diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 8f46dd2575db36faa55d4973525cef17b4f17a72..0000000000000000000000000000000000000000 --- a/.npmrc +++ /dev/null @@ -1,2 +0,0 @@ -registry=https://registry.npmmirror.com/ - diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index 66d4c0d9d803a7017653eef72220ccacc9355a19..0000000000000000000000000000000000000000 --- a/.prettierrc.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/prettierrc", - "semi": true, - "tabWidth": 2, - "singleQuote": true, - "printWidth": 160, - "trailingComma": "es5" -} diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 28805957ad278366fae711acaf3998c30cce12d2..0000000000000000000000000000000000000000 --- a/Dockerfile +++ /dev/null @@ -1,102 +0,0 @@ -FROM node:18.14.1 as Builder - -RUN mkdir -p /home/openeuler/docs -WORKDIR /home/openeuler/docs -COPY . /home/openeuler/docs - -RUN npm install pnpm -g -RUN pnpm install -RUN pnpm build - -FROM swr.cn-north-4.myhuaweicloud.com/opensourceway/openeuler/nginx:1.24.0-22.03-lts-sp1 as NginxBuilder - -FROM openeuler/openeuler:22.03 - -ENV NGINX_CONFIG_FILE /etc/nginx/nginx.conf -ENV NGINX_CONFIG_PATH /etc/nginx/ -ENV NGINX_PID /var/run/nginx.pid -ENV NGINX_USER nginx -ENV NGINX_GROUP nginx -ENV NGINX_BIN /usr/share/nginx/sbin/ -ENV NGINX_HOME /usr/share/nginx/ -ENV NGINX_EXE_FILE /usr/share/nginx/sbin/nginx -ENV DST_PATH /etc/nginx/cert - -COPY --from=NginxBuilder /usr/share/nginx /usr/share/nginx -COPY --from=NginxBuilder /usr/share/nginx/sbin/nginx /usr/share/nginx/sbin/nginx -COPY --from=NginxBuilder /etc/nginx/modules /etc/nginx/modules -COPY --from=NginxBuilder /etc/nginx/geoip /etc/nginx/geoip -COPY --from=NginxBuilder /etc/nginx/mime.types /etc/nginx/mime.types - -COPY --from=Builder /home/openeuler/docs/docs/.vitepress/dist /usr/share/nginx/www/ - -RUN sed -i "s|repo.openeuler.org|mirrors.nju.edu.cn/openeuler|g" /etc/yum.repos.d/openEuler.repo \ - && sed -i '/metalink/d' /etc/yum.repos.d/openEuler.repo \ - && sed -i '/metadata_expire/d' /etc/yum.repos.d/openEuler.repo \ - && yum update -y \ - && yum install -y findutils passwd shadow \ - && find /usr/share/nginx/www -type d -print0| xargs -0 chmod 500 \ - && find /usr/share/nginx/www -type f -print0| xargs -0 chmod 400 - -COPY ./deploy/nginx/nginx.conf /etc/nginx/nginx.conf - -RUN touch /var/run/nginx.pid \ - && groupadd -g 1000 nginx \ - && useradd -u 1000 -g nginx -s /sbin/nologin nginx \ - && chown -R nginx:nginx /usr/share/nginx \ - && find /usr/share/nginx -type d -print0 | xargs -0 chmod 500 \ - && chmod 500 /usr/share/nginx/sbin/nginx \ - && mkdir -p /var/log/nginx \ - && chown -R nginx:nginx /var/log/nginx \ - && chmod -R 640 /var/log/nginx \ - && mkdir -p /var/lib/nginx/tmp/client_body \ - && chown -R nginx:nginx /var/lib/nginx/tmp/client_body \ - && mkdir -p /var/lib/nginx/tmp/fastcgi \ - && chown -R nginx:nginx /var/lib/nginx/tmp/fastcgi \ - && mkdir -p /var/lib/nginx/tmp/proxy \ - && chown -R nginx:nginx /var/lib/nginx/tmp/proxy \ - && mkdir -p /var/lib/nginx/tmp/scgi \ - && chown -R nginx:nginx /var/lib/nginx/tmp/scgi \ - && mkdir -p /var/lib/nginx/tmp/uwsgi \ - && chown -R nginx:nginx /var/lib/nginx/tmp/uwsgi \ - && chmod -R 500 /var/lib/nginx/ \ - && chown -R nginx:nginx /var/lib/nginx/ \ - && chown -R nginx:nginx /var/run/nginx.pid \ - && chmod 640 /var/run/nginx.pid \ - && chown -R nginx:nginx /etc/nginx \ - && chmod 550 /etc/nginx \ - && chmod 550 /etc/nginx/geoip/ \ - && chmod 440 /etc/nginx/geoip/* \ - && chmod 550 /etc/nginx/modules \ - && chmod 440 /etc/nginx/modules/* \ - && chmod 440 /etc/nginx/nginx.conf \ - && chmod 440 /etc/nginx/mime.types \ - && rm -rf /usr/share/nginx/html/ \ - && rm -rf /usr/share/nginx/logs/ \ - && echo "umask 0027" >> /etc/bashrc \ - && echo "set +o history" >> /etc/bashrc \ - && sed -i "s|HISTSIZE=1000|HISTSIZE=0|" /etc/profile \ - && sed -i "s|PASS_MAX_DAYS[ \t]*99999|PASS_MAX_DAYS 30|" /etc/login.defs \ - && passwd -l $NGINX_USER \ - && yum clean all \ - && usermod -s /sbin/nologin sync \ - && usermod -s /sbin/nologin shutdown \ - && usermod -s /sbin/nologin halt \ - && echo "export TMOUT=1800 readonly TMOUT" >> /etc/profile \ - && rm -rf /usr/bin/gdb* \ - && rm -rf /usr/share/gdb \ - && rm -rf /usr/share/gcc-10.3.1 \ - && yum remove gdb-gdbserver findutils passwd shadow -y - -COPY ./deploy/monitor.sh ./deploy/entrypoint.sh /etc/nginx -RUN chmod 500 /etc/nginx/monitor.sh \ - && chmod 500 /etc/nginx/entrypoint.sh \ - && chown nginx:nginx /etc/nginx/monitor.sh \ - && chown nginx:nginx /etc/nginx/entrypoint.sh - -EXPOSE 8080 - -USER nginx - -ENTRYPOINT ["/etc/nginx/entrypoint.sh"] - diff --git a/deploy/entrypoint.sh b/deploy/entrypoint.sh deleted file mode 100644 index d72cb306899d5bffd224ba119f20584b3ddcada1..0000000000000000000000000000000000000000 --- a/deploy/entrypoint.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -bash /etc/nginx/monitor.sh $DET_URL $DST_PATH & -/usr/share/nginx/sbin/nginx -g 'daemon off;' \ No newline at end of file diff --git a/deploy/monitor.sh b/deploy/monitor.sh deleted file mode 100644 index 1597f12a3bc3aad4c15928870252e9ca41420ca4..0000000000000000000000000000000000000000 --- a/deploy/monitor.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -# this script is for website monitoring, -# when website is up, delete all cert file. - -HOST=$1 -DST_PATH=$2 - -delete_file() { - if [ -d $DST_PATH ]; then - echo "found $DST_PATH" > /dev/stdout - rm -rf $DST_PATH/* - else - echo "$DST_PATH not found" > /dev/stdout - fi -} - -while true; -do - sleep 20 - RET=$(curl -sIL -w "%{http_code}\n" -o /dev/null $HOST) - if [ $RET == "200" ]; then - echo "website is up!!!" > /dev/stdout - delete_file - if [ $? -eq 0 ]; then - echo "successful delete file, exit" > /dev/stdout - break - else - echo "failed to delete file" > /dev/stdout - fi - else - echo "waiting for website up, http_status: $RET" > /dev/stdout - fi -done \ No newline at end of file diff --git a/deploy/nginx/nginx-pro.conf b/deploy/nginx/nginx-pro.conf deleted file mode 100644 index b5c753620b49ffea31274f77f6ceb7720adeb02f..0000000000000000000000000000000000000000 --- a/deploy/nginx/nginx-pro.conf +++ /dev/null @@ -1,13 +0,0 @@ -location ^~ /api-id/ { - proxy_set_header X-Forwarded-For $http_x_real_ip; - add_header X-XSS-Protection "1; mode=block"; - add_header X-Frame-Options DENY; - add_header X-Content-Type-Options nosniff; - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; - add_header Content-Security-Policy "script-src 'self'; object-src 'none'; frame-src 'none'"; - add_header Cache-Control "no-cache,no-store,must-revalidate"; - add_header Pragma no-cache; - add_header Expires 0; - - proxy_pass https://omapi.osinfra.cn/; -} diff --git a/deploy/nginx/nginx-test.conf b/deploy/nginx/nginx-test.conf deleted file mode 100644 index 8a0642308f2063fe7c78c1d76ba4c584207710ef..0000000000000000000000000000000000000000 --- a/deploy/nginx/nginx-test.conf +++ /dev/null @@ -1,30 +0,0 @@ -location ^~ /api-search/ { - add_header X-XSS-Protection "1; mode=block"; - add_header X-Frame-Options DENY; - add_header X-Content-Type-Options nosniff; - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; - add_header Content-Security-Policy "script-src 'self' 'unsafe-inline' 'unsafe-eval' ; object-src 'none'; frame-src 'none'"; - add_header Cache-Control "no-cache,no-store,must-revalidate"; - add_header Pragma no-cache; - add_header Expires 0; - - proxy_set_header X-Forwarded-For $http_x_real_ip; - proxy_http_version 1.1; - proxy_set_header Connection ""; - proxy_ssl_protocols TLSv1.2 TLSv1.3; - proxy_pass https://doc-search.test.osinfra.cn/; -} - -location ^~ /api-id/ { - proxy_set_header X-Forwarded-For $http_x_real_ip; - add_header X-XSS-Protection "1; mode=block"; - add_header X-Frame-Options DENY; - add_header X-Content-Type-Options nosniff; - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; - add_header Content-Security-Policy "script-src 'self'; object-src 'none'; frame-src 'none'"; - add_header Cache-Control "no-cache,no-store,must-revalidate"; - add_header Pragma no-cache; - add_header Expires 0; - - proxy_pass https://omapi.test.osinfra.cn/; -} diff --git a/deploy/nginx/nginx.conf b/deploy/nginx/nginx.conf deleted file mode 100644 index 224f56ff7a813d926ed1526bf86506586202d99a..0000000000000000000000000000000000000000 --- a/deploy/nginx/nginx.conf +++ /dev/null @@ -1,145 +0,0 @@ -user $NGINX_USER; - -error_log /dev/stdout info; - -pid /var/run/nginx.pid; - -worker_processes 2; -worker_rlimit_nofile 4096; -events { - use epoll; - worker_connections 1024; -} - -http { - include /etc/nginx/mime.types; - - log_format main '[$time_local] remote_addr: $http_x_real_ip, request: "$request", ' - 'status: $status, body_bytes_sent: $body_bytes_sent, http_referer: "$http_referer", ' - 'http_user_agent: "$http_user_agent"'; - - access_log /dev/stdout main; - - server_tokens off; - - autoindex off; - - port_in_redirect off; - absolute_redirect off; - - client_header_buffer_size 1k; - large_client_header_buffers 4 8k; - client_body_buffer_size 1K; - client_max_body_size 1k; - - client_header_timeout 8; - client_body_timeout 8; - client_body_in_file_only off; - - keepalive_timeout 5 5; - send_timeout 8; - - proxy_hide_header X-Powered-By; - proxy_request_buffering off; - - limit_conn_zone $binary_remote_addr zone=limitperip:10m; - limit_req_zone $binary_remote_addr zone=ratelimit:10m rate=1000r/s; - - gzip on; - gzip_min_length 1k; - gzip_buffers 4 16k; - gzip_comp_level 5; - gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/javascript application/x-httpd-php application/json; - gzip_vary on; - - server { - listen 8080 ssl default_server; - server_name openeuler-docs.test.osinfra.cn; - charset utf-8; - - add_header X-XSS-Protection "1; mode=block"; - add_header X-Frame-Options DENY; - add_header X-Content-Type-Options nosniff; - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; - add_header Content-Security-Policy "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://hm.baidu.com/; object-src 'none'; frame-src 'none'"; - add_header Cache-Control "no-cache,no-store,must-revalidate"; - add_header Pragma no-cache; - add_header Expires 0; - - limit_conn limitperip 10; - ssl_session_tickets off; - ssl_session_timeout 5m; - ssl_session_cache shared:SSL:10m; - - ssl_certificate "cert/server.crt"; - ssl_certificate_key "cert/server.key"; - ssl_password_file "cert/abc.txt"; - ssl_dhparam "cert/dhparam.pem"; - ssl_ecdh_curve auto; - ssl_protocols TLSv1.2; - ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384"; - ssl_prefer_server_ciphers on; - ssl_stapling on; - ssl_stapling_verify on; - resolver 8.8.8.8 8.8.4.4 valid=60s; - resolver_timeout 5s; - - if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE)$) { - return 444; - } - - location ~ /\. { - deny all; - return 404; - } - - location / { - limit_req zone=ratelimit burst=5 nodelay; - proxy_set_header X-Forwarded-For $http_x_real_ip; - proxy_set_header Host $host; - root /usr/share/nginx/www; - index index.html; - } - - include ./confd/nginx*.conf; - - error_page 401 402 403 405 406 407 413 414 /error.html; - error_page 500 501 502 503 504 505 /error.html; - error_page 404 /404.html; - - location = /error.html { - root /usr/share/nginx/www; - } - - location = / { - return 301 /index.html; - } - - location = /zh/ { - return 301 /zh/index.html; - } - - # location ^~ /zh/docs/22.03/ { - # proxy_set_header X-Forwarded-For $http_x_real_ip; - # proxy_http_version 1.1; - # proxy_set_header Connection ""; - # proxy_ssl_protocols TLSv1.3; - # proxy_ssl_verify off; - # # 转发后移除前缀 - # rewrite ^/zh/docs/22.03(/.*)$ $1 break; - # proxy_pass http://openeuler-docs-website-stable-2203.openeuler-website-docs:8080; - # } - - # location ^~ /zh/docs/23.03/ { - # proxy_set_header X-Forwarded-For $http_x_real_ip; - # proxy_http_version 1.1; - # proxy_set_header Connection ""; - # proxy_ssl_protocols TLSv1.3; - # proxy_ssl_verify off; - # # 转发后移除前缀 - # rewrite ^/zh/docs/23.03(/.*)$ $1 break; - # proxy_pass http://openeuler-docs-website-stable-2303.openeuler-website-docs:8080; - # } - - } -} \ No newline at end of file diff --git a/docs/.env.development b/docs/.env.development deleted file mode 100644 index 90d523f5a262f7ab1e448529cfa232203e802c39..0000000000000000000000000000000000000000 --- a/docs/.env.development +++ /dev/null @@ -1,3 +0,0 @@ -VITE_XSRF_COOKIE_NAME = '_U_T_' -VITE_XSRF_HEADER_NAME = 'Token' -VITE_COOKIE_DOMAIN = localhost \ No newline at end of file diff --git a/docs/.env.production b/docs/.env.production deleted file mode 100644 index 0ab488715f550891fd34930c56de8acb4102c684..0000000000000000000000000000000000000000 --- a/docs/.env.production +++ /dev/null @@ -1,5 +0,0 @@ -VITE_LOGIN_URL = https://id.openeuler.org -VITE_XSRF_COOKIE_NAME = '_U_T_' -VITE_XSRF_HEADER_NAME = 'Token' -VITE_COOKIE_DOMAIN = .openeuler.org -VITE_MESSAGE_CENTER_URL = https://message-center.openeuler.org diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts deleted file mode 100644 index a4317ff5d63a052e1e6ddf1f28581109d9bc8029..0000000000000000000000000000000000000000 --- a/docs/.vitepress/config.ts +++ /dev/null @@ -1,88 +0,0 @@ -import hljs from 'highlight.js'; - -export default { - base: '/', - cleanUrls: false, - ignoreDeadLinks: true, - title: '文档 | openEuler', - srcExclude: ['**/_menu.md'], - head: [ - [ - 'link', - { - rel: 'icon', - href: '/favicon.ico?v=2', - }, - ], - [ - 'meta', - { - name: 'viewport', - content: 'width=device-width,initial-scale=1,user-scalable=no', - }, - ], - [ - 'script', - { - src: '/check-dark-mode-v2.js', - }, - ], - ], - appearance: false, // enable dynamic scripts for dark mode - titleTemplate: true, - locales: { - root: { - lang: 'zh', - title: '文档 | openEuler', - description: 'openEuler 文档', - }, - zh: { - label: '简体中文', - lang: 'zh', - title: '文档 | openEuler', - description: 'openEuler 文档', - }, - en: { - label: 'English', - lang: 'en', - title: 'Docs | openEuler', - description: 'openEuler docs', - }, - }, - markdown: { - math: true, - plantuml: true, - highlight: (code: string, lang: string) => { - try { - return `
${
-          lang && hljs.getLanguage(lang)
-            ? hljs.highlight(code, {
-                language: lang === 'shell' ? 'bash' : lang,
-              }).value
-            : hljs.highlightAuto(code).value
-        }
`; - } catch { - return `
${code}
`; - } - }, - config: (md) => { - md.renderer.rules.code_inline = (tokens, idx) => { - const content = tokens[idx].content; - // 转义 - const escapedContent = md.utils.escapeHtml(content); - // 处理双花括号 - return `${escapedContent}`; - }; - - // 替换 {{ }} 内容 - md.renderer.rules.text = (tokens, idx) => { - const content = tokens[idx].content; - const escapedContent = md.utils.escapeHtml(content); - if (/{{(.*?)}}/g.test(content)) { - return `${escapedContent}`; - } - return escapedContent; - }; - }, - }, -}; diff --git a/docs/.vitepress/public/check-dark-mode-v2.js b/docs/.vitepress/public/check-dark-mode-v2.js deleted file mode 100644 index 81dad744f19debdc73dfcae3c8ec3b8b69eddc35..0000000000000000000000000000000000000000 --- a/docs/.vitepress/public/check-dark-mode-v2.js +++ /dev/null @@ -1,19 +0,0 @@ -function getCookie(key) { - const name = `${encodeURIComponent(key)}=`; - const decodedCookies = decodeURIComponent(document.cookie); - const cookies = decodedCookies.split('; '); - for (let cookie of cookies) { - if (cookie.startsWith(name)) { - return cookie.substring(name.length); - } - } - - return null; -} - -const e = getCookie('openEuler-theme-appearance') || 'auto'; -const a = window.matchMedia('(prefers-color-scheme: dark)').matches; -if (!e || e === 'auto' ? a : e === 'dark') { - document.documentElement.classList.add('dark'); - document.documentElement.setAttribute('data-o-theme', 'dark'); -} diff --git a/docs/.vitepress/public/error.html b/docs/.vitepress/public/error.html deleted file mode 100644 index 7dacb97273f024007ceecac80ab8e33925e51fe2..0000000000000000000000000000000000000000 --- a/docs/.vitepress/public/error.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - -
- -

Error

-
- - diff --git a/docs/.vitepress/public/favicon.ico b/docs/.vitepress/public/favicon.ico deleted file mode 100644 index ba6134a0ab94b8dd83d098e059d3c4dd93dd1041..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/public/favicon.ico and /dev/null differ diff --git a/docs/.vitepress/src/@types/type-doc-menu.ts b/docs/.vitepress/src/@types/type-doc-menu.ts deleted file mode 100644 index 86a39eb82b6107f4a5853963f987dd7d6175b818..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/@types/type-doc-menu.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface DocMenuT { - id: string; - label: string; - href?: string; - description?: string; - type: string; - ismanual?: string; - children?: Array; -} diff --git a/docs/.vitepress/src/@types/type-docs.ts b/docs/.vitepress/src/@types/type-docs.ts deleted file mode 100644 index 21451f578197ba540e0a55f430347a2c988bf1d6..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/@types/type-docs.ts +++ /dev/null @@ -1,9 +0,0 @@ -// 文档捉虫参数类型 -export interface DocsBugParamsT { - bugDocFragment: string; // bug文档片段 - existProblem: []; // 问题类型 - problemDetail: string; // 问题类型原因 - comprehensiveSatisfication: string; // 文档满意度 - email: string; // 邮箱 - link: string; // 当前url -} diff --git a/docs/.vitepress/src/@types/type-locale.ts b/docs/.vitepress/src/@types/type-locale.ts deleted file mode 100644 index b166a3d425d02a1cbcceff3efc38215bc20413df..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/@types/type-locale.ts +++ /dev/null @@ -1 +0,0 @@ -export type LocaleT = 'zh' | 'en'; diff --git a/docs/.vitepress/src/@types/type-search.ts b/docs/.vitepress/src/@types/type-search.ts deleted file mode 100644 index 0d7f315f0f0adb6d7cbdefd1ee3de8cb590244af..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/@types/type-search.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { DocMenuNodeT } from '@/utils/tree'; - -export interface SearchRecommendT { - key: string; - count: number; -} - -// 文档搜索参数 -export interface SearchDocQueryT { - keyword: string; - lang: string; - page: number; - version: string; - path: string; -} - -// 文档搜索结果 -export interface SearchDocItemT { - articleName: string; - lang: string; - path: string; - score: number; - textContent: string; - title: string; - type: string; - version: string; - sourceData: DocMenuNodeT[]; -} diff --git a/docs/.vitepress/src/@types/type-user.ts b/docs/.vitepress/src/@types/type-user.ts deleted file mode 100644 index 190529e137399b01ebd44c539473263b6e07048e..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/@types/type-user.ts +++ /dev/null @@ -1,18 +0,0 @@ -export interface Identity { - login_name: string; - userIdInIdp: string; - identity: string; // 第三方平台类型,gitee/github - user_name: string; - accessToken: string; -} - -// 用户账号数据类型 -export interface UserInfoT { - photo: string; // 头像 - username: string; // 用户名 - email: string; // 邮箱 - phoneCountryCode: string; // 区号 - phone: string; // 手机号 - identities: Identity[]; // 绑定的第三方平台账号 - recipientId?: number; // 接收人id -} diff --git a/docs/.vitepress/src/App.vue b/docs/.vitepress/src/App.vue deleted file mode 100644 index f6046c50e575bb3feb8fbf58a37b1966029884e8..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/App.vue +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - - diff --git a/docs/.vitepress/src/NotFound.vue b/docs/.vitepress/src/NotFound.vue deleted file mode 100644 index 353acfed55d919918dcdc5903bbb90fe9a868d9a..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/NotFound.vue +++ /dev/null @@ -1,47 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/api/api-docs.ts b/docs/.vitepress/src/api/api-docs.ts deleted file mode 100644 index 81c8cd37c7576824df368423611decaba61cfb1b..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/api/api-docs.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { request } from '@/shared/axios'; - -import type { DocsBugParamsT } from '@/@types/type-docs'; - -/** - * 文档捉虫 - * @param {string} lang 语言 - * @param { DocsBugParamsT } params 文档捉虫参数类型 - */ -export function submitBug(lang: string, params: DocsBugParamsT) { - const url = `/api-dsapi/query/add/bugquestionnaire?community=openeuler&lang=${lang}`; - return request.post(url, params).then((res) => { - return res.data; - }); -} diff --git a/docs/.vitepress/src/api/api-search.ts b/docs/.vitepress/src/api/api-search.ts deleted file mode 100644 index 905cc4b5d2e7337e80e004a3ceec8d5b9cbb1125..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/api/api-search.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { request } from '@/shared/axios'; -import type { AxiosResponse } from '@/shared/axios'; - -import type { SearchRecommendT, SearchDocQueryT } from '@/@types/type-search'; - -/** - * 获取热门搜索数据 - * @param {String} params 语言 - * @returns {Object} - */ -export function getPop(params: string): Promise<{ - msg: string; - obj: string[]; - status: number; -}> { - const url = `/api-search/search/pop?${params}`; - return request - .post( - url, - // TODO: 取消手动添加请求头 - {}, - { - headers: { - 'Content-Type': 'application/json;charset=UTF-8', - }, - } - ) - .then((res: AxiosResponse) => res.data); -} - -/** - * 关联搜索 - * @param {Object} params 申请表格数据 - * @return {Object} - */ -export function getSearchRecommend(params: { query: string }): Promise<{ - status: number; - obj: { - word: SearchRecommendT[]; - }; - msg: string; -}> { - const url = `/api-search/search/word?query=${params.query}`; - return request.post(url, params).then((res: AxiosResponse) => res.data); -} - -/** - * 获取文档搜索结果 - * @param {SearchDocQueryT} params 搜索参数对象 - * @returns {Promise} 搜索结果 - */ -export function getSearchDocs(params: SearchDocQueryT) { - const url = '/api-search/search/sort/docs'; - return request.post(url, params).then((res: AxiosResponse) => res.data); -} diff --git a/docs/.vitepress/src/api/api-user.ts b/docs/.vitepress/src/api/api-user.ts deleted file mode 100644 index ca328fc2347c1c695be2f2de26b97a3f3d222026..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/api/api-user.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { UserInfoT } from '@/@types/type-user'; -import { request } from '@/shared/axios'; - -interface UserPermissionResponseT { - msg: string; - code: number; - data: UserInfoT; -} - -/** - * 获取用户信息 - * @param community community字段,默认openeuler - * @returns {Promise} 用户信息 - */ -export function queryUserInfo() { - const url = '/api-id/oneid/personal/center/user?community=openeuler'; - return request.get(url).then((res) => res.data.data); -} diff --git a/docs/.vitepress/src/assets/category/common/404-dark.png b/docs/.vitepress/src/assets/category/common/404-dark.png deleted file mode 100644 index 43c80e1785f6d378f91123da426643f4adebd906..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/common/404-dark.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/common/404.png b/docs/.vitepress/src/assets/category/common/404.png deleted file mode 100644 index 9649a1b3b9e05a9f3c3d4dd9e3d452ee4114e6f7..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/common/404.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/common/menu-switch-bar.png b/docs/.vitepress/src/assets/category/common/menu-switch-bar.png deleted file mode 100644 index 1e5c278279f7842abccf572b7248a0ebfe40a8bd..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/common/menu-switch-bar.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/float/bug-bg-hover.png b/docs/.vitepress/src/assets/category/float/bug-bg-hover.png deleted file mode 100644 index e8d115425299e0996b5dbc637028d38e4c6bc079..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/float/bug-bg-hover.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/float/bug-bg.png b/docs/.vitepress/src/assets/category/float/bug-bg.png deleted file mode 100644 index 2ba900e87f7674406ad1f6c0226201adce746d9e..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/float/bug-bg.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/atom-logo.png b/docs/.vitepress/src/assets/category/footer/atom-logo.png deleted file mode 100644 index 25020b8000b592158a67aaf2bd037aca456e6c38..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/atom-logo.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/atom-logo.svg b/docs/.vitepress/src/assets/category/footer/atom-logo.svg deleted file mode 100644 index 0cce03d0379659ecc5f3ec9113f747633ec0f287..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/category/footer/atom-logo.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - 开放原子开源基金会 - - - - - - - - - - \ No newline at end of file diff --git a/docs/.vitepress/src/assets/category/footer/bilibili.png b/docs/.vitepress/src/assets/category/footer/bilibili.png deleted file mode 100644 index 67564c13dddf56675372f9afe99d74912fa5bd03..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/bilibili.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/bilibili_hover.png b/docs/.vitepress/src/assets/category/footer/bilibili_hover.png deleted file mode 100644 index 20220194f36f19869379bc0f2b0959d6c0e6cfb0..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/bilibili_hover.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/code-xzs.png b/docs/.vitepress/src/assets/category/footer/code-xzs.png deleted file mode 100644 index 59d055ddde86c889778e185e8408b00c177be395..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/code-xzs.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/code-zgz-2.png b/docs/.vitepress/src/assets/category/footer/code-zgz-2.png deleted file mode 100644 index aa2dd38c71886d16d71600823cac0249e61bef84..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/code-zgz-2.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/code-zgz.jpg b/docs/.vitepress/src/assets/category/footer/code-zgz.jpg deleted file mode 100644 index ba027341b3cdd608e12491ee13715ab8011200e3..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/code-zgz.jpg and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/code-zgz.png b/docs/.vitepress/src/assets/category/footer/code-zgz.png deleted file mode 100644 index aa2dd38c71886d16d71600823cac0249e61bef84..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/code-zgz.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/csdn.png b/docs/.vitepress/src/assets/category/footer/csdn.png deleted file mode 100644 index 86de6f91345e5e74b0cfdca4baecdb9dc4fca77b..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/csdn.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/csdn_hover.png b/docs/.vitepress/src/assets/category/footer/csdn_hover.png deleted file mode 100644 index aafd561b925f62a5ad024557765dff039b465c1f..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/csdn_hover.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/footer-bg-mo.png b/docs/.vitepress/src/assets/category/footer/footer-bg-mo.png deleted file mode 100644 index 972a780e9762ddcf688c24e6a4a0c238b21cf787..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/footer-bg-mo.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/footer-bg.png b/docs/.vitepress/src/assets/category/footer/footer-bg.png deleted file mode 100644 index 4896c76cce60fa88a97e879319da6a54b6c42267..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/footer-bg.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/footer-bg1.png b/docs/.vitepress/src/assets/category/footer/footer-bg1.png deleted file mode 100644 index 3c5ab6b54ecdfaa4a1e7d2152d2c59b1b7e9063d..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/footer-bg1.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/footer-logo1.png b/docs/.vitepress/src/assets/category/footer/footer-logo1.png deleted file mode 100644 index 80f97536b255acb11f11412c2ee3b3a836e21a43..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/footer-logo1.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/footer-logo2.png b/docs/.vitepress/src/assets/category/footer/footer-logo2.png deleted file mode 100644 index 723cc97315cde70c4aebae844d92be9d0b1b834f..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/footer-logo2.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/img-gzh.png b/docs/.vitepress/src/assets/category/footer/img-gzh.png deleted file mode 100644 index afc3f345e603e73aa297c656ee2e15b085945b18..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/img-gzh.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/img-xzs.png b/docs/.vitepress/src/assets/category/footer/img-xzs.png deleted file mode 100644 index de17acbd32440e608d227645a2d9b4425cb0bda8..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/img-xzs.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/infoq.png b/docs/.vitepress/src/assets/category/footer/infoq.png deleted file mode 100644 index ec5facd385627659b8f38e9cb0438fc5e0c72a08..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/infoq.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/juejin.png b/docs/.vitepress/src/assets/category/footer/juejin.png deleted file mode 100644 index 9a6e4077a16d68b3c4652bd2f8d403313cfc0766..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/juejin.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/juejin_hover.png b/docs/.vitepress/src/assets/category/footer/juejin_hover.png deleted file mode 100644 index 862d71f5f42dbea37ac5c78b2103840717f15401..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/juejin_hover.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/linkdin.png b/docs/.vitepress/src/assets/category/footer/linkdin.png deleted file mode 100644 index 0968f473516e7777494fdb34330796b85ea3a0f4..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/linkdin.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/linkdin_hover.png b/docs/.vitepress/src/assets/category/footer/linkdin_hover.png deleted file mode 100644 index 4b29a86c1a3b8f41bb171f7f8e51564c8c0b8016..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/linkdin_hover.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/oschina.png b/docs/.vitepress/src/assets/category/footer/oschina.png deleted file mode 100644 index 47804ca220039e4d5a540981ecc31819ecb9a990..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/oschina.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/oschina_hover.png b/docs/.vitepress/src/assets/category/footer/oschina_hover.png deleted file mode 100644 index add919f03d2626328dbf8d70daea7bceea8dac1d..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/oschina_hover.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/reddit-square.png b/docs/.vitepress/src/assets/category/footer/reddit-square.png deleted file mode 100644 index 6e88e30532053bdba3048da08d31ac0c174bbf91..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/reddit-square.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/reddit-square_hover.png b/docs/.vitepress/src/assets/category/footer/reddit-square_hover.png deleted file mode 100644 index fc9624a40d53572da544e544205f57bbe32af401..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/reddit-square_hover.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/svg-icons/icon-chat.svg b/docs/.vitepress/src/assets/category/footer/svg-icons/icon-chat.svg deleted file mode 100644 index b4ca3738785b1d4cec20424310917664a7383b0c..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/category/footer/svg-icons/icon-chat.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/docs/.vitepress/src/assets/category/footer/svg-icons/icon-quickissue_dark.svg b/docs/.vitepress/src/assets/category/footer/svg-icons/icon-quickissue_dark.svg deleted file mode 100644 index cd0a77287b9ee0c5176f1378780efe4570b8f39f..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/category/footer/svg-icons/icon-quickissue_dark.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/assets/category/footer/svg-icons/icon-quickissue_light.svg b/docs/.vitepress/src/assets/category/footer/svg-icons/icon-quickissue_light.svg deleted file mode 100644 index 3374a009b0d71eda341b57ee2c408dc643215526..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/category/footer/svg-icons/icon-quickissue_light.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/docs/.vitepress/src/assets/category/footer/svg-icons/icon-smile.svg b/docs/.vitepress/src/assets/category/footer/svg-icons/icon-smile.svg deleted file mode 100644 index f5ecc9acde935861025708ce60055ffb69a53dc7..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/category/footer/svg-icons/icon-smile.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/category/footer/toutiao.png b/docs/.vitepress/src/assets/category/footer/toutiao.png deleted file mode 100644 index 67a2e929bc26cccb97dabd567fbc8b8775dd792e..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/toutiao.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/toutiao_hover.png b/docs/.vitepress/src/assets/category/footer/toutiao_hover.png deleted file mode 100644 index 3a5379ab6531fc1f7b2fa36d87766de7695b9a87..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/toutiao_hover.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/x.png b/docs/.vitepress/src/assets/category/footer/x.png deleted file mode 100644 index d7985af63ca3004d74aeab0cacfae7c91102ce15..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/x.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/x_hover.png b/docs/.vitepress/src/assets/category/footer/x_hover.png deleted file mode 100644 index 05cbf9f8cda7b4bee88a9c6375b01d1bb48d895d..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/x_hover.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/youtube.png b/docs/.vitepress/src/assets/category/footer/youtube.png deleted file mode 100644 index f43e105129f8da83aebfc1de3da4a373c7c0cc6a..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/youtube.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/footer/youtube_hover.png b/docs/.vitepress/src/assets/category/footer/youtube_hover.png deleted file mode 100644 index 730a7157ee651431567f580c7ed0312111bdb643..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/footer/youtube_hover.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/header/annual-report-2024.jpg b/docs/.vitepress/src/assets/category/header/annual-report-2024.jpg deleted file mode 100644 index 9d07341f232ef435c7be48727789d60ee33d82e5..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/header/annual-report-2024.jpg and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/header/logo.svg b/docs/.vitepress/src/assets/category/header/logo.svg deleted file mode 100644 index af74e72eb8319ea4b92aa1467da4ce15766ba0e2..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/category/header/logo.svg +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/.vitepress/src/assets/category/header/logo_dark.svg b/docs/.vitepress/src/assets/category/header/logo_dark.svg deleted file mode 100644 index e27f683229d272a1043b2dc4653d0cd1f9e1f4c9..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/category/header/logo_dark.svg +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/.vitepress/src/assets/category/header/nav_background_left.png b/docs/.vitepress/src/assets/category/header/nav_background_left.png deleted file mode 100644 index f7f8a934fc441ab6c1c50f62479e303404d38a0f..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/header/nav_background_left.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/header/nav_background_right.png b/docs/.vitepress/src/assets/category/header/nav_background_right.png deleted file mode 100644 index 97ec1491e5a6a050343c357f5decd0d9a3d5a2bf..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/header/nav_background_right.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/header/report.png b/docs/.vitepress/src/assets/category/header/report.png deleted file mode 100644 index 454118b9c36d41ca2f1b8aa9e0ba35417ce71e4d..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/header/report.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/header/sig.png b/docs/.vitepress/src/assets/category/header/sig.png deleted file mode 100644 index deb54d4b8c051cddb5ec49a20d17f1015203fdc8..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/header/sig.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/header/summit.png b/docs/.vitepress/src/assets/category/header/summit.png deleted file mode 100644 index d1a83a0befab7e92155527827b2996445fe63643..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/header/summit.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/cloud-bg.png b/docs/.vitepress/src/assets/category/home/cloud-bg.png deleted file mode 100644 index 9a9589f9c55249f92c69eac54a61d26c15822a91..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/cloud-bg.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/edge-computing-bg.png b/docs/.vitepress/src/assets/category/home/edge-computing-bg.png deleted file mode 100644 index b1a708eacda8b68eea5ed25c505c28b60a4d3ba1..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/edge-computing-bg.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/embedded-bg.png b/docs/.vitepress/src/assets/category/home/embedded-bg.png deleted file mode 100644 index 646afee988b57bcb1f064952d6352ec4efb73644..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/embedded-bg.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/home-banner-dark.png b/docs/.vitepress/src/assets/category/home/home-banner-dark.png deleted file mode 100644 index a5577c7cfa1b23ff9f4105e527397f7dbb37fae1..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/home-banner-dark.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/home-banner.png b/docs/.vitepress/src/assets/category/home/home-banner.png deleted file mode 100644 index 38e493a283ab67573b824ef9df52729f4a8d33d6..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/home-banner.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/install-guide-bg-dark.png b/docs/.vitepress/src/assets/category/home/install-guide-bg-dark.png deleted file mode 100644 index 3ed275d32e81e46123470c4817061362f8946c0a..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/install-guide-bg-dark.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/install-guide-bg.png b/docs/.vitepress/src/assets/category/home/install-guide-bg.png deleted file mode 100644 index 2c11b03480c35eb2ec9ed209f6fe5e46a5d0f7ec..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/install-guide-bg.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/install-guide-mo-bg.png b/docs/.vitepress/src/assets/category/home/install-guide-mo-bg.png deleted file mode 100644 index ff42e30277ab93c7434d15e002494b59fc9ab97e..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/install-guide-mo-bg.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/install-mo-bg-dark.png b/docs/.vitepress/src/assets/category/home/install-mo-bg-dark.png deleted file mode 100644 index 979f2a920d9b0dafd5895250c6c845eebac7e404..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/install-mo-bg-dark.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/qa-bg-dark.png b/docs/.vitepress/src/assets/category/home/qa-bg-dark.png deleted file mode 100644 index a3285bf61dcf2e05909b4f4ed313c09257c86f34..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/qa-bg-dark.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/qa-bg.png b/docs/.vitepress/src/assets/category/home/qa-bg.png deleted file mode 100644 index 349fa94d0ea4235c40c7353bae2528be6429ef30..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/qa-bg.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/qa-mo-bg-dark.png b/docs/.vitepress/src/assets/category/home/qa-mo-bg-dark.png deleted file mode 100644 index f6a64344682fd16a5161f43f55cfa870470afaa7..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/qa-mo-bg-dark.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/qa-mo-bg.png b/docs/.vitepress/src/assets/category/home/qa-mo-bg.png deleted file mode 100644 index 3a7b87d4f14f284505f42047817ff3227162e8dd..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/qa-mo-bg.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/server-bg.png b/docs/.vitepress/src/assets/category/home/server-bg.png deleted file mode 100644 index 7a92ccfeaa7f6d875706816176e97fa883f08e0e..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/server-bg.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/started-bg-dark.png b/docs/.vitepress/src/assets/category/home/started-bg-dark.png deleted file mode 100644 index 737cab03621ae3b05d075827ccd107b7dc6f5b94..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/started-bg-dark.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/started-bg.png b/docs/.vitepress/src/assets/category/home/started-bg.png deleted file mode 100644 index b9959f7da41b0d60b28ca9983a9dd19dc8965a36..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/started-bg.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/started-mo-bg-dark.png b/docs/.vitepress/src/assets/category/home/started-mo-bg-dark.png deleted file mode 100644 index 3edeabb509dc11b86898dde7ed99ab07db74328b..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/started-mo-bg-dark.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/started-mo-bg.png b/docs/.vitepress/src/assets/category/home/started-mo-bg.png deleted file mode 100644 index 11dbc204a278b79037fb5c481d697e8c2fd49a6c..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/started-mo-bg.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/svg-icons/cloud.svg b/docs/.vitepress/src/assets/category/home/svg-icons/cloud.svg deleted file mode 100644 index 9a33cfc1f672081d824a19bd0c2fbee08674fd72..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/category/home/svg-icons/cloud.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/docs/.vitepress/src/assets/category/home/svg-icons/edge-computing.svg b/docs/.vitepress/src/assets/category/home/svg-icons/edge-computing.svg deleted file mode 100644 index dc314594239dd5a812ea8b059576341d337c28da..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/category/home/svg-icons/edge-computing.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/assets/category/home/svg-icons/embedded.svg b/docs/.vitepress/src/assets/category/home/svg-icons/embedded.svg deleted file mode 100644 index 3e50be90cd181a5a30b8c34454f8db79dc1ce39c..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/category/home/svg-icons/embedded.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/assets/category/home/svg-icons/server.svg b/docs/.vitepress/src/assets/category/home/svg-icons/server.svg deleted file mode 100644 index 87433c4c25b20ee953c1a71027bd389665977a80..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/category/home/svg-icons/server.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/assets/category/home/svg-icons/virtualization.svg b/docs/.vitepress/src/assets/category/home/svg-icons/virtualization.svg deleted file mode 100644 index b994926478f883206645ad3371f6d92b48d5d1a2..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/category/home/svg-icons/virtualization.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/assets/category/home/virtualization-bg.png b/docs/.vitepress/src/assets/category/home/virtualization-bg.png deleted file mode 100644 index e5fb2c233ec151e41ffae3256fdf2e4db4b8ac55..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/virtualization-bg.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/x2-bg-dark.png b/docs/.vitepress/src/assets/category/home/x2-bg-dark.png deleted file mode 100644 index 553d0c58ab372b61f0146e9e9635990656ff35d2..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/x2-bg-dark.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/x2-bg.png b/docs/.vitepress/src/assets/category/home/x2-bg.png deleted file mode 100644 index 9121ff486e4a0dce1c3a8a174a060f75f752c83e..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/x2-bg.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/x2-mo-bg-dark.png b/docs/.vitepress/src/assets/category/home/x2-mo-bg-dark.png deleted file mode 100644 index 4389369086d138a57e0f40a20c91aae3bb4d359f..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/x2-mo-bg-dark.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/category/home/x2-mo-bg.png b/docs/.vitepress/src/assets/category/home/x2-mo-bg.png deleted file mode 100644 index 4c06aec0fc08d3d94deb617592fa32963e9a0f2d..0000000000000000000000000000000000000000 Binary files a/docs/.vitepress/src/assets/category/home/x2-mo-bg.png and /dev/null differ diff --git a/docs/.vitepress/src/assets/style/base.scss b/docs/.vitepress/src/assets/style/base.scss deleted file mode 100644 index ff70ca7170369270714bbc66b46c36a1c28650da..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/base.scss +++ /dev/null @@ -1,89 +0,0 @@ -/* - * base - */ -html, -body { - margin: 0; - padding: 0; - -webkit-text-size-adjust: none; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); - scroll-behavior: smooth; - box-sizing: border-box; - font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica', 'Arial', sans-serif; - height: 100%; - background: var(--o-color-fill2); - @include text1; - @include scrollbar; -} - -*, -:after, -:before { - box-sizing: inherit; - margin: 0; - padding: 0; -} - -img { - vertical-align: top; -} - -[tabindex] { - outline: none; -} - -a { - cursor: pointer; - color: var(--o-color-link1); - text-decoration: none; - &:hover { - @include respond-to('>phone') { - color: var(--o-color-link2); - } - } - &:active { - @include respond-to('>phone') { - color: var(--o-color-link3); - } - } -} - -blockquote, -figure, -form, -h1, -h2, -h3, -h4, -h5, -h6, -p { - margin: 0; -} -dd, -dl, -li, -ol, -ul { - margin: 0; - padding: 0; -} - -ol, -ul { - list-style: none outside none; -} - -button, -input, -optgroup, -section, -textarea { - font-family: inherit; - font-size: 100%; - line-height: 1.15; - margin: 0; - @include scrollbar; -} diff --git a/docs/.vitepress/src/assets/style/element-plus/index.scss b/docs/.vitepress/src/assets/style/element-plus/index.scss deleted file mode 100644 index 71118eb6ad131f274505be51851256ace728c3cc..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/element-plus/index.scss +++ /dev/null @@ -1,7 +0,0 @@ -@use './input.scss' as *; -@use './pagination.scss' as *; -@use './popper.scss' as *; -@use './select.scss' as *; -@use './table.scss' as *; -@use './scrollbar.scss' as *; -@use './slider.scss' as *; diff --git a/docs/.vitepress/src/assets/style/element-plus/input.scss b/docs/.vitepress/src/assets/style/element-plus/input.scss deleted file mode 100644 index 924139752653de437385c5d70b7698206c4d853e..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/element-plus/input.scss +++ /dev/null @@ -1,15 +0,0 @@ -.el-input { - --el-input-text-color: var(--o-color-info2); - .el-input__wrapper { - box-shadow: none !important; - border: 1px solid var(--o-color-control1); - - &:hover { - border-color: var(--o-color-control2); - } - &.is-focus { - box-shadow: none !important; - border-color: var(--o-color-primary3) !important; - } - } -} diff --git a/docs/.vitepress/src/assets/style/element-plus/pagination.scss b/docs/.vitepress/src/assets/style/element-plus/pagination.scss deleted file mode 100644 index a7439bf75e13309f3f9fd5c492b5173d8f55d71b..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/element-plus/pagination.scss +++ /dev/null @@ -1,47 +0,0 @@ -.el-pagination { - --el-pagination-border-radius: 4px; - --el-pagination-button-bg-color: var(--o-color-fill2); - --el-disabled-bg-color: var(--o-color-fill2); - --el-pagination-button-color: var(--o-color-info1); - .el-pagination__total { - color: var(--o-color-info2); - } - .el-pager { - li { - --el-pagination-button-color: var(--o-color-info1); - &:hover { - background-color: var(--o-color-primary2); - color: var(--o-color-white); - } - } - } - .el-pagination__jump { - color: var(--o-color-info2); - } - .btn-prev, - .btn-next { - border: 1px solid var(--o-color-control1); - &:hover { - border-color: var(--o-color-control2); - } - .el-icon { - font-size: 18px; - } - &:disabled { - border-color: var(--o-color-control1-light); - } - &:focus { - border-color: var(--o-color-primary3) !important; - } - } -} -.el-input__wrapper { - box-shadow: none !important; - border: 1px solid var(--o-color-control1); - background-color: var(--o-color-fill2); - --el-disabled-bg-color: var(--o-color-fill2); - --el-pagination-button-color: var(--o-color-info1); - &:hover { - border-color: var(--o-color-control2); - } -} diff --git a/docs/.vitepress/src/assets/style/element-plus/popper.scss b/docs/.vitepress/src/assets/style/element-plus/popper.scss deleted file mode 100644 index bdbe23c956b26bee822ab2a3119c59fcb1772538..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/element-plus/popper.scss +++ /dev/null @@ -1,8 +0,0 @@ -.el-popper { - --el-bg-color-overlay: var(--o-color-fill2); - --el-border-color-light: var(--o-color-control1); - margin: -7px 0 0; - .el-popper__arrow { - display: none; - } -} diff --git a/docs/.vitepress/src/assets/style/element-plus/scrollbar.scss b/docs/.vitepress/src/assets/style/element-plus/scrollbar.scss deleted file mode 100644 index e4f6528641637fc77379c8f057fb15878e3721b1..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/element-plus/scrollbar.scss +++ /dev/null @@ -1,6 +0,0 @@ -div.el-scrollbar { - --el-scrollbar-bg-color: var(--o-color-control1); - --el-scrollbar-hover-bg-color: var(--o-color-control2); - --el-scrollbar-opacity: 1; - --el-scrollbar-hover-opacity: 1; -} diff --git a/docs/.vitepress/src/assets/style/element-plus/select.scss b/docs/.vitepress/src/assets/style/element-plus/select.scss deleted file mode 100644 index ecfe124ce0524303545059e5987a68224eaeee98..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/element-plus/select.scss +++ /dev/null @@ -1,23 +0,0 @@ -.el-select { - .el-input { - &.is-focus { - .el-input__wrapper { - box-shadow: none !important; - } - } - } -} - -.el-select-dropdown { - .el-select-dropdown__item { - color: var(--o-color-info2); - &:hover, - &.hover { - background-color: var(--o-color-control2-light) !important; - } - &.selected { - background-color: var(--o-color-control3-light) !important; - color: var(--o-color-info1); - } - } -} diff --git a/docs/.vitepress/src/assets/style/element-plus/slider.scss b/docs/.vitepress/src/assets/style/element-plus/slider.scss deleted file mode 100644 index b696a1536aad10c055a528524f4993e798aad34f..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/element-plus/slider.scss +++ /dev/null @@ -1,98 +0,0 @@ -@use '@/assets/style/mixin/screen.scss' as *; -@use '@/assets/style/mixin/font.scss' as *; - -.el-slider { - --el-slider-height: 8px; - --el-slider-border-radius: 8px; - --el-slider-button-wrapper-offset: -13px; - --el-slider-runway-bg-color: var(--o-color-fill1); - - height: 8px; - padding-left: 4px; - @include respond-to('<=pad_v') { - --el-slider-height: 12px; - --el-slider-border-radius: 12px; - - padding: 0 4px; - height: 12px; - } - - .el-slider__bar { - --el-slider-height: 10px; - - background: linear-gradient(90deg, #07caff 0%, #5882ff 100%); - top: -1px; - left: -4px !important; - @include respond-to('<=pad_v') { - --el-slider-height: 16px; - - top: -2px; - } - } - - .el-slider__button-wrapper + div { - transform: translateY(2px); - position: relative; - z-index: 2; - @include respond-to('<=pad_v') { - transform: translateY(5px); - } - - & + div { - transform: translateY(3px); - @include respond-to('<=pad_v') { - transform: translateY(4px); - } - - & > .el-slider__stop:nth-of-type(1) { - transform: translateX(2px); - } - } - } - - .el-slider__marks-text { - opacity: 0; - margin-top: 0; - @include respond-to('<=pad_v') { - opacity: 1; - top: -48px; - color: var(--o-color-info1); - @include text2; - } - } - - .el-slider__stop { - width: 2px; - height: 2px; - background-color: var(--o-color-info3); - @include respond-to('<=pad_v') { - width: 3px; - height: 3px; - } - } - - .el-slider__marks-stop { - background-color: var(--o-color-fill2); - - &:last-child { - transform: translate(-6px, -1px); - background-color: var(--o-color-info3); - } - } - - .el-slider__button { - position: relative; - box-shadow: var(--o-shadow-1); - width: 20px; - height: 20px; - border: 6px solid var(--o-color-fill2); - background-color: var(--o-color-link1); - - &::after { - content: ''; - display: inline-block; - height: 100%; - vertical-align: middle; - } - } -} diff --git a/docs/.vitepress/src/assets/style/element-plus/table.scss b/docs/.vitepress/src/assets/style/element-plus/table.scss deleted file mode 100644 index f47cb45cddd0ad6c4c7b322e233bc0fb5c0d9d73..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/element-plus/table.scss +++ /dev/null @@ -1,119 +0,0 @@ -@use '../mixin/font.scss' as *; -#app .el-table { - --el-table-header-bg-color: var(--o-color-control3-light); - --el-table-border-color: var(--o-color-control4); - --el-table-tr-bg-color: var(--o-color-fill2); - --el-table-expanded-cell-bg-color: var(--o-color-fill2); - --el-table-bg-color: var(--o-color-fill2); - --el-table-row-hover-bg-color: var(--o-color-control2-light); - border-radius: 4px; - --el-table-border: 1px solid var(--o-color-control4); - border-spacing: 0; - color: var(--o-color-info1); - @include text1; - &.is-scrolling-right .el-table-fixed-column--left.is-last-column.el-table__cell, - &.is-scrolling-middle .el-table-fixed-column--left.is-last-column.el-table__cell { - border-right: 1px solid transparent !important; - } - - .el-table__row { - &.hover-row { - .el-table-fixed-column--left, - .el-table-fixed-column--right { - background: var(--el-table-row-hover-bg-color); - } - } - } - .el-table__cell { - padding: 12px 0; - transition: none; - .cell { - padding: 0 20px; - } - &.el-table-fixed-column--left, - &.el-table-fixed-column--right { - background: var(--el-table-tr-bg-color); - } - } - - thead { - tr { - &:first-child { - th { - &.el-table__cell { - &:first-child { - border-radius: 4px 0 0 0; - } - &:last-child { - border-radius: 0 4px 0 0; - } - } - } - } - } - th { - font-weight: 500; - color: var(--o-color-info1); - border-bottom: 0 none; - @include text1; - &.el-table__cell { - background: var(--el-table-header-bg-color); - - &.el-table-fixed-column--left, - &.el-table-fixed-column--right { - background: var(--el-table-header-bg-color); - } - } - } - } - &.el-table--border { - &::after, - &::before { - display: none; - } - } - tr:last-child { - td { - border-bottom: 0; - &:first-child { - border-radius: 0 0 0 4px; - } - &:last-child { - border-radius: 0 0 4px 0; - } - } - } - - td, - th:not([rowspan='1']) { - &:first-child { - .cell { - padding-left: 32px !important; - } - } - &:last-child { - .cell { - padding-right: 32px !important; - } - } - } - - .el-table__expand-icon { - display: flex; - align-items: center; - > .el-icon { - font-size: 16px; - color: var(--o-color-info1); - } - } - .el-table__placeholder { - display: none; - } - .el-scrollbar__wrap { - padding: 1px 0; - } - - .el-table__empty-block { - min-height: 250px; - } -} diff --git a/docs/.vitepress/src/assets/style/element-plus/var.scss b/docs/.vitepress/src/assets/style/element-plus/var.scss deleted file mode 100644 index 6c9b005a8646460a407644e0abb70e4f86d3dfa3..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/element-plus/var.scss +++ /dev/null @@ -1,19 +0,0 @@ -@forward 'element-plus/theme-chalk/src/common/var.scss' with ( - $colors: ( - 'primary': ( - 'base': #002fa7, - ), - 'success': ( - 'base': #82c04d, - ), - 'warning': ( - 'base': #f0934b, - ), - 'danger': ( - 'base': #f3524d, - ), - 'error': ( - 'base': #f3524d, - ), - ) -); diff --git a/docs/.vitepress/src/assets/style/global.scss b/docs/.vitepress/src/assets/style/global.scss deleted file mode 100644 index a30bb9d5431bf5aa51f7a9fa20cfb7e3f58aa2c8..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/global.scss +++ /dev/null @@ -1,94 +0,0 @@ -html { - --layout-pkg-radius: 4px; -} -:root { - --o-radius_control-xs: 4px; - --o-radius_control-s: 4px; - --o-radius_control-m: 4px; - --o-radius_control-l: 4px; - - --el-box-shadow-light: var(--o-shadow-2); - --el-color-primary: var(--o-color-primary1) !important; -} - -// tag -.tags-box { - display: flex; - margin: 12px 0 0; - :deep(.o-tag-icon) { - width: 16px; - height: 16px; - } - > a + a { - margin-left: 8px; - } - .o-tag { - cursor: pointer; - --tag-padding: 2px 4px; - --tag-bd-color: var(--o-color-control1-light); - &.image-icon .o-icon { - color: #007af0; - } - &.epkg-icon .o-icon { - color: #e00070; - } - &.rpm-icon .o-icon { - color: #00a7b3; - } - &:hover { - --tag-bg-color: var(--o-color-control2-light); - } - .o-tag-icon { - height: 16px; - } - svg { - width: 16px; - height: 16px; - color: currentColor; - } - } - .o-tag + .o-tag { - margin-left: 8px; - } -} - -.o-icon { - svg { - fill: currentColor; - } -} - -.o-tab-nav-active { - font-weight: 500; -} - -.o-card-pkg { - .desc { - margin-top: 8px; - color: var(--o-color-info2); - overflow: hidden; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - position: relative; - word-break: break-all; - height: 48px; - --linear-gradient: var(--o-mixedgray-1); - &.dark { - --linear-gradient: var(--o-mixedgray-4); - } - @include text1; - &::after { - background-image: linear-gradient(90deg, rgba(var(--linear-gradient), 0), rgba(var(--linear-gradient), 0.8) 59%, var(--o-color-control-light) 100%); - bottom: 0; - content: ''; - height: 24px; - pointer-events: none; - position: absolute; - right: 0; - width: 4em; - } - span { - color: var(--o-color-primary1); - } - } -} diff --git a/docs/.vitepress/src/assets/style/highlight/atom-one-dark.scss b/docs/.vitepress/src/assets/style/highlight/atom-one-dark.scss deleted file mode 100644 index 5add95da36e531a9646b27e933ad7c63c429d4f4..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/highlight/atom-one-dark.scss +++ /dev/null @@ -1,105 +0,0 @@ -[class='dark'] { - pre code.hljs { - display: block; - overflow-x: auto; - padding: 1em; - } - - code.hljs { - padding: 3px 5px; - } - - /* - -Atom One Dark by Daniel Gamage -Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax - -base: #282c34 -mono-1: #abb2bf -mono-2: #818896 -mono-3: #5c6370 -hue-1: #56b6c2 -hue-2: #61aeee -hue-3: #c678dd -hue-4: #98c379 -hue-5: #e06c75 -hue-5-2: #be5046 -hue-6: #d19a66 -hue-6-2: #e6c07b - -*/ - .hljs { - color: #abb2bf; - background: #2b2b2f; - } - - .hljs-comment, - .hljs-quote { - color: #5c6370; - font-style: italic; - } - - .hljs-doctag, - .hljs-keyword, - .hljs-formula { - color: #c678dd; - } - - .hljs-section, - .hljs-name, - .hljs-selector-tag, - .hljs-deletion, - .hljs-subst { - color: #e06c75; - } - - .hljs-literal { - color: #56b6c2; - } - - .hljs-string, - .hljs-regexp, - .hljs-addition, - .hljs-attribute, - .hljs-meta .hljs-string { - color: #98c379; - } - - .hljs-attr, - .hljs-variable, - .hljs-template-variable, - .hljs-type, - .hljs-selector-class, - .hljs-selector-attr, - .hljs-selector-pseudo, - .hljs-number { - color: #d19a66; - } - - .hljs-symbol, - .hljs-bullet, - .hljs-link, - .hljs-meta, - .hljs-selector-id, - .hljs-title { - color: #61aeee; - } - - .hljs-built_in, - .hljs-title.class_, - .hljs-class .hljs-title { - color: #e6c07b; - } - - .hljs-emphasis { - font-style: italic; - } - - .hljs-strong { - font-weight: bold; - } - - .hljs-link { - text-decoration: underline; - } -} \ No newline at end of file diff --git a/docs/.vitepress/src/assets/style/highlight/atom-one-light.scss b/docs/.vitepress/src/assets/style/highlight/atom-one-light.scss deleted file mode 100644 index a9c5c2bba06e2a7c59a848dbc507f1a69d6149e3..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/highlight/atom-one-light.scss +++ /dev/null @@ -1,103 +0,0 @@ -pre code.hljs { - display: block; - overflow-x: auto; - padding: 1em; -} - -code.hljs { - padding: 3px 5px; -} - -/* - -Atom One Light by Daniel Gamage -Original One Light Syntax theme from https://github.com/atom/one-light-syntax - -base: #fafafa -mono-1: #383a42 -mono-2: #686b77 -mono-3: #a0a1a7 -hue-1: #0184bb -hue-2: #4078f2 -hue-3: #a626a4 -hue-4: #50a14f -hue-5: #e45649 -hue-5-2: #c91243 -hue-6: #986801 -hue-6-2: #c18401 - -*/ -.hljs { - color: #383a42; - background: #f3f3f5; -} - -.hljs-comment, -.hljs-quote { - color: #a0a1a7; - font-style: italic; -} - -.hljs-doctag, -.hljs-keyword, -.hljs-formula { - color: #a626a4; -} - -.hljs-section, -.hljs-name, -.hljs-selector-tag, -.hljs-deletion, -.hljs-subst { - color: #e45649; -} - -.hljs-literal { - color: #0184bb; -} - -.hljs-string, -.hljs-regexp, -.hljs-addition, -.hljs-attribute, -.hljs-meta .hljs-string { - color: #50a14f; -} - -.hljs-attr, -.hljs-variable, -.hljs-template-variable, -.hljs-type, -.hljs-selector-class, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-number { - color: #986801; -} - -.hljs-symbol, -.hljs-bullet, -.hljs-link, -.hljs-meta, -.hljs-selector-id, -.hljs-title { - color: #4078f2; -} - -.hljs-built_in, -.hljs-title.class_, -.hljs-class .hljs-title { - color: #c18401; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} - -.hljs-link { - text-decoration: underline; -} \ No newline at end of file diff --git a/docs/.vitepress/src/assets/style/highlight/index.scss b/docs/.vitepress/src/assets/style/highlight/index.scss deleted file mode 100644 index ebc41ab6a58bc1ed468d33e69c1376d3ca2a2acb..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/highlight/index.scss +++ /dev/null @@ -1,2 +0,0 @@ -@import './atom-one-light.scss'; -@import './atom-one-dark.scss'; \ No newline at end of file diff --git a/docs/.vitepress/src/assets/style/markdown.scss b/docs/.vitepress/src/assets/style/markdown.scss deleted file mode 100644 index 6e3db473fc8043edf817a0bc04bf223b98fbf2c7..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/markdown.scss +++ /dev/null @@ -1,326 +0,0 @@ -@use 'github-markdown-css/github-markdown-light.css' as *; -@use './highlight/index.scss' as *; -@use './mixin/common.scss' as *; - -.markdown-body { - --o-gap-1: 4px; - --o-gap-2: 8px; - --o-gap-3: 12px; - --o-gap-4: 16px; - --o-gap-5: 24px; - --o-gap-6: 32px; - --o-gap-7: 40px; - - @include respond-to('<=laptop') { - --o-gap-1: 4px; - --o-gap-2: 8px; - --o-gap-3: 8px; - --o-gap-4: 12px; - --o-gap-5: 16px; - --o-gap-6: 24px; - --o-gap-7: 24px; - } - - @include respond-to('<=pad') { - --o-gap-1: 4px; - --o-gap-2: 8px; - --o-gap-3: 8px; - --o-gap-4: 8px; - --o-gap-5: 12px; - --o-gap-6: 16px; - --o-gap-7: 16px; - } - - @include respond-to('<=pad_v') { - --o-gap-1: 4px; - --o-gap-2: 8px; - --o-gap-3: 8px; - --o-gap-4: 8px; - --o-gap-5: 12px; - --o-gap-6: 16px; - --o-gap-7: 16px; - } - - @include respond-to('<=phone') { - --o-gap-1: 4px; - --o-gap-2: 8px; - --o-gap-3: 12px; - --o-gap-4: 16px; - --o-gap-5: 24px; - --o-gap-6: 28px; - --o-gap-7: 12px; - } -} - -.markdown-body { - background: var(--o-color-fill2); - color: var(--o-color-info2); - font-family: inherit; - min-height: auto; - @include text1; - - & > div *:first-child { - margin-top: 0 !important; - } - - div[class*='language-'] { - position: relative; - margin-top: var(--o-gap-2); - } - - p { - margin-top: 0 !important; - margin-bottom: var(--o-gap-2); - } - - ol { - list-style-type: decimal !important; - } - - ul { - list-style-type: disc; - } - - ol, - ul { - padding-left: var(--o-gap-5); - margin-top: var(--o-gap-2); - } - - li + li { - margin-top: 0; - } - - li li { - &:first-child { - margin-top: 8px !important; - } - &:last-child { - margin-bottom: 8px; - } - } - - h1, - h2, - h3, - h4, - h5, - h6 { - word-break: break-all; - color: var(--o-color-info1); - padding: 0; - border: none; - font-weight: 500; - } - - h1 { - @include h2; - margin-top: calc(var(--o-gap-6)); - margin-bottom: var(--o-gap-6); - } - - h2 { - @include h4; - margin-top: calc(var(--o-gap-6)); - margin-bottom: var(--o-gap-3); - } - - h3 { - @include text2; - margin-top: var(--o-gap-3); - margin-bottom: var(--o-gap-3); - } - - h4 { - @include text1; - margin-top: var(--o-gap-3); - margin-bottom: var(--o-gap-3); - } - - hr { - height: 1px; - background-color: var(--o-color-control4); - } - - a { - color: var(--o-color-link1); - - @include hover { - color: var(--o-color-link2); - } - } - - img { - border-radius: var(--o-radius-m); - padding: var(--o-gap-2); - margin: 0 auto; - background-color: var(--o-color-fill2); - margin-left: -8px; - } - - code { - border-radius: var(--layout-pkg-radius); - background-color: var(--o-color-control2-light); - margin: 0 4px; - } - p code:first-child { - margin-left: 0; - } - - blockquote { - color: var(--o-color-info2); - padding: 12px 16px; - margin: var(--o-gap-3) 0; - border-left: 0; - background-color: var(--o-color-control2-light); - border-radius: var(--layout-pkg-radius); - li { - margin-top: var(--o-gap-2); - } - img { - padding: 0; - margin-left: 0; - background-color: transparent; - } - } - - pre { - position: relative; - border-radius: var(--layout-pkg-radius); - background-color: var(--o-color-control2-light); - padding: 0; - overflow: hidden; - margin-bottom: var(--o-gap-2); - - code { - display: block; - overflow-x: auto; - padding: 16px 36px 16px 16px; - margin: 0; - @include scrollbar; - } - } - - table { - --table-padding: var(--o-gap-3) var(--o-gap-6); - --table-radius: var(--layout-pkg-radius); - border-spacing: 0; - border-radius: var(--table-radius); - - @include respond-to('<=laptop') { - --table-head-cell-padding: 8px 16px; - } - - @include respond-to('<=pad') { - --table-head-cell-padding: 9px 12px; - } - - @include respond-to('<=phone') { - --table-head-cell-padding: 7px 12px; - } - - th { - background-color: var(--o-color-control3-light); - text-align: left; - border-color: var(--o-color-control3-light) !important; - } - - th, - td { - box-sizing: border-box; - padding: var(--table-padding); - color: var(--o-color-info1); - border-color: var(--o-color-control4); - @include text1; - } - tr { - background: var(--o-color-fill2) !important; - border: 0 !important; - } - - td { - padding: var(--o-gap-4) var(--o-gap-6); - box-sizing: border-box; - } - * { - margin-bottom: 0; - } - * + * { - margin-top: var(--o-gap-2); - } - - li { - &:first-child { - margin-top: 0 !important; - } - &:last-child { - margin-bottom: 0; - } - } - } - - .lang { - display: none; - } - - .vp-adaptive-theme { - @include hover { - .copy { - opacity: 1; - } - } - @include respond-to('phone') { - .copy { - opacity: 1; - width: 16px; - height: 16px; - background-size: 14px; - } - } - } - - .copy { - cursor: pointer; - position: absolute; - top: var(--o-gap-4); - right: var(--o-gap-4); - z-index: 3; - border-radius: 4px; - width: 24px; - height: 24px; - background-image: url('@/assets/svg-icons/icon-copy.svg'); - background-position: 50%; - background-size: 20px; - background-repeat: no-repeat; - border: none; - opacity: 0; - transition: all var(--o-duration-m1) var(--o-easing-standard-in); - @include respond-to('phone') { - top: 4px; - } - } - - pre.mermaid { - background-color: transparent; - } - - div.mermaid { - svg[aria-roledescription="error"] { - display: none; - } - } - - .vp-code { - &.shiki { - span { - color: var(--shiki-light, inherit); - } - } - } -} - -@include in-dark { - .markdown-body img { - @include img-in-dark; - } -} diff --git a/docs/.vitepress/src/assets/style/mixin/common.scss b/docs/.vitepress/src/assets/style/mixin/common.scss deleted file mode 100644 index b3435e070ca02f05f75124c5111962db6bb9a4f9..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/mixin/common.scss +++ /dev/null @@ -1,65 +0,0 @@ -@use '@/assets/style/mixin/screen.scss' as *; - -@mixin in-dark { - [data-o-theme='dark'] { - @content; - } -} - -@mixin text-truncate($line-clamp: 1) { - overflow: hidden; - text-overflow: ellipsis; - word-break: break-all; - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: $line-clamp; -} - -@mixin img-in-dark { - filter: brightness(80%) grayscale(20%) contrast(1.2); -} - -@mixin scrollbar { - &::-webkit-scrollbar-track { - border-radius: 4px; - background-color: var(--o-color-fill1); - } - - &::-webkit-scrollbar { - width: 4px; - height: 4px; - background-color: var(--o-color-fill1); - } - - &::-webkit-scrollbar-thumb { - border-radius: 4px; - background: var(--o-color-control1); - } -} - -.hover-icon-rotate { - .o-icon { - transition: all var(--o-duration-m1) var(--o-easing-standard-in); - } - - @include hover { - .o-icon { - transform: rotate(-180deg); - } - } -} - -@mixin x-svg-hover() { - & { - overflow: hidden; - } - - svg { - transition: all var(--o-duration-m1) var(--o-easing-standard-in); - } - @include hover { - svg { - transform: rotate(180deg); - } - } -} diff --git a/docs/.vitepress/src/assets/style/mixin/font.scss b/docs/.vitepress/src/assets/style/mixin/font.scss deleted file mode 100644 index 66734578a873d0cc06f34bfcea073278905585e3..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/mixin/font.scss +++ /dev/null @@ -1,270 +0,0 @@ -@use '@/assets/style/mixin/screen.scss' as *; - -// 一级数据展示 -@mixin display1 { - font-size: 56px; - line-height: 80px; - @include respond-to('laptop') { - font-size: 48px; - line-height: 64px; - } - @include respond-to('pad_h') { - font-size: 40px; - line-height: 56px; - } - @include respond-to('pad_v') { - font-size: 40px; - line-height: 56px; - } - @include respond-to('phone') { - font-size: 22px; - line-height: 30px; - } -} - -// 二级数据展示 -@mixin display2 { - font-size: 48px; - line-height: 64px; - @include respond-to('laptop') { - font-size: 40px; - line-height: 56px; - } - @include respond-to('pad_h') { - font-size: 32px; - line-height: 44px; - } - @include respond-to('pad_v') { - font-size: 32px; - line-height: 44px; - } - @include respond-to('phone') { - font-size: 20px; - line-height: 28px; - } -} - -// 三级数据展示 -@mixin display3 { - font-size: 40px; - line-height: 56px; - @include respond-to('laptop') { - font-size: 32px; - line-height: 44px; - } - @include respond-to('pad_h') { - font-size: 24px; - line-height: 32px; - } - @include respond-to('pad_v') { - font-size: 22px; - line-height: 30px; - } - @include respond-to('phone') { - font-size: 18px; - line-height: 26px; - } -} - -// 一级标题 -@mixin h1 { - font-size: 32px; - line-height: 44px; - @include respond-to('laptop') { - font-size: 20px; - line-height: 28px; - } - @include respond-to('pad_h') { - font-size: 20px; - line-height: 28px; - } - @include respond-to('pad_v') { - font-size: 18px; - line-height: 26px; - } - @include respond-to('phone') { - font-size: 16px; - line-height: 24px; - } -} - -// 二级标题 -@mixin h2 { - font-size: 24px; - line-height: 32px; - @include respond-to('laptop') { - font-size: 20px; - line-height: 28px; - } - @include respond-to('pad_h') { - font-size: 18px; - line-height: 26px; - } - @include respond-to('pad_v') { - font-size: 18px; - line-height: 26px; - } - @include respond-to('phone') { - font-size: 16px; - line-height: 24px; - } -} - -// 三级标题 -@mixin h3 { - font-size: 22px; - line-height: 30px; - @include respond-to('laptop') { - font-size: 18px; - line-height: 26px; - } - @include respond-to('pad_h') { - font-size: 16px; - line-height: 24px; - } - @include respond-to('pad_v') { - font-size: 16px; - line-height: 24px; - } - @include respond-to('phone') { - font-size: 16px; - line-height: 24px; - } -} - -// 四级标题 -@mixin h4 { - font-size: 20px; - line-height: 28px; - @include respond-to('laptop') { - font-size: 18px; - line-height: 26px; - } - @include respond-to('pad_h') { - font-size: 16px; - line-height: 24px; - } - @include respond-to('pad_v') { - font-size: 16px; - line-height: 24px; - } - @include respond-to('phone') { - font-size: 14px; - line-height: 22px; - } -} - -// 常规正文 -@mixin text1 { - font-size: 16px; - line-height: 24px; - @include respond-to('laptop') { - font-size: 14px; - line-height: 22px; - } - @include respond-to('pad_h') { - font-size: 14px; - line-height: 22px; - } - @include respond-to('pad_v') { - font-size: 14px; - line-height: 22px; - } - @include respond-to('phone') { - font-size: 12px; - line-height: 18px; - } -} - -// 大号正文 -@mixin text2 { - font-size: 18px; - line-height: 26px; - @include respond-to('laptop') { - font-size: 16px; - line-height: 24px; - } - @include respond-to('pad_h') { - font-size: 14px; - line-height: 22px; - } - @include respond-to('pad_v') { - font-size: 14px; - line-height: 22px; - } - @include respond-to('phone') { - font-size: 14px; - line-height: 22px; - } -} - -// 提示文本1 -@mixin tip1 { - font-size: 14px; - line-height: 22px; - @include respond-to('laptop') { - font-size: 12px; - line-height: 18px; - } - @include respond-to('pad_h') { - font-size: 12px; - line-height: 18px; - } - @include respond-to('pad_v') { - font-size: 12px; - line-height: 18px; - } - @include respond-to('phone') { - font-size: 10px; - line-height: 16px; - } -} - -// 提示文本2 -@mixin tip2 { - font-size: 12px; - line-height: 18px; - @include respond-to('laptop') { - font-size: 12px; - line-height: 18px; - } - @include respond-to('pad_h') { - font-size: 12px; - line-height: 18px; - } - @include respond-to('pad_v') { - font-size: 12px; - line-height: 18px; - } - @include respond-to('phone') { - font-size: 10px; - line-height: 16px; - } -} - -// 提示文本1 -@mixin tip1-response-max-height { - font-size: 14px; - line-height: 22px; - max-height: 44px; - @include respond-to('laptop') { - font-size: 12px; - line-height: 18px; - max-height: 36px; - } - @include respond-to('pad_h') { - font-size: 12px; - line-height: 18px; - max-height: 36px; - } - @include respond-to('pad_v') { - font-size: 12px; - line-height: 18px; - max-height: 36px; - } - @include respond-to('phone') { - font-size: 10px; - line-height: 16px; - max-height: 32px; - } -} diff --git a/docs/.vitepress/src/assets/style/mixin/screen.scss b/docs/.vitepress/src/assets/style/mixin/screen.scss deleted file mode 100644 index 4ae3eddaa5eac6bdad0251f31e87f70f5f6d76ac..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/mixin/screen.scss +++ /dev/null @@ -1,73 +0,0 @@ -// 断点定义 -$breakpoints: ( - // phone - 'phone': (0, 600px), - '>phone': 601px, - // pad - 'pad': (601px, 1200px), - '<=pad': (0, 1200px), - '>pad': 1201px, - // pad-v - 'pad_v': (601px, 840px), - '<=pad_v': (0, 840px), - '>pad_v': 841px, - // pad-h - 'pad_h': (841px, 1200px), - // laptop - 'laptop': (1201px, 1440px), - '<=laptop': (0, 1440px), - '>laptop': 1441px, - 'pad-laptop': (601px, 1440px), - 'pad_v-laptop': (841px, 1440px) -); - -@mixin respond-to($breakname) { - $bp: map-get($breakpoints, $breakname); - @if type-of($bp) == 'list' { - $min: nth($bp, 1); - $max: nth($bp, 2); - @if $min == 0 { - @media (max-width: $max) { - @content; - } - } @else { - @media (min-width: $min) and (max-width: $max) { - @content; - } - } - } @else { - @media (min-width: $bp) { - @content; - } - } -} - -@mixin hoverable($hover: hover) { - @media (hover: $hover) { - @content; - } -} - -@mixin hover() { - @media (hover: hover) { - &:hover { - @content; - } - } -} - -@mixin me-hover() { - @content; - @media (hover: hover) { - &:hover { - @content; - } - } -} - -@mixin x-hover() { - transition: all var(--o-duration-m1) var(--o-easing-standard-in); - @include hover { - transform: rotate(180deg); - } -} diff --git a/docs/.vitepress/src/assets/style/theme/anchor.scss b/docs/.vitepress/src/assets/style/theme/anchor.scss deleted file mode 100644 index bcd353e9d739c037473e8f4ffd6c03d4a81cc1ff..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/anchor.scss +++ /dev/null @@ -1,11 +0,0 @@ -.o-anchor { - --anchor-indicator-height: 100%; - .o-anchor-item-link { - &:hover { - --anchor-item-link-bg-color-hover: none; - } - &.is-active { - --anchor-item-link-bg-color-active: none; - } - } -} diff --git a/docs/.vitepress/src/assets/style/theme/button.scss b/docs/.vitepress/src/assets/style/theme/button.scss deleted file mode 100644 index 51ea368e52a1f0acaab6fe2f355923a29c43bc8c..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/button.scss +++ /dev/null @@ -1,3 +0,0 @@ -.o-btn { - --btn-radius: var(--btn-height); -} diff --git a/docs/.vitepress/src/assets/style/theme/card.scss b/docs/.vitepress/src/assets/style/theme/card.scss deleted file mode 100644 index 6dc7d27bbb6a5ad57ad5f94856198077c22692e1..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/card.scss +++ /dev/null @@ -1,17 +0,0 @@ -@use '../mixin/common.scss' as *; -.o-card { - --card-cover-radius: var(--o-radius-xs); - --card-radius: var(--o-radius-xs); -} -.o-card-cover-h { - --card-cover-padding: 0; -} -a.o-card:hover .o-card-title { - color: var(--o-color-primary1); -} - -@include in-dark { - .o-figure img { - @include img-in-dark; - } -} diff --git a/docs/.vitepress/src/assets/style/theme/dark.token.css b/docs/.vitepress/src/assets/style/theme/dark.token.css deleted file mode 100644 index 61682e6302cca48e0a5bc7623319c735cfcc6f12..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/dark.token.css +++ /dev/null @@ -1,2194 +0,0 @@ -/* theme: opendesign.dark */ -[data-o-theme="dark"] { - /** - * @name - * @type palette - * @group white - * @description - */ - --o-white: 255, 255, 255; - /** - * @name - * @type palette - * @group black - * @description - */ - --o-black: 0, 0, 0; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-1: 14, 26, 69; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-2: 18, 34, 87; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-3: 29, 51, 119; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-4: 42, 72, 158; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-5: 51, 91, 196; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-6: 67, 116, 242; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-7: 104, 142, 237 ; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-8: 140, 171, 234; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-9: 176, 199, 241; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-10: 215, 227, 248; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-1: 81, 46, 9; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-2: 121, 75, 15; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-3: 161, 107, 22; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-4: 202, 143, 30; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-5: 242, 183, 38; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-6: 245, 202, 80; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-7: 247, 219, 122; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-8: 250, 234, 166; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-9: 252, 246, 210; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-10: 254, 251, 237; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-1: 77, 24, 0; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-2: 120, 42, 1; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-3: 163, 68, 8; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-4: 207, 97, 19; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-5: 250, 130, 33; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-6: 251, 143, 43; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-7: 252, 174, 91; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-8: 253, 202, 139; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-9: 254, 227, 188; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-10: 255, 248, 237; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-1: 77, 0, 17; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-2: 115, 3, 24; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-3: 153, 9, 31; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-4: 192, 17, 37; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-5: 230, 28, 43; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-6: 235, 35, 45; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-7: 240, 82, 85; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-8: 245, 132, 130; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-9: 250, 183, 180; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-10: 255, 234, 232; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-1: 0, 77, 42; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-2: 2, 102, 53; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-3: 10, 127, 66; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-4: 22, 152, 80; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-5: 36, 177, 95; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-6: 51, 193, 104; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-7: 90, 208, 131; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-8: 135, 224, 163; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-9: 185, 239, 200; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-10: 240, 255, 244; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-1: 77, 30, 0; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-2: 116, 51, 0; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-3: 154, 76, 0; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-4: 193, 105, 0; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-5: 231, 137, 0; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-6: 236, 165, 47; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-7: 241, 191, 96; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-8: 245, 215, 147; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-9: 250, 237, 200; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-10: 253, 247, 232; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-1: 53, 70, 0; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-2: 82, 105, 0; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-3: 112, 141, 1; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-4: 143, 176, 2; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-5: 175, 211, 5; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-6: 184, 220, 48; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-7: 196, 229, 95; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-8: 212, 237, 145; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-9: 231, 246, 198; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-10: 244, 251, 231; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-1: 33, 60, 7; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-2: 51, 90, 11; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-3: 70, 119, 16; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-4: 91, 149, 21; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-5: 112, 179, 27; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-6: 184, 220, 48; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-7: 166, 209, 103; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-8: 195, 225, 148; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-9: 225, 240, 199; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-10: 242, 247, 231; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-1: 0, 60, 48; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-2: 0, 90, 71; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-3: 0, 119, 93; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-4: 0, 149, 113; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-5: 0, 179, 133; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-6: 39, 194, 152; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-7: 84, 209, 173; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-8: 135, 225, 197; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-9: 192, 240, 224; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-10: 228, 247, 241; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-1: 0, 52, 60; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-2: 0, 79, 90; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-3: 0, 107, 119; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-4: 0, 137, 149; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-5: 39, 186, 194; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-6: 84, 205, 209; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-7: 92, 208, 212; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-8: 135, 223, 225; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-9: 192, 240, 240; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-10: 228, 247, 247; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-1: 0, 47, 76; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-2: 0, 72, 115; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-3: 0, 99, 153; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-4: 0, 127, 191; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-5: 0, 156, 229; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-6: 47, 178, 234; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-7: 96, 198, 239; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-8: 147, 218, 245; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-9: 200, 237, 250; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-10: 232, 247, 252; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-1: 0, 43, 97; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-2: 0, 61, 133; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-3: 0, 80, 169; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-4: 0, 100, 204; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-5: 0, 122, 240; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-6: 49, 151, 243; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-7: 98, 178, 246; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-8: 149, 205, 249; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-9: 202, 231, 252; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-10: 233, 245, 254; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-1: 0, 0, 0; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-2: 18, 18, 20; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-3: 26, 26, 28; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-4: 36, 36, 39; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-5: 43, 43, 47; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-6: 53, 53, 57; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-7: 63, 63, 67; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-8: 85, 85, 88; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-9: 118, 118, 122; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-10: 156, 156, 159; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-11: 181, 181, 185; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-12: 208, 208, 210; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-13: 235, 235, 238; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-14: 255,255, 255; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-1: 5, 19, 101; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-2: 10, 28, 118; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-3: 16, 38, 138; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-4: 23, 50, 159; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-5: 31, 63, 179; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-6: 66, 96, 194; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-7: 106, 131, 209; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-8: 150, 170, 225; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-9: 209, 218, 241; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-10: 232, 236, 247; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-1: 34, 0, 109; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-2: 39, 2, 130; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-3: 46, 7, 150; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-4: 53, 13, 171; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-5: 61, 20, 191; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-6: 97, 62, 201; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-7: 150, 130, 223; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-8: 182, 169, 233; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-9: 217, 210, 244; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-10: 240, 237, 250; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-1: 60, 0, 97; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-2: 77, 0, 118; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-3: 95, 0, 138; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-4: 114, 0, 159; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-5: 135, 2, 179; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-6: 161, 41, 194; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-7: 187, 85, 209; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-8: 211, 136, 225; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-9: 234, 192, 240; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-10: 245, 228, 247; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-1: 81, 0, 51; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-2: 117, 0, 70; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-3: 153, 0, 86; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-4: 188, 0, 100; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-5: 224, 0, 112; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-6: 230, 46, 132; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-7: 236, 95, 156; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-8: 243, 146, 184; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-9: 249, 199, 217; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-10: 252, 232, 239; - /** - * @name - * @type color - * @group base - * @description - */ - --o-color-white: rgb(var(--o-white)); - /** - * @name - * @type color - * @group base - * @description - */ - --o-color-black: rgb(var(--o-black)); - /** - * @name - * @type color - * @group primary - * @description 常规 - */ - --o-color-primary1: rgb(var(--o-kleinblue-6)); - /** - * @name - * @type color - * @group primary - * @description 悬浮 - */ - --o-color-primary2: rgb(var(--o-kleinblue-5)); - /** - * @name - * @type color - * @group primary - * @description 激活 - */ - --o-color-primary3: rgb(var(--o-kleinblue-7)); - /** - * @name - * @type color - * @group primary - * @description 禁用 - */ - --o-color-primary4: rgb(var(--o-kleinblue-4)); - /** - * @name - * @type color - * @group primary - * @description 常规-浅 - */ - --o-color-primary1-light: rgb(var(--o-kleinblue-2)); - /** - * @name - * @type color - * @group primary - * @description 悬浮-浅 - */ - --o-color-primary2-light: rgb(var(--o-kleinblue-3)); - /** - * @name - * @type color - * @group primary - * @description 激活-浅 - */ - --o-color-primary3-light: rgb(var(--o-kleinblue-4)); - /** - * @name - * @type color - * @group primary - * @description 禁用-浅 - */ - --o-color-primary4-light: rgb(var(--o-kleinblue-1)); - /** - * @name - * @type color - * @group success - * @description 常规 - */ - --o-color-success1: rgb(var(--o-green-6)); - /** - * @name - * @type color - * @group success - * @description 悬浮 - */ - --o-color-success2: rgb(var(--o-green-4)); - /** - * @name - * @type color - * @group success - * @description 激活 - */ - --o-color-success3: rgb(var(--o-green-7)); - /** - * @name - * @type color - * @group success - * @description 禁用 - */ - --o-color-success4: rgb(var(--o-green-3)); - /** - * @name - * @type color - * @group success - * @description 常规-浅 - */ - --o-color-success1-light: rgb(var(--o-green-2)); - /** - * @name - * @type color - * @group success - * @description 悬浮-浅 - */ - --o-color-success2-light: rgb(var(--o-green-3)); - /** - * @name - * @type color - * @group success - * @description 激活-浅 - */ - --o-color-success3-light: rgb(var(--o-green-4)); - /** - * @name - * @type color - * @group success - * @description 禁用-浅 - */ - --o-color-success4-light: rgb(var(--o-green-1)); - /** - * @name - * @type color - * @group warning - * @description 常规 - */ - --o-color-warning1: rgb(var(--o-orange-6)); - /** - * @name - * @type color - * @group warning - * @description 悬浮 - */ - --o-color-warning2: rgb(var(--o-orange-4)); - /** - * @name - * @type color - * @group warning - * @description 激活 - */ - --o-color-warning3: rgb(var(--o-orange-7)); - /** - * @name - * @type color - * @group warning - * @description 禁用 - */ - --o-color-warning4: rgb(var(--o-orange-3)); - /** - * @name - * @type color - * @group warning - * @description 常规-浅 - */ - --o-color-warning1-light: rgb(var(--o-orange-2)); - /** - * @name - * @type color - * @group warning - * @description 悬浮-浅 - */ - --o-color-warning2-light: rgb(var(--o-orange-3)); - /** - * @name - * @type color - * @group warning - * @description 激活-浅 - */ - --o-color-warning3-light: rgb(var(--o-orange-4)); - /** - * @name - * @type color - * @group warning - * @description 禁用-浅 - */ - --o-color-warning4-light: rgb(var(--o-orange-1)); - /** - * @name - * @type color - * @group danger - * @description 常规 - */ - --o-color-danger1: rgb(var(--o-red-6)); - /** - * @name - * @type color - * @group danger - * @description 悬浮 - */ - --o-color-danger2: rgb(var(--o-red-4)); - /** - * @name - * @type color - * @group danger - * @description 激活 - */ - --o-color-danger3: rgb(var(--o-red-7)); - /** - * @name - * @type color - * @group danger - * @description 禁用 - */ - --o-color-danger4: rgb(var(--o-red-3)); - /** - * @name - * @type color - * @group danger - * @description 常规-浅 - */ - --o-color-danger1-light: rgb(var(--o-red-2)); - /** - * @name - * @type color - * @group danger - * @description 悬浮-浅 - */ - --o-color-danger2-light: rgb(var(--o-red-3)); - /** - * @name - * @type color - * @group danger - * @description 激活-浅 - */ - --o-color-danger3-light: rgb(var(--o-red-4)); - /** - * @name - * @type color - * @group danger - * @description 禁用-浅 - */ - --o-color-danger4-light: rgb(var(--o-red-1)); - /** - * @name - * @type color - * @group fill - * @description 一级填充:页面背景 - */ - --o-color-fill1: rgb(var(--o-mixedgray-3)); - /** - * @name - * @type color - * @group fill - * @description 二级填充:区块/卡片 - */ - --o-color-fill2: rgb(var(--o-mixedgray-4)); - /** - * @name - * @type color - * @group fill - * @description 三级填充:卡片 - */ - --o-color-fill3: rgb(var(--o-mixedgray-5)); - /** - * @name - * @type color - * @group control - * @description 常规,常用于边框 - */ - --o-color-control1: rgba(var(--o-mixedgray-14), 0.25); - /** - * @name - * @type color - * @group control - * @description 悬浮,常用于边框 - */ - --o-color-control2: rgba(var(--o-mixedgray-14), 0.6); - /** - * @name - * @type color - * @group control - * @description 激活,常用于边框 - */ - --o-color-control3: rgba(var(--o-mixedgray-14), 0.8); - /** - * @name - * @type color - * @group control - * @description 禁用,常用于边框 - */ - --o-color-control4: rgba(var(--o-mixedgray-14), 0.15); - /** - * @name - * @type color - * @group control - * @description 常规-浅,常用于背景 - */ - --o-color-control1-light: rgb(var(--o-mixedgray-7), 1.0); - /** - * @name - * @type color - * @group control - * @description 悬浮-浅,常用于背景 - */ - --o-color-control2-light: rgb(var(--o-mixedgray-5), 1); - /** - * @name - * @type color - * @group control - * @description 激活-浅,常用于背景 - */ - --o-color-control3-light: rgb(var(--o-mixedgray-6), 1); - /** - * @name - * @type color - * @group control - * @description 禁用-浅,常用于背景 - */ - --o-color-control4-light: rgb(var(--o-mixedgray-5), 1); - /** - * @name - * @type color - * @group control - * @description 很浅,常用于表格背景色 - */ - --o-color-control-light: rgb(var(--o-mixedgray-4), 1.0); - /** - * @name - * @type color - * @group info - * @description 一级/强调/标题 - */ - --o-color-info1: rgba(var(--o-mixedgray-14), 1.0); - /** - * @name - * @type color - * @group info - * @description 二级/次强调/正文 - */ - --o-color-info2: rgba(var(--o-mixedgray-14), 0.8); - /** - * @name - * @type color - * @group info - * @description 三级/辅助信息 - */ - --o-color-info3: rgba(var(--o-mixedgray-14), 0.6); - /** - * @name - * @type color - * @group info - * @description 置灰/禁用 - */ - --o-color-info4: rgba(var(--o-mixedgray-14), 0.4); - /** - * @name - * @type color - * @group info - * @description 一级/次强调/正文反色 - */ - --o-color-info1-inverse: rgba(var(--o-mixedgray-1), 1.0); - /** - * @name - * @type color - * @group info - * @description 二级/辅助信息反色 - */ - --o-color-info2-inverse: rgba(var(--o-mixedgray-1), 0.8); - /** - * @name - * @type color - * @group info - * @description 三级/辅助信息反色 - */ - --o-color-info3-inverse: rgba(var(--o-mixedgray-1), 0.6); - /** - * @name - * @type color - * @group info - * @description 置灰/禁用反色 - */ - --o-color-info4-inverse: rgba(var(--o-mixedgray-1), 0.4); - /** - * @name - * @type color - * @group mask - * @description 全局遮罩 - */ - --o-color-mask1: rgba(var(--o-mixedgray-1), 0.4); - /** - * @name - * @type color - * @group mask - * @description 局部遮罩 - */ - --o-color-mask2: rgba(var(--o-mixedgray-4), 0.2); - /** - * @name - * @type color - * @group link - * @description 常规 - */ - --o-color-link1: rgba(var(--o-kleinblue-6)); - /** - * @name - * @type color - * @group link - * @description 悬浮 - */ - --o-color-link2: rgba(var(--o-kleinblue-5)); - /** - * @name - * @type color - * @group link - * @description 激活 - */ - --o-color-link3: rgba(var(--o-kleinblue-7)); - /** - * @name - * @type color - * @group link - * @description 禁用 - */ - --o-color-link4: rgba(var(--o-kleinblue-4)); - /** - * @name 阴影1 - * @type shadow - * @group shadow - * @description 用于卡片、小弹窗、楼层阴影 - */ - --o-shadow-1: 0 3px 8px rgba(var(--o-mixedgray-1), 0.08); - /** - * @name 阴影2 - * @type shadow - * @group shadow - * @description 用于卡片悬浮阴影 - */ - --o-shadow-2: 0 2px 24px rgba(var(--o-mixedgray-1), 0.15); - /** - * @name 阴影3 - * @type shadow - * @group shadow - * @description 用于提示阴影 - */ - --o-shadow-3: 0 8px 40px rgba(var(--o-mixedgray-1), 0.1); - /** - * @name 间距1 - * @type gap - * @group gap - * @description 用于组件之间的间距1 - */ - --o-gap-1: 4px; - /** - * @name 间距2 - * @type gap - * @group gap - * @description 用于组件之间的间距2 - */ - --o-gap-2: 8px; - /** - * @name 间距3 - * @type gap - * @group gap - * @description 用于组件之间的间距3 - */ - --o-gap-3: 12px; - /** - * @name 间距4 - * @type gap - * @group gap - * @description 用于组件之间的间距4 - */ - --o-gap-4: 16px; - /** - * @name 间距5 - * @type gap - * @group gap - * @description 用于组件之间的间距5 - */ - --o-gap-5: 24px; - /** - * @name 间距6 - * @type gap - * @group gap - * @description 用于组件之间的间距6 - */ - --o-gap-6: 32px; - /** - * @name 间距7 - * @type gap - * @group gap - * @description 用于组件之间的间距7 - */ - --o-gap-7: 40px; - /** - * @name 间距8 - * @type gap - * @group gap - * @description 用于组件之间的间距8 - */ - --o-gap-8: 48px; - /** - * @name 间距9 - * @type gap - * @group gap - * @description 用于组件之间的间距9 - */ - --o-gap-9: 64px; - /** - * @name 间距10 - * @type gap - * @group gap - * @description 用于组件之间的间距10 - */ - --o-gap-10: 72px; - /** - * @name 超小尺寸 - * @type size - * @group control_size - * @description 超小尺寸 - */ - --o-control_size-2xs: 14px; - /** - * @name 小尺寸 - * @type size - * @group control_size - * @description 小尺寸 - */ - --o-control_size-xs: 16px; - /** - * @name 小尺寸 - * @type size - * @group control_size - * @description 小尺寸 - */ - --o-control_size-s: 24px; - /** - * @name 中尺寸 - * @type size - * @group control_size - * @description 尺寸 - */ - --o-control_size-m: 32px; - /** - * @name 大尺寸 - * @type size - * @group control_size - * @description 尺寸 - */ - --o-control_size-l: 40px; - /** - * @name 大尺寸 - * @type size - * @group control_size - * @description 尺寸 - */ - --o-control_size-xl: 48px; - /** - * @name 大尺寸 - * @type size - * @group control_size - * @description 尺寸 - */ - --o-control_size-2xl: 56px; - /** - * @name 超小尺寸图标 - * @type size - * @group icon_size - * @description 超小尺寸图标 - */ - --o-icon_size-xs: 16px; - /** - * @name 小尺寸图标 - * @type size - * @group icon_size - * @description 小尺寸图标 - */ - --o-icon_size-s: 20px; - /** - * @name 中尺寸图标 - * @type size - * @group icon_size - * @description 中尺寸图标 - */ - --o-icon_size-m: 24px; - /** - * @name 大尺寸图标 - * @type size - * @group icon_size - * @description 大尺寸图标 - */ - --o-icon_size-l: 32px; - /** - * @name 超大尺寸图标 - * @type size - * @group icon_size - * @description 超大尺寸图标 - */ - --o-icon_size-xl: 40px; - /** - * @name 2xl尺寸图标 - * @type size - * @group icon_size - * @description 2xl尺寸图标 - */ - --o-icon_size-2xl: 48px; - /** - * @name 3xl尺寸图标 - * @type size - * @group icon_size - * @description 3xl尺寸图标 - */ - --o-icon_size-3xl: 56px; - /** - * @name 4xl尺寸图标 - * @type size - * @group icon_size - * @description 4xl尺寸图标 - */ - --o-icon_size-4xl: 64px; - /** - * @name 超小尺寸图标 - * @type size - * @group icon_size_control - * @description 超小尺寸控件图标(组件使用) - */ - --o-icon_size_control-xs: 16px; - /** - * @name 小尺寸图标 - * @type size - * @group icon_size_control - * @description 小尺寸控件图标(组件使用) - */ - --o-icon_size_control-s: 20px; - /** - * @name 中尺寸图标 - * @type size - * @group icon_size_control - * @description 中尺寸控件图标(组件使用) - */ - --o-icon_size_control-m: 24px; - /** - * @name 大尺寸图标 - * @type size - * @group icon_size_control - * @description 大尺寸控件图标(组件使用) - */ - --o-icon_size_control-l: 32px; - /** - * @name 超大尺寸图标 - * @type size - * @group icon_size_control - * @description 超大尺寸控件图标(组件使用) - */ - --o-icon_size_control-xl: 40px; - /** - * @name 一级数据展示 - * @type font - * @group font_size - * @description 一级数据展示 - */ - --o-font_size-display1: 56px; - /** - * @name 二级数据展示 - * @type font - * @group font_size - * @description 二级数据展示 - */ - --o-font_size-display2: 48px; - /** - * @name 三级数据展示 - * @type font - * @group font_size - * @description 三级数据展示 - */ - --o-font_size-display3: 40px; - /** - * @name 一级标题 - * @type font - * @group font_size - * @description 一级标题 - */ - --o-font_size-h1: 32px; - /** - * @name 二级标题 - * @type font - * @group font_size - * @description 二级标题 - */ - --o-font_size-h2: 24px; - /** - * @name 三级标题 - * @type font - * @group font_size - * @description 三级标题 - */ - --o-font_size-h3: 22px; - /** - * @name 四级标题 - * @type font - * @group font_size - * @description 四级标题 - */ - --o-font_size-h4: 20px; - /** - * @name 常规正文 - * @type font - * @group font_size - * @description 常规正文 - */ - --o-font_size-text1: 16px; - /** - * @name 大号正文 - * @type font - * @group font_size - * @description 大号正文 - */ - --o-font_size-text2: 18px; - /** - * @name 提示文本1 - * @type font - * @group font_size - * @description 提示文本1 - */ - --o-font_size-tip1: 14px; - /** - * @name 提示文本2 - * @type font - * @group font_size - * @description 提示文本2 - */ - --o-font_size-tip2: 12px; - /** - * @name 一级数据展示 - * @type font - * @group line_height - * @description 一级数据展示 - */ - --o-line_height-display1: 80px; - /** - * @name 二级数据展示 - * @type font - * @group line_height - * @description 二级数据展示 - */ - --o-line_height-display2: 64px; - /** - * @name 三级数据展示 - * @type font - * @group line_height - * @description 三级数据展示 - */ - --o-line_height-display3: 56px; - /** - * @name 一级标题 - * @type font - * @group line_height - * @description 一级标题 - */ - --o-line_height-h1: 44px; - /** - * @name 二级标题 - * @type font - * @group line_height - * @description 二级标题 - */ - --o-line_height-h2: 32px; - /** - * @name 三级标题 - * @type font - * @group line_height - * @description 三级标题 - */ - --o-line_height-h3: 30px; - /** - * @name 四级标题 - * @type font - * @group line_height - * @description 四级标题 - */ - --o-line_height-h4: 28px; - /** - * @name 正文 - * @type font - * @group line_height - * @description 正文 - */ - --o-line_height-text1: 24px; - /** - * @name 正文-大 - * @type font - * @group line_height - * @description 正文-大 - */ - --o-line_height-text2: 26x; - /** - * @name 提示文本1 - * @type font - * @group line_height - * @description 提示文本1 - */ - --o-line_height-tip1: 22px; - /** - * @name 提示文本2 - * @type font - * @group line_height - * @description 提示文本2 - */ - --o-line_height-tip2: 18px; - /** - * @name 超小尺寸圆角 - * @type size - * @group radius - * @description 超小尺寸圆角 - */ - --o-radius-xs: 4px; - /** - * @name 小尺寸圆角 - * @type size - * @group radius - * @description 小尺寸圆角 - */ - --o-radius-s: 8px; - /** - * @name 中尺寸圆角 - * @type size - * @group radius - * @description 中尺寸圆角 - */ - --o-radius-m: 12px; - /** - * @name 大尺寸圆角 - * @type size - * @group radius - * @description 大尺寸圆角 - */ - --o-radius-l: 16px; - /** - * @name 大尺寸圆角 - * @type size - * @group radius - * @description 大尺寸圆角,一般用于卡片 - */ - --o-radius-xl: 24px; - /** - * @name 超小尺寸控件圆角 - * @type size - * @group radius_control - * @description 超小尺寸控件圆角(组件使用) - */ - --o-radius_control-xs: 4px; - /** - * @name 小尺寸控件圆角 - * @type size - * @group radius_control - * @description 小尺寸控件圆角(组件使用) - */ - --o-radius_control-s: 8px; - /** - * @name 中尺寸控件圆角 - * @type size - * @group radius_control - * @description 中尺寸控件圆角(组件使用) - */ - --o-radius_control-m: 12px; - /** - * @name 大尺寸控件圆角 - * @type size - * @group radius_control - * @description 大尺寸控件圆角(组件使用) - */ - --o-radius_control-l: 16px; - /** - * @name 持续时间 - * @type animation - * @group duration - * @description 用于退出屏幕的动画 - */ - --o-duration-s: 200ms; - /** - * @name 持续时间 - * @type animation - * @group duration - * @description 用于当曲线为standard-in时进入屏幕的动画 - */ - --o-duration-m1: 250ms; - /** - * @name 持续时间 - * @type animation - * @group duration - * @description 用于当曲线为standard时开始、结束的动画 - */ - --o-duration-m2: 300ms; - /** - * @name 持续时间 - * @type animation - * @group duration - * @description 用于当曲线为emphasized-in时进入屏幕的动画 - */ - --o-duration-m3: 400ms; - /** - * @name 持续时间 - * @type animation - * @group duration - * @description 用于当曲线为emphasized时开始、结束的动画 - */ - --o-duration-l: 500ms; - /** - * @name 持续时间 - * @type animation - * @group duration - * @description 用于当曲线为emphasized时,轮播切换动画 - */ - --o-duration-xl: 1000ms; - /** - * @name 线性动画曲线 - * @type animation - * @group easing - * @description 线性曲线 - */ - --o-easing-linear: cubic-bezier(0, 0, 1, 1); - /** - * @name 动画曲线 - * @type animation - * @group easing - * @description 用于组件 - */ - --o-easing-standard: cubic-bezier(0.2, 0, 0, 1); - /** - * @name 动画曲线 - * @type animation - * @group easing - * @description 用于组件 - */ - --o-easing-standard-in: cubic-bezier(0, 0, 0, 1); - /** - * @name 动画曲线 - * @type animation - * @group easing - * @description 用于组件 - */ - --o-easing-standard-out: cubic-bezier(0.3, 0, 1, 1); - /** - * @name 动画曲线 - * @type animation - * @group easing - * @description 用于大卡片、场景切换 - */ - --o-easing-emphasized: cubic-bezier(0.2, 0, 0, 1); - /** - * @name 动画曲线 - * @type animation - * @group easing - * @description 用于大卡片、场景切换 - */ - --o-easing-emphasized-in: cubic-bezier(0.3, 0, 0.8, 0.15); - /** - * @name 动画曲线 - * @type animation - * @group easing - * @description 用于大卡片、场景切换 - */ - --o-easing-emphasized-out: cubic-bezier(0.05, 0.7, 0.1, 1); -} \ No newline at end of file diff --git a/docs/.vitepress/src/assets/style/theme/default-light.token.css b/docs/.vitepress/src/assets/style/theme/default-light.token.css deleted file mode 100644 index b2572c848e85fc594d5feb6b2e55033ad6fba36f..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/default-light.token.css +++ /dev/null @@ -1,2194 +0,0 @@ -/* theme: opendesign.light */ -:root,[data-o-theme="light"] { - /** - * @name - * @type palette - * @group white - * @description - */ - --o-white: 255, 255, 255; - /** - * @name - * @type palette - * @group black - * @description - */ - --o-black: 0, 0, 0; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-1: 235, 241, 246; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-2: 206, 219, 245; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-3: 132, 161, 220; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-4: 81, 119, 202; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-5: 37, 81, 185; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-6: 0, 47, 167; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-7: 0, 39, 147; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-8: 0, 31, 126; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-9: 0, 24, 126; - /** - * @name - * @type palette - * @group kleinblue - * @description - */ - --o-kleinblue-10: 0, 18, 85; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-1: 254, 252, 233; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-2: 252, 248, 202; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-3: 249, 237, 149; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-4: 246, 224, 98; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-5: 243, 207, 49; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-6: 240, 188, 6; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-7: 200, 147, 0; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-8: 160, 109, 0; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-9: 120, 76, 0; - /** - * @name - * @type palette - * @group yellow - * @description - */ - --o-yellow-10: 80, 47, 0; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-1: 255, 246, 232; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-2: 254, 226, 186; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-3: 253, 202, 140; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-4: 252, 176, 95; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-5: 251, 147, 50; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-6: 250, 115, 5; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-7: 207, 88, 3; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-8: 163, 64, 2; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-9: 120, 42, 1; - /** - * @name - * @type palette - * @group orange - * @description - */ - --o-orange-10: 77, 24, 0; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-1: 255, 234, 232; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-2: 250, 185, 182; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-3: 245, 136, 134; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-4: 240, 87, 90; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-5: 235, 43, 52; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-6: 230, 0, 18; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-7: 192, 0, 22; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-8: 153, 0, 23; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-9: 115, 0, 21; - /** - * @name - * @type palette - * @group red - * @description - */ - --o-red-10: 77, 0, 17; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-1: 232, 255, 238; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-2: 177, 239, 195; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-3: 128, 224, 158; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-4: 84, 208, 127; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-5: 45, 193, 101; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-6: 11, 177, 81; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-7: 7, 152, 72; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-8: 4, 127, 63; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-9: 2, 102, 53; - /** - * @name - * @type palette - * @group green - * @description - */ - --o-green-10: 0, 77, 42; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-1: 253, 247, 232; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-2: 250, 237, 200; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-3: 245, 215, 147; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-4: 241, 191, 96; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-5: 236, 165, 47; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-6: 231, 137, 0; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-7: 193, 105, 0; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-8: 154, 76, 0; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-9: 116, 51, 0; - /** - * @name - * @type palette - * @group amber - * @description - */ - --o-amber-10: 77, 30, 0; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-1: 243, 250, 230; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-2: 229, 244, 195; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-3: 208, 233, 140; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-4: 191, 223, 89; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-5: 177, 212, 42; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-6: 167, 201, 0; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-7: 136, 168, 0; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-8: 107, 134, 0; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-9: 78, 101, 0; - /** - * @name - * @type palette - * @group lime - * @description - */ - --o-lime-10: 51, 67, 0; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-1: 242, 247, 231; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-2: 225, 240, 199; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-3: 195, 225, 148; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-4: 166, 209, 103; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-5: 138, 194, 62; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-6: 112, 179, 27; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-7: 91, 149, 21; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-8: 70, 119, 16; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-9: 51, 90, 11; - /** - * @name - * @type palette - * @group light-green - * @description - */ - --o-light-green-10: 33, 60, 7; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-1: 228, 247, 241; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-2: 192, 240, 224; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-3: 135, 225, 197; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-4: 84, 209, 173; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-5: 39, 194, 152; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-6: 0, 179, 133; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-7: 0, 149, 113; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-8: 0, 119, 93; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-9: 0, 90, 71; - /** - * @name - * @type palette - * @group teal - * @description - */ - --o-teal-10: 0, 60, 48; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-1: 228, 247, 247; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-2: 192, 240, 240; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-3: 135, 223, 225; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-4: 84, 205, 209; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-5: 39, 186, 194; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-6: 0, 167, 179; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-7: 0, 137, 149; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-8: 0, 107, 119; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-9: 0, 79, 90; - /** - * @name - * @type palette - * @group cyan - * @description - */ - --o-cyan-10: 0, 52, 60; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-1: 232, 247, 252; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-2: 200, 237, 250; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-3: 147, 218, 245; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-4: 96, 198, 239; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-5: 47, 178, 234; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-6: 0, 156, 229; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-7: 0, 127, 191; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-8: 0, 99, 153; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-9: 0, 72, 115; - /** - * @name - * @type palette - * @group light-blue - * @description - */ - --o-light-blue-10: 0, 47, 76; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-1: 233, 245, 254; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-2: 202, 231, 252; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-3: 149, 205, 249; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-4: 98, 178, 246; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-5: 49, 151, 243; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-6: 0, 122, 240; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-7: 0, 100, 204; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-8: 0, 80, 169; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-9: 0, 61, 133; - /** - * @name - * @type palette - * @group blue - * @description - */ - --o-blue-10: 0, 43, 97; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-1: 255, 255, 255; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-2: 243, 243, 245; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-3: 237, 237, 240; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-4: 232, 232, 235; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-5: 222, 222, 227; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-6: 212, 212, 217; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-7: 186, 186, 191; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-8: 149, 149, 157; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-9: 111, 111, 117; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-10: 85 , 85, 92; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-11: 61, 61, 66; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-12: 37, 37, 41; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-13: 21, 21, 23; - /** - * @name - * @type palette - * @group mixedgray - * @description - */ - --o-mixedgray-14: 0, 0, 0; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-1: 232, 236, 247; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-2: 200, 211, 240; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-3: 150, 170, 225; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-4: 106, 131, 209; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-5: 66, 96, 194; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-6: 31, 63, 179; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-7: 23, 50, 159; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-8: 16, 38, 138; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-9: 10, 28, 118; - /** - * @name - * @type palette - * @group indigo - * @description - */ - --o-indigo-10: 5, 19, 101; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-1: 234, 231, 249; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-2: 206, 199, 242; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-3: 163, 147, 229; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-4: 124, 100, 217; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-5: 90, 58, 204; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-6: 61, 20, 191; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-7: 53, 13, 171; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-8: 46, 7, 150; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-9: 39, 2, 130; - /** - * @name - * @type palette - * @group violet - * @description - */ - --o-violet-10: 34, 0, 109; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-1: 245, 228, 247; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-2: 234, 192, 240; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-3: 211, 136, 225; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-4: 187, 85, 209; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-5: 161, 41, 194; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-6: 135, 2, 179; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-7: 114, 0, 159; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-8: 95, 0, 138; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-9: 77, 0, 118; - /** - * @name - * @type palette - * @group purple - * @description - */ - --o-purple-10: 60, 0, 97; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-1: 252, 232, 239; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-2: 249, 199, 217; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-3: 243, 146, 184; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-4: 236, 95, 156; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-5: 230, 46, 132; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-6: 224, 0, 112; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-7: 188, 0, 100; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-8: 153, 0, 86; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-9: 117, 0, 70; - /** - * @name - * @type palette - * @group pink - * @description - */ - --o-pink-10: 81, 0, 51; - /** - * @name - * @type color - * @group base - * @description - */ - --o-color-white: rgb(var(--o-white)); - /** - * @name - * @type color - * @group base - * @description - */ - --o-color-black: rgb(var(--o-black)); - /** - * @name - * @type color - * @group primary - * @description 常规 - */ - --o-color-primary1: rgb(var(--o-kleinblue-6)); - /** - * @name - * @type color - * @group primary - * @description 悬浮 - */ - --o-color-primary2: rgb(var(--o-kleinblue-4)); - /** - * @name - * @type color - * @group primary - * @description 激活 - */ - --o-color-primary3: rgb(var(--o-kleinblue-7)); - /** - * @name - * @type color - * @group primary - * @description 禁用 - */ - --o-color-primary4: rgb(var(--o-kleinblue-3)); - /** - * @name - * @type color - * @group primary - * @description 常规-浅 - */ - --o-color-primary1-light: rgb(var(--o-kleinblue-2)); - /** - * @name - * @type color - * @group primary - * @description 悬浮-浅 - */ - --o-color-primary2-light: rgb(var(--o-kleinblue-3)); - /** - * @name - * @type color - * @group primary - * @description 激活-浅 - */ - --o-color-primary3-light: rgb(var(--o-kleinblue-4)); - /** - * @name - * @type color - * @group primary - * @description 禁用-浅 - */ - --o-color-primary4-light: rgb(var(--o-kleinblue-1)); - /** - * @name - * @type color - * @group success - * @description 常规 - */ - --o-color-success1: rgb(var(--o-green-6)); - /** - * @name - * @type color - * @group success - * @description 悬浮 - */ - --o-color-success2: rgb(var(--o-green-4)); - /** - * @name - * @type color - * @group success - * @description 激活 - */ - --o-color-success3: rgb(var(--o-green-7)); - /** - * @name - * @type color - * @group success - * @description 禁用 - */ - --o-color-success4: rgb(var(--o-green-3)); - /** - * @name - * @type color - * @group success - * @description 常规-浅 - */ - --o-color-success1-light: rgb(var(--o-green-2)); - /** - * @name - * @type color - * @group success - * @description 悬浮-浅 - */ - --o-color-success2-light: rgb(var(--o-green-3)); - /** - * @name - * @type color - * @group success - * @description 激活-浅 - */ - --o-color-success3-light: rgb(var(--o-green-4)); - /** - * @name - * @type color - * @group success - * @description 禁用-浅 - */ - --o-color-success4-light: rgb(var(--o-green-1)); - /** - * @name - * @type color - * @group warning - * @description 常规 - */ - --o-color-warning1: rgb(var(--o-orange-6)); - /** - * @name - * @type color - * @group warning - * @description 悬浮 - */ - --o-color-warning2: rgb(var(--o-orange-4)); - /** - * @name - * @type color - * @group warning - * @description 激活 - */ - --o-color-warning3: rgb(var(--o-orange-7)); - /** - * @name - * @type color - * @group warning - * @description 禁用 - */ - --o-color-warning4: rgb(var(--o-orange-3)); - /** - * @name - * @type color - * @group warning - * @description 常规-浅 - */ - --o-color-warning1-light: rgb(var(--o-orange-2)); - /** - * @name - * @type color - * @group warning - * @description 悬浮-浅 - */ - --o-color-warning2-light: rgb(var(--o-orange-3)); - /** - * @name - * @type color - * @group warning - * @description 激活-浅 - */ - --o-color-warning3-light: rgb(var(--o-orange-4)); - /** - * @name - * @type color - * @group warning - * @description 禁用-浅 - */ - --o-color-warning4-light: rgb(var(--o-orange-1)); - /** - * @name - * @type color - * @group danger - * @description 常规 - */ - --o-color-danger1: rgb(var(--o-red-6)); - /** - * @name - * @type color - * @group danger - * @description 悬浮 - */ - --o-color-danger2: rgb(var(--o-red-4)); - /** - * @name - * @type color - * @group danger - * @description 激活 - */ - --o-color-danger3: rgb(var(--o-red-7)); - /** - * @name - * @type color - * @group danger - * @description 禁用 - */ - --o-color-danger4: rgb(var(--o-red-3)); - /** - * @name - * @type color - * @group danger - * @description 常规-浅 - */ - --o-color-danger1-light: rgb(var(--o-red-2)); - /** - * @name - * @type color - * @group danger - * @description 悬浮-浅 - */ - --o-color-danger2-light: rgb(var(--o-red-3)); - /** - * @name - * @type color - * @group danger - * @description 激活-浅 - */ - --o-color-danger3-light: rgb(var(--o-red-4)); - /** - * @name - * @type color - * @group danger - * @description 禁用-浅 - */ - --o-color-danger4-light: rgb(var(--o-red-1)); - /** - * @name - * @type color - * @group fill - * @description 一级填充:页面背景 - */ - --o-color-fill1: rgb(var(--o-mixedgray-2)); - /** - * @name - * @type color - * @group fill - * @description 二级填充:区块/卡片 - */ - --o-color-fill2: rgb(var(--o-mixedgray-1)); - /** - * @name - * @type color - * @group fill - * @description 三级填充:卡片 - */ - --o-color-fill3: rgb(var(--o-mixedgray-3)); - /** - * @name - * @type color - * @group control - * @description 常规,常用于边框 - */ - --o-color-control1: rgba(var(--o-mixedgray-14), 0.25); - /** - * @name - * @type color - * @group control - * @description 悬浮,常用于边框 - */ - --o-color-control2: rgba(var(--o-mixedgray-14), 0.6); - /** - * @name - * @type color - * @group control - * @description 激活,常用于边框 - */ - --o-color-control3: rgba(var(--o-mixedgray-14), 0.8); - /** - * @name - * @type color - * @group control - * @description 禁用,常用于边框 - */ - --o-color-control4: rgba(var(--o-mixedgray-14), 0.1); - /** - * @name - * @type color - * @group control - * @description 常规-浅,常用于背景 - */ - --o-color-control1-light: rgb(var(--o-mixedgray-5), 1.0); - /** - * @name - * @type color - * @group control - * @description 悬浮-浅,常用于背景 - */ - --o-color-control2-light: rgba(var(--o-kleinblue-1), 1); - /** - * @name - * @type color - * @group control - * @description 激活-浅,常用于背景 - */ - --o-color-control3-light: rgba(var(--o-kleinblue-2), 1); - /** - * @name - * @type color - * @group control - * @description 禁用-浅,常用于背景 - */ - --o-color-control4-light: rgb(var(--o-mixedgray-3), 1); - /** - * @name - * @type color - * @group control - * @description 很浅,常用于表格背景色 - */ - --o-color-control-light: rgb(var(--o-mixedgray-1), 1.0); - /** - * @name - * @type color - * @group info - * @description 一级/强调/标题 - */ - --o-color-info1: rgba(var(--o-mixedgray-14), 1.0); - /** - * @name - * @type color - * @group info - * @description 二级/次强调/正文 - */ - --o-color-info2: rgba(var(--o-mixedgray-14), 0.8); - /** - * @name - * @type color - * @group info - * @description 三级/辅助信息 - */ - --o-color-info3: rgba(var(--o-mixedgray-14), 0.6); - /** - * @name - * @type color - * @group info - * @description 置灰/禁用 - */ - --o-color-info4: rgba(var(--o-mixedgray-14), 0.4); - /** - * @name - * @type color - * @group info - * @description 一级/次强调/正文反色 - */ - --o-color-info1-inverse: rgba(var(--o-mixedgray-1), 1.0); - /** - * @name - * @type color - * @group info - * @description 二级/辅助信息反色 - */ - --o-color-info2-inverse: rgba(var(--o-mixedgray-1), 0.8); - /** - * @name - * @type color - * @group info - * @description 三级/辅助信息反色 - */ - --o-color-info3-inverse: rgba(var(--o-mixedgray-1), 0.6); - /** - * @name - * @type color - * @group info - * @description 置灰/禁用反色 - */ - --o-color-info4-inverse: rgba(var(--o-mixedgray-1), 0.4); - /** - * @name - * @type color - * @group mask - * @description 全局遮罩 - */ - --o-color-mask1: rgba(var(--o-mixedgray-14), 0.4); - /** - * @name - * @type color - * @group mask - * @description 局部遮罩 - */ - --o-color-mask2: rgba(var(--o-mixedgray-1), 0.2); - /** - * @name - * @type color - * @group link - * @description 常规 - */ - --o-color-link1: rgba(var(--o-kleinblue-6)); - /** - * @name - * @type color - * @group link - * @description 悬浮 - */ - --o-color-link2: rgba(var(--o-kleinblue-4)); - /** - * @name - * @type color - * @group link - * @description 激活 - */ - --o-color-link3: rgba(var(--o-kleinblue-7)); - /** - * @name - * @type color - * @group link - * @description 禁用 - */ - --o-color-link4: rgba(var(--o-kleinblue-3)); - /** - * @name 阴影1 - * @type shadow - * @group shadow - * @description 用于卡片、小弹窗、楼层阴影 - */ - --o-shadow-1: 0 3px 8px rgba(var(--o-mixedgray-9), 0.08); - /** - * @name 阴影2 - * @type shadow - * @group shadow - * @description 用于卡片悬浮阴影 - */ - --o-shadow-2: 0 2px 24px rgba(var(--o-mixedgray-9), 0.15); - /** - * @name 阴影3 - * @type shadow - * @group shadow - * @description 用于提示阴影 - */ - --o-shadow-3: 0 8px 40px rgba(var(--o-mixedgray-9), 0.1); - /** - * @name 间距1 - * @type gap - * @group gap - * @description 用于组件之间的间距1 - */ - --o-gap-1: 4px; - /** - * @name 间距2 - * @type gap - * @group gap - * @description 用于组件之间的间距2 - */ - --o-gap-2: 8px; - /** - * @name 间距3 - * @type gap - * @group gap - * @description 用于组件之间的间距3 - */ - --o-gap-3: 12px; - /** - * @name 间距4 - * @type gap - * @group gap - * @description 用于组件之间的间距4 - */ - --o-gap-4: 16px; - /** - * @name 间距5 - * @type gap - * @group gap - * @description 用于组件之间的间距5 - */ - --o-gap-5: 24px; - /** - * @name 间距6 - * @type gap - * @group gap - * @description 用于组件之间的间距6 - */ - --o-gap-6: 32px; - /** - * @name 间距7 - * @type gap - * @group gap - * @description 用于组件之间的间距7 - */ - --o-gap-7: 40px; - /** - * @name 间距8 - * @type gap - * @group gap - * @description 用于组件之间的间距8 - */ - --o-gap-8: 48px; - /** - * @name 间距9 - * @type gap - * @group gap - * @description 用于组件之间的间距9 - */ - --o-gap-9: 64px; - /** - * @name 间距10 - * @type gap - * @group gap - * @description 用于组件之间的间距10 - */ - --o-gap-10: 72px; - /** - * @name 超小尺寸 - * @type size - * @group control_size - * @description 超小尺寸 - */ - --o-control_size-2xs: 14px; - /** - * @name 小尺寸 - * @type size - * @group control_size - * @description 小尺寸 - */ - --o-control_size-xs: 16px; - /** - * @name 小尺寸 - * @type size - * @group control_size - * @description 小尺寸 - */ - --o-control_size-s: 24px; - /** - * @name 中尺寸 - * @type size - * @group control_size - * @description 尺寸 - */ - --o-control_size-m: 32px; - /** - * @name 大尺寸 - * @type size - * @group control_size - * @description 尺寸 - */ - --o-control_size-l: 40px; - /** - * @name 大尺寸 - * @type size - * @group control_size - * @description 尺寸 - */ - --o-control_size-xl: 48px; - /** - * @name 大尺寸 - * @type size - * @group control_size - * @description 尺寸 - */ - --o-control_size-2xl: 56px; - /** - * @name 超小尺寸图标 - * @type size - * @group icon_size - * @description 超小尺寸图标 - */ - --o-icon_size-xs: 16px; - /** - * @name 小尺寸图标 - * @type size - * @group icon_size - * @description 小尺寸图标 - */ - --o-icon_size-s: 20px; - /** - * @name 中尺寸图标 - * @type size - * @group icon_size - * @description 中尺寸图标 - */ - --o-icon_size-m: 24px; - /** - * @name 大尺寸图标 - * @type size - * @group icon_size - * @description 大尺寸图标 - */ - --o-icon_size-l: 32px; - /** - * @name 超大尺寸图标 - * @type size - * @group icon_size - * @description 超大尺寸图标 - */ - --o-icon_size-xl: 40px; - /** - * @name 2xl尺寸图标 - * @type size - * @group icon_size - * @description 2xl尺寸图标 - */ - --o-icon_size-2xl: 48px; - /** - * @name 3xl尺寸图标 - * @type size - * @group icon_size - * @description 3xl尺寸图标 - */ - --o-icon_size-3xl: 56px; - /** - * @name 4xl尺寸图标 - * @type size - * @group icon_size - * @description 4xl尺寸图标 - */ - --o-icon_size-4xl: 64px; - /** - * @name 超小尺寸图标 - * @type size - * @group icon_size_control - * @description 超小尺寸控件图标(组件使用) - */ - --o-icon_size_control-xs: 16px; - /** - * @name 小尺寸图标 - * @type size - * @group icon_size_control - * @description 小尺寸控件图标(组件使用) - */ - --o-icon_size_control-s: 20px; - /** - * @name 中尺寸图标 - * @type size - * @group icon_size_control - * @description 中尺寸控件图标(组件使用) - */ - --o-icon_size_control-m: 24px; - /** - * @name 大尺寸图标 - * @type size - * @group icon_size_control - * @description 大尺寸控件图标(组件使用) - */ - --o-icon_size_control-l: 32px; - /** - * @name 超大尺寸图标 - * @type size - * @group icon_size_control - * @description 超大尺寸控件图标(组件使用) - */ - --o-icon_size_control-xl: 40px; - /** - * @name 一级数据展示 - * @type font - * @group font_size - * @description 一级数据展示 - */ - --o-font_size-display1: 56px; - /** - * @name 二级数据展示 - * @type font - * @group font_size - * @description 二级数据展示 - */ - --o-font_size-display2: 48px; - /** - * @name 三级数据展示 - * @type font - * @group font_size - * @description 三级数据展示 - */ - --o-font_size-display3: 40px; - /** - * @name 一级标题 - * @type font - * @group font_size - * @description 一级标题 - */ - --o-font_size-h1: 32px; - /** - * @name 二级标题 - * @type font - * @group font_size - * @description 二级标题 - */ - --o-font_size-h2: 24px; - /** - * @name 三级标题 - * @type font - * @group font_size - * @description 三级标题 - */ - --o-font_size-h3: 22px; - /** - * @name 四级标题 - * @type font - * @group font_size - * @description 四级标题 - */ - --o-font_size-h4: 20px; - /** - * @name 常规正文 - * @type font - * @group font_size - * @description 常规正文 - */ - --o-font_size-text1: 16px; - /** - * @name 大号正文 - * @type font - * @group font_size - * @description 大号正文 - */ - --o-font_size-text2: 18px; - /** - * @name 提示文本1 - * @type font - * @group font_size - * @description 提示文本1 - */ - --o-font_size-tip1: 14px; - /** - * @name 提示文本2 - * @type font - * @group font_size - * @description 提示文本2 - */ - --o-font_size-tip2: 12px; - /** - * @name 一级数据展示 - * @type font - * @group line_height - * @description 一级数据展示 - */ - --o-line_height-display1: 80px; - /** - * @name 二级数据展示 - * @type font - * @group line_height - * @description 二级数据展示 - */ - --o-line_height-display2: 64px; - /** - * @name 三级数据展示 - * @type font - * @group line_height - * @description 三级数据展示 - */ - --o-line_height-display3: 56px; - /** - * @name 一级标题 - * @type font - * @group line_height - * @description 一级标题 - */ - --o-line_height-h1: 44px; - /** - * @name 二级标题 - * @type font - * @group line_height - * @description 二级标题 - */ - --o-line_height-h2: 32px; - /** - * @name 三级标题 - * @type font - * @group line_height - * @description 三级标题 - */ - --o-line_height-h3: 30px; - /** - * @name 四级标题 - * @type font - * @group line_height - * @description 四级标题 - */ - --o-line_height-h4: 28px; - /** - * @name 正文 - * @type font - * @group line_height - * @description 正文 - */ - --o-line_height-text1: 24px; - /** - * @name 正文-大 - * @type font - * @group line_height - * @description 正文-大 - */ - --o-line_height-text2: 26px; - /** - * @name 提示文本1 - * @type font - * @group line_height - * @description 提示文本1 - */ - --o-line_height-tip1: 22px; - /** - * @name 提示文本2 - * @type font - * @group line_height - * @description 提示文本2 - */ - --o-line_height-tip2: 18px; - /** - * @name 超小尺寸圆角 - * @type size - * @group radius - * @description 超小尺寸圆角 - */ - --o-radius-xs: 4px; - /** - * @name 小尺寸圆角 - * @type size - * @group radius - * @description 小尺寸圆角 - */ - --o-radius-s: 8px; - /** - * @name 中尺寸圆角 - * @type size - * @group radius - * @description 中尺寸圆角 - */ - --o-radius-m: 12px; - /** - * @name 大尺寸圆角 - * @type size - * @group radius - * @description 大尺寸圆角 - */ - --o-radius-l: 16px; - /** - * @name 大尺寸圆角 - * @type size - * @group radius - * @description 大尺寸圆角,一般用于卡片 - */ - --o-radius-xl: 24px; - /** - * @name 超小尺寸控件圆角 - * @type size - * @group radius_control - * @description 超小尺寸控件圆角(组件使用) - */ - --o-radius_control-xs: 4px; - /** - * @name 小尺寸控件圆角 - * @type size - * @group radius_control - * @description 小尺寸控件圆角(组件使用) - */ - --o-radius_control-s: 8px; - /** - * @name 中尺寸控件圆角 - * @type size - * @group radius_control - * @description 中尺寸控件圆角(组件使用) - */ - --o-radius_control-m: 12px; - /** - * @name 大尺寸控件圆角 - * @type size - * @group radius_control - * @description 大尺寸控件圆角(组件使用) - */ - --o-radius_control-l: 16px; - /** - * @name 持续时间 - * @type animation - * @group duration - * @description 用于退出屏幕的动画 - */ - --o-duration-s: 200ms; - /** - * @name 持续时间 - * @type animation - * @group duration - * @description 用于当曲线为standard-in时进入屏幕的动画 - */ - --o-duration-m1: 250ms; - /** - * @name 持续时间 - * @type animation - * @group duration - * @description 用于当曲线为standard时开始、结束的动画 - */ - --o-duration-m2: 300ms; - /** - * @name 持续时间 - * @type animation - * @group duration - * @description 用于当曲线为emphasized-in时进入屏幕的动画 - */ - --o-duration-m3: 400ms; - /** - * @name 持续时间 - * @type animation - * @group duration - * @description 用于当曲线为emphasized时开始、结束的动画 - */ - --o-duration-l: 500ms; - /** - * @name 持续时间 - * @type animation - * @group duration - * @description 用于当曲线为emphasized时,轮播切换动画 - */ - --o-duration-xl: 1000ms; - /** - * @name 线性动画曲线 - * @type animation - * @group easing - * @description 线性曲线 - */ - --o-easing-linear: cubic-bezier(0, 0, 1, 1); - /** - * @name 动画曲线 - * @type animation - * @group easing - * @description 用于组件 - */ - --o-easing-standard: cubic-bezier(0.2, 0, 0, 1); - /** - * @name 动画曲线 - * @type animation - * @group easing - * @description 用于组件 - */ - --o-easing-standard-in: cubic-bezier(0, 0, 0, 1); - /** - * @name 动画曲线 - * @type animation - * @group easing - * @description 用于组件 - */ - --o-easing-standard-out: cubic-bezier(0.3, 0, 1, 1); - /** - * @name 动画曲线 - * @type animation - * @group easing - * @description 用于大卡片、场景切换 - */ - --o-easing-emphasized: cubic-bezier(0.2, 0, 0, 1); - /** - * @name 动画曲线 - * @type animation - * @group easing - * @description 用于大卡片、场景切换 - */ - --o-easing-emphasized-in: cubic-bezier(0.3, 0, 0.8, 0.15); - /** - * @name 动画曲线 - * @type animation - * @group easing - * @description 用于大卡片、场景切换 - */ - --o-easing-emphasized-out: cubic-bezier(0.05, 0.7, 0.1, 1); -} \ No newline at end of file diff --git a/docs/.vitepress/src/assets/style/theme/dialog.scss b/docs/.vitepress/src/assets/style/theme/dialog.scss deleted file mode 100644 index 581c57a9bd991639149ba0c28257a38da910fb6d..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/dialog.scss +++ /dev/null @@ -1,35 +0,0 @@ -@use '../mixin/screen.scss' as *; -@use '../mixin/font.scss' as *; -// 屏蔽loading 遮罩 -.o-layer { - .o-dlg-header { - color: var(--o-color-info1); - } - &.o-loading { - --loading-mask-icon-color: var(--o-color-info1); - --layer-align: top; - --layer-origin: top; - --loading-mask-color: var(--o-color-info1); - --layer-mask: var(--o-color-info4-inverse); - transition: none; - padding-top: 23%; - .o-loading-main { - flex-direction: column; - justify-content: flex-start; - @include text1; - .o-loading-icon { - font-size: 24px; - margin-bottom: 12px; - } - .o-rotating { - width: 24px; - height: 24px; - margin-bottom: 12px; - } - } - } -} - -.o-dialog { - --dlg-radius: var(--layout-pkg-radius); -} diff --git a/docs/.vitepress/src/assets/style/theme/dropdown.scss b/docs/.vitepress/src/assets/style/theme/dropdown.scss deleted file mode 100644 index 067a83b162e997ea13741446cbedde87576b395c..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/dropdown.scss +++ /dev/null @@ -1,3 +0,0 @@ -.o-dropdown-list { - --dropdown-list-radius: 4px; -} diff --git a/docs/.vitepress/src/assets/style/theme/index.scss b/docs/.vitepress/src/assets/style/theme/index.scss deleted file mode 100644 index b0555a333f55396f41af3e40df654e543b38acfa..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/index.scss +++ /dev/null @@ -1,15 +0,0 @@ -@use './anchor.scss' as *; -@use './button.scss' as *; -@use './card.scss' as *; -@use './dialog.scss' as *; -@use './dropdown.scss' as *; -@use './input.scss' as *; -@use './message.scss' as *; -@use './select.scss' as *; -@use './table.scss' as *; -@use './tag.scss' as *; -@use './popup.scss' as *; -@use './tab.scss' as *; -@use './rate.scss' as *; -@use './result.scss' as *; -@use './textarea.scss' as *; diff --git a/docs/.vitepress/src/assets/style/theme/input.scss b/docs/.vitepress/src/assets/style/theme/input.scss deleted file mode 100644 index eadcc6d22b6e77ec9f15fd4cd3b6f2534a2113ee..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/input.scss +++ /dev/null @@ -1,3 +0,0 @@ -.o-input-clear { - font-size: 20px; -} diff --git a/docs/.vitepress/src/assets/style/theme/message.scss b/docs/.vitepress/src/assets/style/theme/message.scss deleted file mode 100644 index fe6ba2c2c65b116009e2a8b9a63317cdf6447e20..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/message.scss +++ /dev/null @@ -1,8 +0,0 @@ -.o-message-list { - z-index: 1008; - --app-header-height: 64px; - --app-footer-height: 300px; - - --message-list-top-offset: calc(var(--app-header-height) + 32px); - --message-list-bottom-offset: calc(var(--app-footer-height) + 32px); -} diff --git a/docs/.vitepress/src/assets/style/theme/popup.scss b/docs/.vitepress/src/assets/style/theme/popup.scss deleted file mode 100644 index 0bc392e4fe2150e2da9f63c95a3f1258c782d7b3..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/popup.scss +++ /dev/null @@ -1,17 +0,0 @@ -.o-popup { - --popup-shadow: var(--o-shadow-2); - --popup-bd: 1px solid var(--o-color-control4); - .o-popup-body { - border-radius: var(--popup-radius); - } - .global-feedback-popup { - border: none; - - textarea::placeholder { - color: var(--o-color-info4); - } - } - .o-popup-anchor { - z-index: 2; - } -} diff --git a/docs/.vitepress/src/assets/style/theme/rate.scss b/docs/.vitepress/src/assets/style/theme/rate.scss deleted file mode 100644 index 30ee6f61c561a557eeb931a07d1e38f26eb8aacf..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/rate.scss +++ /dev/null @@ -1,4 +0,0 @@ -.o-rate { - --rate-color: var(--o-color-info4); - --rate-size: 24px; -} diff --git a/docs/.vitepress/src/assets/style/theme/result.scss b/docs/.vitepress/src/assets/style/theme/result.scss deleted file mode 100644 index 274b722f7c7e9749bb99ee3eaac49b3c8bad83c8..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/result.scss +++ /dev/null @@ -1,3 +0,0 @@ -.o-result-content { - color: var(--o-color-info1); -} diff --git a/docs/.vitepress/src/assets/style/theme/select.scss b/docs/.vitepress/src/assets/style/theme/select.scss deleted file mode 100644 index 698f1d06d21c16c2258963ba6a1724abbb2c58ba..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/select.scss +++ /dev/null @@ -1,4 +0,0 @@ -.o-select { - --select-icon-size: 20px; - --select-radius: 4px; -} diff --git a/docs/.vitepress/src/assets/style/theme/tab.scss b/docs/.vitepress/src/assets/style/theme/tab.scss deleted file mode 100644 index bb1ff81127793dc60ba4ef4b370c16b1a3677f70..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/tab.scss +++ /dev/null @@ -1,79 +0,0 @@ -.field-tabs { - > .o-tab-head > .o-tab-navs { - max-width: var(--layout-content-max-width); - padding-left: var(--layout-content-padding); - padding-right: var(--layout-content-padding); - margin: 0 auto; - } -} -.o-tab { - --tab-nav-divider: 1px solid var(--o-color-control4); -} -.domain-tabs { - &.min { - > .o-tab-head { - .o-tab-nav-anchor { - display: none; - } - - .o-tab-nav-active { - color: var(--o-color-info1); - cursor: default; - } - } - } - .o-tab-head { - display: block !important; - } - .o-tab-navs { - --tab-nav-justify: left; - margin-bottom: 24px; - } - .o-table { - word-break: break-word; - --table-edge-padding: 24px; - .arch, - .appVer { - width: 250px; - } - tbody tr:hover { - background: none; - } - } - - // 应用镜像样式 - &.tabs-switch { - .o-tab-nav-list { - background: var(--o-color-fill1); - border-radius: 8px; - height: 40px; - padding: 4px; - .o-tab-nav { - margin: 0 !important; - position: relative; - padding: 2px 12px; - z-index: 3; - } - } - .o-tab-nav-anchor { - top: 0; - padding: 4px 0; - .o-tab-nav-anchor-line { - box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1); - border-radius: 4px; - height: 100%; - background: var(--o-color-fill2); - } - } - } - &.tabs-one { - .o-tab-nav-active { - color: var(--o-color-info1); - cursor: default; - padding: 0; - } - .o-tab-nav-anchor { - display: none; - } - } -} diff --git a/docs/.vitepress/src/assets/style/theme/table.scss b/docs/.vitepress/src/assets/style/theme/table.scss deleted file mode 100644 index 54aa764a3250753c7fc7758d239340366ec75756..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/table.scss +++ /dev/null @@ -1,45 +0,0 @@ -@use '../mixin/font.scss' as *; -.o-table { - --table-edge-padding: 24px; - --table-cell-padding: 16px 10px; - --table-head-cell-padding: 12px 10px; - --table-head-bg: var(--o-color-control3-light); - --table-color: var(--o-color-info1); - - --table-loading-mask: var(--o-color-info4-inverse); - .o-table-loading-wrap { - z-index: 99; - flex-direction: column; - .o-icon-loading { - font-size: 24px; - } - .o-table-loading-label { - margin: 12px 0 0; - @include text1; - } - } - - th { - font-weight: 500; - border-right: 0; - } - &.table-version { - --table-head-bg: var(--o-color-primary1); - th { - color: #fff; - } - } - td { - word-break: break-word; - } - &.o-table-small { - --table-cell-height: auto; - --table-edge-padding: 24px; - --table-cell-padding: 8px; - --table-head-cell-padding: 8px; - td, - th { - @include tip1; - } - } -} diff --git a/docs/.vitepress/src/assets/style/theme/tag.scss b/docs/.vitepress/src/assets/style/theme/tag.scss deleted file mode 100644 index 6903316a6aca63eef47ac9c2246558baaec90e24..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/tag.scss +++ /dev/null @@ -1,6 +0,0 @@ -.o-tag { - border-radius: var(--layout-pkg-radius); - &.o-tag-small { - --tag-padding: 0 4px; - } -} diff --git a/docs/.vitepress/src/assets/style/theme/textarea.scss b/docs/.vitepress/src/assets/style/theme/textarea.scss deleted file mode 100644 index d63fe2132cb3192311a8545768abff5e67758169..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/style/theme/textarea.scss +++ /dev/null @@ -1,15 +0,0 @@ -@use '../mixin/screen.scss' as *; - -.o-textarea { - height: 126px; - - @include respond-to('<=pad') { - height: 116px; - } -} - -.o_textarea-textarea { - &::-webkit-input-placeholder { - color: var(--o-color-info4); - } -} diff --git a/docs/.vitepress/src/assets/svg-icons/icon-arrow-right.svg b/docs/.vitepress/src/assets/svg-icons/icon-arrow-right.svg deleted file mode 100644 index 54eec72baadf9c4b6e41c383480dff0f5011aa7b..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-arrow-right.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-chevron-down.svg b/docs/.vitepress/src/assets/svg-icons/icon-chevron-down.svg deleted file mode 100644 index e33699d7e07f5062ccac143e5d48eda8cf6f53f5..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-chevron-down.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-chevron-right.svg b/docs/.vitepress/src/assets/svg-icons/icon-chevron-right.svg deleted file mode 100644 index 646c5058cb39e204b88c447d0d19e9e17efc7e5b..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-chevron-right.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-close.svg b/docs/.vitepress/src/assets/svg-icons/icon-close.svg deleted file mode 100644 index 279157ed3b9bf28765043a3e41632117f2e72c07..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-close.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-copy.svg b/docs/.vitepress/src/assets/svg-icons/icon-copy.svg deleted file mode 100644 index e95788f2d35b2e6613735d47f45017da800fca16..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-copy.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-delete.svg b/docs/.vitepress/src/assets/svg-icons/icon-delete.svg deleted file mode 100644 index 0d1256832ad6eed15d682bd9b6e0b83781b1bee8..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-delete.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-expand.svg b/docs/.vitepress/src/assets/svg-icons/icon-expand.svg deleted file mode 100644 index 56ddb7b1d14949873c28c665b311d6c5679785e9..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-expand.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-header-back.svg b/docs/.vitepress/src/assets/svg-icons/icon-header-back.svg deleted file mode 100644 index b64d9a7c6281ad4ea812246d15ff157044ea62ca..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-header-back.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-header-delete.svg b/docs/.vitepress/src/assets/svg-icons/icon-header-delete.svg deleted file mode 100644 index 4e1f96a83b92b50b7e1ca3d941051ee93899a180..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-header-delete.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-header-menu.svg b/docs/.vitepress/src/assets/svg-icons/icon-header-menu.svg deleted file mode 100644 index edf857821413e2003a811cd4793535838f7af2eb..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-header-menu.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-header-moon.svg b/docs/.vitepress/src/assets/svg-icons/icon-header-moon.svg deleted file mode 100644 index 0ea8cc4417ed9603faa682be7ed03209e61d0e56..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-header-moon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-header-next.svg b/docs/.vitepress/src/assets/svg-icons/icon-header-next.svg deleted file mode 100644 index e93dbc59e41400afc986e6bf3de7a1680d27f17a..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-header-next.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-header-person.svg b/docs/.vitepress/src/assets/svg-icons/icon-header-person.svg deleted file mode 100644 index ea47e9ca566d23715ca537cb32ba7586f7914c38..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-header-person.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-header-search.svg b/docs/.vitepress/src/assets/svg-icons/icon-header-search.svg deleted file mode 100644 index 032308b5e70b9fd3f0ac04a52be937947c9f9c3d..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-header-search.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-out-link.svg b/docs/.vitepress/src/assets/svg-icons/icon-out-link.svg deleted file mode 100644 index 08056a9dbfe83996088862ca8542c9b0684a8a6e..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-out-link.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-search.svg b/docs/.vitepress/src/assets/svg-icons/icon-search.svg deleted file mode 100644 index 70235a3b938b0fcc293866752cf3d8f96952e2ce..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-search.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-sun-outline.svg b/docs/.vitepress/src/assets/svg-icons/icon-sun-outline.svg deleted file mode 100644 index 5bfc68965118ffe7ce1238cca5bf833240cea82d..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-sun-outline.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-tips.svg b/docs/.vitepress/src/assets/svg-icons/icon-tips.svg deleted file mode 100644 index 5eaa71136ecc61c03f7aadb204e3c7dbf38f268a..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-tips.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/.vitepress/src/assets/svg-icons/icon-top.svg b/docs/.vitepress/src/assets/svg-icons/icon-top.svg deleted file mode 100644 index c571f630a2260ffb113b2de326a2c1603b0300f1..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/assets/svg-icons/icon-top.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/docs/.vitepress/src/components/AppFooter.vue b/docs/.vitepress/src/components/AppFooter.vue deleted file mode 100644 index 3c76608dc346fce4abe9cae235620c94be3aba5b..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/AppFooter.vue +++ /dev/null @@ -1,518 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/ContentWrapper.vue b/docs/.vitepress/src/components/ContentWrapper.vue deleted file mode 100644 index 02839616a4ec0ef0ad70f08c9aa7ade0e78ca815..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/ContentWrapper.vue +++ /dev/null @@ -1,69 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/CookieNotice.vue b/docs/.vitepress/src/components/CookieNotice.vue deleted file mode 100644 index 6b4947e7c3c016a9b2bb401a643415201b1450a6..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/CookieNotice.vue +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/DocBreadCrumb.vue b/docs/.vitepress/src/components/DocBreadCrumb.vue deleted file mode 100644 index 05ee2d9fae2b2a3c217cc1d715ad669b0fbaa2c9..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/DocBreadCrumb.vue +++ /dev/null @@ -1,104 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/DocBugDialog.vue b/docs/.vitepress/src/components/DocBugDialog.vue deleted file mode 100644 index 9a9076c5b5c2a01577b6b4b22e577eac095d76eb..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/DocBugDialog.vue +++ /dev/null @@ -1,275 +0,0 @@ - - - - diff --git a/docs/.vitepress/src/components/DocFooter.vue b/docs/.vitepress/src/components/DocFooter.vue deleted file mode 100644 index 18ab94c181832b408af7d2f57728f6bc9b182e15..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/DocFooter.vue +++ /dev/null @@ -1,117 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/DocMenu.vue b/docs/.vitepress/src/components/DocMenu.vue deleted file mode 100644 index 5cf84149b3ca1241c418f4bd4d875b8b22f63d7a..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/DocMenu.vue +++ /dev/null @@ -1,285 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/DocSearch.vue b/docs/.vitepress/src/components/DocSearch.vue deleted file mode 100644 index 8c2435c44c71cdedd461ec45cb461897a701ad7a..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/DocSearch.vue +++ /dev/null @@ -1,113 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/FloatingButton.vue b/docs/.vitepress/src/components/FloatingButton.vue deleted file mode 100644 index b63a5c42abb50826b800953912474b5d8391ce8c..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/FloatingButton.vue +++ /dev/null @@ -1,615 +0,0 @@ - - - - - - diff --git a/docs/.vitepress/src/components/ResultEmpty.vue b/docs/.vitepress/src/components/ResultEmpty.vue deleted file mode 100644 index 64619c7e46122c98153081383268b760ffbdfaf3..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/ResultEmpty.vue +++ /dev/null @@ -1,45 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/feedback/FeedbackSlider.vue b/docs/.vitepress/src/components/feedback/FeedbackSlider.vue deleted file mode 100644 index def8fd96a5547cc4381f46c2cbd054023e23ac2a..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/feedback/FeedbackSlider.vue +++ /dev/null @@ -1,275 +0,0 @@ - - - diff --git a/docs/.vitepress/src/components/header/AppHeader.vue b/docs/.vitepress/src/components/header/AppHeader.vue deleted file mode 100644 index 202bf9dac55c7451803e6804042ddfcd5fff9573..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/header/AppHeader.vue +++ /dev/null @@ -1,168 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/header/HeaderCode.vue b/docs/.vitepress/src/components/header/HeaderCode.vue deleted file mode 100644 index aab00237f1c1e646c7b1daf863a8d4ece5d0b557..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/header/HeaderCode.vue +++ /dev/null @@ -1,107 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/header/HeaderLanguage.vue b/docs/.vitepress/src/components/header/HeaderLanguage.vue deleted file mode 100644 index 0ec8e9b350045d33cf818bd3e637a8f483545934..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/header/HeaderLanguage.vue +++ /dev/null @@ -1,192 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/header/HeaderLogin.vue b/docs/.vitepress/src/components/header/HeaderLogin.vue deleted file mode 100644 index d83735038a644e56b9a6391ea92b9286dda3f965..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/header/HeaderLogin.vue +++ /dev/null @@ -1,79 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/header/HeaderNav.vue b/docs/.vitepress/src/components/header/HeaderNav.vue deleted file mode 100644 index 61ddad5637c8ce0976200ce49a29345e53f35694..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/header/HeaderNav.vue +++ /dev/null @@ -1,621 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/header/HeaderNavMoblie.vue b/docs/.vitepress/src/components/header/HeaderNavMoblie.vue deleted file mode 100644 index 7d430f4fdb8a92eee3d5c8e77dd773a7fd2d60f8..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/header/HeaderNavMoblie.vue +++ /dev/null @@ -1,302 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/header/HeaderSearch.vue b/docs/.vitepress/src/components/header/HeaderSearch.vue deleted file mode 100644 index d209a8ad9ef8da4023293dd751358490f6e49d7f..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/header/HeaderSearch.vue +++ /dev/null @@ -1,557 +0,0 @@ - - - diff --git a/docs/.vitepress/src/components/header/HeaderTheme.vue b/docs/.vitepress/src/components/header/HeaderTheme.vue deleted file mode 100644 index 6b6a2a4bad31f89060a097e83dcea6543a65703c..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/header/HeaderTheme.vue +++ /dev/null @@ -1,106 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/header/NavContent.vue b/docs/.vitepress/src/components/header/NavContent.vue deleted file mode 100644 index f61b2b3cc18e4e706367df0f071fcf3303f9c279..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/header/NavContent.vue +++ /dev/null @@ -1,232 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/header/NavLink.vue b/docs/.vitepress/src/components/header/NavLink.vue deleted file mode 100644 index 1cbb6c495ff16aaf915b227077256ace4e27feb1..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/header/NavLink.vue +++ /dev/null @@ -1,72 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/hooks/useClickOutside.ts b/docs/.vitepress/src/components/hooks/useClickOutside.ts deleted file mode 100644 index dbee26388b24cd8d515b3d7c61f06c847b2d55f8..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/hooks/useClickOutside.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { ref, onMounted, onUnmounted, type Ref } from 'vue'; -const useClickOutside = (elementRef: Ref) => { - const isClickOutside = ref(false); - const onClick = (e: MouseEvent) => { - if (elementRef.value) { - isClickOutside.value = !elementRef.value.contains(e.target as HTMLElement); - } - }; - onMounted(() => { - window.addEventListener('click', onClick); - }); - onUnmounted(() => { - window.removeEventListener('click', onClick); - }); - return isClickOutside; -}; - -export default useClickOutside; diff --git a/docs/.vitepress/src/components/menu/RecursionMenu.vue b/docs/.vitepress/src/components/menu/RecursionMenu.vue deleted file mode 100644 index 44b2b52de891c6ee44883cc308461533f7c90b92..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/menu/RecursionMenu.vue +++ /dev/null @@ -1,45 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/components/menu/RecursionMenuItem.vue b/docs/.vitepress/src/components/menu/RecursionMenuItem.vue deleted file mode 100644 index 4867b99f92967abd6d2d3f0f91191ff8253aa586..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/components/menu/RecursionMenuItem.vue +++ /dev/null @@ -1,113 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/composables/useDebounceSearch.ts b/docs/.vitepress/src/composables/useDebounceSearch.ts deleted file mode 100644 index 122a315a788dd72fea1f44ab8ebda2c73fb4fd68..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/composables/useDebounceSearch.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { useDebounceFn } from '@vueuse/core'; - -type FunctionArgs = (...args: Args) => Return; - -export const useDebounceSearch = (fn: T, delay = 300) => { - return useDebounceFn(fn, delay); -}; diff --git a/docs/.vitepress/src/composables/useLocale.ts b/docs/.vitepress/src/composables/useLocale.ts deleted file mode 100644 index 90ee3a9093a3e66b202f2aefb04c6f6d1c2aac9c..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/composables/useLocale.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { computed, onMounted } from 'vue'; -import { useData } from 'vitepress/client'; -import { isClient, isUndefined } from '@opensig/opendesign'; - -import type { LocaleT } from '@/@types/type-locale'; - -import i18n from '@/i18n'; -interface LocaleItemDeatilT { - [key: string]: string; -} -interface LocaleItemT { - [key: string]: LocaleItemDeatilT; -} -export const useLocale = () => { - const { lang } = useData(); - - const locale = computed(() => { - if (lang.value === 'zh' || lang.value === 'en') { - return lang.value === 'zh' ? 'zh' : 'en'; - } else { - if (isClient) { - const { pathname } = window.location; - if (pathname.startsWith('/zh/')) { - return 'zh'; - } else if (pathname.startsWith('/en/')) { - return 'en'; - } else { - if (localStorage.getItem('locale')) { - return localStorage.getItem('locale') === 'zh' ? 'zh' : 'en'; - } else { - return navigator.language.toLowerCase().startsWith('zh') ? 'zh' : 'en'; - } - } - } - - return 'zh'; - } - }); - - const isZh = computed(() => locale.value === 'zh'); - const isEn = computed(() => locale.value === 'en'); - - // 语言切换 - const changeLocale = (lang?: LocaleT) => { - if (locale.value === lang) { - return; - } - - const language = isUndefined(lang) ? (isZh.value ? 'en' : 'zh') : lang; - if (isClient) { - const { pathname } = window.location; - const newPathName = pathname.replace(`/${locale.value}/`, `/${language}/`); - localStorage.setItem('locale', language); - window.location.pathname = newPathName; - } - }; - - const t = (val: string, replacements?: string | string[] | number[]) => { - const [category, key] = val.split('.'); - const info: LocaleItemT = i18n.global.messages.value[locale.value]; - if (info) { - const item = info[category]; - if (item) { - let value = item[key]; - if (replacements) { - if (Array.isArray(replacements)) { - replacements.forEach((replacement, index) => { - value = value?.replace(`{${index}}`, String(replacement)); - }); - } else { - value = value?.replace(`{0}`, replacements); - } - } - return value; - } - } - }; - - const $t = t; - - onMounted(() => { - if (locale.value) { - localStorage.setItem('locale', locale.value); - } - }); - - return { - $t, - t, - locale, - isZh, - isEn, - changeLocale, - }; -}; diff --git a/docs/.vitepress/src/composables/useRoute.ts b/docs/.vitepress/src/composables/useRoute.ts deleted file mode 100644 index fb5879ff912fecbe9705d402db331a29c6699e5a..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/composables/useRoute.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { computed, onMounted, onUnmounted, readonly, ref } from 'vue'; -import { useRouter } from 'vitepress'; -import { isClient } from '@opensig/opendesign'; - -export const useRoute = () => { - const router = useRouter(); - const href = ref(isClient ? window.location.href : ''); - const hash = ref(isClient ? window.location.hash : ''); - - const pathname = computed(() => router.route.path); - const url = computed(() => { - return isClient ? href.value.replace(window.location.origin, '') : ''; - }); - - const hashchange = () => { - href.value = window.location.href || ''; - hash.value = window.location.hash || ''; - }; - - onMounted(() => { - window.addEventListener('hashchange', hashchange); - }) - - onUnmounted(() => { - window.removeEventListener('hashchange', hashchange); - }) - - - router.onAfterRouteChanged = () => { - hash.value = window.location.hash || ''; - href.value = window.location.href || ''; - }; - - return { - href: readonly(href), - hash: readonly(hash), - pathname, - url, - }; -} diff --git a/docs/.vitepress/src/composables/useScreen.ts b/docs/.vitepress/src/composables/useScreen.ts deleted file mode 100644 index ac5deec9acdc06b81de2479c56a38eb82459fefd..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/composables/useScreen.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { ref, reactive, computed, onMounted, onUnmounted, nextTick } from 'vue'; - -export enum Size { - Phone = 'phone', - PadV = 'pad_v', - PadH = 'pad_h', - Laptop = 'laptop', -} - -export type ScreenSizeT = typeof Size.Phone | Size.PadV | Size.PadH | Size.Laptop; - -export const ScreenConfig = { - [Size.Phone]: 600, - [Size.PadV]: 840, - [Size.PadH]: 1200, - [Size.Laptop]: 1440, -}; - -/** - * lt: less than, 小于 < - * le: less than or equal to, 小于等于 <= - * eq: equal to, 等于 = - * ne: never equal to, 不等于 != - * ge: greater than or equal to, 大于等于 >= - * gt: greater than, 大于 > - */ -export type CompareT = 'lt' | 'le' | 'eq' | 'ne' | 'ge' | 'gt'; - -const CompareHandler = { - lt: (a: number, b: number) => a < b, - le: (a: number, b: number) => a <= b, - eq: (a: number, b: number) => a === b, - ne: (a: number, b: number) => a !== b, - ge: (a: number, b: number) => a >= b, - gt: (a: number, b: number) => a > b, -}; - -export const useScreen = () => { - const screenSize = reactive({ - width: 1440, - height: 0, - }); - - const current = ref(Size.Laptop); - - const getSize = (width?: number) => { - if (typeof width === 'undefined') { - width = screenSize.width; - } - if (width < ScreenConfig[Size.Phone]) { - return Size.Phone; - } else if (width < ScreenConfig[Size.PadV]) { - return Size.PadV; - } else if (width < ScreenConfig[Size.PadH]) { - return Size.PadH; - } else { - return Size.Laptop; - } - }; - - const compare = (type: CompareT = 'eq', size: ScreenSizeT) => { - const w1 = screenSize.width; - const w2 = ScreenConfig[size]; - const handler = CompareHandler[type]; - return handler(w1, w2); - }; - - /** - * phone - */ - const isPhone = computed(() => compare('le', Size.Phone)); // [0, 600] - const gtPhone = computed(() => compare('gt', Size.Phone)); // [601, -] - - /** - * pad - */ - const isPad = computed(() => compare('gt', Size.Phone) && compare('le', Size.PadH)); // [601, 1200] - const lePad = computed(() => compare('le', Size.PadH)); // [0, 1200] - const gtPad = computed(() => compare('gt', Size.PadH)); // [1201, -] - - /** - * pad_v - */ - const isPadV = computed(() => compare('gt', Size.Phone) && compare('le', Size.PadV)); // [601, 840] - const lePadV = computed(() => compare('le', Size.PadV)); // [0, 840] - const gtPadV = computed(() => compare('gt', Size.PadV)); // [841, -] - - /** - * pad_h - */ - const isPadH = computed(() => compare('gt', Size.PadV) && compare('le', Size.PadH)); // [841, 1200] - - /** - * laptop - */ - const isLaptop = computed(() => compare('gt', Size.PadH) && compare('le', Size.Laptop)); // [1201, 1440] - const leLaptop = computed(() => compare('le', Size.Laptop)); // [0, 1440] - const gtLaptop = computed(() => compare('gt', Size.Laptop)); // [1441, -] - const isPadToLaptop = computed(() => compare('gt', Size.Phone) && compare('le', Size.Laptop)); // [601, 1440] - const isPadVToLaptop = computed(() => compare('gt', Size.PadV) && compare('le', Size.Laptop)); // [841, 1440] - - const onWindowResize = () => { - const { innerWidth, innerHeight } = window; - screenSize.width = innerWidth; - screenSize.height = innerHeight; - current.value = getSize(); - }; - - onMounted(() => { - if (typeof window !== 'undefined') { - window.addEventListener('resize', onWindowResize); - onWindowResize(); - nextTick(() => onWindowResize()); - } - }); - - onUnmounted(() => { - if (typeof window !== 'undefined') { - window.removeEventListener('resize', onWindowResize); - } - }); - - return { - // 获取屏幕宽度分级 - getSize, - // 当前屏幕分级 - current, - // 当前屏幕宽度 - size: screenSize, - - isPhone, // [0, 600] - gtPhone, // [601, -] - - isPad, // [601, 1200] - lePad, // [0, 1200] - gtPad, // [1201, -] - - isPadV, // [601, 840] - lePadV, // [0, 840] - gtPadV, // [841, -] - - isPadH, // [841, 1200] - - isLaptop, // [1201, 1440] - leLaptop, // [0, 1440] - gtLaptop, // [1441, -] - isPadToLaptop, // [601, 1440] - isPadVToLaptop, // [841, 1440] - }; -}; diff --git a/docs/.vitepress/src/composables/useSelect.ts b/docs/.vitepress/src/composables/useSelect.ts deleted file mode 100644 index 163168d9b53ba041f5f491bc6b5f61ad114b675d..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/composables/useSelect.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { computed, onMounted, onUnmounted, ref } from 'vue'; -import { inBrowser } from 'vitepress'; - -const useSelect = (selector: string) => { - const start = ref([0, 0]); // 鼠标开始位置 - const end = ref([0, 0]); // 鼠标结束位置 - const visible = ref(false); // 是否展示菜单 - const selectionText = ref(); // 选中的内容 - - const x = computed(() => (start.value[0] + end.value[0]) / 2); - const y = computed(() => { - if (scrollY.value) { - return scrollY.value; - } - return Math.min(start.value[1], end.value[1]) - 12; - }); - - const mouseDown = (e: MouseEvent) => { - start.value = [e.x, e.y]; - visible.value = false; - }; - const mouseUp = (e: MouseEvent) => { - end.value = [e.x, e.y]; - selectionText.value = window.getSelection()?.toString(); - visible.value = !!selectionText.value?.length && (start.value[0] !== end.value[0] || start.value[1] !== end.value[1]); - scrollY.value = 0; - }; - - const scrollTop = ref(0); // 当前已滚动距离 - const scrollY = ref(0); // 滚动时popover的位置 - - const scroll = ({ target }: { target: HTMLElement } & any) => { - if (visible.value) { - scrollY.value = y.value - target.scrollTop + scrollTop.value; - } - scrollTop.value = target.scrollTop; - }; - - const addEventListener = () => { - const ele = document.querySelector(selector) as HTMLElement; - if (ele) { - ele.addEventListener('mousedown', mouseDown); - ele.addEventListener('mouseup', mouseUp); - const scrollWrapper = document.querySelector('#app > .o-scroller > .o-scroller-container') as HTMLElement; - if (scrollWrapper) { - scrollWrapper.addEventListener('scroll', scroll); - } - } else { - requestIdleCallback(addEventListener); - } - }; - - onMounted(() => { - if (!inBrowser) return; - addEventListener(); - }); - - onUnmounted(() => { - if (!inBrowser) return; - const ele = document.querySelector(selector) as HTMLElement; - if (!ele) return; - ele?.removeEventListener('mousedown', mouseDown); - ele?.removeEventListener('mouseup', mouseUp); - const scrollWrapper = document.querySelector('#app > .o-scroller > .o-scroller-container'); - if (scrollWrapper) { - scrollWrapper.removeEventListener('scroll', scroll); - } - }); - - return { - x, - y, - visible, - selectionText, - }; -}; - -export default useSelect; diff --git a/docs/.vitepress/src/composables/useVisibleHeight.ts b/docs/.vitepress/src/composables/useVisibleHeight.ts deleted file mode 100644 index 0fa31e803f461d299c2331baf2463b6a4885ce21..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/composables/useVisibleHeight.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { isClient } from "@opensig/opendesign"; -import { onMounted, onUnmounted, readonly, ref } from "vue"; - -export const useVisibleHeight = (parentSelector: string, childSelector: string) => { - const height = ref(0); - let observer: IntersectionObserver | null; - - if (isClient) { - observer = new IntersectionObserver( - (entries) => { - entries.forEach((entry) => { - if (entry.isIntersecting) { - const parent = document.querySelector(parentSelector); - const child = document.querySelector(childSelector); - if (parent && child) { - const parentRect = parent.getBoundingClientRect(); - const childRect = child.getBoundingClientRect(); - const visibleTop = Math.max(0, childRect.top - parentRect.top); - const visibleBottom = Math.min(parentRect.bottom, childRect.bottom) - parentRect.top; - const visibleHeight = visibleBottom - visibleTop; - height.value = visibleHeight > 0 ? visibleHeight : 0; - } - } else { - height.value = 0; - } - }); - }, - { - threshold: Array.from({ length: 90 }, (_, i) => (i + 10) / 100), - } - ); - } - - onMounted(() => { - const footer = document.querySelector('.ly-footer'); - if (footer) { - observer?.observe(footer); - } - }); - - onUnmounted(() => { - const footer = document.querySelector('.ly-footer'); - if (footer) { - observer?.unobserve(footer); - } - - observer = null; - }); - - return readonly(height); -}; \ No newline at end of file diff --git a/docs/.vitepress/src/config/footer.ts b/docs/.vitepress/src/config/footer.ts deleted file mode 100644 index 7951bed4e9a119e9127c7596f1e90d70905cbabb..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/config/footer.ts +++ /dev/null @@ -1,463 +0,0 @@ -// 中文媒体链接 -import LogoBilibili from '@/assets/category/footer/bilibili.png'; -import LogoToutiao from '@/assets/category/footer/toutiao.png'; -import LogoJuejin from '@/assets/category/footer/juejin.png'; -import LogoOschina from '@/assets/category/footer/oschina.png'; -import LogoCsdn from '@/assets/category/footer/csdn.png'; - -// 英文媒体链接 -import LogoRedditSquare from '@/assets/category/footer/reddit-square.png'; -import LogoLinkedin from '@/assets/category/footer/linkdin.png'; -import LogoYoutube from '@/assets/category/footer/youtube.png'; -import LogoTwitter from '@/assets/category/footer/x.png'; - -// 中文媒体链接 -import LogoBilibiliHover from '@/assets/category/footer/bilibili_hover.png'; -import LogoToutiaoHover from '@/assets/category/footer/toutiao_hover.png'; -import LogoJuejinHover from '@/assets/category/footer/juejin_hover.png'; -import LogoOschinaHover from '@/assets/category/footer/oschina_hover.png'; -import LogoCsdnHover from '@/assets/category/footer/csdn_hover.png'; - -// 英文媒体链接 -import LogoRedditSquareHover from '@/assets/category/footer/reddit-square_hover.png'; -import LogoLinkedinHover from '@/assets/category/footer/linkdin_hover.png'; -import LogoYoutubeHover from '@/assets/category/footer/youtube_hover.png'; -import LogoTwitterHover from '@/assets/category/footer/x_hover.png'; - -// 媒体链接 -export const linksData = { - zh: [ - { - path: 'https://my.oschina.net/openeuler', - logo: { - normal: LogoOschina, - hover: LogoOschinaHover, - }, - id: 'oschina', - height: 14, - }, - { - path: 'https://blog.csdn.net/openEuler_?spm=1000.2115.3001.5343', - logo: { - normal: LogoCsdn, - hover: LogoCsdnHover, - }, - id: 'csdn', - height: 11, - }, - { - path: 'https://juejin.cn/user/3183782863845454', - logo: { - normal: LogoJuejin, - hover: LogoJuejinHover, - }, - id: 'juejin', - height: 11, - }, - { - path: 'https://space.bilibili.com/527064077/channel/series', - logo: { - normal: LogoBilibili, - hover: LogoBilibiliHover, - }, - id: 'bilibili', - height: 13, - }, - { - path: 'https://www.toutiao.com/c/user/token/MS4wLjABAAAAZivzVkJzMyQ44GzmX1i_ON0bgxL3E8ybHC-P9HMqZiqUgpYVnjCjynDt-SebKN7r', - logo: { - normal: LogoToutiao, - hover: LogoToutiaoHover, - }, - id: 'toutiao', - height: 13, - }, - ], - en: [ - { - path: 'https://www.linkedin.com/company/openeuler', - logo: { - normal: LogoLinkedin, - hover: LogoLinkedinHover, - }, - id: 'linkedin', - height: 16, - }, - { - path: 'https://x.com/openEuler', - logo: { - normal: LogoTwitter, - hover: LogoTwitterHover, - }, - id: 'twitter', - height: 16, - }, - { - path: 'https://www.youtube.com/channel/UCPzSqXqCgmJmdIicbY7GAeA', - logo: { - normal: LogoYoutube, - hover: LogoYoutubeHover, - }, - id: 'youtube', - height: 12, - }, - { - path: 'https://www.reddit.com/r/openEuler/', - logo: { - normal: LogoRedditSquare, - hover: LogoRedditSquareHover, - }, - id: 'reddit-square', - height: 16, - }, - ], -}; -// 隐私链接 -export const linksData2 = { - zh: [ - { - NAME: '品牌', - URL: 'https://www.openeuler.org/zh/other/brand/', - }, - { - NAME: '隐私政策', - URL: 'https://www.openeuler.org/zh/other/privacy/', - }, - { - NAME: '法律声明', - URL: 'https://www.openeuler.org/zh/other/legal/', - }, - { - NAME: '关于cookies', - URL: 'https://www.openeuler.org/zh/other/cookies/', - }, - ], - en: [ - { - NAME: 'Trademark', - URL: 'https://www.openeuler.org/en/other/brand/', - }, - { - NAME: 'Privacy Policy', - URL: 'https://www.openeuler.org/en/other/privacy/', - }, - { - NAME: 'Legal Notice', - URL: 'https://www.openeuler.org/en/other/legal/', - }, - { - NAME: 'About Cookies', - URL: 'https://www.openeuler.org/en/other/cookies/', - }, - ], -}; -// 底部导航数据 -export const quickNav = { - zh: [ - { - title: '关于openEuler', - list: [ - { - title: '成员单位', - link: '/zh/community/member/', - }, - { - title: '组织架构', - link: '/zh/community/organization/', - }, - { - title: '社区章程', - link: '/zh/community/charter/', - }, - { - title: '贡献看板', - link: 'https://datastat.openeuler.org/zh/overview', - }, - { - title: '社区介绍', - link: '/whitepaper/openEuler%20%E5%BC%80%E6%BA%90%E7%A4%BE%E5%8C%BA%E4%BB%8B%E7%BB%8D.pdf', - }, - ], - }, - { - title: '新闻与资讯', - list: [ - { - title: '新闻', - link: '/zh/interaction/news-list/', - }, - { - title: '博客', - link: '/zh/interaction/blog-list/', - }, - { - title: '白皮书', - link: '/zh/showcase/technical-white-paper/', - }, - ], - }, - { - title: '获取与下载', - list: [ - { - title: '获取openEuler操作系统', - link: '/zh/download/#get-openeuler', - }, - { - title: '最新社区发行版', - link: '/zh/download/', - }, - { - title: '商业发行版', - link: '/zh/download/commercial-release/', - }, - { - title: '软件中心', - link: 'https://easysoftware.openeuler.org/zh', - }, - ], - }, - { - title: '支持与服务', - list: [ - { - title: '文档', - link: 'https://docs.openeuler.org/zh/', - }, - { - title: 'FAQ', - link: 'https://www.openeuler.org/zh/faq/', - }, - { - title: '联系我们', - link: '/zh/contact-us/', - }, - // { - // title: '反馈问题', - // link: '', - // }, - ], - }, - { - title: '互动与交流', - list: [ - { - title: '邮件列表', - link: '/zh/community/mailing-list/', - }, - { - title: '活动', - link: '/zh/interaction/event-list/', - }, - { - title: '论坛', - link: 'https://forum.openeuler.org/', - }, - ], - }, - { - title: '贡献与成长', - list: [ - { - title: 'SIG中心', - link: '/zh/sig/sig-list/', - }, - { - title: '贡献攻略', - link: '/zh/community/contribution/', - }, - { - title: '课程中心', - link: '/zh/learn/mooc/', - }, - ], - }, - ], - en: [ - { - title: 'About openEuler', - list: [ - { - title: 'Members', - link: '/en/community/member/', - }, - { - title: 'Governance', - link: '/en/community/organization/', - }, - { - title: 'Code of Conduct', - link: '/en/community/charter/', - }, - { - title: 'Statistics', - link: 'https://datastat.openeuler.org/en/overview', - }, - ], - }, - { - title: 'News & Blogs', - list: [ - { - title: 'News', - link: '/en/interaction/news-list/', - }, - { - title: 'Blogs', - link: '/en/interaction/blog-list/', - }, - { - title: 'White Papers', - link: '/en/showcase/technical-white-paper/', - }, - ], - }, - { - title: 'Access', - list: [ - { - title: 'openEuler Is Everywhere', - link: '/en/download/#get-openeuler', - }, - { - title: 'Latest Community Releases', - link: '/en/download/', - }, - { - title: 'Commercial Releases', - link: '/en/download/commercial-release/', - }, - // { - // title: '软件中心', - // link: 'https://easysoftware.openeuler.org/en', - // }, - ], - }, - { - title: 'Services & Resources', - list: [ - { - title: 'Documentation', - link: 'https://docs.openeuler.org/en/', - }, - { - title: 'FAQ', - link: 'https://www.openeuler.org/en/faq/', - }, - { - title: 'Contact Us', - link: '/en/contact-us/', - }, - // { - // title: '反馈问题', - // link: '', - // }, - ], - }, - { - title: 'Communicate', - list: [ - { - title: 'Mailing Lists', - link: '/en/community/mailing-list/', - }, - { - title: 'Activities', - link: '/en/interaction/event-list/', - }, - { - title: 'Forum', - link: 'https://forum.openeuler.org/', - }, - ], - }, - { - title: 'Contribute', - list: [ - { - title: 'SIGs', - link: '/en/sig/sig-list/', - }, - { - title: 'Contribution Guide', - link: '/en/community/contribution/', - }, - { - title: 'Training', - link: '/zh/learn/mooc/', - }, - ], - }, - ], -}; - -export const friendshipLinks = { - zh: [ - { - link: 'http://www.mulanos.cn/', - title: '木兰开源社区', - }, - { - link: 'https://www.hikunpeng.com/zh/', - title: '鲲鹏社区', - }, - { - link: 'http://ic-openlabs.huawei.com/chat/#/', - title: '鲲鹏小智', - }, - { - link: 'https://pcl.ac.cn/', - title: '鹏城实验室', - }, - { - link: 'https://www.infoq.cn/?utm_source=openeuler&utm_medium=youlian', - title: 'infoQ', - }, - { - link: 'https://kaiyuanshe.cn/', - title: '开源社', - }, - { - link: 'http://www.vulab.com.cn/', - title: '中科微澜', - }, - { - link: 'https://www.authing.cn/', - title: 'Authing', - }, - { - link: 'https://www.opengauss.org/zh/', - title: 'openGauss', - }, - { - link: 'https://www.mindspore.cn/', - title: '昇思MindSpore', - }, - { - link: 'http://www.ebaina.com/', - title: 'Ebaina', - }, - ], - en: [ - { - link: 'https://www.infoq.cn/?utm_source=openeuler&utm_medium=youlian', - title: 'infoQ', - }, - { - link: 'https://www.authing.cn/', - title: 'Authing', - }, - { - link: 'https://www.opengauss.org/en/', - title: 'openGauss', - }, - { - link: 'https://www.mindspore.cn/', - title: 'MindSpore', - }, - { - link: 'http://www.ebaina.com/', - title: 'Ebaina', - }, - ], -}; diff --git a/docs/.vitepress/src/config/home.ts b/docs/.vitepress/src/config/home.ts deleted file mode 100644 index f93f043f4b0aa3e9e6a285db21e60d2d6719df16..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/config/home.ts +++ /dev/null @@ -1,161 +0,0 @@ -import BgStarted from '@/assets/category/home/started-bg.png'; -import BgStartedMo from '@/assets/category/home/started-mo-bg.png'; -import BgInstallGuide from '@/assets/category/home/install-guide-bg.png'; -import BgInstallGuideMo from '@/assets/category/home/started-mo-bg.png'; -import BgX2 from '@/assets/category/home/x2-bg.png'; -import BgX2Mo from '@/assets/category/home/x2-mo-bg.png'; -import BgQa from '@/assets/category/home/qa-bg.png'; -import BgQaMo from '@/assets/category/home/qa-mo-bg.png'; - -import BgStartedDark from '@/assets/category/home/started-bg-dark.png'; -import BgStartedMoDark from '@/assets/category/home/started-mo-bg-dark.png'; -import BgInstallGuideDark from '@/assets/category/home/install-guide-bg-dark.png'; -import BgInstallGuideMoDark from '@/assets/category/home/install-mo-bg-dark.png'; -import BgX2Dark from '@/assets/category/home/x2-bg-dark.png'; -import BgX2MoDark from '@/assets/category/home/x2-mo-bg-dark.png'; -import BgQaDark from '@/assets/category/home/qa-bg-dark.png'; -import BgQaMoDark from '@/assets/category/home/qa-mo-bg-dark.png'; - -import IconServer from '~icons/home/server.svg'; -import BgServer from '@/assets/category/home/server-bg.png'; -import IconVirtualization from '~icons/home/virtualization.svg'; -import BgVirtualization from '@/assets/category/home/virtualization-bg.png'; -import IconCloud from '~icons/home/cloud.svg'; -import BgCloud from '@/assets/category/home/cloud-bg.png'; -import IconEdgeComputing from '~icons/home/edge-computing.svg'; -import BgEdgeComputing from '@/assets/category/home/edge-computing-bg.png'; -import IconEmbedded from '~icons/home/embedded.svg'; -import BgEmbedded from '@/assets/category/home/embedded-bg.png'; - -// 卡片 -export const cardList = [ - { - background: { - light: BgStarted, - dark: BgStartedDark, - }, - backgroundMo: { - light: BgStartedMo, - dark: BgStartedMoDark, - }, - title: '新手入门', - desc: '10分钟玩转社区,快速构建与成长', - href: '/zh/Server/Quickstart/Quickstart/quick-start.html', - }, - { - background: { - light: BgInstallGuide, - dark: BgInstallGuideDark, - }, - backgroundMo: { - light: BgInstallGuideMo, - dark: BgInstallGuideMoDark, - }, - title: '安装指南', - desc: '指导用户顺利完成 openEuler 操作系统安装', - href: '/zh/Server/InstallationUpgrade/Installation/installation.html', - }, - { - background: { - light: BgQa, - dark: BgQaDark, - }, - backgroundMo: { - light: BgQaMo, - dark: BgQaMoDark, - }, - title: '常见问题', - desc: '常见问题解决方法', - href: 'https://www.openeuler.org/zh/faq/', - }, - { - background: { - light: BgX2, - dark: BgX2Dark, - }, - backgroundMo: { - light: BgX2Mo, - dark: BgX2MoDark, - }, - title: '贡献指南', - desc: '参与文档贡献的方式', - href: '/zh/Contribute/contribution_process.html', - }, -]; - -// 业务场景 -export const businessScenarioList = [ - { - icon: IconServer, - background: BgServer, - title: '服务器', - desc: '提供服务器场景的安装升级、管理运维、性能调优、应用开发等操作指南。', - href: '/zh/Server.html', - }, - { - icon: IconVirtualization, - background: BgVirtualization, - title: '虚拟化', - desc: '提供虚拟化场景(云计算)的用户指南,帮助用户了解虚拟化,以及安装和使用虚拟化。', - href: '/zh/Virtualization.html', - }, - { - icon: IconCloud, - background: BgCloud, - title: '云原生', - desc: '提供云原生场景(云计算)的用户指南,帮助用户安装和使用容器,部署集群等。', - href: '/zh/Cloud.html', - }, - { - icon: IconEdgeComputing, - background: BgEdgeComputing, - title: '边缘计算', - desc: '提供KubeEdge、K3S的安装和使用介绍。', - href: '/zh/EdgeComputing.html', - }, - { - icon: IconEmbedded, - background: BgEmbedded, - title: '嵌入式', - desc: '提供嵌入式场景的镜像构建、应用开发、系统管理等操作指南。', - href: '/zh/Embedded.html', - }, -]; - -export const toolList = [ - { - title: '社区工具', - desc: '提供镜像构建、编译、测试、性能优化、迁移、发布、软件包构建、虚拟化工具使用指南,如isocut、imageTailor、A-Tune、oeA…', - href: '/zh/Tools/CommunityTools.html', - }, - { - title: 'DevOps(社区服务)', - desc: '提供社区服务使用指南,包括patch-tracking、pkgship、EulerMaker、EulerDev…', - href: '/zh/Tools/DevOps.html', - }, - { - title: 'AI', - desc: '提供EulerCopilot智能问答使用指南、AI大模型服务镜像使用指南。', - href: '/zh/Tools/AI.html', - }, - { - title: '图形桌面使用', - desc: '提供桌面环境的安装和使用指南,包括UKUI、DDE、XFCE、Gnome、Kiran、I3', - href: '/zh/Tools/desktop.html', - }, - { - title: '云原生', - desc: '提供虚拟户场景下常用工具用户指南,包含虚拟机数据收集和分析工具vmtop,qemu热补丁框架工具LibcarePlus', - href: '/zh/Tools/Cloud.html', - }, - { - title: '系统运维', - desc: '提供服务器运维常用工具使用指南,包含智能运维框架Aops,异常监控服务sysmonitor', - href: '/zh/Tools/Maintenance.html', - }, - { - title: '安全', - desc: '提供服务器安全配置常用工具使用指南,包含机密计算统一开发框架secGear、OS内构入侵检测系统secDetector、安全防护系统safeg…', - href: '/zh/Tools/Security.html', - }, -]; diff --git a/docs/.vitepress/src/config/menu.ts b/docs/.vitepress/src/config/menu.ts deleted file mode 100644 index db934668086aed3903ed05adf5ae651d884a84b0..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/config/menu.ts +++ /dev/null @@ -1,4 +0,0 @@ -// @ts-ignore -import MENU from '/menu/menu.json?url&raw'; - -export const MENU_CONFIG = JSON.parse(MENU); diff --git a/docs/.vitepress/src/config/version.ts b/docs/.vitepress/src/config/version.ts deleted file mode 100644 index fbb1cee9b7d90fa1d088753291f72606fa3342f7..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/config/version.ts +++ /dev/null @@ -1,22 +0,0 @@ -export const versions = [ - { version: '25.03' }, - { version: '24.03 LTS SP1', href: 'https://docs.openeuler.org/zh/docs/24.03_LTS_SP1/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '22.03 LTS SP4', href: 'https://docs.openeuler.org/zh/docs/22.03_LTS_SP4/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '24.03 LTS', href: 'https://docs.openeuler.org/zh/docs/24.03_LTS/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '22.03 LTS SP3', href: 'https://docs.openeuler.org/zh/docs/22.03_LTS_SP3/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '20.03 LTS SP4', href: 'https://docs.openeuler.org/zh/docs/20.03_LTS_SP4/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '22.03 LTS SP1', href: 'https://docs.openeuler.org/zh/docs/22.03_LTS_SP1/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '24.09', href: 'https://docs.openeuler.org/zh/docs/24.09/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '23.09', href: 'https://docs.openeuler.org/zh/docs/23.09/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '22.03 LTS SP2', href: 'https://docs.openeuler.org/zh/docs/22.03_LTS_SP2/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '23.03', href: 'https://docs.openeuler.org/zh/docs/23.03/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '22.09', href: 'https://docs.openeuler.org/zh/docs/22.09/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '22.03 LTS', href: 'https://docs.openeuler.org/zh/docs/22.03_LTS/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '20.03 LTS SP3', href: 'https://docs.openeuler.org/zh/docs/20.03_LTS_SP3/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '21.09', href: 'https://docs.openeuler.org/zh/docs/21.09/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '20.03 LTS SP2', href: 'https://docs.openeuler.org/zh/docs/20.03_LTS_SP2/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '21.03', href: 'https://docs.openeuler.org/zh/docs/21.03/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '20.03 LTS SP1', href: 'https://docs.openeuler.org/zh/docs/20.03_LTS_SP1/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '20.09', href: 'https://docs.openeuler.org/zh/docs/20.09/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, - { version: '20.03 LTS', href: 'https://docs.openeuler.org/zh/docs/20.03_LTS/docs/Releasenotes/%E6%B3%95%E5%BE%8B%E5%A3%B0%E6%98%8E.html' }, -]; diff --git a/docs/.vitepress/src/directives/highlight.ts b/docs/.vitepress/src/directives/highlight.ts deleted file mode 100644 index 174322c585f25c8c5149fed882cceb18e83a61ed..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/directives/highlight.ts +++ /dev/null @@ -1,15 +0,0 @@ -import hljs from 'highlight.js'; - -export default { - mounted(el: HTMLElement, binding: { value: boolean }) { - if (binding.value) { - hljs.configure({ - ignoreUnescapedHTML: true, - }); - const blocks: NodeList = el.querySelectorAll('pre code'); - blocks.forEach((block) => { - hljs.highlightElement(block as HTMLElement); - }); - } - }, -}; diff --git a/docs/.vitepress/src/directives/index.ts b/docs/.vitepress/src/directives/index.ts deleted file mode 100644 index e73e54a55ae6ce33becb29e462b2b36e9cec3b7c..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/directives/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { Directive } from 'vue'; -import vHighlight from './highlight'; - -const directives: { [key: string]: Directive } = { - highlight: vHighlight, -}; - -export default directives; diff --git a/docs/.vitepress/src/i18n/common/common-en.ts b/docs/.vitepress/src/i18n/common/common-en.ts deleted file mode 100644 index e038e68466b0bc5b53ebaf4dd278380fbf70d1f4..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/i18n/common/common-en.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default { - returnHome: 'Back to Homepage', - empty: 'No data available', -}; diff --git a/docs/.vitepress/src/i18n/common/common-zh.ts b/docs/.vitepress/src/i18n/common/common-zh.ts deleted file mode 100644 index c52b495bc8289d2ccd795bdf2e99f2064fd6c23a..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/i18n/common/common-zh.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default { - returnHome: '返回首页', - empty: '暂无数据', -}; diff --git a/docs/.vitepress/src/i18n/common/index.ts b/docs/.vitepress/src/i18n/common/index.ts deleted file mode 100644 index 5e71d72c1d9ad7ef20febc50832f46fe39e82f91..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/i18n/common/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import zh from './common-zh'; -import en from './common-en'; - -export default { - zh, - en, -}; diff --git a/docs/.vitepress/src/i18n/docs/docs-en.ts b/docs/.vitepress/src/i18n/docs/docs-en.ts deleted file mode 100644 index 28b9e8db9c1a42691b6d683d420f497fcad2a14c..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/i18n/docs/docs-en.ts +++ /dev/null @@ -1,13 +0,0 @@ -export default { - inputTip: 'Enter a keyword.', - origin: 'Source', - noResultText: 'No result is found. Try other keywords.', - find: 'find', - result: 'result', - searchResult: 'Search Result', - copySuccess: 'Copied successfully.', - document: 'Document', - anchorTip: 'Content on This Page', - innerInputTip: 'Search in this document.', - version: 'Document Issue:', -}; diff --git a/docs/.vitepress/src/i18n/docs/docs-zh.ts b/docs/.vitepress/src/i18n/docs/docs-zh.ts deleted file mode 100644 index a499bec44d7b3d1f56c3f8d7fff42d45442ea6eb..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/i18n/docs/docs-zh.ts +++ /dev/null @@ -1,13 +0,0 @@ -export default { - inputTip: '请输入您要查询的文档内容/关键词', - origin: '来自', - noResultText: '未找到相关内容,请尝试其他搜索词', - find: '找到', - result: '个结果', - searchResult: '搜索结果', - copySuccess: '复制成功', - document: '文档', - anchorTip: '本页内容', - innerInputTip: '在本产品文档内搜索', - version: '文档版本:', -}; diff --git a/docs/.vitepress/src/i18n/docs/index.ts b/docs/.vitepress/src/i18n/docs/index.ts deleted file mode 100644 index 240e99ca1c15332d1e1003846fe1da373f14325e..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/i18n/docs/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import zh from './docs-zh'; -import en from './docs-en'; - -export default { - zh, - en, -}; diff --git a/docs/.vitepress/src/i18n/feedback/feedback-en.ts b/docs/.vitepress/src/i18n/feedback/feedback-en.ts deleted file mode 100644 index b89c092f17baab3991be2a47bbc294be0ef2b197..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/i18n/feedback/feedback-en.ts +++ /dev/null @@ -1,20 +0,0 @@ -export default { - title1: 'Are you satisfied with', - title2: ' openEuler Docs', - title3: '', - grade1: '0: Unsatisfied', - grade2: '10: Very satisfied', - placeholder1: 'Please tell us why you are not satisfied with openEuler Docs.', - placeholder2: 'What improvements would you like to see with openEuler Docs?', - placeholder3: 'Please tell us what you like about openEuler Docs.', - more1: 'Thanks for your feedback.', - submit: 'OK', - cancel: 'Cancel', - recommendTip1: 'Please tell us why you are not satisfied with openEuler Docs.', - recommendTip2: 'What improvements would you like to see with openEuler Docs?', - recommendTip3: 'Please tell us why you recommend openEuler Docs.', - submitBusy: 'Too many submissions. Try again later.', - feedbackFailed: 'Feedback failed.', - issueBack: 'Report an Issue', - issueBackDecs: 'Quickly get support from the technical team.', -}; diff --git a/docs/.vitepress/src/i18n/feedback/feedback-zh.ts b/docs/.vitepress/src/i18n/feedback/feedback-zh.ts deleted file mode 100644 index cbd7ab980fab544f922391a7762765b78ff8a0b8..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/i18n/feedback/feedback-zh.ts +++ /dev/null @@ -1,20 +0,0 @@ -export default { - title1: '您对', - title2: ' openEuler文档 ', - title3: '的整体满意度如何?', - grade1: '0-不满意', - grade2: '10-非常满意', - placeholder1: '请输入您不太满意的原因', - placeholder2: '改进哪些方面会让您更满意?', - placeholder3: '请输入您满意的原因', - more1: '感谢您的反馈', - submit: '确定', - cancel: '取消', - recommendTip1: '请输入您不太推荐的原因', - recommendTip2: '改进哪些方面会让您更愿意推荐?', - recommendTip3: '请输入您推荐的原因', - submitBusy: '您的提交过于频繁,请稍后再试', - feedbackFailed: '反馈失败', - issueBack: '问题反馈', - issueBackDecs: '获得技术团队的快速支持', -}; diff --git a/docs/.vitepress/src/i18n/feedback/index.ts b/docs/.vitepress/src/i18n/feedback/index.ts deleted file mode 100644 index 74a8767a27d3d815cf4a1569c2cadee832777e08..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/i18n/feedback/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import en from './feedback-en'; -import zh from './feedback-zh'; - -export default { - en, - zh, -}; diff --git a/docs/.vitepress/src/i18n/footer/footer-en.ts b/docs/.vitepress/src/i18n/footer/footer-en.ts deleted file mode 100644 index f838f3a6d899fdc3567e34ee9c9b4d064f7fa4f3..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/i18n/footer/footer-en.ts +++ /dev/null @@ -1,10 +0,0 @@ -export default { - atomText: 'openEuler is an open source project incubated and operated by the OpenAtom Foundation.', - mail: 'contact@openeuler.io', - copyRight: 'Copyright © {0} openEuler. All rights reserved.', - license_1: 'Licensed under', - license_2: 'the MulanPSL2', - qrCode: 'WeChat Subscription', - qrAssistant: 'WeChat Assistant', - friendshipLink: 'Related Links', -}; diff --git a/docs/.vitepress/src/i18n/footer/footer-zh.ts b/docs/.vitepress/src/i18n/footer/footer-zh.ts deleted file mode 100644 index 669bbd04b613d5441cc1bea70c9e68cab76474e7..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/i18n/footer/footer-zh.ts +++ /dev/null @@ -1,10 +0,0 @@ -export default { - atomText: 'openEuler 是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目', - mail: 'contact@openeuler.io', - copyRight: '版权所有 © {0} openEuler 保留一切权利', - license_1: '遵循', - license_2: '木兰宽松许可证第2版(MulanPSL2)', - qrCode: 'openEuler公众号', - qrAssistant: 'openEuler小助手', - friendshipLink: '友情链接', -}; diff --git a/docs/.vitepress/src/i18n/footer/index.ts b/docs/.vitepress/src/i18n/footer/index.ts deleted file mode 100644 index 950a6f9651894b5097ebb0cd32357659e3547a55..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/i18n/footer/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import zh from './footer-zh'; -import en from './footer-en'; - -export default { - zh, - en, -}; \ No newline at end of file diff --git a/docs/.vitepress/src/i18n/header/header-en.ts b/docs/.vitepress/src/i18n/header/header-en.ts deleted file mode 100644 index cb0d4f095b8b742f5bd4bdba6210282b40970fb2..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/i18n/header/header-en.ts +++ /dev/null @@ -1,609 +0,0 @@ -import { markRaw } from 'vue'; - -import Summit from '@/assets/category/header/summit.png'; -import IconOutLink from '~icons/app/icon-out-link.svg'; -import IconArrowRight from '~icons/app/icon-header-next.svg'; - -const TAG_TYPE = { - HOT: 'HOT', - NEW: 'NEW', -}; - -const OutLink = markRaw(IconOutLink); -const ArrowRight = markRaw(IconArrowRight); - -export default { - NAV_ROUTER: [ - { - NAME: 'Download', - ID: 'download', - CHILDREN: [ - { - NAME: 'Community Releases', - CHILDREN: [ - { - NAME: 'openEuler 24.03 LTS SP1', - DESCRIPTION: - 'openEuler 24.03 LTS SP1, an enhanced version of the 24.03 LTS release based on the 6.6 kernel, is designed for server, cloud, edge computing, and embedded deployments, offering new features and functionality for developers and users across diverse domains.', - TAG: TAG_TYPE.NEW, - URL: '/download/#openEuler 24.03 LTS SP1', - MOBILE_SHOW_CHILD: true, - CHILDREN: [ - { - NAME: 'Server', - URL: '/download/?scenario=ISO#openEuler 24.03 LTS SP1', - }, - { - NAME: 'Edge Cloud', - URL: '/download/?scenario=edge_img#openEuler 24.03 LTS SP1', - }, - { - NAME: 'Cloud Computing', - URL: '/download/?scenario=virtual_machine_img#openEuler 24.03 LTS SP1', - }, - { - NAME: 'Embedded', - URL: '/download/?scenario=embedded_img#openEuler 24.03 LTS SP1', - }, - { - NAME: 'DevStation', - URL: '/download/?scenario=DevStation#openEuler 24.03 LTS SP1', - }, - ], - }, - { - NAME: 'openEuler 24.09', - DESCRIPTION: 'The latest innovation version built on Linux kernel 6.6, with new features and faster updates.', - TAG: null, - URL: '/download/#openEuler 24.09', - MOBILE_SHOW_CHILD: true, - CHILDREN: [ - { - NAME: 'Server', - URL: '/download/?scenario=ISO#openEuler 24.09', - }, - { - NAME: 'Edge Cloud', - URL: '/download/?scenario=edge_img#openEuler 24.09', - }, - { - NAME: 'Cloud Computing', - URL: '/download/?scenario=virtual_machine_img#openEuler 24.09', - }, - { - NAME: 'Embedded', - URL: '/download/?scenario=embedded_img#openEuler 24.09', - }, - { - NAME: 'DevStation', - URL: '/download/?scenario=DevStation#openEuler 24.09', - }, - ], - }, - { - NAME: 'openEuler 22.03 LTS SP4', - DESCRIPTION: 'A patch version of openEuler 22.03 LTS. Both versions share the same lifecycle.', - TAG: null, - URL: '/download/#openEuler 22.03 LTS SP4', - MOBILE_SHOW_CHILD: true, - CHILDREN: [ - { - NAME: 'Server', - URL: '/download/?scenario=ISO#openEuler 22.03 LTS SP4', - }, - { - NAME: 'Edge Cloud', - URL: '/download/?scenario=edge_img#openEuler 22.03 LTS SP4', - }, - { - NAME: 'Cloud Computing', - URL: '/download/?scenario=virtual_machine_img#openEuler 22.03 LTS SP4', - }, - { - NAME: 'Embedded', - URL: '/download/?scenario=embedded_img#openEuler 22.03 LTS SP4', - }, - ], - }, - ], - SHORTCUT: [ - { - NAME: 'Technical White Papers', - URL: '/showcase/technical-white-paper/', - }, - { - NAME: 'openEuler 24.03 LTS SP1 Installation Guide', - URL: 'https://docs.openeuler.org/en/docs/24.03_LTS_SP1/docs/Installation/Installation.html', - }, - { - NAME: 'openEuler 24.09 Installation Guide', - URL: 'https://docs.openeuler.org/en/docs/24.09/docs/Installation/Installation.html', - }, - { - NAME: 'openEuler Lifecycle', - URL: '/other/lifecycle/', - }, - { - NAME: 'Historical Releases', - URL: '/download/archive/', - }, - ], - EXTRAS: [ - { - NAME: 'Get openEuler', - URL: '/download/#get-openeuler', - ICON: ArrowRight, - CHILDREN: [ - { - NAME: 'Cloud Images', - DESCRIPTION: 'openEuler has released official images on mainstream public cloud platforms', - URL: '/download/#cloud', - }, - { - NAME: 'Container Images', - DESCRIPTION: 'openEuler provides official container images', - URL: '/download/#container', - }, - { - NAME: 'Windows', - DESCRIPTION: 'Running openEuler on Windows', - URL: '/download/#windows', - }, - { - NAME: 'MacOS', - DESCRIPTION: 'Running openEuler on MacOS', - URL: '/download/#macos', - }, - { - NAME: 'Virtualization', - DESCRIPTION: 'Running openEuler on VMs', - URL: '/download/#virtualization', - }, - { - NAME: 'Raspberry Pi', - DESCRIPTION: 'Installing openEuler on Raspberry Pi', - URL: '/download/#raspberrypi', - }, - ], - }, - ], - }, - { - NAME: 'Other Releases', - CHILDREN: [ - { - NAME: 'Commercial Releases', - DESCRIPTION: 'Commercial releases for x86, Arm, and RISC-V.', - URL: '/download/commercial-release/', - }, - ], - SHORTCUT: [], - }, - { - NAME: 'Install', - CHILDREN: [ - { - NAME: 'Mirrors', - DESCRIPTION: 'All mirrors of openEuler.', - URL: '/mirror/list/', - }, - { - NAME: 'Repo', - DESCRIPTION: "Repo of openEuler's community releases.", - URL: 'https://repo.openeuler.openatom.cn/', - }, - ], - SHORTCUT: [], - }, - ], - }, - { - NAME: 'Learn', - ID: 'learn', - CHILDREN: [ - { - NAME: 'Documentation', - ICON: ArrowRight, - URL: 'https://docs.openeuler.org/en/', - CHILDREN: [ - { - NAME: 'Trending Docs', - DESCRIPTION: 'The most viewed documents.', - TAG: TAG_TYPE.HOT, - URL: 'https://docs.openeuler.org/en/#hot', - }, - { - NAME: 'Create Apps', - DESCRIPTION: 'Guides for application development on openEuler.', - URL: 'https://docs.openeuler.org/en/docs/24.03_LTS/docs/ApplicationDev/application-development.html', - }, - { - NAME: 'Getting Started', - DESCRIPTION: 'Documentation guides to help you get started with openEuler.', - URL: 'https://docs.openeuler.org/en/#process', - }, - { - NAME: 'Tools', - DESCRIPTION: 'Resources for using and accessing commonly used tools.', - TAG: TAG_TYPE.HOT, - URL: 'https://docs.openeuler.org/en/#tool', - }, - ], - SHORTCUT: [ - { - NAME: 'openEuler 24.03 LTS Documentation', - URL: 'https://docs.openeuler.org/en/docs/24.03_LTS/docs/Releasenotes/terms-of-use.html', - }, - { - NAME: 'Installation and Upgrade', - URL: 'https://docs.openeuler.org/en/docs/24.03_LTS/docs/Installation/Installation.html', - }, - ], - }, - { - NAME: 'Training', - ICON: ArrowRight, - URL: '/learn/mooc/', - CHILDREN: [ - { - NAME: 'Tutorials', - DESCRIPTION: 'Mini video courses presented by openEuler.', - URL: 'https://www.youtube.com/playlist?list=PLtDfk9jvMAziPyVaA-DOkXx0GgIUjXc0_', - ICON: OutLink, - }, - ], - SHORTCUT: [], - }, - { - NAME: 'Migration', - CHILDREN: [ - { - NAME: 'Migrate to openEuler', - DESCRIPTION: 'Guides for migrating to openEuler.', - URL: '/migration/', - }, - ], - SHORTCUT: [ - { - NAME: 'Get x2openEuler', - URL: '/migration/download/', - }, - { - NAME: 'Migration Practices', - URL: '/migration/user-cases/', - }, - ], - }, - { - NAME: 'Tech Highlights', - CHILDREN: [ - { - NAME: 'Success Stories', - DESCRIPTION: 'Explore how openEuler is used across various industries.', - URL: '/showcase/', - }, - { - NAME: 'White Papers', - DESCRIPTION: 'Insights into the tech details and applications of each release.', - URL: '/showcase/technical-white-paper/', - }, - ], - SHORTCUT: [], - }, - ], - }, - { - NAME: 'Develop', - ID: 'development', - CHILDREN: [ - { - NAME: 'Build', - CHILDREN: [ - { - NAME: 'EulerMaker', - DESCRIPTION: 'An open, unified build service for streamlined development.', - URL: 'https://eulermaker.compass-ci.openeuler.openatom.cn/', - ANALYTICSNAME: 'eulermaker', - }, - { - NAME: 'openEuler User Repo', - DESCRIPTION: 'An easy-to-use package hosting and distribution platform.', - URL: 'https://eur.openeuler.openatom.cn/coprs/', - }, - { - NAME: 'Submit Package', - DESCRIPTION: 'Contribute software packages efficiently to the community.', - URL: 'https://software-pkg.openeuler.org/en/package', - }, - ], - }, - { - NAME: 'Release', - CHILDREN: [ - { - NAME: 'OEPKGS', - DESCRIPTION: 'A third-party extension repository for openEuler.', - URL: 'https://oepkgs.net/en-CN', - ICON: OutLink, - }, - ], - }, - { - NAME: 'Analyze', - CHILDREN: [ - { - NAME: 'Pkgship', - DESCRIPTION: 'A tool to query OS package information and dependencies with ease.', - URL: 'https://pkgmanage.openeuler.org/', - ANALYTICSNAME: 'pkgship', - }, - ], - }, - { - NAME: 'Submit Issue', - CHILDREN: [ - { - NAME: 'QuickIssue', - DESCRIPTION: 'Submit and track community issues quickly and easily.', - URL: 'https://quickissue.openeuler.org/en/issues/', - }, - ], - }, - ], - }, - { - NAME: 'Support', - ID: 'approve', - CHILDREN: [ - { - NAME: 'Compatibility', - CHILDREN: [ - { - NAME: 'Compatibility List', - DESCRIPTION: 'Check hardware and software compatibility with openEuler.', - URL: '/compatibility/', - }, - ], - SHORTCUT: [ - { - NAME: 'Overall Introduction to the openEuler Hardware Compatibility Test', - URL: '/compatibility/hardware/', - }, - ], - }, - { - NAME: 'Services & Resources', - CHILDREN: [ - { - NAME: 'x2openEuler', - DESCRIPTION: 'A user-friendly tool to seamlessly migrate your OS to openEuler.', - URL: 'https://docs.openeuler.org/en/docs/20.03_LTS_SP1/docs/x2openEuler/Introduction.html', - }, - { - NAME: 'Security Center', - DESCRIPTION: 'Track the latest vulnerabilities, security advisories, and more.', - URL: '', - MOBILE_SHOW_CHILD: true, - CHILDREN: [ - { - NAME: 'Security Center', - URL: '/security/security-bulletins/', - }, - { - NAME: 'Bug Center', - URL: '/security/bug-bulletins/', - }, - ], - }, - { - NAME: 'FAQs', - DESCRIPTION: 'Find the answers to common questions about openEuler.', - URL: '/faq/', - }, - ], - SHORTCUT: [ - { - NAME: 'QuickIssue ', - URL: 'https://quickissue.openeuler.org/en/issues/', - }, - ], - }, - ], - }, - { - NAME: 'Community', - ID: 'community', - CHILDREN: [ - { - NAME: 'About', - CHILDREN: [ - { - NAME: 'Governance', - DESCRIPTION: 'Members of openEuler committees.', - URL: '/community/organization/', - }, - { - NAME: 'Code of Conduct', - DESCRIPTION: "openEuler's code of conduct.", - URL: '/community/conduct/', - }, - { - NAME: 'Members', - DESCRIPTION: 'Companies and organizations contributing to openEuler.', - URL: '/community/member/', - }, - { - NAME: 'Statistics', - DESCRIPTION: 'Find stats and see how the openEuler community thrives.', - URL: 'https://datastat.openeuler.org/en/overview', - }, - ], - SHORTCUT: [], - }, - { - NAME: 'Contribute', - CHILDREN: [ - { - NAME: 'SIGs', - DESCRIPTION: 'Explore diverse SIGs.', - URL: '/sig/sig-list/', - }, - { - NAME: 'Contribution Guide', - DESCRIPTION: 'See how to get involved and make an impact in our community.', - URL: '/community/contribution/', - }, - { - NAME: 'CLA', - DESCRIPTION: 'Sign the CLA to protect your work—multiple options available!', - URL: 'https://clasign.osinfra.cn/sign/gitee_openeuler-1611298811283968340', - ICON: OutLink, - }, - ], - SHORTCUT: [], - }, - { - NAME: 'Projects', - CHILDREN: [ - { - NAME: 'A-Tune', - DESCRIPTION: 'An AI-powered intelligent tuning engine.', - URL: '/other/projects/atune/', - }, - { - NAME: 'iSula', - DESCRIPTION: 'A container solution.', - URL: '/other/projects/isula/', - }, - { - NAME: 'StratoVirt', - DESCRIPTION: 'An enterprise-grade virtual machine monitor for cloud data centers.', - URL: '/other/projects/stratovirt/', - }, - { - NAME: 'BiSheng JDK', - DESCRIPTION: 'A high-performance Java Virtual Machine.', - URL: '/other/projects/bishengjdk/', - }, - { - NAME: 'secGear', - DESCRIPTION: 'A confidential computing framework for building secure applications.', - URL: '/other/projects/secgear/', - }, - ], - SHORTCUT: [], - }, - { - NAME: 'Engage with Us', - CHILDREN: [ - { - NAME: 'Forum', - DESCRIPTION: 'Share knowledge, ask anything, and solve together.', - URL: 'https://forum.openeuler.org/?locale=en', - }, - { - NAME: 'Mailing Lists', - DESCRIPTION: 'Discuss openEuler tech and progress on our mailing lists.', - URL: '/community/mailing-list/', - }, - { - NAME: 'Contact Us', - DESCRIPTION: '', - URL: '/contact-us/', - TAG: TAG_TYPE.NEW, - }, - ], - SHORTCUT: [], - }, - ], - }, - - { - NAME: 'Stay Updated', - ID: 'update', - CHILDREN: [ - { - NAME: 'Activities', - CHILDREN: [ - { - NAME: 'Community Calendar', - DESCRIPTION: "Stay informed with openEuler's key events, conferences, and releases.", - URL: '/interaction/event-list/', - }, - { - NAME: 'Events', - DESCRIPTION: 'Meet openEuler and connect with the community at every key event.', - URL: '/interaction/summit-list/summit2024/', - }, - { - NAME: 'Call for X Program', - DESCRIPTION: 'Become openEuler Valuable Professionals or contribute tech tutorials!', - URL: '/community/program/', - }, - ], - WITH_PICTURE: true, - SHORTCUT: [ - { - NAME: 'Operating System Confenrence & openEuler Summit 2024', - PICTURE: Summit, - DESCRIPTION: - 'Operating systems form the backbone of digital and intelligent industry transformation. openEuler, an open source operating system born in China for digital infrastructure, has emerged as a key player in the global open source landscape. Over the past five years, its market presence was steadily increasing. And openEuler has been continuously driving innovations in OS for AI and AI for OS, accelerating digital transformation, and fostering a thriving ecosystem though industry-wide collaboration.', - REMARK: 'November 15-16, 2024 | Beijing', - TYPE: 'PICTURE', - URL: '/interaction/summit-list/summit2024/', - }, - ], - }, - { - NAME: 'News & Blogs', - CHILDREN: [ - { - NAME: 'News', - DESCRIPTION: 'Follow the latest developments, releases, and community updates.', - URL: '/interaction/news-list/', - }, - { - NAME: 'Blogs', - DESCRIPTION: 'Gain in-depth knowledge and fresh perspectives on openEuler.', - URL: '/interaction/blog-list/', - }, - { - NAME: 'Monthly Bulletins', - DESCRIPTION: "What's new in the openEuler community.", - URL: '/monthly-bulletins/', - }, - ], - SHORTCUT: [], - }, - ], - }, - ], - USER_CENTER: 'User Center', - MESSAGE_CENTER: 'Message Center', - LOGOUT: 'Logout', - CODE: 'Code', - QUICKLINK: 'Quick Link', - SEARCH: { - BROWSEHISTORY: 'History', - CLEAN: 'Clean up', - TOPSEARCH: 'Top search', - CHANGE: 'Change', - PLEACHOLDER: 'Please enter...', - PLEACHOLDER_EXTEND: 'Please enter the content', - TEXT: 'Search', - }, - SOURCE_CODE: [ - { - NAME: 'Code Sources', - PATH: 'https://gitee.com/openeuler', - }, - { - NAME: 'Package Sources', - PATH: 'https://gitee.com/src-openeuler', - }, - { - NAME: 'GitHub Mirror', - PATH: 'https://github.com/openeuler-mirror', - }, - ], -}; diff --git a/docs/.vitepress/src/i18n/header/header-zh.ts b/docs/.vitepress/src/i18n/header/header-zh.ts deleted file mode 100644 index d8c0cdf9a1b655f619db193d5add68c3bcacff65..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/i18n/header/header-zh.ts +++ /dev/null @@ -1,824 +0,0 @@ -import { markRaw } from 'vue'; - -import Summit from '@/assets/category/header/summit.png'; -import Sig from '@/assets/category/header/sig.png'; -import Report from '@/assets/category/header/report.png'; -import annualReport2024 from '@/assets/category/header/annual-report-2024.jpg'; - -import IconOutLink from '~icons/app/icon-out-link.svg'; -import IconArrowRight from '~icons/app/icon-header-next.svg'; - -const TAG_TYPE = { - HOT: 'HOT', - NEW: 'NEW', -}; - -const OutLink = markRaw(IconOutLink); -const ArrowRight = markRaw(IconArrowRight); - -export default { - NAV_ROUTER: [ - { - NAME: '下载', - ID: 'download', - CHILDREN: [ - { - NAME: '社区发行版', - CHILDREN: [ - { - NAME: 'openEuler 24.03 LTS SP1', - DESCRIPTION: - 'openEuler 24.03 LTS SP1 是基于6.6内核的24.03 LTS版本增强扩展版本,面向服务器、云、边缘计算和嵌入式场景,持续提供更多新特性和功能扩展,给开发者和用户带来全新的体验,服务更多的领域和更多的用户。', - TAG: TAG_TYPE.NEW, - URL: '/download/#openEuler 24.03 LTS SP1', - MOBILE_SHOW_CHILD: true, - CHILDREN: [ - { - NAME: '服务器', - URL: '/download/?scenario=ISO#openEuler 24.03 LTS SP1', - }, - { - NAME: '边缘计算', - URL: '/download/?scenario=edge_img#openEuler 24.03 LTS SP1', - }, - { - NAME: '云计算', - URL: '/download/?scenario=virtual_machine_img#openEuler 24.03 LTS SP1', - }, - { - NAME: '嵌入式', - URL: '/download/?scenario=embedded_img#openEuler 24.03 LTS SP1', - }, - { - NAME: 'DevStation', - URL: '/download/?scenario=DevStation#openEuler 24.03 LTS SP1', - }, - ], - }, - { - NAME: 'openEuler 24.09', - DESCRIPTION: 'openEuler 24.09 是基于Linux 6.6内核的创新版本,面向服务器、云、边缘计算和嵌入式场景,提供更多新特性和功能', - TAG: null, - URL: '/download/#openEuler 24.09', - MOBILE_SHOW_CHILD: true, - CHILDREN: [ - { - NAME: '服务器', - URL: '/download/?scenario=ISO#openEuler 24.09', - }, - { - NAME: '边缘计算', - URL: '/download/?scenario=edge_img#openEuler 24.09', - }, - { - NAME: '云计算', - URL: '/download/?scenario=virtual_machine_img#openEuler 24.09', - }, - { - NAME: '嵌入式', - URL: '/download/?scenario=embedded_img#openEuler 24.09', - }, - { - NAME: 'DevStation', - URL: '/download/?scenario=DevStation#openEuler 24.09', - }, - ], - }, - { - NAME: 'openEuler 22.03 LTS SP4', - DESCRIPTION: 'openEuler 22.03 LTS SP4 是openEuler 22.03 LTS的补丁版本,生命周期与LTS版本相同', - TAG: null, - URL: '/download/#openEuler 22.03 LTS SP4', - MOBILE_SHOW_CHILD: true, - CHILDREN: [ - { - NAME: '服务器', - URL: '/download/?scenario=ISO#openEuler 22.03 LTS SP4', - }, - { - NAME: '边缘计算', - URL: '/download/?scenario=edge_img#openEuler 22.03 LTS SP4', - }, - { - NAME: '云计算', - URL: '/download/?scenario=virtual_machine_img#openEuler 22.03 LTS SP4', - }, - { - NAME: '嵌入式', - URL: '/download/?scenario=embedded_img#openEuler 22.03 LTS SP4', - }, - ], - }, - ], - SHORTCUT: [ - { - NAME: '技术白皮书', - URL: '/showcase/technical-white-paper/', - }, - { - NAME: '24.03 LTS SP1安装指南', - URL: 'https://docs.openeuler.org/zh/docs/24.03_LTS_SP1/docs/Installation/installation.html', - }, - { - NAME: '24.09安装指南', - URL: 'https://docs.openeuler.org/zh/docs/24.09/docs/Installation/installation.html', - }, - { - NAME: '版本生命周期', - URL: '/other/lifecycle/', - }, - { - NAME: '查询所有版本', - URL: '/download?archive=true', - }, - ], - EXTRAS: [ - { - NAME: '其他获取方式', - URL: '/download/#get-openeuler', - ICON: ArrowRight, - CHILDREN: [ - { - NAME: '公有云', - DESCRIPTION: 'openEuler官方镜像在以下主流平台正式发布', - URL: '/download/#cloud', - }, - { - NAME: '容器镜像', - DESCRIPTION: 'openEuler提供官方容器镜像', - URL: '/download/#container', - }, - { - NAME: 'Windows', - DESCRIPTION: '在Windows上运行openEuler', - URL: '/download/#windows', - }, - { - NAME: 'MacOS', - DESCRIPTION: '在MacOS上运行openEuler', - URL: '/download/#macos', - }, - { - NAME: '虚拟化', - DESCRIPTION: '在虚拟机上运行openEuler', - URL: '/download/#virtualization', - }, - { - NAME: '树莓派', - DESCRIPTION: '在树莓派上安装openEuler', - URL: '/download/#raspberrypi', - }, - ], - }, - ], - }, - { - NAME: '其他版本', - CHILDREN: [ - { - NAME: '商业发行版', - DESCRIPTION: '基于openEuler发布的商业发行版。x86、AArch、LoongArch、sw 、RISC-V', - URL: '/download/commercial-release/', - }, - ], - SHORTCUT: [], - }, - { - NAME: '下载资源', - CHILDREN: [ - { - NAME: '软件中心', - DESCRIPTION: '简易便捷地查询openEuler社区软件包', - TAG: TAG_TYPE.NEW, - URL: 'https://easysoftware.openeuler.org/zh', - }, - { - NAME: '镜像仓列表', - DESCRIPTION: '查询openEuler所有镜像站点,欢迎新站点的加入', - URL: '/mirror/list/', - }, - { - NAME: 'Repo源', - DESCRIPTION: '提供openEuler社区版本的repo文件', - URL: 'https://repo.openeuler.openatom.cn/', - }, - ], - SHORTCUT: [], - }, - ], - }, - { - NAME: '学习', - ID: 'learn', - CHILDREN: [ - { - NAME: '文档中心', - ICON: ArrowRight, - URL: 'https://docs.openeuler.org/zh/', - CHILDREN: [ - { - NAME: '热门文档', - DESCRIPTION: '当下最受关注的各类文档', - TAG: TAG_TYPE.HOT, - URL: 'https://docs.openeuler.org/zh/#hot', - }, - { - NAME: '开发教程', - DESCRIPTION: '基于openEuler进行应用程序开发的指南文档', - URL: 'https://docs.openeuler.org/zh/docs/24.03_LTS/docs/ApplicationDev/application-development.html', - }, - { - NAME: '流程规范', - DESCRIPTION: '社区文档贡献的具体流程与规范要求', - URL: 'https://docs.openeuler.org/zh/#process', - }, - { - NAME: '工具查询', - DESCRIPTION: '常用工具的使用指南', - TAG: TAG_TYPE.HOT, - URL: 'https://docs.openeuler.org/zh/#tool', - }, - ], - SHORTCUT: [ - { - NAME: '24.03LTS文档', - URL: 'https://docs.openeuler.org/zh/docs/24.03_LTS/docs/Releasenotes/法律声明.html', - }, - { - NAME: '安装升级', - URL: 'https://docs.openeuler.org/zh/docs/24.03_LTS/docs/Installation/installation.html', - }, - { - NAME: '文档撰写指南', - ICON: OutLink, - URL: 'https://gitee.com/openeuler/docs/blob/master/contribute/写作规范.md', - }, - ], - }, - { - NAME: '课程中心', - ICON: ArrowRight, - URL: '/learn/mooc/', - CHILDREN: [ - { - NAME: 'HCIA-openEuler 认证培训课程', - DESCRIPTION: '学习HCIA-openEuler华为认证openEuler工程师在线课程', - MOBILE_SHOW_CHILD: true, - CHILDREN: [ - { - NAME: '开始学习', - URL: '/learn/mooc/detail/', - }, - { - NAME: '报名考试', - URL: 'https://e.huawei.com/cn/talent/#/cert/product-details?certifiedProductId=383&authenticationLevel=CTYPE_CARE_HCIA&technicalField=PSC&version=1.0', - ICON: OutLink, - }, - ], - }, - { - NAME: 'openEuler精品课程', - DESCRIPTION: 'openEuler从入门到实践系列课程', - URL: 'https://c0605e03bb6b40dca9cd34ab5b3fb1f8.shixizhi.huawei.com/portal/1643780836745113602?pageId=1644269448177651714&activeIndex=-1&sxz-lang=zh_CN', - ICON: OutLink, - }, - { - NAME: 'openEuler安全知识培训', - DESCRIPTION: 'openEuler基础安全意识与能力培训', - MOBILE_SHOW_CHILD: true, - CHILDREN: [ - { - NAME: '开始学习', - URL: 'https://space.bilibili.com/527064077/channel/collectiondetail?sid=2726214', - ICON: OutLink, - }, - { - NAME: '报名考试', - URL: '/blog/openeuler/20240428-security.html', - }, - ], - }, - { - NAME: 'Tutorials', - DESCRIPTION: 'openEuler官方出品的迷你视频课程', - URL: 'https://space.bilibili.com/527064077/channel/collectiondetail?sid=1229363', - ICON: OutLink, - }, - { - NAME: 'openEuler直播', - DESCRIPTION: '众多大咖精彩课程直播', - URL: '/interaction/live-list/', - }, - ], - SHORTCUT: [ - { - NAME: '从入门到精通-openEuler操作系统迁移专题', - URL: 'https://c0605e03bb6b40dca9cd34ab5b3fb1f8.shixizhi.huawei.com/community/community.htm?communityId=1748285175854272513&schoolId=1643780836745113602&activeIndex=-1&subIndex=undefined&subIndex=undefined&sxz-lang=zh_CN', - }, - ], - }, - { - NAME: '迁移与运维', - CHILDREN: [ - { - NAME: '迁移专区', - DESCRIPTION: '助力企业进行操作系统迁移的指南文档', - URL: '/migration/', - }, - { - NAME: '运维专区', - DESCRIPTION: 'openEuler运维全集和工具', - URL: '/om/', - }, - ], - SHORTCUT: [ - { - NAME: '迁移工具x2openEuler', - URL: '/migration/download/', - }, - { - NAME: '迁移实践', - URL: '/migration/user-cases/', - }, - ], - }, - { - NAME: '技术展示', - CHILDREN: [ - { - NAME: '用户案例', - DESCRIPTION: '了解openEuler在各行业的最佳案例', - URL: '/showcase/', - }, - { - NAME: '白皮书', - DESCRIPTION: '了解openEuler各版本的技术详情及在行业的生态现状、业务场景的应用', - URL: '/showcase/technical-white-paper/', - }, - { - NAME: '市场研究报告', - DESCRIPTION: '了解openEuler在行业的市场研究情况', - URL: '/showcase/market-report/', - }, - ], - SHORTCUT: [], - }, - ], - }, - { - NAME: '开发', - ID: 'development', - CHILDREN: [ - { - NAME: '构建', - CHILDREN: [ - { - NAME: 'EulerMaker', - DESCRIPTION: '开放式统一构建服务', - URL: 'https://eulermaker.compass-ci.openeuler.openatom.cn/', - ANALYTICSNAME: 'eulermaker', - }, - { - NAME: '用户软件仓(EUR)', - DESCRIPTION: '开发者易用的软件包托管分发平台', - URL: 'https://eur.openeuler.openatom.cn/coprs/', - }, - { - NAME: '软件包贡献', - DESCRIPTION: '简单高效地贡献软件包', - URL: 'https://software-pkg.openeuler.org/zh/package', - }, - { - NAME: 'License工具门户', - DESCRIPTION: '帮助快速检测License权利、义务、限制', - URL: 'https://compliance.openeuler.org/', - ICON: OutLink, - ANALYTICSNAME: 'license', - }, - ], - }, - { - NAME: '发布', - CHILDREN: [ - { - NAME: 'EulerPublisher', - DESCRIPTION: 'openEuler云原生发布工具', - URL: 'https://gitee.com/openeuler/eulerpublisher', - ICON: OutLink, - }, - { - NAME: 'EulerLauncher', - DESCRIPTION: '跨平台openEuler虚拟机管理工具', - URL: 'https://gitee.com/openeuler/eulerlauncher', - ICON: OutLink, - }, - { - NAME: 'OEPKGS', - DESCRIPTION: 'OEPKGS软件托管平台', - URL: 'https://oepkgs.net/zh-CN', - ICON: OutLink, - }, - ], - }, - { - NAME: '分析', - CHILDREN: [ - { - NAME: 'oecp', - DESCRIPTION: '操作系统差异比较分析工具', - URL: 'https://gitee.com/openeuler/oecp', - ICON: OutLink, - }, - { - NAME: 'Pkgship', - DESCRIPTION: '管理操作系统软件包信息和依赖项的查询工具', - URL: 'https://pkgmanage.openeuler.org/', - ANALYTICSNAME: 'pkgship', - }, - ], - }, - { - NAME: '问题反馈', - CHILDREN: [ - { - NAME: 'QuickIssue', - DESCRIPTION: '简易快捷地查询、提交社区Issues', - URL: 'https://quickissue.openeuler.org/zh/issues/', - }, - ], - }, - ], - }, - { - NAME: '支持', - ID: 'approve', - CHILDREN: [ - { - NAME: '兼容性专区', - CHILDREN: [ - { - NAME: '兼容性列表', - DESCRIPTION: '查看openEuler兼容性列表', - URL: '/compatibility/', - }, - { - NAME: '兼容性技术测评', - DESCRIPTION: '帮助企业快速申请兼容性技术测评', - URL: 'https://certification.openeuler.org/#/', - }, - ], - SHORTCUT: [ - { - NAME: 'openEuler 硬件兼容性测试整体介绍', - URL: '/compatibility/hardware/', - }, - ], - }, - { - NAME: '支持与服务', - CHILDREN: [ - { - NAME: 'x2openEuler', - DESCRIPTION: '将原有业务迁移到openEuler的工具套件', - URL: 'https://docs.openeuler.org/zh/docs/20.03_LTS_SP1/docs/x2openEuler/Introduction.html', - }, - { - NAME: 'OSV技术测评', - DESCRIPTION: '查看OSV技术测评结果', - URL: '/approve/', - }, - { - NAME: '社区公告', - DESCRIPTION: '查看漏洞管理、安全公告等安全问题', - URL: '', - MOBILE_SHOW_CHILD: true, - CHILDREN: [ - { - NAME: '安全中心', - URL: '/security/security-bulletins/', - }, - { - NAME: '缺陷中心', - URL: '/security/bug-bulletins/', - }, - ], - }, - { - NAME: 'FAQ常见问题', - DESCRIPTION: '查看openEuler常见问题', - URL: '/faq/', - }, - ], - SHORTCUT: [ - { - NAME: 'OSV技术测评整体介绍', - URL: '/approve/approve-step/', - }, - { - NAME: 'QuickIssue ', - URL: 'https://quickissue.openeuler.org/zh/issues/', - }, - ], - }, - ], - }, - { - NAME: '社区', - ID: 'community', - CHILDREN: [ - { - NAME: '关于社区', - CHILDREN: [ - { - NAME: '组织架构', - DESCRIPTION: '了解openEuler的委员会成员', - URL: '/community/organization/', - }, - { - NAME: '社区章程', - DESCRIPTION: '了解openEuler的章程、条例、行为准则、License策略', - URL: '/community/charter/', - }, - { - NAME: '成员单位', - DESCRIPTION: '了解openEuler的捐赠单位', - URL: '/community/member/', - }, - { - NAME: '社区荣誉', - DESCRIPTION: '了解openEuler的荣誉奖项', - URL: '/community/honor/', - }, - { - NAME: 'oEEP', - DESCRIPTION: '查看openEuler社区的演进提案', - URL: '/oEEP/?name=oEEP-0000 oEEP 索引', - }, - { - NAME: '城市用户组', - DESCRIPTION: '区域用户交流圈', - URL: '/community/user-group/', - }, - { - NAME: '贡献看板', - DESCRIPTION: '查看openEuler社区数据', - URL: 'https://datastat.openeuler.org/zh/overview', - }, - ], - SHORTCUT: [ - { - NAME: 'openEuler社区介绍PDF', - URL: 'https://www.openeuler.org/whitepaper/openEuler %E5%BC%80%E6%BA%90%E7%A4%BE%E5%8C%BA%E4%BB%8B%E7%BB%8D.pdf', - }, - ], - }, - { - NAME: '贡献与成长', - HASGROUP: true, - CHILDREN: [ - { - NAME: '开发者贡献', - CHILDREN: [ - { - NAME: 'SIG中心', - DESCRIPTION: '查询openEuler社区SIG组(Special Interest Group)', - URL: '/sig/sig-list/', - }, - { - NAME: '贡献攻略', - DESCRIPTION: '参与社区贡献的方式', - URL: '/community/contribution/', - }, - { - NAME: 'CLA签署', - DESCRIPTION: '参与贡献前,需签署贡献者许可协议(CLA)\n个人CLA、企业CLA、员工CLA', - URL: 'https://clasign.osinfra.cn/sign/gitee_openeuler-1611298811283968340', - ICON: OutLink, - }, - ], - }, - { - NAME: '开发者成长', - CHILDREN: [ - { - NAME: '高校', - DESCRIPTION: '了解高校技术小组与实习赛事资讯', - URL: '/universities/', - }, - { - NAME: '人才培养', - DESCRIPTION: '旨在帮助企业快速培养openEuler专业生态人才', - URL: '/talent-assessment/', - }, - { - NAME: '开源实习', - DESCRIPTION: '旨在帮助在校学生在项目实践中提升能力,成为优秀的开源人才', - URL: '/internship/', - }, - ], - }, - ], - SHORTCUT: [ - { - NAME: '企业签署CLA流程', - URL: '/blog/2022-11-25-cla/CLA%E7%AD%BE%E7%BD%B2%E6%B5%81%E7%A8%8B.html', - }, - { - NAME: 'CLA-FAQ', - ICON: OutLink, - URL: 'https://gitee.com/openeuler/infrastructure/blob/master/docs/cla-guide/faq/faq.md', - }, - { - NAME: '开发者日历', - URL: '/meeting/#calendar', - }, - { - NAME: '活动与大赛', - URL: '/universities/#%E6%B4%BB%E5%8A%A8%E4%B8%8E%E5%A4%A7%E8%B5%9B', - }, - { - NAME: '高校技术小组', - URL: '/universities/#%E9%AB%98%E6%A0%A1%E6%8A%80%E6%9C%AF%E5%B0%8F%E7%BB%84', - }, - ], - }, - { - NAME: '项目', - CHILDREN: [ - { - NAME: 'A-Tune', - DESCRIPTION: '一款基于AI开发的智能优化引擎', - URL: '/other/projects/atune/', - }, - { - NAME: 'iSula', - DESCRIPTION: '容器技术方案', - URL: '/other/projects/isula/', - }, - { - NAME: 'StratoVirt', - DESCRIPTION: '面向云数据中心的企业级虚拟化VMM', - URL: '/other/projects/stratovirt/', - }, - { - NAME: 'BiSheng JDK', - DESCRIPTION: '一款高性能Java虚拟机', - URL: '/other/projects/bishengjdk/', - }, - { - NAME: 'secGear', - DESCRIPTION: '供开发者开发安全应用的机密计算框架', - URL: '/other/projects/secgear/', - }, - { - NAME: 'NestOS', - DESCRIPTION: '基于欧拉开源操作系统的云底座操作系统', - URL: '/nestos', - }, - ], - SHORTCUT: [], - }, - { - NAME: '社区交流', - CHILDREN: [ - { - NAME: '论坛', - DESCRIPTION: '与开发者讨论openEuler', - URL: 'https://forum.openeuler.org/?locale=zh_CN', - }, - { - NAME: '邮件列表', - DESCRIPTION: '订阅邮件列表,与SIG成员讨论openEuler的技术与进展', - URL: '/community/mailing-list/', - }, - { - NAME: '线上会议', - DESCRIPTION: '查询并参与SIG组例会', - URL: '/meeting/', - }, - { - NAME: '联系我们', - DESCRIPTION: '', - URL: '/contact-us/', - TAG: TAG_TYPE.NEW, - }, - ], - SHORTCUT: [], - }, - ], - }, - - { - NAME: '动态', - ID: 'update', - CHILDREN: [ - { - NAME: '社区活动', - WITH_PICTURE: true, - CHILDREN: [ - { - NAME: '活动日历', - DESCRIPTION: '了解openEuler社区全年活动', - URL: '/interaction/event-list/', - }, - { - NAME: '峰会', - DESCRIPTION: '查看openEuler年度大会详情', - URL: '/interaction/summit-list/summit2024/', - }, - { - NAME: 'openEuler Call for X计划', - DESCRIPTION: '共享openEuler Call for X计划多元化资源', - URL: '/community/program/', - }, - ], - SHORTCUT: [ - { - NAME: '操作系统大会 & openEuler Summit 2024', - PICTURE: Summit, - DESCRIPTION: - '操作系统是产业数字化、智能化发展的坚实底座。openEuler作为数智基础设施的开源操作系统,开源5年,产业共建、生态繁荣;openEuler系市场份额屡攀新高;技术不断创新,使能AI,加速OS智能化,让数智无所不能;源于中国,贡献全球,已成长为企业级全球开源操作系统社区的重要一员。', - REMARK: '时间:2024/11/15 - 2024/11/16 | 北京', - TYPE: 'PICTURE', - URL: '/interaction/summit-list/summit2024/', - }, - { - NAME: 'openEuler SIG Gathering 2024', - PICTURE: Sig, - DESCRIPTION: - 'openEuler SIG Gathering 2024将于7月26日在北京香格里拉饭店举行。本次活动面向社区108个SIG组,诚邀社区开发者齐聚现场,通过全天线下会议,聚焦openEuler 24.03 LTS 版本后续重要规划和各SIG2024年下半年重要技术方案以及开发计划。', - REMARK: '时间:2024/07/26 | 北京', - TYPE: 'PICTURE', - URL: '/interaction/summit-list/sig-gathering-2024/', - }, - ], - }, - { - NAME: '资讯', - WITH_PICTURE: true, - CHILDREN: [ - { - NAME: '新闻', - DESCRIPTION: '查看openEuler社区动态', - URL: '/interaction/news-list/', - }, - { - NAME: '博客', - DESCRIPTION: '查看openEuler技术文章分享', - URL: '/interaction/blog-list/', - }, - { - NAME: '月刊与年报', - DESCRIPTION: '查看openEuler社区运作报告', - URL: '/monthly-bulletins/', - }, - ], - SHORTCUT: [ - { - NAME: 'openEuler 2024 社区年报', - PICTURE: annualReport2024, - REMARK: '发布时间:2025/01/24', - TYPE: 'PICTURE', - URL: '/annual-report/openEuler-annual-report-2024/', - }, - { - NAME: 'openEuler 2023 社区年报', - PICTURE: Report, - REMARK: '发布时间:2024/01/01', - TYPE: 'PICTURE', - URL: '/news/openEuler/20240223-nianbao/Untitled-1.html', - }, - ], - }, - ], - }, - ], - USER_CENTER: '个人中心', - MESSAGE_CENTER: '消息中心', - LOGOUT: '退出登录', - CODE: '源码', - QUICKLINK: '快捷链接', - SEARCH: { - BROWSEHISTORY: '历史记录', - CLEAN: '清除', - TOPSEARCH: '热门搜索', - CHANGE: '换一批', - PLEACHOLDER: '搜索', - PLEACHOLDER_EXTEND: '请输入搜索内容', - TEXT: '搜索', - }, - SOURCE_CODE: [ - { - NAME: '代码仓', - PATH: 'https://gitee.com/openeuler', - }, - { - NAME: '软件包仓', - PATH: 'https://gitee.com/src-openeuler', - }, - { - NAME: 'Github镜像仓', - PATH: 'https://github.com/openeuler-mirror', - }, - ], -}; diff --git a/docs/.vitepress/src/i18n/header/index.ts b/docs/.vitepress/src/i18n/header/index.ts deleted file mode 100644 index dcc252ae9413d884d3dfeed7ef567f26ef577697..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/i18n/header/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import zh from './header-zh'; -import en from './header-en'; - -export default { - zh, - en, -}; \ No newline at end of file diff --git a/docs/.vitepress/src/i18n/index.ts b/docs/.vitepress/src/i18n/index.ts deleted file mode 100644 index 9de344f0856958bd519a747bb848f9152bd58830..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/i18n/index.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { createI18n } from 'vue-i18n'; -import { getCurrentLocale } from '@/utils/locale'; - -// 公共 -import common from './common'; -import header from './header'; -import footer from './footer'; - -import docs from './docs'; -import feedback from './feedback'; - -const messages = { - zh: { - // 公共 - common: common.zh, - header: header.zh, - footer: footer.zh, - docs: docs.zh, - feedback: feedback.zh, - }, - en: { - // 公共 - common: common.en, - header: header.en, - footer: footer.en, - docs: docs.en, - feedback: feedback.en, - }, -}; - -const locale = getCurrentLocale(); -const i18n = createI18n({ - globalInjection: true, - locale, - legacy: false, - fallbackLocale: 'zh', - messages, -}); - -export default i18n; diff --git a/docs/.vitepress/src/layouts/LayoutDoc.vue b/docs/.vitepress/src/layouts/LayoutDoc.vue deleted file mode 100644 index 8e62a7f99bad616d955c0aa2b8326e755be52728..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/layouts/LayoutDoc.vue +++ /dev/null @@ -1,820 +0,0 @@ - - - - - - - diff --git a/docs/.vitepress/src/shared/axios/handleError.ts b/docs/.vitepress/src/shared/axios/handleError.ts deleted file mode 100644 index 3a08d25130667367ba1c77808c055c9f0eadf553..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/shared/axios/handleError.ts +++ /dev/null @@ -1,61 +0,0 @@ -import type { AxiosError } from 'axios'; - -export default (err: AxiosError) => { - const { response } = err; - - if (response) { - if (!response.status) { - err.code = ''; - err.message = '有response但没有response.status的情况'; - } - - const data = response.data as { code: string; data: any; msg: string }; - - switch (response && response.status) { - case 200: - err.message = '错误响应也会有状态码为200的情况'; - break; - case 400: - err.code = data.code ?? String(response.status); - err.message = '请求错误(400)'; - break; - case 401: - err.message = '未授权,请重新登录(401)'; - break; - case 403: - err.message = '拒绝访问(403)'; - break; - case 404: - err.message = '请求出错(404)'; - break; - case 408: - err.message = '请求超时(408)'; - break; - case 418: - err.message = '服务正在维护升级(418)'; - break; - case 500: - err.message = '服务器错误(500)'; - break; - case 501: - err.message = '服务未实现(501)'; - break; - case 502: - err.message = '网络错误(502)'; - break; - case 503: - err.message = '服务不可用(503)'; - break; - case 504: - err.message = '网络超时(504)'; - break; - case 505: - err.message = 'HTTP版本不受支持(505)'; - break; - default: - err.message = `连接出错,状态码:(${response.status})!`; - } - } - - return err; -}; diff --git a/docs/.vitepress/src/shared/axios/handleResponse.ts b/docs/.vitepress/src/shared/axios/handleResponse.ts deleted file mode 100644 index c24d7db3efbb802d27e04945b80c51e285618e4f..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/shared/axios/handleResponse.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type { AxiosResponse } from 'axios'; - -export default (response: AxiosResponse) => { - return response; -}; diff --git a/docs/.vitepress/src/shared/axios/index.ts b/docs/.vitepress/src/shared/axios/index.ts deleted file mode 100644 index 547d7ebdd580656b91915c777f469cd4f8f1200d..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/shared/axios/index.ts +++ /dev/null @@ -1,224 +0,0 @@ -import type { Ref } from 'vue'; - -import axios from 'axios'; -import type { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosRequestHeaders, AxiosResponse, AxiosStatic, Canceler } from 'axios'; - -import handleResponse from './handleResponse'; -import handleError from './handleError'; -import setConfig from './setConfig'; - -import { isBoolean, useLoading, useMessage, isNull, isUndefined } from '@opensig/opendesign'; -import type { LoadingPropsT } from '@opensig/opendesign/lib/loading/types'; -import { LOGIN_STATUS, clearUserAuth } from '@/shared/login'; -import { useLoginStore } from '@/stores/user'; - -interface RequestConfig extends AxiosRequestConfig { - data?: D; - showLoading?: boolean | { opt?: Partial; wrap: Ref | HTMLElement | string }; // 加载时是否出现Loading框,默认为false - showError?: boolean; // 请求报错是否出现错误提示,默认为true - ignoreError?: number; // 忽略某个状态码错误提示 - ignoreDuplicates?: boolean; // false: 取消重复请求; true: 允许重复请求 - global?: boolean; // 是否为全局请求,全局请求在清除请求池时,不清除 -} - -interface RequestInstance extends AxiosInstance { - removeRequestInterceptor(): void; - removeResponseInterceptor(): void; - clearPendingPool(whiteList: Array): Array | null; - getUri(config?: RequestConfig): string; - request, D = any>(config: RequestConfig): Promise; - get, D = any>(url: string, config?: RequestConfig): Promise; - delete, D = any>(url: string, config?: RequestConfig): Promise; - head, D = any>(url: string, config?: RequestConfig): Promise; - options, D = any>(url: string, config?: RequestConfig): Promise; - post, D = any>(url: string, data?: D, config?: RequestConfig): Promise; - put, D = any>(url: string, data?: D, config?: RequestConfig): Promise; - patch, D = any>(url: string, data?: D, config?: RequestConfig): Promise; -} - -interface InternalRequestConfig extends RequestConfig { - headers: AxiosRequestHeaders; -} - -let loadingInstance: { toggle(show?: boolean): void } | null = null; -let loadingCount = 0; - -/** - * request是基于axios创建的实例,实例只有常见的数据请求方法,没有axios.isCancel/ axios.CancelToken等方法, - * 也就是没有**取消请求**和**批量请求**的方法。 - * 所以如果需要在实例中调用取消某个请求的方法(例如取消上传),请用intactRequest。 - */ -const intactRequest: AxiosStatic = setConfig(axios); -const request: RequestInstance = intactRequest.create() as RequestInstance; - -// 请求中的api -const pendingPool: Map = new Map(); - -const getLoadingInstance = (showLoading: boolean | { opt?: Partial; wrap: Ref | HTMLElement | string }) => { - if (isBoolean(showLoading)) { - return useLoading(); - } else { - const { opt, wrap = 'body' } = showLoading; - if (opt) { - return useLoading(opt, wrap); - } else { - return useLoading(); - } - } -}; - -/** - * 请求拦截 - */ -const requestInterceptorId = request.interceptors.request.use( - (config: InternalRequestConfig) => { - const { showLoading } = config; - - if (loadingCount === 0 && config.showLoading) { - if (showLoading) { - loadingInstance = getLoadingInstance(showLoading); - - loadingInstance.toggle(true); - loadingCount++; - } - } - // 存储请求信息 - // 定义取消请求 - if (!config.ignoreDuplicates) { - config.cancelToken = new axios.CancelToken((cancelFn) => { - if (!config?.url) { - return; - } - - // 如果已请求,则取消重复请求 - if (!pendingPool.has(config.url)) { - // 存储到请求池 - pendingPool.set(config.url, { - method: config.method, - cancelFn, - global: config.global, - }); - } - }); - } - if (config.params) { - Object.keys(config?.params).forEach((key) => { - if (config.params[key] === '' || isNull(config.params[key]) || isUndefined(config.params[key])) { - delete config.params[key]; - } - }); - } - return config; - }, - (err: AxiosError) => { - Promise.reject(err); - } -); - -/** - * 响应拦截 - */ -const responseInterceptorId = request.interceptors.response.use( - (response: AxiosResponse) => { - if (loadingInstance) { - loadingCount--; - } - if (loadingCount === 0 && loadingInstance) { - loadingInstance.toggle(false); - loadingInstance = null; - } - const { config } = response; - - // 请求完成,移除请求池 - if (config.url) { - pendingPool.delete(config.url); - } - - return Promise.resolve(handleResponse(response)); - }, - (err: AxiosError) => { - if (loadingInstance) { - loadingInstance.toggle(false); - loadingCount = 0; - } - - const config = err.config as InternalRequestConfig; - - // 非取消请求发生异常,同样将请求移除请求池 - if (!axios.isCancel(err) && config?.url) { - pendingPool.delete(config.url); - } - - if (err.response) { - if (err.stack && err.stack.includes('timeout')) { - err.message = '请求超时!'; - } - err = handleError(err); - } - // 没有response(没有状态码)的情况 - else { - // 被取消的请求 - if (axios.isCancel(err)) { - throw new axios.Cancel(err.message || `请求'${config?.url}'被取消`); - } - } - - if (config && config.showError !== false && config.ignoreError !== err.response?.status) { - const msg = useMessage(); - msg.show({ - content: err.message, - status: 'danger', - }); - } - - if (err.response?.status === 401) { - clearUserAuth(); - useLoginStore().setLoginStatus(LOGIN_STATUS.FAILED); - } - - return Promise.reject(err); - } -); -// 移除全局的请求拦截器 -function removeRequestInterceptor() { - request.interceptors.request.eject(requestInterceptorId); -} - -// 移除全局的响应拦截器 -function removeResponseInterceptor() { - request.interceptors.response.eject(responseInterceptorId); -} - -/** - * 清除所有pending状态的请求 - * @param {Array} whiteList 白名单,里面的请求不会被取消 - * 返回值 被取消了的api请求 - * 可以在路由变化时取消当前所有非全局的pending状态的请求 - */ -function clearPendingPool(whiteList: Array = []) { - if (!pendingPool.size) { - return null; - } - - const pendingUrlList: Array = Array.from(pendingPool.keys()).filter((url: string) => !whiteList.includes(url)); - if (!pendingUrlList.length) { - return null; - } - - pendingUrlList.forEach((pendingUrl) => { - // 清除掉所有非全局的pending状态下的请求 - if (!pendingPool.get(pendingUrl)?.global) { - pendingPool.get(pendingUrl)?.cancelFn(); - pendingPool.delete(pendingUrl); - } - }); - - return pendingUrlList; -} - -request.removeRequestInterceptor = removeRequestInterceptor; -request.removeResponseInterceptor = removeResponseInterceptor; -request.clearPendingPool = clearPendingPool; - -export { intactRequest, request }; -export type { AxiosResponse, RequestConfig, RequestInstance }; diff --git a/docs/.vitepress/src/shared/axios/setConfig.ts b/docs/.vitepress/src/shared/axios/setConfig.ts deleted file mode 100644 index 18ca43ffea683ae87e34b4da57a59dab2d71e979..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/shared/axios/setConfig.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { AxiosStatic } from 'axios'; -const XSRF_COOKIE_NAME = import.meta.env.VITE_XSRF_COOKIE_NAME; -const XSRF_HEADER_NAME = import.meta.env.VITE_XSRF_HEADER_NAME; - -/** - * @param {axios} axios实例 - * @param {config} 自定义配置对象,可覆盖掉默认的自定义配置 - */ -export default (axios: AxiosStatic, config = {}) => { - const defaultConfig = { - timeout: 20000, - headers: { - 'Content-Type': 'application/json;charset=UTF-8', - }, - xsrfCookieName: XSRF_COOKIE_NAME, - xsrfHeaderName: XSRF_HEADER_NAME, - }; - Object.assign(axios.defaults, defaultConfig, config); - return axios; -}; diff --git a/docs/.vitepress/src/shared/cookie.ts b/docs/.vitepress/src/shared/cookie.ts deleted file mode 100644 index 88c138c191a1c079aec667288c170a330614efdc..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/shared/cookie.ts +++ /dev/null @@ -1,30 +0,0 @@ -import Cookies from 'js-cookie'; - -/** - * 获取指定key的cookie值 - * @param key - * @returns - */ -export const getCustomCookie = (key: string) => { - return Cookies.get(key); -}; - -/** - * 设置cookie - * @param key cookie的key - * @param value cookie的值 - * @param day cookie的过期时间 默认180天 - * @param domain domain地址 - */ -export const setCustomCookie = (key: string, value: string, day = 180, domain: string = location.hostname) => { - Cookies.set(key, value, { expires: day, path: '/', domain: domain }); -}; - -/** - * 删除cookie - * @param key cookie的key - * @param domain domain地址 - */ -export const removeCustomCookie = (key: string, domain: string = location.hostname) => { - Cookies.remove(key, { path: '/', domain: domain }); -}; diff --git a/docs/.vitepress/src/shared/login.ts b/docs/.vitepress/src/shared/login.ts deleted file mode 100644 index 07c04a448da022f68abc04b8c20d17503123e045..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/shared/login.ts +++ /dev/null @@ -1,76 +0,0 @@ -import Cookies from 'js-cookie'; -import { useLangStore } from '@/stores/common'; -import { useLoginStore, useUserInfoStore } from '@/stores/user'; -import { queryUserInfo } from '@/api/api-user'; - -const LOGIN_URL = import.meta.env.VITE_LOGIN_URL; -const XSRF_COOKIE_NAME = import.meta.env.VITE_XSRF_COOKIE_NAME; - -// 登录状态 -export enum LOGIN_STATUS { - FAILED = -1, // 登录失败 - NOT = 0, // 未登录 - DOING = 1, // 登录中 - DONE = 2, // 登录成功 -} -export type LoginStatusT = typeof LOGIN_STATUS.FAILED | LOGIN_STATUS.NOT | LOGIN_STATUS.DOING | LOGIN_STATUS.DONE; - -export const LOGIN_KEYS = { - CSRF_TOKEN: XSRF_COOKIE_NAME, - USER_INFO: '_U_I_', -}; - -/** - * 从cookie中获取csrfToken - * @returns csrfToken - */ -export const getCsrfToken = () => Cookies.get(LOGIN_KEYS.CSRF_TOKEN) || ''; - -// 退出登录 -export function logout() { - location.href = `${LOGIN_URL}/logout?redirect_uri=${encodeURIComponent(window?.location?.origin)}`; -} - -/** - * 跳转登录页 - */ -export function doLogin() { - location.href = `${LOGIN_URL}/login?redirect_uri=${encodeURIComponent(location.href)}&lang=${useLangStore().lang}`; -} - -// 清除用户认证凭据 -export function clearUserAuth() { - // 清除内存中用户信息 - useUserInfoStore().$reset(); - // 清除cookie - if (import.meta.env.DEV) { - Cookies.remove(LOGIN_KEYS.CSRF_TOKEN); - } else { - Cookies.remove(LOGIN_KEYS.CSRF_TOKEN, { domain: import.meta.env.VITE_COOKIE_DOMAIN, path: '/', secure: true }); - } -} - -/** - * 尝试登录 - * @returns 登录结果 - */ -export async function tryLogin() { - const userInfoStore = useUserInfoStore(); - const loginStore = useLoginStore(); - const csrfToken = getCsrfToken(); - if (!csrfToken) { - userInfoStore.$reset(); - loginStore.setLoginStatus(LOGIN_STATUS.NOT); - return; - } - - try { - loginStore.setLoginStatus(LOGIN_STATUS.DOING); - userInfoStore.$patch(await queryUserInfo()); - loginStore.setLoginStatus(LOGIN_STATUS.DONE); - } catch (error) { - loginStore.setLoginStatus(LOGIN_STATUS.FAILED); - - - } -} diff --git a/docs/.vitepress/src/stores/common.ts b/docs/.vitepress/src/stores/common.ts deleted file mode 100644 index 75ec55b66ab5ae73d10ce1b703b3330f0a742f91..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/stores/common.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { defineStore } from 'pinia'; - -// 语言 -export const useLangStore = defineStore('lang', { - state: () => { - return { - lang: '', - }; - }, - actions: { - setLangStore(val: string) { - this.lang = val; - }, - }, -}); - -/** - * 页面状态 - */ -export const useViewStore = defineStore('view', { - state: () => { - return { - notFoundPage: false, - noPermission: false, - }; - }, - actions: { - showNotFound() { - this.notFoundPage = true; - }, - }, -}); - -export const useAppearance = defineStore('appearance', { - state: () => ({ - theme: 'light', - iconMenuShow: true, - }), -}); - -export const usePrevPage = defineStore('prevPage', { - state: () => ({ - prevPageUrl: '', - }), -}); - -/** - * 搜索状态 - */ -export const useSearchingStore = defineStore('isSearching', { - state: () => { - return { - isSearching: false, - keyword: '', - isLoading: false, - currentPage: 1, - version: '', // 文档当前版本 - }; - }, - actions: { - setIsSearching(value: boolean) { - this.isSearching = value; - }, - setKeyword(value: string) { - this.keyword = value; - }, - setIsLoading(value: boolean) { - this.isLoading = value; - }, - setCurrentPage(value: number) { - this.currentPage = value; - }, - }, -}); diff --git a/docs/.vitepress/src/stores/download.ts b/docs/.vitepress/src/stores/download.ts deleted file mode 100644 index 5e3556d187aabd5301b8b7bfe18847e47d6766e9..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/stores/download.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { defineStore } from 'pinia'; - -/** - * vitepress 无法监听 History.replaceState和pushState,使用 pinia 监听 scenario变化 - */ -export const useDownload = defineStore('download', { - state: () => ({ - scenario: '', - version: '', - }), - actions: { - setScenario(val: string) { - this.scenario = val; - }, - setVersion(val: string) { - this.version = val; - }, - }, -}); diff --git a/docs/.vitepress/src/stores/menu.ts b/docs/.vitepress/src/stores/menu.ts deleted file mode 100644 index c8b3ec9371544932db61a72b4e6bf405fccf5ac8..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/stores/menu.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { computed, onMounted, ref, watch } from 'vue'; -import { defineStore } from 'pinia'; -import { MENU_CONFIG } from '@/config/menu'; -import { DocMenuTree, type DocMenuNodeT } from '@/utils/tree'; -import { useRoute } from '@/composables/useRoute'; - -export const useMenuStore = defineStore('menu', () => { - const rootTree = new DocMenuTree(MENU_CONFIG); - const allNodes = rootTree.root.children; - const { url } = useRoute(); - - // -------------------- 当前菜单节点 -------------------- - const currentNode = computed(() => { - const href = url.value.split('#')[0]; - const node = rootTree.getNodeByHref(rootTree.root, decodeURIComponent(url.value)); - const anchorNode = rootTree.getNodeByHref(rootTree.root, decodeURIComponent(href)); - return node || anchorNode; - }); - - // -------------------- 当前菜单节点的所有前驱节点 -------------------- - const prevNodes = computed(() => { - return currentNode.value ? rootTree.getPrevNodes(currentNode.value, 1) : []; - }); - - // -------------------- 当前菜单节点的手册节点 -------------------- - const bookNode = computed(() => { - if (!currentNode.value) { - return null; - } - - let node: DocMenuNodeT | null = currentNode.value; - while (node && !node.ismanual) { - node = node.parent; - } - - return node; - }); - - const bookNodes = computed(() => (bookNode.value ? [bookNode.value] : [])); - - // -------------------- 菜单绑定值 -------------------- - const menuValue = ref(''); - const menuExpanded = ref([]); - - const updateExpanded = () => { - if (!currentNode.value || currentNode.value?.depth < 3) { - menuExpanded.value = []; - return; - } - - const arr = prevNodes.value; - if (currentNode.value.children?.length > 0) { - arr.push(currentNode.value); - } - - menuExpanded.value = arr.map((item) => item.id); - }; - - onMounted(() => { - menuValue.value = currentNode.value?.id || ''; - updateExpanded(); - }); - - watch(currentNode, () => { - menuValue.value = currentNode.value?.id || ''; - updateExpanded(); - }); - - return { - menuValue, // 绑定菜单值 - menuExpanded, // 展开值 - rootTree, // 根节点 - allNodes, // 所有节点 - bookNode, // 手册节点 - bookNodes, // 手册节点数组 - currentNode, // 当前节点 - prevNodes, // 当前节点的所有前驱节点 - }; -}); diff --git a/docs/.vitepress/src/stores/user.ts b/docs/.vitepress/src/stores/user.ts deleted file mode 100644 index d8cb3996c81c8fe8a68553697409b24064ac6217..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/stores/user.ts +++ /dev/null @@ -1,62 +0,0 @@ -import type { Identity } from '@/@types/type-user'; -import { LOGIN_STATUS, type LoginStatusT } from '@/shared/login'; -import { defineStore } from 'pinia'; - -/** - * 用户基本信息 - */ -export const useUserInfoStore = defineStore('userInfo', { - state: () => { - return { - identities: [] as Identity[], - photo: '' as string, - username: '' as string, - upstreamPermission: null as boolean | null, - // 协作平台admin权限 - platformAdminPermission: null as boolean | null, - // 协作平台maintainer权限 - platformMaintainerPermission: null as boolean | null, - }; - }, - getters: { - // 获取giteeID - getGiteeId(status): string { - const id = status.identities.find((id) => id.identity === 'gitee'); - return id ? id.login_name : ''; - }, - }, -}); - -/** - * 登录状态 - */ -export const useLoginStore = defineStore('login', { - state: () => { - return { - loginStatus: LOGIN_STATUS.NOT, - }; - }, - actions: { - setLoginStatus(status: LoginStatusT) { - this.loginStatus = status; - }, - }, - getters: { - // 登录失败 - isLoginFailed(): boolean { - return this.loginStatus === LOGIN_STATUS.FAILED; - }, - // 未登录 - isLoginNot(): boolean { - return this.loginStatus === LOGIN_STATUS.NOT; - }, - // 登录中 - isLoggingIn(): boolean { - return this.loginStatus === LOGIN_STATUS.DOING; - }, - // 登录成功 - isLogined(): boolean { - return this.loginStatus === LOGIN_STATUS.DONE; - }, - }, -}); diff --git a/docs/.vitepress/src/utils/common.ts b/docs/.vitepress/src/utils/common.ts deleted file mode 100644 index 8924c5dbee7af65dd37d1b7c7bfa41c6613d46cd..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/utils/common.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { isClient } from '@opensig/opendesign'; - -/** - * safe window open - */ -export const windowOpen = (url?: string | URL | undefined, target?: string | undefined, features?: string | undefined) => { - const opener = window.open(url, target, features); - opener && (opener.opener = null); -}; - -/** - * 时间戳转 xxxx/xx/xx 格式时间 - * @param {number} timestamp 待转换时间戳 - * @returns {string} 返回格式化时间,如 2024/01/01 - */ -export const changeTimeStamp = (timestamp: number) => { - const date = new Date(timestamp * 1000); - - const year = date.getFullYear(); - const month = ('0' + (date.getMonth() + 1)).slice(-2); - const day = ('0' + date.getDate()).slice(-2); - - return `${year}/${month}/${day}`; -}; - -/** - * URL参数转对象 - * @param {string} url 地址 - * @returns {(string|undefined)} 转换成功返回参数对象,失败返回 undefined - */ -export function getUrlParams(url: string) { - const arrObj = url.split('?'); - if (arrObj.length > 1) { - const arrPara = arrObj[1].split('&'); - const list = {} as any; - for (let i = 0; i < arrPara.length; i++) { - const item = arrPara[i].split('='); - const key = item[0]; - const value = item[1]; - list[key] = value; - } - return list; - } -} - -/** - * 滚动至顶部 - * @param {number} top 滑动到的顶部 - * @param {boolean} smooth 是否平滑滑动 - */ -export const scrollToTop = (top: number = 0, smooth: boolean = true) => { - if (isClient) { - const dom = document.querySelector('#app > .o-scroller > .o-scroller-container'); - dom?.scrollTo({ - top, - behavior: smooth ? 'smooth' : 'instant', - }); - } -}; - -/** - * 获取url搜索参数 - * @param {string} url 完整 url - * @returns {Object} url 中的搜索参数 - */ -export function getSearchUrlParams(url: string) { - const search = new URL(url).search; - const params = new URLSearchParams(search); - return params; -} - -/** - * 判断 key 是否存在于目标对象上 - * @param {(string|number|symbol)} key 待判断 key - * @param {object} obj 目标对象 - * @returns {boolean} 存在返回 true,不存在返回 false - */ -export const isValidKey = (key: string | number | symbol, obj: object): key is keyof typeof obj => { - return Object.prototype.hasOwnProperty.call(obj, key); -}; - -/** - * 获取指定时区偏移量的年份 - * @param {number} offset - 时区偏移量(单位:小时)。例如,UTC+8 时区,传入 8。 - * @returns {number} - 指定时区偏移量对应的年份 - */ -export function getYearByOffset(offset = 8) { - // 获取当前时间的 UTC 时间 - const now = new Date(); - const utcTime = new Date(now.getTime() + now.getTimezoneOffset() * 60000); - - // 设置偏移 - utcTime.setHours(utcTime.getHours() + offset); - - return utcTime.getFullYear(); -} diff --git a/docs/.vitepress/src/utils/cookie.ts b/docs/.vitepress/src/utils/cookie.ts deleted file mode 100644 index 88c138c191a1c079aec667288c170a330614efdc..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/utils/cookie.ts +++ /dev/null @@ -1,30 +0,0 @@ -import Cookies from 'js-cookie'; - -/** - * 获取指定key的cookie值 - * @param key - * @returns - */ -export const getCustomCookie = (key: string) => { - return Cookies.get(key); -}; - -/** - * 设置cookie - * @param key cookie的key - * @param value cookie的值 - * @param day cookie的过期时间 默认180天 - * @param domain domain地址 - */ -export const setCustomCookie = (key: string, value: string, day = 180, domain: string = location.hostname) => { - Cookies.set(key, value, { expires: day, path: '/', domain: domain }); -}; - -/** - * 删除cookie - * @param key cookie的key - * @param domain domain地址 - */ -export const removeCustomCookie = (key: string, domain: string = location.hostname) => { - Cookies.remove(key, { path: '/', domain: domain }); -}; diff --git a/docs/.vitepress/src/utils/element.ts b/docs/.vitepress/src/utils/element.ts deleted file mode 100644 index 08bb56f8030767a9b9101c276adc9021215a2bb7..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/utils/element.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { isWindow, type AnchorContainerT } from "@opensig/opendesign"; - -export const getOffsetTop = (el: HTMLElement, container: AnchorContainerT) => { - const { top } = el.getBoundingClientRect(); - if (isWindow(container)) { - return top - document.documentElement.clientTop; - } - - return top - container.getBoundingClientRect().top; -}; diff --git a/docs/.vitepress/src/utils/locale.ts b/docs/.vitepress/src/utils/locale.ts deleted file mode 100644 index d006e8da9a40a47f4158dce3d0f10dbc458875c2..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/utils/locale.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { isClient } from '@opensig/opendesign'; - -/** - * 获取当前的语言环境,目前只支持 zh 和 en - * @returns {string} 若当前是 zh 环境则返回 zh,否则返回 en - */ -export function getCurrentLocale() { - if (isClient) { - const { pathname } = window.location; - if (pathname.startsWith('/zh/')) { - return 'zh'; - } else if (pathname.startsWith('/en/')) { - return 'en'; - } else { - if (localStorage.getItem('locale')) { - return localStorage.getItem('locale') === 'zh' ? 'zh' : 'en'; - } else { - return navigator.language.toLowerCase().startsWith('zh') ? 'zh' : 'en'; - } - } - } - - return 'zh'; -} diff --git a/docs/.vitepress/src/utils/tree.ts b/docs/.vitepress/src/utils/tree.ts deleted file mode 100644 index 41de70955876890d9b055b4d056da81cedecc634..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/utils/tree.ts +++ /dev/null @@ -1,174 +0,0 @@ -import type { DocMenuT } from '../@types/type-doc-menu'; - -export interface DocMenuNodeT { - id: string; - label: string; - depth: number; - href?: string; - parent: DocMenuNodeT | null; - description: string | null; - type: string; - ismanual: boolean; - children: Array; -} - -export class DocMenuTree { - root: DocMenuNodeT; - constructor(data: Array, base: string = '/') { - this.root = { - id: '', - label: '', - depth: 0, - href: base, - description: null, - parent: null, - type: 'root', - ismanual: false, - children: [], - }; - - this.buildTree(this.root, data); - } - - /** - * 迭代构造树 - * @param {DocMenuNodeT} parent 父节点 - * @param {Array} data 数据 - */ - buildTree(parent: DocMenuNodeT, data: Array) { - for (let i = 0, len = data.length; i < len; i++) { - const curDepth = parent.depth + 1; - const info = data[i]; - const node: DocMenuNodeT = { - id: info.id, - label: info.label, - depth: curDepth, - href: info.href, - parent, - description: info.description || null, - type: info.type || '', - ismanual: info.ismanual === 'Y', - children: [], - }; - - parent.children.push(node); - - if (info.children && info.children.length) { - this.buildTree(node, info.children); - } - } - } - - /** - * BFS 广度优先查找节点 - * @param {DocMenuNodeT} node 父节点 - * @param {string} val id值 - * @returns {(DocMenuNodeT|undefined)} 查找到节点则返回该节点,未找到返回undefined - */ - getNode(node: DocMenuNodeT, val: string): DocMenuNodeT | undefined { - if (node.href === val) { - return node; - } - - const children: Array = node.children; - for (let i = 0, len = children.length; i < len; i++) { - const rlt = this.getNode(children[i], val); - if (rlt) { - return rlt; - } - } - } - - /** - * BFS 广度优先查找节点 - * @param {DocMenuNodeT} node 父节点 - * @param {string} val href值 - * @returns {(DocMenuNodeT|undefined)} 查找到节点则返回该节点,未找到返回undefined - */ - getNodeByHref(node: DocMenuNodeT, val: string): DocMenuNodeT | undefined { - if (node.href === val) { - return node; - } - - const children: Array = node.children; - for (let i = 0, len = children.length; i < len; i++) { - const rlt = this.getNodeByHref(children[i], val); - if (rlt) { - return rlt; - } - } - } - - /** - * BFS 广度优先查找节点 - * @param {DocMenuNodeT} node 父节点 - * @param {string} val label - * @returns {(DocMenuNodeT|undefined)} 查找到节点则返回该节点,未找到返回undefined - */ - getNodeByLabel(node: DocMenuNodeT, val: string): DocMenuNodeT | undefined { - if (node.label === val) { - return node; - } - - const children: Array = node.children; - for (let i = 0, len = children.length; i < len; i++) { - const rlt = this.getNodeByLabel(children[i], val); - if (rlt) { - return rlt; - } - } - } - - /** - * 获取菜单首条点击节点 - * @param {DocMenuNodeT} node 父节点 - * @returns {string} 返回节点id - */ - getFirstHrefNode(node: DocMenuNodeT) { - return node.children[0].children[0].id; - } - - /** - * 获取节点-指定深度的前驱节点 - * @param {DocMenuNodeT} node 节点 - * @param {number} targetDepth 目标深度 - * @returns {DocMenuNodeT} 返回前驱节点 - */ - getPrevNode(node: DocMenuNodeT, targetDepth = 0) { - if (targetDepth < 0 || node.depth < targetDepth) { - return undefined; - } - - let prev = node.parent; - while (prev) { - if (prev.depth === targetDepth) { - return prev; - } - - prev = prev.parent; - } - - return undefined; - } - - /** - * 获取前驱节点(不包含目标节点) - * @param {DocMenuNodeT} node 节点 - * @param {number} stopDepth 停止深度,到达此深度后不再往上收集。默认为0,即根节点。 - * @returns {DocMenuNodeT[]} 返回前驱节点 - */ - getPrevNodes(node: DocMenuNodeT, stopDepth = 0) { - if (!node || stopDepth < 0 || node.depth <= stopDepth) { - return []; - } - - const nodes = []; - let prev = node.parent; - while (prev && prev.depth >= stopDepth) { - nodes.push(prev); - prev = prev.parent; - } - - return nodes; - } -} diff --git a/docs/.vitepress/src/views/docsNode/TheDocsNode.vue b/docs/.vitepress/src/views/docsNode/TheDocsNode.vue deleted file mode 100644 index 924b4fe623ef358d411960d57636ab83d1d125ed..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/views/docsNode/TheDocsNode.vue +++ /dev/null @@ -1,232 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/views/home/TheHome.vue b/docs/.vitepress/src/views/home/TheHome.vue deleted file mode 100644 index 41f660649f1cfbee96d7c6e23f59f02b9317e8a6..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/views/home/TheHome.vue +++ /dev/null @@ -1,361 +0,0 @@ - - - - - diff --git a/docs/.vitepress/src/views/search/TheSearchResult.vue b/docs/.vitepress/src/views/search/TheSearchResult.vue deleted file mode 100644 index 60046ab1eec6830a48a3ab305acadbbf716eee9e..0000000000000000000000000000000000000000 --- a/docs/.vitepress/src/views/search/TheSearchResult.vue +++ /dev/null @@ -1,319 +0,0 @@ - - - - diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts deleted file mode 100644 index 10dfc89a8d1fc04f7e658bc01d6c95697deb1553..0000000000000000000000000000000000000000 --- a/docs/.vitepress/theme/index.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { App } from 'vue'; -import { createPinia } from 'pinia'; - -import Layout from '@/App.vue'; -import NotFound from '@/NotFound.vue'; -import directives from '@/directives'; - -import '@/assets/style/base.scss'; -import 'element-plus/theme-chalk/src/index.scss'; -import '@opensig/opendesign/es/index.scss'; -import '@/assets/style/theme/default-light.token.css'; -import '@/assets/style/theme/dark.token.css'; -import '@/assets/style/markdown.scss'; -import '@/assets/style/theme/index.scss'; -import '@/assets/style/global.scss'; -import '@/assets/style/element-plus/index.scss'; - -import VueDOMPurifyHTML from 'vue-dompurify-html'; - -export default { - Layout, - NotFound, - enhanceApp({ app }: { app: App }) { - app.use(createPinia()); - app.use(VueDOMPurifyHTML, { - default: { - ADD_ATTR: ['target'], - }, - }); - // 指令 - Object.keys(directives).forEach((directive) => { - app.directive(directive, directives[directive]); - }); - }, -}; diff --git a/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/_menu.md b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..eda32737716359ee334353f9a2ccaf701e458227 --- /dev/null +++ b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/_menu.md @@ -0,0 +1,38 @@ +--- +label: 'Kubernetes集群部署指南' +ismanual: 'Y' +description: '在openEuler环境,为搭建稳定高效Kubernetes集群提供基本的操作指引' +children: + - label: '概述' + href: './overview.md' + - label: '准备虚拟机' + href: './preparing-VMs.md' + - label: '手动部署集群' + href: './deploying-a-Kubernetes-cluster-manually.md' + children: + - label: '安装Kubernetes软件包' + href: './installing-the-Kubernetes-software-package.md' + - label: '准备证书' + href: './preparing-certificates.md' + - label: '安装etcd' + href: './installing-etcd.md' + - label: '部署控制面组件' + href: './deploying-control-plane-components.md' + - label: '部署Node节点组件' + href: './deploying-a-node-component.md' + - label: '自动部署集群' + href: './eggo-automatic-deployment.md' + children: + - label: '工具介绍' + href: './eggo-tool-introduction.md' + - label: '部署集群' + href: './eggo-deploying-a-cluster.md' + - label: '拆除集群' + href: './eggo-dismantling-a-cluster.md' + - label: '运行测试pod' + href: './running-the-test-pod.md' + - label: '基于containerd部署集群' + href: './kubernetes-containerd.md' + - label: '常见问题与解决方法' + href: './kubernetes-faqs.md' +--- \ No newline at end of file diff --git a/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/deploying-a-Kubernetes-cluster-manually.md b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/deploying-a-Kubernetes-cluster-manually.md new file mode 100644 index 0000000000000000000000000000000000000000..833e149dd1b395a4b288e728abec78fd67cfc1a5 --- /dev/null +++ b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/deploying-a-Kubernetes-cluster-manually.md @@ -0,0 +1,18 @@ +# 手动部署集群 + +**声明:手动部署方式仅适用于实验和学习环境,不适用于商用环境。** + +本章介绍手动部署 Kubernetes 集群的方法。 + +## 环境说明 + +通过上述虚拟机安装部署,获得如下虚拟机列表: + +| HostName | MAC | IPv4 | +| ---------- | ----------------- | ------------------ | +| k8smaster0 | 52:54:00:00:00:80 | 192.168.122.154/24 | +| k8smaster1 | 52:54:00:00:00:81 | 192.168.122.155/24 | +| k8smaster2 | 52:54:00:00:00:82 | 192.168.122.156/24 | +| k8snode1 | 52:54:00:00:00:83 | 192.168.122.157/24 | +| k8snode2 | 52:54:00:00:00:84 | 192.168.122.158/24 | +| k8snode3 | 52:54:00:00:00:85 | 192.168.122.159/24 | diff --git a/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/deploying-a-node-component.md b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/deploying-a-node-component.md new file mode 100644 index 0000000000000000000000000000000000000000..d169481ede4bd98adadfc304128fc818f1c89e18 --- /dev/null +++ b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/deploying-a-node-component.md @@ -0,0 +1,381 @@ +# 部署 Node 节点组件 + +本章节仅以`k8snode1`节点为例。 + +## 环境准备 + +```bash +# 内网需要配置代理 +$ dnf install -y docker iSulad conntrack-tools socat containernetworking-plugins +$ swapoff -a +$ mkdir -p /etc/kubernetes/pki/ +$ mkdir -p /etc/cni/net.d +$ mkdir -p /opt/cni +# 删除默认kubeconfig +$ rm /etc/kubernetes/kubelet.kubeconfig + +## 使用isulad作为运行时 ######## +# 配置iSulad +cat /etc/isulad/daemon.json +{ + "registry-mirrors": [ + "docker.io" + ], + "insecure-registries": [ + "k8s.gcr.io", + "quay.io" + ], + "pod-sandbox-image": "k8s.gcr.io/pause:3.2",# pause类型 + "network-plugin": "cni", # 置空表示禁用cni网络插件则下面两个路径失效, 安装插件后重启isulad即可 + "cni-bin-dir": "/usr/libexec/cni/", + "cni-conf-dir": "/etc/cni/net.d", +} + +# 在iSulad环境变量中添加代理,下载镜像 +cat /usr/lib/systemd/system/isulad.service +[Service] +Type=notify +Environment="HTTP_PROXY=http://name:password@proxy:8080" +Environment="HTTPS_PROXY=http://name:password@proxy:8080" + +# 重启iSulad并设置为开机自启 +systemctl daemon-reload +systemctl restart isulad + + + + +## 如果使用docker作为运行时 ######## +$ dnf install -y docker +# 如果需要代理的环境,可以给docker配置代理,新增配置文件http-proxy.conf,并编写如下内容,替换name,password和proxy-addr为实际的配置。 +$ cat /etc/systemd/system/docker.service.d/http-proxy.conf +[Service] +Environment="HTTP_PROXY=http://name:password@proxy-addr:8080" +$ systemctl daemon-reload +$ systemctl restart docker +``` + +## 创建 kubeconfig 配置文件 + +对各节点依次如下操作创建配置文件: + +```bash +$ kubectl config set-cluster openeuler-k8s \ + --certificate-authority=/etc/kubernetes/pki/ca.pem \ + --embed-certs=true \ + --server=https://192.168.122.154:6443 \ + --kubeconfig=k8snode1.kubeconfig + +$ kubectl config set-credentials system:node:k8snode1 \ + --client-certificate=/etc/kubernetes/pki/k8snode1.pem \ + --client-key=/etc/kubernetes/pki/k8snode1-key.pem \ + --embed-certs=true \ + --kubeconfig=k8snode1.kubeconfig + +$ kubectl config set-context default \ + --cluster=openeuler-k8s \ + --user=system:node:k8snode1 \ + --kubeconfig=k8snode1.kubeconfig + +$ kubectl config use-context default --kubeconfig=k8snode1.kubeconfig +``` + +**注:修改k8snode1为对应节点名** + +## 拷贝证书 + +和控制面一样,所有证书、密钥和相关配置都放到`/etc/kubernetes/pki/`目录。 + +```bash +$ ls /etc/kubernetes/pki/ +ca.pem k8snode1.kubeconfig kubelet_config.yaml kube-proxy-key.pem kube-proxy.pem +k8snode1-key.pem k8snode1.pem kube_proxy_config.yaml kube-proxy.kubeconfig +``` + +## CNI 网络配置 + +先通过 containernetworking-plugins 作为 kubelet 使用的 cni 插件,后续可以引入 calico,flannel 等插件,增强集群的网络能力。 + +```bash +# 桥网络配置 +$ cat /etc/cni/net.d/10-bridge.conf +{ + "cniVersion": "0.3.1", + "name": "bridge", + "type": "bridge", + "bridge": "cnio0", + "isGateway": true, + "ipMasq": true, + "ipam": { + "type": "host-local", + "subnet": "10.244.0.0/16", + "gateway": "10.244.0.1" + }, + "dns": { + "nameservers": [ + "10.244.0.1" + ] + } +} + +# 回环网络配置 +$ cat /etc/cni/net.d/99-loopback.conf +{ + "cniVersion": "0.3.1", + "name": "lo", + "type": "loopback" +} +``` + +## 部署 kubelet 服务 + +### kubelet 依赖的配置文件 + +```bash +$ cat /etc/kubernetes/pki/kubelet_config.yaml +kind: KubeletConfiguration +apiVersion: kubelet.config.k8s.io/v1beta1 +authentication: + anonymous: + enabled: false + webhook: + enabled: true + x509: + clientCAFile: /etc/kubernetes/pki/ca.pem +authorization: + mode: Webhook +clusterDNS: +- 10.32.0.10 +clusterDomain: cluster.local +runtimeRequestTimeout: "15m" +tlsCertFile: "/etc/kubernetes/pki/k8snode1.pem" +tlsPrivateKeyFile: "/etc/kubernetes/pki/k8snode1-key.pem" +``` + +**注意:clusterDNS 的地址为:10.32.0.10,必须和之前设置的 service-cluster-ip-range 一致** + +### 编写 systemd 配置文件 + +```bash +$ cat /usr/lib/systemd/system/kubelet.service +[Unit] +Description=kubelet: The Kubernetes Node Agent +Documentation=https://kubernetes.io/docs/ +Wants=network-online.target +After=network-online.target + +[Service] +ExecStart=/usr/bin/kubelet \ + --config=/etc/kubernetes/pki/kubelet_config.yaml \ + --network-plugin=cni \ + --pod-infra-container-image=k8s.gcr.io/pause:3.2 \ + --kubeconfig=/etc/kubernetes/pki/k8snode1.kubeconfig \ + --register-node=true \ + --hostname-override=k8snode1 \ + --cni-bin-dir="/usr/libexec/cni/" \ + --v=2 + +Restart=always +StartLimitInterval=0 +RestartSec=10 + +[Install] +WantedBy=multi-user.target +``` + +**注意:如果使用isulad作为runtime,需要增加如下配置** + +```bash +--container-runtime=remote \ +--container-runtime-endpoint=unix:///var/run/isulad.sock \ +``` + +## 部署 kube-proxy + +### kube-proxy 依赖的配置文件 + +```bash +cat /etc/kubernetes/pki/kube_proxy_config.yaml +kind: KubeProxyConfiguration +apiVersion: kubeproxy.config.k8s.io/v1alpha1 +clientConnection: + kubeconfig: /etc/kubernetes/pki/kube-proxy.kubeconfig +clusterCIDR: 10.244.0.0/16 +mode: "iptables" +``` + +### 编写 systemd 配置文件 + +```bash +$ cat /usr/lib/systemd/system/kube-proxy.service +[Unit] +Description=Kubernetes Kube-Proxy Server +Documentation=https://kubernetes.io/docs/reference/generated/kube-proxy/ +After=network.target + +[Service] +EnvironmentFile=-/etc/kubernetes/config +EnvironmentFile=-/etc/kubernetes/proxy +ExecStart=/usr/bin/kube-proxy \ + $KUBE_LOGTOSTDERR \ + $KUBE_LOG_LEVEL \ + --config=/etc/kubernetes/pki/kube_proxy_config.yaml \ + --hostname-override=k8snode1 \ + $KUBE_PROXY_ARGS +Restart=on-failure +LimitNOFILE=65536 + +[Install] +WantedBy=multi-user.target +``` + +## 启动组件服务 + +```bash +$ systemctl enable kubelet kube-proxy +$ systemctl start kubelet kube-proxy +``` + +其他节点依次部署即可。 + +## 验证集群状态 + +等待几分钟,使用如下命令查看node状态: + +```bash +$ kubectl get nodes --kubeconfig /etc/kubernetes/pki/admin.kubeconfig +NAME STATUS ROLES AGE VERSION +k8snode1 Ready 17h v1.20.2 +k8snode2 Ready 19m v1.20.2 +k8snode3 Ready 12m v1.20.2 +``` + +## 部署 coredns + +coredns可以部署到node节点或者master节点,本文这里部署到节点`k8snode1`。 + +### 编写 coredns 配置文件 + +```bash +$ cat /etc/kubernetes/pki/dns/Corefile +.:53 { + errors + health { + lameduck 5s + } + ready + kubernetes cluster.local in-addr.arpa ip6.arpa { + pods insecure + endpoint https://192.168.122.154:6443 + tls /etc/kubernetes/pki/ca.pem /etc/kubernetes/pki/admin-key.pem /etc/kubernetes/pki/admin.pem + kubeconfig /etc/kubernetes/pki/admin.kubeconfig default + fallthrough in-addr.arpa ip6.arpa + } + prometheus :9153 + forward . /etc/resolv.conf { + max_concurrent 1000 + } + cache 30 + loop + reload + loadbalance +} +``` + +说明: + +- 监听53端口; +- 设置kubernetes插件配置:证书、kube api的URL; + +### 准备 systemd 的 service 文件 + +```bash +cat /usr/lib/systemd/system/coredns.service +[Unit] +Description=Kubernetes Core DNS server +Documentation=https://github.com/coredns/coredns +After=network.target + +[Service] +ExecStart=bash -c "KUBE_DNS_SERVICE_HOST=10.32.0.10 coredns -conf /etc/kubernetes/pki/dns/Corefile" + +Restart=on-failure +LimitNOFILE=65536 + +[Install] +WantedBy=multi-user.target +``` + +### 启动服务 + +```bash +$ systemctl enable coredns +$ systemctl start coredns +``` + +### 创建 coredns 的 Service 对象 + +```bash +$ cat coredns_server.yaml +apiVersion: v1 +kind: Service +metadata: + name: kube-dns + namespace: kube-system + annotations: + prometheus.io/port: "9153" + prometheus.io/scrape: "true" + labels: + k8s-app: kube-dns + kubernetes.io/cluster-service: "true" + kubernetes.io/name: "CoreDNS" +spec: + clusterIP: 10.32.0.10 + ports: + - name: dns + port: 53 + protocol: UDP + - name: dns-tcp + port: 53 + protocol: TCP + - name: metrics + port: 9153 + protocol: TCP +``` + +### 创建 coredns 的 endpoint 对象 + +```bash +$ cat coredns_ep.yaml +apiVersion: v1 +kind: Endpoints +metadata: + name: kube-dns + namespace: kube-system +subsets: + - addresses: + - ip: 192.168.122.157 + ports: + - name: dns-tcp + port: 53 + protocol: TCP + - name: dns + port: 53 + protocol: UDP + - name: metrics + port: 9153 + protocol: TCP +``` + +### 确认 coredns 服务 + +```bash +# 查看service对象 +$ kubectl get service -n kube-system kube-dns +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +kube-dns ClusterIP 10.32.0.10 53/UDP,53/TCP,9153/TCP 51m +# 查看endpoint对象 +$ kubectl get endpoints -n kube-system kube-dns +NAME ENDPOINTS AGE +kube-dns 192.168.122.157:53,192.168.122.157:53,192.168.122.157:9153 52m +``` diff --git a/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/deploying-control-plane-components.md b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/deploying-control-plane-components.md new file mode 100644 index 0000000000000000000000000000000000000000..0ace9d653603bbcad4d8ad31aa1146969ed10aa1 --- /dev/null +++ b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/deploying-control-plane-components.md @@ -0,0 +1,357 @@ +# 部署控制面组件 + +## 准备所有组件的 kubeconfig + +### kube-proxy + +```bash +$ kubectl config set-cluster openeuler-k8s --certificate-authority=/etc/kubernetes/pki/ca.pem --embed-certs=true --server=https://192.168.122.154:6443 --kubeconfig=kube-proxy.kubeconfig +$ kubectl config set-credentials system:kube-proxy --client-certificate=/etc/kubernetes/pki/kube-proxy.pem --client-key=/etc/kubernetes/pki/kube-proxy-key.pem --embed-certs=true --kubeconfig=kube-proxy.kubeconfig +$ kubectl config set-context default --cluster=openeuler-k8s --user=system:kube-proxy --kubeconfig=kube-proxy.kubeconfig +$ kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig +``` + +### kube-controller-manager + +```bash +$ kubectl config set-cluster openeuler-k8s --certificate-authority=/etc/kubernetes/pki/ca.pem --embed-certs=true --server=https://127.0.0.1:6443 --kubeconfig=kube-controller-manager.kubeconfig +$ kubectl config set-credentials system:kube-controller-manager --client-certificate=/etc/kubernetes/pki/kube-controller-manager.pem --client-key=/etc/kubernetes/pki/kube-controller-manager-key.pem --embed-certs=true --kubeconfig=kube-controller-manager.kubeconfig +$ kubectl config set-context default --cluster=openeuler-k8s --user=system:kube-controller-manager --kubeconfig=kube-controller-manager.kubeconfig +$ kubectl config use-context default --kubeconfig=kube-controller-manager.kubeconfig +``` + +### kube-scheduler + +```bash +$ kubectl config set-cluster openeuler-k8s --certificate-authority=/etc/kubernetes/pki/ca.pem --embed-certs=true --server=https://127.0.0.1:6443 --kubeconfig=kube-scheduler.kubeconfig +$ kubectl config set-credentials system:kube-scheduler --client-certificate=/etc/kubernetes/pki/kube-scheduler.pem --client-key=/etc/kubernetes/pki/kube-scheduler-key.pem --embed-certs=true --kubeconfig=kube-scheduler.kubeconfig +$ kubectl config set-context default --cluster=openeuler-k8s --user=system:kube-scheduler --kubeconfig=kube-scheduler.kubeconfig +$ kubectl config use-context default --kubeconfig=kube-scheduler.kubeconfig +``` + +### admin + +```bash +$ kubectl config set-cluster openeuler-k8s --certificate-authority=/etc/kubernetes/pki/ca.pem --embed-certs=true --server=https://127.0.0.1:6443 --kubeconfig=admin.kubeconfig +$ kubectl config set-credentials admin --client-certificate=/etc/kubernetes/pki/admin.pem --client-key=/etc/kubernetes/pki/admin-key.pem --embed-certs=true --kubeconfig=admin.kubeconfig +$ kubectl config set-context default --cluster=openeuler-k8s --user=admin --kubeconfig=admin.kubeconfig +$ kubectl config use-context default --kubeconfig=admin.kubeconfig +``` + +### 获得相关 kubeconfig 配置文件 + +```bash +admin.kubeconfig kube-proxy.kubeconfig kube-controller-manager.kubeconfig kube-scheduler.kubeconfig +``` + +## 生成密钥提供者的配置 + +api-server 启动时需要提供一个密钥对`--encryption-provider-config=/etc/kubernetes/pki/encryption-config.yaml`,本文通过 urandom 生成一个: + +```bash +$ cat generate.bash +#!/bin/bash + +ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64) + +cat > encryption-config.yaml < ![](./public_sys-resources/icon-note.gif)**说明** +> +> - 删除集群会删除整个集群的数据,且无法恢复,请谨慎操作。 +> - 当前,拆除集群不会清理容器和容器镜像,但若部署 Kubernetes 集群时,配置了需要安装容器引擎,则会清除容器引擎,这可能导致容器运行异常。 +> - 拆除集群过程中可能会打印一些错误信息,一般是由于清理过程中操作集群时反馈了错误的结果导致,集群仍然能够正常拆除 +> + +可以使用命令行方式删除整个集群。例如,删除 k8s-cluster 集群的参考命令如下: + +```shell +$ eggo -d cleanup --id k8s-cluster +``` diff --git a/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/eggo-tool-introduction.md b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/eggo-tool-introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..0f73d2921d9c69282856fe84e96e4b2636b69208 --- /dev/null +++ b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/eggo-tool-introduction.md @@ -0,0 +1,431 @@ +# 工具介绍 + +本章介绍自动化部署工具的相关内容,建议用户在部署前阅读。 + +## 部署方式 + +openEuler 提供的 Kubernetes 集群自动化部署工具使用命令行方式进行集群的一键部署。它提供了如下几种部署方式: + +- 离线部署:本地准备好所有需要用到的 RPM 软件包、二进制文件、插件、容器镜像,并将它们按照一定的格式打包成一个 tar.gz 文件,然后完成对应 YAML 配置文件的编写,即可执行命令实现一键部署。当虚拟机无法访问外部网络时,可以采用该部署方式。 +- 在线部署:只需要完成对应 YAML 配置文件的编写,所需的RPM 软件包、二进制文件、插件、容器镜像,都在安装部署阶段连接互联网自动下载。该方式需要虚拟机能够访问软件源、集群依赖的镜像仓库,例如 Docker Hub。 + +## 配置介绍 + +使用工具自动化部署 Kubernetes 集群时,使用 YAML 配置文件描述集群部署的信息,此处介绍各配置项含义以及配置示例。 + +### 配置项介绍 + +- cluster-id:集群名称,请遵循 DNS 域名的命名规范。例如 k8s-cluster + +- username:需要部署 k8s 集群的机器的 ssh 登录用户名,所有机器都需要使用同一个用户名。 + +- private-key-path:ssh 免密登录的密钥存储文件的路径。private-key-path 和 password 只需要配置其中一项,如果两者都进行了配置,优先使用 private-key-path + +- masters:master 节点列表,建议每个 master 节点同时作为 worker 节点。每个 master 节点包含如下配置子项,多个 master 节点配置多组子项内容: + - name:master 节点名称,为 k8s 集群看到的该节点名称 + - ip:master 节点的 IP 地址 + - port:ssh 登录该节点的端口,默认为 22 + - arch:master 节点的 CPU 架构,例如 x86_64 取值为 amd64 + +- workers:worker 节点列表。每个 worker 节点包含如下配置子项,多个 worker 节点配置多个子项内容: + - name:worker 节点名称,为 k8s 集群看到的该节点名称 + - ip:worker 节点的 IP 地址 + - port:ssh 登录该节点的端口,默认为 22 + - arch:worker 节点的 CPU 架构,例如 x86_64 取值为 amd64 + +- etcds:etcd 节点的列表。如果该项为空,则会为每个 master 节点部署一个 etcd,否则只会部署配置的 etcd 节点。每个 etcd 节点包含如下配置子项,多个 etcd 节点配置多组子项内容: + - name:etcd 节点的名称,为 k8s 集群看到的该节点的名称 + - ip:etcd 节点的 IP 地址 + - port:ssh 登录的端口 + - arch:etcd 节点的 CPU 架构,例如 x86_64 取值为 amd64 + +- loadbalance:loadbalance 节点列表。每个 loadbalance 节点包含如下配置子项,多个 loadbalance 节点配置多组子项内容: + - name:loadbalance 节点的名称,为 k8s 集群看到的该节点的名称 + - ip:loadbalance 节点的 IP 地址 + - port:ssh 登录的端口 + - arch:loadbalance 节点的 CPU 架构,例如 x86_64 取值为 amd64 + - bind-port:负载均衡服务的侦听端口 + +- external-ca:是否使用外部 CA 证书,使用则配置为 true,反之,配置为 false + +- external-ca-path:外部 CA 证书文件的路径 。仅 external-ca 为 true 时有效 + +- service:k8s 创建的 service 信息。service 配置包含如下配置子项: + - cidr:k8s 创建的 service 的 IP 地址网段 + - dnsaddr:k8s 创建的 service 的 DNS 地址 + - gateway:k8s创建的 service 的网关地址 + - dns:k8s 创建的 coredns 的配置。dns 配置包含如下配置子项: + - corednstype:k8s 创建的 coredns 的部署类型,支持 pod 和 binary + - imageversion:pod 部署类型的 coredns 镜像版本 + - replicas:pod 部署类型的 coredns 副本数量 + +- network:k8s 集群网络配置。network 配置包含如下配置子项: + - podcidr:k8s 集群网络的 IP 地址网段 + - plugin:k8s 集群部署的网络插件 + - plugin-args:k8s 集群网络的网络插件的配置文件路径。例如 : {"NetworkYamlPath": "/etc/kubernetes/addons/calico.yaml"} + +- apiserver-endpoint:进群外部可访问的 APISERVER 服务的地址或域名,如果配置了 loadbalances 则填loadbalance 地址,否则填写第 1 个 master 节点地址。 + +- apiserver-cert-sans:apiserver 相关证书中需要额外配置的 IP 和域名。它包含如下子配置项 + - dnsnames:apiserver 相关证书中需要额外配置的域名数组列表。 + - ips:apiserver 相关证书中需要额外配置的 IP 地址数组列表。 + +- apiserver-timeout:apiserver 响应超时时间 + +- etcd-token:etcd 集群名称 + +- dns-vip:dns 的虚拟 IP 地址 + +- dns-domain:DNS 域名后缀 + +- pause-image:pause 容器的完整镜像名称 + +- network-plugin:网络插件类型。仅支持配置 cni ,配置为空时使用 k8s 默认网络。 + +- cni-bin-dir:网络插件地址,多个地址使用 "," 分隔,例如:/usr/libexec/cni,/opt/cni/bin + +- runtime:指定容器运行时类型,目前支持 docker 和 iSulad + +- runtime-endpoint:容器运行时 endpoint,当 runtime 为 docker 时,可以不指定 + +- registry-mirrors:下载容器镜像时,使用的镜像仓库的 mirror 站点地址 + +- insecure-registries:下载容器镜像时,使用 http 协议下载镜像的镜像仓库地址 + +- config-extra-args:各个组件(例如 kube-apiserver、etcd)服务启动配置的额外参数。它包含如下子配置项: + - name:组件名称,支持 etcd、kube-apiserver、kube-controller-manager、kube-scheduler、kube-proxy、kubelet + + - extra-args:组件的拓展参数,格式为 key: value 格式,注意 key 对应的组件参数前需要加上 "-" 或者 "--" 。 + + - open-ports:配置需要额外打开的端口,k8s 自身所需端口不需要进行配置,k8s 以外的插件端口需要进行额外配置。 + - worker | master | etcd | loadbalance:指定打开端口的节点类型,每项配置包含一个多或者多个 port 和 protocol 子配置项。 + - port:端口地址 + - protocol:端口类型,可选值为 tcp 或者 udp + + - install:配置各种类型节点上需要安装的安装包或者二进制文件的详细信息,注意将对应文件放到在 tar.gz 安装包中。以下为全量配置说明,具体配置请根据实际情况选择。 + - package-source:配置安装包的详细信息 + - type:安装包的压缩类型,目前只支持 tar.gz 类型的安装包 + - dstpath:安装包在对端机器上的路径,必须是可用的绝对路径 + - srcpath:不同架构安装包的存放路径,架构必须与机器架构相对应,必须是可用的绝对路径 + - arm64:arm64 架构安装包的路径,配置的机器中存在 arm64 机器场景下需要配置 + - amd64:amd64 类型安装包的路径,配置的机器中存在 x86_64 机器场景下需要配置 + + > ![](./public_sys-resources/icon-note.gif)**说明**: + > + > install 配置中 etcd、kubernetes-master、kubernetes-worker、network、loadbalance、container、image、dns 中的子配置项相同,都是 name、type、dst,schedule、TimeOut 。其中 dst,schedule、TimeOut 为可选项,用户根据安装的文件决定是否配置。下述仅以 etcd 和 kubernetes-master 节点的配置为例说明。 + + - etcd:etcd 类型节点需要安装的包或二进制文件列表。 + - name:需要安装的软件包或二进制文件的名称,如果是安装包则只写名称,不填写具体的版本号,安装时会使用 `$name*` 识别,例如 etcd 。如果为多个软件包,各名称使用 ,分隔。 + - type:配置项类型,可选值为 pkg、repo、bin、file、dir、image、yaml、shell 。如果配置为 repo ,请在对应节点上配置 repo 源。 + - dst:目的文件夹路径,type 为 bin、file、dir 类型时需要配置。表示将文件/文件夹放到节点的哪个目录下,为了防止用户误配置路径,导致 cleanup 时删除重要文件,此配置必须配置为白名单中的路径。详见 “白名单说明” 。 + - kubernetes-master:k8s master 类型节点需要安装的包或二进制文件列表 + - kubernetes-worker:k8s worker 类型节点需要安装的包或二进制文件列表 + - network:网络需要安装的包或二进制文件列表 + - loadbalance:loadbalance 类型节点需要安装的包或二进制文件列表 + - container:容器需要安装的包或二进制文件列表 + - image:容器镜像 tar 包 + - dns:k8s coredns 安装包。如果 corednstype 配置为 pod,此处无需配置 + - addition:额外的安装包或二进制文件列表 + - master:以下配置会安装在所有 master 节点 + - name:需要安装的软件包或二进制文件的名称 + - type:配置项类型,可选值为 pkg、repo、bin、file、dir、image、yaml、shell 。如果配置为 repo ,请在对应节点上配置 repo 源 + - schedule:仅在 type 为 shell 时有效,代表用户想要执行脚本的时机,支持 prejoin(节点加入前)、postjoin(节点加入后)、precleanup(节点退出前)、postcleanup(节点退出后)。 + - TimeOut:脚本执行超时时间,超时时该进程被强制终止运行。未配置默认为 30s + - worker:配置会安装在所有 worker 节点,具体配置格式和 addition 下的 master 相同 + +### 白名单介绍 + +install 配置中 dst 项的值必须符合白名单规则,配置为白名单对应路径及其子目录。当前白名单如下: + +- /usr/bin +- /usr/local/bin +- /opt/cni/bin +- /usr/libexec/cni +- /etc/kubernetes +- /usr/lib/systemd/system +- /etc/systemd/system +- /tmp + +### 配置示例 + +此处给出一个 YAML 文件配置示例。从示例可知,同一台机器,可以部署多个类型的节点,但是不同节点的配置必须一致,例如 test0 机器部署了 master 和 worker 类型。 + +```yaml +cluster-id: k8s-cluster +username: root +private-key-path: /root/.ssh/private.key +masters: +- name: test0 + ip: 192.168.0.1 + port: 22 + arch: arm64 +workers: +- name: test0 + ip: 192.168.0.1 + port: 22 + arch: arm64 +- name: test1 + ip: 192.168.0.3 + port: 22 + arch: arm64 +etcds: +- name: etcd-0 + ip: 192.168.0.4 + port: 22 + arch: amd64 +loadbalance: + name: k8s-loadbalance + ip: 192.168.0.5 + port: 22 + arch: amd64 + bind-port: 8443 +external-ca: false +external-ca-path: /opt/externalca +service: + cidr: 10.32.0.0/16 + dnsaddr: 10.32.0.10 + gateway: 10.32.0.1 + dns: + corednstype: pod + imageversion: 1.8.4 + replicas: 2 +network: + podcidr: 10.244.0.0/16 + plugin: calico + plugin-args: {"NetworkYamlPath": "/etc/kubernetes/addons/calico.yaml"} +apiserver-endpoint: 192.168.122.222:6443 +apiserver-cert-sans: + dnsnames: [] + ips: [] +apiserver-timeout: 120s +etcd-external: false +etcd-token: etcd-cluster +dns-vip: 10.32.0.10 +dns-domain: cluster.local +pause-image: k8s.gcr.io/pause:3.2 +network-plugin: cni +cni-bin-dir: /usr/libexec/cni,/opt/cni/bin +runtime: docker +runtime-endpoint: unix:///var/run/docker.sock +registry-mirrors: [] +insecure-registries: [] +config-extra-args: + - name: kubelet + extra-args: + "--cgroup-driver": systemd +open-ports: + worker: + - port: 111 + protocol: tcp + - port: 179 + protocol: tcp +install: + package-source: + type: tar.gz + dstpath: "" + srcpath: + arm64: /root/rpms/packages-arm64.tar.gz + amd64: /root/rpms/packages-x86.tar.gz + etcd: + - name: etcd + type: pkg + dst: "" + kubernetes-master: + - name: kubernetes-client,kubernetes-master + type: pkg + kubernetes-worker: + - name: docker-engine,kubernetes-client,kubernetes-node,kubernetes-kubelet + type: pkg + dst: "" + - name: conntrack-tools,socat + type: pkg + dst: "" + network: + - name: containernetworking-plugins + type: pkg + dst: "" + loadbalance: + - name: gd,gperftools-libs,libunwind,libwebp,libxslt + type: pkg + dst: "" + - name: nginx,nginx-all-modules,nginx-filesystem,nginx-mod-http-image-filter,nginx-mod-http-perl,nginx-mod-http-xslt-filter,nginx-mod-mail,nginx-mod-stream + type: pkg + dst: "" + container: + - name: emacs-filesystem,gflags,gpm-libs,re2,rsync,vim-filesystem,vim-common,vim-enhanced,zlib-devel + type: pkg + dst: "" + - name: libwebsockets,protobuf,protobuf-devel,grpc,libcgroup + type: pkg + dst: "" + - name: yajl,lxc,lxc-libs,lcr,clibcni,iSulad + type: pkg + dst: "" + image: + - name: pause.tar + type: image + dst: "" + dns: + - name: coredns + type: pkg + dst: "" + addition: + master: + - name: prejoin.sh + type: shell + schedule: "prejoin" + TimeOut: "30s" + - name: calico.yaml + type: yaml + dst: "" + worker: + - name: docker.service + type: file + dst: /usr/lib/systemd/system/ + - name: postjoin.sh + type: shell + schedule: "postjoin" +``` + +### 安装包结构 + +如果是离线部署,需要准备 Kubernetes 以及相关的离线安装包,并遵循特定目录结构存放离线安装包。需要遵循的目录结构如下: + +```shell +package +├── bin +├── dir +├── file +├── image +├── pkg +└── packages_notes.md +``` + +上述各目录的含义如下: + +- 离线部署包的目录结构与集群配置 config 中的 package 的类型对应,package 类型有 pkg、repo、bin、file、dir、image、yaml、shell 八种。 + +- bin 目录存放二进制文件,对应 package 类型 bin 。 + +- dir 目录存放需要拷贝到目标机器的目录,需要配置 dst 目的地路径,对应 package 类型 dir 。 + +- file 目录存放 file、yaml、shell 三种类型的文件。其中 file 类型代表需要拷贝到目标机器的文件,同时需要配置 dst 目的地路径;yaml 类型代表用户自定义的 YAML 文件,会在集群部署完成后 apply 该 YAML 文件;shell 类型代表用户想要执行的脚本,同时需要配置 schedule 执行时机,执行时机包括 prejoin(节点加入前)、postjoin(节点加入后)、precleanup(节点退出前)、postcleanup(节点退出后)四个阶段。 + +- image 目录存放需要导入的容器镜像。这些容器镜像必须兼容 docker 的 tar 包格式(例如由 docker 或 isula-build 导出镜像)。 + +- pkg 目录下存放需要安装的 rpm/deb 包,对应 package 类型 pkg 。建议使用二进制文件,便于跨发行版本的部署。 + +### 命令参考 + +openEuler 提供的集群部署工具,使用命令行 eggo 进行集群部署。 + +#### 部署 k8s 集群 + +通过指定的 YAML 配置部署 k8s 集群: + +**eggo deploy** [ **-d** ] **-f** *deploy.yaml* + +| 参数 | 是否必选 | 参数含义 | +| ------------- | -------- | --------------------------------- | +| --debug \| -d | 否 | 打印调试信息 | +| --file \| -f | 是 | 指定部署 k8s 集群的 YAML 文件路径 | + +#### 加入单节点 + +将指定的单节点加入到 k8s 集群中: + +**eggo** **join** [ **-d** ] **--id** *k8s-cluster* [ **--type** *master,worker* ] **--arch** *arm64* **--port** *22* [ **--name** *master1*] *IP* + +| 参数 | 是否必选 | 参数含义 | +| ------------- | -------- | ------------------------------------------------------------ | +| --debug \| -d | 否 | 打印调试信息 | +| --id | 是 | 指定将要加入 k8s 集群名称 | +| --type \| -t | 否 | 指定加入节点的类型,支持 master、worker 。多个类型使用 “,” 隔开,默认值为 worker 。 | +| --arch \| -a | 是 | 指定加入节点的 CPU 架构 | +| --port \| -p | 是 | 指定 ssh 登录所加入节点的端口号 | +| --name \| -n | 否 | 指定加入节点的名称 | +| *IP* | 是 | 加入节点的实际 IP 地址 | + +#### 加入多节点 + +将指定的多个节点加入到 k8s 集群: + +**eggo** **join** [ **-d** ] **--id** *k8s-cluster* **-f** *nodes.yaml* + +| 参数 | 是否必选 | 参数含义 | +| ------------- | -------- | -------------------------------- | +| --debug \| -d | 否 | 打印调试信息 | +| --id | 是 | 指定将要加入 k8s 集群名称 | +| --file \| -f | 是 | 指定加入节点的 YAML 配置文件路径 | + +#### 删除节点 + +删除 k8s 集群中的一个或者多个节点: + +**eggo delete** [ **-d** ] **--id** *k8s-cluster* *node* [*node...*] + +| 参数 | 是否必选 | 参数含义 | +| ------------- | -------- | -------------------------------------------- | +| --debug \| -d | 否 | 打印调试信息 | +| --id | 是 | 指定将要删除的节点所在的集群名称 | +| *node* | 是 | 要删除的单个或多个节点的 IP 地址或者节点名称 | + +#### 删除集群 + +删除整个 k8s 集群: + +**eggo cleanup** [ **-d** ] **--id** *k8s-cluster* [ **-f** *deploy.yaml* ] + +| 参数 | 是否必选 | 参数含义 | +| ------------- | -------- | ------------------------------------------------------------ | +| --debug \| -d | 否 | 打印调试信息 | +| --id | 是 | 指定将要清除的 k8s 集群名称 | +| --file \| -f | 否 | 指定清除 k8s 集群的 YAML 文件路径。不指定时,默认使用部署集群时缓存的集群配置。正常情况下,建议不配置该选项,仅异常情况下配置。 | + +> ![](./public_sys-resources/icon-note.gif)**说明** +> +> - 建议使用部署集群时缓存的集群配置删除集群,即正常情况下,不建议配置 --file | -f 参数。当异常导致缓存配置破坏或者丢失时,才配置该参数。 + +#### 查询集群 + +查询当前所有通过 eggo 部署的 k8s 集群: + +**eggo list** [ **-d** ] + +| 参数 | 是否必选 | 参数含义 | +| ------------- | -------- | ------------ | +| --debug \| -d | 否 | 打印调试信息 | + +#### 生成集群配置文件 + +快速生成部署 k8s 集群所需的 YAML 配置文件: + +**eggo template** **-d** **-f** *template.yaml* **-n** *k8s-cluster* **-u** *username* **-p** *password* **--etcd** [*192.168.0.1,192.168.0.2*] **--masters** [*192.168.0.1,192.168.0.2*] **--workers** *192.168.0.3* **--loadbalance** *192.168.0.4* + +| 参数 | 是否必选 | 参数含义 | +| ------------------- | -------- | ------------------------------- | +| --debug \| -d | 否 | 打印调试信息 | +| --file \| -f | 否 | 指定生成的 YAML 文件的路径 | +| --name \| -n | 否 | 指定 k8s 集群的名称 | +| --username \| -u | 否 | 指定 ssh 登录所配置节点的用户名 | +| --password \| -p | 否 | 指定 ssh 登录所配置节点的密码 | +| --etcd | 否 | 指定 etcd 节点的 IP 列表 | +| --masters | 否 | 指定 master 节点的 IP 列表 | +| --workers | 否 | 指定 worker 节点的 IP 列表 | +| --loadbalance \| -l | 否 | 指定 loadbalance 节点的 IP | + +#### 查询帮助信息 + +查询 eggo 命令的帮助信息: + + **eggo help** + +#### 查询子命令帮助信息 + +查询 eggo 子命令的帮助信息: + +**eggo deploy | join | delete | cleanup | list | template -h** + +| 参数 | 是否必选 | 参数含义 | +| ----------- | -------- | ------------ | +| --help\| -h | 是 | 打印帮助信息 | diff --git a/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/figures/advertiseAddress.png b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/figures/advertiseAddress.png new file mode 100644 index 0000000000000000000000000000000000000000..b36e5c4664f2d2e5faaa23128fd4711c11e30179 Binary files /dev/null and b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/figures/advertiseAddress.png differ diff --git a/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/figures/arch.png b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/figures/arch.png new file mode 100644 index 0000000000000000000000000000000000000000..93c5b4cb56b6d165dc5a5cf7aa76a007c362ef55 Binary files /dev/null and b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/figures/arch.png differ diff --git a/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/figures/flannelConfig.png b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/figures/flannelConfig.png new file mode 100644 index 0000000000000000000000000000000000000000..dc9e7c665edd02fad16d3e6f4970e3125efcbef8 Binary files /dev/null and b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/figures/flannelConfig.png differ diff --git a/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/figures/name.png b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/figures/name.png new file mode 100644 index 0000000000000000000000000000000000000000..dd6ddfdc3476780e8c896bfd5095025507f62fa8 Binary files /dev/null and b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/figures/name.png differ diff --git a/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/figures/podSubnet.png b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/figures/podSubnet.png new file mode 100644 index 0000000000000000000000000000000000000000..b368f77dd7dfd7722dcf7751b3e37ec28755e42d Binary files /dev/null and b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/figures/podSubnet.png differ diff --git a/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/installing-etcd.md b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/installing-etcd.md new file mode 100644 index 0000000000000000000000000000000000000000..375f9b87072bf03a867d006658ecd4be6e84ceca --- /dev/null +++ b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/installing-etcd.md @@ -0,0 +1,88 @@ +# 安装 etcd + +## 准备环境 + +使能 etcd 使用的端口: + +```bash +firewall-cmd --zone=public --add-port=2379/tcp +firewall-cmd --zone=public --add-port=2380/tcp +``` + +## 安装 etcd 二进制 + +当前是通过 rpm 包安装 + +```bash +rpm -ivh etcd*.rpm +``` + +准备目录 + +```bash +mkdir -p /etc/etcd /var/lib/etcd +cp ca.pem /etc/etcd/ +cp kubernetes-key.pem /etc/etcd/ +cp kubernetes.pem /etc/etcd/ +# 关闭selinux +setenforce 0 +# 禁用/etc/etcd/etcd.conf文件的默认配置 +# 注释掉即可,例如:ETCD_LISTEN_CLIENT_URLS="http://localhost:2379" +``` + +## 编写 etcd.service 文件 + +以 `k8smaster0`机器为例: + +```bash +$ cat /usr/lib/systemd/system/etcd.service +[Unit] +Description=Etcd Server +After=network.target +After=network-online.target +Wants=network-online.target + +[Service] +Type=notify +WorkingDirectory=/var/lib/etcd/ +EnvironmentFile=-/etc/etcd/etcd.conf +# set GOMAXPROCS to number of processors +ExecStart=/bin/bash -c "ETCD_UNSUPPORTED_ARCH=arm64 /usr/bin/etcd --name=k8smaster0 --cert-file=/etc/etcd/kubernetes.pem --key-file=/etc/etcd/kubernetes-key.pem --peer-cert-file=/etc/etcd/kubernetes.pem --peer-key-file=/etc/etcd/kubernetes-key.pem --trusted-ca-file=/etc/etcd/ca.pem --peer-trusted-ca-file=/etc/etcd/ca.pem --peer-client-cert-auth --client-cert-auth --initial-advertise-peer-urls https://192.168.122.154:2380 --listen-peer-urls https://192.168.122.154:2380 --listen-client-urls https://192.168.122.154:2379,https://127.0.0.1:2379 --advertise-client-urls https://192.168.122.154:2379 --initial-cluster-token etcd-cluster-0 --initial-cluster k8smaster0=https://192.168.122.154:2380,k8smaster1=https://192.168.122.155:2380,k8smaster2=https://192.168.122.156:2380 --initial-cluster-state new --data-dir /var/lib/etcd" + +Restart=always +RestartSec=10s +LimitNOFILE=65536 + +[Install] +WantedBy=multi-user.target +``` + +**注意:** + +- arm64上面需要增加启动设置`ETCD_UNSUPPORTED_ARCH=arm64`; +- 由于本文把etcd和k8s control部署在相同机器,所以使用了`kubernetes.pem`和`kubernetes-key.pem`证书来启动; +- ca证书,在整个部署流程里面使用了一个,etcd可以生成自己的ca,然后用自己的ca签名其他证书,但是需要在apiserver访问etcd的client用该ca签名的证书; +- `initial-cluster`需要把所有部署etcd的配置加上; +- 为了提高etcd的存储效率,可以使用ssd硬盘的目录,作为`data-dir`; + +启动服务 + +```bash +$ systemctl enable etcd +$ systemctl start etcd +``` + +然后,依次部署其他机器即可。 + +## 验证基本功能 + +```bash +$ ETCDCTL_API=3 etcdctl -w table endpoint status --endpoints=https://192.168.122.155:2379,https://192.168.122.156:2379,https://192.168.122.154:2379 --cacert=/etc/etcd/ca.pem --cert=/etc/etcd/kubernetes.pem --key=/etc/etcd/kubernetes-key.pem ++------------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ +| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFTAPPLIED INDEX | ERRORS | ++------------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ +| https://192.168.122.155:2379 | b50ec873e253ebaa | 3.4.14 | 262 kB | false | false | 819 | 21 | 21 | | +| https://192.168.122.156:2379 | e2b0d126774c6d02 | 3.4.14 | 262 kB | true | false | 819 | 21 | 21 | | +| https://192.168.122.154:2379 | f93b3808e944c379 | 3.4.14 | 328 kB | false | false | 819 | 21 | 21 | | ++------------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ +``` diff --git a/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/installing-the-Kubernetes-software-package.md b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/installing-the-Kubernetes-software-package.md new file mode 100644 index 0000000000000000000000000000000000000000..924795f889b5bf8747baed8d21904f1dda27aba9 --- /dev/null +++ b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/installing-the-Kubernetes-software-package.md @@ -0,0 +1,11 @@ +# 安装 Kubernetes 软件包 + +```bash +dnf install -y docker conntrack-tools socat +``` + +配置EPOL源之后,可以直接通过 dnf 安装 K8S + +```bash +dnf install kubernetes +``` diff --git a/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/kubernetes-containerd.md b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/kubernetes-containerd.md new file mode 100644 index 0000000000000000000000000000000000000000..ac603e15c59002ed7aa301f65fc7bd8f0c004735 --- /dev/null +++ b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/kubernetes-containerd.md @@ -0,0 +1,306 @@ +# Kubernetes集群部署指南 - containerd + +Kubernetes自1.21版本开始不再支持Kubernetes+docker部署Kubernetes集群,本文介绍以containerd作为容器运行时快速搭建Kubernetes集群。若需要对集群进行个性化配置,请查阅[官方文档](https://kubernetes.io/zh-cn/docs/home/) 。 + +## 软件包安装 + +### 1. 安装必要软件包 + +```bash +$ yum install -y containerd +$ yum install -y kubernetes* +$ yum install -y cri-tools +``` + +> ![](./public_sys-resources/icon-note.gif)**说明** +> +> - 如果系统中已经安装了Docker,请确保在安装containerd之前卸载Docker,否则可能会引发冲突。 + +要求使用1.6.22-15或更高版本的containerd,如果下载的版本过低请运行以下命令升级成1.6.22-15版本,或自行升级。 + +```bash +$ wget --no-check-certificate https://repo.openeuler.org/openEuler-24.03-LTS/update/x86_64/Packages/containerd-1.6.22-15.oe2403.x86_64.rpm +$ rpm -Uvh containerd-1.6.22-15.oe2403.x86_64.rpm +``` + +本教程中通过yum下载的软件包版本如下所示: + +```bash +1. containerd + -架构:x86_64 + -版本:1.6.22-15 +2. kubernetes - client/help/kubeadm/kubelet/master/node + -架构:x86_64 + -版本:1.29.1-4 +3. cri-tools + -架构:X86_64 + -版本:1.29.0-3 +``` + +### 2. 下载cni组件 + +```bash +$ mkdir -p /opt/cni/bin +$ cd /opt/cni/bin +$ wget --no-check-certificate https://github.com/containernetworking/plugins/releases/download/v1.5.1/cni-plugins-linux-amd64-v1.5.1.tgz +$ tar -xzvf ./cni-plugins-linux-amd64-v1.5.1.tgz -C . +``` + +> ![](./public_sys-resources/icon-note.gif)**说明** +> +> - 这里提供的是AMD64架构版本的下载链接,请根据系统架构选择合适的版本,其他版本可从[github仓库](https://github.com/containernetworking/plugins/releases/)获取。 + +### 3. 下载CNI插件(Flannel) + +```bash +$ wget https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml --no-check-certificate +``` + +## 环境配置 + +本节对Kubernetes运行时所需的操作系统环境进行配置。 + +### 1. 设置主机名 + +```bash +$ hostnamectl set-hostname nodeName +``` + +### 2. 配置防火墙 + +**方法一:** + +配置防火墙规则以开放etcd和API Server的端口,确保控制平面和工作节点之间的正常通信。 +开放etcd的端口: + +```bash +$ firewall-cmd --zone=public --add-port=2379/tcp --permanent +$ firewall-cmd --zone=public --add-port=2380/tcp --permanent +``` + +开放API Server的端口: + +```bash +$ firewall-cmd --zone=public --add-port=6443/tcp --permanent +``` + +使防火墙规则生效: + +```bash +$ firewall-cmd --reload +``` + +> ![](./public_sys-resources/icon-note.gif)**说明** +> +> - 防火墙配置可能会导致某些容器镜像无法正常使用。为了确保其顺利运行,需要根据所使用的镜像开放相应的端口。 + +**方法二:** + +使用以下命令禁用防火墙: + +```bash +$ systemctl stop firewalld +$ systemctl disable firewalld +``` + +### 3. 禁用SELinux + +SELinux的安全策略可能会阻止容器内的某些操作,比如写入特定目录、访问网络资源、或执行具有特权的操作。这会导致 CoreDNS 等关键服务无法正常运行,并表现为CrashLoopBackOff或 Error状态。可以使用以下命令来禁用SELinux: + +```bash +$ setenforce 0 +$ sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config +``` + +### 4. 禁用swap + +Kubernetes的资源调度器根据节点的可用内存和CPU资源来决定将哪些Pod分配到哪些节点上。如果节点上启用了swap,实际可用的物理内存和逻辑上可用的内存可能不一致,这会影响调度器的决策,导致某些节点出现过载,或者在某些情况下调度错误。因此需要禁用swap: + +```bash +$ swapoff -a +$ sed -ri 's/.*swap.*/#&/' /etc/fstab +``` + +### 5. 网络配置 + +启用桥接网络上的IPv6和IPv4流量通过iptables进行过滤,并启动IP转发,运行内核转发IPv4包,确保跨界点的Pod间通信: + +```bash +$ cat > /etc/sysctl.d/k8s.conf << EOF +net.bridge.bridge-nf-call-ip6tables = 1 +net.bridge.bridge-nf-call-iptables = 1 +net.ipv4.ip_forward = 1 +vm.swappiness=0 +EOF +$ modprobe br_netfilter +$ sysctl -p /etc/sysctl.d/k8s.conf +``` + +## 配置containerd + +本节对containerd进行配置,包括设置pause_image、cgroup驱动、关闭"registry.k8s.io"镜像源证书验证、配置代理。 + +首先,生成containerd的默认配置文件并将其输出到containerd_conf指定的文件: + +```bash +$ containerd_conf="/etc/containerd/config.toml" +$ mkdir -p /etc/containerd +$ containerd config default > "${containerd_conf}" +``` + +配置pause_image: + +```bash +$ pause_img=$(kubeadm config images list | grep pause | tail -1) +$ sed -i "/sandbox_image/s#\".*\"#\"${pause_img}\"#" "${containerd_conf}" +``` + +将cgroup驱动指定为systemd: + +```bash +$ sed -i "/SystemdCgroup/s/=.*/= true/" "${containerd_conf}" +``` + +关闭"registry.k8s.io"镜像源证书验证: + +```bash +$ sed -i '/plugins."io.containerd.grpc.v1.cri".registry.configs/a\[plugins."io.containerd.grpc.v1.cri".registry.configs."registry.k8s.io".tls]\n insecure_skip_verify = true' /etc/containerd/config.toml +``` + +配置代理(将HTTP_PROXY、HTTPS_PROXY、NO_PROXY中的"***"替换为自己的代理信息): + +```bash +$ server_path="/etc/systemd/system/containerd.service.d" +$ mkdir -p "${server_path}" +$ cat > "${server_path}"/http-proxy.conf << EOF +[Service] +Environment="HTTP_PROXY=***" +Environment="HTTPS_PROXY=***" +Environment="NO_PROXY=***" +EOF +``` + +重启containerd,使得以上配置生效: + +```bash +$ systemctl daemon-reload +$ systemctl restart containerd +``` + +## 配置crictl使用containerd作为容器运行时 + +```bash +$ crictl config runtime-endpoint unix:///run/containerd/containerd.sock +$ crictl config image-endpoint unix:///run/containerd/containerd.sock +``` + +## 配置kubelet使用systemd作为cgroup驱动 + +```bash +$ systemctl enable kubelet.service +$ echo 'KUBELET_EXTRA_ARGS="--runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice"' >> /etc/sysconfig/kubelet +$ systemctl restart kubelet +``` + +## 使用Kubeadm创建集群(仅控制平面需要) + +### 1. 配置集群信息 + +```bash +$ kubeadm config print init-defaults --component-configs KubeletConfiguration >> kubeletConfig.yaml +$ vim kubeletConfig.yaml +``` + +在kubeletConfig.yaml文件中,配置节点名称、广播地址(advertiseAddress)以及Pod网络的CIDR。 + +**修改name为主机名,与环境配置[第一步](#1-设置主机名)一致:** + +![](./figures/name.png) + +**将advertiseAddress修改为控制平面的ip地址:** + +![](./figures/advertiseAddress.png) + +**在Networking中添加podSubnet指定CIDR范围:** + +![](./figures/podSubnet.png) + +### 2. 部署集群 + +这里使用kubeadm部署集群,许多配置是默认生成的(如认证证书),如需修改请查阅[官方文档](https://kubernetes.io/zh-cn/docs/home/ )。 + +**关闭代理(如有):** + +```bash +$ unset http_proxy https_proxy +``` + +使用kubeadm init部署集群: + +```bash +$ kubeadm init --config kubeletConfig.yaml +``` + +指定kubectl使用的配置文件: + +```bash +$ mkdir -p "$HOME"/.kube +$ cp -i /etc/kubernetes/admin.conf "$HOME"/.kube/config +$ chown "$(id -u)":"$(id -g)" "$HOME"/.kube/config +$ export KUBECONFIG=/etc/kubernetes/admin.conf +``` + +### 3. 部署cni插件(flannel) + +本教程中使用flannel作为cni插件,以下介绍flannel下载和部署。 +以下使用的flannel从registry-1.docker.io镜像源下载,为避免证书验证失败的问题,请在containerd配置文件(/etc/containerd/config.toml)中配置该镜像源跳过证书验证。 + +![](./figures/flannelConfig.png) + +使用kubectl apply部署最开始在软件包安装中下载的kube-flannel.yml。 + +```bash +$ kubectl apply -f kube-flannel.yml +``` + +> ![](./public_sys-resources/icon-note.gif)**说明** +> +> 控制平面可能会有污点的问题,导致kubectl get nodes中节点状态无法变成ready,请查阅[官方文档](https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/)去除污点。 +> +## 加入集群(仅工作节点需要) + +**关闭代理(如有):** + +```bash +$ unset http_proxy https_proxy +``` + +工作节点安装配置完环境后可以通过以下命令加入集群。 + +```bash +$ kubeadm join
: --token
--discovery-token-ca-cert-hash sha256: +``` + +这个命令会在控制平面库kubeadm init结束后生成,也可以在控制平面按照以下命令获取: + +```bash +$ kubeadm token create #生成token +$ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \ + openssl dgst -sha256 -hex | sed 's/^.* //' #获取hash +``` + +加入后可以在控制平面通过以下命令查看工作节点的状态: + +```bash +$ kubectl get nodes +``` + +如果节点状态显示为not ready,可能是因为Flannel插件未成功部署。在这种情况下,请运行本地生成的Flannel可执行文件来完成部署。 + +**在工作节点运行kubectl命令(可选):** + +如果需要在工作节点上运行kubectl命令,需要将控制面板的配置文件/etc/kubernetes/admin.conf复制到同样的目录,然后运行以下命令进行配置: + +```bash +$ export KUBECONFIG=/etc/kubernetes/admin.conf +``` diff --git a/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/kubernetes-faqs.md b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/kubernetes-faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..29cff9ae8ac902643a86b2cf3e5437509af2c3e1 --- /dev/null +++ b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/kubernetes-faqs.md @@ -0,0 +1,13 @@ +# 常见问题与解决方法 + +## **问题1:Kubernetes + docker为什么无法部署** + +原因:Kubernetes自1.21版本开始不再支持Kubernetes + docker部署Kubernetes集群。 + +解决方法:改为使用cri-dockerd+docker部署集群,也可以使用containerd或者iSulad部署集群。 + +## **问题2:openEuler无法通过yum直接安装Kubernetes相关的rpm包** + +原因:Kubernetes相关的rpm包需要配置yum的repo源有关EPOL的部分。 + +解决方法:[参考链接](https://forum.openeuler.org/t/topic/768)中repo源,重新配置环境中的EPOL源。 diff --git a/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/overview.md b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..c0af759cb21ee5fdae603a3d1e014f82addb4f7b --- /dev/null +++ b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/overview.md @@ -0,0 +1,12 @@ +# Kubernetes 集群部署指南 + +本文档介绍在 openEuler 操作系统上,通过二进制部署 K8S 集群的一个参考方法。 + +说明:本文所有操作均使用 `root`权限执行。 + +## 集群状态 + +本文所使用的集群状态如下: + +- 集群结构:6 个 `openEuler 21.09`系统的虚拟机,3 个 master 和 3 个 node 节点 +- 物理机:`openEuler 21.09`的 `x86/ARM`服务器 diff --git a/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/preparing-VMs.md b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/preparing-VMs.md new file mode 100644 index 0000000000000000000000000000000000000000..534c7f6342b39dc512168affbd1746fcfb4ab48b --- /dev/null +++ b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/preparing-VMs.md @@ -0,0 +1,150 @@ +# 准备虚拟机 + +本章介绍使用 virt manager 安装虚拟机的方法,如果您已经准备好虚拟机,可以跳过本章节。 + +## 安装依赖工具 + +安装虚拟机,会依赖相关工具,安装依赖并使能 libvirtd 服务的参考命令如下(如果需要代理,请先配置代理): + +```bash +$ dnf install virt-install virt-manager libvirt-daemon-qemu edk2-aarch64.noarch virt-viewer +$ systemctl start libvirtd +$ systemctl enable libvirtd +``` + +## 准备虚拟机磁盘文件 + +```bash +$ dnf install -y qemu-img +$ virsh pool-define-as vmPool --type dir --target /mnt/vm/images/ +$ virsh pool-build vmPool +$ virsh pool-start vmPool +$ virsh pool-autostart vmPool +$ virsh vol-create-as --pool vmPool --name master0.img --capacity 200G --allocation 1G --format qcow2 +$ virsh vol-create-as --pool vmPool --name master1.img --capacity 200G --allocation 1G --format qcow2 +$ virsh vol-create-as --pool vmPool --name master2.img --capacity 200G --allocation 1G --format qcow2 +$ virsh vol-create-as --pool vmPool --name node1.img --capacity 300G --allocation 1G --format qcow2 +$ virsh vol-create-as --pool vmPool --name node2.img --capacity 300G --allocation 1G --format qcow2 +$ virsh vol-create-as --pool vmPool --name node3.img --capacity 300G --allocation 1G --format qcow2 +``` + +## 打开 VNC 防火墙端口 + +**方法一** + +1. 查询端口 + + ```shell + $ netstat -lntup | grep qemu-kvm + ``` + +2. 打开 VNC 的防火墙端口。假设端口从 5900 开始,参考命令如下: + + ```shell + $ firewall-cmd --zone=public --add-port=5900/tcp + $ firewall-cmd --zone=public --add-port=5901/tcp + $ firewall-cmd --zone=public --add-port=5902/tcp + $ firewall-cmd --zone=public --add-port=5903/tcp + $ firewall-cmd --zone=public --add-port=5904/tcp + $ firewall-cmd --zone=public --add-port=5905/tcp + ``` + +**方法二** + +直接关闭防火墙 + +```shell +$ systemctl stop firewalld +``` + +## 准备虚拟机配置文件 + +创建虚拟机需要虚拟机配置文件。假设配置文件为 master.xml ,以虚拟机 hostname 为 k8smaster0 的节点为例,参考配置如下: + +```bash + cat master.xml + + + k8smaster0 + 8 + 8 + + hvm + /usr/share/edk2/aarch64/QEMU_EFI-pflash.raw + /var/lib/libvirt/qemu/nvram/k8smaster0.fd + + + + + + + + + 1 + + destroy + restart + restart + + /usr/libexec/qemu-kvm + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +由于虚拟机相关配置必须唯一,新增虚拟机需要适配修改如下内容,保证虚拟机的唯一性: + +- name:虚拟机 hostname,建议尽量小写。例中为 `k8smaster0` +- nvram:nvram的句柄文件路径,需要全局唯一。例中为 `/var/lib/libvirt/qemu/nvram/k8smaster0.fd` +- disk 的 source file:虚拟机磁盘文件路径。例中为 `/mnt/vm/images/master0.img` +- interface 的 mac address:interface 的 mac 地址。例中为 `52:54:00:00:00:80` + +## 安装虚拟机 + +1. 创建并启动虚拟机 + + ```shell + $ virsh define master.xml + $ virsh start k8smaster0 + ``` + +2. 获取虚拟机的 VNC 端口号 + + ```shell + $ virsh vncdisplay k8smaster0 + ``` + +3. 使用虚拟机连接工具,例如 VNC Viewer 远程连接虚拟机,并根据提示依次选择配置,完成系统安装 + +4. 设置虚拟机 hostname,例如设置为 k8smaster0 + + ```shell + $ hostnamectl set-hostname k8smaster0 + ``` diff --git a/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/preparing-certificates.md b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/preparing-certificates.md new file mode 100644 index 0000000000000000000000000000000000000000..0ae3428c21353ba3326b44b41d18b3706d4b73a8 --- /dev/null +++ b/docs/en/25.03/Cloud/ClusterDeployment/Kubernetes/preparing-certificates.md @@ -0,0 +1,438 @@ +# 准备证书 + +**声明:本文使用的证书为自签名,不能用于商用环境** + +部署集群前,需要生成集群各组件之间通信所需的证书。本文使用开源 CFSSL 作为验证部署工具,以便用户了解证书的配置和集群组件之间证书的关联关系。用户可以根据实际情况选择合适的工具,例如 OpenSSL 。 + +## 配置go环境 + +1. 下载go + + ```bash + wget https://go.dev/dl/go1.22.3.linux-amd64.tar.gz + ``` + +2. 移除旧版本并安装 + + ```bash + $ rm -rf /usr/local/go && tar -C /usr/local -xzf go1.22.3.linux-amd64.tar.gz + ``` + +3. 添加环境变量 + + ```bash + export PATH=$PATH:/usr/local/go/bin + ``` + +4. 检查是否安装成功 + + ```bash + go version + ``` + +## 编译安装 CFSSL + +编译安装 CFSSL 的参考命令如下(需要互联网下载权限,需要配置代理的请先完成配置,需要配置 go语言环境): + +```bash +$ wget --no-check-certificate https://github.com/cloudflare/cfssl/archive/v1.5.0.tar.gz +$ tar -zxf v1.5.0.tar.gz +$ cd cfssl-1.5.0/ +$ make -j6 +# cp bin/* /usr/local/bin/ +``` + +## 生成根证书 + +编写 CA 配置文件,例如 ca-config.json: + +```bash +$ cat ca-config.json | jq +{ + "signing": { + "default": { + "expiry": "8760h" + }, + "profiles": { + "kubernetes": { + "usages": [ + "signing", + "key encipherment", + "server auth", + "client auth" + ], + "expiry": "8760h" + } + } + } +} +``` + +编写 CA CSR 文件,例如 ca-csr.json: + +```bash +$ cat ca-csr.json | jq +{ + "CN": "Kubernetes", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "CN", + "L": "HangZhou", + "O": "openEuler", + "OU": "WWW", + "ST": "BinJiang" + } + ] +} +``` + +生成 CA 证书和密钥: + +```bash +$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca +``` + +得到如下证书: + +```bash +ca.csr ca-key.pem ca.pem +``` + +## 生成 admin 帐户证书 + +admin 是 K8S 用于系统管理的一个帐户,编写 admin 帐户的 CSR 配置,例如 admin-csr.json: + +```bash +cat admin-csr.json | jq +{ + "CN": "admin", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "CN", + "L": "HangZhou", + "O": "system:masters", + "OU": "Containerum", + "ST": "BinJiang" + } + ] +} +``` + +生成证书: + +```bash +$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin +``` + +结果如下: + +```bash +admin.csr admin-key.pem admin.pem +``` + +## 生成 service-account 帐户证书 + +编写 service-account 帐户的 CSR 配置文件,例如 service-account-csr.json: + +```bash +cat service-account-csr.json | jq +{ + "CN": "service-accounts", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "CN", + "L": "HangZhou", + "O": "Kubernetes", + "OU": "openEuler k8s install", + "ST": "BinJiang" + } + ] +} +``` + +生成证书: + +```bash +$ cfssl gencert -ca=../ca/ca.pem -ca-key=../ca/ca-key.pem -config=../ca/ca-config.json -profile=kubernetes service-account-csr.json | cfssljson -bare service-account +``` + +结果如下: + +```bash +service-account.csr service-account-key.pem service-account.pem +``` + +## 生成 kube-controller-manager 组件证书 + +编写 kube-controller-manager 的 CSR 配置: + +```bash +{ + "CN": "system:kube-controller-manager", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "CN", + "L": "HangZhou", + "O": "system:kube-controller-manager", + "OU": "openEuler k8s kcm", + "ST": "BinJiang" + } + ] +} +``` + +生成证书: + +```bash +$ cfssl gencert -ca=../ca/ca.pem -ca-key=../ca/ca-key.pem -config=../ca/ca-config.json -profile=kubernetes kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager +``` + +结果如下: + +```bash +kube-controller-manager.csr kube-controller-manager-key.pem kube-controller-manager.pem +``` + +## 生成 kube-proxy 证书 + +编写 kube-proxy 的 CSR 配置: + +```bash +{ + "CN": "system:kube-proxy", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "CN", + "L": "HangZhou", + "O": "system:node-proxier", + "OU": "openEuler k8s kube proxy", + "ST": "BinJiang" + } + ] +} +``` + +生成证书: + +```bash +$ cfssl gencert -ca=../ca/ca.pem -ca-key=../ca/ca-key.pem -config=../ca/ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy +``` + +结果如下: + +```bash +kube-proxy.csr kube-proxy-key.pem kube-proxy.pem +``` + +## 生成 kube-scheduler 证书 + +编写 kube-scheduler 的 CSR 配置: + +```bash +{ + "CN": "system:kube-scheduler", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "CN", + "L": "HangZhou", + "O": "system:kube-scheduler", + "OU": "openEuler k8s kube scheduler", + "ST": "BinJiang" + } + ] +} +``` + +生成证书: + +```bash +$ cfssl gencert -ca=../ca/ca.pem -ca-key=../ca/ca-key.pem -config=../ca/ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler +``` + +结果如下: + +```bash +kube-scheduler.csr kube-scheduler-key.pem kube-scheduler.pem +``` + +## 生成 kubelet 证书 + +由于证书涉及到 kubelet 所在机器的 hostname 和 IP 地址信息,因此每个 node 节点配置不尽相同,所以编写脚本完成,生成脚本如下: + +```bash +$ cat node_csr_gen.bash + +#!/bin/bash + +nodes=(k8snode1 k8snode2 k8snode3) +IPs=("192.168.122.157" "192.168.122.158" "192.168.122.159") + +for i in "${!nodes[@]}"; do + +cat > "${nodes[$i]}-csr.json" < ![](./figures/public_sys-resources/icon-note.gif) **说明:** +> gitlab相关的yaml文件可从官网获得。 + +以下为yaml文件的示例参考,请根据实际情况进行修改。 + +gitlab-redis.yaml: + +```bash +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redis + namespace: default + labels: + name: redis +spec: + selector: + matchLabels: + name: redis + template: + metadata: + name: redis + labels: + name: redis + spec: + containers: + - name: redis + image: 10.35.111.11:5000/redis:latest + imagePullPolicy: IfNotPresent + ports: + - name: redis + containerPort: 6379 + volumeMounts: + - mountPath: /var/lib/redis + name: data + livenessProbe: + exec: + command: + - redis-cli + - ping + initialDelaySeconds: 30 + timeoutSeconds: 5 + readinessProbe: + exec: + command: + - redis-cli + - ping + initialDelaySeconds: 5 + timeoutSeconds: 1 + volumes: + - name: data + emptyDir: {} + +--- +apiVersion: v1 +kind: Service +metadata: + name: redis + namespace: default + labels: + name: redis +spec: + ports: + - name: redis + port: 6379 + targetPort: redis + selector: + name: redis + +``` + +gitlab-postgresql.yaml: + +```bash +apiVersion: apps/v1 +kind: Deployment +metadata: + name: postgresql + namespace: default + labels: + name: postgresql +spec: + selector: + matchLabels: + name: postgresql + template: + metadata: + name: postgresql + labels: + name: postgresql + spec: + containers: + - name: postgresql + image: 10.35.111.11:5000/postgres:13.6 + imagePullPolicy: IfNotPresent + env: + - name: POSTGRES_HOST_AUTH_METHOD + value: trust + - name: DB_USER + value: gitlab + - name: DB_PASS + value: passw0rd + - name: DB_NAME + value: gitlab_production + - name: DB_EXTENSION + value: pg_trgm + ports: + - name: postgres + containerPort: 5432 + volumeMounts: + - mountPath: /var/lib/postgresql + name: data + livenessProbe: + exec: + command: + - pg_isready + - -h + - localhost + - -U + - postgres + initialDelaySeconds: 30 + timeoutSeconds: 5 + readinessProbe: + exec: + command: + - pg_isready + - -h + - localhost + - -U + - postgres + initialDelaySeconds: 5 + timeoutSeconds: 1 + volumes: + - name: data + emptyDir: {} + +--- +apiVersion: v1 +kind: Service +metadata: + name: postgresql + namespace: default + labels: + name: postgresql +spec: + ports: + - name: postgres + port: 5432 + targetPort: postgres + selector: + name: postgresql + +``` + +gitlab.yaml: + +```bash +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gitlab + namespace: default + labels: + name: gitlab +spec: + selector: + matchLabels: + name: gitlab + template: + metadata: + name: gitlab + labels: + name: gitlab + spec: + containers: + - name: gitlab + image: 10.35.111.11:5000/yrzr/gitlab-ce-arm64v8:14.3.2-ce.0 + imagePullPolicy: IfNotPresent + env: + - name: TZ + value: Asia/Shanghai + - name: GITLAB_TIMEZONE + value: Beijing + - name: GITLAB_SECRETS_DB_KEY_BASE + value: long-and-random-alpha-numeric-string + - name: GITLAB_SECRETS_SECRET_KEY_BASE + value: long-and-random-alpha-numeric-string + - name: GITLAB_SECRETS_OTP_KEY_BASE + value: long-and-random-alpha-numeric-string + - name: GITLAB_ROOT_PASSWORD + value: admin321 + - name: GITLAB_ROOT_EMAIL + value: 517554016@qq.com + - name: GITLAB_HOST + value: git.qikqiak.com + - name: GITLAB_PORT + value: "80" + - name: GITLAB_SSH_PORT + value: "22" + - name: GITLAB_NOTIFY_ON_BROKEN_BUILDS + value: "true" + - name: GITLAB_NOTIFY_PUSHER + value: "false" + - name: GITLAB_BACKUP_SCHEDULE + value: daily + - name: GITLAB_BACKUP_TIME + value: 01:00 + - name: DB_TYPE + value: postgres + - name: DB_HOST + value: postgresql + - name: DB_PORT + value: "5432" + - name: DB_USER + value: gitlab + - name: DB_PASS + value: passw0rd + - name: DB_NAME + value: gitlab_production + - name: REDIS_HOST + value: redis + - name: REDIS_PORT + value: "6379" + ports: + - name: http + containerPort: 80 + - name: ssh + containerPort: 22 + volumeMounts: + - mountPath: /home/git/data + name: data + livenessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 180 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + timeoutSeconds: 1 + volumes: + - name: data + emptyDir: {} + +--- +apiVersion: v1 +kind: Service +metadata: + name: gitlab + namespace: default + labels: + name: gitlab +spec: + ports: + - name: http + port: 80 + targetPort: http + nodePort: 30852 + - name: ssh + port: 22 + nodePort: 32353 + targetPort: ssh + selector: + name: gitlab + type: NodePort +``` + +启动相应的容器: + +```bash +# kubectl apply -f gitlab-redis.yaml +# kubectl apply -f gitlab-postgresql.yaml +# kubectl apply -f gitlab.yaml +``` + +可通过命令查看gitlab pod是否搭建完成: + +```bash +# kubectl get pod -A -owide +``` + +## 登录gitlab + +查看是否可以登录gitlab网页,网址为ip地址加设定的端口。 + +![网页入口](figures/4.gitlab网页入口.jpg) +用户名为root,默认密码需进入容器后查看密码文件。 + +```bash +# kubectl exec -it gitlab-lab -n default /bin/sh +# cat /etc/gitlab/initial_root_password +``` + +![查询密码](figures/5.查询密码.jpg) + +- 登录后界面如图: + +![登录后页面](figures/6.登录后页面.png) diff --git a/docs/en/25.03/Cloud/ClusterDeployment/iSulad+k8s/gitlab-runner-deploy.md b/docs/en/25.03/Cloud/ClusterDeployment/iSulad+k8s/gitlab-runner-deploy.md new file mode 100644 index 0000000000000000000000000000000000000000..3e8e0a09fe495b21d89ca3e734bf1d34d71a4c0f --- /dev/null +++ b/docs/en/25.03/Cloud/ClusterDeployment/iSulad+k8s/gitlab-runner-deploy.md @@ -0,0 +1,195 @@ +# gitlab runner部署及测试 + +## 镜像/软件信息 + +安装过程中需要用到的镜像名称如下表,版本号为示例安装时用到的版本,仅供参考。 + +| 镜像 | 版本 | +|------------------------------------|----------| +| gitlab/gitlab-runner | alpine-v14.4.0 | +| gitlab/gitlab-runner-helper | x86_64-54944146 | + +如果在无外网环境中搭建,可以从下方链接提前下载对应的镜像。镜像下载地址:dockerhub官网 + +## 使用gitlab-runner.yaml启动runner容器 + +配置gitlab-runner.yaml文件,修改文件中的镜像名,以下为yaml文件的示例参考,请根据实际搭建进行修改。 + +```bash +vim gitlab-runner.yaml +``` + +```conf +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gitlab-runner + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + name: gitlab-runner + template: + metadata: + labels: + name: gitlab-runner + spec: + containers: + - args: + - run + image: gitlab/gitlab-runner:alpine-v14.4.0 + imagePullPolicy: IfNotPresent + name: gitlab-runner + volumeMounts: + - mountPath: /etc/gitlab-runner + name: config + readOnly: false + - mountPath: /etc/ssl/certs + name: cacerts + readOnly: true + restartPolicy: Always + volumes: + - hostPath: + path: /etc/gitlab-runner + name: config + - hostPath: + path: /etc/ssl/key + name: cacerts + +``` + +启动容器: + +```bash +# kubectl apply -f gitlab-runner.yaml +# kubectl get pod -A -o wide +``` + +![镜像](figures/7.镜像.png) + +## 登录gitlab容器网页-用户证书认证 + +1. 新建项目。 + + ![新建项目](figures/8.新建项目.png) + +2. 创建空白项目。 + + ![创建空白项目](figures/9.创建空白项目.png) + +3. 自定义项目名称。 + + ![自定义项目名称](figures/10.自定义项目名称.jpg) + +4. 设置--CI/CD--Runner--展开。 + + ![设置-cicd-runner](figures/11.设置-cicd-runner.png) + +5. 记录注册Runner的地址和令牌。 + + ![记下runner地址与令牌](figures/12.记下runner地址与令牌.jpg) + +6. 导入证书文件。 + + 在master节点上查看并生成证书文件,共三个文件admin.crt、admin.key、ca.crt。 + + - 查看证书信息 + + ```bash + # cat /etc/kubernetes/admin.conf + ``` + + ![查看证书配置文件](figures/13.查看证书配置文件.png) + + - 加密生成admin.crt + + ```bash + # echo “${client-certificate-data}” | base64 -d > admin.crt + ``` + + - 加密生成admin.key + + ```bash + # echo “${client-key-data}” | base64 -d > admin.key + ``` + + - 在manager节点上获取ca的证书 + + ```bash + # cp /etc/kubernetes/pki/ca.crt ./ + ``` + +7. 在runner运行的节点处将三个证书文件导入gitlab-runner容器。 + + > ![](./figures/public_sys-resources/icon-note.gif) **说明:** + > + > 导入容器需查看gitlab-runner运行在哪个节点上,将三个证书文件拷贝至该节点,然后使用isula cp命令导入。 + + ```bash + # isula cp admin.crt [容器id]:存放位置 + # isula cp admin.key [容器id]:存放位置 + # isula cp ca.crt [容器id]:存放位置 + ``` + + 注:isula cp 命令只能一次拷贝一个文件 + + ![证书导入文件](figures/14.证书导入文件.png) + +## 注册gitlab-runner + +进入到runner的容器内进行注册;目前采用交互式注册,注册信息在gitlab上获得,当前配置的 runner服务于项目组,此信息的界面在gitlab-\>项目组(group)-\>设置-\>CI/CD-\>runner中查看。 + +![注册gitlab-runner](figures/15.注册gitlab-runner.jpg) + +![web端已加入](figures/16.web端已加入_LI.jpg) + +将准备好的gitlab-runner-helper镜像提前上传至私有镜像仓,进入gitlab-runner容器中,修改配置文件。 + +```bash +# cd /etc/gitlab-runner +# mkdir kubessl +# cp /home/admin.crt /etc/gitlab-runner/kubessl +# cp /home/ca.crt /etc/gitlab-runner/kubessl +# cp /home/admin.key /etc/gitlab-runner/kubessl +# vim /etc/gitlab-runner/config.toml +``` + +![](figures/17.png) + +## 在manager节点进行如下操作添加gitlab容器的dns记录 + +1. 查看gitlab容器的ip地址。 + + ```bash + # kubectl get pods –Aowide + ``` + +2. 添加gitlabip地址到k8s dns配置文件。 + + ```bash + # kubectl edit configmaps coredns -n kube-system + ``` + + ![dns](figures/18.dns配置.png) + +3. 重启coredns服务。 + + ```bash + # kubectl scale deployment coredns -n kube-system --replicas=0 + # kubectl scale deployment coredns -n kube-system --replicas=2 + ``` + +## gitlab运行测试 + +返回gitlab的web界面,选择CI/CD--编辑器--创建CI/CD流水线。 + +![CICD界面](figures/19.CICD界面.png) + +- 编译yaml文件如下: + +![yaml文件](figures/20.yaml文件.png) + +- 流水线-查看状态。 + +![流水线状态](figures/21.流水线状态.png) diff --git a/docs/en/25.03/Cloud/ClusterDeployment/iSulad+k8s/iSulad+k8s-environment-deploy.md b/docs/en/25.03/Cloud/ClusterDeployment/iSulad+k8s/iSulad+k8s-environment-deploy.md new file mode 100644 index 0000000000000000000000000000000000000000..2e6a63dc41cb14cb00260623bd7aea7ed6841fcc --- /dev/null +++ b/docs/en/25.03/Cloud/ClusterDeployment/iSulad+k8s/iSulad+k8s-environment-deploy.md @@ -0,0 +1,390 @@ +# iSulad+k8s环境部署 + +## 准备集群服务器 + +需准备至少3台openEuler机器,建议在openEuler-22.03及以上版本运行。下表为示例搭建机器信息,仅供参考。 + +| 主机名 | IP | 系统版本 | 角色 | 组件 | +|-------|-------------|------------------------|----------|-----------| +| lab1 | 197.xxx.xxx.xxx | openEuler 22.03 LTS SP4 | 控制节点 | iSulad/k8s | +| lab2 | 197.xxx.xxx.xxx | openEuler 22.03 LTS SP4 | 工作节点1 | iSulad/k8s | +| lab3 | 197.xxx.xxx.xxx | openEuler 22.03 LTS SP4 | 工作节点2 | iSulad/k8s | + +## 镜像/软件信息 + +安装过程中需要用到的软件及镜像名称如下表,版本号为示例安装时用到的版本,仅供参考。 + +| 软件 | 版本 | +|------------------------------------|----------| +| iSulad | 2.0.17-2 | +| kubernetes-client | 1.20.2-9 | +| kubernetes-kubeadm | 1.20.2-9 | +| kubernetes-kubelet | 1.20.2-9 | + +| 镜像 | 版本 | +|------------------------------------|----------| +| k8s.gcr.io/kube-proxy | v1.20.2 | +| k8s.gcr.io/kube-apiserver | v1.20.2 | +| k8s.gcr.io/kube-controller-manager | v1.20.2 | +| k8s.gcr.io/kube-scheduler | v1.20.2 | +| k8s.gcr.io/etcd | 3.4.13-0 | +| k8s.gcr.io/coredns | 1.7.0 | +| k8s.gcr.io/pause | 3.2 | +| calico/node | v3.14.2 | +| calico/pod2daemon-flexvol | v3.14.2 | +| calico/cni | v3.14.2 | +| calico/kube-controllers | v3.14.2 | + +如果在无外网环境中搭建,可以从以下链接提前下载对应的软件包、相关依赖软件包及镜像: + +1. 软件包下载地址:[https://repo.openeuler.org/openEuler-22.03-LTS-SP4/](https://repo.openeuler.org/openEuler-22.03-LTS-SP4/) +2. 镜像下载地址:[https://developer.aliyun.com/mirror/](https://developer.aliyun.com/mirror/) + +## 修改host文件 + +1. 修改主机名,以其中一台机器为例。 + + ```shell + # hostnamectl set-hostname lab1 + # sudo -i + ``` + +2. 配置主机名解析,编辑三台服务器的/etc/hosts文件。 + + ```shell + # vim /etc/hosts + ``` + +3. 在hosts文件中添加以下内容(IP+主机名)。 + + ```text + 197.xxx.xxx.xxx lab1 + 197.xxx.xxx.xxx lab2 + 197.xxx.xxx.xxx lab3 + ``` + +## 环境准备 + +1. 关闭防火墙。 + + ```shell + # systemctl stop firewalld + # systemctl disable firewalld + ``` + +2. 禁用selinux。 + + ```shell + # setenforce 0 + ``` + +3. 关闭系统swap。 + + ```shell + # swapoff -a + # sed -ri 's/.*swap.*/#&/' /etc/fstab + ``` + +4. 网络配置,开启相应的转发机制。 + + ```shell + # cat > /etc/sysctl.d/kubernetes.conf < ![](./figures/public_sys-resources/icon-note.gif) **说明:** + > + > 以下所下载的镜像版本均为示例,具体版本号以上条命令返回结果为准,下同。 + + ```shell + # isula pull k8smx/kube-apiserver:v1.20.15 + # isula pull k8smx/kube-controller-manager:v1.20.15 + # isula pull k8smx/kube-scheduler:v1.20.15 + # isula pull k8smx/kube-proxy:v1.20.15 + # isula pull k8smx/pause:3.2 + # isula pull k8smx/coredns:1.7.0 + # isula pull k8smx/etcd:3.4.13-0 + ``` + +3. 修改已下载的镜像标签。 + + ```shell + # isula tag k8smx/kube-apiserver:v1.20.15 k8s.gcr.io/kube-apiserver:v1.20.15 + # isula tag k8smx/kube-controller-manager:v1.20.15 k8s.gcr.io/kube-controller-manager:v1.20.15 + # isula tag k8smx/kube-scheduler:v1.20.15 k8s.gcr.io/kube-scheduler:v1.20.15 + # isula tag k8smx/kube-proxy:v1.20.15 k8s.gcr.io/kube-proxy:v1.20.15 + # isula tag k8smx/pause:3.2 k8s.gcr.io/pause:3.2 + # isula tag k8smx/coredns:1.7.0 k8s.gcr.io/coredns:1.7.0 + # isula tag k8smx/etcd:3.4.13-0 k8s.gcr.io/etcd:3.4.13-0 + ``` + +4. 删除旧镜像。 + + ```shell + # isula rmi k8smx/kube-apiserver:v1.20.15 + # isula rmi k8smx/kube-controller-manager:v1.20.15 + # isula rmi k8smx/kube-scheduler:v1.20.15 + # isula rmi k8smx/kube-proxy:v1.20.15 + # isula rmi k8smx/pause:3.2 + # isula rmi k8smx/coredns:1.7.0 + # isula rmi k8smx/etcd:3.4.13-0 + ``` + +5. 查看已拉取的镜像。 + + ```shell + # isula images + ``` + +## 安装crictl工具 + +```shell +# yum install -y cri-tools +``` + +## 初始化master节点 + +执行如下命令初始化master节点: + +```shell +# kubeadm init --kubernetes-version v1.20.2 --cri-socket=/var/run/isulad.sock --pod-network-cidr=[指定pod分配IP段] + +//以上参数的解释 +kubernetes-version 为当前安装的版本 +cri-socket 指定引擎为isulad +pod-network-cidr 指定pod分配的ip段 +``` + +根据系统提示输入如下命令: + +```shell +# mkdir -p $HOME/.kube +# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config +# sudo chown $(id -u):$(id -g) $HOME/.kube/config +``` + +初始化成功后,复制最后两行内容,在node节点上执行刚刚复制的命令,将节点加入master集群,如未记录上述命令可通过如下命令生成: + +```shell +# kubeadm token create --print-join-command +``` + +## node节点添加进集群 + +粘贴master上初始化生成的kubeadm join ...命令,并在discovery前添加--cri-socket=/var/run/isulad.sock,执行如下命令: + +```shell +# kubeadm join [IP地址] --token bgyis4.euwkjqb7jwuenwvs --cri-socket=/var/run/isulad.sock --discovery-token-ca-cert-hash sha256:3792f02e136042e2091b245ac71c1b9cdcb97990311f9300e91e1c339e1dfcf6 +``` + +## 安装calico网络插件 + +1. 拉取calico镜像。 + + 需要在master节点配置calico网络插件,同时需要在每个节点中提前拉取需要版本的镜像。 + + ```shell + isula pull calico/node:v3.14.2 + isula pull calico/cni:v3.14.2 + isula pull calico/kube-controllers:v3.14.2 + isula pull calico/pod2daemon-flexvol:v3.14.2 + ``` + +2. 在master节点上获取配置文件。 + + ```shell + wget https://docs.projectcalico.org/v3.14/manifests/calico.yaml + ``` + +3. 修改后创建pod。 + + ```shell + # kubectl apply -f calico.yaml + ``` + + - 如需删除使用如下命令: + + ```shell + # kubectl delete -f calico.yaml + ``` + +4. 查看pod信息。 + + ```shell + # kubectl get pod -A -o wide + ``` + +## 查看master节点node信息 + +使用如下命令可查看节点的详细信息: + +```shell +# kubectl get nodes -o wide +``` + +若需要重置node节点,可使用如下命令: + +```shell +# kubeadm reset +``` diff --git a/docs/en/25.03/Cloud/ClusterDeployment/iSulad+k8s/overview.md b/docs/en/25.03/Cloud/ClusterDeployment/iSulad+k8s/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..cf530d4d57bffb09b457fe3ccfdacbee33b82347 --- /dev/null +++ b/docs/en/25.03/Cloud/ClusterDeployment/iSulad+k8s/overview.md @@ -0,0 +1,23 @@ +# iSulad+k8s集群部署指南 + +本文档介绍在 openEuler 操作系统上,通过 kubeadm 部署 K8S 集群,搭建 K8S+iSulad 的环境,并在该环境上部署 gitlab-runner,指导部署欧拉原生开发环境集群。 + +本文档主要包括以下两个场景内容: + +场景一: 基于 gitlab-ci 从 “0” 开始构建欧拉原生开发CICD部署指导。 +场景二: 欧拉原生开发执行机集群被 gitlab-ci 纳管指导。 + +场景一中需要额外部署gitlab,步骤操作顺序为: + +1. K8s+iSulad 环境部署。 +2. gitlab 部署。 +3. gitlab runner 部署和测试。 + +场景二中已有 gitlab-ci 平台,无需额外部署,步骤操作顺序为: + +1. K8s+iSulad 环境部署。 +2. gitlab runner 部署和测试。 + +> ![](./figures/public_sys-resources/icon-note.gif) **说明:** +> +> 本文档所有操作均使用root权限执行。 diff --git a/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/_menu.md b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..1e1c79b83d470f150486847e3c64de53fc34a721 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/_menu.md @@ -0,0 +1,27 @@ +--- +label: 'Docker容器' +ismanual: 'Y' +description: 'Docker是一个开源的容器引擎项目,用以实现应用的快速打包、部署和交付' +children: + - label: '概述' + href: './overview.md' + - label: '安装配置' + href: './installation-and-configuration-3.md' + - label: '容器管理' + href: './container-management-1.md' + - label: '镜像管理' + href: './image-management-1.md' + - label: '命令行参考' + href: './command-reference.md' + children: + - label: '容器引擎' + href: './container-engine.md' + - label: '容器管理' + href: './container-management-2.md' + - label: '镜像管理' + href: './image-management-2.md' + - label: '统计信息' + href: './statistics.md' + - label: 'Docker常见问题与解决方法' + href: './docker-faqs.md' +--- \ No newline at end of file diff --git a/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/command-reference.md b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/command-reference.md new file mode 100644 index 0000000000000000000000000000000000000000..35483fad78e18adb17749e55558fa74c0759769c --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/command-reference.md @@ -0,0 +1,3 @@ +# 命令行参考 + +本章介绍 Docker 容器相关的命令行。 diff --git a/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/container-engine.md b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/container-engine.md new file mode 100644 index 0000000000000000000000000000000000000000..f8d6b20b702295dfdea39b1750c6fab5bb38a9f3 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/container-engine.md @@ -0,0 +1,302 @@ +# 容器引擎 + +Docker daemon是一个常驻后台的系统进程,docker 子命令执行前先要启动docker daemon。 + +如果是通过rpm包或者系统包管理工具安装的,就可以使用systemctl start docker来启动docker daemon。 + +docker命令支持多个参数选项,对于参数选项有以下约定: + +1. 单个字符的选项可以合并在一起,如: + + ```bash + docker run -t -i busybox /bin/sh + ``` + + 可以写成 + + ```bash + docker run -ti busybox /bin/sh + ``` + +2. 在命令帮助中看到的如\--icc=true之类的bool命令选项,如果没有使用这个选项,则这个标志位的值就是在命令帮助中看到的缺省值,如果使用了这个选项则这个标志位的值就是命令帮助中看的值的相反值,如果启动docker daemon没有加上使用\--icc选项,则默认设置了\--icc=true,如果使用了\--icc选项则表示是\--icc=false。 +3. 在命令帮助中看到的\--attach=\[\]之类的选项,表示这类的选项可以多次设置,如: + + ```bash + docker run --attach=stdin --attach=stdout -i -t busybox /bin/sh + ``` + +4. 在命令帮助中看到的-a, \--attach=\[\]之类的选项,表示这种选项既可以用-a value指定也可以用\--attach=value指定。如: + + ```bash + docker run -a stdin --attach=stdout -i -t busybox /bin/sh + ``` + +5. \--name=””之类的选项需要的是一个字符串,只能指定一次,-c=0之类的选项需要的是一个整数,只能指定一次。 + +**表 1** docker daemon启动时指定参数详解 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数名称

+

说明

+

--api-cors-header

+

开放远程API调用的 CORS 头信息。这个接口开关对想进行二次开发的上层应用提供了支持。为remote API设置CORS头信息。

+

--authorization-plugin=[]

+

指定认证插件。

+

-b, --bridge=""

+

挂载已经存在的网桥设备到 Docker 容器里。注意,使用 none 可以停用容器里的网络。

+

--bip=""

+

使用 CIDR 地址来设定自动创建的网桥的 IP。注意,此参数和 -b 不能一起使用。

+

--cgroup-parent

+

为所有容器设定cgroup父目录。

+

--config-file=/etc/docker/daemon.json

+

启动docker daemon的配置文件。

+

--containerd

+

指定containerd的socket路径。

+

-D, --debug=false

+

开启Debug模式。

+

--default-gateway

+

容器IPv4地址的默认网关。

+

--default-gateway-v6

+

容器IPv6地址的默认网关。

+

--default-ulimit=[]

+

容器的默认ulimit值。

+

--disable-legacy-registry

+

不允许使用原版registry。

+

--dns=[]

+

强制容器使用DNS服务器。

+

例如: --dns 8.8.x.x

+

--dns-opt=[]

+

指定使用DNS的选项。

+

--dns-search=[]

+

强制容器使用指定的DNS搜索域名。

+

例如: --dns-search example.com

+

--exec-opt=[]

+

设置运行时执行选项。

+

例如支持native.umask选项:

+
# 启动的容器umask值为0022 --exec-opt native.umask=normal # 启动的容器umask值为0027(缺省值)--exec-opt  native.umask=secure
+

注意如果docker create/run也配置了native.umask参数则以docker create/run中的配置为准。

+

--exec-root=/var/run/docker

+

指定执行状态文件存放的根目录。

+

--fixed-cidr=""

+

设定子网固定IP(ex: 10.20.0.0/16),这个子网IP必须属于网桥内的。

+

--fixed-cidr-v6

+

同上,使用与IPv6。

+

-G, --group="docker"

+

在后台运行模式下,赋予指定的Group到相应的unix socket上。注意,当此参数 --group 赋予空字符串时,将去除组信息。

+

-g, --graph="/var/lib/docker"

+

配置Docker运行时根目录。

+

-H, --host=[]

+

在后台模式下指定socket绑定,可以绑定一个或多个 tcp://host:port, unix:///path/to/socket, fd://* 或 fd://socketfd。例如:

+

$ dockerd -H tcp://0.0.0.0:2375

+

或者

+

$ export DOCKER_HOST="tcp://0.0.0.0:2375"

+

--insecure-registry=[]

+

指定非安全连接的仓库,docker默认所有的连接都是TLS证书来保证安全的,如果仓库不支持https连接或者证书是docker daemon不清楚的证书颁发机构颁发的,则启动daemon的时候要指定如--insecure-registry=192.168.1.110:5000,使用私有仓库都要指定。

+

--image-layer-check=true

+

开启镜像层完整性检查功能,设置为true;关闭该功能,设置为false。如果没有该参数,默认为关闭。

+

docker启动时会检查镜像层的完整性,如果镜像层被破坏,则相关的镜像不可用。docker进行镜像完整性校验时,无法校验内容为空的文件和目录,以及链接文件。因此若镜像因掉电导致上述类型文件丢失,docker的镜像数据完整性校验可能无法识别。docker版本变更时需要检查是否支持该参数,如果不支持,需要从配置文件中删除。

+

--icc=true

+

启用容器间的通信。

+

--ip="0.0.0.0"

+

容器绑定端口时使用的默认IP地址。

+

--ip-forward=true

+

启动容器的 net.ipv4.ip_forward。

+

--ip-masq=true

+

使能IP伪装。

+

--iptables=true

+

启动Docker容器自定义的iptable规则。

+

-l, --log-level=info

+

设置日志级别。

+

--label=[]

+

设置daemon标签,以key=value形式设置。

+

--log-driver=json-file

+

设置容器日志的默认日志驱动。

+

--log-opt=map[]

+

设置日志驱动参数。

+

--mtu=0

+

设置容器网络的MTU值,如果没有这个参数,选用默认 route MTU,如果没有默认route,就设置成常量值 1500。

+

-p, --pidfile="/var/run/docker.pid"

+

后台进程PID文件路径。

+

--raw-logs

+

带有全部时间戳并不带ANSI颜色方案的日志。

+

--registry-mirror=[]

+

指定dockerd优先使用的镜像仓库。

+

-s, --storage-driver=""

+

强制容器运行时使用指定的存储驱动

+

--selinux-enabled=false

+

启用selinux支持,3.10.0-862.14及以上内核版本不支持--selinux-enabled=true。

+

--storage-opt=[]

+

配置存储驱动的参数,存储驱动为devicemapper的时候有效(e.g. dockerd --storage-opt dm.blocksize=512K)。

+

--tls=false

+

启动TLS认证开关。

+

--tlscacert="/root/.docker/ca.pem"

+

通过CA认证过的certificate文件路径。

+

--tlscert="/root/.docker/cert.pem"

+

TLS的certificate文件路径。

+

--tlskey="/root/.docker/key.pem"

+

TLS的key文件路径。

+

--tlsverify=false

+

使用TLS并做后台进程与客户端通讯的验证。

+

--insecure-skip-verify-enforce

+

是否强制跳过证书的主机名/域名验证,默认为false(不跳过)。

+

--use-decrypted-key=true

+

指定使用解密私钥。

+

--userland-proxy=true

+

容器LO设备使用userland proxy。

+

--userns-remap

+

容器内使用user命名空间的用户映射表。

+
说明:

当前版本不支持该参数。

+
+
diff --git a/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/container-management-1.md b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/container-management-1.md new file mode 100644 index 0000000000000000000000000000000000000000..ac4c9f3cd18d9d0b6aacee21602af946e56202bd --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/container-management-1.md @@ -0,0 +1,706 @@ +# 容器管理 + +- [容器管理](#容器管理) + - [创建容器](#创建容器) + - [创建容器使用hook-spec](#创建容器使用hook-spec) + - [创建容器配置健康检查](#创建容器配置健康检查) + - [停止与删除容器](#停止与删除容器) + - [容器信息查询](#容器信息查询) + - [修改操作](#修改操作) + +## 创建容器 + +### 下载镜像 + +运行docker命令需要root权限,当你使用普通用户登录时,需要用sudo权限执行docker命令。 + +```bash +[root@localhost ~]# docker pull busybox +``` + +该命令行将在docker官方的镜像库中下载busybox:latest(命令行中没指定TAG,所以使用默认的TAG名latest),镜像在下载过程中将检测所依赖的层本地是否存在,如果存在就跳过。从私有镜像库下载镜像时,请带上registry描述,例如:假如建立了一个私有镜像库,地址为192.168.1.110:5000,里面有一些常用镜像。使用下面命令行从私有镜像库中下载镜像。 + +```bash +[root@localhost ~]# docker pull 192.168.1.110:5000/busybox +``` + +从私有镜像库中下载下来的image名字带有镜像库地址的信息名字比较长,可以用docker tag命令生成一个名字简单点的image。 + +```bash +[root@localhost ~]# docker tag 192.168.1.110:5000/busybox busybox +``` + +可以通过docker images命令查看本地镜像列表。 + +### 运行一个简单的应用 + +```bash +[root@localhost ~]# docker run busybox /bin/echo "Hello world" +Hello world +``` + +该命令行使用busybox:latest(命令行中没有指定tag,所以使用默认的tag名latest)镜像创建了一个容器,在容器内执行了echo "Hello world"。使用下面命令行可以查看刚才创建的这个容器。 + +```bash +[root@localhost ~]# docker ps -l +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +d8c0a3315bc0 busybox "/bin/echo 'Hello wo…" 5 seconds ago Exited (0) 3 seconds ago practical_franklin +``` + +### 创建一个交互式的容器 + +```bash +[root@localhost ~]# docker run -it busybox /bin/bash +root@bf22919af2cf:/# ls +bin boot dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var +root@bf22919af2cf:/# pwd +/ +``` + +-ti选项分配一个伪终端给容器并可以使用STDIN进行交互,可以看到这时可以在容器内执行一些命令。这时的容器看起来完全是一个独立的linux虚拟机。使用exit命令退出容器。 + +### 后台运行容器 + +执行下面命令行,-d指示这个容器在后台运行,\--name=container1 指定容器的名字为container1。 + +```bash +[root@localhost ~]# docker run -d --name=container1 busybox /bin/sh -c "while true;do echo hello world;sleep 1;done" +7804d3e16d69b41aac5f9bf20d5f263e2da081b1de50044105b1e3f536b6db1c +``` + +命令行的执行结果是返回了这个容器的ID,没有返回命令的执行结果hello world,此时容器在后台运行,可以用docker ps命令查看正在运行的容器: + +```bash +[root@localhost ~]# docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +7804d3e16d69 busybox "/bin/sh -c 'while tr" 11 seconds ago Up 10 seconds container1 +``` + +用docker logs查看容器运行的输出: + +```bash +[root@localhost ~]# docker logs container1 +hello world +hello world +hello world +... +``` + +### 容器网络连接 + +默认情况下,容器可以访问外部网络,而外部网络访问容器时需要通过端口映射,下面以在docker中运行私有镜像库服务registry为例。下面的命令行中-P使registry镜像中开放的端口暴露给主机。 + +```bash +[root@localhost ~]# docker run --name=container_registry -d -P registry +cb883f6216c2b08a8c439b3957fb396c847a99079448ca741cc90724de4e4731 +``` + +container\_registry这个容器已经启动了,但是并不知道容器中的服务映射到主机的哪个端口,通过docker port查看端口映射。 + +```bash +[root@localhost ~]# docker port container_registry +5000/tcp -> 0.0.0.0:49155 +``` + +从输出可以看出,容器内的5000端口映射到了主机的49155端口。通过主机IP:49155就可以访问registry服务了,在浏览器中输入就可以返回registry的版本信息。 + +在运行registry镜像的时候还可以直接指定端口映射如: + +```bash +docker run --name=container_registry -d -p 5000:5000 registry +``` + +通过-p 5000:5000指定容器的5000端口映射到主机的5000端口。 + +### 注意事项 + +- **启动容器不能单独加-a stdin** + + 启动容器时,不能单独加-a stdin,必须要同时加上-a stdout或者-a stderr,否则会导致终端即使在容器退出后也会卡住。 + +- **避免使用已有容器的长id、短id作为新容器的name** + + 创建容器时,避免使用已有容器A的长id或短id作为新容器B的name。若使用容器A的长id作为容器B的name,当使用容器B的name作为指定容器进行操作时,docker匹配到的是容器A。若使用容器A的短id作为容器B的name,当使用容器A的短id作为指定容器进行相关操作时,docker匹配到的是容器B。这是因为,docker在匹配容器时,先精确匹配所有容器的长id。若未匹配成功,再根据container\_name进行精确匹配;若还未匹配成功,直接对容器id进行模糊匹配。 + +- **使用sh/bash等依赖标准输入输出的容器应该使用\`-ti\`参数,避免出现异常** + + 正常情况:不用\`-ti\`参数启动sh/bash等进程容器,容器会马上退出。 + + 出现这种问题的原因在于,docker会先创建一个匹配用于容器内业务的stdin,在不设置-ti等交互式参数时,docker会在容器启动后关闭该pipe,而业务容器进程sh/bash在检测到stdin被关闭后会直接退出。 + + 异常情况:如果在上述过程中的特定阶段(关闭该pipe之前)强制杀死docker daemon,会导致该pipe的daemon端没有被及时关闭,这样即使不带\`-ti\`的sh/bash进程也不会退出,导致异常场景,这种容器就需要手动清理。 + + Daemon重启后会接管原有的容器stream,而不带\`-ti\`参数的容器可能就无法处理(因为正常情况下这些容器不存在stream需要接管);真实业务下几乎不存在这种使用方式\(不带 \`-ti\`的sh/bash没有任何作用\),为了避免这类问题发生,限制交互类容器应该使用 \`-ti\`参数。 + +- **容器存储卷** + + 启动容器时如果通过\`-v\`参数将主机上的文件挂载到容器中,在主机或容器中使用vi或sed命令修改文件可能会使文件inode发生改变,从而导致主机和容器内的文件不同步。容器中挂载文件时应该尽量避免使用这种文件挂载的方式(或不与vi和sed同时使用),也可以通过挂载文件上层目录来避免该问题。在docker挂载卷时“nocopy”选项可以避免将容器内挂载点目录下原有的文件拷贝到主机源目录下,但是这个选项只能在挂载匿名卷时使用,不能在bind mount的场景下使用。 + +- **避免使用可能会对host造成影响的选项** + + \--privileged 选项会让容器获得所有权限,容器可以做挂载操作和修改/proc、/sys等目录,可能会对host造成影响,普通容器需要避免使用该选项。 + + 共享host的namespace,比如\--pid host/\--ipc host/\--net host等选项可以让容器跟host共享命名空间,同样会导致容器影响host的结果,需要避免使用。 + +- **kernel memory cgroup不稳定,禁止使用** + + kernel memory cgroup在小于4.0版本的Linux内核上仍属于实验阶段,运行起来不稳定,虽然Docker的Warning说是小于4.0就可以,但是我们评估认为,kmemcg在高版本内核仍然不稳定,所以不管是低版本还是高版本,均禁止使用。 + + 当docker run \--kernel-memory时,会产生如下告警: + + ```text + WARNING: You specified a kernel memory limit on a kernel older than 4.0. Kernel memory limits are experimental on older kernels, it won't work as expected as expected and can cause your system to be unstable. + ``` + +- **blkio-weight参数在支持blkio精确控制的内核下不可用** + + \--blkio-weight-device 可以实现容器内更为精确的blkio控制,该控制需要指定磁盘设备,可以通过docker \--blkio-weight-device参数实现。同时在这种内核下docker不再提供\--blkio-weight方式限制容器blkio,使用该参数创建容器将会报错: + + ```text + docker: Error response from daemon: oci runtime error: container_linux.go:247: starting container process caused "process_linux.go:398: container init caused \"process_linux.go:369: setting cgroup config for ready process caused \\\"blkio.weight not supported, use weight_device instead\\\"\"" + ``` + +- **使用\--blkio-weight-device需要磁盘支持CFQ调度策略** + + \--blkio-weight-device参数需要磁盘工作于完全公平队列调度(CFQ:Completely Fair Queuing)的策略时才能工作。 + + 通过查看磁盘scheduler文件(‘/sys/block/\<磁盘>/queue/scheduler’)可以获知磁盘支持的策略以及当前所采用的策略,如查看sda: + + ```bash + # cat /sys/block/sda/queue/scheduler noop [deadline] cfq + ``` + + 当前sda支持三种调度策略:noop, deadline, cfq,并且正在使用deadline策略。通过echo修改策略为cfq: + + ```bash + # echo cfq > /sys/block/sda/queue/scheduler + ``` + +- **容器基础镜像中systemd使用限制** + + 通过基础镜像创建的容器在使用过程中,容器基础镜像中的systemd仅用于系统容器,普通容器不支持使用。 + +### 并发性能 + +- docker内部的消息缓冲有一个上限,超过这个上限就会将消息丢弃,因此在并发执行命令时建议不要超过1000条命令,否则有可能会造成docker内部消息丢失,从而造成容器无法启动等严重问题。 +- 并发创建容器并对容器执行restart时会偶现“oci runtime error: container init still running”报错,这是因为containerd对事件等待队列进行了性能优化,容器stop过程中执行runc delete,尝试在1s内kill掉容器的init进程,如果1s内init进程还没有被kill掉的话runc会返回该错误。由于containerd的GC(垃圾回收机制)每隔10s会回收之前runc delete的残留资源, 所以并不影响下次对容器的操作,一般出现上述报错的话等待4\~5s之后再次启动容器即可。 + +### 安全特性解读 + +1. docker默认的权能配置分析 + + 原生的docker默认配置如下,默认进程携带的Cap如下: + + ```conf + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID", + "CAP_FOWNER", + "CAP_MKNOD", + "CAP_NET_RAW", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETFCAP", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_KILL", + "CAP_AUDIT_WRITE", + ``` + + 默认的seccomp配置是白名单,不在白名单的syscall默认会返回SCMP\_ACT\_ERRNO,根据给docker不同的Cap开放不同的系统调用,不在上面的权限,默认docker都不会给到容器。 + +2. CAP\_SYS\_MODULE + + CAP\_SYS\_MODULE这个Cap是让容器可以插入或移除ko,增加该Cap可以让容器逃逸,甚至破坏内核。因为容器最大的隔离是Namespace,在ko中只要把他的Namespace指向init\_nsproxy即可。 + +3. CAP\_SYS\_ADMIN + + sys\_admin权限给容器带来的能力有: + + - 文件系统(mount,umount,quotactl) + - namespace设置相关的(setns,unshare,clone new namespace) + - driver ioctl + - 对pci的控制,pciconfig\_read, pciconfig\_write, pciconfig\_iobase + - sethostname + +4. CAP\_NET\_ADMIN + + 容器中有访问网络接口的和sniff网络流量的权限,容器可以获取到所有容器包括host的网络流量,对网络隔离破坏极大。 + +5. CAP\_DAC\_READ\_SEARCH + + 该权限开放了open\_by\_handle\_at和name\_to\_handle\_at两个系统调用,如果host上没有selinux保护,容器中可通过暴力搜索file\_handle结构的inode号,进而可以打开host上的任意文件,影响文件系统的隔离性。 + +6. CAP\_SYS\_RAWIO + + 容器中可对host写入io端口,可造成host内核崩溃。 + +7. CAP\_SYS\_PTRACE + + 容器中有ptrace权限,可对容器的进程进行ptrace调试。现runc已经修补该漏洞,但有些工具比如nsenter和docker-enter并没有改保护,容器中可对这些工具执行的进程进行调试,获取这些工具带入的资源信息(Namespace、fd等),另外, ptrace可以绕过seccomp,极大增加内核攻击面。 + +8. Docker Cap接口 \--cap-add all + + --cap-add all表示赋予容器所有的权能,包括本节提到的比较危险的权能,使得容器可以逃逸。 + +9. 不要禁用docker的seccomp特性 + + 默认的docker有一个seccomp的配置,配置中使用的是白名单,不在配置的sys\_call会被seccomp禁掉,使用接口--security-opt 'seccomp:unconfined'可以禁止使用seccomp特性。如果禁用seccomp或使用自定义seccomp配置但过滤名单不全,都会增加容器对内核的攻击面。 + +10. 不要配置/sys和/proc目录可写 + + /sys和/proc目录包含了linux维护内核参数、设备管理的接口,容器中配置该目录可写可能会导致容器逃逸。 + +11. Docker开放Cap \--CAP\_AUDIT\_CONTROL + + 容器可以通过控制系统audit系统,并且通过AUDIT\_TTY\_GET/AUDIT\_TTY\_SET等命令可以获取审计系统中记录的tty执行输入记录,包括root密码。 + +12. CAP\_BLOCK\_SUSPEND和CAP\_WAKE\_ALARM + + 容器可拥有阻塞系统挂起\(epoll\)的能力。 + +13. CAP\_IPC\_LOCK + + 容器拥有该权限后,可以突破ulimit中的max locked memory限制,任意mlock超大内存块,造成一定意义的DoS攻击。 + +14. CAP\_SYS\_LOG + + 容器拥有该权限后,可以dmesg读取系统内核日志,突破内核kaslr防护。 + +15. CAP\_SYS\_NICE + + 容器拥有该权限后,可以改变进程的调度策略和优先级,造成一定意义的DoS攻击。 + +16. CAP\_SYS\_RESOURCE + + 容器可以绕过对其的一些资源限制,比如磁盘空间资源限制、keymaps数量限制、pipe-size-max限制等,造成一定意义的DoS攻击。 + +17. CAP\_SYS\_TIME + + 容器可以改变host上的时间。 + +18. Docker默认Cap风险分析 + + Docker默认的Cap,包含了CAP\_SETUID和CAP\_FSETID,如host和容器共享目录,容器可对共享目录的二进制文件进行+s设置,host上的普通用户可使用其进行提权CAP\_AUDIT\_WRITE,容器可以对host写入,容器可以对host写入日志,host需配置日志防爆措施。 + +19. Docker和host共享namespace参数,比如 \--pid,\--ipc, \--uts + + 该参数为容器和host共享namespace空间,容器和host的namespace隔离没有了,容器可对host进行攻击。比如,使用\--pid 和host共享pid namespace,容器中可以看到host上的进程pid号,可以随意杀死host的进程。 + +20. \--device 把host的敏感目录或者设备,映射到容器中 + + Docker管理面有接口可以把host上的目录或者设备映射到容器中,比如\--device,-v等参数,不要把host上的敏感目录或者设备映射到容器中。 + +## 创建容器使用hook-spec + +### 原理及使用场景 + +docker支持hook的扩展特性,hook应用与底层runc的执行过程中,遵循OCI标准:[https://github.com/opencontainers/runtime-spec/blob/main/config.md\#hooks](#https://github.com/opencontainers/runtime-spec/blob/main/config.md#hooks) 。 + +hook主要有三种类型:prestart,poststart,poststop。分别作用于容器内用户应用程序启动之前,容器应用程序启动之后,容器应用程序停止之后。 + +### 接口参考 + +当前为docker run和create命令增加了参数“--hook-spec”,后面接spec文件的绝对路径,可以指定容器启动时的需要添加的hook,这些hook会自动附加在docker自己动态创建的hook后面(当前docker只有一个libnetwork的prestart hook),随容器的启动/销毁过程执行用户指定的程序。 + +spec的结构体定义为: + +```conf +// Hook specifies a command that is run at a particular event in the lifecycle of a container +type Hook struct{ + Path string `json:"path"` + Args []string `json:"args,omitempty"` + Env []string `json:"env,omitempty"` + Timeout *int `json:"timeout,omitempty"` +} +// Hooks for container setup and teardown +type Hooks struct{ + // Prestart is a list of hooks to be run before the container process is executed. + // On Linux, they are run after the container namespaces are created. + Prestart []Hook `json:"prestart,omitempty"` + // Poststart is a list of hooks to be run after the container process is started. + Poststart []Hook `json:"poststart,omitempty"` + // Poststop is a list of hooks to be run after the container process exits. + Poststop []Hook `json:"poststop,omitempty"` +} +``` + +- Spec文件的path、args、env 都是必填信息; +- Timeout选填\(建议配置\),参数类型为int,不接受浮点数,范围为\[1, 120\]。 +- Spec内容应该是json格式的,格式不对会报错,示例参考前面。 +- 使用的时候既可以\`docker run \--hook-spec /tmp/hookspec.json xxx\`, 也可以 \`docker create \--hook-spec /tmp/hookspec.json xxx && docker start xxx\`。 + +### 为容器定制特有的hook + +以启动过程中添加一个网卡的过程来说明。下面是相应的hook spec文件内容: + +```conf +{ + "prestart": [ + { + "path": "/var/lib/docker/hooks/network-hook", + "args": ["network-hook", "tap0", "myTap"], + "env": [], + "timeout": 5 + } + ], + "poststart":[], + "poststop":[] +} +``` + +指定prestart hook增加一个网络hook的执行。路径是/var/lib/docker/hooks/network-hook,args代表程序的参数,第一个参数一般是程序名字,第二个是程序接受的参数。对于network-hook这个hook程序,需要两个参数,第一个是主机上的网卡名字,第二个是在容器内的网卡重命名。 + +- 注意事项 + 1. hook path必须为docker的graph目录(\--graph)下的hooks文件夹下,默认一般为 /var/lib/docker/hooks,可以通过docker info命令查看root路径。 + + ```bash + [root@localhost ~]# docker info + ... + Docker Root Dir: /var/lib/docker + ... + ``` + + 这个路径可能会跟随用户手动配置,以及user namespace的使用(daemon --userns-remap)而变化。 path进行软链接解析后,必须以Docker Root Dir/hooks开头(如本例中使用 /var/lib/docker/hooks开头),否则会直接报错。 + + 2. hooks path必须指定绝对路径,因为这个是由daemon处理,相对路径对daemon无意义。同时绝对路径也更满足安全要求。 + 3. hook程序打印到stderr的输出会打印给客户端并对容器的声明周期产生影响(比如启动失败),而输出到stdout的打印信息会被直接忽略。 + 4. 严禁在hook里反向调用docker的指令。 + 5. 配置的hook执行文件必须要有可执行权限,否则hook执行会报错。 + 6. 使用hook时,执行时间应尽量短。如果hook中的prestart时间过长(超过2分钟),则会导致容器启动超时失败,如果hook中的poststop时间过长(超过2分钟),也会导致容器异常。 + + 目前已知的异常如下:执行docker stop命令停止容器时,2分钟超时执行清理时,由于hook还没执行结束,因此会等待hook执行结束(该过程持有锁),从而导致和该容器相关的操作都会卡住,需要等到hook执行结束才能恢复。另外,由于docker stop命令的2分钟超时处理是异步的过程,因此即使docker stop命令返回了成功,容器的状态也依然是up状态,需要等到hook执行完后状态才会修改为exited。 + +- 使用建议 + 1. 建议配置hook的Timeout超时时间阈值,超时时间最好在5s以内。 + 2. 建议不要配置过多hook,每个容器建议prestart、poststart、poststop这三个hook都只配置一个,过多hook会导致启动时间长。 + 3. 建议用户识别多个hook之间的依赖关系,如果存在依赖关系,在组合hook配置文件时要根据依赖关系灵活调整顺序,hook的执行顺序是按照配置的spec文件上的先后顺序。 + +### 多个hook-spec + +当有多个hook配置文件,要运行多个hook时,用户必须自己手工将多个hook配置文件组合成一个配置文件,使用\--hook-spec参数指定此合并后的配置文件,方可生效所有的hook;如果配置多个\--hook-spec参数,则只有最后一个生效。 + +配置举例: + +hook1.json内容如下: + +```bash +# cat /var/lib/docker/hooks/hookspec.json +{ + "prestart": [ + { + "path": "/var/lib/docker/hooks/lxcfs-hook", + "args": ["lxcfs-hook", "--log", "/var/log/lxcfs-hook.log"], + "env": [] + } + ], + "poststart":[], + "poststop":[] +} +``` + +hook2.json内容如下: + +```bash +# cat /etc/isulad-tools/hookspec.json +{ + "prestart": [ + { + "path": "/docker-root/hooks/docker-hooks", + "args": ["docker-hooks", "--state", "prestart"], + "env": [] + } + ], + "poststart":[], + "poststop":[ + { + "path": "/docker-root/hooks/docker-hooks", + "args": ["docker-hooks", "--state", "poststop"], + "env": [] + } + ] +} +``` + +手工合并后的json内容如下: + +```conf +{ + "prestart":[ + { + "path": "/var/lib/docker/hooks/lxcfs-hook", + "args": ["lxcfs-hook", "--log", "/var/log/lxcfs-hook.log"], + "env": [] + }, + { + "path": "/docker-root/hooks/docker-hooks", + "args": ["docker-hooks", "--state", "prestart"], + "env": [] + } + ], + "poststart":[], + "poststop":[ + { + "path": "/docker-root/hooks/docker-hooks", + "args": ["docker-hooks", "--state", "poststop"], + "env": [] + } + ] +} +``` + +需要注意的是,docker daemon会按照数组顺序依次读取hook配置文件中prestart等action中的hook二进制,进行执行动作。用户需要识别多个hook之间的依赖关系,如果有依赖关系,在组合hook配置文件时要根据依赖关系灵活调整顺序。 + +### 为所有容器定制默认的hook + +Docker daemon同样可以接收--hook-spec的参数,--hook-spec的语义与docker create/run的--hook-spec参数相同,这里不再复述。也可以在/etc/docker/daemon.json里添加hook配置: + +```conf +{ + "hook-spec": "/tmp/hookspec.json" +} +``` + +容器在运行时,会首先执行daemon定义的--hook-spec中指定的hooks,然后再执行每个容器单独定制的hooks。 + +## 创建容器配置健康检查 + +Docker提供了用户定义的对容器进行健康检查的功能。在Dockerfile中配置HEALTHCHECK CMD选项,或在容器创建时配置\--health-cmd选项,在容器内部周期性地执行命令,通过命令的返回值来监测容器的健康状态。 + +### 配置方法 + +- 在Dockerfile中添加配置,如: + + ```conf + HEALTHCHECK --interval=5m --timeout=3s --health-exit-on-unhealthy=true \ + CMD curl -f http://localhost/ || exit 1 + ``` + + 可配置的选项: + + 1. --interval=DURATION,默认 30s,相邻两次命令执行的间隔时间。另外,容器启动后,经过interval时间进行第一次检查。 + 2. --timeout=DURATION,默认 30s,单次检查命令执行的时间上限,超时则任务命令执行失败。 + 3. --start-period=DURATION,默认 0s,容器初始化时间。初始化期间也会执行健康检查,健康检查失败不会计入最大重试次数。但是,如果在初始化期间运行状况检查成功,则认为容器已启动。之后所有连续的检查失败都将计入最大重试次数。 + 4. --retries=N,默认 3,健康检查失败最大的重试次数。 + 5. --health-exit-on-unhealthy=BOOLEAN,默认false,检测到容器非健康时是否杀死容器 + 6. CMD,必选,在容器内执行的命令。返回值为0表示成功,非0表示失败。 + + 在配置了HEALTHCHECK后创建镜像,HEALTHCHECK相关配置会被写入镜像的配置中。通过docker inspect可以看到。如: + + ```conf + "Healthcheck": { + "Test": [ + "CMD-SHELL", + "/test.sh" + ] + }, + ``` + +- 在容器创建时的配置: + + ```bash + docker run -itd --health-cmd "curl -f http://localhost/ || exit 1" --health-interval 5m --health-timeout 3s --health-exit-on-unhealthy centos bash + ``` + + 可配置的选项: + + 1. \--health-cmd,必选,在容器内执行的命令。返回值为0表示成功,非0表示失败。 + 2. \--health-interval,默认 30s,最大为int64上限(纳秒)相邻两次命令执行的间隔时间。 + 3. \--health-timeout,默认 30s,最大为int64上限(纳秒),单次检查命令执行的时间上限,超时则任务命令执行失败。 + 4. \--health-start-period,默认 0s,最大为int64上限(纳秒),容器初始化时间。 + 5. \--health-retries,默认 3,最大为int32上限,健康检查失败最大的重试次数。 + 6. \--health-exit-on-unhealthy,默认false,检测到容器非健康时是否杀死容器。 + + 容器启动后,HEALTHCHECK相关配置会被写入容器的配置中。通过docker inspect可以看到。如: + + ```conf + "Healthcheck": { + "Test": [ + "CMD-SHELL", + "/test.sh" + ] + }, + ``` + +### 检查规则 + +1. 容器启动后,容器状态中显示health:starting。 +2. 经过start-period时间后开始,以interval为间隔周期性在容器中执行CMD。即:当一次命令执行完毕后,经过interval时间,执行下一次命令。 +3. 若CMD命令在timeout限制的时间内执行完毕,并且返回值为0,则视为一次检查成功,否则视为一次检查失败。检查成功后,容器状态变为health:healthy。 +4. 若CMD命令连续retries次检查失败,则容器状态变为health:unhealthy。失败后容器也会继续进行健康检查。 +5. 容器状态为health:unhealthy时,任意一次检查成功会使得容器状态变为health:healthy。 +6. 设置--health-exit-on-unhealthy的情况下,如果容器因为非被杀死退出(退出返回值137)后,健康检查只有容器在重新启动后才会继续生效。 +7. CMD执行完毕或超时时,docker daemon会将这次检查的起始时间、返回值和标准输出记录到容器的配置文件中。最多记录最新的5条数据。此外,容器的配置文件中还存储着健康检查的相关参数。 + +通过docker ps可以看到容器状态。 + +```bash +[root@bac shm]# docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +7de2228674a2 testimg "bash" About an hour ago Up About an hour (unhealthy) cocky_davinci +``` + +运行中的容器的健康检查状态也会被写入容器配置中。通过docker inspect可以看到。 + +```conf +"Health": { + "Status": "healthy", + "FailingStreak": 0, + "Log": [ + { + "Start": "2018-03-07T07:44:15.481414707-05:00", + "End": "2018-03-07T07:44:15.556908311-05:00", + "ExitCode": 0, + "Output": "" + }, + { + "Start": "2018-03-07T07:44:18.557297462-05:00", + "End": "2018-03-07T07:44:18.63035891-05:00", + "ExitCode": 0, + "Output": "" + }, + ...... +} +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> - 容器内健康检查的状态信息最多保存5条。会保存最后得到的5条记录。 +> - 容器内健康检查相关配置同时最多只能有一条生效。Dockerfile中配置的靠后的条目会覆盖靠前的;容器创建时的配置会覆盖镜像中的。 +> - 在Dockerfile中可以通过 HEALTHCHECK NONE来取消引用的镜像中的健康检查配置。在容器运行时可以通过配置--no-healthcheck来取消镜像中的健康检查配置。不允许在启动时同时配置健康检查相关选项与--no-healthcheck选项。 +> - 带有健康检查配置的容器启动后,若docker daemon退出,则健康检查不会执行,一直等待。docker daemon再次启动后,容器健康状态会变为starting。之后检查规则同上。 +> - 构建容器镜像时若健康检查相关参数配置为空,则按照缺省值处理。 +> - 容器启动时若健康检查相关参数配置为0,则按照缺省值处理。 + +## 停止与删除容器 + +用docker stop停止名为container1的容器: + +```bash +[root@localhost ~]# docker stop container1 +``` + +也可以用docker kill来杀死容器达到停止容器的目的: + +```bash +[root@localhost ~]# docker kill container1 +``` + +当容器停止之后,可以使用docker rm删除容器: + +```bash +[root@localhost ~]# docker rm container1 +``` + +当然,使用docker rm -f 强制删除容器也是可以的: + +```bash +[root@localhost ~]# docker rm -f container1 +``` + +### 注意事项 + +- 禁止使用docker rm -f XXX 删除容器。如果使用强制删除,docker rm会忽略过程中的错误,可能导致容器相关元数据残留。如果使用普通删除,如果删除过程出错,则会删除失败,不会导致元数据残留。 +- 避免使用docker kill命令。docker kill命令发送相关信号给容器内业务进程,依赖于容器内业务进程对信号的处理策略,可能导致业务进程的信号处理行为与指令的预期不符合的情况。 +- docker stop处于restarting状态的容器可能容器不会马上停止。如果一个容器使用了重启规则,当容器处于restarting状态时,docker stop这个容器时有很低的概率会立即返回,容器仍然会在重启规则的作用下再次启动。 +- 不能用docker restart重启加了--rm参数的容器。加了--rm参数的容器在退出时,容器会主动删除,如果重启一个加了--rm的参数的容器, 可能会导致一些异常情况,比如启动容器时,同时加了--rm与-ti参数,对容器执行restart操作,可能会概率性卡住无法退出。 + +### docker stop/restart 指定t参数且t<0时,请确保自己容器的应用会处理stop信号 + +Stop的原理:(Restart会调用Stop流程) + +1. Stop会首先给容器发送Stop 信号(15) +2. 然后等待一定的时间(这个时间就是用户输入的 t) +3. 过了一定时间,如果容器还活着,那么就发送kill信号(9)使容器强制退出 + +输入参数t(单位s)的含义: + +- t<0 : 表示死等,不管多久都等待程序优雅退出,既然用户这么输入了,表示对自己的应用比较放心,认为自己的程序有合理的stop信号的处理机制 +- t=0 : 表示不等,立即发送kill -9 到容器 +- t\>0 : 表示等一定的时间,如果容器还未退出,就发送kill -9 到容器 + +所以如果用户使用t<0 \(比如t=-1\),请确保自己容器的应用会正确处理signal 15,如果容器忽略了该信号,会导致docker stop一直卡住。 + +### 如果容器处于Dead状态,可能底层文件系统处于busy状态,需要手动删除 + +Docker在执行容器删除时,先停止容器的相关进程,之后将容器状态更改为Dead,最后执行容器rootfs的删除操作。当文件系统或者device mapper处于忙碌状态时,最后一步rootfs的删除会失败。docker ps -a查看会发现容器处于Dead状态。Dead状态的容器不能再次启动,需要等待文件系统不繁忙时,手动再次执行docker rm进行删除。 + +### 共享pid namespace容器,子容器处于pause状态会使得父容器stop卡住,并影响docker run命令执行 + +使用--pid参数创建共享pid namespace的父子容器,在执行docker stop父容器时,如果子容器中有进程无法退出(比如处于D状态、pause状态),会产生父容器docker stop命令等待的情况,需要手动恢复这些进程,才能正常执行命令。 + +遇到该问题的时候,请对pause状态的容器使用docker inspect 命令查询 PidMode对应的父容器是否为需要docker stop的容器。如果是该容器,请使用docker unpause将子容器解除pause状态,指令即可继续执行。 + +一般来说,导致该类问题的可能原因是容器对应的pid namespace由于进程残留导致无法被销毁。如果上述方法无法解决问题,可以通过借助linux工具,获取容器内残留进程,确定pid namespace中进程无法退出的原因,解决后容器就可以退出: + +- 获取容器pid namespace id + + ```bash + docker inspect --format={{.State.Pid}} CONTAINERID | awk '{print "/proc/"$1"/ns/pid"}' |xargs readlink + ``` + +- 获取该namespace下的线程 + + ```bash + ls -l /proc/*/task/*/ns/pid |grep -F PIDNAMESPACE_ID |awk '{print $9}' |awk -F \/ '{print $5}' + ``` + +## 容器信息查询 + +在任何情况下,容器的状态都不应该以docker命令执行是否成功返回为判断标准。如想查看容器状态,建议使用: + +```bash +docker inspect +``` + +## 修改操作 + +### docker exec进入容器启动多个进程的注意事项 + +docker exec进入容器执行的第一个命令为 bash 命令时,当退出 exec 时,要保证在这次exec启动的进程都退出了,再执行exit退出,否则会导致exit退出时终端卡住的情况。如果要在exit退出时,exec中启动的进程仍然在后台保持运行,要在启动进程时加上nohup。 + +### docker rename和docker stats \的使用冲突 + +如果使用`docker stats ` 实时监控容器,当使用docker rename重命名容器之后,docker stats中显示的名字将还是原来的名字,不是rename后的名字。 + +### docker rename操作restarting状态的容器可能会失败 + +对一个处于restarting状态的容器执行rename操作的时候,docker会同步修改容器网络的相关配置。由于restarting状态的容器可能还未真正启动起来,网络是不存在的,导致rename操作报错sandbox不存在。建议rename只操作非restarting的稳定状态的容器。 + +### docker cp + +1. 使用docker cp向容器中拷贝文件时,docker ps以及所有对这个容器的操作都将等待docker cp结束之后才能进行。 +2. 容器以非root用户运行,当使用docker cp命令复制主机上的一个非root权限的文件到容器时,文件在容器中的权限角色会变成root。docker cp与cp命令不同,docker cp会修改复制到容器中文件的uid和gid为root。 + +### docker login + +执行docker login后,会将user/passwd经 aes(256位)加密后保存在/root/.docker/config.json,同时生成 _root_.docker/aeskey\(权限0600\),用来解密/root/.docker/config.json中的 user/passwd。目前不能定时更新aeskey,只能由用户手动删除aeskey来更新。aeskey更新后,不管是否重启过docker daemon,都需要重新login,才可以push。例如: + +```bash +root@hello:~/workspace/dockerfile# docker login +Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. +Username: example Password: +Login Succeeded +root@hello:~/workspace/dockerfile# docker push example/empty +The push refers to a repository [docker.io/example/empty] +547b6288eb33: Layer already exists +latest: digest: sha256:99d4fb4ce6c6f850f3b39f54f8eca0bbd9e92bd326761a61f106a10454b8900b size: 524 +root@hello:~/workspace/dockerfile# rm /root/.docker/aeskey +root@hello:~/workspace/dockerfile# docker push example/empty +WARNING: Error loading config file:/root/.docker/config.json - illegal base64 data at input byte 0 +The push refers to a repository [docker.io/example/empty] +547b6288eb33: Layer already exists +errors: +denied: requested access to the resource is denied +unauthorized: authentication required +root@hello:~/workspace/dockerfile# docker login +Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. +Username: example +Password: +Login Succeeded +root@hello:~/workspace/dockerfile# docker push example/empty +The push refers to a repository [docker.io/example/empty] +547b6288eb33: Layer already exists +latest: digest: sha256:99d4fb4ce6c6f850f3b39f54f8eca0bbd9e92bd326761a61f106a10454b8900b size: 524 +``` diff --git a/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/container-management-2.md b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/container-management-2.md new file mode 100644 index 0000000000000000000000000000000000000000..2ef70b25fe1e0e6ef47e8eac46a4cb27cc16b6e8 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/container-management-2.md @@ -0,0 +1,1308 @@ +# 容器管理 + +- [容器管理](#容器管理) + - [总体说明](#总体说明) + - [attach](#attach) + - [commit](#commit) + - [cp](#cp) + - [create](#create) + - [diff](#diff) + - [exec](#exec) + - [export](#export) + - [inspect](#inspect) + - [logs](#logs) + - [pause/unpause](#pause-unpause) + - [port](#port) + - [ps](#ps) + - [rename](#rename) + - [restart](#restart) + - [rm](#rm) + - [run](#run) + - [start](#start) + - [stats](#stats) + - [stop](#stop) + - [top](#top) + - [update](#update) + - [wait](#wait) + +# 总体说明 + +当前docker支持的子命令,按照功能划分为以下几组: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能划分

+

命令

+

命令功能

+

主机环境相关

+

version

+

查看docker版本信息

+

info

+

查看docker系统和主机环境信息

+

容器相关

+

容器生命周期管理

+

create

+

由image创建一个容器

+

run

+

由image创建一个容器并运行

+

start

+

开始一个已停止运行的容器

+

stop

+

停止一个运行中的容器

+

restart

+

重启一个容器

+

wait

+

等待一个容器停止,并打印出退出码

+

rm

+

删除一个容器

+

容器内进程管理

+

pause

+

暂停一个容器内的所有进程

+

unpause

+

恢复一个容器内被暂停的所用进程

+

top

+

查看容器内的进程

+

exec

+

在容器内执行进程

+

容器检视工具

+

ps

+

查看运行中的容器(不加任何选项)

+

logs

+

显示一个容器的日志信息

+

attach

+

连接到一个容器的标准输入输出

+

inspect

+

返回容器的底层信息

+

port

+

列出容器与主机的端口映射

+

diff

+

返回容器相对于镜像中的rootfs所作的改动

+

cp

+

容器与主机之间复制文件

+

export

+

将一个容器中的文件系统导出为一个tar包

+

stats

+

实时查看容器的资源占用情况

+

images相关

+

生成一个新image

+

build

+

通过一个Dockerfile构建一个image

+

commit

+

基于容器的rootfs创建一个新的image

+

import

+

将tar包中的内容作为文件系统创建一个image

+

load

+

从一个tar包中加载一个image

+

与image仓库有关

+

login

+

登录一个registry

+

logout

+

登出一个registry

+

pull

+

从registry中拉取一个image

+

push

+

将一个image推送到registry中

+

search

+

在registry中搜寻image

+

与image管理有关

+

images

+

显示系统中的image

+

history

+

显示一个image的变化历史

+

rmi

+

删除image

+

tag

+

给image打标签

+

save

+

将一个image保存到一个tar包中

+

其他

+

events

+

从docker daemon中获取实时事件

+

rename

+

重命名容器

+
+ +其中有些子命令还有一些参数选项如docker run,通过docker COMMAND --help可以查看相应COMMAND命令的帮助,命令选项参考上文的命令选项约定。下面详细介绍每个命令的使用。 + +## attach + +用法:**docker attach \[OPTIONS\] CONTAINER** + +功能:附加到一个运行着的容器 + +选项: + +\--no-stdin=false 不附加STDIN + +\--sig-proxy=true 代理所有到容器内部的信号,不代理SIGCHLD, SIGKILL, SIGSTOP + +示例: + +```shell +$ sudo docker attach attach_test +root@2988b8658669:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var +``` + +## commit + +用法:**docker commit \[OPTIONS\] CONTAINER \[REPOSITORY\[:TAG\]\]** + +功能:由一个容器创建一个新的image + +选项: + +-a, \--author="" 指定作者 + +-m, \--message="" 提交的信息 + +-p, \--pause=true 在提交过程中暂停容器 + +示例: + +运行一个容器,然后将这个容器提交成一个新的image + +```shell +$ sudo docker commit test busybox:test +sha256:be4672959e8bd8a4291fbdd9e99be932912fe80b062fba3c9b16ee83720c33e1 + +$ sudo docker images +REPOSITORY TAG IMAGE ID CREATED SIZE +busybox latest e02e811dd08f 2 years ago 1.09MB +``` + +## cp + +用法:docker cp \[OPTIONS\] CONTAINER:SRC\_PATH DEST\_PATH|- + +docker cp \[OPTIONS\] SRC\_PATH|- CONTAINER:DEST\_PATH + +功能:从指定的容器内的一个路径复制文件或文件夹到主机的指定路径中,或者把主机的文件或者文件夹拷贝到容器内。 + +注意:docker cp不支持容器内/proc,/sys,/dev,/tmp等虚拟文件系统以及用户在容器内自行挂载的文件系统内的文件拷贝。 + +选项: + +-a, \--archive 将拷贝到容器的文件属主设置为容器运行用户(\--user) + +-L, \--follow-link 解析并跟踪文件的符号链接 + +示例: + +复制registry容器中/test目录到主机的/home/aaa目录中 + +```shell +$ sudo docker cp registry:/test /home/aaa +``` + +## create + +用法:**docker create \[OPTIONS\] IMAGE \[COMMAND\] \[ARG...\]** + +功能:使用image创建一个新的容器,并将返回一个容器的ID,创建之后的容器用docker start命令启动,OPTIONS用于创建容器时对容器进行配置,有些选项将覆盖image中对容器的配置,COMMAND指定容器启动时执行的命令。 + +选项: + +**表 2** 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数含义

+

-a --attach=[]

+

使控制台Attach到容器内进程的STDIN,STDOUT,STDERR

+

--name=""

+

指定容器的名字

+

--add-host=[host:ip]

+

在容器内的/etc/hosts中添加一个hostname到IP地址的映射

+

e.g. --add-host=test:10.10.10.10

+

--annotation

+

设置容器的annotations。例如支持native.umask选项:

+
--annotation native.umask=normal  启动的容器umask值为0022
+--annotation native.umask=secure # 启动的容器umask值为0027
+

注意如果没有配置该参数,则使用dockerd中的umask配置。

+

--blkio-weight

+

blockio的相对权重,从10到1000

+

--blkio-weight-device=[]

+

blockio权重(设置相对权重)

+

-c, --cpu-shares=0

+

容器获得主机CPU的相对权重,通过设置这个选项获得更高的优先级,默认所有的容器都是获得相同的CPU优先权。

+

--cap-add=[]

+

添加Linux权能

+

--cap-drop=[]

+

清除Linux权能

+

--cgroup-parent

+

为容器设置cgroup父目录

+

--cidfile=""

+

将容器的ID写到指定的文件中

+

e.g. --cidfile=/home/cidfile-test 将该容器的ID写入到/home/cidfile-test中

+

--cpu-period

+

设置CFS(完全公平调度策略)进程的CPU周期。

+

缺省值为100ms;一般--cpu-period参数和--cpu-quota是配合使用的,比如--cpu-period=50000 --cpu-quota=25000,意味着如果有1个CPU,该容器可以每50ms获取到50%的CPU。

+

使用--cpus=0.5也可达到同样的效果

+

--cpu-quota

+

设置CFS(完全公平调度策略)进程的CPU配额,默认为0,即没有限制

+

--cpuset-cpus

+

设置容器中进程允许运行的CPU (0-3, 0,1)。默认没有限制

+

--cpuset-mems

+

设置容器中进程运行的内存节点 (0-3, 0,1),只对NUMA系统起作用

+

--device=[]

+

将主机的设备添加到容器中 (e.g. --device=/dev/sdc:/dev/xvdc:rwm)

+

--dns=[]

+

强制容器使用指定的dns服务器(e.g. 创建容器时指定--dns=114.114.xxx.xxx,将在容器的/etc/resolv.conf中写入nameserver 114.114.xxx.xxx并将覆盖原来的内容)

+

--dns-opt=[]

+

设置DNS选项

+

--dns-search=[]

+

强制容器使用指定的dns搜索域名

+

-e, --env=[]

+

设置容器的环境变量

+

--env=[KERNEL_MODULES=]:

+

在容器中插入指定模块。目前仅支持Host主机上有的模块,且容器删除后Host主机上模块仍然驻留,且容器需要同时指定--hook-spec选项。以下都是参数的合法格式:

+

KERNEL_MODULERS=

+

KERNEL_MODULERS=a

+

KERNEL_MODULERS=a,b

+

KERNEL_MODULERS=a,b,

+

--entrypoint=""

+

覆盖image中原有的entrypoint,entrypoint设置容器启动时执行的命令

+

--env-file=[]

+

从一个文件中读取环境变量,多个环境变量在文件中按行分割(e.g. --env-file=/home/test/env,其中env文件中存放了多个环境变量)

+

--expose=[]

+

开放一个容器内部的端口,使用下文介绍的-P选项将会使开放的端口映射到主机的一个端口。

+

--group-add=[]

+

指定容器添加到额外的组

+

-h, --hostname=""

+

设置容器主机名

+

--health-cmd

+

设置容器健康检查执行的命令

+

--health-interval

+

相邻两次命令执行的间隔时间,默认 30s

+

--health-timeout

+

单次检查命令执行的时间上限,超时则任务命令执行失败,默认30s

+

--health-start-period

+

容器启动距离第一次执行健康检查开始的时间,默认0s

+

--health-retries

+

健康检查失败最大的重试次数,默认3

+

--health-exit-on-unhealthy

+

容器被检查为非健康后停止容器,默认false

+

--host-channel=[]

+

设置一个通道供容器内进程与主机进行通信,格式:<host path>:<container path>:<rw/ro>:<size limit>

+

-i, --interactive=false

+

设置STDIN打开即使没有attached

+

--ip

+

设置容器的IPv4地址

+

--ip6

+

设置容器的IPv6地址

+

--ipc

+

指定容器的ipc命名空间

+

--isolation

+

指定容器隔离策略

+

-l, --label=[]

+

设置容器的标签

+

--label-file=[]

+

从文件中获取标签

+

--link=[]

+

链接到其他容器,这个选项将在容器中添加一些被链接容器IP地址和端口的环境变量及在/etc/hosts中添加一条映射(e.g. --link=name:alias)

+

--log-driver

+

设置容器的日志驱动

+

--log-opt=[]

+

设置日志驱动选项

+

-m, --memory=""

+

设置容器的内存限制,格式<number><optional unit>, 其中 unit = b, k, m or g。该参数最小值为4m。

+

--mac-address

+

设置容器的mac地址 (e.g. 92:d0:c6:0a:xx:xx)

+

--memory-reservation

+

设置容器内存限制,默认与--memory一致。可认为--memory是硬限制,--memory-reservation是软限制;当使用内存超过预设值时,会动态调整(系统回收内存时尝试将使用内存降低到预设值以下),但不确保一定不超过预设值。一般可以和--memory一起使用,数值小于--memory的预设值。

+

--memory-swap

+

设置普通内存和交换分区的使用总量,-1为不做限制。如果不设置,则为--memory值的2倍,即SWAP可再使用与--memory相同的内存量。

+

--memory-swappiness=-1

+

设置容器使用交换内存的时机,以剩余内存百分比为度量(0-100)

+

--net="bridge"

+

设置容器的网络模式,当前1.3.0版本的docker有四个模式:bridge、host、none、container:<name|id>。默认使用的是bridge。

+
  • bridge:使用桥接模式在docker daemon启动时使用的网桥上创建一个网络栈。
  • host:在容器内使用主机的网络栈
  • none:不使用网络
  • container:<name|id>:重复利用另外一个容器的网络栈
+

--no-healthcheck

+

设置容器不使用健康检查

+

--oom-kill-disable

+

禁用OOM killer,建议如果不设置-m参数,也不要设置此参数。

+

--oom-score-adj

+

调整容器的oom规则(-1000到1000)

+

-P, --publish-all=false

+

将容器开放的所有端口一一映射到主机的端口,通过主机的端口可以访问容器内部,通过下文介绍的docker port命令可以查看具体容器端口和主机端口具体的映射关系。

+

-p, --publish=[]

+

将容器内的一个端口映射到主机的一个端口,format: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort | containerPort,如果没有指定IP代表侦听主机所有网卡的访问,如果没有指定hostPort,表示自动分配主机的端口。

+

--pid

+

设置容器的PID命名空间

+

--privileged=false

+

给予容器额外的权限,当使用了--privileged选项,容器将可以访问主机的所有设备。

+

--restart=""

+

设置容器退出时候的重启规则,当前1.3.1版本支持3个规则:

+
  • no:当容器停止时,不重启。
  • on-failure:当容器退出码为非0时重启容器,这个规则可以附加最大重启次数,如on-failure:5,最多重启5次。
  • always:无论退出码是什么都退出。
+

--read-only

+

将容器的根文件系统以只读的形式挂载

+

--security-opt=[]

+

容器安全规则

+

--shm-size

+

/dev/shm设备的大小,缺省值是64M

+

--stop-signal=SIGTERM

+

容器停止信号,默认为SIGTERM

+

-t, --tty=false

+

分配一个伪终端

+

--tmpfs=[]

+

挂载tmpfs目录

+

-u, --user=""

+

指定用户名或者用户ID

+

--ulimit=[]

+

ulimit选项

+

--userns

+

指定容器的user命名空间

+

-v, --volume=[]

+

将主机的一个目录挂载到容器内部,或者在容器中创建一个新卷(e.g. -v /home/test:/home将主机的/home/test目录挂载到容器的/home目录下,-v /tmp 在容器中的根目录下创建tmp文件夹,该文件夹可以被其他容器用--volumes-from选项共享 )。不支持将主机目录挂载到容器/proc子目录,否则启动容器会报错。

+

--volume-driver

+

设置容器的数据卷驱动,可选。

+

--volumes-from=[]

+

将另外一个容器的卷挂载到本容器中,实现卷的共享(e.g. -volumes-from container_name将container_name中的卷挂载到这个容器中 )。-v和--volumes-from=[]是两个非常重要的选项用于数据的备份和热迁移。

+

-w, --workdir=""

+

指定容器的工作目录,进入容器时的目录

+
+ +示例: + +创建了一个名为busybox的容器,创建之后的容器用docker start命令启动。 + +```shell +$ sudo docker create -ti --name=busybox busybox /bin/bash +``` + +## diff + +用法:**docker diff CONTAINER** + +功能:检视容器的差异,相比于容器刚创建时做了哪些改变 + +选项:无 + +示例: + +```shell +$ sudo docker diff registry +C /root +A /root/.bash_history +A /test +``` + +## exec + +### 接口原型 + +```shell +rpc Exec(ExecRequest) returns (ExecResponse) {} +``` + +### 接口描述 + +在容器中执行命令,采用的gRPC通讯方式从CRI服务端获取url,再通过获得的url与websocket服务端建立长连接,实现与容器的交互。 + +### 注意事项 + +执行一条单独的命令,也能打开终端与容器交互。stdin/stdout/stderr之一必须是真的。如果tty为真,stderr必须是假的。 不支持多路复用,在这种情况下,stdout和stderr的输出将合并为单流。 + +### 参数 + + + + + + + + + + + + + + + + + + + + + + + + +

参数成员

+

描述

+

string container_id

+

容器ID

+

repeated string cmd

+

待执行的命令

+

bool tty

+

是否在TTY中执行命令

+

bool stdin

+

是否流式标准输入

+

bool stdout

+

是否流式标准输出

+

bool stderr

+

是否流式输出标准错误

+
+ +### 返回值 + + + + + + + + + +

返回值

+

描述

+

string url

+

exec流服务器的完全限定URL

+
+ +## export + +用法:**docker export CONTAINER** + +功能:将一个容器的文件系统内容以tar包导出到STDOUT + +选项:无 + +示例: + +将名为busybox的容器的内容导出到busybox.tar包中: + +```shell +$ sudo docker export busybox > busybox.tar +$ ls +busybox.tar +``` + +## inspect + +用法:**docker inspect \[OPTIONS\] CONTAINER|IMAGE \[CONTAINER|IMAGE...\]** + +功能:返回一个容器或者镜像的底层信息 + +选项: + +-f, \--format="" 按照给定的格式输出信息 + +-s, \--size 若查询类型为容器,显示该容器的总体文件大小 + +\--type 返回指定类型的JSON格式 + +-t, \--time=120 超时时间的秒数,若在该时间内docker inspect未执行成功,则停止等待并立即报错。默认为120秒。 + +示例: + +1. 返回一个容器的信息 + + ```shell + $ sudo docker inspect busybox_test + [ + { + "Id": "9fbb8649d5a8b6ae106bb0ac7686c40b3cbd67ec2fd1ab03e0c419a70d755577", + "Created": "2019-08-28T07:43:51.27745746Z", + "Path": "bash", + "Args": [], + "State": { + "Status": "running", + "Running": true, + "Paused": false, + "Restarting": false, + "OOMKilled": false, + "Dead": false, + "Pid": 64177, + "ExitCode": 0, + "Error": "", + "StartedAt": "2019-08-28T07:43:53.021226383Z", + "FinishedAt": "0001-01-01T00:00:00Z" + }, + ...... + ``` + +2. 按照给定格式返回一个容器的指定信息,下面的例子返回busybox\_test容器IP地址 + + ```shell + $ sudo docker inspect -f {{.NetworkSettings.IPAddress}} busybox_test + 172.17.0.91 + ``` + +## logs + +用法:**docker logs \[OPTIONS\] CONTAINER** + +功能:抓取容器内的日志信息,容器可以是运行状态的也可以是停止状态的 + +选项: + +-f, \--follow=false 实时打印日志信息 + +-t, \--timestamps=false 显示日志的时间戳 + +\--since 显示指定时间之后的日志 + +\--tail="all" 设置显示的行数,默认显示所有 + +示例: + +1. 查看jaegertracing容器的日志信息,该容器上跑了一个jaegertracing服务 + + ```shell + $ sudo docker logs jaegertracing + {"level":"info","ts":1566979103.3696961,"caller":"healthcheck/handler.go:99","msg":"Health Check server started","http-port":14269,"status":"unavailable"} + {"level":"info","ts":1566979103.3820567,"caller":"memory/factory.go:55","msg":"Memory storage configuration","configuration":{"MaxTraces":0}} + {"level":"info","ts":1566979103.390773,"caller":"tchannel/builder.go:94","msg":"Enabling service discovery","service":"jaeger-collector"} + {"level":"info","ts":1566979103.3908608,"caller":"peerlistmgr/peer_list_mgr.go:111","msg":"Registering active peer","peer":"127.0.0.1:14267"} + {"level":"info","ts":1566979103.3922884,"caller":"all-in-one/main.go:186","msg":"Starting agent"} + {"level":"info","ts":1566979103.4047635,"caller":"all-in-one/main.go:226","msg":"Starting jaeger-collector TChannel server","port":14267} + {"level":"info","ts":1566979103.404901,"caller":"all-in-one/main.go:236","msg":"Starting jaeger-collector HTTP server","http-port":14268} + {"level":"info","ts":1566979103.4577134,"caller":"all-in-one/main.go:256","msg":"Listening for Zipkin HTTP traffic","zipkin.http-port":9411} + ``` + +2. 加上-f选项,实时打印jaegertracing容器的日志信息 + + ```shell + $ sudo docker logs -f jaegertracing + {"level":"info","ts":1566979103.3696961,"caller":"healthcheck/handler.go:99","msg":"Health Check server started","http-port":14269,"status":"unavailable"} + {"level":"info","ts":1566979103.3820567,"caller":"memory/factory.go:55","msg":"Memory storage configuration","configuration":{"MaxTraces":0}} + {"level":"info","ts":1566979103.390773,"caller":"tchannel/builder.go:94","msg":"Enabling service discovery","service":"jaeger-collector"} + {"level":"info","ts":1566979103.3908608,"caller":"peerlistmgr/peer_list_mgr.go:111","msg":"Registering active peer","peer":"127.0.0.1:14267"} + {"level":"info","ts":1566979103.3922884,"caller":"all-in-one/main.go:186","msg":"Starting agent"} + ``` + +## pause-unpause + +用法:**docker pause CONTAINER** + +**docker unpause CONTAINER** + +功能:这两个命令是配对使用的,docker pause暂停容器内的所有进程,docker unpause恢复暂停的进程 + +选项:无 + +示例: + +本示例将演示一个跑了docker registry(docker镜像服务)服务的容器,当使用docker pause 命令暂停这个容器的进程后,使用curl命令访问该registry服务将阻塞,使用docker unpause命令将恢复registry服务,可以用curl命令访问。 + +1. 启动一个registry容器 + + ```shell + $ sudo docker run -d --name pause_test -p 5000:5000 registry + ``` + + 此时可以用curl命令访问这个服务,请求状态码会返回200 OK。 + + ```shell + $ sudo curl -v 127.0.0.1:5000 + ``` + +2. 暂停这个容器内的进程 + + ```shell + $ sudo docker pause pause_test + ``` + + 此时用curl命令访问这个服务将阻塞,等待服务开启。 + +3. 恢复运行这个容器内的进程 + + ```shell + $ sudo docker unpause pause_test + ``` + + 此时步骤2中的curl访问将恢复运行,请求状态码返回200 OK。 + +## port + +用法:**docker port CONTAINER \[PRIVATE\_PORT\[/PROTO\]\]** + +功能:列出容器的端口映射,或者查找指定端口在主机的哪个端口 + +选项:无 + +示例: + +1. 列出容器所有的端口映射 + + ```shell + $ sudo docker port registry + 5000/tcp -> 0.0.0.0.:5000 + ``` + +2. 查找容器指定端口的映射 + + ```shell + $ sudo docker port registry 5000 + 0.0.0.0.:5000 + ``` + +## ps + +用法:**docker ps \[OPTIONS\]** + +功能:根据不同的选项列出不同状态的容器,在不加任何选项的情况下,将列出正在运行的容器 + +选项: + +-a, \--all=false 显示所用的容器 + +-f, \--filter=\[\] 筛选值,可用的筛选值有:exited=容器的退出码status=\(restarting|running|paused|exited\)容器的状态码(e.g. -f status=running,列出正在运行的容器) + +-l, \--latest=false 列出最近创建的一个容器 + +-n=-1 列出最近n次创建的容器 + +\--no-trunc=false 将64位的容器ID全部显示出来,默认显示12位容器的ID + +-q, \--quiet=false 显示容器的ID + +-s, \--size=false 显示容器的大小 + +示例: + +1. 列出正在运行的容器 + + ```shell + $ sudo docker ps + ``` + +2. 列出所有的容器 + + ```shell + $ sudo docker ps -a + ``` + +## rename + +用法:**docker rename OLD\_NAME NEW\_NAME** + +功能:重命名容器 + +示例: + +示例中,用docker run创建并启动一个容器,使用docker rename对容器重命名,并查看容器名是否改变。 + +```shell +$ sudo docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +b15976967abb busybox:latest "bash" 3 seconds ago Up 2 seconds festive_morse +$ sudo docker rename pedantic_euler new_name +$ sudo docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +b15976967abb busybox:latest "bash" 34 seconds ago Up 33 seconds new_name +``` + +## restart + +用法:**docker restart \[OPTIONS\] CONTAINER \[CONTAINER...\]** + +功能:重启一个运行中的容器 + +选项: + +-t, \--time=10 在杀掉容器之前等待容器停止的秒数,如果容器已停止,就重启。默认为10秒。 + +示例: + +```shell +$ sudo docker restart busybox +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 容器在restart过程中,如果容器内存在D状态或Z状态的进程,可能会导致容器重启失败,这需要进一步分析导致容器内进程D状态或Z状态的原因,待容器内进程D状态或Z状态解除后,再进行容器restart操作。 + +## rm + +用法:**docker rm \[OPTIONS\] CONTAINER \[CONTAINER...\]** + +功能:删除一个或多个容器 + +选项: + +-f, \--force=false 强制删除运行中的容器 + +-l, \--link=false 删除指定的链接,而不是底层容器 + +-v, \--volumes=false 删除与容器关联的卷 + +示例: + +1. 删除一个停止运行的容器 + + ```shell + $ sudo docker rm test + ``` + +2. 删除一个正在运行的容器 + + ```shell + $ sudo docker rm -f rm_test + ``` + +## run + +用法:**docker run \[OPTIONS\] IMAGE \[COMMAND\] \[ARG...\]** + +功能:该命令将由指定的image(如果指定的IMAGE不存在,则从官方镜像库中下载一个镜像)创建一个容器,并启动这个容器,并在容器中执行指定的命令。该命令集成了docker create命令、docker start命令、docker exec命令。 + +选项:(该命令的选项与docker create命令的选项一样,请参考docker create命令选项,仅仅多了以下两个选项) + +\--rm=false 设置容器退出时自动删除容器 + +-v 挂载本地目录或匿名卷到容器内。注意:当将本地目录以带有selinux的安全标签的方式挂载到容器内的同时,尽量不要同时做该本地目录的增删操作,否则该安全标签可能不生效 + +\--sig-proxy=true 发往进程信号的代理,SIGCHLD, SIGSTOP, SIGKILL不使用代理 + +示例: + +使用busybox镜像运行一个容器,在容器启动后执行/bin/sh + +```shell +$ sudo docker run -ti busybox /bin/sh +``` + +## start + +用法:**docker start \[OPTIONS\] CONTAINER \[CONTAINER...\]** + +功能:启动一个或多个未运行容器 + +选项: + +-a, \--attach=false 容器的标准输出和错误输出附加到host的STDOUT和STDERR上 + +-i, \--interactive=false 容器的标准输入附加到host的STDIN上 + +示例: + +启动一个名为busybox的容器,添加-i -a选项附加标准输入输出,容器启动后直接进入容器内部,输入exit可以退出容器。 + +如果启动容器时不加-i -a选项,容器将在后台启动。 + +```shell +$ sudo docker start -i -a busybox +``` + +## stats + +用法:**docker stats \[OPTIONS\] \[CONTAINER...\]** + +功能:持续监控并显示指定容器(若不指定,则默认全部容器)的资源占用情况 + +选项: + +-a, \--all 显示所有容器(默认仅显示运行状态的容器) + +\--no-stream 只显示第一次的结果,不持续监控 + +示例: + +示例中,用docker run创建并启动一个容器,docker stats将输出容器的资源占用情况。 + +```shell +$ sudo docker stats +CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS +2e242bcdd682 jaeger 0.00% 77.08MiB / 125.8GiB 0.06% 42B / 1.23kB 97.9MB / 0B 38 +02a06be42b2c relaxed_chandrasekhar 0.01% 8.609MiB / 125.8GiB 0.01% 0B / 0B 0B / 0B 10 +deb9e49fdef1 hardcore_montalcini 0.01% 12.79MiB / 125.8GiB 0.01% 0B / 0B 0B / 0B 9 +``` + +## stop + +用法:**docker stop \[OPTIONS\] CONTAINER \[CONTAINER...\]** + +功能:通过向容器发送一个SIGTERM信号并在一定的时间后发送一个SIGKILL信号停止容器 + +选项: + +-t, \--time=10 在杀掉容器之前等待容器退出的秒数,默认为10S + +示例: + +```shell +$ sudo docker stop -t=15 busybox +``` + +## top + +用法:**docker top CONTAINER \[ps OPTIONS\]** + +功能:显示一个容器内运行的进程 + +选项:无 + +示例: + +先运行了一个名为top\_test的容器,并在其中执行了top指令 + +```shell +$ sudo docker top top_test +UID PID PPID C STIME TTY TIME CMD +root 70045 70028 0 15:52 pts/0 00:00:00 bash +``` + +显示的PID是容器内的进程在主机中的PID号。 + +## update + +用法:**docker update \[OPTIONS\] CONTAINER \[CONTAINER...\]** + +功能:热变更一个或多个容器配置。 + +选项: + +**表 3** 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数含义

+

--accel=[]

+

设置容器加速器,可设置一个或多个

+

--blkio-weight

+

设置容器blockio的相对权重,从10到1000

+

--cpu-shares

+

设置容器获得主机CPU的相对权重,通过设置这个选项获得更高的优先级,默认所有的容器都是获得相同的CPU优先权。

+

--cpu-period

+

设置CFS(完全公平调度策略)进程的CPU周期。

+

缺省值为100ms;一般--cpu-period参数和--cpu-quota是配合使用的,比如--cpu-period=50000 --cpu-quota=25000,意味着如果有1个CPU,该容器可以每50ms获取到50%的CPU。

+

--cpu-quota

+

设置CFS(完全公平调度策略)进程的CPU配额,默认为0,即没有限制

+

--cpuset-cpus

+

设置容器中进程允许运行的CPU (0-3, 0,1)。默认没有限制

+

--cpuset-mems

+

设置容器中进程运行运行的内存内存节点 (0-3, 0,1),只对NUMA系统起作用

+

--kernel-memory=""

+

设置容器的kernerl内存限制,格式<number><optional unit>, 其中 unit = b, k, m or g

+

-m, --memory=""

+

设置容器的内存限制,格式<number><optional unit>, 其中 unit = b, k, m or g。该参数最小值为4m。

+

--memory-reservation

+

设置容器内存限制,默认与--memory一致。可认为--memory是硬限制,--memory-reservation是软限制;当使用内存超过预设值时,会动态调整(系统回收内存时尝试将使用内存降低到预设值以下),但不确保一定不超过预设值。一般可以和--memory一起使用,数值小于--memory的预设值。

+

--memory-swap

+

设置普通内存和交换分区的使用总量,-1为不做限制。如果不设置,则为--memory值的2倍,即SWAP可再使用与--memory相同的内存量。

+

--restart=""

+

设置容器退出时候的重启规则,当前1.3.1版本支持3个规则:

+
  • no:当容器停止时,不重启。
  • on-failure:当容器退出码为非0时重启容器,这个规则可以附加最大重启次数,如on-failure:5,最多重启5次。
  • always:无论退出码是什么都退出。
+

--help

+

打印help信息

+
+ +示例: + +变更一个容器名为busybox的cpu和mem配置,包括容器获得主机CPU的相对权重值为512,容器中进程允许运行的CPU核心为0,1,2,3,容器运行内存限制为512m。 + +```shell +$ sudo docker update --cpu-shares 512 --cpuset-cpus=0,3 --memory 512m ubuntu +``` + +## wait + +用法:**docker wait CONTAINER \[CONTAINER...\]** + +功能:等待一个容器停止,并打印出容器的退出码 + +选项:无 + +示例: + +先开启一个名为busybox的容器 + +```shell +$ sudo docker start -i -a busybox +``` + +执行docker wait + +```shell +$ sudo docker wait busybox +0 +``` + +将阻塞等待busybox容器的退出,退出busybox容器后将看到打印退出码“0”。 diff --git a/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/docker-faqs.md b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/docker-faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..9d7aec5ac4aced1046df0f36127fb6f7ed14317b --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/docker-faqs.md @@ -0,0 +1,6 @@ +# Docker常见问题与解决方法 + +## **问题1:docker v18.09.9拉起的容器挂载点相比docker v19.03.0及以后的版本多一个** + +原因:18.09版本的docker,默认ipcmode为shareable,该配置会多挂载一个shmpath挂载点。 +解决方法:结合实际情况修改docker配置文件中的ipcmode选项为private,或者使用新版本的docker。 diff --git a/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/image-management-1.md b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/image-management-1.md new file mode 100644 index 0000000000000000000000000000000000000000..9ed41a02793f861279b4473a076d603e71a8791f --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/image-management-1.md @@ -0,0 +1,62 @@ +# 镜像管理 + +- [镜像管理](#镜像管理) + - [创建镜像](#创建镜像) + - [查看镜像](#查看镜像) + - [删除镜像](#删除镜像) + +## 创建镜像 + +docker pull、docker build、docker commit、docker import、docker load都可以创建一个新的镜像,关于这些命令的使用详见命令行参考镜像管理。 + +### 注意事项 + +1. 避免并发docker load和docker rmi操作。 如果同时满足如下两个条件,可能导致并发性问题: + + - 某个镜像存在于系统中。 + - 同时对该镜像进行docker rmi和docker load操作。 + + 所以使用时应该避免这种场景(注:所有的镜像创建操作如tag,build,load和rmi并发都有可能会导致类似的错误,应该尽量避免这类操作与rmi的并发)。 + +2. 如果Docker操作镜像时系统掉电,可能导致镜像损坏,需要手动恢复。 + + 由于Docker在操作镜像(pull/load/rmi/build/combine/commit/import等)时,镜像数据的操作是异步的、镜像元数据是同步的。所以如果在镜像数据未全部刷到磁盘时掉电,可能导致镜像数据和元数据不一致。对用户的表现是镜像可以看到\(有可能是none 镜像\),但是无法启动容器,或者启动后的容器有异常。这种情况下应该先使用docker rmi删除该镜像,然后重新进行之前的操作,系统可以恢复。 + +3. 生产环境节点应避免存留超大数量镜像,请及时清理不使用的镜像。 + + 镜像数目过多会导致docker image等命令执行过慢,从而导致docker build/docker commit等相关命令执行失败,并可能导致内存堆积。在生产环境中,请及时清理不再使用的镜像和中间过程镜像。 + +4. 使用\--no-parent参数build镜像时,如果有多个build操作同时进行,并且Dockerfile里 FROM的镜像相同,则可能会残留镜像,分为以下两种情况: + - FROM的镜像不是完整镜像,则有可能会残留FROM的镜像运行时生成的镜像。残留的镜像名类似base\_v1.0.0-app\_v2.0.0,或者残留镜像。 + - 如果Dockerfile里的前几条指令相同,则有可能会残留镜像。 + +### 可能会产生none镜像场景 + +1. none镜像是指没有tag的最顶层镜像,比如ubuntu的imageID,只有一个tag是ubuntu,如果这个tag没了,但是imageID还在,那么这个imageID就变成了none镜像。 +2. Save镜像的过程中因为要把镜像的数据导出来,所以对image进行保护,但是如果这个时候来一个删除操作,可能会untag成功,删除镜像ID失败,造成该镜像变成none镜像。 +3. 执行docker pull时掉电,或者系统panic,可能出现none镜像,为保证镜像完整性,此时可通过docker rmi 删除镜像后重新拉取。 +4. 执行docker save保存镜像时,如果指定的名字为镜像ID,则load后的镜像也没有tag,其镜像名为none。 + +### build镜像的同时删除该镜像,有极低概率导致镜像build失败 + +目前的build镜像的过程是通过引用计数来保护的,当build完一个镜像后,紧接着就给该镜像的引用计数加1(holdon操作),一旦holdon操作成功,该镜像就不会被删除了,但是在holdon之前,有极低的概率,还是可以删除成功,导致build镜像失败。 + +## 查看镜像 + +查看本地镜像列表: + +```bash +docker images +``` + +## 删除镜像 + +删除镜像(image处为具体镜像名): + +```bash +docker rmi image +``` + +### 注意事项 + +禁止使用docker rmi -f XXX删除镜像。如果使用强制删除,docker rmi会忽略过程中的错误,可能导致容器或者镜像元数据残留。如果使用普通删除,如果删除过程出错,则会删除失败,不会导致元数据残留。 diff --git a/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/image-management-2.md b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/image-management-2.md new file mode 100644 index 0000000000000000000000000000000000000000..5acdc9ae41dd904553cd3486734b2669c8e8250a --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/image-management-2.md @@ -0,0 +1,465 @@ +# 镜像管理 + +- [镜像管理](#镜像管理) + - [build](#build) + - [history](#history) + - [images](#images) + - [import](#import) + - [load](#load) + - [login](#login) + - [logout](#logout) + - [pull](#pull) + - [push](#push) + - [rmi](#rmi) + - [save](#save) + - [search](#search) + - [tag](#tag) + +## build + +用法:**docker build \[OPTIONS\] PATH | URL | -** + +功能:使用指定路径中的Dockerfile生成构建一个新的image + +选项:常用选项参数如下,更多选项可以查看docker help build + +**表 4** 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数含义

+

--force-rm=false

+

即使没有构建成功也删除构建过程中生成的容器

+

--no-cache=false

+

构建image的过程中不使用缓存

+

-q, --quiet=false

+

禁止构建过程中产生的冗余信息

+

--rm=true

+

构建成功后删除过程中生成的容器

+

-t, --tag=""

+

指定构建生成的image的tag名

+

--build-arg=[]

+

设置构建参数

+

--label=[]

+

镜像相关参数设置,各参数意义与create类似

+

--isolation

+

指定容器的隔离方法

+

--pull

+

构建时总是尝试获取最新版本镜像

+
+ +Dockerfile介绍: + +Dockerfile是一个镜像的表示,可以通过Dockerfile来描述构建镜像的步骤,并自动构建一个容器,所有的 Dockerfile 命令格式都是:**INSTRUCTION arguments** + +**FROM命令** + +格式:FROM 或 FROM : + +功能:该命令指定基本镜像,是所有Dockerfile文件的第一个命令,如果没有指定基本镜像的tag,使用默认tag名latest。 + +**RUN命令** + +格式:RUN \(the command is run in a shell - \`/bin/sh -c\`\) 或者 + +RUN \["executable", "param1", "param2" ... \] \(exec form\) + +功能:RUN命令会在上面FROM指定的镜像里执行指定的任何命令,然后提交\(commit\)结果,提交的镜像会在后面继续用到。RUN命令等价于: + +docker run image command + +docker commit container\_id + +**注释** + +使用\#注释 + +**MAINTAINER命令** + +格式:MAINTAINER + +功能:命令用来指定维护者的姓名和联系方式 + +**ENTRYPOINT命令** + +格式:ENTRYPOINT cmd param1 param2 ... 或者ENTRYPOINT \["cmd", "param1", "param2"...\] + +功能:设置在容器启动时执行命令 + +**USER命令** + +格式:USER name + +功能:指定 memcached 的运行用户 + +**EXPOSE命令** + +格式:EXPOSE \[...\] + +功能:开放镜像的一个或多个端口 + +**ENV命令** + +格式:ENV + +功能:设置环境变量,设置了后,后续的RUN命令都可以使用 + +**ADD命令** + +格式:ADD + +功能:从src复制文件到container的dest路径, 是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件url, 是container中的绝对路径 + +**VOLUME命令** + +格式:VOLUME \[""\] + +功能:创建一个挂载点用于共享目录 + +**WORKDIR命令** + +格式:workdir + +功能:配置RUN, CMD, ENTRYPOINT 命令设置当前工作路径可以设置多次,如果是相对路径,则相对前一个 WORKDIR 命令 + +**CMD命令** + +格式:CMD \["executable","param1","param2"\] \(like an exec, preferred form\) + +CMD \["param1","param2"\] \(as default parameters to ENTRYPOINT\) + +CMD command param1 param2 \(as a shell\) + +功能:一个Dockerfile里只能有一个CMD,如果有多个,只有最后一个生效 + +**ONBUILD命令** + +格式:ONBUILD \[其他指令\] + +功能:后面跟其他指令,比如 RUN、COPY 等,这些指令,在当前镜像构建时并不会被执行,只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行 + +下面是Dockerfile的一个完整例子,该Dockerfile将构建一个安装了sshd服务的image + +```bash +FROM busybox +ENV http_proxy http://192.168.0.226:3128 +ENV https_proxy https://192.168.0.226:3128 +RUN apt-get update && apt-get install -y openssh-server +RUN mkdir -p /var/run/sshd +EXPOSE 22 +ENTRYPOINT /usr/sbin/sshd -D +``` + +示例: + +1. 以上文的Dockerfile构建一个image + + ```bash + $ sudo docker build -t busybox:latest + ``` + +2. 通过以下命令可以看到这个生成的image: + + ```bash + docker images | grep busybox + ``` + +## history + +用法:**docker history \[OPTIONS\] IMAGE** + +功能:显示一个image的变化历史 + +选项: + +-H, \--human=true + +\--no-trunc=false 不对输出进行删减 + +-q, \--quiet=false 只显示ID + +示例: + +```bash +$ sudo docker history busybox:test +IMAGE CREATED CREATED BY SIZE COMMENT +be4672959e8b 15 minutes ago bash 23B +21970dfada48 4 weeks ago 128MB Imported from - +``` + +## images + +用法:**docker images \[OPTIONS\] \[NAME\]** + +功能:列出存在的image,不加选项时不显示中间的image + +选项: + +-a, \--all=false 显示所有的镜像, + +-f, \--filter=\[\] 指定一个过滤值\(i.e. 'dangling=true'\) + +\--no-trunc=false 不对输出进行删减 + +-q, \--quiet=false 只显示ID + +示例: + +```bash +$ sudo docker images +REPOSITORY TAG IMAGE ID CREATED SIZE +busybox latest e02e811dd08f 2 years ago 1.09MB +``` + +## import + +用法:**docker import URL|- \[REPOSITORY\[:TAG\]\]** + +功能:把包含了一个rootfs的tar包导入为镜像。与docker export相对应。 + +选项:无 + +示例: + +从上文介绍的docker export命令时导出的busybox.tar用docker import命令生成一个新的image + +```bash +$ sudo docker import busybox.tar busybox:test +sha256:a79d8ae1240388fd3f6c49697733c8bac4d87283920defc51fb0fe4469e30a4f +$ sudo docker images +REPOSITORY TAG IMAGE ID CREATED SIZE +busybox test a79d8ae12403 2 seconds ago 1.3MB +``` + +## load + +用法:**docker load \[OPTIONS\]** + +功能:把docker save出来的tar包重新加载一个镜像。与docker save相对应。 + +选项: + +-i, \--input="" + +示例: + +```bash +$ sudo docker load -i busybox.tar +Loaded image ID: sha256:e02e811dd08fd49e7f6032625495118e63f597eb150403d02e3238af1df240ba +$ sudo docker images +REPOSITORY TAG IMAGE ID CREATED SIZE +busybox latest e02e811dd08f 2 years ago 1.09MB +``` + +## login + +用法:**docker login \[OPTIONS\] \[SERVER\]** + +功能:登录到一个镜像服务库,没有指定server时,默认登录到 + +选项: + +-e, \--email="" Email + +-p, \--password="" 密码 + +-u, \--username="" 用户名 + +示例: + +```bash +$ sudo docker login +``` + +## logout + +用法:**docker logout \[SERVER\]** + +功能:从一个镜像服务器中登出,没有指定server时,默认登出 + +选项:无 + +示例: + +```bash +$ sudo docker logout +``` + +## pull + +用法:**docker pull \[OPTIONS\] NAME\[:TAG\]** + +功能:从一个镜像库(官方的或私有的)中拉取一个镜像 + +选项: + +-a, \--all-tags=false 下载一个镜像仓库的所有镜像(一个镜像仓库可以被打多个标签,比如一个busybox镜像库,可能有多个标签如busybox:14.04,busybox:13.10,busybox:latest等,使用-a选项后,将所有标签的busybox镜像拉取下来) + +示例: + +1. 从官方镜像库中拉取nginx镜像 + + ```bash + $ sudo docker pull nginx + Using default tag: latest + latest: Pulling from official/nginx + 94ed0c431eb5: Pull complete + 9406c100a1c3: Pull complete + aa74daafd50c: Pull complete + Digest: sha256:788fa27763db6d69ad3444e8ba72f947df9e7e163bad7c1f5614f8fd27a311c3 + Status: Downloaded newer image for nginx:latest + ``` + + 拉取镜像时会检测所依赖的层是否存在,如果存在就用本地的层。 + +2. 从私有镜像库中拉取镜像 + + 从私有镜像库中拉取Fedora镜像,比如所使用的私有镜像库的地址是192.168.1.110:5000: + + ```bash + $ sudo docker pull 192.168.1.110:5000/fedora + ``` + +## push + +用法:**docker push NAME\[:TAG\]** + +功能:将一个image推送到镜像库中 + +选项:无 + +示例: + +1. 将一个image推送到私有镜像库192.168.1.110:5000中 +2. 将要推送的镜像打标签(docker tag命令将在下文介绍),本例中要推送的镜像为busybox:sshd + + ```bash + $ sudo docker tag ubuntu:sshd 192.168.1.110:5000/busybox:sshd + ``` + +3. 将打好标签的镜像推送到私有镜像库中 + + ```bash + $ sudo docker push 192.168.1.110:5000/busybox:sshd + ``` + + 推送的时候会自动检测所依赖的层在镜像库中是否已存在,如果以存在,跳过该层。 + +## rmi + +用法:**docker rmi \[OPTIONS\] IMAGE \[IMAGE...\]** + +功能:删除一个或多个镜像,如果一个镜像在镜像库中有多个标签,删除镜像的时候只是进行untag操作,当删除的是只有一个标签的镜像时,将依次删除所依赖的层。 + +选项: + +-f, \--force=false 强制删除image + +\--no-prune=false 不删除没有标签的父镜像 + +示例: + +```bash +$ sudo docker rmi 192.168.1.110:5000/busybox:sshd +``` + +## save + +用法:**docker save \[OPTIONS\] IMAGE \[IMAGE...\]** + +功能:保存一个image到一个tar包,输出默认是到STDOUT + +选项: + +-o, \--output="" 输出到文件中而不是STDOUT + +示例: + +```bash +$ sudo docker save -o nginx.tar nginx:latest +$ ls +nginx.tar +``` + +## search + +用法:**docker search \[OPTIONS\] TERM** + +功能:在镜像库中查找特定的镜像 + +选项: + +\--automated=false 显示自动构建的image + +\--no-trunc=false 不对输出进行删减 + +-s, \--stars=0 只显示特定星级以上的image + +示例: + +1. 在官方镜像库中搜寻nginx + + ```bash + $ sudo docker search nginx + NAME DESCRIPTION STARS OFFICIAL AUTOMATED + nginx Official build of Nginx. 11873 [OK] + jwilder/nginx-proxy Automated Nginx reverse proxy for docker con… 1645 [OK] + richarvey/nginx-php-fpm Container running Nginx + PHP-FPM capable of… 739 [OK] + linuxserver/nginx An Nginx container, brought to you by LinuxS… 74 + bitnami/nginx Bitnami nginx Docker Image 70 [OK] + tiangolo/nginx-rtmp Docker image with Nginx using the nginx-rtmp… 51 [OK] + ``` + +2. 在私有镜像库中搜寻busybox,在私有镜像库中搜寻时要加上私有镜像库的地址 + + ```bash + $ sudo docker search 192.168.1.110:5000/busybox + ``` + +## tag + +用法:**docker tag \[OPTIONS\] IMAGE\[:TAG\] \[REGISTRYHOST/\]\[USERNAME/\]NAME\[:TAG\]** + +功能:将一个镜像打标签到一个库中 + +选项: + +-f, \--force=false 如果存在相同的tag名将强制替换原来的image + +示例: + +```bash +$ sudo docker tag busybox:latest busybox:test +``` diff --git a/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/installation-and-configuration-3.md b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/installation-and-configuration-3.md new file mode 100644 index 0000000000000000000000000000000000000000..cfd8332516454b3139b1c2623c339264954f66a9 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/installation-and-configuration-3.md @@ -0,0 +1,405 @@ +# 安装配置 + +本章节主要介绍和开源容器Docker安装相关的重要配置。 + +## 注意事项 + +- Docker容器的安装需要使用root权限。 +- docker-engine rpm包与containerd rpm包、runc rpm包、podman rpm包不能同时安装。因为docker-engine rpm包中已经包含Docker运行所需的所有组件,其中包括containerd、runc、docker二进制,且containerd、runc和podman rpm包也分别提供了对应的二进制,所以重复安装时会出现软件包冲突。 + +## 基本安装配置 + +### 配置daemon参数 + +可以通过在/etc/docker/daemon.json文件中添加配置项自定义配置参数,相关配置项以及如何使用可以通过dockerd --help查看。配置示例如下: + +```sh +cat /etc/docker/daemon.json +{ + "debug": true, + "storage-driver": "overlay2", + "storage-opts": ["overlay2.override_kernel_check=true"] +} +``` + +### daemon运行目录配置 + +用户需要明白重新指定各种运行目录和文件(包括--graph、--exec-root等),可能会存在目录冲突,或文件属性变换,对应用的正常使用造成影响。 + +> ![](./public_sys-resources/icon-notice.gif) **须知:** +> +> 用户指定的目录或文件应为docker专用,避免冲突导致的文件属性变化带来安全问题。 + +- 以--graph为例,当我们使用/new/path/作为daemon新的Root Dir时,如果/new/path/下已经存在文件,且目录或文件名与docker需要使用的目录或文件名冲突(例如: containers、hooks、tmp等目录)时,docker可能会更新原有目录或文件的属性,包括属主、权限等为自己的属主和权限。 + +> ![](./public_sys-resources/icon-notice.gif) **须知:** +> +> 从docker-17.05开始,--graph参数被标记为Deprecated,用新的参数--data-root替代。 + +### daemon自带网络配置 + +- Docker daemon使用--bip参数指定docker0网桥的网段之后,如果在下一次重启的时候去掉--bip参数,docker0网桥会沿用上一次的--bip配置,即使重启之前已经删除docker0网桥。原因是docker会保存网络配置并在下一次重启的时候默认恢复上一次配置。 +- Docker network create 并发创建网络的时候,可以创建具有相同名字的两个网络。原因是docker network是通过id来区分的,name只是个便于识别的别名而已,不保证唯一性。 +- Docker在桥接bridge网络模式下,Docker容器是通过宿主机上的NAT模式,建立与宿主机之外世界的通信。Docker Daemon在启动一个容器时,每在宿主机上映射一个端口都会启动一个docker-proxy进程来实现访问代理。建议用户在使用这种userland-proxy时,只映射必须的端口,减少docker-proxy进行端口映射所消耗的资源。 + +### daemon-umask配置 + +容器主进程和exec进程的默认umask为0022,为了满足安全性需求,避免容器受到攻击,修改runc的实现,将默认umask修改为0027。修改后others群组将无法访问新建文件或目录。 + +docker启动容器时的默认umask值为0027,可以在dockerd启动时,使用--exec-opt native.umask=normal参数将容器启动时的umask修改为0022。 + +> ![](./public_sys-resources/icon-notice.gif) **须知:** +> +> 如果docker create/run也配置了native.umask参数,则以docker create/run中的配置为准。 + +详细的配置见[docker create](./容器管理-4.md#create)和[docker run](./容器管理-4.md#run)章节的参数说明。 + +### daemon启动时间 + +Docker服务由systemd管理,systemd对各个服务的启动时间有限制,如果指定时间内docker服务未能成功启动,则可能由以下原因导致: + +- 如果使用devicemapper且为第一次启动,docker daemon需要对该设备做文件系统初始化操作,而该操作会进行大量磁盘IO操作,在磁盘性能不佳或存在大量IO竞争时,很可能会导致docker daemon启动超时。devicemapper设备只需要初始化一次,后续docker daemon启动时不再需要重复初始化。 +- 如果当前系统资源占用太高,导致系统卡顿,系统所有的操作都会变慢,也可能会出现docker服务启动超时的情况。 +- daemon重启过程中,需要遍历并读取docker工作目录下每一个容器的配置文件、容器init层和可写层的配置,如果当前系统存在过多容器(包含created和exited的容器),并且磁盘读写性能受限,也会出现daemon遍历文件过久导致docker服务启动超时的情况。 + +出现服务启动超时情况,建议对以下两种情况进行排查调整: + +- 容器编排层定期清理不需要的容器,尤其是exited的容器。 +- 结合解决方案的性能要求场景,调整编排层的清理周期和docker服务的启动时间。 + +### 关联组件journald + +重启systemd-journald后需要重启docker daemon。journald通过pipe获取docker daemon的日志,如果journald服务重启,会导致该pipe被关闭,docker的日志写入操作便会触发SIGPIPE信号,该错误信号会导致docker daemon crash。由于忽略该信号影响严重,可能导致后续docker daemon的日志无法记录,因此建议用户在重启journald服务或者journald 异常后主动去重启docker daemon,保证docker日志能够被正常记录,避免daemon crash导致的状态异常。 + +### 关联组件firewalld + +需要在重启或拉起firewalld之后重启docker服务,保证docker服务在firewalld之后启动。 + +- firewalld服务启动会清空当前系统的iptables规则,所以在启动docker daemon过程中,重启firewalld可能会导致docker服务插入iptables规则失败,从而导致docker服务启动失败。 +- docker服务启动后重启firewalld服务,或者状态发生了变化(从启动到停止,或者从停止到启动),会导致docker的iptables规则被删除,创建带端口映射的容器失败。 + +### 关联组件iptables + +docker使用--icc=false选项时,可以限制容器之间互通,但若os自带某些规则,可以造成限制容器之间互通失效,例如: + +```text +Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) +... +0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 +... +0 0 DROP all -- docker0 docker0 0.0.0.0/0 0.0.0.0/0 +... +``` + +在Chain FORWARD中,DROP上面多出了一条ACCEPT icmp的规则,造成加了--icc=false后,容器之间也能ping通,但容器之间如果使用udp/tcp协议,对端仍然是不可达的。 + +因此,在容器os中使用docker,如果需要使用--icc=false选项时,建议先在host上清理一下iptables相关的规则。 + +### 关联组件audit + +docker支持配置audit,但不是强制的。例如: + +```text +-w /var/lib/docker -k docker +-w /etc/docker -k docker +-w /usr/lib/systemd/system/docker.service -k docker +-w /usr/lib/systemd/system/docker.socket -k docker +-w /etc/sysconfig/docker -k docker +-w /usr/bin/docker-containerd -k docker +-w /usr/bin/docker-runc -k docker +-w /etc/docker/daemon.json -k docker +``` + +配置docker的audit,好处在于可以记录更多信息便于审计,但从安全角度来看,它对防攻击并没有实质性的作用。另一方面,audit配置会导致严重的效率问题,可能导致系统卡顿,生产环境中请谨慎使用。 + +下面以“-w /var/lib/docker -k docker”为例,演示docker audit的配置: + +```sh +[root@localhost signal]# cat /etc/audit/rules.d/audit.rules | grep docker -w /var/lib/docker/ -k docker +[root@localhost signal]# auditctl -R /etc/audit/rules.d/audit.rules | grep docker +[root@localhost signal]# auditctl -l | grep docker -w /var/lib/docker/ -p rwxa -k docker +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> -p \[r|w|x|a\] 和-w一起使用,观察用户对这个目录的读、写、执行或者属性变化(如时间戳变化)。这样的话,在/var/lib/docker目录下的任何文件、目录操作,都会打印日志到audit.log中,从而会有太多的日志往audit.log中记录,会严重地影响auditd, 比如内存、cpu占用等,进而影响os的运行。例如:每次执行"ls /var/lib/docker/containers"都会有类似如下日志记录到/var/log/audit/audit.log中。 + +```text +type=SYSCALL msg=audit(1517656451.457:8097): arch=c000003e syscall=257 success=yes exit=3 a0=ffffffffffffff9c a1=1b955b0 a2=90800 a3=0 items=1 ppid=17821 pid=1925 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts6 ses=4 comm="ls" exe="/usr/bin/ls" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="docker"type=CWD msg=audit(1517656451.457:8097): cwd="/root"type=PATH msg=audit(1517656451.457:8097): item=0 name="/var/lib/docker/containers" inode=1049112 dev=fd:00 mode=040700 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:container_var_lib_t:s0 objtype=NORMAL +``` + +### 安全配置seccomp + +在做容器网络性能测试时发现,Docker相对于原生内核namespace性能有所下降,经分析开启seccomp后,系统调用(如:sendto)不会通过system\_call\_fastpath进行,而是调用tracesys,这会带来性能大幅下降。因此,建议在有高性能要求的业务的容器场景下关闭seccomp,示例如下: + +```sh +docker run -itd --security-opt seccomp=unconfined busybox:latest +``` + +### 禁止修改docker-daemon的私有目录 + +不允许对Docker用的根目录(默认/var/lib/docker)和运行时目录(默认/run/docker)以及其文件作任何修改,包括在该目录下删除文件,添加文件,对目录或者文件做软/硬链接,修改文件的属性/权限,修改文件的内容等,如果确实需要做修改,后果自负。 + +### 普通用户大量部署容器场景下的配置注意事项 + +普通用户在OS主机上能创建的进程数的上限,例如:可以在系统中创建配置文件“/etc/security/limits.d/20-nproc.conf”限制;类似的,普通用户在容器里也能创建的进程数的上限,由容器镜像中“/etc/security/limits.d/20-nproc.conf”文件对应的值决定,如下所示: + +```sh +cat /etc/security/limits.conf +* soft nproc 4096 +``` + +当普通用户大量部署容器,导致容器内进程过多资源不够出现报错时,需要把容器镜像“/etc/security/limits.d/20-nproc.conf”文件中如上所示的4096配置值加大。 + +可配置的最大值请参考内核的最大能力,如下: + +```sh +[root@localhost ~]# sysctl -a | grep pid_max +kernel.pid_max = 32768 +``` + +## 存储驱动配置 + +本发行版docker支持overlay2和devicemapper两种存储驱动。由于overlay2较devicemapper而言,拥有更好的性能,建议用户在生产环境中优先考虑。 + +### 配置overlay2存储驱动 + +#### 配置方法 + +docker默认为使用overlay2存储驱动,也可以通过如下两种方式显式指定。 + +- 编辑/etc/docker/daemon.json,通过storage-driver字段显式指定。 + + ```sh + cat /etc/docker/daemon.json + { + "storage-driver": "overlay2" + } + ``` + +- 编辑/etc/sysconfig/docker-storage,通过docker daemon启动参数显式指定。 + + ```sh + cat /etc/sysconfig/docker-storage + DOCKER_STORAGE_OPTIONS="--storage-driver=overlay2" + ``` + +#### 注意事项 + +- 部分容器生命周期管理的操作会报找不到相应的rootfs或者相关的可执行文件。 +- 如果容器的健康检查配置的是执行容器内的可执行文件,也会报错,导致容器的健康检查失败。 + +- 如果将overlay2作为graphdriver,在容器中第一次修改镜像中的文件时,若该文件的大小大于系统剩余的空间,修改将会失败。因为即使修改很小,也要把这个文件完整的拷贝到上层,剩余空间不足导致失败。 +- overlay2文件系统相比普通文件系统天然存在一些行为差异,归纳如下: + - 内核版本 + + overlay2只兼容原生4.0以上内核,建议配合使用ext4文件系统。 + + - Copy-UP性能问题 + + 修改lower层文件会触发文件复制到upper层,其中数据块复制和fsync比较耗时。 + + - rename目录问题 + - 只有源路径和目标路径都在merged层时,才允许rename系统调用,否则rename系统调用会报错-EXDEV。 + - 内核4.10引入了redirect dir特性来修复rename问题,对应内核选项为CONFIG\_OVERLAY\_FS\_REDIRECT\_DIR。 + + 在使用overlay2场景下,对文件系统目录进行重命名时,如果系统配置文件/sys/module/overlay/parameters/redirect\_dir中配置的特性开关为关闭状态,则会导致使用失败;如果用户要使用相关特性,需要用户手动设置/sys/module/overlay/parameters/redirect\_dir为“Y”。 + + - Hard link break问题 + - 当lower层目录中有多个硬链接,在merged层写入数据会触发Copy-UP,导致硬链接断开。 + - 内核4.13引入了index feature来修复这个问题,对应内核选项为 CONFIG\_OVERLAY\_FS\_INDEX。注意这个选项没有前向兼容性,不支持热升级。 + + - st\_dev和st\_ino变化 + + 触发Copy-UP之后,用户只能看到merged层中的新文件,inode会变化。虽然attr和xattr可以复制,但st\_dev和st\_ino具有唯一性,不可复制。这会导致stat和ls查看 到相应的变化。 + + - fd变化 + + Copy-UP之前,以只读模式打开文件得到描述符fd1,Copy-UP之后,打开同名文件得到文件描述符fd2, 二者实际指向不同的文件。向fd2写入的数据不会在fd1中体现。 + +#### 异常场景 + +容器使用配置了overlay2存储驱动的过程中,可能出现挂载点被覆盖的异常情况。例如 + +#### 异常场景-挂载点被覆盖 + +挂载关系:在问题容器的挂载点的下面,存在一个/var/lib/docker/overlay2的挂载点: + +```sh +[root@localhost ~]# mount -l | grep overlay +overlay on /var/lib/docker/overlay2/844fd3bca8e616572935808061f009d106a8748dfd29a0a4025645457fa21785/merged type overlay (rw,relatime,seclabel,lowerdir=/var/lib/docker/overlay2/l/JL5PZQLNDCIBU3ZOG3LPPDBHIJ:/var/lib/docker/overlay2/l/ELRPYU4JJG4FDPRLZJCZZE4UO6,upperdir=/var/lib/docker/overlay2/844fd3bca8e616572935808061f009d106a8748dfd29a0a4025645457fa21785/diff,workdir=/var/lib/docker/overlay2/844fd3bca8e616572935808061f009d106a8748dfd29a0a4025645457fa21785/work) +/dev/mapper/dm-root on /var/lib/docker/overlay2 type ext4 (rw,relatime,seclabel,data=ordered) +``` + +执行部分docker命令会遇到错误,比如: + +```sh +[root@localhost ~]# docker rm 1348136d32 +docker rm: Error response from daemon: driver "overlay2" failed to remove root filesystem for 1348136d32: error while removing /var/lib/docker/overlay2/844fd3bca8e616572935808061f009d106a8748dfd29a0a4025645457fa21785: invalid argument +``` + +此时,在主机侧可以发现对应容器的rootfs找不到,但这并不意味着rootfs丢失,只是被/var/lib/docker/overlay2挂载点覆盖,业务仍然可以正常运行,不受影响。修复方案可以参考如下: + +- 修复方案一 + 1. 确定当前docker所使用graphdriver: + + ```sh + docker info | grep "Storage Driver" + ``` + + 2. 查询当前的挂载点: + + ```text + Devicemapper: mount -l | grep devicemapper + Overlay2: mount -l | grep overlay2 + ``` + + 输出格式为: A on B type C \(D\) + + 其中,A:块设备名称或overlay,B:挂载点,C:文件系统类型,D:挂载属性。 + + 3. 从下往上逐一umount这些挂载点B。 + 4. 然后全部docker restart这些容器,或者删除所有容器。 + 5. 重启docker。 + + ```sh + systemctl restart docker + ``` + +- 修复方案二 + 1. 业务迁移 + 2. 节点重启 + +### 配置devicemapper存储驱动 + +用户如果需要使用devicemapper存储驱动,可以通过如下两种方式显式指定。 + +- 编辑/etc/docker/daemon.json,通过storage-driver字段显式指定。 + + ```sh + cat /etc/docker/daemon.json + { + "storage-driver": "devicemapper" + } + ``` + +- 编辑/etc/sysconfig/docker-storage,通过docker daemon启动参数显式指定。 + + ```sh + cat /etc/sysconfig/docker-storage + DOCKER_STORAGE_OPTIONS="--storage-driver=devicemapper" + ``` + +#### 注意事项 + +- 使用devicemapper必须使用devicemapper+direct-lvm的方式,配置的方法可以参考 +- 配置devicemapper时,如果系统上没有足够的空间给thinpool做自动扩容,请禁止自动扩容功能。 +- 禁止把/etc/lvm/profile/docker-thinpool.profile中如下两个值都改成100。 + + ```text + activation { + thin_pool_autoextend_threshold=80 + thin_pool_autoextend_percent=20 + } + ``` + +- 使用devicemapper时推荐加上--storage-opt dm.use\_deferred\_deletion=true --storage-opt dm.use\_deferred\_removal=true。 +- 使用devicemapper时,容器文件系统推荐使用ext4,需要在docker daemon的配置参数中加 上--storage-opt dm.fs=ext4。 +- 当graphdriver为devicemapper时,如果metadata文件损坏且不可恢复,需要人工介入恢复。禁止直接操作或篡改daemon存储devicemapper的元数据。 +- 使用devicemapper lvm时,异常掉电导致的devicemapper thinpool损坏,无法保证thinpool损坏后可以修复,也不能保证数据的完整性,需重建thinpool。 + +docker daemon开启了user namespace特性,切换devicemapper存储池时的**注意事项** + +- 一般启动容器时,deviceset-metadata文件为:/var/lib/docker/devicemapper/metadata/deviceset-metadata。 +- 使用了user namespace场景下,deviceset-metadata文件使用的是:/var/lib/docker/\{userNSUID.GID\}/devicemapper/metadata/deviceset-metadata。 +- 使用devicemapper存储驱动,容器在user namespace场景和普通场景之间切换时,需要将对应deviceset-metadata文件中的BaseDeviceUUID内容清空;针对thinpool扩容或者重建的场景下,也同样的需要将对应deviceset-metadata文件中的BaseDeviceUUID内容清空,否则docker服务会重启失败。 + +## 强制退出docker相关后台进程的影响 + +### 信号量残留 + +使用devicemapper作为graphdriver时,强制退出强制退出可能导致信号量残留。docker在操作dm的过程中会创建信号量,如果在释放信号量前,daemon被强制退出,可能导致该信号量无法释放,一次强制退出最多泄露一个信号量,泄露概率低。而linux系统有信号量上限限制,当信号量泄露次数达到上限值时将无法创建新的信号量,进而导致docker daemon启动失败。排查方法如下: + +1. 首先查看系统上残留的信号量 + + ```sh + $ ipcs + ------ Message Queues -------- + key msqid owner perms used-bytes messages + ------ Shared Memory Segments -------- + key shmid owner perms bytes nattch status + ------ Semaphore Arrays -------- + key semid owner perms nsems + 0x0d4d3358 238977024 root 600 1 + 0x0d4d0ec9 270172161 root 600 1 + 0x0d4dc02e 281640962 root 600 1 + ``` + +2. 接着用dmsetup查看devicemapper创建的信号量,该信号量集合是上一步中查看到的系统信号量的子集 + + ```sh + dmsetup udevcookies + ``` + +3. 最后查看内核信号量设置上限,第四个值就是当前系统的信号量使用上限 + + ```sh + # cat /proc/sys/kernel/sem + 250 32000 32 128 + ``` + + 如果步骤1中残留的信号量数量与步骤3中看到的信号量上限相等,则是达到上限,此时docker daemon无法正常启动。可以使用下述命令增加信号量使用上限值来让docker恢复启动 + + ```sh + echo 250 32000 32 1024 > /proc/sys/kernel/sem + ``` + + 也可以手动清理devicemapper残留的信号量(下面是清理一分钟以前申请的dm相关信号量) + + ```sh + # dmsetup udevcomplete_all 1 + This operation will destroy all semaphores older than 1 minutes with keys that have a prefix 3405 (0xd4d). + Do you really want to continue? [y/n]: y + 0 semaphores with keys prefixed by 3405 (0xd4d) destroyed. 0 skipped. + ``` + +### 网卡残留 + +使用bridge模式启动容器的过程中,强制退出daemon可能导致网卡残留。使用bridge网络模式,当docker创建容器时,会先在host上创建一对veth,然后再把该网卡信息存到数据库中,如果在创建完成,存到docker的数据库之前,daemon被强制退出,那么该网卡无法被docker关联,下次启动也无法删除(docker本身会清理自己数据库中不用的网卡),从而造成网卡残留。 + +### 重启容器失败 + +容器hook耗时较长,且启动阶段遇到containerd被强制退出,再次执行容器start操作可能失败。容器启动阶段遇到containerd被强制退出,docker start操作直接返回错误;containerd被重新拉起后,上次启动可能仍处于runc create执行阶段(执行用户自定义hook,可能耗时较长),此时再次下发docker start命令启动该容器,可能提示以下错误: + +```text +Error response from daemon: oci runtime error: container with id exists: xxxxxx +``` + +该错误是由runc create一个已经存在(创建中)的容器导致,等第一次start对应的runc操作结束后再次执行docker start便可以成功。 + +由于hook的执行不受docker控制,这种场景下尝试回收该容器有可能导致containerd进程启动卡死(执行未知hook程序),且问题的风险可控(短期影响当前容器的创建): + +- 问题出现后等待第一次操作结束可以再次成功启动该容器。 +- 一般是在容器启动失败后创建新的容器,不复用已经失败的容器。 + +综上,该问题暂时作为场景约束。 + +### 服务无法正常重启 + +短时间内频繁重启docker服务导致该服务无法正常重启。docker系统服务由systemd负责监控,如果docker服务在10s内重启次数超过5次,systemd服务就会监控到该异常行为,因此会禁止docker服务启动。只有等到下一个10s周期开始后,docker服务才能响应重启命令正常重启。 + +## 系统掉电影响 + +主机意外掉电或系统panic等场景下,由于docker daemon的状态无法及时刷新到磁盘,导致重启后docker daemon状态不正常,可能出现的问题有(包括但不限于): + +- 掉电前创建的容器,重启后docker ps -a看不到,该问题是因为该容器的状态文件没有刷新到磁盘,从而导致重启后daemon无法获取到该容器的状态(镜像、卷、网络等也可能会有类似问题)。 +- 掉电前某个文件正处于写入状态,尚未完全写入,重启后daemon重新加载该文件发现文件格式不正常或内容不完整,导致重启加载出错。 +- 针对掉电时会破坏docker DB的情况,在重启节点时会清理data-root下面的db文件。因此重启前创建的如下信息在重启后会被删除: + - network,用docker network创建的资源会在重启后清除。 + - volume,用 docker volume创建的资源会在重启后删除。 + - 构建缓存,构建缓存信息会在重启后删除。 + - containerd保存的元数据,由于启动容器会重建containerd元数据,重启节点会清理containerd中保存的元数据。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > + > 用户若选择采用手动清理恢复环境的方式,可通过配置环境变量“DISABLE\_CRASH\_FILES\_DELETE=true”屏蔽daemon掉电重启时db文件清理功能。 diff --git a/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/overview.md b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..546243d3a4cc7ed9aa958eff7bc7f78fc70e72a3 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/overview.md @@ -0,0 +1,7 @@ +# Docker容器 + +Docker是一个开源的Linux容器引擎项目, 用以实现应用的快速打包、部署和交付。Docker的英文本意是码头工人,码头工人的工作就是将商品打包到container\(集装箱\)并且搬运container、装载container。 对应到Linux中,Docker就是将app打包到container,通过container实现app在各种平台上的部署、运行。Docker通过Linux Container技术将app变成一个标准化的、可移植的、自管理的组件,从而实现应用的“一次构建,到处运行”。Docker技术特点就是:应用快速发布、部署简单、管理方便,应用密度更高。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> Docker容器的安装和使用需要root权限。 diff --git a/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-caution.gif b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-caution.gif differ diff --git a/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-danger.gif b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-danger.gif differ diff --git a/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-note.gif b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-notice.gif b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-notice.gif differ diff --git a/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-tip.gif b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-tip.gif differ diff --git a/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-warning.gif b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/public_sys-resources/icon-warning.gif differ diff --git a/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/statistics.md b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/statistics.md new file mode 100644 index 0000000000000000000000000000000000000000..d688f5d71f965a0b05ab2225f0845525c4c277e2 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/DockerEngine/statistics.md @@ -0,0 +1,97 @@ +# 统计信息 + +## events + +用法:**docker events \[OPTIONS\]** + +功能:从docker daemon中获取实时事件 + +选项: + +\--since="" 显示指定时间戳之后的事件 + +\--until="" 显示直到指定时间戳的事件 + +示例: + +该示例中,执行docker events后,用docker run创建并启动一个容器,docker events将输出create事件和start事件。 + +```sh +$ sudo docker events +2019-08-28T16:23:09.338838795+08:00 container create 53450588a20800d8231aa1dc4439a734e16955387efb5f259c47737dba9e2b5e (image=busybox:latest, name=eager_wu) +2019-08-28T16:23:09.339909205+08:00 container attach 53450588a20800d8231aa1dc4439a734e16955387efb5f259c47737dba9e2b5e (image=busybox:latest, name=eager_wu) +2019-08-28T16:23:09.397717518+08:00 network connect e2e20f52662f1ee2b01545da3b02e5ec7ff9c85adf688dce89a9eb73661dedaa (container=53450588a20800d8231aa1dc4439a734e16955387efb5f259c47737dba9e2b5e, name=bridge, type=bridge) +2019-08-28T16:23:09.922224724+08:00 container start 53450588a20800d8231aa1dc4439a734e16955387efb5f259c47737dba9e2b5e (image=busybox:latest, name=eager_wu) +2019-08-28T16:23:09.924121158+08:00 container resize 53450588a20800d8231aa1dc4439a734e16955387efb5f259c47737dba9e2b5e (height=48, image=busybox:latest, name=eager_wu, width=210) +``` + +## info + +用法:**docker info** + +功能:显示docker系统级的相关信息,包括系统中的Container数量、Image数量、Image的存储驱动、容器的执行驱动、内核版本、主机操作系统版本等信息。 + +选项:无 + +示例: + +```sh +$ sudo docker info +Containers: 4 + Running: 3 + Paused: 0 + Stopped: 1 +Images: 45 +Server Version: 18.09.0 +Storage Driver: devicemapper + Pool Name: docker-thinpool + Pool Blocksize: 524.3kB + Base Device Size: 10.74GB + Backing Filesystem: ext4 + Udev Sync Supported: true + Data Space Used: 11GB + Data Space Total: 51GB + Data Space Available: 39.99GB + Metadata Space Used: 5.083MB + Metadata Space Total: 532.7MB + Metadata Space Available: 527.6MB + Thin Pool Minimum Free Space: 5.1GB + Deferred Removal Enabled: true + Deferred Deletion Enabled: true + Deferred Deleted Device Count: 0 +...... +``` + +## version + +用法:**docker version** + +功能:显示docker的版本信息,包括Client版本、Server版本、Go版本、OS/Arch等信息 + +选项:无 + +示例: + +```sh +$ sudo docker version +Client: + Version: 18.09.0 + EulerVersion: 18.09.0.48 + API version: 1.39 + Go version: go1.11 + Git commit: cbf6283 + Built: Mon Apr 1 00:00:00 2019 + OS/Arch: linux/arm64 + Experimental: false + +Server: + Engine: + Version: 18.09.0 + EulerVersion: 18.09.0.48 + API version: 1.39 (minimum version 1.12) + Go version: go1.11 + Git commit: cbf6283 + Built: Mon Apr 1 00:00:00 2019 + OS/Arch: linux/arm64 + Experimental: false +``` diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/_menu.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..557ee68b66358561d792d7403ef4b16be11347b7 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/_menu.md @@ -0,0 +1,56 @@ +--- +label: 'iSula容器引擎' +ismanual: 'Y' +description: '在iSula是使用C/C++实现的容器引起,具有轻、灵、巧、快的特点' +children: + - label: '概述' + href: './overview.md' + - label: '安装、升级与卸载' + href: './installation-upgrade-Uninstallation.md' + children: + - label: '安装与配置' + href: './installation-configuration.md' + - label: '升级' + href: './upgrade-methods.md' + - label: '卸载' + href: './uninstallation.md' + - label: '使用指南' + href: './application-scenarios.md' + children: + - label: '容器管理' + href: './container-management.md' + - label: '支持CNI网络' + href: './interconnection-with-the-cni-network.md' + - label: '容器资源管理' + href: './container-resource-management.md' + - label: '特权容器' + href: './privileged-container.md' + - label: 'CRI-v1alpha2接口' + href: './cri.md' + - label: 'CRI-v1接口' + href: './cri-2.md' + - label: '镜像管理' + href: './image-management.md' + - label: '容器健康状态检查' + href: './checking-the-container-health-status.md' + - label: '查询信息' + href: './querying-information.md' + - label: '安全特性' + href: './security-features.md' + - label: '支持OCI hooks' + href: './supporting-oci-hooks.md' + - label: '本地卷管理' + href: './local-volume-management.md' + - label: 'iSulad shim v2 对接 StratoVirt' + href: './interconnecting-isula-shim-v2-with-stratovirt.md' + - label: 'iSulad支持cgroup v2' + href: './isulad-support-cgroup-v2.md' + - label: 'iSulad支持CDI' + href: './isulad-support-cdi.md' + - label: 'iSulad支持NRI' + href: './isulad-support-nri.md' + - label: '常见问题与解决方法' + href: './isula-faqs.md' + - label: '附录' + href: './appendix.md' +--- diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/appendix.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/appendix.md new file mode 100644 index 0000000000000000000000000000000000000000..8347bcb6b6cdfe60e6b86d7891a937caa3d2450b --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/appendix.md @@ -0,0 +1,885 @@ +# 附录 + +- [附录](#附录.md) + - [命令行参数说明](#命令行参数说明) + - [CNI配置参数](#cni配置参数) + +## 命令行参数说明 + +**表 1** login命令参数列表 + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

login

+

  

+

  

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

--help

+

打印帮助信息

+

-p, --password

+

登录镜像仓库的密码

+

--password-stdin

+

从标准输入获取仓库的密码

+

-u, --username

+

登录镜像仓库的用户名

+
+ +
+ +**表 2** logout命令参数列表 + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

logout

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

--help

+

打印帮助信息

+
+ +
+ +**表 3** pull命令参数列表 + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

pull

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

--help

+

打印帮助信息

+
+ +
+ +**表 4** rmi命令参数列表 + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

rmi

+

  

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

--help

+

打印帮助信息

+

-D, --debug

+

开启调试模式

+

-f, --force

+

强制移除镜像

+
+ +
+ +**表 5** load命令参数列表 + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

load

+

-H, --host (仅 isula支持)

+

指定要连接的iSulad socket文件路径

+

--help

+

打印帮助信息

+

-D, --debug

+

开启调试模式

+

-i, --input

+

指定从哪里导入镜像。如果是docker类型,则为镜像压缩包路径,如果是embedded类型,则为镜像manifest路径。

+

--tag

+

不使用默认的镜像名称,而是使用TAG指定的名称,type为docker类型时支持该参数

+
+ +
+ +**表 6** images命令参数列表 + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

images

+

  

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

--help

+

打印帮助信息

+

-D, --debug

+

开启调试模式

+

-f, --filter

+

过滤出指定镜像信息

+

-q, --quit

+

只显示镜像名字

+
+ +
+ +**表 7** inspect命令参数列表 + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

inspect

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

--help

+

打印帮助信息

+

-D, --debug

+

开启调试模式

+

-f, --format

+

使用模板格式化输出

+

-t, --time

+

超时时间的秒数,若在该时间内inspect查询容器信息未执行成功,则停止等待并立即报错,默认为120秒,当配置小于等于0的值,表示不启用timeout机制inspect查询容器信息会一直等待,直到获取容器信息成功后返回。

+
+ +**表 8** tag命令参数列表 + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

tag

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

--help

+

打印帮助信息

+

-D, --debug

+

开启调试模式

+
+ +
+ +**表 9** import命令参数列表 + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

import

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

--help

+

打印帮助信息

+

-D, --debug

+

开启调试模式

+
+ +
+ +**表 10** export命令参数列表 + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

export

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

--help

+

打印帮助信息

+

-D, --debug

+

开启调试模式

+

-o, --output

+

导出到指定文件

+
+ +
+ +## CNI配置参数 + +**表 1** CNI单网络配置参数 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

类型

+

是否可选

+

说明

+

cniVersion

+

string

+

必选

+

CNI版本号,当前只支持0.3.0,0.3.1。

+

name

+

string

+

必选

+

网络名称,由用户自定义,需保证唯一。

+

type

+

string

+

必选

+

网络类型。目前支持的网络类型:

+

underlay_ipvlan

+

overlay_l2

+

underlay_l2

+

vpc-router

+

dpdk-direct

+

phy-direct

+

ipMasq

+

bool

+

可选

+

设置IP masquerade

+

ipam

+

结构体

+

可选

+

详细定义参考IPAM参数定义

+

ipam.type

+

string

+

可选

+

IPAM类型,目前支持的类型:

+

(1)underlay_l2、overlay_l2、vpc-router组网缺省值distributed_l2,且只支持distributed_l2。

+

(2)underlay_ipvlan组网,默认distributed_l2。CCN场景只支持null、fixed;CCE和FST 5G core场景只支持null、distributed_l2。

+

(3)phy-direct、dpdk-direct组网,默认l2,可选null、distributed_l2。FST 5G core场景只支持null、distributed_l2。

+

说明:

+

超出选择范围(比如host-local),Canal会自动设置为默认,不会返回错误。

+

null:不使用canal管理ip。

+

fixed:固定ip,CCN场景使用。

+

l2:目前没有场景使用。

+

distributed_l2:使用分布式小子网管理ip。

+

ipam.subnet

+

string

+

可选

+

子网信息。Canal支持的subnet mask范围为[8,29],并且要求IP地址不能为Multicast地址(如224.0.0.0/4),保留地址(240.0.0.0/4),本地link地址(169.254.0.0/16)以及本地loop地址(127.0.0.0/8)。

+

ipam.gateway

+

string

+

可选

+

网关IP

+

ipam.range-start

+

string

+

可选

+

可用的起始IP地址

+

ipam.range-end

+

string

+

可选

+

可用的结束IP地址

+

ipam.routes

+

结构体

+

可选

+

subnet列表,每个元素都是一个route字典。参考route定义.

+

ipam.routes.dst

+

string

+

可选

+

表示目的网络

+

ipam.routes.gw

+

string

+

可选

+

表示网关地址

+

dns

+

结构体

+

可选

+

包含一些DNS的特殊值。

+

dns.nameservers

+

[]string

+

可选

+

nameservers

+

dns.domain

+

string

+

可选

+

domain

+

dns.search

+

[]string

+

可选

+

search

+

dns.options

+

[]string

+

可选

+

选项

+

multi_entry

+

int

+

可选

+

表示一个vnic需要的ip数量,范围0~16。对于物理直通,单个网卡最多可申请128个IP。

+

backup_mode

+

bool

+

可选

+

表示主备模式,仅用于phy-direct和dpdk-direct组网。

+

vlanID

+

int

+

可选

+

0~4095,允许PaaS直接指定。

+

vlan_inside

+

bool

+

可选

+

true表示vlan功能由Node内部实现,false表示vlan在外部实现。

+

vxlanID

+

int

+

可选

+

0~16777215,允许PaaS直接指定。

+

vxlan_inside

+

bool

+

可选

+

true表示vlan功能由Node内部实现,false表示vlan在外部实现。

+

action

+

string

+

可选

+

该参数只能和特殊containerID “000000000000”一起使用。

+

Create表示创建网络。

+

Delete表示删除网络。

+

args

+

map[string]interface{}

+

可选

+

主要描述键值对类型。表2

+

runtimeConfig

+

结构体

+

可选

+

+

capabilities

+

结构体

+

可选

+

+
+ +
+ +**表 2** CNI args参数表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

类型

+

是否可选

+

说明

+

K8S_POD_NAME

+

string

+

可选

+

申请固定IP(runtimeConfig.ican_caps.fixed_ip为true)时需要设置K8S_POD_NAME

+

K8S_POD_NAMESPACE

+

string

+

可选

+

申请固定IP(runtimeConfig.ican_caps.fixed_ip为true)时需要设置K8S_POD_NAMESPACE

+

SECURE_CONTAINER

+

string

+

可选

+

安全容器标志

+

multi_port

+

int

+

可选

+

缺省值为1,取值范围1-8。只支持phy-direct和dpdk-direct两种类型网络,指定直通网卡数量

+

phy-direct

+

string

+

可选

+

用于在创建硬直通容器网络时指定接入的网卡

+

dpdk-direct

+

string

+

可选

+

用于在创建dpdk直通容器网络时指定接入的网卡

+

tenant_id

+

string

+

可选

+

租户的ID。

+

只支持vpc-router类型网络。

+

vpc_id

+

string

+

可选

+

VPC的ID。

+

只支持vpc-router类型网络。

+

secret_name

+

string

+

可选

+

表示k8s apiserver中保存有ak sk的对象名。

+

只支持vpc-router类型网络

+

参考配置VPC-Router逻辑网络

+

IP

+

string

+

可选

+

用户指定ip地址,格式“192.168.0.10”

+

K8S_POD_NETWORK_ARGS

+

string

+

可选

+

指定ip地址,格式“192.168.0.10”。若args中IP和K8S_POD_NETWORK_ARGS都不为空,以K8S_POD_NETWORK_ARGS为准。

+

INSTANCE_NAME

+

string

+

可选

+

INSTANCE ID。

+

参考支持容器固定IP

+

dist_gateway_disable

+

bool

+

可选

+

true表示不创建gateway,false表示创建gateway。

+

phynet

+

string或[]string

+

可选

+

所需加入的物理平面信息,为预先定义好的物理网络名称,与SNC体系中的呼应,输入两个平面名时,支持主备平面。例如:"phy_net1" 或 ["phy_net2","phy_net3"]

+

endpoint_policies

+

struct

+

可选

+

"endpoint_policies": [

+

{

+

"Type": "",

+

"ExceptionList": [

+

""

+

],

+

"NeedEncap": true,

+

"DestinationPrefix": ""

+

}

+

]

+

port_map

+

struct

+

可选

+

NAT类型网络中,支持容器端口发布至主机端口。

+

"port_map": [

+

{

+

"local_port": number,

+

"host_port": number,

+

"protocol": [string…]

+

}...

+

]

+
+ +
+ +**表 3** CNI多网络配置参数 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

类型

+

是否可选

+

说明

+

cniVersion

+

string

+

必选

+

CNI版本号,当前只支持0.3.0,0.3.1。

+

name

+

string

+

必选

+

网络名称,由用户自定义,需保证唯一。

+

plugins

+

struct

+

必选

+

具体配置请参见表1 CNI单网络配置参数

+
diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/application-scenarios.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/application-scenarios.md new file mode 100644 index 0000000000000000000000000000000000000000..8a9147aa3754ec51b829cc39be0d568921c3c9bb --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/application-scenarios.md @@ -0,0 +1,5 @@ +# 使用指南 + +本章介绍iSula容器引擎的使用方法。 +>![](./public_sys-resources/icon-note.gif) **说明:** +>iSulad的所有使用操作均需要使用root权限。 diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/checking-the-container-health-status.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/checking-the-container-health-status.md new file mode 100644 index 0000000000000000000000000000000000000000..4901650f20be00808efa0e3b27762bd86ddf75d9 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/checking-the-container-health-status.md @@ -0,0 +1,67 @@ +# 容器健康状态检查 + +- [容器健康状态检查](#容器健康状态检查) + - [场景说明](#场景说明) + - [配置方法](#配置方法) + - [检查规则](#检查规则) + - [使用限制](#使用限制) + +## 场景说明 + +在实际的生产环境中,开发者提供的应用程序或者平台提供的服务难免存在bug,因此,一套管理系统对运行的应用程序进行周期性的健康检查和修复就是不可或缺的。容器健康检查机制便添加了用户定义的对容器进行健康检查的功能。在容器创建时配置\--health-cmd选项,在容器内部周期性地执行命令,通过命令的返回值来监测容器的健康状态。 + +## 配置方法 + +在容器启动时的配置: + +```bash +isula run -itd --health-cmd "echo iSulad >> /tmp/health_check_file || exit 1" --health-interval 5m --health-timeout 3s --health-exit-on-unhealthy busybox bash +``` + +可配置的选项: + +- \--health-cmd,必选,在容器内执行的命令。返回值为0表示成功,非0表示失败。 +- \--health-interval,默认 30s,最大为int64上限(纳秒),自定义配置最小值1s,相邻两次命令执行的间隔时间(注:入参0s时视为default)。 +- \--health-timeout,默认 30s,最大为int64上限(纳秒),自定义配置最小值1s,单次检查命令执行的时间上限,超时则任务命令执行失败(注:入参0s时视为default)。 +- \--health-start-period,默认 0s,最大为int64上限(纳秒),自定义配置最小值1s,容器初始化时间。 +- \--health-retries,默认 3,最大为int32上限,健康检查失败最大的重试次数。 +- \--health-exit-on-unhealthy,默认false,检测到容器非健康时是否杀死容器。 + +## 检查规则 + +1. 容器启动后,容器状态中显示health:starting。 +2. 经过start-period时间后开始,以interval为间隔周期性在容器中执行CMD。即:当一次命令执行完毕后,经过interval时间,执行下一次命令。 +3. 若CMD命令在timeout限制的时间内执行完毕,并且返回值为0,则视为一次检查成功。否则视为一次检查失败。检查成功后,容器状态变为health:healthy。 +4. 若CMD命令连续retries次检查失败,则容器状态变为health:unhealthy。失败后容器也会继续进行健康检查。 +5. 容器状态为health:unhealthy时,任意一次检查成功会使得容器状态变为health:healthy。 +6. 设置\--exit-on-unhealthy的情况下,如果容器因为非被杀死退出(退出返回值137)后,健康检查只有容器在重新启动后才会继续生效。 +7. CMD执行完毕或超时时,iSulad daemon会将这次检查的起始时间、返回值和标准输出记录到容器的配置文件中。最多记录5条。此外,容器的配置文件中还存储着健康检查的相关参数。 +8. 运行中的容器的健康检查状态也会被写入容器配置中。通过isula inspect可以看到。 + +```conf +"Health": { + "Status": "healthy", + "FailingStreak": 0, + "Log": [ + { + "Start": "2018-03-07T07:44:15.481414707-05:00", + "End": "2018-03-07T07:44:15.556908311-05:00", + "ExitCode": 0, + "Output": "" + }, + { + "Start": "2018-03-07T07:44:18.557297462-05:00", + "End": "2018-03-07T07:44:18.63035891-05:00", + "ExitCode": 0, + "Output": "" + }, + ...... +} +``` + +## 使用限制 + +- 容器内健康检查的状态信息最多保存5条。会保存最后得到的5条记录。 +- 容器启动时若健康检查相关参数配置为0,则按照缺省值处理。 +- 带有健康检查配置的容器启动后,若iSulad daemon退出,则健康检查不会执行。iSulad daemon再次启动后,正在运行且带有健康检查配置的容器其健康状态会变为starting。之后检查规则同上。 +- 如果健康检查从第一次开始便一直失败,其状态保持与之前一致(starting),直到达到指定失败次数(--health-retries)后变为unhealthy,或者检查成功后变为healthy。 diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/container-management.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/container-management.md new file mode 100644 index 0000000000000000000000000000000000000000..fc891ee4a8ccb45f32fad97630dfadb1b2601338 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/container-management.md @@ -0,0 +1,2476 @@ +# 容器管理 + +## 创建容器 + +### 描述 + +isula create 命令用于创建一个新的容器。容器引擎会使用指定的容器镜像创建容器读写层,或者使用指定的本地rootfs作为容器的运行环境。创建完成后,会将容器的ID输出到标准输出,后续可以使用isula start 命令启动该容器。新创建的容器状态为**inited**状态。 + +### 用法 + +```bash +isula create [OPTIONS] IMAGE [COMMAND] [ARG...] +``` + +### 参数 + +create命令支持参数参考下表。 + +**表 1** create命令参数列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

create

+

  

+

--add-host

+

添加自定义主机到IP的映射(host:ip)

+

--annotation

+

设置容器的annotations。例如支持native.umask选项:

+
--annotation native.umask=normal # 启动的容器umask值为0022
+--annotation native.umask=secure # 启动的容器umask值为0027
+

注意如果没有配置该参数,则使用isulad中的umask配置。

+

--blkio-weight

+

Block IO(相对权重),在10和1000之间,或0禁用(默认为0)

+

--blkio-weight-device

+

Block IO权重(相对设备权重),格式为:DEVICE_NAME: weight,权重值在10到1000之间,或0表示禁用(默认0)

+

--cap-add

+

添加Linux权限功能

+

--cap-drop

+

删除Linux 权限功能

+

--cgroup-parent

+

指定容器cgroup父路径

+

--cpu-period

+

限制CPU CFS(完全公平调度器)的期限

+

--cpu-quota

+

限制CPU CFS(完全公平调度器)的配额

+

--cpu-rt-period

+

限制CPU实时周期(以微秒为单位)

+

--cpu-rt-runtime

+

限制CPU实时运行时间(以微秒为单位)

+

--cpu-shares

+

CPU份额(相对权重)

+

--cpus

+

CPU数量

+

--cpuset-cpus

+

允许执行的CPU(e.g. 0-3,0,1)

+

--cpuset-mems

+

允许执行的内存(0-3,0,1)

+

--device

+

为容器添加一个主机设备

+

--device-cgroup-rule

+

向cgroup允许的设备列表中添加一条规则

+

--device-read-bps

+

从设备限制读取速率(每秒字节数)

+

--device-read-iops

+

从设备限制读取速率(每秒IO)

+

--device-write-bps

+

限制设备的写入速率(每秒字节数)

+

--device-write-iops

+

限制写入到设备的速率(IO每秒)

+

--dns

+

添加DNS服务器

+

--dns-opt

+

添加DNS选项

+

--dns-search

+

设定容器的搜索域

+

--entrypoint

+

启动容器时要运行的入口点

+

-e, --env

+

设置环境变量

+

--env-file

+

通过文件配置环境变量

+

--env-target-file

+

将环境变量导出到rootfs中的目标文件路径

+

--external-rootfs=PATH

+

指定一个不由iSulad管理的rootfs(可以为文件夹或块设备)给容器

+

--files-limit

+

调整容器内能够打开的文件句柄数(-1表示不限制)

+

--group-add=[]

+

指定额外的用户组添加到容器

+

--help

+

打印帮助信息

+

--health-cmd

+

在容器内执行的命令

+

--health-exit-on-unhealthy

+

检测到容器非健康时是否杀死容器

+

--health-interval

+

相邻两次命令执行的间隔时间

+

--health-retries

+

健康检查失败最大的重试次数

+

--health-start-period

+

容器初始化时间

+

--health-timeout

+

单次检查命令执行的时间上限

+

--hook-spec

+

钩子配置文件

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

--host-channel

+

在主机和容器之间创建共享内存

+

-h, --hostname

+

容器主机名称

+

--hugetlb-limit=[]

+

大页文件限制,例如:--hugetlb-limit 2MB:32MB

+

-i, --interactive

+

即使没有连接到容器的标准输入,也要保持容器的标准输入打开

+

--ipc

+

IPC命名空间使用

+

--kernel-memory

+

内核内存限制

+

-l,--label

+

为容器设置标签

+

--lablel-file

+

通过文件设置容器标签

+

--log-driver

+

记录容器的驱动程序

+

--log-opt=[]

+

日志驱动程序选项,默认禁用记录容器串口日志功能,可以通过"--log-opt disable-log=false"来开启。

+

-m, --memory

+

内存限制

+

--memory-reservation

+

设置容器内存限制,默认与--memory一致。可认为--memory是硬限制,--memory-reservation是软限制;当使用内存超过预设值时,会动态调整(系统回收内存时尝试将使用内存降低到预设值以下),但不确保一定不超过预设值。一般可以和--memory一起使用,数值小于--memory的预设值,最小设置为4MB。

+

--memory-swap

+

正整数,内存 + 交换空间,-1 表示不限制

+

--memory-swappiness

+

正整数,swappiness参数值可设置范围在0到100之间。 此参数值越低,就会让Linux系统尽量少用swap分区,多用内存;参数值越高就是反过来,使内核更多的去使用swap空间,缺省值为-1,表示使用系统缺省值。

+

--mount

+

挂载主机目录/卷/文件系统到容器中

+

--name=NAME

+

容器名

+

--net=none

+

容器连接到网络

+

--no-healthcheck

+

禁用健康检查配置

+

--ns-change-opt

+

系统容器的命名空间内核参数选项

+

--oom-kill-disable

+

禁用OOM

+

--oom-score-adj

+

调整主机的OOM偏好设置(-1000至1000)

+

--pid

+

要使用的PID命名空间

+

--pids-limit

+

调整容器内能够执行的进程数(-1表示不限制)

+

--privileged

+

给予容器扩展的特权

+

--pull

+

运行前拉取镜像

+

-R, --runtime

+

容器运行时,参数支持"lcr",忽略大小写,因此"LCR"和"lcr"是等价的

+

--read-only

+

设置容器的根文件系统为只读

+

--restart

+

当容器退出时重启策略

+

系统容器支持--restart on-reboot

+

--security-opt

+

安全选项

+

--shm-size

+

/dev/shm的大小,缺省值为64MB

+

--stop-signal

+

信号停止容器,默认情况下为SIGTERM

+

--storage-opt

+

配置容器的存储驱动选项

+

--sysctl

+

设置sysctl选项

+

--system-container

+

启动系统容器

+

--tmpfs

+

挂载tmpfs目录

+

-t, --tty

+

分配伪终端

+

--ulimit

+

为容器设置ulimit限制

+

-u, --user

+

用户名或UID,格式[<name|uid>][:<group|gid>]

+

--user-remap

+

映射用户到容器(用于系统容器)

+

--userns

+

启用'user-remap'选项时,为容器设置用户命令空间

+

--uts

+

设置PID namespace

+

-v, --volume=[]

+

挂载一个卷

+

--volumes-from=[]

+

使用指定的容器的挂载配置

+

--workdir

+

设置容器内的工作目录

+
+ +### 约束限制 + +- 使用--user或--group-add参数,在容器启动阶段校验user或group时,容器如果使用的是OCI镜像,是从镜像的真实rootfs的etc/passwd和etc/group文件中校验,如果使用的是rootfs文件夹或块设备作为容器的rootfs,则校验的是host中的etc/passwd和etc/group文件;查找时使用的rootfs会忽略-v 和--mount等挂载参数,意味着使用这些参数尝试覆盖etc/passwd和etc/group两个文件时,在查找阶段不生效,只在容器真正启动时生效。生成的配置保存在"iSulad根目录/engine/容器ID/start\_generate\_config.json",文件格式如下: + + ```conf + { + "uid": 0, + "gid": 8, + "additionalGids": [ + 1234, + 8 + ] + } + ``` + +### 示例 + +创建一个新容器 + +```bash +# isula create busybox +fd7376591a9c3d8ee9a14f5d2c2e5255b02cc44cddaabca82170efd4497510e1 +# isula ps -a +STATUS PID IMAGE COMMAND EXIT_CODE RESTART_COUNT STARTAT FINISHAT RUNTIME ID NAMES +inited - busybox "sh" 0 0 - - lcr fd7376591a9c fd7376591a9c4521... +``` + +## 启动容器 + +### 描述 + +isula start命令用于启动一个或多个容器。 + +### 用法 + +```bash +isula start [OPTIONS] CONTAINER [CONTAINER...] +``` + +### 参数 + +start命令支持参数参考下表。 + +**表 1** start命令参数列表 + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

start

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-a, --attach

+

连接到容器的STDOUT和STDERR

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+
+ +### 示例 + +启动一个新容器 + +```bash +# isula start fd7376591a9c3d8ee9a14f5d2c2e5255b02cc44cddaabca82170efd4497510e1 +``` + +## 运行容器 + +### 描述 + +isula run命令命令用于创建一个新的容器。会使用指定的容器镜像创建容器读写层,并且为运行指定的命令做好准备。创建完成后,使用指定的命令启动该容器。run命令相当于create然后start容器。 + +### 用法 + +```bash +isula run [OPTIONS] ROOTFS|IMAGE [COMMAND] [ARG...] +``` + +### 参数 + +run命令支持参数参考下表。 + +**表 1** run命令参数列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

run

+

--annotation

+

设置容器的annotations。例如支持native.umask选项:

+
--annotation native.umask=normal # 启动的容器umask值为0022
+--annotation native.umask=secure # 启动的容器umask值为0027
+

注意如果没有配置该参数,则使用isulad中的umask配置。

+

--add-host

+

添加自定义主机到IP的映射(host:ip)

+

--blkio-weight

+

Block IO(相对权重),在10和1000之间,或0禁用(默认为0)

+

--blkio-weight-device

+

Block IO权重(相对设备权重),格式为:DEVICE_NAME: weight,权重值在10到1000之间,或0表示禁用(默认0)

+

--cap-add

+

添加Linux功能

+

--cap-drop

+

删除Linux功能

+

--cgroup-parent

+

指定容器cgroup父路径

+

--cpu-period

+

限制CPU CFS(完全公平调度器)的期限

+

--cpu-quota

+

限制CPU CFS(完全公平调度器)的配额

+

--cpu-rt-period

+

限制CPU实时周期(以微秒为单位)

+

--cpu-rt-runtime

+

限制CPU实时运行时间(以微秒为单位)

+

--cpu-shares

+

CPU份额(相对权重)

+

--cpus

+

CPU数量

+

--cpuset-cpus

+

允许执行的CPU(e.g. 0-3,0,1)

+

--cpuset-mems

+

允许执行的内存(0-3,0,1)

+

-d, --detach

+

后台运行容器并打印容器ID

+

--device=[]

+

为容器添加一个主机设备

+

--device-cgroup-rule

+

向cgroup允许的设备列表中添加一条规则

+

--device-read-bps

+

从设备限制读取速率(每秒字节数)

+

--device-read-iops

+

从设备限制读取速率(每秒IO)

+

--device-write-bps

+

限制设备的写入速率(每秒字节数)

+

--device-write-iops

+

限制写入到设备的速率(IO每秒)

+

--dns

+

添加DNS服务器

+

--dns-opt

+

添加DNS选项

+

--dns-search

+

设定容器的搜索域

+

--entrypoint

+

启动容器时要运行的入口点

+

-e, --env

+

设置环境变量

+

--env-file

+

通过文件配置环境变量

+

--env-target-file

+

将环境变量导出到rootfs中的目标文件路径

+

--external-rootfs=PATH

+

指定一个不由iSulad管理的rootfs(可以为文件夹或块设备)给容器

+

--files-limit

+

调整容器内能够打开的文件句柄数(-1表示不限制)

+

--group-add=[]

+

指定额外的用户组添加到容器

+

--help

+

打印帮助信息

+

--health-cmd

+

在容器内执行的命令

+

--health-exit-on-unhealthy

+

检测到容器非健康时是否杀死容器

+

--health-interval

+

相邻两次命令执行的间隔时间

+

--health-retries

+

健康检查失败最大的重试次数

+

--health-start-period

+

容器初始化时间

+

--health-timeout

+

单次检查命令执行的时间上限

+

--hook-spec

+

钩子配置文件

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

--host-channel

+

在主机和容器之间创建共享内存

+

-h, --hostname

+

容器主机名称

+

--hugetlb-limit=[]

+

大页文件限制,例如:--hugetlb-limit 2MB:32MB

+

-i, --interactive

+

即使没有连接到容器的标准输入,也要保持容器的标准输入打开

+

--ipc

+

IPC命名空间使用

+

--kernel-memory

+

内核内存限制

+

-l,--label

+

为容器设置标签

+

--lablel-file

+

通过文件设置容器标签

+

--log-driver

+

设置日志驱动,支持syslog和json-file。

+

--log-opt=[]

+

日志驱动程序选项,默认禁用记录容器串口日志功能,可以通过"--log-opt disable-log=false"来开启。

+

-m, --memory

+

内存限制

+

--memory-reservation

+

设置容器内存限制,默认与--memory一致。可认为--memory是硬限制,--memory-reservation是软限制;当使用内存超过预设值时,会动态调整(系统回收内存时尝试将使用内存降低到预设值以下),但不确保一定不超过预设值。一般可以和--memory一起使用,数值小于--memory的预设值,最小设置为4MB。

+

--memory-swap

+

正整数,内存 + 交换空间,-1 表示不限制

+

--memory-swappiness

+

正整数,swappiness参数值可设置范围在0到100之间。 此参数值越低,就会让Linux系统尽量少用swap分区,多用内存;参数值越高就是反过来,使内核更多的去使用swap空间,缺省值为-1,表示使用系统缺省值。

+

--mount

+

挂载主机目录到容器中

+

--name=NAME

+

容器名

+

--net=none

+

容器连接到网络

+

--no-healthcheck

+

禁用健康检查配置

+

--ns-change-opt

+

系统容器的命名空间内核参数选项

+

--oom-kill-disable

+

禁用OOM

+

--oom-score-adj

+

调整主机的OOM偏好设置(-1000至1000)

+

--pid

+

要使用的PID命名空间

+

--pids-limit

+

调整容器内能够执行的进程数(-1表示不限制)

+

--privileged

+

给予容器扩展的特权

+

--pull

+

运行前拉取镜像

+

-R, --runtime

+

容器运行时,参数支持"lcr",忽略大小写,因此"LCR"和"lcr"是等价的

+

--read-only

+

设置容器的根文件系统为只读

+

--restart

+

当容器退出时重启策略

+

系统容器支持--restart on-reboot

+

--rm

+

当容器退出时自动清理容器

+

--security-opt

+

安全选项

+

--shm-size

+

/dev/shm的大小,缺省值为64MB

+

--stop-signal

+

信号停止容器,默认情况下为SIGTERM

+

--storage-opt

+

配置容器的存储驱动选项

+

--sysctl

+

设置sysctl选项

+

--system-container

+

启动系统容器

+

--tmpfs

+

挂载tmpfs目录

+

-t, --tty

+

分配伪终端

+

--ulimit

+

为容器设置ulimit限制

+

-u, --user

+

用户名或UID,格式[<name|uid>][:<group|gid>]

+

--user-remap

+

映射用户到容器(用于系统容器)

+

--userns

+

启用'user-remap'选项时,为容器设置用户命令空间

+

--uts

+

设置PID namespace

+

-v, --volume=[]

+

挂载一个卷

+

--volumes-from=[]

+

使用指定的容器的挂载配置

+

--workdir

+

设置容器内的工作目录

+
+ +### 约束限制 + +- 容器父进程进程退出时,则对应的容器也自动退出。 +- 创建普通容器时父进程不能为init,因为普通容器的权限不够,导致容器可以创建成功,但是attach进去的时候会卡住。 +- 运行容器时,不指定--net,默认hostname为**localhost**。 +- 使用--files-limit参数传入一个很小的值,如1时,启动容器时,iSulad创建cgroup子组后先设置files.limit值,再将容器进程的PID写入该子组的cgroup.procs文件,此时容器进程已经打开超过1个句柄,因而写入报错导致启动失败启动容器会失败。 +- --mount参数和--volume参数同时存在时,如果目的路径有冲突,则--mount会在--volume之后挂载\(即将--volume中的挂载点覆盖掉\)。 + + 备注:轻量级容器的参数中type支持bind或squashfs,当type=squashfs时,src是镜像的路径;原生docker的参数type支持bind、volume、tmpfs。 + +- restart重启策略不支持unless-stopped。 +- 以下三种情况与docker 返回值不一致,docker返回127,轻量级容器返回125 + + --device参数指定主机设备为不存在的设备 + + --hook-spec参数指定不存在的hook json文件 + + --entrypoint 参数指定不存在的入口参数 + +- 使用--volume参数时,由于容器启动时会对/dev/ptmx设备进行删除重建,因此请勿将/dev目录挂载至容器/dev目录,应使用--device对/dev下的设备在容器中进行挂载 +- 使用-it参数时,由于容器启动时会对/dev/ptmx设备进行删除重建,因此请勿将/dev目录挂载至容器/dev目录,应使用--device对/dev下的设备再容器中进行挂载。 +- 禁止使用echo的方式向run命令的stdin输入数据,会导致客户端卡死。应该直接将echo的值作为命令行参数传给容器 + + ```bash + # echo ls | isula run -i busybox /bin/sh + + + ^C + # + ``` + + 上述命令出现客户端卡死现象,这是由于上述命令相当于往stdin输入ls,随后EOF被读取,客户端不再发送数据,等待服务端退出,但是服务端无法区分客户端是否需要继续发送数据,因而服务端卡在read数据上,最终导致双方均卡死。 + + 正确的执行方式为: + + ```bash + # isula run -i busybox ls + bin + dev + etc + home + proc + root + sys + tmp + usr + var + # + ``` + +- 使用host的根目录(/)作为容器的文件系统,那么在挂载路径时,如果有如下情况 + + **表 2** 挂载情况 + + + + + + + + + + + + + +

Host 路径(source)

+

容器路径(dest

+

/home/test1

+

/mnt/

+

/home/test2

+

/mnt/abc

+
+ + > ![](./public_sys-resources/icon-notice.gif) **须知:** + > + > 第一种情况,先挂载/home/test1,然后挂载/home/test2,这种情况会导致/home/test1的内容覆盖掉原来/mnt下面的内容,这样可能导致/mnt下面不存在abc目录,这样会导致挂载/home/test2到/mnt/abc失败。 + > 第二种情况,先挂载/home/test2,然后挂载/home/test1。这种情况,第二次的挂载会把/mnt的内容替换为/home/test1的内容,这样第一次挂载的/home/test2到/mnt/abc的内容就看不到了。 + > 因此,不支持第一种使用方式;第二种使用用户需要了解这种数据无法访问的风险 + +- 请谨慎配置/sys和/proc目录可写。/sys和/proc目录包含了linux维护内核参数、设备管理的接口,容器中配置该目录可写可能会导致容器逃逸。 +- 请谨慎配置容器与host共享namespace。比如—pid,--ipc, --uts,--net配置该参数为容器和host共享namespace空间,容器和host的namespace隔离没有了,在容器中可对host进行攻击。比如,使用—pid 和host共享pid namespace,容器中可以看到host上的进程pid号,可以随意杀死host的进程。 +- 请谨慎配置使用--device、-v 等可以挂载主机资源的参数,请勿将host的敏感目录或者设备,映射到容器中,以防止敏感信息泄漏。 +- 请谨慎使用--privileged选项启动容器,--privileged选项会导致容器权限过大,影响宿主机配置。 + + > ![](./public_sys-resources/icon-notice.gif) **须知:** + > + > 高并发场景(并发启动200容器)下,glibc的内存管理机制会导致内存空洞以及虚拟内存较大(例如10GB)的问题。该问题是高并发场景下glibc内存管理机制的限制,而不是内存泄露,不会导致内存消耗无限增大。可以通过设置MALLOC\_ARENA\_MAX环境变量来减少虚拟内存的问题,而且可以增大减少物理内存的概率。但是这个环境变量会导致iSulad的并发性能下降,需要用户根据实际情况做配置。 + > + > 参考实践情况,平衡性能和内存,可以设置MALLOC_ARENA_MAX为4。(在arm64服务器上面对iSulad的性能影响在10%以内) + > 配置方法: + > 1. 手动启动iSulad的场景,可以直接export MALLOC_ARENA_MAX=4,然后再启动iSulad即可。 + > 2. systemd管理iSulad的场景,可以修改/etc/sysconfig/iSulad,增加一条MALLOC_ARENA_MAX=4即可。 + +### 示例 + +运行一个新容器 + +```bash +# isula run -itd busybox +9c2c13b6c35f132f49fb7ffad24f9e673a07b7fe9918f97c0591f0d7014c713b +``` + +## 停止容器 + +### 描述 + +isula stop命令用于停止一个或多个运行中的容器。首先向容器中的首进程会发送**SIGTERM**信号,在指定时间(默认为10s)内容器未停止时,会发送**SIGKILL**。 + +### 用法 + +```bash +isula stop [OPTIONS] CONTAINER [CONTAINER...] +``` + +### 参数 + +stop命令支持参数参考下表。 + +**表 1** stop命令参数列表 + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

stop

+

-f, --force

+

强制停止正在运行的容器

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+

-t, --time

+

先优雅停止,超过这个时间,则强行终止

+
+ +### 约束限制 + +- 指定t参数且t<0时,请确保自己容器的应用会处理stop信号。 + + Stop的原理:Stop会首先给容器发送Stop 信号(SIGTERM),然后等待一定的时间(这个时间就是用户输入的 t),过了指定时间如果容器还仍处于运行状态,那么就发送kill信号(SIGKILL)使容器强制退出。 + +- 输入参数t的含义: + + t<0 : 表示一直等待,不管多久都等待程序优雅退出,既然用户这么输入了,表示对自己的应用比较放心,认为自己的程序有 合理的stop信号的处理机制。 + + t=0 : 表示不等,立即发送kill -9 到容器。 + + t\>0 : 表示等一定的时间,如果容器还未退出,就发送kill -9 到容器。 + + 所以如果用户使用t<0 (比如t=-1),请确保自己容器的应用会正确处理SIGTERM. 如果容器忽略了该信号,会导致isula stop一直卡住。 + +### 示例 + +停止一个容器 + +```bash +# isula stop fd7376591a9c3d8ee9a14f5d2c2e5255b02cc44cddaabca82170efd4497510e1 +fd7376591a9c3d8ee9a14f5d2c2e5255b02cc44cddaabca82170efd4497510e1 +``` + +## 强制停止容器 + +### 描述 + +isula kill命令用于强制停止一个或多个运行中的容器。 + +### 用法 + +```bash +isula kill [OPTIONS] CONTAINER [CONTAINER...] +``` + +### 参数 + +kill命令支持参数参考下表。 + +**表 1** kill命令参数列表 + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

kill

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+

-s, --signal

+

发送给容器的信号

+
+ +### 示例 + +杀掉一个容器 + +```bash +# isula kill fd7376591a9c3d8ee9a14f5d2c2e5255b02cc44cddaabca82170efd4497510e1 +fd7376591a9c3d8ee9a14f5d2c2e5255b02cc44cddaabca82170efd4497510e1 +``` + +## 删除容器 + +### 描述 + +isula rm命令用于删除一个或多个容器。 + +### 用法 + +```bash +isula rm [OPTIONS] CONTAINER [CONTAINER...] +``` + +### 参数 + +rm命令支持参数参考下表。 + +**表 1** rm命令参数列表 + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

rm

+

-f, --force

+

强制移除正在运行的容器

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-v, --volume

+

移除挂载在容器上的卷(备注:目前iSulad尚不使用此功能)

+
+ +### 约束限制 + +- 在IO正常情况,空环境(只有1个容器)删除一个running容器的时间为T1,200个容器的环境(容器无大量IO操作,host IO正常)删除一个running容器所需时间为T2。T2的规格为:T2 = max \{ T1 \* 3, 5 \} 秒钟。 + +### 示例 + +删除一个停止状态的容器 + +```bash +# isula rm fd7376591a9c3d8ee9a14f5d2c2e5255b02cc44cddaabca82170efd4497510e1 +fd7376591a9c3d8ee9a14f5d2c2e5255b02cc44cddaabca82170efd4497510e1 +``` + +## 接入容器 + +### 描述 + +isula attach命令用于将当前终端的标准输入、标准输出和标准错误连接到正在运行的容器。 + +### 用法 + +```bash +isula attach [OPTIONS] CONTAINER +``` + +### 参数 + +attach命令支持参数参考下表。 + +**表 1** attach命令参数列表 + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

attach

+

--help

+

打印帮助信息

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-D, --debug

+

开启debug模式

+
+ +### 约束限制 + +- 原生docker attach容器会直接进入容器,而isulad attach容器后需要敲一个回车才进入。 + +### 示例 + +接入一个运行状态的容器 + +```bash +# isula attach fd7376591a9c3d8ee9a14f5d2c2e5255b02cc44cddaabca82170efd4497510e1 +/ # +/ # +``` + +## 重命名容器 + +### 描述 + +isula rename命令用于重命名容器。 + +### 用法 + +```bash +isula rename [OPTIONS] OLD_NAME NEW_NAME +``` + +### 参数 + +rename命令支持参数参考下表。 + +**表 1** rename 命令参数列表 + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

rename

+

--help

+

打印帮助信息

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-D, --debug

+

开启debug模式

+
+ +### 示例 + +重命名一个容器 + +```bash +# isula rename my_container my_new_container +``` + +## 在容器中执行新命令 + +### 描述 + +isula exec命令用于正在运行的容器中运行一个新命令。新执行的命令将在容器的默认目录中运行。如果基础镜像指定了自定义目录,则将使用该目录。 + +### 用法 + +```bash +isula exec [OPTIONS] CONTAINER COMMAND [ARG...] +``` + +### 参数 + +exec命令支持参数参考下表。 + +**表 1** exec命令参数列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

exec

+

  

+

-d, --detach

+

后台运行命令

+

-D, --debug

+

开启调试模式

+

-e, --env

+

设置环境变量(备注:目前iSulad尚不使用此功能)

+

--help

+

打印帮助信息

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-i, --interactive

+

没有连接,也要保持标准输入打开(备注:目前iSulad尚不使用此功能)

+

-t, --tty

+

分配伪终端(备注:目前iSulad尚不使用此功能)

+

-u, --user

+

指定用户登录容器执行命令

+

--workdir

+

指定执行命令的工作目录,该功能只有runtime为lcr时才支持

+
+ +### 约束限制 + +- isula exec 不指定任何参数时,会默认使用-it参数, 表示分配一个伪终端,以交互式的方式进入容器 +- 当使用isula exec 执行脚本,在脚本中执行后台进程时,需使用nohup标志忽略SIGHUP信号。 + + 使用isula exec运行脚本,在脚本中运行后台进程需使用nohup标志。否则内核会在exec执行的进程(session首进程)退出时,向后台执行的进程发送SIGHUP信号,导致后台进程退出,出现僵尸进程。 + +- isula exec 进入容器进程后,不能执行后台程序,否则会出现卡死现象。 + + isula exec执行后台进程的方式如下: + + 1. 使用isula exec进入容器终端,isula exec container\_name bash + 2. 进入容器后,执行 script & + 3. 执行exit,导致终端卡死 + + isula exec 进入容器后,执行后台程序卡住的原因为isula exec进入容器运行后台while1程序,当bash退出时,while1程序并不会退出,变为孤儿进程由1号 + 进程接管,while1程序是由容器的初始bash进程fork &exec执行的,while1进程复制了bash进程的文件句柄,导致bash退出时,句柄并未完全关闭,导致 + console进程收不到句柄关闭事件,epoll_wait卡住,进程不退出。 + +- isula exec 不能用后台方式执行,否则可能会出现卡死现象。 + + isula exec后台执行的方式如下: + + 使用**isula exec 脚本 &**的方式后台执行exec,如:isula exec container\_name script & ,isula exec 后台执行,执行的脚本中不断cat某一文件,正常时在当前终端有输出,如果在当前终端执行回车操作,客户端会因读IO失败而退出读stdout的动作,使终端不再输出,服务端由于进程仍然在cat文件,会继续往fifo的buffer里写入数据,当缓存写满时,容器内进程会卡死在write动作上。 + +- 轻量级容器使用exec执行带有管道操作的命令时,建议使用/bin/bash -c 方式执行该命令。 + + 典型应用场景: + + 使用isula exec container\_name -it ls /test | grep "xx" | wc -l,用于统计test目录下xx的文件个数,因exec执行的为"ls /test",其输出通过管道进行grep、wc 处理。exec执行的为"ls /test"的输出会换行,再针对该输出进行处理时,结果有误。 + + 原因:使用exec 执行ls /test,输出带有换行,针对该输出进行“| grep "xx" | wc -l“,处理结果为2(两行) + + ```bash + # isula exec -it container ls /test + xx xx10 xx12 xx14 xx3 xx5 xx7 xx9 + xx1 xx11 xx13 xx2 xx4 xx6 xx8 + # + ``` + + 建议处理方式:使用run/exec执行带有管道操作的命令时,使用/bin/bash -c 执行命令,在容器中执行管道操作。 + + ```bash + # isula exec -it container /bin/sh -c "ls /test | grep "xx" | wc -l" + 15 + # + ``` + +- 禁止使用echo的方式向exec命令的stdin输入数据,会导致客户端卡死。应该直接将echo的值作为命令行参数传给容器 + + ```bash + # echo ls | isula exec 38 /bin/sh + + + ^C + # + ``` + + 上述命令可能出现客户端卡死现象,这是由于上述命令相当于往stdin输入ls,随后EOF被读取,客户端不再发送数据,等待服务端退出,但是服务端无法区分客户端是否需要继续发送数据,因而服务端卡在read数据上,最终导致双方均卡死。 + + 正确的执行方式为: + + ```bash + # isula exec 38 ls + bin dev etc home proc root sys tmp usr var + ``` + +### 示例 + +在运行中的容器中,执行echo命令 + +```bash +# isula exec c75284634bee echo "hello,world" +hello,world +``` + +## 查询单个容器信息 + +### 描述 + +isula inspect提供了容器的详细信息。 + +### 用法 + +```bash +isula inspect [OPTIONS] CONTAINER|IMAGE [CONTAINER|IMAGE...] +``` + +### 参数 + +inspect命令支持参数参考下表。 + +**表 1** inspect命令参数列表 + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

inspect

+

  

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+

-f, --format

+

使用模板格式化输出

+

-t, --time

+

超时时间的秒数,若在该时间内inspect查询容器信息未执行成功,则停止等待并立即报错,默认为120秒,当配置小于等于0的值,表示不启用timeout机制inspect查询容器信息会一直等待,直到获取容器信息成功后返回。

+
+ +### 示例 + +查询容器信息 + +```bash +# isula inspect -f '{{.State.Status} {{.State.Running}}}' c75284634bee +running +true + + +# isula inspect c75284634bee +[ + { + "Id": "c75284634beeede3ab86c828790b439d16b6ed8a537550456b1f94eb852c1c0a", + "Created": "2019-08-01T22:48:13.993304927-04:00", + "Path": "sh", + "Args": [], + "State": { + "Status": "running", + "Running": true, + "Paused": false, + "Restarting": false, + "Pid": 21164, + "ExitCode": 0, + "Error": "", + "StartedAt": "2019-08-02T06:09:25.535049168-04:00", + "FinishedAt": "2019-08-02T04:28:09.479766839-04:00", + "Health": { + "Status": "", + "FailingStreak": 0, + "Log": [] + } + }, + "Image": "busybox", + "ResolvConfPath": "", + "HostnamePath": "", + "HostsPath": "", + "LogPath": "none", + "Name": "c75284634beeede3ab86c828790b439d16b6ed8a537550456b1f94eb852c1c0a", + "RestartCount": 0, + "HostConfig": { + "Binds": [], + "NetworkMode": "", + "GroupAdd": [], + "IpcMode": "", + "PidMode": "", + "Privileged": false, + "SystemContainer": false, + "NsChangeFiles": [], + "UserRemap": "", + "ShmSize": 67108864, + "AutoRemove": false, + "AutoRemoveBak": false, + "ReadonlyRootfs": false, + "UTSMode": "", + "UsernsMode": "", + "Sysctls": {}, + "Runtime": "lcr", + "RestartPolicy": { + "Name": "no", + "MaximumRetryCount": 0 + }, + "CapAdd": [], + "CapDrop": [], + "Dns": [], + "DnsOptions": [], + "DnsSearch": [], + "ExtraHosts": [], + "HookSpec": "", + "CPUShares": 0, + "Memory": 0, + "OomScoreAdj": 0, + "BlkioWeight": 0, + "BlkioWeightDevice": [], + "CPUPeriod": 0, + "CPUQuota": 0, + "CPURealtimePeriod": 0, + "CPURealtimeRuntime": 0, + "CpusetCpus": "", + "CpusetMems": "", + "SecurityOpt": [], + "StorageOpt": {}, + "KernelMemory": 0, + "MemoryReservation": 0, + "MemorySwap": 0, + "OomKillDisable": false, + "PidsLimit": 0, + "FilesLimit": 0, + "Ulimits": [], + "Hugetlbs": [], + "HostChannel": { + "PathOnHost": "", + "PathInContainer": "", + "Permissions": "", + "Size": 0 + }, + "EnvTargetFile": "", + "ExternalRootfs": "" + }, + "Mounts": [], + "Config": { + "Hostname": "localhost", + "User": "", + "Env": [ + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + "TERM=xterm", + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + ], + "Tty": true, + "Cmd": [ + "sh" + ], + "Entrypoint": [], + "Labels": {}, + "Annotations": { + "log.console.file": "none", + "log.console.filerotate": "7", + "log.console.filesize": "1MB", + "rootfs.mount": "/var/lib/isulad/mnt/rootfs", + "native.umask": "secure" + }, + "HealthCheck": { + "Test": [], + "Interval": 0, + "Timeout": 0, + "StartPeriod": 0, + "Retries": 0, + "ExitOnUnhealthy": false + } + }, + "NetworkSettings": { + "IPAddress": "" + } + } +] +``` + +## 查询所有容器信息 + +### 描述 + +isula ps 用于查询所有容器的信息。 + +### 用法 + +```bash +isula ps [OPTIONS] +``` + +### 参数 + +ps命令支持参数参考下表。 + +**表 1** ps命令参数列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

ps

+

  

+

  

+

  

+

  

+

-a, --all

+

显示所有的容器

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-q, --quiet

+

只显示容器名字

+

-f, --filter

+

增加筛选过滤条件

+

--format

+

按照模板声明的方式输出数据

+

--no-trunc

+

不对容器ID进行截断打印

+
+ +### 示例 + +查询所有容器信息 + +```bash +# isula ps -a + +ID IMAGE STATUS PID COMMAND EXIT_CODE RESTART_COUNT STARTAT FINISHAT RUNTIME NAMES +e84660aa059c rnd-dockerhub.huawei.com/official/busybox running 304765 "sh" 0 0 13 minutes ago - lcr e84660aa059cafb0a77a4002e65cc9186949132b8e57b7f4d76aa22f28fde016 +# isula ps -a --format "table {{.ID}} {{.Image}}" --no-trunc +ID IMAGE +e84660aa059cafb0a77a4002e65cc9186949132b8e57b7f4d76aa22f28fde016 rnd-dockerhub.huawei.com/official/busybox + +``` + +## 重启容器 + +### 描述 + +isula restart 用于重启一个或者多个容器。 + +### 用法 + +```bash +isula restart [OPTIONS] CONTAINER [CONTAINER...] +``` + +### 参数 + +restart命令支持参数参考下表。 + +**表 1** restart 命令参数列表 + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

restart

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+

-t, --time

+

先优雅停止,超过这个时间,则强行终止

+
+ +### 约束限制 + +- 指定t参数且t<0时,请确保自己容器的应用会处理stop信号。 + + restart会首先调用stop停止容器。stop会首先给容器发送stop信号(SIGTERM),然后等待一定的时间(这个时间就是用户输入的 t),过了一定时间如果容器仍处于运行状态,那么就发送kill信号(SIGKILL)使容器强制退出。 + +- 输入参数t的含义: + + t<0 : 表示一直等待,不管多久都等待程序优雅退出,既然用户这么输入了,表示对自己的应用比较放心,认为自己的程序有合理的stop信号的处理机制。 + + t=0 : 表示不等,立即发送kill -9 到容器。 + + t\>0 : 表示等一定的时间,如果容器还未退出,就发送kill -9 到容器。 + + 所以如果用户使用t<0(比如t=-1),请确保自己容器的应用会正确处理SIGTERM. 如果容器忽略了该信号,会导致isula restart一直卡住。 + +### 示例 + +重启单个容器 + +```bash +# isula restart c75284634beeede3ab86c828790b439d16b6ed8a537550456b1f94eb852c1c0a + c75284634beeede3ab86c828790b439d16b6ed8a537550456b1f94eb852c1c0a +``` + +## 等待容器退出 + +### 描述 + +isula wait用于等待一个或者多个容器退出。仅支持runtime类型为lcr的容器。 + +### 用法 + +```bash +isula wait [OPTIONS] CONTAINER [CONTAINER...] +``` + +### 参数 + +wait命令支持参数参考下表。 + +**表 1** wait命令参数列表 + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

wait

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+
+ +### 示例 + +等待单个容器退出 + +```bash +# isula wait c75284634beeede3ab86c828790b439d16b6ed8a537550456b1f94eb852c1c0a + 137 +``` + +## 查看容器中进程信息 + +### 描述 + +isula top用于查看容器中的进程信息。 + +### 用法 + +```bash +isula top [OPTIONS] container [ps options] +``` + +### 参数 + +top命令支持参数参考下表。 + +**表 1** top命令参数列表 + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

top

+

  

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+
+ +### 示例 + +查询容器中进程信息 + +```bash +# isula top 21fac8bb9ea8e0be4313c8acea765c8b4798b7d06e043bbab99fc20efa72629c +UID PID PPID C STIME TTY TIME CMD +root 22166 22163 0 23:04 pts/1 00:00:00 sh +``` + +## 查看容器使用的资源 + +### 描述 + +isula stats用于实时显示资源使用的统计信息。 + +### 用法 + +```bash +isula stats [OPTIONS] [CONTAINER...] +``` + +### 参数 + +stats命令支持参数参考下表。 + +**表 1** stats命令参数列表 + + + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

stats

+

  

+

  

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+

-a, --all

+

显示所有容器(默认只显示运行中的容器)

+

--no-stream

+

非流式方式的stats,只打印第一次结果

+

--original

+

显示容器的原始数据信息,不进行统计计算

+
+ +### 示例 + +显示资源使用的统计信息 + +```bash +# isula stats --no-stream 21fac8bb9ea8e0be4313c8acea765c8b4798b7d06e043bbab99fc20efa72629c CONTAINER CPU % MEM USAGE / LIMIT MEM % BLOCK I / O PIDS +21fac8bb9ea8 0.00 56.00 KiB / 7.45 GiB 0.00 0.00 B / 0.00 B 1 +``` + +## 获取容器日志 + +### 描述 + +isula logs用于获取容器的日志。 + +### 用法 + +```bash +isula logs [OPTIONS] [CONTAINER...] +``` + +### 参数 + +logs命令支持参数参考下表。 + +**表 1** logs命令参数列表 + + + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

logs

+

  

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+

-f, --follow

+

跟踪日志输出

+

--tail

+

显示日志行数

+

-t, --timestamps

+

显示时间戳

+
+ +### 约束限制 + +- 容器串口logs日志记录功能,默认为开启状态,需要关闭可以通过 isula create --log-opt disable-log=true 或 isula run --log-opt disable-log=true 关闭。 + +### 示例 + +获取容器日志 + +```bash +# isula logs 6a144695f5dae81e22700a8a78fac28b19f8bf40e8827568b3329c7d4f742406 +hello, world +hello, world +hello, world +``` + +## 容器与主机之间数据拷贝 + +### 描述 + +isula cp 用于容器与主机之间的数据拷贝,仅支持runtime类型为lcr的容器。 + +### 用法 + +```bash +isula cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH +isula cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH +``` + +### 参数 + +cp命令支持参数参考下表。 + +**表 1** cp命令参数列表 + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

cp

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+
+ +### 约束限制 + +- iSulad在执行拷贝时,不会挂载/etc/hostname, /etc/resolv.conf,/etc/hosts三个文件,也不会对--volume和--mount参数传入的参数挂载到host,所以对这些文件的拷贝使用的是镜像中的原始文件,而不是真实容器中的文件。 + + ```bash + # isula cp b330e9be717a:/etc/hostname /tmp/hostname + # cat /tmp/hostname + # + ``` + +- iSulad在解压文件时,不会对文件系统中即将被覆盖的文件或文件夹做类型判断,而是直接覆盖,所以在拷贝时,如果源为文件夹,同名的文件会被强制覆盖为文件夹;如果源为文件,同名的文件夹会被强制覆盖为文件。 + + ```bash + # rm -rf /tmp/test_file_to_dir && mkdir /tmp/test_file_to_dir + # isula exec b330e9be717a /bin/sh -c "rm -rf /tmp/test_file_to_dir && touch /tmp/test_file_to_dir" + # isula cp b330e9be717a:/tmp/test_file_to_dir /tmp + # ls -al /tmp | grep test_file_to_dir + -rw-r----- 1 root root 0 Apr 26 09:59 test_file_to_dir + ``` + +- cp命令仅供维护定位时使用,应避免在生产环境上线使用cp命令。 + +### 示例 + +将主机/test/host目录拷贝到容器21fac8bb9ea8的/test目录下。 + +```bash +isula cp /test/host 21fac8bb9ea8:/test +``` + +将容器21fac8bb9ea8的/www目录拷贝到主机的/tmp目录中。 + +```bash +isula cp 21fac8bb9ea8:/www /tmp/ +``` + +## 暂停容器中所有的进程 + +### 描述 + +isula pause用于暂停一个或者多个容器中的所有进程。 + +### 用法 + +```bash +isula pause [OPTIONS] CONTAINER [CONTAINER...] +``` + +### 参数 + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

pause

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+
+ +### 约束限制 + +- 只有状态为running的容器可以被执行pause操作 +- 当容器被pause后,无法执行其他生命周期管理操作(如restart/exec/attach/kill/stop/rm等) +- 当带有健康检查配置的容器被pause后,容器状态最终变为unhealthy状态 + +### 示例 + +暂停一个正在运行的容器,命令示例如下: + +```bash +# isula pause 8fe25506fb5883b74c2457f453a960d1ae27a24ee45cdd78fb7426d2022a8bac + 8fe25506fb5883b74c2457f453a960d1ae27a24ee45cdd78fb7426d2022a8bac +``` + +## 恢复容器容器中的所有进程 + +### 描述 + +isula unpause用于恢复一个或者多个容器中的所有进程, 为isula pause的逆过程。 + +### 用法 + +```bash +isula unpause [OPTIONS] CONTAINER [CONTAINER...] +``` + +### 参数 + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

pause

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+
+ +### 约束限制 + +- 只有状态为paused的容器可以被执行unpause操作 + +### 示例 + +恢复一个被暂停的容器,命令示例如下: + +```bash +# isula unpause 8fe25506fb5883b74c2457f453a960d1ae27a24ee45cdd78fb7426d2022a8bac + 8fe25506fb5883b74c2457f453a960d1ae27a24ee45cdd78fb7426d2022a8bac +``` + +## 从服务端实时获取事件消息 + +### 描述 + +isula events用于从服务端获取实时事件。 + +### 用法 + +```bash +isula events [OPTIONS] +``` + +### 参数 + + + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

events

+

-H, --host

+

指定要连接的iSulad socket文件路径

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+

-n, --name

+

获取指定容器的事件消息

+

-S, --since

+

获取指定时间以来的事件消息

+

-U, --until

+

获取到指定时间点位置的事件

+
+ +### 约束限制 + +- 支持容器相关事件为:create、start、restart、stop、exec_create、exec_die、attach、kill、top、rename、archive-path、extract-to-dir、update、pause、unpause、export、resize。 +- 支持镜像相关事件为:load、remove、pull、login、logout。 + +### 示例 + +从服务端实时获取事件消息,命令示例如下: + +```bash +# isula events +``` diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/container-resource-management.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/container-resource-management.md new file mode 100644 index 0000000000000000000000000000000000000000..036b686a1d13aa184db140de3b209f52e3555781 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/container-resource-management.md @@ -0,0 +1,744 @@ +# 容器资源管理 + +## 描述 + +可以通过namespace和cgroup等功能实现对容器的资源管理。isula支持使用cgroup v1和cgroup v2实现对资源的限制,其中 +cgroup v2属于实验特性,不支持商用。当系统配置为只支持cgroup v2并将cgroup v2挂载到/sys/fs/cgroup目录时,isula使用 +cgroup v2来进行资源管理。无论是cgroup v1还是使用cgroup v2对容器资源进行管理,isula提供给用户实现资源限制的接口是 +一致的。 + +## 资源共享 + +### 描述 + +容器间或者容器与host之间可以共享namespace信息,包括pid, net, ipc, uts。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 当使用与主机共享namespace信息时,即缺少了对应的namespace隔离机制,在容器中可以查询、操作主机上的信息,存在安全 +隐患。比如使用--pid=host共享主机pid namespace时,即可以看到主机上其他进程信息,造成信息泄露,甚至直接kill杀死主机 +进程。请在确保安全的场景下,谨慎使用共享主机host namespace功能。 + +### 用法 + +isula create/run时使用namespace相关的参数共享资源,具体参数见下方参数列表。 + +### 参数 + +create/run时可以指定下列参数。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数项

+

参数说明

+

取值范围

+

是否必选

+

--pid

+

指定要共享的pid namespace

+

[none, host, container:<containerID>],none表示不共享,host表示与host共用namespace,container:<containerID>表示与容器containerID共享同一个namespace

+

+

--net

+

指定要共享的net namespace

+

[none, host, container:<containerID>],none表示不共享,host表示与host共用namespace,container:<containerID>表示与容器containerID共享同一个namespace

+

+

--ipc

+

指定要共享的ipc namespace

+

[none, host, container:<containerID>],none表示不共享,host表示与host共用namespace,container:<containerID>表示与容器containerID共享同一个namespace

+

+

--uts

+

指定要共享的uts namespace

+

[none, host, container:<containerID>],none表示不共享,host表示与host共用namespace,container:<containerID>表示与容器containerID共享同一个namespace

+

+
+ +### 示例 + +如果两个容器需要共享同一个pid namespace,在运行容器时,直接加上--pid container: 即可,如: + +```bash +isula run -tid --name test_pid busybox sh +isula run -tid --name test --pid container:test_pid busybox sh +``` + +## 限制运行时的CPU资源 + +### 描述 + +可以通过参数限制容器的各项cpu资源值。 + +### 用法 + +isula create/run时使用cpu相关的参数限制容器的各项cpu资源值,具体参数及取值见下方参数列表。 + +### 参数 + +create/run时可以指定下列参数。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数项

+

参数说明

+

取值范围

+

是否必选

+

--cpu-period

+

限制容器中cpu cfs(完全公平调度)周期

+

64位整数(int64)

+

+

--cpu-quota

+

限制容器中cpu cfs(完全公平调度) 的配额

+

64位整数(int64)

+

+

--cpu-shares

+

限制容器中cpu相对权重

+

64位整数(int64)

+

+

--cpu-rt-period

+

限制容器中cpu实时周期(以微秒为单位)

+

64位整数(int64)

+

+

--cpu-rt-runtime

+

限制容器中cpu实时运行时间(以微秒为单位)

+

64位整数(int64)

+

+

--cpuset-cpus

+

限制容器中使用cpu节点

+

字符串。值为要设置的cpu编号,有效范围为主机上的cpu数量,例如可以设置0-3或者0,1.

+

+

--cpuset-mems

+

限制容器中cpuset使用的mem节点

+

字符串。值为要设置的cpu编号,有效范围为主机上的cpu数量,例如可以设置0-3或者0,1.

+

+
+ +### 示例 + +如果需要限制容器只是用特定的cpu,在运行容器时,直接加上--cpuset-cpus number 即可,如: + +```bash +isula run -tid --cpuset-cpus 0,2-3 busybox sh +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 是否设置成功,请参见“查询单个容器信息”章节。 + +## 限制运行时的内存 + +### 描述 + +可以通过参数限制容器的各项内存值上限。 + +### 用法 + +isula create/run时使用内存相关的参数限制容器的各项内存使用上限,具体参数及取值见下方参数列表。 + +### 参数 + +create/run时可以指定下列参数。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数项

+

参数说明

+

取值范围

+

是否必选

+

--memory

+

限制容器中内存使用上限

+

64位整数(int64)。值为非负数,0表示不设置(不限制);单位可以为空(byte),KB,MB,GB,TB,PB.

+

+

--memory-reservation

+

限制容器中内存的软上限

+

64位整数(int64)。值为非负数,0表示不设置(不限制);单位可以为空(byte),KB,MB,GB,TB,PB.

+

+

--memory-swap

+

限制容器中交换内存的上限

+

64位整数(int64)。值为-1或非负数,-1表示不限制,0表示不设置(不限制);单位可以为空(byte),KB,MB,GB,TB,PB.

+

+

--kernel-memory

+

限制容器中内核内存的上限

+

64位整数(int64)。值为非负数,0表示不设置(不限制);单位可以为空(byte),KB,MB,GB,TB,PB.

+

+
+ +### 示例 + +如果需要限制容器内内存的上限,在运行容器时,直接加上`--memory []`即可,如: + +```bash +isula run -tid --memory 1G busybox sh +``` + +## 限制运行时的IO资源 + +### 描述 + +可以通过参数限制容器中设备读写速度。 + +### 用法 + +isula create/run时使用--device-read-bps/--device-write-bps :\[\]来限制容器中设备的读写速度。 + +### 参数 + +create/run时指定--device-read/write-bps参数。 + + + + + + + + + + + + + + +

参数项

+

参数说明

+

取值范围

+

是否必选

+

--device-read-bps/--device-write-bps

+

限制容器中设备的读速度/写速度

+

64位整数(int64)。值为正整数,可以为0,0表示不设置(不限制);单位可以为空(byte),KB,MB,GB,TB,PB.

+

+
+ +### 示例 + +如果需要限制容器内设备的读写速度,在运行容器时,直接加上--device-write-bps/--device-read-bps :\[\]即可,例如,限制容器busybox内设备/dev/sda的读速度为 1MB 每秒,则命令如下: + +```bash +isula run -tid --device-write /dev/sda:1mb busybox sh +``` + +限制写速度的命令如下: + +```bash +isula run -tid read-bps /dev/sda:1mb busybox sh +``` + +## 限制容器rootfs存储空间 + +### 描述 + +在ext4上使用overlay2时,可以设置单个容器的文件系统限额,比如设置A容器的限额为5G,B容器为10G。 + +该特性通过ext4文件系统的project quota功能来实现,在内核支持的前提下,通过系统调用SYS\_IOCTL设置某个目录的project ID,再通过系统调用SYS\_QUOTACTL设置相应的project ID的hard limit和solft limit值达到限额的目的。 + +### 用法 + +1. 环境准备 + + 文件系统支持Project ID和Project Quota属性,4.19版本内核已经支持,外围包e2fsprogs版本不低于1.43.4-2。 + +2. 在容器挂载overlayfs之前,需要对不同容器的upper目录和work目录设置不同的project id,同时设置继承选项,在容器挂载overlayfs之后不允许再修改project id和继承属性。 +3. 配额的设置需要在容器外以特权用户进行。 +4. daemon中增加如下配置 + + ```shell + -s overlay2 --storage-opt overlay2.override_kernel_check=true + ``` + +5. daemon支持以下选项,用于为容器设置默认的限制, + + --storage-opt overlay2.basesize=128M 指定默认限制的大小,若isula run时也指定 了--storage-opt size选项,则以run时指定来生效,若daemon跟isula run时都不指定大小,则表示不限制。 + +6. 需要开启文件系统Project ID和Project Quota属性。 + - 新格式化文件系统并mount + + ```shell + # mkfs.ext4 -O quota,project /dev/sdb + # mount -o prjquota /dev/sdb /var/lib/isulad + ``` + +### 参数 + +create/run时指定--storage-opt参数。 + + + + + + + + + + + + + + +

参数项

+

参数说明

+

取值范围

+

是否必选

+

--storage-opt size=${rootfsSize}

+

限制容器rootfs存储空间。

+

rootfsSize解析出的大小为int64范围内以字节表示的正数,默认单位为B,也可指定为([kKmMgGtTpP])?[iI]?[bB]?$。(device mapper场景下最小取值为10G)

+

+
+ +### 示例 + +在isula run/create命令行上通过已有参数“--storage-opt size=”来设置限额。其中value是一个正数,单位可以是`[kKmMgGtTpP]?[iI]?[bB]?`,在不带单位的时候默认单位是字节。 + +```bash +# isula run -ti --storage-opt size=10M busybox +/ # df -h +Filesystem Size Used Available Use% Mounted on +overlay 10.0M 48.0K 10.0M 0% / +none 64.0M 0 64.0M 0% /dev +none 10.0M 0 10.0M 0% /sys/fs/cgroup +tmpfs 64.0M 0 64.0M 0% /dev +shm 64.0M 0 64.0M 0% /dev/shm +/dev/mapper/vg--data-ext41 + 9.8G 51.5M 9.2G 1% /etc/hostname +/dev/mapper/vg--data-ext41 + 9.8G 51.5M 9.2G 1% /etc/resolv.conf +/dev/mapper/vg--data-ext41 + 9.8G 51.5M 9.2G 1% /etc/hosts +tmpfs 3.9G 0 3.9G 0% /proc/acpi +tmpfs 64.0M 0 64.0M 0% /proc/kcore +tmpfs 64.0M 0 64.0M 0% /proc/keys +tmpfs 64.0M 0 64.0M 0% /proc/timer_list +tmpfs 64.0M 0 64.0M 0% /proc/sched_debug +tmpfs 3.9G 0 3.9G 0% /proc/scsi +tmpfs 64.0M 0 64.0M 0% /proc/fdthreshold +tmpfs 64.0M 0 64.0M 0% /proc/fdenable +tmpfs 3.9G 0 3.9G 0% /sys/firmware +/ # +/ # dd if=/dev/zero of=/home/img bs=1M count=12 && sync +dm-4: write failed, project block limit reached. +10+0 records in +9+0 records out +10432512 bytes (9.9MB) copied, 0.011782 seconds, 844.4MB/s +/ # df -h | grep overlay +overlay 10.0M 10.0M 0 100% / +/ # +``` + +### 约束 + +1. 限额只针对rw层。 + + overlay2的限额是针对容器的rw层的,镜像的大小不计算在内。 + +2. 内核支持并使能。 + + 内核必须支持ext4的project quota功能,并在mkfs的时候要加上-O quota,project,挂载的时候要加上-o prjquota。任何一个不满足,在使用--storage-opt size=时都将报错。 + + ```bash + # isula run -it --storage-opt size=10Mb busybox df -h + Error response from daemon: Failed to prepare rootfs with error: time="2019-04-09T05:13:52-04:00" level=fatal msg="error creating read- + write layer with ID "a4c0e55e82c55e4ee4b0f4ee07f80cc2261cf31b2c2dfd628fa1fb00db97270f": --storage-opt is supported only for overlay over + xfs or ext4 with 'pquota' mount option" + ``` + +3. 限制额度的说明。 + 1. 限制的额度大于isulad的root所在分区的size时,在容器内用df看到的文件系统的额度是isulad的root所在分区的size,而不是设置的限额。 + 2. --storage-opt size=0代表不限制,且设置值不能小于4096。size的精度为1个字节,如果指定精度含小数个字节,小数部分被忽略,如指定size=0.1实际等同于size=0不限制。(受计算机存储浮点数精度的限制,即0.999999999999999999999999999与1是等价的,具体的9的个数不同计算机可能存在差异,故设置4095.999999999999999999999999999与4096等价,其他情况类似),注意isula inspect显示原始命令行指定形式,如果含小数字节,需自行忽略小数部分。 + 3. 限制的额度过小时,比如--storage-opt size=4k,可能会导致容器无法启动,因为启动容器本身需要创建一些文件。 + 4. 上一次启动isulad时,isulad的root所在分区挂载时加了-o prjquota选项,这次启动时不加,那么上一次启动中创建的带quota的容器的设置值不生效。 + 5. daemon端配额--storage-opt overlay2.basesize,其取值范围与--storage-opt size相同。 + +4. 指定storage-opt为4k时,轻量级容器启动与docker有差异 + + 使用选项 storage-opt size=4k 和镜像 rnd-dockerhub.huawei.com/official/ubuntu-arm64:latest 运行容器。 + + docker启动失败。 + + ```bash + # docker run -itd --storage-opt size=4k rnd-dockerhub.huawei.com/official/ubuntu-arm64:latest + docker: Error response from daemon: symlink /proc/mounts /var/lib/docker/overlay2/e6e12701db1a488636c881b44109a807e187b8db51a50015db34a131294fcf70-init/merged/etc/mtab: disk quota exceeded. + See 'docker run --help'. + ``` + + 轻量级容器不报错,正常启动 + + ```bash + # isula run -itd --storage-opt size=4k rnd-dockerhub.huawei.com/official/ubuntu-arm64:latest + 636480b1fc2cf8ac895f46e77d86439fe2b359a1ff78486ae81c18d089bbd728 + # isula ps + STATUS PID IMAGE COMMAND EXIT_CODE RESTART_COUNT STARTAT FINISHAT RUNTIME ID NAMES + running 17609 rnd-dockerhub.huawei.com/official/ubuntu-arm64:latest /bin/bash 0 0 2 seconds ago - lcr 636480b1fc2c 636480b1fc2cf8ac895f46e77d86439fe2b359a1ff78486ae81c18d089bbd728 + ``` + + 在启动容器的过程中,如果需要在容器的rootfs路径下创建文件,若镜像本身占用的大小超过4k,且此时的quota设置为4k,则创建文件必定失败。 + + docker在启动容器的过程中,会比isulad创建更多的挂载点,用于挂载host上的某些路径到容器中,如/proc/mounts, /dev/shm等,如果镜像内本身不存在这些文件,则会创建,根据上述原因该操作会导致文件创建失败,因而容器启动失败。 + + 轻量级容器在启动容器过程中,使用默认配置时,挂载点较少,如/proc,或/sys等路径不存在时,才会创建。用例中的镜像rnd-dockerhub.huawei.com/official/ubuntu-arm64:latest本身含有/proc, /sys等,因此整个启动容器的过程中,都不会有新文件或路径生成,故轻量级容器启动过程不会报错。为验证这一过程,当把镜像替换为rnd-dockerhub.huawei.com/official/busybox-aarch64:latest时,由于该镜像内无/proc存在,轻量级容器启动一样会报错。 + + ```bash + # isula run -itd --storage-opt size=4k rnd-dockerhub.huawei.com/official/busybox-aarch64:latest + 8e893ab483310350b8caa3b29eca7cd3c94eae55b48bfc82b350b30b17a0aaf4 + Error response from daemon: Start container error: runtime error: 8e893ab483310350b8caa3b29eca7cd3c94eae55b48bfc82b350b30b17a0aaf4:tools/lxc_start.c:main:404 starting container process caused "Failed to setup lxc, + please check the config file." + ``` + +5. 其他说明。 + + 使用限额功能的isulad切换数据盘时,需要保证被切换的数据盘使用\`prjquota\`选项挂载,且/var/lib/isulad/storage/overlay2目录的挂载方式与/var/lib/isulad相同。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > + > 切换数据盘时需要保证/var/lib/isulad/storage/overlay2的挂载点被卸载。 + +## 限制容器内文件句柄数 + +### 描述 + +可以通过参数限制容器中可以打开的文件句柄数。 + +### 用法 + +isula create/run时使用--files-limit来限制容器中可以打开的文件句柄数。 + +### 参数 + +create/run时指定--files-limit参数。 + + + + + + + + + + + + + + +

参数项

+

参数说明

+

取值范围

+

是否必选

+

--files-limit

+

限制容器中可以打开的文件句柄数。

+

64位整数(int64)。可以为0、负,但不能超过2的63 次方减 1,0、负表示不做限制(max)。

+

由于创建容器的过程中会临时打开一些句柄,所以此值不能设置的太小,不然容器可能不受files limit的限制(如果设置的数小于当前已经打开的句柄数,会导致cgroup文件写不进去),建议大于30。

+

+
+ +### 示例 + +在运行容器时,直接加上--files-limit n 即可,如: + +```bash +isula run -ti --files-limit 1024 busybox bash +``` + +### 约束 + +1. 使用--files-limit参数传入一个很小的值,如1,可能导致容器启动失败。 + + ```bash + # isula run -itd --files-limit 1 rnd-dockerhub.huawei.com/official/busybox-aarch64 + 004858d9f9ef429b624f3d20f8ba12acfbc8a15bb121c4036de4e5745932eff4 + Error response from daemon: Start container error: Container is not running:004858d9f9ef429b624f3d20f8ba12acfbc8a15bb121c4036de4e5745932eff4 + ``` + + 而docker会启动成功,其files.limit cgroup值为max。 + + ```bash + # docker run -itd --files-limit 1 rnd-dockerhub.huawei.com/official/busybox-aarch64 + ef9694bf4d8e803a1c7de5c17f5d829db409e41a530a245edc2e5367708dbbab + # docker exec -it ef96 cat /sys/fs/cgroup/files/files.limit + max + ``` + + 根因是lxc和runc启动过程的原理不一样,lxc创建cgroup子组后先设置files.limit值,再将容器进程的PID写入该子组的cgroup.procs文件,此时该进程已经打开超过1个句柄,因而写入报错导致启动失败。runc创建cgroup子组后先将容器进程的PID写入该子组的cgroup.procs文件,再设置files.limit值,此时由于该子组内的进程已经打开超过1个句柄,因而写入files.limit不会生效,内核也不会报错,容器启动成功。 + +## 限制容器内可以创建的进程/线程数 + +### 描述 + +可以通过参数限制容器中能够创建的进程/线程数。 + +### 用法 + +在容器create/run时,使用参数--pids-limit来限制容器中可以创建的进程/线程数。 + +### 参数 + +create/run时指定--pids-limit参数。 + + + + + + + + + + + + + + +

参数项

+

参数说明

+

取值范围

+

是否必选

+

--pids-limit

+

限制容器中可以打开的文件句柄数。

+

64位整数(int64)。可以为0、负,但不能超过2的63 次方减 1,0、负表示不做限制(max)。

+

+
+ +### 示例 + +在运行容器时,直接加上--pids-limit n 即可,如: + +```bash +isula run -ti --pids-limit 1024 busybox bash +``` + +### 约束 + +由于创建容器的过程中会临时创建一些进程,所以此值不能设置的太小,不然容器可能起不来,建议大于10。 + +## 配置容器内的ulimit值 + +### 描述 + +可以通过参数控制执行程序的资源。 + +### 用法 + +在容器create/run时配置--ulimit参数,或通过daemon端配置,控制容器中执行程序的资源。 + +### 参数 + +通过两种方法配置ulimit + +1. isula create/run时使用--ulimit =\[:\]来控制shell执行程序的资源。 + + + + + + + + + + + + + + +

参数项

+

参数说明

+

取值范围

+

是否必选

+

--ulimit

+

限制shell执行程序的资源

+

soft/hard是64位整数(int64)。soft取值 <= hard取值,如果仅仅指定了soft的取值,则hard=soft。对于某些类型的资源并不支持负数,详见下表

+

+
+ +2. 通过daemon端参数或配置文件 + + 详见"(命令行参数说明"与"部署方式"的--default-ulimits相关选项。 + + --ulimit可以对以下类型的资源进行限制。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

类型

+

说明

+

取值范围

+

core

+

limits the core file size (KB)

+

64位整数(INT64),无单位。可以为0、负、其中-1表示UNLIMITED,即不做限制,其余的负数会被强制转换为一个大的正整数。

+

cpu

+

max CPU time (MIN)

+

data

+

max data size (KB)

+

fsize

+

maximum filesize (KB)

+

locks

+

max number of file locks the user can hold

+

memlock

+

max locked-in-memory address space (KB)

+

msgqueue

+

max memory used by POSIX message queues (bytes)

+

nice

+

nice priority

+

nproc

+

max number of processes

+

rss

+

max resident set size (KB)

+

rtprio

+

max realtime priority

+

rttime

+

realtime timeout

+

sigpending

+

max number of pending signals

+

stack

+

max stack size (KB)

+

nofile

+

max number of open file descriptors

+

64位整数(int64),无单位。不可以为负,负数被强转为大数,设置时会出现Operation not permitted

+
+ +### 示例 + +在容器的创建或者运行时,加上`--ulimit =[:]`即可,如: + +```bash +isula create/run -tid --ulimit nofile=1024:2048 busybox sh +``` + +### 约束 + +不能在daemon.json和/etc/sysconfig/iSulad文件(或isulad命令行)中同时配置ulimit限制,否则isulad启动会报错。 diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/cri-2.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/cri-2.md new file mode 100644 index 0000000000000000000000000000000000000000..52f1df63d11dc6a8746d4308016b6f9b05316146 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/cri-2.md @@ -0,0 +1,310 @@ +# CRI V1接口支持 + +## 概述 + +CRI(Container Runtime Interface, 容器运行时接口)是kublet与容器引擎通信使用的主要协议。 +在K8S 1.25及之前,K8S存在CRI v1alpha2 和 CRI V1两种版本的CRI接口,但从1.26开始,K8S仅提供对于CRI V1的支持。 + +iSulad同时提供对[CRI v1alpha2](./cri.md)和CRI v1的支持, +对于CRI v1,iSulad支持[CRI v1alpha2](./cri.md)所述功能, +并提供对CRI V1中所定义新接口和字段的支持。 + +目前iSulad支持的CRI V1版本为1.29,对应官网描述API如下: + +[https://github.com/kubernetes/cri-api/blob/kubernetes-1.29.0/pkg/apis/runtime/v1/api.proto](https://github.com/kubernetes/cri-api/blob/kubernetes-1.29.0/pkg/apis/runtime/v1/api.proto) + +iSulad使用的API描述文件,与官方API略有出入,以本文档描述的接口为准。 + +## 新增字段描述 + +- **CgroupDriver** + + cgroup驱动的enum值列表 + + + + + + + + + + + + + +

参数成员

+

描述

+

SYSTEMD = 0

+

systemd cgroup驱动

+

CGROUPFS = 1

+

cgroupfs驱动

+
+ +- **LinuxRuntimeConfiguration** + + 容器引擎所使用的cgroup驱动 + + + + + + + + + + +

参数成员

+

描述

+

CgroupDriver cgroup_driver

+

容器引擎所使用的cgroup驱动枚举值

+
+ +- **ContainerEventType** + + 容器事件类型枚举值 + + + + + + + + + + + + + + + + + + + +

参数成员

+

描述

+

CONTAINER_CREATED_EVENT = 0

+

容器创建类型

+

CONTAINER_STARTED_EVENT = 1

+

容器启动类型

+

CONTAINER_STOPPED_EVENT = 1

+

容器停止类型

+

CONTAINER_DELETED_EVENT = 1

+

容器删除类型

+
+ +- **SwapUsage** + + 虚拟内存使用情况 + + + + + + + + + + + + + + + + +

参数成员

+

描述

+

int64 timestamp

+

时间戳信息

+

UInt64Value swap_available_bytes

+

可使用虚拟内存字节数

+

UInt64Value swap_usage_bytes

+

已使用虚拟内存字节数

+
+ +## 新增接口描述 + +### RuntimeConfig + +#### 接口原型 + +```text +rpc RuntimeConfig(RuntimeConfigRequest) returns (RuntimeConfigResponse) {} +``` + +#### 接口描述 + +获取cgroup驱动配置 cgroupfs 或 systemd-cgroup + +#### 参数 RuntimeConfigRequest + +无字段 + +#### 返回值 RuntimeConfigResponse + + + + + + + + + +

返回值

+

描述

+

LinuxRuntimeConfiguration linux

+

描述cgroupfs或者systemd-cgroup的CgroupDriver枚举值

+
+ +### GetContainerEvents + +#### 接口原型 + +```text +rpc GetContainerEvents(GetEventsRequest) returns (stream ContainerEventResponse) {} +``` + +#### 接口描述 + +获取Pod生命周期事件流 + +#### 参数 GetEventsRequest + +无字段 + +#### 返回值 ContainerEventResponse + + + + + + + + + + + + + + + + + + + + + +

返回值

+

描述

+

string container_id

+

容器id

+

ContainerEventType container_event_type

+

容器事件类型

+

int64 created_at

+

容器事件产生时间

+

PodSandboxStatus pod_sandbox_status

+

容器所属Pod的status信息

+

repeated ContainerStatus containers_statuses

+

容器所属Pod内所有容器的status信息

+
+ +## 变更描述 + +### CRI V1.29更新变更描述 + +#### [获取cgroup驱动配置](https://github.com/kubernetes/kubernetes/pull/118770) + +`RuntimeConfig` 获取cgroup驱动配置 cgroupfs 或 systemd-cgroup + +#### [GetContainerEvents支持pod生命周期事件](https://github.com/kubernetes/kubernetes/pull/111384) + +`GetContainerEents`,提供对pod生命周期相关事件流 + +`PodSandboxStatus`有相应调整,增加ContainerStatuses提供沙箱内容器status信息 + +#### [ContainerStats虚拟内存信息](https://github.com/kubernetes/kubernetes/pull/118865) + +`ContainerStats`新增虚拟内存使用情况信息: `SwapUsage` + +#### [ContainerStatus reason字段OOMKilled设置](https://github.com/kubernetes/kubernetes/pull/112977) + +ContainerStatus中reason字段在cgroup out-of-memory时应该设置为OOMKilled + +#### [PodSecurityContext.SupplementalGroups描述修改](https://github.com/kubernetes/kubernetes/pull/113047) + +描述修改,优化`PodSecurityContext.SupplementalGroups`的注释,明确容器镜像定义的主UID不在该列表下的行为 + +#### [ExecSync输出限制](https://github.com/kubernetes/kubernetes/pull/110435) + +ExecSync返回值输出小于16MB + +## 使用手册 + +### 配置iSulad支持CRI V1 + +该需求需要iSulad对K8S新版本CRI接口1.29提供支持, + +对于1.25及之前的CRI接口,V1alpha2和V1功能保持一致,1.26及之后新增的特性仅在CRI V1中提供支持。 +此次升级的功能和特性仅在CRI V1中提供支持,因此新增特性均需要按照以下配置使能CRI V1。 + +CRI V1使能: + +iSulad daemon.json中enable-cri-v1设置为true,重启iSulad + +```json +{ + "group": "isula", + "default-runtime": "runc", + ... + "enable-cri-v1": true +} +``` + +若通过源码进行编译安装iSulad需开启ENABLE_CRI_API_V1编译选项 + +```bash +cmake ../ -D ENABLE_CRI_API_V1=ON +``` + +### RuntimeConfig获取cgroup驱动配置 + +#### systemd-cgroup配置 + +iSulad同时提供对systemd和cgroupfs两种cgroup驱动支持, +默认使用cgroupfs作为cgroup驱动,可以通过配置iSulad容器引擎提供对systemd cgroup驱动支持。 +iSulad仅提供底层运行时为runc时systemd-cgroup的支持。通过修改iSulad配置文件daemon.json, +设置systemd-cgroup为true,重启iSulad,则使用systemd cgroup驱动。 + +```json +{ + "group": "isula", + "default-runtime": "runc", + ... + "enable-cri-v1": true, + "systemd-cgroup": true +} +``` + +### GetContainerEvents Pod 生命周期事件生成 + +#### Pod Events配置 + +修改iSulad配置文件daemon.json, +设置enable-pod-events为true,重启iSulad。 + +```json +{ + "group": "isula", + "default-runtime": "runc", + ... + "enable-cri-v1": true, + "enable-pod-events": true +} +``` + +## 使用限制 + +1. 以上新增特性,iSulad仅提供容器运行时设置为runc时的支持。 +2. 由于cgroup oom会同时触发容器cgroup路径删除,若iSulad对oom事件处理发生在cgroup路径删除之后,iSulad则无法成功捕捉容器oom事件,可能导致ContainerStatus中reason字段设置不正确。 +3. iSulad不支持交叉使用不同的cgroup驱动管理容器,启动容器后iSulad的cgroup驱动配置不应该发生变化。 diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/cri.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/cri.md new file mode 100644 index 0000000000000000000000000000000000000000..387c24a6d4fcef558f1626f8dbd666bbf9e75deb --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/cri.md @@ -0,0 +1,1977 @@ +# CRI V1alpha2 接口 + +## 描述 + +CRI API 接口是由kubernetes 推出的容器运行时接口,CRI定义了容器和镜像的服务接口。ISulad使用CRI接口,实现和kubernetes 的对接。 + +因为容器运行时与镜像的生命周期是彼此隔离的,因此需要定义两个服务。该接口使用[Protocol Buffer](https://developers.google.com/protocol-buffers/)定义,基于[gRPC](https://grpc.io/)。 + +当前iSulad使用默认CRI版本为v1alpha2版本,官方API描述文件如下: + +[https://github.com/kubernetes/kubernetes/blob/release-1.14/pkg/kubelet/apis/cri/runtime/v1alpha2/api.proto](https://github.com/kubernetes/kubernetes/blob/release-1.14/pkg/kubelet/apis/cri/runtime/v1alpha2/api.proto), + +ISulad使用的为pass使用的1.14版本API描述文件,与官方API略有出入,以本文档描述的接口为准。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> CRI接口websocket流式服务,服务端侦听地址为127.0.0.1,端口为10350,端口可通过命令行--websocket-server-listening-port参数接口或者daemon.json配置文件进行配置。 + +## 接口 + +各接口中可能用到的参数清单如下,部分参数暂不支持配置,已在配置中标出。 + +### 接口参数列表 + +- **DNSConfig** + + 配置sandbox的DNS服务器和搜索域 + + | 参数成员 | 描述 | + |--------------------------|------------------------------------------------------------| + | repeated string servers | 集群的DNS服务器列表 | + | repeated string searches | 集群的DNS搜索域列表 | + | repeated string options | DNS可选项列表,参考 | + +- **Protocol** + + 协议的enum值列表 + + + + + + + + + + + + + +

参数成员

+

描述

+

TCP = 0

+

TCP协议

+

UDP = 1

+

UDP协议

+
+ +- **PortMapping** + + 指定sandbox的端口映射配置 + + | **参数成员** | **描述** | + |----------------------|--------------------| + | Protocol protocol | 端口映射使用的协议 | + | int32 container_port | 容器内的端口号 | + | int32 host_port | 主机上的端口号 | + | string host_ip | 主机IP地址 | + +- **MountPropagation** + + 挂载传播属性的enum列表 + + + + + + + + + + + + + + + + +

参数成员

+

描述

+

PROPAGATION_PRIVATE = 0

+

无挂载传播属性,即linux中的private

+

PROPAGATION_HOST_TO_CONTAINER = 1

+

挂载属性能从host传播到容器中,即linux中的rslave

+

PROPAGATION_BIDIRECTIONAL = 2

+

挂载属性能在host和容器中双向传播,即linux中的rshared

+
+ +- **Mount** + + Mount指定host上的一个挂载卷挂载到容器中(只支持文件和文件夹\) + + | **参数成员** | **描述** | + |------------------------------|---------------------------------------------------------------------------------| + | string container_path | 容器中的路径 | + | string host_path | 主机上的路径 | + | bool readonly | 是否配置在容器中是只读的, 缺省值: false | + | bool selinux_relabel | 是否设置SELinux标签(不支持配置) | + | MountPropagation propagation | 挂载传播属性配置(取值**0/1/2**,分别对应**private/rslave/rshared**传播属性) **缺省值:0** | + +- **NamespaceOption** + + + + + + + + + + + + + + + + +

参数成员

+

描述

+

bool host_network

+

是否使用host的网络命名空间

+

bool host_pid

+

是否使用host的PID命名空间

+

bool host_ipc

+

是否使用host的IPC命名空间

+
+ +- **Capability** + + 包含待添加与待删除的权能信息 + + + + + + + + + + + + + +

参数成员

+

描述

+

repeated string add_capabilities

+

待新增的权能

+

repeated string drop_capabilities

+

待删除的权能

+
+ +- **Int64Value** + + int64类型的封装 + + + + + + + + + + +

参数成员

+

描述

+

int64 value

+

实际的int64值

+
+ +- **UInt64Value** + + uint64类型的封装 + + + + + + + + + + +

参数成员

+

描述

+

uint64 value

+

实际的uint64值

+
+ +- **LinuxSandboxSecurityContext** + + 配置sandbox的linux安全选项。 + + 注意,这些安全选项不会应用到sandbox中的容器中,也可能不适用于没有任何running进程的sandbox。 + + | **参数成员** | **描述** | + |------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| + | NamespaceOption namespace_options | 配置sandbox的命名空间选项 | + | SELinuxOption selinux_options | 配置SELinux选项(不支持) | + | Int64Value run_as_user | 配置sandbox中进程的uid | + | bool readonly_rootfs | 配置sandbox的根文件系统是否只读 | + | repeated int64 supplemental_groups | 配置除主GID之外的sandbox的1号进程用户组信息 | + | bool privileged | 配置sandbox是否为特权容器 | + | string seccomp_profile_path | seccomp配置文件路径,有效值为:
// unconfined: 不配置seccomp
// localhost/\<配置文件的全路径>: 安装在系统上的配置文件路径
// \<配置文件的全路径>: 配置文件全路径
// 默认不配置,即unconfined。 | + +- **LinuxPodSandboxConfig** + + 设定和Linux主机及容器相关的一些配置 + + | **参数成员** | **描述** | + |----------------------------------------------|-----------------------------------------------------------------------------------------| + | string cgroup_parent | sandbox的cgroup父路径,runtime可根据实际情况使用cgroupfs或systemd的语法。(不支持配置) | + | LinuxSandboxSecurityContext security_context | sandbox的安全属性 | + | map\ sysctls | sandbox的linux sysctls配置 | + +- **PodSandboxMetadata** + + Sandbox元数据包含构建sandbox名称的所有信息,鼓励容器运行时在用户界面中公开这些元数据以获得更好的用户体验,例如,运行时可以根据元数据生成sandbox的唯一命名。 + + + + + + + + + + + + + + + + + + + +

参数成员

+

描述

+

string name

+

sandbox的名称

+

string uid

+

sandbox的UID

+

string namespace

+

sandbox的命名空间

+

uint32 attempt

+

尝试创建sandbox的次数,默认为0

+
+ +- **PodSandboxConfig** + + 包含创建sandbox的所有必选和可选配置信息 + + | **参数成员** | **描述** | + |------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------| + | PodSandboxMetadata metadata | sandbox的元数据,这项信息唯一标识一个sandbox,runtime必须利用此信息确保操作正确,runtime也可以根据此信息来改善用户体验,例如构建可读的sandbox名称。 | + | string hostname | sandbox的hostname | + | string log_directory | 配置sandbox内的容器的日志文件所存储的文件夹 | + | DNSConfig dns_config | sandbox的DNS配置 | + | repeated PortMapping port_mappings | sandbox的端口映射 | + | map\ labels | 可用于标识单个或一系列sandbox的键值对 | + | map\ annotations | 存储任意信息的键值对,这些值是不可更改的,且能够利用PodSandboxStatus接口查询 | + | LinuxPodSandboxConfig linux | 与linux主机相关的可选项 | + +- **PodSandboxNetworkStatus** + + 描述sandbox的网络状态 + + + + + + + + + + + + + + + + +

参数成员

+

描述

+

string ip

+

sandbox的ip地址

+

string name

+

sandbox内的网络接口名

+

string network

+

附加网络的名称

+
+ +- **Namespace** + + 命名空间选项 + + | **参数成员** | **描述** | + |-------------------------|--------------------| + | NamespaceOption options | Linux 命名空间选项 | + +- **LinuxPodSandboxStatus** + + 描述Linux sandbox的状态 + + | **参数成员** | **描述** | + |----------------------|-----------------| + | Namespace **namespaces** | sandbox命名空间 | + +- **PodSandboxState** + + sandbox状态值的enum数据 + + + + + + + + + + + + + +

参数成员

+

描述

+

SANDBOX_READY = 0

+

sandbox处于ready状态

+

SANDBOX_NOTREADY = 1

+

sandbox处于非ready状态

+
+ +- **PodSandboxStatus** + + 描述Podsandbox的状态信息 + + | **参数成员** | **描述** | + |-------------------------------------------|---------------------------------------------------| + | string id | sandbox的ID | + | PodSandboxMetadata metadata | sandbox的元数据 | + | PodSandboxState state | sandbox的状态值 | + | int64 created_at | sandbox的创建时间戳,单位纳秒 | + | repeated PodSandboxNetworkStatus networks | sandbox的多平面网络状态 | + | LinuxPodSandboxStatus linux | Linux规范的sandbox状态 | + | map\ labels | 可用于标识单个或一系列sandbox的键值对 | + | map\ annotations | 存储任意信息的键值对,这些值是不可被runtime更改的 | + +- **PodSandboxStateValue** + + 对PodSandboxState的封装 + + | **参数成员** | **描述** | + |-----------------------|-----------------| + | PodSandboxState state | sandbox的状态值 | + +- **PodSandboxFilter** + + 用于列出sandbox时添加过滤条件,多个条件取交集显示 + + | **参数成员** | **描述** | + |------------------------------------|------------------------------------------------------| + | string id | sandbox的ID | + | PodSandboxStateValue state | sandbox的状态 | + | map\ label_selector | sandbox的labels,label只支持完全匹配,不支持正则匹配 | + +- **PodSandbox** + + 包含最小化描述一个sandbox的数据 + + | **参数成员** | **描述** | + |---------------------------------|---------------------------------------------------| + | string id | sandbox的ID | + | PodSandboxMetadata metadata | sandbox的元数据 | + | PodSandboxState state | sandbox的状态值 | + | int64 created_at | sandbox的创建时间戳,单位纳秒 | + | map\ labels | 可用于标识单个或一系列sandbox的键值对 | + | map\ annotations | 存储任意信息的键值对,这些值是不可被runtime更改的 | + +- **KeyValue** + + 键值对的封装 + + + + + + + + + + + + + +

参数成员

+

描述

+

string key

+

+

string value

+

+
+ +- **SELinuxOption** + + 应用于容器的SELinux标签 + + + + + + + + + + + + + + + + + + + +

参数成员

+

描述

+

string user

+

用户

+

string role

+

角色

+

string type

+

类型

+

string level

+

级别

+
+ +- **ContainerMetadata** + + Container元数据包含构建container名称的所有信息,鼓励容器运行时在用户界面中公开这些元数据以获得更好的用户体验,例如,运行时可以根据元数据生成container的唯一命名。 + + + + + + + + + + + + + +

参数成员

+

描述

+

string name

+

container的名称

+

uint32 attempt

+

尝试创建container的次数,默认为0

+
+ +- **ContainerState** + + 容器状态值的enum列表 + + + + + + + + + + + + + + + + + + + +

参数成员

+

描述

+

CONTAINER_CREATED = 0

+

container创建完成

+

CONTAINER_RUNNING = 1

+

container处于运行状态

+

CONTAINER_EXITED = 2

+

container处于退出状态

+

CONTAINER_UNKNOWN = 3

+

未知的容器状态

+
+ +- **ContainerStateValue** + + 封装ContainerState的数据结构 + + | **参数成员** | **描述** | + |----------------------|------------| + | ContainerState **state** | 容器状态值 | + +- **ContainerFilter** + + 用于列出container时添加过滤条件,多个条件取交集显示 + + | **参数成员** | **描述** | + |------------------------------------|--------------------------------------------------------| + | string id | container的ID | + | PodSandboxStateValue state | container的状态 | + | string pod_sandbox_id | sandbox的ID | + | map\ label_selector | container的labels,label只支持完全匹配,不支持正则匹配 | + +- **LinuxContainerSecurityContext** + + 指定应用于容器的安全配置 + + | **参数成员** | **描述** | + |------------------------------------|------------------------------------------------------------------------------------------------------------------------------------| + | Capability capabilities | 新增或去除的权能 | + | bool privileged | 指定容器是否未特权模式, **缺省值:false** | + | NamespaceOption namespace_options | 指定容器的namespace选项 | + | SELinuxOption selinux_options | SELinux context(可选配置项) **暂不支持** | + | Int64Value run_as_user | 运行容器进程的UID。 一次只能指定run_as_user与run_as_username其中之一,run_as_username优先生效 | + | string run_as_username | 运行容器进程的用户名。 如果指定,用户必须存在于容器映像中(即在映像内的/etc/passwd中),并由运行时在那里解析; 否则,运行时必须出错 | + | bool readonly_rootfs | 设置容器中根文件系统是否为只读 **缺省值由config.json配置** | + | repeated int64 supplemental_groups | 容器运行的除主GID外首进程组的列表 | + | string apparmor_profile | 容器的AppArmor配置文件 **暂不支持** | + | string seccomp_profile_path | 容器的seccomp配置文件路径 | + | bool no_new_privs | 是否在容器上设置no_new_privs的标志 | + +- **LinuxContainerResources** + + 指定Linux容器资源的特定配置 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数成员

+

描述

+

int64 cpu_period

+

CPU CFS(完全公平调度程序)周期。 缺省值:0

+

int64 cpu_quota

+

CPU CFS(完全公平调度程序)配额。 缺省值:0

+

int64 cpu_shares

+

所占CPU份额(相对于其他容器的相对权重)。 缺省值:0

+

int64 memory_limit_in_bytes

+

内存限制(字节)。 缺省值:0

+

int64 oom_score_adj

+

OOMScoreAdj用于调整oom-killer。 缺省值:0

+

string cpuset_cpus

+

指定容器使用的CPU核心。 缺省值:“”

+

string cpuset_mems

+

指定容器使用的内存节点。 缺省值:“”

+
+ +- **Image** + + Image信息描述一个镜像的基本数据。 + + | **参数成员** | **描述** | + |------------------------------|------------------------| + | string id | 镜像ID | + | repeated string repo_tags | 镜像tag 名称 repo_tags | + | repeated string repo_digests | 镜像digest信息 | + | uint64 size | 镜像大小 | + | Int64Value uid | 镜像默认用户UID | + | string username | 镜像默认用户名称 | + +- **ImageSpec** + + 表示镜像的内部数据结构,当前,ImageSpec只封装容器镜像名称 + + + + + + + + + + +

参数成员

+

描述

+

string image

+

容器镜像名

+
+ +- **StorageIdentifier** + + 唯一定义storage的标识 + + + + + + + + + + +

参数成员

+

描述

+

string uuid

+

设备的UUID

+
+ +- **FilesystemUsage** + + | **参数成员** | **描述** | + |------------------------------|----------------------------| + | int64 timestamp | 收集文件系统信息时的时间戳 | + | StorageIdentifier storage_id | 存储镜像的文件系统UUID | + | UInt64Value used_bytes | 存储镜像元数据的大小 | + | UInt64Value inodes_used | 存储镜像元数据的inodes个数 | + +- **AuthConfig** + + + + + + + + + + + + + + + + + + + + + + + + +

参数成员

+

描述

+

string username

+

下载镜像使用的用户名

+

string password

+

下载镜像使用的密码

+

string auth

+

下载镜像时使用的认证信息,base64编码

+

string server_address

+

下载镜像的服务器地址,暂不支持

+

string identity_token

+

用于与镜像仓库鉴权的令牌信息,暂不支持

+

string registry_token

+

用于与镜像仓库交互的令牌信息,暂不支持

+
+ +- **Container** + + 用于描述容器信息,例如ID, 状态等。 + + | **参数成员** | **描述** | + |---------------------------------|-------------------------------------------------------------| + | string id | container的ID | + | string pod_sandbox_id | 该容器所属的sandbox的ID | + | ContainerMetadata metadata | container的元数据 | + | ImageSpec image | 镜像规格 | + | string image_ref | 代表容器使用的镜像,对大多数runtime来产,这是一个image ID值 | + | ContainerState state | container的状态 | + | int64 created_at | container的创建时间戳,单位为纳秒 | + | map\ labels | 可用于标识单个或一系列container的键值对 | + | map\ annotations | 存储任意信息的键值对,这些值是不可被runtime更改的 | + +- **ContainerStatus** + + 用于描述容器状态信息 + + | **参数成员** | **描述** | + |---------------------------------|---------------------------------------------------------------------------| + | string id | container的ID | + | ContainerMetadata metadata | container的元数据 | + | ContainerState state | container的状态 | + | int64 created_at | container的创建时间戳,单位为纳秒 | + | int64 started_at | container启动时的时间戳,单位为纳秒 | + | int64 finished_at | container退出时的时间戳,单位为纳秒 | + | int32 exit_code | 容器退出码 | + | ImageSpec image | 镜像规格 | + | string image_ref | 代表容器使用的镜像,对大多数runtime来产,这是一个image ID值 | + | string reason | 简要描述为什么容器处于当前状态 | + | string message | 易于人工阅读的信息,用于表述容器处于当前状态的原因 | + | map\ labels | 可用于标识单个或一系列container的键值对 | + | map\ annotations | 存储任意信息的键值对,这些值是不可被runtime更改的 | + | repeated Mount mounts | 容器的挂载点信息 | + | string log_path | 容器日志文件路径,该文件位于PodSandboxConfig中配置的log_directory文件夹下 | + +- **ContainerStatsFilter** + + 用于列出container stats时添加过滤条件,多个条件取交集显示 + + + + + + + + + + + + + + + + +

参数成员

+

描述

+

string id

+

container的ID

+

string pod_sandbox_id

+

sandbox的ID

+

map<string, string> label_selector

+

container的labels,label只支持完全匹配,不支持正则匹配

+
+ +- **ContainerStats** + + 用于列出container stats时添加过滤条件,多个条件取交集显示 + + | **参数成员** | **描述** | + |--------------------------------|----------------| + | ContainerAttributes attributes | 容器的信息 | + | CpuUsage cpu | CPU使用情况 | + | MemoryUsage memory | 内存使用情况 | + | FilesystemUsage writable_layer | 可写层使用情况 | + +- **ContainerAttributes** + + 列出container的基本信息 + + | **参数成员** | **描述** | + |--------------------------------|---------------------------------------------------| + | string id | 容器的ID | + | ContainerMetadata metadata | 容器的metadata | + | map\ labels | 可用于标识单个或一系列container的键值对 | + | map\ annotations | 存储任意信息的键值对,这些值是不可被runtime更改的 | + +- **CpuUsage** + + 列出container的CPU使用信息 + + + + + + + + + + + + + +

参数成员

+

描述

+

int64 timestamp

+

时间戳

+

UInt64Value usage_core_nano_seconds

+

CPU的使用值,单位/纳秒

+
+ +- **MemoryUsage** + + 列出container的内存使用信息 + + + + + + + + + + + + + +

参数成员

+

描述

+

int64 timestamp

+

时间戳

+

UInt64Value working_set_bytes

+

内存的使用值

+
+ +- **FilesystemUsage** + + 列出container的读写层信息 + + + + + + + + + + + + + + + + + + + +

参数成员

+

描述

+

int64 timestamp

+

时间戳

+

StorageIdentifier storage_id

+

可写层目录

+

UInt64Value used_bytes

+

镜像在可写层的占用字节

+

UInt64Value inodes_used

+

镜像在可写层的占用inode数

+
+ +- **Device** + + 指定待挂载至容器的主机卷 + + + + + + + + + + + + + + + +

参数成员

+

描述

+

string container_path

+

容器内的挂载路径

+

string host_path

+

主机上的挂载路径

+

string permissions

+

设备的Cgroup权限,(r允许容器从指定的设备读取; w允许容器从指定的设备写入; m允许容器创建尚不存在的设备文件)

+
+ +- **LinuxContainerConfig** + + 包含特定于Linux平台的配置 + + | **参数成员** | **描述** | + |------------------------------------------------|-------------------------| + | LinuxContainerResources resources | 容器的资源规范 | + | LinuxContainerSecurityContext security_context | 容器的Linux容器安全配置 | + +- **ContainerConfig** + + 包含用于创建容器的所有必需和可选字段 + + | **参数成员** | **描述** | + |---------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------| + | ContainerMetadata metadata | 容器的元数据。 此信息将唯一标识容器,运行时应利用此信息来确保正确操作。 运行时也可以使用此信息来提升UX(用户体检设计),例如通过构造可读名称。(必选) | + | ImageSpec image | 容器使用的镜像 (**必选**) | + | repeated string command | 待执行的命令 **缺省值: "/bin/sh"** | + | repeated string args | 待执行命令的参数 | + | string working_dir | 命令执行的当前工作路径 | + | repeated KeyValue envs | 在容器中配置的环境变量 | + | repeated Mount mounts | 待在容器中挂载的挂载点信息 | + | repeated Device devices | 待在容器中映射的设备信息 | + | map\ labels | 可用于索引和选择单个资源的键值对。 | + | map\ annotations | 可用于存储和检索任意元数据的非结构化键值映射。 | + | string log_path | 相对于PodSandboxConfig.LogDirectory的路径,用于存储容器主机上的日志(STDOUT和STDERR)。 | + | bool stdin | 是否打开容器的stdin | + | bool stdin_once | 当某次连接stdin的数据流断开时,是否立即断开其他与stdin连接的数据流 **(暂不支持)** | + | bool tty | 是否使用伪终端连接容器的stdio | + | LinuxContainerConfig linux | linux系统上容器的特定配置信息 | + +- **RuntimeConfig** + + Runtime的网络配置 + + | **参数成员** | **描述** | + |------------------------------|-------------------| + | NetworkConfig network_config | Runtime的网络配置 | + +- **RuntimeCondition** + + 描述runtime的状态信息 + + + + + + + + + + + + + + + + + + +

参数成员

+

描述

+

string type

+

Runtime状态的类型

+

bool status

+

Runtime状态

+

string reason

+

简要描述runtime状态变化的原因

+

string message

+

具备可阅读性的信息表明runtime状态变化的原因

+
+ +- **RuntimeStatus** + + Runtime的状态 + + + + + + + + + +

参数成员

+

描述

+

repeated RuntimeCondition conditions

+

描述当前runtime状态的列表

+
+ +### Runtime服务 + +Runtime服务中包含操作pod和容器的接口,以及查询runtime自身配置和状态信息的接口。 + +#### RunPodSandbox + +#### 接口原型 + +```text +rpc RunPodSandbox(RunPodSandboxRequest) returns (RunPodSandboxResponse) {} +``` + +#### 接口描述 + +创建和启动一个pod sandbox,若运行成功,sandbox处于ready状态。 + +#### 注意事项 + +1. 启动sandbox的默认镜像为rnd-dockerhub.huawei.com/library/pause-$\{machine\}:3.0, 其中$\{machine\}为架构,在x86\_64上,machine的值为amd64,在arm64上,machine的值为aarch64,当前rnd-dockerhub仓库上只有amd64和aarch64镜像可供下载,若机器上无此镜像,请确保机器能从rnd-dockerhub下载,若要使用其他镜像,请参考“iSulad部署配置”中的pod-sandbox-image指定镜像。 +2. 由于容器命名以PodSandboxMetadata中的字段为来源,且以下划线"\_"为分割字符,因此限制metadata中的数据不能包含下划线,否则会出现sandbox运行成功,但无法使用ListPodSandbox接口查询的现象。 + +#### 参数 + +| **参数成员** | **描述** | +|-------------------------|-----------------------------------------------------------------------| +| PodSandboxConfig config | sandbox的配置 | +| string runtime_handler | 指定创建sandbox的runtime运行时,当前支持lcr、kata-runtime运行时类型。 | + +#### 返回值 + + + + + + + + + +

返回值

+

描述

+

string pod_sandbox_id

+

成功,返回response数据

+
+ +#### StopPodSandbox + +#### 接口原型 + +```text +rpc StopPodSandbox(StopPodSandboxRequest) returns (StopPodSandboxResponse) {} +``` + +#### 接口描述 + +停止pod sandbox,停止sandbox容器,回收分配给sandbox的网络资源(比如IP地址)。如果有任何running的容器属于该sandbox,则必须被强制停止。 + +#### 参数 + + + + + + + + + +

参数成员

+

描述

+

string pod_sandbox_id

+

sandbox的id

+
+ +#### 返回值 + + + + + + + + + +

返回值

+

描述

+

+

+
+ +#### RemovePodSandbox + +#### 接口原型 + +```text +rpc RemovePodSandbox(RemovePodSandboxRequest) returns (RemovePodSandboxResponse) {} +``` + +#### 接口描述 + +删除sandbox,如果有任何running的容器属于该sandbox,则必须被强制停止和删除,如果sandbox已经被删除,不能返回错误。 + +#### 注意事项 + +1. 删除sandbox时,不会删除sandbox的网络资源,在删除pod前必须先调用StopPodSandbox才能清理网络资源,调用者应当保证在删除sandbox之前至少调用一次StopPodSandbox。 +2. 删除sandbox时,如果sandbox中的容器删除失败,则会出现sanbox被删除但容器还残留的情况,此时需要手动删除残留的容器进行清理。 + +#### 参数 + + + + + + + + + +

参数成员

+

描述

+

string pod_sandbox_id

+

sandbox的id

+
+ +#### 返回值 + + + + + + + + + +

返回值

+

描述

+

+

+
+ +#### PodSandboxStatus + +#### 接口原型 + +```text +rpc PodSandboxStatus(PodSandboxStatusRequest) returns (PodSandboxStatusResponse) {} +``` + +#### 接口描述 + +查询sandbox的状态,如果sandbox不存在,返回错误。 + +#### 参数 + + + + + + + + + + + + +

参数成员

+

描述

+

string pod_sandbox_id

+

sandbox的id

+

bool verbose

+

标识是否显示sandbox的一些额外信息。(暂不支持配置)

+
+ +#### 返回值 + +| **返回值** | **描述** | +|--------------------------|------------------------------------------------------------------------------------------------------------------------------------------| +| PodSandboxStatus status | sandbox的状态信息 | +| map\ info | sandbox的额外信息,key是任意string,value是json格式的字符串,这些信息可以是任意调试内容。当verbose为true时info不能为空。(暂不支持配置) | + +#### ListPodSandbox + +#### 接口原型 + +```text +rpc ListPodSandbox(ListPodSandboxRequest) returns (ListPodSandboxResponse) {} +``` + +#### 接口描述 + +返回sandbox信息的列表,支持条件过滤。 + +#### 参数 + +| **参数成员** | **描述** | +|-------------------------|--------------| +| PodSandboxFilter filter | 条件过滤参数 | + +#### 返回值 + +| **返回值** | **描述** | +|---------------------------|-------------------| +| repeated PodSandbox items | sandbox信息的列表 | + +#### CreateContainer + +#### 接口原型 + +```text +rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {} +``` + +#### 接口描述 + +在PodSandbox内创建一个容器。 + +#### 注意事项 + +- 请求CreateContainerRequest 中的sandbox\_config与传递给RunPodSandboxRequest以创建PodSandbox的配置相同。 它再次传递,只是为了方便参考。 PodSandboxConfig是不可变的,在pod的整个生命周期内保持不变。 +- 由于容器命名以ContainerMetadata中的字段为来源,且以下划线"\_"为分割字符,因此限制metadata中的数据不能包含下划线,否则会出现sandbox运行成功,但无法使用ListContainers接口查询的现象。 +- CreateContainerRequest中无runtime\_handler字段,创建container时的runtime类型和其对应的sandbox的runtime相同。 + +#### 参数 + +| **参数成员** | **描述** | +|---------------------------------|------------------------------------| +| string pod_sandbox_id | 待在其中创建容器的PodSandbox的ID。 | +| ContainerConfig config | 容器的配置信息 | +| PodSandboxConfig sandbox_config | PodSandbox的配置信息 | + +#### 补充 + +可用于存储和检索任意元数据的非结构化键值映射。有一些字段由于cri接口没有提供特定的参数,可通过该字段将参数传入 + +- 自定义 + + + + + + + + + +

自定义 key:value

+

描述

+

cgroup.pids.max:int64_t

+

用于限制容器内的进/线程数(set -1 for unlimited)

+
+ +#### 返回值 + + + + + + + + + +

返回值

+

描述

+

string container_id

+

创建完成的容器ID

+
+ +#### StartContainer + +#### 接口原型 + +```text +rpc StartContainer(StartContainerRequest) returns (StartContainerResponse) {} +``` + +#### 接口描述 + +启动一个容器。 + +#### 参数 + + + + + + + + + +

参数成员

+

描述

+

string container_id

+

容器id

+
+ +#### 返回值 + + + + + + + + + +

返回值

+

描述

+

+

+
+ +#### StopContainer + +#### 接口原型 + +```text +rpc StopContainer(StopContainerRequest) returns (StopContainerResponse) {} +``` + +#### 接口描述 + +停止一个running的容器,支持配置优雅停止时间timeout,如果容器已经停止,不能返回错误。 + +#### 参数 + + + + + + + + + + + + +

参数成员

+

描述

+

string container_id

+

容器id

+

int64 timeout

+

强制停止容器前的等待时间,缺省值为0,即强制停止容器。

+
+ +#### 返回值 + +无 + +#### RemoveContainer + +#### 接口原型 + +```text +rpc RemoveContainer(RemoveContainerRequest) returns (RemoveContainerResponse) {} +``` + +#### 接口描述 + +删除一个容器,如果容器正在运行,必须强制停止,如果容器已经被删除,不能返回错误。 + +#### 参数 + + + + + + + + + +

参数成员

+

描述

+

string container_id

+

容器id

+
+ +#### 返回值 + +无 + +#### ListContainers + +#### 接口原型 + +```text +rpc ListContainers(ListContainersRequest) returns (ListContainersResponse) {} +``` + +#### 接口描述 + +返回container信息的列表,支持条件过滤。 + +#### 参数 + +| **参数成员** | **描述** | +|------------------------|--------------| +| ContainerFilter filter | 条件过滤参数 | + +#### 返回值 + +| **返回值** | **描述** | +|-------------------------------|----------------| +| repeated Container containers | 容器信息的列表 | + +#### ContainerStatus + +#### 接口原型 + +```text +rpc ContainerStatus(ContainerStatusRequest) returns (ContainerStatusResponse) {} +``` + +#### 接口描述 + +返回容器状态信息,如果容器不存在,则返回错误。 + +#### 参数 + + + + + + + + + + + + +

参数成员

+

描述

+

string container_id

+

容器id

+

bool verbose

+

标识是否显示sandbox的一些额外信息。(暂不支持配置)

+
+ +#### 返回值 + +| **返回值** | **描述** | +|--------------------------|------------------------------------------------------------------------------------------------------------------------------------------| +| ContainerStatus status | 容器的状态信息 | +| map\ info | sandbox的额外信息,key是任意string,value是json格式的字符串,这些信息可以是任意调试内容。当verbose为true时info不能为空。(暂不支持配置) | + +#### UpdateContainerResources + +#### 接口原型 + +```text +rpc UpdateContainerResources(UpdateContainerResourcesRequest) returns (UpdateContainerResourcesResponse) {} +``` + +#### 接口描述 + +该接口用于更新容器资源配置。 + +#### 注意事项 + +- 该接口仅用于更新容器的资源配置,不能用于更新Pod的资源配置。 +- 当前不支持更新容器oom\_score\_adj配置。 + +#### 参数 + +| **参数成员** | **描述** | +|-------------------------------|-------------------| +| string container_id | 容器id | +| LinuxContainerResources linux | linux资源配置信息 | + +#### 返回值 + +无 + +#### ExecSync + +#### 接口原型 + +```text +rpc ExecSync(ExecSyncRequest) returns (ExecSyncResponse) {} +``` + +#### 接口描述 + +以同步的方式在容器中执行命令,采用的gRPC通讯方式。 + +#### 注意事项 + +执行一条单独的命令,不能打开终端与容器交互。 + +#### 参数 + + + + + + + + + + + + + + + +

参数成员

+

描述

+

string container_id

+

容器ID

+

repeated string cmd

+

待执行命令

+

int64 timeout

+

停止命令的超时时间(秒)。 缺省值:0(无超时限制)。 暂不支持

+
+ +#### 返回值 + + + + + + + + + + + + + + + +

返回值

+

描述

+

bytes stdout

+

捕获命令标准输出

+

bytes stderr

+

捕获命令标准错误输出

+

int32 exit_code

+

退出代码命令完成。 缺省值:0(成功)。

+
+ +#### Exec + +#### 接口原型 + +```text +rpc Exec(ExecRequest) returns (ExecResponse) {} +``` + +#### 接口描述 + +在容器中执行命令,采用的gRPC通讯方式从CRI服务端获取url,再通过获得的url与websocket服务端建立长连接,实现与容器的交互。 + +#### 注意事项 + +执行一条单独的命令,也能打开终端与容器交互。stdin/stdout/stderr之一必须是真的。如果tty为真,stderr必须是假的。 不支持多路复用, 在这种情况下, stdout和stderr的输出将合并为单流。 + +#### 参数 + + + + + + + + + + + + + + + + + + + + + + + + +

参数成员

+

描述

+

string container_id

+

容器ID

+

repeated string cmd

+

待执行的命令

+

bool tty

+

是否在TTY中执行命令

+

bool stdin

+

是否流式标准输入

+

bool stdout

+

是否流式标准输出

+

bool stderr

+

是否流式输出标准错误

+
+ +#### 返回值 + + + + + + + + + +

返回值

+

描述

+

string url

+

exec流服务器的完全限定URL

+
+ +#### Attach + +#### 接口原型 + +```text +rpc Attach(AttachRequest) returns (AttachResponse) {} +``` + +#### 接口描述 + +接管容器的1号进程,采用gRPC通讯方式从CRI服务端获取url,再通过获取的url与websocket服务端建立长连接,实现与容器的交互。 + +#### 参数 + + + + + + + + + + + + + + + + + + + + + +

参数成员

+

描述

+

string container_id

+

容器id

+

bool tty

+

是否在TTY中执行命令

+

bool stdin

+

是否流式标准输入

+

bool stdout

+

是否流式标准输出

+

bool stderr

+

是否流式标准错误

+
+ +#### 返回值 + + + + + + + + + +

返回值

+

描述

+

string url

+

attach流服务器的完全限定URL

+
+ +#### ContainerStats + +#### 接口原型 + +```text +rpc ContainerStats(ContainerStatsRequest) returns (ContainerStatsResponse) {} +``` + +#### 接口描述 + +返回单个容器占用资源信息,仅支持runtime类型为lcr的容器。 + +#### 参数 + + + + + + + + + +

参数成员

+

描述

+

string container_id

+

容器id

+
+ +#### 返回值 + +| **返回值** | **描述** | +|----------------------|---------------------------------------------------------| +| ContainerStats stats | 容器信息。
注:disk和inodes只支持oci格式镜像起的容器查询 | + +#### ListContainerStats + +#### 接口原型 + +```text +rpc ListContainerStats(ListContainerStatsRequest) returns (ListContainerStatsResponse) {} +``` + +#### 接口描述 + +返回多个容器占用资源信息,支持条件过滤 + +#### 参数 + +| **参数成员** | **描述** | +|-----------------------------|--------------| +| ContainerStatsFilter filter | 条件过滤参数 | + +#### 返回值 + +| **返回值** | **描述** | +|-------------------------------|-----------------------------------------------------------------| +| repeated ContainerStats stats | 容器信息的列表。注:disk和inodes只支持oci格式镜像启动的容器查询 | + +#### UpdateRuntimeConfig + +#### 接口原型 + +```text +rpc UpdateRuntimeConfig(UpdateRuntimeConfigRequest) returns (UpdateRuntimeConfigResponse); +``` + +#### 接口描述 + +提供标准的CRI接口,目的为了更新网络插件的Pod CIDR,当前CNI网络插件无需更新Pod CIDR,因此该接口只会记录访问日志。 + +#### 注意事项 + +接口操作不会对系统管理信息修改,只是记录一条日志。 + +#### 参数 + +| **参数成员** | **描述** | +|------------------------------|-------------------------| +| RuntimeConfig runtime_config | 包含Runtime要配置的信息 | + +#### 返回值 + +无 + +#### Status + +#### 接口原型 + +```text +rpc Status(StatusRequest) returns (StatusResponse) {}; +``` + +#### 接口描述 + +获取runtime和pod的网络状态,在获取网络状态时,会触发网络配置的刷新。 + +#### 注意事项 + +如果网络配置刷新失败,不会影响原有配置;只有刷新成功时,才会覆盖原有配置。 + +#### 参数 + + + + + + + + + +

参数成员

+

描述

+

bool verbose

+

是否显示关于Runtime额外的信息(暂不支持)

+
+ +#### 返回值 + +| **返回值** | **描述** | +|--------------------------|-------------------------------------------------------------------------------------------------------------| +| RuntimeStatus status | Runtime的状态 | +| map\ info | Runtime额外的信息,info的key为任意值,value为json格式,可包含任何debug信息;只有Verbose为true是才应该被赋值 | + +### Image服务 + +提供了从镜像仓库拉取、查看、和移除镜像的gRPC API。 + +#### ListImages + +#### 接口原型 + +```text +rpc ListImages(ListImagesRequest) returns (ListImagesResponse) {} +``` + +#### 接口描述 + +列出当前已存在的镜像信息。 + +#### 注意事项 + +为统一接口,对于embedded格式镜像,可以通过cri images查询到。但是因embedded镜像不是标准OCI镜像,因此查询得到的结果有以下限制: + +- 因embedded镜像无镜像ID,显示的镜像ID为镜像的config digest。 +- 因embedded镜像本身无digest仅有config的digest,且格式不符合OCI镜像规范,因此无法显示digest。 + +#### 参数 + +| **参数成员** | **描述** | +|------------------|----------------| +| ImageSpec filter | 筛选的镜像名称 | + +#### 返回值 + +| **返回值** | **描述** | +|-----------------------|--------------| +| repeated Image images | 镜像信息列表 | + +#### ImageStatus + +#### 接口原型 + +```text +rpc ImageStatus(ImageStatusRequest) returns (ImageStatusResponse) {} +``` + +#### 接口描述 + +查询指定镜像信息。 + +#### 注意事项 + +1. 查询指定镜像信息,若镜像不存在,则返回ImageStatusResponse,其中Image设置为nil。 +2. 为统一接口,对于embedded格式镜像,因不符合OCI格式镜像,缺少字段,无法通过本接口进行查询。 + +#### 参数 + +| **参数成员** | **描述** | +|-----------------|----------------------------------------| +| ImageSpec image | 镜像名称 | +| bool verbose | 查询额外信息,暂不支持,无额外信息返回 | + +#### 返回值 + +| **返回值** | **描述** | +|--------------------------|----------------------------------------| +| Image image | 镜像信息 | +| map\ info | 镜像额外信息,暂不支持,无额外信息返回 | + +#### PullImage + +#### 接口原型 + +```text + rpc PullImage(PullImageRequest) returns (PullImageResponse) {} +``` + +#### 接口描述 + +下载镜像。 + +#### 注意事项 + +当前支持下载public镜像,使用用户名、密码、auth信息下载私有镜像,不支持authconfig中的server\_address、identity\_token、registry\_token字段。 + +#### 参数 + +| **参数成员** | **描述** | +|---------------------------------|-----------------------------------| +| ImageSpec image | 要下载的镜像名称 | +| AuthConfig auth | 下载私有镜像时的验证信息 | +| PodSandboxConfig sandbox_config | 在Pod上下文中下载镜像(暂不支持) | + +#### 返回值 + + + + + + + + + +

返回值

+

描述

+

string image_ref

+

返回已下载镜像信息

+
+ +#### RemoveImage + +#### 接口原型 + +```text +rpc RemoveImage(RemoveImageRequest) returns (RemoveImageResponse) {} +``` + +#### 接口描述 + +删除指定镜像。 + +#### 注意事项 + +为统一接口,对于embedded格式镜像,因不符合OCI格式镜像,缺少字段,无法通过本接口使用image id进行删除。 + +#### 参数 + +| **参数成员** | **描述** | +|-----------------|------------------------| +| ImageSpec image | 要删除的镜像名称或者ID | + +#### 返回值 + +无 + +#### ImageFsInfo + +#### 接口原型 + +```text +rpc ImageFsInfo(ImageFsInfoRequest) returns (ImageFsInfoResponse) {} +``` + +#### 接口描述 + +查询存储镜像的文件系统信息。 + +#### 注意事项 + +查询到的为镜像元数据下的文件系统信息。 + +#### 参数 + +无 + +#### 返回值 + +| **返回值** | **描述** | +|--------------------------------------------|----------------------| +| repeated FilesystemUsage image_filesystems | 镜像存储文件系统信息 | + +### 约束 + +1. 如果创建sandbox时,PodSandboxConfig参数中配置了log\_directory,则所有属于该sandbox的container在创建时必须在ContainerConfig中指定log\_path,否则可能导致容器无法使用CRI接口启动,甚至无法使用CRI接口删除。 + + 容器的真实LOGPATH=log\_directory/log\_path,如果log\_path不配置,那么最终的LOGPATH会变为LOGPATH=log\_directory。 + + - 如果该路径不存在,isulad在启动容器时会创建一个软链接,指向最终的容器日志真实路径,此时log\_directory变成一个软链接,此时有两种情况: + 1. 第一种情况,如果该sandbox里其他容器也没配置log\_path,在启动其他容器时,log\_directory会被删除,然后重新指向新启动容器的log\_path,导致之前启动的容器日志指向后面启动容器的日志。 + 2. 第二种情况,如果该sandbox里其他容器配置了log\_path,则该容器的LOGPATH=log\_directory/log\_path,由于log\_directory实际是个软链接,使用log\_directory/log\_path为软链接指向容器真实日志路径时,创建会失败。 + + - 如果该路径存在,isulad在启动容器时首先会尝试删除该路径(非递归),如果该路径是个文件夹,且里面有内容,删除会失败,从而导致创建软链接失败,容器启动失败,删除该容器时,也会出现同样的现象,导致删除失败。 + +2. 如果创建sandbox时,PodSandboxConfig参数中配置了log\_directory,且container创建时在ContainerConfig中指定log\_path,那么最终的LOGPATH=log\_directory/log\_path,isulad不会递归的创建LOGPATH,因而用户必须保证dirname\(LOGPATH\)存在,即最终的日志文件的上一级路径存在。 +3. 如果创建sandbox时,PodSandboxConfig参数中配置了log\_directory,如果有两个或多个container创建时在ContainerConfig中指定了同一个log\_path,或者不同的sandbox内的容器最终指向的LOGPATH是同一路径,若容器启动成功,则后启动的容器日志路径会覆盖掉之前启动的容器日志路径。 +4. 如果远程镜像仓库中镜像内容发生变化,调用CRI Pull image接口重新下载该镜像时,若本地原来存储有原镜像,则原镜像的镜像名称、TAG会变更为“none” + + 举例如下: + + 本地已存储镜像: + + ```text + IMAGE TAG IMAGE ID SIZE + rnd-dockerhub.huawei.com/pproxyisulad/test latest 99e59f495ffaa 753kB + ``` + + 远程仓库中rnd-dockerhub.huawei.com/pproxyisulad/test:latest 镜像更新后,重新下载后: + + ```text + IMAGE TAG IMAGE ID SIZE + 99e59f495ffaa 753kB + rnd-dockerhub.huawei.com/pproxyisulad/test latest d8233ab899d41 1.42MB + ``` + + 使用isula images 命令行查询,REF显示为"-": + + ```text + REF IMAGE ID CREATED SIZE + rnd-dockerhub.huawei.com/pproxyisulad/test:latest d8233ab899d41 2019-02-14 19:19:37 1.42MB + - 99e59f495ffaa 2016-05-04 02:26:41 753kB + ``` + +5. iSulad CRI exec/attach接口采用websocket协议实现,需要采用同样协议的客户端与iSulad进行交互;使用exec/attach接口时,请避免进行串口大量数据及文件的传输,仅用于基本命令交互,若用户侧处理不及时将存在数据丢失的风险;同时请勿使用cri exec/attach接口进行二进制数据及文件传输。 +6. iSulad CRI exec/attach流式接口依赖libwebsockets实现,流式接口建议仅用于长连接交互使用,不建议在大并发场景下使用,可能会因为宿主机资源不足导致连接失败,建议并发量不超过100。 diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/errorLabelCheck.py b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/errorLabelCheck.py new file mode 100644 index 0000000000000000000000000000000000000000..153724c54b4695d4fd58e84faa84c0453650a4cb --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/errorLabelCheck.py @@ -0,0 +1,121 @@ +import re +import os +from common import get_pr_files + + +def check_unclosed_tags(html, markdown_lines, html_start_line): + """ + 检查未闭合的HTML标签,并返回错误信息。 + 行号信息映射到原始 Markdown 文件中的位置。 + """ + stack = [] + index = 0 + line_number = 1 + errors = [] + # 精确匹配 HTML 标签的正则表达式 + html_tag_pattern = re.compile(r'<([a-zA-Z]+)(?:\s[^>]*)?(?:/>|>)|') + + while index < len(html): + match = html_tag_pattern.search(html, index) + if not match: + break + + start_index = match.start() + end_index = match.end() + tag = match.group(0) + + # 更新行号 + line_number += html[index:start_index].count('\n') + + # 将 HTML 中的行号映射到原始 Markdown 文件中的行号 + markdown_line_number = html_start_line + line_number - 1 + + if tag.startswith(''): + # 自闭合标签,不压入栈中 + pass + else: + stack.append((tag_name, markdown_line_number)) # 记录标签名和行号 + + index = end_index + + # 检查栈中是否还有未闭合的开始标签 + if stack: + for tag, tag_line in stack: + errors.append(f"在文件中的第 {tag_line} 行发现未闭合的开始标签: <{tag}>") + + return errors + + +def extract_html_from_markdown(markdown): + html_blocks = [] + block_start_lines = [] + # 匹配 HTML 块的正则表达式,如
...
这种完整块 + html_block_pattern = re.compile(r'<([a-zA-Z]+)(?:\s[^>]*)?>(.*?)', re.DOTALL) + # 匹配单个 HTML 标签的正则表达式 + single_tag_pattern = re.compile(r'<([a-zA-Z]+)(?:\s[^>]*)?/>') + + # 先提取完整的 HTML 块 + for match in html_block_pattern.finditer(markdown): + start_index = match.start() + start_line = markdown[:start_index].count('\n') + 1 + html_blocks.append(match.group(0)) + block_start_lines.append(start_line) + + # 再提取单个自闭合 HTML 标签 + for match in single_tag_pattern.finditer(markdown): + start_index = match.start() + start_line = markdown[:start_index].count('\n') + 1 + html_blocks.append(match.group(0)) + block_start_lines.append(start_line) + + return html_blocks, block_start_lines + + +def process_markdown_file(file_path): + """ + 处理Markdown文件,修复未闭合的HTML标签。 + """ + with open(file_path, 'r', encoding='utf-8') as file: + content = file.read() + markdown_lines = content.split('\n') + + html_blocks, block_start_lines = extract_html_from_markdown(content) + all_errors = [] + + for html_block, start_line in zip(html_blocks, block_start_lines): + errors = check_unclosed_tags(html_block, markdown_lines, start_line) + all_errors.extend(errors) + + if all_errors: + for error in all_errors: + print(f"文件{file_path}中发现错误:{error}") + raise ValueError("发现未闭合的HTML标签") + else: + print(f"文件 {file_path} 中的HTML标签已检查,未发现未闭合标签。") + + +if __name__ == "__main__": + try: + pr_files = 'docs/zh/Cloud/ContainerEngine/iSulaContainerEngine/安装特性.md' + for pr_file in pr_files: + if not os.path.exists(pr_file): + print(f"文件不存在: {pr_file}") + continue + if ' ' in pr_file: + pr_file = pr_file.replace(' ', '\ ') + process_markdown_file(pr_file) + print(f"文件 {pr_file} 中的HTML标签已检查,未发现未闭合标签。") + except ValueError as e: + print(f"错误: {e}") + exit(1) # 退出脚本并返回非零状态码 diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/figures/zh-cn_image_0183048952.png b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/figures/zh-cn_image_0183048952.png new file mode 100644 index 0000000000000000000000000000000000000000..fe9074f8fba969795f1e1d40fb879e21d5fc2a7c Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/figures/zh-cn_image_0183048952.png differ diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/image-management.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/image-management.md new file mode 100644 index 0000000000000000000000000000000000000000..5824b3bf6bf347b0833e2302509ba6333c48bb83 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/image-management.md @@ -0,0 +1,495 @@ +# 镜像管理 + + + +- [镜像管理](#镜像管理) + - [docker镜像管理](#docker镜像管理) + - [登录到镜像仓库](#登录到镜像仓库) + - [从镜像仓库退出登录](#从镜像仓库退出登录) + - [从镜像仓库拉取镜像](#从镜像仓库拉取镜像) + - [删除镜像](#删除镜像) + - [加载镜像](#加载镜像) + - [列出镜像](#列出镜像) + - [检视镜像](#检视镜像) + - [双向认证](#双向认证) + - [embedded镜像管理](#embedded镜像管理) + - [加载镜像](#加载镜像-1) + - [列出镜像](#列出镜像-1) + - [检视镜像](#检视镜像-1) + - [删除镜像](#删除镜像-1) + + + +## docker镜像管理 + +### 登录到镜像仓库 + +#### 描述 + +isula login命令用于登录到镜像仓库。登录成功后可以使用isula pull命令从该镜像仓库拉取镜像。如果镜像仓库不需要密码,则拉取镜像前不需要执行该命令。 + +#### 用法 + +```bash +isula login [OPTIONS] SERVER +``` + +#### 参数 + +login命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表1 表1-20 login命令参数列表" 。 + +#### 示例 + +```bash +$ isula login -u abc my.csp-edge.com:5000 + +Login Succeeded +``` + +### 从镜像仓库退出登录 + +#### 描述 + +isula logout命令用于从镜像仓库退出登录。退出登录成功后再执行isula pull命令从该镜像仓库拉取镜像会因为未认证而拉取失败。 + +#### 用法 + +```bash +isula logout SERVER +``` + +#### 参数 + +logout命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表2 logout命令参数列表"。 + +#### 示例 + +```bash +$ isula logout my.csp-edge.com:5000 +Logout Succeeded +``` + +### 从镜像仓库拉取镜像 + +#### 描述 + +从镜像仓库拉取镜像到本地。 + +#### 用法 + +```bash +isula pull [OPTIONS] NAME[:TAG] +``` + +#### 参数 + +login命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表3 pull命令参数列表"。 + +#### 示例 + +```bash +$ isula pull localhost:5000/official/busybox +Image "localhost:5000/official/busybox" pulling +Image "localhost:5000/official/busybox@sha256:bf510723d2cd2d4e3f5ce7e93bf1e52c8fd76831995ac3bd3f90ecc866643aff" pulled +``` + +### 删除镜像 + +#### 描述 + +删除一个或多个镜像。 + +#### 用法 + +```bash +isula rmi [OPTIONS] IMAGE [IMAGE...] +``` + +#### 参数 + +rmi命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表4 rmi命令参数列表"。 + +#### 示例 + +```bash +$ isula rmi rnd-dockerhub.huawei.com/official/busybox +Image "rnd-dockerhub.huawei.com/official/busybox" removed +``` + +### 添加镜像标签 + +#### 描述 + +tag命令用于添加镜像标签 + +#### 用法 + +```bash +isula tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG] +``` + +#### 参数 + +tag命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表8 tag命令参数列表"。 + +#### 示例 + +```bash +$ isula tag busybox:latest test:latest +``` + +### 加载镜像 + +#### 描述 + +从一个tar包加载镜像。该tar包必须是使用docker save命令导出的tar包或格式一致的tar包。 + +#### 用法 + +```bash +isula load [OPTIONS] +``` + +#### 参数 + +load命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表5 load命令参数列表"。 + +#### 示例 + +```bash +$ isula load -i busybox.tar +Load image from "/root/busybox.tar" success +``` + +### 列出镜像 + +#### 描述 + +列出当前环境中所有镜像。 + +#### 用法 + +```bash +isula images [OPTIONS] +``` + +#### 参数 + +images命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表6 images命令参数列表"。 + +#### 示例 + +```bash +$ isula images +REPOSITORY TAG IMAGE ID CREATED SIZE +busybox latest beae173ccac6 2021-12-31 03:19:41 1.184MB +``` + +### 检视镜像 + +#### 描述 + +返回该镜像的配置信息。可以使用-f参数过滤出需要的信息。 + +#### 用法 + +```bash +isula inspect [options] CONTAINER|IMAGE [CONTAINER|IMAGE...] +``` + +#### 参数 + +inspect命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表7 inspect命令参数列表"。 + +#### 示例 + +```bash +$ isula inspect -f "{{json .image.id}}" rnd-dockerhub.huawei.com/official/busybox +"e4db68de4ff27c2adfea0c54bbb73a61a42f5b667c326de4d7d5b19ab71c6a3b" +``` + +### 双向认证 + +#### 描述 + +开启该功能后isulad和镜像仓库之间的通信采用https通信,isulad和镜像仓库都会验证对方的合法性。 + +#### 用法 + +要支持该功能,需要镜像仓库支持该功能,同时isulad也需要做相应的配置: + +1. 修改isulad的配置\(默认路径/etc/isulad/daemon.json\),将配置里的use-decrypted-key项配置为false。 +2. 需要将相关的证书放置到/etc/isulad/certs.d目录下对应的镜像仓库命名的文件夹下,证书具体的生成方法见docker的官方链接: + - [https://docs.docker.com/engine/security/certificates/](https://docs.docker.com/engine/security/certificates/) + - [https://docs.docker.com/engine/security/https/](https://docs.docker.com/engine/security/https/) + +3. 执行systemctl restart isulad重启isulad。 + +#### 参数 + +可以在/etc/isulad/daemon.json中配置参数,也可以在启动isulad时携带参数: + +```bash +isulad --use-decrypted-key=false +``` + +#### 示例 + +配置use-decrypted-key参数为false + +```bash +$ cat /etc/isulad/daemon.json +{ + "group": "isulad", + "graph": "/var/lib/isulad", + "state": "/var/run/isulad", + "engine": "lcr", + "log-level": "ERROR", + "pidfile": "/var/run/isulad.pid", + "log-opts": { + "log-file-mode": "0600", + "log-path": "/var/lib/isulad", + "max-file": "1", + "max-size": "30KB" + }, + "log-driver": "stdout", + "hook-spec": "/etc/default/isulad/hooks/default.json", + "start-timeout": "2m", + "storage-driver": "overlay2", + "storage-opts": [ + "overlay2.override_kernel_check=true" + ], + "registry-mirrors": [ + "docker.io" + ], + "insecure-registries": [ + "rnd-dockerhub.huawei.com" + ], + "pod-sandbox-image": "", + "image-opt-timeout": "5m", + "native.umask": "secure", + "network-plugin": "", + "cni-bin-dir": "", + "cni-conf-dir": "", + "image-layer-check": false, + "use-decrypted-key": false, + "insecure-skip-verify-enforce": false +} +``` + +将证书放到对应的目录下 + +```bash +$ pwd +/etc/isulad/certs.d/my.csp-edge.com:5000 +$ ls +ca.crt tls.cert tls.key +``` + +重启isulad + +```bash +$ systemctl restart isulad +``` + +执行pull命令从仓库下载镜像 + +```bash +$ isula pull my.csp-edge.com:5000/busybox +Image "my.csp-edge.com:5000/busybox" pulling +Image "my.csp-edge.com:5000/busybox@sha256:f1bdc62115dbfe8f54e52e19795ee34b4473babdeb9bc4f83045d85c7b2ad5c0" pulled +``` + +### 导入rootfs + +#### 描述 + +把包含了一个rootfs的tar包导入为镜像,该tar包一般是之前使用export命令导出的,也可以是格式兼容的包含rootfs的tar包。目前支持 +格式(.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz),请勿使用其他格式的tar包进行导入。 + +#### 用法 + +```bash +isula import file REPOSITORY[:TAG] +``` + +导入成功后打印的字符串是导入的rootfs生成的镜像id + +#### 参数 + +import命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表9 import命令参数列表"。 + +#### 示例 + +```bash +$ isula import busybox.tar test +sha256:441851e38dad32478e6609a81fac93ca082b64b366643bafb7a8ba398301839d +$ isula images +REPOSITORY TAG IMAGE ID CREATED SIZE +test latest 441851e38dad 2020-09-01 11:14:35 1.168 MB +``` + +### 导出rootfs + +#### 描述 + +把一个容器的rootfs文件系统内容导出成tar包,导出的rootfs的tar包可以在后面使用import功能重新导入成镜像。 + +#### 用法 + +```bash +isula export [OPTIONS] [ID|NAME] +``` + +#### 参数 + +export命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表10 export命令参数列表"。 + +#### 示例 + +```bash +$ isula run -tid --name container_test test sh +d7e601c2ef3eb8d378276d2b42f9e58a2f36763539d3bfcaf3a0a77dc668064b +$ isula export -o rootfs.tar d7e601c +$ ls +rootfs.tar +``` + +## embedded镜像管理 + +### 加载镜像 + +#### 描述 + +根据embedded镜像的manifest加载镜像。注意--type的值必须填写embedded。 + +#### 用法 + +```bash +isula load [OPTIONS] --input=FILE --type=TYPE +``` + +#### 参数 + +load命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表5 load命令参数列表"。 + +#### 示例 + +```bash +$ isula load -i test.manifest --type embedded +Load image from "/root/work/bugfix/tmp/ci_testcase_data/embedded/img/test.manifest" success +``` + +### 列出镜像 + +#### 描述 + +列出当前环境中所有镜像。 + +#### 用法 + +```bash +isula images [OPTIONS] +``` + +#### 参数 + +images命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表6 images命令参数列表"。 + +#### 示例 + +```bash +$ isula images +REPOSITORY TAG IMAGE ID CREATED SIZE +busybox latest beae173ccac6 2021-12-31 03:19:41 1.184MB +``` + +### 检视镜像 + +#### 描述 + +返回该镜像的配置信息。可以使用-f参数过滤出需要的信息。 + +#### 用法 + +```bash +isula inspect [options] CONTAINER|IMAGE [CONTAINER|IMAGE...] +``` + +#### 参数 + +inspect命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表7 inspect命令参数列表"。 + +#### 示例 + +```bash +$ isula inspect -f "{{json .created}}" test:v1 +"2018-03-01T15:55:44.322987811Z" +``` + +### 删除镜像 + +#### 描述 + +删除一个或多个镜像。 + +#### 用法 + +```bash +isula rmi [OPTIONS] IMAGE [IMAGE...] +``` + +#### 参数 + +rmi命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表4 rmi命令参数列表"。 + +#### 示例 + +```bash +$ isula rmi test:v1 +Image "test:v1" removed +``` + +### 添加名称 + +#### 描述 + +给镜像添加一个名称。 + +#### 用法 + +```bash +isula tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG] +``` + +#### 参数 + +tag命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表8 tag命令参数列表"。 + +#### 示例 + +```bash +$ isula tag test:v1 test:v2 +``` + +### 导入镜像 + +#### 描述 + +将tar格式的rootfs导入生成一个新的镜像,该tar包必须是通过export命令导出的tar包。 + +#### 用法 + +```bash +isula export [command options] [ID|NAME] +``` + +#### 参数 + +export命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表9 export命令参数列表"。 + +#### 示例 + +```bash +$ isula export -o test.tar containername +``` diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/installation-configuration.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/installation-configuration.md new file mode 100644 index 0000000000000000000000000000000000000000..1de46d31627c6164e373362404094728fda57bbd --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/installation-configuration.md @@ -0,0 +1,1022 @@ +# 安装与配置 + +本章介绍iSulad的安装、安装后配置,以及升级和卸载的方法。 +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> iSulad的安装、升级、卸载均需要使用root权限。 + +## 安装方法 + +iSulad可以通过yum或rpm命令两种方式安装,由于yum会自动安装依赖,而rpm命令需要手动安装所有依赖,所以推荐使用yum安装。 + +这里给出两种安装方式的操作方法。 + +- (推荐)使用yum安装iSulad,参考命令如下: + + ```bash + # sudo yum install -y iSulad + ``` + +- 使用rpm安装iSulad,需要下载iSulad及其所有依赖的RPM包,然后手动安装。安装单个iSulad的RPM包(依赖包安装方式相同),参考命令如下: + + ```bash + # sudo rpm -ihv iSulad-xx.xx.xx-xx.xxx.aarch64.rpm + ``` + +## 配置方法 + +iSulad 安装完成后,可以根据需要进行相关配置。 + +### 配置方式 + +轻量级容器引擎(iSulad)服务端daemon为isulad,isulad可以通过配置文件进行配置,也可以通过命令行的方式进行配置,例如:isulad --xxx,优先级从高到低是:命令行方式\>配置文件\>代码中默认配置。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 如果采用systemd管理iSulad进程,修改/etc/sysconfig/iSulad文件中的OPTIONS字段,等同于命令行方式进行配置。 + +- **命令行方式** + + 在启动服务的时候,直接通过命令行进行配置。其配置选项可通过以下命令查阅: + + ```bash + # isulad --help + isulad + + lightweight container runtime daemon + + Usage: isulad [global options] + + GLOBAL OPTIONS: + + --authorization-plugin Use authorization plugin + --cgroup-parent Set parent cgroup for all containers + --cni-bin-dir The full path of the directory in which to search for CNI plugin binaries. Default: /opt/cni/bin + --cni-conf-dir The full path of the directory in which to search for CNI config files. Default: /etc/cni/net.d + --container-log-driver Set default container log driver, such as: json-file + --container-log-opts Set default container log driver options, such as: max-file=7 to set max number of container log files + --default-ulimit Default ulimits for containers (default []) + -e, --engine Select backend engine + -g, --graph Root directory of the iSulad runtime + -G, --group Group for the unix socket(default is isulad) + --help Show help + --hook-spec Default hook spec file applied to all containers + -H, --host The socket name used to create gRPC server + --image-layer-check Check layer intergrity when needed + --insecure-registry Disable TLS verification for the given registry + --insecure-skip-verify-enforce Force to skip the insecure verify(default false) + --log-driver Set daemon log driver, such as: file + -l, --log-level Set log level, the levels can be: FATAL ALERT CRIT ERROR WARN NOTICE INFO DEBUG TRACE + --log-opt Set daemon log driver options, such as: log-path=/tmp/logs/ to set directory where to store daemon logs + --native.umask Default file mode creation mask (umask) for containers + --network-plugin Set network plugin, default is null, support null and cni + -p, --pidfile Save pid into this file + --pod-sandbox-image The image whose network/ipc namespaces containers in each pod will use. (default "pause-${machine}:3.0") + --registry-mirrors Registry to be prepended when pulling unqualified images, can be specified multiple times + --selinux-enabled Enable selinux support + --start-timeout timeout duration for waiting on a container to start before it is killed + -S, --state Root directory for execution state files + --storage-driver Storage driver to use(default overlay2) + -s, --storage-opt Storage driver options + --tls Use TLS; implied by --tlsverify + --tlscacert Trust certs signed only by this CA (default "/root/.iSulad/ca.pem") + --tlscert Path to TLS certificate file (default "/root/.iSulad/cert.pem") + --tlskey Path to TLS key file (default "/root/.iSulad/key.pem") + --tlsverify Use TLS and verify the remote + --use-decrypted-key Use decrypted private key by default(default true) + --userns-remap User/Group setting for user namespaces + -V, --version Print the version + --websocket-server-listening-port CRI websocket streaming service listening port (default 10350) + ``` + + 示例: 启动isulad,并将日志级别调整成DEBUG + + ```bash + # isulad -l DEBUG + ``` + +- **配置文件方式** + + isulad配置文件为/etc/isulad/daemon.json和/etc/isulad/daemon_constants.json,各配置字段说明如下: + + 配置文件/etc/isulad/daemon.json + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

配置参数

+

配置文件示例

+

参数解释

+

备注

+

-e, --engine

+

"engine": "lcr"

+

iSulad的运行时,默认是lcr

+

+

-G, --group

+

"group": "isulad"

+

socket所属组

+

+

--hook-spec

+

"hook-spec": "/etc/default/isulad/hooks/default.json"

+

针对所有容器的默认钩子配置文件

+

+

-H, --host

+

"hosts": "unix:///var/run/isulad.sock"

+

通信方式

+

除本地socket外,还支持tcp://ip:port方式,port范围(0-65535,排除被占用端口)

+

--log-driver

+

"log-driver": "file"

+

日志驱动配置

+

+

-l, --log-level

+

"log-level": "ERROR"

+

设置日志输出级别

+

+

--log-opt

+

"log-opts": {

+

"log-file-mode": "0600",

+

"log-path": "/var/lib/isulad",

+

"max-file": "1",

+

"max-size": "30KB"

+

}

+

日志相关的配置

+

可以指定max-file,max-size,log-path。max-file指日志文件个数;max-size指日志触发防爆的阈值,若max-file为1,max-size失效;log-path指定日志文件存储路径;log-file-mode用于设置日志文件的读写权限,格式要求必须为八进制格式,如0666。

+

--container-log-driver

+

"container-log": {

+

"driver": "json-file"

+

}

+

容器串口日志驱动默认配置

+

指定所有容器的默认串口日志的驱动

+

--start-timeout

+

"start-timeout": "2m"

+

启动容器的耗时

+

+

+

"default-runtime": "lcr"

+

创建容器时的runtime运行时,默认是lcr

+

当命令行和配置文件均未指定时,默认为lcr,runtime的三种指定方式优先级:命令行>配置文件>默认lcr,当前支持lcr、kata-runtime。

+

+
"runtimes":  {
+        "kata-runtime": {
+          "path": "/usr/bin/kata-runtime",
+          "runtime-args": [
+            "--kata-config",
+            "/usr/share/defaults/kata-containers/configuration.toml"
+          ]
+        }
+    }
+

启动容器时,通过此字段指定多runtimes配置,在此集合中的元素均为有效的启动容器的runtime运行时。

+

容器的runtime白名单,在此集合中的自定义runtime才是有效的。示例为以kata-runtime为例的配置。

+

-p, --pidfile

+

"pidfile": "/var/run/isulad.pid"

+

保存pid的文件

+

当启动一个容器引擎的时候不需要配置,当需要启动两个以上的容器引擎时才需要配置。

+

-g, --graph

+

"graph": "/var/lib/isulad"

+

iSulad运行时的根目录

+

-S, --state

+

"state": "/var/run/isulad"

+

执行文件的根目录

+

--storage-driver

+

"storage-driver": "overlay2"

+

镜像存储驱动,默认为overlay2

+

当前只支持overlay2

+

-s, --storage-opt

+

"storage-opts": [ "overlay2.override_kernel_check=true" ]

+

镜像存储驱动配置选项

+

可使用的选项为:

+
overlay2.override_kernel_check=true # 忽略内核版本检查
+    overlay2.size=${size} # 设置rootfs quota限额为${size}大小
+    overlay2.basesize=${size} #等价于overlay2.size
+

--registry-mirrors

+

"registry-mirrors": [ "docker.io" ]

+

镜像仓库地址

+

+

--insecure-registry

+

"insecure-registries": [ ]

+

不使用TLS校验的镜像仓库

+

+

--native.umask

+

"native.umask": "secure"

+

容器umask策略,默认"secure",normal为不安全配置

+

设置容器umask值。

+

支持配置空字符(使用缺省值0027)、"normal"、"secure":

+
normal    # 启动的容器umask值为0022
+    secure    # 启动的容器umask值为0027(缺省值)
+

--pod-sandbox-image

+

"pod-sandbox-image": "rnd-dockerhub.huawei.com/library/pause-aarch64:3.0"

+

pod默认使用镜像,默认为"rnd-dockerhub.huawei.com/library/pause-${machine}:3.0"

+

+

--network-plugin

+

"network-plugin": ""

+

指定网络插件,默认为空字符,表示无网络配置,创建的sandbox只有loop网卡。

+

支持cni和空字符,其他非法值会导致isulad启动失败。

+

--cni-bin-dir

+

"cni-bin-dir": ""

+

指定cni插件依赖的二进制的存储位置

+

默认为/opt/cni/bin

+

--cni-conf-dir

+

"cni-conf-dir": ""

+

指定cni网络配置文件的存储位置

+

默认为/etc/cni/net.d

+

--image-layer-check=false

+

"image-layer-check": false

+

开启镜像层完整性检查功能,设置为true;关闭该功能,设置为false。默认为关闭。

+

isulad启动时会检查镜像层的完整性,如果镜像层被破坏,则相关的镜像不可用。isulad进行镜像完整性校验时,无法校验内容为空的文件和目录,以及链接文件。因此若镜像因掉电导致上述类型文件丢失,isulad的镜像数据完整性校验可能无法识别。isulad版本变更时需要检查是否支持该参数,如果不支持,需要从配置文件中删除。

+

--insecure-skip-verify-enforce=false

+

"insecure-skip-verify-enforce": false

+

Bool类型,是否强制跳过证书的主机名/域名验证,默认为false。当设置为true时,为不安全配置,会跳过证书的主机名/域名验证

+

默认为false(不跳过),注意:因isulad使用的yajl json 解析库限制,若在/etc/isulad/daemon.json配置文件中配置非Bool类型的其他符合json格式的值时,isulad将使用缺省值false。

+

--use-decrypted-key=true

+

"use-decrypted-key": true

+

Bool类型,指定是否使用不加密的私钥。指定为true,表示使用不加密的私钥;指定为false,表示使用的为加密后的私钥,即需要进行双向认证。

+

默认配置为true(使用不加密的私钥),注意:因isulad使用的yajl json 解析库限制,若在/etc/isulad/daemon.json配置文件中配置非Bool类型的其他符合json格式的值时,isulad将使用缺省值true。

+

--tls

+

"tls":false

+

Bool类型,是否使用TLS

+

缺省值为false, 仅用于-H tcp://IP:PORT方式

+

--tlsverify

+

"tlsverify":false

+

Bool类型,是否使用TLS,并验证远程访问

+

仅用于-H tcp://IP:PORT方式

+

--tlscacert

+

--tlscert

+

--tlskey

+

"tls-config": {

+

"CAFile": "/root/.iSulad/ca.pem",

+

"CertFile": "/root/.iSulad/server-cert.pem",

+

"KeyFile":"/root/.iSulad/server-key.pem"

+

}

+

TLS证书相关的配置

+

仅用于-H tcp://IP:PORT方式

+

--authorization-plugin

+

"authorization-plugin": "authz-broker"

+

用户权限认证插件

+

当前只支持authz-broker

+

--cgroup-parent

+

"cgroup-parent": "lxc/mycgroup"

+

字符串类型,容器默认cgroup父路径

+

指定daemon端容器默认的cgroup父路径,如果客户端指定了--cgroup-parent,以客户端参数为准。

+

注意:如果启了一个容器A,然后启一个容器B,容器B的cgroup父路径指定为容器A的cgroup路径,在删除容器的时候需要先删除容器B再删除容器A,否则会导致cgroup资源残留。

+

--default-ulimits

+

"default-ulimits": {

+

"nofile": {

+

"Name": "nofile",

+

"Hard": 6400,

+

"Soft": 3200

+

}

+

}

+

ulimit指定限制的类型,soft值及hard值

+

指定限制的资源类型,如“nofile”。两个字段名字必须相同,即都为nofile,否则会报错。Hard指定的值需要大于等于Soft'。如果Hard字段或者Soft字段未设置,则默认该字段默认为0。

+

--websocket-server-listening-port

+

"websocket-server-listening-port": 10350

+

设置CRI websocket流式服务侦听端口,默认端口号10350

+

指定CRI websocket流式服务侦听端,如果客户端指定了

+

--websocket-server-listening-port,以客户端参数为准。端口范围1024-49151

+

+

"cri-runtimes": {

+

"kata": "io.containerd.kata.v2"

+

}

+

自定义cri runtimes的映射

+

isulad通过自定义的cri runtimes映射,可以将runtimeclass转换为对应的runtime。

+
+ + 配置文件/etc/isulad/daemon_constants.json + + + + + + + + + + + + + + + + + + + +

配置参数

+

配置文件示例

+

参数解释

+

备注

+

不支持

+

"default-host": "docker.io"

+

如果镜像名以该镜像仓库名为前缀,则保存和显示时会去除该镜像仓库名前缀

+

一般情况下该参数不需要修改

+

不支持

+

"registry-transformation": {

+

"docker.io": "registry-1.docker.io",

+

"index.docker.io": "registry-1.docker.io"

+

}

+

"key":"value"格式,表示从key指定的仓库拉取镜像时实际从value指定的仓库拉取镜像

+

一般情况下该参数不需要修改

+
+ + 示例: + + ```bash + # cat /etc/isulad/daemon.json + { + "group": "isulad", + "default-runtime": "lcr", + "graph": "/var/lib/isulad", + "state": "/var/run/isulad", + "engine": "lcr", + "log-level": "ERROR", + "pidfile": "/var/run/isulad.pid", + "log-opts": { + "log-file-mode": "0600", + "log-path": "/var/lib/isulad", + "max-file": "1", + "max-size": "30KB" + }, + "log-driver": "stdout", + "hook-spec": "/etc/default/isulad/hooks/default.json", + "start-timeout": "2m", + "storage-driver": "overlay2", + "storage-opts": [ + "overlay2.override_kernel_check=true" + ], + "registry-mirrors": [ + "docker.io" + ], + "insecure-registries": [ + "rnd-dockerhub.huawei.com" + ], + "pod-sandbox-image": "", + "native.umask": "secure", + "network-plugin": "", + "cni-bin-dir": "", + "cni-conf-dir": "", + "image-layer-check": false, + "use-decrypted-key": true, + "insecure-skip-verify-enforce": false, + "cri-runtime": { + "kata": "io.containerd.kata.v2" + } + } + + # cat /etc/isulad/daemon.json + { + "default-host": "docker.io", + "registry-transformation":{ + "docker.io": "registry-1.docker.io", + "index.docker.io": "registry-1.docker.io" + } + } + + ``` + + > ![](./public_sys-resources/icon-notice.gif) **须知:** + > + > 默认配置文件/etc/isulad/daemon.json仅供参考,请根据实际需要进行配置。 + +### 存储说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

文件名

+

文件路径

+

内容

+

\*

+

/etc/default/isulad/

+

存放isulad的OCI配置文件和钩子模板文件,文件夹下的配置文件权限设置为0640,sysmonitor检查脚本权限为0550

+

\*

+

/etc/isulad/

+

isulad的默认配置文件和seccomp的默认配置文件

+

isulad.sock

+

/var/run/

+

管道通信文件,客户端和isulad的通信使用的socket文件

+

isulad.pid

+

/var/run/

+

存放isulad的PID,同时也是一个文件锁防止启动多个isulad实例

+

\*

+

/run/lxc/

+

文件锁文件,isula运行过程创建的文件

+

\*

+

/var/run/isulad/

+

实时通讯缓存文件,isulad运行过程创建的文件

+

\*

+

/var/run/isula/

+

实时通讯缓存文件,isula运行过程创建的文件

+

\*

+

/var/lib/isulad/

+

isulad运行的根目录,存放创建的容器配置、日志的默认路径、数据库文件、mount点等

+

/var/lib/isulad/mnt/ :容器rootfs的mount点

+

/var/lib/isulad/engines/lcr/ :存放lcr容器配置目录,每个容器一个目录(以容器名命名)

+
+ +### 约束限制 + +- 高并发场景(并发启动200容器)下,glibc的内存管理机制会导致内存空洞以及虚拟内存较大(例如10GB)的问题。该问题是高并发场景下glibc内存管理机制的限制,而不是内存泄露,不会导致内存消耗无限增大。可以通过设置MALLOC\_ARENA\_MAX环境变量来减少虚拟内存的问题,而且可以增大减少物理内存的概率。但是这个环境变量会导致iSulad的并发性能下降,需要用户根据实际情况做配置。 + + 参考实践情况,平衡性能和内存,可以设置MALLOC_ARENA_MAX为4。(在arm64服务器上面对iSulad的性能影响在10%以内) + + 配置方法: + 1. 手动启动iSulad的场景,可以直接export MALLOC_ARENA_MAX=4,然后再启动iSulad即可。 + 2. systemd管理iSulad的场景,可以修改/etc/sysconfig/iSulad,增加一条MALLOC_ARENA_MAX=4即可。 + +- 为daemon指定各种运行目录时的注意事项 + + 以--root为例,当使用/new/path/作为daemon新的Root Dir时,如果/new/path/下已经存在文件,且目录或文件名与isulad需要使用的目录或文件名冲突(例如:engines、mnt等目录)时,isulad可能会更新原有目录或文件的属性,包括属主、权限等为自己的属主和权限。 + + 所以,用户需要明白重新指定各种运行目录和文件,会对冲突目录、文件属性的影响。建议用户指定的新目录或文件为isulad专用,避免冲突导致的文件属性变化以及带来的安全问题。 + +- 日志文件管理: + + > ![](./public_sys-resources/icon-notice.gif) **须知:** + > + > 日志功能对接: iSulad由systemd管理,日志也由systemd管理,然后传输给rsyslogd。rsyslog默认会对写日志速度有限制,可以通过修改/etc/rsyslog.conf文件,增加"$imjournalRatelimitInterval 0"配置项,然后重启rsyslogd的服务即可。 + +- 命令行参数解析限制 + + 使用iSulad命令行接口时,其参数解析方式与docker略有不同,对于命令行中带参数的flag,不管使用长flag还是短flag,只会将该flag后第一个空格或与flag直接相连接的'='后的字符串作为flag的参数,具体如下: + + 1. 使用短flag时,与“-”连接的字符串中的每个字符都被当作短flag(当有=号时,=号后的字符串当成=号前的短flag的参数)。 + + isula run -du=root busybox 等价于 isula run -du root busybox 或 isula run -d -u=root busybox 或 isula run -d -u root busybox ,当使用isula run -du:root时,由于-:不是有效的短flag,因此会报错。前述的命令行也等价于isula run -ud root busybox,但不推荐这种使用方式,可能带来语义困扰。 + + 2. 使用长flag时,与“--”连接的字符串作为一个整体当成长flag,若包含=号,则=号前的字符串为长flag,=号后的为参数。 + + ```bash + isula run --user=root busybox + ``` + + 等价于 + + ```bash + isula run --user root busybox + ``` + +- 启动一个isulad容器,不能够以非root用户进行isula run -i/-t/-ti以及isula attach/exec操作。 +- isulad的临时文件存放路径默认为/var/lib/isulad/isulad_tmpdir,如果更换了isulad的根目录,则路径为`$isulad_root/isulad_tmpdir`。如果需要修改isulad存放临时文件的目录,可以通过在启动isulad前配置ISULAD_TMPDIR环境变量来实现,isulad启动时会进行检查,如果发现配置了ISULAD_TMPDIR环境变量,则会将`$ISULAD_TMPDIR/isulad_tmpdir`目录作为临时文件存放的路径,注意`$ISULAD_TMPDIR`下面的不要存放名称为isulad_tmpdir的文件/文件夹等,因为isulad启动时会递归删除`$ISULAD_TMPDIR/isulad_tmpdir`目录来防止数据残留。同时请确保`$ISULAD_TMPDIR`路径只有root用户可以访问,防止其他用户操作导致的安全问题。 + +### DAEMON多端口的绑定 + +## 描述 + +daemon端可以绑定多个unix socket或者tcp端口,并在这些端口上侦听,客户端可以通过这些端口和daemon端进行交互。 + +## 接口 + +用户可以在/etc/isulad/daemon.json文件的hosts字段配置一个或者多个端口。当然用户也可以不指定hosts。 + +```conf +{ + "hosts": [ + "unix:///var/run/isulad.sock", + "tcp://localhost:5678", + "tcp://127.0.0.1:6789" + ] +} +``` + +用户也可以在/etc/sysconfig/iSulad中通过-H或者--host配置端口。用户同样可以不指定hosts。 + +```conf +OPTIONS='-H unix:///var/run/isulad.sock --host tcp://127.0.0.1:6789' +``` + +如果用户在daemon.json文件及iSulad中均未指定hosts,则daemon在启动之后将默认侦听unix:///var/run/isulad.sock。 + +## 限制 + +- 用户不可以在/etc/isulad/daemon.json和/etc/sysconfig/iSulad两个文件中同时指定hosts,如果这样做将会出现错误,isulad无法正常启动; + + ```text + unable to configure the isulad with file /etc/isulad/daemon.json: the following directives are specified both as a flag and in the configuration file: hosts: (from flag: [unix:///var/run/isulad.sock tcp://127.0.0.1:6789], from file: [unix:///var/run/isulad.sock tcp://localhost:5678 tcp://127.0.0.1:6789]) + ``` + +- 若指定的host是unix socket,则必须是合法的unix socket,需要以"unix://"开头,后跟合法的socket绝对路径; +- 若指定的host是tcp端口,则必须是合法的tcp端口,需要以"tcp://"开头,后跟合法的IP地址和端口,IP地址可以为localhost; +- 可以指定至多10个有效的端口,超过10个则会出现错误,isulad无法正常启动。 + +### 配置TLS认证与开启远程访问 + +#### 描述 + +iSulad采用C/S模式进行设计,在默认情况,iSulad守护进程isulad只侦听本地/var/run/isulad.sock,因此只能在本地通过客户端isula执行相关命令操作容器。为了能使isula可以远程访问容器,isulad守护进程需要通过tcp:ip的方式侦听远程访问的端口。然而,仅通过简单配置tcp ip:port进行侦听,这样会导致所有的ip都可以通过调用`isula -H tcp://:port`与isulad通信,容易导致安全问题,因此推荐使用较安全版本的TLS(**Transport Layer Security - 安全传输层协议**)方式进行远程访问。 + +#### 生成TLS证书 + +- 明文私钥和证书生成方法示例 + + ```bash + #!/bin/bash + set -e + echo -n "Enter pass phrase:" + read password + echo -n "Enter public network ip:" + read publicip + echo -n "Enter host:" + read HOST + + echo " => Using hostname: $publicip, You MUST connect to iSulad using this host!" + + mkdir -p $HOME/.iSulad + cd $HOME/.iSulad + rm -rf $HOME/.iSulad/* + + echo " => Generating CA key" + openssl genrsa -passout pass:$password -aes256 -out ca-key.pem 4096 + echo " => Generating CA certificate" + openssl req -passin pass:$password -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem -subj "/C=CN/ST=zhejiang/L=hangzhou/O=Huawei/OU=iSulad/CN=iSulad@huawei.com" + echo " => Generating server key" + openssl genrsa -passout pass:$password -out server-key.pem 4096 + echo " => Generating server CSR" + openssl req -passin pass:$password -subj /CN=$HOST -sha256 -new -key server-key.pem -out server.csr + echo subjectAltName = DNS:$HOST,IP:$publicip,IP:127.0.0.1 >> extfile.cnf + echo extendedKeyUsage = serverAuth >> extfile.cnf + echo " => Signing server CSR with CA" + openssl x509 -req -passin pass:$password -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf + echo " => Generating client key" + openssl genrsa -passout pass:$password -out key.pem 4096 + echo " => Generating client CSR" + openssl req -passin pass:$password -subj '/CN=client' -new -key key.pem -out client.csr + echo " => Creating extended key usage" + echo extendedKeyUsage = clientAuth > extfile-client.cnf + echo " => Signing client CSR with CA" + openssl x509 -req -passin pass:$password -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile-client.cnf + rm -v client.csr server.csr extfile.cnf extfile-client.cnf + chmod -v 0400 ca-key.pem key.pem server-key.pem + chmod -v 0444 ca.pem server-cert.pem cert.pem + ``` + +- 加密私钥和证书请求文件生成方法示例 + + ```bash + #!/bin/bash + + echo -n "Enter public network ip:" + read publicip + echo -n "Enter pass phrase:" + read password + + # remove certificates from previous execution. + rm -f *.pem *.srl *.csr *.cnf + + + # generate CA private and public keys + echo 01 > ca.srl + openssl genrsa -aes256 -out ca-key.pem -passout pass:$password 2048 + openssl req -subj '/C=CN/ST=zhejiang/L=hangzhou/O=Huawei/OU=iSulad/CN=iSulad@huawei.com' -new -x509 -days $DAYS -passin pass:$password -key ca-key.pem -out ca.pem + + # create a server key and certificate signing request (CSR) + openssl genrsa -aes256 -out server-key.pem -passout pass:$PASS 2048 + openssl req -new -key server-key.pem -out server.csr -passin pass:$password -subj '/CN=iSulad' + + echo subjectAltName = DNS:iSulad,IP:${publicip},IP:127.0.0.1 > extfile.cnf + echo extendedKeyUsage = serverAuth >> extfile.cnf + # sign the server key with our CA + openssl x509 -req -days $DAYS -passin pass:$password -in server.csr -CA ca.pem -CAkey ca-key.pem -out server-cert.pem -extfile extfile.cnf + + # create a client key and certificate signing request (CSR) + openssl genrsa -aes256 -out key.pem -passout pass:$password 2048 + openssl req -subj '/CN=client' -new -key key.pem -out client.csr -passin pass:$password + + # create an extensions config file and sign + echo extendedKeyUsage = clientAuth > extfile.cnf + openssl x509 -req -days 365 -passin pass:$password -in client.csr -CA ca.pem -CAkey ca-key.pem -out cert.pem -extfile extfile.cnf + + # remove the passphrase from the client and server key + openssl rsa -in server-key.pem -out server-key.pem -passin pass:$password + openssl rsa -in key.pem -out key.pem -passin pass:$password + + # remove generated files that are no longer required + rm -f ca-key.pem ca.srl client.csr extfile.cnf server.csr + ``` + +#### 接口 + +```conf +{ + "tls": true, + "tls-verify": true, + "tls-config": { + "CAFile": "/root/.iSulad/ca.pem", + "CertFile": "/root/.iSulad/server-cert.pem", + "KeyFile":"/root/.iSulad/server-key.pem" + } +} +``` + +#### 限制 + +服务端支持的模式如下: + +- 模式1(验证客户端):tlsverify, tlscacert, tlscert, tlskey。 +- 模式2(不验证客户端):tls, tlscert, tlskey。 + +客户端支持的模式如下: + +- 模式1\(使用客户端证书进行身份验证,并根据给定的CA验证服务器\):tlsverify, tlscacert, tlscert, tlskey。 +- 模式2\(验证服务器\):tlsverify, tlscacert。 + +如果需要采用双向认证方式进行通讯,则服务端采用模式1,客户端采用模式1; + +如果需要采用单向认证方式进行通讯,则服务端采用模式2,客户端采用模式2。 + +> ![](./public_sys-resources/icon-notice.gif) **须知:** +> +> - 采用RPM安装方式时,服务端配置可通过/etc/isulad/daemon.json以及/etc/sysconfig/iSulad配置修改。 +> - 相比非认证或者单向认证方式,双向认证具备更高的安全性,推荐使用双向认证的方式进行通讯。 +> - GRPC开源组件日志不由iSulad进行接管,如果需要查看GRPC相关日志,请按需设置GRPC\_VERBOSITY和GRPC\_TRACE环境变量。 + +#### 示例 + +服务端: + +```bash + isulad -H=tcp://0.0.0.0:2376 --tlsverify --tlscacert ~/.iSulad/ca.pem --tlscert ~/.iSulad/server-cert.pem --tlskey ~/.iSulad/server-key.pem +``` + +客户端: + +```bash + isula version -H=tcp://$HOSTIP:2376 --tlsverify --tlscacert ~/.iSulad/ca.pem --tlscert ~/.iSulad/cert.pem --tlskey ~/.iSulad/key.pem +``` + +### 配置devicemapper存储驱动 + +使用devicemapper存储驱动需要先配置一个thinpool设备,而配置thinpool需要一个独立的块设备,且该设备需要有足够的空闲空间用于创建thinpool,请用户根据实际需求确定。这里假设独立块设备为/dev/xvdf,具体的配置方法如下: + +**一、配置thinpool** + +1. 停止isulad服务。 + + ```bash + # systemctl stop isulad + ``` + +2. 基于块设备创建一个lvm卷。 + + ```bash + # pvcreate /dev/xvdf + ``` + +3. 使用刚才创建的物理卷创建一个卷组。 + + ```bash + # vgcreate isula /dev/xvdf + Volume group "isula" successfully created: + ``` + +4. 创建名为thinpool和thinpoolmeta的两个逻辑卷。 + + ```bash + # lvcreate --wipesignatures y -n thinpool isula -l 95%VG + Logical volume "thinpool" created. + ``` + + ```bash + # lvcreate --wipesignatures y -n thinpoolmeta isula -l 1%VG + Logical volume "thinpoolmeta" created. + ``` + +5. 将新创建的两个逻辑卷转换成thinpool以及thinpool所使用的metadata,这样就完成了thinpool配置。 + + ```bash + # lvconvert -y --zero n -c 512K --thinpool isula/thinpool --poolmetadata isula/thinpoolmeta + + WARNING: Converting logical volume isula/thinpool and isula/thinpoolmeta to + thin pool's data and metadata volumes with metadata wiping. + THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.) + Converted isula/thinpool to thin pool. + ``` + +**二、修改isulad配置文件** + +1. 如果环境之前运行过isulad,请先备份之前的数据。 + + ```bash + # mkdir /var/lib/isulad.bk + # mv /var/lib/isulad/* /var/lib/isulad.bk + ``` + +2. 修改配置文件 + + 这里提供了两种配置方式,用户可根据实际情况的选择合适的方式。 + + - 编辑/etc/isulad/daemon.json,配置storage-driver字段值为devicemapper,并配置storage-opts字段的相关参数,支持参数请参见[参数说明](#zh-cn_topic_0222861454_section1712923715282)。配置参考如下所示: + + ```conf + { + "storage-driver": "devicemapper" + "storage-opts": [ + "dm.thinpooldev=/dev/mapper/isula-thinpool", + "dm.fs=ext4", + "dm.min_free_space=10%" + ] + } + ``` + + - 或者也可以通过编辑/etc/sysconfig/iSulad,在isulad启动参数里显式指定,支持参数请参见[参数说明](#zh-cn_topic_0222861454_section1712923715282)。配置参考如下所示: + + ```conf + OPTIONS="--storage-driver=devicemapper --storage-opt dm.thinpooldev=/dev/mapper/isula-thinpool --storage-opt dm.fs=ext4 --storage-opt dm.min_free_space=10%" + ``` + +3. 启动isulad,使配置生效。 + + ```bash + # systemctl start isulad + ``` + +#### 参数说明 + +storage-opts 支持的参数请参见[表1](#zh-cn_topic_0222861454_table3191161993812)。 + +**表 1** storage-opts字段参数说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

是否必选

+

含义

+

dm.fs

+

+

用于指定容器使用的文件系统类型。当前必须配置为ext4,即dm.fs=ext4

+

dm.basesize

+

+

用于指定单个容器的最大存储空间大小,单位为k/m/g/t/p,也可以使用大写字母,例如dm.basesize=50G。该参数只在首次初始化时有效。

+

dm.mkfsarg

+

+

用于在创建基础设备时指定额外的mkfs参数。例如“dm.mkfsarg=-O ^has_journal”

+

dm.mountopt

+

+

用于在挂载容器时指定额外的mount参数。例如dm.mountopt=nodiscard

+

dm.thinpooldev

+

+

用于指定容器/镜像存储时使用的thinpool设备。

+

dm.min_free_space

+

+

用于指定最小的预留空间,用百分比表示。例如dm.min_free_space=10%,表示当剩余存储空间只剩10%左右时,创建容器等和存储相关操作就会失败。

+
+ +#### 注意事项 + +- 配置devicemapper时,如果系统上没有足够的空间给thinpool做自动扩容,请禁止自动扩容功能。 + + 禁止自动扩容的方法是把/etc/lvm/profile/isula-thinpool.profile中thin\_pool\_autoextend\_threshold和thin\_pool\_autoextend\_percent两个值都改成100,如下所示: + + ```conf + activation { + thin_pool_autoextend_threshold=100 + thin_pool_autoextend_percent=100 + } + ``` + +- 使用devicemapper时,容器文件系统必须配置为ext4,需要在isulad的配置参数中加上--storage-opt dm.fs=ext4。 +- 当graphdriver为devicemapper时,如果metadata文件损坏且不可恢复,需要人工介入恢复。禁止直接操作或篡改daemon存储devicemapper的元数据。 +- 使用devicemapper lvm时,异常掉电导致的devicemapper thinpool损坏,无法保证thinpool损坏后可以修复,也不能保证数据的完整性,需重建thinpool。 + +**iSula开启了user namespace特性,切换devicemapper存储池时的注意事项** + +- 一般启动容器时,deviceset-metadata文件为:/var/lib/isulad/devicemapper/metadata/deviceset-metadata。 +- 使用了user namespace场景下,deviceset-metadata文件使用的是:/var/lib/isulad/\{userNSUID.GID\}/devicemapper/metadata/deviceset-metadata。 +- 使用devicemapper存储驱动,容器在user namespace场景和普通场景之间切换时,需要将对应deviceset-metadata文件中的BaseDeviceUUID内容清空;针对thinpool扩容或者重建的场景下,也同样的需要将对应deviceset-metadata文件中的BaseDeviceUUID内容清空,否则isulad服务会重启失败。 diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/installation-upgrade-Uninstallation.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/installation-upgrade-Uninstallation.md new file mode 100644 index 0000000000000000000000000000000000000000..f6d55640a1c0df735a3d9cdd8e698d47960e1cd0 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/installation-upgrade-Uninstallation.md @@ -0,0 +1,3 @@ +# 安装、升级与卸载 + +本章介绍 iSulad 的安装、安装后配置,以及升级和卸载的方法。 diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/interconnecting-isula-shim-v2-with-stratovirt.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/interconnecting-isula-shim-v2-with-stratovirt.md new file mode 100644 index 0000000000000000000000000000000000000000..571b0d164531ed5eb56951ac2f12d577649dcea5 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/interconnecting-isula-shim-v2-with-stratovirt.md @@ -0,0 +1,218 @@ +# iSula对接shim v2安全容器 + +## 概述 + +shim v2 是新一代 shim 架构方案,相比于 shim v1, 具有调用链更短、架构清晰的优势,在多业务容器场景,具备明显的低内存开销优势。iSula 运行安全容器可以通过 isulad-shim 或者 containerd-shim-kata-v2 来实现,其中 isulad-shim 组件是 shim v1 方案的具体实现,containerd-shim-kata-v2 组件是 shim v2 方案在安全容器场景的一种具体实现,本文介绍 iSula 与 containerd-shim-kata-v2 的对接。 + +## 对接 containerd-shim-kata-v2 + +### **前提条件** + +iSula 对接 containerd-shim-kata-v2 前,需要满足如下前提: + +- 已安装 iSulad和 kata-containers +- StratoVirt 仅支持 devicemapper 存储驱动,因此需要配置 devicemapper 环境并确保 iSulad 使用的 devicemapper 存储驱动正常工作 + +### 环境准备 + +此处给出安装 iSulad 和 kata-containers 并进行相应配置的参考方法。 + +#### 安装依赖软件 + +按照所使用的OS版本自行配置相应的 yum 源,使用 root 权限安装 iSulad和kata-containers : + +```shell +# yum install iSulad +# yum install kata-containers +``` + +#### 制作并配置存储 Storage + +需要用户准备一个磁盘, 如 /dev/sdx , 该磁盘会被格式化,本章使用块设备 /dev/sda 进行演示。 + +一、创建devicemapper + +1. 创建 PV + + ```shell + $ pvcreate /dev/sda + Physical volume "/dev/loop0" successfully created. + ``` + +2. 创建 VG + + ```shell + $ vgcreate isula /dev/sda + Volume group "isula" successfully created + ``` + +3. 创建 thinpool 以及 thinpoolmeta 逻辑卷 + + ```shell + $ lvcreate --wipesignatures y -n thinpool isula -l 95%VG + Logical volume "thinpool" created. + + $ lvcreate --wipesignatures y -n thinpoolmeta isula -l 1%VG + Logical volume "thinpoolmeta" created. + ``` + +4. 将上面创建的逻辑卷转换为 thinpool + + ```shell + $ lvconvert -y --zero n -c 64K \ + --thinpool isula/thinpool \ + --poolmetadata isula/thinpoolmeta + Thin pool volume with chunk size 512.00 KiB can address at most 126.50 TiB of data. + WARNING: Converting isula/thinpool and isula/thinpoolmeta to thin pool's data and metadata volumes with metadata wiping. + THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.) + Converted isula/thinpool and isula/thinpoolmeta to thin pool. + ``` + +5. 设置 lvm thinpool 自动扩展功能 + + ```shell + $ touch /etc/lvm/profile/isula-thinpool.profile + $ cat << EOF > /etc/lvm/profile/isula-thinpool.profile + activation { + thin_pool_autoextend_threshold=80 + thin_pool_autoextend_percent=20 + } + EOF + $ lvchange --metadataprofile isula-thinpool isula/thinpool + Logical volume isula/thinpool changed. + ``` + +二、修改 iSulad 存储驱动类型并设置默认runtime + +更改配置文件 /etc/isulad/daemon.json, 将 default-runtime 设置为 io.containerd.kata.v2 , 将默认存储驱动类型 overlay 配置成 devicemapper,修改后如下所示: + +```json + { + "default-runtime": "io.containerd.kata.v2", + "storage-driver": "devicemapper", + "storage-opts": [ + "dm.thinpooldev=/dev/mapper/isula-thinpool", + "dm.fs=ext4", + "dm.min_free_space=10%" + ], +} +``` + +三、使能配置 + +1. 重启 isulad使得配置生效 : + + ```shell + # systemctl daemon-reload + # systemctl restart isulad + ``` + +2. 确认 iSula 存储驱动是否配置成功: + + ```shell + # isula info + ``` + + 若回显有如下信息,说明配置成功。 + + ```text + Storage Driver: devicemapper + ``` + +### 对接指导 + +本章给出 iSula 对接 containerd-shim-kata-v2 的操作指导。 + +containerd-shim-kata-v2 默认使用 QEMU 虚拟化组件,本章分别介绍使用 QEMU 和 StratoVirt 两种虚拟化组件时的配置方法。 + +#### 使用 QEMU + +containerd-shim-kata-v2 使用的虚拟化组件为 QEMU 时,iSula 对接 containerd-shim-kata-v2 的操作如下: + +1. 修改 kata 配置文件,路径为 /usr/share/defaults/kata-containers/configuration.toml + + sandbox_cgroup_with_emulator 需要设置为 false, 目前 shimv2 不支该改功能, 其他参数与 shim v1 中 kata 配置参数保持一致或者保持缺省值。 + + ```conf + sandbox_cgroup_with_emulator = false + ``` + +2. 使用 busybox 镜像运行安全容器并检查使用的 runtime 为 io.containerd.kata.v2 + + ```bash + $ id=`isula run -tid busybox /bin/sh` + $ isula inspect -f '{{ json .HostConfig.Runtime }}' $id + "io.containerd.kata.v2" + ``` + +3. 确认 qemu 虚拟机进程被拉起,说明 qemu 和 shim v2 安全容器的对接成功 + + ```bash + $ ps -ef | grep qemu + ``` + +#### 使用 StratoVirt + +containerd-shim-kata-v2 使用的虚拟化组件为 StratoVirt 时,iSula 对接 containerd-shim-kata-v2 的操作如下: + +1. 在任一目录(例如 /home 目录)新建脚本文件 stratovirt.sh 并使用 root 权限给文件添加执行权限: + + ```shell + # touch /home/stratovirt.sh + # chmod +x /home/stratovirt.sh + ``` + + stratovirt.sh 内容如下,用于指定 StratoVirt 路径: + + ```shell + #!/bin/bash + export STRATOVIRT_LOG_LEVEL=info # set log level which includes trace, debug, info, warn and error. + /usr/bin/stratovirt $@ + ``` + +2. 修改 kata 配置文件 ,将安全容器的 hypervisor 类型配置为 stratovirt,kernel 配置 StratoVirt 的 kernel 镜像绝对路径,initrd 配置为 kata-containers 的 initrd 镜像文件(使用 yum 安装 kata-containers 时,默认会下载这个文件并存放在 /var/lib/kata/ 目录),StratoVirt 仅支持 devicemapper 存储模式,需提前准备好环境并将 iSulad 设置为 devicemapper 模式。 + + 配置参考如下: + + ```shell + [hypervisor.stratovirt] + path = "/home/stratovirt.sh" + kernel = "/var/lib/kata/vmlinux.bin" + initrd = "/var/lib/kata/kata-containers-initrd.img" + block_device_driver = "virtio-mmio" + use_vsock = true + enable_netmon = true + internetworking_model="tcfilter" + sandbox_cgroup_with_emulator = false + disable_new_netns = false + disable_block_device_use = false + disable_vhost_net = true + ``` + + StratoVirt 中使用 vsock 功能, 需要开启 vhost_vsock 内核模块并确认是否开启成功 + + ```bash + $ modprobe vhost_vsock + $ lsmod |grep vhost_vsock + ``` + + 下载对应版本和架构的 kernel 并放到 /var/lib/kata/ 路径下, 如下载 openEuler 21.03 版本 x86 架构的内核 [openeuler repo](https://repo.openeuler.org): + + ```bash + $ cd /var/lib/kata + $ wget https://archives.openeuler.openatom.cn/openEuler-21.03/stratovirt_img/x86_64/vmlinux.bin + ``` + +3. 使用 busybox 镜像运行安全容器并检查使用的 runtime 为 io.containerd.kata.v2 + + ```bash + $ id=`isula run -tid busybox sh` + $ isula inspect -f '{{ json .HostConfig.Runtime }}' $id + "io.containerd.kata.v2" + ``` + +4. 确认 stratovirt 虚拟机进程被拉起,说明 StratoVirt 和 shim v2 安全容器的对接成功 + + ```bash + $ ps -ef | grep stratovirt + ``` diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/interconnection-with-the-cni-network.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/interconnection-with-the-cni-network.md new file mode 100644 index 0000000000000000000000000000000000000000..7f634748f66e918fe162bc5582b5ca02565ae2fb --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/interconnection-with-the-cni-network.md @@ -0,0 +1,121 @@ +# 支持CNI网络 + +## 描述 + +实现CRI接口对接CNI网络的能力,包括CNI网络配置文件的解析、CNI网络的加入和退出。Pod需要支持网络时,例如通过canal等容器网络插件提供网络能力,那么需要CRI接口能够和canal实现对接,并且调用canal的接口,为Pod提供网络能力。 + +CNI配置文件相关行为描述: + +- 对--cni-conf-dir目录下的合法配置文件名进行字典排序,取第一个合法配置作为default网络平面的配置; +- 每隔5s对配置目录进行扫描,重新加载更新CNI配置; +- CRI Status接口不更新CNI的网络配置; + +## 接口 + +CNI对用户可见的接口,主要涉及CNI网络配置和Pod配置中CNI网络相关的项。 + +- CNI网络配置相关的接口,主要是isulad指定CNI网络配置文件所在路径、CNI网络插件二进制文件所在的路径以及使用的网络模式。详情请参见[表1 CNI网络配置接口](#zh-cn_topic_0183259146_table18221919589)。 +- Pod配置中CNI网络相关的项,主要是设置Pod加入的附加CNI网络列表,默认情况Pod只会加入到default CNI网络平面中,可以通过该配置把Pod加入到多个CNI网络平面中。 + +**表 1** CNI网络配置接口 + + + + + + + + + + + + + + + + + + + + + + + + +

  

+

命令行

+

配置文件

+

说明

+

设置CNI网络插件二进制文件所在路径

+

--cni-bin-dir

+

"cni-bin-dir": "",

+

缺省值为/opt/cni/bin

+

设置CNI网络配置文件所在路径

+

--cni-conf-dir

+

"cni-conf-dir": "",

+

系统会遍历目录下面所有后缀名为".conf"、".conflist"和 ".json"的文件。缺省值为/etc/cni/net.d

+

指定网络模式

+

--network-plugin

+

"network-plugin": "",

+

指定网络插件,默认为空字符,表示无网络配置,创建的sandbox只有loop网卡。支持cni和空字符,其他非法值会导致isulad启动失败。

+
+ +附加CNI网络配置方式: + +在Pod的配置文件的"annotations"中,增加一项"network.alpha.kubernetes.io/network": "网络平面配置"; + +网络平面配置为json格式,包含两项: + +- name:指定CNI网络平面的名字 +- interface:指定网络接口的名字 + +附加CNI网络配置方式示例如下: + +```conf +"annotations" : { + "network.alpha.kubernetes.io/network": "{\"name\": \"mynet\", \"interface\": \"eth1\"}" + } +``` + +### CNI网络配置说明 + +CNI网络配置包含两种类型,文件格式都为json: + +- 单网络平面配置,以.conf和.json为后缀的文件:具体的配置项请参见"附录 > CNI配置参数" 章节的 "表1 CNI单网络配置参数"。 +- 多网络平面配置,以.conflist为后缀的文件:具体的配置项请参见"附录 > CNI配置参数" 章节的 "表3 CNI多网络配置参数"。 + +### 加入CNI网络列表 + +如果iSulad配置了--network-plugin=cni,而且设置了default网络平面配置,那么在启动Pod的时候,会自动把Pod加入到default网络平面。如果在Pod的配置中配置了附加网络配置,那么启动Pod的时候也会把Pod加入到这些附加网络平面中。 + +Pod配置中和网络相关的还有port\_mappings项,用于设置Pod的端口映射关系。配置方式如下: + +```conf +"port_mappings":[ + { + "protocol": 1, + "container_port": 80, + "host_port": 8080 + } +] +``` + +- protocol:表示映射使用的协议,支持tcp(用0标识)、udp(用1标识); +- container\_port:表示容器映射出去的port; +- host\_port:表示映射到主机的port。 + +### 退出CNI网络列表 + +StopPodSandbox的时候,会调用退出CNI网络的接口,清理网络相关的资源。 + +>![](./public_sys-resources/icon-note.gif) **说明:** +> +> - 在调用RemovePodSandbox接口之前,至少要调用一次StopPodSandbox接口。 +> - StopPodSandbox调用CNI接口失败,导致的网络资源残留,由CNI网络插件负责清理。 + +## 使用限制 + +- cniVersion的版本,当前只支持0.3.0和0.3.1。由于后期可能需要支持0.1.0和0.2.0,错误日志打印时,保留了0.1.0和0.2.0的提示信息。 +- name:必须是小写字符、数字、'-'以及'.'组成; '.'和'-'不能作为首字符和尾字符; 而且长度不超过200个字符。 +- 配置文件个数不超过200个,单个配置文件大小不超过1MB。 +- 扩展之后的参数,需要根据实际网络需求来配置,不需要使用的可选参数可以不写入到netconf.json文件中。 diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/isula-faqs.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/isula-faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..b41f205b7a5dc5bb145da44a387ec15742a39480 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/isula-faqs.md @@ -0,0 +1,22 @@ +# 常见问题与解决方法 + +## **问题1:修改`iSulad`默认运行时为`lxc`,启动容器报错:Failed to initialize engine or runtime** + +原因:`iSulad`默认运行时为`runc`,设置默认运行时为`lxc`时缺少依赖。 + +解决方法:若需修改`iSulad`默认运行时为`lxc`,需要安装`lcr`、`lxc`软件包依赖,且配置`iSulad`配置文件中`runtime`为`lcr` +或者启动容器时指定`--runtime lcr`。启动容器后不应该随意卸载`lcr`、`lxc`软件包,否则可能会导致删除容器时的资源残留。 + +## **问题2:使用`iSulad` `CRI V1`接口,报错:rpc error: code = Unimplemented desc =** + +原因:`iSulad`同时支持`CRI V1alpha2`和`CRI V1`接口,默认使用`CRI V1alpha2`,若使用`CRI V1`,需要开启相应的配置。 + +解决方法:在`iSulad`配置文件`/etc/isulad/daemon.json`中开启`CRI V1`的配置。 + +```json +{ + "enable-cri-v1": true, +} +``` + +若使用源码编译`iSulad`,还需在编译时增加`cmake`编译选项`-D ENABLE_CRI_API_V1=ON`。 diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/isulad-support-cdi.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/isulad-support-cdi.md new file mode 100644 index 0000000000000000000000000000000000000000..08c299a85c497dae2295a889de22f07f551b9d60 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/isulad-support-cdi.md @@ -0,0 +1,120 @@ +# iSulad支持CDI + +## 概述 + +CDI(Container Device Interface,容器设备接口)是容器运行时的一种规范,用于支持第三方设备。 + +CDI解决了如下问题: +在Linux上,为了使容器具有设备感知能力,过去只需在该容器中暴露一个设备节点。但是,随着设备和软件变得越来越复杂,供应商希望执行更多的操作,例如: + +- 向容器公开设备可能需要公开多个设备节点、从运行时命名空间挂载文件或隐藏procfs条目。 +- 执行容器和设备之间的兼容性检查(例如:检查容器是否可以在指定设备上运行)。 +- 执行特定于运行时的操作(例如:虚拟机与基于Linux容器的运行时)。 +- 执行特定于设备的操作(例如:清理GPU的内存或重新配置FPGA)。 + +在缺乏第三方设备标准的情况下,供应商通常不得不为不同的运行时编写和维护多个插件,甚至直接在运行时中贡献特定于供应商的代码。此外,运行时不统一地暴露插件系统(甚至根本不暴露插件系统),导致在更高级别的抽象(例如Kubernetes设备插件)中重复功能。 + +CDI解决上述问题的方法: +CDI描述了一种允许第三方供应商与设备交互的机制,从而不需要更改容器运行时。 + +使用的机制是一个JSON文件(类似于容器网络接口(CNI)),它允许供应商描述容器运行时应该对容器的OCI规范执行的操作。 + +iSulad目前已支持[CDI v0.6.0](https://github.com/cncf-tags/container-device-interface/blob/v0.6.0/SPEC.md)规范。 + +## 配置iSulad支持CDI + +需要对daemon.json做如下配置,然后重启iSulad: + +```json +{ + ... + "enable-cri-v1": true, + "cdi-spec-dirs": ["/etc/cdi", "/var/run/cdi"], + "enable-cdi": true +} +``` + +其中"cdi-spec-dirs"用于指定CDI specs所在目录,如果不指定则默认为"/etc/cdi", "/var/run/cdi"。 + +## 使用示例 + +### CDI specification实例 + +具体每个字段含义详见[CDI v0.6.0](https://github.com/cncf-tags/container-device-interface/blob/v0.6.0/SPEC.md) + +```bash +$ mkdir /etc/cdi +$ cat > /etc/cdi/vendor.json < + +![](./figures/zh-cn_image_0183048952.png) diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/privileged-container.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/privileged-container.md new file mode 100644 index 0000000000000000000000000000000000000000..2c92da456dcde37f3282857129809db175067815 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/privileged-container.md @@ -0,0 +1,232 @@ +# 特权容器 + +## 场景说明 + +iSulad默认启动的是普通容器,普通容器适合启动普通进程,其权限非常受限,仅具备/etc/default/isulad/config.json中capabilities所定义的默认权限。当需要特权操作时(比如操作/sys下的设备),需要特权容器完成这些操作,使用该特性,容器内的root将拥有宿主机的root权限, 否则,容器内的root在只是宿主机的普通用户权限。 + +## 使用限制 + +特权容器为容器提供了所有功能,还解除了设备cgroup控制器强制执行的所有限制,具备以下特性: + +- Secomp不block任何系统调用 +- /sys、/proc路径可写 +- 容器内能访问主机上所有设备 + +- 系统的权能将全部打开 + +普通容器默认权能为: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Capability Key

+

Capability Description

+

SETPCAP

+

修改进程权能

+

MKNOD

+

允许使用mknod()系统调用创建特殊文件

+

AUDIT_WRITE

+

向内核审计日志写记录

+

CHOWN

+

对文件的 UIDs 和 GIDs 做任意的修改(参考 chown(2))

+

NET_RAW

+

使用 RAW 和 PACKET sockets;为透明代理绑定任何地址

+

DAC_OVERRIDE

+

忽略文件的DAC访问限制

+

FOWNER

+

忽略文件属主ID必须和进程用户ID相匹配的限制

+

FSETID

+

允许设置文件的setuid位

+

KILL

+

允许对不属于自己的进程发送信号

+

SETGID

+

允许改变进程的组ID

+

SETUID

+

允许改变进程的用户ID

+

NET_BIND_SERVICE

+

允许绑定到小于1024的端口

+

SYS_CHROOT

+

允许使用chroot()系统调用

+

SETFCAP

+

允许向其他进程转移能力以及删除其他进程的能力

+
+ +当容器为特权模式时,将添加以下权能 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Capability Key

+

Capability Description

+

SYS_MODULE

+

加载和卸载内核模块

+

SYS_RAWIO

+

允许直接访问/devport,/dev/mem,/dev/kmem及原始块设备

+

SYS_PACCT

+

允许执行进程的BSD式审计

+

SYS_ADMIN

+

允许执行系统管理任务,如加载或卸载文件系统、设置磁盘配额等

+

SYS_NICE

+

允许提升优先级及设置其他进程的优先级

+

SYS_RESOURCE

+

忽略资源限制

+

SYS_TIME

+

允许改变系统时钟

+

SYS_TTY_CONFIG

+

允许配置TTY设备

+

AUDIT_CONTROL

+

启用和禁用内核审计;修改审计过滤器规则;提取审计状态和过滤规则

+

MAC_ADMIN

+

覆盖强制访问控制 (Mandatory Access Control (MAC)),为Smack Linux安全模块(Linux Security Module (LSM)) 而实现

+

MAC_OVERRIDE

+

允许 MAC 配置或状态改变。为 Smack LSM 而实现

+

NET_ADMIN

+

允许执行网络管理任务

+

SYSLOG

+

执行特权 syslog(2) 操作

+

DAC_READ_SEARCH

+

忽略文件读及目录搜索的DAC访问限制

+

LINUX_IMMUTABLE

+

允许修改文件的IMMUTABLE和APPEND属性标志

+

NET_BROADCAST

+

允许网络广播和多播访问

+

IPC_LOCK

+

允许锁定共享内存片段

+

IPC_OWNER

+

忽略IPC所有权检查

+

SYS_PTRACE

+

允许跟踪任何进程

+

SYS_BOOT

+

允许重新启动系统

+

LEASE

+

允许修改文件锁的FL_LEASE标志

+

WAKE_ALARM

+

触发将唤醒系统的功能,如设置 CLOCK_REALTIME_ALARM 和 CLOCK_BOOTTIME_ALARM 定时器

+

BLOCK_SUSPEND

+

可以阻塞系统挂起的特性

+
+ +## 使用指导 + +iSulad使用--privileged给容器添加特权模式,在非必要情况下,不要给容器添加特权,遵循最小特权原则,减少存在的安全风险。 + +```bash +isula run --rm -it --privileged busybox +``` diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-caution.gif b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-caution.gif differ diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-danger.gif b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-danger.gif differ diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-note.gif b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-notice.gif b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-notice.gif differ diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-tip.gif b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-tip.gif differ diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-warning.gif b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/public_sys-resources/icon-warning.gif differ diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/querying-information.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/querying-information.md new file mode 100644 index 0000000000000000000000000000000000000000..e6f485be203565724baadd5e59b77c4541bc8bd0 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/querying-information.md @@ -0,0 +1,95 @@ +# 查询信息 + +- [查询信息](#查询信息) + - [查询服务版本信息](#查询服务版本信息) + - [查询系统级信息](#查询系统级信息) + +## 查询信息 + +## 查询服务版本信息 + +### 描述 + +isula version 命令用于查询iSulad服务的版本信息。 + +### 用法 + +```bash +isula version +``` + +### 实例 + +查询版本信息 + +```bash +isula version +``` + +如果isulad服务正常运行,则可以查看到客户端、服务端以及OCI config的版本等信息。 + +```text +Client: + Version: 1.0.31 + Git commit: fa7f9902738e8b3d7f2eb22768b9a1372ddd1199 + Built: 2019-07-30T04:21:48.521198248-04:00 + +Server: + Version: 1.0.31 + Git commit: fa7f9902738e8b3d7f2eb22768b9a1372ddd1199 + Built: 2019-07-30T04:21:48.521198248-04:00 + +OCI config: + Version: 1.0.0-rc5-dev + Default file: /etc/default/isulad/config.json +``` + +若isulad服务未运行,则仅仅查询到客户端的信息,并提示无法连接到服务端。 + +```text +Client: + Version: 1.0.31 + Git commit: fa7f9902738e8b3d7f2eb22768b9a1372ddd1199 + Built: 2019-07-30T04:21:48.521198248-04:00 + +Can not connect with server.Is the iSulad daemon running on the host? +``` + +因此,isula version命令也常常用来检验isulad是否正常运行。 + +## 查询系统级信息 + +### 描述 + +isula info命令用于对系统级信息,以及容器和镜像数目等信息的查询。 + +### 用法 + +```bash +isula info +``` + +### 示例 + +查询系统级信息,可以展示容器数目,镜像数目,内核版本、操作系统等信息 + +```bash +# isula info +Containers: 2 + Running: 0 + Paused: 0 + Stopped: 2 +Images: 8 +Server Version: 1.0.31 +Logging Driver: json-file +Cgroup Driverr: cgroupfs +Hugetlb Pagesize: 2MB +Kernel Version: 4.19 +Operating System: Fedora 29 (Twenty Nine) +OSType: Linux +Architecture: x86_64 +CPUs: 8 +Total Memory: 7 GB +Name: localhost.localdomain +iSulad Root Dir: /var/lib/isulad +``` diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/security-features.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/security-features.md new file mode 100644 index 0000000000000000000000000000000000000000..8a436e5fe85668805bf88a626a9c86a6de846959 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/security-features.md @@ -0,0 +1,248 @@ +# 安全特性 + +- [安全特性](#安全特性.md) + - [seccomp安全配置场景](#seccomp安全配置场景) + - [capabilities安全配置场景](#capabilities安全配置场景) + - [SELinux安全配置场景](#selinux安全配置场景) + +## seccomp安全配置场景 + +### 场景说明 + +seccomp(**secure computing** **mode**)是linux kernel从2.6.23版本开始引入的一种简洁的sandboxing机制。在一些特定场景下,用户需要在容器中执行一些“特权”操作,但又不想启动特权容器,用户经常会在run时添加--cap-add来获得一些“小范围”的权限。对于安全要求比较严格的容器实例,上述的CAP粒度不一定能够满足安全需要,可使用一些办法精细化控制权限范围。 + +- 举例 + + 普通容器场景中,用户使用-v将宿主机某目录(包含某普通用户无法执行的二进制),映射到容器中。 + + 在容器中,可以将二进制修改权限chmod 4777加入S标志位。这样在宿主机上,原先不能运行二进制的普通用户(或者运行此二进制受限),可以在S标志位的添加动作后,在运行此二进制的时候,获取到二进制自身的权限(比如root),从而提权运行或者访问其他文件。 + + 这个场景,如果在严格安全要求下,需要使用seccomp裁剪chmod、fchmod、fchmodat系统调用。 + +### 使用限制 + +- 不要禁用iSulad的seccomp特性 + + 默认的iSulad有一个seccomp的配置,配置中使用的是白名单,不在配置的sys_call会被seccomp禁掉,使用接口--security-opt 'seccomp:unconfined'可以禁止使用seccomp特性。如果禁用seccomp或使用自定义seccomp配置但过滤名单不全,都会增加容器对内核的攻击面。 + +- 默认的Seccomp配置是白名单,不在白名单的syscall默认会返回SCMP_ACT_ERRNO,同时会根据不同的Cap开放不同的系统调用,不在白名单上面的权限,iSulad默认不会将权限给到容器。 + +### 使用指导 + +通过--security-opt将配置文件传给要过滤系统调用的容器。 + +```bash +isula run -itd --security-opt seccomp=/path/to/seccomp/profile.json rnd-dockerhub.huawei.com/official/busybox +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> - 创建容器时通过--security-opt将配置文件传给容器时,采用默认配置文件(/etc/isulad/seccomp\_default.json)。 +> - 创建容器时--security-opt设置为unconfined时,对容器不过滤系统调用。 +> - “/path/to/seccomp/profile.json”需要是绝对路径。 +> - --security-opt采用“=”号进行分割,不支持使用“:”号分割。 + +#### 获取普通容器的默认seccomp配置 + +- 启动一个普通容器(或者是带--cap-add的容器),并查看默认权限配置: + + ```bash + cat /etc/isulad/seccomp_default.json | python -m json.tool > profile.json + ``` + + 可以看到"seccomp"字段中,有很多的"syscalls",在此基础上,仅提取syscalls的部分,参考定制seccomp配置文件,进行定制化操作。 + + ```conf + "defaultAction": "SCMP_ACT_ERRNO", + "syscalls": [ + { + "action": "SCMP_ACT_ALLOW", + "name": "accept" + }, + { + "action": "SCMP_ACT_ALLOW", + "name": "accept4" + }, + { + "action": "SCMP_ACT_ALLOW", + "name": "access" + }, + { + "action": "SCMP_ACT_ALLOW", + "name": "alarm" + }, + { + "action": "SCMP_ACT_ALLOW", + "name": "bind" + }, + ]... + ``` + +- 查看转换为lxc可识别的seccomp配置 + + ```bash + cat /var/lib/isulad/engines/lcr/74353e38021c29314188e29ba8c1830a4677ffe5c4decda77a1e0853ec8197cd/seccomp + ``` + + ```text + ... + waitpid allow + write allow + writev allow + ptrace allow + personality allow [0,0,SCMP_CMP_EQ,0] + personality allow [0,8,SCMP_CMP_EQ,0] + personality allow [0,131072,SCMP_CMP_EQ,0] + personality allow [0,131080,SCMP_CMP_EQ,0] + personality allow [0,4294967295,SCMP_CMP_EQ,0] + ... + ``` + +#### 定制seccomp配置文件 + +在启动容器的时候使用--security-opt引入seccomp配置文件,容器实例会按照配置文件规则进行限制系统API的运行。首先获取普通容器的默认seccomp,得到完整模板,然后按照本节定制配置文件,启动容器: + +```bash +isula run --rm -it --security-opt seccomp:/path/to/seccomp/profile.json rnd-dockerhub.huawei.com/official/busybox +``` + +配置文件模板: + +```conf +{ +"defaultAction": "SCMP_ACT_ALLOW", +"syscalls": [ +{ +"name": "syscall-name", +"action": "SCMP_ACT_ERRNO", +"args": null +} +] +} +``` + +> ![](./public_sys-resources/icon-notice.gif) **须知:** +> +> - defaultAction、syscalls:对应的action的类型是一样的,但其值是不能一样的,目的就是让所有的syscall都有一个默认的action,并且如果syscalls数组中有明确的定义,就以syscalls中的为准,由于defaultAction、action的值不一样,就能保证action不会有冲突。当前支持的action有: +> - "SCMP\_ACT\_ERRNO":禁止,并打印错误信息。 +> - "SCMP\_ACT\_ALLOW":允许。 +> - syscalls: 数组,可以只有一个syscall,也可以有多个,可以带args,也可以不带。 +> - name:要过滤的syscall。 +> - args:数组,里面的每个object的定义如下: +> +> ```conf +> type Arg struct { +> Index uint `json:"index"` //参数的序号,如open(fd, buf, len),fd 对应的就是0,buf为1 +> Value uint64 `json:"value"` //跟参数进行比较的值 +> ValueTwo uint64 `json:"value_two"` //仅当Op=MaskEqualTo时起作用,用户传入值跟Value按位与操作后,跟ValueTwo进行比较,若相等则执行action。 +> Op Operator `json:"op"` +> } +> ``` +> +> args中的Op,其取值可以下页面的任意一种: +> "SCMP\_CMP\_NE": NotEqualTo +> "SCMP\_CMP\_LT": LessThan +> "SCMP\_CMP\_LE": LessThanOrEqualTo +> "SCMP\_CMP\_EQ": EqualTo +> "SCMP\_CMP\_GE": GreaterThanOrEqualTo +> "SCMP\_CMP\_GT": GreaterThan +> "SCMP\_CMP\_MASKED\_EQ": MaskEqualTo + +## capabilities安全配置场景 + +### 场景说明 + +capabilities机制是linux kernel 2.2之后引入的安全特性,用更小的粒度控制超级管理员权限,可以避免使用 root 权限,将root用户的权限细分为不同的领域,可以分别启用或禁用。capabilities详细信息可通过Linux Programmer's Manual进行查看([capabilities\(7\) - Linux man page](http://man7.org/linux/man-pages/man7/capabilities.7.html)): + +```bash +man capabilities +``` + +### 使用限制 + +- isulad默认Capabilities(白名单)配置如下,普通容器进程将默认携带: + + ```conf + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID", + "CAP_FOWNER", + "CAP_MKNOD", + "CAP_NET_RAW", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETFCAP", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_KILL", + "CAP_AUDIT_WRITE" + ``` + +- 默认的权能配置,包含了CAP\_SETUID和CAP\_FSETID,如host和容器共享目录,容器可对共享目录的二进制文件进行文件权限设置,host上的普通用户可能使用该特性进行提权攻击。CAP\_AUDIT\_WRITE,容器可以对host写入,存在一定的风险,如果使用场景不需要,推荐在启动容器的时候使用--cap-drop将其删除。 +- 增加Capabilities意味着容器进程具备更大的能力,同时也会开放更多的系统调用接口。 + +### 使用指导 + +iSulad使用--cap-add/--cap-drop给容器增加/删去特定的权限,在非必要情况下,不要给容器增加额外的权限,推荐将容器默认但非必要的权限也去掉。 + +```bash +isula run --rm -it --cap-add all --cap-drop SYS_ADMIN rnd-dockerhub.huawei.com/official/busybox +``` + +## SELinux安全配置场景 + +### 场景说明 + +SELinux\(Security-Enhanced Linux\)是一个Linux内核的安全模块,提供了访问控制安全策略机制,iSulad将采用MCS(多级分类安全)实现对容器内进程打上标签限制容器访问资源的方式,减少提权攻击的风险,防止造成更为重要的危害。 + +### 使用限制 + +- 确保宿主机已使能SELinux,且daemon端已打开SELinux使能开发(/etc/isulad/daemon.json中“selinux-enabled”字段为true, 或者命令行参数添加--selinux-enabled) +- 确保宿主机上已配置合适的selinux策略,推荐使用container-selinux进行配置 +- 引入SELinux会影响性能,设置SELinux之前需要对场景进行评估,确定必要时打开daemon端SELinux开关并设置容器SELinux配置 +- 对挂载卷进行标签配置时,源目录不允许为/、/usr、/etc、/tmp、/home、/run、/var、/root以及/usr的子目录。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> - 目前iSulad不支持对容器的文件系统打标签,确保容器文件系统及配置目录打上容器可访问标签,需使用chcon命令对其打上标签。 +> - 若iSulad启用SELinux访问控制,建议daemon启动前对/var/lib/isulad目录打上标签,容器容器创建时目录下生产的文件及文件夹将默认继承其标签,例如: +> +> ```bash +> chcon -R system_u:object_r:container_file_t:s0 /var/lib/isulad +> ``` + +### 使用指导 + +- daemon端使能selinux: + + ```bash + isulad --selinux-enabled + ``` + +- 启动容器时配置selinux标签安全上下文 + + --security-opt="label=user:USER" 配置安全上下文用户 + + --security-opt="label=role:ROLE" 配置安全上下文角色 + + --security-opt="label=type:TYPE" 配置安全上下文类型 + + --security-opt="label=level:LEVEL" 配置安全上下文域 + + --security-opt="label=disable" 容器禁用SELinux配置 + + ```bash + $ isula run -itd --security-opt label=type:container_t --security-opt label=level:s0:c1,c2 rnd-dockerhub.huawei.com/official/centos + 9be82878a67e36c826b67f5c7261c881ff926a352f92998b654bc8e1c6eec370 + ``` + +- 为挂载卷打selinux标签\('z'为共享模式\) + + ```bash + $ isula run -itd -v /test:/test:z rnd-dockerhub.huawei.com/official/centos + 9be82878a67e36c826b67f5c7261c881ff926a352f92998b654bc8e1c6eec370 + + $ls -Z /test + system_u:object_r:container_file_t:s0 file + ``` diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/supporting-oci-hooks.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/supporting-oci-hooks.md new file mode 100644 index 0000000000000000000000000000000000000000..00373d38356374fe90a49d674afddf75ca4edd3a --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/supporting-oci-hooks.md @@ -0,0 +1,77 @@ +# 支持OCI hooks + +## 描述 + +支持在容器的生命周期中,运行OCI标准hooks。包括三种类型的hooks: + +- prestart hook:在执行isula start命令之后,而在容器的1号进程启动之前,被执行。 +- poststart hook:在容器1号进程启动之后,而在isula start命令返回之前,被执行。 +- poststop hook:在容器被停止之后,但是在停止命令返回之前,被执行。 + +OCI hooks的配置格式规范如下: + +- path:格式是字符串,必须项,必须为绝对路径,指定的文件必须有可执行权限。 +- args:格式是字符串数组,可选项,语义和execv的args一致。 +- env:格式是字符串数组,可选项,语义和环境变量一致,内容为键值对,如:"PATH=/usr/bin"。 +- timeout:格式是整数,可选项,必须大于0,表示钩子执行的超时时间。如果钩子进程运行时间超过配置的时间,那么钩子进程会被杀死。 + +hook的配置为json格式,一般存放在json结尾的文件中,示例如下: + +```json +{ + "prestart": [ + { + "path": "/usr/bin/echo", + "args": ["arg1", "arg2"], + "env": [ "key1=value1"], + "timeout": 30 + }, + { + "path": "/usr/bin/ls", + "args": ["/tmp"] + } + ], + "poststart": [ + { + "path": "/usr/bin/ls", + "args": ["/tmp"], + "timeout": 5 + } + ], + "poststop": [ + { + "path": "/tmp/cleanup.sh", + "args": ["cleanup.sh", "-f"] + } + ] +} +``` + +## 接口 + +isulad和isula都提供了hook的接口,isulad提供了默认的hook配置,会作用于所有容器;而isula提供的hook接口,只会作用于当前创建的容器。 + +isulad提供的默认OCI hooks配置: + +- 通过/etc/isulad/daemon.json配置文件的hook-spec配置项设置hook配置的文件路径:"hook-spec": "/etc/default/isulad/hooks/default.json"。 +- 通过isulad --hook-spec参数设置hook配置的文件路径。 + +isula提供的OCI hooks配置: + +- isula create --hook-spec:指定hook配置的json文件的路径。 +- isula run --hook-spec:指定hook配置的json文件的路径。 + +run的配置其实也是在create阶段生效了。 + +## 使用限制 + +- hook-spec指定的路径必须是绝对路径。 +- hook-spec指定的文件必须存在。 +- hook-spec指定的路径对应的必须是普通文本文件,格式为json。 +- hook-spec指定的文件大小不能超过10MB。 +- hooks配置的path字段必须为绝对路径。 +- hooks配置的path字段指定文件必须存在。 +- hooks配置的path字段指定文件必须有可执行权限。 +- hooks配置的path字段指定文件的owner必须是root。 +- hooks配置的path字段指定文件必须只有root有写权限。 +- hooks配置的timeout必须大于0。 diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/uninstallation.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/uninstallation.md new file mode 100644 index 0000000000000000000000000000000000000000..c7e5d64daa66f0149f9746963890a41241f3a075 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/uninstallation.md @@ -0,0 +1,22 @@ +# 卸载 + +卸载iSulad的操作步骤如下: + +1. 卸载iSulad及其依赖软件包 + - 若使用yum方式安装,卸载的参考命令如下: + + ```bash + # yum remove iSulad + ``` + + - 若使用rpm方式安装,需卸载iSulad及其依赖包,卸载单个RPM包的参考命令如下: + + ```bash + # rpm -e iSulad-xx.xx.xx-YYYYmmdd.HHMMSS.gitxxxxxxxx.aarch64.rpm + ``` + +2. 镜像、容器、volumes以及相关配置文件不会自动删除,需要手动删除。参考命令如下: + + ```bash + # rm -rf /var/lib/iSulad + ``` diff --git a/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/upgrade-methods.md b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/upgrade-methods.md new file mode 100644 index 0000000000000000000000000000000000000000..d0f24f80ae9655ad1121f0fc5f71a1c9269953bb --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerEngine/iSulaContainerEngine/upgrade-methods.md @@ -0,0 +1,24 @@ +# 升级 + +- 若为相同大版本之间的升级,例如从2.x.x版本升级到2.x.x版本,请执行如下命令: + + ```bash + # sudo yum update -y iSulad + ``` + +- 若为不同大版本之间的升级,例如从1.x.x版本升级到2.x.x版本,请先保存当前的配置文件/etc/isulad/daemon.json,并卸载已安装的iSulad软件包,然后安装待升级的iSulad软件包,随后恢复配置文件。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> - 可通过**sudo rpm -qa |grep iSulad** 或 **isula version** 命令确认当前iSulad的版本号。 +> - 相同大版本之间,如果希望手动升级,请下载iSulad及其所有依赖库的RPM包进行升级,参考命令如下: +> +> ```bash +> # sudo rpm -Uhv iSulad-xx.xx.xx-YYYYmmdd.HHMMSS.gitxxxxxxxx.aarch64.rpm +> ``` +> +> 若升级失败,可通过--force选项进行强制升级,参考命令如下: +> +> ```bash +> # sudo rpm -Uhv --force iSulad-xx.xx.xx-YYYYmmdd.HHMMSS.gitxxxxxxxx.aarch64.rpm +> ``` diff --git a/docs/en/25.03/Cloud/ContainerForm/SecureContainer/_menu.md b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..44c1a7d062ddf01722070d128ef316905df9ee80 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/_menu.md @@ -0,0 +1,21 @@ +--- +label: '安全容器' +ismanual: 'Y' +description: '安全容器结合了虚拟化技术和容器技术,具有更好的隔离性' +children: + - label: '概述' + href: './overview.md' + - label: '安装与配置' + href: './installation-and-deployment-2.md' + - label: '使用方法' + href: './application-scenarios-2.md' + children: + - label: '管理安全容器的生命周期' + href: './managing-the-lifecycle-of-a-secure-container.md' + - label: '为安全容器配置资源' + href: './configuring-resources-for-a-secure-container.md' + - label: '监控安全容器' + href: './monitoring-secure-containers.md' + - label: '附录' + href: './appendix-2.md' +--- \ No newline at end of file diff --git a/docs/en/25.03/Cloud/ContainerForm/SecureContainer/appendix-2.md b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/appendix-2.md new file mode 100644 index 0000000000000000000000000000000000000000..9fea9ff3482d0626aaea39a60ceec25602cfae62 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/appendix-2.md @@ -0,0 +1,488 @@ +# 附录 + +- [附录](#附录) + - [configuration.toml配置说明](#configuration-toml配置说明) + - [接口列表](#接口列表) + +## configuration-toml配置说明 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> configuration.toml配置文件中各个字段的取值以kata-containers-.rpm包中的configuration.toml文件为准,不支持用户对配置文件中的字段任意取值。 + +```conf +[hypervisor.qemu] +path :指定虚拟化qemu执行路径 +kernel :指定guest kernel执行路径 +initrd :指定guest initrd执行路径 +image :指定guest image执行路径(不适用) +machine_type :指定模拟芯片类型,ARM架构为virt,x86架构为pc +kernel_params :指定guest内核运行参数 +firmware :指定固件路径,设空则使用默认固件 +machine_accelerators :指定加速器 +default_vcpus :指定每个SB/VM的默认vCPU数量 +default_maxvcpus :指定每个SB/VM的默认最大vCPU数量 +default_root_ports :指定每个SB/VM的默认Root Ports数量 +default_bridges :指定每个SB/VM的默认bridges数量 +default_memory :指定每个SB/VM的默认内存大小,默认为1024 MiB +memory_slots :指定每个SB/VM的内存插槽数量,默认为10 +memory_offset :指定内存偏移量,默认为0 +disable_block_device_use :禁止将块设备用于容器的rootfs +shared_fs :指定共享文件系统类型,默认为virtio-9p +virtio_fs_daemon :指定vhost-user-fs守护进程路径 +virtio_fs_cache_size :指定DAX缓存的默认大小 +virtio_fs_cache :指定缓存模式 +block_device_driver :指定块设备驱动 +block_device_cache_set :指定块设备是否设置缓存相关选项,默认false +block_device_cache_direct :指定是否使能O_DIRECT,默认false +block_device_cache_noflush :指定是否忽略设备刷新请求,默认false +enable_iothreads :使能iothreads +enable_mem_prealloc :使能VM RAM预分配,默认false +enable_hugepages :使能大页,默认false +enable_swap :使能swap,默认false +enable_debug :使能qemu debug,默认false +disable_nesting_checks :关闭嵌套检查 +msize_9p = 8192 :指定每个9p包传输的字节数 +use_vsock :使用vsocks与agent直接通信(前提支持vsocks),默认false +hotplug_vfio_on_root_bus :使能vfio设备在root bus热插拔,默认false +disable_vhost_net :关闭vhost_net,默认false +entropy_source :指定默认熵源 +guest_hook_path :指定guest hook二进制路径 + +[factory] +enable_template :使能VM模板,默认false +template_path :指定模板路径 +vm_cache_number :指定VMCache的缓存数量,默认0 +vm_cache_endpoint :指定VMCache使用的Unix socket的地址,默认/var/run/kata-containers/cache.sock + +[proxy.kata] +path :指定kata-proxy运行路径 +enable_debug :使能proxy debug,默认false + +[shim.kata] +path :指定kata-shim运行路径 +enable_debug :使能shim debug,默认false +enable_tracing :使能shim opentracing + +[agent.kata] +enable_debug :使能agent debug,默认false +enable_tracing :使能agent tracing +trace_mode :指定trace模式 +trace_type :指定trace类型 +enable_blk_mount :开启block设备guest挂载 + +[netmon] +enable_netmon :使能网络监控,默认false +path :指定kata-netmon运行路径 +enable_debug :使能netmon debug,默认false + +[runtime] +enable_debug :使能runtime debug,默认false +enable_cpu_memory_hotplug :使能cpu和内存热插拔,默认false +internetworking_model :指定VM和容器网络互联模式 +disable_guest_seccomp :关闭在guest应用seccemp安全机制,默认true +enable_tracing :使能runtime opentracing,默认false +disable_new_netns :不为shim和hypervisor进程创建网络命名空间,默认false +experimental :开启实验特性,不支持用户自定义配置 +``` + +## 接口列表 + +**表 1** kata-runtime网络相关的命令行接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

子命令

+

文件示例

+

字段

+

含义

+

备注

+

kata-network

+
说明:
  • kata-network命令需成组使用。不经过kata-runtime kata-network添加的网络设备,无法使用kata-runtime kata-network删除或者列出。反之亦然。
  • kata-runtime kata-network通过文件或stdin传入配置参数。
+
+

add-iface

+
说明:
  • 一个interface只能添加到1个容器中。
  • 执行结果以返回值为准(非零返回值)。
+
+

  

+

{

+

"device":"tap1",

+

"name":"eth1",

+

"IPAddresses":[{"address":"172.17.1.10","mask":"24"}],

+

"mtu":1300,

+

"hwAddr":"02:42:20:6f:a2:80"

+

"vhostUserSocket":"/usr/local/var/run/openvswitch/vhost-user1"

+

}

+

  

+

device

+

设置网卡的主机端名称

+

必选。支持字母、数字、下划线“\_”、“-” 以及“.”字符,必须以字母开头,且长度不超过15。需要确保同一个宿主机上device不能重复。

+

name

+

设置网卡的容器内名称

+

必选。支持字母、数字、下划线“\_”、“-” 以及“.”字符,必须以字母开头,且长度不超过15。需要确保同一个Sandbox内name不能重复。

+

IPAddresses

+

设置网卡的IP地址

+

可选。

+

暂时支持一张网卡配置一个IP,如果不配置IP,则不会在容器内部配置IP。

+

mtu

+

设置网卡的mtu值

+

必选。

+

有效范围46~9600。

+

hwAddr

+

设置网卡的mac值

+

必选。

+

vhostUserSocket

+

设置dpdk轮循socket路径

+

可选。

+

路径最大长度128字节,命名规则支持数字、字母、“-”。必须以字母开头。

+

del-iface

+

{

+

"name":"eth1"

+

}

+

+

删除容器内的一个网卡

+
说明:

删除网卡时,仅根据网卡容器内名称(name字段)来删除。即便填写其他字段,kata也不会使用。

+
+

list-ifaces

+

+

+

查询容器内的网卡列表

+

+

add-route

+

{

+

"dest":"172.17.10.10/24",

+

"gateway":"",

+

"device":"eth1"

+

}

+

dest

+

设置路由对应的网段

+

格式为<ip>/<mask>,<ip>必选。

+

分三种情况:

+

1. 配置<ip>/<mask>;

+

2. 只配置<ip>,则默认掩码为32;

+

3. 配置"dest":"default",默认无dest,需传入gateway。

+

gateway

+

设置路由的下一跳网关

+

设置"dest":"default"时,gateway必选;其他情况可选。

+

device

+

设置路由对应的网卡名称

+

必选。

+

最长支持15字符。

+

del-route

+

{

+

"dest":"172.17.10.10/24"

+

}

+

+

删除容器的路由规则

+

dest为必选,device/gateway均为可选。

+
说明:

kata根据不同字段进行模糊匹配,删除对应的路由规则。

+
+

list-routes

+

+

+

查询容器内的路由列表

+

+
+ +**表 2** kata-ipvs命令行接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

子命令

+

字段

+

参数

+

子参数

+

含义

+

备注

+

kata-ipvs

+

ipvsadm

+

--parameters

+

-A, --add-service

+

-t, --tcp-service

+

-u, --udp-service

+

虚拟服务类型

+

必选项。--tcp-service、--udp-service,两个参数只能选择其一。格式为“ip:port”,port取值[1,65535]。

+

举例:

+
kata-runtime kata-ipvs ipvsadm --parameters "--add-service --tcp-service 172.17.0.7:80 --scheduler rr --persistent 3000" <container-id>
+

-s, --scheduler

+

负载均衡调度算法

+

必选项。取值范围:rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq。

+

-p, --persistent

+

持续服务时间

+

必选项。取值范围[1, 2678400],单位s。

+

-E, --edit-service

+

-t, --tcp-service

+

-u, --udp-service

+

虚拟服务类型

+

必选项。--tcp-service、--udp-service,两个参数只能选择其一。格式为“ip:port”,port取值[1,65535]。

+

-s, --scheduler

+

负载均衡调度算法

+

必选项。取值范围:rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq

+

-p, --persistent

+

持续服务时间

+

必选项。取值范围[1, 2678400],单位s。

+

-D, --delete-service

+

-t, --tcp-service

+

-u, --udp-service

+

虚拟服务类型

+

必选项。--tcp-service、--udp-service,两个参数只能选择其一。格式为“ip:port”,port取值[1,65535]。

+

-a, --add-server

+

-t, --tcp-service

+

-u, --udp-service

+

虚拟服务类型

+

必选项。--tcp-service、--udp-service,两个参数只能选择其一。格式为“ip:port”,port取值[1,65535]。

+

举例:

+
kata-runtime kata-ipvs ipvsadm --parameters "--add-server --tcp-service 172.17.0.7:80 --real-server 172.17.0.4:80 --weight 100" <container-id>
+

-r, --real-server

+

真实服务器地址

+

必选项。格式为“ip:port”,port取值[1,65535]。

+

-w, --weight

+

权重

+

可选项,取值[0,65535]。

+

-e, --edit-server

+

-t, --tcp-service

+

-u, --udp-service

+

虚拟服务类型

+

必选项。--tcp-service、--udp-service,两个参数只能选择其一。格式为“ip:port”,port取值[1,65535]。

+

-r, --real-server

+

真实服务器地址

+

必选项。格式为“ip:port”,port取值[1,65535]。

+

-w, --weight

+

权重

+

可选项,取值[0,65535]。

+

-d, --delete-server

+

-t, --tcp-service

+

-u, --udp-service

+

虚拟服务类型

+

必选项。--tcp-service、--udp-service,两个参数只能选择其一。格式为“ip:port”,port取值[1,65535]。

+

-r, --real-server

+

真实服务器地址

+

必选项。格式为“ip:port”,port取值[1,65535]。

+

-L, --list

+

-t, --tcp-service

+

-u, --udp-service

+

指定查询虚拟服务信息

+

可选项。

+

举例:

+
kata-runtime kata-ipvs ipvsadm --parameters "--list --tcp-service ip:port" <container-id>
+

--set

+

--tcp

+

tcp超时

+

必选项,取值[0, 1296000]。

+

举例:

+
kata-runtime kata-ipvs ipvsadm --parameters "--set 100 100 200" <container-id>
+

--tcpfin

+

tcpfin超时

+

必选项,取值[0, 1296000]。

+

--udp

+

udp超时

+

必选项,取值[0, 1296000]。

+

--restore

+

-

+

标准输入批量导入

+

可指定规则文件

+

举例:

+
kata-runtime kata-ipvs ipvsadm --restore -  <  <规则文件路径> <container-id>
+
说明:

单条添加时默认使用NAT模式,批量导入时添加真实服务器需手动添加-m参数使用NAT模式。

+

规则文件内容示例:

+

-A -t 10.10.11.12:100 -s rr -p 3000

+

-a -t 10.10.11.12:100 -r 172.16.0.1:80 -m

+

-a -t 10.10.11.12:100 -r 172.16.0.1:81 -m

+

-a -t 10.10.11.12:100 -r 172.16.0.1:82 -m

+
+

cleanup

+

--parameters

+

-d, --orig-dst

+

ip信息

+

必选项。

+

举例:

+
kata-runtime kata-ipvs cleanup --parameters "--orig-dst 172.17.0.4 --protonum tcp" <container-id>
+

-p, --protonum

+

协议类型

+

必选项,取值为tcp|udp 。

+
diff --git a/docs/en/25.03/Cloud/ContainerForm/SecureContainer/application-scenarios-2.md b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/application-scenarios-2.md new file mode 100644 index 0000000000000000000000000000000000000000..0850389b7cf36241dc1f940e78bbc1fbe9071f78 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/application-scenarios-2.md @@ -0,0 +1,6 @@ +# 使用方法 + +本章介绍安全容器的使用方法。 +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 安全容器的使用需要root权限。 diff --git a/docs/en/25.03/Cloud/ContainerForm/SecureContainer/configuring-resources-for-a-secure-container.md b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/configuring-resources-for-a-secure-container.md new file mode 100644 index 0000000000000000000000000000000000000000..e0b99d129f0c396cb72dff92558556d48696614a --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/configuring-resources-for-a-secure-container.md @@ -0,0 +1,36 @@ +# 为安全容器配置资源 + +- [为安全容器配置资源](#为安全容器配置资源) + - [资源共享](#资源共享-27) + - [限制资源](#限制资源) + - [热插拔限制内存资源](#热插拔限制内存资源) + +安全容器运行于虚拟化隔离的轻量级虚拟机内,因此资源的配置应分为两部分:对轻量级虚拟机的资源配置,即Host资源配置;对虚拟机内容器的配置,即Guest容器资源配置。以下资源配置均分为这两部分。 + +## 资源共享 + +由于安全容器运行于虚拟化隔离的轻量虚拟机内,故无法访问Host上某些namespace下的资源,因此启动时不支持--net host,--ipc host,--pid host,--uts host。 + +当启动一个Pod时,同一个Pod中的所有容器默认共享同一个net namespace和ipc namespace。如果同一个Pod中的容器需要共享pid namespace,则可以通过Kubernetes进行配置,Kubernetes 1.11版本该值为默认关闭。 + +## 限制资源 + +对资源的限制建议在configuration.toml中进行配置。 +常用的字段的有: + +- default_vcpus :指定每个SB/VM的默认vCPU数量 +- default_maxvcpus :指定每个SB/VM的默认最大vCPU数量 +- default_root_ports :指定每个SB/VM的默认Root Ports数量 +- default_bridges :指定每个SB/VM的默认bridges数量 +- default_memory :指定每个SB/VM的默认内存大小,默认为1024 MiB +- memory_slots :指定每个SB/VM的内存插槽数量,默认为10 + +## 热插拔限制内存资源 + +内存热插拔对于容器在部署时内存动态分配来说是一项关键特性。由于安全容器是运行在虚拟机当中的,所以这一项特性需要VMM和guest kernel两方面的支持。目前kata在arm64上默认使用的QEMU和guest kernel都是支持这一特性的。除了VMM和guest kernel,内存热插拔还取决于依赖着固件的ACPI。在x86上,由于ACPI可以隐式地随固件一起启动,所以可以直接用QEMU去启动一个打开了ACPI的虚拟机。不过在arm64上的话,在使用内存热插拔之前就需要手动去安装UEFI ROM。 + +```shell +$ pushd $GOPATH/src/github.com/kata-containers/tests +$ sudo .ci/aarch64/install_rom_aarch64.sh #仅限ubuntu +$ popd +``` diff --git a/docs/en/25.03/Cloud/ContainerForm/SecureContainer/figures/kata-arch.png b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/figures/kata-arch.png new file mode 100644 index 0000000000000000000000000000000000000000..60fbb602d94cf7a8e13bd6ecb520c99e574037e6 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/figures/kata-arch.png differ diff --git a/docs/en/25.03/Cloud/ContainerForm/SecureContainer/figures/zh_cn_image_0221924928.png b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/figures/zh_cn_image_0221924928.png new file mode 100644 index 0000000000000000000000000000000000000000..df046870b3dfbcbe4acb4a91f509ba8b26fa7c80 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/figures/zh_cn_image_0221924928.png differ diff --git a/docs/en/25.03/Cloud/ContainerForm/SecureContainer/installation-and-deployment-2.md b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/installation-and-deployment-2.md new file mode 100644 index 0000000000000000000000000000000000000000..7443f11f9b8ac34883523449a2d060ab5c1b310c --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/installation-and-deployment-2.md @@ -0,0 +1,114 @@ +# 安装与配置 + +## 安装方法 + +### 前提条件 + +- 安全容器的安装需要使用root权限。 +- 为了获取更好的性能体验,安全容器需要运行在裸金属服务器上,**暂不支持安全容器运行在虚拟机内**。 +- 安全容器运行依赖以下组件,请确保环境上已安装所需版本的依赖组件。以下组件来自配套的openEuler版本。如果使用iSula容器引擎,请参考iSula容器引擎的[安装与配置](../../ContainerEngine/iSulaContainerEngine/installation-configuration.md)章节安装iSulad。 + - docker-engine + - qemu + +### 安装操作 + +安全容器发布组件集成在同一个`kata-containers-.rpm`包中,使用rpm命令可以直接安装对应的软件,其中version为版本号。 + +```bash +rpm -ivh kata-containers-.rpm +``` + +## 配置方法 + +### docker-engine容器引擎的配置 + +为了让docker-engine容器引擎支持新的容器运行时kata-runtime,需要通过以下步骤对docker-engine容器引擎进行配置: + +1. 请保证环境上所有的软件包(docker-engine、kata-containers)都已经安装完毕。 +2. 停止docker-engine。 + + ```bash + systemctl stop docker + ``` + +3. 修改docker-engine的配置文件/etc/docker/daemon.json,并新增如下配置: + + ```conf + { + "runtimes": { + "kata-runtime": { + "path": "/usr/bin/kata-runtime", + "runtimeArgs": [ + "--kata-config", + "/usr/share/defaults/kata-containers/configuration.toml" + ] + } + } + } + ``` + +4. 重新启动docker-engine。 + + ```bash + systemctl start docker + ``` + +### iSula容器引擎的配置 + +与docker-engine容器引擎类似,为了让iSula容器引擎支持新的容器运行时kata-runtime,需要通过以下步骤对iSula容器引擎进行配置: + +1. 请保证环境上所有的软件包(iSulad、kata-containers)都已经安装完毕。 +2. 停止isulad。 + + ```bash + systemctl stop isulad + ``` + +3. 修改iSula容器引擎的配置文件/etc/isulad/daemon.json,并新增如下配置: + + ```conf + { + "runtimes": { + "kata-runtime": { + "path": "/usr/bin/kata-runtime", + "runtime-args": [ + "--kata-config", + "/usr/share/defaults/kata-containers/configuration.toml" + ] + } + } + } + ``` + +4. 重新启动isulad。 + + ```bash + systemctl start isulad + ``` + +### 安全容器全局配置文件configuration-toml + +安全容器提供全局配置文件configuration.toml进行配置开关,用户也可以定制安全容器配置文件路径与配置选项。 + +在docker-engine的runtimeArges字段可以利用--kata-config指定私有文件,默认的配置文件路径为/usr/share/defaults/kata-containers/configuration.toml。 + +常用配置文件字段如下,详细的配置文件选项参见“安全容器 > 附录 > configuration.toml配置说明”。 + +1. hypervisor.qemu + - path :指定虚拟化qemu执行路径。 + - kernel :指定guest kernel执行路径。 + - initrd :指定guest initrd执行路径。 + - machin\_type :指定模拟芯片类型,其中arm为virt,x86架构为pc。 + - kernel\_params :指定guest内核运行参数。 + +2. proxy.kata + - path :指定kata-proxy运行路径。 + - enable\_debug :kata-proxy进程debug开关。 + +3. agent.kata + - enable\_blk\_mount :开启block设备guest挂载。 + - enable\_debug :kata-agent进程debug开关。 + +4. runtime + - enable\_cpu\_memory\_hotplug:CPU和内存热插拔开关。 + - enable\_debug:kata-runtime进程debug开关。 diff --git a/docs/en/25.03/Cloud/ContainerForm/SecureContainer/managing-the-lifecycle-of-a-secure-container.md b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/managing-the-lifecycle-of-a-secure-container.md new file mode 100644 index 0000000000000000000000000000000000000000..1d8d63c6ff0df8fc8e9ed1674f09733053c8d9d7 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/managing-the-lifecycle-of-a-secure-container.md @@ -0,0 +1,100 @@ +# 管理安全容器的生命周期 + +- [管理安全容器的生命周期](#管理安全容器的生命周期) + - [启动安全容器](#启动安全容器) + - [停止安全容器](#停止安全容器) + - [删除安全容器](#删除安全容器) + - [在容器中执行一条新的命令](#在容器中执行一条新的命令) + +## 启动安全容器 + +用户可以使用docker-engine或者iSulad作为安全容器的容器引擎,两者的调用方式类似,请用户自行选择一种方式启动安全容器。 + +启动安全容器的操作步骤如下: + +1. 确保安全容器组件已经正确安装部署。 +2. 准备容器镜像。假设容器镜像为busybox,使用docker-engine和iSula容器引擎下载容器镜像的命令分别如下: + + ```bash + docker pull busybox + ``` + + ```bash + isula pull busybox + ``` + +3. 启动一个安全容器。使用docker-engine和iSula容器引擎启动安全容器的命令分别如下: + + ```bash + docker run -tid --runtime kata-runtime --network none busybox + ``` + + ```bash + isula run -tid --runtime kata-runtime --network none busybox + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > + > 安全容器网络使用仅支持CNI网络,不支持CNM网络,不支持使用-p和--expose暴露容器端口,使用安全容器时需指定参数--net=none。 + +4. 启动一个Pod + 1. 启动pause容器并根据回显获取pod的sandbox-id。使用docker-engine和iSula容器引擎启动的命令分别如下: + + ```bash + docker run -tid --runtime kata-runtime --network none --annotation io.kubernetes.docker.type=podsandbox + ``` + + ```bash + isula run -tid --runtime kata-runtime --network none --annotation io.kubernetes.cri.container-type=sandbox + ``` + + 2. 创建业务容器并加入到这个pod中。使用docker-engine和iSula容器引擎创建的命令分别如下: + + ```bash + docker run -tid --runtime kata-runtime --network none --annotation io.kubernetes.docker.type=container --annotation io.kubernetes.sandbox.id= busybox + ``` + + ```bash + isula run -tid --runtime kata-runtime --network none --annotation io.kubernetes.cri.container-type=container --annotation io.kubernetes.cri.sandbox-id= busybox + ``` + + --annotation用于容器类型的标注,这里的docker-engine和isula提供该字段,上游社区的开源docker引擎则不提供。 + +## 停止安全容器 + +- 停止一个安全容器。 + + ```bash + docker stop + ``` + +- 停止一个Pod。 + + Pod停止需要注意顺序,pause容器与Pod生命周期相同,因此先停止业务容器后再停止pause容器。 + +## 删除安全容器 + +删除前请确保容器已经停止: + +```bash +docker rm +``` + +如果需要强制删除一个正在运行的容器,可以使用**-f**强制删除: + +```bash +docker rm -f +``` + +## 在容器中执行一条新的命令 + +由于pause容器仅作为占位容器,如果启动一个Pod时,请在业务容器内执行新的命令,pause容器并没有相应的指令;如果只启动一个容器时,则可以直接执行新增命令: + +```bash +docker exec -ti +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> - 如遇到docker exec -ti进入容器的同时,另一终端执行docker restart或者docker stop命令造成exec界面卡住的情况,可使用Ctrl+P+Q退出docker exec操作界面。 +> - 如果使用-d参数则命令在后台执行,不会打印错误信息,其退出码也不能作为命令执行是否正确的判断依据。 diff --git a/docs/en/25.03/Cloud/ContainerForm/SecureContainer/monitoring-secure-containers.md b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/monitoring-secure-containers.md new file mode 100644 index 0000000000000000000000000000000000000000..5f728428d80839c62d4d14c405f18f7aab673539 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/monitoring-secure-containers.md @@ -0,0 +1,54 @@ +# 监控安全容器 + +## 描述 + +kata 2.x中移除了kata-runtime events命令,代之以kata-runtime metrics命令,用以收集sandbox的指标信息,包括但不限于虚拟机信息、shim v2的cpu seconds、guest OS的CPU信息等等。格式符合Prometheus metric,可以配合kata-monitor上报至Prometheus。 + +## 用法 + +```bash +kata-runtime metrics +``` + +## 前置条件 + +sandbox id为长id,要查询的容器状态必须为running,否则报错:Get " unix /run/vc/\/shim-monitor : connect : connection refused + +当使用annotation指定容器类型为运行在某个sandbox中的容器时,用kata-runtime metrics查询该容器会失败,只能去查询该容器对应的sandbox。 + +该命令只支持查询监控一个sandbox的状态。 + +## 示例 + +```bash +$ kata-runtime metrics e2270357d23f9d3dd424011e1e70aa8defb267d813c3d451db58f35aeac97a04 + +# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles. +# TYPE go_gc_duration_seconds summary +go_gc_duration_seconds{quantile="0"} 2.656e-05 +go_gc_duration_seconds{quantile="0.25"} 3.345e-05 +go_gc_duration_seconds{quantile="0.5"} 3.778e-05 +go_gc_duration_seconds{quantile="0.75"} 4.657e-05 +go_gc_duration_seconds{quantile="1"} 0.00023001 +go_gc_duration_seconds_sum 0.00898126 +go_gc_duration_seconds_count 195 +# HELP go_goroutines Number of goroutines that currently exist. +# TYPE go_goroutines gauge +go_goroutines 27 +# HELP go_info Information about the Go environment. +# TYPE go_info gauge +go_info{version="go1.17.3"} 1 +# HELP kata_hypervisor_netdev Net devices statistics. +# TYPE kata_hypervisor_netdev gauge +kata_hypervisor_netdev{interface="lo",item="recv_bytes"} 0 +kata_hypervisor_netdev{interface="lo",item="recv_compressed"} 0 +kata_hypervisor_netdev{interface="lo",item="recv_drop"} 0 +kata_hypervisor_netdev{interface="lo",item="recv_errs"} 0 +kata_hypervisor_netdev{interface="lo",item="recv_fifo"} 0 +kata_hypervisor_netdev{interface="lo",item="recv_frame"} 0 +kata_hypervisor_netdev{interface="lo",item="recv_multicast"} 0 +kata_hypervisor_netdev{interface="lo",item="recv_packets"} 0 +kata_hypervisor_netdev{interface="lo",item="sent_bytes"} 0 +kata_hypervisor_netdev{interface="lo",item="sent_carrier"} 0 +kata_hypervisor_netdev{interface="lo",item="sent_colls"} 0 +``` diff --git a/docs/en/25.03/Cloud/ContainerForm/SecureContainer/overview.md b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..795e5282aec84fe82d0e5583e7f0932191671ac0 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/overview.md @@ -0,0 +1,27 @@ +# 概述 + +安全容器是虚拟化技术和容器技术的有机结合,相比普通linux容器,安全容器具有更好的隔离性。 + +普通linux容器利用namespace进行进程间运行环境的隔离,并使用cgroup进行资源限制;因此普通linux容器本质上还是共用同一个内核,单个容器有意或无意影响到内核都会影响到整台宿主机上的容器。 + +安全容器是使用虚拟化层进行容器间的隔离,同一个主机上不同的容器间运行互相不受影响。 + +**图 1** 安全容器架构 +![](./figures/kata-arch.png) + +安全容器与Kubernetes中的Pod概念紧密联系,Kubernetes为容器调度管理平台的开源生态标准,它定义了一组容器操作相关接口(Container Runtime Interface 简称CRI)。 + +在CRI标准中,Pod为完成一组服务需要的一组容器集合,是编排调度的最小单元,通常共享IPC和网络namespace;一个Pod必然包含一个占位容器(pause容器)以及一个或多个业务容器,其中pause容器的生命周期与其所在Pod的生命周期相同。 + +其中安全容器中的一个轻量级虚拟机对应为一个Pod,在此虚拟机中启动的第一个容器为pause容器,以后依次启动的容器为业务容器。 + +安全容器同时提供启动单个容器与启动Pod的功能。 + +安全容器与周边组件的关系如[图2](#fig17734185518269)所示。 + +**图 2** 安全容器与周边组件的关系 +![](./figures/zh_cn_image_0221924928.png) + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 安全容器的安装和使用需要使用root权限。 diff --git a/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-caution.gif b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-caution.gif differ diff --git a/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-danger.gif b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-danger.gif differ diff --git a/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-note.gif b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-notice.gif b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-notice.gif differ diff --git a/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-tip.gif b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-tip.gif differ diff --git a/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-warning.gif b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerForm/SecureContainer/public_sys-resources/icon-warning.gif differ diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/_menu.md b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..fee0af8970dafda0e01d0409606483556b7756e3 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/_menu.md @@ -0,0 +1,37 @@ +--- +label: '系统容器' +ismanual: 'Y' +description: '解决在重计算、高性能、大并发的场景下,重型应用和业务云化的问题' +children: + - label: '概述' + href: './overview.md' + - label: '安装指导' + href: './installation-guideline.md' + - label: '使用指南' + href: './usage-guide.md' + children: + - label: '指定rootfs创建容器' + href: './specifying-rootfs-to-create-a-container.md' + - label: '通过systemd启动容器' + href: './using-systemd-to-start-a-container.md' + - label: '容器内reboot/shutdown' + href: './reboot-or-shutdown-in-a-container.md' + - label: 'cgroup路径可配置' + href: './configurable-cgroup-path.md' + - label: 'namespace化内核参数可写' + href: './writable-namespace-kernel-parameters.md' + - label: '共享内存通道' + href: './shared-memory-channels.md' + - label: '动态加载内核模块' + href: './dynamically-loading-the-kernel-module.md' + - label: '环境变量持久化' + href: './environment-variable-persisting.md' + - label: '最大句柄数限制' + href: './maximum-number-of-handles.md' + - label: '安全性和隔离性' + href: './security-and-isolation.md' + - label: '容器资源动态管理' + href: './dynamically-managing-container-resources-(syscontainer-tools).md' + - label: '附录' + href: './appendix-1.md' +--- \ No newline at end of file diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/appendix-1.md b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/appendix-1.md new file mode 100644 index 0000000000000000000000000000000000000000..d29a56e4de1bc1b5135b71d2308711839b8da628 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/appendix-1.md @@ -0,0 +1,92 @@ +# 附录 + +- [附录](#附录) + - [命令行接口列表](#命令行接口列表) + +## 命令行接口列表 + +此处仅列出系统容器与普通容器的差异命令,其他命令用户可以查阅iSulad容器引擎相关章节,或者执行isula XXX --help进行查询。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

参数指定值说明

+

isula create/run

+

--external-rootfs

+
  • 字符串变量。
  • 宿主机某个绝对路径。
  • 运行系统容器时,必须使用此参数指定特定虚拟机的rootfs。
+

--system-container

+
  • 布尔变量。
  • 指定某个容器是否属于系统容器,如果是系统容器场景,必须使能。
+

--add-host

+
  • 字符串变量。
  • 格式为:<hostname>:<ip>,指定容器的hosts配置,可以指定多个参数。
+

--dns,--dns-option,--dns-search

+
  • 字符串变量。
  • 可以指定多个,指定容器的dns配置。
+

--ns-change-opt

+
  • 字符串变量。
  • 容器namespace化内核参数可修改选项,参数只能为net或ipc,如果指定多个,用逗号隔开,例如--ns-change-opt=net,ipc。
+

--oom-kill-disable

+
  • 布尔变量。
  • 表示是否打开oom-kill-disable功能。
+

--shm-size

+
  • 字符串变量。
  • 设置/dev/shm大小,默认64MB。 支持单位B(b)、K(k)、M(m)、G(g)、T(t)、P(p)。
+

--sysctl

+
  • 字符串变量。
  • 指定容器内核参数值,格式为key=value,可传入多个,sysctl白名单如下:
+

kernel.msgmax,kernel.msgmnb,kernel.msgmni,kernel.sem,kernel.shmall,kernel.shmmax,kernel.shmmni, kernel.shm_rmid_forced,kernel.pid_max,net.,fs.mqueue。

+
说明:

容器内kernel.pid_max参数需要内核支持pid_max namespace化,否则会报错。

+

容器内sysctl白名单参数值限制与物理机对应的内核参数限制保持一致(包括参数类型、参数取值范围等)。

+
+

--env-target-file

+
  • 字符串变量。
  • 指定env持久化文件路径(路径必须为绝对路径,且文件必须在rootfs目录下),文件如果存在不能超过10MB,如果--env和文件里面的env出现冲突,--env指定值生效。
  • 绝对路径的根目录/为rootfs根目录,,即要指定文件路径为容器内/etc/environment,只用指定env-target-file=/etc/environment,而不是env-target-file=/path/of/root-fs/etc/environemt。
+

--cgroup-parent

+
  • 字符串变量。
  • 指定容器的cgroup父目录,cgroup根路径为/sys/fs/cgroup/<controller>。
+

--host-channel

+
  • 字符串变量。
  • 指定宿主机和容器共享内存空间(tmpfs),格式为:
+

<host path>:<container path>:<rw/ro>:<size limit>

+

--files-limit

+
  • 字符串变量。
  • 整数值,指定容器内文件句柄数最大值。
+

--user-remap

+
  • 字符串变量。
  • 参数格式为:<uid>:<gid>:<offset>
+
diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/configurable-cgroup-path.md b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/configurable-cgroup-path.md new file mode 100644 index 0000000000000000000000000000000000000000..e8d6d6d201544e8b3035eaddb26dfc80fce90e9a --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/configurable-cgroup-path.md @@ -0,0 +1,95 @@ +# cgroup路径可配置 + +## 功能描述 + +系统容器提供在宿主机上进行容器资源隔离和预留的能力。通过\--cgroup-parent参数,可以将容器使用的cgroup目录指定到某个特定目录下,从而达到灵活分配宿主机资源的目的。例如可以设置容器a、b、c的cgroup父路径为/lxc/cgroup1,容器d、e、f的cgroup父路径为/lxc/cgroup2,这样通过cgroup路径将容器分为两个group,实现容器cgroup组层面的资源隔离。 + +## 参数说明 + + + + + + + + + + + + +

命令

+

参数

+

参数指定值说明

+

isula create/run

+

--cgroup-parent

+
  • 字符串变量。
  • 指定容器cgroup父路径。
+
+ +除了通过命令行指定单个系统容器对应的cgroup父路径外,还可通过修改iSulad容器引擎启动配置文件,指定所有容器的cgroup路径。 + + + + + + + + + + + + +

配置文件路径

+

配置项

+

配置项说明

+

/etc/isulad/daemon.json

+

--cgroup-parent

+
  • 字符串变量。
  • 指定容器默认cgroup父路径。
  • 配置示例:"cgroup-parent": "/lxc/mycgroup"
+
+ +## 约束限制 + +- 如果daemon端和客户端都设置了cgroup parent参数,最终以客户端指定的\--cgroup-parent生效。 +- 如果已启动容器A,然后启动容器B,容器B的cgroup父路径指定为容器A的cgroup路径,在删除容器的时候需要先删除容器B再删除容器A,否则会导致cgroup资源残留。 + +## 使用示例 + +启动系统容器,指定--cgroup-parent参数: + +```bash +[root@localhost ~]# isula run -tid --cgroup-parent /lxc/cgroup123 --system-container --external-rootfs /root/myrootfs none init +115878a4dfc7c5b8c62ef8a4b44f216485422be9a28f447a4b9ecac4609f332e +``` + +查看容器init进程的cgroup信息: + +```bash +[root@localhost ~]# isula inspect -f "{{json .State.Pid}}" 11 +22167 +[root@localhost ~]# cat /proc/22167/cgroup +13:blkio:/lxc/cgroup123/115878a4dfc7c5b8c62ef8a4b44f216485422be9a28f447a4b9ecac4609f332e +12:perf_event:/lxc/cgroup123/115878a4dfc7c5b8c62ef8a4b44f216485422be9a28f447a4b9ecac4609f332e +11:cpuset:/lxc/cgroup123/115878a4dfc7c5b8c62ef8a4b44f216485422be9a28f447a4b9ecac4609f332e +10:pids:/lxc/cgroup123/115878a4dfc7c5b8c62ef8a4b44f216485422be9a28f447a4b9ecac4609f332e +9:rdma:/lxc/cgroup123/115878a4dfc7c5b8c62ef8a4b44f216485422be9a28f447a4b9ecac4609f332e +8:devices:/lxc/cgroup123/115878a4dfc7c5b8c62ef8a4b44f216485422be9a28f447a4b9ecac4609f332e +7:hugetlb:/lxc/cgroup123/115878a4dfc7c5b8c62ef8a4b44f216485422be9a28f447a4b9ecac4609f332e +6:memory:/lxc/cgroup123/115878a4dfc7c5b8c62ef8a4b44f216485422be9a28f447a4b9ecac4609f332e +5:net_cls,net_prio:/lxc/cgroup123/115878a4dfc7c5b8c62ef8a4b44f216485422be9a28f447a4b9ecac4609f332e +4:cpu,cpuacct:/lxc/cgroup123/115878a4dfc7c5b8c62ef8a4b44f216485422be9a28f447a4b9ecac4609f332e +3:files:/lxc/cgroup123/115878a4dfc7c5b8c62ef8a4b44f216485422be9a28f447a4b9ecac4609f332e +2:freezer:/lxc/cgroup123/115878a4dfc7c5b8c62ef8a4b44f216485422be9a28f447a4b9ecac4609f332e +1:name=systemd:/lxc/cgroup123/115878a4dfc7c5b8c62ef8a4b44f216485422be9a28f447a4b9ecac4609f332e/init.scope +0::/lxc/cgroup123/115878a4dfc7c5b8c62ef8a4b44f216485422be9a28f447a4b9ecac4609f332e +``` + +可以看到容器的cgroup父路径被设置为/sys/fs/cgroup//lxc/cgroup123 + +同时,对于所有容器cgroup父路径的设置可以配置一下容器daemon文件,例如: + +```conf +{ + "cgroup-parent": "/lxc/cgroup123", +} +``` + +然后重启容器引擎,配置生效。 diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/dynamically-loading-the-kernel-module.md b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/dynamically-loading-the-kernel-module.md new file mode 100644 index 0000000000000000000000000000000000000000..dac7da266cdca29ab3ab40458e49b9d50b0c6890 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/dynamically-loading-the-kernel-module.md @@ -0,0 +1,53 @@ +# 动态加载内核模块 + +## 功能描述 + +容器内业务可能依赖某些内核模块,可通过设置环境变量的方式,在系统容器启动前动态加载容器中业务需要的内核模块到宿主机,此特性需要配合syscontainer-hooks一起使用,具体使用可参看"容器资源动态管理(syscontainer-tools)"章节。 + +## 参数说明 + + + + + + + + + + + + +

命令

+

参数

+

参数指定值说明

+

isula create/run

+

-e KERNEL_MODULES=module_name1,module_name

+
  • 字符串变量。
  • 支持配置多个模块,模块名以逗号分隔。
+
+ +## 约束限制 + +- 如果加载的内核模块是未经过验证的,或者跟宿主机已有模块冲突的场景,会导致宿主机出现不可预知问题,在做加载内核模块时需要谨慎操作。 +- 动态加载内核模块通过将需要加载的内核模块传递给容器,此功能是依靠syscontainer-tools捕获到容器启动的环境变量实现,依赖syscontainer-tools的正确安装部署。 +- 加载的内核模块需要手动进行删除。 + +## 使用示例 + +启动系统容器时,指定-e KERNEL\_MODULES参数,待系统容器启动后,可以看到ip\_vs模块被成功加载到内核中。 + +```bash +[root@localhost ~]# lsmod | grep ip_vs +[root@localhost ~]# isula run -tid -e KERNEL_MODULES=ip_vs,ip_vs_wrr --hook-spec /etc/syscontainer-tools/hookspec.json --system-container --external-rootfs /root/myrootfs none init +ae18c4281d5755a1e153a7bff6b3b4881f36c8e528b9baba8a3278416a5d0980 +[root@localhost ~]# lsmod | grep ip_vs +ip_vs_wrr 16384 0 +ip_vs 176128 2 ip_vs_wrr +nf_conntrack 172032 7 xt_conntrack,nf_nat,nf_nat_ipv6,ipt_MASQUERADE,nf_nat_ipv4,nf_conntrack_netlink,ip_vs +nf_defrag_ipv6 20480 2 nf_conntrack,ip_vs +libcrc32c 16384 3 nf_conntrack,nf_nat,ip_vs +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> - 宿主机需要安装syscontainer-tools。 +> - 需要指定--hooks-spec为syscontainer hooks。 diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/dynamically-managing-container-resources-(syscontainer-tools).md b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/dynamically-managing-container-resources-(syscontainer-tools).md new file mode 100644 index 0000000000000000000000000000000000000000..287e9b935d453e936da743e194c37ec5e7ac98c3 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/dynamically-managing-container-resources-(syscontainer-tools).md @@ -0,0 +1,476 @@ +# 容器资源动态管理 + +普通容器无法支持对容器内的资源进行管理,例如添加一个块设备到容器、插入一块物理/虚拟网卡到容器。系统容器场景下,通过syscontainer-tools工具可以实现动态为容器挂载/卸载块设备,网络设备,路由和卷等资源。 + +要使用此功能,需要安装syscontainer-tools工具: + +```sh +[root@localhost ~]# yum install syscontainer-tools +``` + +## 设备管理 + +### 功能描述 + +syscontainer-tools支持将宿主机上的块设备(比如磁盘、LVM)或字符设备(比如GPU、binner、fuse)添加到容器中。在容器中使用该设备,例如可以对磁盘进行fdisk格式化,写入fs等操作。在容器不需要设备时,syscontainer-tools可以将设备从容器中删除,归还宿主机。 + +### 命令格式 + +```sh +syscontainer-tools [COMMAND][OPTIONS] [ARG...] +``` + +其中: + +COMMAND:设备管理相关的命令。 + +OPTIONS:设备管理命令支持的选项。 + +container\_id:容器id。 + +ARG:命令对应的参数。 + +### 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

功能说明

+

选项说明

+

参数说明

+

add-device

+

将宿主机块设备/字符设备添加到容器中。

+

支持的选项如下:

+
  • --blkio-weight-device:设置块设备IO权重(相对权重,10-100之间)。
  • --device-read-bps:设置块设备读取速率限制(byte/秒)。
  • --device-read-iops:设置块设备读取速率限制(IO/秒)。
  • --device-write-bps:设置块设备写入速率限制(byte/秒)。
  • --device-write-iops:设置块设备写入速率限制(IO/秒)。
  • --follow-partition:如果块设备是基础块设备(主SCSI块磁盘),加入此参数可以添加主磁盘下的所有分区。
  • --force:如果容器中已有块设备/字符设备,使用此参数覆盖旧的块设备/字符设备文件。
  • --update-config-only:只更新配置文件不实际做添加磁盘动作。
+

参数格式为:hostdevice[:containerdevice][:permission] [hostdevice[:containerdevice][:permission] ...]

+

其中:

+

hostdevice:设备在主机上的路径。

+

containerdevice:设备在容器中的路径。

+

permission:容器内对设备的操作权限。

+

remove-device

+

将块设备/字符设备从容器中删除,还原至宿主机。

+

支持的选项如下:

+

--follow-partition:如果块设备是基础块设备(主SCSI块磁盘),加入此参数可以删除容器中主磁盘下的所有分区,还原至宿主机。

+

参数格式为:hostdevice[:containerdevice] [hostdevice[:containerdevice] ...]

+

其中:

+

hostdevice:设备在主机上的路径。

+

containerdevice:设备在容器中的路径。

+

list-device

+

列出容器中所有的块设备/字符设备。

+

支持的选项如下:

+
  • --pretty:按照json格式输出。
  • --sub-partition:如果某磁盘为主磁盘,加入此flag,在显示主磁盘的同时,也显示主磁盘的子分区。
+

+

update-device

+

更新磁盘Qos。

+

支持的选项如下:

+
  • --device-read-bps:设置块设备读取速率限制(byte/秒),建议设置值大于等于1024。
  • --device-read-iops:设置块设备读取速率限制(IO/秒)。
  • --device-write-bps:设置块设备写入速率限制(byte/秒),建议设置值大于等于1024。
  • --device-write-iops:设置块设备写入速率限制(IO/秒)。
+

+
+ +### 约束限制 + +- 添加/删除设备的时机可以是容器实例非运行状态,完成操作后启动容器,容器内会有体现;也可以在容器运行时(running)动态添加。 +- 不能在容器内和host上并发进行fdisk对磁盘的格式化写入,会影响容器磁盘使用。 +- add-device将磁盘添加到容器的特定目录时,如果容器内的父目录为多级目录(比如/dev/a/b/c/d/e...)且目录层级不存在,则syscontainer-tools会自动在容器内创建对应目录;当删除时,不会将创建的父目录删除。如果用户下一次add-device到该父目录,则会提示已经存在无法添加成功。 +- add-device添加磁盘、更新磁盘参数时,配置磁盘Qos;当配置磁盘Qos的read/write bps、read/write IOPS值时,不建议配置值过小,当设置过小时,会造成磁盘表现为不可读(实际原因是速度过慢),最终影响业务功能。 +- 使用--blkio-weight-device来限制指定块设备的权重,如果当前块设备仅支持BFQ模式,可能会报错,提示用户检查当前OS环境是否支持BFQ块设备权重值设置。 + +### 使用示例 + +- 启动一个系统容器,指定hook spec为syscontainer hook执行配置脚本 + + ```sh + [root@localhost ~]# isula run -tid --hook-spec /etc/syscontainer-tools/hookspec.json --system-container --external-rootfs /root/root-fs none init + eed1096c8c7a0eca6d92b1b3bc3dd59a2a2adf4ce44f18f5372408ced88f8350 + ``` + +- 添加一个块设备到容器 + + ```sh + [root@localhost ~]# syscontainer-tools add-device ee /dev/sdb:/dev/sdb123 + Add device (/dev/sdb) to container(ee,/dev/sdb123) done. + [root@localhost ~]# isula exec ee fdisk -l /dev/sdb123 + Disk /dev/sdb123: 50 GiB, 53687091200 bytes, 104857600 sectors + Units: sectors of 1 * 512 = 512 bytes + Sector size (logical/physical): 512 bytes / 512 bytes + I/O size (minimum/optimal): 512 bytes / 512 bytes + Disklabel type: dos + Disk identifier: 0xda58a448 + + Device Boot Start End Sectors Size Id Type + /dev/sdb123p1 2048 104857599 104855552 50G 5 Extended + /dev/sdb123p5 4096 104857599 104853504 50G 83 Linux + ``` + +- 更新设备信息 + + ```sh + [root@localhost ~]# syscontainer-tools update-device --device-read-bps /dev/sdb:10m ee + Update read bps for device (/dev/sdb,10485760) done. + ``` + +- 删除设备 + + ```sh + [root@localhost ~]# syscontainer-tools remove-device ee /dev/sdb:/dev/sdb123 + Remove device (/dev/sdb) from container(ee,/dev/sdb123) done. + Remove read bps for device (/dev/sdb) done. + ``` + +## 网卡管理 + +### 功能描述 + +syscontainer-tools支持将宿主机上的物理网卡或虚拟网卡插入到容器,在不使用网卡的时候从容器中删除归还给宿主机,并且可以动态修改网卡配置。插入物理网卡即把宿主机上一块网卡直接添加到容器中,插入虚拟网卡则需要先创建一对veth pair,之后将一端插入到容器中。 + +### 命令格式 + +```sh +syscontainer-tools [COMMAND][OPTIONS] +``` + +其中: + +COMMAND:网卡管理相关的命令。 + +OPTIONS:网卡管理命令支持的选项。 + +container\_id:容器id。 + +### 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

功能说明

+

选项说明

+

add-nic

+

给容器创建一个网卡。

+

支持的选项如下:

+
  • --type:设置网卡类型,当前只支持eth/veth。
  • --name:设置网卡名称,格式为[host:]<container>,host不写是随机名字。
  • --ip:设置网卡IP地址。
  • --mac:设置网卡mac地址。
  • --bridge:设置网卡绑定的网桥。
  • --mtu:设置网卡的mtu值,缺省值为1500。
  • --update-config-only:如果此flag设置了,只更新配置文件,不会实际做添加网卡的动作。
  • --qlen:配置qlen值,缺省值为1000。
+

remove-nic

+

从容器中将网卡删除,还原至宿主机。

+

支持的选项如下:

+
  • --type:设置网卡的类型。
  • --name:设置网卡的名称,格式为[host:]<container>。
+

list-nic

+

列出容器中所有的网卡。

+

支持的选项如下:

+
  • --pretty:按照json格式输出。
  • --filter:按照过滤格式输出,比如--filter '{"ip":"192.168.3.4/24", "Mtu":1500}'。
+

update-nic

+

更改容器内指定网卡的配置参数。

+

支持的选项如下:

+
  • --name:容器内网卡名(必须项)。
  • --ip:设置网卡IP地址。
  • --mac:设置网卡mac地址。
  • --bridge:设置网卡绑定的网桥。
  • --mtu:设置网卡的mtu值。
  • --update-config-only:如果此flag设置了,只更新配置文件,不会实际做更新网卡的动作。
  • --qlen:配置qlen值。
+
+ +### 约束限制 + +- 支持添加物理网卡(eth)和虚拟网卡(veth)两种类型。 +- 在添加网卡时可以同时对网卡进行配置,参数包括--ip/--mac/--bridge/--mtu/--qlen。 +- 支持最多添加8个物理网卡到容器。 +- 使用syscontainer-tools add-nic向容器添加eth网卡后,如果不加hook,在容器退出前必须手工将nic删除,否则在host上的eth网卡的名字会被更改成容器内的名字。 +- 对于物理网卡(1822 vf网卡除外),add-nic必须使用原mac地址,update-nic禁止修改mac地址,容器内也不允许修改mac地址。 +- 使用syscontainer-tools add-nic时,设置mtu值,设置范围跟具体的网卡型号有关。 +- 使用syscontainer-tools向容器添加网卡和路由时,建议先执行add-nic添加网卡,然后执行add-route添加路由;使用syscontainer-tools从容器删除网卡和路由时,建议先执行remove-route删除路由,然后执行remove-nic删除网卡。 +- 使用syscontainer-tools添加网卡时,一块网卡只能添加到一个容器中。 + +### 使用示例 + +- 启动一个系统容器,指定hook spec为syscontainer hook执行配置脚本: + + ```sh + [root@localhost ~]# isula run -tid --hook-spec /etc/syscontainer-tools/hookspec.json --system-container --external-rootfs /root/root-fs none init + 2aaca5c1af7c872798dac1a468528a2ccbaf20b39b73fc0201636936a3c32aa8 + ``` + +- 添加一个虚拟网卡到容器 + + ```sh + [root@localhost ~]# syscontainer-tools add-nic --type "veth" --name abc2:bcd2 --ip 172.17.28.5/24 --mac 00:ff:48:13:xx:xx --bridge docker0 2aaca5c1af7c + Add network interface to container 2aaca5c1af7c (bcd2,abc2) done + ``` + +- 添加一个物理网卡到容器 + + ```sh + [root@localhost ~]# syscontainer-tools add-nic --type "eth" --name eth3:eth1 --ip 172.17.28.6/24 --mtu 1300 --qlen 2100 2aaca5c1af7c + Add network interface to container 2aaca5c1af7c (eth3,eth1) done + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > + > 添加虚拟网卡或物理网卡时,请确保网卡处于空闲状态,添加正在使用的网卡会导致系统网络断开。 + +## 路由管理 + +### 功能描述 + +syscontainer-tools工具可以对系统容器进行动态添加/删除路由表。 + +### 命令格式 + +```sh +syscontainer-tools [COMMAND][OPTIONS] [ARG...] +``` + +其中: + +COMMAND:路由管理相关的命令。 + +OPTIONS:路由管理命令支持的选项。 + +container\_id:容器id。 + +ARG:命令对应的参数。 + +### 接口说明 + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

功能说明

+

选项说明

+

参数说明

+

add-route

+

将网络路由规则添加到容器中。

+

支持的选项如下:

+

--update-config-only:添加此参数,只更新配置文件,不做实际的更新路由表的动作。

+

参数格式:[{rule1},{rule2}]

+

rule样例:

+

'[{"dest":"default", "gw":"192.168.10.1"},{"dest":"192.168.0.0/16","dev":"eth0","src":"192.168.1.2"}]'

+
  • dest:目标网络,如果为空则是默认网关。
  • src:路由源IP。
  • gw:路由网关。
  • dev:网络设备。
+

remove-route

+

从容器中删除路由。

+

支持的选项如下:

+

--update-config-only:设置此参数,只更新配置文件,不做实际从容器中删除路由的动作。

+

参数格式:[{rule1},{rule2}]

+

rule样例:

+

'[{"dest":"default", "gw":"192.168.10.1"},{"dest":"192.168.0.0/16","dev":"eth0","src":"192.168.1.2"}]'

+
  • dest:目标网络,如果为空则是默认网关。
  • src:路由源IP。
  • gw:路由网关。
  • dev:网络设备。
+

list-route

+

列出容器中所有的路由规则。

+

支持的选项如下:

+
  • --pretty:按照json格式输出。
  • --filter:按照过滤格式输出,比如--filter '{"ip":"192.168.3.4/24", "Mtu":1500}'。
+

+
+ +### 约束限制 + +- 使用syscontainer-tools向容器添加网卡和路由时,建议先执行add-nic添加网卡,然后执行add-route添加路由;使用syscontainer-tools从容器删除网卡和路由时,建议先执行remove-route删除路由,然后执行remove-nic删除网卡。 +- 向容器内添加路由规则时,需确保所添加的路由规则与容器内现有的路由规则不会产生冲突。 + +### 使用示例 + +- 启动一个系统容器,指定hook spec为syscontainer hook执行配置脚本: + + ```sh + [root@localhost ~]# isula run -tid --hook-spec /etc/syscontainer-tools/hookspec.json --system-container --external-rootfs /root/root-fs none init + 0d2d68b45aa0c1b8eaf890c06ab2d008eb8c5d91e78b1f8fe4d37b86fd2c190b + ``` + +- syscontainer-tools向系统容器添加一块物理网卡: + + ```sh + [root@localhost ~]# syscontainer-tools add-nic --type "eth" --name enp4s0:eth123 --ip 172.17.28.6/24 --mtu 1300 --qlen 2100 0d2d68b45aa0 + Add network interface (enp4s0) to container (0d2d68b45aa0,eth123) done + ``` + +- syscontainer-tools添加一条路由规则到系统容器,注意格式需按照'\[\{"dest":"default", "gw":"192.168.10.1"\},\{"dest":"192.168.0.0/16","dev":"eth0","src":"192.168.1.2"\}\]'来配置。如果dest为空会自动填成default。 + + ```sh + [root@localhost ~]# syscontainer-tools add-route 0d2d68b45aa0 '[{"dest":"172.17.28.0/32", "gw":"172.17.28.5","dev":"eth123"}]' + Add route to container 0d2d68b45aa0, route: {dest:172.17.28.0/32,src:,gw:172.17.28.5,dev:eth123} done + ``` + +- 查看容器内是否新增一条路由规则: + + ```sh + [root@localhost ~]# isula exec -it 0d2d68b45aa0 route + Kernel IP routing table + Destination Gateway Genmask Flags Metric Ref Use Iface + 172.17.28.0 172.17.28.5 255.255.255.255 UGH 0 0 0 eth123 + 172.17.28.0 0.0.0.0 255.255.255.0 U 0 0 0 eth123 + ``` + +## 挂卷管理 + +### 功能描述 + +普通容器仅支持在创建时指定--volume参数将宿主机的目录/卷挂载到容器实现资源共享,但是无法在容器运行时将挂载到容器中的目录/卷卸载掉,也不支持将宿主机的目录/卷挂载到容器。系统容器可以通过syscontainer-tools工具实现动态将宿主机的目录/卷挂载到容器,以及将容器中的目录/卷进行卸载。 + +### 命令格式 + +```sh +syscontainer-tools [COMMAND][OPTIONS] [ARG...] +``` + +其中: + +COMMAND:路由管理相关的命令。 + +OPTIONS:路由管理命令支持的选项。 + +container\_id:容器id。 + +ARG:命令对应的参数。 + +### 接口说明 + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

功能说明

+

选项说明

+

参数说明

+

add-path

+

将宿主机文件/目录添加到容器中。

+

+

参数格式为:

+

hostpath:containerpath:permission [hostpath:containerpath:permission ...]

+

其中:

+

hostdevice:卷在主机上的路径。

+

containerdevice:卷在容器中的路径。

+

permission:容器内对挂载路径的操作权限。

+

remove-path

+

将容器中的目录/文件删除,还原到宿主机中。

+

+

参数格式为:hostpath:containerpath [hostpath:containerpath ...]

+

其中:

+

hostdevice:卷在主机上的路径。

+

containerdevice:卷在容器中的路径。

+

list-path

+

列出容器中所有的path目录。

+

支持的选项如下:

+

--pretty:按照json格式输出。

+

+
+ +### 约束限制 + +- 挂载目录(add-path)的时候必须要指定绝对路径。 +- 挂载目录(add-path)会在主机上生成/.sharedpath挂载点。 +- 最多可以向单个容器中添加128个volume,超过128后无法添加成功。 +- add-path不能将主机目录覆盖容器中的根目录(/),否则会造成功能影响。 + +### 使用示例 + +- 启动一个系统容器,指定hook spec为syscontainer hook执行配置脚本: + + ```sh + [root@localhost ~]# isula run -tid --hook-spec /etc/syscontainer-tools/hookspec.json --system-container --external-rootfs /root/root-fs none init + e45970a522d1ea0e9cfe382c2b868d92e7b6a55be1dd239947dda1ee55f3c7f7 + ``` + +- syscontainer-tools将宿主机某个目录挂载到容器,实现资源共享: + + ```sh + [root@localhost ~]# syscontainer-tools add-path e45970a522d1 /home/test123:/home/test123 + Add path (/home/test123) to container(e45970a522d1,/home/test123) done. + ``` + +- 宿主机目录/home/test123创建一个文件,然后在容器内查看文件是否可以访问: + + ```sh + [root@localhost ~]# echo "hello world" > /home/test123/helloworld + [root@localhost ~]# isula exec e45970a522d1 bash + [root@localhost /]# cat /home/test123/helloworld + hello world + ``` + +- syscontainer-tools将挂载目录从容器内删除: + + ```sh + [root@localhost ~]# syscontainer-tools remove-path e45970a522d1 /home/test123:/home/test123 + Remove path (/home/test123) from container(e45970a522d1,/home/test123) done + [root@localhost ~]# isula exec e45970a522d1 bash + [root@localhost /]# ls /home/test123/helloworld + ls: cannot access '/home/test123/helloworld': No such file or directory + ``` diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/environment-variable-persisting.md b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/environment-variable-persisting.md new file mode 100644 index 0000000000000000000000000000000000000000..75a6507e207703a4aa371a9a2aa3fe8e3e273a28 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/environment-variable-persisting.md @@ -0,0 +1,47 @@ +# 环境变量持久化 + +## 功能描述 + +系统容器支持通过指定--env-target-file接口参数将env变量持久化到容器rootfs目录下的配置文件中。 + +## 参数说明 + + + + + + + + + + + + +

命令

+

参数

+

参数指定值说明

+

isula create/run

+

--env-target-file

+
  • 字符串变量。
  • env持久化文件必须在rootfs目录下,且配置为绝对路径。
+
+ +## 约束限制 + +- --env-target-file指定的目标文件如果存在的话,大小不能超过10MB。 +- --env-target-file指定的参数为rootfs目录下的绝对路径。 +- 如果--env和目标文件里面的env出现冲突,以--env指定值的参数为准。 + +## 使用示例 + +启动系统容器,指定env环境变量和--env-target-file参数: + +```bash +[root@localhost ~]# isula run -tid -e abc=123 --env-target-file /etc/environment --system-container --external-rootfs /root/myrootfs none init +b75df997a64da74518deb9a01d345e8df13eca6bcc36d6fe40c3e90ea1ee088e +[root@localhost ~]# isula exec b7 cat /etc/environment +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +TERM=xterm +abc=123 +``` + +可以看到容器的env变量(abc=123)已经持久化到/etc/environment配置文件中。 diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/installation-guideline.md b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/installation-guideline.md new file mode 100644 index 0000000000000000000000000000000000000000..ce8d5e3a0ea7314d308bceeb1c729e77826a4f3d --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/installation-guideline.md @@ -0,0 +1,30 @@ +# 安装指导 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 系统容器的安装需要使用root权限。 + +1. 首先需要安装iSulad容器引擎。 + + ```bash + # yum install iSulad + ``` + +2. 安装系统容器依赖包。 + + ```bash + # yum install syscontainer-tools authz lxcfs-tools lxcfs + ``` + +3. 查看iSulad是否已经启动。 + + ```bash + # systemctl status isulad + ``` + +4. 开启lxcfs和authz服务。 + + ```bash + # systemctl start lxcfs + # systemctl start authz + ``` diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/maximum-number-of-handles.md b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/maximum-number-of-handles.md new file mode 100644 index 0000000000000000000000000000000000000000..227197b882c82a41348c1b08d5c47a9595c89b78 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/maximum-number-of-handles.md @@ -0,0 +1,55 @@ +# 最大句柄数限制 + +## 功能描述 + +系统容器支持对容器内使用文件句柄数进行限制,文件句柄包括普通文件句柄和网络套接字,启动容器时,可以通过指定--files-limit参数限制容器内打开的最大句柄数。 + +## 参数说明 + + + + + + + + + + + + +

命令

+

参数

+

参数指定值说明

+

isula create/run

+

--files-limit

+

  

+
  • 整数值,不能为负数。
  • 指定为0表示不受限制,最大值限制由当前内核files cgroup决定。
+
+ +## 约束限制 + +- 如果\--files-limit指定的值太小,可能会导致系统容器无法通过exec执行命令,报"open too many files"错误,所以files limit的值应该设置大一些。 +- 文件句柄包括普通文件句柄和网络套接字。 + +## 使用示例 + +使用\--files-limit限制容器内打开文件句柄数需要内核支持files cgroup,可以执行以下命令查看: + +```bash +[root@localhost ~]# cat /proc/1/cgroup | grep files +10:files:/ +``` + +结果显示files,说明内核支持files cgroup。 + +容器启动指定--files-limit参数,并检查files.limit参数是否成功写入: + +```bash +[root@localhost ~]# isula run -tid --files-limit 1024 --system-container --external-rootfs /tmp/root-fs empty init 01e82fcf97d4937aa1d96eb8067f9f23e4707b92de152328c3fc0ecb5f64e91d +[root@localhost ~]# isula exec -it 01e82fcf97d4 bash +[root@localhost ~]# cat /sys/fs/cgroup/files/files.limit +1024 + +``` + +可以看出,容器内文件句柄数被成功限制。 diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/overview.md b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..c1126a1c3c3cd3900ff1452ac9a973f013d25732 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/overview.md @@ -0,0 +1,3 @@ +# 系统容器 + +系统容器主要应对在重计算、高性能、大并发的场景下,重型应用和业务云化的问题。相比较虚拟机技术,系统容器可直接继承物理机特性,同时具备性能更优良,较少overhead的优点。从系统资源分配来看,系统容器在有限资源上相比虚拟机可分配更多计算单元,降低成本,通过系统容器可以构建产品的差异化竞争力,提供计算密度更高,价格更便宜,性能更优良的计算单元实例。 diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-caution.gif b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-caution.gif differ diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-danger.gif b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-danger.gif differ diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-note.gif b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-notice.gif b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-notice.gif differ diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-tip.gif b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-tip.gif differ diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-warning.gif b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/public_sys-resources/icon-warning.gif differ diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/reboot-or-shutdown-in-a-container.md b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/reboot-or-shutdown-in-a-container.md new file mode 100644 index 0000000000000000000000000000000000000000..37fb5386d605a45be16d467873ca8ad73881418c --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/reboot-or-shutdown-in-a-container.md @@ -0,0 +1,76 @@ +# 容器内reboot/shutdown + +## 功能描述 + +系统容器支持在容器内执行reboot和shutdown命令。执行reboot命令效果同重启容器一致;执行shutdown命令效果同停止容器一致。 + +## 参数说明 + + + + + + + + + + + + +

命令

+

参数

+

参数指定值说明

+

isula create/run

+

--restart

+
  • 字符串变量。
  • 可取指定值:

    on-reboot:表示重启系统容器。

    +

      

    +
+
+ +## 约束限制 + +- shutdown功能,依赖于不同的OS,以实际容器运行环境对应OS为准。 +- 执行“shutdown -h now”命令关闭系统时,不能多次占用console。例如“isula run -ti”命令打开一个console,在另一个host bash中isula attach该容器,会打开另一个console,此时执行shutdown会失败。 + +## 使用示例 + +- 容器启动时指定\--restart on-reboot参数,示例如下: + + ```bash + [root@localhost ~]# isula run -tid --restart on-reboot --system-container --external-rootfs /root/myrootfs none init + 106faae22a926e22c828a0f2b63cf5c46e5d5986ea8a5b26de81390d0ed9714f + ``` + +- 进入容器执行reboot命令: + + ```bash + [root@localhost ~]# isula exec -it 10 bash + [root@localhost /]# reboot + ``` + + 查看容器是否重启: + + ```bash + [root@localhost ~]# isula exec -it 10 ps aux + USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND + root 1 0.1 0.0 21588 9504 ? Ss 12:11 0:00 init + root 14 0.1 0.0 27024 9376 ? Ss 12:11 0:00 /usr/lib/system + root 17 0.0 0.0 18700 5876 ? Ss 12:11 0:00 /usr/lib/system + dbus 22 0.0 0.0 9048 3624 ? Ss 12:11 0:00 /usr/bin/dbus-d + root 26 0.0 0.0 8092 3012 ? Rs+ 12:13 0:00 ps aux + ``` + +- 进入容器执行shutdown命令: + + ```bash + [root@localhost ~]# isula exec -it 10 bash + [root@localhost /]# shutdown -h now + [root@localhost /]# [root@localhost ~]# + ``` + + 检查容器是否停止: + + ```bash + [root@localhost ~]# isula exec -it 10 bash + Error response from daemon: Exec container error;Container is not running:106faae22a926e22c828a0f2b63cf5c46e5d5986ea8a5b26de81390d0ed9714f + ``` diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/security-and-isolation.md b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/security-and-isolation.md new file mode 100644 index 0000000000000000000000000000000000000000..6344bfa3550485e9c1d852c2f02cdc8579c26df7 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/security-and-isolation.md @@ -0,0 +1,344 @@ +# 安全性和隔离性 + +- [安全性和隔离性](#安全性和隔离性) + - [user namespace多对多](#user-namespace多对多) + - [用户权限控制](#用户权限控制) + - [proc文件系统隔离](#proc文件系统隔离) + +## user-namespace多对多 + +### 功能描述 + +user namespace是将容器的root映射到主机的普通用户,使得容器中的进程和用户在容器里有特权,但是在主机上就是普通权限,防止容器中的进程逃逸到主机上,进行非法操作。更进一步,使用user namespace技术后,容器和主机使用不同的uid和gid,保证容器内部的用户资源和主机资源进行隔离,例如文件描述符等。 + +系统容器支持通过--user-remap接口参数将不同容器的user namespace映射到宿主机不同的user namespace,实现容器user namespace隔离。 + +### 参数说明 + + + + + + + + + + + + +

命令

+

参数

+

参数指定值说明

+

isula create/run

+

--user-remap

+

参数格式为<uid>:<gid>:<offset>,参数说明如下:

+
  • uid、gid为整数型,且必须大于等于0。
  • offset为整数型,且必须大于0,并且小于65536。取值不能太小,否则容器无法启动。
  • uid加上offset的值必须小于等于232-1,gid加上offset的值必须小于等于232-1,否则容器启动会报错。
+
+ +### 约束限制 + +- 如果系统容器指定了--user-remap,那么rootfs目录必须能够被--user-remap指定的uid/gid用户所访问,否则会导致容器user namespace无法访问rootfs,容器启动失败。 +- 容器内所有的id都应该能映射到主机rootfs,某些目录/文件可能是从主机mount到容器,比如/dev/pts目录下面的设备文件,如果offset值太小可能会导致mount失败。 +- uid、gid和offset的值由上层调度平台控制,容器引擎只做合法性检查。 +- --user-remap只适用于系统容器。 +- --user-remap和--privileged不能共存,否则容器启动会报错。 +- 如果uid或gid指定为0,则--user-remap参数不生效。 +- 如果系统容器指定了--user-remap,用户需保证--user-remap指定的uid/gid用户能访问isulad元数据目录(/var/lib/isulad/、/var/lib/isulad/engines/、/var/lib/isulad/engines/lcr)。 +- --user-remap与--userns不能同时使用。 + +### 使用指导 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 指定--user-remap参数前,请先将rootfs下所有目录和文件的uid和gid做整体偏移,偏移量为--user-remap指定uid和gid的偏移量。 +> 例如将dev目录的uid和gid整体uid和gid偏移100000的参考命令为: +> chown 100000:100000 dev + +系统容器启动指定--user-remap参数: + +```bash +[root@localhost ~]# chmod 751 /var/lib/isulad/ +[root@localhost ~]# chmod 751 /var/lib/isulad/engines/ +[root@localhost ~]# chmod 751 /var/lib/isulad/engines/lcr +[root@localhost ~]# isula run -tid --user-remap 100000:100000:65535 --system-container --external-rootfs /home/root-fs none /sbin/init +eb9605b3b56dfae9e0b696a729d5e1805af900af6ce24428fde63f3b0a443f4a +``` + +分别在宿主机和容器内查看/sbin/init进程信息: + +```bash +[root@localhost ~]# isula exec eb ps aux | grep /sbin/init +root 1 0.6 0.0 21624 9624 ? Ss 15:47 0:00 /sbin/init +[root@localhost ~]# ps aux | grep /sbin/init +100000 4861 0.5 0.0 21624 9624 ? Ss 15:47 0:00 /sbin/init +root 4948 0.0 0.0 213032 808 pts/0 S+ 15:48 0:00 grep --color=auto /sbin/init +``` + +可以看到/sbin/init进程在容器内的owner是root用户,但是在宿主机的owner是uid=100000这个用户。 + +在容器内创建一个文件,然后在宿主机上查看文件的owner: + +```bash +[root@localhost ~]# isula exec -it eb bash +[root@localhost /]# echo test123 >> /test123 +[root@localhost /]# exit +exit +[root@localhost ~]# ll /home/root-fs/test123 +-rw-------. 1 100000 100000 8 Aug 2 15:52 /home/root-fs/test123 +``` + +可以看到,在容器内生成了一个文件,它的owner是root,但是在宿主机上看到的owner是id=100000这个用户。 + +## 用户权限控制 + +### 功能描述 + +容器引擎支持通过TLS认证方式来认证用户的身份,并依此控制用户的权限,当前容器引擎可以对接authz插件实现权限控制。 + +### 接口说明 + +通过配置iSulad容器引擎启动参数来指定权限控制插件,daemon配置文件默认为/etc/isulad/daemon.json。 + + + + + + + + + + + + +

配置参数

+

示例

+

说明

+

--authorization-plugin

+

"authorization-plugin": "authz-broker"

+

用户权限认证插件,当前只支持authz-broker。

+
+ +### 约束限制 + +- authz需要配置用户权限策略,策略文件默认为/var/lib/authz-broker/policy.json,该配置文件支持动态修改,修改完即时生效,不需要重启插件服务。 +- 由于容器引擎为root用户启动,放开一般用户使用的一些命令可能会导致该用户不当获得过大权限,需谨慎配置。目前container\_attach、container\_create和container\_exec\_create动作可能会有风险。 +- 对于某些复合操作,比如isula exec、isula attach等命令依赖isula inspect是否有权限,如果用户没有inspect权限会直接报错。 +- 采用SSL/TLS 加密通道在增加安全性的同时也会带来性能损耗,如增加延时,消耗较多的CPU资源,除了数据传输外,加解密需要更大吞吐量,因此在并发场景下,相比非TLS通信,其并发量有一定程度上的下降。经实测,在ARM服务器(Cortex-A72 64核)接近空载情况下,采用TLS并发起容器,其最大并发量在200\~250范围内。 +- 服务端指定--tlsverify时,认证文件默认配置路径为/etc/isulad。且默认文件名分别为ca.pem、cert.pem、key.pem。 + +### 使用示例 + +1. 确认宿主机安装了authz插件,如果需要安装,安装并启动authz插件服务命令如下: + + ```bash + [root@localhost ~]# yum install authz + [root@localhost ~]# systemctl start authz + ``` + +2. 要启动该功能,首先需要配置容器引擎和用户的TLS证书。可以使用OPENSSL来生成需要的证书,具体步骤如下: + + ```bash + #SERVERSIDE + + # Generate CA key + openssl genrsa -aes256 -passout "pass:$PASSWORD" -out "ca-key.pem" 4096 + # Generate CA + openssl req -new -x509 -days $VALIDITY -key "ca-key.pem" -sha256 -out "ca.pem" -passin "pass:$PASSWORD" -subj "/C=$COUNTRY/ST=$STATE/L=$CITY/O=$ORGANIZATION/OU=$ORGANIZATIONAL_UNIT/CN=$COMMON_NAME/emailAddress=$EMAIL" + # Generate Server key + openssl genrsa -out "server-key.pem" 4096 + + # Generate Server Certs. + openssl req -subj "/CN=$COMMON_NAME" -sha256 -new -key "server-key.pem" -out server.csr + + echo "subjectAltName = DNS:localhost,IP:127.0.0.1" > extfile.cnf + echo "extendedKeyUsage = serverAuth" >> extfile.cnf + + openssl x509 -req -days $VALIDITY -sha256 -in server.csr -passin "pass:$PASSWORD" -CA "ca.pem" -CAkey "ca-key.pem" -CAcreateserial -out "server-cert.pem" -extfile extfile.cnf + + #CLIENTSIDE + + openssl genrsa -out "key.pem" 4096 + openssl req -subj "/CN=$CLIENT_NAME" -new -key "key.pem" -out client.csr + echo "extendedKeyUsage = clientAuth" > extfile.cnf + openssl x509 -req -days $VALIDITY -sha256 -in client.csr -passin "pass:$PASSWORD" -CA "ca.pem" -CAkey "ca-key.pem" -CAcreateserial -out "cert.pem" -extfile extfile.cnf + ``` + + 若要直接使用以上过程作为脚本,需替换各变量为配置数值。生成CA时使用的参数若为空则写为“''”。PASSWORD、COMMON\_NAME、CLIENT\_NAME、VALIDITY为必选项。 + +3. 容器引擎启动时添加TLS相关参数和认证插件相关参数,并保证认证插件的运行。此外,为了使用TLS认证,容器引擎必须使用TCP侦听的方式启动,不能使用传统的unix socket的方式启动。容器daemon端配置如下: + + ```conf + { + "tls": true, + "tls-verify": true, + "tls-config": { + "CAFile": "/root/.iSulad/ca.pem", + "CertFile": "/root/.iSulad/server-cert.pem", + "KeyFile":"/root/.iSulad/server-key.pem" + }, + "authorization-plugin": "authz-broker" + } + ``` + +4. 然后需要配置策略,对于基本授权流程,所有策略都位于一个配置文件下/var/lib/authz-broker/policy.json。该配置文件支持动态修改,更改时不需要重新启动插件,只需要向authz进程发送SIGHUP信号。文件格式是每行一个策略JSON对象。每行只有一个匹配。具体的策略配置示例如下: + + - 所有用户都可以运行所有iSulad命令:\{"name":"policy\_0","users":\[""\],"actions":\[""\]\}。 + - Alice可以运行所有iSulad命令:\{"name":"policy\_1","users":\["alice"\],"actions":\[""\]\}。 + - 空用户都可以运行所有iSulad命令: \{"name":"policy\_2","users":\[""\],"actions":\[""\]\}。 + - Alice和Bob可以创建新的容器:\{"name":"policy\_3","users":\["alice","bob"\],"actions":\["container\_create"\]\}。 + - service\_account可以读取日志并运行docker top:\{"name":"policy\_4","users":\["service\_account"\],"actions":\["container\_logs","container\_top"\]\}。 + - Alice可以执行任何container操作:\{"name":"policy\_5","users":\["alice"\],"actions":\["container"\]\}。 + - Alice可以执行任何container操作,但请求的种类只能是get:\{"name":"policy\_5","users":\["alice"\],"actions":\["container"\], "readonly":true \}。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > + > - 配置中匹配action支持正则表达式。 + > - users不支持正则表达式。 + > - users不能有重复用户,即同一用户不能被多条规则匹配。 + +5. 配置并更新完之后,客户端配置TLS参数连接容器引擎,即是以受限的权限访问。 + + ```bash + [root@localhost ~]# isula version --tlsverify --tlscacert=/root/.iSulad/ca.pem --tlscert=/root/.iSulad/cert.pem --tlskey=/root/.iSulad/key.pem -H=tcp://127.0.0.1:2375 + ``` + + 如果想默认配置TLS认证进行客户端连接,可以将文件移动到\~/.iSulad,并设置 ISULAD\_HOST和ISULAD\_TLS\_VERIFY变量(而不是每次调用时传递 -H=tcp://$HOST:2375和--tlsverify)。 + + ```bash + [root@localhost ~]# mkdir -pv ~/.iSulad + [root@localhost ~]# cp -v {ca,cert,key}.pem ~/.iSulad + [root@localhost ~]# export ISULAD_HOST=localhost:2375 ISULAD_TLS_VERIFY=1 + [root@localhost ~]# isula version + ``` + +## proc文件系统隔离 + +### 场景描述 + +容器虚拟化带来轻量高效,快速部署的同时,也因其隔离性不够彻底,给用户带来一定程度的使用不便。由于Linux内核namespace本身还不够完善,因此容器在隔离性方面也存在一些缺陷。例如,在容器内部proc文件系统中可以看到宿主机上的proc信息(如meminfo, cpuinfo,stat, uptime等)。利用lxcfs工具可以将容器内的看到宿主机/proc文件系统的内容,替换成本容器实例的相关/proc内容,以便容器内业务获取正确的资源数值。 + +### 接口说明 + +系统容器对外提供两个工具包:一个是lxcfs软件,另外一个是配合lxcfs一起使用的lxcfs-tools工具。其中lxcfs作为宿主机daemon进程常驻,lxcfs-tools通过hook机制将宿主机的lxcfs文件系统绑定挂载到容器。 + +lxcfs-tools命令行格式如下: + +```bash +lxcfs-tools [OPTIONS] COMMAND [COMMAND_OPTIONS] +``` + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

功能说明

+

参数

+

remount

+

将lxcfs重新mount到容器中

+

--all:对所有的容器执行remout lxcfs操作

+

--container-id:remount lxcfs到特定的容器ID

+

umount

+

将lxcfs从容器中umount掉

+

--all:对所有的容器执行umout lxcfs操作

+

--container-id:对特定容器执行umount lxcfs操作

+

check-lxcfs

+

检查lxcfs服务是否运行

+

+

prestart

+

在lxcfs服务启动前将/var/lib/lxcfs目录mount到容器中

+

+
+ +### 约束限制 + +- 当前只支持proc文件系统下的cpuinfo, meminfo, stat, diskstats, partitions,swaps和uptime文件,其他的文件和其他内核API文件系统(比如sysfs)未做隔离 。 +- 安装rpm包后会在/var/lib/isulad/hooks/hookspec.json生成样例json文件,用户如果需要增加日志功能,需要在定制时加入--log配置。 +- diskstats只能显示支持cfq调度的磁盘信息,无法显示分区信息。容器内设备会被显示为/dev目录下的名字。若不存在则为空。此外,容器根目录所在设备会被显示为sda。 +- 挂载lxcfs时必须使用slave参数。若使用shared参数,可能会导致容器内挂载点泄露到主机,影响主机运行 。 +- lxcfs支持服务优雅降级使用,若lxcfs服务crash或者不可用,容器内查看到的cpuinfo, meminfo, stat, diskstats, partitions, swaps和uptime均为host信息,容器其他业务功能不受影响。 +- lxcfs底层依赖fuse内核模块以及libfuse库,因此需要内核支持fuse。 +- lxcfs当前仅支持容器内运行64位的app,如果容器内运行32位的app可能会导致app读取到的cpuinfo信息不符合预期。 +- lxcfs只是对容器cgroup进行资源视图模拟,对于容器内的系统调用(例如sysconf)获取到的仍然是主机的信息,lxcfs无法做到内核隔离。 +- lxcfs使用隔离后的cpuinfo显示的cpu信息具有如下特征: + - processor:从0开始依次递增。 + - physical id:从0开始依次递增。 + - sibliing:固定为1。 + - core id:固定为0。 + - cpu cores:固定为1。 + +### 使用示例 + +1. 首先需要安装lxcfs和lxcfs-tools这两个包,并启动lxcfs服务。 + + ```bash + [root@localhost ~]# yum install lxcfs lxcfs-tools + [root@localhost ~]# systemctl start lxcfs + ``` + +2. 容器启动完成之后查看容器内是否存在lxcfs挂载点。 + + ```bash + [root@localhost ~]# isula run -tid -v /var/lib/lxc:/var/lib/lxc --hook-spec /var/lib/isulad/hooks/hookspec.json --system-container --external-rootfs /home/root-fs none init + a8acea9fea1337d9fd8270f41c1a3de5bceb77966e03751346576716eefa9782 + [root@localhost ~]# isula exec a8 mount | grep lxcfs + lxcfs on /var/lib/lxc/lxcfs type fuse.lxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other) + lxcfs on /proc/cpuinfo type fuse.lxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other) + lxcfs on /proc/diskstats type fuse.lxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other) + lxcfs on /proc/meminfo type fuse.lxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other) + lxcfs on /proc/partitions type fuse.lxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other) + lxcfs on /proc/stat type fuse.lxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other) + lxcfs on /proc/swaps type fuse.lxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other) + lxcfs on /proc/uptime type fuse.lxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other) + ``` + +3. 执行update命令更新容器的cpu和mem资源配置,然后查看容器资源。根据如下回显可知,容器资源视图显示的是容器真实资源数据而不是宿主机的数据。 + + ```bash + [root@localhost ~]# isula update --cpuset-cpus 0-1 --memory 1G a8 + a8 + [root@localhost ~]# isula exec a8 cat /proc/cpuinfo + processor : 0 + BogoMIPS : 100.00 + cpu MHz : 2400.000 + Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid + CPU implementer : 0x41 + CPU architecture: 8 + CPU variant : 0x0 + CPU part : 0xd08 + CPU revision : 2 + + processor : 1 + BogoMIPS : 100.00 + cpu MHz : 2400.000 + Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid + CPU implementer : 0x41 + CPU architecture: 8 + CPU variant : 0x0 + CPU part : 0xd08 + CPU revision : 2 + + [root@localhost ~]# isula exec a8 free -m + total used free shared buff/cache available + Mem: 1024 17 997 7 8 1006 + Swap: 4095 0 4095 + ``` diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/shared-memory-channels.md b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/shared-memory-channels.md new file mode 100644 index 0000000000000000000000000000000000000000..87c11f1f025b1dadce15cc11ac53d92c0a1a65ea --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/shared-memory-channels.md @@ -0,0 +1,56 @@ +# 共享内存通道 + +## 功能描述 + +系统容器提供容器与主机进程通过共享内存进行通信的功能,通过在容器创建时配置\--host-channel参数,可以在容器与主机之间共享同一tmpfs,从而达到主机与容器间通信的功能。 + +## 参数说明 + + + + + + + + + + + + +

命令

+

参数

+

参数指定值说明

+

isula create/run

+

--host-channel

+
  • 字符串变量,格式为:
    <host path>:<container path>:<rw/ro>:<size limit>
    +
  • 参数说明如下:

    <host path>:将在宿主机上挂载tmpfs的路径,必须是绝对路径。

    +

    <container path>:将在容器内挂载tmpfs的路径,必须是绝对路径。

    +

    <rw/ro>:在容器内挂载的文件系统的使用权限,只能配置为rw(可读写)或ro(只读),默认为rw。

    +

    <size limit>:挂载的tmpfs能够使用的最大限制,最小支持1物理页(4KB),最大支持系统总物理内存的1/2 。默认为64MB。

    +
+
+ +## 约束限制 + +- 宿主机上挂载的tmpfs的生命周期为从容器启动到容器删除,容器删除并解除对空间的占用后会移除这片空间。 +- 容器删除时会将宿主机上挂载tmpfs的路径删除,所以不允许使用宿主机上已存在的目录。 +- 为了宿主机上非root用户运行的进程能够与容器内进行通信,宿主机上tmpfs挂载的权限为1777。 + +## 使用示例 + +创建容器时指定\--host-channel参数: + +```bash +[root@localhost ~]# isula run --rm -it --host-channel /testdir:/testdir:rw:32M --system-container --external-rootfs /root/myrootfs none init +root@3b947668eb54:/# dd if=/dev/zero of=/testdir/test.file bs=1024 count=64K +dd: error writing '/testdir/test.file': No space left on device +32769+0 records in +32768+0 records out +33554432 bytes (34 MB, 32 MiB) copied, 0.0766899 s, 438 MB/s +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> - 使用--host-channel大小限制时,若在容器内创建共享文件,则会受到容器内的内存配额限制(在容器内存使用达到极限时可能会产生oom)。 +> - 若用户在主机端创建共享文件,则不受容器内的内存配额限制。 +> - 若用户需要在容器内创建共享文件,且业务为内存密集型,可以通过设置容器内存配额为在原本基础上加上--host-channel配置的大小来消除影响。 diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/specifying-rootfs-to-create-a-container.md b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/specifying-rootfs-to-create-a-container.md new file mode 100644 index 0000000000000000000000000000000000000000..654b784d33d71671828b701afb02517c5cbbef4a --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/specifying-rootfs-to-create-a-container.md @@ -0,0 +1,46 @@ +# 指定rootfs创建容器 + +## 功能描述 + +系统容器不同于普通容器,普通容器需要指定一个容器镜像来启动,而系统容器通过参数 \--external-rootfs 指定一个本地的根文件系统rootfs(Root File System)来启动,rootfs包含了容器运行时依赖的操作系统环境。 + +## 参数说明 + + + + + + + + + + + + +

命令

+

参数

+

参数指定值说明

+

isula create/run

+

--external-rootfs

+
  • 字符串变量。
  • 容器根文件系统对应的绝对路径,即 rootfs 的路径。
+
+ +## 约束限制 + +- 参数--external-rootfs指定的rootfs目录必须为绝对路径,不能为相对路径。 +- 参数--external-rootfs指定的rootfs目录必须为一个完整运行的操作系统环境(包含systemd软件包),否则容器会启动失败。 +- 容器删除时,不会删除--external-rootfs指定的rootfs目录。 +- 不支持在x86环境上运行基于arm rootfs的容器,也不支持在arm环境上运行基于x86 rootfs的容器。 +- 同一份rootfs,不建议启动多个容器实例,即同一份rootfs只供一个生命周期内的容器实例使用。 + +## 使用示例 + +假设本地rootfs的路径为/root/myrootfs,那么启动一个系统容器的命令如下: + +```bash +# isula run -tid --system-container --external-rootfs /root/myrootfs none init +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> rootfs为自定义的文件系统,请用户自行准备。例如容器镜像的tar包解压后,即为一个rootfs。 diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/usage-guide.md b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/usage-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..87f72bab61139ff168295bdfa7dbeb232bd1f0a6 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/usage-guide.md @@ -0,0 +1,21 @@ +# 使用指南 + +系统容器基于iSula容器引擎进行功能增强,提供系统容器相关功能。系统容器提供的容器管理功能和iSula容器引擎保持一致,其命令格式和功能与iSula容器引擎相同。 + +本文档仅描述系统容器提供的增强功能对应的使用方式,其他命令行操作请参考 "iSula容器引擎" 章节。 + +系统容器功能仅涉及isula create/run命令行,后续未特别说明,各功能均使用此命令行。其命令行格式如下所示: + +```sh +# isula create/run [OPTIONS] [COMMAND] [ARG...] +``` + +其中: + +- OPTIONS:命令参数,可以一个或者多个,可选参数请参见 "iSula容器引擎 > 附录 > 命令行参数说明"。 +- COMMAND:系统容器启动后执行的命令。 +- ARG:系统容器启动后执行命令对应的参数。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 系统容器的使用需要root权限。 diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/using-systemd-to-start-a-container.md b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/using-systemd-to-start-a-container.md new file mode 100644 index 0000000000000000000000000000000000000000..1eb74dae831358246d740739a30009b6a5a2620a --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/using-systemd-to-start-a-container.md @@ -0,0 +1,85 @@ +# 通过systemd启动容器 + +## 功能描述 + +系统容器与普通容器最大的差异就在于容器启动的init进程,普通容器无法通过systemd启动系统服务,而系统容器具备这个能力,通过在启动容器时指定\--system-container参数可以使能systemd服务。 + +## 参数说明 + + + + + + + + + + + + +

命令

+

参数

+

参数指定值说明

+

isula create/run

+

--system-container

+
  • 布尔变量,取值为true、false,未指定值时表示true。
  • 指定某个容器类型是否属于系统容器,必须使能。
+
+ +## 约束限制 + +- systemd服务需要调用一些特殊系统调用,包括mount、umount2、unshare、reboot以及name\_to\_handle\_at,所以在不开启特权容器标签的情况下,系统容器打开了调用上述接口的权限。 +- 系统容器都是init启动,init进程不响应表示正常退出的SIGTERM信号,stop默认在10s之后才会强制杀死容器。如果需要快速结束,可以手动指定stop的超时时间。 +- \--system-container必须配合\--external-rootfs参数一起使用。 +- 系统容器内支持运行各类服务,服务的启停通过systemctl来管理,服务之间可能会出现相互依赖关系导致异常情况下某些服务进程出现D/Z状态,使得容器无法正常退出。 +- 系统容器内的某些服务进程可能会影响其他操作结果,例如容器内若运行了NetworkManager服务,可能会影响向容器添加网卡的行为(网卡添加成功然后被NetworkManger停掉),导致不可预期的结果。 +- 系统容器和主机暂时无法实现udev事件隔离,所以fstab配置也暂不支持。 +- systemd服务可能和libcgroup提供的cgconfig服务在功能上出现冲突,建议在容器内去掉libcgroup相关的包或者配置cgconfig服务的Delegate值为no。 + +## 使用示例 + +- 指定\--system-container和\--external-rootfs参数启动系统容器。 + + ```sh + [root@localhost ~]# isula run -tid -n systest01 --system-container --external-rootfs /root/myrootfs none init + ``` + +- 执行以上命令后容器成功运行,通过exec进入容器查看进程信息,可看到systemd服务已启动。 + + ```sh + [root@localhost ~]# isula exec -it systest01 bash + [root@localhost /]# ps -ef + UID PID PPID C STIME TTY TIME CMD + root 1 0 2 06:49 ? 00:00:00 init + root 14 1 2 06:49 ? 00:00:00 /usr/lib/systemd/systemd-journal + root 16 1 0 06:49 ? 00:00:00 /usr/lib/systemd/systemd-network + dbus 23 1 0 06:49 ? 00:00:00 /usr/bin/dbus-daemon --system -- + root 25 0 0 06:49 ? 00:00:00 bash + root 59 25 0 06:49 ? 00:00:00 ps –ef + ``` + +- 容器内执行systemctl命令查看服务状态,可看到服务被systemd管理。 + + ```sh + [root@localhost /]# systemctl status dbus + ● dbus.service - D-Bus System Message Bus + Loaded: loaded (/usr/lib/systemd/system/dbus.service; static; vendor preset: + disabled) + Active: active (running) since Mon 2019-07-22 06:49:38 UTC; 2min 5 + 8s ago + Docs: man:dbus-daemon(1) + Main PID: 23 (dbus-daemon) + CGroup: /system.slice/dbus.service + └─23 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidf + ile --systemd-activation --syslog-only + + Jul 22 06:49:38 localhost systemd[1]: Started D-Bus System Message Bus. + ``` + +- 容器内通过systemctl stop/start服务,可看到服务被systemd管理。 + + ```sh + [root@localhost /]# systemctl stop dbus + Warning: Stopping dbus.service, but it can still be activated by: + dbus.socket + [root@localhost /]# systemctl start dbus + ``` diff --git a/docs/en/25.03/Cloud/ContainerForm/SystemContainer/writable-namespace-kernel-parameters.md b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/writable-namespace-kernel-parameters.md new file mode 100644 index 0000000000000000000000000000000000000000..4997867535adbe8d5f938ad1b46c04310c5ace48 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerForm/SystemContainer/writable-namespace-kernel-parameters.md @@ -0,0 +1,87 @@ +# namespace化内核参数可写 + +## 功能描述 + +对于运行在容器内的业务,如数据库,大数据,包括普通应用,有对部分内核参数进行设置和调整的需求,以满足最佳的业务运行性能和可靠性。内核参数要么不允许修改,要么全部允许修改(特权容器): + +在不允许用户在容器内修改时,只提供了--sysctl外部接口,而且容器内不能灵活修改参数值。 + +在允许用户在容器内修改时,部分内核参数是全局有效的,某个容器修改后,会影响主机上所有的程序,安全性降低。 + +系统容器提供--ns-change-opt参数,可以指定namespace化的内核参数在容器内动态设置,当前仅支持net、ipc。 + +## 参数说明 + + + + + + + + + + + + +

命令

+

参数

+

参数指定值说明

+

isula create/run

+

--ns-change-opt

+
  • 字符串变量。
  • 仅支持配置net、ipc:

    net:支持/proc/sys/net目录下所有namespace化参数。

    +

    ipc:支持的namespace化参数列表如下:

    +

    /proc/sys/kernel/msgmax

    +

    /proc/sys/kernel/msgmnb

    +

    /proc/sys/kernel/msgmni

    +

    /proc/sys/kernel/sem

    +

    /proc/sys/kernel/shmall

    +

    /proc/sys/kernel/shmmax

    +

    /proc/sys/kernel/shmmni

    +

    /proc/sys/kernel/shm_rmid_forced

    +

    /proc/sys/fs/mqueue/msg_default

    +

    /proc/sys/fs/mqueue/msg_max

    +

    /proc/sys/fs/mqueue/msgsize_default

    +

    /proc/sys/fs/mqueue/msgsize_max

    +

    /proc/sys/fs/mqueue/queues_max

    +
  • 支持通知指定多个namespace配置,多个配置间通过逗号隔开,例如:--ns-change-opt=net,ipc。
+
+ +## 约束限制 + +- 如果容器启动同时指定了--privileged(特权容器)和--ns-change-opt,则--ns-change-opt不生效。 + +## 使用示例 + +启动容器, 指定--ns-change-opt=net: + +```bash +[root@localhost ~]# isula run -tid --ns-change-opt net --system-container --external-rootfs /root/myrootfs none init +4bf44a42b4a14fdaf127616c90defa64b4b532b18efd15b62a71cbf99ebc12d2 +[root@localhost ~]# isula exec -it 4b mount | grep /proc/sys +proc on /proc/sys type proc (ro,nosuid,nodev,noexec,relatime) +proc on /proc/sysrq-trigger type proc (ro,nosuid,nodev,noexec,relatime) +proc on /proc/sys/net type proc (rw,nosuid,nodev,noexec,relatime) +``` + +可以看到容器内/proc/sys/net挂载点为rw,说明net相关的namespace化的内核参数具有读写权限。 + +再启动一个容器,指定--ns-change-opt=ipc: + +```bash +[root@localhost ~]# isula run -tid --ns-change-opt ipc --system-container --external-rootfs /root/myrootfs none init +c62e5e5686d390500dab2fa76b6c44f5f8da383a4cbbeac12cfada1b07d6c47f +[root@localhost ~]# isula exec -it c6 mount | grep /proc/sys +proc on /proc/sys type proc (ro,nosuid,nodev,noexec,relatime) +proc on /proc/sysrq-trigger type proc (ro,nosuid,nodev,noexec,relatime) +proc on /proc/sys/kernel/shmmax type proc (rw,nosuid,nodev,noexec,relatime) +proc on /proc/sys/kernel/shmmni type proc (rw,nosuid,nodev,noexec,relatime) +proc on /proc/sys/kernel/shmall type proc (rw,nosuid,nodev,noexec,relatime) +proc on /proc/sys/kernel/shm_rmid_forced type proc (rw,nosuid,nodev,noexec,relatime) +proc on /proc/sys/kernel/msgmax type proc (rw,nosuid,nodev,noexec,relatime) +proc on /proc/sys/kernel/msgmni type proc (rw,nosuid,nodev,noexec,relatime) +proc on /proc/sys/kernel/msgmnb type proc (rw,nosuid,nodev,noexec,relatime) +proc on /proc/sys/kernel/sem type proc (rw,nosuid,nodev,noexec,relatime) +proc on /proc/sys/fs/mqueue type proc (rw,nosuid,nodev,noexec,relatime) +``` + +可以看到容器内ipc相关的内核参数挂载点为rw,说明ipc相关的namespace化的内核参数具有读写权限。 diff --git a/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/_menu.md b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..e7c2af6fcdacc194b76be340372aa6f9305df337 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/_menu.md @@ -0,0 +1,14 @@ +--- +label: 'Kuasar多沙箱容器运行时' +ismanual: 'Y' +description: '一款支持多种类型沙箱统一管理的容器运行时,可同时支持多种业界主流的沙箱隔离技术' +children: + - label: '概述' + href: './overview.md' + - label: '安装与配置' + href: './kuasar-install-config.md' + - label: '使用指南' + href: './kuasar-usage.md' + - label: '附录' + href: './kuasar-appendix.md' +--- \ No newline at end of file diff --git a/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/figures/kuasar_arch.png b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/figures/kuasar_arch.png new file mode 100644 index 0000000000000000000000000000000000000000..73cc7144880271677c1e2e684a3ac7b950e35e6f Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/figures/kuasar_arch.png differ diff --git a/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/kuasar-appendix.md b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/kuasar-appendix.md new file mode 100644 index 0000000000000000000000000000000000000000..7d44dabaab12d58d1354de4fa6b722ed03f97bc7 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/kuasar-appendix.md @@ -0,0 +1,24 @@ +# 附录 + + /var/lib/kuasar/config_stratovirt.toml配置文件字段说明: + +```conf +[sandbox] +log_level :指定kuasar日志级别,默认为info + +[hypervisor] +path :指定stratovirt二进制路径 +machine_type :指定模拟芯片类型,ARM架构为virt,x86架构为q35 +kernel_path :指定guest kernel执行路径 +image_path :指定guest image执行路径 +initrd_path :指定guest initrd执行路径,与image二选一 +kernel_params :指定guest内核运行参数 +vcpus :指定每个沙箱的默认vCPU数量,默认为1 +memory_in_mb :指定每个沙箱的默认内存大小,默认为1024 MiB +block_device_driver :指定块设备驱动 +debug :指定是否开启debug模式 +enable_mem_prealloc :指定是否开启内存预占 + +[hypervisor.virtiofsd_conf] +path :指定vhost_user_fs路径 +``` diff --git a/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/kuasar-install-config.md b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/kuasar-install-config.md new file mode 100644 index 0000000000000000000000000000000000000000..0eecaadf1929acefa46ebc6c9aafa8296212001f --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/kuasar-install-config.md @@ -0,0 +1,126 @@ +# 安装与配置 + +## 安装方法 + +### 前提条件 + +- 为了获取更好的性能体验,kuasar需要运行在裸金属服务器上,**暂不支持kuasar运行在虚拟机内**。 +- kuasar运行依赖以下openEuler组件,请确保环境上已安装所需版本的依赖组件。 + - iSulad(请参考iSula容器引擎的[安装与配置](../../ContainerEngine/iSulaContainerEngine/installation-configuration.md)章节安装iSulad) + - StratoVirt(请参考StratoVirt的[安装](../../../Virtualization/VirtualizationPlatform/StratoVirt/Install_StratoVirt.md)章节安装StratoVirt) + +### 安装操作 + +1. kuasar发布组件集成在kuasar rpm包中,使用yum命令可以直接安装 + + ```sh + $ yum install kuasar + ``` + +2. 安装启动沙箱及容器需要使用的cri命令行工具crictl + + ```sh + # arm环境 + $ wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.25.0/crictl-v1.25.0-linux-arm64.tar.gz + $ tar -zxvf crictl-v1.25.0-linux-arm64.tar.gz -C /usr/local/bin + # x86环境 + $ wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.25.0/crictl-v1.25.0-linux-amd64.tar.gz + $ tar -zxvf crictl-v1.25.0-linux-amd64.tar.gz -C /usr/local/bin + ``` + +3. 安装cri配置网络需要使用的cni插件 + + ```sh + $ mkdir -p /opt/cni/bin && mkdir -p /etc/cni/net.d + + # arm环境 + $ wget https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-arm64-v1.3.0.tgz + $ tar -zxvf cni-plugins-linux-arm64-v1.3.0.tgz -C /opt/cni/bin/ + # x86环境 + $ wget https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-amd64-v1.3.0.tgz + $ tar -zxvf cni-plugins-linux-amd64-v1.3.0.tgz -C /opt/cni/bin/ + ``` + +## 配置方法 + +### iSulad容器引擎的配置 + +修改iSulad容器引擎的配置文件/etc/isulad/daemon.json以支持iSulad容器引擎调用kuasar vmm虚拟机类型的容器运行时,新增如下配置: + +```sh +$ cat /etc/isulad/daemon.json +... + "cri-sandboxers": { + "vmm": { + "name": "vmm", + "address": "/run/vmm-sandboxer.sock" + } + }, + "cri-runtimes": { + "vmm": "io.containerd.vmm.v1" + }, +... +``` + +重新启动iSulad + +```sh +$ systemctl restart isulad +``` + +### crictl的配置 + +修改crictl配置文件/etc/crictl.yaml对接isulad + +```sh +$ cat /etc/crictl.yaml +runtime-endpoint: unix:///var/run/isulad.sock +image-endpoint: unix:///var/run/isulad.sock +timeout: 10 +``` + +### kuasar的配置 + +修改kuasar对接stratovirt配置文件(可使用默认配置,配置文件字段说明详见[附录](./kuasar-appendix.md)) + +```sh +$ cat /var/lib/kuasar/config_stratovirt.toml +[sandbox] +log_level = "info" + +[hypervisor] +path = "/usr/bin/stratovirt" +machine_type = "virt,mem-share=on" +kernel_path = "/var/lib/kuasar/vmlinux.bin" +image_path = "" +initrd_path = "/var/lib/kuasar/kuasar.initrd" +kernel_params = "task.log_level=debug task.sharefs_type=virtiofs" +vcpus = 1 +memory_in_mb = 1024 +block_device_driver = "virtio-blk" +debug = true +enable_mem_prealloc = false + +[hypervisor.virtiofsd_conf] +path = "/usr/bin/vhost_user_fs" +``` + +启动kuasar-vmm服务 + +```sh +$ systemctl start kuasar-vmm +``` + +确认服务已处于running状态 + +```sh +$ systemctl status kuasar-vmm +● kuasar-vmm.service - Kuasar microVM type sandboxer daemon process + Loaded: loaded (/usr/lib/systemd/system/kuasar-vmm.service; disabled; vendor preset: disabled) + Active: active (running) since Sat 2023-08-26 14:57:08 CST; 1h 25min ago + Main PID: 1000445 (vmm-sandboxer) + Tasks: 99 (limit: 814372) + Memory: 226.4M + CGroup: /system.slice/kuasar-vmm.service + └─ 1000445 /usr/local/bin/vmm-sandboxer --listen /run/vmm-sandboxer.sock --dir /run/kuasar-vmm +``` diff --git a/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/kuasar-usage.md b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/kuasar-usage.md new file mode 100644 index 0000000000000000000000000000000000000000..c326b1dc42f1218d8009c7e0ecfd66aa26f09adb --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/kuasar-usage.md @@ -0,0 +1,93 @@ +# 使用指南 + +启动kuasar沙箱的操作步骤如下: + +1. 确保kuasar及其相关组件已经正确安装配置 + +2. 准备业务容器镜像,假设容器镜像为busybox,使用iSula容器引擎下载容器镜像 + + ```sh + $ isula pull busybox + ``` + +3. 准备pod和container的yaml文件,范例如下: + + ```sh + $ cat podsandbox.yaml + metadata: + name: busybox-sandbox + namespace: default + uid: hdishd83djaidwnduwk28bcsc + log_directory: /tmp + linux: + namespaces: + options: {} + + $ cat pod-container.yaml + metadata: + name: busybox + image: + image: docker.io/library/busybox:latest + command: + - top + log_path: busybox.log + ``` + +4. 启动pod + + ```sh + $ crictl runp --runtime=vmm podsandbox.yaml + 5cbcf744949d8500e7159d6bd1e3894211f475549c0be15d9c60d3c502c7ede3 + ``` + + 查看pod列表,pod为Ready状态 + + ```sh + $ crictl pods + POD ID CREATED STATE NAME NAMESPACE ATTEMPT + 5cbcf744949d8 About a minute ago Ready busybox-sandbox default 1 + ``` + +5. 在pod内创建一个业务容器 + + ```sh + $ crictl create 5cbcf744949d8500e7159d6bd1e3894211f475549c0be15d9c60d3c502c7ede3 pod-container.yaml podsandbox.yaml + c11df540f913e57d1e28372334c028fd6550a2ba73208a3991fbcdb421804a50 + ``` + + 查看容器列表,容器为Created状态 + + ```sh + $ crictl ps -a + CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID + c11df540f913e docker.io/library/busybox:latest 15 seconds ago Created busybox 0 5cbcf744949d + ``` + +6. 启动业务容器 + + ```sh + $ crictl start c11df540f913e57d1e28372334c028fd6550a2ba73208a3991fbcdb421804a50 + ``` + + 查看容器列表,容器为running状态 + + ```sh + $ crictl ps + CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID + c11df540f913e docker.io/library/busybox:latest 2 minutes ago Running busybox 0 5cbcf744949d8 + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > + > 以上步骤4、5、6也可以通过`crictl run`命令直接启动一个pod以及对应的业务容器 + > + > ```sh + > $ crictl run -r vmm --no-pull container-config.yaml podsandbox-config.yaml + > ``` + +7. 停止并删除容器以及pod + + ```sh + $ crictl rm -f c11df540f913e + $ crictl rmp -f 5cbcf744949d8 + ``` diff --git a/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/overview.md b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..5f1a13d9685233d55d33f2671379e8226d4a13d3 --- /dev/null +++ b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/overview.md @@ -0,0 +1,13 @@ +# Kuasar多沙箱容器运行时 + +## 概述 + +Kuasar是一款支持多种类型沙箱统一管理的容器运行时,可同时支持业界主流的多种沙箱隔离技术,例如包括基于内核的原生容器沙箱、基于轻量级虚拟化技术的microVM沙箱、基于进程级虚拟化的App Kernel沙箱,以及新兴的WebAssembly沙箱。 +openEuler基于Kuasar统一容器运行时并结合已有openEuler生态中iSulad容器引擎和StratoVirt虚拟化引擎技术,打造面向云原生场景轻量级全栈自研的安全容器,构建极低底噪、极速启动的关键竞争力。 + +**图 1** Kuasar多沙箱容器运行时架构 +![](./figures/kuasar_arch.png) + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> kuasar的安装和使用需要使用root权限。 diff --git a/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-caution.gif b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-caution.gif differ diff --git a/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-danger.gif b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-danger.gif differ diff --git a/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-note.gif b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-notice.gif b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-notice.gif differ diff --git a/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-tip.gif b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-tip.gif differ diff --git a/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-warning.gif b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ContainerRuntime/Kuasar/public_sys-resources/icon-warning.gif differ diff --git a/docs/en/25.03/Cloud/HybridDeployment/oncn-bwm/_menu.md b/docs/en/25.03/Cloud/HybridDeployment/oncn-bwm/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..f51097462a99de75eb50a484ee9f61f23af8b13a --- /dev/null +++ b/docs/en/25.03/Cloud/HybridDeployment/oncn-bwm/_menu.md @@ -0,0 +1,8 @@ +--- +label: 'oncn-bwm用户指南' +ismanual: 'Y' +description: '混合业务场景下的Pod带宽管理方案' +children: + - label: '概述' + href: './overview.md' +--- \ No newline at end of file diff --git a/docs/en/25.03/Cloud/HybridDeployment/oncn-bwm/overview.md b/docs/en/25.03/Cloud/HybridDeployment/oncn-bwm/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..2eaff8cd71456e37eb9acee8d5cad44b72d5d67d --- /dev/null +++ b/docs/en/25.03/Cloud/HybridDeployment/oncn-bwm/overview.md @@ -0,0 +1,237 @@ +# oncn-bwm用户指南 + +## 简介 + +随着云计算、大数据、人工智能、5G、物联网等技术的迅速发展,数据中心的建设越来越重要。然而,数据中心的服务器资源利用率很低,造成了巨大的资源浪费。为了提高服务器资源利用率,oncn-bwm 应运而生。 + +oncn-bwm 是一款适用于在线、离线业务混合部署场景的 Pod 带宽管理工具,它会根据 QoS 分级对节点内的网络资源进行合理调度,保障在线业务服务体验的同时,大幅提升节点整体的网络带宽利用率。 + +oncn-bwm 工具支持如下功能: + +- 使能/去除/查询 Pod 带宽管理 +- 设置 Pod 网络优先级 +- 设置离线业务带宽范围和在线业务水线 +- 内部统计信息查询 + +## 安装 + +安装 oncn-bwm 工具需要操作系统为 openEuler 22.09,在配置了 openEuler yum 源的机器直接使用 yum 命令安装,参考命令如下: + +```shell +# yum install oncn-bwm +``` + +此处介绍如何安装 oncn-bwm 工具。 + +### 环境要求 + +- 操作系统:openEuler 22.09 + +### 安装步骤 + +安装 oncn-bwm 工具的操作步骤如下: + +1. 配置openEuler的yum源,直接使用yum命令安装 + + ```shell + yum install oncn-bwm + ``` + +## 使用方法 + +oncn-bwm 工具提供了 `bwmcli` 命令行工具来使能 Pod 带宽管理或进行相关配置。`bwmcli` 命令的整体格式如下: + +**bwmcli** \< option(s) > + +> 说明: +> +> 使用 `bwmcli` 命令需要 root 权限。 +> +> 仅支持节点上出方向(报文从节点内发往其他节点)的 Pod 带宽管理。 +> +> 已设置 tc qdisc 规则的网卡,不支持使能 Pod 带宽管理。 +> +> 升级 oncn-bwm 包不会影响升级前的使能状态;卸载 oncn-bwm 包会关闭所有网卡的 Pod 带宽管理。 + +### 命令接口 + +#### Pod 带宽管理 + +**命令和功能** + +| 命令格式 | 功能 | +| --------------------------- | ------------------------------------------------------------ | +| **bwmcli –e** \<网卡名称> | 使能指定网卡的 Pod 带宽管理。 | +| **bwmcli -d** \<网卡名称> | 去除指定网卡的 Pod 带宽管理。 | +| **bwmcli -p devs** | 查询节点所有网卡的 Pod 带宽管理。 | + +> 说明: +> +> - 不指定网卡名时,上述命令会对节点上的所有的网卡生效。 +> +> - 执行 `bwmcli` 其他命令前需要开启 Pod 带宽管理。 + +**使用示例** + +- 使能网卡 eth0 和 eth1 的 Pod 带宽管理 + + ```shell + # bwmcli –e eth0 –e eth1 + enable eth0 success + enable eth1 success + ``` + +- 取消网卡 eth0 和 eth1 的 Pod 带宽管理 + + ```shell + # bwmcli –d eth0 –d eth1 + disable eth0 success + disable eth1 success + ``` + +- 查询节点所有网卡的 Pod 带宽管理 + + ```shell + # bwmcli -p devs + eth0 : enabled + eth1 : disabled + eth2 : disabled + docker0 : disabled + lo : disabled + ``` + +#### Pod 网络优先级 + +**命令和功能** + +| 命令格式 | 功能 | +| ------------------------------------------------------------ | ------------------------------------------------------------ | +| **bwmcli –s** *path* \ | 设置 Pod 网络优先级。其中 *path* 为 Pod 对应的 cgroup 路径, *prio* 为优先级。*path* 取相对路径或者绝对路径均可。 *prio* 缺省值为 0,可选值为 0 和 -1,0 标识为在线业务,-1 标识为离线业务。 | +| **bwmcli –p** *path* | 查询 Pod 网络优先级。 | + +> 说明: +> +> 支持在线或离线两种网络优先级,oncn-bwm 工具会按照网络优先级实时控制 Pod 的带宽,具体策略为:对于在线类型的 Pod ,不会限制其带宽;对于离线类型的 Pod ,会将其带宽限制在离线带宽范围内。 + +**使用示例** + +- 设置 cgroup 路径为 /sys/fs/cgroup/net_cls/test_online 的 Pod 的优先级为 0 + + ```shell + # bwmcli -s /sys/fs/cgroup/net_cls/test_online 0 + set prio success + ``` + +- 查询 cgroup 路径为 /sys/fs/cgroup/net_cls/test_online 的 Pod 的优先级 + + ```shell + # bwmcli -p /sys/fs/cgroup/net_cls/test_online + 0 + ``` + +#### 离线业务带宽范围 + +| 命令格式 | 功能 | +| ---------------------------------- | ------------------------------------------------------------ | +| **bwmcli –s bandwidth** `` | 设置一个主机/虚拟机的离线带宽。其中 low 表示最低带宽,high 表示最高带宽,其单位可取值为 kb/mb/gb ,有效范围为 [1mb, 9999gb]。 | +| **bwmcli –p bandwidth** | 查询设置一个主机/虚拟机的离线带宽。 | + +> 说明: +> +> - 一个主机上所有使能 Pod 带宽管理的网卡在实现内部被当成一个整体看待,也就是共享设置的在线业务水线和离线业务带宽范围。 +> +> - 使用 `bwmcli` 设置 Pod 带宽对此节点上所有离线业务生效,所有离线业务的总带宽不能超过离线业务带宽范围。在线业务没有网络带宽限制。 +> +> - 离线业务带宽范围与在线业务水线共同完成离线业务带宽限制,当在线业务带宽低于设置的水线时,离线业务允许使用设置的最高带宽;当在线业务带宽高于设置的水线时,离线业务允许使用设置的最低带宽。 + +**使用示例** + +- 设置离线带宽范围在 30mb 到 100mb + + ```shell + # bwmcli -s bandwidth 30mb,100mb + set bandwidth success + ``` + +- 查询离线带宽范围 + + ```shell + # bwmcli -p bandwidth + bandwidth is 31457280(B),104857600(B) + ``` + +#### 在线业务水线 + +**命令和功能** + +| 命令格式 | 功能 | +| ---------------------------------------------- | ------------------------------------------------------------ | +| **bwmcli –s waterline** \ | 设置一个主机/虚拟机的在线业务水线,其中 *val* 为水线值,单位可取值为 kb/mb/gb ,有效范围为 [20mb, 9999gb]。 | +| **bwmcli –p waterline** | 查询一个主机/虚拟机的在线业务水线。 | + +> 说明: +> +> - 当一个主机上所有在线业务的总带宽高于水线时,会限制离线业务可以使用的带宽,反之当一个主机上所有在线业务的总带宽低于水线时,会提高离线业务可以使用的带宽。 +> - 判断在线业务的总带宽是否超过/低于设置的水线的时机:每 10 ms 判断一次,根据每个 10 ms 内统计的在线带宽是否高于水线来决定对离线业务采用的带宽限制。 + +**使用示例** + +- 设置在线业务水线为 20mb + + ```shell + # bwmcli -s waterline 20mb + set waterline success + ``` + +- 查询在线业务水线 + + ```shell + # bwmcli -p waterline + waterline is 20971520(B) + ``` + +#### 统计信息 + +**命令和功能** + +| 命令格式 | 功能 | +| ------------------- | ------------------ | +| **bwmcli –p stats** | 查询内部统计信息。 | + +> 说明: +> +> - offline_target_bandwidth 表示离线业务目标带宽 +> +> - online_pkts 表示开启 Pod 带宽管理后在线业务总包数 +> +> - offline_pkts 表示开启 Pod 带宽管理后离线业务总包数 +> +> - online_rate 表示当前在线业务速率 +> +> - offline_rate 表示当前离线业务速率 + +**使用示例** + +查询内部统计信息 + +```shell +# bwmcli -p stats +offline_target_bandwidth: 2097152 +online_pkts: 2949775 +offline_pkts: 0 +online_rate: 602 +offline_rate: 0 +``` + +### 典型使用案例 + +完整配置一个节点上的 Pod 带宽管理可以按照如下步骤顺序操作: + +```shell +bwmcli -p devs # 查询系统当前网卡 Pod 带宽管理状态 +bwmcli -e eth0 # 使能 eth0 的网卡 Pod 带宽管理 +bwmcli -s /sys/fs/cgroup/net_cls/online 0 # 设置在线业务 Pod 的网络优先级为 0 +bwmcli -s /sys/fs/cgroup/net_cls/offline -1 # 设置离线业务 Pod 的网络优先级为 -1 +bwmcli -s bandwidth 20mb,1gb # 配置离线业务带宽范围 +bwmcli -s waterline 30mb # 配置在线业务的水线 +``` diff --git a/docs/en/25.03/Cloud/HybridDeployment/rubik/_menu.md b/docs/en/25.03/Cloud/HybridDeployment/rubik/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..4006270bdc442d94bc9fbbd0f3e457fdcd91e62a --- /dev/null +++ b/docs/en/25.03/Cloud/HybridDeployment/rubik/_menu.md @@ -0,0 +1,14 @@ +--- +label: '云原生混合部署rubik用户指南' +ismanual: 'Y' +description: '在业务混合部署的场景下,根据QoS分级,对资源进行合理调度' +children: + - label: '概述' + href: './overview.md' + - label: '安装与部署' + href: './installation-and-deployment.md' + - label: 'http接口文档' + href: './http-apis.md' + - label: '混部隔离示例' + href: './example-of-isolation-for-hybrid-deployed-services.md' +--- \ No newline at end of file diff --git a/docs/en/25.03/Cloud/HybridDeployment/rubik/example-of-isolation-for-hybrid-deployed-services.md b/docs/en/25.03/Cloud/HybridDeployment/rubik/example-of-isolation-for-hybrid-deployed-services.md new file mode 100644 index 0000000000000000000000000000000000000000..d9c1e15876008d3fb7354ff95da35ef12f6b5376 --- /dev/null +++ b/docs/en/25.03/Cloud/HybridDeployment/rubik/example-of-isolation-for-hybrid-deployed-services.md @@ -0,0 +1,233 @@ +# 混部隔离示例 + +## 环境准备 + +查看内核是否支持混部隔离功能 + +```bash +# 查看/boot/config-系统配置是否开启混部隔离功能 +# 若CONFIG_QOS_SCHED=y则说明使能了混部隔离功能,例如: +cat /boot/config-5.10.0-60.18.0.50.oe2203.x86_64 | grep CONFIG_QOS +CONFIG_QOS_SCHED=y +``` + +安装docker容器引擎 + +```bash +yum install -y docker-engine +docker version +# 如下为docker version显示结果 +Client: + Version: 18.09.0 + EulerVersion: 18.09.0.300 + API version: 1.39 + Go version: go1.17.3 + Git commit: aa1eee8 + Built: Wed Mar 30 05:07:38 2022 + OS/Arch: linux/amd64 + Experimental: false + +Server: + Engine: + Version: 18.09.0 + EulerVersion: 18.09.0.300 + API version: 1.39 (minimum version 1.12) + Go version: go1.17.3 + Git commit: aa1eee8 + Built: Tue Mar 22 00:00:00 2022 + OS/Arch: linux/amd64 + Experimental: false +``` + +## 混部业务 + +**在线业务(clickhouse)** + +使用clickhouse-benchmark测试工具进行性能测试,统计出QPS/P50/P90/P99等相关性能指标,用法参考: + +**离线业务(stress)** + +stress是一个CPU密集型测试工具,可以通过指定--cpu参数启动多个并发CPU密集型任务给系统环境加压 + +## 使用说明 + +1)启动一个clickhouse容器(在线业务)。 + +2)进入容器内执行clickhouse-benchmark命令,设置并发线程数为10个、查询10000次、查询总时间30s。 + +3)同时启动一个stress容器(离线业务),并发执行10个CPU密集型任务对环境进行加压。 + +4)clickhouse-benchmark执行完后输出一个性能测试报告。 + +混部隔离测试脚本(**test_demo.sh**)如下: + +```bash +#!/bin/bash + +with_offline=${1:-no_offline} +enable_isolation=${2:-no_isolation} +stress_num=${3:-10} +concurrency=10 +timeout=30 +output=/tmp/result.json +online_container= +offline_container= + +exec_sql="echo \"SELECT * FROM system.numbers LIMIT 10000000 OFFSET 10000000\" | clickhouse-benchmark -i 10000 -c $concurrency -t $timeout" + +function prepare() +{ + echo "Launch clickhouse container." + online_container=$(docker run -itd \ + -v /tmp:/tmp:rw \ + --ulimit nofile=262144:262144 \ + -p 34424:34424 \ + yandex/clickhouse-server) + + sleep 3 + echo "Clickhouse container lauched." +} + +function clickhouse() +{ + echo "Start clickhouse benchmark test." + docker exec $online_container bash -c "$exec_sql --json $output" + echo "Clickhouse benchmark test done." +} + +function stress() +{ + echo "Launch stress container." + offline_container=$(docker run -itd joedval/stress --cpu $stress_num) + echo "Stress container launched." + + if [ $enable_isolation == "enable_isolation" ]; then + echo "Set stress container qos level to -1." + echo -1 > /sys/fs/cgroup/cpu/docker/$offline_container/cpu.qos_level + fi +} + +function benchmark() +{ + if [ $with_offline == "with_offline" ]; then + stress + sleep 3 + fi + clickhouse + echo "Remove test containers." + docker rm -f $online_container + docker rm -f $offline_container + echo "Finish benchmark test for clickhouse(online) and stress(offline) colocation." + echo "===============================clickhouse benchmark==================================================" + cat $output + echo "===============================clickhouse benchmark==================================================" +} + +prepare +benchmark +``` + +## 测试结果 + +单独执行clickhouse在线业务 + +```bash +sh test_demo.sh no_offline no_isolation +``` + +得到在线业务的QoS(QPS/P50/P90/P99等指标)**基线数据**如下: + +```json +{ +"localhost:9000": { +"statistics": { +"QPS": 1.8853412284364512, +...... +}, +"query_time_percentiles": { +...... +"50": 0.484905256, +"60": 0.519641313, +"70": 0.570876148, +"80": 0.632544937, +"90": 0.728295525, +"95": 0.808700418, +"99": 0.873945121, +...... +} +} +} +``` + +启用stress离线业务,未开启混部隔离功能下,执行test_demo.sh测试脚本 + +```bash +# with_offline参数表示启用stress离线业务 +# no_isolation参数表示未开启混部隔离功能 +sh test_demo.sh with_offline no_isolation +``` + +**未开启混部隔离的情况下**,clickhouse业务QoS数据(QPS/P80/P90/P99等指标)如下: + +```json +{ +"localhost:9000": { +"statistics": { +"QPS": 0.9424028693636205, +...... +}, +"query_time_percentiles": { +...... +"50": 0.840476774, +"60": 1.304607373, +"70": 1.393591017, +"80": 1.41277543, +"90": 1.430316688, +"95": 1.457534764, +"99": 1.555646855, +...... +} +} +``` + +启用stress离线业务,开启混部隔离功能下,执行test_demo.sh测试脚本 + +```bash +# with_offline参数表示启用stress离线业务 +# enable_isolation参数表示开启混部隔离功能 +sh test_demo.sh with_offline enable_isolation +``` + +**开启混部隔离功能的情况下**,clickhouse业务QoS数据(QPS/P80/P90/P99等指标)如下: + +```json +{ +"localhost:9000": { +"statistics": { +"QPS": 1.8825798759270718, +...... +}, +"query_time_percentiles": { +...... +"50": 0.485725185, +"60": 0.512629901, +"70": 0.55656488, +"80": 0.636395956, +"90": 0.734695906, +"95": 0.804118275, +"99": 0.887807409, +...... +} +} +} +``` + +从上面的测试结果整理出一个表格如下: + +| 业务部署方式 | QPS | P50 | P90 | P99 | +| -------------------------------------- | ------------- | ------------- | ------------- | ------------- | +| 单独运行clickhouse在线业务(基线) | 1.885 | 0.485 | 0.728 | 0.874 | +| clickhouse+stress(未开启混部隔离功能) | 0.942(-50%) | 0.840(-42%) | 1.430(-49%) | 1.556(-44%) | +| clickhouse+stress(开启混部隔离功能) | 1.883(-0.11%) | 0.486(-0.21%) | 0.735(-0.96%) | 0.888(-1.58%) | + +在未开启混部隔离功能的情况下,在线业务clickhouse的QPS从1.9下降到0.9,同时业务的响应时延(P90)也从0.7s增大到1.4s,在线业务QoS下降了50%左右;而在开启混部隔离功能的情况下,不管是在线业务的QPS还是响应时延(P50/P90/P99)相比于基线值下降不到2%,在线业务QoS基本没有变化。 diff --git a/docs/en/25.03/Cloud/HybridDeployment/rubik/figures/icon-note.gif b/docs/en/25.03/Cloud/HybridDeployment/rubik/figures/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Cloud/HybridDeployment/rubik/figures/icon-note.gif differ diff --git a/docs/en/25.03/Cloud/HybridDeployment/rubik/http-apis.md b/docs/en/25.03/Cloud/HybridDeployment/rubik/http-apis.md new file mode 100644 index 0000000000000000000000000000000000000000..d8ec85832901f95a8426c485f2387fd82a5a78f0 --- /dev/null +++ b/docs/en/25.03/Cloud/HybridDeployment/rubik/http-apis.md @@ -0,0 +1,67 @@ +# http接口 + +## 概述 + +rubik对外开放接口均为http接口,当前包括pod优先级设置/更新接口、rubik探活接口和rubik版本号查询接口。 + +## 接口介绍 + +### 设置、更新Pod优先级接口 + +rubik提供了设置或更新pod优先级的功能,外部可通过调用该接口发送pod相关信息,rubik根据接收到的pod信息对其设置优先级从而达到资源隔离的目的。接口调用格式为: + +```bash +HTTP POST /run/rubik/rubik.sock +{ + "Pods": { + "podaaa": { + "CgroupPath": "kubepods/burstable/podaaa", + "QosLevel": 0 + }, + "podbbb": { + "CgroupPath": "kubepods/burstable/podbbb", + "QosLevel": -1 + } + } +} +``` + +Pods 配置中为需要设置或更新优先级的 Pod 信息,每一个http请求至少需要指定配置1个 pod,每个 pod 必须指定CgroupPath 和 QosLevel,其含义如下: + +| 配置项 | 配置值类型 | 配置取值范围 | 配置含义 | +| ---------- | ---------- | ------------ | ------------------------------------------------------- | +| QosLevel | int | 0、-1 | pod优先级,0表示其为在线业务,-1表示其为离线业务 | +| CgroupPath | string | 相对路径 | 对应Pod的cgroup子路径(即其在cgroup子系统下的相对路径) | + +接口调用示例如下: + +```sh +curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST --data '{"Pods": {"podaaa": {"CgroupPath": "kubepods/burstable/podaaa","QosLevel": 0},"podbbb": {"CgroupPath": "kubepods/burstable/podbbb","QosLevel": -1}}}' --unix-socket /run/rubik/rubik.sock http://localhost/ +``` + +### 探活接口 + +rubik作为HTTP服务,提供探活接口用于帮助判断rubik是否处于运行状态。 + +接口形式:HTTP/GET /ping + +接口调用示例如下: + +```sh +curl -XGET --unix-socket /run/rubik/rubik.sock http://localhost/ping +``` + +若返回ok则代表rubik服务处于运行状态。 + +### 版本信息查询接口 + +rubik支持通过HTTP请求查询当前rubik的版本号。 + +接口形式:HTTP/GET /version + +接口调用示例如下: + +```sh +curl -XGET --unix-socket /run/rubik/rubik.sock http://localhost/version +{"Version":"0.0.1","Release":"1","Commit":"29910e6","BuildTime":"2021-05-12"} +``` diff --git a/docs/en/25.03/Cloud/HybridDeployment/rubik/installation-and-deployment.md b/docs/en/25.03/Cloud/HybridDeployment/rubik/installation-and-deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..5dcc45a391945dc50d3172f9446d6d105cf07fd0 --- /dev/null +++ b/docs/en/25.03/Cloud/HybridDeployment/rubik/installation-and-deployment.md @@ -0,0 +1,198 @@ +# 安装与部署 + +## 概述 + +本章节主要介绍rubik组件的安装以及部署方式。 + +## 软硬件要求 + +### 硬件要求 + +* 当前仅支持 x86、aarch64架构。 +* rubik磁盘使用需求:配额1GB及以上。 +* rubik内存使用需求:配额100MB及以上。 + +### 软件要求 + +* 操作系统:openEuler 22.03-LTS +* 内核:openEuler 22.03-LTS版本内核 + +### 环境准备 + +* 安装 openEuler 系统,安装方法参考《[安装指南](../../../Server/InstallationUpgrade/Installation/installation.md)》。 +* 安装并部署 kubernetes,安装及部署方法参考《Kubernetes 集群部署指南》。 +* 安装docker或isulad容器引擎,若采用isulad容器引擎,需同时安装isula-build容器镜像构建工具。 + +## 安装rubik + +rubik以k8s daemonSet形式部署在k8s的每一个节点上,故需要在每一个节点上使用以下步骤安装rubik rpm包。 + +1. 配置 yum 源:openEuler 22.03-LTS 和 openEuler 22.03-LTS:EPOL(rubik组件当前仅在EPOL源中),参考如下: + + ```conf + # openEuler 22.03-LTS 官方发布源 + name=openEuler22.03 + baseurl=https://repo.openeuler.org/openEuler-22.03-LTS/everything/$basearch/ + enabled=1 + gpgcheck=1 + gpgkey=https://repo.openeuler.org/openEuler-22.03-LTS/everything/$basearch/RPM-GPG-KEY-openEuler + ``` + + ```conf + # openEuler 22.03-LTS:Epol 官方发布源 + name=Epol + baseurl=https://repo.openeuler.org/openEuler-22.03-LTS/EPOL/$basearch/ + enabled=1 + gpgcheck=0 + ``` + +2. 使用root权限安装rubik: + + ```bash + sudo yum install -y rubik + ``` + +> ![](./figures/icon-note.gif)**说明**: +> +> rubik工具相关文件会安装在/var/lib/rubik目录下 + +## 部署rubik + +rubik以容器形式运行在混合部署场景下的k8s集群中,用于对不同优先级业务进行资源隔离和限制,避免离线业务对在线业务产生干扰,在提高资源总体利用率的同时保障在线业务的服务质量。当前rubik支持对CPU、内存资源进行隔离和限制,需配合openEuler 22.03-LTS版本的内核使用。若用户想要开启内存优先级特性(即针对不同优先级业务实现内存资源的分级),需要通过设置/proc/sys/vm/memcg_qos_enable开关,有效值为0和1,其中0为缺省值表示关闭特性,1表示开启特性。 + +```bash +sudo echo 1 > /proc/sys/vm/memcg_qos_enable +``` + +### 部署rubik daemonset + +1. 使用docker或isula-build容器引擎构建rubik镜像,由于rubik以daemonSet形式部署,故每一个节点都需要rubik镜像。用户可以在一个节点构建镜像后使用docker save/load功能将rubik镜像load到k8s的每一个节点,也可以在各节点上都构建一遍rubik镜像。以isula-build为例,参考命令如下: + + ```bash + isula-build ctr-img build -f /var/lib/rubik/Dockerfile --tag rubik:0.1.0 . + ``` + +2. 在k8s master节点,修改`/var/lib/rubik/rubik-daemonset.yaml`文件中的rubik镜像名,与上一步构建出来的镜像名保持一致。 + + ```yaml + ... + containers: + - name: rubik-agent + image: rubik:0.1.0 # 此处镜像名需与上一步构建的rubik镜像名一致 + imagePullPolicy: IfNotPresent + ... + ``` + +3. 在k8s master节点,使用kubectl命令部署rubik daemonset,rubik会自动被部署在k8s的所有节点: + + ```bash + kubectl apply -f /var/lib/rubik/rubik-daemonset.yaml + ``` + +4. 使用`kubectl get pods -A`命令查看rubik是否已部署到集群每一个节点上(rubik-agent数量与节点数量相同且均为Running状态) + + ```bash + [root@localhost rubik]# kubectl get pods -A + NAMESPACE NAME READY STATUS RESTARTS AGE + ... + kube-system rubik-agent-76ft6 1/1 Running 0 4s + ... + ``` + +## 常用配置说明 + +通过以上方式部署的rubik将以默认配置启动,用户可以根据实际需要修改rubik配置,可通过修改rubik-daemonset.yaml文件中的config.json段落内容后重新部署rubik daemonset实现。 + +本章介绍 config.json 的常用配置,以方便用户根据需要进行配置。 + +### 配置项说明 + +```yaml +# 该部分配置内容位于rubik-daemonset.yaml文件中的config.json段落 +{ + "autoConfig": true, + "autoCheck": false, + "logDriver": "stdio", + "logDir": "/var/log/rubik", + "logSize": 1024, + "logLevel": "info", + "cgroupRoot": "/sys/fs/cgroup" +} +``` + +| 配置项 | 配置值类型 | 配置取值范围 | 配置含义 | +| ---------- | ---------- | ------------------ | ------------------------------------------------------------ | +| autoConfig | bool | true、false | true:开启Pod自动感知功能。
false:关闭 Pod 自动感知功能。 | +| autoCheck | bool | true、false | true:开启 Pod 优先级校验功能。
false:关闭 Pod 优先级校验功能。 | +| logDriver | string | stdio、file | stdio:直接向标准输出打印日志,日志收集和转储由调度平台完成。
file:将文件打印到日志目录,路径由logDir指定。 | +| logDir | string | 绝对路径 | 指定日志存放的目录路径。 | +| logSize | int | [10,1048576] | 指定日志存储总大小,单位 MB,若日志总量达到上限则最早的日志会被丢弃。 | +| logLevel | string | error、info、debug | 指定日志级别。 | +| cgroupRoot | string | 绝对路径 | 指定 cgroup 挂载点。 | + +### Pod优先级自动配置 + +若在rubik config中配置autoConfig为true开启了Pod自动感知配置功能,用户仅需在部署业务pod时在yaml中通过annotation指定其优先级,部署后rubik会自动感知当前节点pod的创建与更新,并根据用户配置的优先级设置pod优先级。 + +### 依赖于kubelet的Pod优先级配置 + +由于Pod优先级自动配置依赖于来自api-server pod创建事件的通知,具有一定的延迟性,无法在进程启动之前及时完成Pod优先级的配置,导致业务性能可能存在抖动。用户可以关闭优先级自动配置选项,通过修改kubelet源码,在容器cgroup创建后、容器进程启动前调用rubik http接口配置pod优先级,http接口具体使用方法详见[http接口文档](./http-apis.md) + +### 支持自动校对Pod优先级 + +rubik支持在启动时对当前节点Pod QoS优先级配置进行一致性校对,此处的一致性是指k8s集群中的配置和rubik对pod优先级的配置之间的一致性。该校对功能默认关闭,用户可以通过 autoCheck 选项控制是否开启。若开启该校对功能,启动或者重启 rubik 时,rubik会自动校验并更正当前节点pod优先级配置。 + +## 在离线业务配置示例 + +rubik部署成功后,用户在部署实际业务时,可以根据以下配置示例对业务yaml文件进行修改,指定业务的在离线类型,rubik即可在业务部署后对其优先级进行配置,从而达到资源隔离的目的。 + +以下为部署一个nginx在线业务的示例: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx + namespace: qosexample + annotations: + volcano.sh/preemptable: "false" # volcano.sh/preemptable为true代表业务为离线业务,false代表业务为在线业务,默认为false +spec: + containers: + - name: nginx + image: nginx + resources: + limits: + memory: "200Mi" + cpu: "1" + requests: + memory: "200Mi" + cpu: "1" +``` + +## 约束限制 + +* rubik接受HTTP请求并发量上限1000QPS,并发量超过上限则报错。 + +* rubik接受的单个请求中pod上限为100个,pod数量越界则报错。 + +* 每个k8s节点只能部署一个rubik,多个rubik会冲突。 + +* rubik不提供端口访问,只能通过socket通信。 + +* rubik只接收合法http请求路径及网络协议:](./http-apis.md)。 + +* rubik磁盘使用需求:配额1GB及以上。 + +* rubik内存使用需求:配额100MB及以上。 + +* 禁止将业务从低优先级(离线业务)往高优先级(在线业务)切换。如业务A先被设置为离线业务,接着请求设置为在线业务,rubik报错。 + +* 容器挂载目录时,rubik本地套接字/run/rubik的目录权限需由业务侧保证最小权限700。 + +* rubik服务端可用时,单个请求超时时间为120s。如果rubik进程进入T(暂停状态或跟踪状态)、D状态(不可中断的睡眠状态),则服务端不可用,此时rubik服务不会响应任何请求。为了避免此情况的发生,请在客户端设置超时时间,避免无限等待。 + +* 使用混部后,原始的cgroup cpu share功能存在限制。具体表现为: + + 若当前CPU中同时有在线任务和离线任务运行,则离线任务的CPU share配置无法生效。 + + 若当前CPU中只有在线任务或只有离线任务,CPU share能生效。 diff --git a/docs/en/25.03/Cloud/HybridDeployment/rubik/overview.md b/docs/en/25.03/Cloud/HybridDeployment/rubik/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..c07cf4abfff942d0b036db88692cd3eb640345dc --- /dev/null +++ b/docs/en/25.03/Cloud/HybridDeployment/rubik/overview.md @@ -0,0 +1,17 @@ +# rubik使用指南 + +## 概述 + +服务器资源利用率低一直是业界公认的难题,随着云原生技术的发展,将在线(高优先级)、离线(低优先级)业务混合部署成为了当下提高资源利用率的有效手段。 + +rubik容器调度在业务混合部署的场景下,根据QoS分级,对资源进行合理调度,从而实现在保障在线业务服务质量的前提下,大幅提升资源利用率。 + +rubik当前支持如下特性: + +- pod CPU优先级的配置 +- pod memory优先级的配置 + +本文档适用于使用openEuler系统并希望了解和使用rubik的社区开发者、开源爱好者以及相关合作伙伴。使用人员需要具备以下经验和技能: + +- 熟悉Linux基本操作 +- 熟悉kubernetes和docker/iSulad基本操作 diff --git a/docs/en/25.03/Cloud/ImageBuilder/isula-build/_menu.md b/docs/en/25.03/Cloud/ImageBuilder/isula-build/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..e8c0a785c81f8776b8f184c4b97e7c36fd02d6f6 --- /dev/null +++ b/docs/en/25.03/Cloud/ImageBuilder/isula-build/_menu.md @@ -0,0 +1,14 @@ +--- +label: '容器镜像构建' +ismanual: 'Y' +description: '支持通过Dockerfile文件快速构建容器镜像' +children: + - label: '概述' + href: './overview.md' + - label: '使用指南' + href: './isula-build.md' + - label: '常见问题与解决方法' + href: './isula-build-faqs.md' + - label: '附录' + href: './isula-build-appendix.md' +--- \ No newline at end of file diff --git a/docs/en/25.03/Cloud/ImageBuilder/isula-build/figures/isula-build_arch.png b/docs/en/25.03/Cloud/ImageBuilder/isula-build/figures/isula-build_arch.png new file mode 100644 index 0000000000000000000000000000000000000000..911a9ae6f46988586ab49f15de282948f5470c37 Binary files /dev/null and b/docs/en/25.03/Cloud/ImageBuilder/isula-build/figures/isula-build_arch.png differ diff --git a/docs/en/25.03/Cloud/ImageBuilder/isula-build/isula-build-appendix.md b/docs/en/25.03/Cloud/ImageBuilder/isula-build/isula-build-appendix.md new file mode 100644 index 0000000000000000000000000000000000000000..35b0fbcc9e4ad33ac420f0706a2c35acdaefa780 --- /dev/null +++ b/docs/en/25.03/Cloud/ImageBuilder/isula-build/isula-build-appendix.md @@ -0,0 +1,91 @@ +# 附录 + +## 命令行参数说明 + +**表1** ctr-img build 命令参数列表 + +| **命令** | **参数** | **说明** | +| ------------- | -------------- | ------------------------------------------------------------ | +| ctr-img build | --build-arg | string列表,构建过程中需要用到的变量 | +| | --build-static | KV值,构建二进制一致性。目前包含如下K值:- build-time:string,使用固定时间戳来构建容器镜像;时间戳格式为“YYYY-MM-DD HH-MM-SS” | +| | -f, --filename | string,Dockerfile的路径,不指定则是使用当前路径的Dockerfile文件 | +| | --format | string,设置构建镜像的镜像格式:oci|docker(需开启实验特性选项)| +| | --iidfile | string,输出 image ID 到本地文件 | +| | -o, --output | string,镜像导出的方式和路径 | +| | --proxy | 布尔值,继承主机侧环境的proxy环境变量(默认为true) | +| | --tag | string,给构建的镜像添加tag | +| | --cap-add | string列表,构建过程中RUN指令所需要的权限 | + +**表2** ctr-img load 命令参数列表 + +| **命令** | **参数** | **说明** | +| ------------ | ----------- | --------------------------------- | +| ctr-img load | -i, --input | string,需要导入的本地tar包的路径 | + +**表3** ctr-img push 命令参数列表 + +| **命令** | **参数** | **说明** | +| ------------ | ----------- | --------------------------------- | +| ctr-img push | -f, --format | string,推送的镜像格式:oci|docker(需开启实验特性选项)| + +**表4** ctr-img rm 命令参数列表 + +| **命令** | **参数** | **说明** | +| ---------- | ----------- | --------------------------------------------- | +| ctr-img rm | -a, --all | 布尔值,删除所有本地持久化存储的镜像 | +| | -p, --prune | 布尔值,删除所有没有tag的本地持久化存储的镜像 | + +**表5** ctr-img save 命令参数列表 + +| **命令** | **参数** | **说明** | +| ------------ | ------------ | ---------------------------------- | +| ctr-img save | -o, --output | string,镜像导出后在本地的存储路径 | +| | -f, --format | string,导出层叠镜像的镜像格式:oci|docker(需开启实验特性选项)| + +**表6** login 命令参数列表 + +| **命令** | **参数** | **说明** | +| -------- | -------------------- | ------------------------------------------------------- | +| login | -p, --password-stdin | 布尔值,是否通过stdin读入密码;或采用交互式界面输入密码 | +| | -u, --username | string,登录镜像仓库所使用的用户名 | + +**表7** logout 命令参数列表 + +| **命令** | **参数** | **说明** | +| -------- | --------- | ------------------------------------ | +| logout | -a, --all | 布尔值,是否登出所有已登录的镜像仓库 | + +**表8** manifest annotate命令参数列表 + +| **命令** | **说明** | **参数** | +| ----------------- | ------------- | ------------------------------------------ | +| manifest annotate | --arch | string,重写镜像适用架构 | +| | --os | string,重写镜像适用系统 | +| | --os-features | string列表,指定镜像需要的OS特性,很少使用 | +| | --variant | string,指定列表中记录镜像的变量 | + +## 通信矩阵 + +isula-build两个组件进程之间通过unix socket套接字文件进行通信,无端口通信。 + +## 文件与权限 + +* isula-build 所有的操作均需要使用 root 权限。如需使用非特权用户操作,则需要配置--group参数 + +* isula-build 运行涉及文件权限如下表所示: + +| **文件路径** | **文件/文件夹权限** | **说明** | +| ------------------------------------------- | ------------------- | ------------------------------------------------------------ | +| /usr/bin/isula-build | 550 | 命令行工具二进制文件。 | +| /usr/bin/isula-builder | 550 | 服务端isula-builder进程二进制文件。 | +| /usr/lib/systemd/system/isula-build.service | 640 | systemd配置文件,用于管理isula-build服务。 | +| /etc/isula-build | 650 | isula-builder 配置文件根目录 | +| /etc/isula-build/configuration.toml | 600 | isula-builder 总配置文件,包含设置 isula-builder 日志级别、持久化目录和运行时目录、OCI runtime等。 | +| /etc/isula-build/policy.json | 600 | 签名验证策略文件的语法文件。 | +| /etc/isula-build/registries.toml | 600 | 针对各个镜像仓库的配置文件,含可用的镜像仓库列表、镜像仓库黑名单。 | +| /etc/isula-build/storage.toml | 600 | 本地持久化存储的配置文件,包含所使用的存储驱动的配置。 | +| /etc/isula-build/isula-build.pub | 400 | 非对称加密公钥文件 | +| /var/run/isula_build.sock | 660 | 服务端isula-builder的本地套接字。 | +| /var/lib/isula-build | 700 | 本地持久化目录。 | +| /var/run/isula-build | 700 | 本地运行时目录。 | +| /var/lib/isula-build/tmp/[buildid]/isula-build-tmp-*.tar | 644 | 镜像导出至iSulad时的本地暂存目录。 | diff --git a/docs/en/25.03/Cloud/ImageBuilder/isula-build/isula-build-faqs.md b/docs/en/25.03/Cloud/ImageBuilder/isula-build/isula-build-faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..a9c308f1669737a117553b7d3b8278048c5670d6 --- /dev/null +++ b/docs/en/25.03/Cloud/ImageBuilder/isula-build/isula-build-faqs.md @@ -0,0 +1,7 @@ +# 常见问题与解决方法 + +## **问题1:isula-build拉取镜像报错:pinging container registry xx: get xx: dial tcp host:repo: connect: connection refused** + +原因:拉取的镜像来源于非授信仓库。 + +解决方法:修改isula-build镜像仓库的配置文件/etc/isula-build/registries.toml,将该非授信仓库加入[registries.insecure],重启isula-build。 diff --git a/docs/en/25.03/Cloud/ImageBuilder/isula-build/isula-build.md b/docs/en/25.03/Cloud/ImageBuilder/isula-build/isula-build.md new file mode 100644 index 0000000000000000000000000000000000000000..d4838f986ef64dfbe9277b51d75ee738ea2fa606 --- /dev/null +++ b/docs/en/25.03/Cloud/ImageBuilder/isula-build/isula-build.md @@ -0,0 +1,934 @@ +# 安装 + +## 环境准备 + +为了确保isula-build成功安装,需满足以下软件硬件要求。 + +* 支持的机器架构:x86_64 和 AArch64 +* 支持的操作系统:openEuler +* 用户具有root权限。 + +### 安装isula-build + +使用isula-build构建容器镜像,需要先安装以下软件包。 + +#### (推荐)方法一:使用yum安装 + +1. 配置openEuler yum源。 + +2. 使用root权限,登录目标服务器,安装isula-build。 + + ```sh + sudo yum install -y isula-build + ``` + +#### 方法二:使用rpm包安装 + +1. 从openEuler yum源中获取isula-build对应安装包isula-build-*.rpm。例如isula-build-0.9.6-4.oe1.x86_64.rpm。 + +2. 将获取的rpm软件包上传至目标服务器的任一目录,例如 /home/。 + +3. 使用root权限,登录目标服务器,参考如下命令安装isula-build。 + + ```sh + sudo rpm -ivh /home/isula-build-*.rpm + ``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 安装完成后,需要手工启动isula-build服务。启动请参见[管理服务](isula-build构建工具.md#管理服务)。 + +# 配置与管理服务 + +## 配置服务 + +在安装完 isula-build 软件包之后,systemd 管理服务会以 isula-build 软件包自带的 isula-build 服务端默认配置启动 isula-build 服务。如果 isula-build 服务端的默认配置文件不能满足用户的需求,可以参考如下介绍进行定制化配置。需要注意的是,修改完默认配置之后,需要重启 isula-build 服务端使新配置生效,具体操作可参考下一章节。 + +目前 isula-build 服务端包含如下配置文件: + +* /etc/isula-build/configuration.toml:isula-builder 总体配置文件,用于设置 isula-builder 日志级别、持久化目录和运行时目录、OCI runtime等。其中各参数含义如下: + +| 配置项 | 是否可选 | 配置项含义 | 配置项取值 | +| --------- | -------- | --------------------------------- | ----------------------------------------------- | +| debug | 可选 | 设置是否打开debug日志 | true:打开debug日志
false:关闭debug日志 | +| loglevel | 可选 | 设置日志级别 | debug
info
warn
error | +| run_root | 必选 | 设置运行时数据根目录 | 运行时数据根目录路径,例如/var/run/isula-build/ | +| data_root | 必选 | 设置本地持久化目录 | 本地持久化目录路径,例如/var/lib/isula-build/ | +| runtime | 可选 | 设置runtime种类,目前仅支持runc | runc | +| group | 可选 | 设置本地套接字isula_build.sock文件属组使得加入该组的非特权用户可以操作isula-build | isula | +| experimental | 可选 | 设置是否开启实验特性 | true:开启实验特性;false:关闭实验特性 | + +* /etc/isula-build/storage.toml: 本地持久化存储的配置文件,包含所使用的存储驱动的配置。 + +| 配置项 | 是否可选 | 配置项含义 | +| ------ | -------- | ------------------------------ | +| driver | 可选 | 存储驱动类型,目前支持overlay2 | + + 更多设置可参考 [containers-storage.conf.5](https://github.com/containers/storage/blob/main/docs/containers-storage.conf.5.md)。 + +* /etc/isula-build/registries.toml : 针对各个镜像仓库的配置文件。 + +| 配置项 | 是否可选 | 配置项含义 | +| ------------------- | -------- | ------------------------------------------------------------ | +| registries.search | 可选 | 镜像仓库搜索域,在此list的镜像仓库可以被感知,不在此列的不被感知。 | +| registries.insecure | 可选 | 可访问的不安全镜像仓库地址,在此列表中的镜像仓库将不会通过鉴权,不推荐使用。 | + + 更多设置可参考 [containers-registries.conf.5](https://github.com/containers/image/blob/main/docs/containers-registries.conf.5.md)。 + +* /etc/isula-build/policy.json:镜像pull/push策略文件。当前不支持对其进行配置。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> * isula-build 支持最大 1MiB 的上述配置文件。 +> * isula-build 不支持将持久化工作目录 dataroot 配置在内存盘上,比如 tmpfs。 +> * isula-build 目前仅支持使用overlay2为底层 graphdriver。 +> * 在设置--group参数前,需保证本地OS已经创建了对应的用户组,且非特权用户已经加入该组。重启isula-builder之后即可使该非特权用户使用isula-build功能。同时,为了保持权限一致性,isula-build的配置文件目录/etc/isula-build的属组也会被设置为--group指定的组。 + +## 管理服务 + +目前 openEuler 采用 systemd 管理软件服务,isula-build 软件包已经自带了 systemd 的服务文件,用户安装完 isula-build 软件包之后,可以直接通过 systemd 工具对它进行服务启停等操作。用户同样可以手动启动 isula-build 服务端软件。需要注意的是,同一个节点上不可以同时启动多个 isula-build 服务端软件。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 同一个节点上不可以同时启动多个 isula-build 服务端软件。 + +### 通过 systemd 管理(推荐方式) + +用户可以通过如下 systemd 的标准指令控制 isula-build 服务的启动、停止、重启等动作: + +* 启动 isula-build 服务: + + ```sh + sudo systemctl start isula-build.service + ``` + +* 停止 isula-build 服务: + + ```sh + sudo systemctl stop isula-build.service + ``` + +* 重启 isula-build 服务: + + ```sh + sudo systemctl restart isula-build.service + ``` + +isula-build 软件包安装的 systemd 服务文件保存在 `/usr/lib/systemd/system/isula-build.service`。如果用户需要修改 isula-build 服务的 systemd 配置,可以修改该文件,执行如下命令使配置生效,之后再根据上面提到的 systemd 管理指令重启 isula-build 服务 + +```sh +sudo systemctl daemon-reload +``` + +### 直接运行 isula-build 服务端 + +您也可以通过执行 isula-build 服务端命令( isula-builder)的方式启动服务。其中,服务端启动配置,可通过isula-builder命令支持的 flags 设置。isula-build 服务端目前支持的 flags 如下: + +* -D, --debug: 是否开启调测模式。 +* --log-level: 日志级别,支持 “debug”, “info”, “warn” or “error”,默认为 “info”。 +* --dataroot: 本地持久化路径,默认为”/var/lib/isula-build/“。 +* --runroot: 运行时路径,默认为”/var/run/isula-build/“。 +* --storage-driver:底层存储驱动类型。 +* --storage-opt: 底层存储驱动配置。 +* --group: 设置本地套接字isula_build.sock文件属组使得加入该组的非特权用户可以操作isula-build,默认为“isula”。 +* --experimental: 是否开启实验特性,默认为false。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 当命令行启动参数中传递了与配置文件相同的配置选项时,优先使用命令行参数启动。 + +启动 isula-build 服务。例如指定本地持久化路径/var/lib/isula-build,且不开启调试的参考命令如下: + +```sh +sudo isula-builder --dataroot "/var/lib/isula-build" --debug=false +``` + +# 使用指南 + +## 前提条件 + +isula-build 构建 Dockerfile 内的 RUN 指令时依赖可执行文件 runc ,需要 isula-build 的运行环境上预装好 runc。安装方式视用户使用场景而定,如果用户不需要使用完整的 docker-engine 工具链,则可以仅安装 docker-runc rpm包: + +```sh +sudo yum install -y docker-runc +``` + +如果用户需要使用完整的 docker-engine 工具链,则可以安装 docker-engine rpm包,默认包含可执行文件 runc : + +```sh +sudo yum install -y docker-engine +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 用户需保证OCI runtime(runc)可执行文件的安全性,避免被恶意替换。 + +## 总体说明 + +isula-build 客户端提供了一系列命令用于构建和管理容器镜像,当前 isula-build 包含的命令行指令如下: + +* ctr-img,容器镜像管理。ctr-img又包含如下子命令: + * build,根据给定dockerfile构建出容器镜像。 + * images,列出本地容器镜像。 + * import,导入容器基础镜像。 + * load,导入层叠镜像。 + * rm,删除本地容器镜像。 + * save,导出层叠镜像至本地磁盘。 + * tag,给本地容器镜像打tag。 + * pull,拉取镜像到本地。 + * push,推送本地镜像到远程仓库。 +* info,查看isula-build的运行环境和系统信息。 +* login,登录远端容器镜像仓库。 +* logout,退出远端容器镜像仓库。 +* version,查看isula-build和isula-builder的版本号。 +* manifest(实验特性),管理manifest列表。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> * isula-build completion 和 isula-builder completion 命令用于生成bash命令补全脚本。该命令为命令行框架隐式提供,不会显示在help信息中。 +> * isula-build客户端不包含配置文件,当用户需要使用isula-build实验特性时,需要在客户端通过命令`export ISULABUILD_CLI_EXPERIMENTAL=enabled`配置环境变量ISULABUILD_CLI_EXPERIMENTAL来开启实验特性。 + +以下按照上述维度依次详细介绍这些命令行指令的使用。 + +## ctr-img: 容器镜像管理 + +isula-build 将所有容器镜像管理相关命令划分在子命令 `ctr-img` 下,命令原型为: + +```sh +isula-build ctr-img [command] +``` + +### build: 容器镜像构建 + +ctr-img 的子命令 build 用于构建容器镜像,命令原型为: + +```sh +isula-build ctr-img build [flags] +``` + +其中 build 包含如下 flags: + +* --build-arg:string列表,构建过程中需要用到的变量。 +* --build-static:KeyValue值,构建二进制一致性。目前包含如下Key值: + * build-time:string,使用固定时间戳来构建容器镜像;时间戳格式为“YYYY-MM-DD HH-MM-SS”。 +* -f, --filename:string,Dockerfile的路径,不指定则是使用当前路径的Dockerfile文件。 +* --format: string, 设置构建镜像的镜像格式:oci | docker(需开启实验特性选项)。 +* --iidfile:string,输出 image ID 到本地文件。 +* -o, --output:string,镜像导出的方式和路径。 +* --proxy:布尔值,继承主机侧环境的proxy环境变量(默认为true)。 +* --tag:string,设置构建成功的镜像的tag值。 +* --cap-add:string列表,构建过程中RUN指令所需要的权限。 + +**以下为各个 flags 的详解。** + +**\--build-arg** + +从命令行接受参数作为Dockerfile中的参数,用法: + +```sh +$ echo "This is bar file" > bar.txt +$ cat Dockerfile_arg +FROM busybox +ARG foo +ADD ${foo}.txt . +RUN cat ${foo}.txt +$ sudo isula-build ctr-img build --build-arg foo=bar -f Dockerfile_arg +STEP 1: FROM busybox +Getting image source signatures +Copying blob sha256:8f52abd3da461b2c0c11fda7a1b53413f1a92320eb96525ddf92c0b5cde781ad +Copying config sha256:e4db68de4ff27c2adfea0c54bbb73a61a42f5b667c326de4d7d5b19ab71c6a3b +Writing manifest to image destination +Storing signatures +STEP 2: ARG foo +STEP 3: ADD ${foo}.txt . +STEP 4: RUN cat ${foo}.txt +This is bar file +Getting image source signatures +Copying blob sha256:6194458b07fcf01f1483d96cd6c34302ffff7f382bb151a6d023c4e80ba3050a +Copying blob sha256:6bb56e4a46f563b20542171b998cb4556af4745efc9516820eabee7a08b7b869 +Copying config sha256:39b62a3342eed40b41a1bcd9cd455d77466550dfa0f0109af7a708c3e895f9a2 +Writing manifest to image destination +Storing signatures +Build success with image id: 39b62a3342eed40b41a1bcd9cd455d77466550dfa0f0109af7a708c3e895f9a2 +``` + +**\--build-static** + +指定为静态构建,即使用isula-build构建容器镜像时消除所有时间戳和其他构建因素(例如容器ID、hostname等)的差异。最终构建出满足静态要求的容器镜像。 + +在使用isula-build进行容器镜像构建时,假如给 build 子命令一个固定的时间戳,并在限定如下条件的时候: + +* 构建环境前后保持一致。 +* 构建Dockerfile前后保持一致。 +* 构建产生的中间数据前后保持一致。 +* 构建命令相同。 +* 第三方库版本一致。 + +对于容器镜像构建,isula-build支持相同的Dockerfile。如果构建环境相同,则多次构建生成的镜像内容和镜像ID相同。 + +--build-static接受k=v形式的键值对选项,当前支持的选项有: + +* build-time:字符串类型。构建静态镜像的固定时间戳,格式为“YYYY-MM-DD HH-MM-SS”。时间戳影响diff层创建修改时间的文件属性。 + + 使用示例如下: + + ```sh + sudo isula-build ctr-img build -f Dockerfile --build-static='build-time=2020-05-23 10:55:33' . + ``` + + 以此方式,同一环境多次构建出来的容器镜像和镜像ID均会保持一致。 + +**\--format** +开始实验特性后该选项可用,默认为OCI镜像格式。可以手动指定镜像格式进行构建,例如,下面分别为构建OCI镜像格式以及Docker镜像格式镜像的命令。 + + ```sh + export ISULABUILD_CLI_EXPERIMENTAL=enabled; sudo isula-build ctr-img build -f Dockerfile --format oci . + ``` + + ```sh + export ISULABUILD_CLI_EXPERIMENTAL=enabled; sudo isula-build ctr-img build -f Dockerfile --format docker . + ``` + +**\--iidfile** + +将构建的镜像ID输出到文件,用法: + +```sh +isula-build ctr-img build --iidfile filename +``` + +例如,将容器镜像ID输出到testfile的参考命令如下: + + ```sh +sudo isula-build ctr-img build -f Dockerfile_arg --iidfile testfile + ``` + + 查看testfile中的容器镜像ID: + + ```sh +$ cat testfile +76cbeed38a8e716e22b68988a76410eaf83327963c3b29ff648296d5cd15ce7b + ``` + +**\-o, --output** + +目前 -o, --output 支持如下形式: + +* `isulad:image:tag`:将构建成功的镜像直接推送到 iSulad。比如:`-o isulad:busybox:latest`。同时需要注意如下约束: + + * isula-build 和 iSulad 必须在同一个节点上 + * tag必须配置 + * isula-build client端需要将构建成功的镜像暂存成 `/var/tmp/isula-build-tmp-%v.tar` 再导入至 iSulad,用户需要保证 `/var/tmp/` 目录有足够磁盘空间 + +* `docker-daemon:image:tag`:将构建成功的镜像直接推送到 Docker daemon。比如:`-o docker-daemon:busybox:latest`。同时需要注意如下约束: + * isula-build 和 docker 必须在同一个节点上 + * tag必须配置 + +* `docker://registry.example.com/repository:tag`:将构建成功的镜像以Docker镜像格式直接推送到远端镜像仓库。比如:`-o docker://localhost:5000/library/busybox:latest`。 + +* `docker-archive:/:image:tag`:将构建成功的镜像以Docker镜像格式保存至本地。比如:`-o docker-archive:/root/image.tar:busybox:latest`。 + +打开实验特性之后,可以启用相应OCI镜像的构建: + +* `oci://registry.example.com/repository:tag`:将构建成功的镜像以OCI镜像格式直接推送到远端镜像仓库(远程镜像仓库须支持OCI镜像格式)。比如:`-o oci://localhost:5000/library/busybox:latest`。 + +* `oci-archive:/:image:tag`:将构建成功的镜像以OCI镜像的格式保存至本地。比如:`-o oci-archive:/root/image.tar:busybox:latest`。 + +除去各个flags之外,build子命令的命令行最后还会接收一个argument,该argument类型是string,意义为context,即该Dockerfile构建环境的上下文。该参数缺省值为isula-build被执行的当前路径。该路径会影响 .dockerignore 和 Dockerfile的ADD/COPY指令 所检索的路径。 + +**\--proxy** + +选择构建时RUN指令启动的容器是否从环境上继承proxy相关环境变量“http_proxy”,“https_proxy”,“ftp_proxy”,“no_proxy”,“HTTP_PROXY”,“HTTPS_PROXY”,“FTP_PROXY”,“NO_PROXY”,默认为true。 + +当用户在Dockerfile配置proxy相关ARG或ENV,将覆盖所继承的环境变量。 + +注意:若client与daemon不在同一个终端运行,所能继承的环境变量为daemon所在终端的环境变量。 + +**\--tag** + +设置镜像构建成功之后,该镜像在本地磁盘存储时的tag。 + +**\--cap-add** + +添加构建过程中RUN指令所需权限,用法: + +```sh +isula-build ctr-img build --cap-add ${CAP} +``` + +使用举例: + +```sh +sudo isula-build ctr-img build --cap-add CAP_SYS_ADMIN --cap-add CAP_SYS_PTRACE -f Dockerfile +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> * isula-build最大支持并发构建100个容器镜像。 +> * isula-build支持Dockerfile最大为1MiB。 +> * isula-build支持 .dockerignore 最大为 1MiB。 +> * 用户需保证Dockerfile文件的权限为仅当前用户可读写,避免别的用户进行篡改。 +> * 构建时,RUN指令会启动容器在容器内进行构建,目前 isula-build 仅支持使用主机网络。 +> * isula-build 导出的镜像压缩格式,目前仅支持tar格式。 +> * isula-build 在每一个镜像构建stage完成后做一次提交,而不是每执行 Dockerfile的一行就提交一次。 +> * isula-build 暂不支持构建缓存。 +> * isula-build 仅在构建RUN指令时会启动构建容器。 +> * 目前不支持docker镜像格式的history功能。 +> * isula-build 的stage name支持以数字开头。 +> * isula-build 的stage name最长可为64个字符。 +> * isula-build 暂不支持对单次Dockerfile的构建进行资源限制。如有资源限制需求,可通过对 isula-builder 服务端配置资源限额的方式进行限制。 +> * isula-build 目前不支持Dockerfile里的ADD指令提供的数据来源是远端url。 +> * isula-build 使用docker-archive以及oci-archive类型导出的本地tar包未经压缩。如有需求,用户可以手动进行压缩。 + +### image: 查看本地持久化构建镜像 + +可通过images命令查看当前本地持久化存储的镜像: + +```sh +$ sudo isula-build ctr-img images +--------------------------------------- ----------- ----------------- ------------------------ ------------ +REPOSITORY TAG IMAGE ID CREATED SIZE +--------------------------------------- ----------- ----------------- ------------------------ ------------ +localhost:5000/library/alpine latest a24bb4013296 2022-01-17 10:02:19 5.85 MB + 39b62a3342ee 2022-01-17 10:01:12 1.45 MB +--------------------------------------- ----------- ----------------- ------------------------ ------------ +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 通过`isula-build ctr-img images`查看的镜像大小与`docker images`的显示上有一定差异。这是因为统计镜像大小时,isula-build是直接计算每层tar包大小之和,而docker是通过解压tar遍历diff目录计算文件大小之和,因此存在统计上的差异。 + +### import: 导入容器基础镜像 + +可以通过`ctr-img import`指令将rootfs形式的tar文件导入到isula-build中。 + +命令原型如下: + +```sh +isula-build ctr-img import [flags] +``` + +使用举例: + +```sh +$ sudo isula-build ctr-img import busybox.tar mybusybox:latest +Getting image source signatures +Copying blob sha256:7b8667757578df68ec57bfc9fb7754801ec87df7de389a24a26a7bf2ebc04d8d +Copying config sha256:173b3cf612f8e1dc34e78772fcf190559533a3b04743287a32d549e3c7d1c1d1 +Writing manifest to image destination +Storing signatures +Import success with image id: "173b3cf612f8e1dc34e78772fcf190559533a3b04743287a32d549e3c7d1c1d1" +$ sudo isula-build ctr-img images +--------------------------------------- ----------- ----------------- ------------------------ ------------ +REPOSITORY TAG IMAGE ID CREATED SIZE +--------------------------------------- ----------- ----------------- ------------------------ ------------ +mybusybox latest 173b3cf612f8 2022-01-12 16:02:31 1.47 MB +--------------------------------------- ----------- ----------------- ------------------------ ------------ +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> isula-build 支持导入最大1GiB的容器基础镜像。 + +### load: 导入层叠镜像 + +层叠镜像指的是通过 docker save 或 isula-build ctr-img save 等指令,将一个构建完成的镜像保存至本地之后,镜像压缩包内是一层一层 layer.tar 的镜像包。可以通过 ctr-img load 指令将它导入至 isula-build。 + +命令原型如下: + +```sh +isula-build ctr-img load [flags] +``` + +目前支持的 flags 为: + +* -i, --input:本地tar包的路径 + +使用举例如下: + +```sh +$ sudo isula-build ctr-img load -i ubuntu.tar +Getting image source signatures +Copying blob sha256:cf612f747e0fbcc1674f88712b7bc1cd8b91cf0be8f9e9771235169f139d507c +Copying blob sha256:f934e33a54a60630267df295a5c232ceb15b2938ebb0476364192b1537449093 +Copying blob sha256:943edb549a8300092a714190dfe633341c0ffb483784c4fdfe884b9019f6a0b4 +Copying blob sha256:e7ebc6e16708285bee3917ae12bf8d172ee0d7684a7830751ab9a1c070e7a125 +Copying blob sha256:bf6751561805be7d07d66f6acb2a33e99cf0cc0a20f5fd5d94a3c7f8ae55c2a1 +Copying blob sha256:c1bd37d01c89de343d68867518b1155cb297d8e03942066ecb44ae8f46b608a3 +Copying blob sha256:a84e57b779297b72428fc7308e63d13b4df99140f78565be92fc9dbe03fc6e69 +Copying blob sha256:14dd68f4c7e23d6a2363c2320747ab88986dfd43ba0489d139eeac3ac75323b2 +Copying blob sha256:a2092d776649ea2301f60265f378a02405539a2a68093b2612792cc65d00d161 +Copying blob sha256:879119e879f682c04d0784c9ae7bc6f421e206b95d20b32ce1cb8a49bfdef202 +Copying blob sha256:e615448af51b848ecec00caeaffd1e30e8bf5cffd464747d159f80e346b7a150 +Copying blob sha256:f610bd1e9ac6aa9326d61713d552eeefef47d2bd49fc16140aa9bf3db38c30a4 +Copying blob sha256:bfe0a1336d031bf5ff3ce381e354be7b2bf310574cc0cd1949ad94dda020cd27 +Copying blob sha256:f0f15db85788c1260c6aa8ad225823f45c89700781c4c793361ac5fa58d204c7 +Copying config sha256:c07ddb44daa97e9e8d2d68316b296cc9343ab5f3d2babc5e6e03b80cd580478e +Writing manifest to image destination +Storing signatures +Loaded image as c07ddb44daa97e9e8d2d68316b296cc9343ab5f3d2babc5e6e03b80cd580478e +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> * isula-build 支持导入最大50G的容器层叠镜像。 +> * isula-build 会自动识别容器层叠镜像的格式并进行导入。 + +### rm: 删除本地持久化镜像 + +可通过rm命令删除当前本地持久化存储的镜像。命令原型为: + +```sh +isula-build ctr-img rm IMAGE [IMAGE...] [FLAGS] +``` + +目前支持的 flags 为: + +* -a, --all:删除所有本地持久化存储的镜像。 +* -p, --prune:删除所有没有tag的本地持久化存储的镜像。 + +使用示例如下: + +```sh +$ sudo isula-build ctr-img rm -p +Deleted: sha256:78731c1dde25361f539555edaf8f0b24132085b7cab6ecb90de63d72fa00c01d +Deleted: sha256:eeba1bfe9fca569a894d525ed291bdaef389d28a88c288914c1a9db7261ad12c +``` + +### save: 导出层叠镜像 + +可通过save命令导出层叠镜像到本地磁盘。命令原型如下: + +```sh +isula-build ctr-img save [REPOSITORY:TAG]|imageID -o xx.tar +``` + +目前支持的 flags 为: + +* -f, --format:导出层叠镜像的镜像格式:oci | docker(需开启实验特性选项) +* -o, --output:本地tar包路径 + +以下示例通过 `image/tag` 的形式将镜像进行导出: + +```sh +$ sudo isula-build ctr-img save busybox:latest -o busybox.tar +Getting image source signatures +Copying blob sha256:50644c29ef5a27c9a40c393a73ece2479de78325cae7d762ef3cdc19bf42dd0a +Copying blob sha256:824082a6864774d5527bda0d3c7ebd5ddc349daadf2aa8f5f305b7a2e439806f +Copying blob sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef +Copying config sha256:21c3e96ac411242a0e876af269c0cbe9d071626bdfb7cc79bfa2ddb9f7a82db6 +Writing manifest to image destination +Storing signatures +Save success with image: busybox:latest +``` + +以下示例通过 `ImageID` 的形式将镜像进行导出: + +```sh +$ sudo isula-build ctr-img save 21c3e96ac411 -o busybox.tar +Getting image source signatures +Copying blob sha256:50644c29ef5a27c9a40c393a73ece2479de78325cae7d762ef3cdc19bf42dd0a +Copying blob sha256:824082a6864774d5527bda0d3c7ebd5ddc349daadf2aa8f5f305b7a2e439806f +Copying blob sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef +Copying config sha256:21c3e96ac411242a0e876af269c0cbe9d071626bdfb7cc79bfa2ddb9f7a82db6 +Writing manifest to image destination +Storing signatures +Save success with image: 21c3e96ac411 +``` + +以下示例导出多个镜像到同一个tar包: + +```sh +$ sudo isula-build ctr-img save busybox:latest nginx:latest -o all.tar +Getting image source signatures +Copying blob sha256:eb78099fbf7fdc70c65f286f4edc6659fcda510b3d1cfe1caa6452cc671427bf +Copying blob sha256:29f11c413898c5aad8ed89ad5446e89e439e8cfa217cbb404ef2dbd6e1e8d6a5 +Copying blob sha256:af5bd3938f60ece203cd76358d8bde91968e56491daf3030f6415f103de26820 +Copying config sha256:b8efb18f159bd948486f18bd8940b56fd2298b438229f5bd2bcf4cedcf037448 +Writing manifest to image destination +Storing signatures +Getting image source signatures +Copying blob sha256:e2d6930974a28887b15367769d9666116027c411b7e6c4025f7c850df1e45038 +Copying config sha256:a33de3c85292c9e65681c2e19b8298d12087749b71a504a23c576090891eedd6 +Writing manifest to image destination +Storing signatures +Save success with image: [busybox:latest nginx:latest] +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> * save 导出的镜像默认格式为未压缩的tar格式,如有需求,用户可以再save之后手动压缩。 +> * 在使用镜像名导出镜像时,需要给出完整的镜像名格式:REPOSITORY:TAG。 + +### tag: 给本地持久化镜像打标签 + +可使用tag命令给本地持久化的容器镜像打tag。命令原型如下: + +```sh +isula-build ctr-img tag / busybox:latest +``` + +使用举例: + +```sh +$ sudo isula-build ctr-img images +--------------------------------------- ----------- ----------------- -------------------------- ------------ +REPOSITORY TAG IMAGE ID CREATED SIZE +--------------------------------------- ----------- ----------------- -------------------------- ------------ +alpine latest a24bb4013296 2020-05-29 21:19:46 5.85 MB +--------------------------------------- ----------- ----------------- -------------------------- ------------ +$ sudo isula-build ctr-img tag a24bb4013296 alpine:v1 +$ sudo isula-build ctr-img images +--------------------------------------- ----------- ----------------- ------------------------ ------------ +REPOSITORY TAG IMAGE ID CREATED SIZE +--------------------------------------- ----------- ----------------- ------------------------ ------------ +alpine latest a24bb4013296 2020-05-29 21:19:46 5.85 MB +alpine v1 a24bb4013296 2020-05-29 21:19:46 5.85 MB +--------------------------------------- ----------- ----------------- ------------------------ ------------ +``` + +### pull: 拉取镜像到本地 + +可通过pull命令拉取远程镜像仓库中的镜像到本地。命令原型如下: + +```sh +isula-build ctr-img pull REPOSITORY[:TAG] +``` + +使用示例: + +```sh +$ sudo isula-build ctr-img pull example-registry/library/alpine:latest +Getting image source signatures +Copying blob sha256:8f52abd3da461b2c0c11fda7a1b53413f1a92320eb96525ddf92c0b5cde781ad +Copying config sha256:e4db68de4ff27c2adfea0c54bbb73a61a42f5b667c326de4d7d5b19ab71c6a3b +Writing manifest to image destination +Storing signatures +Pull success with image: example-registry/library/alpine:latest +``` + +### push: 将本地镜像推送到远程仓库 + +可通过push命令将本地镜像推送到远程仓库。命令原型如下: + +```sh +isula-build ctr-img push REPOSITORY[:TAG] +``` + +目前支持的 flags 为: + +* -f, --format:推送的镜像格式:oci|docker(需开启实验特性选项) + +使用示例: + +```sh +$ sudo isula-build ctr-img push example-registry/library/mybusybox:latest +Getting image source signatures +Copying blob sha256:d2421964bad195c959ba147ad21626ccddc73a4f2638664ad1c07bd9df48a675 +Copying config sha256:f0b02e9d092d905d0d87a8455a1ae3e9bb47b4aa3dc125125ca5cd10d6441c9f +Writing manifest to image destination +Storing signatures +Push success with image: example-registry/library/mybusybox:latest +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 推送镜像时,需要先登录对应的镜像仓库 + +## info: 查看运行环境与系统信息 + +可以通过“isula-build info”指令查看 isula-build 目前的运行环境与系统信息。命令原型如下: + +```sh +isula-build info [flags] +``` + +支持如下Flags: + +* -H, --human-readable 布尔值,以常用内存表示格式打印内存信息,使用1000次幂 +* -V, --verbose 布尔值,显示运行时内存占用信息 + +使用示例: + +```sh +$ sudo isula-build info -HV + General: + MemTotal: 7.63 GB + MemFree: 757 MB + SwapTotal: 8.3 GB + SwapFree: 8.25 GB + OCI Runtime: runc + DataRoot: /var/lib/isula-build/ + RunRoot: /var/run/isula-build/ + Builders: 0 + Goroutines: 12 + Store: + Storage Driver: overlay + Backing Filesystem: extfs + Registry: + Search Registries: + oepkgs.net + Insecure Registries: + localhost:5000 + oepkgs.net + Runtime: + MemSys: 68.4 MB + HeapSys: 63.3 MB + HeapAlloc: 7.41 MB + MemHeapInUse: 8.98 MB + MemHeapIdle: 54.4 MB + MemHeapReleased: 52.1 MB +``` + +## login: 登录远端镜像仓库 + +用户可以运行 login 命令来登录远程镜像仓库。命令原型如下: + +```sh + isula-build login SERVER [FLAGS] +``` + +目前支持的flag有: + +```Conf + Flags: + -p, --password-stdin Read password from stdin + -u, --username string Username to access registry +``` + +通过stdin输入密码。以下示例通过通过管道将creds.txt里的密码传给isula-build的stdin进行输入: + +```sh + $ cat creds.txt | sudo isula-build login -u cooper -p mydockerhub.io + Login Succeeded +``` + +通过交互式输入密码: + +```sh + $ sudo isula-build login mydockerhub.io -u cooper + Password: + Login Succeeded +``` + +## logout: 退出远端镜像仓库 + +用户可以运行 logout 命令来登出远程镜像仓库。命令原型如下: + +```sh +isula-build logout [SERVER] [FLAGS] +``` + +目前支持的flag有: + +```sh + Flags: + -a, --all Logout all registries +``` + +使用示例如下: + +```sh +$ sudo isula-build logout -a + Removed authentications +``` + +## version: 版本查询 + +可通过version命令查看当前版本信息: + +```sh +$ sudo isula-build version +Client: + Version: 0.9.6-4 + Go Version: go1.15.7 + Git Commit: 83274e0 + Built: Wed Jan 12 15:32:55 2022 + OS/Arch: linux/amd64 + +Server: + Version: 0.9.6-4 + Go Version: go1.15.7 + Git Commit: 83274e0 + Built: Wed Jan 12 15:32:55 2022 + OS/Arch: linux/amd64 +``` + +## manifest: manifest列表管理 + +manifest列表包含不同系统架构对应的镜像信息,通过使用manifest列表,用户可以在不同的架构中使用相同的manifest(例如openeuler:latest)获取对应架构的镜像,manifest包含create、annotate、inspect和push子命令。 +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> manifest为实验特性,使用时需开启客户端和服务端的实验选项,方式详见客户端总体说明和配置服务章节。 + +### create: manifest列表创建 + +manifest的子命令create用于创建manifest列表,命令原型为: + +```sh +isula-build manifest create MANIFEST_LIST MANIFEST [MANIFEST...] +``` + +用户可以指定manifest列表的名称以及需要加入到列表中的远程镜像,若不指定任何远程镜像,则会创建一个空的manifest列表。 + +使用示例如下: + +```sh +sudo isula-build manifest create openeuler localhost:5000/openeuler_x86:latest localhost:5000/openeuler_aarch64:latest +``` + +### annotate: manifest列表更新 + +manifest的子命令annotate用于更新manifest列表,命令原型为: + +```sh +isula-build manifest annotate MANIFEST_LIST MANIFEST [flags] +``` + +用户可以指定需要更新的manifest列表以及其中的镜像,通过flags指定需要更新的选项,此命令也可用于添加新的镜像到列表中。 + +其中annotate包含如下flags: + +* --arch: string,重写镜像适用架构 +* --os: string,重写镜像适用系统 +* --os-features: string列表,指定镜像需要的OS特性,很少使用 +* --variant: string,指定列表中记录镜像的变量 + +使用示例如下: + +```sh +sudo isula-build manifest annotate --os linux --arch arm64 openeuler:latest localhost:5000/openeuler_aarch64:latest +``` + +### inspect: manifest列表查询 + +manifest子命令inspect用于查询manifest列表信息,命令原型为: + +```sh +isula-build manifest inspect MANIFEST_LIST +``` + +使用示例如下: + +```sh +$ sudo isula-build manifest inspect openeuler:latest +{ + "schemaVersion": 2, + "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", + "manifests": [ + { + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "size": 527, + "digest": "sha256:bf510723d2cd2d4e3f5ce7e93bf1e52c8fd76831995ac3bd3f90ecc866643aff", + "platform": { + "architecture": "amd64", + "os": "linux" + } + }, + { + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "size": 527, + "digest": "sha256:f814888b4bb6149bd39ba8375a1932fb15071b4dbffc7f76c7b602b06abbb820", + "platform": { + "architecture": "arm64", + "os": "linux" + } + } + ] +} +``` + +### push: 将manifest列表推送到远程仓库 + +manifest子命令push用于将manifest列表推送到远程仓库,命令原型为: + +```sh +isula-build manifest push MANIFEST_LIST DESTINATION +``` + +使用示例如下: + +```sh +sudo isula-build manifest push openeuler:latest localhost:5000/openeuler:latest +``` + +# 直接集成容器引擎 + +isula-build可以与iSulad和docker集成,将构建好的容器镜像导入到容器引擎的本地存储中。 + +## 与iSulad集成 + +支持将构建成功的镜像直接导出到iSulad。 + +命令行举例: + +```sh +sudo isula-build ctr-img build -f Dockerfile -o isulad:busybox:2.0 +``` + +通过在-o参数中指定iSulad,将构建好的容器镜像导出到iSulad,可以通过isula images查询: + +```sh +$ sudo isula images +isula images +REPOSITORY TAG IMAGE ID CREATED SIZE +busybox 2.0 2d414a5cad6d 2020-08-01 06:41:36 5.577 MB +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> * 要求isula-build和iSulad在同一节点。 +> * 直接导出镜像到iSulad时,isula-build client端需要将构建成功的镜像暂存成 `/var/lib/isula-build/tmp/[buildid]/isula-build-tmp-%v.tar` 再导入至 iSulad,用户需要保证 /var/lib/isula-build/tmp/ 目录有足够磁盘空间;同时如果在导出过程中 isula-build client进程被KILL或Ctrl+C终止,需要依赖用户手动清理 `/var/lib/isula-build/tmp/[buildid]/isula-build-tmp-%v.tar` 文件。 + +## 与Docker集成 + +支持将构建成功的镜像直接导出到Docker daemon。 + +命令行举例: + +```sh +sudo isula-build ctr-img build -f Dockerfile -o docker-daemon:busybox:2.0 +``` + +通过在-o参数中指定docker-daemon,将构建好的容器镜像导出到docker, 可以通过docker images查询。 + +```sh +$ sudo docker images +REPOSITORY TAG IMAGE ID CREATED SIZE +busybox 2.0 2d414a5cad6d 2 months ago 5.22MB +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 要求isula-build和Docker在同一节点。 + +# 使用注意事项 + +本章节主要介绍在使用isula-build构建镜像时相关的约束和限制,以及与docker build的差异。 + +## 约束和限制 + +1. 当导出镜像到[`iSulad`](https://gitee.com/openeuler/iSulad/blob/master/README.md/)时,镜像必须指明tag。 +2. 因为isula-builder运行`RUN`指令时,需要调用系统中的oci 运行时(如`runc`),用户需要保证该运行时的安全性,不受篡改。 +3. `DataRoot`不能设置在内存盘上(tmpfs)。 +4. `Overlay2`是目前isula-builder唯一支持的存储驱动。 +5. `Docker`镜像是目前唯一支持的镜像格式,未来即将支持`oci`格式镜像。 +6. `Dockerfile`文件权限强烈建议设置为**0600**以防止恶意篡改。 +7. `RUN`命令中目前只支持主机侧网络(host network)。 +8. 当导出镜像到本地tar包时,目前只支持保存为`tar`格式。 +9. 当使用`import`功能导入基础镜像时,最大支持**1G**。 + +## 与“docker build”差异 + +`isula-build`兼容[Docker镜像格式规范](https://docs.docker.com/engine/reference/builder/),但仍然和`docker build`存在一些差异: + +1. 支持镜像压缩,即对每个`stage`进行提交而非每一行。 +2. 目前不支持构建缓存。 +3. 只有`RUN`指令会运行容器进行构建。 +4. 目前不支持查询镜像构建历史。 +5. `Stage`名称可以用数字开头。 +6. `Stage`名称最大长度为64。 +7. `ADD`命令不支持远端URL格式。 +8. 暂不支持对单次构建进行资源限额,可采取对isula-builder配置资源限额的方式进行限制。 +9. 统计镜像大小时,isula-build是直接计算每层tar包大小之和,而docker是通过解压tar遍历diff目录计算文件大小之和,因此通过`isula-build ctr-img images`查看的镜像大小与`docker images`的显示上有一定差异。 +10. 操作时的镜像名称需要明确,格式为IMAGE_NAME:IMAGE_TAG。例如 busybox:latest, 其中latest不可省略。 diff --git a/docs/en/25.03/Cloud/ImageBuilder/isula-build/overview.md b/docs/en/25.03/Cloud/ImageBuilder/isula-build/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..67e98d6f48ca701fd3f59d820aa1066e2c7257ac --- /dev/null +++ b/docs/en/25.03/Cloud/ImageBuilder/isula-build/overview.md @@ -0,0 +1,11 @@ +# 容器镜像构建 + +isula-build是iSula容器团队推出的容器镜像构建工具,支持通过Dockerfile文件快速构建容器镜像。 + +isula-build采用服务端/客户端模式。其中,isula-build为客户端,提供了一组命令行工具,用于镜像构建及管理等;isula-builder为服务端,用于处理客户端管理请求,作为守护进程常驻后台。 + +![isula-build architecture](./figures/isula-build_arch.png) + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> isula-build当前支持OCI镜像格式([OCI Image Format Specification](https://github.com/opencontainers/image-spec/blob/main/spec.md/))以及Docker镜像格式([Image Manifest Version 2, Schema 2](https://docs.docker.com/registry/spec/manifest-v2-2/))。通过命令`export ISULABUILD_CLI_EXPERIMENTAL=enabled`开启实验特性以支持OCI镜像格式。不开启实验特性时,isula-build默认采用Docker镜像格式;当开启实验特性后,将默认采用OCI镜像格式。 diff --git a/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-caution.gif b/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-caution.gif differ diff --git a/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-danger.gif b/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-danger.gif differ diff --git a/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-note.gif b/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-notice.gif b/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-notice.gif differ diff --git a/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-tip.gif b/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-tip.gif differ diff --git a/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-warning.gif b/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Cloud/ImageBuilder/isula-build/public_sys-resources/icon-warning.gif differ diff --git a/docs/en/25.03/Cloud/Kmesh/Kmesh/_menu.md b/docs/en/25.03/Cloud/Kmesh/Kmesh/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..83190a6946c3dd42af885686afd153f68515d1a1 --- /dev/null +++ b/docs/en/25.03/Cloud/Kmesh/Kmesh/_menu.md @@ -0,0 +1,18 @@ +--- +label: 'Kmesh用户指南' +ismanual: 'Y' +description: 'openEuler系统高性能服务网格数据面软件' +children: + - label: '概述' + href: './overview.md' + - label: '认识Kmesh' + href: './getting-to-know-kmesh.md' + - label: '安装与部署' + href: './installation-and-deployment.md' + - label: '使用方法' + href: './usage.md' + - label: '常见问题与解决方法' + href: './faqs.md' + - label: '附录' + href: './appendixes.md' +--- \ No newline at end of file diff --git a/docs/en/25.03/Cloud/Kmesh/Kmesh/appendixes.md b/docs/en/25.03/Cloud/Kmesh/Kmesh/appendixes.md new file mode 100644 index 0000000000000000000000000000000000000000..59b86f94ad67534866cb2e20abc826bebd3bd785 --- /dev/null +++ b/docs/en/25.03/Cloud/Kmesh/Kmesh/appendixes.md @@ -0,0 +1,3 @@ +# 附录 + +更详细的使用说明可访问[Kmesh](https://gitee.com/openeuler/Kmesh#kmesh)项目首页获取。 diff --git a/docs/en/25.03/Cloud/Kmesh/Kmesh/faqs.md b/docs/en/25.03/Cloud/Kmesh/Kmesh/faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..eab2cba82cd4416c1798ad786f93f9f8478f79b6 --- /dev/null +++ b/docs/en/25.03/Cloud/Kmesh/Kmesh/faqs.md @@ -0,0 +1,23 @@ +# 常见问题与解决方法 + +## **问题1:在使用集群启动模式时,若没有配置控制面程序ip信息,Kmesh服务启动后会报错退出** + +![](./figures/not_set_cluster_ip.png) + +原因:集群启动模式下,Kmesh服务需要跟控制面程序通信,然后从控制面获取配置信息,因此需要设置正确的控制面程序ip信息。 + +解决方法:参考[安装与部署](./installation-and-deployment.md)章节中集群启动模式,设置正确的控制面程序ip信息。 + +## **问题2:Kmesh服务在启动时,提示"get kube config error!"** + +![](./figures/get_kubeconfig_error.png) + +原因:集群启动模式下,Kmesh服务会根据k8s的配置,自动获取控制面程序ip信息,若环境中没有配置k8s的kubeconfig路径,会导致获取kubeconfig失败,然后提示上述信息。(若已经手动修改Kmesh的配置文件,正确配置控制面程序ip信息,该问题可忽略) + +解决方法:按如下方式配置kubeconfig: + +```shell +mkdir -p $HOME/.kube +sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config +sudo chown $(id -u):$(id -g) $HOME/.kube/config +``` diff --git a/docs/en/25.03/Cloud/Kmesh/Kmesh/figures/get_kubeconfig_error.png b/docs/en/25.03/Cloud/Kmesh/Kmesh/figures/get_kubeconfig_error.png new file mode 100644 index 0000000000000000000000000000000000000000..99087b68c6fafea1506e5f8bd862c371e93bdc97 Binary files /dev/null and b/docs/en/25.03/Cloud/Kmesh/Kmesh/figures/get_kubeconfig_error.png differ diff --git a/docs/en/25.03/Cloud/Kmesh/Kmesh/figures/kmesh-arch.png b/docs/en/25.03/Cloud/Kmesh/Kmesh/figures/kmesh-arch.png new file mode 100644 index 0000000000000000000000000000000000000000..000ec80ff35556199caef6ce78953599c1c52312 Binary files /dev/null and b/docs/en/25.03/Cloud/Kmesh/Kmesh/figures/kmesh-arch.png differ diff --git a/docs/en/25.03/Cloud/Kmesh/Kmesh/figures/not_set_cluster_ip.png b/docs/en/25.03/Cloud/Kmesh/Kmesh/figures/not_set_cluster_ip.png new file mode 100644 index 0000000000000000000000000000000000000000..9c879f37fa93c0f4fe0ab0f6220beff174e5f436 Binary files /dev/null and b/docs/en/25.03/Cloud/Kmesh/Kmesh/figures/not_set_cluster_ip.png differ diff --git a/docs/en/25.03/Cloud/Kmesh/Kmesh/getting-to-know-kmesh.md b/docs/en/25.03/Cloud/Kmesh/Kmesh/getting-to-know-kmesh.md new file mode 100644 index 0000000000000000000000000000000000000000..d82f45f673d721178235b9202323c81f7f59b94f --- /dev/null +++ b/docs/en/25.03/Cloud/Kmesh/Kmesh/getting-to-know-kmesh.md @@ -0,0 +1,38 @@ +# 认识Kmesh + +## 简介 + +随着越来越多的应用云原生化,云上应用的规模、应用SLA诉求等都对云基础设施提出了很高的要求。 + +基于k8s的云基础设施能够帮助应用实现敏捷的部署管理,但在应用流量编排方面有所欠缺,serviceMesh的出现很好的弥补了k8s流量编排的缺陷,与k8s互补,真正实现敏捷的云应用开发运维;但随着对serviceMesh应用的逐步深入,当前基于sidecar的网格架构在数据面存在明显的性能缺陷,已成为业界共识的问题: + +* 时延性能差 + 以serviceMesh典型软件istio为例,网格化后,服务访问单跳时延增加2.65ms;无法满足时延敏感型应用诉求 + +* 底噪开销大 + istio中,每个sidecar软件占用内存50M+,CPU默认独占2 core,对于大规模集群底噪开销太大,降低了业务容器的部署密度 + +Kmesh基于可编程内核,将网格流量治理下沉OS,数据路径3跳->1跳,大幅提升网格数据面的时延性能,帮助业务快速创新。 + +## 架构 + +Kmesh总体架构如下图所示: + +![](./figures/kmesh-arch.png) + +Kmesh的主要部件包括: + +* kmesh-controller: + kmesh管理程序,负责Kmesh生命周期管理、XDS协议对接、观测运维等功能 + +* kmesh-api: + kmesh对外提供的api接口层,主要包括:xds转换后的编排API、观测运维通道等 + +* kmesh-runtime: + kernel中实现的支持L3~L7流量编排的运行时 + +* kmesh-orchestration: + 基于ebpf实现L3~L7流量编排,如路由、灰度、负载均衡等 + +* kmesh-probe: + 观测运维探针,提供端到端观测能力 diff --git a/docs/en/25.03/Cloud/Kmesh/Kmesh/installation-and-deployment.md b/docs/en/25.03/Cloud/Kmesh/Kmesh/installation-and-deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..690bee66b471b4aefbfcdc3ba7d08fb57d0ebaf2 --- /dev/null +++ b/docs/en/25.03/Cloud/Kmesh/Kmesh/installation-and-deployment.md @@ -0,0 +1,101 @@ +# 安装与部署 + +## 软件要求 + +* 操作系统:openEuler 23.09 + +## 硬件要求 + +* x86_64架构 + +## 环境准备 + +* 安装openEuler系统,安装方法参考 《[安装指南](../../../Server/InstallationUpgrade/Installation/installation.md)》。 + +* 安装Kmesh需要使用root权限。 + +## 安装Kmesh + +* 安装Kmesh软件包,参考命令如下: + +```shell +[root@openEuler ~]# yum install Kmesh +``` + +* 查看安装是否成功,参考命令如下,若回显有对应软件包,表示安装成功: + +```shell +[root@openEuler ~]# rpm -q Kmesh +``` + +## 部署Kmesh + +### 集群启动模式 + +启动前,先进行配置修改,设置集群中控制面程序ip信息(如istiod ip地址),操作如下: + +```json + "clusters": [ + { + "name": "xds-grpc", + "type" : "STATIC", + "connect_timeout": "1s", + "lb_policy": "ROUND_ROBIN", + "load_assignment": { + "cluster_name": "xds-grpc", + "endpoints": [{ + "lb_endpoints": [{ + "endpoint": { + "address":{ + "socket_address": { + "protocol": "TCP", + "address": "192.168.0.1",# 设置控制面ip(如istiod ip) + "port_value": 15010 + } + } + } + }] + }] +``` + +当前集群启动模式下仅支持Kmesh流量编排功能。 + +### 本地启动模式 + +启动前,修改kmesh.service,选择需要使用的功能选项。 + +使用流量编排功能,操作如下: + +```shell +# 选择-enable-kmesh,禁用ads开关 +[root@openEuler ~]# vim /usr/lib/systemd/system/kmesh.service +ExecStart=/usr/bin/kmesh-daemon -enable-kmesh -enable-ads=false +[root@openEuler ~]# systemctl daemon-reload +``` + +使用网格加速功能,操作如下: + +```shell +# 选择-enable-mda选项,禁用ads开关 +[root@openEuler ~]# vim /usr/lib/systemd/system/kmesh.service +ExecStart=/usr/bin/kmesh-daemon -enable-mda -enable-ads=false +[root@openEuler ~]# systemctl daemon-reload +``` + +Kmesh服务启动时会调用kmesh-daemon程序,具体使用方式可以参考[kmesh-daemon使用](./usage.md)。 + +### 启动Kmesh + +```shell +# 启动Kmesh服务 +[root@openEuler ~]# systemctl start kmesh.service +# 查看Kmesh运行状态 +[root@openEuler ~]# systemctl status kmesh.service +``` + +### 停止Kmesh + +```shell +# 停止Kmesh服务 +[root@openEuler ~]# systemctl stop kmesh.service +``` diff --git a/docs/en/25.03/Cloud/Kmesh/Kmesh/overview.md b/docs/en/25.03/Cloud/Kmesh/Kmesh/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..611ee4e6b6004e3f36603cd533b3ae3f82ad9031 --- /dev/null +++ b/docs/en/25.03/Cloud/Kmesh/Kmesh/overview.md @@ -0,0 +1,5 @@ +# Kmesh用户指南 + +本文档介绍openEuler系统高性能服务网格数据面软件Kmesh的安装部署与使用方法,以指导用户快速了解并使用Kmesh。 + +本文档适用于使用openEuler系统并希望了解和使用Kmesh的社区开发者、开源爱好者以及相关合作伙伴。使用人员需要具备基本的Linux操作系统知识。 diff --git a/docs/en/25.03/Cloud/Kmesh/Kmesh/usage.md b/docs/en/25.03/Cloud/Kmesh/Kmesh/usage.md new file mode 100644 index 0000000000000000000000000000000000000000..8b604c9bfef0466b6852692fe36b3c50c01db89e --- /dev/null +++ b/docs/en/25.03/Cloud/Kmesh/Kmesh/usage.md @@ -0,0 +1,76 @@ +# 使用方法 + +## kmesh-daemon使用 + +```shell +# 命令help +[root@openEuler ~]# kmesh-daemon -h +Usage of kmesh-daemon: + -bpf-fs-path string + bpf fs path (default "/sys/fs/bpf") + -cgroup2-path string + cgroup2 path (default "/mnt/kmesh_cgroup2") + -config-file string + [if -enable-kmesh] deploy in kube cluster (default "/etc/kmesh/kmesh.json") + -enable-ads + [if -enable-kmesh] enable control-plane from ads (default true) + -enable-kmesh + enable bpf kmesh + -enable-mda + enable mda + -service-cluster string + [if -enable-kmesh] TODO (default "TODO") + -service-node string + [if -enable-kmesh] TODO (default "TODO") + +# 默认使能ads +[root@openEuler ~]# kmesh-daemon -enable-kmesh + +# 使能ads,并指定配置文件路径 +[root@openEuler ~]# kmesh-daemon -enable-kmesh -enable-ads=true -config-file=/examples/kmesh.json + +# 不使能ads +[root@openEuler ~]# kmesh-daemon -enable-kmesh -enable-ads=false + +# 使能sockmap加速 +[root@openEuler ~]# kmesh-daemon -enable-mda -enable-ads=false +``` + +## kmesh-cmd使用 + +```shell +# 命令help +[root@openEuler ~]# kmesh-cmd -h +Usage of kmesh-cmd: + -config-file string + input config-resources to bpf maps (default "./config-resources.json") + +# 手动加载配置 +[root@openEuler ~]# kmesh-cmd -config-file=/examples/config-resources.json +``` + +## 运维相关命令使用 + +```shell +# 命令help +[root@openEuler ~]# curl http://localhost:15200/help + /help: print list of commands + /options: print config options + /bpf/kmesh/maps: print bpf kmesh maps in kernel + /controller/envoy: print control-plane in envoy cache + /controller/kubernetes: print control-plane in kubernetes cache + +# 读取加载的配置 +[root@openEuler ~]# curl http://localhost:15200/bpf/kmesh/maps +[root@openEuler ~]# curl http://localhost:15200/options +``` + +## 注意事项 + +* -enable-ads=true时,Kmesh从服务网格控制面自动接收编排规则,此配置下,不要使用kmesh-cmd命令下发规则,避免多次配置。 + +* -bpf-fs-path选项用于指定系统的bpf文件系统路径,kmesh bpf程序相关的数据会存放在该路径下,默认路径为/sys/fs/bpf。 + +* -cgroup2-path选项用于指定系统cgroup路径,默认路径为/mnt/kmesh_cgroup2。 + +* -enable-kmesh和-enable-mda当前不支持同时使用,同一时刻只能使用其中一种。 diff --git a/docs/en/25.03/Cloud/KubeOS/KubeOS/_menu.md b/docs/en/25.03/Cloud/KubeOS/KubeOS/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..ffbc4d0644b636b967966f84e66bd6fe13ffec86 --- /dev/null +++ b/docs/en/25.03/Cloud/KubeOS/KubeOS/_menu.md @@ -0,0 +1,16 @@ +--- +label: '容器OS升级用户指南' +ismanual: 'Y' +description: 'KubeOS是专为容器化业务涉及的轻量级操作系统,支持原子化升级,确保版本一致性,降低运维复杂性' +children: + - label: '概述' + href: './overview.md' + - label: '认识容器OS升级' + href: './about-kubeos.md' + - label: '安装与部署' + href: './installation-and-deployment.md' + - label: '使用方法' + href: './usage-instructions.md' + - label: '容器OS镜像制作指导' + href: './kubeos-image-creation.md' +--- \ No newline at end of file diff --git a/docs/en/25.03/Cloud/KubeOS/KubeOS/about-kubeos.md b/docs/en/25.03/Cloud/KubeOS/KubeOS/about-kubeos.md new file mode 100644 index 0000000000000000000000000000000000000000..ae57ffb2d09fb8338cf9e18b9abe1fa061474db2 --- /dev/null +++ b/docs/en/25.03/Cloud/KubeOS/KubeOS/about-kubeos.md @@ -0,0 +1,39 @@ +# 认识容器 OS 升级 + +## 概述 + +在云场景中,容器和 kubernetes 的应用越来越广泛。然而,当前对容器和 OS 进行独立管理的方式,往往面临功能冗余、两套调度系统协同困难的问题。另外,OS 的版本管理比较困难,相同版本的 OS 在使用过程中会各自安装、更新、删除软件包,一段时间后 OS 版本变得不一致,导致版本分裂,并且 OS 可能和业务紧耦合,造成大版本升级等比较困难。为了应对上述问题,openEuler 推出了基于openEuler的容器 OS 升级工具。 + +容器 OS 针对业务以容器的形式运行的场景,专门设计的一种轻量级操作系统。基于openEuler的容器 OS 升级工具将容器 OS 作为组件接入 kubernetes,使容器 OS 和业务处于同等地位,通过 kubernetes 集群统一管理容器和容器 OS,实现一套系统管理容器和OS。 + +openEuler 容器 OS 升级工具通过 kubernetes operator 扩展机制控制容器 OS 的升级流程,对容器 OS 进行整体升级,从而实现 OS 管理器和业务协同,该升级方式会在容器 OS 升级前,将业务迁移到其他非升级节点,减少 OS 升级、配置过程中对业务的影响。该升级方式是对容器 OS 进行原子升级,使 OS 一直向预想的状态同步,保证集群里的 OS 版本一致,避免版本分裂问题。 + +## 架构介绍 + +### 容器 OS 升级架构 + +**图1** 容器 OS 升级架构 + +![](./figures/容器OS架构.png) + +如图所示,容器 OS 主要包含三个组件 os-operator,os-proxy 和 os-agent 。os-operator 和 os-proxy 运行在容器中,部署在 kubernetes 集群内;os-agent 不属于集群,直接作为进程运行在 Worker Node 中。 + +- os-operator:全局的容器 OS 管理器,持续查看所有节点的容器 OS 版本信息,并根据用户配置的信息控制同时进行升级的节点个数,并标记准备升级的节点。 + +- os-proxy:单节点的 OS 管理器,持续查看当前节点的容器 OS 版本信息。如果当前节点被 os-operator 标记为准备升级的节点后,锁定节点并驱逐 pod,转发升级信息到 os-agent 。 + +- os-agent:接收来自 proxy 的信息,从 OSImage Server 下载用于更新的容器 OS 镜像,然后进行升级并重启节点。 + +### 容器 OS 文件系统 + +**图 2** 容器 OS 文件系统布局 + +![](./figures/容器OS文件布局.png) + +如图所示,容器 OS 包含四个分区: + +- boot 分区:grub2文件分区 +- Persist 分区:用于存放持久性用户数据,容器 OS 升级时,该分区的数据也会保留。 +- 两个 root 分区:容器 OS 采用双分区模式,将 root 分区划分为 rootA 和 rootB。假定初始化时,系统运行在 rootA 分区上,当进行系统更新时,会下载新系统到 rootB 分区,grub会有两个启动项分别为A,B,将 grub 默认启动项设置为B,最后会重启虚拟机。虚拟机启动后容器 OS 将运行在刚更新过的 rootB 分区上。 + +容器OS的root文件系统为只读,用户的持久化数据存放在Persist持久化数据分区 。 diff --git "a/docs/en/25.03/Cloud/KubeOS/KubeOS/figures/\345\256\271\345\231\250OS\346\226\207\344\273\266\345\270\203\345\261\200.png" "b/docs/en/25.03/Cloud/KubeOS/KubeOS/figures/\345\256\271\345\231\250OS\346\226\207\344\273\266\345\270\203\345\261\200.png" new file mode 100644 index 0000000000000000000000000000000000000000..7dfdcb3aaef79462ecc196159659b22cb21b9a9d Binary files /dev/null and "b/docs/en/25.03/Cloud/KubeOS/KubeOS/figures/\345\256\271\345\231\250OS\346\226\207\344\273\266\345\270\203\345\261\200.png" differ diff --git "a/docs/en/25.03/Cloud/KubeOS/KubeOS/figures/\345\256\271\345\231\250OS\346\236\266\346\236\204.png" "b/docs/en/25.03/Cloud/KubeOS/KubeOS/figures/\345\256\271\345\231\250OS\346\236\266\346\236\204.png" new file mode 100644 index 0000000000000000000000000000000000000000..626071e62735bab2e33ec2a6f1a5839409d33319 Binary files /dev/null and "b/docs/en/25.03/Cloud/KubeOS/KubeOS/figures/\345\256\271\345\231\250OS\346\236\266\346\236\204.png" differ diff --git a/docs/en/25.03/Cloud/KubeOS/KubeOS/installation-and-deployment.md b/docs/en/25.03/Cloud/KubeOS/KubeOS/installation-and-deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..c4f8ffcbb1706a72dcde655a804524b337e68091 --- /dev/null +++ b/docs/en/25.03/Cloud/KubeOS/KubeOS/installation-and-deployment.md @@ -0,0 +1,183 @@ +# 安装与部署 + +本章介绍如何安装和部署容器 OS 升级工具。 + +## 软硬件要求 + +### 硬件要求 + +- 当前仅支持 x86和 AArch64 架构 + +### 软件要求 + +- 操作系统:openEuler 24.09 + +### 环境准备 + +- 安装 openEuler 系统,安装方法参考《[安装指南](../../../Server/InstallationUpgrade/Installation/installation.md)》 +- 安装 qemu-img,bc,parted,tar,yum,docker,dosfstools + +## 安装容器OS升级工具 + +安装容器 OS 升级工具的操作步骤如下: + +1. 配置 openEuler 24.09 yum 源: + + ```conf + [openEuler24.09] # openEuler 24.09 官方发布源 + name=openEuler24.09 + baseurl=http://repo.openeuler.org/openEuler-24.09/everything/$basearch/ + enabled=1 + gpgcheck=1 + gpgkey=http://repo.openeuler.org/openEuler-24.09/everything/$basearch/RPM-GPG-KEY-openEuler + ``` + +2. 使用 root 帐户安装容器 OS 升级工具: + + ```shell + # yum install KubeOS KubeOS-scripts -y + ``` + +> ![](./public_sys-resources/icon-note.gif)**说明**: +> +> 容器 OS 升级工具会安装在 /opt/kubeOS 目录下,包括os-operator,os-proxy,os-agent二进制,制作容器 OS 工具及相应配置文件 。 + +## 部署容器OS升级工具 + +容器OS升级工具安装完成后,需要对此进行配置部署,本章介绍如何配置和部署容器OS升级工具。 + +### 制作os-operator和os-proxy镜像 + +#### 环境准备 + +使用 Docker 制作容器镜像,请先确保 Docker 已经安装和配置完成。 + +#### 操作步骤 + +1. 进入工作目录。 + + ```shell + cd /opt/kubeOS + ``` + +2. 指定 proxy 的镜像仓库、镜像名及版本。 + + ```shell + export IMG_PROXY=your_imageRepository/os-proxy_imageName:version + ``` + +3. 指定 operator 的镜像仓库、镜像名及版本。 + + ```shell + export IMG_OPERATOR=your_imageRepository/os-operator_imageName:version + ``` + +4. 请用户自行编写Dockerfile来构建镜像 ,Dockfile编写请注意以下几项 + + - os-operator和os-proxy镜像需要基于baseimage进行构建,请用户保证baseimage的安全性 + - 需将os-operator和os-proxy二进制文件分别拷贝到对应的镜像中 + - 请确保os-proxy镜像中os-proxy二进制文件件属主和属组为root,文件权限为500 + - 请确保os-operator镜像中os-operator二进制文件属主和属组为容器内运行os-operator进程的用户,文件权限为500 + - os-operator和os-proxy的二进制文件在镜像内的位置和容器启动时运行的命令需与部署的yaml中指定的字段相对应。 + + Dockerfile示例如下 + + ```shell + FROM your_baseimage + COPY ./bin/proxy /proxy + ENTRYPOINT ["/proxy"] + ``` + + ```shell + FROM your_baseimage + COPY --chown=6552:6552 ./bin/operator /operator + ENTRYPOINT ["/operator"] + ``` + + Dockerfile也可以使用多阶段构建。 + +5. 构建容器镜像(os-operator 和 os-proxy 镜像)。 + + ```shell + # 指定proxy的Dockerfile地址 + export DOCKERFILE_PROXY=your_dockerfile_proxy + # 指定operator的Dockerfile路径 + export DOCKERFILE_OPERATOR=your_dockerfile_operator + # 镜像构建 + docker build -t ${IMG_OPERATOR} -f ${DOCKERFILE_OPERATOR} . + docker build -t ${IMG_PROXY} -f ${DOCKERFILE_PROXY} . + ``` + +6. 将容器镜像 push 到镜像仓库。 + + ```shell + docker push ${IMG_OPERATOR} + docker push ${IMG_PROXY} + ``` + +### 制作容器OS虚拟机镜像 + +#### 注意事项 + +- 以虚拟机镜像为例,如需进行物理机的镜像制作请见《容器OS镜像制作指导》 +- 制作容器OS 镜像需要使用 root 权限 +- 容器OS 镜像制作工具的 rpm 包源为 openEuler 具体版本的 everything 仓库和 EPOL 仓库。制作镜像时提供的 repo 文件中,yum 源建议同时配置 openEuler 具体版本的 everything 仓库和 EPOL 仓库 +- 使用默认 rpmlist 制作的容器OS虚拟机镜像,默认和制作工具保存在相同路径,该分区至少有 25GiB 的剩余磁盘空间 +- 制作容器 OS 镜像时,不支持用户自定义配置挂载文件 + +#### 操作步骤 + +制作容器OS 虚拟机镜像使用 kbimg.sh 脚本,命令详情请见《容器OS镜像制作指导》 + +制作容器OS 虚拟机镜像的步骤如下: + +1. 进入执行目录: + + ```shell + cd /opt/kubeOS/scripts + ``` + +2. 执行 kbming.sh 制作容器OS,参考命令如下: + + ```shell + bash kbimg.sh create vm-image -p xxx.repo -v v1 -b ../bin/os-agent -e '''$1$xyz$RdLyKTL32WEvK3lg8CXID0''' + ``` + + 其中 xx.repo 为制作镜像所需要的 yum 源,yum 源建议配置为 openEuler 具体版本的 everything 仓库和 EPOL 仓库。 + + 容器 OS 镜像制作完成后,会在 /opt/kubeOS/scripts 目录下生成: + + - raw格式的系统镜像system.img,system.img大小默认为20G,支持的根文件系统分区大小<2560MiB,持久化分区<14GB。 + - qcow2 格式的系统镜像 system.qcow2。 + - 可用于升级的根文件系统分区镜像 update.img。 + + 制作出来的容器 OS 虚拟机镜像目前只能用于 CPU 架构为 x86 和 AArch64 的虚拟机场景,不支持 x86 架构的虚拟机使用 legacy 启动模式启动。 + +### 部署CRD,operator和proxy + +#### 注意事项 + +- 请先部署 Kubernetes 集群,部署方法参考《openEuler 24.09 Kubernetes 集群部署指南》 + +- 集群中准备进行升级的 Worker 节点的 OS 需要为使用上一节方式制作出来的容器 OS,如不是,请用 system.qcow2重新部署虚拟机,虚拟机部署请见《openEuler 24.09 虚拟化用户指南》,Master节点目前不支持容器 OS 升级,请用openEuler 24.09部署Master节点 +- 部署 OS 的 CRD(CustomResourceDefinition),os-operator,os-proxy 以及 RBAC (Role-based access control) 机制的 YAML 需要用户自行编写。 +- operator 和 proxy 部署在 kubernetes 集群中,operator 应部署为 deployment,proxy 应部署为damonset +- 尽量部署好 kubernetes 的安全措施,如 rbac 机制,pod 的 service account 和 security policy 配置等 + +#### 操作步骤 + +1. 准备 YAML 文件,包括用于部署 OS 的CRD、RBAC 机制、os- operator 和os- proxy 的 YAML 文件,可参考[yaml-example](https://gitee.com/openeuler/KubeOS/tree/master/docs/example/config)。假设分别为 crd.yaml、rbac.yaml、manager.yaml 。 + +2. 部署 CRD、RBAC、os-operator 和 os-proxy。假设 crd.yaml、rbac.yaml、manager.yaml 文件分别存放在当前目录的 config/crd、config/rbac、config/manager 目录下 ,参考命令如下: + + ```shell + kubectl apply -f config/crd + kubectl apply -f config/rbac + kubectl apply -f config/manager + ``` + +3. 部署完成后,执行以下命令,确认各个组件是否正常启动。如果所有组件的 STATUS 为 Running,说明组件已经正常启动。 + + ```shell + kubectl get pods -A + ``` diff --git a/docs/en/25.03/Cloud/KubeOS/KubeOS/kubeos-image-creation.md b/docs/en/25.03/Cloud/KubeOS/KubeOS/kubeos-image-creation.md new file mode 100644 index 0000000000000000000000000000000000000000..21b229b3a3c234167609ae87d3253d444dcfae99 --- /dev/null +++ b/docs/en/25.03/Cloud/KubeOS/KubeOS/kubeos-image-creation.md @@ -0,0 +1,169 @@ +# 容器OS镜像制作指导 + +## 简介 + +kbimg是KubeOS部署和升级所需的镜像制作工具,可以使用kbimg制作KubeOS docker,虚拟机和物理机镜像。 + +## 命令介绍 + +### 命令格式 + +**bash kbimg.sh** \[ --help | -h \] create \[ COMMANDS \] \[ OPTIONS \] + +### 参数说明 + +* COMMANDS + + | 参数 | 描述 | + | ------------- | ---------------------------------------------- | + | upgrade-image | 生成用于安装和升级的OCI镜像格式的 KubeOS 镜像 | + | vm-image | 生成用于部署和升级的虚拟机镜像 | + | pxe-image | 生成物理机安装所需的镜像及文件 | + +* OPTIONS + + | 参数 | 描述 | + | ------------ | ------------------------------------------------------------ | + | -p | repo 文件的路径,repo 文件中配置制作镜像所需要的 yum 源 | + | -v | 制作出来的KubeOS镜像的版本 | + | -b | os-agent二进制的路径 | + | -e | KubeOS 镜像 root 用户密码,加密后的带盐值的密码,可以用 openssl,kiwi 命令生成 | + | -d | 生成或者使用的 docke r镜像 | + | -h --help | 查看帮助信息 | + +## 使用说明 + +### 注意事项 + +* kbimg.sh 执行需要 root 权限 +* 当前仅支持 x86和 AArch64 架构使用 +* 容器 OS 镜像制作工具的 rpm 包源为 openEuler 具体版本的 everything 仓库和 EPOL 仓库。制作镜像时提供的 repo 文件中,yum 源建议同时配置 openEuler 具体版本的 everything 仓库和 EPOL 仓库 + +### KubeOS OCI 镜像制作 + +#### 注意事项 + +* 制作的 OCI 镜像仅用于后续的虚拟机/物理机镜像制作或升级使用,不支持启动容器 +* 使用默认 rpmlist 进行容器OS镜像制作时所需磁盘空间至少为6G,如自已定义 rpmlist 可能会超过6G + +#### 使用示例 + +* 如需进行DNS配置,请先在```scripts```目录下自定义```resolv.conf```文件 + +```shell + cd /opt/kubeOS/scripts + touch resolv.conf + vim resolv.conf +``` + +* 制作KubeOS容器镜像 + +``` shell +cd /opt/kubeOS/scripts +bash kbimg.sh create upgrade-image -p xxx.repo -v v1 -b ../bin/os-agent -e '''$1$xyz$RdLyKTL32WEvK3lg8CXID0''' -d your_imageRepository/imageName:version +``` + +* 制作完成后查看制作出来的KubeOS容器镜像 + +``` shell +docker images +``` + +### KubeOS 虚拟机镜像制作 + +#### 注意事项 + +* 如使用 docker 镜像制作请先拉取相应镜像或者先制作docker镜像,并保证 docker 镜像的安全性 +* 制作出来的容器 OS 虚拟机镜像目前只能用于 CPU 架构为 x86 和 AArch64 的虚拟机 +* 容器 OS 目前不支持 x86 架构的虚拟机使用 legacy 启动模式启动 +* 使用默认rpmlist进行容器OS镜像制作时所需磁盘空间至少为25G,如自已定义rpmlist可能会超过25G + +#### 使用示例 + +* 使用repo源制作 + * 如需进行DNS配置,请先在```scripts```目录下自定义```resolv.conf```文件 + + ```shell + cd /opt/kubeOS/scripts + touch resolv.conf + vim resolv.conf + ``` + + * KubeOS虚拟机镜像制作 + + ``` shell + cd /opt/kubeOS/scripts + bash kbimg.sh create vm-image -p xxx.repo -v v1 -b ../bin/os-agent -e '''$1$xyz$RdLyKTL32WEvK3lg8CXID0''' + ``` + +* 使用docker镜像制作 + + ``` shell + cd /opt/kubeOS/scripts + bash kbimg.sh create vm-image -d your_imageRepository/imageName:version + ``` + +* 结果说明 + 容器 OS 镜像制作完成后,会在 /opt/kubeOS/scripts 目录下生成: + * system.qcow2: qcow2 格式的系统镜像,大小默认为 20GiB,支持的根文件系统分区大小 < 2020 MiB,持久化分区 < 16GiB 。 + * update.img: 用于升级的根文件系统分区镜像 + +### KubeOS 物理机安装所需镜像及文件制作 + +#### 注意事项 + +* 如使用 docker 镜像制作请先拉取相应镜像或者先制作 docker 镜像,并保证 docker 镜像的安全性 +* 制作出来的容器 OS 物理安装所需的镜像目前只能用于 CPU 架构为 x86 和 AArch64 的物理机安装 +* Global.cfg配置中指定的ip为安装时使用的临时ip,请在系统安装启动后请参考《openEuler 22.09 管理员指南-配置网络》进行网络配置 +* 不支持多个磁盘都安装KubeOS,可能会造成启动失败或挂载紊乱 +* 容器OS 目前不支持 x86 架构的物理机使用 legacy 启动模式启动 +* 使用默认rpmlist进行镜像制作时所需磁盘空间至少为5G,如自已定义 rpmlist 可能会超过5G + +#### 使用示例 + +* 首先需要修改```00bootup/Global.cfg```的配置,对相关参数进行配置,参数均为必填,ip目前仅支持ipv4,配置示例如下 + + ```shell + # rootfs file name + rootfs_name=kubeos.tar + # select the target disk to install kubeOS + disk=/dev/sda + # pxe server ip address where stores the rootfs on the http server + server_ip=192.168.1.50 + # target machine temporary ip + local_ip=192.168.1.100 + # target machine temporary route + route_ip=192.168.1.1 + # target machine temporary netmask + netmask=255.255.255.0 + # target machine netDevice name + net_name=eth0 + ``` + +* 使用 repo 源制作 + * 如需进行DNS配置,请在```scripts```目录下自定义```resolv.conf```文件 + + ```shell + cd /opt/kubeOS/scripts + touch resolv.conf + vim resolv.conf + ``` + + * KubeOS物理机安装所需镜像制作 + + ```shell + cd /opt/kubeOS/scripts + bash kbimg.sh create pxe-image -p xxx.repo -v v1 -b ../bin/os-agent -e '''$1$xyz$RdLyKTL32WEvK3lg8CXID0''' + ``` + +* 使用 docker 镜像制作 + + ``` shell + cd /opt/kubeOS/scripts + bash kbimg.sh create pxe-image -d your_imageRepository/imageName:version + ``` + +* 结果说明 + + * initramfs.img: 用于pxe启动用的 initramfs 镜像 + * kubeos.tar: pxe安装所用的 OS diff --git a/docs/en/25.03/Cloud/KubeOS/KubeOS/overview.md b/docs/en/25.03/Cloud/KubeOS/KubeOS/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..3b9405aa48795ce6ede124d3aa67b17f00c590d9 --- /dev/null +++ b/docs/en/25.03/Cloud/KubeOS/KubeOS/overview.md @@ -0,0 +1,8 @@ +# 容器OS升级指南 + +本文档介绍基于openEuler系统的容器OS升级特性的安装部署和使用方法,容器OS升级是使OS可以通过标准扩展方式接入调度系统,通过调度系统管理集群内节点的OS的升级。 + +本文档适用于使用openEuler系统并希望了解和使用容器OS的社区开发者、开源爱好者以及相关合作伙伴。使用人员需要具备以下经验和技能: + +* 熟悉Linux基本操作。 +* 对kubernetes和docker有一定了解 diff --git a/docs/en/25.03/Cloud/KubeOS/KubeOS/public_sys-resources/icon-note.gif b/docs/en/25.03/Cloud/KubeOS/KubeOS/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Cloud/KubeOS/KubeOS/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Cloud/KubeOS/KubeOS/usage-instructions.md b/docs/en/25.03/Cloud/KubeOS/KubeOS/usage-instructions.md new file mode 100644 index 0000000000000000000000000000000000000000..ad0d0294a900e713929149665255a4c4b7b9f7db --- /dev/null +++ b/docs/en/25.03/Cloud/KubeOS/KubeOS/usage-instructions.md @@ -0,0 +1,503 @@ +# 使用方法 + +## 注意事项 + +- 公共注意事项 + - 仅支持虚拟机和物理机x86和arm64 UEFI场景。 + - 使用kubectl apply通过YAML创建或更新OS的CR时,不建议并发apply,当并发请求过多时,kube-apiserver会无法处理请求导致失败。 + - 如用户配置了容器镜像仓的证书或密钥,请用户保证证书或密钥文件的权限最小。 +- 升级注意事项 + - 升级为所有软件包原子升级,默认不提供单包升级能力。 + - 升级为双区升级的方式,不支持更多分区数量。 + - 当前暂不支持跨大版本升级。 + - 单节点的升级过程的日志可在节点的 /var/log/messages 文件查看。 + - 请严格按照提供的升级和回退流程进行操作,异常调用顺序可能会导致系统无法升级或回退。 + - 节点上containerd如需配置ctr使用的私有镜像,请将配置文件host.toml按照ctr指导放在/etc/containerd/certs.d目录下。 + - 使用OCI 镜像升级和mtls双向认证仅支持 openEuler 22.09 及之后的版本 + - nodeselector、executionmode、timewindow和timeinterval 仅支持openEuler 24.09及之后版本 + - KubeOS 24.09 版本与历史版本不兼容 + +- 配置注意事项 + - 用户自行指定配置内容,用户需保证配置内容安全可靠 ,尤其是持久化配置(kernel.sysctl.persist、grub.cmdline.current、grub.cmdline.next),KubeOS不对参数有效性进行检验。 + - opstype=config时,若osversion与当前集群节点的OS版本不一致,配置不会进行。 + - 当前仅支持kernel参数临时配置(kernel.sysctl)、持久化配置(kernel.sysctl.persist)和grub cmdline配置(grub.cmdline.current和grub.cmdline.next)。 + - 持久化配置会写入persist持久化分区,升级重启后配置保留;kernel参数临时配置重启后不保留。 + - 配置grub.cmdline.current或grub.cmdline.next时,如为单个参数(非key=value格式参数),请指定key为该参数,value为空。 + - 进行配置删除(operation=delete)时,key=value形式的配置需保证key、value和实际配置一致。 + - 配置不支持回退,如需回退,请修改配置版本和配置内容,重新下发配置。 + - 配置出现错误,节点状态陷入config时,请将配置版本恢复成上一版本并重新下发配置,从而使节点恢复至idel状态。 但是请注意:出现错误前已经配置完成的参数无法恢复。 + - 在配置grub.cmdline.current或grub.cmdline.next时,若需要将已存在的“key=value”格式的参数更新为只有key无value格式,比如将“rd.info=0”更新成rd.info,需要先删除“key=value”,然后在下一次配置时,添加key。不支持直接更新或者更新删除动作在同一次完成。 + +## OS CR参数说明 + +在集群中创建类别为OS的定制对象,设置相应字段。类别OS来自于安装和部署章节创建的CRD对象,字段及说明如下: + +- imageurl指定的地址里包含协议,只支持http或https协议。imageurl为https协议时为安全传输,imageurl为http地址时,需指定flagSafe为true,即用户明确该地址为安全时,才会下载镜像。如imageurl为http地址且没有指定flagSafe为true,默认该地址不安全,不会下载镜像并且在升级节点的日志中提示用户该地址不安全。 +- 对于imageurl,推荐使用https协议,使用https协议需要升级的机器已安装相应证书。如果镜像服务器由用户自己维护,需要用户自己进行签名,并保证升级节点已安装对应证书。用户需要将证书放在容器OS```/etc/KubeOS/certs```目录下。地址由管理员传入,管理员应该保证网址的安全性,推荐采用内网地址。 +- 容器OS镜像的合法性检查需要由容器OS镜像服务提供者做合法性检查,确保下载的容器OS镜像来源可靠。 +- 集群存在多OS版本即存在多个OS的实例时,OS的nodeselector字段需要与其他OS不同,即通过label区分的一类node只能对应一个OS实例: + - 当有OS的nodeselector为all-label时,集群只能存在这一个OS的有效实例(有效实例为存在与这个OS对应的节点)。 + - nodeselector不配置的OS也只能有一个,因为nodeselector不配置时认为是对没有label的节点进行操作。 +- timewinterval参数说明: + - 参数不设置时默认为15s。 + - 参数设置为0时,由于k8s controller-runtime的rate limit限制,operator下发任务的时间间隔会逐渐增加直至1000s。 + - 并行时为每批次operator下发升级/配置的时间间隔。 + - 在串行时为每批次节点串行升级完毕后与下次升级/配置下发的时间间隔,批次内部的时间间隔为15s。 + - OS的实例字段进行更新会立刻触发operator。 + + | 参数 |参数类型 | 参数说明 | 使用说明 | 是否必选 | + | -------------- | ------ | ------------------------------------------------------------ | ----- | ---------------- | + | imagetype | string | 升级镜像的类型 | 仅支持docker ,containerd ,或者是 disk,仅在升级场景有效。**注意**:若使用containerd,agent优先使用crictl工具拉取镜像,没有crictl时才会使用ctr命令拉取镜像。使用ctr拉取镜像时,镜像如果在私有仓内,需按照[官方文档](https://github.com/containerd/containerd/blob/main/docs/hosts.md)在/etc/containerd/certs.d目录下配置私有仓主机信息,才能成功拉取镜像。 |是 | + | opstype | string | 操作类型:升级,回退或者配置 | 仅支持upgrade ,config 或者 rollback |是 | + | osversion | string | 升级/回退的目标版本 | osversion需与节点的目标os版本对应(节点上/etc/os-release中PRETTY_NAME字段或k8s检查到的节点os版本) 例如:KubeOS 1.0.0。 |是 | + | maxunavailable | int | 每批同时进行升级/回退/配置的节点数。 | maxunavailable值大于实际节点数时,取实际节点数进行升级/回退/配置。 |是 | + | containerimage | string | 用于升级的容器镜像 | 仅在imagetype是容器类型时生效,仅支持以下3种格式的容器镜像地址: repository/name repository/name@sha256:xxxx repository/name:tag |是 | + | imageurl | string | 用于升级的磁盘镜像的地址 | imageurl中包含协议,只支持http或https协议,例如:```https://192.168.122.15/update.img``` ,仅在使用磁盘镜像升级场景下有效 |是 | + | checksum | string | 用于升级的磁盘镜像校验的checksum(SHA-256)值或者是用于升级的容器镜像的digests值 | 仅在升级场景下有效 |是 | + | flagSafe | bool | 当imageurl的地址使用http协议表示是否是安全的 | 需为 true 或者 false ,仅在imageurl使用http协议时有效 |是 | + | mtls | bool | 用于表示与imageurl连接是否采用https双向认证 | 需为 true 或者 false ,仅在imageurl使用https协议时有效|是 | + | cacert | string | https或者https双向认证时使用的根证书文件 | 仅在imageurl使用https协议时有效| imageurl使用https协议时必选 | + | clientcert | string | https双向认证时使用的客户端证书文件 | 仅在使用https双向认证时有效|mtls为true时必选 | + | clientkey | string | https双向认证时使用的客户端公钥 | 仅在使用https双向认证时有效|mtls为true时必选 | + | evictpodforce | bool | 升级/回退时是否强制驱逐pod | 需为 true 或者 false ,仅在升级或者回退时有效| 必选 | + | sysconfigs | / | 配置设置 | 1. “opstype=config”时只进行配置。
2.“opstype=upgrade/rollback”时,代表升级/回退后配置,即在升级/回退重启后进行配置,详细字段说明请见[配置(Settings)指导](#配置settings指导) | “opstype=config”时必选 | + | upgradeconfigs | / | 升级前配置设置 | 在升级或者回退时有效,在升级或者回退操作之前起效,详细字段说明请见[配置(Settings)指导](#配置settings指导)| 可选 | + | nodeselector | string | 需要进行升级/配置/回滚操作的节点label | 用于只对具有某些特定label的节点而不是集群所有worker节点进行运维的场景,需要进行运维操作的节点需要包含key为upgrade.openeuler.org/node-selector的label,nodeselector为该label的value值。
注意事项:
1.此参数不配置时,或者配置为“no-label”时对没有upgrade.openeuler.org/node-selector的节点进行操作
2.此参数为“”时,对具有upgrade.openeuler.org/node-selector=“”的节点进行操作
3.如需忽略label,对所有节点进行操作,需指定此参数为all-label| 可选 | + | timewindow | / | 升级/配置/回滚操作的时间窗口 |1.指定时间窗口时starttime和endtime都需指定,即二者需要同时为空或者同时不为空
2.starttime和endtime类型为string,需要为YYYY-MM-DD HH:MM:SS格式或者HH:MM:SS格式,且二者格式需一致
3.为HH:MM:SS格式时,starttime \< endtime认为starttime是下一天的该时间
4.timewindow不配置时默认为不存在时间窗限制| 可选 | + | timeinterval | int | 升级/配置/回滚操作每批次任务下发的时间间隔 |参数单位为秒,时间间隔为operator下发任务的时间间隔,如k8s集群繁忙无法立即响应operator请求,实际时间间隔可能会大于指定时间| 可选 | + | executionmode | string | 升级/配置/回滚操作执行的方式 |仅支持serial或者parallel,即串行或者并行,当次参数不设置时,默认采用并行的方式| 可选 | + +## 升级指导 + +1. 编写YAML文件,在集群中部署 OS 的cr实例,用于部署cr实例的YAML示例如下,假定将上面的YAML保存到upgrade_v1alpha1_os.yaml; + + - 使用磁盘镜像进行升级 + + ```yaml + apiVersion: upgrade.openeuler.org/v1alpha1 + kind: OS + metadata: + name: os-sample + spec: + imagetype: disk + opstype: upgrade + osversion: edit.os.version + maxunavailable: edit.node.upgrade.number + containerimage: "" + evictpodforce: true/false + imageurl: edit.image.url + checksum: image.checksum + flagSafe: imageurl.safety + mtls: imageurl use mtls or not + cacert: ca certificate + clientcert: client certificate + clientkey: client certificate key + ``` + + - 使用容器镜像进行升级 + - 使用容器镜像进行升级前请先制作升级所需的容器镜像,制作方式请见[《容器OS镜像制作指导》](./kubeos-image-creation.md)中 [KubeOS OCI 镜像制作](./kubeos-image-creation.md#kubeos-oci-镜像制作) + - 节点容器引擎为docker + + ```shell + apiVersion: upgrade.openeuler.org/v1alpha1 + kind: OS + metadata: + name: os-sample + spec: + imagetype: docker + opstype: upgrade + osversion: edit.os.version + maxunavailable: edit.node.upgrade.number + containerimage: container image like repository/name:tag + evictpodforce: true/false + imageurl: "" + checksum: container image digests + flagSafe: false + mtls: true + ``` + + - 节点容器引擎为containerd + + ```yaml + apiVersion: upgrade.openeuler.org/v1alpha1 + kind: OS + metadata: + name: os-sample + spec: + imagetype: containerd + opstype: upgrade + osversion: edit.os.version + maxunavailable: edit.node.upgrade.number + containerimage: container image like repository/name:tag + evictpodforce: true/false + imageurl: "" + checksum: container image digests + flagSafe: false + mtls: true + ``` + + - 升级并且进行配置的示例如下 + - 以节点容器引擎为containerd为例,升级方式对配置无影响,upgradeconfigs在升级前起效,sysconfigs在升级后起效,配置参数说明请见[配置(Settings)指导](#配置settings指导) + - 升级并且配置时opstype字段需为upgrade + - upgradeconfig为升级之前执行的配置,sysconfigs为升级机器重启后执行的配置,用户可按需进行配置 + + ```yaml + apiVersion: upgrade.openeuler.org/v1alpha1 + kind: OS + metadata: + name: os-sample + spec: + imagetype: "" + opstype: upgrade + osversion: edit.os.version + maxunavailable: edit.node.upgrade.number + containerimage: "" + evictpodforce: true/false + imageurl: "" + checksum: container image digests + flagSafe: false + mtls: false + sysconfigs: + version: edit.os.version + configs: + - model: kernel.sysctl + contents: + - key: kernel param key1 + value: kernel param value1 + - key: kernel param key2 + value: kernel param value2 + - model: kernel.sysctl.persist + configpath: persist file path + contents: + - key: kernel param key3 + value: kernel param value3 + - key: "" + value: "" + upgradeconfigs: + version: 1.0.0 + configs: + - model: kernel.sysctl + contents: + - key: kernel param key4 + value: kernel param value4 + ``` + + - 设置nodeselector、timewindow、timeinterval、executionmode升级部分节点示例如下 + - 以节点容器引擎为containerd为例,升级方式对节点筛选无影响 + - 需要进行升级的节点需包含key为upgrade.openeuler.org/node-selector的label,nodeselector的值为该label的value,即假定nodeselector值为kubeos,则只对包含upgrade.openeuler.org/node-selector=kubeos的label的worker节点进行升级 + - nodeselector、timewindow、timeinterval、executionmode对配置和回滚同样有效 + - 节点添加label、修改label、删除label和查看label命令示例如下: + + ```shell + # 为节点kubeos-node1增加label + kubectl label nodes kubeos-node1 upgrade.openeuler.org/node-selector=kubeos-v1 + # 修改节点kubeos-node1的label + kubectl label --overwrite nodes kubeos-node1 upgrade.openeuler.org/node-selector=kubeos-v2 + # 删除节点kubeos-node1的label + kubectl label nodes kubeos-node1 upgrade.openeuler.org/node-selector- + # 查看节点的label + kubectl get nodes --show-labels + ``` + + - yaml示例如下: + + ```yaml + apiVersion: upgrade.openeuler.org/v1alpha1 + kind: OS + metadata: + name: os-sample + spec: + imagetype: containerd + opstype: upgrade + osversion: edit.os.version + maxunavailable: edit.node.upgrade.number + containerimage: container image like repository/name:tag + evictpodforce: true/false + imageurl: "" + checksum: container image digests + flagSafe: false + mtls: true + nodeselector: edit.node.label.key + timewindow: + starttime: "HH::MM::SS/YYYY-MM-DD HH::MM::SS" + endtime: "HH::MM::SS/YYYY-MM-DD HH::MM::SS" + timeinterval: time intervel like 30 + executionmode: serial/parallel + ``` + +2. 查看未升级的节点的 OS 版本 + + ```shell + kubectl get nodes -o custom-columns='NAME:.metadata.name,OS:.status.nodeInfo.osImage' + ``` + +3. 执行命令,在集群中部署cr实例后,节点会根据配置的参数信息进行升级。 + + ```shell + kubectl apply -f upgrade_v1alpha1_os.yaml + ``` + +4. 再次查看节点的 OS 版本来确认节点是否升级完成 + + ```shell + kubectl get nodes -o custom-columns='NAME:.metadata.name,OS:.status.nodeInfo.osImage' + ``` + +5. 如果后续需要再次升级,与上面相同,对upgrade_v1alpha1_os.yaml的相应字段进行修改 + +> ![](./public_sys-resources/icon-note.gif)**说明**: +> +> 如果后续需要再次升级,与上面相同对 upgrade_v1alpha1_os.yaml 的 imageurl ,osversion,checksum,maxunavailable,flagSafe 或者dockerimage字段进行相应修改。 + +## 配置(Settings)指导 + +- Settings参数说明: + + 基于示例YAML对配置的参数进行说明,示例YAML如下,配置的格式(缩进)需和示例保持一致: + + ```yaml + apiVersion: upgrade.openeuler.org/v1alpha1 + kind: OS + metadata: + name: os-sample + spec: + imagetype: "" + opstype: config + osversion: edit.os.version + maxunavailable: edit.node.config.number + containerimage: "" + evictpodforce: false + checksum: "" + sysconfigs: + version: edit.sysconfigs.version + configs: + - model: kernel.sysctl + contents: + - key: kernel param key1 + value: kernel param value1 + - key: kernel param key2 + value: kernel param value2 + operation: delete + - model: kernel.sysctl.persist + configpath: persist file path + contents: + - key: kernel param key3 + value: kernel param value3 + - model: grub.cmdline.current + contents: + - key: boot param key1 + - key: boot param key2 + value: boot param value2 + - key: boot param key3 + value: boot param value3 + operation: delete + - model: grub.cmdline.next + contents: + - key: boot param key4 + - key: boot param key5 + value: boot param value5 + - key: boot param key6 + value: boot param value6 + operation: delete + ``` + + 配置的参数说明如下: + + | 参数 | 参数类型 | 参数说明 | 使用说明 | 配置中是否必选 | + | ---------- | -------- | --------------------------- | ------------------------------------------------------------ | ----------------------- | + | version | string | 配置的版本 | 通过version是否相等来判断配置是否触发,version为空(为""或者没有值)时同样进行判断,所以不配置sysconfigs/upgradeconfigs时,继存的version值会被清空并触发配置。 | 是 | + | configs | / | 具体配置内容 | 包含具体配置项列表。 | 是 | + | model | string | 配置的类型 | 支持的配置类型请看附录下的[Settings列表](#setting-列表) | 是 | + | configpath | string | 配置文件路径 | 仅在kernel.sysctl.persist配置类型中生效,请看附录下的[Settings列表](#setting-列表)对配置文件路径的说明。 | 否 | + | contents | / | 具体key/value的值及操作类型 | 包含具体配置参数列表。 | 是 | + | key | string | 参数名称 | key不能为空,不能包含"=",不建议配置含空格、tab键的字符串,具体请看附录下的[Settings列表](#setting-列表)中每种配置类型对key的说明。 | 是 | + | value | string | 参数值 | key=value形式的参数中,value不能为空,不建议配置含空格、tab键的字符串,具体请看附录下的[Settings列表](#setting-列表)中对每种配置类型对value的说明。 | key=value形式的参数必选 | + | operation | string | 对参数进行的操作 | 仅对kernel.sysctl.persist、grub.cmdline.current、grub.cmdline.next类型的参数生效。默认为添加或更新。仅支持配置为delete,代表删除已存在的参数(key=value需完全一致才能删除)。 | 否 | + + - upgradeconfigs与sysconfigs参数相同,upgradeconfigs为升级/回退前进行的配置,仅在upgrade/rollback场景起效,sysconfigs既支持只进行配置,也支持在升级/回退重启后进行配置 + +- 使用说明 + + - 编写YAML文件,在集群中部署 OS 的cr实例,用于部署cr实例的YAML示例如上,假定将上面的YAML保存到upgrade_v1alpha1_os.yaml + + - 查看配置之前的节点的配置的版本和节点状态(NODESTATUS状态为idle) + + ```shell + kubectl get osinstances -o custom-columns='NAME:.metadata.name,NODESTATUS:.spec.nodestatus,SYSCONFIG:status.sysconfigs.version,UPGRADECONFIG:status.upgradeconfigs.version' + ``` + + - 执行命令,在集群中部署cr实例后,节点会根据配置的参数信息进行配置,再次查看节点状态(NODESTATUS变成config) + + ```shell + kubectl apply -f upgrade_v1alpha1_os.yaml + kubectl get osinstances -o custom-columns='NAME:.metadata.name,NODESTATUS:.spec.nodestatus,SYSCONFIG:status.sysconfigs.version,UPGRADECONFIG:status.upgradeconfigs.version' + ``` + + - 再次查看节点的配置的版本确认节点是否配置完成(NODESTATUS恢复为idle) + + ```shell + kubectl get osinstances -o custom-columns='NAME:.metadata.name,NODESTATUS:.spec.nodestatus,SYSCONFIG:status.sysconfigs.version,UPGRADECONFIG:status.upgradeconfigs.version' + ``` + +- 如果后续需要再次配置,与上面相同对 upgrade_v1alpha1_os.yaml 的相应字段进行相应修改。 + +## 回退指导 + +- 回退场景 + - 虚拟机无法正常启动时,可在grub启动项页面手动切换启动项,使系统回退至上一版本(即手动回退)。 + - 虚拟机能够正常启动并且进入系统时,支持工具回退和手动回退,建议使用工具回退。 + - 工具回退有两种方式: + 1. rollback模式直接回退至上一版本。 + 2. upgrade模式重新升级至上一版本。 +- 手动回退指导 + - 手动重启虚拟机,进入启动项页面后,选择第二启动项进行回退,手动回退仅支持回退到上一个版本。 +- 工具回退指导 + - 回退至任意版本 + 1. 修改 OS 的cr实例的YAML 配置文件(例如 upgrade_v1alpha1_os.yaml),设置相应字段为期望回退的老版本镜像信息。类别OS来自于安装和部署章节创建的CRD对象,字段说明及示例请见上一节升级指导。 + 2. YAML修改完成后执行更新命令,在集群中更新定制对象后,节点会根据配置的字段信息进行回退 + + ```bash + kubectl apply -f upgrade_v1alpha1_os.yaml + ``` + + - 回退至上一版本 + - OS回退至上一版本:修改upgrade_v1alpha1_os.yaml,设置osversion为上一版本,opstype为rollback,回退至上一版本(即切换至上一分区)。YAML示例如下: + + ```yaml + apiVersion: upgrade.openeuler.org/v1alpha1 + kind: OS + metadata: + name: os-sample + spec: + imagetype: "" + opstype: rollback + osversion: KubeOS previous version + maxunavailable: 2 + containerimage: "" + evictpodforce: true/false + imageurl: "" + checksum: "" + flagSafe: false + mtls: true + ``` + + - 配置回退至上一版本:修改upgrade_v1alpha1_os.yaml,设置sysconfigs/upgradeconfigs的version为上一版本,回退至上一版本(已配置的参数无法回退)。YAML示例如下: + + ```yaml + apiVersion: upgrade.openeuler.org/v1alpha1 + kind: OS + metadata: + name: os-sample + spec: + imagetype: "" + opstype: config + osversion: edit.os.version + maxunavailable: edit.node.config.number + containerimage: "" + evictpodforce: true/false + imageurl: "" + checksum: "" + flagSafe: false + mtls: false + sysconfigs: + version: previous config version + configs: + - model: kernel.sysctl + contents: + - key: kernel param key1 + value: kernel param value1 + - key: kernel param key2 + value: kernel param value2 + - model: kernel.sysctl.persist + configpath: persist file path + contents: + - key: kernel param key3 + value: kernel param value3 + ``` + + - YAML修改完成后执行更新命令,在集群中更新定制对象后,节点会根据配置的字段信息进行回退 + + ```shell + kubectl apply -f upgrade_v1alpha1_os.yaml + ``` + + 更新完成后,节点会根据配置信息回退容器 OS。 + - 查看节点容器 OS 版本(回退OS版本)或节点config版本&节点状态为idle(回退config版本),确认回退是否成功。 + + ```shell + kubectl get osinstances -o custom-columns='NAME:.metadata.name,NODESTATUS:.spec.nodestatus,SYSCONFIG:status.sysconfigs.version,UPGRADECONFIG:status.upgradeconfigs.version' + ``` + +## 附录 + +### Setting 列表 + +#### kernel Settings + +- kernel.sysctl:临时设置内核参数,重启后无效,key/value 表示内核参数的 key/value, key与value均不能为空且key不能包含“=”,该参数不支持删除操作(operation=delete)示例如下: + + ```yaml + configs: + - model: kernel.sysctl + contents: + - key: user.max_user_namespaces + value: 16384 + - key: net.ipv4.tcp_tw_recycle + value: 0 + operation: delete + ``` + +- kernel.sysctl.persist: 设置持久化内核参数,key/value表示内核参数的key/value,key与value均不能为空且key不能包含“=”, configpath为配置文件路径,支持新建(需保证父目录存在),如不指定configpath默认修改/etc/sysctl.conf,示例如下: + + ```yaml + configs: + - model: kernel.sysctl.persist + configpath : /etc/persist.conf + contents: + - key: user.max_user_namespaces + value: 16384 + - key: net.ipv4.tcp_tw_recycle + value: 0 + operation: delete + ``` + +#### Grub Settings + +- grub.cmdline.current/next: 设置grub.cfg文件中的内核引导参数,该行参数在grub.cfg文件中类似如下示例: + + ```shell + linux /boot/vmlinuz root=/dev/sda2 ro rootfstype=ext4 nomodeset quiet oops=panic softlockup_panic=1 nmi_watchdog=1 rd.shell=0 selinux=0 crashkernel=256M panic=3 + ``` + + - KubeOS使用双分区,grub.cmdline.current/next支持对当前分区或下一分区进行配置: + + - grub.cmdline.current:对当前分区的启动项参数进行配置。 + - grub.cmdline.next:对下一分区的启动项参数进行配置。 + + - 注意:升级/回退前后的配置,始终基于升级/回退操作下发时的分区位置进行current/next的区分。假设当前分区为A分区,下发升级操作并在sysconfigs(升级重启后配置)中配置grub.cmdline.current,重启后进行配置时仍修改A分区对应的grub cmdline。 + + - grub.cmdline.current/next支持“key=value”(value不能为空),也支持单key。若value中有“=”,例如“root=UUID=some-uuid”,key应设置为第一个“=”前的所有字符,value为第一个“=”后的所有字符。 配置方法示例如下: + + ```yaml + configs: + - model: grub.cmdline.current + contents: + - key: selinux + value: "0" + - key: root + value: UUID=e4f1b0a0-590e-4c5f-9d8a-3a2c7b8e2d94 + - key: panic + value: "3" + operation: delete + - key: crash_kexec_post_notifiers + - model: grub.cmdline.next + contents: + - key: selinux + value: "0" + - key: root + value: UUID=e4f1b0a0-590e-4c5f-9d8a-3a2c7b8e2d94 + - key: panic + value: "3" + operation: delete + - key: crash_kexec_post_notifiers + ``` diff --git a/docs/en/25.03/Cloud/NestOS/NestOS/_menu.md b/docs/en/25.03/Cloud/NestOS/NestOS/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..378fcc9f6aa8a731dce93d80ef1f09554be45fec --- /dev/null +++ b/docs/en/25.03/Cloud/NestOS/NestOS/_menu.md @@ -0,0 +1,12 @@ +--- +label: 'NestOS用户指南' +ismanual: 'Y' +description: 'NestOS是为容器化设计的轻量级操作系统,采用双分区院子更新,确保安全可靠' +children: + - label: '概述' + href: './overview.md' + - label: 'NestOS For Container用户指南' + href: './nestos-for-container.md' + - label: '功能特性描述' + href: './feature-description.md' +--- \ No newline at end of file diff --git a/docs/en/25.03/Cloud/NestOS/NestOS/feature-description.md b/docs/en/25.03/Cloud/NestOS/NestOS/feature-description.md new file mode 100644 index 0000000000000000000000000000000000000000..d916f2ba5f73096ca4faa328532f378040d77a0f --- /dev/null +++ b/docs/en/25.03/Cloud/NestOS/NestOS/feature-description.md @@ -0,0 +1,105 @@ +# 功能特性描述 + +## 容器技术 + +NestOS通过容器化 (containerized) 的运算环境向应用程序提供运算资源,应用程序之间共享系统内核和资源,但是彼此之间又互不可见。这意味着应用程序将不会再被直接安装到操作系统中,而是通过 容器引擎(Docker、Podman、iSulad等) 运行在容器中。大大降低了操作系统、应用程序及运行环境之间的耦合度。相对于传统的应用程序部署部署方式而言,在NestOS 集群中部署应用程序更加灵活便捷,应用程序运行环境之间的干扰更少,而且操作系统自身的维护也更加容易。 + +## rpm-ostree + +### 系统更新 + +rpm-ostree是一种镜像/包混合系统,可以看成是rpm和ostree的合体。一方面它提供了基于rpm的软件包安装管理方式,另一方面它提供了基于ostree的操作系统更新升级。rpm-ostree将这两种操作都视为对操作系统的更新,每次对系统的更新都像rpm-ostree在提交“Transaction-事务”,从而确保更新全部成功或全部失败,并且允许在更新系统后回滚到更新前的状态。 + +rpm-ostree在更新操作系统的时候会有2个bootable区域,分别为主动分区和被动分区,对系统的更新升级在被动分区进行,在重启操作系统主动分区和被动分区转换后才生效。如果软件安装或升级出现问题,通过rpm-ostree会使NestOS回滚到先前的状态。NestOS的“/ostree/”和“/boot/”目录是ostree Repository环境,通过该目录可以查看当前boot使用的哪个ostree。 + +### 只读文件系统 + +在rpm-ostree的文件系统布局中,只有/etc和/var是唯一可写的目录,/var中的任何数据不会被触及,而是在升级过程中共享。在系统升级的过程中采用新的缺省值/etc,并将更改添加到顶部。这意味着升级将会接收/etc中新的默认文件,这是一个非常关键的特性。 + +在通用操作系统中,/var目录下的部分文件采用“/var to tmpfiles.d”的处理策略,即系统通过systemd-tmpfile-setup.service读取/usr/lib/tmpfiles.d/目录下的conf文件,完成/var目录下文件夹和空白文件的创建,/usr/lib/tmpfiles.d/目录下的conf文件全部由相关rpm包提供。在NestOS中,/var目录不涉及rpm-ostree的commit分层,rpm-ostree各个commit 分层都会共享一个/var目录,但是/var目录下的文件会与ostree事务更新模型冲突,在安装软件包时rpm-ostree会将该文件删除。/var目录下的内容完全依赖“/var to tmpfiles.d”来生成,因此NestOS的/usr/lib/tmpfiles.d/目录下,除了部分rpm提供出的conf外,还存在由rpm-ostree在安装XXX软件包时生成的pkg-XXX.conf文件(即使XXX已经提供了conf文件),该文件记录了XXX软件包提供的/var下的文件夹,不涉及文件(文件在rpm-ostree安装包时已经删除)。当用户需要对rpm包提供的/var下的文件夹进行操作时,如删除某文件夹,简单的使用rm命令只能暂时删除,当系统重启后,该文件夹依旧存在,只有修改pkg-XXX.conf文件才能完成永久删除。 + +ostree旨在可以并行安装多个独立操作系统的版本,ostree依赖于一个新的ostree 目录,该目录实际上可以并行安装在现有的操作系统或者是占据物理/root目录的发行版本中。每台客户机和每组部署上都存储在 /ostree/deploy/STATEROOT/CHECKSUM 上,而且还有一个ostree Repository存储在 /ostree/repo 中。每个部署主要由一组指向存储库的硬链接组成,这意味着每个版本都进行了重复数据的删除并且升级过程中只消耗了与新文件成比例的磁盘空间加上一些恒定的开销。 + +ostree模型强调的是OS只读内容保存在 /usr 中,它附带了⽤于创建Linux只读安装以防止无意损坏的代码,对于给定的操作系统,每个部署之间都有一个 /var 共享的可供读写的目录。ostree核心代码不触及该目录的内容,如何管理和升级状态取决于每个操作系统中的代码。 + +### 系统扩展 + +出于安全性和可维护性的考虑,NestOS让基础镜像尽可能保持小巧和精简。但是在某些情况下,需要向基本操作系统本⾝添加软件,例如驱动软件,VPN等等,因为它们比较难容器化。这些包拓展了操作系统的功能,为此,rpm-ostree将这些包视为拓展,而不是仅仅在用户运行时提供。也就是说,目前NestOS对于实际安装哪些包没有限制,默认情况下,软件包是从openEuler仓库下载的。 + +要对软件包进行分层,需要重新编写一个systemd单元来执行rpm-ostree命令安装所需要的包,所做的更改应⽤于新部署,重新启动才能⽣效。 + +## nestos-installer + +nestos-installer是一个帮助安装Nestos的程序,它可以执行以下操作: + +(1)安装操作系统到一个目标磁盘,可使用Ignition和首次引导内核参数对其进行自定义(nestos-installer install) + +(2)下载并验证各种云平台、虚拟化或者裸机平台的操作系统映像(nestos-installer download) + +(3)列出可供下载的nestos镜像(nestos-installer list-stream) + +(4)在ISO中嵌入一个Ignition配置,以自定义地从中启动操作系统(nestos-installer iso ignition) + +(5)将Ignition配置包装在initd映像中,该映像可以被加入到PXE initramfs中以自定义从中启动的操作系统(nestos-installer pxe ignition) + +## zincati + +Zincati是NestOS⾃动更新的代理,它作为Cincinnati服务的客户端,负责监听NestOS版本变化并调用rpn-ostree进行⾃动更新。Zincati有如下特点: + +(1)支持自动更新代理,支持分阶段推出 + +(2)通过toml配置文件支持运行时自定义,用户自定义配置文件可覆盖默认配置 + +(3)多种更新策略 + +(4)通过维护窗口每周在特定时间范围内进行更新的策略 + +(5)收集和导出本地运行的zincati内部指标,可提供给Prometheus以减轻跨大量节点的监控任务 + +(6)具有可配置优先级的日志记录 + +(7)通过Cincinnati协议支持复杂的更新图 + +(8)通过外部锁管理器支持集群范围的重启编排 + +## 系统初始化(Ignition) + +Ignition 是一个与分发无关的配置实用程序,不仅用于安装,还读取配置文件(JSON 格式)并根据该配置初始化NestOS。可配置的组件包括存储和文件系统、systemd单元和用户。 + +Ignition仅在系统第一次引导期间运行一次(在initramfs中)。因为 Ignition 在启动过程的早期运行,所以它可以在用户空间开始启动之前重新分区磁盘、格式化文件系统、创建用户和写入文件。 因此,systemd 服务在 systemd 启动时已经写入磁盘,从而加快了启动速度。 + +(1)Ignition 仅在第一次启动时运行 + +Ignition 旨在用作配置工具,而不是配置管理工具。 Ignition 鼓励不可变的基础设施,其中机器修改要求用户丢弃旧节点并重新配置机器。 + +(2)Ignition不是在任何情况下都可以完成配置 + +Ignition 执行它需要的操作,使系统与 Ignition 配置中描述的状态相匹配。 如果由于任何原因 Ignition 无法提供配置要求的确切机器,Ignition 会阻止机器成功启动。例如,如果用户想要获取托管在 的文档并将其写入磁盘,如果无法解析给定的 URL,Ignition 将阻止机器启动。 + +(3)Ignition只是声明性配置 + +Ignition配置只描述了系统的状态,没有列出 Ignition 应该采取的一系列步骤。 + +Ignition 配置不允许用户提供任意逻辑(包括 Ignition 运行的脚本)。用户只需描述哪些文件系统必须存在、哪些文件必须创建、哪些用户必须存在等等。任何进一步的定制都必须使用由 Ignition 创建的 systemd 服务。 + +(4)Ignition配置不应手写 + +Ignition 配置被设计为人类可读但难以编写,是为了阻止用户尝试手动编写配置。可以使用Butane或类似工具生成或转化生成Ignition 配置。 + +## Afterburn + +Afterburn是类似于云平台一样的一次性代理,可以用于与特定的提供者的元数据端点进行交互,通常和Ignition结合使用。 + +Afterburn包含了很多可以在实例生命周期中不同时间段运行的模块。下面是特定的平台可能在第一次启动时在initramfs中运行的服务: + +(1)设置本地主机名 + +(2)加入网络命令行参数 + +以下的功能是在一定条件下,作为systemd服务单元在一些平台上才能使用的: + +(1)为本地系统用户安装公共SSH密钥 + +(2)从实例元数据中检索属性 + +(3)给提供者登记以便报道成功的启动或实例供应 diff --git a/docs/en/25.03/Cloud/NestOS/NestOS/figures/figure1.png b/docs/en/25.03/Cloud/NestOS/NestOS/figures/figure1.png new file mode 100644 index 0000000000000000000000000000000000000000..b4eb9017ed202e854c076802492d8561942dfc88 Binary files /dev/null and b/docs/en/25.03/Cloud/NestOS/NestOS/figures/figure1.png differ diff --git a/docs/en/25.03/Cloud/NestOS/NestOS/figures/figure2.png b/docs/en/25.03/Cloud/NestOS/NestOS/figures/figure2.png new file mode 100644 index 0000000000000000000000000000000000000000..90049769c04e2bd494533da1613e38a5199da3d7 Binary files /dev/null and b/docs/en/25.03/Cloud/NestOS/NestOS/figures/figure2.png differ diff --git a/docs/en/25.03/Cloud/NestOS/NestOS/nestos-for-container.md b/docs/en/25.03/Cloud/NestOS/NestOS/nestos-for-container.md new file mode 100644 index 0000000000000000000000000000000000000000..9b7e0e383245e4c8286966a4332adc721c73a306 --- /dev/null +++ b/docs/en/25.03/Cloud/NestOS/NestOS/nestos-for-container.md @@ -0,0 +1,995 @@ +# NestOS用户使用指南 + +## 1. NestOS介绍 + +### 1.1 前言 + +NestOS是麒麟软件在openEuler社区开源孵化的云底座操作系统,集成了rpm-ostree支持、ignition配置等技术,采用双根文件系统互为主备、原子化更新的设计思路,提供nestos-assembler工具快速集成构建。NestOS针对K8S、OpenStack平台进行适配,优化容器运行底噪,使系统具备十分便捷的集群组建能力,可以更安全的运行大规模的容器化工作负载。 + +本手册将完整阐述从构建、安装部署到使用NestOS的全流程,帮助用户充分利用NestOS的优势,快速高效地完成系统的配置和部署。 + +### 1.2 应用场景与优势 + +NestOS 适合作为以容器化应用为主的云场景基础运行环境,解决了在使用容器技术与容器编排技术实现业务发布、运维时与底层环境高度解耦而带来的运维技术栈不统一,运维平台重复建设等问题,保证了业务与底座操作系统运维的一致性。 + +![figure1](./figures/figure1.png) + +## 2. 环境准备 + +### 2.1 构建环境要求 + +#### 2.1.1 制作构建工具nestos-assembler环境要求 + +- 推荐使用openEuler环境 + +- 剩余可用硬盘空间 > 5G + +#### 2.1.2 构建NestOS环境要求 + +| **类别** | **要求** | +| :------: | :---------------: | +| CPU | 4vcpu | +| 内存 | 4GB | +| 硬盘 | 剩余可用空间>10GB | +| 架构 | x86_64或aarch64 | +| 其他 | 支持kvm | + +### 2.2 部署配置要求 + +| **类别** | **推荐配置** | **最低配置** | +| :------: | :-------------: | :----------: | +| CPU | >4vcpu | 1vcpu | +| 内存 | >4GB | 512M | +| 硬盘 | >20GB | 10GB | +| 架构 | x86_64、aarch64 | / | + +## 3. 快速使用 + +### 3.1 快速构建 + +1)获取nestos-assembler容器镜像 + +推荐使用基于openEuler的base镜像,更多说明请参考6.1 + +```bash +docker pull hub.oepkgs.net/nestos/nestos-assembler:24.03-LTS.20240903.0-aarch64 +``` + +2)编写名为nosa的脚本并存放至/usr/local/bin,并赋予可执行权限 + +```bash +#!/bin/bash + +sudo docker run --rm -it --security-opt label=disable --privileged --user=root \ + -v ${PWD}:/srv/ --device /dev/kvm --device /dev/fuse --network=host \ + --tmpfs /tmp -v /var/tmp:/var/tmp -v /root/.ssh/:/root/.ssh/ -v /etc/pki/ca-trust/:/etc/pki/ca-trust/ \ + ${COREOS_ASSEMBLER_CONFIG_GIT:+-v $COREOS_ASSEMBLER_CONFIG_GIT:/srv/src/config/:ro} \ + ${COREOS_ASSEMBLER_GIT:+-v $COREOS_ASSEMBLER_GIT/src/:/usr/lib/coreos-assembler/:ro} \ + ${COREOS_ASSEMBLER_CONTAINER_RUNTIME_ARGS} \ + ${COREOS_ASSEMBLER_CONTAINER:-nestos-assembler:your_tag} "$@" +``` + +注意修改COREOS_ASSEMBLER_CONTAINER 的值为本地环境中实际的nestos-assembler容器镜像。 + +3)获取nestos-config + +使用nosa init 初始化构建工作目录,拉取构建配置,创建工作目录nestos-build,在该目录下执行如下命令 + +```bash +nosa init https://gitee.com/openeuler/nestos-config +``` + +4)调整构建配置 + +nestos-config提供默认构建配置,无需额外操作。如需调整,请参考第5章。 + +5)NestOS镜像构建 + +```bash +# 拉取构建配置、更新缓存 +nosa fetch +# 生成根文件系统、qcow2及OCI镜像 +nosa build +# 生成live iso及PXE镜像 +nosa buildextend-metal +nosa buildextend-metal4k +nosa buildextend-live +``` + +详细构建及部署流程请参考第6章。 + +### 3.2 快速部署 + +以NestOS ISO镜像为例,启动进入live环境后,执行如下命令根据向导提示完成安装: + +```bash +sudo installnestos +``` + +其他部署方式请参考第8章。 + +## 4. 系统默认配置 + +| **选项** | **默认配置** | +| :-------------: | :---------------------: | +| docker服务 | 默认disable,需主动开启 | +| ssh服务安全策略 | 默认仅支持密钥登录 | + +## 5. 构建配置nestos-config + +### 5.1 获取配置 + +nestos-config的仓库地址为 + +### 5.2 配置目录结构说明 + +| **目录/****文件** | **说明** | +| :---------------: | :--------------------: | +| live/* | 构建liveiso的引导配置 | +| overlay.d/* | 自定义文件配置 | +| tests/* | 用户自定义测试用例配置 | +| *.repo | repo源配置 | +| .yaml,manifests/ | 主要构建配置 | + +### 5.3 主要文件解释 + +#### 5.3.1 repo文件 + +目录下的repo文件可用来配置用于构建nestos的软件仓库。 + +#### 5.3.2 yaml配置文件 + +目录下的yaml文件主要是提供nestos构建的各种配置,详见5.4章节。 + +### 5.4 主要字段解释 + +| **字段名称** | **作用** | +| :------------------------------------------ | ------------------------------------------------------------ | +| packages-aarch64、packages-x86_64、packages | 软件包集成范围 | +| exclude-packages | 软件包集成黑名单 | +| remove-from-packages | 从指定软件包删除文件(夹) | +| remove-files | 删除特定文件(夹) | +| extra-kargs | 额外内核引导参数 | +| initramfs-args | initramfs构建参数 | +| postprocess | 文件系统构建后置脚本 | +| default-target | 配置default-target,如 multi-user.target | +| rolij.name、releasever | 镜像相关信息(镜像名称、版本) | +| lockfile-repos | 构建可使用的仓库名列表,与5.3.1 介绍的repo文件中的仓库名需要对应 | + +### 5.5 用户可配置项说明 + +#### 5.5.1 repo源配置 + +1)在配置目录编辑repo文件,将内容修改为期望的软件仓库 + +```bash +$ vim nestos-pool.repo +[repo_name_1] +Name=xxx +baseurl = https://ip.address/1 +enabled = 1 + +[repo_name_2] +Name=xxx +baseurl = https://ip.address/2 +enabled = 1 +``` + +2)修改yaml配置文件中的lockfile-repo字段内容为相应的仓库名称列表 + +注:仓库名称为repo文件中[]内的内容,不是name字段内容 + +```bash +$ vim manifests/rpmlist.yaml +修改lockfile-repo字段内容为 +lockfile-repos: +- repo_name_1 +- repo_name_2 +``` + +#### 5.5.2 软件包裁剪 + +修改packages、packages-aarch64、packages-x86_64字段,可在其中添加或删除软件包。 + +如下所示,在package字段中添加了nano,构建安装后系统中会有nano 。 + +```bash +$ vim manifests/rpmlist.yaml +packages: +- bootupd +... +- authselect +- nano +... +packages-aarch64: +- grub2-efi-aa64 +packages-x86_64: +- microcode_ctl +- grub2-efi-x64 +``` + +#### 5.5.3 自定义镜像名称与版本号 + +修改yaml文件中的releasever及rolij.name 字段,这些字段分别控制镜像的版本号及名称。 + +```bash +$ vim manifest.yaml + +releasever: "1.0" +rojig: + license: MIT + name: nestos + summary: NestOS stable +``` + +如上配置,构建出的镜像格式为:nestos-1.0.$(date "+%Y%m%d").$build_num.$type,其中build_num为构建次数,type为类型后缀。 + +#### 5.5.4 自定义镜像中的release信息 + +正常release信息是由我们集成的release包(如openeuler-release)提供的,但是我们也可以通过添加postprocess脚本对/etc/os-release文件进行重写操作。 + +```bash +$ vim manifests/ system-configuration.yaml +在postprocess添加如下内容,若已存在相关内容,则只需修改对应release信息即可 +postprocess: + - | + #!/usr/bin/env bash + set -xeuo pipefail + export OSTREE_VERSION="$(tail -1 /etc/os-release)" + date_now=$(date "+%Y%m%d") + echo -e 'NAME="openEuler NestOS"\nVERSION="24.03-LTS"\nID="openeuler"\nVERSION_ID="24.03-LTS"\nPRETTY_NAME="NestOS"\nANSI_COLOR="0;31"\nBUILDID="'${date_now}'"\nVARIANT="NestOS"\nVARIANT_ID="nestos"\n' > /usr/lib/os-release + echo -e $OSTREE_VERSION >> /usr/lib/os-release + cp -f /usr/lib/os-release /etc/os-release +``` + +#### 5.5.5 成自定义文件 + +在overlay.d目录下每个目录进行自定义文件的添加和修改,这种操作可以实现构建镜像内容的自定义。 + +```bash +mkdir -p overlay.d/15nestos/etc/test/test.txt +echo "This is a test message !" > overlay.d/15nestos/etc/test/test.txt +``` + +使用如上配置进行镜像构建,启动构建出的镜像,查看系统中对应文件内容即为我们上述自定义添加的内容。 + +```bash +[root@nosa-devsh ~]# cat /etc/test/test.txt +This is a test message ! +``` + +## 6.构建流程 + +NestOS采用容器化的方式将构建工具链集成为一个完整的容器镜像,称为NestOS-assembler。 + +NestOS提供构建NestOS-assembler容器镜像能力,方便用户使用。使用该容器镜像,用户可在任意linux发行版环境中构建多种形态NestOS镜像(例如在现有CICD环境中使用),也可对构建发布件进行管理、调试和自动化测试。 + +### 6.1 制作构建工具NestOS-assembler容器镜像 + +#### 6.1.1 前置步骤 + +1)准备容器base镜像 + +NestOS-assembler容器镜像需要基于支持yum/dnf软件包管理器的base镜像制作,理论上可由任意发行版base镜像制作,但为最大程度减少软件包兼容性问题,仍推荐使用基于openEuler的base镜像。 + +2)安装必要软件包 + +安装必备依赖docker + +```bash +dnf install -y docker +``` + +3)克隆nestos-assembler源代码仓库 + +```bash +git clone --depth=1 --single-branch https://gitee.com/openeuler/nestos-assembler.git +``` + +#### 6.1.2 构建NestOS-assembler容器镜像 + +使用openEuler容器镜像作为base镜像,使用以下指令构建: + +```bash +cd nestos-assembler/ +docker build -f Dockerfile . -t nestos-assembler:your_tag +``` + +### 6.2 使用NestOS-assembler容器镜像 + +#### 6.2.1 前置步骤 + +1)准备nestos-assembler容器镜像 + +参考6.1章节构建nestos-assembler容器镜像后,可通过私有化部署容器镜像仓库对该容器镜像进行管理和分发。请确保构建NestOS前,拉取适当版本的nestos-assembler容器镜像至当前环境。 + +2)编写使用脚本nosa + +因NestOS构建过程需多次调用nestos-assembler容器镜像执行不同命令,同时需配置较多参数,为简化用户操作,可编写nosa命令脚本,可参见3.1快速构建部分。 + +#### 6.2.2 使用说明 + +构建工具命令一览 + +| **命令** | **功能说明** | +| :-------------------: | :-------------------------------------------------: | +| init | 初始化构建环境及构建配置,详见6.3 | +| fetch | 根据构建配置获取最新软件包至本地缓存 | +| build | 构建ostree commit,是构建NestOS的核心命令 | +| run | 直接启动一个qemu实例,默认使用最新构建版本 | +| prune | 清理历史构建版本,默认保留最新3个版本 | +| clean | 删除全部构建发布件,添加--all参数时同步清理本地缓存 | +| list | 列出当前构建环境中存在的版本及发布件 | +| build-fast | 基于前次构建记录快速构建新版本 | +| push-container | 推送容器镜像发布件至容器镜像仓库 | +| buildextend-live | 构建支持live环境的ISO发布件及PXE镜像 | +| buildextend-metal | 构建裸金属raw发布件 | +| buildextend-metal4k | 构建原生4K模式的裸金属raw发布件 | +| buildextend-openstack | 构建适用于openstack平台的qcow2发布件 | +| buildextend-qemu | 构建适用于qemu的qcow2发布件 | +| basearch | 获得当前架构信息 | +| compress | 压缩发布件 | +| kola | 自动化测试框架 | +| kola-run | 输出汇总结果的自动化测试封装 | +| runc | 以容器方式挂载当前构建根文件系统 | +| tag | 管理构建工程tag | +| virt-install | 通过virt-install为指定构建版本创建实例 | +| meta | 管理构建工程元数据 | +| shell | 进入nestos-assembler容器镜像 | + +### 6.3 准备构建环境 + +NestOS构建环境需要独立的空文件夹作为工作目录,且支持多次构建,保留、管理历史构建版本。创建构建环境前需首先准备构建配置(参考第5章)。 + +建议一份独立维护的构建配置对应一个独立的构建环境,即如果您希望构建多个不同用途的NestOS,建议同时维护多份构建配置及对应的构建环境目录,这样可以保持不同用途的构建配置独立演进和较为清晰的版本管理。 + +#### 6.3.1 初始化构建环境 + +进入待初始化工作目录,执行如下命令即可初始化构建环境: + +```bash +nosa init https://gitee.com/openeuler/nestos-config +``` + +仅首次构建时需初始化构建环境,后续构建在不对构建配置做出重大更改的前提下,可重复使用该构建环境。 + +#### 6.3.2 构建环境说明 + +初始化完成后,工作目录创建出如下文件夹: + +**builds:**构建发布件及元数据存储目录,latest子目录软链接指向最新构建版本。 + +**cache:**缓存目录,根据构建配置中的软件源及软件包列表拉取至本地,历史构建NestOS的ostree repo均缓存于此目录。 + +**overrides:**构建过程希望附加到最终发布件rootfs中的文件或rpm包可置于此目录。 + +**src:**构建配置目录,存放nestos-config相关内容。 + +**tmp:**临时目录,构建过程、自动化测试等场景均会使用该目录作为临时目录,构建发生异常时可在此处查看虚拟机命令行输出、journal日志等信息。 + +### 6.4 构建步骤 + +NestOS构建主要步骤及参考命令如下: + +![figure2](./figures/figure2.png) + +#### 6.4.1 首次构建 + +首次构建时需初始化构建环境,详见6.3。 + +非首次构建可直接使用原构建环境,可通过nosa list查看当前构建环境已存在版本及对应发布件。 + +#### 6.4.2 更新构建配置及缓存 + +初始化构建环境后,执行如下命令更新构建配置及缓存: + +```bash +nosa fetch +``` + +该步骤初步校验构建配置是否可用,并通过配置的软件源拉取软件包至本地缓存。当构建配置发生变更或单纯希望更新软件源中最新版本软件包,均需要重新执行该步骤,否则可能导致构建失败或不符合预期。 + +当构建配置发生较大变更,希望清空本地缓存重新拉取时,需执行如下命令: + +```bash +nosa clean --all +``` + +#### 6.4.3 构建不可变根文件系统 + +NestOS不可变操作系统的核心是基于ostree技术的不可变根文件系统,执行如下步骤构建ostree文件系统: + +```bash +nosa build +``` + +build命令默认会生成ostree文件系统和OCI归档文件,您也可以在执行命令时同步添加qemu、metal、metal4k中的一个或多个,同步构建发布件,等效于后续继续执行buildextend-qemu、buildextend-metal和buildextend-metal4k命令。 + +```bash +nosa build qemu metal metal4k +``` + +如您希望在构建NestOS时,添加自定义文件或rpm包,请在执行build命令前将相应文件放入构建环境overrides目录下rootfs/或rpm/文件夹。 + +#### 6.4.4 构建各类发布件 + +build命令执行完毕后,可继续执行buildextend-XXX命令用于构建各类型发布件,具体介绍如下: + +- 构建qcow2镜像 + +```bash +nosa buildextend-qemu +``` + +- 构建带live环境的ISO镜像或PXE启动组件 + +```bash +nosa buildextend-metal +nosa buildextend-metal4k +nosa buildextend-live +``` + +- 构建适用于openstack环境的qcow2镜像 + +```bash +nosa buildextend-openstack +``` + +- 构建适用于容器镜像方式更新的容器镜像 + +执行nosa build命令构建ostree文件系统时,会同时生成ociarchive格式镜像,该镜像可直接执行如下命令推送到本地或远程镜像仓库,无需执行其他构建步骤。 + +```bash +nosa push-container [container-image-name] +``` + + 远程镜像仓库地址需附加到推送容器镜像名称中,且除隔离镜像tag外,不得出现":"。如未检测到":",该命令会自动生成{latest_build}-{arch}格式的tag。示例如下: + +```bash +nosa push-container registry.example.com/nestos:1.0.20240903.0-x86_64 +``` + +该命令支持以下可选参数: + +--authfile :指定登录远程镜像仓库的鉴权文件 + +--insecure:如远程镜像仓库采用自签名证书等场景,添加该参数可不校验SSL/TLS协议 + +--transport:指定目标镜像推送协议,默认为docker,具体支持项及说明如下: + +​ containers-storage:推送至podman、crio等容器引擎本地存储目录 + +​ dir:推送至指定本地目录 + +​ docker:以docker API推送至私有或远端容器镜像仓库 + +​ docker-archive:等效于docker save导出归档文件,可供docker load使用 + +​ docker-daemon:推送至docker容器引擎本地存储目录 + +### 6.5 获取发布件 + +构建完毕后,发布件均生成于构建环境中如下路径: + +```bash +builds/{version}/{arch}/ +``` + +如您仅关心最新构建版本或通过CI/CD调用,提供latest目录软链接至最新版本目录,即: + +```bash +builds/latest/{arch}/ +``` + +为方便传输,您可以调用如下命令,压缩发布件体积: + +```bash +nosa compress +``` + +压缩后原文件会被移除,会导致部分调试命令无法使用,可以调用解压命令恢复原文件: + +```bash +nosa uncompress +``` + +### 6.6 构建环境维护 + +在构建NestOS环境前后,可能存在如下需求,可使用推荐的命令解决相应问题: + +#### 6.6.1 清理历史或无效构建版本,以释放磁盘空间 + +可以通过以下命令清理历史版本构建: + +```bash +nosa prune +``` + +也可删除当前构建环境中的全部发布件: + +```bash +nosa clean +``` + +如构建配置更换过软件源或历史缓存无保留价值,可彻底清理当前构建环境缓存: + +```bash +nosa clean --all +``` + +#### 6.6.2 临时运行构建版本实例,用于调试或确认构建正确 + +```bash +nosa run +``` + +可通过--qemu-image或--qemu-iso指定启动镜像地址,其余参数请参考nosa run --help说明。 + +实例启动后,构建环境目录会被挂载至/var/mnt/workdir,可通过构建环境目录 + +#### 6.6.3 运行自动化测试 + +```bash +nosa kola run +``` + +该命令会执行预设的测试用例,也可在其后追加测试用例名称,单独执行单条用例。 + +```bash +nosa kola testiso +``` + +该命令会执行iso或pxe live环境安装部署测试,可作为构建工程的冒烟测试。 + +#### 6.6.4 调试验证构建工具(NestOS-assembler) + +```bash +nosa shell +``` + +该命令可启动进入构建工具链容器的shell环境,您可以通过此命令验证构建工具链工作环境是否正常。 + +## 7. 部署配置 + +### 7.1 前言 + +在开始部署NestOS之前,了解和准备必要的配置是至关重要的。NestOS通过点火文件(ignition文件)提供了一系列灵活的配置选项,可以通过Butane工具进行管理,方便用户进行自动化部署和环境设置。 + +在本章节中,将详细的介绍Butane工具的功能和使用方法,并根据不同场景提供配置示例。这些配置将帮助您快速启动和运行NestOS,在满足应用需求的同时,确保系统的安全性和可靠性。此外,还会介绍如何自定义镜像,将点火文件预集成至镜像中,以满足特定应用场景的需求,从而实现高效的配置和部署NestOS。 + +### 7.2 Butane简介 + +Butane是一个用于将人类可读的YAML配置文件转换为NestOS点火文件(Ignition 文件)的工具。Butane工具简化了复杂配置的编写过程,允许用户以更易读的格式编写配置文件,然后将其转换为适合NestOS使用的JSON格式。 + +NestOS对Butane进行了适配修改,新增nestos变体支持和配置规范版本v1.0.0,对应的点火(ignition)配置规范为v3.3.0,确保了配置的稳定性和兼容性。 + +### 7.3 Butane使用 + +安装butane软件包 + +```bash +dnf install butane +``` + +编辑example.yaml并执行以下指令将其转换为点火文件example.ign,其中关于yaml文件的编写,将在后续展开: + +```bash +butane example.yaml -o example.ign -p +``` + +### 7.4 支持的功能场景 + +以下配置示例(example.yaml)简述了NestOS主要支持的功能场景和进阶使用方法。 + +#### 7.4.1 设置用户和组并配置密码/密钥 + +```conf +variant: nestos +version: 1.0.0 +passwd: + users: + - name: nest + ssh_authorized_keys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDHn2eh... + - name: jlebon + groups: + - wheel + ssh_authorized_keys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDC5QFS... + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIveEaMRW... + - name: miabbott + groups: + - docker + - wheel + password_hash: $y$j9T$aUmgEDoFIDPhGxEe2FUjc/$C5A... + ssh_authorized_keys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDTey7R... +``` + +#### 7.4.2 文件操作——以配置网卡为例 + +```conf +variant: nestos +version: 1.0.0 +storage: + files: + - path: /etc/NetworkManager/system-connections/ens2.nmconnection + mode: 0600 + contents: + inline: | + [connection] + id=ens2 + type=ethernet + interface-name=ens2 + [ipv4] + address1=10.10.10.10/24,10.10.10.1 + dns=8.8.8.8; + dns-search= + may-fail=false + method=manual +``` + +#### 7.4.3 创建目录、文件、软连接并配置权限 + +```conf +variant: nestos +version: 1.0.0 +storage: + directories: + - path: /opt/tools + overwrite: true + files: + - path: /var/helloworld + overwrite: true + contents: + inline: Hello, world! + mode: 0644 + user: + name: dnsmasq + group: + name: dnsmasq + - path: /opt/tools/transmogrifier + overwrite: true + contents: + source: https://mytools.example.com/path/to/archive.gz + compression: gzip + verification: + hash: sha512-00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + mode: 0555 + links: + - path: /usr/local/bin/transmogrifier + overwrite: true + target: /opt/tools/transmogrifier + hard: false +``` + +#### 7.4.4 编写systemd服务——以启停容器为例 + +```conf +variant: nestos +version: 1.0.0 +systemd: + units: + - name: hello.service + enabled: true + contents: | + [Unit] + Description=MyApp + After=network-online.target + Wants=network-online.target + + [Service] + TimeoutStartSec=0 + ExecStartPre=-/bin/podman kill busybox1 + ExecStartPre=-/bin/podman rm busybox1 + ExecStartPre=/bin/podman pull busybox + ExecStart=/bin/podman run --name busybox1 busybox /bin/sh -c ""trap 'exit 0' INT TERM; while true; do echo Hello World; sleep 1; done"" + + [Install] + WantedBy=multi-user.target +``` + +### 7.5 点火文件预集成 + +NestOS构建工具链支持用户根据实际使用场景和需求定制镜像。在镜像制作完成后,nestos-installer还提供了针对镜像部署与应用等方面进行自定义的一系列功能,如嵌入点火文件、预分配安装位置、增删内核参数等功能,以下将针对主要功能进行介绍。 + +#### 7.5.1 点火文件预集成至ISO镜像 + +准备好NestOS的ISO镜像至本地;安装nestos-installer软件包;编辑example.yaml,并使用butane工具将其转换为ign文件,在这里,我们仅配置简单的用户名和密码(密码要求加密,示例中为qwer1234),内容如下: + +```conf +variant: nestos +version: 1.0.0 +passwd: + users: + - name: root + password_hash: "$1$root$CPjzNGH.NqmQ7rh26EeXv1" +``` + +将上述yaml转换为ign文件后,执行如下指令嵌入点火文件并指定目标磁盘位置,其中xxx.iso为准备至本地的NestOS ISO镜像: + +```bash +nestos-installer iso customize --dest-device /dev/sda --dest-ignition example.ign xxx.iso +``` + +使用该集成点火文件的ISO镜像进行安装时,NestOS会自动读取点火文件并安装至目标磁盘,待进度条完成度为100%后,自动进入安装好的NestOS环境,用户可根据ign文件配置的用户名和密码进入系统。 + +#### 7.5.2 点火文件预集成至PXE镜像 + +准备好NestOS的PXE镜像至本地,组件获取方式参考6.5【获取发布件】章节,其他步骤同上。 + +为了方便用户使用,nestos-installer也支持从ISO镜像中提取PXE组件的功能,执行如下指令,其中xxx.iso为保存至本地的NestOS ISO镜像: + +```bash +nestos-installer iso extract pxe xxx.iso +``` + +得到如下输出件: + +```text +xxx-initrd.img +xxx-rootfs.img +xxx-vmlinuz +``` + +执行如下指令嵌入点火文件并指定目标磁盘位置: + +```bash +nestos-installer pxe customize --dest-device /dev/sda --dest-ignition example.ign xxx-initrd.img --output custom-initrd.img +``` + +根据使用PXE安装NestOS的方式,替换相应的xxx-initrd.img为custom-initrd.img。启动后NestOS会自动读取点火文件并安装至目标磁盘,待进度条完成度为100%后,自动进入安装好的NestOS环境,用户可根据ign文件配置的用户名和密码进入系统。 + +## 8. 部署流程 + +### 8.1 简介 + +NestOS支持多种部署平台及常见部署方式,当前主要支持qcow2、ISO与PXE三种部署方式。与常见通用OS部署相比,主要区别在于如何传入以ign文件为特征的自定义部署配置,以下各部分将会分别介绍。 + +### 8.2 使用qcow2镜像安装 + +#### 8.2.1 使用qemu创建qcow2实例 + +准备NestOS的qcow2镜像及相应点火文件(详见第7章),终端执行如下步骤: + +```conf +IGNITION_CONFIG="/path/to/example.ign" +IMAGE="/path/to/image.qcow2" +IGNITION_DEVICE_ARG="-fw_cfg name=opt/com.coreos/config,file=${IGNITION_CONFIG}" + +qemu-img create -f qcow2 -F qcow2 -b ${IMAGE} my-nestos-vm.qcow2 +``` + +aarch64环境执行如下命令: + +```bash +qemu-kvm -m 2048 -M virt -cpu host -nographic -drive if=virtio,file=my-nestos-vm.qcow2 ${IGNITION_DEVICE_ARG} -nic user,model=virtio,hostfwd=tcp::2222-:22 -bios /usr/share/edk2/aarch64/QEMU_EFI-pflash.raw +``` + +x86_64环境执行如下命令: + +```bash +qemu-kvm -m 2048 -M pc -cpu host -nographic -drive if=virtio,file=my-nestos-vm.qcow2 ${IGNITION_DEVICE_ARG} -nic user,model=virtio,hostfwd=tcp::2222-:22 +``` + +#### 8.2.2 使用virt-install创建qcow2实例 + +假设libvirt服务正常,网络默认采用default子网,绑定virbr0网桥,您可参考以下步骤创建NestOS实例。 + +准备NestOS的qcow2镜像及相应点火文件(详见第7章),终端执行如下步骤: + +```conf +IGNITION_CONFIG="/path/to/example.ign" +IMAGE="/path/to/image.qcow2" +VM_NAME="nestos" +VCPUS="4" +RAM_MB="4096" +DISK_GB="10" +IGNITION_DEVICE_ARG=(--qemu-commandline="-fw_cfg name=opt/com.coreos/config,file=${IGNITION_CONFIG}") +``` + +**注意:使用virt-install安装,qcow2镜像及ign文件需指定绝对路径。** + +执行如下命令创建实例: + +```bash +virt-install --connect="qemu:///system" --name="${VM_NAME}" --vcpus="${VCPUS}" --memory="${RAM_MB}" --os-variant="kylin-hostos10.0" --import --graphics=none --disk="size=${DISK_GB},backing_store=${IMAGE}" --network bridge=virbr0 "${IGNITION_DEVICE_ARG[@]} +``` + +### 8.3 使用ISO镜像安装 + +准备NestOS的ISO镜像并启动。首次启动的NestOS ISO镜像会默认进入Live环境,该环境为易失的内存环境。 + +#### 8.3.1 通过nestos-installer安装向导脚本安装OS至目标磁盘 + +1)在NestOS的Live环境中,根据首次进入的打印提示,可输入以下指令,即可自动生成一份简易的点火文件并自动安装重启 + +```bash +sudo installnestos +``` + +2)根据终端提示信息依次输入用户名和密码; + +3)选择目标磁盘安装位置,可直接选择回车设置为默认项/dev/sda; + +4)执行完以上步骤后,nestos-installer开始根据我们提供的配置将NestOS安装至目标磁盘,待进度条100%后,自动重启; + +5)重启后自动进入NestOS,在grub菜单直接回车或者等待5s后启动系统,随后根据此前配置的用户名和密码进入系统。至此,安装完成。 + +#### 8.3.2 通过nestos-installer命令手动安装OS至目标磁盘 + +1)准备好点火文件example.ign(详见第7章); + +2)根据首次进入NestOS的Live环境打印的提示,输入以下指令开始安装: + +```bash +sudo nestos-installer install /dev/sda --ignition-file example.ign +``` + +如具备网络条件,点火文件也可通过网络获取,如: + +```bash +sudo nestos-installer install /dev/sda --ignition-file http://www.example.com/example.ign +``` + +3)执行完上述指令后,nestos-installer开始根据我们提供的配置将NestOS安装至目标磁盘,待进度条100%后,自动重启; + +4)重启后自动进入NestOS,在gurb菜单直接回车或者等待5s后启动系统,随后根据此前配置的用户名和密码进入系统。至此,安装完成 + +### 8.4 PXE部署 + +NestOS的PXE安装组件包括kernel、initramfs.img和rootfs.img。这些组件以nosa buildextend-live命令生成(详见第6章)。 + +1)使用PXELINUX 的kernel命令行指定内核,简单示例如下: + +```bash +KERNEL nestos-live-kernel-x86_64 +``` + +2)使用PXELINUX 的append命令行指定initrd和rootfs,简单示例如下: + +```bash +APPEND initrd=nestos-live-initramfs.x86_64.img,nestos-live-rootfs.x86_64.img +``` + +**注意:如您采用7.5章节所述,已将点火文件预集成至PXE组件,则仅需在此进行替换,无需执行后续步骤。** + +3)指定安装位置,以/dev/sda为例,在APPEND后追加,示例如下: + +```bash +nestosos.inst.install_dev=/dev/sda +``` + +4)指定点火文件,需通过网络获取,在APPEND后追加相应地址,示例如下: + +```bash +nestos.inst.ignition_url=http://www.example.com/example.ign +``` + +5)启动后NestOS会自动读取点火文件并安装至目标磁盘,待进度条完成度为100%后,自动进入安装好的NestOS环境,用户可根据ign文件配置的用户名和密码进入系统。 + +## 9. 基本使用 + +### 9.1 简介 + +NestOS采用基于ostree和rpm-ostree技术的操作系统封装方案,将关键目录设置为只读状态,核心系统文件和配置不会被意外修改;采用overlay分层思想,允许用户在基础ostree文件系统之上分层管理RPM包,不会破坏初始系统体系结构;同时支持构建OCI格式镜像,实现以镜像为最小粒度进行操作系统版本的切换。 + +### 9.2 SSH连接 + +出于安全考虑,NestOS 默认不支持用户使用密码进行SSH登录,而只能使用密钥认证方式。这一设计旨在增强系统的安全性,防止因密码泄露或弱密码攻击导致的潜在安全风险。 + +NestOS通过密钥进行SSH连接的方法与openEuler一致,如果用户需要临时开启密码登录,可按照以下步骤执行: + +1)编辑ssh服务附加配置文件 + +```bash +vi /etc/ssh/sshd_config.d/40-disable-passwords.conf +``` + +2)修改默认配置PasswordAuthentication为如下内容: + +```conf +PasswordAuthentication yes +``` + +3)重启sshd服务,便可实现临时使用密码进行SSH登录。 + +### 9.3 RPM包安装 + +**注意:不可变操作系统不提倡在运行环境中安装软件包,提供此方法仅供临时调试等场景使用,因业务需求需要变更集成软件包列表请通过更新构建配置重新构建实现。** + +NestOS不支持常规的包管理器dnf/yum,而是通过rpm-ostree来管理系统更新和软件包安装。rpm-ostree结合了镜像和包管理的优势,允许用户在基础系统之上分层安装和管理rpm包,并且不会破环初始系统的结构。使用以下命令安装rpm包: + +```bash +rpm-ostree install +``` + +安装完成后,重新启动操作系统,可以看到引导加载菜单出现了两个分支,默认第一个分支为最新的分支 + +```bash +systemctl reboot +``` + +重启进入系统,查看系统包分层状态,可看到当前版本已安装\ + +```bash +rpm-ostree status -v +``` + +### 9.4 版本回退(临时/永久) + +更新/rpm包安装完成后,上一版本的操作系统部署仍会保留在磁盘上。如果更新导致问题,用户可以使用rpm-ostree进行版本回退,这一步操作需要用户手动操作,具体流程如下: + +#### 9.4.1 临时回退 + +要临时回滚到之前的OS部署,在系统启动过程中按住shift键,当引导加载菜单出现时,在菜单中选择相应的分支(默认有两个,选择另外一个即可)。在此之前,可以使用以下指令查看当前环境中已存在的两个版本分支: + +```bash +rpm-ostree status +``` + +#### 9.4.2 永久回退 + +要永久回滚到之前的操作系统部署,用户需在当前版本中运行如下指令,此操作将使用之前版本的系统部署作为默认部署。 + +```bash +rpm-ostree rollback +``` + +重新启动以生效,引导加载菜单的默认部署选项已经改变,无需用户手动切换。 + +```bash +systemctl reboot +``` + +## 10. 容器镜像方式更新 + +### 10.1 应用场景说明 + +NestOS作为基于不可变基础设施思想的容器云底座操作系统,将文件系统作为一个整体进行分发和更新。这一方案在运维与安全方面带来了巨大的便利。然而,在实际生产环境中,官方发布的版本往往难以满足用户的需求。例如,用户可能希望在系统中默认集成自维护的关键基础组件,或者根据特定场景的需求对软件包进行进一步的裁剪,以减少系统的运行负担。因此,与通用操作系统相比,用户对NestOS有着更强烈和更频繁的定制需求。 + + NestOS-assembler 可提供符合OCI标准的容器镜像,且不仅是将根文件系统打包分发,利用ostree native container特性,可使容器云场景用户使用熟悉的技术栈,只需编写一个ContainerFile(Dockerfile)文件,即可轻松构建定制版镜像,用于自定义集成组件或后续的升级维护工作。 + +### 10.2 使用方式 + +#### 10.2.1 定制镜像 + +- 基本步骤 + +(1) 参考第6章构建NestOS容器镜像,可使用nosa push-container命令推送至公共或私有容器镜像仓库。 + +(2) 编写Containerfile(Dockerfile)示例如下: + +```conf +FROM registry.example.com/nestos:1.0.20240603.0-x86_64 + +# 执行自定义构建步骤,例如安装软件或拷贝自构建组件 +# 此处以安装strace软件包为例 +RUN rpm-ostree install strace && rm -rf /var/cache && ostree container commit +``` + +(3)执行docker build或集成于CICD中构建相应镜像 + +- 注意事项 + +(1) NestOS 无yum/dnf包管理器,如需安装软件包可采用rpm-ostree install命令安装本地rpm包或软件源中提供软件 + +(2) 如有需求也可修改/etc/yum.repo.d/目录下软件源配置 + +(3) 每层有意义的构建命令末尾均需添加&& ostree container commit命令,从构建容器镜像最佳实践角度出发,建议尽可能减少RUN层的数量 + +(4) 构建过程中会对非/usr或/etc目录内容进行清理,因此通过容器镜像方式定制主要适用于软件包或组件更新,请勿通过此方式进行系统维护或配置变更(例如添加用户useradd) + +#### 10.2.2 部署/升级镜像 + +假设上述步骤构建容器镜像被推送为registry.example.com/nestos:1.0.20240903.0-x86_64。 + +在已部署NestOS的环境中执行如下命令: + +```bash +sudo rpm-ostree rebase ostree-unverified-registry:registry.example.com/nestos:1.0.20240903.0-x86_64 +``` + +重新引导后完成定制版本部署。 + +当您使用容器镜像方式部署后,rpm-ostree upgrade 默认会将更新源从ostree更新源地址更新为容器镜像地址。之后,您可以在相同的tag下更新容器镜像,使用 rpm-ostree upgrade 可以检测远端镜像是否已经更新,如果有变更,它会拉取最新的镜像并完成部署。 diff --git a/docs/en/25.03/Cloud/NestOS/NestOS/overview.md b/docs/en/25.03/Cloud/NestOS/NestOS/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..1d744c820ca42dca9441b53db275b9d72cddaa21 --- /dev/null +++ b/docs/en/25.03/Cloud/NestOS/NestOS/overview.md @@ -0,0 +1,4 @@ +# NestOS云底座操作系统 + +本文介绍云底座操作系统NestOS For Container(下称NestOS)的安装部署与各个特性说明和使用方法,使用户能够快速了解并使用NestOS。NestOS For Virt的使用方法与通用操作系统使用方法一致,可参考欧拉官方文档。 +Nestos搭载了docker、iSulad、podman、cri-o等常见容器引擎,将ignition配置、rpm-ostree、OCI支持、SElinux强化等技术集成在一起,采用基于双系统分区、容器技术和集群架构的设计思路,可以适配云场景下多种基础运行环境。同时NestOS针对Kubernetes进行优化,在IaaS生态构建方面,针对openStack、oVirt等平台提供支持;在PaaS生态构建方面,针对OKD、Rancher等平台提供支持,使系统具备十分便捷的集群组建能力,可以更安全的运行大规模的容器化工作负载。镜像下载地址详见[NestOS官网](https://nestos.openeuler.org/)。 diff --git a/docs/en/25.03/Cloud/_menu.md b/docs/en/25.03/Cloud/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..7d05dfaf0421483d91cdb9c4d6819d6ce927d133 --- /dev/null +++ b/docs/en/25.03/Cloud/_menu.md @@ -0,0 +1,35 @@ +--- +label: '云原生' +children: + - label: '容器引擎' + children: + - reference: './ContainerEngine/iSulaContainerEngine/_menu.md' + - reference: './ContainerEngine/DockerEngine/_menu.md' + - label: '容器形态' + children: + - reference: './ContainerForm/SecureContainer/_menu.md' + - reference: './ContainerForm/SystemContainer/_menu.md' + - label: '容器运行时' + children: + - reference: './ContainerRuntime/Kuasar/_menu.md' + - label: '容器镜像构建工具' + children: + - reference: './ImageBuilder/isula-build/_menu.md' + - label: '云原生操作系统' + children: + - reference: './KubeOS/KubeOS/_menu.md' + - label: '云底座操作系统' + children: + - reference: './NestOS/NestOS/_menu.md' + - label: '混合部署' + children: + - reference: './HybridDeployment/rubik/_menu.md' + - reference: './HybridDeployment/oncn-bwm/_menu.md' + - label: '集群部署' + children: + - reference: './ClusterDeployment/Kubernetes/_menu.md' + - reference: './ClusterDeployment/iSulad+k8s/_menu.md' + - label: '服务网格' + children: + - reference: './Kmesh/Kmesh/_menu.md' +--- diff --git a/docs/en/25.03/Cloud/index.md b/docs/en/25.03/Cloud/index.md new file mode 100644 index 0000000000000000000000000000000000000000..7d3f4694f4b5e1bde97476c3ffd396573ed55d31 --- /dev/null +++ b/docs/en/25.03/Cloud/index.md @@ -0,0 +1,4 @@ +--- +title: 云原生 +overview: true +--- \ No newline at end of file diff --git a/docs/en/25.03/EdgeComputing/K3s/K3s-deployment-guide.md b/docs/en/25.03/EdgeComputing/K3s/K3s-deployment-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..de7ce199c804388851a09d47582dd6ee59138f92 --- /dev/null +++ b/docs/en/25.03/EdgeComputing/K3s/K3s-deployment-guide.md @@ -0,0 +1,90 @@ +# K3s部署指南 + +## 什么是K3s + +K3s 是一个轻量级的 Kubernetes 发行版,它针对边缘计算、物联网等场景进行了高度优化。K3s 有以下增强功能: + +- 打包为单个二进制文件。 +- 使用基于 sqlite3 的轻量级存储后端作为默认存储机制。同时支持使用 etcd3、MySQL 和 PostgreSQL 作为存储机制。 +- 封装在简单的启动程序中,通过该启动程序处理很多复杂的 TLS 和选项。 +- 默认情况下是安全的,对轻量级环境有合理的默认值。 +- 添加了简单但功能强大的batteries-included功能,例如:本地存储提供程序,服务负载均衡器,Helm controller 和 Traefik Ingress controller。 +- 所有 Kubernetes control-plane 组件的操作都封装在单个二进制文件和进程中,使 K3s 具有自动化和管理包括证书分发在内的复杂集群操作的能力。 +- 最大程度减轻了外部依赖性,K3s 仅需要 kernel 和 cgroup 挂载。 + +## 适用场景 + +K3s 适用于以下场景: + +- 边缘计算(Edge Computing) +- 物联网(Internet of Things,IoT) +- 持续集成(Continuous Integration,CI) +- 开发(Development) +- 基于ARM的单板计算机(ARM-based single-board computers) +- 嵌入式K8s(Embedded K8s) + +由于运行 K3s 所需的资源相对较少,所以 K3s 也适用于开发和测试场景。在这些场景中,如果开发或测试人员需要对某些功能进行验证,或对某些问题进行重现,那么使用 K3s 不仅能够缩短启动集群的时间,还能够减少集群需要消耗的资源。 + +## 部署K3s + +### 准备工作 + +- 确保server节点及agent节点主机名不一致: + +可以通过 hostnamectl set-hostname “主机名” 进行主机名的修改。 + +![1661829534335](./figures/set-hostname.png) + +- 在各节点yum 安装 K3s: + + K3s官网采用下载对应架构二进制可执行文件的格式,通过install.sh脚本进行离线安装,openEuler社区将该二进制文件的编译过程移植到社区中,并编译出RPM包。此处可通过yum命令直接进行下载安装。 + +![1661830441538](./figures/yum-install.png) + +### 部署server节点 + +如需在单个服务器上安装 K3s,可以在 server 节点上执行如下操作: + +```sh +INSTALL_K3S_SKIP_DOWNLOAD=true k3s-install.sh +``` + +![1661825352724](./figures/server-install.png) + +### 检查server部署情况 + +![1661825403705](./figures/check-server.png) + +### 部署agent节点 + +首先查询server节点的token值,该token可在server节点的/var/lib/rancher/k3s/server/node-token查到。 + +> **注意**: +> +> 后续我们只用到该token的后半部分。 + +![1661825538264](./figures/token.png) + +选择添加其他 agent,请在每个 agent 节点上执行以下操作。 + +```sh +INSTALL_K3S_SKIP_DOWNLOAD=true K3S_URL=https://myserver:6443 K3S_TOKEN=mynodetoken k3s-install.sh +``` + +> **注意** +> +> 将 myserver 替换为 server 的 IP 或有效的 DNS,并将 mynodetoken 替换 server 节点的 token: + +![1661829392357](./figures/agent-install.png) + +### 检查agent节点是否部署成功 + +安装完毕后,回到 **server** 节点,执行 `kubectl get nodes`,可以看到agent节点已注册成功。 + +![1661826797319](./figures/check-agent.png) + +至此,一个基础的k3s集群搭建完成。 + +### 更多用法 + +K3s的更多用法可以参考K3s官网, diff --git a/docs/en/25.03/EdgeComputing/K3s/_menu.md b/docs/en/25.03/EdgeComputing/K3s/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..9717536710792eedcfc8845caaebfb73d59e4889 --- /dev/null +++ b/docs/en/25.03/EdgeComputing/K3s/_menu.md @@ -0,0 +1,8 @@ +--- +label: 'K3s部署指南' +ismanual: 'Y' +description: 'K3s 是一个轻量级的 Kubernetes 发行版,针对边缘计算等场景进行了优化' +children: + - label: 'K3s部署指南' + href: './K3s-deployment-guide.md' +--- diff --git a/docs/en/25.03/EdgeComputing/K3s/figures/agent-install.png b/docs/en/25.03/EdgeComputing/K3s/figures/agent-install.png new file mode 100644 index 0000000000000000000000000000000000000000..dca1d64ec8aae821393bb715daf4c56b783a68e0 Binary files /dev/null and b/docs/en/25.03/EdgeComputing/K3s/figures/agent-install.png differ diff --git a/docs/en/25.03/EdgeComputing/K3s/figures/check-agent.png b/docs/en/25.03/EdgeComputing/K3s/figures/check-agent.png new file mode 100644 index 0000000000000000000000000000000000000000..aa467713353d70ad513e8ee13ac9d8b6520b7ee0 Binary files /dev/null and b/docs/en/25.03/EdgeComputing/K3s/figures/check-agent.png differ diff --git a/docs/en/25.03/EdgeComputing/K3s/figures/check-server.png b/docs/en/25.03/EdgeComputing/K3s/figures/check-server.png new file mode 100644 index 0000000000000000000000000000000000000000..06343de9a8b0eacb0f6194cf438b2b27af88cae4 Binary files /dev/null and b/docs/en/25.03/EdgeComputing/K3s/figures/check-server.png differ diff --git a/docs/en/25.03/EdgeComputing/K3s/figures/server-install.png b/docs/en/25.03/EdgeComputing/K3s/figures/server-install.png new file mode 100644 index 0000000000000000000000000000000000000000..7d30c8f4f73946c8b0555186c1736492039da731 Binary files /dev/null and b/docs/en/25.03/EdgeComputing/K3s/figures/server-install.png differ diff --git a/docs/en/25.03/EdgeComputing/K3s/figures/set-hostname.png b/docs/en/25.03/EdgeComputing/K3s/figures/set-hostname.png new file mode 100644 index 0000000000000000000000000000000000000000..32564d6159825b6d4131a6b138a493188ce88c6c Binary files /dev/null and b/docs/en/25.03/EdgeComputing/K3s/figures/set-hostname.png differ diff --git a/docs/en/25.03/EdgeComputing/K3s/figures/token.png b/docs/en/25.03/EdgeComputing/K3s/figures/token.png new file mode 100644 index 0000000000000000000000000000000000000000..79e5313bd1d5e707659cd08d4aafdf528b9df8f0 Binary files /dev/null and b/docs/en/25.03/EdgeComputing/K3s/figures/token.png differ diff --git a/docs/en/25.03/EdgeComputing/K3s/figures/yum-install.png b/docs/en/25.03/EdgeComputing/K3s/figures/yum-install.png new file mode 100644 index 0000000000000000000000000000000000000000..0e601a23a5a67e7927f12bc90d1a4137e1a3a567 Binary files /dev/null and b/docs/en/25.03/EdgeComputing/K3s/figures/yum-install.png differ diff --git a/docs/en/25.03/EdgeComputing/KubeEdge/_menu.md b/docs/en/25.03/EdgeComputing/KubeEdge/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..d8b89a2d5ecd7ce104cc4c746b7b93fc015de4a3 --- /dev/null +++ b/docs/en/25.03/EdgeComputing/KubeEdge/_menu.md @@ -0,0 +1,11 @@ +--- +label: 'KubeEdge部署指南' +ismanual: 'Y' +description: 'KubeEdge 将 Kubernetes 的能力延伸到了边缘场景中' +children: + - label: 'KubeEdge使用文档' + href: './kubeedge-usage-guide.md' + - label: 'KubeEdge部署指南' + href: './kubeedge-deployment-guide.md' +--- + diff --git a/docs/en/25.03/EdgeComputing/KubeEdge/kubeedge-deployment-guide.md b/docs/en/25.03/EdgeComputing/KubeEdge/kubeedge-deployment-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..5857daaf8bed314c269ba3ebdfb9c9091d06ab69 --- /dev/null +++ b/docs/en/25.03/EdgeComputing/KubeEdge/kubeedge-deployment-guide.md @@ -0,0 +1,224 @@ +# KubeEdge 部署指南 + +## 介绍 + +### KubeEdge + +KubeEdge 是一个致力于解决边缘场景问题的开源系统,它将容器化应用程序编排和设备管理的能力扩展到边缘设备。基于 Kubernetes,KubeEdge 为网络、应用程序部署以及云侧与边缘侧之间的元数据同步提供核心基础设施支持。KubeEdge 支持 MQTT,并允许开发人员编写自定义逻辑,在边缘上启用资源受限的设备通信。KubeEdge 由云部分和边缘部分组成,目前均已开源。 + +> + +### iSulad + +iSulad 是一个轻量级容器 runtime 守护程序,专为 IOT 和 Cloud 基础设施而设计,具有轻便、快速且不受硬件规格和体系结构限制的特性,可以被更广泛地应用在云、IoT、边缘计算等多个场景。 + +> + +## 集群概览 + +### 组件版本 + +| 组件 | 版本 | +| ---------- | --------------------------------- | +| OS | openEuler 22.03 | +| Kubernetes | 1.20.2-4 | +| iSulad | 2.0.11 | +| KubeEdge | v1.8.0 | + +### 节点规划(示例) + +| 节点名 | 位置 | 组件 | +| -------------- | ------------ | ------------------------------ | +| cloud.kubeedge | 云侧(cloud) | k8s(master)、isulad、cloudcore | +| edge.kubeedge | 边缘侧(edge) | isulad、edgecore | + +> 提示:云侧和边缘侧的主机名可以使用 `hostnamectl set-hostname [cloud,edge].kubeedge` 命令提前设置好 + +## 准备 + +### 下载工具包 + +[kubeedge-tools](https://gitee.com/Poorunga/kubeedge-tools) 工具包提供了完备的离线安装包以及部署脚本,降低了部署复杂度并且支持在节点无法访问外网的条件下快速搭建 KubeEdge 集群。 + +```bash +# 下载 kubeedge-tools 工具包并解压(包括云侧和边缘侧) +$ wget -O kubeedge-tools.zip https://gitee.com/Poorunga/kubeedge-tools/repository/archive/master.zip +$ unzip kubeedge-tools.zip + +# 进入 kubeedge-tools 工具包目录(后续所有操作基于此目录) +$ cd kubeedge-tools-master +``` + +### 部署 k8s + +以下操作仅在云侧执行 + +#### 初始化云侧环境 + +```bash +$ ./setup-cloud.sh +``` + +#### 安装 k8s + +k8s 的安装部署使用 openEuler 22.03 SP2 的版本 + +#### 安装云侧容器网络 + +目前有丰富的 cni 软件可以为 k8s 节点提供容器网络功能,比如 [flannel](https://github.com/flannel-io/flannel)、[calico](https://github.com/projectcalico/calico)、[cilium](https://github.com/cilium/cilium) 等,如果你暂时不明确选用哪款 cni 软件,可以使用下方命令安装云侧容器网络: + +```bash +$ ./install-flannel-cloud.sh +``` + +#### 检查部署情况 + +```bash +# 查看节点状态(Ready 即正常) +$ kubectl get nodes +NAME STATUS ROLES AGE VERSION +cloud.kubeedge Ready control-plane,master 12m v1.20.2 + +# 查看所有 k8s 组件运行状态(Running 即正常) +$ kubectl get pods -n kube-system +NAME READY STATUS RESTARTS AGE +coredns-74ff55c5b-4ptkh 1/1 Running 0 15m +coredns-74ff55c5b-zqx5n 1/1 Running 0 15m +etcd-cloud.kubeedge 1/1 Running 0 15m +kube-apiserver-cloud.kubeedge 1/1 Running 0 15m +kube-controller-manager-cloud.kubeedge 1/1 Running 0 15m +kube-flannel-cloud-ds-lvh4n 1/1 Running 0 13m +kube-proxy-2tcnn 1/1 Running 0 15m +kube-scheduler-cloud.kubeedge 1/1 Running 0 15m +``` + +## 部署 + +### 部署 cloudcore + +以下操作仅在云侧执行 + +#### 初始化集群 + +```bash +# --advertise-address 填写云侧节点的主机 IP 地址 +$ keadm init --advertise-address="云侧IP" --kubeedge-version=1.8.0 +... +CloudCore started +``` + +#### 调整 cloudcore 配置 + +```bash +$ ./patch-cloud.sh +``` + +#### 检查部署情况 + +```bash +# active (running)即正常 +$ systemctl status cloudcore | grep running + Active: active (running) since Fri 2022-03-04 10:54:30 CST; 5min ago +``` + +至此,云侧的 cloudcore 已部署完成,接下来部署边缘侧 edgecore。 + +### 部署 edgecore + +以下命令如无特殊说明则仅在边缘侧执行 + +#### 初始化边缘侧环境 + +```bash +$ ./setup-edge.sh +``` + +#### 纳管边缘节点 + +```bash +# keadm gettoken 命令需要在云侧执行 +$ keadm gettoken +96058ab80ffbeb87fe58a79bfb19ea13f9a5a6c3076a17c00f80f01b406b4f7c.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDY0NDg4NzF9.1mJegWB7SUVjgf-OvAqILgbZXeMHR9eOzMxpNFc42SI +# 记录并保存此 token 值,后续步骤需要使用 + + +# keadm join 命令在边缘侧执行 +# --cloudcore-ipport 填写云侧节点的主机 IP 地址:10000,--token 填写上方 token 值 +$ keadm join --cloudcore-ipport=云侧IP:10000 --kubeedge-version=1.8.0 --token=96058ab80ffbeb87fe58a79bfb19ea13f9a5a6c3076a17c00f80f01b406b4f7c.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDY0NDg4NzF9.1mJegWB7SUVjgf-OvAqILgbZXeMHR9eOzMxpNFc42SI +... +KubeEdge edgecore is running... +``` + +#### 调整 edgecore 配置 + +```bash +$ ./patch-edge.sh +``` + +#### 安装边缘侧容器网络 + +如果你暂时不明确选用哪款 cni 软件,可以使用下方命令安装边缘侧容器网络: + +```bash +# 下方命令需要在云侧执行 +$ ./install-flannel-edge.sh +``` + +#### 检查边缘节点是否纳管成功 + +```bash +# 下方命令需要在云侧执行(发现已经有了边缘节点) +$ kubectl get nodes +NAME STATUS ROLES AGE VERSION +cloud.kubeedge Ready control-plane,master 1h v1.20.2 +edge.kubeedge Ready agent,edge 10m v1.19.3-kubeedge-v1.8.0 +``` + +至此,KubeEdge 集群部署完成,接下来我们测试一下从云侧下发应用到边缘侧。 + +### 部署应用 + +以下命令在云侧执行 + +#### 部署nginx + +```bash +$ kubectl apply -f yamls/nginx-deployment.yaml +deployment.apps/nginx-deployment created + +# 查看应用是否部署到了边缘侧(Running 即正常) +$ kubectl get pod -owide | grep nginx +nginx-deployment-84b99f4bf-jb6sz 1/1 Running 0 30s 10.244.1.2 edge.kubeedge +``` + +#### 测试功能 + +```bash +# 进入边缘侧节点,访问 nginx 应用 +$ curl 10.244.1.2:80 + + + +Welcome to nginx! + + + +

Welcome to nginx!

+

If you see this page, the nginx web server is successfully installed and +working. Further configuration is required.

+ +

For online documentation and support please refer to +nginx.org.
+Commercial support is available at +nginx.com.

+ +

Thank you for using nginx.

+ + +``` + +至此,KubeEdge 部署已经全流程打通。 diff --git a/docs/en/25.03/EdgeComputing/KubeEdge/kubeedge-usage-guide.md b/docs/en/25.03/EdgeComputing/KubeEdge/kubeedge-usage-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..64cd9a6a8f83e5e26e6388a1e9825b49d9267623 --- /dev/null +++ b/docs/en/25.03/EdgeComputing/KubeEdge/kubeedge-usage-guide.md @@ -0,0 +1,224 @@ +# KubeEdge使用文档 + +KubeEdge将Kubernetes的能力延伸到了边缘场景中,为云和边缘之间的网络,应用部署和元数据同步提供基础架构支持。KubeEdge在使用上与Kubernetes保持完全一致,除此之外还扩展了对边缘设备的管理与控制。本节将通过一个简单的例子向用户演示如何通过KubeEdge完成设备边云协同任务。 + +## 1. 准备工作 + +选用示例:**KubeEdge Counter Demo** + +计数器是一个伪设备,用户无需任何额外的物理设备即可运行此演示。计数器在边缘侧运行,用户可以从云侧在Web中对其进行控制,也可以从云侧在Web中获得计数器值。原理图如下: + +详细文档参考: + +1. 本示例要求KubeEdge版本必须是v1.2.1+,此次选择最新版的KubeEdge v1.8.0 + + ```sh + [root@ke-cloud ~]# kubectl get node + NAME STATUS ROLES AGE VERSION + ke-cloud Ready master 13h v1.20.2 + ke-edge1 Ready agent,edge 64s v1.19.3-kubeedge-v1.8.0 + + 说明:本文接下来的验证将使用边缘节点ke-edge1进行,如果你参考本文进行相关验证,后续边缘节点名称的配置需要根据你的实际情况进行更改。 + ``` + +2. 确保k8s apiserver开启了以下配置: + + ```shell + --insecuret-port=8080 + --insecure-bind-address=0.0.0.0 + ``` + + 可以通过修改/etc/kubernetes/manifests/kube-apiserver.yaml文件,并重启k8s-apiserver组件的pod来进行更改。 + +3. 下载示例代码: + + ```sh + [root@ke-cloud ~]# git clone https://github.com/kubeedge/examples.git $GOPATH/src/github.com/kubeedge/examples + ``` + +## 2. 创建device model和device + +1. 创建device model + + ```sh + [root@ke-cloud ~]# cd $GOPATH/src/github.com/kubeedge/examples/kubeedge-counter-demo/crds + [root@ke-cloud crds~]# kubectl create -f kubeedge-counter-model.yaml + ``` + +2. 创建device + + 根据你的实际情况修改matchExpressions: + + ```sh + [root@ke-cloud ~]# cd $GOPATH/src/github.com/kubeedge/examples/kubeedge-counter-demo/crds + [root@ke-cloud crds~]# vim kubeedge-counter-instance.yaml + apiVersion: devices.kubeedge.io/v1alpha1 + kind: Device + metadata: + name: counter + labels: + description: 'counter' + manufacturer: 'test' + spec: + deviceModelRef: + name: counter-model + nodeSelector: + nodeSelectorTerms: + - matchExpressions: + - key: 'kubernetes.io/hostname' + operator: In + values: + - ke-edge1 + + status: + twins: + - propertyName: status + desired: + metadata: + type: string + value: 'OFF' + reported: + metadata: + type: string + value: '0' + + [root@ke-cloud crds~]# kubectl create -f kubeedge-counter-instance.yaml + ``` + +## 3. 部署云端应用 + +1. 修改代码 + + 云端应用web-controller-app用来控制边缘端的pi-counter-app应用,该程序默认监听的端口号为80,此处修改为8089,如下所示: + + ```sh + [root@ke-cloud ~]# cd $GOPATH/src/github.com/kubeedge/examples/kubeedge-counter-demo/web-controller-app + [root@ke-cloud web-controller-app~]# vim main.go + package main + + import ( + "github.com/astaxie/beego" + "github.com/kubeedge/examples/kubeedge-counter-demo/web-controller-app/controller" + ) + + func main() { + beego.Router("/", new(controllers.TrackController), "get:Index") + beego.Router("/track/control/:trackId", new(controllers.TrackController), "get,post:ControlTrack") + + beego.Run(":8089") + } + ``` + +2. 构建镜像 + + 注意:构建镜像时,请将源码拷贝到GOPATH对应的路径下,如果开启了go mod请关闭。 + + ```sh + [root@ke-cloud web-controller-app~]# make all + [root@ke-cloud web-controller-app~]# make docker + ``` + +3. 部署web-controller-app + + ```sh + [root@ke-cloud ~]# cd $GOPATH/src/github.com/kubeedge/examples/kubeedge-counter-demo/crds + [root@ke-cloud crds~]# kubectl apply -f kubeedge-web-controller-app.yaml + ``` + +## 4. 部署边缘端应用 + +边缘端的pi-counter-app应用受云端应用控制,主要与mqtt服务器通信,进行简单的计数功能。 + +1. 修改代码与构建镜像 + + 需要将Makefile中的GOARCH修改为amd64才能运行该容器。 + + ```sh + [root@ke-cloud ~]# cd $GOPATH/src/github.com/kubeedge/examples/kubeedge-counter-demo/counter-mapper + [root@ke-cloud counter-mapper~]# vim Makefile + .PHONY: all pi-execute-app docker clean + all: pi-execute-app + + pi-execute-app: + GOARCH=amd64 go build -o pi-counter-app main.go + + docker: + docker build . -t kubeedge/kubeedge-pi-counter:v1.0.0 + + clean: + rm -f pi-counter-app + + [root@ke-cloud counter-mapper~]# make all + [root@ke-cloud counter-mapper~]# make docker + ``` + +2. 部署Pi Counter App + + ```sh + [root@ke-cloud ~]# cd $GOPATH/src/github.com/kubeedge/examples/kubeedge-counter-demo/crds + [root@ke-cloud crds~]# kubectl apply -f kubeedge-pi-counter-app.yaml + + 说明:为了防止Pod的部署卡在`ContainerCreating`,这里直接通过docker save、scp和docker load命令将镜像发布到边缘端 + + [root@ke-cloud ~]# docker save -o kubeedge-pi-counter.tar kubeedge/kubeedge-pi-counter:v1.0.0 + [root@ke-cloud ~]# scp kubeedge-pi-counter.tar root@192.168.1.56:/root + [root@ke-edge1 ~]# docker load -i kubeedge-pi-counter.tar + ``` + +## 5. 体验Demo + +现在,KubeEdge Demo的云端部分和边缘端的部分都已经部署完毕,如下: + +```sh +[root@ke-cloud ~]# kubectl get pods -o wide +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +kubeedge-counter-app-758b9b4ffd-f8qjj 1/1 Running 0 26m 192.168.1.66 ke-cloud +kubeedge-pi-counter-c69698d6-rb4xz 1/1 Running 0 2m 192.168.1.56 ke-edge1 +``` + +我们现在开始测试一下该Demo运行效果: + +1. 执行ON命令 + + 在web页面上选择ON,并点击Execute,可以在edge节点上通过以下命令查看执行结果: + + ```sh + [root@ke-edge1 ~]# docker logs -f counter-container-id + ``` + +2. 查看counter STATUS + + 在web页面上选择STATUS,并点击Execute,会在Web页面上返回counter当前的status。 + +3. 执行OFF命令 + + 在web页面上选择OFF,并点击Execute,可以再edge节点上通过以下命令查看执行结果: + + ```sh + [root@ke-edge1 ~]# docker logs -f counter-container-id + ``` + +## 6. 其他 + +1. 更多的KubeEdge官方示例请参考 + + |Name | Description | + |---|---| + |[LED-RaspBerry-Pi](https://github.com/kubeedge/examples/blob/master/led-raspberrypi/README.md) |Controlling a LED light with Raspberry Pi using KubeEdge platform.| + |[Data Analysis @ Edge](https://github.com/kubeedge/examples/blob/master/apache-beam-analysis/README.md) | Analyzing data at edge by using Apache Beam and KubeEdge.| + |[Security@Edge](https://github.com/kubeedge/examples/blob/master/security-demo/README.md) | Security at edge using SPIRE for identity management.| + |[Bluetooth-CC2650-demo](https://github.com/kubeedge/examples/blob/master/bluetooth-CC2650-demo/README.md) |Controlling a CC2650 SensorTag bluetooth device using KubeEdge platform.| + |[Play Music @Edge through WeChat](https://github.com/kubeedge/examples/blob/master/wechat-demo/README.md) | Play music at edge based on WeChat and KubeEdge.| + |[Play Music @Edge through Web](https://github.com/kubeedge/examples/blob/master/web-demo/README.md) | Play music at edge based on Web and KubeEdge.| + |[Collecting temperature @Edge](https://github.com/kubeedge/examples/blob/master/temperature-demo/README.md) | Collecting temperature at edge based KubeEdge.| + |[Control pseudo device counter and collect data](https://github.com/kubeedge/examples/blob/master/kubeedge-counter-demo/README.md) | Control pseudo device counter and collect data based KubeEdge.| + |[Play Music @Edge through Twitter](https://github.com/kubeedge/examples/blob/master/ke-twitter-demo/README.md)| Play music at edge based on Twitter and KubeEdge.| + |[Control Zigbee @Edge through cloud](https://github.com/kubeedge/examples/blob/master/kubeedge-edge-ai-application/README.md) | Face detection at cloud using OpenCV and using it to control zigbee on edge using Kubeedge.| + +2. 使用EdgeMesh做边缘服务发现 + + + +3. 自定义云边消息路由 + + diff --git a/docs/en/25.03/EdgeComputing/KubeEdge/overview.md b/docs/en/25.03/EdgeComputing/KubeEdge/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..b52a1d7075b8b60f255b9f2b6cce1380e259d3e6 --- /dev/null +++ b/docs/en/25.03/EdgeComputing/KubeEdge/overview.md @@ -0,0 +1,3 @@ +# KubeEdge 边缘计算平台用户指南 + +本文档主要介绍了边缘计算平台 KubeEdge 的部署指南与使用文档,让用户了解 KubeEdge,并指导用户和管理员安装和使用 KubeEdge。 diff --git a/docs/en/25.03/EdgeComputing/_menu.md b/docs/en/25.03/EdgeComputing/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..7fa74d942a4656718366fa8e46d38dba32834731 --- /dev/null +++ b/docs/en/25.03/EdgeComputing/_menu.md @@ -0,0 +1,6 @@ +--- +label: '边缘计算' +children: + - reference: './KubeEdge/_menu.md' + - reference: './K3s/_menu.md' +--- diff --git a/docs/en/25.03/EdgeComputing/index.md b/docs/en/25.03/EdgeComputing/index.md new file mode 100644 index 0000000000000000000000000000000000000000..0a19114ebd5ee2338e79c0423c84ee8941730f38 --- /dev/null +++ b/docs/en/25.03/EdgeComputing/index.md @@ -0,0 +1,4 @@ +--- +title: 边缘计算 +overview: true +--- \ No newline at end of file diff --git a/docs/en/25.03/Embedded/UniProton/UniProton-apis.md b/docs/en/25.03/Embedded/UniProton/UniProton-apis.md new file mode 100644 index 0000000000000000000000000000000000000000..eaf58cce8f31d56291c3b952d17aec0c2066de0e --- /dev/null +++ b/docs/en/25.03/Embedded/UniProton/UniProton-apis.md @@ -0,0 +1,6311 @@ +# UniProton接口说明 + +## 任务 + +### 创建并激活任务 + +在OS启动之前(比如在uniAppInit)中创建的任务,只是简单地加入就绪队列。 OS启动后创建的任务,如果优先级高于当前任务且未锁任务,则立即发生任务调度并被运行,否则加入就绪队列,等待执行。 + +**输入**: 任务创建参数,包括任务名、任务栈大小、任务优先级、任务处理函数等。 + +**处理**: + +1. 申请任务栈空间,初始化任务栈,置栈顶魔术字。 +2. 初始化任务上下文。 +3. 初始化任务控制块。 +4. 激活任务,任务是否马上能得到执行,取决于OS是否已经启动、优先级是否高于当前任务且没有锁任务调度、当前线程是否为硬中断。 + +**输出** : + +- 成功:任务ID,若任务具备执行条件,则直接运行任务,否则将任务挂入就绪队列。 + +- 失败:提示错误码。 + +### 删除任务 + + 删除任务并释放任务资源。 + +**输入**:任务ID。 + +**处理**: + +1. 检查任务是否具备删除条件,如锁任务调度情况下不允许删除任务。 +2. 如果任务处于阻塞状态,从对应的阻塞队列中摘除。 +3. 释放任务控制块。 +4. 释放任务栈空间。 +5. 从就绪队列中载入最高优先级的任务,若具备调度条件,则执行。 + +**输出**: + +- 成功:若具备调度条件,则执行就绪队列中的最高任务; + +- 失败:返回错误码。 + +### 挂起任务 + + 挂起任务。 + +**输入**:任务ID。 + +**处理**:将指定任务从就绪队列中摘除,若指定任务处于Running态,则会触发任务切换。 + +**输出**: + +- 成功:挂起指定任务。 + +- 失败:返回错误码。 + +### 恢复任务 + +恢复挂起的任务。 + +**输入**:任务ID。 + +**处理**:恢复挂起的任务,若任务仍处于延时、阻塞态,则只是取消挂起态,并不加入就绪队列。 + +**输出**: + +- 成功:取消任务挂起状态。 +- 失败:返回错误码。 + +### 任务延时 + +将当前任务延时指定时间。 + +**输入**:延时时间。 + +**处理**: + +1. 延时时间转换成OS的Tick数。 +2. 将当前任务从就绪队列中摘除,置成延时态。 +3. 从就绪队列中载入最高优先级的任务,并执行。 +4. Tick中断处理函数中判断任务的延时时间是否已经足够,如果足够,将任务加入就绪队列。 + +**输出**: + +- 成功:当前任务切出,就绪队列中的最高优先级任务切入。 +- 失败:返回错误码。 + +### 锁任务调度 + +禁止任务之间的切换。 + +**输入**:锁任务调度请求。 + +**处理**: + +1. 若有任务切换请求,将其清除。 +2. 锁任务调度次数依次递增。 + +**输出**: 任务之间无法切换。 + +### 恢复任务调度的锁/解锁状态 + +与锁任务调度配对使用,是否解锁任务调度,取决于最近一次锁任务调度前,是否允许任务调度。 + +**输入**:恢复任务调度的锁/解锁状态请求。 + +**处理**: + +1. 锁任务调度次数依次递减。 +2. 若锁任务调度次数等于0,则发起任务调度。 + +**输出**:若最近一次锁任务调度前,允许任务调度,则从就绪队列中载入最高优先级任务,并执行。否则,维持原状,不能发生任务切换。 + +### 任务PID合法性检查 + +检查指定任务PID是否合法。 + +**输入**:任务PID。 + +**处理**:判断输入的任务PID是否超过最大任务PID号或是否已创建。 + +**输出**: + +- TRUE :任务PID有效。 +- FALSE:任务PID无效。 + +### 任务私有数据获取 + +获取当前任务的私有数据。 + +**输入**:无。 + +**处理**:将任务TCB中记录的任务私有数据返回。 + +**输出**:任务私有数据。 + +### 查询本核指定任务正在PEND的信号量 + +查询指定任务正在PEND的信号量ID。 + +**输入**:任务PID。 + +**处理**: 根据任务状态和任务控制块,判断任务是否PEND在某个信号量上,以及PEND的信号量ID。 + +**输出**: + +- 成功:返回信号量ID。 +- 失败:返回错误码。 + +### 查询任务状态 + +获取指定任务的状态。 + +**输入**:任务PID。 + +**处理**:将指定任务的TCB中记录的任务状态字段返回。 + +**输出**: + +- 成功:返回任务状态信息。 +- 失败:返回错误码。 + +### 查询任务上下文信息 + +获取指定任务的上下文信息。 + +**输入**:任务PID。 + +**处理**: 将指定任务的TCB中记录的任务上下文信息返回。 + +**输出**: + +- 成功:返回任务上下文信息。 +- 失败:返回错误码。 + +### 查询任务基本信息 + +获取任务基本信息,包括任务切换时的PC,SP、任务状态、优先级、任务栈大小、栈顶值,任务名等。 + +**输入**:任务PID,用于存放任务基本信息查询结果的缓冲区 + +**处理**: 将指定任务的TCB中记录的任务基本信息返回。 + +**输出**: + +- 成功:返回任务基本信息。 +- 失败:返回错误码。 + +### 任务优先级获取 + +获取指定任务的优先级。 + +**输入**:任务PID + +**处理**:将指定任务的TCB中记录的优先级字段返回。 + +**输出**: + +- 成功:返回任务优先级信息。 +- 失败:返回错误码。 + +### 任务优先级设定 + +设置指定任务的优先级。 + +**输入**:任务PID、优先级值 + +**处理**:将输入的任务优先级信息存入指定任务TCB中优先级字段 + +**输出**: + +- 成功:指定任务的优先级被修改。 +- 失败:返回错误码。 + +### 调整指定优先级的任务调度顺序 + +设置指定任务的优先级以及调整调度顺序。 + +**输入**:指定的优先级、指定需要调整调度顺序的任务,用于保存被调整到队首的任务ID的缓冲。 + +**处理**:若指定要调整调度顺序的任务为TASK_NULL_ID,则优先级队列中的第一个就绪任务调整至队尾;否则,将指定要调整调度顺序的任务调整至优先级队列的队首。 + +**输出**: + +- 成功:指定优先级的任务调度顺序被修改。 +- 失败:返回错误码。 + +## 事件 + +### 写事件 + +写事件操作实现对指定任务写入指定类型的事件,可以一次同时写多个事件。 + +**输入**:任务ID、事件号。 + +**处理**: + +1. 对指定任务事件类型写上输入事件。 +2. 判断目的任务是否正在接收等待事件,且其等待的事件是否已经符合唤醒条件(唤醒条件即读取的事件已经发生)。 +3. 如果符合唤醒条件,则需清除任务读事件状态。 +4. 如果符合唤醒条件,则需清除任务读事件状态。 +5. 清除任务超时状态。 +6. 在任务没有被挂起的情况下,需要将任务加入就绪队列并尝试任务调度。 + +**输出**: + +- 成功:事件写入成功。 +- 失败:错误码。 + +### 读事件 + +读事件操作可以根据入参事件掩码类型读取单个或者多个事件。 + +**输入**:要读取的事件掩码、读取事件所采取的策略、超时时间、接收事件的指针。 + +**处理**: + +1. 根据入参事件掩码类型对自身任务输入读取事件类型。 +2. 判断事件读取模式,是读取输入的所有事件还是其中的任意一种事件。 +3. 根据读取模式,判断期望的事件是否满足读取情况。 +4. 判断事件等待模式:如果为等待事件模式则根据模式来设置相应的超时时间;如果为非等待模式则事件读取失败。 +5. 如果需要等待阻塞读取,则需要将自己的任务从就绪列表中删除,并进行任务调度。 +6. 读取成功后,清除读取的事件类型,并且把事件类型返回。 + +**输出**: + +- 成功:读事件成功,事件指针赋值。 +- 失败:错误码 + +## 队列 + +### 创建队列 + +创建一个队列,创建时可以设定队列长度和队列结点大小。 + +**输入**: 队列节点个数、每个队列节点大小、队列ID指针。 + +**处理**: + +1. 申请一个空闲的队列资源。 +2. 申请队列所需内存。 +3. 初始化队列配置。 + +**输出**: + +- 成功:队列ID。 +- 失败:错误码。 + +### 读队列 + +读指定队列的数据。 + +**输入**:队列ID、缓冲区指针、长度指针、超时时间。 + +**处理**: + +1. 获取指定队列控制块。 +2. 读队列PEND标志,根据缓冲区大小填入队列数据。 +3. 修改队列头指针。 + +**输出**: + +- 成功:缓冲区内填入队列数据。 +- 失败:错误码。 + +### 写队列 + +写数据到指定队列。 + +**输入**: 队列ID、缓冲区指针、缓冲区长度、超时时间、优先级。 + +**处理**: + +1. 获取指定队列控制块。 +2. 读队列PEND标志,选取消息节点,初始化消息节点并拷贝数据。 +3. 队列读资源计数器加一。 + +**输出**: + +- 成功:写入队列数据成功。 +- 失败:错误码。 + +### 删除队列 + +删除一个消息队列,删除后队列资源被回收。 + +**输入**:队列ID。 + +**处理**: + +1. 获取指定队列控制块,确保队列未在使用中。 +2. 释放队列内存。 + +**输出**: + +- 成功:删除队列成功。 +- 失败:错误码 + +### 查询队列的历史最大使用长度 + +获取从队列创建到删除前的历史最大使用长度。 + +**输入**:队列ID、队列节点使用峰值指针。 + +**处理**: + +1. 获取指定队列控制块。 +2. 将队列节点使用峰值赋值到指针参数。 + +**输出**: + +- 成功:获取峰值成功。 +- 失败:错误码 + +### 查询指定源PID的待处理消息个数 + +从指定队列中,获取指定源PID的待处理消息个数。 + +**输入**:队列ID、线程PID、待处理的消息个数指针。 + +**处理**: + +1. 获取指定队列控制块。 +2. 遍历队列查询待处理的消息个数,赋值到指针变量。 + +**输出**: + +- 成功:获取待处理的消息个数成功。 +- 失败:错误码。 + +## 中断 + +### 创建硬中断 + +硬中断在使用前,必须先创建。 + +**输入**:硬中断的创建参数,如:硬中断号(与芯片相关)、硬中断优先级、硬中断处理函数等。 + +**处理**:根据硬中断号设置硬中断优先级、处理函数。 + +**输出**: + +- 成功:硬中断触发后,CPU能够响应该硬中断,并回调硬中断处理函数。 +- 失败:返回错误码。 + +### 硬中断属性设置 + +在创建硬中断前,需要设置硬中断的模式,包括独立型(#OS_HWI_MODE_ENGROSS)和组合型(#OS_HWI_MODE_COMBINE)两种配置模式。 + +**输入**:硬中断号、硬中断模式。 + +**处理**:根据硬中断号设置硬中断的模式; + +**输出**: + +- 成功:指定的硬中断号被设置好硬中断模式。 +- 失败:返回错误码。 + +### 删除硬中断 + +删除相应硬中断或事件,取消硬中断处理函数的注册。 + +**输入**:硬中断号。 + +**处理**:取消指定硬中断的处理函数与中断号的绑定关系。 + +**输出**:硬中断被删除,当硬中断信号触发后,CPU不会响应该中断。 + +### 使能硬中断 + +使能指定的硬中断。 + +**输入**:硬中断号。 + +**处理**:将指定硬中断的使能位置位。 + +**输出**:指定的硬中断被使能,当硬中断信号触发后,CPU会响应该中断。 + +### 屏蔽硬中断 + +屏蔽指定的硬中断。 + +**输入**:硬中断号。 + +**处理**:清除指定硬中断的使能位。 + +**输出**:指定的硬中断被屏蔽,当硬中断信号触发后,CPU不会响应该中断。 + +### 恢复指定硬中断 + +恢复指定的硬中断。 + +**输入**:硬中断号、中断使能寄存器的保存值。 + +**处理**:还原指定硬中断的使能位。 + +**输出**:指定中断的使能位恢复为指定状态。 + +### 禁止硬中断 + +禁止响应所有可屏蔽硬中断。 + +**输入**:禁止硬中断请求。 + +**处理**: + +1. 记录系统状态,用于后续返回。 +2. 禁止响应所有可屏蔽硬中断。 + +**输出**: + +- 所有可屏蔽硬中断都不能响应。 +- 禁止硬中断响应前的系统状态。 + +### 恢复硬中断 + +恢复硬中断的禁止或允许响应状态,与禁止硬中断配对使用。是否允许响应硬中断,取决于最近一次禁止硬中断前,系统是否允许响应硬中断。 + +**输入**:最近一次禁止硬中断前的系统状态。 + +**处理**:将系统状态恢复到最近一次禁止硬中断前。 + +**输出**:系统状态恢复到最近一次禁止硬中断前。 + +### 响应硬中断 + +硬中断触发后,CPU会响应硬中断。 + +**输入**:硬件触发的硬中断信号,且系统没有禁止硬中断。 + +**处理**: + +1. 保存当前上下文。 +2. 调用硬中断处理函数。 +3. 若任务被打断,则恢复最高优先级任务的上下文,该任务不一定是被中断打断的任务。 +4. 若低优先级中断被打断,则直接恢复低先级中断的上下文。 + +**输出**:硬中断被响应。 + +### 触发硬中断 + +触发指定核号的指定硬中断。 + +**输入**:核号、硬中断号。 + +**处理**: + +1. 目前只支持触发本核的硬中断,若指定的核号不为本核,则做报错处理。 +2. 目前只支持触发软件可触发的硬中断,若指定的中断无法进行软件触发,则做报错处理。 +3. 当以前两个条件都满足,则设置对应的中断触发寄存器,软件触发中断。 + +**输出**: + +- 成功:响应的硬中断被触发。 +- 失败:返回错误码。 + +### 清除中断位 + +清除所有的中断请求位或指定的中断请求位。 + +**输入**:硬中断号。 + +**处理**:清除所有的中断请求位或指定的中断请求位。 + +**输出**:所有的中断请求位或指定的中断请求位被清除 + +## 定时器 + +### 定时器创建 + +根据定时器类型,触发模式,定时时长,处理函数等创建一个定时器。 + +**输入**: + +1. 创建参数结构体(包括定时器类型,触发模式,定时时长,处理函数等)。 +2. 用于保存输出的定时器句柄的指针。 + +**处理**:根据入参找到空闲控制块,将入参内容填入控制块中相应的字段中。 + +**输出**: + +- 成功:定时器创建成功,后续可根据得到的定时器句柄做启动、删除等操作。 +- 失败:返回错误码。 + +### 定时器删除 + +删除指定的定时器。 + +**输入**: 定时器句柄 + +**处理**:根据传入的定时器句柄,找到定时器控制块,将其内容清空并将控制块挂接到相应的空闲链表中。 + +**输出**: + +- 成功:定时器被删除。 +- 失败:返回错误码。 + +### 定时器启动 + +指定的定时器开始计时。 + +**输入**: 定时器句柄 + +**处理**:对于软件定时器,根据当前Tick计数以及定时器周期,计算结束时间,将此定时器控制块挂入定时器SortLink。 + +**输出**: + +- 成功:定时器开始计时。 +- 失败:返回错误码。 + +### 定时器停止 + +指定的定时器停止计时。 + +**输入**:定时器句柄。 + +**处理**:对于软件定时器,计算剩余时间并将其保存后,将此定时器控制块从定时器SortLink中摘除。 + +**输出**: + +- 成功:指定任务的信号量计数值被修改。 +- 失败:返回错误码。 + +### 定时器重启 + +指定的定时器重新开始计时。 + +**输入**:定时器句柄 + +**处理**:对于软件定时器,根据当前Tick计数以及定时器周期,计算结束时间,将此定时器控制块挂入定时器SortLink。 + +**输出**: + +- 成功:指定任务的信号量计数值被修改。 +- 失败:返回错误码。 + +### 软件定时器组创建 + +创建一个软件定时器组,后续的软件定时器创建时需要以此为基础。 + +**输入**: + +1. 软件定时器组创建参数(主要关注时钟源类型及最大支持的定时器个数)。 +2. 用于保存输出的定时器组号的地址。 + +**处理**:根据传入的最大支持的定时器个数申请定时器控制块内存,并完成其初始化操作。 + +**输出**: + +- 成功:基于Tick的软件定时器组被成功创建。 +- 失败:返回错误码。 + +## 信号量 + +### 信号量创建 + +创建一个信号量,并设置其初始计数器数值。 + +**输入**:信号量初始计数值、用于保存创建得到句柄的地址。 + +**处理**:找到一个空闲信号量控制块,将输入的初始计数值填入后将信号量ID当做句柄返回。 + +**输出**: + +- 成功:信号量被创建。 +- 失败:返回错误码。 + +### 信号量删除 + +删除指定信号量,若有任务阻塞于该信号量,则删除失败。 + +**输入**:信号量句柄 + +**处理**:对于核内信号量,根据输入的信号量句柄找到信号量控制块,通过查看控制块中任务阻塞链表是否为空来判断是否有任务阻塞于该信号量,若有则删除失败返回,否则释放该信号量控制块。 + +**输出**: + +- 成功:信号量被删除。 +- 失败:返回错误码。 + +### Pend信号量 + +申请指定的信号量,若其计数值大于0,则直接将计数值减1返回,否则发生任务阻塞,等待时间可通过入参设定。 + +**输入**:信号量句柄、等待时间 + +**处理**: + +![](./figures/pend_semaphore.png) + +**输出**: + +- 成功:返回0。 +- 失败:返回错误码。 + +### Post信号量 + +发布信号量,将该信号量计数值+1,若有任务阻塞于该信号量,则将其唤醒。 + +**输入**:信号量句柄。 + +**处理**: + +![](./figures/post_semaphore.png) + +**输出**: + +- 成功:信号量发布成功。 +- 失败:返回错误码。 + +### 信号量计数值重置 + +设置指定信号量计数值,如果有任务阻塞于该信号量,则设置失败。 + +**输入**:信号量句柄、信号量计数值。 + +**处理**:根据输入的信号量句柄,找到相应的信号量控制块,查看控制块中任务阻塞链表,若其不为空,则返回错误,否则将控制块中信号量计数值设为输入的计数值。 + +**输出**: + +- 成功:指定信号量的计数值被修改; +- 失败:返回错误码。 + +### 信号量计数值获取 + + 获取指定信号量计数值。 + +**输入**: 信号量句柄 + +**处理**:根据输入的信号量句柄,找到相应的信号量控制块,将控制块中记录的信号量计数值返回。 + +**输出**: + +- 成功:返回信号量计数值。 +- 失败:返回错误计数值标记。 + +### 信号量阻塞任务PID获取 + +获取阻塞在指定信号量上的任务个数及任务PID列表。 + +**输入**: + +1. 信号量句柄。 +2. 用于存放输出的阻塞任务个数的地址。 +3. 用于存放输出的阻塞任务PID的缓冲区首地址。 +4. 用于存放输出的阻塞任务PID的缓冲区长度。 + +**处理**:若有任务阻塞于指定信号量,则输出阻塞任务的个数及任务PID清单;否则,将阻塞任务个数置为0。 + +**输出**: + +- 成功:输出阻塞于该信号量的任务个数及任务PID清单。 +- 失败:返回错误码。 + +## 异常 + +### 用户注册异常处理钩子 + +用户注册异常处理函数类型定义的异常处理函数钩子,记录异常信息。 + +**输入**:类型为ExcProcFunc的钩子函数。 + +**处理**:将用户注册的钩子函数注册到OS框架里,发生异常时调用。 + +**输出**: + +- 成功:注册成功。 +- 失败:返回错误码。 + +## CPU占用率 + +### 获取当前cpu占用率 + +通过本接口获取当前cpu占用率。 + +**输入**:无。 + +**处理**:采用基于IDLE计数的统计算法,统计结果会有一定误差,误差不超过百分之五。 + +**输出**: + +- 成功:返回当前的cpu占用率[0,10000]。 +- 失败:返回错误码。 + +### 获取指定个数的线程的CPU占用率 + +根据用户输入的线程个数,获取指定个数的线程CPU占用率。 + +**输入**: 线程个数、缓冲区指针、实际线程个数指针。 + +**处理**: + +1. 采用基于 IDLE 计数的统计算法,统计结果会有一定误差,误差不超过百分之五。 +2. 当配置项中的采样周期值等于0时,线程级CPUP采样周期为两次调用该接口或者PRT_CpupNow之间的间隔。否则,线程级CPUP采样周期为配置项中的OS_CPUP_SAMPLE_INTERVAL大小。 +3. 输出的实际线程个数不大于系统中实际的线程个数(任务个数和一个中断线程)。 +4. 若在一个采样周期内有任务被删除,则统计的任务线程和中断线程CPUP总和小于10000。 + +**输出**: + +- 成功:在缓冲区写入cpu占用率。 +- 失败:返回错误码。 + +### 设置CPU占用率告警阈值 + +根据用户配置的 CPU 占用率告警阈值 warn 和告警恢复阈值 resume,设置告警和恢复阈值。 + +**输入**:告警阈值、恢复阈值。 + +**处理**:设置 CPUP 告警阈值和恢复阈值 + +**输出**: + +- 成功:设置成功。 +- 失败:返回错误码。 + +### 查询CPUP告警阈值和告警恢复阈值 + +根据用户配置的告警阈值指针 warn 和告警恢复阈值指针 resume,查询告警阈值和告警恢复阈值。 + +**输入**:告警阈值指针、恢复阈值指针。 + +**处理**:获取 CPUP 告警阈值和恢复阈值,赋值指针变量。 + +**输出**: + +- 成功:获取成功。 +- 失败:返回错误码。 + +### 注册CPUP告警回调函数 + +根据用户配置的回调函数 hook,注册 CPUP 告警回调函数。 + +**输入**:类型为 CpupHookFunc 的 CPU 告警回调函数。 + +**处理**:将用户的钩子函数注册到 OS 框架。 + +**输出**: + +- 成功:注册成功。 +- 失败:错误码 + +## OS启动 + +### main函数入口 + +二进制执行文件函数入口。 + +**输入**:无 + +**输出**: + +- 成功:返回OK。 +- 失败:错误码 + +### 用户业务入口 + +PRT_AppInit 用户业务函数入口,在 main 函数后调用,在此函数中添加业务功能代码。 + +**输入**:无 + +**输出**: + +- 成功:返回OK。 +- 失败:错误码 + +### 硬件驱动初始化入口 + +PRT_HardDrvInit 硬件驱动初始化函数入口,在 main 函数后调用,在此函数中添加板级驱动初始化功能代码。 + +**输入**:无 + +**输出**: + +- 成功:返回OK。 +- 失败:错误码 + +### 硬件启动流程入口 + +PRT_HardBootInit 在 OS 启动时调用,在main函数前被调用,可以用于 BSS 初始化、随机值设置等。 + +**输入**:无 + +**输出**: + +- 成功:返回OK。 +- 失败:错误码。 + +## openamp + +### 初始化openamp资源函数 + +初始化保留内存,初始化 remoteproc、virtio、rpmsg,建立 Uniproton 与 Linux 两端配对的 endpoint,供消息收发使用。 + +**输入**:无。 + +**输出**: + +- 成功:初始化成功。 +- 失败:错误码。 + +### 消息接收函数 + +接收消息,并触发SGI中断 + +**输入**: + +1. 类型为 unsigned char * 的存储消息的缓冲区。 +2. 类型为 int 的消息预期长度。 +3. 类型为 int *,用于获取消息实际长度。 + +**输出**: + +- 成功:消息接收成功。 +- 失败:错误码。 + +### 消息发送函数 + +发送消息和SGI中断 + +**输入**:类型为 unsigned char * 的存储消息的缓冲区、类型为 int 的消息长度。 + +**输出**: + +- 成功:消息发送成功。 +- 失败:错误码。 + +### 释放openamp资源 + +用于释放openamp资源。 + +**输入**:无 + +**输出**: + +- 成功:资源释放成功。 +- 失败:错误码。 + +## POSIX接口 + +| 接口名 | 适配情况 | +| :---: | :-----: | +| [pthread_atfork](#pthread_atfork) | 不支持 | +| [pthread_attr_destroy](#pthread_attr_destroy) | 支持 | +| [pthread_attr_getdetachstate](#pthread_attr_getdetachstate) | 支持 | +| [pthread_attr_getguardsize](#pthread_attr_getguardsize) | 不支持 | +| [pthread_attr_getinheritsched](#pthread_attr_getinheritsched) | 支持 | +| [pthread_attr_getschedparam](#pthread_attr_getschedparam) | 支持 | +| [pthread_attr_getschedpolicy](#pthread_attr_getschedpolicy) | 支持 | +| [pthread_attr_getscope](#pthread_attr_getscope) | 支持 | +| [pthread_attr_getstack](#pthread_attr_getstack) | 支持 | +| [pthread_attr_getstackaddr](#pthread_attr_getstackaddr) | 支持 | +| [pthread_attr_getstacksize](#pthread_attr_getstacksize) | 支持 | +| [pthread_attr_init](#pthread_attr_init) | 支持 | +| [pthread_attr_setdetachstate](#pthread_attr_setdetachstate) | 支持 | +| [pthread_attr_setguardsize](#pthread_attr_setguardsize) | 不支持 | +| [pthread_attr_setinheritsched](#pthread_attr_setinheritsched) | 支持 | +| [pthread_attr_setschedparam](#pthread_attr_setschedparam) | 部分支持 | +| [pthread_attr_setschedpolicy](#pthread_attr_setschedpolicy) | 部分支持 | +| [pthread_attr_setscope](#pthread_attr_setscope) | 部分支持 | +| [pthread_attr_setstack](#pthread_attr_setstack) | 支持 | +| [pthread_attr_setstackaddr](#pthread_attr_setstackaddr) | 支持 | +| [pthread_attr_setstacksize](#pthread_attr_setstacksize) | 支持 | +| [pthread_barrier_destroy](#pthread_barrier_destroy) | 支持 | +| [pthread_barrier_init](#pthread_barrier_init) | 部分支持 | +| [pthread_barrier_wait](#pthread_barrier_wait) | 支持 | +| [pthread_barrierattr_getpshared](#pthread_barrierattr_getpshared) | 支持 | +| [pthread_barrierattr_setpshared](#pthread_barrierattr_setpshared) | 部分支持 | +| [pthread_cancel](#pthread_cancel) | 支持 | +| [pthread_cond_broadcast](#pthread_cond_broadcast) | 支持 | +| [pthread_cond_destroy](#pthread_cond_destroy) | 支持 | +| [pthread_cond_init](#pthread_cond_init) | 支持 | +| [pthread_cond_signal](#pthread_cond_signal) | 支持 | +| [pthread_cond_timedwait](#pthread_cond_timedwait) | 支持 | +| [pthread_cond_wait](#pthread_cond_wait) | 支持 | +| [pthread_condattr_destroy](#pthread_condattr_destroy) | 支持 | +| [pthread_condattr_getclock](#pthread_condattr_getclock) | 支持 | +| [pthread_condattr_getpshared](#pthread_condattr_getpshared) | 支持 | +| [pthread_condattr_init](#pthread_condattr_init) | 支持 | +| [pthread_condattr_setclock](#pthread_condattr_setclock) | 部分支持 | +| [pthread_condattr_setpshared](#pthread_condattr_setpshared) | 部分支持 | +| [pthread_create](#pthread_create) | 支持 | +| [pthread_detach](#pthread_detach) | 支持 | +| [pthread_equal](#pthread_equal) | 支持 | +| [pthread_exit](#pthread_exit) | 支持 | +| [pthread_getcpuclockid](#pthread_getcpuclockid) | 不支持 | +| [pthread_getschedparam](#pthread_getschedparam) | 支持 | +| [pthread_getspecific](#pthread_getspecific) | 支持 | +| [pthread_join](#pthread_join) | 支持 | +| [pthread_key_create](#pthread_key_create) | 支持 | +| [pthread_key_delete](#pthread_key_delete) | 支持 | +| [pthread_kill](#pthread_kill) | 不支持 | +| [pthread_mutex_consistent](#pthread_mutex_consistent) | 不支持 | +| [pthread_mutex_destroy](#pthread_mutex_destroy) | 支持 | +| [pthread_mutex_getprioceiling](#pthread_mutex_getprioceiling) | 不支持 | +| [pthread_mutex_init](#pthread_mutex_init) | 支持 | +| [pthread_mutex_lock](#pthread_mutex_lock) | 支持 | +| [pthread_mutex_setprioceiling](#pthread_mutex_setprioceiling) | 不支持 | +| [pthread_mutex_timedlock](#pthread_mutex_timedlock) | 支持 | +| [pthread_mutex_trylock](#pthread_mutex_trylock) | 支持 | +| [pthread_mutex_unlock](#pthread_mutex_unlock) | 支持 | +| [pthread_mutexattr_destroy](#pthread_mutexattr_destroy) | 支持 | +| [pthread_mutexattr_getprioceiling](#pthread_mutexattr_getprioceiling) | 不支持 | +| [pthread_mutexattr_getprotocol](#pthread_mutexattr_getprotocol) | 支持 | +| [pthread_mutexattr_getpshared](#pthread_mutexattr_getpshared) | 部分支持 | +| [pthread_mutexattr_getrobust](#pthread_mutexattr_getrobust) | 部分支持 | +| [pthread_mutexattr_gettype](#pthread_mutexattr_gettype) | 支持 | +| [pthread_mutexattr_init](#pthread_mutexattr_init) | 支持 | +| [pthread_mutexattr_setprioceiling](#pthread_mutexattr_setprioceiling) | 不支持 | +| [pthread_mutexattr_setprotocol](#pthread_mutexattr_setprotocol) | 部分支持 | +| [pthread_mutexattr_setpshared](#pthread_mutexattr_setpshared) | 不支持 | +| [pthread_mutexattr_setrobust](#pthread_mutexattr_setrobust) | 部分支持 | +| [pthread_mutexattr_settype](#pthread_mutexattr_settype) | 支持 | +| [pthread_once](#pthread_once) | 部分支持 | +| [pthread_rwlock_destroy](#pthread_rwlock_destroy) | 支持 | +| [pthread_rwlock_init](#pthread_rwlock_init) | 支持 | +| [pthread_rwlock_rdlock](#pthread_rwlock_rdlock) | 支持 | +| [pthread_rwlock_timedrdlock](#pthread_rwlock_timedrdlock) | 支持 | +| [pthread_rwlock_timedwrlock](#pthread_rwlock_timedwrlock) | 支持 | +| [pthread_rwlock_tryrdlock](#pthread_rwlock_tryrdlock) | 支持 | +| [pthread_rwlock_trywrlock](#pthread_rwlock_trywrlock) | 支持 | +| [pthread_rwlock_unlock](#pthread_rwlock_unlock) | 支持 | +| [pthread_rwlock_wrlock](#pthread_rwlock_wrlock) | 支持 | +| [pthread_rwlockattr_destroy](#pthread_rwlockattr_destroy) | 不支持 | +| [pthread_rwlockattr_getpshared](#pthread_rwlockattr_getpshared) | 部分支持 | +| [pthread_rwlockattr_init](#pthread_rwlockattr_init) | 不支持 | +| [pthread_rwlockattr_setpshared](#pthread_rwlockattr_setpshared) | 部分支持 | +| [pthread_self](#pthread_self) | 支持 | +| [pthread_setcancelstate](#pthread_setcancelstate) | 支持 | +| [pthread_setcanceltype](#pthread_setcanceltype) | 支持 | +| [pthread_setschedparam](#pthread_setschedparam) | 部分支持 | +| [pthread_setschedprio](#pthread_setschedprio) | 支持 | +| [pthread_setspecific](#pthread_setspecific) | 支持 | +| [pthread_sigmask](#pthread_sigmask) | 不支持 | +| [pthread_spin_init](#pthread_spin_init) | 不支持 | +| [pthread_spin_destory](#pthread_spin_destory) | 不支持 | +| [pthread_spin_lock](#pthread_spin_lock) | 不支持 | +| [pthread_spin_trylock](#pthread_spin_trylock) | 不支持 | +| [pthread_spin_unlock](#pthread_spin_unlock) | 不支持 | +| [pthread_testcancel](#pthread_testcancel) | 支持 | +| [sem_close](#sem_close) | 支持 | +| [sem_destroy](#sem_destroy) | 支持 | +| [sem_getvalue](#sem_getvalue) | 支持 | +| [sem_init](#sem_init) | 支持 | +| [sem_open](#sem_open) | 支持 | +| [sem_post](#sem_post) | 支持 | +| [sem_timedwait](#sem_timedwait) | 支持 | +| [sem_trywait](#sem_trywait) | 支持 | +| [sem_unlink](#sem_unlink) | 部分支持 | +| [sem_wait](#sem_wait) | 支持 | +| [sched_yield](#sched_yield) | 支持 | +| [sched_get_priority_max](#sched_get_priority_max) | 支持 | +| [sched_get_priority_min](#sched_get_priority_min) | 支持 | +| [asctime](#asctime) | 支持 | +| [asctime_r](#asctime_r) | 支持 | +| [clock](#clock) | 支持 | +| [clock_getcpuclockid](#clock_getcpuclockid) | 部分支持 | +| [clock_getres](#clock_getres) | 部分支持 | +| [clock_gettime](#clock_gettime) | 支持 | +| [clock_nanosleep](#clock_nanosleep) | 部分支持 | +| [clock_settime](#clock_settime) | 支持 | +| [ctime](#ctime) | 支持 | +| [ctime_r](#ctime_r) | 支持 | +| [difftime](#difftime) | 支持 | +| [getdate](#getdate) | 不支持 | +| [gettimeofday](#gettimeofday) | 支持 | +| [gmtime](#gmtime) | 支持 | +| [gmtime_r](#gmtime_r) | 支持 | +| [localtime](#localtime) | 支持 | +| [localtime_r](#localtime_r) | 支持 | +| [mktime](#mktime) | 支持 | +| [nanosleep](#nanosleep) | 支持 | +| [strftime](#strftime) | 不支持 | +| [strftime_l](#strftime_l) | 不支持 | +| [strptime](#strptime) | 支持 | +| [time](#time) | 支持 | +| [timer_create](#timer_create) | 支持 | +| [timer_delete](#timer_delete) | 支持 | +| [timer_getoverrun](#timer_getoverrun) | 支持 | +| [timer_gettime](#timer_gettime) | 支持 | +| [timer_settime](#timer_settime) | 支持 | +| [times](#times) | 支持 | +| [timespec_get](#timespec_get) | 支持 | +| [utime](#utime) | 不支持 | +| [wcsftime](#wcsftime) | 不支持 | +| [wcsftime_l](#wcsftime_l) | 不支持 | +| [malloc](#malloc) | 支持 | +| [free](#free) | 支持 | +| [memalign](#memalign) | 支持 | +| [realloc](#realloc) | 支持 | +| [malloc_usable_size](#malloc_usable_size) | 支持 | +| [aligned_alloc](#aligned_alloc) | 支持 | +| [reallocarray](#reallocarray) | 支持 | +| [calloc](#calloc) | 支持 | +| [posix_memalign](#posix_memalign) | 支持 | +| [abort](#abort) | 支持 | +| [_Exit](#_Exit) | 支持 | +| [atexit](#atexit) | 支持 | +| [quick_exit](#quick_exit) | 支持 | +| [at_quick_exit](#at_quick_exit) | 支持 | +| [assert](#assert) | 支持 | +| [div](#div) | 支持 | +| [ldiv](#ldiv) | 支持 | +| [lldiv](#lldiv) | 支持 | +| [imaxdiv](#imaxdiv) | 支持 | +| [wcstol](#wcstol) | 支持 | +| [wcstod](#wcstod) | 支持 | +| [fcvt](#fcvt) | 支持 | +| [ecvt](#ecvt) | 支持 | +| [gcvt](#gcvt) | 支持 | +| [qsort](#qsort) | 支持 | +| [abs](#abs) | 支持 | +| [labs](#labs) | 支持 | +| [llabs](#llabs) | 支持 | +| [imaxabs](#imaxabs) | 支持 | +| [strtol](#strtol) | 支持 | +| [strtod](#strtod) | 支持 | +| [atoi](#atoi) | 支持 | +| [atol](#atol) | 支持 | +| [atoll](#atoll) | 支持 | +| [atof](#atof) | 支持 | +| [bsearch](#bsearch) | 支持 | +| [semget](#semget) | 支持 | +| [semctl](#semctl) | 部分支持 | +| [semop](#semop) | 部分支持 | +| [semtimedop](#semtimedop) | 部分支持 | +| [msgget](#msgget) | 支持 | +| [msgctl](#msgctl) | 部分支持 | +| [msgsnd](#msgsnd) | 部分支持 | +| [msgrcv](#msgrcv) | 部分支持 | +| [shmget](#shmget) | 不支持 | +| [shmctl](#shmctl) | 不支持 | +| [shmat](#shmat) | 不支持 | +| [shmdt](#shmdt) | 不支持 | +| [ftok](#ftok) | 不支持 | +| [fstatat](#fstatat) | 支持 | +| [fchmodat](#fchmodat) | 支持 | +| [mkdir](#mkdir) | 支持 | +| [chmod](#chmod) | 支持 | +| [lstat](#lstat) | 支持 | +| [utimensat](#utimensat) | 支持 | +| [mkfifo](#mkfifo) | 支持 | +| [fchmod](#fchmod) | 支持 | +| [mknod](#mknod) | 支持 | +| [statvfs](#statvfs) | 支持 | +| [mkfifoat](#mkfifoat) | 支持 | +| [umask](#umask) | 支持 | +| [mknodat](#mknodat) | 支持 | +| [futimesat](#futimesat) | 支持 | +| [lchmod](#lchmod) | 支持 | +| [futimens](#futimens) | 支持 | +| [mkdirat](#mkdirat) | 支持 | +| [fstat](#fstat) | 支持 | +| [stat](#stat) | 支持 | +| [open](#open) | 支持 | +| [creat](#creat) | 支持 | +| [posix_fadvise](#posix_fadvise) | 不支持 | +| [fcntl](#fcntl) | 支持 | +| [posix_fallocate](#posix_fallocate) | 支持 | +| [openat](#openat) | 支持 | +| [scandir](#scandir) | 不支持 | +| [seekdir](#seekdir) | 支持 | +| [readdir_r](#readdir_r) | 不支持 | +| [fdopendir](#fdopendir) | 支持 | +| [versionsort](#versionsort) | 支持 | +| [alphasort](#alphasort) | 支持 | +| [rewinddir](#rewinddir) | 支持 | +| [dirfd](#dirfd) | 支持 | +| [readdir](#readdir) | 不支持 | +| [telldir](#telldir) | 支持 | +| [closedir](#closedir) | 支持 | +| [opendir](#opendir) | 支持 | +| [putwchar](#putwchar) | 支持 | +| [fgetws](#fgetws) | 支持 | +| [vfwprintf](#vfwprintf) | 支持 | +| [fscanf](#fscanf) | 支持 | +| [snprintf](#snprintf) | 支持 | +| [sprintf](#sprintf) | 支持 | +| [fgetpos](#fgetpos) | 支持 | +| [vdprintf](#vdprintf) | 支持 | +| [gets](#gets) | 支持 | +| [ungetc](#ungetc) | 支持 | +| [ftell](#ftell) | 支持 | +| [clearerr](#clearerr) | 支持 | +| [getc_unlocked](#getc_unlocked) | 支持 | +| [fmemopen](#fmemopen) | 支持 | +| [putwc](#putwc) | 支持 | +| [getchar](#getchar) | 支持 | +| [open_wmemstream](#open_wmemstream) | 支持 | +| [asprintf](#asprintf) | 支持 | +| [funlockfile](#funlockfile) | 支持 | +| [fflush](#fflush) | 支持 | +| [vfprintf](#vfprintf) | 支持 | +| [vsscanf](#vsscanf) | 支持 | +| [vfwscanf](#vfwscanf) | 支持 | +| [puts](#puts) | 支持 | +| [getchar_unlocked](#getchar_unlocked) | 支持 | +| [setvbuf](#setvbuf) | 支持 | +| [getwchar](#getwchar) | 支持 | +| [setbuffer](#setbuffer) | 支持 | +| [vsnprintf](#vsnprintf) | 支持 | +| [freopen](#freopen) | 支持 | +| [fwide](#fwide) | 支持 | +| [sscanf](#sscanf) | 支持 | +| [fgets](#fgets) | 支持 | +| [vswscanf](#vswscanf) | 支持 | +| [vprintf](#vprintf) | 支持 | +| [fputws](#fputws) | 支持 | +| [wprintf](#wprintf) | 支持 | +| [wscanf](#wscanf) | 支持 | +| [fputc](#fputc) | 支持 | +| [putchar](#putchar) | 支持 | +| [flockfile](#flockfile) | 支持 | +| [vswprintf](#vswprintf) | 支持 | +| [fputwc](#fputwc) | 支持 | +| [fopen](#fopen) | 支持 | +| [tmpnam](#tmpnam) | 支持 | +| [ferror](#ferror) | 支持 | +| [printf](#printf) | 支持 | +| [open_memstream](#open_memstream) | 支持 | +| [fwscanf](#fwscanf) | 支持 | +| [fprintf](#fprintf) | 支持 | +| [fgetc](#fgetc) | 支持 | +| [rewind](#rewind) | 支持 | +| [getwc](#getwc) | 支持 | +| [scanf](#scanf) | 支持 | +| [perror](#perror) | 支持 | +| [vsprintf](#vsprintf) | 支持 | +| [vasprintf](#vasprintf) | 支持 | +| [getc](#getc) | 支持 | +| [dprintf](#dprintf) | 支持 | +| [popen](#popen) | 不支持 | +| [putc](#putc) | 支持 | +| [fseek](#fseek) | 支持 | +| [fgetwc](#fgetwc) | 支持 | +| [tmpfile](#tmpfile) | 支持 | +| [putw](#putw) | 支持 | +| [tempnam](#tempnam) | 支持 | +| [vwprintf](#vwprintf) | 支持 | +| [getw](#getw) | 支持 | +| [putchar_unlocked](#putchar_unlocked) | 支持 | +| [fread](#fread) | 支持 | +| [fileno](#fileno) | 支持 | +| [remove](#remove) | 支持 | +| [putc_unlocked](#putc_unlocked) | 支持 | +| [fclose](#fclose) | 支持 | +| [feof](#feof) | 支持 | +| [fwrite](#fwrite) | 支持 | +| [setbuf](#setbuf) | 支持 | +| [pclose](#pclose) | 不支持 | +| [swprintf](#swprintf) | 支持 | +| [fwprintf](#fwprintf) | 支持 | +| [swscanf](#swscanf) | 支持 | +| [rename](#rename) | 支持 | +| [getdelim](#getdelim) | 支持 | +| [vfscanf](#vfscanf) | 支持 | +| [setlinebuf](#setlinebuf) | 支持 | +| [fputs](#fputs) | 支持 | +| [fsetpos](#fsetpos) | 支持 | +| [fopencookie](#fopencookie) | 支持 | +| [fgetln](#fgetln) | 支持 | +| [vscanf](#vscanf) | 支持 | +| [ungetwc](#ungetwc) | 支持 | +| [getline](#getline) | 支持 | +| [ftrylockfile](#ftrylockfile) | 支持 | +| [vwscanf](#vwscanf) | 支持 | + +### 任务管理 + +#### pthread_attr_init + +pthread_attr_init() 函数初始化一个线程对象的属性,需要用 pthread_attr_destroy() 函数对其去除初始化。 + +**参数**:指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr,结构中的元素分别对应着新线程的运行属性。 + +**输出**: + +- 0:初始化成功。 +- ENOMEM:内存不足,无法初始化线程属性对象。 +- EBUSY:attr是以前初始化但未销毁的线程属性。 + +#### pthread_attr_destroy + +pthread_attr_destroy()函数应销毁线程属性对象。被销毁的attr属性对象可以使用pthread_attr_init()重新初始化;在对象被销毁后引用该对象的结果是未定义的。 + +**参数**:指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr。 + +**输出**: + +- 0:函数销毁对象成功。 +- EINVAL:attr指向的是未初始化的线程属性对象。 + +#### pthread_attr_setstackaddr + +pthread_attr_setstackaddr()函数设置attr对象中的线程创建堆栈addr属性。堆栈addr属性指定用于创建线程堆栈的存储位置。 + +**输入**:指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr、 栈地址stackaddr。 + +**输出**: + +- 0:设置成功。 +- EINVAL:attr指向的是未初始化的线程属性对象。 + +#### pthread_attr_getstackaddr + +pthread_attr_getstackaddr()如果成功,函数将堆栈地址属性值存储在堆栈地址中。 + +**参数**:指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr、栈地址stackaddr. + +**输出**: + +- 0:获取成功。 +- EINVAL:attr指向的是未初始化的线程属性对象。 + +#### pthread_attr_getstacksize + +pthread_attr_getstacksize()和pthread_attr_setstacksize()函数分别应获取和设置 attr 对象中的线程创建堆栈大小属性(以字节为单位)。 + +**参数**: + +1. 指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr. +2. 栈大小指针stacksize,指向设置或获取的堆栈大小。 + +**输出**: + +- 0:获取成功。 +- EINVAL:attr指向的是未初始化的线程属性对象。 + +#### pthread_attr_setstacksize + +设置attr对象中的线程创建堆栈大小属性。 + +**参数**: + +1. 指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr。 +2. 栈大小指针stacksize,指向设置或获取的堆栈大小。 + +**输出**: + +- 0:设置成功。 +- EINVAL:堆栈size小于最小值或超过限制。 + +#### pthread_attr_getinheritsched + +获取线程的继承属性。 + +**参数**: + +- 指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr。 +- 线程的继承性指针inheritsched。 + +**输出**: + +- 0:获取成功。 +- EINVAL:attr指向的是未初始化的线程属性对象。 + +#### pthread_attr_setinheritsched + +设置线程的继承属性。可设置如下参数: + +- PTHREAD_INHERIT_SCHED:指定线程调度属性应继承自创建线程,并且应忽略此attr参数中的调度属性。 +- PTHREAD_EXPLICIT_SCHED:指定线程调度属性应设置为此属性对象中的相应值。 + +**参数**: + +- 指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr。 +- 线程的继承性inheritsched。 + +**输出**: + +- 0:设置成功。 +- EINVAL:继承的值无效,或attr指向的是未初始化的线程属性对象。 +- ENOTSUP:试图将属性设置为不支持的值。 + +#### pthread_attr_getschedpolicy + +获取调度策略属性,策略支持SCHED_FIFO。当使用调度策略SCHED_FIFO执行的线程正在等待互斥体时,互斥体解锁,它们应按优先级顺序获取互斥体。 + +**参数**: + +1. 指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr。 +2. 线程的调度策略指针policy。 + +**输出**: + +- 0:获取成功。 +- EINVAL:attr指向的是未初始化的线程属性对象。 + +#### pthread_attr_setschedpolicy + +设置调度策略属性,策略支持SCHED_FIFO。当使用调度策略SCHED_FIFO执行的线程正在等待互斥体时,互斥体解锁时,它们应按优先级顺序获取互斥体。 + +**参数**: + +1. 指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr。 +2. 线程的调度策略policy。 + +**输出**: + +- 0:设置成功。 +- EINVAL:policy的值无效,或者attr指向没有初始化的线程对象。 +- ENOTSUP:试图将属性设置为不支持的值。 + +#### pthread_attr_getdetachstate + +获取线程分离属性,分离状态应设置为PTHREAD_CREATE_DETAED或PTHREAD_CREATE_JOI无BLE。 + +**参数**: + +1. 指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr。 +2. 分离属性指针detachstate。 + +**输出**: + +- 0:获取成功。 +- EINVAL:attr指向没有初始化的线程对象。 + +#### pthread_attr_setdetachstate + +设置线程分离属性。分离状态应设置为PTHREAD_CREATE_DETAED或PTHREAD_CREATE_JOINABLE。 + +**参数**: + +1. 指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr。 +2. 分离属性detachstate。 + +**输出**: + +- 0:设置成功。 +- EINVAL:attr指向没有初始化的线程对象或分离状态的值无效。 + +#### pthread_attr_setschedparam + +pthread_attr_setschedparam() 可用来设置线程属性对象的优先级属性。 + +**参数**: + +1. 指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr。 +2. 调度属性指针schedparam。 + +**输出**: + +- 0:操作成功。 +- EINVAL:参数不合法或attr未初始化。 +- ENOTSUP:schedparam的优先级属性不支持。 + +#### pthread_attr_getschedparam + +pthread_attr_getschedparam() 可用来获取线程属性对象的优先级属性。 + +**参数**: + +1. 指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr。 +2. 调度属性指针schedparam。 + +**输出**: + +- 0:操作成功。 +- EINVAL:参数不合法或attr未初始化。 + +#### pthread_attr_getscope + +pthread_attr_getscope() 可用来获取线程属性对象的作用域属性。 + +**参数**: + +- 指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr。 +- 线程的作用域属性指针scope。 + +**输出**: + +- 0:获取成功。 +- EINVAL:指针未初始化。 + +#### pthread_attr_setscope + +设置线程的作用域,支持PTHREAD_SCOPE_SYSTEM,控制线程在系统级竞争资源。 + +**参数**: + +1. 指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr。 +2. 作用域scope。 + +**输出**: + +- 0:设置成功。 +- EINVAL:scope的值无效,或者attr指向没有初始化的线程对象。 +- ENOTSUP:试图将属性设置为不支持的值。 + +#### pthread_attr_getstack + +pthread_attr_getstack() 可用来获取线程属性对象的栈信息。 + +**参数**: + +- 指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr。 +- 线程的栈地址指针stackAddr。 +- 线程的栈大小指针stackSize。 + +**输出**: + +- 0:获取成功。 +- EINVAL:指针未初始化。 + +#### pthread_attr_setstack + +pthread_attr_setstack() 可用来设置线程属性对象的栈地址和栈大小。 + +**参数**: + +- 指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr。 +- 线程的栈地址stackAddr。 +- 线程的栈大小stackSize。 + +**输出**: + +- 0:获取成功。 +- EINVAL:指针未初始化或值无效。 + +#### pthread_attr_getguardsize + +暂不支持。 + +#### pthread_attr_setguardsize + +暂不支持。 + +#### pthread_atfork + +暂不支持。 + +#### pthread_create + +pthread_create()函数创建一个新线程,其属性由 attr 指定。如果 attr 为 NULL,则使用默认属性。创建成功后,pthread_create()应将创建的线程的ID存储在参数 thread 的位置。 + +**参数**: + +1. 指向线程[标识符](https://baike.baidu.com/item/标识符?fromModule=lemma_inlink)的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)thread。 +2. 指向一个线程属性结构的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)attr。 +3. 线程处理函数的起始地址 start_routine。 +4. 运行函数的参数 arg。 + +**输出**: + +- 0:创建成功。 +- EINVAL:attr指定的属性无效。 +- EAGAIN:系统缺少创建新线程所需的资源,或者将超过系统对线程总数施加的限制。 +- EPERM:调用者没有权限。 + +#### pthread_cancel + +取消线程的执行。pthread_cancel()函数应请求取消线程。目标线程的可取消状态和类型决定取消何时生效。当取消被操作时,应调用线程的取消处理程序。 + +**参数**:线程的ID thread。 + +**输出**: + +- 0:取消成功。 +- ESRCH:找不到与给定线程ID相对应的线程。 + +#### pthread_testcancel + +设置可取消状态。pthread_testcancel()函数应在调用线程中创建一个取消点。如果禁用了可取消性,pthread_testcancel()函数将无效。 + +**参数**:无 + +**输出**:无 + +#### pthread_setcancelstate + +pthread_setcancelstate() 将调用线程的可取消性状态设置为 state 中给出的值。线程以前的可取消性状态返回到oldstate所指向的缓冲区中。state状态的合法值为PTHREAD_CANCEL_E无BLE和PTHREAD_CANCEL_DISABLE。 + +**参数**: + +- 线程的可取消性状态 state。 +- 之前的可取消状态 oldstate。 + +**输出**: + +- 0:设置成功。 +- EINVAL:指定的状态不是 PTHREAD_CANCEL_E无BLE 或 PTHREAD_CANCEL_DISABLE。 + +#### pthread_setcanceltype + +pthread_setcanceltype()函数应原子地将调用线程的可取消类型设置为指定的类型,并在oldtype引用的位置返回上一个可取消类型。类型的合法值为PTHREAD_CANCEL_DEFERRED和PTHREAD_CANCEL_ASYNCHRONOUS。 + +**输入**: + +- 线程的可取消类型type。 +- 之前的可取消类型oldtype。 + +**输出**: + +- 0:设置成功。 +- EINVAL:指定的类型不是PTHREAD_CANCEL_DEFERRED或PTHREAD_CANCEL_ASYNCHRONOUS。 + +#### pthread_exit + +线程的终止可以是调用 pthread_exit 或者该线程的例程结束。由此可看出,一个线程可以隐式退出,也可以显式调用 pthread_exit 函数来退出。pthread_exit 函数唯一的参数 value_ptr 是函数的返回代码,只要 pthread_join 中的第二个参数 value_ptr 不是NULL,这个值将被传递给 value_ptr。 + +**参数**:线程退出状态value_ptr,通常传NULL。 + +**输出**:无 + +#### pthread_cleanup_push + +pthread_cleanup_push() 函数应将指定的取消处理程序推送到调用线程的取消堆栈上。pthread_cleanup_push必须和pthread_cleanup_pop同时使用。当push后,在线程退出前使用pop,便会调用清理函数。 + +**参数**: + +1. 取消处理程序入口地址 routine。 +2. 传递给处理函数的参数 arg。 + +**输出**:无 + +#### pthread_cleanup_pop + +pthread_cleanup_pop()应删除调用线程取消处理程序,并可选择调用它(如果execute非零)。 + +**参数**:执行参数execute。 + +**输出**:无 + +#### pthread_setschedprio + +pthread_setschedprio()函数应将线程 ID 指定的调度优先级设置为 prio 给出的值。如果 pthread_setschedprio()函数失败,则目标线程的调度优先级不应更改。 + +**参数**: + +1. 线程ID:thread。 +2. 优先级:prio。 + +**输出**: + +- 0,设置成功。 +- EINVAL:prio对指定线程的调度策略无效。 +- ENOTSUP:试图将优先级设置为不支持的值。 +- EPERM:调用者没有设置指定线程的调度策略的权限。 +- EPERM:不允许将优先级修改为指定的值。 +- ESRCH:thread指定的线程不存在。 + +#### pthread_self + +pthread_self()函数应返回调用线程的线程ID。 + +**参数**:无 + +**输出**:返回调用线程的线程ID。 + +#### pthread_equal + +此函数应比较线程ID t1和t2。 + +**参数**: + +1. 线程ID t1。 +2. 线程ID t2。 + +**输出**: + +- 如果t1和t2相等,pthread_equal()函数应返回非零值。 +- 如果t1和t2不相等,应返回零。 +- 如果t1或t2不是有效的线程ID,则行为未定义。 + +#### sched_yield + +sched_yield()函数应强制正在运行的线程放弃处理器,并触发线程调度。 + +**参数**:无 + +**输出**:输出0时,成功完成;否则应返回值-1。 + +#### sched_get_priority_max + +sched_get_priority_max()和 sched_get_priority_min()函数应分别返回指定调度策略的优先级最大值或最小值。 + +**参数**:调度策略policy。 + +**输出**: + +返回值: + +- -1:失败。 +- 返回优先级最大值。 + +errno: + +- EINVAL:调度策略非法。 + +#### sched_get_priority_min + +返回指定调度策略的优先级最小值 + +**参数**:调度策略policy。 + +**输出**: + +返回值: + +- -1:失败。 +- 返回优先级最小值。 + +errno: + +- EINVAL:调度策略非法。 + +#### pthread_join + +pthread_join() 函数,以阻塞的方式等待 thread 指定的线程结束。当函数返回时,被等待线程的资源被收回。如果线程已经结束,那么该函数会立即返回。并且 thread 指定的线程必须是 joi无ble 的。当 pthread_join()成功返回时,目标线程已终止。对指定同一目标线程的pthread_join()的多个同时调用的结果未定义。如果调用pthread_join()的线程被取消,则目标线程不应被分离 + +**参数**: + +1. 线程ID:thread。 +2. 退出线程:返回值value_ptr。 + +**输出**: + +- 0:成功完成。 +- ESRCH:找不到与给定ID相对应的线程。 +- EDEADLK:检测到死锁或thread的值指定调用线程。 +- EINVAL:thread指定的线程不是joinable的。 + +#### pthread_detach + +实现线程分离,即主线程与子线程分离,子线程结束后,资源自动回收。 + +**参数**:线程ID:thread。 + +**输出**: + +- 0:成功完成。 +- EINVAL:thread是分离线程。 +- ESRCH:给定线程ID指定的线程不存在。 + +#### pthread_key_create + +分配用于标识线程特定数据的键。pthread_key_create 第一个参数为指向一个键值的[指针](https://baike.baidu.com/item/指针/2878304?fromModule=lemma_inlink),第二个参数指明了一个 destructor 函数,如果这个参数不为空,那么当每个线程结束时,系统将调用这个函数来释放绑定在这个键上的内存块。 + +**参数**: + +1. 键值的[指针](https://baike.baidu.com/item/指针/2878304?fromModule=lemma_inlink)key。 +2. destructor 函数入口 destructor。 + +**输出**: + +- 0:创建成功。 +- EAGAIN:系统缺乏创建另一个特定于线程的数据密钥所需的资源,或者已超过系统对每个进程的密钥总数施加的限制。 +- ENOMEM:内存不足,无法创建密钥。 + +#### pthread_setspecific + +pthread_setspecific() 函数应将线程特定的 value 与通过先前调用 pthread_key_create()获得的 key 关联起来。不同的线程可能会将不同的值绑定到相同的键上。这些值通常是指向已保留供调用线程使用的动态分配内存块的指针。 + +**参数**: + +1. 键值key。 +2. 指针value + +**输出**: + +- 0:设置成功。 +- ENOMEM:内存不足,无法将非NULL值与键关联。 +- EINVAL:key的值不合法。 + +#### pthread_getspecific + +将与key关联的数据读出来,返回数据类型为 void *,可以指向任何类型的数据。需要注意的是,在使用此返回的指针时,需满足是 void 类型,虽指向关联的数据地址处,但并不知道指向的数据类型,所以在具体使用时,要对其进行强制类型转换。 + +**参数**:键值key。 + +**输出**: + +- 返回与给定 key 关联的线程特定数据值。 +- NULL:没有线程特定的数据值与键关联。 + +#### pthread_key_delete + +销毁线程特定数据键。 + +**参数**:需要删除的键key。 + +**输出**: + +- 0:删除成功。 +- EINVAL:key值无效。 + +#### pthread_getcpuclockid + +暂不支持。 + +#### pthread_getschedparam + +获取线程调度策略和优先级属性。 + +**参数**: + +1. 线程对象指针thread。 +2. 调度策略指针policy。 +3. 调度属性对象指针param。 + +**输出**: + +- 0:删除成功。 +- EINVAL:指针未初始化。 + +#### pthread_setschedparam + +设置线程调度策略和优先级属性。调度策略仅支持SCHED_FIFO。 + +**参数**: + +1. 线程对象指针thread。 +2. 调度策略指针policy。 +3. 调度属性对象指针param。 + +**输出**: + +- 0:删除成功。 +- EINVAL:指针未初始化。 +- ENOTSUP:设置不支持的值。 + +#### pthread_kill + +暂不支持。 + +#### pthread_once + +pthread_once() 函数使用指定once_contol变量会保证init_routine函数只执行一次。当前init_routine函数不支持被取消。 + +**参数**: + +1. 控制变量control。 +2. 执行函数init_routine。 + +**输出**: + +- 0:删除成功。 +- EINVAL:指针未初始化。 + +#### pthread_sigmask + +暂不支持。 + +#### pthread_spin_init + +暂不支持。 + +#### pthread_spin_destory + +暂不支持。 + +#### pthread_spin_lock + +暂不支持。 + +#### pthread_spin_trylock + +暂不支持。 + +#### pthread_spin_unlock + +暂不支持。 + +### 信号量管理 + +#### sem_init + +sem_init()函数应初始化 sem 引用的匿名信号量。初始化信号量的值应为 value。在成功调用 sem_init()后,信号量可用于后续调用 sem_wait()、sem_timedwait()、sem_trywait()、sem_post()和sem_destroy()。此信号量应保持可用,直到信号量被销毁。 + +**参数**: + +1. 指向信号量指针sem。 +2. 指明信号量的类型pshared。 +3. 信号量值的大小value。 + +**输出**: + +- 0:初始化成功。 +- EINVAL:值参数超过{SEM_VALUE_MAX}。 +- ENOSPC:初始化信号量所需的资源已耗尽,或已达到信号量的限制。 +- EPERM:缺乏初始化信号量的权限。 + +#### sem_destroy + +sem_destroy()函数销毁 sem 指示的匿名信号量。只有使用 sem_init()创建的信号量才能使用 sem_destroy()销毁;使用命名信号量调用 sem_destroy()的效果未定义。在 sem 被另一个对 sem_init()的调用重新初始化之前,后续使用信号量 sem 的效果是未定义的。 + +**参数**:指向信号量指针sem。 + +**输出**: + +- 0:销毁成功。 +- EINVAL:sem不是有效的信号量。 +- EBUSY:信号量上当前有线程被阻止。 + +#### sem_open + +创建并初始化有名信号量。此信号量可用于后续对 sem_wait()、sem_timedwait()、sem_trywait()、sem_post()和sem_close() 的调用。 + +**参数**: + +1. 信号量名无me指针。 + +2. oflag参数控制信号量是创建还是仅通过调用sem_open()访问。以下标志位可以在oflag中设置: + + - O_CREAT:如果信号量不存在,则此标志用于创建信号量。 + + - O_EXCL:如果设置了O_EXCL和O_CREAT,且信号量名称存在,sem_open()将失败。如果设置了O_EXCL而未设置O_CREAT,则效果未定义。 + +3. 如果在oflag参数中指定了O_CREAT和O_EXCL以外的标志,则效果未指定。 + +**输出**: + +- 创建并初始化成功,返回信号量地址。 +- EACCES:创建命名信号量的权限被拒绝。 +- EEXIST:已设置O_CREAT和O_EXCL,且命名信号量已存在。 +- EINTR:sem_open()操作被信号中断。 +- EINVAL:给定名称不支持sem_open(),或在oflag中指定了O_CREAT,并且值大于最大值。 +- EMFILE:当前使用的信号量描述符或文件描述符太多。 +- ENAMETOOLONG:name参数的长度超过{PATH_MAX},或者路径名组件的长度超过{NAME_MAX}。 +- ENFILE:系统中当前打开的信号量太多。 +- ENOENT:未设置O_CREAT且命名信号量不存在。 +- ENOSPC:没有足够的空间来创建新的命名信号量。 + +#### sem_close + +关闭一个命名信号量。未命名的信号量(由sem_init() 创建的信号量)调用 sem_close() 的效果未定义。sem_close() 函数应解除系统分配给此信号量的任何系统资源。此过程后续使用sem指示的信号量的影响未定义。 + +**参数**:信号量指针sem。 + +**输出**: + +- 0: 销毁成功。 +- EINVAL:sem参数不是有效的信号量描述符。 + +#### sem_wait + +sem_wait()函数通过对 sem 引用的信号量执行信号量锁定操作来锁定该信号量。如果信号量值当前为零,则调用线程在锁定信号量或调用被信号中断之前,不会从对 sem_wait()的调用返回。 + +**参数**:信号量指针sem。 + +**输出**: + +- 0:操作成功。 +- EAGAIN:信号量已被锁定,无法立即被 sem_trywait()操作。 +- EDEADLK:检测到死锁条件。 +- EINTR:信号中断了此功能。 +- EINVAL:sem参数未引用有效的信号量。 + +#### sem_trywait + +只有当信号量当前未锁定时,即信号量值当前为正值,sem_trywait()函数才应锁定 sem 引用的信号量。否则它不应锁定信号量。 + +**参数**:信号量指针sem。 + +**输出**: + +- 0:操作成功。 +- EAGAIN:信号量已被锁定,无法立即被sem_trywait()操作。 +- EDEADLK:检测到死锁条件。 +- EINTR:信号中断了此功能。 +- EINVAL:sem参数未引用有效的信号量。 + +#### sem_timedwait + +sem_timedwait()函数应锁定 sem 引用的信号量,就像 sem_wait()函数一样。如果在不等待另一个线程执行sem_post()解锁信号量的情况下无法锁定信号量,则在指定的超时到期时,此等待将终止。 + +**参数**: + +1. 信号量指针sem。 +2. 阻塞时间指针abs_timeout。 + +**输出**: + +- 0:操作成功。 +- EINVAL:线程可能会阻塞,abs_timeout 指定的纳秒值小于0或大于等于1000 million。 +- ETIMEDOUT:在指定的超时到期之前,无法锁定信号量。 +- EDEADLK:检测到死锁条件。 +- EINTR:信号中断了此功能。 +- EINVAL:sem参数未引用有效的信号量。 + +#### sem_post + +sem_post()函数应通过对 sem 引用的信号量执行信号量解锁操作,当有线程阻塞在这个信号量上时,调用这个函数会使其中一个线程不在阻塞,选择机制是有线程的调度策略决定的。 + +**参数**:信号量指针sem。 + +**输出**: + +- 0:操作成功。 +- EINVAL:sem参数未引用有效的信号量。 + +#### sem_getvalue + +sem_getvalue()函数获取 sem 引用的信号量的值,而不影响信号量的状态。获取的 sval 值表示在调用期间某个未指定时间发生的实际信号量值。 + +**参数**: + +1. 信号量指针sem。 +2. 信号量计数值指针sval。 + +**输出**: + +- 0:操作成功。 +- EINVAL:sem参数未引用有效的信号量。 + +#### sem_unlink + +sem_unlink() 函数将删除由字符串名称命名的信号量。如果信号量当前被其他进程引用,那么sem_unlink() 将不会影响信号量的状态。如果在调用sem_unlink() 时一个或多个进程打开了信号量,则信号量的销毁将被推迟,直到信号量的所有引用都被销毁了。 + +**参数**:信号量名称name。 + +**输出**: + +- 0:操作成功。 +- -1:name参数未引用有效的信号量。 + +### 互斥量管理 + +#### pthread_mutexattr_init + +pthread_mutexattr_init()函数初始化互斥锁。如果调用 pthread_mutexattr_init()指定已初始化的attr属性对象行为未定义。 + +**参数**:互斥锁属性对象指针attr。 + +**输出**: + +- 0:操作成功。 +- ENOMEM:内存不足,无法初始化互斥属性对象。 + +#### pthread_mutexattr_destroy + + 注销一个互斥锁。销毁一个互斥锁即意味着释放它所占用的资源,且要求锁当前处于开放状态。 + +**参数**:互斥锁属性对象指针attr。 + +**输出**: + +- 0:操作成功。 +- EINVAL:attr指定的值无效。 + +#### pthread_mutexattr_settype + +pthread_mutexattr_settype()函数设置互斥 type 属性。默认值为 PTHREAD_MUTEX_DEFAULT。有效的互斥类型包括: + +PTHREAD_MUTEX_NORMAL:此类型的互斥锁不会检测死锁。 + +- 如果线程在不解除互斥锁的情况下尝试重新锁定该互斥锁,则会产生死锁。 +- 如果尝试解除由其他线程锁定的互斥锁,会产生不确定的行为。 +- 如果尝试解除锁定的互斥锁未锁定,则会产生不确定的行为。 + +PTHREAD_MUTEX_ERRORCHECK:此类型的互斥锁可提供错误检查。 + +- 如果线程在不解除锁定互斥锁的情况下尝试重新锁定该互斥锁,则会返回错误。 +- 如果线程尝试解除锁定的互斥锁已经由其他线程锁定,则会返回错误。 +- 如果线程尝试解除锁定的互斥锁未锁定,则会返回错误。 + +PTHREAD_MUTEX_RECURSIVE: + +- 如果线程在不解除锁定互斥锁的情况下尝试重新锁定该互斥锁,则可成功锁定该互斥锁。 与 PTHREAD_MUTEX_NORMAL 类型的互斥锁不同,对此类型互斥锁进行重新锁定时不会产生死锁情况。多次锁定互斥锁需要进行相同次数的解除锁定才可以释放该锁,然后其他线程才能获取该互斥锁。 +- 如果线程尝试解除锁定的互斥锁已经由其他线程锁定,则会返回错误。 +- 如果线程尝试解除锁定的互斥锁未锁定,则会返回错误。 + +PTHREAD_MUTEX_DEFAULT: + +- 如果尝试以[递归](https://baike.baidu.com/item/递归?fromModule=lemma_inlink)方式锁定此类型的互斥锁,则会产生不确定的行为。 +- 对于不是由调用线程锁定的此类型互斥锁,如果尝试对它解除锁定,则会产生不确定的行为。 +- 对于尚未锁定的此类型互斥锁,如果尝试对它解除锁定,也会产生不确定的行为。 + +**参数**: + +1. 互斥锁属性对象指针attr。 +2. 互斥锁类型type。 + +**输出**: + +- 0:操作成功。 +- EINVAL:attr指定的值无效,或type无效。 + +#### pthread_mutexattr_gettype + +pthread_mutexattr_gettype() 可用来获取由 pthread_mutexattr_settype() 设置的互斥锁的 type 属性。 + +**参数**: + +1. 互斥锁属性对象指针attr。 +2. 互斥锁类型指针type。 + +**输出**: + +- 0:操作成功。 +- EINVAL:attr指定的值无效。 + +#### pthread_mutexattr_setprotocol + +pthread_mutexattr_setprotocol() 可用来设置互斥锁属性对象的协议属性。定义的 protocol 可以为以下值之一: + +- PTHREAD_PRIO_NONE +- PTHREAD_PRIO_INHERIT +- PTHREAD_PRIO_PROTECT(当前版本暂不支持) + +**参数**: + +1. 互斥锁属性对象指针 attr。 +2. 互斥锁属性对象的协议 protocol。 + +**输出**: + +- 0:操作成功。 +- ENOTSUP:协议指定的值不支持。 +- EINVAL:attr指定的值无效。 +- EPERM:调用者没有权限。 + +#### pthread_mutexattr_getprotocol + +pthread_mutexattr_getprotocol() 获取互斥锁属性对象的协议属性。 + +**参数**: + +1. 互斥锁属性对象指针attr。 +2. 互斥锁属性对象的协议指针protocol。 + +**输出**: + +- 0:操作成功。 +- EINVAL:attr指定的值无效。 +- EPERM:调用者没有权限。 + +#### pthread_mutexattr_getprioceiling + +暂不支持。 + +#### pthread_mutexattr_setprioceiling + +暂不支持。 + +#### pthread_mutexattr_getpshared + +获取互斥锁属性对象的共享属性。当前支持PTHREAD_PROCESS_PRIVATE,互斥锁为进程内私有。 + +**参数**: + +1. 互斥锁属性对象指针attr。 +2. 共享属性指针pshared。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 + +#### pthread_mutexattr_setpshared + +暂不支持。 + +#### pthread_mutexattr_getrobust + +获取互斥锁属性对象的健壮属性。当前支持PTHREAD_MUTEX_STALLED,如果互斥锁的所有者在持有互斥锁时终止,则不会执行特殊操作。 + +**参数**: + +1. 互斥锁属性对象指针attr。 +2. 健壮属性指针robust。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 + +#### pthread_mutexattr_setrobust + +设置互斥锁属性对象的健壮属性。当前支持PTHREAD_MUTEX_STALLED。 + +**参数**: + +1. 互斥锁属性对象指针attr。 +2. 健壮属性robust。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 +- ENOTSUP:设置不支持的值。 + +#### pthread_mutex_init + +pthread_mutex_init()函数初始化互斥锁,属性由 attr 指定。如果 attr 为NULL,则使用默认互斥属性。 + +**参数**: + +1. 互斥锁指针mutex。 +2. 互斥锁属性对象指针attr。 + +**输出**: + +- 0:操作成功。 +- EAGAIN:缺少初始化互斥锁所需的资源(内存除外)。 +- ENOMEM:内存不足,无法初始化互斥体。 +- EPERM:没有执行操作的权限。 +- EBUSY:互斥锁已经初始化但尚未销毁。 +- EINVAL:attr指定的值无效。 + +#### pthread_mutex_destroy + +pthread_mutex_destroy() 用于注销一个互斥锁。销毁一个互斥锁即意味着释放它所占用的资源,且要求锁当前处于开放状态。 + +**参数**:互斥锁指针mutex。 + +**输出**: + +- 0:操作成功。 +- EBUSY:锁当前未处于开放状态。 +- EINVAL:mutex指定的值无效。 + +#### pthread_mutex_lock + +当pthread_mutex_lock() 返回时,该[互斥锁](https://baike.baidu.com/item/互斥锁/841823?fromModule=lemma_inlink)已被锁定。[线程](https://baike.baidu.com/item/线程/103101?fromModule=lemma_inlink)调用该函数让互斥锁上锁,如果该互斥锁已被另一个线程锁定和拥有,则调用该线程将阻塞,直到该互斥锁变为可用为止。 + +**参数**:互斥锁指针mutex。 + +**输出**: + +- 0:操作成功。 +- EINVAL:mutex指定的值未初始化。 +- EAGAIN:无法获取互斥锁。 +- EDEADLK:当前线程已经拥有互斥锁。 + +#### pthread_mutex_trylock + +pthread_mutex_trylock() 语义与 pthread_mutex_lock() 类似,不同点在于锁已经被占据时返回 EBUSY, 而非挂起等待。 + +**参数**:互斥锁指针mutex。 + +**输出**: + +- 0,操作成功。 +- EBUSY:mutex指定的锁已经被占据。 +- EINVAL:mutex指定的值未初始化。 +- EAGAIN:无法获取互斥锁。 +- EDEADLK:当前线程已经拥有互斥锁。 + +#### pthread_mutex_timedlock + +pthread_mutex_timedlock() 语义与pthread_mutex_lock() 类似,不同点在于锁已经被占据时增加一个超时时间,等待超时返回错误码。 + +**参数**: + +1. 互斥锁指针mutex。 +2. 超时时间指针abs_timeout。 + +**输出**: + +- 0:操作成功。 +- EINVAL:mutex指定的值未初始化,abs_timeout指定的纳秒值小于0或大于等于1000 million。 +- ETIMEDOUT:等待超时。 +- EAGAIN:无法获取互斥锁。 +- EDEADLK:当前线程已经拥有互斥锁。 + +#### pthread_mutex_unlock + +释放互斥锁。 + +**参数**:互斥锁指针mutex。 + +**输出**: + +- 0:操作成功。 +- EINVAL:mutex指定的值未初始化。 +- EPERM:当前线程不拥有互斥锁。 + +#### pthread_mutex_consistent + +暂不支持。 + +#### pthread_mutex_getprioceiling + +暂不支持。 + +#### pthread_mutex_setprioceiling + +暂不支持。 + +### 读写锁编程 + +#### pthread_rwlock_init + +pthread_rwlock_init()初始化读写锁。如果 attr 为 NULL,则使用默认的读写锁属性。一旦初始化,锁可以使用任何次数,而无需重新初始化。调用 pthread_rwlock_init()指定已初始化的读写锁行为未定义。如果在没有初始化的情况下使用读写锁,则结果是未定义的。 + +**参数**: + +1. 读写锁指针rwlock。 +2. 读写锁属性指针attr。 + +**输出**: + +- 0:操作成功。 +- EAGAIN:系统缺少初始化读写锁所需的资源(内存除外)。 +- ENOMEM:内存不足,无法初始化读写锁。 +- EPERM:没有执行操作的权限。 +- EBUSY:rwlock是以已初始化但尚未销毁的读写锁。 +- EINVAL:attr指定的值无效。 + +#### pthread_rwlock_destroy + +pthread_rwlock_destroy()函数应销毁 rwlock 引用的读写锁,并释放锁使用的资源。在再次调用pthread_rwlock_init()重新初始化锁之前,后续使用锁的行为未定义。如果在任何线程持有 rwlock 时调用pthread_rwlock_destroy()行为未定义。尝试销毁未初始化的读写锁行为未定义。 + +**参数**:读写锁指针rwlock。 + +**输出**: + +- 0:操作成功。 +- EBUSY: rwlock引用的对象被锁定时销毁该对象。 +- EINVAL:attr指定的值无效。 + +#### pthread_rwlock_rdlock + +pthread_rwlock_rdlock()函数应将读锁应用于rwlock引用的读写锁。 + +**参数**:读写锁指针rwlock。 + +**输出**: + +- 0:操作成功。 +- EINVAL:rwlock是未初始化的读写锁。 +- EAGAIN:无法获取读锁,因为已超过rwlock的最大读锁数。 +- EDEADLK:检测到死锁条件或当前线程已拥有写锁。 + +#### pthread_rwlock_tryrdlock + +pthread_rwlock_tryrdlock()函数语义与pthread_rwlock_rdlock()类似。在任何情况下,pthread_rwlock_tryrdlock()函数都不会阻塞;它会一直获取锁,或者失败并立即返回。 + +**参数**:读写锁指针rwlock。 + +**输出**: + +- 0:操作成功。 +- EINVAL:rwlock是未初始化的读写锁。 +- EAGAIN:无法获取读锁,因为已超过rwlock的最大读锁数。 +- EBUSY:无法获取读写锁以进行读取,因为写入程序持有该锁。 + +#### pthread_rwlock_timedrdlock + +pthread_rwlock_timedrdlock()语义与pthread_rwlock_rdlock()类似,不同的是在锁已经被占据时增加一个超时时间,等待超时返回错误码。 + +**参数**: + +1. 读写锁指针rwlock。 +2. 超时时间指针abs_timeout。 + +**输出**: + +- 0:操作成功。 +- ETIMEDOUT:在指定的超时到期之前,无法获取锁。 +- EAGAIN:无法获取读锁,超过锁的最大读锁数量。 +- EDEADLK:检测到死锁条件或调用线程已在rwlock上持有写锁。 +- EINVAL:rwlock指定的锁未初始化,或者abs_timeout纳秒值小于0或大于等于1000 million。 + +#### pthread_rwlock_wrlock + +pthread_rwlock_wrlock()函数将写锁应用于 rwlock 引用的读写锁。如果没有其他线程持有读写锁 rwlock,调用线程将获得写锁。否则,线程应阻塞,直到它能够获得锁。如果调用线程在调用时持有读写锁(无论是读锁还是写锁),则调用线程可能会死锁。 + +**参数**:读写锁指针rwlock。 + +**输出**: + +- 0:操作成功。 +- EINVAL:rwlock指定的值未初始化。 +- EDEADLK:检测到死锁情况,或者当前线程已经拥有用于写入或读取的读写锁。 + +#### pthread_rwlock_trywrlock + +pthread_rwlock_trywrlock()函数类似 pthread_rwlock_wrlock(),但如果任何线程当前持有rwlock(用于读取或写入,该函数将失败)。 + +**参数**:读写锁指针rwlock。 + +**输出**: + +- 0:操作成功。 +- EBUSY:无法获取读写锁以进行写入,因为它已被锁定以进行读取或写入。 +- EINVAL:rwlock指定的值未初始化。 + +#### pthread_rwlock_timedwrlock + +pthread_rwlock_timedwrlock()语义与pthread_rwlock_wrlock()类似,不同的是在锁已经被占据时增加一个超时时间,等待超时返回错误码。 + +**参数**: + +1. 读写锁指针rwlock。 +2. 超时时间指针abs_timeout。 + +**输出**: + +- 0:操作成功。 +- ETIMEDOUT:在指定的超时到期之前,无法获取锁。 +- EAGAIN:无法获取读锁,超过锁的最大读锁数量。 +- EDEADLK:检测到死锁条件或调用线程已在rwlock上持有写锁。 +- EINVAL;rwlock指定的锁未初始化,或者abs_timeout纳秒值小于0或大于等于1000 million。 + +#### pthread_rwlock_unlock + +pthread_rwlock_unlock()函数释放rwlock引用的读写锁上持有的锁。如果读写锁rwlock未被调用线程持有,则结果未定义。 + +**参数**:读写锁指针rwlock。 + +**输出**: + +- 0:操作成功。 +- EINVAL:rwlock指定的锁未初始化。 +- EPERM:当前线程不持有读写锁。 + +#### pthread_rwlockattr_init + +暂不支持 + +#### pthread_rwlockattr_destroy + +暂不支持 + +#### pthread_rwlockattr_getpshared + +pthread_rwlockattr_getpshared() 函数从attr引用的读写锁属性对象中获取进程共享属性的值。 + +**参数**: + +1. 读写锁属性指针attr。 +2. 共享属性指针pshared。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 + +### pthread_rwlockattr_setpshared + +设置读写锁属性对象中进程共享属性的值。当前支持PTHREAD_PROCESS_PRIVATE,读写锁为进程私有。 + +**参数**: + +1. 读写锁属性指针attr。 +2. 共享属性指针pshared。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 +- ENOTSUP:设置不支持的值。 + +### 线程屏障管理 + +#### pthread_barrier_destroy + +销毁线程屏障变量,并释放该屏障使用的任何资源。 + +**参数**:屏障变量指针b。 + +**输出**: + +- 0:操作成功。 +- EBUSY:另一个线程在使用该变量。 + +#### pthread_barrier_init + +分配线程屏障变量所需的资源,并使用attr的属性初始化屏障。如果attr为NULL,则使用默认的屏障属性。 + +**参数**: + +1. 屏障变量指针b。 +2. 屏障属性指针attr。 +3. 等待线程个数count。 + +**输出**: + +- 0:操作成功。 +- EINVAL:count为0。 +- ENOTSUP:attr指定的屏障属性不支持。 +- EAGAIN:系统缺乏初始化一个屏障所需的资源。 + +#### pthread_barrier_wait + +pthread_barrier_wait() 阻塞调用线程,直到等待的线程达到了预定的数量。 + +**参数**:屏障变量指针b。 + +**输出**: + +- 0:操作成功。 +- -1:第一个线程成功返回。 + +#### pthread_barrierattr_getpshared + +获取屏障属性的共享属性值。 + +**参数**: + +1. 屏障属性指针a。 +2. 共享属性值指针pshared。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 + +#### pthread_barrierattr_setpshared + +设置屏障属性的共享属性值。支持PTHREAD_PROCESS_PRIVATE,该屏障为进程私有的,不允许不同进程的线程访问该屏障。 + +**参数**: + +1. 屏障属性指针a。 +2. 共享属性值pshared。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 +- ENOTSUP:试图将属性设置为不支持的值。 + +### 条件变量管理 + +#### pthread_cond_init + +使用attr引用的属性初始化cond引用的条件变量。如果attr为NULL,则使用默认条件变量属性。 + +**参数** + +1. 条件变量指针cond。 +2. 条件变量属性指针attr。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 +- EAGAIN:系统缺乏初始化一个条件变量所需的资源。 + +#### pthread_cond_destroy + +销毁指定条件变量,使得该条件变量未初始化,可以使用pthread_cond_init() 重新初始化。 + +**参数**:条件变量指针cond。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 +- EBUSY:另一个线程在使用该变量。 + +#### pthread_cond_broadcast + +pthread_cond_broadcast()函数取消阻塞指定条件变量cond上当前阻塞的所有线程。 + +**参数**:条件变量指针cond。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 + +#### pthread_cond_signal + +pthread_cond_signal() 函数取消阻塞在指定的条件变量cond上阻塞的线程中的至少一个(如果有任何线程在cond上被阻塞)。 + +**参数**:条件变量指针cond。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 + +#### pthread_cond_timedwait + +pthread_cond_timedwait() 函数阻塞当前线程等待cond指定的条件变量,并释放互斥体指定的互斥体。只有在另一个线程使用相同的条件变量调用pthread_cond_signal() 或pthread_cond_broadcast() 后,或者如果系统时间达到指定的时间,并且当前线程重新获得互斥锁时,等待线程才会解锁。 + +**参数**: + +1. 条件变量指针cond。 +2. 互斥锁指针m。 +3. 超时时间指针ts。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 +- ETIMEDOUT:阻塞超时 + +#### pthread_cond_wait + +pthread_cond_wait() 函数与pthread_cond_timedwait() 类似,阻塞当前线程等待cond指定的条件变量,并释放互斥体指定的互斥体。只有在另一个线程使用相同的条件变量调用pthread_cond_signal() 或pthread_cond_broadcast() 后,并且当前线程重新获得互斥锁时,等待线程才会解锁。 + +**参数**: + +1. 条件变量指针cond。 +2. 互斥锁指针m。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 + +#### pthread_condattr_init + +使用属性的默认值初始化条件变量属性对象attr。 + +**参数**: 条件变量属性对象指针attr。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 + +#### pthread_condattr_destroy + +pthread_condattr_destroy)函数销毁条件变量属性对象,使对象变得未初始化,可以使用pthread_condattr_init() 重新初始化。 + +**参数**:条件变量属性对象指针attr。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 + +#### pthread_condattr_getclock + +从attr引用的属性对象中获取时钟属性的值。 + +**参数**: + +1. 条件变量属性对象指针attr。 +2. 时钟属性指针clk。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 + +#### pthread_condattr_setclock + +设置attr引用的属性对象中时钟属性的值。当前支持CLOCK_REALTIME,采用系统时间。 + +**参数**: + +1. 条件变量属性对象指针attr。 +2. 时钟属性clock。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 +- ENOTSUP:设置不支持的值。 + +#### pthread_condattr_getpshared + +从attr引用的属性对象中获取共享属性的值。 + +**参数**: + +1. 条件变量属性对象指针attr。 +2. 共享属性指针pshared。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 + +#### pthread_condattr_setpshared + +设置attr引用的属性对象中共享属性属性的值。当前支持PTHREAD_PROCESS_PRIVATE,该条件变量为进程私有的,不允许不同进程的线程访问。 + +**参数**: + +1. 条件变量属性对象指针attr。 +2. 共享属性pshared。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 +- ENOTSUP:设置不支持的值。 + +### 时钟管理 + +#### asctime + +asctime() 函数将timeptr指向的tm结构体对象转换为的字符串。 + +**参数**: tm结构体指针timeptr。 + +**输出**: + +- 成功则返回字符串指针。 +- 失败返回NULL。 + +#### asctime_r + +与asctime() 函数类似,将timeptr指向的tm结构体对象转换为的字符串。不同的是该字符串放置在用户提供的缓冲区buf(至少包含26字节)中,然后返回buf。 + +**参数**: + +1. tm结构体指针timeptr。 +2. 字符串缓冲区buf。 + +**输出**: + +- 成功则返回字符串指针。 +- 失败返回NULL。 + +#### clock + +返回该进程使用等处理器时间的最佳近似值。 + +**参数**:无 + +**输出**: + +- 成功则返回时间。 +- -1:失败。 + +#### clock_gettime + +clock_gettime()函数应返回指定时钟的当前值tp。 + +**参数**: + +1. 时钟类型clock_id。 +2. timespec结构体指针tp。 + +**输出**: + +返回值: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EINVAL:clock_id不合法。 +- ENOTSUP:clock_id不支持。 + +#### clock_settime + +clock_settime()函数应将指定的clock_id设置为tp指定的值。 + +**参数**: + +1. 时钟类型clock_id。 +2. timespec结构体指针tp。 + +**输出**: + +返回值: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EINVAL:clock_id不合法,或tp参数指定的纳秒值小于0或大于等于1000 million。 +- ENOTSUP:clock_id不支持。 + +#### clock_getres + +clock_getres()返回时钟的分辨率。如果参数res不为NULL,则指定时钟的分辨率应存储在res指向的位置。如果res为NULL,则不返回时钟分辨率。如果clock_settime()的时间参数不是res的倍数,则该值将被截断为res的倍数。 + +**参数**: + +1. 时钟类型clock_id。 +2. timespec结构体指针res。 + +**输出**: + +返回值: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EINVAL:clock_id不合法。 +- ENOTSUP:clock_id不支持。 + +#### clock_getcpuclockid + +clock_getcpuclockid函数获取CPU时间时钟的ID,当前进程只有一个,因此无论传入的pid是什么,都返回CLOCK_PROCESS_CPUTIME_ID。 + +**参数**: + +1. 进程ID:pid。 +2. 时钟指针:clk。 + +**输出**: + +- 0:操作成功。 + +#### clock_nanosleep + +与nanosleep类似,clock_nanosleep() 允许调用线程在以纳秒精度指定的时间间隔内休眠,并可以将睡眠间隔指定为绝对值或相对值。当前支持CLOCK_REALTIME。 + +**参数**: + +1. 时钟ID:clk。 +2. 是否为绝对值:flag。 +3. 指定的时间间隔值eq。 +4. 剩余时间值:rem。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 +- EINVAL:时钟ID错误。 +- ENOTSUP:不支持的时钟ID。 + +#### nanosleep + +nanosleep()函数应导致当前线程暂停执行,直到rqtp参数指定的时间间隔过去或信号传递到调用线程。挂起时间可能比请求的长,因为参数值被四舍五入到睡眠分辨率的整数倍,或者因为系统调度了其他活动。但是,除被信号中断外,暂停时间不得小于rqtp规定的时间。 + +如果rmtp参数是非NULL,则更新其为剩余的时间量(请求的时间减去实际睡眠时间)。如果rmtp参数为NULL,则不返回剩余时间。 + +**参数**: + +1. timespec结构体指针rqtp。 +2. timespec结构体指针rmtp。 + +**输出**: + +返回值: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EINVAL:rqtp参数指定的纳秒值小于0或大于等于1000 million。 +- EINTR:信号中断。 + +#### sleep + +sleep()函数应导致调用线程暂停执行,直到参数seconds指定的实时秒数过去或信号被传递到调用线程。由于系统安排了其他活动,暂停时间可能比请求的要长。 + +**参数**: 秒数seconds。 + +**输出**: + +- 0:操作成功。 +- 如果由于信号的传递而返回,则返回值应为“未睡眠”量,以秒为单位。 + +#### timer_create + +timer_create()函数使用指定的时钟clock_id作为时序基创建计时器,在timerid引用的位置返回计时器ID,用于标识计时器。在删除计时器之前,此计时器ID在调用过程中应是唯一的。 + +**参数**: + +1. 时钟类型clock_id。 +2. sigevent结构体指针evp。(仅支持SIGEV_THREAD) +3. 定时器ID指针timerid。 + +**输出**: + +- 0:操作成功。 +- EINVAL:clock_id不合法。 +- EAGAIN:系统缺少足够的资源来满足请求。 +- EINVAL:指定的时钟ID未定义。 +- ENOTSUP:不支持创建附加到clock_id时钟上的计时器。 + +#### timer_delete + +删除定时器。 + +**参数**:定时器ID指针timerid。 + +**输出**: + +- 0:操作成功。 +- EINVAL:timerid不合法。 + +#### timer_settime + +如果value的it_value成员非0,timer_settime()函数从value参数的it_value成员设置timerid指定的计时器的到期时间。如果在调用timer_settime()时指定的计时器已启用,则此调用应将下次到期的时间重置为指定的值。如果value的it_value成员为0,则应解除计时器。 + +**参数**: + +1. 定时器ID timerid。 +2. 计时器的特征flag。 +3. itimerspec结构体指针value。 +4. itimerspec结构体指针ovalue。返回上一次计时器设置超时时间。 + +**输出**: + +- 0:操作成功。 +- EINVAL:timerid不合法。 + +#### timer_gettime + +timer_gettime() 函数存储定时器 timerid 的剩余时间以及间隔。value 的 it_value 成员包含计时器到期前的时间量,如果计时器已解除,则为零。value 的 it_interval 成员将包含 timer_settime() 上次设置的间隔时间。 + +**参数**: + +1. 定时器ID timerid。 +2. itimerspec结构体指针value。 + +**输出**: + +- 0:操作成功。 +- EINVAL:timerid不合法。 + +#### timer_getoverrun + +根据指定的定时器ID,获取定时器的超时次数。 + +**参数**: + +1. 定时器ID timerid。 +2. itimerspec结构体指针value。 + +**输出**: + +- 非负数:超时次数。 +- -1:操作失败。 + +errno: + +- EINVAL:无效ID或定时器未初始化。 + +#### times + +获取进程的执行时间。由于UniProton无用户模式/内核模式且无子进程概念,出参和返回值均为进程执行总时间。 + +**参数**: + +1. tms结构体指针ts。 + +**输出**: + +- 非负数:进程的执行时间。 + +#### ctime + +ctime() 函数将tp指向的time_t结构体对象转换为的字符串。效果等同于asctime(localtime(t))。 + +**参数**: time_t结构体指针tp。 + +**输出**: + +- 成功则返回字符串指针。 +- 失败返回NULL。 + +#### ctime_r + +ctime_r() 函数将tp指向的time_t结构体对象转换为的字符串,并将字符串放入buf指向的数组中(其大小应至少为26字节)并返回buf。 + +**参数**: + +1. tm结构体指针timeptr。 +2. 字符串缓冲区buf。 + +**输出**: + +- 成功则返回字符串指针。 +- 失败返回NULL。 + +#### difftime + +计算两个日历时间之间的差值(由第一个参数减去第二个参数)。 + +**参数**: + +1. 第一个时间值t1。 +2. 第二个时间值t0。 + +**输出**: + +- 返回时间差值。 + +#### getdate + +暂不支持 + +#### gettimeofday + +gettimeofday() 函数应获取当前时间,并将其存储在tp指向的timeval结构中。如果时区结果tz不是空指针,则行为未指定。 + +**参数**: + +1. timeval结构体指针tp。 +2. 时区指针tz。 + +**输出**: + +- 返回0。 + +#### gmtime + +将time_t结构表示的日历时间转换为tm结构表示的时间,无时区转换。 + +**参数**:time_t结构体指针。 + +**输出**: + +返回值: + +- tm结构体指针。 + +errno: + +- EOVERFLOW:转换溢出。 + +#### gmtime_r + +与gmtime函数类似,不同的是gmtime_r会将结果放入在用户提供的tm结构体中。 + +**参数**: + +1. time_t结构体指针。 +2. tm结构体指针。 + +**输出**: + +返回值: + +- tm结构体指针。 + +errno: + +- EOVERFLOW:转换溢出。 + +#### localtime + +将time_t结构表示的日历时间转换为tm结构表示的本地时间,受时区的影响。 + +**参数**:time_t结构体指针。 + +**输出**: + +返回值: + +- tm结构体指针。 + +errno: + +- EOVERFLOW:转换溢出。 + +#### localtime_r + +与localtime函数类似,不同的是localtime_r会将结果放入在用户提供的tm结构体中。 + +**参数**: + +1. time_t结构体指针。 +2. tm结构体指针。 + +**输出**: + +返回值: + +- tm结构体指针。 + +errno: + +- EOVERFLOW:转换溢出。 + +#### mktime + +将已经根据时区信息计算好的tm结构表示的时间转换为time_t结构表示的时间戳,受时区的影响。 + +**参数**:tm结构体指针。 + +**输出**: + +返回值: + +- time_t结构体指针。 + +errno: + +- EOVERFLOW:转换溢出。 + +#### strftime + +暂不支持 + +#### strftime_l + +暂不支持 + +#### strptime + +使用format指定的格式,将buf指向的字符串解析转换为tm结构体的时间值。 + +**参数**: + +1. 时间字符串buf。 +2. 格式字符串format。 +3. tm结构体指针tp。 + +**输出**: + +- 成功则返回指针,指向解析的最后一个字符后面的字符。 +- 失败返回NULL。 + +#### time + +获取当前的日历时间,即从一个标准时间点到此时的时间经过的秒数。 + +**参数**:time_t结构体指针t。 + +**输出**:time_t结构体指针t。 + +#### timespec_get + +返回基于给定时基base的时间,由timespec结构体保存。时基通常为TIME_UTC。 + +**参数**: + +1. timespec结构体指针ts。 +2. 时基base + +**输出**: + +- 成功则返回时基的值。 +- 失败则返回0。 + +#### utime + +暂不支持。 + +#### wcsftime + +暂不支持 + +#### wcsftime_l + +暂不支持 + +### 内存管理 + +#### malloc + +malloc()分配大小(以字节为单位)size 的未使用的空间。 + +**参数**:大小size。 + +**输出**:分配成功时,返回指向分配空间的指针。 + +- 如果size 为0,则返回空指针或可以成功传递给 free()的唯一指针。 +- 否则它将返回一个空指针,并设置 errno 来指示错误:ENOMEM 存储空间不足。 + +#### free + +Free()函数释放ptr指向的空间,即可供进一步分配。如果ptr是空指针,则不发生任何操作。如果空间已被对free()或realloc()的调用释放,则行为未定义。 + +**参数**:指针ptr。 + +**输出**:无 + +#### memalign + +memalign()函数将分配按align大小字节对齐,大小为len的内存空间指针。 + +**参数**:align是对齐字节数,len指定分配内存的字节大小。 + +**输出**:成功完成后,空间大小为len的指针。 + +#### realloc + +realloc()函数将释放ptr所指向的旧对象,并返回一个指向新对象的指针,该对象的大小由size指定。并拷贝旧指针指向的内容到新指针,然后释放旧指针指向的空间。如果ptr是空指针,则realloc()对于指定的大小应等同于malloc()。 + +**参数**:旧指针地址;新指针的目标分配空间大小。 + +**输出**:在成功完成后,realloc()将返回一个指向分配空间的指针。如果size为0,则行为不可预测。 + +#### malloc_usable_size + +malloc_usable_size()函数返回ptr所指向的块中的可用字节数。 + +**参数**:待计算内存块大小的指针。 + +**输出**:返回ptr指向的已分配内存块中的可用字节数。如果ptr为NULL,则返回0。 + +#### aligned_alloc + +aligned_alloc()函数分配size字节未初始化的存储空间,按照alignment指定对齐。 + +**参数**:alignment指定对齐;size是分配的字节数。 + +**输出**:返回指向新分配内存的指针。 + +#### reallocarray + +reallocarray()函数将释放ptr所指向的旧对象,并返回一个指向新对象的指针,该对象的大小由size由入参m和n决定。等同于realloc(ptr, m * n); + +**参数**:ptr待释放的指针内容,m和n代表数组的长度和单个元素的字节数。 + +**输出**:在成功完成后返回一个指向分配空间的指针。如果size为0,则行为不可预测。 + +#### calloc + +calloc()函数将为一个数组分配未使用的空间,并将该空间应初始化为所有位0。 + +**参数**:m和n分别代表数组的元素个数或单个元素的大小。 + +**输出**:分配成功时,返回指向分配空间的指针。失败时则行为不可预测。 + +#### posix_memalign + +posix_memalign()函数将分配按align指定的边界对齐的大小字节,并返回指向在memptr中分配的内存的指针。对齐的值应该是sizeof(void *)的2倍幂。 + +**参数**:res分配好的内存空间的首地址,align是对齐字节数,len指定分配内存的字节大小。 + +**输出**:成功完成后,posix_memalign()将返回零;否则,将返回一个错误号来表示错误,并且不修改memptr的内容,或者将其设置为空指针。 + +### 退出管理 + +#### abort + +abort()函数触发程序的异常终止,除了信号SIGABRT没有被捕获或者返回。 + +**参数**:无 + +**输出**:无 + +#### _Exit + +_Exit()函数终止程序。 + +**参数**:入参是0,EXIT_SUCCESS, EXIT_FAILURE或任何其他值。wait()和waitpid()只能获得最低有效的8位(即status & 0377);完整的值应该可以从waitid()和siginfo_t中获得,SIGCHLD传递给信号处理程序。 + +**输出**:无 + +#### atexit + +atexit()注册一个在程终止时运行的函数。在正常的程序终止时,所有由atexit()函数注册的函数都应该按照其注册的相反顺序被调用,除非一个函数在之前注册的函数之后被调用,而这些函数在注册时已经被调用了。正常的终止发生在调用exit()或从main()返回时。 + +**参数**:函数指针,该入参函数不带参数。 + +**输出**:成功返回0;失败返回非0。 + +#### quick_exit + +quick_exit()函数触发快速程序终止,并以后进先出(LIFO)的顺序调用由at_quick_exit注册的函数。 + +**参数**:程序退出的状态码。 + +**输出**:无 + +#### at_quick_exit + +at_quick_exit()函数注册由func指向的函数,在快速程序终止时(通过quick_exit)调用。最多能注册32个函数。 + +**参数**:指向快速程序退出时要调用的函数的指针。 + +**输出**:注册成功返回0,否则为非零值。 + +#### assert + +assert()宏将在程序中插入断言,它将扩展为一个void表达式。当它被执行时,如果判断条件失败。assert()将写失败特定的调用信息,并将调用abort()退出程序。 + +**参数**:判断表达式。 + +**输出**:无 + +### stdlib接口 + +#### div + +div()函数计算int型除法的商和余数。如果余数或商不能表示,结果是未知的。 + +**参数**:int numer(分子), int denom(分母)。 + +**输出**:结构体div_t,int型的商和余数。 + +#### ldiv + +ldiv()函数将计算long型除法的商和余数。如果余数或商不能表示,结果是未知的。 + +**参数**:long numer(分子), long denom(分母)。 + +**输出**:结构体ldiv_t,long型的商和余数。 + +#### lldiv + +lldiv()函数将计算long long型除法的商和余数。如果余数或商不能表示,结果是未知的。 + +**参数**:long long numer(分子), long long denom(分母)。 + +**输出**:结构体lldiv_t,long long型的商和余数。 + +#### imaxdiv + +imaxdiv()函数将计算intmax_t型除法的商和余数。如果余数或商不能表示,结果是未知的。 + +**参数**:intmax_t numer(分子), intmax_t denom(分母)。 + +**输出**:结构体imaxdiv_t,intmax_t型的商和余数。 + +#### wcstol + +wcstol()将宽字符串转换为long型正数。输入字符串分解为三部分。 + +1. 初始的(可能为空的)空白宽字符代码序列(由iswspace()指定)。 +2. long型整数,进制的类型由base入参决定。 +3. 由一个或多个无法识别的宽字符代码组成的最终宽字符串。 + +**参数**:指向要解释的以空字符结尾的宽字符串的指针;指向宽字符的指针;解释的整数值的基数。 + +**输出**:转换后的long型数值。如果无法进行转换,则返回0,并设置errno表示错误。如果正确值在可表示的值范围之外,则返回LONG_MIN,LONG_MAX,LLONG_MIN或LLONG_MAX,并将errno设置为ERANGE。 + +#### wcstod + +wcstod()将宽字符串转换为double型浮点数。输入字符串分解为三部分。 + +1. 初始的(可能为空的)空白宽字符代码序列(由iswspace()指定)。 +2. double型浮点数、无穷大或者NaN。 +3. 由一个或多个无法识别的宽字符代码组成的最终宽字符串。 + +**参数**:指向要解释的以空字符结尾的宽字符串的指针;指向宽字符的指针; + +**输出**:转换后的double型浮点数。如果越界,则可能返回±HUGE_VAL, ±HUGE_VALF或±HUGE_VALL,并将errno设置为ERANGE。 + +#### fcvt + +fcvt()将浮点数转换为要求长度的字符串,没有小数点,如果超过value的数字长度将补零。 + +**参数**:待转换的浮点数、转换后字符串的长度、小数点所在位指针、符号位指针。 + +**输出**:转换后字符串指针。 + +#### ecvt + +ecvt()函数将浮点数转换为要求长度的字符串,没有小数点,如果超过value的数字长度不补零(与fcvt的区别)。 + +**参数**:待转换的浮点数、转换后字符串的长度、小数点所在位指针、符号位指针。 + +**输出**:转换后字符串指针。 + +#### gcvt + +gcvt()函数将double类型的值转换为要求长度的字符串,包含小数点。 + +**参数**:待转换的浮点数,转换后字符串的长度、转换后字符串指针。 + +**输出**:转换后字符串指针(等于函数成功调用后第三个入参的指针)。 + +#### qsort + +qsort()函数对数据表进行排序。 + +**参数**:qsort()函数将对nel对象数组进行排序,该数组的初始元素由base指向。每个对象的大小(以字节为单位)由width参数指定。如果nel参数的值为0,则不会调用comp所指向的比较函数,也不会进行重排。应用程序应确保compar所指向的比较函数不会改变数组的内容。实现可以在调用比较函数之间对数组元素重新排序,但不能改变任何单个元素的内容。 + +**输出**:无 + +#### abs + +abs()函数计算并返回int型数值的绝对值。 + +**参数**:int整型数值。 + +**输出**:int整型数值的绝对值。 + +#### labs + +labs()函数计算并返回long型数值的绝对值。 + +**参数**:long型数值。 + +**输出**:long型数值的绝对值。 + +#### llabs + +llabs()函数计算并返回long long型数值的绝对值。 + +**参数**:long long型数值。 + +**输出**:long long型数值的绝对值。 + +#### imaxabs + +imaxabs()函数计算并返回intmax_t型的绝对值。 + +**参数**:intmax_t型数值。 + +**输出**:intmax_t型数值的绝对值。 + +#### strtol + +strtol()函数转换字符串到long型数值。这将nptr所指向的字符串的初始部分转换为long类型的表示形式。首先,它们将输入字符串分解为三部分: + +1. 一个初始的、可能为空的空白字符序列(由isspace()函数判断)。 +2. long型整数,进制的类型由base入参决定。 +3. 由一个或多个不可识别字符组成的最后字符串,包括输入字符串的终止NUL字符。 + +**参数**:待转换的字符串的指针;指向字符的指针;解释的整数值的基数。 + +**输出**:转换后的long型。如果无法进行转换,则返回0,并设置errno表示错误。如果正确值在可表示的值范围之外,则返回LONG_MIN, LONG_MAX, LLONG_MIN或LLONG_MAX,并将errno设置为EINVAL。 + +#### strtod + +strtod()函数将字符串转换为double型。输入字符串分解为三部分。 + +1. 初始的(可能为空的)空白字符代码序列(由isspace()指定)。 +2. double型浮点数、无穷大或者NaN。 +3. 由一个或多个无法识别的字符代码组成的最终字符串。 + +**参数**:待转换的字符串的指针;指向字符的指针; + +**输出**:转换后的double型浮点数。如果越界,则可能返回±HUGE_VAL, ±HUGE_VALF或±HUGE_VALL,并将errno设置为EINVAL。 + +#### atoi + +atoi()函数将字符串转换为int型整数。 + +**参数**:待转换的字符串的指针。 + +**输出**:转换后的int型数值。如果是无法显示数值,返回值不可预测。 + +#### atol + +atol()函数将字符串转换为long型整数。 + +**参数**:待转换的字符串的指针。 + +**输出**:转换后的long型数值。如果是无法显示数值,返回值不可预测。 + +#### atoll + +atoll()函数将字符串转换为long long型整数。 + +**参数**:待转换的字符串的指针。 + +**输出**:转换后的long long型数值。如果是无法显示数值,返回值不可预测。 + +#### atof + +atof()函数将字符串转换为double型浮点数。 + +**参数**:待转换的字符串的指针。 + +**输出**:转换后的double型数值。如果是无法显示数值,返回值不可预测。 + +#### bsearch + +bsearch()函数二分查找一个已排序表.将搜索一个nel对象数组,该数组的初始元素由base指向,以查找与key指向的对象匹配的元素。数组中每个元素的大小由width指定。如果nel参数的值为0,则不会调用compar所指向的比较函数,也不会找到匹配项。 + +**参数**:依次为目标查找的元素,待查找的数组的指针,数组的元素个数,数组每个元素的size大小,两个元素的比较函数。 + +**输出**:指向数组中匹配成员的指针,如果没找到则返回空指针。 + +### SystemV IPC + +#### semget + +semget()函数返回与参数key相关联的SystemV信号量集的标识符。它可用于获得先前创建的信号量集合的标识符(当flag为0且key不为IPC_PRIVATE时)或来创建一个新的集合。最多可以支持创建SEMSET_MAX_SYS_LIMIT个信号量集合,每个集合最多支持SEMSET_MAX_SEM_NUM个信号量。 + +**参数**: + +1. 键值key。 +2. 信号量的个数nsems。 +3. 信号量的创建方式和权限flag。 + +**输出**: + +- 非负数:信号量集的标识符。 +- -1: 操作失败。 + +errno: + +- EINVAL:参数错误。 +- ENOENT:信号量集不存在。 +- ENOSPC:超出最大信号量集合的限制。 +- EEXIST:flag包含了IPC_CREAT和IPC_EXCL但标识符已存在。 + +#### semctl + +semctl()函数在由semid标识的SystemV信号量集合中的第semnum个信号量上执行由cmd指定的控制操作。集合中的信号量从0开始编号。当前支持的cmd包括IPC_STAT(支持获取信号量集合中的个数)、GETALL(获取信号量集合中所有信号量的值)、GETVAL(获取单个信号量的值)和IPC_RMID(根据标识符删除信号量集合)。 + +**参数**: + +1. 信号量集合标识符semid。 +2. 信号量中的编号semnum。 +3. 要执行的操作命令cmd。 +4. 可选参数union semun结构体arg。 + +**输出**: + +- 0:操作成功。 +- -1: 操作失败。 + +errno: + +- EINVAL:参数错误。 +- EIDRM:信号量集合已删除。 +- EFAULT:arg中的buf或array指针为空。 + +#### semop + +semop()函数对semid关联的信号量集合中选定的信号量进行操作,也就是使用资源或者释放资源。具体操作由struct sembuf结构体来决定。结构体包括数组索引semnum,信号量操作(支持+1或-1,表示释放资源和使用资源)op,操作方式flag(支持IPC_NOWAIT,不阻塞操作)。当前只支持单个信号量的操作。 + +**参数**: + +1. 信号量集合标识符semid。 +2. 指向struct sembuf结构体的数组sops。 +3. 数组个数nsops。 + +**输出**: + +- 0:操作成功。 +- -1: 操作失败。 + +errno: + +- EINVAL:参数错误。 +- ENOTSUP:操作不支持。 +- EFAULT:数组指针sops为空。 +- E2BIG:数组个数nsops超过限制。 +- EIDRM;信号量集合已删除。 +- EFBIG:某个信号量索引超过限制。 +- EAGAIN:操作无法立即进行,如flag包含了IPC_NOWAIT或超时。 + +#### semtimedop + +semtimedop()的行为与semop()相同,不同点在于增加一个超时时间,等待超时返回错误码。 + +**参数**: + +1. 信号量集合标识符semid。 +2. 指向struct sembuf结构体的数组sops。 +3. 数组个数nsops。 +4. timespec结构体指针timeout。 + +**输出**: + +- 0:操作成功。 +- -1: 操作失败。 + +errno: + +- EINVAL:参数错误。 +- ENOTSUP:操作不支持。 +- EFAULT:数组指针sops为空。 +- E2BIG:数组个数nsops超过限制。 +- EIDRM;信号量集合已删除。 +- EFBIG:某个信号量索引超过限制。 +- EAGAIN:操作无法立即进行,如flag包含了IPC_NOWAIT或超时。 + +#### msgget + +msgget()返回与参数key相关联的SystemV消息队列的标识符。它可用于获得先前创建的消息队列的标识符(当flag为0且key不为IPC_PRIVATE时)或来创建一个新的消息队列。最多支持创建MSGQUE_MAX_SYS_LIMIT个消息队列,消息队列默认大小为MSGQUE_MAX_MSG_NUM,消息大小默认为MSGQUE_MAX_MSG_SIZE。 + +**参数**: + +1. 键值key。 +2. 消息队列的创建方式和权限flag。 + +**输出**: + +- 非负数:消息队列的标识符。 +- -1: 操作失败。 + +errno: + +- EINVAL:参数错误。 +- ENOENT:消息队列不存在。 +- ENOSPC:超出最大消息队列的限制。 +- EEXIST:flag包含了IPC_CREAT和IPC_EXCL但标识符已存在。 +- ENOMEM:内存不足。 + +#### msgctl + +msgctl()在标识为msgqid的SystemV消息队列上执行cmd指定的控制操作。当前支持IPC_STAT(支持获取消息队列中的消息个数和大小)、IPC_RMID(删除消息队列)。 + +**参数**: + +1. 消息队列标识符msgqid。 +2. 消息队列控制命令cmd。 +3. 消息队列信息msqid_ds结构体buf。 + +**输出**: + +- 0:操作成功。 +- -1: 操作失败。 + +errno: + +- EINVAL:参数错误。 +- EFAULT:msqid_ds结构体指针为空。 +- EIDRM:消息队列已删除。 +- ENOTSUP:不支持的命令。 + +#### msgsnd + +msgsnd()将msgp指向的消息追加到msgqid指定的SystemV消息队列中,如果队列有足够空间,msgsnd立即执行。消息大小不超过MSGQUE_MAX_MSG_SIZE。当前flag支持IPC_NOWAIT,表示操作不等待。 + +**参数**: + +1. 消息队列标识符msgqid。 +2. 需要发送的消息msgp。 +3. 发送消息的大小msgsz。 +4. 发送方式flag。 + +**输出**: + +- 0:操作成功。 +- -1: 操作失败。 + +errno: + +- EINVAL:参数错误。 +- EFAULT:msgp指针为空。 +- EIDRM:消息队列已删除。 +- ENOTSUP:不支持的命令。 + +#### msgrcv + +msgrcv()函数将消息从msgqid指定的消息队列中移除,并放入msgp指向的缓冲区中。参数msgsz指定了缓冲区buf的大小。当前msgtype支持的值为0,flag支持IPC_NOWAIT,表示操作不等待。 + +**参数**: + +1. 消息队列标识符msgqid。 +2. 需要接受消息的缓冲区msgp。 +3. 接受消息的大小msgsz。 +4. 接受消息的类型msgtype。 +5. 发送方式flag。 + +**输出**: + +- 0:操作成功。 +- -1: 操作失败。 + +errno: + +- EINVAL:参数错误。 +- EFAULT:msgp指针为空。 +- EIDRM:消息队列已删除。 +- ENOTSUP:不支持的命令。 +- ENOMSG:消息队列中没有请求类型的消息。 + +#### shmget + +暂不支持 + +#### shmctl + +暂不支持 + +#### shmat + +暂不支持 + +#### shmdt + +暂不支持 + +#### ftok + +暂不支持 + +#### fstatat + +fstatat()函数根据相对路径获取相关的文件统计信息。 + +**参数**: + +1. 文件描述符fd。 +2. 路径名path。 +3. 文件信息指针st。 +4. 操作标记flag。 + +**输出**: + +- 目录流指针:操作成功。 +- NULL:操作失败。 + +errno: + +- EFAULT:指针为空。 +- ENOENT:没有这样的文件。 +- ENOSYS:缺少相关函数。 + +#### fchmodat + +fchmodat()函数根据相对路径更改相关文件的访问权限。 + +**参数**: + +1. 文件描述符fd。 +2. 路径名path。 +3. 访问模式mode。 +4. 操作标记flag。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EINVAL:参数错误。 +- ELOOP:符号连接的层数过多。 +- ENOSYS:缺少相关函数。 + +#### mkdir + +mkdir()函数用于参数路径名path的创建目录。 + +**参数**: + +1. 路径名path。 +2. 访问模式mode。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- ENXIO:驱动程序问题。 +- EEXIST:目录已存在。 +- ENOSYS:缺少相关函数。 + +#### chmod + +chmod()函数用来控制相关文件的权限。 + +**参数**: + +1. 路径名path。 +2. 访问模式mode。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EINVAL:参数错误。 +- ELOOP:符号连接的层数过多。 + +#### lstat + +lstat()函数根据路径名path获取相关的链接文件统计信息。 + +**参数**: + +1. 路径名path。 +2. 文件信息结构体stat。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EFAULT:参数指针为空。 +- ENOENT:没有这样的文件。 +- ENOMEM:内存不足。 + +#### utimensat + +utimensat()函数根据相对目录更改相关的文件时间戳。 + +**参数**: + +1. 文件描述符fd。 +2. 路径名pathname。 +3. 时间结构体数组times。 +4. 操作标识flags。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +#### mkfifo + +mkfifo()函数用于在文件系统中创建一个有名管道。 + +**参数**: + +1. 路径名pathname。 +2. 访问模式mode。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EEXIST:文件已存在。 +- ENXIO:驱动程序问题。 +- ENOSYS:缺少相关函数。 + +#### fchmod + +fchmod()函数可以修改文件描述符fd相关的文件权限。 + +**参数**: + +1. 文件描述符fd。 +2. 访问模式mode。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EINVAL:参数错误。 +- ELOOP:符号连接的层数过多。 +- ENOSYS:缺少相关函数。 + +#### mknod + +mknod()函数用于建立FIFO、字符设备文件以及块设备文件等。 + +**参数**: + +1. 路径名path。 +2. 访问模式mode。 +3. 设备号dev。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EEXIST:文件已存在。 +- ENXIO:驱动程序问题。 +- ENOSYS:缺少相关函数。 + +#### statvfs + +statvfs()函数根据路径名path获取磁盘信息。 + +**参数**: + +1. 路径名path。 +2. statvfs结构体指针buf。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EFAULT:错误地址。 +- ENOENT:不存在文件。 +- ENOMEM:内存不足。 + +#### mkfifoat + +mkfifoat()函数与mkfifo()函数类似,在参数fd表示的目录相关位置创建一个有名管道。 + +**参数**: + +1. 文件描述符fd。 +2. 路径名path。 +3. 访问模式mode。 +4. 设备号dev。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EEXIST:文件已存在。 +- ENXIO:驱动程序问题。 +- ENOSYS:缺少相关函数。 + +#### umask + +umask()函数设置预设的文件权限。 + +**参数**: + +1. 访问权限mode。 + +**输出**: + +- 前一个访问权限:操作成功。 + +#### mknodat + +mknodat()函数用于建立FIFO、字符设备文件以及块设备文件等,在参数fd表示的目录相关位置创建。 + +**参数**: + +1. 文件描述符fd。 +2. 路径名path。 +3. 访问模式mode。 +4. 设备号dev。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EEXIST:文件已存在。 +- ENXIO:驱动程序问题。 +- ENOSYS:缺少相关函数。 + +#### futimesat + +futimesat()函数根据目录文件描述符更改相关的文件时间戳。 + +**参数**: + +1. 文件描述符fd。 +2. 路径名pathname。 +3. 时间结构体数组times。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +#### lchmod + +lchmod()函数用来控制相关文件的权限。 + +**参数**: + +1. 路径名pathname。 +2. 访问模式mode。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EINVAL:参数错误。 +- ELOOP:符号连接的层数过多。 +- ENOSYS:缺少相关函数。 + +#### futimens + +futimens()函数根据文件描述符fd更改相关的文件时间戳的方法。 + +**参数**: + +1. 文件描述符fd。 +2. 时间结构体数组times。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +#### mkdirat + +mkdirat()函数根据相对目录文件描述符创建一个新目录。 + +**参数**: + +1. 文件描述符fd。 +2. 路径名path。 +3. 访问模式mode。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- ENXIO:驱动程序问题。 +- EEXIST:目录已存在。 +- ENOSYS:缺少相关函数。 + +#### fstat + +fstat()函数根据文件描述符fd获取相关文件的信息。 + +**参数**: + +1. 文件描述符fd。 +2. stat结构体指针buf。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EBADF:无效的描述符。 +- ENOSYS:缺少相关函数。 + +#### stat + +stat()函数根据路径名获取相关文件的信息。 + +**参数**: + +1. 路径名path。 +2. stat结构体指针buf。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EFAULT:参数指针为空。 +- ENOENT:不存在文件。 +- ENOSYS:缺少相关函数。 + +#### open + +open()函数根据文件名pathname打开相关的文件。 + +**参数**: + +1. 文件名pathname。 +2. 文件访问模式mode。 +3. 可变参数。 + +**输出**: + +- 文件描述符fd:操作成功。 +- -1:操作失败。 + +errno: + +- EINVAL:参数错误。 +- ELOOP:符号连接的层数过多。 +- EACCES:权限不足。 +- ENXIO:驱动程序问题。 + +#### creat + +creat()函数根据文件名pathname创建相关的文件。 + +**参数**: + +1. 文件名pathname。 +2. 文件访问模式mode。 + +**输出**: + +- 文件描述符fd:操作成功。 +- -1:操作失败。 + +errno: + +- EINVAL:参数错误。 +- ELOOP:符号连接的层数过多。 +- EACCES:权限不足。 +- ENXIO:驱动程序问题。 + +#### posix_fadvise + +暂不支持。 + +#### fcntl + +fcntl()函数用来修改已经打开文件的属性的函数。操作命令目前只支持F_DUPFD、F_DUPFD_CLOEXEC、F_GETFD、F_SETFD、F_GETFL、F_SETFL、F_GETPATH。 + +**参数**: + +1. 文件描述符fd。 +2. 操作命名cmd。 +3. 可变参数。 + +**输出**: + +- 文件描述符fd:操作成功。 +- -1:操作失败。 + +errno: + +- EBADF:无效的描述符。 +- ENOSYS:缺少相关函数。 +- EINVAL:参数错误。 + +#### posix_fallocate + +posix_fallocate()函数确保为文件描述符fd引用的文件分配磁盘空间,从偏移开始,持续len字节。如果文件大小小于offset+len,则文件为增加到这个大小,否则将保留文件大小不变。 + +**参数**: + +1. 文件描述符fd。 +2. 偏移offset。 +3. 长度len。 + +**输出**: + +- 文件描述符fd:操作成功。 +- -1:操作失败。 + +errno: + +- EINVAL:参数错误。 +- EFBIG:长度错误。 +- EBADF:无效的描述符。 +- EROFS:文件系统仅可读。 +- ENOSYS:缺少相关函数。 + +#### openat + +openat()函数当参数传入为绝对路径时,与open()函数一致。如果openat()函数的第一个参数fd是常量AT_FDCWD时,则其后的第二个参数路径名是以当前工作目录为基址的;否则以fd指定的目录文件描述符为基址。 + +**参数**: + +1. 文件描述符fd。 +2. 文件路径path。 +3. 打开标识oflag。 +4. 访问模式mode。 + +**输出**: + +- 文件描述符fd:操作成功。 +- -1:操作失败。 + +errno: + +- EINVAL:参数错误。 +- EFBIG:长度错误。 +- EBADF:无效的描述符。 +- EROFS:文件系统仅可读。 +- ENOSYS:缺少相关函数。 + +#### scandir + +暂不支持。 + +#### seekdir + +seekdir()函数用来设置参数dir目录流当前的读取位置。 + +**参数**: + +1. 目录流指针dir。 +2. 偏移位置off。 + +**输出**:无。 + +#### readdir_r + +暂不支持。 + +#### fdopendir + +fdopendir()函数打开与目录名称相对应的目录流指针。 + +**参数**: + +1. 文件描述符fd。 + +**输出**: + +- 目录流指针dir:操作成功。 +- NULL:操作失败。 + +errno: + +- EBADF:无效的描述符。 +- ENOTDIR:不是目录。 + +#### versionsort + +versionsort()函数将dirent的名称通过strverscmp()进行比较,用于比较版本号字符串。 + +**参数**: + +1. dirent指针a。 +2. dirent指针b。 + +**输出**: + +- 小于,等于或大于零的整数:操作成功。 + +#### alphasort + +alphasort()函数将dirent的名称通过strcoll()进行比较,用于比较版本号字符串。 + +**参数**: + +1. dirent指针a。 +2. dirent指针b。 + +**输出**: + +- 小于,等于或大于零的整数:操作成功。 + +#### rewinddir + +rewinddir()函数设置参数dir目录流读取位置为原来开头的读取位置。 + +**参数**: + +1. 目录流指针dir。 + +**输出**:无。 + +#### dirfd + +dirfd()函数返回参数dir目录流相关的文件描述符fd。 + +**参数**: + +1. 目录流指针dir。 + +**输出**: + +- 整型文件描述符值:操作成功。 + +#### readdir + +暂不支持。 + +#### telldir + +telldir()函数返回一个目录流dir的当前位置。 + +**参数**: + +1. 目录流指针dir。 + +**输出**: + +- 位置整型值:操作成功。 + +#### closedir + +closedir()函数关闭一个目录流dir。 + +**参数**: + +1. 目录流指针dir。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EBADF:无效的描述符。 + +#### opendir + +opendir()函数用来打开参数name指定的目录流。 + +**参数**: + +1. 文件名name。 + +**输出**: + +- 目录流指针:操作成功。 +- NULL:操作失败。 + +errno: + +- EINVAL:参数错误。 +- ELOOP:符号连接的层数过多。 +- EACCES:权限不足。 +- ENXIO:驱动程序问题。 + +#### putwchar + +putwchar()函数将宽字符wc写入标准输出stdout。 + +**参数**: + +1. 宽字符wc。 + +**输出**: + +- wc:操作成功。 +- WEOF: 操作失败。 + +errno: + +- EILSEQ:宽字符转换错误。 + +#### fgetws + +fgetws()函数文件流中读取最多n-1个宽字符的字符串,并增加一个终结宽空字符,保存到输入字符串ws中。 + +**参数**: + +1. 宽字符串ws。 +2. 宽字符串长度n。 +3. 文件流stream。 + +**输出**: + +- ws:操作成功。 +- NULL:操作失败。 + +#### vfwprintf + +vfwprintf()函数将format指向可变参数列表中的格式化数据的字符串写入文件流stream。 + +**参数**: + +1. 文件流stream。 +2. 指向宽字符串的指针format。 + +**输出**: + +- 成功转换字符数:操作成功。 +- -1:操作失败。 + +errno: + +- EOVERFLOW:字符串长度溢出。 +- EINVAL:参数错误。 + +#### fscanf + +fscanf()函数从文件流stream读取格式化数据到变量参数列表中。 + +**参数**: + +1. 文件流stream。 +2. 格式化输入format。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- EOF:操作失败。 + +#### snprintf + +snprintf()函数用于格式化输出字符串,并将结果写入到指定的缓冲区,并限制输出的字符数,避免缓冲区溢出。 + +**参数**: + +1. 目标字符串str。 +2. 字符数组的大小size。 +3. 格式化字符串format。 +4. 可变参数。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- -1:操作失败。 + +#### sprintf + +sprintf()函数发送格式化输出到str所指向的字符串。 + +**参数**: + +1. 目标字符串str。 +2. 格式化字符串format。 +3. 可变参数。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- -1:操作失败。 + +#### fgetpos + +fgetpos()函数获取文件流stream的当前文件位置,并把它写入到pos。 + +**参数**: + +1. 指向文件流对象指针stream。 +2. 指向fpos_t对象的指针。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +#### vdprintf + +vdprintf()函数将可变参数的格式化后的字符串输出到文件描述符中。 + +**参数**: + +1. 文件描述符fd。 +2. 格式化字符串format。 +3. 可变参数。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +#### gets + +gets()函数从标准输入stdin读取一行,并存储在str所指向的字符串中。 + +**参数**: + +1. 字符串指针str。 + +**输出**: + +- 字符串指针str:操作成功。 +- NULL:操作失败。 + +#### ungetc + +ungetc()函数将字符char推入到指定的文件流stream中,以便它是下一个被读取到的字符。 + +**参数**: + +1. 被推入的字符char。 +2. 文件流指针stream。 + +**输出**: + +- 字符char:操作成功。 +- EOF:操作失败。 + +#### ftell + +ftell()函数返回给定文件流stream的当前文件位置。 + +**参数**: + +1. 文件流指针stream。 + +**输出**: + +- 当前文件位置:操作成功。 +- -1:操作失败。 + +errno: + +- EOVERFLOW:文件位置溢出。 + +#### clearerr + +clearerr()函数清除给定文件流stream的文件结束符和错误标识符。 + +**参数**: + +1. 文件流指针stream。 + +**输出**:无 + +#### getc_unlocked + +getc_unlocked()函数从文件流stream读取字符char。 + +**参数**: + +1. 文件流指针stream。 + +**输出**: + +- 字符char:操作成功。 +- EOF:文件流结束。 + +#### fmemopen + +fmemopen()函数打开一个内存流,使其可以读取或写入由buf指定的缓冲区。 + +**参数**: + +1. 缓冲区buf。 +2. 缓冲区大小size。 +3. 操作模式mode。 + +**输出**: + +- 文件流指针:操作成功。 +- NULL:操作失败。 + +errno: + +- EINVAL:参数失败。 +- ENOMEM:内存不足。 + +#### putwc + +putwc()函数将宽字符wc写入给定的文件流stream中。 + +**参数**: + +1. 宽字符wc。 +2. 文件流stream。 + +**输出**: + +- 宽字符wc:操作成功。 +- WEOF:操作失败。 + +errno: + +- EILSEQ:宽字符转换错误。 + +#### getchar + +getchar()函数从标准输入stdin获取一个字符。 + +**参数**:无 + +**输出**: + +- 字符ch:操作成功。 +- EOF:操作失败或文件末尾。 + +#### open_wmemstream + +open_wmemstream()函数打开用于写入宽字符串缓冲区的文件流。缓冲区是动态分配的。 + +**参数**: + +1. 指向缓冲区宽字符串指针ptr。 +2. 指向缓冲区大小的指针size。 + +**输出**: + +- 文件流指针:操作成功。 +- NULL:操作失败。 + +#### asprintf + +asprintf()函数将可变参数的格式化后的数据写入字符串缓冲区buffer。 + +**参数**: + +1. 存放字符串的指针buf。 +2. 格式化字符串format。 +3. 可变参数。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- -1:操作失败。 + +#### funlockfile + +funlockfile()函数将文件流解锁。 + +**参数**: + +1. 文件流指针stream。 + +**输出**:无 + +#### fflush + +fflush()函数刷新文件流stream的输出缓冲区。 + +**参数**: + +1. 文件流指针stream。 + +**输出**: + +- 0:操作成功。 +- EOF:操作失败。 + +#### vfprintf + +vfprintf()函数将可变参数的格式化数据输出到文件流stream中。 + +**参数**: + +1. 文件流指针stream。 +2. 格式化字符串format。 +3. 可变参数。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- -1:操作失败。 + +errno: + +- EOVERFLOW:字符串长度溢出。 +- EINVAL:参数错误。 + +#### vsscanf + +vsscanf()函数从字符串中读取格式化的数据到变量参数列表中。 + +**参数**: + +1. 处理字符串的指针str。 +2. 格式化字符串format。 +3. 可变参数。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- -1:操作失败。 + +#### vfwscanf + +vfwscanf()函数从文件流中读取格式化的数据到变量参数列表中。 + +**参数**: + +1. 输入文件流stream。 +2. 格式化字符串format。 +3. 可变参数。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- -1:操作失败。 + +#### puts + +puts()函数将指定字符串写入到标准输出stdout中。 + +**参数**: + +1. 输出字符串str。 + +**输出**: + +- 字符串长度:操作成功。 +- EOF:操作失败。 + +#### getchar_unlocked + +getchar_unlocked()函数读取标准输入stdin的一个字符。 + +**参数**:无。 + +**输出**: + +- 读取字符char:操作成功。 +- EOF:操作失败。 + +#### setvbuf + +setvbuf()函数设置文件流stream的缓冲模式。当前只支持无缓冲模式。 + +**参数**: + +1. 文件流stream。 +2. 分配的缓冲区buf。 +3. 指定文件缓冲的模式mode。 +4. 缓冲区大小size。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +#### getwchar + +getwchar()函数从标准输入stdin获取一个宽字符。 + +**参数**:无。 + +**输出**: + +- 宽字符ch:操作成功。 +- EOF:操作失败或文件末尾。 + +#### setbuffer + +setbuffer()函数用来设置文件流stream的缓冲区。 + +**参数**: + +1. 文件流指针stream。 +2. 缓冲区buf。 +3. 缓冲区大小size。 + +**输出**:无。 + +#### vsnprintf + +vsnprintf()函数将可变参数的格式化数据输出到字符串缓冲区中。 + +**参数**: + +1. 字符串缓冲区str。 +2. 缓冲区大小size。 +3. 格式化字符串format。 +4. 可变参数。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- -1:操作失败。 + +#### freopen + +freopen()函数将一个新的文件名filename与给定的打开的流stream关联,同时关闭流中的旧文件。 + +**参数**: + +1. 新的文件名filename。 +2. 文件访问模式mode。 +3. 文件流指针stream。 + +**输出**: + +- 文件流指针stream:操作成功。 +- NULL:操作失败。 + +#### fwide + +fwide()函数用于设置文件流的定向。 + +**参数**: + +1. 文件流fp。 +2. 设置模式mode。 + +**输出**: + +- mode:操作成功。 + +#### sscanf + +sscanf()函数从字符串中读取格式化的数据到变量列表中。 + +**参数**: + +1. 处理字符串的指针str。 +2. 格式化字符串format。 +3. 可变参数。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- -1:操作失败。 + +#### fgets + +fgets()函数从指定的流中读取数据,每次读取n-1个字符或换行符或结束,并存储在参数str所指向的字符串内。 + +**参数**: + +1. 字符串的指针str。 +2. 读取最大字符数n. +3. 文件流stream。 + +**输出**: + +- 返回相同的str参数:操作成功。 +- NULL:操作失败。 + +#### vswscanf + +vswscanf()函数从参数str读取格式化的宽字符数据到变量参数列表中。 + +**参数**: + +1. 字符串的指针str。 +2. 格式化字符串format。 +3. 可变参数。 + +**输出**: + +- 成功匹配数:操作成功。 +- -1:操作失败。 + +#### vprintf + +vprintf()函数将格式化字符串输出到标准输出stdout。 + +**参数**: + +1. 格式化字符串format。 +2. 可变参数。 + +**输出**: + +- 成功写入字符数:操作成功。 +- -1:操作失败。 + +errno: + +- EINVAL:参数错误。 +- EOVERFLOW:字符串溢出。 + +#### fputws + +fputws()函数将参数宽字符串str写入指定的文件流stream。 + +**参数**: + +1. 宽字符串str。 +2. 文件流指针stream。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +#### wprintf + +wprintf()函数将格式化字符串format写入到标准输出stdout。 + +**参数**: + +1. 格式化字符串format。 +2. 可变参数。 + +**输出**: + +- 返回写入字符数:操作成功。 +- -1:操作失败。 + +#### wscanf + +wscanf()函数从标准输入stdin读取格式化的宽字符数据到可变变量列表。 + +**参数**: + +1. 格式化字符串format。 +2. 可变参数。 + +**输出**: + +- 返回成功匹配数:操作成功。 +- -1:操作失败。 + +#### fputc + +fputc()函数将字符c写入指定的文件流stream。 + +**参数**: + +1. 输入字符c。 +2. 文件流指针stream。 + +**输出**: + +- 返回成功匹配数:操作成功。 +- EOF:操作失败。 + +#### putchar + +putchar()函数将字符c写入标准输入stdin。 + +**参数**: + +1. 输入字符c。 + +**输出**: + +- 返回成功匹配数:操作成功。 +- EOF:操作失败。 + +#### flockfile + +flockfile()函数将指定的文件流锁定。 + +**参数**: + +1. 文件流指针stream。 + +**输出**:无。 + +#### vswprintf + +vswprintf()函数将格式化字符串写入大小已设置的缓冲区中。 + +**参数**: + +1. 宽字符串ws。 +2. 宽字符串大小len。 +3. 格式化字符串format。 +4. 可变参数。 + +**输出**: + +- 返回成功匹配数:操作成功。 +- -1:操作失败。 + +errno: + +- EOVERFLOW:字符串溢出。 + +#### fputwc + +fputwc()函数将参数宽字符wc写入文件流stream。 + +**参数**: + +1. 宽字符wc。 +2. 文件流指针stream。 + +**输出**: + +- 宽字符wc:操作成功。 +- WEOF:操作失败。 + +#### fopen + +fopen()函数使用给定的模式mode打开filename所指向的文件。 + +**参数**: + +1. 文件名filename。 +2. 文件访问模式mode。 + +**输出**: + +- 文件流指针:操作成功。 +- NULL:操作失败。 + +errno: + +- EINVAL:参数错误。 + +#### tmpnam + +tmpnam()函数生成并返回一个有效的临时文件名,并存储在参数缓冲区buf中。 + +**参数**: + +1. 文件名filename。 + +**输出**: + +- 临时文件名:操作成功。 +- NULL:操作失败。 + +#### ferror + +ferror()函数测试给定文件流stream的错误标识符。 + +**参数**: + +1. 文件流指针stream。 + +**输出**: + +- 0:文件流未出错。 +- 非零值:文件流出错。 + +#### printf + +printf()函数将格式化字符串format写入到标准输出stdout。 + +**参数**: + +1. 格式化字符串format。 +2. 可变参数。 + +**输出**: + +- 成功写入字符数:操作成功。 +- -1:操作失败。 + +#### open_memstream + +open_memstream()函数打开用于写入字符串缓冲区的文件流。缓冲区是动态分配的。 + +**参数**: + +1. 指向缓冲区宽字符串指针ptr。 +2. 指向缓冲区大小的指针size。 + +**输出**: + +- 文件流指针:操作成功。 +- NULL:操作失败。 + +#### fwscanf + +fwscanf()函数从文件流stream中读取格式化数据将值存储到可变变量列表中。 + +**参数**: + +1. 文件流指针stream。 +2. 格式化字符串format。 +3. 可变参数。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- -1:操作失败。 + +#### fprintf + +fprintf()函数将格式化字符串写入到指定文件流stream。 + +**参数**: + +1. 文件流指针stream。 +2. 格式化字符串format。 +3. 可变参数。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- -1:操作失败。 + +errno: + +- EOVERFLOW:字符串长度溢出。 +- EINVAL:参数错误。 + +#### fgetc + +fgetc()函数从文件流stream中读取一个字符c。 + +**参数**: + +1. 文件流指针stream。 + +**输出**: + +- 读取的字符c:操作成功。 +- EOF:操作失败。 + +#### rewind + +rewind()函数将文件流内部指针重新指向开头。 + +**参数**: + +1. 文件流指针stream。 + +**输出**:无。 + +#### getwc + +getwc()函数从文件流读取一个宽字符wc。 + +**参数**: + +1. 文件流指针stream。 + +**输出**: + +- 读取的宽字符c:操作成功。 +- WEOF:操作失败。 + +#### scanf + +scanf()函数从标准输入stdin读取格式化输入到可变变量列表中。 + +**参数**: + +1. 格式化字符串format。 +2. 可变参数。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- -1:操作失败。 + +#### perror + +perror()函数将错误提示字符串打印出来。 + +**参数**: + +1. 错误字符串msg。 + +**输出**:无。 + +#### vsprintf + +vsprintf()函数将格式化字符串输出到参数指定的字符串str。 + +**参数**: + +1. 字符串缓冲区str。 +2. 格式化字符串format。 +3. 可变参数。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- -1:操作失败。 + +#### vasprintf + +vasprintf()函数将格式化字符串写入动态分配的字符串缓冲区中。 + +**参数**: + +1. 字符串缓冲区指针str。 +2. 格式化字符串format。 +3. 可变参数。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- -1:操作失败。 + +#### getc + +getc()函数从文件流stream中读取一个字符c。 + +**参数**: + +1. 文件流指针stream。 + +**输出**: + +- 读取的字符c:操作成功。 +- EOF:操作失败。 + +#### dprintf + +dprintf()函数将格式化字符串写入到文件描述符fd指定的文件中。 + +**参数**: + +1. 文件描述符fd。 +2. 格式化字符串format。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- -1:操作失败。 + +errno: + +- EINVAL:参数错误。 +- EOVERFLOW:字符串溢出。 + +#### popen + +暂不支持。 + +#### putc + +putc()函数将一个字符c写入文件流stream。 + +**参数**: + +1. 文件描述符fd。 +2. 格式化字符串format。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- -1:操作失败。 + +#### fseek + +fseek()函数设置文件流stream的位置。 + +**参数**: + +1. 文件流stream。 +2. 相对偏移量offset。 +3. 开始位置whence。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +#### fgetwc + +fgetwc()函数从文件流stream读取一个宽字符wc。 + +**参数**: + +1. 文件流指针stream。 + +**输出**: + +- 宽字符wc:操作成功。 +- WEOF:操作失败。 + +errno: + +- EILSEQ:转换失败。 + +#### tmpfile + +tmpfile()函数生成一个临时文件流指针。 + +**参数**:无。 + +**输出**: + +- 临时文件流指针:操作成功。 +- NULL:操作失败。 + +#### putw + +putw()函数将一个字符c写入指定的文件流stream。 + +**参数**: + +1. 输出字符c。 +2. 文件流指针stream。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +#### tempnam + +tempnam()函数在指定的目录中可用于创建一个临时文件的文件名。 + +**参数**: + +1. 指定目录dir。 +2. 文件名前缀prefix。 + +**输出**: + +- 临时文件名:操作成功。 +- NULL:操作失败。 + +#### vwprintf + +vwprintf()函数将格式化宽字符串写入到标准输出stdout。 + +**参数**: + +1. 格式化字符串format。 +2. 可变参数。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- -1:操作失败。 + +errno: + +- EINVAL:参数错误。 +- EOVERFLOW:字符串溢出。 + +#### getw + +getw()函数从指定文件流stream读取一个字符c。 + +**参数**: + +1. 文件流stream。 + +**输出**: + +- 读取的字符c:操作成功。 +- EOF:操作失败。 + +#### putchar_unlocked + +putchar_unlocked()函数将一个字符c写入标准输出stdout。 + +**参数**: + +1. 写入字符c。 + +**输出**: + +- 字符c:操作成功。 +- EOF:操作失败。 + +#### fread + +fread()函数从给定文件流stream读取最多count的字符到字符串缓冲区buf。 + +**参数**: + +1. 缓冲区指针buf。 +2. 每个元素大小size。 +3. 元素个数count。 +4. 文件流指针stream。 + +**输出**: + +- 成功匹配字符数:操作成功。 +- 0:操作失败。 + +#### fileno + +fileno()函数返回文件流stream相关的文件描述符。 + +**参数**: + +1. 文件流指针stream。 + +**输出**: + +- 文件描述符:操作成功。 +- -1:操作失败。 + +errno: + +- EBADF:无效的描述符。 + +#### remove + +remove()函数删除给定的文件名filename。 + +**参数**: + +1. 文件名filename。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +#### putc_unlocked + +putc_unlocked()函数将一个字符c写入指定的文件流stream。 + +**参数**: + +1. 写入字符c。 +2. 文件流指针stream。 + +**输出**: + +- 写入字符c:操作成功。 +- EOF:操作失败。 + +#### fclose + +fclose()函数关闭文件流stream。 + +**参数**: + +1. 文件流指针stream。 + +**输出**: + +- 0:操作成功。 +- EOF:操作失败。 + +#### feof + +feof()函数检测文件流的文件结束符。 + +**参数**: + +1. 文件流指针stream。 + +**输出**: + +- 1:文件结束。 +- 0:文件未结束。 + +#### fwrite + +fwrite()函数将指定的字符串str写入文件流stream。 + +**参数**: + +1. 字符串str。 +2. 元素的大小size。 +3. 元素的个数count。 +4. 文件流指针stream。 + +**输出**: + +- 返回成功写入字符数:操作成功。 +- 0:操作失败。 + +#### setbuf + +setbuf()函数打开或关闭缓冲机制。 + +**参数**: + +1. 文件流指针stream。 +2. 缓冲区buf。 + +**输出**:无。 + +#### pclose + +暂不支持。 + +#### swprintf + +swprintf()函数将格式化的数据写入到指定的宽字符串中。 + +**参数**: + +1. 宽字符串缓冲区buf。 +2. 宽字符串大小size。 +3. 格式化字符串format。 +4. 可变参数。 + +**输出**: + +- 成功写入字符数:操作成功。 +- -1:操作失败。 + +errno: + +- EOVERFLOW:字符串溢出。 + +#### fwprintf + +fwprintf()函数将格式化宽字符串写入文件流stream。 + +**参数**: + +1. 文件流stream。 +2. 格式化宽字符串format。 +3. 可变参数。 + +**输出**: + +- 成功写入字符数:操作成功。 +- -1:操作失败。 + +errno: + +- EINVAL:参数错误。 +- EOVERFLOW:字符串溢出。 + +#### swscanf + +swscanf()函数从宽字符串中读取格式化的数据到变量列表中。 + +**参数**: + +1. 宽字符串ws。 +2. 格式化宽字符串format。 +3. 可变参数。 + +**输出**: + +- 成功匹配数:操作成功。 +- -1:操作失败。 + +#### rename + +rename()函数将旧文件名old_filename重命名为新文件名new_filename。 + +**参数**: + +1. 旧文件名old_filename。 +2. 新文件名new_filename。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +errno: + +- EINVAL:参数错误。 + +#### getdelim + +getdelim()函数从文件流中读取字符串,由参数指定的delimiter的进行分隔。 + +**参数**: + +1. 字符串缓冲区buf。 +2. 字符串缓冲区大小指针n。 +3. 分隔符delimiter。 +4. 文件流指针stream。 + +**输出**: + +- 成功写入字符数:操作成功。 +- -1:操作失败。 + +#### vfscanf + +vfscanf()函数从文件流stream读取格式化的数据到变量参数列表中。 + +**参数**: + +1. 文件流指针stream。 +2. 格式化字符串format。 +3. 可变参数。 + +**输出**: + +- 成功匹配数:操作成功。 +- -1:操作失败。 + +#### setlinebuf + +setlinebuf()函数设置文件流stream的行缓冲模式。 + +**参数**: + +1. 文件流指针stream。 + +**输出**:无。 + +#### fputs + +fputs()函数将字符串str写入到指定的文件流stream。 + +**参数**: + +1. 字符串str。 +2. 文件流指针stream。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +#### fsetpos + +fsetpos()函数将文件指针定位在参数pos指定的位置上。 + +**参数**: + +1. 文件流指针stream。 +2. 文件位置pos。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +#### fopencookie + +fopencookie()函数打开一个可以自定义实现的I/O流。 + +**参数**: + +1. 结构体指针cookie。 +2. 访问模式mode。 +3. 自定义I/O流函数。 + +**输出**: + +- 文件流指针:操作成功。 +- NULL:操作失败。 + +#### fgetln + +fgetln()函数从文件流中读取一行数据,并存储在大小为*len的缓冲区中。 + +**参数**: + +1. 文件流指针stream。 +2. 缓冲区长度指针len。 + +**输出**: + +- 字符串指针:操作成功。 +- NULL:操作失败。 + +#### vscanf + +vscanf()函数从标准输入stdin将格式化的数据读入可变参数列表。 + +**参数**: + +1. 格式化字符串format。 +2. 可变参数。 + +**输出**: + +- 成功匹配数:操作成功。 +- -1:操作失败。 + +#### ungetwc + +ungetwc()函数将宽字符ch推回与文件流关联的缓冲区中,除非ch等于WEOF。 + +**参数**: + +1. 宽字符wc。 +2. 文件流指针stream。 + +**输出**: + +- 返回宽字符wc:操作成功。 +- WEOF:操作失败。 + +#### getline + +getline()函数从文件流中读取字符串,由换行符\n的进行分隔。 + +**参数**: + +1. 字符串缓冲区buf。 +2. 字符串缓冲区大小指针n。 +3. 文件流指针stream。 + +**输出**: + +- 成功写入字符数:操作成功。 +- -1:操作失败。 + +#### ftrylockfile + +ftrylockfile()函数尝试进行文件锁定。 + +**参数**: + +1. 文件流指针stream。 + +**输出**: + +- 0:操作成功。 +- -1:操作失败。 + +#### vwscanf + +vwscanf()函数从标准输入stdin中读取格式化的数据到变量参数列表中。 + +**参数**: + +1. 文件流指针stream。 +2. 可变参数。 + +**输出**: + +- 成功匹配数:操作成功。 +- -1:操作失败。 + +## C11接口 + +| 接口名 | 适配情况 | +| :---: | :-----: | +| [cnd_broadcast](#cnd_broadcast) | 支持 | +| [cnd_destroy](#cnd_destroy) | 支持 | +| [cnd_init](#cnd_init) | 支持 | +| [cnd_signal](#cnd_signal) | 支持 | +| [cnd_timedwait](#cnd_timedwait) | 支持 | +| [cnd_wait](#cnd_wait) | 支持 | +| [mtx_destroy](#mtx_destroy) | 支持 | +| [mtx_init](#mtx_init) | 支持 | +| [mtx_lock](#mtx_lock) | 支持 | +| [mtx_timedlock](#mtx_timedlock) | 支持 | +| [mtx_trylock](#mtx_trylock) | 支持 | +| [thrd_create](#thrd_create) | 支持 | +| [thrd_current](#thrd_current) | 支持 | +| [thrd_detach](#thrd_detach) | 支持 | +| [thrd_equal](#thrd_equal) | 支持 | +| [thrd_exit](#thrd_exit) | 支持 | +| [thrd_join](#thrd_join) | 支持 | +| [thrd_sleep](#thrd_sleep) | 支持 | +| [thrd_yield](#thrd_yield) | 支持 | +| [tss_create](#tss_create) | 支持 | +| [tss_delete](#tss_delete) | 支持 | +| [tss_get](#tss_get) | 支持 | +| [tss_set](#tss_set) | 支持 | + +### 条件变量管理 + +#### cnd_init + +初始化条件变量cond。同使用条件变量属性为NULL的pthread_cond_init()。 + +**参数** + +1. 条件变量指针cond。 +2. 条件变量属性指针attr。 + +**输出**: + +- thrd_success:操作成功。 +- thrd_error:操作失败。 + +#### cnd_destroy + +销毁指定条件变量,使得该条件变量未初始化,可以使用cnd_init() 重新初始化。同pthread_cond_destory()。 + +**参数**:条件变量指针cond。 + +**输出**:无。 + +#### cnd_broadcast + +取消阻止当前等待cond所指向的条件变量的所有线程。如果没有线程被阻塞,则不执行任何操作并返回thrd_success。 + +**参数**:条件变量指针cond。 + +**输出**: + +- thrd_success:操作成功。 +- thrd_error:操作失败。 + +#### cnd_signal + +取消阻塞在指定的条件变量cond上阻塞的线程中的至少一个(如果有任何线程在cond上被阻塞)。 + +**参数**:条件变量指针cond。 + +**输出**: + +- thrd_success:操作成功。 +- thrd_error:操作失败。 + +#### cnd_timedwait + +阻塞当前线程等待cond指定的条件变量,并释放互斥体指定的互斥体。只有在另一个线程使用相同的条件变量调用cnd_signal() 或cnd_broadcast() 后,或者如果系统时间达到指定的时间,并且当前线程重新获得互斥锁时,等待线程才会解锁。 + +**参数**: + +1. 条件变量指针cond。 +2. 互斥锁指针m。 +3. 超时时间指针ts。 + +**输出**: + +- thrd_success:操作成功。 +- thrd_error:操作失败。 +- thrd_timedout:阻塞超时 + +#### cnd_wait + +cnd_wait() 函数与cnd_timedwait() 类似,阻塞当前线程等待cond指定的条件变量,并释放互斥体指定的互斥体。只有在另一个线程使用相同的条件变量调用cnd_signal() 或cnd_broadcast() 后,并且当前线程重新获得互斥锁时,等待线程才会解锁。 + +**参数**: + +1. 条件变量指针cond。 +2. 互斥锁指针m。 + +**输出**: + +- thrd_success:操作成功。 +- thrd_error:操作失败。 + +### 互斥锁管理 + +#### mtx_init + +mtx_init()函数根据属性type初始化互斥锁。 + +**参数**: + +1. 互斥锁指针mutex。 +2. 互斥锁属性type。 + +**输出**: + +- thrd_success:操作成功。 +- thrd_error:操作失败。 + +#### mtx_destroy + +mtx_destroy() 用于注销一个互斥锁。销毁一个互斥锁即意味着释放它所占用的资源,且要求锁当前处于开放状态。 + +**参数**:互斥锁指针mutex。 + +**输出**:无。 + +#### mtx_lock + +当pthread_mutex_lock() 返回时,该[互斥锁](https://baike.baidu.com/item/互斥锁/841823?fromModule=lemma_inlink)已被锁定。[线程](https://baike.baidu.com/item/线程/103101?fromModule=lemma_inlink)调用该函数让互斥锁上锁,如果该互斥锁已被另一个线程锁定和拥有,则调用该线程将阻塞,直到该互斥锁变为可用为止。 + +**参数**:互斥锁指针mutex。 + +**输出**: + +- thrd_success:操作成功。 +- thrd_error:操作失败。 + +#### mtx_timedlock + +mtx_timedlock() 语义与mtx_lock() 类似,不同点在于锁已经被占据时增加一个超时时间,等待超时返回错误码。 + +**参数**: + +1. 互斥锁指针mutex。 +2. 超时时间指针ts。 + +**输出**: + +- thrd_success:操作成功。 +- thrd_error:操作失败。 +- thrd_timedout:等待超时。 + +#### mtx_trylock + +mtx_trylock() 语义与 mtx_lock() 类似,不同点在于锁已经被占据时返回 thrd_busy, 而非挂起等待。 + +**参数**:互斥锁指针mutex。 + +**输出**: + +- thrd_success:操作成功。 +- thrd_busy:mutex指定的锁已经被占据。 +- thrd_error:操作失败。 + +### 任务管理 + +#### thrd_create + +thrd_create()函数创建一个执行函数为func的新线程,创建成功后,将创建的线程的ID存储在参数 thread 的位置。 + +**参数**: + +1. 指向线程[标识符](https://baike.baidu.com/item/标识符?fromModule=lemma_inlink)的[指针](https://baike.baidu.com/item/指针?fromModule=lemma_inlink)thread。 +2. 线程处理函数的起始地址 func。 +3. 运行函数的参数 arg。 + +**输出**: + +- thrd_success:创建成功。 +- thrd_error:attr指定的属性无效。 +- thrd_nomem:系统缺少创建新线程所需的资源。 + +#### thrd_current + +返回调用线程的线程ID。 + +**参数**:无 + +**输出**:返回调用线程的线程ID。 + +#### thrd_detach + +实现线程分离,即主线程与子线程分离,子线程结束后,资源自动回收。 + +**参数**:线程ID:thread。 + +**输出**: + +- 0:成功完成。 +- EINVAL:thread是分离线程。 +- ESRCH:给定线程ID指定的线程不存在。 + +#### thrd_equal + +此函数应比较线程ID t1和t2。 + +**参数**: + +1. 线程ID t1。 +2. 线程ID t2。 + +**输出**: + +- 如果t1和t2相等,pthread_equal()函数应返回非零值。 +- 如果t1和t2不相等,应返回零。 +- 如果t1或t2不是有效的线程ID,则行为未定义。 + +#### thrd_exit + +线程的终止可以是调用 thrd_exit 或者该线程的例程结束。由此可看出,一个线程可以隐式退出,也可以显式调用 thrd_exit 函数来退出。thrd_exit 函数唯一的参数 value_ptr 是函数的返回代码,只要 thrd_join 中的第二个参数 value_ptr 不是NULL,这个值将被传递给 value_ptr。 + +**参数**:线程退出状态value_ptr,通常传NULL。 + +**输出**:无 + +#### thrd_join + +thrd_join() 函数,以阻塞的方式等待 thread 指定的线程结束。当函数返回时,被等待线程的资源被收回。如果线程已经结束,那么该函数会立即返回。并且 thread 指定的线程必须是 joinable 的。当 thrd_join()成功返回时,目标线程已终止。对指定同一目标线程的thrd_join()的多个同时调用的结果未定义。如果调用thrd_join()的线程被取消,则目标线程不应被分离。 + +**参数**: + +1. 线程ID:thread。 +2. 退出线程:返回值value_ptr。 + +**输出**: + +- thrd_success:操作成功。 + +#### thrd_sleep + +至少在达到time_point指向的基于TIME_UTC的时间点之前,阻塞当前线程的执行。如果收到未被忽略的信号,睡眠可能会恢复。 + +**参数**: + +1. 应等待时间:req。 +2. 实际等待时间:rem。 + +**输出**: + +- 0:操作成功。 +- -2: 操作失败。 + +#### thrd_yield + +thrd_yield()函数应强制正在运行的线程放弃处理器,并触发线程调度。 + +**参数**:无 + +**输出**:输出0时,成功完成;否则应返回值-1。 + +#### tss_create + +分配用于标识线程特定数据的键。tss_create 第一个参数为指向一个键值的[指针](https://baike.baidu.com/item/指针/2878304?fromModule=lemma_inlink),第二个参数指明了一个 destructor 函数,如果这个参数不为空,那么当每个线程结束时,系统将调用这个函数来释放绑定在这个键上的内存块。 + +**参数**: + +1. 键值的[指针](https://baike.baidu.com/item/指针/2878304?fromModule=lemma_inlink)tss。 +2. destructor 函数入口 destructor。 + +**输出**: + +- thrd_success:操作成功。 +- thrd_error:操作失败。 + +#### tss_delete + +销毁线程特定数据键。 + +**参数**:需要删除的键key。 + +**输出**:无 + +#### tss_get + +将与key关联的数据读出来,返回数据类型为 void *,可以指向任何类型的数据。需要注意的是,在使用此返回的指针时,需满足是 void 类型,虽指向关联的数据地址处,但并不知道指向的数据类型,所以在具体使用时,要对其进行强制类型转换。 + +**参数**:键值key。 + +**输出**: + +- 返回与给定 key 关联的线程特定数据值。 +- NULL:没有线程特定的数据值与键关联。 + +#### tss_set + +tss_set() 函数应将线程特定的 value 与通过先前调用 tss_create()获得的 key 关联起来。不同的线程可能会将不同的值绑定到相同的键上。这些值通常是指向已保留供调用线程使用的动态分配内存块的指针。 + +**参数**: + +1. 键值key。 +2. 指针value + +**输出**: + +- 0:设置成功。 + +## 其他接口 + +| 接口名 | 适配情况 | +| :---: | :-----: | +| [pthread_getattr_default_np](#pthread_getattr_default_np) | 支持 | +| [pthread_getattr_np](#pthread_getattr_np) | 支持 | +| [pthread_getname_np](#pthread_getattr_np) | 支持 | +| [pthread_setattr_default_np](#pthread_setattr_default_np) | 支持 | +| [pthread_setname_np](#pthread_setname_np) | 支持 | +| [pthread_timedjoin_np](#pthread_timedjoin_np) | 支持 | +| [pthread_tryjoin_np](#pthread_tryjoin_np) | 支持 | +| [ftime](#ftime) | 支持 | +| [timegm](#timegm) | 支持 | + +### pthread_getattr_default_np + +pthread_getattr_default_np() 函数初始化attr引用的线程属性对象,使其包含用于创建线程的默认属性。 + +**参数**:线程属性对象attr。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 + +### pthread_setattr_default_np + +pthread_setattr_default_np() 函数用于设置创建新线程的默认属性,即当使用NULL的第二个参数调用pthread_create时使用的属性。 + +**参数**:线程属性对象attr。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 + +### pthread_getattr_np + +pthread_getattr_np() 函数初始化attr引用的线程属性对象,使其包含描述正在运行的线程线程的实际属性值。 + +**参数**: + +1. 线程ID值thread。 +2. 线程属性对象attr。 + +**输出**: + +- 0:操作成功。 +- 非0值:操作失败。 + +### pthread_getname_np + +pthread_getname_np() 函数可用于检索线程的名称。thread参数指定要检索其名称的线程。 + +**参数**: + +1. 线程ID值thread。 +2. 线程名字符串name。 +3. 字符串大小len。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 + +### pthread_setname_np + +pthread_setname_np() 函数可用于设置线程的名称。 + +**参数**: + +1. 线程ID值thread。 +2. 线程名字符串name。 +3. 字符串大小len。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 + +### pthread_timedjoin_np + +类似pthread_join,如果线程尚未终止,则调用将阻塞直到abstime中指定的最大时间。如果超时在线程终止之前到期,则调用将返回错误。 + +**参数**: + +1. 线程ID值thread。 +2. 线程退出状态status。 +3. 阻塞时间指针ts。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 +- ETIMEDOUT:阻塞超时。 + +### pthread_tryjoin_np + +类似pthread_join,但如果线程尚未终止,将立即返回EBUSY。 + +**参数**: + +1. 线程ID值thread。 +2. 线程退出状态status。 + +**输出**: + +- 0:操作成功。 +- EINVAL:指针未初始化。 +- EBUSY:调用时线程尚未终止。 + +### ftime + +取得当前的时间和日期,由一个timeb结构体返回。 + +**参数**: + +1. timeb结构体指针tp。 + +**输出**:无 + +### timegm + +将tm结构体表示的时间转换为自一个标准时间点以来的时间,不受本地时区的影响。 + +**参数**: + +1. tm结构体指针tp。 + +**输出**: + +返回值: + +- time_t结构体表示的时间值。 +- -1: 转换失败。 + +errno: + +- EOVERFLOW:转换溢出。 + +## math数学库 + +| 接口名 | 描述 | 输入参数 | 适配情况 | +| :---: | :-----: | :-----: | :-----: | +| [acos](#acos) | 计算参数x的反余弦值,参数x的取值范围[-1, +1],返回类型double | double类型的浮点数x | 支持 | +| [acosf](#acosf) | 计算参数x的反余弦值,参数x的取值范围[-1, +1],返回类型float | float类型的浮点数x | 支持 | +| [acosl](#acosl) | 计算参数x的反余弦值,参数x的取值范围[-1, +1],返回类型long double | long double类型的浮点数x | 支持 | +| [acosh](#acosh) | 计算参数x的反双曲余弦值,返回类型double | double类型的浮点数x | 支持 | +| [acoshf](#acoshf) | 计算参数x的反双曲余弦值,返回类型float | float类型的浮点数x | 支持 | +| [acoshl](#acoshl) | 计算参数x的反双曲余弦值,返回类型long double | long double类型的浮点数x | 支持 | +| [asin](#asin) | 计算参数x的反正弦值,参数x的取值范围为[-1, +1] | duoble类型的浮点数x | 支持 | +| [asinf](#asinf) | 计算参数x的反正弦值,参数x的取值范围为[-1, +1] | float类型的浮点数x | 支持 | +| [asinl](#asinl) | 计算参数x的反正弦值,参数x的取值范围为[-1, +1] | long double类型的浮点数x | 支持 | +| [asinh](#asinh) | 计算参数x的反双曲正弦值,返回类型double | double类型的浮点数x | 支持 | +| [asinhf](#asinhf) | 计算参数x的反双曲正弦值,返回类型float | float类型的浮点数x | 支持 | +| [asinhl](#asinhl) | 计算参数x的反双曲正弦值,返回类型long double | long double类型的浮点数x | 支持 | +| [atan](#atan) | 计算参数x的反正切值,返回类型double | double类型的浮点数x | 支持 | +| [atanf](#atanf) | 计算参数x的反正切值,返回类型float | float类型的浮点数x | 支持 | +| [atanl](#atanl) | 计算参数x的反正切值,返回类型long double | long double类型的浮点数x | 支持 | +| [atan2](#atan2) | 计算参数y除以x的反正切值,使用两个参数的符号确定返回值的象限 | double类型的浮点数y
double类型的浮点数x | 支持 | +| [atan2f](#atan2f) | 计算参数y除以x的反正切值,使用两个参数的符号确定返回值的象限 | float类型的浮点数y
float类型的浮点数x | 支持 | +| [atan2l](#atan2l) | 计算参数y除以x的反正切值,使用两个参数的符号确定返回值的象限 | long double类型的浮点数y
long double类型的浮点数x | 支持 | +| [atanh](#atanh) | 计算参数x的反双曲正切值,返回类型double | double类型的浮点数x | 支持 | +| [atanhf](#atanhf) | 计算参数x的反双曲正切值,返回类型float | float类型的浮点数x | 支持 | +| [atanhl](#atanhl) | 计算参数x的反双曲正切值,返回类型long double | long double类型的浮点数x | 支持 | +| [cbrt](#cbrt) | 计算参数x的立方根,返回类型double | double类型的浮点数x | 支持 | +| [cbrtf](#cbrtf) | 计算参数x的立方根,返回类型float | float类型的浮点数x | 支持 | +| [cbrtl](#cbrtl) | 计算参数x的立方根,返回类型long double | long double类型的浮点数x | 支持 | +| [ceil](#ceil) | 计算不小于参数x的最小整数值,返回类型double | duoble类型的浮点数x | 支持 | +| [ceilf](#ceilf) | 计算不小于参数x的最小整数值,返回类型float | float类型的浮点数x | 支持 | +| [ceill](#ceill) | 计算不小于参数x的最小整数值,返回类型long double | long duoble类型的浮点数x | 支持 | +| [copysign](#copysign) | 生成一个值,该值具有参数x的大小和参数y的符号 | duoble类型的浮点数x
double类型的浮点数y | 支持 | +| [copysignf](#copysignf) | 生成一个值,该值具有参数x的大小和参数y的符号 | float类型的浮点数x
float类型的浮点数y | 支持 | +| [copysignl](#copysignl) | 生成一个值,该值具有参数x的大小和参数y的符号 | long duoble类型的浮点数x
long double类型的浮点数y | 支持 | +| [cos](#cos) | 计算参数x的余弦值,参数应为弧度值,返回类型double | duoble类型的浮点数x | 支持 | +| [cosf](#cosf) | 计算参数x的余弦值,参数应为弧度值,返回类型float | float类型的浮点数x | 支持 | +| [cosl](#cosl) | 计算参数x的余弦值,参数应为弧度值,返回类型long double | long double类型的浮点数x | 支持 | +| [cosh](#cosh) | 计算参数x的双曲余弦值,返回类型double | double类型的浮点数x | 支持 | +| [coshf](#coshf) | 计算参数x的双曲余弦值,返回类型float | float类型的浮点数x | 支持 | +| [coshl](#coshl) | 计算参数x的双曲余弦值,返回类型long double | long double类型的浮点数x | 支持 | +| [erf](#erf) | 计算参数x的高斯误差函数的值 | double类型的浮点数x | 支持 | +| [erff](#erff) | 计算参数x的高斯误差函数的值 | float类型的浮点数x | 支持 | +| [erfl](#erfl) | 计算参数x的高斯误差函数的值 | long double类型的浮点数x | 支持 | +| [erfc](#erfc) | 计算参数x的高斯误差函数的值 | double类型的浮点数x | 支持 | +| [erfcf](#erfcf) | 计算参数x的互补误差函数的值 | float类型的浮点数x | 支持 | +| [erfcl](#erfcl) | 计算参数x的互补误差函数的值 | long double类型的浮点数x | 支持 | +| [exp](#exp) | 以e为基数的指数,即$e^x$的值,返回类型double | double类型的浮点数x | 支持 | +| [expf](#expf) | 以e为基数的指数,即$e^x$的值,返回类型float | float类型的浮点数x | 支持 | +| [expl](#expl) | 以e为基数的指数,即$e^x$的值,返回类型long double | long double类型的浮点数x | 支持 | +| [exp10](#exp10) | 以10为基数的指数,即$10^x$的值,返回类型double | double类型的浮点数x | 支持 | +| [exp10f](#exp10f) | 以10为基数的指数,即$10^x$的值,返回类型float | float类型的浮点数x | 支持 | +| [exp10l](#exp10l) | 以10为基数的指数,即$10^x$的值,返回类型long double | long double类型的浮点数x | 支持 | +| [exp2](#exp2) | 以2为基数的指数函数,返回类型double | double类型的浮点数x | 支持 | +| [exp2f](#exp2f) | 以2为基数的指数函数,返回类型float | float类型的浮点数x | 支持 | +| [exp2l](#exp2l) | 以2为基数的指数函数,返回类型long double | long double类型的浮点数x | 支持 | +| [expm1](#expm1) | 计算$e^x - 1$的值。如果参数x是个小值,expm1(x)函数的值比表达式$e^x - 1$更准确 | double类型的浮点数x | 支持 | +| [expm1f](#expm1f) | 计算$e^x - 1$的值。如果参数x是个小值,expm1(x)函数的值比表达式$e^x - 1$更准确 | float类型的浮点数x | 支持 | +| [expm1l](#expm1l) | 计算$e^x - 1$的值。如果参数x是个小值,expm1(x)函数的值比表达式$e^x - 1$更准确 | long double类型的浮点数x | 支持 | +| [fabs](#fabs) | 计算参数x的绝对值,返回类型double | double类型的浮点数x | 支持 | +| [fabsf](#fabsf) | 计算参数x的绝对值,返回类型float | float类型的浮点数x | 支持 | +| [fabsl](#fabsl) | 计算参数x的绝对值,返回类型long double | long double类型的浮点数x | 支持 | +| [fdim](#fdim) | 计算参数x和参数y之间的正差值 | double类型的浮点数x
double类型的浮点数y | 支持 | +| [fdimf](#fdimf) | 计算参数x和参数y之间的正差值 | float类型的浮点数x
float类型的浮点数y | 支持 | +| [fdiml](#fdiml) | 计算参数x和参数y之间的正差值 | long double类型的浮点数x
long double类型的浮点数y | 支持 | +| [finite](#finite) | 如果参数x既不是无限值也不是NaN,则返回一个非零值,否则返回0 | double类型的浮点数x | 支持 | +| [finitef](#finitef) | 如果参数x既不是无限值也不是NaN,则返回一个非零值,否则返回0 | float类型的浮点数x| 支持 | +| [floor](#floor) | 计算不大于参数x到最大整数值,返回类型double | double类型的浮点数x | 支持 | +| [floorf](#floorf) | 计算不大于参数x到最大整数值,返回类型float | float类型的浮点数x | 支持 | +| [floorl](#floorl) | 计算不大于参数x到最大整数值,返回类型long double | long double类型的浮点数x | 支持 | +| [fma](#fma) | 计算表达式$(x * y) + z$的值,返回double类型 | double类型的浮点数x
double类型的浮点数y
double类型的浮点数z | 支持 | +| [fmaf](#fmaf) | 计算表达式$(x * y) + z$的值,返回float类型 | float类型的浮点数x
float类型的浮点数y
float类型的浮点数z | 支持 | +| [fmal](#fmal) | 计算表达式$(x * y) + z$的值,返回long double类型 | long double类型的浮点数x
long double类型的浮点数y
long double类型的浮点数z | 支持 | +| [fmax](#fmax) | 确定其参数的最大数值。如果一个参数是非数值(NaN),另一个参数是数值,fmax函数将选择数值 | double类型的浮点数x
double类型的浮点数y | 支持 | +| [fmaxf](#fmaxf) | 确定其参数的最大数值。如果一个参数是非数值(NaN),另一个参数是数值,fmax函数将选择数值 | float类型的浮点数x
float类型的浮点数y | 支持 | +| [fmaxl](#fmaxl) | 确定其参数的最大数值。如果一个参数是非数值(NaN),另一个参数是数值,fmax函数将选择数值 | long double类型的浮点数x
long double类型的浮点数y | 支持 | +| [fmin](#fmin) | 返回其参数的最小数值。非数值NaN参数视为缺失数据。如果一个参数是非数值,另一个参数是数值,fmin函数将选择数值 | double类型的浮点数x
double类型的浮点数y | 支持 | +| [fminf](#fminf) | 返回其参数的最小数值。非数值NaN参数视为缺失数据。如果一个参数是非数值,另一个参数是数值,fmin函数将选择数值 | float类型的浮点数x
float类型的浮点数y | 支持 | +| [fminl](#fminl) | 返回其参数的最小数值。非数值NaN参数视为缺失数据。如果一个参数是非数值,另一个参数是数值,fmin函数将选择数值 | long double类型的浮点数x
long double类型的浮点数y | 支持 | +| [fmod](#fmod) | 计算表达式x/y的浮点余数,返回double类型 | double类型的浮点数x
double类型的浮点数y | 支持 | +| [fmodf](#fmodf) | 计算表达式x/y的浮点余数,返回float类型 | float类型的浮点数x
float类型的浮点数y | 支持 | +| [fmodl](#fmodl) | 计算表达式x/y的浮点余数,返回long double类型 | long double类型的浮点数x
long double类型的浮点数y | 支持 | +| [frexp](#frexp) | 将浮点数分解为规格化小数和2的整数幂,并将整数存入参数exp指向的对象中 | double类型的浮点数x
int *类型的浮点数y | 支持 | +| [frexpf](#frexpf) | 将浮点数分解为规格化小数和2的整数幂,并将整数存入参数exp指向的对象中 | float类型的浮点数x
int *类型的浮点数y | 支持 | +| [frexpl](#frexpl) | 将浮点数分解为规格化小数和2的整数幂,并将整数存入参数exp指向的对象中 | long double类型的浮点数x
int *类型的浮点数y | 支持 | +| [hypot](#hypot) | 计算表达式$(x^2 + y^2)^{1/2}$的值 | double类型的浮点数x
double类型的浮点数y | 支持 | +| [hypotf](#hypotf) | 计算表达式$(x^2 + y^2)^{1/2}$的值 | float类型的浮点数x
float类型的浮点数y | 支持 | +| [hypotl](#hypotl) | 计算表达式$(x^2 + y^2)^{1/2}$的值 | long double类型的浮点数x
long double类型的浮点数y | 支持 | +| [ilogb](#ilogb) | 以FLT_RADIX作为对数的底数,返回double类型x的对数的整数部分 | double类型的浮点数x | 支持 | +| [ilogbf](#ilogbf) | 以FLT_RADIX作为对数的底数,返回float类型x的对数的整数部分 | float类型的浮点数x | 支持 | +| [ilogbl](#ilogbl) | 以FLT_RADIX作为对数的底数,返回long double类型x的对数的整数部分 | long double类型的浮点数x | 支持 | +| [j0](#j0) | 计算参数x的第一类0阶贝塞尔函数 | double类型浮点数x | 支持 | +| [j0f](#j0f) | 计算参数x的第一类0阶贝塞尔函数 | float类型浮点数x | 支持 | +| [j1](#j1) | 计算参数x的第一类1阶贝塞尔函数 | double类型浮点数x | 支持 | +| [j1f](#j1f) | 计算参数x的第一类1阶贝塞尔函数 | float类型浮点数x | 支持 | +| [jn](#jn) | 计算参数x的第一类n阶贝塞尔函数 | int类型阶数
double类型浮点数x | 支持 | +| [jnf](#jnf) | 计算参数x的第一类n阶贝塞尔函数 | int类型阶数
float类型浮点数x | 支持 | +| [ldexp](#ldexp) | 计算参数x与2的exp次幂的乘积,即返回$x * 2^{exp}$的double类型值。 | double类型的浮点数x
int类型的指数exp | 支持 | +| [ldexpf](#ldexpf) | 计算参数x与2的exp次幂的乘积,即返回$x * 2^{exp}$的float类型值。 | float类型的浮点数x
int类型的指数exp | 支持 | +| [ldexpl](#ldexpl) | 计算参数x与2的exp次幂的乘积,即返回$x * 2^{exp}$的long double类型值。 | long double类型的浮点数x
int类型的指数exp | 支持 | +| [lgamma](#lgamma) | 计算参数x伽玛绝对值的自然对数,返回double类型 | double类型的浮点数x | 支持 | +| [lgammaf](#lgammaf) | 计算参数x伽玛绝对值的自然对数,返回float类型 | float类型的浮点数x | 支持 | +| [lgammal](#lgammal) | 计算参数x伽玛绝对值的自然对数,返回long double类型 | long double类型的浮点数x | 支持 | +| [lgamma_r](#lgamma_r) | 计算参数x伽玛绝对值的自然对数,与lgamma不同在于是线程安全的 | double类型的浮点数x
int *类型符号参数 | 支持 | +| [lgamma_r](#lgamma_r) | 计算参数x伽玛绝对值的自然对数,与lgamma不同在于是线程安全的 | float类型的浮点数x
int *类型符号参数 | 支持 | +| [llrint](#llrint) | 根据当前舍入模式,将参数舍入为long long int类型的最接近整数值 | double类型的浮点数x | 支持 | +| [llrintf](#llrintf) | 根据当前舍入模式,将参数舍入为long long int类型的最接近整数值 | float类型的浮点数x | 支持 | +| [llrintl](#llrintl) | 根据当前舍入模式,将参数舍入为long long int类型的最接近整数值 | long double类型的浮点数x | 支持 | +| [llround](#llround) | 将double类型x舍入为浮点形式表示的long long int型最近整数值。如果x位于两个整数中心,将向远离0的方向舍入。 | double类型的浮点数x | 支持 | +| [llroundf](#llroundf) | 将float类型x舍入为浮点形式表示的long long int型最近整数值。如果x位于两个整数中心,将向远离0的方向舍入。 | float类型的浮点数x | 支持 | +| [llroundl](#llroundl) | 将long double类型x舍入为浮点形式表示的long long int型最近整数值。如果x位于两个整数中心,将向远离0的方向舍入。 | long double类型的浮点数x | 支持 | +| [log](#log) | double类型x的自然对数函数 | double类型的浮点数x | 支持 | +| [logf](#logf) | float类型x的自然对数函数 | float类型的浮点数x | 支持 | +| [logl](#logl) | long double类型x的自然对数函数 | long double类型的浮点数x | 支持 | +| [log10](#log10) | double类型x以10为底数的对数函数 | double类型的浮点数x | 支持 | +| [log10f](#log10f) | float类型x以10为底数的对数函数 | float类型的浮点数x | 支持 | +| [log10l](#log10l) | long double类型x以10为底数的对数函数 | long double类型的浮点数x | 支持 | +| [log1p](#log1p) | 以e为底数的对数函数,计算$log_e(1 + x)$的值。如果参数x是个小值,表达式log1p(x)比表达式log(1 + x)更准确 | double类型的浮点数x | 支持 | +| [log1pf](#log1pf) | 以e为底数的对数函数,计算$log_e(1 + x)$的值。如果参数x是个小值,表达式log1p(x)比表达式log(1 + x)更准确 | float类型的浮点数x | 支持 | +| [log1pl](#log1pl) | 以e为底数的对数函数,计算$log_e(1 + x)$的值。如果参数x是个小值,表达式log1p(x)比表达式log(1 + x)更准确 | long double类型的浮点数x | 支持 | +| [log2](#log2) | double类型x以2为底数的对数函数 | double类型的浮点数x | 支持 | +| [log2f](#log2f) | float类型x以2为底数的对数函数 | flaot类型的浮点数x | 支持 | +| [log2l](#log2l) | long double类型x以2为底数的对数函数 | long double类型的浮点数x | 支持 | +| [logb](#logb) | double类型x以FLT_RADIX为的底数到对数函数 | double类型的浮点数x | 支持 | +| [logbf](#logbf) | float类型x以FLT_RADIX为的底数到对数函数 | float类型的浮点数x | 支持 | +| [logbl](#logbl) | double类型x以FLT_RADIX为的底数到对数函数 | double类型的浮点数x | 支持 | +| [lrint](#lrint) | 根据当前舍入模式,将参数舍入为long int类型的最接近整数值 | double类型的浮点数x | 支持 | +| [lrintf](#lrintf) | 根据当前舍入模式,将参数舍入为long int类型的最接近整数值 | float类型的浮点数x | 支持 | +| [lrintl](#lrintl) | 根据当前舍入模式,将参数舍入为long int类型的最接近整数值 | long double类型的浮点数x | 支持 | +| [lround](#lround) | 将double类型x舍入为浮点形式表示的long int型最近整数值。如果x位于两个整数中心,将向远离0的方向舍入。 | double类型的浮点数x | 支持 | +| [lroundf](#lroundf) | 将float类型x舍入为浮点形式表示的long int型最近整数值。如果x位于两个整数中心,将向远离0的方向舍入。 | float类型的浮点数x | 支持 | +| [lroundl](#lroundl) | 将long double类型x舍入为浮点形式表示的long int型最近整数值。如果x位于两个整数中心,将向远离0的方向舍入。 | long double类型的浮点数x | 支持 | +| [modf](#modf) | 将double类型的参数value分成整数部分和小数部分,两部分与参数value具有相同的类型和符号。整数部分以浮点形式存入参数iptr指向的对象中 | double类型的浮点数value
double *类型的指数iptr | 支持 | +| [modff](#modff) | 将float类型的参数value分成整数部分和小数部分,两部分与参数value具有相同的类型和符号。整数部分以浮点形式存入参数iptr指向的对象中 | float类型的浮点数value
float *类型的指数iptr | 支持 | +| [modfl](#modfl) | 将long double类型的参数value分成整数部分和小数部分,两部分与参数value具有相同的类型和符号。整数部分以浮点形式存入参数iptr指向的对象中 | long double类型的浮点数value
long double *类型的指数iptr | 支持 | +| [nan](#nan) | 返回一个double类型的非数值NaN,内容由参数tagp确定 | const char*类型tagp | 支持 | +| [nanf](#nanf) | 返回一个float类型的非数值NaN,内容由参数tagp确定 | const char*类型tagp | 支持 | +| [nanl](#nanl) | 返回一个long double类型的非数值NaN,内容由参数tagp确定 | const char*类型tagp | 支持 | +| [nearbyint](#nearbyint) | 根据当前舍入模式,将double型参数x舍入为浮点格式的double型整数值 | double类型x | 支持 | +| [nearbyintf](#nearbyintf) | 根据当前舍入模式,将float型参数x舍入为浮点格式的float型整数值 | float类型x | 支持 | +| [nearbyintl](#nearbyintl) | 根据当前舍入模式,将long double型参数x舍入为浮点格式的double型整数值 | long double类型x | 支持 | +| [nextafter](#nextafter) | 返回double类型参数x沿参数y方向的下一个可表示值 | double类型x
double类型y | 支持 | +| [nextafterf](#nextafterf) | 返回double类型参数x沿参数y方向的下一个可表示值 | float类型x
flaot类型y | 支持 | +| [nextafterl](#nextafterl) | 返回double类型参数x沿参数y方向的下一个可表示值 | long double类型x
long double类型y | 支持 | +| [nexttoward](#nexttoward) | 返回double类型参数x沿参数y方向的下一个可表示值,等价于nextafter,区别在于参数y为long double | double类型浮点数x
long double类型浮点数y | 支持 | +| [nexttowardf](#nexttowardf) | 返回double类型参数x沿参数y方向的下一个可表示值,等价于nextafter,区别在于参数y为long double | float类型浮点数x
long double类型浮点数y | 支持 | +| [nexttowardl](#nexttowardl) | 返回double类型参数x沿参数y方向的下一个可表示值,等价于nextafter,区别在于参数y为long double | long double类型浮点数x
long double类型浮点数y | 支持 | +| [pow](#pow) | 计算表达式$x^y$的值 | double类型浮点数x
double类型浮点数y | 支持 | +| [powf](#powf) | 计算表达式$x^y$的值 | float类型浮点数x
float类型浮点数y | 支持 | +| [powl](#powl) | 计算表达式$x^y$的值 | long double类型浮点数x
long double类型浮点数y | 支持 | +| [pow10](#pow10) | 计算表达式$10^x$的值 | double类型浮点数x | 支持 | +| [pow10f](#pow10f) | 计算表达式$10^x$的值 | float类型浮点数x| 支持 | +| [pow10l](#pow10l) | 计算表达式$10^x$的值 | long double类型浮点数x | 支持 | +| [remainder](#remainder) | 计算参数x除以y的余数,等同于drem | double类型浮点数x
double类型浮点数y | 支持 | +| [remainderf](#remainderf) | 计算参数x除以y的余数,等同于dremf | float类型浮点数x
float类型浮点数y | 支持 | +| [remainderl](#remainderl) | 计算参数x除以y的余数 | long double类型浮点数x
long double类型浮点数y | 支持 | +| [remquo](#remquo) | 计算参数x和参数y的浮点余数,并将商保存在传递的参数指针quo中 | double类型浮点数x
double类型浮点数y
int *类型商que | 支持 | +| [remquof](#remquof) | 计算参数x和参数y的浮点余数,并将商保存在传递的参数指针quo中 | float类型浮点数x
float类型浮点数y
int *类型商que | 支持 | +| [remquol](#remquol) | 计算参数x和参数y的浮点余数,并将商保存在传递的参数指针quo中 | long double类型浮点数x
long double类型浮点数y
int *类型商que | 支持 | +| [rint](#rint) | 根据当前舍入模式,将参数x舍入为浮点个数的整数值 | double类型的浮点数x | 支持 | +| [rintf](#rintf) | 根据当前舍入模式,将参数x舍入为浮点个数的整数值 | float类型的浮点数x | 支持 | +| [rintl](#rintl) | 根据当前舍入模式,将参数x舍入为浮点个数的整数值 | long double类型的浮点数x | 支持 | +| [round](#round) | 将double类型x舍入为浮点形式表示的double型最近整数值。如果x位于两个整数中心,将向远离0的方向舍入。 | double类型的浮点数x | 支持 | +| [roundf](#roundf) | 将float类型x舍入为浮点形式表示的float型最近整数值。如果x位于两个整数中心,将向远离0的方向舍入。 | float类型的浮点数x | 支持 | +| [roundl](#roundl) | 将long double类型x舍入为浮点形式表示的long double型最近整数值。如果x位于两个整数中心,将向远离0的方向舍入。 | long double类型的浮点数x | 支持 | +| [scalb](#scalb) | 计算$x * FLT\_RADIX^{exp}$的double类型值 | double类型的浮点数x
double类型的指数exp | 支持 | +| [scalbf](#scalbf) | 计算$x * FLT\_RADIX^{exp}$的float类型值 | float类型的浮点数x
float类型的指数exp | 支持 | +| [scalbln](#scalbln) | 计算$x * FLT\_RADIX^{exp}$的double类型值 | double类型的浮点数x
long类型的指数exp | 支持 | +| [scalblnf](#scalblnf) | 计算$x * FLT\_RADIX^{exp}$的float类型值 | float类型的浮点数x
long类型的指数exp | 支持 | +| [scalblnl](#scalblnl) | 计算$x * FLT\_RADIX^{exp}$的long double类型值 | long double类型的浮点数x
long类型的指数exp | 支持 | +| [scalbn](#scalbn) | 计算$x * FLT\_RADIX^{exp}$的double类型值 | double类型的浮点数x
int类型的指数exp | 支持 | +| [scalbnf](#scalbnf) | 计算$x * FLT\_RADIX^{exp}$的float类型值 | float类型的浮点数x
int类型的指数exp | 支持 | +| [scalbnl](#scalbnl) | 计算$x * FLT\_RADIX^{exp}$的long double类型值 | long double类型的浮点数x
int类型的指数exp | 支持 | +| [significand](#significand) | 用于分离浮点数x的尾数部分,返回double类型 | double类型的浮点数x | 支持 | +| [significandf](#significandf) | 用于分离浮点数x的尾数部分,返回double类型 | double类型的浮点数x | 支持 | +| [sin](#sin) | 计算参数x的正弦值,参数应为弧度值,返回double类型 | double类型的浮点数x | 支持 | +| [sinf](#sinf) | 计算参数x的正弦值,参数应为弧度值,返回float类型 | float类型的浮点数x | 支持 | +| [sinl](#sinl) | 计算参数x的正弦值,参数应为弧度值,返回long double类型 | long double类型的浮点数x | 支持 | +| [sincos](#sincos) | 同时计算参数x的正弦值和余弦值,并将结果存储在*sin和*cos,比单独调用sin和cos效率更高 | double类型的浮点数x
double*类型的浮点数sin
double*类型的浮点数cos | 支持 | +| [sincosf](#sincosf) | 同时计算参数x的正弦值和余弦值,并将结果存储在*sin和*cos,比单独调用sin和cos效率更高 | float类型的浮点数x
float*类型的浮点数sin
float*类型的浮点数cos | 支持 | +| [sincosl](#sincosl) | 同时计算参数x的正弦值和余弦值,并将结果存储在*sin和*cos,比单独调用sin和cos效率更高 | long double类型的浮点数x
long double*类型的浮点数sin
long double*类型的浮点数cos | 支持 | +| [sinh](#sinh) | 计算参数x的双曲正弦值,返回double类型 | double类型的浮点数x | 支持 | +| [sinhf](#sinhf) | 计算参数x的双曲正弦值,返回float类型 | float类型的浮点数x | 支持 | +| [sinhl](#sinhl) | 计算参数x的双曲正弦值,返回long double类型 | long double类型的浮点数x | 支持 | +| [sqrt](#sqrt) | 计算参数x的平方根,返回类型double | double类型的浮点数x | 支持 | +| [sqrtf](#sqrtf) | 计算参数x的平方根,返回类型float | float类型的浮点数x | 支持 | +| [sqrtl](#sqrtl) | 计算参数x的平方根,返回类型long double | long double类型的浮点数x | 支持 | +| [tan](#tan) | 计算参数x的正切值,参数应为弧度值,返回double类型 | double类型的浮点数x | 支持 | +| [tanf](#tanf) | 计算参数x的正切值,参数应为弧度值,返回float类型 | float类型的浮点数x | 支持 | +| [tanl](#tanl) | 计算参数x的正切值,参数应为弧度值,返回long double类型 | long double类型的浮点数x | 支持 | +| [tanh](#tanh) | 计算参数x的双曲正切值,返回double类型 | double类型的浮点数x | 支持 | +| [tanhf](#tanhf) | 计算参数x的双曲正切值,返回float类型 | float类型的浮点数x | 支持 | +| [tanhl](#tanhl) | 计算参数x的双曲正切值,返回long double类型 | long double类型的浮点数x | 支持 | +| [tgamma](#tgamma) | 计算参数x的伽马函数,返回double类型 | double类型的浮点数x | 支持 | +| [tgammaf](#tgammaf) | 计算参数x的伽马函数,返回float类型 | float类型的浮点数x | 支持 | +| [tgammal](#tgammal) | 计算参数x的伽马函数,返回long double类型 | long double类型的浮点数x | 支持 | +| [trunc](#trunc) | 截取参数x的整数部分,并将整数部分以浮点形式表示 | double类型的浮点数x | 支持 | +| [truncf](#truncf) | 截取参数x的整数部分,并将整数部分以浮点形式表示 | float类型的浮点数x | 支持 | +| [truncl](#truncl) | 截取参数x的整数部分,并将整数部分以浮点形式表示 | long double类型的浮点数x | 支持 | +| [y0](#y0) | 计算参数x的第二类0阶贝塞尔函数 | double类型的浮点数x | 支持 | +| [y0f](#y0f) | 计算参数x的第二类0阶贝塞尔函数 | float类型的浮点数x | 支持 | +| [y1](#y1) | 计算参数x的第二类1阶贝塞尔函数 | double类型的浮点数x | 支持 | +| [y1f](#y1f) | 计算参数x的第二类1阶贝塞尔函数 | float类型的浮点数x | 支持 | +| [yn](#yn) | 计算参数x的第二类n阶贝塞尔函数 | int类型阶数n
double类型的浮点数x | 支持 | +| [ynf](#ynf) | 计算参数x的第二类n阶贝塞尔函数 | int类型阶数n
float类型的浮点数x | 支持 | + +## 设备驱动 + +### register_driver + +在文件系统中注册一个字符设备驱动程序。 + +**参数**: + +1. 要创建的索引节点的路径path。 +2. file_operations结构体指针fops。 +3. 访问权限mode。 +4. 将与inode关联的私有用户数据priv。 + +**输出**: + +- 0:操作成功。 +- 负数值:操作失败。 + +#### unregister_driver + +从文件系统中删除“path”处的字符驱动程序。 + +**参数**: + +1. 要删除的索引节点的路径path。 + +**输出**: + +- 0:操作成功。 +- -EINVAL:无效的path路径。 +- -EEXIST:path中已存在inode。 +- -ENOMEM:内存不足。 + +#### register_blockdriver + +在文件系统中注册一个块设备驱动程序。 + +**参数**: + +1. 要创建的索引节点的路径path。 +2. block_operations结构体指针bops。 +3. 访问权限mode。 +4. 将与inode关联的私有用户数据priv。 + +**输出**: + +- 0:操作成功。 +- -EINVAL:无效的path路径。 +- -EEXIST:path中已存在inode。 +- -ENOMEM:内存不足。 + +#### unregister_blockdriver + +从文件系统中删除“path”处的块设备驱动程序。 + +**参数**: + +1. 要删除的索引节点的路径path。 + +**输出**: + +- 0:操作成功。 +- -EINVAL:无效的path路径。 +- -EEXIST:path中已存在inode。 +- -ENOMEM:内存不足。 + +## Shell模块 + +### SHELLCMD_ENTRY + +向Shell模块静态注册命令。 + +**参数**: + +1. 命令变量名name。 +2. 命令类型cmdType。 +3. 命令关键字cmdKey。 +4. 处理函数的入参最大个数paraNum。 +5. 命令处理函数回调cmdHook。 + +**输出**:无 + +### osCmdReg + +向Shell模块动态注册命令。 + +**参数**: + +1. 命令类型cmdType。 +2. 命令关键字cmdKey。 +3. 处理函数的入参最大个数paraNum。 +4. 命令处理函数回调cmdHook。 + +**输出**: + +- 0:操作成功。 +- OS_ERRNO_SHELL_NOT_INIT:shell模块未初始化。 +- OS_ERRNO_SHELL_CMDREG_PARA_ERROR:无效的输入参数。 +- OS_ERRNO_SHELL_CMDREG_CMD_ERROR:无效的字符串关键字。 +- OS_ERRNO_SHELL_CMDREG_CMD_EXIST:关键字已存在。 +- OS_ERRNO_SHELL_CMDREG_MEMALLOC_ERROR:内存不足。 diff --git a/docs/en/25.03/Embedded/UniProton/UniProton-functions.md b/docs/en/25.03/Embedded/UniProton/UniProton-functions.md new file mode 100644 index 0000000000000000000000000000000000000000..29349da52cfd8d8d9f3959cfccd4fb83dbbfd6f0 --- /dev/null +++ b/docs/en/25.03/Embedded/UniProton/UniProton-functions.md @@ -0,0 +1,195 @@ +# UniProton功能设计 + + + +- [UniProton功能设计](#uniproton功能设计) + + - [支持任务管理](#支持任务管理) + + - [支持事件管理](#支持事件管理) + + - [支持队列管理](#支持队列管理) + + - [支持硬中断管理](#支持硬中断管理) + + - [支持内存管理](#支持内存管理) + + [FSC内存算法](#fsc内存算法) + + [核心思想](#核心思想) + + [内存申请](#内存申请) + + [内存释放](#内存释放) + + - [支持定时器管理](#支持定时器管理) + + - [支持信号量管理](#支持信号量管理) + + - [支持异常管理](#支持异常管理) + + - [支持CPU占用率统计](#支持cpu占用率统计) + + - [支持STM32F407ZGT6开发板](#支持stm32f407zgt6开发板) + + - [支持OpenAMP混合部署](#支持openamp混合部署) + + - [支持POSIX标准接口](#支持posix标准接口) + + + +## 支持任务管理 + +UniProton是一个单进程支持多线程的操作系统。在UniProton中,一个任务表示一个线程。UniProton中的任务为抢占式调度机制,而非时间片轮转调度方式。高优先级的任务可打断低优先级任务,低优先级任务必须在高优先级任务挂起或阻塞后才能得到调度。 + +UniProton的任务一共有32个优先级(0-31),最高优先级为0,最低优先级为31。每个优先级可以创建多个任务。 + +UniProton任务管理模块提供任务创建、任务删除、任务挂起、任务恢复、任务延时、锁任务调度、解锁任务调度、当前任务ID获取、任务私有数据获取与设置、查询指定任务正在Pending的信号量ID、查询指定任务状态、上下文信息、任务通用信息、任务优先级设定与获取、调整指定优先级的任务调度顺序、注册及取消任务创建钩子、任务删除钩子、任务切换钩子等功能。UniProton在初始化阶段,默认会创建一个最低优先级的IDLE任务,用户在没有处于运行态的任务时,IDLE任务被运行。 + +## 支持事件管理 + +事件机制可以实现线程之间的通讯。事件通讯只能是事件类型的通讯,无数据传输。 + +UniProton事件作为任务的扩展,实现任务之间的通讯。每个任务支持32种类型事件(32个 bit位,每bit代表一种事件类型)。 + +UniProton提供读取本任务事件和写指定任务事件的功能。读事件时可以同时读取多种事件,也可以只读取一种事件,写事件时也可以同时写一种或多种类型事件。 + +## 支持队列管理 + +队列(Queue),又称消息队列,是线程间实现通信的一种方式,实现了数据的存储和传递功能。根据优先级可以将数据写入到队列头或队列尾,但只能从队列的头处读取数据。 + +UniProton创建队列时,根据用户传入队列长度和消息单元大小来开辟相应的内存空间以供该队列使用。在队列控制块中维护一个头指针Head和一个尾指针Tail来表示当前队列中数据存储情况。头指针Head表示队列中被占用消息的起始地址,尾指针Tail表示队列中空闲消息的起始地址。 + +## 支持硬中断管理 + +硬中断是由硬件触发的会改变系统运行轨迹的一个电平信号,硬中断用于通知CPU某个硬件事件的发生。硬中断一般分为可屏蔽中断和不可屏蔽中断(NMI)两种。 + +硬中断的优先级高于所有任务,其内部也有不同的优先级,当同时有多个硬中断被触发时,最高优先级的硬中断总是优先得到响应。高优先级硬中断是否能打断正在执行的低优先级硬中断(即中断嵌套),视不同芯片平台而异。 + +出于任务延时、软件定时器等需要,OS会在初始化阶段,创建1个Tick硬中断,其实质是一个周期性的硬件定时器。 + +## 支持内存管理 + +内存管理主要工作是动态的划分并管理用户分配好的大片内存区间。当程序某一部分需要使用内存,可以通过操作系统的内存申请函数索取指定大小内存块,一旦使用完毕,通过内存释放函数归还所占用内存,使之可以重复使用。 + +目前UniProton提供了FSC内存算法,该算法优缺点及应用场景如下表所示: + +| 内存算法 | 优点 | 缺点 | 应用场景 | +| :----------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------ | ------------------------------------ | +| 类型私有FSC算法 | 内存控制块信息占用内存较少,支持最小4字节对齐的内存块大小申请;支持相邻内存块的快速分割合并,无内存碎片。 | 内存申请和内存释放的效率较低。 | 能够灵活适应各种产品的场景。 | + +如下简要描述一下FSC内存算法: + +### FSC内存算法 + +#### 核心思想 + +对于申请的内存大小为uwSize,如果用二进制,则表示为0b{0}1xxx,{0}表示1前面可能有0个或多个零。无论1后面xxx为何内容,如果将1变成10,xxx则全部变成0,则总会出现10yyy > 1xxx(此处yyy表示xxx的对应位全部变成0)。 + +我们可以直接得到最左边的1的下标。下标值或者从高位到低位依次为0-31(BitMap),或者从低位到高位依次为0-31(uwSize)。如果32位寄存器从高位到低位的bit位的下标依次为0-31,则0x80004000的最左边1的下标为0。于是我们可以维护一个空闲链表头数组(元素数不超过31),以内存块大小最左边的1的下标做为链表头的数组索引,即将所有最左边的1的下标相同的内存块挂接在同一个空闲链表中。 + +如:索引为2的链表可挂接的空闲块大小为4、5、6、7;索引为N的链表可挂接的空闲块大小为2^N到2^(N+1)-1。 + +![](./figures/FCS.png) + +#### 内存申请 + +当申请uwSize大小的内存时,首先利用汇编指令得到最左边的1的下标,假定为n。为确保空闲链表中的第一个空闲内存块满足uwSize,从索引为n+1开始搜索。若n+1所属空闲链表不为空,则取该链表中的第一个空闲块。若n+1链表为空,则判断n+2链表,依次类推,直到找到非空链表或索引达到31。 + +为避免for循环逐级判断空闲链表是否为空,定义一个32位的BitMap全局变量。若索引n的空闲链表非空,则BitMap的下标为n的位置1,否则清0。BitMap的下标为31的位在初始化时直接置1。于是查找从n+1开始的第一个非空闲链表,可以首先将BitMap复本的0到n位清零,然后获取复本的最左边的1的下标,若不等于31,即为第一个空闲链表非空的数组索引。 + +所有的空闲块都以双向链表的形式,串接在空闲链表中。若从链表中获取的第一个空闲块比较大,即分割出一个uwSize的内存块后,剩下的空间至少可做一次最小分配,则将剩余的空闲块调整到对应的空闲链表中。 + + ![](./figures/MemoryApplication.png) + +内存控制头中记录空闲内存块的大小(包括控制头本身)。内存控制头中有一个复用成员,位于最首部。当内存块空闲时,作为指向后一个空闲内存块的指针;当内存块占用时,存放魔术字,表示该内存块非空闲。为避免魔术字与指针冲突(与地址值相同),高低4位均为0xf。因为已分配的内存块起始地址需按4字节对齐,所以不存在冲突。 + +#### 内存释放 + +当释放内存时,需要将前后相邻的空闲块进行合并。首先,通过判断控制头中的魔术字,确认地址参数(pAddr)的合法性。通过首地址加偏移值的方式,得到后邻的内存块控制头的起始地址。若后邻内存块是空闲的,则将后邻内存块从所属空闲链表中删除,调整当前内存块的大小。 + +为了使内存释放时能迅速找到前邻的内存块控制头,及判断前邻的内存块是否空闲。内存控制头中增加一个成员,标记前邻的内存块是否空闲。可在内存申请时,将后邻的该标记设置为占用态(若空闲内存块被分割成两块,前一块为空闲,将当前内存块的该标记设置为空闲态);在内存释放时,将后邻的该标记设置为空闲态。释放当前内存时,若前邻的内存块标记为使用,则不需要合并前邻的内存块;若前邻的内存块标记为空闲,则需要进行合并。若某个内存块为空闲时,则将其后邻控制块的标记设为到本控制块的距离值。 + + ![](./figures/MemoryRelease.png) + +## 支持定时器管理 + +定时器管理是为满足产品定时业务需要,UniProton提供了软件定时器功能。 + +对于软件定时器,是基于Tick实现,所以定时周期必须为Tick的整数倍,在Tick处理函数中进行软件定时器的超时扫描。 + +目前提供的软件定时器接口,可以完成定时器创建,启动,停止,重启,删除操作。 + +## 支持信号量管理 + +信号量(Semaphore)常用于协助一组互相竞争的任务来访问临界资源,在需要互斥的场合作为临界资源计数使用,根据临界资源使用场景分为核内信号量和核间信号量。 + +信号量对象有一个内部计数器,它支持如下两种操作: + +- 申请(Pend):Pend 操作等待指定的信号量,若其计数器值大于0,则直接减1返回成功。否则任务阻塞,等待其他线程发布该信号量,等待的容忍时间可设定。 + +- 释放(Post):Post操作发布指定的信号量,若无任务等待该信号量,则直接将计数器加1返回。否则唤醒为此信号量挂起的任务列表中的第一个任务(最早阻塞的)。 + +通常一个信号量的计数值用于对应有效的资源数,表示剩余可被占用的互斥资源数。其值的含义如下有两种情况: + +- 为0值:表示没有积累下来的Post操作,且有可能有在此信号量上阻塞的任务。 + +- 为正值:表示有一个或多个Post下来的发布操作。 + +## 支持异常管理 + +UniProton中的异常接管属于维测特性,其主要目的是在系统出现异常后,记录尽可能多的异常现场信息,便于后续问题定位。同时提供异常时的钩子函数,便于用户能够在异常发生时做一些用户化的特殊处理。其主要功能是接管内部异常处理或者外部硬件异常。 + +## 支持CPU占用率统计 + +UniProton中的系统CPU占用率(CPU Percent)是指周期时间内系统的CPU占用率,用于表示系统一段时间内的闲忙程度,也表示CPU的负载情况。系统CPU占用率的有效表示范围为0~10000,其精度为万分比。10000表示系统满负荷运转。 + +UniProton中的线程CPU占用率指单个线程的CPU占用率,用于表示单个线程在一段时间内的闲忙程度。线程CPU占用率的有效表示范围为0~10000,其精度为万分比。10000表示在一段时间内系统一直在运行该线程。单核系统所有线程(包括中断和空闲任务)的CPU之和为10000。 + +UniProton的系统级CPU占用率依赖于Tick模块,通过Tick采样IDLE任务或IDLE软中断计数来实现 + +## 支持STM32F407ZGT6开发板 + +支持开发板主要涉及OS内核外围的启动流程和单板驱动,目录结构如下: + +├─apps # 基于UniProton实时OS编程的demo程序。 + +│ └─hello_world # hello_world示例程序。 + +├─bsp # 提供的板级驱动与OS对接。 + +├─build # 提供编译脚本编译出最终镜像。 + +├─config # 配置选项,供用户调整运行时参数。 + +├─include # UniProton实时部分提供的编程接口API。 + +└─libs # UniProton实时部分的静态库,build目录中的makefile示例已经将头文件和静态库的引用准备好,应用可直接使用。 + +## 支持OpenAMP混合部署 + +OpenAMP是一个开源软件框架,旨在通过非对称多处理器的开源解决方案,来标准化异构嵌入式系统中操作环境之间的交互。OpenAMP包括如下四大组件: + +1. remoteproc:管理从核的生命周期,管理共享内存、通信使用的buffer、vring等资源,初始化rpmsg和virtio。 +2. rpmsg:实现多核通信的通道,基于virtio实现。 +3. virtio:通过一套虚拟IO实现主从核的驱动程序通信,是一种半虚拟化技术。 +4. libmetal:屏蔽操作系统实现细节,提供通用用户API访问设备,处理设备中断、内存请求。 + +## 支持POSIX标准接口 + +[UniProton支持posix标准接口](./UniProton接口说明.md) + +## 支持设备驱动 + +UniProton的驱动结构、风格与linux类似,将驱动设备文件化,即VFS系统,通过驱动注册接口,将驱动注册到文件系统中,应用层只需要通过标准系统调用,即可调用底层驱动。整个驱动框架代码适配自开源RTOS系统Nuttx的驱动模块,因此接口调用也与Nuttx基本一致。struct file_operations结构体保存设备文件操作的方法,定义在fs.h头文件中,通过register_driver接口将驱动设备挂到对应的struct inode节点中,struct inode描述了每个设备节点的位置和数据。当系统调用操作设备文件时,根据对应文件的inode就能索引到对应的函数。接口详细信息可以查看[UniProton接口说明](./UniProton接口说明.md)。 + +## 支持Shell命令行 + +UniProton提供shell命令行,它能够以命令行交互的方式访问操作系统的功能或服务:它接受并解析用户输入的命令,并处理操作系统的输出结果。UniProton的shell模块代码适配自开源ROTS系统LiteOS的shell模块。因此与LiteOS一致,用户可以新增定制的命令,新增命令需重新编译烧录后才能执行。当前UniProton只支持了help命令,其他命令将在后续的版本中进行完善。Shell模块为用户提供下面几个接口。 + +| 接口名 | 描述 | +| :---: | :--: | +| SHELLCMD_ENTRY | 静态注册命令 | +| osCmdReg | 动态注册命令 | + +通常静态注册命令方式一般用于注册系统常用命令,动态注册命令方式一般用于注册用户命令。静态注册命令有5个入参,动态注册命令有4个入参。下面除去第一个入参是静态注册独有的,剩余的四个入参两个注册命令是一致的。接口详细信息可以查看[UniProton接口说明](./UniProton接口说明.md) diff --git a/docs/en/25.03/Embedded/UniProton/_menu.md b/docs/en/25.03/Embedded/UniProton/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..848998e4dc31b20cd176fe31917cdb85a27d7f41 --- /dev/null +++ b/docs/en/25.03/Embedded/UniProton/_menu.md @@ -0,0 +1,12 @@ +--- +label: 'UniProton用户指南' +ismanual: 'Y' +description: 'UniProton是面向嵌入式场景的操作系统,支持任务和内存管理、中断处理,提供强大调试能力' +children: + - label: '概述' + href: './overview.md' + - label: 'UniProton功能设计' + href: './UniProton-functions.md' + - label: 'UniProton接口说明' + href: './UniProton-apis.md' +--- \ No newline at end of file diff --git a/docs/en/25.03/Embedded/UniProton/figures/FCS.png b/docs/en/25.03/Embedded/UniProton/figures/FCS.png new file mode 100644 index 0000000000000000000000000000000000000000..afb47c557755c10a3f0b196b7080b16a0f86ab6a Binary files /dev/null and b/docs/en/25.03/Embedded/UniProton/figures/FCS.png differ diff --git a/docs/en/25.03/Embedded/UniProton/figures/MemoryApplication.png b/docs/en/25.03/Embedded/UniProton/figures/MemoryApplication.png new file mode 100644 index 0000000000000000000000000000000000000000..de46581c40122a82b92db8a67ae3fcd76a97041a Binary files /dev/null and b/docs/en/25.03/Embedded/UniProton/figures/MemoryApplication.png differ diff --git a/docs/en/25.03/Embedded/UniProton/figures/MemoryRelease.png b/docs/en/25.03/Embedded/UniProton/figures/MemoryRelease.png new file mode 100644 index 0000000000000000000000000000000000000000..f91c89bb02311f104949e2af42cddc4a3faaaca3 Binary files /dev/null and b/docs/en/25.03/Embedded/UniProton/figures/MemoryRelease.png differ diff --git a/docs/en/25.03/Embedded/UniProton/figures/pend_semaphore.png b/docs/en/25.03/Embedded/UniProton/figures/pend_semaphore.png new file mode 100644 index 0000000000000000000000000000000000000000..59d8159d1ff1cecb43f59cc5d7c5a9900db8e767 Binary files /dev/null and b/docs/en/25.03/Embedded/UniProton/figures/pend_semaphore.png differ diff --git a/docs/en/25.03/Embedded/UniProton/figures/post_semaphore.png b/docs/en/25.03/Embedded/UniProton/figures/post_semaphore.png new file mode 100644 index 0000000000000000000000000000000000000000..fa08d76dafd335b60838dda08db61ccadd8c6b8d Binary files /dev/null and b/docs/en/25.03/Embedded/UniProton/figures/post_semaphore.png differ diff --git a/docs/en/25.03/Embedded/UniProton/overview.md b/docs/en/25.03/Embedded/UniProton/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..79ecdf23c70904b152181c164a0e4f4543c5d881 --- /dev/null +++ b/docs/en/25.03/Embedded/UniProton/overview.md @@ -0,0 +1,11 @@ +# UniProton用户指南 + +## 介绍 + +UniProton是基于openEuler社区面向嵌入式场景的操作系统,旨在成为一个高质量的为上层业务软件屏蔽底层硬件差异,并提供强大的调试功能的操作系统平台。使业务软件可以在不同的硬件平台之间快速移植,方便产品芯片选型,降低硬件采购成本和软件维护成本。 + +本文档主要用于介绍UniProton的基本功能和接口说明,便于开发人员了解基本的UniProton操作系统知识。 + +## 编译教程 + +相关编译教程,可参考:[https://gitee.com/openeuler/UniProton/blob/master/doc/UniProton_build.md](https://gitee.com/openeuler/UniProton/blob/master/doc/UniProton_build.md/)。 diff --git a/docs/en/25.03/Embedded/_menu.md b/docs/en/25.03/Embedded/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..eff38b3a4abf71f626e4d3e1d8e92165661cefc8 --- /dev/null +++ b/docs/en/25.03/Embedded/_menu.md @@ -0,0 +1,9 @@ +--- +label: '嵌入式' +children: + - label: 'openEuler Embedded用户指南' + href: 'https://pages.openeuler.openatom.cn/embedded/docs/build/html/master/index.html' + description: 'openEuler Embedded是为嵌入式场景设计的轻量、安全、实时操作系统,支持多硬件架构' + - reference: './UniProton/_menu.md' +--- + diff --git a/docs/en/25.03/Embedded/index.md b/docs/en/25.03/Embedded/index.md new file mode 100644 index 0000000000000000000000000000000000000000..1b2561452e4f59fce10fffb5625d2dcb32f93c66 --- /dev/null +++ b/docs/en/25.03/Embedded/index.md @@ -0,0 +1,4 @@ +--- +title: 嵌入式 +overview: true +--- \ No newline at end of file diff --git a/docs/en/25.03/Server/Administration/Administrator/_menu.md b/docs/en/25.03/Server/Administration/Administrator/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..84eaa9a00c4176d230222e8ec513b347336e71d6 --- /dev/null +++ b/docs/en/25.03/Server/Administration/Administrator/_menu.md @@ -0,0 +1,31 @@ +--- +label: '管理员指南' +ismanual: 'Y' +description: 'openEuler 系统常用的管理员操作' +children: + - label: '查看系统信息' + href: './viewing-system-information.md' + - label: '基础配置' + href: './basic-configuration.md' + - label: '管理用户和用户组' + href: './user-and-user-group-management.md' + - label: '使用DNF管理软件包' + href: './using-dnf-to-manage-software-packages.md' + - label: '管理服务' + href: './service-management.md' + - label: '管理进程' + href: './process-management.md' + - label: '搭建服务' + href: './configuring-services.md' + children: + - label: '搭建repo服务器' + href: './configuring-the-repo-server.md' + - label: '搭建FTP服务器' + href: './configuring-the-ftp-server.md' + - label: '搭建web服务器' + href: './configuring-the-web-server.md' + - label: '搭建数据库服务器' + href: './setting-up-the-database-server.md' + - label: '常见问题与解决方法' + href: './faqs.md' +--- diff --git a/docs/en/25.03/Server/Administration/Administrator/administration.md b/docs/en/25.03/Server/Administration/Administrator/administration.md new file mode 100644 index 0000000000000000000000000000000000000000..89dd0f1865325203c28439b9e89e44b99839d526 --- /dev/null +++ b/docs/en/25.03/Server/Administration/Administrator/administration.md @@ -0,0 +1,4 @@ +# 管理员指南 + +本文档提供了openEuler系统常用的管理员操作,方便管理员更好地使用openEuler。 +本文档适用于所有使用openEuler系统的管理员。 diff --git a/docs/en/25.03/Server/Administration/Administrator/basic-configuration.md b/docs/en/25.03/Server/Administration/Administrator/basic-configuration.md new file mode 100644 index 0000000000000000000000000000000000000000..11a57803405e33678e2da50ab72ee6763632d9a4 --- /dev/null +++ b/docs/en/25.03/Server/Administration/Administrator/basic-configuration.md @@ -0,0 +1,498 @@ +# 基础配置 + + + +- [基础配置](#基础配置) + - [设置语言环境](#设置语言环境) + - [显示当前语言环境状态](#显示当前语言环境状态) + - [列出可用的语言环境](#列出可用的语言环境) + - [设置语言环境](#设置语言环境-1) + - [设置键盘](#设置键盘) + - [显示当前设置](#显示当前设置) + - [列出可用的键盘布局](#列出可用的键盘布局) + - [设置键盘布局](#设置键盘布局) + - [设置日期和时间](#设置日期和时间) + - [使用timedatectl命令设置](#使用timedatectl命令设置) + - [显示日期和时间](#显示日期和时间) + - [通过远程服务器进行时间同步](#通过远程服务器进行时间同步) + - [修改日期](#修改日期) + - [修改时间](#修改时间) + - [修改时区](#修改时区) + - [使用date命令设置](#使用date命令设置) + - [显示当前的日期和时间](#显示当前的日期和时间) + - [修改时间](#修改时间-1) + - [修改日期](#修改日期-1) + - [使用hwclock命令设置](#使用hwclock命令设置) + - [硬件时钟和系统时钟](#硬件时钟和系统时钟) + - [显示日期和时间](#显示日期和时间-1) + - [设置日期和时间](#设置日期和时间-1) + - [设置kdump](#设置kdump) + - [设置kdump预留内存](#设置kdump预留内存) + - [预留内存参数格式](#预留内存参数格式) + - [预留内存推荐值](#预留内存推荐值) + - [禁用网络相关驱动](#禁用网络相关驱动) + - [设置磁盘调度算法](#设置磁盘调度算法) + - [临时修改调度策略](#临时修改调度策略) + - [永久设置调度策略](#永久设置调度策略) + + + +## 设置语言环境 + +您可以通过localectl修改系统的语言环境,对应的参数设置保存在/etc/locale.conf文件中。这些参数会在系统启动过程中被systemd的守护进程读取。 + +### 显示当前语言环境状态 + +显示当前语言环境,命令如下: + +```shell +localectl status +``` + +例如显示系统当前的设置,命令和输出如下: + +```shell +# localectl status + System Locale: LANG=zh_CN.UTF-8 + VC Keymap: cn + X11 Layout: cn +``` + +### 列出可用的语言环境 + +显示当前可用的语言环境,命令如下: + +```shell +# localectl list-locales +``` + +例如显示当前系统中所有可用的中文环境,命令和输出如下: + +```shell +# localectl list-locales | grep zh +zh_CN.UTF-8 +``` + +### 设置语言环境-1 + +要设置语言环境,在root权限下执行如下命令,其中 _locale_ 是您要设置的语言类型,取值范围可通过**localectl list-locales**获取,请根据实际情况修改。 + +```shell +# localectl set-locale LANG=locale +``` + +例如设置为简体中文语言环境,在root权限下执行如下命令: + +```shell +# localectl set-locale LANG=zh_CN.UTF-8 +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 修改后需要重新登录或者在root权限下执行`source /etc/locale.conf`命令刷新配置文件,使修改生效。 + +## 设置键盘 + +您可以通过localectl修改系统的键盘设置,对应的参数设置保存在/etc/locale.conf文件中。这些参数,会在系统启动的早期被systemd的守护进程读取。 + +### 显示当前设置 + +显示当前键盘设置,命令如下: + +```shell +# localectl status +``` + +例如显示系统当前的设置,命令和输出如下: + +```shell +# localectl status + System Locale: LANG=zh_CN.UTF-8 + VC Keymap: cn + X11 Layout: cn +``` + +### 列出可用的键盘布局 + +显示当前可用的键盘布局,命令如下: + +```shell +# localectl list-keymaps +``` + +例如显示系统当前的中文键盘布局,命令和输出如下: + +```shell +# localectl list-keymaps | grep cn +cn +``` + +### 设置键盘布局 + +设置键盘布局,在root权限下执行如下命令,其中 _map_ 是您想要设置的键盘类型,取值范围可通过**localectl list-keymaps**获取,请根据实际情况修改: + +```shell +# localectl set-keymap map +``` + +此时设置的键盘布局同样也会应用到图形界面中。 + +设置完成后,查看当前状态: + +```shell +# localectl status + System Locale: LANG=zh_CN.UTF-8 + VC Keymap: cn + X11 Layout: us +``` + +## 设置日期和时间 + +本节介绍如何通过timedatectl、date、hwclock命令来设置系统的日期、时间和时区等。 + +### 使用timedatectl命令设置 + +#### 显示日期和时间 + +显示当前的日期和时间,命令如下: + +```shell +# timedatectl +``` + +例如显示系统当前的日期和时间,命令和输出如下: + +```shell +# timedatectl + Local time: Mon 2019-09-30 04:05:00 EDT + Universal time: Mon 2019-09-30 08:05:00 UTC + RTC time: Mon 2019-09-30 08:05:00 + Time zone: China Standard Time (CST), UTC +8 +System clock synchronized: no + NTP service: inactive + RTC in local TZ: no +``` + +#### 通过远程服务器进行时间同步 + +您可以启用NTP远程服务器进行系统时钟的自动同步。是否启用NTP,可在root权限下执行如下命令进行设置。其中 _boolean_ 可取值yes和no,分别表示启用和不启用NTP进行系统时钟自动同步,请根据实际情况修改。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 若启用了NTP远程服务器进行系统时钟自动同步,则不能手动修改日期和时间。若需要手动修改日期或时间,则需确保已经关闭NTP系统时钟自动同步。可执行`timedatectl set-ntp no`命令进行关闭。 + +例如开启自动远程时间同步,命令如下: + +```shell +# timedatectl set-ntp yes +``` + +#### 修改日期 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 修改日期前,请确保已经关闭NTP系统时钟自动同步。 + +修改当前的日期,在root权限下执行如下命令,其中 _YYYY_ 代表年份,_MM_ 代表月份,_DD_ 代表某天,请根据实际情况修改: + +```shell +# timedatectl set-time YYYY-MM-DD +``` + +例如修改当前的日期为2019年8月14号,命令如下: + +```shell +# timedatectl set-time '2019-08-14' +``` + +#### 修改时间 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 修改时间前,请确保已经关闭NTP系统时钟自动同步。 + +修改当前的时间,在root权限下执行如下命令,其中 _HH_ 代表小时,_MM_ 代表分钟,_SS_ 代表秒,请根据实际情况修改: + +```shell +# timedatectl set-time HH:MM:SS +``` + +例如修改当前的时间为15点57分24秒,命令如下: + +```shell +# timedatectl set-time 15:57:24 +``` + +#### 修改时区 + +显示当前可用时区,命令如下: + +```shell +timedatectl list-timezones +``` + +要修改当前的时区,在root权限下执行如下命令,其中 _time\_zone_ 是您想要设置的时区,请根据实际情况修改: + +```shell +# timedatectl set-timezone time_zone +``` + +例如修改当前的时区,首先查询所在地域的可用时区,此处以Asia为例: + +```shell +# timedatectl list-timezones | grep Asia +Asia/Aden +Asia/Almaty +Asia/Amman +Asia/Anadyr +Asia/Aqtau +Asia/Aqtobe +Asia/Ashgabat +Asia/Baghdad +Asia/Bahrain +…… + +Asia/Seoul +Asia/Shanghai +Asia/Singapore +Asia/Srednekolymsk +Asia/Taipei +Asia/Tashkent +Asia/Tbilisi +Asia/Tehran +Asia/Thimphu +Asia/Tokyo +``` + +然后修改当前的时区为“Asia/Shanghai”,命令如下: + +```shell +# timedatectl set-timezone Asia/Shanghai +``` + +### 使用date命令设置 + +#### 显示当前的日期和时间 + +显示当前的日期和时间,命令如下: + +```shell +# date +``` + +默认情况下,date命令显示本地时间。要显示UTC时间,添加\-\-utc或-u参数: + +```shell +# date --utc +``` + +要自定义对应的输出信息格式,添加 +"format" 参数: + +```shell +# date +"format" +``` + +**表 1** 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

格式参数

+

说明

+

%H

+

小时以HH格式(例如 17)。

+

%M

+

分钟以MM格式(例如 37)。

+

%S

+

秒以SS格式(例如 25)。

+

%d

+

日期以DD格式(例如 15)。

+

%m

+

月份以MM格式(例如 07)。

+

%Y

+

年份以YYYY格式(例如 2019)。

+

%Z

+

时区缩写(例如CEST)。

+

%F

+

日期整体格式为YYYY-MM-DD(例如 2019-7-15),等同%Y-%m-%d。

+

%T

+

时间整体格式为HH:MM:SS(例如 18:30:25),等同%H:%M:%S。

+
+ +实际使用示例如下: + +- 显示当前的日期和本地时间。 + + ```shell + # date + 2019年 08月 17日 星期六 17:26:34 CST + ``` + +- 显示当前的日期和UTC时间。 + + ```shell + # date --utc + 2019年 08月 17日 星期六 09:26:18 UTC + ``` + +- 自定义date命令的输出。 + + ```shell + # date +"%Y-%m-%d %H:%M" + 2019-08-17 17:24 + ``` + +#### 修改时间-1 + +要修改当前的时间,添加\-\-set或者-s参数。在root权限下执行如下命令,其中 _HH_ 代表小时,_MM_ 代表分钟,_SS_ 代表秒,请根据实际情况修改: + +```shell +# date --set HH:MM:SS +``` + +默认情况下, date命令设置本地时间。要设置UTC时间,添加\-\-utc或-u参数: + +```shell +# date --set HH:MM:SS --utc +``` + +例如修改当前的时间为23点26分00秒,在root权限下执行如下命令: + +```shell +# date --set 23:26:00 +``` + +#### 修改日期-1 + +修改当前的日期,添加\-\-set或者-s参数。在root权限下执行如下命令,其中 _YYYY_ 代表年份,_MM_ 代表月份,_DD_ 代表某天,请根据实际情况修改: + +```shell +# date --set YYYY-MM-DD +``` + +例如修改当前的日期为2019年11月2日,命令如下: + +```shell +# date --set 2019-11-02 +``` + +### 使用hwclock命令设置 + +可以使用 hwclock 命令设置硬件时钟RTC \(Real Time Clock\) 。 + +#### 硬件时钟和系统时钟 + +Linux 将时钟分为: + +- 系统时钟 \(System Clock\) :当前Linux Kernel中的时钟。 +- 硬件时钟 RTC:主板上由电池供电的主板硬件时钟,该时钟可以在BIOS的 "Standard BIOS Feature" 项中进行设置。 + +当Linux启动时,会读取硬件时钟,并根据硬件时间来设置系统时间。 + +#### 显示日期和时间-1 + +显示当前硬件的日期和时间,在root权限下执行如下命令: + +```shell +# hwclock +``` + +例如显示当前硬件的日期和时间,命令和输出如下: + +```shell +# hwclock +2019-08-26 10:18:42.528948+08:00 +``` + +#### 设置日期和时间-1 + +修改当前硬件的日期和时间,在root权限下执行如下命令,其中 _dd_ 表示日,_mm_ 表示月份,_yyyy_ 表示年份,_HH_ 表示小时,_MM_ 表示分钟,请根据实际情况修改: + +```shell +# hwclock --set --date "yyyy-mm-dd HH:MM" +``` + +例如修改当前的时间为2019年10月21日21点17分,命令如下: + +```shell +# hwclock --set --date "2019-10-21 21:17" +``` + +## 设置kdump + +本节介绍如何设置kdump预留内存及修改kdump配置文件参数。 + +### 设置kdump预留内存 + +#### 预留内存参数格式 + +kdump预留内存参数必须添加到内核启动参数中,配置文件为/boot/efi/EFI/openEuler/grub.cfg(UEFI引导模式)或/boot/grub2/grub.cfg(legacy引导模式),openEuler发布版本中默认已经添加,可以根据实际使用情况调整。添加和修改启动参数后,重启系统生效。kdump预留内存参数格式如下: + +| 内核启动参数 | 描述 | 缺省值 | 备注 | +|--------------------|-------------------------------------------|---------------|------------------------------------------------------------| +| crashkernel=x | 在4G以下的物理内存预留x大小的内存给kdump使用。 | x86版本默认配置512M | 该配置方法只在4G以下内存预留,必须保证4G以下连续可用内存足够预留。 | +| crashkernel=x@y | 在y起始地址预留x大小的内存给kdump使用。 | 未使用 | 需要确保y起始地址的x大小的内存未被其他模块预留。 | +| crashkernel=x,high | 在4G以下的物理内存中预留256M内存,在4G以上预留x大小内存给kdump使用。 | arm64版本默认配置1024M,high | 需要确保4G以下有256M连续可用的物理内存,4G以上有连续的x大小的连续物理内存。实际预留内存大小为256M+x。 | +| crashkernel=x,low crashkernel=y,high | 在4G以下的物理内存中预留x大小,在4G以上预留y大小内存给kdump使用。 | 未使用 | 需要确保4G以下有连续的x大小物理内存,4G以上有连续的y大小物理内存。 | + +### 预留内存推荐值 + +| 推荐方案 | 预留参数 | 参数说明 | +|------|------------------------|----------------------------------------------| +| 通用方案 | crashkernel=2048M,high | 4G以下预留256M,4G以上预留2048M内存给kdump使用。共256+2048M。 | +| 经济方案 | crashkernel=1024M,high | 4G以下预留256M,4G以上预留1024M内存给kdump使用。共256+1024M。 推荐系统512M内存以内的场景,并不使用网络转储kdump文件。对于虚拟机场景,可以适当减少内存预留值,推荐虚拟机设置为crashkernel=512M或者crashkernel=256M,high | + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 不通过网络转储kdump文件时,需要设置kdump文件系统不打包网络相关驱动。网络驱动加载需要申请较大内存,可能导致预留内存不足,kdump失败。因此建议禁用网络相关驱动。 + +### 禁用网络相关驱动 + +kdump配置文件(/etc/kdump.conf)中,dracut参数可以设置裁剪的驱动模块,可以将网络驱动配置到裁剪驱动列表中,让kdump文件系统中不加载该驱动,修改配置文件后,重启kdump服务生效。dracut参数配置如下所示: + +`dracut_args --omit-drivers "mdio-gpi usb_8dev et1011c rt2x00usb bcm-phy-lib mac80211_hwsim rtl8723be rndis_host hns3_cae amd vrf rtl8192cu mt76x02-lib int51x1 ppp_deflate team_mode_loadbalance smsc911x aweth bonding mwifiex_usb hnae dnet rt2x00pci vaser_pci hdlc_ppp marvell rtl8xxxu mlxsw_i2c ath9k_htc rtl8150 smc91x cortina at803x rockchip cxgb4 spi_ks8995 mt76x2u smsc9420 mdio-cavium bnxt_en ch9200 dummy macsec ice mt7601u rtl8188ee ixgbevf net1080 liquidio_vf be2net mlxsw_switchx2 gl620a xilinx_gmii2rgmii ppp_generic rtl8192de sja1000_platform ath10k_core cc770_platform realte igb c_can_platform c_can ethoc dm9601 smsc95xx lg-vl600 ifb enic ath9 mdio-octeon ppp_mppe ath10k_pci cc770 team_mode_activebackup marvell10g hinic rt2x00lib mlx4_en iavf broadcom igc c_can_pci alx rtl8192se rtl8723ae microchip lan78xx atl1c rtl8192c-common almia ax88179_178a qed netxen_nic brcmsmac rt2800usb e1000 qla3xxx mdio-bitbang qsemi mdio-mscc-miim plx_pci ipvlan r8152 cx82310_eth slhc mt76x02-usb ems_pci xen-netfront usbnet pppoe mlxsw_minimal mlxsw_spectrum cdc_ncm rt2800lib rtl_usb hnae3 ath9k_common ath9k_hw catc mt76 hns_enet_drv ppp_async huawei_cdc_ncm i40e rtl8192ce dl2 qmi_wwan mii peak_usb plusb can-dev slcan amd-xgbe team_mode_roundrobin ste10Xp thunder_xcv pptp thunder_bgx ixgbe davicom icplus tap tun smsc75xx smsc dlci hns_dsaf mlxsw_core rt2800mmi softing uPD60620 vaser_usb dp83867 brcmfmac mwifiex_pcie mlx4_core micrel team macvlan bnx2 virtio_net rtl_pci zaurus hns_mdi libcxgb hv_netvsc nicvf mt76x0u teranetics mlxfw cdc_eem qcom-emac pppox mt76-usb sierra_net i40evf bcm87xx mwifiex pegasus rt2x00mmi sja1000 ena hclgevf cnic cxgb4vf ppp_synctty iwlmvm team_mode_broadcast vxlan vsockmon hdlc_cisc rtl8723-common bsd_comp fakelb dp83822 dp83tc811 cicada fm10 8139t sfc hs geneve hclge xgene-enet-v2 cdc_mbim hdlc asix netdevsim rt2800pci team_mode_random lxt ems_usb mlxsw_pci sr9700 mdio-thunder mlxsw_switchib macvtap atlantic cdc_ether mcs7830 nicpf mdi peak_pci atl1e cdc_subset ipvtap btcoexist mt76x0-common veth slip iwldvm bcm7xxx vitesse netconsole epic100 myri10ge r8169 qede microchip_t1 liquidi bnx2x brcmutil mwifiex_sdi mlx5_core rtlwifi vmxnet3 nlmon hns3 hdlc_raw esd_usb2 atl2 mt76x2-common iwlwifi mdio-bcm-unimac national ath rtwpci rtw88 nfp rtl8821ae fjes thunderbolt-net 8139cp atl1 mscc vcan dp83848 dp83640 hdlc_fr e1000e ipheth net_failover aquantia rtl8192ee igbvf rocker intel-xway tg3" --omit "ramdisk network ifcfg qemu-net" --install "chmod" --nofscks` + +## 设置磁盘调度算法 + +本节介绍如何设置磁盘调度算法。 + +### 临时修改调度策略 + +例如将所有IO调度算法修改为mq-deadline,此修改重启后会失效。 + +```shell +# echo mq-deadline > /sys/block/sd*/queue/scheduler +``` + +### 永久设置调度策略 + +可以通过在内核启动配置文件grub.cfg中的kernel行追加:elevator=mq-deadline,重启后生效。 + +```text +linux /vmlinuz-4.19.90-2003.4.0.0036.oe1.x86_64 root=/dev/mapper/openeuler-root ro resume=/dev/mapper/openeuler-swap rd.lvm.lv=openeuler/root rd.lvm.lv=openeuler/swap quiet crashkernel=512M elevator=mq-deadline +``` diff --git a/docs/en/25.03/Server/Administration/Administrator/configuring-services.md b/docs/en/25.03/Server/Administration/Administrator/configuring-services.md new file mode 100644 index 0000000000000000000000000000000000000000..72cb121e1c967ead660145cd62b8819585148b63 --- /dev/null +++ b/docs/en/25.03/Server/Administration/Administrator/configuring-services.md @@ -0,0 +1 @@ +# 搭建服务 diff --git a/docs/en/25.03/Server/Administration/Administrator/configuring-the-ftp-server.md b/docs/en/25.03/Server/Administration/Administrator/configuring-the-ftp-server.md new file mode 100644 index 0000000000000000000000000000000000000000..bec57655007ef97303720676265cac13d81daf7d --- /dev/null +++ b/docs/en/25.03/Server/Administration/Administrator/configuring-the-ftp-server.md @@ -0,0 +1,503 @@ +# 搭建FTP服务器 + +## 总体介绍 + +### FTP简介 + +FTP(File Transfer Protocol)即文件传输协议,是互联网最早的传输协议之一,其最主要的功能是服务器和客户端之间的文件传输。FTP使用户可以通过一套标准的命令访问远程系统上的文件,而不需要直接登录远程系统。另外,FTP服务器还提供了如下主要功能: + +- 用户分类 + + 默认情况下,FTP服务器依据登录情况,将用户分为实体用户(real user)、访客(guest)、匿名用户(anonymous)三类。三类用户对系统的访问权限差异较大,实体用户具有较完整的访问权限,匿名用户仅有下载资源的权限。 + +- 命令记录和日志文件记录 + + FTP可以利用系统的syslogd记录数据,这些数据包括用户历史使用命令与用户传输数据(传输时间、文件大小等),用户可以在/var/log/中获得各项日志信息。 + +- 限制用户的访问范围 + + FTP可以将用户的工作范围限定在用户主目录。用户通过FTP登录后系统显示的根目录就是用户主目录,这种环境被称为change root,简称chroot。这种方式可以限制用户只能访问主目录,而不允许访问/etc、/home、/usr/local等系统的重要目录,从而保护系统,使系统更安全。 + +### FTP使用到的端口 + +FTP的正常工作需要使用到多个网络端口,服务器端会使用到的端口主要有: + +- 命令通道,默认端口为21 +- 数据通道,默认端口为20 + +两者的连接发起端不同,端口21主要接收来自客户端的连接,端口20则是FTP服务器主动连接至客户端。 + +### vsftpd简介 + +由于FTP历史悠久,它采用未加密的传输方式,所以被认为是一种不安全的协议。为了更安全地使用FTP,这里介绍FTP较为安全的守护进程vsftpd(Very Secure FTP Daemon)。 + +之所以说vsftpd安全,是因为它最初的发展理念就是构建一个以安全为中心的FTP服务器。它具有如下特点: + +- vsftpd服务的启动身份为一般用户,具有较低的系统权限。此外,vsftpd使用chroot改变根目录,不会误用系统工具。 +- 任何需要较高执行权限的vsftpd命令均由一个特殊的上层程序控制,该上层程序的权限较低,以不影响系统本身为准。 +- vsftpd整合了大部分FTP会使用到的额外命令(例如dir、ls、cd等),一般不需要系统提供额外命令,对系统来说比较安全。 + +## 使用vsftpd + +### 安装vsftpd + +使用vsftpd需要安装vsftpd软件,在已经配置yum源的情况下,通过root权限执行如下命令,即可完成vsftpd的安装。 + +```shell +# dnf install vsftpd +``` + +### 管理vsftpd服务 + +启动、停止和重启vsftpd服务,请在root权限下执行对应命令。 + +- 启动vsftpd服务 + + ```shell + # systemctl start vsftpd + ``` + + 可以通过netstat命令查看通信端口21是否开启,如下显示说明vsftpd已经启动。 + + ```shell + # netstat -tulnp | grep 21 + tcp6 0 0 :::21 :::* LISTEN 19716/vsftpd + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 如果没有**netstat**命令,可以执行**dnf install net-tools**命令安装后再使用**netstat**命令。 + +- 停止vsftpd服务 + + ```shell + # systemctl stop vsftpd + ``` + +- 重启vsftpd服务 + + ```shell + # systemctl restart vsftpd + ``` + +## 配置vsftpd + +### vsftpd配置文件介绍 + +用户可以通过修改vsftpd的配置文件,控制用户权限等。vsftpd的主要配置文件和含义如[表1](#table1541615718372)所示,用户可以根据需求修改配置文件的内容。更多的配置参数含义可以通过man查看。 + +**表 1** vsftpd配置文件介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

配置文件

+

含义

+

/etc/vsftpd/vsftpd.conf

+

vsftpd进程的主配置文件,配置内容格式为“参数=参数值”,且参数和参数值不能为空。

+

vsftpd.conf 的详细介绍可以使用如下命令查看:

+

man 5 vsftpd.conf

+

/etc/pam.d/vsftpd

+

PAM(Pluggable Authentication Modules)认证文件,主要用于身份认证和限制一些用户的操作。

+

/etc/vsftpd/ftpusers

+

禁止使用vsftpd的用户列表文件。默认情况下,系统帐号也在该文件中,因此系统帐号默认无法使用vsftpd。

+

/etc/vsftpd/user_list

+

禁止或允许登录vsftpd服务器的用户列表文件。该文件是否生效,取决于主配置文件vsftpd.conf中的如下参数:

+

userlist_enable:是否启用userlist机制,YES为启用,此时userlist_deny配置有效,NO为禁用。

+

userlist_deny:是否禁止user_list中的用户登录,YES为禁止名单中的用户登录,NO为允许命令中的用户登录。

+

例如userlist_enable=YES,userlist_deny=YES,则user_list中的用户都无法登录。

+

/etc/vsftpd/chroot_list

+

是否限制在主目录下的用户列表。该文件默认不存在,需要手动建立。它是主配置文件vsftpd.conf中参数chroot_list_file的参数值。

+

其作用是限制还是允许,取决于主配置文件vsftpd.conf中的如下参数:

+
  • chroot_local_user:是否将所有用户限制在主目录,YES为启用,NO禁用
  • chroot_list_enable:是否启用限制用户的名单,YES为启用,NO禁用。
+

例如chroot_local_user=YES,chroot_list_enable=YES,且指定chroot_list_file=/etc/vsftpd/chroot_list时,表示所有用户被限制在其主目录下,而chroot_list中的用户不受限制。

+

/usr/sbin/vsftpd

+

vsftpd的唯一执行文件。

+

/var/ftp/

+

匿名用户登录的默认根目录,与ftp帐户的用户主目录有关。

+
+ +### 默认配置说明 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 文档中的配置内容仅供参考,请用户根据实际情况(例如安全加固需要)进行修改。 + +openEuler系统中 ,vsftpd默认不开放匿名用户,使用vim命令查看主配置文件,其内容如下: + +```shell +# vim /etc/vsftpd/vsftpd.conf +anonymous_enable=NO +local_enable=YES +write_enable=YES +local_umask=022 +dirmessage_enable=YES +xferlog_enable=YES +connect_from_port_20=YES +xferlog_std_format=YES +listen=NO +listen_ipv6=YES +pam_service_name=vsftpd +userlist_enable=YES +``` + +其中各参数含义如[表2](#table18185162512499)所示。 + +**表 2** 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

含义

+

anonymous_enable

+

是否允许匿名用户登录,YES为允许匿名登录,NO为不允许。

+

local_enable

+

是否允许本地用户登入,YES 为允许本地用户登入,NO为不允许。

+

write_enable

+

是否允许登录用户有写权限,YES为启用上传写入功能,NO为禁用。

+

local_umask

+

本地用户新增档案时的umask值。

+

dirmessage_enable

+

当用户进入某个目录时,是否显示该目录需要注意的内容,YES为显示注意内容,NO为不显示。

+

xferlog_enable

+

是否记录使用者上传与下载文件的操作,YES为记录操作,NO为不记录。

+

connect_from_port_20

+

Port模式进行数据传输是否使用端口20,YES为使用端口20,NO为不使用端口20。

+

xferlog_std_format

+

传输日志文件是否以标准xferlog格式书写,YES为使用该格式书写,NO为不使用。

+

listen

+

设置vsftpd是否以stand alone的方式启动,YES为使用stand alone方式启动,NO为不使用该方式。

+

pam_service_name

+

支持PAM模块的管理,配置值为服务名称,例如vsftpd。

+

userlist_enable

+

是否支持/etc/vsftpd/user_list文件内的帐号登录控制,YES为支持,NO为不支持。

+

tcp_wrappers

+

是否支持TCP Wrappers的防火墙机制,YES为支持,NO为不支持。

+

listen_ipv6

+

是否侦听IPv6的FTP请求,YES为侦听,NO为不侦听。listen和listen_ipv6不能同时开启。

+
+ +### 配置本地时间 + +#### 概述 + +openEuler系统中,vsftpd默认使用GMT时间(格林尼治时间),可能和本地时间不一致,例如GMT时间比北京时间晚8小时,请用户改为本地时间,否则服务器和客户端时间不一致,在上传下载文件时可能引起错误。 + +#### 设置方法 + +在root权限下设置vsftpd时间为本地时间的操作步骤如下: + +1. 打开配置文件vsftpd.conf,将参数use\_localtime的参数值改为YES。命令如下: + + ```shell + # vim /etc/vsftpd/vsftpd.conf + ``` + + 配置内容如下: + + ```text + use_localtime=YES + ``` + +2. 重启vsftpd服务。 + + ```shell + # systemctl restart vsftpd + ``` + +3. 设置vsftpd服务开机启动。 + + ```shell + # systemctl enable vsftpd + ``` + +### 配置欢迎信息 + +使用vsftpd服务,建议新建欢迎信息文件(没有也不影响使用)。在root权限下设置vsftpd的欢迎信息welcome.txt文件的操作步骤如下: + +1. 打开配置文件vsftpd.conf,加入欢迎信息文件配置内容后保存退出。 + + ```shell + # vim /etc/vsftpd/vsftpd.conf + ``` + + 需要加入的配置行如下: + + ```shell + banner_file=/etc/vsftpd/welcome.txt + ``` + +2. 建立欢迎信息。即打开welcome.txt文件,写入欢迎信息后保存退出。 + + ```shell + # vim /etc/vsftpd/welcome.txt + ``` + + 欢迎信息举例如下: + + ```text + Welcome to this FTP server! + ``` + +### 配置系统帐号登录权限 + +一般情况下,用户需要限制部分帐号的登录权限。用户可根据需要进行配置。 + +vsftpd有两个默认存放用户名单的文件,来对访问FTP服务的用户身份进行管理和限制。vsftpd会分别检查两个配置文件,只要是被任何一个文件所禁止的用户,FTP访问到本机的请求都会被拒绝。 + +- /etc/vsftpd/user_list:可以作为用户白名单,或者是黑名单,或者无效名单,由userlist_enable和userlist_deny这两个参数决定。 +- /etc/vsftpd/ftpusers:只能是用户黑名单,不受任何参数限制。 + +## 验证FTP服务是否搭建成功 + +可以使用openEuler提供的FTP客户端进行验证。命令和回显如下,根据提示输入用户名(用户为系统中存在的用户)和密码。如果显示Login successful,即说明FTP服务器搭建成功。 + +```shell +# ftp localhost +Trying 127.0.0.1... +Connected to localhost (127.0.0.1). +220-Welcome to this FTP server! +220 +Name (localhost:root): USERNAME +331 Please specify the password. +Password: +230 Login successful. +Remote system type is UNIX. +Using binary mode to transfer files. +ftp> bye +221 Goodbye. +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 如果没有**ftp**命令,可以在root权限下执行**dnf install ftp**命令安装后再使用**ftp**命令。 + +## 配置防火墙 + +如果要将FTP开放给Internet使用,需要在root权限下对防火墙和SElinux进行设置。 + +```shell +# firewall-cmd --add-service=ftp --permanent +success +# firewall-cmd --reload +success +# setsebool -P ftpd_full_access on +``` + +## 传输文件 + +### 概述 + +这里给出vsftpd服务启动后,如何进行文件传输的指导。 + +### 连接服务器 + +#### 命令格式 + +**ftp** \[_hostname_ | _ip-address_\] + +其中hostname为服务器名称,ip-address为服务器IP地址。 + +#### 操作说明 + +在openEuler系统的命令行终端,执行如下命令: + +```shell +# ftp ip-address +``` + +根据提示输入用户名和密码,认证通过后显示如下,说明ftp连接成功,此时进入了连接到的服务器目录。 + +```shell +ftp> +``` + +在该提示符下,可以输入不同的命令进行相关操作: + +- 显示服务器当前路径 + + ```shell + ftp>pwd + ``` + +- 显示本地路径,用户可以将该路径下的文件上传到FTP服务器对应位置 + + ```shell + ftp>lcd + ``` + +- 退出当前窗口,返回本地Linux终端 + + ```shell + ftp>! + ``` + +### 下载文件 + +通常使用get或mget命令下载文件。 + +#### get使用方法 + +- 功能说明:将文件从远端主机中传送至本地主机中 +- 命令格式:**get** \[_remote-file_\] \[_local-file_\] + + 其中 _remote-file_ 为远程文件,_local-file_ 为本地文件 + +- 示例:获取远程服务器上的/home/openEuler/openEuler.htm文件到本地/home/myopenEuler/,并改名为myopenEuler.htm,命令如下: + + ```shell + ftp> get /home/openEuler/openEuler.htm /home/myopenEuler/myopenEuler.htm + ``` + +#### mget使用方法 + +- 功能说明:从远端主机接收一批文件至本地主机 +- 命令格式:**mget** \[_remote-file_\] + + 其中 _remote-file_ 为远程文件 + +- 示例:获取服务器上/home/openEuler/目录下的所有文件,命令如下: + + ```shell + ftp> cd /home/openEuler/ + ftp> mget *.* + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 此时每下载一个文件,都会有提示信息。如果要屏蔽提示信息,则在 **mget \*.\*** 命令前先执行**prompt off** + > 文件都被下载到Linux主机的当前目录下。比如,在/home/myopenEuler/下运行的ftp命令,则文件都下载到/home/myopenEuler/下。 + +### 上传文件 + +通常使用put或mput命令上传文件。 + +#### put使用方法 + +- 功能说明:将本地的一个文件传送到远端主机中 +- 命令格式:**put** \[_local-file_\] \[_remote-file_\] + + 其中 _remote-file_ 为远程文件,_local-file_ 为本地文件 + +- 示例:将本地的myopenEuler.htm传送到远端主机/home/openEuler/,并改名为openEuler.htm,命令如下: + + ```shell + ftp> put myopenEuler.htm /home/openEuler/openEuler.htm + ``` + +#### mput使用方法 + +- 功能说明:将本地主机中一批文件传送至远端主机 +- 命令格式:**mput** \[_local-file_\] + + 其中 _local-file_ 为本地文件 + +- 示例:将本地当前目录下所有htm文件上传到服务器/home/openEuler/下,命令如下: + + ```shell + ftp> cd /home/openEuler/ + ftp> mput *.htm + ``` + +### 删除文件 + +通常使用delete或mdelete命令删除文件。 + +#### delete使用方法 + +- 功能说明:删除远程服务器上的一个或多个文件 +- 命令格式:**delete** \[_remote-file_\] + + 其中 _remote-file_ 为远程文件 + +- 示例:删除远程服务器上/home/openEuler/下的openEuler.htm文件,命令如下: + + ```shell + ftp> cd /home/openEuler/ + ftp> delete openEuler.htm + ``` + +#### mdelete使用方法 + +- 功能说明:删除远程服务器上的文件,常用于批量删除 +- 命令格式:**mdelete** \[_remote-file_\] + + 其中 _remote-file_ 为远程文件 + +- 示例:删除远程服务器上/home/openEuler/下所有a开头的文件,命令如下: + + ```shell + ftp> cd /home/openEuler/ + ftp> mdelete a* + ``` + +### 断开服务器 + +断开与服务器的连接,使用bye命令,如下: + +```shell +ftp> bye +``` diff --git a/docs/en/25.03/Server/Administration/Administrator/configuring-the-repo-server.md b/docs/en/25.03/Server/Administration/Administrator/configuring-the-repo-server.md new file mode 100644 index 0000000000000000000000000000000000000000..9922cc486fd205d39847ead28639234ee6541b13 --- /dev/null +++ b/docs/en/25.03/Server/Administration/Administrator/configuring-the-repo-server.md @@ -0,0 +1,376 @@ +# 搭建repo服务器 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> openEuler提供了多种repo源供用户在线使用,各repo源含义可参考[系统安装](../../Releasenotes/Releasenotes/installing-the-os.md)。若用户无法在线获取openEuler repo源,则可使用openEuler提供的ISO发布包创建为本地openEuler repo源。本章节中以openEuler-21.09-aarch64-dvd.iso发布包为例,请根据实际需要的ISO发布包进行修改。 + +## 概述 + +将openEuler提供的ISO发布包openEuler-21.09-aarch64-dvd.iso创建为repo源,如下以使用nginx进行repo源部署,提供http服务为例进行说明。 + +## 创建/更新本地repo源 + +使用mount挂载,将openEuler的ISO发布包openEuler-21.09-aarch64-dvd.iso创建为repo源,并能够对repo源进行更新。 + +### 获取ISO发布包 + +请从如下网址获取openEuler的ISO发布包: + +[https://repo.openeuler.org/openEuler-21.09/](https://repo.openeuler.org/openEuler-21.09/) + +### 挂载ISO创建repo源 + +在root权限下使用mount命令挂载ISO发布包。 + +示例如下: + +```shell +# mount /home/openEuler/openEuler-21.09-aarch64-dvd.iso /mnt/ +``` + +挂载好的mnt目录如下: + +```text +. +│── boot.catalog +│── docs +│── EFI +│── images +│── Packages +│── repodata +│── TRANS.TBL +└── RPM-GPG-KEY-openEuler +``` + +其中,Packages为rpm包所在的目录,repodata为repo源元数据所在的目录,RPM-GPG-KEY-openEuler为openEuler的签名公钥。 + +### 创建本地repo源 + +可以拷贝ISO发布包中相关文件至本地目录以创建本地repo源,示例如下: + +```shell +# mount /home/openEuler/openEuler-21.09-aarch64-dvd.iso /mnt/ +# mkdir -p /home/openEuler/srv/repo/ +# cp -r /mnt/Packages /home/openEuler/srv/repo/ +# cp -r /mnt/repodata /home/openEuler/srv/repo/ +# cp -r /mnt/RPM-GPG-KEY-openEuler /home/openEuler/srv/repo/ +``` + +从而本地repo目录如下: + +```text +. +│── Packages +│── repodata +└── RPM-GPG-KEY-openEuler +``` + +Packages为rpm包所在的目录,repodata为repo源元数据所在的目录,RPM-GPG-KEY-openEuler为openEuler的签名公钥。 + +### 更新repo源 + +更新repo源有两种方式: + +- 通过新版本的ISO更新已有的repo源,与创建repo源的方式相同,即挂载ISO发布包或重新拷贝ISO发布包至本地目录。 + +- 在repo源的Packages目录下添加rpm包,然后通过createrepo命令更新repo源。 + + ```shell + # createrepo --update --workers=10 ~/srv/repo + ``` + + 其中,\-\-update表示更新,\-\-workers表示线程数,可自定义。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 若命令打印信息为“createrepo:未找到命令”,则表示未安装createrepo软件,可在root权限下执行**dnf install createrepo**进行安装。 + +## 部署远端repo源 + +安装openEuler操作系统,在openEuler上通过nginx部署repo源。 + +### nginx安装与配置 + +1. 请自行下载nginx工具并在root权限下安装nginx。 +2. 安装nginx之后,在root权限下配置/etc/nginx/nginx.conf。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 文档中的配置内容仅供参考,请用户根据实际情况(例如安全加固需要)进行配置。 + + ```text + user nginx; + worker_processes auto; # 建议设置为core-1 + error_log /var/log/nginx/error.log warn; # log存放位置 + 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; + keepalive_timeout 65; + + server { + listen 80; + server_name localhost; # 服务器名(url) + client_max_body_size 4G; + root /usr/share/nginx/repo; # 服务默认目录 + + location / { + autoindex on; # 开启访问目录下层文件 + autoindex_exact_size on; + autoindex_localtime on; + } + + } + + } + ``` + +### 启动nginx服务 + +1. 在root权限下通过systemctl命令启动nginx服务: + + ```shell + # systemctl enable nginx + # systemctl start nginx + ``` + +2. nginx是否启动成功可通过下面命令查看: + + ```shell + # systemctl status nginx + ``` + + - [图1](#zh-cn_topic_0151920971_fd25e3f1d664b4087ae26631719990a71)表示nginx服务启动成功 + + **图 1** nginx服务启动成功 + ![](./figures/nginx_start_success.png) + + - 若nginx服务启动失败,查看错误信息: + + ```shell + # systemctl status nginx.service --full + ``` + + **图 2** nginx服务启动失败 + ![](./figures/nginx_start_failed.png) + + 如[图2](#zh-cn_topic_0151920971_f1f9f3d086e454b9cba29a7cae96a4c54)所示nginx服务创建失败,是由于目录/var/spool/nginx/tmp/client\_body创建失败,在root权限下手动进行创建,类似的问题也这样处理: + + ```shell + # mkdir -p /var/spool/nginx/tmp/client_body + # mkdir -p /var/spool/nginx/tmp/proxy + # mkdir -p /var/spool/nginx/tmp/fastcgi + # mkdir -p /usr/share/nginx/uwsgi_temp + # mkdir -p /usr/share/nginx/scgi_temp + ``` + +### repo源部署 + +1. 在root权限下创建nginx配置文件/etc/nginx/nginx.conf中指定的目录/usr/share/nginx/repo: + + ```shell + # mkdir -p /usr/share/nginx/repo + ``` + +2. 在root权限下修改目录/usr/share/nginx/repo的权限: + + ```shell + # chmod -R 755 /usr/share/nginx/repo + ``` + +3. 设置防火墙规则,开启nginx设置的端口(此处为80端口),在root权限下通过firewall设置端口开启: + + ```shell + # firewall-cmd --add-port=80/tcp --permanent + # firewall-cmd --reload + ``` + + 在root权限下查询80端口是否开启成功,输出为yes则表示80端口开启成功: + + ```shell + # firewall-cmd --query-port=80/tcp + ``` + + 也可在root权限下通过iptables来设置80端口开启: + + ```shell + # iptables -I INPUT -p tcp --dport 80 -j ACCEPT + ``` + +4. nginx服务设置好之后,即可通过ip直接访问网页,如[图3](#zh-cn_topic_0151921017_fig1880404110396): + + **图 3** nginx部署成功 + ![](./figures/nginx_deployed_success.png) + +5. 通过下面几种方式将repo源放入到/usr/share/nginx/repo下: + - 在root权限下拷贝镜像中相关文件至/usr/share/nginx/repo下,并修改目录权限。 + + ```shell + # mount /home/openEuler/openEuler-21.09-aarch64-dvd.iso /mnt/ + # cp -r /mnt/Packages /usr/share/nginx/repo + # cp -r /mnt/repodata /usr/share/nginx/repo + # cp -r /mnt/RPM-GPG-KEY-openEuler /usr/share/nginx/repo + # chmod -R 755 /usr/share/nginx/repo + ``` + + openEuler-21.09-aarch64-dvd.iso存放在/home/openEuler目录下。 + + - 使用root在/usr/share/nginx/repo下创建repo源的软链接。 + + ```shell + # ln -s /mnt /usr/share/nginx/repo/os + ``` + + /mnt为已经创建好的repo源,/usr/share/nginx/repo/os将指向/mnt。 + +## 使用repo源 + +repo可配置为yum源,yum(全称为 Yellow dog Updater, Modified)是一个Shell前端软件包管理器。基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软件包,无须繁琐地一次次下载和安装。 + +### repo配置为yum源(软件源) + +构建好的repo可以配置为yum源使用,在/etc/yum.repos.d/目录下使用root权限创建\*\*\*.repo的配置文件(必须以.repo为扩展名),分为本地和http服务器配置yum源两种方式: + +- 配置本地yum源 + + 在/etc/yum.repos.d目录下创建openEuler.repo文件,使用构建的本地repo源作为yum源,openEuler.repo的内容如下: + + ```text + [base] + name=base + baseurl=file:///home/openEuler/srv/repo + enabled=1 + gpgcheck=1 + gpgkey=file:///home/openEuler/srv/repo/RPM-GPG-KEY-openEuler + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > + > - \[*repoid*\]中的repoid为软件仓库(repository)的ID号,所有.repo配置文件中的各repoid不能重复,必须唯一。示例中repoid设置为**base**。 + > - name为软件仓库描述的字符串。 + > - baseurl为软件仓库的地址。 + > - enabled为是否启用该软件源仓库,可选值为1和0。缺省值为1,表示启用该软件源仓库。 + > - gpgcheck可设置为1或0,1表示进行gpg(GNU Private Guard)校验,0表示不进行gpg校验,gpgcheck可以确定rpm包的来源是有效和安全的。 + > - gpgkey为验证签名用的公钥。 + +- 配置http服务器yum源 + + 在/etc/yum.repos.d目录下创建openEuler.repo文件。 + + - 若使用用户部署的http服务端的repo源作为yum源,openEuler.repo的内容如下: + + ```text + [base] + name=base + baseurl=http://192.168.139.209/ + enabled=1 + gpgcheck=1 + gpgkey=http://192.168.139.209/RPM-GPG-KEY-openEuler + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > “192.168.139.209”为示例地址,请用户根据实际情况进行配置。 + + - 若使用openEuler提供的openEuler repo源作为yum源,以openEuler-24.03-LTS-SP1版本的AArch64架构的OS repo源为例,openEuler.repo的内容如下: + + ```text + [base] + name=base + baseurl=http://repo.openeuler.org/openEuler-24.03-LTS-SP1/OS/aarch64/ + enabled=1 + gpgcheck=1 + gpgkey=http://repo.openeuler.org/openEuler-24.03-LTS-SP1/OS/aarch64/RPM-GPG-KEY-openEuler + ``` + +### repo优先级 + +当有多个repo源时,可通过在.repo文件的priority参数设置repo的优先级(如果不设置,默认优先级是99,当相同优先级的源中存在相同rpm包时,会安装最新的版本)。其中,1为最高优先级,99为最低优先级,如给openEuler.repo配置优先级为2: + +```text +[base] +name=base +baseurl=http://192.168.139.209/ +enabled=1 +priority=2 +gpgcheck=1 +gpgkey=http://192.168.139.209/RPM-GPG-KEY-openEuler +``` + +### dnf相关命令 + +dnf命令在安装升级时能够自动解析包的依赖关系,一般的使用方式如下: + +```shell +dnf +``` + +常用的命令如下: + +- 安装,需要在root权限下执行。 + + ```shell + # dnf install + ``` + +- 升级,需要在root权限下执行。 + + ```shell + # dnf update + ``` + +- 回退,需要在root权限下执行。 + + ```shell + # dnf downgrade + ``` + +- 检查更新 + + ```shell + # dnf check-update + ``` + +- 卸载,需要在root权限下执行。 + + ```shell + # dnf remove + ``` + +- 查询 + + ```shell + # dnf search + ``` + +- 本地安装,需要在root权限下执行。 + + ```shell + # dnf localinstall + ``` + +- 查看历史记录 + + ```shell + # dnf history + ``` + +- 清除缓存目录 + + ```shell + # dnf clean all + ``` + +- 更新缓存 + + ```shell + # dnf makecache + ``` diff --git a/docs/en/25.03/Server/Administration/Administrator/configuring-the-web-server.md b/docs/en/25.03/Server/Administration/Administrator/configuring-the-web-server.md new file mode 100644 index 0000000000000000000000000000000000000000..4fed7d46a18f2c6231a71a48d71275c3c0b2a6f2 --- /dev/null +++ b/docs/en/25.03/Server/Administration/Administrator/configuring-the-web-server.md @@ -0,0 +1,498 @@ +# 搭建web服务器 + +## Apache服务器 + +### 概述 + +Web(World Wide Web)是目前最常用的Internet协议之一。目前在Unix-Like系统中的web服务器主要通过Apache服务器软件实现。为了实现运营动态网站,产生了LAMP(Linux + Apache +MySQL + PHP)。web服务可以结合文字、图形、影像以及声音等多媒体,并支持超链接(Hyperlink)的方式传输信息。 + +openEuler系统中的web服务器版本是Apache HTTP服务器2.4版本,即httpd,一个由Apache软件基金会发展而来的开源web服务器。 + +### 管理httpd + +#### 概述 + +通过systemctl工具,可以对httpd服务进行管理,包括启动、停止、重启服务,以及查看服务状态等。本章介绍Apache HTTP服务的管理操作,以指导用户使用。 + +#### 前提条件 + +- 为了能够使用Apache HTTP服务,请确保您的系统中已经安装httpd服务的rpm包。在root权限下执行如下命令进行安装: + + ```shell + # dnf install httpd + ``` + + 更多关于管理服务的内容,请参见[管理服务](./service-management.md)。 + +- 启动、停止和重启httpd服务,需要使用root权限。 + +#### 启动服务 + +- 启动并运行httpd服务,命令如下: + + ```shell + # systemctl start httpd + ``` + +- 假如希望在系统启动时,httpd服务自动启动,则命令和回显如下: + + ```shell + # systemctl enable httpd + Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service. + ``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 假如正在运行的Apache HTTP服务器作为一个安全服务器,系统开机启动后需要密码,这个密码使用的是加密的私有SSL密钥。 + +#### 停止服务 + +- 停止运行的httpd服务,命令如下: + + ```shell + # systemctl stop httpd + ``` + +- 如果希望防止服务在系统开机阶段自动开启,命令和回显如下: + + ```shell + # systemctl disable httpd + Removed /etc/systemd/system/multi-user.target.wants/httpd.service. + ``` + +#### 重启服务 + +重启服务有三种方式: + +- 完全重启服务 + + ```shell + # systemctl restart httpd + ``` + + 该命令会停止运行的httpd服务并且立即重新启动它。一般在服务安装以后或者去除一个动态加载的模块(例如PHP)时使用这个命令。 + +- 重新加载配置 + + ```shell + # systemctl reload httpd + ``` + + 该命令会使运行的httpd服务重新加载它的配置文件。任何当前正在处理的请求将会被中断,从而造成客户端浏览器显示一个错误消息或者重新渲染部分页面。 + +- 重新加载配置而不影响激活的请求 + + ```shell + # apachectl graceful + ``` + + 该命令会使运行的httpd服务重新加载它的配置文件。任何当前正在处理的请求将会继续使用旧的配置文件。 + +#### 验证服务状态 + +验证httpd服务是否正在运行 + +```shell +# systemctl is-active httpd +``` + +回显为“active”说明服务处于运行状态。 + +### 配置文件说明 + +当httpd服务启动后,默认情况下它会读取如[表1](#table24341012096)所示的配置文件。 + +**表 1** 配置文件说明 + + + + + + + + + + + + + +

文件

+

说明

+

/etc/httpd/conf/httpd.conf

+

主要的配置文件

+

/etc/httpd/conf.d

+

配置文件的辅助目录,这些配置文件也被包含在主配置文件当中

+

一个配置文件的辅助目录被包含在主要的配置文件中

+
+ +虽然默认配置可以适用于多数情况,但是用户至少需要熟悉里面的一些重要配置项。配置文件修改完成后,可以在root权限下使用如下命令检查配置文件可能出现的语法错误。 + +```shell +# apachectl configtest +``` + +如果回显如下,说明配置文件语法正确。 + +```text +Syntax OK +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 在修改配置文件之前,请先备份原始文件,以便出现问题时能够快速恢复配置文件。 +> 需要重启web服务,才能使修改后的配置文件生效。 + +### 管理模块和SSL + +#### 概述 + +httpd服务是一个模块化的应用,它和许多动态共享对象DSO(Dynamic Shared Objects)一起分发。动态共享对象DSO,在必要情况下,可以在运行时被动态加载或卸载。服务器操作系统中这些模块位于/usr/lib64/httpd/modules/目录下。本节介绍如何加载和写入模块。 + +#### 加载模块 + +为了加载一个特殊的DSO模块,在配置文件中使用加载模块指示。独立软件包提供的模块一般在/etc/httpd/conf.modules.d目录下有他们自己的配置文件。 + +例如,加载asis DSO模块的操作步骤如下: + +1. 在/etc/httpd/conf.modules.d/00-optional.conf文件中,使用root权限取消注释如下配置行。 + + ```shell + LoadModule asis_module modules/mod_asis.so + ``` + +2. 加载完成后,请使用root权限重启httpd服务以便于重新加载配置文件。 + + ```shell + # systemctl restart httpd + ``` + +3. 加载完成后,在root权限下使用httpd -M的命令查看是否已经加载了asis DSO模块。 + + ```shell + # httpd -M | grep asis + ``` + + 回显如下,说明asis DSO模块加载成功。 + + ```text + asis_module (shared) + ``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> **httpd 的常用命令:** +> httpd -v : 查看httpd的版本号。 +> httpd -l:查看编译进httpd程序的静态模块。 +> httpd -M:查看已经编译进httpd程序的静态模块和已经加载的动态模块。 + +#### SSL介绍 + +安全套接层SSL(Secure Sockets Layer)是一个允许服务端和客户端之间进行安全通信的加密协议。其中,传输层安全性协议TLS(Transport Layer Security)为网络通信提供了安全性和数据完整性保障。openEuler支持Mozilla NSS(Network Security Services)作为安全性协议TLS进行配置。加载SSL的操作步骤如下: + +1. 在root权限下安装mod\_ssl的rpm包。 + + ```shell + # dnf install mod_ssl + ``` + +2. 安装完成后,请在root权限下重启httpd服务以便于重新加载配置文件。 + + ```shell + # systemctl restart httpd + ``` + +3. 加载完成后,在root权限下使用httpd -M的命令查看是否已经加载了SSL。 + + ```shell + # httpd -M | grep ssl + ``` + + 回显如下,说明SSL已加载成功。 + + ```text + ssl_module (shared) + ``` + +### 验证web服务是否搭建成功 + +Web服务器搭建完成后,可以通过如下方式验证是否搭建成功。 + +1. 在root权限下查看服务器的IP地址,命令如下: + + ```shell + # ip a + + ``` + +2. 在root权限下配置防火墙: + + ```shell + # firewall-cmd --add-service=http --permanent + success + # firewall-cmd --reload + success + ``` + +3. 验证web服务器是否搭建成功,用户可选择Linux或Windows系统进行验证。 + - 使用Linux系统验证 + + 执行如下命令,查看是否可以访问网页信息,服务搭建成功时,该网页可以正常访问。 + + ```shell + # curl http://192.168.1.60 + ``` + + 执行如下命令,查看命令返回值是否为0,返回值为0,说明httpd服务器搭建成功。 + + ```shell + # echo $? + ``` + + - 使用Windows系统验证 + + 打开浏览器,在地址栏输入如下地址,如果能正常访问网页,说明httpd服务器搭建成功。 + + + + 如果修改了端口号,输入地址格式如下: + + + +## Nginx服务器 + +### 概述 + +Nginx 是一款轻量级的 Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,其特点是占有内存少,并发能力强,支持FastCGI、SSL、Virtual Host、URL Rewrite、Gzip等功能,并且支持很多第三方的模块扩展。 + +### 安装 + +1. 配置本地yum源,详细信息请参考[搭建repo服务器](./configuring-the-repo-server.md)。 +2. 清除缓存。 + + ```shell + # dnf clean all + ``` + +3. 创建缓存。 + + ```shell + # dnf makecache + ``` + +4. 在root权限下安装nginx服务。 + + ```shell + # dnf install nginx + ``` + +5. 查看安装后的rpm包。 + + ```shell + # dnf list all | grep nginx + ``` + +### 管理nginx + +#### 概述 + +通过systemctl工具,可以对nginx服务进行管理,包括启动、停止、重启服务,以及查看服务状态等。本章介绍nginx服务的管理操作,以指导用户使用。 + +#### 前提条件 + +- 为了能够使用nginx服务,请确保您的系统中已经安装nginx服务。若未安装,可参考[安装](#安装)进行安装。 + +- 更多关于管理服务的内容,请参见[管理服务](./service-management.md)。 + +- 启动、停止和重启nginx服务,需要使用root权限。 + +#### 启动服务 + +- 启动并运行nginx服务,命令如下: + + ```shell + # systemctl start nginx + ``` + +- 假如希望在系统启动时,nginx服务自动启动,则命令和回显如下: + + ```shell + # systemctl enable nginx + Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service. + ``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 假如正在运行的nginx服务器作为一个安全服务器,系统开机启动后需要密码,这个密码使用的是加密的私有SSL密钥。 + +#### 停止服务 + +- 停止运行的nginx服务,命令如下: + + ```shell + # systemctl stop nginx + ``` + +- 如果希望防止服务在系统开机阶段自动开启,命令和回显如下: + + ```shell + # systemctl disable nginx + Removed /etc/systemd/system/multi-user.target.wants/nginx.service. + ``` + +#### 重启服务 + +重启服务有三种方式: + +- 完全重启服务 + + ```shell + # systemctl restart nginx + ``` + + 该命令会停止运行的nginx服务并且立即重新启动它。一般在服务安装以后或者去除一个动态加载的模块(例如PHP)时使用这个命令。 + +- 重新加载配置 + + ```shell + # systemctl reload nginx + ``` + + 该命令会使运行的nginx服务重新加载它的配置文件。任何当前正在处理的请求将会被中断,从而造成客户端浏览器显示一个错误消息或者重新渲染部分页面。 + +- 平滑重启nginx + + ```shell + # kill -HUP 主进程ID + ``` + + 该命令会使运行的nginx服务重新加载它的配置文件。任何当前正在处理的请求将会继续使用旧的配置文件。 + +#### 验证服务状态 + +验证nginx服务是否正在运行 + +```shell +# systemctl is-active nginx +``` + +回显为“active”说明服务处于运行状态。 + +### 配置文件说明 + +当nginx服务启动后,默认情况下它会读取如[表2](#table24341012096)所示的配置文件。 + +**表 2** 配置文件说明 + + + + + + + + + + + + + +

文件

+

说明

+

/etc/nginx/nginx.conf

+

主要的配置文件

+

/etc/nginx/conf.d

+

配置文件的辅助目录,这些配置文件也被包含在主配置文件当中

+

一个配置文件的辅助目录被包含在主要的配置文件中

+
+ +虽然默认配置可以适用于多数情况,但是用户至少需要熟悉里面的一些重要配置项。配置文件修改完成后,可以在root权限下使用如下命令检查配置文件可能出现的语法错误。 + +```shell +# nginx -t +``` + +如果回显信息中有“syntax is ok”,说明配置文件语法正确。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 在修改配置文件之前,请先备份原始文件,以便出现问题时能够快速恢复配置文件。 +> 需要重启web服务,才能使修改后的配置文件生效。 + +### 管理模块 + +#### 概述 + +nginx服务是一个模块化的应用,它和许多动态共享对象DSO(Dynamic Shared Objects)一起分发。动态共享对象DSO,在必要情况下,可以在运行时被动态加载或卸载。服务器操作系统中这些模块位于/usr/lib64/nginx/modules/目录下。本节介绍如何加载和写入模块。 + +#### 加载模块 + +为了加载一个特殊的DSO模块,在配置文件中使用加载模块指示。独立软件包提供的模块一般在/usr/share/nginx/modules目录下有他们自己的配置文件。 + +openEuler操作系统中使用dnf install nginx安装nginx时会自动加载DSO。 + +### 验证web服务是否搭建成功 + +Web服务器搭建完成后,可以通过如下方式验证是否搭建成功。 + +1. 在root权限下查看服务器的IP地址,命令如下: + + ```shell + # ip a + ``` + + 回显信息如下,说明服务器IP为 192.168.1.60。 + + ```text + enp3s0: flags=4163 mtu 1500 + inet 192.168.1.60 netmask 255.255.255.0 broadcast 192.168.1.255 + inet6 fe80::5054:ff:fe95:499f prefixlen 64 scopeid 0x20 + ether 52:54:00:95:49:9f txqueuelen 1000 (Ethernet) + RX packets 150713207 bytes 49333673733 (45.9 GiB) + RX errors 0 dropped 43 overruns 0 frame 0 + TX packets 2246438 bytes 203186675 (193.7 MiB) + TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 + + enp4s0: flags=4163 mtu 1500 + ether 52:54:00:7d:80:9e txqueuelen 1000 (Ethernet) + RX packets 149937274 bytes 44652889185 (41.5 GiB) + RX errors 0 dropped 1102561 overruns 0 frame 0 + TX packets 0 bytes 0 (0.0 B) + TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 + + lo: flags=73 mtu 65536 + inet 127.0.0.1 netmask 255.0.0.0 + inet6 ::1 prefixlen 128 scopeid 0x10 + loop txqueuelen 1000 (Local Loopback) + RX packets 37096 bytes 3447369 (3.2 MiB) + RX errors 0 dropped 0 overruns 0 frame 0 + TX packets 37096 bytes 3447369 (3.2 MiB) + TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 + ``` + +2. 在root权限下配置防火墙: + + ```shell + # firewall-cmd --add-service=http --permanent + success + # firewall-cmd --reload + success + ``` + +3. 验证web服务器是否搭建成功,用户可选择Linux或Windows系统进行验证。 + - 使用Linux系统验证 + + 执行如下命令,查看是否可以访问网页信息,服务搭建成功时,该网页可以正常访问。 + + ```shell + # curl http://192.168.1.60 + ``` + + 执行如下命令,查看命令返回值是否为0,返回值为0,说明nginx服务器搭建成功。 + + ```shell + # echo $? + ``` + + - 使用Windows系统验证 + + 打开浏览器,在地址栏输入如下地址,如果能正常访问网页,说明nginx服务器搭建成功。 + + + + 如果修改了端口号,输入地址格式如下: + + diff --git a/docs/en/25.03/Server/Administration/Administrator/faqs.md b/docs/en/25.03/Server/Administration/Administrator/faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..746cec8056689834ca9a15f83f950cfeb3a4afe6 --- /dev/null +++ b/docs/en/25.03/Server/Administration/Administrator/faqs.md @@ -0,0 +1,391 @@ +# 常见问题与解决方法 + +## **问题1:使用systemctl和top命令查询libvirtd服务占用内存不同** + +### 问题描述 + +使用systemctl和systemd-cgtop命令查询libvirtd服务占用内存超1.5G,而使用top命令查询libvirtd服务占用内存仅70M左右。 + +### 原因分析 + +systemd管理的服务(包括systemctl和systemd-cgtop)中显示的内存通过查询CGroup对应的memory.usage\_in\_bytes得到。top是直接统计/proc下内存相关信息计算得出。两者的统计方法不同,不能直接比较。 + +一般来说,业务进程使用的内存主要有以下几种情况: + +- anon\_rss:用户空间的匿名映射页(Anonymous pages in User Mode address spaces),比如调用malloc分配的内存,以及使用MAP\_ANONYMOUS的mmap。当系统内存不够时,内核可以将这部分内存交换出去。 +- file\_rss:用户空间的文件映射页(Mapped pages in User Mode address spaces),包含map file和map tmpfs,前者比如指定文件的mmap,后者比如IPC共享内存。当系统内存不够时,内核可以回收这些页,但回收之前可能需要与文件同步数据。 +- file\_cache:文件缓存(page in page cache of disk file),普通读写(read/write)文件时产生的文件缓存。当系统内存不够时,内核可以回收这些页,但回收之前可能需要与文件同步数据。 +- buffer pages:属于page cache,比如读取块设备文件时的相关缓存。 + +其中anon\_rss和file\_rss属于进程的RSS,file\_cache和buffer pages属于page cache。简单来说: + +top里的RSS = anon\_rss + file\_rss,SHR = file\_rss。 + +CGroup里的memory.usage\_in\_bytes = cache + RSS + swap。 + +由上可知,syestemd相关命令和top命令的内存占用率含义不同,所以查询结果不同。 + +## **问题2:设置RAID0卷,参数stripsize设置为4时出错** + +### 问题现象 + +设置RAID0卷,参数stripsize设置为4时出错。 + +### 原因分析 + +64K页表开启只能支持64K场景。 + +### 解决方法 + +不需要修改配置文件,openEuler执行lvcreate命令时,条带化规格支持的stripesize最小值为64KB,将参数stripesize设置为64。 + +## **问题3:使用rpmbuild编译mariadb失败** + +### 问题描述 + +如果使用root帐号登录系统,并在该帐号下使用rpmbuild命令编译mariadb源代码,会出现编译失败现象,提示: + +```shell +# echo 'mysql can'\''t run test as root' +mysql can't run test as root +# exit 1 +``` + +### 原因分析 + +mariadb数据库不允许使用root权限的帐号进行测试用例执行,所以会阻止编译过程(编译过程中会自动执行测试用例)。 + +### 解决方案 + +使用vi等文本编辑工具,修改mariadb.spec文件中runtest变量的值。 + +修改前: + +```text +%global runtest 1 +``` + +修改后: + +```text +%global runtest 0 +``` + +该修改关闭了编译阶段执行测试用例的功能,但不会影响编译和编译后的RPM包内容。 + +## **问题4:使用默认配置启动SNTP服务失败** + +### 问题现象 + +默认配置情况下SNTP服务启动失败。 + +### 原因分析 + +默认配置中未添加授时服务器域名。 + +### 解决方案 + +修改/etc/sysconfig/sntp文件 ,在文件中添加中国NTP快速授时服务器域名:0.generic.pool.ntp.org。 + +## **问题5:安装时出现软件包冲突、文件冲突或缺少软件包导致安装失败** + +### 问题现象 + +安装软件包过程中,可能出现软件包冲突、文件冲突或缺少软件包,从而导致升安装被中断,最终安装失败。软件包冲突、文件冲突和缺少软件包的报错信息分别如下所示。 + +软件包冲突报错信息示例(以 libev-libevent-devel-4.24-11.oe1.aarch64与libevent-devel-2.1.11-2.oe1.aarch64冲突为例): + +```text +package libev-libevent-devel-4.24-11.oe1.aarch64 conflicts with libevent-devel provided by libevent-devel-2.1.11-2.oe1.aarch64 + - cannot install the best candidate for the job + - conflicting requests +``` + +文件冲突报错信息示例(以/usr/bin/containerd文件冲突为例): + +```text +Error: Transaction test error: + file /usr/bin/containerd from install of containerd-1.2.0-101.oe1.aarch64 conflicts with file from package docker-engine-18.09.0-100.aarch64 + file /usr/bin/containerd-shim from install of containerd-1.2.0-101.oe1.aarch64 conflicts with file from package docker-engine-18.09.0-100.aarch64 +``` + +缺少软件包的报错信息示例(以缺失blivet-data软件包为例): + +```text +Error: + Problem: cannot install both blivet-data-1:3.1.1-6.oe1.noarch and blivet-data-1:3.1.1-5.noarch + - package python2-blivet-1:3.1.1-5.noarch requires blivet-data = 1:3.1.1-5, but none of the providers can be installed + - cannot install the best update candidate for package blivet-data-1:3.1.1-5.noarch + - problem with installed package python2-blivet-1:3.1.1-5.noarch(try to add '--allowerasing' to command line to replace conflicting packages or '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages) +``` + +### 原因分析 + +- openEuler提供的软件包中,有些软件包虽然名称不同,但功能相同,导致两个软件包无法同时安装。 +- openEuler提供的软件包中,有些软件包虽然名称不同,但功能相同,导致安装时安装后的文件相同,从而产生了文件冲突。 +- 有些软件包,因在升级安装前被其他软件包所依赖,一旦该软件包升级后,可能导致依赖它的软件包因缺少软件包而不能安装。 + +### 解决方案 + +若为软件包冲突,则按如下步骤进行处理(以问题现象中示例的软件包冲突为例): + +1. 根据安装过程中的软件包冲突报错信息,确定与待安装的 libev-libevent-devel-4.24-11.oe1.aarch64软件包冲突的软件包为libevent-devel-2.1.11-2.oe1.aarch64。 +2. 执行**dnf remove**命令将与待安装软件包冲突的软件包单独卸载。 + + ```shell + # dnf remove libevent-devel-2.1.11-2.oe1.aarch64 + ``` + +3. 重新进行安装操作。 + +若为文件冲突,则按如下步骤进行处理(以问题现象中示例的文件冲突为例): + +1. 根据安装过程中的文件冲突报错信息,确定导致文件冲突的软件包名称为containerd-1.2.0-101.oe1.aarch64和docker-engine-18.09.0-100.aarch64。 +2. 将不需要安装的软件包名称记录下来,以不需要安装docker-engine-18.09.0-100.aarch64为例。 +3. 执行**dnf remove**命令将不需要安装的软件包单独卸载。 + + ```shell + # dnf remove docker-engine-18.09.0-100.aarch64 + ``` + +4. 重新进行安装操作。 + +若为缺少软件包,则按如下步骤进行处理(以问题现象中示例的缺少软件包为例): + +1. 根据升级安装过程中的缺少软件包报错信息,确定待升级的软件包名称blivet-data-1:3.1.1-5.noarch及依赖它的软件包名称python2-blivet-1:3.1.1-5.noarch。 +2. 执行dnf remove命令将依赖待升级包才能安装的软件包单独卸载或在升级软件包时加上\-\-allowerasing参数。 + - 执行**dnf remove**命令将依赖blivet-data-1:3.1.1-5.noarch软件包才能安装的软件包单独卸载。 + + ```shell + # dnf remove python2-blivet-1:3.1.1-5.noarch + ``` + + - 升级软件包时加上\-\-allowerasing参数。 + + ```shell + # yum update blivet-data-1:3.1.1-5.noarch -y --allowerasing + ``` + +3. 重新进行升级操作。 + +### 安装冲突实例 + +- 文件冲突 + + python3-edk2-devel.noarch 与 build.noarch 因文件名重复存在冲突。 + + ```shell + # yum install python3-edk2-devel.noarch build.noarch + ... + Error: Transaction test error: + file /usr/bin/build conflicts between attempted installs of python3-edk2-devel-202002-3.oe1.noarch and build-20191114-324.4.oe1.noarch + ``` + +## **问题6:libiscsi降级失败** + +### 问题现象 + +libiscsi-1.19.0-4 版本及以上降级到 libiscsi-1.19.0-3 及以下版本时失败。 + +```text +Error: +Problem: problem with installed package libiscsi-utils-1.19.0-4.oe1.x86_64 +- package libiscsi-utils-1.19.0-4.oe1.x86_64 requires libiscsi(x86-64) = 1.19.0-4.oe1, but none of the providers can be installed +- cannot install both libiscsi-1.19.0-3.oe1.x86_64 and libiscsi-1.19.0-4.oe1.x86_64 +- cannot install both libiscsi-1.19.0-4.oe1.x86_64 and libiscsi-1.19.0-3.oe1.x86_64 +- conflicting requests +(try to add '--allowerasing' to command line to replace conflicting packages or '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages) +``` + +### 原因分析 + +libiscsi-1.19.0-3 之前的版本把 iscsi-xxx 等二进制文件打包进了主包 libiscsi,而这些二进制文件引入了不合理的依赖 CUnit, 为了解决这种不合理的依赖,在 libiscsi-1.19.0-4 版本把这些二进制文件单独拆分出来一个子包 libiscsi-utils,主包弱依赖于子包,产品可以根据自己的需求在做镜像时是否集成该子包;不集成或卸载子包不会影响 libiscsi 主包的功能。 +如果系统中安装了 libiscsi-utils 子包,libiscsi-1.19.0-4 及以上版本降级到 libiscsi-1.19.0-3 及以下版本时,由于 libiscsi-1.19.0-3 及以下版本无法提供对应的 libiscsi-utils,因此 libiscsi-utils 不会降级,但 libiscsi-utils 依赖于降级前的 libiscsi 主包,导致依赖问题无法解决,最终导致降级失败。 + +### 解决方案 + +执行以下命令,卸载 libiscsi-utils 子包,卸载成功后再进行降级操作。 + +```text +yum remove libiscsi-utils +``` + +## **问题7:xfsprogs降级失败** + +### 问题现象 + +xfsprogs-5.6.0-2 及以上版本降级到 xfsprogs-5.6.0-1 及以下版本时失败。 + +```text +Error: +Problem: problem with installed package xfsprogs-xfs_scrub-5.6.0-2.oe1.x86_64 +- package xfsprogs-xfs_scrub-5.6.0-2.oe1.x86_64 requires xfsprogs = 5.6.0-2.oe1, but none of the providers can be installed +- cannot install both xfsprogs-5.6.0-1.oe1.x86_64 and xfsprogs-5.6.0-2.oe1.x86_64 +- cannot install both xfsprogs-5.6.0-2.oe1.x86_64 and xfsprogs-5.6.0-1.oe1.x86_64 +- conflicting requests +``` + +### 原因分析 + +在 xfsprogs-5.6.0-2 版本中,为了减少 xfsprogs 主包的不合理依赖,同时将实验性质的命令从主包中分来,我们将 xfs_scrub* 命令拆分到单独的 xfsprogs-xfs_scrub 子包中。而 xfsprogs 主包弱依赖于 xfsprogs-xfs_scrub 子包,所以产品可以根据自己的需求在做镜像时是否集成该子包,或者是否卸载该子包。不集成或卸载该子包不会影响 xfsprogs 主包功能。 + +如果系统中安装了 xfsprogs-xfs_scrub 子包,从 xfsprogs-5.6.0-2 及以上版本降级到 xfsprogs-5.6.0-1 及以下版本时,由于 xfsprogs-5.6.0-1 及以下版本无法提供对应的 xfsprogs-xfs_scrub,因此 xfsprogs-xfs_scrub 不会降级,但 xfsprogs-xfs_scrub 依赖于降级前的 xfsprogs 主包,导致依赖问题无法解决,最终导致降级失败。 + +### 解决方案 + +执行以下命令,卸载 xfsprogs-xfs_scrub 子包,卸载成功后再进行降级操作。 + +```shell +# yum remove xfsprogs-xfs_scrub +``` + +## **问题8:elfutils降级失败** + +### 问题现象 + +elfutils降级缺少依赖,导致无法降级。 + +![](figures/1665628542704.png) + +### 原因分析 + +22.03-LTS、22.03-LTS-Next分支:elfutils-0.185-12 + +master分支:elfutils-0.187-7 + +20.03-LTS-SP1分支:elfutils-0.180-9 + +如上版本,elfutils主包提供的eu-objdump、eu-readelf、eu-nm命令拆分到elfutils-extra子包中。当系统已安装elfutils-extra,且elfutils进行降级时,由于低版本(如上分支版本)无法提供对应的elfutils-extra包,因此elfutils-extra子包不会降级(elfutils-extra依赖于降级前的elfutils包),导致依赖问题无法解决,最终elfutils降级失败。 + +### 解决方案 + +执行以下命令,先卸载elfutils-extra包,再进行降级操作。 + +```shell +# yum remove -y elfutils-extra +``` + +## **问题9:cpython/Lib发现CVE-2019-9674:Zip炸弹漏洞** + +### 问题现象 + +Python 3.7.2 及以下版本中的 Lib/zipfile.py 允许远程攻击者通过 zip 炸弹制造拒绝服务请求,从而导致资源消耗过大。 + +### 原因分析 + +远程攻击者通过 zip 炸弹导致拒绝服务,影响目标系统业务甚至达到使系统崩溃的结果。zip 炸弹就是一个高压缩比的 zip 文件,它本身可能只有几M或几十M的大小,但是解压缩之后会产生巨大的数据量,产生巨大的资源消耗。 + +### 解决方案 + +在 zipfile 文档中添加告警信息: + +## **问题10:不合理使用glibc正则表达式引起ReDoS攻击** + +### 问题现象 + +使用glibc的regcomp/regexec接口编程,或者grep/sed等应用glibc正则表达式的shell命令,不合理的正则表达式或输入会造成ReDoS攻击(CVE-2019-9192/CVE-2018-28796)。 +典型正则表达式pattern为“反向引用”(\1表示)与“*”(匹配零次或多次)、“+”(匹配一次或多次)、“{m,n}”(最小匹配m次,最多匹配n次)的组合,或者配合超长字符串输入,示例如下: + +```shell +# echo D | grep -E "$(printf '(\0|)(\\1\\1)*')"Segmentation fault (core dumped) +# grep -E "$(printf '(|)(\\1\\1)*')" +Segmentation fault (core dumped) +# echo A | sed '/\(\)\(\1\1\)*/p' +Segmentation fault (core dumped) +# time python -c 'print "a"*40000' | grep -E "a{1,32767}" +Segmentation fault (core dumped) +# time python -c 'print "a"*40900' | grep -E "(a)\\1" +Segmentation fault (core dumped) +``` + +### 原因分析 + +使用正则表达式的进程coredump。具体原因为glibc正则表达式的实现为NFA/DFA混合算法,内部原理是使用贪婪算法进行递归查找,目的是尽可能匹配更多的字符串,贪婪算法在处理递归正则表达式时会导致ReDoS。 + +### 解决方案 + +1. 需要对用户做严格的权限控制,减少攻击面。 +2. 用户需保证正则表达式的正确性,不输入无效正则表达式,或者超长字符串配合正则的“引用” “*”等容易触发无限递归的组合。 + + ```shell + # ()(\1\1)* + # "a"*400000 + ``` + +3. 用户程序在检测到进程异常之后,通过重启进程等手段恢复业务,提升程序的可靠性。 + +## **问题11:安装卸载httpd-devel和apr-util-devel软件包,其中的依赖包gdbm-devel安装、卸载有报错** + +### 问题现象 + +1. gdbm-devel-1.18.1-1包安装、卸载有报错; +2. 问题1修复后,gdbm和gdbm-devel包更新到1.18.1-2版本,但在安装httpd-devel、apr-util-devel等包(依赖关系中有gdbm-devel软件包)时,默认安装的gdbm-devel还是1.18.1-1旧版本,导致问题报错依然存在。 + +### 原因分析 + +1. gdbm-devel-1.18.1-1包中缺少提供info信息的help软件包,导致单独安装gdbm-devel并不能将help包引入进来,所以出现了如下告警信息。 + + ```text + install-info: 没有那个文件或目录 for /usr/share/info/gdbm.info.gz + ``` + +2. 由于系统默认安装的gdbm主包是1.18.1-1版本,而没有安装gdbm-devel包。依赖gdbm-devel包的相关软件包在安装gdbm-devel包的过程中,仍会匹配gdbm的主包版本,故而依然安装了gdbm-devel的旧版本1.18.1-1,导致警告信息依然存在。 + +### 解决方案 + +1. 单包升级gdbm,安装使用gdbm-1.18.1-2版本相关软件包后,告警信息消失; +2. 在单包升级gdbm后,再进行安装依赖的gdbm-devel软件包安装,让其依赖高版本gdbm软件包,告警信息消失。 + +## **问题12:系统reboot后,执行yum/dnf等命令报错,提示rpmdb error** + +### 问题现象 + +1. reboot系统,重启后,执行rpm相关命令(yum/dnf)提示: + error: db5 error(-30973) from dbenv->open: BDB0087 DB_RUNRECOVERY: Fatal error, run database recovery + error: cannot open Packages index using db5 - (-30973) + error: cannot open Packages database in /var/lib/rpm + Error: Error: rpmdb open failed + +### 原因分析 + +1. 执行安装升级动作过程中,会对/var/lib/rpm/__db.00*文件进行读写操作,如果在运行中出现强制下电、磁盘空间满或者 ‘kill -9’ 等异常中断操作,会导致对应_db文件损坏,后续执行rpm相关命令(dnf/yum)会发生报错 + +### 解决方案 + +步骤1 执行`kill -9`停止所有正在运行的rpm命令。 +步骤2 执行`rm -rf /var/lib/rpm/__db.00*`删除所有db.00的文件。 +步骤3 执行`rpmdb --rebuilddb`命令,重建rpm db后即可。 + +## **问题13:执行 rpmrebuild -d /home/test filesystem对filesystem包rebuild时,rebuild失败** + +### 问题现象 + +执行 rpmrebuild --comment-missing=y --keep-perm -b -d /home/test filesystem-3.16-3.oe1.aarch64对filesystem包rebuild时,rebuild失败. +/usr/lib/rpmrebuild/rpmrebuild.sh:Error:(RpmBuild) Package 'filesystem-3.16-3.oe1.aarch64' build failed. +/usr/lib/rpmrebuild/rpmrebuild.sh:Error: RpmBuild + +### 原因分析 + +软件包在%pretrans -p阶段创建目录,并在%ghost阶段对该目录进行修饰,如果用户在该目录下创建目录或文件,执行rpmrebuild对该包进行打包,发现创建的目录或文件也会打包到该包中。 + +上述问题的根本原因是因为filesystem在%pretrans阶段创建了/proc目录,并在%ghost阶段对该目录进行了修饰,但是该目录在系统运行时会动态的创建一些微量进程,这些进程非目录也非文件,在执行rpmrebuild的时无法对这些进程进行打包,所以rebuild失败。 + +### 解决方案 + +暂时不使用rpmrebuild命令对filesystem进行rebuild。 + +## **问题14:带参数f执行modprobe或insmod报错** + +### 问题现象 + +执行`modprobe -f `或`insmod -f .ko.xz`报错,比如`insmod -f xfs.ko.xz`报错:`modprobe: ERROR: could not insert 'xfs': Key was rejected by service`。 + +迄今为止(2022.09.20, kmod v30),该问题尚未被kmod社区修复。Linux v5.17 [b1ae6dc](https://github.com/torvalds/linux/commit/b1ae6dc41eaaa98bb75671e0f3665bfda248c3e7)添加了对压缩内核模块的支持,kmod尚未支持该特性。 + +### 原因分析 + +对于未经压缩的ko,`{modprobe, insmod}`使用`finit_module()`系统调用,而对于压缩的ko,解压由kmod完成,使用`init_module()`系统调用。系统调用`init_module()`无法传入ignore check的flag,导致内核执行路径中`mod_verify_sig()`始终进入,并且`{modprobe, insmod} -f`参数会更改ko有关的校验信息,导致`mod_verify_sig()`校验失败。 + +### 解决方案 + +对压缩了的ko不使用`{insmod, modprobe} -f`。 diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/1665628542704.png b/docs/en/25.03/Server/Administration/Administrator/figures/1665628542704.png new file mode 100644 index 0000000000000000000000000000000000000000..58907e0ed31c79b260be80480d4fd4c27e4e2e24 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/1665628542704.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/D1376B2A-D036-41C4-B852-E8368F363B5E-1.png b/docs/en/25.03/Server/Administration/Administrator/figures/D1376B2A-D036-41C4-B852-E8368F363B5E-1.png new file mode 100644 index 0000000000000000000000000000000000000000..900cdc07c1f0e844bc48fe2342e83c91a23c24ec Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/D1376B2A-D036-41C4-B852-E8368F363B5E-1.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/D1376B2A-D036-41C4-B852-E8368F363B5E.png b/docs/en/25.03/Server/Administration/Administrator/figures/D1376B2A-D036-41C4-B852-E8368F363B5E.png new file mode 100644 index 0000000000000000000000000000000000000000..900cdc07c1f0e844bc48fe2342e83c91a23c24ec Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/D1376B2A-D036-41C4-B852-E8368F363B5E.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/PostgreSql_architecture.png b/docs/en/25.03/Server/Administration/Administrator/figures/PostgreSql_architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..f780ad9cb56378e7baa3497da68ca1610a6dfadb Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/PostgreSql_architecture.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/creat_datadisk.png b/docs/en/25.03/Server/Administration/Administrator/figures/creat_datadisk.png new file mode 100644 index 0000000000000000000000000000000000000000..0dfd6a2802184af6d809c485191ea52452cf28d5 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/creat_datadisk.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/creat_datadisk1.png b/docs/en/25.03/Server/Administration/Administrator/figures/creat_datadisk1.png new file mode 100644 index 0000000000000000000000000000000000000000..0dfd6a2802184af6d809c485191ea52452cf28d5 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/creat_datadisk1.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/etmem-system-architecture.png b/docs/en/25.03/Server/Administration/Administrator/figures/etmem-system-architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..1e077e00f44c0404526a4742d49c6e866601eee1 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/etmem-system-architecture.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/logical_architectureofMariaDB.png b/docs/en/25.03/Server/Administration/Administrator/figures/logical_architectureofMariaDB.png new file mode 100644 index 0000000000000000000000000000000000000000..8caa189a6fbf37bf4e9fd863c2ebb24e25547789 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/logical_architectureofMariaDB.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/login.png b/docs/en/25.03/Server/Administration/Administrator/figures/login.png new file mode 100644 index 0000000000000000000000000000000000000000..d15c2cad98fba16320d587f3c7b0c80f435c5d3a Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/login.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/nginx_deployed_success.png b/docs/en/25.03/Server/Administration/Administrator/figures/nginx_deployed_success.png new file mode 100644 index 0000000000000000000000000000000000000000..9ffb2c142defbd690e5407659116bf8e5582ba73 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/nginx_deployed_success.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/nginx_start_failed.png b/docs/en/25.03/Server/Administration/Administrator/figures/nginx_start_failed.png new file mode 100644 index 0000000000000000000000000000000000000000..c8b855453433796265de42d7ffd0189c7ff9be2b Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/nginx_start_failed.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/nginx_start_success.png b/docs/en/25.03/Server/Administration/Administrator/figures/nginx_start_success.png new file mode 100644 index 0000000000000000000000000000000000000000..bc6929772fd98fac3494b4436f26910b09818cb7 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/nginx_start_success.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/postgres.png b/docs/en/25.03/Server/Administration/Administrator/figures/postgres.png new file mode 100644 index 0000000000000000000000000000000000000000..e7fc36882718587ec949133fe9892185cb4c2158 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/postgres.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/top_display.png b/docs/en/25.03/Server/Administration/Administrator/figures/top_display.png new file mode 100644 index 0000000000000000000000000000000000000000..2d77d3dc2934763b5da896a827b9805da34d1c09 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/top_display.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0229622729.png b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0229622729.png new file mode 100644 index 0000000000000000000000000000000000000000..a32856aa08e459ed0f51f8fcf4c2f51511c12095 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0229622729.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0229622789.png b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0229622789.png new file mode 100644 index 0000000000000000000000000000000000000000..d245d48dc07e2b01734e21ec1952e89fa9269bdb Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0229622789.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0230050789.png b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0230050789.png new file mode 100644 index 0000000000000000000000000000000000000000..0b785be2a026fe059c6ee41700a971a11cfff7ae Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0230050789.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143176.png b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143176.png new file mode 100644 index 0000000000000000000000000000000000000000..300165189e6d3e8fa356f3d463cfc627c2ece0e2 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143176.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143177.png b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143177.png new file mode 100644 index 0000000000000000000000000000000000000000..ccafce4b0c58a4da0a9f7aece335ede24e5030c0 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143177.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143178.png b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143178.png new file mode 100644 index 0000000000000000000000000000000000000000..bff125f096215e91b28ee6deacde6d886e5b21eb Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143178.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143180.png b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143180.png new file mode 100644 index 0000000000000000000000000000000000000000..52f5644f9c985bcc39c0d146006dd9136140bc01 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143180.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143181.png b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143181.png new file mode 100644 index 0000000000000000000000000000000000000000..d3698e6c0e021a56be46b9f4944c858a425eb66c Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143181.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143183.png b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143183.png new file mode 100644 index 0000000000000000000000000000000000000000..55ffdfa2616ee259543c1539e46c3e05f9335354 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143183.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143185.png b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143185.png new file mode 100644 index 0000000000000000000000000000000000000000..bff125f096215e91b28ee6deacde6d886e5b21eb Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143185.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143187.png b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143187.png new file mode 100644 index 0000000000000000000000000000000000000000..52f5644f9c985bcc39c0d146006dd9136140bc01 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231143187.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231563132.png b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231563132.png new file mode 100644 index 0000000000000000000000000000000000000000..bb801a9471f3f3541ba96491654f25e2df9ce8bf Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231563132.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231563134.png b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231563134.png new file mode 100644 index 0000000000000000000000000000000000000000..398d15376d29d3aa406abb2e7e065d4625428c4d Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231563134.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231563135.png b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231563135.png new file mode 100644 index 0000000000000000000000000000000000000000..785977142a6bf0e1c1815b82dea73d75fa206a75 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231563135.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231563136.png b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231563136.png new file mode 100644 index 0000000000000000000000000000000000000000..c274db4d0ca9d8758267a916e19fdef4aa22d0ba Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/figures/zh-cn_image_0231563136.png differ diff --git a/docs/en/25.03/Server/Administration/Administrator/process-management.md b/docs/en/25.03/Server/Administration/Administrator/process-management.md new file mode 100644 index 0000000000000000000000000000000000000000..5e267c94c37366a128d6de75d6ed1cae958a6eab --- /dev/null +++ b/docs/en/25.03/Server/Administration/Administrator/process-management.md @@ -0,0 +1,333 @@ +# 管理进程 + +操作系统管理多个用户的请求和多个任务。大多数系统都只有一个CPU和一个主要存储,但一个系统可能有多个二级存储磁盘和多个输入/输出设备。操作系统管理这些资源并在多个用户间共享资源,当用户提出一个请求时,造成好像系统被用户独占的假象。实际上操作系统监控着一个等待执行的任务队列,这些任务包括用户任务、操作系统任务、邮件和打印任务等。本章节将从用户的角度讲述如何控制进程。 + +## 查看进程 + +Linux是一个多任务系统,经常需要对这些进程进行一些调配和管理。要进行管理,首先就要知道现在的进程情况:有哪些进程、进程的状态如何等。Linux提供了多种命令来了解进程的状况。 + +### who命令 + +who命令主要用于查看当前系统中的用户情况。如果用户想和其他用户建立即时通讯,比如使用talk命令,那么首先要确定的就是该用户确实在线上,不然talk进程就无法建立起来。又如,系统管理员希望监视每个登录的用户此时此刻的所作所为,也要使用who命令。who命令应用起来非常简单,可以比较准确地掌握用户的情况,所以使用非常广泛。 + +例如查看系统中的用户及其状态。使用如下: + +```shell +# who +admin tty1 Jul 28 15:55 +admin pts/0 Aug 5 15:46 (192.168.0.110) +admin pts/2 Jul 29 19:52 (192.168.0.110) +root pts/3 Jul 30 12:07 (192.168.0.110) +root pts/4 Jul 31 10:29 (192.168.0.144) +root pts/5 Jul 31 14:52 (192.168.0.11) +root pts/6 Aug 6 10:12 (192.168.0.234) +root pts/8 Aug 6 11:34 (192.168.0.234) +``` + +### ps命令 + +ps命令是最基本又非常强大的进程查看命令。使用该命令可以确定有哪些进程正在运行和运行的状态、进程是否结束、进程有没有僵尸、哪些进程占用了过多的资源等,大部分进程信息都是可以通过执行该命令得到的。 + +ps命令最常用的还是用来监控后台进程的工作情况,因为后台进程是不与屏幕、键盘这些标准输入/输出设备进行通信的,所以如果需要检测其状况,就可使用ps命令。ps命令的常见选项如[表1](#zh-cn_topic_0151921029_t34619d964a3d41ad8694189ec383359c)所示。 + +**表 1** 选项说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

选项

+

描述

+

-e

+

显示所有进程。

+

-f

+

全格式。

+

-h

+

不显示标题。

+

-l

+

使用长格式。

+

-w

+

宽行输出。

+

-a

+

显示终端上的所有进程,包括其他用户的进程。

+

-r

+

只显示正在运行的进程。

+

-x

+

显示没有控制终端的进程。

+
+ +例如显示系统中终端上的所有进程。命令如下: + +```shell +# ps -a + PID TTY TIME CMD +12175 pts/6 00:00:00 bash +24526 pts/0 00:00:00 vsftpd +29478 pts/5 00:00:00 ps +32461 pts/0 1-01:58:33 sh +``` + +### top命令 + +top命令和ps命令的基本作用是相同的,显示系统当前的进程和其他状况,但是top是一个动态显示过程,即可以通过用户按键来不断刷新进程的当前状态,如果在前台执行该命令,它将独占前台,直到用户终止该程序为止。其实top命令提供了实时的对系统处理器的状态监视。它将显示系统中CPU的任务列表。该命令可以按CPU使用、内存使用和执行时间对任务进行排序,而且该命令的很多特性都可以通过交互式命令或者在定制文件中进行设定。 + +top命令输出的示例如[图1](#zh-cn_topic_0151921029_f289234fcdbac453796200d80e9889cd1)所示: + +**图 1** top显示 +![](./figures/top_display.png) + +### kill命令 + +当需要中断一个前台进程的时候,通常足使用“Ctrl+c”组合键,而对于后台进程不能用组合键来终止,这时就可以使用kill命令。该命令可以终止前台和后台进程。终止后台进程的原因包括:该进程占用CPU的时间过多、该进程已经死锁等。 + +kill命令是通过向进程发送指定的信号来结束进程的。如果没有指定发送的信号,那么缺省值为TERM信号。TERM信号将终止所有不能捕获该信号的进程。至于那些可以捕获该信号的进程可能就需要使用KILL信号(它的编号为9),而该信号不能被捕捉。 + +kill命令的浯法格式有以下两种方式: + +```shell +kill [-s 信号 | -p] [-a] 进程号… +kill -l [信号] +``` + +其中进程号可以通过ps命令的输出得到。-s选项是给程序发送指定的信号,详细的信号可以用“kill -l”命令查看;-p选项只显示指定进程的ID号。 + +杀死pid为1409的进程,在root权限下执行如下命令: + +```shell +# kill -9 1409 +``` + +显示所有的信号及其编号对应关系,示例如下: + +```shell +# kill -l + 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP + 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 +11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM +16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP +21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ +26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR +31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 +38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 +43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 +48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 +53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 +58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 +63) SIGRTMAX-1 64) SIGRTMAX +``` + +## 调度启动进程 + +有时候需要对系统进行一些比较费时而且占用资源的维护工作,这些工作适合在深夜进行,这时候用户就可以事先进行调度安排,指定任务运行的时间或者场合,到时候系统会自动完成这些任务。要使用自动启动进程的功能,就需要掌握以下几个启动命令。 + +### 定时运行一批程序(at) + +#### at命令 + +用户使用at命令在指定时刻执行指定的命令序列。该命令至少需要指定一个命令和一个执行时间。at命令可以只指定时间,也可以时间和日期一起指定。 + +at命令的语法格式如下: + +```shell + at [-V] [-q 队列] [-f 文件名] [-mldbv] 时间 + at -c 作业 [作业…] +``` + +#### 设置时间 + +at允许使用一套相当复杂的时间指定方法,比如: + +- 接受在当天的hh:mm(小时:分钟)式的时间指定。如果该时间已经过去,那么就放在第二天执行。 +- 使用midnight(深夜)、noon(中午)、teatime(饮茶时间,一般是下午4点)等比较模糊的词语来指定时间。 +- 采用12小时计时制,即在时间后面加上AM(上午)或者PM(下午)来说明是上午还是下午。 +- 指定命令执行的具体日期,指定格式为month day(月日)或者mm/dd/yy(月/日/年)或者dd.mm.yy(日.月.年)。指定的日期必须跟在指定时间的后面。 + +上面介绍的都是绝对计时法,其实还可以使用相对计时法,这对于安排不久就要执行的命令是很有好处的。指定格式为now+count time-units,now就是当前时间,time-units是时间单位,这里可以是minutes(分钟)、hours(小时)、days(天)、weeks(星期)。count是时间的数量,究竟是几天,还是几小时等。还有一种计时方法就是直接使用today(今天)、tomorrow(明天)来指定完成命令的时间。下面通过一些例子来说明具体用法。 + +例如指定在今天下午4:30执行某个命令。假设现在时间是中午12:30,2019年6月7日,可用命令格式如下: + +```shell + at 4:30pm + at 16:30 + at 16:30 today + at now+4 hours + at now+ 240 minutes + at 16:30 7.6.19 + at 16:30 6/7/19 + at 16:30 Jun 7 +``` + +以上这些命令表达的意义是完全一样的,所以在安排时间的时候完全可以根据个人喜好和具体情况自由选择。一般采用绝对时间的24小时计时法可以避免由于用户自己的疏忽造成计时错误,例如上例可以写成:at 16:30 6/7/19。 + +#### 执行权限 + +对于at命令来说,需要定时执行的命令是从标准输入或者使用-f选项指定的文件中读取并执行的。如果at命令是从一个使用su命令切换到用户shell中执行的,那么当前用户被认为是执行用户,所有的错误和输出结果都会送给这个用户。但是如果有邮件送出的话,收到邮件的将是原来的用户,也就是登录时shell的所有者。 + +例如在6月8日上午10点执行slocate -u命令。在root权限下执行命令如下: + +```shell +# at 10:00 6/8/19 +at> slocate -u +at> +[1]+ Stopped at 10:00 6/8/19 +``` + +上面的结果中,输入at命令之后,会出现提示符at\>,提示用户输入命令,在此输入了slocate -u,然后按回车键。还可以输入多条命令,当所有要执行的命令输入结束后,按“Ctrl+d”键结束at命令。 + +在任何情况下,管理员帐户都可以使用这个命令。对于其他用户来说,是否可以使用就取决于/etc/at.allow和/etc/at.deny文件。 + +### 周期性运行一批程序(cron) + +前面介绍at命令都会在一定时间内完成一定任务,但是它只能执行一次。也就是说,当指定了运行命令后,系统在指定时间完成任务,以后就不再执行了。但是在很多情况下需要周期性重复执行一些命令,这时候就需要使用cron命令来完成任务。 + +#### 运行机制 + +首先cron命令会搜索/var/spool/cron目录,寻找以/etc/passwd文件中的用户名命名的crontab文件,被找到的这种文件将装入内存。比如一个用户名为userexample的用户,对应的crontab文件应该是/var/spool/cron/userexample,即以该用户命名的crontab文件存放在/var/spool/cron目录下面。 + +cron命令还将搜索/etc/crontab文件,这个文件是用不同的格式写成的。cron启动以后,它将首先检查是否有用户设置了crontab文件,如果没有就转入睡眠状态,释放系统资源。所以该后台进程占用资源极少,它每分钟被唤醒一次,查看当前是否有需要运行的命令。 + +命令执行结束后,任何输出都将作为邮件发送给crontab的所有者,或者是/etc/crontab文件中MAILTO环境变量中指定的用户。这是cron的工作原理,但是cron命令的执行不需要用户干涉,用户只需要修改crontab中要执行的命令。 + +#### crontab命令 + +crontab命令用于安装、删除或者显示用于驱动cron后台进程的表格。用户把需要执行的命令序列放到crontab文件中以获得执行,而且每个用户都可以有自己的crontab文件。 + +crontab命令的常用方法如下: + +- crontab -u //设置某个用户的cron服务,root用户在执行crontab时需要此参数。 +- crontab -l //列出某个用户cron服务的详细内容。 +- crontab -r //删除某个用户的cron服务。 +- crontab -e //编辑某个用户的cron服务。 + +例如root查看自己的cron设置。命令如下: + +```shell +# crontab -u root -l +``` + +#### crontab文件 + +在crontab文件中输入需要执行的命令和时间。该文件中每行都包括6个域,其中前5个域是指定命令被执行的时间,最后一个域是要被执行的命令。每个域之间使用空格或者制表符分隔。格式如下: + +```shell +minute hour day-of-month month-of-year day-of-week commands +``` + +对于每一项的说明如[表2](#zh-cn_topic_0151921016_t7d97d1204fe249d7ae0a87b4cf9a9353)所示。 + +**表 2** 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

描述

+

minute

+

分钟(0~59)。

+

hour

+

小时(0~23)。

+

day-of-month

+

一个月的第几天(1~31)。

+

month-of-year

+

一年的第几个月(1~12)。

+

day-of-week

+

一周的星期几(0~6),0代表星期天。

+

commands

+

需要执行的命令。

+
+ +这些项都不能为空,必须指定值。除了数字还有几个特殊的符号“\*”、“/”和“-”、“,”。其中,\*代表所有的取值范围内的数字,/代表每的意思,“\*/5”表示每5个单位,“-”代表从某个数字到某个数字,“,”用于分开几个离散数字。对于要执行的命令,调用的时候需要写出命令的完整路径。 + +例如晚上18点到22点之间每两个小时,在/tmp/test.txt文件中加入sleepy文本。在crontab文件中对应的行如下: + +```shell +* 18-22/2 * * * echo "sleepy" >> /tmp/test.txt +``` + +每次编辑完某个用户的cron设置后,cron自动在/var/spool/cron下生成一个与此用户同名的文件。此用户的cron信息都记录在这个文件中,这个文件是不可以直接编辑的,只可以用crontab -e来编辑。用户也可以另外建立一个文件,使用“cron文件名”命令导入cron设置。 + +假设有个用户名为userexample,它需要为自己创建一个crontab文件。步骤如下: + +1. 首先可以使用任何文本编辑器建立一个新文件,并向该文件加入需要运行的命令和要定期执行的时间,假设该文件为 \~/userexample.cron。 +2. 然后在root权限下使用crontab命令安装这个文件,使之成为该用户的crontab文件。命令如下: + + ```shell + # crontab -u userexample ~/userexample.cron + ``` + +这样crontab文件就建立好了,可以转到/var/spool/cron目录下面查看,发现多了一个userexample文件。这个文件就是所需的crontab文件。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> cron启动后,每过一分钟读一次crontab文件,检查是否要执行里面的命令。因此该文件被修改后不需要重新启动cron服务。 + +#### 编辑配置文件 + +cron服务每分钟不仅要读一次/var/spool/cron内的所有文件,还需要读一次/etc/crontab,因此通过配置这个文件也能得到cron的服务。用crontab配置是针对某个用户的,而编辑/etc/crontab是针对系统的任务。此文件的文件格式如下: + +```text +SHELL=/bin/sh +PATH=/usr/bin:/usr/sbin:/sbin:/bin:/usr/lib/news/bin +MAILTO=root //如果出现错误,或者有数据输出,将发邮件给这个帐号 +HOME=/ +# run-parts +01 * * * * root run-parts /etc/cron.hourly //每个小时执行一次/etc/cron.hourly里的脚本 +02 4 * * * root run-parts /etc/cron.daily //每天执行一次/etc/cron.daily里的脚本 +22 4 * * 0 root run-parts /etc/cron.weekly //每周执行一次/etc/cron.weekly里的脚本 +42 4 1 * * root run-parts /etc/cron.monthly //每月执行一次/etc/cron.monthly里的脚本 +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 如果去掉run-parts参数,其后面就是运行的某个脚本名,而不是目录名。 + +## 挂起/恢复进程 + +作业控制允许进程挂起并可以在需要时恢复进程的运行,被挂起的作业恢复后将从中止处开始继续运行。只要在键盘上按“Ctrl+Z”键,即可挂起当前的前台作业。在键盘上按“Ctrl+Z”键后,将挂起当前执行的命令cat。使用jobs命令可以显示shell的作业清单,包括具体的作业、作业号以及作业当前所处的状态。 + +恢复进程执行时,有两种选择:用fg命令将挂起的作业放回到前台执行;用bg命令将挂起的作业放到后台执行。灵活使用上述命令,将给自己带来很大的方便。 diff --git a/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-caution.gif b/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-caution.gif differ diff --git a/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-danger.gif b/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-danger.gif differ diff --git a/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-note.gif b/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-notice.gif b/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-notice.gif differ diff --git a/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-tip.gif b/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-tip.gif differ diff --git a/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-warning.gif b/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Administration/Administrator/public_sys-resources/icon-warning.gif differ diff --git a/docs/en/25.03/Server/Administration/Administrator/service-management.md b/docs/en/25.03/Server/Administration/Administrator/service-management.md new file mode 100644 index 0000000000000000000000000000000000000000..5b33f6c514e5c86a95a58433652bd754613085e3 --- /dev/null +++ b/docs/en/25.03/Server/Administration/Administrator/service-management.md @@ -0,0 +1,805 @@ +# 管理服务 + +本章介绍如何使用systemd进行系统和服务管理。 + +## 简介 + +systemd是在Linux下,与SysV和LSB初始化脚本兼容的系统和服务管理器。systemd使用socket和D-Bus来开启服务,提供基于守护进程的按需启动策略,支持快照和系统状态恢复,维护挂载和自挂载点,实现了各服务间基于从属关系的一个更为精细的逻辑控制,拥有更高的并行性能。 + +### 概念介绍 + +systemd开启和监督整个系统是基于unit的概念。unit是由一个与配置文件对应的名字和类型组成的(例如:avahi.service unit有一个具有相同名字的配置文件,是守护进程Avahi的一个封装单元)。unit有多种类型,如[表1](#zh-cn_topic_0151921012_t2dcb6d973cc249ed9ccd56729751ca6b)所示。 + +**表 1** unit说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

unit名称

+

后缀名

+

描述

+

Service unit

+

.service

+

系统服务。

+

Target unit

+

.target

+

一组systemd units。

+

Automount unit

+

.automount

+

文件系统挂载点。

+

Device unit

+

.device

+

内核识别的设备文件。

+

Mount unit

+

.mount

+

文件系统挂载点。

+

Path unit

+

.path

+

在一个文件系统中的文件或目录。

+

Scope unit

+

.scope

+

外部创建的进程。

+

Slice unit

+

.slice

+

一组用于管理系统进程分层组织的units。

+

Socket unit

+

.socket

+

一个进程间通信的Socket。

+

Swap unit

+

.swap

+

swap设备或者swap文件。

+

Timer unit

+

.timer

+

systemd计时器。

+
+ +所有的可用systemd unit类型,可在如[表2](#zh-cn_topic_0151921012_t2523a0a9a0c54f9b849e52d1efa0160c)所示的路径下查看。 + +**表 2** 可用systemd unit类型 + + + + + + + + + + + + + + + + +

路径

+

描述

+

/usr/lib/systemd/system/

+

随安装的RPM产生的systemd units。

+

/run/systemd/system/

+

在运行时创建systemd units。

+

/etc/systemd/system/

+

由系统管理员创建和管理的systemd units。

+
+ +## 特性说明 + +### 更快的启动速度 + +systemd提供了比UpStart更激进的并行启动能力,采用了socket/D-Bus activation等技术启动服务,带来了更快的启动速度。 + +为了减少系统启动时间,systemd的目标是: + +- 尽可能启动更少的进程。 +- 尽可能将更多进程并行启动。 + +### 提供按需启动能力 + +当sysvinit系统初始化的时候,它会将所有可能用到的后台服务进程全部启动运行。并且系统必须等待所有的服务都启动就绪之后,才允许用户登录。这种做法有两个缺点:首先是启动时间过长;其次是系统资源浪费。 + +某些服务很可能在很长一段时间内,甚至整个服务器运行期间都没有被使用过。比如CUPS,打印服务在多数服务器上很少被真正使用到。您可能没有想到,在很多服务器上SSHD也是很少被真正访问到的。花费在启动这些服务上的时间是不必要的;同样,花费在这些服务上的系统资源也是一种浪费。 + +systemd可以提供按需启动的能力,只有在某个服务被真正请求的时候才启动它。当该服务结束,systemd可以关闭它,等待下次需要时再次启动它。 + +### 采用cgroup特性跟踪和管理进程的生命周期 + +init系统的一个重要职责就是负责跟踪和管理服务进程的生命周期。它不仅可以启动一个服务,也能够停止服务。这看上去没有什么特别的,然而在真正用代码实现的时候,您或许会发现停止服务比一开始想的要困难。 + +服务进程一般都会作为守护进程(daemon)在后台运行,为此服务程序有时候会派生(fork)两次。在UpStart中,需要在配置文件中正确地配置expect小节。这样UpStart通过对fork系统调用进行计数,从而获知真正的精灵进程的PID号。 + +cgroup已经出现了很久,它主要用来实现系统资源配额管理。cgroup提供了类似文件系统的接口,使用方便。当进程创建子进程时,子进程会继承父进程的cgroup。因此无论服务如何启动新的子进程,所有的这些相关进程都会属于同一个cgroup,systemd只需要简单地遍历指定的cgroup即可正确地找到所有的相关进程,将它们逐一停止即可。 + +### 启动挂载点和自动挂载的管理 + +传统的Linux系统中,用户可以用/etc/fstab文件来维护固定的文件系统挂载点。这些挂载点在系统启动过程中被自动挂载,一旦启动过程结束,这些挂载点就会确保存在。这些挂载点都是对系统运行至关重要的文件系统,比如HOME目录。和sysvinit一样,systemd管理这些挂载点,以便能够在系统启动时自动挂载它们。systemd还兼容/etc/fstab文件,您可以继续使用该文件管理挂载点。 + +有时候用户还需要动态挂载点,比如打算访问DVD内容时,才临时执行挂载以便访问其中的内容,而不访问光盘时该挂载点被取消(umount),以便节约资源。传统地,人们依赖autofs服务来实现这种功能。 + +systemd内建了自动挂载服务,无需另外安装autofs服务,可以直接使用systemd提供的自动挂载管理能力来实现autofs的功能。 + +### 实现事务性依赖关系管理 + +系统启动过程是由很多的独立工作共同组成的,这些工作之间可能存在依赖关系,比如挂载一个NFS文件系统必须依赖网络能够正常工作。systemd虽然能够最大限度地并发执行很多有依赖关系的工作,但是类似“挂载NFS”和“启动网络”这样的工作还是存在天生的先后依赖关系,无法并发执行。对于这些任务,systemd维护一个“事务一致性”的概念,保证所有相关的服务都可以正常启动而不会出现互相依赖,以至于死锁的情况。 + +### 与SysV初始化脚本兼容 + +和UpStart一样,systemd引入了新的配置方式,对应用程序的开发也有一些新的要求。如果systemd想替代目前正在运行的初始化系统,就必须和现有程序兼容。任何一个Linux发行版都很难为了采用systemd而在短时间内将所有的服务代码都修改一遍。 + +systemd提供了和sysvinit以及LSB initscripts兼容的特性。系统中已经存在的服务和进程无需修改。这降低了系统向systemd迁移的成本,使得systemd替换现有初始化系统成为可能。 + +### 能够对系统进行快照和恢复 + +systemd支持按需启动,因此系统的运行状态是动态变化的,人们无法准确地知道系统当前运行了哪些服务。systemd快照提供了一种将当前系统运行状态保存并恢复的能力。 + +比如系统当前正运行服务A和B,可以用systemd命令行对当前系统运行状况创建快照。然后将进程A停止,或者做其他的任意的对系统的改变,比如启动新的进程C。在这些改变之后,运行systemd的快照恢复命令,就可立即将系统恢复到快照时刻的状态,即只有服务A和B在运行。一个可能的应用场景是调试:比如服务器出现一些异常,为了调试用户将当前状态保存为快照,然后可以进行任意的操作,比如停止服务等等。等调试结束,恢复快照即可。 + +## 管理系统服务 + +systemd提供systemctl命令来运行、关闭、重启、显示、启用/禁用系统服务。 + +### sysvinit命令和systemd命令 + +systemd提供systemctl命令与sysvinit命令的功能类似。当前版本中依然兼容service和chkconfig命令,相关说明如[表3](#zh-cn_topic_0151920917_ta7039963b0c74b909b72c22cbc9f2e28),但建议用systemctl进行系统服务管理。 + +**表 3** sysvinit命令和systemd命令的对照表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

sysvinit命令

+

systemd命令

+

备注

+

service network start

+

systemctl start network.service

+

用来启动一个服务 (并不会重启现有的)。

+

service network stop

+

systemctl stop network.service

+

用来停止一个服务 (并不会重启现有的)。

+

service network restart

+

systemctl restart network.service

+

用来停止并启动一个服务。

+

service network reload

+

systemctl reload network.service

+

当支持时,重新装载配置文件而不中断等待操作。

+

service network condrestart

+

systemctl condrestart network.service

+

如果服务正在运行那么重启它。

+

service network status

+

systemctl status network.service

+

检查服务运行状态

+

chkconfig network on

+

systemctl enable network.service

+

在下次启动时或满足其他触发条件时设置服务为启用。

+

chkconfig network off

+

systemctl disable network.service

+

在下次启动时或满足其他触发条件时设置服务为禁用。

+

chkconfig network

+

systemctl is-enabled network.service

+

用来检查一个服务在当前环境下被配置为启用还是禁用。

+

chkconfig --list

+

systemctl list-unit-files --type=service

+

输出在各个运行级别下服务的启用和禁用情况。

+

chkconfig network --list

+

ls /etc/systemd/system/*.wants/network.service

+

用来列出该服务在哪些运行级别下启用和禁用。

+

chkconfig network --add

+

systemctl daemon-reload

+

当您创建新服务文件或者变更设置时使用。

+
+ +### 显示所有当前服务 + +如果您需要显示当前正在运行的服务,使用命令如下: + +```shell +systemctl list-units --type service +``` + +如果您需要显示所有的服务(包括未运行的服务),需要添加-all参数,使用命令如下: + +```shell +# systemctl list-units --type service --all +``` + +例如显示当前正在运行的服务,命令如下: + +```shell +# systemctl list-units --type service +UNIT LOAD ACTIVE SUB DESCRIPTION +atd.service loaded active running Deferred execution scheduler +auditd.service loaded active running Security Auditing Service +avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack +chronyd.service loaded active running NTP client/server +crond.service loaded active running Command Scheduler +dbus.service loaded active running D-Bus System Message Bus +dracut-shutdown.service loaded active exited Restore /run/initramfs on shutdown +firewalld.service loaded active running firewalld - dynamic firewall daemon +getty@tty1.service loaded active running Getty on tty1 +gssproxy.service loaded active running GSSAPI Proxy Daemon +...... +``` + +### 显示服务状态 + +如果您需要显示某个服务的状态,可执行如下命令: + +```shell +systemctl status name.service +``` + +相关状态显示参数说明如[表4](#zh-cn_topic_0151920917_t36cd267d69244ed39ae06bb117ed8e62)所示。 + +**表 4** 状态参数说明 + + + + + + + + + + + + + + + + + + + +

参数

+

描述

+

Loaded

+

说明服务是否被加载,并显示服务对应的绝路径以及是否启用。

+

Active

+

说明服务是否正在运行,并显示时间节点。

+

Main PID

+

相应的系统服务的PID值。

+

CGroup

+

相关控制组(CGroup)的其他信息。

+
+ +如果您需要鉴别某个服务是否运行,可执行如下命令: + +```shell +systemctl status name.service +``` + +is-active命令的返回结果如下: + +**表 5** is-active命令的返回结果 + + + + + + + + + + + + + + + + + + + +

状态

+

含义

+

active(running)

+

有一个或多个程序正在系统中执行。

+

active(exited)

+

仅执行一次就正常结束的服务,目前并没有任何程序在系统中执行。 举例来说,开机或者 是挂载时才会进行一次的 quotaon 功能。

+

active(waiting)

+

正在执行当中,不过要等待其他的事件才能继续处理。例如:打印的队列相关服务 就是这种状态,虽然正在启动中,不过也需要真的有队列进来 (打印作业) 这样他才会继续唤醒打印机 服务来进行下一步打印的功能

+

inactive

+

这个服务没有运行

+
+ +同样,如果您需要判断某个服务是否被启用,可执行如下命令: + +```shell +systemctl is-enabled name.service +``` + +is-enabled命令的返回结果如下: + +**表 6** is-enabled命令的返回结果 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

状态

+

含义

+

"enabled"

+

已经通过 /etc/systemd/system/ 目录下的 Alias= 别名、 .wants/ 或 .requires/ 软链接被永久启用。

+

"enabled-runtime"

+

已经通过 /run/systemd/system/ 目录下的 Alias= 别名、 .wants/ 或 .requires/ 软链接被临时启用。

+

"linked"

+

虽然单元文件本身不在标准单元目录中,但是指向此单元文件的一个或多个软链接已经存在于 /etc/systemd/system/ 永久目录中。

+

"linked-runtime"

+

虽然单元文件本身不在标准单元目录中,但是指向此单元文件的一个或多个软链接已经存在于 /run/systemd/system/ 临时目录中。

+

"masked"

+

已经被 /etc/systemd/system/ 目录永久屏蔽(软链接指向 /dev/null 文件),因此 start 操作会失败。

+

"masked-runtime"

+

已经被 /run/systemd/systemd/ 目录临时屏蔽(软链接指向 /dev/null 文件),因此 start 操作会失败。

+

"static"

+

尚未被启用,并且单元文件的 "[Install]" 小节中没有可用于 enable 命令的选项。

+

"indirect"

+

尚未被启用,但是单元文件的 "[Install]" 小节中 Also= 选项的值列表非空(也就是列表中的某些单元可能已被启用)、或者它拥有一个不在 Also= 列表中的其他名称的别名软链接。对于模版单元来说,表示已经启用了一个不同于 DefaultInstance= 的实例。

+

"disabled"

+

尚未被启用,但是单元文件的 "[Install]" 小节中存在可用于 enable 命令的选项

+

"generated"

+

单元文件是被单元生成器动态生成的。被生成的单元文件可能并未被直接启用,而是被单元生成器隐含的启用了。

+

"transient"

+

单元文件是被运行时API动态临时生成的。该临时单元可能并未被启用。

+

"bad"

+

单元文件不正确或者出现其他错误。 is-enabled 不会返回此状态,而是会显示一条出错信息。 list-unit-files 命令有可能会显示此单元。

+
+ +例如查看gdm.service服务状态,命令如下: + +```shell +# systemctl status gdm.service +gdm.service - GNOME Display Manager Loaded: loaded (/usr/lib/systemd/system/gdm.service; enabled) Active: active (running) since Thu 2013-10-17 17:31:23 CEST; 5min ago + Main PID: 1029 (gdm) + CGroup: /system.slice/gdm.service + ├─1029 /usr/sbin/gdm + ├─1037 /usr/libexec/gdm-simple-slave --display-id /org/gno... + └─1047 /usr/bin/Xorg :0 -background none -verbose -auth /r...Oct 17 17:31:23 localhost systemd[1]: Started GNOME Display Manager. +``` + +### 运行服务 + +如果您需要运行某个服务,请在root权限下执行如下命令: + +```shell +systemctl start name.service +``` + +例如运行httpd服务,命令如下: + +```shell +# systemctl start httpd.service +``` + +### 关闭服务 + +如果您需要关闭某个服务,请在root权限下执行如下命令: + +```shell +systemctl stop name.service +``` + +例如关闭蓝牙服务,命令如下: + +```shell +# systemctl stop bluetooth.service +``` + +### 重启服务 + +如果您需要重启某个服务,请在root权限下执行如下命令: + +```shell +systemctl restart name.service +``` + +执行命令后,当前服务会被关闭,但马上重新启动。如果您指定的服务,当前处于关闭状态,执行命令后,服务也会被启动。 + +例如重启蓝牙服务,命令如下: + +```shell +# systemctl restart bluetooth.service +``` + +### 启用服务 + +如果您需要在开机时启用某个服务,请在root权限下执行如下命令: + +```shell +systemctl enable name.service +``` + +例如设置httpd服务开机时启动,命令如下: + +```shell +# systemctl enable httpd.service +ln -s '/usr/lib/systemd/system/httpd.service' '/etc/systemd/system/multi-user.target.wants/httpd.service' +``` + +### 禁用服务 + +如果您需要在开机时禁用某个服务,请在root权限下执行如下命令: + +```shell +systemctl disable name.service +``` + +例如在开机时禁用蓝牙服务启动,命令如下: + +```shell +# systemctl disable bluetooth.service +Removed /etc/systemd/system/bluetooth.target.wants/bluetooth.service. +Removed /etc/systemd/system/dbus-org.bluez.service. +``` + +## 改变运行级别 + +### Target和运行级别 + +systemd用目标(target)替代了运行级别的概念,提供了更大的灵活性,如您可以继承一个已有的目标,并添加其他服务,来创建自己的目标。[表7](#zh-cn_topic_0151920939_t9af92c282ad240ea9a79fb08d26e8181)列举了systemd下的目标和常见runlevel的对应关系。 + +**表 7** 运行级别和systemd目标 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

运行级别

+

systemd目标(target)

+

描述

+

0

+

runlevel0.target,poweroff.target

+

关闭系统。

+

1, s, single

+

runlevel1.target,rescue.target

+

单用户模式。

+

2, 4

+

runlevel2.target,runlevel4.target,multi-user.target

+

用户定义/域特定运行级别。默认等同于3。

+

3

+

runlevel3.target,multi-user.target

+

多用户,非图形化。用户可以通过多个控制台或网络登录。

+

5

+

runlevel5.target,graphical.target

+

多用户,图形化。通常为所有运行级别3的服务外加图形化登录。

+

6

+

runlevel6.target,reboot.target

+

重启系统。

+

emergency

+

emergency.target

+

紧急Shell。

+
+ +### 查看系统默认启动目标 + +查看当前系统默认的启动目标,命令如下: + +```shell +systemctl get-default +``` + +### 查看当前系统所有的启动目标 + +查看当前系统所有的启动目标,命令如下: + +```shell +systemctl list-units --type=target +``` + +### 改变默认目标 + +改变系统默认的目标,在root权限下执行如下命令: + +```shell +systemctl set-default name.target +``` + +### 改变当前目标 + +改变当前系统的目标,在root权限下执行如下命令: + +```shell +systemctl isolate name.target +``` + +### 切换到救援模式 + +改变当前系统为救援模式,在root权限下执行如下命令: + +```shell +systemctl rescue +``` + +这条命令和“systemctl isolate rescue.target”类似。命令执行后会在串口有如下打印信息: + +```shell +You are in rescue mode. After logging in, type "journalctl -xb" to viewsystem logs, "systemctl reboot" to reboot, "systemctl default" or "exit"to boot into default mode. +Give root password for maintenance +(or press Control-D to continue): +``` + +>![](./public_sys-resources/icon-note.gif) **说明:** +>从救援模式进入正常模式,用户需要重启系统。 + +### 切换到紧急模式 + +改变当前系统为紧急模式,在root权限下执行如下命令: + +```shell +systemctl emergency +``` + +这条命令和“systemctl isolate emergency.target”类似。命令执行后会在串口有如下打印信息: + +```shell +You are in emergency mode. After logging in, type "journalctl -xb" to viewsystem logs, "systemctl reboot" to reboot, "systemctl default" or "exit"to boot into default mode. +Give root password for maintenance +(or press Control-D to continue): +``` + +>![](./public_sys-resources/icon-note.gif) **说明:** +>从紧急模式进入正常模式,用户需要重启系统。 + +## 关闭、暂停和休眠系统 + +### systemctl命令 + +systemd通过systemctl命令可以对系统进行关机、重启、休眠等一系列操作。当前仍兼容部分Linux常用管理命令,对应关系如[表8](#zh-cn_topic_0151920964_t3daaaba6a03b4c36be9668efcdb61f3b)。建议用户使用systemctl命令进行操作。 + +**表 8** 命令对应关系 + + + + + + + + + + + + + + + + + + + + +

Linux常用管理命令

+

systemctl命令

+

描述

+

halt

+

systemctl halt

+

关闭系统

+

poweroff

+

systemctl poweroff

+

关闭电源

+

reboot

+

systemctl reboot

+

重启

+
+ +### 关闭系统 + +关闭系统并下电,在root权限下执行如下命令: + +```shell +systemctl poweroff +``` + +关闭系统但不下电机器,在root权限下执行如下命令: + +```shell +systemctl halt +``` + +执行上述命令会给当前所有的登录用户发送一条提示消息。如果不想让systemd发送该消息,您可以添加“--no-wall”参数。具体命令如下: + +```shell +systemctl --no-wall poweroff +``` + +### 重启系统 + +重启系统,在root权限下执行如下命令: + +```shell +systemctl reboot +``` + +执行上述命令会给当前所有的登录用户发送一条提示消息。如果不想让systemd发送该消息,您可以添加“--no-wall”参数。具体命令如下: + +```shell +systemctl --no-wall reboot +``` + +### 使系统待机 + +使系统待机,在root权限下执行如下命令: + +```shell +systemctl suspend +``` + +### 使系统休眠 + +使系统休眠,在root权限下执行如下命令: + +```shell +systemctl hibernate +``` + +使系统待机且处于休眠状态,在root权限下执行如下命令: + +```shell +systemctl hybrid-sleep +``` diff --git a/docs/en/25.03/Server/Administration/Administrator/setting-up-the-database-server.md b/docs/en/25.03/Server/Administration/Administrator/setting-up-the-database-server.md new file mode 100644 index 0000000000000000000000000000000000000000..3ac924ff2042ddcc1e367eebfb0cd3fdcbbc7432 --- /dev/null +++ b/docs/en/25.03/Server/Administration/Administrator/setting-up-the-database-server.md @@ -0,0 +1,2134 @@ +# 搭建数据库服务器 + +## PostgreSql服务器 + +### 软件介绍 + +PostgreSQL的架构如[图1](#fig26022387391)所示,主要进程说明如[表1](#table62020913417)所示。 + +**图 1** PostgreSql架构 +![](./figures/PostgreSql_architecture.png) + +**表 1** PostgreSql中的主要进程说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

进程类别

+

进程名称

+

说明

+

主进程

+

Postmaster

+

Postmaster是整个数据库实例的总控进程,负责启动和关闭该数据库实例。

+

常驻进程

+

Postgres(常驻进程)

+

管理后端的常驻进程,也称为“postmaster”。其默认侦听UNIXDomain Socket和TCP/IP(Windows等,一部分的平台只侦听TCP/IP)的5432端口,等待来自前端的连接处理。侦听的端口号可以在PostgreSql的设置文件postgresql.conf中修改。

+

子进程

+

Postgres(子进程)

+

子进程根据pg_hba.conf定义的安全策略来判断是否允许进行连接,根据策略,会拒绝某些特定的IP及网络,或者也可以只允许某些特定的用户或者对某些数据库进行连接。

+

Postgres会接受前端过来的查询,然后对数据库进行检索,最后把结果返回,有时也会对数据库进行更新。更新的数据同时还会记录在事务日志里面(PostgreSQL称为WAL日志)。这个主要是当停电、服务器宕机、重新启动的时候进行恢复处理的时候使用。另外,把日志归档保存起来,可在需要进行恢复的时候使用。在PostgreSQL 9.0以后,通过把WAL日志传送其他的postgreSQL,可以实时的进行数据库复制,这就是所谓的“数据库复制”功能。

+

辅助进程

+

SysLogger(系统日志)

+

需要在Postgres.conf中logging_collection设置为on,此时主进程才会启动Syslogger辅助进程。

+

BgWriter(后台写)

+

把共享内存中的脏页写到磁盘上的进程。主要是为了提高插入、更新和删除数据的性能。

+

WALWriter(预写式日志)

+

在修改数据之前把修改操作记录到磁盘中,以便后面更新实时数据时就不需要数据持久化到文件中。

+

PgArch(归档)

+

WAL日志会被循环使用,PgArch在归档前会把WAL日志备份出来。通过PITY(Point in Time Recovery)技术,可以在数据库进行一次全量备份后,将全量备份时间点之后的WAL日志通过归档进行备份,然后凭借数据库的全量备份再加上后面产生的WAL日志,即可把数据库向前推到全量备份后的任意一个时间点。

+

AutoVacuum(系统自动清理)

+

在PostgreSQL数据库中,对表进行DELETE操作后,旧的数据并不会立即被删除,并且,在更新数据时,也并不会在旧的数据上做更新,而是新生成一行数据。旧的数据只是被标识为删除状态,只有在没有并发的其他事务读到这些就数据时,它们才会被清除。这个清除工作就由AutoVacuum进程完成。

+

PgStat(统计收集)

+

做数据的统计收集工作。主要用于查询优化时的代价估算,包括一个表和索引进行了多少次的插入、更新、删除操作,磁盘块读写的次数、行的读次数。pg_statistic中存储了PgStat收集的各类信息。

+

CheckPoint(检查点)

+

检查点是系统设置的事务序列点,设置检查点保证检查点前的日志信息刷到磁盘中。

+
+ +### 配置环境 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 以下环境配置仅为参考示例,具体配置视实际需求做配置。 + +#### 关闭防火墙并取消开机自启动 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 测试环境下通常会关闭防火墙以避免部分网络因素影响,视实际需求做配置。 + +1. 在root权限下停止防火墙。 + + ```shell + systemctl stop firewalld + ``` + +2. 在root权限下关闭防火墙。 + + ```shell + systemctl disable firewalld + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 执行disable命令关闭防火墙的同时,也取消了开机自启动。 + +#### 修改SELINUX为disabled + +在root权限下修改配置文件。 + +```shell +sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config +``` + +#### 创建组和用户 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 服务器环境下,为了系统安全,通常会为进程分配单独的用户,以实现权限隔离。本章节创建的组和用户都是操作系统层面的,不是数据库层面的。 + +1. 在root权限下创建PostgreSQL用户(组)。 + + ```shell + groupadd postgres + useradd -g postgres postgres + ``` + +2. 在root权限下设置postgres用户密码(重复输入密码)。 + + ```shell + passwd postgres + ``` + +#### 搭建数据盘 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 测试极限性能时,建议单独挂载IO性能更优的NVME SSD存储介质创建PostgreSQL测试实例,避免磁盘IO对性能测试结果的影响,本文以单独挂载NVME SSD为例,参考步骤1\~步骤4。 +> 非性能测试时,在root权限下执行以下命令,创建数据目录即可。然后跳过本小节:`mkdir /data` + +1. 在root权限下创建文件系统(以xfs为例,根据实际需求创建文件系统),若磁盘之前已做过文件系统,执行此命令会出现报错,可使用-f参数强制创建文件系统。 + + ```shell + mkfs.xfs /dev/nvme0n1 + ``` + +2. 在root权限下创建数据目录。 + + ```shell + mkdir /data + ``` + +3. 在root权限下挂载磁盘。 + + ```shell + mount -o noatime,nobarrier /dev/nvme0n1 /data + ``` + +#### 数据目录授权 + +1. 在root权限下修改目录权限。 + + ```shell + chown -R postgres:postgres /data/ + ``` + +### 安装、运行和卸载 + +#### 安装 + +1. 配置本地yum源,详细信息请参考[搭建repo服务器](./configuring-the-repo-server.md)。 +2. 清除缓存。 + + ```shell + dnf clean all + ``` + +3. 创建缓存。 + + ```shell + dnf makecache + ``` + +4. 在root权限下安装PostgreSQL服务器。 + + ```shell + dnf install postgresql-server + ``` + +5. 查看安装后的rpm包。 + + ```shell + rpm -qa | grep postgresql + ``` + +#### 运行 + +##### 初始化数据库 + +> ![](./public_sys-resources/icon-notice.gif) **须知:** +> 此步骤在postgres用户下操作。 + +1. 切换到已创建的PostgreSQL用户。 + + ```shell + su - postgres + ``` + +2. 初始化数据库,其中命令中的/usr/bin是命令initdb所在的目录。 + + ```shell + usr/bin/initdb -D /data/ + ``` + +##### 启动数据库 + +1. 启动PostgreSQL数据库。 + + ```shell + /usr/bin/pg_ctl -D /data/ -l /data/logfile start + ``` + +2. 确认PostgreSQL数据库进程是否正常启动。 + + ```shell + ps -ef | grep postgres + ``` + + 命令执行后,打印信息如下图所示,PostgreSQL相关进程已经正常启动了。 + + ![](./figures/postgres.png) + +##### 登录数据库 + +1. 登录数据库。 + + ```shell + /usr/bin/psql -U postgres + ``` + + ![](./figures/login.png) + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 初次登录数据库,无需密码。 + +##### 配置数据库帐号密码 + +1. 登录后,设置postgres密码。 + + ```shell + postgres=#alter user postgres with password '123456'; + ``` + + ![](./figures/zh-cn_image_0230050789.png) + +##### 退出数据库 + +1. 执行\\q退出数据库。 + + ```shell + postgres=#\q + ``` + +##### 停止数据库 + +1. 停止PostgreSQL数据库。 + + ```shell + /usr/bin/pg_ctl -D /data/ -l /data/logfile stop + ``` + +#### 卸载 + +1. 在postgres用户下停止数据库。 + + ```shell + /usr/bin/pg_ctl -D /data/ -l /data/logfile stop + ``` + +2. 在root用户下执行**dnf remove postgresql-server**卸载PostgreSQL数据库。 + + ```shell + dnf remove postgresql-server + ``` + +### 管理数据库角色 + +#### 创建角色 + +可以使用CREATE ROLE语句或createuser来创建角色。createuser是对CREATE ROLE命令的封装,需要在shell界面执行,而不是在数据库界面。 + +```shell +CREATE ROLE rolename [ [ WITH ] option [ ... ] ]; +``` + +```shell +createuser rolename +``` + +其中: + +- rolename:角色名。 +- option为参数选项,常用的有: + - SUPERUSER | NOSUPERUSER:决定一个新角色是否为"超级用户",若未指定,则默认为NOSUPERUSER,即不是超级用户。 + - CREATEDB | NOCREATEDB:定义一个角色是否能创建数据库,若未指定,则默认为NOCREATEDB,即不能创建数据库。 + - CREATEROLE | NOCREATEROLE:决定一个角色是否可以创建新角色,若未指定,则默认为NOCREATEROLE,即不能创建新角色。 + - INHERIT | NOINHERIT:决定一个角色是否"继承"它所在组的角色的权限。一个带有 INHERIT 属性的角色可以自动使用已经赋与它直接或间接所在组的任何权限。若未指定,则默认为INHERIT。 + - LOGIN | NOLOGIN:决定一个角色是否可以登录,一个拥有LOGIN属性的角色可以认为是一个用户,若无此属性的角色可以用于管理数据库权限,但是并不是用户,若未指定,则默认为NOLOGIN。但若创建角色是使用的是CREATE USER而不是CREATE ROLE,则默认是LOGIN属性。 + - \[ ENCRYPTED | UNENCRYPTED \] PASSWORD 'password':设置角色的密码,密码只对那些拥有 LOGIN 属性的角色有意义。ENCRYPTED | UNENCRYPTED表示是否对密码进行加密,若未指定,则默认为ENCRYPTED,即加密。 + - VALID UNTIL 'timestamp':角色的密码失效的时间戳,若为指定,则表示密码永久有效。 + - IN ROLE rolename1:列出一个或多个现有的角色,新角色rolename将立即加入这些角色,成为rolename1的成员。 + - ROLE rolename2:列出一个或多个现有的角色,它们将自动添加为新角色rolename的成员,即新角色为"组"。 + +要使用这条命令,必须拥有 CREATEROLE 权限或者是数据库超级用户。 + +##### 示例 + +创建一个可以登录的角色roleexample1。 + +```shell +postgres=# CREATE ROLE roleexample1 LOGIN; +``` + +创建一个密码为123456的角色roleexample2。 + +```shell +postgres=# CREATE ROLE roleexample2 WITH LOGIN PASSWORD '123456'; +``` + +创建角色名为roleexample3的角色。 + +```shell +[postgres@localhost ~]# createuser roleexample3 +``` + +#### 查看角色 + +可以使用SELECT语句或psql的元命令\\du查看角色。 + +```shell +SELECT rolename FROM pg_roles; +``` + +```shell +\du +``` + +其中:rolename:角色名。 + +##### 示例 + +查看roleexample1角色。 + +```shell +postgres=# SELECT roleexample1 from pg_roles; +``` + +查看现有角色。 + +```shell +postgres=# \du +``` + +#### 修改角色 + +##### 修改用户名 + +可以使用ALTER ROLE语句修改一个已经存在的角色名。 + +```shell +ALTER ROLE oldrolername RENAME TO newrolename; +``` + +其中: + +- oldrolername:旧的角色名。 +- newrolename:新的角色名。 + +##### 修改用户示例 + +将角色名roleexample1修改为roleexapme2。 + +```shell +postgres=# ALTER ROLE roleexample1 RENAME TO roleexample2; +``` + +##### 修改用户密码 + +可以使用ALTER ROLE语句修改一个角色的登录密码。 + +```shell +ALTER ROLE rolename PASSWORD 'password' +``` + +其中: + +- rolename:角色名。 +- password:密码。 + +##### 修改角色密码示例 + +将roleexample1的密码修改为456789。 + +```shell +postgres=# ALTER ROLE roleexample1 WITH PASSWORD '456789'; +``` + +#### 删除角色 + +可以使用DROP ROLE语句或dropuser来删除角色。dropuser是对DROP ROLE命令的封装,需要在shell界面执行,而不是在数据库界面。 + +```shell +DROP ROLE rolename; +``` + +```shell +dropuser rolename +``` + +其中:rolename为角色名。 + +##### 示例 + +删除userexample1角色。 + +```shell +postgres=# DROP ROLE userexample1; +``` + +删除userexample2角色。 + +```shell +[postgres@localhost ~]# dropuser userexample2 +``` + +#### 角色授权 + +可以使用GRANT语句来对角色授权。 + +对角色授予表的操作权限: + +```shell +GRANT { { SELECT | INSERT | UPDATE | DELETE | REFERENCES | TRIGGER } [,...] | ALL [ PRIVILEGES ] } ON [ TABLE ] tablename [, ...] TO { rolename | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ] +``` + +对角色授予序列的操作权限: + +```shell +GRANT { { USAGE | SELECT | UPDATE } [,...] | ALL [ PRIVILEGES ] } ON SEQUENCE sequencename [, ...] TO { rolename | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ] +``` + +对角色授予数据库的操作权限: + +```shell +GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] } ON DATABASE databasename [, ...] TO { rolename | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ] +``` + +对角色授予函数的操作权限: + +```shell +GRANT { EXECUTE | ALL [ PRIVILEGES ] } ON FUNCTION funcname ( [ [ argmode ] [ argname ] argtype [, ...] ] ) [, ...] TO { rolename | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ] +``` + +对角色授予过程语言的操作权限: + +```shell +GRANT { USAGE | ALL [ PRIVILEGES ] } ON LANGUAGE langname [, ...] TO { rolename | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ] +``` + +对角色授予模式的操作权限: + +```shell +GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] } ON SCHEMA schemaname [, ...] TO { rolename | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ] +``` + +对角色授予表空间的操作权限: + +```shell +GRANT { CREATE | ALL [ PRIVILEGES ] } ON TABLESPACE tablespacename [, ...] TO { rolename | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ] +``` + +将角色rolename1的成员关系赋予角色rolename2: + +```shell +GRANT rolename1 [, ...] TO rolename2 [, ...] [ WITH ADMIN OPTION ] +``` + +其中: + +- SELECT、INSERT、UPDATE、DELETE、REFERENCES、TRIGGER、USAGE、CREATE、CONNECT、TEMPORARY、TEMP、EXECUTE、ALL \[ PRIVILEGES \]:用户的操作权限,ALL \[ PRIVILEGES \]表示所有的权限,PRIVILEGES关键字在 PostgreSQL里是可选的,但是严格的SQL 要求有这个关键字。 +- ON字句:用于指定权限授予的对象。 +- tablename:表名。 +- TO字句:用来指定被赋予权限的角色。 +- rolename、rolename1、rolename2:角色名。 +- groupname:角色组名。 +- PUBLIC:表示该权限要赋予所有角色,包括那些以后可能创建的用户。 +- WITH GRANT OPTION:表示权限的接收者也可以将此权限赋予他人,否则就不能授权他人。该选项不能赋予给PUBLIC。 +- sequencename:序列名。 +- databasename:数据库名。 +- funcname \( \[ \[ argmode \] \[ argname \] argtype \[, ...\] \] \):函数名及其参数。 +- langname:过程语言名。 +- schemaname:模式名。 +- tablespacename:表空间名。 +- WITH ADMIN OPTION:表示成员随后就可以将角色的成员关系赋予其他角色,以及撤销其他角色的成员关系。 + +##### 示例 + +对userexample授予数据库database1的CREATE权限。 + +```shell +postgres=# GRANT CREATE ON DATABASE database1 TO userexample; +``` + +对所有用户授予表table1的所有权限。 + +```shell +postgres=# GRANT ALL PRIVILEGES ON TABLE table1 TO PUBLIC; +``` + +#### 删除用户权限 + +可以使用REVOKE语句来撤销以前赋予一个或多个角色的权限。 + +撤销角色对表的操作权限: + +```shell +REVOKE [ GRANT OPTION FOR ] { { SELECT | INSERT | UPDATE | DELETE | REFERENCES | TRIGGER } [,...] | ALL [ PRIVILEGES ] } ON [ TABLE ] tablename [, ...] FROM { rolename | GROUP groupname | PUBLIC } [, ...] +``` + +撤销角色对序列的操作权限: + +```shell +REVOKE [ GRANT OPTION FOR ] { { USAGE | SELECT | UPDATE } [,...] | ALL [ PRIVILEGES ] } ON SEQUENCE sequencename [, ...] FROM { rolename | GROUP groupname | PUBLIC } [, ...] [ CASCADE | RESTRICT ] +``` + +撤销角色对数据库的操作权限: + +```shell +REVOKE [ GRANT OPTION FOR ] { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] } ON DATABASE databasename [, ...] FROM { rolename | GROUP groupname | PUBLIC } [, ...] [ CASCADE | RESTRICT ] +``` + +撤销角色对函数的操作权限: + +```shell +REVOKE [ GRANT OPTION FOR ] { EXECUTE | ALL [ PRIVILEGES ] } ON FUNCTION funcname ( [ [ argmode ] [ argname ] argtype [, ...] ] ) [, ...] FROM { rolename | GROUP groupname | PUBLIC } [, ...] [ CASCADE | RESTRICT ] +``` + +撤销角色对过程语言的操作权限: + +```shell +REVOKE [ GRANT OPTION FOR ] { USAGE | ALL [ PRIVILEGES ] } ON LANGUAGE langname [, ...] FROM { rolename | GROUP groupname | PUBLIC } [, ...] [ CASCADE | RESTRICT ] +``` + +撤销角色对模式的操作权限: + +```shell +REVOKE [ GRANT OPTION FOR ] { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] } ON SCHEMA schemaname [, ...] FROM { rolename | GROUP groupname | PUBLIC } [, ...] [ CASCADE | RESTRICT ] +``` + +撤销角色对表空间的操作权限: + +```shell +REVOKE [ GRANT OPTION FOR ] { CREATE | ALL [ PRIVILEGES ] } ON TABLESPACE tablespacename [, ...] FROM { rolename | GROUP groupname | PUBLIC } [, ...] [ CASCADE | RESTRICT ] +``` + +删除rolename2的rolename1的成员关系: + +```shell +REVOKE [ ADMIN OPTION FOR ] rolename1 [, ...] FROM rolename2 [, ...] [ CASCADE | RESTRICT ] +``` + +其中: + +- GRANT OPTION FOR:表示只是撤销对该权限的授权的权力,而不是撤销该权限本身。 +- SELECT、INSERT、UPDATE、DELETE、REFERENCES、TRIGGER、USAGE、CREATE、CONNECT、TEMPORARY、TEMP、EXECUTE、ALL \[ PRIVILEGES \]:用户的操作权限,ALL \[ PRIVILEGES \]表示所有的权限,PRIVILEGES关键字在 PostgreSQL里是可选的,但是严格的SQL 要求有这个关键字。 +- ON字句:用于指定撤销权限的对象。 +- tablename:表名。 +- FROM字句:用来指定被撤销权限的角色。 +- rolename、rolename1、rolename2:角色名。 +- groupname:角色组名。 +- PUBLIC:表示撤销隐含定义的、拥有所有角色的组,但并不意味着所有角色都失去了权限,那些直接得到的权限以及通过一个组得到的权限仍然有效。 +- sequencename:序列名。 +- CASCADE:撤销所有依赖性权限。 +- RESTRICT:不撤销所有依赖性权限。 +- databasename:数据库名。 +- funcname \( \[ \[ argmode \] \[ argname \] argtype \[, ...\] \] \):函数名及其参数。 +- langname:过程语言名。 +- schemaname:模式名。 +- tablespacename:表空间名。 +- ADMIN OPTION FOR:表示传递的授权不会自动收回。 + +##### 示例 + +对userexample授予数据库database1的CREATE权限。 + +```shell +postgres=# GRANT CREATE ON DATABASE database1 TO userexample; +``` + +对所有用户授予表table1的所有权限。 + +```shell +postgres=# GRANT ALL PRIVILEGES ON TABLE table1 TO PUBLIC; +``` + +### 管理数据库 + +#### 创建数据库 + +可以使用CREATE DATABASE语句或createdb来创建数据库。createrdb是对CREATE DATABASE命令的封装,需要在shell界面执行,而不是在数据库界面。 + +```shell +CREATE DATABASE databasename; +``` + +```shell +createdb databasename +``` + +其中:databasename为数据库名。 + +要使用这条命令,必须拥有CREATEDB权限。 + +##### 示例 + +创建一个数据库database1。 + +```shell +postgres=# CREATE DATABASE database1; +``` + +#### 选择数据库 + +可以使用\\c语句来选择数据库。 + +```shell +\c databasename; +``` + +其中:databasename为数据库名称。 + +##### 示例 + +选择databaseexample数据库。 + +```shell +postgres=# \c databaseexample; +``` + +#### 查看数据库 + +可以使用\\l语句来查看数据库。 + +```shell +\l; +``` + +##### 示例 + +查看所有数据库。 + +```shell +postgres=# \l; +``` + +#### 删除数据库 + +可以使用DROP DATABASE语句或dropdb来删除数据库。dropdb是对DROP DATABASE命令的封装,需要在shell界面执行,而不是在数据库界面。 + +> ![](./public_sys-resources/icon-caution.gif) **注意:** +> 删除数据库要谨慎操作,一旦删除,数据库中的所有表和数据都会删除。 + +```shell +DROP DATABASE databasename; +``` + +```shell +dropdb databasename +``` + +其中:databasename为数据库名称。 + +DROP DATABASE会删除数据库的系统目录项并且删除包含数据的文件目录。 + +DROP DATABASE只能由超级管理员或数据库拥有者执行。 + +##### 示例 + +删除databaseexample数据库。 + +```shell +postgres=# DROP DATABASE databaseexample; +``` + +#### 备份数据库 + +可以使用pg\_dump命令备份数据库,将数据库转储到一个脚本文件或其他归档文件中。 + +```shell +pg_dump [option]... [databasename] > outfile +``` + +其中: + +- databasename:数据库名称。如果没有声明这个参数,那么使用环境变量 PGDATABASE 。如果那个环境变量也没声明,那么使用发起连接的用户名。 +- outfile:数据库备份的文件。 +- option:pg\_dump命令参数选项,多个参数之间可以使用空格分隔。常用的pg\_dump命令参数选项如下: + - -f,\-\-file= _filename_ :指输出到指定的文件。如果忽略,则使用标准输出。 + - -d,\-\-dbname= _databasename_ :指定转储的数据库。 + - -h,\-\-host= _hostname_ :指定主机名。 + - -p,\-\-port= _portnumber_ :指定端口。 + - -U,\-\-username= _username_ :指定连接的用户名。 + - -W,\-\-password:强制口令提示(自动)。 + +##### 示例 + +备份主机为192.168.202.144,端口为3306,postgres用户下的database1数据库到db1.sql中。 + +```shell +[postgres@localhost ~]# pg_dump -h 192.168.202.144 -p 3306 -U postgres -W database1 > db1.sql +``` + +#### 恢复数据库 + +可以使用psql命令恢复数据库。 + +```shell +psql [option]... [databasename [username]] < infile +``` + +其中: + +- databasename:数据库名称。如果没有声明这个参数,那么使用环境变量 PGDATABASE 。如果那个环境变量也没声明,那么使用发起连接的用户名。 +- username:用户名。 +- infile:pg\_dump命令中的outfile参数。 +- option:psql命令参数选项,多个参数之间可以使用空格分隔。常用的psql命令参数选项如下: + - -f,--file=filename:指输出到指定的文件。如果忽略,则使用标准输出。 + - -d,--dbname=databasename:指定转储的数据库。 + - -h,--host=hostname:指定主机名。 + - -p,--port=portnumber:指定端口。 + - -U,--username=username:指定连接的用户名。 + - -W,--password:强制口令提示(自动)。 + +psql命令不会自动创建databasename数据库,所以在执行psql恢复数据库之前需要先创建databasename数据库。 + +##### 示例 + +将db1.sql脚本文件导入到主机为192.168.202.144,端口为3306,postgres用户下newdb数据库中。 + +```shell +[postgres@localhost ~]# createdb newdb +[postgres@localhost ~]# psql -h 192.168.202.144 -p 3306 -U postgres -W -d newdb < db1.sql +``` + +## Mariadb服务器 + +### 软件介绍 + +MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可。MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品,MariaDB还提供了许多更好的新特性。 + +MariaDB的架构如[图2](#fig13492418164520)所示。 + +**图 2** MariaDB逻辑架构 +![](./figures/logical_architectureofMariaDB.png) + +当Mariadb接受到Sql语句时,其详细的执行过程如下: + +1. 当客户端连接到mariadb的时候,会认证客户端的主机名、用户、密码,认证功能可以做成插件。 +2. 如果登录成功,客户端发送sql命令到服务端。由解析器解析sql语句。 +3. 服务端检查客户端是否有权限去获取它想要的资源。 +4. 如果查询已经存储在query cache当中,那么结果立即返回。 +5. 优化器将会找出最快的执行策略,或者是执行计划,也就是说优化器可以决定什么表将会被读,以及哪些索引会被访问,哪些临时表会被使用,一个好的策略能够减少大量的磁盘访问和排序操作等。 +6. 存储引擎读写数据和索引文件,cache用来加速这些操作,其他的诸如事物和外键特性,都是在存储引擎层处理的。 + +存储引擎在物理层管控数据,它负责数据文件、数据、索引、cache等的管理,这使得管理和读取数据变得更高效,每一张表,都有一个.frm文件,这些文件包含着表的定义。 + +每一个存储引擎管理、存储数据的方式都是不同的,所支持的特性和性能也不尽相同。例如: + +- MyISAM,适合读多写少的环境,且不支持事务,支持全文索引等。 +- noDB,支持事务,支持行锁和外键等。 +- MEMORY,将数据存储在内存当中。 +- CSV,将数据存储为CSV格式。 + +### 配置环境 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 以下环境配置仅为参考示例,具体配置视实际需求做配置 + +#### 关闭防火墙并取消开机自启动 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 测试环境下通常会关闭防火墙以避免部分网络因素影响,视实际需求做配置。 + +1. 在root权限下停止防火墙。 + + ```shell + systemctl stop firewalld + ``` + +2. 在root权限下关闭防火墙。 + + ```shell + systemctl disable firewalld + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 执行disable命令关闭防火墙的同时,也取消了开机自启动。 + +#### 修改SELINUX为disabled + +1. 在root权限下修改配置文件。 + + ```shell + sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux + ``` + +#### 创建组和用户 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 服务器环境下,为了系统安全,通常会为进程分配单独的用户,以实现权限隔离。本章节创建的组和用户都是操作系统层面的,不是数据库层面的。 + +1. 在root权限下创建MySQL用户(组)。 + + ```shell + groupadd mysql + ``` + + ```shell + useradd -g mysql mysql + ``` + +2. 在root权限下设置MySQL用户密码。 + + ```shell + passwd mysql + ``` + + 重复输入密码(根据实际需求设置密码)。 + +#### 搭建数据盘 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 进行性能测试时,数据目录使用单独硬盘,需要对硬盘进行格式化并挂载,参考方法一或者方法二。 +> 非性能测试时,在root权限下执行`mkdir /data`创建数据目录即可。然后跳过本小节。 + +##### 方法一:在root权限下使用fdisk进行磁盘管理 + +1. 创建分区(以/dev/sdb为例,根据实际情况创建) + + ```shell + fdisk /dev/sdb + ``` + +2. 输入n,按回车确认。 +3. 输入p,按回车确认。 +4. 输入1,按回车确认。 +5. 采用默认配置,按回车确认。 +6. 采用默认配置,按回车确认。 +7. 输入w,按回车保存。 +8. 创建文件系统(以xfs为例,根据实际需求创建文件系统) + + ```shell + mkfs.xfs /dev/sdb1 + ``` + +9. 挂载分区到“/data”以供操作系统使用。 + + ```shell + mkdir /data + ``` + + ```shell + mount /dev/sdb1 /data + ``` + +10. 执行命令“vi /etc/fstab", 编辑“/etc/fstab”使重启后自动挂载数据盘。如下图中,添加最后一行内容。 + + 其中,/dev/nvme0n1p1为示例,具体名称以实际情况为准。 + + ![](./figures/creat_datadisk1.png) + +##### 方法二:在root权限下使用LVM进行磁盘管理 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 此步骤需要安装镜像中的lvm2相关包,步骤如下: +>(1)配置本地yum源,详细信息请参考[搭建repo服务器](./configuring-the-repo-server.md)。如果已经执行,则可跳过此步。 +>(2)在root权限下执行`yum install lvm2`命令安装lvm2。 + +1. 创建物理卷(sdb为硬盘名称,具体名字以实际为准)。 + + ```shell + pvcreate /dev/sdb + ``` + +2. 创建物理卷组(其中datavg为创建的卷组名称,具体名字以实际规划为准)。 + + ```shell + vgcreate datavg /dev/sdb + ``` + +3. 创建逻辑卷(其中600G为规划的逻辑卷大小,具体大小以实际情况为准;datalv为创建的逻辑卷的名字,具体名称以实际规划为准。)。 + + ```shell + lvcreate -L 600G -n datalv datavg + ``` + +4. 创建文件系统。 + + ```shell + mkfs.xfs /dev/datavg/datalv + ``` + +5. 创建数据目录并挂载。 + + ```shell + mkdir /data + mount /dev/datavg/datalv /data + ``` + +6. 执行命令**vi /etc/fstab**,编辑“/etc/fstab”使重启后自动挂载数据盘。如下图中,添加最后一行内容。 + + 其中,/dev/datavg/datalv为示例,具体名称以实际情况为准。 + + ![](./figures/D1376B2A-D036-41C4-B852-E8368F363B5E.png) + +#### 创建数据库目录并且授权 + +1. 在已创建的数据目录 **/data** 基础上,使用root权限继续创建进程所需的相关目录并授权MySQL用户(组)。 + + ```shell + mkdir -p /data/mariadb + cd /data/mariadb + mkdir data tmp run log + chown -R mysql:mysql /data + ``` + +### 安装、运行和卸载 + +#### 安装 + +1. 配置本地yum源,详细信息请参考[搭建repo服务器](./configuring-the-repo-server.md)。 +2. 清除缓存。 + + ```shell + dnf clean all + ``` + +3. 创建缓存。 + + ```shell + dnf makecache + ``` + +4. 在root权限下安装mariadb服务器。 + + ```shell + dnf install mariadb-server + ``` + +5. 查看安装后的rpm包。 + + ```shell + rpm -qa | grep mariadb + ``` + +#### 运行 + +1. 在root权限下开启mariadb服务器。 + + ```shell + systemctl start mariadb + ``` + +2. 在root权限下初始化数据库。 + + ```shell + /usr/bin/mysql_secure_installation + ``` + + 命令执行过程中需要输入数据库的root设置的密码,若没有密码则直接按“Enter”。然后根据提示及实际情况进行设置。 + +3. 登录数据库。 + + ```shell + mysql -u root -p + ``` + + 命令执行后提示输入密码。密码为[2](#li197143190587)中设置的密码。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 执行 **\\q** 或者 **exit** 可退出数据库。 + +#### 卸载 + +1. 在root权限下关闭数据库进程。 + + ```shell + ps -ef | grep mysql + kill -9 进程ID + ``` + +2. 在root权限下执行**dnf remove mariadb-server**命令卸载mariadb。 + + ```shell + dnf remove mariadb-server + ``` + +### 管理数据库用户 + +#### 创建用户 + +可以使用CREATE USER语句来创建一个或多个用户,并设置相应的口令。 + +```shell +CREATE USER 'username'@'hostname' IDENTIFIED BY 'password'; +``` + +其中: + +- username:用户名。 +- host:主机名,即用户连接数据库时所在的主机的名字。若是本地用户可用localhost,若在创建的过程中,未指定主机名,则主机名默认为“%”,表示一组主机。 +- password:用户的登录密码,密码可以为空,如果为空则该用户可以不需要密码登录服务器,但从安全的角度而言,不推荐这种做法。 + +使用CREATE USER语句必须拥有数据库的INSERT权限或全局CREATE USER权限。 + +使用CREATE USER语句创建一个用户帐号后,会在系统自身的数据库的user表中添加一条新记录。若创建的帐户已经存在,则语句执行时会出现错误。 + +新创建的用户拥有的权限很少,只允许进行不需要权限的操作,如使用SHOW语句查询所有存储引擎和字符集的列表等。 + +##### 示例 + +创建密码为123456,用户名为userexample1的本地用户。 + +```shell +> CREATE USER 'userexample1'@'localhost' IDENTIFIED BY '123456'; +``` + +创建密码为123456,用户名为userexample2,主机名为192.168.1.100的用户。 + +```shell +> CREATE USER 'userexample2'@'192.168.1.100' IDENTIFIED BY '123456'; +``` + +#### 查看用户 + +可以使用SHOW GRANTS语句或SELECT语句查看一个或多个用户。 + +查看特定用户: + +```shell +SHOW GRANTS [FOR 'username'@'hostname']; +``` + +```shell +SELECT USER,HOST,PASSWORD FROM mysql.user WHERE USER='username'; +``` + +查看所有用户: + +```shell +SELECT USER,HOST,PASSWORD FROM mysql.user; +``` + +其中: + +- username:用户名。 +- hostname:主机名。 + +##### 示例 + +查看userexample1用户。 + +```shell +> SHOW GRANTS FOR 'userexample1'@'localhost'; +``` + +查看mysql数据库中所有用户。 + +```shell +> SELECT USER,HOST,PASSWORD FROM mysql.user; +``` + +#### 修改用户 + +##### 修改用户名 + +可以使用RENAME USER语句修改一个或多个已经存在的用户名。 + +```shell +RENAME USER 'oldusername'@'hostname' TO 'newusername'@'hostname'; +``` + +其中: + +- oldusername:旧的用户名。 +- newusername:新的用户名。 +- hostname:主机名。 + +RENAME USER语句用于对原有的帐号进行重命名。若系统中旧帐号不存在或者新帐号已存在,则该语句执行时会出现错误。 + +使用RENAME USER语句,必须拥有数据库的UPDATE权限或全局CREATE USER权限。 + +##### 修改用户示例 + +将用户名userexample1修改为userexapme2,主机名为locahost。 + +```shell +> RENAME USER 'userexample1'@'localhost' TO 'userexample2'@'localhost'; +``` + +##### 修改用户密码 + +可以使用SET PASSWORD语句修改一个用户的登录密码。 + +```shell +SET PASSWORD FOR 'username'@'hostname' = PASSWORD('newpassword'); +``` + +其中: + +- FOR 'username'@'hostname':FOR字句,可选项,指定欲修改密码的用户名及主机名。 +- PASSWORD\('newpassword'\):表示使用函数PASSWORD\(\)设置新口令,即新口令必须传递到函数PASSWORD\(\)中进行加密。 + +> ![](./public_sys-resources/icon-caution.gif) **注意:** +> PASSWORD\(\)函数为单向加密函数,一旦加密后不能解密出原明文。 + +在SET PASSWORD语句中,若不加上FOR子句,表示修改当前用户的密码。 + +FOR字句中必须以'username'@'hostname'的格式给定,username为帐户的用户名,hostname为帐户的主机名。 + +欲修改密码的帐号必须在系统中存在,否则语句执行时会出现错误。 + +##### 修改用户密码示例 + +将用户名为userexample的密码修改为0123456,主机名为locahost。 + +```shell +> SET PASSWORD FOR 'userexample'@'localhost' = PASSWORD('0123456') ; +``` + +#### 删除用户 + +可以使用DROP USER语句来删除一个或多个用户帐号以及相关的权限。 + +```shell +DROP USER 'username1'@'hostname1' [,'username2'@'hostname2']…; +``` + +> ![](./public_sys-resources/icon-caution.gif) **注意:** +> 用户的删除不会影响他们之前所创建的表、索引或其他数据库对象,因为数据库并不会记录创建了这些对象的帐号。 + +DROP USER语句可用于删除一个或多个数据库帐号,并删除其原有权限。 + +使用DROP USER语句必须拥有数据库的DELETE权限或全局CREATE USER权限。 + +在DROP USER语句的使用中,若没有明确地给出帐号的主机名,则该主机名默认为“%”。 + +##### 示例 + +删除用户名为userexample的本地用户。 + +```shell +> DROP USER 'userexample'@'localhost'; +``` + +#### 用户授权 + +可以使用GRANT语句来对新建用户的授权。 + +```shell +GRANT privileges ON databasename.tablename TO 'username'@'hostname'; +``` + +其中: + +- ON字句:用于指定权限授予的对象和级别。 +- privileges:用户的操作权限,如SELECT,INSERT,UPDATE等,如果要授予所有的权限则使用ALL。 +- databasename:数据库名。 +- tablename:表名。 +- TO字句:用来设定用户密码,以及指定被赋予权限的用户。 +- username:用户名。 +- hostname:主机名。 + +如果要授予该用户对所有数据库和表的相应操作权限则可用\*表示,如\*.\*。 + +如果在TO子句中给系统中存在的用户指定密码,则新密码会将原密码覆盖。 + +如果权限被授予给一个不存在的用户,则会自动执行一条CREATE USER语句来创建这个用户,但同时必须为该用户指定密码。 + +##### 示例 + +对本地用户userexample授予SELECT和INSERT权限。 + +```shell +> GRANT SELECT,INSERT ON *.* TO 'userexample'@'localhost'; +``` + +#### 删除用户权限 + +可以使用REVOKE语句来删除一个用户的权限,但此用户不会被删除。 + +```shell +REVOKE privilege ON databasename.tablename FROM 'username'@'hostname'; +``` + +其中REVOKE语句的参数与GRANT语句的参数含义相同。 + +要使用 REVOKE 语句,必须拥有数据库的全局CREATE USER权限或UPDATE权限。 + +##### 示例 + +删除本地用户userexample的INSERT权限。 + +```shell +> REVOKE INSERT ON *.* FROM 'userexample'@'localhost'; +``` + +### 管理数据库 + +#### 创建数据库 + +可以使用CREATE DATABASE语句来创建数据库。 + +```shell +CREATE DATABASE databasename; +``` + +其中:databasename为数据库名称,且数据库名称不区分大小写。 + +##### 示例 + +创建数据库名为databaseexample的数据库。 + +```shell +> CREATE DATABASE databaseexample; +``` + +#### 查看数据库 + +可以使用SHOW DATABASES语句来查看数据库。 + +```shell +SHOW DATABASES; +``` + +##### 示例 + +查看所有数据库。 + +```shell +> SHOW DATABASES; +``` + +#### 选择数据库 + +一般创建表,查询表等操作首先需要选择一个目标数据库。可以使用USE语句来选择数据库。 + +```shell +USE databasename; +``` + +其中:databasename为数据库名称。 + +##### 示例 + +选择databaseexample数据库。 + +```shell +> USE databaseexample; +``` + +#### 删除数据库 + +可以使用DROP DATABASE语句来删除数据库。 + +> ![](./public_sys-resources/icon-caution.gif) **注意:** +> 删除数据库要谨慎操作,一旦删除,数据库中的所有表和数据都会删除。 + +```shell +DROP DATABASE databasename; +``` + +其中:databasename为数据库名称。 + +DROP DATABASE命令用于删除创建过\(已存在\)的数据库,且会删除数据库中的所有表,但数据库的用户权限不会自动删除。 + +要使用DROP DATABASE,您需要数据库的DROP权限。 + +DROP SCHEMA是DROP DATABASE的同义词。 + +##### 示例 + +删除databaseexample数据库。 + +```shell +> DROP DATABASE databaseexample; +``` + +#### 备份数据库 + +可以在root权限下使用mysqldump命令备份数据库。 + +备份一个或多个表: + +```shell +mysqldump [options] databasename [tablename ...] > outfile +``` + +备份一个或多个库: + +```shell +mysqldump [options] -databases databasename ... > outfile +``` + +备份所有库: + +```shell +mysqldump [options] -all-databases > outputfile +``` + +其中: + +- databasename:数据库名称。 +- tablename:数据表名称。 +- outfile:数据库备份的文件。 +- options:mysqldump命令参数选项,多个参数之间可以使用空格分隔。常用的mysqldump命令参数选项如下: + - -u, \-\-user= _username_ :指定用户名。 + - -p, \-\-password\[= _password_\]:指定密码。 + - -P, \-\-port= _portnumber_ :指定端口。 + - -h, \-\-host= _hostname_ :指定主机名。 + - -r, \-\-result-file= _filename_ :将导出结果保存到指定的文件中,等同于“\>”。 + - -t:只备份数据。 + - -d:只备份表结构。 + +##### 示例 + +备份主机为192.168.202.144,端口为3306,root用户下的所有数据库到alldb.sql中。 + +```shell +mysqldump -h 192.168.202.144 -P 3306 -uroot -p123456 --all-databases > alldb.sql +``` + +备份主机为192.168.202.144,端口为3306,root用户下的db1数据库到db1.sql中。 + +```shell +mysqldump -h 192.168.202.144 -P 3306 -uroot -p123456 --databases db1 > db1.sql +``` + +备份主机为192.168.202.144,端口为3306,root用户下的db1数据库的tb1表到db1tb1.sql中。 + +```shell +mysqldump -h 192.168.202.144 -P 3306 -uroot -p123456 db1 tb1 > db1tb1.sql +``` + +只备份主机为192.168.202.144,端口为3306,root用户下的db1数据库的表结构到db1.sql中。 + +```shell +mysqldump -h 192.168.202.144 -P 3306 -uroot -p123456 -d db1 > db1.sql +``` + +只备份主机为192.168.202.144,端口为3306,root用户下的db1数据库的数据到db1.sql中。 + +```shell +mysqldump -h 192.168.202.144 -P 3306 -uroot -p123456 -t db1 > db1.sql +``` + +#### 恢复数据库 + +可以在root权限下使用mysql命令恢复数据库。 + +恢复一个或多个表: + +```shell +mysql -h hostname -P portnumber -u username -ppassword databasename < infile +``` + +其中: + +- hostname:主机名。 +- portnumber:端口号。 +- username:用户名。 +- password:密码。 +- databasename:数据库名。 +- infile:mysqldump命令中的outfile参数。 + +##### 示例 + +恢复数据库。 + +```shell +# mysql -h 192.168.202.144 -P 3306 -uroot -p123456 -t db1 < db1.sql +``` + +## MySQL服务器 + +### 软件介绍 + +MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle旗下产品。MySQL是业界最流行的RDBMS \(Relational Database Management System,关系数据库管理系统\)之一,尤其在WEB应用方面。 + +关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就加快了速度并提高了灵活性。 + +MySQL所使用的SQL语言是用于访问数据库的最常用标准化语言。MySQL软件采用了双授权模式,分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择MySQL作为网站数据库。 + +### 配置环境 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 以下环境配置仅为参考示例,具体配置视实际需求做配置 + +#### 关闭防火墙并取消开机自启动 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 测试环境下通常会关闭防火墙以避免部分网络因素影响,视实际需求做配置。 + +1. 在root权限下停止防火墙。 + + ```shell + systemctl stop firewalld + ``` + +2. 在root权限下关闭防火墙。 + + ```shell + systemctl disable firewalld + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 执行disable命令关闭防火墙的同时,也取消了开机自启动。 + +#### 修改SELINUX为disabled + +1. 在root权限下修改配置文件。 + + ```shell + sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux + ``` + +#### 创建组和用户 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 服务器环境下,为了系统安全,通常会为进程分配单独的用户,以实现权限隔离。本章节创建的组和用户都是操作系统层面的,不是数据库层面的。 + +1. 在root权限下创建MySQL用户(组)。 + + ```shell + groupadd mysql + ``` + + ```shell + useradd -g mysql mysql + ``` + +2. 在root权限下设置MySQL用户密码。 + + ```shell + passwd mysql + ``` + + 重复输入密码(根据实际需求设置密码)。 + +#### 搭建数据盘 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 进行性能测试时,数据目录使用单独硬盘,需要对硬盘进行格式化并挂载,参考方法一或者方法二。 +> 非性能测试时,在root权限下执行`mkdir /data`创建数据目录即可。然后跳过本小节。 + +##### 方法一:在root权限下使用fdisk进行磁盘管理 + +1. 创建分区(以/dev/sdb为例,根据实际情况创建) + + ```shell + fdisk /dev/sdb + ``` + +2. 输入n,按回车确认。 +3. 输入p,按回车确认。 +4. 输入1,按回车确认。 +5. 采用默认配置,按回车确认。 +6. 采用默认配置,按回车确认。 +7. 输入w,按回车保存。 +8. 创建文件系统(以xfs为例,根据实际需求创建文件系统) + + ```shell + mkfs.xfs /dev/sdb1 + ``` + +9. 挂载分区到“/data”以供操作系统使用。 + + ```shell + mkdir /data + ``` + + ```shell + mount /dev/sdb1 /data + ``` + +10. 执行命令“vi /etc/fstab", 编辑“/etc/fstab”使重启后自动挂载数据盘。如下图中,添加最后一行内容。 + + 其中,/dev/nvme0n1p1为示例,具体名称以实际情况为准。 + + ![](./figures/creat_datadisk.png) + +##### 方法二:在root权限下使用LVM进行磁盘管理 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 此步骤需要安装镜像中的lvm2相关包,步骤如下: +>(1)配置本地yum源,详细信息请参考[搭建repo服务器](./configuring-the-repo-server.md)。如果已经执行,则可跳过此步。 +>(2)执行`yum install lvm2`安装lvm2。 + +1. 创建物理卷(sdb为硬盘名称,具体名字以实际为准)。 + + ```shell + pvcreate /dev/sdb + ``` + +2. 创建物理卷组(其中datavg为创建的卷组名称,具体名字以实际规划为准)。 + + ```shell + vgcreate datavg /dev/sdb + ``` + +3. 创建逻辑卷(其中600G为规划的逻辑卷大小,具体大小以实际情况为准;datalv为创建的逻辑卷的名字,具体名称以实际规划为准。)。 + + ```shell + lvcreate -L 600G -n datalv datavg + ``` + +4. 创建文件系统。 + + ```shell + mkfs.xfs /dev/datavg/datalv + ``` + +5. 创建数据目录并挂载。 + + ```shell + mkdir /data + ``` + + ```shell + mount /dev/datavg/datalv /data + ``` + +6. 执行命令**vi /etc/fstab**,编辑“/etc/fstab”使重启后自动挂载数据盘。如下图中,添加最后一行内容。 + + 其中,/dev/datavg/datalv为示例,具体名称以实际情况为准。 + + ![](./figures/D1376B2A-D036-41C4-B852-E8368F363B5E-1.png) + +#### 创建数据库目录并且授权 + +1. 在已创建的数据目录 **/data** 基础上,使用root权限继续创建进程所需的相关目录并授权MySQL用户(组)。 + + ```shell + mkdir -p /data/mysql + cd /data/mysql + mkdir data tmp run log + chown -R mysql:mysql /data + ``` + +### 安装、运行和卸载 + +#### 安装 + +1. 配置本地yum源,详细信息请参考[搭建repo服务器](./configuring-the-repo-server.md)章节。 +2. 清除缓存。 + + ```shell + dnf clean all + ``` + +3. 创建缓存。 + + ```shell + dnf makecache + ``` + +4. 在root权限下安装MySQL服务器。 + + ```shell + dnf install mysql-server + ``` + +5. 查看安装后的rpm包。 + + ```shell + rpm -qa | grep mysql-server + ``` + +#### 运行 + +1. 修改配置文件。 + 1. 在root权限下创建my.cnf文件,其中文件路径(包括软件安装路径basedir、数据路径datadir等)根据实际情况修改。 + + ```shell + vi /etc/my.cnf + ``` + + 编辑my.cnf内容如下: + + ```text + [mysqld_safe] + log-error=/data/mysql/log/mysql.log + pid-file=/data/mysql/run/mysqld.pid + [mysqldump] + quick + [mysql] + no-auto-rehash + [client] + default-character-set=utf8 + [mysqld] + basedir=/usr/local/mysql + socket=/data/mysql/run/mysql.sock + tmpdir=/data/mysql/tmp + datadir=/data/mysql/data + default_authentication_plugin=mysql_native_password + port=3306 + user=mysql + ``` + + 2. 确保my.cnf配置文件修改正确。 + + ```shell + cat /etc/my.cnf + ``` + + ![](./figures/zh-cn_image_0231563132.png) + + > ![](./public_sys-resources/icon-caution.gif) **注意:** + > 其中basedir为软件安装路径,请根据实际情况修改。 + + 3. 在root权限下修改/etc/my.cnf文件的组和用户为mysql:mysql + + ```shell + chown mysql:mysql /etc/my.cnf + ``` + +2. 配置环境变量。 + 1. 安装完成后,在root权限下将MySQL二进制文件路径到PATH。 + + ```shell + echo export PATH=$PATH:/usr/local/mysql/bin >> /etc/profile + ``` + + > ![](./public_sys-resources/icon-caution.gif) **注意:** + > 其中PATH中的“/usr/local/mysql/bin“路径,为MySQL软件安装目录下的bin文件的绝对路径。请根据实际情况修改。 + + 2. 在root权限下使环境变量配置生效。 + + ```shell + source /etc/profile + ``` + +3. 在root权限下初始化数据库。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 本步骤倒数第2行中有初始密码,请注意保存,登录数据库时需要使用。 + + ```shell + # mysqld --defaults-file=/etc/my.cnf --initialize + 2020-03-18T03:27:13.702385Z 0 [System] [MY-013169] [Server] /usr/local/mysql/bin/mysqld (mysqld 8.0.17) initializing of server in progress as process 34014 + 2020-03-18T03:27:24.112453Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: iNat=)#V2tZu + 2020-03-18T03:27:28.576003Z 0 [System] [MY-013170] [Server] /usr/local/mysql/bin/mysqld (mysqld 8.0.17) initializing of server has completed + ``` + + 查看打印信息,打印信息中包括“initializing of server has completed”表示初始化数据库完成,且打印信息中“A temporary password is generated for root@localhost: iNat=\)V2tZu”的“iNat=\)V2tZu”为初始密码。 + +4. 启动数据库。 + + > ![](./public_sys-resources/icon-caution.gif) **注意:** + > 如果第一次启动数据库服务,以root用户启动数据库,则启动时会提示缺少mysql.log文件而导致失败。使用mysql用户启动之后,会在/data/mysql/log目录下生成mysql.log文件,再次使用root用户启动则不会报错。 + + 1. 在root权限下修改文件权限。 + + ```shell + chmod 777 /usr/local/mysql/support-files/mysql.server + chown mysql:mysql /var/log/mysql/* + ``` + + 2. 在root权限下启动MySQL。 + + ```shell + cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql + chkconfig mysql on + ``` + + 以mysql用户启动数据库。 + + ```shell + su - mysql + service mysql start + ``` + +5. 登录数据库。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 提示输入密码时,请输入[3](#li15634560582)产生的初始密码。 + > 如果采用官网RPM安装方式,则mysql文件在/usr/bin目录下。登录数据库的命令根据实际情况修改。 + + ```shell + # /usr/local/mysql/bin/mysql -uroot -p -S /data/mysql/run/mysql.sock + ``` + + ![](./figures/zh-cn_image_0231563134.png) + +6. 配置数据库帐号密码。 + 1. 登录数据库以后,修改通过root用户登录数据库的密码。 + + ```shell + mysql> alter user 'root'@'localhost' identified by "123456"; + ``` + + 2. 创建全域root用户(允许root从其他服务器访问)。 + + ```shell + mysql> create user 'root'@'%' identified by '123456'; + ``` + + 3. 进行授权。 + + ```shell + mysql> grant all privileges on *.* to 'root'@'%'; + mysql> flush privileges; + ``` + + ![](./figures/zh-cn_image_0231563135.png) + +7. 退出数据库。 + + 执行 **\\q** 或者 **exit** 退出数据库。 + + ```shell + mysql> exit + ``` + + ![](./figures/zh-cn_image_0231563136.png) + +#### 卸载 + +1. 在root权限下关闭数据库进程。 + + ```shell + ps -ef | grep mysql + kill -9 进程ID + ``` + +2. 在root权限下执行**dnf remove mysql**命令卸载MySQL。 + + ```shell + dnf remove mysql + ``` + +### 管理数据库用户 + +#### 创建用户 + +可以使用CREATE USER语句来创建一个或多个用户,并设置相应的口令。 + +```shell +CREATE USER 'username'@'hostname' IDENTIFIED BY 'password'; +``` + +其中: + +- username:用户名。 +- host:主机名,即用户连接数据库时所在的主机的名字。若是本地用户可用localhost,若在创建的过程中,未指定主机名,则主机名默认为“%”,表示一组主机。 +- password:用户的登录密码,密码可以为空,如果为空则该用户可以不需要密码登录服务器,但从安全的角度而言,不推荐这种做法。 + +使用CREATE USER语句必须拥有数据库的INSERT权限或全局CREATE USER权限。 + +使用CREATE USER语句创建一个用户帐号后,会在系统自身的数据库的user表中添加一条新记录。若创建的帐户已经存在,则语句执行时会出现错误。 + +新创建的用户拥有的权限很少,只允许进行不需要权限的操作,如使用SHOW语句查询所有存储引擎和字符集的列表等。 + +##### 示例 + +创建密码为123456,用户名为userexample1的本地用户。 + +```shell +> CREATE USER 'userexample1'@'localhost' IDENTIFIED BY '123456'; +``` + +创建密码为123456,用户名为userexample2,主机名为192.168.1.100的用户。 + +```shell +> CREATE USER 'userexample2'@'192.168.1.100' IDENTIFIED BY '123456'; +``` + +#### 查看用户 + +可以使用SHOW GRANTS语句或SELECT语句查看一个或多个用户。 + +查看特定用户: + +```shell +SHOW GRANTS [FOR 'username'@'hostname']; +``` + +```shell +SELECT USER,HOST,PASSWORD FROM mysql.user WHERE USER='username'; +``` + +查看所有用户: + +```shell +SELECT USER,HOST FROM mysql.user; +``` + +其中: + +- username:用户名。 +- hostname:主机名。 + +##### 示例 + +查看userexample1用户。 + +```shell +> SHOW GRANTS FOR 'userexample1'@'localhost'; +``` + +查看mysql数据库中所有用户。 + +```shell +> SELECT USER,HOST FROM mysql.user; +``` + +#### 修改用户 + +##### 修改用户名 + +可以使用RENAME USER语句修改一个或多个已经存在的用户名。 + +```shell +RENAME USER 'oldusername'@'hostname' TO 'newusername'@'hostname'; +``` + +其中: + +- oldusername:旧的用户名。 +- newusername:新的用户名。 +- hostname:主机名。 + +RENAME USER语句用于对原有的帐号进行重命名。若系统中旧帐号不存在或者新帐号已存在,则该语句执行时会出现错误。 + +使用RENAME USER语句,必须拥有数据库的UPDATE权限或全局CREATE USER权限。 + +##### 修改用户示例 + +将用户名userexample1修改为userexapme2,主机名为locahost。 + +```shell +> RENAME USER 'userexample1'@'localhost' TO 'userexample2'@'localhost'; +``` + +##### 修改用户密码 + +可以使用SET PASSWORD语句修改一个用户的登录密码。 + +```shell +SET PASSWORD FOR 'username'@'hostname' = 'newpassword'; +``` + +其中: + +- FOR 'username'@'hostname':FOR字句,可选项,指定欲修改密码的用户名及主机名。 +- 'newpassword':新密码。 + +在SET PASSWORD语句中,若不加上FOR子句,表示修改当前用户的密码。 + +FOR字句中必须以'username'@'hostname'的格式给定,username为帐户的用户名,hostname为帐户的主机名。 + +欲修改密码的帐号必须在系统中存在,否则语句执行时会出现错误。 + +##### 修改用户密码示例 + +将用户名为userexample的密码修改为0123456,主机名为locahost。 + +```shell +> SET PASSWORD FOR 'userexample'@'localhost' = '0123456'; +``` + +#### 删除用户 + +可以使用DROP USER语句来删除一个或多个用户帐号以及相关的权限。 + +```shell +DROP USER 'username1'@'hostname1' [,'username2'@'hostname2']…; +``` + +> ![](./public_sys-resources/icon-caution.gif) **注意:** +> 用户的删除不会影响他们之前所创建的表、索引或其他数据库对象,因为数据库并不会记录创建了这些对象的帐号。 + +DROP USER语句可用于删除一个或多个数据库帐号,并删除其原有权限。 + +使用DROP USER语句必须拥有数据库的DELETE权限或全局CREATE USER权限。 + +在DROP USER语句的使用中,若没有明确地给出帐号的主机名,则该主机名默认为“%”。 + +##### 示例 + +删除用户名为userexample的本地用户。 + +```shell +> DROP USER 'userexample'@'localhost'; +``` + +#### 用户授权 + +可以使用GRANT语句来对新建用户的授权。 + +```shell +GRANT privileges ON databasename.tablename TO 'username'@'hostname'; +``` + +其中: + +- ON字句:用于指定权限授予的对象和级别。 +- privileges:用户的操作权限,如SELECT,INSERT,UPDATE等,如果要授予所有的权限则使用ALL。 +- databasename:数据库名。 +- tablename:表名。 +- TO字句:用来设定用户密码,以及指定被赋予权限的用户。 +- username:用户名。 +- hostname:主机名。 + +如果要授予该用户对所有数据库和表的相应操作权限则可用\*表示,如\*.\*。 + +如果在TO子句中给系统中存在的用户指定密码,则新密码会将原密码覆盖。 + +如果权限被授予给一个不存在的用户,则会自动执行一条CREATE USER语句来创建这个用户,但同时必须为该用户指定密码。 + +##### 示例 + +对本地用户userexample授予SELECT和INSERT权限。 + +```shell +> GRANT SELECT,INSERT ON *.* TO 'userexample'@'localhost'; +``` + +#### 删除用户权限 + +可以使用REVOKE语句来删除一个用户的权限,但此用户不会被删除。 + +```shell +REVOKE privilege ON databasename.tablename FROM 'username'@'hostname'; +``` + +其中REVOKE语句的参数与GRANT语句的参数含义相同。 + +要使用 REVOKE 语句,必须拥有数据库的全局CREATE USER权限或UPDATE权限。 + +##### 示例 + +删除本地用户userexample的INSERT权限。 + +```shell +> REVOKE INSERT ON *.* FROM 'userexample'@'localhost'; +``` + +### 管理数据库 + +#### 创建数据库 + +可以使用CREATE DATABASE语句来创建数据库。 + +```shell +CREATE DATABASE databasename; +``` + +其中:databasename为数据库名称,且数据库名称不区分大小写。 + +##### 示例 + +创建数据库名为databaseexample的数据库。 + +```shell +> CREATE DATABASE databaseexample; +``` + +#### 查看数据库 + +可以使用SHOW DATABASES语句来查看数据库。 + +```shell +SHOW DATABASES; +``` + +##### 示例 + +查看所有数据库。 + +```shell +> SHOW DATABASES; +``` + +#### 选择数据库 + +一般创建表,查询表等操作首先需要选择一个目标数据库。可以使用USE语句来选择数据库。 + +```shell +USE databasename; +``` + +其中:databasename为数据库名称。 + +##### 示例 + +选择databaseexample数据库。 + +```shell +> USE databaseexample; +``` + +#### 删除数据库 + +可以使用DROP DATABASE语句来删除数据库。 + +> ![](./public_sys-resources/icon-caution.gif) **注意:** +> 删除数据库要谨慎操作,一旦删除,数据库中的所有表和数据都会删除。 + +```shell +DROP DATABASE databasename; +``` + +其中:databasename为数据库名称。 + +DROP DATABASE命令用于删除创建过\(已存在\)的数据库,且会删除数据库中的所有表,但数据库的用户权限不会自动删除。 + +要使用DROP DATABASE,您需要数据库的DROP权限。 + +DROP SCHEMA是DROP DATABASE的同义词。 + +##### 示例 + +删除databaseexample数据库。 + +```shell +> DROP DATABASE databaseexample; +``` + +#### 备份数据库 + +可以在root权限下使用mysqldump命令备份数据库。 + +备份一个或多个表: + +```shell +mysqldump [options] databasename [tablename ...] > outfile +``` + +备份一个或多个库: + +```shell +mysqldump [options] -databases databasename ... > outfile +``` + +备份所有库: + +```shell +mysqldump [options] -all-databases > outputfile +``` + +其中: + +- databasename:数据库名称。 +- tablename:数据表名称。 +- outfile:数据库备份的文件。 +- options:mysqldump命令参数选项,多个参数之间可以使用空格分隔。常用的mysqldump命令参数选项如下: + - -u, \-\-user= _username_ :指定用户名。 + - -p, \-\-password\[= _password_\]:指定密码。 + - -P, \-\-port= _portnumber_ :指定端口。 + - -h, \-\-host= _hostname_ :指定主机名。 + - -r, \-\-result-file= _filename_ :将导出结果保存到指定的文件中,等同于“\>”。 + - -t:只备份数据。 + - -d:只备份表结构。 + +##### 示例 + +备份主机为192.168.202.144,端口为3306,root用户下的所有数据库到alldb.sql中。 + +```shell +mysqldump -h 192.168.202.144 -P 3306 -uroot -p123456 --all-databases > alldb.sql +``` + +备份主机为192.168.202.144,端口为3306,root用户下的db1数据库到db1.sql中。 + +```shell +mysqldump -h 192.168.202.144 -P 3306 -uroot -p123456 --databases db1 > db1.sql +``` + +备份主机为192.168.202.144,端口为3306,root用户下的db1数据库的tb1表到db1tb1.sql中。 + +```shell +mysqldump -h 192.168.202.144 -P 3306 -uroot -p123456 db1 tb1 > db1tb1.sql +``` + +只备份主机为192.168.202.144,端口为3306,root用户下的db1数据库的表结构到db1.sql中。 + +```shell +mysqldump -h 192.168.202.144 -P 3306 -uroot -p123456 -d db1 > db1.sql +``` + +只备份主机为192.168.202.144,端口为3306,root用户下的db1数据库的数据到db1.sql中。 + +```shell +mysqldump -h 192.168.202.144 -P 3306 -uroot -p123456 -t db1 > db1.sql +``` + +#### 恢复数据库 + +可以在root权限下使用mysql命令恢复数据库。 + +恢复一个或多个表: + +```shell +mysql -h hostname -P portnumber -u username -ppassword databasename < infile +``` + +其中: + +- hostname:主机名。 +- portnumber:端口号。 +- username:用户名。 +- password:密码。 +- databasename:数据库名。 +- infile:mysqldump命令中的outfile参数。 + +##### 示例 + +恢复数据库。 + +```shell +# mysql -h 192.168.202.144 -P 3306 -uroot -p123456 -t db1 < db1.sql +``` diff --git a/docs/en/25.03/Server/Administration/Administrator/user-and-user-group-management.md b/docs/en/25.03/Server/Administration/Administrator/user-and-user-group-management.md new file mode 100644 index 0000000000000000000000000000000000000000..fb803cd42aa2e98a4cd1d575a97f02de11224b88 --- /dev/null +++ b/docs/en/25.03/Server/Administration/Administrator/user-and-user-group-management.md @@ -0,0 +1,324 @@ +# 管理用户 + +在Linux中,每个普通用户都有一个帐户,包括用户名、密码和主目录等信息。除此之外,还有一些系统本身创建的特殊用户,它们具有特殊的意义,其中最重要的是管理员帐户,默认用户名是root。同时Linux也提供了用户组,使每一个用户至少属于一个组,从而便于权限管理。 + +用户和用户组管理是系统安全管理的重要组成部分,本章主要介绍openEuler提供的用户管理和组管理命令,以及为普通用户分配特权的方法。 + +## 管理用户 + +### 增加用户 + +#### useradd命令 + +在root权限下,通过useradd命令可以为系统添加新用户信息,其中 _options_ 为相关参数, _username_ 为用户名称。 + +```shell +useradd [options] username +``` + +#### 用户信息文件 + +与用户帐号信息有关的文件如下: + +- /etc/passwd:用户帐号信息文件。 +- /etc/shadow:用户帐号信息加密文件。 +- /etc/group:组信息文件。 +- /etc/default/useradd:定义默认设置文件。 +- /etc/login.defs:系统广义设置文件。 +- /etc/skel:默认的初始配置文件目录。 + +#### 创建用户实例 + +例如新建一个用户名为userexample的用户,在root权限下执行如下命令: + +```shell +# useradd userexample +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 没有任何提示,表明用户建立成功。这时并没有设置用户的口令,请使用passwd命令修改用户的密码,没有设置密码的新帐号不能登录系统。 + +使用id命令查看新建的用户信息,命令如下: + +```shell +# id userexample +uid=502(userexample) gid=502(userexample) groups=502(userexample) +``` + +修改用户userexample的密码: + +```shell +# passwd userexample +``` + +建议在修改用户密码时满足密码复杂度要求,密码的复杂度的要求如下: + +1. 口令长度至少8个字符。 +2. 口令至少包含大写字母、小写字母、数字和特殊字符中的任意3种。 +3. 口令不能和帐号一样。 +4. 口令不能使用字典词汇。 + - 查询字典 + 在已装好的openEuler环境中,可以通过如下命令导出字典库文件dictionary.txt,用户可以查询密码是否在该字典中。 + + ```shell + cracklib-unpacker /usr/share/cracklib/pw_dict > dictionary.txt + ``` + + - 修改字典 + 1. 修改上面导出的字典文件,执行如下命令更新系统字典库。 + + ```shell + # create-cracklib-dict dictionary.txt + ``` + + 2. 在原字典库基础上新增其他字典内容custom.txt。 + + ```shell + # create-cracklib-dict dictionary.txt custom.txt + ``` + +根据提示两次输入新用户的密码,完成密码更改。过程如下: + +```shell +# passwd userexample +Changing password for user userexample. +New password: +Retype new password: +passwd: all authentication tokens updated successfully. +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 若打印信息中出现“BAD PASSWORD: The password fails the dictionary check - it is too simplistic/systematic”,表示设置的密码过于简单,建议设置复杂度较高的密码。 + +### 修改用户帐号 + +#### 修改密码 + +普通用户可以用passwd修改自己的密码,只有管理员才能用passwd username为其他用户修改密码。 + +#### 修改用户shell设置 + +使用chsh命令可以修改自己的shell,只有管理员才能用chsh username为其他用户修改shell设置。 + +用户也可以使用usermod命令修改shell信息,在root权限下执行如下命令,其中 _new\_shell\_path_ 为目标shell路径,_username_ 为要修改用户的用户名,请根据实际情况修改: + +```shell +usermod -s new_shell_path username +``` + +例如,将用户userexample的shell改为csh,命令如下: + +```shell +# usermod -s /bin/csh userexample +``` + +#### 修改主目录 + +- 修改主目录,可以在root权限下执行如下命令,其中 _new\_home\_directory_ 为已创建的目标主目录的路径,_username_ 为要修改用户的用户名,请根据实际情况修改: + + ```shell + usermod -d new_home_directory username + ``` + +- 如果想将现有主目录的内容转移到新的目录,应该使用-m选项,命令如下: + + ```shell + usermod -d new_home_directory -m username + ``` + +#### 修改UID + +修改用户ID,在root权限下执行如下命令,其中 _UID_ 代表目标用户ID,_username_ 代表用户名,请根据实际情况修改: + +```shell +usermod -u UID username +``` + +该用户主目录中所拥有的文件和目录都将自动修改UID设置。但是,对于主目录外所拥有的文件,只能使用chown命令手动修改所有权。 + +#### 修改帐号的有效期 + +如果使用了影子口令,则可以在root权限下,执行如下命令来修改一个帐号的有效期,其中 _MM_ 代表月份,_DD_ 代表某天,_YY_ 代表年份,_username_ 代表用户名,请根据实际情况修改: + +```shell +usermod -e MM/DD/YY username +``` + +### 删除用户 + +在root权限下,使用userdel命令可删除现有用户。 + +例如,删除用户Test,命令如下: + +```shell +# userdel Test +``` + +如果想同时删除该用户的主目录以及其中所有内容,要使用-r参数递归删除。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 不建议直接删除已经进入系统的用户,如果需要强制删除,请使用 userdel -f _Test_ 命令。 + +### 管理员帐户授权 + +使用sudo命令可以允许普通用户执行管理员帐户才能执行的命令。 + +sudo命令允许已经在/etc/sudoers文件中指定的用户运行管理员帐户命令。例如,一个已经获得许可的普通用户可以运行如下命令: + +```shell +sudo /usr/sbin/useradd newuserl +``` + +实际上,sudo的配置完全可以指定某个已经列入/etc/sudoers文件的普通用户可以做什么,不可以做什么。 + +/etc/sudoers的配置行如下所示。 + +- 空行或注释行(以\#字符打头):无具体功能的行。 +- 可选的主机别名行:用来创建主机列表的简称。必须以Host\_Alias关键词开头,列表中的主机必须用逗号隔开,如: + + ```shell + Host_Alias linux=ted1,ted2 + ``` + + 其中ted1和ted2是两个主机名,可使用linux(别名)称呼它们。 + +- 可选的用户别名行:用来创建用户列表的简称。用户别名行必须以User\_Alias关键词开头,列表中的用户名必须以逗号隔开。其格式同主机别名行。 +- 可选的命令别名行:用来创建命令列表的简称。必须以Cmnd\_Alias开头,列表中的命令必须用逗号隔开。 +- 可选的运行方式别名行:用来创建用户列表的简称。不同的是,使用这样的别名可以告诉sudo程序以列表中某一用户的身份来运行程序。 +- 必要的用户访问说明行。 + + 用户访问的说明语法如下: + + ```text + user host = [ run as user ] command list + ``` + + 在user处指定一个真正的用户名或定义过的别名,host也可以是一个真正的主机名或者定义过的主机别名。默认情况下,sudo执行的所有命令都是以root身份执行。如果您想使用其他身份可以指定。command list可以是以逗号分隔的命令列表,也可以是一个已经定义过的别名,如: + + ```text + ted1 ted2=/sbin/shutdown + ``` + + 这一句说明ted1可以在ted2主机上运行关机命令。 + + ```text + newuser1 ted1=(root) /usr/sbin/useradd,/usr/sbin/userdel + ``` + + 这一句说明ted1主机上的newuser1具有以root用户权限执行useradd,userdel命令的功能。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 可以在一行定义多个别名,中间用冒号 \(:\) 隔开。 + > 可在命令或命令别名之前加上感叹号 \(!\),使该命令或命令别名无效。 + > 有两个关键词:ALL和NOPASSWD。ALL意味着“所有”(所有文件、所有主机或所有命令),NOPASSWD意味着不用密码。 + > 通过修改用户访问,将普通用户的访问权限修改为同root一样,则可以给普通用户分配特权。 + +下面是一个sudoers文件的例子: + +```text +#sudoers files +#User alias specification +User_Alias ADMIN=ted1:POWERUSER=globus,ted2 +#user privilege specification +ADMIN ALL=ALL +POWERUSER ALL=ALL,!/bin/su +``` + +其中: + +- User\_Alias ADMIN=ted1:POWERUSER=globus,ted2 + + 定义了两个别名ADMIN和POWERUSER + +- ADMIN ALL=ALL + + 说明在所有主机上,ADMIN用户都可以以root身份执行所有命令 + +- POWERUSER ALL=ALL,!/bin/su + + 给POWERUSER用户除了运行su命令外等同ADMIN的权限 + +## 管理用户组 + +### 增加用户组 + +#### groupadd命令 + +在root权限下,通过groupadd命令可以为系统添加新用户组信息,其中 _options_ 为相关参数, _groupname_ 为用户组名称。 + +```shell +groupadd [options] groupname +``` + +#### 用户组信息文件 + +与用户组信息有关的文件如下: + +- /etc/gshadow:用户组信息加密文件。 +- /etc/group:组信息文件。 +- /etc/login.defs:系统广义设置文件。 + +#### 创建用户组实例 + +例如新建一个用户组名为groupexample的用户,在root权限下执行如下命令: + +```shell +# groupadd groupexample +``` + +### 修改用户组 + +#### 修改GID + +修改用户组ID,在root权限下执行如下命令,其中 _GID_ 代表目标用户组ID, _groupname_ 代表用户组,请根据实际情况修改: + +```shell +# groupmod -g GID groupname +``` + +#### 修改用户组名 + +修改用户组名,在root权限下执行如下命令,其中 _newgroupname_ 代表新用户组名, _oldgroupname_ 代表已经存在的待修改的用户组名,请根据实际情况修改: + +```shell +# groupmod -n newgroupname oldgroupname +``` + +### 删除用户组 + +在root权限下,使用groupdel命令可删除用户组。 + +例如,删除用户组Test,命令如下: + +```shell +# groupdel Test +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> groupdel不能直接删除用户的主组,如果需要强制删除用户主组,请使用 groupdel -f _Test_ 命令。 + +### 将用户加入用户组或从用户组中移除 + +在root权限下,使用gpasswd命令将用户加入用户组或从用户组中移除。 + +例如,将用户 _userexample_ 加入用户组 _Test_ ,命令如下: + +```shell +# gpasswd -a userexample Test +``` + +例如,将用户 _userexample_ 从 _Test_ 用户组中移除,命令如下: + +```shell +# gpasswd -d userexample Test +``` + +### 切换用户组 + +一个用户同时属于多个用户组时,则在用户登录后,使用newgrp命令可以切换到其他用户组,以便具有其他用户组的权限。 + +例如,将用户 _userexample_ 切换到 _Test_ 用户组,命令如下: + +```shell +newgrp Test +``` diff --git a/docs/en/25.03/Server/Administration/Administrator/using-dnf-to-manage-software-packages.md b/docs/en/25.03/Server/Administration/Administrator/using-dnf-to-manage-software-packages.md new file mode 100644 index 0000000000000000000000000000000000000000..b5db583349ca1b61019468c039c4ede7836cab2d --- /dev/null +++ b/docs/en/25.03/Server/Administration/Administrator/using-dnf-to-manage-software-packages.md @@ -0,0 +1,419 @@ +# 使用DNF管理软件包 + +DNF是一款Linux软件包管理工具,用于管理RPM软件包。DNF可以查询软件包信息,从指定软件库获取软件包,自动处理依赖关系以安装或卸载软件包,以及更新系统到最新可用版本。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> DNF与YUM完全兼容,提供了YUM兼容的命令行以及为扩展和插件提供的API。 +> 使用DNF需要管理员权限,本章所有命令需要在管理员权限下执行。 + +## 配置DNF + +### DNF配置文件 + +DNF 的主要配置文件是 /etc/dnf/dnf.conf,该文件包含两部分: + +- “main”部分保存着DNF的全局设置。 + +- “repository”部分保存着软件源的设置,可以有零个或多个“repository”。 + +另外,在/etc/yum.repos.d 目录中保存着零个或多个repo源相关文件,它们也可以定义不同的“repository”。 + +所以openEuler软件源的配置一般有两种方式,一种是直接配置/etc/dnf/dnf.conf文件中的“repository”部分,另外一种是在/etc/yum.repos.d目录下增加.repo文件。 + +#### 配置main部分 + +/etc/dnf/dnf.conf 文件包含的“main”部分,配置示例如下: + +```text +[main] +gpgcheck=1 +installonly_limit=3 +clean_requirements_on_remove=True +best=True +``` + +常用选项说明: + +**表 1** main参数说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

说明

+

cachedir

+

缓存目录,该目录用于存储RPM包和数据库文件。

+

keepcache

+

可选值是1和0,表示是否要缓存已安装成功的那些RPM包及头文件,缺省值为0,即不缓存。

+

debuglevel

+

设置dnf生成的debug信息。取值范围:[0-10],数值越大会输出越详细的debug信息。缺省值为2,设置为0表示不输出debug信息。

+

clean_requirements_on_remove

+

删除在dnf remove期间不再使用的依赖项,如果软件包是通过DNF安装的,而不是通过显式用户请求安装的,则只能通过clean_requirements_on_remove删除软件包,即它是作为依赖项引入的。 缺省值为True。

+

best

+

升级包时,总是尝试安装其最高版本,如果最高版本无法安装,则提示无法安装的原因并停止安装。缺省值为True。

+

obsoletes

+

可选值1和0,设置是否允许更新陈旧的RPM包。缺省值为1,表示允许更新。

+

gpgcheck

+

可选值1和0,设置是否进行gpg校验。缺省值为1,表示需要进行校验。

+

plugins

+

可选值1和0,表示启用或禁用dnf插件。缺省值为1,表示启用dnf插件。

+

installonly_limit

+

设置可以同时安装“installonlypkgs”指令列出包的数量。缺省值为3,不建议降低此值。

+
+ +#### 配置repository部分 + +repository部分允许您定义定制化的openEuler软件源仓库,各个仓库的名称不能相同,否则会引起冲突。配置repository部分有两种方式,一种是直接配置/etc/dnf/dnf.conf文件中的“repository”部分,另外一种是配置/etc/yum.repos.d目录下的.repo文件。 + +- 直接配置/etc/dnf/dnf.conf文件中的“repository”部分 + + 下面是\[repository\]部分的一个最小配置示例: + + ```text + [repository] + name=repository_name + baseurl=repository_url + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > openEuler提供在线的镜像源,地址:[https://repo.openeuler.org/](https://repo.openeuler.org/)。以 openEuler 23.09的aarch64版本为例,baseurl可配置为[https://repo.openeuler.org/openEuler-23.09/OS/aarch64/](https://repo.openeuler.org/openEuler-23.09/OS/aarch64/)。 + + 选项说明: + + **表 2** repository参数说明 + | 参数
| 说明
| + |--------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------| + | name=repository_name
| 软件仓库(repository )描述的字符串。
| + | baseurl=repository_url
| 软件仓库(repository )的地址。
使用http协议的网络位置:例如
使用ftp协议的网络位置:例如
本地位置:例如 file://path/to/local/repo
| + +- 配置/etc/yum.repos.d目录下的.repo文件 + + openEuler提供了多种repo源供用户在线使用,各repo源含义可参考[系统安装](../../Releasenotes/Releasenotes/installing-the-os.md)。使用root权限添加openEuler repo源,示例如下: + + ```shell + # vi /etc/yum.repos.d/openEuler.repo + + [OS] + name=openEuler-$releasever-OS + baseurl=https://repo.openeuler.org/openEuler-23.09/OS/$basearch/ + enabled=1 + gpgcheck=1 + gpgkey=https://repo.openeuler.org/openEuler-23.09/OS/$basearch/RPM-GPG-KEY-openEuler + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > enabled为是否启用该软件源仓库,可选值为1和0。缺省值为1,表示启用该软件源仓库。 + > gpgkey为验证签名用的公钥。 + +#### 显示当前配置 + +- 显示当前的配置信息: + + ```shell + # dnf config-manager --dump + ``` + +- 显示相应软件源的配置,首先查询repo id: + + ```shell + # dnf repolist + ``` + + 然后执行如下命令,显示对应id的软件源配置,其中 *repository* 为查询得到的repo id: + + ```shell + # dnf config-manager --dump repository + ``` + +- 您也可以使用一个全局正则表达式,来显示所有匹配部分的配置: + + ```shell + # dnf config-manager --dump glob_expression + ``` + +### 创建本地软件源仓库 + +要建立一个本地软件源仓库,请按照下列步骤操作。 + +1. 安装createrepo软件包。 + + ```shell + # dnf install createrepo + ``` + +2. 将需要的软件包复制到一个目录下,如/mnt/local\_repo/ 。 + +3. 创建软件源。 + + ```shell + # createrepo /mnt/local_repo + ``` + +### 添加、启用和禁用软件源 + +本节将介绍如何通过“dnf config-manager”命令添加、启用和禁用软件源仓库。 + +#### 添加软件源 + +要定义一个新的软件源仓库,您可以在 /etc/dnf/dnf.conf 文件中添加“repository”部分,或者在/etc/yum.repos.d/目录下添加“.repo”文件进行说明。建议您通过添加“.repo”的方式,每个软件源都有自己对应的“.repo”文件,以下介绍该方式的操作方法。 + +要在您的系统中添加一个这样的源,请在root权限下执行如下命令,执行完成之后会在/etc/yum.repos.d/目录下生成对应的repo文件。其中 *repository\_url* 为repo源地址,详情请参见[表2](#zh-cn_topic_0151921080_t7c83ace02ab94e9986c0684f417e3436)。 + +```shell +# dnf config-manager --add-repo repository_url +``` + +#### 启用软件源 + +要启用软件源,请在root权限下执行如下命令,其中 *repository* 为新增.repo文件中的repo id(可通过dnf repolist查询): + +```shell +# dnf config-manager --set-enable repository +``` + +您也可以使用一个全局正则表达式,来启用所有匹配的软件源。其中 *glob\_expression* 为对应的正则表达式,用于同时匹配多个repo id: + +```shell +# dnf config-manager --set-enable glob_expression +``` + +#### 禁用软件源 + +要禁用软件源,请在root权限下执行如下命令: + +```shell +# dnf config-manager --set-disable repository +``` + +同样的,您也可以使用一个全局正则表达式来禁用所有匹配的软件源: + +```shell +# dnf config-manager --set-disable glob_expression +``` + +## 管理软件包 + +使用dnf能够让您方便的进行查询、安装、删除软件包等操作。 + +### 搜索软件包 + +您可以使用rpm包名称、缩写或者描述搜索需要的RPM包,使用命令如下: + +```shell +# dnf search httpd (以httpd为例) +``` + +### 列出软件包清单 + +要列出系统中所有已安装的以及可用的RPM包信息,使用命令如下: + +```shell +# dnf list all +``` + +要列出系统中特定的RPM包信息,使用命令如下: + +```shell +# dnf list httpd (以httpd为例) +``` + +### 显示RPM包信息 + +要显示一个或者多个RPM包信息,多个包之间以空格分隔,使用命令如下: + +```shell +# dnf info httpd zip (以httpd,zip两个包为例) +``` + +### 安装RPM包 + +要安装一个软件包及其所有未安装的依赖,请在root权限下执行如下命令: + +```shell +# dnf install package_name +``` + +您也可以通过添加软件包名字同时安装多个软件包。配置文件/etc/dnf/dnf.conf添加参数strict=False,运行dnf命令参数添加\-\-setopt=strict=0。请在root权限下执行如下命令: + +```shell +# dnf install package_name package_name... --setopt=strict=0 +``` + +示例如下: + +```shell +# dnf install httpd +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 安装RPM包过程中,若出现安装失败,可参考[安装时出现软件包冲突、文件冲突或缺少软件包导致安装失败](./faqs.md#安装时出现软件包冲突文件冲突或缺少软件包导致安装失败)。 + +### 下载软件包 + +使用dnf下载软件包,请在root权限下输入如下命令: + +```shell +# dnf download package_name +``` + +如果需要同时下载未安装的依赖,则加上\-\-resolve,使用命令如下: + +```shell +# dnf download --resolve package_name +``` + +示例如下: + +```shell +# dnf download --resolve httpd +``` + +### 删除软件包 + +要卸载软件包以及相关的依赖软件包,请在root权限下执行如下命令: + +```shell +# dnf remove package_name... +``` + +示例如下: + +```shell +# dnf remove totem +``` + +## 管理软件包组 + +软件包集合是服务于一个共同的目的一组软件包,例如系统工具集等。使用dnf可以对软件包组进行安装/删除等操作,使相关操作更高效。 + +### 列出软件包组清单 + +使用summary参数,可以列出系统中所有已安装软件包组、可用的组,可用的环境组的数量,命令如下: + +```shell +# dnf groups summary +``` + +要列出所有软件包组和它们的组ID ,命令如下: + +```shell +# dnf group list +``` + +### 显示软件包组信息 + +要列出包含在一个软件包组中必须安装的包和可选包,使用命令如下: + +```shell +# dnf group info glob_expression... +``` + +例如显示Development Tools信息,示例如下: + +```shell +# dnf group info "Development Tools" +``` + +### 安装软件包组 + +每一个软件包组都有自己的名称以及相应的ID(groupid),您可以使用软件包组名称或它的ID进行安装。 + +要安装一个软件包组,请在root权限下执行如下命令: + +```shell +# dnf group install group_name +# dnf group install groupid +``` + +例如安装Development Tools相应的软件包组,命令如下: + +```shell +# dnf group install "Development Tools" +# dnf group install development +``` + +### 删除软件包组 + +要卸载软件包组,您可以使用软件包组名称或它的ID,在root权限下执行如下命令: + +```shell +# dnf group remove group_name +# dnf group remove groupid +``` + +例如删除Development Tools相应的软件包组,命令如下: + +```shell +# dnf group remove "Development Tools" +# dnf group remove development +``` + +## 检查并更新 + +dnf可以检查您的系统中是否有软件包需要更新。您可以通过dnf列出需要更新的软件包,并可以选择一次性全部更新或者只对指定包进行更新。 + +### 检查更新 + +如果您需要显示当前系统可用的更新,使用命令如下: + +```shell +# dnf check-update +``` + +### 升级 + +如果您需要升级单个软件包,在root权限下执行如下命令: + +```shell +# dnf update package_name +``` + +例如升级rpm包,示例如下: + +```shell +# dnf update anaconda-gui.aarch64 (以anaconda-gui包为例) +``` + +类似的,如果您需要升级软件包组,在root权限下执行如下命令: + +```shell +# dnf group update group_name +``` + +### 更新所有的包和它们的依赖 + +要更新所有的包和它们的依赖,在root权限下执行如下命令: + +```shell +# dnf update +``` diff --git a/docs/en/25.03/Server/Administration/Administrator/viewing-system-information.md b/docs/en/25.03/Server/Administration/Administrator/viewing-system-information.md new file mode 100644 index 0000000000000000000000000000000000000000..87473680384a361ab9f7d8f38f4c3c8c870783d8 --- /dev/null +++ b/docs/en/25.03/Server/Administration/Administrator/viewing-system-information.md @@ -0,0 +1,45 @@ +# 查看系统信息 + +- 查看系统信息,命令如下: + + ```shell + cat /etc/os-release + ``` + + 例如,命令和输出如下: + + ```shell + $ cat /etc/os-release + NAME="openEuler" + VERSION="23.09" + ID="openEuler" + VERSION_ID="23.09" + PRETTY_NAME="openEuler 23.09" + ANSI_COLOR="0;31" + ``` + +- 查看系统相关的资源信息。 + + 查看CPU信息,命令如下: + + ```shell + # lscpu + ``` + + 查看内存信息,命令如下: + + ```shell + free + ``` + + 查看磁盘信息,命令如下: + + ```shell + fdisk -l + ``` + +- 查看系统资源实时信息,命令如下: + + ```shell + top + ``` diff --git a/docs/en/25.03/Server/Administration/CompaCommand/_menu.md b/docs/en/25.03/Server/Administration/CompaCommand/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..041e2b9858750adda95abe57ed9c204796c5ded2 --- /dev/null +++ b/docs/en/25.03/Server/Administration/CompaCommand/_menu.md @@ -0,0 +1,10 @@ +--- +label: '兼容性命令' +ismanual: 'Y' +description: '基于 Rust 语言重构的 shell 及 Linux 命令,与 Linux 原生命令兼容' +children: + - label: 'utshell用户指南' + href: './utshell_guide.md' + - label: 'utsudo用户指南' + href: './utsudo_user_guide.md' +--- diff --git a/docs/en/25.03/Server/Administration/CompaCommand/figures/image-20230828094539717.png b/docs/en/25.03/Server/Administration/CompaCommand/figures/image-20230828094539717.png new file mode 100644 index 0000000000000000000000000000000000000000..db620cb37b44ba6cc3c30035ce65a2ef5a18efea Binary files /dev/null and b/docs/en/25.03/Server/Administration/CompaCommand/figures/image-20230828094539717.png differ diff --git a/docs/en/25.03/Server/Administration/CompaCommand/figures/image-20230828094723153.png b/docs/en/25.03/Server/Administration/CompaCommand/figures/image-20230828094723153.png new file mode 100644 index 0000000000000000000000000000000000000000..fe85725a5748b7405bf0c4ac104158449098403e Binary files /dev/null and b/docs/en/25.03/Server/Administration/CompaCommand/figures/image-20230828094723153.png differ diff --git a/docs/en/25.03/Server/Administration/CompaCommand/figures/image-20230828135001624.png b/docs/en/25.03/Server/Administration/CompaCommand/figures/image-20230828135001624.png new file mode 100644 index 0000000000000000000000000000000000000000..2b17e0dd49ad6ec34028fc233738581d0fa6e209 Binary files /dev/null and b/docs/en/25.03/Server/Administration/CompaCommand/figures/image-20230828135001624.png differ diff --git a/docs/en/25.03/Server/Administration/CompaCommand/figures/image-20230828140355863.png b/docs/en/25.03/Server/Administration/CompaCommand/figures/image-20230828140355863.png new file mode 100644 index 0000000000000000000000000000000000000000..de9dbabc6e6f8a157a18e23ee8fbeb68ec2630e1 Binary files /dev/null and b/docs/en/25.03/Server/Administration/CompaCommand/figures/image-20230828140355863.png differ diff --git a/docs/en/25.03/Server/Administration/CompaCommand/figures/image-20230828140709441.png b/docs/en/25.03/Server/Administration/CompaCommand/figures/image-20230828140709441.png new file mode 100644 index 0000000000000000000000000000000000000000..9dd87d5c65190428efd9bf81ee18e8809d6cc6d9 Binary files /dev/null and b/docs/en/25.03/Server/Administration/CompaCommand/figures/image-20230828140709441.png differ diff --git a/docs/en/25.03/Server/Administration/CompaCommand/media/media/image1.png b/docs/en/25.03/Server/Administration/CompaCommand/media/media/image1.png new file mode 100644 index 0000000000000000000000000000000000000000..feff5b7bae51f432b5a8a05828295ace5b2f616d Binary files /dev/null and b/docs/en/25.03/Server/Administration/CompaCommand/media/media/image1.png differ diff --git a/docs/en/25.03/Server/Administration/CompaCommand/media/media/image2.png b/docs/en/25.03/Server/Administration/CompaCommand/media/media/image2.png new file mode 100644 index 0000000000000000000000000000000000000000..c241e9356595daf58732a25a2bb31cd0a75bd027 Binary files /dev/null and b/docs/en/25.03/Server/Administration/CompaCommand/media/media/image2.png differ diff --git a/docs/en/25.03/Server/Administration/CompaCommand/media/media/image3.png b/docs/en/25.03/Server/Administration/CompaCommand/media/media/image3.png new file mode 100644 index 0000000000000000000000000000000000000000..f00123d7b8553d8b7c374c7a0becd4269a663084 Binary files /dev/null and b/docs/en/25.03/Server/Administration/CompaCommand/media/media/image3.png differ diff --git a/docs/en/25.03/Server/Administration/CompaCommand/media/media/image4.png b/docs/en/25.03/Server/Administration/CompaCommand/media/media/image4.png new file mode 100644 index 0000000000000000000000000000000000000000..9a047ff75fb1144c7df513345acef97357aa82b7 Binary files /dev/null and b/docs/en/25.03/Server/Administration/CompaCommand/media/media/image4.png differ diff --git a/docs/en/25.03/Server/Administration/CompaCommand/overview.md b/docs/en/25.03/Server/Administration/CompaCommand/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..847b50270f91686278a8fa70b96144c557929ddf --- /dev/null +++ b/docs/en/25.03/Server/Administration/CompaCommand/overview.md @@ -0,0 +1,3 @@ +# 兼容性命令 + +本文档是介绍基于 Rust 语言重构的 shell 及 Linux 命令,可在 openEuler 系统上使用,与 Linux 原生命令兼容。 diff --git a/docs/en/25.03/Server/Administration/CompaCommand/utshell_guide.md b/docs/en/25.03/Server/Administration/CompaCommand/utshell_guide.md new file mode 100644 index 0000000000000000000000000000000000000000..65a02a46f73e2e9358d9079ce45716894bf3ba66 --- /dev/null +++ b/docs/en/25.03/Server/Administration/CompaCommand/utshell_guide.md @@ -0,0 +1,273 @@ +# utshell 用户手册 + +## 介绍 + +utshell 是一个与 bash 兼容的 shell。它实现了基本的内建命令执行和启动外部命令。同时也实现了任务、管道和信号处理等功能。 + +## 安装和卸载 + +### 安装 + +utshell 使用 rpm 命令进行安装,我们假设使用的是欧拉的 2309 系统: + +进入命令行界面执行: + +![截图.png](./media/media/image1.png) + +根据提示输入\"y\",即可安装成功。 + +![截图.png](./media/media/image2.png) + +### 卸载 + +在命令行执行`rpm -e utshell`即可卸载 utshell。 + +```shell + +rpm -e utshell + +``` + +![截图.png](./media/media/image3.png) + +## 使用 + +### 一般命令 + +在 utshell 环境下,直接键入命令名即可执行对应的命令。 + +utshell 支持如下内建命令: + +![截图.png](./media/media/image4.png) + +### 变量定义和使用 + +#### 变量定义 + +变量定义直接用\"=\",中间不能有空格。 + +```shell + +var=4 + +``` + +#### 变量使用 + +```shell + +echo \${var} + +``` + +### 数组的定义和使用 + +#### 数组的定义 + +```shell + +distros=(ubuntu fedora suse \"arch linux\") + +``` + +#### 数组的使用 + +```shell + +echo \${distros\[2\]} + +``` + +### 函数定义和使用 + +#### 函数的定义 + +```shell + +func() { echo \$1; } + +``` + +#### 函数的调用 + +```shell + +func 1 + +``` + +#### 给函数传递参数 + +调用函数时,在函数名后面直接以空格分割参数: + +func firstParam secondParam + +在函数体中使用\$1,\$2\...\...其中\$1 表示第一个参数,\$2 表示第二个参数,大于 9 的需要用大括号括起来。 + +```shell + +func() { + +echo \$1 \${10} \#需要传递 10 个参数 + +} + +\#调用 + +func 1 2 3 4 5 6 7 8 9 0 + +``` + +### 逻辑判断 + +#### if 语句 + +语法为: + +```shell + +if condition; then + +do-if-true; + +elif second-condition; then + +do-else-if-true + +elif third-condition; then + +do-else-if-third-true + +else + +do-else-false + +fi + +``` + +其中 condition 可以是命令,如: + +```shell + +if \[ \"\$s\" = \"string\" \]; then + +echo \"string is equivalent to \\\$s\" + +else + +echo \"string is not equivalent to \\\$s\" + +fi + +``` + +也可以是测试条件操作符: + +下面简单介绍些条件操作符: + +```shell + + -f 检查文件是否存在并且它是一个普通文件。 + + -d 检查提供的参数是否是目录。 + + -h 检查提供的参数是否是符号链接。 + + -s 检查文件是否存在且不为空。 + + -r 检查文件是否可读。 + + -w 检查文件是否可写。 + + -x 检查文件是否可执行。 + +``` + +如果用于数字比较,可以用如下测试条件操作符: + +```shell + + -lt 小于 + + -gt 大于 + + -ge 大于等于 + + -le 小于等于 + + -ne 不等于 + +``` + +如果用于字符串比较,可以用如下测试条件操作符: + +```shell + + == 两个字符串相同 + + = 两个字符串相同(同==) + + != 两个字符串不同 + + -z 空字符串,返回 true + + -n 长度不是 0,则返回 true + +``` + +### 循环 + +#### for 循环 + +```shell + +for number in 1 2 3 4 5 + +do + +echo \$number + +done + +使用列表: + +for number in {1..500..2} + +do + +echo \$number + +done + +``` + +其中{1..500..2}表示起始数字为 1,结束数字为 500(包括),步长为 2。 + +#### until 循环 + +```shell + +until \[condition\]; do + +commands + +done + +``` + +当条件为真时,执行循环; + +#### while 循环 + +```shell + +while \[ condition \]; do + +commands + +done + +``` + +当条件为真时,执行循环。 diff --git a/docs/en/25.03/Server/Administration/CompaCommand/utsudo_user_guide.md b/docs/en/25.03/Server/Administration/CompaCommand/utsudo_user_guide.md new file mode 100644 index 0000000000000000000000000000000000000000..3200c0588968a7b10b63650304f158476f276a14 --- /dev/null +++ b/docs/en/25.03/Server/Administration/CompaCommand/utsudo_user_guide.md @@ -0,0 +1,83 @@ +# utsudo 使用指南 + +本文档主要介绍`utsudo`工具的安装和简单使用,帮助用户快速上手。`utsudo`从参数功能到插件使用都是完全兼容`sudo`,大大降低了用户的学习成本,欢迎大家使用。 + +本文档主要适用于`utsudo`的开发人员、测试人员、以及普通用户。 + +## utsudo 介绍 + +utsudo 诞生于 2022 年 6 月份,是一个目前正在进行的使用 Rust 语言重构 Sudo 的项目。utsudo 旨在提供一个更加高效、安全、灵活的提权工具,涉及的模块主要有:通用工具库、整体框架和插件功能等。 + +## utsudo 安装 + +在`0.0.1`版本中,`utsudo`与`sudo`还存在部分文件冲突。需要先使用`yum`命令,把`utsudo`的二进制`rpm`包下载到本地,再使用`rpm`命令进行安装 ,以允许与`sudo`的文件冲突。 + +首先使用`yumdownloader utsudo`命令下载`utsudo`二进制包到本地。 + +然后使用`sudo rpm -Uvh utsudo-0.0.1-0.01.x86_64.rpm --replacefiles`命令安装`utsudo`,执行过程如下所示。 + +![image-20230828094539717](./figures/image-20230828094539717.png) + +安装完成后,使用`rpm -qa | grep utsudo`命令查看`utsudo`是否正常安装,如下图所示。 + +![image-20230828094723153](./figures/image-20230828094723153.png) + +由上图可知,`utsudo`已正常安装,安装的版本是`0.0.1-0.01`。 + +`utsudo`后续还会有版本更新,大家以自己安装的版本为准。 + +## utsudo使用 + +下面给大家介绍一下`utsudo`的简单使用。 + +`utsudo`参数较多,下面简单列出部分参数,详细内容可使用`utsudo -h`列出。 + +```shell + +-e, --edit 编辑文件而非执行命令 +-k, --reset-timestamp 无效的时间戳文件 +-l, --list 列出用户权限或检查某个特定命令;对于长格式,使用两次 + +``` + +### `-e` 参数 + +`-e`参数的功能:编辑文件。 + +`utsudo -e`相当于`sudoedit`命令,执行时会调用普通用户进行编辑,而位于调用用户可写目录中的文件是无法编辑的,除非该用户是`root`用户。 + +在当前用户没有可写权限的目录`e`中,存在一个当前用户没有可编辑权限的文件:`test.txt`。使用普通用户编辑`test.txt`文件,会提示没有权限。使用`utsudo -e`后,可以正常编辑。具体执行过程如下图所示。 + +![image-20230828135001624](./figures/image-20230828135001624.png) + +由上图可知,成功修改了`test.txt`文件的内容。(其中`utsudo -e is okay !!`,是我们在编辑器中自己添加的。) + +### `-k`参数 + +`-k`参数功能:使时间戳无效。 + +默认使用`utsudo`执行命令时,第一次是需要输入密码的,短时间内(默认是5分钟)再次执行`sudo`命令则不需要再次输入密码。使用`-k`参数可以强迫使用者在下一次执行`utsudo`时询问密码。 + +![image-20230828140355863](./figures/image-20230828140355863.png) + +`utsudo`输入密码后,默认`5`分钟之内不需要输入密码。 + +但是,由上图可知,`utsudo -k`使得`utsudo`的时间戳失效了。 + +### `-l`参数 + +`-l`参数功能:用于显示当前用户可以用`utsudo`执行哪些命令。 + +执行过程如下所示: + +![image-20230828140709441](./figures/image-20230828140709441.png) + +上图显示了`test`用户,可以运行如下命令: + +```shell +(ALL) ALL +``` + +也就是所有命令,说明`/etc/sudoers`文件中,并没有对`test`用户做过多的限制。 + +`utsudo`的使用,就简单介绍这些,除了上面介绍到的,`utsudo`还有很多其他的功能和参数,此处就不一一列举了。欢迎大家讨论。 diff --git a/docs/en/25.03/Server/Administration/sysMaster/_menu.md b/docs/en/25.03/Server/Administration/sysMaster/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..4d8914c66edeb3c1657daea8e4daf509b4d68363 --- /dev/null +++ b/docs/en/25.03/Server/Administration/sysMaster/_menu.md @@ -0,0 +1,22 @@ +--- +label: 'sysMaster用户指南' +ismanual: 'Y' +description: '使用 sysMaster 管理服务器和设备' +children: + - label: '概述' + href: './overview.md' + - label: '服务管理' + href: './service_management.md' + children: + - label: '安装与部署' + href: './sysmaster_install_deploy.md' + - label: '使用说明' + href: './sysmaster_usage.md' + - label: '设备管理' + href: './device_management.md' + children: + - label: '安装与部署' + href: './devmaster_install_deploy.md' + - label: '使用说明' + href: './devmaster_usage.md' +--- diff --git a/docs/en/25.03/Server/Administration/sysMaster/device_management.md b/docs/en/25.03/Server/Administration/sysMaster/device_management.md new file mode 100644 index 0000000000000000000000000000000000000000..9fa6b496e474b31d090c5ff35a0679fa072b6e93 --- /dev/null +++ b/docs/en/25.03/Server/Administration/sysMaster/device_management.md @@ -0,0 +1,14 @@ +# 设备管理 + +设备管理器作为链接用户态软件与底层物理设备的桥梁,支撑着 `lvm2`、`NetworkManager`等关键基础软件的运作。`devmaster`作为 `sysMaster`的设备管理组件,一方面支撑 `sysMaster`的快速启动以及用户态软件的生态兼容,另一方面通过对 `Linux`生态下主流设备管理方案的现状和优劣进行了总结和思考,从而提供一种分层解耦、可扩展性强、面向通用 `OS`的设备管理能力。 + +`devmaster`由常驻进程、客户端工具和动态库组成。常驻进程`devmaster`基于内核提供的`netlink`、`inotify`、`sysfs`等机制,监听设备事件并触发规则处理任务;客户端工具`devctl`和动态库`libs`提供一组命令行指令以及公开接口,用于调试规则、控制常驻进程、查询设备状态等等。`devmaster`的总体架构如下图所示: + +**图1 devMaster的总体架构** +![devMaster的总体架构](./figures/devmaster_architecture.png) + +`devmaster`使用 `Rust`语言编写,能够原生消除内存安全类问题。`devmaster`的核心功能如下: + +1. 事件驱动:利用队列缓存和 `worker`池机制,满足设备事件高并发的场景,并支持将设备就绪状态动态地通知到用户态进程。 +2. 机制与策略分离:将设备处理逻辑定义在规则中,避免业务硬编码,提供按需定制、灵活组合的能力。 +3. 生态兼容:良好地兼容 `udev`语法和 `udev`用户态广播协议,支持原有业务低成本迁移到 `devmaster`环境。 diff --git a/docs/en/25.03/Server/Administration/sysMaster/devmaster_install_deploy.md b/docs/en/25.03/Server/Administration/sysMaster/devmaster_install_deploy.md new file mode 100644 index 0000000000000000000000000000000000000000..4c5b602f46062936c73c990747e39aa9da07672c --- /dev/null +++ b/docs/en/25.03/Server/Administration/sysMaster/devmaster_install_deploy.md @@ -0,0 +1,67 @@ +# 安装与部署 + +`devmaster`目前可应用于虚拟机环境,本章节介绍安装部署的规格约束以及操作流程。 + +## 软件要求 + +* 操作系统:`openEuler 23.09` + +## 硬件要求 + +* `x86_64`架构、`aarch64`架构 + +## 安装部署流程 + +1. 执行如下命令,使用`yum`工具安装`sysmaster-devmaster`包: + + ```shell + # yum install sysmaster-devmaster + ``` + +2. 执行如下命令,创建默认规则文件`/etc/devmaster/rules.d/99-default.rules`和常驻进程的配置文件`/etc/devmaster/config.toml`: + + ```shell + # mkdir -p /etc/devmaster/rules.d + # mkdir -p /etc/devmaster/network.d + # echo "TAG+=\"devmaster\"" > /etc/devmaster/rules.d/99-default.rules + # cat << EOF > /etc/devmaster/config.toml + log_level = "info" + rules_d = ["/etc/devmaster/rules.d"] + network_d = ["/etc/devmaster/network.d"] + max_workers = 1 + log_targets = ["console"] + EOF + ``` + +3. 执行如下命令启动常驻进程`devmaster`,并将日志导出到`/tmp/devmaster.log`文件中: + + ```shell + # /lib/devmaster/devmaster &>> /tmp/devmaster.log & + ``` + + > ![说明](./public_sys-resources/icon-note.gif) **说明:** + > `devmaster`需要以 `root`权限启动,并且不能和 `udev`同时处于运行状态,启动 `devmaster`前需要停止`udev`服务。 + + 要停止`udev`服务,`sysmaster`启动环境下,执行以下命令: + + ```shell + # sctl stop udevd.service udevd-control.socket udevd-kernel.socket + ``` + + 要停止`udev`服务,`systemd`启动环境下,执行以下命令: + + ```shell + # systemctl stop systemd-udevd.service systemd-udevd systemd-udevd-kernel.socket systemd-udevd-control.socket + ``` + +4. 执行如下命令,使用 `devctl`工具触发设备事件: + + ```shell + # devctl trigger + ``` + +5. 查看 `/run/devmaster/data/`目录,如果生成设备数据库,则表示部署成功: + + ```shell + # ll /run/devmaster/data/ + ``` diff --git a/docs/en/25.03/Server/Administration/sysMaster/devmaster_usage.md b/docs/en/25.03/Server/Administration/sysMaster/devmaster_usage.md new file mode 100644 index 0000000000000000000000000000000000000000..77d56576ac5bfb6c1c6a78932495170c35bbf2ed --- /dev/null +++ b/docs/en/25.03/Server/Administration/sysMaster/devmaster_usage.md @@ -0,0 +1,251 @@ +# 使用说明 + +本章介绍 `devmaster`的使用方法,包括常驻进程配置、客户端工具、规则使用说明和网卡配置。 + +## 常驻进程配置 + +常驻进程 `devmaster`启动后会读取配置文件,并根据配置文件内容,调整日志级别、设置规则加载路径等等。`devmaster`拥有唯一的配置文件,路径为 `/etc/devmaster/config.toml`,文件内容采用 `toml`格式。 + +### 配置选项 + +目前 `devmaster`配置文件中支持的配置选项如下: + +- `rules_d`: 指定规则加载路径,默认规则中设置为 `["/etc/devmaster/rules.d"]`,未指定时无默认加载路径。`devmaster`当前不支持规则加载优先级,不同规则路径下的同名规则文件不会发生覆盖。规则文件的加载顺序按照 `rules_d`配置项中指定的目录顺序,相同目录下按照规则文件的字典序进行加载。 +- `max_workers`: 指定最大 `worker`线程并发数,未指定时默认为3。 +- `log_level`: 指定日志级别,支持 `debug`和 `info`级别,未指定时默认为 `"info"`。 +- `network_d`: 指定网卡配置加载路径,默认规则中设置为 `["/etc/devmaster/network.d"]`,未指定时无默认加载路径。网卡配置用于控制 `devmaster`的内置命令 `net_setup_link`的行为,具体可参考[网卡配置说明](#网卡配置)。 + +## 客户端工具 + +`devctl`是常驻进程 `devmaster`的客户端工具,用来控制 `devmaster`的行为、模拟设备事件、调试规则等等。 + + ```shell + # devctl --help + devmaster 0.5.0 + parse program arguments + + USAGE: + devctl + + OPTIONS: + -h, --help Print help information + -V, --version Print version information + + SUBCOMMANDS: + monitor Monitor device events from kernel and userspace + kill Kill all devmaster workers + test Send a fake device to devmaster + trigger Trigger a fake device action, then the kernel will report an uevent + test-builtin Test builtin command on a device + help Print this message or the help of the given subcommand(s) + ``` + +选项说明: + + `-h, --help`: 显示帮助信息。 + + `-V, --version`: 显示版本信息。 + + ``: 选择执行的子命令,包括`monitor`、`trigger`、`test-builtin`等。 + +接下来介绍三种常用的子命令,分别用于监听设备事件、触发设备事件以及测试内置命令。 + +### 监听设备事件 + +监听内核上报的 `uevent`事件和 `devmaster`处理完设备后发出的事件,分别以 `KERNEL`和 `USERSPACE`作为前缀进行区分,执行的命令如下: + + ```shell + # devctl monitor [OPTIONS] + ``` + +选项说明: + + `-h, --help`: 显示帮助信息。 + +### 触发设备事件 + +模拟一个设备动作,使内核上报对应的uevent事件,用于重放内核初始化过程中的冷插(coldplug)设备事件,执行的命令如下: + + ```shell + # devctl trigger [OPTIONS] [DEVICES...] + ``` + +选项说明: + + `-h, --help`: 显示帮助信息。 + + `-a, --action `: 指定设备事件的动作类型。 + + `-t, --type `: 指定搜索的设备类型,可以是`devices`(设备)或者`subsystems`(子系统)。 + + `-v, --verbose`: 打印搜索到的设备。 + + `-n, --dry-run`: 不会实际触发设备事件,配合`--verbose`选项使用时,可以查看系统中的设备清单。 + + `[DEVICES...]`: 指定若干个需要触发事件的设备,如果为空,则触发系统中所有设备的事件。 + +### 测试内置命令 + +测试内置命令在某个设备上的执行效果,执行的命令如下: + + ```shell + # devctl test-builtin [OPTIONS] + ``` + +选项说明: + + `-a, --action `: 指定设备事件的动作类型,包括:`add`、`change`、`remove`、`move`、`online`、`offline`、`bind`和 `unbind`。 + + `-h, --help`: 显示帮助信息。 + + ``: 选择执行的内置命令,目前支持`blkid`、`input_id`、`kmod`、`net_id`、`net_setup_link`、`path_id`、`usb_id`。 + + ``: 指定设备的 `sysfs`路径。 + +## 规则使用说明 + +`devmaster`的规则由一组规则文件组成,`devmaster`常驻进程启动后会根据配置文件中指定的规则加载目录,按字典序依次加载各个规则文件。 + +> ![说明](./public_sys-resources/icon-note.gif) **说明:** +> 增加、删除、修改规则后,均需要重启 `devmaster`使之生效。 + +### 常用规则案例 + +以下介绍几种常见的规则应用案例,规则语法详见官方文档中的[devmaster手册](http://sysmaster.online/man/exts/devmaster/devmaster/)。 + +#### 示例1: 创建块设备软链接 + +通过 `blkid`内置命令,读取块设备的 `uuid`,并基于 `uuid`创建块设备的软链接。 + +触发拥有文件系统的某块设备的事件后,在 `/dev/test`目录下生成该设备对应的软链接。 + +以 `sda1`分区块设备为例,测试规则效果: + +1. 创建规则文件 `/etc/devmaster/rules.d/00-persist-storage.rules`,内容如下: + + ```shell + SUBSYSTEM!="block", GOTO="end" + + IMPORT{builtin}=="blkid" + + ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="test/$env{ID_FS_UUID_ENC}" + + LABEL="end" + ``` + +2. 触发 `sda1`设备的事件: + + ```shell + # devctl trigger /dev/sda1 + ``` + +3. 查看 `/dev/test/`目录下存在指向 `sda1`的软链接,表示规则生效: + + ```shell + # ll /dev/test/ + total 0 + lrwxrwxrwx 1 root root 7 Sep 6 15:35 06771fe1-39da-42d7-ad3c-236a10d08a7d -> ../sda1 + ``` + +#### 示例2: 网卡重命名 + +使用 `net_id`内置命令,获取网卡设备的硬件属性,再使用 `net_setup_link`内置命令,基于网卡配置选择某个硬件属性作为网卡名,最后通过 `NAME`规则重命名网卡。 + +以 `ens33`网卡为例,测试网卡重命名规则的效果: + +1. 创建规则文件 `/etc/devmaster/rules.d/01-netif-rename.rules`,内容如下: + + ```shell + SUBSYSTEM!="net", GOTO="end" + + IMPORT{builtin}=="net_id" + + IMPORT{builtin}=="net_setup_link" + + ENV{ID_NET_NAME}=="?*", NAME="$env{ID_NET_NAME}" + + LABEL="end" + ``` + +2. 创建网卡配置`/etc/devmaster/network.d/99-default.link`,内容如下: + + ```shell + [Match] + OriginalName = "*" + + [Link] + NamePolicy = ["database", "onboard", "slot", "path"] + ``` + +3. 先将网卡设备下线: + + ```shell + # ip link set ens33 down + ``` + +4. 将网卡名临时命名为 `tmp`: + + ```shell + # ip link set ens33 name tmp + ``` + +5. 触发网卡设备的 `add`事件: + + ```shell + # devctl trigger /sys/class/net/tmp --action add + ``` + +6. 查看网卡名称,发现重新命名为 `ens33`,表示规则生效: + + ```shell + # ll /sys/class/net/| grep ens33 + lrwxrwxrwx 1 root root 0 Sep 6 11:57 ens33 -> ../../devices/pci0000:00/0000:00:11.0/0000:02:01.0/net/ens33 + ``` + +7. 激活网卡后恢复网络连接: + + ```shell + # ip link set ens33 up + ``` + +> ![说明](./public_sys-resources/icon-note.gif) **说明:** +> 网卡设备处于激活状态下无法重命名,需要先将其下线。另外 `devmaster`仅在网卡设备的 `add`事件下对网卡重命名才会生效。 + +#### 示例3: 修改设备节点的用户权限 + +`OPTIONS+="static_node=`规则会使 `devmaster`启动后,立即将本规则行中的用户权限应用在 `/dev/`设备节点上。重启 `devmaster`后立即生效,无需设备事件触发。 + +1. 创建规则文件`/etc/devmaster/rules.d/02-devnode-privilege.rules`,内容如下: + + ```shell + OWNER="root", GROUP="root", MODE="777", OPTIONS+="static_node=tty5" + ``` + +2. 重启 `devmaster`后,观察 `/dev/tty5`的用户、用户组和权限,变更为 `root`、`root`和 `rwxrwxrwx`,表示规则生效: + + ```shell + # ll /dev/tty5 + crwxrwxrwx 1 root root 4, 5 Feb 3 2978748 /dev/tty5 + ``` + +## 网卡配置 + +`devmaster`的网卡重命名功能由内置命令 `net_id`、`net_setup_link`和网卡配置文件配合完成。在规则文件中,通过 `net_id`获取网卡的硬件属性,再使用 `net_setup_link`选择某个网卡属性作为新的网卡名。`net_setup_link`命令基于网卡配置,针对特定网卡设备,控制网卡命名的风格。本章主要介绍网卡配置文件的使用方法,网卡重命名的实施方法可参考[网卡重命名规则案例](#示例2-网卡重命名)。 + +### 默认网卡配置 + +`devmaster`提供了如下默认网卡配置: + + ```toml + [Match] + OriginalName = "*" + + [Link] + NamePolicy = ["onboard", "slot", "path"] + ``` + +网卡配置文件中包含 `[Match]`匹配节和 `[Link]`控制节,每节中包含若干配置项。匹配节的配置项用于匹配网卡设备,当网卡满足所有匹配条件时,将控制节中的所有配置项作用在网卡上,比如设置网卡名选取策略、调整网卡参数等等。 + +以上列举的默认网卡配置表示将该配置作用在所有网卡设备上,并依次检查 `onboard`、`slot`和 `path`风格的网卡命名风格,如果找到一个可用的风格,就以该风格对网卡进行命名。 + +网卡配置的详细说明可以参考 `sysMaster`官方手册中的[devmaster手册](http://sysmaster.online/man/exts/devmaster/netif_config/#1)。 diff --git a/docs/en/25.03/Server/Administration/sysMaster/figures/devmaster_architecture.png b/docs/en/25.03/Server/Administration/sysMaster/figures/devmaster_architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..c60c9505c570093c78fa5335b590e7da58c7cc7c Binary files /dev/null and b/docs/en/25.03/Server/Administration/sysMaster/figures/devmaster_architecture.png differ diff --git a/docs/en/25.03/Server/Administration/sysMaster/figures/sysMaster.png b/docs/en/25.03/Server/Administration/sysMaster/figures/sysMaster.png new file mode 100644 index 0000000000000000000000000000000000000000..5f4a8d239727c4d22f2b8841946bb12cd4a8d86b Binary files /dev/null and b/docs/en/25.03/Server/Administration/sysMaster/figures/sysMaster.png differ diff --git a/docs/en/25.03/Server/Administration/sysMaster/overview.md b/docs/en/25.03/Server/Administration/sysMaster/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..f6e9a47416daf2f6fe4fc45f8f4c1e4ede347042 --- /dev/null +++ b/docs/en/25.03/Server/Administration/sysMaster/overview.md @@ -0,0 +1,26 @@ +# sysMaster用户指南 + +## 概述 + +`sysMaster`是一套超轻量、高可靠的服务管理程序集合,是对 `1`号进程的全新实现,旨在改进传统的 `init`守护进程。它使用 `Rust`编写,具有故障监测、秒级自愈和快速启动等能力,从而提升操作系统可靠性和业务可用度。 + +`sysMaster`支持进程、容器和虚拟机的统一管理,其适用于服务器、云计算和嵌入式等多个场景。 + +`sysMaster`实现思路是将传统 `1`号进程的功能解耦分层,结合使用场景,拆分出 `1+1+N`的架构。 + +如下面 `sysMaster`系统架构图所示,主要包含三个方面: +• `sysmaster-init`:新的 `1`号进程提供系统初始化、僵尸进程回收、监控保活等功能,可单独应用于嵌入式场景。 +• `sysmaster-core`:承担原有服务管理的核心功能,引入可靠性框架,使其具备崩溃快速自愈、热升级等能力,保障业务全天在线。 +• `sysmaster-exts`:使原本耦合的各组件功能独立,提供系统关键功能的组件集合(如设备管理 `devMaster`,总线通信 `busMaster`等),各组件可单独使用,可根据不同场景灵活选用。 + +**图1** sysMaster整体架构图 +![sysMaster](./figures/sysMaster.png) + +`sysMaster`目前主要由 `sysmaster`和 `devmaster`2部分功能组成,其中 `sysmaster`负责服务的管理,`devmaster`负责设备的管理,下面将对这2部分功能进行说明。 + +## 读者对象 + +本文档主要适用于使用 `openEuler`并需要对服务和设备进行管理的用户。用户需要具备以下经验和技能: + +* 熟悉 `Linux`基本操作 +* 对服务配置和设备有一定了解 diff --git a/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-caution.gif b/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-caution.gif differ diff --git a/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-danger.gif b/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-danger.gif differ diff --git a/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-note.gif b/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-notice.gif b/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-notice.gif differ diff --git a/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-tip.gif b/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-tip.gif differ diff --git a/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-warning.gif b/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Administration/sysMaster/public_sys-resources/icon-warning.gif differ diff --git a/docs/en/25.03/Server/Administration/sysMaster/service_management.md b/docs/en/25.03/Server/Administration/sysMaster/service_management.md new file mode 100644 index 0000000000000000000000000000000000000000..ba8dedd4f178a8048eba05d6d0234c17f76f3fd2 --- /dev/null +++ b/docs/en/25.03/Server/Administration/sysMaster/service_management.md @@ -0,0 +1,5 @@ +# 服务管理 + +在 `Linux`中,有很多在后台运行的程序或进程,如 `Web`服务器、数据库服务器、邮件服务器等。系统启动和运行过程中会启动和停止这些程序。 `sysmaster`对此提供了高效的服务管理的命令及配置,确保系统正常工作。 + +本文主要介绍 `sysmaster`的安装部署与各个特性说明和使用方法,使用户能够快速了解并使用。 diff --git a/docs/en/25.03/Server/Administration/sysMaster/sysmaster_install_deploy.md b/docs/en/25.03/Server/Administration/sysMaster/sysmaster_install_deploy.md new file mode 100644 index 0000000000000000000000000000000000000000..19acc7673fc287af4ca341eabd88a0fe809da256 --- /dev/null +++ b/docs/en/25.03/Server/Administration/sysMaster/sysmaster_install_deploy.md @@ -0,0 +1,100 @@ +# 安装与部署 + +`sysmaster`可应用于容器和虚拟机,本文档将以 `aarch64`系统为例说明如何在各场景下进行安装与部署。 + +## 软件要求 + +* 操作系统:`openEuler 23.09` + +## 硬件要求 + +* `x86_64`架构、`aarch64`架构 + +## 容器场景安装与部署 + +1. 安装 docker + + ```bash + yum install -y docker + systemctl restart docker + ``` + +2. 加载基础容器镜像 + + 下载容器镜像 + + ```bash + wget https://repo.openeuler.org/openEuler-23.09/docker_img/aarch64/openEuler-docker.aarch64.tar.xz + xz -d openEuler-docker.aarch64.tar.xz + ``` + + 加载容器镜像 + + ```bash + docker load --input openEuler-docker.aarch64.tar + ``` + +3. 构建容器 + + 创建 Dockerfile + + ```bash + cat << EOF > Dockerfile + FROM openeuler-23.09 + RUN yum install -y sysmaster + CMD ["/usr/lib/sysmaster/init"] + EOF + ``` + + 构建容器 + + ```bash + docker build -t openeuler-23.09:latest . + ``` + +4. 启动并进入容器 + + 启动容器 + + ```bash + docker run -itd --privileged openeuler-23.09:latest + ``` + + 获取`CONTAINERID` + + ```bash + docker ps + ``` + + 使用上一步获取到`CONTAINERID`进入容器 + + ```bash + docker exec -it CONTAINERID /bin/bash + ``` + +## 虚拟机场景安装与部署 + +1. `initramfs`镜像制作 + 为了避免 `initrd`阶段 `systemd`的影响,需要制作一个剔除 `systemd`的 `initramfs`镜像,并以该镜像进入 `initrd`流程。使用如下命令: + + ```bash + dracut -f --omit "systemd systemd-initrd systemd-networkd dracut-systemd" /boot/initrd_withoutsd.img + ``` + +2. 新增启动项 + + 在 `grub.cfg`中增加新的启动项,`aarch64`下的路径为 `/boot/efi/EFI/openEuler/grub.cfg`,`x86_64`下的路径为 `/boot/grub2/grub.cfg`,拷贝一份原有启动项,并做以下几处修改: + + * `menuentry` 项修改启动项名称 `openEuler (6.4.0-5.0.0.13.oe23.09.aarch64) 23.09`为 `openEuler 23.09 withoutsd` + * `linux` 项内核启动参数修改 `root=/dev/mapper/openeuler-root ro` 为 `root=/dev/mapper/openeuler-root rw` + * `linux` 项内核启动参数修改 `plymouth`,如果环境上安装了 `plymouth`, 需要添加 `plymouth.enable=0` 禁用 `plymouth` + * `linux` 项内核启动参数增加 `init=/usr/lib/sysmaster/init` + * `initrd` 项修改为 `/initrd_withoutsd.img` + +3. 安装 sysmaster + + ```bash + yum install sysmaster + ``` + +4. 重启后出现 `openEuler 23.09 withoutsd`启动项表示已成功配置,选择此启动项进入虚拟机 diff --git a/docs/en/25.03/Server/Administration/sysMaster/sysmaster_usage.md b/docs/en/25.03/Server/Administration/sysMaster/sysmaster_usage.md new file mode 100644 index 0000000000000000000000000000000000000000..b39bef3db4da92c84ccb577a41a7130aac0a138b --- /dev/null +++ b/docs/en/25.03/Server/Administration/sysMaster/sysmaster_usage.md @@ -0,0 +1,102 @@ +# sysmaster使用说明 + +本章主要通过一些实例来带领用户初步使用 `sysmaster`,例如: + +* 如何创建 `service`服务单元配置文件。 +* 如何管理单元服务,例如启动、停止、查看服务。 + +## 创建单元配置文件 + +用户可以在 `/usr/lib/sysmaster/system/`目录下创建单元配置文件。 + +### 单元配置文件的类型 + +当前 `sysmaster`支持 `target`、`socket`、`service`类型的单元配置文件。 + +* `target`:封装了一个由 `sysmaster`管理的启动目标,用于将多个单元集中到一个同步点。`sysmaster`提供不同阶段的 `target`单元,例如 `multi-user.target`代表系统已完成启动,用户可以依赖此目标,启动自己的服务。 +* `socket`:封装了一个用于进程间通信的套接字 `socket`, 以支持基于套接字的启动。例如用户可以配置 `service`单元依赖此 `socket`,当此 `socket`有数据写入时,`sysmaster`会拉起对应的 `service`单元。 +* `service`:封装了一个被 `sysmaster`监视与控制的进程。 + +### 单元配置文件的构成 + +单元配置文件通常由3块组成: + +* `Unit`:单元的公共配置说明,如服务名称、描述、依赖关系等。 +* `Install`:描述如何安装和启动服务。 +* `Service`、`Socket`:各个单元类型的配置。 + +### 创建service单元配置 + +`sshd`服务被用来远程登录到服务器,并在远程终端上执行命令和操作。 +使用如下配置项来创建一个 `sshd.service`服务单元配置。 + +```bash +[Unit] +Description="OpenSSH server daemon" +Documentation="man:sshd(8) man:sshd_config(5)" +After="sshd-keygen.target" +Wants="sshd-keygen.target" + +[Service] +Type="notify" +EnvironmentFile="-/etc/sysconfig/sshd" +ExecStart="/usr/sbin/sshd -D $OPTIONS" +ExecReload="/bin/kill -HUP $MAINPID" +KillMode="process" +Restart="on-failure" +RestartSec=42 + +[Install] +WantedBy="multi-user.target" +``` + +以下是对单元配置文件中选项配置的说明,更多可以查阅[官方手册](http://sysmaster.online/man/all/)。 + +* `Description`:说明该 `unit`的主要功能。 +* `Documentation`:说明该 `unit`的文档链接。 +* `After`:配置同时启动的单元的先后顺序,`sshd.service`服务将在 `sshd-keygen.target`之后启动。 +* `Wants`:配置一个单元对另一个单元的依赖,启动 `sshd.service`服务,将会自动启动 `sshd-keygen.target`。 +* `Type`:配置 `sysmaster` 如何启动此服务,`notify`表明需要主进程启动完成后发送通知消息。 +* `EnvironmentFile`:设置环境变量的文件读取路径。 +* `ExecStart`:配置服务启动时执行的命令,启动 `sshd.service`服务会执行 `sshd`命令。 +* `ExecReload`:配置重新加载 `sshd.service`的配置时执行的命令。 +* `KillMode`:配置当需要停止服务进程时,杀死服务进程的方法,`process`表示只杀死主进程。 +* `Restart`:配置服务不同情况下退出或终止,是否重新启动服务,`on-failure`表示当服务非正常退出时重新启动服务。 +* `RestartSec`:配置当服务退出时,重新拉起服务的间隔时间。 +* `WantedBy`:配置依赖当前 `sshd.service`服务的单元。 + +## 管理单元服务 + +`sctl`是 `sysmaster`的命令行工具,用于检查和控制 `sysmaster`服务端行为和各个服务的状态,它可以启动、停止、重启、检查系统服务。 + +### 启动服务 + +使用以下命令可以启动 `sshd`服务和运行 `ExecStart`所配置的命令。 + +```bash +sctl start sshd.service +``` + +### 停止服务 + +使用以下命令可以停止 `sshd`服务,杀死 `ExecStart`所运行的进程。 + +```bash +sctl stop sshd.service +``` + +### 重启服务 + +使用以下命令可以重启 `sshd`服务,该命令会先停止后启动服务。 + +```bash +sctl restart sshd.service +``` + +### 查看服务状态 + +使用以下命令可以查看服务 `sshd`运行状态,用户可以查看服务的状态来获取服务是否正常运行。 + +```bash +sctl status sshd.service +``` diff --git a/docs/en/25.03/Server/Development/ApplicationDev/FAQ.md b/docs/en/25.03/Server/Development/ApplicationDev/FAQ.md new file mode 100644 index 0000000000000000000000000000000000000000..a84d3a2cb3d5fd7eb7bf2637b97a385ed2222dde --- /dev/null +++ b/docs/en/25.03/Server/Development/ApplicationDev/FAQ.md @@ -0,0 +1,19 @@ +# 常见问题与解决方法 + +## **问题1:部分依赖java-devel的应用程序自编译失败** + +### 问题描述 + +部分依赖java-devel的应用程序会出现使用rpmbuild命令自编译失败的问题。 + +### 原因分析 + +为了提供更新的openjdk特性和对广大java应用程序的兼容,openEuler同时提供了openjdk-1.8.0、openjdk-11等多个版本的openjdk。部分应用程序在编译时需要依赖java-devel包,安装java-devel包时系统会默认安装更高版本的java-11-openjdk,从而导致这些应用的编译失败。 + +### 解决方法 + +用户需手动使用如下命令安装java-1.8.0-openjdk后再使用rpmbuild命令进行自编译。 + +```shell +# yum install java-1.8.0-openjdk +``` diff --git a/docs/en/25.03/Server/Development/ApplicationDev/_menu.md b/docs/en/25.03/Server/Development/ApplicationDev/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..d7bc58ce51503b0fd705353d5e88f6364e1f8f34 --- /dev/null +++ b/docs/en/25.03/Server/Development/ApplicationDev/_menu.md @@ -0,0 +1,22 @@ +--- +label: '应用开发指南' +ismanual: 'Y' +description: '基于 openEuler 开发应用程序' +children: + - label: '概述' + href: './application-development.md' + - label: '开发环境准备' + href: './preparations-for-development-environment.md' + - label: '使用GCC编译' + href: './using-gcc-for-compilation.md' + - label: '使用Clang编译' + href: './using-clang-for-compilation.md' + - label: '使用make编译' + href: './using-make-for-compilation.md' + - label: '使用JDK编译' + href: './using-jdk-for-compilation.md' + - label: '构建RPM包' + href: './building-an-rpm-package.md' + - label: '常见问题与解决方法' + href: './FAQ.md' +--- diff --git a/docs/en/25.03/Server/Development/ApplicationDev/application-development.md b/docs/en/25.03/Server/Development/ApplicationDev/application-development.md new file mode 100644 index 0000000000000000000000000000000000000000..00b1c690c5a3a4dab74536e5f0347697a7c09a5b --- /dev/null +++ b/docs/en/25.03/Server/Development/ApplicationDev/application-development.md @@ -0,0 +1,77 @@ +# 应用开发指南 + +本文档简要介绍应用程序开发需要的常用工具,以指导用户使用openEuler并基于openEuler进行应用程序开发。 + +## 概述 + +本文档主要介绍如下四部分内容,以指导用户使用openEuler并基于openEuler进行代码开发。 + +- 在openEuler系统中安装和使用GCC编译器,并完成一个简单代码的开发、编译和执行。 +- 在openEuler系统中使用JDK自带工具完成代码的编译和执行。 +- 在openEuler系统中安装IntelliJ IDEA进行Java开发。 +- 在本地或使用OBS(Open Build Service)创建RPM(The RPM Package Manager)软件包的方法。 + +## 读者对象 + +本文档适用于所有使用openEuler操作系统进行代码开发的用户。用户需要具备如下经验或能力: + +- 具备Linux操作系统基础知识 +- 了解Linux命令行的基本使用方法 + +## 符号约定 + +在本文中可能出现下列标志,它们所代表的含义如下。 + +| 符号 |说明 | +|:--- |:---- | +| ![](./figures/zh-cn_image_0229243712.png)|用于传递设备或环境安全警示信息,若不避免,可能会导致设备损坏、数据丢失、设备性能降低或其他不可预知的结果。
“注意”不涉及人身伤害。| +| ![](./figures/zh-cn_image_0229243671.png)|用于突出重要/关键信息、最佳实践和小窍门等。
“说明”不是安全警示信息,不涉及人身、设备及环境伤害。| + +## 命令行格式约定 + +**表 1** 命令行格式的约定 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

格式

+

含义

+

粗体

+

命令行关键字,即命令中保持不变、必须照输的部分,采用加粗字体表示。

+

斜体

+

命令行参数,即命令中必须由实际值进行替代的部分,采用斜体表示。

+

[ ]

+

用“[ ]”括起来的部分表示在命令配置时是可选的。

+

{ x | y | ... }

+

表示从两个或多个选项中选取一个。

+

[ x | y | ... ]

+

表示从两个或多个选项中选取一个或者不选。

+

{ x | y | ... }\*

+

表示从两个或多个选项中选取多个,最少选取一个,最多选取所有选项。

+

[ x | y | ... ]\*

+

表示从两个或多个选项中选取一个、多个或者不选。

+
diff --git a/docs/en/25.03/Server/Development/ApplicationDev/building-an-rpm-package.md b/docs/en/25.03/Server/Development/ApplicationDev/building-an-rpm-package.md new file mode 100644 index 0000000000000000000000000000000000000000..676e61fe293bd67277b58376a2ec4bae408e4e6c --- /dev/null +++ b/docs/en/25.03/Server/Development/ApplicationDev/building-an-rpm-package.md @@ -0,0 +1,584 @@ +# 构建RPM包 + +本章介绍通过本地或OBS构建RPM软件包的方法。详见打包规则。 + +## 打包说明 + +### 原理介绍 + +RPM打包的时候需要编译源码,需要把编译好的配置文件、二进制命令文件等放到合适的位置,还要根据需要对RPM的包进行测试,这些都需要先有一个“工作空间”。rpmbuild命令使用一套标准化的“工作空间”: + +```sh +rpmdev-setuptree +``` + +rpmdev-setuptree这个命令就是安装 rpmdevtools 带来的。可以看到运行了这个命令之后,在“/root”目录(非root用户为“/home/用户名”目录)下多了一个 rpmbuild 的文件夹,目录结构如下: + +```sh +# tree rpmbuild +rpmbuild +├── BUILD +├── RPMS +├── SOURCES +├── SPECS +└── SRPMS +``` + +内容相关的说明如下: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

目录

+

宏代码

+

名称

+

功能

+

~/rpmbuild/BUILD

+

%_builddir

+

构建目录

+

源码包被解压至此,并在该目录的子目录完成编译

+

~/rpmbuild/RPMS

+

%_rpmdir

+

标准 RPM 包目录

+

生成/保存二进制 RPM 包

+

~/rpmbuild/SOURCES

+

%_sourcedir

+

源代码目录

+

保存源码包(如 .tar 包)和所有 patch 补丁

+

~/rpmbuild/SPECS

+

%_specdir

+

Spec 文件目录

+

保存 RPM 包配置(.spec)文件

+

~/rpmbuild/SRPMS

+

%_srcrpmdir

+

源代码 RPM 包目录

+

生成/保存源码 RPM 包(SRPM)

+
+ +SPECS 下是RPM包的配置文件,是RPM打包的“图纸”,这个文件会告诉rpmbuild命令如何去打包。“宏代码”这一列就可以在SPEC文件中用来代指所对应的目录,类似于编程语言中的宏或全局变量。 + +### 打包流程 + +打包的过程主要分为如下步骤: + +1. 把源代码放到%\_sourcedir中。 +2. 进行编译,编译的过程是在%\_builddir中完成的,一般情况下,源代码是压缩包格式,需要先进行解压。 +3. 进行“安装”,类似于预先组装软件包,把软件包应该包含的内容(比如二进制文件、配置文件、man文档等)复制到%\_buildrootdir中,并按照实际安装后的目录结构组装,比如二进制命令可能会放在/usr/bin下,那么就在%\_buildrootdir下也按照同样的目录结构放置。 +4. 做一些必要的配置,比如在实际安装前的准备,安装后的清理等等。这些都是通过配置在SPEC文件中来告诉rpmbuild命令。 +5. 检查软件是否正常运行。 +6. 生成的RPM包放置到%\_rpmdir,源码包放置到%\_srcrpmdir下。 + +在SPEC文件中,各个阶段说明如下: + +| 阶段 | 读取的目录 | 写入的目录 | 具体动作 | +|-------------------|--------------|-----------------|-------------------------------------------| +| %prep | %_sourcedir | %_builddir | 读取位于 %_sourcedir 目录的源代码和 patch 之后,解压源代码至 %_builddir 的子目录并应用所有 patch。 | +| %build | %_builddir | %_builddir |编译位于 %_builddir 构建目录下的文件。通过执行类似 ./configure && make 的命令实现。| +| %install | %_builddir | %_buildrootdir |读取位于 %_builddir 构建目录下的文件并将其安装至 %_buildrootdir 目录。这些文件就是用户安装 RPM 后,最终得到的文件。| +| %check | %_builddir | %_builddir | 检查软件是否正常运行。通过执行类似 make test 的命令实现。| +| bin | %_buildrootdir | %_rpmdir| 读取位于 %_buildrootdir 最终安装目录下的文件,以便最终在 %_rpmdir 目录下创建 RPM 包。在该目录下,不同架构的 RPM 包会分别保存至不同子目录, noarch 目录保存适用于所有架构的 RPM 包。这些 RPM 文件就是用户最终安装的 RPM 包。 | +| src | %_sourcedir | %_srcrpmdir | 创建源码 RPM 包(简称 SRPM,以.src.rpm 作为后缀名),并保存至 %_srcrpmdir 目录。SRPM 包通常用于审核和升级软件包。 | + +### 打包选项 + +通过rpmbuild命令构建软件包。rpmbuild构建软件包一般可以通过构建SPEC文件、tar文件、source文件实现。 + +rpmbuild命令格式为:rpmbuild \[_option_...\] + +常用的rpmbuild打包选项如下所示。 + +| option取值 | 说明 | +|----------|--------------| +|-bp specfile |从specfile文件的%prep段开始构建(解开源码包并打补丁)。 | +|-bc specfile |从specfile文件的%build段开始构建。 | +|-bi specfile |从specfile文件的%install段开始构建。 | +|-bl specfile |从specfile文件的%files段开始检查。 | +|-ba specfile |通过specfile文件构建源码包和二进制包。 | +|-bb specfile |通过specfile文件构建二进制包。 | +|-bs specfile |通过specfile文件构建源码包。 | +|-rp sourcefile |从sourcefile文件的%prep段开始构建(解开源码包并打补丁)。 | +|-rc sourcefile |从sourcefile文件的%build段开始构建。 | +|-ri sourcefile |从sourcefile文件的%install段开始构建。 | +|-rl sourcefile |从sourcefile文件的%files段开始检查。 | +|-ra sourcefile |通过sourcefile文件构建源码包和二进制包。 | +|-rb sourcefile |通过sourcefile文件构建二进制包。 | +|-rs sourcefile |通过sourcefile文件构建源码包。 | +|-tp tarfile |从tarfile文件的%prep段开始构建(解开源码包并打补丁)。 | +|-tc tarfile |从tarfile文件的%build段开始构建。 | +|-ti tarfile |从tarfile文件的%install段开始构建。 | +|-ta tarfile |通过tarfile文件构建源码包和二进制包。 | +|-tb tarfile |通过tarfile文件构建二进制包。 | +|-ts tarfile |通过tarfile文件构建源码包。 | +|--buildroot=DIRECTORY |在构建时,使用DIRECTORY目录覆盖默认的/root目录。 | +|--clean |完成打包后清除BUILD目录下的文件。 | +|--nobuild |不执行任何实际的构建步骤。可用于测试spec文件。 | +|--noclean |不执行spec文件的"%clean"阶段(即使它确实存在)。 | +|--nocheck |不执行spec文件的"%check"阶段(即使它确实存在)。 | +|--dbpath DIRECTORY |使用DIRECTORY中的数据库,而不是默认的 /var/lib/rpm。 | +|--root DIRECTORY |使DIRECTORY为最高级别的路径,默认“/”为最高路径。 | +|--recompile sourcefile |将安装指定的源代码包sourcefile,然后进行准备、编译、安装。 | +|--rebuild sourcefile |在\-\-recompile 的基础上额外构建一个新的二进制包。在构建结束时,构建目录、源代码和 spec 文件都将被删除(就好像用了 \-\-clean)。 | +|-?,--help |打印详细的帮助信息。 | +|--version |打印详细的版本信息。 | + +## 本地构建 + +本章通过一个简单的示例介绍如何在本地构建RPM软件包的方法。 + +### 搭建开发环境 + +#### 前提条件 + +需要root权限,已设置openEuler的repo软件源。 + +#### 操作步骤 + +用户可以直接使用DNF工具安装 rpmdevtools,其中包含 rpm-build 等命令以及相关依赖(例如make、gdb)。使用如下命令: + +```sh +# dnf install rpmdevtools* +``` + +### 创建Hello World RPM包 + +这里以GNU “Hello World” 项目的打包过程作为示例,包含了典型的FOSS(Free and Open Source Software) 软件项目相关的最常用的外围组件,其中包括配置/编译/安装环境、文档、国际化等等。 + +#### 下载源码 + +我们直接下载官方例子的源码,使用如下命令: + +```sh +# rpmdev-setuptree +# cd ~/rpmbuild/SOURCES +# wget http://ftp.gnu.org/gnu/hello/hello-2.10.tar.gz +``` + +#### 编辑SPEC文件 + +在**~/rpmbuild/SPECS**目录下新建spec文件,参考命令如下: + +```sh +# cd ~/rpmbuild/SPECS +# vi hello.spec +``` + +在文件中写入对应内容后保存文件。文件内容示例如下,请根据实际情况修改相应字段。 + +```Conf +Name: hello +Version: 2.10 +Release: 1 +Summary: The "Hello World" program from GNU +License: GPL-3.0-or-later +URL: https://ftp.gnu.org/gnu/hello +Source0: https://ftp.gnu.org/gnu/hello/%{name}-%{version}.tar.gz + +BuildRequires: gettext + +%description +The "Hello World" program, done with all bells and whistles of a proper FOSS +project, including configuration, build, internationalization, help files, etc. + +%prep +%autosetup -p1 -n %{name}-%{version} + +%build +%configure +%make_build + +%install +%make_install +%find_lang %{name} + +%check +%make_build check + +%files -f %{name}.lang +%doc AUTHORS ChangeLog NEWS README THANKS TODO +%license COPYING +%{_bindir}/hello +%{_mandir}/man1/hello.1* +%{_infodir}/hello.info* + +%changelog +* Thu Dec 26 2019 Your Name - 2.10-1 +- Update to 2.10 + +* Sat Dec 3 2016 Your Name - 2.9-1 +- Update to 2.9 +``` + +- Name 标签是软件名,Version 标签是版本号,而 Release 标签是发布编号。 +- Summary 标签是简要说明,英文的话第一个字母应大写,以避免 rpmlint 工具(打包检查工具)警告。 +- License 标签说明软件包的协议版本,审查软件的 License 状态是打包者的职责,这可以通过检查源码或 LICENSE 文件,或与作者沟通来完成。 +- Group 标签过去用于按照 /usr/share/doc/rpm-/GROUPS 分类软件包。目前该标记已丢弃,vim的模板还有这一条,删掉即可,不过添加该标记也不会有任何影响。%changelog 标签应包含每个 Release 所做的更改日志,尤其应包含上游的安全/漏洞补丁的说明。%changelog 条目应包含版本字符串,以避免 rpmlint 工具警告。 +- 多行的部分,如 %changelog 或 %description 由指令下一行开始,空行结束。 +- 一些不需要的行 \(如 BuildRequires 和 Requires\) 可在行首使用‘\#’注释。 +- %prep、%build、%install、%files暂时用默认的,未做任何修改。 + +#### 构建RPM包 + +构建源码、二进制和包含调试信息的软件包,在spec文件所在目录执行如下命令: + +```sh +rpmbuild -ba hello.spec +``` + +执行成功后,查看结果,使用如下命令: + +```sh +# tree ~/rpmbuild/*RPMS + +/home/testUser/rpmbuild/RPMS +└── aarch64 + ├── hello-2.10-1.aarch64.rpm + ├── hello-debuginfo-2.10-1.aarch64.rpm + └── hello-debugsource-2.10-1.aarch64.rpm +/home/testUser/rpmbuild/SRPMS +└── hello-2.10-1.src.rpm +``` + +## 使用OBS构建 + +本章介绍通过网页和osc构建RPM软件包的方法。主要包括如下两类: + +- 修改已有软件包:修改已有软件包源代码,然后将修改后的源代码构建成一个RPM软件包。 +- 新增软件包:从无到有全新开发一个新的软件源文件,并将新开发的源文件构建成一个RPM软件包。 + +### OBS简介 + +OBS是基于openSUSE发行版的通用编译框架,用于将源码包构建为RPM软件包或Linux镜像。OBS采用自动化的分布式编译方式,支持多种Linux操作系统发行版(openEuler、SUSE、Debian等)镜像和安装包的编译,且支持在多种架构平台(x86、ARM64等)上编译。 + +OBS由后端和前端组成,后端实现所有核心功能,前端提供了网页应用和API,用于与后端进行交互。此外,OBS还有一个API命令行客户端osc,osc是在一个单独的存储库中开发的。 + +OBS使用工程组织软件包。基础的权限控制、相关的存储仓库和构建目标(操作系统和架构)都可以在工程中定义。一个工程可以包含多个子工程,各个子工程可以独立配置,共同完成任务。 + +### 在线构建软件包 + +本章介绍通过OBS网页端在线构建RPM软件包的方法。 + +#### 构建已有软件包 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 若为首次使用,请首先在OBS网页注册个人帐号。 +> 该方法需要拷贝修改后的代码,因此,请在执行下述操作前完成代码修改并提交到正确的代码路径。代码路径会在\_service文件中指定。 + +使用OBS网页端,修改已有软件的源代码,并将修改后的源文件构建为RPM软件包的操作方法如下: + +1. 登录OBS界面,地址为:[https://build.openeuler.openatom.cn](https://build.openeuler.openatom.cn)。 +2. 单击“All Projects”进入所有工程页面。 +3. 单击需要修改的对应工程,进入该工程的详情页面,例如单击“openEuler:Mainline”。 +4. 在工程详情页面的搜索框查找需要修改的软件包,然后单击该软件包包名,进入该软件包详情页面。 +5. 单击“Branch package”,在弹出的确认页面单击“Accept”确认创建子工程,如[图1](#fig77646143214)所示。 + + **图 1** Branch Confirmation页面 + ![](./figures/Branch-Confirmationpage.png) + +6. 单击“\_service”文件进入编辑页面,修改\_service内容后点击“Save”保存该文件。\_service内容示例如下,其中 _userCodeURL_、 _userCommitID_ 分别为用户代码托管路径、用户代码提交版本号或分支。 + + ```Conf + + + git + userCodeURL + userCommitID + + + bz2 + *.tar + + + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 单击“Save”保存\_service文件后,OBS服务会根据\_service文件描述,从指定的url下载源码到OBS对应工程的软件目录下并替换原有文件,例如上述例子中 “openEuler:Mainline”工程的kernel目录。 + +7. 文件拷贝并替换完成后,OBS会自动开始构建RPM软件包。等待构建完成,并查看右侧状态栏的构建状态。 + - succeeded:构建成功。用户可以单击“succeeded”查看构建日志,如[图2](#fig10319114217337)所示。 + + **图 2** succeeded的页面 + ![](./figures/succeededpage.png) + + - failed:构建失败。请单击“failed”查看错误日志进行问题定位后重新构建。 + - unresolvable:未进行构建,可能由于缺失依赖。 + - disabled:构建被手动关闭或正在排队构建。 + - excluded:构建被禁止,可能由于缺少spec文件或者spec文件中禁止了目标架构的编译。 + +#### 新增软件包 + +使用OBS网页端,新增一个全新软件包的操作方法如下: + +1. 登录OBS界面。 +2. 根据新增软件包的依赖情况,选择合适的工程,即单击“All Projects”选择对应工程,例如“openEuler:Mainline”。 +3. 单击工程下任一软件包,进入该软件包的详情页面。 +4. 单击“Branch package”,在弹出的确认页面单击“Accept”确认创建子工程。 +5. 单击“Delete package”,删除新创建子工程中的软件包,如[图3](#fig18306181103615)所示。 + + **图 3** 删除子工程中软件包 + ![](./figures/delete_package.png) + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 通过已有软件创建新工程是为了继承环境等依赖,而不需要实际的文件,所以这里需要把这些文件删除。 + +6. 单击“Create Package”,在弹出的页面输入软件包名称、标题和软件包描述,然后单击“Create”创建软件包,分别如[图4](#fig6762111693811)、[图5](#fig18351153518389)所示。 + + **图 4** Create Package页面 + ![](./figures/Create-Packagepage.png) + + **图 5** 创建软件包信息填写页面 + ![](./figures/setting_software_info.png) + +7. 在页面中单击“Add file”上传spec文件和需要编译的文件(在spec文件中指定),如[图6](#fig1475845284011)所示。 + + **图 6** Add file页面 + ![](./figures/filepage.png) + +8. 文件上传成功后,OBS会自动开始构建RPM软件包。等待构建完成,并查看右侧状态栏的构建状态。 + - succeeded:构建成功。用户可以单击“succeeded”查看构建日志。 + - failed:构建失败。请单击“failed”查看错误日志进行问题定位后重新构建。 + - unresolvable:未进行构建,可能由于缺失依赖。 + - disabled:构建被手动关闭或正在排队构建。 + - excluded:构建被禁止,可能由于缺少spec文件或者spec文件中禁止了目标架构的编译。 + +#### 获取软件包 + +RPM软件包构建完成后,通过网页端获取对应RPM软件包的方法如下: + +1. 登录OBS界面。 +2. 单击“All Projects”找到所需软件包的对应工程,例如“openEuler:Mainline”。 +3. 在工程下单击所需软件包的包名,进入该软件包详情页面。例如上述例子中的kernel页面。 +4. 选择Repositories页签进入软件包的软件仓库管理页面,在Publish Flag中通过单击选择“Enable”开启(状态由![](./figures/zh-cn_image_0229243704.png)变为![](./figures/zh-cn_image_0229243702.png))对应的RPM软件包下载功能,如[图7](#fig17480830144217)所示。 + + **图 7** Repositories页面 + ![](./figures/Repositoriespage.png) + +5. 单击Repository列的构建工程名称,进入RPM软件包下载页面,单击RPM软件包右侧的“Download”即可下载对应RPM软件包,如[图8](#fig12152145615438)所示。 + + **图 8** RPM软件包下载页面 + ![](./figures/RPM_package_download.png) + +### 使用osc构建软件包 + +本章介绍使用OBS的命令行工具osc创建工程并构建RPM软件包的方法。 + +#### 安装并配置osc + +##### 前提条件 + +需要root权限,已设置openEuler的repo软件源。 + +##### 操作步骤 + +1. 使用root用户安装osc命令行工具及依赖。 + + ```sh + # dnf install osc build + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 编译RPM软件包的过程中会依赖build。 + +2. 配置osc。 + 1. 打开\~/.oscrc,命令如下: + + ```sh + # vi ~/.oscrc + ``` + + 2. 在\~/.oscrc中添加user和pass字段,如下所示,它们的取值 _userName_ 和 _passWord_ 分别是用户在OBS网页([https://build.openeuler.openatom.cn](https://build.openeuler.openatom.cn))上已经注册的帐号和密码。 + + ```sh + [general] + apiurl = https://build.openeuler.openatom.cn + [https://build.openeuler.openatom.cn] + user=userName + pass=passWord + ``` + +#### 构建已有软件包 + +创建工程 + +1. 通过拷贝已有工程,创建属于用户自己的子工程。例如将openEuler:Mainline工程下的zlib软件包添加到新分支,参考命令如下: + + ```sh + # osc branch openEuler:Mainline zlib + ``` + + 回显如下所示,说明在用户testUser下创建了新的分支工程home:testUser:branches:openEuler:Mainline。 + + ```text + A working copy of the branched package can be checked out with: + osc co home:testUser:branches:openEuler:Mainline/zlib + ``` + +2. 将需要修改软件包的相关配置文件(例如\_service)下载到本地当前路径。其中 _testUser_ 为\~/.oscrc配置文件中配置的帐户名称,请根据实际情况修改。 + + ```sh + # osc co home:testUser:branches:openEuler:Mainline/zlib + ``` + + 回显如下所示: + + ```text + A home:testUser:branches:openEuler:Mainline + A home:testUser:branches:openEuler:Mainline/zlib + A home:testUser:branches:openEuler:Mainline/zlib/_service + ``` + +3. 进入本地子工程目录,并将软件包远程代码同步到本地。 + + ```sh + # cd home:testUser:branches:openEuler:Mainline/zlib + # osc up -S + ``` + + 回显如下所示: + + ```text + A _service:tar_scm_kernel_repo:0001-Neon-Optimized-hash-chain-rebase.patch + A _service:tar_scm_kernel_repo:0002-Porting-optimized-longest_match.patch + A _service:tar_scm_kernel_repo:0003-arm64-specific-build-patch.patch + A _service:tar_scm_kernel_repo:zlib-1.2.11-optimized-s390.patch + A _service:tar_scm_kernel_repo:zlib-1.2.11.tar.xz + A _service:tar_scm_kernel_repo:zlib-1.2.5-minizip-fixuncrypt.patch + A _service:tar_scm_kernel_repo:zlib.spec + ``` + +构建RPM包 + +1. 重命名源文件,然后将重命名后的源文件添加到OBS暂存中。 + + ```sh + # rm -f _service;for file in `ls | grep -v .osc`;do new_file=${file##*:};mv $file $new_file;done + # osc addremove * + ``` + +2. 修改源代码和spec文件,并执行如下命令更新文件。 + + ```sh + # osc up + ``` + +3. 将对应软件包的所有修改同步到OBS服务器。参考命令如下,-m参数后的信息为提交记录。 + + ```sh + # osc ci -m "commit log" + ``` + +4. 获取当前工程的仓库名称和架构,参考命令如下: + + ```sh + # osc repos home:testUser:branches:openEuler:Mainline + ``` + +5. 修改提交成功后,OBS会自动开始编译软件包。可以通过如下命令,查看对应仓库的编译日志,其中 _standard_aarch64_ 、 _aarch64_ 分别为查询所得仓库名称和架构。 + + ```sh + # osc buildlog standard_aarch64 aarch64 + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 用户也可以通过网页端打开自己创建的对应工程,查看构建日志。 + +#### 新增软件包 + +使用OBS的osc工具新增一个全新软件包的操作方法如下: + +创建工程 + +1. 根据新增软件包的依赖情况,基于合适的工程,创建属于用户自己的个人工程。例如基于 _openEuler:Mainline_ 工程的 zlib 创建工程的参考命令如下,zlib 为工程下的任一软件包。 + + ```sh + # osc branch openEuler:Mainline zlib + ``` + +2. 删除创建工程时新增的无用软件包。例如删除zlib软件包的参考命令如下: + + ```sh + # cd home:testUser:branches:openEuler:Mainline + # osc rm zlib + # osc commit -m "commit log" + ``` + +3. 在个人工程下创建新增的软件包。例如新增软件包 my-first-obs-package命令如下: + + ```sh + # mkdir my-first-obs-package + # cd my-first-obs-package + ``` + +构建RPM包 + +1. 添加准备的源文件和spec文件到软件包目录。 +2. 修改源代码和spec文件,并将对应软件包的所有文件上传到OBS服务器。参考命令如下,-m 参数后的信息为提交记录。 + + ```sh + # cd home:testUser:branches:openEuler:Mainline + # osc add my-first-obs-package + # osc ci -m "commit log" + ``` + +3. 获取当前工程的仓库名称和架构,参考命令如下: + + ```sh + # osc repos home:testUser:branches:openEuler:Mainline + ``` + +4. 修改提交成功后,OBS会自动开始编译软件包。可以通过如下命令,查看对应仓库的编译日志,其中 _standard_aarch64_ 、 _aarch64_ 分别为查询所得仓库名称和架构。 + + ```sh + # cd home:testUser:branches:openEuler:Mainline/my-first-obs-package + # osc buildlog standard_aarch64 aarch64 + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 用户也可以通过网页端打开自己创建的对应工程,查看构建日志。 + +#### 获取软件包 + +RPM软件包构建完成后,使用osc获取对应RPM软件包的命令如下: + +```sh +# osc getbinaries home:testUser:branches:openEuler:Mainline my-first-obs-package standard_aarch64 aarch64 +``` + +命令中的各参数含义如下,请用户根据实际情况修改: + +- _home:testUser:branches:openEuler:Mainline_ :软件包所在工程名称 +- _my-first-obs-package_ :软件包名称 +- _standard\_aarch64_ :仓库名称 +- _aarch64_ :仓库架构名称 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 使用osc构建的软件包也可以在网页端获取,获取方式请参见[获取软件包](#获取软件包)。 diff --git a/docs/en/25.03/Server/Development/ApplicationDev/figures/Branch-Confirmationpage.png b/docs/en/25.03/Server/Development/ApplicationDev/figures/Branch-Confirmationpage.png new file mode 100644 index 0000000000000000000000000000000000000000..e66cbcd22217b74785381b85128ea61895194882 Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/figures/Branch-Confirmationpage.png differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/figures/Create-Packagepage.png b/docs/en/25.03/Server/Development/ApplicationDev/figures/Create-Packagepage.png new file mode 100644 index 0000000000000000000000000000000000000000..36ea525856d428b6f88a338202e7cb59b2204fc0 Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/figures/Create-Packagepage.png differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/figures/RPM_package_download.png b/docs/en/25.03/Server/Development/ApplicationDev/figures/RPM_package_download.png new file mode 100644 index 0000000000000000000000000000000000000000..9f32d6c16d344df6951fc4e6aa027d02dfb9ccb5 Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/figures/RPM_package_download.png differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/figures/Repositoriespage.png b/docs/en/25.03/Server/Development/ApplicationDev/figures/Repositoriespage.png new file mode 100644 index 0000000000000000000000000000000000000000..b7c04eedf9dd32cf4a9d024a05f5c8b294c76934 Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/figures/Repositoriespage.png differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/figures/delete_package.png b/docs/en/25.03/Server/Development/ApplicationDev/figures/delete_package.png new file mode 100644 index 0000000000000000000000000000000000000000..a365cd1f46bfb8bec094b79477c0168861a5193b Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/figures/delete_package.png differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/figures/filepage.png b/docs/en/25.03/Server/Development/ApplicationDev/figures/filepage.png new file mode 100644 index 0000000000000000000000000000000000000000..83f0bfaeeb9227bcbb863a93ab8d3535e2b2bc1d Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/figures/filepage.png differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/figures/setting_software_info.png b/docs/en/25.03/Server/Development/ApplicationDev/figures/setting_software_info.png new file mode 100644 index 0000000000000000000000000000000000000000..0144be1f86e2a1d977881355022f7b5a5940cacb Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/figures/setting_software_info.png differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/figures/succeededpage.png b/docs/en/25.03/Server/Development/ApplicationDev/figures/succeededpage.png new file mode 100644 index 0000000000000000000000000000000000000000..3f10cd1db8bdc9be1ab8b660ef93e8a481c2d6b8 Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/figures/succeededpage.png differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/figures/zh-cn_image_0229243671.png b/docs/en/25.03/Server/Development/ApplicationDev/figures/zh-cn_image_0229243671.png new file mode 100644 index 0000000000000000000000000000000000000000..a32856aa08e459ed0f51f8fcf4c2f51511c12095 Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/figures/zh-cn_image_0229243671.png differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/figures/zh-cn_image_0229243702.png b/docs/en/25.03/Server/Development/ApplicationDev/figures/zh-cn_image_0229243702.png new file mode 100644 index 0000000000000000000000000000000000000000..96096879d161f04750a332e5c749a834c49d3173 Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/figures/zh-cn_image_0229243702.png differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/figures/zh-cn_image_0229243704.png b/docs/en/25.03/Server/Development/ApplicationDev/figures/zh-cn_image_0229243704.png new file mode 100644 index 0000000000000000000000000000000000000000..267bc9508f3a065b5b40c367e745f0d8c3ddb5fa Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/figures/zh-cn_image_0229243704.png differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/figures/zh-cn_image_0229243712.png b/docs/en/25.03/Server/Development/ApplicationDev/figures/zh-cn_image_0229243712.png new file mode 100644 index 0000000000000000000000000000000000000000..8d5a343524e14d11a3e2a94be4066fbb2d20599e Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/figures/zh-cn_image_0229243712.png differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/preparations-for-development-environment.md b/docs/en/25.03/Server/Development/ApplicationDev/preparations-for-development-environment.md new file mode 100644 index 0000000000000000000000000000000000000000..6f0cddd2144e645ad6970e45bcb8b9c5039ae1b2 --- /dev/null +++ b/docs/en/25.03/Server/Development/ApplicationDev/preparations-for-development-environment.md @@ -0,0 +1,414 @@ +# 开发环境准备 + +## 环境要求 + +- 若使用的是物理机,则开发环境所需的最小硬件要求如[表1](#table154419352610)所示。 + + **表 1** 最小硬件要求 + + + + + + + + + + + + + + + + + + + + + + + + +

部件名称

+

最小硬件要求

+

说明

+

架构

+
  • AArch64
  • x86_64
+
  • 支持Arm的64位架构。
  • 支持Intel的x86_64位架构。
+

CPU

+
  • 华为鲲鹏920系列CPU
  • Intel® Xeon®处理器
+

-

+

内存

+

不小于4GB(为了获得更好的应用体验,建议不小于8GB)

+

-

+

硬盘

+

为了获得更好的应用体验,建议不小于120GB)

+

支持IDE、SATA、SAS等接口的硬盘。

+
+ +- 若使用的是虚拟机,则开发环境所需的最小虚拟化空间要求如[表2](#table780410493819)所示。 + + **表 2** 最小虚拟化空间要求 + + + + + + + + + + + + + + + + + + + + + + + + +

部件名称

+

最小虚拟化空间要求

+

说明

+

架构

+
  • AArch64
  • x86_64
+

-

+

CPU

+

2个CPU

+

-

+

内存

+

不小于4GB(为了获得更好的应用体验,建议不小于8GB)

+

-

+

硬盘

+

不小于32GB(为了获得更好的应用体验,建议不小于120GB)

+

-

+
+ +### 操作系统要求 + +操作系统要求为openEuler操作系统。 + +openEuler操作系统具体安装方法请参考[安装指南](../../InstallationUpgrade/Installation/installation.md),其中“软件选择”页面的“已选环境的附加选项”中将“开发工具”勾选。 + +## 配置openEuler yum源 + +通过直接获取在线的openEuler repo源配置在线yum源或通过挂载ISO创建本地openEuler repo源配置本地yum源。 + +### 通过直接获取在线的openEuler repo源配置在线yum源 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> openEuler提供了多种repo源供用户在线使用,各repo源含义可参考[系统安装](../../Releasenotes/Releasenotes/installing-the-os.md)。本操作以AArch64架构的OS repo源为例将其配置为yum源。 + +1. 进入到yum源目录并查看目录下的.repo配置文件。 + + ```shell + # cd /etc/yum.repos.d + # ls + openEuler-xxx.repo + ``` + +2. 在root权限下编辑openEuler-xxx.repo文件,将在线的openEuler repo源配置为yum源。 + + ```shell + # vi openEuler-xxx.repo + ``` + + 编辑openEuler-xxx.repo文件的内容如下,其中{version}和{arch}请根据实际情况进行替换: + + ```text + [osrepo] + name=osrepo + baseurl=http://repo.openeuler.org/openEuler-{version}/OS/{arch}/ + enabled=1 + + gpgcheck=1 + gpgkey=http://repo.openeuler.org/openEuler-{version}/OS/{arch}/RPM-GPG-KEY-openEuler + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > + > - \[*repoid*\]中的repoid为软件仓库(repository)的ID号,所有.repo配置文件中的各repoid不能重复,必须唯一。示例中repoid设置为**osrepo**。 + > - name为软件仓库描述的字符串。 + > - baseurl为软件仓库的地址。 + > - enabled为是否启用该软件源仓库,可选值为1和0。缺省值为1,表示启用该软件源仓库。 + > - gpgcheck可设置为1或0,1表示进行gpg(GNU Private Guard)校验,0表示不进行gpg校验,gpgcheck可以确定rpm包的来源是有效和安全的。 + > - gpgkey为验证签名用的公钥。 + +### 通过挂载ISO创建本地openEuler repo源配置本地yum源 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> openEuler提供了多种ISO发布包,各ISO发布包含义可参考[系统安装](../../Releasenotes/Releasenotes/installing-the-os.md)。本操作中忽略具体的版本号和架构,请根据实际需要的ISO发布包和校验文件进行修改。 + +1. 下载ISO发布包。 + - 通过跨平台文件传输工具下载ISO镜像。 + 1. 登录[openEuler社区](https://openeuler.org/zh/)网站。 + 2. 单击“下载”。 + 3. 单击“社区发行版”,显示版本列表。 + 4. 在版本列表处找到对应的版本号,单击“前往下载”按钮,进入版本下载列表。 + 5. 在对应的系统下载列表中,可以查看系统镜像架构和应用场景。 + + 架构分类如下: + AArch64:AArch64架构的ISO。 + x86\_64:x86\_64架构的ISO。 + ARM32:嵌入式的Image。 + + 场景分类如下: + 服务器:服务器场景的ISO。 + 边缘计算:边缘计算场景的ISO。 + 云计算:云计算场景的ISO。 + 嵌入式:嵌入式的Image(只有选择AArch64或ARM32架构时,才可选该场景)。 + + 6. 单击“AArch64”,选择AArch64架构。 + 7. 单击“服务器”,选择服务器场景。 + 8. 在“软件包类型”栏选择需要的ISO,单击“立即下载”。 + 9. 单击该ISO对应的完整性校验文件“SHA256”,复制校验值到本地。 + 10. 登录openEuler操作系统,新建用于存放发布包的目录,如“~/iso”。 + + ```shell + # mkdir ~/iso + ``` + + 11. 使用跨平台文件传输工具(如WinSCP)将本地的openEuler发布包上传到openEuler操作系统。 + + - 通过wget命令下载ISO镜像。 + 1. 登录[openEuler社区](https://openeuler.org/zh/)网站。 + 2. 单击“下载”。 + 3. 单击“社区发行版”,显示版本列表。 + 4. 在版本列表处找到对应的版本号,单击“前往下载”按钮,进入版本下载列表。 + 5. 在对应的系统下载列表中,可以查看系统镜像架构和应用场景。 + + 架构分类如下: + AArch64:AArch64架构的ISO。 + x86\_64:x86\_64架构的ISO。 + ARM32:嵌入式的Image。 + + 场景分类如下: + 服务器:服务器场景的ISO。 + 边缘计算:边缘计算场景的ISO。 + 云计算:云计算场景的ISO。 + 嵌入式:嵌入式的Image(只有选择AArch64或ARM32架构时,才可选该场景)。 + + 6. 单击“AArch64”,选择AArch64架构。 + 7. 单击“服务器”,选择服务器场景。 + 8. 在“软件包类型”栏选择需要的ISO,右键单击“立即下载”,单击“复制链接地址”,将openEuler发布包地址记录好。 + 9. 单击复制该ISO对应的完整性校验文件“SHA256”,将openEuler校验文件记录好。 + 10. 登录openEuler操作系统,新建用于存放发布包和检验文件的目录,如“~/iso”,并切换到该目录。 + + ```shell + # mkdir ~/iso + # cd ~/iso + ``` + + 11. 使用**wget**命令远程下载发布包,命令中的 *ipaddriso* 为openEuler发布包地址。 + + ```shell + # wget ipaddriso + ``` + +2. 发布包完整性校验。 + 1. 计算openEuler发布包的sha256校验值。 + + ```shell + sha256sum openEuler-xxx-dvd.iso + ``` + + 命令执行完成后,输出校验值。 + + 2. 对比步骤1和复制的校验值是否一致。 + + 如果校验值一致说明iso文件完整性没有被破坏,如果校验值不一致则可以确认文件完整性已被破坏,需要重新获取。 + +3. 挂载ISO并创建为repo源。 + + 在root权限下使用mount命令挂载镜像文件。 + + 示例如下: + + ```shell + # mount /home/iso/openEuler-xxx-dvd.iso /mnt/ + ``` + + 挂载好的mnt目录如下: + + ```text + . + │── boot.catalog + │── docs + │── EFI + │── images + │── Packages + │── repodata + │── TRANS.TBL + └── RPM-GPG-KEY-openEuler + ``` + + 其中,Packages为rpm包所在的目录,repodata为repo源元数据所在的目录,RPM-GPG-KEY-openEuler为openEuler的签名公钥。 + +4. 进入到yum源目录并查看目录下的.repo配置文件。 + + ```shell + # cd /etc/yum.repos.d + # ls + openEuler-xxx.repo + ``` + +5. 在root权限下编辑openEuler-xxx.repo文件,将[3](#li6236932222)中创建的repo源配置为本地yum源。 + + ```shell + # vi openEuler-xxx.repo + ``` + + 编辑openEuler-xxx.repo文件的内容如下: + + ```text + [localosrepo] + name=localosrepo + baseurl=file:///mnt + enabled=1 + gpgcheck=1 + gpgkey=file:///mnt/RPM-GPG-KEY-openEuler + ``` + +## 安装软件包 + +安装开发过程中需要用到的软件。不同的开发需要的软件不一样,但安装方法相同,本章以安装常用的几个软件包(JDK,rpm-build)为例。有些开发软件openEuler操作系统已默认自带,如GCC、GNU make。 + +### 安装JDK软件包 + +1. 执行 `dnf list installed | grep jdk` 查询JDK软件是否已安装。 + + 查看回显,若回显中包含“jdk”,表示该软件已经安装了,则不需要再安装。若无任何回显,则表示该软件未安装。 + +2. 执行 `dnf clean all` 清除缓存。 + +3. 执行 `dnf makecache` 创建缓存。 + +4. 执行 `dnf search jdk | grep jdk` 查询可安装的JDK软件包。 + + 查看回显,选择安装java-{version}-openjdk-devel.aarch64软件包。 + +5. root权限执行 `dnf install java-{version}-openjdk-devel.aarch64` 安装JDK软件包。 + +6. 执行 `java -version` 查询JDK软件版本。 + + 查看回显,若回显中包含“openjdk version”信息,表示已正确安装。 + +### 安装rpm-build软件包 + +1. 执行 `dnf list installed | grep rpm-build` 查询rpm-build软件是否已安装。 + + 查看回显,若回显中包含“rpm-build”,表示该软件已经安装了,则不需要再安装。若无任何回显,则表示该软件未安装。 + +2. 执行 `dnf clean all` 清除缓存。 + +3. 执行 `dnf makecache` 创建缓存。 + +4. root权限执行 `dnf install rpm-build` 安装rpm-build软件包。 + +5. 执行 `rpmbuild --version` 查询rpm-build软件版本。 + +## 使用IDE进行Java开发 + +对于小型的Java程序,可以直接参考“使用JDK编译”章节得到可运行Java应用。但是对于大中型Java应用,这种方式已经无法满足开发者的需求。因此您可以参考如下步骤安装IDE并进行使用,以方便您在openEuler系统上的Java开发工作。 + +### 简介 + +IntelliJ IDEA是一款非常流行的Java IDE,其社区版可以免费下载使用。目前openEuler支持使用IntelliJ IDEA集成开发环境(IDE)进行Java程序的开发,从而可以提升开发人员的工作效率。 + +### 使用MobaXterm登录服务器 + +MobaXterm是一款非常优秀的SSH客户端,其自带X Server,可以轻松解决远程GUI显示问题。 + +您需要提前下载安装好MobaXterm并打开,然后SSH登录您的服务器并进行以下操作。 + +### 设置JDK环境 + +在设置JAVA\_HOME之前您需要先找到JDK的安装路径。在“开发环境准备 \> 安装软件包 \> 安装JDK软件包”章节中您已经学会了如何安装JDK,如果您还没安装好JDK,请提前安装好。 + +查看java路径,命令如下: + +```shell +# which java +/usr/bin/java +``` + +查看软链接的实际指向目录,命令如下: + +```shell +# ls -la /usr/bin/java +lrwxrwxrwx. 1 root root 22 Mar 6 20:28 /usr/bin/java -> /etc/alternatives/java +# ls -la /etc/alternatives/java +lrwxrwxrwx. 1 root root 83 Mar 6 20:28 /etc/alternatives/java -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-1.h2.aarch64/jre/bin/java +``` + +发现JDK的真实路径为/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-1.h2.aarch64,设置JAVA\_HOME和PATH,命令如下: + +```shell +# export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-1.h2.aarch64 +# export PATH=$JAVA_HOME/bin:$PATH +``` + +### 下载安装GTK库 + +运行如下命令: + +```shell +# dnf list installed | grep gtk +``` + +如果显示gtk2或者gtk3,则表示您已安装该库,可以直接跳过进入下一步,否则在root权限下运行如下命令自动下载安装gtk库。 + +```shell +# dnf -y install gtk2 libXtst libXrender xauth +``` + +### 设置X11 Forwarding + +切换到sshd配置目录 + +```shell +# cd ~/.ssh +``` + +如果该目录不存在,则创建目录后再进行切换,创建目录命令如下: + +```shell +# mkdir ~/.ssh +``` + +然后在.ssh目录下编辑config文件并保存: + +1. 使用vim打开config文件 + + ```shell + # vim config + ``` + +2. 将以下内容添加到文件末尾并保存: + + ```text + Host * + ForwardAgent yes + ForwardX11 yes + ``` + +### 下载并运行IntelliJ IDEA + +在执行如上环境配置后,您就可以下载使用IntelliJ IDEA了。鉴于最新版的IntelliJ IDEA和openEuler系统在部分功能上有兼容性问题,建议您从此[链接](https://www.jetbrains.com/idea/download/other.html)下载2018版本linux压缩包。下载好后把压缩包移到您想要安装该软件的目录,对压缩包进行解压: + +```shell +# tar -xf ideaIC-2018.3.tar.gz +``` + +解压后切换到IntelliJ IDEA的目录下并运行。 + +```shell +# cd ./idea-IC-183.4284.148 +# bin/idea.sh & +``` diff --git a/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-caution.gif b/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-caution.gif differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-danger.gif b/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-danger.gif differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-note.gif b/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-notice.gif b/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-notice.gif differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-tip.gif b/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-tip.gif differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-warning.gif b/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Development/ApplicationDev/public_sys-resources/icon-warning.gif differ diff --git a/docs/en/25.03/Server/Development/ApplicationDev/using-clang-for-compilation.md b/docs/en/25.03/Server/Development/ApplicationDev/using-clang-for-compilation.md new file mode 100644 index 0000000000000000000000000000000000000000..2d25fd54df82d76231dd303bae176647b60968fb --- /dev/null +++ b/docs/en/25.03/Server/Development/ApplicationDev/using-clang-for-compilation.md @@ -0,0 +1,103 @@ +# 使用LLVM/Clang编译 + +本章介绍LLVM/Clang编译的一些基本知识,并通过示例进行实际演示。更多Clang使用方法请通过**clang --help**命令查询。 + + +- [使用LLVM/Clang编译](#使用llvmclang编译) + - [简介](#简介) + - [LLVM/Clang安装](#llvmclang安装) + - [多版本共存支持](#多版本共存支持) + - [示例](#示例) + + + +## 简介 + +LLVM是一种涵盖多种编程语言和目标处理器的编译器,使用Clang作为C和C++的编译和驱动程序。Clang不仅仅可以将C, C++程序编译为LLVM中间表示的IR,也会调用所有以代码生成为目标的LLVM优化遍,直到生成最终的二进制文件。 + +## LLVM/Clang安装 + +openEuler操作系统中通过yum源安装Clang和LLVM软件包。默认安装llvm-12 + +```shell +yum install llvm +yum install clang +yum install lld // openEuler yum源中目前没有lld-12版本 +``` + +验证安装是否成功 + +```shell +clang -v +``` + +若返回结果中包含clang版本信息,说明安装成功。 + +## 多版本共存支持 + +openEuler LLVM/Clang 多版本支持的方式如下: + +```text +yum包名: +llvm{-*} +clang{-*} +lld{-*} +bolt{-*} +例如: +clang15 +llvm15-devel + +安装路径: +/usr/lib64/llvm +例如: +/usr/lib64/llvm15 + +/usr/bin目录下会安装带有-后缀的可执行文件 +例如: +/usr/bin/clang-15 +/usr/bin/lld-15 +``` + +目前支持的LLVM/Clang版本有 + +```text +llvm //默认llvm12 +llvm-15 +``` + +通过yum安装其他版本 + +```shell +yum install llvm15 +yum install clang15 +yum install lld15 +``` + +验证安装是否成功 + +```shell +clang-15 -v +``` + +## 示例 + +编译运行C/C++程序 + +```shell +clang [command line flags] hello.c -o hello.o +./hello.o +``` + +```shell +clang++ [command line flags] hello.cpp -o hello.o +./hello.o +``` + +指定的链接器为LLVM的lld,若不指定它则使用默认的lld。 + +```shell +clang [command line flags] -fuse-ld=lld hello.c -o hello.o +./hello.o +``` + +其他通用信息请参考LLVM的[用户指导](https://llvm.org/docs/UserGuides.html) diff --git a/docs/en/25.03/Server/Development/ApplicationDev/using-gcc-for-compilation.md b/docs/en/25.03/Server/Development/ApplicationDev/using-gcc-for-compilation.md new file mode 100644 index 0000000000000000000000000000000000000000..043f6876746f8eafc6cfe05d50e56391524bda16 --- /dev/null +++ b/docs/en/25.03/Server/Development/ApplicationDev/using-gcc-for-compilation.md @@ -0,0 +1,612 @@ +# 使用GCC编译 + +本章介绍GCC编译的一些基本知识,并通过示例进行实际演示。更多的GCC知识请通过**man gcc**命令查询。 + + +- [使用GCC编译](#使用gcc编译) + - [简介](#简介) + - [基本规则](#基本规则) + - [文件类型](#文件类型) + - [编译流程](#编译流程) + - [编译选项](#编译选项) + - [多源文件编译](#多源文件编译) + - [库](#库) + - [动态链接库](#动态链接库) + - [静态链接库](#静态链接库) + - [示例](#示例) + - [使用GCC编译C程序示例](#使用gcc编译c程序示例) + - [使用GCC创建和使用动态链接库示例](#使用gcc创建和使用动态链接库示例) + - [使用GCC创建和使用静态链接库示例](#使用gcc创建和使用静态链接库示例) + + + +## 简介 + +GCC(GNU Compiler Collection)是GNU推出的功能强大、性能优越的多平台编译器。GCC编译器能将C、C++语言源程序、汇编程序和目标程序编译、链接成可执行文件。openEuler操作系统中已默认安装了GCC软件包。 + +## 基本规则 + +### 文件类型 + +对于任何给定的输入文件,文件类型决定进行何种编译。GCC常用的文件类型如[表1](#table634145764320)所示。 + +**表 1** GCC常用的文件类型 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

扩展名(后缀)

+

说明

+

.c

+

C语言源代码文件。

+

.C,.cc或.cxx

+

C++源代码文件。

+

.m

+

Objective-C源代码文件。

+

.s

+

汇编语言源代码文件。

+

.i

+

已经预处理的C源代码文件。

+

.ii

+

已经预处理的C++源代码文件。

+

.S

+

已经预处理的汇编语言源代码文件。

+

.h

+

程序所包含的头文件。

+

.o

+

编译后的目标文件。

+

.so

+

动态链接库,它是一种特殊的目标文件。

+

.a

+

静态链接库。

+

.out

+

可执行文件,但可执行文件没有统一的后缀,系统从文件的属性来区分可执行文件和不可执行文件。如果没有给出可执行文件的名字,GCC将生成一个名为a.out的文件。

+
+ +### 编译流程 + +使用GCC将源代码文件生成可执行文件,需要经过预处理、编译、汇编和链接。 + +1. 预处理:将源程序(如 **.c** 文件)预处理,生成 **.i** 文件。 +2. 编译:将预处理后的 **.i** 文件编译成为汇编语言,生成 **.s** 文件。 +3. 汇编:将汇编语言文件经过汇编,生成目标文件 **.o** 文件。 +4. 链接:将各个模块的 **.o** 文件链接起来生成一个可执行程序文件。 + +其中 **.i** 文件、**.s**文件、**.o**文件是中间文件或临时文件,如果使用GCC一次性完成C语言程序的编译,则这些文件会被删除。 + +### 编译选项 + +GCC编译的命令格式为:**gcc** \[_options_\] filenames + +其中: + +_options_ :编译选项。 + +_filenames_ :文件名称。 + +GCC是一个功能强大的编译器,其 _options_ 参数取值很多,但大部分并不常用,常用的 _options_ 取值如[表2](#table1342946175212)所示。 + +**表 2** GCC常用的编译选项 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

options取值

+

说明

+

示例

+

-c

+

编译、汇编指定的源文件生成目标文件,但不进行链接。通常用于编译不包含主程序的子程序文件。

+

#使用-c选项编译test1.c、test2.c源文件

+

gcc -c test1.c test2.c

+

-S

+

编译指定的源文件生成以.s作为后缀的汇编语言文件,但不进行汇编。

+

#编译器预处理 circle.c,将其翻译成汇编语言,并将结果存储在 circle.s 文件中。

+

gcc -S circle.c

+

-E

+

预处理指定的源文件,但不进行编译。

+

默认情况下,预处理器的输出会被导入到标准输出流(如显示器),可以利用-o选项把它导入到某个输出文件。

+

#预处理的结果导出到 circle.i 文件。

+

gcc -E circle.c -o circle.i

+

-o file

+

用在生成可执行文件时,生成指定的输出文件file。同时该名称不能和源文件同名。如果不给出这个选项,gcc就给出预设的可执行文件a.out。

+

#将源文件作为输入文件,将可执行文件作为输出文件,也即完整地编译整个程序。

+

gcc main.c func.c -o app.out

+

-g

+

在可执行程序中包含标准调试信息。

+

-

+

-L library_path

+

在库文件的搜索路径列表中添加library_path路径。

+

-

+

-Ilibrary

+

链接时搜索指定的函数库library

+

使用 GCC 编译和链接程序时,GCC 默认会链接 libc.a 或者 libc.so,但是对于其他的库(例如非标准库、第三方库等),就需要手动添加。

+

#使用-l选项,以链接数学库。

+

gcc main.c -o main.out -lm

+
说明:

数学库的文件名是 libm.a。前缀lib和后缀.a是标准的,m是基本名称,GCC 会在-l选项后紧跟着的基本名称的基础上自动添加这些前缀、后缀,本例中,基本名称为 m。

+
+

-I head_path

+

在头文件的搜索路径列表中添加head_path路径。

+

-

+

-static

+

进行静态编译,及链接静态库,禁止链接动态库。

+

-

+

-shared

+

默认选项,可省略。

+
  • 可以生成动态库文件。
  • 进行动态编译,优先链接动态库,只有没有动态库时才会链接同名的静态库。
+

-

+

-fPIC(或-fpic)

+

生成使用相对地址的位置无关的目标代码。通常使用-static选项从该PIC目标文件生成动态库文件。

+

-

+
+ +### 多源文件编译 + +多个源文件的编译方法有2种。 + +- 多个源文件一起编译。编译时需要所有文件重新编译。 + + 示例:将test1.c和test2.c分别编译后链接成test可执行文件。 + + ```shell + gcc test1.c test2.c -o test + ``` + +- 分别编译各个源文件,之后对编译后输出的目标文件链接。编译时只重新编译修改的文件,未修改的文件不用重新编译。 + + 示例:分别编译test1.c,test2.c,再将二者的目标文件test1.o,test2.o链接成test可执行文件。 + + ```shell + gcc -c test1.c + gcc -c test2.c + gcc test1.o test2.o -o test + ``` + +## 库 + +库是写好的、现有的、成熟的、可以复用的代码。每个程序都要依赖很多基础的底层库。 + +库文件在命名时约定,以lib为前缀,以.so(动态库)或.a(静态库)为后缀,中间为库文件名。如libfoo.so或libfoo.a。由于所有的库文件都遵循了同样的规范,因此当在链接库时,-l 选项指定链接的库文件名时可以省去lib前缀,即GCC 在对-lfoo 进行处理时,会自动去链接名为libfoo.so 或libfoo.a的库文件。而当在创建库时,必须指定完整文件名libfoo.so或libfoo.a。 + +根据链接时期的不同,库分为静态库和动态库。静态库是在链接阶段,将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中;而动态库是在程序编译时并不会被链接到目标代码中,而是在程序运行时才被载入。二者有如下差异。 + +- 资源利用不一样。 + + 静态库为生成的可执行文件的一部分,而动态库为单独的文件。所以使用静态库和动态库的可执行文件大小和占用的磁盘空间大小不一样,导致资源利用不一样。 + +- 扩展性与兼容性不一样 + + 静态库中某个函数的实现变了,那么可执行文件必须重新编译,而对于动态链接生成的可执行文件,只需要更新动态库本身即可,不需要重新编译可执行文件。 + +- 依赖不一样 + + 静态库的可执行文件不需要依赖其他的内容即可运行,而动态库的可执行文件必须依赖动态库的存在。所以静态库更方便移植。 + +- 加载速度不一样 + + 静态库在链接时就和可执行文件在一块了,而动态库在加载或者运行时才链接,因此,对于同样的程序,静态链接的要比动态链接加载更快。 + +### 动态链接库 + +使用-shared选项 和-fPIC选项,可直接使用源文件、汇编文件或者目标文件创建一个动态库。其中-fPIC 选项作用于编译阶段,在生成目标文件时就需要使用该选项,以生成位置无关的代码。 + +示例1:从源文件生成动态链接库。 + +```shell +gcc -fPIC -shared test.c -o libtest.so +``` + +示例2:从目标文件生成动态链接库。 + +```shell +gcc -fPIC -c test.c -o test.o +gcc -shared test.o -o libtest.so +``` + +将一个动态库链接到可执行文件,需要在命令行中列出动态库的名称。 + +示例:将main.c和libtest.so一起编译成 app.out,当 app.out 运行时,会动态地加载链接库 libtest.so。 + +```shell +gcc main.c libtest.so -o app.out +``` + +这种方式是直接指定使用当前目录下的libtest.so文件。 + +若使用下面搜索动态库的方式,则为了确保程序在运行时能够链接到动态库,需要通过如下三种方法中的任一种实现。 + +- 将动态库保存在标准目录下,例如 /usr/lib。 +- 把动态库所在路径libraryDIR增加到环境变量LD\_LIBRARY\_PATH中 + + ```sh + # export LD\_LIBRARY\_PATH=libraryDIR:$LD\_LIBRARY\_PATH + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > LD\_LIBRARY\_PATH为动态库的环境变量。当运行动态库时,若动态库不在缺省文件夹(/lib 和/usr/lib)下,则需要指定环境变量LD\_LIBRARY\_PATH。 + +- 把动态库所在路径libraryDIR增加 /etc/ld.so.conf中然后执行ldconfig或者以动态库所在路径libraryDIR为参数执行ldconfig。 + +```shell +gcc main.c -L libraryDIR -ltest -o app.out +export LD_LIBRARY_PATH=libraryDIR:$LD_LIBRARY_PATH +``` + +### 静态链接库 + +创建一个静态链接库,需要先将源文件编译为目标文件,然后再使用ar命令将目标文件打包成静态链接库。 + +示例:将源文件test1.c,test2.c,test3.c编译并打包成静态库。 + +```shell +gcc -c test1.c test2.c test3.c +ar rcs libtest.a test1.o test2.o test3.o +``` + +其中ar是一个备份压缩命令,可以将多个文件打包成一个备份文件(也叫归档文件),也可以从备份文件中提取成员文件。ar最常见的用法是将目标文件打包为静态链接库。 + +ar将目标文件打包成静态链接库的命令格式为: + +ar rcs _Sllfilename_ _Targetfilelist_ + +- _Sllfilename_ :静态库文件名。 +- _Targetfilelist_ :目标文件列表。 +- r: 替换库中已有的目标文件,或者加入新的目标文件。 +- c: 创建一个库,不管库是否存在,都将创建。 +- s: 创建目标文件索引,在创建较大的库时能提高速度。 + +示例:创建一个main.c文件来使用静态库 + +```shell +gcc main.c -L libraryDIR -ltest -o test.out +``` + +其中libraryDIR为libtest.a库的路径。 + +## 示例 + +### 使用GCC编译C程序示例 + +1. cd到代码目录,此处以目录“~/code”进行举例,如下所示: + + ```shell + cd ~/code + ``` + +2. 编写Hello World程序,保存为helloworld.c,此处以编译Hello World程序进行举例说明,示例如下: + + ```shell + vi helloworld.c + ``` + + 代码内容示例: + + ```c + #include + int main() + { + printf("Hello World!\n"); + return 0; + } + ``` + +3. 在代码目录,执行编译,使用命令: + + ```shell + gcc helloworld.c -o helloworld + ``` + + 编译执行未报错,表明执行通过。 + +4. 编译完成后,会生成helloworld文件,查看编译结果,示例如下: + + ```shell + # ./helloworld + Hello World! + ``` + +### 使用GCC创建和使用动态链接库示例 + +1. cd到代码目录,此处以目录“~/code”进行举例。并在该目录下创建src,lib,include子目录,分别用于存放源文件,动态库文件和头文件。 + + ```shell + cd ~/code + mkdir src lib include + ``` + +2. cd到~/code/src目录,创建2个函数add.c、sub.c,分别实现加、减。 + + ```shell + cd ~/code/src + vi add.c + vi sub.c + ``` + + add.c代码内容示例: + + ```shell + #include "math.h" + int add(int a, int b) + { + return a+b; + } + ``` + + sub.c代码内容示例: + + ```c + #include "math.h" + int sub(int a, int b) + { + return a-b; + } + ``` + +3. 将add.c、sub.c源文件创建为动态库libmath.so,并将该动态库存放在~/code/lib目录。 + + ```shell + gcc -fPIC -shared add.c sub.c -o ~/code/lib/libmath.so + ``` + +4. cd到~/code/include目录,创建1个头文件math.h,声明函数的头文件。 + + ```shell + cd ~/code/include + vi math.h + ``` + + math.h代码内容示例: + + ```c + #ifndef __MATH_H_ + #define __MATH_H_ + int add(int a, int b); + int sub(int a, int b); + #endif + ``` + +5. cd到~/code/src目录,创建一个调用add\(\)和sub\(\)的main.c函数。 + + ```shell + cd ~/code/src + vi main.c + ``` + + math.c代码内容示例: + + ```c + #include + #include "math.h" + int main() + { + int a, b; + printf("Please input a and b:\n"); + scanf("%d %d", &a, &b); + printf("The add: %d\n", add(a,b)); + printf("The sub: %d\n", sub(a,b)); + return 0; + } + ``` + +6. 将main.c和libmath.so一起编译成math.out。 + + ```shell + gcc main.c -I ~/code/include -L ~/code/lib -lmath -o math.out + ``` + +7. 将动态链接库所在的路径加入到环境变量中。 + + ```shell + export LD_LIBRARY_PATH=~/code/lib:$LD_LIBRARY_PATH + ``` + +8. 执行math.out。 + + ```shell + ./math.out + ``` + + 执行结果如下所示: + + ```text + Please input a and b: + 9 2 + The add: 11 + The sub: 7 + ``` + +### 使用GCC创建和使用静态链接库示例 + +1. cd到代码目录,此处以目录“~/code”进行举例。并在该目录下创建src,lib,include子目录,分别用于存放源文件,静态库文件和头文件。 + + ```shell + cd ~/code + mkdir src lib include + ``` + +2. cd到~/code/src目录,创建2个函数add.c、sub.c,分别实现加、减。 + + ```shell + cd ~/code/src + vi add.c + vi sub.c + ``` + + add.c代码内容示例: + + ```c + #include "math.h" + int add(int a, int b) + { + return a+b; + } + ``` + + sub.c代码内容示例: + + ```c + #include "math.h" + int sub(int a, int b) + { + return a-b; + } + ``` + +3. 将add.c、sub.c源文件编译为目标文件add.o、sub.o。 + + ```shell + gcc -c add.c sub.c + ``` + +4. 将add.o、sub.o目标文件通过ar命令打包成静态库libmath.a,并将该静态库存放在~/code/lib目录。 + + ```shell + ar rcs ~/code/lib/libmath.a add.o sub.o + ``` + +5. cd到~/code/include目录,创建1个头文件math.h,声明函数的头文件。 + + ```shell + cd ~/code/include + vi math.h + ``` + + math.h代码内容示例: + + ```c + #ifndef __MATH_H_ + #define __MATH_H_ + int add(int a, int b); + int sub(int a, int b); + #endif + ``` + +6. cd到~/code/src目录,创建一个调用add\(\)和sub\(\)的main.c函数。 + + ```shell + cd ~/code/src + vi main.c + ``` + + math.c代码内容示例: + + ```c + #include + #include "math.h" + int main() + { + int a, b; + printf("Please input a and b:\n"); + scanf("%d %d", &a, &b); + printf("The add: %d\n", add(a,b)); + printf("The sub: %d\n", sub(a,b)); + return 0; + } + ``` + +7. 将main.c和libmath.a一起编译成math.out。 + + ```shell + gcc main.c -I ~/code/include -L ~/code/lib -lmath -o math.out + ``` + +8. 执行math.out。 + + ```shell + ./math.out + ``` + + 执行结果如下所示: + + ```text + Please input a and b: + 9 2 + The add: 11 + The sub: 7 + ``` diff --git a/docs/en/25.03/Server/Development/ApplicationDev/using-jdk-for-compilation.md b/docs/en/25.03/Server/Development/ApplicationDev/using-jdk-for-compilation.md new file mode 100644 index 0000000000000000000000000000000000000000..a8abf11152d08224a146bb916f47ed7ecc2fcc74 --- /dev/null +++ b/docs/en/25.03/Server/Development/ApplicationDev/using-jdk-for-compilation.md @@ -0,0 +1,526 @@ +# 使用JDK编译 + + + +- [使用JDK编译](#使用jdk编译) + - [简介](#简介) + - [基本规则](#基本规则) + - [文件类型及工具](#文件类型及工具) + - [java程序生成流程](#java程序生成流程) + - [JDK常用工具选项](#jdk常用工具选项) + - [类库](#类库) + - [包的声明](#包的声明) + - [包的引用](#包的引用) + - [示例](#示例) + - [编译不带包的java程序示例](#编译不带包的java程序示例) + - [编译带包的java程序示例](#编译带包的java程序示例) + + + +## 简介 + +JDK(Java Development Kit)是 Java 开发者进行 Java 开发所必须的软件包,包含 JRE(Java Runtime Environment)和编译、调测工具。openEuler在OpenJDK 的基础上进行了 GC 优化、并发稳定性增强、安全性增强等修改,提高了 Java 应用程序在 ARM 上的性能和稳定性。 + +## 基本规则 + +### 文件类型及工具 + +对于任何给定的输入文件,文件类型决定采用何种工具进行处理。JDK常用的文件类型如[表1](#table634145764320)所示,JDK常用的工具如[表2](#table103504146433)所示。 + +**表 1** JDK常用的文件类型 + + + + + + + + + + + + + + + + +

扩展名(后缀)

+

说明

+

.java

+

java语言源代码文件。

+

.class

+

java的字节码文件,是一种和任何具体机器环境及操作系统环境无关的中间代码。它是一种二进制文件,是Java 源文件由 Java 编译器编译后生成的目标代码文件。

+

.jar

+

java的jar压缩文件。

+
+ +**表 2** JDK常用的工具 + + + + + + + + + + + + + + + + +

工具名称

+

说明

+

java

+

Java运行工具,用于运行.class字节码文件或.jar文件。

+

javac

+

Java编程语言的编译器,将.java的源代码文件编译成.class的字节码文件。

+

jar

+

创建和管理Jar文件

+
+ +### java程序生成流程 + +通过JDK将java源代码文件生成并运行Java程序,需要经过编译和运行。 + +1. 编译:是指使用Java编译器(javac)将java源代码文件(.java文件)编译为.class的字节码文件。 +2. 运行:是指在Java虚拟机上执行字节码文件。 + +### JDK常用工具选项 + +#### javac编译选项 + +javac编译的命令格式为:**javac** \[_options_\] \[_sourcefiles_\] \[_classes_\] \[@_argfiles_\] + +其中: + +_options_ :命令选项。 + +_sourcefiles_ :一个或多个需要编译的源文件。 + +_classes_ :一个或多个要为注释处理的类。 + +@_argfiles_ :一个或多个列出选项和源文件的文件。这些文件中不允许有-J选项。 + +javac是java编译器,其 _options_ 参数取值很多,但有些大部分并不常用,常用的 _options_ 取值如[表3](#table1342946175212)所示。 + +**表 3** javac常用的编译选项 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

options取值

+

说明

+

示例

+

-d path

+

指定存放生成的类文件的路径

+

默认情况下,编译生成的类文件与源文件在同一路径下。使用-d选项可以将类文件输出到指定路径。

+

#使用-d选项将所有类文件输出到bin路径下

+

javac /src/*.java -d /bin

+

-s path

+

指定存放生成的源文件的路径

+

-

+

-cp path或-classpath path

+

搜索编译所需的class文件,指出编译所用到的class文件的位置。

+

#在Demo中要调用GetStringDemo类中的getLine()方法,而GetStringDemo类编译后的文件,即.class文件在bin目录下。

+

javac -cp bin Demo.java -d bin

+

-verbose

+

输出关于编译器正在执行的操作的消息,如加载的类信息和编译的源文件信息。

+

#输出关于编译器正在执行的操作的消息。

+

javac -verbose -cp bin Demo.java

+

-source sourceversion

+

指定查找输入源文件的位置。

+

-

+

-sourcepath path

+

用于搜索编译所需的源文件(即java文件),指定要搜索的源文件的位置,如jar、zip或其他包含java文件的目录。

+

-

+

-target targetversion

+

生成特定JVM版本的类文件。取值为1.1,1.2,1.3,1.4,1.5(或5),1.6(或6),1.7(或7),1.8(或8)。targetversion的缺省值与-source选项的sourceversion有关。sourceversion取值:

+
  • 1.2,targetversion为1.4;
  • 1.3,targetversion为1.4;
  • 1.5、1.6、1.7、未指定,targetversion为1.8。
  • 其他值,targetversionsourceversion取值相同。
+

-

+
+ +#### java运行选项 + +java运行的格式为: + +运行类文件:**java** \[_options_\] _classesname_ \[args\] + +运行jar文件:**java** \[_options_\] -jar _filename_ \[args\] + +其中: + +_options_ :命令选项,选项之间用空格分隔。 + +_classname_ :运行的.class文件名。 + +_filename_ :运行的.jar文件名。 + +args:传递给main\(\)函数的参数,参数之间用空格分隔。 + +java是运行java应用程序的工具,其 _options_ 参数取值很多,但有些大部分并不常用,常用的 _options_ 取值如[表4](#table371918587238)所示。 + +**表 4** java常用的运行选项 + + + + + + + + + + + + + + + + +

options取值

+

说明

+

示例

+

-cp path或-classpath path

+

指定要运行的文件所在的位置以及需要用到的类路径,包括jar、zip和class文件目录。

+

当路径有多个时,使用“:”分隔。

+

-

+

-verbose

+

输出关于编译器正在执行的操作的消息,如加载的类信息和编译的源文件信息。

+

#输出关于编译器正在执行的操作的消息。

+

java -verbose -cp bin Demo.java

+
+ +#### jar打包选项 + +jar的命令格式为:**jar** \{c | t | x | u\}\[vfm0M\] \[_jarfile_\] \[_manifest_\] \[-C _dir_\] _file_... + +jar命令参数说明如[表5](#table3691718114817)所示。 + +**表 5** jar命令参数说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

说明

+

示例

+

c

+

创建jar文件包。

+

#把当前目录的hello.class文件打包到Hello.jar,且不显示打包的过程。如果Hello.jar文件还不存在,就创建它,否则首先清空它。

+

jar cf Hello.jar hello.class

+

t

+

列出jar文件包的内容列表。

+

#列出Hello.jar包含的文件清单。

+

jar tf Hello.jar

+

x

+

展开jar文件包的指定文件或者所有文件。

+

#解压Hello.jar 到当前目录,不显示任何信息。

+

jar xf Hello.jar

+

u

+

更新已存在的jar文件包,如添加文件到jar文件包中。

+

-

+

v

+

生成详细报告并打印到标准输出。

+

#把当前目录的hello.class文件打包到Hello.jar,并显示打包的过程。如果Hello.jar文件还不存在,就创建它,否则首先清空它。

+

jar cvf Hello.jar hello.class

+

f

+

指定jar文件名,通常这个参数是必须的。

+

-

+

m

+

指定需要包含的manifest清单文件。

+

-

+

0

+

只存储,不压缩,这样产生的jar文件包会比不用该参数产生的体积大,但速度更快。

+

-

+

M

+

不产生所有项的manifest清单文件,此参数会忽略m参数

+

#把当前目录的hello.class文件打包到Hello.jar,并显示打包的过程。如果Hello.jar文件还不存在,就创建它,否则首先清空它。但在创建Hello.jar时不产生manifest 文件。

+

jar cvfM Hello.jar hello.class

+

jarfile

+

.jar文件包,它是f参数的附属参数。

+

-

+

manifest

+

.mf的manifest清单文件,它是m参数的附属参数。

+

-

+

-C dir

+

转到指定dir下执行jar命令,只能配合参数c、t使用。

+

-

+

file

+

指定文件/路径列表,文件或路径下的所有文件(包括递归路径下的)都会被打入jar文件包中,或解压jar文件到路径下。

+

#把当前目录的所有class文件打包到Hello.jar,并显示打包的过程。如果Hello.jar文件还不存在,就创建它,否则首先清空它。

+

jar cvf Hello.jar *.class

+
+ +## 类库 + +java类库是以包的形式实现的,包是类和接口的集合。java编译器为每个类生成一个字节码文件,且文件名与类名相同,因此同名的类之间就有可能发生冲突。java语言中,把一组类和接口封装在一个包内,包可以有效地管理类名空间,位于不同包中的类即使同名也不会冲突,从而解决了同名类之间可能发生的冲突问题,为管理大量的类和接口提供了方便,也有利于类和接口的安全。 + +除java提供的许多包外,开发者也可以自定义包,把自己编写的类和接口等组成程序包的形式,以便后续使用。 + +自定义包需要先声明包,然后在使用包。 + +### 包的声明 + +包的声明格式为:package pkg1\[.pkg2\[.pkg3...\]\]; + +为了声明一个包,首先必须建立一个相应的目录结构,子目录与包名一致,然后在需要放入该包的类文件开头声明包,表示该文件的全部类都属于这个包。包声明中的“.”指明了目录的层次。如果源程序文件中没有package语句,则指定为无名包。无名包没有路径,一般情况下,java仍然会把源文件中的类存储在当前工作目录(即存放java源文件的目录)下。 + +包声明语句必须被加到源程序文件的起始部分,而且前面不能有注释和空格。如果在不同源程序文件中使用相同的包声明语句,就可以将不同源程序文件中的类都包含在相同的包中。 + +### 包的引用 + +在 Java 中,为了能使用java提供的包中的公用类,或者使用自定义的包中的类,有两种方法。 + +- 在要引用的类名前带上包名。 + + 如:name.A obj=new name.A \(\); + + 其中,name为包名,A为类名,obj为对象。表示程序中用name包中的A类定义一个对象obj。 + + 示例:新建一个example包中Test类的test对象。 + + ```shell + example.Test test = new example.Test(); + ``` + +- 在文件开头使用import来导入包中的类。 + + import语句的格式为:import pkg1\[.pkg2\[.pkg3...\]\].\(classname | \*\); + + 其中,pkg1\[.pkg2\[.pkg3...\]\]表明包的层次,classname为所要导入的类。如果要从一个包中导入多个类,则可以使用通配符“\*”来替代。 + + 示例:导入example包中的Test类。 + + ```java + import example.Test; + ``` + + 示例:将example 整个包导入。 + + ```java + import example.*; + ``` + +## 示例 + +### 编译不带包的java程序示例 + +1. cd到代码目录,此处以用户“~/code”进行举例。如下所示: + + ```shell + cd ~/code + ``` + +2. 编写Hello World程序,保存为HelloWorld.java,此处以编译Hello World程序进行举例说明。示例如下: + + ```shell + vi HelloWorld.java + ``` + + 代码内容示例: + + ```java + public class HelloWorld { + public static void main(String[] args) { + System.out.println("Hello World"); + } + } + ``` + +3. 在代码目录,执行编译,使用命令: + + ```shell + javac HelloWorld.java + ``` + + 编译执行未报错,表明执行通过。 + +4. 编译完成后,会生成 HelloWorld.class 文件,通过java命令可执行查看结果,示例如下: + + ```shell + # java HelloWorld + Hello World + ``` + +### 编译带包的java程序示例 + +1. cd到代码目录,此处以用户“~/code”进行举例。并在该目录下创建“~/code/Test/my/example”、“~/code/Hello/world/developers”、“~/code/Hi/openos/openeuler”子目录,分别用于存放源文件。 + + ```shell + cd ~/code + mkdir -p Test/my/example + mkdir -p Hello/world/developers + mkdir -p Hi/openos/openeuler + ``` + +2. cd到~/code/Test/my/example目录,创建Test.java。 + + ```shell + cd ~/code/Test/my/example + vi Test.java + ``` + + Test.java代码内容示例: + + ```java + package my.example; + import world.developers.Hello; + import openos.openeuler.Hi; + public class Test { + public static void main(String[] args) { + Hello me = new Hello(); + me.hello(); + Hi you = new Hi(); + you.hi(); + } + } + ``` + +3. cd到~/code/Hello/world/developers目录,创建Hello.java。 + + ```shell + cd ~/code/Hello/world/developers + vi Hello.java + ``` + + Hello.java代码内容示例: + + ```java + package world.developers; + public class Hello { + public void hello(){ + System.out.println("Hello, openEuler."); + } + } + ``` + +4. ~/code/Hi/openos/openeuler目录,创建Hi.java。 + + ```shell + cd ~/code/Hi/openos/openeuler + vi Hi.java + ``` + + Hi.java代码内容示例: + + ```java + package openos.openeuler; + public class Hi { + public void hi(){ + System.out.println("Hi, the global developers."); + } + } + ``` + +5. cd到~/code,使用javac编译源文件。 + + ```shell + cd ~/code + javac -classpath Hello:Hi Test/my/example/Test.java + ``` + + 执行完命令后,会在“~/code/Test/my/example”、“~/code/Hello/world/developers”、“~/code/Hi/openos/openeuler”目录下分别生成Test.class、Hello.class、Hi.class文件。 + +6. cd到~/code,使用java运行Test程序。 + + ```shell + cd ~/code + java -classpath Test:Hello:Hi my/example/Test + ``` + + 执行结果如下所示: + + ```text + Hello, openEuler. + Hi, the global developers. + ``` diff --git a/docs/en/25.03/Server/Development/ApplicationDev/using-make-for-compilation.md b/docs/en/25.03/Server/Development/ApplicationDev/using-make-for-compilation.md new file mode 100644 index 0000000000000000000000000000000000000000..0e1efbafa7f3ed1dfaba0b060da09964b1be0bd7 --- /dev/null +++ b/docs/en/25.03/Server/Development/ApplicationDev/using-make-for-compilation.md @@ -0,0 +1,373 @@ +# 使用make编译 + +本章介绍make编译的一些基本知识,并通过示例进行实际演示。更多的make选项请通过**man make**命令查询。 + + +- [使用make编译](#使用make编译) + - [简介](#简介) + - [基本规则](#基本规则) + - [文件类型](#文件类型) + - [make工作流程](#make工作流程) + - [make选项](#make选项) + - [Makefile](#makefile) + - [Makefile结构](#makefile结构) + - [Makefile主要内容](#makefile主要内容) + - [示例](#示例) + - [使用Makefile实现编译的示例](#使用makefile实现编译的示例) + + + +## 简介 + +GNU make实用程序(通常缩写为make)是一种用于控制从源文件生成可执行文件的工具。 make会自动确定复杂程序的哪些部分已更改并需要重新编译。 make使用称为Makefiles的配置文件来控制程序的构建方式。 + +## 基本规则 + +### 文件类型 + +makefile文件中可能用到的文件类型如[表1](#table634145764320)所示。 + +**表 1** 文件类型 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

扩展名(后缀)

+

说明

+

.c

+

C语言源代码文件。

+

.C,.cc或.cxx

+

C++源代码文件。

+

.m

+

Objective-C源代码文件。

+

.s

+

汇编语言源代码文件。

+

.i

+

已经预处理的C源代码文件。

+

.ii

+

已经预处理的C++源代码文件。

+

.S

+

已经预处理的汇编语言源代码文件。

+

.h

+

程序所包含的头文件。

+

.o

+

编译后的目标文件。

+

.so

+

动态链接库,它是一种特殊的目标文件。

+

.a

+

静态链接库。

+

.out

+

可执行文件,但可执行文件没有统一的后缀,系统从文件的属性来区分可执行文件和不可执行文件。如果没有给出可执行文件的名字,GCC将生成一个名为a.out的文件。

+
+ +### make工作流程 + +使用make由源代码文件生成可执行文件,需要经过如下步骤。 + +1. make命令会读入Makefile文件,包括当前目录下命名为"GNUmakefile" 、"makefile" 、"Makefile"的文件、被include的makefile文件、参数-f、\-\-file、\-\-makefile指定的规则文件。 +2. 初始化变量。 +3. 推导隐含规则,分析依赖关系,并创建依赖关系链。 +4. 根据依赖关系链,决定哪些目标需要重新生成。 +5. 执行生成命令,最终输出终极文件。 + +### make选项 + +make命令格式为:**make** \[_option_\]... \[_target_\]... + +其中: + +_option_ :参数选项。 + +_target_ :Makefile中指定的目标。 + +常用make的 _option_ 取值如[表2](#table261872312343)所示。 + +**表 2** 常用的make选项 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

options取值

+

说明

+

-C dir,--directory=dir

+

指定make在开始运行后的工作目录为dir

+

当存在多个 -C 选项的时候,make 的最终工作目录是第一个目录的相对路径。

+

-d

+

make在执行的过程中打印出所有的调试信息。使用-d选项可以显示make构造依赖关系链、重建目标过程中的所有信息。

+

-e,--environment-overrides

+

使用环境变量定义覆盖Makefile中的同名变量定义。

+

-f file,--file=file

+

--makefile=file

+

指定file文件为make 执行的Makefile文件。

+

-h,--help

+

打印帮助信息。

+

-i,--ignore-errors

+

执行过程中忽略规则命令执行的错误。

+

-k,--keep-going

+

执行命令错误时不终止make的执行,make 尽最大可能执行所有的命令,直至出现致命的错误才终止。

+

-n,--just-print,--dry-run

+

按实际运行时的执行顺序模拟执行命令(包括用@开头的命令),没有实际执行效果,仅仅用于显示执行过程。

+

-o file,--old-file=file,--assume-old=file

+

指定file文件不需要重建,即使它的依赖已经过期,同时不重建此依赖文件的任何目标。

+

-p,--print-data-base

+

命令执行之前,打印出make读取的Makefile的所有数据,同时打印出 make的版本信息。如果只需要打印这些数据信息,可以使用 “make -qp”命令,查看 make 执行之前预设的规则和变量,可使用命令“make -p -f /dev/null”。

+

-r,--no-builtin-rules

+

忽略内嵌的隐含规则的使用,同时忽略所有后缀规则的隐含后缀列表。

+

-R,--no-builtin-variables

+

忽略内嵌的隐含变量。

+

-s,--silent,--quiet

+

取消命令执行过程中的打印。

+

-S,--no-keep-going,--stop

+

取消 "-k" 的选项在递归的 make 过程中子 make 通过 "MAKEFLAGS" 变量继承了上层的命令行选项那个。我们可以在子 make 中使用“-S”选项取消上层传递的 "-k" 选项,或者取消系统环境变量 "MAKEFLAGS" 中 "-k"选项。

+

-t,--touch

+

更新所有的目标文件的时间戳到当前系统时间。防止 make 对所有过时目标文件的重建。

+

-v,--version

+

查看make的版本信息。

+
+ +## Makefile + +make是通过Makefile文件获取如何编译、链接和安装、清理的方法,从而实现将源代码文件生成可执行文件和其他相关文件的工具。因此,Makefile中描述了整个工程的编译和链接等规则,其中包含了哪些文件需要编译,哪些文件不需要编译,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重建等等。Makefile文件让工程编译实现了自动化,不需要每次都手动输入一堆源文件和参数。 + +本章简单介绍Makefile文件的结构和主要内容,更多Makefile的内容请通过**info make**命令查询 + +### Makefile结构 + +Makefile文件结构如下所示: + +_targets_:_prereguisites_ + +_command_ + +或者是: + +_targets_:_prerequisites_;_command_ + +_command_ + +其中: + +- _targets_ :目标,可以是目标文件、可执行文件或标签。 +- _prerequisites_ :依赖文件,生成targets需要的文件或者是目标。可以是多个,也可以没有。 +- _command_ :make需要执行的命令(任意的 shell 命令)。可以有多条命令,每一条命令占一行。 +- 目标和依赖文件之间要使用“:”分隔,命令的开始一定要按“Tab”。 + +Makefile文件结构表明了输出的目标,输出目标的依赖对象和生成目标需要执行的命令。 + +### Makefile主要内容 + +一个Makefile文件主要由以下内容组成。 + +- 显式规则 + + 明确写出来的依赖关系,如要生成的文件,文件的依赖文件,生成的命令。 + +- 隐含规则 + + 由make自动推导的规则,make命令支持自动推导功能。 + +- 变量的定义 +- 文件指示 + + 文件指示包括三部分: + + - include 其他 Makefile,如include xx.md。 + - 选择执行,如\#ifdef。 + - 定义多行命令,如define...endef。\(define ... endef\) + +- 注释 + + 以 “\#” 开头。 + +## 示例 + +### 使用Makefile实现编译的示例 + +1. cd到代码目录,此处以目录“~/code”进行举例。 + + ```shell + cd ~/code + ``` + +2. 创建1个头文件hello.h和2个函数hello.c、main.c。 + + ```c + vi hello.h + vi hello.c + vi main.c + ``` + + hello.h代码内容示例: + + ```c + #pragma once + #include + void hello(); + ``` + + hello.c代码内容示例: + + ```c + #include "hello.h" + void hello() + { + int i=1; + while(i<5) + { + printf("The %dth say hello.\n", i); + i++; + } + } + + ``` + + main.c代码内容示例: + + ```c + #include "hello.h" + #include + int main() + { + hello(); + return 0; + } + ``` + +3. 创建Makefile文件。 + + ```shell + vi Makefile + ``` + + Makefile文件内容示例: + + ```text + main:main.o hello.o + gcc -o main main.o hello.o + main.o:main.c + gcc -c main.c + hello.o:hello.c + gcc -c hello.c + clean: + rm -f hello.o main.o main + ``` + +4. 执行make命令。 + + ```shell + make + ``` + + 命令执行后,会打印Makefile中执行的命令。如果不需要打印该信息,可以在执行make命令时加上参数-s。 + + gcc -c main.c + + gcc -c hello.c + + gcc -o main main.o hello.o + +5. 执行./main目标。 + + ```shell + ./main + ``` + + 命令执行后,打印如下信息: + + The 1th say hello. + + The 2th say hello. + + The 3th say hello. + + The 4th say hello. diff --git a/docs/en/25.03/Server/Development/GCC/_menu.md b/docs/en/25.03/Server/Development/GCC/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..f6a1c5fdaa2285ed644e012ee9a973689a95fd2b --- /dev/null +++ b/docs/en/25.03/Server/Development/GCC/_menu.md @@ -0,0 +1,16 @@ +--- +label: 'GCC用户指南' +ismanual: 'Y' +description: 'GCC for openEuler 编译器基于开源 GCC 开发,聚焦于C、C++、Fortran语言的优化' +children: + - label: '内核反馈优化特性' + href: './kernel_FDO_user_guide.md' + - label: '链接时优化特性' + href: './link-time-optimization-user-guide.md' + - label: 'GCC基础性能优化特性' + href: './gcc-basic-performance-optimization-user-guide.md' + - label: 'GCC14副版本编译工具链' + href: './gcc14-sub-version-compilation-toolchain-user-guide.md' + - label: 'GCC插件框架特性' + href: './plugin-framework-user-guide.md' +--- diff --git a/docs/en/25.03/Server/Development/GCC/gcc-basic-performance-optimization-user-guide.md b/docs/en/25.03/Server/Development/GCC/gcc-basic-performance-optimization-user-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..9d6302c3a1ab6c7a54925a92352ac45ee3c8769e --- /dev/null +++ b/docs/en/25.03/Server/Development/GCC/gcc-basic-performance-optimization-user-guide.md @@ -0,0 +1,185 @@ +# GCC 基础性能优化用户指南 + +## 简介 + +编译器基础性能优化对于提高应用程序的开发效率、运行性能和可维护性都非常重要。它是计算机科学领域的一个重要研究方向,也是软件开发过程中的重要环节之一。GCC for openEuler 在通用编译优化能力的基础上,对中后端性能优化技术进行了增强,包括指令优化、向量化增强、预取增强、数据流分析增强等优化。 + +## 安装与部署 + +### 软件要求 + +操作系统:openEuler 24.09 + +### 硬件要求 + +aarch64 架构 + +### 安装软件 + +按需安装 GCC 和相关组件即可,以 GCC 为例。 + +```shell +yum install gcc +``` + +## 使用方法 + +### CRC优化 + +#### 说明 + +识别CRC软件循环代码,生成高效硬件指令。 + +#### 使用方法 + +在编译时增加 -floop-crc 选项。 + +注:`-floop-crc`选项需要和`-O3 -march=armv8.1-a`一起使用。 + +### If-conversion 增强 + +#### 说明 + +增强 If conversion 优化,使用更多的寄存器以减少冲突。 + +#### 使用方法 + +本优化是 RTL 优化 if-conversion 的一部分,使用如下编译选项控制优化启用。 + +`-fifcvt-allow-complicated-cmps` + +`--param=ifcvt-allow-register-renaming=[0,1,2]`数字用于控制优化范围。 + +注:此优化依赖`-O2`优化等级,以及与`--param=max-rtl-if-conversion-unpredictable-cost=48`、`--param=max-rtl-if-conversion-predictable-cost=48`共同使用。 + +### 乘法计算优化 + +#### 说明 + +Arm 相关指令合并优化,实现32位复杂组合的64位整形乘法逻辑的识别,并以高效的64位指令数输出。 + +#### 使用方法 + +使用`-fuaddsub-overflow-match-all`和`-fif-conversion-gimple`选项使能优化。 + +注:此优化需要`-O3`及以上优化等级。 + +### cmlt 指令生成优化 + +#### 说明 + +对一些四则运算生成`cmlt`指令,减少指令数。 + +#### 使用方法 + +使用选项`-mcmlt-arith`使能优化。 + +注:此优化需要`-O3`以上优化等级使用。 + +### 向量化优化增强 + +#### 说明 + +识别并简化向量化过程中生成的冗余指令,允许更短的循环进入向量化。 + +#### 使用方法 + +使用参数`--param=vect-alias-flexible-segment-len=1`使能,默认为0。 + +注:此优化需要`-O3`及以上优化等级。 + +### min max 和 uzp1/uzp2 指令联合优化 + +#### 说明 + +识别 min max 和 uzp1/uzp2 指令联合优化机会,减少指令数从而提升性能。 + +#### 使用方法 + +使用`-fconvert-minmax`选项使能`min max`优化,`uzp1/uzp2`指令优化在`-O3`以上等级默认使能。 + +注:依赖`-O3`及以上优化等级。 + +### ldp/stp 优化 + +#### 说明 + +识别某些性能表现差的 ldp/stp,将其拆分成2个 ldr 和 str。 + +#### 使用方法 + +使用`-fsplit-ldp-stp`选项使能优化,使用参数`--param=param-ldp-dependency-search-range=[1,32]`控制搜索范围,默认16。 + +注:依赖`-O1`及以上优化等级。 + +### AES指令优化 + +#### 说明 + +识别 AES 软件算法指令序列,使用硬件指令加速。 + +#### 使用方法 + +使用`-fcrypto-accel-aes`选项使能优化。 + +注:依赖`-O3`及以上优化等级。 + +### 间接调用提升 + +#### 说明 + +识别和分析程序中的间接调用,尝试将其优化为直接调用。 + +#### 使用方法 + +使用选项`-ficp -ficp-speculatively`使能优化。 + +注:此优化需要和-O2 -flto -flto-partition=one共同使用。 + +### IPA-prefetch + +#### 说明 + +识别循环中的间接访存,插入预取指令,从而减少间接访存的延迟。 + +#### 使用方法 + +通过选项`-fipa-prefetch -fipa-ic`使能优化。 + +注:此优化需要和-O3 -flto共同使用。 + +### -fipa-struct-reorg + +#### 说明 + +内存空间布局优化,将结构体成员在内存中的排布进行新的排列组合,来提高cache的命中率。 + +#### 使用方法 + +在选项中加入`-O3 -flto -flto-partition=one -fipa-struct-reorg`即可。 + +注:-fipa-struct-reorg选项,需要在-O3 -flto -flto-partition=one全局同时开启的基础上才使能。 + +### -fipa-reorder-fields + +#### 说明 + +内存空间布局优化,根据结构体中成员的占用空间大小,将成员从大到小排列,以减少边界对齐引入的padding,来减少结构体整体占用的内存大小,以提高cache的命中率。 + +#### 使用方法 + +在选项中加入`-O3 -flto -flto-partition=one -fipa-reorder-fields`即可。 + +注:-fipa-reorder-fields选项,需要在-O3 -flto -flto-partition=one全局同时开启的基础上才使能。 + +### -ftree-slp-transpose-vectorize + +#### 说明 + +该选项在循环拆分阶段,增强对存在连续访存读的循环的数据流分析能力,通过插入临时数组拆分循环;SLP矢量化阶段,新增对grouped_stores进行转置的SLP分析。 + +#### 使用方法 + +在选项中加入`-O3 -ftree-slp-transpose-vectorize`即可。 + +注:-ftree-slp-transpose-vectorize选项,需要在-O3开启的基础上才使能。 diff --git a/docs/en/25.03/Server/Development/GCC/gcc14-sub-version-compilation-toolchain-user-guide.md b/docs/en/25.03/Server/Development/GCC/gcc14-sub-version-compilation-toolchain-user-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..1c1bdf80e88d8256af53ab9f0a2071be59c2991d --- /dev/null +++ b/docs/en/25.03/Server/Development/GCC/gcc14-sub-version-compilation-toolchain-user-guide.md @@ -0,0 +1,144 @@ +# 背景介绍 + +## 简介 + +为确保操作系统的稳健性,基础软件的选型策略通常倾向于采用经过时间验证、相对稳定的版本,而非最新发布版本。这一策略旨在避免版本更迭带来的潜在不稳定因素,确保在整个长期支持(LTS)周期内,系统版本保持相对稳定。因此,当前 openEuler 在 24.03 LTS 版本整个生命周期都是选择使用 GCC 12.3.1 作为基线进行开发。 + +这样的选择会带来如下问题。首先,许多的硬件特性需要基础 GCC 工具链的支持,选择非最新版本的 GCC 会导致新特性无法及时在新发布的操作系统上使能。另外,某些用户倾向使用最新版本的编译器使能最新特性,这些特性相较于低版本编译器会带来部分性能提升。 + +因此,为了使能多样算例新特性,满足不同用户对不同硬件特性支持的需求,在 openEuler 24.09 版本推出 openEuler GCC Toolset 工具链,这是一个专为 openEuler 系统设计的 GCC 多版本编译工具链,该工具链提供一个高于系统主 GCC 版本的副版本 GCC 编译工具链,为用户提供了更加灵活且高效的编译环境选择。通过使用 openEuler GCC Toolset 14 多版本编译工具链,用户可以轻松地在不同版本的 GCC 之间进行切换,以便充分利用新硬件特性,同时享受到 GCC 最新优化所带来的性能提升。 + +## 方案设计 + +### 编译工具链功能介绍 + +GCC 编译工具链是一套由 GNU 开发和维护的开源编译器集合,它是用于将高级语言代码转换为机器语言的工具集,GCC 编译工具链不仅包括GCC编译器本身,还包含一系列辅助工具和库,这些组件共同构成了一个完整的编译环境。 + +1. GCC 编译器(gcc/g++/gfrotran 等): + + * 作用:GCC 编译器是工具链的核心,负责完成预处理和编译过程,将源代码转换成汇编代码或中间表示。对于 C++ 代码,g++ 是 GCC 的 C++ 编译器前端,除了完成编译工作外,还会自动链接 C++ 标准库。 + +2. Binutils 工具集: + + * 包含工具:链接器(ld)、汇编器(as)、目标文件格式查看器(readelf)、符号查看器(nm)、目标文件格式转换工具(objcopy)、反汇编工具(objdump)、尺寸查看工具(size)等。 + * 作用:这些工具在编译过程中起辅助作用,如将汇编代码转换成机器码(汇编器)、将多个目标文件链接成可执行文件(链接器)、查看目标文件或可执行文件的信息(readelf、nm、objdump)等。 + +3. glibc 库: + + * 作用: glibc 是 GNU C Library 的缩写,是 GNU 组织为 GNU 系统以及 Linux 系统编写的 C 语言标准库。它包含了 C 语言中常用的标准函数,如 printf、malloc 等,是编译 C 语言程序时必不可少的部分。 + +4. 其他辅助工具: + + * 调试器(gdb):用于调试可执行文件,帮助开发者定位和解决程序中的错误。 + * 性能分析工具(gprof):用于分析程序的性能,帮助开发者优化代码。 + +### 工具链选型 + +在编译过程中,工具链中的软件组件对编译结果具有直接影响。具体而言,GCC、binutils 以及 glibc是其核心要素。glibc 作为 C 语言标准库,其选型通常与操作系统内核版本紧密绑定,不轻易进行更改。本工具链仅包含 GCC 和 binutils 两款软件来满足副版本编译需求。 + +当前最新的 GCC release 版本为 gcc-14.2.0,因此 openEuler GCC Toolset 工具链选型 的 GCC 的版本为gcc-14.2.0 。 + +至于 binutils,openEuler 24.09 的默认 binutils 为 2.41 版本,而最新的 GCC-14 官方推荐搭配 binutils-2.42 使用,因此本工具链的 binutils 的版本选择 binutils-2.42 。 + +基于此考量,openEuler GCC Toolset 副版本工具链引入 gcc-14.2.0 和 binutils-2.42,此举旨在确保编译环境的稳定性和效率,同时避免不必要的复杂性,力求在保障编译结果质量的同时,优化用户的使用体验。后期待 gcc-14.3.0 在上游社区 release 后,同步更新此工具链 GCC 版本。 + +### 架构设计 + +为区分于默认工具链安装,并防止 openEuler GCC Toolset 副版本编译工具链安装与默认编译工具链安装之间的依赖库冲突,将此工具链命名为 gcc-toolset-14 ,其软件包名均以前缀`gcc-toolset-14-`开头,后接原有工具链软件包名。同时,考虑到默认编译工具链安装路径为`/usr`,为避免路径重叠,特将 gcc-toolset-14 安装路径设定为`/opt/openEuler/gcc-toolset-14/`。为了与开源 GCC 做出区分,也便于后期合入更多 openEuler 社区特性,gcc-toolset-14-gcc 的版本设置为 14.2.1 。 + +副版本编译工具链 gcc-toolset-14 提供的应用程序和库不会取代系统默认GCC版本,其包含的应用程序和库旨在与系统默认编译工具链版本并存,而非取代或覆盖它们,亦不会自动设为默认或首选选项。此外,为了实现低成本切换编译工具链版本,便于版本切换与管理,本方案引入 scl-utils 版本切换工具,具体使用和切换方式见下文。 + +## 安装与部署 + +### 软件要求 + +* 操作系统:openEuler 24.09 + +### 硬件要求 + +* Aarch64 / X86_64 + +### 安装方式 + +默认 GCC 编译器 gcc-12.3.1,安装路径为 /usr : + +```shell +yum install -y gcc gcc-c++ +``` + +副版本编译工具链 gcc-toolset-14 安装路径为 /opt/openEuler/gcc-toolset-14/root/usr/ : + +```shell +yum install -y gcc-toolset-14-gcc* +yum install -y gcc-toolset-14-binutils* +``` + +## 使用方式 + +本方案引入 SCL(Software Collections)工具进行不同版本编译工具链的管理。 + +## scl工具 + +SCL(Software Collections)是 Linux 系统中一个非常重要的工具,它为用户提供了一种方便、安全的安装和使用应用程序及运行时环境多个版本的方式,同时避免了系统混乱。 + +SCL 的主要用途包括: + +1. 多版本共存:允许用户在同一系统上安装和使用多个版本的软件库、工具和语言运行环境,从而满足不同应用和开发需求。 +2. 避免系统冲突:通过隔离不同版本的软件,避免了新版本软件与系统原有版本之间的冲突。 +3. 提升开发效率:对于开发人员来说,SCL 提供了最新的开发工具链和运行时环境,从而提升了开发效率。 + +### 版本切换方式 + +**安装 SCL:** + +```shell +yum install scl-utils scl-utils-build +``` + +**注册 gcc-toolset-14:** + +```shell +## 注册 gcc-toolset-14 +scl register /opt/openEuler/gcc-toolset-14/ + +## 取消注册 gcc-toolset-14 +scl deregister gcc-toolset-14 +``` + +使用 `scl list-collections` 显示 gcc-toolset-14 已经在 scl 中注册成功; + +**切换 gcc-toolset-14:** + +```shell +scl enable gcc-toolset-14 bash +``` + +此命令会启动一个新的 bash shell 会话,使用 gcc-toolset-14 内的工具版本,而不是系统默认版本。在新的 bash shell 会话中,无需再显式切换编译器版本和路径。 +如果需要退出 gcc-toolset-14 的编译环境,输入 `exit` 退出 bash shell 会话,此时编译工具链的版本切换成系统默认版本。 + +SCL工具的本质就是自动设置不同工具版本的环境变量,具体可以参考 `/opt/openEuler/gcc-toolset-14/enable` 文档,gcc-toolset-14 的环境变量均在该文件中设置。若用户系统没有 SCL 工具,则可以使用以下方式进行工具链版本切换: + +```shell +## 方案一:无 SCL 工具,使用脚本切换编译工具链 +source /opt/openEuler/gcc-toolset-14/enable + +## 方案二:有 SCL 工具,使用 SCL 工具切换编译工具链并激活运行环境 +scl enable gcc-toolset-14 bash +``` + +## 使用约束 + +### 编译场景 + +主版本场景:正常编译使用系统默认的 gcc-12.3.1 进行构建; + +副版本场景:需要使用 GCC-14 高版本特性构建相关应用,使用 SCL 工具将 bash 环境切换为 gcc-toolset-14 编译工具链的编译环境。 + +### 副版本GCC-14使用说明 + +1. openEuler GCC Toolset 14 副版本编译工具链提供如下两种使用方式: + + 1)动态链接:默认场景下会自动添加选项 -lstdc++ 进行动态链接,此时会链接系统库动态库 /usr/lib64/libstdc++.so.6 和 GCC-14 副版本提供的 libstdc++_nonshared.a 静态库,此静态库是 GCC-14 相比于 GCC-12 新增的稳定 C++ 特性; + 2)静态链接:用户使用选项 -static 进行静态链接,此时会链接 GCC-14 副版本提供的 libstdc++.a 全量特性静态库,该静态库路径为 `/opt/openEuler/gcc-toolset-14/root/usr/lib/gcc/aarch64-openEuler-linux/14/libstdc++.a`。 + +2. 用户默认构建使用动态链接,会链接新增的 libstdc++_nonshared.a 静态库,该库为了保持和系统兼容性,仅对 C++ 中正式标准特性进行封装。对于 -fmodules-ts , -fmodule-header 等选项,属于 C++20 的模块特性,而该特性在 C++20 中仍属于实验性质,并未封装在 libstdc++_nonshared.a 中,若用户需要使用此类新增特性,建议直接使用静态链接的方式全量链接 GCC-14 副版本的静态库。 diff --git a/docs/en/25.03/Server/Development/GCC/kernel_FDO_user_guide.md b/docs/en/25.03/Server/Development/GCC/kernel_FDO_user_guide.md new file mode 100644 index 0000000000000000000000000000000000000000..439dfc86813a151ede9f637cc6d66e26d6e7e937 --- /dev/null +++ b/docs/en/25.03/Server/Development/GCC/kernel_FDO_user_guide.md @@ -0,0 +1,68 @@ +# 内核反馈优化特性用户指南 + +## 简介 + +内核反馈优化(PGO kernel)特性为内核提供了反馈优化能力的支持,使用户可以为不同的应用程序构建针对性优化的内核,在单应用场景下提高目标应用的性能。同时,该特性一并在openEuler GCC内提供了相应的编译支持,以及在A-FOT中提供了自动优化的功能,使用户能够便捷地使能内核反馈优化特性。 + +## 安装与部署 + +### 软件要求 + +* 操作系统:openEuler 23.09 + +### 硬件要求 + +* aarch64架构 +* x86_64架构 + +### 安装软件 + +安装内核源码、A-FOT和其他依赖软件包 + +```shell +yum install -y kernel-source A-FOT make gcc flex bison elfutils-libelf-devel diffutils openssl-devel dwarves +``` + +复制内核源码 + +```shell +cp -r /usr/src/linux-6.4.0-8.0.0.16.oe2309.aarch64 . +``` + +**注意:具体的版本号可能会有变化。** + +## 使用方法 + +用户可以通过A-FOT工具使能内核反馈优化,一键得到优化内核。将opt_mode指定Auto_kernel_PGO则为PGO kernel模式。所有配置选项也可以通过命令行指定,例如./a-fot --pgo_phase 1,另外-s、-n选项只能在命令行指定。PGO kernel相关的选项说明如下表所示。 + +| 序号 | 选项名称(配置文件) | 选项说明 | 默认值 | +| ---- | -------------------- | ------------------------------------------------------------ | ------------------------ | +| 1 | config_file | 配置文件路径;根据此文件内容读取用户的选项配置。 | ${afot_path}/a-fot.ini | +| 2 | opt_mode | 优化模式;工具将执行的优化模式,必须为AutoFDO、AutoPrefetch、AutoBOLT、Auto_kernel_PGO四者之一;分别代表自动反馈优化、自动预取、自动二进制优化和自动内核反馈优化。 | AutoPrefetch | +| 3 | pgo_mode | PGO模式;内核的反馈优化模式,GCOV或完整的PGO*,必须为arc或all;分别代表仅使用arc profile和使用arc+value profile。 | all | +| 4 | pgo_phase | 内核反馈优化的执行阶段;工具根据阶段执行不同的操作,必须为1或2;1代表编译插桩内核的阶段,2代表收集数据、编译优化内核的阶段。 | 1 | +| 5 | kernel_src | 内核源码目录;指定则工具进入编译内核,否则工具自动下载源码。 | 无(可选) | +| 6 | kernel_name | 内核构建的本地名;工具将根据阶段添加"-pgoing"或"-pgoed"后缀。 | kernel | +| 7 | work_path | 脚本工作目录;此目录用于存放日志文件、wrapper和profile。 | /opt(不能在/tmp目录下) | +| 8 | run_script | 应用执行脚本路径;此脚本为目标应用的执行脚本,需要用户完成编写;工具将后台运行此脚本以执行目标应用。 | /root/run.sh | +| 9 | gcc_path | GCC路径;工具调用真正编译器GCC的路径。 | /usr | +| 10 | -s | 安静模式;工具自动重启系统切换内核、执行第二阶段。 | 无 | +| 11 | -n | 不要让工具来编译内核;适用于执行环境和内核编译环境分离的场景。 | 无 | + +配置完编译选项后,可以使用如下命令进行A-FOT自动化优化内核: + +```shell +a-fot --config_file ./a-fot.ini -s +``` + +**注意:-s选项会让A-FOT工具自动重启机器切换内核,如果用户不希望自动进行这一项敏感操作,请去掉这一选项。但用户需要在重启后手动执行第二阶段(--pgo_phase 2)。** + +**注意:所有路径名请使用绝对路径。** + +**注意*:openEuler 23.09版本的内核暂不支持完整的PGO,请修改pgo_mode值为arc。** + +## 兼容性说明 + +此节主要列出当前一些特殊场景下的兼容性问题。本项目持续迭代中,会尽快进行修复,也欢迎广大开发者加入。 + +* openEuler 23.09版本的内核暂不支持完整的PGO,目前只支持arc模式。 diff --git a/docs/en/25.03/Server/Development/GCC/link-time-optimization-user-guide.md b/docs/en/25.03/Server/Development/GCC/link-time-optimization-user-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..85b4760405a946e2d220c9601816208bec6201d6 --- /dev/null +++ b/docs/en/25.03/Server/Development/GCC/link-time-optimization-user-guide.md @@ -0,0 +1,25 @@ +# 链接时优化简介 + +在传统编译流程中,gcc 将单个源文件(称谓一个编译单元)直接进行编译优化生成包含汇编代码的`.o`目标对象文件,并由链接器对这些`.o`文件进行符号表解析与重定位,链接成可执行文件。在这个过程中,拥有跨文件函数调用信息的链接器由于操作的是汇编代码,难以进行编译优化,而可以执行编译优化的环节,却没有跨文件的全局信息。这样的编译框架,虽然提高了编译效率,每次重新编译只需要编译修改过的少量编译单元,但也丢失了许多跨文件的优化机会。 + +链接时优化(LTO), 设计的初衷就是希望能够在链接时,拥有跨编译单元的调用信息的时候,进行编译优化,提供更多的优化机会。为了达到这个目的,LTO 需要将编译优化所需的 IR 信息保留到链接时。在链接时,链接器会调用 LTO 插件,执行全程序分析,生成更加有效的优化决策,再经由编译优化生成更高效的IR,进一步转成包含汇编代码的目标对象文件,最后由链接器完成常规的链接工作。 + +# 版本构建使能 + +## 背景 + +为了获得更优的性能与更小的二进制体积,许多海外社区已经在版本构建中使用了链接时优化,链接时优化也正在成为各方寻找编译优化机会的新战场。openEuler 计划从 24.09 创新版本开始,在版本构建中引入 LTO。 + +## 方案 + +我们将在 openEuler-rpm-config 的 macro 中所包含的全局编译选项中插入 `-flto -ffat-lto-objects` ,以达到在构建软件包是使能 lto 的效果。其中 `-flto` 用以使能链接时优化,而 `-ffat-lto-objects` 用以生成同时包含 LTO 对象信息和常规链接所需的汇编信息的胖目标对象。在当前构建中,LTO 对象信息会参与 LTO 优化,而由于 LTO 目标对象文件在不同版本的 gcc 之间是不通用的,因此在打包生成对应的 `.rpm` 包之前,我们会将 `.o/.a` 文件中的 LTO 相关字段给消除,仅保留常规链接所需的汇编代码信息,不对静态库本身产生影响。 + +## 使能范围 + +由于 LTO 的编译流程与常规的编译流程相差较大,影响较广,为了控制 LTO 对版本质量的冲击,我们当前仅对 500+ 个软件包使能了 lto,你可以在 `/usr/lib/rpm/%{_vendor}/lto_white_list` 中找到这些软件包的清单。这些白名单应用在使能了 LTO 之后构建成功,并通过了自带的测试套。lto 编译选项仅在构建白名单应用时被设置为 `-flto -ffat-lto-objects`,否则置为空。 + +我们会在后续的创新版本上,联合应用维护者,扩大 LTO 使能的范围。 + +## 注意事项 + +当前热补丁机制与 LTO 仍存在不兼容,热补丁在 LTO 开启时会失效。我们已与热补丁团队就解决方式达成一致,会在后续版本中解决该问题。 diff --git a/docs/en/25.03/Server/Development/GCC/overview.md b/docs/en/25.03/Server/Development/GCC/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..84a82e187149c7b4ea3b45529e1b4b25fdfbe9a8 --- /dev/null +++ b/docs/en/25.03/Server/Development/GCC/overview.md @@ -0,0 +1,3 @@ +# GCC for openEuler用户指南 + +GCC for openEuler编译器基于开源GCC(GNU Compiler Collection,GNU编译器套装)开发。开源GCC是一种支持多种编程语言的跨平台开源编译器,采用GPLv3(GNU General Public License, version 3)协议,是Linux系统上目前应用最广泛的C/C++编译器,基本被认为是跨平台编译器的事实标准。而GCC for openEuler在继承了开源GCC能力的基础上,聚焦于C、C++、Fortran语言的优化,增强自动反馈优化、软硬件协同、内存优化、自动向量化等特性,并适配国产硬件平台,如鲲鹏、飞腾、龙芯等,充分释放国产硬件算力。 diff --git a/docs/en/25.03/Server/Development/GCC/plugin-framework-user-guide.md b/docs/en/25.03/Server/Development/GCC/plugin-framework-user-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..1230609cec29a51c8d01e359a19ede260f9abec6 --- /dev/null +++ b/docs/en/25.03/Server/Development/GCC/plugin-framework-user-guide.md @@ -0,0 +1,134 @@ +# 安装与部署 + +## 软件要求 + +* 操作系统:openEuler 23.03 + +## 硬件要求 + +* x86_64架构 +* ARM架构 + +## 环境准备 + +* 安装openEuler系统,安装方法参考 《[安装指南](../../InstallationUpgrade/Installation/installation.md)》。 + +### 安装依赖软件 + +#### 安装插件框架GCC客户端依赖软件 + +```shell +yum install -y grpc +yum install -y grpc-devel +yum install -y grpc-plugins +yum install -y protobuf-devel +yum install -y jsoncpp +yum install -y jsoncpp-devel +yum install -y gcc-plugin-devel +yum install -y llvm-mlir +yum install -y llvm-mlir-devel +yum install -y llvm-devel +``` + +#### 安装插件框架服务端依赖软件 + +```shell +yum install -y grpc +yum install -y grpc-devel +yum install -y grpc-plugins +yum install -y protobuf-devel +yum install -y jsoncpp +yum install -y jsoncpp-devel +yum install -y llvm-mlir +yum install -y llvm-mlir-devel +yum install -y llvm-devel +``` + +## 安装Pin + +### rpm构建 + +#### 构建插件框架GCC客户端 + +```shell +git clone https://gitee.com/src-openeuler/pin-gcc-client.git +cd pin-gcc-client +mkdir -p ~/rpmbuild/SOURCES +cp *.path pin-gcc-client.tar.gz ~/rpmbuild/SOURCES +rpmbuild -ba pin-gcc-client.spec +cd ~/rpmbuild/RPMS +rpm -ivh pin-gcc-client.rpm +``` + +#### 构建插件框架服务端 + +```shell +git clone https://gitee.com/src-openeuler/pin-server.git +cd pin-server +mkdir -p ~/rpmbuild/SOURCES +cp *.path pin-server.tar.gz ~/rpmbuild/SOURCES +rpmbuild -ba pin-server.spec +cd ~/rpmbuild/RPMS +rpm -ivh pin-server.rpm +``` + +### 编译构建 + +#### 构建插件框架GCC客户端 + +```shell +git clone https://gitee.com/openeuler/pin-gcc-client.git +cd pin-gcc-client +mkdir build +cd build +cmake ../ -DMLIR_DIR=${MLIR_PATH} -DLLVM_DIR=${LLVM_PATH} +make +``` + +#### 构建插件框架服务端 + +```shell +git clone https://gitee.com/openeuler/pin-server.git +cd pin-server +mkdir build +cd build +cmake ../ -DMLIR_DIR=${MLIR_PATH} -DLLVM_DIR=${LLVM_PATH} +make +``` + +# 使用方法 + +用户可以通过`-fplugin`和`-fplugin-arg-libpin_xxx`使能插件工具。 +命令如下: + +```shell +$(TARGET): $(OBJS) + $(CXX) -fplugin=${CLIENT_PATH}/build/libpin_gcc_client.so \ + -fplugin-arg-libpin_gcc_client-server_path=${SERVER_PATH}/build/pin_server \ + -fplugin-arg-libpin_gcc_client-log_level="1" \ + -fplugin-arg-libpin_gcc_client-arg1="xxx" +``` + +为了方便用户使用,可以通过`${INSTALL_PATH}/bin/pin-gcc-client.json`文件,进行插件配置。配置选项如下: + +`path` : 配置插件框架服务端可执行文件路径 + +`sha256file` : 配置插件工具的校验文件`xxx.sha256`路径 + +`timeout` : 配置跨进程通信超时时间,单位`ms` + +编译选项: + +`-fplugin`:指定插件客户端.so所在路径 + +`-fplugin-arg-libpin_gcc_client-server_path`:指定插件服务端可执行程序所在路径 + +`-fplugin-arg-libpin_gcc_client-log_level`:指定日志系统默认记录等级,取值`0~3`。默认为`1` + +`-fplugin-arg-libpin_gcc_client-argN`:用户可以根据插件工具要求,指定其他参数。argN代指插件工具要求的参数字段。 + +# 兼容性说明 + +此节主要列出当前一些特殊场景下的兼容性问题。本项目持续迭代中,会尽快进行修复,也欢迎广大开发者加入。 + +* 插件框架在`-flto`阶段使能时,不支持使用`make -j`多进程编译。建议改用`make -j1`进行编译。 diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/_menu.md b/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..8ebe0c614e14fc0e12e832d75768b15c36397801 --- /dev/null +++ b/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/_menu.md @@ -0,0 +1,12 @@ +--- +label: 'DPU-OS' +ismanual: 'Y' +description: '介绍基于openEuler操作系统裁剪构建DPU-OS镜像的方法以及部署验证方法' +children: + - label: 'DPU-OS背景与需求' + href: './dpu-os-background-and-requirements.md' + - label: 'DPU-OS裁剪指导' + href: './dpu-os-tailoring-guide.md' + - label: '验证与部署' + href: './verification-and-deployment.md' +--- diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/dpu-os-background-and-requirements.md b/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/dpu-os-background-and-requirements.md new file mode 100644 index 0000000000000000000000000000000000000000..b310da809defb43e6d59dde99e5e2a679b492c4c --- /dev/null +++ b/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/dpu-os-background-and-requirements.md @@ -0,0 +1,67 @@ +# DPU-OS背景与需求 + +## 概述 + +在数据中心及云场景下,摩尔定律失效,通用处理单元CPU算力增长速率放缓,而网络IO类速率及性能不断攀升,二者增长速率差异形成剪刀差,即当前通用处理器的处理能力无法跟上网络、磁盘等IO处理的需求。传统数据中心下越来越多的通用CPU算力被IO及管理面等处理占用,这部分资源损耗称之为数据中心税(Datacenter Tax)。据AWS统计,数据中心税可能占据数据中心算力的30%以上,部分场景下甚至可能更多。 + +DPU (Data Processing Unit) 的出现就是为了将这部分算力资源从主机CPU上解放出来,通过将管理面、网络、存储、安全等能力卸载到专有的处理器芯片上进行处理加速,达成降本增效的结果。目前主流云厂商如AWS、阿里云、华为云都通过自研芯片完成管理面及相关数据面的卸载,实现数据中心计算资源100%售卖给客户。 + +目前DPU发展非常火热,云厂商及大数据在相关场景下对DPU存在较强烈的需求,国内也有很多DPU初创公司推出不同的DPU产品。在这一背景下,云和大数据等厂商需要考虑如何整合使用不同DPU产品,而DPU厂商也面临对不同客户交付时设备驱动适配客户指定操作系统的问题。openEuler作为国内领先的开源开放操作系统,通过基于openEuler构建的DPU-OS,解决DPU厂商及客户之间的适配问题。另外DPU上OS用于承载部分业务加速的需求,需要对DPU-OS进行性能优化加速,可以基于openEuler构建DPU相关加速能力,内置在DPU-OS中,构建DPU相关软件生态。 + +## DPU-OS需求分析及设计 + +### DPU现状及对OS需求 + +DPU普遍具有以下特点和问题: + +* DPU通用处理能力资源受限 + + 当前DPU仍处在发展早期阶段,硬件上仍在不断演进,而且由于DPU供电限制,当前硬件规格普遍较低。主流DPU中通用处理器CPU核数普遍较少,约8-24CPU,且单核处理能力较弱。内存大小受限,普遍在16-32GB。DPU本地存储空间为几十到几百GB不等。运行于DPU之上的操作系统也需要考虑这些限制。 + +* DPU-OS安装方式多样 + + 当前DPU厂商及产品多种多样,对应操作系统的安装部署方式也不尽相同,包括PXE网络安装、U盘安装或其他自定义安装方式(由HOST下发安装镜像)。 + +* DPU性能需求 + + DPU的应用场景决定其对性能有强烈需求,相比于通用服务器操作系统,DPU-OS可能对内核特性或功能组件有特殊要求,比如用于设备直通热迁移的vDPA特性、厂商特定驱动适配支持、DPU进程的无感卸载特性、定制优化的用户态数据面加速工具如DPDK/SPDK/OVS、DPU管理监控相关的工具类组件。 + +针对以上DPU现状,提出对DPU-OS的需求如下: + +* 极致轻量的DPU-OS安装包 + + 通过裁剪openEuler系统镜像,减少非必要安装包的空间占用;通过优化系统服务,减少资源底噪开销。 + +* 裁剪配置及工具支持 + + 提供裁剪配置及裁剪工具支持,客户或DPU厂商可根据各自需求进行定制;openEuler提供ISO参考实现。 + +* 定制化内核及系统,提供极致性能 + + 通过定制内核及相关驱动,提供DPU竞争力内核特性;定制化加速类组件,使能DPU硬件加速能力;优化系统配置提供更优性能;通过DPU相关管理控制工具,方便用户统一管理。 + +### DPU-OS设计 + +**图1**DPU-OS整体设计 + +![dpuos-arch](./figures/dpuos-arch.png) + +如图1所示,DPU-OS分为五层设计: + +* 内核层:通过定制内核config,裁剪非必需内核特性及模块,达成内核轻量级效果;使能特定内核特性提供高性能DPU内核能力。 + +* 驱动层:对openEuler原生驱动进行裁剪定制,选择最小集合;DPU厂商相关底层驱动集成,原生支持部分DPU硬件产品。 + +* 系统配置层:通过对系统sysctl、proc进行配置,为DPU相关业务提供最优性能。 + +* 外围包层:对openEuler外围包进行裁剪定制,选择最小集合;提供DPU相关的定制工具集合。 + +* 系统服务层:通过优化系统原生服务启动项,减少非必要系统服务运行,保证系统运行时底噪最小化。 + +通过上述五层设计达成轻量化、极致性能DPU-OS的目标。该方案为相对长期设计,且对DPU相关软硬件生态有较强的依赖;当前第一阶段先实现基于openEuler imageTailor进行裁剪。 + +DPU-OS的裁剪步骤可参考[DPU-OS裁剪指导文档](./dpu-os-tailoring-guide.md),验证与部署可参考[DPU-OS部署验证指导文档](./verification-and-deployment.md)。 + +> ![](./public_sys-resources/icon-note.gif)**说明**: +> +> 当前阶段DPU-OS先基于openEuler现有内核及外围包,使用镜像裁剪工具imageTailor进行裁剪,提供轻量化OS安装镜像。后续可根据实际诉求,进行相关内核及外围包特性的开发及集成。 diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/dpu-os-tailoring-guide.md b/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/dpu-os-tailoring-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..9f34d577dd9828fd9d226d1f6bf04201835c2c34 --- /dev/null +++ b/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/dpu-os-tailoring-guide.md @@ -0,0 +1,65 @@ +# DPU-OS裁剪指导 + +本文档主要介绍`imageTailor`的使用方法并结合[dpu-utilities仓库](https://gitee.com/openeuler/dpu-utilities/tree/master/dpuos)的`dpuos`配置文件裁剪得到`dpuos`的安装镜像,具体步骤如下: + +## 准备imageTailor和所需的rpm包 + +参照[imageTailor使用指导文档](https://docs.openeuler.org/zh/docs/22.03_LTS/docs/TailorCustom/imageTailor%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97.html)安装好`imageTailor`工具并将裁剪所要用到的rpm包准备好。 + +可以使用openEuler提供安装镜像作为镜像裁剪所需要rpm包源,`openEuler-22.03-LTS-everything-debug-aarch64-dvd.iso`中的rpm比较全但是此镜像很大,可以用镜像`openEuler-22.03-LTS-aarch64-dvd.iso`中的rpm包和一个`install-scripts.noarch`实现。 + +`install-scripts.noarch`包括可以从everything包中获取,或者在系统中通过yum下载: + +```bash +yum install -y --downloadonly --downloaddir=./ install-scripts +``` + +## 拷贝dpuos相关的配置文件 + +`imageTailor`工具默认安装在`/opt/imageTailor`路径下。执行下面的命令将`dpuos`的配置拷贝到对应的路径下,拷贝时选择对应架构目录。当前DPU-OS裁剪配置库支持x86_64和aarch64两种架构。 + +```bash +cp -rf custom/cfg_dpuos /opt/imageTailor/custom +cp -rf kiwi/minios/cfg_dpuos /opt/imageTailor/kiwi/minios/cfg_dpuos +``` + +## 修改其他配置文件 + +* 修改`kiwi/eulerkiwi/product.conf`,增加一行`dpuos`相关配置: + +```bash +dpuos PANGEA EMBEDDED DISK GRUB2 install_mode=install install_media=CD install_repo=CD selinux=0 +``` + +* 修改`kiwi/eulerkiwi/minios.conf`,增加一行`dpuos`的相关配置: + +```bash +dpuos kiwi/minios/cfg_dpuos yes +``` + +* 修改`repos/RepositoryRule.conf`,增加一行`dpuos`的相关配置: + +```bash +dpuos 1 rpm-dir euler_base +``` + +## 设置密码 + +进入到`/opt/imageTailor`子目录下,修改下面3个文件的密码: + +* `custom/cfg_dpuos/usr_file/etc/default/grub` + +* `custom/cfg_dpuos/rpm.conf` + +* `kiwi/minios/cfg_dpuos/rpm.conf` + +密码生成及修改方法可详见openEuler imageTailor手册[配置初始密码](https://docs.openeuler.org/zh/docs/22.03_LTS/docs/TailorCustom/imageTailor%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97.html#%E9%85%8D%E7%BD%AE%E5%88%9D%E5%A7%8B%E5%AF%86%E7%A0%81)章节。 + +## 执行裁剪命令 + +执行下面的命令进行裁剪,最后裁剪出来的iso在`/opt/imageTailor/result`路径下: + +```bash +cd /opt/imageTailor +./mkdliso -p dpuos -c custom/cfg_dpuos --sec --minios force +``` diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/figures/dpuos-arch.png b/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/figures/dpuos-arch.png new file mode 100644 index 0000000000000000000000000000000000000000..453370ab07858a13a6c40f8d22e3f608e9ec6b4c Binary files /dev/null and b/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/figures/dpuos-arch.png differ diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/overview.md b/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..da40e928858c43a4b6d54e59995ad58897b40f8f --- /dev/null +++ b/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/overview.md @@ -0,0 +1,11 @@ +# 概述 + +本文档介绍DPU-OS的背景需求及整体设计思想,并介绍基于openEuler操作系统裁剪构建DPU-OS镜像的方法以及部署验证方法。该特性基于openEuler生态构建轻量化以及极致性能的DPU-OS,为DPU场景及用户提供DPU-OS参考实现。 + +本文档适用于使用openEuler系统并希望了解和使用DPU的社区开发者、DPU厂商及客户。使用人员需要具备以下经验和技能: + +- 熟悉Linux基本操作。 + +- 熟悉Linux系统构建及部署的相关基础知识和操作。 + +- 对openEuler ImageTailor镜像裁剪工具有一定了解。 diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/public_sys-resources/icon-note.gif b/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/verification-and-deployment.md b/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/verification-and-deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..3284d19d7655bfd48cb29e9b57e908e1b8dd3e11 --- /dev/null +++ b/docs/en/25.03/Server/DiversifiedComputing/DPU-OS/verification-and-deployment.md @@ -0,0 +1,38 @@ +# 验证与部署 + +DPU-OS制作完成后可以安装部署进行验证。由于目前DPU硬件还不成熟,也可以通过VirtualBox拉起虚拟机进行相关部署验证。 + +## 在VirtualBox上部署DPU-OS + +本章节展示了如何在VirtualBox虚拟机管理程序上安装部署DPU-OS。 + +### 验证准备 + +在开始部署 DPU-OS 之前,需要做如下准备工作: + +- 获取 DPU-OS ISO +- 安装有VirtualBox的宿主机 + +### 初步安装与启动 + +#### 创建虚拟机 + +通过VirtualBox创建新的虚拟机: + +- 选择虚拟机配置,CPU及内存建议2CPU+4GB内存以上 + +- 创建虚拟机磁盘,磁盘大小建议60GB以上 + +- 系统扩展属性部分,勾选启动EFI + +- 存储设置部分,光驱配置选择本地DPU-OS ISO作为光驱文件 + +- 其他网络或显示设置可自定义 + +#### 启动虚拟机 + +启动新建的虚拟机,启动项选择`Install from ISO`进行DPU-OS安装,安装过程自动进行无需手动干预,安装完成后自动重启。 + +选择启动项 `Boot From Local Disk`,启动后即可进入DPU-OS。密码为DPU-OS制作时指定的密码。 + +通过上述步骤,即可完成DPU-OS的本地部署验证。 diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/_menu.md b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..8fa33f8bf9431224f9e53853d0851d3c0d0954d8 --- /dev/null +++ b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/_menu.md @@ -0,0 +1,17 @@ +--- +label: '直连聚合用户指南' +ismanual: 'Y' +description: '介绍基于openEuler操作系统的容器管理面DPU无感卸载功能特性及安装部署方法' +children: + - label: '直连聚合环境搭建' + href: './libvirt-direct-connection-aggregation-environment-establishment.md' + - label: 'qtfs共享文件系统架构' + href: './qtfs-architecture-and-usage.md' + - label: '容器管理面DPU无感卸载' + href: './overview.md' + children: + - label: '容器管理面无感卸载' + href: './imperceptible-container-management-plane-offload.md' + - label: '容器管理面无感卸载部署指导' + href: './offload-deployment-guide.md' +--- diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/config/rexec.service b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/config/rexec.service new file mode 100644 index 0000000000000000000000000000000000000000..ee9e5e4895adb5c010e3f8d4db6652cfaed3d355 --- /dev/null +++ b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/config/rexec.service @@ -0,0 +1,13 @@ +[Unit] +Description=Rexec_server Service +After=network.target + +[Service] +Type=simple +Environment=CMD_NET_ADDR=tcp://0.0.0.0:7777 +ExecStart=/usr/bin/rexec_server +ExecReload=/bin/kill -s HUP $MAINPID +KillMode=process + +[Install] +WantedBy=multi-user.target diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/figures/arch.png b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/figures/arch.png new file mode 100644 index 0000000000000000000000000000000000000000..b6a7836fd6fab75009e781ac1ed96c73c352f75b Binary files /dev/null and b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/figures/arch.png differ diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/figures/offload-arch.png b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/figures/offload-arch.png new file mode 100644 index 0000000000000000000000000000000000000000..944900b42c13091e4ec40c6d51dc3c95088aa1b8 Binary files /dev/null and b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/figures/offload-arch.png differ diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/figures/qtfs-arch.png b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/figures/qtfs-arch.png new file mode 100644 index 0000000000000000000000000000000000000000..40fd7e28707642801ec0b984690a25c08e092ac4 Binary files /dev/null and b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/figures/qtfs-arch.png differ diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/imperceptible-container-management-plane-offload.md b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/imperceptible-container-management-plane-offload.md new file mode 100644 index 0000000000000000000000000000000000000000..0eb57b2e40fb8c356f109075842288209052163a --- /dev/null +++ b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/imperceptible-container-management-plane-offload.md @@ -0,0 +1,31 @@ +# 容器管理面无感卸载介绍 + +## 概述 + +在数据中心及云场景下,随着摩尔定律失效,通用处理单元CPU算力增长速率放缓,而同时网络IO类速率及性能不断攀升,二者增长速率差异形成的剪刀差,即当前通用处理器的处理能力无法跟上网络、磁盘等IO处理的需求。传统数据中心下越来越多的通用CPU算力被IO及管理面等占用,这部分资源损耗称之为数据中心税(Data-center Tax)。据AWS统计,数据中心税可能占据数据中心算力的30%以上,部分场景下甚至可能更多。 + +DPU的出现就是为了将这部分算力资源从主机CPU上解放出来,通过将管理面、网络、存储、安全等能力卸载到专有的处理器芯片(DPU)上进行处理加速,达成降本增效的结果。目前主流云厂商如AWS、阿里云、华为云都通过自研芯片完成管理面及相关数据面的卸载,达成数据中心计算资源100%售卖给客户。 + +管理面进程卸载到DPU可以通过对组件源码进行拆分达成,将源码根据功能逻辑拆分成独立运行的两部分,分别运行在主机和DPU,达成组件卸载的目的。但是这种做法有以下问题:一是影响组件的软件兼容性,组件后续版本升级和维护需要自己维护相关patch,带来一定的维护工作量;二是卸载工作无法被其他组件继承,后续组件卸载后仍需要进行代码逻辑分析和拆分等工作。为解决上述问题,本方案提出DPU的无感卸载,通过OS提供的抽象层,屏蔽应用在主机和DPU间跨主机访问的差异,让业务进程近似0改动达成卸载到DPU运行的目标,且这部分工作属于操作系统通用层,与上层业务无关,其他业务进行DPU卸载时也可以继承。 + +## 架构介绍 + +### 容器管理面DPU无感卸载架构 + +**图1**容器管理面DPU无感卸载架构 + +![offload-arch](./figures/offload-arch.png) + +如图1所示,容器管理面卸载后,dockerd、kubelet等管理进程运行在DPU侧,容器进程本身运行在HOST,进程之间的交互关系由系统层提供对应的能力来保证: + +* 通信层:DPU和主机之间可能通过PCIe或网络进行通信,需要基于底层物理连接提供通信接口层,为上层业务提供通信接口。 + +* 内核共享文件系统qtfs:容器管理面组件kubelet、dockerd与容器进程之间的主要交互通过文件系统进行;管理面工具需要为容器进程准备rootfs、volume等数据面路径;还需要在运行时通过proc文件系统、cgroup文件系统等控制和监控容器进程的资源及状态。共享文件系统的详细介绍参考[共享文件系统介绍](qtfs-architecture-and-usage.md) + +* 用户态卸载环境:用户态需要使用qtfs为容器管理面准备卸载后的运行时环境,将主机的容器管理及运行时相关目录远程挂载到DPU;另外由于需要挂载proc、sys、cgroup等系统管理文件系统,为防止对DPU原生系统功能的破坏,上述挂载动作都在chroot环境内完成。另外管理面(运行于DPU)和容器进程(运行于主机)之间仍存在调用关系,需要通过远程二进制执行工具(rexec)提供对应功能。 + +容器管理面无感卸载的操作步骤可参考[部署指导文档](./offload-deployment-guide.md) + +> ![](./public_sys-resources/icon-note.gif)**说明**: +> +> 上述操作指导涉及对容器管理面组件的少量改动和rexec工具修改,这些修改基于指定版本,其他版本可基于实际执行环境做适配修改。文档中提供的patch仅供验证指导使用,不具备实际商用的条件。 diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/libvirt-direct-connection-aggregation-environment-establishment.md b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/libvirt-direct-connection-aggregation-environment-establishment.md new file mode 100644 index 0000000000000000000000000000000000000000..cade9bd0849591d2ae972cb53f403634c17f643e --- /dev/null +++ b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/libvirt-direct-connection-aggregation-environment-establishment.md @@ -0,0 +1,425 @@ +# **1** 硬件准备 + +## 测试模式 + +需准备2台物理机(虚拟机当前未试过),网络互通。 + +其中一台作为DPU模拟,另一台作为HOST模拟。在本文档中用DPU和HOST指代这两台服务器。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 测试模式因为会暴露网络端口且不做连接认证,存在网络安全风险,仅能用于内部测试验证,不要用于实际生产环境。 + +## vsock模式 + +需要DPU加HOST,且DPU能支持通过virtio提供vsock通信方式。 + +目前还未基于真实的支持DPU vsock的环境调试过,本文档当前仅描述基于测试模式的方法,下面的内容依然默认使用测试模式。 + +# **2** libvirt卸载架构图 + +![arch](./figures/arch.png) + +# **3** 环境搭建 + +## **3.1** QTFS文件系统部署 + +可参考qtfs主页: + +QTFS建联需要关闭防火墙。 + +## **3.2** UDSPROXYD服务部署 + +### 3.2.1 简介 + +udsproxyd是一个跨主机的unix domain socket代理服务,需要分别部署在host和dpu上,在host和dpu上的udsproxyd组件是对等的关系,可以实现分布在host与dpu上的2个进程之间的uds通信,通信进程是无感的,也就是说如果这两个进程在同一主机内通过uds正常通信的功能,拉远到host和dpu之间也可以,不需要做代码适配,只需要作为client的一端加一个环境变量`LD_PRELOAD=libudsproxy.so`。udsproxyd作为一个跨主机的unix socket服务,本身可以用LD_PRELOAD=libudsproxy.so的方式对接使用,在qtfs的支持下也可以无感应用,这需要提前做好白名单相关配置,具体有两种方式,将在后面详述。 + +### 3.2.2 部署方式 + +首先,在dpu-utilities工程内编译udsproxyd: + +```bash + +cd qtfs/ipc + +make -j UDS_TEST_MODE=1 && make install + +``` + +当前最新版本下,qtfs server侧的engine服务已经整合了udsproxyd的能力,所以server侧若部署了qtfs后不需要再额外启动udsproxyd。client侧则单独拉起udsproxyd服务: + +```bash + +nohup /usr/bin/udsproxyd 2>&1 & + +``` + +参数解释: + +```bash + +thread num: 线程数量,目前只支持单线程,填1. + +addr: 本机使用的ip + +port:本机占用的port + +peer addr: udsproxyd对端的ip + +peer port: 对端port + +``` + +示例: + +```bash + +nohup /usr/bin/udsproxyd 1 192.168.10.10 12121 192.168.10.11 12121 2>&1 & + +``` + +如果未拉起qtfs的engine服务,想单独测试udsproxyd,则在server端也对等拉起udsproxyd即可: + +```bash + +nohup /usr/bin/udsproxyd 1 192.168.10.11 12121 192.168.10.10 12121 2>&1 & + +``` + +### 3.2.3 应用方式 + +#### 3.2.3.1 独立使用udsproxyd服务 + +需要在使用uds服务的unix socket应用程序的client端进程启动时添加LD_PRELOAD=libudsproxy.so环境变量,以接管glibc的connect api进行uds对接,在libvirt卸载场景中可以将libudsproxy.so拷贝到libvirt的chroot目录下的/usr/lib64中以提供给libvirtd服务使用,这一步在后面介绍。 + +#### 3.2.3.2 无感使用udsproxyd服务 + +首先为qtfs配置uds服务的白名单,这里说的白名单是unix socket的server端bind的sock文件地址,例如libvirt的虚拟机建立的unix socket的服务端文件地址都在/var/lib/libvirt下,则我们需要增加一条白名单路径为/var/lib/libvirt/,提供两种方式供选择: + +a) 通过配置工具qtcfg加载,进入qtfs/qtinfo目录编译工具: + +在qtfs的client端执行 + +```bash + +make role=client +make install + +``` + +在qtfs的server端执行 + +```bash + +make role=server +make install + +``` + +配置工具将会自动安装,然后使用qtcfg命令配置白名单,假设需要增加的白名单为"/var/lib/libvirt/",输入: + +```bash + +qtcfg -x /var/lib/libvirt/ + +``` + +查询白名单为: + +```bash + +qtcfg -z + +``` + +删除白名单为: + +```bash + +qtcfg -y 0 + +``` + +删除白名单时,参数为查询白名单时列出来的index序号。 + +b) 通过配置文件增加,这需要在qtfs或qtfs_server内核模块加载前配置,通过内核模块初始化时读取该文件进行白名单配置。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 白名单是为了防止不相干的unix socket链接也进行远程连接产生错误,或者浪费不必要的资源,所以白名单尽量设置得精确一些,比如本文中针对libvirt场景设置为/var/lib/libvirt/比较好,而直接将/var/lib/或/var/或直接将根目录加入的做法是有较大风险的。 + +## **3.3** REXEC服务部署 + +### 3.3.1 简介 + +rexec是一个用c语言开发的远程执行组件,分为rexec client和rexec server。server端为一个常驻服务进程,client端为一个二进制文件,client端被执行后会基于udsproxyd服务与server端建立uds连接,并由server常驻进程在server端拉起指定程序。在libvirt虚拟化卸载中,libvirtd卸载到DPU上,当它需要在HOST拉起虚拟机qemu进程时调起rexec client进行远程拉起。 + +### 3.3.2 部署方法 + +#### 3.3.2.1 配置环境变量与白名单 + +在host侧配置rexec server的白名单,将文件whitelist放置在/etc/rexec/目录下并修改权限为只读: + +```bash + +chmod 400 /etc/rexec/whitelist + +``` + +如果想仅用于测试,可以不进行白名单配置,删除此文件重启rexec_server进程后则没有白名单限制。 + +下载dpu-utilities代码后,进入qtfs/rexec主目录下,执行:`make && make install`即可安装rexec所需全部二进制到/usr/bin目录下,包括了:`rexec、rexec_server`两个二进制可执行文件。 + +在server端启动rexec_server服务之前,检查是否存在/var/run/rexec目录,没有则创建: + +```bash + +mkdir /var/run/rexec + +``` + +#### 3.3.2.2 服务方式 + +server端可以通过两种方式拉起rexec_server服务。 + +- 方式1: + +配置systemd服务 + +在/usr/lib/systemd/system/下增加rexec.service文件,内容如下: + +[rexec.service](./config/rexec.service) + +然后通过systemctl管理rexec服务。 + +首次配置服务时: + +```bash + +systemctl daemon-reload + +systemctl enable --now rexec + +``` + +后续重启新启动服务: + +```bash + +systemctl stop rexec + +systemctl start rexec + +``` + +- 方式2: + +手动后台拉起 + +```bash + +nohup /usr/bin/rexec_server 2>&1 & + +``` + +## **3.4** libvirt服务部署 + +### 3.4.1 HOST侧部署 + +HOST无需额外部署,只需要安装虚拟机启动环境以及libvirt即可(安装libvirt主要是为了创建对应的目录): + +```bash + +yum install -y qemu libvirt edk2-aarch64 #(arm环境虚拟机启动需要) + +``` + +HOST需要放置虚拟机镜像,后面通过qtfs挂载到client端共享给libvirt。 + +### 3.4.2 DPU侧部署 + +#### 3.4.2.1 创建chroot环境 + +a) 从openEuler官网下载qcow镜像,例如23.09版本 + +b) 将qcow2挂载出来: + +```bash + +cd /root/ + +mkdir p2 new_root_origin new_root + +modprobe nbd maxport=8 + +qemu-nbd -c /dev/nbd0 xxx.qcow2 + +mount /dev/nbd0p2 /root/p2 + +cp -rf /root/p2/* /root/new_root_origin/ + +umount /root/p2 + +qemu-nbd -d /dev/nbd0 + +``` + +c) 此时new_root_origin有解压出来的镜像根目录,再将new_root绑定挂载到该目录上,作为chroot的根目录挂载点: + +```bash + +mount --bind /root/new_root_origin /root/new_root + +``` + +#### 3.4.2.2 安装libvirt + +此处介绍patch方式源码编译,如果计算提供rpm包则参考计算提供的安装方法。 + +a) 进入chroot环境,安装编译环境和常用工具: + +```bash + +yum groupinstall "Development tools" -y +yum install -y vim meson qemu qemu-img strace edk2-aarch64 tar + +``` + +其中edk2-aarch64是arm环境下虚拟机启动需要的。 + +b) 安装libvirt编译需要的依赖包: + +```bash + +yum install -y rpcgen python3-docutils glib2-devel gnutls-devel libxml2-devel libpciaccess-devel libtirpc-devel yajl-devel systemd-devel dmidecode glusterfs-api numactl + +``` + +c) 下载libvirt-x.x.x。源码包: + +d) 获取直连聚合libvirt patch: + + + +e) 将源码包解压到chroot环境下的目录,如/home。将patch打上。 + +f) 进入libvirt-x.x.x目录。 + +```bash + +meson build --prefix=/usr -Ddriver_remote=enabled -Ddriver_network=enabled -Ddriver_qemu=enabled -Dtests=disabled -Ddocs=enabled -Ddriver_libxl=disabled -Ddriver_esx=disabled -Dsecdriver_selinux=disabled -Dselinux=disabled + +``` + +g) 安装成功 + +```bash + +ninja -C build install + +``` + +#### 3.4.2.3 启动libvirtd服务 + +libvirt直连聚合卸载模式,需要从chroot内启动libvirtd服务,首先需要把chroot之外的libvirtd服务停掉。 + +a) 放置虚拟机跳板脚本在chroot环境下的/usr/bin和/usr/libexec下:[qemu-kvm](./scripts/qemu-kvm)。替换原同名二进制,这个跳板脚本就是用于调用rexec拉起远端虚拟机。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> virsh使用的xml中,\下面的\需要填qemu-kvm,如果是填的其他,则需要修改为qemu-kvm,或者将跳板脚本替换\指代的二进制,且跳板脚本内容需要对应地更改。 + +b) 将udsproxyd编译时附带产生的libudsproxy.so拷贝到本chroot目录下/usr/lib64下,如果配置qtfs的uds白名单方式使用udsproxyd服务,则不需要。 + +c) 将前面rexec编译产生的rexec二进制放置到本chroot的/usr/bin/目录下。 + +d) 配置chroot的挂载环境,需要挂载一些目录,使用如下配置脚本: + +- [virt_start.sh](./scripts/virt_start.sh)为配置脚本,virt_start.sh脚本中需要手动修改qtfs ko dir为编译的ko位置,host ip address为正确的host地址。 + +- [virt_umount.sh](./scripts/virt_umount.sh)为消除配置脚本。 + +e) 脚本中挂载目录位置都是按照本文档前文创建目录位置与名称为准,如果有修改需要同步适配修改脚本。 + +f) 配置好chroot环境后,进入chroot环境,手动拉起libvirtd。 + +未配置qtfs使用udsproxyd白名单的拉起方式: + +```bash + +LD_PRELOAD=/usr/lib64/libudsproxy.so virtlogd -d +LD_PRELOAD=/usr/lib64/libudsproxy.so libvirtd -d + +```` + +如果已配置qtfs使用udsproxyd白名单,则不需要增加LD_PRELOAD前缀: + +```bash + +virtlogd -d +libvirtd -d + +``` + +查看是否已配置白名单的方式,在chroot之外的窗口,执行: + +```bash + +qtcfg -z + +``` + +查看列举出来的白名单是否包含/var/lib/libvirt/。 + +## **3.5** 拉起虚拟机 + +服务部署完成后,即可以在DPU侧进行虚拟机的生命周期管理。 + +### 3.5.1 虚拟机define + +a) 将虚拟机启动镜像放置在HOST侧某目录,例如: + +```bash + +/home/VMs/Domain_name + +``` + +b) 使用qtfs将这个目录挂载到DPU侧: + +```bash + +mount -t qtfs /home/VMs /home/VMs + +``` + +c) xml中使用`/home/VMs/Domain_name`作为启动镜像,这样在DPU和HOST侧看到的都是同一个镜像文件(Domain_name是虚拟机domain的名字)。 + +d) 检查xml中\是否指向了跳板脚本。 + +e) 执行以下命令。 + +```bash + +virsh define xxx.xml + +``` + +### 3.5.2 虚拟机start + +```bash + +virsh start domain + +``` + +# **4** 环境重置 + +由于libvirt在DPU和HOST之间共享了部分目录,卸载环境时需要先将这部分目录全部umount。一般先停掉libvirtd和virtlogd进程,调用virt_umount脚本即可。如果HOST还有虚拟机运行,也需要先杀掉才能umount。 + +# **5** 部分问题定位思路 + +1、 libvirt编译失败:检查依赖包安装是否完全,如果chroot挂载了外部目录或者host目录,也可能导致编译失败,需先解除挂载。 + +2、 QTFS挂载失败:可能server端engine进程没拉起、防火墙没关导致qtfs建联失败。 + +3、 虚拟机define失败:检查xml里的项目仿真器是否指向跳板脚本、虚拟机镜像是否已经通过qtfs挂载到DPU上可见,且路径与HOST一致。 + +4、 虚拟机启动失败:libvirtd和virtlogd服务是否拉起、rexec服务是否拉起、跳板进程是否拉起、是否qemu-kvm拉起时报错。 diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/offload-deployment-guide.md b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/offload-deployment-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..8363931a67044640282a26bf88b7136d424828ea --- /dev/null +++ b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/offload-deployment-guide.md @@ -0,0 +1,167 @@ +# 容器管理面无感卸载部署指导 + +> ![](./public_sys-resources/icon-note.gif)**说明**: +> +> 本指导涉及对容器管理面组件的少量改动和rexec工具修改,这些修改基于指定版本,其他版本可基于实际执行环境做适配修改。文档中提供的patch仅供验证指导使用,不具备实际商用的条件。 +> ![](./public_sys-resources/icon-note.gif)**说明**: +> +> 当前共享文件系统之间通信通过网络完成,可通过网络互连的两台物理机器或VM模拟验证。 +> +> 建议用户验证前先搭建可正常使用的kubernetes集群和容器运行环境,针对其中单个节点的管理面进程进行卸载验证,卸载环境(DPU)可选择一台具备网络连接的物理机或VM。 + +## 简介 + +容器管理面,即kubernetes、dockerd、containerd、isulad等容器的管理工具,而容器管理面卸载,即是将容器管理面卸载到与容器所在机器(以下称为HOST)之外的另一台机器(当前场景下是指DPU,一个具备独立运行环境的硬件集合)上运行。 + +我们使用共享文件系统qtfs将HOST上与容器运行相关的目录挂载到DPU上,使得容器管理面工具(运行在DPU)可以访问到这些目录,并为容器(运行在HOST)准备运行所需要的环境,此处,因为需要挂载远端的proc和sys等特殊文件系统,所以,我们创建了一个专门的rootfs以作为kubernetes、dockerd的运行环境(以下称为`/another_rootfs`)。 + +并且通过rexec执行容器的拉起、删除等操作,使得可以将容器管理面和容器分离在不同的两台机器上,远程对容器进行管理。 + +## 相关组件补丁介绍 + +### rexec介绍 + +rexec是一个用go语言开发的远程执行工具,基于docker/libchan下的[rexec](https://github.com/docker/libchan/tree/master/examples/rexec)示例工具改造而成,实现远程调用远端二进制的功能,为方便使用在rexec中增加了环境变量传递和监控原进程退出等能力。 + +rexec工具的具体使用方式为在服务器端用`CMD_NET_ADDR=tcp://0.0.0.0:<端口号> rexec_server`的方式拉起rexec服务进程,然后在客户端用`CMD_NET_ADDR=tcp://<服务端ip>:<端口号> rexec [要执行的指令]`的方式启动,便可以调用rexec_server执行需要执行的指令,并等待指令执行结果返回。 + +### dockerd相关改动介绍 + +对dockerd的改动基于18.09版本。 + +在containerd中,暂时注释掉了通过hook调用libnetwork-setkey的部分,此处不影响容器的拉起。并且,为了docker load的正常使用,注释掉了在mounter_linux.go 中mount函数中一处错误的返回。 + +最后,因为在容器管理面的运行环境中,将`/proc`挂在了服务端的proc文件系统,而本地的proc文件系统则挂载在了`/local_proc`,所以,dockerd以及containerd中的对`/proc/self/xxx`或者`/proc/getpid()/xxx`或者相关的文件系统访问的部分,我们统统将`/proc`改为了`/local_proc`。 + +### containerd相关改动介绍 + +对于containerd的改动基于containerd-1.2-rc.1版本。 + +在获取mountinfo时,因为`/proc/self/mountinfo`只能获取到dockerd本身在本地的mountinfo,而无法获取到服务端的mountinfo,所以,将其改为了`/proc/1/mountinfo`,使其通过获取服务端1号进程mountinfo的方式得到服务端的mountinfo。 + +在contaienrd-shim中,将与containerd通信的unix socket改为了用tcp通信,containerd通过`SHIM_HOST`环境变量获取containerd-shim所运行环境的ip,即服务端ip。用shim的哈希值计算出一个端口号,并以此作为通信的端口,来拉起containerd-shim. + +并且,将原来的通过系统调用给contaienr-shim发信号的方式,改为了通过远程调用kill指令的方式向shim发信号,确保了docker杀死容器的行为可以正确的执行。 + +### kubernetes相关改动介绍 + +kubelet暂不需要功能性改动,可能会遇到容器QoS管理器首次设置失败的错误,该错误不影响后续Pods拉起流程,暂时忽略该报错。 + +## 容器管理面卸载操作指南 + +在服务器端和客户端,都要拉起rexec_server。服务器端拉起rexec_server,主要是用于客户端创建容器时用rexec拉起containerd-shim,而客户端拉起rexec_server,则是为了执行containerd-shim对dockerd和containerd的调用。 + +### 服务器端 + +创建容器管理面所需要的文件夹,然后插入qtfs_server.ko,并拉起engine进程。 + +此外在服务器端,还需要创建rexec脚本/usr/bin/dockerd. + +``` shell +#!/bin/bash +CMD_NET_ADDR=tcp://<客户端ip>: rexec /usr/bin/dockerd $* +``` + +### 客户端 + +需要准备一个rootfs,作为dockerd与containerd的运行环境,通过如下的脚本,将dockerd、containerd所需要的服务端目录挂载到客户端。并且,需要确保在以下脚本中被挂载的远程目录在服务端和客户端都存在。 + +``` shell +#!/bin/bash +mkdir -p /another_rootfs/var/run/docker/containerd +iptables -t nat -N DOCKER +echo "---------insmod qtfs ko----------" +insmod /YOUR/QTFS/PATH/qtfs.ko qtfs_server_ip=<服务端ip> qtfs_log_level=INFO + +# chroot环境内的proc使用DPU的proc共享文件系统替换,需要将本机真实proc文件系统挂载到local_proc下使用 +mount -t proc proc /another_rootfs/local_proc/ + +# 将chroot内环境与外部环境bind,方便进行配置和运行 +mount --bind /var/run/ /another_rootfs/var/run/ +mount --bind /var/lib/ /another_rootfs/var/lib/ +mount --bind /etc /another_rootfs/etc + +mkdir -p /another_rootfs/var/lib/isulad + +# 在chroot环境内创建并挂载dev、sys和cgroup文件系统 +mount -t devtmpfs devtmpfs /another_rootfs/dev/ +mount -t sysfs sysfs /another_rootfs/sys +mkdir -p /another_rootfs/sys/fs/cgroup +mount -t tmpfs tmpfs /another_rootfs/sys/fs/cgroup +list="perf_event freezer files net_cls,net_prio hugetlb pids rdma cpu,cpuacct memory devices blkio cpuset" +for i in $list +do + echo $i + mkdir -p /another_rootfs/sys/fs/cgroup/$i + mount -t cgroup cgroup -o rw,nosuid,nodev,noexec,relatime,$i /another_rootfs/sys/fs/cgroup/$i +done + +## common system dir +mount -t qtfs -o proc /proc /another_rootfs/proc +echo "proc" +mount -t qtfs /sys /another_rootfs/sys +echo "cgroup" + +# 挂载容器管理面所需要的共享目录 +mount -t qtfs /var/lib/docker/containers /another_rootfs/var/lib/docker/containers +mount -t qtfs /var/lib/docker/containerd /another_rootfs/var/lib/docker/containerd +mount -t qtfs /var/lib/docker/overlay2 /another_rootfs/var/lib/docker/overlay2 +mount -t qtfs /var/lib/docker/image /another_rootfs/var/lib/docker/image +mount -t qtfs /var/lib/docker/tmp /another_rootfs/var/lib/docker/tmp +mkdir -p /another_rootfs/run/containerd/io.containerd.runtime.v1.linux/ +mount -t qtfs /run/containerd/io.containerd.runtime.v1.linux/ /another_rootfs/run/containerd/io.containerd.runtime.v1.linux/ +mkdir -p /another_rootfs/var/run/docker/containerd +mount -t qtfs /var/run/docker/containerd /another_rootfs/var/run/docker/containerd +mount -t qtfs /var/lib/kubelet/pods /another_rootfs/var/lib/kubelet/pods +``` + +在/another_rootfs中,需要创建以下脚本,用来支持部分跨主机操作。 + +* /another_rootfs/usr/local/bin/containerd-shim + +``` shell +#!/bin/bash +CMD_NET_ADDR=tcp://<服务端ip>: /usr/bin/rexec /usr/bin/containerd-shim $* +``` + +* /another_rootfs/usr/local/bin/remote_kill + +``` shell +#!/bin/bash +CMD_NET_ADDR=tcp://<服务端ip>: /usr/bin/rexec /usr/bin/kill $* +``` + +* /another_rootfs/usr/sbin/modprobe + +``` shell +#!/bin/bash +CMD_NET_ADDR=tcp://<服务端ip>: /usr/bin/rexec /usr/sbin/modprobe $* +``` + +在chroot到dockerd和containerd运行所需的rootfs后,用如下的命令拉起dockerd和containerd + +* containerd + +``` shell +#!/bin/bash +SHIM_HOST=<服务端ip> containerd --config /var/run/docker/containerd/containerd.toml --address /var/run/containerd/containerd.sock +``` + +* dockerd + +``` shell +#!/bin/bash +SHIM_HOST=<服务端ip> CMD_NET_ADDR=tcp://<服务端ip>: /usr/bin/dockerd --containerd /var/run/containerd/containerd.sock +``` + +* kubelet + +在chroot环境内使用原参数拉起kubelet即可。 + +因为我们已经将/var/run/和/another_rootfs/var/run/绑定在了一起,所以可以在正常的rootfs下,通过docker来访问docker.sock接口进行容器管理。 + +至此,完成容器管理面卸载到DPU,可以通过docker相关操作进行容器创建、删除等操作,也可以通过kubectl在当前节点进行pods调度和销毁,且实际容器业务进程运行在HOST侧。 + +> ![](./public_sys-resources/icon-note.gif)**说明**: +> +> 本指导所述操作只涉及容器管理面进程卸载,不包含容器网络和数据卷volume等卸载,如有相关需求,需要通过额外的网络或存储卸载能力支持。本指导支持不带网络和存储的容器跨节点拉起。 diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/overview.md b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..4f4ee65a44030b0e956c71b4500e53cf8a095847 --- /dev/null +++ b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/overview.md @@ -0,0 +1,11 @@ +# 容器管理面DPU无感卸载指南 + +本文档介绍基于openEuler操作系统的容器管理面DPU无感卸载功能特性及安装部署方法,该特性可以通过操作系统提供的统一抽象层,屏蔽容器管理面跨主机资源访问的差异,实现容器管理面业务无感卸载到DPU上。 + +本文档适用于使用openEuler系统并希望了解和使用操作系统内核及容器的社区开发者、开源爱好者以及相关合作伙伴。使用人员需要具备以下经验和技能: + +- 熟悉Linux基本操作 + +- 熟悉linux内核文件系统相关基础机制 + +- 对kubernetes和docker有一定了解,熟悉docker及kubernetes部署及使用。 diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/public_sys-resources/icon-note.gif b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/qtfs-architecture-and-usage.md b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/qtfs-architecture-and-usage.md new file mode 100644 index 0000000000000000000000000000000000000000..fc24e9ce06588570651ca3f131e73aea34f61922 --- /dev/null +++ b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/qtfs-architecture-and-usage.md @@ -0,0 +1,67 @@ +# qtfs + +## 介绍 + +qtfs是一个共享文件系统项目,可部署在host-dpu的硬件架构上,也可以部署在2台服务器之间。以客户端服务器的模式工作,使客户端能通过qtfs访问服务端的指定文件系统,得到本地文件访问一致的体验。 + +qtfs的特性: + ++ 支持挂载点传播; + ++ 支持proc、sys、cgroup等特殊文件系统的共享; + ++ 支持远程文件读写的共享; + ++ 支持在客户端对服务端的文件系统进行远程挂载; + ++ 支持特殊文件的定制化处理; + ++ 支持远端fifo、unix-socket等,并且支持epoll,使客户端和服务端像本地通信一样使用这些文件; + ++ 支持基于host-dpu架构通过PCIe协议底层通信,性能大大优于网络; + ++ 支持内核模块形式开发,无需对内核进行侵入式修改。 + +## 软件架构 + +软件大体框架图: + +![qtfs-arch](./figures/qtfs-arch.png) + +## 安装教程 + +目录说明: + ++ **qtfs**: 客户端内核模块相关代码,直接在该目录下编译客户端ko。 + ++ **qtfs_server**: 服务端内核模块相关代码,直接在该目录下编译服务端ko和相关程序。 + ++ **qtinfo**: 诊断工具,支持查询文件系统的工作状态以及修改log级别等。 + ++ **demo**、**test**、**doc**: 测试程序、演示程序以及项目资料等。 + ++ 根目录: 客户端与服务端通用的公共模块代码。 + +首先找两台服务器(或虚拟机)配置内核编译环境: + +1. 要求内核版本在5.10或更高版本。 +2. 安装内核开发包:yum install kernel-devel。 + +服务端安装: + +1. cd qtfs_server +2. make clean && make +3. insmod qtfs_server.ko qtfs_server_ip=x.x.x.x qtfs_server_port=12345 qtfs_log_level=WARN +4. ./engine 4096 16 + +客户端安装: + +1. cd qtfs +2. make clean && make +3. insmod qtfs.ko qtfs_server_ip=x.x.x.x qtfs_server_port=12345 qtfs_log_level=WARN + +## 使用说明 + +安装完成后,客户端通过挂载把服务端的文件系统让客户端可见,例如:`mount -t qtfs / /root/mnt/` + +客户端进入"/root/mnt"后便可查看到server端的所有文件,以及对其进行相关操作。 diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/scripts/qemu-kvm b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/scripts/qemu-kvm new file mode 100644 index 0000000000000000000000000000000000000000..e869371be109b57f59709fc23bc5b1cb2002cfbf --- /dev/null +++ b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/scripts/qemu-kvm @@ -0,0 +1,3 @@ +#!/bin/bash + +exec /usr/bin/rexec /usr/bin/qemu-kvm $* diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/scripts/virt_start.sh b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/scripts/virt_start.sh new file mode 100644 index 0000000000000000000000000000000000000000..06ca194b7a639a947b6e395f116beeba7c897459 --- /dev/null +++ b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/scripts/virt_start.sh @@ -0,0 +1,48 @@ +#!/bin/bash +insmod ./qtfs.ko qtfs_server_ip=192.168.10.11 qtfs_log_level=NONE + +systemctl stop libvirtd + +if [ ! -d "/root/new_root/local_proc" ]; then + mkdir -p /root/new_root/local_proc +fi +if [ ! -d "/root/new_root/local" ]; then + mkdir -p /root/new_root/local +fi +mount -t proc proc /root/new_root/local_proc/ +mount -t proc proc /root/new_root/local/proc +mount -t sysfs sysfs /root/new_root/local/sys +mount --bind /var/run/ /root/new_root/var/run/ +mount --bind /var/lib/ /root/new_root/var/lib/ +mount --bind /var/cache/ /root/new_root/var/cache +mount --bind /etc /root/new_root/etc + +mkdir -p /root/new_root/home/VMs/ +mount -t qtfs /home/VMs/ /root/new_root/home/VMs/ + +mount -t qtfs /var/lib/libvirt /root/new_root/var/lib/libvirt + +mount -t devtmpfs devtmpfs /root/new_root/dev/ +mount -t hugetlbfs hugetlbfs /root/new_root/dev/hugepages/ +mount -t mqueue mqueue /root/new_root/dev/mqueue/ +mount -t tmpfs tmpfs /root/new_root/dev/shm + +mount -t sysfs sysfs /root/new_root/sys +mkdir -p /root/new_root/sys/fs/cgroup +mount -t tmpfs tmpfs /root/new_root/sys/fs/cgroup +list="perf_event freezer files net_cls,net_prio hugetlb pids rdma cpu,cpuacct memory devices blkio cpuset" +for i in $list +do + echo $i + mkdir -p /root/new_root/sys/fs/cgroup/$i + mount -t cgroup cgroup -o rw,nosuid,nodev,noexec,relatime,$i /root/new_root/sys/fs/cgroup/$i +done + +## common system dir +mount -t qtfs -o proc /proc /root/new_root/proc +echo "proc" + +mount -t qtfs /sys /root/new_root/sys +echo "cgroup" +mount -t qtfs /dev/pts /root/new_root/dev/pts +mount -t qtfs /dev/vfio /root/new_root/dev/vfio diff --git a/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/scripts/virt_umount.sh b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/scripts/virt_umount.sh new file mode 100644 index 0000000000000000000000000000000000000000..4adddec913c23069c6bffddec0bf1770f8c5ce71 --- /dev/null +++ b/docs/en/25.03/Server/DiversifiedComputing/DPUOffload/scripts/virt_umount.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +umount /root/new_root/dev/hugepages +umount /root/new_root/etc +umount /root/new_root/home/VMs +umount /root/new_root/local_proc +umount /root/new_root/local/proc +umount /root/new_root/var/lib/libvirt +umount /root/new_root/var/lib +umount /root/new_root/* +umount /root/new_root/dev/pts +umount /root/new_root/dev/mqueue +umount /root/new_root/dev/shm +umount /root/new_root/dev/vfio +umount /root/new_root/dev +rmmod qtfs + +umount /root/new_root/sys/fs/cgroup/* +umount /root/new_root/sys/fs/cgroup +umount /root/new_root/sys diff --git a/docs/en/25.03/Server/HighAvailability/HA/HA_use_cases.md b/docs/en/25.03/Server/HighAvailability/HA/HA_use_cases.md new file mode 100644 index 0000000000000000000000000000000000000000..727ec4b40b4515597e437c9c209f73b48841d699 --- /dev/null +++ b/docs/en/25.03/Server/HighAvailability/HA/HA_use_cases.md @@ -0,0 +1,248 @@ +# HA使用实例 + +本章介绍如何快速使用HA高可用集群,以及添加一个实例。若不了解怎么安装,请参考[HA的安装与部署文档](./HAuserguide.md)。 + +## 快速使用指南 + +以下操作均以社区新开发的管理平台为例。 + +### 登录页面 + +用户名为`hacluster`,密码为该用户在主机上设置的密码。 + +![](./figures/HA-api.png) + +### 主页面 + +登录系统后显示主页面,主页面由四部分组成:侧边导航栏、顶部操作区、资源节点列表区以及节点操作浮动区。 + +以下将详细介绍这四部分的特点与使用方法。 + +![](./figures/HA-home-page.png) + +#### 导航栏 + +侧边导航栏由两部分组成:高可用集群软件名称和 logo 以及系统导航。系统导航由三项组成:【系统】、【集群配置】和【工具】。【系统】是默认选项,也是主页面的对应项,主要展示系统中所有资源的相关信息以及操作入口;【集群配置】下设【首选项配置】和【心跳配置】两项;【工具】下设【日志下载】和【集群快捷操作】两项,点击后以弹出框的形式出现。 + +#### 顶部操作区 + +登录用户是静态显示,鼠标滑过用户图标,出现操作菜单项,包括【刷新设置】和【退出登录】两项,点击【刷新设置】,弹出【刷新设置】对话框,包含【刷新设置】选项,可以设置系统的自动刷新模式,包括【不自动刷新】、【每 5 秒刷新】和【每 10 秒刷新】三种选择,默认选择【不自动刷新】、【退出登录】即可注销本次登录,系统将自动跳到登录页面,此时,如果希望继续访问系统,则需要重新进行登录。 + +![](./figures/HA-refresh.png) + +#### 资源节点列表区 + +资源节点列表集中展现系统中所有资源的【资源名】、【状态】、【资源类型】、【服务】、【运行节点】等资源信息,以及系统中所有的节点和节点的运行情况等节点信息。同时提供资源的【添加】、【编辑】、【启动】、【停止】、【清理】、【迁移】、【回迁】、【删除】和【关系】操作。 + +#### 节点操作浮动区 + +节点操作浮动区域默认是收起的状态,每当点击资源节点列表表头中的节点时,右侧会弹出节点操作扩展区域,如图所示,该区域由收起按钮、节点名称、停止和备用四个部分组成,提供节点的【停止】和【备用】操作。点击区域左上角的箭头,该区域收起。 + +### 首选项配置 + +以下操作均可用命令行配置,现只做简单示例,若想使用更多命令可以使用``pcs --help``进行查询。 + +- 命令行方式 + + ```sh + # pcs property set stonith-enabled=false + # pcs property set no-quorum-policy=ignore + ``` + + 执行如下命令,可以查看全部配置。 + + ```sh + # pcs property + ``` + + ![](./figures/HA-firstchoice-cmd.png) + +- 图形界面方式 + 点击侧边导航栏中的【首选项配置】按钮,弹出【首选项配置】对话框。将No Quorum Policy和Stonith Enabled由默认状态改为如下对应状态;修改完成后,点击【确定】按钮完成配置。 + + ![](./figures/HA-firstchoice.png) + +### 添加资源 + +#### 添加普通资源 + +1. 点击【添加普通资源】,弹出【创建资源】对话框。 + 其中资源的所有必填配置项均在【基本】页面内,选择【基本】页面内的【资源类型】后会进一步给出该类资源的其他必填配置项以及选填配置项。 + +2. 填写资源配置信息。 + 对话框右侧会出现灰色文字区域,对当前的配置项进行解释说明。全部必填项配置完毕后,点击【确定】按钮即可创建普通资源,点击【取消】按钮,取消本次添加动作。 + 【实例属性】、【元属性】或者【操作属性】页面中的选填配置项为选填项,不配置不会影响资源的创建过程,可以根据场景需要可选择修改,否则将按照系统缺省值处理。 + +下面以Apache为例,分别以命令行方式和图形界面方式介绍添加资源的方法。 + +- 命令行方式 + + ```sh + # pcs resource create httpd ocf:heartbeat:apache + ``` + + 查看资源运行状态 + + ```sh + # pcs status + ``` + + ![](./figures/HA-pcs-status.png) + +- 图形界面方式 + +1. 填写资源名称和资源类型,如下图所示。 + + ![](./figures/HA-add-resource.png) + +2. 回显为如下,则资源添加成功并启动,运行于其中一个节点上,例如ha1。 + + ![](./figures/HA-apache-suc.png) +3. 访问apache界面成功。 + + ![](./figures/HA-apache-show.png) + +#### 添加组资源 + +>**须知:** +> 添加组资源时,集群中需要至少存在一个普通资源。 + +1. 点击【添加组资源】,弹出【创建资源】对话框。 + 【基本】页面内均为必填项,填写完毕后,点击【确定】按钮,即可完成资源的添加,点击【取消】按钮,取消本次添加动作。 + + ![](./figures/HA-group.png) + + > **注意:** + > 组资源的启动是按照子资源的顺序启动的,所以选择子资源时需要注意按照顺序选择。 + +2. 回显如下,资源添加成功。 + + ![](./figures/HA-group-suc.png) + +#### 添加克隆资源 + +1. 点击【添加克隆资源】,弹出【创建资源】对话框。 + 【基本】页面内填写克隆对象,资源名称会自动生成,填写完毕后,点击【确定】按钮,即可完成资源的添加,点击【取消】按钮,取消本次添加动作。 + + ![](./figures/HA-clone.png) + +2. 回显如下,资源添加成功。 + + ![](./figures/HA-clone-suc.png) + +### 编辑资源 + +- 启动资源:资源节点列表中选中一个目标资源,要求:该资源处于非运行状态。对该资源执行启动动作。 +- 停止资源:资源节点列表中选中一个目标资源,要求:该资源处于运行状态。对该资源执行停止操作。 +- 清理资源:资源节点列表中选中一个目标资源,对该资源执行清理操作。 +- 迁移资源:资源节点列表中选中一个目标资源,要求:该资源为处于运行状态的普通资源或者组资源,执行迁移操作可以将资源迁移到指定节点上运行。 +- 回迁资源:资源节点列表中选中一个目标资源,要求:该资源已经完成迁移动作,执行回迁操作,可以清除该资源的迁移设置,资源重新迁回到原来的节点上运行。(点击按钮后,列表中该资源项的变化状态与启动资源时一致。) +- 删除资源:资源节点列表中选中一个目标资源,对该资源执行删除操作。 + +### 设置资源关系 + +资源关系即为目标资源设定限制条件,资源的限制条件分为三种:资源位置、资源协同和资源顺序。 + +- 资源位置:设置集群中的节点对于该资源的运行级别,由此确定启动或者切换时资源在哪个节点上运行,运行级别按照从高到低的顺序依次为:Master Node、Slave 1。 +- 资源协同:设置目标资源与集群中的其他资源是否运行在同一节点上,同节点资源表示该资源与目标资源必须运行在相同节点上,互斥节点资源表示该资源与目标资源不能运行在相同的节点上。 +- 资源顺序:设置目标资源与集群中的其他资源启动时的先后顺序,前置资源是指目标资源运行之前,该资源必须已经运行;后置资源是指目标资源运行之后,该资源才能运行。 + +## 高可用mysql实例配置 + +### 配置虚拟IP + +1. 在首页中点击“添加”,再选择添加普通资源,并按如下进行配置。 + + ![](./figures/HA-vip.png) + +2. 资源创建成功并启动,运行于其中一个节点上,例如ha1。 +3. 可以ping通并连接,登录后可正常执行各种操作;资源切换到ha2运行;能够正常访问。如下图所示。 + ![](./figures/HA-vip-suc.png) + +### 配置NFS存储 + +另找一台机器作为nfs服务端进行配置,操作步骤如下: + +1. 安装软件包 + + ```sh + # yum install -y nfs-utils rpcbind + ``` + +2. 关闭防火墙 + + ```sh + # systemctl stop firewalld && systemctl disable firewalld + ``` + +3. 修改/etc/selinux/config文件中SELINUX状态为disabled + + ```Conf + SELINUX=disabled + ``` + +4. 启动服务 + + ```sh + # systemctl start rpcbind && systemctl enable rpcbind + # systemctl start nfs-server && systemctl enable nfs-server + ``` + +5. 服务端创建一个共享目录 + + ```sh + # mkdir -p /test + ``` + +6. 修改NFS配置文件 + + ```sh + # vim /etc/exports + # /test *(rw,no_root_squash) + ``` + +7. 重新加载服务 + + ```sh + # systemctl reload nfs + ``` + +8. 客户端安装软件包,需要先安装mysql,可以将nfs挂载到mysql数据路径。 + + ```sh + # yum install -y nfs-utils mariadb-server + ``` + +9. 在首页中依次点击“添加”,“添加普通资源”,并按如下进行配置NFS资源。 + + ![](./figures/HA-nfs.png) + +10. 资源创建成功并启动,运行于其中一个节点上,例如ha1;nfs成功挂载到`/var/lib/mysql`路径下。资源切换到ha2运行;nfs从ha1节点取消挂载,并自动在ha2节点上挂载成功。如下图所示。 + + ![](./figures/HA-nfs-suc.png) + +### 配置mysql + +1. 在首页中依次点击“添加”,“添加普通资源”,并按如下进行配置mysql资源。 + + ![](./figures/HA-mariadb.png) + +2. 若回显为如下,则资源添加成功。 + + ![](./figures/HA-mariadb-suc.png) + +### 添加上述资源为组资源 + +1. 按资源启动顺序添加三个资源 + + 在首页中依次点击“添加”,“添加组资源”,并按如下进行配置组资源。 + + ![](./figures/HA-group-new.png) + +2. 组资源创建成功并启动,若回显与上述三个普通资源成功现象一致,则资源添加成功。 + + ![](./figures/HA-group-new-suc.png) + +3. 将ha1节点备用,成功迁移到ha2节点,运行正常。 + + ![](./figures/HA-group-new-suc2.png) diff --git a/docs/en/25.03/Server/HighAvailability/HA/HAuserguide.md b/docs/en/25.03/Server/HighAvailability/HA/HAuserguide.md new file mode 100644 index 0000000000000000000000000000000000000000..7230f8bd53bae8cff17e3957b7e768a7e0f4c99e --- /dev/null +++ b/docs/en/25.03/Server/HighAvailability/HA/HAuserguide.md @@ -0,0 +1,201 @@ +# HA的安装与部署 + +本文介绍如何安装和部署HA高可用集群。 + +## 安装与部署 + +### 环境准备 + +需要至少两台安装了openEuler 21.03 的物理机/虚拟机(现以两台为例),安装方法参考《[安装指南](../../InstallationUpgrade/Installation/installation.md)》。 + +### 修改主机名称及/etc/hosts文件 + +**注**:两台主机均需要进行以下操作,现以其中一台为例,下文中使用的IP仅供参考。** + +在使用HA软件之前,需要确认修改主机名并将所有主机名写入/etc/hosts文件中。 + +1. 修改主机名 + + ```sh + # hostnamectl set-hostname ha1 + ``` + +2. 编辑`/etc/hosts`文件并写入以下字段 + + ```text + 172.30.30.65 ha1 + 172.30.30.66 ha2 + ``` + +### 配置yum源 + +成功安装系统后,会默认配置好yum源,文件位置存放在`/etc/yum.repos.d/openEuler.repo`文件中,HA软件包会用到以下源: + +```Conf +[OS] +name=OS +baseurl=http://repo.openeuler.org/openEuler-23.09/OS/$basearch/ +enabled=1 +gpgcheck=1 +gpgkey=http://repo.openeuler.org/openEuler-23.09/OS/$basearch/RPM-GPG-KEY-openEuler + +[everything] +name=everything +baseurl=http://repo.openeuler.org/openEuler-23.09/everything/$basearch/ +enabled=1 +gpgcheck=1 +gpgkey=http://repo.openeuler.org/openEuler-23.09/everything/$basearch/RPM-GPG-KEY-openEuler + +[EPOL] +name=EPOL +baseurl=http://repo.openeuler.org/openEuler-23.09/EPOL/$basearch/ +enabled=1 +gpgcheck=1 +gpgkey=http://repo.openeuler.org/openEuler-23.09/OS/$basearch/RPM-GPG-KEY-openEuler +``` + +### 安装HA软件包组件 + +```sh +# yum install -y corosync pacemaker pcs fence-agents fence-virt corosync-qdevice sbd drbd drbd-utils +``` + +### 设置hacluster用户密码 + +```sh +# passwd hacluster +``` + +### 修改`/etc/corosync/corosync.conf`文件 + +```Conf +totem { + version: 2 + cluster_name: hacluster + crypto_cipher: none + crypto_hash: none +} +logging { + fileline: off + to_stderr: yes + to_logfile: yes + logfile: /var/log/cluster/corosync.log + to_syslog: yes + debug: on + logger_subsys { + subsys: QUORUM + debug: on + } +} +quorum { + provider: corosync_votequorum + expected_votes: 2 + two_node: 1 + } +nodelist { + node { + name: ha1 + nodeid: 1 + ring0_addr: 172.30.30.65 + } + node { + name: ha2 + nodeid: 2 + ring0_addr: 172.30.30.66 + } + } +``` + +### 管理服务 + +#### 关闭防火墙 + +1. 执行如下命令,关闭防火墙。 + + ```sh + # systemctl stop firewalld + ``` + +2. 修改`/etc/selinux/config`文件中SELINUX状态为disabled。 + + ```sh + # SELINUX=disabled + ``` + +#### 管理pcs服务 + +1. 启动pcs服务: + + ```sh + # systemctl start pcsd + ``` + +2. 查询pcs服务状态: + + ```sh + # systemctl status pcsd + ``` + + 若回显为如下,则服务启动成功。 + + ![](./figures/HA-pcs.png) + +#### 管理pacemaker服务 + +1. 启动pacemaker服务: + + ```sh + # systemctl start pacemaker + ``` + +2. 查询pacemaker服务状态: + + ```sh + # systemctl status pacemaker + ``` + + 若回显为如下,则服务启动成功。 + + ![](./figures/HA-pacemaker.png) + +#### 管理corosync服务 + +1. 启动corosync服务: + + ```sh + # systemctl start corosync + ``` + +2. 查询corosync服务状态: + + ```sh + # systemctl status corosync + ``` + + 若回显为如下,则服务启动成功。 + + ![](./figures/HA-corosync.png) + +### 节点鉴权 + +注:**任选一个节点上执行即可** + +```sh +# pcs host auth ha1 ha2 +``` + +### 访问前端管理平台 + +上述服务启动成功后,打开浏览器(建议使用:Chrome,Firefox),在浏览器导航栏中输入`https://localhost:2224`即可。 + +- 以下界面为原生管理平台 + +![](./figures/HA-login.png) + +若安装社区新开发的管理平台请参考文档[https://gitee.com/openeuler/ha-api/blob/master/docs/build.md](https://gitee.com/openeuler/ha-api/blob/master/docs/build.md) + +- 以下为社区新开发的管理平台 + +![](./figures/HA-api.png) + +想了解如何快速使用HA高可用集群,以及添加一个实例。请参考[HA的使用实例文档](./HA_use_cases.md)。 diff --git a/docs/en/25.03/Server/HighAvailability/HA/_menu.md b/docs/en/25.03/Server/HighAvailability/HA/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..9746e29a0782142c2b0325a4dc86a1f34a911f66 --- /dev/null +++ b/docs/en/25.03/Server/HighAvailability/HA/_menu.md @@ -0,0 +1,10 @@ +--- +label: 'HA用户指南' +ismanual: 'Y' +description: '安装和使用 HA 高可用集群' +children: + - label: 'HA 安装与部署' + href: './HAuserguide.md' + - label: 'HA 使用实例' + href: './HA_use_cases.md' +--- diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-add-resource.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-add-resource.png new file mode 100644 index 0000000000000000000000000000000000000000..ac24895a1247828d248132f6c789ad8ef51a57e4 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-add-resource.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-apache-show.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-apache-show.png new file mode 100644 index 0000000000000000000000000000000000000000..c216500910f75f2de1108f6b618c5c08f4df8bae Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-apache-show.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-apache-suc.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-apache-suc.png new file mode 100644 index 0000000000000000000000000000000000000000..23a7aaa702e3e68190ff7e01a5a673aee2c92409 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-apache-suc.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-api.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-api.png new file mode 100644 index 0000000000000000000000000000000000000000..f825fe005705d30809d12df97958cff0e5a80135 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-api.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-clone-suc.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-clone-suc.png new file mode 100644 index 0000000000000000000000000000000000000000..4b6099ccc88d4f6f907a0c4563e729ab2a4dece1 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-clone-suc.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-clone.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-clone.png new file mode 100644 index 0000000000000000000000000000000000000000..1b09ab73849494f4ffd759fa612ae3c241bd9c1d Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-clone.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-corosync.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-corosync.png new file mode 100644 index 0000000000000000000000000000000000000000..c4d93242e65c503b6e1b6a457e2517f647984a66 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-corosync.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-firstchoice-cmd.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-firstchoice-cmd.png new file mode 100644 index 0000000000000000000000000000000000000000..a265bab07f1d8e46d9d965975be180a8de6c9eb2 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-firstchoice-cmd.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-firstchoice.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-firstchoice.png new file mode 100644 index 0000000000000000000000000000000000000000..bd982ddcea55c629c0257fca86051a9ffa77e7b4 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-firstchoice.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-group-new-suc.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-group-new-suc.png new file mode 100644 index 0000000000000000000000000000000000000000..437fd01ee83a9a1f65c12838fe56eea8435f6759 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-group-new-suc.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-group-new-suc2.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-group-new-suc2.png new file mode 100644 index 0000000000000000000000000000000000000000..4fb933bd761f9808de95a324a50226ff041ebd4f Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-group-new-suc2.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-group-new.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-group-new.png new file mode 100644 index 0000000000000000000000000000000000000000..9c914d0cc2e14f3220fc4346175961f129efb37b Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-group-new.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-group-suc.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-group-suc.png new file mode 100644 index 0000000000000000000000000000000000000000..2338580343833ebab08627be3a2efbcdb48aef9e Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-group-suc.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-group.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-group.png new file mode 100644 index 0000000000000000000000000000000000000000..6897817665dee90c0f8c47c6a3cb4bb09db52d78 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-group.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-home-page.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-home-page.png new file mode 100644 index 0000000000000000000000000000000000000000..c9a7a82dc412250d4c0984b3876c6f93c6aca789 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-home-page.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-login.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-login.png new file mode 100644 index 0000000000000000000000000000000000000000..65d0ae11ec810da7574ec72bebf6e1b020c94a0d Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-login.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-mariadb-suc.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-mariadb-suc.png new file mode 100644 index 0000000000000000000000000000000000000000..6f6756c945121715edc623bd9a848bc48ffeb4ca Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-mariadb-suc.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-mariadb.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-mariadb.png new file mode 100644 index 0000000000000000000000000000000000000000..d29587c8609b9d6aefeb07170901361b5ef8402d Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-mariadb.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-nfs-suc.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-nfs-suc.png new file mode 100644 index 0000000000000000000000000000000000000000..c0ea6af79e91649f1ad7d97ab6c2a0069a4f4fb8 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-nfs-suc.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-nfs.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-nfs.png new file mode 100644 index 0000000000000000000000000000000000000000..f6917938eec2e0431a9891c067475dd0b21c1bd9 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-nfs.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-pacemaker.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-pacemaker.png new file mode 100644 index 0000000000000000000000000000000000000000..7681f963f67d2b803fef6fb2c3247384136201f8 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-pacemaker.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-pcs-status.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-pcs-status.png new file mode 100644 index 0000000000000000000000000000000000000000..fb150fba9f6258658702b35caacf98076d1fd109 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-pcs-status.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-pcs.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-pcs.png new file mode 100644 index 0000000000000000000000000000000000000000..283670d7c3d0961ee1cb41345c2b2a013d7143b0 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-pcs.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-qdevice.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-qdevice.png new file mode 100644 index 0000000000000000000000000000000000000000..2964f36c952fc7e62fb7b041fcf6d2de8ead712c Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-qdevice.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-refresh.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..c2678c0c2945acbabfbeae0d5de8924a216bbf31 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-refresh.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-vip-suc.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-vip-suc.png new file mode 100644 index 0000000000000000000000000000000000000000..313ce56e14f931c78dad4349ed57ab3fd7907f50 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-vip-suc.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/HA-vip.png b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-vip.png new file mode 100644 index 0000000000000000000000000000000000000000..d8b417df2e64527d3b29d0289756dfbb01bf66ec Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/HA-vip.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/image.png b/docs/en/25.03/Server/HighAvailability/HA/figures/image.png new file mode 100644 index 0000000000000000000000000000000000000000..7681f963f67d2b803fef6fb2c3247384136201f8 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/image.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/image3.png b/docs/en/25.03/Server/HighAvailability/HA/figures/image3.png new file mode 100644 index 0000000000000000000000000000000000000000..c4d93242e65c503b6e1b6a457e2517f647984a66 Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/image3.png differ diff --git a/docs/en/25.03/Server/HighAvailability/HA/figures/image4.png b/docs/en/25.03/Server/HighAvailability/HA/figures/image4.png new file mode 100644 index 0000000000000000000000000000000000000000..65d0ae11ec810da7574ec72bebf6e1b020c94a0d Binary files /dev/null and b/docs/en/25.03/Server/HighAvailability/HA/figures/image4.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/FAQ1.md b/docs/en/25.03/Server/InstallationUpgrade/Installation/FAQ1.md new file mode 100644 index 0000000000000000000000000000000000000000..4952db34cbfaf732d4c79a1d7ece2aee17673000 --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Installation/FAQ1.md @@ -0,0 +1,66 @@ +# 常见问题与解决方法 + +## **问题1:树莓派启动失败** + +### 问题现象 + +将 openEuler 发布的树莓派镜像刷写入 SD 卡后,树莓派启动失败。 + +### 原因分析 + +刷写 openEuler 发布的树莓派镜像后,树莓派启动失败,大致有以下几种情况: + +1. 下载的镜像文件不完整,请确保该镜像通过完整性校验。 +2. 镜像写入 SD 卡过程中出现问题,多出现在 Windows 环境下使用应用软件刷写镜像到 SD 卡的情况。 + +### 解决方法 + +将完整的镜像重新刷写入 SD 卡。 + +## **问题2:nmcli 命令连接 WIFI 失败** + +### 问题现象 + +执行 `nmcli dev wifi connect SSID password PWD` 命令连接 WIFI 失败。例如提示 `Error: Connection activation failed: (7) Secrets were required, but not provided.` 等错误。 + +### 原因分析 + +执行的命令缺少密码。注意,如果密码中包含特殊字符,需要使用单引号将密码括起来。如果使用 nmcli 命令行连接 WIFI 失败,建议使用 nmtui 字符界面进行连接。 + +### 解决方法 + +执行 `nmtui` 命令进入到 nmtui 字符界面,按照以下步骤连接 WIFI。 + +1. 选择 `Edit a connection`,按 `Enter` 进入编辑网络连接窗口。 +2. 按下键盘右方向键选择 `Add`,按 `Enter` 进入新建网络连接窗口。 +3. 连接类型选择 `Wi-Fi` ,然后按下键盘右方向键选择 `Create`,按 `Enter` 进入 WIFI 编辑连接信息的界面。 +4. WIFI 连接信息界面主要需要编辑以下内容,其他信息根据实际情况而定。编辑结束后选择 `OK`,按 `Enter` 完成编辑并回退到编辑网络连接窗口。 + 1. `Profile name` 栏输入该 WIFI 连接的名称,这里可以使用默认名称,如 `Wi-Fi connection 1`; + 2. `Device` 栏输入要使用的无线网卡接口,这里输入 `wlan0`; + 3. `SSID` 栏输入要连接的 WIFI 的 SSID; + 4. `Security` 栏选择 WIFI 密码加密方式,这里根据实际情况选择,例如选择 `WPA & WPA2 Personal`; + 5. `Password` 栏输入 WIFI 密码。 + +5. 选择 `Back` 回退到最初的 nmtui 字符界面。 +6. 选择 `Activate a connection`,按 `Enter` 进入激活网络连接窗口。 +7. 查看添加的 WIFI 连接是否已激活(已激活的连接名称前有 `*` 标记)。如果未激活,选择该 WIFI 连接,然后按下键盘右方向键选择 `Activate`,按 `Enter` 激活该连接。待激活完成后,选择 `Back`,按 `Enter` 退出该激活界面,回退到最初的 nmtui 字符界面。 +8. 选择 `Quit`,然后按下键盘右方向键选择 `OK`,按 `Enter` 退出 nmtui 字符界面。 + +## **问题3:tensorflow包及相关包安装失败** + +### 问题现象 + +使用yum安装tensorflow及相关包时失败。 + +### 原因分析 + +tensorflow的依赖包暂时未升级至适配tensorflow==2.12.1的版本,因此需要通过pip手动安装其依赖软件。 + +### 解决方法 + +1. yumdownloader下载tensorflow的rpm包:yumdownloader python3-tensorflow。 +2. 使用rpm --nodeps安装这个包:rpm -ivh --nodeps python3-tensorflow。 +3. 安装tensorflow依赖包。 + 1. 使用pip安装依赖:pip3 install tensorflow-estimator==2.12.0 keras==2.12.0 protobuf==3.20.3。 + 2. 使用yum安装其他依赖软件:yum install python3-termcolor python3-future python3-numpy python3-six python3-astunparse python3-google-pasta python3-opt-einsum python3-typing-extensions python3-wrapt python3-h5py python3-grpcio python3-absl-py python3-flatbuffers python3-gast +4. 直接用yum下载相关包,例如python-keras-rl2,直接执行yum install python-keras-rl2。 diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/Installation-Guide1.md b/docs/en/25.03/Server/InstallationUpgrade/Installation/Installation-Guide1.md new file mode 100644 index 0000000000000000000000000000000000000000..8107613c2a03a79a14f0ded0e9f7fc30c41f41f8 --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Installation/Installation-Guide1.md @@ -0,0 +1,177 @@ +# 安装指导 + +本章介绍将“[树莓派镜像刷写入 SD 卡](./Installation-Modes1.md)”后,启用树莓派的主要过程。 + + + +- [安装指导](#安装指导) + - [启动系统](#启动系统) + - [登录系统](#登录系统) + - [配置系统](#配置系统) + - [扩展根目录分区](#扩展根目录分区) + - [连接 WIFI](#连接-wifi) + + + +## 启动系统 + +将刷写镜像后的 SD 卡插入树莓派,通电启用。 + +树莓派硬件相关信息请参考[树莓派官网](https://www.raspberrypi.org/)。 + +## 登录系统 + +登录树莓派有以下两种方式: + +1. 本地登录 + + 树莓派连接显示器(树莓派视频输出接口为 Micro HDMI)、键盘、鼠标后,启动树莓派,可以看到树莓派启动日志输出到显示器上。待树莓派启动成功,输入用户名(root)和密码(openeuler)登录。 + +2. ssh 远程登录 + + 树莓派默认采用 DHCP 的方式自动获取 IP。如果树莓派连接已知路由器,可登录路由器查看,新增的 IP 即为树莓派 IP。例如,树莓派对应 IP 为:192.168.31.109,使用命令 `ssh root@192.168.31.109` 后输入密码 `openeuler`,即可远程登录树莓派。 + +## 配置系统 + +### 扩展根目录分区 + +默认根目录分区空间比较小,在使用之前,需要对分区进行扩容。 + +请按照以下步骤扩展根目录分区: + +1. 在 root 权限下执行 `fdisk -l` 命令查看磁盘分区信息。命令和回显如下: + + ```sh + # fdisk -l + Disk /dev/mmcblk0: 14.86 GiB, 15931539456 bytes, 31116288 sectors + Units: sectors of 1 * 512 = 512 bytes + Sector size (logical/physical): 512 bytes / 512 bytes + I/O size (minimum/optimal): 512 bytes / 512 bytes + Disklabel type: dos + Disk identifier: 0xf2dc3842 + + Device Boot Start End Sectors Size Id Type + /dev/mmcblk0p1 * 8192 593919 585728 286M c W95 FAT32 (LBA) + /dev/mmcblk0p2 593920 1593343 999424 488M 82 Linux swap / Solaris + /dev/mmcblk0p3 1593344 5044223 3450880 1.7G 83 Linux + ``` + + SD 卡对应盘符为 /dev/mmcblk0,包括 3 个分区,分别为 + + - /dev/mmcblk0p1:引导分区 + - /dev/mmcblk0p2:交换分区 + - /dev/mmcblk0p3:根目录分区 + + 这里我们需要将根目录分区 `/dev/mmcblk0p3` 进行扩容。 + +2. 在 root 权限下执行 `fdisk /dev/mmcblk0` 命令进入到交互式命令行界面,按照以下步骤扩展分区,如[图 1](#zh-cn_topic_0151920806_f6ff7658b349942ea87f4521c0256c315)所示。 + + 1. 输入 `p`,查看分区信息。 + + 记录分区 `/dev/mmcblk0p3` 的起始扇区号,即 `/dev/mmcblk0p3` 分区信息中 `Start` 列的值,示例中为 `1593344`。 + + 2. 输入 `d`,删除分区。 + 3. 输入 `3` 或直接按 `Enter`,删除序号为 `3` 的分区,即 `/dev/mmcblk0p3` 分区。 + 4. 输入 `n`,创建新的分区。 + 5. 输入 `p` 或直接按 `Enter`,创建 `Primary` 类型的分区。 + 6. 输入 `3` 或直接按 `Enter`,创建序号为 `3` 的分区,即 `/dev/mmcblk0p3` 分区。 + 7. 输入新分区的起始扇区号,即第 `1` 步中记录的起始扇区号,示例中为 `1593344`。 + + > ![](./public_sys-resources/icon-notice.gif) **须知:** + > 请勿直接按“Enter”或使用默认参数。 + + 8. 按 `Enter`,使用默认的最后一个扇区号作为新分区的终止扇区号。 + 9. 输入 `N`,不修改扇区标记。 + 10. 输入 `w`,保存分区设置并退出交互式命令行界面。 + + **图 1** 分区扩容 + ![](./figures/Partition_expansion.png) + +3. 在 root 权限下执行 `fdisk -l` 命令查看磁盘分区信息,以确保磁盘分区正确。命令和回显如下: + + ```sh + # fdisk -l + Disk /dev/mmcblk0: 14.86 GiB, 15931539456 bytes, 31116288 sectors + Units: sectors of 1 * 512 = 512 bytes + Sector size (logical/physical): 512 bytes / 512 bytes + I/O size (minimum/optimal): 512 bytes / 512 bytes + Disklabel type: dos + Disk identifier: 0xf2dc3842 + + Device Boot Start End Sectors Size Id Type + /dev/mmcblk0p1 * 8192 593919 585728 286M c W95 FAT32 (LBA) + /dev/mmcblk0p2 593920 1593343 999424 488M 82 Linux swap / Solaris + /dev/mmcblk0p3 1593344 31116287 29522944 14.1G 83 Linux + ``` + +4. 在 root 权限下执行 `resize2fs /dev/mmcblk0p3`,增大未加载的文件系统大小。 +5. 执行 `df -lh` 命令查看磁盘空间信息,以确保根目录分区已扩展。 + + > ![](./public_sys-resources/icon-notice.gif) **须知:** + > 如果根目录分区未扩展,可执行 `reboot` 命令重启树莓派之后再在 root 权限下执行 `resize2fs /dev/mmcblk0p3`。 + +### 连接 WIFI + +请按照以下步骤连接 WIFI: + +1. 查看 IP 和网卡信息 + + `ip a` + + 获取无线网卡 wlan0 信息: + + ```sh + 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + inet 127.0.0.1/8 scope host lo + valid_lft forever preferred_lft forever + inet6 ::1/128 scope host + valid_lft forever preferred_lft forever + 2: eth0: mtu 1500 qdisc mq state UP group default qlen 1000 + link/ether dc:a6:32:50:de:57 brd ff:ff:ff:ff:ff:ff + inet 192.168.31.109/24 brd 192.168.31.255 scope global dynamic noprefixroute eth0 + valid_lft 41570sec preferred_lft 41570sec + inet6 fe80::cd39:a969:e647:3043/64 scope link noprefixroute + valid_lft forever preferred_lft forever + 3: wlan0: mtu 1500 qdisc fq_codel state DOWN group default qlen 1000 + link/ether e2:e6:99:89:47:0c brd ff:ff:ff:ff:ff:ff + ``` + +2. 扫描可以连接的 WIFI 信息 + + `nmcli dev wifi` + +3. 连接 WIFI + + 在 root 权限下执行 `nmcli dev wifi connect SSID password PWD` 命令连接 WIFI。 + + 其中,`SSID` 为上一步扫描到的可供连接的 WIFI 的 SSID,`PWD` 为对应 WIFI 的密码。例如,`SSID` 为 `openEuler-wifi`,密码为 `12345678`,则连接该 WIFI 命令为:`nmcli dev wifi connect openEuler-wifi password 12345678`,连接成功: + + ```sh + Device 'wlan0' successfully activated with '26becaab-4adc-4c8e-9bf0-1d63cf5fa3f1'. + ``` + +4. 查看 IP 和无线网卡信息 + + `ip a` + + ```sh + 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + inet 127.0.0.1/8 scope host lo + valid_lft forever preferred_lft forever + inet6 ::1/128 scope host + valid_lft forever preferred_lft forever + 2: eth0: mtu 1500 qdisc mq state UP group default qlen 1000 + link/ether dc:a6:32:50:de:57 brd ff:ff:ff:ff:ff:ff + inet 192.168.31.109/24 brd 192.168.31.255 scope global dynamic noprefixroute eth0 + valid_lft 41386sec preferred_lft 41386sec + inet6 fe80::cd39:a969:e647:3043/64 scope link noprefixroute + valid_lft forever preferred_lft forever + 3: wlan0: mtu 1500 qdisc fq_codel state UP group default qlen 1000 + link/ether dc:a6:32:50:de:58 brd ff:ff:ff:ff:ff:ff + inet 192.168.31.110/24 brd 192.168.31.255 scope global dynamic noprefixroute wlan0 + valid_lft 43094sec preferred_lft 43094sec + inet6 fe80::394:d086:27fa:deba/64 scope link noprefixroute + valid_lft forever preferred_lft forever + ``` diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/Installation-Modes1.md b/docs/en/25.03/Server/InstallationUpgrade/Installation/Installation-Modes1.md new file mode 100644 index 0000000000000000000000000000000000000000..f6f1dea16f42e54420c5b78d23bcf4ad80a08762 --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Installation/Installation-Modes1.md @@ -0,0 +1,110 @@ +# 安装方式介绍 + +> ![](./public_sys-resources/icon-notice.gif) **须知:** +> 硬件仅支持树莓派 3B/3B+/4B。 +> 采用刷写镜像到 SD 卡方式安装。本章节提供 Windows/Linux/Mac 上刷写镜像的操作方法。 +> 本章节使用的镜像是参考“[安装准备](./Installation-Preparations1.md)”获取 openEuler 的树莓派版本镜像。 + + + +- [安装方式介绍](#安装方式介绍) + - [Windows 下刷写镜像](#windows-下刷写镜像) + - [格式化 SD 卡](#格式化-sd-卡) + - [写入 SD 卡](#写入-sd-卡) + - [Linux 下刷写镜像](#linux-下刷写镜像) + - [查看磁盘分区信息](#查看磁盘分区信息) + - [卸载 SD 卡挂载点](#卸载-sd-卡挂载点) + - [写入 SD 卡](#写入-sd-卡-1) + - [Mac 下刷写镜像](#mac-下刷写镜像) + - [查看磁盘分区信息](#查看磁盘分区信息-1) + - [卸载 SD 卡挂载点](#卸载-sd-卡挂载点-1) + - [写入 SD 卡](#写入-sd-卡-2) + + + +## Windows 下刷写镜像 + +本节以 Windows 10 为例,介绍如何在 Windows 环境下将镜像刷写到 SD 卡。 + +### 格式化 SD 卡 + +请按照以下步骤格式化 SD 卡: + +1. 下载并安装格式化 SD 卡工具,以下操作以 SD Card Formatter 格式化工具为例。 +2. 打开 SD Card Formatter,在 “Select card” 中选择需要格式化的 SD 卡的盘符。 + + 若 SD 卡之前未安装过镜像,盘符只有一个。在 “Select card” 中选择需要格式化的 SD 卡对应盘符。 + + 若 SD 卡之前安装过镜像,盘符会有一个或多个。例如,SD 卡对应三个盘符:E、G、H。在 “Select card” 中选择需要格式化的 SD 卡对应 boot 分区盘符 E。 + +3. 在 “Formatting options” 中选择格式化方式。默认为 “Quick format”。 +4. 单击“Format”开始格式化。界面通过进度条显示格式化进度。 +5. 格式化完成后会弹出 “Formatting was successfully completed” 的提示框,单击“确定”完成格式化。 + +### 写入 SD 卡 + +> ![](./public_sys-resources/icon-notice.gif) **须知:** +> 如果获取的是压缩后的镜像文件“openEuler-21.09-raspi-aarch64.img.xz”,需要先将压缩文件解压得到 “openEuler-21.09-raspi-aarch64.img”镜像文件。 + +请按照以下步骤将“openEuler-21.09-raspi-aarch64.img”镜像文件写入 SD 卡: + +1. 下载并安装刷写镜像的工具,以下操作以 Win32 Disk Imager 工具为例。 +2. 右键选择“以管理员身份运行”,打开 Win32 Disk Imager。 +3. 在“映像文件”中选择 img 格式的镜像文件路径。 +4. 在“设备”中选择待写入的 SD 卡盘符。 +5. 单击“写入”。界面通过任务进度条显示写入 SD 卡的进度。 +6. 写入完成后会弹出 “写入成功” 的提示框,单击“OK”完成写入。 + +## Linux 下刷写镜像 + +本节介绍如何在 Linux 环境下将镜像刷写到SD卡。 + +### 查看磁盘分区信息 + +在 root 权限下执行 `fdisk -l` 获取 SD 卡磁盘信息,例如 SD 卡对应磁盘为 /dev/sdb。 + +### 卸载 SD 卡挂载点 + +1. 执行 `df -lh` 命令查看当前已挂载的卷。 +2. 如果 SD 卡对应的分区未挂载,则跳过该步骤;如果 SD 卡对应分区已挂载,如 SD 卡对应的两个分区 /dev/sdb1 和 /dev/sdb3 已挂载,则需要卸载对应分区,在 root 权限下执行以下命令: + + `umount /dev/sdb1` + + `umount /dev/sdb3` + +### 写入 SD 卡 + +1. 如果获取的是压缩后的镜像,需要先执行 `xz -d openEuler-21.09-raspi-aarch64.img.xz` 命令将压缩文件解压得到“openEuler-21.09-raspi-aarch64.img”镜像文件;否则,跳过该步骤。 +2. 将镜像 `openEuler-21.09-raspi-aarch64.img` 刷写入 SD 卡,在 root 权限下执行以下命令: + + `dd bs=4M if=openEuler-21.09-raspi-aarch64.img of=/dev/sdb` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 一般情况下,将块大小设置为 4M。如果写入失败或者写入的镜像无法使用,可以尝试将块大小设置为 1M 重新写入,但是设置为 1M 比较耗时。 + +## Mac 下刷写镜像 + +本节介绍如何在 Mac 环境下将镜像刷写到SD卡。 + +### 查看磁盘分区信息 + +在 root 权限下执行 `diskutil list` 获取 SD 卡磁盘信息,例如 SD 卡对应磁盘为 /dev/disk3。 + +### 卸载 SD 卡挂载点 + +1. 执行 `df -lh` 命令查看当前已挂载的卷。 +2. 如果 SD 卡对应的分区未挂载,则跳过该步骤;如果 SD 卡对应分区已挂载,如 SD 卡对应的两个分区 /dev/disk3s1 和 /dev/disk3s3 已挂载,则需要卸载对应分区,在 root 权限下执行以下命令: + + `diskutil umount /dev/disk3s1` + + `diskutil umount /dev/disk3s3` + +### 写入 SD 卡 + +1. 如果获取的是压缩后的镜像,需要先执行 `xz -d openEuler-21.09-raspi-aarch64.img.xz` 命令将压缩文件解压得到“openEuler-21.09-raspi-aarch64.img”镜像文件;否则,跳过该步骤。 +2. 将镜像 `openEuler-21.09-raspi-aarch64.img` 刷入 SD 卡,在 root 权限下执行以下命令: + + `dd bs=4m if=openEuler-21.09-raspi-aarch64.img of=/dev/disk3` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 一般情况下,将块大小设置为 4m。如果写入失败或者写入的镜像无法使用,可以尝试将块大小设置为 1m 重新写入,但是设置为 1m 比较耗时。 diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/Installation-Preparations1.md b/docs/en/25.03/Server/InstallationUpgrade/Installation/Installation-Preparations1.md new file mode 100644 index 0000000000000000000000000000000000000000..378f77cbbe5d0d92831d4cc9d76ba9e88b5312f3 --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Installation/Installation-Preparations1.md @@ -0,0 +1,100 @@ +# 安装准备 + +介绍安装前需要考虑软硬件兼容性状况,以及相关的配置和准备工作。 + +## 获取安装源 + +在安装开始前,您需要获取 openEuler 发布的树莓派镜像及其校验文件。 + +1. 登录[openEuler Repo](https://repo.openeuler.org/)网站。 +2. 在版本列表单击“openEuler 22.03 LTS SP2”,进入openEuler 22.03 LTS SP2下载列表。 +3. 单击“raspi_img”,进入树莓派镜像的下载列表。 +4. 单击“openEuler-22.03-LTS-SP2-raspi-aarch64.img.xz”,将 openEuler 发布的树莓派镜像下载到本地。 +5. 单击“openEuler-22.03-LTS-SP2-raspi-aarch64.img.xz.sha256sum”,将 openEuler 发布的树莓派镜像的校验文件下载到本地。 + +## 镜像完整性校验 + +### 简介 + +为了防止软件包在传输过程中由于网络原因或者存储设备原因出现下载不完整的问题,在获取到软件包后,需要对软件包的完整性进行校验,通过了校验的软件包才能部署。 + +这里通过对比校验文件中记录的校验值和手动方式计算的文件校验值,判断软件包是否完整。若两个值相同,说明下载的文件完整,否则,下载的文件完整性被破坏,请重新获取软件包。 + +### 前提条件 + +在校验镜像文件的完整性之前,需要准备如下文件: + +镜像文件:openEuler-22.03-LTS-SP2-raspi-aarch64.img.xz + +校验文件:openEuler-22.03-LTS-SP2-raspi-aarch64.img.xz.sha256sum + +### 操作指导 + +文件完整性校验操作步骤如下: + +1. 获取校验文件中的校验值。执行命令如下: + + ```shell + cat openEuler-22.03-LTS-SP2-raspi-aarch64.img.xz.sha256sum + ``` + +2. 计算文件的 sha256 校验值。执行命令如下: + + ```shell + sha256sum openEuler-22.03-LTS-SP2-raspi-aarch64.img.xz + ``` + + 命令执行完成后,输出校验值。 + +3. 对比步骤 1 和步骤 2 计算的校验值是否一致。 + + 如果校验值一致说明下载的文件完整性没有被破坏,如果校验值不一致则可以确认文件完整性已被破坏,需要重新获取。 + +## 安装要求 + +在树莓派环境上安装 openEuler 操作系统,则树莓派需要满足如下的硬件兼容性和最小硬件要求。 + +### 硬件兼容支持 + +openEuler 树莓派版本镜像目前支持树莓派 3B/3B+/4B。 + +### 最小硬件要求 + +openEuler 树莓派版本镜像所需的最小硬件要求如[表1](#tff48b99c9bf24b84bb602c53229e2542)所示。 + +**表 1** 最小硬件要求 + + + + + + + + + + + + + + + + + + + + + + +

部件名称

+

最小硬件要求

+

说明

+

树莓派版本

+
  • 树莓派 3B
  • 树莓派 3B+
  • 树莓派 4B
  • 树莓派 400
+

-

+

内存

+

不小于 2GB(为了获得更好的应用体验,建议至少 4GB)

+

-

+

硬盘

+

为了获得更好的应用体验,建议不小于 8GB

+

-

+
diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/More-Resources.md b/docs/en/25.03/Server/InstallationUpgrade/Installation/More-Resources.md new file mode 100644 index 0000000000000000000000000000000000000000..3694c0654909b4d1d809a54577d87f7df8a63853 --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Installation/More-Resources.md @@ -0,0 +1,4 @@ +# 参考资料 + +- 如何构建树莓派镜像文件 +- 如何使用树莓派 diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/_menu.md b/docs/en/25.03/Server/InstallationUpgrade/Installation/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..87a0a3c321ee6b48315f87a4d81a4e00260309b8 --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Installation/_menu.md @@ -0,0 +1,39 @@ +--- +label: '安装指南' +ismanual: 'Y' +description: '安装 openEuler 操作系统' +children: + - label: '安装在服务器' + href: './install-server.md' + children: + - label: '安装准备' + href: './installation-preparations.md' + - label: '安装方式介绍' + href: './installation-modes.md' + - label: '安装指导' + href: './installation-guideline.md' + - label: '使用kickstart自动化安装' + href: './using-kickstart-for-automatic-installation.md' + - label: '常见问题与解决方法' + href: './faqs.md' + - label: '安装在树莓派' + href: './install-pi.md' + children: + - label: '安装准备' + href: './Installation-Preparations1.md' + - label: '安装方式介绍' + href: './Installation-Modes1.md' + - label: '安装指导' + href: './Installation-Guide1.md' + - label: '常见问题与解决方法' + href: './FAQ1.md' + - label: '更多资源' + href: './More-Resources.md' + - label: 'RISC-V安装指南' + href: './riscv.md' + children: + - label: '虚拟机安装' + href: './riscv_qemu.md' + - label: '更多资源' + href: './riscv_more.md' +--- diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/faqs.md b/docs/en/25.03/Server/InstallationUpgrade/Installation/faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..e7d1f421648dd41da798cfd18b122ff9eee9f37f --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Installation/faqs.md @@ -0,0 +1,341 @@ +# 常见问题与解决方法 + +## **问题1:安装openEuler时选择第二盘位为安装目标,操作系统无法启动** + +### 问题现象 + +安装操作系统时,直接将系统安装到第二块磁盘sdb,重启系统后启动失败。 + +### 原因分析 + +当安装系统到第二块磁盘时,MBR和GRUB会默认安装到第二块磁盘sdb。这样会有下面两种情况: + +1. 如果第一块磁盘中有完整系统,则加载第一块磁盘中的系统启动。 +2. 如果第一块磁盘中没有完好的操作系统,则会导致硬盘启动失败。 + +以上两种情况都是因为BIOS默认从第一块磁盘sda中加载引导程序启动系统,如果sda没有系统,则会导致启动失败。 + +### 解决方法 + +有以下两种解决方案: + +- 当系统处于安装过程中,在选择磁盘(选择第一块或者两块都选择)后,指定引导程序安装到第一块盘sda中。 +- 当系统已经安装完成,若BIOS支持选择从哪个磁盘启动,则可以通过修改BIOS中磁盘启动顺序,尝试重新启动系统。 + +## **问题2:openEuler开机后进入emergency模式** + +### 问题现象 + +openEuler系统开机后进入emergency模式,如下图所示: + +![](./figures/zh-cn_image_0229291264.jpg) + +### 原因分析 + +操作系统文件系统损坏导致磁盘挂载失败,或者io压力过大导致磁盘挂载超时(超时时间为90秒)。 + +系统异常掉电、物理磁盘io性能低等情况都可能导致该问题。 + +### 解决方法 + +1. 用户直接输入root帐号的密码,登录系统。 +2. 使用fsck工具,检测并修复文件系统,然后重启。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > fsck(file system check)用来检查和维护不一致的文件系统。若系统掉电或磁盘发生问题,可利用fsck命令对文件系统进行检查。 用户可以通过“fsck.ext3 -h”、“fsck.ext4 -h”命令查看fsck的使用方法。 + +另外,如果用户需要取消磁盘挂载超时时间,可以直接在“/etc/fstab”文件中添加“x-systemd.device-timeout=0”。如下: + +```sh +# /etc/fstab +# Created by anaconda on Mon Sep 14 17:25:48 2015 +# +# 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/openEuler-root / ext4 defaults,x-systemd.device-timeout=0 0 0 +UUID=afcc811f-4b20-42fc-9d31-7307a8cfe0df /boot ext4 defaults,x-systemd.device-timeout=0 0 0 +/dev/mapper/openEuler-home /home ext4 defaults 0 0 +/dev/mapper/openEuler-swap swap swap defaults 0 0 +``` + +## **问题3:系统中存在无法激活的逻辑卷组时,重装系统失败** + +### 问题现象 + +由于磁盘故障,系统中存在无法激活的逻辑卷组,重装系统出现异常。 + +### 原因分析 + +安装时有激活逻辑卷组的操作,无法激活时会抛出异常。 + +### 解决方法 + +重装系统前如果系统中存在无法激活的逻辑卷组,为了避免重装系统过程出现异常,需在重装前将逻辑卷组恢复到正常状态或者清除这些逻辑卷组。举例如下: + +- 恢复逻辑卷组状态 + 1. 使用以下命令清除vg激活状态, 防止出现“Can't open /dev/sdc exclusively mounted filesystem”。 + + ```sh + # vgchange -a n testvg32947 + ``` + + 2. 根据备份文件重新创建pv。 + + ```sh + # pvcreate --uuid JT7zlL-K5G4-izjB-3i5L-e94f-7yuX-rhkLjL --restorefile /etc/lvm/backup/testvg32947 /dev/sdc + ``` + + 3. 恢复vg信息。 + + ```sh + # vgcfgrestore testvg32947 + ``` + + 4. 重新激活vg。 + + ```sh + # vgchange -ay testvg32947 + ``` + +- 清除逻辑卷组 + + ```sh + # vgchange -a n testvg32947 + # vgremove -y testvg32947 + ``` + +## **问题4:选择安装源出现异常** + +### 问题现象 + +选择安装源后出现:"Error checking software selection"。 + +### 原因分析 + +这种现象是由于安装源中的软件包依赖存在问题。 + +### 解决方法 + +检查安装源是否存在异常。使用新的安装源。 + +## **问题5:如何手动开启kdump服务** + +### 问题现象 + +执行systemctl status kdump命令,显示状态信息如下,提示无预留内存。 + +![](./figures/zh-cn_image_0229291280.png) + +### 原因分析 + +kdump服务需要系统预留一段内存用于运行kdump内核,而当前系统没有为kdump服务预留内存,所以无法运行kdump服务。 + +### 解决方法 + +已安装操作系统的场景 + +1. 修改/boot/efi/EFI/openEuler/grub.cfg,添加crashkernel=1024M,high。 +2. 重启系统使配置生效。 +3. 执行如下命令,检查kdump状态: + + ```sh + # systemctl status kdump + ``` + + 若回显如下,即kdump的状态为active,说明kdump已使能,操作结束。 + + ![](./figures/zh-cn_image_0229291272.png) + +### 参数说明 + +kdump内核预留内存参数说明如下: + +**表 1** crashkernel参数说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

内核启动参数

+

描述

+

缺省值

+

备注

+

crashkernel=X

+

在4G以下的物理内存预留X大小的内存给kdump使用

+

无,用户根据实际情况调整

+

该配置方法只在4G以下内存预留,必须保证4G以下连续可用内存足够预留

+

crashkernel=X@Y

+

在Y起始地址预留X大小的内存给kdump使用

+

无,用户根据实际情况调整

+

需要确保Y起始地址的X大小内存未被其他模块预留

+

crashkernel=X,high

+

在4G以下的物理内存中预留256M大小,在4G以上预留X大小内存给kdump使用

+

无,用户根据实际情况调整,推荐值为1024M,high

+

确保4G以下内存有256M连续可用内存,4G以上有连续X大小内存可预留。实际预留内存大小为256M+X

+

crashkernel=X,low

+

crashkernel=Y,high

+

在4G以下的物理内存中预留X大小,在4G以上预留Y大小内存给kdump使用

+

无,用户根据实际情况调整

+

需要确保4G以下有X大小连续可用内存,4G以上有Y大小连续可用内存。实际预留内存大小为X+Y

+
+ +## **问题6:多块磁盘组成逻辑卷安装系统后,再次安装不能只选其中一块磁盘** + +### 问题现象 + +在安装系统时,如果之前的系统选择多块磁盘组成逻辑卷进行安装,再次安装时,如果只选择了其中的一块或几块磁盘,没有全部选择,在保存配置时提示配置错误,如[图1](#fig115949762617)所示。 + +**图 1** 配置错误提示 +![](./figures/Configuration_error_prompt.png) + +### 原因分析 + +之前的逻辑卷包含了多块磁盘,只在一块磁盘上安装会破坏逻辑卷。 + +### 解决方法 + +因为多块磁盘组成逻辑卷相当于一个整体,所以只需要删除对应的卷组即可。 + +1. 按“Ctrl+Alt+F2”可以切换到命令行,执行如下命令找到卷组。 + + ```sh + # vgs + ``` + + ![](./figures/zh-cn_image_0231657950.png) + +2. 执行如下命令,删除卷组。 + + ```sh + # vgremove euleros + ``` + +3. 执行如下命令,重启安装程序即可生效。 + + ```sh + # systemctl restart anaconda + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 图形模式下也可以按“Ctrl+Alt+F6”回到图形界面,点击[图1](#fig115949762617)右下角的“Refresh”刷新存储配置生效。 + +## **问题7:x86物理机UEFI模式由于security boot安全选项问题无法安装** + +### 问题现象 + +x86物理机安装系统时,由于设置了BIOS选项security boot 为enable(默认是disable),导致系统一直停留在“No bootable device”提示界面,无法继续安装,如[图2](#fig115949762618)所示。 + +**图 2** “No bootable device”提示界面 +![](./figures/No-bootable-device.png) + +### 原因分析 + +开启security boot后,主板会验证引导程序及操作系统 ,若没有用对应的私钥进行签名,则无法通过主板上内置公钥的认证。 + +### 解决方法 + +进入BIOS,设置security boot为disable,重新安装即可。 + +1. 系统启动时,按“F11”,输入密码“Admin@9000”进入BIOS。 + + ![](./figures/BIOS.png) + +2. 选择进入Administer Secure Boot。 + + ![](./figures/security.png) + +3. 设置Enforce Secure Boot为Disabled。 + + ![](./figures/select.png) + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 设置security boot为disable之后,保存退出,重新安装即可。 + +## **问题8:安装openEuler时,软件选择页面选择“服务器-性能工具”,安装后messages日志有pmie_check报错信息** + +### 问题现象 + +安装系统时软件选择勾选服务器-性能工具,会安装pcp相关软件包,正常安装并重启后,/var/log/messages日志文件中会产生报错:pmie_check failed in /usr/share/pcp/lib/pmie。 + +### 原因分析 + +anaconda不支持在chroot环境中安装selinux策略模块,当安装pcp-selinux时,postin脚本安装pcp相关selinux策略模块执行失败,从而导致重启后产生报错。 + +### 解决办法 + +完成安装并重启后,以下方法选择其一。 + +1. 执行如下命令,安装selinux策略模块pcpupstream + + ```sh + # /usr/libexec/pcp/bin/selinux-setup /var/lib/pcp/selinux install "pcpupstream" + ``` + +2. 重新安装pcp-selinux + + ```sh + # sudo dnf reinstall pcp-selinux + ``` + +## **问题9:在两块已经安装了系统的磁盘上进行重复选择,并自定义分区时,安装失败** + +### 问题现象 + +用户在安装操作系统过程中,存在两块都已经安装过的磁盘,此时如果先选择一块盘,进行自定义分区,然后点击取消按钮,再选择第二块盘,并进行自定义分区时,会出现安装失败。 + +![](./figures/cancle_disk.png) +![](./figures/custom_paratition.png) + +### 原因分析 + +用户存在两次选择磁盘的操作,当前点击取消后,再选择第二块磁盘,磁盘信息不正确,导致安装失败。 + +### 解决方法 + +直接选择目标磁盘进行自定义分区,请勿频繁取消操作,如果一定要进行取消重选建议重新安装。 + +### issue访问链接 + + + +## **问题10:安装LSI MegaRAID卡的物理机kdump无法生成vmcore** + +### 问题现象 + +部署好kdump服务后,手动执行`echo c > /proc/sysrq-trigger`命令或由于kernel故障导致kernel宕机,触发kdump启动second kernel过程中,MegaRAID驱动报错“BRCM Debug mfi stat 0x2d,data len requested/completed 0x200/0x0”,报错信息如下图,最终导致无法生成vmcore。 + +![](./figures/Megaraid_IO_Request_uncompleted.png) + +### 原因分析 + +由于默认配置了reset_devices启动参数,second kernel启动过程中会触发设备复位(reset_devices)操作,设备复位操作导致MegaRAID控制器或磁盘状态故障,转储vmcore文件时访问MegaRAID卡的磁盘报错,进而无法生成vmcore。 + +### 解决方法 + +在物理机`etc/sysconfig/kdump`文件中将second kernel默认启动参数`reset_devices`删除,可以规避second kernel启动过程中由于MegaRAID卡驱动复位设备所致IO请求未完成问题,以成功生成vmcore。 +![](./figures/reset_devices.png) diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Advanced_User_Configuration.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Advanced_User_Configuration.png new file mode 100644 index 0000000000000000000000000000000000000000..29fc332ed3ecdc70b2a031d2633a6ec4ec5a9f0b Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Advanced_User_Configuration.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Automatic_installation_complete.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Automatic_installation_complete.png new file mode 100644 index 0000000000000000000000000000000000000000..f2169685ef202bae133ae74fec620ec64aea46df Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Automatic_installation_complete.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/BIOS.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/BIOS.png new file mode 100644 index 0000000000000000000000000000000000000000..d5a96738001c5a910174c030af583bb09ff29ce6 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/BIOS.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/CD-ROM_drive_icon.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/CD-ROM_drive_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9e87cfaf1bdee860b3cbc35150decd8db492f8aa Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/CD-ROM_drive_icon.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Configuration_error_prompt.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Configuration_error_prompt.png new file mode 100644 index 0000000000000000000000000000000000000000..a4eb734b3b84247bb2aa897e74898e8b5375aec8 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Configuration_error_prompt.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Disk_encryption_password.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Disk_encryption_password.png new file mode 100644 index 0000000000000000000000000000000000000000..c76b59d3214da2c55119f0300103be0b9c2d8792 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Disk_encryption_password.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Image_dialog_box.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Image_dialog_box.png new file mode 100644 index 0000000000000000000000000000000000000000..e72253b3d16d4388fa051c73b94e8923020ad467 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Image_dialog_box.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Installation_source.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Installation_source.png new file mode 100644 index 0000000000000000000000000000000000000000..b2ff6ff142722b27b4aa474ca246f5aedc278df8 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Installation_source.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Installation_wizard.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Installation_wizard.png new file mode 100644 index 0000000000000000000000000000000000000000..fc3a96c0cd4b5a2ece94a0b3fc484720440adace Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Installation_wizard.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Keyboard_layout.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Keyboard_layout.png new file mode 100644 index 0000000000000000000000000000000000000000..12447c247e913ff4460dc2e736b1ece57a8d128b Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Keyboard_layout.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Manual_partitioning.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Manual_partitioning.png new file mode 100644 index 0000000000000000000000000000000000000000..4ff41957f520ee0abdf55fbe90cd92dd0ea35f1f Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Manual_partitioning.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Manual_partitioning1.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Manual_partitioning1.png new file mode 100644 index 0000000000000000000000000000000000000000..4097e12f77be60a965c4b00b57d41c19c90619d8 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Manual_partitioning1.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Megaraid_IO_Request_uncompleted.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Megaraid_IO_Request_uncompleted.png new file mode 100644 index 0000000000000000000000000000000000000000..9f5a9e0f03055c59148830c8f8894196acd6861f Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Megaraid_IO_Request_uncompleted.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/NetworkandHostName.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/NetworkandHostName.png new file mode 100644 index 0000000000000000000000000000000000000000..5d77ccbe602dd1ce565e77c48e27628cc9ec591a Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/NetworkandHostName.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/No-bootable-device-page.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/No-bootable-device-page.png new file mode 100644 index 0000000000000000000000000000000000000000..944c658d621f00b18e4aa75eaca420d76c08715c Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/No-bootable-device-page.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/No-bootable-device.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/No-bootable-device.png new file mode 100644 index 0000000000000000000000000000000000000000..944c658d621f00b18e4aa75eaca420d76c08715c Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/No-bootable-device.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Partition_expansion.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Partition_expansion.png new file mode 100644 index 0000000000000000000000000000000000000000..37a6ef7a2371a9a5518f6d2ce0dc6d36fc71fe1b Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Partition_expansion.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Setting_the_System_Boot_Option.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Setting_the_System_Boot_Option.png new file mode 100644 index 0000000000000000000000000000000000000000..682f555c3a6da63e1cf6e6eed402e2851c4a7ebb Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Setting_the_System_Boot_Option.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Target_installation_position.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Target_installation_position.png new file mode 100644 index 0000000000000000000000000000000000000000..5dcf04a4bfa256efef32a1cf7dd146161030381d Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/Target_installation_position.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/cancle_disk.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/cancle_disk.png new file mode 100644 index 0000000000000000000000000000000000000000..ff0e9a143fc14dc725d0b1e770bd54ce874aeec6 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/cancle_disk.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/choice.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/choice.png new file mode 100644 index 0000000000000000000000000000000000000000..0e40f5fd8d73dbcbad6bdcec5d56d3883d54023a Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/choice.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/choicelanguage.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/choicelanguage.png new file mode 100644 index 0000000000000000000000000000000000000000..51dfe50057e0652a34b5c94192c411c356133b24 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/choicelanguage.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/choosesoftware.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/choosesoftware.png new file mode 100644 index 0000000000000000000000000000000000000000..e9f4dbfb6de56498a46752cbebe88ab623366160 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/choosesoftware.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/confignetwork1.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/confignetwork1.png new file mode 100644 index 0000000000000000000000000000000000000000..d46f71cc21fb8f2defab62c08ba5537f225be328 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/confignetwork1.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/createuser.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/createuser.png new file mode 100644 index 0000000000000000000000000000000000000000..a280f355f07f34e590bfcb5c33a16b2201051857 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/createuser.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/custom_paratition.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/custom_paratition.png new file mode 100644 index 0000000000000000000000000000000000000000..0f46bc9fcfbf57cd986661029c6b2c037dac2919 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/custom_paratition.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/dateandtime.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/dateandtime.png new file mode 100644 index 0000000000000000000000000000000000000000..10ff8aceeb1789333833f79a668214eb69e50643 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/dateandtime.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/installation_overview.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/installation_overview.png new file mode 100644 index 0000000000000000000000000000000000000000..fb9c052855bd920532c0cf69c658eaadab628f5f Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/installation_overview.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/installation_procedure.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/installation_procedure.png new file mode 100644 index 0000000000000000000000000000000000000000..06a9d14a166bdfe86c5eec0be7929a7a99c5ea45 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/installation_procedure.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/installsource.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/installsource.png new file mode 100644 index 0000000000000000000000000000000000000000..df788bdb010a1e711eef0446348587dce7b55b95 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/installsource.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/languagesupport.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/languagesupport.png new file mode 100644 index 0000000000000000000000000000000000000000..322a38cfea59362ae595ff204d907ae1fd41dc30 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/languagesupport.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/reset_devices.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/reset_devices.png new file mode 100644 index 0000000000000000000000000000000000000000..70cc2e0138dd48950f4704bd3f1160448d5058a1 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/reset_devices.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/restart_icon.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/restart_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a1b02b2dff42c90845d2491192507ea6967352e3 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/restart_icon.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/restarticon.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/restarticon.png new file mode 100644 index 0000000000000000000000000000000000000000..33bf7cd2e435ff04f3947eb39ba20019b12bf2d2 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/restarticon.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/root_password.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/root_password.png new file mode 100644 index 0000000000000000000000000000000000000000..fe285fc2bfd682e1ef3799e62ef2786507e49372 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/root_password.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/security.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/security.png new file mode 100644 index 0000000000000000000000000000000000000000..59ac7bfcef796fc32d0127a9d6095d32cb282fb2 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/security.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/select.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/select.png new file mode 100644 index 0000000000000000000000000000000000000000..0e40f5fd8d73dbcbad6bdcec5d56d3883d54023a Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/select.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/select_software.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/select_software.png new file mode 100644 index 0000000000000000000000000000000000000000..4b1384943d2770317396be452b137b6602d1dfea Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/select_software.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/selectlanguage.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/selectlanguage.png new file mode 100644 index 0000000000000000000000000000000000000000..4351e637cb673e156864cf5110e68efb3c3e1f2b Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/selectlanguage.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/sourceftp.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/sourceftp.png new file mode 100644 index 0000000000000000000000000000000000000000..6866700da46d0a283cb1585dc425feb79337f726 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/sourceftp.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/sourcenfs.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/sourcenfs.png new file mode 100644 index 0000000000000000000000000000000000000000..430d9433904fef0ac833495ec1ae704acdd9026f Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/sourcenfs.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/startparam.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/startparam.png new file mode 100644 index 0000000000000000000000000000000000000000..661febc759a150367509505577ea7ea216f911be Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/startparam.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/target_install_position.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/target_install_position.png new file mode 100644 index 0000000000000000000000000000000000000000..5dcf04a4bfa256efef32a1cf7dd146161030381d Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/target_install_position.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291229.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291229.png new file mode 100644 index 0000000000000000000000000000000000000000..d245d48dc07e2b01734e21ec1952e89fa9269bdb Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291229.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291236.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291236.png new file mode 100644 index 0000000000000000000000000000000000000000..a32856aa08e459ed0f51f8fcf4c2f51511c12095 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291236.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291243.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291243.png new file mode 100644 index 0000000000000000000000000000000000000000..2418510f855facae4b47129840894490a1eac7ca Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291243.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291247.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291247.png new file mode 100644 index 0000000000000000000000000000000000000000..d67b599b9ab74017c0800529053befed3efab8a7 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291247.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291264.jpg b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291264.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3f0a0658e08010f4f453e558a41e31257783b416 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291264.jpg differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291270.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291270.png new file mode 100644 index 0000000000000000000000000000000000000000..deefef68670d64c131e4c41911a01236158f1dd1 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291270.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291272.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291272.png new file mode 100644 index 0000000000000000000000000000000000000000..e0ad8102bddd886c3bd7a306b088e8a52e2b99c9 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291272.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291280.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291280.png new file mode 100644 index 0000000000000000000000000000000000000000..5754e734c48b23ace2a4fbf1302b820077cd7b71 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291280.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291286.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291286.png new file mode 100644 index 0000000000000000000000000000000000000000..4ffcb081e2c8f82bcc49a65a939f2cd8bd6f949b Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229291286.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229420473.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229420473.png new file mode 100644 index 0000000000000000000000000000000000000000..86c61a4b8e2a5795baff2fc74629924d01d7b97b Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0229420473.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0231657950.png b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0231657950.png new file mode 100644 index 0000000000000000000000000000000000000000..bea985ef710c57aeba16600067304b1005ad92e8 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/figures/zh-cn_image_0231657950.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/install-pi.md b/docs/en/25.03/Server/InstallationUpgrade/Installation/install-pi.md new file mode 100644 index 0000000000000000000000000000000000000000..8481d337ff33f15514737f643fd0b2b6e578a1bf --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Installation/install-pi.md @@ -0,0 +1,3 @@ +# 安装在树莓派 + +本文是介绍 openEuler 操作系统安装在树莓派的方法,使用本手册的用户需要具备基础的 Linux 系统管理知识。 diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/install-server.md b/docs/en/25.03/Server/InstallationUpgrade/Installation/install-server.md new file mode 100644 index 0000000000000000000000000000000000000000..5c112feb9d12020e68916a01fba015125822929e --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Installation/install-server.md @@ -0,0 +1,3 @@ +# 安装在服务器 + +本文是介绍 openEuler 操作系统安装在服务器的方法,使用本手册的用户需要具备基础的 Linux 系统管理知识。 diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/installation-guideline.md b/docs/en/25.03/Server/InstallationUpgrade/Installation/installation-guideline.md new file mode 100644 index 0000000000000000000000000000000000000000..bebb8c46a264a9243baf9c4ae725fa1a0fbcce22 --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Installation/installation-guideline.md @@ -0,0 +1,318 @@ +# 安装指导 + +本章以光盘安装为例介绍安装openEuler,其他安装方式除在启动安装时的引导方式不同外,待启动安装后安装流程相同,在此不再说明。 + +## 启动安装 + +### 使用光盘引导安装 + +在服务器的光驱中加载openEuler安装镜像,重启服务器,具体步骤如下。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 在安装开始前,需要保证服务器启动选项为光驱优先。安装步骤以BMC挂载虚拟光驱进行光盘安装的操作举例。通过物理光驱安装的操作简单,启动安装后的流程相同,在此不再说明。 + +1. 在虚拟界面工具栏中,单击虚拟光驱工具如下图所示。 + + **图 1** 光驱图标 + ![](./figures/CD-ROM_drive_icon.png) + + 弹出镜像对话框,如下图所示。 + + **图 2** 镜像对话框 + ![](./figures/Image_dialog_box.png) + +2. 在镜像对话框中,选择“镜像文件”, 并单击“...”。弹出“打开”对话框。 +3. 选择镜像文件,单击“打开”。然后在镜像对话框中,单击“连接”。当“连接”显示为“断开”后,表示虚拟光驱已连接到服务器。 +4. 在工具栏中,单击重启工具重启设备,如下图所示。 + + **图 3** 重启图标 + ![](./figures/restarticon.png) + +### 安装引导界面 + +系统使用引导介质完成引导后会显示引导菜单。该引导菜单除启动安装程序外还提供一些选项。安装系统时,默认采用“Test this media & install openEuler 21.09”方式进行安装。如果要选择默认选项之外的选项,请使用键盘中的“↑”和“↓”方向键进行选择,并在选项为高亮状态时按“Enter”。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 如果60秒内未按任何键,系统将从默认选项“Test this media & install openEuler 21.09”自动进入安装界面。 +> 安装物理机时,如果使用键盘上下键无法选择启动选项,按“Enter”键无响应,可以单击BMC界面上的鼠标控制图标“![](./figures/zh-cn_image_0229420473.png)”,设置“键鼠复位”。 + +**图 4** 安装引导界面 +![](./figures/Installation_wizard.png) + +安装引导选项说明如下: + +- Install openEuler 21.09 —— 在您的服务器上使用图形用户界面模式安装。 + +- Test this media & install openEuler 21.09 —— 默认选项,在您的服务器上使用图形用户界面模式安装,但在启动安装程序前会进行安装介质的完整性检查。 + +- Troubleshooting —— 问题定位模式,系统无法正常安装时使用。进入问题定位模式后,有如下两个选项。 + - Install openEuler 21.09 in basic graphics mode —— 简单图形安装模式,该模式下在系统启动并运行之前不启动视频驱动程序。 + - Rescue the openEuler system —— 救援模式,用于修复系统。该模式下输出定向到VNC或BMC(Baseboard Management Controller)端,串口不可用。 + +在安装引导界面,按“e”进入已选选项的参数编辑界面,按“c”进入命令行模式。 + +### 图形化模式安装 + +在“安装引导界面”中选择“Test this media & install openEuler 21.09”进入图形化模式安装。 + +可以通过键盘操作图形化安装程序。 + +- “Tab”、“shift Tab”:界面控件(按钮、区域框、复选框等)间的移动。 +- “↑”、“↓”方向键:列表里的移动。 +- “←”、“→”方向键:水平工具条和表条间移动。 +- “空格”、“Enter”:选择或删除高亮显示的选项、展开或折叠下拉菜单。 +- “Alt”+“快捷键”:选择快捷键所在的控件,其中快捷键可通过按住Alt高亮(加下划线)显示。 + +## 设置安装程序语言 + +启动安装后,在进入安装程序主界面之前,系统会提示用户设置安装过程中使用的语言。当前默认为英语,用户可根据实际情况进行调整,如[图5](#zh-cn_topic_0186390093_zh-cn_topic_0122145864_fig144630179151)所示,选择“中文”。 + +**图 5** 选择语言 +![](./figures/selectlanguage.png) + +完成设置后,单击“继续”,进入安装设置主界面。 + +如果您想退出安装,可以单击“退出”并在弹出的“您确定要退出安装程序吗?”对话框中单击“是”重新进入“安装引导界面”。 + +## 进入安装界面 + +系统安装程序正常启动后,会进入[图6](#zh-cn_topic_0186390094_zh-cn_topic_0122145883_fig5969171592212)所示的安装设置主界面。用户可以进行时间、语言、安装源、网络、安装位置等相关设置。 + +部分配置项会有告警符号,用户完成该选项配置后,告警符号消失。当界面上不存在告警符号时,用户才能单击“开始安装”进行系统安装。 + +如果您想退出安装,可以单击“退出”并在弹出的“您确定要退出安装程序吗?”对话框中单击“是”重新进入“安装引导界面”。 + +**图 6** 安装概览 +![](./figures/installation_overview.png) + +## 设置键盘 + +在“安装概览”页面中选择“键盘”,用户可以在系统中添加或者删除多个键盘布局。 + +- 要查看键盘布局,请在左侧选框中单击选中该键盘布局,然后单击下面的“键盘”按钮。 +- 要测试键盘布局,请在左侧选框中添加键盘布局,然后在右上角键盘图标处进行点击切换为目标键盘,单击右侧文本框内部,输入文本以确认所选键盘布局可正常工作。 + +**图 7** 键盘布局 +![](./figures/Keyboard_layout.png) + +设置完成后,请单击左上角“完成”返回“安装概览”页面。 + +## 设置系统语言 + +在“安装概览”页面中选择“语言支持”,设置系统的语言。如[图8](#zh-cn_topic_0186390098_zh-cn_topic_0122145772_fig187301927172619)所示,用户也可根据实际情况进行调整,选择“中文”。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 若选择“中文”,系统安装完成后,使用VNC登录不支持中文显示,使用串口登录支持中文显示,使用SSH登录时是否支持中文显示与使用的SSH客户端有关。若选择“English”,则无影响。 + +**图 8** 语言支持 +![](./figures/languagesupport.png) + +设置完成后,请单击左上角“完成”返回“安装概览”页面。 + +## 设置时间和日期 + +在“安装概览”页面中选择“时间和日期”,设置系统的时区、日期、时间等。 + +设置时区时,用户可通过页面顶部的“地区”和“城市”下拉菜单中进行选择,如[图9](#zh-cn_topic_0186390096_zh-cn_topic_0122145900_fig1260162652312)所示。 + +如果您所在城市没有出现在下拉菜单中,请选择同一时区中离您最近的城市。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 手动设置时区时,请先关闭右上角“网络时间”同步开关。 +> 如需使用网络时间,请保证网络能连通远程NTP服务器,设置网络具体请参见“[设置网络和主机名](#设置网络和主机名)”。 + +**图 9** 日期和时间 +![](./figures/dateandtime.png) + +设置完成后,请单击左上角“完成”返回“安装概览”页面。 + +## 设置安装源 + +在“安装概览”页面中选择“安装源”,指定安装源的位置。 + +- 当使用完整光盘安装,安装程序会自动探测并显示安装源信息,用户直接使用默认配置即可,不需要进行设置,如[图10](#zh-cn_topic_0186390100_zh-cn_topic_0144427079_fig93633295132)所示。 + + **图 10** 安装源 + ![](./figures/Installation_source.png) + +- 当使用网络源进行安装的时候,需设置网络源的 URL。 + + - http 或 https 方式 + + http 或 https 方式的安装源如下图所示。输入框内容以实际版本发布的安装源地址为准,如 ,其中 openEuler-24.03-LTS-SP1 为版本号,x86_64 为CPU 架构,可根据实际情况输入。 + + ![](./figures/installsource.png) + + 如果https服务器使用的是私有证书,则需要在安装引导界面按“e”进入已选选项的参数编辑界面,在参数中增加 inst.noverifyssl 参数。 + + - ftp 方式 + + ftp 方式的安装源如下图所示,输入框内容根据的 ftp 地址输入。 + + ![](./figures/sourceftp.png) + + ftp服务器需要用户自己搭建,将iso镜像进行挂载,挂载出的文件拷贝到ftp的共享目录中。其中x86_64为CPU 架构,可根据实际情况使用镜像。 + + - nfs 方式 + + nfs 方式的安装源如下图所示,输入框内容根据的 nfs 地址输入。 + + ![](./figures/sourcenfs.png) + + nfs服务器需要用户自己搭建,将iso镜像进行挂载,挂载出的文件拷贝到nfs的共享目录中。其中x86_64为CPU 架构,可根据实际情况使用镜像。 + +安装过程中,如果“设置安装源”有疑问,可参考“[选择安装源出现异常](./安装在服务器常见问题与解决方法.md#问题4选择安装源出现异常)”。 + +设置完成后,请单击左上角“完成”返回“安装概览”页面。 + +## 选择安装软件 + +在“安装概览”页面中选择“软件选择”,指定需要安装的软件包。 + +用户需要根据实际的业务需求,在左侧选择一个“最小安装”,在右侧选择安装环境的附加选项,如[图11](#zh-cn_topic_0186390261_zh-cn_topic_0122145865_fig03031519101414)所示。 + +**图 11** 软件选择 +![](./figures/choosesoftware.png) + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> (1)在最小安装的环境下,并非安装源中所有的包都会安装。如果用户需要使用的包未安装,可将安装源挂载到本地制作repo源,通过DNF工具单独安装。 +> (2)选择“虚拟化主机”时会默认安装虚拟化组件qemu、libvirt、edk2,且可在附加选项处选择是否安装ovs等组件。 + +设置完成后,请单击左上角“完成”返回“安装概览”页面。 + +## 设置安装目的地 + +在“安装概览”页面中选择“安装目的地”,设置操作系统的安装磁盘及分区。 + +在[图12](#fig1195417125015)所示的页面中您可以看到计算机中的本地可用存储设备。 + +**图 12** 安装目标位置 +![](./figures/Target_installation_position.png) + +### 存储配置 + +在“安装目标位置”界面,您需要进行存储配置以便对系统分区。您可以手动配置分区,也可以选择让安装程序自动分区。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> (1)在进行分区时,出于系统性能和安全的考虑,建议您划分如下单独分区:/boot、/var、/var/log 、/var/log/audit、/home、/tmp。 分区建议如[表1](#table1)所示。 +> (2)系统如果配置了swap分区,当系统的物理内存不够用时,会使用swap分区。虽然 swap分区可以增大物理内存大小的限制,但是如果由于内存不足使用到swap分区,会增加系统的响应时间,性能变差。因此在物理内存充足或者性能敏感的系统中,不建议配置swap分区。 +> (3)如果需要拆分逻辑卷组则需要选择“自定义”进行手动分区,并在“手动分区”界面单击“卷组”区域中的“修改”按钮重新配置卷组。 + +**表1** 磁盘分区建议 + +| 分区类型 | 逻辑挂载点 | 分区大小 | 说明 | +| --- | --- | --- | --- | +| 主分区 | / | 20G | 根目录,用于安装操作系统。 | +| 主分区 | /boot | 1G | 引导分区。 | +| 主分区 | /swap | 16G | 交换分区。 | +| 逻辑分区 | /home | 1G | 存放本地用户数据。 | +| 逻辑分区 | /tmp | 10G | 存放临时文件。 | +| 逻辑分区 | /var | 5G | 存放守护进程和其他系统服务进程的动态数据。 | +| 逻辑分区 | /var/log | 10G | 存放系统日志数据。 | +| 逻辑分区 | /var/log/audit | 2G | 存放系统审计日志数据。 | +| 逻辑分区 | /usr| 5G | 存放可共享和只读的应用程序。 | +| 逻辑分区 | /var/tmp | 5G | 存放系统重启过程中可以保留的临时文件。 | +| 逻辑分区 | /opt | 剩余磁盘空间大小。 | 用于安装应用软件。 | + +**自动**分区 + +如果是在未使用过的存储设备中执行全新安装,或者不需要保留该存储设备中任何数据,建议选择“自动”进行自动分区。设置完成后,请单击“完成”返回“安装概览”页面。 + +**自定义**分区 + +若用户需进行手动分区,选择“自定义”按钮,并单击左上角“完成”,出现手动分区界面。 + +在“手动分区”界面可以通过如下两种方式进行分区,分区完成后如[图13](#fig1277151815248)所示。 + +- 自动创建:在界面单击“点击这里自动创建它们”,系统会根据可用的存储空间,自动分出5个挂载点:/boot、/、/home、/boot/efi、swap。 + +- 手动创建:单击“![](./figures/zh-cn_image_0229291243.png)”添加新挂载点,建议每个挂载点的期望容量不超过可用空间。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 若设置的挂载点期望容量超过了可用空间,系统将剩余的可用空间全部分配给该挂载点。 + +**图 13** 手动分区 +![](./figures/Manual_partitioning.png) + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 如果选择非 UEFI 引导,则不需要 /boot/efi 分区。若选择 UEFI 引导,则必须有 /boot/efi 分区。 + +设置完成后,请单击左上角”完成“按钮,弹出“更改摘要”对话框,提示更改产生的变更信息。 + +点击“接受更改”,返回“安装概览”页面。 + +## 设置网络和主机名 + +在“安装概览”页面中选择“网络和主机名”,设置系统的网络功能。 + +安装程序会自动探测可本地访问的接口。探测到的接口列在左侧方框中,右侧显示相应的接口详情,如[图14](#zh-cn_topic_0186390264_zh-cn_topic_0122145831_fig123700157297)所示。用户可以通过页面右上角的开关,来开启或者关闭网络接口。开关默认是关闭状态,若设置安装源选择的是在网络上安装,需要开启开关。用户还可以单击“配置”以配置选中的接口。勾选“自动以优先级连接”选项,即可将该网卡设置为开机自启动,如[图15](#zh-cn_topic_0186390264_zh-cn_topic_0122145831_fig6)所示。 + +用户可在页面下方“主机名”字段输入主机名。主机名可以是完全限定域名(FQDN),其格式为hostname.domainname;也可以是简要主机名,其格式为hostname。 + +**图 14** 网络和主机名 +![](./figures/NetworkandHostName.png) + +**图 15** 配置网络 +![](./figures/confignetwork1.png) + +设置完成后,请单击左上角“完成”返回“安装概览”页面。 + +## 设置Root帐户 + +在“安装概览”页面中选择“Root帐户”,弹出设置“ROOT帐户”界面,如[图16](#zh-cn_topic_0186390266_zh-cn_topic_0122145909_fig1323165793018)所示,根据[密码复杂度](#密码复杂度)输入密码并再次输入密码进行确认。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> root帐户是用来执行关键系统管理任务,不建议您在日常工作及系统访问时使用root帐户。 +> 在“ROOT帐户”界面若选择“禁用root帐户”则root帐户将禁用。 + +**图 16** root帐户 +![](./figures/root_password.png) + +### 密码复杂度 + +用户设置的root用户密码或新创建用户的密码均需要满足密码复杂度要求,否则会导致密码设置或用户创建失败。设置密码的复杂度的要求如下: + +1. 口令长度至少8个字符。 +2. 口令至少包含大写字母、小写字母、数字和特殊字符中的任意3种。 +3. 口令不能和帐号一样。 +4. 口令不能使用字典词汇。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 在已装好的openEuler环境中,可以通过`cracklib-unpacker /usr/share/cracklib/pw_dict dictionary.txt`命令导出字典库文件dictionary.txt,用户可以查询密码是否在该字典中。 + +完成设置后,单击左上角的“完成”返回“安装概览”页面。 + +## 创建用户 + +在“安装概览”页面中选择“创建用户”,弹出“创建用户”的界面如[图17](#zh-cn_topic_0186390266_zh-cn_topic_0122145909_fig1237715313319)所示。输入用户名,并设置密码。另外您还可以通过“高级”选项设置用户主目录、用户组等,如[图18](#zh-cn_topic_0186390266_zh-cn_topic_0122145909_fig128716531312)所示。 + +**图 17** 创建用户 +![](./figures/createuser.png) + +**图 18** 高级用户配置 +![](./figures/Advanced_User_Configuration.png) + +完成设置后,单击左上角的“完成”返回“安装概览”页面。 + +## 开始安装 + +在安装界面上完成所有必填选项的配置后,界面上的警告会消失。此时,用户可以单击“开始安装”进行系统安装。 + +## 安装过程 + +开始安装后会出现进度页面,显示安装进度及所选软件包写入系统的进度,如[图19](#zh-cn_topic_0186390266_zh-cn_topic_0122145909_fig1590863119306)所示。 + +>![](./figures/zh-cn_image_0229291229.png) +>若系统安装过程中,单击“退出”,或复位、下电服务器,则安装过程被中断,系统将不可用,需要重新进行安装。 + +**图 19** 安装过程 +![](./figures/installation_procedure.png) + +## 安装完成 + +安装过程执行完成后,openEuler完成安装,单击“重启系统”后,系统将重新启动。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> - 如果当前使用物理光盘安装操作系统,且在重启过程中安装光盘没有自动弹出,请手动取出光盘,则可以直接进入openEuler命令行登录界面。 +> - 如果当前使用虚拟光驱安装操作系统,则需要修改服务器的启动项为“硬盘”,然后重启服务器,则可以直接进入openEuler命令行登录界面。 diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/installation-modes.md b/docs/en/25.03/Server/InstallationUpgrade/Installation/installation-modes.md new file mode 100644 index 0000000000000000000000000000000000000000..d48819da7728aab973b279fc299191d7ccb7853d --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Installation/installation-modes.md @@ -0,0 +1,198 @@ +# 安装方式介绍 + +> ![](./public_sys-resources/icon-notice.gif) **须知:** +> 硬件服务器仅支持Taishan 200服务器和FusionServer Pro 机架服务器,具体支持的服务器型号可参考“[硬件兼容支持](./安装准备.html#硬件兼容支持)”;虚拟化平台仅支持openEuler自有的虚拟化组件(HostOS为openEuler,虚拟化组件为发布包中的qemu、KVM)创建的虚拟化平台和华为公有云的x86虚拟化平台。 +> 安装方式当前仅支持光盘、USB盘安装、网络安装、qcow2镜像安装和私有镜像安装。其中仅华为公有云的x86虚拟化平台支持私有镜像安装。 + + + +- [安装方式介绍](#安装方式介绍) + - [通过光盘安装](#通过光盘安装) + - [准备安装源](#准备安装源) + - [启动安装](#启动安装) + - [通过USB盘安装](#通过usb盘安装) + - [准备安装源](#准备安装源-1) + - [启动安装](#启动安装-1) + - [使用PXE通过网络安装](#使用pxe通过网络安装) + - [通过qcow2镜像安装](#通过qcow2镜像安装) + - [制作qcow2镜像](#制作qcow2镜像) + - [启动安装](#启动安装-2) + - [通过私有镜像安装](#通过私有镜像安装) + - [制作私有镜像](#制作私有镜像) + - [启动安装](#启动安装-3) + + + +## 通过光盘安装 + +本节介绍如何使用或者制作光盘安装源,并介绍相应的操作步骤,指导用户进行安装。 + +### 准备安装源 + +如果您获取的是系统安装光盘,那么可以直接使用光盘安装系统。如果您获取的是系统ISO镜像,可以通过刻录软件将系统的ISO镜像刻录到DVD中,使用刻录完成的DVD安装系统。 + +### 启动安装 + +根据以下步骤启动安装程序: + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 您需要先设置您的系统优先从光盘进行启动引导。以BIOS为例,您需要将“Boot Type Order”中的“CD/DVD-ROM Drive”选项调整到首位。 + +1. 断开所有安装不需要的驱动器,比如USB。 +2. 启动您的计算机系统。 +3. 在计算机中插入安装光盘。 +4. 重启计算机系统。 + +在短暂的延迟后会出现图形化引导界面,该界面包含不同引导选项。如果您在一分钟内未进行任何操作,安装程序将自动以默认选项开始运行。 + +## 通过USB盘安装 + +本节介绍如何制作USB盘安装源,并介绍基本的操作步骤,指导用户进行安装。 + +### 准备安装源 + +您需要注意USB盘容量的大小,它必须有足够的空间放下整个镜像,建议USB盘空间大于16G。 + +1. 将USB盘连接到该系统中,并执行 dmesg 命令查看相关的日志信息。在该日志的最后可以看到刚刚连接的USB盘所生成的一组信息,应类似如下: + + ```sh + [ 170.171135] sd 5:0:0:0: [sdb] Attached SCSI removable disk + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 连接的USB盘名称以sdb进行举例。 + +2. 切换为root用户。使用su命令,需要输入相应的密码。 + + ```sh + su - root + ``` + +3. 确保USB盘没有被挂载。使用如下命令进行查询: + + ```sh + # findmnt /dev/sdb + ``` + + - 如果执行此命令后无输出,表明未挂载,可以继续执行下一步。 + + - 如果输出以下信息,表明USB盘已经自动挂载。 + + ```sh + # findmnt /dev/sdb + TARGET SOURCE FSTYPE OPTIONS + /mnt/iso /dev/sdb iso9660 ro,relatime + ``` + + 此时,您需要使用umount命令卸载该设备。 + + ```sh + # umount /mnt/iso + ``` + +4. 使用dd命令将ISO安装镜像直接写入USB盘: + + ```sh + # dd if=/path/to/image.iso of=/dev/device bs=blocksize + ``` + + 使用您下载的ISO镜像文件的完整路径替换 /path/to/image.iso,使用之前由 dmesg 命令给出的设备名称替换device,同时设置合理的块大小(例如:512k)替换 blocksize,这样可以加快写入进度。 + + 例如:如果该ISO镜像文件位于 /home/testuser/Downloads/openEuler-21.09-aarch64-dvd.iso,同时探测到的设备名称为sdb,则该命令如下: + + ```sh + # dd if=/home/testuser/Downloads/openEuler-21.09-aarch64-dvd.iso of=/dev/sdb bs=512k + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 如isolinux描述,由mkisofs命令创建的ISO 9660 文件系统会通过BIOS固件启动,但只能从CD、DVD和BD等介质启动。所以在使用dd命令制作x86的启动U盘前需要使用 isohybrid -u your.iso 对iso进行处理,然后正常使用dd命令将iso写入u盘即可。(该问题仅影响X86)。 + +5. 等待镜像写入完成,拔掉USB盘。 + + 镜像写入过程中不会有进度显示,当\#号再次出现时,执行如下命令将数据同步写入磁盘。退出root帐户,拔掉USB盘。此时,您可以使用该USB盘作为系统的安装源。 + + ```bash + # sync + ``` + +### 启动安装 + +请根据以下步骤启动安装程序: + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 您需要先设置您的系统优先从USB进行启动引导。以BIOS为例,您需要将“Boot Type Order”中的USB选项调整到首位。 + +1. 断开所有安装不需要的驱动器。 +2. 打开您的计算机系统。 +3. 在计算机中插入USB盘。 +4. 重启计算机系统。 + +在短暂的延迟后会出现图形化引导页面,该页面包含不同引导选项。如果您在一分钟内未进行任何操作,安装程序将自动开始安装。 + +## 使用PXE通过网络安装 + +要使用 PXE 引导,您需要正确配置服务器以及您的计算机需拥有支持 PXE 的网络接口。 + +如果目标硬件安装有支持PXE的网络接口卡,我们可以配置它从其他网络系统的文件而不是本地介质(如光盘)来引导计算机并执行Anaconda安装程序。 + +对于PXE网络安装,客户机通过支持PXE的网卡,向网络发送请求DHCP信息的广播,请求IP地址等信息。DHCP服务器给客户机提供一个IP地址和其他网络信息如域名服务器、ftp服务器(它提供启动安装程序所必须的文件)的IP地址或主机名,以及服务器上文件的位置。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 此处不详细讨论tftp、DHCP、http等服务器配置,相关详细配置请参考“[全自动化安装指导](./使用kickstart自动化安装.html#全自动化安装指导)”。 + +## 通过qcow2镜像安装 + +本节介绍如何使用或者制作qcow2镜像,并介绍相应的操作步骤,指导用户进行安装。 + +### 制作qcow2镜像 + +1. 安装qemu-img软件包。 + + ```sh + # dnf install -y qemu-img + ``` + +2. 使用qemu-img工具的create命令,创建镜像文件,命令格式为: + + ```sh + qemu-img create -f -o + ``` + + 其中,各参数含义如下: + + - _imgFormat_ :镜像格式,取值为raw、qcow2等。 + - _fileOption_ :文件选项,用于设置镜像文件的特性,如指定后端镜像文件,压缩,加密等特性。 + - _fileName_ :文件名称。 + - _diskSize_ :磁盘大小,用于指定块磁盘设备的大小,支持的单位有K、M、G、T,分别代表KiB、MiB、GiB、TiB。 + + 例如,创建一个磁盘设备大小为32GB、格式为qcow2的镜像文件openEuler-imge.qcow2,命令和回显如下: + + ```sh + $ qemu-img create -f qcow2 openEuler-image.qcow2 32G + Formatting 'openEuler-image.qcow2', fmt=qcow2 size=34359738368 cluster_size=65536 lazy_refcounts=off refcount_bits=16 + ``` + +### 启动安装 + +根据以下步骤启动安装程序: + +1. 准备qcow2镜像文件。 +2. 准备虚拟机网络。 +3. 准备UEFI引导工具集EDK II。 +4. 准备虚拟机XML配置文件。 +5. 创建虚拟机。 +6. 启动虚拟机。 + +各步骤详细的操作请参考《[虚拟化用户指南](../../../Virtualization/VirtualizationPlatform/Virtualization/virtualization.md)》。 + +## 通过私有镜像安装 + +本节介绍如何使用或者制作私有镜像,并介绍相应的操作步骤,指导用户进行安装。 + +### 制作私有镜像 + +制作私有镜像的方法请参见[《镜像服务用户指南》](https://support.huaweicloud.com/usermanual-ims/zh-cn_topic_0013901628.html)。 + +### 启动安装 + +华为公有云的x86虚拟化平台的启动请参见[弹性云服务器 ECS的用户指南](https://support.huaweicloud.com/wtsnew-ecs/index.html)。 diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/installation-preparations.md b/docs/en/25.03/Server/InstallationUpgrade/Installation/installation-preparations.md new file mode 100644 index 0000000000000000000000000000000000000000..8fda4a247116032a9a263a9032086d3350c0fedc --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Installation/installation-preparations.md @@ -0,0 +1,108 @@ +# 安装准备 + +介绍安装前需要考虑软硬件兼容性状况,以及相关的配置和准备工作。 + +## 获取安装源 + +在安装开始前,您需要获取openEuler的发布包和校验文件。 + +请按以下步骤获取openEuler的发布包和校验文件: + +1. 登录[openEuler社区](https://openeuler.org)网站。 +2. 单击“下载”。 +3. 单击“社区发行版”,显示版本列表。 +4. 在版本列表的“openEuler 22.03 LTS SP2”版本处单击“前往下载”按钮,进入openEuler 22.03_LTS_SP2版本下载列表。 +5. 根据实际待安装环境的架构和场景选择需要下载的 openEuler 的发布包和校验文件。 + 1. 若为AArch64架构。 + 1. 单击“AArch64”。 + 2. 若选择本地安装,选择“Offline Standard ISO”或者“Offline Everything ISO”对应的“立即下载”将发布包 “openEuler-22.03-LTS-SP2-aarch64-dvd.iso”下载到本地。 + 3. 若选择网络安装,选择“Network Install ISO”将发布包 “openEuler-22.03-LTS-SP2-netinst-aarch64-dvd.iso”下载到本地。 + 2. 若为x86_64架构。 + 1. 单击“x86_64”。 + 2. 若选择本地安装,选择“Offline Standard ISO”或者“Offline Everything ISO”对应的“立即下载”将发布包 “openEuler-22.03-LTS-SP2-x86_64-dvd.iso”下载到本地。 + 3. 若选择网络安装,选择“Network Install ISO”将发布包 “openEuler-22.03-LTS-SP2-netinst-x86_64-dvd.iso ”下载到本地。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> - 网络安装方式的 ISO 发布包较小,在有网络的安装环境可以选择网络安装方式。 +> - AArch64架构的发布包支持UEFI模式,x86\_64架构的发布包支持UEFI模式和Legacy模式。 + +## 发布包完整性校验 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 本章节以AArch64架构的发布包完整性校验为例,x86\_64架构的发布包完整性校验的操作方法相同。 + +### 简介 + +为了确认软件包在传输过程中由于网络原因或者存储设备原因是否出现下载不完整的问题,在获取到软件包后,需要对软件包的完整性进行校验,通过了校验的软件包才能部署。 + +这里通过对比校验文件中记录的校验值和手动方式计算的iso文件校验值,判断软件包是否完整。若两个值相同,说明iso文件完整,否则,iso完整性被破坏,请重新获取iso发布包。 + +### 前提条件 + +在校验发布包完整性之前,需要准备如下文件: + +- iso文件:openEuler-22.03-LTS-SP2-aarch64-dvd.iso。 + +- 校验文件:ISO对应完整性校验值,复制保存对应的ISO值。 + +### 操作指导 + +文件完整性校验操作步骤如下: + +1. 计算文件的sha256校验值。执行命令如下: + + ```sh + sha256sum openEuler-22.03-LTS-SP2-aarch64-dvd.iso + ``` + + 命令执行完成后,输出校验值。 + +2. 对比步骤1计算的校验值与对刚刚复制的SHA256的值是否一致。 + + 如果校验值一致说明iso文件破坏,如果校验值不一致则可以确认文件完整性已被破坏,需要重新获取。 + +## 物理机的安装要求 + +若需要在物理机环境上安装openEuler操作系统,则物理机需要满足如下的硬件兼容性和最小硬件要求。 + +### 硬件兼容支持 + +openEuler安装时,应注意硬件兼容性方面的问题,当前已支持的服务器类型请参考[兼容性列表](https://www.openeuler.org/zh/compatibility/)。 + +### 最小硬件要求 + +openEuler所需的最小硬件要求如[表2](#tff48b99c9bf24b84bb602c53229e2541)所示。 + +**表 2** 最小硬件要求 + +| 部件名称 | 最小硬件要求 | +| :---- | :---- | +| 架构 | AArch64或x86_64 | +| CPU | 2个CPU | +| 内存 | 不小于4GB(为了获得更好的应用体验,建议不小于8GB) | +| 硬盘 | 不小于32GB(为了获得更好的应用体验,建议不小于120GB) | + +## 虚拟机的安装要求 + +若需要在虚拟机环境上安装openEuler操作系统,则虚拟机需要满足如下的虚拟化平台兼容性和最小虚拟化要求。 + +### 虚拟化平台兼容性 + +openEuler安装时,应注意虚拟化平台兼容性的问题,当前已支持的虚拟化平台为: + +- openEuler自有的虚拟化组件(HostOS为openEuler,虚拟化组件为发布包中的qemu、KVM)创建的虚拟化平台。 +- 华为公有云的x86虚拟化平台。 + +### 最小虚拟化空间要求 + +openEuler所需的最小虚拟化空间要求如[表3](#tff48b99c9bf24b84bb602c53229e2541)所示。 + +**表 3** 最小虚拟化空间要求 + +| 部件名称 | 最小虚拟化空间要求 | +| :---- | :---- | +| 架构 | AArch64或x86_64 | +| CPU | 2个CPU | +| 内存 | 不小于4GB(为了获得更好的应用体验,建议不小于8GB) | +| 硬盘 | 不小于32GB(为了获得更好的应用体验,建议不小于120GB) | diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/installation.md b/docs/en/25.03/Server/InstallationUpgrade/Installation/installation.md new file mode 100644 index 0000000000000000000000000000000000000000..73d369e0dabf5156dd4b7d120a8d93331981a7c6 --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Installation/installation.md @@ -0,0 +1,5 @@ +# 安装指南 + +本文档主要介绍openEuler操作系统安装方法,以指导用户顺利完成openEuler操作系统安装。 + +本文档适用于所有使用openEuler操作系统的用户,特别是初次使用或想了解openEuler的用户,包括系统工程师、管理员及维护人员等。使用本手册的用户需要具备基础的Linux系统管理知识。 diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-caution.gif b/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-caution.gif differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-danger.gif b/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-danger.gif differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-note.gif b/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-notice.gif b/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-notice.gif differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-tip.gif b/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-tip.gif differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-warning.gif b/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Installation/public_sys-resources/icon-warning.gif differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/riscv.md b/docs/en/25.03/Server/InstallationUpgrade/Installation/riscv.md new file mode 100644 index 0000000000000000000000000000000000000000..11128008cc0c31fa395bba64e1a36e21020ce76e --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Installation/riscv.md @@ -0,0 +1,3 @@ +# RISC-V安装指南 + +本文是介绍 openEuler 操作系统在 RISC-V 架构的安装方法,使用本手册的用户需要具备基础的 Linux 系统管理知识。 diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/riscv_more.md b/docs/en/25.03/Server/InstallationUpgrade/Installation/riscv_more.md new file mode 100644 index 0000000000000000000000000000000000000000..6a106f35a83dcdfc9cfe883357b182968292771f --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Installation/riscv_more.md @@ -0,0 +1,4 @@ +# 参考资料 + +- visionfive 上使用 openEuler RISC-V +- 在 RISC-V 平台玩转 openEuler diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/riscv_qemu.md b/docs/en/25.03/Server/InstallationUpgrade/Installation/riscv_qemu.md new file mode 100644 index 0000000000000000000000000000000000000000..6ed7c17dc6524b737124950bc20da4273632ee4c --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Installation/riscv_qemu.md @@ -0,0 +1,341 @@ +# 安装指导 + +本章以 QEMU 安装为例介绍安装openEuler,其他安装方式参考开发板安装页面。 + +## 安装 QEMU + +### 系统环境 + +目前该方案测试过的环境包括 WSL2 (Ubuntu 20.04.4 LTS and Ubuntu 22.04.1 LTS) 和 Ubuntu 22.04.1 live-server LTS。 + +## 安装支持 RISC-V 架构的 QEMU 模拟器 + +安装发行版提供的 `qemu-system-riscv64` 软件包。截止本文档编写时,openEuler 23.09 x86_64 提供 QEMU 6.2.0 (qemu-system-riscv-6.2.0-80.oe2309.x86_64): + +``` bash +dnf install -y qemu-system-riscv +``` + +由于 QEMU 8.0 及更新版本提供了大量针对 RISC-V 的修复和更新,我们推荐使用 QEMU 8.0 或更新版本以获得更佳体验。下面以 QEMU 8.1.2 为例。 + +### 手动编译安装 + +由于自带的包常常过旧,若软件包过旧,使用以下方案编译和安装。 + +``` bash +wget https://download.qemu.org/qemu-8.1.2.tar.xz +tar -xvf qemu-8.1.2.tar.xz +cd qemu-8.1.2 +mkdir res +cd res +sudo apt install libspice-protocol-dev libepoxy-dev libgtk-3-dev libspice-server-dev build-essential autoconf automake autotools-dev pkg-config bc curl gawk git bison flex texinfo gperf libtool patchutils mingw-w64 libmpc-dev libmpfr-dev libgmp-dev libexpat-dev libfdt-dev zlib1g-dev libglib2.0-dev libpixman-1-dev libncurses5-dev libncursesw5-dev meson libvirglrenderer-dev libsdl2-dev -y +../configure --target-list=riscv64-softmmu,riscv64-linux-user --prefix=/usr/local/bin/qemu-riscv64 --enable-slirp +make -j$(nproc) +sudo make install +``` + +上述指令会将 QEMU 安装到 `/usr/local/bin/qemu-riscv64`。将 `/usr/local/bin/qemu-riscv64/bin` 添加至 `$PATH` 即可使用。 + +如需在其他操作系统下,包括 openEuler 下进行编译安装,请参考 [QEMU 官方文档](https://wiki.qemu.org/Hosts/Linux)。 + +openEuler 编译所需依赖包可参考 RHEL / CentOS,如下: + +``` bash +sudo dnf install -y git glib2-devel libfdt-devel pixman-devel zlib-devel bzip2 ninja-build python3 \ + libaio-devel libcap-ng-devel libiscsi-devel capstone-devel \ + gtk3-devel vte291-devel ncurses-devel \ + libseccomp-devel nettle-devel libattr-devel libjpeg-devel \ + brlapi-devel libgcrypt-devel lzo-devel snappy-devel \ + librdmacm-devel libibverbs-devel cyrus-sasl-devel libpng-devel \ + libuuid-devel pulseaudio-libs-devel curl-devel libssh-devel \ + systemtap-sdt-devel libusbx-devel +curl -LO https://download.qemu.org/qemu-8.1.2.tar.xz +tar -xvf qemu-8.1.2.tar.xz +cd qemu-8.1.2 +mkdir res +cd res +../configure --target-list=riscv64-softmmu,riscv64-linux-user --prefix=/usr/local/bin/qemu-riscv64 +make -j$(nproc) +sudo make install +``` + +## 准备 openEuler RISC-V 磁盘映像 + +### 下载磁盘映像 + +需要下载启动固件 (`fw_payload_oe_uboot_2304.bin`),磁盘映像(`openEuler-23.09-RISC-V-qemu-riscv64.qcow2.xz`)和启动脚本(`start_vm.sh`)。 + +### 下载目录 + +目前的构建位于 [openEuler Repo](https://repo.openeuler.org/openEuler-23.09/virtual_machine_img/riscv64/) 中。您也可以访问 [openEuler 官网](https://www.openeuler.org/zh/download/),从其他镜像源获取镜像。 + +### 内容说明 + +- `fw_payload_oe_uboot_2304.bin`: 启动固件 +- `openEuler-23.09-RISC-V-qemu-riscv64.qcow2.xz`: openEuler RISC-V QEMU 虚拟机磁盘映像压缩包 +- `openEuler-23.09-RISC-V-qemu-riscv64.qcow2.xz.sha256sum`: openEuler RISC-V QEMU 虚拟机磁盘映像压缩包的校验。使用 `sha256sum -c openEuler-23.09-RISC-V-qemu-riscv64.qcow2.xz.sha256sum` 校验。 +- `start_vm.sh`: 官方虚拟机启动脚本 + +### [可选] 配置 copy-on-write(COW)磁盘 + +> 写时复制(copy-on-write,缩写COW)技术不会对原始的映像文件做更改,变化的部分写在另外的映像文件中,这种特性在 QEMU 中只有 QCOW 格式支持,多个磁盘映像可以指向同一映像同时测试多个配置, 而不会破坏原映像。 + +#### 创建新映像 + +使用如下的命令创建新的映像,并在下方启动虚拟机时使用新映像。假设原映像为 `openEuler-23.09-RISC-V-qemu-riscv64.qcow2`,新映像为 `test.qcow2`。 + +``` bash +qemu-img create -o backing_file=openEuler-23.09-RISC-V-qemu-riscv64.qcow2,backing_fmt=qcow2 -f qcow2 test.qcow2 +``` + +#### 查看映像信息 + +``` bash +qemu-img info --backing-chain test.qcow2 +``` + +#### 修改基础映像位置 + +使用如下的命令修改基础映像位置。假设新的基础映像为 `another.qcow2`,欲修改映像为 `test.qcow2`。 + +``` bash +qemu-img rebase -b another.qcow2 test.qcow2 +``` + +#### 合并映像 + +将修改后的镜像合并到原来的镜像。假设新映像为 `test.qcow2`。 + +``` bash +qemu-img commit test.qcow2 +``` + +#### 扩容根分区 + +为了扩大根分区以获得更大的可使用空间,按照如下操作进行。 + +扩大磁盘镜像。 + +``` bash +qemu-img resize test.qcow2 +100G +``` + +输出 + +```text +Image resized. +``` + +启动虚拟机,使用下列指令检查磁盘大小。 + +``` bash +lsblk +``` + +列出分区情况。 + +``` bash +fdisk -l +``` + +修改根分区。 + +``` bash +fdisk /dev/vda +Welcome to fdisk (util-linux 2.35.2). +Changes will remain in memory only, until you decide to write them. +Be careful before using the write command. + +Command (m for help): p # 输出分区情况 +Disk /dev/vda: 70 GiB, 75161927680 bytes, 146800640 sectors +Units: sectors of 1 * 512 = 512 bytes +Sector size (logical/physical): 512 bytes / 512 bytes +I/O size (minimum/optimal): 512 bytes / 512 bytes +Disklabel type: dos +Disk identifier: 0x247032e6 + +Device Boot Start End Sectors Size Id Type +/dev/vda1 2048 4194303 4192256 2G e W95 FAT16 (LBA) +/dev/vda2 4194304 83886079 79691776 38G 83 Linux + +Command (m for help): d # 删除原有分区 +Partition number (1,2, default 2): 2 + +Partition 2 has been deleted. + +Command (m for help): n # 新建分区 +Partition type + p primary (1 primary, 0 extended, 3 free) + e extended (container for logical partitions) +Select (default p): p # 选择主分区 +Partition number (2-4, default 2): 2 +First sector (4194304-146800639, default 4194304): # 此处和上文的 /dev/vda2 的起始块应当一致 +Last sector, +/-sectors or +/-size{K,M,G,T,P} (4194304-146800639, default 146800639): #保持默认直接分配到最尾端 + +Created a new partition 2 of type 'Linux' and of size 68 GiB. +Partition #2 contains a ext4 signature.Do you want to remove the signature? [Y]es/[N]o: n + +Command (m for help): p #再次检查 + +Disk /dev/vda: 70 GiB, 75161927680 bytes, 146800640 sectors +Units: sectors of 1 * 512 = 512 bytes +Sector size (logical/physical): 512 bytes / 512 bytes +I/O size (minimum/optimal): 512 bytes / 512 bytes +Disklabel type: dos +Disk identifier: 0x247032e6 + +Device Boot Start End Sectors Size Id Type +/dev/vda1 2048 4194303 4192256 2G e W95 FAT16 (LBA) +/dev/vda2 4194304 146800639 142606336 68G 83 Linux + +Command (m for help): w # 写入到磁盘 +The partition table has been altered. +Syncing disks. +``` + +更新磁盘信息。 + +``` bash +resize2fs /dev/vda2 +``` + +## 启动 openEuler RISC-V 虚拟机 + +### 启动虚拟机 + +- 确认当前目录内包含 `fw_payload_oe_uboot_2304.bin`,磁盘映像压缩包,以及启动脚本。 +- 解压映像压缩包 `xz -dk openEuler-23.09-RISC-V-qemu-riscv64.qcow2.xz` +- 调整启动参数 +- 执行启动脚本 `$ bash start_vm.sh` + +### [可选] 启动参数调整 + +- `vcpu` 为 QEMU 运行线程数,与 CPU 核数没有严格对应。当设定的 `vcpu` 值大于宿主机核心值时,可能导致运行阻塞和速度严重降低。默认为 `4`。 +- `memory` 为虚拟机内存大小,可随需要调整。默认为 `2`。 +- `drive` 为虚拟磁盘路径,如果在上文中配置了 COW 映像,此处填写创建的新映像。 +- `fw` 为 U-Boot 镜像路径。 +- `ssh_port` 为转发的 SSH 端口,默认为 `12055`。设定为空以关闭该功能。 + +## 登录虚拟机 + +脚本提供了 SSH 登录支持。 + +如果这是暴露在外网的虚拟机,请在登录成功之后立即修改 root 用户密码。 + +### SSH 登录 + +Secure Shell(安全外壳协议,简称 SSH)是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境。SSH 通过在网络中创建安全隧道来实现SSH客户端与服务器之间的连接。SSH 最常见的用途是远程登录系统,人们通常利用SSH来传输命令行界面和远程执行命令。SSH 使用频率最高的场合是类 Unix 系统,但是 Windows 操作系统也能有限度地使用 SSH。2015 年,微软宣布将在未来的操作系统中提供原生SSH协议支持,Windows 10 1803 及更新版本中已提供 OpenSSH 客户端。 + +- 用户名: `root` 或 `openeuler` +- 默认密码: `openEuler12#$` +- 登录方式: 参见脚本提示 (或使用您偏好的 ssh 客户端) + +登录成功之后,可以看到如下的信息: + +``` bash +Authorized users only. All activities may be monitored and reported. + +Authorized users only. All activities may be monitored and reported. +Last login: Sun Oct 15 17:19:52 2023 from 10.0.2.2 + +Welcome to 6.4.0-10.1.0.20.oe2309.riscv64 + +System information as of time: Sun Oct 15 19:40:07 CST 2023 + +System load: 0.47 +Processes: 161 +Memory used: .7% +Swap used: 0.0% +Usage On: 11% +IP address: 10.0.2.15 +Users online: 1 + +[root@openeuler ~]# +``` + +### VNC 登录 + +这是一个类似于远程操作真机的方式,但是没有声音,受 QEMU 原生支持。 + +> VNC(Virtual Network Computing),为一种使用 RFB 协议的屏幕画面分享及远程操作软件。此软件借由网络,可发送键盘与鼠标的动作及即时的屏幕画面。 +> +> VNC 与操作系统无关,因此可跨平台使用,例如可用 Windows 连接到某 Linux 的电脑,反之亦同。甚至在没有安装客户端程序的电脑中,只要有支持 Java 的浏览器,也可使用。 + +#### 安装 VNC Viewer + +前往 [此处](https://sourceforge.net/projects/tigervnc/files/stable/) 下载 TigerVNC,或前往 [此处](https://www.realvnc.com/en/connect/download/viewer/) 下载 VNC Viewer。 + +#### 修改启动脚本 + +在启动脚本 `sleep 2` 行之前中添加如下内容: + +``` bash +vnc_port=12056 +echo -e "\033[37mVNC Port: \033[0m \033[34m"$vnc_port"\033[0m" +cmd="${cmd} -vnc :"$((vnc_port-5900)) +``` + +#### 连接到 VNC + +启动 TigerVNC 或 VNC Viewer,粘贴地址按下回车即可。操作界面和真机类似。 + +## 修改默认软件源配置 + +openEuler 23.09 RISC-V 版本的软件源目前仅包含 [OS] 和 [source] 仓库,而默认配置文件中包含了其他 RISC-V 版本并未提供的仓库。 + +用户在使用包管理器安装软件包之前,需要手动编辑软件源配置,移除 [OS] 和 [source] 两节之外的内容。 + +SSH 或 VNC 连接至虚拟机,使用 root 用户登录(若使用非特权用户登录,需要使用 sudo),在终端中进行如下操作: + +### 修改 /etc/yum.repos.d/openEuler.repo + +``` bash +vi /etc/yum.repos.d/openEuler.repo +# 或者 nano /etc/yum.repos.d/openEuler.repo +``` + +删除 [everything], [EPOL], [debuginfo], [update], [update-source] 小节,仅保留 [OS] 和 [source] 两部分。 + +修改完成后,您的 openEuler.repo 配置应该与下述基本一致: + +``` text +#generic-repos is licensed under the Mulan PSL v2. +#You can use this software according to the terms and conditions of the Mulan PSL v2. +#You may obtain a copy of Mulan PSL v2 at: +# http://license.coscl.org.cn/MulanPSL2 +#THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +#PURPOSE. +#See the Mulan PSL v2 for more details. + +[OS] +name=OS +baseurl=http://repo.openeuler.org/openEuler-23.09/OS/$basearch/ +metalink=https://mirrors.openeuler.org/metalink?repo=$releasever/OS&arch=$basearch +metadata_expire=1h +enabled=1 +gpgcheck=1 +gpgkey=http://repo.openeuler.org/openEuler-23.09/OS/$basearch/RPM-GPG-KEY-openEuler + +[source] +name=source +baseurl=http://repo.openeuler.org/openEuler-23.09/source/ +metalink=https://mirrors.openeuler.org/metalink?repo=$releasever&arch=source +metadata_expire=1h +enabled=1 +gpgcheck=1 +gpgkey=http://repo.openeuler.org/openEuler-23.09/source/RPM-GPG-KEY-openEuler +``` + +接下来就可以正常使用 `dnf` 包管理器进行软件包的安装了。初次安装的时候需要导入 openEuler 的 GPG key,若出现如下提示时,需输入 y 并确认,还请注意。 + +``` text +retrieving repo key for OS unencrypted from http://repo.openeuler.org/openEuler-23.09/OS/riscv64/RPM-GPG-KEY-openEuler +OS 18 kB/s | 2.1 kB 00:00 +Importing GPG key 0xB25E7F66: + Userid : "private OBS (key without passphrase) " + Fingerprint: 12EA 74AC 9DF4 8D46 C69C A0BE D557 065E B25E 7F66 + From : http://repo.openeuler.org/openEuler-23.09/OS/riscv64/RPM-GPG-KEY-openEuler +Is this ok [y/N]: y +Key imported successfully +``` diff --git a/docs/en/25.03/Server/InstallationUpgrade/Installation/using-kickstart-for-automatic-installation.md b/docs/en/25.03/Server/InstallationUpgrade/Installation/using-kickstart-for-automatic-installation.md new file mode 100644 index 0000000000000000000000000000000000000000..5c9b1662bc61459da6dcfb1d35a20475f2fce98f --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Installation/using-kickstart-for-automatic-installation.md @@ -0,0 +1,365 @@ +# 使用kickstart自动化安装 + + + +- [使用kickstart自动化安装](#使用kickstart自动化安装) + - [总体介绍](#总体介绍) + - [概述](#概述) + - [优缺点对比](#优缺点对比) + - [背景知识](#背景知识) + - [半自动化安装指导](#半自动化安装指导) + - [环境要求](#环境要求) + - [操作步骤](#操作步骤) + - [全自动化安装指导](#全自动化安装指导) + - [环境要求](#环境要求-1) + - [操作步骤](#操作步骤-1) + + + +## 总体介绍 + +### 概述 + +用户可以使用kickstart工具进行openEuler系统的自动化安装,包括如下两种方式: + +- 半自动化安装:安装人员不需要手动设定操作系统的键盘、语言、分区等具体属性(通过kickstart实现自动化),但是需要手动指定kickstart文件的位置。 +- 全自动化安装:实现操作系统的安装过程全自动化。 + +### 优缺点对比 + +使用kickstart工具进行半自动化安装和全自动化安装的优缺点对比如[表1](#table1388812373315)所示,用户可以自行选择安装方式。 + +**表 1** 优缺点对比 + + + + + + + + + + + + + + + + +

安装方式

+

优点

+

缺点

+

半自动化安装

+

不需要准备tftp,pxe,dhcp等服务

+

需要手动指定kickstart文件的位置

+

全自动化安装

+

操作系统的全自动化安装

+

需要配置tftp,dhcpd,pxe等服务

+
+ +### 背景知识 + +**kickstart** + +kickstart是一种无人值守的安装方式。它的工作原理是在安装过程中记录典型的需要人工干预填写的各种参数,并生成一个配置文件(ks.cfg),在安装过程中,安装程序首先会去查找ks配置文件,如果找到合适的参数,就采用所找到的参数;如果没有找到合适的参数,便需要安装者手工设定。所以,如果kickstart文件涵盖了安装过程中需要设定的所有参数,安装者只需要告诉安装程序从何处取ks.cfg文件,就能实现系统安装的自动化。 + +kickstart 安装提供一个安装过程自动化的方法,可以是部分自动化,也可以是完全自动化。 + +**PXE** + +PXE(Pre-boot Execution Environment,预启动执行环境),工作于Client/Server的网络模式,支持PXE的客户端在启动过程中,能够从DHCP服务器获取IP,结合TFTP(trivial file transfer protocol)等协议可以实现客户端的网络引导和安装。 + +**TFTP** + +TFTP(Trivial File Transfer Protocol,简单文件传输协议),该协议用来实现客户机与服务器之间的简单文件传输,它提供不复杂、开销不大的文件传输服务。 + +## 半自动化安装指导 + +### 环境要求 + +使用kickstart进行openEuler系统的半自动化安装的环境要求如下: + +- 物理机/虚拟机(虚拟机创建可参考对应厂商的资料)。包括使用kickstart工具进行自动化安装的计算机和被安装的计算机。 +- httpd:存放kickstart文件。 +- ISO: openEuler-21.09-aarch64-dvd.iso + +### 操作步骤 + +使用kickstart进行openEuler系统的半自动化安装的操作步骤如下: + +**环境准备** + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 安装之前,请确保http服务器的防火墙处于关闭状态。关闭防火墙可参照如下命令: +> +>``` sh +>iptables -F +>``` + +1. httpd的安装与服务启动。 + + ```sh + # dnf install httpd -y + # systemctl start httpd + # systemctl enable httpd + ``` + +2. kickstart文件的准备。 + + ```sh + # mkdir /var/www/html/ks + # vim /var/www/html/ks/openEuler-ks.cfg ===>根据已安装openEuler系统自动生成的anaconda-ks.cfg修改得到 + ==================================== + ***以下内容需要根据实际需求进行修改*** + #version=DEVEL + ignoredisk --only-use=sda + autopart --type=lvm + # Partition clearing information + clearpart --none --initlabel + # Use graphical install + graphical + # Use CDROM installation media + cdrom + # Keyboard layouts + keyboard --vckeymap=cn --xlayouts='cn' + # System language + lang zh_CN.UTF-8 + + # Network information + network --bootproto=dhcp --device=enp4s0 --ipv6=auto --activate + network --hostname=openeuler.com + # Root password + rootpw --iscrypted $6$fQE83lxEZ48Or4zc$j7/PlUMHn29yTjCD4Fi44WTZL/RzVGxJ/7MGsZMl6QfE3KjIVT7M4UrhFXbafvRq2lUddAFcyWHd5WRmXfEK20 + # Run the Setup Agent on first boot + firstboot --enable + # Do not configure the X Window System + skipx + # System services + services --disabled="chronyd" + # System timezone + timezone Asia/Shanghai --utc --nontp + + %packages + @^minimal-environment + @standard + + %end + + %anaconda + pwpolicy root --minlen=8 --minquality=1 --notstrict --nochanges --notempty + pwpolicy user --minlen=8 --minquality=1 --notstrict --nochanges --emptyok + pwpolicy luks --minlen=8 --minquality=1 --notstrict --nochanges --notempty + %end + + %post + #enable kdump + sed -i "s/ ro / ro crashkernel=1024M,high /" /boot/efi/EFI/openEuler/grub.cfg + %end + ===================================== + ``` + + 密码密文生成方式: + + ```sh + # python3 + Python 3.7.0 (default, Apr 1 2019, 00:00:00) + [GCC 7.3.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>>> import crypt + >>>> passwd = crypt.crypt("myPasswd") + >>>> print (passwd) + $6$63c4tDmQGn5SDayV$mZoZC4pa9Jdt6/ALgaaDq6mIExiOO2EjzomB.Rf6V1BkEMJDcMddZeGdp17cMyc9l9ML9ldthytBEPVcnboR/0 + ``` + +3. 将ISO镜像文件挂载到需要安装openEuler计算机的光驱上。 + + 另外,也可以选择NFS等网络安装,kickstart文件中需要指定安装源位置(默认是cdrom)。 + +**安装系统** + +1. 启动系统进入安装选择界面。 + 1. 在“[启动安装](./安装指导.html#启动安装)”中的“安装引导界面”中选择“Install openEuler 21.09”,并按下“e”键。 + 2. 启动参数中追加“inst.ks= ip/ks/openEuler-ks.cfg”。 + + ![](./figures/startparam.png) + + 3. 按“Ctrl+x”,开始系统的自动安装。 + +2. 确认系统安装完毕。 + + 系统安装完毕以后会自动重启,如果优先从光驱启动,会再次进入到安装界面,此时关闭计算机,调整启动顺序(优先从硬盘启动)。 + + ![](./figures/Automatic_installation_complete.png) + +## 全自动化安装指导 + +### 环境要求 + +使用kickstart进行openEuler系统的全自动化安装的环境要求如下: + +- 物理机/虚拟机(虚拟机创建可参考对应厂商的资料)。包括使用kickstart工具进行自动化安装的计算机和被安装的计算机。 +- httpd:存放kickstart文件。 +- tftp:提供vmlinuz和initrd文件。 +- dhcpd/pxe:提供DHCP服务。 +- ISO:openEuler-21.09-aarch64-dvd.iso。 + +### 操作步骤 + +使用kickstart进行openEuler系统的全自动化安装的操作步骤如下: + +**环境准备** + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 安装之前,请确保http服务器的防火墙处于关闭状态。关闭防火墙可参照如下命令: +> +>```sh +>iptables -F +>``` + +1. httpd的安装与服务启动。 + + ```sh + # dnf install httpd -y + # systemctl start httpd + # systemctl enable httpd + ``` + +2. tftp的安装与配置。 + + ```sh + # dnf install tftp-server -y + # vim /etc/xinetd.d/tftp + service tftp + { + socket_type = dgram + protocol = udp + wait = yes + user = root + server = /usr/sbin/in.tftpd + server_args = -s /var/lib/tftpboot + disable = no + per_source = 11 + cps = 100 2 + flags = IPv4 + } + # systemctl start tftp + # systemctl enable tftp + # systemctl start xinetd + # systemctl status xinetd + # systemctl enable xinetd + ``` + +3. 安装源的制作。 + + ```sh + # mount openEuler-21.09-aarch64-dvd.iso /mnt + # cp -r /mnt/* /var/www/html/openEuler/ + ``` + +4. 设置和修改kickstart配置文件 openEuler-ks.cfg,参考[3](#zh-cn_topic_0151920754_l1692f6b9284e493683ffa2ef804bc7ca)安装源的目录,此处选择http安装源。 + + ```sh + #vim /var/www/html/ks/openEuler-ks.cfg + ==================================== + ***以下内容根据实际需求进行修改*** + #version=DEVEL + ignoredisk --only-use=sda + autopart --type=lvm + # Partition clearing information + clearpart --none --initlabel + # Use graphical install + graphical + # Keyboard layouts + keyboard --vckeymap=cn --xlayouts='cn' + # System language + lang zh_CN.UTF-8 + #Use http installation source + url --url=http://192.168.122.1/openEuler/ + %post + #enable kdump + sed -i "s/ ro / ro crashkernel=1024M,high /" /boot/efi/EFI/openEuler/grub.cfg + %end + ... + ``` + +5. 修改pxe配置文件grub.cfg, 可参考如下内容(注意:openEuler当前不支持bls格式的cfg文件)。 + + ```sh + # cp -r /mnt/images/pxeboot/* /var/lib/tftpboot/ + # cp /mnt/EFI/BOOT/grubaa64.efi /var/lib/tftpboot/ + # cp /mnt/EFI/BOOT/grub.cfg /var/lib/tftpboot/ + # ls /var/lib/tftpboot/ + grubaa64.efi grub.cfg initrd.img TRANS.TBL vmlinuz + # vim /var/lib/tftpboot/grub.cfg + set default="1" + + function load_video { + if [ x$feature_all_video_module = xy ]; then + insmod all_video + else + insmod efi_gop + insmod efi_uga + insmod ieee1275_fb + insmod vbe + insmod vga + insmod video_bochs + insmod video_cirrus + fi + } + + load_video + set gfxpayload=keep + insmod gzio + insmod part_gpt + insmod ext2 + + set timeout=60 + + + ### BEGIN /etc/grub.d/10_linux ### + menuentry 'Install openEuler 21.03 ' --class red --class gnu-linux --class gnu --class os { + set root=(tftp,192.168.1.1) + linux /vmlinuz ro inst.geoloc=0 console=ttyAMA0 console=tty0 rd.iscsi.waitnet=0 inst.ks=http://192.168.122.1/ks/openEuler-ks.cfg + initrd /initrd.img + } + ``` + +6. DHCP的配置(可以使用dnsmasq代替 )。 + + ```sh + # dnf install dhcp -y + # + # DHCP Server Configuration file. + # see /usr/share/doc/dhcp-server/dhcpd.conf.example + # see dhcpd.conf(5) man page + # + # vim /etc/dhcp/dhcpd.conf + ddns-update-style interim; + ignore client-updates; + filename "grubaa64.efi";    # pxelinux 启动文件位置; + next-server 192.168.122.1;  # (重要)TFTP Server 的IP地址; + subnet 192.168.122.0 netmask 255.255.255.0 { + option routers 192.168.122.1; # 网关地址 + option subnet-mask 255.255.255.0; # 子网掩码 + range dynamic-bootp 192.168.122.50 192.168.122.200; # 动态ip范围 + default-lease-time 21600; + max-lease-time 43200; + } + # systemctl start dhcpd + # systemctl enable dhcpd + ``` + +**安装系统** + +1. 在“Start boot option”界面按下“F2”选择从网络pxe启动,开始自动化安装。 + + ![](./figures/zh-cn_image_0229291270.png) + + ![](./figures/zh-cn_image_0229291286.png) + + ![](./figures/zh-cn_image_0229291247.png) + +2. 进入系统全自动化安装界面。 +3. 确认系统安装完毕。 + + ![](./figures/Automatic_installation_complete.png) diff --git a/docs/en/25.03/Server/InstallationUpgrade/Upgrade/_menu.md b/docs/en/25.03/Server/InstallationUpgrade/Upgrade/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..9d7ab097bdbad01b61074118e2fad84489436f78 --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Upgrade/_menu.md @@ -0,0 +1,9 @@ +--- +label: '升级指南' +ismanual: 'Y' +description: '升级 openEuler 操作系统' +children: + - label: '升降级指导' + href: './openEuler_22.03_LTS_upgrade_and_downgrade.md' +--- + diff --git a/docs/en/25.03/Server/InstallationUpgrade/Upgrade/images/LTS_version.png b/docs/en/25.03/Server/InstallationUpgrade/Upgrade/images/LTS_version.png new file mode 100644 index 0000000000000000000000000000000000000000..84132f5825f1bdc743736ab2c65cd23c7ec9afa9 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Upgrade/images/LTS_version.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Upgrade/images/SP1_repo.png b/docs/en/25.03/Server/InstallationUpgrade/Upgrade/images/SP1_repo.png new file mode 100644 index 0000000000000000000000000000000000000000..42336cddfc122937e4ac2a8ce07182fa166ce942 Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Upgrade/images/SP1_repo.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Upgrade/images/SP1_version.png b/docs/en/25.03/Server/InstallationUpgrade/Upgrade/images/SP1_version.png new file mode 100644 index 0000000000000000000000000000000000000000..d22f8523c22dbd094d21ccdfb86446062b63b5ea Binary files /dev/null and b/docs/en/25.03/Server/InstallationUpgrade/Upgrade/images/SP1_version.png differ diff --git a/docs/en/25.03/Server/InstallationUpgrade/Upgrade/openEuler_22.03_LTS_upgrade_and_downgrade.md b/docs/en/25.03/Server/InstallationUpgrade/Upgrade/openEuler_22.03_LTS_upgrade_and_downgrade.md new file mode 100644 index 0000000000000000000000000000000000000000..9f112b7e15ec32400ed558caaeec958f3d03ea66 --- /dev/null +++ b/docs/en/25.03/Server/InstallationUpgrade/Upgrade/openEuler_22.03_LTS_upgrade_and_downgrade.md @@ -0,0 +1,74 @@ +# 升降级指导 + +本文档以openEuler-22.03-LTS到openEuler-22.03-LTS-SP1的升降级为例,其他版本同理 + +## **1**. **系统安装** + +获取openEuler-22.03-LTS镜像,参考安装指南,完成openEuler操作系统的安装。 + +查看当前环境openEuler、kernel版本 + +![LTS_version](./images/LTS_version.png) + +## **2**. **升级操作** + +### 2.1 新增openEuler-22.03-LTS-SP1 repo源 (openEuler-22.03-LTS-SP1.repo) + +```bash +vi /etc/yum.repos.d/openEuler-22.03-LTS-SP1.repo +``` + + 输入以下openEuler-22.03-LTS-SP1 repo源信息并保存退出 + +```bash +SP1_OS、SP1_everything、SP1_EPOL、SP1_debuginfo、SP1_source、SP1_update +``` + +![SP1_repo](./images/SP1_repo.png) + +### 2.2 执行升级 + +```bash +dnf update | tee update_log +``` + +```bash +补充说明: +1、安装报错时,通过执行 dnf update --skip-broken -x conflict_pkg1 |tee update_log 规避安装冲突问题,如果有多个包冲突,添加多个-x conflict_pkg1 -x conflict_pkg2 -x conflict_pkg3,待升级完成后,对跳过的软件包单独进行分析、验证、升级; +2、参数释义: +--allowerasing 通过卸载已安装的软件包解决依赖关系 +--skip-broken 通过跳过软件包解决依赖问题 +-x 跟--skip-broken配合使用,后边跟需要跳过的软件包名 +``` + +### 2.4 重启系统 + +```bash +reboot +``` + +## **3**. **升级结果验证** + +查看当前环境的openEuler、kernel版本 + +![SP1_version](./images/SP1_version.png) + +## **4**. **降级操作** + +### 4.1 执行降级 + +```bash +dnf downgrade | tee downgrade_log +``` + +### 4.2 重启系统 + +```bash +reboot +``` + +## **5**. **降级结果验证** + +查看当前环境的openEuler、kernel版本 + +![LTS_version](./images/LTS_version.png) diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/_menu.md b/docs/en/25.03/Server/Maintenance/A-Ops/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..5552659d14fc9e005c56446f120b2b7421382565 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/A-Ops/_menu.md @@ -0,0 +1,22 @@ +--- +label: 'A-Ops用户指南' +ismanual: 'Y' +description: '使用 A-Ops 智能运维框架进行故障快速定位、配置项统筹管理等' +children: + - label: '部署A-Ops' + href: './deploying-aops.md' + - label: '使用A-Ops智能定位框架' + href: './aops-intelligent-positioning-framework-user-manual.md' + - label: '部署aops-agent' + href: './deploying-aops-agent.md' + - label: '使用热补丁dnf插件' + href: './dnf-command-usage.md' + - label: '配置溯源服务' + href: './configuration-tracing-service-user-manual.md' + - label: '架构感知服务' + href: './architecture-awareness-service-manual.md' + - label: '社区热补丁制作发布流程' + href: './community-hotpatch-creation-and-release-process.md' + - label: '自动化运维服务' + href: './automated-maintenance-user-manual.md' +--- diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/aops-intelligent-positioning-framework-user-manual.md b/docs/en/25.03/Server/Maintenance/A-Ops/aops-intelligent-positioning-framework-user-manual.md new file mode 100644 index 0000000000000000000000000000000000000000..113ef9bb115ac74210011ad07fe4c74e9e533ae9 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/A-Ops/aops-intelligent-positioning-framework-user-manual.md @@ -0,0 +1,182 @@ +# AOps 智能定位框架使用手册 + +参照[AOps部署指南](./deploying-aops.md)部署AOps前后端服务后,即可使用AOps智能定位框架。 + +下文会从页面的维度进行AOps智能定位框架功能的介绍。 + +## 工作台 + + 该页面为数据看板页面,用户登录后,仍在该页面。 + + ![4911661916984_.pic](./figures/工作台.jpg) + +支持操作: + +- 当前纳管的主机数量 +- 当前所有未确认的告警数量 + +- 每个主机组告警情况的统计 + +- 用户帐户操作 + + - 修改密码 + - 退出登录 +- 业务域和CVE信息暂不支持 + +## 资产管理 + +资产管理分为对主机组进行管理以及对主机进行管理。每个主机在agent侧注册时需指定一个已存在的主机组进行注册,注册完毕后会在前端进行显示。 + +(1)主机组页面: + +![4761661915951_.pic](./figures/主机组.jpg) + +支持如下操作: + +- 主机组添加 +- 主机组删除 +- 查看当前所有主机组 +- 查看每个主机组下的主机信息 + +添加主机组时,需指定主机组的名称和描述。注意:请勿重复名称。 + +![添加主机组](./figures/添加主机组.jpg) + +(2)主机管理页面: + +![主机管理](./figures/主机管理.jpg) + +支持如下操作: + +- 查看主机列表(可根据主机组、管理节点进行筛选,可根据主机名称进行排序) +- 删除主机 +- 点击主机可跳转到主机详情界面 + +(3)主机详细信息界面: + +![主机详情](./figures/主机详情.jpg) + +详情页的上半部分展示了该主机的操作系统及CPU等的基础信息。 + +![插件管理](./figures/插件管理.jpg) + +详情页的下半部分,用户可以看到该主机当前运行的采集插件信息(目前agent只支持gala-gopher插件)。 + +支持如下操作: + +- 查看主机基础信息及插件信息 +- 插件的管理(gala-gopher) + - 插件资源查看 + - 插件的开启和管理 + - gala-gopher的采集探针的开启和关闭 +- 主机场景的识别 + +点击场景识别后,系统会生成该主机的场景,并推荐检测该场景所需开启的插件以及采集项,用户可以根据推荐结果进行插件/探针的调整。 + +注意:修改插件信息如关闭插件或开关探针后,需要点击保存才能生效。 + +![修改插件](./figures/修改插件.png) + +## 智能定位 + +AOps项目的智能定位策略采用内置网络诊断应用作为模板,生成个性化工作流的策略进行检测和诊断。 + +“应用”作为工作流的模板,描述了检测中各步骤的串联情况,内置各步骤中使用的检测模型的推荐逻辑。用户在生成工作流时,可根据各主机的采集项、场景等信息,定制出工作流的详细信息。 + +(1)工作流列表页面: + +![工作流](./figures/工作流.jpg) + +支持操作: + +- 查看当前工作流列表,支持按照主机组、应用和状态进行筛选,并支持分页操作 +- 查看当前应用列表 + +(2)工作流详情页面: + +![工作流详情](./figures/工作流详情.jpg) + +支持操作: + +- 查看工作流所属主机组,主机数量、状态等基础信息 +- 查看单指标检测、多指标检测、集群故障诊断各步骤的详细算法模型信息 +- 修改检测各步骤应用的模型 +- 执行、暂停和删除工作流 + +修改某检测步骤的模型时,用户可根据模型名或标签搜索系统内置的模型库,选中模型后点击应用进行更改。 + +![修改模型](./figures/修改模型.png) + +(3)应用详情页面 + +![app详情](./figures/应用.png) + +支持操作: + +- 查看应用的整体流程 +- 基于应用创建工作流 + +创建工作流时,点击右上角的创建工作流按钮,并在右侧弹出的窗口中输入工作流的名称和描述,选择要检测的主机组。选中主机组后,下方会列出该主机组的所有主机,用户可选中部分主机后移到右侧的列表,最后点击创建,即可在工作流列表中看到新创建的工作流。 + +![app详情](./figures/app详情.jpg) + +![创建工作流](./figures/创建工作流.jpg) + +(4)告警 + +启动工作流后,会根据工作流的执行周期定时触发诊断,每次诊断若结果为异常,则会作为一条告警存入数据库,同时也会反应在前端告警页面中。 + +![告警](./figures/告警.jpg) + +支持操作: + +- 查看当前告警总数 +- 查看各主机组的告警数量 +- 查看告警列表 +- 告警确认 +- 查看告警详情 +- 下载诊断报告 + +告警确认后,将不在列表中显示 + +![告警确认](./figures/告警确认.jpg) + +点击异常详情后,可以根据主机维度查看告警详情,包括异常数据项的展示以及根因节点、根因异常的判断等。 + +![告警详情](./figures/告警详情.jpg) + +## 配置溯源 + +AOps项目的配置溯源用于对目标主机配置文件内容的变动进行检测记录,对于文件配置错误类引发的故障起到很好的支撑作用。 + +### 创建配置域 + +![](./figures/chuangjianyewuyu.png) + +### 添加配置域纳管node + +![](./figures/tianjianode.png) + +### 添加配置域配置 + +![](./figures/xinzengpeizhi.png) + +### 查询预期配置 + +![](./figures/chakanyuqi.png) + +### 删除配置 + +![](./figures/shanchupeizhi.png) + +### 查询实际配置 + +![](./figures/chaxunshijipeizhi.png) + +### 配置校验 + +![](./figures/zhuangtaichaxun.png) + +### 配置同步 + +暂未提供 diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/architecture-awareness-service-manual.md b/docs/en/25.03/Server/Maintenance/A-Ops/architecture-awareness-service-manual.md new file mode 100644 index 0000000000000000000000000000000000000000..4191b0b93c59cd3b31206df5b4189384c39c8025 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/A-Ops/architecture-awareness-service-manual.md @@ -0,0 +1,74 @@ +# 架构感知服务使用手册 + +## 安装 + +### 手动安装 + +- 通过yum挂载repo源实现 + + 配置yum源:openEuler23.09 和 openEuler23.09:Epol,repo源路径:/etc/yum.repos.d/openEuler.repo。 + + ```ini + [everything] # openEuler 23.09 官方发布源 + name=openEuler23.09 + baseurl=https://repo.openeuler.org/openEuler-23.09/everything/$basearch/ + enabled=1 + gpgcheck=1 + gpgkey=https://repo.openeuler.org/openEuler-23.09/everything/$basearch/RPM-GPG-KEY-openEuler + + [Epol] # openEuler 23.09:Epol 官方发布源 + name=Epol + baseurl=https://repo.openeuler.org/openEuler-23.09/EPOL/main/$basearch/ + enabled=1 + gpgcheck=1 + gpgkey=https://repo.openeuler.org/openEuler-23.09/OS/$basearch/RPM-GPG-KEY-openEuler + ``` + + 然后执行如下指令下载以及安装gala-spider及其依赖。 + + ```shell + # A-Ops 架构感知,通常安装在主节点上 + yum install gala-spider + yum install python3-gala-spider + + # A-Ops 架构感知探针,通常安装在主节点上 + yum install gala-gopher + ``` + +- 通过安装rpm包实现。先下载gala-spider-vx.x.x-x.oe1.aarch64.rpm,然后执行如下命令进行安装(其中x.x-x表示版本号,请用实际情况替代)。 + + ```shell + rpm -ivh gala-spider-vx.x.x-x.oe1.aarch64.rpm + rpm -ivh gala-gopher-vx.x.x-x.oe1.aarch64.rpm + ``` + +### 使用Aops部署服务安装 + +#### 编辑任务列表 + +修改部署任务列表,打开gala_spider步骤开关: + +```yaml +--- +step_list: + ... + gala_gopher: + enable: false + continue: false + gala_spider: + enable: false + continue: false + ... +``` + +#### 编辑主机清单 + +具体步骤参见其他章节gala-spider与gala-gopher模块主机配置。 + +#### 编辑变量列表 + +具体步骤参见其他章节gala-spider与gala-gopher模块变量配置。 + +#### 执行部署任务 + +具体步骤参见其他章节执行部署任务。 diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/automated-maintenance-user-manual.md b/docs/en/25.03/Server/Maintenance/A-Ops/automated-maintenance-user-manual.md new file mode 100644 index 0000000000000000000000000000000000000000..7277fef3f64a28dbf6f9f035ccba8d1a16e837c9 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/A-Ops/automated-maintenance-user-manual.md @@ -0,0 +1,64 @@ +# 自动化运维服务使用手册 + +## 主要功能 + +本服务主要包括批量命令执行和批量脚本执行的功能,两者均支持定时任务。 + +### 命令相关 + +命令页面包含命令管理和命令执行两个页签 + +#### 命令管理 + +命令管理界面可以对命令进行增删查改功能: +![](./image/新建命令.png) +![](./image/命令管理界面.png) + +#### 命令执行 + +命令执行界面可以创建命令执行任务: +![](./image/新建命令任务.png) + +命令执行界面可以对创建的任务进行任务信息查看,任务执行,任务结果查看,删除任务等操作: +![](./image/命令执行.png) +任务结果查看: +![](./image/任务结果查看.png) + +### 脚本相关 + +脚本页面包含脚本管理、脚本执行、操作管理三个页签 + +#### 操作管理 + +为了屏蔽操作系统的架构,系统对脚本执行的影响,抽象出操作的概念。一个操作对应一组包括各类架构和系统的脚本,脚本执行时选择主机和操作后,根据主机的系统和架构选择对应的脚本进行执行。 + +操作管理界面可以对操作进行增删查改功能: + +![](./image/操作管理.png) + +#### 脚本管理 + +脚本管理界面可以对脚本进行上传,查询,删除,编辑功能: +![](./image/脚本管理.png) +创建脚本: +![](./image/创建脚本.png) + +#### 脚本执行 + +脚本执行界面可以创建脚本执行任务,创建脚本任务仅能通过选择操作来选择对应脚本: +![](./image/脚本执行.png) +创建脚本任务: +![](./image/创建脚本任务.png) + +### 定时任务 + +定时任务支持指定时间执行和周期执行功能 +单次执行: +![](./image/单次执行.png) +周期执行: +![](./image/周期执行.png) + +### 文件推送 + +文件推送功能支持将脚本推送至指定目录,此类任务不会执行脚本,且推送任务与定时任务互斥: +![](./image/文件推送.png) diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/community-hotpatch-creation-and-release-process.md b/docs/en/25.03/Server/Maintenance/A-Ops/community-hotpatch-creation-and-release-process.md new file mode 100644 index 0000000000000000000000000000000000000000..00165edd722393672544bbc274c516ce8867fb2b --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/A-Ops/community-hotpatch-creation-and-release-process.md @@ -0,0 +1,260 @@ +# 社区热补丁制作发布流程 + +## 制作内核态/用户态热补丁 + +### 场景1. 在src-openEuler/openEuler仓下评论pr制作新版本热补丁 + +> 制作内核态热补丁需在**openEuler/kernel**仓评论pr。 +> +> 制作用户态热补丁需在src-openEuler仓评论pr,现在支持**src-openEuler/openssl,src-openEuler/glibc,src-openEuler/systemd**。 + +#### 1. 在已合入pr下评论制作热补丁 + +- 从src-openeuler仓【支持openssl, glibc, systemd】评论已合入pr制作新版本热补丁。 + +```shell +/makehotpatch [软件包版本号] [patch list] [cve/bug] [issue id] [os_branch] +``` + +命令说明:使用多个patch用','分隔,需注意patch的先后顺序。 + +![image-20230629114903593](./image/src-openEuler仓评论.png) + +- 从openeuler仓【支持kernel】评论已合入pr制作新版本热补丁。 + +```shell +/makehotpatch [软件包版本号] [cve/bug] [issue id] [os_branch] +``` + +![image-20230629142933917](./image/openEuler仓评论.png) + +评论后,门禁触发hotpatch_metadata仓创建热补丁issue以及同步该pr。 + +#### 2. hotpatch_metadata仓自动创建热补丁issue、同步该pr + +pr评论区提示启动热补丁制作流程。 + +![image-20230629143426498](./image/启动热补丁工程流程.png) + +随后,hotpatch_metadata仓自动创建热补丁issue,并在hotpatch_metadata仓同步该pr。 + +> 热补丁issue用于跟踪热补丁制作流程。 +> +> hotpatch_metadata仓用于触发制作热补丁。 + +![image-20230629144503840](./image/热补丁issue链接和pr链接.png) + +点击查看热补丁issue链接内容。 + +- 热补丁Issue类别为hotpatch。 + +![image-20230607161545732](./image/image-20230607161545732.png) + +点击查看在hotpatch_metadata仓自动创建的pr。 + +![hotpatch-fix-pr](./image/hotpatch-fix-pr.png) + +#### 3. 触发制作热补丁 + +打开hotpatch_metadata仓自动创建的pr,评论区可以查看热补丁制作信息。 + +![img](./image/45515A7F-0EC2-45AA-9B58-AB92DE9B0979.png) + +查看热补丁制作结果。 + +![img](./image/E574E637-0BF3-4F3B-BAE6-04ECBD09D151.png) + +如果热补丁制作失败,可以根据相关日志信息修改pr、评论 /retest直到热补丁可以被成功制作。 + +如果热补丁制作成功,可以通过Download link下载热补丁进行自验。 + +![image-20230608151244425](./image/hotpatch-pr-success.png) + +**若热补丁制作成功,可以对热补丁进行审阅**。 + +### 场景2、从hotpatch_metadata仓提pr修改热补丁 + +> 从hotpatch_metadata仓提pr只能修改还未正式发布的热补丁。 +> + +#### 1. 提pr + +用户需要手动创建热补丁issue。 + +(1)阅读readme,根据热补丁issue模版创建热补丁。 + +![image-20230612113428096](./image/image-20230612113428096.png) + +> 用户不允许修改热补丁元数据文件中已被正式发布的热补丁的相关内容。 +> + +pr内容: + +- patch文件。 +- 修改热补丁元数据hotmetadata.xml文件。 + +#### 2. 触发制作热补丁 + +**若热补丁制作成功,可以对热补丁进行审阅**。 + +### 场景3、从hotpatch_metadata仓提pr制作新版本热补丁 + +#### 1. 提pr + +在hotpatch_metadata仓提pr。 + +(1)阅读readme,根据热补丁issue模版创建热补丁。 + +![image-20230612113428096](./image/image-20230612113428096.png) + +pr内容: + +- patch文件。 +- 如果没有相应热补丁元数据hotmetadata.xml文件,则手动创建;否则修改热补丁元数据hotmetadata.xml文件。 + +#### 2. 触发制作热补丁 + +**若热补丁制作成功,可以对热补丁进行审阅**。 + +## 审阅热补丁 + +### 1. 审阅热补丁pr + +确认可发布,合入pr。 + +### 2. pr合入,回填热补丁issue + +在热补丁issue页面补充热补丁路径,包含src.rpm/arm架构/x86架构的rpm包,以及对应hotpatch.xml,用于展示热补丁信息。 + +> 如果一个架构失败,强行合入,也可只发布单架构的包。 + +![img](./image/EF5E0132-6E5C-4DD1-8CB5-73035278E233.png) + +- 热补丁Issue标签为hotpatch。 + +- 查看热补丁元数据内容。 + +热补丁元数据模版: + +> 热补丁元数据用于管理查看热补丁相关历史制作信息。 + +```xml + + + Managing Hot Patch Metadata + + + + src.rpm归档地址 + x86架构debuginfo二进制包归档地址 + arm架构debuginfo二进制包归档地址 + patch文件 + + https://gitee.com/wanghuan158/hot-patch_metadata/issues/I7AE5F + + + + +``` + +```xml + + + Managing Hot Patch Metadata + + + + download_link + download_link + download_link + 0001-PEM-read-bio-ret-failure.patch + + https://gitee.com/wanghuan158/hot-patch_metadata/issues/I7AE5F + + + download_link + download_link + download_link + 0001-PEM-read-bio-ret-failure.patch + + https://gitee.com/wanghuan158/hot-patch_metadata/issues/I7AE5P + + + + +``` + +> 注意:download_link均为repo仓正式的归档链接。 +> +> 热补丁当前只考虑演进,version 2基于version 1的src继续构建。 + +![image-20230607163358749](./image/image-20230607163358749.png) + +### 3. 关闭相应热补丁Issue + +## 发布热补丁 + +### 1、收集热补丁发布需求 + +在release-management仓库每周update需求收集的issue下方,手动评论start-update命令,此时会收集待发布的热补丁和待发布的修复cve的冷补丁。后台会在hotpatch_meta仓库根据hotpatch标签查找已关闭的热补丁issue。 + +### 2、生成安全公告热补丁信息 + +社区根据收集到的热补丁issue信息,在生成安全公告的同时生成hotpatch字段补丁,过滤已经发布的漏洞补丁。 + +- 在安全公告文件新增HotPatchTree字段,记录和公告相关漏洞的热补丁,每个补丁按架构和CVE字段区分(Type=ProductName 记录分支,Type=ProductArch 记录补丁具体的rpm包)。 + +![](./image/patch-file.PNG) + +### 3、Majun平台上传文件到openEuler官网,同步生成updateinfo.xml文件 + +社区将生成的安全公告上传到openEuler官网,同时基于所收集的热补丁信息生成updateinfo.xml文件。 + +![](./image/hotpatch-xml.PNG) + +updateinfo.xml文件样例: + +```xml + + + + openEuler-SA-2022-1 + An update for mariadb is now available for openEuler-22.03-LTS + Important + openEuler + + + + + + patch-redis-6.2.5-1-HP001.(CVE-2022-24048) + + + openEuler + + patch-redis-6.2.5-1-HP001-1-1.aarch64.rpm + + + patch-redis-6.2.5-1-HP001-1-1.x86_64.rpm + + + patch-redis-6.2.5-1-HP002-1-1.aarch64.rpm + + + patch-redis-6.2.5-1-HP002-1-1.x86_64.rpm + + + + + ... + +``` + +### 4、openEuler官网可以查看更新的热补丁信息,以cve编号划分 + +![image-20230612113626330](./image/image-20230612113626330.png) + +### 5、获取热补丁相关文件 + +社区将热补丁相关文件同步至openEuler的repo源下,可以在各个分支的hotpatch目录下获取相应文件。 +> openEuler的repo地址: diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/configuration-tracing-service-user-manual.md b/docs/en/25.03/Server/Maintenance/A-Ops/configuration-tracing-service-user-manual.md new file mode 100644 index 0000000000000000000000000000000000000000..c04c0e51f6abfec8cfbe5284b14a723bfd630f5d --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/A-Ops/configuration-tracing-service-user-manual.md @@ -0,0 +1,160 @@ +# gala-ragdoll的使用指导 + +============================ + +## 安装 + +### 手动安装 + +- 通过yum挂载repo源实现 + + 配置yum源:openEuler23.09 和 openEuler23.09:Epol,repo源路径:/etc/yum.repos.d/openEuler.repo。 + + ```ini + [everything] # openEuler 23.09 官方发布源 + name=openEuler23.09 + baseurl=https://repo.openeuler.org/openEuler-23.09/everything/$basearch/ + enabled=1 + gpgcheck=1 + gpgkey=https://repo.openeuler.org/openEuler-23.09/everything/$basearch/RPM-GPG-KEY-openEuler + + [Epol] # openEuler 23.09:Epol 官方发布源 + name=Epol + baseurl=https://repo.openeuler.org/openEuler-23.09/EPOL/main/$basearch/ + enabled=1 + gpgcheck=1 + gpgkey=https://repo.openeuler.org/openEuler-23.09/OS/$basearch/RPM-GPG-KEY-openEuler + ``` + + 然后执行如下指令下载以及安装gala-ragdoll及其依赖。 + + ```shell + yum install gala-ragdoll # A-Ops 配置溯源 + yum install python3-gala-ragdoll + + yum install gala-spider # A-Ops 架构感知 + yum install python3-gala-spider + ``` + +- 通过安装rpm包实现。先下载gala-ragdoll-vx.x.x-x.oe1.aarch64.rpm,然后执行如下命令进行安装(其中x.x-x表示版本号,请用实际情况替代) + + ```shell + rpm -ivh gala-ragdoll-vx.x.x-x.oe1.aarch64.rpm + ``` + +### 使用Aops部署服务安装 + +#### 编辑任务列表 + +修改部署任务列表,打开gala_ragdoll步骤开关: + +```yaml +--- +step_list: + ... + gala_ragdoll: + enable: false + continue: false + ... +``` + +#### 编辑主机清单 + +具体步骤参见其他章节gala-ragdoll模块主机配置 + +#### 编辑变量列表 + +具体步骤参见其他章节gala-ragdoll模块变量配置 + +#### 执行部署任务 + +具体步骤参见其他章节执行部署任务 + +### 配置文件介绍 + +`/etc/yum.repos.d/openEuler.repo`是用来规定yum源地址的配置文件,该配置文件内容为: + + ```shell + [OS] + name=OS + baseurl=http://repo.openeuler.org/openEuler-23.09/OS/$basearch/ + enabled=1 + gpgcheck=1 + gpgkey=http://repo.openeuler.org/openEuler-23.09/OS/$basearch/RPM-GPG-KEY-openEuler + ``` + +### yang模型介绍 + +`/etc/yum.repos.d/openEuler.repo`采用yang语言进行表示,参见`gala-ragdoll/yang_modules/openEuler-logos-openEuler.repo.yang`; +其中增加了三个拓展字段: + +| 拓展字段名称 | 拓展字段格式 | 样例 | +| ------------ | ---------------------- | ----------------------------------------- | +| path | OS类型:配置文件的路径 | openEuler:/etc/yum.repos.d/openEuler.repo | +| type | 配置文件类型 | ini、key-value、json、text等 | +| spacer | 配置项和配置值的中间键 | “ ”、“=”、“:”等 | + +附:yang语言的学习地址: + +### 通过配置溯源创建域 + +#### 查看配置文件 + +gala-ragdoll中存在配置溯源的配置文件 + + ```shell + [root@openeuler-development-1-1drnd ~]# cat /etc/ragdoll/gala-ragdoll.conf + [git] // 定义当前的git信息:包括git仓的目录和用户信息 + git_dir = "/home/confTraceTestConf" + user_name = "user" + user_email = "email" + + [collect] // A-OPS 对外提供的collect接口 + collect_address = "http://192.168.0.0:11111" + collect_api = "/manage/config/collect" + + [ragdoll] + port = 11114 + ``` + +#### 创建配置域 + +![](./figures/chuangjianyewuyu.png) + +#### 添加配置域纳管node + +![](./figures/tianjianode.png) + +#### 添加配置域配置 + +![](./figures/xinzengpeizhi.png) + +#### 查询预期配置 + +![](./figures/chakanyuqi.png) + +#### 删除配置 + +![](./figures/shanchupeizhi.png) + +#### 查询实际配置 + +![](./figures/chaxunshijipeizhi.png) + +#### 配置校验 + +![](./figures/zhuangtaichaxun.png) + +#### 配置同步 + +![](./figures/peizhitongbu.png) + +#### 配置文件追溯 + +##### 打开监控开关 + +![](./figures/chuangjianyewuyu.png) + +##### 配置文件修改记录追溯 + +![](./figures/conf_file_trace.png) diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/deploying-aops-agent.md b/docs/en/25.03/Server/Maintenance/A-Ops/deploying-aops-agent.md new file mode 100644 index 0000000000000000000000000000000000000000..c65187796d5e2ce549d7ffd526214a7d5597500f --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/A-Ops/deploying-aops-agent.md @@ -0,0 +1,652 @@ +# aops-agent部署指南 + +## 环境要求 + +1台openEuler机器,建议openEuler-20.03及以上版本运行。 + +## 配置环境部署 + +### 1. 关闭防火墙 + +```shell +systemctl stop firewalld +systemctl disable firewalld +systemctl status firewalld +``` + +### 2. aops-agent部署 + +1. 基于yum源安装:yum install aops-agent + +2. 修改配置文件:将agent节点下IP标签值修改为本机IP, + + vim /etc/aops/agent.conf,以IP地址为192.168.1.47为例 + + ```ini + [agent] + ;启动aops-agent时,绑定的IP与端口 + ip=192.168.1.47 + port=12000 + + [gopher] + ;gala-gopher默认配置文件路径,如需修改请确保文件路径的准确性 + config_path=/opt/gala-gopher/gala-gopher.conf + + ;aops-agent采集日志配置 + [log] + ;采集日志级别,可设置为DEBUG,INFO,WARNING,ERROR,CRITICAL + log_level=INFO + ;采集日志存放位置 + log_dir=/var/log/aops + ;日志文件最大值 + max_bytes=31457280 + ;备份日志的数量 + backup_count=40 + ``` + +3. 启动服务:systemctl start aops-agent + +### 3. 向aops-manager注册 + +为了辨别使用者的身份,避免接口被随意调用,aops-agent采用token验证身份,以减轻所部署主机的压力。 + +基于安全性考虑,项目采用主动注册的方式去获取token。注册前,须在agent侧准备好需要注册的信息,调用register命令向aops-manager注册。由于agent未配置数据库,注册成功后,自动将token保存到指定文件内,并在前台展示注册结果。同时将本机相关信息存入到aops-manager侧的数据库中,以便后续管理。 + +1. 准备register.json 文件 + + 在aops-agent侧准备好注册所需信息以json格式存入文件中,数据结构如下: + + ```JSON + { + // 前端登录用户名 + "web_username":"admin", + // 用户密码 + "web_password": "changeme", + // 主机名称 + "host_name": "host1", + // 主机所在组名称 + "host_group_name": "group1", + // aops-manager运行主机IP地址 + "manager_ip":"192.168.1.23", + // 是否注册为管理机器 + "management":false, + // aops-manager运行对外端口 + "manager_port":"11111", + // agent运行端口 + "agent_port":"12000" + } + ``` + + `注意:确保aops-manager已在目标主机运行,如192.168.1.23,且注册的主机组要存在。` + +2. 执行:aops_agent register -f register.json, +3. 前台展示注册结果,注册成功时,保存token字符串至指定文件;注册失败时,根据提示以及日志内容了解具体原因。(/var/log/aops/aops.log) + + 注册结果示例: + + `注册成功` + + ```shell + [root@localhost ~]# aops_agent register -f register.json + Agent Register Success + ``` + + `注册失败,以aops-manager未启动为示例` + + ```shell + [root@localhost ~]# aops_agent register -f register.json + Agent Register Fail + [root@localhost ~]# + ``` + + `对应日志内容` + + ```shell + 2022-09-05 16:11:52,576 ERROR command_manage/register/331: HTTPConnectionPool(host='192.168.1.23', port=11111): Max retries exceeded with url: /manage/host/add (Caused by NewConnectionError(': Failed to establish a new connection: [Errno 111] Connection refused')) + [root@localhost ~]# + ``` + +## 插件支持 + +### 3.1 gala-gopher + +#### 3.1.1 介绍 + +gala-gopher是基于eBPF的低负载探针框架,可用于对主机的CPU,内存,网络等状态的监控以及数据采集服务。可根据实际业务需求对已有采集探针采集状态进行配置。 + +#### 3.1.2 部署 + +1. 基于yum源安装:yum install gala-gopher +2. 基于实际的业务需求,选择需要探针进行开启,探针信息可在/opt/gala-gopher/gala-gopher.conf下查看。 +3. 启动服务:systemctl start gala-gopher + +#### 3.1.3 其他 + +gala-gopher更多信息可参考文档 + +## 接口支持 + +### 4.1 对外接口清单 + +| 序号 | 接口名称 | 类型 | 说明 | +| ---- | ------------------------------ | ---- | ----------------------| +| 1 | /v1/agent/plugin/start | POST | 启动插件 | +| 2 | /v1/agent/plugin/stop | POST | 停止插件 | +| 3 | /v1/agent/application/info | GET | 采集目标应用集内正在运行的应用 | +| 4 | /v1/agent/host/info | GET | 获取主机信息 | +| 5 | /v1/agent/plugin/info | GET | 获取agent中插件运行信息 | +| 6 | /v1/agent/file/collect | POST | 采集配置文件内容 | +| 7 | /v1/agent/collect/items/change | POST | 改变插件采集项的运行状态 | + +#### 4.1.1、/v1/agent/plugin/start + ++ 描述:启动已安装但未运行的插件,目前仅支持gala-gopher插件。 + ++ HTTP请求方式:POST + ++ 数据提交方式:query + ++ 请求参数: + + | 参数名 | 必选 | 类型 | 说明 | + | ----------- | ---- | ---- | ------ | + | plugin_name | True | str | 插件名 | + ++ 请求参数示例 + + | 参数名 | 参数值 | + | ----------- | ----------- | + | plugin_name | gala-gopher | + ++ 返回体参数 + + | 参数名 | 类型 | 说明 | + | ------ | ---- | ---------------- | + | code | int/ | 返回码 | + | msg | str | 状态码对应的信息 | + ++ 返回示例 + + ```json + { + "code": 200, + "msg": "xxxx" + } + ``` + +#### 4.1.2、/v1/agent/plugin/stop + ++ 描述:使正在运行的插件停止,目前仅支持gala-gopher插件。 + ++ HTTP请求方式:POST + ++ 数据提交方式:query + ++ 请求参数: + + | 参数名 | 必选 | 类型 | 说明 | + | ----------- | ---- | ---- | ------ | + | plugin_name | True | str | 插件名 | + ++ 请求参数示例: + + | 参数名 | 参数值 | + | ----------- | ----------- | + | plugin_name | gala-gopher | + ++ 返回体参数: + + | 参数名 | 类型 | 说明 | + | ------ | ---- | ---------------- | + | code | int | 返回码 | + | msg | str | 状态码对应的信息 | + ++ 返回示例: + + ```json + { + "code": 200, + "msg": "xxxx" + } + ``` + +#### 4.1.3、/v1/agent/application/info + ++ 描述:采集目标应用集内正在运行的应用,当前目标应用集包含mysql, kubernetes, hadoop, nginx, docker, gala-gopher。 + ++ HTTP请求方式:GET + ++ 数据提交方式:query + ++ 请求参数: + + | 参数名 | 必选 | 类型 | 说明 | + | ------ | ---- | ---- | ---- | + | | | | | + ++ 请求参数示例: + + | 参数名 | 参数值 | + | ------ | ------ | + | | | + ++ 返回体参数: + + | 参数名 | 类型 | 说明 | + | ------ | ---- | ---------------- | + | code | int | 返回码 | + | msg | str | 状态码对应的信息 | + | resp | dict | 响应数据主体 | + + + resp + + | 参数名 | 类型 | 说明 | + | ------- | --------- | -------------------------- | + | running | List[str] | 包含正在运行应用名称的系列 | + ++ 返回示例: + + ```json + { + "code": 200, + "msg": "xxxx", + "resp": { + "running": [ + "mysql", + "docker" + ] + } + } + ``` + +#### 4.1.4、/v1/agent/host/info + ++ 描述:获取安装agent主机的信息,包含系统版本,BIOS版本,内核版本,CPU信息以及内存信息。 + ++ HTTP请求方式:POST + ++ 数据提交方式:application/json + ++ 请求参数: + + | 参数名 | 必选 | 类型 | 说明 | + | --------- | ---- | --------- | ------------------------------------------------ | + | info_type | True | List[str] | 需采集信息的名称,目前仅支持cpu、disk、memory、os | + ++ 请求参数示例: + + ```json + ["os", "cpu","memory", "disk"] + ``` + ++ 返回体参数: + + | 参数名 | 类型 | 说明 | + | ------ | ---- | ---------------- | + | code | int | 返回码 | + | msg | str | 状态码对应的信息 | + | resp | dict | 响应数据主体 | + + resp + + | 参数名 | 类型 | 说明 | + | ------ | ---------- | -------- | + | cpu | dict | cpu信息 | + | memory | dict | 内存信息 | + | os | dict | OS信息 | + | disk | List[dict] | 硬盘信息 | + + cpu + + | 参数名 | 类型 | 说明 | + | ------------ | ---- | --------------- | + | architecture | str | CPU架构 | + | core_count | int | 核心数 | + | l1d_cache | str | 1级数据缓存大小 | + | l1i_cache | str | 1级指令缓存大小 | + | l2_cache | str | 2级缓存大小 | + | l3_cache | str | 3级缓存大小 | + | model_name | str | 模式名称 | + | vendor_id | str | 厂商ID | + + memory + + | 参数名 | 类型 | 说明 | + | ------ | ---------- | -------------- | + | size | str | 总内存大小 | + | total | int | 内存条数量 | + | info | List[dict] | 所有内存条信息 | + + info + + | 参数名 | 类型 | 说明 | + | ------------ | ---- | -------- | + | size | str | 内存大小 | + | type | str | 类型 | + | speed | str | 速度 | + | manufacturer | str | 厂商 | + + os + + | 参数名 | 类型 | 说明 | + | ------------ | ---- | -------- | + | bios_version | str | bios版本 | + | os_version | str | 系统名称 | + | kernel | str | 内核版本 | + ++ 返回示例: + + ```json + { + "code": 200, + "msg": "operate success", + "resp": { + "cpu": { + "architecture": "aarch64", + "core_count": "128", + "l1d_cache": "8 MiB (128 instances)", + "l1i_cache": "8 MiB (128 instances)", + "l2_cache": "64 MiB (128 instances)", + "l3_cache": "128 MiB (4 instances)", + "model_name": "Kunpeng-920", + "vendor_id": "HiSilicon" + }, + "memory": { + "info": [ + { + "manufacturer": "Hynix", + "size": "16 GB", + "speed": "2933 MT/s", + "type": "DDR4" + }, + { + "manufacturer": "Hynix", + "size": "16 GB", + "speed": "2933 MT/s", + "type": "DDR4" + } + ], + "size": "32G", + "total": 2 + }, + "os": { + "bios_version": "1.82", + "kernel": "5.10.0-60.18.0.50", + "os_version": "openEuler 22.03 LTS" + }, + "disk": [ + { + "capacity": "xxGB", + "model": "xxxxxx" + } + ] + } + } + ``` + +#### 4.1.5、/v1/agent/plugin/info + ++ 描述:获取主机的插件运行情况,目前仅支持gala-gopher插件。 + ++ HTTP请求方式:GET + ++ 数据提交方式:query + ++ 请求参数: + + | 参数名 | 必选 | 类型 | 说明 | + | ------ | ---- | ---- | ---- | + | | | | | + ++ 请求参数示例: + + | 参数名 | 参数值 | + | ------ | ------ | + | | | + ++ 返回体参数: + + | 参数名 | 类型 | 说明 | + | ------ | ---------- | ---------------- | + | code | int | 返回码 | + | msg | str | 状态码对应的信息 | + | resp | List[dict] | 响应数据主体 | + + resp + + | 参数名 | 类型 | 说明 | + | ------------- | ---------- | ------------------ | + | plugin_name | str | 插件名称 | + | collect_items | list | 插件采集项运行情况 | + | is_installed | str | 状态码对应的信息 | + | resource | List[dict] | 插件资源使用情况 | + | status | str | 插件运行状态 | + + resource + + | 参数名 | 类型 | 说明 | + | ------------- | ---- | ---------- | + | name | str | 资源名称 | + | current_value | str | 资源使用值 | + | limit_value | str | 资源限制值 | + ++ 返回示例: + + ```json + { + "code": 200, + "msg": "operate success", + "resp": [ + { + "collect_items": [ + { + "probe_name": "system_tcp", + "probe_status": "off", + "support_auto": false + }, + { + "probe_name": "haproxy", + "probe_status": "auto", + "support_auto": true + }, + { + "probe_name": "nginx", + "probe_status": "auto", + "support_auto": true + }, + ], + "is_installed": true, + "plugin_name": "gala-gopher", + "resource": [ + { + "current_value": "0.0%", + "limit_value": null, + "name": "cpu" + }, + { + "current_value": "13 MB", + "limit_value": null, + "name": "memory" + } + ], + "status": "active" + } + ] + } + ``` + +#### 4.1.6、/v1/agent/file/collect + ++ 描述:采集目标配置文件内容、文件权限、文件所属用户等信息。当前仅支持读取小于1M,无执行权限,且支持UTF8编码的文本文件。 + ++ HTTP请求方式:POST + ++ 数据提交方式:application/json + ++ 请求参数: + + | 参数名 | 必选 | 类型 | 说明 | + | --------------- | ---- | --------- | ------------------------ | + | configfile_path | True | List[str] | 需采集文件完整路径的序列 | + ++ 请求参数示例: + + ```json + [ "/home/test.conf", "/home/test.ini", "/home/test.json"] + ``` + ++ 返回体参数: + + | 参数名 | 类型 | 说明 | + | ------------- | ---------- | ---------------- | + | infos | List[dict] | 文件采集信息 | + | success_files | List[str] | 采集成功文件列表 | + | fail_files | List[str] | 采集失败文件列表 | + + infos + + | 参数名 | 类型 | 说明 | + | --------- | ---- | -------- | + | path | str | 文件路径 | + | content | str | 文件内容 | + | file_attr | dict | 文件属性 | + + file_attr + + | 参数名 | 类型 | 说明 | + | ------ | ---- | ------------ | + | mode | str | 文件类型权限 | + | owner | str | 文件所属用户 | + | group | str | 文件所属群组 | + ++ 返回示例: + + ```json + { + "infos": [ + { + "content": "this is a test file", + "file_attr": { + "group": "root", + "mode": "0644", + "owner": "root" + }, + "path": "/home/test.txt" + } + ], + "success_files": [ + "/home/test.txt" + ], + "fail_files": [ + "/home/test.txt" + ] + } + ``` + +#### 4.1.7、/v1/agent/collect/items/change + ++ 描述:更改插件采集项的采集状态,当前仅支持对gala-gopher采集项的更改,gala-gopher采集项可在配置文件中查看`/opt/gala-gopher/gala-gopher.conf`。 + ++ HTTP请求方式:POST + ++ 数据提交方式:application/json + ++ 请求参数: + + | 参数名 | 必选 | 类型 | 说明 | + | ----------- | ---- | ---- | -------------------------- | + | plugin_name | True | dict | 插件采集项预期修改结果数据 | + + plugin_name + + | 参数名 | 必选 | 类型 | 说明 | + | ------------ | ---- | ------ | ------------------ | + | collect_item | True | string | 采集项预期修改结果 | + ++ 请求参数示例: + + ```json + { + "gala-gopher":{ + "redis":"auto", + "system_inode":"on", + "tcp":"on", + "haproxy":"auto" + } + } + ``` + ++ 返回体参数: + + | 参数名 | 类型 | 说明 | + | ------ | ---------- | ---------------- | + | code | int | 返回码 | + | msg | str | 状态码对应的信息 | + | resp | List[dict] | 响应数据主体 | + + resp + + | 参数名 | 类型 | 说明 | + | ----------- | ---- | ------------------ | + | plugin_name | dict | 对应采集项修改结果 | + + plugin_name + + | 参数名 | 类型 | 说明 | + | ------- | --------- | ---------------- | + | success | List[str] | 修改成功的采集项 | + | failure | List[str] | 修改失败的采集项 | + ++ 返回示例: + + ```json + { + "code": 200, + "msg": "operate success", + "resp": { + "gala-gopher": { + "failure": [ + "redis" + ], + "success": [ + "system_inode", + "tcp", + "haproxy" + ] + } + } + } + ``` + +## 注意事项 + +1. 若有报错,请查看日志/var/log/aops/aops.log,根据日志中相关报错提示解决问题,并重启服务。 + +2. 建议项目在Python3.7以上环境运行,安装Python依赖库时需要注意其版本。 + +3. access_token值可在注册完成后,从`/etc/aops/agent.conf`文件中获取。 + +4. 对于插件CPU,以及内存的资源限制目前通过在插件对应service文件中的Service节点下添加MemoryHigh和CPUQuota标签实现。 + + 如对gala-gopher内存限制为40M,CPU限制为20%。 + + ```ini + [Unit] + Description=a-ops gala gopher service + After=network.target + + [Service] + Type=exec + ExecStart=/usr/bin/gala-gopher + Restart=on-failure + RestartSec=1 + RemainAfterExit=yes + ;尽可能限制该单元中的进程最多可以使用多少内存,该限制允许突破,但突破限制后,进程运行速度会收到限制,并且系统会尽可能回收超出的内存 + ;选项值可以是以字节为单位的 绝对内存大小(可以使用以1024为基数的 K, M, G, T 后缀), 也可以是以百分比表示的相对内存大小 + MemoryHigh=40M + ;为此单元的进程设置CPU时间限额,必须设为一个以"%"结尾的百分数, 表示该单元最多可使用单颗CPU总时间的百分之多少 + CPUQuota=20% + + [Install] + WantedBy=multi-user.target + ``` diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/deploying-aops.md b/docs/en/25.03/Server/Maintenance/A-Ops/deploying-aops.md new file mode 100644 index 0000000000000000000000000000000000000000..036dfb1c5dce06812491ea8192a0851bddafe7b9 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/A-Ops/deploying-aops.md @@ -0,0 +1,458 @@ +# A-Ops部署指南 + +## 环境要求 + +- 2台openEuler 24.09机器 + + 分别用于部署check模块的两种模式:调度器,执行器。其他服务如mysql、elasticsearch、aops-manager等可在任意一台机器独立部署,为便于操作,将这些服务部署在机器A。 + +- 内存尽量为:8G+ + +## 配置部署环境 + +### 机器A + +机器A需部署的aops服务有:aops-tools、aops-manager、aops-check、aops-hermes、aops-agent、gala-gopher。 + +需部署的第三方服务有:mysql、elasticsearch、zookeeper、kafka、prometheus。 + +具体部署步骤如下: + +#### 2.1 关闭防火墙 + +关闭本节点防火墙 + +```shell +systemctl stop firewalld +systemctl disable firewalld +systemctl status firewalld +``` + +#### 2.2 部署aops-tools + +安装aops-tools: + +```shell +yum install aops-tools +``` + +#### 2.3 部署数据库[mysql、elasticsearch] + +##### 2.3.1 部署mysql + +使用安装aops-tools时安装的aops-basedatabase脚本进行安装 + +```shell +cd /opt/aops/aops_tools +./aops-basedatabase mysql +``` + +修改mysql配置文件 + +```shell +vim /etc/my.cnf +``` + +新增bind-address, 值为本机ip + +![1662346986112](./figures/修改mysql配置文件.png) + +重启mysql服务 + +```shell +systemctl restart mysqld +``` + +连接数据库,设置权限: + +```shell +mysql +show databases; +use mysql; +select user,host from user;//出现user为root,host为localhost时,说明mysql只允许本机连接,外网和本地软件客户端则无法连接。 +update user set host = '%' where user='root'; +flush privileges;//刷新权限 +exit +``` + +##### 2.3.2 部署elasticsearch + +使用安装aops-tools时安装的aops-basedatabase脚本进行安装 + +```shell +cd /opt/aops/aops_tools +./aops-basedatabase elasticsearch +``` + +修改配置文件: + +修改elasticsearch配置文件: + +```shell +vim /etc/elasticsearch/elasticsearch.yml +``` + +![1662370718890](./figures/elasticsearch配置2.png) + +![1662370575036](./figures/elasticsearch配置1.png) + +![1662370776219](./figures/elasticsearch3.png) + +重启elasticsearch服务: + +```shell +systemctl restart elasticsearch +``` + +#### 2.4 部署aops-manager + +安装aops-manager + +```shell +yum install aops-manager +``` + +修改配置文件: + +```shell +vim /etc/aops/manager.ini +``` + +将配置文件中各服务的地址修改为真实地址,由于将所有服务都部署在机器A,故需把IP地址配为机器A的地址。 + +```shell +[manager] +ip=192.168.1.1 // 此处及后续服务ip修改为机器A真实ip +port=11111 +host_vault_dir=/opt/aops +host_vars=/opt/aops/host_vars + +[uwsgi] +wsgi-file=manage.py +daemonize=/var/log/aops/uwsgi/manager.log +http-timeout=600 +harakiri=600 + +[elasticsearch] +ip=192.168.1.1 // 此处及后续服务ip修改为机器A真实ip +port=9200 +max_es_query_num=10000000 + +[mysql] +ip=192.168.1.1 // 此处及后续服务ip修改为机器A真实ip +port=3306 +database_name=aops +engine_format=mysql+pymysql://@%s:%s/%s +pool_size=10000 +pool_recycle=7200 + +[aops_check] +ip=192.168.1.1 // 此处及后续服务ip修改为机器A真实ip +port=11112 +``` + +启动aops-manager服务: + +```shell +systemctl start aops-manager +``` + +#### 2.5 部署aops-hermes + +安装aops-hermes + +```shell +yum install aops-hermes +``` + +修改配置文件,由于将所有服务都部署在机器A,故需将web访问的各服务地址配置成机器A的真实ip。 + +```shell +vim /etc/nginx/aops-nginx.conf +``` + +部分服务配置截图: + +![1662378186528](./figures/配置web.png) + +开启aops-hermesb服务: + +```shell +systemctl start aops-hermes +``` + +#### 2.6 部署kafka + +##### 2.6.1 部署zookeeper + +安装: + +```shell +yum install zookeeper +``` + +启动服务: + +```shell +systemctl start zookeeper +``` + +##### 2.6.2 部署kafka + +安装: + +```shell +yum install kafka +``` + +修改配置文件: + +```shell +vim /opt/kafka/config/server.properties +``` + +将listener 改为本机ip + +![1662381371927](./figures/kafka配置.png) + +启动kafka服务: + +```shell +cd /opt/kafka/bin +nohup ./kafka-server-start.sh ../config/server.properties & +tail -f ./nohup.out # 查看nohup所有的输出出现A本机ip 以及 kafka启动成功INFO; +``` + +#### 2.7 部署aops-check + +安装aops-check: + +```shell +yum install aops-check +``` + +修改配置文件: + +```shell +vim /etc/aops/check.ini +``` + +将配置文件中各服务的地址修改为真实地址,由于将所有服务都部署在机器A,故需把IP地址配为机器A的地址。 + +```shell +[check] +ip=192.168.1.1 // 此处及后续服务ip修改为机器A真实ip +port=11112 +mode=configurable // 该模式为configurable模式,用于常规诊断模式下的调度器 +timing_check=on + +[default_mode] +period=30 +step=30 + +[elasticsearch] +ip=192.168.1.1 // 此处及后续服务ip修改为机器A真实ip +port=9200 + +[mysql] +ip=192.168.1.1 // 此处及后续服务ip修改为机器A真实ip +port=3306 +database_name=aops +engine_format=mysql+pymysql://@%s:%s/%s +pool_size=10000 +pool_recycle=7200 + +[prometheus] +ip=192.168.1.1 // 此处及后续服务ip修改为机器A真实ip +port=9090 +query_range_step=15s + +[agent] +default_instance_port=8888 + +[manager] +ip=192.168.1.1 // 此处及后续服务ip修改为机器A真实ip +port=11111 + +[consumer] +kafka_server_list=192.168.1.1:9092 // 此处及后续服务ip修改为机器A真实ip +enable_auto_commit=False +auto_offset_reset=earliest +timeout_ms=5 +max_records=3 +task_name=CHECK_TASK +task_group_id=CHECK_TASK_GROUP_ID +result_name=CHECK_RESULT +[producer] +kafka_server_list = 192.168.1.1:9092 // 此处及后续服务ip修改为机器A真实ip +api_version = 0.11.5 +acks = 1 +retries = 3 +retry_backoff_ms = 100 +task_name=CHECK_TASK +task_group_id=CHECK_TASK_GROUP_ID +``` + +启动aops-check服务(configurable模式): + +```shell +systemctl start aops-check +``` + +#### 2.8 部署客户端服务 + +客户端机器的服务需要部署aops-agent及gala-gopher,具体可参考[aops-agent部署指南](./deploying-aops-agent.md)。 + +注意:主机注册时需要先在前端添加主机组操作,确保该主机所属的主机组存在。此处只对机器A做部署、纳管。 + +#### 2.9 部署prometheus + +安装prometheus: + +```shell +yum install prometheus2 +``` + +修改配置文件: + +```shell +vim /etc/prometheus/prometheus.yml +``` + +将所有客户端的gala-gopher地址新增到prometheus的监控节点中。 + +![1662377261742](./figures/prometheus配置.png) + +启动服务: + +```shell +systemctl start prometheus +``` + +#### 2.10 部署gala-ragdoll + +A-Ops配置溯源功能依赖gala-ragdoll实现,通过Git实现配置文件的变动监测。 + +安装gala-ragdoll: + +```shell +yum install gala-ragdoll # A-Ops 配置溯源 +``` + +修改配置文件: + +```shell +vim /etc/ragdoll/gala-ragdoll.conf +``` + +将collect节点collect_address中IP地址修改为机器A的地址,collect_api与collect_port修改为实际接口地址。 + +```text +[git] +git_dir = "/home/confTraceTest" +user_name = "user_name" +user_email = "user_email" + +[collect] +collect_address = "http://192.168.1.1" //此处修改为机器A的真实IP +collect_api = "/manage/config/collect" //此处修改为配置文件采集的实际接口 +collect_port = 11111 //此处修改为服务的实际端口 + +[sync] +sync_address = "http://0.0.0.0" +sync_api = "/demo/syncConf" +sync_port = 11114 + + +[ragdoll] +port = 11114 + +``` + +启动gala-ragdoll服务 + +```shell +systemctl start gala-ragdoll +``` + +### 机器B + +机器B只需部署aops-check作为执行器。 + +#### 2.11 部署aops-check + +安装aops-check: + +```shell +yum install aops-check +``` + +修改配置文件: + +```shell +vim /etc/aops/check.ini +``` + +将配置文件中各服务的地址修改为真实地址,除check服务为机器B的地址外,其他服务都部署在机器A,故只需把IP地址配置为机器A的地址即可。 + +```shell +[check] +ip=192.168.1.2 // 此处ip改为机器B真实ip +port=11112 +mode=executor // executor,用于常规诊断模式下的执行器 +timing_check=on + +[default_mode] +period=30 +step=30 + +[elasticsearch] +ip=192.168.1.1 // 此处及后续服务ip修改为机器A真实ip +port=9200 + +[mysql] +ip=192.168.1.1 // 此处及后续服务ip修改为机器A真实ip +port=3306 +database_name=aops +engine_format=mysql+pymysql://@%s:%s/%s +pool_size=10000 +pool_recycle=7200 + +[prometheus] +ip=192.168.1.1 // 此处及后续服务ip修改为机器A真实ip +port=9090 +query_range_step=15s + +[agent] +default_instance_port=8888 + +[manager] +ip=192.168.1.1 // 此处及后续服务ip修改为机器A真实ip +port=11111 + +[consumer] +kafka_server_list=192.168.1.1:9092 // 此处及后续服务ip修改为机器A真实ip +enable_auto_commit=False +auto_offset_reset=earliest +timeout_ms=5 +max_records=3 +task_name=CHECK_TASK +task_group_id=CHECK_TASK_GROUP_ID +result_name=CHECK_RESULT +[producer] +kafka_server_list = 192.168.1.1:9092 // 此处及后续服务ip修改为机器A真实ip +api_version = 0.11.5 +acks = 1 +retries = 3 +retry_backoff_ms = 100 +task_name=CHECK_TASK +task_group_id=CHECK_TASK_GROUP_ID +``` + +启动aops-check服务(executor模式): + +```shell +systemctl start aops-check +``` + +至此,两台机器的服务部署完成。 diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/dnf-command-usage.md b/docs/en/25.03/Server/Maintenance/A-Ops/dnf-command-usage.md new file mode 100644 index 0000000000000000000000000000000000000000..d9e66e3dda25fd51db4898057461b301c3fdc8a7 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/A-Ops/dnf-command-usage.md @@ -0,0 +1,550 @@ +# dnf插件命令使用手册 + +首先需要安装dnf插件: + +```shell +dnf install dnf-hotpatch-plugin +``` + +将dnf热补丁插件安装完成后,可使用dnf命令调用热补丁操作,命令包含热补丁扫描(dnf hot-updateinfo),热补丁状态设置及查询(dnf hotpatch ),热补丁应用(dnf hotupgrade),本文将介绍上述命令的具体使用方法。 + +## 热补丁扫描 + +`hot-updateinfo`命令支持扫描热补丁并指定cve查询相关热补丁,命令使用方式如下: + +```shell +dnf hot-updateinfo list cves [--cve [cve_id]] + +General DNF options: + -h, --help, --help-cmd + show command help + --cve CVES, --cves CVES + Include packages needed to fix the given CVE, in updates + +``` + +- `--list` + +1. 查询主机所有可修复的cve和对应的冷/热补丁。 + + ```shell + [root@localhost dnf]# dnf hot-updateinfo list cves + # cve-id level cold-patch hot-patch + Last metadata expiration check: 0:54:46 ago on 2023年03月16日 星期四 09时40分27秒. + CVE-2022-3080 Important/Sec. bind-libs-9.16.23-10.oe2203.aarch64 patch-bind-libs-9.16.23-09-name-1-111.aarch64 + CVE-2021-25220 Moderate/Sec. bind-9.16.23-10.oe2203.aarch64 - + CVE-2022-1886 Critical/Sec. vim-common-8.2-39.oe2203.aarch64 patch-vim-common-8.2-38-name-1-233.aarch64 + CVE-2022-1725 Low/Sec. vim-minimal-8.2-58.oe2203.aarch64 patch-vim-minimal-8.2-57-name-2-11.aarch64 + ``` + +2. 指定cve查询对应的冷/热补丁。 + + ```shell + [root@localhost dnf]# dnf hot-updateinfo list cves --cve CVE-2022-3080 + # cve-id level cold-patch hot-patch + Last metadata expiration check: 0:54:46 ago on 2023年03月16日 星期四 09时40分27秒. + CVE-2022-3080 Important/Sec. bind-libs-9.16.23-10.oe2203.aarch64 patch-bind-libs-9.16.23-09-name-1-111.aarch64 + ``` + +3. cve不存在时列表为空。 + + ```shell + [root@localhost dnf]# dnf hot-updateinfo list cves --cve CVE-2022-3089 + # cve-id level cold-patch hot-patch + Last metadata expiration check: 0:54:46 ago on 2023年03月16日 星期四 09时40分27秒. + ``` + +## 热补丁状态及转换图 + +- 热补丁状态图 + + NOT-APPLIED: 热补丁尚未安装。 + + DEACTIVED: 热补丁已被安装。 + + ACTIVED: 热补丁已被激活。 + + ACCEPT: 热补丁已被接受,后续重启后会被自动应用。 + + ![热补丁状态转换图](./figures/热补丁状态图.png) + +## 热补丁状态查询和切换 + +`hotpatch`命令支持查询、切换热补丁的状态,命令使用方式如下: + +```shell +dnf hotpatch + +General DNF options: + -h, --help, --help-cmd + show command help + --cve CVES, --cves CVES + Include packages needed to fix the given CVE, in updates + +Hotpatch command-specific opetions: + --list [{cve, cves}] show list of hotpatch + --apply APPLY_NAME apply hotpatch + --remove REMOVE_NAME remove hotpatch + --active ACTIVE_NAME active hotpatch + --deactive DEACTIVE_NAME + deactive hotpatch + --accept ACCEPT_NAME accept hotpatch +``` + +1. 使用`dnf hotpatch --list`命令查询当前系统中可使用的热补丁状态并展示。 + + ```shell + [root@localhost dnf]# dnf hotpatch --list + Last metadata expiration check: 0:54:46 ago on 2023年03月16日 星期四 09时40分27秒. + base-pkg/hotpatch status + redis-6.2.5-1/HP001 NOT-APPLIED + redis-6.2.5-1/HP001 NOT-APPLIED + redis-6.2.5-1/HP002 ACTIVED + redis-6.2.5-1/HP002 ACTIVED + ``` + +2. 使用`dnf hotpatch --list cves`查询漏洞(CVE-id)对应热补丁及其状态并展示。 + + ```shell + [root@localhost dnf]# dnf hotpatch --list cves + Last metadata expiration check: 0:54:46 ago on 2023年03月16日 星期四 09时40分27秒. + CVE-id base-pkg/hotpatch status + CVE-2023-1111 redis-6.2.5-1/HP001 NOT-APPLIED + CVE-2023-1112 redis-6.2.5-1/HP001 NOT-APPLIED + CVE-2023-2221 redis-6.2.5-1/HP002 ACTIVED + CVE-2023-2222 redis-6.2.5-1/HP002 ACTIVED + ``` + +3. 使用`dnf hotpatch --list cves --cve `筛选指定CVE对应的热补丁及其状态并展示。 + + ```shell + [root@localhost dnf]# dnf hotpatch --list cves --cve CVE-2023-1111 + Last metadata expiration check: 0:54:46 ago on 2023年03月16日 星期四 09时40分27秒. + CVE-id base-pkg/hotpatch status + CVE-2023-1111 redis-6.2.5-1/HP001 NOT-APPLIED + ``` + +4. 使用`dnf hotpatch --list cves --cve `查询无结果时展示为空。 + + ```shell + [root@localhost dnf]# dnf hotpatch --list cves --cve CVE-2023-1 + Last metadata expiration check: 0:54:46 ago on 2023年03月16日 星期四 09时40分27秒. + ``` + +5. 使用`dnf hotpatch --apply `命令应用热补丁,可使用`syscare list`查询应用后的状态变化,变化逻辑见上文的热补丁状态转换图。 + + ```shell + [root@openEuler dnf-plugins]# dnf hotpatch --apply redis-6.2.5-1/HP2 + Last metadata expiration check: 2:38:51 ago on 2023年05月25日 星期四 13时49分28秒. + Gonna apply this hot patch: redis-6.2.5-1/HP2 + apply hot patch 'redis-6.2.5-1/HP2' succeed + [root@openEuler dnf-plugins]# syscare list + Uuid Name Status + 25209ddc-b1e4-48e0-b715-e759ec8db401 redis-6.2.5-1/HP2 ACTIVED + ``` + +6. 使用`dnf hotpatch --deactive `停用热补丁,可使用`syscare list`查询停用后的状态变化,变化逻辑见上文的热补丁状态转换图。 + + ```shell + [root@openEuler dnf-plugins]# dnf hotpatch --deactive redis-6.2.5-1/HP2 + Last metadata expiration check: 2:39:10 ago on 2023年05月25日 星期四 13时49分28秒. + Gonna deactive this hot patch: redis-6.2.5-1/HP2 + deactive hot patch 'redis-6.2.5-1/HP2' succeed + [root@openEuler dnf-plugins]# syscare list + Uuid Name Status + 25209ddc-b1e4-48e0-b715-e759ec8db401 redis-6.2.5-1/HP2 DEACTIVED + ``` + +7. 使用`dnf hotpatch --remove `删除热补丁,可使用`syscare list`查询删除后的状态变化,变化逻辑见上文的热补丁状态转换图。 + + ```shell + [root@openEuler dnf-plugins]# dnf hotpatch --remove redis-6.2.5-1/HP2 + Last metadata expiration check: 2:53:25 ago on 2023年05月25日 星期四 13时49分28秒. + Gonna remove this hot patch: redis-6.2.5-1/HP2 + remove hot patch 'redis-6.2.5-1/HP2' succeed + [root@openEuler dnf-plugins]# syscare list + Uuid Name Status + 25209ddc-b1e4-48e0-b715-e759ec8db401 redis-6.2.5-1/HP2 NOT-APPLIED + ``` + +8. 使用`dnf hotpatch --active `激活热补丁,可使用`syscare list`查询激活后的状态变化,变化逻辑见上文的热补丁状态转换图。 + + ```shell + [root@openEuler dnf-plugins]# dnf hotpatch --active redis-6.2.5-1/HP2 + Last metadata expiration check: 2:53:37 ago on 2023年05月25日 星期四 13时49分28秒. + Gonna active this hot patch: redis-6.2.5-1/HP2 + active hot patch 'redis-6.2.5-1/HP2' failed, remain original status. + [root@openEuler dnf-plugins]# syscare list + Uuid Name Status + 25209ddc-b1e4-48e0-b715-e759ec8db401 redis-6.2.5-1/HP2 ACTIVED + ``` + +9. 使用`dnf hotpatch --accept `接收热补丁,可使用`syscare list`查询接收后的状态变化,变化逻辑见上文的热补丁状态转换图。 + + ```shell + [root@openEuler dnf-plugins]# dnf hotpatch --accept redis-6.2.5-1/HP2 + Last metadata expiration check: 2:53:25 ago on 2023年05月25日 星期四 13时49分28秒. + Gonna accept this hot patch: redis-6.2.5-1/HP2 + remove hot patch 'redis-6.2.5-1/HP2' succeed + [root@openEuler dnf-plugins]# syscare list + Uuid Name Status + 25209ddc-b1e4-48e0-b715-e759ec8db401 redis-6.2.5-1/HP2 ACCEPTED + ``` + +## 热补丁应用 + +`hotupgrade`命令根据cve id和热补丁名称进行热补丁修复,同时也支持全量修复。命令使用方式如下: + +```shell +dnf hotupgrade [--cve [cve_id]] [SPEC ...] + +General DNF options: + -h, --help, --help-cmd + show command help + --cve CVES, --cves CVES + Include packages needed to fix the given CVE, in updates + +command-specific options: + SPEC Hotpatch specification +``` + +- Case1:当热补丁已经安装时,使用`dnf hotupgrade`安装所有存在的热补丁。这时dnf hotupgrade会返回形如"Package xx is already installed."提示信息,告诉用户该软件包已安装。 + + ```shell + [root@openEuler aops-ceres]# dnf hotupgrade + Last metadata expiration check: 4:04:34 ago on 2023年06月02日 星期五 06时33分41秒. + Gonna apply these hot patches:['patch-redis-6.2.5-1-HP001-1-1.x86_64', 'patch-redis-6.2.5-1-HP002-1-1.x86_64'] + The target package 'redis-6.2.5-1' has a hotpatch 'HP001' applied + Gonna remove these hot patches: ['redis-6.2.5-1/HP001'] + Remove hot patch redis-6.2.5-1/HP001. + Package patch-redis-6.2.5-1-HP001-1-1.x86_64 is already installed. + Package patch-redis-6.2.5-1-HP002-1-1.x86_64 is already installed. + Dependencies resolved. + Nothing to do. + Complete! + Applying hot patch + Apply hot patch succeed: redis-6.2.5-1/HP001. + Apply hot patch failed: redis-6.2.5-1/HP002. + ``` + +- Case2: 热补丁未安装时,使用`dnf hotupgrade`命令安装存在的所有热补丁,将显示安装信息。(补充:使用hotupgrade命令时,如果热补丁已安装,会提示case1中的返回信息,如果未安装,则会返回次case中的信息。) + + ```shell + [root@openEuler A-ops]# dnf hotupgrade + Last metadata expiration check: 4:13:16 ago on 2023年06月02日 星期五 06时33分41秒. + Gonna apply these hot patches:['patch-redis-6.2.5-1-HP002-1-1.x86_64', 'patch-redis-6.2.5-1-HP001-1-1.x86_64'] + Package patch-redis-6.2.5-1-HP002-1-1.x86_64 is already installed. + Dependencies resolved. + xxxx(Install messgaes) + Is this ok [y/N]: y + Downloading Packages: + xxxx(Install process) + Complete! + + Applying hot patch + Apply hot patch succeed: redis-6.2.5-1/HP001. + ``` + +- Case3: 使用`dnf hotupgrade `升级指定热补丁包。 + + ```shell + [root@openEuler ~]# dnf hotupgrade patch-redis-6.2.5-1-HP001-1-1.x86_64 + Last metadata expiration check: 0:07:49 ago on 2023年06月08日 星期四 12时03分46秒. + Package patch-redis-6.2.5-1-HP001-1-1.x86_64 is already installed. + Dependencies resolved. + Nothing to do. + Complete! + Applying hot patch + Apply hot patch succeed: redis-6.2.5-1/HP001. + ``` + +- `--cve` + + - Case1:使用`dnf hotupgrade --cve `指定cve_id安装指定CVE对应的热补丁。 + + ```shell + [root@localhost dnf]# dnf hotupgrade --cve CVE-2021-11 + Last metadata expiration check: xxx + Dependencies resolved. + xxxx(Install messgaes) + Is this ok [y/N]: y + Downloading Packages: + xxxx(Install process) + Complete! + Applying hot patch + Apply hot patch succeed: redis-6.2.5-1/HP001 + ``` + + - Case2:使用`dnf hotupgrade --cve `指定cve_id安装时cve不存在。 + + ```shell + [root@localhost dnf]# dnf hotupgrade --cve CVE-2021-11 + Last metadata expiration check: xxx + The cve doesnt exist: CVE-2021-11 + Error: No hot patches marked for install. + ``` + + - Case3:使用`dnf hotupgrade --cve `指定cve_id安装时,该CVE对应的低版本热补丁已安装时,删除低版本热补丁包,安装高版本热补丁包。 + + ```shell + [root@localhost dnf]# dnf hotupgrade --cve CVE-2021-22 + Last metadata expiration check: xxx + The target package 'redis-6.2.5-1' has a hotpatch 'HP001' applied + Gonna remove these hot patches: ['redis-6.2.5-1/HP001'] + Is this ok [y/N]: y + Remove hot patch redis-6.2.5-1/HP001 + xxxx (install messages and process install) + Apply hot patch + apply hot patch succeed: redis-6.2.5-1/HP002 + ``` + + - Case4:使用`dnf hotupgrade --cve `指定cve_id安装时,该CVE对应的最高版本热补丁包已存在。 + + ```shell + [root@localhost dnf]# dnf hotupgrade --cve CVE-2021-22 + Package patch -redis-6.2.5-1-HP002-1-1.x86_64 is already installed. + Dependencies resolved. + Nothing to do. + Complete! + Applying hot patch + Apply hot patch succeed: redis-6.2.5-1/HP002 + ``` + +- `SPEC` + + ```shell + [root@localhost dnf]# dnf hotupgrade bind-libs-hotpatch + ``` + +子命令的输出根据不同的情况与"--cve"命令相同。 + +## 使用场景说明 + +本段落介绍上述命令的使用场景及顺序介绍,需要提前确认本机的热补丁repo源和相应冷补丁repo源已开启。 + +使用热补丁扫描命令查看本机待修复cve。 + +```shell +[root@openEuler aops-apollo_src]# dnf hot-updateinfo list cves +Last metadata expiration check: 0:00:38 ago on 2023年03月25日 星期六 11时53分46秒. +CVE-2023-22995 Important/Sec. python3-perf-5.10.0-136.22.0.98.oe2203sp1.x86_64 - +CVE-2023-26545 Important/Sec. python3-perf-5.10.0-136.22.0.98.oe2203sp1.x86_64 - +CVE-2022-40897 Important/Sec. python3-setuptools-59.4.0-5.oe2203sp1.noarch - +CVE-2021-1 Important/Sec. redis-6.2.5-2.x86_64 patch-redis-6.2.5-1-HP001-1-1.x86_64 +CVE-2021-11 Important/Sec. redis-6.2.5-2.x86_64 patch-redis-6.2.5-1-HP001-1-1.x86_64 +CVE-2021-2 Important/Sec. redis-6.2.5-3.x86_64 patch-redis-6.2.5-1-HP002-1-1.x86_64 +CVE-2021-22 Important/Sec. redis-6.2.5-3.x86_64 patch-redis-6.2.5-1-HP002-1-1.x86_64 +CVE-2021-33 Important/Sec. redis-6.2.5-4.x86_64 - +CVE-2021-3 Important/Sec. redis-6.2.5-4.x86_64 - +CVE-2022-38023 Important/Sec. samba-client-4.17.2-5.oe2203sp1.x86_64 - +CVE-2022-37966 Important/Sec. samba-client-4.17.2-5.oe2203sp1.x86_64 - +``` + +找到提供热补丁的相应cve,发现CVE-2021-1、CVE-2021-11、CVE-2021-2和CVE-2021-22可用热补丁修复。 + +在安装补丁前测试功能,基于redis.conf配置文件启动redis服务。 + +```shell +[root@openEuler redis_patch]# sudo redis-server ./redis.conf & +[1] 285075 +[root@openEuler redis_patch]# 285076:C 25 Mar 2023 12:09:51.503 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo +285076:C 25 Mar 2023 12:09:51.503 # Redis version=255.255.255, bits=64, commit=00000000, modified=0, pid=285076, just started +285076:C 25 Mar 2023 12:09:51.503 # Configuration loaded +285076:M 25 Mar 2023 12:09:51.504 * Increased maximum number of open files to 10032 (it was originally set to 1024). +285076:M 25 Mar 2023 12:09:51.504 * monotonic clock: POSIX clock_gettime + _._ + _.-``__ ''-._ + _.-`` `. `_. ''-._ Redis 255.255.255 (00000000/0) 64 bit + .-`` .-```. ```\/ _.,_ ''-._ + ( ' , .-` | `, ) Running in standalone mode + |`-._`-...-` __...-.``-._|'` _.-'| Port: 6380 + | `-._ `._ / _.-' | PID: 285076 + `-._ `-._ `-./ _.-' _.-' + |`-._`-._ `-.__.-' _.-'_.-'| + | `-._`-._ _.-'_.-' | https://redis.io + `-._ `-._`-.__.-'_.-' _.-' + |`-._`-._ `-.__.-' _.-'_.-'| + | `-._`-._ _.-'_.-' | + `-._ `-._`-.__.-'_.-' _.-' + `-._ `-.__.-' _.-' + `-._ _.-' + `-.__.-' + +285076:M 25 Mar 2023 12:09:51.505 # Server initialized +285076:M 25 Mar 2023 12:09:51.505 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect. +285076:M 25 Mar 2023 12:09:51.506 * Ready to accept connections + +``` + +安装前测试功能。 + +```shell +[root@openEuler ~]# telnet 127.0.0.1 6380 +Trying 127.0.0.1... +Connected to 127.0.0.1. +Escape character is '^]'. + +*100 + +-ERR Protocol error: expected '$', got ' ' +Connection closed by foreign host. +``` + +指定修复CVE-2021-1,确认关联到对应的热补丁包,显示安装成功。 + +```shell +[root@openEuler aops-apollo_src]# dnf hotupgrade --cve CVE-2021-1 +Last metadata expiration check: 0:05:19 ago on 2023年03月25日 星期六 11时53分46秒. +Package patch-redis-6.2.5-1-HP001-1-1.x86_64 is already installed. +Dependencies resolved. +Nothing to do. +Complete! +Applying hot patch +Apply hot patch succeed: redis-6.2.5-1/HP001. +``` + +使用syscare确认该热补丁是否安装成功,确认Status为ACTIVED。 + +```shell +[root@openEuler ~]# syscare list +Uuid Name Status +cf47649c-b370-4f5a-a914-d2ca4d8f1f3a redis-6.2.5-1/HP001 ACTIVED +``` + +确认该cve是否已被修复,由于CVE-2021-1所使用的热补丁包patch-redis-6.2.5-1-HP001-1-1.x86_64同样修复CVE-2021-11,CVE-2021-1和CVE-2021-11都不予显示。 + +```shell +[root@openEuler dnf-plugins]# dnf hot-updateinfo list cves +Last metadata expiration check: 0:08:48 ago on 2023年03月25日 星期六 11时53分46秒. +CVE-2023-22995 Important/Sec. python3-perf-5.10.0-136.22.0.98.oe2203sp1.x86_64 - +CVE-2023-1076 Important/Sec. python3-perf-5.10.0-136.22.0.98.oe2203sp1.x86_64 - +CVE-2023-26607 Important/Sec. python3-perf-5.10.0-136.22.0.98.oe2203sp1.x86_64 - +CVE-2022-40897 Important/Sec. python3-setuptools-59.4.0-5.oe2203sp1.noarch - +CVE-2021-22 Important/Sec. redis-6.2.5-3.x86_64 patch-redis-6.2.5-1-HP002-1-1.x86_64 +CVE-2021-2 Important/Sec. redis-6.2.5-3.x86_64 patch-redis-6.2.5-1-HP002-1-1.x86_64 +CVE-2021-33 Important/Sec. redis-6.2.5-4.x86_64 - +CVE-2021-3 Important/Sec. redis-6.2.5-4.x86_64 - +CVE-2022-38023 Important/Sec. samba-client-4.17.2-5.oe2203sp1.x86_64 - +CVE-2022-37966 Important/Sec. samba-client-4.17.2-5.oe2203sp1.x86_64 - +``` + +激活后测试功能,对比激活前回显内容。 + +```shell +[root@openEuler ~]# telnet 127.0.0.1 6380 +Trying 127.0.0.1... +Connected to 127.0.0.1. +Escape character is '^]'. + +*100 + +-ERR Protocol error: unauthenticated multibulk length +Connection closed by foreign host. +``` + +由于热补丁还未开发完卸载功能,使用syscare指定Name手动卸载。 + +```shell +[root@openEuler ~]# syscare remove redis-6.2.5-1/HP001 +[root@openEuler ~]# syscare list +Uuid Name Status +cf47649c-b370-4f5a-a914-d2ca4d8f1f3a redis-6.2.5-1/HP001 NOT-APPLIED +``` + +使用热补丁扫描命令查看本机待修复cve,确认CVE-2021-1和CVE-2021-11正常显示。 + +```shell +[root@openEuler aops-apollo_src]# dnf hot-updateinfo list cves +Last metadata expiration check: 0:00:38 ago on 2023年03月25日 星期六 11时53分46秒. +CVE-2023-22995 Important/Sec. python3-perf-5.10.0-136.22.0.98.oe2203sp1.x86_64 - +CVE-2023-26545 Important/Sec. python3-perf-5.10.0-136.22.0.98.oe2203sp1.x86_64 - +CVE-2022-40897 Important/Sec. python3-setuptools-59.4.0-5.oe2203sp1.noarch - +CVE-2021-1 Important/Sec. redis-6.2.5-2.x86_64 patch-redis-6.2.5-1-HP001-1-1.x86_64 +CVE-2021-11 Important/Sec. redis-6.2.5-2.x86_64 patch-redis-6.2.5-1-HP001-1-1.x86_64 +CVE-2021-2 Important/Sec. redis-6.2.5-3.x86_64 patch-redis-6.2.5-1-HP002-1-1.x86_64 +CVE-2021-22 Important/Sec. redis-6.2.5-3.x86_64 patch-redis-6.2.5-1-HP002-1-1.x86_64 +CVE-2021-33 Important/Sec. redis-6.2.5-4.x86_64 - +CVE-2021-3 Important/Sec. redis-6.2.5-4.x86_64 - +CVE-2022-38023 Important/Sec. samba-client-4.17.2-5.oe2203sp1.x86_64 - +CVE-2022-37966 Important/Sec. samba-client-4.17.2-5.oe2203sp1.x86_64 - +``` + +- case 1 + +指定安装热补丁包patch-redis-6.2.5-1-HP002-1-1.x86_64。 + +```shell +[root@openEuler aops-apollo_src]# dnf hotupgrade patch-redis-6.2.5-1-HP002-1-1.x86_64 +Last metadata expiration check: 0:05:19 ago on 2023年03月25日 星期六 11时53分46秒. +Package patch-redis-6.2.5-1-HP002-1-1.x86_64 is already installed. +Dependencies resolved. +Nothing to do. +Complete! +Applying hot patch +Apply hot patch succeed: redis-6.2.5-1/HP002. +``` + +使用热补丁扫描命令查看本机待修复cve,由于patch-redis-6.2.5-1-HP002-1-1.x86_64对应的冷补丁redis-6.2.5-3.x86_64比redis-6.2.5-2.x86_64版本高,redis-6.2.5-2.x86_64对应的CVE-2021-1和CVE-2021-11,以及CVE-2021-2和CVE-2021-22都被修复。 + +```shell +[root@openEuler aops-apollo_src]# dnf hot-updateinfo list cves +Last metadata expiration check: 0:00:38 ago on 2023年03月25日 星期六 11时53分46秒. +CVE-2023-22995 Important/Sec. python3-perf-5.10.0-136.22.0.98.oe2203sp1.x86_64 - +CVE-2023-26545 Important/Sec. python3-perf-5.10.0-136.22.0.98.oe2203sp1.x86_64 - +CVE-2022-40897 Important/Sec. python3-setuptools-59.4.0-5.oe2203sp1.noarch - +CVE-2021-33 Important/Sec. redis-6.2.5-4.x86_64 - +CVE-2021-3 Important/Sec. redis-6.2.5-4.x86_64 - +CVE-2022-38023 Important/Sec. samba-client-4.17.2-5.oe2203sp1.x86_64 - +CVE-2022-37966 Important/Sec. samba-client-4.17.2-5.oe2203sp1.x86_64 - +``` + +- case 2 + +查看热补丁repo源中repodata目录下的xxx-updateinfo.xml.gz,确认文件中的CVE-2021-33、CVE-2021-3相关信息。 + +```xml + + openEuler-SA-2022-3 + An update for mariadb is now available for openEuler-22.03-LTS + Important + openEuler + + + + + + patch-redis-6.2.5-2-HP001.(CVE-2022-24048) + + + openEuler + + patch-redis-6.2.5-2-HP001-1-1.aarch64.rpm + + + patch-redis-6.2.5-2-HP001-1-1.x86_64.rpm + + + + +``` + +package中的name字段"patch-redis-6.2.5-2-HP001"的组成部分为:patch-源码包名-源码包版本-源码包release-热补丁包名,该热补丁包需要本机安装redis-6.2.5-2源码版本,检查本机redis安装版本。 + +```shell +[root@openEuler ~]# rpm -qa | grep redis +redis-6.2.5-1.x86_64 +``` + +由于本机安装版本不匹配,该热补丁包名不显示,以'-'显示。 + +```shell +[root@openEuler aops-apollo_src]# dnf hot-updateinfo list cves +Last metadata expiration check: 0:00:38 ago on 2023年03月25日 星期六 11时53分46秒. +CVE-2023-22995 Important/Sec. python3-perf-5.10.0-136.22.0.98.oe2203sp1.x86_64 - +CVE-2023-26545 Important/Sec. python3-perf-5.10.0-136.22.0.98.oe2203sp1.x86_64 - +CVE-2022-40897 Important/Sec. python3-setuptools-59.4.0-5.oe2203sp1.noarch - +CVE-2021-33 Important/Sec. redis-6.2.5-4.x86_64 - +CVE-2021-3 Important/Sec. redis-6.2.5-4.x86_64 - +CVE-2022-38023 Important/Sec. samba-client-4.17.2-5.oe2203sp1.x86_64 - +CVE-2022-37966 Important/Sec. samba-client-4.17.2-5.oe2203sp1.x86_64 - +``` diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/029B66B9-5A3E-447E-B33C-98B894FC4833.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/029B66B9-5A3E-447E-B33C-98B894FC4833.png new file mode 100644 index 0000000000000000000000000000000000000000..230489c21dba54311356bbf2df56e817c0975f91 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/029B66B9-5A3E-447E-B33C-98B894FC4833.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/0BFA7C40-D404-4772-9C47-76EAD7D24E69.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/0BFA7C40-D404-4772-9C47-76EAD7D24E69.png new file mode 100644 index 0000000000000000000000000000000000000000..528bf4e30dc6221c496dd9a6d637359f592856db Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/0BFA7C40-D404-4772-9C47-76EAD7D24E69.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631073636579.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631073636579.png new file mode 100644 index 0000000000000000000000000000000000000000..5aacc487264ac63fbe5322b4f89fca3ebf9c7cd9 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631073636579.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631073840656.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631073840656.png new file mode 100644 index 0000000000000000000000000000000000000000..122e391eafe7c0d8d081030a240df90aea260150 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631073840656.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631101736624.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631101736624.png new file mode 100644 index 0000000000000000000000000000000000000000..74e2f2ded2ea254c66b221e8ac27a0d8bed9362a Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631101736624.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631101865366.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631101865366.png new file mode 100644 index 0000000000000000000000000000000000000000..abfbc280a368b93af1e1165385af3a9cac89391d Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631101865366.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631101982829.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631101982829.png new file mode 100644 index 0000000000000000000000000000000000000000..0b1c9c7c3676b804dbdf19afbe4f3ec9dbe0627f Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631101982829.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631102019026.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631102019026.png new file mode 100644 index 0000000000000000000000000000000000000000..54e8e7d1cffbb28711074e511b08c73f66c1fb75 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/1631102019026.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/20210908212726.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/20210908212726.png new file mode 100644 index 0000000000000000000000000000000000000000..f7d399aecd46605c09fe2d1f50a1a8670cd80432 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/20210908212726.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/D466AC8C-2FAF-4797-9A48-F6C346A1EC77.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/D466AC8C-2FAF-4797-9A48-F6C346A1EC77.png new file mode 100644 index 0000000000000000000000000000000000000000..d87c5e04fa8cf4f2af0884226be66ddfb5f481e1 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/D466AC8C-2FAF-4797-9A48-F6C346A1EC77.png differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/a-ops\350\275\257\344\273\266\346\236\266\346\236\204.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/a-ops\350\275\257\344\273\266\346\236\266\346\236\204.png" new file mode 100644 index 0000000000000000000000000000000000000000..047c6f1bfe3e38c66d34285563d910f6f3bd07e1 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/a-ops\350\275\257\344\273\266\346\236\266\346\236\204.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/app\350\257\246\346\203\205.jpg" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/app\350\257\246\346\203\205.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..bd179be46c9e711d7148ee44dc56f4a7a02f56bf Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/app\350\257\246\346\203\205.jpg" differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/chakanyuqi.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/chakanyuqi.png new file mode 100644 index 0000000000000000000000000000000000000000..bbead6a91468d5dee570cfdc66faf9a4ab155d7c Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/chakanyuqi.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/chaxunshijipeizhi.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/chaxunshijipeizhi.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f6e450fc0e1e246492ca71a6fcd8db572eb469 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/chaxunshijipeizhi.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/check.PNG b/docs/en/25.03/Server/Maintenance/A-Ops/figures/check.PNG new file mode 100644 index 0000000000000000000000000000000000000000..2dce821dd43eec6f0d13cd6b2dc1e30653f35489 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/check.PNG differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/chuangjianyewuyu.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/chuangjianyewuyu.png new file mode 100644 index 0000000000000000000000000000000000000000..8849a2fc81dbd14328c6c66c53033164a0b67b52 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/chuangjianyewuyu.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/conf_file_trace.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/conf_file_trace.png new file mode 100644 index 0000000000000000000000000000000000000000..e1e518157f8def332adfa5516b37fdb89768499c Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/conf_file_trace.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/dashboard.PNG b/docs/en/25.03/Server/Maintenance/A-Ops/figures/dashboard.PNG new file mode 100644 index 0000000000000000000000000000000000000000..2a4a827191367309aad28a8a6c1835df602bdf72 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/dashboard.PNG differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/deploy.PNG b/docs/en/25.03/Server/Maintenance/A-Ops/figures/deploy.PNG new file mode 100644 index 0000000000000000000000000000000000000000..e30dcb0eb05eb4f41202c736863f3e0ff216398d Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/deploy.PNG differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/diag.PNG b/docs/en/25.03/Server/Maintenance/A-Ops/figures/diag.PNG new file mode 100644 index 0000000000000000000000000000000000000000..a67e8515b8313a50b06cb985611ef9c166851811 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/diag.PNG differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/domain.PNG b/docs/en/25.03/Server/Maintenance/A-Ops/figures/domain.PNG new file mode 100644 index 0000000000000000000000000000000000000000..bad499f96df5934565d36edf2308cec5e4147719 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/domain.PNG differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/domain_config.PNG b/docs/en/25.03/Server/Maintenance/A-Ops/figures/domain_config.PNG new file mode 100644 index 0000000000000000000000000000000000000000..8995424b35cda75f08881037446b7816a0ca09dc Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/domain_config.PNG differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/elasticsearch3.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/elasticsearch3.png new file mode 100644 index 0000000000000000000000000000000000000000..893aae242aa9117c64f323374d4728d230894973 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/elasticsearch3.png differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/elasticsearch\351\205\215\347\275\2561.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/elasticsearch\351\205\215\347\275\2561.png" new file mode 100644 index 0000000000000000000000000000000000000000..1b7e0eab093b2f0455b8f3972884e5f757fbec3d Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/elasticsearch\351\205\215\347\275\2561.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/elasticsearch\351\205\215\347\275\2562.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/elasticsearch\351\205\215\347\275\2562.png" new file mode 100644 index 0000000000000000000000000000000000000000..620dbbda71259e3b6ee6a2efb646a9692adf2456 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/elasticsearch\351\205\215\347\275\2562.png" differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/group.PNG b/docs/en/25.03/Server/Maintenance/A-Ops/figures/group.PNG new file mode 100644 index 0000000000000000000000000000000000000000..584fd1f7195694a3419482cace2a71fa1cd9a3ec Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/group.PNG differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/host.PNG b/docs/en/25.03/Server/Maintenance/A-Ops/figures/host.PNG new file mode 100644 index 0000000000000000000000000000000000000000..3c00681a567cf8f1e1baddfb6fdb7b6cf7df43de Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/host.PNG differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/jiemi.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/jiemi.png new file mode 100644 index 0000000000000000000000000000000000000000..da07cfdf9296e201a82cceb210e651261fe7ecee Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/jiemi.png differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/kafka\351\205\215\347\275\256.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/kafka\351\205\215\347\275\256.png" new file mode 100644 index 0000000000000000000000000000000000000000..57eb17ccbd2fa63d97f700c29847fac7f08042ff Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/kafka\351\205\215\347\275\256.png" differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/peizhitongbu.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/peizhitongbu.png new file mode 100644 index 0000000000000000000000000000000000000000..c8c229bf41b27f1fe6629106957fd5e47851096d Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/peizhitongbu.png differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/prometheus\351\205\215\347\275\256.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/prometheus\351\205\215\347\275\256.png" new file mode 100644 index 0000000000000000000000000000000000000000..7c8d0328967e8eb9bc4aa7465a273b9ef5a30b58 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/prometheus\351\205\215\347\275\256.png" differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/shanchupeizhi.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/shanchupeizhi.png new file mode 100644 index 0000000000000000000000000000000000000000..cfea2eb44f7b8aa809404b8b49b4bd2e24172568 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/shanchupeizhi.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/shanchuzhuji.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/shanchuzhuji.png new file mode 100644 index 0000000000000000000000000000000000000000..b3da935739369dad1318fe135146755ede13c694 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/shanchuzhuji.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/shanchuzhujizu.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/shanchuzhujizu.png new file mode 100644 index 0000000000000000000000000000000000000000..e4d85f6e3f1a269a483943f5115f54daa3de51de Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/shanchuzhujizu.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/spider.PNG b/docs/en/25.03/Server/Maintenance/A-Ops/figures/spider.PNG new file mode 100644 index 0000000000000000000000000000000000000000..53bad6dd38e36db9cadfdbeda21cbc3ef59eddf7 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/spider.PNG differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/spider_detail.jpg b/docs/en/25.03/Server/Maintenance/A-Ops/figures/spider_detail.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6d4d2e2b9e79c53dbd359faa03e1c90f07c0ade6 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/spider_detail.jpg differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/tianjianode.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/tianjianode.png new file mode 100644 index 0000000000000000000000000000000000000000..d68f5e12a62548f2ec59374bda9ab07f43b8b5cb Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/tianjianode.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/tianjiazhujizu.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/tianjiazhujizu.png new file mode 100644 index 0000000000000000000000000000000000000000..ed4ab3616d418ecf33a006fee3985b8b6d2d965d Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/tianjiazhujizu.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/xinzengpeizhi.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/xinzengpeizhi.png new file mode 100644 index 0000000000000000000000000000000000000000..18d71c2e099c19b5d28848eec6a8d11f29ccee27 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/xinzengpeizhi.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/zhuangtaichaxun.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/zhuangtaichaxun.png new file mode 100644 index 0000000000000000000000000000000000000000..a3d0b3294bf6e0eeec50a2c2f8c5059bdc256376 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/zhuangtaichaxun.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/zhuji.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/zhuji.png new file mode 100644 index 0000000000000000000000000000000000000000..f4c7b9103baab7748c83392f6120c8f00880860f Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/zhuji.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/figures/zuneizhuji.png b/docs/en/25.03/Server/Maintenance/A-Ops/figures/zuneizhuji.png new file mode 100644 index 0000000000000000000000000000000000000000..9f188d207162fa1418a61a10f83ef9c51a512e65 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/figures/zuneizhuji.png differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\270\273\346\234\272\347\256\241\347\220\206.jpg" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\270\273\346\234\272\347\256\241\347\220\206.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..9f6d8858468c0cc72c1bd395403f064cc63f82bd Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\270\273\346\234\272\347\256\241\347\220\206.jpg" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\270\273\346\234\272\347\273\204.jpg" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\270\273\346\234\272\347\273\204.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..fb5472de6b3d30abf6af73e286f70ac8e1d58c15 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\270\273\346\234\272\347\273\204.jpg" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\270\273\346\234\272\350\257\246\346\203\205.jpg" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\270\273\346\234\272\350\257\246\346\203\205.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..effd8c29aba14c2e8f301f9f60d8f25ce8c533f0 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\270\273\346\234\272\350\257\246\346\203\205.jpg" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\277\256\346\224\271mysql\351\205\215\347\275\256\346\226\207\344\273\266.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\277\256\346\224\271mysql\351\205\215\347\275\256\346\226\207\344\273\266.png" new file mode 100644 index 0000000000000000000000000000000000000000..d83425ee0622be329782620318818662b292e88b Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\277\256\346\224\271mysql\351\205\215\347\275\256\346\226\207\344\273\266.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\277\256\346\224\271\346\217\222\344\273\266.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\277\256\346\224\271\346\217\222\344\273\266.png" new file mode 100644 index 0000000000000000000000000000000000000000..ba4a8d4d9aadb7f712bdcb4b193f05f956d38841 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\277\256\346\224\271\346\217\222\344\273\266.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\277\256\346\224\271\346\250\241\345\236\213.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\277\256\346\224\271\346\250\241\345\236\213.png" new file mode 100644 index 0000000000000000000000000000000000000000..23ff4e5fddb87ac157b1002a70c47d9b4c76b873 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\344\277\256\346\224\271\346\250\241\345\236\213.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\210\233\345\273\272\345\267\245\344\275\234\346\265\201.jpg" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\210\233\345\273\272\345\267\245\344\275\234\346\265\201.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..1a2b45e860914a1ac0cfb6908b02fb5cad4cbd60 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\210\233\345\273\272\345\267\245\344\275\234\346\265\201.jpg" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\221\212\350\255\246.jpg" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\221\212\350\255\246.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..89ac88e154275d4be8179d773e7093f2357f425f Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\221\212\350\255\246.jpg" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\221\212\350\255\246\347\241\256\350\256\244.jpg" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\221\212\350\255\246\347\241\256\350\256\244.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..57844f772853c541f7a1328b007a9b6ae4d5caf0 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\221\212\350\255\246\347\241\256\350\256\244.jpg" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\221\212\350\255\246\350\257\246\346\203\205.jpg" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\221\212\350\255\246\350\257\246\346\203\205.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..5b4830b47897a0d51be28238a879a70b1de9ca3b Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\221\212\350\255\246\350\257\246\346\203\205.jpg" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\267\245\344\275\234\345\217\260.jpg" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\267\245\344\275\234\345\217\260.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..998b81e3b88d888d0915dcff48dc8cc5df30d91c Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\267\245\344\275\234\345\217\260.jpg" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\267\245\344\275\234\346\265\201.jpg" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\267\245\344\275\234\346\265\201.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..17fb5b13034e1fc5276c68583fed1952415b0b5f Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\267\245\344\275\234\346\265\201.jpg" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\267\245\344\275\234\346\265\201\350\257\246\346\203\205.jpg" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\267\245\344\275\234\346\265\201\350\257\246\346\203\205.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..458e023847bb2ad1f198f5a2dd1691748038137e Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\267\245\344\275\234\346\265\201\350\257\246\346\203\205.jpg" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\272\224\347\224\250.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\272\224\347\224\250.png" new file mode 100644 index 0000000000000000000000000000000000000000..aa34bb909ee7c86a95126c13fa532ce93410a931 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\345\272\224\347\224\250.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\211\247\350\241\214\350\257\212\346\226\255.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\211\247\350\241\214\350\257\212\346\226\255.png" new file mode 100644 index 0000000000000000000000000000000000000000..afb5f7e9fbfb1d1ce46d096a61729766b4940cd3 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\211\247\350\241\214\350\257\212\346\226\255.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\212\245\345\221\212\345\206\205\345\256\271.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\212\245\345\221\212\345\206\205\345\256\271.png" new file mode 100644 index 0000000000000000000000000000000000000000..2029141179302ecef45d34cb0c9dc916b9142e7b Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\212\245\345\221\212\345\206\205\345\256\271.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\217\222\344\273\266\347\256\241\347\220\206.jpg" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\217\222\344\273\266\347\256\241\347\220\206.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..2258d03976902052aaf39d36b6374fa680b9f8aa Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\217\222\344\273\266\347\256\241\347\220\206.jpg" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\226\260\345\242\236\346\225\205\351\232\234\346\240\221.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\226\260\345\242\236\346\225\205\351\232\234\346\240\221.png" new file mode 100644 index 0000000000000000000000000000000000000000..664efd5150fcb96f009ce0eddc3d9ac91b9e622f Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\226\260\345\242\236\346\225\205\351\232\234\346\240\221.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\237\245\347\234\213\346\212\245\345\221\212\345\210\227\350\241\250.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\237\245\347\234\213\346\212\245\345\221\212\345\210\227\350\241\250.png" new file mode 100644 index 0000000000000000000000000000000000000000..58307ec6ef4c73b6b0f039b1052e5870629ac2e8 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\237\245\347\234\213\346\212\245\345\221\212\345\210\227\350\241\250.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\237\245\347\234\213\346\225\205\351\232\234\346\240\221.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\237\245\347\234\213\346\225\205\351\232\234\346\240\221.png" new file mode 100644 index 0000000000000000000000000000000000000000..a566417b18e8bcf19153730904893fc8d827d885 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\237\245\347\234\213\346\225\205\351\232\234\346\240\221.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\267\273\345\212\240\344\270\273\346\234\272\347\273\204.jpg" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\267\273\345\212\240\344\270\273\346\234\272\347\273\204.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..9fcd24d949e500323e7a466be7cbfaf48d257ad0 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\346\267\273\345\212\240\344\270\273\346\234\272\347\273\204.jpg" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\347\203\255\350\241\245\344\270\201\347\212\266\346\200\201\345\233\276.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\347\203\255\350\241\245\344\270\201\347\212\266\346\200\201\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..f5f8a3a95705145787e7aaf9c8d1fff404892240 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\347\203\255\350\241\245\344\270\201\347\212\266\346\200\201\345\233\276.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\350\257\212\346\226\255error1.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\350\257\212\346\226\255error1.png" new file mode 100644 index 0000000000000000000000000000000000000000..9e5b1139febe9f00156b37f3268269ac30a78737 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\350\257\212\346\226\255error1.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\350\257\212\346\226\255\344\270\273\347\225\214\351\235\242.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\350\257\212\346\226\255\344\270\273\347\225\214\351\235\242.png" new file mode 100644 index 0000000000000000000000000000000000000000..b536af938250004bac3053b234bf20bcbf075c9b Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\350\257\212\346\226\255\344\270\273\347\225\214\351\235\242.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\350\257\212\346\226\255\345\233\276\347\211\207.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\350\257\212\346\226\255\345\233\276\347\211\207.png" new file mode 100644 index 0000000000000000000000000000000000000000..6cef6216522407997d705d29131287f3a30b0f8f Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\350\257\212\346\226\255\345\233\276\347\211\207.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/figures/\351\205\215\347\275\256web.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\351\205\215\347\275\256web.png" new file mode 100644 index 0000000000000000000000000000000000000000..721335115922e03f255e67e6b775c1ac0cfbbc50 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/figures/\351\205\215\347\275\256web.png" differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/45515A7F-0EC2-45AA-9B58-AB92DE9B0979.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/45515A7F-0EC2-45AA-9B58-AB92DE9B0979.png new file mode 100644 index 0000000000000000000000000000000000000000..c810b26ad0c052960dfdf4bfd78e9224ce465318 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/45515A7F-0EC2-45AA-9B58-AB92DE9B0979.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/E574E637-0BF3-4F3B-BAE6-04ECBD09D151.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/E574E637-0BF3-4F3B-BAE6-04ECBD09D151.png new file mode 100644 index 0000000000000000000000000000000000000000..6ef6ef9bd126e6c2007389065bbecc1cfdd97f5b Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/E574E637-0BF3-4F3B-BAE6-04ECBD09D151.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/EF5E0132-6E5C-4DD1-8CB5-73035278E233.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/EF5E0132-6E5C-4DD1-8CB5-73035278E233.png new file mode 100644 index 0000000000000000000000000000000000000000..a2a29d2e1b62f7df409e87d03f2525ba8355f77e Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/EF5E0132-6E5C-4DD1-8CB5-73035278E233.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/hotpatch-fix-pr.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/hotpatch-fix-pr.png new file mode 100644 index 0000000000000000000000000000000000000000..209c73f7b4522819c52662a9038bdf19a88eacfd Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/hotpatch-fix-pr.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/hotpatch-pr-1.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/hotpatch-pr-1.png new file mode 100644 index 0000000000000000000000000000000000000000..1dc5269655c51b355d3cd89b71c6688fbb0d8d5d Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/hotpatch-pr-1.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/hotpatch-pr-success.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/hotpatch-pr-success.png new file mode 100644 index 0000000000000000000000000000000000000000..48ea807e03c0f8e6efbceacbbc583c6ac3b3c865 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/hotpatch-pr-success.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/hotpatch-pr.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/hotpatch-pr.png new file mode 100644 index 0000000000000000000000000000000000000000..159fd2b7bc76e002554722d1f0f12070a2bd2e19 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/hotpatch-pr.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/hotpatch-xml.PNG b/docs/en/25.03/Server/Maintenance/A-Ops/image/hotpatch-xml.PNG new file mode 100644 index 0000000000000000000000000000000000000000..f1916620d3cc7b1c29059bcc5513fdc7ee94127b Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/hotpatch-xml.PNG differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230525193235084.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230525193235084.png new file mode 100644 index 0000000000000000000000000000000000000000..9850a11a0dcfeed69099635f3147a2230fe6faa5 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230525193235084.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230525193254541.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230525193254541.png new file mode 100644 index 0000000000000000000000000000000000000000..73bfbaa15a2584611ac06839965eca2869b89991 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230525193254541.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527165206707.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527165206707.png new file mode 100644 index 0000000000000000000000000000000000000000..7d7f0992fc048777340678974d38b3c193269385 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527165206707.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527165700642.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527165700642.png new file mode 100644 index 0000000000000000000000000000000000000000..2c4500cb54ba0225704020160d72b4aaf265d3f7 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527165700642.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527165823568.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527165823568.png new file mode 100644 index 0000000000000000000000000000000000000000..7b26b545bc7d37f09eca7736f30d2eb3a6062890 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527165823568.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527165845170.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527165845170.png new file mode 100644 index 0000000000000000000000000000000000000000..9719210a961a18b639d56cbf88b8586370930b4c Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527165845170.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527165922876.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527165922876.png new file mode 100644 index 0000000000000000000000000000000000000000..56ff3380d12b9c1002881eca98e32a49cc292b9a Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527165922876.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527170343909.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527170343909.png new file mode 100644 index 0000000000000000000000000000000000000000..57c343360f278b2f67b77d37114a1f567a3ce63a Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230527170343909.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230607161425282.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230607161425282.png new file mode 100644 index 0000000000000000000000000000000000000000..d2fbca2a23e80edff661d05065987ede1cc7e8af Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230607161425282.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230607161545732.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230607161545732.png new file mode 100644 index 0000000000000000000000000000000000000000..ba6992bea8d2a1d7ca4769ebfdd850b98d1a372f Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230607161545732.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230607163358749.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230607163358749.png new file mode 100644 index 0000000000000000000000000000000000000000..191c36b65058ce8dea6bb2f1fe10a85b0177f2cf Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230607163358749.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230607172021782.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230607172021782.png new file mode 100644 index 0000000000000000000000000000000000000000..d25c3ebfb1aefe5d8f36b0b153afa64efd88dd63 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230607172021782.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230612113428096.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230612113428096.png new file mode 100644 index 0000000000000000000000000000000000000000..48b59b5e6cb4043703de96066c8d67e85eed4f16 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230612113428096.png differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230612113626330.png b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230612113626330.png new file mode 100644 index 0000000000000000000000000000000000000000..9d3621022deb02b267c3eb29315a7fe33c1f095e Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/image-20230612113626330.png differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/image/openEuler\344\273\223\350\257\204\350\256\272.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/image/openEuler\344\273\223\350\257\204\350\256\272.png" new file mode 100644 index 0000000000000000000000000000000000000000..29223cbddc39f8fcc0b725a3ed83495709e05f78 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/image/openEuler\344\273\223\350\257\204\350\256\272.png" differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/image/patch-file.PNG b/docs/en/25.03/Server/Maintenance/A-Ops/image/patch-file.PNG new file mode 100644 index 0000000000000000000000000000000000000000..f587a48c2be945beaadecf44a6d711da14be50c6 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/A-Ops/image/patch-file.PNG differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/image/src-openEuler\344\273\223\350\257\204\350\256\272.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/image/src-openEuler\344\273\223\350\257\204\350\256\272.png" new file mode 100644 index 0000000000000000000000000000000000000000..3f8fbd534e8f8a48fdd60a5c3f13b33531a4112a Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/image/src-openEuler\344\273\223\350\257\204\350\256\272.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/image/\344\273\273\345\212\241\347\273\223\346\236\234\346\237\245\347\234\213.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\344\273\273\345\212\241\347\273\223\346\236\234\346\237\245\347\234\213.png" new file mode 100644 index 0000000000000000000000000000000000000000..31fe24f44facaaa62fbeddd3eef0090a3be88908 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\344\273\273\345\212\241\347\273\223\346\236\234\346\237\245\347\234\213.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\210\233\345\273\272\350\204\232\346\234\254.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\210\233\345\273\272\350\204\232\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..feb95836d056335d9d7ef673acc5fdf39e29bd8e Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\210\233\345\273\272\350\204\232\346\234\254.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\210\233\345\273\272\350\204\232\346\234\254\344\273\273\345\212\241.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\210\233\345\273\272\350\204\232\346\234\254\344\273\273\345\212\241.png" new file mode 100644 index 0000000000000000000000000000000000000000..e7b1c5fc77c4027f1cdb96941440220db8637e5f Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\210\233\345\273\272\350\204\232\346\234\254\344\273\273\345\212\241.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\215\225\346\254\241\346\211\247\350\241\214.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\215\225\346\254\241\346\211\247\350\241\214.png" new file mode 100644 index 0000000000000000000000000000000000000000..8020c60843c11e566778a1a03c1fa7516de9dd6b Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\215\225\346\254\241\346\211\247\350\241\214.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\220\257\345\212\250\347\203\255\350\241\245\344\270\201\345\267\245\347\250\213\346\265\201\347\250\213.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\220\257\345\212\250\347\203\255\350\241\245\344\270\201\345\267\245\347\250\213\346\265\201\347\250\213.png" new file mode 100644 index 0000000000000000000000000000000000000000..1405eced0a14e3956191e111b7c1d588e5b3d27b Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\220\257\345\212\250\347\203\255\350\241\245\344\270\201\345\267\245\347\250\213\346\265\201\347\250\213.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\221\250\346\234\237\346\211\247\350\241\214.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\221\250\346\234\237\346\211\247\350\241\214.png" new file mode 100644 index 0000000000000000000000000000000000000000..b75743556384fe58690847b3794607ef9a890d6d Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\221\250\346\234\237\346\211\247\350\241\214.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\221\275\344\273\244\346\211\247\350\241\214.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\221\275\344\273\244\346\211\247\350\241\214.png" new file mode 100644 index 0000000000000000000000000000000000000000..b5c9fbbeb5a4bba5f81d753fa5aa620ad261804c Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\221\275\344\273\244\346\211\247\350\241\214.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\221\275\344\273\244\347\256\241\347\220\206\347\225\214\351\235\242.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\221\275\344\273\244\347\256\241\347\220\206\347\225\214\351\235\242.png" new file mode 100644 index 0000000000000000000000000000000000000000..c0357fc88d33c8b706203b70016d53629a3db70c Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\345\221\275\344\273\244\347\256\241\347\220\206\347\225\214\351\235\242.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/image/\346\223\215\344\275\234\347\256\241\347\220\206.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\346\223\215\344\275\234\347\256\241\347\220\206.png" new file mode 100644 index 0000000000000000000000000000000000000000..3a1b8c3accdfb688da2e8e54eb17e86d18ee4d0b Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\346\223\215\344\275\234\347\256\241\347\220\206.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/image/\346\226\207\344\273\266\346\216\250\351\200\201.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\346\226\207\344\273\266\346\216\250\351\200\201.png" new file mode 100644 index 0000000000000000000000000000000000000000..c449eb18608e0146275f1b9f4ca41d05d48af021 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\346\226\207\344\273\266\346\216\250\351\200\201.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/image/\346\226\260\345\273\272\345\221\275\344\273\244.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\346\226\260\345\273\272\345\221\275\344\273\244.png" new file mode 100644 index 0000000000000000000000000000000000000000..50d5bd4ce5499512acf2b8af86445fe6df6ce29f Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\346\226\260\345\273\272\345\221\275\344\273\244.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/image/\346\226\260\345\273\272\345\221\275\344\273\244\344\273\273\345\212\241.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\346\226\260\345\273\272\345\221\275\344\273\244\344\273\273\345\212\241.png" new file mode 100644 index 0000000000000000000000000000000000000000..792ec4e81017575fd27466a275c0502563808296 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\346\226\260\345\273\272\345\221\275\344\273\244\344\273\273\345\212\241.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/image/\347\203\255\350\241\245\344\270\201issue\351\223\276\346\216\245\345\222\214pr\351\223\276\346\216\245.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\347\203\255\350\241\245\344\270\201issue\351\223\276\346\216\245\345\222\214pr\351\223\276\346\216\245.png" new file mode 100644 index 0000000000000000000000000000000000000000..c9f6dc0a0f1a1758bb936b61ec939f8f5eeee633 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\347\203\255\350\241\245\344\270\201issue\351\223\276\346\216\245\345\222\214pr\351\223\276\346\216\245.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/image/\350\204\232\346\234\254\346\211\247\350\241\214.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\350\204\232\346\234\254\346\211\247\350\241\214.png" new file mode 100644 index 0000000000000000000000000000000000000000..4ab626ad5949e17a5d486431ae4c0481ca42a442 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\350\204\232\346\234\254\346\211\247\350\241\214.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/A-Ops/image/\350\204\232\346\234\254\347\256\241\347\220\206.png" "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\350\204\232\346\234\254\347\256\241\347\220\206.png" new file mode 100644 index 0000000000000000000000000000000000000000..62c60399dc58a79a9ab48a7eb584ce615c11b05c Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/A-Ops/image/\350\204\232\346\234\254\347\256\241\347\220\206.png" differ diff --git a/docs/en/25.03/Server/Maintenance/A-Ops/overview.md b/docs/en/25.03/Server/Maintenance/A-Ops/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..25c3aa9f994f68a7c56c22dd44d477005886761f --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/A-Ops/overview.md @@ -0,0 +1,3 @@ +# A-Ops用户指南 + +本文介绍A-Ops智能运维框架以及智能定位、配置溯源等服务的安装与使用方法,使用户能够快速了解并使用A-Ops。用户能够借由A-Ops降低系统集群的运维成本,实现系统故障快速定位、配置项统筹管理等功能。 diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/_menu.md b/docs/en/25.03/Server/Maintenance/CommonSkills/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..b12695007a445e42b9c0bfc8cf1f317bc68bcc2e --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/CommonSkills/_menu.md @@ -0,0 +1,10 @@ +--- +label: '常用技能' +ismanual: 'Y' +description: '运维常用配置及命令' +children: + - label: '信息收集' + href: './information-collection.md' + - label: '常用配置' + href: './common-skills.md' +--- diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/common-skills.md b/docs/en/25.03/Server/Maintenance/CommonSkills/common-skills.md new file mode 100644 index 0000000000000000000000000000000000000000..3164535db82aaa8c2b81df0015059d66849533ef --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/CommonSkills/common-skills.md @@ -0,0 +1,563 @@ +# 常用配置 + +- [常用配置](#常用配置) + - [配置网络](#配置网络) + - [管理RPM包](#管理rpm包) + - [配置SSH](#配置ssh) + +## 配置网络 + +1. 配置IP地址 + + 使用IP命令为接口配置地址,**interface-name**为网卡名称。 + + ```sh + ip addr [ add | del ] address dev interface-name + ``` + +2. 配置静态地址 + + ```shell + # 配置静态IP地址 + ip address add 192.168.0.10/24 dev enp3s0 + + # 查看配置结果,在root权限使用如下命令 + ip addr show dev enp3s0 + + # 结果如下 + 2: enp3s0: mtu 1500 qdisc fq_codel state UP group default qlen 1000 + link/ether 52:54:00:aa:ad:4a brd ff:ff:ff:ff:ff:ff + inet 192.168.202.248/16 brd 192.168.255.255 scope global dynamic noprefixroute enp3s0 + valid_lft 9547sec preferred_lft 9547sec + inet 192.168.0.10/24 scope global enp3s0 + valid_lft forever preferred_lft forever + inet6 fe80::32e8:cc22:9db2:f4d4/64 scope link noprefixroute + valid_lft forever preferred_lft forever + ``` + +3. 配置静态路由 + + 静态路由,可使用 `ip route add` 命令**在路由表中添加**,使用 `ip route del` 命令删除。常用的 `ip route` 命令格式如下: + + ```shell + ip route [ add | del | change | append | replace ] destination-address + ``` + + - **在主机地址中添加一个静态路由**,在 root 权限下,使用以下命令格式: + + ```shell + ip route add 192.168.2.1 via 10.0.0.1 [dev interface-name] + ``` + + - **在网络中添加一个静态路由**,在root权限下运行以下命令格式: + + ```shell + ip route add 192.168.2.0/24 via 10.0.0.1 [dev interface-name] + ``` + +4. 通过ifcfg文件配置网络 + + 通过在root权限下**修改ifcfg文件**实现,在/etc/sysconfig/network-scripts/目录中生成名为ifcfg-enp4s0的文件中,修改参数配置,示例如下: + + ```shell + TYPE=Ethernet + PROXY_METHOD=none + BROWSER_ONLY=no + BOOTPROTO=none + IPADDR=192.168.0.10 + PREFIX=24 + DEFROUTE=yes + IPV4_FAILURE_FATAL=no + IPV6INIT=yes + IPV6_AUTOCONF=yes + IPV6_DEFROUTE=yes + IPV6_FAILURE_FATAL=no + IPV6_ADDR_GEN_MODE=stable-privacy + NAME=enp4s0static + UUID=xx + DEVICE=enp4s0 + ONBOOT=yes + ``` + +## 管理RPM包 + +**RPM**的全名是**Red Hat Package Manager**,本意是Red Hat 软件包管理。在**openEuler、Fedora 、Redhat、Mandriva、SuSE、YellowDog**等主流发行版本,以及在这些版本基础上二次开发出来的发行版采用。 + + **RPM**以数据库记录的方式将需要的软件安装到Linux主机的一套管理程序,特点是将要安装的软件**先编译并打包**,通过包装好的软件中默认的数据库记录,记录这个软件在安装的时候需要的依赖属性模块,在用户的Linux主机安装时,**RPM**会先根据软件里的记录数据,查询Linux主机的依赖属性软件是否满足: + +- 若满足则予以安装。 +- 若不满足则不安装。 + +安装时将该软件的信息全部写入RPM的数据库中以便后续查询、验证与卸载。 + +![zh-cn_other_0000001337581224](./images/zh-cn_other_0000001337581224.jpeg) + +1. rpm包默认安装路径 + + 通常情况下,**RPM**采用系统默认的安装路径(默认安装路径可以通过命令查询,后续章节中将会详细介绍),所有安装文件都会按照类别分散到如下表格所示的目录中。 + + **表 1** RPM安装路径及其含义 + + |安装路径|含义| + |--|--| + |/etc/|配置文件安装目录。| + |/usr/bin/|可执行命令安装目录。| + |/usr/lib/|程序所使用的函数库保存位置。| + |/usr/share/doc|基本软件使用手册保存位置。| + |/usr/share/man/|帮助文件保存位置。| + + **注意:** RPM包支持手动指定安装路径,但此方式不推荐使用。通过手动指定安装路径后,所有的安装文件会集中安装到指定位置,且系统中用来查询安装路径的命令也无法使用(需手动配置才能被系统识别)。 + +2. rpm命令选项 + + **操作1. 软件包RPM签名检查** + + Linux机器安装RPM包之前,需要检查PGP签名,确保签名的完整性和来源无问题后,使用RPM命令中的以下选项来验证有效性。 + + ```sh + rpm --checksig nano-2.3.1-10.el7.x86_64.rpm + ``` + + **操作2. 安装RPM包** + + Linux系统中安装RPM包时,请在rpm命令中使用 **-i** 选项。 + + ```sh + rpm -ivh nano-2.3.1-10.el7.x86_64.rpm + ``` + + - **-i** : 安装软件包 + - **-v**: 详细信息 + - **-h**: 套件安装时列出标记 + + **操作3. 查询已安装的RPM包** + + 查询Linux系统中已经安装的RPM包(dnf),可以在rpm命令中使用 **-q** 选项。 + + ```sh + rpm -q dnf + ``` + + - **-q:** 查询操作 + + 如果系统未安装给定的包,会出现以下错误信息。 + + ```sh + # rpm -q dnf + package dnf is not installed + ``` + + **操作4. 查询所有已安装的RPM包** + + 查询Linux系统中安装的所有RPM包,请在rpm命令中使用 **-qa** 选项。 + + ```sh + # rpm -qa + dracut-config-rescue-055-7.oe2203sp2.x86_64 + parted-3.5-1.oe2203sp2.x86_64 + irqbalance-1.8.0-9.oe2203sp2.x86_64 + ...... + ``` + + **注意**:一般在使用 **-qa** 选项时,会配合管道符 “|” 一起使用,提升查找的准确率。 + + **操作5. 查看已安装的RPM包详细信息** + + 在rpm命令中使用 **-qi** 选项来验证系统中安装的RPM包的详细信息。 + + ```sh + # rpm -qi python3 + Name : python3 + Version : 3.9.9 + Release : 24.oe2203sp2 + Architecture: x86_64 + Install Date: Wed 30 Mar 2022 08:30:23 AM UTC + Group : Unspecified + Size : 35916839 + License : Python + Signature : RSA/SHA1, Wed 30 Mar 2022 03:29:30 AM UTC, Key ID d557065eb25e7f66 + Source RPM : python3-3.9.9-24.oe2203sp2.x86_64.rpm + Build Date : Tue 15 Mar 2022 12:00:00 AM UTC + Build Host : obs-worker1639015616-x86-0001 + Packager : http://openeuler.org + Vendor : http://openeuler.org + URL : https://www.python.org/ + Summary : Interpreter of the Python3 programming language + Description : + Python combines remarkable power with very clear syntax. It has modules, + classes, exceptions, very high level dynamic data types, and dynamic + typing. There are interfaces to many system calls and libraries, as well + as to various windowing systems. New built-in modules are easily written + in C or C++ (or other languages, depending on the chosen implementation). + Python is also usable as an extension language for applications written + in other languages that need easy-to-use scripting or automation interfaces. + + This package Provides python version 3. + ``` + + **操作6. 查看未安装的RPM包所有文件** + + 查看未安装的RPM包的文件列表,可以在rpm命令中使用 **-qlp** 选项。 + + ```sh + # rpm -qlp pkgship-2.2.0-10.oe2203sp2.noarch.rpm + /etc/ima/digest_lists.tlv/0-metadata_list-compact_tlv-pkgship-2.2.0-10.oe2203sp2.noarch + /etc/ima/digest_lists/0-metadata_list-compact-pkgship-2.2.0-10.oe2203sp2.noarch + /etc/pkgship/auto_install_pkgship_requires.sh + /etc/pkgship/conf.yaml + /etc/pkgship/package.ini + ...... + ``` + + **操作7. 查看未安装的RPM包依赖项** + + 查看未安装的RPM包编译的依赖包列表,可以在rpm命令中使用 **-qRp** 选项。 + + ```sh + # rpm -qRp pkgship-2.2.0-10.oe2203sp2.noarch.rpm + /bin/bash + /bin/sh + /usr/bin/python3 + config(pkgship) = 2.2.0-10.oe2203sp2 + python3 + python3-Flask-Limiter + ...... + ``` + + **操作8. 验证所有已安装的RPM包** + + 验证已安装的RPM包时,将包中安装的文件信息与**rpm数据库**中存储的包元数据中获取的文件的信息进行比较,可以通过在rpm命令中使用 **-Va** 选项。 + + ```sh + # rpm -Va + S.5....T. c /root/.bashrc + .......T. c /etc/yum.repos.d/openEuler.repo + S.5....T. c /etc/issue + S.5....T. c /etc/issue.net + S.5....T. c /etc/csh.login + S.5....T. c /etc/profile + .M....G.. g /var/log/lastlog + .M....... c /boot/grub2/grubenv + ...... + ``` + + rpm -Va命令相关输出字段及其含义: + + |字段|含义| + |--|--| + |S|文件长度发生变化。| + |M|文件的访问权限或文件类型发生变化。| + |5|MD5校验和发生变化。| + |D|设备节点的属性发生变化。| + |L|文件的符号链接发生变化。| + |U|文件/子目录/ 设备节点的owner发生变化。| + |G|文件/子目录/ 设备节点的group发生变化。| + |T|文件最后一次的修改时间发生变化。| + + **操作9. 查看特定文件的RPM包** + + 在Linux上找到一个提供特定二进制文件的RPM包,可以在rpm命令中使用 **-qf** 选项。 + + ```sh + # rpm -qf /usr/share/doc/pkgship + pkgship-2.2.0-10.oe2203sp2.noarch.rpm + ``` + + **操作10. 查看已安装RPM包中的文件** + + 查看特定RPM包的安装文件列表,可以在rpm命令中使用 **-ql** 选项。 + + ```sh + # rpm -ql dnf + /etc/bash_completion.d/dnf + /etc/ima/digest_lists.tlv/0-metadata_list-compact_tlv-dnf-4.14.0-14.oe2203sp2.noarch + /etc/ima/digest_lists/0-metadata_list-compact-dnf-dnf-4.14.0-14.oe2203sp2.noarch + /usr/bin/dnf + /usr/lib/systemd/system/dnf-makecache.service + /usr/lib/systemd/system/dnf-makecache.timer + /usr/share/doc/dnf + /usr/share/doc/dnf/AUTHORS + /usr/share/doc/dnf/README.rst + /usr/share/licenses/dnf + /usr/share/licenses/dnf/COPYING + /usr/share/licenses/dnf/PACKAGE-LICENSING + /var/cache/dnf + ``` + + **操作11. 查看最近安装的RPM包** + + Linux是一个多用户操作系统,在使用过程中,其他用户可能已经安装了部分软件包。如需在系统中找到最近安装的包,可以在rpm命令中使用 **-qa** **--last** 选项。 + + ```sh + # rpm -qa --last + ntp-4.2.8p15-11.oe2203sp2.x86_64 + ntpstat-0.6-4.oe2203sp2.noarch + ntp-help-4.2.8p15-11.oe2203sp2.noarch + ``` + + **操作12. 只查看已安装RPM包的文档** + + 可以从Linux Man页面获得任何命令的帮助(**/usr/share/doc/Package\_Name-Version\_Number/docs**\* 文档存放路径),查看安装的RPM包相关联的文档列表,请在rpm命令中使用 **-qdf** 选项,并输入**二进制文件路径**。 + + ```sh + # rpm -qdf /usr/bin/grep + /usr/share/doc/grep/NEWS + /usr/share/doc/grep/README + /usr/share/doc/grep/THANKS + /usr/share/doc/grep/TODO + /usr/share/info/grep.info.gz + /usr/share/man/man1/egrep.1.gz + /usr/share/man/man1/fgrep.1.gz + /usr/share/man/man1/grep.1.gz + ``` + + **操作13. 升级已安装的RPM包** + + 通过使用 **-Uvh** 选项和rpm命令,可以轻松地将已经安装的rpm包升级到最新版本。 + + ```sh + # rpm -Uvh pkgship-2.2.0-10.oe2203sp2.noarch.rpm + Preparing... ################################# [100%] + ``` + + **注意**:升级安装的RPM包时,会删除旧RPM包,安装新RPM包。 + + **操作14. 移除已安装的RPM包** + + 删除安装在系统上的rpm包,请在rpm命令中使用 **-ev** 或 **-e** 选项。 + + ```shell + rpm -ev pkgship + ``` + + **操作15. 重建损坏的RPM数据库** + + 在尝试使用**yum update**命令更新系统时,可能会收到一条错误消息(**RPM数据库已损坏**),如果收到该信息,请在RPM命令中使用 **--rebuilddb** 选项。 + + ```shell + rm /var/lib/rpm/__db* + rpm --rebuilddb + ``` + + **操作16. 检查特定包的漏洞是否已修复** + + 可以通过在rpm命令中使用 **--changelog** 选项并输入相应的**CVE**来实现。 + + ```shell + rpm -q --changelog python-2.6.6 | grep -i "CVE-2019-9636" + ``` + + **操作17. 导入RPM GPG密钥** + + 默认情况下,当向Linux系统添加新的存储库时,GPG密钥将自动导入。同时,也可在RPM命令中添加**--import** 手动导入RPM GPG密钥,用于从存储库下载时检查包的完整性。 + + ```shell + rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-OpenEuler-22.03-LTS-SP2 + ``` + +3. dnf命令 + + dnf命令及其相关概述 + + |命令|概述| + |--|--| + |repolist|显示已配置的软件repo源。| + |install|Linux上安装单个或多个软件包。| + |upgrade|升级Linux上的一个或多个软件包。| + |list|列出一个或一组软件包。| + |info|显示关于软件包或软件包组的详细信息。| + |updateinfo|显示关于包的公告信息。| + |search|在软件包详细信息中搜索指定字符串。| + |check-update|检查是否有软件包升级。| + |remove|从系统中移除一个或多个软件包。| + |reinstall|重装一个包。| + |downgrade|降级软件包。| + |autoremove|删除所有原先因为依赖关系安装的不需要的软件包。| + |distro-sync|同步已经安装的软件包到最新可用版本。| + |makecache|创建元数据缓存。| + |repository-package|对指定仓库中的所有软件包运行命令。| + |provides|查找提供指定内容的软件包。| + |group|显示或使用组信息。| + |history|显示或使用事务历史。| + |clean|删除已缓存的数据。| + + **操作1. 已配置的软件repo** + + 显示已配置的软件仓库,默认添加 **--enabled** 选项(显示启用的仓库)。 + + ```sh + # dnf repolist --enabled + repo id repo name + EPOL EPOL + OS OS + debuginfo debuginfo + everything everything + pkgship_elasticsearch Elasticsearch repositor + source source + update update + ``` + + - **--all**: 显示所有的软件仓库 + - **--disabled**: 显示被禁用的软件仓库 + - **--enabled**: 显示已经启用的仓库(默认) + + **操作2. 安装单个或多个软件包** + + 通过**install** 命令可以安装RPM包。 + + ```sh + # dnf install 软件包 + ``` + + 安装软件包的过程中可能会存在**冲突**的包或**无法安装**的包,可以在命令中增加 **--allowerasing** 来替换冲突的软件包或 **--skip-broken** 来跳过无法安装的软件包。 + + ```sh + # dnf install 软件包 [软件包 ...] --allowerasing --skip-broken + ``` + + 当使用dnf安装软件包时,通过添加 **--installroot** 设置软件包安装的根目录。 + + ```sh + # dnf install 软件包 --installroot 软件包安装的根目录 + ``` + + 需要临时指定特定的repo源安装时,可以添加 **--setopt=reposdir=** 选项来指定repo源的加载目录。 + + ```sh + # dnf install 软件包 --setopt=reposdir=repo源的加载目录 + ``` + + 在安装选项时,不需要交互式确认时,可以通过添加 **-y** 或**--assumeyes** 使需要安装的软件包全部自动应答为**是**。 + + ```sh + # dnf install 软件包 -y + ``` + + 指定特定的repo源安装rpm包时,可以通过指定 **--repo** 或 **--enablerepo** 选项。为了达到相同的效果,也可以通过使用 **--disablerepo** 选项来禁用匹配的repo源,此处推荐您使用--repo选项来安装RPM包。 + + ```sh + # dnf install 软件包 --repo=repo源 + ``` + + **操作3. 重新安装软件包** + + 系统上的软件包需要执行重新安装操作时,可以执行 **reinstall** 命令。 + + ```sh + # dnf reinstall 软件包 + ``` + + **操作4. 升级一个或多个软件包** + + - 通过**upgrade**或 **update**升级Linux上的一个或多个软件包。 + + ```sh + # dnf upgrade 软件包 [软件包 ...] + # dnf update 软件包 [软件包 ...] + ``` + + **操作5. 软件包降级** + + 当软件包版本过高发生兼容性问题时,可以采用降级的方式解决。 + + ```sh + # dnf downgrade 软件包 + ``` + + **操作6. 列出一个或一组软件包** + + 罗列系统中已安装的软件包和配置的repo仓中存在的软件包列表,可以使用 `list` 命令。 + + ```sh + # dnf list + ``` + + 可以通过添加选项过滤显示的包列表 + + - **--all**: 显示所有的软件包(默认) + - **--available**: 只显示可用的软件包 + - **--installed**: 只显示已安装的软件包 + - **--extras**: 只显示额外的软件包 + - **--updates**: 只显示需要被升级的软件包 + - **--upgrades**: 只显示需要被升级的软件包 + - **--autoremove**: 只显示需要被删除的软件包 + - **--recent**: 限制最近被改变的软件包 + + **操作7. 查看软件包详细信息** + + 查看软件包的详细信息时,可以使用`info` 命令。 + + ```sh + # dnf info 软件包 + ``` + + **操作8. 搜索软件包** + + 如需在系统中安装软件包,但不确定软件包全称时,可使用`search`命令查找匹配的包。 + + ```sh + # dnf search 软件包 + ``` + + **操作9. 卸载一个或多个软件包** + + 删除已过期或重复的软件包时,可使用`remove`命令移除一个软件包。 + + ```sh + # dnf remove 软件包 + ``` + + - **--duplicates**: 删除已安装(重复)的软件包 + - **--oldinstallonly**: 移除过期的“仅安装”软件包 + + **操作10. 自动删除因为依赖关系安装的软件包** + + 删除因为依赖关系安装的不需要的软件包时,可使用`autoremove`命令。 + + ```sh + # dnf autoremove 软件包 + ``` + +## 配置SSH + +1. SSH服务介绍 + + **SSH(Secure Shell)**是目前较可靠,专为远程登录会话和其他网络服务**提供安全性保障**的协议。利用SSH协议可以有效防止远程管理过程中的信息泄露问题。透过SSH可以对所有传输的数据进行加密,并防止DNS欺骗和IP欺骗。OpenSSH是SSH协议的免费开源实现。 + +2. 配置SSH服务 + + ```shell + # 打开并修改/etc/ssh/sshd_config文件 + vi /etc/ssh/sshd_config + + # 重新启动SSH服务 + systemctl restart sshd + + # 检查SSH服务状态 + systemctl status sshd + ``` + +3. SSH服务配置文件主要选项 + + ```shell + # 指定SSH协议版本(Specify SSH Protocol Version) + Protocol 2 + + # 允许的用户(Allowed Users) + AllowUsers xxx + + # 被拒绝的用户(Denied Users) + DenyUser root + + # 配置会话超时(Configure Session Timeout) + ClientAliveInterval 120 + + # 禁用SSH根登录(Disable SSH Root Login) + PermitRootLogin no + + # 配置或更改SSH端口号(Configure or Change SSH Port Number) + Port 1234 + + # 禁用SSH密码身份验证 (Disable SSH Password Authentication) + PasswordAuthentication no + ``` diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001335816300.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001335816300.png new file mode 100644 index 0000000000000000000000000000000000000000..619f0c33503cd27d92f227216c722d554b9132f2 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001335816300.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001336729664.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001336729664.png new file mode 100644 index 0000000000000000000000000000000000000000..4d73507cceab2e0b123d6864d9f86c86eb1eee2f Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001336729664.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337000118.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337000118.png new file mode 100644 index 0000000000000000000000000000000000000000..37131647778506f24be4ff401392a9cc209a36eb Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337000118.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337051916.jpg b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337051916.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a2083b7783041884394f796222352d8772ada6cc Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337051916.jpg differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337053248.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337053248.png new file mode 100644 index 0000000000000000000000000000000000000000..8859f37749a4f8a4394e24ddfb54fc473e8c10c2 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337053248.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337172594.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337172594.png new file mode 100644 index 0000000000000000000000000000000000000000..4e806f83c57880543a777807778f14eeb0105aba Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337172594.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337212144.jpg b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337212144.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c6f0874250475f598efa7375516109b540918fb8 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337212144.jpg differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337260780.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337260780.png new file mode 100644 index 0000000000000000000000000000000000000000..09d521d933f5fa0caacc592ea92acee959786051 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337260780.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337268560.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337268560.png new file mode 100644 index 0000000000000000000000000000000000000000..663f67428487d88e23aa9c3291c31399fec2f2c3 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337268560.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337268820.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337268820.png new file mode 100644 index 0000000000000000000000000000000000000000..cd1732ee870a6dde0acc54642f34793933ce3356 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337268820.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337419960.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337419960.png new file mode 100644 index 0000000000000000000000000000000000000000..c3b493bf1e57f130e122b59e99ff45cd44539dad Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337419960.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337420372.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337420372.png new file mode 100644 index 0000000000000000000000000000000000000000..2300bcd7426748236fd48b85688bd3d1fa3315df Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337420372.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337422904.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337422904.png new file mode 100644 index 0000000000000000000000000000000000000000..01e250c6f7cbb64abe0b136cd80fda7ae68b629d Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337422904.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337424024.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337424024.png new file mode 100644 index 0000000000000000000000000000000000000000..6532d98885f756c6704bc4bacc0f9133d78405a7 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337424024.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337424304.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337424304.png new file mode 100644 index 0000000000000000000000000000000000000000..9ecb384ed58458c24d8e3ae729c4de197b982b86 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337424304.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337427216.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337427216.png new file mode 100644 index 0000000000000000000000000000000000000000..8633dbdd658f98501dfc91a704395260f2d4df3c Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337427216.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337427392.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337427392.png new file mode 100644 index 0000000000000000000000000000000000000000..74f5cb24520c94de8628b2e64e6916c563f9f5a2 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337427392.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337533690.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337533690.png new file mode 100644 index 0000000000000000000000000000000000000000..1f02d9b155754a113347a54a7d35ba9b060175a8 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337533690.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337536842.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337536842.png new file mode 100644 index 0000000000000000000000000000000000000000..5a9ee2c989638c9a6aad3fcfb35bb9b9f2d4683c Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337536842.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337579708.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337579708.png new file mode 100644 index 0000000000000000000000000000000000000000..5cd8ed939434e6447dd55679eeaa3756d861751f Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337579708.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337580216.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337580216.png new file mode 100644 index 0000000000000000000000000000000000000000..5516b8d261b769287c74cf860a6708fcde6bbb8a Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337580216.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337584296.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337584296.png new file mode 100644 index 0000000000000000000000000000000000000000..fa76ecb59018fb154ffe1d9f6da1484d652f3ac1 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337584296.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337696078.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337696078.png new file mode 100644 index 0000000000000000000000000000000000000000..3864852e345eaf01794042feaa85b012b8af71de Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337696078.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337740252.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337740252.png new file mode 100644 index 0000000000000000000000000000000000000000..fd83fb600a54ab8bc39ee2ae54210be8b6c48973 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337740252.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337740540.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337740540.png new file mode 100644 index 0000000000000000000000000000000000000000..b8e25128a47dccaed733fc192f52f2ca7828e516 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337740540.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337747132.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337747132.png new file mode 100644 index 0000000000000000000000000000000000000000..41ea7d47f5fe5fca46816d93cb08b5da00abc0ad Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337747132.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337748300.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337748300.png new file mode 100644 index 0000000000000000000000000000000000000000..32488dc1740408834954cf8d57a2843d98f09c2e Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337748300.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337748528.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337748528.png new file mode 100644 index 0000000000000000000000000000000000000000..f2d62c85c844c2756f4d27a48711560dfb9615ea Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001337748528.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001386699925.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001386699925.png new file mode 100644 index 0000000000000000000000000000000000000000..cf5b13b35e65ed0143a01a5bcad1e11eaddaded7 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001386699925.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387293085.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387293085.png new file mode 100644 index 0000000000000000000000000000000000000000..7f56b020949c53d018eba016952c2409f0d7dca9 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387293085.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387413509.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387413509.png new file mode 100644 index 0000000000000000000000000000000000000000..2245427058fc31f3e5d7f40062c0551936a67199 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387413509.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387413793.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387413793.png new file mode 100644 index 0000000000000000000000000000000000000000..aa649bf7215662819766d897513fb711d9d1e7f8 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387413793.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387415629.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387415629.png new file mode 100644 index 0000000000000000000000000000000000000000..01189358354090591de6580f8ef88ef78ddba3a1 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387415629.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387691985.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387691985.png new file mode 100644 index 0000000000000000000000000000000000000000..31c3096fa837c1b397ab2fe27acdd87e2cec36de Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387691985.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387692269.jpg b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387692269.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b79e3ddf78520277046b933c4662c6b72f45ab85 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387692269.jpg differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387692893.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387692893.png new file mode 100644 index 0000000000000000000000000000000000000000..49ea515d834b58d4ded14c55a6a2b07034d76137 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387692893.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387755969.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387755969.png new file mode 100644 index 0000000000000000000000000000000000000000..b2daa95d6b757e7bd443d8fd961922f248dd6853 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387755969.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387780357.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387780357.png new file mode 100644 index 0000000000000000000000000000000000000000..1aab3b8be2cd0c906253d70036a9fee3050a1055 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387780357.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387784693.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387784693.png new file mode 100644 index 0000000000000000000000000000000000000000..62a40117a892ba6c163be81bce1d198c2920f0e9 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387784693.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387787605.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387787605.png new file mode 100644 index 0000000000000000000000000000000000000000..8c1893e16fb929f77bb6b9a70cb25d3479dd684c Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387787605.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387855149.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387855149.png new file mode 100644 index 0000000000000000000000000000000000000000..731e957c367cb05e4229f53cf97dcee2cde69dff Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387855149.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387857005.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387857005.png new file mode 100644 index 0000000000000000000000000000000000000000..872f5c9eb05169831df4ba49d017629e8a943c64 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387857005.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387902849.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387902849.png new file mode 100644 index 0000000000000000000000000000000000000000..ffe2043c199308ed2033e3eb02a0662a65141ece Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387902849.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387907229.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387907229.png new file mode 100644 index 0000000000000000000000000000000000000000..084fbea1aee4d09b1e623c66b4f07641c7a0208d Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387907229.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387908045.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387908045.png new file mode 100644 index 0000000000000000000000000000000000000000..1fca645598e7a67da6e75b98c44f3c9a740be374 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387908045.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387908453.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387908453.png new file mode 100644 index 0000000000000000000000000000000000000000..b97804a0a575fd18235e7a0c7e4f2d0183e3b460 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387908453.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387961737.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387961737.png new file mode 100644 index 0000000000000000000000000000000000000000..ae4ddce8cf2629b811e9711c61186b3efa4dfe3c Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001387961737.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388020197.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388020197.png new file mode 100644 index 0000000000000000000000000000000000000000..1816e1e068ee0294677ebb357ffd158a14bb86cf Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388020197.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388024321.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388024321.png new file mode 100644 index 0000000000000000000000000000000000000000..da3ba54203ded0093b7c2b5308de0e2afd85a146 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388024321.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388024397.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388024397.png new file mode 100644 index 0000000000000000000000000000000000000000..4e4531dd19dc703399c9d4dd0e95236fa9a064c8 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388024397.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388028161.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388028161.png new file mode 100644 index 0000000000000000000000000000000000000000..b3beb92520c34ba771d096a8a146fb2c5b5edbb7 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388028161.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388028537.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388028537.png new file mode 100644 index 0000000000000000000000000000000000000000..ffb244306787c397ef4a9f4d9c3eb504172d3777 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388028537.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388184025.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388184025.png new file mode 100644 index 0000000000000000000000000000000000000000..cbce6fe1e32c547426319923c0fdb13e95554b99 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388184025.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388187249.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388187249.png new file mode 100644 index 0000000000000000000000000000000000000000..0ac83f21e269d909e550b68cb0bdc6347c05dcac Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388187249.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388187325.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388187325.png new file mode 100644 index 0000000000000000000000000000000000000000..02dbdf218da2cb1c844dfc13a463875df5124d48 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388187325.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388188365.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388188365.png new file mode 100644 index 0000000000000000000000000000000000000000..dbe3bfb48446bab88e3e622b9f8066383f269590 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388188365.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388241577.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388241577.png new file mode 100644 index 0000000000000000000000000000000000000000..8dacb6e343ea4c750904fa090bb99213e012379d Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388241577.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388972645.png b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388972645.png new file mode 100644 index 0000000000000000000000000000000000000000..e32606925f4bb4380b262d9f946d4cd106202b87 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_image_0000001388972645.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_other_0000001337581224.jpeg b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_other_0000001337581224.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..2c019b828bdf9c699f203f09ba3542968ff21262 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonSkills/images/zh-cn_other_0000001337581224.jpeg differ diff --git a/docs/en/25.03/Server/Maintenance/CommonSkills/information-collection.md b/docs/en/25.03/Server/Maintenance/CommonSkills/information-collection.md new file mode 100644 index 0000000000000000000000000000000000000000..9a301de64fb64089f1e30e92baa72d266276a5a5 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/CommonSkills/information-collection.md @@ -0,0 +1,157 @@ +# 信息收集 + +## 查看OS信息 + +1. 查看操作系统版本信息 + + ```shell + # cat /etc/openEuler-latest + # cat /etc/os-release + # cat /etc/openEuler-release + ``` + +2. 查看内核版本信息 + + ```shell + # uname -a + ``` + +## 查看硬件信息 + +1. 查看cpu的统计信息 + + ```shell + # lscpu + ``` + +2. 查看CPU相关参数 + + ```shell + # cat /proc/cpuinfo + ``` + +3. 查看系统内存信息 + + ```shell + # cat /proc/meminfo + ``` + +4. 查看内存信息 + + ```shell + # dmidecode -t memory + ``` + +5. 查看硬盘和分区分布 + + ```shell + # lsblk + ``` + +6. 看硬盘和分区的详细信息 + + ```shell + # fdisk -l + ``` + +7. 查看网卡硬件信息 + + ```shell + # lspci | grep -i 'eth' + ``` + +8. 查看所有网络接口 + + ```shell + # ip a + # yum install -y net-tools + # ifconfig + ``` + +9. 查看某个网络接口的详细信息 + + ```shell + # ethtool enp7s0 (以enp7s0为例) + ``` + +10. 查看pci信息 + + ```shell + # lspci + ``` + +11. 查看设备树 + + ```shell + # lspci -t + ``` + +12. 查看bios信息 + + ```shell + # dmidecode -t bios + ``` + +## 查看软件信息 + +1. 查看软件包的详细信息 + + ```shell + # rpm -qi systemd(以systemd为例) + ``` + +2. 查看软件包提供的模块 + + ```shell + # rpm -q --provides systemd (以systemd为例) + ``` + +3. 查看所有已安装软件包 + + ```shell + # rpm -qa | grep systemd (以systemd为例) + ``` + +4. 查看软件包文件列表 + + ```shell + # rpm -ql python3-rpm (以python3-rpm为例) + ``` + +## 查看OS日志 + +1. 查看系统启动后的信息和错误日志 + + ```shell + # cat /var/log/messages + ``` + +2. 查看安全相关的日志信息 + + ```shell + # cat /var/log/secure + ``` + +3. 查看邮件相关的日志信息 + + ```shell + # cat /var/log/maillog + ``` + +4. 查看定时任务相关的日志信息 + + ```shell + # cat /var/log/cron + ``` + +5. 查看UUCP和news设备相关的日志信息 + + ```shell + # cat /var/log/spooler + ``` + +6. 查看守护进程启动和停止相关的日志消息 + + ```shell + # cat /var/log/boot.log + ``` diff --git a/docs/en/25.03/Server/Maintenance/CommonTools/_menu.md b/docs/en/25.03/Server/Maintenance/CommonTools/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..6b09ff0752e558bdd9ad7cc94743198419c6bd34 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/CommonTools/_menu.md @@ -0,0 +1,8 @@ +--- +label: '常用定位定界工具' +ismanual: 'Y' +description: '常用定位定界工具,包括 ftrace,strace 和 kdump' +children: + - label: '常用定位定界工具' + href: './commonly-used-tools.md' +--- diff --git a/docs/en/25.03/Server/Maintenance/CommonTools/commonly-used-tools.md b/docs/en/25.03/Server/Maintenance/CommonTools/commonly-used-tools.md new file mode 100644 index 0000000000000000000000000000000000000000..5bb98772935838f56f2aa295f8c479bca5c1af8f --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/CommonTools/commonly-used-tools.md @@ -0,0 +1,201 @@ +# 常用工具 + +- [常用工具](#常用工具) + - [ftrace](#ftrace) + - [strace](#strace) + - [kdump](#kdump) + +## ftrace + +1. ftrace:是一个针对linux kernel内核空间的debug工具,内核中会提供trace events供用户追踪。而ftrace则可以将events抓取出来,让用户能够直观地看到这些事件,同时也可以追踪内核的函数。 +2. ftrace的配置和使用:要使用ftrace,需要**将其相关的依赖编译进内核**,openEuler已经默认编译了ftrace选项,如果没开启可以在menuconfig里选择Kernel hacking -\> Tracers -\> Trace syscalls开启,同时还要**编译debugfs**,选择Kernel hacking -\> Generic Kernel Debugging Instruments -\> Debug Filesystem。 + +- **ftrace的功能配置** + +ftrace通过debugfs向用户空间提供访问接口,内核配置debugfs后,会创建/sys/kernel/debug目录,debugfs文件系统就是挂载到该目录。如果内核支持ftrace相关的配置项后,会在debugfs下创建一个tracing目录,debugfs文件系统会挂载到该目录,该目录内容如下图所示: + +![](./images/zh-cn_image_0000001322372918.png) + +- **ftrace debugfs接口介绍** + +用户可看到ftrace通过debugfs文件系统提供的一些控制和输出文件,如下对常用的文件做简单说明: + + available_tracers:可用的跟踪程序 + + current_tracer:正在运行的跟踪程序 + + available_events:列举了系统所有可用的trace events + + events:该目录对events按模块做了区分。 + + set_event:列举当前要追踪的events + + tracing_on:用于控制跟踪打开或停止,echo 0 \> tracing\_on表示关闭,1表示打开 + + trace:查看跟踪数据 + +- **可用的跟踪程序** + +![zh-cn_image_0000001373373585](./images/zh-cn_image_0000001373373585.png) + + function:一个无需参数的函数调用跟踪程序 + + function_graph:一个使用子调用的函数调用跟踪程序 + +- **追踪event** + +```shell +# 先注明要追踪ras的arm_event +echo ras:arm_event > /sys/kernel/debug/tracing/set_event + +# 这个文件可以看到event的具体格式,会打印什么字段 +cat /sys/kernel/debug/tracing/events/ras/arm_event/format + +# 启动追踪 +echo 1 > /sys/kernel/debug/tracing/tracing_on + +# 观察trace的输出 +tail -f /sys/kernel/debug/tracing/trace +``` + +![c50cb9df64f4659787c810167c89feb4_1884x257](./images/c50cb9df64f4659787c810167c89feb4_1884x257.png) + +- **追踪内核函数入参** + +选择跟踪mmap,其对应系统调用do\_mmap,选择输出addr入参。 + +![zh-cn_image_0000001373379529](./images/zh-cn_image_0000001373379529.png) + +```shell +# 通过kprobe跟踪 +echo 'p:probe1 do_mmap addr=%x1' > kprobe_events + +# 启用kprobe +echo 1 > events/kprobes/probe1/enable + +# 启动追踪 +echo 1 > tracing_on + +# 查看trace数据 +``` + +![zh-cn_image_0000001322379488](./images/zh-cn_image_0000001322379488.png) + +- **追踪函数调用** + +```shell +# 选择追踪类型 +echo function_graph > current_tracer + +# 设置过滤进程pid +echo set_ftrace_pid + +# 开始追踪 +echo 1 > tracing_on + +# 查看trace数据 +``` + +![zh-cn_image_0000001322219840](./images/zh-cn_image_0000001322219840.png) + +## strace + +strace命令是一个诊断、调试工具,可以通过使用strace对应用的系统调用及信号传递来进行分析,从而达到解决问题或了解应用执行过程的目的。 + +可以通过`strace -h`来查看strace提供了哪些功能。 + +![zh-cn_image_0000001322112990](./images/zh-cn_image_0000001322112990.png) + +最常用的使用方式(追踪xx命令,跟踪forks,打印时间,结果输出到output文件中)。 + +```shell +strace -f -tt -o output xx +``` + +## kdump + +1. crash/kdump原理介绍 + + kdump是系统运行在某个时间点的内存状态的快照,便于运维人员debug分析系统挂掉的原因,常用于系统宕机和panic。 + + 大致流程如下: + + ![zh-cn_image_0000001321685172](./images/zh-cn_image_0000001321685172.png) + +2. 相关工具安装配置 + + ```shell + # 使用yum安装相应软件包 + yum install kernel-debuginfo-$(uname -r) kexec-tools crash -y + + # 设置crashkernel预留内存大小 + vim /etc/default/grub + ``` + + ![zh-cn_image_0000001372821865](./images/zh-cn_image_0000001372821865.png) + + ```shell + # 重新生成grub配置文件 + grub2-mkconfig -o /boot/efi/EFI/openEuler/grub.cfg + reboot + + # 启动kdump服务 + systemctl start kdump #启动kdump + systemctl enable kdump #设置开机启动 + ``` + +3. crash触发 + + 步骤1. 内核具备默认配置,当硬锁和oops的时候会触发panic。 + + ![zh-cn_image_0000001372824637](./images/zh-cn_image_0000001372824637.png) + + 步骤2. 用户可以修改该配置,以下相关命令可使配置生效一次,重启后失效。 + + ```shell + # 设置软锁触发panic + echo 1 > /proc/sys/kernel/softlockup_panic + + # 设置kernel遇到OOM触发panic + echo 1 > /proc/sys/vm/panic_on_oom + + # 进程出现hang时引发panic + echo 1 > /proc/sys/kernel/hung_task_panic + + # 进程hangtask机制超时时间设置 + echo 60 > /proc/sys/kernel/kernel.hung_task_timeout_secs + ``` + + 步骤3. 如需要重启自动重启配置,将下列参数写入/etc/sysctl.conf文件,执行sysctl -p生效。 + + ```shell + kernel.hung_task_panic=1 + kernel.hung_task_timeout_secs=60 + kernel.softlockup_panic=1 + vm.panic_on_oom=1 + ``` + +4. crash分析 + + 步骤1. 开启crash调试。 + + 步骤2. 生成的vmcore文件一般会在“/var/crash/IP地址-时间”目录下。 + + 步骤3. 执行如下命令即可进入crash调试。 + + ```shell + crash {vmcore文件} {调试内核vmlinux} + ``` + + ![zh-cn_image_0000001372748125](./images/zh-cn_image_0000001372748125.png) + + crash调试命令格式为 command args,command为需要执行的命令,args为部分调试命令需要的参数。 + + |命令|用途| + |--|--| + |help|打印命令的help信息,可展示支持命令,也可查看具体命令的help信息,如 help bt。| + |bt|打印函数调用栈信息。| + |log|打印系统消息缓冲区,可追加参数,如log。 | + |ps|显示进程的状态,>表示进程为活跃状态。| + |dis|对给定函数或者地址进行反汇编,如dis -l [func]。 | + |mount|展示当前的文件系统信息| diff --git a/docs/en/25.03/Server/Maintenance/CommonTools/images/c50cb9df64f4659787c810167c89feb4_1884x257.png b/docs/en/25.03/Server/Maintenance/CommonTools/images/c50cb9df64f4659787c810167c89feb4_1884x257.png new file mode 100644 index 0000000000000000000000000000000000000000..01081f25627731c56764c196e3fae32d55bc7023 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonTools/images/c50cb9df64f4659787c810167c89feb4_1884x257.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001321685172.png b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001321685172.png new file mode 100644 index 0000000000000000000000000000000000000000..a98265bdf251608c0ff394fefe545cd3192bdb28 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001321685172.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001322112990.png b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001322112990.png new file mode 100644 index 0000000000000000000000000000000000000000..6f4b32bf2b36595abe10f2550cda5714bc355553 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001322112990.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001322219840.png b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001322219840.png new file mode 100644 index 0000000000000000000000000000000000000000..48b28664df46ddf9aa38c7570bb9e9edb8080ac9 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001322219840.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001322372918.png b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001322372918.png new file mode 100644 index 0000000000000000000000000000000000000000..5424367c9bc564e713220ba87f963096881833b8 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001322372918.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001322379488.png b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001322379488.png new file mode 100644 index 0000000000000000000000000000000000000000..8b18cdca066be43b74443498edc5500ea9e1e608 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001322379488.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001372748125.png b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001372748125.png new file mode 100644 index 0000000000000000000000000000000000000000..5f6326b9415cf766dd8379dbadd5aa1a0dc6861f Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001372748125.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001372821865.png b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001372821865.png new file mode 100644 index 0000000000000000000000000000000000000000..21e8dad1cd90755440cf858523b12c036a91e1ad Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001372821865.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001372824637.png b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001372824637.png new file mode 100644 index 0000000000000000000000000000000000000000..aefb5d83c079e6718ef88fd934b4b496cdc29565 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001372824637.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001373373585.png b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001373373585.png new file mode 100644 index 0000000000000000000000000000000000000000..c4e5e47c9beca2c7c7630d78916f80eda652b52a Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001373373585.png differ diff --git a/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001373379529.png b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001373379529.png new file mode 100644 index 0000000000000000000000000000000000000000..daa40b49e679668905632f25ff42bf8599ba0ead Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/CommonTools/images/zh-cn_image_0000001373379529.png differ diff --git a/docs/en/25.03/Server/Maintenance/Gala/_menu.md b/docs/en/25.03/Server/Maintenance/Gala/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..0b67e027f5b16503945373c2b481db2d0363b4c4 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/Gala/_menu.md @@ -0,0 +1,12 @@ +--- +label: 'gala用户指南' +ismanual: 'Y' +description: '故障智能检测、性能数据采集分析以及资源监测管理' +children: + - label: '使用gala-anteater' + href: './using-gala-anteater.md' + - label: '使用gala-gopher' + href: './using-gala-gopher.md' + - label: '使用gala-spider' + href: './using-gala-spider.md' +--- diff --git "a/docs/en/25.03/Server/Maintenance/Gala/figures/attach\346\265\201\347\250\213.png" "b/docs/en/25.03/Server/Maintenance/Gala/figures/attach\346\265\201\347\250\213.png" new file mode 100644 index 0000000000000000000000000000000000000000..73b548cc332212f3ae2eec4dcec34c8af6e0e55a Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/Gala/figures/attach\346\265\201\347\250\213.png" differ diff --git a/docs/en/25.03/Server/Maintenance/Gala/figures/deadlock.png b/docs/en/25.03/Server/Maintenance/Gala/figures/deadlock.png new file mode 100644 index 0000000000000000000000000000000000000000..d4f863a1a87d7aad3128481c763ee715aefd0a9f Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/Gala/figures/deadlock.png differ diff --git a/docs/en/25.03/Server/Maintenance/Gala/figures/deadlock2.png b/docs/en/25.03/Server/Maintenance/Gala/figures/deadlock2.png new file mode 100644 index 0000000000000000000000000000000000000000..3be42a5a34f90c2f3b351c7077635c580ea847a7 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/Gala/figures/deadlock2.png differ diff --git a/docs/en/25.03/Server/Maintenance/Gala/figures/deadlock3.png b/docs/en/25.03/Server/Maintenance/Gala/figures/deadlock3.png new file mode 100644 index 0000000000000000000000000000000000000000..5ef1a08394daf6433e10f85a5b3c57df25c3e303 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/Gala/figures/deadlock3.png differ diff --git a/docs/en/25.03/Server/Maintenance/Gala/figures/flame_muti_ins.png b/docs/en/25.03/Server/Maintenance/Gala/figures/flame_muti_ins.png new file mode 100644 index 0000000000000000000000000000000000000000..5943c7fda223a7fde4d2987ad56af4ffa776bd81 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/Gala/figures/flame_muti_ins.png differ diff --git "a/docs/en/25.03/Server/Maintenance/Gala/figures/gala-gopher\346\210\220\345\212\237\345\220\257\345\212\250\347\212\266\346\200\201.png" "b/docs/en/25.03/Server/Maintenance/Gala/figures/gala-gopher\346\210\220\345\212\237\345\220\257\345\212\250\347\212\266\346\200\201.png" new file mode 100644 index 0000000000000000000000000000000000000000..ab16e9d3661db3fd4adc6c605b2d2d08e79fdc1c Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/Gala/figures/gala-gopher\346\210\220\345\212\237\345\220\257\345\212\250\347\212\266\346\200\201.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/Gala/figures/gala-spider\350\275\257\344\273\266\346\236\266\346\236\204\345\233\276.png" "b/docs/en/25.03/Server/Maintenance/Gala/figures/gala-spider\350\275\257\344\273\266\346\236\266\346\236\204\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..c5a0768be63a98ef7ccc4a56996a8c715f7090af Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/Gala/figures/gala-spider\350\275\257\344\273\266\346\236\266\346\236\204\345\233\276.png" differ diff --git "a/docs/en/25.03/Server/Maintenance/Gala/figures/gopher\350\275\257\344\273\266\346\236\266\346\236\204\345\233\276.png" "b/docs/en/25.03/Server/Maintenance/Gala/figures/gopher\350\275\257\344\273\266\346\236\266\346\236\204\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..f151965a21d11dd7a3e215cc4ef23d70d059f4b1 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/Gala/figures/gopher\350\275\257\344\273\266\346\236\266\346\236\204\345\233\276.png" differ diff --git a/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete1.png b/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete1.png new file mode 100644 index 0000000000000000000000000000000000000000..5848b114e02d09f23303da8cff7aef56216f655f Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete1.png differ diff --git a/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete2.png b/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete2.png new file mode 100644 index 0000000000000000000000000000000000000000..ed02a882a145dafeafb76469f328085edecc6775 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete2.png differ diff --git a/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete3.png b/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete3.png new file mode 100644 index 0000000000000000000000000000000000000000..3992edc5b7ea61d8a2aa08ce47f0876b7d2e8cf3 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete3.png differ diff --git a/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete4.png b/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete4.png new file mode 100644 index 0000000000000000000000000000000000000000..049ac49bcc1fb71ea9fe6866bd27e84d0acf42b1 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete4.png differ diff --git a/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete5.png b/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete5.png new file mode 100644 index 0000000000000000000000000000000000000000..8b5cf5aaef43f125abdf3adb8a7f798dd2c86b54 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete5.png differ diff --git a/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete6.png b/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete6.png new file mode 100644 index 0000000000000000000000000000000000000000..c3b1f5f097b9e9bcabf75229eabc6ce8fe126a71 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/Gala/figures/lockcompete6.png differ diff --git "a/docs/en/25.03/Server/Maintenance/Gala/figures/spider\346\213\223\346\211\221\345\205\263\347\263\273\345\233\276.png" "b/docs/en/25.03/Server/Maintenance/Gala/figures/spider\346\213\223\346\211\221\345\205\263\347\263\273\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..5823a116f384801e1197350f151b4d04ef519ac4 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/Gala/figures/spider\346\213\223\346\211\221\345\205\263\347\263\273\345\233\276.png" differ diff --git a/docs/en/25.03/Server/Maintenance/Gala/figures/tprofiling-dashboard-detail.png b/docs/en/25.03/Server/Maintenance/Gala/figures/tprofiling-dashboard-detail.png new file mode 100644 index 0000000000000000000000000000000000000000..2093808bc4e1654956f6143393757c1244f08f98 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/Gala/figures/tprofiling-dashboard-detail.png differ diff --git a/docs/en/25.03/Server/Maintenance/Gala/figures/tprofiling-dashboard.png b/docs/en/25.03/Server/Maintenance/Gala/figures/tprofiling-dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..15f4917f5a0bfcf5dee1f8fe68e65635ffebd85e Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/Gala/figures/tprofiling-dashboard.png differ diff --git a/docs/en/25.03/Server/Maintenance/Gala/figures/tprofiling-run-arch.png b/docs/en/25.03/Server/Maintenance/Gala/figures/tprofiling-run-arch.png new file mode 100644 index 0000000000000000000000000000000000000000..0ad835125a5e7b7f66938543de1e1c9d53706ce4 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/Gala/figures/tprofiling-run-arch.png differ diff --git a/docs/en/25.03/Server/Maintenance/Gala/using-gala-anteater.md b/docs/en/25.03/Server/Maintenance/Gala/using-gala-anteater.md new file mode 100644 index 0000000000000000000000000000000000000000..b5d4adfe43a427b2d32ca3d6831d9eccd0bcf320 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/Gala/using-gala-anteater.md @@ -0,0 +1,394 @@ +# gala-anteater使用手册 + +gala-anteater是一款基于AI的操作系统异常检测平台。主要提供时序数据预处理、异常点发现、异常上报等功能。基于线下预训练、线上模型的增量学习与模型更新,能够很好地适用于多维多模态数据故障诊断。 + +本文主要介绍如何部署和使用gala-anteater服务。 + +## 安装 + +挂载repo源: + +```basic +[everything] +name=everything +baseurl=http://121.36.84.172/dailybuild/EBS-openEuler-24.09/EBS-openEuler-24.09/everything/$basearch/ +enabled=1 +gpgcheck=0 +priority=1 + +[EPOL] +name=EPOL +baseurl=http://repo.openeuler.org/openEuler-22.03-LTS-SP4/EPOL/main/$basearch/ +enabled=1 +gpgcheck=0 +priority=1 +``` + +安装gala-anteater: + +```bash +yum install gala-anteater +``` + +## 配置 + +> 说明:gala-anteater采用配置的config文件设置参数启动,配置文件位置: /etc/gala-anteater/config/gala-anteater.yaml。 + +### 配置文件默认参数 + +```yaml +Global: + data_source: "prometheus" + +Arangodb: + url: "http://localhost:8529" + db_name: "spider" + +Kafka:f + server: "192.168.122.100" + port: "9092" + model_topic: "gala_anteater_hybrid_model" + rca_topic: "gala_cause_inference" + meta_topic: "gala_gopher_metadata" + group_id: "gala_anteater_kafka" + # auth_type: plaintext/sasl_plaintext, please set "" for no auth + auth_type: "" + username: "" + password: "" + +Prometheus: + server: "localhost" + port: "9090" + steps: "5" + +Aom: + base_url: "" + project_id: "" + auth_type: "token" + auth_info: + iam_server: "" + iam_domain: "" + iam_user_name: "" + iam_password: "" + ssl_verify: 0 + +Schedule: + duration: 1 + +``` + +| 参数 | 含义 | 默认值 | +| ----------- | --------------------------------------------------- | ---------------------------- | +| Global | | | +| data_source | 设置数据来源 | “prometheus” | +| Arangodb | | | +| url | 图数据库Arangodb的ip地址 | "" | +| db_name | 图数据库名 | "spider" | +| Kafka | | | +| server | Kafka Server的ip地址,根据安装节点ip配置 | | +| port | Kafka Server的port,如:9092 | | +| model_topic | 故障检测结果上报topic | "gala_anteater_hybrid_model" | +| rca_topic | 根因定位结果上报topic | "gala_cause_inference" | +| meta_topic | gopher采集指标数据topic | "gala_gopher_metadata" | +| group_id | kafka设置组名 | "gala_anteater_kafka" | +| Prometheus | | | +| server | Prometheus Server的ip地址,根据安装节点ip配置 | | +| port | Prometheus Server的port,如:9090 | | +| steps | 指标采样间隔 | | +| Schedule | | | +| duration | 异常检测模型执行频率(单位:分),每x分钟,检测一次 | 1 | + +## 启动 + +执行如下命令启动gala-anteater + +```shell +systemctl start gala-anteater +``` + +**注意**:gala-anteater支持启动一个进程实例,启动多个会导致内存占用过大,日志混乱。 + +### 故障注入 + +gala-anteater为故障检测与根因定位模块,测试阶段需要通过故障注入来构造故障,从而通过故障检测和根因定位模块获得故障节点信息和故障传播根因节点信息。 + +* 故障注入(仅提供参考) + + ```bash + chaosblade create disk burn --size 10 --read --write --path /var/lib/docker/overlay2/cf0a469be8a84cabe1d057216505f8d64735e9c63159e170743353a208f6c268/merged --timeout 120 + ``` + + *chaosblade 为故障注入工具, 可以模拟各种故障, 包括但不限于磁盘故障、网络故障、IO故障等待 + 备注: 通过注入不一样的故障, 指标采集器(例如 gala-gopher) 监控关联指标并上报到 promethues 模块, prometheus graph 指标图部分关联指标会存在明显波动。 + +### 查询gala-anteater服务状态 + +若日志显示如下内容,说明服务启动成功,启动日志也会保存到当前运行目录下`logs/anteater.log`文件中。 + +```log +2022-09-01 17:52:54,435 - root - INFO - Run gala_anteater main function... +2022-09-01 17:52:54,436 - root - INFO - Start to try updating global configurations by querying data from Kafka! +2022-09-01 17:52:54,994 - root - INFO - Loads metric and operators from file: xxx\metrics.csv +2022-09-01 17:52:54,997 - root - INFO - Loads metric and operators from file: xxx\metrics.csv +2022-09-01 17:52:54,998 - root - INFO - Start to re-train the model based on last day metrics dataset! +2022-09-01 17:52:54,998 - root - INFO - Get training data during 2022-08-31 17:52:00+08:00 to 2022-09-01 17:52:00+08:00! +2022-09-01 17:53:06,994 - root - INFO - Spends: 11.995422840118408 seconds to get unique machine_ids! +2022-09-01 17:53:06,995 - root - INFO - The number of unique machine ids is: 1! +2022-09-01 17:53:06,996 - root - INFO - Fetch metric values from machine: xxxx. +2022-09-01 17:53:38,385 - root - INFO - Spends: 31.3896164894104 seconds to get get all metric values! +2022-09-01 17:53:38,392 - root - INFO - The shape of training data: (17281, 136) +2022-09-01 17:53:38,444 - root - INFO - Start to execute vae model training... +2022-09-01 17:53:38,456 - root - INFO - Using cpu device +2022-09-01 17:53:38,658 - root - INFO - Epoch(s): 0 train Loss: 136.68 validate Loss: 117.00 +2022-09-01 17:53:38,852 - root - INFO - Epoch(s): 1 train Loss: 113.73 validate Loss: 110.05 +2022-09-01 17:53:39,044 - root - INFO - Epoch(s): 2 train Loss: 110.60 validate Loss: 108.76 +2022-09-01 17:53:39,235 - root - INFO - Epoch(s): 3 train Loss: 109.39 validate Loss: 106.93 +2022-09-01 17:53:39,419 - root - INFO - Epoch(s): 4 train Loss: 106.48 validate Loss: 103.37 +... +2022-09-01 17:53:57,744 - root - INFO - Epoch(s): 98 train Loss: 97.63 validate Loss: 96.76 +2022-09-01 17:53:57,945 - root - INFO - Epoch(s): 99 train Loss: 97.75 validate Loss: 96.58 +2022-09-01 17:53:57,969 - root - INFO - Schedule recurrent job with time interval 1 minute(s). +2022-09-01 17:53:57,973 - apscheduler.scheduler - INFO - Adding job tentatively -- it will be properly scheduled when the scheduler starts +2022-09-01 17:53:57,974 - apscheduler.scheduler - INFO - Added job "partial" to job store "default" +2022-09-01 17:53:57,974 - apscheduler.scheduler - INFO - Scheduler started +2022-09-01 17:53:57,975 - apscheduler.scheduler - DEBUG - Looking for jobs to run +2022-09-01 17:53:57,975 - apscheduler.scheduler - DEBUG - Next wakeup is due at 2022-09-01 17:54:57.973533+08:00 (in 59.998006 seconds) +``` + +## 异常检测输出数据 + +gala-anteater如果检测到异常点,会将结果输出至kafka的model_topic,输出数据格式如下: + +```json +{ + "Timestamp":1659075600000, + "Attributes":{ + "entity_id":"xxxxxx_sli_1513_18", + "event_id":"1659075600000_1fd37742xxxx_sli_1513_18", + "event_type":"app" + }, + "Resource":{ + "anomaly_score":1.0, + "anomaly_count":13, + "total_count":13, + "duration":60, + "anomaly_ratio":1.0, + "metric_label":{ + "machine_id":"1fd37742xxxx", + "tgid":"1513", + "conn_fd":"18" + }, + "recommend_metrics":{ + "gala_gopher_tcp_link_notack_bytes":{ + "label":{ + "__name__":"gala_gopher_tcp_link_notack_bytes", + "client_ip":"x.x.x.165", + "client_port":"51352", + "hostname":"localhost.localdomain", + "instance":"x.x.x.172:8888", + "job":"prometheus-x.x.x.172", + "machine_id":"xxxxxx", + "protocol":"2", + "role":"0", + "server_ip":"x.x.x.172", + "server_port":"8888", + "tgid":"3381701" + }, + "score":0.24421279500639545 + }, + ... + }, + "metrics":"gala_gopher_ksliprobe_recent_rtt_nsec" + }, + "SeverityText":"WARN", + "SeverityNumber":14, + "Body":"TimeStamp, WARN, APP may be impacting sli performance issues." +} +``` + +## 根因定位输出数据 + +异常检测结果的每个异常节点都会触发根因定位,根因定位的结果会上报至kafka的rca_topic。输出数据格式如下: + +```yaml +{ + "Timestamp": 1724287883452, + "event_id": "1721125159975_475ae627-7e88-41ed-8bb8-ff0fee95a69d_l7_3459438_192.168.11.103_192.168.11.102_26_tcp_server_server_http", + "Attributes": { + "event_id": "1721125159975_475ae627-7e88-41ed-8bb8-ff0fee95a69d_l7_3459438_192.168.11.103_192.168.11.102_26_tcp_server_server_http", + "event_source": "root-cause-inference" + }, + "Resource": { + "abnormal_kpi": { + "metric_id": "gala_gopher_l7_latency_sum", + "entity_id": "", + "metric_labels": { + "client_ip": "192.168.11.103", + "comm": "python", + "container_id": "83d0c2f4a7f4", + "container_image": "ba2d060a624e", + "container_name": "/k8s_backend_backend-node2-01-5bcb47fd7c-4jxxs_default_475ae627", + "instance": "192.168.122.102:8888", + "job": "192.168.122.102", + "l4_role": "tcp_server", + "l7_role": "server", + "machine_id": "66086618-3bad-489e-b17d-05245224f29a-192.168.122.102", + "pod": "default/backend-node2-01-5bcb47fd7c-4jxxs", + "pod_id": "475ae627-7e88-41ed-8bb8-ff0fee95a69d", + "pod_namespace": "default", + "protocol": "http", + "server_ip": "192.168.11.102", + "server_port": "26", + "ssl": "no_ssl", + "tgid": "3459438" + }, + "desc": "L7 session averaged latency.", + "score": 0.3498585816683402 + }, + "cause_metrics": [ + { + "metric_id": "gala_gopher_container_cpu_user_seconds_total@4a9fcc23-8ba2-4b0a-bcb0-b1bfd89ed929", + "entity_id": "", + "metric_labels": { + "container_id": "1319ff912a6f", + "container_image": "ba2d060a624e", + "container_name": "/k8s_backend_backend-node3-02-654dd97bf9-s8jg5_default_4a9fcc23", + "instance": "192.168.122.103:8888", + "job": "192.168.122.103", + "machine_id": "494a61be-23cc-4c97-a871-902866e43747-192.168.122.103", + "pod": "default/backend-node3-02-654dd97bf9-s8jg5", + "pod_id": "4a9fcc23-8ba2-4b0a-bcb0-b1bfd89ed929", + "pod_namespace": "default" + }, + "desc": "\u5bb9\u56681s\u5185\u7528\u6237\u6001CPU\u8d1f\u8f7d", + "keyword": "process", + "score": 0.1194249668036936, + "path": [ + { + "pod_id": "4a9fcc23-8ba2-4b0a-bcb0-b1bfd89ed929", + "pod": "default/backend-node3-02-654dd97bf9-s8jg5", + "instance": "192.168.122.103:8888", + "job": "192.168.122.103", + "pod_state": "normal" + }, + { + "pod_id": "475ae627-7e88-41ed-8bb8-ff0fee95a69d", + "pod": "default/backend-node2-01-5bcb47fd7c-4jxxs", + "instance": "192.168.122.102:8888", + "job": "192.168.122.102", + "pod_state": "abnormal" + } + ] + }, + { + "metric_id": "gala_gopher_proc_wchar_bytes@67134fb4-b2a3-43c5-a5b3-b3b463ad7d43", + "entity_id": "", + "metric_labels": { + "cmdline": "python ./backend.py ", + "comm": "python", + "container_id": "de570c7328bb", + "container_image": "ba2d060a624e", + "container_name": "/k8s_backend_backend-node2-02-548c79d989-bnl9g_default_67134fb4", + "instance": "192.168.122.102:8888", + "job": "192.168.122.102", + "machine_id": "66086618-3bad-489e-b17d-05245224f29a-192.168.122.102", + "pgid": "3459969", + "pod": "default/backend-node2-02-548c79d989-bnl9g", + "pod_id": "67134fb4-b2a3-43c5-a5b3-b3b463ad7d43", + "pod_namespace": "default", + "ppid": "3459936", + "start_time": "1139543501", + "tgid": "3459969" + }, + "desc": "\u8fdb\u7a0b\u7cfb\u7edf\u8c03\u7528\u81f3FS\u7684\u5199\u5b57\u8282\u6570", + "keyword": "process", + "score": 0.37121879175399997, + "path": [ + { + "pod_id": "67134fb4-b2a3-43c5-a5b3-b3b463ad7d43", + "pod": "default/backend-node2-02-548c79d989-bnl9g", + "instance": "192.168.122.102:8888", + "job": "192.168.122.102", + "pod_state": "normal" + }, + { + "pod_id": "4a9fcc23-8ba2-4b0a-bcb0-b1bfd89ed929", + "pod": "default/backend-node3-02-654dd97bf9-s8jg5", + "instance": "192.168.122.103:8888", + "job": "192.168.122.103", + "pod_state": "normal" + }, + { + "pod_id": "475ae627-7e88-41ed-8bb8-ff0fee95a69d", + "pod": "default/backend-node2-01-5bcb47fd7c-4jxxs", + "instance": "192.168.122.102:8888", + "job": "192.168.122.102", + "pod_state": "abnormal" + } + ] + }, + { + "metric_id": "gala_gopher_l7_latency_avg@956c70a2-9918-459c-a0a8-39396251f952", + "entity_id": "", + "metric_labels": { + "client_ip": "192.168.11.103", + "comm": "python", + "container_id": "eef1ca1082a7", + "container_image": "ba2d060a624e", + "container_name": "/k8s_backend_backend-node2-03-584f4c6cfd-w4d2b_default_956c70a2", + "instance": "192.168.122.102:8888", + "job": "192.168.122.102", + "l4_role": "tcp_server", + "l7_role": "server", + "machine_id": "66086618-3bad-489e-b17d-05245224f29a-192.168.122.102", + "pod": "default/backend-node2-03-584f4c6cfd-w4d2b", + "pod_id": "956c70a2-9918-459c-a0a8-39396251f952", + "pod_namespace": "default", + "protocol": "http", + "server_ip": "192.168.11.113", + "server_port": "26", + "ssl": "no_ssl", + "tgid": "3460169" + }, + "desc": "L7 session averaged latency.", + "keyword": null, + "score": 0.5624857367147617, + "path": [ + { + "pod_id": "956c70a2-9918-459c-a0a8-39396251f952", + "pod": "default/backend-node2-03-584f4c6cfd-w4d2b", + "instance": "192.168.122.102:8888", + "job": "192.168.122.102", + "pod_state": "abnormal" + }, + { + "pod_id": "4a9fcc23-8ba2-4b0a-bcb0-b1bfd89ed929", + "pod": "default/backend-node3-02-654dd97bf9-s8jg5", + "instance": "192.168.122.103:8888", + "job": "192.168.122.103", + "pod_state": "normal" + }, + { + "pod_id": "475ae627-7e88-41ed-8bb8-ff0fee95a69d", + "pod": "default/backend-node2-01-5bcb47fd7c-4jxxs", + "instance": "192.168.122.102:8888", + "job": "192.168.122.102", + "pod_state": "abnormal" + } + ] + } + ] + }, + "desc": "L7 session averaged latency.", + "top1": "gala_gopher_container_cpu_user_seconds_total@4a9fcc23-8ba2-4b0a-bcb0-b1bfd89ed929\u5f02\u5e38", + "top2": "gala_gopher_proc_wchar_bytes@67134fb4-b2a3-43c5-a5b3-b3b463ad7d43\u5f02\u5e38", + "top3": "gala_gopher_l7_latency_avg@956c70a2-9918-459c-a0a8-39396251f952\u5f02\u5e38", + "keywords": [ + "process", + null + ], + "SeverityText": "WARN", + "SeverityNumber": 13, + "Body": "A cause inferring event for an abnormal event" +} +``` diff --git a/docs/en/25.03/Server/Maintenance/Gala/using-gala-gopher.md b/docs/en/25.03/Server/Maintenance/Gala/using-gala-gopher.md new file mode 100644 index 0000000000000000000000000000000000000000..8076979f4ddd735ae6799f6f7cdb42c576086a49 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/Gala/using-gala-gopher.md @@ -0,0 +1,1130 @@ +# gala-gopher使用手册 + +gala-gopher作为数据采集模块提供OS级的监控能力,支持动态加 /卸载探针,可无侵入式地集成第三方探针,快速扩展监控范围。 + +本文介绍如何部署和使用gala-gopher服务。 + +## 安装 + +挂载repo源: + +```basic +[oe-2309] # openEuler 2309 官方发布源 +name=oe2309 +baseurl=http://119.3.219.20:82/openEuler:/23.09/standard_x86_64 +enabled=1 +gpgcheck=0 +priority=1 + +[oe-2309:Epol] # openEuler 2309:Epol 官方发布源 +name=oe2309_epol +baseurl=http://119.3.219.20:82/openEuler:/23.09:/Epol/standard_x86_64/ +enabled=1 +gpgcheck=0 +priority=1 +``` + +安装gala-gopher: + +```bash +# yum install gala-gopher +``` + +## 配置 + +### 配置介绍 + +gala-gopher配置文件为`/opt/gala-gopher/gala-gopher.conf`,该文件配置项说明如下(省略无需用户配置的部分)。 + +如下配置可以根据需要进行修改: + +- global:gala-gopher全局配置信息 + - log_file_name:gala-gopher日志文件名 + - log_level:gala-gopher日志级别(暂未开放此功能) + - pin_path:ebpf探针共享map存放路径(建议维持默认配置) +- metric:指标数据metrics输出方式配置 + - out_channel:metrics输出通道,支持配置web_server|logs|kafka,配置为空则输出通道关闭 + - kafka_topic:若输出通道为kafka,此为topic配置信息 +- event:异常事件event输出方式配置 + - out_channel:event输出通道,支持配置logs|kafka,配置为空则输出通道关闭 + - kafka_topic:若输出通道为kafka,此为topic配置信息 + - timeout:同一异常事件上报间隔设置 + - desc_language:异常事件描述信息语言选择,当前支持配置zh_CN|en_US +- meta:元数据metadata输出方式配置 + - out_channel:metadata输出通道,支持logs|kafka,配置为空则输出通道关闭 + - kafka_topic:若输出通道为kafka,此为topic配置信息 +- ingress:探针数据上报相关配置 + - interval:暂未使用 +- egress:上报数据库相关配置 + - interval:暂未使用 + - time_range:暂未使用 +- imdb:cache缓存规格配置 + - max_tables_num:最大的cache表个数,/opt/gala-gopher/meta目录下每个meta对应一个表 + - max_records_num:每张cache表最大记录数,通常每个探针在一个观测周期内产生至少1条观测记录 + - max_metrics_num:每条观测记录包含的最大的metric指标个数 + - record_timeout:cache表老化时间,若cache表中某条记录超过该时间未刷新则删除记录,单位为秒 +- web_server:输出通道web_server配置 + - port:监听端口 +- rest_api_server + - port:RestFul API监听端口 + - ssl_auth:设置RestFul API开启https加密以及鉴权,on为开启,off为不开启,建议用户在实际生产环境开启 + - private_key:用于RestFul API https加密的服务端私钥文件绝对路径,当ssl_auth为“on”必配 + - cert_file:用于RestFul API https加密的服务端证书绝对路径,当ssl_auth为“on”必配 + - ca_file:用于RestFul API对客户端进行鉴权的CA中心证书绝对路径,当ssl_auth为“on”必配 +- kafka:输出通道kafka配置 + - kafka_broker:kafka服务器的IP和port + - batch_num_messages:每个批次发送的消息数量 + - compression_codec:消息压缩类型 + - queue_buffering_max_messages:生产者缓冲区中允许的最大消息数 + - queue_buffering_max_kbytes:生产者缓冲区中允许的最大字节数 + - queue_buffering_max_ms:生产者在发送批次之前等待更多消息加入的最大时间 +- logs:输出通道logs配置 + - metric_dir:metrics指标数据日志路径 + - event_dir:异常事件数据日志路径 + - meta_dir:metadata元数据日志路径 + - debug_dir:gala-gopher运行日志路径 + +#### 配置文件示例 + +- 配置选择数据输出通道: + + ```yaml + metric = + { + out_channel = "web_server"; + kafka_topic = "gala_gopher"; + }; + + event = + { + out_channel = "kafka"; + kafka_topic = "gala_gopher_event"; + }; + + meta = + { + out_channel = "kafka"; + kafka_topic = "gala_gopher_metadata"; + }; + ``` + +- 配置kafka和webServer: + + ```yaml + web_server = + { + port = 8888; + }; + + kafka = + { + kafka_broker = ":9092"; + }; + ``` + +### 启动 + +配置完成后,执行如下命令启动gala-gopher。 + +```bash +# systemctl start gala-gopher.service +``` + +查询gala-gopher服务状态。 + +```bash +# systemctl status gala-gopher.service +``` + +若显示结果如下,说明服务启动成功。需要关注开启的探针是否已启动,如果探针线程不存在,请检查配置文件及gala-gopher运行日志文件。 + +![gala-gopher成功启动状态](./figures/gala-gopher成功启动状态.png) + +> 说明:gala-gopher部署和运行均需要root权限。 + +### REST 动态配置接口 + +WEB server端口可配置(缺省9999),URL组织方式 ,比如火焰图的URL:(以下文档均以火焰图举例)。 + +#### 配置探针监控范围 + +探针默认关闭,可以通过API动态开启、设置监控范围。以火焰图为例,通过REST分别开启oncpu/offcpu/mem火焰图能力。并且监控范围支持进程ID、进程名、容器ID、POD四个维度来设置。 + +下面是火焰图同时开启oncpu, offcpu采集特性的API举例: + +```sh +curl -X PUT http://localhost:9999/flamegraph --data-urlencode json=' +{ + "cmd": { + "bin": "/opt/gala-gopher/extend_probes/stackprobe", + "check_cmd": "", + "probe": [ + "oncpu", + "offcpu" + ] + }, + "snoopers": { + "proc_id": [ + 101, + 102 + ], + "proc_name": [ + { + "comm": "app1", + "cmdline": "", + "debugging_dir": "" + }, + { + "comm": "app2", + "cmdline": "", + "debugging_dir": "" + } + ], + "pod_id": [ + "pod1", + "pod2" + ], + "container_id": [ + "container1", + "container2" + ] + } +}' +``` + +全量采集特性说明如下: + +| 采集特性 | 采集特性说明 | 采集子项范围 | 监控对象 | 启动文件 | 启动条件 | +| ------------- | ------------------------------------- | ------------------------------------------------------------ | ---------------------------------------- | ---------------------------------- | ------------------------- | +| flamegraph | 在线性能火焰图观测能力 | oncpu, offcpu, mem | proc_id, proc_name, pod_id, container_id | $gala-gopher-dir/stackprobe | NA | +| l7 | 应用7层协议观测能力 | l7_bytes_metrics、l7_rpc_metrics、l7_rpc_trace | proc_id, proc_name, pod_id, container_id | $gala-gopher-dir/l7probe | NA | +| tcp | TCP异常、状态观测能力 | tcp_abnormal, tcp_rtt, tcp_windows, tcp_rate, tcp_srtt, tcp_sockbuf, tcp_stats,tcp_delay | proc_id, proc_name, pod_id, container_id | $gala-gopher-dir/tcpprobe | NA | +| socket | Socket(TCP/UDP)异常观测能力 | tcp_socket, udp_socket | proc_id, proc_name, pod_id, container_id | $gala-gopher-dir/endpoint | NA | +| io | Block层I/O观测能力 | io_trace, io_err, io_count, page_cache | NA | $gala-gopher-dir/ioprobe | NA | +| proc | 进程系统调用、I/O、DNS、VFS等观测能力 | base_metrics, proc_syscall, proc_fs, proc_io, proc_dns,proc_pagecache | proc_id, proc_name, pod_id, container_id | $gala-gopher-dir/taskprobe | NA | +| jvm | JVM层GC, 线程, 内存, 缓存等观测能力 | NA | proc_id, proc_name, pod_id, container_id | $gala-gopher-dir/jvmprobe | NA | +| ksli | Redis性能SLI(访问时延)观测能力 | NA | proc_id, proc_name, pod_id, container_id | $gala-gopher-dir/ksliprobe | NA | +| postgre_sli | PG DB性能SLI(访问时延)观测能力 | NA | proc_id, proc_name, pod_id, container_id | $gala-gopher-dir/pgsliprobe | NA | +| opengauss_sli | openGauss访问吞吐量观测能力 | NA | [ip, port, dbname, user,password] | $gala-gopher-dir/pg_stat_probe.py | NA | +| dnsmasq | DNS会话观测能力 | NA | proc_id, proc_name, pod_id, container_id | $gala-gopher-dir/rabbitmq_probe.sh | NA | +| lvs | lvs会话观测能力 | NA | NA | $gala-gopher-dir/trace_lvs | lsmod\|grep ip_vs\| wc -l | +| nginx | Nginx L4/L7层会话观测能力 | NA | proc_id, proc_name, pod_id, container_id | $gala-gopher-dir/nginx_probe | NA | +| haproxy | Haproxy L4/7层会话观测能力 | NA | proc_id, proc_name, pod_id, container_id | $gala-gopher-dir/trace_haproxy | NA | +| kafka | kafka 生产者/消费者topic观测能力 | NA | dev, port | $gala-gopher-dir/kafkaprobe | NA | +| baseinfo | 系统基础信息 | cpu, mem, nic, disk, net, fs, proc,host | proc_id, proc_name, pod_id, container_id | system_infos | NA | +| virt | 虚拟化管理信息 | NA | NA | virtualized_infos | NA | +| tprofiling | 线程级性能profiling观测能力 | oncpu, syscall_file, syscall_net, syscall_lock, syscall_sched | proc_id, proc_name, pod_id, container_id | $gala-gopher-dir/tprofiling | NA | +| container | 容器信息 | NA | proc_id, proc_name, container_id | $gala-gopher-dir/cadvisor_probe.py | NA | + +#### 配置探针运行参数 + +探针在运行期间还需要设置一些参数设置,例如:设置火焰图的采样周期、上报周期。 + +```sh +curl -X PUT http://localhost:9999/flamegraph --data-urlencode json=' +{ + "params": { + "report_period": 180, + "sample_period": 180, + "metrics_type": [ + "raw", + "telemetry" + ] + } +}' +``` + +详细参数运行参数如下: + +| 参数 | 含义 | 缺省值&范围 | 单位 | 支持的监控范围 | gala-gopher是否支持 | +| ------------------ | ------------------------------------------------------ | ------------------------------------------------------------ | ------- | ------------------------ | ------------------- | +| sample_period | 采样周期 | 5000, [100~10000] | ms | io, tcp | Y | +| report_period | 上报周期 | 60, [5~600] | s | ALL | Y | +| latency_thr | 时延上报门限 | 0, [10~100000] | ms | tcp, io, proc, ksli | Y | +| offline_thr | 进程离线上报门限 | 0, [10~100000] | ms | proc | Y | +| drops_thr | 丢包上送门限 | 0, [10~100000] | package | tcp, nic | Y | +| res_lower_thr | 资源百分比下限 | 0%, [0%~100%] | percent | ALL | Y | +| res_upper_thr | 资源百分比上限 | 0%, [0%~100%] | percent | ALL | Y | +| report_event | 上报异常事件 | 0, [0, 1] | NA | ALL | Y | +| metrics_type | 上报telemetry metrics | raw, [raw, telemetry] | NA | ALL | N | +| env | 工作环境类型 | node, [node, container, kubenet] | NA | ALL | N | +| report_source_port | 是否上报源端口 | 0, [0, 1] | NA | tcp | Y | +| l7_protocol | L7层协议范围 | http, [http, pgsql, mysql, redis, kafka, mongo, rocketmq, dns] | NA | l7 | Y | +| support_ssl | 支持SSL加密协议观测 | 0, [0, 1] | NA | l7 | Y | +| multi_instance | 是否每个进程输出独立火焰图 | 0, [0, 1] | NA | flamegraph | Y | +| native_stack | 是否显示本地语言堆栈(针对JAVA进程) | 0, [0, 1] | NA | flamegraph | Y | +| cluster_ip_backend | 执行Cluster IP backend转换 | 0, [0, 1] | NA | tcp,l7 | Y | +| pyroscope_server | 设置火焰图UI服务端地址 | localhost:4040 | NA | flamegraph | Y | +| svg_period | 火焰图svg文件生成周期 | 180, [30, 600] | s | flamegraph | Y | +| perf_sample_period | oncpu火焰图采集堆栈信息的周期 | 10, [10, 1000] | ms | flamegraph | Y | +| svg_dir | 火焰图svg文件存储目录 | "/var/log/gala-gopher/stacktrace" | NA | flamegraph | Y | +| flame_dir | 火焰图原始堆栈信息存储目录 | "/var/log/gala-gopher/flamegraph" | NA | flamegraph | Y | +| dev_name | 观测的网卡/磁盘设备名 | "" | NA | io, kafka, ksli, postgre_sli,baseinfo, tcp | Y | +| continuous_sampling | 是否持续采样 | 0, [0, 1] | NA | ksli | Y | +| elf_path | 要观测的可执行文件的路径 | "" | NA | nginx, haproxy, dnsmasq | Y | +| kafka_port | 要观测的kafka端口号 | 9092, [1, 65535] | NA | kafka | Y | +| cadvisor_port | 启动的cadvisor端口号 | 8080, [1, 65535] | NA | cadvisor | Y | + +#### 启动、停止探针 + +```sh +curl -X PUT http://localhost:9999/flamegraph --data-urlencode json=' +{ + "state": "running" // optional: running,stopped +}' +``` + +#### 约束与限制说明 + +1. 接口为无状态形式,每次上传的设置为该探针的最终运行结果,包括状态、参数、监控范围。 +2. 监控对象可以任意组合,监控范围取合集。 +3. 启动文件必须真实有效。 +4. 采集特性可以按需开启全部/部分能力,关闭时只能整体关闭某个采集特性。 +5. opengauss监控对象是DB实例(IP/Port/dbname/user/password)。 +6. 接口每次最多接收2048长度的数据。 + +#### 获取探针配置与运行状态 + +```sh +curl -X GET http://localhost:9999/flamegraph +{ + "cmd": { + "bin": "/opt/gala-gopher/extend_probes/stackprobe", + "check_cmd": "" + "probe": [ + "oncpu", + "offcpu" + ] + }, + "snoopers": { + "proc_id": [ + 101, + 102 + ], + "proc_name": [ + { + "comm": "app1", + "cmdline": "", + "debugging_dir": "" + }, + { + "comm": "app2", + "cmdline": "", + "debugging_dir": "" + } + ], + "pod_id": [ + "pod1", + "pod2" + ], + "container_id": [ + "container1", + "container2" + ] + }, + "params": { + "report_period": 180, + "sample_period": 180, + "metrics_type": [ + "raw", + "telemetry" + ] + }, + "state": "running" +} +``` + +## stackprobe 介绍 + +适用于云原生环境的性能火焰图。 + +### 特性 + +- 支持观测C/C++、Go、Rust、Java语言应用。 + +- 调用栈支持容器、进程粒度:对于容器内进程,在调用栈底部分别以[Pod]和[Con]前缀标记工作负载Pod名称、容器Container名称。进程名以[\]前缀标识,线程及函数(方法)无前缀。 + +- 支持本地生成svg格式火焰图或上传调用栈数据到中间件。 + +- 支持依照进程粒度多实例生成/上传火焰图。 + +- 对于Java进程的火焰图,支持同时显示本地方法和Java方法。 + +- 支持oncpu/offcpu/mem等多类型火焰图。 + +- 支持自定义采样周期。 + +### 使用说明 + +启动命令示例(基本):使用默认参数启动性能火焰图。 + +```sh +curl -X PUT http://localhost:9999/flamegraph -d json='{ "cmd": {"probe": ["oncpu"] }, "snoopers": {"proc_name": [{ "comm": "cadvisor"}] }, "state": "running"}' +``` + +启动命令示例(进阶):使用自定义参数启动性能火焰图。完整可配置参数列表参见[配置探针运行参数](#配置探针运行参数)。 + +```sh +curl -X PUT http://localhost:9999/flamegraph -d json='{ "cmd": { "check_cmd": "", "probe": ["oncpu", "offcpu", "mem"] }, "snoopers": { "proc_name": [{ "comm": "cadvisor", "cmdline": "", "debugging_dir": "" }, { "comm": "java", "cmdline": "", "debugging_dir": "" }] }, "params": { "perf_sample_period": 100, "svg_period": 300, "svg_dir": "/var/log/gala-gopher/stacktrace", "flame_dir": "/var/log/gala-gopher/flamegraph", "pyroscope_server": "localhost:4040", "multi_instance": 1, "native_stack": 0 }, "state": "running"}' +``` + +下面说明主要配置项: + +- 设置开启的火焰图类型 + + 通过probe参数设置,参数值为`oncpu`,`offcpu`,`mem`,分别代表进程cpu占用时间,进程被阻塞时间,进程申请内存大小的统计。 + + 示例: + + `"probe": ["oncpu", "offcpu", "mem"]` + +- 设置生成本地火焰图svg文件的周期 + + 通过svg_period参数设置,单位为秒,默认值180,可选设置范围为[30, 600]的整数。 + + 示例: + + `"svg_period": 300` + +- 开启/关闭堆栈信息上传到pyroscope + + 通过pyroscope_server参数设置,参数值需要包含addr和port,参数为空或格式错误则探针不会尝试上传堆栈信息。 + + 上传周期30s。 + + 示例: + + `"pyroscope_server": "localhost:4040"` + +- 设置调用栈采样周期 + + 通过perf_sample_period设置,单位为毫秒,默认值10,可选设置范围为[10, 1000]的整数,此参数仅对oncpu类型的火焰图有效。 + + 示例: + + `"perf_sample_period": 100` + +- 开启/关闭多实例生成火焰图 + + 通过multi_instance设置,参数值为0或1,默认值为0。值为0表示所有进程的火焰图会合并在一起,值为1表示分开生成每个进程的火焰图。 + + 示例: + + `"multi_instance": 1` + +- 开启/关闭本地调用栈采集 + + 通过native_stack设置,参数值为0或1,默认值为0。此参数仅对JAVA进程有效。值为0表示不采集JVM自身的调用栈,值为1表示采集JVM自身的调用栈。 + + 示例: + + `"native_stack": 1` + + 显示效果:(左"native_stack": 1,右"native_stack": 0) + + ![image-20230804172905729](./figures/flame_muti_ins.png) + +### 实现方案 + +#### 1. 用户态程序逻辑 + +周期性地(30s)根据符号表将内核态上报的堆栈信息从地址转换为符号。然后使用flamegraph插件或pyroscope将符号化的调用栈转换为火焰图。 + +其中,对于代码段类型获取符号表的方法不同。 + +- 内核符号表获取:读取/proc/kallsyms。 + +- 本地语言符号表获取:查询进程的虚拟内存映射文件(/proc/{pid}/maps),获取进程内存中各个代码段的地址映射,然后利用libelf库加载每个代码段对应模块的符号表。 + +- Java语言符号表获取: + + 由于 Java 方法没有静态映射到进程的虚拟地址空间,因此我们采用其他方式获取符号化的Java调用栈。 + +##### 方式一:perf观测 + +通过往Java进程加载JVM agent动态库来跟踪JVM的方法编译加载事件,获取并记录内存地址到Java符号的映射,从而实时生成Java进程的符号表。这种方法需要Java进程开启-XX:+PreserveFramePointer启动参数。本方式的优点是火焰图中可显示JVM自身的调用栈,而且这种方式生成的Java火焰图可以和其他进程的火焰图合并显示。 + +##### 方式二:JFR观测 + +通过动态开启JVM内置分析器JFR来跟踪Java应用程序的各种事件和指标。开启JFR的方式为往Java进程加载Java agent,Java agent中会调用JFR API。本方式的优点是对Java方法调用栈的采集会更加准确详尽。 + +上述两种针对Java进程的性能分析方法都可以实时加载(不需要重启Java进程)且具有低底噪的优点。当stackprobe的启动参数为"multi_instance": 1且"native_stack": 0时,stackprobe会使用方法二生成Java进程火焰图,否则会使用方法一。 + +#### 2. 内核态程序逻辑 + +内核态基于eBPF实现。不同火焰图类型对应不同的eBPF程序。eBPF程序会周期性地或通过事件触发的方式遍历当前用户态和内核态的调用栈,并上报用户态。 + +##### 2.1 oncpu火焰图 + +在perf SW事件PERF_COUNT_SW_CPU_CLOCK上挂载采样eBPF程序,周期性采样调用栈。 + +##### 2.2 offcpu火焰图 + +在进程调度的tracepoint(sched_switch)上挂载采样eBPF程序,采样eBPF程序中记录进程被调度出去时间和进程id,在进程被调度回来时采样调用栈。 + +#### 2.3 mem火焰图 + +在缺页异常的tracepoint(page_fault_user)上挂载采样eBPF程序,事件触发时采样调用栈。 + +#### 3. Java语言支持 + +- stackprobe主进程: + + 1. 接收到ipc消息获取要观测的Java进程。 + 2. 使用Java代理加载模块向待观测的Java进程加载JVM代理程序:jvm_agent.so(对应[方式一](#方式一perf观测))或JstackProbeAgent.jar(对应[方式二](#方式二jfr观测))。 + 3. 方式一主进程会加载对应java进程的java-symbols.bin文件,供地址转换符号时查询。方式二主进程会加载对应java进程的stacks-{flame_type}.txt文件,可直接供火焰图生成。 + +- Java代理加载模块 + + 1. 发现新增java进程则将JVM代理程序复制到该进程空间下/proc/\/root/tmp(因为attach时容器内JVM需要可见此代理程序)。 + 2. 设置上述目录和JVM代理程序的owner和被观测java进程一致。 + 3. 启动jvm_attach子进程,并传入被观测java进程相关参数。 + +- JVM代理程序 + + - jvm_agent.so:注册JVMTI回调函数 + + 当JVM加载一个Java方法或者动态编译一个本地方法时JVM会调用回调函数,回调函数会将java类名和方法名以及对应的内存地址写入到被观测java进程空间下(/proc/\/root/tmp/java-data-\/java-symbols.bin)。 + - JstackProbeAgent.jar:调用JFR API + + 开启持续30s的JFR功能,并转换JFR统计结果为火焰图可用的堆栈格式,结果输出到到被观测java进程空间下(/proc/\/root/tmp/java-data-\/stacks-\.txt)。详见[JstackProbe简介](https://gitee.com/openeuler/gala-gopher/blob/dev/src/probes/extends/java.probe/jstack.probe/readme.md)。 + +- jvm_attach:用于实时加载JVM代理程序到被观测进程的JVM上 + (参考jdk源码中sun.tools.attach.LinuxVirtualMachine和jattach工具)。 + + 1. 设置自身的namespace(JVM加载agent时要求加载进程和被观测进程的namespace一致)。 + + 2. 检查JVM attach listener是否启动(是否存在UNIX socket文件:/proc/\/root/tmp/.java_pid\)。 + + 3. 未启动则创建/proc/\/cwd/.attach_pid\,并发送SIGQUIT信号给JVM。 + + 4. 连接UNIX socket。 + + 5. 读取响应为0表示attach成功。 + + attach agent流程图示: + + ![attach流程](./figures/attach流程.png) + +### 注意事项 + +- 对于Java应用的观测,为获取最佳观测效果,请设置stackprobe启动选项为"multi_instance": 1, "native_stack": 0来使能JFR观测(JDK8u262+)。否则stackprobe会以perf方式来生成Java火焰图。perf方式下,请开启JVM选项XX:+PreserveFramePointer(JDK8以上)。 + +### 约束条件 + +- 支持基于hotspot JVM的Java应用观测。 + +## tprofiling 介绍 + +tprofiling 是 gala-gopher 提供的一个基于 ebpf 的线程级应用性能诊断工具,它使用 ebpf 技术观测线程的关键系统性能事件,并关联丰富的事件内容,从而实时地记录线程的运行状态和关键行为,帮助用户快速识别应用性能问题。 + +### 功能特性 + +从操作系统的视角来看,一个运行的应用程序是由多个进程组成,每个进程是由多个运行的线程组成。tprofiling 通过观测这些线程运行过程中执行的一些关键行为(后面称之为**事件**)并记录下来,然后在前端界面以时间线的方式进行展示,进而就可以很直观地分析这些线程在某段时间内正在做什么,是在 CPU 上执行还是阻塞在某个文件、网络操作上。当应用程序出现性能问题时,通过分析对应线程的关键性能事件的执行序列,快速地进行定界定位。 + +基于当前已实现的事件观测范围, tprofiling 能够定位的应用性能问题场景主要包括: + +- 文件 I/O 耗时、阻塞问题 +- 网络 I/O 耗时、阻塞问题 +- 锁竞争问题 +- 死锁问题 + +随着更多类型的事件不断地补充和完善,tprofiling 将能够覆盖更多类型的应用性能问题场景。 + +### 事件观测范围 + +tprofiling 当前支持的系统性能事件包括两大类:系统调用事件和 oncpu 事件。 + +**系统调用事件** + +应用性能问题通常是由于系统资源出现瓶颈导致,比如 CPU 资源占用过高、I/O 资源等待。应用程序往往通过系统调用访问这些系统资源,因此可以对关键的系统调用事件进行观测来识别耗时、阻塞的资源访问操作。 + +tprofiling 当前已观测的系统调用事件参见章节: [支持的系统调用事件](#支持的系统调用事件) ,大致分为几个类型:文件操作(file)、网络操作(net)、锁操作(lock)和调度操作(sched)。下面列出部分已观测的系统调用事件: + +- 文件操作(file) + - read/write:读写磁盘文件或网络,可能会耗时、阻塞。 + - sync/fsync:对文件进行同步刷盘操作,完成前线程会阻塞。 +- 网络操作(net) + - send/recv:读写网络,可能会耗时、阻塞。 +- 锁操作(lock) + - futex:用户态锁实现相关的系统调用,触发 futex 往往意味出现锁竞争,线程可能进入阻塞状态。 +- 调度操作(sched):这里泛指那些可能会引起线程状态变化的系统调用事件,如线程让出 cpu 、睡眠、或等待其他线程等。 + - nanosleep:线程进入睡眠状态。 + - epoll_wait:等待 I/O 事件到达,事件到达之前线程会阻塞。 + +**oncpu 事件** + +此外,根据线程是否在 CPU 上运行可以将线程的运行状态分为两种:oncpu 和 offcpu ,前者表示线程正在 CPU 上运行,后者表示线程不在 CPU 上运行。通过观测线程的 oncpu 事件,可以识别线程是否正在执行耗时的 cpu 操作。 + +### 事件内容 + +线程 profiling 事件主要包括以下几部分内容。 + +- 事件来源信息:包括事件所属的线程ID、线程名、进程ID、进程名、容器ID、容器名、主机ID、主机名等信息。 + + - `thread.pid`:事件所属的线程ID。 + - `thread.comm`:事件所属的线程名。 + - `thread.tgid`:事件所属的进程ID。 + - `proc.name`:事件所属的进程名。 + - `container.id`:事件所属的容器ID。 + - `container.name`:事件所属的容器名。 + - `host.id`:事件所属的主机ID。 + - `host.name`:事件所属的主机名。 + +- 事件属性信息:包括公共的事件属性和扩展的事件属性。 + + - 公共的事件属性:包括事件名、事件类型、事件开始时间、事件结束时间、事件执行时间等。 + + - `event.name`:事件名。 + - `event.type`:事件类型,目前支持 oncpu、file、net、lock、sched 五种。 + - `start_time`:事件开始时间,聚合事件中第一个事件的开始时间,关于聚合事件的说明参见章节:[聚合事件](#聚合事件) 。 + - `end_time`:事件结束时间,聚合事件中最后一个事件的结束时间。 + - `duration`:事件执行时间,值为(end_time - start_time)。 + - `count`:事件聚合数量。 + + - 扩展的事件属性:针对不同的系统调用事件,补充更加丰富的事件内容。如 read/write 文件或网络时,提供文件路径、网络连接以及函数调用栈等信息。 + + - `func.stack`:事件的函数调用栈信息。 + - `file.path`:文件类事件的文件路径信息。 + - `sock.conn`:网络类事件的tcp连接信息。 + - `futex.op`:futex系统调用事件的操作类型,取值为 wait 或 wake 。 + + 不同事件类型支持的扩展事件属性的详细情况参见章节:[支持的系统调用事件](#支持的系统调用事件) 。 + +### 事件输出 + +tprofiling 作为 gala-gopher 提供的一个扩展的 ebpf 探针程序,产生的系统事件会发送至 gala-gopher 处理,并由 gala-gopher 按照开源的 openTelemetry 事件格式对外输出,并通过 json 格式发送到 kafka 消息队列中。前端可以通过对接 kafka 消费 tprofiling 事件。 + +下面是线程 profiling 事件的一个输出示例: + +```json +{ + "Timestamp": 1661088145000, + "SeverityText": "INFO", + "SeverityNumber": 9, + "Body": "", + "Resource": { + "host.id": "", + "host.name": "", + "thread.pid": 10, + "thread.tgid": 10, + "thread.comm": "java", + "proc.name": "xxx.jar", + "container.id": "", + "container.name": "", + }, + "Attributes": { + values: [ + { + // common info + "event.name": "read", + "event.type": "file", + "start_time": 1661088145000, + "end_time": 1661088146000, + "duration": 0.1, + "count": 1, + // extend info + "func.stack": "read;", + "file.path": "/test.txt" + }, + { + "event.name": "oncpu", + "event.type": "oncpu", + "start_time": 1661088146000, + "end_time": 1661088147000, + "duration": 0.1, + "count": 1, + } + ] + } +} +``` + +部分字段说明: + +- `Timestamp`:事件上报的事件点。 +- `Resource`:包括事件来源信息。 +- `Attributes`:包括事件属性信息,它包含一个 `values` 列表字段,列表中的每一项表示一个属于相同来源的 tprofiling 事件,其中包含该事件的属性信息。 + +### 快速开始 + +#### 安装部署 + +tprofiling 是 gala-gopher 提供的一个扩展的 ebpf 探针程序,因此,需要先安装部署好 gala-gopher 软件,然后再开启 tprofiling 功能。 + +另外,为了能够在前端用户界面使用 tprofiling 的能力,[gala-ops](https://gitee.com/openeuler/gala-docs) 基于开源的 `kafka + logstash + elasticsearch + grafana` 可观测软件搭建了用于演示的 tprofiling 功能的用户界面,用户可以使用 gala-ops 提供的部署工具进行快速部署。 + +#### 运行架构 + +![](./figures/tprofiling-run-arch.png) + +前端软件说明: + +- kafka:一个开源的消息队列中间件,用于接收并存储 gala-gopher 采集的 tprofiling 事件。 +- logstash:一个实时的开源日志收集引擎,用于从 kafka 消费 tprofiling 事件,经过过滤、转换等处理后发送至 elasticsearch 。 +- elasticsearch:一个开放的分布式搜索和分析引擎,用于储存经过处理后的 tprofiling 事件,供 grafana 查询和可视化展示。 +- grafana:一个开源的可视化工具,用于查询并可视化展示采集的 tprofiling 事件。用户最终通过 grafana 提供的用户界面来使用 tprofiling 的功能,分析应用性能问题。 + +#### 部署 tprofiling 探针 + +用户需要先安装好 gala-gopher,具体的安装部署说明可参考 [gala-gopher文档](https://gitee.com/openeuler/gala-gopher#快速开始) 。由于 tprofiling 事件会发送到 kafka 中,因此部署时需要配置好 kafka 的服务地址。 + +安装并运行 gala-gopher 后,使用 gala-gopher 提供的基于 HTTP 的动态配置接口启动 tprofiling 探针。 + +```sh +curl -X PUT http://:9999/tprofiling -d json='{"cmd": {"probe": ["oncpu", "syscall_file", "syscall_net", "syscall_sched", "syscall_lock"]}, "snoopers": {"proc_name": [{"comm": "java"}]}, "state": "running"}' +``` + +配置参数说明: + +- ``:部署 gala-gopher 的节点 IP。 +- `probe`:`cmd` 下的 `probe` 配置项指定了 tprofiling 探针观测的系统事件范围。其中,oncpu、syscall_file、syscall_net、syscall_sched、syscall_lock 分别对应 oncpu 事件、以及 file、net、sched、lock 四类系统调用事件。用户可根据需要只开启部分 tprofiling 事件类型的观测。 +- `proc_name`:`snoopers` 下的 `proc_name` 配置项用于过滤要观测的进程名。另外也可以通过 `proc_id` 配置项来过滤要观测的进程ID,详情参考:[REST 动态配置接口](#rest-动态配置接口)。 + +要关闭 tprofiling 探针,执行如下命令: + +```sh +curl -X PUT http://:9999/tprofiling -d json='{"state": "stopped"}' +``` + +#### 部署前端软件 + +使用 tprofiling 功能的用户界面需要用到的软件包括:kafka、logstash、elasticsearch、grafana。这些软件安装在管理节点,用户可以使用 gala-ops 提供的部署工具进行快速安装部署,参考:[在线部署文档](https://gitee.com/openeuler/gala-docs#%E5%9C%A8%E7%BA%BF%E9%83%A8%E7%BD%B2)。 + +在管理节点上,通过 [在线部署文档](https://gitee.com/openeuler/gala-docs#%E5%9C%A8%E7%BA%BF%E9%83%A8%E7%BD%B2) 获取部署脚本后,执行如下命令一键安装中间件:kafka、logstash、elasticsearch。 + +```sh +sh deploy.sh middleware -K <部署节点管理IP> -E <部署节点管理IP> -A -p +``` + +执行如下命令一键安装 grafana 。 + +```sh +sh deploy.sh grafana -P -E +``` + +#### 使用 + +完成上述部署动作后,即可通过浏览器访问 `http://[部署节点管理IP]:3000` 登录 grafana 来使用 A-Ops,登录用户名、密码默认均为 admin。 + +登录 grafana 界面后,找到名为 `ThreadProfiling` 的 dashboard。 + +![image-20230628155002410](./figures/tprofiling-dashboard.png) + +点击进入 tprofiling 功能的前端界面,接下来就可以探索 tprofiling 的功能了。 + +![image-20230628155249009](./figures/tprofiling-dashboard-detail.png) + +### 使用案例 + +#### 案例1:死锁问题定位 + +![image-20230628095802499](./figures/deadlock.png) + +上图是一个死锁 Demo 进程的线程 profiling 运行结果,从饼图中进程事件执行时间的统计结果可以看到,这段时间内 lock 类型事件(灰色部分)占比比较高。下半部分是整个进程的线程 profiling 展示结果,纵轴展示了进程内不同线程的 profiling 事件的执行序列。其中,线程 `java` 为主线程一直处于阻塞状态,业务线程 `LockThd1` 和 `LockThd2` 在执行一些 oncpu 事件和 file 类事件后会间歇性的同时执行一段长时间的 lock 类事件。将光标悬浮到 lock 类型事件上可以查看事件内容,(如下图所示)它触发了 futex 系统调用事件,执行时间为 60 秒。 + +![image-20230628101056732](./figures/deadlock2.png) + +基于上述观测,我们可以发现业务线程 `LockThd1` 和 `LockThd2` 可能存在异常行为。接下来,我们可以进入线程视图,查看这两个业务线程 `LockThd1` 和 `LockThd2` 的线程 profiling 结果。 + +![image-20230628102138540](./figures/deadlock3.png) + +上图是每个线程的 profiling 结果展示,纵轴展示线程内不同事件类型的执行序列。从图中可以看到,线程 `LockThd1` 和 `LockThd2` 正常情况下会定期执行 oncpu 事件,其中包括执行一些 file 类事件和 lock 类事件。但是在某个时间点(10:17:00附近)它们会同时执行一个长时间的 lock 类型的 futex 事件,而且这段时间内都没有 oncpu 事件发生,说明它们都进入了阻塞状态。futex 是用户态锁实现相关的系统调用,触发 futex 往往意味出现锁竞争,线程可能进入阻塞状态。 + +基于上述分析,线程 `LockThd1` 和 `LockThd2` 很可能是出现了死锁问题。 + +#### 案例2:锁竞争问题定位 + +![image-20230628111119499](./figures/lockcompete1.png) + +上图是一个锁竞争 Demo 进程的线程 profiling 运行结果。从图中可以看到,该进程在这段时间内主要执行了 lock、net、oncpu 三类事件,该进程包括 3 个运行的业务线程。在11:05:45 - 11:06:45 这段时间内,我们发现这 3 个业务线程的事件执行时间都变得很长了,这里面可能存在性能问题。同样,我们进入线程视图,查看每个线程的线程 profiling 结果,同时我们将时间范围缩小到可能有异常的时间点附近。 + +![image-20230628112709827](./figures/lockcompete2.png) + +通过查看每个线程的事件执行序列,可以大致了解每个线程这段时间在执行什么功能。 + +- 线程 CompeteThd1:每隔一段时间触发短时的 oncpu 事件,执行一次计算任务;但是在 11:05:45 时间点附近开始触发长时的 oncpu 事件,说明正在执行耗时的计算任务。 + + ![image-20230628113336435](./figures/lockcompete3.png) + +- 线程 CompeteThd2:每隔一段时间触发短时的 net 类事件,点击事件内容可以看到,该线程正在通过 write 系统调用发送网络消息,且可以看到对应的 tcp 连接信息;同样在 11:05:45 时间点附近开始执行长时的 futex 事件并进入阻塞状态,此时 write 网络事件的执行间隔变长了。 + + ![image-20230628113759887](./figures/lockcompete4.png) + + ![image-20230628114340386](./figures/lockcompete5.png) + +- 线程 tcp-server:tcp 服务器,不断通过 read 系统调用读取客户端发送的请求;同样在 11:05:45 时间点附近开始,read 事件执行时间变长,说明此时正在等待接收网络请求。 + + ![image-20230628114659071](./figures/lockcompete6.png) + +基于上述分析,我们可以发现,每当线程 CompeteThd1 在执行耗时较长的 oncpu 操作时,线程 CompeteThd2 都会调用 futex 系统调用进入阻塞状态,一旦线程 CompeteThd1 完成 oncpu 操作时,线程 CompeteThd2 将获取 cpu 并执行网络 write 操作。因此,大概率是因为线程 CompeteThd1 和线程 CompeteThd2 之间存在锁竞争的问题。而线程 tcp-server 与线程 CompeteThd2 之间存在 tcp 网络通信,由于线程 CompeteThd2 等待锁资源无法发送网络请求,从而导致线程 tcp-server 大部分时间都在等待 read 网络请求。 + +### topics + +#### 支持的系统调用事件 + +选择需要加入观测的系统调用事件的基本原则为: + +1. 选择可能会比较耗时、阻塞的事件(如文件操作、网络操作、锁操作等),这类事件通常涉及对系统资源的访问。 +2. 选择影响线程运行状态的事件。 + +| 事件名/系统调用名 | 描述 | 默认的事件类型 | 扩展的事件内容 | +| ----------------- | ----------------------------------------------------- | -------------- | -------------------------------- | +| read | 读写磁盘文件或网络,线程可能会耗时、阻塞 | file | file.path, sock.conn, func.stack | +| write | 读写磁盘文件或网络,线程可能会耗时、阻塞 | file | file.path, sock.conn, func.stack | +| readv | 读写磁盘文件或网络,线程可能会耗时、阻塞 | file | file.path, sock.conn, func.stack | +| writev | 读写磁盘文件或网络,线程可能会耗时、阻塞 | file | file.path, sock.conn, func.stack | +| preadv | 读写磁盘文件或网络,线程可能会耗时、阻塞 | file | file.path, sock.conn, func.stack | +| pwritev | 读写磁盘文件或网络,线程可能会耗时、阻塞 | file | file.path, sock.conn, func.stack | +| sync | 对文件进行同步刷盘操作,完成前线程会阻塞 | file | func.stack | +| fsync | 对文件进行同步刷盘操作,完成前线程会阻塞 | file | file.path, sock.conn, func.stack | +| fdatasync | 对文件进行同步刷盘操作,完成前线程会阻塞 | file | file.path, sock.conn, func.stack | +| sched_yield | 线程主动让出 CPU 重新进行调度 | sched | func.stack | +| nanosleep | 线程进入睡眠状态 | sched | func.stack | +| clock_nanosleep | 线程进入睡眠状态 | sched | func.stack | +| wait4 | 线程阻塞 | sched | func.stack | +| waitpid | 线程阻塞 | sched | func.stack | +| select | 无事件到达时线程会阻塞等待 | sched | func.stack | +| pselect6 | 无事件到达时线程会阻塞等待 | sched | func.stack | +| poll | 无事件到达时线程会阻塞等待 | sched | func.stack | +| ppoll | 无事件到达时线程会阻塞等待 | sched | func.stack | +| epoll_wait | 无事件到达时线程会阻塞等待 | sched | func.stack | +| sendto | 读写网络时,线程可能会耗时、阻塞 | net | sock.conn, func.stack | +| recvfrom | 读写网络时,线程可能会耗时、阻塞 | net | sock.conn, func.stack | +| sendmsg | 读写网络时,线程可能会耗时、阻塞 | net | sock.conn, func.stack | +| recvmsg | 读写网络时,线程可能会耗时、阻塞 | net | sock.conn, func.stack | +| sendmmsg | 读写网络时,线程可能会耗时、阻塞 | net | sock.conn, func.stack | +| recvmmsg | 读写网络时,线程可能会耗时、阻塞 | net | sock.conn, func.stack | +| futex | 触发 futex 往往意味着出现锁等待,线程可能进入阻塞状态 | lock | futex.op, func.stack | + +#### 聚合事件 + +tprofiling 当前支持的系统性能事件包括两大类:系统调用事件和 oncpu 事件。其中,oncpu 事件以及部分系统调用事件(比如read/write)在特定的应用场景下可能会频繁触发,从而产生大量的系统事件,这会对观测的应用程序性能以及 tprofiling 探针本身的性能造成较大的影响。 + +为了优化性能,tprofiling 将一段时间内(1s)属于同一个线程的具有相同事件名的多个系统事件聚合为一个事件进行上报。因此,一个 tprofiling 事件实际上指的是一个聚合事件,它包含一个或多个相同的系统事件。相比于一个真实的系统事件,一个聚合事件的部分属性的含义有如下变化, + +- `start_time`:事件开始时间,在聚合事件中是指第一个系统事件的开始时间。 +- `end_time`:事件结束时间,在聚合事件中是指(`start_time + duration`)。 +- `duration`:事件执行时间,在聚合事件中是指所有系统事件实际执行时间的累加值。 +- `count`:聚合事件中系统事件的数量,当值为 1 时,聚合事件就等价于一个系统事件。 +- 扩展的事件属性:在聚合事件中是指第一个系统事件的扩展属性。 + +## L7Probe 介绍 + +定位:L7流量观测,覆盖常见的HTTP1.X、PG、MySQL、Redis、Kafka、HTTP2.0、MongoDB、RocketMQ协议,支持加密流观测。 + +场景:覆盖Node、Container、Pod(K8S)三类场景。 + +### 代码框架设计 + +```shell +L7Probe + | --- included // 公共头文件 + +​ | --- connect.h // L7 connect对象定义 + +​ | --- pod.h // pod/container对象定义 + +​ | --- conn_tracker.h // L7协议跟踪对象定义 + + | --- protocol // L7协议解析 + +​ | --- http // HTTP1.X L7 message结构定义及解析 + +​ | --- mysql // mysql L7 message结构定义及解析 + +​ | --- pgsql // pgsql L7 message结构定义及解析 + + | --- bpf // 内核bpf代码 + +​ | --- L7.h // BPF程序解析L7层协议类型 + +​ | --- kern_sock.bpf.c // 内核socket层观测 + +​ | --- libssl.bpf.c // openSSL层观测 + +​ | --- gossl.bpf.c // GO SSL层观测 + +​ | --- cgroup.bpf.c // pod 生命周期观测 + + | --- pod_mng.c // pod/container实例管理(感知pod/container生命周期) + + | --- conn_mng.c // L7 Connect实例管理(处理BPF观测事件,比如Open/Close事件、Stats统计) + + | --- conn_tracker.c // L7 流量跟踪(跟踪BPF观测数据,比如send/write、read/recv等系统事件产生的数据) + + | --- bpf_mng.c // BPF程序生命周期管理(按需、实时open、load、attach、unload BPF程序,包括uprobe BPF程序) + + | --- session_conn.c // 管理jsse Session(记录jsse Session和sock连接的对应关系,上报jsse连接信息) + + | --- L7Probe.c // 探针主程序 +``` + +### 探针输出 + +| metrics_name | table_name | metrics_type | unit | metrics description | +| --------------- | ---------- | ------------ | ---- | ------------------------------------------------------------ | +| tgid | NA | key | NA | Process ID of l7 session. | +| client_ip | NA | key | NA | Client IP address of l7 session. | +| server_ip | NA | key | NA | Server IP address of l7 session.
备注:K8S场景支持Cluster IP转换成Backend IP | +| server_port | NA | key | NA | Server Port of l7 session.
备注:K8S场景支持Cluster Port转换成Backend Port | +| l4_role | NA | key | NA | Role of l4 protocol(TCP Client/Server or UDP) | +| l7_role | NA | key | NA | Role of l7 protocol(Client or Server) | +| protocol | NA | key | NA | Name of l7 protocol(http/http2/mysql...) | +| ssl | NA | label | NA | Indicates whether an SSL-encrypted l7 session is used. | +| bytes_sent | l7_link | gauge | NA | Number of bytes sent by a l7 session. | +| bytes_recv | l7_link | gauge | NA | Number of bytes recv by a l7 session. | +| segs_sent | l7_link | gauge | NA | Number of segs sent by a l7 session. | +| segs_recv | l7_link | gauge | NA | Number of segs recv by a l7 session. | +| throughput_req | l7_rpc | gauge | qps | Request throughput of l7 session. | +| throughput_resp | l7_rpc | gauge | qps | Response throughput of l7 session. | +| req_count | l7_rpc | gauge | NA | Request num of l7 session. | +| resp_count | l7_rpc | gauge | NA | Response num of l7 session. | +| latency_avg | l7_rpc | gauge | ns | L7 session averaged latency. | +| latency | l7_rpc | histogram | ns | L7 session histogram latency. | +| latency_sum | l7_rpc | gauge | ns | L7 session sum latency. | +| err_ratio | l7_rpc | gauge | % | L7 session error rate. | +| err_count | l7_rpc | gauge | NA | L7 session error count. | + +### 动态控制 + +#### 控制观测Pod范围 + +1. REST->gala-gopher。 +2. gala-gopher->L7Probe。 +3. L7Probe 基于Pod获取相关Container。 +4. L7Probe 基于Container获取其 CGroup id(cpuacct_cgrp_id),并写入object模块(API: cgrp_add)。 +5. Socket系统事件上下文中,获取进程所属CGroup(cpuacct_cgrp_id),参考Linux代码(task_cgroup)。 +6. 观测过程中,通过object模块过滤(API: is_cgrp_exist)。 + +#### 控制观测能力 + +1. REST->gala-gopher。 +2. gala-gopher->L7Probe。 +3. L7Probe根据输入参数动态的开启、关闭BPF观测能力(包括吞吐量、时延、Trace、协议类型)。 + +### 观测点 + +#### 内核Socket系统调用 + +TCP相关系统调用 + +// int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); + +// int accept(int sockfd, struct sockaddr \*addr, socklen_t \*addrlen); + +// int accept4(int sockfd, struct sockaddr \*addr, socklen_t \*addrlen, int flags); + +// ssize_t write(int fd, const void *buf, size_t count); + +// ssize_t send(int sockfd, const void *buf, size_t len, int flags); + +// ssize_t read(int fd, void *buf, size_t count); + +// ssize_t recv(int sockfd, void *buf, size_t len, int flags); + +// ssize_t writev(int fd, const struct iovec *iov, int iovcnt); + +// ssize_t readv(int fd, const struct iovec *iov, int iovcnt); + +TCP&UDP相关系统调用 + +// ssize_t sendto(int sockfd, const void \*buf, size_t len, int flags, const struct sockaddr \*dest_addr, socklen_t addrlen); + +// ssize_t recvfrom(int sockfd, void \*buf, size_t len, int flags, struct sockaddr \*src_addr, socklen_t \*addrlen); + +// ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags); + +// ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags); + +// int close(int fd); + +注意点: + +1. read/write、readv/writev 与普通的文件I/O操作会混淆,通过观测内核security_socket_sendmsg函数区分FD是否属于socket操作。 +2. sendto/recvfrom、sendmsg/recvmsg TCP/UDP均会使用,参考下面手册的介绍。 +3. sendmmsg/recvmmsg、sendfile 暂不支持。 + +[sendto manual](https://man7.org/linux/man-pages/man2/send.2.html) :If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET) socket, the arguments dest_addr and addrlen are ignored (and the error EISCONN may be returned when they are not NULL and 0), and the error ENOTCONN is returned when the socket was not actually connected. otherwise, the address of the target is given by dest_addr with addrlen specifying its size. + +sendto 判断dest_addr参数为NULL则为TCP,否则为UDP。 + +[recvfrom manual](https://linux.die.net/man/2/recvfrom):The recvfrom() and recvmsg() calls are used to receive messages from a socket, and may be used to receive data on a socket whether or not it is connection-oriented. + +recvfrom判断src_addr参数为NULL则为TCP,否则为UDP。 + +[sendmsg manual](https://man7.org/linux/man-pages/man3/sendmsg.3p.html):The sendmsg() function shall send a message through a connection-mode or connectionless-mode socket. If the socket is a connectionless-mode socket, the message shall be sent to the address specified by msghdr if no pre-specified peer address has been set. If a peer address has been pre-specified, either themessage shall be sent to the address specified in msghdr (overriding the pre-specified peer address), or the function shall return -1 and set errno to [EISCONN]. If the socket is connection-mode, the destination address in msghdr shall be ignored. + +sendmsg判断msghdr->msg_name参数为NULL则为TCP,否则为UDP。 + +[recvmsg manual](https://man7.org/linux/man-pages/man3/recvmsg.3p.html): The recvmsg() function shall receive a message from a connection-mode or connectionless-mode socket. It is normally used with connectionless-mode sockets because it permits the application to retrieve the source address of received data. + +recvmsg判断msghdr->msg_name参数为NULL则为TCP,否则为UDP。 + +#### libSSL API + +SSL_write + +SSL_read + +#### Go SSL API + +#### JSSE API + +sun/security/ssl/SSLSocketImpl$AppInputStream + +sun/security/ssl/SSLSocketImpl$AppOutputStream + +### JSSE观测方案 + +#### 加载JSSEProbe探针 + +main函数中通过l7_load_jsse_agent加载JSSEProbe探针。 + +轮询观测白名单(g_proc_obj_map_fd)中的进程,若为java进程,则通过jvm_attach将JSSEProbeAgent.jar加载到此观测进程上。加载成功后,该java进程会在指定观测点(参见[JSSE API](#jsse-api))将观测信息输出到jsse-metrics输出文件(/tmp/java-data-\/jsse-metrics.txt)中。 + +#### 处理JSSEProbe消息 + +l7_jsse_msg_handler线程中处理JSSEProbe消息。 + +轮询观测白名单(g_proc_obj_map_fd)中的进程,若该进程有对应的jsse-metrics输出文件,则按行读取此文件并解析、转换、上报jsse读写信息。 + +##### 1. 解析jsse读写信息 + +jsse-metrics.txt的输出格式如下,从中解析出一次jsse请求的pid, sessionId, time, read/write操作, IP, port, payload信息: +`|jsse_msg|662220|Session(1688648699909|TLS_AES_256_GCM_SHA384)|1688648699989|Write|127.0.0.1|58302|This is test message|` + +解析出的原始信息存储于session_data_args_s中。 + +##### 2. 转换jsse读写信息 + +将session_data_args_s中的信息转换为sock_conn和conn_data。 + +转化时需要查询如下两个hash map: + +session_head:记录jsse连接的session Id和sock connection Id的对应关系。若进程id和四元组信息一致,则认为session和sock connection对应。 + +file_conn_head:记录java进程的最后一个sessionId,以备L7probe读jsseProbe输出时,没有从请求开头开始读取,找不到sessionId信息。 + +##### 3. 上报jsse读写信息 + +将sock_conn和conn_data上报到map中。 + +## sliprobe 介绍 + +基于 ebpf 采集并周期性上报容器粒度的 SLI 指标。 + +### 特性 + +- 按照容器粒度采集周期内CPU调度事件的时延总计和统计直方图,关注的事件包括:调度等待,主动睡眠,锁/IO引起的阻塞,调度延迟,长系统调用等 +- 按照容器粒度采集周期内Memory分配事件的时延总计和统计直方图,关注的事件包括:内存回收,换页,内存规整等 +- 按照容器粒度采集周期内BIO层IO操作的时延总计和统计直方图 + +### 使用说明 + +启动命令示例:指定上报周期为15秒,观测容器id为abcd12345678和abcd87654321的两个容器的SLI指标。 + +`curl -X PUT http://localhost:9999/sli -d json='{"params":{"report_period":15}, "snoopers":{"container_id":[{"container_id": "abcd12345678","abcd87654321"}]}, "state":"running"}'` + +### 代码逻辑 + +#### 总体思路 + +1. 用户态接收待观测的容器列表,将容器的cpuacct子系统目录inode记录在ebpf map中,共享给内核态。 + +2. 通过ebpf kprobe/tracepoint跟踪相关内核事件,判断当前进程是否属于待观测范围,记录事件类型,时间戳等信息。每隔一定周期将同一cgroup内进程的SLI指标进行聚合上报。 +3. 用户态接收并打印内核态上报的SLI指标信息。 + +#### SLI指标计算方式 + +##### CPU SLI + +1. **cpu_wait** + + 在sched_stat_wait观测点,获取第二个参数delay的值 + +2. **cpu_sleep** + + 在sched_stat_sleep观测点,获取第二个参数delay的值 + +3. **cpu_iowait** + + 在sched_stat_blocked观测点,判断当前进程in_iowait,则获取第二个参数delay的值 + +4. **cpu_block** + + 在sched_stat_blocked观测点,判断当前进程非in_iowait,则获取第二个参数delay的值 + +5. **cpu_rundelay** + + 在sched_switch观测点,通过第三个参数next获取将被调度进程的run_delay值:next->sched_info.run_delay,记录在task_sched_map中。计算同一进程两次被调度时run_delay的差值 + +6. **cpu_longsys** + + 在sched_switch观测点,通过第三个参数next获取将被调度进程的task结构体,从task结构体中获取上下文切换次数(nvcsw+nivcsw)和用户态执行时间utime。如果同一进程两次被调度时的上下文切换次数和用户态执行时间都不变,则说明在该进程在执行一个较长的系统调用,累积该进程处在内核态的时间 + +##### MEM SLI + +1. **mem_reclaim** + + 计算mem_cgroup_handle_over_high函数返回时间戳和进入时间戳的差值 + + 计算mm_vmscan_memcg_reclaim_end观测点和mm_vmscan_memcg_reclaim_begin观测点时间戳的差值 + +2. **mem_swapin** + + 计算do_swap_page函数返回时间戳和进入时间戳的差值 + +3. **mem_compact** + + 计算try_to_compact_pages函数返回时间戳和进入时间戳的差值 + +##### IO SLI + +1. **bio_latency** + + 计算进入bio_endio函数和触发block_bio_queue观测点的时间戳差值 + + 计算进入bio_endio函数和退出generic_make_request_checks函数的时间戳差值 + +## 使用方法 + +### 外部依赖软件部署 + +![gopher软件架构图](./figures/gopher软件架构图.png) + +如上图所示,绿色部分为gala-gopher的外部依赖组件。gala-gopher会将指标数据metrics输出到prometheus,将元数据metadata、异常事件event输出到kafka,灰色部分的gala-anteater和gala-spider会从prometheus和kafka获取数据。 + +> 说明:安装kafka、prometheus软件包时,需要从官网获取安装包进行部署。 + +### 输出数据 + +- **指标数据metrics** + + Prometheus Server内置了Express Browser UI,用户可以通过PromQL查询语句查询指标数据内容。详细教程参见官方文档:[Using the expression browser](https://prometheus.io/docs/prometheus/latest/getting_started/#using-the-expression-browser)。示例如下: + + 指定指标名称为`gala_gopher_tcp_link_rcv_rtt`,UI显示的指标数据为: + + `gala_gopher_tcp_link_rcv_rtt{client_ip="x.x.x.165",client_port="1234",hostname="openEuler",instance="x.x.x.172:8888",job="prometheus",machine_id="1fd3774xx",protocol="2",role="0",server_ip="x.x.x.172",server_port="3742",tgid="1516"} 1` + +- **元数据metadata** + + 可以直接从kafka消费topic为`gala_gopher_metadata`的数据来看。示例如下: + + ```bash + # 输入请求 + ./bin/kafka-console-consumer.sh --bootstrap-server x.x.x.165:9092 --topic gala_gopher_metadata + # 输出数据 + {"timestamp": 1655888408000, "meta_name": "thread", "entity_name": "thread", "version": "1.0.0", "keys": ["machine_id", "pid"], "labels": ["hostname", "tgid", "comm", "major", "minor"], "metrics": ["fork_count", "task_io_wait_time_us", "task_io_count", "task_io_time_us", "task_hang_count"]} + ``` + +- **异常事件event** + + 可以直接从kafka消费topic为`gala_gopher_event`的数据来看。示例如下: + + ```bash + # 输入请求 + ./bin/kafka-console-consumer.sh --bootstrap-server x.x.x.165:9092 --topic gala_gopher_event + # 输出数据 + {"timestamp": 1655888408000, "meta_name": "thread", "entity_name": "thread", "version": "1.0.0", "keys": ["machine_id", "pid"], "labels": ["hostname", "tgid", "comm", "major", "minor"], "metrics": ["fork_count", "task_io_wait_time_us", "task_io_count", "task_io_time_us", "task_hang_count"]} + ``` diff --git a/docs/en/25.03/Server/Maintenance/Gala/using-gala-spider.md b/docs/en/25.03/Server/Maintenance/Gala/using-gala-spider.md new file mode 100644 index 0000000000000000000000000000000000000000..4c58a3c1acda08cd5e108e788114265bac71176c --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/Gala/using-gala-spider.md @@ -0,0 +1,527 @@ +# gala-spider使用手册 + +本文档主要介绍如何部署和使用gala-spider和gala-inference。 + +## gala-spider + +gala-spider 提供 OS 级别的拓扑图绘制功能,它将定期获取 gala-gopher (一个 OS 层面的数据采集软件)在某个时间点采集的所有观测对象的数据,并计算它们之间的拓扑关系,最终将生成的拓扑图保存到图数据库 arangodb 中。 + +### 安装 + +挂载 yum 源: + +```basic +[oe-2309] # openEuler 2309 官方发布源 +name=oe2309 +baseurl=http://119.3.219.20:82/openEuler:/23.09/standard_x86_64 +enabled=1 +gpgcheck=0 +priority=1 + +[oe-2309:Epol] # openEuler 2309:Epol 官方发布源 +name=oe2309_epol +baseurl=http://119.3.219.20:82/openEuler:/23.09:/Epol/standard_x86_64/ +enabled=1 +gpgcheck=0 +priority=1 +``` + +安装 gala-spider: + +```sh +# yum install gala-spider +``` + +### 配置 + +#### 配置文件说明 + +gala-spider 配置文件为 `/etc/gala-spider/gala-spider.yaml` ,该文件配置项说明如下。 + +- global:全局配置信息。 + - data_source:指定观测指标采集的数据库,当前只支持 prometheus。 + - data_agent:指定观测指标采集代理,当前只支持 gala_gopher。 +- spider:spider配置信息。 + - log_conf:日志配置信息。 + - log_path:日志文件路径。 + - log_level:日志打印级别,值包括 DEBUG/INFO/WARNING/ERROR/CRITICAL 。 + - max_size:日志文件大小,单位为兆字节(MB)。 + - backup_count:日志备份文件数量。 +- storage:拓扑图存储服务的配置信息。 + - period:存储周期,单位为秒,表示每隔多少秒存储一次拓扑图。 + - database:存储的图数据库,当前只支持 arangodb。 + - db_conf:图数据库的配置信息。 + - url:图数据库的服务器地址。 + - db_name:拓扑图存储的数据库名称。 +- kafka:kafka配置信息。 + - server:kafka服务器地址。 + - metadata_topic:观测对象元数据消息的topic名称。 + - metadata_group_id:观测对象元数据消息的消费者组ID。 +- prometheus:prometheus数据库配置信息。 + - base_url:prometheus服务器地址。 + - instant_api:单个时间点采集API。 + - range_api:区间采集API。 + - step:采集时间步长,用于区间采集API。 + +#### 配置文件示例 + +```yaml +global: + data_source: "prometheus" + data_agent: "gala_gopher" + +prometheus: + base_url: "http://localhost:9090/" + instant_api: "/api/v1/query" + range_api: "/api/v1/query_range" + step: 1 + +spider: + log_conf: + log_path: "/var/log/gala-spider/spider.log" + # log level: DEBUG/INFO/WARNING/ERROR/CRITICAL + log_level: INFO + # unit: MB + max_size: 10 + backup_count: 10 + +storage: + # unit: second + period: 60 + database: arangodb + db_conf: + url: "http://localhost:8529" + db_name: "spider" + +kafka: + server: "localhost:9092" + metadata_topic: "gala_gopher_metadata" + metadata_group_id: "metadata-spider" +``` + +### 启动 + +1. 通过命令启动。 + + ```sh + # spider-storage + ``` + +2. 通过 systemd 服务启动。 + + ```sh + # systemctl start gala-spider + ``` + +### 使用方法 + +#### 外部依赖软件部署 + +gala-spider 运行时需要依赖多个外部软件进行交互。因此,在启动 gala-spider 之前,用户需要将gala-spider依赖的软件部署完成。下图为 gala-spider 项目的软件依赖图。 + +![gala-spider软件架构图](./figures/gala-spider软件架构图.png) + +其中,右侧虚线框内为 gala-spider 项目的 2 个功能组件,绿色部分为 gala-spider 项目直接依赖的外部组件,灰色部分为 gala-spider 项目间接依赖的外部组件。 + +- **spider-storage**:gala-spider 核心组件,提供拓扑图存储功能。 + 1. 从 kafka 中获取观测对象的元数据信息。 + 2. 从 Prometheus 中获取所有的观测实例信息。 + 3. 将生成的拓扑图存储到图数据库 arangodb 中。 +- **gala-inference**:gala-spider 核心组件,提供根因定位功能。它通过订阅 kafka 的异常 KPI 事件触发异常 KPI 的根因定位流程,并基于 arangodb 获取的拓扑图来构建故障传播图,最终将根因定位的结果输出到 kafka 中。 +- **prometheus**:时序数据库,gala-gopher 组件采集的观测指标数据会上报到 prometheus,再由 gala-spider 做进一步处理。 +- **kafka**:消息中间件,用于存储 gala-gopher 上报的观测对象元数据信息,异常检测组件上报的异常事件,以及 cause-inference 组件上报的根因定位结果。 +- **arangodb**:图数据库,用于存储 spider-storage 生成的拓扑图。 +- **gala-gopher**:数据采集组件,请提前部署gala-gopher。 +- **arangodb-ui**:arangodb 提供的 UI 界面,可用于查询拓扑图。 + +gala-spider 项目中的 2 个功能组件会作为独立的软件包分别发布。 + +​**spider-storage** 组件对应本节中的 gala-spider 软件包。 + +​**gala-inference** 组件对应 gala-inference 软件包。 + +gala-gopher软件的部署参见[gala-gopher使用手册](./using-gala-gopher.md),此处只介绍 arangodb 的部署。 + +当前使用的 arangodb 版本是 3.8.7 ,该版本对运行环境有如下要求: + +- 只支持 x86 系统 +- gcc10 以上 + +arangodb 官方部署文档参见:[arangodb部署](https://www.arangodb.com/docs/3.9/deployment.html) 。 + +arangodb 基于 rpm 的部署流程如下: + +1. 配置 yum 源。 + + ```basic + [oe-2309] # openEuler 2309 官方发布源 + name=oe2309 + baseurl=http://119.3.219.20:82/openEuler:/23.09/standard_x86_64 + enabled=1 + gpgcheck=0 + priority=1 + + [oe-2309:Epol] # openEuler 2309:Epol 官方发布源 + name=oe2309_epol + baseurl=http://119.3.219.20:82/openEuler:/23.09:/Epol/standard_x86_64/ + enabled=1 + gpgcheck=0 + priority=1 + ``` + +2. 安装 arangodb3。 + + ```sh + # yum install arangodb3 + ``` + +3. 配置修改。 + + arangodb3 服务器的配置文件路径为 `/etc/arangodb3/arangod.conf` ,需要修改如下的配置信息: + + - endpoint:配置 arangodb3 的服务器地址 + - authentication:访问 arangodb3 服务器是否需要进行身份认证,当前 gala-spider 还不支持身份认证,故此处将authentication设置为 false。 + + 示例配置如下: + + ```yaml + [server] + endpoint = tcp://0.0.0.0:8529 + authentication = false + ``` + +4. 启动 arangodb3。 + + ```sh + # systemctl start arangodb3 + ``` + +#### gala-spider配置项修改 + +依赖软件启动后,需要修改 gala-spider 配置文件的部分配置项内容。示例如下: + +配置 kafka 服务器地址: + +```yaml +kafka: + server: "localhost:9092" +``` + +配置 prometheus 服务器地址: + +```yaml +prometheus: + base_url: "http://localhost:9090/" +``` + +配置 arangodb 服务器地址: + +```yaml +storage: + db_conf: + url: "http://localhost:8529" +``` + +#### 启动服务 + +运行 `systemctl start gala-spider` 。查看启动状态可执行 `systemctl status gala-spider` ,输出如下信息说明启动成功。 + +```sh +[root@openEuler ~]# systemctl status gala-spider +● gala-spider.service - a-ops gala spider service + Loaded: loaded (/usr/lib/systemd/system/gala-spider.service; enabled; vendor preset: disabled) + Active: active (running) since Tue 2022-08-30 17:28:38 CST; 1 day 22h ago + Main PID: 2263793 (spider-storage) + Tasks: 3 (limit: 98900) + Memory: 44.2M + CGroup: /system.slice/gala-spider.service + └─2263793 /usr/bin/python3 /usr/bin/spider-storage +``` + +#### 输出示例 + +用户可以通过 arangodb 提供的 UI 界面来查询 gala-spider 输出的拓扑图。使用流程如下: + +1. 在浏览器输入 arangodb 服务器地址,如: ,进入 arangodb 的 UI 界面。 + +2. 界面右上角切换至 `spider` 数据库。 + +3. 在 `Collections` 面板可以看到在不同时间段存储的观测对象实例的集合、拓扑关系的集合,如下图所示: + + ![spider拓扑关系图](./figures/spider拓扑关系图.png) + +4. 可进一步根据 arangodb 提供的 AQL 查询语句查询存储的拓扑关系图,详细教程参见官方文档: [aql文档](https://www.arangodb.com/docs/3.8/aql/)。 + +## gala-inference + +gala-inference 提供异常 KPI 根因定位能力,它将基于异常检测的结果和拓扑图作为输入,根因定位的结果作为输出,输出到 kafka 中。gala-inference 组件在 gala-spider 项目下进行归档。 + +### 安装 + +挂载 yum 源: + +```basic +[oe-2309] # openEuler 2309 官方发布源 +name=oe2309 +baseurl=http://119.3.219.20:82/openEuler:/23.09/standard_x86_64 +enabled=1 +gpgcheck=0 +priority=1 + +[oe-2309:Epol] # openEuler 2309:Epol 官方发布源 +name=oe2309_epol +baseurl=http://119.3.219.20:82/openEuler:/23.09:/Epol/standard_x86_64/ +enabled=1 +gpgcheck=0 +priority=1 +``` + +安装 gala-inference: + +```sh +# yum install gala-inference +``` + +### 配置 + +#### 配置文件说明 + +gala-inference 配置文件 `/etc/gala-inference/gala-inference.yaml` 配置项说明如下。 + +- inference:根因定位算法的配置信息。 + - tolerated_bias:异常时间点的拓扑图查询所容忍的时间偏移,单位为秒。 + - topo_depth:拓扑图查询的最大深度。 + - root_topk:根因定位结果输出前 K 个根因指标。 + - infer_policy:根因推导策略,包括 dfs 和 rw 。 + - sample_duration:指标的历史数据的采样周期,单位为秒。 + - evt_valid_duration:根因定位时,有效的系统异常指标事件周期,单位为秒。 + - evt_aging_duration:根因定位时,系统异常指标事件的老化周期,单位为秒。 +- kafka:kafka配置信息。 + - server:kafka服务器地址。 + - metadata_topic:观测对象元数据消息的配置信息。 + - topic_id:观测对象元数据消息的topic名称。 + - group_id:观测对象元数据消息的消费者组ID。 + - abnormal_kpi_topic:异常 KPI 事件消息的配置信息。 + - topic_id:异常 KPI 事件消息的topic名称。 + - group_id:异常 KPI 事件消息的消费者组ID。 + - abnormal_metric_topic:系统异常指标事件消息的配置信息。 + - topic_id:系统异常指标事件消息的topic名称。 + - group_id:系统异常指标事件消息的消费者组ID。 + - consumer_to:消费系统异常指标事件消息的超时时间,单位为秒。 + - inference_topic:根因定位结果输出事件消息的配置信息。 + - topic_id:根因定位结果输出事件消息的topic名称。 +- arangodb:arangodb图数据库的配置信息,用于查询根因定位所需要的拓扑子图。 + - url:图数据库的服务器地址。 + - db_name:拓扑图存储的数据库名称。 +- log_conf:日志配置信息。 + - log_path:日志文件路径。 + - log_level:日志打印级别,值包括 DEBUG/INFO/WARNING/ERROR/CRITICAL。 + - max_size:日志文件大小,单位为兆字节(MB)。 + - backup_count:日志备份文件数量。 +- prometheus:prometheus数据库配置信息,用于获取指标的历史时序数据。 + - base_url:prometheus服务器地址。 + - range_api:区间采集API。 + - step:采集时间步长,用于区间采集API。 + +#### 配置文件示例 + +```yaml +inference: + # 异常时间点的拓扑图查询所容忍的时间偏移,单位:秒 + tolerated_bias: 120 + topo_depth: 10 + root_topk: 3 + infer_policy: "dfs" + # 单位: 秒 + sample_duration: 600 + # 根因定位时,有效的异常指标事件周期,单位:秒 + evt_valid_duration: 120 + # 异常指标事件的老化周期,单位:秒 + evt_aging_duration: 600 + +kafka: + server: "localhost:9092" + metadata_topic: + topic_id: "gala_gopher_metadata" + group_id: "metadata-inference" + abnormal_kpi_topic: + topic_id: "gala_anteater_hybrid_model" + group_id: "abn-kpi-inference" + abnormal_metric_topic: + topic_id: "gala_anteater_metric" + group_id: "abn-metric-inference" + consumer_to: 1 + inference_topic: + topic_id: "gala_cause_inference" + +arangodb: + url: "http://localhost:8529" + db_name: "spider" + +log: + log_path: "/var/log/gala-inference/inference.log" + # log level: DEBUG/INFO/WARNING/ERROR/CRITICAL + log_level: INFO + # unit: MB + max_size: 10 + backup_count: 10 + +prometheus: + base_url: "http://localhost:9090/" + range_api: "/api/v1/query_range" + step: 5 +``` + +### 启动 + +1. 通过命令启动。 + + ```sh + # gala-inference + ``` + +2. 通过 systemd 服务启动。 + + ```sh + # systemctl start gala-inference + ``` + +### 使用方法 + +#### 依赖软件部署 + +gala-inference 的运行依赖和 gala-spider一样,请参见[外部依赖软件部署](#外部依赖软件部署)。此外,gala-inference 还间接依赖 [gala-spider](#gala-spider) 和 [gala-anteater](./using-gala-anteater.md) 软件的运行,请提前部署gala-spider和gala-anteater软件。 + +#### 配置项修改 + +修改 gala-inference 的配置文件中部分配置项。示例如下: + +配置 kafka 服务器地址: + +```yaml +kafka: + server: "localhost:9092" +``` + +配置 prometheus 服务器地址: + +```yaml +prometheus: + base_url: "http://localhost:9090/" +``` + +配置 arangodb 服务器地址: + +```yaml +arangodb: + url: "http://localhost:8529" +``` + +#### 启动服务 + +直接运行 `systemctl start gala-inference` 即可。可通过执行 `systemctl status gala-inference` 查看启动状态,如下打印表示启动成功。 + +```sh +[root@openEuler ~]# systemctl status gala-inference +● gala-inference.service - a-ops gala inference service + Loaded: loaded (/usr/lib/systemd/system/gala-inference.service; enabled; vendor preset: disabled) + Active: active (running) since Tue 2022-08-30 17:55:33 CST; 1 day 22h ago + Main PID: 2445875 (gala-inference) + Tasks: 10 (limit: 98900) + Memory: 48.7M + CGroup: /system.slice/gala-inference.service + └─2445875 /usr/bin/python3 /usr/bin/gala-inference +``` + +#### 输出示例 + +当异常检测模块 gala-anteater 检测到 KPI 异常后,会将对应的异常 KPI 事件输出到 kafka 中,gala-inference 会一直监测该异常 KPI 事件的消息,如果收到异常 KPI 事件的消息,就会触发根因定位。根因定位会将定位结果输出到 kafka 中,用户可以在 kafka 服务器中查看根因定位的输出结果,基本步骤如下: + +1. 若通过源码安装 kafka ,需要进入 kafka 的安装目录下。 + + ```sh + cd /root/kafka_2.13-2.8.0 + ``` + +2. 执行消费 topic 的命令获取根因定位的输出结果。 + + ```sh + ./bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic gala_cause_inference + ``` + + 输出示例如下: + + ```json + { + "Timestamp": 1661853360000, + "event_id": "1661853360000_1fd37742xxxx_sli_12154_19", + "Attributes": { + "event_id": "1661853360000_1fd37742xxxx_sli_12154_19" + }, + "Resource": { + "abnormal_kpi": { + "metric_id": "gala_gopher_sli_rtt_nsec", + "entity_id": "1fd37742xxxx_sli_12154_19", + "timestamp": 1661853360000, + "metric_labels": { + "machine_id": "1fd37742xxxx", + "tgid": "12154", + "conn_fd": "19" + } + }, + "cause_metrics": [ + { + "metric_id": "gala_gopher_proc_write_bytes", + "entity_id": "1fd37742xxxx_proc_12154", + "metric_labels": { + "__name__": "gala_gopher_proc_write_bytes", + "cmdline": "/opt/redis/redis-server x.x.x.172:3742", + "comm": "redis-server", + "container_id": "5a10635e2c43", + "hostname": "openEuler", + "instance": "x.x.x.172:8888", + "job": "prometheus", + "machine_id": "1fd37742xxxx", + "pgid": "12154", + "ppid": "12126", + "tgid": "12154" + }, + "timestamp": 1661853360000, + "path": [ + { + "metric_id": "gala_gopher_proc_write_bytes", + "entity_id": "1fd37742xxxx_proc_12154", + "metric_labels": { + "__name__": "gala_gopher_proc_write_bytes", + "cmdline": "/opt/redis/redis-server x.x.x.172:3742", + "comm": "redis-server", + "container_id": "5a10635e2c43", + "hostname": "openEuler", + "instance": "x.x.x.172:8888", + "job": "prometheus", + "machine_id": "1fd37742xxxx", + "pgid": "12154", + "ppid": "12126", + "tgid": "12154" + }, + "timestamp": 1661853360000 + }, + { + "metric_id": "gala_gopher_sli_rtt_nsec", + "entity_id": "1fd37742xxxx_sli_12154_19", + "metric_labels": { + "machine_id": "1fd37742xxxx", + "tgid": "12154", + "conn_fd": "19" + }, + "timestamp": 1661853360000 + } + ] + } + ] + }, + "SeverityText": "WARN", + "SeverityNumber": 13, + "Body": "A cause inferring event for an abnormal event" + } + ``` diff --git a/docs/en/25.03/Server/Maintenance/KernelLiveUpgrade/KernelLiveUpgrade.md b/docs/en/25.03/Server/Maintenance/KernelLiveUpgrade/KernelLiveUpgrade.md new file mode 100644 index 0000000000000000000000000000000000000000..8a3119e3c5d9fba383940e429f01ec47e5f9990e --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/KernelLiveUpgrade/KernelLiveUpgrade.md @@ -0,0 +1,14 @@ +# 内核热升级用户指南 + +本文档介绍openEuler系统内核热升级特性的安装部署和使用方法,openEuler的内核热替换特性通过快速重启内核和程序热迁移实现,我们提供了一个用户态工具以自动化这一过程。 + +本文档适用于使用openEuler系统并希望了解和使用内核热升级的社区开发者、开源爱好者以及相关合作伙伴。使用人员需要具备基础的Linux操作系统知识。 + +## 使用场景 + +内核热升级的目标,是实现在秒级的端到端时延下,实现进程运行现场的保存和恢复。 + +使用场景通常符合以下两个条件: + +1. 内核由于漏洞修复,版本更新等原因,需要重新启动 +2. 运行在内核之上的业务能够在内核重启后快速恢复状态 diff --git a/docs/en/25.03/Server/Maintenance/KernelLiveUpgrade/_menu.md b/docs/en/25.03/Server/Maintenance/KernelLiveUpgrade/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..3cb37707922b12957a5d782a23288e4839214e81 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/KernelLiveUpgrade/_menu.md @@ -0,0 +1,12 @@ +--- +label: '内核热升级指南' +ismanual: 'Y' +description: '使用用户态自动化工具快速重启内核和程序热迁移实现内核热替换特性' +children: + - label: '安装与部署' + href: './installation-and-deployment.md' + - label: '使用方法' + href: './how-to-run.md' + - label: '常见问题与解决方法' + href: './common-problems-and-solutions.md' +--- diff --git a/docs/en/25.03/Server/Maintenance/KernelLiveUpgrade/common-problems-and-solutions.md b/docs/en/25.03/Server/Maintenance/KernelLiveUpgrade/common-problems-and-solutions.md new file mode 100644 index 0000000000000000000000000000000000000000..c51c7cf0a0565124e5b8ece9c8469b6ac31dcb18 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/KernelLiveUpgrade/common-problems-and-solutions.md @@ -0,0 +1,31 @@ +# 常见问题与解决方法 + +## **问题1:执行nvwa update后未升级** + +原因:保留现场或者内核替换过程中出现错误。 + +解决方法:查看日志,找出错误原因。 + +## **问题2:开启加速特性后,nvwa执行命令失败** + +原因:nvwa提供了诸多加速特性,包括quick kexec,pin memory,cpu park等等。这些特性都涉及到cmdline的配置和内存的分配,在选取内存时,通过cat /proc/iomemory确保选取的内存没有与其他程序冲突。 + +解决方法:必要时,通过dmesg查看使能特性后是否存在错误日志。 + +## **问题3:热升级后,相关现场未被恢复** + +原因:首先检查nvwa服务是否运行,运行情况下,可能存在两种情况:一种是服务恢复失败,一种是进程恢复失败。 + +解决方法:通过service nvwa status查看nvwa的日志,如果是服务启动失败,首先确认是否使能了该服务,再通过systemd查看对应服务的日志。进一步的日志,去criu_dir指定的路径对应命名的进程/服务文件夹中。其中dump.log为保存现场产生的日志,restore.log为恢复现场产生的。 + +## **问题4:恢复失败,日志显示Can't fork for 948: File exists** + +原因:内核热升级工具在恢复程序过程中,发现程序的pid已经被占用。 + +解决方法:当前内核没有提供保留pid的机制,相关策略正在开发,预计会在将来的内核版本中解决这一限制,当前仅能手动重启相关进程。 + +## **问题5:使用nvwa去保存和恢复简单程序(hello world),显示失败或者程序未在执行** + +原因: criu使用存在诸多限制。 + +解决办法:查看nvwa的日志,如果显示是criu相关的错误,去相应的目录下检查dump.log或者restore.log,criu相关使用限制,可以参考[criu社区wiki](https://criu.org/What_cannot_be_checkpointed)。 diff --git a/docs/en/25.03/Server/Maintenance/KernelLiveUpgrade/how-to-run.md b/docs/en/25.03/Server/Maintenance/KernelLiveUpgrade/how-to-run.md new file mode 100644 index 0000000000000000000000000000000000000000..2188bf085a41acf2522f99da1fdb1476ec297396 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/KernelLiveUpgrade/how-to-run.md @@ -0,0 +1,112 @@ +# 使用方法 + + + +- [命令用法](#命令用法) +- [使用限制](#使用限制) +- [加速特性说明及使用](#加速特性说明及使用) +- [产生的日志信息](#产生的日志信息) + + + +## 命令用法 + +- nvwa help + + 打印帮助信息,打印的信息如下: + + ```shell + NAME: + nvwa - a tool used for openEuler kernel update. + + USAGE: + nvwa [global options] command [command options] [arguments...] + + VERSION: + 0.1 + + COMMANDS: + update specify kernel version for nvwa to update + init init nvwa running environment + help, h Shows a list of commands or help for one command + + GLOBAL OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + ``` + + 需要注意的是,由于当前参数解析的限制,暂不支持nvwa --help, nvwa --version之类的GLOBAL OPTIONS用法,后续版本会修复该问题。 + 如需查看系统已经安装的nvwa版本,可通过`rpm -qa nvwa`查看。 + +- nvwa update \ + + 热升级到内核某一版本,nvwa会去/boot目录下寻找内核镜像和ramfs,kernel的命名格式需为vmlinuz-\, rootfs命名格式需为initramfs-\.img + + 需要注意的是,升级过程有可能会失败,如果失败,部分被dump的进程或者服务,将停止运行。 + + 当前版本的\可以通过`uname -r`获得,参照当前\的格式,可以在/boot目录下找到当前系统已有的所有版本。 + +- nvwa init + + 清除nvwa产生的现场信息以及对systemd的配置修改,用于nvwa执行前或者执行失败后,对现场进行清理。 + +## 使用限制 + +1. 对于需要通过nvwa保存的service,其配置中需要设置标准输出(StandardOutput)和错误输出(StandardError),以redis为例: + + ```shell + [Unit] + Description=Redis persistent key-value database + After=network.target + [Service] + ExecStart=/usr/bin/redis-server /etc/redis.conf --supervised systemd + Type=notify + User=redis + Group=redis + RuntimeDirectory=redis + RuntimeDirectoryMode=0755 + StandardOutput=file:/root/log1.log + StandardError=file:/root/log2.log + [Install] + WantedBy=multi-user.target + ``` + +2. 使用加速特性需要修改cmdline以及分配合适的内存,参见下方[加速特性说明及使用](#加速特性说明及使用)。 + +3. 运行过程中需要关闭SELINUX + + 理论上,仅需要在执行nvwa update之后和系统重启nvwa恢复现场这段时间前需要关闭。稳妥起见,建议全程关闭SELINUX。 + +## 加速特性说明及使用 + +1. cpu park(加速内核重启过程) + + cpu park,是在使用kexec过程,使cpu进入一种忙等的状态,更快的响应主核发送的中断请求,减少状态的变化。 + + 使用cpu park,需要在cmdline中加入"cpuparkmem=0x200000000",其中0x200000000是一段未被其他程序使用的内存起始地址,cpuparkmem将占用从该地址开始,size为1M左右的内存空间。 + + 需要注意的是,在内存允许的情况下,此处的地址选择,建议范围在4G(0x100000000)之后,前4G通常被系统各组件预留,容易冲突。 + +2. quick kexec(加速内核启动过程) + + quick kexec,是对kexec加载镜像过程中的一种加速。 + + 使用quick kexec,需要在配置文件中使能相关选项,更多信息参考\<<[安装与部署-配置介绍](./installation-and-deployment.md#配置介绍)>>。 + +3. pin_memory(加速现场保存恢复过程) + + pin memory,是对criu进行现场保存恢复过程中的一种加速。 + + 使用pin memory,需要在配置文件中使能相关选项,更多信息参考\<<[安装与部署-配置介绍](./installation-and-deployment.md#配置介绍)>>。 + +## 产生的日志信息 + +内核热升级工具产生的日志分为两部分: + +- 运行过程产生的日志: + + 通过`service nvwa status`查看。 + +- 保留现场过程中产生的日志: + + 日志位于criu_dir指定的路径对应命名的进程/服务文件夹中。 diff --git a/docs/en/25.03/Server/Maintenance/KernelLiveUpgrade/installation-and-deployment.md b/docs/en/25.03/Server/Maintenance/KernelLiveUpgrade/installation-and-deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..204c78d29709c7a1158ac8f08ddb38b19993d024 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/KernelLiveUpgrade/installation-and-deployment.md @@ -0,0 +1,180 @@ +# 安装与部署 + +本章介绍如何安装和部署内核热升级工具。 + + + +- [安装与部署](#安装与部署) + - [软硬件要求](#软硬件要求) + - [硬件要求](#硬件要求) + - [软件要求](#软件要求) + - [环境准备](#环境准备) + - [安装内核热升级工具](#安装内核热升级工具) + - [部署内核热升级工具](#部署内核热升级工具) + - [配置介绍](#配置介绍) + - [使能内核热升级工具](#使能内核热升级工具) + + + +## 软硬件要求 + +### 硬件要求 + +- 当前仅支持arm64架构 + +### 软件要求 + +- 操作系统:openEuler 22.03 + +## 环境准备 + +- 安装openEuler系统,安装方法参考 《[安装指南](../../InstallationUpgrade/Installation/installation.md)》 + +- 安装内核热升级工具需要使用root权限 + +## 安装内核热升级工具 + +本章介绍内核热升级工具的安装方法 + +安装内核热升级工具的操作步骤如下: + +1. 挂载openEuler的iso文件 + + ```sh + # mount openEuler-22.03-LTS-everything-aarch64-dvd.iso /mnt + ``` + +2. 配置本地yum源 + + ```sh + # vim /etc/yum.repos.d/local.repo + ``` + + 配置内容如下所示: + + ```sh + [local] + name=local + baseurl=file:///mnt + gpgcheck=1 + enabled=1 + ``` + +3. 将RPM数字签名的GPG公钥导入系统 + + ```sh + # rpm --import /mnt/RPM-GPG-KEY-openEuler + ``` + +4. 安装内核热升级工具 + + ```sh + # yum install nvwa -y + ``` + +5. 验证是否安装成功。命令和回显如下表示安装成功 + + ```sh + # rpm -qa | grep nvwa + nvwa-xxx + ``` + +## 部署内核热升级工具 + +本章介绍内核热升级工具的配置部署: + +### 配置介绍 + +内核热升级工具的配置文件位于/etc/nvwa,配置文件包括: + +- nvwa-restore.yaml + + 该配置文件用于指导内核热升级工具在内核热升级过程中如何保存和恢复现场,具体配置如下: + + - pids + + pids用于指明nvwa热升级过程中需要保留和恢复的进程,此处的进程通过进程号(pid)进行标识,需要注意的是,nvwa管理的进程在nvwa服务启动后,会被自动恢复。 + + - services + + services用于指明nvwa热升级过程中需要保留和恢复的服务。与pids的区别在于,内核热升级工具可以直接保存和恢复进程的状态,对于服务,内核热升级工具则需要依赖systemd进行相关操作。此处的服务名称,应该使用systemd中使用的服务名称。需要注意的是,对于nvwa管理的服务,是否要在nvwa启动时自动恢复,取决于systemd中有没有使能该服务,且当前支持的服务类型只有notify和oneshot。 + + - restore_net + + restore_net用于指明是否需要内核热升级工具保存和恢复网络配置,如果网络配置有误,有可能导致恢复后网络不可用,默认关闭。 + + - enable_quick_kexec + + enable_quick_kexec用于指明是否需要使能quick kexec特性,quick kexec是nvwa社区推出的,加速内核重启过程的一个特性。使用该特性,需要在cmdline中,加入"quickkexec=128M"。128指分配给quick kexec特性的内存大小,该内存将用于在升级过程中加载kernel和initramfs,因此大小需要大于升级过程中涉及到的kernel,initramfs大小之和。该特性默认关闭。 + + - enable_pin_memory + + enable_pin_memory用于指明是否需要使能pin memory特性,pin memory是nvwa社区推出的,加速进程保存恢复过程的一个特性。pin_memory特性暂不支持多进程应用备份恢复,使用该特性,需要在cmdline中,加入"max_pin_pid_num=10 redirect_space_size=2M pinmemory=200M@0x640000000"。 + + 其中,max_pin_pid_num代表支持pin memory恢复的最大进程数目,redirect_space_size代表pin memory过程中重定向物理页所需要的预留内存空间,建议配置为pin memory总预留内存的1/100,pinmemory指明这段内存的起点和大小。从0x640000000开始的200M空间,是pin memory使用的全部内存空间,这段空间不应该被其他程序使用。 + +- nvwa-restore.yaml的配置示例 + +```sh +pids: + - 14109 +services: + - redis +restore_net: false +enable_quick_kexec: true +enable_pin_memory: true +``` + +- nvwa-server.yaml + + 该文件包含了内核热升级工具运行过程中,需要使用到的配置信息,具体如下: + + - criu_dir + + 用于指明内核热升级工具在保存现场过程中,存储产生的信息文件夹路径。需要注意的是,这些信息可能会占用较大的磁盘空间。 + + - criu_exe + + 用于指明内核热升级工具使用的criu可执行文件路径,除非是对criu进行调测,一般不建议修改。 + + - kexec_exe + + 用于指明内核热升级工具使用的kexec可执行文件路径,除非是对kexec进行调测,一般不建议修改。 + + - systemd_etc + + 用于指明覆盖systemd配置过程中,使用到的文件夹路径。该路径由systemd决定,一般不需要修改。 + + - log_dir + + 存放内核热升级工具产生的log信息,log模块当前未启用。内核热升级工具日志信息的查看,参考其他章节\<\<使用方法>> + +- nvwa-server.yaml的配置示例 + +```sh +criu_dir: /var/nvwa/running/ +criu_exe: /usr/sbin/criu +kexec_exe: /usr/sbin/kexec +systemd_etc: /etc/systemd/system/ +log_dir: /etc/nvwa/log/ +``` + +## 使能内核热升级工具 + +内核热升级工具的运行依赖配置文件,配置文件修改后应该重新运行内核热升级工具程序。 + +安装成功后,可以通过systemd的相关命令来操作内核热升级工具 + +- 使能nvwa + + systemctl enable nvwa + +- 启动nvwa + + systemctl start nvwa + +- 查看nvwa日志 + + service nvwa status + +- 更多用法参考systemd用法 diff --git a/docs/en/25.03/Server/Maintenance/SysCare/SysCare_introduction.md b/docs/en/25.03/Server/Maintenance/SysCare/SysCare_introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..14f73580cdc5eb85873dd880539726b163c542f9 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/SysCare/SysCare_introduction.md @@ -0,0 +1,23 @@ +# 认识SysCare + +## 简介 + +SysCare是一个操作系统热补丁服务,统一了操作系统内核态、用户态热补丁服务。为操作系统提供在线的热补丁修复能力,可以自动化、无感知地在线修复内核、用户态服务、动态库等系统基础组件bug和漏洞。 + +![img](./figures/syscare逻辑架构.png) + +## SysCare系统功能 + +SysCare提供补丁制作、补丁激活和补丁卸载等功能,支持内核热补丁、用户态热补丁制作和管理: + +1. 一键式补丁制作能力 + 目前SysCare统一内核热补丁和用户态热补丁的制作流程,提供一键制作补丁能力,对用户屏蔽制作补丁细节及用户态、内核态补丁制作差异。 + +2. 补丁安装、激活、卸载 + SysCare提供统一补丁管理接口,方便用户在补丁安装、激活、卸载查询使用。 + +## SysCare系统技术 + +1. SysCare归一化补丁制作,对用户屏蔽补丁制作的细节及差异,提供统一的补丁管理工具,提升运维效率。 +2. SysCare提供的用户态热补丁支持在用户态多进程/多线程业务热修复,具有修复简单的特点,能够提升运维效率;在进程/线程新拉起、重启均生效。 +3. 热补丁lazy机制,克服`ptrace`缺陷(需全部退出内核调用),提升修复成功率。 diff --git a/docs/en/25.03/Server/Maintenance/SysCare/SysCare_user_guide.md b/docs/en/25.03/Server/Maintenance/SysCare/SysCare_user_guide.md new file mode 100644 index 0000000000000000000000000000000000000000..d6d489f21ae60737ef9bbb0d30f6041d187fb70e --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/SysCare/SysCare_user_guide.md @@ -0,0 +1,11 @@ +# SysCare用户使用手册 + +本文档给出SysCare介绍,并给出基于openEuler的SysCare安装方法以及如何使用SysCare,让用户了解SysCare,并指导用户安装和使用SysCare。 + +# 读者对象 + +本文档主要适用于使用openEuler并需要使用热补丁的用户。用户需要具备以下经验和技能: + +* 熟悉Linux基本操作 +* 熟悉软件编译相关基本概念 +* 对rpm软件包以及其制作过程有一定了解 diff --git a/docs/en/25.03/Server/Maintenance/SysCare/_menu.md b/docs/en/25.03/Server/Maintenance/SysCare/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..05be622507040c2dd6919833f83c5847ac11eaaf --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/SysCare/_menu.md @@ -0,0 +1,16 @@ +--- +label: 'SysCare用户指南' +ismanual: 'Y' +description: '提供在线的热补丁修复能力' +children: + - label: '认识SysCare' + href: './SysCare_introduction.md' + - label: '安装SysCare' + href: './installing_SysCare.md' + - label: '使用SysCare' + href: './using_SysCare.md' + - label: '约束限制' + href: './constraints.md' + - label: '常见问题与解决方法' + href: './faqs.md' +--- diff --git a/docs/en/25.03/Server/Maintenance/SysCare/constraints.md b/docs/en/25.03/Server/Maintenance/SysCare/constraints.md new file mode 100644 index 0000000000000000000000000000000000000000..354e346733511c78d46c1e1e6552f05c5f4641ba --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/SysCare/constraints.md @@ -0,0 +1,35 @@ +# 约束限制 + +## 版本约束 + +内核版本:当前SysCare支持openEuler 22.03 SP1及以上版本。 + +硬件架构:x86_64 / aarch64。 + +## 应用约束 + +1. 当前对LINE宏的处理需要对每个软件进行适配,当前仅考虑适配redis、nginx,其他未适配的软件可能会造成patch的size过大。后续会考虑引入参数支持用户自行适配。 +2. 用户态热补丁对于一个ELF文件,只支持一个补丁,如需修复多个bug,可将多个bugfix的patch文件同时传入补丁制作参数中,可制作出修复多个bug的热补丁。 + +## 语言约束 + +原理上补丁制作在object file一级进行比较,与编程语言无关。 +当前仅测试了C / C++语言。 + +## 其他约束 + +- 当前仅支持64位系统; +- 当前仅支持ELF格式的热修复,暂不支持解释型语言; +- 当前仅支持gcc / g++编译器; +- 编译器需要支持`-gdwarf`、`-ffunction-sections`、`-fdata-sections`参数; +- 仅支持DWARF格式的调试信息; +- 暂不支持交叉编译; +- 暂无法识别文件名相同,并且局部变量和函数名称完全一致的不同路径源码文件; +- 暂不支持汇编修改(包括`.S`文件及内联汇编); +- 暂不支持新增外部符号(动态库依赖); +- 暂不支持对同一个二进制打多个补丁; +- 暂不支持C & C++ 混合编译; +- 暂不支持C++ exception修改; +- 暂不支持group section: ```-g3```编译选项,特定编译优化选项,特定gcc plugin等; +- 暂不支持新增ifunc: ```__attribute__((ifunc("foo")))```; +- 暂不支持新增TLS变量: ```__thread int foo```。 diff --git a/docs/en/25.03/Server/Maintenance/SysCare/faqs.md b/docs/en/25.03/Server/Maintenance/SysCare/faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..3c57b6671bd87b0bac6abdc2f197761cbc8b944e --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/SysCare/faqs.md @@ -0,0 +1,16 @@ +# 常见问题与解决方法 + +## **问题1:报错:“alloc upatch module memory failed”** + + 原因:触发selinux约束。 + 解决方法:按照报错建议命令操作,手动添加策略,由于不同情况添加策略不同,无法穷尽枚举,参考该issue: 。 + +## **问题2:报错: “patch file error 2”** + + 原因:补丁检测失败。 + 解决方法:补丁无法正常打入,更换补丁。 + +## **问题3:报错: “build project error 11”** + + 原因:源码包编译失败。 + 解决方法:尝试使用```rpmbuild -ra *.src.rpm```命令测试源码包是否可正常编译并满足其编译依赖。 diff --git "a/docs/en/25.03/Server/Maintenance/SysCare/figures/syscare\351\200\273\350\276\221\346\236\266\346\236\204.png" "b/docs/en/25.03/Server/Maintenance/SysCare/figures/syscare\351\200\273\350\276\221\346\236\266\346\236\204.png" new file mode 100644 index 0000000000000000000000000000000000000000..4ed8b88331695d295351dd57bd570251c18d9502 Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/SysCare/figures/syscare\351\200\273\350\276\221\346\236\266\346\236\204.png" differ diff --git a/docs/en/25.03/Server/Maintenance/SysCare/installing_SysCare.md b/docs/en/25.03/Server/Maintenance/SysCare/installing_SysCare.md new file mode 100644 index 0000000000000000000000000000000000000000..dc4f5ba8ea9823e73c6ca99d3766d55b88512080 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/SysCare/installing_SysCare.md @@ -0,0 +1,55 @@ +# 安装SysCare + +本章介绍在openEuler中安装SysCare的方法。 + +## 安装SysCare核心组件 + +### 最低硬件要求 + +* 2 CPU (x86_64 / aarch64) +* 4GB RAM +* 100GB 硬盘 + +### 前提条件 + +安装openEuler 23.09版本。 + +### 源码编译安装SysCare + +SysCare源码已经归档至代码仓,用户可自行下载并编译安装。 + +SysCare在编译前需要安装依赖包,相关命令如下: + +```shell +dnf install cmake make rust cargo kernel-devel elfutils-libelf-devel llvm clang bpftool libbpf libbpf-devel libbpf-static +``` + +示例如下: + +```shell +git clone https://gitee.com/openeuler/syscare.git +cd syscare +mkdir build +cd build +cmake -DCMAKE_INSTALL_PREFIX=/usr -DKERNEL_VERSION=$(uname -r) .. +make +make install +``` + +### repo安装SysCare + +如果repo源中有SysCare相关的包,则可以通过dnf或yum命令进行下载、安装。 + +相关命令如下: + +```shell +dnf install syscare syscare-kmod syscare-build syscare-build-ebpf +``` + +### 卸载SysCare + +相关命令如下: + +```shell +dnf erase syscare syscare-kmod syscare-build syscare-build-ebpf +``` diff --git a/docs/en/25.03/Server/Maintenance/SysCare/using_SysCare.md b/docs/en/25.03/Server/Maintenance/SysCare/using_SysCare.md new file mode 100644 index 0000000000000000000000000000000000000000..cb940632d5aa441bc6a47fb8fdfecd8d14cf639f --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/SysCare/using_SysCare.md @@ -0,0 +1,310 @@ +# 使用SysCare + +本章介绍在openEuler中使用SysCare的方法。 + +## 前提条件 + +安装openEuler 23.09版本。 + +## SysCare使用 + +本章节将介绍 SysCare 的使用方法,包含热补丁制作及热补丁管理。 + +### 热补丁制作 + +用户可以使用`sycare build`命令制作热补丁,该命令为纯CLI工具,提供从RPM包生成热补丁包的功能,热补丁包以RPM包的形式封装维护,支持制作内核热补丁及用户态热补丁。 + +#### 热补丁制作流程 + +1. 准备热补丁目标软件源码包(source rpm)及软件调试信息包(debuginfo rpm) + + 示例: + + ```shell + yumdownloader kernel --source --debuginfo + ``` + +2. 确认满足对应软件编译依赖 + + 示例: + + ```shell + dnf install make gcc bison flex openssl-devel dwarves python3-devel elfutils-libelf-devel + ``` + +3. 执行`syscare build`命令构建热补丁 + + 示例: + + ```shell + syscare build \ + --patch_name HP001 \ + --source kernel-5.10.0-60.66.0.91.oe2203.src.rpm \ + --debuginfo kernel-debuginfo-5.10.0-60.66.0.91.oe2203.x86_64.rpm \ + --output output \ + --patch 001-kernel-patch-test.patch + ``` + + 热补丁制作过程将会在由`--workdir`参数所指定的目录中(默认为当前目录)创建以`syscare-build`开头的临时文件夹,用于存放临时文件及编译日志。 + + 示例: + + ```shell + dev@openeuler-dev:[~]$ ls -l syscare-build.111602/ + total 100 + -rw-r--r--. 1 dev dev 92303 Nov 12 00:00 build.log + drwxr-xr-x. 6 dev dev 4096 Nov 12 00:00 package + drwxr-xr-x. 4 dev dev 4096 Nov 12 00:00 patch + ``` + + 编译日志将会生成在临时文件夹中,名称为`build.log`。 + + ```shell + dev@openeuler-dev:[~]$ cat syscare-build.111602/build.log | less + ``` + + 若补丁制作成功,且未指定`--skip-compiler-check`参数,将不会保留该临时文件夹。 + +4. 检查编译结果 + + 示例: + + ```shell + dev@openeuler-dev:[~]$ ls -l + total 189680 + -rw-r--r--. 1 dev dev 194218767 Nov 12 00:00 kernel-5.10.0-60.91.0.115.oe2203-HP001-1-1.x86_64.src.rpm + -rw-r--r--. 1 dev dev 10937 Nov 12 00:00 patch-kernel-5.10.0-60.91.0.115.oe2203-HP001-1-1.x86_64.rpm + ``` + + 其中 + + - `patch-kernel-5.10.0-60.91.0.115.oe2203-HP001-1-1.x86_64.rpm`为补丁包 + - `kernel-5.10.0-60.91.0.115.oe2203-HP001-1-1.x86_64.src.rpm`为二进制包 + +#### 热补丁制作工具 + +```shell +USAGE: + syscare build [OPTIONS] --patch_name --source --debuginfo ... --patch ... + +OPTIONS: + -n, --patch_name Patch name + --patch_arch Patch architecture [default: x86_64] + --patch_version Patch version [default: 1] + --patch_release Patch release [default: 1] + --patch_description Patch description [default: (none)] + -s, --source Source package + -d, --debuginfo ... Debuginfo package(s) + --workdir Working directory [default: .] + -o, --output Output directory [default: .] + -j, --jobs Parllel build jobs [default: 96] + --skip_compiler_check Skip compiler version check (not recommended) + --skip_cleanup Skip post-build cleanup + -v, --verbose Provide more detailed info + -p, --patch ... Patch file(s) + -h, --help Prints help information + -V, --version Prints version information +``` + +|名称|描述|类型|备注| +| ---- | ---- | ---- | ---- | +|-n, --patch_name ``|补丁名称|字符串|必选参数,需符合RPM命名规范| +|--patch_arch ``|补丁架构|字符串|默认为当前架构,需符合RPM命名规范| +|--patch_version ``|补丁版本号|字符串|默认值为1,需符合RPM命名规范| +|--patch_release ``|补丁release|数字|默认值为1,需符合RPM命名规范| +|--patch_description ``|补丁描述|字符串|默认为(none)| +|-s, --source ``|目标软件src.rpm源码包路径|字符串|必选参数,需为合法路径| +|-d, --debuginfo `...`|目标软件debuginfo包路径|字符串|必选参数,可指定多个,需为合法路径| +|--workdir ``|临时文件夹路径|字符串|默认为当前执行目录,需为合法路径| +|-o, --output ``|补丁输出文件夹|字符串|默认为当前执行目录,需为合法路径| +|-j, --jobs ``|并行编译线程数|数字|默认为cpu线程数| +|--skip-compiler-check|跳过编译器检查|标识|-| +|--skip-cleanup|跳过临时文件清理|标识|-| +|-v, --verbose|打印详细信息|标识|-| +|-p, --patch `...`|补丁文件路径|字符串|必选参数,可指定多个,需为合法路径| +|-h, --help|打印帮助信息|标识|-| +|-V, --version|打印版本信息|标识|-| + +示例: + +```shell +syscare build \ + --patch_name "HP001" \ + --patch_description "CVE-2021-32675 - When parsing an incoming Redis Standard Protocol (RESP) request, Redis allocates memory according to user-specified values which determine the number of elements (in the multi-bulk header) and size of each element (in the bulk header). An attacker delivering specially crafted requests over multiple connections can cause the server to allocate significant amount of memory. Because the same parsing mechanism is used to handle authentication requests, this vulnerability can also be exploited by unauthenticated users." \ + --source ./redis-6.2.5-1.src.rpm \ + --debuginfo ./redis-debuginfo-6.2.5-1.x86_64.rpm \ + --output ./output \ + --patch ./0001-Prevent-unauthenticated-client-from-easily-consuming.patch +``` + +#### 热补丁包命名规则 + +- 热补丁包:patch-目标软件全名-补丁名称-补丁版本-补丁release.架构名.rpm +- 热补丁源码包:目标软件全名-补丁名称-补丁版本-补丁release.架构名.src.rpm + +#### 输出 + +- 热补丁包:包含SysCare热补丁的二进制及元信息,用于热补丁安装。 +- 热补丁源码包:包含目标软件源码及新增补丁文件,用于新版本热补丁制作。 + +#### 错误定位 + +如果热补丁制作过程出现错误,请参考位于工作目录下名称为`build.log`的编译日志。 + +示例: + +```shell +Building patch, this may take a while +- Preparing build requirements +- Building patch +Error: UserPatchBuilder: Failed to build patch + +Caused by: + Process "/usr/libexec/syscare/upatch-build" exited unsuccessfully, exit_code=253 +For more information, please check "/home/dev/syscare-build.345549/build.log" +``` + +### 热补丁包管理 + +热补丁的安装以及卸载需要提供对应rpm包的名称,下面使用`$patch_package`来指代rpm包名称。 + +1. 热补丁包安装 + + ```shell + dnf install $patch_package.rpm + ``` + + 热补丁包安装后,热补丁相关文件存放在如下路径: + + ```shell + /usr/lib/syscare/patches + ``` + +2. 热补丁包卸载 + + ```shell + dnf remove $patch_package + ``` + + 注:若热补丁处于`ACTIVED`以上状态时,热补丁将会被自动卸载。 + +### 热补丁管理 + +使用`syscare`命令可以对热补丁进行管理。 + +对单一热补丁操作前,用户需要提供一个字符串来搜索热补丁,后续使用`$patch_identifier`来指代这个字符串。 + +热补丁管理搜索规则为:目标包名/补丁名,其中“目标包名/”在补丁名唯一的情况下可以省略,也可使用UUID来进行管理。 + +- 目标包名:待打入补丁的目标软件的软件包名称; +- 补丁名:热补丁名称。 + +#### 补丁元信息 + +补丁元信息中包含以下字段: + +| 字段名称 | 字段描述 | +| ----------- | ---------------------- | +| uuid | 补丁ID | +| name | 补丁名称 | +| version | 补丁版本 | +| release | 补丁Release | +| arch | 补丁架构 | +| type | 补丁类型 | +| target | 目标软件名 | +| entities | 目标软件可执行文件名称 | +| digest | 补丁指纹 | +| license | 目标软件许可证 | +| description | 补丁描述 | +| patch| 补丁文件列表 | + +示例: + +```shell +sudo syscare info redis-6.2.5-1/HP002-1-1 +uuid: 980fa0d0-e753-447c-8494-01de595f35d0 +name: HP002 +version: 1 +release: 1 +arch: x86_64 +type: UserPatch +target: redis-6.2.5-1 +target_elf: redis-server, redis-benchmark, redis-cli +license: BSD and MIT +description: CVE-2021-32675 - When parsing an incoming Redis Standard Protocol (RESP) request, Redis allocates memory according to user-specified values which determine the number of elements (in the multi-bulk header) and size of each element (in the bulk header). An attacker delivering specially crafted requests over multiple connections can cause the server to allocate significant amount of memory. Because the same parsing mechanism is used to handle authentication requests, this vulnerability can also be exploited by unauthenticated users. +patch: +0001-Prevent-unauthenticated-client-from-easily-consuming.patch +``` + +#### 热补丁状态 + +SysCare将热补丁的生命周期分成如下状态: + +- 未加载:`NOT-APPLIED` +- 未激活:`DEACTIVED` +- 已激活:`ACTIVED` +- 已接受:`ACCEPTED` + +#### 补丁信息查询 + +1. 补丁基本信息查询: + + ```shell + syscare info $patch_identifier + ``` + +2. 补丁状态查询: + + ```shell + syscare status $patch_identifier + ``` + +3. 查询所有补丁状态: + + ```shell + syscare list + ``` + +#### 热补丁状态管理 + +1. 加载热补丁: + + ```shell + syscare apply $patch_identifier + ``` + +2. 卸载热补丁: + + ```shell + syscare remove $patch_identifier + ``` + +3. 激活热补丁: + + ```shell + syscare active $patch_identifier + ``` + +4. 反激活热补丁: + + ```shell + syscare deactive $patch_identifier + ``` + +5. 接受热补丁: + + ```shell + syscare accept $patch_identifier + ``` + +6. 保存所有补丁状态: + + ```shell + syscare save + ``` + +7. 恢复所有补丁状态: + + ```shell + syscare restore + ``` diff --git a/docs/en/25.03/Server/Maintenance/Troubleshooting/_menu.md b/docs/en/25.03/Server/Maintenance/Troubleshooting/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..5fd32a2391c5867224d046f2e77f6be96ece572c --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/Troubleshooting/_menu.md @@ -0,0 +1,8 @@ +--- +label: '故障应急处理' +ismanual: 'Y' +description: '常见的故障应急处理方法' +children: + - label: '故障应急处理' + href: './troubleshooting.md' +--- diff --git a/docs/en/25.03/Server/Maintenance/Troubleshooting/images/zh-cn_image_0000001372249333.png b/docs/en/25.03/Server/Maintenance/Troubleshooting/images/zh-cn_image_0000001372249333.png new file mode 100644 index 0000000000000000000000000000000000000000..48cd37225954e212cb3e159acc137866d8edc362 Binary files /dev/null and b/docs/en/25.03/Server/Maintenance/Troubleshooting/images/zh-cn_image_0000001372249333.png differ diff --git a/docs/en/25.03/Server/Maintenance/Troubleshooting/troubleshooting.md b/docs/en/25.03/Server/Maintenance/Troubleshooting/troubleshooting.md new file mode 100644 index 0000000000000000000000000000000000000000..d11c117c4830f19a961ded583456f18067179339 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/Troubleshooting/troubleshooting.md @@ -0,0 +1,101 @@ +# 故障应急处理 + +- [故障应急处理](#故障应急处理) + - [触发kdump重启](#触发kdump重启) + - [强制重启](#强制重启) + - [重启网络](#重启网络) + - [修复文件系统](#修复文件系统) + - [手动dropcache](#手动dropcache) + - [救援模式和单用户模式](#救援模式和单用户模式) + +## 触发kdump重启 + +```shell +# 向sysrq文件中写入1, 开启SysRq功能,开启该功能后,内核会响应任何操作。 +echo 1 > /proc/sys/kernel/sysrq + +# 让系统崩溃 +echo c > /proc/sysrq-trigger +``` + +## 强制重启 + +强制重启有以下两种方式: + +1.手动重启OS。 + +```shell +reboot -f +``` + +2.通过iBMC强制上下电。 + +![zh-cn_image_0000001372249333](./images/zh-cn_image_0000001372249333.png) + +## 重启网络 + +openEuler使用**NetworkManager**来管理网络,执行下面命令即可重启网络。 + +```shell +systemctl restart NetworkManager +``` + +## 修复文件系统 + +当系统强行上下电重启后,文件系统可能受到损坏,系统启动时会自动检查并修复文件系统,当文件系统没有自动修复成功时,便需要手动使用**fsck**进行扫描和修复。 + +```shell +# 此时一般会进入救援模式,在日志中查看是哪个文件系统路径损坏。 +journalctl -xb +# 修复前检查该分区是否已经挂载 +cat /proc/mounts +# 卸载该目录 +umount xx +# 若无法卸载,**kill**占用该目录的进程 +lsof | grep xxx +kill xxx +# 执行fsck命令进行修复,过程中需要输入yes or no +fsck -y /dev/xxx +``` + +## 手动dropcache + +```shell +#当N数值不同时,可以达到不同的清理目的。根据linux内核文档建议,在清理前先执行sync(因为drop操作不会释放任何脏对象,而sync命令将所有未写的系统缓冲区写到磁盘中,包含已修改的inodes、已延迟的块I/O和读写映射文件,这样可以减少脏对象,从而让更多对象可以被释放。) +echo N > /proc/sys/vm/drop_caches + +#释放pagecache +echo 1 > /proc/sys/vm/drop_caches + +#释放dentries和inodes +echo 2 > /proc/sys/vm/drop_caches + +#释放pagecache, dentries和inodes +echo 3 > /proc/sys/vm/drop_caches +``` + +## 救援模式和单用户模式 + +- 救援模式 + + 挂载openEuler 22.03 LTS SP2镜像进入救援模式。 + + 1. 选择Troubleshooting。 + 2. 选择Rescue a openEuler system。 + 3. 按提示操作进行。 + + 1)Continue + + 2)Read-only mount + + 3)Skip to shell + + 4)Quit(Reboot) + +- 单用户模式 + + 在登录界面,输入字母e,进入grub界面,在linux行加入init=/bin/sh,按`ctrl+x`进入界面。 + + 1. 执行`mount -o remount,rw /`。 + 2. 执行修改密码等操作。 + 3. exit退出。 diff --git a/docs/en/25.03/Server/Maintenance/sysmonitor/_menu.md b/docs/en/25.03/Server/Maintenance/sysmonitor/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..b74739988261a321bd21c3837ce0ee0309bc0488 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/sysmonitor/_menu.md @@ -0,0 +1,8 @@ +--- +label: 'sysmonitor用户指南' +ismanual: 'Y' +description: '使用 sysmonitor 服务监控 OS 系统运行过程中的异常' +children: + - label: 'sysmonitor用户指南' + href: './sysmonitor-user-guide.md' +--- diff --git "a/docs/en/25.03/Server/Maintenance/sysmonitor/figures/sysmonitor\345\212\237\350\203\275\345\210\227\350\241\250.png" "b/docs/en/25.03/Server/Maintenance/sysmonitor/figures/sysmonitor\345\212\237\350\203\275\345\210\227\350\241\250.png" new file mode 100644 index 0000000000000000000000000000000000000000..701e925d66a8771774e1bb38fdf70edd982913bf Binary files /dev/null and "b/docs/en/25.03/Server/Maintenance/sysmonitor/figures/sysmonitor\345\212\237\350\203\275\345\210\227\350\241\250.png" differ diff --git a/docs/en/25.03/Server/Maintenance/sysmonitor/sysmonitor-user-guide.md b/docs/en/25.03/Server/Maintenance/sysmonitor/sysmonitor-user-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..d26148ae9cfd777d6ecc65f1ee62542aed98c9e4 --- /dev/null +++ b/docs/en/25.03/Server/Maintenance/sysmonitor/sysmonitor-user-guide.md @@ -0,0 +1,799 @@ +# sysmonitor + +## 介绍 + +System Monitor Daemon + +sysmonitor 负责监控 OS 系统运行过程中的异常,将监控到的异常记录到系统日志(`/var/log/sysmonitor.log`)中。sysmonitor 以服务的形式提供,可以通过 `systemctl start|stop|restart|reload sysmonitor` 启动、关闭、重启、重载服务。建议产品部署 sysmonitor 调测软件,便于定位系统异常问题。 + +![](./figures/sysmonitor功能列表.png) + +### 注意事项 + +- sysmonitor 不支持并发执行。 +- 各配置文件须合法配置,否则可能造成监控框架异常。 +- sysmonitor 服务操作和配置文件修改,日志查询需要 root 权限。root 用户具有系统最高权限,在使用 root 用户进行操作时,请严格按照操作指导进行操作,避免不规范操作造成系统管理及安全风险。 + +### 配置总览 + +sysmonitor 有一个主配置文件(`/etc/sysconfig/sysmonitor`),用于配置各监控项的监控周期、是否需要监控。配置项的=和"之间不能有空格,如`PROCESS_MONITOR="on"`。 + +配置说明 + +| 配置项 | 配置项说明 | 是否必配 | 默认值 | +| ------------------------- | ------------------------------------------------------------ | -------- | -------------------------------------- | +| PROCESS_MONITOR | 设定是否开启关键进程监控,on为开启,off为关闭 | 否 | on | +| PROCESS_MONITOR_PERIOD | 设置关键进程监控的周期,单位秒 | 否 | 3s | +| PROCESS_RECALL_PERIOD | 关键进程恢复失败后再次尝试拉起周期,单位分,取值范围为1到1440之间的整数 | 否 | 1min | +| PROCESS_RESTART_TIMEOUT | 关键进程服务异常恢复过程中超时时间,单位秒,取值范围为30至300之间的整数 | 否 | 90s | +| PROCESS_ALARM_SUPRESS_NUM | 设置关键进程监控配置使用告警命令上报告警时的告警抑制次数,取值范围为正整数 | 否 | 5 | +| FILESYSTEM_MONITOR | 设定是否开启 ext3/ext4 文件系统监控,on 为开启,off 为关闭 | 否 | on | +| DISK_MONITOR | 设定是否开启磁盘分区监控,on为开启,off 为关闭 | 否 | on | +| DISK_MONITOR_PERIOD | 设定磁盘监控周期,单位秒 | 否 | 60s | +| INODE_MONITOR | 设定是否开启磁盘 inode 监控,on 为开启, off 为关闭 | 否 | on | +| INODE_MONITOR_PERIOD | 设定磁盘 inode 监控周期,单位秒 | 否 | 开启 | +| NETCARD_MONITOR | 设定是否开启网卡监控,on 为开启, off 为关闭 | 否 | on | +| FILE_MONITOR | 设定是否开启文件监控,on为开启, off 为关闭 | 否 | on | +| CPU_MONITOR | 设定是否开启 cpu 监控,on 为开启, off 为关闭 | 否 | on | +| MEM_MONITOR | 设定是否开启内存监控,on 为开启, off 为关闭 | 否 | on | +| PSCNT_MONITOR | 设定是否开启进程数监控,on为开启,off 为关闭 | 否 | on | +| FDCNT_MONITOR | 设定是否开启 fd 总数监控,on 为开启,off 为关闭 | 否 | on | +| CUSTOM_DAEMON_MONITOR | 用户自定义的 daemon类型的监控项,on为开启,off为关闭 | 否 | on | +| CUSTOM_PERIODIC_MONITOR | 用户自定义的 periodic 类型的监控项,on为开启, off 为关闭 | 否 | on | +| IO_DELAY_MONITOR | 本地磁盘 IO 延时监控开关,on 为开启,off 为关闭 | 否 | off | +| PROCESS_FD_NUM_MONITOR | 设定是否开启单个进程句柄数监控,on为开启,off 为关闭 | 否 | on | +| PROCESS_MONITOR_DELAY | sysmonitor 启动时,是否等待所有的监控项都正常,on为等待,off为不等待 | 否 | on | +| NET_RATE_LIMIT_BURST | 网卡监控路由信息打印抑制频率,即一秒内打印多少条日志 | 否 | 5
有效范围是 0-100,默认为5 | +| FD_MONITOR_LOG_PATH | 文件句柄监控日志文件 | 否 | 默认配置路径为 /var/log/sysmonitor.log | +| ZOMBIE_MONITOR | 僵尸进程监控开关 | 否 | off | +| CHECK_THREAD_MONITOR | 内部线程自愈开关,on为开启,off为关闭 | 否 | on
若不配置,默认值为开启 | +| CHECK_THREAD_FAILURE_NUM | 内部线程自愈的周期检查次数 | 否 | 默认值为3,范围为【2,10】 | + +- 修改 `/etc/sysconfig/sysmonitor` 配置文件后,需要重启 sysmonitor 服务生效。 +- 配置文件中,如果某一项没有配置,默认为监控项开启。 +- 内部线程自愈开启后,当监控项子线程卡住,且超过配置的周期检查次数,会重启 sysmonitor 服务,进行恢复,会重新加载配置,对于配置的关键进程监控和自定义监控,会重新拉起执行。如果对于用户使用有影响,可以选择关闭该功能。 + +### 命令参考 + +- 启动监控服务 + +``` shell +systemctl start sysmonitor +``` + +- 关闭监控服务 + +``` shell +systemctl stop sysmonitor +``` + +- 重启监控服务 + +``` shell +systemctl restart sysmonitor +``` + +- 修改监控项的配置文件后,重载监控服务可使修改后的配置动态生效 + +``` shell +systemctl reload sysmonitor +``` + +### 监控日志 + +在默认情况下,为了防止 sysmonitor.log 文件过大,提供了切分转储日志的机制。日志将被转储到磁盘目录下,这样就能够保持一定量的日志。 + +配置文件为 `/etc/rsyslog.d/sysmonitor.conf`,因为增加了 rsyslog 配置文件,第一次安装 sysmonitor 后,需要重启 rsyslog 服务生效 sysmonitor 日志配置。 + +```sh +$template sysmonitorformat,"%TIMESTAMP:::date-rfc3339%|%syslogseverity-text%|%msg%\n" + +$outchannel sysmonitor, /var/log/sysmonitor.log, 2097152, /usr/libexec/sysmonitor/sysmonitor_log_dump.sh +if ($programname == 'sysmonitor' and $syslogseverity <= 6) then { +:omfile:$sysmonitor;sysmonitorformat +stop +} + +if ($msg contains 'Time has been changed') then { +:omfile:$sysmonitor;sysmonitorformat +stop +} + +if ($programname == 'sysmonitor' and $syslogseverity > 6) then { +/dev/null +stop +} +``` + +## ext3/ext4 文件系统监控 + +### 简介 + +当文件系统出现故障时会导致 IO 操作异常从而引发操作系统一系列问题。通过文件系统故障检测及时发现,以便于系统管理员或用户及时处理故障,修复问题。 + +### 配置文件说明 + +无 + +### 异常日志 + +对于增加了 errors=remount-ro 挂载选项的文件系统,如果监控到 ext3/ext4文件系统故障,sysmonitor.log 中打印异常信息示例如下: + +```sh +info|sysmonitor[127]: loop0 filesystem error. Remount filesystem read-only. +``` + +其他异常场景下,如果监控到 ext3/ext4 文件系统故障,sysmonitor.log 中打印异常信息示例如下: + +```sh +info|sysmonitor[127]: fs_monitor_ext3_4: loop0 filesystem error. flag is 1879113728. +``` + +## 关键进程监控 + +### 简介 + +定期监控系统中关键进程,当系统内关键进程异常退出时,自动尝试恢复关键进程。如果恢复失败并需要告警,可上报告警。系统管理员能被及时告知进程异常退出事件,以及进程是否被恢复拉起。问题定位人员能从日志中定位进程异常退出的时间。 + +### 配置文件说明 + +配置目录为`/etc/sysmonitor/process`, 每个进程或模块一个配置文件。 + +```sh +USER=root +NAME=irqbalance +RECOVER_COMMAND=systemctl restart irqbalance +MONITOR_COMMAND=systemctl status irqbalance +STOP_COMMAND=systemctl stop irqbalance +``` + +各配置项如下: + +| 配置项 | 配置项说明 | 是否必配 | 默认值 | +| ---------------------- | ------------------------------------------------------------ | -------- | --------------------------------------------------- | +| NAME | 进程或模块名 | 是 | 无 | +| RECOVER_COMMAND | 恢复命令 | 否 | 无 | +| MONITOR_COMMAND | 监控命令
命令返回值为0视为进程正常,命令返回大于 0视为进程异常 | 否 | pgrep -f $(which xxx) "xxx"为NAME字段中配置的进程名 | +| STOP_COMMAND | 停止命令 | 否 | 无 | +| USER | 用户名
使用指定的用户执行、监控、恢复、停止命令或脚本 | 否 | 如果配置项为空,则默认使用 root | +| CHECK_AS_PARAM | 参数传递开关
开关设置为 on 时,在执行 RECOVER_COMMAND 命令时,会将 MONITOR_COMMAND 的返回值作为入参,传给 RECOVER_COMMAND 命令或脚本。 开关为 off 或其他时,功能关闭 | 否 | 无 | +| MONITOR_MODE | 监控模式
- 配置为 parallel,并行监控
- 配置为 serial,串行监控 | 否 | serial | +| MONITOR_PERIOD | 监控周期
- 并行监控监控周期
- 监控模块配置为 serial,该配置项不生效 | 否 | 3 | +| USE_CMD_ALARM | 告警模式
配置为 on 或 ON,则使用告警命令上报告警 | 否 | 无 | +| ALARM_COMMAND | 上报告警命令 | 否 | 无 | +| ALARM_RECOVER_COMMAND | 恢复告警命令 | 否 | 否 | + +- 修改关键进程监控的配置文件后,须执行 `systemctl reload sysmonitor`, 新的配置在一个监控周期后生效。 +- 恢复命令和监控命令不阻塞,否则会造成关键进程监控线程异常。 +- 当恢复命令执行超过 90 s时,会调用停止命令终止进程。 +- 当恢复命令配置为空或不配置时,监控命令检查到关键进程异常时,不会尝试进行拉起。 +- 当关键进程异常时,并且尝试拉起三次都不成功,最终会按照全局配置文件中配置的 PROCESS_RECALL_PERIOD 周期进行拉起。 +- 当监控的进程不是 daemon 进程,MONITOR_COMMAND 必配。 +- 若配置的关键服务在当前系统上不存在,则该监控不会生效,日志中会有相应提示;其他配置项,出现致命性错误,将使用默认配置,不报错。 +- 配置文件权限为 600,监控项建议为 systemd 中的 service类型(如 MONITOR_COMMAND=systemctl status irqbalance), 若监控的为进程,请确保 NAME 字段为绝对路径。 +- sysmonitor 重启(restart)、重载(reload)、退出(stop)都不会影响所监控的进程或服务。 +- 若 USE_CMD_ALARM 的配置为 on,ALARM_COMMAND、ALARM_RECOVER_COMMAND 的配置由用户保障。ALARM_COMMAND、ALARM_RECOVER_COMMAND 为空或没有配置,则不上报告警。 +- 对于用户自行配置的命令,如监控命令,恢复命令,停止命令,上报告警命令,恢复告警命令等,命令的安全性由用户保证。命令由 root 权限执行,建议脚本命令权限设置为仅供 root 使用,避免普通用户提权风险。 +- 配置监控命令的长度不大于200,大于 200,添加进程监控失败。 +- 当恢复命令配置为 systemd 的重启服务命令时(如`RECOVER_COMMAND=systemctl restart irqbalance`),需注意是否与开源 systemd 恢复服务的机制冲突,否则可能会影响关键进程异常后的行为模式。 +- 由 sysmonitor 恢复拉起的进程将和 sysmonitor 服务在同一个 Cgroup 当中,无法单独进行资源限制,因此建议优先使用开源 systemd 机制进行恢复。 + +### 异常日志 + +- 配置 RECOVER_COMMAND + + 如果监控到进程或模块异常,/var/log/sysmonitor.log 中打印异常信息示例如下: + + ```sh + info|sysmonitor[127]: irqbalance is abnormal, check cmd return 1, use "systemctl restart irqbalance" to recover + ``` + + 如果监控到进程或模块恢复正常,/var/log/sysmonitor.log 中打印日志示例如下: + + ```sh + info|sysmonitor[127]: irqbalance is recovered + ``` + +- 不配置 RECOVER_COMMAND + + 如果监控到进程或模块异常,/var/log/sysmonitor.log 中打印异常信息示例如下: + + ```sh + info|sysmonitor[127]: irqbalance is abnormal, check cmd return 1, recover cmd is null, will not recover + ``` + + 如果监控到进程或模块恢复正常,/var/log/sysmonitor.log 中打印日志示例如下: + + ```sh + info|sysmonitor[127]: irqbalance is recovered + ``` + +## 文件监控 + +### 简介 + +系统关键文件被意外删除后,会导致系统运行异常甚至崩溃。通过文件监控可以及时获知系统中关键文件被删除或者有恶意文件被添加,以便管理员和用户及时获知并处理故障。 + +### 配置文件说明 + +配置文件为 `/etc/sysmonitor/file`。每个监控配置项为一行,监控配置项包含两个内容:监控文件(目录)和监控事件。监控文件(目录)是绝对路径,监控文件(目录)和监控事件中间由一个或多个空格隔开。 + +配置文件支持在 `/etc/sysmonitor/file.d` 目录下增加文件监控项配置,配置方法与 `/etc/sysmoitor/file` 相同。 + +- 由于日志长度限制,建议配置的文件和目录绝对路径长度小于 223。如果配置的监控对象绝对路径长度超过223,可能会有日志打印不完整的现象出现。 + +- 请用户自行确保监控文件路径正确,如果配置文件不存在或路径错误则无法监控到该文件。 + +- 由于系统路径长度限制,监控的文件或目录绝对路径长度必须小于 4096。 + +- 支持监控目录和常规文件,/proc 和 /proc/*、/dev和/dev/*、/sys和/sys/* 管道文件 socket 文件等均不支持监控。 + +- /var/log 和 /var/log/* 均只支持删除事件。 + +- 当配置文件中存在多个相同路径的时候,以第一条合法配置为准,其他相同配置均不生效。在日志文件中可以查看到其他相同配置被忽略的提示。 + +- 不支持对软链接配置监控;当配置硬链接文件的删除事件时,需删除该文件和它的全部硬链接才会打印文件删除事件。 + +- 当文件添加监控成功及监控的事件发生时,监控日志打印的是配置文件中路径的绝对路径。 + +- 目前暂不支持目录递归监控,只能监控配置文件中的目录,子目录不会监控。 + +- 监控文件(目录)采用了位图的方式配置要监控的事件,对文件或目录进行监控的事件位图如下所示: + +```sh + ------------------------------- + | 11~32 | 10 | 9 | 1~8 | + ------------------------------- +``` + +事件位图每一位代表一个事件,第N位如果置1,则表示监控第n位对应的事件;如果第 n 位置 0,则表示不监控第 n 位对应的事件。监控位图对应的 16 进制数,即是写到配置文件中的监控事件项。 + +| 配置项 | 配置项说明 | 是否必配 | +| ------ | ------------------ | -------- | +| 1~8 | 保留 | 否 | +| 9 | 文件、目录添加事件 | 是 | +| 10 | 文件、目录删除事件 | 是 | +| 11~32 | 保留 | 否 | + +- 修改文件监控的配置文件后,须执行 `systemctl reload sysmonitor`,新的配置在最多 60 秒后生效。 +- 监控事件需要严格遵守上述规则,如果配置有误,则无法监控;如果配置项中监控事件为空,则默认只监控删除事件,即 0x200。 +- 文件或目录删除后,只有当所有打开该文件的进程都停止后才会上报删除事件。 +- 监控的文件通过 vi、sed 等操作修改后会在监控日志中打印 File "XXX" may have been changed。 +- 文件监控目前实现了对添加和删除事件的监控,即第9位和第10位有效,其他位为保留位,暂不生效。如果配置了保留位,监控日志会提示监控事件配置错误。 + +**示例** + +配置对 /home 下子目录的增加和删除事件监控,低12 位位图为:001100000000,则可以配置如下: + +```sh +/home 0x300 +``` + +配置对 /etc/ssh/sshd_config 文件的删除事件监控,低12位位图为:001000000000,则可以配置如下: + +```sh +/etc/sshd/sshd_config 0x200 +``` + +### 异常日志 + +如果监控文件有配置的事件发生,/var/log/sysmonitor.log 中打印日志示例如下: + +```sh +info|sysmonitor[127]: 1 events queued +info|sysmonitor[127]: 1th events handled +info|sysmonitor[127]: Subfile "111" under "/home" was added. +``` + +## 磁盘分区监控 + +### 简介 + +定期监控系统中挂载的磁盘分区空间,当磁盘分区使用率大于或等于用户设置的告警阈值时,记录磁盘空间告警。当磁盘分区使用率小于用户设置的告警恢复阈值时,记录磁盘空间恢复告警。 + +### 配置文件说明 + +配置文件为 `/etc/sysmonitor/disk`。 + +```sh +DISK="/var/log" ALARM="90" RESUME="80" +DISK="/" ALARM="95" RESUME="85" +``` + +| 配置项 | 配置项说明 | 是否必配 | 默认值 | +| ------ | ---------------------- | -------- | ------ | +| DISK | 磁盘挂载目录名 | 是 | 无 | +| ALARM | 整数,磁盘空间告警阈值 | 否 | 90 | +| RESUME | 整数,磁盘空间恢复阈值 | 否 | 80 | + +- 修改磁盘空间监控的配置文件后,须执行 systemctl reload sysmonitor,新的配置在一个监控周期后生效。 +- 重复配置的挂载目录,最后一个配置项生效。 +- ALARM 值应该大于 RESUME 值。 +- 只能针对挂载点或被挂载点的磁盘分区做监控。 +- 在 CPU 和 IO 高压场景下,df 命令执行超时,会导致磁盘利用率获取不到。 +- 当多个挂载点对应同一个磁盘分区时,以挂载点为准来上报告警。 + +### 异常日志 + +如果监控到磁盘空间告警,`/var/log/sysmonitor.log` 中打印信息示例如下: + +```sh +warning|sysmonitor[127]: report disk alarm, /var/log used:90% alarm:90% +info|sysmonitor[127]: report disk recovered, /var/log used:4% resume:10% +``` + +## 网卡状态监控 + +### 简介 + +系统运行过程中可能出现人为原因或异常而导致网卡状态或 IP 发生改变,对网卡状态和 IP 变化进行监控,以便及时感知到异常并方便定位异常原因。 + +### 配置文件说明 + +配置文件为 `/etc/sysmonitor/network`。 + +```sh +#dev event +eth1 UP +``` + +各配置项说明如下表 +| 配置项 | 配置项说明 | 是否必配 | 默认值 | +| ------ | ------------------------------------------------------------ | -------- | ------------------------------------------------- | +| dev | 网卡名 | 是 | 无 | +| event | 侦听事件,可取 UP, DOWN,NEWADDR, DELADDR.
- UP: 网卡 UP
- DOWN: 网卡 DOWN
- NEWADDR: 增加 ip 地址
- DELADDR: 删除 ip 地址 | 否 | 若侦听事件为空则 UP,DOWN,NEWADDR,DELADDR都监控 | + +- 修改网卡监控的配置文件后,执行 `systemctl reload sysmonitor`,新的配置生效。 +- 不支持虚拟网卡 UP 和 DOWN 状态监控。 +- 请确保网卡监控的配置文件每行少于 4096 个字符,若超过4096个字符会在监控日志中打印配置错误的提示信息。 +- 默认监控所有网卡的所有事件信息,即不配置任何网卡,默认监控所有网卡的 UP,DOWN,NEWADDR,DELADDR 事件。 +- 如果配置网卡,不配置事件,则默认监控改网卡的所有事件。 +- 增加路由信息,默认一秒五条,可通过/etc/sysconfig/sysmonitor 的 NET_RATE_LIMIT_BURST 配置选项配置一秒钟打印路由信息数量。 + +### 异常日志 + +如果监控到配置的网卡事件,`/var/log/sysmonitor.log` 中打印信息示例如下: + +```sh +info|sysmonitor[127]: lo: ip[::1] prefixlen[128] is added, comm: (ostnamed)[1046], parent comm: syst emd[1] +info|sysmonitor[127]: lo: device is up, comm: (ostnamed)[1046], parent comm: systemd[1] +``` + +如果监控到路由事件, `/var/log/sysmonitor.log` 中打印信息示例如下: + +```sh +info|sysmonitor[881]: Fib4 replace table=255 192.168.122.255/32, comm: daemon-init[1724], parent com m: systemd[1] +info|sysmonitor[881]: Fib4 replace table=254 192.168.122.0/24, comm: daemon-init[1724], parent comm: systemd[1] +info|sysmonitor[881]: Fib4 replace table=255 192.168.122.0/32, comm: daemon-init[1724], parent comm: systemd[1] +info|sysmonitor[881]: Fib6 replace fe80::5054:ff:fef6:b73e/128, comm: kworker/1:3[209], parent comm: kthreadd[2] +``` + +## cpu 监控 + +### 简介 + +监控系统全局或指定域内 cpu 的占用情况,当 cpu 使用率超出用户设置的告警阈值时,执行用户配置的日志收集命令。 + +### 配置文件说明 + +配置文件为`/etc/sysmonitor/cpu`。 + +当监控系统全局 cpu 时,配置文件示例如下: + +```sh +# cpu usage alarm percent +ALARM="90" + +# cpu usage alarm resume percent +RESUME="80" + +# monitor period (second) +MONITOR_PERIOD="60" + +# stat period (second) +STAT_PERIOD="300" + +# command executed when cpu usage exceeds alarm percent +REPORT_COMMAND="" +``` + +当监控系统指定域 cpu 时,配置文件示例如下: + +```sh +# monitor period (second) +MONITOR_PERIOD="60" + +# stat period (second) +STAT_PERIOD="300" + +DOMAIN="0,1" ALARM="90" RESUME="80" +DOMAIN="2,3" ALARM="50" RESUME="40" + +# command executed when cpu usage exceeds alarm percent +REPORT_COMMAND="" +``` + +| 配置项 | 配置项说明 | 是否必配 | 默认值 | +| -------------- | ------------------------------------------------------------ | -------- | ------ | +| ALARM | 大于0,cpu 使用率告警阈值 | 否 | 90 | +| RESUME | 大于等于0,cpu 使用率恢复阈值 | 否 | 80 | +| MONITOR_PERIOD | 监控周期(秒),取值大于0 | 否 | 60 | +| STAT_PERIOD | 统计周期(秒),取值大于0 | 否 | 300 | +| DOMAIN | 域内的 cpu 信号,cpu 号均以十进制数字表示
- 可以通过列举方式指定,cpu 号之间通过逗号分隔,例如:1,2,3。也可以通过范围方式指定,格式 X-Y(X- 每个监控域单独一个配置项,每个项支持最多配置 256 个 cpu,域内以及域之间 cpu 号均不能重复 | 否 | 无 | +| REPORT_COMMAND | cpu 使用率超过告警阈值后的日志收集命令 | 否 | 无 | + +- 修改 cpu 监控的配置文件后,须执行 systemctl reload sysmonitor, 新的配置在一个监控周期后生效。 +- ALARM 值应该大于 RESUME 值。 +- 当配置监控 cpu 域后,不再对系统全局 cpu 平均使用率进行监控,单独配置的 ALARM、RESUME 值不生效。 +- 如果某个监控域的配置存在非法,则整个 cpu 监控不执行。 +- DOMAIN 内配置的 cpu 必须全部处于在线工作状态,否则对该域的监控无法正常进行。 +- REPORT_COMMAND 项的命令不能包含 &、;、> 等不安全字符且总长度不能超过 159个字符,否则命令无法生效。 +- REPORT_COMMAND 项的命令安全性、有效性由用户自己保证,sysmonitor 只负责以 root 用户执行该命令。 +- REPORT_COMMAND 项的命令不能阻塞,当该命令执行时间超过 60s后,sysmonitor 会强行终止执行。 +- 每轮监控即使有多个域 cpu 使用率超过阈值,REPORT_COMMAND 也仅会执行一次。 + +### 异常日志 + +如果监控到全局 cpu 使用率告警或恢复且配置了日志收集命令,`/var/log/sysmonitor.log` 中打印信息示例如下: + +```sh +info|sysmonitor[127]: CPU usage alarm: 91.3% +info|sysmonitor[127]: cpu monitor: execute REPORT_COMMAND[sysmoniotrcpu] successfully +info|sysmonitor[127]: CPU usage resume 70.1% +``` + +如果监控到某个域的 cpu 平均使用率告警或恢复且配置了日志收集命令,`/var/log/sysmonitor.log` 中打印信息示例如下: + +```sh +info|sysmonitor[127]: CPU 1,2,3 usage alarm: 91.3% +info|sysmonitor[127]: cpu monitor: execute REPORT_COMMAND[sysmoniotrcpu] successfully +info|sysmonitor[127]: CPU 1,2,3 usage resume 70.1% +``` + +## 内存监控 + +### 简介 + +监控系统内存占用情况,当内存使用率超出或低于阈值时,记录日志。 + +### 配置文件说明 + +配置文件为 `/etc/sysmonitor/memory`。 + +```sh +# memory usage alarm percent +ALARM="90" + +# memory usage alarm resume percent +RESUME="80" + +# monitor period(second) +PERIOD="60" +``` + +### 配置项说明 + +| 配置项 | 配置项说明 | 是否必配 | 默认值 | +| ------ | ----------------------------- | -------- | ------ | +| ALARM | 大于0,内存占用率告警阈值 | 否 | 90 | +| RESUME | 大于等于0,内存占用率恢复阈值 | 否 | 80 | +| PERIOD | 监控周期(秒),取值大于 0 | 否 | 60 | + +- 修改内存监控的配置文件后,须执行 `systemctl reload sysmonitor`,新的配置在一个监控周期后生效。 +- ALARM 值应该大于 RESUME值。 +- 取三个监控周期的内存占用的平均值,来作为是否上报发生告警或恢复告警的依据。 + +### 异常日志 + +如果监控到内存告警,sysmonitor 获取 `/proc/meminfo` 信息,打印到 `/var/log/sysmonitor.log` 中,信息如下: + +```sh +info|sysmonitor[127]: memory usage alarm: 90% +info|sysmonitor[127]:---------------show /proc/meminfo: --------------- +info|sysmonitor[127]:MemTotal: 3496388 kB +info|sysmonitor[127]:MemFree: 2738100 kB +info|sysmonitor[127]:MemAvailable: 2901888 kB +info|sysmonitor[127]:Buffers: 165064 kB +info|sysmonitor[127]:Cached: 282360 kB +info|sysmonitor[127]:SwapCached: 4492 kB +...... +info|sysmonitor[127]:---------------show_memory_info end. --------------- +``` + +sysmonitor 有如下打印信息时,表示 sysmonitor 会调用 "echo m > /proc/sysrq-trigger" 命令导出内存分配的信息(可以在 /var/log/messages 中进行查看)。 + +```sh +info|sysmonitor[127]: sysrq show memory ifno in message。 +``` + +告警恢复时,打印信息如下: + +```sh +info|sysmonitor[127]: memory usage resume: 4.6% +``` + +## 进程数/线程数监控 + +### 简介 + +监控系统进程数目和线程数目,当进程总数或线程总数超出或低于阈值时,记录日志或上报告警。 + +### 配置文件说明 + +配置文件为 `/etc/sysmonitor/pscnt`。 + +```sh +# number of processes(include threads) when alarm occur +ALARM="1600" + +# number of processes(include threads) when alarm resume +RESUME="1500" + +# monitor period(second) +PERIOD="60" + +# process count usage alarm percent +ALARM_RATIO="90" + +# process count usage resume percent +RESUME_RATIO="80" + +# print top process info with largest num of threads when threads alarm +# (range: 0-1024, default: 10, monitor for thread off:0) +SHOW_TOP_PROC_NUM="10" +``` + +| 配置项 | 配置项说明 | 是否必配 | 默认值 | +| ----------------- | ------------------------------------------------------------ | -------- | ------ | +| ALARM | 大于 0 的整数,进程总数告警阈值 | 否 | 1600 | +| RESUME | 大于等于0的整数,进程总数恢复阈值 | 否 | 1500 | +| PERIOD | 监控周期(秒),取值大于0 | 否 | 60 | +| ALARM_RATIO | 大于0小于等于100的值,可以为小数。进程使用率告警阈值 | 否 | 90 | +| RESUME_RATIO | 大于等于0小于100的值,可以为小数。进程使用率恢复阈值,必须必告警阈值小。 | 否 | 80 | +| SHOW_TOP_PROC_NUM | 使用线程数量最新 TOP 的进程信息 | 否 | 10 | + +- 修改进程数监控的配置文件后,须执行 `systemctl reload sysmonitor`,新的配置在一个监控周期后生效。 +- ALARM 值应该大于 RESUME 值。 +- 进程数告警产生阈值取 ALARM 值与 `/proc/sys/kernel/pid_max` 的 ALARM_RATIO 中的最大值,告警恢复阈值取 RESUME 值与 `/proc/sys/kernel/pid_max` 的 RESUME_RATIO 中的最大值。 +- 线程数告警产生阈值取 ALARM 值与 `/proc/sys/kernel/threads-max` 的 ALARM_RATIO 中的最大值,告警恢复阈值取 RESUME 值与 `/proc/sys/kernel/threads-max` 的 RESUME_RATIO 中的最大值。 +- SHOW_TOP_PROC_NUM 的取值范围为0-1024,为0时,表示不启用线程监控;当设置值较大时,如 1024,在环境中产生线程告警,且告警阈值较高时,会有性能影响,建议设置为默认值 10 及更小值,若影响较大,建议设置为 0,不启动线程监控。 +- 线程监控启动时,由 `/etc/sysconfig/sysmonitor` 中 `PSCNT_MONITOR` 项和 `/etc/sysmonitor/pscnt` 中 `SHOW_TOP_PROC_NUM` 项设置。 + - `PSCNT_MONITOR` 为 on,且 `SHOW_TOP_PROC_NUM` 设置为合法值时,为启动。 + - `PSCNT_MONITOR` 为 on, `SHOW_TOP_PROC_NUM` 为 0时,为关闭。 + - `PSCNT_MONITOR` 为 off,为关闭。 +- 进程数量告警时,增加打印系统句柄使用信息和内存信息(/proc/meminfo)。 +- 线程数量告警时,会记录线程总数信息,TOP 进程信息,当前环境进程数量信息,系统句柄数信息,内存信息(/proc/meminfo)。 +- 监控项监控周期到达前,若系统出现资源不足(如线程数超过系统最大线程数),则监控告警本身将由于资源受限无法正常运行,进而无法进行告警。 + +### 异常日志 + +如果监控到进程数告警,`/var/log/sysmonitor.log` 中打印信息示例如下: + +```sh +info|sysmonitor[127]:---------------process count alarm start: --------------- +info|sysmonitor[127]: process count alarm:1657 +info|sysmonitor[127]: process count alarm, show sys fd count: 2592 +info|sysmonitor[127]: process count alarm, show mem info +info|sysmonitor[127]:---------------show /proc/meminfo: --------------- +info|sysmonitor[127]:MemTotal: 3496388 kB +info|sysmonitor[127]:MemFree: 2738100 kB +info|sysmonitor[127]:MemAvailable: 2901888 kB +info|sysmonitor[127]:Buffers: 165064 kB +info|sysmonitor[127]:Cached: 282360 kB +info|sysmonitor[127]:SwapCached: 4492 kB +...... +info|sysmonitor[127]:---------------show_memory_info end. --------------- +info|sysmonitor[127]:---------------process count alarm end: --------------- +``` + +如果监控到进程数恢复告警,`/var/log/sysmonitor.log` 中打印信息示例如下: + +```sh +info|sysmonitor[127]: process count resume: 1200 +``` + +如果监控到线程数告警,`/var/log/sysmonitor.log` 中打印信息示例如下: + +```sh +info|sysmonitor[127]:---------------threads count alarm start: --------------- +info|sysmonitor[127]:threads count alarm: 273 +info|sysmonitor[127]:open threads most 10 processes is [top1:pid=1756900,openthreadsnum=13,cmd=/usr/bin/sysmonitor --daemon] +info|sysmonitor[127]:open threads most 10 processes is [top2:pid=3130,openthreadsnum=13,cmd=/usr/lib/gassproxy -D] +..... +info|sysmonitor[127]:---------------threads count alarm end. --------------- +``` + +## 系统句柄总数监控 + +### 简介 + +监控系统文件句柄(fd)数目,当系统文件句柄总数超过或低于阈值时,记录日志。 + +### 配置文件说明 + +配置文件为 `/etc/sysmonitor/sys_fd_conf`。 + +```sh +# system fd usage alarm percent +SYS_FD_ALARM="80" +# system fd usage alarm resume percent +SYS_FD_RESUME="70" +# monitor period (second) +SYS_FD_PERIOD="600" +``` + +配置项说明: + +| 配置项 | 配置项说明 | 是否必配 | 默认值 | +| ------------- | --------------------------------------------------------- | -------- | ------ | +| SYS_FD_ALARM | 大于0小于100的整数,fd总数与系统最大 fd数百分比的告警阈值 | 否 | 80% | +| SYS_FD_RESUME | 大于0小于100的整数,fd 总数与系统最大fd数百分比的恢复阈值 | 否 | 70% | +| SYS_FD_PERIOD | 监控周期(秒),取值为100~86400 之间的整数 | 否 | 600 | + +- 修改fd 总数监控的配置文件后,须执行 `systemctl reload sysmonitor`,新的配置在一个监控周期后生效。 +- `SYS_FD_ALARM` 值应该大于 `SYS_FD_RESUME` 值,当配置非法时,会使用默认值,并打印日志。 + +### 异常日志 + +如果监控到 fd 总数告警,在监控日志中打印告警。`/var/log/sysmonitor.log` 中打印信息示例如下: + +```sh +info|sysmonitor[127]: sys fd count alarm: 259296 +``` + +系统句柄使用告警时,会打印前三个使用句柄数最多的进程: + +```sh +info|sysmonitor[127]:open fd most three processes is:[top1:pid=23233,openfdnum=5000,cmd=/home/openfile] +info|sysmonitor[127]:open fd most three processes is:[top2:pid=23267,openfdnum=5000,cmd=/home/openfile] +info|sysmonitor[127]:open fd most three processes is:[top3:pid=30144,openfdnum=5000,cmd=/home/openfile] +``` + +## 磁盘 inode 监控 + +### 简介 + +定期监控系统中挂载的磁盘分区 inode,当磁盘分区 inode 使用率大于或等于用户设置的告警阈值,记录磁盘 inode 告警。发生告警后,当磁盘分区 inode 使用率小于用户设置的告警恢复阈值,记录磁盘 inode 恢复告警。 + +### 配置文件说明 + +配置文件为 `/etc/sysmonitor/inode`。 + +```sh +DISK="/" +DISK="/var/log" +``` + +| 配置项 | 配置项说明 | 是否必配 | 默认值 | +| ------ | ------------------------- | -------- | ------ | +| DISK | 磁盘挂载目录名 | 是 | 无 | +| ALARM | 整数,磁盘 inode 告警阈值 | 否 | 90 | +| RESUME | 整数,磁盘 inode 恢复阈值 | 否 | 80 | + +- 修改磁盘 inode 监控的配置文件后,须执行 `systemctl reload sysmonitor`,新的配置在一个监控周期后生效。 +- 重复配置的挂载目录,最后一个配置项生效。 +- ALARM 值应该大于 RESUME 值。 +- 只能针对挂载点或被挂载的磁盘分区做监控。 +- 在 CPU 和 IO 高压场景下,df 执行命令超时,会导致磁盘 inode 利用率获取不到。 +- 当多个挂载点对应同一个磁盘分区,以挂载点为准来上报告警。 + +### 异常日志 + +如果监控到磁盘 inode 告警,`/var/log/sysmonitor.log`中打印信息示例如下: + +```sh +info|sysmonitor[4570]:report disk inode alarm, /var/log used:90% alarm:90% +info|sysmonitor[4570]:report disk inode recovered, /var/log used:79% alarm:80% +``` + +## 本地磁盘 io 延时监控 + +### 简介 + +每5秒读取一次本地磁盘 io 延时数据,每五分钟对在该五分钟内60组数据进行统计,如果有多于30次(一半)的数据大于配置的最大 IO 延时数据,则记录该磁盘的 IO 延时过大日志。 + +### 配置文件说明 + +配置文件为 `/etc/sysmonitor/iodelay`。 + +```sh +DELAY_VALUE="500" +``` + +| 配置项 | 配置项说明 | 是否必配 | 默认值 | +| ----------- | -------------------- | -------- | ------ | +| DELAY_VALUE | 磁盘 IO 延时的最大值 | 是 | 500 | + +### 异常日志 + +如果监控到本地磁盘 IO 延时过大告警,`/var/log/sysmonitor.log` 中打印信息示例如下: + +```sh +info|sysmonitor[127]:local disk sda IO delay is too large, I/O delay threshold is 70. +info|sysmonitor[127]:disk is sda, io delay data: 71 72 75 87 99 29 78 ...... +``` + +如果监控到本地磁盘 IO 延时告警恢复,`/var/log/sysmonitor.log` 中打印信息示例如下: + +```sh +info|sysmonitor[127]:local disk sda IO delay is normal, I/O delay threshold is 70. +info|sysmonitor[127]:disk is sda, io delay data: 11 22 35 8 9 29 38 ...... +``` + +## 僵尸进程监控 + +### 简介 + +监控系统僵尸进程数量,大于告警阈值,记录告警日志。当系统僵尸进程数小于恢复阈值时,告警恢复。 + +### 配置文件说明 + +配置文件为`/etc/sysmonitor/zombie`。 + +```sh +# Ceiling zombie process counts of alarm +ALARM="500" + +# Floor zombie process counts of resume +RESUME="400" + +# Periodic (second) +PERIOD="600" +``` + +| 配置项 | 配置项说明 | 是否必配 | 默认值 | +| ------ | ------------------------------- | -------- | ------ | +| ALARM | 大于0,僵尸进程个数告警阈值 | 否 | 500 | +| RESUME | 大于等于0,僵尸进程个数恢复阈值 | 否 | 400 | +| PERIOD | 监控周期(秒),取值大于0 | 否 | 60 | + +### 异常日志 + +如果监控到僵尸进程个数告警,`/var/log/sysmonitor.log`中打印信息如下: + +```sh +info|sysmonitor[127]: zombie process count alarm: 600 +info|sysmonitor[127]: zombie process count resume: 100 +``` + +## 自定义监控 + +### 简介 + +用户可以自定义监控项,监控框架读取配置文件内容,解析配置文件各监控属性,在监控框架里调用用户要执行的监控动作。监控模块仅提供监控框架,不感知用户在监控的内容以及如何监控,不负责上报告警。 + +### 配置文件说明 + +配置文件位于`/etc/sysmonitor.d/`路径下,每个进程或模块对应一个配置文件。 + +```sh +MONITOR_SWITCH="on" +TYPE="periodic" +EXECSTART="/usr/sbin/iomonitor_daemon" +PERIOD="1800" +``` + +| 配置项 | 配置项说明 | 是否必配 | 默认值 | +| -------------- | ------------------------------------------------------------ | --------------------- | ------ | +| MONITOR_SWITCH | 监控开关 | 否 | off | +| TYPE | 自定义监控项的类型
daemon:后台运行
periodic:周期运行 | 是 | 无 | +| EXECSTART | 执行监控命令 | 是 | 无 | +| ENVIROMENTFILE | 环境变量存放文件 | 否 | 无 | +| PERIOD | 若 type 为 periodic 类型,此为必配项,为自定义监控的周期,取值为大于0的整数 | periodic 类型为必配项 | 无 | + +- 配置文件名称,环境变量文件名称,加上绝对路径总长度不能超过127个字符。环境变量文件必须为绝对路径和实际路径,不能是软链接路径。 +- EXECSTART项的命令总长度不能超过159个字符,关键字段配置不能有空格。 +- 周期性监控的执行命令不能超时,否则对自定义监控框架产生影响。 +- 目前支持配置的环境变量最多为256个。 +- daemon 类型的自定义监控每间隔10s会统一查询是否有 reload 命令下发,或者是否有 daemon 进程异常退出;如果有reload 命令下发,需要等待 10s 后才会重新加载新的配置,如果有 daemon 进程异常退出,需要等待 10s才会重新拉起。 +- ENVIROMENTFLE 对应的文件中的内容发生变化,如新增环境变量,或环境变量的值发生变化,需要重启 sysmonitor 服务,新的环境变量才能生效。 +- `/etc/sysmonitor.d/`目录下的配置文件权限建议为 600, EXECSTART 项中若只配置了执行文件,则执行文件的权限建议为 550。 +- daemon 进程异常退出后,sysmonitor 会重新加载该 daemon进程的配置文件。 + +### 异常日志 + +如果 daemon 类型监控项异常退出,/var/log/sysmonitor.log 中会有如下记录: + +```sh +info|sysmonitor[127]: custom daemon monitor: child process[11609] name unetwork_alarm exit code[127],[1] times. +``` diff --git a/docs/en/25.03/Server/MemoryandStorage/GMEM/GMEM_introduction.md b/docs/en/25.03/Server/MemoryandStorage/GMEM/GMEM_introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..8befaf35369d916ab0a68c44721a2734592e100a --- /dev/null +++ b/docs/en/25.03/Server/MemoryandStorage/GMEM/GMEM_introduction.md @@ -0,0 +1,37 @@ +# 认识GMEM + +## 简介 + +当前异构侧数据管理CPU与异构侧分离,数据显式搬移,易用性和性能难以平衡:异构设备HBM内存严重不足,应用手动SWAP方案性能损耗大且通用性差;搜推、大数据场景存在大量无效数据搬移,缺少高效内存池化方案,急需统一的有效对等内存管理机制,Linux现有HMM框架搁浅,编程复杂度高且依赖人工调优,NV、AMD虽尝试接入,但由于架构问题导致代码缺乏通用性,性能可移植性差,引起上游OS社区反弹。 + +GMEM (Generalized Memory Management) 提供了异构互联内存的中心化管理,GMEM API支持设备接入统一地址空间,获得针对异构内存编程的优化,将CPU架构相关的实现从Linux的内存管理系统中独立出来。 + +当CPU和加速卡的内存被封装到一个统一的虚拟地址空间中后,开发者们就不再需要在两个并行的地址空间中手动转移内存,只需要使用一套统一的申请释放函数。在这种模式下甚至可以选择将CPU的DRAM内存作为加速卡的cache,代码开销也不会过大。 + +## 架构 + +![GMEM-架构.png](images/GMEM-架构.png) + +## 应用场景 + +大模型训推场景 + +* GMEM实现异构内存透明扩容技术,实现HBM内存自动超分,实现高性能、低门槛训推。 +* 提供OS原生的极简异构内存管理,超分大模型性能相比NVIDIA性能提升60%。 + +大内存共享场景 + +* 提供远程访问与按需搬移内存的灵活策略,解决内存搬移瓶颈,提升搜推、大数据应用端到端性能。 + +## 功能描述 + +驱动开发侧,GMEM提供了统一的函数注册接口,让驱动开发者避免反复造相同的轮子,确保内存管理代码不再爆炸式地增长,也规避了额外的漏洞。 + +* 调用GMEM提供的接口,简化驱动使用物理内存的代码。 +* 驱动使用GMEM统一提供的接口,避免自行造轮子时出现漏洞。 + +加速卡用户侧,GMEM给使用加速卡进行AI模型及机器学习框架开发提供了更强的可编程性:不再需要手动管理数据是存放在加速卡上还是CPU上。 + +* 通过统一的内存申请释放函数与CPU及卡上的内存交互。 +* 同一虚拟地址空间中既可以映射到CPU上,也可以映射到加速卡上。 +* GMEM封装内存管理代码,相比手动管理获得性能提升。 diff --git a/docs/en/25.03/Server/MemoryandStorage/GMEM/_menu.md b/docs/en/25.03/Server/MemoryandStorage/GMEM/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..844995a11ab1c5ad453bf086fc95b92bcaae796b --- /dev/null +++ b/docs/en/25.03/Server/MemoryandStorage/GMEM/_menu.md @@ -0,0 +1,12 @@ +--- +label: 'GMEM用户指南' +ismanual: 'Y' +description: '提供异构互联内存的中心化管理' +children: + - label: '概述' + href: './GMEM_introduction.md' + - label: '安装与部署' + href: './install_deploy.md' + - label: '使用方法' + href: './usage.md' +--- diff --git "a/docs/en/25.03/Server/MemoryandStorage/GMEM/images/GMEM-\346\236\266\346\236\204.png" "b/docs/en/25.03/Server/MemoryandStorage/GMEM/images/GMEM-\346\236\266\346\236\204.png" new file mode 100644 index 0000000000000000000000000000000000000000..0ca62843c8c5148330ead20167f4b3e2576ca463 Binary files /dev/null and "b/docs/en/25.03/Server/MemoryandStorage/GMEM/images/GMEM-\346\236\266\346\236\204.png" differ diff --git a/docs/en/25.03/Server/MemoryandStorage/GMEM/install_deploy.md b/docs/en/25.03/Server/MemoryandStorage/GMEM/install_deploy.md new file mode 100644 index 0000000000000000000000000000000000000000..50c7519e9f4083abd5c5139a805cffe092054f0c --- /dev/null +++ b/docs/en/25.03/Server/MemoryandStorage/GMEM/install_deploy.md @@ -0,0 +1,116 @@ +# 安装与部署 + +本章介绍如何安装和部署GMEM。 + +## 软硬件要求 + +* 鲲鹏920处理器 +* 昇腾910芯片 +* 操作系统:openEuler 23.09 + +## 环境准备 + +* 使用和配置GMEM需要使用root权限。 +* GMEM的开关只能在系统层面开启或关闭。 +* 请管理员确保GMEM的配置安全、可用。 + +## 安装GMEM + +* 文件准备 + + [CANN社区版历史版本-昇腾社区 (hiascend.com)](https://www.hiascend.com/software/cann/community-history) + + [固件与驱动-昇腾社区 (hiascend.com)](https://www.hiascend.com/zh/hardware/firmware-drivers/community?product=2&model=19&cann=6.0.1.alpha001&driver=1.0.18.alpha) + + | 来源 | 软件包 | + | ------------------------------------------------------------ | ------------------------------------------------------------ | + | openEuler 23.09 | kernel-6.4.0-xxx.aarch64.rpm
kernel-devel-6.4.0-xxx.aarch64.rpm
libgmem-xxx.aarch64.rpm
libgmem-devel-xxx.aarch64.rpm | + | 昇腾社区 | # CANN软件包
Ascend-cann-toolkit-xxx-linux.aarch64.rpm
# NPU固件与驱动
Ascend-hdk-910-npu-driver-xxx.aarch64.rpm
Ascend-hdk-910-npu-firmware-xxx.noarch.rpm | + | 联系GMEM社区维护人员
[@yang_yanchao](https://gitee.com/yang_yanchao) email:
[@LemmyHuang](https://gitee.com/LemmyHuang) email: | gmem-example-xxx.aarch64.rpm
mindspore-xxx-linux_aarch64.whl | + +* 安装内核 + + 使用的openEuler内核版本,确认GMEM相关编译选项已打开(当前默认已经打开)。 + + ```sh + [root@localhost ~]# cat /boot/config-`uname -r` | grep CONFIG_GMEM + CONFIG_GMEM=y + CONFIG_GMEM_DEV=m + + [root@localhost ~]# cat /boot/config-`uname -r` | grep CONFIG_REMOTE_PAGER + CONFIG_REMOTE_PAGER=m + CONFIG_REMOTE_PAGER_MASTER=m + ``` + + 在启动项中添加`gmem=on` 。 + + ```sh + [root@localhost gmem]# cat /proc/cmdline + BOOT_IMAGE=/vmlinuz-xxx root=/dev/mapper/openeuler-root ... gmem=on + ``` + + 修改`transparent_hugepage` 。 + + ```sh + echo always > /sys/kernel/mm/transparent_hugepage/enabled + ``` + +* 安装用户态动态库 libgmem。 + + ```sh + yum install libgmem libgmem-devel + ``` + +* 安装CANN框架。 + + 安装版本配套的CANN,包括toolkit,driver以及firmware,根据指引完成安装后重启系统。 + + ```sh + rpm -ivh Ascend-cann-toolkit-xxx-linux.aarch64.rpm + # 使用libgmem提供的工具安装npu-driver + sh /usr/local/gmem/install_npu_driver.sh Ascend-hdk-910-npu-driver-xxx.aarch64.rpm + rpm -ivh Ascend-hdk-910-npu-firmware-xxx.noarch.rpm + ``` + + 通过Ascend目录下的环境配置脚本配置好环境变量。 + + ```sh + source /usr/local/Ascend/ascend-toolkit/set_env.sh + ``` + + 查看NPU设备是否正常。 + + ```sh + [root@localhost ~]# npu-smi info + +-------------------------------------------------------------------------------------------+ + | npu-smi 22.0.4.1 Version: 22.0.4.1 | + +----------------------+---------------+----------------------------------------------------+ + | NPU Name | Health | Power(W) Temp(C) Hugepages-Usage(page)| + | Chip | Bus-Id | AICore(%) Memory-Usage(MB) HBM-Usage(MB) | + +======================+===============+====================================================+ + | 0 910B | OK | 79.4 82 0 / 0 | + | 0 | 0000:81:00.0 | 0 1979 / 15039 0 / 32768 | + +======================+===============+====================================================+ + ``` + +* 安装gmem-example软件包。 + + gmem-example会更新host驱动、NPU侧驱动及NPU侧内核。安装完成后重启系统使驱动生效。 + + ```sh + rpm -ivh gmem-example-xxx.aarch64.rpm + ``` + +* 安装mindspore。 + + 获取正确的mindspore版本并安装,安装后可通过执行以下命令验证mindspore功能是否正常。 + + ```sh + python -c "import mindspore;mindspore.run_check()" + MindSpore version: x.x.x + The result of multiplication calculation is correct, MindSpore has been installed on platform [Ascend] successfully! + ``` + +## 执行训练或推理任务 + +基于mindspore的训练或推理任务,在完成以上安装流程后,可直接执行,不需要做任何适配。 diff --git a/docs/en/25.03/Server/MemoryandStorage/GMEM/usage.md b/docs/en/25.03/Server/MemoryandStorage/GMEM/usage.md new file mode 100644 index 0000000000000000000000000000000000000000..57bd8154c9000df11922393834edd8090cefa16a --- /dev/null +++ b/docs/en/25.03/Server/MemoryandStorage/GMEM/usage.md @@ -0,0 +1,66 @@ +# 使用说明 + +## 简介 + +GMEM通过特定的flag申请对等互访的虚拟内存,并对外提供了一些内存优化语义,通过这部分内存语义可以达到性能优化的效果。 +libgmem是GMEM用户接口的抽象层,主要功能是是对上述内存语义进行封装,简化用户的使用。 + +## 接口说明 + +* 内存申请 + + GMEM扩展了mmap的含义,增加了一个flag MAP_PEER_SHARED申请异构内存,使用时默认返回2MB对齐的虚拟地址。 + + ```cpp + addr = mmap(NULL , size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_PEER_SHARED, -1, 0); + ``` + +* 内存释放 + + 通过munmap接口释放host和device的内存。 + + ```cpp + munmap(addr, size); + ``` + +* 内存语义 + + FreeEager:对于给定范围[addr, addr + size]的地址段,FreeEager会对范围向内对齐页面大小的完整页面进行释放(默认页面大小2M)。如果范围内不存在完整页面,将直接返回成功。 + + 接口成功返回0,失败返回错误码。 + + ```cpp + 接口原型: int gmemFreeEager(unsigned long addr, size_t size, void *stream); + 接口用法: ret = gmemFreeEager(addr, size, stream); + ``` + + Prefetch:对于给定范围[addr, addr + size]的地址段,Prefetch会对范围向外对齐页面大小的完整页面(覆盖整个地址段)进行预取。确保指定的计算单元设备hnid在接下来对vma发起的访问不会触发page fault。 + + 接口成功返回0,失败返回错误码。 + + ```cpp + 接口原型: int gmemPrefetch(unsigned long addr, size_t size, int hnid, void *stream); + 接口用法: ret = gmemPrefetch(addr, size, hnid, stream); + ``` + + 在上述内存语义使用的时候stream为空表示同步调用,非空表示异步调用。 + +* 其他接口 + + 获取当前设备的numaid。接口成功返回设备号,失败返回错误码。 + + ```cpp + 接口原型: int gmemGetNumaId(void); + 接口用法: numaid = gmemGetNumaId(); + ``` + + 获取内核的gmem统计信息。 + + ```sh + cat /proc/gmemstat + ``` + +## 约束限制 + +1. 目前仅支持2M大页,所以host OS以及NPU卡内OS的透明大页需要默认开启。 +2. 通过MAP_PEER_SHARED申请的异构内存目前不支持fork时继承。 diff --git a/docs/en/25.03/Server/MemoryandStorage/HSAK/_menu.md b/docs/en/25.03/Server/MemoryandStorage/HSAK/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..09729c1805c41bd3498e1f613d2775074d236795 --- /dev/null +++ b/docs/en/25.03/Server/MemoryandStorage/HSAK/_menu.md @@ -0,0 +1,14 @@ +--- +label: 'HSAK开发指南' +ismanual: 'Y' +description: 'HSAK 针对新型存储介质提供高带宽低时延的IO软件栈' +children: + - label: '概述' + href: './introduce_hsak.md' + - label: '使用HSAK开发应用程序' + href: './develop_with_hsak.md' + - label: 'HSAK工具使用说明' + href: './hsak_tools_usage.md' + - label: 'HSAK接口说明' + href: './hsak_interface.md' +--- diff --git a/docs/en/25.03/Server/MemoryandStorage/HSAK/develop_with_hsak.md b/docs/en/25.03/Server/MemoryandStorage/HSAK/develop_with_hsak.md new file mode 100644 index 0000000000000000000000000000000000000000..3257b9fa1a8101618311e116f4d203431f8e1aa5 --- /dev/null +++ b/docs/en/25.03/Server/MemoryandStorage/HSAK/develop_with_hsak.md @@ -0,0 +1,219 @@ +# HSAK 使用指南 + +## nvme.conf.in配置文件 + +HSAK配置文件默认安装在/etc/spdk/nvme.conf.in,开发人员可以根据实际业务需要对配置文件进行修改,配置文件内容如下: + +- [Global] + +1. ReactorMask:指定用于轮询IO的核(16进制,不能指定0核,按bit位从低位到高位,分别表示不同CPU核,如:0x1表示0核,0x6表示1、2两个核,以此类推,本字段最大支持34个字符,去掉表示16进制的0x标记,剩余32个计数字符,每个16进制字符最大是F,可表示4个核,所以最多可以支持32*4=128个核)。 +2. LogLevel:HSAK日志打印级别(0:error;1:warning;2:notice;3:info;4:debug)。 +3. MemSize:HSAK占用的内存(最小值为500MB)。 +4. MultiQ:是否在同一个块设备上开启多队列。 +5. E2eDif:DIF类型(1:半程保护;2:全程保护),不同厂商的硬盘对DIF支持能力可能不同,具体请参考硬件厂家资料。 +6. IoStat:是否使能IO统计开关(Yes\No)。 +7. RpcServer:是否启动rpc侦听线程(Yes\No)。 +8. NvmeCUSE:是否启动CUSE功能(Yes\No),开启后在/dev/spdk目录下生成nvme字符设备。 + +- [Nvme] + +1. TransportID:指定NVMe控制器的PCI地址和名称,使用格式为:TransportID "trtype:PCIe traddr:0000:09:00.0" nvme0。 +2. RetryCount:IO失败时的重试次数,0表示不重试,最大255。 +3. TimeoutUsec:IO超时时间,0或者不配置该配置项表示不设置超时时间,单位是μs。 +4. ActionOnTimeout:IO超时行为(None:仅打印信息;Reset:reset控制器;abort:丢弃超时指令),默认None。 + +- [Reactor] + +1. BatchSize:支持批量提交提交IO的个数,默认是8,最大是32。 + +## 头文件引用 + +HSAK提供两个对外头文件,开发者在使用HSAK进行开发时需要包含这两个文件: + +1. bdev_rw.h:定义了数据面用户态IO操作的宏、枚举、数据结构和接口API。 +2. ublock.h:定义了管理面设备管理、信息获取等功能的宏、枚举、数据结构和接口API。 + +## 业务运行 + +开发者在进行软件开发编译后,运行前,需要先运行setup.sh脚本程序,用于重新绑定NVMe盘驱动到用户态,该脚本默认安装在:/opt/spdk。 +执行如下命令将盘驱动从内核态绑定到用户态,同时预留1024个2M大页: + +```shell +[root@localhost ~]# cd /opt/spdk +[root@localhost spdk]# ./setup.sh +0000:3f:00.0 (8086 2701): nvme -> uio_pci_generic +0000:40:00.0 (8086 2701): nvme -> uio_pci_generic +``` + +执行如下命令将盘驱动从用户态恢复到内核态,同时释放预留的大页: + +```shell +[root@localhost ~]# cd /opt/spdk +[root@localhost spdk]# ./setup.sh reset +0000:3f:00.0 (8086 2701): uio_pci_generic -> nvme +0000:40:00.0 (8086 2701): uio_pci_generic -> nvme +``` + +## 用户态IO读写场景 + +开发者通过以下顺序调用HSAK接口,实现经由用户态IO通道的业务数据读写: + +1. 初始化HSAK UIO模块。可调用接口libstorage_init_module,完成HSAK用户态IO通道的初始化。 + +2. 打开磁盘块设备。可调用libstorage_open,打开指定块设备,如需打开多个块设备,需要多次重复调用。 + +3. 申请IO内存。可调用接口libstorage_alloc_io_buf或libstorage_mem_reserve,前者最大可申请单个65K的IO,后者没有限制(除非无可用空间)。 + +4. 对磁盘进行读写操作。根据实际业务需要,可调用如下接口进行读写操作: + + - libstorage_async_read + - libstorage_async_readv + - libstorage_async_write + - libstorage_async_writev + - libstorage_sync_read + - libstorage_sync_write + +5. 释放IO内存。可调用接口libstorage_free_io_buf或libstorage_mem_free,需要与申请时调用的接口对应。 + +6. 关闭磁盘块设备。可调用接口libstorage_close,关闭指定块设备,如果打开了多个块设备,则需要多次重复调用接口进行关闭。 + + | 接口名称 | 功能描述 | + | ----------------------- | --------------------------------------------- | + | libstorage_init_module | HSAK模块初始化接口。 | + | libstorage_open | 打开块设备。 | + | libstorage_alloc_io_buf | 从SPDK的buf_small_pool或者buf_large_pool中分配内存。 | + | libstorage_mem_reserve | 从DPDK预留的大页内存中分配内存空间。 | + | libstorage_async_read | HSAK下发异步IO读请求的接口(读缓冲区为连续buffer)。 | + | libstorage_async_readv | HSAK下发异步IO读请求的接口(读缓冲区为离散buffer)。 | + | libstorage_async_write | HSAK下发异步IO写请求的接口(写缓冲区为连续buffer)。 | + | libstorage_async_wrtiev | HSAK下发异步IO写请求的接口(写缓冲区为离散buff)。 | + | libstorage_sync_read | HSAK下发同步IO读请求的接口(读缓冲区为连续buffer)。 | + | libstorage_sync_write | HSAK下发同步IO写请求的接口(写缓冲区为连续buffer)。 | + | libstorage_free_io_buf | 释放所分配的内存到SPDK的buf_small_pool或者buf_large_pool中。 | + | libstorage_mem_free | 释放libstorage_mem_reserve所申请的内存空间。 | + | libstorage_close | 关闭块设备。 | + | libstorage_exit_module | HSAK模块退出接口。 | + +## 盘管理场景 + +HSAK包含一组C接口,可以对盘进行格式化、创建、删除namespace操作。 + +1. 首先需要调用C接口对HSAK UIO组件进行初始化,如果已经初始化过了,就不需要再调用了。 + + libstorage_init_module + +2. 根据业务需要,调用相应的接口进行盘操作,以下接口可单独调用: + + - libstorage_create_namespace + - libstorage_delete_namespace + - libstorage_delete_all_namespace + - libstorage_nvme_create_ctrlr + - libstorage_nvme_delete_ctrlr + - libstorage_nvme_reload_ctrlr + - libstorage_low_level_format_nvm + - libstorage_deallocate_block + +3. 最后如果退出程序,则需要销毁HSAK UIO,如果还有其他业务在使用,不需要退出,则不用销毁。 + + libstorage_exit_module + + | 接口名称 | 功能描述 | + | ------------------------------- | ----------------------------------------- | + | libstorage_create_namespace | 在指定控制器上创建namespace(前提是控制器具有namespace管理能力)。 | + | libstorage_delete_namespace | 在指定控制器上删除namespace。 | + | libstorage_delete_all_namespace | 删除指定控制器上所有namespace。 | + | libstorage_nvme_create_ctrlr | 根据PCI地址创建NVMe控制器。 | + | libstorage_nvme_delete_ctrlr | 根据控制器名称销毁NVMe控制器。 | + | libstorage_nvme_reload_ctrlr | 根据传入的配置文件自动创建或销毁NVMe控制器。 | + | libstorage_low_level_format_nvm | 低级格式化NVMe盘。 | + | libstorage_deallocate_block | 告知NVMe盘可释放的块,用于垃圾回收。 | + +## 数据面盘信息查询 + +在HSAK的IO数据面提供一组C接口,用于查询盘信息,上层业务可根据查询到的信息进行相关的业务逻辑处理。 + +1. 首先需要调用C接口对HSAK UIO进行初始化,如果已经初始化过了,就不需要再调用了。 + + libstorage_init_module + +2. 根据业务需要,调用相应接口进行信息查询,以下接口可单独调用: + + - libstorage_get_nvme_ctrlr_info + - libstorage_get_mgr_info_by_esn + - libstorage_get_mgr_smart_by_esn + - libstorage_get_bdev_ns_info + - libstorage_get_ctrl_ns_info + +3. 最后如果退出程序,则需要销毁HSAK UIO,如果还有其他业务在使用,不需要退出,则不用销毁。 + + libstorage_exit_module + + | 接口名称 | 功能描述 | + | ------------------------------- | ----------------------------- | + | libstorage_get_nvme_ctrlr_info | 获取所有控制器信息。 | + | libstorage_get_mgr_info_by_esn | 数据面获取设备序列号(ESN)对应的磁盘的管理信息。 | + | libstorage_get_mgr_smart_by_esn | 数据面获取设备序列号(ESN)对应的磁盘的SMART信息。 | + | libstorage_get_bdev_ns_info | 根据设备名称,获取namespace信息。 | + | libstorage_get_ctrl_ns_info | 根据控制器名称,获取所有namespace信息。 | + +## 管理面盘信息查询场景 + +在HSAK的管理面组件ublock提供一组C接口,用于支持在管理面对盘信息进行查询。 + +1. 首先调用C接口对HSAK ublock服务端进行初始化。 + + | 接口名称 | 功能描述 | + | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | + | init_ublock | 初始化ublock功能模块,本接口必须在其他所有ublock接口之前被调用,同一个进程只能初始化一次,原因是init_ublock接口中会初始化DPDK,而DPDK初始化所分配的内存同进程PID绑定,一个PID只能绑定一块内存,且DPDK没有提供释放这块内存的接口,只能通过进程退出来释放。 | + | ublock_init | 本身是对init_ublock接口的宏定义,可理解为将ublock初始化为需要RPC服务。 | + | ublock_init_norpc | 本身是对init_ublock接口的宏定义,可理解为ublock初始化为无RPC服务。 | + +2. 根据业务需要,在另一个进程中调用HSAK UIO组件初始化接口。 + +3. 在ublock服务端进程或客户端进程调用如下接口进行相应的信息查询业务。 + + | 接口名称 | 功能描述 | + | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | + | ublock_get_bdevs | 业务进程通过调用本接口获取设备列表,获取的设备列表中只有PCI地址,不包含具体设备信息,需要获取具体设备信息,请调用接口ublock_get_bdev。 | + | ublock_get_bdev | 进程通过调用本接口获取具体某个设备的信息,设备信息中包括:设备的序列号、型号、fw版本号信息以字符数组形式保持,不是字符串形式。 | + | ublock_get_bdev_by_esn | 进程通过调用该接口,根据给定的ESN号获取对应设备的信息,设备信息中:序列号、型号、fw版本号。 | + | ublock_get_SMART_info | 进程通过调用本接口获取指定设备的SMART信息。 | + | ublock_get_SMART_info_by_esn | 进程通过调用本接口获取ESN号对应设备的SMART信息。 | + | ublock_get_error_log_info | 进程通过调用本接口获取设备的Error log信息。 | + | ublock_get_log_page | 进程通过调用本接口获取指定设备,指定log page的信息。 | + +4. 对于块设备列表,在获取相应信息后需要调用以下接口进行资源释放。 + + | 接口名称 | 功能描述 | + | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | + | ublock_free_bdevs | 进程通过调用本接口释放设备列表。 | + | ublock_free_bdev | 进程通过调用本接口释放设备资源。 | + +5. 最后如果退出程序,则需要销毁HSAK ublock模块(服务端和客户端销毁方法相同)。 + + | 接口名称 | 功能描述 | + | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | + | ublock_fini | 销毁ublock功能模块,本接口将销毁ublock模块以及内部创建的资源,本接口同ublock初始化接口需要配对使用。 | + +## 日志管理 + +HSAK的日志当前是通过syslog默认输出到/var/log/messages中,由操作系统的rsyslog服务管理。如果您需要自定义日志目录,可以通过rsyslog配置。 + +1. 首先需要在配置文件/etc/rsyslog.conf中增加如下修改: + + ```shell + if ($programname == 'LibStorage') then { + action(type="omfile" fileCreateMode="0600" file="/var/log/HSAK/run.log") + stop + } + ``` + +2. 重启rsyslog服务: + + ```shell + sysemctl restart rsyslog + ``` + +3. 启动HSAK进程,日志信息即重定向到对应目录。 + +4. 重定向日志如果需要转储,需要用户在/etc/logrotate.d/syslog文件中手动配置。 diff --git a/docs/en/25.03/Server/MemoryandStorage/HSAK/hsak_interface.md b/docs/en/25.03/Server/MemoryandStorage/HSAK/hsak_interface.md new file mode 100644 index 0000000000000000000000000000000000000000..ffaf50e8f60a0e2f6199806cb02f079c45248fb2 --- /dev/null +++ b/docs/en/25.03/Server/MemoryandStorage/HSAK/hsak_interface.md @@ -0,0 +1,2540 @@ +# HSAK 接口说明 + +## C接口 + +### 宏定义和枚举 + +#### bdev_rw.h + +##### enum libstorage_ns_lba_size + +1. 原型 + + ```sh + enum libstorage_ns_lba_size + { + LIBSTORAGE_NVME_NS_LBA_SIZE_512 = 0x9, + LIBSTORAGE_NVME_NS_LBA_SIZE_4K = 0xc + }; + ``` + +2. 描述 + +磁盘sector_size(数据)大小。 + +##### enum libstorage_ns_md_size + +1. 原型 + + ```shell + enum libstorage_ns_md_size + { + LIBSTORAGE_METADATA_SIZE_0 = 0, + LIBSTORAGE_METADATA_SIZE_8 = 8, + LIBSTORAGE_METADATA_SIZE_64 = 64 + }; + ``` + +2. 描述 + + 磁盘meta data(元数据) size大小。 + +3. 备注 + + - ES3000 V3(单端口)支持5种扇区类型的格式化(512+0,512+8,4K+64,4K,4K+8)。 + + - ES3000 V3(双端口)支持4种扇区类型的格式化(512+0,512+8,4K+64,4K)。 + + - ES3000 V5 支持5种扇区类型的格式化(512+0,512+8,4K+64,4K,4K+8)。 + + - Optane盘支持7种扇区类型的格式化(512+0,512+8,512+16,4K,4K+8,4K+64,4K+128)。 + +##### enum libstorage_ns_pi_type + +1. 原型 + + ```shell + enum libstorage_ns_pi_type + { + LIBSTORAGE_FMT_NVM_PROTECTION_DISABLE = 0x0, + LIBSTORAGE_FMT_NVM_PROTECTION_TYPE1 = 0x1, + LIBSTORAGE_FMT_NVM_PROTECTION_TYPE2 = 0x2, + LIBSTORAGE_FMT_NVM_PROTECTION_TYPE3 = 0x3, + }; + ``` + +2. 描述 + + 磁盘支持的保护类型。 + +3. 备注 + + ES3000仅支持保护类型0和保护类型3,Optane盘仅支持保护类型0和保护类型1。 + +##### enum libstorage_crc_and_prchk + +1. 原型 + + ```shell + enum libstorage_crc_and_prchk + { + LIBSTORAGE_APP_CRC_AND_DISABLE_PRCHK = 0x0, + LIBSTORAGE_APP_CRC_AND_ENABLE_PRCHK = 0x1, + LIBSTORAGE_LIB_CRC_AND_DISABLE_PRCHK = 0x2, + LIBSTORAGE_LIB_CRC_AND_ENABLE_PRCHK = 0x3, + # define NVME_NO_REF 0x4 + LIBSTORAGE_APP_CRC_AND_DISABLE_PRCHK_NO_REF = LIBSTORAGE_APP_CRC_AND_DISABLE_PRCHK | NVME_NO_REF, + LIBSTORAGE_APP_CRC_AND_ENABLE_PRCHK_NO_REF = LIBSTORAGE_APP_CRC_AND_ENABLE_PRCHK | NVME_NO_REF, + }; + ``` + +2. 描述 + + - LIBSTORAGE_APP_CRC_AND_DISABLE_PRCHK:应用层做CRC校验,HSAK不做CRC校验,关闭盘的CRC校验。 + + - LIBSTORAGE_APP_CRC_AND_ENABLE_PRCHK:应用层做CRC校验,HSAK不做CRC校验,开启盘的CRC校验。 + + - LIBSTORAGE_LIB_CRC_AND_DISABLE_PRCHK:应用层不做CRC校验,HSAK做CRC校验,关闭盘的CRC校验。 + + - LIBSTORAGE_LIB_CRC_AND_ENABLE_PRCHK:应用层不做CRC校验,HSAK做CRC校验,开启盘的CRC校验。 + + - LIBSTORAGE_APP_CRC_AND_DISABLE_PRCHK_NO_REF:应用层做CRC校验,HSAK不做CRC校验,关闭盘的CRC校验。对于PI TYPE为1的磁盘(Intel optane P4800),关闭盘的REF TAG校验。 + + - LIBSTORAGE_APP_CRC_AND_ENABLE_PRCHK_NO_REF:应用层做CRC校验,HSAK不做CRC校验,开启盘的CRC校验。对于PI TYPE为1的磁盘(Intel optane P4800),关闭盘的REF TAG校验。 + + - Intel optane P4800盘PI TYPE为1,默认会校验元数据区的CRC和REF TAG。 + + - Intel optane P4800盘的512+8格式支持DIF,4096+64格式不支持。 + + - ES3000 V3和ES3000 V5盘PI TYPE为3,默认只校验元数据区的CRC。 + + - ES3000 V3的512+8格式支持DIF,4096+64格式不支持。ES3000 V5的512+8和4096+64格式均支持DIF。 + + 总结为如下: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
端到端校验方式ctrlflagCRC生成者写流程读流程
应用校验HSAK校验CRC盘校验CRC应用校验HSAK校验CRC盘校验CRC
半程保护0控制器XXXXXX
1控制器XXXXX
2控制器XXXXXX
3控制器XXXXX
全程保护0APPXXXX
1APPXX
2HSAKXXXX
3HSAKXX
+ +##### enum libstorage_print_log_level + +1. 原型 + + ```shell + enum libstorage_print_log_level + { + LIBSTORAGE_PRINT_LOG_ERROR, + LIBSTORAGE_PRINT_LOG_WARN, + LIBSTORAGE_PRINT_LOG_NOTICE, + LIBSTORAGE_PRINT_LOG_INFO, + LIBSTORAGE_PRINT_LOG_DEBUG, + }; + ``` + +2. 描述 + + SPDK日志打印级别:ERROR、WARN、NOTICE、INFO、DEBUG,分别对应配置文件中的0~4。 + +##### MAX_BDEV_NAME_LEN + +1. 原型 + + ```bash + # define MAX_BDEV_NAME_LEN 24 + ``` + +2. 描述 + + 块设备名最大长度限制。 + +##### MAX_CTRL_NAME_LEN + +1. 原型 + + ```bash + # define MAX_CTRL_NAME_LEN 16 + ``` + +2. 描述 + + 控制器名最大长度限制。 + +##### LBA_FORMAT_NUM + +1. 原型 + + ```bash + # define LBA_FORMAT_NUM 16 + ``` + +2. 描述 + + 控制器所支持的LBA格式数目。 + +##### LIBSTORAGE_MAX_DSM_RANGE_DESC_COUNT + +1. 原型 + + ```bash + # define LIBSTORAGE_MAX_DSM_RANGE_DESC_COUNT 256 + ``` + +2. 描述 + + 数据集管理命令中16字节集的最大数目。 + +#### ublock.h + +##### UBLOCK_NVME_UEVENT_SUBSYSTEM_UIO + +1. 原型 + + ```bash + # define UBLOCK_NVME_UEVENT_SUBSYSTEM_UIO 1 + ``` + +2. 描述 + + 用于定义uevent事件所对应的子系统是内核uio,在业务收到uevent事件时,通过该宏定义判断是否为需要处理的内核uio事件。 + + 数据结构struct ublock_uevent中成员int subsystem的值取值为UBLOCK_NVME_UEVENT_SUBSYSTEM_UIO,当前仅此一个可选值。 + +##### UBLOCK_TRADDR_MAX_LEN + +1. 原型 + + ```bash + # define UBLOCK_TRADDR_MAX_LEN 256 + ``` + +2. 描述 + + 以"域:总线:设备.功能"(%04x:%02x:%02x.%x)格式表示的PCI地址字符串的最大长度,其实实际长度远小于256字节。 + +##### UBLOCK_PCI_ADDR_MAX_LEN + +1. 原型 + + ```bash + # define UBLOCK_PCI_ADDR_MAX_LEN 256 + ``` + +2. 描述 + + PCI地址字符串最大长度,实际长度远小于256字节;此处PCI地址格式可能的形式为: + + - 全地址:%x:%x:%x.%x 或 %x.%x.%x.%x。 + + - 功能值为0:%x:%x:%x。 + + - 域值为0:%x:%x.%x 或 %x.%x.%x。 + + - 域和功能值为0:%x:%x 或 %x.%x。 + +##### UBLOCK_SMART_INFO_LEN + +1. 原型 + + ```bash + # define UBLOCK_SMART_INFO_LEN 512 + ``` + +2. 描述 + + 获取NVMe盘SMART信息结构体的大小,为512字节。 + +##### enum ublock_rpc_server_status + +1. 原型 + + ```bash + enum ublock_rpc_server_status { + // start rpc server or not + UBLOCK_RPC_SERVER_DISABLE = 0, + UBLOCK_RPC_SERVER_ENABLE = 1, + }; + ``` + +2. 描述 + + 用于表示HSAK内部RPC服务状态,启用或关闭。 + +##### enum ublock_nvme_uevent_action + +1. 原型 + + ```bash + enum ublock_nvme_uevent_action { + UBLOCK_NVME_UEVENT_ADD = 0, + UBLOCK_NVME_UEVENT_REMOVE = 1, + UBLOCK_NVME_UEVENT_INVALID, + }; + ``` + +2. 描述 + + 用于表示uevent热插拔事件是插入硬盘还是移除硬盘。 + +##### enum ublock_subsystem_type + +1. 原型 + + ```bash + enum ublock_subsystem_type { + SUBSYSTEM_UIO = 0, + SUBSYSTEM_NVME = 1, + SUBSYSTEM_TOP + }; + ``` + +2. 描述 + + 指定回调函数类型,用于区分产品注册回调函数时是针对于uio驱动还是针对于内核nvme驱动。 + +### 数据结构 + +#### bdev_rw.h + +##### struct libstorage_namespace_info + +1. 原型 + + ```conf + struct libstorage_namespace_info + { + char name[MAX_BDEV_NAME_LEN]; + uint64_t size; /** namespace size in bytes */ + uint64_t sectors; /** number of sectors */ + uint32_t sector_size; /** sector size in bytes */ + uint32_t md_size; /** metadata size in bytes */ + uint32_t max_io_xfer_size; /** maximum i/o size in bytes */ + uint16_t id; /** namespace id */ + uint8_t pi_type; /** end-to-end data protection information type */ + uint8_t is_active :1; /** namespace is active or not */ + uint8_t ext_lba :1; /** namespace support extending LBA size or not */ + uint8_t dsm :1; /** namespace supports Dataset Management or not */ + uint8_t pad :3; + uint64_t reserved; + }; + ``` + +2. 描述 + + 该数据结构中包含硬盘namespace相关信息。 + +3. 结构体成员 + + | **成员** | 描述 | + |------------------------------|------------------------------------------------| + | char name[MAX_BDEV_NAME_LEN] | Namespace名字 | + | uint64_t size | 该namespace所分配的硬盘大小,字节为单位 | + | uint64_t sectors | 扇区数 | + | uint32_t sector_size | 每扇区大小,字节为单位 | + | uint32_t md_size | Metadata大小,字节为单位 | + | uint32_t max_io_xfer_size | 最大允许的单次IO操作数据大小,字节为单位 | + | uint16_t id | Namespace ID | + | uint8_t pi_type | 数据保护类型,取值自enum libstorage_ns_pi_type | + | uint8_t is_active :1 | Namespace是否激活 | + | uint8_t ext_lba :1 | Namespace是否支持扩展LBA | + | uint8_t dsm :1 | Namespace是否支持数据集管理 | + | uint8_t pad :3 | 保留字段 | + | uint64_t reserved | 保留字段 | + +##### struct libstorage_nvme_ctrlr_info + +1. 原型 + + ```conf + struct libstorage_nvme_ctrlr_info + { + char name[MAX_CTRL_NAME_LEN]; + char address[24]; + struct + { + uint32_t domain; + uint8_t bus; + uint8_t dev; + uint8_t func; + } pci_addr; + uint64_t totalcap; /* Total NVM Capacity in bytes */ + uint64_t unusecap; /* Unallocated NVM Capacity in bytes */ + int8_t sn[20]; /* Serial number */ + uint8_t fr[8]; /* Firmware revision */ + uint32_t max_num_ns; /* Number of namespaces */ + uint32_t version; + uint16_t num_io_queues; /* num of io queues */ + uint16_t io_queue_size; /* io queue size */ + uint16_t ctrlid; /* Controller id */ + uint16_t pad1; + struct + { + struct + { + /** metadata size */ + uint32_t ms : 16; + /** lba data size */ + uint32_t lbads : 8; + uint32_t reserved : 8; + } lbaf[LBA_FORMAT_NUM]; + uint8_t nlbaf; + uint8_t pad2[3]; + uint32_t cur_format : 4; + uint32_t cur_extended : 1; + uint32_t cur_pi : 3; + uint32_t cur_pil : 1; + uint32_t cur_can_share : 1; + uint32_t mc_extented : 1; + uint32_t mc_pointer : 1; + uint32_t pi_type1 : 1; + uint32_t pi_type2 : 1; + uint32_t pi_type3 : 1; + uint32_t md_start : 1; + uint32_t md_end : 1; + uint32_t ns_manage : 1; /* Supports the Namespace Management and Namespace Attachment commands */ + uint32_t directives : 1; /* Controller support Directives or not */ + uint32_t streams : 1; /* Controller support Streams Directives or not */ + uint32_t dsm : 1; /* Controller support Dataset Management or not */ + uint32_t reserved : 11; + } cap_info; + }; + ``` + +2. 描述 + + 该数据结构中包含硬盘控制器相关信息。 + +3. 结构体成员 + + | **成员** | **描述** | + |----------|----------| + | char name[MAX_CTRL_NAME_LEN] | 控制器名字 | + | char address[24] | PCI地址,字符串形式 | + | struct
{
uint32_t domain;
uint8_t bus;
uint8_t dev;
uint8_t func;
} pci_addr | PCI地址,分段形式 | + | uint64_t totalcap | 控制器的总容量大小(字节为单位)Optane盘基于NVMe 1.0协议,不支持该字段 | + | uint64_t unusecap | 控制器未使用的容量大小(字节为单位)Optane盘基于NVMe 1.0协议,不支持该字段 | + | int8_t sn[20]; | 硬盘序列号。不带'0'的ASCII字符串 | + | uint8_t fr[8]; | 硬盘firmware版本号。不带'0'的ASCII字符串 | + | uint32_t max_num_ns | 最大允许的namespace数 | + | uint32_t version | 控制器支持的NVMe标准协议版本号 | + | uint16_t num_io_queues | 硬盘支持的IO队列数量 | + | uint16_t io_queue_size | IO队列最大深度 | + | uint16_t ctrlid | 控制器ID | + | uint16_t pad1 | 保留字段 | + + struct cap_info子结构体成员: + + | **成员** | **描述** | + |-----------------------------------|------------------------------------| + | struct
{
uint32_t ms : 16;
uint32_t lbads : 8;
uint32_t reserved : 8;
}lbaf[LBA_FORMAT_NUM] | ms:元数据大小,最小为8字节
lbads:指示LBA大小为2^lbads,lbads不小于9 | + | uint8_t nlbaf | 控制器所支持的LBA格式数 | + | uint8_t pad2[3] | 保留字段 | + | uint32_t cur_format : 4 | 控制器当前的LBA格式 | + | uint32_t cur_extended : 1 | 控制器当前是否支持扩展型LBA | + | uint32_t cur_pi : 3 | 控制器当前的保护类型 | + | uint32_t cur_pil : 1 | 控制器当前的PI(保护信息)位于元数据的first eight bytes或者last eight bytes | + | uint32_t cur_can_share : 1 | namespace是否支持多路径传输 | + | uint32_t mc_extented : 1 | 元数据是否作为数据缓冲区的一部分进行传输 | + | uint32_t mc_pointer : 1 | 元数据是否与数据缓冲区分离 | + | uint32_t pi_type1 : 1 | 控制器是否支持保护类型一 | + | uint32_t pi_type2 : 1 | 控制器是否支持保护类型二 | + | uint32_t pi_type3 : 1 | 控制器是否支持保护类型三 | + | uint32_t md_start : 1 | 控制器是否支持PI(保护信息)位于元数据的first eight bytes | + | uint32_t md_end : 1 | 控制器是否支持PI(保护信息)位于元数据的last eight bytes | + | uint32_t ns_manage : 1 | 控制器是否支持namespace管理 | + | uint32_t directives : 1 | 是否支持Directives命令集 | + | uint32_t streams : 1 | 是否支持Streams Directives | + | uint32_t dsm : 1 | 是否支持Dataset Management命令 | + | uint32_t reserved : 11 | 保留字段 | + +##### struct libstorage_dsm_range_desc + +1. 原型 + + ```bash + struct libstorage_dsm_range_desc + { + /* RESERVED */ + uint32_t reserved; + + /* NUMBER OF LOGICAL BLOCKS */ + uint32_t block_count; + + /* UNMAP LOGICAL BLOCK ADDRESS */uint64_t lba;}; + ``` + +2. 描述 + + 数据管理命令集中单个16字节集的定义。 + +3. 结构体成员 + + | **成员** | **描述** | + |----------------------|--------------| + | uint32_t reserved | 保留字段 | + | uint32_t block_count | 单位LBA的数量 | + | uint64_t lba | 起始LBA | + +##### struct libstorage_ctrl_streams_param + +1. 原型 + + ```bash + struct libstorage_ctrl_streams_param + { + /* MAX Streams Limit */ + uint16_t msl; + + /* NVM Subsystem Streams Available */ + uint16_t nssa; + + /* NVM Subsystem Streams Open */uint16_t nsso; + + uint16_t pad; + }; + ``` + +2. 描述 + + NVMe盘支持的Streams属性值。 + +3. 结构体成员 + + | **成员** | **描述** | + |---------------|--------------------------------------| + | uint16_t msl | 硬盘支持的最大Streams资源数 | + | uint16_t nssa | 每个NVM子系统可使用的Streams资源数 | + | uint16_t nsso | 每个NVM子系统已经使用的Streams资源数 | + | uint16_t pad | 保留字段 | + +##### struct libstorage_bdev_streams_param + +1. 原型 + + ```bash + struct libstorage_bdev_streams_param + { + /* Stream Write Size */ + uint32_t sws; + + /* Stream Granularity Size */ + uint16_t sgs; + + /* Namespace Streams Allocated */ + uint16_t nsa; + + /* Namespace Streams Open */ + uint16_t nso; + + uint16_t reserved[3]; + }; + ``` + +2. 描述 + + Namespace的Streams属性值。 + +3. 结构体成员 + + |**成员** | **描述** | + |-------------------------|---------------------------------| + |uint32_t sws |性能最优的写粒度,单位:sectors| + |uint16_t sgs |Streams分配的写粒度,单位:sws| + |uint16_t nsa |Namespace可使用的私有Streams资源数| + |uint16_t nso |Namespace已使用的私有Streams资源数| + |uint16_t reserved[3] |保留字段| + +##### struct libstorage_mgr_info + +1. 原型 + + ```bash + struct libstorage_mgr_info + { + char pci[24]; + char ctrlName[MAX_CTRL_NAME_LEN]; + uint64_t sector_size; + uint64_t cap_size; + uint16_t device_id; + uint16_t subsystem_device_id; + uint16_t vendor_id; + uint16_t subsystem_vendor_id; + uint16_t controller_id; + int8_t serial_number[20]; + int8_t model_number[40]; + uint8_t firmware_revision[8]; + }; + ``` + +2. 描述 + + 磁盘管理信息(与管理面使用的磁盘信息一致)。 + +3. 结构体成员 + + |**成员** | **描述**| + |-------------------------|------------------------------------| + |char pci[24] |磁盘PCI地址字符串| + |char ctrlName[MAX_CTRL_NAME_LEN] |磁盘控制器名字符串| + |uint64_t sector_size |磁盘扇区大小| + |uint64_t cap_size |磁盘容量,单位:字节| + |uint16_t device_id |磁盘设备ID| + |uint16_t subsystem_device_id |磁盘子系统设备ID| + |uint16­_t vendor_id |磁盘厂商ID| + |uint16_t subsystem_vendor_id |磁盘子系统厂商ID| + |uint16_t controller_id |磁盘控制器ID| + |int8_t serial_number[20] |磁盘序列号| + |int8_t model_number[40] |设备型号| + |uint8_t firmware_revision[8] |固件版本号| + +##### struct __attribute__((packed)) libstorage_smart_info + +1. 原型 + + ```bash + /* same with struct spdk_nvme_health_information_page in nvme_spec.h */ + struct __attribute__((packed)) libstorage_smart_info { + /* details of uint8_t critical_warning + + union spdk_nvme_critical_warning_state { + + uint8_t raw; + * + + struct { + + uint8_t available_spare : 1; + + uint8_t temperature : 1; + + uint8_t device_reliability : 1; + + uint8_t read_only : 1; + + uint8_t volatile_memory_backup : 1; + + uint8_t reserved : 3; + + } bits; + + }; + */ + uint8_t critical_warning; + uint16_t temperature; + uint8_t available_spare; + uint8_t available_spare_threshold; + uint8_t percentage_used; + uint8_t reserved[26]; + + /* + + Note that the following are 128-bit values, but are + + defined as an array of 2 64-bit values. + */ + /* Data Units Read is always in 512-byte units. */ + uint64_t data_units_read[2]; + /* Data Units Written is always in 512-byte units. */ + uint64_t data_units_written[2]; + /* For NVM command set, this includes Compare commands. */ + uint64_t host_read_commands[2]; + uint64_t host_write_commands[2]; + /* Controller Busy Time is reported in minutes. */ + uint64_t controller_busy_time[2]; + uint64_t power_cycles[2]; + uint64_t power_on_hours[2]; + uint64_t unsafe_shutdowns[2]; + uint64_t media_errors[2]; + uint64_t num_error_info_log_entries[2]; + /* Controller temperature related. */ + uint32_t warning_temp_time; + uint32_t critical_temp_time; + uint16_t temp_sensor[8]; + uint8_t reserved2[296]; + }; + ``` + +2. 描述 + + 该数据结构定义了硬盘SMART INFO信息内容。 + +3. 结构体成员 + + | **成员** | **描述(具体可以参考NVMe协议)** | + |-----------------------------------|------------------------------------| + | uint8_t critical_warning | 该域表示控制器状态的重要的告警,bit位设置为1表示有效,可以设置
多个bit位有效。重要的告警信息通过异步事件返回给主机端。
Bit0:设置为1时表示冗余空间小于设定的阈值
Bit1:设置为1时表示温度超过或低于一个重要的阈值
Bit2:设置为1时表示由于重要的media错误或者internal error,器件的可靠性已经降低。
Bit3:设置为1时,该介质已经被置为只读模式。
Bit4:设置为1时,表示控制器的易失性器件fail,该域仅在控制器内部存在易失性器件时有效。
Bit 5~7:保留 | + | uint16_t temperature | 表示整个器件的温度,单位为Kelvin。 | + | uint8_t available_spare | 表示可用冗余空间的百分比(0到100%)。 | + | uint8_t available_spare_threshold | 可用冗余空间的阈值,低于该阈值时上报异步事件。 | + | uint8_t percentage_used | 该值表示用户实际使用和厂家设定的器件寿命的百分比,100表示已经达
到厂家预期的寿命,但可能不会失效,可以继续使用。该值允许大于100
,高于254的值都会被置为255。 | + | uint8_t reserved[26] | 保留 | + | uint64_t data_units_read[2] | 该值表示主机端从控制器中读走的512字节数目,其中1表示读走100
0个512字节,该值不包括metadata。当LBA大小不为512
B时,控制器将其转换成512B进行计算。16进制表示。 | + | uint64_t data_units_written[2] | 该值表示主机端写入控制器中的512字节数目,其中1表示写入1000
个512字节,该值不包括metadata。当LBA大小不为512B
时,控制器将其转换成512B进行计算。16进制表示。 | + | uint64_t host_read_commands[2] | 表示下发到控制器的读命令的个数。 | + | uint64_t host_write_commands[2] | 表示下发到控制器的写命令的个数 | + | uint64_t controller_busy_time[2] | 表示控制器处理I/O命令的busy时间,从命令下发SQ到完成命令返回到CQ的整个过程都为busy。该值以分钟为单位。 | + | uint64_t power_cycles[2] | 上下电次数。 | + | uint64_t power_on_hours[2] | power-on时间小时数。 | + | uint64_t unsafe_shutdowns[2] | 异常关机次数,掉电时仍未接收到CC.SHN时该值加1。 | + | uint64_t media_errors[2] | 表示控制器检测到不可恢复的数据完整性错误的次数,
其中包括不可纠的ECC错误,CRC错误,LBA tag不匹配。 | + | uint64_t num_error_info_log_entries[2] | 该域表示控制器生命周期内的错误信息日志的entry数目。 | + | uint32_t warning_temp_time | 温度超过warning告警值的累积时间,单位分钟。 | + | uint32_t critical_temp_time | 温度超过critical告警值的累积时间,单位分钟。 | + | uint16_t temp_sensor[8] | 温度传感器1~8的温度值,单位Kelvin。 | + | uint8_t reserved2[296] | 保留 | + +##### libstorage_dpdk_contig_mem + +1. 原型 + + ```bash + struct libstorage_dpdk_contig_mem { + uint64_t virtAddr; + uint64_t memLen; + uint64_t allocLen; + }; + ``` + +2. 描述 + + DPDK内存初始化之后,通知业务层初始化完成的回调函数参数中描述一段连续虚拟内存的信息。 + + 当前HSAK预留了800M内存,其他内存通过该结构体中的allocLen返回给业务层,用于业务层申请内存自行管理。 + + HSAK需要预留的总内存是800M左右,每一个内存段上预留的内存是根据环境的NUMA节点数来计算的。在NUMA节点过多时,每个内存段上预留的内存过小,会导致HSAK初始化失败。因此HSAK只支持最多4个NUMA节点的环境。 + +3. 结构体成员 + + | **成员** | **描述** | + |--------------------|----------------------| + |uint64_t virtAddr |虚拟内存起始地址。| + |uint64_t memLen |虚拟内存长度,单位:字节。| + |uint64_t allocLen |该内存段中可用的内存长度,单位:字节。| + +##### struct libstorage_dpdk_init_notify_arg + +1. 原型 + + ```bash + struct libstorage_dpdk_init_notify_arg { + uint64_t baseAddr; + uint16_t memsegCount; + struct libstorage_dpdk_contig_mem *memseg; + }; + ``` + +2. 描述 + + 用于DPDK内存初始化之后,通知业务层初始化完成的回调函数参数,表示所有虚拟内存段信息。 + +3. 结构体成员 + + | **成员** | **描述**| + |------------------------|-----------------------| + |uint64_t baseAddr |虚拟内存起始地址。| + |uint16_t memsegCount |有效的'memseg'数组成员个数,即连续的虚拟内存段的段数。| + |struct libstorage_dpdk_contig_mem *memseg |指向内存段数组的指针,每个数组元素都是一段连续的虚拟内存,两两元素之间是不连续的。| + +##### struct libstorage_dpdk_init_notify + +1. 原型 + + ```bash + struct libstorage_dpdk_init_notify { + const char *name; + void (*notifyFunc)(const struct libstorage_dpdk_init_notify_arg *arg); + TAILQ_ENTRY(libstorage_dpdk_init_notify) tailq; + }; + ``` + +2. 描述 + + 用于DPDK内存初始化之后,通知业务层回调函数注册的结构体。 + +3. 结构体成员 + + | **成员** | **描述**| + |-------------------------------|--------------------------| + |const char *name |注册的回调函数的业务层模块名字。| + |void (*notifyFunc)(const struct libstorage_dpdk_init_notify_arg*arg) |DPDK内存初始化之后,通知业务层初始化完成的回调函数参数。| + |TAILQ_ENTRY(libstorage_dpdk_init_notify) tailq |存放回调函数注册的链表。| + +#### ublock.h + +##### struct ublock_bdev_info + +1. 原型 + + ```bash + struct ublock_bdev_info { + uint64_t sector_size; + uint64_t cap_size; // cap_size + uint16_t device_id; + uint16_t subsystem_device_id; // subsystem device id of nvme control + uint16_t vendor_id; + uint16_t subsystem_vendor_id; + uint16_t controller_id; + int8_t serial_number[20]; + int8_t model_number[40]; + int8_t firmware_revision[8]; + }; + ``` + +2. 描述 + + 该数据结构中包含硬盘设备信息。 + +3. 结构体成员 + + | **成员** | **描述**| + |------------------|------------| + |uint64_t sector_size |硬盘扇区大小,比如512字节 | + |uint64_t cap_size |硬盘总容量,字节为单位 | + |uint16_t device_id |设备id号 | + |uint16_t subsystem_device_id |子系统的设备id号 | + |uint16_t vendor_id |设备厂商主id号 | + |uint16_t subsystem_vendor_id |设备厂商子id号 | + |uint16_t controller_id |设备控制器id号 | + |int8_t serial_number[20] |设备序列号 | + |int8_t model_number[40] |设备型号 | + |int8_t firmware_revision[8] |固件版本号 | + +##### struct ublock_bdev + +1. 原型 + + ```bash + struct ublock_bdev { + char pci[UBLOCK_PCI_ADDR_MAX_LEN]; + struct ublock_bdev_info info; + struct spdk_nvme_ctrlr *ctrlr; + TAILQ_ENTRY(ublock_bdev) link; + }; + ``` + +2. 描述 + + 该数据结构中包含指定PCI地址的硬盘信息,而结构本身为队列的一个节点。 + +3. 结构体成员 + + |**成员** | **描述** | + |-----------------------------------|----------------------------------------------------------------------------------------------------| + |char pci[UBLOCK_PCI_ADDR_MAX_LEN] | PCI地址 | + |struct ublock_bdev_info info | 硬盘设备信息 | + |struct spdk_nvme_ctrlr *ctrlr | 设备控制器数据结构,该结构体内成员不对外开放,外部业务可通过SPDK开源接口获取相应成员数据。 | + |TAILQ_ENTRY(ublock_bdev) link | 队列前后指针结构体 | + +##### struct ublock_bdev_mgr + +1. 原型 + + ```bash + struct ublock_bdev_mgr { + TAILQ_HEAD(, ublock_bdev) bdevs; + }; + ``` + +2. 描述 + + 该数据结构内定义了一个ublock_bdev队列的头结构。 + +3. 结构体成员 + + |**成员** | **描述** | + |---------------------------------|------------------| + |TAILQ_HEAD(, ublock_bdev) bdevs; | 队列头结构体 | + +##### struct __attribute__((packed)) ublock_SMART_info + +1. 原型 + + ```bash + struct __attribute__((packed)) ublock_SMART_info { + uint8_t critical_warning; + uint16_t temperature; + uint8_t available_spare; + uint8_t available_spare_threshold; + uint8_t percentage_used; + uint8_t reserved[26]; + /* + + Note that the following are 128-bit values, but are + + defined as an array of 2 64-bit values. + */ + /* Data Units Read is always in 512-byte units. */ + uint64_t data_units_read[2]; + /* Data Units Written is always in 512-byte units. */ + uint64_t data_units_written[2]; + /* For NVM command set, this includes Compare commands. */ + uint64_t host_read_commands[2]; + uint64_t host_write_commands[2]; + /* Controller Busy Time is reported in minutes. */ + uint64_t controller_busy_time[2]; + uint64_t power_cycles[2]; + uint64_t power_on_hours[2]; + uint64_t unsafe_shutdowns[2]; + uint64_t media_errors[2]; + uint64_t num_error_info_log_entries[2]; + /* Controller temperature related. */ + uint32_t warning_temp_time; + uint32_t critical_temp_time; + uint16_t temp_sensor[8]; + uint8_t reserved2[296]; + }; + ``` + +2. 描述 + + 该数据结构定义了硬盘SMART INFO信息内容。 + +3. 结构体成员 + + | **成员** | **描述(具体可以参考NVMe协议)** | + |-----------------------------------|-----------------------------------| + | uint8_t critical_warning | 该域表示控制器状态的重要的告警,bit位设置为1表示有效,可以设置
多个bit位有效。重要的告警信息通过异步事件返回给主机端。
Bit0:设置为1时表示冗余空间小于设定的阈值
Bit1:设置为1时表示温度超过或低于一个重要的阈值
Bit2:设置为1时表示由于重要的media错误或者internal error,器件的可靠性已经降低。
Bit3:设置为1时,该介质已经被置为只读模式。
Bit4:设置为1时,表示控制器的易失性器件fail,该域仅在控制器内部存在易失性器件时有效。
Bit 5~7:保留 | + | uint16_t temperature | 表示整个器件的温度,单位为Kelvin。 | + | uint8_t available_spare | 表示可用冗余空间的百分比(0到100%)。 | + | uint8_t available_spare_threshold | 可用冗余空间的阈值,低于该阈值时上报异步事件。 | + | uint8_t percentage_used | 该值表示用户实际使用和厂家设定的器件寿命的百分比,100表示已经达
到厂家预期的寿命,但可能不会失效,可以继续使用。该值允许大于100
,高于254的值都会被置为255。 | + | uint8_t reserved[26] | 保留 | + | uint64_t data_units_read[2] | 该值表示主机端从控制器中读走的512字节数目,其中1表示读走100
0个512字节,该值不包括metadata。当LBA大小不为512B
时,控制器将其转换成512B进行计算。16进制表示。 | + | uint64_t data_units_written[2] | 该值表示主机端写入控制器中的512字节数目,其中1表示写入1000
个512字节,该值不包括metadata。当LBA大小不为512B
时,控制器将其转换成512B进行计算。16进制表示。 | + | uint64_t host_read_commands[2] | 表示下发到控制器的读命令的个数。 | + | uint64_t host_write_commands[2] | 表示下发到控制器的写命令的个数 | + | uint64_t controller_busy_time[2] | 表示控制器处理I/O命令的busy时间,从命令下发SQ到完成命令返回到CQ的整个过程都为busy。该值以分钟为单位。| + | uint64_t power_cycles[2] | 上下电次数。 | + | uint64_t power_on_hours[2] | power-on时间小时数。 | + | uint64_t unsafe_shutdowns[2] | 异常关机次数,掉电时仍未接收到CC.SHN时该值加1。 | + | uint64_t media_errors[2] | 表示控制器检测到不可恢复的数据完整性错误的次数,其中包括不可纠的E
CC错误,CRC错误,LBA
tag不匹配。 | + | uint64_t num_error_info_log_entries[2] | 该域表示控制器生命周期内的错误信息日志的entry数目。 | + | uint32_t warning_temp_time | 温度超过warning告警值的累积时间,单位分钟。 | + | uint32_t critical_temp_time | 温度超过critical告警值的累积时间,单位分钟。 | + | uint16_t temp_sensor[8] | 温度传感器1~8的温度值,单位Kelvin。 | + | uint8_t reserved2[296] | 保留 | + +##### struct ublock_nvme_error_info + +1. 原型 + + ```bash + struct ublock_nvme_error_info { + uint64_t error_count; + uint16_t sqid; + uint16_t cid; + uint16_t status; + uint16_t error_location; + uint64_t lba; + uint32_t nsid; + uint8_t vendor_specific; + uint8_t reserved[35]; + }; + ``` + +2. 描述 + + 该数据结构中包含设备控制器中单条错误信息具体内容,不同控制器可支持的错误条数可能不同。 + +3. 结构体成员 + + |**成员** | **描述(具体可以参考NVMe协议)** | + |------------------------|----------------------------------------------------------------------------------------------------------------------------------------| + |uint64_t error_count | Error序号,累增。 | + |uint16_t sqid | 此字段指示与错误信息关联的命令的提交队列标识符。如果错误无法关联特定命令,则该字段应设置为FFFFh。 | + |uint16_t cid | 此字段指示与错误信息关联的命令标识符。如果错误无法关联特定命令,则该字段应设置为FFFFh。 | + |uint16_t status | 此字段指示已完成命令的"状态字段"。 | + |uint16_t error_location | 此字段指示与错误信息关联的命令参数。 | + |uint64_t lba | 该字段表示遇到错误情况的第一个LBA。 | + |uint32_t nsid | 该字段表示遇到错误情况的namespace。 | + |uint8_t vendor_specific | 如果有其他供应商特定的错误信息可用,则此字段提供与该页面关联的日志页面标识符。 值00h表示没有可用的附加信息。有效值的范围为80h至FFh。 | + |uint8_t reserved[35] | 保留 | + +##### struct ublock_uevent + +1. 原型 + + ```bash + struct ublock_uevent { + enum ublock_nvme_uevent_action action; + int subsystem; + char traddr[UBLOCK_TRADDR_MAX_LEN + 1]; + }; + ``` + +2. 描述 + + 该数据结构中包含用于表示uevent事件的相关参数。 + +3. 结构体成员 + + | **成员** | **描述** | + |----------------------------------------|-------------------------------------------------------------------------------------------------------------------------| + | enum ublock_nvme_uevent_action action | 通过枚举,表示uevent事件类型为插入硬盘,还是移除硬盘。 | + | int subsystem | 表示uevent事件的子系统类型,当前仅支持UBLOCK_NVME_UEVENT_SUBSYSTEM_UIO,如果应用程序收到其他值,则可不处理。 | + | char traddr[UBLOCK_TRADDR_MAX_LEN + 1] | 以"域:总线:设备.功能"(%04x:%02x:%02x.%x)格式表示的PCI地址字符串。 | + +##### struct ublock_hook + +1. 原型 + + ```bash + struct ublock_hook + { + ublock_callback_func ublock_callback; + void *user_data; + }; + ``` + +2. 描述 + + 该数据结构用于注册回调函数。 + +3. 结构体成员 + + | **成员** | **描述** | + |---------------------------------------|---------------------------------------------------------------------------| + | ublock_callback_func ublock_callback | 表示回调时执行的函数,类型为bool func(void *info, void*user_data). | + | void *user_data | 传给回调函数的用户参数 | + +##### struct ublock_ctrl_iostat_info + +1. 原型 + + ```bash + struct ublock_ctrl_iostat_info + { + uint64_t num_read_ops; + uint64_t num_write_ops; + uint64_t read_latency_ms; + uint64_t write_latency_ms; + uint64_t io_outstanding; + uint64_t num_poll_timeout; + uint64_t io_ticks_ms; + }; + ``` + +2. 描述 + + 该数据结构用于获取控制器的IO统计信息。 + +3. 结构体成员 + + | **成员** | **描述** | + |-----------------------------|---------------------------------------------| + | uint64_t num_read_ops | 获取的该控制器的读IO个数(累加值) | + | uint64_t num_write_ops | 获取的该控制器的写IO个数(累加值) | + | uint64_t read_latency_ms | 获取的该控制器的读时延(累加值,ms) | + | uint64_t write_latency_ms | 获取的该控制器的写时延(累加值,ms) | + | uint64_t io_outstanding | 获取的该控制器的队列深度 | + | uint64_t num_poll_timeout | 获取的该控制器的轮询超时次数(累加值) | + | uint64_t io_ticks_ms | 获取的该控制器的IO处理时延(累加值,ms) | + +### API + +#### bdev_rw.h + +##### libstorage_get_nvme_ctrlr_info + +1. 接口原型 + + uint32_t libstorage_get_nvme_ctrlr_info(struct libstorage_nvme_ctrlr_info** ppCtrlrInfo); + +2. 接口描述 + + 获取所有控制器信息。 + +3. 参数 + + | **参数成员** | **描述** | + |-----------------------------------|-----------------------------------| + | struct libstorage_nvme_ctrlr_info** ppCtrlrInfo| 出参,返回所有获取到的控制器信息。
说明:
使用后务必通过free接口释放内存。 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|----------------------------------------------| + | 0 | 控制器信息获取失败,或未获取到任何控制器信息 | + | 大于0 | 获取到的控制器个数 | + +##### libstorage_get_mgr_info_by_esn + +1. 接口原型 + + ```bash + int32_t libstorage_get_mgr_info_by_esn(const char *esn, struct libstorage_mgr_info *mgr_info); + ``` + +2. 接口描述 + + 数据面获取设备序列号(ESN)对应的NVMe磁盘的管理信息。 + +3. 参数 + + | **参数成员** | **描述** | + |---------------------------|----------------------------------------------| + | const char *esn | 被查询设备的ESN号
说明:
ESN号是最大有效长度为20的字符串(不包括字符串结束符),但该长
度根据不同硬件厂商可能存在差异,如不足20字符,需要在字符串末尾加
空格补齐。 | + | struct libstorage_mgr_info *mgr_info | 出参,返回所有获取到的NVMe磁盘管理信息。 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|------------------------------------------| + | 0 | 查询ESN对应的NVMe磁盘管理信息成功。 | + | -1 | 查询ESN对应的NVMe磁盘管理信息失败。 | + | -2 | 未获取到任何匹配ESN的NVMe磁盘。 | + +##### libstorage_get_mgr_smart_by_esn + +1. 接口原型 + + ```bash + int32_t libstorage_get_mgr_smart_by_esn(const char *esn, uint32_t nsid, struct libstorage_smart_info *mgr_smart_info); + ``` + +2. 接口描述 + + 数据面获取设备序列号(ESN)对应的NVMe磁盘的SMART信息。 + +3. 参数 + + | **参数成员** | **描述** | + |-------------------------------|------------------------------------------| + | const char *esn | 被查询设备的ESN号
说明:
ESN号是最大有效长度为20的字符串(不包括字符串结束符),但该长
度根据不同硬件厂商可能存在差异,如不足20字符,需要在字符串末尾加
空格补齐。 | + | uint32_t nsid | 指定的namespace | + | struct libstorage_mgr_info *mgr_info | 出参,返回所有获取到的NVMe磁盘SMART信息。 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|---------------------------------------| + | 0 | 查询ESN对应的NVMe磁盘SMART信息成功。 | + | -1 | 查询ESN对应的NVMe磁盘SMART信息失败。 | + | -2 | 未获取到任何匹配ESN的NVMe磁盘。 | + +##### libstorage_get_bdev_ns_info + +1. 接口原型 + + ```bash + uint32_t libstorage_get_bdev_ns_info(const char* bdevName, struct libstorage_namespace_info** ppNsInfo); + ``` + +2. 接口描述 + + 根据设备名称,获取namespace信息。 + +3. 参数 + + | **参数成员** | **描述** | + |-------------------------------|---------------------------------------| + | const char* bdevName | 设备名称 | + | struct libstorage_namespace_info** ppNsInfo | 出参,返回namespace信息。
说明
使用后务必通过free接口释放内存。 | + +4. 返回值 + + | **返回值**| **描述** | + |------------|---------------| + | 0 | 获取失败 | + | 1 | 获取成功 | + +##### libstorage_get_ctrl_ns_info + +1. 接口原型 + + ```bash + uint32_t libstorage_get_ctrl_ns_info(const char* ctrlName, struct libstorage_namespace_info** ppNsInfo); + ``` + +2. 接口描述 + + 根据控制器名称,获取所有namespace信息。 + +3. 参数 + + | **参数成员** | **描述** | + |-------------------------------|---------------------------------------| + | const char* ctrlName | 控制器名称 | + | struct libstorage_namespace_info** ppNsInfo| 出参,返回所有namespace信息。
说明
使用后务必通过free接口释放内存。 | + +4. 返回值 + + | **返回值**| **描述** | + |------------|-------------------------------------------| + | 0 | 获取失败,或未获取到任何namespace信息 | + | 大于0 | 获取到的namespace个数 | + +##### libstorage_create_namespace + +1. 接口原型 + + ```bash + int32_t libstorage_create_namespace(const char* ctrlName, uint64_t ns_size, char** outputName); + ``` + +2. 接口描述 + + 在指定控制器上创建namespace(前提是控制器具有namespace管理能力)。 + + Optane盘基于NVMe 1.0协议,不支持namespace管理,因此不支持该接口的使用。 + + ES3000 V3和V5默认只支持一个namespace。在控制器上默认会存在一个namespace,如果要创建新的namespace,需要将原有namespace删除。 + +3. 参数 + + | **参数成员** | **描述** | + |--------------------------|-------------------------------------------| + | const char* ctrlName | 控制器名称 | + | uint64_t ns_size | 要创建的namespace大小(以sertor_size为单位) | + | char** outputName | 出参:创建的namespace名称
说明
使用后务必通过free接口释放内存。 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|-----------------------------------| + | 小于等于0 | 创建namespace失败 | + | 大于0 | 所创建的namespace编号(从1开始) | + +##### libstorage_delete_namespace + +1. 接口原型 + + ```bash + int32_t libstorage_delete_namespace(const char* ctrlName, uint32_t ns_id); + ``` + +2. 接口描述 + + 在指定控制器上删除namespace。Optane盘基于NVMe 1.0协议,不支持namespace管理,因此不支持该接口的使用。 + +3. 参数 + + | **参数成员** | **描述** | + |-----------------------|-------------------| + | const char* ctrlName | 控制器名字 | + | uint32_t ns_id | Namespace ID | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|-------------------------------------------| + | 0 | 删除成功 | + | 非0 | 删除失败
说明
删除namespace前要求先停止IO相关动作,否则删除失败。 | + +##### libstorage_delete_all_namespace + +1. 接口原型 + + ```bash + int32_t libstorage_delete_all_namespace(const char* ctrlName); + ``` + +2. 接口描述 + + 删除指定控制器上所有namespace。Optane盘基于NVMe 1.0协议,不支持namespace管理,因此不支持该接口的使用。 + +3. 参数 + + | **参数成员** | **描述** | + |------------------------|----------------| + | const char* ctrlName |控制器名称 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|-------------------------------------------| + | 0 | 删除成功 | + | 非0 | 删除失败
说明
删除namespace前要求先停止IO相关动作,否则删除失败。 | + +##### libstorage_nvme_create_ctrlr + +1. 接口原型 + + ```bash + int32_t libstorage_nvme_create_ctrlr(const char *pci_addr, const char *ctrlr_name); + ``` + +2. 接口描述 + + 根据PCI地址创建NVMe控制器。 + +3. 参数 + + | **参数成员** | **描述** | + |--------------------|-------------------| + | char *pci_addr |PCI地址 | + | char *ctrlr_name |控制器名称 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|--------------| + | 小于0 | 创建失败 | + | 0 | 创建成功 | + +##### libstorage_nvme_delete_ctrlr + +1. 接口原型 + + ```bash + int32_t libstorage_nvme_delete_ctrlr(const char *ctrlr_name); + ``` + +2. 接口描述 + + 根据控制器名称销毁NVMe控制器。 + +3. 参数 + + | **参数成员** | **描述** | + |-------------------------|-----------------| + | const char *ctrlr_name | 控制器名称 | + + 确保已下发的io已经全部返回后方可调用本接口。 + +4. 返回值 + + | **返回值** | **描述** | + |-------------|--------------| + | 小于0 | 销毁失败 | + | 0 | 销毁成功 | + +##### libstorage_nvme_reload_ctrlr + +1. 接口原型 + + ```bash + int32_t libstorage_nvme_reload_ctrlr(const char *cfgfile); + ``` + +2. 接口描述 + + 根据配置文件增删NVMe控制器。 + +3. 参数 + + | **参数成员** | **描述** | + |----------------------|-------------------| + | const char *cfgfile | 配置文件路径 | + + 使用本接口删盘时,需要确保已下发的io已经全部返回。 + +4. 返回值 + + | **返回值** | **描述** | + |-------------|-----------------------------------------------------| + | 小于0 | 根据配置文件增删盘失败(可能部分控制器增删成功) | + | 0 | 根据配置文件增删盘成功 | + +> 使用限制 + +- 目前最多支持在配置文件中配置36个控制器。 + +- 重加载接口会尽可能创建多的控制器,某个控制器创建失败,不会影响其他控制器的创建。 + +- 无法保证并发场景下最终的盘初始化情况与最后调用传入的配置文件相符。 + +- 对正在下发io的盘通过reload删除时,会导致io失败。 + +- 修改配置文件中pci地址对应的控制器名称(e.g.nvme0),调用此接口后无法生效。 + +- reload仅针对于增删盘的场景有效,配置文件中的其他配置项修改无法重载。 + +##### libstorage_low_level_format_nvm + +1. 接口原型 + + ```bash + int8_t libstorage_low_level_format_nvm(const char* ctrlName, uint8_t lbaf, + enum libstorage_ns_pi_type piType, + bool pil_start, bool ms_extented, uint8_t ses); + ``` + +2. 接口描述 + + 低级格式化NVMe盘。 + +3. 参数 + + | **参数成员** | **描述** | + |-------------------------------------|----------------------------------------------------------------------------| + | const char* ctrlName | 控制器名称 | + | uint8_t lbaf | 所要使用的LBA格式 | + | enum libstorage_ns_pi_type piType |所要使用的保护类型 | + | bool pil_start | pi信息位于元数据的first eight bytes(1) or last eight bytes (0) | + | bool ms_extented | 是否要格式化成扩展型 | + | uint8_t ses | 格式化时是否进行安全擦除(当前仅支持设置为0:no-secure earse) | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|-----------------------------| + | 小于0 | 格式化失败 | + | 大于等于0 | 当前格式化成功的LBA格式 | + +> 使用限制 + +- 该低级格式化接口会清除磁盘namespace的数据和元数据,请谨慎使用。 + +- ES3000盘在格式化时耗时数秒,Intel Optane盘在格式化时需耗时数分钟,在使用该接口时需要等待其执行完成。若强行杀掉格式化进程,会导致格式化失败。 + +- 在格式化执行之前,需要停止数据面的IO操作。如果当前磁盘正在处理IO请求,格式化操作会概率性出现失败,并且在格式化成功的情况下会存在硬盘丢弃正在处理的IO的可能,所以在格式化前,请保证数据面的IO操作已停止。 + +- 格式化过程中会reset控制器,导致之前已经初始化的磁盘资源不可用。因此格式化完成之后,需要重启数据面IO进程。 + +- ES3000 V3支持保护类型0和3,支持PI start和PI end,仅支持mc extended。ES3000 V3的512+8格式支持DIF,4096+64格式不支持。 + +- ES3000 V5支持保护类型0和3,支持PI start和PI end,支持mc extended和mc pointer。ES3000 V5的512+8和4096+64格式均支持DIF。 + +- Optane盘支持保护类型0和1,仅支持PI end,仅支持mc extended。Optane的512+8格式支持DIF,4096+64格式不支持。 + +| **磁盘类型** | **LBA格式** | **磁盘类型** | **LBA格式** | +|----------------------|-----------------|---------------|-------------------| +| Intel Optane P4800 | lbaf0:512+0
lbaf1:512+8
lbaf2:512+16
lbaf3:4096+0
lbaf4:4096+8
lbaf5:4096+64
lbaf6:4096+128 | ES3000 V3、V5 | lbaf0:512+0
lbaf1:512+8
lbaf2:4096+64
lbaf3:4096+0
lbaf4:4096+8 | + +##### LIBSTORAGE_CALLBACK_FUNC + +1. 接口原型 + + ```bash + typedef void (*LIBSTORAGE_CALLBACK_FUNC)(int32_t cb_status, int32_t sct_code, void* cb_arg); + ``` + +2. 接口描述 + + 注册的HSAK io完成回调函数。 + +3. 参数 + + | **参数成员** | **描述** | + |------------------------------------|-----------------------------| + | int32_t cb_status | io 状态码,0为成功,负值为系统错误码,正值为硬盘错误码(不同错误码的
含义见[附录](#附录)) | + | int32_t sct_code | io 状态码类型(0:[GENERIC](#generic);
1:[COMMAND_SPECIFIC](#command_specific);
2:[MEDIA_DATA_INTERGRITY_ERROR](#media_data_intergrity_error)
7:VENDOR_SPECIFIC) | + | void* cb_arg | 回调函数的入参 | + +4. 返回值 + + 无。 + +##### libstorage_deallocate_block + +1. 接口原型 + + ```bash + int32_t libstorage_deallocate_block(int32_t fd, struct libstorage_dsm_range_desc *range, uint16_t range_count, LIBSTORAGE_CALLBACK_FUNC cb, void* cb_arg); + ``` + +2. 接口描述 + + 告知NVMe盘可释放的块。 + +3. 参数 + + | **参数成员** | **描述** | + |------------------------------------|-----------------------------| + | int32_t fd | 已打开的硬盘文件描述符 | + | struct libstorage_dsm_range_desc *range | NVMe盘可释放的块描述列表
说明
该参数需要使用libstorage_mem_reserve分配
大页内存,分配内存时需要4K对齐,即align设置为4096。
盘的TRIM的范围根据不同的盘进行约束,超过盘侧的最大TRIM范围
可能触发数据异常。 | + | uint16_t range_count | 数组range的成员数 | + | LIBSTORAGE_CALLBACK_FUNC cb | 回调函数 | + | void* cb_arg | 回调函数参数 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|----------------| + | 小于0 | 请求下发失败 | + | 0 | 请求下发成功 | + +##### libstorage_async_write + +1. 接口原型 + + ```bash + int32_t libstorage_async_write(int32_t fd, void *buf, size_t nbytes, off64_t offset, void *md_buf, size_t md_len, enum libstorage_crc_and_prchk dif_flag, LIBSTORAGE_CALLBACK_FUNC cb, void* cb_arg); + ``` + +2. 接口描述 + + HSAK下发异步IO写请求的接口(写缓冲区为连续buffer)。 + +3. 参数 + + | **参数成员** | **描述** | + |------------------------------------|-----------------------------| + | int32_t fd | 块设备的文件描述符 | + | void *buf | IO写数据的缓冲区(四字节对齐,不能跨4K页面边界)
说明
注:扩展型LBA要包含元数据内存大小。 | + | size_t nbytes | 单次写IO大小(单位:字节。sector_size的整数倍)
说明
仅包含数据大小,扩展型LBA也不含元数据大小。 | + | off64_t offset | LBA的写偏移(单位:字节。sector_size的整数倍)
说明
仅包含数据大小,扩展型LBA也不含元数据大小。 | + | void *md_buf | 元数据的缓冲区(仅适用于分离型LBA,扩展型LBA设置为NULL即可) | + | size_t md_len | 元数据的缓冲区长度(仅适用于分离型LBA,扩展型LBA设置为0即可) | + | enum libstorage_crc_and_prchk dif_flag | 是否计算DIF、是否开启盘的校验 | + | LIBSTORAGE_CALLBACK_FUNC cb | 注册的回调函数 | + | void* cb_arg | 回调函数的参数 | + +4. 返回值 + + | **返回值**| **描述** | + |------------|--------------------| + | 0 | IO写请求提交成功 | + | 非0 | IO写请求提交失败 | + +##### libstorage_async_read + +1. 接口原型 + + ```bash + int32_t libstorage_async_read(int32_t fd, void *buf, size_t nbytes, off64_t offset, void *md_buf, size_t md_len, enum libstorage_crc_and_prchk dif_flag, LIBSTORAGE_CALLBACK_FUNC cb, void* cb_arg); + ``` + +2. 接口描述 + + HSAK下发异步IO读请求的接口(读缓冲区为连续buffer)。 + +3. 参数 + + | **参数成员** | **描述** | + |------------------------------------|----------------------------------| + | int32_t fd | 块设备的文件描述符 | + | void *buf | IO读数据的缓冲区(四字节对齐,不能跨4K页面边界)
说明
扩展型LBA要包含元数据内存大小。 | + | size_t nbytes | 单次读IO大小(单位:字节。sector_size的整数倍)
说明
仅包含数据大小,扩展型LBA也不含元数据大小。 | + | off64_t offset | LBA的读偏移(单位:字节。sector_size的整数倍)
说明
仅包含数据大小,扩展型LBA也不含元数据大小。 | + | void *md_buf | 元数据的缓冲区(仅适用于分离型LBA,扩展型LBA设置为NULL即可) | + | size_t md_len | 元数据的缓冲区长度(仅适用于分离型LBA,扩展型LBA设置为0即可) | + | enum libstorage_crc_and_prchk dif_flag | 是否计算DIF、是否开启盘的校验 | + | LIBSTORAGE_CALLBACK_FUNC cb | 注册的回调函数 | + | void* cb_arg | 回调函数的参数 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|------------------| + | 0 | IO读请求提交成功 | + | 非0 | IO读请求提交失败 | + +##### libstorage_async_writev + +1. 接口原型 + + ```bash + int32_t libstorage_async_writev(int32_t fd, struct iovec *iov, int iovcnt, size_t nbytes, off64_t offset, void *md_buf, size_t md_len, enum libstorage_crc_and_prchk dif_flag, LIBSTORAGE_CALLBACK_FUNC cb, void* cb_arg); + ``` + +2. 接口描述 + + HSAK下发异步IO写请求的接口(写缓冲区为离散buffer)。 + +3. 参数 + + | **参数成员** | **描述** | + |------------------------------------|----------------------------------| + | int32_t fd | 块设备的文件描述符 | + | struct iovec *iov | IO写数据的缓冲区
说明
扩展型LBA要包含元数据大小。
地址要求四字节对齐,长度不超过4GB。 | + | int iovcnt | IO写数据的缓冲区个数 | + | size_t nbytes | 单次写IO大小(单位:字节。sector_size的整数倍)
说明
仅包含数据大小,扩展型LBA也不含元数据大小。 | + | off64_t offset | LBA的写偏移(单位:字节。sector_size的整数倍)
说明
仅包含数据大小,扩展型LBA也不含元数据大小。 | + | void *md_buf | 元数据的缓冲区(仅适用于分离型LBA,扩展型LBA设置为NULL即可) | + | size_t md_len | 元数据的缓冲区长度(仅适用于分离型LBA,扩展型LBA设置为0即可) | + | enum libstorage_crc_and_prchk dif_flag | 是否计算DIF、是否开启盘的校验 | + | LIBSTORAGE_CALLBACK_FUNC cb | 注册的回调函数 | + | void* cb_arg | 回调函数的参数 | + +4. 返回值 + + | **返回值** | **描述** | + |--------------|-------------------| + | 0 | IO写请求提交成功 | + | 非0 | IO写请求提交失败 | + +##### libstorage_async_readv + +1. 接口原型 + + ```bash + int32_t libstorage_async_readv(int32_t fd, struct iovec *iov, int iovcnt, size_t nbytes, off64_t offset, void *md_buf, size_t md_len, enum libstorage_crc_and_prchk dif_flag, LIBSTORAGE_CALLBACK_FUNC cb, void* cb_arg); + ``` + +2. 接口描述 + + HSAK下发异步IO读请求的接口(读缓冲区为离散buffer)。 + +3. 参数 + + | **参数成员** | **描述** | + |------------------------------------|----------------------------------| + | int32_t fd | 块设备的文件描述符 | + | struct iovec *iov | IO读数据的缓冲区
说明
扩展型LBA要包含元数据大小。
地址要求四字节对齐,长度不超过4GB。 | + | int iovcnt | IO读数据的缓冲区个数 | + | size_t nbytes | 单次读IO大小(单位:字节。sector_size的整数倍)
说明
仅包含数据大小,扩展型LBA也不含元数据大小。 | + | off64_t offset | LBA的读偏移(单位:字节。sector_size的整数倍)
说明
仅包含数据大小,扩展型LBA也不含元数据大小。 | + | void *md_buf | 元数据的缓冲区(仅适用于分离型LBA,扩展型LBA设置为NULL即可) | + | size_t md_len | 元数据的缓冲区长度(仅适用于分离型LBA,扩展型LBA设置为0即可) | + | enum libstorage_crc_and_prchk dif_flag | 是否计算DIF、是否开启盘的校验 | + | LIBSTORAGE_CALLBACK_FUNC cb | 注册的回调函数 | + | void* cb_arg | 回调函数的参数 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|----------------------| + | 0 | IO读请求提交成功 | + | 非0 | IO读请求提交失败 | + +##### libstorage_sync_write + +1. 接口原型 + + ```bash + int32_t libstorage_sync_write(int fd, const void *buf, size_t nbytes, off_t offset); + ``` + +2. 接口描述 + + HSAK下发同步IO写请求的接口(写缓冲区为连续buffer)。 + +3. 参数 + + | **参数成员** | **描述** | + |------------------------------------|----------------------------------| + | int32_t fd | 块设备的文件描述符 | + | void *buf | IO写数据的缓冲区(四字节对齐,不能跨4K页面边界)
说明
扩展型LBA要包含元数据内存大小。 | + | size_t nbytes | 单次写IO大小(单位:字节。sector_size的整数倍)
说明
仅包含数据大小,扩展型LBA也不含元数据大小。 | + | off64_t offset | LBA的写偏移(单位:字节。sector_size的整数倍)
说明
仅包含数据大小,扩展型LBA也不含元数据大小。 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|-----------------------| + | 0 | IO写请求提交成功 | + | 非0 | IO写请求提交失败 | + +##### libstorage_sync_read + +1. 接口原型 + + ```bash + int32_t libstorage_sync_read(int fd, const void *buf, size_t nbytes, off_t offset); + ``` + +2. 接口描述 + + HSAK下发同步IO读请求的接口(读缓冲区为连续buffer)。 + +3. 参数 + + | **参数成员** | **描述** | + |------------------------------------|----------------------------------| + | int32_t fd | 块设备的文件描述符 | + | void *buf | IO读数据的缓冲区(四字节对齐,不能跨4K页面边界)
说明
扩展型LBA要包含元数据内存大小。 | + | size_t nbytes | 单次读IO大小(单位:字节。sector_size的整数倍)
说明
仅包含数据大小,扩展型LBA也不含元数据大小。 | + | off64_t offset | LBA的读偏移(单位:字节。sector_size的整数倍)
说明
仅包含数据大小,扩展型LBA也不含元数据大小。 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|-----------------------| + | 0 | IO读请求提交成功 | + | 非0 | IO读请求提交失败 | + +##### libstorage_open + +1. 接口原型 + + ```bash + int32_t libstorage_open(const char* devfullname); + ``` + +2. 接口描述 + + 打开块设备。 + +3. 参数 + + | **参数成员** | **描述** | + |--------------------------|---------------------------------| + | const char* devfullname | 块设备名称(格式为nvme0n1) | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|-------------------------------------------------------------------| + | -1 | 打开失败(如设备名不对,或打开的fd数目>NVME盘的可使用通道数目) | + | 大于0 | 块设备的文件描述符 | + + 开启nvme.conf.in中的MultiQ开关以后,同一个线程多次打开同一个设备,会返回不同的fd;否则仍返回同一个fd。该特性只针对NVME设备。 + +##### libstorage_close + +1. 接口原型 + + ```bash + int32_t libstorage_close(int32_t fd); + ``` + +2. 接口描述 + + 关闭块设备。 + +3. 参数 + + | **参数成员** | **描述** | + |--------------|---------------------------| + | int32_t fd |已打开的块设备的文件描述符 | + +4. 返回值 + + | **返回值**| **描述** | + |------------|--------------------------------| + | -1 | 无效文件描述符 | + | -16 | 文件描述符正忙,需要重试 | + | 0 | 关闭成功 | + +##### libstorage_mem_reserve + +1. 接口原型 + + ```bash + void* libstorage_mem_reserve(size_t size, size_t align); + ``` + +2. 接口描述 + + 从DPDK预留的大页内存中分配内存空间。 + +3. 参数 + + | **参数成员**| **描述** | + |---------------|-------------------------------| + | size_t size | 需要分配的内存的大小 | + | size_t align | 所分配的内存空间按照align对齐 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|---------------------------| + | NULL | 分配失败 | + | 非NULL | 所分配内存空间的地址 | + +##### libstorage_mem_free + +1. 接口原型 + + ```bash + void libstorage_mem_free(void* ptr); + ``` + +2. 接口描述 + + 释放ptr指向的内存空间。 + +3. 参数 + + | **参数成员** | **描述** | + |---------------|--------------------------| + | void* ptr |所要释放的内存空间的地址 | + +4. 返回值 + + 无。 + +##### libstorage_alloc_io_buf + +1. 接口原型 + + ```bash + void* libstorage_alloc_io_buf(size_t nbytes); + ``` + +2. 接口描述 + + 从SPDK的buf_small_pool或者buf_large_pool中分配内存。 + +3. 参数 + + | **参数成员** | **描述** | + |----------------|-----------------------------| + | size_t nbytes | 所需要分配的缓冲区大小 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|--------------------------| + | 非NULL | 所分配的缓冲区的首地址 | + +##### libstorage_free_io_buf + +1. 接口原型 + + ```bash + int32_t libstorage_free_io_buf(void *buf, size_t nbytes); + ``` + +2. 接口描述 + + 释放所分配的内存到SPDK的buf_small_pool或者buf_large_pool中。 + +3. 参数 + + | **参数成员** | **描述** | + |----------------|------------------------------| + | void *buf | 所要释放的缓冲区的首地址 | + | size_t nbytes | 所要释放的缓冲区的大小 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|--------------| + | -1 | 释放失败 | + | 0 | 释放成功 | + +##### libstorage_init_module + +1. 接口原型 + + ```bash + int32_t libstorage_init_module(const char* cfgfile); + ``` + +2. 接口描述 + + HSAK模块初始化接口。 + +3. 参数 + + | **参数成员** | **描述** | + |----------------------|---------------------| + | const char* cfgfile | HSAK 配置文件名称 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|---------------| + | 非0 | 初始化失败 | + | 0 | 初始化成功 | + +##### libstorage_exit_module + +1. 接口原型 + + ```bash + int32_t libstorage_exit_module(void); + ``` + +2. 接口描述 + + HSAK模块退出接口。 + +3. 参数 + + 无。 + +4. 返回值 + + | **返回值** | **描述** | + |-------------|---------------| + | 非0 | 退出清理失败 | + | 0 | 退出清理成功 | + +##### LIBSTORAGE_REGISTER_DPDK_INIT_NOTIFY + +1. 接口原型 + + ```bash + LIBSTORAGE_REGISTER_DPDK_INIT_NOTIFY(_name, _notify) + ``` + +2. 接口描述 + + 业务层注册函数,用于注册DPDK初始化完成时的回调函数。 + +3. 参数 + + | **参数成员** | **描述** | + |----------------|---------------------------------------------------------------------------------------------------| + | _name |业务层模块名称。 | + | _notify |业务层注册的回调函数原型:void (*notifyFunc)(const struct libstorage_dpdk_init_notify_arg*arg); | + +4. 返回值 + + 无。 + +#### ublock.h + +##### init_ublock + +1. 接口原型 + + ```bash + int init_ublock(const char *name, enum ublock_rpc_server_status flg); + ``` + +2. 接口描述 + + 初始化Ublock功能模块,本接口必须在其他所有Ublock接口之前被调用。如果flag被置为UBLOCK_RPC_SERVER_ENABLE,即ublock作为rpc server,则同一个进程只能初始化一次。 + + 在ublock作为rpc server启动时,会同时启动一个server的monitor线程。monitor线程监控到rpc server线程出现异常(如卡死时),会主动调用exit触发进程退出。 + + 此时依赖于产品的脚本再次拉起相关进程。 + +3. 参数 + + | **参数成员** | **描述** | + |----------------------------------|---------------------------------| + | const char *name | 模块名字,缺省值为"ublock",建议该参数可以传NULL。 | + | enum ublock_rpc_server_status
flg | 是否启用RPC的标记值:UBLOCK_RPC_SERVER_
DISABLE或UBLOCK_RPC_SERVER_ENAB
LE;
在不启用RPC情况下,如果硬盘被业务进程占用,那么Ublock模块
将无法获取该硬盘信息。 | + +4. 返回值 + + | **返回值** | **描述** | + |----------------------------------|---------------------------------| + | 0 | 初始化成功。 | + | -1 | 初始化失败,可能原因:Ublock模块已经被初始化。 | + | 进程exit | Ublock认为在两种情况下属于无法修复异常,直接调用exit接口
退出进程:
- 需要创建RPC服务,但RPC服务现场创建失败。
- 创建热插拔监控线程,但失败。 | + +##### ublock_init + +1. 接口原型 + + ```bash + # define ublock_init(name) init_ublock(name, UBLOCK_RPC_SERVER_ENABLE) + ``` + +2. 接口描述 + + 本身是对init_ublock接口的宏定义,可理解为将Ublock初始化为需要RPC服务。 + +3. 参数 + + | **参数成员** | **描述** | + |---------------|----------------------------------------------------| + | name | 模块名字,缺省值为"ublock",建议该参数可以传NULL。 | + +4. 返回值 + + | **返回值** | **描述** | + |---------------|----------------------------------------------------| + | 0 | 初始化成功。 | + | -1 | 初始化失败,可能原因:Ublock rpc
server模块已经被初始化。 | + | 进程exit | Ublock认为在两种情况下属于无法修复异常,直接调用exit接口
退出进程:
- 需要创建RPC服务,但RPC服务现场创建失败。
- 创建热插拔监控线程,但失败。 | + +##### ublock_init_norpc + +1. 接口原型 + + ```bash + # define ublock_init_norpc(name) init_ublock(name, UBLOCK_RPC_SERVER_DISABLE) + ``` + +2. 接口描述 + + 本身是对init_ublock接口的宏定义,可理解为将Ublock初始化为无RPC服务。 + +3. 参数 + + | **参数成员** | **描述** | + |---------------|------------------------------------------------------| + | name | 模块名字,缺省值为"ublock",建议该参数可以传NULL。 | + +4. 返回值 + + | **返回值** | **描述** | + |---------------------------------|-----------------------------| + | 0 | 初始化成功。 | + | -1 | 初始化失败,可能原因:Ublock
client模块已经被初始化。 | + | 进程exit | Ublock认为在两种情况下属于无法修复异常,直接调用exit接口
退出进程:
- 需要创建RPC服务,但RPC服务现场创建失败。
- 创建热插拔监控线程,但失败。 | + +##### ublock_fini + +1. 接口原型 + + ```cpp + void ublock_fini(void); + ``` + +2. 接口描述 + + 销毁Ublock功能模块,本接口将销毁Ublock模块以及内部创建的资源,本接口同Ublock初始化接口需要配对使用。 + +3. 参数 + + 无。 + +4. 返回值 + + 无。 + +##### ublock_get_bdevs + +1. 接口原型 + + ```bash + int ublock_get_bdevs(struct ublock_bdev_mgr* bdev_list); + ``` + +2. 接口描述 + + 业务进程通过调用本接口获取设备列表(环境上所有的NVME设备,包括内核态驱动和用户态驱动),获取的NVMe设备列表中只有PCI地址,不包含具体设备信息,需要获取具体设备信息,请调用接口ublock_get_bdev。 + +3. 参数 + + | **参数成员** | **描述** | + |-------------------------------------|------------------------------------------------------| + | struct ublock_bdev_mgr* bdev_list |出参,返回设备队列,bdev_list指针需要在外部分配。 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|-----------------------| + | 0 | 获取设备队列成功。 | + | -2 | 环境中没有NVMe设备。 | + | 其余值 | 获取设备队列失败。 | + +##### ublock_free_bdevs + +1. 接口原型 + + ```bash + void ublock_free_bdevs(struct ublock_bdev_mgr* bdev_list); + ``` + +2. 接口描述 + + 业务进程通过调用本接口释放设备列表。 + +3. 参数 + + | **参数成员** | **描述** | + |-------------------------------------|--------------------------------------------------------------| + | struct ublock_bdev_mgr* bdev_list |设备队列头指针,设备队列清空后,bdev_list指针本身不会被释放。 | + +4. 返回值 + + 无。 + +##### ublock_get_bdev + +1. 接口原型 + + ```bash + int ublock_get_bdev(const char *pci, struct ublock_bdev *bdev); + ``` + +2. 接口描述 + + 业务进程通过调用本接口获取具体某个设备的信息,设备信息中:NVMe设备的序列号、型号、fw版本号信息以字符数组形式保存,不是字符串形式(不同硬盘控制器返回形式不同,不保证数组结尾必定含有"0")。 + + 本接口调用后,对应设备会被Ublock占用,请务必在完成相应业务操作后立即调用ublock_free_bdev释放资源。 + +3. 参数 + + | **参数成员** | **描述** | + |---------------------------|--------------------------------------------------| + | const char *pci | 需要获取信息的设备PCI地址 | + | struct ublock_bdev *bdev | 出参,返回设备信息,bdev指针需要在外部分配。 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|------------------------------------------------------------| + | 0 | 获取设备信息成功。 | + | -1 | 获取设备信息失败,如参数错误等。 | + | -11(EAGAIN) | 获取设备信息失败,如rpc查询失败,需要重试(建议sleep 3s)。 | + +##### ublock_get_bdev_by_esn + +1. 接口原型 + + ```bash + int ublock_get_bdev_by_esn(const char *esn, struct ublock_bdev *bdev); + ``` + +2. 接口描述 + + 业务进程通过调用本接口,根据给定的ESN号获取对应设备的信息,设备信息中:NVMe设备的序列号、型号、fw版本号信息以字符数组形式保存,不是字符串形式(不同硬盘控制器返回形式不同,不保证数组结尾必定含有"0")。 + + 本接口调用后,对应设备会被Ublock占用,请务必在完成相应业务操作后立即调用ublock_free_bdev释放资源。 + +3. 参数 + + | **参数成员** | **描述** | + |---------------------------|--------------------------------------------------| + | const char *esn | 需要获取信息的设备ESN号。
说明
ESN号是最大有效长度为20的字符串(不包括字符串结束符),但该长
度根据不同硬件厂商可能存在差异,如不足20字符,需要在字符串末尾加
空格补齐。 | + | struct ublock_bdev *bdev | 出参,返回设备信息,bdev指针需要在外部分配。 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|--------------------------------------------------------------| + | 0 | 获取设备信息成功。 | + | -1 | 获取设备信息失败,如参数错误等 | + | -11(EAGAIN)| 获取设备信息失败,如rpc查询失败,需要重试(建议sleep 3s)。 | + +##### ublock_free_bdev + +1. 接口原型 + + ```cpp + void ublock_free_bdev(struct ublock_bdev *bdev); + ``` + +2. 接口描述 + + 业务进程通过调用本接口释放设备资源。 + +3. 参数 + + | **参数成员** | **描述** | + |----------------------------|-------------------------------------------------------------| + | struct ublock_bdev *bdev | 设备信息指针,该指针内数据清空后,bdev指针本身不会被释放。 | + +4. 返回值 + + 无。 + +##### TAILQ_FOREACH_SAFE + +1. 接口原型 + + ```bash + # define TAILQ_FOREACH_SAFE(var, head, field, tvar) + for ((var) = TAILQ_FIRST((head)); + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); + (var) = (tvar)) + ``` + +2. 接口描述 + + 提供安全访问队列每个成员的宏定义。 + +3. 参数 + + | **参数成员** | **描述** | + |---------------|----------------------------------------------------------------------------------------------------| + | var | 当前操作的队列节点成员 | + | head | 队列头指针,一般情况下是指通过TAILQ_HEAD(xx, xx) obj定义的obj的地址 | + | field | 队列节点中用于保存队列前后指针的结构体名字,一般情况下是指通过TAILQ_ENTRY(xx)name定义的名字name | + | tvar | 下一个队列节点成员 | + +4. 返回值 + + 无。 + +##### ublock_get_SMART_info + +1. 接口原型 + + ```bash + int ublock_get_SMART_info(const char *pci, uint32_t nsid, struct ublock_SMART_info *smart_info); + ``` + +2. 接口描述 + + 业务进程通过调用本接口获取指定设备的SMART信息。 + +3. 参数 + + | **参数成员** | **描述** | + |---------------------------------------|----------------------------| + | const char *pci | 设备PCI地址 | + | uint32_t nsid | 指定的namespace | + | struct ublock_SMART_info *smart_info | 出参,返回设备SMART信息 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|---------------------------------------------------------------| + | 0 | 获取SMART信息成功。 | + | -1 | 获取SMART信息失败,如参数错误等。 | + | -11(EAGAIN)| 获取SMART信息失败,如rpc查询失败,需要重试(建议sleep 3s)。 | + +##### ublock_get_SMART_info_by_esn + +1. 接口原型 + + ```bash + int ublock_get_SMART_info_by_esn(const char *esn, uint32_t nsid, struct ublock_SMART_info *smart_info); + ``` + +2. 接口描述 + + 业务进程通过调用本接口获取ESN号对应设备的SMART信息。 + +3. 参数 + + | **参数成员** | **描述** | + |--------------------------|-----------------------------------------------| + | const char *esn | 设备ESN号
说明
ESN号是最大有效长度为20的字符串(不包括字符串结束符),但该长
度根据不同硬件厂商可能存在差异,如不足20字符,需要在字符串末尾加
空格补齐。 | + | uint32_t nsid | 指定的namespace | + | struct ublock_SMART_info
*smart_info | 出参,返回设备SMART信息 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|--------------------------------------------------------------| + | 0 | 获取SMART信息成功。 | + | -1 | 获取SMART信息失败,如参数错误等。 | + | -11(EAGAIN) | 获取SMART信息失败,如rpc查询失败,需要重试(建议sleep 3s)。 | + +##### ublock_get_error_log_info + +1. 接口原型 + + ```bash + int ublock_get_error_log_info(const char *pci, uint32_t err_entries, struct ublock_nvme_error_info *errlog_info); + ``` + +2. 接口描述 + + 业务进程通过调用本接口获取指定设备的Error log信息。 + +3. 参数 + + | **参数成员** | **描述** | + |---------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------| + | const char *pci | 设备PCI地址 | + | uint32_t err_entries | 指定希望获取的Error Log条数,最多256条 | + | struct ublock_nvme_error_info *errlog_info | 出参,返回设备Error log信息,errlog_info指针需要调用者申请空间,且确保申请的空间大于或等于err_entries * sizeof (struct ublock_nvme_error_info) | + +4. 返回值 + + | **返回值** | **描述** | + |-------------------------------------|--------------------------------------------------------------| + | 获取到的Error log条数,大于或等于0 | 获取Error log成功。 | + | -1 | 获取Error log失败,如参数错误等。 | + | -11(EAGAIN) | 获取Error log失败,如rpc查询失败,需要重试(建议sleep 3s)。 | + +##### ublock_get_log_page + +1. 接口原型 + + ```bash + int ublock_get_log_page(const char *pci, uint8_t log_page, uint32_t nsid, void *payload, uint32_t payload_size); + ``` + +2. 接口描述 + + 业务进程通过调用本接口获取指定设备,指定log page的信息。 + +3. 参数 + + | **参数成员** | **描述** | + |------------------------|-------------------------------------------------------------------------------------------------------------------------| + | const char *pci | 设备PCI地址 | + | uint8_t log_page | 指定希望获取的log page ID,比如0xC0, 0xCA代表ES3000 V5盘自定义的SMART信息 | + | uint32_t nsid | 指定namespace ID,各个log page对按namespace获取支持情况不一致,如果不支持按namespace获取,调用者需要显示传0xFFFFFFFF | + | void *payload | 出参,存储log page信息,由调用者负责申请内存 | + | uint32_t payload_size | 申请的payload大小,不大于4096 Bytes | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|------------------------------------| + | 0 | 获取log page成功 | + | -1 | 获取Error log失败,如参数错误等 | + +##### ublock_info_get_pci_addr + +1. 接口原型 + + ```bash + char *ublock_info_get_pci_addr(const void *info); + ``` + +2. 接口描述 + + 业务进程的回调函数中,通过调用本接口获取热插拔设备的PCI地址。 + + info占用的内存以及返回的PCI地址占用得内存不需要业务进程进行释放。 + +3. 参数 + + | **参数成员** | **描述** | + |-------------------|---------------------------------------------| + | const void *info | 热插拔监控线程传递给回调函数的热插拔事件信息 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|--------------------| + | NULL | 获取失败 | + | 非NULL | 获取的PCI地址 | + +##### ublock_info_get_action + +1. 接口原型 + + ```bash + enum ublock_nvme_uevent_action ublock_info_get_action(const void *info); + ``` + +2. 接口描述 + + 业务进程的回调函数中,通过调用本接口获取热插拔事件的类型。 + + info占用的内存不需要业务进程进行释放。 + +3. 参数 + + | **参数成员** | **描述** | + |-------------------|------------------------------------------------| + | const void *info | 热插拔监控线程传递给回调函数的热插拔事件信息 | + +4. 返回值 + + | **返回值** | **描述** | + |----------------|------------------------------------------------------------------------------| + | 热插拔事件类型| 触发回调函数的事件类型,详见结构体enum ublock_nvme_uevent_action的定义。 | + +##### ublock_get_ctrl_iostat + +1. 接口原型 + + ```bash + int ublock_get_ctrl_iostat(const char* pci, struct ublock_ctrl_iostat_info *ctrl_iostat); + ``` + +2. 接口描述 + + 业务进程通过调用本接口获取控制器的IO统计信息。 + +3. 参数 + + | **参数成员** | **描述** | + |-----------------------------------------------|----------------------------------------------------------| + | const char* pci | 需要获取IO统计信息的控制器的PCI地址。 | + | struct ublock_ctrl_iostat_info *ctrl_iostat |出参,返回IO统计信息,ctrl_iostat指针需要在外部分配。 | + +4. 返回值 + + | **返回值** | **描述** | + |-------------|-------------------------------------------------| + | 0 | 获取IO统计信息成功。 | + | -1 | 获取IO统计信息失败(无效参数、RPC error)。 | + | -2 | 获取IO统计信息失败(NVMe盘没有被IO进程接管)。 | + | -3 | 获取IO统计信息失败(IO统计开关未打开)。 | + +##### ublock_nvme_admin_passthru + +1. 接口原型 + + ```bash + int32_t ublock_nvme_admin_passthru(const char *pci, void *cmd, void *buf, size_t nbytes); + ``` + +2. 接口描述 + + 业务进程通过调用该接口透传nvme admin命令给nvme设备。当前仅支持获取identify字段的nvme admin命令。 + +3. 参数 + + | **参数成员** | **描述** | + |------------------|----------------------------------------------------------------------------------------------------| + | const char *pci | nvme admin命令目的控制器的PCI地址。 | + | void *cmd | nvme admin命令结构体指针,结构体大小为64字节,内容参考nvme spec。当前仅支持获取identify字段命令。 | + | void *buf | 保存nvme admin命令返回内容,其空间由用户分配,大小为nbytes。 | + | size_t nbytes | 用户buf的大小。identify字段为4096字节,获取identify命令的nbytes为4096。 | + +4. 返回值 + + | **返回值**| **描述** | + |------------|--------------------| + | 0 | 用户命令执行成功。 | + | -1 | 用户命令执行失败。 | + +## 附录 + +### GENERIC + +通用类型错误码参考 + +|sc |value| +|---------------------------------------------|---------------| +| NVME_SC_SUCCESS | 0x00 | +| NVME_SC_INVALID_OPCODE | 0x01 | +| NVME_SC_INVALID_FIELD | 0x02 | +| NVME_SC_COMMAND_ID_CONFLICT | 0x03 | +| NVME_SC_DATA_TRANSFER_ERROR | 0x04 | +| NVME_SC_ABORTED_POWER_LOSS | 0x05 | +| NVME_SC_INTERNAL_DEVICE_ERROR | 0x06 | +| NVME_SC_ABORTED_BY_REQUEST | 0x07 | +| NVME_SC_ABORTED_SQ_DELETION | 0x08 | +| NVME_SC_ABORTED_FAILED_FUSED | 0x09 | +| NVME_SC_ABORTED_MISSING_FUSED | 0x0a | +| NVME_SC_INVALID_NAMESPACE_OR_FORMAT | 0x0b | +| NVME_SC_COMMAND_SEQUENCE_ERROR | 0x0c | +| NVME_SC_INVALID_SGL_SEG_DESCRIPTOR | 0x0d | +| NVME_SC_INVALID_NUM_SGL_DESCIRPTORS | 0x0e | +| NVME_SC_DATA_SGL_LENGTH_INVALID | 0x0f | +| NVME_SC_METADATA_SGL_LENGTH_INVALID | 0x10 | +| NVME_SC_SGL_DESCRIPTOR_TYPE_INVALID | 0x11 | +| NVME_SC_INVALID_CONTROLLER_MEM_BUF | 0x12 | +| NVME_SC_INVALID_PRP_OFFSET | 0x13 | +| NVME_SC_ATOMIC_WRITE_UNIT_EXCEEDED | 0x14 | +| NVME_SC_OPERATION_DENIED | 0x15 | +| NVME_SC_INVALID_SGL_OFFSET | 0x16 | +| NVME_SC_INVALID_SGL_SUBTYPE | 0x17 | +| NVME_SC_HOSTID_INCONSISTENT_FORMAT | 0x18 | +| NVME_SC_KEEP_ALIVE_EXPIRED | 0x19 | +| NVME_SC_KEEP_ALIVE_INVALID | 0x1a | +| NVME_SC_ABORTED_PREEMPT | 0x1b | +| NVME_SC_SANITIZE_FAILED | 0x1c | +| NVME_SC_SANITIZE_IN_PROGRESS | 0x1d | +| NVME_SC_SGL_DATA_BLOCK_GRANULARITY_INVALID | 0x1e | +| NVME_SC_COMMAND_INVALID_IN_CMB | 0x1f | +| NVME_SC_LBA_OUT_OF_RANGE | 0x80 | +| NVME_SC_CAPACITY_EXCEEDED | 0x81 | +| NVME_SC_NAMESPACE_NOT_READY | 0x82 | +| NVME_SC_RESERVATION_CONFLICT | 0x83 | +| NVME_SC_FORMAT_IN_PROGRESS | 0x84 | + +### COMMAND_SPECIFIC + +特定命令错误码参考 + +|sc |value| +|---------------------------------------------|---------------| +| NVME_SC_COMPLETION_QUEUE_INVALID | 0x00 | +| NVME_SC_INVALID_QUEUE_IDENTIFIER | 0x01 | +| NVME_SC_MAXIMUM_QUEUE_SIZE_EXCEEDED | 0x02 | +| NVME_SC_ABORT_COMMAND_LIMIT_EXCEEDED | 0x03 | +| NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED | 0x05 | +| NVME_SC_INVALID_FIRMWARE_SLOT | 0x06 | +| NVME_SC_INVALID_FIRMWARE_IMAGE | 0x07 | +| NVME_SC_INVALID_INTERRUPT_VECTOR | 0x08 | +| NVME_SC_INVALID_LOG_PAGE | 0x09 | +| NVME_SC_INVALID_FORMAT | 0x0a | +| NVME_SC_FIRMWARE_REQ_CONVENTIONAL_RESET | 0x0b | +| NVME_SC_INVALID_QUEUE_DELETION | 0x0c | +| NVME_SC_FEATURE_ID_NOT_SAVEABLE | 0x0d | +| NVME_SC_FEATURE_NOT_CHANGEABLE | 0x0e | +| NVME_SC_FEATURE_NOT_NAMESPACE_SPECIFIC | 0x0f | +| NVME_SC_FIRMWARE_REQ_NVM_RESET | 0x10 | +| NVME_SC_FIRMWARE_REQ_RESET | 0x11 | +| NVME_SC_FIRMWARE_REQ_MAX_TIME_VIOLATION | 0x12 | +| NVME_SC_FIRMWARE_ACTIVATION_PROHIBITED | 0x13 | +| NVME_SC_OVERLAPPING_RANGE | 0x14 | +| NVME_SC_NAMESPACE_INSUFFICIENT_CAPACITY | 0x15 | +| NVME_SC_NAMESPACE_ID_UNAVAILABLE | 0x16 | +| NVME_SC_NAMESPACE_ALREADY_ATTACHED | 0x18 | +| NVME_SC_NAMESPACE_IS_PRIVATE | 0x19 | +| NVME_SC_NAMESPACE_NOT_ATTACHED | 0x1a | +| NVME_SC_THINPROVISIONING_NOT_SUPPORTED | 0x1b | +| NVME_SC_CONTROLLER_LIST_INVALID | 0x1c | +| NVME_SC_DEVICE_SELF_TEST_IN_PROGRESS | 0x1d | +| NVME_SC_BOOT_PARTITION_WRITE_PROHIBITED | 0x1e | +| NVME_SC_INVALID_CTRLR_ID | 0x1f | +| NVME_SC_INVALID_SECONDARY_CTRLR_STATE | 0x20 | +| NVME_SC_INVALID_NUM_CTRLR_RESOURCES | 0x21 | +| NVME_SC_INVALID_RESOURCE_ID | 0x22 | +| NVME_SC_CONFLICTING_ATTRIBUTES | 0x80 | +| NVME_SC_INVALID_PROTECTION_INFO | 0x81 | +| NVME_SC_ATTEMPTED_WRITE_TO_RO_PAGE | 0x82 | + +### MEDIA_DATA_INTERGRITY_ERROR + +介质异常错误码参考 + +|sc |value| +|-----------------------------------------|---------------| +| NVME_SC_WRITE_FAULTS | 0x80 | +| NVME_SC_UNRECOVERED_READ_ERROR | 0x81 | +| NVME_SC_GUARD_CHECK_ERROR | 0x82 | +| NVME_SC_APPLICATION_TAG_CHECK_ERROR | 0x83 | +| NVME_SC_REFERENCE_TAG_CHECK_ERROR | 0x84 | +| NVME_SC_COMPARE_FAILURE | 0x85 | +| NVME_SC_ACCESS_DENIED | 0x86 | +| NVME_SC_DEALLOCATED_OR_UNWRITTEN_BLOCK | 0x87 | diff --git a/docs/en/25.03/Server/MemoryandStorage/HSAK/hsak_tools_usage.md b/docs/en/25.03/Server/MemoryandStorage/HSAK/hsak_tools_usage.md new file mode 100644 index 0000000000000000000000000000000000000000..822eb64c4faf4226fecc9c64c7284e52a24f3f4d --- /dev/null +++ b/docs/en/25.03/Server/MemoryandStorage/HSAK/hsak_tools_usage.md @@ -0,0 +1,125 @@ +# HSAK 工具使用说明 + +## 命令行接口 + +### 盘信息查询命令 + +#### 命令格式 + +```shell +libstorage-list [] [] +``` + +#### 参数说明 + +- commands: 只有“help”可选,“libstorage-list help”用于显示帮助内容。 + +- device: 指定PCI地址,格式如:0000:09:00.0,允许同时多个,中间用空格隔离,如果不设置具体的PCI地址,则命令行列出所有枚举到的设备信息。 + +#### 注意事项 + +- 故障注入功能仅限于开发、调试以及测试场景使用,禁止在用户现网使用,否则会引起业务及安全风险。 + +- 在执行本命令时,管理组件(ublock)服务端必须已经启动,用户态IO组件(uio)未启动或已正确启动均可。 + +- 对于未被ublock组件和用户态IO组件占用的盘,在本命令执行过程中会被占用,此时如果ublock组件或用户态IO组件尝试获取盘控制权,可能存储设备访问冲突,导致失败。 + +### 盘切换驱动命令 + +#### 命令格式 + +```shell +libstorage-shutdown reset [ ...] +``` + +#### 参数说明 + +- reset: 用于对指定盘从uio驱动切换到内核态驱动; + +- device: 指定PCI地址,格式如:0000:09:00.0,允许同时多个,中间用空格隔离。 + +#### 注意事项 + +- libstorage-shutdown reset命令用于将盘从用户态uio驱动切换到内核态nvme驱动。 + +- 在执行本命令时,管理组件(ublock)服务端必须已经启动,用户态IO组件未启动或已正确启动均可。 + +- libstorage-shutdown reset命令为危险动作,请确认在切换nvme设备驱动之前,用户态实例已经停止对nvme设备下发IO,nvme设备上的fd已全部关闭,且访问nvme设备的实例已退出。 + +### 获取IO统计数据命令 + +#### 命令格式 + +```shell +libstorage-iostat [-t ] [-i ] [-d ] +``` + +#### 参数说明 + +- -t: 时间间隔,以秒为单位,最小1秒,最大为3600秒。该参数为int型,如果入参值超过int型上限,将被截断成负数或者正数。 + +- -i: 收集次数,最小为1,最大为MAX_INT次,如果不设置,默认以时间间隔持续收集。该参数为int型,如果入参超过int型上限,将被截断成负数或者正数。 + +- -d:指定块设备名称(eg:nvme0n1,其依赖于/etc/spdk/nvme.conf.in中配置的控制器名称),可以通过本参数收集指定一个或多个设备性能数据,如果不设置本参数,则收集所有识别到的设备性能数据。 + +#### 注意事项 + +- IO统计配置项已使能。 + +- 进程已经通过用户态IO组件对所需要查询性能信息的盘下发IO操作。 + +- 如果当前环境上没有任何设备被业务进程占用下发IO,则该命令将在提示:You cannot get iostat info for nvme device no deliver io后退出。 + +- 在磁盘打开多队列情况下,IO统计工具将该磁盘上多队列的性能数据汇总后统一输出。 + +- IO统计工具最多支持8192个磁盘队列的数据记录。 + +- IO统计数据输出结果如下: + + | Device | r/s | w/s | rKB/s | wKB/s | avgrq-sz | avgqu-sz | r_await | w_await | await | svctm | util% | poll-n | + | ------ | ------- | ------- | ------- | ------- | ------------ | --------- | --------- | --------- | ---------- | ------------ | ----- | ------ | + | 设备名称 | 每秒读IO个数 | 每秒写IO个数 | 每秒读IO字节 | 每秒写IO字节 | 平均下发IO大小(字节) | 磁盘排队的IO深度 | IO读时延(us) | IO写时延(us) | 读写平均时延(us) | 单个IO处理时延(us) | 设备利用率 | 轮询超时次数 | + +## 盘读写命令 + +### 命令格式 + +```shell +libstorage-rw [OPTIONS...] +``` + +### 参数说明 + +1. COMMAND参数 + + - read,从设备读取指定的逻辑块到数据缓存区(默认是标准输出)。 + + - write,将数据缓存区(默认是标准输入)的数据写入到NVMe设备的指定逻辑块。 + + - help,显示该命令行的帮助信息。 + +2. device: 指定PCI地址,格式如:0000:09:00.0。 + +3. OPTIONS参数 + + - --start-block,-s:读写逻辑块的64位首地址(缺省值为0)。 + + - --block-count,-c:读写逻辑块的数量(从0开始计数)。 + + - --data-size,-z:读写数据的字节数。 + + - --namespace-id,-n:设备的namespace id(默认id值是1)。 + + - --data,-d:读写用的数据文件(读时保存读出的数据,写时提供写入数据)。 + + - --limited-retry,-l:设备控制器进行有限次数的重启来完成设备读写。 + + - --force-unit-access,-f:确保指令完成之前从非易失介质中完成读写。 + + - --show-command,-v:发送读写命令之前显示指令相关信息。 + + - --dry-run,-w:仅显示读写指令相关信息,不进行实际读写操作。 + + - --latency,-t:统计命令行端到端读写的时延。 + + - --help,-h:显示相关命令的帮助信息。 diff --git a/docs/en/25.03/Server/MemoryandStorage/HSAK/introduce_hsak.md b/docs/en/25.03/Server/MemoryandStorage/HSAK/introduce_hsak.md new file mode 100644 index 0000000000000000000000000000000000000000..63d102908ddff3901c5ea3031b88d4db1a027481 --- /dev/null +++ b/docs/en/25.03/Server/MemoryandStorage/HSAK/introduce_hsak.md @@ -0,0 +1,47 @@ +# HSAK开发者指南 + +## 介绍 + +随着NVMe SSD、SCM等存储介质性能不断提升,介质层在IO栈中的时延开销不断缩减,软件栈的开销成为瓶颈,急需重构内核IO数据面,减少软件栈的开销,HSAK针对新型存储介质提供高带宽低时延的IO软件栈,相对传统IO软件栈,软件栈开销降低50%以上。 +HSAK用户态IO引擎基于开源的SPDK基础上进行开发: + +1. 对外提供统一的接口,屏蔽开源接口的差异。 +2. 在开源基础上新增IO数据面增强特性,如DIF功能,磁盘格式化,IO批量下发,trim特性,动态增删盘等特性。 +3. 提供磁盘设备管理,磁盘IO监测,维测工具等特性。 + +## 编译教程 + +1. 下载hsak源码 + + $ git clone + +2. 编译和运行依赖 + + hsak的编译和运行依赖于spdk、dpdk、libboundscheck等组件 + +3. 编译 + + $ cd hsak + + $ mkdir build + + $ cd build + + $ cmake .. + + $ make + +## 注意事项 + +### 使用约束 + +- 同一台机器最多使用和管理512个NVMe设备。 +- 启用HSAK执行IO相关业务时,需要确保系统有至少500M以上连续的空闲大页内存。 +- 启用用户态IO组件执行相关业务时,需要确保硬盘管理组件(ublock)已经启用。 +- 启用磁盘管理组件(ublock)执行相关业务时,需确保系统有足够的连续空闲内存,每次初始化ublock组件会申请20MB大页内存。 +- 每次运行HSAK之前,产品需要调用setup.sh来配置大页,解绑NVMe设备内核态驱动。 +- 执行libstorage_init_module成功后方可使用HSAK模块提供的其他接口;每个进程仅能执行一次libstorage_init_module调用。 +- 执行libstorage_exit_module函数之后不能再使用HSAK提供的其他接口,再多线程场景特别需要注意,在所有线程结束之后再退出HSAK。 +- HSAK ublock组件在一个服务器上只能启动一个服务,且最大支持64个ublock客户端并发访问,ublock服务端处理客户端请求的处理上限是20次/秒。 +- HSAK ublock组件必须早于数据面IO组件和ublock客户端启动,HSAK提供的命令行工具也必须在ublock服务端启动后才能执行。 +- 不要注册SIGBUS信号处理函数;spdk针对该信号有单独的处理函数;若该函数被覆盖,会导致spdk注册的SIGBUS处理函数失效,产生coredump。 diff --git a/docs/en/25.03/Server/MemoryandStorage/etmem/_menu.md b/docs/en/25.03/Server/MemoryandStorage/etmem/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..b94537768a44a6b606520a97c999a4695f14cff9 --- /dev/null +++ b/docs/en/25.03/Server/MemoryandStorage/etmem/_menu.md @@ -0,0 +1,9 @@ +--- +label: 'etmem用户指南' +ismanual: 'Y' +description: '使用内存分级扩展技术 etmem 扩展内存容量' +children: + - label: '使用etmem' + href: './memory-management.md' +--- + diff --git a/docs/en/25.03/Server/MemoryandStorage/etmem/memory-management.md b/docs/en/25.03/Server/MemoryandStorage/etmem/memory-management.md new file mode 100644 index 0000000000000000000000000000000000000000..b9df37a949566a33d08ec51a1ca38e895e8a9d7f --- /dev/null +++ b/docs/en/25.03/Server/MemoryandStorage/etmem/memory-management.md @@ -0,0 +1,798 @@ +# etmem用户指南 + +## 介绍 + +随着CPU算力的发展,尤其是ARM核成本的降低,内存成本和内存容量成为约束业务成本和性能的核心痛点,因此如何节省内存成本,如何扩大内存容量成为存储迫切要解决的问题。 + +etmem内存分级扩展技术,通过DRAM+内存压缩/高性能存储新介质形成多级内存存储,对内存数据进行分级,将分级后的内存冷数据从内存介质迁移到高性能存储介质中,达到内存容量扩展的目的,从而实现内存成本下降。 + +etmem软件包运行的工具主要分为etmem客户端和etmemd服务端。etmemd服务端工具,运行后常驻,其中实现了目的进程的内存冷热识别及淘汰等功能。etmem客户端工具,调用时运行一次,根据命令参数的不同,控制etmemd服务端响应不同的操作。 + +## 编译教程 + +1. 下载etmem源码 + + ```bash + git clone https://gitee.com/openeuler/etmem.git + ``` + +2. 编译和运行依赖 + + etmem的编译和运行依赖于libboundscheck组件 + + 安装命令: + + ```bash + yum install libboundscheck + ``` + + 通过rpm包进行确认是否安装: + + ```bash + rpm -qi libboundscheck + ``` + +3. 编译 + + ```bash + cd etmem + + mkdir build + + cd build + + cmake .. + + make + ``` + +## 注意事项 + +### 运行依赖 + +etmem作为内存扩展工具,需要依赖于内核态的特性支持,为了可以识别内存访问情况和支持主动将内存写入swap分区来达到内存垂直扩展的需求,etmem在运行时需要插入`etmem_scan`和`etmem_swap`模块: + +```bash +modprobe etmem_scan +modprobe etmem_swap +``` + +### 权限限制 + +运行etmem进程需要root权限,root用户具有系统最高权限,在使用root用户进行操作时,请严格按照操作指导进行操作,避免其他操作造成系统管理及安全风险。 + +### 使用约束 + +- etmem的客户端和服务端需要在同一个服务器上部署,不支持跨服务器通信的场景。 +- etmem仅支持扫描进程名小于或等于15个字符长度的目标进程。在使用进程名时,支持的进程名有效字符为:“字母”, “数字”,特殊字符“./%-_”以及上述三种的组合,其余组合认为是非法字符。 +- 在使用AEP介质进行内存扩展的时候,依赖于系统可以正确识别AEP设备并将AEP设备初始化为`numa node`。并且配置文件中的`vm_flags`字段只能配置为`ht`。 +- 引擎私有命令仅针对对应引擎和引擎下的任务有效,比如cslide所支持的`showhostpages`和`showtaskpages`。 +- 第三方策略实现代码中,`eng_mgt_func`接口中的`fd`不能写入`0xff`和`0xfe`字。 +- 支持在一个工程内添加多个不同的第三方策略动态库,以配置文件中的`eng_name`来区分。 +- 禁止并发扫描同一个进程。 +- 未加载`etmem_scan`和`etmem_swap` ko时,禁止使用`/proc/xxx/idle_pages`和`/proc/xxx/swap_pages`文件。 +- etmem对应配置文件,其权限要求为属主为root用户,且权限为600或400,配置文件大小不超过10M。 +- etmem在进行第三方策略注入时,第三方策略的`so`权限要求为属主为root用户,且权限为500或700。 + +## 使用说明 + +### etmem配置文件 + +在运行etmem进程之前,需要管理员预先规划哪些进程需要做内存扩展,将进程信息配置到etmem配置文件中,并配置内存扫描的周期、扫描次数、内存冷热阈值等信息。 + +配置文件的示例文件在源码包中,放置在`/etc/etmem`文件路径下,按照功能划分为3个示例文件, + +```text +/etc/etmem/cslide_conf.yaml +/etc/etmem/slide_conf.yaml +/etc/etmem/thirdparty_conf.yaml +``` + +示例内容分别为: + +```sh +#slide引擎示例 +#slide_conf.yaml +[project] +name=test +loop=1 +interval=1 +sleep=1 +sysmem_threshold=50 +swapcache_high_vmark=10 +swapcache_low_vmark=6 + +[engine] +name=slide +project=test + +[task] +project=test +engine=slide +name=background_slide +type=name +value=mysql +T=1 +max_threads=1 +swap_threshold=10g +swap_flag=yes + +#cslide引擎示例 +#cslide_conf.yaml +[engine] +name=cslide +project=test +node_pair=2,0;3,1 +hot_threshold=1 +node_mig_quota=1024 +node_hot_reserve=1024 + +[task] +project=test +engine=cslide +name=background_cslide +type=pid +name=23456 +vm_flags=ht +anon_only=no +ign_host=no + +#thirdparty引擎示例 +#thirdparty_conf.yaml +[engine] +name=thirdparty +project=test +eng_name=my_engine +libname=/usr/lib/etmem_fetch/my_engine.so +ops_name=my_engine_ops +engine_private_key=engine_private_value + +[task] +project=test +engine=my_engine +name=background_third +type=pid +value=12345 +task_private_key=task_private_value +``` + +配置文件各字段说明: + +| 配置项 | 配置项含义 | 是否必须 | 是否有参数 | 参数范围 | 示例说明 | +|-----------|---------------------|------|-------|------------|-----------------------------------------------------------------| +| [project] | project公用配置段起始标识 | 否 | 否 | NA | project参数的开头标识,表示下面的参数直到另外的[xxx]或文件结尾为止的范围内均为project section的参数 | +| name | project的名字 | 是 | 是 | 64个字以内的字符串 | 用来标识project,engine和task在配置时需要指定要挂载到的project | +| loop | 内存扫描的循环次数 | 是 | 是 | 1~120 | loop=3 //扫描3次 | +| interval | 每次内存扫描的时间间隔 | 是 | 是 | 1~1200 | interval=5 //每次扫描之间间隔5s | +| sleep | 每个内存扫描+操作的大周期之间时间间隔 | 是 | 是 | 1~1200 | sleep=10 //每次大周期之间间隔10s | +| sysmem_threshold| slide engine的配置项,系统内存换出阈值 | 否 | 是 | 0~100 | sysmem_threshold=50 //系统内存剩余量小于50%时,etmem才会触发内存换出| +| swapcache_high_wmark| slide engine的配置项,swacache可以占用系统内存的比例,高水线 | 否 | 是 | 1~100 | swapcache_high_wmark=5 //swapcache内存占用量可以为系统内存的5%,超过该比例,etmem会触发swapcache回收
注: swapcache_high_wmark需要大于swapcache_low_wmark| +| swapcache_low_wmark| slide engine的配置项,swacache可以占用系统内存的比例,低水线 | 否 | 是 | [1~swapcache_high_wmark) | swapcache_low_wmark=3 //触发swapcache回收后,系统会将swapcache内存占用量回收到低于3%| +| [engine] | engine公用配置段起始标识 | 否 | 否 | NA | engine参数的开头标识,表示下面的参数直到另外的[xxx]或文件结尾为止的范围内均为engine section的参数 | +| project | 声明所在的project | 是 | 是 | 64个字以内的字符串 | 已经存在名字为test的project,则可以写为project=test | +| engine | 声明所在的engine | 是 | 是 | slide/cslide/thridparty | 声明使用的是slide或cslide或thirdparty策略 | +| node_pair | cslide engine的配置项,声明系统中AEP和DRAM的node pair | engine为cslide时必须配置 | 是 | 成对配置AEP和DRAM的node号,AEP和DRAM之间用逗号隔开,没对pair之间用分号隔开 | node_pair=2,0;3,1 | +| hot_threshold | cslide engine的配置项,声明内存冷热水线的阈值 | engine为cslide时必须配置 | 是 | 大于等于0,小于等于INT_MAX的整数 | hot_threshold=3 //访问次数小于3的内存会被识别为冷内存 | +|node_mig_quota|cslide engine的配置项,流控,声明每次DRAM和AEP互相迁移时单向最大流量|engine为cslide时必须配置|是|大于等于0,小于等于INT_MAX的整数|node_mig_quota=1024 //单位为MB,AEP到DRAM或DRAM到AEP搬迁一次最大1024M| +|node_hot_reserve|cslide engine的配置项,声明DRAM中热内存的预留空间大小|engine为cslide时必须配置|是|大于等于0,小于等于INT_MAX的整数|node_hot_reserve=1024 //单位为MB,当所有虚拟机热内存大于此配置值时,热内存也会迁移到AEP中| +|eng_name|thirdparty engine的配置项,声明engine自己的名字,供task挂载|engine为thirdparty时必须配置|是|64个字以内的字符串|eng_name=my_engine //对此第三方策略engine挂载task时,task中写明engine=my_engine| +|libname|thirdparty engine的配置项,声明第三方策略的动态库的地址,绝对地址|engine为thirdparty时必须配置|是|256个字以内的字符串|libname=/user/lib/etmem_fetch/code_test/my_engine.so| +|ops_name|thirdparty engine的配置项,声明第三方策略的动态库中操作符号的名字|engine为thirdparty时必须配置|是|256个字以内的字符串|ops_name=my_engine_ops //第三方策略实现接口的结构体的名字| +|engine_private_key|thirdparty engine的配置项,预留给第三方策略自己解析私有参数的配置项,选配|否|否|根据第三方策略私有参数自行限制|根据第三方策略私有engine参数自行配置| +| [task] | task公用配置段起始标识 | 否 | 否 | NA | task参数的开头标识,表示下面的参数直到另外的[xxx]或文件结尾为止的范围内均为task section的参数 | +| project | 声明所挂的project | 是 | 是 | 64个字以内的字符串 | 已经存在名字为test的project,则可以写为project=test | +| engine | 声明所挂的engine | 是 | 是 | 64个字以内的字符串 | 所要挂载的engine的名字 | +| name | task的名字 | 是 | 是 | 64个字以内的字符串 | name=background1 //声明task的名字是backgound1 | +| type | 目标进程识别的方式 | 是 | 是 | pid/name | pid代表通过进程号识别,name代表通过进程名称识别 | +| value | 目标进程识别的具体字段 | 是 | 是 | 实际的进程号/进程名称 | 与type字段配合使用,指定目标进程的进程号或进程名称,由使用者保证配置的正确及唯一性 | +| T | engine为slide的task配置项,声明内存冷热水线的阈值 | engine为slide时必须配置 | 是 | 0~loop * 3 | T=3 //访问次数小于3的内存会被识别为冷内存 | +| max_threads | engine为slide的task配置项,etmemd内部线程池最大线程数,每个线程处理一个进程/子进程的内存扫描+操作任务 | 否 | 是 | 1~2 * core数 + 1,缺省值为1 | 对外部无表象,控制etmemd服务端内部处理线程个数,当目标进程有多个子进程时,配置越大,并发执行的个数也多,但占用资源也越多 | +| vm_flags | engine为cslide的task配置项,通过指定flag扫描的vma,不配置此项时扫描则不会区分 | 否 | 是 | 256长度以内的字符串,不同flag以空格隔开 | vm_flags=ht //扫描flags为ht(大页)的vma内存 | +| anon_only | engine为cslide的task配置项,标识是否只扫描匿名页 | 否 | 是 | yes/no | anon_only=no //配置为yes时只扫描匿名页,配置为no时非匿名页也会扫描 | +| ign_host | engine为cslide的task配置项,标识是否忽略host上的页表扫描信息 | 否 | 是 | yes/no | ign_host=no //yes为忽略,no为不忽略 | +| task_private_key | engine为thirdparty的task配置项,预留给第三方策略的task解析私有参数的配置项,选配 | 否 | 否 | 根据第三方策略私有参数自行限制 | 根据第三方策略私有task参数自行配置 | +| swap_threshold |slide engine的配置项,进程内存换出阈值 | 否 | 是 | 进程可用内存绝对值 | swap_threshold=10g //进程占用内存在低于10g时不会触发换出。
当前版本下,仅支持g/G作为内存绝对值单位。与sysmem_threshold配合使用,仅系统内存低于阈值时,进行白名单中进程阈值判断 | +| swap_flag|slide engine的配置项,进程指定内存换出 | 否 | 是 | yes/no | swap_flag=yes//使能进程指定内存换出 | + +### etmemd服务端启动 + +在使用etmem提供的服务时,首先根据需要修改相应的配置文件,然后运行etmemd服务端,常驻在系统中来操作目标进程的内存。除了支持在命令行中通过二进制来启动etmemd的进程外,还可以通过配置`service`文件来使etmemd服务端通过`systemctl`方式拉起,此场景需要通过`mode-systemctl`参数来指定支持 + +#### 使用方法 + +可以通过下列示例命令启动etmemd的服务端: + +```bash +etmemd -l 0 -s etmemd_socket +``` + +或者 + +```bash +etmemd --log-level 0 --socket etmemd_socket +``` + +其中`-l`的`0`和`-s`的`etmemd_socket`是用户自己输入的参数,参数具体含义参考以下列表。 + +#### 命令行参数说明 + +| 参数 | 参数含义 | 是否必须 | 是否有参数 | 参数范围 | 示例说明 | +| --------------- | ---------------------------------- | -------- | ---------- | --------------------- | ------------------------------------------------------------ | +| -l或\-\-log-level | etmemd日志级别 | 否 | 是 | 0~3 | 0:debug级别
1:info级别
2:warning级别
3:error级别
只有大于等于配置的级别才会打印到/var/log/message文件中 | +| -s或\-\-socket | etmemd监听的名称,用于与客户端交互 | 是 | 是 | 107个字符之内的字符串 | 指定服务端监听的名称 | +| -m或\-\-mode-systemctl| 指定通过systemctl方式来拉起stmemd服务| 否| 否| NA| service文件中需要指定-m参数| +| -h或\-\-help | 帮助信息 | 否 | 否 | NA | 执行时带有此参数会打印后退出 | + +### 通过etmem客户端添加或者删除工程/引擎/任务 + +#### 场景描述 + +1)管理员创建etmem的project/engine/task(一个工程可包含多个etmem engine,一个engine可以包含多个任务) + +2)管理员删除已有的etmem project/engine/task(删除工程前,会自动先停止该工程中的所有任务) + +#### 使用方法 + +在etmemd服务端正常运行后,通过etmem客户端,通过第二个参数指定为obj,来进行创建或删除动作,对project/engine/task则是通过配置文件中配置的内容来进行识别和区分。 + +- 添加对象: + + ```bash + etmem obj add -f /etc/etmem/slide_conf.yaml -s etmemd_socket + ``` + + 或 + + ```bash + etmem obj add --file /etc/etmem/slide_conf.yaml --socket etmemd_socket + ``` + +- 删除对象: + + ```bash + etmem obj del -f /etc/etmem/slide_conf.yaml -s etmemd_socket + ``` + + 或 + + ```bash + etmem obj del --file /etc/etmem/slide_conf.yaml --socket etmemd_socket + ``` + +#### 命令行参数说明 + +| 参数 | 参数含义 | 是否必须 | 是否有参数 | 示例说明 | +| ------------ | ------------------------------------------------------------ | -------- | ---------- | -------------------------------------------------------- | +| -f或\-\-file | 指定对象的配置文件 | 是 | 是 | 需要指定路径名称 | +| -s或\-\-socket | 与etmemd服务端通信的socket名称,需要与etmemd启动时指定的保持一致 | 是 | 是 | 必须配置,在有多个etmemd时,由管理员选择与哪个etmemd通信 | + +### 通过etmem客户端查询/启动/停止工程 + +#### 场景描述 + +在已经通过`etmem obj add`添加工程之后,在还未调用`etmem obj del`删除工程之前,可以对etmem的工程进行启动和停止。 + +1)管理员启动已添加的工程 + +2)管理员停止已启动的工程 + +在管理员调用`obj del`删除工程时,如果工程已经启动,则会自动停止。 + +#### 使用方法 + +对于已经添加成功的工程,可以通过`etmem project`的命令来控制工程的启动和停止,命令示例如下: + +- 查询工程 + + ```bash + etmem project show -n test -s etmemd_socket + ``` + + 或 + + ```bash + etmem project show --name test --socket etmemd_socket + ``` + +- 启动工程 + + ```bash + etmem project start -n test -s etmemd_socket + ``` + + 或 + + ```bash + etmem project start --name test --socket etmemd_socket + ``` + +- 停止工程 + + ```bash + etmem project stop -n test -s etmemd_socket + ``` + + 或 + + ```bash + etmem project stop --name test --socket etmemd_socket + ``` + +- 打印帮助 + + ```bash + etmem project help + ``` + +#### 命令行参数说明 + +| 参数 | 参数含义 | 是否必须 | 是否有参数 | 示例说明 | +| ------------ | ------------------------------------------------------------ | -------- | ---------- | -------------------------------------------------------- | +| -n或\-\-name | 指定project名称 | 是 | 是 | project名称,与配置文件一一对应 | +| -s或\-\-socket | 与etmemd服务端通信的socket名称,需要与etmemd启动时指定的保持一致 | 是 | 是 | 必须配置,在有多个etmemd时,由管理员选择与哪个etmemd通信 | + +### 通过etmem客户端,支持内存阈值换出以及指定内存换出 + +当前支持的策略中,只有slide策略支持私有的功能特性 + +- 进程或系统内存阈值换出 + +为了获得业务的极致性能,需要考虑etmem内存扩展进行内存换出的时机;当系统可用内存足够,系统内存压力不大时,不进行内存交换;当进程占用内存不高时,不进行内存交换;提供系统内存换出阈值控制以及进程内存换出阈值控制。 + +- 进程指定内存换出 + +在存储环境下,具有IO时延敏感型业务进程,上述进程内存不希望进行换出,因此提供一种机制,由业务指定可换出内存 + +针对进程或系统内存阈值换出,进程指定内存换出功能,可以在配置文件中添加`sysmem_threshold`,`swap_threshold`,`swap_flag`参数,示例如下,具体含义请参考etmem配置文件说明章节。 + +```sh +#slide_conf.yaml +[project] +name=test +loop=1 +interval=1 +sleep=1 +sysmem_threshold=50 + +[engine] +name=slide +project=test + +[task] +project=test +engine=slide +name=background_slide +type=name +value=mysql +T=1 +max_threads=1 +swap_threshold=10g +swap_flag=yes +``` + +#### 系统内存阈值换出 + +配置文件中`sysmem_threshold`用于指示系统内存阈值换出功能,`sysmem_threshold`取值范围为0-100,如果配置文件中设定了`sysmem_threshold`,那么只有系统内存剩余量低于该比例时,etmem才会触发内存换出流程 + +示例使用方法如下: + +1. 参考示例编写配置文件,配置文件中填写`sysmem_threshold`参数,例如`sysmem_threshold=20` +2. 启动服务端,并通过服务端添加,启动工程。 + + ```bash + etmemd -l 0 -s monitor_app & + etmem obj add -f etmem_config -s monitor_app + etmem project start -n test -s monitor_app + etmem project show -s monitor_app + ``` + +3. 观察内存换出结果,只有系统可用内存低于20%时,etmem才会触发内存换出 + +#### 进程内存阈值换出 + +配置文件中`swap_threshold`用于指示进程内存阈值换出功能,`swap_threshold`为进程内存占用量绝对值(格式为"数字+单位g/G"),如果配置文件中设定了`swap_threshold`,那么该进程内存占用量在小于该设定的可用内存量时,etmem不会针对该进程触发换出流程 + +示例使用方法如下: + +1. 参考示例编写配置文件,配置文件中填写`swap_threshold`参数,例如`swap_threshold=5g` +2. 启动服务端,并通过服务端添加,启动工程。 + + ```bash + etmemd -l 0 -s monitor_app & + etmem obj add -f etmem_config -s monitor_app + etmem project start -n test -s monitor_app + etmem project show -s monitor_app + ``` + +3. 观察内存换出结果,只有进程占用内存绝对值高于5G时,etmem才会触发内存换出 + +#### 进程指定内存换出 + +配置文件中`swap_flag`用于指示进程指定内存换出功能,`swap_flag`取值仅有两个:`yes/no`,如果配置文件中设定了`swap_flag`为no或者未配置,那么etmem换出功能无变化,如果`swap_flag`设定为yes,那么etmem仅仅换出进程指定的内存。 + +示例使用方法如下: + +1. 参考示例编写配置文件,配置文件中填写`swap_flag`参数,例如`swap_flag=yes` +2. 业务进程对需要进行换出的内存打标记 + + ```bash + madvise(addr_start, addr_len, MADV_SWAPFLAG) + ``` + +3. 启动服务端,并通过服务端添加,启动工程。 + + ```bash + etmemd -l 0 -s monitor_app & + etmem obj add -f etmem_config -s monitor_app + etmem project start -n test -s monitor_app + etmem project show -s monitor_app + ``` + +4. 观察内存换出结果,只有进程打标记的部分内存会被换出,其余内存保留在DRAM中,不会被换出 + +针对进程指定页面换出的场景中,在原扫描接口`idle_pages`中添加`ioctl`命令字的形式,来确认不带有特定标记的vma不进行扫描与换出操作 + +扫描管理接口 + +- 函数原型 + + ```c + ioctl(fd, cmd, void *arg); + ``` + +- 输入参数 + + ```text + 1. fd:文件描述符,通过open调用在/proc/pid/idle_pages下打开文件获得 + + 2.cmd:控制扫描行为,当前支持如下cmd: + VMA_SCAN_ADD_FLAGS:新增vma指定内存换出标记,仅扫描带有特定标记的VMA + VMA_SCAN_REMOVE_FLAGS:删除新增的VMA指定内存换出标记 + + 3.args:int指针参数,传递具体标记掩码,当前仅支持如下参数: + VMA_SCAN_FLAG:在etmem_scan.ko扫描模块开始扫描前,会调用接口walk_page_test接口判断vma地址是否符合扫描要求,此标记置位时,会仅扫描带有特定换出标记的vma地址段,而忽略其他vma地址 + ``` + +- 返回值 + + ```text + 1.成功,返回0 + 2.失败返回非0 + ``` + +- 注意事项 + + ```text + 所有不支持的标记都会被忽略,但是不会返回错误 + ``` + +### 通过etmem客户端,支持swapcache内存回收指令 + +用户态etmem发起内存淘汰回收操作,通过`write procfs`接口与内核态的内存回收模块交互,内存回收模块解析用户态下发的虚拟地址,获取地址对应的page页面,并调用内核原生接口将该page对应内存进行换出回收,在内存换出的过程中,swapcache会占用部分系统内存,为进一步节约内存,添加swapcache内存回收功能. + +针对swapcache内存回收功能,可以在配置文件中添加`swapcache_high_wmark`,`swapcache_low_wmark`参数。 + +- `swapcache_high_wmark`: swapcache可以占用系统内存的高水位线 +- `swapcache_low_wmark`:swapcache可以占用系统内存的低水位线 + +在etmem进行一轮内存换出后,会进行swapcache占用系统内存比例的检查,当占用比例超过高水位线后,会通过`swap_pages`下发`ioctl`命令,触发swapcache内存回收,并回收到低水位线停止 + +配置参数示例如下,具体请参考etmem配置文件相关章节: + +```sh +#slide_conf.yaml +[project] +name=test +loop=1 +interval=1 +sleep=1 +swapcache_high_vmark=5 +swapcache_low_vmark=3 + +[engine] +name=slide +project=test + +[task] +project=test +engine=slide +name=background_slide +type=name +value=mysql +T=1 +max_threads=1 +``` + +针对swap换出场景中,需要通过swapcache内存回收进一步节约内存,在原内存换出接口`swap_pages`中通过添加`ioctl`接口的方式,来提供swapcache水线的设定以及swapcache内存占用量回收的启动与关闭 + +- 函数原型 + + ```c + ioctl(fd, cmd, void *arg); + ``` + +- 输入参数 + + ```text + 1. fd:文件描述符,通过open调用在/proc/pid/idle_pages下打开文件获得 + + 2.cmd:控制扫描行为,当前支持如下cmd: + RECLAIM_SWAPCACHE_ON:启动swapcache内存换出 + RECLAIM_SWAPCACHE_OFF:关闭swapcache内存换出 + SET_SWAPCACHE_WMARK:设定swapcache内存水线 + + 3.args:int指针参数,传递具体标记掩码,当前仅支持如下参数: + 参数用来传递swapcache水线具体值 + ``` + +- 返回值 + + ```text + 1.成功,返回0 + 2.失败返回非0 + ``` + +- 注意事项 + + ```text + 所有不支持的标记都会被忽略,但是不会返回错误 + ``` + +### 通过etmem客户端,执行引擎私有命令或功能 + +当前支持的策略中,只有cslide策略支持私有的命令 + +- `showtaskpages` +- `showhostpages` + +针对使用此策略引擎的engine和engine所有的task,可以通过这两个命令分别查看task相关的页面访问情况和虚拟机的host上系统大页的使用情况。 + +示例命令如下: + +```bash +etmem engine showtaskpages <-t task_name> -n proj_name -e cslide -s etmemd_socket +etmem engine showhostpages -n proj_name -e cslide -s etmemd_socket +``` + +**注意** :`showtaskpages`和`showhostpages`仅支持引擎使用cslide的场景 + +#### 命令行参数说明 + +| 参数 | 参数含义 | 是否必须 | 是否有参数 | 实例说明 | +|----|------|------|-------|------| +|-n或\-\-proj_name| 指定project的名字| 是| 是| 指定已经存在,所需要执行的project的名字| +|-s或\-\-socket| 与etmemd服务端通信的socket名称,需要与etmemd启动时指定的保持一致| 是| 是| 必须配置,在有多个etmemd时,由管理员选择与哪个etmemd通信| +|-e或\-\-engine| 指定执行的引擎的名字| 是| 是| 指定已经存在的,所需要执行的引擎的名字| +|-t或\-\-task_name| 指定执行的任务的名字| 否| 是| 指定已经存在的,所需要执行的任务的名字| + +### 支持kernel swap功能开启与关闭 + +针对swap换出到磁盘场景,当etmem用于内存扩展时,用户可以选择是否同时开启内核swap功能。用户可以关闭内核原生swap机制,以免原生swap机制换出不应被换出的内存,导致用户态进程出现问题。 + +通过提供sys接口实现上述控制,在`/sys/kernel/mm/swap`目录下创建`kobj`对象,对象名为`kernel_swap_enable`,缺省值为`true`,用于控制kernel swap的启动与关闭 + +具体示例如下: + +```sh +#开启kernel swap +echo true > /sys/kernel/mm/swap/kernel_swap_enbale +或者 +echo 1 > /sys/kernel/mm/swap/kernel_swap_enbale + +#关闭kernel swap +echo false > /sys/kernel/mm/swap/kernel_swap_enbale +或者 +echo 0 > /sys/kernel/mm/swap/kernel_swap_enbale + +``` + +### etmem支持随系统自启动 + +#### 场景描述 + +etmemd支持由用户配置`systemd`配置文件后,以`fork`模式作为`systemd`服务被拉起运行 + +#### 使用方法 + +编写`service`配置文件,来启动etmemd,必须使用-m参数来指定此模式,例如 + +```bash +etmemd -l 0 -s etmemd_socket -m +``` + +#### 命令行参数说明 + +| 参数 | 参数含义 | 是否必须 | 是否有参数 | 参数范围 | 实例说明 | +|----------------|------------|------|-------|------|-----------| +| -l或\-\-log-level | etmemd日志级别 | 否 | 是 | 0~3 | 0:debug级别;1:info级别;2:warning级别;3:error级别;只有大于等于配置的级别才会打印到/var/log/message文件中| +| -s或\-\-socket |etmemd监听的名称,用于与客户端交互 | 是 | 是| 107个字符之内的字符串| 指定服务端监听的名称| +|-m或\-\-mode-systemctl | etmemd作为service被拉起时,命令中需要指定此参数来支持 | 否 | 否 | NA | NA | +| -h或\-\-help | 帮助信息 | 否 |否 |NA |执行时带有此参数会打印后退出| + +### etmem支持第三方内存扩展策略 + +#### 场景描述 + +etmem支持用户注册第三方内存扩展策略,同时提供扫描模块动态库,运行时通过第三方策略淘汰算法淘汰内存。 + +用户使用etmem所提供的扫描模块动态库并实现对接etmem所需要的结构体中的接口 + +#### 使用方法 + +用户使用自己实现的第三方扩展淘汰策略,主要需要按下面步骤进行实现和操作: + +1. 按需调用扫描模块提供的扫描接口, + +2. 按照etmem头文件中提供的函数模板来实现各个接口,最终封装成结构体 + +3. 编译出第三方扩展淘汰策略的动态库 + +4. 在配置文件中按要求声明类型为thirdparty的engine + +5. 将动态库的名称和接口结构体的名称按要求填入配置文件中task对应的字段 + +其他操作步骤与使用etmem的其他engine类似 + +接口结构体模板 + +```c +struct engine_ops { + +/* 针对引擎私有参数的解析,如果有,需要实现,否则置NULL */ + +int (*fill_eng_params)(GKeyFile *config, struct engine *eng); + +/* 针对引擎私有参数的清理,如果有,需要实现,否则置NULL */ + +void (*clear_eng_params)(struct engine *eng); + +/* 针对任务私有参数的解析,如果有,需要实现,否则置NULL */ + +int (*fill_task_params)(GKeyFile *config, struct task *task); + +/* 针对任务私有参数的清理,如果有,需要实现,否则置NULL */ + +void (*clear_task_params)(struct task *tk); + +/* 启动任务的接口 */ + +int (*start_task)(struct engine *eng, struct task *tk); + +/* 停止任务的接口 */ + +void (*stop_task)(struct engine *eng, struct task *tk); + +/* 填充pid相关私有参数 */ + +int (*alloc_pid_params)(struct engine *eng, struct task_pid **tk_pid); + +/* 销毁pid相关私有参数 */ + +void (*free_pid_params)(struct engine *eng, struct task_pid **tk_pid); + +/* 第三方策略自身所需要的私有命令支持,如果没有,置为NULL */ + +int (*eng_mgt_func)(struct engine *eng, struct task *tk, char *cmd, int fd); + +}; +``` + +扫描模块对外接口说明 + +| 接口名称 |接口描述| +| ------------ | --------------------- | +| etmemd_scan_init | scan模块初始化| +| etmemd_scan_exit | scan模块析构| +| etmemd_get_vmas | 获取需要扫描的vma| +| etmemd_free_vmas | 释放etmemd_get_vmas扫描到的vma| +| etmemd_get_page_refs | 扫描vmas中的页面| +| etmemd_free_page_refs | 释放etmemd_get_page_refs获取到的页访问信息链表| + +针对扫描虚拟机的场景中,在原扫描接口`idle_pages`中添加`ioctl`接口的方式,来提供区分扫描`ept`的粒度和是否忽略host上页访问标记的机制 + +针对进程指定页面换出的场景中,在原扫描接口`idle_pages`中添加`ioctl`命令字的形式,来确认不带有特定标记的vma不进行扫描和换出操作 + +扫描管理接口: + +- 函数原型 + + ```c + ioctl(fd, cmd, void *arg); + ``` + +- 输入参数 + + ```text + 1. fd:文件描述符,通过open调用在/proc/pid/idle_pages下打开文件获得 + + 2.cmd:控制扫描行为,当前支持如下cmd: + IDLE_SCAN_ADD_FLAG:新增一个扫描标记 + IDLE_SCAM_REMOVE_FLAGS:删除一个扫描标记 + VMA_SCAN_ADD_FLAGS:新增vma指定内存换出标记,仅扫描带有特定标记的VMA + VMA_SCAN_REMOVE_FLAGS:删除新增的VMA指定内存换出标记 + + 3.args:int指针参数,传递具体标记掩码,当前仅支持如下参数: + SCAN_AS_HUGE:扫描ept页表时,按照2M大页粒度扫描页是否被访问过。此标记未置位时,按照ept页表自身粒度扫描 + SCAN_IGN_HUGE:扫描虚拟机时,忽略host侧页表上的访问标记。此标记未置位时,不会忽略host侧页表上的访问标记。 + VMA_SCAN_FLAG:在etmem_scan.ko扫描模块开始扫描前,会调用接口walk_page_test接口判断vma地址是否符合扫描要求,此标记置位时,会仅扫描带有特定换出标记的vma地址段,而忽略其他vma地址 + ``` + +- 返回值 + + ```text + 1. 成功,返回0 + 2. 失败返回非0 + ``` + +- 注意事项 + + ```text + 所有不支持的标记都会被忽略,但是不会返回错误 + ``` + +配置文件示例如下所示,具体含义请参考配置文件说明章节: + +```text +#thirdparty +[engine] +name=thirdparty +project=test +eng_name=my_engine +libname=/user/lib/etmem_fetch/code_test/my_engine.so +ops_name=my_engine_ops +engine_private_key=engine_private_value +[task] +project=test +engine=my_engine +name=background1 +type=pid +value=1798245 +task_private_key=task_private_value +``` + + **注意** : + +用户需使用etmem所提供的扫描模块动态库并实现对接etmem所需要的结构体中的接口 + +`eng_mgt_func`接口中的`fd`不能写入`0xff`和`0xfe`字 + +支持在一个工程内添加多个不同的第三方策略动态库,以配置文件中的`eng_name`来区分 + +### etmem客户端和服务端帮助说明 + +通过下列命令可以打印etmem服务端帮助说明 + +```bash +etmemd -h +``` + +或 + +```bash +etmemd --help +``` + +通过下列命令可以打印etmem客户端帮助说明 + +```bash +etmem help +``` + +通过下列命令可以打印etmem客户端操作工程/引擎/任务相关帮助说明 + +```bash +etmem obj help +``` + +通过下列命令可以打印etmem客户端对项目相关帮助说明 + +```bash +etmem project help +``` + +## 参与贡献 + +1. Fork本仓库 +2. 新建个人分支 +3. 提交代码 +4. 新建Pull Request diff --git a/docs/en/25.03/Server/MemoryandStorage/lvm/_menu.md b/docs/en/25.03/Server/MemoryandStorage/lvm/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..74bb18f953d67f279eeeddf1224b03f3360c3ab2 --- /dev/null +++ b/docs/en/25.03/Server/MemoryandStorage/lvm/_menu.md @@ -0,0 +1,8 @@ +--- +label: '配置和管理逻辑卷' +ismanual: 'Y' +description: '使用 LVM 管理硬盘' +children: + - label: '使用 LVM 管理硬盘' + href: './managing-hard-disks-through-lvm.md' +--- diff --git a/docs/en/25.03/Server/MemoryandStorage/lvm/managing-hard-disks-through-lvm.md b/docs/en/25.03/Server/MemoryandStorage/lvm/managing-hard-disks-through-lvm.md new file mode 100644 index 0000000000000000000000000000000000000000..1d98a17568d29aa4e0f09e60dee35ef91b92bae3 --- /dev/null +++ b/docs/en/25.03/Server/MemoryandStorage/lvm/managing-hard-disks-through-lvm.md @@ -0,0 +1,575 @@ +# 使用LVM管理硬盘 + + + +- [使用LVM管理硬盘](#使用lvm管理硬盘) + - [LVM简介](#lvm简介) + - [基本概念](#基本概念) + - [安装](#安装) + - [管理物理卷](#管理物理卷) + - [创建物理卷](#创建物理卷) + - [查看物理卷](#查看物理卷) + - [修改物理卷属性](#修改物理卷属性) + - [删除物理卷](#删除物理卷) + - [管理卷组](#管理卷组) + - [创建卷组](#创建卷组) + - [查看卷组](#查看卷组) + - [修改卷组属性](#修改卷组属性) + - [扩展卷组](#扩展卷组) + - [收缩卷组](#收缩卷组) + - [删除卷组](#删除卷组) + - [管理逻辑卷](#管理逻辑卷) + - [创建逻辑卷](#创建逻辑卷) + - [查看逻辑卷](#查看逻辑卷) + - [调整逻辑卷大小](#调整逻辑卷大小) + - [扩展逻辑卷](#扩展逻辑卷) + - [收缩逻辑卷](#收缩逻辑卷) + - [删除逻辑卷](#删除逻辑卷) + - [创建并挂载文件系统](#创建并挂载文件系统) + - [创建文件系统](#创建文件系统) + - [手动挂载文件系统](#手动挂载文件系统) + - [自动挂载文件系统](#自动挂载文件系统) + + + +## LVM简介 + +LVM是逻辑卷管理(Logical Volume Manager)的简称,它是Linux环境下对磁盘分区进行管理的一种机制。LVM通过在硬盘和文件系统之间添加一个逻辑层,来为文件系统屏蔽下层硬盘分区布局,提高硬盘分区管理的灵活性。 + +使用LVM管理硬盘的基本过程如下: + +1. 将硬盘创建为物理卷 +2. 将多个物理卷组合成卷组 +3. 在卷组中创建逻辑卷 +4. 在逻辑卷之上创建文件系统 + +通过LVM管理硬盘之后,文件系统不再受限于硬盘的大小,可以分布在多个硬盘上,也可以动态扩容。 + +### 基本概念 + +- 物理存储介质(The physical media):指系统的物理存储设备,如硬盘,系统中为/dev/hda、/dev/sda等等,是存储系统最低层的存储单元。 + +- 物理卷(Physical Volume,PV):指硬盘分区或从逻辑上与磁盘分区具有同样功能的设备\(如RAID\),是LVM的基本存储逻辑块。物理卷包括一个特殊的标签,该标签默认存放在第二个 512 字节扇区,但也可以将标签放在最开始的四个扇区之一。该标签包含物理卷的随机唯一识别符(UUID),记录块设备的大小和LVM元数据在设备中的存储位置。 + +- 卷组(Volume Group,VG):由物理卷组成,屏蔽了底层物理卷细节。可在卷组上创建一个或多个逻辑卷且不用考虑具体的物理卷信息。 + +- 逻辑卷(Logical Volume,LV):卷组不能直接用,需要划分成逻辑卷才能使用。逻辑卷可以格式化成不同的文件系统,挂载后直接使用。 + +- 物理块(Physical Extent,PE):物理卷以大小相等的“块”为单位存储,块的大小与卷组中逻辑卷块的大小相同。 + +- 逻辑块(Logical Extent,LE):逻辑卷以“块”为单位存储,在一卷组中的所有逻辑卷的块大小是相同的。 + +## 安装 + +> ![](../public_sys-resources/icon-note.gif) **说明:** +> openEuler操作系统默认已安装LVM。可通过**rpm -qa | grep lvm2**命令查询,若打印信息中包含“lvm2”信息,则表示已安装LVM,可跳过本章节内容;若无任何打印信息,则表示未安装,可参考本章节内容进行安装。 + +1. 配置本地yum源,详细信息请参考[搭建repo服务器](../../Administration/Administrator/configuring-the-repo-server.md)。 +2. 清除缓存。 + + ```shell + dnf clean all + ``` + +3. 创建缓存。 + + ```shell + dnf makecache + ``` + +4. 在root权限下安装LVM。 + + ```shell + # dnf install lvm2 + ``` + +5. 查看安装后的rpm包。 + + ```shell + rpm -qa | grep lvm2 + ``` + +## 管理物理卷 + +### 创建物理卷 + +可在root权限下通过pvcreate命令创建物理卷。 + +```shell +pvcreate [option] devname ... +``` + +其中: + +- option:命令参数选项。常用的参数选项有: + - -f:强制创建物理卷,不需要用户确认。 + + - -u:指定设备的UUID。 + - -y:所有的问题都回答“yes”。 + +- devname:指定要创建的物理卷对应的设备名称,如果需要批量创建,可以填写多个设备名称,中间以空格间隔。 + +示例1:将/dev/sdb、/dev/sdc创建为物理卷。 + +```shell +# pvcreate /dev/sdb /dev/sdc +``` + +示例2:将/dev/sdb1、/dev/sdb2创建为物理卷。 + +```shell +# pvcreate /dev/sdb1 /dev/sdb2 +``` + +### 查看物理卷 + +可在root权限通过pvdisplay命令查看物理卷的信息,包括:物理卷名称、所属的卷组、物理卷大小、PE大小、总PE数、可用PE数、已分配的PE数和UUID。 + +```shell +pvdisplay [option] devname +``` + +其中: + +- option:命令参数选项。常用的参数选项有: + - -s:以短格式输出。 + - -m:显示PE到LE的映射。 + +- devname:指定要查看的物理卷对应的设备名称。如果不指定物理卷名称,则显示所有物理卷的信息。 + +示例:显示物理卷/dev/sdb的基本信息。 + +```shell +# pvdisplay /dev/sdb +``` + +### 修改物理卷属性 + +可在root权限下通过pvchange命令修改物理卷的属性。 + +```shell +pvchange [option] pvname ... +``` + +其中: + +- option:命令参数选项。常用的参数选项有: + - -u:生成新的UUID。 + - -x:是否允许分配PE。 + +- pvname:指定要修改属性的物理卷对应的设备名称,如果需要批量修改,可以填写多个设备名称,中间以空格间隔。 + +示例:禁止分配/dev/sdb物理卷上的PE。没有加入卷组的物理卷执行pvdisplay命令显示Allocatable属性为NO,需要加入卷组才能成功修改该属性。 + +```shell +# pvchange -x n /dev/sdb +``` + +### 删除物理卷 + +可在root权限下通过pvremove命令删除物理卷。 + +```shell +pvremove [option] pvname ... +``` + +其中: + +- option:命令参数选项。常用的参数选项有: + - -f:强制删除物理卷,不需要用户确认。 + - -y:所有的问题都回答“yes”。 + +- pvname:指定要删除的物理卷对应的设备名称,如果需要批量删除,可以填写多个设备名称,中间以空格间隔。 + +示例:删除物理卷/dev/sdb。如果物理卷已经加入卷组,需要先删除卷组或者从卷组中移除,再删除物理卷。 + +```shell +# pvremove /dev/sdb +``` + +## 管理卷组 + +### 创建卷组 + +可在root权限下通过vgcreate命令创建卷组。 + +```shell +vgcreate [option] vgname pvname ... +``` + +其中: + +- option:命令参数选项。常用的参数选项有: + - -l:卷组上允许创建的最大逻辑卷数。 + - -p:卷组中允许添加的最大物理卷数。 + - -s:卷组上的物理卷的PE大小。 + +- vgname:要创建的卷组名称。 +- pvname:要加入到卷组中的物理卷名称。 + +示例:创建卷组 vg1,并且将物理卷/dev/sdb和/dev/sdc添加到卷组中。 + +```shell +# vgcreate vg1 /dev/sdb /dev/sdc +``` + +### 查看卷组 + +可在root权限下通过vgdisplay命令查看卷组的信息。 + +```shell +vgdisplay [option] [vgname] +``` + +其中: + +- option:命令参数选项。常用的参数选项有: + - -s:以短格式输出。 + - -A:仅显示活动卷组的属性。 + +- vgname:指定要查看的卷组名称。如果不指定卷组名称,则显示所有卷组的信息。 + +示例:显示卷组vg1的基本信息。 + +```shell +# vgdisplay vg1 +``` + +### 修改卷组属性 + +可在root权限下通过vgchange命令修改卷组的属性。 + +```shell +vgchange [option] vgname +``` + +其中: + +- option:命令参数选项。常用的参数选项有: + - -a:设置卷组的活动状态。 + +- vgname:指定要修改属性的卷组名称。 + +示例:将卷组vg1状态修改为活动。 + +```shell +# vgchange -ay vg1 +``` + +### 扩展卷组 + +可在root权限下通过vgextend命令动态扩展卷组。它通过向卷组中添加物理卷来增加卷组的容量。 + +```shell +vgextend [option] vgname pvname ... +``` + +其中: + +- option:命令参数选项。常用的参数选项有: + - -d:调试模式。 + - -t:仅测试。 + +- vgname:要扩展容量的卷组名称。 +- pvname:要加入到卷组中的物理卷名称。 + +示例:向卷组vg1中添加物理卷/dev/sdb。 + +```shell +# vgextend vg1 /dev/sdb +``` + +### 收缩卷组 + +可在root权限下通过vgreduce命令删除卷组中的物理卷来减少卷组容量。不能删除卷组中剩余的最后一个物理卷。 + +```shell +vgreduce [option] vgname pvname ... +``` + +其中: + +- option:命令参数选项。常用的参数选项有: + - -a:如果命令行中没有指定要删除的物理卷,则删除所有的空物理卷。 + - \-\-removemissing:删除卷组中丢失的物理卷,使卷组恢复正常状态。 + +- vgname:要收缩容量的卷组名称。 +- pvname:要从卷组中删除的物理卷名称。 + +示例:从卷组vg1中移除物理卷/dev/sdb2。 + +```shell +# vgreduce vg1 /dev/sdb2 +``` + +### 删除卷组 + +可在root权限下通过vgremove命令删除卷组。 + +```shell +vgremove [option] vgname +``` + +其中: + +- option:命令参数选项。常用的参数选项有: + - -f:强制删除卷组,不需要用户确认。 + +- vgname:指定要删除的卷组名称。 + +示例:删除卷组vg1。 + +```shell +# vgremove vg1 +``` + +## 管理逻辑卷 + +### 创建逻辑卷 + +可在root权限下通过lvcreate命令创建逻辑卷。 + +```shell +lvcreate [option] vgname +``` + +其中: + +- option:命令参数选项。常用的参数选项有: + - -L:指定逻辑卷的大小,单位为“kKmMgGtT”字节。 + - -l:指定逻辑卷的大小(LE数)。 + - -n:指定要创建的逻辑卷名称。 + - -s:创建快照。 + +- vgname:要创建逻辑卷的卷组名称。 + +示例1:在卷组vg1中创建10G大小的逻辑卷。 + +```shell +# lvcreate -L 10G vg1 +``` + +示例2:在卷组vg1中创建200M的逻辑卷,并命名为lv1。 + +```shell +# lvcreate -L 200M -n lv1 vg1 +``` + +### 查看逻辑卷 + +可在root权限下通过lvdisplay命令查看逻辑卷的信息,包括逻辑卷空间大小、读写状态和快照信息等属性。 + +```shell +lvdisplay [option] [lvname] +``` + +其中: + +- option:命令参数选项。常用的参数选项有: + + - -v:显示LE到PE的映射。 + +- lvname:指定要显示属性的逻辑卷对应的设备文件。如果省略,则显示所有的逻辑卷属性。 + + > ![](../public_sys-resources/icon-note.gif) **说明:** + > 逻辑卷对应的设备文件保存在卷组目录下,例如:在卷组vg1上创建一个逻辑卷lv1,则此逻辑卷对应的设备文件为/dev/vg1/lv1。 + +示例:显示逻辑卷lv1的基本信息。 + +```shell +# lvdisplay /dev/vg1/lv1 +``` + +### 调整逻辑卷大小 + +可在root权限下通过lvresize命令调整LVM逻辑卷的空间大小,可以增大空间和缩小空间。使用lvresize命令调整逻辑卷空间大小和缩小空间时需要谨慎,因为有可能导致数据丢失。 + +```shell +lvresize [option] vgname +``` + +其中: + +- option:命令参数选项。常用的参数选项有: + - -L:指定逻辑卷的大小,单位为“kKmMgGtT”字节。 + - -l:指定逻辑卷的大小(LE数)。 + - -f:强制调整逻辑卷大小,不需要用户确认。 + +- lvname:指定要调整的逻辑卷名称。 + +示例1:为逻辑卷/dev/vg1/lv1增加200M空间。 + +```shell +# lvresize -L +200 /dev/vg1/lv1 +``` + +示例2:为逻辑卷/dev/vg1/lv1减少200M空间。 + +```shell +# lvresize -L -200 /dev/vg1/lv1 +``` + +### 扩展逻辑卷 + +可在root权限下通过lvextend命令动态在线扩展逻辑卷的空间大小,而不中断应用程序对逻辑卷的访问。 + +```shell +lvextend [option] lvname +``` + +其中: + +- option:命令参数选项。常用的参数选项有: + - -L:指定逻辑卷的大小,单位为“kKmMgGtT”字节。 + - -l:指定逻辑卷的大小(LE数)。 + - -f:强制调整逻辑卷大小,不需要用户确认。 + +- lvname:指定要扩展空间的逻辑卷的设备文件。 + +示例:为逻辑卷/dev/vg1/lv1增加100M空间。 + +```shell +# lvextend -L +100M /dev/vg1/lv1 +``` + +### 收缩逻辑卷 + +可在root权限下通过lvreduce命令减少逻辑卷占用的空间大小。使用lvreduce命令收缩逻辑卷的空间大小有可能会删除逻辑卷上已有的数据,所以在操作前必须进行确认。 + +```shell +lvreduce [option] lvname +``` + +其中: + +- option:命令参数选项。常用的参数选项有: + - -L:指定逻辑卷的大小,单位为“kKmMgGtT”字节。 + - -l:指定逻辑卷的大小(LE数)。 + - -f:强制调整逻辑卷大小,不需要用户确认。 + +- lvname:指定要扩展空间的逻辑卷的设备文件。 + +示例:将逻辑卷/dev/vg1/lv1的空间减少100M。 + +```shell +# lvreduce -L -100M /dev/vg1/lv1 +``` + +### 删除逻辑卷 + +可在root权限下通过lvremove命令删除逻辑卷。如果逻辑卷已经使用mount命令加载,则不能使用lvremove命令删除。必须使用umount命令卸载后,逻辑卷方可被删除。 + +```shell +lvremove [option] vgname +``` + +其中: + +- option:命令参数选项。常用的参数选项有: + - -f:强制删除逻辑卷,不需要用户确认。 + +- vgname:指定要删除的逻辑卷。 + +示例:删除逻辑卷/dev/vg1/lv1。 + +```shell +# lvremove /dev/vg1/lv1 +``` + +## 创建并挂载文件系统 + +在创建完逻辑卷之后,需要在逻辑卷之上创建文件系统并挂载文件系统到相应目录下。 + +### 创建文件系统 + +可在root权限下通过mkfs命令创建文件系统。 + +```shell +mkfs [option] lvname +``` + +其中: + +- option:命令参数选项。常用的参数选项有: + - -t:指定创建的linux文件系统类型,如ext2,ext3,ext4等等,默认类型为ext2。 + +- lvname:指定要创建的文件系统对应的逻辑卷设备文件名。 + +示例:在逻辑卷/dev/vg1/lv1上创建ext4文件系统。 + +```shell +# mkfs -t ext4 /dev/vg1/lv1 +``` + +### 手动挂载文件系统 + +手动挂载的文件系统仅在当时有效,一旦操作系统重启则会不存在。 + +可在root权限下通过mount命令挂载文件系统。 + +```shell +mount lvname mntpath +``` + +其中: + +- lvname:指定要挂载文件系统的逻辑卷设备文件名。 +- mntpath:挂载路径。 + +示例:将逻辑卷/dev/vg1/lv1挂载到/mnt/data目录。 + +```shell +# mount /dev/vg1/lv1 /mnt/data +``` + +### 自动挂载文件系统 + +手动挂载的文件系统在操作系统重启之后会不存在,需要重新手动挂载文件系统。但若在手动挂载文件系统后在root权限下进行如下设置,可以实现操作系统重启后自动挂载文件系统。 + +1. 执行blkid命令查询逻辑卷的UUID,逻辑卷以/dev/vg1/lv1为例。 + + ```shell + # blkid /dev/vg1/lv1 + ``` + + 查看打印信息,打印信息中包含如下内容,其中 _uuidnumber_ 是一串数字,为UUID, _fstype_ 为文件系统。 + + /dev/vg1/lv1: UUID=" _uuidnumber_ " TYPE=" _fstype_ " + +2. 执行**vi /etc/fstab**命令编辑fstab文件,并在最后加上如下内容。 + + ```shell + UUID=uuidnumber mntpath fstype defaults 0 0 + ``` + + 内容说明如下: + + - 第一列:UUID,此处填写[1](#li65701520154311)查询的 _uuidnumber_ 。 + - 第二列:文件系统的挂载目录 _mntpath_ 。 + - 第三列:文件系统的文件格式,此处填写[1](#li65701520154311)查询的 _fstype_ 。 + - 第四列:挂载选项,此处以“defaults”为例; + - 第五列:备份选项,设置为“1”时,系统自动对该文件系统进行备份;设置为“0”时,不进行备份。此处以“0”为例; + - 第六列:扫描选项,设置为“1”时,系统在启动时自动对该文件系统进行扫描;设置为“0”时,不进行扫描。此处以“0”为例。 + +3. 验证自动挂载功能。 + 1. 执行umount命令卸载文件系统,逻辑卷以/dev/vg1/lv1为例。 + + ```shell + # umount /dev/vg1/lv1 + ``` + + 2. 执行如下命令,将/etc/fstab文件所有内容重新加载。 + + ```shell + # mount -a + ``` + + 3. 执行如下命令,查询文件系统挂载信息,挂载目录以/mnt/data为例。 + + ```shell + # mount | grep /mnt/data + ``` + + 查看打印信息,若信息中包含如下信息表示自动挂载功能生效。 + + /dev/vg1/lv1 on /mnt/data diff --git a/docs/en/25.03/Server/MemoryandStorage/overview.md b/docs/en/25.03/Server/MemoryandStorage/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..0fdc84070759dd1f44bb03a6b143f031e7eac9ff --- /dev/null +++ b/docs/en/25.03/Server/MemoryandStorage/overview.md @@ -0,0 +1,150 @@ +# 管理内存 + +## 基本概念 + +**内存**是计算机的重要组成部件,用于暂时存放CPU中的运算数据,以及与硬件等外部存储器交换的数据。特别地,**非统一内存访问架构**(non-uniform memory access,简称NUMA)是一种为多处理器的电脑设计的内存架构,**内存访问时间取决于内存相对于处理器的位置**。在NUMA下,处理器访问本地内存的速度比非本地内存速度(内存位于另一个处理器,或者是处理器之间共享的内存)快。 + +## 查看内存 + +1. free:可用于**显示系统内存状态**。 + + 例如: + + ```shell + # 显示系统内存状态,以MB单位显示 + free -m + ``` + + 回显信息如下: + + ```shell + [root@openEuler ~]# free -m + total used free shared buff/cache available + Mem: 2633 436 324 23 2072 2196 + Swap: 4043 0 4043 + ``` + + 在命令的输出信息中,各字段所代表的含义如下: + + |标识|含义| + |--|--| + |total|总内存数。| + |used|已经使用的内存数。| + |free|空闲的内存数。| + |shared|多个进程共享的内存总数。| + |buff/cache|缓冲和缓存内存总数。| + |available|估计有多少内存可用于启动新应用程序,而不交换。| + +2. vmstat:可以**动态地监控系统内存**,查看系统内存的使用情况。 + + 例如: + + ```shell + # 监测系统内存,显示活跃和非活跃内存 + vmstat -a + ``` + + 回显信息如下: + + ```shell + [root@openEuler ~]# vmstat -a + procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- + r b swpd free inact active si so bi bo in cs us sy id wa st + 2 0 520 331980 1584728 470332 0 0 0 2 15 19 0 0 100 0 0 + ``` + + 在命令的输出信息中,与内存相关的memory字段所代表的含义如下: + + |字段|含义| + |--|--| + |memory|内存信息字段。-swpd:虚拟内存的使用情况,单位为 KB。-free:空闲的内存容量,单位为 KB。-inact:非活跃的内存容量,单位为 KB。-active:活跃的内存容量,单位为 KB。| + +3. sar:可用于**监控系统的内存使用情况**。 + + 例如: + + ```shell + # 系统内存在采样时间内的使用情况,每2秒统计一次,统计 3 次 + sar -r 2 3 + ``` + + 回显信息如下: + + ```shell + [root@openEuler ~]# sar -r 2 3 + + 04:02:09 PM kbmemfree kbavail kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact kb + dirty + 04:02:11 PM 332180 2249308 189420 7.02 142172 1764312 787948 11.52 470404 1584924 + 36 + 04:02:13 PM 332148 2249276 189452 7.03 142172 1764312 787948 11.52 470404 1584924 + 36 + 04:02:15 PM 332148 2249276 189452 7.03 142172 1764312 787948 11.52 470404 1584924 + 36 + Average: 332159 2249287 189441 7.03 142172 1764312 787948 11.52 470404 1584924 + 36 + ``` + + 在命令的输出信息中,各字段所代表的含义如下: + + |字段|含义| + |--|--| + |kbmemfree|内存的未使用空间。| + |kbmemused|内存的已使用空间。| + |%memused|已使用空间的百分比。| + |kbbuffers|缓冲区的数据存取量。| + |kbcached|系统全域的数据存取量。| + +4. numactl:可用于**查看NUMA节点配置和状态**。 + + 例如: + + ```shell + # 查看当前的NUMA配置 + numactl -H + ``` + + 回显信息如下: + + ```shell + [root@openEuler ~]# numactl -H + available: 1 nodes (0) + node 0 cpus: 0 1 2 3 + node 0 size: 2633 MB + node 0 free: 322 MB + node distances: + node 0 + 0: 10 + ``` + + 服务器共划分为1个NUMA节点。每个节点包含4个CPU core,每个节点的内存大小约为6GB。 + 同时,该命令还给出了不同节点间的距离,距离越远,跨NUMA内存访问的延时越大。应用程序运行时应减少跨NUMA访问内存。 + + numastat:可用于**观察各个NUMA节点的状态** + + ```shell + # 观察NUMA节点的状态 + numastat + ``` + + ```shell + [root@openEuler ~]# numastat + node0 + numa_hit 5386186 + numa_miss 0 + numa_foreign 0 + interleave_hit 17483 + local_node 5386186 + other_node 0 + ``` + + numastat命令输出字段及其含义如下: + + |标识|含义| + |--|--| + |numa_hit|节点内CPU核访问本地内存的次数。| + |numa_miss|节点内核访问其他节点内存的次数。| + |numa_foreign|初始分配在本地,最后分配在其他节点的叶数量。每个numa_foreign对应numa_miss事件。| + |interleave_hit|interleave策略页成功分配到这个节点。| + |local_node|该节点的进程成功在这个节点上分配内存访问的大小。| + |other_node|该节点的进程在其他节点上分配的内存访问大小。| diff --git a/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-caution.gif b/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-caution.gif differ diff --git a/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-danger.gif b/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-danger.gif differ diff --git a/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-note.gif b/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-notice.gif b/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-notice.gif differ diff --git a/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-tip.gif b/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-tip.gif differ diff --git a/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-warning.gif b/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/MemoryandStorage/public_sys-resources/icon-warning.gif differ diff --git a/docs/en/25.03/Server/Network/Gazelle/Gazelle.md b/docs/en/25.03/Server/Network/Gazelle/Gazelle.md new file mode 100644 index 0000000000000000000000000000000000000000..3eb407374898ef8a50c5acc752cc4b26a2fb1f06 --- /dev/null +++ b/docs/en/25.03/Server/Network/Gazelle/Gazelle.md @@ -0,0 +1,290 @@ +# Gazelle用户指南 + +## 简介 + +Gazelle是一款高性能用户态协议栈。它基于DPDK在用户态直接读写网卡报文,共享大页内存传递报文,使用轻量级LwIP协议栈。能够大幅提高应用的网络I/O吞吐能力。专注于数据库网络性能加速,如MySQL、redis等。 + +- 高性能 + + 报文零拷贝,无锁,灵活scale-out,自适应调度。 + +- 通用性 + + 完全兼容POSIX,零修改,适用不同类型的应用。 + + 单进程且网卡支持多队列时,只需使用liblstack.so有更短的报文路径。 + +## 安装 + +配置openEuler的yum源,直接使用yum命令安装 + +```sh +yum install dpdk +yum install libconfig +yum install numactl +yum install libboundscheck +yum install libpcap +yum install gazelle +``` + +>说明: +dpdk >= 21.11-2 + +## 使用方法 + +配置运行环境,使用Gazelle加速应用程序步骤如下: + +### 1. 使用root权限安装ko + +根据实际情况选择使用ko,提供绑定网卡到用户态功能。 +网卡从内核驱动绑为用户态驱动的ko,根据实际情况选择一种。 + +```sh +#若IOMMU能使用 +modprobe vfio-pci + +#若IOMMU不能使用,且VFIO支持noiommu +modprobe vfio enable_unsafe_noiommu_mode=1 +modprobe vfio-pci + +#其他情况 +modprobe igb_uio +``` + +>说明: +可根据机器BIOS配置,查看是否使能IOMMU。 + +### 2. dpdk绑定网卡 + +将网卡绑定到步骤1选择的驱动。为用户态网卡驱动提供网卡资源访问接口。 + +```sh +#使用vfio-pci +dpdk-devbind -b vfio-pci enp3s0 + +#使用igb_uio +dpdk-devbind -b igb_uio enp3s0 +``` + +### 3. 大页内存配置 + +Gazelle使用大页内存提高效率。使用root权限配置系统预留大页内存,可选用任意页大小。因每页内存都需要一个fd,使用内存较大时,建议使用1G的大页,避免占用过多fd。 +根据实际情况,选择一种页大小,配置足够的大页内存即可。配置大页操作如下: + +```sh +#配置2M大页内存:在node0上配置 2M * 1024 = 2G +echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages + +#配置1G大页内存:在node0上配置1G * 5 = 5G +echo 5 > /sys/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages +``` + +>说明: +cat查询实际预留页个数,连续内存不足时可能比预期少 + +### 4. 挂载大页内存 + +创建目录,给lstack的进程访问大页内存使用。操作步骤如下: + +```sh +mkdir -p /mnt/hugepages-lstack +chmod -R 700 /mnt/hugepages-lstack + +mount -t hugetlbfs nodev /mnt/hugepages-lstack -o pagesize=2M +``` + +### 5. 应用程序使用Gazelle + +有两种使用Gazelle方法,根据需要选择其一 + +- 重新编译应用程序,替换sockets接口 + +```sh +#makefile中添加Gazelle的Makefile +-include /etc/gazelle/lstack.Makefile + +#编译添加LSTACK_LIBS变量 +gcc test.c -o test ${LSTACK_LIBS} +``` + +- 使用LD_PRELOAD加载Gazelle库 + + GAZELLE_BIND_PROCNAME环境变量指定进程名,LD_PRELOAD指定Gazelle库路径。 + + ```sh + GAZELLE_BIND_PROCNAME=test LD_PRELOAD=/usr/lib64/liblstack.so ./test + ``` + +- 使用GAZELLE_THREAD_NAME指定Gazelle绑定的线程名 + + 同一进程中的多个线程中,仅有某个线程满足gazelle的使用条件时,可以使用GAZELLE_THREAD_NAME来指定仅由对应的线程名使用gazelle,而其他线程走内核态协议栈。 + + ```sh + GAZELLE_BIND_PROCNAME=test GAZELLE_THREAD_NAME=test_thread LD_PRELOAD=/usr/lib64/liblstack.so ./test + ``` + +### 6. 配置文件 + +- lstack.conf用于指定lstack的启动参数,默认路径为/etc/gazelle/lstack.conf, 配置文件参数如下 + +|选项|参数格式|说明| +|:---|:---|:---| +|dpdk_args|--socket-mem(必需)
--huge-dir(必需)
--proc-type(必需)
--legacy-mem
--map-perfect
-d|dpdk初始化参数,参考dpdk说明
--map-perfect为扩展特性,用于防止dpdk占用多余的地址空间,保证有额外的地址空间分配给lstack。
-d参数加载指定so库文件| +|listen_shadow| 0/1 | 是否使用影子fd监听。单listen线程,多协议栈线程时是能| +|use_ltran| 0/1 | 是否使用ltran ,功能已衰退,不再支持| +|num_cpus|"0,2,4 ..."|lstack线程绑定的cpu编号,编号的数量为lstack线程个数(小于等于网卡多队列数量)。可按NUMA选择cpu| +|low_power_mode|0/1|是否开启低功耗模式,暂不支持| +|kni_switch|0/1|rte_kni开关,默认为0。功能已衰退,不再支持| +|unix_prefix|"string"|gazelle进程间通信使用的unix socket文件前缀字符串,默认为空,和需要通信的ltran.conf的unix_prefix或gazellectl的-u参数配置一致。不能含有特殊字符,最大长度为128。| +|host_addr|"192.168.xx.xx"|协议栈的IP地址,也是应用程序的IP地址| +|mask_addr|"255.255.xx.xx"|掩码地址| +|gateway_addr|"192.168.xx.1"|网关地址| +|devices|"aa:bb:cc:dd:ee:ff"|网卡通信的mac地址,在bond1模式下作为bond的主网口| +|app_bind_numa|0/1|应用的epoll和poll线程是否绑定到协议栈所在的numa,缺省值是1,即绑定| +|send_connect_number|4|设置为正整数,表示每次协议栈循环中发包处理的连接个数| +|read_connect_number|4|设置为正整数,表示每次协议栈循环中收包处理的连接个数| +|rpc_number|4|设置为正整数,表示每次协议栈循环中rpc消息处理的个数| +|nic_read_num|128|设置为正整数,表示每次协议栈循环中从网卡读取的数据包的个数| +|bond_mode|-1|设置组bond,当前支持两个网口组bond模式,默认值-1关闭bond,当前支持bond1/4/6| +|bond_slave_mac|"aa:bb:cc:dd:ee:ff;AA:BB:CC:DD:EE:FF"|设置组bond网口的mac地址信息,以;分隔| +|bond_miimon|10|设置bond模式的监听间隔,默认值10,取值范围0~1500| +|udp_enable|0/1|是否开启udp功能,默认值1开启| +|nic_vlan_mode|-1|是否开启vlan模式,默认值-1关闭,取值范围-1~4095,0和4095是业界通用预留id无实际效果| +|tcp_conn_count|1500|tcp的最大连接数,该参数乘以mbuf_count_per_conn是初始化时申请的mbuf池大小,配置过小会启动失败,`tcp_conn_count * mbuf_count_per_conn *` 2048字节不能大于大页大小 | +|mbuf_count_per_conn|170|每个tcp连接需要的mbuf个数,该参数乘以tcp_conn_count是初始化时申请的mbuf地址池大小,配置过小会启动失败,`tcp_conn_count * mbuf_count_per_conn *`2048字节不能大于大页大小| + +lstack.conf示例: + +```sh +dpdk_args=["--socket-mem", "2048,0,0,0", "--huge-dir", "/mnt/hugepages-lstack", "--proc-type", "primary", "--legacy-mem", "--map-perfect"] + +use_ltran=0 +kni_switch=0 + +low_power_mode=0 + +num_cpus="2,22" +num_wakeup="3,23" + +host_addr="192.168.1.10" +mask_addr="255.255.255.0" +gateway_addr="192.168.1.1" +devices="aa:bb:cc:dd:ee:ff" + +send_connect_number=4 +read_connect_number=4 +rpc_number=4 +nic_read_num=128 +mbuf_pool_size=1024000 +bond_mode=1 +bond_slave_mac="aa:bb:cc:dd:ee:ff;AA:BB:CC:DD:EE:FF" +udp_enable=1 +nic_vlan_mode=-1 +``` + +- ltran模式功能已衰退,多进程使用需求可尝试使用SR-IOV组网硬件虚拟化组网模式: + +### 7. 启动应用程序 + +- 启动应用程序 + + 启动应用程序前不使用环境变量LSTACK_CONF_PATH指定配置文件,则使用默认路径/etc/gazelle/lstack.conf + + ```sh + export LSTACK_CONF_PATH=./lstack.conf + LD_PRELOAD=/usr/lib64/liblstack.so GAZELLE_BIND_PROCNAME=redis-server redis-server redis.conf + ``` + +### 8. API + +Gazelle wrap应用程序POSIX接口,应用程序无需修改代码。 + +### 9. 调测命令 + +```sh +Usage: gazellectl [-h | help] + or: gazellectl lstack {show | set} {ip | pid} [LSTACK_OPTIONS] [time] [-u UNIX_PREFIX] + + where LSTACK_OPTIONS := + show lstack all statistics + -r, rate show lstack statistics per second + -s, snmp show lstack snmp + -c, connetct show lstack connect + -l, latency show lstack latency + -x, xstats show lstack xstats + -k, nic-features show state of protocol offload and other feature + -a, aggregatin [time] show lstack send/recv aggregation + set: + loglevel {error | info | debug} set lstack loglevel + lowpower {0 | 1} set lowpower enable + [time] measure latency time default 1S +``` + +-u参数指定gazelle进程间通信的unix socket前缀,和需要通信的lstack.conf的unix_prefix配置一致。 + +**抓包工具** +gazelle使用的网卡由dpdk接管,因此普通的tcpdump无法抓到gazelle的数据包。作为替代,gazelle使用dpdk-tools软件包中提供的gazelle-pdump作为数据包捕获工具,它使用dpdk的多进程模式和lstack进程共享内存。 +[详细使用方法](https://gitee.com/openeuler/gazelle/blob/master/doc/pdump.md) + +**线程名绑定** +lstack启动时可以通过指定环境变量GAZELLE_THREAD_NAME来指定lstack绑定的线程名,在业务进程中有多个不同线程时,可以通过使用此参数来指定需要lstack接管网络接口的线程名,未指定的线程将走内核态协议栈。默认为空,即绑定进程内的所有线程。 + +### 10. 使用注意 + +#### 1. dpdk配置文件的位置 + +如果是root用户,dpdk启动后的配置文件将会放到/var/run/dpdk目录下; +如果是非root用户,dpdk配置文件的路径将由环境变量XDG_RUNTIME_DIR决定; + +- 如果XDG_RUNTIME_DIR为空,dpdk配置文件放到/tmp/dpdk目录下; +- 如果XDG_RUNTIME_DIR不为空,dpdk配置文件放到变量XDG_RUNTIME_DIR下; +- 注意有些机器会默认设置XDG_RUNTIME_DIR + +## 约束限制 + +使用 Gazelle 存在一些约束限制: + +### 功能约束 + +- 不支持accept阻塞模式或者connect阻塞模式。 +- 最多支持1500个TCP连接。 +- 当前仅支持TCP、ICMP、ARP、IPv4、UDP 协议。 +- 在对端ping Gazelle时,要求指定报文长度小于等于14000B。 +- 不支持使用透明大页。 +- 虚拟机网卡不支持多队列。 + +### 操作约束 + +- 提供的命令行、配置文件默认root权限。非root用户使用,需先提权以及修改文件所有者。 +- 将用户态网卡绑回到内核驱动,必须先退出Gazelle。 +- 大页内存不支持在挂载点里创建子目录重新挂载。 +- 每个应用实例协议栈线程最低大页内存为800MB 。 +- 仅支持64位系统。 +- 构建x86版本的Gazelle使用了-march=native选项,基于构建环境的CPU(Intel® Xeon® Gold 5118 CPU @ 2.30GHz指令集进行优化。要求运行环境CPU支持 SSE4.2、AVX、AVX2、AVX-512 指令集。 +- 最大IP分片数为10(ping 最大包长14790B),TCP协议不使用IP分片。 +- sysctl配置网卡rp_filter参数为1,否则可能不按预期使用Gazelle协议栈,而是依然使用内核协议栈。 +- 不支持使用多种类型的网卡混合组bond。 +- bond1主备模式,只支持链路层故障主备切换(例如网线断开),不支持物理层故障主备切换(例如网卡下电、拔网卡)。 +- 发送udp报文包长超过45952(32 * 1436)B时,需要将send_ring_size扩大为至少64个。 + +## 注意事项 + +用户根据使用场景评估使用Gazelle + +ltran模式及kni模块由于上游社区及依赖包变更,功能在新版本中不再支持. + +共享内存 + +- 现状 + 大页内存 mount 至 /mnt/hugepages-lstack 目录,进程初始化时在 /mnt/hugepages-lstack 目录下创建文件,每个文件对应一个大页,并 mmap 这些文件。 +- 当前消减措施 + 大页文件权限 600,只有 OWNER 用户才能访问文件,默认 root 用户,支持配置成其他用户; + 大页文件有 DPDK 文件锁,不能直接写或者映射。 +- 注意 + 属于同一用户的恶意进程模仿DPDK实现逻辑,通过大页文件共享大页内存,写破坏大页内存,导致Gazelle程序crash。建议用户下的进程属于同一信任域。 + +**流量限制** +Gazelle没有做流量限制,用户有能力发送最大网卡线速流量的报文到网络,可能导致网络流量拥塞。 + +**进程仿冒** +建议lstack进程都为可信任进程。 diff --git a/docs/en/25.03/Server/Network/Gazelle/_menu.md b/docs/en/25.03/Server/Network/Gazelle/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..98f2e96e52304d26c3c736456ed67dd4d9072a9c --- /dev/null +++ b/docs/en/25.03/Server/Network/Gazelle/_menu.md @@ -0,0 +1,8 @@ +--- +label: 'Gazelle用户指南' +ismanual: 'Y' +description: '提高应用的网络 I/O 吞吐能力' +children: + - label: 'Gazelle用户指南' + href: './Gazelle.md' +--- diff --git a/docs/en/25.03/Server/Network/NetworConfig/_menu.md b/docs/en/25.03/Server/Network/NetworConfig/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..aedf25cb8be0b8e19485d90c9d0466a8b68baae6 --- /dev/null +++ b/docs/en/25.03/Server/Network/NetworConfig/_menu.md @@ -0,0 +1,8 @@ +--- +label: '配置网络' +ismanual: 'Y' +description: '配置ip,主机名,网络绑定等' +children: + - label: '配置网络' + href: './configuring-the-network.md' +--- diff --git a/docs/en/25.03/Server/Network/NetworConfig/configuring-the-network.md b/docs/en/25.03/Server/Network/NetworConfig/configuring-the-network.md new file mode 100644 index 0000000000000000000000000000000000000000..dd6bf986f312d632268ca6bde5b74ae4d0332996 --- /dev/null +++ b/docs/en/25.03/Server/Network/NetworConfig/configuring-the-network.md @@ -0,0 +1,1361 @@ +# 配置网络 + +## 配置 IP + +### 使用nmcli命令 + +> ![](../public_sys-resources/icon-note.gif) **说明:** +> 使用nmcli命令配置的网络配置可以立即生效且系统重启后配置也不会丢失。 + +#### nmcli介绍 + +nmcli是NetworkManager的一个命令行工具,它提供了使用命令行配置由NetworkManager管理网络连接的方法。nmcli命令的基本格式为: + +```shell +# nmcli [OPTIONS] OBJECT { COMMAND | help } +``` + +其中,OBJECT选项可以是general、networking、radio、connection或device等。在日常使用中,最常使用的是-t, \-\-terse(用于脚本)、-p, \-\-pretty选项(用于用户)及-h, \-\-help选项,用户可以使用“nmcli help”获取更多参数及使用信息。 + +```shell +# nmcli help +``` + +常用命令使用举例如下: + +- 显示NetworkManager状态: + + ```shell + # nmcli general status + ``` + +- 显示所有连接: + + ```shell + # nmcli connection show + ``` + +- 只显示当前活动连接,如下所示添加-a, \-\-active: + + ```shell + # nmcli connection show --active + ``` + +- 显示由NetworkManager识别到的设备及其状态: + + ```shell + # nmcli device status + ``` + +- 使用nmcli工具启动和停止网络接口,在root权限下执行如下命令: + + ```shell + # nmcli connection up id enp3s0 + # nmcli device disconnect enp3s0 + ``` + +#### 设备管理 + +##### 连接到设备 + +使用如下命令,NetworkManager将连接到对应网络设备,尝试找到合适的连接配置,并激活配置。 + +```shell +# nmcli device connect "$IFNAME" +``` + +>如果不存在相应的配置连接,NetworkManager将创建并激活具有默认设置的新配置文件。 + +##### 断开设备连接 + +使用如下命令,NetworkManager将断开设备连接,并防止设备自动激活。 + +```shell +# nmcli device disconnect "$IFNAME" +``` + +#### 设置网络连接 + +列出目前可用的网络连接: + +```shell +# nmcli con show + + +NAME UUID TYPE DEVICE +enp4s0 5afce939-400e-42fd-91ee-55ff5b65deab ethernet enp4s0 +enp3s0 c88d7b69-f529-35ca-81ab-aa729ac542fd ethernet enp3s0 +virbr0 ba552da6-f014-49e3-91fa-ec9c388864fa bridge virbr0 +``` + +> ![](../public_sys-resources/icon-note.gif) **说明:** +> 输出结果中的NAME字段代表连接ID(名称)。 + +添加一个网络连接会生成相应的配置文件,并与相应的设备关联。检查可用的设备,方法如下: + +```shell +# nmcli dev status + +DEVICE TYPE STATE CONNECTION +enp3s0 ethernet connected enp3s0 +enp4s0 ethernet connected enp4s0 +virbr0 bridge connected virbr0 +lo loopback unmanaged -- +virbr0-nic tun unmanaged -- +``` + +##### 配置动态IP连接 + +###### 配置IP + +要使用 DHCP 分配网络时,可以使用动态IP配置添加网络配置文件,命令格式如下: + +```shell +nmcli connection add type ethernet con-name connection-name ifname interface-name +``` + +例如创建名为net-test的动态连接配置文件,在root权限下使用以下命令: + +```shell +# nmcli connection add type ethernet con-name net-test ifname enp3s0 +Connection 'net-test' (a771baa0-5064-4296-ac40-5dc8973967ab) successfully added. +``` + +NetworkManager 会将参数 connection.autoconnect 设定为 yes,并将设置保存到 “/etc/sysconfig/network-scripts/ifcfg-net-test”文件中,在该文件中会将 ONBOOT 设置为 yes。 + +###### 激活连接并检查状态 + +在root权限下使用以下命令激活网络连接: + +```shell +# nmcli con up net-test +Connection successfully activated (D-Bus active path:/org/freedesktop/NetworkManager/ActiveConnection/5) +``` + +检查这些设备及连接的状态,使用以下命令: + +```shell +# nmcli device status + +DEVICE TYPE STATE CONNECTION +enp4s0 ethernet connected enp4s0 +enp3s0 ethernet connected net-test +virbr0 bridge connected virbr0 +lo loopback unmanaged -- +virbr0-nic tun unmanaged -- +``` + +##### 配置静态IP连接 + +###### 配置IP + +添加静态 IPv4 配置的网络连接,可使用以下命令: + +```shell +nmcli connection add type ethernet con-name connection-name ifname interface-name ip4 address gw4 address +``` + +> ![](../public_sys-resources/icon-note.gif) **说明:** +> 如果要添加 IPv6 地址和网关信息,使用 ip6 和 gw6 选项。 + +例如创建名为 net-static的静态连接配置文件,在root权限下使用以下命令: + +```shell +# nmcli con add type ethernet con-name net-static ifname enp3s0 ip4 192.168.0.10/24 gw4 192.168.0.254 +``` + +还可为该设备同时指定 IPv6 地址和网关,示例如下: + +```shell +# nmcli con add type ethernet con-name test-lab ifname enp3s0 ip4 192.168.0.10/24 gw4 192.168.0.254 ip6 abbe::**** gw6 2001:***::* +Connection 'net-static' (63aa2036-8665-f54d-9a92-c3035bad03f7) successfully added. +``` + +NetworkManager 会将其内部参数 ipv4.method 设定为 manual,将 connection.autoconnect 设定为yes,并将设置写入 /etc/sysconfig/network-scripts/ifcfg-net-static 文件,其中会将对应 BOOTPROTO 设定为 none,将 ONBOOT 设定为 yes。 + +设定两个 IPv4 DNS 服务器地址,在root权限下使用以下命令: + +```shell +# nmcli con mod net-static ipv4.dns "*.*.*.* *.*.*.*" +``` + +设置两个 IPv6 DNS 服务器地址,在root权限下使用以下命令: + +```shell +# nmcli con mod net-static ipv6.dns "2001:4860:4860::**** 2001:4860:4860::****" +``` + +###### 激活连接并检查状态 + +激活新的网络连接,在root权限下使用以下命令: + +```shell +# nmcli con up net-static ifname enp3s0 +Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/6) +``` + +检查这些设备及连接的状态,使用以下命令: + +```shell +# nmcli device status + +DEVICE TYPE STATE CONNECTION +enp4s0 ethernet connected enp4s0 +enp3s0 ethernet connected net-static +virbr0 bridge connected virbr0 +lo loopback unmanaged -- +virbr0-nic tun unmanaged -- +``` + +查看配置的连接详情,使用以下命令(使用 -p,\-\-pretty 选项在输出结果中添加标题和分段): + +```shell +# nmcli -p con show net-static +=============================================================================== +Connection profile details (net-static ) +=============================================================================== +connection.id: net-static +connection.uuid: b9f18801-6084-4aee-af28-c8f0598ff5e1 +connection.stable-id: -- +connection.type: 802-3-ethernet +connection.interface-name: enp3s0 +connection.autoconnect: yes +connection.autoconnect-priority: 0 +connection.autoconnect-retries: -1 (default) +connection.multi-connect: 0 (default) +connection.auth-retries: -1 +connection.timestamp: 1578988781 +connection.read-only: no +connection.permissions: -- +connection.zone: -- +connection.master: -- +connection.slave-type: -- +connection.autoconnect-slaves: -1 (default) +connection.secondaries: -- +connection.gateway-ping-timeout: 0 +connection.metered: unknown +connection.lldp: default +connection.mdns: -1 (default) +connection.llmnr: -1 (default) +``` + +##### 添加 Wi-Fi 连接 + +有两种方式添加Wi-Fi 连接。 + +###### 方法1. 通过网络接口连接wifi + +连接到由SSID或BSSID指定的wifi网络。命令如下,该命令找到匹配的连接或创建一个连接,然后在设备上激活它。 + +```shell +nmcli device wifi connect "$SSID" password "$PASSWORD" ifname "$IFNAME" +nmcli --ask device wifi connect "$SSID" +``` + +###### 方法2. 通过配置文件连接Wi-Fi** + +1,使用以下命令查看可用 Wi-Fi 访问点: + +```shell +# nmcli dev wifi list +``` + +2,使用以下命令生成使用的静态 IP 配置,但允许自动 DNS 地址分配的 Wi-Fi 连接: + +```shell +# nmcli con add con-name Wifi ifname wlan0 type wifi ssid MyWifi ip4 192.168.100.101/24 gw4 192.168.100.1 +``` + +3,请使用以下命令设定 WPA2 密码,例如 “answer”: + +```shell +# nmcli con modify Wifi wifi-sec.key-mgmt wpa-psk +# nmcli con modify Wifi wifi-sec.psk answer +``` + +4,使用以下命令更改 Wi-Fi 状态: + +```shell +# nmcli radio wifi [ on | off ] +``` + +##### 更改属性 + +请使用以下命令检查具体属性,比如 mtu: + +```shell +# nmcli connection show id 'Wifi ' | grep mtu +802-11-wireless.mtu: auto +``` + +使用如下命令更改设置的属性: + +```shell +# nmcli connection modify id 'Wifi ' 802-11-wireless.mtu 1350 +``` + +使用如下命令确认更改: + +```shell +# nmcli connection show id 'Wifi ' | grep mtu +802-11-wireless.mtu: 1350 +``` + +#### 配置静态路由 + +- 使用nmcli命令为网络连接配置静态路由,使用命令如下: + + ```shell + # nmcli connection modify enp3s0 +ipv4.routes "192.168.122.0/24 10.10.10.1" + ``` + +- 使用编辑器配置静态路由,使用如下命令: + + ```shell + # nmcli con edit type ethernet con-name enp3s0 + ===| nmcli interactive connection editor |=== + Adding a new '802-3-ethernet' connection + Type 'help' or '?' for available commands. + Type 'describe [.]' for detailed property description. + You may edit the following settings: connection, 802-3-ethernet (ethernet), 802-1x, ipv4, ipv6, dcb + nmcli> set ipv4.routes 192.168.122.0/24 10.10.10.1 + nmcli> + nmcli> save persistent + Saving the connection with 'autoconnect=yes'. That might result in an immediate activation of the connection. + Do you still want to save? [yes] yes + Connection 'enp3s0' (1464ddb4-102a-4e79-874a-0a42e15cc3c0) successfully saved. + nmcli> quit + ``` + +- 使用如下命令激活连接以生效配置: + + ```shell + # nmcli con up enp3s0 + ``` + +### 使用ip命令 + +> ![](../public_sys-resources/icon-note.gif) **说明:** +> 使用ip命令配置的网络配置可以立即生效但系统重启后配置会丢失。 + +#### 配置IP地址 + +使用ip命令为接口配置地址,命令格式如下,其中 _interface-name_ 为网卡名称。 + +```shell +# ip addr [ add | del ] address dev interface-name +``` + +##### 配置静态地址 + +在root权限下,配置静态IP地址,使用示例如下: + +```shell +# ip address add 192.168.0.10/24 dev enp3s0 +``` + +查看配置结果,在root权限使用如下命令: + +```shell +# ip addr show dev enp3s0 +2: enp3s0: mtu 1500 qdisc fq_codel state UP group default qlen 1000 + link/ether 52:54:00:aa:ad:4a brd ff:ff:ff:ff:ff:ff + inet 192.168.202.248/16 brd 192.168.255.255 scope global dynamic noprefixroute enp3s0 + valid_lft 9547sec preferred_lft 9547sec + inet 192.168.0.10/24 scope global enp3s0 + valid_lft forever preferred_lft forever + inet6 fe80::32e8:cc22:9db2:f4d4/64 scope link noprefixroute + valid_lft forever preferred_lft forever +``` + +##### 配置多个地址 + +ip 命令支持为同一接口分配多个地址,可在root权限下重复多次使用 ip 命令实现分配多个地址。使用示例如下: + +```shell +# ip address add 192.168.2.223/24 dev enp4s0 +# ip address add 192.168.4.223/24 dev enp4s0 +# ip addr + +3: enp4s0: mtu 1500 qdisc fq_codel state UP group default qlen 1000 + link/ether 52:54:00:aa:da:e2 brd ff:ff:ff:ff:ff:ff + inet 192.168.203.12/16 brd 192.168.255.255 scope global dynamic noprefixroute enp4s0 + valid_lft 8389sec preferred_lft 8389sec + inet 192.168.2.223/24 scope global enp4s0 + valid_lft forever preferred_lft forever + inet 192.168.4.223/24 scope global enp4s0 + valid_lft forever preferred_lft forever + inet6 fe80::1eef:5e24:4b67:f07f/64 scope link noprefixroute + valid_lft forever preferred_lft forever +``` + +#### 配置静态路由 + +如果需要静态路由,可使用 ip route add 命令在路由表中添加,使用 ip route del 命令删除。最常使用的 ip route 命令格式如下: + +```shell +# ip route [ add | del | change | append | replace ] destination-address +``` + +在root权限下使用 ip route 命令显示当前的 IP 路由表。示例如下: + +```shell +# ip route + +default via 192.168.0.1 dev enp3s0 proto dhcp metric 100 +default via 192.168.0.1 dev enp4s0 proto dhcp metric 101 +192.168.0.0/16 dev enp3s0 proto kernel scope link src 192.168.202.248 metric 100 +192.168.0.0/16 dev enp4s0 proto kernel scope link src 192.168.203.12 metric 101 +192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown +``` + +在主机地址中添加一个静态路由,在 root 权限下,使用以下命令格式: + +```shell +# ip route add 192.168.2.1 via 10.0.0.1 [dev interface-name] +``` + +其中 192.168.2.1 是用点分隔的十进制符号中的 IP 地址,10.0.0.1 是下一个跃点,_interface-name_ 是进入下一个跃点的退出接口。 + +要在网络中添加一个静态路由,即代表 IP 地址范围的 IP 地址,请在root权限下运行以下命令格式: + +```shell +# ip route add 192.168.2.0/24 via 10.0.0.1 [dev interface-name] +``` + +其中 192.168.2.1 是目标网络的 IP 地址,10.0.0.1 是网络前缀,_interface-name_ 为网卡名称。 + +### 通过ifcfg文件配置网络 + +> ![](../public_sys-resources/icon-note.gif) **说明:** +> 通过ifcfg文件配置的网络配置不会立即生效,修改文件后(以ifcfg-enp3s0为例),需要在root权限下执行**nmcli con reload;nmcli con up enp3s0**命令以重新加载配置文件并激活连接才生效。 + +#### 配置静态网络 + +以enp4s0网络接口进行静态网络设置为例,通过在root权限下修改ifcfg文件实现,在/etc/sysconfig/network-scripts/目录中生成名为ifcfg-enp4s0的文件中,修改参数配置,示例如下: + +```text +TYPE=Ethernet +PROXY_METHOD=none +BROWSER_ONLY=no +BOOTPROTO=none +IPADDR=192.168.0.10 +PREFIX=24 +DEFROUTE=yes +IPV4_FAILURE_FATAL=no +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_FAILURE_FATAL=no +IPV6_ADDR_GEN_MODE=stable-privacy +NAME=enp4s0static +UUID=08c3a30e-c5e2-4d7b-831f-26c3cdc29293 +DEVICE=enp4s0 +ONBOOT=yes +``` + +#### 配置动态网络 + +要通过ifcfg文件为em1接口配置动态网络,请按照如下操作在/etc/sysconfig/network-scripts/目录中生成名为 ifcfg-em1 的文件,示例如下: + +```text +DEVICE=em1 +BOOTPROTO=dhcp +ONBOOT=yes +``` + +要配置一个向DHCP服务器发送不同的主机名的接口,请在ifcfg文件中新增一行内容,如下所示: + +```text +DHCP_HOSTNAME=hostname +``` + +要配置忽略由DHCP服务器发送的路由,防止网络服务使用从DHCP服务器接收的DNS服务器更新/etc/resolv.conf。请在ifcfg文件中新增一行内容,如下所示: + +```text +PEERDNS=no +``` + +要配置一个接口使用具体DNS服务器,请将参数PEERDNS=no,并在ifcfg文件中添加以下行: + +```text +DNS1=ip-address +DNS2=ip-address +``` + +其中ip-address是DNS服务器的地址。这样就会让网络服务使用指定的DNS服务器更新/etc/resolv.conf。 + +#### 配置默认网关 + +在确定默认网关时,首先解析 /etc/sysconfig/network 文件,然后解析 ifcfg 文件 ,将最后读取的 GATEWAY 的取值作为路由表中的默认路由。 + +在动态网络环境中,使用 NetworkManager 管理主机时,建议设置为由 DHCP 来分配。 + +### 通过 nmtui 工具 + +nmtui 工具提供了一个交互式的界面,可以用来配置网络连接。要使用 nmtui 工具,以 root 权限执行以下命令: + +```shell +# nmtui +``` + +选择 **Edit a connection** 选项,然后选择要编辑的网络连接,按 **Enter** 键,进入编辑界面。 + +在交互界面中,可以使用方向键选择要编辑的选项,按 **Tab** 键切换到下一个选项,按 **Enter** 键进入编辑状态,按 **Esc** 键退出编辑状态。可以使用方向键选择 IPV4 CONFIGURATION 或 IPV6 CONFIGURATION 的配置方式,并选择 Show 显示详细信息。 + +## 配置主机名 + +### 简介 + +hostname有三种类型:static、transient和pretty。 + +- static:静态主机名,可由用户自行设置,并保存在/etc/hostname 文件中。 +- transient:动态主机名,由内核维护,初始是 static 主机名,缺省值为“localhost”。可由DHCP或mDNS在运行时更改。 +- pretty:灵活主机名,允许使用自由形式(包括特殊/空白字符)进行设置。静态/动态主机名遵从域名的通用限制。 + +> ![](../public_sys-resources/icon-note.gif) **说明:** +> static和transient主机名只能包含a-z、A-Z、0-9、“-”和“.”,不能在开头或结尾处使用句点,不允许使用两个相连的句点,大小限制为 64 个字符。 + +### 使用hostnamectl配置主机名 + +#### 查看所有主机名 + +查看当前的主机名,使用如下命令: + +```shell +# hostnamectl status +``` + +> ![](../public_sys-resources/icon-note.gif) **说明:** +> 如果命令未指定任何选项,则默认使用status选项。 + +#### 设定所有主机名 + +在root权限下,设定系统中的所有主机名,使用如下命令: + +```shell +# hostnamectl set-hostname name +``` + +#### 设定特定主机名 + +在root权限下,通过不同的参数来设定特定主机名,使用如下命令: + +```shell +# hostnamectl set-hostname name [option...] +``` + +其中option可以是\-\-pretty、\-\-static、\-\-transient中的一个或多个选项。 + +如果\-\-static或\-\-transient与\-\-pretty选项一同使用时,则会将static和transient主机名简化为pretty主机名格式,使用“-”替换空格,并删除特殊字符。 + +当设定pretty主机名时,如果主机名中包含空格或单引号,需要使用引号。命令示例如下: + +```shell +# hostnamectl set-hostname "Stephen's notebook" --pretty +``` + +#### 清除特定主机名 + +要清除特定主机名,并将其还原为默认形式,在root权限下,使用如下命令: + +```shell +# hostnamectl set-hostname "" [option...] +``` + +其中 "" 是空白字符串,option是\-\-pretty、\-\-static和\-\-transient中的一个或多个选项。 + +#### 远程更改主机名 + +在远程系统中运行hostnamectl命令时,要使用-H,\-\-host 选项,在root权限下使用如下命令: + +```shell +# hostnamectl set-hostname -H [username]@hostname new_hostname +``` + +其中hostname是要配置的远程主机,username为自选项,new\_hostname为新主机名。hostnamectl会通过SSH连接到远程系统。 + +### 使用nmcli配置主机名 + +查询static主机名,使用如下命令: + +```shell +# nmcli general hostname +``` + +在root权限下,将static主机名设定为host-server,使用如下命令: + +```shell +# nmcli general hostname host-server +``` + +要让系统hostnamectl感知到static主机名的更改,在root权限下,重启hostnamed服务,使用如下命令: + +```shell +# systemctl restart systemd-hostnamed +``` + +### 通过 nmtui 工具 + +nmtui 提供了一个交互式的界面,可以用来配置网络连接。要使用 nmtui 工具,以 root 权限执行以下命令: + +```shell +# nmtui +``` + +选择 **Set system hostname** 选项,输入新的主机名,然后按 **Enter** 键。选择 OK 确认修改。 + +## 配置网络绑定 + +### 使用nmcli + +- 创建名为mybond0的绑定,使用示例如下: + + ```shell + # nmcli con add type bond con-name mybond0 ifname mybond0 mode active-backup + ``` + +- 添加从属接口,使用示例如下: + + ```shell + # nmcli con add type bond-slave ifname enp3s0 master mybond0 + ``` + + 要添加其他从属接口,重复上一个命令,并在命令中使用新的接口,使用示例如下: + + ```shell + # nmcli con add type bond-slave ifname enp4s0 master mybond0 + Connection 'bond-slave-enp4s0' (05e56afc-b953-41a9-b3f9-0791eb49f7d3) successfully added. + ``` + +- 要启动绑定,则必须首先启动从属接口,使用示例如下: + + ```shell + # nmcli con up bond-slave-enp3s0 + Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/14) + ``` + + ```shell + # nmcli con up bond-slave-enp4s0 + Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/15) + ``` + + 现在可以启动绑定,使用示例如下: + + ```shell + # nmcli con up mybond0 + Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/16) + ``` + +### 使用命令行 + +#### 检查是否已安装Bonding内核模块 + +在系统中默认已加载相应模块。要载入绑定模块,可在root权限下使用如下命令: + +```shell +# modprobe --first-time bonding +``` + +显示该模块的信息,可在root权限下使用如下命令: + +```shell +# modinfo bonding +``` + +更多命令请在root权限下使用modprobe \-\-help查看。 + +#### 创建频道绑定接口 + +要创建绑定接口,可在root权限下通过在 /etc/sysconfig/network-scripts/ 目录中创建名为 ifcfg-bondN 的文件(使用接口号码替换 N,比如 0)。 + +根据要绑定接口类型的配置文件来编写相应的内容,比如网络接口。接口配置文件示例如下: + +```text +DEVICE=bond0 +NAME=bond0 +TYPE=Bond +BONDING_MASTER=yes +IPADDR=192.168.1.1 +PREFIX=24 +ONBOOT=yes +BOOTPROTO=none +BONDING_OPTS="bonding parameters separated by spaces" +``` + +#### 创建从属接口 + +创建频道绑定接口后,必须在从属接口的配置文件中添加 MASTER 和 SLAVE 指令。 + +例如将两个网络接口enp3s0 和 enp4s0 以频道方式绑定,其配置文件示例分别如下: + +```text +TYPE=Ethernet +NAME=bond-slave-enp3s0 +UUID=3b7601d1-b373-4fdf-a996-9d267d1cac40 +DEVICE=enp3s0 +ONBOOT=yes +MASTER=bond0 +SLAVE=yes +``` + +```text +TYPE=Ethernet +NAME=bond-slave-enp4s0 +UUID=00f0482c-824f-478f-9479-abf947f01c4a +DEVICE=enp4s0 +ONBOOT=yes +MASTER=bond0 +SLAVE=yes +``` + +#### 激活频道绑定 + +要激活绑定,则需要启动所有从属接口。请在root权限下,运行以下命令: + +```text +# ifup enp3s0 +Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/7) +``` + +```text +# ifup enp4s0 +Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/8) +``` + +> ![](../public_sys-resources/icon-note.gif) **说明:** +> 对于已经处于“up”状态的接口,请首先使用“ifdown _enp3s0_ ”命令修改状态为down,其中 _enp3s0_ 为实际网卡名称。 + +完成后,启动所有从属接口以便启动绑定(不将其设定为 “down”)。 + +要让 NetworkManager 感知到系统所做的修改,在每次修改后,请在root权限下,运行以下命令: + +```shell +# nmcli con load /etc/sysconfig/network-scripts/ifcfg-device +``` + +查看绑定接口的状态,请在root权限下运行以下命令: + +```shell +# ip link show + +1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 +2: enp3s0: mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000 + link/ether 52:54:00:aa:ad:4a brd ff:ff:ff:ff:ff:ff +3: enp4s0: mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000 + link/ether 52:54:00:aa:da:e2 brd ff:ff:ff:ff:ff:ff +4: virbr0: mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000 + link/ether 86:a1:10:fb:ef:07 brd ff:ff:ff:ff:ff:ff +5: virbr0-nic: mtu 1500 qdisc fq_codel master virbr0 state DOWN mode DEFAULT group default qlen 1000 + link/ether 52:54:00:29:35:4c brd ff:ff:ff:ff:ff:ff +``` + +#### 创建多个绑定 + +系统会为每个绑定创建一个频道绑定接口,包括 BONDING\_OPTS 指令。使用这个配置方法可让多个绑定设备使用不同的配置。请按照以下操作创建多个频道绑定接口: + +- 创建多个 ifcfg-bondN 文件,文件中包含 BONDING\_OPTS 指令,让网络脚本根据需要创建绑定接口。 +- 创建或编辑要绑定的现有接口配置文件,添加 SLAVE 指令。 +- 使用 MASTER 指令工具在频道绑定接口中分配要绑定的接口,即从属接口。 + +以下是频道绑定接口配置文件示例: + +```text +DEVICE=bondN +NAME=bondN +TYPE=Bond +BONDING_MASTER=yes +IPADDR=192.168.1.1 +PREFIX=24 +ONBOOT=yes +BOOTPROTO=none +BONDING_OPTS="bonding parameters separated by spaces" +``` + +在这个示例中,使用绑定接口的号码替换 N。例如要创建两个接口,则需要使用正确的 IP 地址创建两个配置文件 ifcfg-bond0 和 ifcfg-bond1。 + +### 使用 nmtui 工具 + +在 nmtui 工具中,选择 **Edit a connection**,然后选择 **Bond**,按照提示输入相关信息,即可创建绑定。 + +返回 nmtui 的主菜单,选择 **Activate a connection**,然后选择刚刚创建的绑定,即可激活绑定。 + +## IPv6使用差异说明(vs IPv4) + +### 配置说明 + +#### 设置接口设备MTU值 + +##### 概述 + +IPv6场景中会发现整个路由路径中的最小mtu的值作为当前链接的PMTU的值,源端根据PMTU的值确定是否进行分片发送,而在整个路径中的其他设备将不再需要进行分片处理,从而可以降低中间路由设备的负载大小。其中IPv6 PMTU设置的最小值为1280。 + +##### 设置接口设备的mtu + +如果在配置了IPv6地址的接口上设置mtu的值小于1280(IPv6 PMTU设置的最小值),则会导致该接口的IPv6地址被删除。并且无法再次添加IPv6地址。所以在IPv6场景中,对接口设备的mtu的配置一定要大于等于1280。 +请在root权限下运行如下命令查看具体现象: + +```shell +# ip addr show enp3s0 +3: enp3s0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 + link/ether 52:54:00:62:xx:xx brd ff:ff:ff:ff:xx:xx + inet 10.41.125.236/16 brd 10.41.255.255 scope global noprefixroute dynamic enp3s0 + valid_lft 38663sec preferred_lft 38663sec + inet6 2001:222::2/64 scope global + valid_lft forever preferred_lft forever +``` + +```shell +# ip link set dev enp3s0 mtu 1200 +# ip addr show enp3s0 +3: enp3s0: mtu 1200 qdisc pfifo_fast state UP group default qlen 1000 + link/ether 52:54:00:62:xx:xx brd ff:ff:ff:ff:xx:xx + inet 10.41.125.236/16 brd 10.41.255.255 scope global noprefixroute dynamic enp3s0 + valid_lft 38642sec preferred_lft 38642sec +``` + +```shell +# ip addr add 2001:222::2/64 dev enp3s0 +RTNETLINK answers: No buffer space available +``` + +```shell +# ip link set dev enp3s0 mtu 1500 +# ip addr show enp3s0 +3: enp3s0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 + link/ether 52:54:00:62:xx:xx brd ff:ff:ff:ff:xx:xx + inet 10.41.125.236/16 brd 10.41.255.255 scope global noprefixroute dynamic enp3s0 + valid_lft 38538sec preferred_lft 38538sec +``` + +```shell +# ip addr add 2001:222::2/64 dev enp3s0 +# ip addr show enp3s0 +3: enp3s0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 + link/ether 52:54:00:62:xx:xx brd ff:ff:ff:ff:xx:xx + inet 10.41.125.236/16 brd 10.41.255.255 scope global noprefixroute dynamic enp3s0 + valid_lft 38531sec preferred_lft 38531sec + inet6 2001:222::2/64 scope global + valid_lft forever preferred_lft forever +``` + +#### 有状态自动配置IPv6地址 + +##### 概述 + +IPv6与IPv4都可以在root权限下通过DHCP的方式获得IP地址。IPv6地址有两种配置方式:无状态自动配置和有状态自动配置。 + +- 无状态自动配置 + + 不需要DHCP服务进行管理,设备根据网络RA(路由公告)获得网络前缀,或者link-local地址为固定fe80::。而接口ID则根据ifcfg配置IPV6\_ADDR\_GEN\_MODE的具体设置来进行自动获得: + + 1. IPv6\_ADDR\_GEN\_MODE="stable-privacy" 则根据设备及网络环境来确定一个随机接口ID。 + 2. IPv6\_ADDR\_GEN\_MODE="EUI64" 则根据设备MAC地址来确定接口ID。 + +- 有状态自动配置:需要DHCP服务器进行管理分配,服从DHCPv6协议来从DHCPv6服务器端租赁IPv6地址。 + + 在有状态自动配置IPv6地址时,DHCPv6服务端可以通过客户端设置的vendor class将客户端进行分类,不同类别分配不同地址段的IPv6地址。在IPv4场景中,客户端可以直接用dhclient的-V选项来设置vendor-class-identifier,DHCP服务端在配置文件中根据vendor-class-identifier来对客户端进行分类处理。而IPv6场景中,如果使用同样的方法对客户端分类,则分类并不会生效。 + + ```shell + dhclient -6 -V + ``` + + 这是由于DHCPv6和DHCP协议存在较大差异,DHCPv6的可选项中使用vendor-class-option替代了DHCP中的vendor-class-identifier。而dhclient的-V选项并不能设置vendor-class-option。 + +##### 有状态自动配置IPv6地址时dhclient设置vendor class方法 + +- 在客户端使用配置文件方式添加对vendor class的设置,使用方法如下: + + 客户端配置文件(/etc/dhcp/dhclient6.conf),文件位置可以自定义,在使用时需要通过dhclient -cf选项来指定配置文件: + + ```text + option dhcp6.vendor-class code 16 = {integer 32, integer 16, string}; + interface "enp3s0" { + send dhcp6.vendor-class ; + } + ``` + + > ![](../public_sys-resources/icon-note.gif) **说明:** + > + > - ``,32位整型数字,企业标识号,企业通过IANA注册。 + > - ``,16位整型数字,vendor class字符串长度。 + > - ``,要设置的vendor class字符串,例如:“HWHW”。 + + 客户端使用方法: + + ```shell + dhclient -6 -cf /etc/dhcp/dhclient6.conf + ``` + +- DHCPv6服务端配置文件(/etc/dhcp/dhcpd6.conf),需要dhcpd -cf选项来指定该配置文件: + + ```text + option dhcp6.vendor-class code 16 = {integer 32, integer 16, string}; + subnet6 fc00:4:12:ffff::/64 { + class "hw" { + match if substring ( option dhcp6.vendor-class, 6, 10 ) = "HWHW"; + } + pool6 { + allow members of "hw"; + range6 fc00:4:12:ffff::ff10 fc00:4:12:ffff::ff20; + } + pool6 { + allow unknown clients; + range6 fc00:4:12:ffff::100 fc00:4:12:ffff::120; + } + } + ``` + + > ![](../public_sys-resources/icon-note.gif) **说明:** + > substring \( option dhcp6.vendor-class, 6, 10 \) 其中子字符串的开始位置为6,因为前面包含4个字节的\和2个字节的\。而子字符串的结束位置为:6+\。这里vendor class string为“HWHW”,字符串的长度为4,所以子字符串的结束位置为6+4=10。用户可以根据实际需要来确定\及相应的\。 + + 服务端使用方法: + + ```shell + dhcpd -6 -cf /etc/dhcp/dhcpd6.conf + ``` + +#### 内核支持socket相关系统调用 + +##### 概述 + +IPv6地址长度扩展到128比特,所以有足够的IPv6地址可供分配使用。同时IPv6头相比IPv4头进行了简化,并增强了IPv6的自动配置功能。IPv6地址分为单播地址,组播地址和任意播地址。常用的单播地址又包含:链路本地地址(link-local address),唯一本地地址(Unique local address)和全局地址(global address)。由于IPv6的全局地址十分充足,唯一本地地址一般不被使用(其前身为站点本地地址(site-local address),已于2004年被废弃)。当前主要使用的单播地址为:链路本地地址(link-local address)和全局地址(global address)。当前内核支持socket系统调用,在使用单播地址的链路本地地址和全局地址时存在差异。 + +##### link-local地址和global地址在socket调用时的差异 + +RFC 2553: Basic Socket Interface Extensions for IPv6 定义sockaddr\_in6的数据结构如下; + +```text +struct sockaddr_in6 { + uint8_t sin6_len; /* length of this struct */ + sa_family_t sin6_family; /* AF_INET6 */ + in_port_t sin6_port; /* transport layer port # */ + uint32_t sin6_flowinfo; /* IPv6 flow information */ + struct in6_addr sin6_addr; /* IPv6 address */ + uint32_t sin6_scope_id; /* set of interfaces for a scope */ +}; +``` + +> ![](../public_sys-resources/icon-note.gif) **说明:** +> sin6\_scope\_id: 32位整型,对于链路本地地址(link-local address),对于链路范围的sin6\_addr,它可以用来标识指定的接口索引号。如果是站点范围的sin6\_addr,则用来作为站点的标识符(站点本地地址已被抛弃)。 + +在使用link-local地址进行socket通信时,在构造目的地址时,需要指定该地址所对应的接口索引号。一般可以通过if\_nametoindex函数将接口名转化为接口索引号。具体方式如下, + +```text +int port = 1234; +int sk_fd; +int iff_index = 0; +char iff_name[100] = "enp3s0"; +char * ll_addr[100] = "fe80::123:456:789"; +struct sockaddr_in6 server_addr; + +memset(&server_addr,0,sizeof(structsockaddr_in6)); +iff_index=if_nametoindex(iff_name); + +server_addr.sin6_family=AF_INET6; +server_addr.sin6_port=htons(port); +server_addr.sin6_scope_id=iff_index; +inet_pton(AF_INET6, ll_addr, &(server_addr.sin6_addr)); + +sk_fd=socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); +connect(sk_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in6)); +``` + +#### IPv4的dhclient守护进程持久化配置 + +##### 概述 + +通过NetworkManager服务来管理网络服务时,如果接口ifcfg-配置文件中配置了DHCP方式获得IP地址,则相应地NetworkManager服务会拉起dhclient守护进程来通过DHCP协议方式来从DHCP服务器获取IP地址。 + +dhclient提供了"-1"选项来决定dhclient进程在未获得DHCP服务响应时,是会不断持久化尝试请求地址还是会尝试时间超时后退出。针对IPv4的dhclient守护进程,可以在ifcfg-配置文件中设置PERSISTENT\_DHCLIENT来决定是否设置IPv4的dhclient进程的持久化。 + +##### 约束限制 + +1. 当dhclient进程在运行中被杀死,network服务无法自动将其拉起,可靠性需要用户自己保障。 +2. 配置了持久化选项PERSISTENT\_DHCLIENT,需要确保有相应的DHCP服务器。如果在拉起network时无可用DHCP服务器,dhclient进程不断尝试发送请求包但无回应,则会导致network服务卡死直到network服务超时失败。由于network服务在拉起多个网卡的IPv4 dhclient进程时,是通过串行的方式来拉起的。如果有网卡配置了持久化而DHCP服务器没有准备好,则会导致network服务在给该网卡获取IPv4地址超时卡死,进而导致后续网卡无法获得IPv4/IPv6地址。 + +以上两种约束限制是特殊的应用场景,需要用户自己进行可靠性保障。 + +##### IPv4 DHCP和IPv6 DHCPv6方式获取地址的配置差异 + +可以通过配置接口ifcfg-参数来分别实现IPv4和IPv6通过DHCP/DHCPv6协议来动态获取IP地址,具体配置说明如下; + +```text +BOOTPROTO=none|bootp|dhcp +DHCPV6C=yes|no +PERSISTENT_DHCLIENT=yes|no|1|0 +``` + +- BOOTPROTO: none表示静态配置IPv4地址,bootp|dhcp则会拉起DHCP dhclient来动态获取IPv4地址。 +- DHCPV6C: no表示静态配置IPv6地址,yes则会拉起DHCPv6 dhclient来动态获取IPv6地址。 +- PERSISTENT\_DHCLIENT:no|0表示IPv4的dhclient进程配置为“非持久化”,当dhclient向DHCP服务器发送一次请求报文而无响应,则会间隔一段时间后退出,退出值为2。yes|1则表示IPv4的dhclient进程配置为“持久化”,dhclient会向DHCP服务器反复发送请求报文。**如果没有配置PERSISTENT\_DHCLIENT项,则IPv4的dhclient会默认设置为“持久化”**。 + + > ![](../public_sys-resources/icon-note.gif) **说明:** + > PERSISTENT\_DHCLIENT配置只针对IPv4生效,对IPv6相关dhclient -6进程不生效,IPv6默认不进行持久化配置。 + +#### iproute相关命令配置IPv4与IPv6时的差异说明 + +##### 概述 + +由于IPv4和IPv6是两个不同的协议标准,iproute相关命令在使用方法上存在一定的差异。本章节主要梳理iproute包中用户经常使用到命令在IPv4和IPv6使用方面的差异,从而可以更好地指导用户使用iproute包中相关命令。 + +iproute相关命令均需要在root权限下运行。 + +##### IPv6地址的生命周期 + + + + + + + + + + + + + + + + + + + +

IPv6状态

+

解释

+

tentative

+

临时状态:刚添加地址还处于地址重复检测DAD过程。

+

preferred

+

首选状态:完成DAD过程,没有收到相应的NA报文,表示该地址没有冲突。

+

deprecated

+

弃用状态:地址有一定的使用时限(valid_lft和preferred_lft),preferred_lft到期后地址会变化deprecated状态。

+

该状态下的地址不能用于创建新的连接,但是原有的连接可以继续使用。

+

invalid

+

无效状态:使用时限超过preferred_lft一段时间后仍然没有成功进行租约续约,则valid_lft时间到后地址状态会被设置为invalid,表示该地址不可以再被使用。

+
+ +其他说明: + +- preferred\_lft:preferred lifetime,地址为首选状态的寿命,preferred\_lft没有到期的地址可以用于正常通信使用,若有多个preferred地址则按照内核具体机制选择地址。 +- valid\_lft: valid lifetime,地址有效的寿命,在\[preferred\_lft, valid\_lft\]时间段内该地址不能被用于新建连接,已经创建的连接继续有效。 + +##### ip link 命令 + +命令: + +```shell +ip link set IFNAME mtu MTU +``` + +IPv6中PMTU的最小值为1280,如果mtu值设置小于1280则会导致IPv6地址丢失。其他设备无法ping通该IPv6地址。 + +##### ip addr命令 + +1. 命令: + + ```shell + # ip [-6] addr add IFADDR dev IFNAME + ``` + + 添加IPv6地址可以选择添加-6选项也可以不添加,ip addr命令会根据具体地址类型来判断是ipv4地址还是IPv6地址。 + + 如果指定“-6”选项,但是IFADDR 是ipv4地址则会有错误返回。 + +2. 命令: + + ```shell + # ip [-6] addr add IFADDR dev IFNAME [home|nodad] + ``` + + \[home|nodad\] 选项只针对IPv6地址有效。 + + - home:将该地址指定为RFC 6275中定义的家庭地址。(这是移动节点从家庭链路获取的地址, 是移动节点的永久地址,如果移动节点保持在相同的归属链路中,则各种实体之间的通信照常进行。) + - nodad:配置该项(仅限IPv6)添加此地址时不执行重复地址检测DAD(RFC 4862)。如果一台设备上多个接口通过nodad配置了多个相同的IPv6地址,则会按照接口顺序使用该IPv6地址。同一个接口上不能添加一个nodad一个非nodad的相同IPv6地址。因为两个地址是一样的,所以会报“RTNETLINK answers: File exists”。 + +3. 命令: + + ```shell + # ip [-6] addr del IFADDR dev IFNAME + ``` + + 删除IPv6地址可以选择添加-6选项也可以不添加,ip addr del命令会根据具体地址类型来判断是ipv4地址还是IPv6地址。 + +4. 命令: + + ```shell + # ip [-6] addr show dev IFNAME [tentative|-tentative|deprecated|-deprecated|dadfailed|-dadfailed|temporary] + ``` + + - 不指定-6选项,则会同时打印IPv4和IPv6地址。指定-6选项则只打印IPv6地址。 + - \[tentative|-tentative|deprecated|-deprecated|dadfailed|-dadfailed|temporary\],这些选项只针对IPv6,可以根据IPv6地址状态对地址进行筛选查看。 + 1. tentative:(仅限IPv6)仅列出尚未通过重复地址检测的地址。 + 2. -tentative:(仅限IPv6)仅列出当前未处于重复地址检测过程中的地址。 + 3. deprecated:(仅限IPv6)仅列出已弃用的地址。 + 4. -deprecated:(仅限IPv6)仅列出未弃用的地址。 + 5. dadfailed:(仅限IPv6)仅列出重复地址检测失败的地址。 + 6. -dadfailed:(仅限IPv6)仅列出未重复地址检测失败的地址。 + 7. temporary:(仅限IPv6)仅列出临时地址 + +##### ip route命令 + +1. 命令: + + ```shell + # ip [-6] route add ROUTE [mtu lock MTU] + ``` + + - -6选项:添加IPv6路由可以选择添加-6选项也可以不添加,ip route命令会根据具体地址类型来判断是IPv4地址还是IPv6地址。 + + - mtu lock MTU:锁定路由的MTU值。如果不锁定MTU,则MTU的值则可能在PMTUD过程中被内核改变。如果锁定MTU,则不会尝试PMTUD,所有IPv4包都将不设置DF位发出,IPv6包则会按照MTU进行分段处理。 + +2. 命令: + + ```shell + # ip [-6] route del ROUTE + ``` + + 删除IPv6路由可以选择添加-6选项也可以不添加,ip route命令会根据具体地址类型来判断是IPv4地址还是IPv6地址。 + +##### ip rule命令 + +1. 命令: + + ```shell + # ip [-6] rule list + ``` + + -6选项:设置-6选项打印IPv6的策略路由,不设置-6选项打印IPv4的策略路由。所以需要根据具体协议类型来配置-6选项。 + +2. 命令: + + ```shell + # ip [-6] rule [add|del] [from|to] ADDR table TABLE pref PREF + ``` + + -6选项:IPv6相关的策略路由表项需要设置-6选项,否则会报错:“Error: Invalid source address.”。相应地,IPv4相关的策略路由表项不可以设置-6选项,否则会报错:“Error: Invalid source address.”。 + +#### NetworkManager服务配置差异说明 + +##### 概述 + +NetworkManager服务使用ifup/ifdown的逻辑接口定义进行高级网络设置。其参数大多数都是在/etc/sysconfig/network和/etc/sysconfig/network-scripts/ifcfg-两个配置文件设置。前者为全局设置,后者为指定网卡的设置,当两者有冲突时,后者生效。 + +##### 配置差异说明 + +其中在/etc/sysconfig/network下的配置差异有: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

IPv4

+

IPv6

+

含义说明

+

NA

+

IPV6FORWARDING=yes|no

+

IPv6转发,默认不转发。

+

NA

+

IPV6_AUTOCONF=yes|no

+

IPv6转发打开是no,否则是yes。

+

NA

+

IPV6_ROUTER=yes|no

+

IPv6转发打开是yes,否则是no。

+

NA

+

IPV6_AUTOTUNNEL=yes|no

+

指定Tunnel为自动隧道模式,默认是no。

+

GATEWAY

+

IPV6_DEFAULTGW=<IPv6 address[%interface]> (optional)

+

在IPv6中设置默认网关。

+

NA

+

IPV6_DEFAULTDEV=<interface> (optional)

+

指定默认转发的网卡。

+

NA

+

IPV6_RADVD_PIDFILE=<pid-file> (optional)

+

默认ipv6_radvd_pid路径:/var/run/radvd/radvd.pid。

+

NA

+

IPV6_RADVD_TRIGGER_ACTION=startstop|reload|restart|SIGHUP (optional)

+

radvd默认触发动作。

+
+ +而在/etc/sysconfig/network-scripts/ifcfg-下的差异主要有: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

IPv4

+

IPv6

+

含义说明

+

IPADDRn

+

IPV6ADDR=<IPv6 address>[/<prefix length>]

+

ip地址。

+

PREFIXn

+

NA

+

网络前缀,网络别名和ppp无效,优先级高于NETMASK。

+

NETMASKn

+

NA

+

子网掩码,仅用于别名和ppp。

+

GATEWAY

+

IPV6_DEFAULTGW=<IPv6 address[%interface]> (optional)

+

默认网关。

+

MTU

+

IPV6_MTU=<MTU of link> (optional)

+

默认MTU。

+

IPV4_FAILURE_FATAL=yes|no

+

IPV6_FAILURE_FATAL

+

缺省值是no。若设置为yes,dhclient失败ifup-eth会直接退出。

+

NA

+

IPV6_PRIVACY=rfc3041

+

默认禁用。

+

NA

+

IPV6INIT=yes|no

+

默认开启IPv6。

+

NA

+

IPV6FORWARDING=yes|no

+

默认关闭,已废弃。

+
+ +### FAQ + +#### iscsi-initiator-utils不支持登录fe80 IPv6地址 + +##### 问题现象 + +客户端通过IPv6登录iscsi服务端时,使用如“iscsiadm -m node -p ipv6address -l”的命令格式登录,如果是全局地址(global address),直接替换将命令范例中的“ipv6address”替换为全局地址即可;但如果是链路本地地址(link-local address,fe80开头的IPv6地址)则无法使用,因为iscsi-initiator-utils目前机制还不支持用链路本地地址(link-local address)地址登录iscsi服务端。 + +##### 原因分析 + +如果使用格式如“iscsiadm -m node -p fe80::xxxx -l”登录,会登录超时返回,这是因为使用链路本地地址必须指定接口,否则使用iscsi\_io\_tcp\_connect函数调用connect函数会失败,并且产生标准错误码22。 + +如果使用格式如“iscsiadm -m node -p fe80::xxxx%enp3s0 -l”登录时,iscsi\_addr\_match函数会将地址“fe80::xxxx%enp3s0”与服务端返回的node信息中的地址“fe80::xxxx”对比,对比结果不匹配,导致登录失败。 + +因此,**iscsi-initiator-utils目前机制还不支持用链路本地地址(link-local address)登录iscsi服务端**。 + +#### 网卡down掉之后,IPv6地址丢失 + +##### 问题现象 + +通过ip link down+up网卡或ifconfig down+up网卡命令,将网卡down掉之后再上线,查看网卡上配置的ip地址,发现ipv4地址不丢失,而配置的IPv6地址丢失。 + +##### 原因分析 + +内核中的处理逻辑为如果网卡设置为down状态,会清空所有IPv4及IPv6地址,将网卡重新up之后,ipv4地址自动恢复,网卡上自动配置的IPv6链路本地地址也会恢复,但是其他IPv6地址默认会丢失。如果需要保留这些IPv6地址,可以通过“sysctl -w net.ipv6.conf.\<网卡名>.keep_addr_on_down=1”来实现。 + +#### bond口已具有多个IPv6地址时,添加或删除IPv6地址耗时过久 + +##### 问题现象 + +下列方式配置或删除(包括flush)IPv6地址,X为动态变化的低16位,并且配置在bond口时,耗时会随已配置的IPv6地址数量成倍增加。例如由4个物理网卡组成的bond口添加IPv6地址时,单线程添加删除3000个IPv6地址均需大概5分钟,而普通物理网卡耗时在10秒内。 + +```shell +ip a add/del 192:168::18:X/64 dev DEVICE +``` + +##### 原因分析 + +bond口在添加IPv6地址时,会生成IPv6组播地址,并进行同步到所有的物理网卡上,此耗时会随IPv6数量增加而增加,导致耗时过长。 + +##### 解决方法 + +IPv6的组播地址是由IPv6地址的低24位与33-33-ff组合生成,组播地址过多会导致添加删除耗时增加,如果生成的组播地址为少量,耗时不会受此影响。 + +建议添加IPv6地址时,可保持低24位一致,保持高位变动,单网卡中仅需一个网段的一个地址即可与外部正常通信,此配置更符合常规使用。 + +#### Rsyslog在IPv4和IPv6混合使用场景中日志传输延迟 + +##### 问题现象 + +rsyslog客户端配置文件同时配置IPv4和IPv6地址,且端口配置相同的情况下,服务端收集log时会概率性出现日志打印延迟。 + +##### 原因分析 + +延迟是因为rsyslog内部存在缓冲队列机制,默认情况下需要缓冲区队列达到一定数量才会写入文件。 + +##### 解决方法 + +可在root权限下通过配置Direct模式,关闭缓冲队列机制解决该问题。在rsyslog远程传输服务端的/etc/rsyslog.d目录下新增的远程传输配置文件中,最开头增加如下配置: + +```shell +# ActionQueueType Direct +# MainMsgQueueType Direct +``` + +> ![](../public_sys-resources/icon-note.gif) **说明:** +> +> - Direct模式减少队列大小为1,所以在队列中会保留1条日志到下次日志打印; +> - Direct模式会降低服务器端的rsyslog性能。 diff --git a/docs/en/25.03/Server/Network/public_sys-resources/icon-caution.gif b/docs/en/25.03/Server/Network/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Network/public_sys-resources/icon-caution.gif differ diff --git a/docs/en/25.03/Server/Network/public_sys-resources/icon-danger.gif b/docs/en/25.03/Server/Network/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Network/public_sys-resources/icon-danger.gif differ diff --git a/docs/en/25.03/Server/Network/public_sys-resources/icon-note.gif b/docs/en/25.03/Server/Network/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Server/Network/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Server/Network/public_sys-resources/icon-notice.gif b/docs/en/25.03/Server/Network/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/docs/en/25.03/Server/Network/public_sys-resources/icon-notice.gif differ diff --git a/docs/en/25.03/Server/Network/public_sys-resources/icon-tip.gif b/docs/en/25.03/Server/Network/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/docs/en/25.03/Server/Network/public_sys-resources/icon-tip.gif differ diff --git a/docs/en/25.03/Server/Network/public_sys-resources/icon-warning.gif b/docs/en/25.03/Server/Network/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Network/public_sys-resources/icon-warning.gif differ diff --git a/docs/en/25.03/Server/Performance/CPUOptimization/KAE/_menu.md b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..b009ca4959d5032904e7a254ff2f217aac1a851e --- /dev/null +++ b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/_menu.md @@ -0,0 +1,8 @@ +--- +label: '使用KAE加速引擎' +ismanual: 'Y' +description: '使用 KAE 加速引擎降低处理器消耗,提高处理器效率' +children: + - label: '使用KAE加速引擎' + href: './using-the-kae.md' +--- diff --git a/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143189.png b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143189.png new file mode 100644 index 0000000000000000000000000000000000000000..7656f3aa5f5907f1e9f981c0cb5d44d4fcb84ef3 Binary files /dev/null and b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143189.png differ diff --git a/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143191.png b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143191.png new file mode 100644 index 0000000000000000000000000000000000000000..a82d1bcb2b719e3a372f63ae099cb5d52a93b536 Binary files /dev/null and b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143191.png differ diff --git a/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143193.png b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143193.png new file mode 100644 index 0000000000000000000000000000000000000000..94614045bddb0871b44d2f6603402f914871ad61 Binary files /dev/null and b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143193.png differ diff --git a/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143195.png b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143195.png new file mode 100644 index 0000000000000000000000000000000000000000..05011dbabe2d245c37ec68de646851bf955a2361 Binary files /dev/null and b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143195.png differ diff --git a/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143196.png b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143196.png new file mode 100644 index 0000000000000000000000000000000000000000..9bdbac969920af77721980804bd1c5433bea5bc9 Binary files /dev/null and b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143196.png differ diff --git a/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143197.png b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143197.png new file mode 100644 index 0000000000000000000000000000000000000000..5ea4eec4002374096d8ac18eb973ed3bf874b632 Binary files /dev/null and b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143197.png differ diff --git a/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143198.png b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143198.png new file mode 100644 index 0000000000000000000000000000000000000000..7d6360c150495d204da4b069e6dc62677580888f Binary files /dev/null and b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/figures/zh-cn_image_0231143198.png differ diff --git a/docs/en/25.03/Server/Performance/CPUOptimization/KAE/public_sys-resources/icon-note.gif b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Server/Performance/CPUOptimization/KAE/using-the-kae.md b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/using-the-kae.md new file mode 100644 index 0000000000000000000000000000000000000000..a09e327741d937c0c73cbe1ff6945daac8c91aba --- /dev/null +++ b/docs/en/25.03/Server/Performance/CPUOptimization/KAE/using-the-kae.md @@ -0,0 +1,709 @@ +# 使用KAE加速引擎 + +## 简介 + +KAE加速引擎为openEuler的一个软件加速库,搭载在Kunpeng 920处理器上联合提供硬件加速引擎功能,包含了对称加密、非对称加密和数字签名,用于加速SSL/TLS应用,可以显著降低处理器消耗,提高处理器效率。此外,用户通过OpenSSL标准接口可实现业务快速迁移。 + +KAE加速引擎支持以下算法: + +- 摘要算法SM3, 支持异步模式。 +- 对称加密算法SM4,支持异步模式,支持CTR/XTS/CBC模式。 +- 对称加密算法AES, 支持异步模式,支持ECB/CTR/XTS/CBC模式。 +- 非对称算法RSA,支持异步模式,支持 Key Sizes 1024/2048/3072/4096。 +- 密钥协商算法DH, 支持异步模式,支持 Key Sizes 768/1024/1536/2048/3072/4096。 + +## 应用场景 + +KAE加速引擎主要有以下应用场景,如[表1](#table11915824163418)所示。 + +**表 1** 应用场景 + + + + + + + + + + + + + + + + + + + +

场景

+

数据

+

大数据

+

流数据

+

数据加密

+

块数据

+

智能安防

+

视频流数据

+

Web服务

+

握手连接

+
+ +## 安装、升级和卸载 + +### 安装加速器软件包 + +#### 安装前准备 + +##### 环境要求 + +- TaiShan 200服务器,开启加速引擎功能 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 需要导入加速器许可证,具体操作请参考《[TaiShan 机架服务器 iBMC \(V500及以上\) 用户指南](https://support.huawei.com/enterprise/zh/doc/EDOC1100121687)》中“许可证管理”章节。 +> 物理机场景使用加速器需要关闭SMMU,具体操作请参考《[TaiShan 200服务器BIOS参数参考](https://support.huawei.com/enterprise/zh/doc/EDOC1100088653)》。 + +- CPU:Kunpeng 920 +- 操作系统:openEuler-21.09-aarch64-dvd.iso + +##### KAE加速引擎软件说明 + +**表 2** 加速引擎的rpm软件包 + + + + + + + + + + + + + + + + +

软件包名称

+

软件包说明

+

kae_driver-版本号-1.OS类型.aarch64.rpm

+

加速器驱动,包含内容:uacce.ko、hisi_qm.ko、hisi_sec2.ko、hisi_hpre.ko内核模块

+

支持:SM3/SM4/AES/RSA/DH算法

+

libwd-版本号-1.OS类型.aarch64.rpm

+

包含内容:libwd.so动态链接库

+

提供接口给KAE引擎

+

libkae-版本号-1.OS类型.aarch64.rpm

+

依赖:libwd rpm包

+

包含内容:libkae.so动态库

+

支持:SM3/SM4/AES/RSA/DH等算法

+
+ +#### 安装加速器软件包 + +##### 前提条件 + +- 已在本地安装远程SSH登录工具 +- 已安装openEuler操作系统 +- RPM工具能正常使用。 +- 已安装OpenSSL 1.1.1a或以上版本。 + + 使用如下命令查询OpenSSL的版本号 + + - openssl version + +##### 安装步骤 + +1. 以root帐号登录openEuler OS命令行界面。 +2. 新建目录用于存放加速器引擎软件包。 +3. 使用SSH远程登录工具,将所有加速引擎软件包拷贝到已建好的目录下。 +4. 在存放加速引擎软件包目录下,使用rpm -ivh命令安装加速器引擎软件包。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 由于libkae包的安装依赖libwd包,所以libwd的安装必须先于libkae。 + + ```shell + # rpm -ivh uacce*.rpm hisi*.rpm libwd-*.rpm libkae*.rpm + Verifying... ################################# [100%] + Preparing... ################################# [100%] + checking installed modules + uacce modules start to install + Updating / installing... + 1:uacce-1.2.10-4.oe1 ################################# [ 14%] + uacce modules installed + 2:libwd-1.2.10-3.oe1 ################################# [ 29%] + 3:libkae-1.2.10-3.oe1 ################################# [ 43%] + checking installed modules + hisi_hpre modules start to install + 4:hisi_hpre-1.2.10-4.oe1 ################################# [ 57%] + hisi_hpre modules installed + checking installed modules + hisi_rde modules start to install + 5:hisi_rde-1.2.10-4.oe1 ################################# [ 71%] + hisi_rde modules installed + checking installed modules + hisi_sec2 modules start to install + 6:hisi_sec2-1.2.10-4.oe1 ################################# [ 86%] + hisi_sec2 modules installed + checking installed modules + hisi_zip modules start to install + 7:hisi_zip-1.2.10-4.oe1 ################################# [100%] + hisi_zip modules installed + ``` + +5. 使用rpm -qa命令,查看加速器软件包是否已正常安装到系统内。使用rpm -ql命令 ,查看软件包的文件是否正确。示例如下。 + + ```shell + # rpm -qa|grep -E "hisi|uacce|libwd|libkae" + hisi_rde-1.2.10-4.oe1.aarch64 + hisi_sec2-1.2.10-4.oe1.aarch64 + libkae-1.2.10-3.oe1.aarch64 + hisi_hpre-1.2.10-4.oe1.aarch64 + uacce-1.2.10-4.oe1.aarch64 + libwd-1.2.10-3.oe1.aarch64 + hisi_zip-1.2.10-4.oe1.aarch64 + ``` + + ```shell + # rpm -ql uacce hisi* libwd* libkae + /lib/modules/4.19.90-2003.4.0.0036.oe1.aarch64/extra/hisi_qm.ko + /lib/modules/4.19.90-2003.4.0.0036.oe1.aarch64/extra/uacce.ko + /etc/modprobe.d/hisi_hpre.conf + /lib/modules/4.19.90-2003.4.0.0036.oe1.aarch64/extra/hisi_hpre.ko + /etc/modprobe.d/hisi_rde.conf + /lib/modules/4.19.90-2003.4.0.0036.oe1.aarch64/extra/hisi_rde.ko + /etc/modprobe.d/hisi_sec2.conf + /lib/modules/4.19.90-2003.4.0.0036.oe1.aarch64/extra/hisi_sec2.ko + /etc/modprobe.d/hisi_zip.conf + /lib/modules/4.19.90-2003.4.0.0036.oe1.aarch64/extra/hisi_zip.ko + /usr/include/warpdrive/config.h + /usr/include/warpdrive/include/uacce.h + /usr/include/warpdrive/smm.h + /usr/include/warpdrive/wd.h + /usr/include/warpdrive/wd_bmm.h + /usr/include/warpdrive/wd_cipher.h + /usr/include/warpdrive/wd_comp.h + /usr/include/warpdrive/wd_dh.h + /usr/include/warpdrive/wd_digest.h + /usr/include/warpdrive/wd_rsa.h + /usr/lib64/libwd.so.1.2.10 + /usr/local/lib/engines-1.1/libkae.so.1.2.10 + ``` + +6. 重启系统或通过命令行手动依次加载加速器引擎驱动到内核,并查看是否加载成功。 + + ```shell + # modprobe uacce + # lsmod | grep uacce + # modprobe hisi_qm + # lsmod | grep hisi_qm + # modprobe hisi_sec2 #加载hisi_sec2驱动时将根据/etc/modprobe.d/hisi_sec2.conf 下的配置文件加载到内核 + # modprobe hisi_hpre #加载hisi_hpre驱动时将根据/etc/modprobe.d/hisi_hpre.conf 下的配置文件加载到内核 + ``` + +##### 设置环境变量 + +通过以下命令导出环境变量:如果用户指定安装路径,则下面/usr/local应根据实际安装路径进行修改。 + +```shell +export OPENSSL_ENGINES=/usr/local/lib/engines-1.1 +``` + +##### 安装后检查 + +执行**rpm -qa**命令查看加速器引擎软件包是否安装成功。 + +打印信息中包含“ _软件包名-版本号-_ ”表示该软件包安装成功。示例如下。 + +```shell +# rpm -qa|grep -E "hisi|uacce|libwd|libkae" +hisi_rde-1.2.10-4.oe1.aarch64 +hisi_sec2-1.2.10-4.oe1.aarch64 +libkae-1.2.10-3.oe1.aarch64 +hisi_hpre-1.2.10-4.oe1.aarch64 +uacce-1.2.10-4.oe1.aarch64 +libwd-1.2.10-3.oe1.aarch64 +hisi_zip-1.2.10-4.oe1.aarch64 +``` + +#### 安装后操作 + +##### OpenSSL加速器引擎测试 + +用户可以通过以下命令测试部分加速器功能。 + +- 使用OpenSSL的软件算法测试RSA性能。 + + ```shell + linux-rmw4:/usr/local/bin # ./openssl speed -elapsed rsa2048 + ... + sign verify sign/s verify/s + rsa 2048 bits 0.001384s 0.000035s 724.1 28365.8. + ``` + +- 使用KAE引擎的测试RSA性能。 + + ```shell + linux-rmw4:/usr/local/bin # ./openssl speed -elapsed -engine kae rsa2048 + .... + sign verify sign/s verify/s + rsa 2048 bits 0.000355s 0.000022s 2819.0 45478.4 + ``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 使用KAE引擎加速后签名性能从724.1sign/s提升到2819sign/s。 + +- 使用OpenSSL的软件算法测试异步RSA性能。 + + ```shell + linux-rmw4:/usr/local/bin # ./openssl speed -elapsed -async_jobs 36 rsa2048 + .... + sign verify sign/s verify/s + rsa 2048 bits 0.001318s 0.000032s 735.7 28555 + ``` + +- 使用KAE引擎的测试异步RSA性能。 + + ```shell + linux-rmw4:/usr/local/bin # ./openssl speed -engine kae -elapsed -async_jobs 36 rsa2048 + .... + sign verify sign/s verify/s + rsa 2048 bits 0.000018s 0.000009s 54384.1 105317.0 + ``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 使用KAE引擎加速后异步RSA签名性能从735.7 sign/s提升到 54384.1sign/s。 + +- 使用OpenSSL的软件算法测试SM4 CBC模式性能。 + + ```shell + linux-rmw4:/usr/local/bin # ./openssl speed -elapsed -evp sm4-cbc + You have chosen to measure elapsed time instead of user CPU time. + .... + Doing sm4-cbc for 3s on 10240 size blocks: 2196 sm4-cbc's in 3.00s .... + type 51200 bytes 102400 bytes1048576 bytes2097152 bytes4194304 bytes8388608 bytes + sm4-cbc 82312.53k 85196.80k 85284.18k 85000.85k 85284.18k 85261.26k + ``` + +- 使用KAE引擎的测试SM4 CBC模式性能。 + + ```shell + linux-rmw4:/usr/local/bin # ./openssl speed -elapsed -engine kae -evp sm4-cbc + engine "kae" set. + You have chosen to measure elapsed time instead of user CPU time. + ... + Doing sm4-cbc for 3s on 1048576 size blocks: 11409 sm4-cbc's in 3.00s + ... + type 51200 bytes 102400 bytes1048576 bytes2097152 bytes4194304 bytes8388608 bytes + sm4-cbc 383317.33k 389427.20k 395313.15k 392954.73k 394264.58k 394264.58k + ``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 使用KAE加速后SM4 CBC模式在输入数据块大小为8M时,从82312.53k/s提升到383317.33k/s。 + +- 使用OpenSSL的软件算法测试SM3模式性能。 + + ```shell + linux-rmw4:/usr/local/bin # ./openssl speed -elapsed -evp sm3 + You have chosen to measure elapsed time instead of user CPU time. + Doing sm3 for 3s on 102400 size blocks: 1536 sm3's in 3.00s + .... + type 51200 bytes 102400 bytes1048576 bytes2097152 bytes4194304 bytes8388608 bytes + sm3 50568.53k 52428.80k 52428.80k 52428.80k 52428.80k 52428.80k + ``` + +- 使用KAE引擎测试SM3模式性能。 + + ```shell + linux-rmw4:/usr/local/bin # ./openssl speed -elapsed -engine kae -evp sm3 + engine "kae" set. + You have chosen to measure elapsed time instead of user CPU time. + Doing sm3 for 3s on 102400 size blocks: 19540 sm3's in 3.00s + .... + type 51200 bytes 102400 bytes 1048576 bytes 2097152 bytes 4194304 bytes 8388608 bytes + sm3 648243.20k 666965.33k 677030.57k 678778.20k 676681.05k 668292.44k + ``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 使用KAE加速后SM3算法在输入数据块大小为8M时,从52428.80 k/s提升到668292.44k/s。 + +- 使用OpenSSL软件算法测试AES算法CBC模式异步性能。 + + ```shell + linux-rmw4:/usr/local/bin # ./openssl speed -elapsed -evp aes-128-cbc -async_jobs 4 + You have chosen to measure elapsed time instead of user CPU time. + Doing aes-128-cbc for 3s on 51200 size blocks: 65773 aes-128-cbc's in 3.00s + Doing aes-128-cbc for 3s on 102400 size blocks: 32910 aes-128-cbc's in 3.00s + .... + type 51200 bytes 102400 bytes1048576 bytes2097152 bytes4194304 bytes8388608 bytes + aes-128-cbc 1122525.87k 1123328.00k 1120578.22k 1121277.27k 1119879.17k 1115684.86k + ``` + +- 使用KAE引擎测试AES算法CBC模式异步性能。 + + ```shell + linux-rmw4:/usr/local/bin # ./openssl speed -elapsed -evp aes-128-cbc -async_jobs 4 -engine kae + engine "kae" set. + You have chosen to measure elapsed time instead of user CPU time. + Doing aes-128-cbc for 3s on 51200 size blocks: 219553 aes-128-cbc's in 3.00s + Doing aes-128-cbc for 3s on 102400 size blocks: 117093 aes-128-cbc's in 3.00s + .... + type 51200 bytes 102400 bytes1048576 bytes2097152 bytes4194304 bytes8388608 bytes + aes-128-cbc 3747037.87k 3996774.40k 1189085.18k 1196774.74k 1196979.11k 1199570.94k + ``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> AES仅支持数据长度为256KB及以下场景的异步使用。 +> 使用KAE加速后AES算法在输入数据块为100K大小时,从1123328.00k/s提升到3996774.40 k/s 。 + +### 升级加速器软件包 + +#### 使用场景 + +当需要更新加速器软件版本时可以使用rpm -Uvh方式进行升级。 + +#### 操作步骤 + +1. 从openEuler社区下载最新版本的加速引擎软件包。 +2. 使用SSH远程登录工具,以root帐号进入Linux操作系统命令行界面。 +3. 将下载下来的最新版本的软件包都放在某个路径下。 +4. 在存放软件包的路径下使用rpm -Uvh 命令升级加速器驱动包及引擎库包。示例如下。 + + 命令和信息回显如下所示。 + + ![](./figures/zh-cn_image_0231143189.png) + + ![](./figures/zh-cn_image_0231143191.png) + +5. 使用rpm -qa 命令查询是否升级成功。确认查询到的版本是最新的升级后版本。 + + ![](./figures/zh-cn_image_0231143193.png) + + ![](./figures/zh-cn_image_0231143195.png) + +6. 重启系统或通过命令行手动卸载旧版本驱动,然后加载新版本驱动,并查看是否加载成功 + + ```shell + 卸载旧驱动 + # lsmod | grep uacce + uacce 262144 3 hisi_hpre,hisi_sec2,hisi_qm + # + # rmmod hisi_hpre + # rmmod hisi_sec2 + # rmmod hisi_qm + # rmmod uacce + # lsmod | grep uacce + # + 加载新驱动# modprobe uacce + # modprobe hisi_qm# modprobe hisi_sec2 #加载hisi_sec2驱动时将根据/etc/modprobe.d/hisi_sec2.conf 下的配置文件加载到内核 + # modprobe hisi_hpre #加载hisi_hpre驱动时将根据/etc/modprobe.d/hisi_hpre.conf 下的配置文件加载到内核 + # lsmod | grep uacce + uacce 36864 3 hisi_sec2,hisi_qm,hisi_hpre + ``` + +### 卸载加速器软件包 + +#### 使用场景 + +用户不再使用加速引擎软件,或进行新版本加速引擎软件的安装。 + +#### 操作步骤 + +1. 使用SSH远程登录工具,以root帐号进入Linux操作系统命令行界面。 +2. 重启系统或通过命令行手动将已加载到内核的驱动卸载掉,并查看是否卸载成功。 + + ```shell + # lsmod | grep uacce + uacce 36864 3 hisi_sec2,hisi_qm,hisi_hpre + # rmmod hisi_hpre + # rmmod hisi_sec2 + # rmmod hisi_qm + # rmmod uacce + # lsmod | grep uacce + # + ``` + +3. 通过rpm -e 命令卸载加速引擎软件包。示例如下。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 由于存在依赖关系,卸载libwd前须先卸载libkae引擎软件包。 + + ![](./figures/zh-cn_image_0231143196.png) + + ![](./figures/zh-cn_image_0231143197.png) + +4. 使用rpm -qa |grep 软件包名命令查询是否卸载成功。 + + ![](./figures/zh-cn_image_0231143198.png) + +## 日志查询 + +加速器引擎涉及日志信息如[表3](#table52821836)所示。 + +**表 3** 日志信息 + + + + + + + + + + + + + + + + +

目录

+

文件名

+

文件内容说明

+

/var/log/

+

kae.log

+

OpenSSL引擎日志默认打印等级为error级别,如需要设置日志级别按照如下操作:

+
  1. export KAE_CONF_ENV=/var/log/
  2. 在/var/log/下创建文件kae.cnf
  3. 在kae.cnf 文件中设置如下:

    [LogSection]

    +

    debug_level=error #取值内容none/error/info/warning/debug

    +
+
说明:

正常情况下不建议开启info或debug级别日志,否则会导致加速器性能的下降。

+
+

/var/log/

+

message/syslog

+
  • 内核日志路径为/var/log/message。
+
说明:

或通过dmesg > /var/log/dmesg.log日志收集内核相关日志,包含驱动及内核态日志。

+
+
+ +## 加速引擎的应用 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 如果用户未购买引擎许可证,建议用户不要通过kae引擎调用相应算法,否则可能会影响openSSL加密算法的性能。 + +### KAE引擎使用示例代码 + +```c +#include + +#include + +/* OpenSSL headers */ + +#include + +#include + +#include + +#include + +int main(int argc, char **argv) + +{ + + /* Initializing OpenSSL */ + + SSL_load_error_strings(); + + ERR_load_BIO_strings(); + + OpenSSL_add_all_algorithms(); + + /*You can use ENGINE_by_id Function to get the handle of the Huawei Accelerator Engine*/ + + ENGINE *e = ENGINE_by_id("kae"); + + /*使能加速器异步功能,可选配置,设置为“0”表示不使能,设置为“1”表示使能,默认使能异步功能*/ + + ENGINE_ctrl_cmd_string(e, "KAE_CMD_ENABLE_ASYNC", "1", 0) + + ENGINE_init(e); + + + RSA *rsa = RSA_new_method(e);#指定引擎用于RSA加解密 + + /*The user code*/ + + …… + +; + + ENGINE_free(e); + +; + +} +``` + +### 通过OpenSSL配置文件openssl.cnf使用KAE引擎 + +新建openssl.cnf 需要添加如下配置信息 + +```text +openssl_conf=openssl_def +[openssl_def] +engines=engine_section +[engine_section] +kae=kae_section +[kae_section] +engine_id=kae +dynamic_path=/usr/local/lib/engines-1.1/kae.so +KAE_CMD_ENABLE_ASYNC=1 # 0,表示不使能异步功能,1表示使能异步功能,默认使能 +default_algorithms=ALL +init=1 +``` + +导出OPENSSL\_CONF环境变量: + +```shell +export OPENSSL_CONF=/home/app/openssl.cnf #该路径为openssl.cnf存放路径 +``` + +使用OpenSSL配置文件示例如下: + +```c +#include + +#include + +/* OpenSSL headers */ + +#include + +#include + +#include + +#include + +int main(int argc, char **argv) + +{ + + /* Initializing OpenSSL */ + + SSL_load_error_strings(); + + ERR_load_BIO_strings(); + +#Load openssl configure + +OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); OpenSSL_add_all_algorithms(); + + /*You can use ENGINE_by_id Function to get the handle of the Huawei Accelerator Engine*/ + + ENGINE *e = ENGINE_by_id("kae"); + + /*The user code*/ + + …… + +; + + ENGINE_free(e); + +; +} +``` + +## 故障处理 + +### 初始化失败 + +#### 故障现象 + +加速器引擎没有完全加载成功。 + +#### 处理步骤 + +1. 检查加速器驱动是否加载成功,运行lsmod 命令查看uacce.ko、qm.ko 、sgl.ko 、hisi\_sec2.ko 、hisi\_hpre.ko 、hisi\_zip.ko、 hisi\_rde.ko是否在位。 + + ```shell + # lsmod | grep uacce + uacce 262144 2 hisi_hpre,hisi_qm,hisi_sec2,hisi_zip,hisi_rde + ``` + +2. 检查/usr/lib64(RPM方式安装时目录)或者/usr/local/lib(源码方式安装时目录)和OpenSSL安装目录是否有加速器引擎库,且建立正确的软链接。 + + ```shell + # 查询kae是否正确安装并建立软链接,如果有正确安装显示如下内容 + # ll /usr/local/lib/engines-1.1/ |grep kae + lrwxrwxrwx. 1 root root 22 Nov 12 02:33 kae.so -> kae.so.1.0.1 + lrwxrwxrwx. 1 root root 22 Nov 12 02:33 kae.so.0 -> kae.so.1.0.1 + -rwxr-xr-x. 1 root root 112632 May 25 2019 kae.so.1.0.1 + + # 查询libwd是否正确安装并建立软链接,如果有正确安装显示如下内容 + # ll /usr/lib64/ | grep libwd + lrwxrwxrwx. 1 root root 14 Nov 12 02:33 libwd.so -> libwd.so.1.0.1 + lrwxrwxrwx. 1 root root 14 Nov 12 02:33 libwd.so.0 -> libwd.so.1.0.1 + -rwxr-xr-x. 1 root root 137120 May 25 2019 libwd.so.1.0.1 + ``` + +3. 检查OpenSSL引擎库的路径是否能通过export命令进行导出。 + + ```shell + # echo $OPENSSL_ENGINES + # export OPENSSL_ENGINES=/usr/local/lib/engines-1.1 + # echo $OPENSSL_ENGINES + /usr/local/lib/engines-1.1 + ``` + +### 安装完加速器引擎之后,查找不到加速器设备 + +#### 故障现象 + +安装完加速器引擎之后,查找不到加速器设备。 + +#### 解决方法 + +1. 检查虚拟文件系统下是否有相应设备。正常情况下有如下相应的加速器设备。 + + ```shell + # ls -al /sys/class/uacce/ + total 0 + lrwxrwxrwx. 1 root root 0 Nov 14 03:45 hisi_hpre-2 -> ../../devices/pci0000:78/0000:78:00.0/0000:79:00.0/uacce/hisi_hpre-2 + lrwxrwxrwx. 1 root root 0 Nov 14 03:45 hisi_hpre-3 -> ../../devices/pci0000:b8/0000:b8:00.0/0000:b9:00.0/uacce/hisi_hpre-3 + lrwxrwxrwx. 1 root root 0 Nov 17 22:09 hisi_rde-4 -> ../../devices/pci0000:78/0000:78:01.0/uacce/hisi_rde-4 + lrwxrwxrwx. 1 root root 0 Nov 17 22:09 hisi_rde-5 -> ../../devices/pci0000:b8/0000:b8:01.0/uacce/hisi_rde-5 + lrwxrwxrwx. 1 root root 0 Nov 14 08:39 hisi_sec-0 -> ../../devices/pci0000:74/0000:74:01.0/0000:76:00.0/uacce/hisi_sec-0 + lrwxrwxrwx. 1 root root 0 Nov 14 08:39 hisi_sec-1 -> ../../devices/pci0000:b4/0000:b4:01.0/0000:b6:00.0/uacce/hisi_sec-1 + lrwxrwxrwx. 1 root root 0 Nov 17 22:09 hisi_zip-6 -> ../../devices/pci0000:74/0000:74:00.0/0000:75:00.0/uacce/hisi_zip-6 + lrwxrwxrwx. 1 root root 0 Nov 17 22:09 hisi_zip-7 -> ../../devices/pci0000:b4/0000:b4:00.0/0000:b5:00.0/uacce/hisi_zip-7 + ``` + +2. 若要使用hpre设备但是在[1](#li1760055514614)中未查询到,请按[初始化失败](#初始化失败)排查加速器软件是否已正确安装。 +3. 若[2](#li1600175515610)已确认加速器软件正确安装,请通过lspci命令排查物理设备是否存在。 + + ```shell + # lspci | grep HPRE + 79:00.0 Network and computing encryption device: Huawei Technologies Co., Ltd. HiSilicon HPRE Engine (rev 21) + b9:00.0 Network and computing encryption device: Huawei Technologies Co., Ltd. HiSilicon HPRE Engine (rev 21) + ## lspci | grep SEC + 76:00.0 Network and computing encryption device: Huawei Technologies Co., Ltd. HiSilicon SEC Engine (rev 21) + b6:00.0 Network and computing encryption device: Huawei Technologies Co., Ltd. HiSilicon SEC Engine (rev 21) + ## lspci | grep RDE + 78:01.0 RAID bus controller: Huawei Technologies Co., Ltd. HiSilicon RDE Engine (rev 21) + b8:01.0 RAID bus controller: Huawei Technologies Co., Ltd. HiSilicon RDE Engine (rev 21) + ## lspci | grep ZIP + 75:00.0 Processing accelerators: Huawei Technologies Co., Ltd. HiSilicon ZIP Engine (rev 21) + b5:00.0 Processing accelerators: Huawei Technologies Co., Ltd. HiSilicon ZIP Engine (rev 21) + # + ``` + +4. 若[3](#li1560012551369)未查询到相应的物理设备,请确认以下,不分先后: + - 确认是否已导入加速器许可证,若未导入,请参考《[TaiShan 机架服务器 iBMC \(V500及以上\) 用户指南](https://support.huawei.com/enterprise/zh/doc/EDOC1100121687)》中“许可证管理”章节,导入加速器许可证。导入加速器许可证之后,需要掉电重启iBMC,使能License。 + - 确认iBMC和BIOS版本是否支持加速器特性。 + +### 升级加速器驱动失败 + +#### 故障现象 + +升级加速器驱动后,重启系统驱动版本仍为旧版本。 + +#### 可能原因 + +在升级加速器驱动前,系统更新了其他驱动包,这些驱动包可能重新更新了引导文件系统initramfs,将未升级前的加速器驱动一起更新到了initramfs文件系统中。例如系统更新了网卡驱动,或者人为更新了initramfs文件系统,导致系统重启时优先从initramfs文件系统中加载加速器驱动。 + +#### 处理步骤 + +升级加速器驱动版本后,通过执行dracut \-\-force命令重新更新initramfs文件系统。 diff --git a/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/_menu.md b/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..612551da4503b3a060fabf1fa89ebafe6457d052 --- /dev/null +++ b/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/_menu.md @@ -0,0 +1,12 @@ +--- +label: 'sysBoost用户指南' +ismanual: 'Y' +description: '优化代码与运行环境的 CPU 微架构的适应性,提升程序性能' +children: + - label: '认识sysBoost' + href: './getting-to-know-sysBoost.md' + - label: '安装与部署' + href: './installation-and-deployment.md' + - label: '使用方法' + href: './usage-instructions.md' +--- diff --git a/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/figures/icon-note.gif b/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/figures/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/figures/icon-note.gif differ diff --git "a/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/figures/\346\236\266\346\236\204.png" "b/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/figures/\346\236\266\346\236\204.png" new file mode 100644 index 0000000000000000000000000000000000000000..92611802616844553a7c6ad79c12c0ed29d369ee Binary files /dev/null and "b/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/figures/\346\236\266\346\236\204.png" differ diff --git a/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/getting-to-know-sysBoost.md b/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/getting-to-know-sysBoost.md new file mode 100644 index 0000000000000000000000000000000000000000..81fff10694a7c12c96533d95d4b4ab98094acede --- /dev/null +++ b/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/getting-to-know-sysBoost.md @@ -0,0 +1,61 @@ +# 认识sysBoost + +## 概述 + +通过代码重排技术对可执行文件和动态库文件在线重排操作,优化代码与运行环境的CPU微架构的适应性,提升程序性能。 + +## 问题背景 + +- 大型APP应用,使用大量的第3方或自研动态库,函数调用产生大量PLT跳转导致IPC指令执行效率下降。 + +- 汇编代码体积大内存占用大,导致iTLB miss概率高。热点代码段布局离散,导致iCache miss高,影响CPU流水线执行效率。 + +- 应用开发者对操作系统与CPU微架构不熟悉,IPC性能调优成本过大。 + +## 设计方案 + +### 关键技术 + +- 动态库拼接:通过ld加载阶段将分散的动态库的代码段数据段拼接聚合,然后使用大页内存提升iTLB命中率。 + +- 消除PLT跳转:应用代码调用动态库函数的流程,需要先跳转PLT表,然后跳转真实函数,消除PLT跳转能提升IPC。 + +- 热点Section在线重排:默认情况下代码段是按动态库粒度排布的,通过在线重排技术可以实现热点代码按Section粒度重排。 + +- exec原生大页:用户态大页机制需要应用修改配置和重编译,exec原生大页机制直接在内核加载ELF文件阶段使用大页内存,对APP透明。 + +### 架构 + +**图 1** sysBoost设计总体方案 + +![](./figures/架构.png) + +## sysBoost支持的功能特性 + +- 支持全静态合并场景:将应用与其依赖的动态库合并为一个二进制,并进行段级别的重排,将多个离散的代码段/数据段合并为一个,提升应用性能。 + +- 自动对系统中的二进制进行优化:sysBoost守护进程读取配置文件获取需要优化的二进制以及对应的优化方式,按照用户的要求进行优化,并将优化好的二进制存储在.rto后缀的文件中。 + +- 二进制代码段/数据段大页预加载:用户态页表映射物理内存时,使用大页(2M)映射可以提升性能,而当前openeuler不支持文件页的大页映射。sysBoost提供大页预加载的功能,在二进制优化完成后立即将其内容以大页形式加载到内核中,在应用启动时将预加载的内容批量映射到用户态页表,减少应用的缺页中断和访存延迟,提升启动速度和运行效率。 + +- 二进制异常监控:如果sysBoost生成的.rto二进制出现BUG,应用可能会crash。为了避免应用被反复拉起,反复crash等严重后果,防止故障扩散,sysBoost会对加载.rto二进制的进程进行监控。如果发现这样的进程发生了crash,sysBoost会回退优化,将该.rto文件和原应用文件的标记删除;同时也会将配置文件重命名,防止下次sysBoost服务重启后再次进行优化。 + +## 价值概述 + +### 场景一 + +在UnixBench的Bash测试中,通常会执行一些常见的命令和脚本,例如 ls、grep、awk 等。这些命令和脚本通常会调用一些系统库,例如 libc、libpthread 等,这些库文件通常需要动态链接。由于动态链接会增加程序的启动时间和延迟,因此采用二进制合并技术将这些库文件合并到可执行文件中,可以显著提高Bash的性能,从而提高UnixBench的得分。 + +### 场景二 + +云核等产品组件动态可装配设计, 使用大量动态库,带来了以下问题: + +- 动态库机制引入函数间接跳转和代码布局离散问题, 导致CPU执行效率降低。 +- 动态库大量的符号解析过程, 影响程序启动速度。 +- 基于特定业务模型的预先离线编译优化(Profile-Guided Optimization), 无法适应不同业务模型变化。 + +在业务进程现网部署阶段, 通过sysBoost生成大进程可有效解决上述问题: + +- 通过自研exec大页机制加载大进程, 使代码段和数据段利用大页内存, 降低TLB miss。 +- 大进程包含所有动态库代码和应用代码,消除函数间接跳转问题。 +- 智能识别业务, 选择合适的热点模型, 重新生成大进程,在线适应业务变化。 diff --git a/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/installation-and-deployment.md b/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/installation-and-deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..18ecb4697bfc164efc8b940fa0b1d88c8fed348e --- /dev/null +++ b/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/installation-and-deployment.md @@ -0,0 +1,66 @@ +# 安装与部署 + +## 软硬件要求 + +- 硬件:鲲鹏920处理器 + +- 软件:操作系统openEuler 23.09 + +## 环境准备 + +- 安装openEuler系统。 + +- 安装sysBoost需要使用root权限。 + +## 安装sysBoost + +安装sysBoost的操作步骤如下(xxx在以下描述中代表版本号): + +1. 挂载openEuler的iso文件 + + ```sh + # 使用对应的openEuler版本 + mount openEuler-xxx-aarch64-dvd.iso /mnt + ``` + +2. 配置本地yum源 + + ```sh + vim /etc/yum.repos.d/local.repo + ``` + + 配置内容如下所示: + + ```sh + [localosrepo] + name=localosrepo + baseurl=file:///mnt + enabled=1 + gpgcheck=1 + gpgkey=file:///mnt/RPM-GPG-KEY-openEuler + ``` + +3. 安装sysBoost + + ```sh + yum install sysboost -y + ``` + +4. 验证是否安装成功,命令和回显如下表示安装成功 + + ```sh + rpm -qa | grep sysboost + # sysboost-xxx + rpm -qa | grep native-turbo + # native-turbo-xxx + ``` + +5. 安装需要合并的ELF文件所对应的relocation包 + + ```sh + yum install bash-relocation-xxx -y + yum install ncurses-relocation-xxx -y + ``` + +> ![](./figures/icon-note.gif) **说明:** +> 若当前所需要的可执行ELF文件及其依赖库中已经包含relocation段,则可以跳过步骤5。 diff --git a/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/sysBoost.md b/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/sysBoost.md new file mode 100644 index 0000000000000000000000000000000000000000..8e4a4d115017583fe4c94ea436c8040e6afd17d5 --- /dev/null +++ b/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/sysBoost.md @@ -0,0 +1,5 @@ +# sysBoost 用户指南 + +本文档介绍可执行ELF文件在线重排性能优化软件sysBoost的安装部署和使用方法,以指导用户快速了解并使用sysBoost。 + +本文档适用于使用openEuler系统并希望了解和使用sysBoost的社区开发者、开源爱好者以及相关合作伙伴。使用人员需要具备基本的Linux操作系统知识。 diff --git a/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/usage-instructions.md b/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/usage-instructions.md new file mode 100644 index 0000000000000000000000000000000000000000..fbef7a804eebc3caa45263c663c2ae0bb593be32 --- /dev/null +++ b/docs/en/25.03/Server/Performance/CPUOptimization/sysBoost/usage-instructions.md @@ -0,0 +1,94 @@ +# 使用方法 + +## 总体说明 + +- 使用和配置sysBoost需要使用root权限。 +- sysBoost不支持多实例运行。 +- 请管理员确保配置文件的正确性。 + +## 配置方法 + +### 配置文件说明 + +配置文件目录:/etc/sysboost.d/ + +**表 1** 客户端yaml文件配置说明 + + + + + + + + + + + + + + + + + + + + + + + + + +

配置名称

+

配置说明

+

参数类型

+

取值范围

+

elf_path

+

需要合并的可执行ELF文件的名称

+

字符串

+

sysBoost支持的可执行ELF文件路径名称

+

mode

+

sysBoost的运行模式

+

字符串

+

"static-nolibc"

+

libs

+

elf_path所指定的可执行ELF文件的依赖库,sysBoost可以自动探测依赖库,故为可选项

+

字符串

+

sysBoost支持的可执行ELF文件的依赖库的路径名称

+
+ +### 配置示例 + +sysBoost的toml配置文件示例: + +```sh +# /etc/sysboost.d/bash.toml +elf_path = "/usr/bin/bash" +mode = "static-nolibc" +libs = ["/usr/lib64/libtinfo.so.6"] +``` + +## 操作方法 + +- 启动sysBoost服务 + + ```sh + systemctl start sysboost.service + ``` + +- 关闭sysBoost服务 + + ```sh + systemctl stop sysboost.service + ``` + +- 状态查询(若没有标红字体,说明sysBoost运行正常) + + ```sh + systemctl status sysboost.service + ``` + +- 日志(若sysBoost出现错误,可通过系统日志查询相关信息) + + ```sh + cat /var/log/messages + ``` diff --git a/docs/en/25.03/Server/Performance/Overall/systemResource/_menu.md b/docs/en/25.03/Server/Performance/Overall/systemResource/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..c46fc7a6371d7d782d8a665343a2db439663e91d --- /dev/null +++ b/docs/en/25.03/Server/Performance/Overall/systemResource/_menu.md @@ -0,0 +1,8 @@ +--- +label: '系统资源与性能' +ismanual: 'Y' +description: '介绍CPU,内存,I/O 及常用性能分析工具' +children: + - label: '系统资源与性能' + href: './system-resources-and-performance.md' +--- diff --git a/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001335457246.png b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001335457246.png new file mode 100644 index 0000000000000000000000000000000000000000..325d6a8ce097db0b92b1a883bc4b3d4ad0bc6a49 Binary files /dev/null and b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001335457246.png differ diff --git a/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001336448570.png b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001336448570.png new file mode 100644 index 0000000000000000000000000000000000000000..4bd494d78d83fef2e8a89c80e17c9b6db892a2e9 Binary files /dev/null and b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001336448570.png differ diff --git a/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001337039920.png b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001337039920.png new file mode 100644 index 0000000000000000000000000000000000000000..40c07e9b6ec27cdbe47d39788736b892f1174cc8 Binary files /dev/null and b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001337039920.png differ diff --git a/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001384808269.png b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001384808269.png new file mode 100644 index 0000000000000000000000000000000000000000..be18ecef3a149d5742f18535552f66f26ab34832 Binary files /dev/null and b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001384808269.png differ diff --git a/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001385585749.png b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001385585749.png new file mode 100644 index 0000000000000000000000000000000000000000..c13604ab7095c2a7717bde1384f0aea3d53f69e3 Binary files /dev/null and b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001385585749.png differ diff --git a/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001385611905.png b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001385611905.png new file mode 100644 index 0000000000000000000000000000000000000000..8c233e40a21e678ddf4115c2e2e80c96e25a60ce Binary files /dev/null and b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001385611905.png differ diff --git a/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001385905845.png b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001385905845.png new file mode 100644 index 0000000000000000000000000000000000000000..a6cb8bc4a188ef444919d71f7f16baa06422788b Binary files /dev/null and b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001385905845.png differ diff --git a/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001386149037.png b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001386149037.png new file mode 100644 index 0000000000000000000000000000000000000000..da73fead24d8805bb43287f53c757e80ff0d597f Binary files /dev/null and b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001386149037.png differ diff --git a/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001389098425.png b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001389098425.png new file mode 100644 index 0000000000000000000000000000000000000000..c63903009ab9ba454f169250632dbec1b3c94467 Binary files /dev/null and b/docs/en/25.03/Server/Performance/Overall/systemResource/images/zh-cn_image_0000001389098425.png differ diff --git a/docs/en/25.03/Server/Performance/Overall/systemResource/system-resources-and-performance.md b/docs/en/25.03/Server/Performance/Overall/systemResource/system-resources-and-performance.md new file mode 100644 index 0000000000000000000000000000000000000000..18dd9640703ae82f8781a04caa14758e8e2c75d6 --- /dev/null +++ b/docs/en/25.03/Server/Performance/Overall/systemResource/system-resources-and-performance.md @@ -0,0 +1,329 @@ +# 系统资源与性能 + +## CPU + +### 基本概念 + +中央处理器(Central Processing Unit,简称CPU)是计算机的主要设备之一,其功能是解释计算机指令以及处理计算机软件中的数据。 + +1. 物理核:可以真实看到的CPU核,有独立的电路元件以及L1、L2缓存,可以独立地执行指令。一个CPU可以有多个物理核。 +2. 逻辑核:在同一个物理核内,逻辑层面上存在的核。一般一个物理核对应一个线程,但是如果开启了超线程,当超线程数量为n时,一个物理核可以分成n个逻辑核。 + +可以通过lscpu命令查看服务器中有多少个CPU,每个CPU中有几个物理核,以及每个CPU有几个逻辑核。 + +### 常用CPU性能分析工具 + +1. uptime:可用于**打印系统平均负载**,通过查看最后三个数字,可以判断平均负载的变化趋势。 + 平均负载大于CPU数量时表示CPU不足以服务线程,部分线程在等待;平均负载小于CPU数量,代表当前还有余量。 + + ![zh-cn_image_0000001384808269](./images/zh-cn_image_0000001384808269.png) + +2. vmstat:可以**动态地了解系统资源的使用情况**,以及查看系统中是哪一个环节最占用系统资源。 + 通过**vmstat -h**命令可以查看命令详解参数。 + 例如: + + ```shell + #使用vmstat进行监测,每隔1秒刷新一次 + vmstat 1 + ``` + + ![](./images/zh-cn_image_0000001385585749.png) + 在命令的输出信息中,各字段所代表的含义如下: + |字段|含义| + |--|--| + |procs|进程信息字段。| + |memory|内存信息字段。| + |swap|交换分区信息字段。| + |io|磁盘读/写信息字段。| + |system|系统信息字段。| + |cpu|CPU信息字段。-us:非内核进程消耗 CPU 运算时间的百分比。-sy:内核进程消耗 CPU 运算时间的百分比。-id:空闲。-wa:等待 I/O 所消耗的 CPU 百分比。-st:被虚拟机所盗用的 CPU 百分比。| + +3. sar:可用于**分析系统性能**,可以用来观察当前的活动以及配置,用以归档和报告历史统计信息。 + 例如: + + ```shell + # 安装sysstat + yum install -y sysstat + + # 查看系统CPU的整体负载情况,每3秒统计一次,共统计5次 + sar -u 3 5 + ``` + + ![zh-cn_image_0000001336448570](./images/zh-cn_image_0000001336448570.png) + + 在命令的输出信息中,各字段所代表的含义如下: + + |字段|含义| + |--|--| + |%user|用户模式下消耗的 CPU 时间的比例。| + |%nice|通过 nice 改变了进程调度优先级的进程,在用户模式下消耗的 CPU 时间的比例。| + |%system|系统模式下消耗的 CPU 时间的比例。| + |%iowait|CPU 等待磁盘 I/O 导致空闲状态消耗的时间比例。| + |%steal|利用操作系统等虚拟化技术,等待其他虚拟CPU计算占用的时间比例。| + |%idle|CPU空闲时间比例。| + +4. ps:可用于**查看正在运行的进程**。 + + ```shell + # 查看系统中所有的进程,以及查看进程的父进程的 PID 和进程优先级 + ps -le + ``` + + ![zh-cn_image_0000001337039920](./images/zh-cn_image_0000001337039920.png) + + ```shell + # 查看当前shell产生的进程 + ps -l + ``` + + ![zh-cn_image_0000001385611905](./images/zh-cn_image_0000001385611905.png) + +5. top:可以**动态地持续监听进程的运行状态,显示最消耗CPU的进程**。 + + ```shell + top + ``` + + ![zh-cn_image_0000001335457246](./images/zh-cn_image_0000001335457246.png) + +## 内存 + +### 基本概念 + +**内存**是计算机的重要组成部件,用于暂时存放CPU中的运算数据,以及与硬件等外部存储器交换的数据。特别地,**非统一内存访问架构**(non-uniform memory access,简称NUMA)是一种为多处理器的电脑设计的内存架构,**内存访问时间取决于内存相对于处理器的位置**。在NUMA下,处理器访问本地内存的速度比非本地内存速度(内存位于另一个处理器,或者是处理器之间共享的内存)快。 + +### 常用内存分析工具/方式 + +1. free:可用于**显示系统内存状态**。 + + 例如: + + ```shell + # 显示系统内存状态,以MB单位显示 + free -m + ``` + + 回显信息如下: + + ```shell + [root@openEuler ~]# free -m + total used free shared buff/cache available + Mem: 2633 436 324 23 2072 2196 + Swap: 4043 0 4043 + ``` + + 在命令的输出信息中,各字段所代表的含义如下: + + |标识|含义| + |--|--| + |total|总内存数。| + |used|已经使用的内存数。| + |free|空闲的内存数。| + |shared|多个进程共享的内存总数。| + |buff/cache|缓冲和缓存内存总数。| + |available|估计有多少内存可用于启动新应用程序,而不交换。| + +2. vmstat:可以**动态地监控系统内存**,查看系统内存的使用情况。 + + 例如: + + ```shell + # 监测系统内存,显示活跃和非活跃内存 + vmstat -a + ``` + + 回显信息如下: + + ```shell + [root@openEuler ~]# vmstat -a + procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- + r b swpd free inact active si so bi bo in cs us sy id wa st + 2 0 520 331980 1584728 470332 0 0 0 2 15 19 0 0 100 0 0 + ``` + + 在命令的输出信息中,与内存相关的memory字段所代表的含义如下: + + |字段|含义| + |--|--| + |memory|内存信息字段。-swpd:虚拟内存的使用情况,单位为 KB。-free:空闲的内存容量,单位为 KB。-inact:非活跃的内存容量,单位为 KB。-active:活跃的内存容量,单位为 KB。| + +3. sar:可用于**监控系统的内存使用情况**。 + + 例如: + + ```shell + # 系统内存在采样时间内的使用情况,每2秒统计一次,统计 3 次 + sar -r 2 3 + ``` + + 回显信息如下: + + ```shell + [root@openEuler ~]# sar -r 2 3 + + 04:02:09 PM kbmemfree kbavail kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact kb + dirty + 04:02:11 PM 332180 2249308 189420 7.02 142172 1764312 787948 11.52 470404 1584924 + 36 + 04:02:13 PM 332148 2249276 189452 7.03 142172 1764312 787948 11.52 470404 1584924 + 36 + 04:02:15 PM 332148 2249276 189452 7.03 142172 1764312 787948 11.52 470404 1584924 + 36 + Average: 332159 2249287 189441 7.03 142172 1764312 787948 11.52 470404 1584924 + 36 + ``` + + 在命令的输出信息中,各字段所代表的含义如下: + + |字段|含义| + |--|--| + |kbmemfree|内存的未使用空间。| + |kbmemused|内存的已使用空间。| + |%memused|已使用空间的百分比。| + |kbbuffers|缓冲区的数据存取量。| + |kbcached|系统全域的数据存取量。| + +4. numactl:可用于**查看NUMA节点配置和状态**。 + + 例如: + + ```shell + # 查看当前的NUMA配置 + numactl -H + ``` + + 回显信息如下: + + ```shell + [root@openEuler ~]# numactl -H + available: 1 nodes (0) + node 0 cpus: 0 1 2 3 + node 0 size: 2633 MB + node 0 free: 322 MB + node distances: + node 0 + 0: 10 + ``` + + 服务器共划分为1个NUMA节点。每个节点包含4个CPU core,每个节点的内存大小约为6GB。 + 同时,该命令还给出了不同节点间的距离,距离越远,跨NUMA内存访问的延时越大。应用程序运行时应减少跨NUMA访问内存。 + + numastat:可用于**观察各个NUMA节点的状态** + + ```shell + # 观察NUMA节点的状态 + numastat + ``` + + ```shell + [root@openEuler ~]# numastat + node0 + numa_hit 5386186 + numa_miss 0 + numa_foreign 0 + interleave_hit 17483 + local_node 5386186 + other_node 0 + ``` + + numastat命令输出字段及其含义如下: + + |标识|含义| + |--|--| + |numa_hit|节点内CPU核访问本地内存的次数。| + |numa_miss|节点内核访问其他节点内存的次数。| + |numa_foreign|初始分配在本地,最后分配在其他节点的叶数量。每个numa_foreign对应numa_miss事件。| + |interleave_hit|interleave策略页成功分配到这个节点。| + |local_node|该节点的进程成功在这个节点上分配内存访问的大小。| + |other_node|该节点的进程在其他节点上分配的内存访问大小。| + +## I/O + +### 基本概念 + +**I/O**表示输入(Input)/输出(Output),输入指系统接收信号或数据的操作,输出指从系统发出信号或数据的操作。对于CPU 和主存储器的组合,**任何信息传入或传出 CPU/内存组合,就会被认为是 I/O**。 + +### 常用I/O性能分析工具 + +1. iostat:可以**汇报所有在线磁盘的统计信息**。 + + 例如: + + ```shell + # 详细显示磁盘信息,以KB为单位显示,以100秒为周期统计(命令本身不会主动停止,需要执行Ctrl+C手动停止) + iostat -d -k -x 100 + + # 详细显示磁盘信息,以KB为单位显示,以1秒为周期统计,总共统计100s + iostat -d -k -x 1 100 + ``` + + ![zh-cn_image_0000001385905845](./images/zh-cn_image_0000001385905845.png) + + 在命令的输出信息中,各字段所代表的含义如下: + + |字段|含义| + |--|--| + |Device|监测设备名称。| + |r/s|设备每秒完成的读取请求数(合并后)。| + |rKB/s|每秒从磁盘读取KB数。| + |rrqm/s|每秒合并放入请求队列的读操作数。| + |%rrqm|读取请求在发送到设备之前合并在一起的百分比。| + |r_await|每个读请求耗费的平均时间。| + |rareq-sz|向设备发出的读取请求的平均大小(以KB为单位)。| + |w/s|设备每秒完成的写入请求数(合并后)。| + |wKB/s|每秒写入磁盘KB数。| + |wrqm/s|每秒合并放入请求队列的写操作数。| + |%wrqm|写入请求在发送到设备之前合并在一起的百分比。| + |w_await|每个写请求耗费的平均时间。| + |wareq-sz|向设备发出的写入请求的平均大小(以KB为单位)。| + |d/s|设备每秒完成的丢弃请求数。| + |dKB/s|每秒为设备丢弃的扇区(KB)数。| + |drqm/s|每秒合并到设备排队的丢弃请求数。| + |%drqm|丢弃请求在发送到设备之前合并在一起的百分比。| + |d_await|向要服务的设备发出丢弃请求的平均时间。| + |dareq-sz|向设备发出的丢弃请求的平均大小(以KB为单位)。| + |f/s|设备每秒完成的刷新请求数(合并后)。| + |f_await|向要服务的设备发出的刷新请求的平均时间。| + |aqu-sz|向设备发出的请求的平均队列长度。| + |%util|用于I/O操作时间的百分比,即使用率。| + +2. sar:可用于**查看系统磁盘的读写性能**。 + + 例如: + + ```shell + # 显示系统所有硬盘设备在采样时间内的使用状态,每3秒统计一次,统计5次 + sar -d 3 5 + ``` + + ![zh-cn_image_0000001386149037](./images/zh-cn_image_0000001386149037.png) + + 在命令的输出信息中,各字段所代表的含义如下: + + |标识|含义| + |--|--| + |tps|每秒向物理设备发出的传输总数。| + |rKB/s|每秒从设备读取的KB数。| + |wKB/s|每秒写入设备的KB数。| + |dKB/s|设备每秒丢弃的KB数。| + |areq-sz|向设备发出的I/O请求的平均大小(KB)。| + |aqu-sz|向设备发出的请求的平均队列长度。| + |await|向要服务的设备发出的I/O请求的平均时间。| + |%util|向设备发出I/O请求的已用时间百分比(设备的带宽利用率)。| + +3. vmstat + + ```shell + # 使用vmstat进行监测,报告磁盘相关统计信息 + vmstat -d + ``` + + ![zh-cn_image_0000001389098425](./images/zh-cn_image_0000001389098425.png) + + 在命令的输出信息中,各字段所代表的含义如下: + + |字段|含义| + |--|--| + |reads|-total:已成功完成的读取总数。-merged:分组读取(导致一次I/O)。-sectors:扇区读取成功。-ms:读取花费的毫秒数。| + |writes|-total:已成功完成的写入总数。-merged:分组写入(导致一次I/O)。-sectors:写入成功的扇区。-ms:写入所花费的毫秒数。| + |IO|-cur:正在进行的 I/O 数。-sec:I/O 所花费的秒数。| diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/A-Tune.md b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/A-Tune.md new file mode 100644 index 0000000000000000000000000000000000000000..f437a25bcd5ac9c2df2537b870506570d70b7fc7 --- /dev/null +++ b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/A-Tune.md @@ -0,0 +1,5 @@ +# A-Tune 用户指南 + +本文档介绍openEuler系统性能自优化软件A-Tune的安装部署和使用方法,以指导用户快速了解并使用A-Tune。 + +本文档适用于使用openEuler系统并希望了解和使用A-Tune的社区开发者、开源爱好者以及相关合作伙伴。使用人员需要具备基本的Linux操作系统知识。 diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/_menu.md b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..7367a0bd65d81d1e0c952d3371414acd4978c8ab --- /dev/null +++ b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/_menu.md @@ -0,0 +1,18 @@ +--- +label: 'A-Tune用户指南' +ismanual: 'Y' +description: '利用人工智能技术,实现对 openEuler 系统性能的智能化、自动化调优' +children: + - label: '认识A-Tune' + href: './getting-to-know-a-tune.md' + - label: '安装与部署' + href: './installation-and-deployment.md' + - label: '使用方法' + href: './usage-instructions.md' + - label: 'native-turbo特性' + href: './native-turbo.md' + - label: '常见问题与解决方法' + href: './faqs.md' + - label: '附录' + href: './appendixes.md' +--- diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/appendixes.md b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/appendixes.md new file mode 100644 index 0000000000000000000000000000000000000000..23a121ab80620eb42bfd88138a68e01ff32fef52 --- /dev/null +++ b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/appendixes.md @@ -0,0 +1,28 @@ +# 附录 + + + +- [附录](#附录) + - [术语和缩略语](#术语和缩略语) + + + +## 术语和缩略语 + +**表 1** 术语表 + + + + + + + + + + + +

术语

+

含义

+

profile

+

优化项集合,最佳的参数配置

+
diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/faqs.md b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..b7124fd1b75be0806ef7bea5352babc21a8e87b7 --- /dev/null +++ b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/faqs.md @@ -0,0 +1,52 @@ +# 常见问题与解决方法 + +## **问题1:train命令训练模型出错,提示“training data failed”** + +原因:collection命令只采集一种类型的数据。 + +解决方法:至少采集两种数据类型的数据进行训练。 + +## **问题2:atune-adm无法连接atuned服务** + +可能原因: + +1. 检查atuned服务是否启动,并检查atuned侦听地址。 + + ```shell + # systemctl status atuned + # netstat -nap | grep atuned + ``` + +2. 防火墙阻止了atuned的侦听端口。 +3. 系统配置了http代理导致无法连接。 + +解决方法: + +1. 如果atuned没有启动,启动该服务,参考命令如下: + + ```shell + # systemctl start atuned + ``` + +2. 分别在atuned和atune-adm的服务器上执行如下命令,允许侦听端口接收网络包,其中60001为atuned的侦听端口号。 + + ```shell + # iptables -I INPUT -p tcp --dport 60001 -j ACCEPT + # iptables -I INPUT -p tcp --sport 60001 -j ACCEPT + ``` + +3. 不影响业务的前提下删除http代理,或对侦听IP不进行http代理,命令如下: + + ```shell + # no_proxy=$no_proxy,侦听地址 + ``` + +## **问题3:atuned服务无法启动,提示“Job for atuned.service failed because a timeout was exceeded.”** + +原因:hosts文件中缺少localhost配置 + +解决方法:在/etc/hosts文件中127.0.0.1这一行添加上localhost + +```ini +127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 +``` diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/picture1.png b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/picture1.png new file mode 100644 index 0000000000000000000000000000000000000000..52d496e95f06ef8636730dbbc1aa84d88aea6a34 Binary files /dev/null and b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/picture1.png differ diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/picture4.png b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/picture4.png new file mode 100644 index 0000000000000000000000000000000000000000..85d57aa2024615a6f0fbff5a7d2a207941eb3085 Binary files /dev/null and b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/picture4.png differ diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0213178479.png b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0213178479.png new file mode 100644 index 0000000000000000000000000000000000000000..d245d48dc07e2b01734e21ec1952e89fa9269bdb Binary files /dev/null and b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0213178479.png differ diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0213178480.png b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0213178480.png new file mode 100644 index 0000000000000000000000000000000000000000..a32856aa08e459ed0f51f8fcf4c2f51511c12095 Binary files /dev/null and b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0213178480.png differ diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0214540398.png b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0214540398.png new file mode 100644 index 0000000000000000000000000000000000000000..cea2292307b57854aa629ec102a5bc1b16d244a0 Binary files /dev/null and b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0214540398.png differ diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0227497000.png b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0227497000.png new file mode 100644 index 0000000000000000000000000000000000000000..db9b5ce8b6d211d54ea36930504cca415ddfb8ca Binary files /dev/null and b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0227497000.png differ diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0227497343.png b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0227497343.png new file mode 100644 index 0000000000000000000000000000000000000000..aecf293846ebd12f15b9a3fb5fdc2618d9d527dc Binary files /dev/null and b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0227497343.png differ diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0231122163.png b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0231122163.png new file mode 100644 index 0000000000000000000000000000000000000000..66bf082a6537ad70c84e4e8f07de745f973482b9 Binary files /dev/null and b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0231122163.png differ diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0245342444.png b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0245342444.png new file mode 100644 index 0000000000000000000000000000000000000000..10f0fceb42c00c80ef49decdc0c480eb04c2ca6d Binary files /dev/null and b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/figures/zh-cn_image_0245342444.png differ diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/getting-to-know-a-tune.md b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/getting-to-know-a-tune.md new file mode 100644 index 0000000000000000000000000000000000000000..cda223c09cddf46580ff377e57d8eb2f8e58c94d --- /dev/null +++ b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/getting-to-know-a-tune.md @@ -0,0 +1,522 @@ +# 认识A-Tune + + + +- [认识A-Tune](#认识a-tune) + - [简介](#简介) + - [架构](#架构) + - [支持特性与业务模型](#支持特性与业务模型) + - [支持特性](#支持特性) + - [支持业务模型](#支持业务模型) + + + +## 简介 + +操作系统作为衔接应用和硬件的基础软件,如何调整系统和应用配置,充分发挥软硬件能力,从而使业务性能达到最优,对用户至关重要。然而,运行在操作系统上的业务类型成百上千,应用形态千差万别,对资源的要求各不相同。当前硬件和基础软件组成的应用环境涉及高达7000多个配置对象,随着业务复杂度和调优对象的增加,调优所需的时间成本呈指数级增长,导致调优效率急剧下降,调优成为了一项极其复杂的工程,给用户带来巨大挑战。 + +其次,操作系统作为基础设施软件,提供了大量的软硬件管理能力,每种能力适用场景不尽相同,并非对所有的应用场景都通用有益,因此,不同的场景需要开启或关闭不同的能力,组合使用系统提供的各种能力,才能发挥应用程序的最佳性能。 + +另外,实际业务场景成千上万,计算、网络、存储等硬件配置也层出不穷,实验室无法遍历穷举所有的应用和业务场景,以及不同的硬件组合。 + +为了应对上述挑战,openEuler推出了A-Tune。 + +A-Tune是一款基于AI开发的系统性能优化引擎,它利用人工智能技术,对业务场景建立精准的系统画像,感知并推理出业务特征,进而做出智能决策,匹配并推荐最佳的系统参数配置组合,使业务处于最佳运行状态。 + +![](./figures/zh-cn_image_0227497000.png) + +## 架构 + +A-Tune核心技术架构如下图,主要包括智能决策、系统画像和交互系统三层。 + +- 智能决策层:包含感知和决策两个子系统,分别完成对应用的智能感知和对系统的调优决策。 +- 系统画像层:主要包括自动特征工程和两层分类模型,自动特征工程用于业务特征的自动选择,两层分类模型用于业务模型的学习和分类。 +- 交互系统层:用于各类系统资源的监控和配置,调优策略执行在本层进行。 + +![](./figures/zh-cn_image_0227497343.png) + +## 支持特性与业务模型 + +### 支持特性 + +A-Tune支持的主要特性、特性成熟度以及使用建议请参见[表1](#table1919220557576)。 + +**表 1** 特性成熟度 + + + + + + + + + + + + + + + + + + + + +

特性

+

成熟度

+

使用建议

+

11大类15款应用负载类型自动优化

+

已测试

+

试用

+

自定义profile和业务模型

+

已测试

+

试用

+

参数自调优

+

已测试

+

试用

+
+ +### 支持业务模型 + +根据应用的负载特征,A-Tune将业务分为11大类,各类型的负载特征和A-Tune支持的应用请参见[表2](#table2819164611311)。 + +**表 2** 支持的业务类型和应用 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

业务大类

+
+

业务类型

+
+

瓶颈点

+
+

支持的应用

+
+

待规划的应用

+
+

default

+
+

默认类型

+
+

算力、内存、网络、IO各维度资源使用率都不高

+
+

N/A

+
+

 N/A

+
+

webserver

+
+

web应用

+
+

算力瓶颈、网络瓶颈

+
+

NginxApache Traffic Server

+
+

 N/A

+
+

database

+
+

数据库

+
+

算力瓶颈、内存瓶颈、IO瓶颈

+
+

MongodbMysqlPostgresqlMariadb

+
+

 N/A

+
+

big-data

+
+

大数据

+
+

算力瓶颈、内存瓶颈

+
+

N/A

+
+

Hadoop-hdfsHadoop-spark

+
+

middleware

+
+

中间件框架

+
+

算力瓶颈、网络瓶颈

+
+

Dubbo

+
+

 N/A

+
+

in-memory-database

+
+

内存数据库

+
+

内存瓶颈、IO瓶颈

+
+

Redis

+
+

 N/A

+
+

basic-test-suite

+
+

基础测试套

+
+

算力瓶颈、内存瓶颈

+
+

SPECCPU2006SPECjbb2015

+
+

 N/A

+
+

hpc

+
+

人类基因组

+
+

算力瓶颈、内存瓶颈、IO瓶颈

+
+

Gatk4

+
+

 N/A

+
+

storage

+
+

存储

+
+

网络瓶颈、IO瓶颈

+
+

N/A

+
+

Ceph

+
+

virtualization

+
+

虚拟化

+
+

算力瓶颈、内存瓶颈、IO瓶颈

+
+

Consumer-cloudMariadb

+
+

 N/A

+
+

docker

+
+

容器

+
+

算力瓶颈、内存瓶颈、IO瓶颈

+
+

Mariadb

+
+

 N/A

+
diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/installation-and-deployment.md b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/installation-and-deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..968c0b20320bf7378f6e5803796c9d2a68e2ba84 --- /dev/null +++ b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/installation-and-deployment.md @@ -0,0 +1,536 @@ +# 安装与部署 + +本章介绍如何安装和部署A-Tune。 + + + +- [安装与部署](#安装与部署) + - [软硬件要求](#软硬件要求) + - [硬件要求](#硬件要求) + - [软件要求](#软件要求) + - [环境准备](#环境准备) + - [安装A-Tune](#安装a-tune) + - [安装模式介绍](#安装模式介绍) + - [安装操作](#安装操作) + - [部署A-Tune](#部署a-tune) + - [配置介绍](#配置介绍) + - [配置示例](#配置示例) + - [配置示例](#配置示例-1) + - [启动A-Tune](#启动a-tune) + - [启动A-Tune engine](#启动a-tune-engine) + - [分部式部署](#分部式部署) + - [分部式部署目的](#分部式部署目的) + - [配置文件](#配置文件) + - [注意事项](#注意事项) + - [举例](#举例) + - [atuned.cnf](#atunedcnf) + - [engine.cnf](#enginecnf) + - [集群部署](#集群部署) + - [集群部署的目的](#集群部署的目的) + - [atuned.cnf配置文件修改](#atunedcnf配置文件修改) + - [注意事项](#注意事项-1) + - [举例](#举例-1) + - [atuned.cnf](#atunedcnf-1) + - [engine.cnf](#enginecnf-1) + + + +## 软硬件要求 + +### 硬件要求 + +- 鲲鹏920处理器 + +### 软件要求 + +- 操作系统:openEuler 21.03 + +## 环境准备 + +- 安装openEuler系统,安装方法参考 《[安装指南](../../../InstallationUpgrade/Installation/installation.md)》。 + +- 安装A-Tune需要使用root权限。 + +## 安装A-Tune + +本节介绍A-Tune的安装模式和安装方法。 + +### 安装模式介绍 + +A-Tune支持单机模式、分布式模式安装和集群模式安装: + +- 单机模式 + + client和server安装到同一台机器上。 + +- 分布式模式 + + client和server分别安装在不同的机器上。 + +- 集群模式 + + 由一台client机器和大于一台server机器组成。 + +三种安装模式的简单图示如下: + +![](./figures/zh-cn_image_0231122163.png) + +### 安装操作 + +安装A-Tune的操作步骤如下: + +1. 挂载openEuler的iso文件。 + + ```shell + # mount openEuler-22.03-LTS-everything-x86_64-dvd.iso /mnt + ``` + + 请安装everything的iso。 + +2. 配置本地yum源。 + + ```shell + # vim /etc/yum.repos.d/local.repo + ``` + + 配置内容如下所示: + + ```shell + [local] + name=local + baseurl=file:///mnt + gpgcheck=1 + enabled=1 + ``` + +3. 将RPM数字签名的GPG公钥导入系统。 + + ```shell + # rpm --import /mnt/RPM-GPG-KEY-openEuler + ``` + +4. 安装A-Tune服务端。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 本步骤会同时安装服务端和客户端软件包,对于单机部署模式,请跳过**步骤5**。 + + ```shell + # yum install atune -y + # yum install atune-engine -y + ``` + +5. 若为分布式部署,请安装A-Tune客户端。 + + ```shell + # yum install atune-client -y + ``` + +6. 验证是否安装成功。命令和回显如下表示安装成功。 + + ```shell + # rpm -qa | grep atune + atune-client-xxx + atune-db-xxx + atune-xxx + atune-engine-xxx + ``` + +## 部署A-Tune + +本节介绍A-Tune的配置部署。 + +### 配置介绍 + +A-Tune配置文件/etc/atuned/atuned.cnf的配置项说明如下: + +- A-Tune服务启动配置(可根据需要进行修改)。 + + - protocol:系统gRPC服务使用的协议,unix或tcp,unix为本地socket通信方式,tcp为socket监听端口方式。默认为unix。 + - address:系统gRPC服务的侦听地址,默认为unix socket,若为分布式部署,需修改为侦听的ip地址。 + - port:系统gRPC服务的侦听端口,范围为0\~65535未使用的端口。如果protocol配置是unix,则不需要配置。 + - connect:若为集群部署时,A-Tune所在节点的ip列表,ip地址以逗号分隔。 + - rest_host:系统rest service的侦听地址,默认为localhost。 + - rest_port:系统rest service的侦听端口,范围为0~65535未使用的端口,默认为8383。 + - engine_host:与系统atune engine service链接的地址。 + - engine_port:与系统atune engine service链接的端口。 + - sample_num:系统执行analysis流程时采集样本的数量,默认为20。 + - interval:系统执行analysis流程时采集样本的间隔时间,默认为5s。 + - grpc_tls:系统gRPC的SSL/TLS证书校验开关,默认不开启。开启grpc_tls后,atune-adm命令在使用前需要设置以下环境变量方可与服务端进行通讯: + - export ATUNE_TLS=yes + - export ATUNED_CACERT=\<客户端CA证书路径> + - export ATUNED_CLIENTCERT=\<客户端证书路径> + - export ATUNED_CLIENTKEY=\<客户端密钥路径> + - export ATUNED_SERVERCN=server + - tlsservercafile:gRPC服务端CA证书路径。 + - tlsservercertfile:gRPC服务端证书路径。 + - tlsserverkeyfile:gRPC服务端密钥路径。 + - rest_tls:系统rest service的SSL/TLS证书校验开关,默认开启。 + - tlsrestcacertfile:系统rest service的服务端CA证书路径。 + - tlsrestservercertfile:系统rest service的服务端证书路径 + - tlsrestserverkeyfile:系统rest service的服务端密钥路径。 + - engine_tls:系统atune engine service的SSL/TLS证书校验开关,默认开启。 + - tlsenginecacertfile:系统atune engine service的客户端CA证书路径。 + - tlsengineclientcertfile:系统atune engine service的客户端证书路径 + - tlsengineclientkeyfile:系统atune engine service的客户端密钥路径 + +- system信息 + + system为系统执行相关的优化需要用到的参数信息,必须根据系统实际情况进行修改。 + + - disk:执行analysis流程时需要采集的对应磁盘的信息或执行磁盘相关优化时需要指定的磁盘。 + - network:执行analysis时需要采集的对应的网卡的信息或执行网卡相关优化时需要指定的网卡。 + + - user:执行ulimit相关优化时用到的用户名。目前只支持root用户。 + +- 日志信息 + + 根据情况修改日志的级别,默认为info级别,日志信息打印在/var/log/messages中。 + +- monitor信息 + + 为系统启动时默认采集的系统硬件信息。 + +- tuning信息 + + tuning为系统进行离线调优时需要用到的参数信息。 + + - noise:高斯噪声的评估值。 + - sel_feature:控制离线调优参数重要性排名输出的开关,默认关闭。 + +### 配置示例 + +```shell +#################################### server ############################### + # atuned config + [server] + # the protocol grpc server running on + # ranges: unix or tcp + protocol = unix + + # the address that the grpc server to bind to + # default is unix socket /var/run/atuned/atuned.sock + # ranges: /var/run/atuned/atuned.sock or ip address + address = /var/run/atuned/atuned.sock + + # the atune nodes in cluster mode, separated by commas + # it is valid when protocol is tcp + # connect = ip01,ip02,ip03 + + # the atuned grpc listening port + # the port can be set between 0 to 65535 which not be used + # port = 60001 + + # the rest service listening port, default is 8383 + # the port can be set between 0 to 65535 which not be used + rest_host = localhost + rest_port = 8383 + + # the tuning optimizer host and port, start by engine.service + # if engine_host is same as rest_host, two ports cannot be same + # the port can be set between 0 to 65535 which not be used + engine_host = localhost + engine_port = 3838 + + # when run analysis command, the numbers of collected data. + # default is 20 + sample_num = 20 + + # interval for collecting data, default is 5s + interval = 5 + + # enable gRPC authentication SSL/TLS + # default is false + # grpc_tls = false + # tlsservercafile = /etc/atuned/grpc_certs/ca.crt + # tlsservercertfile = /etc/atuned/grpc_certs/server.crt + # tlsserverkeyfile = /etc/atuned/grpc_certs/server.key + + # enable rest server authentication SSL/TLS + # default is true + rest_tls = true + tlsrestcacertfile = /etc/atuned/rest_certs/ca.crt + tlsrestservercertfile = /etc/atuned/rest_certs/server.crt + tlsrestserverkeyfile = /etc/atuned/rest_certs/server.key + + # enable engine server authentication SSL/TLS + # default is true + engine_tls = true + tlsenginecacertfile = /etc/atuned/engine_certs/ca.crt + tlsengineclientcertfile = /etc/atuned/engine_certs/client.crt + tlsengineclientkeyfile = /etc/atuned/engine_certs/client.key + + + #################################### log ############################### + [log] + # either "debug", "info", "warn", "error", "critical", default is "info" + level = info + + #################################### monitor ############################### + [monitor] + # with the module and format of the MPI, the format is {module}_{purpose} + # the module is Either "mem", "net", "cpu", "storage" + # the purpose is "topo" + module = mem_topo, cpu_topo + + #################################### system ############################### + # you can add arbitrary key-value here, just like key = value + # you can use the key in the profile + [system] + # the disk to be analysis + disk = sda + + # the network to be analysis + network = enp189s0f0 + + user = root + + #################################### tuning ############################### + # tuning configs + [tuning] + noise = 0.000000001 + sel_feature = false +``` + +A-Tune engine配置文件/etc/atuned/engine.cnf的配置项说明如下: + +- A-Tune engine服务启动配置(可根据需要进行修改)。 + - engine_host:系统atune engine service的侦听地址,默认为localhost。 + - engine_port:系统atune engine service的侦听端口,范围为0~65535未使用的端口,默认为3838。 + - engine_tls:系统atune engine service的SSL/TLS证书校验开关,默认开启。 + - tlsenginecacertfile:系统atune engine service的服务端CA证书路径。 + - tlsengineservercertfile:系统atune engine service的服务端证书路径 + - tlsengineserverkeyfile:系统atune engine service的服务端密钥路径。 + +- 日志信息 + + 根据情况修改日志的级别,默认为info级别,日志信息打印在/var/log/messages中。 + +### 配置示例 + +```shell + #################################### engine ############################### + [server] + # the tuning optimizer host and port, start by engine.service + # if engine_host is same as rest_host, two ports cannot be same + # the port can be set between 0 to 65535 which not be used + engine_host = localhost + engine_port = 3838 + + # enable engine server authentication SSL/TLS + # default is true + engine_tls = true + tlsenginecacertfile = /etc/atuned/engine_certs/ca.crt + tlsengineservercertfile = /etc/atuned/engine_certs/server.crt + tlsengineserverkeyfile = /etc/atuned/engine_certs/server.key + + #################################### log ############################### + [log] + # either "debug", "info", "warn", "error", "critical", default is "info" + level = info +``` + +## 启动A-Tune + +A-Tune安装完成后,需要配置A-Tune服务,然后启动A-Tune服务。 + +- 配置A-Tune服务: + 修改atuned.cnf配置文件中网卡和磁盘的信息 + > 说明: + > + > 如果通过'make install'安装了atuned服务,网卡和磁盘已经自动更新为当前机器中的默认设备。如果需要从其他设备收集数据,请按照以下步骤配置 atuned 服务。 + + 通过以下命令可以查找当前需要采集或者执行网卡相关优化时需要指定的网卡,并修改/etc/atuned/atuned.cnf中的network配置选项为对应的指定网卡。 + + ```shell + ip addr + ``` + + 通过以下命令可以查找当前需要采集或者执行磁盘相关优化时需要指定的磁盘,并修改/etc/atuned/atuned.cnf中的disk配置选项为对应的指定磁盘。 + + ```shell + fdisk -l | grep dev + ``` + +- 关于证书: + 因为A-Tune的引擎和客户端使用了grpc通信协议,所以为了系统安全,需要配置证书。因为信息安全的原因,A-Tune不会提供证书生成方法,请用户自行配置系统证书。 + 如果不考虑安全问题,可以将/etc/atuned/atuned.cnf中的rest_tls 和 engine_tls配置选项设置为false,并且将/etc/atuned/engine.cnf中的engine_tls配置选项设为false。 + 如果不配置安全证书导致的一切后果与A-Tune无关。 + +- 启动atuned服务: + + ```shell + # systemctl start atuned + ``` + +- 查询atuned服务状态: + + ```shell + # systemctl status atuned + ``` + + 若回显为如下,则服务启动成功。 + + ![](./figures/zh-cn_image_0214540398.png) + +## 启动A-Tune engine + +若需要使用AI相关的功能,需要启动A-Tune engine服务才能使用。 + +- 启动atune-engine服务: + + ```shell + # systemctl start atune-engine + ``` + +- 查询atune-engine服务状态: + + ```shell + # systemctl status atune-engine + ``` + + 若回显为如下,则服务启动成功。 + + ![](./figures/zh-cn_image_0245342444.png) + +## 分部式部署 + +### 分部式部署目的 + +为了实现分布式架构和按需部署的目标,A-Tune支持分部式部署。可以将三个组件分开部署,轻量化组件部署对业务影响小,也避免安装过多依赖软件,减轻系统负担。
+ +部署方式:本文档只介绍常用的一种部署方式:在同一节点部署客户端和服务端,在另一个节点上部署引擎模块。其他的部署方式请咨询A-Tune开发人员。 + +**部署关系图:**
+![输入图片说明](figures/picture1.png) + +### 配置文件 + +分部式部署需要修改配置文件,将引擎的ip地址和端口号写入配置文件中,别的组件才能访问该ip地址上的引擎组件。 + +1. 修改服务端节点上的`/etc/atuned/atuned.cnf`文件: + - 34行的`engine_host`和`engine_port`修改为引擎节点的ip地址和端口号。如上图,应该修改为`engine_host = 192.168.0.1 engine_port = 3838`。 + - 将49行和55行的 rest_tls 和engine_tls 改为false,否则需要申请和配置证书。在测试环境中可以不用配置ssl证书,但是正式的现网环境需要配置证书,否则会有安全隐患。 +2. 修改引擎节点/etc/atuned/engine.cnf文件: + - 17行和18行的`engine_host`和`engine_port`修改为引擎节点的ip地址和端口号。如上图,应该修改为`engine_host = 192.168.0.1 engine_port = 3838`。 + - 第22行的engine_tls的值改成false。 +3. 修改完配置文件后需要重启服务,配置才会生效: + - 服务端节点输入命令:`systemctl restart atuned`。 + - 引擎端节点输入命令:`systemctl restart atune-engine`。 +4. (可选步骤)在`A-Tune/examples/tuning/compress`文件夹下运行tuning命令: + - 请先参考`A-Tune/examples/tuning/compress/README`的指导进行预处理。 + - 执行`atune-adm tuning --project compress --detail compress_client.yaml`。 + - 本步骤的目的是检验分部式部署是否成功。 + +### 注意事项 + +1. 本文档不对认证证书配置方法作详细说明,如有需要也可以将atuned.cnf和engine.cnf中的rest_tls/engine_tls设成false。 +2. 修改完配置文件后需要重启服务,否则修改不会生效。 +3. 注意使用atune服务时不要同时打开代理。 +4. atuned.cnf 文件中的[system]模块的disk和network项需要修改,修改方法见[A-Tune用户指南2.4.1章节](https://gitee.com/gaoruoshu/A-Tune/blob/master/Documentation/UserGuide/A-Tune%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97.md),本文不展开描述。 + +### 举例 + +#### atuned.cnf + +```bash +# ...前略... + +# the tuning optimizer host and port, start by engine.service +# if engine_host is same as rest_host, two ports cannot be same +# the port can be set between 0 to 65535 which not be used +engine_host = 192.168.0.1 +engine_port = 3838 + +# ...后略... +``` + +#### engine.cnf + +```bash +[server] +# the tuning optimizer host and port, start by engine.service +# if engine_host is same as rest_host, two ports cannot be same +# the port can be set between 0 to 65535 which not be used +engine_host = 192.168.0.1 +engine_port = 3838 +``` + +## 集群部署 + +### 集群部署的目的 + +为了支持多节点场景快速调优,A-Tune支持对多个节点里的参数配置同时进行动态调优,避免用户单独多次对每个节点进行调优,从而提升调优效率。
+集群部署的方式:分为一个主节点和若干个从节点。在主节点部署客户端和服务端,负责接受命令和引擎交互。其他节点接受主节点的指令,对当前节点的参数进行配置。 + +**部署关系图:**
+ ![输入图片说明](figures/picture4.png) + +上图中客户端和服务端部署在ip为192.168.0.0的节点上,项目文件存放在该节点上,其他节点不用放置项目文件。
+主节点和从节点之间通过tcp协议通信,所以需要修改配置文件。 + +### atuned.cnf配置文件修改 + +1. protocol 值设置为tcp。 +2. address设置为当前节点的ip地址。 +3. connect设置为所有节点的ip地址,第一个为主节点,其余为从节点ip,中间用逗号隔开。 +4. 在调试时,可以设置rest_tls 和engine_tls 为false。 +5. 所有的主从节点的atuned.cnf都按照上方描述修改。 + +### 注意事项 + +1. 将engine.cnf中的`engine_host`和`engine_port`设置为服务端atuned.cnf中`engine_host`和`engine_port`一样的ip和端口号。 +2. 本文档不对认证证书配置方法作详细说明,如有需要也可以将atuned.cnf和engine.cnf中的rest_tls和engine_tls设置为false。 +3. 修改完配置文件后需要重启服务,否则修改不会生效。 +4. 注意使用atune服务时不要同时打开代理。 + +### 举例 + +#### atuned.cnf + +```bash +# ...前略... + +[server] +# the protocol grpc server running on +# ranges: unix or tcp +protocol = tcp + +# the address that the grpc server to bind to +# default is unix socket /var/run/atuned/atuned.sock +# ranges: /var/run/atuned/atuned.sock or ip address +address = 192.168.0.0 + +# the atune nodes in cluster mode, separated by commas +# it is valid when protocol is tcp +connect = 192.168.0.0,192.168.0.1,192.168.0.2,192.168.0.3 + +# the atuned grpc listening port +# the port can be set between 0 to 65535 which not be used +port = 60001 + +# the rest service listening port, default is 8383 +# the port can be set between 0 to 65535 which not be used +rest_host = localhost +rest_port = 8383 + +# the tuning optimizer host and port, start by engine.service +# if engine_host is same as rest_host, two ports cannot be same +# the port can be set between 0 to 65535 which not be used +engine_host = 192.168.1.1 +engine_port = 3838 + +# ...后略... +``` + +#### engine.cnf + +```bash +[server] +# the tuning optimizer host and port, start by engine.service +# if engine_host is same as rest_host, two ports cannot be same +# the port can be set between 0 to 65535 which not be used +engine_host = 192.168.1.1 +engine_port = 3838 +``` + +**备注:** engine.cnf参考分部式部署的配置文件。 diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/native-turbo.md b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/native-turbo.md new file mode 100644 index 0000000000000000000000000000000000000000..81cede9a4b7f6545466ddeda45e2fed2eee52f71 --- /dev/null +++ b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/native-turbo.md @@ -0,0 +1,54 @@ +# native-turbo特性 + +## 简介 + +大型程序的代码段、数据段可达数百MB,关键业务流程TLB miss较高。内核页表大小对性能有影响。 + +为了方便用户使用大页,native-turbo特性实现了加载程序时自动使用大页的功能,可以针对代码段、数据段使用大页。 + +## 使用方法 + +1. 打开特性开关 + + 该特性有两级开关,sysctl fs.exec-use-hugetlb用于控制本系统是否打开该特性(由root用户控制,0不打开,1打开,其他值非法)。 + + 如果不打开该开关,即使用户设置了环境变量也不会使用该特性,内核会忽略相关流程。 + + 系统打开该特性后,普通用户可以通过环境变量HUGEPAGE_PROBE自行决定运行的程序是否需要使用大页(1使用,不设置或其他值不使用)。 + + ```shell + sysctl fs.exec-use-hugetlb=1 #主程序使用大页 + export HUGEPAGE_PROBE=1 #动态库使用大页 + ``` + + 动态库大页也可以使用LD_HUGEPAGE_LIB=1环境变量强制所有段使用大页。 + +2. 标记需要使用大页的段,默认标记所有段,-x表示仅代码段,-d清除已有标记。 + + ```shell + hugepageedit [-x] [-d] app + ``` + + 该工具由glibc-devel包提供。 + +3. 启动程序 + + ./app + +## 约束限制 + +1. 程序与动态库必须按照2M对齐编译,可通过添加如下gcc编译参数实现: + + ```shell + -zcommon-page-size=0x200000 -zmax-page-size=0x200000 + ``` + +2. 使用前需要预留足够的大页,否则程序会执行失败。 + + 如果使用cgroup,请注意hugetlb的限制,如果限制小于所需大页数量,可能导致运行时崩溃。 + +3. 由于进程页表改为2M,mprotect等系统调用的参数需要按2M对齐,否则会执行失败。 + +4. 不支持libcareplus热补丁机制。 + +5. 多个进程间无法共享大页,会消耗多倍内存。 diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-caution.gif b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-caution.gif differ diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-danger.gif b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-danger.gif differ diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-note.gif b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-notice.gif b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-notice.gif differ diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-tip.gif b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-tip.gif differ diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-warning.gif b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/public_sys-resources/icon-warning.gif differ diff --git a/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/usage-instructions.md b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/usage-instructions.md new file mode 100644 index 0000000000000000000000000000000000000000..ff9602b004e2b5c4458b5178ab131829c6e934df --- /dev/null +++ b/docs/en/25.03/Server/Performance/SystemOptimization/A-Tune/usage-instructions.md @@ -0,0 +1,730 @@ +# 使用方法 + +用户可以通过命令行客户端atune-adm使用A-Tune提供的功能。本章介绍A-Tune客户端包含的功能和使用方法。 + +## 总体说明 + +- 使用A-Tune需要使用root权限。 +- atune-adm支持的命令可以通过 **atune-adm help/--help/-h** 查询。 +- define、update、undefine、collection、train、upgrade不支持远程执行。 +- 命令格式中,\[ \] 表示参数可选,<\> 表示参数必选,具体参数由实际情况确定。 + +## 查询负载类型 + +### list + +### 功能描述 + +查询系统当前支持的profile,以及当前处于active状态的profile。 + +### 命令格式 + +**atune-adm list** + +### 使用示例 + +```sh +# atune-adm list + +Support profiles: ++------------------------------------------------+-----------+ +| ProfileName | Active | ++================================================+===========+ +| arm-native-android-container-robox | false | ++------------------------------------------------+-----------+ +| basic-test-suite-euleros-baseline-fio | false | ++------------------------------------------------+-----------+ +| basic-test-suite-euleros-baseline-lmbench | false | ++------------------------------------------------+-----------+ +| basic-test-suite-euleros-baseline-netperf | false | ++------------------------------------------------+-----------+ +| basic-test-suite-euleros-baseline-stream | false | ++------------------------------------------------+-----------+ +| basic-test-suite-euleros-baseline-unixbench | false | ++------------------------------------------------+-----------+ +| basic-test-suite-speccpu-speccpu2006 | false | ++------------------------------------------------+-----------+ +| basic-test-suite-specjbb-specjbb2015 | false | ++------------------------------------------------+-----------+ +| big-data-hadoop-hdfs-dfsio-hdd | false | ++------------------------------------------------+-----------+ +| big-data-hadoop-hdfs-dfsio-ssd | false | ++------------------------------------------------+-----------+ +| big-data-hadoop-spark-bayesian | false | ++------------------------------------------------+-----------+ +| big-data-hadoop-spark-kmeans | false | ++------------------------------------------------+-----------+ +| big-data-hadoop-spark-sql1 | false | ++------------------------------------------------+-----------+ +| big-data-hadoop-spark-sql10 | false | ++------------------------------------------------+-----------+ +| big-data-hadoop-spark-sql2 | false | ++------------------------------------------------+-----------+ +| big-data-hadoop-spark-sql3 | false | ++------------------------------------------------+-----------+ +| big-data-hadoop-spark-sql4 | false | ++------------------------------------------------+-----------+ +| big-data-hadoop-spark-sql5 | false | ++------------------------------------------------+-----------+ +| big-data-hadoop-spark-sql6 | false | ++------------------------------------------------+-----------+ +| big-data-hadoop-spark-sql7 | false | ++------------------------------------------------+-----------+ +| big-data-hadoop-spark-sql8 | false | ++------------------------------------------------+-----------+ +| big-data-hadoop-spark-sql9 | false | ++------------------------------------------------+-----------+ +| big-data-hadoop-spark-tersort | false | ++------------------------------------------------+-----------+ +| big-data-hadoop-spark-wordcount | false | ++------------------------------------------------+-----------+ +| cloud-compute-kvm-host | false | ++------------------------------------------------+-----------+ +| database-mariadb-2p-tpcc-c3 | false | ++------------------------------------------------+-----------+ +| database-mariadb-4p-tpcc-c3 | false | ++------------------------------------------------+-----------+ +| database-mongodb-2p-sysbench | false | ++------------------------------------------------+-----------+ +| database-mysql-2p-sysbench-hdd | false | ++------------------------------------------------+-----------+ +| database-mysql-2p-sysbench-ssd | false | ++------------------------------------------------+-----------+ +| database-postgresql-2p-sysbench-hdd | false | ++------------------------------------------------+-----------+ +| database-postgresql-2p-sysbench-ssd | false | ++------------------------------------------------+-----------+ +| default-default | false | ++------------------------------------------------+-----------+ +| docker-mariadb-2p-tpcc-c3 | false | ++------------------------------------------------+-----------+ +| docker-mariadb-4p-tpcc-c3 | false | ++------------------------------------------------+-----------+ +| hpc-gatk4-human-genome | false | ++------------------------------------------------+-----------+ +| in-memory-database-redis-redis-benchmark | false | ++------------------------------------------------+-----------+ +| middleware-dubbo-dubbo-benchmark | false | ++------------------------------------------------+-----------+ +| storage-ceph-vdbench-hdd | false | ++------------------------------------------------+-----------+ +| storage-ceph-vdbench-ssd | false | ++------------------------------------------------+-----------+ +| virtualization-consumer-cloud-olc | false | ++------------------------------------------------+-----------+ +| virtualization-mariadb-2p-tpcc-c3 | false | ++------------------------------------------------+-----------+ +| virtualization-mariadb-4p-tpcc-c3 | false | ++------------------------------------------------+-----------+ +| web-apache-traffic-server-spirent-pingpo | false | ++------------------------------------------------+-----------+ +| web-nginx-http-long-connection | true | ++------------------------------------------------+-----------+ +| web-nginx-https-short-connection | false | ++------------------------------------------------+-----------+ + +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> Active为true表示当前激活的profile,示例表示当前激活的profile是web-nginx-http-long-connection。 + +## 分析负载类型并自优化 + +### analysis + +### 功能描述 + +采集系统的实时统计数据进行负载类型识别,并进行自动优化。 + +### 命令格式 + +**atune-adm analysis** \[OPTIONS\] + +### 参数说明 + +- OPTIONS + +| 参数
| 描述
| +|----------------------------------|-------------------------------| +| --model, -m
| 用户自训练产生的新模型
| +| --characterization, -c
| 使用默认的模型进行应用识别,不进行自动优化
| +| --times value, -t value
| 指定收集数据的时长
| +| --script value, -s value
| 指定需要运行的文件
| + +### 使用示例 + +- 使用默认的模型进行应用识别 + + ```sh + # atune-adm analysis --characterization + ``` + +- 使用默认的模型进行应用识别,并进行自动优化 + + ```sh + # atune-adm analysis + ``` + +- 使用自训练的模型进行应用识别 + + ```sh + # atune-adm analysis --model /usr/libexec/atuned/analysis/models/new-model.m + ``` + +## 自定义模型 + +A-Tune支持用户定义并学习新模型。定义新模型的操作流程如下: + +1. 用define命令定义一个新应用的profile +2. 用collection命令收集应用对应的系统数据 +3. 用train命令训练得到模型 + +### define + +### 功能描述 + +添加用户自定义的应用场景,及对应的profile优化项。 + +### 命令格式 + +`atune-adm define ` + +### 使用示例 + +新增一个profile,service_type的名称为test_service,application_name的名称为test_app,scenario_name的名称为test_scenario,优化项的配置文件为example.conf。 + +```sh +# atune-adm define test_service test_app test_scenario ./example.conf +``` + +example.conf 可以参考如下方式书写(以下各优化项非必填,仅供参考),也可通过**atune-adm info**查看已有的profile是如何书写的。 + +```Conf + [main] + # list its parent profile + [kernel_config] + # to change the kernel config + [bios] + # to change the bios config + [bootloader.grub2] + # to change the grub2 config + [sysfs] + # to change the /sys/* config + [systemctl] + # to change the system service status + [sysctl] + # to change the /proc/sys/* config + [script] + # the script extension of cpi + [ulimit] + # to change the resources limit of user + [schedule_policy] + # to change the schedule policy + [check] + # check the environment + [tip] + # the recommended optimization, which should be performed manunaly +``` + +### collection + +### 功能描述 + +采集业务运行时系统的全局资源使用情况以及OS的各项状态信息,并将收集的结果保存到csv格式的输出文件中,作为模型训练的输入数据集。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 本命令依赖采样工具perf,mpstat,vmstat,iostat,sar。 +> CPU型号目前仅支持鲲鹏920,可通过dmidecode -t processor检查CPU型号。 + +### 命令格式 + +**atune-adm collection** + +### 参数说明 + +- OPTIONS + +| 参数
| 描述
| +|---------------------------|--------------------------------------| +| --filename, -f
| 生成的用于训练的csv文件名:名称-时间戳.csv
| +| --output_path, -o
| 生成的csv文件的存放路径,需提供绝对路径
| +| --disk, -b
| 业务运行时实际使用的磁盘,如/dev/sda
| +| --network, -n
| 业务运行时使用的网络接口,如eth0
| +| --app_type, -t
| 标记业务的应用类型,作为训练时使用的标签
| +| --duration, -d
| 业务运行时采集数据的时间,单位秒,默认采集时间1200秒
| +| --interval,-i
| 采集数据的时间间隔,单位秒,默认采集间隔5秒
| + +### 使用示例 + +```sh +# atune-adm collection --filename name --interval 5 --duration 1200 --output_path /home/data --disk sda --network eth0 --app_type test_service-test_app-test_scenario +``` + +> 说明: +> +> 实例中定义了每隔5秒收集一次数据,一共收集1200秒;采集后的数据存放在/home/data目录下名称为name的文件中,业务的应用类型是通过atune-adm define指定的业务类型,这里为test_service-test_app-test_scenario +> 采集间隔和采集时间都可以通过上述选项指定时长。 +> +### train + +### 功能描述 + +使用采集的数据进行模型的训练。训练时至少采集两种应用类型的数据,否则训练会出错。 + +### 命令格式 + +**atune-adm train** + +### 参数说明 + +- OPTIONS + +| 参数
| 描述
| +|---------------------------|---------------------------| +| --data_path, -d
| 存放模型训练所需的csv文件的目录
| +| --output_file, -o
| 训练生成的新模型
| + +### 使用示例 + +使用data目录下的csv文件作为训练输入,生成的新模型new-model.m存放在model目录下。 + +```shell +# atune-adm train --data_path /home/data --output_file /usr/libexec/atuned/analysis/models/new-model.m +``` + +### undefine + +### 功能描述 + +删除用户自定义的profile。 + +### 命令格式 + +**atune-adm undefine** + +### 使用示例 + +删除自定义的profile。 + +```shell +# atune-adm undefine test_service-test_app-test_scenario +``` + +## 查询profile + +### info + +### 功能描述 + +查看对应的profile内容。 + +### 命令格式 + +**atune-adm info** + +### 使用示例 + +查看web-nginx-http-long-connection的profile内容: + +```shell +# atune-adm info web-nginx-http-long-connection + +*** web-nginx-http-long-connection: + +# +# nginx http long connection A-Tune configuration +# +[main] +include = default-default + +[kernel_config] +#TODO CONFIG + +[bios] +#TODO CONFIG + +[bootloader.grub2] +iommu.passthrough = 1 + +[sysfs] +#TODO CONFIG + +[systemctl] +sysmonitor = stop +irqbalance = stop + +[sysctl] +fs.file-max = 6553600 +fs.suid_dumpable = 1 +fs.aio-max-nr = 1048576 +kernel.shmmax = 68719476736 +kernel.shmall = 4294967296 +kernel.shmmni = 4096 +kernel.sem = 250 32000 100 128 +net.ipv4.tcp_tw_reuse = 1 +net.ipv4.tcp_syncookies = 1 +net.ipv4.ip_local_port_range = 1024 65500 +net.ipv4.tcp_max_tw_buckets = 5000 +net.core.somaxconn = 65535 +net.core.netdev_max_backlog = 262144 +net.ipv4.tcp_max_orphans = 262144 +net.ipv4.tcp_max_syn_backlog = 262144 +net.ipv4.tcp_timestamps = 0 +net.ipv4.tcp_synack_retries = 1 +net.ipv4.tcp_syn_retries = 1 +net.ipv4.tcp_fin_timeout = 1 +net.ipv4.tcp_keepalive_time = 60 +net.ipv4.tcp_mem = 362619 483495 725238 +net.ipv4.tcp_rmem = 4096 87380 6291456 +net.ipv4.tcp_wmem = 4096 16384 4194304 +net.core.wmem_default = 8388608 +net.core.rmem_default = 8388608 +net.core.rmem_max = 16777216 +net.core.wmem_max = 16777216 + +[script] +prefetch = off +ethtool = -X {network} hfunc toeplitz + +[ulimit] +{user}.hard.nofile = 102400 +{user}.soft.nofile = 102400 + +[schedule_policy] +#TODO CONFIG + +[check] +#TODO CONFIG + +[tip] +SELinux provides extra control and security features to linux kernel. Disabling SELinux will improve the performance but may cause security risks. = kernel +disable the nginx log = application +``` + +## 更新profile + +用户根据需要更新已有profile。 + +### update + +### 功能描述 + +将已有profile中原来的优化项更新为new.conf中的内容。 + +### 命令格式 + +**atune-adm update** + +### 使用示例 + +更新名为test_service-test_app-test_scenario的profile优化项为new.conf。 + +```shell +# atune-adm update test_service-test_app-test_scenario ./new.conf +``` + +## 激活profile + +### profile + +### 功能描述 + +手动激活profile,使其处于active状态。 + +### 命令格式 + +**atune-adm profile** + +### 参数说明 + +profile名参考list命令查询结果。 + +### 使用示例 + +激活web-nginx-http-long-connection对应的profile配置。 + +```sh +# atune-adm profile web-nginx-http-long-connection +``` + +## 回滚profile + +### rollback + +### 功能描述 + +回退当前的配置到系统的初始配置。 + +### 命令格式 + +**atune-adm rollback** + +### 使用示例 + +```sh +# atune-adm rollback +``` + +## 更新数据库 + +### upgrade + +### 功能描述 + +更新系统的数据库。 + +### 命令格式 + +**atune-adm upgrade** + +### 参数说明 + +- DB\_FILE + + 新的数据库文件路径 + +### 使用示例 + +数据库更新为new\_sqlite.db。 + +```sh +# atune-adm upgrade ./new_sqlite.db +``` + +## 系统信息查询 + +### check + +### 功能描述 + +检查系统当前的cpu、bios、os、网卡等信息。 + +### 命令格式 + +**atune-adm check** + +### 使用示例 + +```sh +# atune-adm check + cpu information: + cpu:0 version: Kunpeng 920-6426 speed: 2600000000 HZ cores: 64 + cpu:1 version: Kunpeng 920-6426 speed: 2600000000 HZ cores: 64 + system information: + DMIBIOSVersion: 0.59 + OSRelease: 4.19.36-vhulk1906.3.0.h356.eulerosv2r8.aarch64 + network information: + name: eth0 product: HNS GE/10GE/25GE RDMA Network Controller + name: eth1 product: HNS GE/10GE/25GE Network Controller + name: eth2 product: HNS GE/10GE/25GE RDMA Network Controller + name: eth3 product: HNS GE/10GE/25GE Network Controller + name: eth4 product: HNS GE/10GE/25GE RDMA Network Controller + name: eth5 product: HNS GE/10GE/25GE Network Controller + name: eth6 product: HNS GE/10GE/25GE RDMA Network Controller + name: eth7 product: HNS GE/10GE/25GE Network Controller + name: docker0 product: +``` + +## 参数自调优 + +A-Tune提供了最佳配置的自动搜索能力,免去人工反复做参数调整、性能评价的调优过程,极大地提升最优配置的搜寻效率。 + +### tuning + +### 功能描述 + +使用指定的项目文件对参数进行动态空间的搜索,找到当前环境配置下的最优解。 + +### 命令格式 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 在运行命令前,需要满足如下条件: +>(1)服务端的yaml配置文件已经编辑完成并放置于atuned服务下的**/etc/atuned/tuning/**目录中。 +>(2)客户端的yaml配置文件已经编辑完成并放置于atuned客户端任意目录下。 + +**atune-adm tuning** \[OPTIONS\] + +### 参数说明 + +- OPTIONS + +| 参数
| 描述
| +|-----------------------|-----------------------------| +| --restore, -r
| 恢复tuning优化前的初始配置
| +| --project, -p
| 指定需要恢复的yaml文件中的项目名称
| +| --restart, -c
| 基于历史调优结果进行调优
| +| --detail, -d
| 打印tuning过程的详细信息
| + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 当使用参数时,-p参数后需要跟具体的项目名称且必须指定该项目yaml文件。 + +- PROJECT\_YAML:客户端yaml配置文件。 + +### 配置说明 + +**表 1** 服务端yaml文件 + +| 配置名称
| 配置说明
| 参数类型
| 取值范围
| +|-------------------|---------------------------------------------------------------------------|----------|------------| +| project
| 项目名称。
| 字符串
| -
| +| startworkload
| 待调优服务的启动脚本。
| 字符串
| -
| +| stopworkload
| 待调优服务的停止脚本。
| 字符串
| -
| +| maxiterations
| 最大调优迭代次数,用于限制客户端的迭代次数。一般来说,调优迭代次数越多,优化效果越好,但所需时间越长。用户必须根据实际的业务场景进行配置。
| 整型
| >10
| +| object
| 需要调节的参数项及信息。
object 配置项请参见表2。
| -
| -
| + +**表 2** object项配置说明 + +| 配置名称
| 配置说明
| 参数类型
| 取值范围
| +|-----------------|-----------------------------------------------------------------|------------|------------------------------| +| name
| 待调参数名称
| 字符串
| -
| +| desc
| 待调参数描述
| 字符串
| -
| +| get
| 查询参数值的脚本
| -
| -
| +| set
| 设置参数值的脚本
| -
| -
| +| needrestart
| 参数生效是否需要重启业务
| 枚举
| "true", "false"
| +| type
| 参数的类型,目前支持discrete, continuous两种类型,对应离散型、连续型参数
| 枚举
| "discrete", "continuous"
| +| dtype
| 该参数仅在type为discrete类型时配置,目前支持int, float, string类型
| 枚举
| int, float, string
| +| scope
| 参数设置范围,仅在type为discrete且dtype为int或float时或者type为continuous时生效
| 整型/浮点型
| 用户自定义,取值在该参数的合法范围
| +| step
| 参数值步长,dtype为int或float时使用
| 整型/浮点型
| 用户自定义
| +| items
| 参数值在scope定义范围之外的枚举值,dtype为int或float时使用
| 整型/浮点型
| 用户自定义,取值在该参数的合法范围
| +| options
| 参数值的枚举范围,dtype为string时使用
| 字符串
| 用户自定义,取值在该参数的合法范围
| + +**表 3** 客户端yaml文件配置说明 + +| 配置名称
| 配置说明
| 参数类型
| 取值范围
| +|---------------------------|--------------------------------------------------------------|----------|-------------------------------------------------------| +| project
| 项目名称,需要与服务端对应配置文件中的project匹配
| 字符串
| -
| +| engine
| 调优算法
| 字符串
| "random", "forest", "gbrt", "bayes", "extraTrees"
| +| iterations
| 调优迭代次数
| 整型
| >=10
| +| random_starts
| 随机迭代次数
| 整型
| <iterations
| +| feature_filter_engine
| 参数搜索算法,用于重要参数选择,该参数可选
| 字符串
| "lhs"
| +| feature_filter_cycle
| 参数搜索轮数,用于重要参数选择,该参数配合feature_filter_engine使用
| 整型
| -
| +| feature_filter_iters
| 每轮参数搜索的迭代次数,用于重要参数选择,该参数配合feature_filter_engine使用
| 整型
| -
| +| split_count
| 调优参数取值范围中均匀选取的参数个数,用于重要参数选择,该参数配合feature_filter_engine使用
| 整型
| -
| +| benchmark
| 性能测试脚本
| -
| -
| +| evaluations
| 性能测试评估指标
evaluations 配置项请参见表4
| -
| -
| + +**表 4** evaluations项配置说明 + +| 配置名称
| 配置说明
| 参数类型
| 取值范围
| +|---------------|---------------------------------------------------|----------|---------------------------| +| name
| 评价指标名称
| 字符串
| -
| +| get
| 获取性能评估结果的脚本
| -
| -
| +| type
| 评估结果的正负类型,positive代表最小化性能值,negative代表最大化对应性能值
| 枚举
| "positive","negative"
| +| weight
| 该指标的权重百分比,0-100
| 整型
| 0-100
| +| threshold
| 该指标的最低性能要求
| 整型
| 用户指定
| + +### 配置示例 + +服务端yaml文件配置示例: + +```Conf +project: "compress" +maxiterations: 500 +startworkload: "" +stopworkload: "" +object : + - + name : "compressLevel" + info : + desc : "The compresslevel parameter is an integer from 1 to 9 controlling the level of compression" + get : "cat /root/A-Tune/examples/tuning/compress/compress.py | grep 'compressLevel=' | awk -F '=' '{print $2}'" + set : "sed -i 's/compressLevel=\\s*[0-9]*/compressLevel=$value/g' /root/A-Tune/examples/tuning/compress/compress.py" + needrestart : "false" + type : "continuous" + scope : + - 1 + - 9 + dtype : "int" + - + name : "compressMethod" + info : + desc : "The compressMethod parameter is a string controlling the compression method" + get : "cat /root/A-Tune/examples/tuning/compress/compress.py | grep 'compressMethod=' | awk -F '=' '{print $2}' | sed 's/\"//g'" + set : "sed -i 's/compressMethod=\\s*[0-9,a-z,\"]*/compressMethod=\"$value\"/g' /root/A-Tune/examples/tuning/compress/compress.py" + needrestart : "false" + type : "discrete" + options : + - "bz2" + - "zlib" + - "gzip" + dtype : "string" +``` + +客户端yaml文件配置示例: + +```yaml +project: "compress" +engine : "gbrt" +iterations : 20 +random_starts : 10 + +benchmark : "python3 /root/A-Tune/examples/tuning/compress/compress.py" +evaluations : + - + name: "time" + info: + get: "echo '$out' | grep 'time' | awk '{print $3}'" + type: "positive" + weight: 20 + - + name: "compress_ratio" + info: + get: "echo '$out' | grep 'compress_ratio' | awk '{print $3}'" + type: "negative" + weight: 80 +``` + +### 使用示例 + +- 下载测试数据 + + ```sh + wget http://cs.fit.edu/~mmahoney/compression/enwik8.zip + ``` + +- 准备调优环境 + prepare.sh文件示例: + + ```sh + #!/usr/bin/bash + if [ "$#" -ne 1 ]; then + echo "USAGE: $0 the path of enwik8.zip" + exit 1 + fi + + path=$( + cd "$(dirname "$0")" + pwd + ) + + echo "unzip enwik8.zip" + unzip "$path"/enwik8.zip + + echo "set FILE_PATH to the path of enwik8 in compress.py" + sed -i "s#compress/enwik8#$path/enwik8#g" "$path"/compress.py + + echo "update the client and server yaml files" + sed -i "s#python3 .*compress.py#python3 $path/compress.py#g" "$path"/compress_client.yaml + sed -i "s# compress/compress.py# $path/compress.py#g" "$path"/compress_server.yaml + + echo "copy the server yaml file to /etc/atuned/tuning/" + cp "$path"/compress_server.yaml /etc/atuned/tuning/ + ``` + + 运行脚本: + + ```sh + sh prepare.sh enwik8.zip + ``` + +- 进行tuning调优 + + ```sh + atune-adm tuning --project compress --detail compress_client.yaml + ``` + +- 恢复tuning调优前的初始配置,compress为yaml文件中的项目名称 + + ```sh + atune-adm tuning --restore --project compress + ``` diff --git a/docs/en/25.03/Server/Performance/TuningFramework/oeAware/_menu.md b/docs/en/25.03/Server/Performance/TuningFramework/oeAware/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..2eedf364d72b2d56844116e91261cce0c4c36082 --- /dev/null +++ b/docs/en/25.03/Server/Performance/TuningFramework/oeAware/_menu.md @@ -0,0 +1,8 @@ +--- +label: 'oeAware用户指南' +ismanual: 'Y' +description: '动态感知系统行为后,智能使能系统的调优特性' +children: + - label: 'oeAware用户指南' + href: './oeAware-user-guide.md' +--- diff --git a/docs/en/25.03/Server/Performance/TuningFramework/oeAware/figures/dep-failed.png b/docs/en/25.03/Server/Performance/TuningFramework/oeAware/figures/dep-failed.png new file mode 100644 index 0000000000000000000000000000000000000000..7c98140ff9545ba7943c04cb2dc414fcc39b03e4 Binary files /dev/null and b/docs/en/25.03/Server/Performance/TuningFramework/oeAware/figures/dep-failed.png differ diff --git a/docs/en/25.03/Server/Performance/TuningFramework/oeAware/figures/dep.png b/docs/en/25.03/Server/Performance/TuningFramework/oeAware/figures/dep.png new file mode 100644 index 0000000000000000000000000000000000000000..06875fc73adae0a4379e30722a9864197212c55a Binary files /dev/null and b/docs/en/25.03/Server/Performance/TuningFramework/oeAware/figures/dep.png differ diff --git "a/docs/en/25.03/Server/Performance/TuningFramework/oeAware/figures/\344\276\235\350\265\226\345\205\263\347\263\273.png" "b/docs/en/25.03/Server/Performance/TuningFramework/oeAware/figures/\344\276\235\350\265\226\345\205\263\347\263\273.png" new file mode 100644 index 0000000000000000000000000000000000000000..0f4c65a2533cebc54f6dedf4e6eba2d232b1feeb Binary files /dev/null and "b/docs/en/25.03/Server/Performance/TuningFramework/oeAware/figures/\344\276\235\350\265\226\345\205\263\347\263\273.png" differ diff --git a/docs/en/25.03/Server/Performance/TuningFramework/oeAware/oeAware-user-guide.md b/docs/en/25.03/Server/Performance/TuningFramework/oeAware/oeAware-user-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..c48d33bf0a9d7d3c5aa1488d558561a091527a4f --- /dev/null +++ b/docs/en/25.03/Server/Performance/TuningFramework/oeAware/oeAware-user-guide.md @@ -0,0 +1,535 @@ +# oeAware用户指南 + +## 简介 + +oeAware是在openEuler上实现低负载采集感知调优的框架,目标是动态感知系统行为后智能使能系统的调优特性。传统调优特性都以独立运行且静态打开关闭为主,oeAware将调优拆分采集、感知和调优三层,每层通过订阅方式关联,各层采用插件式开发尽可能复用。 + +## 插件说明 + +**插件定义**:一个插件对应一个.so文件,插件分为采集插件、感知插件和调优插件。 + +**实例定义**:服务中的调度单位是实例,一个插件中包括多个实例。例如,一个采集插件包括多个采集项,每个采集项是一个实例。 + +**实例之间依赖关系** + +每个实例运行前,需要满足其依赖关系。 + +![img](./figures/依赖关系.png) + +- 采集实例不依赖任何其他实例。 + +- 感知实例依赖采集实例和其他感知实例。 + +- 调优实例依赖采集实例、感知实例和其他调优实例。 + +## 安装 + +配置openEuler的yum源,使用yum命令安装。在openEuler-22.03-LTS-SP4版本中会默认安装。 + +```shell +yum install oeAware-manager +``` + +### 服务启动 + +通过systemd服务启动。安装完成后会默认启动。 + +```shell +systemctl start oeaware +``` + +如果不需要手动修改配置可跳过此步。 + +配置文件路径:/etc/oeAware/config.yaml + +```yaml +log_path: /var/log/oeAware #日志存储路径 +log_level: 1 #日志等级 1:DEBUG 2:INFO 3:WARN 4:ERROR +enable_list: #默认使能插件 + - name: libtest.so #只配置插件,使能本插件的所有实例 + - name: libtest1.so #配置插件实例,使能配置的插件实例 + instances: + - instance1 + - instance2 + ... + ... +plugin_list: #可支持下载的包 + - name: test #名称需要唯一,如果重复取第一个配置 + description: hello world + url: https://gitee.com/openeuler/oeAware-manager/raw/master/README.md #url非空 + ... +``` + +修改配置文件后,通过以下命令重启服务。 + +```shell +systemctl restart oeaware +``` + +## 使用方法 + +首先启动oeaware服务,然后通过oeawarectl命令进行插件和实例进行管理,主要包括插件的加载、卸载和查询,实例的使能、关闭和查询。 + +### 插件加载 + +服务会默认加载插件存储路径下的插件。 + +插件路径:/usr/lib64/oeAware-plugin/ + +另外也可以通过手动加载的方式加载插件。 + +```shell +oeawarectl -l | --load <插件名> +``` + +示例 + +```shell +[root@localhost ~]# oeawarectl -l libthread_collect.so +Plugin loaded successfully. +``` + +失败返回错误说明。 + +### 插件卸载 + +```shell +oeawarectl -r <插件名> | --remove <插件名> +``` + +示例 + +```shell +[root@localhost ~]# oeawarectl -r libthread_collect.so +Plugin remove successfully. +``` + +失败返回错误说明。 + +### 插件查询 + +#### 查询插件状态信息 + +```shell +oeawarectl -q #查询系统中已经加载的所有插件 +oeawarectl --query <插件名> #查询指定插件 +``` + +示例 + +```shell +[root@localhost ~]# oeawarectl -q +Show plugins and instances status. +------------------------------------------------------------ +libthread_collector.so + thread_collector(available, close) # 插件实例及其状态 +libpmu.so + pmu_cycles_sampling(available, close) + pmu_cycles_counting(available, close) + pmu_uncore_counting(available, close) + pmu_spe_sampling(available, close) +libthread_tune.so + thread_tune(available, close) +libthread_scenario.so + thread_scenario(available, close) +------------------------------------------------------------ +format: +[plugin] + [instance]([dependency status], [running status]) +dependency status: available means satisfying dependency, otherwise unavailable. +running status: running means that instance is running, otherwise close. +``` + +失败返回错误说明。 + +#### 查询插件依赖 + +```shell +oeawarectl -Q #查询已加载实例的依赖关系图 +oeawarectl --query-dep= <插件实例> #查询指定实例依赖关系图 +``` + +在当前目录下生成dep.png,显示依赖关系。 + +示例 + +依赖满足下的关系图。 +![img](./figures/dep.png) + +缺少依赖的关系图。 + +![img](./figures/dep-failed.png) + +失败返回错误说明。 + +### 插件实例使能 + +#### 使能插件实例 + +```shell +oeawarectl -e | --enable <插件实例> +``` + +使能某个插件实例,会将其依赖的实例一起使能。 + +失败返回错误说明。 + +#### 关闭插件实例 + +```shell +oeawarectl -d | --disable <插件实例> +``` + +关闭某个插件实例,会将其依赖的实例(无其他实例依赖)一起关闭。 + +失败返回错误说明。 + +### 插件下载安装 + +通过--list命令查询支持下载的rpm包和已安装的插件。 + +```shell +oeawarectl --list +``` + +查询结果如下。 + +```shell +Supported Packages: #可下载的包 +[name1] #config中配置的plugin_list +[name2] +... +Installed Plugins: #已安装的插件 +[name1] +[name2] +... +``` + +通过--install命令下载安装rpm包。 + +```shell +oeawarectl -i | --install #指定--list下查询得到的包名称(Supported Packages下的包) +``` + +失败返回错误说明。 + +### 帮助 + +通过--help查看帮助。 + +```shell +usage: oeawarectl [options]... + options + -l|--load [plugin] load plugin. + -r|--remove [plugin] remove plugin from system. + -e|--enable [instance] enable the plugin instance. + -d|--disable [instance] disable the plugin instance. + -q query all plugins information. + --query [plugin] query the plugin information. + -Q query all instances dependencies. + --query-dep [instance] query the instance dependency. + --list the list of supported plugins. + -i|--install [plugin] install plugin from the list. + --help show this help message. +``` + +## 插件开发 + +### 插件公共数据结构 + +```c +struct DataBuf { + int len; + void *data; +}; +``` + +struct DataBuf 即数据的buf。 + +- data:具体的数据,data是一个数组,data的类型可以由插件的开发者自行定义。 +- len:data的大小。 + +```c +struct DataRingBuf { + const char *instance_name; + int index; + uint64_t count; + struct DataBuf *buf; + int buf_len; +}; +``` + +struct DataRingBuf 即插件和插件之间传递数据的结构,里面主要是一个循环的buf。 + +- instance_name :传入的数据的实例名称。例如当数据传递到感知插件时,用来区分是哪个采集插件的哪个采集项。 + +- index: 表示当前写入数据的位置。例如某一次数据采集后,index++。 + +- count:实例的执行次数,一直累加。 + +- buf: 数据的buf。例如某些采集项要采样多次后才会被感知插件使用,所以用buf数组保存。 + +- buf_len:数据buf的大小。buf_len在数据buf初始化申请后是固定值。 + +```C +struct Param { + const struct DataRingBuf **ring_bufs; + int len; +}; +``` + +- ring_bufs:实例需要的数据,来自其他实例。 +- len:ring_bufs数组的长度。 + +### 实例接口 + +```C +struct Interface { + const char* (*get_version)(); + /* The instance name is a unique identifier in the system. */ + const char* (*get_name)(); + const char* (*get_description)(); + /* Specifies the instance dependencies, which is used as the input information + * for instance execution. + */ + const char* (*get_dep)(); + /* Instance scheduling priority. In a uniform time period, a instance with a + * lower priority is scheduled first. + */ + int (*get_priority)(); + int (*get_type)(); + /* Instance execution period. */ + int (*get_period)(); + bool (*enable)(); + void (*disable)(); + const struct DataRingBuf* (*get_ring_buf)(); + void (*run)(const struct Param*); +}; +``` + +```c +int get_instance(Interface **interface); +``` + +每个插件都有一个get_instance函数,用来向框架输入实例。 + +获取版本号 + +1. 接口定义 + + ```c + const char* (*get_version)(); + ``` + +2. 接口说明 + +3. 参数说明 + +4. 返回值说明 + + 返回具体的版本号,预留。 + +获取实例名称 + +1. 接口定义 + + ```c + const char* (*get_name)(); + ``` + +2. 接口说明 + + 获取实例名称,客户端`-q`命令查询时会显示实例名称,同时`--enable`命令能够使能该实例。 + +3. 参数说明 + +4. 返回值说明 + + 返回具体的实例名称,必须保证实例名称唯一。 + +获取描述信息 + +1. 接口定义 + + ```c + const char* (*get_description)(); + ``` + +2. 接口说明 + +3. 参数说明 + +4. 返回值说明 + + 返回具体的描述信息,预留。 + +获取类型 + +1. 接口定义 + + ```c + int (*get_type)(); + ``` + +2. 接口说明 + +3. 参数说明 + +4. 返回值说明 + + 返回具体的类型信息,预留。 + +获取优先级 + +1. 接口定义 + + ```C + int (*get_priority)(); + ``` + +2. 接口说明 + + 获取实例优先级。在同一执行周期内,值越小优先级越高。 + +3. 参数说明 + +4. 返回值说明 + + 优先级的值。 + +获取采样周期 + +1. 接口定义 + + ```c + int (*get_period)(); + ``` + +2. 接口说明 + + 获取执行周期,不同的实例可以使用不同的执行周期。 + +3. 参数说明 + +4. 返回值说明 + + 返回具体的执行周期,单位是ms。 + +获取依赖 + +1. 接口定义 + + ```c + const char* (*get_dep)(); + ``` + +2. 接口说明 + +3. 参数说明 + +4. 返回值说明 + + 返回依赖的实例名称。若有多个依赖实例,则用`-`连接。比如实例C依赖实例”A“和实例”B“,则返回”A-B“(实例名称不允许含有“-”字符)。 + +使能实例 + +1. 接口定义 + + ```c + bool (*enable)(); + ``` + +2. 接口说明 + + 使能实例。实例执行前的初始化。 + +3. 参数说明 + +4. 返回值说明 + + 使能成功返回true,失败时返回false。 + +关闭实例 + +1. 接口定义 + + ```c + void (*disable)(); + ``` + +2. 接口说明 + + 关闭实例。实例关闭时,进行资源释放等操作。 + +3. 参数说明 + +4. 返回值说明 + +获取数据buf + +1. 接口定义 + + ```c + const DataRingBuf* (*get_ring_buf)(); + ``` + +2. 接口说明 + + 获取数据buf管理指针(内存由插件自行申请),由其他实例调用。 + +3. 参数说明 + +4. 返回值说明 + + 返回struct DataRingBuf管理指针。 + +实例执行 + +1. 接口定义 + + ```c + void (*run)(const Param*); + ``` + +2. 接口说明 + + 根据执行周期,定期执行。 + +3. 参数说明 + + 实例执行时需要的数据。 + +4. 返回值说明 + +## 可支持插件列表 + +- libpmu.so:采集插件,采集pmu相关数据。 +- libthread_collector.so:采集插件,采集系统中的线程信息。 +- libthread_scenario.so:感知插件,感知某个线程的信息。 +- libthread_tune.so:调优插件,对unixbench进行性能调优。 +- libsmc_tune.so:调优插件,使能smc加速,让所有使用tcp协议的连接无感加速。 +- libtune_numa.so:调优插件,优化跨numa访存问题,提升系统性能。 + +## 约束限制 + +### 功能约束 + +oeAware默认集成了arm的微架构采集libkperf模块,该模块同一时间只能有一个进程进行调用,如其他进程调用或者使用perf命令可能存在冲突。 + +### 操作约束 + +当前oeAware仅支持root权限用户进行操作。 + +## 注意事项 + +oeAware的配置文件和插件用户组和权限有严格校验,不要对oeAware的相关文件进行权限和用户组进行修改。 + +权限说明: + +- 插件文件:440 + +- 客户端执行文件:750 + +- 服务端执行文件:750 + +- 服务配置文件:640 diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/_menu.md b/docs/en/25.03/Server/Quickstart/Quickstart/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..b0119d9dcf8c0fba1b562d2d9510b1b11975e505 --- /dev/null +++ b/docs/en/25.03/Server/Quickstart/Quickstart/_menu.md @@ -0,0 +1,8 @@ +--- +label: '快速入门' +ismanual: 'Y' +description: '快速地安装和使用 openEuler 操作系统' +children: + - label: '快速入门' + href: './quick-start.md' +--- diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/figures/Advanced_User_Configuration.png b/docs/en/25.03/Server/Quickstart/Quickstart/figures/Advanced_User_Configuration.png new file mode 100644 index 0000000000000000000000000000000000000000..29fc332ed3ecdc70b2a031d2633a6ec4ec5a9f0b Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/figures/Advanced_User_Configuration.png differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/figures/CD-ROM_drive_icon.png b/docs/en/25.03/Server/Quickstart/Quickstart/figures/CD-ROM_drive_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9e87cfaf1bdee860b3cbc35150decd8db492f8aa Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/figures/CD-ROM_drive_icon.png differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/figures/Image_dialog_box.png b/docs/en/25.03/Server/Quickstart/Quickstart/figures/Image_dialog_box.png new file mode 100644 index 0000000000000000000000000000000000000000..e72253b3d16d4388fa051c73b94e8923020ad467 Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/figures/Image_dialog_box.png differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/figures/Installation_Overview.png b/docs/en/25.03/Server/Quickstart/Quickstart/figures/Installation_Overview.png new file mode 100644 index 0000000000000000000000000000000000000000..f6542ffc0c01cf2489071ebf5addb47f12b0a242 Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/figures/Installation_Overview.png differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/figures/Installation_Procedure.png b/docs/en/25.03/Server/Quickstart/Quickstart/figures/Installation_Procedure.png new file mode 100644 index 0000000000000000000000000000000000000000..06a9d14a166bdfe86c5eec0be7929a7a99c5ea45 Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/figures/Installation_Procedure.png differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/figures/Installation_wizard.png b/docs/en/25.03/Server/Quickstart/Quickstart/figures/Installation_wizard.png new file mode 100644 index 0000000000000000000000000000000000000000..fc3a96c0cd4b5a2ece94a0b3fc484720440adace Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/figures/Installation_wizard.png differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/figures/Setting_the_System_Boot_Option.png b/docs/en/25.03/Server/Quickstart/Quickstart/figures/Setting_the_System_Boot_Option.png new file mode 100644 index 0000000000000000000000000000000000000000..682f555c3a6da63e1cf6e6eed402e2851c4a7ebb Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/figures/Setting_the_System_Boot_Option.png differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/figures/Target_installation_position.png b/docs/en/25.03/Server/Quickstart/Quickstart/figures/Target_installation_position.png new file mode 100644 index 0000000000000000000000000000000000000000..5dcf04a4bfa256efef32a1cf7dd146161030381d Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/figures/Target_installation_position.png differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/figures/choosesoftware.png b/docs/en/25.03/Server/Quickstart/Quickstart/figures/choosesoftware.png new file mode 100644 index 0000000000000000000000000000000000000000..e9f4dbfb6de56498a46752cbebe88ab623366160 Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/figures/choosesoftware.png differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/figures/createuser.png b/docs/en/25.03/Server/Quickstart/Quickstart/figures/createuser.png new file mode 100644 index 0000000000000000000000000000000000000000..a280f355f07f34e590bfcb5c33a16b2201051857 Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/figures/createuser.png differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/figures/restarticon.png b/docs/en/25.03/Server/Quickstart/Quickstart/figures/restarticon.png new file mode 100644 index 0000000000000000000000000000000000000000..33bf7cd2e435ff04f3947eb39ba20019b12bf2d2 Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/figures/restarticon.png differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/figures/root_password.png b/docs/en/25.03/Server/Quickstart/Quickstart/figures/root_password.png new file mode 100644 index 0000000000000000000000000000000000000000..acc7ac215cecfe996a991cf61c69c52d19a06d31 Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/figures/root_password.png differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/figures/selectlanguage.png b/docs/en/25.03/Server/Quickstart/Quickstart/figures/selectlanguage.png new file mode 100644 index 0000000000000000000000000000000000000000..4351e637cb673e156864cf5110e68efb3c3e1f2b Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/figures/selectlanguage.png differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/figures/zh-cn_image_0229420473.png b/docs/en/25.03/Server/Quickstart/Quickstart/figures/zh-cn_image_0229420473.png new file mode 100644 index 0000000000000000000000000000000000000000..86c61a4b8e2a5795baff2fc74629924d01d7b97b Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/figures/zh-cn_image_0229420473.png differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-caution.gif b/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-caution.gif differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-danger.gif b/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-danger.gif differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-note.gif b/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-notice.gif b/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-notice.gif differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-tip.gif b/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-tip.gif differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-warning.gif b/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Quickstart/Quickstart/public_sys-resources/icon-warning.gif differ diff --git a/docs/en/25.03/Server/Quickstart/Quickstart/quick-start.md b/docs/en/25.03/Server/Quickstart/Quickstart/quick-start.md new file mode 100644 index 0000000000000000000000000000000000000000..858a64641487b613fbb0a3bc705b67ffcefcff00 --- /dev/null +++ b/docs/en/25.03/Server/Quickstart/Quickstart/quick-start.md @@ -0,0 +1,320 @@ +# 快速入门 + +本文档以TaiShan 200服务器上安装openEuler 21.09 为例,旨在指导用户快速地安装和使用openEuler操作系统,更详细的安装要求和安装方法请参考《[安装指南](../../InstallationUpgrade/Installation/installation.md)》。 + +## 安装要求 + +- 硬件兼容支持 + + 支持的服务器类型如[表1](#table14948632047)所示。 + + **表 1** 支持的服务器类型 + + + + + + + + + + + + + + + + +

服务器形态

+

服务器名称

+

服务器型号

+

机架服务器

+

TaiShan 200

+

2280均衡型

+

机架服务器

+

FusionServer Pro 机架服务器

+

FusionServer Pro 2288H V5

+
说明:

服务器要求配置Avago 3508 RAID控制卡和启用LOM-X722网卡。

+
+
+ +- 最小硬件要求 + + 最小硬件要求如[表2](#tff48b99c9bf24b84bb602c53229e2541)所示。 + + **表 2** 最小硬件要求 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

部件名称

最小硬件要求

说明

架构

  • AArch64
  • x86_64
  • 支持Arm的64位架构。
  • 支持Intel的x86 64位架构。

CPU

  • 华为鲲鹏920系列CPU
  • Intel® Xeon®处理器

-

内存

不小于4GB(为了获得更好的应用体验,建议不小于8GB)

-

硬盘

为了获得更好的应用体验,建议不小于120GB

  • 支持IDE、SATA、SAS等接口的硬盘。
  • 用DIF功能的NVME盘,需要对应驱动支持,如果无法使用,请联系硬件厂商。

+ +## 获取安装源 + +请按以下步骤获取openEuler的发布包和校验文件: + +1. 登录[openEuler社区](https://openeuler.org)网站。 +2. 单击“下载”。 +3. 单击“社区发行版”,显示版本列表。 +4. 在版本列表的“openEuler 22.03 LTS SP2”版本处单击“前往下载”按钮,进入openEuler 22.03_LTS_SP2版本下载列表。 +5. 根据实际待安装环境的架构和场景选择需要下载的 openEuler 的发布包和校验文件。 + 1. 若为AArch64架构。 + 1. 单击“AArch64”。 + 2. 若选择本地安装,选择“Offline Standard ISO”或者“Offline Everything ISO”对应的“立即下载”将发布包 “openEuler-22.03-LTS-SP2-aarch64-dvd.iso”下载到本地。 + 3. 若选择网络安装,选择“Network Install ISO”将发布包 “openEuler-22.03-LTS-SP2-netinst-aarch64-dvd.iso”下载到本地。 + 2. 若为x86_64架构。 + 1. 单击“x86_64”。 + 2. 若选择本地安装,选择“Offline Standard ISO”或者“Offline Everything ISO”对应的“立即下载”将发布包 “openEuler-22.03-LTS-SP2-x86_64-dvd.iso”下载到本地。 + 3. 若选择网络安装,选择“Network Install ISO”将发布包 “openEuler-22.03-LTS-SP2-netinst-x86_64-dvd.iso ”下载到本地。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> - 网络安装方式的 ISO 发布包较小,在有网络的安装环境可以选择网络安装方式。 +> - AArch64架构的发布包支持UEFI模式,x86\_64架构的发布包支持UEFI模式和Legacy模式。 + +## 发布包完整性校验 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 本章节以AArch64架构的发布包完整性校验为例,x86\_64架构的发布包完整性校验的操作方法相同。 + +### 简介 + +为了确认软件包在传输过程中由于网络原因或者存储设备原因是否出现下载不完整的问题,在获取到软件包后,需要对软件包的完整性进行校验,通过了校验的软件包才能部署。 + +这里通过对比校验文件中记录的校验值和手动方式计算的iso文件校验值,判断软件包是否完整。若两个值相同,说明iso文件完整,否则,iso完整性被破坏,请重新获取iso发布包。 + +### 前提条件 + +在校验发布包完整性之前,需要准备如下文件: + +iso文件:openEuler-22.03-LTS-SP2-aarch64-dvd.iso + +校验文件:ISO对应完整性校验值,复制保存对应的ISO值 + +### 操作指导 + +文件完整性校验操作步骤如下: + +1. 计算文件的sha256校验值。执行命令如下: + + ```sh + # sha256sum openEuler-22.03-LTS-SP2-aarch64-dvd.iso + ``` + + 命令执行完成后,输出校验值。 + +2. 对比步骤1计算的校验值与对刚刚复制的SHA256的值是否一致。 + + 如果校验值一致说明iso文件完整性没有被破坏,如果校验值不一致则可以确认文件完整性已被破坏,需要重新获取。 + +## 启动安装 + +1. 登录服务器iBMC Web界面。具体方法请参考《[TaiShan 200 服务器 用户指南 (型号 2280)](https://support.huawei.com/enterprise/zh/doc/EDOC1100088652)》。 +2. 在上方标题栏中,选择“配置”,在左侧导航树中选择“系统启动项”,显示“系统启动项”界面。 + + 将“优先引导介质”设置为“光驱”,选择“单次有效”,并单击“保存”以保存配置。如[图1](#fig1011938131018)所示。 + + **图 1** 设置系统启动项 + ![](./figures/Setting_the_System_Boot_Option.png) + +3. 在上方标题栏中,选择“远程控制”,在左侧导航树中选择“远程控制”,显示“远程控制”界面。 + + 根据实际情况选择一个集成远程控制台以进入远程虚拟控制台,如选择“Java集成远程控制台\(共享\)”。 + +4. 在虚拟界面工具栏中,单击虚拟光驱工具如下图所示。 + + **图 2** 光驱图标 + ![](./figures/CD-ROM_drive_icon.png) + + 弹出镜像对话框,如下图所示。 + + **图 3** 镜像对话框 + ![](./figures/Image_dialog_box.png) + +5. 在镜像对话框中,选择“镜像文件”, 并单击“浏览”。弹出“打开”对话框。 +6. 选择镜像文件,单击“打开”。然后在镜像对话框中,单击“连接”。当“连接”显示为“断开”后,表示虚拟光驱已连接到服务器。 +7. 在工具栏中,单击重启工具重启设备,如下图所示。 + + **图 4** 重启图标 + ![](./figures/restarticon.png) + +8. 设备重启后进入到openEuler操作系统安装引导界面,如[图5](#fig1648754873314)所示。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > + > - 如果60秒内未按任何键,系统将从默认选项“Test this media & install openEuler 21.09”自动进入安装界面。 + > - 安装物理机时,如果使用键盘上下键无法选择启动选项,按“Enter”键无响应,可以单击BMC界面上的鼠标控制图标“![](./figures/zh-cn_image_0229420473.png)”,设置“键鼠复位”。 + > + + **图 5** 安装引导界面 + ![](./figures/Installation_wizard.png) + +9. 在安装引导界面,按“Enter”,进入默认选项“Test this media & install openEuler 21.09”的图形化安装界面。 + +## 安装 + +进入图形化安装界面后,按如下步骤进行安装。 + +1. 设置安装语言,默认为英语,用户可根据实际情况进行调整,如[图6](#fig874344811484)所示,选择“中文”。 + + **图 6** 选择语言 + ![](./figures/selectlanguage.png) + +2. 在安装概览界面,根据实际情况设置各配置项。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > + > - 配置项有告警符号的,表示用户必须完成该选项配置后,告警符号消失,才能进行下一步操作。 + > - 配置项无告警符号的,表示该配置项已有默认配置。 + > - 所有配置项均无告警符号时用户才能单击“开始安装”进行系统安装。 + > + + **图 7** 安装概览 + ![](./figures/Installation_Overview.png) + + 1. 选择“软件选择”,设置“软件选择”配置项。 + + 用户需要根据实际的业务需求,在左侧选择一个“最小安装”,在右侧选择安装环境的附加选项,如[图8](#fig1133717611109)所示。 + + **图 8** 软件选择 + ![](./figures/choosesoftware.png) + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > + > - 在最小安装的环境下,并非安装源中所有的包都会安装。如果用户需要使用的包未安装,可将安装源挂载到本地制作repo源,通过DNF工具单独安装。 + > - 选择“虚拟化主机”时会默认安装虚拟化组件qemu、libvirt、edk2,且可在附加选项处选择是否安装ovs等组件。 + + 设置完成后,请单击左上角“完成”返回“安装概览”页面。 + + 2. 选择“安装目的地”,设置“安装目的地”配置项。 + + 在安装位置页面中,您可以选择计算机中的本地可用存储设备。 + + > ![](./public_sys-resources/icon-notice.gif) **须知:** + > + > - 由于很多服务器BIOS内置NVMe驱动程序版本较低,不支持NVMe的数据保护特性(数据保护:将磁盘扇区格式化为512+N或4096+N字节)。所以,在选择合适的存储介质时,建议不要选择开启数据保护特性的NVMe SSD存储介质作为系统盘,否则可能出现操作系统无法引导等问题。 + > - 用户可以选择优先咨询服务器厂商关于BIOS是否支持开启数据保护特性的NVMe磁盘作为系统盘。如果您无法确认BIOS是否支持,则不推荐使用NVMe安装操作系统,或者选择关闭NVMe盘的数据保护功能实现操作系统安装。 + + 您还需要进行存储配置以便对系统分区。您可以手动配置分区,也可以选择让安装程序自动分区。如果是在未使用过的存储设备中执行全新安装,或者不需要保留该存储设备中任何数据,建议选择“自动”进行自动分区。如[图9](#fig153381468101)所示。 + + **图 9** 安装目标位置 + ![](./figures/Target_installation_position.png) + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > + > - 在进行分区时,出于系统性能和安全的考虑,建议您划分如下单独分区:/boot、/var、/var/log 、/var/log/audit、/home、/tmp。 + > - 系统如果配置了swap分区,当系统的物理内存不够用时,会使用swap分区。虽然 swap分区可以增大物理内存大小的限制,但是如果由于内存不足使用到swap分区,会增加系统的响应时间,性能变差。因此在物理内存充足或者性能敏感的系统中,不建议配置swap分区。 + > - 如果需要拆分逻辑卷组则需要选择“自定义”进行手动分区,并在“手动分区”界面单击“卷组”区域中的“修改”按钮重新配置卷组。 + + 设置完成后,请单击左上角“完成”返回“安装概览”页面。 + + 3. 选择“根密码”,设置“根密码”配置项。 + + 在如图10所示的“ROOT密码”页面中,根据密码复杂度输入密码并再次输入密码进行确认。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > + > - root帐户是用来执行关键系统管理任务,不建议您在日常工作及系统访问时使用root帐户。 + > - 在“ROOT密码”界面若选择“锁定root帐户”则root帐户将禁用。 + + **密码复杂度** + + 用户设置的root用户密码或新创建用户的密码均需要满足密码复杂度要求,否则会导致密码设置或用户创建失败。设置密码的复杂度的要求如下: + + 1. 口令长度至少8个字符。 + 2. 口令至少包含大写字母、小写字母、数字和特殊字符中的任意3种。 + 3. 口令不能和帐号一样。 + 4. 口令不能使用字典词汇。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 在已装好的openEuler环境中,可以通过`cracklib-unpacker /usr/share/cracklib/pw_dict > dictionary.txt`命令导出字典库文件dictionary.txt,用户可以查询密码是否在该字典中。 + + **图 10** root密码 + ![](./figures/root_password.png) + + 设置完成后,单击左上角的“完成”返回“安装概览”页面。 + + 4. 选择“创建用户”,设置“创建用户”配置项。 + + 在创建用户的界面如[图11](#zh-cn_topic_0186390266_zh-cn_topic_0122145909_fig1237715313319)所示。输入用户名,并设置密码,其中密码复杂度要求与root密码复杂度要求一致。另外您还可以通过“高级”选项设置用户主目录、用户组等,如[图12](#zh-cn_topic_0186390266_zh-cn_topic_0122145909_fig128716531312)所示。 + + **图 11** 创建用户 + ![](./figures/createuser.png) + + **图 12** 高级用户配置 + ![](./figures/Advanced_User_Configuration.png) + + 完成设置后,单击左上角的“完成”返回“安装概览”页面。 + + 5. 设置其他配置项,其他配置项可以使用默认配置。 + +3. 单击“开始安装”进行系统安装,如[图13](#fig1717019357392)所示。 + + **图 13** 开始安装 + ![](./figures/Installation_Procedure.png) +4. 安装完成后重启系统。 + + openEuler完成安装后,单击“重启”按钮,系统将重新启动。 + +## 查看系统信息 + +系统安装完成并重启后直接进入系统命令行登录界面,输入安装过程中设置的用户和密码,进入openEuler操作系统,查看如下系统信息。若需要进行系统管理和配置操作,请参考《[管理员指南](https://openeuler.org/zh/docs/21.09/docs/Administration/administration.html)》。 + +- 查看系统信息,命令如下: + + ```sh + cat /etc/os-release + ``` + +- 查看系统相关的资源信息。 + + 查看CPU信息,命令如下: + + ```sh + # lscpu + ``` + + 查看内存信息,命令如下: + + ```sh + # free + ``` + + 查看磁盘信息,命令如下: + + ```sh + # fdisk -l + ``` + +- 查看IP地址,命令如下: + + ```sh + # ip addr + ``` diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/_menu.md b/docs/en/25.03/Server/Releasenotes/Releasenotes/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..e242f4863f1b4767c79260098207d875b2347165 --- /dev/null +++ b/docs/en/25.03/Server/Releasenotes/Releasenotes/_menu.md @@ -0,0 +1,30 @@ +--- +label: '发行说明' +ismanual: 'Y' +description: 'openEuler 25.03 版本的发行说明' +children: + - label: '简介' + href: './introduction.md' + - label: '法律声明' + href: './terms-of-use.md' + - label: '用户须知' + href: './user-notice.md' + - label: '帐号清单' + href: './account-list.md' + - label: '系统安装' + href: './installing-the-os.md' + - label: '关键特性' + href: './key-features.md' + - label: '已知问题' + href: './known-issues.md' + - label: '已修复问题' + href: './resolved-issues.md' + - label: 'CVE漏洞' + href: './common-vulnerabilities-and-exposures-(cve).md' + - label: '源代码' + href: './source-code.md' + - label: '参与贡献' + href: './contribution.md' + - label: '致谢' + href: './acknowledgment.md' +--- diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/account-list.md b/docs/en/25.03/Server/Releasenotes/Releasenotes/account-list.md new file mode 100644 index 0000000000000000000000000000000000000000..594e43206644bc6da9625321958e802ed6e9d1c0 --- /dev/null +++ b/docs/en/25.03/Server/Releasenotes/Releasenotes/account-list.md @@ -0,0 +1,6 @@ +# openEuler帐号清单 + +| 用户名 | 默认密码 | 用户用途 | 用户状态 | 登录方式 | 备注 | +|--- |--- | --- | --- |--- |--- | +| root | openEuler12#$| 虚拟机镜像默认用户 | 启用 | 远程登录 | 登录使用openEuler虚拟机镜像安装的虚拟机 | +| root | openEuler#12 | 登录GRUB2 | 启用 | 本地登录、远程登录 | GRUB (GRand UnifiedBootloader) 是操作系统启动管理器,用来引导不同系统(如Windows、Linux)。
GRUB2是GRUB的升级版。系统启动时,可以通过GRUB2界面修改启动参数。为了确保系统的启动参数不被任意修改,需要对GRUB2界面进行加密,仅在输入正确的GRUB2口令时才能修改。 | diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/acknowledgment.md b/docs/en/25.03/Server/Releasenotes/Releasenotes/acknowledgment.md new file mode 100644 index 0000000000000000000000000000000000000000..1bbe74bfc69de3609389419b1156abe4135b73ec --- /dev/null +++ b/docs/en/25.03/Server/Releasenotes/Releasenotes/acknowledgment.md @@ -0,0 +1,3 @@ +# 致谢 + +我们衷心地感谢参与和协助openEuler项目的所有成员。是你们的辛勤付出使得版本顺利发布,也为openEuler更好地发展提供可能。 diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/common-vulnerabilities-and-exposures-(cve).md b/docs/en/25.03/Server/Releasenotes/Releasenotes/common-vulnerabilities-and-exposures-(cve).md new file mode 100644 index 0000000000000000000000000000000000000000..e826e0f56506b3ac239843c6a6bf0d607691b318 --- /dev/null +++ b/docs/en/25.03/Server/Releasenotes/Releasenotes/common-vulnerabilities-and-exposures-(cve).md @@ -0,0 +1,3 @@ +# CVE漏洞 + +版本涉及的CVE可通过[CVE列表](https://www.openeuler.org/zh/security/cve)查询。 diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/contribution.md b/docs/en/25.03/Server/Releasenotes/Releasenotes/contribution.md new file mode 100644 index 0000000000000000000000000000000000000000..af67aa4a7fb979e24865e5b891b104650c083d6a --- /dev/null +++ b/docs/en/25.03/Server/Releasenotes/Releasenotes/contribution.md @@ -0,0 +1,21 @@ +# 参与贡献 + +作为openEuler用户,你可以通过多种方式协助openEuler社区。参与社区贡献的方法请参见[贡献攻略](https://www.openeuler.org/zh/community/contribution/),这里简单列出部分方式供参考。 + +## 特别兴趣小组 + +openEuler将拥有共同兴趣的人们聚在一起,组成了不同的特别兴趣小组(SIG)。当前已有的SIG请参见[SIG列表](https://www.openeuler.org/zh/sig/sig-list/)。 + +我们欢迎并鼓励你加入已有的SIG或创建新的SIG,创建方法请参见[SIG管理指南](https://gitee.com/openeuler/community/blob/master/zh/technical-committee/governance/README.md)。 + +## 邮件列表和任务 + +欢迎你积极地帮助用户解决在[邮件列表](https://www.openeuler.org/zh/community/mailing-list/)和issue任务(包括[代码仓任务](https://gitee.com/organizations/openeuler/issues)和[软件包仓任务](https://gitee.com/organizations/src-openeuler/issues))中提出的问题。另外,我们也欢迎你提出问题。这些都将帮助openEuler社区更好地发展。 + +## 文档 + +我们不仅欢迎你通过提交代码参与社区贡献,还欢迎你反馈遇到的问题、困难,或者对文档易用性、完整性等提出改进建议。例如获取软件或文档过程中的问题,使用系统过程中的难点。欢迎关注并改进[openEuler社区](https://www.openeuler.org/zh/)的文档模块。 + +## IRC + +openEuler也在IRC开辟了频道,作为提供社区支持和交互的额外渠道。详情请参见[openEuler IRC](https://gitee.com/openeuler/community/blob/master/zh/communication/IRCs.md)。 diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/installing-the-os.md b/docs/en/25.03/Server/Releasenotes/Releasenotes/installing-the-os.md new file mode 100644 index 0000000000000000000000000000000000000000..bb95a3493333ae2d9e8bdbe08e90f9850dd59ccd --- /dev/null +++ b/docs/en/25.03/Server/Releasenotes/Releasenotes/installing-the-os.md @@ -0,0 +1,307 @@ +# 系统安装 + +## 发布件 + +openEuler发布件包括[ISO发布包](https://www.openeuler.org/zh/download/archive/)、[虚拟机镜像](http://repo.openeuler.org/openEuler-22.09/)、[容器镜像](http://repo.openeuler.org/openEuler-22.09/)、[嵌入式镜像](http://repo.openeuler.org/openEuler-22.09/)和[repo源](http://repo.openeuler.org/openEuler-22.09/)。ISO发布包请参见[表1](#table8396719144315)。容器镜像清单参见[表3](#table1276911538154)。repo源方便在线使用,repo源目录请参见[表5](#table953512211576)。 + +**表 1** 发布ISO列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

名称

+

描述

+

openEuler-22.09-aarch64-dvd.iso

+

AArch64架构的基础安装ISO,包含了运行最小系统的核心组件

+

openEuler-22.09-everything-aarch64-dvd.iso

+

AArch64架构的全量安装ISO,包含了运行完整系统所需的全部组件

+

openEuler-22.09-everything-debug-aarch64-dvd.iso

+

AArch64架构下openEuler的调试ISO,包含了调试所需的符号表信息

+

openEuler-22.09-x86_64-dvd.iso

+

x86_64架构的基础安装ISO,包含了运行最小系统的核心组件

+

openEuler-22.09-everything-x86_64-dvd.iso

+

x86_64架构的全量安装ISO,包含了运行完整系统所需的全部组件

+

openEuler-22.09-everything-debuginfo-x86_64-dvd.iso

+

x86_64架构下openEuler的调试ISO,包含了调试所需的符号表信息

+

openEuler-22.09-source-dvd.iso

+

openEuler源码ISO

+

openEuler-21.09-edge-aarch64-dvd.iso

+

AArch64架构的边缘ISO,包含了运行最小系统的核心组件

+

openEuler-21.09-edge-x86_64-dvd.iso

+

x86_64架构的边缘ISO,包含了运行最小系统的核心组件

+

openEuler-21.09-Desktop-aarch64-dvd.iso

+

AArch64架构的开发者桌面ISO,包含了运行开发桌面的最小软件集合

+

openEuler-21.09-Desktop-x86_64-dvd.iso

+

x86_64架构的开发者桌面ISO,包含了运行开发桌面的最小软件集合

+
+ +**表 2** 虚拟机镜像 + + + + + + + + + + + + + + +

名称

+

描述

+

openEuler-22.09-aarch64.qcow2.xz

+

AArch64架构下openEuler虚拟机镜像

+

openEuler-22.09-x86_64.qcow2.xz

+

x86_64架构下openEuler虚拟机镜像

+
+ +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 虚拟机镜像root用户默认密码为:openEuler12\#$,首次登录后请及时修改。 + +**表 3** 容器镜像列表 + + + + + + + + + + + + + +

名称

+

描述

+

openEuler-docker.aarch64.tar.xz

+

AArch64架构下openEuler容器镜像

+

openEuler-docker.x86_64.tar.xz

+

x86_64架构下openEuler容器镜像

+
+ +**表 4** 嵌入式镜像列表 + +| 名称 | 描述 | +| -------------------------------------- | ------------------------------- | +| arm64/aarch64-std/zImage | AArch64架构下支持qemu的内核镜像 | +| arm64/aarch64-std/\*toolchain-22.09.sh | AArch64架构下对应的开发编译链 | +| arm64/aarch64-std/\*rootfs.cpio.gz | AArch64架构下支持qemu的文件系统 | +| arm32/arm-std/zImage | Arm架构下支持qemu的内核镜像 | +| arm32/arm-std/\*toolchain-22.09.sh | Arm架构下对应的开发编译链 | +| arm32/arm-std/\*rootfs.cpio.gz | Arm架构下支持qemu的文件系统 | +| source-list/manifest.xml | 构建使用的源码清单 | + +**表 5** repo源列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

目录

+

描述

+

ISO

+

存放ISO镜像

+

OS

+

存放基础软件包源

+

debuginfo

+

存放调试包源

+

docker_img

+

存放容器镜像

+

virtual_machine_img

+

存放虚拟机镜像

+

embedded_img

+

存放嵌入式镜像

+

everything

+

存放全量软件包源

+

extras

+

存放扩展软件包源

+

source

+

存放源码软件源

+

update

+

存放升级软件包源

+

EPOL

+

存放openEuler扩展包

+
+ +## 最小硬件要求 + +安装 openEuler 22.09-LTS 所需的最小硬件要求如[表6](#zh-cn_topic_0182825778_tff48b99c9bf24b84bb602c53229e2541)所示。 + +**表 6** 最小硬件要求 + + + + + + + + + + + + + + + + +

部件名称

+

最小硬件要求

+

CPU

+

鲲鹏 920(架构为AArch64)

+

Skylake以上(架构为x86_64)

+

内存

+

不小于8GB

+

硬盘

+

不小于120GB

+
+ +## 硬件兼容性 + +openEuler已验证支持的服务器和各部件典型配置请参见[表7](#zh-cn_topic_0227922427_table39822012)。openEuler后续将逐步增加对其他服务器的支持,也欢迎广大合作伙伴/开发者参与贡献和验证。openEuler当前支持的服务器可见[兼容列表](https://www.openeuler.org/zh/compatibility/)。 + +**表 7** 支持的服务器及典型配置 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

厂商

+

服务器名称

+

服务器具体型号

+

部件名称

+

典型配置

+

华为

+

TaiShan 200

+

2280均衡型

+

CPU

+

HiSilicon Kunpeng 920

+

内存

+

32G*4 2933MHz

+

RAID卡

+

LSI SAS3508

+

网络

+

TM210

+

华为

+

FusionServer Pro

+

2288H V5(机架服务器)

+

CPU

+

Intel(R) Xeon(R) Gold 5118 CPU @ 2.30GHz

+

内存

+

32G*4 2400MHz

+

RAID卡

+

LSI SAS3508

+

网络

+

X722

+
diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/introduction.md b/docs/en/25.03/Server/Releasenotes/Releasenotes/introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..a784c4fe1c3c1893491aa30f1536bb68e4c93a9b --- /dev/null +++ b/docs/en/25.03/Server/Releasenotes/Releasenotes/introduction.md @@ -0,0 +1,3 @@ +# 简介 + +openEuler是一款开源操作系统。当前openEuler内核源于Linux,支持鲲鹏及其他多种处理器,能够充分释放计算芯片的潜能,是由全球开源贡献者构建的高效、稳定、安全的开源操作系统,适用于数据库、大数据、云计算、人工智能等应用场景。同时,openEuler是一个面向全球的操作系统开源社区,通过社区合作,打造创新平台,构建支持多处理器架构、统一和开放的操作系统,推动软硬件应用生态繁荣发展。 diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/key-features.md b/docs/en/25.03/Server/Releasenotes/Releasenotes/key-features.md new file mode 100644 index 0000000000000000000000000000000000000000..2b6e6c9ef00f33cbe3814ff819de04784d920817 --- /dev/null +++ b/docs/en/25.03/Server/Releasenotes/Releasenotes/key-features.md @@ -0,0 +1,295 @@ +# 关键特性 + +## 异构通用内存管理框架(GMEM)特性 + +异构通用内存管理框架 GMEM (Generalized Memory Management),提供了异构内存互联的中心化管理机制,是面向 OS For AI 的终极内存管理解决方案。GMEM 革新了 Linux 内核中的内存管理架构,其中逻辑映射系统屏蔽了 CPU 和加速器地址访问差异,remote_pager内存消息交互框架提供了设备接入抽象层。在统一的地址空间下,GMEM可以在数据需要被访问或换页时,自动地迁移数据到OS或加速器端。GMEM API与Linux原生内存管理API保持统一,易用性强,性能与可移植性好。 + +- **逻辑映射系统**: 在内核中提供 GMEM 高层 API,允许加速器驱动直接获取内存管理功能,建立逻辑页表。逻辑页表将内存管理的高层逻辑与 CPU 的硬件相关层解耦,从而抽象出能让各类加速器复用的高层内存管理逻辑。 + +- **Remote Pager 内存消息交互框架**:实现可供主机和加速器设备交互的消息通道、进程管理、内存交换和内存预取等模块。通过 remote_pager 抽象层可以让第三方加速器很容易的接入 GMEM 系统,简化设备适配难度。 + +- **用户API**: 使用 OS 的 mmap 分配统一虚拟内存,GMEM 在 mmap 系统调用中新增分配统一虚拟内存标志(MMAP_PEER_SHARED)。同时 libgmem 用户态库提供内存预取语义 hmadvise 接口,协助用户优化加速器内存访问效率。 + +## 开源大模型原生支持(LLaMa和ChatGLM) + +llama.cpp 和 chatglm-cpp 是基于 C/C++ 实现的模型推理框架,通过模型量化等手段,支持用户可以在CPU机器上完成开源大模型的部署和使用。llama.cpp 支持多个英文开源大模型的部署,如 LLaMa/LLaMa2/Vicuna 等。chatglm-cpp 支持多个中文开源大模型的部署,如 ChatGLM-6B/ChatGLM2-6B/Baichuan-13B等。 + +- 基于 ggml 的 C/C++ 实现。 + +- 通过 int4/int8 量化、优化的 KV 缓存和并行计算等多种方式加速内存高效 CPU 推理。 + +## openEuler 6.6 内核中的特性 + +openEuler 24.09 基于 Linux Kernel 6.6 内核构建,在此基础上,同时吸收了社区高版本的有益特性及社区创新特性。 + +- **内存管理folio特性**:Linux内存管理基于page(页)转换到由folio(拉丁语 foliō,对开本)进行管理,相比page,folio可以由一个或多个page组成,采用struct folio参数的函数声明它将对整个(1个或者多个)页面进行操作,而不仅仅是PAGE_SIZE字节,从而移除不必要复合页转换,降低误用tail page问题;从内存管理效率上采用folio减少LRU链表数量,提升内存回收效率,另一方,一次分配更多连续内存减少page fault次数,一定程度降低内存碎片化;而在IO方面,可以加速大IO的读写效率,提升吞吐。全量支持匿名页、文件页的large folio,提供系统级别的开关控制,业务可以按需使用。对于ARM64架构,基于硬件contiguous bit技术(16个连续PTE只占一个 TLB entry),可以进一步降低系统TLB miss,从而提升整体系统性能。24.09新增支持anonymous shmem分配mTHP与支持mTHP的lazyfree,进一步增加内存子系统对于large folio的支持;新增page cache分配mTHP的sysfs控制接口,提供系统级别的开关控制,业务可以按需使用。 + +- **MPTCP特性支持**:MPTCP协议诞生旨在突破传统 TCP 协议的单一路径传输瓶颈,允许应用程序使用多个网络路径进行并行数据传输。这一设计优化了网络硬件资源的利用效率,通过智能地将流量分配至不同传输路径,显著缓解了网络拥塞问题,从而提高数据传输的可靠性和吞吐量。 + + 目前,MPTCP 在下述网络场景中已经展现出了其优秀的性能: + + - 网络通路的选择:在现有的网络通路中,根据延迟、带宽等指标评估,选择最优的通路。 + - 无缝切网:在不同类型网络之间切换时,数据传输不中断。 + - 数据分流:同时使用多个通道传输,对数据包进行分发实现并发传输,增加网络带宽。 + + 在实验环境中,采用MPTCP v1技术的RSYNC文件传输工具展现出了令人满意的效率提升。具体而言,传输1.3GB大小的文件时,传输时间由原来的114.83 s缩短至仅14.35s,平均传输速度由原来的11.08 MB/s提升至88.25 MB/s,可以极大程度的缩减文件传输时间。同时,实验模拟了传输过程中一条或多条路径突发故障而断开的场景,MPTCP在此种场景下可以将数据无缝切换至其他可用的数据通道,确保数据传输的连续性与完整性。 + + 在openEuler 24.09中,已经完成了对linux主线内核6.9中MPTCP相关特性的全面移植与功能优化。 + +- **ext4文件系统支持Large folio**:iozone性能总分可以提升80%。 + + iomap框架回写流程支持批量映射block。支持ext4默认模式下批量申请block,大幅优化各类benchmark下ext4性能表现。ext4 buffer io读写流程以及pagecache回写流程弃用老旧的buffer_head框架,切换至iomap框架,并通过iomap框架实现ext4支持large folio。24.09新增对于block size < folio size场景的小buffered IO(<=4KB)的性能优化,性能提升20%。 + +- **按需加载支持failover特性**:cachefiles在按需模式下,如果守护进程崩溃或被关闭,按需加载相关的读取和挂载将返回-EIO。所有挂载点必须要在重新拉起 daemon 后重新挂载后方可继续使用。这在公共云服务生产环境中发生时是无法接受的,这样的I/O错误将传播给云服务用户,可能会影响他们作业的执行,并危及系统的整体稳定性。cachefiles failover 特性避免了守护进程崩溃后重新挂载所有挂载点,只需快速重新拉起守护进程即可,用户和服务是不感知守护进程崩溃的。 + +- **支持CLANG 编译的PGO优化**:PGO(Profile-Guided Optimization)是一种编译器反馈优化技术,通过收集程序运行时的信息,指导编译器的优化决策。根据业界经验,对于数据中心大型应用(如MySQL、Nginx、Redis等)通过反馈优化技术优化应用本身和Linux kernel有较好优化效果。经过测试,LLVM PGO可以在Nginx上有20%+性能提升,其中优化kernel提升10+%。 + +## 嵌入式 + +openEuler 23.09 Embedded 支持嵌入式虚拟化弹性底座,提供 Jailhouse 虚拟化方案、openAMP 轻量化混合部署方案,用户可以根据自己的使用场景选择最优的部署方案。同时支持 ROS humble 版本,集成 ros-core、rosbase、SLAM 等核心软件包,满足 ROS2 运行时要求。 + +- **南向生态**:openEuler Embedded Linux 当前主要支持 ARM64、x86-64 两种芯片架构,支持 RK3568、Hi3093、树莓派 4B、x86-64 工控机等具体硬件,23.09 版本新增支持 RK3399、RK3588 芯片。初步支持 ARM32、RISC-V 两种架构具体通过 QEMU 仿真来体现。 + +- **嵌入式弹性虚拟化底座**:openEuler Embedded 的融合弹性底座是为了在多核片上系统(SoC,System On Chip)上实现多个操作系统/运行时共同运行的一系列技术的集合,包含了裸金属、嵌入式虚拟化、轻量级容器、LibOS、可信执行环境(TEE)、异构等多种实现形态。 + +- **混合关键性部署框架**:构建在融合弹性底座之上,通过一套统一的框架屏蔽下层融合弹性底座形态的不同,从而实现 Linux 和其他 OS 运行时便捷地混合部署。 + +- **北向生态**:350+ 嵌入式领域常用软件包的构建;支持 ROS2 humble 版本,集成 ros-core、ros-base、SLAM 等核心包,并提供 ROS SDK,简化嵌入式 ROS 开发;基于 Linux 5.10 内核提供软实时能力,软实时中断响应时延微秒级;集成 OpenHarmony 的分布式软总线和 hichain 点对点认证模块,实现欧拉嵌入式设备之间互联互通、欧拉嵌入式设备和 OpenHarmony 设备之间互联互通。 + +- **硬实时系统(UniProton)**:是一款实时操作系统,具备极致的低时延和灵活的混合关键性部署特性,可以适用于工业控制场景,既支持微控制器 MCU,也支持算力强的多核 CPU。 + +## SysCare 热补丁能力 + +SysCare 是一个系统级热修复软件,为操作系统提供安全补丁和系统错误热修复能力,主机无需重新启动即可修复该系统问题。SysCare 将内核态热补丁技术与用户态热补丁技术进行融合统一,用户仅需聚焦在自己核心业务中,系统修复问题交予 SysCare 进行处理。后期计划根据修复组件的不同,提供系统热升级技术,进一步解放运维用户提升运维效率。 + +**支持容器内构建补丁**: + +- 通过使用 ebpf 技术监控编译器进程,实现无需创建字符设备、纯用户态化获取热补丁变化信息,并允许用户在多个不同容器内进行并行热补丁编译。 + +- 用户可以通过安装不同 rpm 包(syscare-build-kmod 或 syscare-build-ebpf)来选择使用 ko 或者 ebpf 实现,syscare-build 进程将会自适应相应底层实现。 + +## GCC for openEuler + +GCC for openEuler 基线版本从 GCC 10.3 升级到 GCC 12.3 版本,支持自动反馈优化、软硬件协同、内存优化、SVE向量化、矢量化数学库等特性。 + +- GCC 版本升级到 12.3,默认语言标准从 14 升级到 C17/C++17 标准,支持 Armv9-a 架构,X86 的 AVX512 FP16 等更多硬件架构特性。 + +- 支持结构体优化,指令选择优化等,充分使能 ARM 架构的硬件特性,运行效率更高,在 SPEC CPU 2017 等基准测试中性能大幅优于上游社区的 GCC 10.3 版本。 + +- 支持自动反馈优化特性,实现应用层 MySQL 数据库等场景性能大幅提升。 + +## A-Ops智能运维 + +IT基础设施和应用产生的数据量快速增长(每年增长2~3倍),应用大数据和机器学习技术日趋成熟,驱动高效智能运维系统产生,助力企业降本增效。openEuler 智能运维提供智能运维基本框架,支持 CVE 管理、异常检测(数据库场景)等基础能力,支持快速排障和运维成本降低。 + +- **智能补丁管理**:支持补丁服务、内核热修复、智能补丁巡检、冷热补丁混合管理。 + +- **异常检测**:提供 MySQL、openGauss 业务场景中出现的网络 I/O 时延、丢包、中断等故障以及磁盘 I/O 高负载故障检测能力。 + +- **配置溯源**:支持集群配置收集和基线能力,实现配置可管可控。对整体集群实现配置检查,实时与基线进行对比,快速识别未经授权的配置变更,实现故障快速定位。 + +## A-Ops gala 特性 + +GALA 项目将全面支持 K8S 场景故障诊断,提供包括应用 drill-down 分析、微服务& DB 性能可观测、云原生网络监控、云原生性能 Profiling、进程性能诊断等特性,支撑 OS 五类问题(网络、磁盘、进程、内存、调度)分钟级诊断。 + +- **DDE服务器版本优化K8S环境易部署**:gala-gopher 提供 daemonset 方式部署,每个 Work Node 部署一个 gala-gopher 实例;gala-spider、gala-anteater 以容器方式部署至 K8S 管理 Node。 + +- **应用drill-down分析**:提供云原生场景中亚健康问题的故障诊断能力,分钟级完成应用与云平台之间问题定界能力。 + +- **全栈监控**:提供面向应用的精细化监控能力,覆盖语言运行时(JVM)、GLIBC、系统调用、内核(TCP、I/O、调度等)等跨软件栈观测能力,实时查看系统资源对应用的影响。 + +- **全链路监控**:提供网络流拓扑(TCP、RPC)、软件部署拓扑信息,基于这些信息构建系统 3D 拓扑,精准查看应用依赖的资源范围,快速识别故障半径。 + +- **GALA因果型AI**:提供可视化根因推导能力,分钟级定界至资源节点。 + +- **微服务&DB性能可观测**:提供非侵入式的微服务、DB 访问性能可观测能力,包括 HTTP 1.x 访问性能可观测,性能包括吞吐量、时延、错误率等,支持 API 精细化可观测能力,以及 HTTP Trace 能力,便于查看异常 HTTP 请求过程。 + +- **PGSQL访问性能可观测**:性能包括吞吐量、时延、错误率等,支持基于 SQL 访问精细化观测能力,以及慢 SQL Trace 能力,便于查看慢 SQL 的具体 SQL 语句。 + +- **云原生应用性能Profiling**:提供非侵入、零修改的跨栈 profiling 分析工具,并能够对接 pyroscope 业界通用UI前端。 + +- **云原生网络监控**:针对 K8S 场景,提供 TCP、Socket、DNS 监控能力,具备更精细化网络监控能力。 + +- **GALA因果型AI**:提供可视化根因推导能力,分钟级定界至资源节点。 + +- **进程性能诊断**:针对云原生场景的中间件(比如 MySQL、Redis 等)提供进程级性能问题诊断能力,同时监控进程性能 KPI、进程相关系统层 Metrics(比如I/O、内存、TCP等),完成进程性能 KPI 异常检测以及影响该KPI的系统层 Metrics。 + +## sysMaster 特性 + +sysMaster 是一套超轻量、高可靠的服务管理程序集合,是对 1 号进程的全新实现,旨在改进传统的 init 守护进程。它使用 Rust 编写,具有故障监测、秒级自愈和快速启动等能力,从而提升操作系统可靠性和业务可用度。本次发布的 0.5.0 版本,支持在容器、虚机两种场景下,以 sysMaster 的方式管理系统中的服务。 + +- 支持devMaster组件,用于管理设备热插拔。 + +- 支持sysMaster热升级、热重启功能。 + +- 支持在虚机中以1号进程运行。 + +## utsudo 项目 + +utsudo 是一个采用 Rust 重构 Sudo 的项目,旨在提供一个更加高效、安全、灵活的提权工具,涉及的模块主要有通用工具、整体框架和功能插件等。 + +- **访问控制**:根据需求限制用户可以执行的命令,并规定所需的验证方式。 + +- **审计日志**:记录和追踪每个用户使用 utsudo 执行的命令和任务。 + +- **临时提权**:允许普通用户通过输入自己的密码,临时提升为超级用户执行特定的命令或任务。 + +- **灵活配置**:设置参数如命令别名、环境变量、执行参数等,以满足复杂的系统管理需求。 + +## utshell 项目 + +utshell 是一个延续了 bash 使用习惯的全新 shell,它能够与用户进行命令行交互,响应用户的操作去执行命令并给予反馈。并且能执行自动化脚本帮助运维。 + +- **命令执行**:执行部署在用户机器上的命令,并将执行的返回值反馈给用户。 + +- **批处理**:通过脚本完成自动任务执行。 + +- **作业控制**:能够将用户命令作为后台作业,从而实现多个命令同时执行。并对并行执行的任务进行管理和控制。 + +- **历史记录**:记录用户所输入的命令。 + +- **别名功能**:能够让用户对命令起一个自己喜欢的别名,从而个性化自己的操作功能。 + +## migration-tools 项目 + +migration-tools 是一款操作系统迁移软件,面向已部署业务应用于其他操作系统且具有国产化替换需求的用户,帮助其快速、平滑、稳定且安全地迁移至 openEuler 系操作系统。迁移软件的系统架构分为以下模块。 + +- **Server 模块**,迁移的软件的核心,采用 pythonflaskweb 框架研发,负责接收任务请求,同时处理相关执行指令并分发至各 Agent。 + +- **Agent模块**,安装在待迁移的操作系统中,负责接收Server发出的任务请求,执行迁移等功能。 + +- **配置模块**,为 Server 模块和 Agent 模块提供配置文件的读取功能。 + +- **日志模块**,提供迁移的全部运行过程记录日志。 + +- **迁移评估模块**,提供迁移前的基础环境检测、软件包对比分析、ABI 兼容性检测等评估报告,为用户的迁移工作提供依据。 + +- **迁移功能模块**,提供一键迁移、迁移进度展示、迁移结果判断等功能。 + +## DDE组件 + +统信桌面环境(DDE)专注打磨产品交互、视觉设计,拥有桌面环境的核心技术,主要功能包含:登录锁屏、桌面及文件管理器、启动器、任务栏(DOCK)、窗口管理器、 控制中心等。由于界面美观、交互优雅、安全可靠、尊重隐私,一直是用户首选 桌面环境之一,用户可以使用它进行办公与娱乐,在工作中发挥创意和提高效率,和亲朋好友保持联系,轻松浏览网页、享受影音播放。 + +## Kmesh 项目 + +Kmesh 基于可编程内核,将服务治理下沉OS,实现高性能服务网格数据面,服务间通信时延对比业界方案提升5倍。 + +- 支持对接遵从 XDS 协议的网格控制面(如 istio)。 + +- **流量编排能力**,支持轮询等负载均衡策略;支持L4、L7路由规则;支持百分比灰度方式选择后端服务策略。 + +- **sockamp 网格加速能力**,以典型的 service mesh 场景为例,使能 sockmap 网格加速能力之后,业务容器和 envoy 容器之间的通信将被ebpf程序短接,通过缩短通信路径从而达到加速效果,对于同节点上 Pod 间通信也能通过 ebpf 程序进行加速。 + +## RISC-V 架构 QEMU 镜像 + +openEuler 23.09 版本中发布了官方支持的 RISC-V 架构的操作系统。该版本的操作系统底座旨在为上层应用程序提供基础支持,具备高度可定制性、灵活性和安全性。它为 RISC-V 架构的计算平台提供稳定、可靠的操作环境,方便用户进行上层应用的安装和验证,共同推动 RISC-V 架构下软件生态的丰富和质量的提升。 + +- 该操作系统底座的功能包括升级到 6.4.0 版本的内核,与主流架构保持一致。 + +- 提供稳定的基础系统底座,包括处理器管理、内存管理、任务调度、设备驱动等核心功能,以及常用的工具等。 + +## 动态完整性度量特性 + +DIM(Dynamic Integrity Measurement)动态完整性度量特性通过在程序运行时对内存中的关键数据(如代码段)进行度量,并将度量结果和基准值进行对比,确定内存数据是否被篡改,从而检测攻击行为,并采取应对措施。 + +- 支持度量用户态进程、内核模块、内核内存代码段数据。 + +- 支持将度量结果扩展至 TPM 2.0 芯片 PCR 寄存器,用于对接远程证明。 + +- 支持配置度量策略,支持度量策略签名校验。 + +- 支持工具生成并导入度量基线数据,支持基线数据签名校验。 + +- 支持配置国密 SM3 度量算法。 + +## Kuasar 统一容器运行时特性 + +Kuasar 是一款支持多种类型沙箱统一管理的容器运行时,可同时支持业界主流的多钟沙箱隔离技术,openEuler 基于 Kuasar 统一容器运行时并结合已有 openEuler 生态中 iSulad 容器引擎和 StratoVirt 虚拟化引擎技术,打造面向云原生场景轻量级全栈自研的安全容器极低底噪、极速启动的关键竞争力。 + +本次发布的 Kuasar 0.1.0 版本,支持 StratoVirt 类型轻量级虚拟机沙箱,支持通过 K8S+iSulad 创建 StratoVirt 类型的安全容器实例。 + +- 支持 iSulad 容器引擎对接 Kuasar 容器运行时,兼容 K8S 云原生生态。 + +- 支持基于 StratoVirt 类型轻量级虚拟机沙箱技术创建安全容器沙箱。 + +- 支持 StratoVirt 类型安全容器进行资源精准限制管理。 + +## sysBoost 项目 + +sysBoost 是一个为应用进行系统微架构优化的工具,优化涉及汇编指令、代码布局、数据布局、内存大页、系统调用等方面。 + +- **二进制文件合并**:目前只支持全静态合并场景,将应用与其依赖的动态库合并为一个二进制,并进行段级别的重排,将多个离散的代码段/数据段合并为一个,提升应用性能。 + +- **sysBoost 守护进程服务**:sysBoost 使用注册 systemd 服务的方式使性能开箱最优,系统启动后,systemd将会拉起sysBoost守护进程,sysBoost 守护进程读取配置文件获取需要优化的二进制以及对应的优化方式。 + +- **rto二进制加载内核模块**:采用新增二进制加载模块的方法,在内核加载二进制时自动加载优化的二进制。 + +- **二进制代码段/数据段大页预加载**:sysBoost 提供大页预加载的功能,在二进制优化完成后立即将其内容以大页形式加载到内核中,在应用启动时将预加载的内容批量映射到用户态页表,减少应用的缺页中断和访存延迟,提升启动速度和运行效率。 + +## CTinspector 项目 + +CTinspector 是天翼云科技有限公司基于 ebpf 指令集自主创新研发的语言虚拟机运行框架。基于 CTinspector 运行框架可以快速拓展其应用实例用于诊断网络性能瓶颈点,诊断存储 I/O 处理的热点和负载均衡等,提高系统运行时诊断的稳定性和时效性。 + +- 采用一个 ebpf 指令集的语言虚拟机 Packet VM,它最小只有 256 字节,包含所有虚拟机应有的部件:寄存器,堆栈段,代码段,数据段,页表。 + +- Packet VM 支持自主的 migration,即 packet VM 内的代码可以调用 migrate kernel function,以将 packet VM 迁移至它自己指定的节点。 + +- Packet VM 同时支持断点续执行,即 packet VM 迁移至下一个节点后可以沿着上一个节点中断的位置继续执行下一条指令。 + +## CVE-ease 项目 + +CVE-ease 是天翼云自主创新开发的一个专注于CVE信息的平台,它搜集了多个安全平台发布的各种 CVE 信息,并通过邮件、微信、钉钉等多种渠道及时通知用户。CVE-ease 平台旨在帮助用户快速了解和应对系统中存在的漏洞,在提高系统安全性和稳定性的同时,用户可以通过 CVE-ease 平台查看 CVE 信息的详细内容,包括漏洞描述、影响范围、修复建议等,并根据自己的系统情况选择合适的修复方案。 + +目前 CVE-ease 主要包括以下功能: + +- CVE 信息动态获取和整合,实时跟踪多平台 CVE 披露信息,并进整合放入 CVE 数据库。 + +- CVE 信息提取和更新,对收集到的 CVE 信息提取关键信息并实时更新发生变更的 CVE。 + +- CVE 数据保存和管理,自动维护和管理 CVE 数据库。 + +- 历史 CVE 信息查看,通过交互方式查询各种条件的 CVE。 + +- CVE 信息实时播报,通过企业微信、钉钉、邮箱等方式实时播报历史CVE信息。 + +## PilotGo运维管理平台特性 + +PilotGo 是 openEuler 社区原生孵化的运维管理平台,采用插件式架构设计,功能模块轻量化组合、独立迭代演进,同时保证核心功能稳定;同时使用插件来增强平台功能,并打通不同运维组件之间的壁垒,实现了全局的状态感知及自动化流程。 + +PilotGo核心功能模块包括: + +- **用户管理**:支持按照组织结构分组管理,支持导入已有平台账号,迁移方便。 + +- **权限管理**:支持基于 RBAC 的权限管理,灵活可靠。 + +- **主机管理**:状态前端可视化、直接执行软件包管理、服务管理、内核参数调优、简单易操作。 + +- **批次管理**:支持运维操作并发执行,稳定高效。 + +- **日志审计**:跟踪记录用户及插件的变更操作,方便问题回溯及安全审计。 + +- **告警管理**:平台异常实时感知。 + +- **平台异常实时感知**:支持扩展平台功能,插件联动,自动化能力倍增,减少人工干预。 + +## CPDS 支持对容器 TOP 故障、亚健康检测的监测与识别 + +云原生技术的广泛应用,致使现代应用部署环境越来越复杂。容器架构提供了灵活性和便利性,但也带来了更多的监测和维护挑战。CPDS(容器故障检测系统)应运而生,旨在为容器化应用提供可靠性和稳定性的保障。 + +- **集群信息采集**:在宿主机上实现节点代理,采用 systemd、initv、ebpf 等技术,对容器关键服务进行监控,采集集群基础服务类数据;对节点网络、内核、磁盘 LVM 等相关信息进行监控,采集集群 OS 类异常数据;采用无侵入的方式在节点、容器内设置跨NS的代理,针对对应用状态、资源消耗情况、关键系统函数执行情况、IO 执行状态等执行异常进行监控,采集业务服务异常类数据。 + +- **集群异常检测**:处理各节点原始数据,基于异常规则对采集的原始数据进行异常检测,提取关键信息。同时基于异常规则对采集数据进行异常检测,后将检测结果数据和原始据进行在线上传,并同步进行持久化操作。 + +- **节点、业务容器故障/亚健康诊断**:基于异常检测数据,对节点、业务容器进行故障/亚健康诊断,将分析检测结果进行持久化存储,并提供 UI 层进行实时、历史的诊断数据查看。 + +## EulerMaker 构建系统 + +EulerMaker 构建系统是一款软件包构建系统,完成源码到二进制软件包的构建,并支持开发者通过搭积木的方式,组装和定制出适合自己需求的场景化 OS。主要提供增量/全量构建,分层定制与镜像定制的能力。 + +- **增量/全量构建**:基于软件包变化,结合软件包依赖关系,分析影响范围,得到待构建软件包列表,按照依赖顺序并行下发构建任务。 + +- **构建依赖查询**:提供工程中软件包构建依赖表,支持筛选及统计软件包依赖及被依赖的软件包内容。 + +- **分层定制**:支持在构建工程中,通过选择与配置层模型,实现对软件包的patch,构建依赖,安装依赖,编译选项等内容的定制,完成针对软件包的场景化定制。 + +- **镜像定制**:支持开发者通过配置 repo 源,生成 iso、qcow2、容器等 OS 镜像,并支持对镜像进行软件包列表定制。 diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/known-issues.md b/docs/en/25.03/Server/Releasenotes/Releasenotes/known-issues.md new file mode 100644 index 0000000000000000000000000000000000000000..47c4f2d8b861b794e432f25261178779ebf2a4bb --- /dev/null +++ b/docs/en/25.03/Server/Releasenotes/Releasenotes/known-issues.md @@ -0,0 +1,10 @@ +# 已知问题 + +| 序号 | 问题单号 | 问题简述 | 问题级别 | 影响分析 | 规避措施 | 历史发现场景 | +| ---- | ------- | -------- | -------- | ------- | -------- | --------- | +| 1 | [I5LZXD](https://gitee.com/src-openEuler/openldap/issues/I5LZXD) | openldap build problem in openEuler:22.09 | 次要 | 构建过程中,用例执行失败。为用例设计问题,影响可控,通过sleep的方式等待操作执行完成,在高负载下偶先失败 | skip相关用力,并持续跟踪上游社区解决 | | +| 2 | [I5NLZI](https://gitee.com/src-openEuler/dde/issues/I5NLZI) | 【openEuler 22.09 rc2】启动器中个别应用图标显示异常 | 次要 | 仅为DDE桌面启动器的图标显示异常,无功能影响,易用性问题整体影响可控 | 建议切换主题规避 | | +| 3 | [I5P5HM](https://gitee.com/src-openEuler/afterburn/issues/I5P5HM) | 【22.09_RC3_EPOL】【arm/x86】卸载afterburn提示Failed to stop afterburn-sshkeys@.service | 次要 | | | | +| 4 | [I5PQ3O](https://gitee.com/src-openEuler/openmpi/issues/I5PQ3O) | 【openEuler-22.09-RC3】ompi-clean -v -d参数执行报错 | 主要 | 该包为NestOS使用软件包,使用范围较为局限,默认为 NestOS 中的“core”用户启用,对服务器版本影响较小 | sig暂未提供规避手段 | | +| 5 | [I5Q2FE](https://gitee.com/src-openEuler/udisks2/issues/I5Q2FE) | udisks2 build problem in openEuler:22.09 | 次要 | 构建过程中,用例执行失败。环境未保留,长期本地构建未复现 | 持续跟踪社区构建成功率 | | +| 6 | [I5SJ0R](https://gitee.com/src-openEuler/podman/issues/I5SJ0R) | [22.09RC5 arm/x86]podman create --blkio-weight-device /dev/loop0:123:15 fedora ls 执行报错 | 次要 | blkio-weight为4.xx版本内核特性。5.10版本不支持 | 需跟进升级podman组件 | | diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-caution.gif b/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-caution.gif differ diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-danger.gif b/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-danger.gif differ diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-note.gif b/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-notice.gif b/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-notice.gif differ diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-tip.gif b/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-tip.gif differ diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-warning.gif b/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Releasenotes/Releasenotes/public_sys-resources/icon-warning.gif differ diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/release_notes.md b/docs/en/25.03/Server/Releasenotes/Releasenotes/release_notes.md new file mode 100644 index 0000000000000000000000000000000000000000..1578f3aa8364f52da274a503bc815db8da894b99 --- /dev/null +++ b/docs/en/25.03/Server/Releasenotes/Releasenotes/release_notes.md @@ -0,0 +1,3 @@ +# 发行说明 + +本文档是 openEuler 22.09 版本的发行说明。 diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/resolved-issues.md b/docs/en/25.03/Server/Releasenotes/Releasenotes/resolved-issues.md new file mode 100644 index 0000000000000000000000000000000000000000..0f1e2ca427bd1e631b4c6eec858e20829fba8fd0 --- /dev/null +++ b/docs/en/25.03/Server/Releasenotes/Releasenotes/resolved-issues.md @@ -0,0 +1,15 @@ +# 已修复问题 + +完整问题清单请参见[完整问题清单](https://gitee.com/organizations/src-openeuler/issues)。 + +完整的内核提交记录请参见[提交记录](https://gitee.com/openeuler/kernel/commits/openEuler-21.03)。 + +已修复问题请参见[表1](#table249714911433)。 + +**表 1** 修复问题列表 + +| ISSUE |问题描述 | +|:--- |:---- | +|[I5J302](https://gitee.com/open_euler/dashboard?issue_id=I5J302)|【安装冲突arm/x86_64】openEuler:22.09分支fwupd与dbxtool包安装冲突| +|[I5J36Q](https://gitee.com/open_euler/dashboard?issue_id=I5J36Q)|【安装冲突 arm/x86_64】python3-wrapt在22.09分支存在安装冲突| +|[I5J3K1](https://gitee.com/open_euler/dashboard?issue_id=I5J3K1)|【安装冲突arm/x86_64】openEuler:22.09分支mariadb与mysql包安装冲突| diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/source-code.md b/docs/en/25.03/Server/Releasenotes/Releasenotes/source-code.md new file mode 100644 index 0000000000000000000000000000000000000000..d6fc6ff3afb3c8bf3d099e72a76d4c3587a0ff39 --- /dev/null +++ b/docs/en/25.03/Server/Releasenotes/Releasenotes/source-code.md @@ -0,0 +1,8 @@ +# 源代码 + +openEuler主要包含两个代码仓库: + +- 代码仓:[https://gitee.com/openeuler](https://gitee.com/openeuler) +- 软件包仓:[https://gitee.com/src-openeuler](https://gitee.com/src-openeuler) + +openEuler发布件同时也提供source iso,具体请参见“系统安装”的内容。 diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/terms-of-use.md b/docs/en/25.03/Server/Releasenotes/Releasenotes/terms-of-use.md new file mode 100644 index 0000000000000000000000000000000000000000..440c626c2f65b5553291e3b309486e4d3c64acbd --- /dev/null +++ b/docs/en/25.03/Server/Releasenotes/Releasenotes/terms-of-use.md @@ -0,0 +1,13 @@ +# 法律声明 + +**版权所有 © 2023 openEuler社区** + +您对“本文档”的复制、使用、修改及分发受知识共享\(Creative Commons\)署名—相同方式共享4.0国际公共许可协议\(以下简称“CC BY-SA 4.0”\)的约束。为了方便用户理解,您可以通过访问[https://creativecommons.org/licenses/by-sa/4.0/](https://creativecommons.org/licenses/by-sa/4.0/)了解CC BY-SA 4.0的概要 \(但不是替代\)。CC BY-SA 4.0的完整协议内容您可以访问如下网址获取:[https://creativecommons.org/licenses/by-sa/4.0/legalcode](https://creativecommons.org/licenses/by-sa/4.0/legalcode)。 + +**商标声明** + +文档中提及的商标或注册商标,由各自所有人拥有。对openEuler商标的使用,应当遵从[openEuler品牌使用规范](https://www.openeuler.org/zh/other/brand/)。 + +**免责声明** + +本文档仅作为使用指导,除非适用法强制规定或者双方有明确书面约定, openEuler社区对本文档中的所有陈述、信息和建议不做任何明示或默示的声明或保证,包括但不限于不侵权、时效性或满足特定目的的担保。 diff --git a/docs/en/25.03/Server/Releasenotes/Releasenotes/user-notice.md b/docs/en/25.03/Server/Releasenotes/Releasenotes/user-notice.md new file mode 100644 index 0000000000000000000000000000000000000000..19ad23cf5fda65d4a6057b33c9cdb5ce3691d424 --- /dev/null +++ b/docs/en/25.03/Server/Releasenotes/Releasenotes/user-notice.md @@ -0,0 +1,5 @@ +# 用户须知 + +- openEuler版本号计数规则由openEuler x.x变更为以年月为版本号,以便用户了解版本发布时间,例如openEuler 21.03表示发布时间为2021年3月。 +- [Python核心团队](https://www.python.org/dev/peps/pep-0373/#update)已经于2020年1月停止对Python 2的维护。2021年,openEuler 21.03版本仅修复Python 2的致命CVE。 +- 从openEuler 22.03-LTS版本开始,停止支持和维护Python 2,仅支持Python 3,请您切换并使用Python 3。 diff --git a/docs/en/25.03/Server/Security/CVE-ease/_menu.md b/docs/en/25.03/Server/Security/CVE-ease/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..6d14244809d3bd39fd748cbc3c82a319581fb250 --- /dev/null +++ b/docs/en/25.03/Server/Security/CVE-ease/_menu.md @@ -0,0 +1,10 @@ +--- +label: 'CVE-ease设计指南' +ismanual: 'Y' +description: '帮助用户快速应对系统漏洞' +children: + - label: 'CVE-ease设计介绍' + href: './cve-ease-design-introduction.md' + - label: 'CVE-ease介绍和安装说明' + href: './cve-ease-introduction-and-installation-instructions.md' +--- diff --git a/docs/en/25.03/Server/Security/CVE-ease/cve-ease-design-introduction.md b/docs/en/25.03/Server/Security/CVE-ease/cve-ease-design-introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..e3649141a70900c60e029f35e94df942f0b6b97b --- /dev/null +++ b/docs/en/25.03/Server/Security/CVE-ease/cve-ease-design-introduction.md @@ -0,0 +1,33 @@ +# CVE-ease设计介绍 + +## 概述 + +CVE(通用漏洞披露)是关乎系统安全稳定的关键信息,因此对CVE信息的处理和管理就显得尤为重要。基于此,开发CVE-ease的CVE漏洞管理系统,以实现漏洞信息实时获取、管理和播报。 + +## 主要功能 + +CVE-ease主要有以下功能: + +* CVE信息获取和分析 +* CVE信息整理和存放 +* 历史CVE和实时CVE信息查看 +* CVE状态实时跟踪 +* CVE动态信息实时播报 + +## 模块功能 + +![](./figures/CVE-ease_desigin_table.png) + +### 3.1 CVE获取 + +当CVE-ease运行时,系统会按照特定时间间隔从CVE披露网站抓取CVE信息。抓取CVE信息前,需要对CVE数据库进行扫描。建立已有CVE编号的索引,并测试系统和各CVE平台是否连通。抓取过程中,首先抓取最新披露的CVE信息编号,再根据CVE编号抓取CVE描述等具体信息,如果信息正常抓取到,流程结束。否则重新执行抓取,直到抓取到。 + +### 3.2 CVE信息整理和存放 + +抓取到的CVE需要进行整理,按照特定的数据结构放入数据库,并计算特征值。如果爬取到的CVE编号不存在于数据库中,则直接放入漏洞数据库,如果存在,则对比特征值是否一致,不一致则根据差异对该条CVE内容进行更新。 + +### 3.3 历史CVE和实时CVE信息查看 + +在用户交互界面,可以通过交互指令查询特定的CVE信息。默认展示的是最新的前10条CVE信息,也可通过修改指令选项来查询特定范围的历史CVE信息(CVE分数,年份等)。 + +![](./figures/CVE-ease_function.png) diff --git a/docs/en/25.03/Server/Security/CVE-ease/cve-ease-introduction-and-installation-instructions.md b/docs/en/25.03/Server/Security/CVE-ease/cve-ease-introduction-and-installation-instructions.md new file mode 100644 index 0000000000000000000000000000000000000000..92090a72f8ed7a355fd642dac5b413159bafb87e --- /dev/null +++ b/docs/en/25.03/Server/Security/CVE-ease/cve-ease-introduction-and-installation-instructions.md @@ -0,0 +1,567 @@ +# CVE-ease project + +## 项目介绍 + +CVE-ease +是一个专注于CVE信息的平台,它搜集了社区发布的各种CVE信息,并通过邮件、微信、钉钉等多种渠道及时通知用户。用户可以通过CVE-ease平台查看CVE信息的详细内容,包括漏洞描述、影响范围、修复建议等,并根据自己的系统情况选择合适的修复方案。 + +CVE-ease 平台旨在帮助用户快速了解和应对系统中存在的漏洞,提高系统安全性和稳定性。 + +CVE-ease 是**天翼云自主创新项目**,它已经在欧拉社区开放源码,严格遵循**Mulan PSL2**开源规范,期待社区的朋友们加入项目开发,共同打造一个安全、稳定、可靠的国产操作系统生态。 + +开源说明: + +* 本仓库**严格**遵循 [木兰宽松许可证, 第2版](http://license.coscl.org.cn/MulanPSL2)。 +* **本仓库严格遵守 天翼云科技有限公司 开源规范,经过严格的审核和准备,提交优质开源项目,相关的文档和资料都皆以齐备**。 +* 本仓库由公司指派专人负责,**LTS长期跟进维护**,持续孵化产出。 + +## 软件架构 + +CVE-ease是一个专注于CVE信息的平台,它的架构主要由四个模块组成,分别是CVE爬虫、CVE分析器、CVE通知器和CVE前端。下面我们分别介绍这四个模块的功能和设计。 + +* CVE爬虫 + +这个模块负责从openEuler社区提供的各个CVE数据源抓取CVE信息,并将其存储到MySQL等关系型数据库中。这些关键信息主要来源于cve-manager项目。目前,cve-manager支持从以下数据源获取CVE信息:NVD、CNNVD、CNVD、RedHat、Ubuntu、Debian等。CVE-ease使用Python编写了多个爬虫脚本,每个脚本对应一个数据源,可以定时或手动运行。爬虫脚本会将抓取到的原始CVE信息格式化后持久化存储,以便后续的分析和处理。 + +* CVE分析器 + +这个模块负责对CVE信息进行解析、归类、评分等操作。CVE-ease使用Python编写了一个分析器脚本,它会定期从关系型数据库中读取原始CVE信息,并进行以下操作:解析CVE信息的基本属性(如编号、标题、描述等)、归类CVE信息的影响范围(如操作系统、软件包等)、评分CVE信息的危害程度(如CVSS评分等)、匹配CVE信息的修复建议(如补丁链接等)。分析器脚本会将处理后的结构化CVE信息以SQL格式持久化到数据库中,以便后续的查询和展示。 + +* CVE通知器 + +这个模块负责根据用户的订阅配置,通过邮件、微信、钉钉等方式发送CVE通知给用户。CVE-ease使用Python编写了一个通知器脚本,它会定期从MySQL数据库中读取结构化CVE信息,并进行以下操作:过滤出用户关注的影响范围(如操作系统、软件包等)、生成适合不同渠道的通知内容(如文本、图片等)、调用不同渠道的API发送通知给用户(如SMTP协议发送邮件、HTTP协议发送微信或钉钉消息等)。通知器脚本会记录发送结果和反馈情况,并更新MySQL数据库中的订阅状态。 + +* CVE前端 + +这个模块负责提供一个友好的cli终端命令,让用户可以查看、搜索、订阅CVE信息。 + +CVE-ease的架构设计旨在实现高效、灵活、可扩展的CVE信息平台,为用户提供及时准确地安全漏洞情报服务。 + +## 研发规划 + +1. repodata 适配多厂家 OSV( Operating System Software Provider ) +2. motd 登录播报功能 +3. dnf 插件扩展修复功能 +4. 自动修复特定包功能 +5. 增加特定包感知功能 +6. ... + +**我们非常欢迎您对 CVE-ease 研发方向的宝贵意见,如果您有任何想法或建议,请不要犹豫,尽情地与我们分享,我们将十分感激~** + +## 安装教程 + +目前CVE-ease处于快速迭代研发阶段,支持的安装方式有,直接安装,容器安装,rpm包安装。 + +### 直接安装 + +```shell +git clone https://gitee.com/openeuler/cve-ease cve-ease.git +cd cve-ease.git/cve-ease +make install +``` + +### 容器安装 + +```shell +git clone https://gitee.com/openeuler/cve-ease cve-ease.git +cd cve-ease.git/cve-ease +make run-in-docker +``` + +### rpm包安装 + +```shell +git clone https://gitee.com/openeuler/cve-ease cve-ease.git +cd cve-ease.git/cve-ease +make gensrpm +cd .. +rpm -ivh *.src.rpm +cd ~/rpmbuild +rpmbuild -ba SPECS/cve-ease.spec +cd RPMS/noarch +rpm -ivh *.rpm +``` + +## 使用说明 + +### 帮助信息 + +* cve-ease命令不带任何参数,则显示帮助信息。 +* cve-ease子命令有多个,按类别分为basic、info、notifier。 +* help子命令用于显示不同类别命令帮助信息。 + +```shell +# cve-ease + +Available commands: + +basic commands: + config Print cve-ease config + daemon Run as daemon without interactive + motd Motd info manager + service Service manager + +info commands: + cve OpenEuler CVE info + cvrf OpenEuler CVRF info + db Database manager + help List available commands + logger Logger config + repodata Repodata info + rpm Rpm info + sa OpenEuler security notice info + +notifier commands: + dingding Notifier of dingding + feishu Notifier of feishu + mail163 Notifier of mail163 + mailqq Notifier of mailqq + wecom Notifier of wecom + +Try "cve-ease --help" for help about global gconfig +Try "cve-ease help" to get all available commands +Try "cve-ease --help" for help about the gconfig of a particular command +Try "cve-ease help " to get commands under a particular category +Available commands are: basic, info, notifier + +# cve-ease help info +Available commands: + +info commands: + cve OpenEuler CVE info + cvrf OpenEuler CVRF info + db Database manager + help List available commands + logger Logger config + repodata Repodata info + rpm Rpm info + sa OpenEuler security notice info + +Try "cve-ease --help" for help about global gconfig +Try "cve-ease help" to get all available commands +Try "cve-ease --help" for help about the gconfig of a particular command +Try "cve-ease help " to get commands under a particular category +Available commands are: basic, info, notifier +``` + +### 配置文件 + +配置文件位于 ```/etc/cve-ease/cve-ease.cfg```: + +```shell +[main] +pid_file_path = /var/log/cve-ease/cve-ease.pid +lock_file_path = /var/log/cve-ease/cve-ease.lock + +# log configuration + +# debug/ error(default) / warn +log_level = debug +log_file_path = /var/log/cve-ease/cve-ease.log +log_maxbytes = 10240 +log_backup_num = 30 + +# sql configuration +db_type = sqlite +db_file_path = /usr/share/cve-ease/cve-ease.db +db_user = +db_password = +db_host = +db_port = +product = openEuler-23.09 +expiration_days = 14 + +# notifier +notifier_record_num = 9 + +# filter +focus_on = kernel,systemd,openssh,openssl + +[wecom] +enabled = 1 +# https://developer.work.weixin.qq.com/document/path/91770?version=4.0.19.6020&platform=win +# https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=fe9eae1f-xxxx-4ae3-xxxx-ecf9f77abba6 + +update_key = 2142ef2a-d99d-417d-8c31-b550b0fcb4e3 +status_key = 2142ef2a-d99d-417d-8c31-b550b0fcb4e3 + + +[dingding] +enabled = 1 +# just for test +update_key = 81907155a6cc88004e1ed6bcdd86c68d5b21565ed59d549ca031abc93d90d9cb +status_key = 81907155a6cc88004e1ed6bcdd86c68d5b21565ed59d549ca031abc93d90d9cb + + +[feishu] +enabled = 1 +# just for test +update_key = 5575739b-f59d-48db-b737-63672b2c32ab +status_key = 5575739b-f59d-48db-b737-63672b2c32ab + + +[mail163] +enabled = 0 +mail_sender = xxxxxxx@163.com +mail_recver = xxxxxxx@163.com +mail_smtp_token = xxxxxx + + +[mailqq] +enabled = 0 +mail_sender = xxxxxxx@qq.com +mail_recver = xxxxxxx@qq.com +mail_smtp_token = xxxxxxxx +``` + +### CVE-ease服务 + +CVE-ease服务包含 cve-ease.service 和 cve-ease.timer 两个文件,基于systemd timer机制实现周期周期执行。 + +```shell +# /usr/lib/systemd/system/cve-ease.timer +# CTyunOS cve-ease: MulanPSL2 +# +# This file is part of cve-ease. +# + +[Unit] +Description=CTyunOS cve-ease Project +Documentation=https://gitee.com/openeuler/cve-ease + +[Timer] +OnBootSec=1m +OnUnitActiveSec=10m +RandomizedDelaySec=10 + +[Install] +WantedBy=timers.target +``` + +```shell +# systemctl enable --now cve-ease.timer +Created symlink /etc/systemd/system/timers.target.wants/cve-ease.timer → /usr/lib/systemd/system/cve-ease.timer. +# systemctl status cve-ease.timer +● cve-ease.timer - CTyunOS cve-ease Project + Loaded: loaded (/usr/lib/systemd/system/cve-ease.timer; enabled; vendor preset: disabled) + Active: active (waiting) since Sat 2023-03-18 17:55:53 CST; 5s ago + Trigger: Sat 2023-03-18 18:05:55 CST; 9min left + Docs: https://gitee.com/openeuler/cve-ease + +Mar 18 17:55:53 56d941221b41 systemd[1]: Started CTyunOS cve-ease Project. +# systemctl status cve-ease.service +● cve-ease.service - CTyunOS cve-ease project + Loaded: loaded (/usr/lib/systemd/system/cve-ease.service; disabled; vendor preset: disabled) + Active: inactive (dead) since Sat 2023-03-18 17:55:56 CST; 5s ago + Docs: https://gitee.com/openeuler/cve-ease + Process: 196 ExecStart=/usr/bin/cve-ease daemon (code=exited, status=0/SUCCESS) + Main PID: 196 (code=exited, status=0/SUCCESS) + +Mar 18 17:55:53 56d941221b41 systemd[1]: Starting CTyunOS cve-ease project... +Mar 18 17:55:56 56d941221b41 systemd[1]: cve-ease.service: Succeeded. +Mar 18 17:55:56 56d941221b41 systemd[1]: Started CTyunOS cve-ease project. +``` + +### basic基础命令 + +#### config配置相关子命令 + +```shell +Usage: cve-ease config +(Specify the --help global option for a list of other help options) + +Options: + -h, --help show this help message and exit + -r, --rawdata print raw config file content +``` + +```shell +cve-ease config # 显示配置文件路径及有效配置 +cve-ease config -r # 显示配置文件路径及裸数据 +``` + +#### daemon服务 + +* daemon命令用户systemd service服务入口,一般不直接执行。 +* 该服务由对应cve-ease 的systemd timer服务定时执行。 + +```shell +# /usr/lib/systemd/system/cve-ease.service +# CTyunOS cve-ease: MulanPSL2 +# +# This file is part of cve-ease. +# + +[Unit] +Description=CTyunOS cve-ease project +Documentation=https://gitee.com/openeuler/cve-ease + +[Service] +Type=oneshot +ExecStart=/usr/bin/cve-ease daemon + +[Install] +WantedBy=multi-user.target +``` + +#### motd更新通知相关子命令 + +* TODO 待实现。 + +#### service相关子命令 + +CVE-ease服务的相关控制命令: + +```shell +Usage: cve-ease service +(Specify the --help global option for a list of other help options) + +Options: + -h, --help show this help message and exit + -k, --kill kill cve-ease service + -r, --restart restart cve-ease service + -s, --status get cve-ease service status + -v, --verbose show verbose output +``` + +```shell +cve-ease service -k # 暂停cve-ease服务 +cve-ease service -r # 重启cve-ease服务 +cve-ease service -s # 查看cve-ease服务状态 +``` + +### info信息类别命令 + +#### cve子命令 + +爬取openEuler社区CVE公告信息,地址: [openEuler 官方CVE公告](https://www.openeuler.org/zh/security/cve/) + +```shell +Usage: cve-ease cve +(Specify the --help global option for a list of other help options) + +Options: + -h, --help show this help message and exit + -r, --rawdata get cve cache and print raw data without write db + -m, --makecache get cve cache + -l, --list list all cve info + -t, --total get cve info statistics + -v, --verbose show verbose output +``` + +```shell +cve-ease cve -m # 爬取 CVE 信息并写入数据库 +cve-ease cve -l # 从数据库获取并格式化显示 CVE 信息 +cve-ease cve -t # 从数据库获取并显示 CVE 统计信息 +cve-ease cve -r # 爬取 CVE 信息并显示裸数据(未写入数据库) +``` + +#### sa子命令 + +爬取openEuler社区安全公告信息,地址: [openEuler 官方CVE公告](https://www.openeuler.org/zh/security/safety-bulletin/) + +```shell +Usage: cve-ease sa +(Specify the --help global option for a list of other help options) + +Options: + -h, --help show this help message and exit + -r, --rawdata get sa cache and print raw data without write db + -m, --makecache get sa cache + -l, --list list all sa info + -t, --total get sa info statistics + -v, --verbose show verbose output +``` + +```shell +cve-ease sa -m # 爬取 SA 信息并写入数据库 +cve-ease sa -l # 从数据库获取并格式化显示 SA 信息 +cve-ease sa -t # 从数据库获取并显示 SA 统计信息 +cve-ease sa -r # 爬取 SA 信息并显示裸数据(未写入数据库) +``` + +#### cvrf子命令 + +安全公告相关: + +```shell +cve-ease cvrf -m # 爬取 CVRF 信息并写入数据库 +cve-ease cvrf -l # 从数据库获取并格式化显示 CVRF 信息 +cve-ease cvrf -t # 从数据库获取并显示 CVRF 统计信息 +``` + +#### rpm子命令 + +```shell +Usage: cve-ease rpm +(Specify the --help global option for a list of other help options) + +Options: + -h, --help show this help message and exit + -l, --list list all rpm info + -v, --verbose show verbose output +``` + +```shell +cve-ease rpm -l # 调用rpm接口列出当前系统中已安装的rpm包信息 +``` + +#### repodata子命令 + +```shell +Usage: cve-ease repodata +(Specify the --help global option for a list of other help options) + +Options: + -h, --help show this help message and exit + -m, --makecache cache repodata to database + -p PRODUCT, --product=PRODUCT + specific product (work with --check) + --osv=OSV specific osv rpm release + -t, --total get total rpm statistics + -l, --list list all rpm + -c, --check check repo cve + -v, --verbose show verbose output +``` + +```shell +cve-ease repodata -p ctyunos2 -m # 选定ctyunos2作为OSV版本,缓存ctyunos2的源数据,写入数据库 +cve-ease repodata --osv ctyunos2 -p openEuler-23.09 -c # ctyunos2的源于openEuler源做比对 +cve-ease repodata -l # 列出数据库中包含的包信息 +cve-ease repodata -t # 获取数据库中源包的统计信息 +``` + +#### logger子命令 + +```shell +Usage: cve-ease logger +(Specify the --help global option for a list of other help options) + +Options: + -h, --help show this help message and exit + -l, --list list all logger info + -t, --total get logger statistics + -v, --verbose show verbose output +``` + +#### db子命令 + +```shell +Usage: cve-ease db +(Specify the --help global option for a list of other help options) + +Options: + -h, --help show this help message and exit + -p, --purge purge db and recreate it (Danger Operation) + -s, --stats get database statistics + -v, --verbose show verbose output +``` + +### notifier消息通知类命令 + +#### wecom企业微信群聊机器人 + +```shell +Usage: cve-ease wecom +(Specify the --help global option for a list of other help options) + +Options: + -h, --help show this help message and exit + -t, --test run test + -v, --verbose show verbose output + -c CONTENT, --content=CONTENT + show verbose output +``` + +```shell +cve-ease wecom -t # 发送测试消息到企业微信群 +cve-ease wecom -t -c 'helloworld' # 发送自定义测试消息到企业微信群 +``` + +#### dingding钉钉群聊机器人 + +```shell +Usage: cve-ease dingding +(Specify the --help global option for a list of other help options) + +Options: + -h, --help show this help message and exit + -t, --test run test + -v, --verbose show verbose output + -c CONTENT, --content=CONTENT + show verbose output +``` + +```shell +cve-ease dingding -t # 发送测试消息到钉钉群 +cve-ease dingding -t -c 'helloworld' # 发送自定义测试消息到钉钉群 +``` + +#### feishu飞书群聊机器人 + +```shell +Usage: cve-ease feishu +(Specify the --help global option for a list of other help options) + +Options: + -h, --help show this help message and exit + -t, --test run test + -v, --verbose show verbose output + -c CONTENT, --content=CONTENT + show verbose output +``` + +```shell +cve-ease feishu -t # 发送测试消息到飞书群 +cve-ease feishu -t -c 'helloworld' # 发送自定义测试消息到飞书群 +``` + +#### mail163邮箱 + +```shell +Usage: cve-ease mail163 +(Specify the --help global option for a list of other help options) + +Options: + -h, --help show this help message and exit + -t, --test run test + -v, --verbose show verbose output + -c CONTENT, --content=CONTENT + show verbose output +``` + +```shell +cve-ease mail163 -t # 发送测试消息到163邮箱 +cve-ease mail163 -t -c 'helloworld' # 发送自定义测试消息到163邮箱 +``` + +#### mailqq邮箱 + +```shell +Usage: cve-ease mailqq +(Specify the --help global option for a list of other help options) + +Options: + -h, --help show this help message and exit + -t, --test run test + -v, --verbose show verbose output + -c CONTENT, --content=CONTENT + show verbose output +``` + +```shell +cve-ease mailqq -t # 发送测试消息到QQ邮箱 +cve-ease mailqq -t -c 'helloworld' # 发送自定义测试消息到QQ邮箱 +``` + +## 如何参与贡献 + +1. Fork 本仓库。 +2. 当前快速迭代期间,仅 master 分支,因此您只需在 master 做变更后提交。 +3. 创建 pr ,描述清楚 pr 的具体功能、作用,并提供相关测试用例。 +4. 通知仓库 maintainer 审核 pr。 + +## 核心研发人员及联系方式 + +* 游益锋 - [Gitee私信](https://gitee.com/youyifeng) +* 吴开顺 - [Gitee私信](https://gitee.com/wuzimo) diff --git a/docs/en/25.03/Server/Security/CVE-ease/figures/CVE-ease_desigin_table.png b/docs/en/25.03/Server/Security/CVE-ease/figures/CVE-ease_desigin_table.png new file mode 100644 index 0000000000000000000000000000000000000000..8164b9a10207a376200a162ec153b536a1d32e22 Binary files /dev/null and b/docs/en/25.03/Server/Security/CVE-ease/figures/CVE-ease_desigin_table.png differ diff --git a/docs/en/25.03/Server/Security/CVE-ease/figures/CVE-ease_function.png b/docs/en/25.03/Server/Security/CVE-ease/figures/CVE-ease_function.png new file mode 100644 index 0000000000000000000000000000000000000000..b645dc750378127ca11b49720deba12569a884bc Binary files /dev/null and b/docs/en/25.03/Server/Security/CVE-ease/figures/CVE-ease_function.png differ diff --git a/docs/en/25.03/Server/Security/CertSignature/_menu.md b/docs/en/25.03/Server/Security/CertSignature/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..7ab0c3cee46bb7490ec7992416d7db6bf74b9085 --- /dev/null +++ b/docs/en/25.03/Server/Security/CertSignature/_menu.md @@ -0,0 +1,12 @@ +--- +label: '证书签名' +ismanual: 'Y' +description: 'openEuler 签名平台提供签名服务,保护系统文件的完整性' +children: + - label: '认识证书和签名' + href: './overview.md' + - label: '签名证书介绍' + href: './signature-certificate-introduction.md' + - label: '安全启动' + href: './secure-boot.md' +--- diff --git a/docs/en/25.03/Server/Security/CertSignature/figures/cert-tree.png b/docs/en/25.03/Server/Security/CertSignature/figures/cert-tree.png new file mode 100644 index 0000000000000000000000000000000000000000..cfbea157cb7b7308d668196ca5b0b0386067fd9e Binary files /dev/null and b/docs/en/25.03/Server/Security/CertSignature/figures/cert-tree.png differ diff --git a/docs/en/25.03/Server/Security/CertSignature/figures/mokutil-db.png b/docs/en/25.03/Server/Security/CertSignature/figures/mokutil-db.png new file mode 100644 index 0000000000000000000000000000000000000000..82dbe6e04cafe3e9ac039ba19acd5996d4cf2259 Binary files /dev/null and b/docs/en/25.03/Server/Security/CertSignature/figures/mokutil-db.png differ diff --git a/docs/en/25.03/Server/Security/CertSignature/figures/mokutil-sb-off.png b/docs/en/25.03/Server/Security/CertSignature/figures/mokutil-sb-off.png new file mode 100644 index 0000000000000000000000000000000000000000..f3018c9fd0236e9c2cf560f0da3827ed2a877f6d Binary files /dev/null and b/docs/en/25.03/Server/Security/CertSignature/figures/mokutil-sb-off.png differ diff --git a/docs/en/25.03/Server/Security/CertSignature/figures/mokutil-sb-on.png b/docs/en/25.03/Server/Security/CertSignature/figures/mokutil-sb-on.png new file mode 100644 index 0000000000000000000000000000000000000000..449b6774dc61a601cf884845fbd0be5d314108e1 Binary files /dev/null and b/docs/en/25.03/Server/Security/CertSignature/figures/mokutil-sb-on.png differ diff --git a/docs/en/25.03/Server/Security/CertSignature/figures/mokutil-sb-unsupport.png b/docs/en/25.03/Server/Security/CertSignature/figures/mokutil-sb-unsupport.png new file mode 100644 index 0000000000000000000000000000000000000000..525c72f78b897ffaba0d356406ab9d9e64024d91 Binary files /dev/null and b/docs/en/25.03/Server/Security/CertSignature/figures/mokutil-sb-unsupport.png differ diff --git a/docs/en/25.03/Server/Security/CertSignature/overview.md b/docs/en/25.03/Server/Security/CertSignature/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..ddec74977c565a539c3d11af7f96e361c471bacf --- /dev/null +++ b/docs/en/25.03/Server/Security/CertSignature/overview.md @@ -0,0 +1,29 @@ +# 认识证书和签名 + +## 概述 + +数字签名是保护操作系统完整性的重要技术。通过对系统关键组件添加签名,并在后续的组件启动加载、运行访问等流程中进行签名验证,可以有效检查组件的完整性,避免组件被篡改而导致的安全问题。业界已支持多种系统完整性保护机制,在系统运行的各个阶段对不同类型的组件进行完整性保护,典型的技术机制有: + +- 安全启动; +- 内核模块签名; +- IMA完整性度量架构; +- RPM签名验证。 + +上述完整性保护的安全机制都需要依赖签名(通常需要在组件发布阶段集成),而开源社区普遍存在缺乏签名私钥和证书管理机制,因此社区发布的操作系统发行版通常不提供默认签名,或仅使用构建阶段临时生成的私钥进行签名。往往需要用户或者下游OSV厂商进行二次签名后才可开启这些完整性保护安全机制,增加了安全功能的使用成本并降低了易用性。 + +## 解决方案 + +openEuler社区基础设施支持签名服务,通过签名平台统一管理签名私钥和证书,并与EulerMaker构建平台结合,实现在社区发行版的软件包构建过程中对关键文件进行自动签名。当前支持的文件类型有: + +- EFI文件; +- 内核模块文件; +- IMA摘要列表文件; +- RPM软件包。 + +## 约束限制 + +openEuler社区的签名服务功能存在如下约束限制: + +- 当前仅支持为openEuler社区官方发布分支进行签名,暂不支持对个人构建分支进行签名; +- 当前仅支持对OS安全启动相关的EFI文件进行签名,包括shim、grub、kernel文件; +- 当前仅支持对kernel软件包提供的内核模块文件进行签名。 diff --git a/docs/en/25.03/Server/Security/CertSignature/secure-boot.md b/docs/en/25.03/Server/Security/CertSignature/secure-boot.md new file mode 100644 index 0000000000000000000000000000000000000000..7607a58baf7b9c0c0f5a229af7db9cc0688c550e --- /dev/null +++ b/docs/en/25.03/Server/Security/CertSignature/secure-boot.md @@ -0,0 +1,50 @@ +# 安全启动 + +## 概述 + +安全启动(Secure Boot)就是利用公私钥对启动部件进行签名和验证。在启动过程中,前一个部件验证后一个部件的数字签名,如果能验证通过,则运行后一个部件;如果验证不通过,则暂停启动。通过安全启动可以保证系统启动过程中各个部件的完整性,防止没有经过认证的部件被加载运行,从而防止对系统及用户数据产生安全威胁。 +安全启动涉及的验证组件: BIOS->shim->grub->vmlinuz(依次验签通过并加载),其中vmlinuz是内核镜像。 +相关的EFI启动组件由openEuler签名平台采用signcode方式进行签名。公钥证书由BIOS集成到签名数据库DB中,启动过程中BIOS对shim进行验证,shim和grub组件从BIOS的签名数据库DB中获取公钥证书并对下一级组件进行验证。 + +## 背景和解决方案 + +前期openEuler版本中,安全启动相关组件没有签名,无法直接使用安全启动功能保障系统组件的完整性。 +从22.03-LTS-SP3版本开始,openEuler使用社区签名平台对OS侧的相关组件进行签名,包括grub和vmlinuz组件,并将社区签名根证书内嵌于shim组件中。 +对于shim组件,为了便于端到端实现安全启动功能,当前使用openEuler社区的签名平台进行签名。后续外部国产CA(如CFCA,中国金融认证中心)正式运营安全启动组件签名服务后,将计划在openEuler的shim模块中集成这些国产CA的签名。 + +## 使用方法 + +### openEuler证书获取 + +openEuler根证书获取地址:,进入“证书中心”目录下载。 +网页上根证书识别名称为“openEuler Shim Default CA”,default-x509ca.cert。 + +### BIOS侧操作 + +将openEuler根证书导入BIOS的db证书库中,并在BIOS中开启安全启动开关,可实现安全启动功能。 +BIOS证书导入方法及安全启动开启方法可参考具体BIOS厂商提供的资料。 + +### OS侧操作 + +**查看db数据库中的证书信息**:mokutil –db +![](./figures/mokutil-db.png) +说明:证书信息较多,截图中只显示部分重要信息 +**查看系统安全启动状态**:mokutil --sb + +- SecureBoot disabled:安全启动关闭 + + ![](./figures/mokutil-sb-off.png) + +- SecureBoot enabled:安全启动开启 + + ![](./figures/mokutil-sb-on.png) + +- not supported:系统不支持安全启动 + + ![](./figures/mokutil-sb-unsupport.png) + +## 约束限制 + +- **软件限制**:OS系统需要采用UEFI启动 +- **架构限制**:ARM/X86 +- **硬件约束**:需要BIOS支持安全启动相关校验功能 diff --git a/docs/en/25.03/Server/Security/CertSignature/signature-certificate-introduction.md b/docs/en/25.03/Server/Security/CertSignature/signature-certificate-introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..adac8a9835f311db5f7d07d7df26ba04e22bd155 --- /dev/null +++ b/docs/en/25.03/Server/Security/CertSignature/signature-certificate-introduction.md @@ -0,0 +1,46 @@ +# 签名证书介绍 + +openEuler当前支持两种签名机制:openPGP和CMS,分别用于不同的文件类型: + +| 文件类型 | 签名类型 | 签名格式 | +| --------------- | ------------ | -------- | +| EFI文件 | authenticode | CMS | +| 内核模块文件 | modsig | CMS | +| IMA摘要列表文件 | modsig | CMS | +| RPM软件包 | RPM | openPGP | + +## openPGP证书签名 + +openEuler通过openPGP证书实现RPM软件包的签名,签名证书随操作系统镜像发布,用户可通过两种方式获取到当前openEuler版本所使用的证书: + +方法一:通过REPO源下载,以openEuler 24.03 LTS版本为例,可通过如下路径下载: + +```shell +https://repo.openeuler.org/openEuler-24.03-LTS/OS/aarch64/RPM-GPG-KEY-openEuler +``` + +方法二:进入系统通过指定路径获取: + +```shell +cat /etc/pki/rpm-gpg/RPM-GPG-KEY-openEuler +``` + +## CMS证书签名 + +openEuler签名平台采用三级证书链管理签名的私钥和证书: + +![](./figures/cert-tree.png) + +根据不同等级的证书分别具有不同的有效期,当前规划为: + +| 证书类型 | 有效期 | +| -------- | ------ | +| 根证书 | 30年 | +| 二级证书 | 10年 | +| 三级证书 | 3年 | + +openEuler根证书可通过社区证书中心下载: + +```shell +https://www.openeuler.org/zh/security/certificate-center/ +``` diff --git a/docs/en/25.03/Server/Security/Sbom/.keep b/docs/en/25.03/Server/Security/Sbom/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/docs/en/25.03/Server/Security/Sbom/SBOM-introduction.md b/docs/en/25.03/Server/Security/Sbom/SBOM-introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..793e6fc7007e156827d2caf3fd6cdf0110c64e37 --- /dev/null +++ b/docs/en/25.03/Server/Security/Sbom/SBOM-introduction.md @@ -0,0 +1,46 @@ +# 1. SBOM介绍 + +SBOM是一种正式标准化的、机器可读的元数据,它唯一地标识软件组件及其内容;也可能包括版权和许可证等成分数据。SBOM旨在跨组织共享,有助于提供软件供应链成分清单与透明度,并且未来趋势将作为软件交付件必要清单。 + +# 2. SBOM最小集定义 + +美国国家电信和信息管理局(National Telecommunications and Information Administration)发布SBOM最小集的定义: 数据字段是关于必须捕获和维护每个组件的基础数据,以便在整个软件供应链中跟踪组件,并基于此扩展License和漏洞库等其他数据字段。 + +| 数据字段 | 描述 | +| :------------- | :----------------------------------------------------------- | +| 供应商名称 | 创建、定义和标识组件的实体的名称。 | +| 组件名称 | 分配给原始供应商定义的软件单元的名称。 | +| 组件的版本 | 组件版本号、供应商用来指定软件从先前标识的版本发生变化的标识符。 | +| 其它唯一标识符 | 用于标识组件或用作相关数据库的查找键的其他标识符。 | +| 依赖关系 | 软件依赖关系、表征上游组件 X 包含在软件 Y 中的关系 | +| SBOM数据的作者 | 为此组件创建SBOM数据的实体的名称。 | +| 时间戳 | 记录SBOM数据组装的日期和时间。 | +| **推荐的数据** | | +| 组件的哈希 | 组件的唯一哈希,以帮助允许列表或拒绝列表。 | +| 生命周期阶段 | SDLC 中捕获 SBOM 数据的获取的阶段。 | + +# 3. openEuler发布的SBOM字段说明 + +| 最小集数据字段 | SPDX | +| ----------------- | ------------------------------------------------------------ | +| 组件供应商名称 | document->packages->supplier | +| 组件名称 | document->packages->name | +| 组件版本 | document->packages->versionInfo(openEuler使用了epoch:version-release格式) | +| 组件其他唯一标识 | document->packages->externalRefs(category:PACKAGE_MANAGER)->purl | +| 组件依赖关系 | document->packages->externalRefs(category:EXTERNAL_MANAGER)->purl | +| SBOM数据作者 | document->creationInfo->creators | +| SBOM时间戳 | document->creationInfo->created | +| 组件的哈希 | document->packages->checksums | +| 生命周期阶段 | 未支持 | +| 其他组件关系 | 内部子组件:document->packages->externalRefs(category:PROVIDE_MANAGER)->purl 运行时依赖:document->relationships(relationshipType:DEPENDS_ON) | +| 组件License信息 | document->packages->licenseDeclared document->packages->licenseConcluded | +| 组件Copyright信息 | document->packages->copyrightText | +| 组件上游社区信息 | document->packages->externalRefs(category:SOURCE_MANAGER)->url | +| 组件补丁信息 | 补丁文件:document->files(fileTypes:SOURCE) 补丁关系:document->relationships(relationshipType:PATCH_APPLIED) | +| 组件来源 | document->packages->downloadLocation | +| 组件信息 | document->packages->description document->packages->summary | +| 组件官网/博客 | document->packages->homepage | + +# 4. SBOM文件示例 + +解析最小颗粒度是RPM包 diff --git a/docs/en/25.03/Server/Security/Sbom/_menu.md b/docs/en/25.03/Server/Security/Sbom/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..85a38d479fcb346ac3921d9f3e587da716e2fb86 --- /dev/null +++ b/docs/en/25.03/Server/Security/Sbom/_menu.md @@ -0,0 +1,8 @@ +--- +label: 'SBOM用户指南' +ismanual: 'Y' +description: 'SBOM 唯一标识软件组件及其内容' +children: + - label: 'SBOM介绍' + href: './SBOM-introduction.md' +--- diff --git a/docs/en/25.03/Server/Security/SecHarden/_menu.md b/docs/en/25.03/Server/Security/SecHarden/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..26e50658b778c9bf1f6823ccf8ad04e067379bed --- /dev/null +++ b/docs/en/25.03/Server/Security/SecHarden/_menu.md @@ -0,0 +1,29 @@ +--- +label: '安全加固指南' +ismanual: 'Y' +description: '指导用户进行安全加固' +children: + - label: '操作系统加固概述' + href: './os-hardening-overview.md' + - label: '安全配置说明' + href: './security-configuration-benchmark.md' + - label: '加固指导' + href: './secHarden.md' + children: + - label: '帐户口令' + href: './account-passwords.md' + - label: '授权认证' + href: './authentication-and-authorization.md' + - label: '系统服务' + href: './system-services.md' + - label: '文件权限' + href: './file-permissions.md' + - label: '内核参数' + href: './kernel-parameters.md' + - label: 'SELinux配置' + href: './selinux-configuration.md' + - label: '安全加固工具' + href: './security-hardening-tools.md' + - label: '附录' + href: './appendix.md' +--- diff --git a/docs/en/25.03/Server/Security/SecHarden/account-passwords.md b/docs/en/25.03/Server/Security/SecHarden/account-passwords.md new file mode 100644 index 0000000000000000000000000000000000000000..0ee24b74a8a1e51ffaf10920da37bdb335e9b149 --- /dev/null +++ b/docs/en/25.03/Server/Security/SecHarden/account-passwords.md @@ -0,0 +1,329 @@ +# 帐户口令 + +- [帐户口令](#帐户口令) + - [屏蔽系统帐户](#屏蔽系统帐户) + - [限制使用su命令的帐户](#限制使用su命令的帐户) + - [设置口令复杂度](#设置口令复杂度) + - [设置口令有效期](#设置口令有效期) + - [设置口令的加密算法](#设置口令的加密算法) + - [登录失败超过三次后锁定](#登录失败超过三次后锁定) + - [加固su命令](#加固su命令) + +## 屏蔽系统帐户 + +### 说明 + +除了用户帐户外,其他帐号称为系统帐户。系统帐户仅系统内部使用,禁止用于登录系统或其他操作,因此屏蔽系统帐户。 + +### 实现 + +将系统帐户的Shell修改为/sbin/nologin。 + +```sh +usermod -L -s /sbin/nologin $systemaccount +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> $systemaccount 指系统帐户。 + +## 限制使用su命令的帐户 + +### 说明 + +su命令用于在不同帐户之间切换。为了增强系统安全性,有必要对su命令的使用权进行控制,只允许root和wheel群组的帐户使用su命令,限制其他帐户使用。 + +### 实现 + +su命令的使用控制通过修改/etc/pam.d/su文件实现,配置如下: + +```sh +auth required pam_wheel.so use_uid +``` + +**表 1** pam\_wheel.so配置项说明 + + + + + + + + + + +

配置项

+

说明

+

use_uid

+

基于当前帐户的uid。

+
+ +## 设置口令复杂度 + +### 说明 + +用户可以通过修改对应配置文件设置口令的复杂度要求,建议用户根据实际情况设置口令复杂度。 + +### 实现 + +口令复杂度通过/etc/pam.d/password-auth和/etc/pam.d/system-auth文件中的pam\_pwquality.so和pam\_pwhistory.so模块实现。用户可以通过修改这两个模块中的配置项修改口令复杂度。 + +### 设置举例 + +这里给出一个配置口令复杂度的例子,供用户参考。 + +**密码复杂度要求** + +1. 口令长度至少8个字符。 +2. 口令必须包含如下至少3种字符的组合: + + -至少一个小写字母 + + -至少一个大写字母 + + -至少一个数字 + + -至少一个特殊字符:\`\~!@\#$%^&\*\(\)-\_=+\\|\[\{\}\];:'",<.\>/?和空格 + +3. 口令不能和帐号或者帐号的倒写一样。 +4. 不能修改为过去5次使用过的旧口令。 + +**配置实现** + +在/etc/pam.d/password-auth和/etc/pam.d/system-auth文件中password配置项的前两行添加如下配置内容: + +```sh +password requisite pam_pwquality.so minlen=8 minclass=3 enforce_for_root try_first_pass local_users_only retry=3 dcredit=0 ucredit=0 lcredit=0 ocredit=0 +password required pam_pwhistory.so use_authtok remember=5 enforce_for_root +``` + +**配置项说明** + +pam\_pwquality.so和pam\_pwhistory.so的配置项请分别参见[表2](#table201221044172117)和[表3](#table1212544452120)。 + +**表 2** pam\_pwquality.so配置项说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

配置项

+

说明

+

minlen=8

+

口令长度至少包含8个字符

+

minclass=3

+

口令至少包含大写字母、小写字母、数字和特殊字符中的任意3种

+

ucredit=0

+

口令包含任意个大写字母

+

lcredit=0

+

口令包含任意个小写字母

+

dcredit=0

+

口令包含任意个数字

+

ocredit=0

+

口令包含任意个特殊字符

+

retry=3

+

每次修改最多可以尝试3次

+

enforce_for_root

+

本设置对root帐户同样有效

+
+ +**表 3** pam\_pwhistory.so配置项说明 + + + + + + + + + + + + + +

配置项

+

说明

+

remember=5

+

口令不能修改为过去5次使用过的旧口令

+

enforce_for_root

+

本设置对root帐户同样有效

+
+ +## 设置口令有效期 + +### 说明 + +出于系统安全性考虑,建议设置口令有效期限,且口令到期前通知用户更改口令。 + +### 实现 + +口令有效期的设置通过修改/etc/login.defs文件实现,加固项如[表7](#zh-cn_topic_0152100281_t77b5d0753721450c81911c18b74e82eb)所示。表中所有的加固项都在文件/etc/login.defs中。表中字段直接通过修改配置文件完成。 + +**表 4** login.defs配置项说明所示 + + + + + + + + + + + + + + + + + + + + + + + + +

加固项

+

加固项说明

+

建议加固

+

openEuler默认是否已加固为建议值

+

PASS_MAX_DAYS

+

口令最大有效期

+

90

+

+

PASS_MIN_DAYS

+

两次修改口令的最小间隔时间

+

0

+

+

PASS_WARN_AGE

+

口令过期前开始提示天数

+

7

+

+
+ +> ![](./public_sys-resources/icon-note.gif) **说明:** +> login.defs是设置用户帐号限制的文件,可配置口令的最大过期天数、最大长度约束等。该文件里的配置对root用户无效。如果/etc/shadow文件里有相同的选项,则以/etc/shadow配置为准,即/etc/shadow的配置优先级高于/etc/login.defs。口令过期后用户重新登录时,提示口令过期并强制要求修改,不修改则无法进入系统。 + +## 设置口令的加密算法 + +### 说明 + +出于系统安全考虑,口令不允许明文存储在系统中,应该加密保护。在不需要还原口令的场景,必须使用不可逆算法加密。设置口令的加密算法为sha512,openEuler默认已设置。通过上述设置可以有效防范口令泄露,保证口令安全。 + +### 实现 + +口令的加密算法设置通过修改/etc/pam.d/password-auth和/etc/pam.d/system-auth文件实现,添加如下配置: + +```sh +password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok +``` + +**表 5** pam\_unix.so配置项说明 + + + + + + + + + + +

配置项

+

说明

+

sha512

+

使用sha512算法对口令加密。

+
+ +## 登录失败超过三次后锁定 + +### 说明 + +为了保障用户系统的安全,建议用户设置口令出错次数的阈值(建议3次),以及由于口令出错次数超过阈值,导致账户被锁定的自动解锁时间(建议300秒)。 + +用户锁定期间,任何输入被判定为无效,锁定时间不因用户的再次输入而重新计时;解锁后,用户的错误输入记录被清空。通过上述设置可以有效防范口令被暴力破解,增强系统的安全性。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> openEuler默认口令出错次数的阈值为3次,系统被锁定后自动解锁时间为60秒。 + +### 实现 + +口令复杂度的设置通过修改/etc/pam.d/password-auth和/etc/pam.d/system-auth文件实现,设置口令的最大出错次数为3次,系统锁定后的解锁时间为300秒的配置如下: + +```text +auth required pam_faillock.so preauth audit deny=3 even_deny_root unlock_time=300 +auth [default=die] pam_faillock.so authfail audit deny=3 even_deny_root unlock_time=300 +auth sufficient pam_faillock.so authsucc audit deny=3 even_deny_root unlock_time=300 +``` + +**表 6** pam\_faillock.so配置项说明 + + + + + + + + + + + + + + + + + + + +

配置项

+

说明

+

authfail

+

捕获用户登录失败的事件。

+

deny=3

+

用户连续登录失败次数超过3次即被锁定。

+

unlock_time=300

+

普通用户自动解锁时间为300秒(即5分钟)。

+

even_deny_root

+

同样限制root帐户。

+
+ +## 加固su命令 + +### 说明 + +为了增强系统安全性,防止使用“su”切换用户时将当前用户环境变量带入其他环境,openEuler默认已做配置。总是在使用su切换用户时初始化PATH。 + +### 实现 + +通过修改/etc/login.defs实现,配置如下: + +```sh +ALWAYS_SET_PATH=yes +``` diff --git a/docs/en/25.03/Server/Security/SecHarden/appendix.md b/docs/en/25.03/Server/Security/SecHarden/appendix.md new file mode 100644 index 0000000000000000000000000000000000000000..4f3eff1715b09bc701dd552a5d2f58a6d3b1125b --- /dev/null +++ b/docs/en/25.03/Server/Security/SecHarden/appendix.md @@ -0,0 +1,35 @@ +# 附录 + +介绍文件权限的含义和umask值的含义。 + + + +- [附录](#附录) + - [文件和目录权限含义](#文件和目录权限含义) + - [umask值含义](#umask值含义) + + + +## 文件和目录权限含义 + +Linux系统中文件和目录权限用于限定谁能通过何种方式对文件和目录进行访问和操作。文件和目录的访问权限分为只读,只写和可执行三种。 + +有三种不同类型的用户可对文件和目录进行访问: + +- 文件所有者:文件的创建者。 +- 同组用户:与文件所有者在同一个属组的用户。 +- 其他用户:与文件所有者不在同一个属组的用户。 + +文件和目录的权限含义通过以下例子说明: + +假设/usr/src的权限为755,将每位数字转化为二进制后为:111101101,含义如下: + +- 左侧三个bit位111表示文件所有者的权限依次为:可读、可写、可执行。 +- 中间三个bit位101表示同组用户的权限依次为:可读、不可写、可执行。 +- 右侧三个bit位101表示其他用户的权限依次为:可读、不可写、可执行。 + +## umask值含义 + +当用户新创建文件或目录时,该文件或目录具有一个缺省权限。该缺省权限由umask值来指定。 + +umask值代表的是权限的“补码”,即用缺省最大权限值减去umask值得到实际权限值。文件的缺省最大权限为可读可写,目录的缺省最大权限为可读可写可执行。即一个文件的实际缺省权限为666减去umask值。目录的实际缺省权限为777减去umask值。 diff --git a/docs/en/25.03/Server/Security/SecHarden/authentication-and-authorization.md b/docs/en/25.03/Server/Security/SecHarden/authentication-and-authorization.md new file mode 100644 index 0000000000000000000000000000000000000000..67fa3c2e6dc79a77d5acd87286d79622a591b9e5 --- /dev/null +++ b/docs/en/25.03/Server/Security/SecHarden/authentication-and-authorization.md @@ -0,0 +1,146 @@ +# 授权认证 + +## 设置网络远程登录的警告信息 + +### 说明 + +设置网络远程登录的警告信息,用于在登录进入系统之前向用户提示警告信息,明示非法侵入系统可能受到的惩罚,吓阻潜在的攻击者。同时也可以隐藏系统架构及其他系统信息,避免招致对系统的目标性攻击。 + +### 实现 + +该设置可以通过修改/etc/issue.net文件的内容实现。将/etc/issue.net文件原有内容替换为如下信息(openEuler默认已设置): + +```text +Authorized users only. All activities may be monitored and reported. +``` + +## 禁止通过Ctrl+Alt+Del重启系统 + +### 说明 + +操作系统默认能够通过“Ctrl+Alt+Del”进行重启,建议禁止该项特性,防止因为误操作而导致数据丢失。 + +### 实现 + +禁止通过“Ctrl+Alt+Del”重启系统的操作步骤如下: + +1. 删除两个ctrl-alt-del.target文件,参考命令如下: + + ```shell + rm -f /etc/systemd/system/ctrl-alt-del.target + rm -f /usr/lib/systemd/system/ctrl-alt-del.target + ``` + +2. 修改/etc/systemd/system.conf文件,将\#CtrlAltDelBurstAction=reboot-force修改为CtrlAltDelBurstAction=none。 +3. 重启systemd,使修改生效,参考命令如下: + (注:使用 systemctl daemon-reexec 命令可能会导致短暂的系统服务不可用或重启,并且必须具有 root 或具有 sudo 权限的用户才能执行这个操作) + + ```shell + systemctl daemon-reexec + ``` + +## 设置终端的自动退出时间 + +### 说明 + +无人看管的终端容易被侦听或被攻击,可能会危及系统安全。因此建议设置终端在停止运行一段时间后能够自动退出。 + +### 实现 + +自动退出时间由/etc/profile文件的TMOUT字段(单位为秒)控制,在/etc/profile的尾部添加如下配置: + +```sh +export TMOUT=300 +``` + +## 设置用户的默认umask值为077 + +### 说明 + +umask值用于为用户新创建的文件和目录设置缺省权限。如果umask的值设置过小,会使群组用户或其他用户的权限过大,给系统带来安全威胁。因此设置所有用户默认的umask值为0077,即用户创建的目录默认权限为700,文件的默认权限为600。umask值代表的是权限的“补码”,umask值和权限的换算方法请参见"附录 > umask值含义"。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> openEuler默认已设置用户的默认umask值为022。 + +### 实现 + +1. 分别在/etc/bashrc文件和/etc/profile.d/目录下的所有文件中加入“umask 0077”。 + + ```shell + echo "umask 0077" >> $FILE + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > _$FILE_ 为具体的文件名,例如:echo "umask 0077" \>\> /etc/bashrc + +2. 设置/etc/bashrc文件和/etc/profile.d/目录下所有文件的属主为root,群组为root。 + + ```shell + chown root.root $FILE + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > _$FILE_ 为具体的文件名,例如:chown root.root /etc/bashrc + +## 设置GRUB2加密口令 + +### 说明 + +GRUB是GRand Unified Bootloader的缩写,它是一个操作系统启动管理器,用来引导不同系统(如Windows、Linux),GRUB2是GRUB的升级版。 + +系统启动时,可以通过GRUB2界面修改系统的启动参数。为了确保系统的启动参数不被任意修改,需要对GRUB2界面进行加密,仅在输入正确的GRUB2口令时才能修改启动参数。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> GRUB2默认设置的口令为openEuler\#12,建议用户首次登录时修改默认密码并定期更新,避免密码泄露后,启动选项被篡改,导致系统启动异常。 + +### 实现 + +1. 使用grub2-mkpasswd-pbkdf2命令生成加密的口令: + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > GRUB2加密算法使用sha512。 + + ```shell + # grub2-mkpasswd-pbkdf2 + Enter password: + Reenter password: + PBKDF2 hash of your password is + grub.pbkdf2.sha512.10000.5A45748D892672FDA02DD3B6F7AE390AC6E6D532A600D4AC477D25C7D087644697D8A0894DFED9D86DC2A27F4E01D925C46417A225FC099C12DBD3D7D49A7425.2BD2F5BF4907DCC389CC5D165DB85CC3E2C94C8F9A30B01DACAA9CD552B731BA1DD3B7CC2C765704D55B8CD962D2AEF19A753CBE9B8464E2B1EB39A3BB4EAB08 + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 在Enter password和Reenter password输入相同的口令。 + > grub.pbkdf2.sha512.10000.5A45748D892672FDA02DD3B6F7AE390AC6E6D532A600D4AC477D25C7D087644697D8A0894DFED9D86DC2A27F4E01D925C46417A225FC099C12DBD3D7D49A7425.2BD2F5BF4907DCC389CC5D165DB85CC3E2C94C8F9A30B01DACAA9CD552B731BA1DD3B7CC2C765704D55B8CD962D2AEF19A753CBE9B8464E2B1EB39A3BB4EAB08为openEuler\#12经过grub2-mkpasswd-pbkdf2加密后的输出,每次输出的密文不同。 + +2. 使用vi工具打开/boot/efi/EFI/openEuler/grub.cfg文件(不同模式下grub.cfg文件所在路径不同,详见说明),并在开头位置追加如下字段: + + ```text + set superusers="root" + password_pbkdf2 root grub.pbkdf2.sha512.10000.5A45748D892672FDA02DD3B6F7AE390AC6E6D532A600D4AC477D25C7D087644697D8A0894DFED9D86DC2A27F4E01D925C46417A225FC099C12DBD3D7D49A7425.2BD2F5BF4907DCC389CC5D165DB85CC3E2C94C8F9A30B01DACAA9CD552B731BA1DD3B7CC2C765704D55B8CD962D2AEF19A753CBE9B8464E2B1EB39A3BB4EAB08 + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > + >- 不同模式下grub.cfg文件所在路径不同:x86架构的UEFI模式下路径为/boot/efi/EFI/openEuler/grub.cfg,legacy BIOS模式下路径为/boot/grub2/grub.cfg;aarch64架构下路径为/boot/efi/EFI/openEuler/grub.cfg。 + >- superusers字段用于设置GRUB2的超级管理员的帐户名。 + >- password\_pbkdf2字段后的参数,第1个参数为GRUB2的帐户名,第2个为该帐户的加密口令。 + +## 安全单用户模式 + +### 说明 + +单用户模式是以root权限进入系统,如不设置密码,将存在较大安全隐患。 + +### 实现 + +该设置可以通过修改/etc/sysconfig/init文件内容实现。将SINGLE选项配置为SINGLE=/sbin/sulogin。 + +## 禁止交互式启动 + +### 说明 + +使用交互式引导,控制台用户可以禁用审计、防火墙或其他服务,削弱了系统安全性。用户可以禁止使用交互式引导,提升安全性。openEuler默认已禁止。 + +### 实现 + +该设置可以通过修改/etc/sysconfig/init文件内容实现。将PROMPT选项配置为PROMPT=no。 diff --git a/docs/en/25.03/Server/Security/SecHarden/figures/zh-cn_image_0221925211.png b/docs/en/25.03/Server/Security/SecHarden/figures/zh-cn_image_0221925211.png new file mode 100644 index 0000000000000000000000000000000000000000..d245d48dc07e2b01734e21ec1952e89fa9269bdb Binary files /dev/null and b/docs/en/25.03/Server/Security/SecHarden/figures/zh-cn_image_0221925211.png differ diff --git a/docs/en/25.03/Server/Security/SecHarden/figures/zh-cn_image_0221925212.png b/docs/en/25.03/Server/Security/SecHarden/figures/zh-cn_image_0221925212.png new file mode 100644 index 0000000000000000000000000000000000000000..a32856aa08e459ed0f51f8fcf4c2f51511c12095 Binary files /dev/null and b/docs/en/25.03/Server/Security/SecHarden/figures/zh-cn_image_0221925212.png differ diff --git a/docs/en/25.03/Server/Security/SecHarden/file-permissions.md b/docs/en/25.03/Server/Security/SecHarden/file-permissions.md new file mode 100644 index 0000000000000000000000000000000000000000..eaa7e82af6da641da9044737fa765e78301e303b --- /dev/null +++ b/docs/en/25.03/Server/Security/SecHarden/file-permissions.md @@ -0,0 +1,230 @@ +# 文件权限 + +- [文件权限](#文件权限) + - [设置文件的权限和属主](#设置文件的权限和属主) + - [删除无主文件](#删除无主文件) + - [处理空链接文件](#处理空链接文件) + - [设置守护进程的umask值](#设置守护进程的umask值) + - [为全局可写目录添加粘滞位属性](#为全局可写目录添加粘滞位属性) + - [删除非授权文件的全局可写属性](#删除非授权文件的全局可写属性) + - [限制at命令的使用权限](#限制at命令的使用权限) + - [限制cron命令的使用权限](#限制cron命令的使用权限) + - [限制sudo命令的使用权限](#限制sudo命令的使用权限) + +## 设置文件的权限和属主 + +### 说明 + +Linux将所有对象都当作文件来处理,即使一个目录也被看作是包含有多个其他文件的大文件。因此,Linux中最重要的就是文件和目录的安全性。文件和目录的安全性主要通过权限和属主来保证。 + +openEuler默认对系统中的常用目录、可执行文件和配置文件设置了权限和属主。 + +### 实现 + +以/bin目录为例,修改文件权限和文件属主的操作如下: + +- 修改文件权限。例如将/bin目录权限设置为755。 + + ```sh + chmod 755 /bin + ``` + +- 修改文件属主。例如将/bin目录的拥有者和群组设置为root:root。 + + ```sh + chown root:root /bin + ``` + +## 删除无主文件 + +### 说明 + +系统管理员在删除用户/群组时,存在着忘记删除该用户/该群组所拥有文件的问题。如果后续新创建的用户/群组与被删除的用户/群组同名,则新用户/新群组会拥有部分不属于其权限的文件,建议将此类文件删除。 + +### 实现 + +删除用户ID不存在的文件 + +1. 查找用户ID不存在的文件。 + + ```sh + find / -nouser + ``` + +2. 删除查找到的文件。其中 filename 为用户ID不存在文件的文件名。 + + ```sh + rm -f filename + ``` + +删除群组ID不存在的文件 + +1. 查找群组ID不存在的文件。 + + ```sh + find / -nogroup + ``` + +2. 删除查找到的文件。其中 filename 为群组ID不存在文件的文件名。 + + ```sh + rm -f filename + ``` + +## 处理空链接文件 + +### 说明 + +无指向的空链接文件,可能会被恶意用户利用,影响系统安全性。建议用户删除无效的空链接文件,提高系统安全性。 + +### 特殊场景 + +openEuler系统安装完成后,可能存在空链接文件,这些空链接文件可能有对应用途(有些空链接文件是预制的,会被其他组件依赖)。请用户根据实际环境进行处理,处理方式请参见[实现](#zh-cn_topic_0152100319_s1b24647cdd834a8eaca3032611baf072)。 + +例如,openEuler支持UEFI和legacy BIOS两种安装模式,两种引导场景支持的grub相关包默认都安装,当用户选择legacy BIOS模式安装时,形成空链接文件“/etc/grub2-efi.cfg”;当用户选择UEFI模式安装时,会形成空链接文件“/etc/grub2.cfg”,需要用户根据实际情况处理空链接。 + +### 实现 + +1. 通过如下命令查找系统中的空链接文件。 + + ```sh + find dirname -type l -follow 2>/dev/null + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > dirname为搜索目录的名称,通常需要关注系统关键目录:/bin、/boot、/usr、/lib64、/lib、/var等。 + +2. 如果此类文件无实际作用,可通过如下命令删除。 + + ```sh + rm -f filename + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > filename为[步骤1](#zh-cn_topic_0152100319_l4dc74664c4fb400aaf91fb314c4f9da6)找出的文件名。 + +## 设置守护进程的umask值 + +### 说明 + +umask值用来为新创建的文件和目录设置缺省权限。如果没有设定umask值,则生成的文件具有全局可写权限,存在一定的风险。守护进程负责系统上某个服务,让系统可以接受来自用户或者是网络客户的要求。为了提高守护进程所创建文件和目录的安全性,建议设置其umask值为0027。umask值代表的是权限的“补码”,umask值和权限的换算方法请参见 "[附录 > umask值含义](附录.md/#umask值含义)" 。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> openEuler默认已设置守护进程的umask值为0022。 + +### 实现 + +在配置文件/etc/sysconfig/init中新增一行:umask 0027。 + +## 为全局可写目录添加粘滞位属性 + +### 说明 + +任意用户可以删除、修改全局可写目录中的文件和目录,为了确保全局可写目录中的文件和目录不会被任意删除,需要为全局可写目录添加粘滞位属性。 + +### 实现 + +1. 搜索全局可写目录。 + + ```sh + find / -type d -perm -0002 ! -perm -1000 -ls | grep -v proc + ``` + +2. 为全局可写目录添加粘滞位属性。dirname 为实际查找到的目录名。 + + ```sh + chmod +t dirname + ``` + +## 删除非授权文件的全局可写属性 + +### 说明 + +全局可写文件可被系统中的任意用户修改,影响系统完整性。 + +### 实现 + +1. 列举系统中所有的全局可写文件。 + + ```sh + find / -type d ( -perm -o+w ) | grep -v proc + find / -type f ( -perm -o+w ) | grep -v proc + ``` + +2. 查看步骤1列举的所有文件\(粘滞位的文件和目录可以排除在外\),删除文件或去掉其全局可写权限。使用以下命令去掉权限,其中filename为对应文件名: + + ```sh + chmod o-w filename + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 可通过如下命令确定对应文件或目录是否设置了粘滞位,若回显中包含T标记,则为粘滞位文件或目录。命令中的filename为需要查询文件或目录的名称。 + > `ls -l filename` + +## 限制at命令的使用权限 + +### 说明 + +at命令用于创建在指定时间自动执行的任务。为避免任意用户通过at命令安排工作,造成系统易受攻击,需要指定可使用该命令的用户。 + +### 实现 + +1. 删除/etc/at.deny文件。 + + ```sh + rm -f /etc/at.deny + ``` + +2. 创建/etc/at.allow文件并将/etc/at.allow的文件属主改为root:root。 + + ```sh + touch /etc/at.allow + chown root:root /etc/at.allow + ``` + +3. 控制/etc/at.allow的文件权限,仅root可操作。 + + ```sh + chmod og-rwx /etc/at.allow + ``` + +## 限制cron命令的使用权限 + +### 说明 + +cron命令用于创建例行性任务。为避免任意用户通过cron命令安排工作,造成系统易受攻击,需要指定可使用该命令的用户。 + +### 实现 + +1. 删除/etc/cron.deny文件。 + + ```sh + rm -f /etc/cron.deny + ``` + +2. 创建/etc/cron.allow文件并将/etc/cron.allow的文件属主改为root:root。 + + ```sh + touch /etc/cron.allow + chown root:root /etc/cron.allow + ``` + +3. 控制/etc/cron.allow的文件权限,仅root可操作。 + + ```sh + chmod og-rwx /etc/cron.allow + ``` + +## 限制sudo命令的使用权限 + +### 说明 + +sudo命令用于普通用户以root权限执行命令。为了增强系统安全性,有必要对sudo命令的使用权进行控制,只允许root使用sudo命令,限制其他帐户使用。openEuler默认未限制非root用户使用sudo命令的权限。 + +### 实现 + +sudo命令的使用控制通过修改/etc/sudoers文件实现,需要注释掉如下配置行: + +```sh +#%wheel ALL=(ALL) ALL +``` diff --git a/docs/en/25.03/Server/Security/SecHarden/kernel-parameters.md b/docs/en/25.03/Server/Security/SecHarden/kernel-parameters.md new file mode 100644 index 0000000000000000000000000000000000000000..4e2314812581c39943f2a9f9fdc257bbc949b526 --- /dev/null +++ b/docs/en/25.03/Server/Security/SecHarden/kernel-parameters.md @@ -0,0 +1,224 @@ +# 内核参数 + +## 加固内核参数 + +### 说明 + +内核参数决定配置和应用特权的状态。内核提供用户可配置的系统控制,这一系统控制可微调或配置,该功能特性可通过控制各种可配置的内核参数,来提高操作系统的安全特性。比如:通过微调或配置网络选项,可有效提高系统的安全性。 + +### 实现 + +1. 将[表1](#zh-cn_topic_0152100187_t69b5423c26644b26abe94d88d38878eb)中的加固项写入/etc/sysctl.conf文件中。 + + 写入方式如下: + + ```text + net.ipv4.icmp_echo_ignore_broadcasts = 1 + net.ipv4.conf.all.rp_filter = 1 + net.ipv4.conf.default.rp_filter = 1 + ``` + + **表 1** 内核参数加固策略说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

加固项

+

加固项说明

+

加固建议

+

openEuler默认是否已加固为建议值

+

net.ipv4.icmp_echo_ignore_broadcasts

+

是否接受ICMP广播报文。加固策略为不接受。

+

1

+

+

net.ipv4.conf.all.rp_filter

+

验证数据包使用的实际源地址是否与路由表相关,以及使用该特定源IP地址的数据包是否通过接口获取其响应。加固策略为启用该项。

+

1

+

+

net.ipv4.conf.default.rp_filter

+

1

+

+

net.ipv4.ip_forward

+

IP Forwarding可阻止未授权的IP数据包渗透至网络。加固策略为禁用该特性。

+

0

+

+

net.ipv4.conf.all.accept_source_route

+

accept_source_route指允许数据包的发送者指定数据包的发送路径,以及返回给发送者的数据包所走的路径。加固策略为禁用该特性。

+

0

+

+

net.ipv4.conf.default.accept_source_route

+

0

+

+

net.ipv4.conf.all.accept_redirects

+

是否发送ICMP重定向报文。加固策略为禁止发送。

+

0

+

+

net.ipv4.conf.default.accept_redirects

+

0

+

+

net.ipv6.conf.all.accept_redirects

+

0

+

+

net.ipv6.conf.default.accept_redirects

+

0

+

+

net.ipv4.conf.all.send_redirects

+

是否将ICMP重定向报文发送至其他主机。只有当主机作为路由时,应启用该策略。加固策略为禁用该项。

+

0

+

+

net.ipv4.conf.default.send_redirects

+

0

+

+

net.ipv4.icmp_ignore_bogus_error_responses

+

忽略伪造的ICMP数据包,不会将其记录到日志,将节省大量的硬盘空间。加固策略为启用该项。

+

1

+

+

net.ipv4.tcp_syncookies

+

SYN Attack是一种通过占用系统资源迫使系统重启的DoS攻击。加固策略为开启TCP-SYN cookie保护。

+

1

+

+

kernel.dmesg_restrict

+

加固dmesg信息,仅允许管理员查看。

+

1

+

+

kernel.sched_autogroup_enabled

+

该选项决定内核是否对线程进行自动分组调度。开启后调度组之间互相竞争时间片,调度组内的线程再竞争调度组分配到的时间片。加固策略为不启用该项。

+

0

+

+

kernel.sysrq

+

禁用魔术键。

+
说明:

建议禁用魔术键,避免由于直接发送命令到内核对系统造成影响,增强内核安全性。

+
+

0

+

+

net.ipv4.conf.all.secure_redirects

+

设置系统是接收来自任何主机的ICMP重定向消息还是从默认网关列表中的网关处接收ICMP重定向消息。加固策略为采用前者。

+

0

+

+

net.ipv4.conf.default.secure_redirects

+

0

+

+
+ +2. 加载sysctl.conf文件中设置的内核参数。 + + ```sh + # sysctl -p /etc/sysctl.conf + ``` + +### 其他安全建议 + +- net.ipv4.icmp\_echo\_ignore\_all:忽略ICMP请求。 + + 出于安全考虑,建议开启此项(当前默认值为0,开启将值设为1)。 + + 但开启后会忽略所有接收到的icmp echo请求的包\(会导致机器无法ping通\),建议用户根据实际组网场景决定是否开启此项。 + +- net.ipv4.conf.all.log\_martians/net.ipv4.conf.default.log\_martians:对于仿冒/源路由/重定向数据包开启日志记录。 + + 出于安全考虑,建议开启此项(当前默认值为0,开启将值设为1)。 + + 但是开启后会记录带有不允许的地址的数据到内核日志中,存在冲日志风险,建议用户根据实际使用场景决定是否开启此项。 + +- net.ipv4.tcp\_timestamps:关闭tcp\_timestamps。 + + 出于安全考虑,建议关闭tcp\_timestamps(当前默认值为1,关闭将值设为0)。 + + 但是关闭此项会影响TCP超时重发的性能,建议用户根据实际使用场景决定是否关闭此项。 + +- net.ipv4.tcp\_max\_syn\_backlog:决定了SYN\_RECV状态队列的数量。 + + 该参数决定了SYN\_RECV状态队列的数量,超过这个数量,系统将不再接受新的TCP连接请求,一定程度上可以防止系统资源耗尽。建议由用户根据实际使用场景配置合适的值。 diff --git a/docs/en/25.03/Server/Security/SecHarden/os-hardening-overview.md b/docs/en/25.03/Server/Security/SecHarden/os-hardening-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..40fdc82ae3ed774886e30ab030fccc5a6e5200b7 --- /dev/null +++ b/docs/en/25.03/Server/Security/SecHarden/os-hardening-overview.md @@ -0,0 +1,135 @@ +# 操作系统加固概述 + +介绍对openEuler系统进行加固的目的和加固方案。 + + +- [操作系统加固概述](#操作系统加固概述) + - [加固目的](#加固目的) + - [加固方案](#加固方案) + - [加固影响](#加固影响) + + + +## 须知 + +由于安全加固对系统至关重要,因此只有root用户允许修改并应用安全加固策略。 + +## 加固目的 + +操作系统作为信息系统的核心,承担着管理硬件资源和软件资源的重任,是整个信息系统安全的基础。操作系统之上的各种应用,要想获得信息的完整性、机密性、可用性和可控性,必须依赖于操作系统。脱离了对操作系统的安全保护,仅依靠其他层面的防护手段来阻止黑客和病毒等对网络信息系统的攻击,是无法满足安全需求的。 + +因此,需要对操作系统进行安全加固,构建动态、完整的安全体系,增强产品的安全性,提升产品的竞争力。 + +## 加固方案 + +本章描述openEuler的安全加固方案,包括加固方式和加固内容。 + +### 加固方式 + +用户可以通过手动修改加固配置或执行相关命令对系统进行加固,也可以通过加固工具批量修改加固项。openEuler的安全加固工具security tool以openEuler-security.service服务的形式运行。系统首次启动时会自动运行该服务去执行默认加固策略,服务运行后会将该服务自动设置为后续开机不启动。 + +用户可以通过修改security.conf,使用安全加固工具实现个性化安全加固的效果。 + +### 加固内容 + +openEuler系统加固内容主要分为以下5个部分: + +- 系统服务 +- 文件权限 +- 内核参数 +- 授权认证 +- 帐号口令 + +## 加固影响 + +对文件权限、帐户口令等安全加固,可能造成用户使用习惯变更,从而影响系统的易用性。影响系统易用性的常见加固项请参见[表1](#zh-cn_topic_0152100325_ta4a48f54ff2849ada7845e2380209917)。 + +**表 1** 加固影响说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

加固项

+

建议加固

+

易用性影响

+

openEuler默认是否设置了该加固项

+

字符界面等待超时限制

+

当字符界面长时间处在空闲状态,字符界面会自动退出。

+
说明:

当用户通过SSH登录,超时时间由/etc/profile文件的TMOUT字段和/etc/ssh/sshd_config文件的ClientAliveInterval字段两个值中较小的值决定。建议加固为300秒。

+
+

用户长时间不操作字符界面,字符界面会自动退出。

+

+

口令复杂度限制

+

口令长度最小为8位,口令至少包含大写字母、小写字母、数字和特殊字符中的3种。

+

系统中所有用户不能设置简单的口令,口令必须符合复杂度要求。

+

+

限定登录失败时的尝试次数

+

当用户登录系统时,口令连续输错3次,帐户将被锁定60秒,锁定期间不能登录系统。

+

用户不能随意登录系统,帐户被锁定后必须等待60秒。

+

+

用户默认umask值限制

+

设置所有用户的默认umask值为077,使用户创建文件的默认权限为600、目录权限为700。

+

用户需要按照需求修改指定文件或目录的权限。

+

+

口令有效期

+

口令有效期的设置通过修改/etc/login.defs文件实现,加固默认值为口令最大有效期90天,两次修改口令的最小间隔时间为0,口令过期前开始提示天数为7。

+

口令过期后用户重新登录时,提示口令过期并强制要求修改,不修改则无法进入系统。

+

+

su权限限制

+

su命令用于在不同帐户之间切换。为了增强系统安全性,有必要对su命令的使用权进行控制,只允许root和wheel群组的帐户使用su命令,限制其他帐户使用。

+

普通帐户执行su命令失败,必须加入wheel群组才可以su成功。

+

+

禁止root帐户直接SSH登录系统

+

设置/etc/ssh/sshd_config文件的PermitRootLogin字段的值为no,用户无法使用root帐户直接SSH登录系统。

+

用户需要先使用普通帐户SSH登录后,再切换至root帐户。

+

+

SSH强加密算法

+

SSH服务的MACs和Ciphers配置,禁止对CBC、MD5、SHA1算法的支持,修改为CTR、SHA2算法。

+

当前 Windows下使用的部分低版本的Xshell、PuTTY不支持aes128-ctr、aes192-ctr、aes256-ctr、hmac-sha2-256、hmac-sha2-512算法,可能会出现无法通过SSH登录系统的情况,请使用最新的PuTTY(0.63版本以上)、Xshell(5.0版本及以上版本)登录。

+

+
diff --git a/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-caution.gif b/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-caution.gif differ diff --git a/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-danger.gif b/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-danger.gif differ diff --git a/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-note.gif b/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-notice.gif b/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-notice.gif differ diff --git a/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-tip.gif b/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-tip.gif differ diff --git a/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-warning.gif b/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Server/Security/SecHarden/public_sys-resources/icon-warning.gif differ diff --git a/docs/en/25.03/Server/Security/SecHarden/secHarden.md b/docs/en/25.03/Server/Security/SecHarden/secHarden.md new file mode 100644 index 0000000000000000000000000000000000000000..004a6114a8c7a9720d6c013a0879f00ec5e9fd41 --- /dev/null +++ b/docs/en/25.03/Server/Security/SecHarden/secHarden.md @@ -0,0 +1,5 @@ +# 安全加固指南 + +本文档给出openEuler的加固介绍和加固方法,指导用户进行安全加固。 + +本文档主要适用于需要对openEuler进行安全加固的管理员。管理员需要熟悉操作系统安全架构和安全技术。 diff --git a/docs/en/25.03/Server/Security/SecHarden/security-configuration-benchmark.md b/docs/en/25.03/Server/Security/SecHarden/security-configuration-benchmark.md new file mode 100644 index 0000000000000000000000000000000000000000..1f12011defdaf8af964a937023d798d6b08302b1 --- /dev/null +++ b/docs/en/25.03/Server/Security/SecHarden/security-configuration-benchmark.md @@ -0,0 +1,3 @@ +# openEuler安全配置说明 + +详细内容请参考[openEuler安全配置说明](https://gitee.com/openeuler/security-committee/tree/master/secure-configuration-benchmark)。 diff --git a/docs/en/25.03/Server/Security/SecHarden/security-hardening-guide.md b/docs/en/25.03/Server/Security/SecHarden/security-hardening-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..d8f4f7cd5b1e0c5d07d9c7c33b62a4cfac5965ab --- /dev/null +++ b/docs/en/25.03/Server/Security/SecHarden/security-hardening-guide.md @@ -0,0 +1,3 @@ +# 加固指导 + +用户可以通过修改加固策略配置文件或加固脚本进行系统加固。本节介绍各加固项的含义以及openEuler是否已默认加固,并给出加固方法,指导用户进行安全加固。 diff --git a/docs/en/25.03/Server/Security/SecHarden/security-hardening-tools.md b/docs/en/25.03/Server/Security/SecHarden/security-hardening-tools.md new file mode 100644 index 0000000000000000000000000000000000000000..bc816fec8c2cd358e1a27a4d3c1949affa903e6c --- /dev/null +++ b/docs/en/25.03/Server/Security/SecHarden/security-hardening-tools.md @@ -0,0 +1,121 @@ +# 安全加固工具 + +## 加固操作 + +### 概述 + +安全加固工具会根据usr-security.conf设置加固策略,使用加固工具设置加固策略需要用户修改usr-security.conf。本节介绍usr-security.conf的修改规则。用户可配置的加固项请参见[加固指导](https://openeuler.org/zh/docs/21.03/docs/SecHarden/%E5%8A%A0%E5%9B%BA%E6%8C%87%E5%AF%BC.html)对应内容。 + +### 注意事项 + +- 修改配置后,需要重启安全加固服务使配置生效。重启方法请参见[加固生效](#加固生效)对应内容。 +- 用户修改加固配置时,仅修改/etc/openEuler\_security/usr-security.conf文件,不建议修改/etc/openEuler\_security/security.conf。security.conf中为基本加固项,仅运行一次。 +- 当重启安全加固服务使配置生效后,在usr-security.conf中删除对应加固项并重启安全加固服务并不能清除之前已生效的配置。 +- 安全加固操作记录在日志文件/var/log/openEuler-security.log中。 + +### 配置格式 + +usr-security.conf中的每一行代表一项配置,根据配置内容的不同有不同配置格式,这里给出各类配置的格式说明。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 所有配置项以执行ID开头,执行ID仅为了方便用户识别配置内容,取值为正整数,由用户自行定义。 +> 配置项的各内容之间使用@作为分隔符。 +> 若实际配置内容中包含@,需要使用@@表示以和分隔符区分,例如实际内容为xxx@yyy,则配置为xxx@@yyy。目前不支持@位于配置内容的开头和结尾。 + +- d:注释 + + 格式:执行ID@d@对象文件@匹配项 + + 功能:将对象文件中以匹配项开头(行首可以有空格)的行注释(在行首添加\#)。 + + 示例:执行ID为401,注释/etc/sudoers文件中以%wheel开头的行。 + + ```sh + 401@d@/etc/sudoers@%wheel + ``` + +- m:替换 + + 格式:执行ID@m@对象文件@匹配项@替换目标值 + + 功能:将对象文件中以匹配项开头(行首可以有空格)的行替换为“匹配项加替换目标值 ”。若匹配行开头有空格,替换后将删除这些空格。 + + 示例:执行ID为101,将/etc/ssh/sshd\_config文件中以Protocol 开头的行替换为Protocol 2。匹配和替换时也会考虑Protocol后的空格。 + + ```sh + 101@m@/etc/ssh/sshd_config@Protocol @2 + ``` + +- sm:精确修改 + + 格式:执行ID@sm@对象文件@匹配项@替换目标值 + + 功能:将对象文件中以匹配项开头(行首可以有空格)的行替换为“匹配项加替换目标值 ”。若匹配行开头有空格,替换后将保留这些空格,这是sm和m的区别。 + + 示例:执行ID为201,将/etc/audit/hzqtest文件中以size开头的行替换为size 2048。 + + ```sh + 201@sm@/etc/audit/hzqtest@size@ 2048 + ``` + +- M:修改子项 + + 格式:执行ID@M@对象文件@匹配项@匹配子项\[@匹配子项的值\] + + 功能:匹配对象文件中以匹配项开头(行首可以有空格)的行,并将该行中以匹配子项开始的内容替换为“匹配子项和匹配子项的值”,其中匹配子项的值可选。 + + 示例:执行ID为101,找到file文件中以key开头的行,并将这些行中以key2开始的内容替换为key2value2。 + + ```sh + 101@M@file@key@key2@value2 + ``` + +- systemctl:管理服务 + + 格式:执行ID@systemctl@对象服务@具体操作 + + 功能:使用systemctl管理对象服务,具体操作可取值为start、stop、restart、disable等systemctl所有可用的命令。 + + 示例:执行ID为218,停止cups.service服务,等同于systemctl stop cups.service的配置行。 + + ```sh + 218@systemctl@cups.service@stop + ``` + +- 其他命令 + + 格式:执行ID@命令@对象文件 + + 功能:执行对应命令,即执行命令行“命令 对象文件”。 + + 示例一:执行ID为402,使用rm -f命令删除文件/etc/pki/ca-trust/extracted/pem/email-ca-bundle.pem。 + + ```sh + 402@rm -f @/etc/pki/ca-trust/extracted/pem/email-ca-bundle.pem + ``` + + 示例二:执行ID为215,使用touch命令创建文件/etc/cron.allow。 + + ```sh + 215@touch @/etc/cron.allow + ``` + + 示例三:执行ID为214,使用chown命令将文件/etc/at.allow的属主改为root:root。 + + ```sh + 214@chown root:root @/etc/at.allow + ``` + + 示例四:执行ID为214,使用chmod命令去除文件/etc/at.allow属主所在群组及其他非属主用户的rwx权限。 + + ```sh + 214@chmod og-rwx @/etc/at.allow + ``` + +## 加固生效 + +完成修改usr-security.conf文件后,请运行如下命令使新添加的配置生效。 + +```sh +systemctl restart openEuler-security.service +``` diff --git a/docs/en/25.03/Server/Security/SecHarden/selinux-configuration.md b/docs/en/25.03/Server/Security/SecHarden/selinux-configuration.md new file mode 100644 index 0000000000000000000000000000000000000000..0f238499ece0c85ae9a642c2603e414950ace926 --- /dev/null +++ b/docs/en/25.03/Server/Security/SecHarden/selinux-configuration.md @@ -0,0 +1,273 @@ +# SELinux配置 + +## 概述 + +自主访问控制DAC(Discretionary Access Control)基于用户、组和其他权限,决定一个资源是否能被访问的因素是某个资源是否拥有对应用户的权限,它不能使系统管理员创建全面和细粒度的安全策略。SELinux(Security-Enhanced Linux)是Linux内核的一个模块,也是Linux的一个安全子系统。SELinux的实现了强制访问控制MAC(Mandatory Access Control ),每个进程和系统资源都有一个特殊的安全标签,资源能否被访问除了DAC规定的原则外,还需要判断每一类进程是否拥有对某一类资源的访问权限。 + +openEuler默认使用SELinux提升系统安全性。SELinux分为三种模式: + +- permissive:SELinux仅打印告警而不强制执行。 +- enforcing:SELinux安全策略被强制执行。 +- disabled:不加载SELinux安全策略。 + +## 配置说明 + +- 获取当前SELinux运行状态: + + ```sh + # getenforce + Enforcing + ``` + +- SELinux开启的前提下,设置运行状态为enforcing模式: + + ```sh + # setenforce 1 + # getenforce + Enforcing + ``` + +- SELinux开启的前提下,设置运行状态为permissive模式: + + ```sh + # setenforce 0 + # getenforce + Permissive + ``` + +- SELinux开启的前提下,设置当前SELinux运行状态为disabled(关闭SELinux,需要重启系统)。 + 1. 修改SELinux配置文件/etc/selinux/config,设置“SELINUX=disabled”。 + + ```sh + # cat /etc/selinux/config | grep "SELINUX=" + SELINUX=disabled + ``` + + 2. 重启系统: + + ```sh + # reboot + ``` + + 3. 状态切换成功: + + ```sh + # getenforce + Disabled + ``` + +- SELinux关闭的前提下,设置SELinux运行状态为permissive。 + 1. 修改SELinux配置文件/etc/selinux/config,设置“SELINUX=permissive”: + + ```sh + # cat /etc/selinux/config | grep "SELINUX=" + SELINUX=permissive + ``` + + 2. 在根目录下创建.autorelabel文件: + + ```sh + # touch /.autorelabel + ``` + + 3. 重启系统,此时系统会重启两次: + + ```sh + # reboot + ``` + + 4. 状态切换成功: + + ```sh + # getenforce + Permissive + ``` + +- SELinux关闭的前提下,设置SELinux运行状态为enforcing。 + 1. 按照上一步骤所述,设置SELinux运行状态为permissive。 + 2. 修改SELinux配置文件/etc/selinux/config,设置“SELINUX=enforcing”: + + ```sh + # cat /etc/selinux/config | grep "SELINUX=" + SELINUX=enforcing + ``` + + 3. 重启系统: + + ```sh + # reboot + ``` + + 4. 状态切换成功: + + ```sh + # getenforce + Enforcing + ``` + +## SELinux相关命令 + +- 查询运行SELinux的系统状态。SELinux status表示SELinux的状态,enabled表示启用SELinux,disabled表示关闭SELinux。Current mode表示SELinux当前的安全策略。 + + ```sh + # sestatus + SELinux status: enabled + SELinuxfs mount: /sys/fs/selinux + SELinux root directory: /etc/selinux + Loaded policy name: targeted + Current mode: enforcing + Mode from config file: enforcing + Policy MLS status: enabled + Policy deny_unknown status: allowed + Memory protection checking: actual (secure) + Max kernel policy version: 31 + ``` + +## 策略添加 + +- 从audit日志中获取并添加缺失策略(需要audit服务开启且audit日志中已经存在SELinux访问拒绝日志)。 + 1. 查询audit日志中是否有SELinux访问拒绝日志,其中audit日志的路径视具体情况决定。 + + ```sh + # grep avc /var/log/audit/audit.log* + ``` + + 2. 查询缺失规则。 + + ```sh + # audit2allow -a /var/log/audit/audit.log* + ``` + + 3. 根据缺失规则生成一个策略模块,命名为demo。 + + ```sh + # audit2allow -a /var/log/audit/audit.log* -M demo + ******************** IMPORTANT *********************** + To make this policy package active, execute: + semodule -i demo.pp + ``` + + 4. 加载demo策略模块。 + + ```sh + # semodule -i demo.pp + ``` + +- 编写并添加SELinux策略模块。 + 1. 编写FC文件(涉及新增文件安全上下文需要编写)。 + + ```sh + # cat demo.fc + /usr/bin/example -- system_u:object_r:example_exec_t:s0 + /resource -- system_u:object_r:resource_file_t:s0 + ``` + + 2. 编写TE文件(仅供参考)。 + + ```sh + # cat demo.te + module demo 1.0; + require + { + role unconfined_r; + role system_r; + type user_devpts_t; + type root_t; + attribute file_type; + attribute domain; + class dir { getattr search add_name create open remove_name rmdir setattr write }; + class file { entrypoint execute getattr open read map setattr write create }; + class process { sigchld rlimitinh siginh transition setcap getcap }; + class unix_stream_socket { accept bind connect listen recvfrom sendto listen create lock read write getattr setattr getopt setopt append shutdown ioctl connectto }; + class capability { chown dac_override dac_read_search }; + class chr_file { append getattr ioctl read write }; + }; + role unconfined_r types example_t; + role system_r types example_t; + type example_exec_t, file_type; + type resource_file_t, file_type; + type example_t, domain; + allow example_t user_devpts_t : chr_file { append getattr ioctl read write }; + allow example_t file_type : dir { getattr search }; + allow example_t example_exec_t : file { entrypoint execute getattr map open read }; + allow domain example_exec_t : file { execute getattr map open read }; + allow example_t example_exec_t : process { sigchld }; + allow domain example_t : process { rlimitinh siginh transition }; + allow example_t resource_file_t : file { create getattr open read setattr write }; + allow example_t root_t : dir { add_name create getattr open remove_name rmdir search setattr write }; + allow example_t example_t : unix_stream_socket { accept append bind connect create getattr getopt ioctl listen listen lock read recvfrom sendto setattr setopt shutdown write }; + allow example_t domain : unix_stream_socket { connectto }; + allow example_t example_t : capability { chown dac_override dac_read_search }; + allow example_t example_t : process { getcap setcap }; + type_transition domain example_exec_t : process example_t; + type_transition example_t root_t : file resource_file_t "resource"; + ``` + + 3. 编译demo.te为demo.mod。 + + ```sh + # checkmodule -Mmo demo.mod demo.te + ``` + + 4. 打包demo.mod和demo.fc为策略模块文件。 + + ```sh + semodule_package -m demo.mod -f demo.fc -o demo.pp + ``` + + 5. 加载策略模块。 + + ```sh + # semodule -i demo.pp + ``` + + 6. 删除加载的策略模块。 + + ```sh + # semodule -r demo + libsemanage.semanage_direct_remove_key: Removing last demo module (no other demo module exists at another priority). + ``` + +## 功能验证 + +- SELinux为白名单机制,未配置合理策略的模块可能会由于缺少权限无法正常运行。故对模块进行功能验证并适配合理的规则是很有必要的。 + 1. 查看audit服务是否开启。 + + ```sh + # systemctl status auditd + ``` + + 2. 设置SELinux模式为permissive(仅打印告警而不强制执行,参考 配置说明 )。 + + ```sh + # getenforce + Permissive + ``` + + 3. 全量跑测试模块的功能用例,查看audit日志中SELinux访问拒绝日志。 + + ```sh + # grep avc /var/log/audit/audit.log* + ``` + + 4. 分析访问拒绝日志,并过滤出缺失的合理规则。 + + ```sh + type=AVC msg=audit(1596161643.271:1304): avc: denied { read } for pid=1782603 comm="smbd" name=".viminfo" dev="dm-0" ino=2488208 scontext=system_u:system_r:smbd_t:s0 tcontext=staff_u:object_r:user_home_t:s0 tclass=file permissive=1 + 表示进程smbd(安全上下文为system_u:system_r:smbd_t:s0)对文件.viminfo(安全上下文为staff_u:object_r:user_home_t:s0)执行文件读操作被权限拒绝。 + permissive=1表示当前运行的是permissive模式,该日志只记录未执行禁止。 + ``` + + 5. 参考“策略添加”章节,将缺少的合理规则补全。 + +## 注意事项 + +- 如用户需使能SELinux功能,建议通过dnf升级方式将selinux-policy更新为最新版本,否则应用程序有可能无法正常运行。升级命令示例: + + ```sh + dnf update selinux-policy -y + ``` + +- 如果用户由于SELinux配置不当(如误删策略或未配置合理的规则或安全上下文)导致系统无法启动,可以在启动参数中添加selinux=0,关闭SELinux功能,系统即可正常启动。 + +- 开启SELinux后,会对访问行为进行权限检查,对操作系统性能会有一定程度(与运行环境访问操作频率相关)的影响。 diff --git a/docs/en/25.03/Server/Security/SecHarden/system-services.md b/docs/en/25.03/Server/Security/SecHarden/system-services.md new file mode 100644 index 0000000000000000000000000000000000000000..3b4aaa3f855161eef63321f8efda9dc02bf55905 --- /dev/null +++ b/docs/en/25.03/Server/Security/SecHarden/system-services.md @@ -0,0 +1,452 @@ +# 系统服务 + +## 加固SSH服务 + +### 说明 + +SSH(Secure Shell)是目前较可靠,专为远程登录会话和其他网络服务提供安全性保障的协议。利用SSH协议可以有效防止远程管理过程中的信息泄露问题。通过SSH可以对所有传输的数据进行加密,并防止DNS欺骗和IP欺骗。OpenSSH是SSH协议的免费开源实现。 + +加固SSH服务,是指修改SSH服务中的配置来设置系统使用OpenSSH协议时的算法、认证等参数,从而提高系统的安全性。[表1](#zh-cn_topic_0152100390_ta2fdb8e4931b4c1a8f502b3c7d887b95)中详细说明了各加固项含义、建议加固值及其默认策略。 + +### 实现 + +服务端加固操作如下: + +1. 打开服务端SSH服务的配置文件/etc/ssh/sshd\_config,在该文件中修改或添加对应加固项及其加固值。 +2. 保存/etc/ssh/sshd\_config文件。 +3. 重启SSH服务,命令如下: + + ```sh + # systemctl restart sshd + ``` + +客户端加固操作如下: + +1. 打开客户端SSH服务的配置文件/etc/ssh/ssh\_config,在该文件中修改或添加对应加固项及其加固值。 +2. 保存/etc/ssh/ssh\_config文件。 +3. 重启SSH服务,命令如下: + + ```sh + # systemctl restart sshd + ``` + +### 加固项说明 + +- 服务端加固策略 + + SSH服务的所有加固项均保存在配置文件/etc/ssh/sshd\_config中,服务端各加固项的含义、加固建议以及openEuler默认是否已经加固为建议加固值请参见[表1](#zh-cn_topic_0152100390_ta2fdb8e4931b4c1a8f502b3c7d887b95)。 + + **表 1** SSH服务端加固项说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

加固项

+

加固项说明

+

加固建议

+

openEuler默认是否已加固为建议值

+

Protocol

+

设置使用SSH协议的版本

+

2

+

+

SyslogFacility

+

设置SSH服务的日志类型。加固策略将其设置为“AUTH”,即认证类日志

+

AUTH

+

+

LogLevel

+

设置记录sshd日志消息的层次

+

VERBOSE

+

+

X11Forwarding

+

设置使用SSH登录后,能否使用图形化界面

+

no

+

+

MaxAuthTries

+

最大认证尝试次数

+

3

+

+

PubkeyAuthentication

+

设置是否允许公钥认证。

+

yes

+

+

RSAAuthentication

+

设置是否允许只有RSA安全验证

+

yes

+

+

IgnoreRhosts

+

设置是否使用rhosts文件和shosts文件进行验证。rhosts文件和shosts文件用于记录可以访问远程计算机的计算机名及关联的登录名

+

yes

+

+

RhostsRSAAuthentication

+

设置是否使用基于rhosts的RSA算法安全验证。rhosts文件记录可以访问远程计算机的计算机名及关联的登录名

+

no

+

+

HostbasedAuthentication

+

设置是否使用基于主机的验证。基于主机的验证是指已信任客户机上的任何用户都可以使用SSH连接

+

no

+

+

PermitRootLogin

+

+

是否允许root帐户直接使用SSH登录系统

+
说明:

若需要直接使用root帐户通过SSH登录系统,请修改/etc/ssh/sshd_config文件的PermitRootLogin字段的值为yes。

+
+

no

+

+

PermitEmptyPasswords

+

设置是否允许用口令为空的帐号登录

+

no

+

+

PermitUserEnvironment

+

设置是否解析 ~/.ssh/environment和~/.ssh/authorized_keys中设定的环境变量

+

no

+

+

Ciphers

+

设置SSH数据传输的加密算法

+

aes128-ctr,aes192-ctr,aes256-ctr,chacha20-poly1305@openssh.com,aes128-gcm@openssh.com,aes256-gcm@openssh.com

+

+

ClientAliveCountMax

+

设置超时次数。服务器发出请求后,客户端没有响应的次数达到一定值,连接自动断开

+

0

+

+

Banner

+

指定登录SSH前后显示的提示信息的文件

+

/etc/issue.net

+

+

MACs

+

设置SSH数据校验的哈希算法

+

hmac-sha2-512,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-256-etm@openssh.com

+

+

StrictModes

+

设置SSH在接收登录请求之前是否检查用户HOME目录和rhosts文件的权限和所有权

+

yes

+

+

UsePAM

+

使用PAM登录认证

+

yes

+

+

AllowTcpForwarding

+

设置是否允许TCP转发

+

no

+

+

Subsystem sftp /usr/libexec/openssh/sftp-server

+

sftp日志记录级别,记录INFO级别以及认证日志。

+

-l INFO -f AUTH

+

+

AllowAgentForwarding

+

设置是否允许SSH Agent转发

+

no

+

+

GatewayPorts

+

设置是否允许连接到转发客户端端口

+

no

+

+

PermitTunnel

+

Tunnel设备是否允许使用

+

no

+

+

KexAlgorithms

+

设置SSH密钥交换算法

+

curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256

+
  

LoginGraceTime

+

限制用户必须在指定的时限内认证成功,0 表示无限制。缺省值是 60 秒。

+

60

+

+
+ + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 默认情况下,登录SSH前后显示的提示信息保存在/etc/issue.net文件中,/etc/issue.net默认信息为“Authorized users only. All activities may be monitored and reported.”。 + +- 客户端加固策略 + + SSH服务的所有加固项均保存在配置文件/etc/ssh/ssh\_config中,客户端各加固项的含义、加固建议以及openEuler默认是否已经加固为建议加固值请参见[表2](#zh-cn_topic_0152100390_tb289c5a6f1c7420ab4339187f9018ea4)。 + + **表 2** SSH客户端加固项说明 + + + + + + + + + + + + + + + + + + + +

加固项

+

加固项说明

+

加固建议

+

openEuler默认是否已加固为建议值

+

KexAlgorithms

+

设置SSH密钥交换算法

+

ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256

+

+

VerifyHostKeyDNS

+

是否使用DNS或者SSHFP资源记录验证HostKey

+

ask

+

+
+ + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 对于使用dh算法进行密钥交换的第三方客户端和服务端工具,要求允许建立连接的最低长度为2048bits。 + +### 其他安全建议 + +- SSH服务仅侦听指定IP地址 + + 出于安全考虑,建议用户在使用SSH服务时,仅在必需的IP上进行绑定侦听,而不是侦听0.0.0.0,可修改/etc/ssh/sshd\_config文件中的ListenAddress配置项。 + + 1. 打开并修改/etc/ssh/sshd\_config文件 + + ```sh + # vi /etc/ssh/sshd_config + ``` + + 修改内容如下,表示绑定侦听IP为 _192.168.1.100_,用户可根据实际情况修改需要侦听的IP + + ```Conf + ... + ListenAddress 192.168.1.100 + ... + ``` + + 2. 重启SSH服务 + + ```sh + # systemctl restart sshd.service + ``` + +- 限制SFTP用户向上跨目录访问 + + SFTP是FTP over SSH的安全FTP协议,对于访问SFTP的用户建议使用专用帐号,只能上传或下载文件,不能用于SSH登录,同时对SFTP可以访问的目录进行限定,防止目录遍历攻击,具体配置如下: + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > sftpgroup为示例用户组,sftpuser为示例用户名。 + + 1. 创建SFTP用户组 + + ```sh + # groupadd sftpgroup + ``` + + 2. 创建SFTP根目录 + + ```sh + # mkdir /sftp + ``` + + 3. 修改SFTP根目录属主和权限 + + ```sh + # chown root:root /sftp + # chmod 755 /sftp + ``` + + 4. 创建SFTP用户 + + ```sh + # useradd -g sftpgroup -s /sbin/nologin sftpuser + ``` + + 5. 设置SFTP用户的口令 + + ```sh + # passwd sftpuser + ``` + + 6. 创建SFTP用户上传目录 + + ```sh + # mkdir /sftp/sftpuser + ``` + + 7. 修改SFTP用户上传目录属主和权限 + + ```sh + # chown root:root /sftp/sftpuser + # chmod 777 /sftp/sftpuser + ``` + + 8. 修改/etc/ssh/sshd\_config文件 + + ```sh + # vi /etc/ssh/sshd_config + ``` + + 修改内容如下: + + ```sh + #Subsystem sftp /usr/libexec/openssh/sftp-server -l INFO -f AUTH + Subsystem sftp internal-sftp -l INFO -f AUTH + ... + + Match Group sftpgroup + ChrootDirectory /sftp/%u + ForceCommand internal-sftp + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > %u代表当前sftp用户的用户名,这是一个通配符,用户原样输入即可。 + > 以下内容必须加在/etc/ssh/sshd\_config文件的末尾: + > Match Group sftpgroup + >   ChrootDirectory /sftp/%u + >   ForceCommand internal-sftp + + 9. 重启SSH服务 + + ```sh + # systemctl restart sshd.service + ``` + +- SSH远程执行命令 + + OpenSSH通用机制,在远程执行命令时,默认不开启tty,如果执行需要密码的命令,密码会明文回显。出于安全考虑,建议用户增加-t选项,确保密码输入安全。如下: + + ```sh + # ssh -t testuser@192.168.1.100 su + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 192.168.1.100为示例IP,testuser为示例用户。 diff --git a/docs/en/25.03/Server/Security/ShangMi/_menu.md b/docs/en/25.03/Server/Security/ShangMi/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..0b8e6a704be778fa833a2dda78ab6912ac04ff3e --- /dev/null +++ b/docs/en/25.03/Server/Security/ShangMi/_menu.md @@ -0,0 +1,28 @@ +--- +label: '国密' +ismanual: 'Y' +description: '对操作系统的关键安全特性进行国密算法使能' +children: + - label: '概述' + href: './overview.md' + - label: '磁盘加密' + href: './disk-encryption.md' + - label: '内核模块签名' + href: './kernel-module-signing.md' + - label: '算法库' + href: './algorithm-library.md' + - label: '文件完整性保护' + href: './file-integrity-protection.md' + - label: '用户身份鉴别' + href: './user-identity-authentication.md' + - label: '证书' + href: './certificates.md' + - label: '安全启动' + href: './secure-boot.md' + - label: 'SSH协议栈' + href: './ssh-stack.md' + - label: 'TLCP协议栈' + href: './tlcp-stack.md' + - label: 'RPM支持国密签名验签' + href: './rpm-signature-verification.md' +--- \ No newline at end of file diff --git a/docs/en/25.03/Server/Security/ShangMi/algorithm-library.md b/docs/en/25.03/Server/Security/ShangMi/algorithm-library.md new file mode 100644 index 0000000000000000000000000000000000000000..363f515f21e2974c49a6f4b68c7abcc3c9232612 --- /dev/null +++ b/docs/en/25.03/Server/Security/ShangMi/algorithm-library.md @@ -0,0 +1,193 @@ +# 算法库 + +## openSSL加密接口 + +openSSL是常用的密码算法库软件,当前已经支持商密算法SM2/3/4,用户可以通过命令行或API调用商密算法的加解密功能。 + +### 前置条件 + +openSSL大于或等于1.1.1m-6版本: + +```bash +$ rpm -qa openssl +openssl-1.1.1m-6.oe2209.x86_64 +``` + +### 如何使用 + +#### 场景1:使用命令行调用密码算法 + +1. SM2公钥算法 + + 生成SM2私钥: + + ```bash + $ openssl ecparam -genkey -name SM2 -out priv.key + ``` + + 根据私钥生成公钥: + + ```bash + $ openssl ec -in priv.key -pubout -out pub.key + read EC key + writing EC key + ``` + + 使用SM2算法对文件进行签名,摘要算法指定为SM3: + + ```bash + $ openssl dgst -sm3 -sign priv.key -out data.sig data + ``` + + 使用公钥进行验签: + + ```bash + $ openssl dgst -sm3 -verify pub.key -signature data.sig data + Verified OK + ``` + +2. SM3摘要算法 + + 使用SM3算法计算数据摘要: + + ```bash + $ openssl dgst -sm3 data + SM3(data)= a794922bb9f0a034257f6c7090a3e8429801a42d422c21f1473e83b7f7eac385 + ``` + +3. SM4对称加密算法 + + 使用SM4算法对数据进行加密,其中-K和-iv分别指定加密所使用的key值和iv值,通常需要随机生成: + + ```bash $ openssl enc -sm4 -in data -K 123456789ABCDEF0123456789ABCDEF0 -iv 123456789ABCDEF0123456789ABCDEF0 -out data.enc + ``` + + 使用SM4算法对数据进行解密: + + ```bash + $ openssl enc -d -sm4 -in data.enc -K 123456789ABCDEF0123456789ABCDEF0 -iv 123456789ABCDEF0123456789ABCDEF0 -out data.raw + ``` + + 对比加解密数据,结果一致: + + ```bash + $ diff data data.raw + ``` + +#### 场景2:使用API调用密码算法 + +可直接安装openssl-help并查询man手册: + +```bash +$ yum install openssl-help +$ man sm2 +$ man EVP_sm3 +$ man EVP_sm4_cbc +``` + +## 内核加密接口 + +### 概述 + +Linux内核的加密算法采用crypto框架管理,不同的算法实现在crypto框架中分别进行注册和调用。openEuler提供的5.10内核提供了对商密算法(SM2/3/4)的支持,其中SM2/3算法默认编译在内核中,SM4算法以内核模块的形式提供。 + +### 前置条件 + +内核大于或等于5.10.0-106版本: + +```bash +# rpm -qa kernel +kernel-5.10.0-106.1.0.55.oe2209.x86_64 +``` + +### 如何使用 + +#### 场景1:查询内核支持的加密算法 + +通过/proc/crypto查询已注册的商密算法,其中SM2/SM3算法默认加载: + +```bash +$ cat /proc/crypto | grep sm3 -A8 +name : sm3 +driver : sm3-generic +module : kernel +priority : 100 +refcnt : 1 +selftest : passed +internal : no +type : shash +blocksize : 64 +digestsize : 32 + +$ cat /proc/crypto | grep sm2 -A6 +name : sm2 +driver : sm2-generic +module : kernel +priority : 100 +refcnt : 1 +selftest : passed +internal : no +type : akcipher +``` + +sm4算法默认不加载,需要先插入对应模块: + +```bash +$ modprobe sm4-generic +$ cat /proc/crypto | grep sm4 -A8 +name : sm4 +driver : sm4-generic +module : sm4_generic +priority : 100 +refcnt : 1 +selftest : passed +internal : no +type : cipher +blocksize : 16 +min keysize : 16 +max keysize : 16 +``` + +#### 场景2:算法API调用 + +商密算法的调用和其他相同类型的算法调用方法一致,可参考Linux内核文档: + +```bash +https://www.kernel.org/doc/html/v5.10/crypto/userspace-if.html +``` + +#### 场景3:指令集优化 + +Crypto框架支持注册架构相关的算法实现,可以通过特定指令集实现算法性能的优化。当前openEuler 5.10内核支持的指令集优化包括: + +| 驱动 | 指令集支持 | 优先级 | +| -------------------------------- | ---------------------- | ------ | +| sm4-neon(ecb/cbc/cfb/ctr) | ARM64-NEON指令集 | 200 | +| sm3-avx | X86-AVX指令集 | 300 | +| sm4-aesni-avx (ecb/cbc/cfb/ctr) | X86-AVX指令集 | 400 | +| sm4-aesni-avx 2(ecb/cbc/cfb/ctr) | X86-AVX2指令集 | 500 | + +当同一个算法注册多个实例时,按照各个算法实例注册的priority选择默认的算法实现,priority数值越大则优先级越高,纯软件的算法实现(后缀为-generic)的priority固定为100。商密算法的指令集优化不默认使能,以内核模块的形式对用户提供,如使能SM3算法的AVX指令集优化的方法为: + +```bash +$ modprobe sm3-avx +$ cat /proc/crypto | grep sm3 -A8 +name : sm3 +driver : sm3-avx +module : sm3_avx_x86_64 +priority : 300 +refcnt : 1 +selftest : passed +internal : no +type : shash +blocksize : 64 +digestsize : 32 + +...... +``` + +#### 注意事项 + +1. 算法指令集优化使能的前提是CPU支持对应指令集,可以通过/proc/cpuinfo接口查询当前CPU支持的指令集; +2. 特定指令集的调用本身存在一定开销,因此并不能保证在所有的场景下,指令集优化的性能都高于软件实现; +3. 部分指令集优化存在一定限制,如neon指令集仅在支持并行计算的加密模式下存在优化效果。 diff --git a/docs/en/25.03/Server/Security/ShangMi/certificates.md b/docs/en/25.03/Server/Security/ShangMi/certificates.md new file mode 100644 index 0000000000000000000000000000000000000000..1f07e5efbf5c94582aad567276df8dd8a3900f79 --- /dev/null +++ b/docs/en/25.03/Server/Security/ShangMi/certificates.md @@ -0,0 +1,89 @@ +# 证书 + +## 概述 + +商密证书指的是满足《SM2椭圆曲线公钥密码算法》以及《基于SM2密码算法的数字证书格式规范》等标准的数字证书。openEuler发布的openSSL软件提供了对商密证书的支持。 + +## 前置条件 + +openSSL大于或等于1.1.1m-6版本: + +```bash +$ rpm -qa openssl +openssl-1.1.1m-6.oe2209.x86_64 +``` + +## 如何使用 + +### 场景1:生成商密证书 + +1. 生成SM2签名私钥: + + ```bash + $ openssl ecparam -genkey -name SM2 -out sm2.key + ``` + +2. 生成签名请求: + + ```bash + $ openssl req -new -sm3 -key sm2.key -out sm2.csr + ``` + +3. 生成商密证书(可使用-extfile指定证书配置文件): + + ```bash + $ openssl x509 -req -days 3650 -signkey sm2.key -in sm2.csr -out sm2.crt + ``` + +4. 查看证书信息: + + ```bash + $ openssl x509 -text -in sm2.crt + ``` + +### 场景2:构建证书链 + +#### 使用x509命令(一般用于功能测试) + +1. 生成CA私钥和证书: + + ```bash + $ openssl ecparam -genkey -name SM2 -out ca.key + $ openssl req -new -sm3 -key ca.key -out ca.csr + $ openssl x509 -req -days 3650 -signkey ca.key -in ca.csr -out ca.crt + ``` + +2. 生成二级签名私钥和签名请求: + + ```bash + $ openssl ecparam -genkey -name SM2 -out sm2.key + $ openssl req -new -sm3 -key sm2.key -out sm2.csr + ``` + +3. 基于一级证书生成二级证书(可使用-extfile指定证书配置文件): + + ```bash + $ openssl x509 -req -sm3 -CAcreateserial -CA ca.crt -CAkey ca.key -in sm2.csr -out sm2.crt + ``` + +#### 使用ca配置文件(一般用于正式场景) + +1. 准备用于生成证书的配置文件(可使用openssl源码目录下的apps/openssl.cnf); +2. 生成自签名CA证书(下列命令为使用openSSL 1.1.1版本的场景,如使用openSSL 3.0.0以上的版本,*openssl req*命令中的*-newkey*参数需要替换为*sm2:SM2.pem*): + + ```bash + $ openssl ecparam -name SM2 -out SM2.pem + $ openssl req -config ./openssl.cnf -nodes -keyout CA.key -newkey ec:SM2.pem -new -out CA.csr + $ openssl x509 -sm3 -req -days 30 -in CA.csr -extfile ./openssl.cnf -extensions v3_ca -signkey CA.key -out CA.crt + ``` + +3. 生成二级证书(下列命令为使用openSSL 1.1.1版本的场景,如使用openSSL 3.0.9及以上的版本,*openssl req*命令中的*-newkey*参数需要替换为*sm2:SM2.pem*): + + ```bash + $ openssl req -config ./openssl.cnf -nodes -keyout SS.key -newkey ec:SM2.pem -new -out SS.csr + $ openssl x509 -sm3 -req -days 30 -in SS.csr -CA CA.crt -CAkey CA.key -extfile ./openssl.cnf -extensions v3_req -out SS.crt -CAcreateserial + ``` + +### 场景3:生成TLCP通信证书 + +详见《TLCP协议栈》章节。 diff --git a/docs/en/25.03/Server/Security/ShangMi/disk-encryption.md b/docs/en/25.03/Server/Security/ShangMi/disk-encryption.md new file mode 100644 index 0000000000000000000000000000000000000000..ce32e51e8b62c3effcae1d158397224796b0f26a --- /dev/null +++ b/docs/en/25.03/Server/Security/ShangMi/disk-encryption.md @@ -0,0 +1,90 @@ +# 磁盘加密 + +## 概述 + +磁盘加密是对重要数据存储机密性进行保护,按照给定加密算法对数据进行加密后写入磁盘,从而保障重要数据的机密性。该特性主要涉及用户态工具cryptsetup和内核态的dm-crypt模块。当前openEuler操作系统提供的磁盘加密特性已支持商密算法。相关参数如下: + +- 加密模式:支持luks2和plain两种模式; +- 密钥长度:支持256位; +- 摘要算法:支持商密SM3算法; +- 加密算法:支持商密sm4-xts-plain64算法。 + +## 前置条件 + +1. 内核大于或等于5.10.0-106版本: + + ```bash + $ rpm -qa kernel + kernel-5.10.0-106.1.0.55.oe2209.x86_64 + ``` + +2. cryptsetup大于或等于2.4.1-1版本: + + ```bash + $ rpm -qa cryptsetup + cryptsetup-2.4.1-1.oe2209.x86_64 + ``` + +## 如何使用 + +通过将磁盘格式化成指定加密模式的磁盘,然后映射到/dev/mapper下作为dm设备,后续对磁盘的读写都通过该dm设备进行,数据的加解密过程由内核态完成,用户态不感知。参考步骤如下: + +1. 格式化磁盘,将磁盘映射为dm设备: + + a. luks2模式 + + 加密模式使用luks2,加密算法使用sm4-xts-plain64,密钥大小为256位,摘要算法使用sm3: + + ```bash + # cryptsetup luksFormat /dev/sdd -c sm4-xts-plain64 --key-size 256 --hash sm3 + # cryptsetup luksOpen /dev/sdd crypt1 + ``` + + b. plain模式 + + 加密模式使用plain,加密算法使用sm4-xts-plain64,密钥大小为256位,摘要算法使用sm3: + + ```bash + # cryptsetup plainOpen /dev/sdd crypt1 -c sm4-xts-plain64 --key-size 256 --hash sm3 + ``` + +2. 映射成功后可通过lsblk查看设备信息: + + ```bash + # lsblk + NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS + ...... + sdd 8:48 0 50G 0 disk + └─crypt1 253:3 0 50G 0 crypt + ...... + ``` + +3. 对加密后的设备进行IO读写: + + 直接对裸盘下发IO: + + ```bash + # dd if=/dev/random of=/dev/mapper/crypt1 bs=4k count=10240 + ``` + + 通过文件系统下发IO: + + ```bash + # mkfs.ext4 /dev/mapper/crypt1 + # mount /dev/mapper/crypt1 /mnt/crypt/ + # dd if=/dev/random of=/mnt/crypt/tmp bs=4k count=10240 + ``` + +4. 关闭设备映射: + + 如果挂载了文件系统,需要先卸载: + + ```bash + # umount /mnt/crypt + ``` + + 关闭设备: + + ```bash + # cryptsetup close crypt1 + ``` diff --git a/docs/en/25.03/Server/Security/ShangMi/file-integrity-protection.md b/docs/en/25.03/Server/Security/ShangMi/file-integrity-protection.md new file mode 100644 index 0000000000000000000000000000000000000000..e578b029960ef2832371a59c0987e67b9cd3b6f3 --- /dev/null +++ b/docs/en/25.03/Server/Security/ShangMi/file-integrity-protection.md @@ -0,0 +1,462 @@ +# 文件完整性保护 + +## 内核完整性度量架构(IMA) + +IMA全称Integrity Measurement Architecture,是Linux内核提供的强制访问控制子系统,通过在文件访问系统调用添加检查hook,实现文件的完整性度量/校验。 + +### 前置条件 + +1. 准备openEuler内核编译环境,可参考: + +2. 建议选取最新内核源码进行编译; + +3. 生成IMA校验证书(仅评估模式涉及): + + ```sh + # 生成证书配置文件(配置文件其他字段可按需定义) + echo 'subjectKeyIdentifier=hash' > ima.cfg + echo 'authorityKeyIdentifier=keyid,issuer' >> ima.cfg + echo 'keyUsage=digitalSignature,nonRepudiation' >> ima.cfg + # 生成SM2签名私钥 + # openssl ecparam -genkey -name SM2 -out ima.key + # 生成签名请求 + # openssl req -new -sm3 -key ima.key -out ima.csr + # 生成SM2证书 + # openssl x509 -req -days 3650 -extfile ima.cfg -signkey ima.key -in ima.csr -out ima.crt + ``` + +4. 生成IMA二级证书: + + **创建证书配置文件** + + echo 'subjectKeyIdentifier=hash' > ima.cfg + echo 'authorityKeyIdentifier=keyid,issuer' >> ima.cfg + + **生成私钥** + + openssl ecparam -genkey -name SM2 -out ima.key + + **生成签名请求** + + openssl req -new -sm3 -key ima.key -out ima.csr + + **基于一级证书生成二级证书** + + openssl x509 -req -sm3 -CAcreateserial -CA ca.crt -CAkey ca.key -extfile ima.cfg -in ima.csr -out ima.crt + + **转换为DER格式** + + openssl x509 -outform DER -in ima.crt -out x509_ima.der0 + +5. 将根证书放置到内核源码目录,并修改内核编译选项CONFIG_SYSTEM_TRUSTED_KEYS,将指定证书编译到内核TRUSTED密钥中(仅评估模式涉及): + + ```sh + # cp /path/to/ima.crt . + # make openeuler_defconfig + # cat .config | grep CONFIG_SYSTEM_TRUSTED_KEYS + CONFIG_SYSTEM_TRUSTED_KEYS="ima.crt" + ``` + +6. 编译并安装内核(仅评估模式涉及): + + ```sh + make -j64 + make modules_install + make install + ``` + +### 使用方法 + +### 场景1:原生IMA + +#### IMA度量模式 + +启动参数配置IMA策略和摘要算法,关闭IMA评估模式,重启系统: + +```text +ima_policy=tcb ima_hash=sm3 ima_appraise=off +``` + +检查度量日志,可以发现IMA对于所有目标保护文件都进行了度量,且摘要算法为SM3: + +```sh +# cat /sys/kernel/security/ima/ascii_runtime_measurements +10 601989730f01fb4688bba92d0ec94340cd90757f ima-sig sm3:0000000000000000000000000000000000000000000000000000000000000000 boot_aggregate +10 dc0a98316b03ab15edd2b8daae75a0d64bca7c56 ima-sig sm3:3c62ee3c13ee32d7a287e04c843c03ebb428a5bb3dd83561efffe9b08444be22 /usr/lib/systemd/systemd +10 1d0a5140e3924e2542963ad887a80def0aa8acac ima-sig sm3:4d3b83e143bd9d5288ef099eff4d01444947516d680165c6dd08cd5900768032 /usr/lib64/ld-linux-x86-64.so.2 +...... +``` + +#### IMA评估模式(hash) + +启动参数配置IMA策略和摘要算法,开启IMA评估fix模式,重启系统: + +```text +ima_policy=appraise_tcb ima_hash=sm3 ima_appraise=fix +``` + +appraise_tcb代表对所有 root 属主的文件进行评估。 + +对所有需要评估的文件进行一次open操作,以自动标记ima扩展属性: + +```sh +# find / -fstype ext4 -type f -uid 0 -exec dd if='{}' of=/dev/null count=0 status=none \; +``` + +完成标记后,可以看到所有的文件都标记了SM3摘要算法的ima扩展属性: + +```sh +getfattr -m - -d -e hex /bin/bash +getfattr: Removing leading '/' from absolute path names +# file: bin/bash +security.ima=0x0411a794922bb9f0a034257f6c7090a3e8429801a42d422c21f1473e83b7f7eac385 +security.selinux=0x73797374656d5f753a6f626a6563745f723a7368656c6c5f657865635f743a733000 + +openssl dgst -sm3 /bin/bash +SM3(/bin/bash)= a794922bb9f0a034257f6c7090a3e8429801a42d422c21f1473e83b7f7eac385 +``` + +开启enforce模式后重启,系统可正常运行: + +```text +ima_policy=appraise_tcb ima_hash=sm3 ima_appraise=enforce +``` + +#### IMA评估模式(签名) + +**前置条件:** + +1. 内核预置商密根证书; +2. 安装ima-evm-utils软件包,且大于或等于指定版本: + +```sh +$ rpm -qa ima-evm-utils +ima-evm-utils-1.3.2-4.oe2209.x86_64 +``` + +对需要进行保护的文件执行签名操作,如此处对/usr/bin目录下所有root用户的可执行文件进行签名: + +```sh +# find /usr/bin -fstype ext4 -type f -executable -uid 0 -exec evmctl -a sm3 ima_sign --key /path/to/ima.key '{}' \; +``` + +开启enforce模式后重启,系统可正常运行: + +```text +ima_policy=appraise_tcb ima_hash=sm3 ima_appraise=enforce +``` + +检查签名模式的保护效果: + +```sh +# getfattr -m - -d /bin/echo +getfattr: Removing leading '/' from absolute path names +# file: bin/echo +security.ima=0sAwIRNJFkBQBIMEYCIQDLBg/bYlrkBqSaXNQMyK7rhiZj+qRiKdu+0fqW8lSmPQIhAJY2qSZJ0HgSu7kygydrS4MCC0KTK59nUkvISenZAUCo +security.selinux="system_u:object_r:bin_t:s0" + +# echo 123 >> /bin/echo +-bash: /bin/echo: Permission denied +``` + +**注意事项:** + +对于每一个在IMA防护范围内的文件,都需要选择使用hash模式和签名模式其中之一的方法标记完整性信息。一般情况下,对于可能发生变化的文件(如数据文件、配置文件等)采用hash模式标记,对于不会发生变化的文件(如可执行文件、动态链接库等)采用签名模式标记。 + +### 场景2:IMA摘要列表模式 + +#### 生成SM3摘要列表 + +gen_digest_lists支持-a sm3参数,支持生成SM3摘要列表: + +```sh +gen_digest_lists -a sm3 -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/bash -d -i i: +gen_digest_lists -a sm3 -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/bash -d -i i: -T +``` + +#### 配置SM3摘要算法 + +整体步骤与开启IMA摘要列表特性相同,唯一区别在于将ima_hash启动参数配置为SM3。启动参数参考配置如下: + +```sh +# log模式 +ima_template=ima-sig ima_policy="exec_tcb|appraise_exec_tcb|appraise_exec_immutable" initramtmpfs ima_hash=sm3 ima_appraise=log evm=allow_metadata_writes evm=x509 ima_digest_list_pcr=11 ima_appraise_digest_list=digest +# enforce模式 +ima_template=ima-sig ima_policy="exec_tcb|appraise_exec_tcb|appraise_exec_immutable" initramtmpfs ima_hash=sm3 ima_appraise=enforce-evm evm=allow_metadata_writes evm=x509 ima_digest_list_pcr=11 ima_appraise_digest_list=digest +``` + +其余步骤可参考 **管理员指南->可信计算->摘要列表场景初次部署** 章节。 + +配置完成后重启系统,通过查询度量日志可以看到,度量日志中的默认算法已变成SM3: + +```sh +cat /sys/kernel/security/ima/ascii_runtime_measurements +...... +11 9e32183b5b1da72c6ff4298a44026e3f9af510c9 ima-sig sm3:5a2d81cd135f41e73e0224b9a81c3d8608ccde8caeafd5113de959ceb7c84948 /usr/bin/upload_digest_lists +11 f3b9264761dbaeaf637d08b86cc3655e8f3380f7 ima-sig sm3:cc6faecee9976c12279dab1627a78ef36f6998c65779f3b846494ac5fe5493a1 /usr/libexec/rpm_parser +11 dc0a98316b03ab15edd2b8daae75a0d64bca7c56 ima-sig sm3:3c62ee3c13ee32d7a287e04c843c03ebb428a5bb3dd83561efffe9b08444be22 /usr/lib/systemd/systemd +...... +``` + +#### 配置SM2证书校验摘要列表(评估模式) + +**前置条件:** + +1. 内核预置商密根证书; +2. 安装digest-list-tools和ima-evm-utils软件包,且大于或等于指定版本: + +```sh +# rpm -qa ima-evm-utils +ima-evm-utils-1.3.2-4.oe2209.x86_64 +# rpm -qa digest-list-tools +digest-list-tools-0.3.95-10.oe2209.x86_64 +``` + +**执行步骤**: + +将IMA摘要列表使用IMA/EVM证书对应的私钥进行签名,签名后可被正常导入内核: + +```sh +# 使用evmctl对摘要列表进行签名 +# evmctl ima_sign --key /path/to/ima.key -a sm3 0-metadata_list-compact-tree-1.8.0-2.oe2209.x86_64 +# 检查签名后的扩展属性 +# getfattr -m - -d 0-metadata_list-compact-tree-1.8.0-2.oe2209.x86_64 +file: 0-metadata_list-compact-tree-1.8.0-2.oe2209.x86_64 +security.ima=0sAwIRNJFkBQBHMEUCIQCzdKVWdxw1hoVm9lgZB6sl+sxapptUFNjqHt5XZD87hgIgBMuZqBdrcNm7fXq/reQw7rzY/RN/UXPrIOxrVvpTouw= +security.selinux="unconfined_u:object_r:admin_home_t:s0" +# 将签名后的摘要列表文件导入内核 +# echo /root/tree/etc/ima/digest_lists/0-metadata_list-compact-tree-1.8.0-2.oe2209.x86_64 > /sys/kernel/security/ima/digest_list_data +# 检查度量日志,可以看到摘要列表的导入记录 +# cat /sys/kernel/security/ima/ascii_runtime_measurements +11 43b6981f84ba2725d05e91f19577cedb004adffb ima-sig sm3:b9430bbde2b7f30e935d91e29ab6778b6a825a2c3e5e7255895effb8747b7c1a /root/tree/etc/ima/digest_lists/0-metadata_list-compact-tree-1.8.0-2.oe2209.x86_64 0302113491640500473045022100b374a556771c35868566f6581907ab25facc5aa69b5414d8ea1ede57643f3b86022004cb99a8176b70d9bb7d7abfade430eebcd8fd137f5173eb20ec6b56fa53a2ec +``` + +**注意:** + +1. openEuler默认提供的摘要列表中使用的哈希算法为SHA256。当IMA摘要列表度量算法配置为SM3算法时,必须将/etc/ima/digest_lists目录下的摘要列表移除,然后重新生成并签名,否则会导致文件完整性校验错误。参考步骤如下: + + ```sh + # 重置磁盘SELinux标签(开启IMA扩展属性校验,并开启SELinux时执行) + fixfiles -F restore + # 为所有文件生成摘要列表(也可自行设置生成范围) + gen_digest_lists -a sm3 -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/ -d /etc/ima/digest_lists -i i: + # 修改生成的摘要列表文件名(可选) + mv /etc/ima/digest_lists/0-metadata_list-compact- /etc/ima/digest_lists/0-metadata_list-compact-everything-sm3 + # 签名 + evmctl ima_sign --key /path/to/ima.key -a sm3 /etc/ima/digest_lists/0-metadata_list-compact-everything-sm3 + # 重新制作initrd + dracut -f -e xattr + ``` + +2. 对于openEuler发布的软件包,会默认提供IMA摘要列表文件。由于默认提供的摘要算法为sha256,因此当摘要算法切换为SM3时,会导致openEuler发布的摘要列表无法被导入,在软件包安装过程中可能出现提示信息: + + ```sh + Cannon parse /etc/ima/digest_lists/0-metadata_list-rpm-...... + ``` + +3. 当前openEuler 24.03内核暂不支持二级商密IMA证书(/etc/keys/x509_ima.der和/etc/keys/x509_evm.der)导入。 + +## 轻量入侵检测(AIDE) + +AIDE是一款轻量级的入侵检测工具,主要通过检测文件的完整性,以及时发现针对系统的恶意入侵行为。AIDE数据库能够使用sha256、sha512等哈希算法,用密文形式建立每个文件的校验码或散列号。openEuler提供的AIDE在开源软件的基础上新增了对SM3算法的支持。 + +### 前置条件 + +AIDE大于或等于0.17.4-1版本: + +```sh +$ rpm -qa aide +aide-0.17.4-1.oe2209.x86_64 +``` + +### 使用方法 + +修改/etc/aide.conf配置文件,添加SM3算法支持: + +```sh +...... +FIPSR = p+i+n+u+g+s+m+c+acl+selinux+xattrs+sha256+sm3 +...... +DATAONLY = p+n+u+g+s+acl+selinux+xattrs+sha256+sm3 +...... +``` + +初始化数据库,并保存数据库作为基准: + +初始化数据库 + +```sh +aide -c /etc/aide.conf -i +``` + +示例输出如下: + +```text +AIDE initialized database at /var/lib/aide/aide.db.new.gz + +Number of entries: 64249 + +--------------------------------------------------- +The attributes of the (uncompressed) database(s): +--------------------------------------------------- + +/var/lib/aide/aide.db.new.gz + MD5 : a7y5ErdpBAezV2iGdaVleg== + SHA1 : u7W7jxomFtZn8rwMlkIRCN0r7iQ= + SHA256 : 88Kw5b2yJ9bejwO+NqT6lyAieno+K0+W + BPVBjXcUl08= + SHA512 : WyOIgRxk9SeSoktF6BYVV0tRL7nGNDKQ + A9QyxVCgzg+PwPMV7tzxmwOZI/dB64pP + vQ/D2jqJdf3NS2PHMI4yvg== + RMD160 : qTEPs2SIxPm3iEwsCnwvp9hR4s4= + TIGER : 0HgLucmhCcB56bxOMj+j1Kuja8UIsFRg + CRC32 : VKE1TA== + WHIRLPOOL : JSA35/NmkMOkUWEpcZJf3PR1UUz5WcLG + AmBKPkao3fzQUsLMTJizCV4CwAE0G/Yc + KX0mpW5vx+gk3njya8rAvA== + GOST : yKjiytOwRr3bJcFsxnJ310t1FY6YE3HB + YNT8XP93xpc= + STRIBOG256: 9bzS+5j4ZAoU/P7v3tkKOWn4ZfggcX28 + 9dLQVhaiJtQ= + STRIBOG512: 9LLXgqsRIRiXP2WOrOJt1qhx6psfbACd + un+GTVmu441quX4zaaPIIG9lzDMBAqMg + hZx5DlxsQj3YjMezSUsXLg== + SM3 : Vwii+uw3Ge5Hh3eo1KOombxn2jWgyYRX + ZdyCRZqWZ/E= + + +End timestamp: 2022-08-12 09:01:25 +0800 (run time: 2m 43s) +``` + +保存数据库作为基准: + +```sh +mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz +``` + +### 场景1:检测被保护文件变化 + +```sh +$ aide -c /etc/aide.conf --check +--------------------------------------------------- +Detailed information about changes: +--------------------------------------------------- + +File: /boot/config-5.10.0-106.3.0.57.oe2209.aarch64 + Size : 182936 | 182938 + Mtime : 2022-08-04 08:00:00 +0800 | 2022-08-12 09:05:34 +0800 + Ctime : 2022-08-11 01:42:44 +0800 | 2022-08-12 09:05:34 +0800 + SHA256 : ae0fOzf7U+e/evTZKpk6JQa00kvSkc5J | gOlhcUgnZWhcyJYMEPxCYccXwFr9lERX + vMTX5Ysh+1k= | KK3O/ytfR/g= + SHA512 : zAPIxIAM7YvJPjwl/PH23leBb/HiO0Rf | p+WxVOZ6DX323rHDRF864w297yh7POk6 + PlRME7yvpzFZk/5BrNe2ofQWR/0sFu1m | 11dOzahlKTWpAKaexC/u+4REiCzjl1rm + JsDSy8m57wzCpJA9iUFq1g== | eb/kd3Xgp1LoKwn49mtqxw== + SM3 : CW0GnITxNeGeYOCAm4xfu78Vqm+wLp/Z | GWq/3nXL16tMYyxyFD/HTZbvJi2h+ttg + cOmXmIKJT4Q= | 6d8XmSHu26A= +``` + +### 场景2:更新数据库 + +执行以下命令进行数据库更新,更新后数据库文件为 /var/lib/aide/aide.db.new.gz: + +```sh +$ aide -c /etc/aide.conf --update +--------------------------------------------------- +Detailed information about changes: +--------------------------------------------------- + +File: /boot/config-5.10.0-106.3.0.57.oe2209.aarch64 + Size : 182936 | 182938 + Mtime : 2022-08-04 08:00:00 +0800 | 2022-08-12 09:05:34 +0800 + Ctime : 2022-08-11 01:42:44 +0800 | 2022-08-12 09:05:34 +0800 + SHA256 : ae0fOzf7U+e/evTZKpk6JQa00kvSkc5J | gOlhcUgnZWhcyJYMEPxCYccXwFr9lERX + vMTX5Ysh+1k= | KK3O/ytfR/g= + SHA512 : zAPIxIAM7YvJPjwl/PH23leBb/HiO0Rf | p+WxVOZ6DX323rHDRF864w297yh7POk6 + PlRME7yvpzFZk/5BrNe2ofQWR/0sFu1m | 11dOzahlKTWpAKaexC/u+4REiCzjl1rm + JsDSy8m57wzCpJA9iUFq1g== | eb/kd3Xgp1LoKwn49mtqxw== + SM3 : CW0GnITxNeGeYOCAm4xfu78Vqm+wLp/Z | GWq/3nXL16tMYyxyFD/HTZbvJi2h+ttg + cOmXmIKJT4Q= | 6d8XmSHu26A= +``` + +### 场景3:比较数据库 + +在/etc/aide.conf中配置两个数据库: + +```sh +# The location of the database to be read. +database_in=file:@@{DBDIR}/aide.db.gz +database_new=file:@@{DBDIR}/aide.db.new.gz +``` + +执行以下命令进行数据库比较: + +```sh +$ aide -c /etc/aide.conf --compare +--------------------------------------------------- +Detailed information about changes: +--------------------------------------------------- + +File: /boot/config-5.10.0-106.3.0.57.oe2209.aarch64 + Size : 182936 | 182938 + Mtime : 2022-08-04 08:00:00 +0800 | 2022-08-12 09:05:34 +0800 + Ctime : 2022-08-11 01:42:44 +0800 | 2022-08-12 09:05:34 +0800 + SHA256 : ae0fOzf7U+e/evTZKpk6JQa00kvSkc5J | gOlhcUgnZWhcyJYMEPxCYccXwFr9lERX + vMTX5Ysh+1k= | KK3O/ytfR/g= + SHA512 : zAPIxIAM7YvJPjwl/PH23leBb/HiO0Rf | p+WxVOZ6DX323rHDRF864w297yh7POk6 + PlRME7yvpzFZk/5BrNe2ofQWR/0sFu1m | 11dOzahlKTWpAKaexC/u+4REiCzjl1rm + JsDSy8m57wzCpJA9iUFq1g== | eb/kd3Xgp1LoKwn49mtqxw== + SM3 : CW0GnITxNeGeYOCAm4xfu78Vqm+wLp/Z | GWq/3nXL16tMYyxyFD/HTZbvJi2h+ttg + cOmXmIKJT4Q= | 6d8XmSHu26A= + +--------------------------------------------------- +The attributes of the (uncompressed) database(s): +--------------------------------------------------- + +/var/lib/aide/aide.db.gz + MD5 : a7y5ErdpBAezV2iGdaVleg== + SHA1 : u7W7jxomFtZn8rwMlkIRCN0r7iQ= + SHA256 : 88Kw5b2yJ9bejwO+NqT6lyAieno+K0+W + BPVBjXcUl08= + SHA512 : WyOIgRxk9SeSoktF6BYVV0tRL7nGNDKQ + A9QyxVCgzg+PwPMV7tzxmwOZI/dB64pP + vQ/D2jqJdf3NS2PHMI4yvg== + RMD160 : qTEPs2SIxPm3iEwsCnwvp9hR4s4= + TIGER : 0HgLucmhCcB56bxOMj+j1Kuja8UIsFRg + CRC32 : VKE1TA== + WHIRLPOOL : JSA35/NmkMOkUWEpcZJf3PR1UUz5WcLG + AmBKPkao3fzQUsLMTJizCV4CwAE0G/Yc + KX0mpW5vx+gk3njya8rAvA== + GOST : yKjiytOwRr3bJcFsxnJ310t1FY6YE3HB + YNT8XP93xpc= + STRIBOG256: 9bzS+5j4ZAoU/P7v3tkKOWn4ZfggcX28 + 9dLQVhaiJtQ= + STRIBOG512: 9LLXgqsRIRiXP2WOrOJt1qhx6psfbACd + un+GTVmu441quX4zaaPIIG9lzDMBAqMg + hZx5DlxsQj3YjMezSUsXLg== + SM3 : Vwii+uw3Ge5Hh3eo1KOombxn2jWgyYRX + ZdyCRZqWZ/E= + +/var/lib/aide/aide.db.new.gz + MD5 : sKt4dVDKY/8A9EY/X4Ue2A== + SHA1 : hagLXMv7G+KbEKh861kjjFSYpRw= + SHA256 : HTHF7k5U294ECjCLneoZ3o8bH6PYgY5u + AzoIyCacZp4= + SHA512 : 5gWi7K/ztWMl7H+PK1doV/tWDHmaE2m/ + ndRXGR7b5J3v82Jv2HeJPoOt5A4Z/9FH + 5H+uCLYaHwRleyalyy5Wew== + RMD160 : uMM1HtAbfz+G3Y9Z+rVR4qjdqcQ= + TIGER : OTHdXNQOxnHnOl6C9M3czSC42+SeZAZA + CRC32 : T9G1Tw== + WHIRLPOOL : FRMnQ2wHgylsTmpKE8RwdUvkzXucHwu1 + W9ZkUrxoXeci2g7jIgoMmpoeDPhH73qz + nZ7fKj1lStSpiUGD5KPeWA== + GOST : haeO5dhT+t34C1GJf+2dc3q1GMN71FqB + kqoiODo+j2o= + STRIBOG256: lgZUZhhd9JfMOXgNzYptapqagwgmvdM+ + 7uWzJsmOxoY= + STRIBOG512: PA6jksprS37xQzHm1ZIvLR9ROa+FxoiF + /xbAe0pSi4lMXXzABrPKkjyK0WtjxFvx + 07Poj2iDwNNcUJWekbaEXA== + SM3 : R5/HXng5MNvrjoCh8/JzrWle1IO8ggsR + P5i2ePX5BpY= +``` diff --git a/docs/en/25.03/Server/Security/ShangMi/kernel-module-signing.md b/docs/en/25.03/Server/Security/ShangMi/kernel-module-signing.md new file mode 100644 index 0000000000000000000000000000000000000000..cbdc9dc0aa8645ab56efbf701a82be64cc08a48c --- /dev/null +++ b/docs/en/25.03/Server/Security/ShangMi/kernel-module-signing.md @@ -0,0 +1,107 @@ +# 内核模块签名 + +## 概述 + +内核模块签名机制是保护Linux内核安全的重要机制,通过在内核模块文件末尾按照一定格式追加签名信息,并在内核模块加载时检查签名是否与内核预置的公钥匹配,从而保障内核模块文件的真实性和完整性。 + +## 前置条件 + +1. 准备openEuler内核编译环境,可参考: +2. 内核模块签名支持商密算法在openEuler 5.10内核支持,建议选取最新5.10内核源码进行编译; +3. 生成用于内核模块签名的SM2私钥和证书。使用openssl生成的参考命令如下: + +```bash +# 生成证书配置文件(配置文件其他字段可按需定义) +$ echo 'subjectKeyIdentifier=hash' > mod.cfg +# 生成SM2签名私钥 +$ openssl ecparam -genkey -name SM2 -out mod.key +# 生成签名请求 +$ openssl req -new -sm3 -key mod.key -out mod.csr +# 生成SM2证书 +$ openssl x509 -req -days 3650 -extfile mod.cfg -signkey mod.key -in mod.csr -out mod.crt +``` + +## 如何使用 + +### 场景1:自动签名 + +将证书和私钥写入到mod.pem文件中: + +```bash +$ cat /path/to/mod.key > mod.pem +$ cat /path/to/mod.crt >> mod.pem +``` + +在内核编译选项中配置使用SM3算法进行内核模块签名,参考步骤如下: + +```bash +$ make openeuler_defconfig +$ make menuconfig +``` + +在图形界面中配置 Enable loadable module support -> Sign modules with SM3: + +```conf +Which hash algorithm should modules be signed with? (Sign modules with SM3) +``` + +指定内核签名使用的私钥和证书从mod.pem中读取 Cryptographic API -> Certificates for signature checking: + +```conf +(mod.pem) File name or PKCS#11 URI of module signing key +``` + +编译内核: + +```bash +$ make -j64 +$ make modules_install +$ make install +``` + +通过modinfo检查内核模块的签名信息: + +```bash +$ modinfo /usr/lib/modules/5.10.0/kernel/crypto/sm4.ko +filename: /usr/lib/modules/5.10.0/kernel/crypto/sm4.ko +license: GPL v2 +description: Generic SM4 library +srcversion: 371050FDB8BF9878D9B5B9B +depends: +retpoline: Y +intree: Y +name: sm4 +vermagic: 5.10.0 SMP mod_unload modversions +sig_id: PKCS#7 +signer: Internet Widgits Pty Ltd +sig_key: 33:0B:96:3E:1F:C1:CA:28:98:72:F5:AE:FF:3F:A4:F3:50:5D:E1:87 +sig_hashalgo: sm3 +signature: 30:45:02:21:00:81:96:8D:40:CE:7F:7D:AE:3A:4B:CC:DC:9A:F2:B4: + 16:87:3E:C3:DC:77:ED:BC:6E:F5:D8:F3:DD:77:2B:D4:05:02:20:3B: + 39:5A:89:9D:DC:27:83:E8:D8:B4:75:86:FF:33:2B:34:33:D0:90:76: + 32:4D:36:88:84:34:31:5C:83:63:6B +``` + +### 场景2:手动签名 + +在内核源码目录下调用sign_file对指定内核模块进行签名: + +```bash +$ ./scripts/sign-file sm3 /path/to/mod.key /path/to/mod.crt +``` + +其余步骤与场景1相同。 + +### 场景3:模块加载校验 + +在内核启动参数中添加module.sig_enforce,开启内核模块强制签名校验: + +```bash +linux /vmlinuz-5.10.0-106.1.0.55.oe2209.x86_64 root=/dev/mapper/openeuler-root ro resume=/dev/mapper/openeuler-swap rd.lvm.lv=openeuler/root rd.lvm.lv=openeuler/swap crashkernel=512M module.sig_enforce +``` + +重启系统后,只有通过指定证书校验的内核模块才能被正常加载: + +```bash +# insmod /usr/lib/modules/5.10.0/kernel/crypto/sm4.ko +``` diff --git a/docs/en/25.03/Server/Security/ShangMi/overview.md b/docs/en/25.03/Server/Security/ShangMi/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..3530a2e99e404622a9d48f00a16739ab832e1936 --- /dev/null +++ b/docs/en/25.03/Server/Security/ShangMi/overview.md @@ -0,0 +1,29 @@ +# 概述 + +国产商用密码算法(后文简称商密)属于商用的、不涉及国家秘密的密码技术。密码算法是信息系统的安全技术基础,在国际上已经有广泛使用的RSA、AES、SHA256等密码算法。与之相对的,国内也有一系列自主研发的密码算法,可以覆盖主流的应用场景。其中在操作系统场景,相对应用广泛的算法是SM2/3/4: + +| 算法 | 是否公开 | 类型 | 应用场景 | +|---|---|---|---| +| SM2 | 是 | 非对称加解密算法 | 数字签名、密钥交换、加解密,广泛应用于PKI体系 | +| SM3 | 是 | 杂凑算法(哈希算法) | 应用于完整性保护、单向加密等通用场景 | +| SM4 | 是 | 对称加解密算法) | 数据加密存储、安全传输 | + +除此之外,还包括SM9、ZUC等公开算法,以及SM1、SM7等非公开算法。值得一提的是,所有已经公开的国产算法都已经纳入ISO/IEC标准,成为了被国际所认可的密码算法。围绕这些密码算法,我国制定并发布一系列密码技术规范和应用标准,如商密证书标准、TLCP协议栈等。它们共同构成了我国的商密标准体系,指导了国内的密码安全产业链的构建。 + +openEuler操作系统商密支持旨在对操作系统的关键安全特性进行商密算法使能,并为上层应用提供商密算法库、证书、安全传输协议等密码服务。 + +当前已支持的商密特性包括: + +1. openSSL/libgcrypt等用户态算法库支持SM2/3/4算法; +2. openSSH支持SM2/3/4商密算法套件; +3. openSSL支持商密TLCP协议栈; +4. 磁盘加密(dm-crypt/cryptsetup)支持SM3/SM4算法; +5. 用户身份鉴别(pam/libuser/shadow)支持SM3口令加密; +6. 入侵检测(AIDE)支持SM3摘要算法; +7. 内核加密框架(crypto)支持SM2/3/4算法,以及AVX/CE/NEON等指令集优化; +8. 内核完整性度量架构(IMA/EVM)支持SM3摘要算法和SM2证书; +9. 内核模块签名/验签支持SM2证书; +10. 内核KTLS支持SM4-CBC和SM4-GCM算法; +11. 鲲鹏KAE加速引擎支持SM3/4算法加速; +12. UEFI安全启动支持SM3摘要算法和SM2数字签名; +13. RPM支持国密SM2加解密算法+SM3摘要算法的签名及验签。 diff --git a/docs/en/25.03/Server/Security/ShangMi/rpm-signature-verification.md b/docs/en/25.03/Server/Security/ShangMi/rpm-signature-verification.md new file mode 100644 index 0000000000000000000000000000000000000000..828cc0475085356d8adf149f580a1e2058a7c9af --- /dev/null +++ b/docs/en/25.03/Server/Security/ShangMi/rpm-signature-verification.md @@ -0,0 +1,99 @@ +# RPM验签 + +## 概述 + +openEuler当前采用RPM格式的软件包管理,RPM采用符合openPGP签名规范,openEuler-24.03-LTS-SP1版本发布的RPM软件在开源版本的基础上增加了对SM2/3算法的签名/验签功能支持。 + +对如下软件包进行商密使能: + +- GnuPG:gpg命令行应用程序支持生成国密签名 +- RPM:支持调用gpg命令以及openSSL API实现国密签名生成/验证 +- openSSL:支持国密签名验证(开源已支持) + +## 前置条件 + +1. openEuler操作系统安装的gnupg2、libgcrypt、rpm软件版本号需大于等于如下版本: + + ```sh + $ rpm -qa libgcrypt + libgcrypt-1.10.2-3.oe2403sp1.x86_64 + + $ rpm -qa gnupg2 + gnupg2-2.4.3-5.oe2403sp1.x86_64 + + $ rpm -qa rpm + rpm-4.18.2-20.oe2403sp1.x86_64 + ``` + +2. ecdsa的签名及验签仅支持sm2的 + +## 使用方法 + +1. 生成秘钥 + + 方法1: + + ```sh + $ gpg --full-generate-key --expert + ``` + + 方法2: + + ```sh + $ gpg --quick-generate-key <密钥标识> sm2p256v1 + ``` + + 中间会要求输入密码,后续操作秘钥或签名需要输入密码,若直接不输入,按回车,则表示无密码。 + +2. 导出证书 + + ```sh + $ gpg -o <证书路径> --export <密钥标识> + ``` + +3. 打开配置sm3哈希算法和sm2算法的宏 + + ```sh + $ vim /usr/lib/rpm/macros + %_enable_sm2p256v1_sm3_algo 1 + ``` + +4. 将证书导入rpm数据库 + + ```sh + $ rpm --import <证书路径> + ``` + +5. 编写签名所需的macro + + ```sh + $ vim ~/.rpmmacros + %_signature gpg + %_gpg_path /root/.gnupg + %_gpg_name <密钥标识> + %_gpgbin /usr/bin/gpg2 + + %__gpg_sign_cmd %{shescape:%{__gpg}} \ + gpg --no-verbose --no-armor --no-secmem-warning --passphrase-file /root/passwd \ + %{?_gpg_digest_algo:--digest-algo=%{_gpg_digest_algo}} \ + %{?_gpg_sign_cmd_extra_args} \ + %{?_gpg_name:-u %{shescape:%{_gpg_name}}} \ + -sbo %{shescape:%{?__signature_filename}} \ + %{?__plaintext_filename:-- %{shescape:%{__plaintext_filename}}} + ``` + + 其中%__gpg_sign_cmd信息为默认信息加上了--passphrase-file /root/passwd,passwd文件存的是密码,若步骤1没有设置密码,则无需添加。 + +6. 生成RPM包签名 + + ```sh + $ rpmsign --addsign + ``` + +7. 验证RPM包签名 + + ```sh + $ rpm -Kv + ``` + + 如果输出中显示“Header V4 ECDSA/SM3 Signature”,并且显示“OK”,则说明签名验证成功。 diff --git a/docs/en/25.03/Server/Security/ShangMi/secure-boot.md b/docs/en/25.03/Server/Security/ShangMi/secure-boot.md new file mode 100644 index 0000000000000000000000000000000000000000..f75fdf15012ed78b78b25872c808d3ef4dc97929 --- /dev/null +++ b/docs/en/25.03/Server/Security/ShangMi/secure-boot.md @@ -0,0 +1,186 @@ +# 安全启动 + +安全启动是UEFI规范的标准功能,通过对系统启动中的各个组件进行逐级签名验证,实现启动过程的完整性和真实性保证。Linux系统的UEFI安全启动主要包括以下三个流程: + +1. BIOS通过内置证书验证shim组件的签名信息; +2. shim组件通过内置证书验证grub组件的签名信息; +3. grub组件通过shim组件提供的接口验证kernel组件的签名信息。 + +openEuler对EFI签名工具(pesign及其算法库nss)和shim进行了商密算法扩展支持,即支持使用SM3算法进行EFI文件的哈希计算,使用SM2数字签名算法进行EFI文件的签名/验签,从而建立基于商密算法的操作系统启动安全保障。 + +## 约束限制 + +- openEuler shim组件支持商密安全启动,即支持shim验签grub,grub验签kernel流程。shim组件的验签依赖BIOS支持; +- 需要基于支持UEFI安全启动的arm64/x86物理机运行; +- pesign工具最多支持二级证书签名; +- pesign工具当前仅支持生成签名,不支持验证签名。 + +## 前置条件 + +1. 系统中安装下列软件包且高于指定版本: + + ```shell + openssl-1.1.1m-15.oe2203.aarch64 + nss-3.72.0-4.oe2203.aarch64 + pesign-115-2.oe2203.aarch64 + shim-15.6-7.oe2203.aarch64 + crypto-policies-20200619-3.git781bbd4.oe2203.noarch + ``` + +2. 下载openEuler shim组件源码,注意需要检查spec文件中的版本号大于15.6-7: + + ```shell + git clone https://gitee.com/src-openeuler/shim.git -b openEuler-22.03-LTS-SP1 --depth 1 + ``` + +3. 安装编译shim组件所需要的软件包: + + ```shell + yum install elfutils-libelf-devel gcc gnu-efi gnu-efi-devel openssl-devel make git rpm-build + ``` + +4. 检查nss是否使能SM3算法,如果未使能则按照如下所示修改: + + ```shell + cat /usr/share/crypto-policies/DEFAULT/nss.txt | grep SM3 + config="disallow=ALL allow=HMAC-SHA256:HMAC-SHA1:HMAC-SHA384:HMAC-SHA512:CURVE25519:SECP256R1:SECP384R1:SECP521R1:aes256-gcm:chacha20-poly1305:aes256-cbc:aes128-gcm:aes128-cbc:SHA256:SHA384:SHA512:SHA224:SHA1:ECDHE-RSA:ECDHE-ECDSA:RSA:DHE-RSA:ECDSA:RSA-PSS:RSA-PKCS:tls-version-min=tls1.0:dtls-version-min=dtls1.0:DH-MIN=1023:DSA-MIN=2048:RSA-MIN=2048:SM3" + ``` + +## 生成密钥和证书 + +1. 生成用于签名shim组件的密钥和证书,shim组件由BIOS校验签名,由于当前大部分BIOS不支持商密算法,此处选择使用RSA算法,如支持商密算法,可按照步骤2生成SM2密钥和证书: + + ```shell + openssl genrsa -out rsa.key 4096 + openssl req -new -key rsa.key -out rsa.csr -subj '/C=AA/ST=BB/O=CC/OU=DD/CN=secure boot BIOS' + openssl x509 -req -days 365 -in rsa.csr -signkey rsa.key -out rsa.crt + openssl x509 -in rsa.crt -out rsa.der -outform der + ``` + +2. 生成用签名grub和kernel组件的SM2密钥和证书: + + ```shell + openssl ecparam -genkey -name SM2 -out sm2.key + openssl req -new -sm3 -key sm2.key -out sm2.csr -subj '/C=AA/ST=BB/O=CC/OU=DD/CN=secure boot shim' + openssl x509 -req -days 3650 -signkey sm2.key -in sm2.csr -out sm2.crt + openssl x509 -in sm2.crt -out sm2.der -outform der + ``` + +3. 建立NSS数据库,并将以上两步骤生成的密钥和证书导入NSS数据库: + + ```shell + # NSS数据库以目录形式组织,存放位置可自定义 + mkdir certdb + certutil -N -d certdb + # 将SM2证书和RSA证书导入NSS数据库,分别命名为sm2和rsa + certutil -A -n sm2 -d certdb -t CT,CT,CT -i sm2.crt + certutil -A -n rsa -d certdb -t CT,CT,CT -i rsa.crt + # 将SM2密钥和RSA密钥导入NSS数据库,需要先打包成pkcs12文件 + openssl pkcs12 -export -out rsa.p12 -inkey rsa.key -in rsa.crt + openssl pkcs12 -export -out sm2.p12 -inkey sm2.key -in sm2.crt + pk12util -d certdb -i rsa.p12 + pk12util -d certdb -i sm2.p12 + ``` + +## 编译shim组件 + +1. 进入shim源码目录,修改shim.spec中的配置变量,开启商密算法支持,并指定内置SM2证书: + + ```shell + %global enable_sm 1 + %global vendor_cert /path/to/sm2.der + ``` + +2. 编译shim软件包: + + ```shell + rpmbuild -ba shim.spec --define "_sourcedir $PWD" + ``` + +3. 安装编译完成的shim软件包: + + ```shell + rpm -Uvh ~/rpmbuild/RPMS/aarch64/shim-xxx.rpm + ``` + +## UEFI文件商密签名 + +1. 使用RSA密钥和证书签名shim组件并替换: + + ```shell + # arm64架构 + pesign -n certdb -c rsa -s -i /boot/efi/EFI/openEuler/shimaa64.efi -o shimaa64.efi.signed + cp shimaa64.efi.signed /boot/efi/EFI/openEuler/shimaa64.efi + # x86架构 + pesign -n certdb -c rsa -s -i /boot/efi/EFI/openEuler/shimx64.efi -o shimx64.efi.signed + cp shimx64.efi.signed /boot/efi/EFI/openEuler/shimx64.efi + ``` + +2. 使用SM2密钥和证书签名grub组件并替换: + + ```shell + # arm64架构 + pesign -n certdb -c sm2 -s -i /boot/efi/EFI/openEuler/grubaa64.efi -o grubaa64.efi.signed -d sm3 + cp grubaa64.efi.signed /boot/efi/EFI/openEuler/grubaa64.efi + # x86架构 + pesign -n certdb -c sm2 -s -i /boot/efi/EFI/openEuler/grubx64.efi -o grubx64.efi.signed -d sm3 + cp grubx64.efi.signed /boot/efi/EFI/openEuler/grubx64.efi + ``` + +3. 使用SM2密钥和证书签名kernel组件并替换(注意文件名包含实际的版本号): + + ```shell + # arm64架构,需要解压、签名、重新压缩 + cp /boot/vmlinuz-5.10.0-126.0.0.66.oe2203.aarch64 vmlinuz-5.10.0-126.0.0.66.oe2203.aarch64.gz + gzip -d vmlinuz-5.10.0-126.0.0.66.oe2203.aarch64.gz + pesign -n certdb -c sm2 -s -i vmlinuz-5.10.0-126.0.0.66.oe2203.aarch64 -o vmlinuz-5.10.0-126.0.0.66.oe2203.aarch64.signed -d sm3 + gzip vmlinuz-5.10.0-126.0.0.66.oe2203.aarch64.signed + cp vmlinuz-5.10.0-126.0.0.66.oe2203.aarch64.signed.gz /boot/vmlinuz-5.10.0-126.0.0.66.oe2203.aarch64 + # x86架构 + pesign -n certdb -c sm2 -s -i /boot/vmlinuz-5.10.0-126.0.0.66.oe2203.x86_64 -o vmlinuz-5.10.0-126.0.0.66.oe2203.x86_64.signed -d sm3 + cp vmlinuz-5.10.0-126.0.0.66.oe2203.x86_64.signed /boot/vmlinuz-5.10.0-126.0.0.66.oe2203.x86_64 + ``` + +4. 检查签名信息,以shim和grub为例: + + ```shell + pesign -S -i /boot/efi/EFI/openEuler/grubaa64.efi + pesign -S -i /boot/efi/EFI/openEuler/shimaa64.efi + ``` + +## 安全启动 + +进入BIOS,导入shim组件的签名证书,并开启安全启动选项。不同的BIOS操作方法不同,以鲲鹏2280 v2服务器为例: + +1. 将签名shim组件的RSA证书放入/boot/efi/EFI/openEuler目录下: + + ```shell + cp rsa.der /boot/efi/EFI/openEuler + ``` + +2. 重启系统; + +3. 进入BIOS配置界面开启安全启动,配置路径: + + ```shell + Setup->安全->安全启动->启用 + ``` + +4. 配置安全启动为自定义模式,配置路径: + + ```shell + Setup->安全->安全启动证书配置->安全启动模式->自定义模式 + ``` + +5. 导入安全启动证书,配置路径: + + ```shell + Setup->安全->安全启动证书配置->安全启动自定义模式相关选项->DB相关选项->导入签名->通过文件添加签名->选择rsa.der->保存并退出 + ``` + +6. 保存配置后重启系统,系统启动成功,查询安全启动状态为开启: + + ```shell + mokutil --sb-state + SecureBoot enabled + ``` diff --git a/docs/en/25.03/Server/Security/ShangMi/ssh-stack.md b/docs/en/25.03/Server/Security/ShangMi/ssh-stack.md new file mode 100644 index 0000000000000000000000000000000000000000..31aa234318257337a0d99540782a1adc043a0daf --- /dev/null +++ b/docs/en/25.03/Server/Security/ShangMi/ssh-stack.md @@ -0,0 +1,52 @@ +# SSH协议栈 + +## 概述 + +openSSH组件是以C语言的openSSL的libcrypto为基础,实现的安全外壳协议(Secure Shell)组件。主要功能为远程登录系统,保证非安全网络环境中信息加密完整可靠。openEuler提供的SSH的服务端和客户端配置项中涉及密钥交换、公钥认证、对称加密和完整性认证的配置参数取值可以选择为商密算法套件(包含SM2/3/4算法)。 + +## 前置条件 + +openssh大于等于8.8p1-5版本: + +```bash +$ rpm -qa | grep openssh +openssh-8.8p1-5.oe2209.x86_64 +openssh-server-8.8p1-5.oe2209.x86_64 +openssh-clients-8.8p1-5.oe2209.x86_64 +``` + +## 如何使用 + +### 场景1:用户远程登录 + +1. 客户端调用ssh-keygen生成用户密钥,默认保存为“\~/.ssh/id_sm2”和“\~/.ssh/id_sm2.pub”,将“\~/.ssh/id_sm2.pub”发送给服务端(也可使用ssh-copy-id命令发送): + + ```bash + $ ssh-keygen -t sm2 -m PEM + ``` + +2. 服务端调用ssh-keygen生成主机密钥,并将客户端发送的公钥加入授权密钥文件列表(如使用ssh-copy-id命令传输,则会自动写入): + + ```bash + $ ssh-keygen -t sm2 -m PEM -f /etc/ssh/ssh_host_sm2_key + $ cat /path/to/id_sm2.pub >> ~/.ssh/authorized_keys + ``` + +3. 修改配置文件,配置支持商密算法登录。服务端的配置文件路径为/etc/ssh/sshd_config,客户端配置文件路径为/etc/ssh/ssh_config。可配置的商密参数如下表: + + | 配置项含义 | 配置项参数 | 配置项参数的商密取值 | + |---------------------|------------------------|---------------| + | HostKey | 主机密钥公钥认证密钥 | /etc/ssh/ssh_host_sm2_key | + | HostKeyAlgorithms | 主机密钥公钥认证算法 | sm2 | + | KexAlgorithms | 密钥交换算法 | sm2-sm3 | + | Ciphers | 对称加密算法 | sm4-ctr | + | MACs | 完整性校验算法 | hmac-sm3 | + | PubkeyAcceptedKeyTypes | 用户公钥认证算法 | sm2 | + | IdentityFile | 用户公钥认证密钥 | ~/.ssh/id_sm2 | + | FingerprintHash | 打印密钥指纹使用的哈希算法 | sm3 | + +4. 客户端配置商密算法完成登录。客户端可以使用命令行方式或者修改配置文件(默认配置文件路径为/etc/ssh/ssh_config)的方式使能商密算法套件。使用命令行登录方式如下: + + ```bash + ssh -o PreferredAuthentications=publickey -o HostKeyAlgorithms=sm2 -o PubkeyAcceptedKeyTypes=sm2 -o Ciphers=sm4-ctr -o MACs=hmac-sm3 -o KexAlgorithms=sm2-sm3 -i ~/.ssh/id_sm2 [remote-ip] + ``` diff --git a/docs/en/25.03/Server/Security/ShangMi/tlcp-stack.md b/docs/en/25.03/Server/Security/ShangMi/tlcp-stack.md new file mode 100644 index 0000000000000000000000000000000000000000..fb21e643f7faeab30e0847266db8d9d9798dd792 --- /dev/null +++ b/docs/en/25.03/Server/Security/ShangMi/tlcp-stack.md @@ -0,0 +1,524 @@ +# TLCP协议栈 + +## 概述 + +TLCP是指符合《GB/T38636 2020信息安全技术 传输层密码协议(TLCP)》的安全通信协议,其特点是采用加密证书/私钥和签名证书/私钥相分离的方式。openEuler 22.09版本之后发布的openSSL软件在开源版本的基础上增加了对商密TLCP协议的支持,提供了如下主要的功能: + +- 新增对TLCP商密双证书加载的支持; +- 新增对ECC_SM4_CBC_SM3和ECDHE_SM4_CBC_SM3算法套件的支持; +- 新增对SM2证书的支持。 + +## 前置条件 + +openEuler操作系统安装的openSSL软件版本号大于1.1.1m-4: + +```bash +$ rpm -qa openssl +openssl-1.1.1m-6.oe2209.x86_64 +``` + +注意:当前仅openssl 1.1.1支持TLCP协议栈,openssl 3.x版本暂未支持。 + +## 如何使用 + +### 场景1:生成SM2双证书 + +根据TLCP协议标准,通信过程需要两本证书:签名证书和加密证书。签名证书在认证过程使用,作用是验证身份;加密证书在密钥协商时使用,作用是数据加密。CA是证书认证机构(Certificate Authority)的缩写。CSR证书请求文件得到CA的签发后才可形成证书。下面是一个参考案例,介绍使用自签名的CA证书来签发实体证书: + +1. 准备生成证书所需要使用的配置文件openssl.cnf,参考的内容如下(基于openssl源码apps/openssl.cnf修改): + + ```conf + # This definition stops the following lines choking if HOME isn't + # defined. + HOME = . + + # Extra OBJECT IDENTIFIER info: + #oid_file = $ENV::HOME/.oid + oid_section = new_oids + + # To use this configuration file with the "-extfile" option of the + # "openssl x509" utility, name here the section containing the + # X.509v3 extensions to use: + # extensions = + # (Alternatively, use a configuration file that has only + # X.509v3 extensions in its main [= default] section.) + + [ new_oids ] + + # We can add new OIDs in here for use by 'ca', 'req' and 'ts'. + # Add a simple OID like this: + # testoid1=1.2.3.4 + # Or use config file substitution like this: + # testoid2=${testoid1}.5.6 + + # Policies used by the TSA examples. + tsa_policy1 = 1.2.3.4.1 + tsa_policy2 = 1.2.3.4.5.6 + tsa_policy3 = 1.2.3.4.5.7 + + #################################################################### + [ ca ] + default_ca = CA_default # The default ca section + + #################################################################### + [ CA_default ] + + dir = ./demoCA # Where everything is kept + certs = $dir/certs # Where the issued certs are kept + crl_dir = $dir/crl # Where the issued crl are kept + database = $dir/index.txt # database index file. + #unique_subject = no # Set to 'no' to allow creation of + # several certs with same subject. + new_certs_dir = $dir/newcerts # default place for new certs. + + certificate = $dir/cacert.pem # The CA certificate + serial = $dir/serial # The current serial number + crlnumber = $dir/crlnumber # the current crl number + # must be commented out to leave a V1 CRL + crl = $dir/crl.pem # The current CRL + private_key = $dir/private/cakey.pem# The private key + + x509_extensions = usr_cert # The extensions to add to the cert + + # Comment out the following two lines for the "traditional" + # (and highly broken) format. + name_opt = ca_default # Subject Name options + cert_opt = ca_default # Certificate field options + + # Extension copying option: use with caution. + # copy_extensions = copy + + # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs + # so this is commented out by default to leave a V1 CRL. + # crlnumber must also be commented out to leave a V1 CRL. + # crl_extensions = crl_ext + + default_days = 365 # how long to certify for + default_crl_days= 30 # how long before next CRL + default_md = default # use public key default MD + preserve = no # keep passed DN ordering + + # A few difference way of specifying how similar the request should look + # For type CA, the listed attributes must be the same, and the optional + # and supplied fields are just that :-) + policy = policy_match + + # For the CA policy + [ policy_match ] + countryName = match + stateOrProvinceName = match + organizationName = match + organizationalUnitName = optional + commonName = supplied + emailAddress = optional + + # For the 'anything' policy + # At this point in time, you must list all acceptable 'object' + # types. + [ policy_anything ] + countryName = optional + stateOrProvinceName = optional + localityName = optional + organizationName = optional + organizationalUnitName = optional + commonName = supplied + emailAddress = optional + + #################################################################### + [ req ] + default_bits = 2048 + default_keyfile = privkey.pem + distinguished_name = req_distinguished_name + attributes = req_attributes + x509_extensions = v3_ca # The extensions to add to the self signed cert + + # Passwords for private keys if not present they will be prompted for + # input_password = secret + # output_password = secret + + # This sets a mask for permitted string types. There are several options. + # default: PrintableString, T61String, BMPString. + # pkix : PrintableString, BMPString (PKIX recommendation before 2004) + # utf8only: only UTF8Strings (PKIX recommendation after 2004). + # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). + # MASK:XXXX a literal mask value. + # WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. + string_mask = utf8only + + # req_extensions = v3_req # The extensions to add to a certificate request + + [ req_distinguished_name ] + countryName = Country Name (2 letter code) + countryName_default = AU + countryName_min = 2 + countryName_max = 2 + + stateOrProvinceName = State or Province Name (full name) + stateOrProvinceName_default = Some-State + + localityName = Locality Name (eg, city) + + 0.organizationName = Organization Name (eg, company) + 0.organizationName_default = Internet Widgits Pty Ltd + + # we can do this but it is not needed normally :-) + #1.organizationName = Second Organization Name (eg, company) + #1.organizationName_default = World Wide Web Pty Ltd + + organizationalUnitName = Organizational Unit Name (eg, section) + #organizationalUnitName_default = + + commonName = Common Name (e.g. server FQDN or YOUR name) + commonName_max = 64 + + emailAddress = Email Address + emailAddress_max = 64 + + # SET-ex3 = SET extension number 3 + + [ req_attributes ] + challengePassword = A challenge password + challengePassword_min = 4 + challengePassword_max = 20 + + unstructuredName = An optional company name + + [ usr_cert ] + + # These extensions are added when 'ca' signs a request. + + # This goes against PKIX guidelines but some CAs do it and some software + # requires this to avoid interpreting an end user certificate as a CA. + + basicConstraints=CA:FALSE + + # Here are some examples of the usage of nsCertType. If it is omitted + # the certificate can be used for anything *except* object signing. + + # This is OK for an SSL server. + # nsCertType = server + + # For an object signing certificate this would be used. + # nsCertType = objsign + + # For normal client use this is typical + # nsCertType = client, email + + # and for everything including object signing: + # nsCertType = client, email, objsign + + # This is typical in keyUsage for a client certificate. + # keyUsage = nonRepudiation, digitalSignature, keyEncipherment + + # This will be displayed in Netscape's comment listbox. + nsComment = "OpenSSL Generated Certificate" + + # PKIX recommendations harmless if included in all certificates. + subjectKeyIdentifier=hash + authorityKeyIdentifier=keyid,issuer + + # This stuff is for subjectAltName and issuerAltname. + # Import the email address. + # subjectAltName=email:copy + # An alternative to produce certificates that aren't + # deprecated according to PKIX. + # subjectAltName=email:move + + # Copy subject details + # issuerAltName=issuer:copy + + #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem + #nsBaseUrl + #nsRevocationUrl + #nsRenewalUrl + #nsCaPolicyUrl + #nsSslServerName + + # This is required for TSA certificates. + # extendedKeyUsage = critical,timeStamping + + [ v3_req ] + + # Extensions to add to a certificate request + + basicConstraints = CA:FALSE + keyUsage = nonRepudiation, digitalSignature + + [ v3enc_req ] + + # Extensions to add to a certificate request + + basicConstraints = CA:FALSE + keyUsage = keyAgreement, keyEncipherment, dataEncipherment + + [ v3_ca ] + + # Extensions for a typical CA + + + # PKIX recommendation. + + subjectKeyIdentifier=hash + + authorityKeyIdentifier=keyid:always,issuer + + basicConstraints = critical,CA:true + + # Key usage: this is typical for a CA certificate. However since it will + # prevent it being used as an test self-signed certificate it is best + # left out by default. + keyUsage = cRLSign, keyCertSign + + # Some might want this also + # nsCertType = sslCA, emailCA + + # Include email address in subject alt name: another PKIX recommendation + # subjectAltName=email:copy + # Copy issuer details + # issuerAltName=issuer:copy + + # DER hex encoding of an extension: beware experts only! + # obj=DER:02:03 + # Where 'obj' is a standard or added object + # You can even override a supported extension: + # basicConstraints= critical, DER:30:03:01:01:FF + + [ crl_ext ] + + # CRL extensions. + # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + + # issuerAltName=issuer:copy + authorityKeyIdentifier=keyid:always + + [ proxy_cert_ext ] + # These extensions should be added when creating a proxy certificate + + # This goes against PKIX guidelines but some CAs do it and some software + # requires this to avoid interpreting an end user certificate as a CA. + + basicConstraints=CA:FALSE + + # Here are some examples of the usage of nsCertType. If it is omitted + # the certificate can be used for anything *except* object signing. + + # This is OK for an SSL server. + # nsCertType = server + + # For an object signing certificate this would be used. + # nsCertType = objsign + + # For normal client use this is typical + # nsCertType = client, email + + # and for everything including object signing: + # nsCertType = client, email, objsign + + # This is typical in keyUsage for a client certificate. + # keyUsage = nonRepudiation, digitalSignature, keyEncipherment + + # This will be displayed in Netscape's comment listbox. + nsComment = "OpenSSL Generated Certificate" + + # PKIX recommendations harmless if included in all certificates. + subjectKeyIdentifier=hash + authorityKeyIdentifier=keyid,issuer + + # This stuff is for subjectAltName and issuerAltname. + # Import the email address. + # subjectAltName=email:copy + # An alternative to produce certificates that aren't + # deprecated according to PKIX. + # subjectAltName=email:move + + # Copy subject details + # issuerAltName=issuer:copy + + #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem + #nsBaseUrl + #nsRevocationUrl + #nsRenewalUrl + #nsCaPolicyUrl + #nsSslServerName + + # This really needs to be in place for it to be a proxy certificate. + proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo + + #################################################################### + [ tsa ] + + default_tsa = tsa_config1 # the default TSA section + + [ tsa_config1 ] + + # These are used by the TSA reply generation only. + dir = ./demoCA # TSA root directory + serial = $dir/tsaserial # The current serial number (mandatory) + crypto_device = builtin # OpenSSL engine to use for signing + signer_cert = $dir/tsacert.pem # The TSA signing certificate + # (optional) + certs = $dir/cacert.pem # Certificate chain to include in reply + # (optional) + signer_key = $dir/private/tsakey.pem # The TSA private key (optional) + signer_digest = sha256 # Signing digest to use. (Optional) + default_policy = tsa_policy1 # Policy if request did not specify it + # (optional) + other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) + digests = sha1, sha256, sha384, sha512 # Acceptable message digests (mandatory) + accuracy = secs:1, millisecs:500, microsecs:100 # (optional) + clock_precision_digits = 0 # number of digits after dot. (optional) + ordering = yes # Is ordering defined for timestamps? + # (optional, default: no) + tsa_name = yes # Must the TSA name be included in the reply? + # (optional, default: no) + ess_cert_id_chain = no # Must the ESS cert id chain be included? + # (optional, default: no) + ess_cert_id_alg = sha1 # algorithm to compute certificate + # identifier (optional, default: sha1) + ``` + +2. 生成自签名CA证书(下列命令为使用openSSL 1.1.1版本的场景,如使用openSSL 3.0.9及以上的版本,*openssl req*命令中的*-newkey*参数需要替换为*sm2:SM2.pem*): + + ```bash + openssl ecparam -name SM2 -out SM2.pem + openssl req -config ./openssl.cnf -nodes -subj '/C=AA/ST=BB/O=CC/OU=DD/CN=root ca' -keyout CA.key -newkey ec:SM2.pem -new -out CA.csr + openssl x509 -sm3 -req -days 30 -in CA.csr -extfile ./openssl.cnf -extensions v3_ca -signkey CA.key -out CA.crt + ``` + +3. 生成服务端签名证书和加密证书(下列命令为使用openSSL 1.1.1版本的场景,如使用openSSL 3.0.9及以上的版本,*openssl req*命令中的*-newkey*参数需要替换为*sm2:SM2.pem*): + + ```bash + openssl req -config ./openssl.cnf -nodes -subj '/C=AA/ST=BB/O=CC/OU=DD/CN=server sign' -keyout SS.key -newkey ec:SM2.pem -new -out SS.csr + openssl x509 -sm3 -req -days 30 -in SS.csr -CA CA.crt -CAkey CA.key -extfile ./openssl.cnf -extensions v3_req -out SS.crt -CAcreateserial + openssl req -config ./openssl.cnf -nodes -subj '/C=AA/ST=BB/O=CC/OU=DD/CN=server enc' -keyout SE.key -newkey ec:SM2.pem -new -out SE.csr + openssl x509 -sm3 -req -days 30 -in SE.csr -CA CA.crt -CAkey CA.key -extfile ./openssl.cnf -extensions v3enc_req -out SE.crt -CAcreateserial + ``` + +4. 生成客户端签名证书和加密证书: + + ```bash + openssl req -config ./openssl.cnf -nodes -subj '/C=AA/ST=BB/O=CC/OU=DD/CN=client sign' -keyout CS.key -newkey ec:SM2.pem -new -out CS.csr + openssl x509 -sm3 -req -days 30 -in CS.csr -CA CA.crt -CAkey CA.key -extfile ./openssl.cnf -extensions v3_req -out CS.crt -CAcreateserial + openssl req -config ./openssl.cnf -nodes -subj '/C=AA/ST=BB/O=CC/OU=DD/CN=client enc' -keyout CE.key -newkey ec:SM2.pem -new -out CE.csr + openssl x509 -sm3 -req -days 30 -in CE.csr -CA CA.crt -CAkey CA.key -extfile ./openssl.cnf -extensions v3enc_req -out CE.crt -CAcreateserial + ``` + +### 场景2:使用openSSL命令行验证TLCP协议栈 + +openSSL中提供的s_server/s_client工具可以用来测试TLCP协议: + +```bash +# 开启服务端 +openssl s_server -verify 5 -accept 4433 \ + -cert SS.crt \ + -key SS.key \ + -dcert SE.crt \ + -dkey SE.key \ + -CAfile CA.crt + +# 开启客户端 +openssl s_client -verify 5 -connect 127.0.0.1:4433 \ + -cert CS.crt \ + -key CS.key \ + -dcert CE.crt \ + -dkey CE.key \ + -CAfile CA.crt -tlcp +``` + +### 场景3:openSSL API使用 + +服务端参考代码: + +```cpp +int main() { + // 变量定义 + SSL_CTX *ctx = NULL; + const char *sign_cert_file = "SS.crt"; + const char *sign_key_file = "SS.key"; + const char *enc_cert_file = "SE.crt"; + const char *enc_key_file = "SE.key"; + + // 生成上下文 + ctx = SSL_CTX_new(TLS_server_method()); + + // 加载签名证书,加密证书及其私钥 + if (!SSL_CTX_use_gm_certificate_file(ctx, sign_cert_file, SSL_FILETYPE_PEM, SSL_USAGE_SIG)) + goto err; + + if (!SSL_CTX_use_gm_PrivateKey_file(ctx, sign_key_file, SSL_FILETYPE_PEM, SSL_USAGE_SIG)) + goto err; + + if (!SSL_CTX_use_gm_certificate_file(ctx, enc_cert_file, SSL_FILETYPE_PEM, SSL_USAGE_ENC)) + goto err; + + if (!SSL_CTX_use_gm_PrivateKey_file(ctx, enc_key_file, SSL_FILETYPE_PEM, SSL_USAGE_ENC)) + goto err; + + SSL_CTX_set_options(ctx, SSL_OP_ENCCERT_SECOND_POSITION); + + // 后续同标准tls流程 + SSL *ssl = SSL_new(ctx); +} +``` + +客户端参考代码: + +```cpp +int main() { + // 变量定义 + SSL_CTX *ctx = NULL; + const char *sign_cert_file = "CS.crt"; + const char *sign_key_file = "CS.key"; + const char *enc_cert_file = "CE.crt"; + const char *enc_key_file = "CE.key"; + + // 生成上下文 + ctx = SSL_CTX_new(TLCP_client_method()); + + // 加载签名证书,加密证书及其私钥 + if (!SSL_CTX_use_gm_certificate_file(ctx, sign_cert_file, SSL_FILETYPE_PEM, SSL_USAGE_SIG)) + goto err; + + if (!SSL_CTX_use_gm_PrivateKey_file(ctx, sign_key_file, SSL_FILETYPE_PEM, SSL_USAGE_SIG)) + goto err; + + if (!SSL_CTX_use_gm_certificate_file(ctx, enc_cert_file, SSL_FILETYPE_PEM, SSL_USAGE_ENC)) + goto err; + + if (!SSL_CTX_use_gm_PrivateKey_file(ctx, enc_key_file, SSL_FILETYPE_PEM, SSL_USAGE_ENC)) + goto err; + + // 设置算法套件为ECC-SM4-CBC-SM3或者ECDHE-SM4-CBC-SM3 + // 这一步并不强制编写,默认ECC-SM4-CBC-SM3优先 + if(SSL_CTX_set_cipher_list(ctx, "ECC-SM4-CBC-SM3") <= 0) + goto err; + + // 后续同标准tls流程 + SSL *ssl = SSL_new(ctx); +} +``` + +# KTLS卸载 + +## 概述 + +Linux内核协议栈仅实现了TCP/IP模型,并不支持SSL/TLS会话层协议。目前TLS加解密一般由用户态来实现。但在部分场景下,如内核sendfile发送文件,会产生多次跨态拷贝导致性能开销。因此内核实现了KTLS,即支持对socket配置加密上下文,从而将数据加密过程卸载到内核态或下层硬件实现。 + +openEuler 5.10内核的KTLS特性提供了对商密算法的支持,目前支持SM4-GCM和SM4-CCM两种算法。 + +## 前置条件 + +内核大于或等于5.10.0-106版本: + +```bash +# rpm -qa kernel +kernel-5.10.0-106.1.0.55.oe2209.x86_64 +``` + +## 如何使用 + +商密算法的调用和其他相同类型的加密算法调用方法一致,可参考Linux内核文档: + +```bash +https://www.kernel.org/doc/html/v5.10/networking/tls.html +``` diff --git a/docs/en/25.03/Server/Security/ShangMi/user-identity-authentication.md b/docs/en/25.03/Server/Security/ShangMi/user-identity-authentication.md new file mode 100644 index 0000000000000000000000000000000000000000..06c0d358558c8643af68275e61e17c3e924f72bd --- /dev/null +++ b/docs/en/25.03/Server/Security/ShangMi/user-identity-authentication.md @@ -0,0 +1,131 @@ +# 用户身份鉴别 + +操作系统通常使用口令的机制完成用户身份鉴别,openEuler提供了PAM、passwd、shadow、libuser等用户口令管理组件。用户口令在设置完成后,需要进行加密存储,通常使用哈希算法进行加密。openEuler提供的用户口令管理组件新增了对商密SM3的支持。 + +## PAM配置用户口令加密 + +### 概述 + +PAM是系统的可插拔认证模块,为上层应用提供认证机制。openEuler发布的PAM新增了对SM3算法用户口令加密的支持。 + +### 前置条件 + +1. PAM软件包大于或等于1.5.2-2版本: + + ```sh + $ rpm -qa pam + pam-1.5.2-2.oe2209.x86_64 + ``` + +2. libxcrypt软件包大于或等于4.4.26-2版本: + + ```sh + $ rpm -qa libxcrypt + pam-4.4.26-2.oe2209.x86_64 + ``` + +### 如何使用 + +1. 修改/etc/pam.d/password-auth和/etc/pam.d/system-auth文件,找到文件中“password sufficient pam_unix.so”开头的行,修改该行中算法字段为sm3: + + ```sh + $ cat /etc/pam.d/password-auth + ...... + password sufficient pam_unix.so sm3 shadow nullok try_first_pass use_authtok + ...... + + $ cat /etc/pam.d/system-auth + ...... + password sufficient pam_unix.so sm3 shadow nullok try_first_pass use_authtok + ...... + ``` + +2. 修改配置之后通过passwd命令修改密码或新增用户创建的密码,会使用sm3算法加密,加密结果以sm3开头存储在/etc/shadow中: + + ```sh + $ passwd testuser + Changing password for user testuser. + New password: + Retype new password: + passwd: all authentication tokens updated successfully. + $ cat /etc/shadow | grep testuser + testuser:$sm3$wnY86eyUlB5946gU$99LlMr0ddeZNDqnB2KRxn9f30SFCCvMv1WN1cFdsKJ2:19219:0:90:7:35:: + ``` + +### 注意事项 + +1. PAM配置默认使用sha512算法,修改配置使用商密SM3算法后,对已存在的用户密码无影响,需要修改密码才能更新密码算法; +2. 若PAM和libxcrypt要降级到非商密版本,并且已存在帐户密码使用SM3算法加密,则需先修改配 + 置为非商密算法,再修改帐号密码,再降级到非商密版本,否则这些帐户将无法正常登录。 + +## shadow配置用户口令加密 + +### 概述 + +shadow是Linux系统中常用的用户管理组件,提供了chpasswd、chgpasswd与newusers等命令。openEuler提供的shadow组件新增了对商密算法SM3的支持,以便在用户管理时使用SM3加密算法。因为shadow默认使用PAM安全认证机制,因此该组件支持商密算法只影响chpasswd与chgpasswd命令。 + +### 前置条件 + +shadow大于或等于4.9-4版本: + +```sh +$ rpm -qa shadow +shadow-4.9-4.oe2209.x86_64 +``` + +### 如何使用 + +1. chpasswd默认使用pam配置,通过-c指定SM3算法,会以SM3算法加密,加密结果以sm3开头存储在/etc/shadow中: + + ```sh + $ echo testuser:testPassword |chpasswd -c SM3 + $ cat /etc/shadow | grep testuser + testuser:$sm3$moojQQeBfdGOrL14$NqjckLHlk3ICs1cx.0rKZwRHafjVlqksdSJqfx9eYh6:19220:0:99999:7::: + ``` + +2. chgpasswd默认使用pam配置,通过-c指定SM3算法,会以SM3算法加密,加密结果以sm3开头存储在/etc/shadow中: + + ```sh + $ echo testGroup:testPassword |chpasswd -c SM3 + $ cat /etc/gshadow | grep testGroup + testGroup:$sm3$S3h3X6U6KsXg2Gkc$LFCAnKbi6JItarQz4Y/Aq9/hEbEMQXq9nQ4rY1j9BY9:: + ``` + +### 注意事项 + +shadow默认使用PAM安全认证机制,相关命令使用-c参数指定加密算法时,不使用PAM机制。 + +## libuser配置用户口令加密 + +### 概述 + +libuser库实现了一个标准化的接口,用于操作和管理用户和组帐户。该库经过封装,对外提供了命令行接口和python接口,用于管理用户和组。其中涉及用户密码的管理,支持使用des、md5、blowfish、sha256、sha512等算法对用户口令进行加密,openEuler发布的libuser新增了对SM3算法加密支持。 + +### 前置条件 + +libuser大于或等于0.63-3版本: + +```sh +$ rpm -qa libuser +libuser-0.63-3.oe2209.x86_64 +``` + +### 如何使用 + +1. 编辑/etc/libuser.conf,修改[defaults]域crypt_style=sm3: + + ```sh + $ cat /etc/libuser.conf + ...... + [defaults] + crypt_style = sm3 + ...... + ``` + +2. 通过lusermod、lpasswd、luseradd等命令设置用户口令时,口令加密算法默认为sm3。加密结果以sm3开头存储在/etc/shadow中: + + ```sh + # luseradd testuser -P Test@123 + # cat /etc/shadow | grep testuser + testuser:$sm3$1IJtoN6zlBDCiPKC$5oxscBTgiquPAEmZWGNDVqTPrboHJw3fFSohjF6sONB:18862:0:90:7:35:: + ``` diff --git a/docs/en/25.03/Server/Security/TrustedComputing/DIM.md b/docs/en/25.03/Server/Security/TrustedComputing/DIM.md new file mode 100644 index 0000000000000000000000000000000000000000..8b9157467d3e3e784c318cdecfade1d5ad0588af --- /dev/null +++ b/docs/en/25.03/Server/Security/TrustedComputing/DIM.md @@ -0,0 +1,727 @@ +# 动态完整性度量(DIM) + +本章节为DIM(Dynamic Integrity Measurement)动态完整性度量的特性介绍以及使用说明。 + +## 背景 + +随着信息产业的不断发展,信息系统所面临的安全风险也日益增长。信息系统中可能运行大量软件,部分软件不可避免地存在漏洞,这些漏洞一旦被攻击者利用,可能会对系统业务造成严重的影响,如数据泄露、服务不可用等。 + +绝大部分的软件攻击,都会伴随着完整性破坏,如恶意进程运行、配置文件篡改、后门植入等。因此业界提出了完整性保护技术,指的是从系统启动开始,对关键数据进行度量和校验,从而保证系统运行达到预期效果。当前业界已广泛使用的完整性保护技术(如安全启动、文件完整性度量等)都无法对进程运行时的内存数据进行保护。如果攻击者利用一些手段修改了进程的代码指令,可能导致进程被劫持或被植入后门,具有攻击性强,隐蔽性高的特点。对于这种攻击手段,业界提出了动态完整性度量技术,即对进程的运行时内存中的关键数据进行度量和保护。 + +## 术语说明 + +静态基线:针对度量目标的二进制文件进行解析所生成的度量基准数据; + +动态基线:针对度量目标执行首次度量的结果; + +度量策略:指定度量目标的配置信息; + +度量日志:存储度量结果的列表,包含度量对象、度量结果等信息。 + +## 特性简介 + +DIM特性通过在程序运行时对内存中的关键数据(如代码段、数据段)进行度量,并将度量结果和基准值进行对比,确定内存数据是否被篡改,从而检测攻击行为,并采取应对措施。 + +### 功能范围 + +- 当前DIM特性支持在ARM64/X86架构系统中运行; +- 当前DIM特性支持对以下关键内存数据执行度量: + - 用户态进程的代码段:对应ELF文件中属性为PT_LOAD、权限为RX的段,对应进程加载后权限为RX的vma区域; + - 内核模块代码段:起始地址为内核模块对应struct module结构体中的core_layout.base,长度为core_layout.text_size; + - 内核代码段:对应\_stext符号至\_etext,跳过可能由于内核static key机制发生变化的地址。 +- 当前DIM特性支持对接以下硬件平台: + - 支持将度量结果扩展至TPM 2.0芯片的PCR寄存器,以实现远程证明服务对接。 + +### 技术限制 + +- 对于用户态进程,仅支持度量文件映射代码段,不支持度量匿名代码段; +- 不支持度量内核热补丁; +- 仅支持主动触发机制,如果两次触发过程中发生了篡改-恢复的行为,会导致无法识别攻击; +- 对于主动修改代码段的场景(如代码段重定位、自修改或热补丁),会被识别为攻击; +- 对于内核、内核模块的度量,以触发动态基线时的度量结果作为度量基准值,静态基线值仅作为一个固定标识; +- 度量目标必须在触发动态基线的时刻就已在内存中加载(如进程运行或内核模块加载),否则后续无法度量; +- 在需要使用TPM芯片的PCR寄存器验证度量日志的场景下,DIM模块不允许卸载,否则会导致度量日志清空,而无法和PCR寄存器匹配; + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 特性启用后,会对系统性能存在一定影响,主要包括以下方面: +> +> - DIM特性自身加载以及基线数据、度量日志管理会对系统内存造成消耗,具体影响与保护策略配置相关; +> - DIM特性执行度量期间需要进行哈希运算,造成CPU消耗,具体影响与需要度量的数据大小有关; +> - DIM特性执行度量期间需要对部分资源执行上锁或获取信号量操作,可能导致其他并发进程等待。 + +### 规格约束 + +| 规格项 | 值 | +| ------------------------------------------------------------ | ---- | +| 文件大小上限(策略文件、静态基线文件、签名文件、证书文件) | 10MB | +| 同一个度量目标在一次动态基线后多次度量期间最多记录的篡改度量日志条数 | 10条 | +| /etc/dim/policy中度量策略最大可记录数|10000条| + +### 架构说明 + +DIM包含两个软件包dim_tools和dim,分别提供如下组件: + +| 软件包 | 组件 | 说明 | +| --------- | ---------------- | ------------------------------------------------------------ | +| dim_tools | dim_gen_baseline | 用户态组件,静态基线生成工具,用于生成动态度量所需要的基线数据,该基线数据在DIM特性运行时会被导入并作为度量基准值 | +| dim | dim_core | 内核模块,执行核心的动态度量逻辑,包括策略解析、静态基线解析、动态基线建立、度量执行、度量日志记录、TPM芯片扩展操作等,实现对内存关键数据的度量功能 | +| dim | dim_monitor | 内核模块,执行对dim_core的代码段和关键数据的度量保护,一定程度防止由于dim_core遭受攻击导致的DIM功能失效。 | + +整体架构如下图所示: + +![](./figures/dim_architecture.jpg) + +### 关键流程说明 + +dim_core和dim_monitor模块均提供了对内存数据的度量功能,包含两个核心流程: + +- 动态基线流程:dim_core模块读取并解析策略和静态基线文件,然后对目标进程执行代码段度量,度量结果在内存中以动态基线形式存放,最后将动态基线数据和静态基线数据进行对比,并将对比结果记录度量日志;dim_monitor模块对dim_core模块的代码段和关键数据进行度量,作为动态基线并记录度量日志; +- 动态度量流程:dim_core和dim_monitor模块对目标执行度量,并将度量结果与动态基线值进行对比,如果对比不一致,则将结果记录度量日志。 + +### 接口说明 + +#### 文件路径说明 + +| 路径 | 说明 | +| ------------------------------- | ------------------------------------------------------------ | +| /etc/dim/policy | 度量策略文件 | +| /etc/dim/policy.sig | 度量策略签名文件,用于存放策略文件的签名信息,在签名校验功能开启的情况下使用 | +| /etc/dim/digest_list/*.hash | 静态基线文件,用于存放度量的基准值信息 | +| /etc/dim/digest_list/*.hash.sig | 静态基线签名文件,用于存放静态基线文件的签名信息,在签名校验功能开启的情况下使用 | +| /etc/keys/x509_dim.der | 证书文件,用于校验策略文件和静态基线文件的签名信息,在签名校验功能开启的情况下使用 | +| /sys/kernel/security/dim | DIM文件系统目录,DIM内核模块加载后生成,目录下提供对DIM功能进行操作的内核接口 | + +#### 文件格式说明 + +1. 度量策略文件格式说明 + + 文本文件,以UNIX换行符进行分隔,每行代表一条度量策略,当前支持以下几种配置格式: + + 1. 用户态进程代码段度量配置: + + ```sh + measure obj=BPRM_TEXT path=<度量目标进程可执行文件或动态库对应二进制文件的绝对路径> + ``` + + 2. 内核模块代码段度量配置: + + ```sh + measure obj=MODULE_TEXT name=<内核模块名> + ``` + + 3. 内核度量配置: + + ```sh + measure obj=KERNEL_TEXT + ``` + + **参考示例:** + + ```sh + # cat /etc/dim/policy + measure obj=BPRM_TEXT path=/usr/bin/bash + measure obj=BPRM_TEXT path=/usr/lib64/libc.so.6 + measure obj=MODULE_TEXT name=ext4 + measure obj=KERNEL_TEXT + ``` + +2. 静态基线文件格式说明 + + 文本文件,以UNIX换行符进行分隔,每行代表一条静态基线,当前支持以下几种配置格式: + + 1. 用户态进程基线: + + ```sh + dim USER sha256:6ae347be2d1ba03bf71d33c888a5c1b95262597fbc8d00ae484040408a605d2b <度量目标进程可执行文件或动态库对应二进制文件的绝对路径> + ``` + + 2. 内核模块基线: + + ```sh + dim KERNEL sha256:a18bb578ff0b6043ec5c2b9b4f1c5fa6a70d05f8310a663ba40bb6e898007ac5 <内核release号>/<内核模块名> + ``` + + 3. 内核基线: + + ```sh + dim KERNEL sha256:2ce2bc5d65e112ba691c6ab46d622fac1b7dbe45b77106631120dcc5441a3b9a <内核release号> + ``` + + **参考示例:** + + ```sh + dim USER sha256:6ae347be2d1ba03bf71d33c888a5c1b95262597fbc8d00ae484040408a605d2b /usr/bin/bash + dim USER sha256:bc937f83dee4018f56cc823f5dafd0dfedc7b9872aa4568dc6fbe404594dc4d0 /usr/lib64/libc.so.6 + dim KERNEL sha256:a18bb578ff0b6043ec5c2b9b4f1c5fa6a70d05f8310a663ba40bb6e898007ac5 6.4.0-1.0.1.4.oe2309.x86_64/dim_monitor + dim KERNEL sha256:2ce2bc5d65e112ba691c6ab46d622fac1b7dbe45b77106631120dcc5441a3b9a 6.4.0-1.0.1.4.oe2309.x86_64 + ``` + +3. 度量日志格式说明 + + 文本内容,以UNIX换行符进行分隔,每行代表一条度量日志,格式为: + + ```sh + <度量日志哈希值> <度量算法>:<度量哈希值> <度量对象> <度量日志类型> + ``` + + **参考示例:** + + 1. 对bash进程代码段执行度量,度量结果与静态基线一致: + + ```sh + 12 0f384a6d24e121daf06532f808df624d5ffc061e20166976e89a7bb24158eb87 sha256:db032449f9e20ba37e0ec4a506d664f24f496bce95f2ed972419397951a3792e /usr/bin.bash [static baseline] + ``` + + 2. 对bash进程代码段执行度量,度量结果与静态基线不一致: + + ```sh + 12 0f384a6d24e121daf06532f808df624d5ffc061e20166976e89a7bb24158eb87 sha256:db032449f9e20ba37e0ec4a506d664f24f496bce95f2ed972419397951a3792e /usr/bin.bash [tampered] + ``` + + 3. 对ext4内核模块代码段执行度量,未找到静态基线: + + ```sh + 12 0f384a6d24e121daf06532f808df624d5ffc061e20166976e89a7bb24158eb87 sha256:db032449f9e20ba37e0ec4a506d664f24f496bce95f2ed972419397951a3792e ext4 [no static baseline] + ``` + + 4. dim_monitor对dim_core执行度量,记录基线时的度量结果: + + ```sh + 12 660d594ba050c3ec9a7cdc8cf226c5213c1e6eec50ba3ff51ff76e4273b3335a sha256:bdab94a05cc9f3ad36d29ebbd14aba8f6fd87c22ae580670d18154b684de366c dim_core.text [dynamic baseline] + 12 28a3cefc364c46caffca71e7c88d42cf3735516dec32796e4883edcf1241a7ea sha256:0dfd9656d6ecdadc8ec054a66e9ff0c746d946d67d932cd1cdb69780ccad6fb2 dim_core.data [dynamic baseline] + ``` + +4. 证书/签名文件格式说明 + +为通用格式,详见[开启签名校验](#开启签名校验)章节。 + +#### 内核模块参数说明 + +1. dim_core模块参数 + + | 参数名 | 参数内容 | 取值范围 | 默认值 | + | -------------------- | ------------------------------------------------------------ | ------------------------ | ------ | + | measure_log_capacity | 度量日志最大条数,当dim_core记录的度量日志数量达到参数设置时,停止记录度量日志 | 100-UINT_MAX(64位系统) | 100000 | + | measure_schedule | 度量完一个进程/模块后调度的时间,单位毫秒,设置为0代表不调度 | 0-1000 | 0 | + | measure_interval | 自动度量周期,单位分钟,设置为0代表不设置自动度量 | 0-525600 | 0 | + | measure_hash | 度量哈希算法 | sha256, sm3 | sha256 | + | measure_pcr | 将度量结果扩展至TPM芯片的PCR寄存器,设置为0代表不扩展(注意需要与芯片实际的PCR编号保持一致) | 0-128 | 0 | + | signature | 是否启用策略文件和签名机制,设置为0代表不启用,设置为1代表启用 | 0, 1 | 0 | + + **使用示例**: + + ```sh + insmod /path/to/dim_core.ko measure_log_capacity=10000 measure_schedule=10 measure_pcr=12 + modprobe dim_core measure_log_capacity=10000 measure_schedule=10 measure_pcr=12 + ``` + +2. dim_monitor模块参数 + + | 参数名 | 参数内容 | 取值范围 | 默认值 | + | -------------------- | ------------------------------------------------------------ | ------------------------ | ------ | + | measure_log_capacity | 度量日志最大条数,当dim_monitor记录的度量日志数量达到参数设置时,停止记录度量日志 | 100-UINT_MAX(64位系统) | 100000 | + | measure_hash | 度量哈希算法 | sha256, sm3 | sha256 | + | measure_pcr | 将度量结果扩展至TPM芯片的PCR寄存器,设置为0代表不扩展 | 0-128 | 0 | + + **使用示例**: + + ```sh + insmod /path/to/dim_monitor.ko measure_log_capacity=10000 measure_hash=sm3 + modprobe dim_monitor measure_log_capacity=10000 measure_hash=sm3 + ``` + +#### 内核接口说明 + +1. dim_core模块接口 + + | 接口名 | 属性 | 功能 | 示例 | + | -------------------------- | ---- | ------------------------------------------------------------ | --------------------------------------------------------- | + | measure | 只写 | 写入字符串1触发动态度量,成功返回0,失败返回错误码 | echo 1 > /sys/kernel/security/dim/measure | + | baseline_init | 只写 | 写入字符串1触发动态基线,成功返回0,失败返回错误码 | echo 1 > /sys/kernel/security/dim/baseline_init | + | ascii_runtime_measurements | 只读 | 读取接口查询度量日志 | cat /sys/kernel/security/dim/ascii_runtime_measurements | + | runtime_status | 只读 | 读取接口返回状态类型信息,失败返回错误码 | cat /sys/kernel/security/dim/runtime_status | + | interval | 读写 | 写入数字字符串设置自动度量周期(范围同measure_interval参数);读取接口查询当前自动度量周期,失败返回错误码 | echo 10 > /sys/kernel/security/dim/interval
cat /sys/kernel/security/dim/interval | + + **dim_core状态类型信息说明:** + + 状态信息以如下字段取值: + + - DIM_NO_BASELINE:表示dim_core已加载,但未进行任何操作; + - DIM_BASELINE_RUNNING:表示正在进行动态基线建立; + - DIM_MEASURE_RUNNING:表示正在进行动态度量度量; + - DIM_PROTECTED:表示已完成动态基线建立,处于受保护状态; + - DIM_ERROR:执行动态基线建立或动态度量时发生错误,需要用户解决错误后重新触发动态基线建立或动态度量。 + +2. dim_monitor模块接口 + + | 接口名 | 属性 | 说明 | 示例 | + | ---------------------------------- | ---- | ---------------------------------------------- | ------------------------------------------------------------ | + | monitor_run | 只写 | 写入字符串1触发度量,成功返回0,失败返回错误码 | echo 1 > /sys/kernel/security/dim/monitor_run | + | monitor_baseline | 只写 | 写入字符串1触发基线,成功返回0,失败返回错误码 | echo 1 > /sys/kernel/security/dim/monitor_baseline | + | monitor_ascii_runtime_measurements | 只读 | 读取接口查询度量日志 | cat /sys/kernel/security/dim/monitor_ascii_runtime_measurements | + | monitor_status | 只读 | 读取接口返回状态类型信息,失败返回错误码 | cat /sys/kernel/security/dim/monitor_status | + + **dim_monitor状态类型信息说明:** + + - ready:表示dim_monitior已加载,但未进行任何操作; + - running:表示正在进行动态基线建立或动态度量; + - error:执行动态基线建立或动态度量时发生错误,需要用户解决错误后重新触发动态基线建立或动态度量; + - protected:表示已完成动态基线建立,处于受保护状态。 + +#### 用户态工具接口说明 + +dim_gen_baseline命令行接口,详见: 。 + +## 如何使用 + +### 安装/卸载 + +**前置条件**: + +- OS版本:支持openEuler 23.09及以上版本; +- 内核版本:支持openEuler kernel 5.10/6.4版本。 + +安装dim_tools和dim软件包,以openEuler 23.09版本为例: + +```sh +# yum install -y dim_tools dim +``` + +软件包安装完成后,DIM内核组件不会默认加载,可通过如下命令进行加载和卸载: + +```sh +# modprobe dim_core 或 insmod /path/to/dim_core.ko +# modprobe dim_monitor 或 insmod /path/to/dim_monitor.ko +# rmmod dim_monitor +# rmmod dim_core +``` + +加载成功后,可以通过如下命令查询: + +```sh +# lsmod | grep dim_core +dim_core 77824 1 dim_monitor +# lsmod | grep dim_monitor +dim_monitor 36864 0 +``` + +卸载前需要先卸载ko,再卸载rpm包 + +```sh +# rmmod dim_monitor +# rmmod dim_core +# rpm -e dim +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> dim_monitor必须后于dim_core加载,先于dim_core卸载; +> 也可使用源码编译安装,详见 。 + +### 度量用户态进程代码段 + +**前置条件**: + +- dim_core模块加载成功; + +- 用户需要准备一个常驻的度量目标用户态程序,本小节以程序路径/opt/dim/demo/dim_test_demo为例: + + ```sh + # /opt/dim/demo/dim_test_demo & + ``` + +**步骤1**:为度量目标进程对应的二进制文件生成静态基线 + +```sh +# mkdir -p /etc/dim/digest_list +# dim_gen_baseline /opt/dim/demo/dim_test_demo -o /etc/dim/digest_list/test.hash +``` + +**步骤2**:配置度量策略 + +```sh +# echo "measure obj=BPRM_TEXT path=/opt/dim/demo/dim_test_demo" > /etc/dim/policy +``` + +**步骤3**:触发动态基线建立 + +```sh +# echo 1 > /sys/kernel/security/dim/baseline_init +``` + +**步骤4**:查询度量日志 + +```sh +# cat /sys/kernel/security/dim/ascii_runtime_measurements +0 e9a79e25f091e03a8b3972b1a0e4ae2ccaed1f5652857fe3b4dc947801a6913e sha256:02e28dff9997e1d81fb806ee5b784fd853eac8812059c4dba7c119c5e5076989 /opt/dim/demo/dim_test_demo [static baseline] +``` + +如上度量日志说明目标进程被成功度量,且度量结果与静态基线一致。 + +**步骤5**:触发动态度量 + +```sh +# echo 1 > /sys/kernel/security/dim/measure +``` + +度量完成后可通过**步骤4**查询度量日志,如果度量结果和动态基线阶段的度量结果一致,则度量日志不会更新,否则会新增异常度量日志。如果攻击者尝试篡改目标程序(如采用修改代码重新编译的方式,过程略)并重新启动目标程序: + +```sh +# pkill dim_test_demo +# /opt/dim/demo/dim_test_demo & +``` + +再次触发度量并查询度量日志,可以发现有标识为“tampered”的度量日志: + +```sh +# echo 1 > /sys/kernel/security/dim/measure +# cat /sys/kernel/security/dim/ascii_runtime_measurements +0 e9a79e25f091e03a8b3972b1a0e4ae2ccaed1f5652857fe3b4dc947801a6913e sha256:02e28dff9997e1d81fb806ee5b784fd853eac8812059c4dba7c119c5e5076989 /opt/dim/demo/dim_test_demo [static baseline] +0 08a2f6f2922ad3d1cf376ae05cf0cc507c2f5a1c605adf445506bc84826531d6 sha256:855ec9a890ff22034f7e13b78c2089e28e8d217491665b39203b50ab47b111c8 /opt/dim/demo/dim_test_demo [tampered] +``` + +### 度量内核模块代码段 + +**前置条件**: + +- dim_core模块加载成功; + +- 用户需要准备一个度量目标内核模块,本小节假设内核模块路径为/opt/dim/demo/dim_test_module.ko,模块名为dim_test_module: + + ```sh + # insmod /opt/dim/demo/dim_test_module.ko + ``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 需要保证内核模块的内核编译环境版本号和当前系统内核版本号一致,可以使用如下方法确认: +> +>```sh +># modinfo dim_monitor.ko | grep vermagic | grep "$(uname -r)" +>vermagic: 6.4.0-1.0.1.4.oe2309.x86_64 SMP preempt mod_unload modversions +>``` + +即内核模块vermagic信息的第一个字段需要和当前内核版本号完全一致。 + +**步骤1**:为度量目标内核模块生成静态基线 + +```sh +# mkdir -p /etc/dim/digest_list +# dim_gen_baseline /opt/dim/demo/dim_test_module.ko -o /etc/dim/digest_list/test.hash +``` + +**步骤2**:配置度量策略 + +```sh +# echo "measure obj=MODULE_TEXT name=dim_test_module" > /etc/dim/policy +``` + +**步骤3**:触发动态基线建立 + +```sh +# echo 1 > /sys/kernel/security/dim/baseline_init +``` + +**步骤4**:查询度量日志 + +```sh +# cat /sys/kernel/security/dim/ascii_runtime_measurements +0 9603a9d5f87851c8eb7d2619f7abbe28cb8a91f9c83f5ea59f036794e23d1558 sha256:9da4bccc7ae1b709deab8f583b244822d52f3552c93f70534932ae21fac931c6 dim_test_module [static baseline] +``` + +如上度量日志说明dim_test_module模块被成功度量,并以当前的度量结果作为后续度量的基准值(此时度量日志中的哈希值不代表实际度量值)。 + +**步骤5**:触发动态度量 + +```sh +echo 1 > /sys/kernel/security/dim/measure +``` + +度量完成后可通过**步骤4**查询度量日志,如果度量结果和动态基线阶段的度量结果一致,则度量日志不会更新,否则会新增异常度量日志。如果攻击者尝试篡改内核模块(如采用修改代码重新编译的方式,过程略)并重新加载: + +```sh +rmmod dim_test_module +insmod /opt/dim/demo/dim_test_module.ko +``` + +再次触发度量并查询度量日志,可以发现有标识为“tampered”的度量日志: + +```sh +# cat /sys/kernel/security/dim/ascii_runtime_measurements +0 9603a9d5f87851c8eb7d2619f7abbe28cb8a91f9c83f5ea59f036794e23d1558 sha256:9da4bccc7ae1b709deab8f583b244822d52f3552c93f70534932ae21fac931c6 dim_test_module [static baseline] +0 6205915fe63a7042788c919d4f0ff04cc5170647d7053a1fe67f6c0943cd1f40 sha256:4cb77370787323140cb572a789703be1a4168359716a01bf745aa05de68a14e3 dim_test_module [tampered] +``` + +### 度量内核代码段 + +**前置条件**: + +- dim_core模块加载成功。 + +**步骤1**:为内核生成静态基线 + +```sh +# mkdir -p /etc/dim/digest_list +# dim_gen_baseline -k "$(uname -r)" -o /etc/dim/digest_list/test.hash /boot/vmlinuz-6.4.0-1.0.1.4.oe2309.x86_64 +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> /boot/vmlinuz-6.4.0-1.0.1.4.oe2309.x86_64文件名不固定。 + +**步骤2**:配置DIM策略 + +```sh +# echo "measure obj=KERNEL_TEXT" > /etc/dim/policy +``` + +**步骤3**:触发动态基线建立 + +```sh +# echo 1 > /sys/kernel/security/dim/baseline_init +``` + +**步骤4**:查询度量日志 + +```sh +# cat /sys/kernel/security/dim/ascii_runtime_measurements +0 ef82c39d767dece1f5c52b31d1e8c7d55541bae68a97542dda61b0c0c01af4d2 sha256:5f1586e95b102cd9b9f7df3585fe13a1306cbd464f2ebe47a51ad34128f5d0af 6.4.0-1.0.1.4.oe2309.x86_64 [static baseline] +``` + +如上度量日志说明内核被成功度量,并以当前的基线结果作为后续度量的基准值(此时度量日志中的哈希值不代表实际度量值)。 + +**步骤5**:触发动态度量 + +```sh +# echo 1 > /sys/kernel/security/dim/measure +``` + +度量完成后可通过**步骤4**查询度量日志,如果度量结果和动态基线阶段的度量结果一致,则度量日志不会更新,否则会新增异常度量日志。 + +### 度量dim_core模块 + +**前置条件**: + +- dim_core和dim_monitor模块加载成功; +- 度量策略配置完成。 + +**步骤1**:触发dim_core动态基线 + +```sh +# echo 1 > /sys/kernel/security/dim/baseline_init +``` + +**步骤2**:触发dim_monitor动态基线 + +```sh +# echo 1 > /sys/kernel/security/dim/monitor_baseline +``` + +**步骤3**:查询dim_monitor度量日志 + +```sh +# cat /sys/kernel/security/dim/monitor_ascii_runtime_measurements +0 c1b0d9909ddb00633fc6bbe7e457b46b57e165166b8422e81014bdd3e6862899 sha256:35494ed41109ebc9bf9bf7b1c190b7e890e2f7ce62ca1920397cd2c02a057796 dim_core.text [dynamic baseline] +0 9be7121cd2c215d454db2a8aead36b03d2ed94fad0fbaacfbca83d57a410674f sha256:f35d20aae19ada5e633d2fde6e93133c3b6ae9f494ef354ebe5b162398e4d7fa dim_core.data [dynamic baseline] +``` + +如上度量日志说明dim_core模块被成功度量,并以当前的基线结果作为后续度量的基准值。 +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 若跳过动态基线创建,直接进行度量,日志中会显示tampered。 + +**步骤4**:触发dim_monitor动态度量 + +```sh +# echo 1 > /sys/kernel/security/dim/monitor_run +``` + +如果度量结果和动态基线阶段的度量结果一致,则度量日志不会更新,否则会新增异常度量日志。尝试修改策略后重新执触发dim_core动态基线,此时由于度量目标发生变化,dim_core管理的基线数据也会发生变更,从而dim_monitor的度量结果也会发生变化: + +```sh +# echo "measure obj=BPRM_TEXT path=/usr/bin/bash" > /etc/dim/policy +# echo 1 > /sys/kernel/security/dim/baseline_init +``` + +再次触发dim_monitor度量并查询度量日志,可以发现有标识为“tampered”的度量日志: + +```sh +# echo 1 > /sys/kernel/security/dim/monitor_run +# cat /sys/kernel/security/dim/monitor_ascii_runtime_measurements +0 c1b0d9909ddb00633fc6bbe7e457b46b57e165166b8422e81014bdd3e6862899 sha256:35494ed41109ebc9bf9bf7b1c190b7e890e2f7ce62ca1920397cd2c02a057796 dim_core.text [dynamic baseline] +0 9be7121cd2c215d454db2a8aead36b03d2ed94fad0fbaacfbca83d57a410674f sha256:f35d20aae19ada5e633d2fde6e93133c3b6ae9f494ef354ebe5b162398e4d7fa dim_core.data [dynamic baseline] +0 6a60d78230954aba2e6ea6a6b20a7b803d7adb405acbb49b297c003366cfec0d sha256:449ba11b0bfc6146d4479edea2b691aa37c0c025a733e167fd97e77bbb4b9dab dim_core.data [tampered] +``` + +### 扩展TPM PCR寄存器 + +**前置条件**: + +- 系统已安装TPM 2.0芯片,执行如下命令返回不为空: + + ```sh + # ls /dev/tpm* + /dev/tpm0 /dev/tpmrm0 + ``` + +- 系统已安装tpm2-tools软件包,执行如下命令返回不为空: + + ```sh + # rpm -qa tpm2-tools + ``` + +- 度量策略和静态基线配置完成。 + +**步骤1**:加载dim_core和dim_monitor模块,并配置扩展度量结果的PCR寄存器编号,这里为dim_core度量结果指定PCR 12,为dim_monitor指定PCR 13 + +```sh +# modprobe dim_core measure_pcr=12 +# modprobe dim_monitor measure_pcr=13 +``` + +**步骤2**:触发dim_core和dim_monitor基线 + +```sh +# echo 1 > /sys/kernel/security/dim/baseline_init +# echo 1 > /sys/kernel/security/dim/monitor_baseline +``` + +**步骤3**:查看度量日志,每条日志都显示了对应的TPM PCR寄存器编号 + +```sh +# cat /sys/kernel/security/dim/ascii_runtime_measurements +12 2649c414d1f9fcac1c8d0df8ae7b1c18b5ea10a162b957839bdb8f8415ec6146 sha256:83110ce600e744982d3676202576d8b94cea016a088f99617767ddbd66da1164 /usr/lib/systemd/systemd [static baseline] +# cat /sys/kernel/security/dim/monitor_ascii_runtime_measurements +13 72ee3061d5a80eb8547cd80c73a80c3a8dc3b3e9f7e5baa10f709350b3058063 sha256:5562ed25fcdf557efe8077e231399bcfbcf0160d726201ac8edf7a2ca7c55ad0 dim_core.text [dynamic baseline] +13 8ba44d557a9855c03bc243a8ba2d553347a52c1a322ea9cf8d3d1e0c8f0e2656 sha256:5279eadc235d80bf66ba652b5d0a2c7afd253ebaf1d03e6e24b87b7f7e94fa02 dim_core.data [dynamic baseline] +``` + +**步骤4**:检查TPM芯片的PCR寄存器,对应的寄存器均已被写入了扩展值 + +```sh +# tpm2_pcrread sha256 | grep "12:" + 12: 0xF358AC6F815BB29D53356DA2B4578B4EE26EB9274E553689094208E444D5D9A2 +# tpm2_pcrread sha256 | grep "13:" + 13: 0xBFB9FF69493DEF9C50E52E38B332BDA8DE9C53E90FB96D14CD299E756205F8EA +``` + +### 开启签名校验 + +**前置条件**: + +- 用户准备公钥证书和签名私钥,签名算法需要为RSA,哈希算法为sha256,证书格式需要为DER。也可以采用如下方式生成: + + ```sh + # openssl genrsa -out dim.key 4096 + # openssl req -new -sha256 -key dim.key -out dim.csr -subj "/C=AA/ST=BB/O=CC/OU=DD/CN=DIM Test" + # openssl x509 -req -days 3650 -signkey dim.key -in dim.csr -out dim.crt + # openssl x509 -in dim.crt -out dim.der -outform DER + ``` + +- 度量策略配置完成。 + +**步骤1**:将DER格式的证书放置在/etc/keys/x509_dim.der路径 + +```sh +# mkdir -p /etc/keys +# cp dim.der /etc/keys/x509_dim.der +``` + +**步骤2**:对策略文件和静态基线文件进行签名,签名文件必须为原文件名直接添加.sig后缀 + +```sh +# openssl dgst -sha256 -out /etc/dim/policy.sig -sign dim.key /etc/dim/policy +# openssl dgst -sha256 -out /etc/dim/digest_list/test.hash.sig -sign dim.key /etc/dim/digest_list/test.hash +``` + +**步骤3**:加载dim_core模块,开启签名校验功能 + +```sh +modprobe dim_core signature=1 +``` + +此时,策略文件和静态基线文件均需要通过签名校验后才能加载。 +修改策略文件触发基线,会导致基线失败: + +```sh +# echo "" >> /etc/dim/policy +# echo 1 > /sys/kernel/security/dim/baseline_init +-bash: echo: write error: Key was rejected by service +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 如果某个静态基线文件签名校验失败,dim_core会跳过该文件的解析,而不会导致基线失败。 + +### 配置度量算法 + +**前置条件**: + +- 度量策略配置完成。 + +**步骤1**:加载dim_core和dim_monitor模块,并配置度量算法,这里以sm3算法为例 + +```sh +# modprobe dim_core measure_hash=sm3 +# modprobe dim_monitor measure_hash=sm3 +``` + +**步骤2**:配置策略并为度量目标程序生成sm3算法的静态基线 + +```sh +# echo "measure obj=BPRM_TEXT path=/opt/dim/demo/dim_test_demo" > /etc/dim/policy +# dim_gen_baseline -a sm3 /opt/dim/demo/dim_test_demo -o /etc/dim/digest_list/test.hash +``` + +**步骤3**:触发基线 + +```sh +# echo 1 > /sys/kernel/security/dim/baseline_init +# echo 1 > /sys/kernel/security/dim/monitor_baseline +``` + +**步骤4**:查看度量日志,每条日志都显示了对应的哈希算法 + +```sh +# cat /sys/kernel/security/dim/ascii_runtime_measurements +0 585a64feea8dd1ec415d4e67c33633b97abb9f88e6732c8a039064351d24eed6 sm3:ca84504c02bef360ec77f3280552c006ce387ebb09b49b316d1a0b7f43039142 /opt/dim/demo/dim_test_demo [static baseline] +# cat /sys/kernel/security/dim/monitor_ascii_runtime_measurements +0 e6a40553499d4cbf0501f32cabcad8d872416ca12855a389215b2509af76e60b sm3:47a1dae98182e9d7fa489671f20c3542e0e154d3ce941440cdd4a1e4eee8f39f dim_core.text [dynamic baseline] +0 2c862bb477b342e9ac7d4dd03b6e6705c19e0835efc15da38aafba110b41b3d1 sm3:a4d31d5f4d5f08458717b520941c2aefa0b72dc8640a33ee30c26a9dab74eae9 dim_core.data [dynamic baseline] +``` + +### 配置自动周期度量 + +**前置条件**: + +- 度量策略配置完成; + +**方式1**:加载dim_core模块,配置定时度量间隔,此处配置为1分钟 + +```sh +modprobe dim_core measure_interval=1 +``` + +在模块加载完成后,自动触发动态基线流程,后续每隔1分钟触发一次动态度量。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 此时不能配置dim_core度量自身代码段的度量策略,否则会产生误报。 +> 同时需要提前配置/etc/dim/policy,否则指定measure_interval=1加载模块会失败 + +**方式2**:加载dim_core模块后,也可通过内核模块接口配置定时度量间隔,此处配置为1分钟 + +```sh +modprobe dim_core +echo 1 > /sys/kernel/security/dim/interval +``` + +此时不会立刻触发度量,1分钟后会触发动态基线或动态度量,后续每隔1分钟触发一次动态度量。 + +### 配置度量调度时间 + +**前置条件**: + +- 度量策略配置完成; + +加载dim_core模块,配置定时度量调度时间,此处配置为10毫秒: + +```sh +modprobe dim_core measure_schedule=10 +``` + +触发动态基线或动态度量时,dim_core每度量一个进程,就会调度让出CPU 10毫秒时间。 diff --git a/docs/en/25.03/Server/Security/TrustedComputing/IMA.md b/docs/en/25.03/Server/Security/TrustedComputing/IMA.md new file mode 100644 index 0000000000000000000000000000000000000000..2320166d135370a05231f41c1be1e30ad998e825 --- /dev/null +++ b/docs/en/25.03/Server/Security/TrustedComputing/IMA.md @@ -0,0 +1,1132 @@ +# 内核完整性度量(IMA) + +## 概述 + +### IMA介绍 + +IMA,全称 Integrity Measurement Architecture(完整性度量架构),是内核中的一个子系统,能够基于自定义策略对通过`execve()`、`mmap()`和`open()`等系统调用访问的文件进行度量,度量结果可被用于**本地/远程证明**,或者和已有的参考值比较以**控制对文件的访问**。 + +IMA的运行模式主要包含以下两种: + +- 度量(measure):提供了对文件的完整性状态观测功能,访问受保护文件时,会往度量日志(位于内核内存中)增加度量记录。如果系统包含TPM芯片,还可以往TPM芯片PCR寄存器中扩展度量摘要值,以保证度量信息不被篡改。度量场景并不提供对文件访问的控制,它记录的文件信息可传递给上层应用软件,进一步用于远程证明。 +- 评估(appraise):提供了对文件的完整性校验功能,从根本上杜绝了未知的/被篡改的文件的访问。通过哈希、签名、HMAC等密码学技术对文件的内容进行完整性验证,如果验证失败,则不允许任何进程对该文件进行访问。该特性为系统提供了底层韧性设计,在系统被破坏时牺牲一部分功能(被篡改的部分文件),避免攻击造成的影响进一步升级。 + +可以看到,IMA度量模式相当于一个“只记录不干涉”的观察员,IMA评估模式相当于一位严格的保安人员,它的职责是拒绝对所有“人证不一”的文件访问。 + +### EVM介绍 + +EVM,全称 Extended Verification Module(扩展验证模块),是对IMA功能的扩展,在通过IMA实现对于文件内容的完整性保护的基础上,使用EVM可以更进一步地实现对于文件扩展属性(如UID、security.ima 、security.selinux等属性)的保护。 + +### IMA摘要列表介绍 + +IMA Digest Lists(IMA摘要列表)是openEuler对内核原生完整性保护机制的增强,旨在对原生的IMA/EVM机制的以下痛点进行优化: + +**TPM扩展导致文件访问性能下降:** + +IMA度量模式下,每次触发度量都需要访问TPM芯片,TPM属于低速芯片,通常采用几十MHz时钟频率的SPI协议与CPU通信,导致系统调用性能下降: + +![](./figures/ima_tpm.png) + +**非对称运算导致文件访问性能下降:** + +IMA评估模式下,需要使用签名机制保护不可变文件,每次触发文件校验都需要进行签名验证,而非对称运算相对复杂 ,同样导致系统调用性能下降: + +![](./figures/ima_sig_verify.png) + +**复杂的部署方式导致效率和安全性下降:** + +IMA评估模式下,需要通过fix模式进行部署,即系统首先需要进入fix模式进行IMA/EVM扩展属性标记,然后再切换为校验模式启动。同时在受保护的文件升级时,需要重启进入fix模式,完成文件和扩展属性更新。一方面降低了部署效率,另一方面需要在运行环境中访问密钥,降低了安全性: + +![](./figures/ima_priv_key.png) + +IMA摘要列表旨在通过一个哈希列表文件管理一系列文件的基准摘要值,即将若干文件(如一个软件包中的所有可执行文件)的基准摘要值汇总到单个文件中进行管理。基准摘要值可包含文件内容摘要(对应IMA模式)和文件扩展属性摘要(对应EVM模式),这个文件就是IMA摘要列表文件。 + +![](./figures/ima_digest_list_pkg.png) + +开启IMA摘要列表功能后,内核维护一个哈希白名单池,用于存放导入的IMA摘要列表文件中的摘要值,并通过securityfs对外提供IMA摘要列表文件的导入/删除/查询等接口。 + +在度量模式下,导入内核的摘要列表文件需要进行度量和TPM扩展才可添加至白名单池,后续如果度量的目标文件的摘要值和白名单池匹配,则不进行额外的度量日志记录以及TPM扩展;在评估模式下,导入内核的摘要列表文件需要通过签名验证才可添加至白名单池,后续将访问的目标文件的摘要值和白名单池中的摘要值进行匹配即可判断评估结果。 + +![](./figures/ima_digest_list_flow.png) + +相比Linux原生IMA/EVM机制,IMA摘要列表扩展从安全性、性能、易用性三个方面进行了改良,以实现更好的落地效果: + +- 安全性:IMA摘要列表可以随软件包一起发布,软件包安装时同步导入摘要列表,确保了基准值来自于软件发行商(如openEuler社区),避免在运行环境生成基准值的流程,实现了完整的信任链。 +- 性能:IMA摘要列表机制以摘要列表为单位进行度量/校验,降低TPM访问和非对称运算频率为1/n(n为平均单个摘要列表管理的文件哈希数量),可一定程度提升系统调用性能和系统启动性能。 +- 易用性:IMA摘要列表机制可以实现“开箱即用”,即完成系统安装后直接进入评估模式,且允许在评估模式下直接安装/升级软件包,而无需进入fix模式进行文件标记,从而实现快速部署和平滑升级。 + +需要注意的是,IMA摘要列表相比原生IMA/EVM,将度量/评估的基准值在内核内存中进行维护,也引入了一个假设,即内核内存不可被未授权篡改,这就使得IMA摘要列表也依赖于其他安全机制(如内核模块安全启动和内存动态度量等)以保护内核内存的完整性。 + +但无论社区原生IMA机制还是IMA摘要列表扩展,都只是系统安全链中的一环,无法孤立地保证系统的安全性,安全自始至终都是一个构建纵深防御的系统工程。 + +## 接口说明 + +### 内核启动参数说明 + +openEuler IMA/EVM机制提供的内核启动参数及说明如下: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
参数名称取值功能
ima_appraiseenforce-evmIMA评估强制校验模式(EVM开启)
log-evmIMA评估日志模式(EVM开启)
enforceIMA评估强制校验模式
logIMA评估日志模式
off关闭IMA评估
ima_appraise_digest_listdigest基于摘要列表进行IMA+EVM评估(比较文件内容和扩展属性)
digest-nometadata基于摘要列表进行IMA评估(只比较文件内容)
evmx509直接开启基于可移植签名的EVM(无论EVM证书是否加载)
complete启动后不允许通过securityfs接口修改EVM模式
allow_metadata_writes允许修改文件元数据,EVM不做拦截
ima_hashsha256/sha1/...声明IMA度量哈希算法
ima_templateima声明IMA度量模板(d|n)
ima-ng声明IMA度量模板(d-ng|n-ng),默认使用该模板
ima-sig声明IMA度量模板(d-ng|n-ng|sig)
ima_policyexec_tcb度量所有执行、映射方式访问的文件,以及加载的内核模块、固件、内核等文件
tcb在exec_tcb策略的基础上,额外度量以uid=0或euid=0身份访问的文件
secure_boot评估所有加载的内核模块、固件、内核等文件,并指定使用IMA签名模式
appraise_exec_tcb在secure_boot策略的基础上,额外评估所有执行、映射方式访问的文件
appraise_tcb评估访问的所有属主为0的文件
appraise_exec_immutable与appraise_exec_tcb策略配合使用,可执行文件的扩展属性不可变
ima_digest_list_pcr10在PCR 10中扩展基于摘要列表的IMA度量结果,禁用原生IMA度量
11在PCR 11中扩展基于摘要列表的IMA度量结果,禁用原生IMA度量
+11在PCR 11中扩展基于摘要列表的IMA度量结果,在PCR 10中扩展原生IMA度量结果
ima_digest_db_sizenn[M]设置内核摘要列表上限(0M~64M),不做配置的情况下默认为16MB(不做配置指的是不写该参数,但注意不能将值留空,如ima_digest_db_size=)
ima_capacity-1~2147483647设置内核度量日志条数上限,不做配置的情况下默认为100000条,配置-1表示无上限
initramtmpfs在initrd中支持tmpfs,以携带文件扩展属性
+ +根据用户实际场景诉求,建议采取如下参数组合: + +**1) 原生IMA度量:** + +```sh +# 原生IMA度量+自定义策略 +无需配置,默认开启 +# 原生IMA度量+TCB默认策略 +ima_policy="tcb" +``` + +**2) 基于摘要列表的IMA度量:** + +```sh +# 摘要列表IMA度量+自定义策略 +ima_digest_list_pcr=11 ima_template=ima-ng initramtmpfs +# 摘要列表IMA度量+默认策略 +ima_digest_list_pcr=11 ima_template=ima-ng ima_policy="exec_tcb" initramtmpfs +``` + +**3) 基于摘要列表的IMA评估,只保护文件内容:** + +```sh +# IMA评估+日志模式 +ima_appraise=log ima_appraise_digest_list=digest-nometadata ima_policy="appraise_exec_tcb" initramtmpfs +# IMA评估+强制校验模式 +ima_appraise=enforce ima_appraise_digest_list=digest-nometadata ima_policy="appraise_exec_tcb" initramtmpfs +``` + +**4) 基于摘要列表的IMA评估,保护文件内容和扩展属性:** + +```sh +# IMA评估+日志模式 +ima_appraise=log-evm ima_appraise_digest_list=digest ima_policy="appraise_exec_tcb|appraise_exec_immutable" initramtmpfs evm=x509 evm=complete +# IMA评估+强制校验模式 +ima_appraise=enforce-evm ima_appraise_digest_list=digest ima_policy="appraise_exec_tcb|appraise_exec_immutable" initramtmpfs evm=x509 evm=complete +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 以上四种参数都可以单独配置使用,但只有基于摘要列表的度量和评估模式可以组合使用,即2)和3)搭配或2)和4)搭配。 + +### securityfs接口说明 + +openEuler IMA提供的securityfs接口位于`/sys/kernel/security`目录下,接口名及说明如下: + +| 路径 | 权限 | 说明 | +| :----------------------------- | :--- | :-------------------------------------- | +| ima/policy | 600 | IMA策略查询/导入接口 | +| ima/ascii_runtime_measurement | 440 | 查询IMA度量日志,以字符串形式输出 | +| ima/binary_runtime_measurement | 440 | 查询IMA度量日志,以二进制形式输出 | +| ima/runtime_measurement_count | 440 | 查询IMA度量日志条数 | +| ima/violations | 440 | 查询异常IMA度量日志数量 | +| ima/digests_count | 440 | 显示系统哈希表中的总摘要数量(IMA+EVM) | +| ima/digest_list_data | 200 | 摘要列表新增接口 | +| ima/digest_list_data_del | 200 | 摘要列表删除接口 | +| evm | 660 | 查询/设置EVM模式 | + +其中,`/sys/kernel/security/evm` 的接口的取值有以下三种: + +- 0:EVM 未初始化; +- 1:使用 HMAC(对称加密)方式校验扩展属性完整性; +- 2:使用公钥验签(非对称加密)方式校验扩展属性完整性; +- 6:关闭扩展属性完整性校验。 + +### 摘要列表管理工具说明 + +digest-list-tools软件包提供IMA摘要列表文件生成和管理的工具,主要包含如下几个命令行工具: + +#### gen_digest_lists工具 + +用户可通过调用gen_digest_lists命令行工具生成摘要列表。命令参数定义如下: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
参数名称取值功能
-d<path>指定生成摘要列表文件存放的位置,需为有效目录。
-fcompact指定生成摘要列表文件的格式,当前仅支持compact格式。
-i<option arg>:<option value>指定生成摘要列表的目标文件范围,具体参数定义如下。
I:<path>指定需要生成摘要列表的文件绝对路径,如指定目录,则会执行递归生成。
E:<path>指定需要排除的路径或目录。
F:<path>指定路径或目录,为该路径或目录下所有文件生成摘要列表(同时指定e:参数时,忽略e:选项的筛选效果)。
e:仅对可执行文件生成摘要列表。
l:policy从系统SELinux策略匹配文件安全上下文,而不是直接从文件扩展属性中读取安全上下文。
i:当生成metadata类型的摘要列表时,被计算的扩展属性信息包含文件的摘要值(必须指定)。
M:允许显式指定文件的扩展属性信息(需要结合rpmbuild命令使用)。
u:将“L:”参数所指定的列表文件名作为生成摘要列表的文件名(需要结合rpmbuild命令使用)。
L:<path>指定列表文件的路径,列表文件中包含需要生成摘要列表的信息数据(需要结合rpmbuild命令使用)。
-oadd指定生成摘要列表的操作,当前仅支持add操作,即将摘要列表添加到文件中。
-p-1指定将摘要列表写入文件中的位置,当前仅支持指定-1。
-tfile只针对文件内容生成摘要列表。
metadata针对对文件的内容和扩展属性分别生成摘要列表。
-TNA不添加该参数,则生成摘要列表文件,添加该参数则生成TLV摘要列表文件。
-A<path>指定相对根目录,将文件路径截去指定的前缀进行路径匹配和SELinux标签匹配。
-mimmutable指定生成摘要列表文件的modifiers属性,当前仅支持指定immutable。摘要列表在enforce/enforece-evm模式下,摘要列表只能以只读模式打开。
-hNA打印帮助信息。
+ +**参考使用示例:** + +- 场景1:为单个文件生成摘要列表/TLV摘要列表。 + + ```sh + gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/ls -d ./ -i i: gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/ls -d ./ -i i: -T + ``` + +- 场景2: 为单个文件生成摘要列表/TLV摘要列表,并指定相对根目录。 + + ```sh + gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/ls -A /usr/ -d ./ -i i: gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/ls -A /usr/ -d ./ -i i: -T + ``` + +- 场景3:为目录下的文件递归生成摘要列表/TLV摘要列表。 + + ```sh + gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/ -d ./ -i i: + gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/ -d ./ -i i: -T + ``` + +- 场景4:为目录下的可执行文件递归生成摘要列表/TLV摘要列表。 + + ```sh + gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/ -d ./ -i i: -i e:gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/ -d ./ -i i: -i e: -T + ``` + +- 场景5:为目录下的文件递归生成摘要列表/TLV摘要列表,排除部分子目录。 + + ```sh + gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/ -d ./ -i i: -i E:/usr/bin/gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/ -d ./ -i i: -i E:/usr/bin/ -T + ``` + +- 场景6:rpmbuild回调脚本中,通过读取rpmbuild传入的列表文件生成摘要列表。 + + ```sh + gen_digest_lists -i M: -t metadata -f compact -d $DIGEST_LIST_DIR -i l:policy \ + -i i: -o add -p -1 -m immutable -i L:$BIN_PKG_FILES -i u: \ + -A $RPM_BUILD_ROOT -i e: \ + -i E:/usr/src \ + -i E:/boot/efi \ + -i F:/lib \ + -i F:/usr/lib \ + -i F:/lib64 \ + -i F:/usr/lib64 \ + -i F:/lib/modules \ + -i F:/usr/lib/modules \ + -i F:/lib/firmware \ + -i F:/usr/lib/firmware + + gen_digest_lists -i M: -t metadata -f compact -d $DIGEST_LIST_DIR.tlv \ + -i l:policy -i i: -o add -p -1 -m immutable -i L:$BIN_PKG_FILES -i u: \ + -T -A $RPM_BUILD_ROOT -i e: \ + -i E:/usr/src \ + -i E:/boot/efi \ + -i F:/lib \ + -i F:/usr/lib \ + -i F:/lib64 \ + -i F:/usr/lib64 \ + -i F:/lib/modules \ + -i F:/usr/lib/modules \ + -i F:/lib/firmware \ + -i F:/usr/lib/firmware + ``` + +#### manage_digest_lists工具 + +manage_digest_lists命令行工具主要用于将二进制格式的TLV摘要列表文件解析转换为可读的文本形式。命令参数定义如下: + +| 参数名称 | 取值 | 功能 | +| -------- | ---------- | ----------------------------------------------------------- | +| -d | \ | 指定TLV摘要列表文件存放的目录。 | +| -f | \ | 指定TLV摘要列表文件名。 | +| -p | dump | 指定操作类型,当前仅支持dump,表示解析打印TLV摘要列表操作。 | +| -v | NA | 打印详细信息。 | +| -h | NA | 打印帮助信息。 | + +**参考使用示例:** + +查看TLV摘要列表信息: + +```sh +manage_digest_lists -p dump -d /etc/ima/digest_lists.tlv/ +``` + +## 文件格式说明 + +### IMA策略文件语法说明 + +IMA策略文件为文本文件,一个文件中可包含若干条按照换行符`\n`分隔的规则语句,每条规则语句都必须以 action 关键字代表的**动作**开头,后接**筛选条件**: + +```sh + <筛选条件1> [筛选条件2] [筛选条件3]... +``` + +action表示该条策略具体的动作,一条策略只能选一个 action,具体的action见后表(实际书写时**可忽略 action 字样**,例如直接书写 dont_measure,不需要写成 action=dont_measure): + +筛选条件支持如下几种类型: + +- func:表示被度量或评估的文件类型,常和 mask 匹配使用,一条策略只能选一个 func。 + - FILE_CHECK 只能同 MAY_EXEC、MAY_WRITE、MAY_READ 匹配使用。 + - MODULE_CHECK、MMAP_CHECK、BPRM_CHECK 只能同 MAY_EXEC 匹配使用。 + - 匹配关系以外的组合不会产生效果。 + +- mask:表示文件在做什么操作时将被度量或评估,一条策略只能选一个 mask。 + +- fsmagic:表示文件系统类型的十六进制魔数,定义在 `/usr/include/linux/magic.h` 文件中(默认情况下度量所有文件系统,除非使用 dont_measure/dont_appraise 标记不度量某文件系统)。 + +- fsuuid:表示系统设备 uuid 的 16 位的十六进制字符串。 + +- objtype:表示文件安全类型,一条策略只能选一个文件类型,objtype 相比 func 而言,划分的粒度更细,比如 obj_type=nova_log_t 表示SELinux类型为 nova_log_t 的文件。 + +- uid:表示哪个用户(用用户 id 表示)对文件进行操作,一条策略只能选一个 uid。 + +- fowner:表示文件的属主(用用户 id 表示)是谁,一条策略只能选一个 fowner。 + +关键字的具体取值及说明如下: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
关键字说明
actionmeasure开启IMA度量
dont_measure禁用IMA度量
appraise开启IMA评估
dont_appraise禁用IMA评估
audit开启审计
funcFILE_CHECK将要被打开的文件
MODULE_CHECK将要被装载的内核模块文件
MMAP_CHECK将要被映射到进程内存空间的动态库文件
BRPM_CHECK将要被执行的文件(不含通过 /bin/hash 等程序打开的脚本文件)
POLICY_CHECK将要被导入的IMA策略文件
FIRMWARE_CHECK将要被加载到内存中的固件
DIGEST_LIST_CHECK将要被加载到内核中的摘要列表文件
KEXEC_KERNEL_CHECK将要切换的 kexec 内核
maskMAY_EXEC执行文件
MAY_WRITE写文件
MAY_READ读文件
MAY_APPEND扩展文件属性
fsmagicfsmagic=xxx表示文件系统类型的十六进制魔数
fsuuidfsuuid=xxx表示系统设备 uuid 的 16 位的十六进制字符串
fownerfowner=xxx文件属主的用户 id
uiduid=xxx操作文件的用户 id
obj_typeobj_type=xxx_t表示文件的类型(基于 SELinux 标签)
pcrpcr=选择 TPM 中用于扩展度量值的 PCR(默认为 10)
appraise_typeimasig基于签名进行IMA评估
meta_immutable基于签名进行文件扩展属性的评估(支持摘要列表)
+ +## 使用说明 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 原生IMA/EVM为Linux开源特性,本章节仅简单介绍基本使用方式,其他资料可参考开源WIKI: +> + +### 原生IMA使用说明 + +#### IMA度量模式 + +用户需要配置度量策略,开启IMA度量功能,具体步骤如下: + +**步骤1:** 用户可通过配置启动参数或手动配置的方式,指定度量策略。通过启动参数配置IMA策略的示例如下: + +```sh +ima_policy="tcb" +``` + +手动配置IMA策略的示例如下: + +```sh +echo "measure func=BPRM_CHECK" > /sys/kernel/security/ima/policy +``` + +**步骤2:** 重启系统,用户可实时检查度量日志获取当前的度量情况: + +```sh +cat /sys/kernel/security/ima/ascii_runtime_measurements +``` + +#### IMA评估模式 + +用户需要首先进入fix模式,完成文件的IMA标记后,再开启log或enforce模式。具体步骤如下: + +**步骤1:** 配置启动参数,重启后进入fix模式: + +```sh +ima_appraise=fix ima_policy=appraise_tcb +``` + +**步骤2:** 为所有需要评估的文件生成IMA扩展属性: + +对于不可变文件(如二进制程序文件)可以使用签名模式,将文件摘要值的签名写入IMA扩展属性中。举例如下(其中`/path/to/ima.key`指的是和IMA证书匹配的签名私钥): + +```sh +find /usr/bin -fstype ext4 -type f -executable -uid 0 -exec evmctl -a sha256 ima_sign --key /path/to/ima.key '{}' \; +``` + +对于可变文件(如数据文件)可以使用哈希模式,将文件的摘要值写入IMA扩展属性中。IMA支持自动标记机制,即在fix模式下仅需触发文件访问,即可自动生成IMA扩展属性: + +```sh +find / -fstype ext4 -type f -uid 0 -exec dd if='{}' of=/dev/null count=0 status=none \; +``` + +可通过如下命令检查文件是否被成功标记了IMA扩展属性(security.ima): + +```sh +getfattr -m - -d /sbin/init +``` + +**步骤3:** 配置启动参数,修改IMA评估为log或enforce模式后,重启系统: + +```sh +ima_appraise=enforce ima_policy=appraise_tcb +``` + +### IMA摘要列表使用说明 + +#### 前置条件 + +IMA摘要列表特性使用前,用户需安装`ima-evm-utils`和`digest-list-tools`软件包: + +```sh +yum install ima-evm-utils digest-list-tools +``` + +#### 机制介绍 + +##### 摘要列表文件 + +在安装openEuler发布的RPM包后,默认会在`/etc/ima`目录下生成摘要列表文件。根据文件名的不同,存在如下几种文件: + +**/etc/ima/digest_lists/0-metadata_list-compact-\** + +为IMA摘要列表文件,通过`gen_digest_lists`命令生成(生成方法详见[gen_digest_lists工具](#gen_digest_list工具)),该文件为二进制格式,包含header信息以及一连串SHA256哈希值,分别代表合法的文件内容摘要值和文件扩展属性摘要值。该文件被度量或评估后,最终被导入内核,并以该文件中的白名单摘要值为基准进行IMA摘要列表度量或评估。 + +**/etc/ima/digest_lists/0-metadata_list-rpm-\** + +为RPM摘要列表文件,**实际为RPM包的头信息**。RPM包安装后,如果IMA摘要列表文件不包含签名,则会把RPM头信息写入该文件中,并将头信息的签名写入`security.ima`扩展属性中。这样通过签名可验证RPM头信息的真实性,由于RPM头信息又包含了摘要列表文件的摘要值,则可实现摘要列表的间接验证。 + +**/etc/ima/digest_lists/0-parser_list-compact-libexec** + +为IMA PARSER摘要列表文件,存放`/usr/libexec/rpm_parser`文件的摘要值。该文件用于实现RPM摘要列表->IMA摘要列表的信任链,内核IMA摘要列表机制会对该文件执行后产生的进程进行特殊校验,如果确定是`rpm_parser`程序,则会信任其导入的所有摘要列表而无需校验签名。 + +**/etc/ima/digest_lists.sig/0-metadata_list-compact-\.sig** + +为IMA摘要列表的签名文件,若RPM包中包含此文件,则在RPM包安装阶段,会将该文件的内容写入对应的RPM摘要列表文件的`security.ima`扩展属性,从而在IMA摘要列表导入内核阶段进行签名验证。 + +**/etc/ima/digest_lists.tlv/0-metadata_list-compact_tlv-\** + +为TLV摘要列表文件,通常在对目标文件生成IMA摘要列表文件时一并生成,存放目标文件的完整性信息(文件内容摘要值、文件扩展属性等)。该文件的功能是协助用户查询/恢复目标文件的完整性信息。 + +##### 摘要列表文件签名方式 + +在IMA摘要列表评估模式下,IMA摘要列表文件需要经过签名验证才可导入内核,并用于后续的文件白名单匹配。IMA摘要列表文件支持如下几种签名方式: + +**1) IMA扩展属性签名** + +即原生的IMA签名机制,将签名信息按照一定格式,存放在`security.ima`扩展属性中。可通过`evmctl`命令生成并添加: + +```sh +evmctl ima_sign --key /path/to/ima.key -a sha256 +``` + +也可添加`-f`参数,将签名信息和头信息存入独立的文件中: + +```sh +evmctl ima_sign -f --key /path/to/ima.key -a sha256 +``` + +在开启IMA摘要列表评估模式下,可直接将摘要列表文件路径写入内核接口,实现摘要列表的导入/删除。该过程会自动触发评估,基于`security.ima`扩展属性完成对摘要列表文件内容的签名验证: + +```sh +# 导入IMA摘要列表文件 +echo > /sys/kernel/security/ima/digest_list_data +# 删除IMA摘要列表文件 +echo > /sys/kernel/security/ima/digest_list_data_del +``` + +**2) IMA摘要列表追加签名(openEuler 24.03 LTS版本默认)** + +openEuler 24.03 LTS版本开始支持IMA专用签名密钥,并采用CMS签名。由于签名信息包含证书链,可能由于长度超出限制而无法写入文件的`security.ima`扩展属性中,因此采用类似内核模块的追加签名的方式: + + + +其签名机制为: + +(1) 将CMS签名信息追加到IMA摘要列表文件末尾; + +(2) 填充结构体并添加到签名信息末尾,结构体定义如下: + + ```sh + struct module_signature { + u8 algo; /* Public-key crypto algorithm [0] */ + u8 hash; /* Digest algorithm [0] */ + u8 id_type; /* Key identifier type [PKEY_ID_PKCS7] */ + u8 signer_len; /* Length of signer's name [0] */ + u8 key_id_len; /* Length of key identifier [0] */ + u8 __pad[3]; + __be32 sig_len; /* Length of signature data */ + }; + ``` + +(3) 添加魔鬼字符串`"~Module signature appended~\n"` + +此步骤的参考脚本如下: + +```shell +#!/bin/bash +DIGEST_FILE=$1 # IMA摘要列表文件路径 +SIG_FILE=$2 # IMA摘要列表签名信息保存路径 +OUT=$3 #完成签名信息添加后的摘要列表文件输出路径 + +cat $DIGEST_FILE $SIG_FILE > $OUT +echo -n -e "\x00\x00\x02\x00\x00\x00\x00\x00" >> $OUT +echo -n -e $(printf "%08x" "$(ls -l $SIG_FILE | awk '{print $5}')") | xxd -r -ps >> $OUT +echo -n "~Module signature appended~" >> $OUT +echo -n -e "\x0a" >> $OUT +``` + +**3) 复用RPM签名(openEuler 22.03 LTS版本默认)** + +openEuler 22.03 LTS版本支持复用RPM签名机制实现IMA摘要列表文件的签名。旨在解决版本无专用IMA签名密钥的问题。用户无需感知该签名流程,当RPM包中含有IMA摘要列表文件,而不包含IMA摘要列表的签名文件时,会自动使用该签名机制。其核心原理是通过RPM包的头信息实现对IMA摘要列表的验证。 + +对于openEuler发布的RPM包,每一个包文件可以包含两部分: + +- **RPM头信息:** 存放RPM包属性字段,如包名、文件摘要值列表等,通过RPM头签名保证其完整性; +- **RPM文件:** 实际安装至系统中的文件,也包括构建阶段生成的IMA摘要列表文件。 + + + +在RPM包安装阶段,如果RPM进程检测到包中的摘要列表文件不包含签名,则在`/etc/ima`目录下创建一个RPM摘要列表文件,将RPM头信息写入文件内容,将RPM头签名写入文件的`security.ima`扩展属性中。后续可通过RPM摘要列表间接实现IMA摘要列表的验证和导入。 + +##### IMA摘要列表导入 + +在开启IMA度量模式下,导入IMA摘要列表文件无需经过签名验证,可直接将路径写入内核接口,实现摘要列表的导入/删除: + +```sh +# 导入IMA摘要列表文件 +echo > /sys/kernel/security/ima/digest_list_data +# 删除IMA摘要列表文件 +echo > /sys/kernel/security/ima/digest_list_data_del +``` + +在开启IMA评估模式下,导入摘要列表必须通过签名验证。根据签名方式不同,可分为两种导入方式。 + +**直接导入方式** + +对于已包含签名信息的IMA摘要列表文件(IMA扩展属性签名或IMA摘要列表追加签名),可直接将路径写入内核接口,实现摘要列表的导入/删除。该过程会自动触发评估,基于`security.ima`扩展属性完成对摘要列表文件内容的签名验证: + +```sh +# 导入IMA摘要列表文件 +echo > /sys/kernel/security/ima/digest_list_data +# 删除IMA摘要列表文件 +echo > /sys/kernel/security/ima/digest_list_data_del +``` + +**调用`upload_digest_lists`导入方式** + +对于复用RPM签名的IMA摘要列表文件,需要调用`upload_digest_lists`命令实现导入。具体命令如下(注意指定的路径为对应的RPM摘要列表): + +```sh +# 导入IMA摘要列表文件 +upload_digest_lists add +# 删除IMA摘要列表文件 +upload_digest_lists del +``` + +该流程相对复杂,需要满足以下前置条件: + +1) 系统已导入openEuler发布的`digest_list_tools`软件包中的摘要列表(包含IMA摘要列表和IMA PARSER摘要列表); + +2) 已配置对应用程序执行的IMA评估策略(BPRM_CHECK策略)。 + +#### 操作指导 + +##### RPM构建自动生成摘要列表 + +openEuler RPM工具链支持`%__brp_digest_list`宏定义,配置格式如下: + +```sh +%__brp_digest_list /usr/lib/rpm/brp-digest-list %{buildroot} +``` + +当配置了该宏定义后,当用户调用`rpmbuild`命令进行软件包构建时,在RPM打包阶段会调用`/usr/lib/rpm/brp-digest-list`脚本进行摘要列表的生成和签名等流程。openEuler默认针对可执行程序、动态库、内核模块等关键文件生成摘要列表。用户也可以通过修改脚本,自行配置生成摘要列表的范围和指定签名密钥。如下示例使用用户自定义的签名密钥`/path/to/ima.key`进行摘要列表签名。 + +```sh +...... (line 66) +DIGEST_LIST_TLV_PATH="$DIGEST_LIST_DIR.tlv/0-metadata_list-compact_tlv-$(basename $BIN_PKG_FILES)" +[ -f $DIGEST_LIST_TLV_PATH ] || exit 0 + +chmod 644 $DIGEST_LIST_TLV_PATH +echo $DIGEST_LIST_TLV_PATH + +evmctl ima_sign -f --key /path/to/ima.key -a sha256 $DIGEST_LIST_PATH &> /dev/null +chmod 400 $DIGEST_LIST_PATH.sig +mkdir -p $DIGEST_LIST_DIR.sig +mv $DIGEST_LIST_PATH.sig $DIGEST_LIST_DIR.sig +echo $DIGEST_LIST_DIR.sig/0-metadata_list-compact-$(basename $BIN_PKG_FILES).sig +``` + +##### IMA摘要列表度量 + +用户可通过如下功能开启IMA摘要列表度量: + +**步骤1:** 用户需要配置启动参数度量策略,开启IMA度量功能,具体步骤同**原生IMA度量**,不同的是需要单独配置度量所使用的TPM PCR寄存器,启动参数示例如下: + +```sh +ima_policy=exec_tcb ima_digest_list_pcr=11 +``` + +**步骤2:** 用户导入IMA摘要列表,以`bash`软件包的摘要列表为例: + +```sh +echo /etc/ima/digest_lists/0-metadata_list-compact-bash-5.1.8-6.oe2203sp1.x86_64 > /sys/kernel/security/ima/digest_list_data +``` + +可查询到IMA摘要列表的度量日志: + +```sh +cat /sys/kernel/security/ima/ascii_runtime_measurements +``` + +导入IMA摘要列表后,如果后续度量的文件摘要值包含在IMA摘要列表中,则不会额外记录度量日志。 + +##### IMA摘要列表评估 + +###### 默认策略启动场景 + +用户可在启动参数中配置`ima_policy`参数指定IMA默认策略,则在内核启动阶段,IMA初始化完成后立即启用默认策略进行评估。用户可通过如下功能开启IMA摘要列表评估: + +**步骤1:** 执行`dracut`命令将摘要列表文件写入initrd: + +```sh +dracut -f -e xattr +``` + +**步骤2:** 配置启动参数和IMA策略,典型的配置如下: + +```sh +# 基于摘要列表的IMA评估log/enforce模式,只保护文件内容,配置默认策略为appraise_exec_tcb +ima_appraise=log ima_appraise_digest_list=digest-nometadata ima_policy="appraise_exec_tcb" initramtmpfs module.sig_enforce +ima_appraise=enforce ima_appraise_digest_list=digest-nometadata ima_policy="appraise_exec_tcb" initramtmpfs module.sig_enforce +# 基于摘要列表的IMA评估log/enforce模式,保护文件内容和扩展属性,配置默认策略为appraise_exec_tcb+appraise_exec_immutable +ima_appraise=log-evm ima_appraise_digest_list=digest ima_policy="appraise_exec_tcb|appraise_exec_immutable" initramtmpfs evm=x509 evm=complete module.sig_enforce +ima_appraise=enforce-evm ima_appraise_digest_list=digest ima_policy="appraise_exec_tcb|appraise_exec_immutable" initramtmpfs evm=x509 evm=complete module.sig_enforce +``` + +重启系统即可开启IMA摘要列表评估功能,启动过程中自动完成IMA策略生效和IMA摘要列表文件导入。 + +###### 无默认策略启动场景 + +用户可在启动参数中不配置`ima_policy`参数,代表系统启动阶段无默认策略,IMA评估机制等待用户导入策略后生效启用。 + +**步骤1:** 配置启动参数,典型的配置如下: + +```sh +# 基于摘要列表的IMA评估log/enforce模式,只保护文件内容,无默认策略 +ima_appraise=log ima_appraise_digest_list=digest-nometadata initramtmpfs +ima_appraise=enforce ima_appraise_digest_list=digest-nometadata initramtmpfs +# 基于摘要列表的IMA评估log/enforce模式,保护文件内容和扩展属性,无默认策略 +ima_appraise=log-evm ima_appraise_digest_list=digest initramtmpfs evm=x509 evm=complete +ima_appraise=enforce-evm ima_appraise_digest_list=digest initramtmpfs evm=x509 evm=complete +``` + +重启系统,此时由于系统无策略,IMA评估并不生效。 + +**步骤2:** 导入IMA策略,将策略文件的全路径写入内核接口: + +```sh +echo /path/to/policy > /sys/kernel/security/ima/policy +``` + +策略中需要包含一些固定规则,用户可参考如下策略模板: +openEuler 22.03 LTS版本的策略模板如下(复用RPM签名场景): + +```sh +# 不评估securityfs文件系统的访问行为 +dont_appraise fsmagic=0x73636673 +# 其他用户自定义的dont_appraise规则 +...... +# 评估导入的IMA摘要列表文件 +appraise func=DIGEST_LIST_CHECK appraise_type=imasig +# 评估/usr/libexec/rpm_parser进程打开的所有文件 +appraise parser appraise_type=imasig +# 评估执行的应用程序(触发对/usr/libexec/rpm_parser执行的评估,也可以新增其他限制条件,如SELinux标签等) +appraise func=BPRM_CHECK appraise_type=imasig +# 其他用户自定义的appraise规则 +...... +``` + +openEuler 24.03 LTS版本的策略模板如下(IMA扩展属性签名或追加签名场景): + +```sh +# 用户自定义的dont_appraise规则 +...... +# 评估导入的IMA摘要列表文件 +appraise func=DIGEST_LIST_CHECK appraise_type=imasig|modsig +# 其他用户自定义的appraise规则 +...... +``` + +**步骤3:** 导入IMA摘要列表文件,对于不同签名方式的摘要列表,需要使用不同的导入方式。 + +openEuler 22.03 LTS的摘要列表导入方式如下(复用RPM签名的IMA摘要列表): + +```sh +# 导入digest_list_tools软件包的摘要列表 +echo /etc/ima/digest_lists/0-metadata_list-compact-digest-list-tools-0.3.95-13.x86_64 > /sys/kernel/security/ima/digest_list_data +echo /etc/ima/digest_lists/0-parser_list-compact-libexec > /sys/kernel/security/ima/digest_list_data +# 导入其他的RPM摘要列表 +upload_digest_lists add /etc/ima/digest_lists +# 检查导入的摘要列表条数 +cat /sys/kernel/security/ima/digests_count +``` + +openEuler 24.03 LTS的摘要列表导入方式如下(追加签名的IMA摘要列表): + +```sh +find /etc/ima/digest_lists -name "0-metadata_list-compact-*" -exec echo {} > /sys/kernel/security/ima/digest_list_data \; +``` + +##### 软件升级场景 + +开启IMA摘要列表功能后,对于覆盖在IMA保护范围内的文件,在升级更新场景需要同步更新摘要列表。对于openEuler发布的RPM包,在包安装、升级、卸载的同时,将自动完成RPM包中的摘要列表的添加、更新和删除,不需要用户手动操作。对于用户维护的非RPM格式的软件包,则需要手动完成摘要列表的导入。 + +##### 用户证书导入 + +用户可以通过导入自定义证书,从而针对非openEuler发布的软件进行度量或评估。openEuler IMA评估模式支持从如下两种密钥环中获取证书进行签名校验: + +- builtin_trusted_keys密钥环:内核编译时预置的根证书; +- ima密钥环:通过initrd中的/etc/keys/x509_ima.der导入,需要为builtin_trusted_keys密钥环中任意一本证书的子证书。 + +**将根证书导入builtin_trusted_keys密钥环的步骤如下:** + +**步骤1:** 生成根证书,以openssl命令为例: + +```sh +echo 'subjectKeyIdentifier=hash' > root.cfg +openssl genrsa -out root.key 4096 +openssl req -new -sha256 -key root.key -out root.csr -subj "/C=AA/ST=BB/O=CC/OU=DD/CN=openeuler test ca" +openssl x509 -req -days 3650 -extfile root.cfg -signkey root.key -in root.csr -out root.crt +openssl x509 -in root.crt -out root.der -outform DER +``` + +**步骤2:** 获取openEuler kernel源码,以最新的OLK-5.10分支为例: + +```sh +git clone https://gitee.com/openeuler/kernel.git -b OLK-5.10 +``` + +**步骤3:** 进入源码目录,并将根证书拷贝至目录下: + +```sh +cd kernel +cp /path/to/root.der . +``` + +修改config文件的CONFIG_SYSTEM_TRUSTED_KEYS选项: + +```sh +CONFIG_SYSTEM_TRUSTED_KEYS="./root.crt" +``` + +**步骤4:** 编译安装内核(步骤略,注意需要为内核模块生成摘要列表)。 + +**步骤5:** 重启后检查证书导入成功: + +```sh +keyctl show %:.builtin_trusted_keys +``` + +**将子证书导入ima密钥环的步骤如下,注意需要提前将根证书导入builtin_trusted_keys密钥环:** + +**步骤1:** 基于根证书生成子证书,以openssl命令为例: + +```sh +echo 'subjectKeyIdentifier=hash' > ima.cfg +echo 'authorityKeyIdentifier=keyid,issuer' >> ima.cfg +echo 'keyUsage=digitalSignature' >> ima.cfg +openssl genrsa -out ima.key 4096 +openssl req -new -sha256 -key ima.key -out ima.csr -subj "/C=AA/ST=BB/O=CC/OU=DD/CN=openeuler test ima" +openssl x509 -req -sha256 -CAcreateserial -CA root.crt -CAkey root.key -extfile ima.cfg -in ima.csr -out ima.crt +openssl x509 -outform DER -in ima.crt -out x509_ima.der +``` + +**步骤2:** 将IMA证书拷贝到/etc/keys目录下: + +```sh +mkdir -p /etc/keys/ +cp x509_ima.der /etc/keys/ +``` + +**步骤3:** 打包initrd,将IMA证书和摘要列表置入initrd镜像中: + +```sh +echo 'install_items+=" /etc/keys/x509_ima.der "' >> /etc/dracut.conf +dracut -f -e xattr +``` + +**步骤4:** 重启后检查证书导入成功: + +```sh +keyctl show %:.ima +``` + +#### 典型使用场景 + +根据运行模式的不同,IMA摘要列表可应用于可信度量场景和用户态安全启动场景。 + +##### 可信度量场景 + +可信度量场景主要基于IMA摘要列表度量模式,由内核+硬件可信根(如TPM)共同完成对关键文件的度量,再结合远程证明工具链完成对当前系统的文件可信状态的证明: + +![](./figures/ima_trusted_measurement.png) + +**运行阶段** + +- 软件包部署时同步导入摘要列表,IMA对摘要列表进行度量并记录度量日志(同步扩展TPM); + +- 应用程序执行时触发IMA度量,若文件摘要值匹配白名单则忽略,否则记录度量日志(同步扩展TPM) 。 + +**证明阶段(业界通用流程)** + +- 远程证明服务器下发证明请求,客户端回传IMA度量日志以及经过签名的TPM PCR值; + +- 远程证明服务器依次校验PCR(校验签名)、度量日志(PCR回放)、文件度量信息(比对本地基准值)的正确性,上报结果至安全中心; + +- 安全管理中心采取对应操作,如事件通知、节点隔离等。 + +##### 用户态安全启动场景 + +用户态安全启动场景主要基于IMA摘要列表评估模式,与安全启动类似,旨在对执行的应用程序或访问的关键文件执行完整性校验,如果校验失败,则拒绝访问: + +![](./figures/ima_secure_boot.png) + +**运行阶段** + +- 应用部署时导入摘要列表,内核验签通过后,加载摘要值到内核哈希表中作为白名单; +- 应用程序执行时触发IMA校验,计算文件hash值,若与基线值一致,则允许访问,否则记录日志或拒绝访问 。 + +## 附录 + +### 内核编译选项说明 + +原生IMA/EVM提供的编译选项及说明如下: + +| 编译选项 | 功能 | +| :------------------------------- | :------------------------ | +| CONFIG_INTEGRITY | IMA/EVM 总编译开关 | +| CONFIG_INTEGRITY_SIGNATURE | 使能IMA签名校验 | +| CONFIG_INTEGRITY_ASYMMETRIC_KEYS | 使能IMA非对称签名校验 | +| CONFIG_INTEGRITY_TRUSTED_KEYRING | 使能 IMA/EVM 密钥环 | +| CONFIG_INTEGRITY_AUDIT | 编译 IMA audit 审计模块 | +| CONFIG_IMA | IMA 总编译开关 | +| CONFIG_IMA_WRITE_POLICY | 允许在运行阶段更新IMA策略 | +| CONFIG_IMA_MEASURE_PCR_IDX | 允许指定IMA度量 PCR 序号 | +| CONFIG_IMA_LSM_RULES | 允许配置 LSM 规则 | +| CONFIG_IMA_APPRAISE | IMA 评估总编译开关 | +| IMA_APPRAISE_BOOTPARAM | 启用IMA评估启动参数 | +| CONFIG_EVM | EVM 总编译开关 | + +openEuler IMA摘要列表特性提供的编译选项及说明如下(openEuler内核编译默认开启): + +| 编译选项 | 功能 | +| :----------------- | :---------------------- | +| CONFIG_DIGEST_LIST | 开启IMA摘要列表特性开关 | + +### IMA摘要列表根证书说明 + +openEuler 22.03版本使用RPM密钥对IMA摘要列表进行签名,为保证IMA功能开箱可用,openEuler内核编译时默认将RPM根证书(PGP证书)导入内核。当前包含旧版本使用的OBS证书和openEuler 22.03 LTS SP1版本切换的openEuler证书: + +```shell +# cat /proc/keys | grep PGP +1909b4ad I------ 1 perm 1f030000 0 0 asymmetri private OBS b25e7f66: PGP.rsa b25e7f66 [] +2f10cd36 I------ 1 perm 1f030000 0 0 asymmetri openeuler fb37bc6f: PGP.rsa fb37bc6f [] +``` + +由于当前内核不支持导入PGP子公钥,而切换后的openEuler证书采用子密钥签名,因此openEuler内核编译前对证书进行了预处理,抽取子公钥并导入内核,具体处理流程可见内核软件包代码仓内的process_pgp_certs.sh脚本文件: + +openEuler 24.03及之后的版本支持IMA专用证书,详见[证书签名](../CertSignature/signature-certificate-introduction.md)文档相关章节。 + +如果用户不使用IMA摘要列表功能或使用其他密钥实现签名/验签,则可将相关代码移除,自行实现内核根证书配置。 diff --git a/docs/en/25.03/Server/Security/TrustedComputing/TPCM.md b/docs/en/25.03/Server/Security/TrustedComputing/TPCM.md new file mode 100644 index 0000000000000000000000000000000000000000..5abf5595d6fd8066e0642864415965d59518bcda --- /dev/null +++ b/docs/en/25.03/Server/Security/TrustedComputing/TPCM.md @@ -0,0 +1,37 @@ +# 可信平台控制模块(TPCM) + +## 背景 + +可信计算在近40年的研究过程中,经历了不断的发展和完善,已经成为信息安全的一个重要分支。中国的可信计算技术近年发展迅猛,在可信计算2.0的基础上解决了可信体系与现有体系的融合问题、可信管理问题以及可信开发的简化问题,形成了基于主动免疫体系的可信计算技术--可信计算3.0。相对于可信计算2.0被动调用的外挂式体系结构,可信计算3.0提出了以自主密码为基础、控制芯片为支柱、双融主板为平台、可信软件为核心、可信连接为纽带、策略管控成体系、安全可信保应用的全新的可信体系框架,在网络层面解决可信问题。 + +可信平台控制模块(Trusted Platform Control Module,TPCM)是一种可集成在可信计算平台中,用于建立和保障信任源点的基础核心模块。它作为中国可信计算3.0中的创新点之一和主动免疫机制的核心,实现了对整个平台的主动可控。 + +TPCM可信计算3.0架构为双体系架构,分为防护部件和计算部件,以可信密码模块为基础,通过可信平台控制模块对防护部件和计算部件及组件的固件进行可信度量,可信软件基(Trusted Software Base,TSB)对系统软件及应用软件进行可信度量,同时TPCM管理平台实现对可信度量的验证及可信策略同步和管理。 + +## 功能描述 + +如下图所示,整体系统方案由防护部件、计算部件和可信管理中心三部分组成。 + +![](./figures/TPCM.png) + +- 可信管理中心:对可信计算节点的防护策略和基准值进行制定、下发、维护、存储等操作的集中管理平台,可信管理中心由第三方厂商提供。 +- 防护部件:独立于计算部件执行,为可信计算平台提供具有主动度量和主动控制特征的可信计算防护功能,实现运算的同时进行安全防护。防护部件包括可信平台控制模块、可信软件基,以及可信密码模块(Trusted Cryptography Module,TCM)。TPCM是可信计算节点中实现可信防护功能的关键部件,可以采用多种技术途径实现,如板卡、芯片、IP核等,其内部包含中央处理器、存储器等硬件,固件,以及操作系统与可信功能组件等软件,支撑其作为一个独立于计算部件的防护部件组件,并行于计算部件按内置防护策略工作,对计算部件的硬件、固件及软件等需防护的资源进行可信监控,是可信计算节点中的可信根。 + +- 计算部件:主要包括硬件、操作系统和应用层软件。其中操作系统分为引导阶段和运行阶段,在引导阶段openEuler的shim和grub2支持可信度量能力,可实现对shim、grub2以及操作系统内核、initramfs等启动文件的可信度量防护;在运行阶段,openEuler操作系统支持部署可信验证要素代理(由第三方厂商可信华泰提供),它负责将数据发送给TPCM模块,用以实现运行阶段的可信度量防护。 + +其中,TPCM作为可信计算节点中实现可信防护功能的关键部件,需要与TSB、TCM、可信管理中心和可信计算节点的计算部件交互,交互方式如下: + +1. TPCM的硬件、固件与软件为TSB提供运行环境,设置的可信功能组件为TSB按策略库解释要求实现度量、控制、支撑与决策等功能提供支持。 +2. TPCM通过访问TCM获取可信密码功能,完成对防护对象可信验证、度量和保密存储等计算任务,并提供TCM服务部件以支持对TCM的访问。 +3. TPCM通过管理接口连接可信管理中心,实现防护策略管理、可信报告处理等功能。 +4. TPCM通过内置的控制器和I/O端口,经由总线与计算部件的控制器交互,实现对计算部件的主动监控。 +5. 计算部件操作系统中内置的防护代理获取预设的防护对象有关代码和数据提供给TPCM,TPCM将监控信息转发给TSB,由TSB依据策略库进行分析处理。 + +## 约束限制 + +适配服务器:TaiShan 200(型号2280)VF
+适配BMC插卡型号:BC83SMMC + +## 应用场景 + +通过TPCM特性构成一个完整的信任链,保障系统启动以后进入一个可信的计算环境。 diff --git a/docs/en/25.03/Server/Security/TrustedComputing/_menu.md b/docs/en/25.03/Server/Security/TrustedComputing/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..bde4f58cf7b4e088a1ad8a6fa3bdd60fbd692b5a --- /dev/null +++ b/docs/en/25.03/Server/Security/TrustedComputing/_menu.md @@ -0,0 +1,18 @@ +--- +label: '可信计算' +ismanual: 'Y' +description: '介绍可信计算的定义和相关概念' +children: + - label: '可信计算定义' + href: './trusted-computing.md' + - label: '内核完整性度量(IMA)' + href: './IMA.md' + - label: '动态完整性度量(DIM)' + href: './DIM.md' + - label: '远程证明(鲲鹏安全库)' + href: './remote-proof(kunpeng-security-library).md' + - label: '可信平台控制模块(TPCM)' + href: './TPCM.md' + - label: '可信计算常见问题与解决方法' + href: './trusted-computing-faqs.md' +--- diff --git a/docs/en/25.03/Server/Security/TrustedComputing/figures/RA-arch-1.png b/docs/en/25.03/Server/Security/TrustedComputing/figures/RA-arch-1.png new file mode 100644 index 0000000000000000000000000000000000000000..bc55e411637b825b0ce44a7efca08f7e52e0fa70 Binary files /dev/null and b/docs/en/25.03/Server/Security/TrustedComputing/figures/RA-arch-1.png differ diff --git a/docs/en/25.03/Server/Security/TrustedComputing/figures/RA-arch-2.png b/docs/en/25.03/Server/Security/TrustedComputing/figures/RA-arch-2.png new file mode 100644 index 0000000000000000000000000000000000000000..7effbaf881ffe42823142561b9135237989d7153 Binary files /dev/null and b/docs/en/25.03/Server/Security/TrustedComputing/figures/RA-arch-2.png differ diff --git a/docs/en/25.03/Server/Security/TrustedComputing/figures/TPCM.png b/docs/en/25.03/Server/Security/TrustedComputing/figures/TPCM.png new file mode 100644 index 0000000000000000000000000000000000000000..290bdb3471b46dca3e9f0c0907c3855367bd5b65 Binary files /dev/null and b/docs/en/25.03/Server/Security/TrustedComputing/figures/TPCM.png differ diff --git a/docs/en/25.03/Server/Security/TrustedComputing/figures/dim_architecture.jpg b/docs/en/25.03/Server/Security/TrustedComputing/figures/dim_architecture.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a1e672d01dd7174c6f631bc0443cea5717a27bfb Binary files /dev/null and b/docs/en/25.03/Server/Security/TrustedComputing/figures/dim_architecture.jpg differ diff --git a/docs/en/25.03/Server/Security/TrustedComputing/figures/ima-modsig.png b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima-modsig.png new file mode 100644 index 0000000000000000000000000000000000000000..c3e54e27b6ce30bd21e97908b6168a73f318c117 Binary files /dev/null and b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima-modsig.png differ diff --git a/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_digest_list_flow.png b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_digest_list_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..2f5c18f97c644069d5d3e6cad82d01ca519418a4 Binary files /dev/null and b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_digest_list_flow.png differ diff --git a/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_digest_list_pkg.png b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_digest_list_pkg.png new file mode 100644 index 0000000000000000000000000000000000000000..a93ff611da5cbeec856b5971126e710d91e63567 Binary files /dev/null and b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_digest_list_pkg.png differ diff --git a/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_digest_list_update.png b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_digest_list_update.png new file mode 100644 index 0000000000000000000000000000000000000000..771067e31cee84591fbb914d7be4e8c576d7f5d2 Binary files /dev/null and b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_digest_list_update.png differ diff --git a/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_priv_key.png b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_priv_key.png new file mode 100644 index 0000000000000000000000000000000000000000..1fe6ac6bb01b224e0248603df39aa743ae62966d Binary files /dev/null and b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_priv_key.png differ diff --git a/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_rpm.png b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_rpm.png new file mode 100644 index 0000000000000000000000000000000000000000..484e59535b8b0957dfa0618b83764c13d59e3612 Binary files /dev/null and b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_rpm.png differ diff --git a/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_secure_boot.png b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_secure_boot.png new file mode 100644 index 0000000000000000000000000000000000000000..656e4cadb8798be2fe634a074e64f15b0f6a6004 Binary files /dev/null and b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_secure_boot.png differ diff --git a/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_sig_verify.png b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_sig_verify.png new file mode 100644 index 0000000000000000000000000000000000000000..c2b43abf07ae9bf59f0e913585cf89b1f079ed00 Binary files /dev/null and b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_sig_verify.png differ diff --git a/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_tpm.png b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_tpm.png new file mode 100644 index 0000000000000000000000000000000000000000..56fc12820d4dd98c4d6a4db01419d1a72382b0af Binary files /dev/null and b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_tpm.png differ diff --git a/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_trusted_measurement.png b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_trusted_measurement.png new file mode 100644 index 0000000000000000000000000000000000000000..79ebc8f8952bc766741482ea023c507b3a2e15a3 Binary files /dev/null and b/docs/en/25.03/Server/Security/TrustedComputing/figures/ima_trusted_measurement.png differ diff --git a/docs/en/25.03/Server/Security/TrustedComputing/figures/trusted_chain.png b/docs/en/25.03/Server/Security/TrustedComputing/figures/trusted_chain.png new file mode 100644 index 0000000000000000000000000000000000000000..034f0f092f41fb500ee4122339c447d10d4138ec Binary files /dev/null and b/docs/en/25.03/Server/Security/TrustedComputing/figures/trusted_chain.png differ diff --git a/docs/en/25.03/Server/Security/TrustedComputing/public_sys-resources/icon-note.gif b/docs/en/25.03/Server/Security/TrustedComputing/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Server/Security/TrustedComputing/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Server/Security/TrustedComputing/remote-proof(kunpeng-security-library).md b/docs/en/25.03/Server/Security/TrustedComputing/remote-proof(kunpeng-security-library).md new file mode 100644 index 0000000000000000000000000000000000000000..1bf89f24a84b0b8d0eb8eaa4cc8c27a080da083e --- /dev/null +++ b/docs/en/25.03/Server/Security/TrustedComputing/remote-proof(kunpeng-security-library).md @@ -0,0 +1,400 @@ +# 远程证明(鲲鹏安全库) + +## 介绍 + +本项目开发运行在鲲鹏处理器上的基础安全软件组件,前期主要聚焦在远程证明等可信计算相关领域,使能社区安全开发者。 + +## 软件架构 + +在未使能TEE的平台上,本项目可提供平台远程证明特性,其软件架构如下图所示: + +![img](./figures/RA-arch-1.png) + +在已使能TEE的平台上,本项目可提供TEE远程证明特性,其软件架构如下图所示: + +![img](./figures/RA-arch-2.png) + +## 安装配置 + +1. 使用yum安装程序的rpm包,命令如下: + + ```shell + # yum install kunpengsecl-ras kunpengsecl-rac kunpengsecl-rahub kunpengsecl-qcaserver kunpengsecl-attester kunpengsecl-tas kunpengsecl-devel + ``` + +2. 准备数据库环境:进入 `/usr/share/attestation/ras` 目录,执行 `prepare-database-env.sh` 脚本进行自动化的数据库环境配置。 + +3. 程序运行时依赖的配置文件有三个路径,分别为:当前路径 `./config.yaml` ,家路径 `${HOME}/.config/attestation/ras(rac)(rahub)(qcaserver)(attester)(tas)/config.yaml` ,以及系统路径 `/etc/attestation/ras(rac)(rahub)(qcaserver)(attester)(tas)/config.yaml` 。 + +4. (可选)如果需要创建家目录配置文件,可在安装好rpm包后,执行位于 `/usr/share/attestation/ras(rac)(rahub)(qcaserver)(attester)(tas)` 下的脚本 `prepare-ras(rac)(hub)(qca)(attester)(tas)conf-env.sh` 从而完成家目录配置文件的部署。 + +## 相关参数 + +### RAS启动参数 + +命令行输入 `ras` 即可启动RAS程序。请注意,在当前目录下需要提供**ECDSA**公钥并命名为 `ecdsakey.pub` 。相关参数如下: + +```shell + -H --https http/https模式开关,默认为https(true),false=http + -h --hport https模式下RAS监听的restful api端口 + -p, --port string RAS监听的client api端口 + -r, --rest string http模式下RAS监听的restful api端口 + -T, --token 生成一个测试用的验证码并退出 + -v, --verbose 打印更详细的RAS运行时日志信息 + -V, --version 打印RAS版本并退出 +``` + +### RAC启动参数 + +命令行输入 `sudo raagent` 即可启动RAC程序,请注意,物理TPM模块的开启需要sudo权限。相关参数如下: + +```shell + -s, --server string 指定待连接的RAS服务端口 + -t, --test 以测试模式启动 + -v, --verbose 打印更详细的RAC运行时日志信息 + -V, --version 打印RAC版本并退出 + -i, --imalog 指定ima文件路径 + -b, --bioslog 指定bios文件路径 + -T, --tatest 以TA测试模式启动 +``` + +**注意:** +>1.若要使用TEE远程证明特性,需要以非TA测试模式启动RAC,并将待证明TA的uuid、是否使用TCB、mem_hash和img_hash按序放入RAC执行路径下的**talist**文件内。同时预装由TEE团队提供的**libqca.so**库和**libteec.so**库。**talist**文件格式如下: +> +>```text +>e08f7eca-e875-440e-9ab0-5f381136c600 false ccd5160c6461e19214c0d8787281a1e3c4048850352abe45ce86e12dd3df9fde 46d5019b0a7ffbb87ad71ea629ebd6f568140c95d7b452011acfa2f9daf61c7a +>``` +> +>2.若不使用TEE远程证明特性,则需要将 `${DESTDIR}/usr/share/attestation/qcaserver` 目录下的libqca.so库和libteec.so库复制到 `/usr/lib` 或 `/usr/lib64` 目录,并以TA测试模式启动RAC。 + +### QCA启动参数 + +命令行输入 `${DESTDIR}/usr/bin/qcaserver` 即可启动QCA程序,请注意,这里必须要使用qcaserver的完整路径以正常启动QTA,同时需要使QTA中的CA路径参数与该路径保持相同。相关参数如下: + +```shell + -C, --scenario int 设置程序的应用场景,默认为no_as场景(0),1=as_no_daa场景,2=as_with_daa场景 + -S, --server string 指定开放的服务器地址/端口 +``` + +### ATTESTER启动参数 + +命令行输入 `attester` 即可启动ATTESTER程序。相关参数如下: + +```shell + -B, --basevalue string 设置基准值文件读取路径 + -M, --mspolicy int 设置度量策略,默认为-1,需要手动指定。1=仅比对img-hash值,2=仅比对hash值,3=同时比对img-hash和hash两个值 + -S, --server string 指定待连接的服务器地址 + -U, --uuid int 指定待验证的可信应用 + -V, --version 打印程序版本并退出 + -T, --test 读取固定的nonce值以匹配目前硬编码的可信报告 +``` + +### TAS启动参数 + +命令行输入 `tas` 即可启动TAS程序。相关参数如下: + +```shell + -T, --token 生成一个测试用的验证码并退出 +``` + +**注意:** +>1.若要启用TAS服务,需要先为TAS配置好私钥。可以按如下命令修改家目录下的配置文件: +> +>```shell +># cd ${HOME}/.config/attestation/tas +># vim config.yaml +> # 如下DAA_GRP_KEY_SK_X和DAA_GRP_KEY_SK_Y的值仅用于测试,正常使用前请务必更新其内容以保证安全。 +>tasconfig: +> port: 127.0.0.1:40008 +> rest: 127.0.0.1:40009 +> akskeycertfile: ./ascert.crt +> aksprivkeyfile: ./aspriv.key +> huaweiitcafile: ./Huawei IT Product CA.pem +> DAA_GRP_KEY_SK_X: 65a9bf91ac8832379ff04dd2c6def16d48a56be244f6e19274e97881a776543c65a9bf91ac8832379ff04dd2c6def16d48a56be244f6e19274e97881a776543c +> DAA_GRP_KEY_SK_Y: 126f74258bb0ceca2ae7522c51825f980549ec1ef24f81d189d17e38f1773b56126f74258bb0ceca2ae7522c51825f980549ec1ef24f81d189d17e38f1773b56 +>``` +> +>之后再输入`tas`启动TAS程序。 +> +>2.在有TAS环境中,为提高QCA配置证书的效率,并非每一次启动都需要访问TAS以生成相应证书,而是通过证书的本地化存储,即读取QCA侧 `config.yaml` 中配置的证书路径,通过 `func hasAKCert(s int) bool` 函数检查是否已有TAS签发的证书保存于本地,若成功读取证书,则无需访问TAS,若读取证书失败,则需要访问TAS,并将TAS返回的证书保存于本地。 + +## 接口定义 + +### RAS接口 + +为了便于管理员对目标服务器、RAS以及目标服务器上部署的TEE中的用户 TA 进行管理,本程序设计了以下接口可供调用: + +| 接口 | 方法 | +| --------------------------------- | --------------------------- | +| / | GET | +| /{id} | GET、POST、DELETE | +| /{from}/{to} | GET | +| /{id}/reports | GET | +| /{id}/reports/{reportid} | GET、DELETE | +| /{id}/basevalues | GET | +| /{id}/newbasevalue | POST | +| /{id}/basevalues/{basevalueid} | GET、POST、DELETE | +| /{id}/ta/{tauuid}/status | GET | +| /{id}/ta/{tauuid}/tabasevalues | GET | +| /{id}/ta/{tauuid}/tabasevalues/{tabasevalueid} | GET、POST、DELETE | +| /{id}/ta/{tauuid}/newtabasevalue | POST | +| /{id}/ta/{tauuid}/tareports | GET | +| /{id}/ta/{tauuid}/tareports/{tareportid} | GET、POST、DELETE | +| /{id}/basevalues/{basevalueid} | GET、DELETE | +| /version | GET | +| /config | GET、POST | +| /{id}/container/status | GET | +| /{id}/device/status | GET | + +上述接口的具体用法分别介绍如下。 + +若需要查询所有服务器的信息,可以使用`"/"`接口。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/ +``` + +*** +若需要查询目标服务器的详细信息,可以使用`"/{id}"`接口的`GET`方法,其中{id}是RAS为目标服务器分配的唯一标识号。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1 +``` + +*** +若需要修改目标服务器的信息,可以使用`"/{id}"`接口的`POST`方法,其中$AUTHTOKEN是事先使用`ras -T`自动生成的身份验证码。 + +```go +type clientInfo struct { + Registered *bool `json:"registered"` // 目标服务器注册状态 + IsAutoUpdate *bool `json:"isautoupdate"`// 目标服务器基准值更新策略 +} +``` + +```shell +# curl -X POST -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1 -d '{"registered":false, "isautoupdate":false}' +``` + +*** +若需要删除目标服务器,可以使用`"/{id}"`接口的`DELETE`方法。 +**注意:** +>使用该方法并非删除目标服务器的所有信息,而是把目标服务器的注册状态置为`false`! + +```shell +# curl -X DELETE -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1 +``` + +*** +若需要查询指定范围内的所有服务器信息,可以使用`"/{from}/{to}"`接口的`GET`方法。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/9 +``` + +*** +若需要查询目标服务器的所有可信报告,可以使用`"/{id}/reports"`接口的`GET`方法。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/reports +``` + +*** +若需要查询目标服务器指定可信报告的详细信息,可以使用`"/{id}/reports/{reportid}"`接口的`GET`方法,其中{reportid}是RAS为目标服务器指定可信报告分配的唯一标识号。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/reports/1 +``` + +*** +若需要删除目标服务器指定可信报告,可以使用`"/{id}/reports/{reportid}"`接口的`DELETE`方法。 +**注意:** +>使用该方法将删除指定可信报告的所有信息,将无法再通过接口对该报告进行查询! + +```shell +# curl -X DELETE -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1/reports/1 +``` + +*** +若需要查询目标服务器的所有基准值,可以使用`"/{id}/basevalues"`接口的`GET`方法。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/basevalues +``` + +*** +若需要给目标服务器新增一条基准值信息,可以使用`"/{id}/newbasevalue"`接口的`POST`方法。 + +```go +type baseValueJson struct { + BaseType string `json:"basetype"` // 基准值类型 + Uuid string `json:"uuid"` // 容器或设备的标识号 + Name string `json:"name"` // 基准值名称 + Enabled bool `json:"enabled"` // 基准值是否可用 + Pcr string `json:"pcr"` // PCR值 + Bios string `json:"bios"` // BIOS值 + Ima string `json:"ima"` // IMA值 + IsNewGroup bool `json:"isnewgroup"` // 是否为一组新的基准值 +} +``` + +```shell +# curl -X POST -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1/newbasevalue -d '{"name":"test", "basetype":"host", "enabled":true, "pcr":"testpcr", "bios":"testbios", "ima":"testima", "isnewgroup":true}' +``` + +*** +若需要查询目标服务器指定基准值的详细信息,可以使用`"/{id}/basevalues/{basevalueid}"`接口的`GET`方法,其中{basevalueid}是RAS为目标服务器指定基准值分配的唯一标识号。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/basevalues/1 +``` + +*** +若需要修改目标服务器指定基准值的可用状态,可以使用`"/{id}/basevalues/{basevalueid}"`接口的`POST`方法。 + +```shell +# curl -X POST -H "Content-type: application/json" -H "Authorization: $AUTHTOKEN" http://localhost:40002/1/basevalues/1 -d '{"enabled":true}' +``` + +*** +若需要删除目标服务器指定基准值,可以使用`"/{id}/basevalues/{basevalueid}"`接口的`DELETE`方法。 +**注意:** +>使用该方法将删除指定基准值的所有信息,将无法再通过接口对该基准值进行查询! + +```shell +# curl -X DELETE -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1/basevalues/1 +``` + +*** +若需要查询目标服务器上特定用户 TA 的可信状态,可以使用`"/{id}/ta/{tauuid}/status"`接口的GET方法。其中{id}是RAS为目标服务器分配的唯一标识号,{tauuid}是特定用户 TA 的身份标识号。 + +```shell +# curl -X GET -H "Content-type: application/json" -H "Authorization: $AUTHTOKEN" http://localhost:40002/1/ta/test/status +``` + +*** +若需要查询目标服务器上特定用户 TA 的所有基准值信息,可以使用`"/{id}/ta/{tauuid}/tabasevalues"`接口的GET方法。 + +```shell +# curl -X GET -H "Content-type: application/json" http://localhost:40002/1/ta/test/tabasevalues +``` + +*** +若需要查询目标服务器上特定用户 TA 的指定基准值的详细信息,可以使用`"/{id}/ta/{tauuid}/tabasevalues/{tabasevalueid}"`接口的GET方法。其中{tabasevalueid}是RAS为目标服务器上特定用户 TA 的指定基准值分配的唯一标识号。 + +```shell +# curl -X GET -H "Content-type: application/json" http://localhost:40002/1/ta/test/tabasevalues/1 +``` + +*** +若需要修改目标服务器上特定用户 TA 的指定基准值的可用状态,可以使用`"/{id}/ta/{tauuid}/tabasevalues/{tabasevalueid}"`接口的`POST`方法。 + +```shell +# curl -X POST -H "Content-type: application/json" -H "Authorization: $AUTHTOKEN" http://localhost:40002/1/ta/test/tabasevalues/1 --data '{"enabled":true}' +``` + +*** +若需要删除目标服务器上特定用户 TA 的指定基准值,可以使用`"/{id}/ta/{tauuid}/tabasevalues/{tabasevalueid}"`接口的`DELETE`方法。 +**注意:** +>使用该方法将删除指定基准值的所有信息,将无法再通过接口对该基准值进行查询! + +```shell +# curl -X DELETE -H "Content-type: application/json" -H "Authorization: $AUTHTOKEN" -k http://localhost:40002/1/ta/test/tabasevalues/1 +``` + +*** +若需要给目标服务器上特定用户 TA 新增一条基准值信息,可以使用`"/{id}/ta/{tauuid}/newtabasevalue"`接口的`POST`方法。 + +```go +type tabaseValueJson struct { + Uuid string `json:"uuid"` // 用户 TA 的标识号 + Name string `json:"name"` // 基准值名称 + Enabled bool `json:"enabled"` // 基准值是否可用 + Valueinfo string `json:"valueinfo"` // 镜像哈希值和内存哈希值 +} +``` + +```shell +# curl -X POST -H "Content-Type: application/json" -H "Authorization: $AUTHTOKEN" -k http://localhost:40002/1/ta/test/newtabasevalue -d '{"uuid":"test", "name":"testname", "enabled":true, "valueinfo":"test info"}' +``` + +*** +若需要查询目标服务器上特定用户 TA 的所有可信报告,可以使用`"/{id}/ta/{tauuid}/tareports"`接口的`GET`方法。 + +```shell +# curl -X GET -H "Content-type: application/json" http://localhost:40002/1/ta/test/tareports +``` + +*** +若需要查询目标服务器上特定用户 TA 的指定可信报告的详细信息,可以使用`"/{id}/ta/{tauuid}/tareports/{tareportid}"`接口的`GET`方法,其中{tareportid}是RAS为目标服务器上特定用户 TA 的指定可信报告分配的唯一标识号。 + +```shell +# curl -X GET -H "Content-type: application/json" http://localhost:40002/1/ta/test/tareports/2 +``` + +*** +若需要删除目标服务器上特定用户 TA 的指定可信报告,可以使用`"/{id}/ta/{tauuid}/tareports/{tareportid}"`接口的`DELETE`方法。 +**注意:** +>使用该方法将删除指定可信报告的所有信息,将无法再通过接口对该报告进行查询! + +```shell +# curl -X DELETE -H "Content-type: application/json" http://localhost:40002/1/ta/test/tareports/2 +``` + +*** +若需要获取本程序的版本信息,可以使用`"/version"`接口的`GET`方法。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/version +``` + +*** +若需要查询目标服务器/RAS/数据库的配置信息,可以使用`"/config"`接口的`GET`方法。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/config +``` + +*** +若需要修改目标服务器/RAS/数据库的配置信息,可以使用`"/config"`接口的`POST`方法。 + +```go +type cfgRecord struct { + // 目标服务器配置 + HBDuration string `json:"hbduration" form:"hbduration"` + TrustDuration string `json:"trustduration" form:"trustduration"` + DigestAlgorithm string `json:"digestalgorithm" form:"digestalgorithm"` + // RAS配置 + MgrStrategy string `json:"mgrstrategy" form:"mgrstrategy"` + ExtractRules string `json:"extractrules" form:"extractrules"` + IsAllupdate *bool `json:"isallupdate" form:"isallupdate"` + LogTestMode *bool `json:"logtestmode" form:"logtestmode"` +} +``` + +```shell +# curl -X POST -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/config -d '{"hbduration":"5s","trustduration":"20s","DigestAlgorithm":"sha256"}' +``` + +### TAS接口 + +为了便于管理员对TAS服务的远程控制,本程序设计了以下接口可供调用: + +| 接口 | 方法 | +| --------------------| ------------------| +| /config | GET、POST | + +若需要查询TAS的配置信息,可使用`"/config"`接口的`GET`方法: + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40009/config +``` + +*** +若需要修改TAS的配置信息,可使用`"/config"`接口的`POST`方法: + +```shell +curl -X POST -H "Content-Type: application/json" -H "Authorization: $AUTHTOKEN" http://localhost:40009/config -d '{"basevalue":"testvalue"}' +``` + +**注意:** +>TAS的配置信息读取与修改目前仅支持基准值 diff --git a/docs/en/25.03/Server/Security/TrustedComputing/trusted-computing-faqs.md b/docs/en/25.03/Server/Security/TrustedComputing/trusted-computing-faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..ec04aa831adb29afcce8399a27aa9ba987bfdde5 --- /dev/null +++ b/docs/en/25.03/Server/Security/TrustedComputing/trusted-computing-faqs.md @@ -0,0 +1,254 @@ +# 常见问题与解决方法 + +## **问题1:开启IMA评估enforce模式并配置默认策略后,系统启动失败** + +### 原因分析 + +IMA默认策略可能包含对应用程序执行、内核模块加载等关键文件访问流程的校验,如果关键文件访问失败,可能导致系统无法启动。通常原因有: + +1) IMA校验证书未导入内核,导致摘要列表无法被正确校验; +2) 摘要列表文件未正确签名,导致摘要列表校验失败; +3) 摘要列表文件未导入initrd中,导致启动过程无法导入摘要列表; +4) 摘要列表文件和应用程序不匹配,导致应用程序匹配已导入的摘要列表失败。 + +### 解决方法 + +用户需要通过log模式进入系统进行问题定位和修复。重启系统,进入grub界面修改启动参数,采用log模式启动: + +```sh +ima_appraise=log +``` + +系统启动后,可参考如下流程进行问题排查: + +**步骤1:** 检查keyring中的IMA证书: + +```sh +keyctl show %:.builtin_trusted_keys +``` + +对于openEuler LTS版本,至少应存在以下几本内核证书(其他未列出版本可根据发布时间前推参考): + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
版本证书
openEuler 22.03 LTSprivate OBS b25e7f66
openEuler 22.03 LTS SP1/2/3private OBS b25e7f66
openeuler <openeuler@compass-ci.com> b675600b
openEuler 22.03 LTS SP4private OBS b25e7f66
openeuler <openeuler@compass-ci.com> b675600b
openeuler <openeuler@compass-ci.com> fb37bc6f
openEuler 24.03openEuler kernel ICA 1: 90bb67eb4b57eb62bf6f867e4f56bd4e19e7d041
+ +如果用户导入了其他内核根证书,也同样需要通过`keyctl`命令查询确认证书是否被成功导入。openEuler默认不使用IMA密钥环,如果用户存在使用的情况,则需要通过如下命令查询IMA密钥环中是否存在用户证书: + +```sh +keyctl show %:.ima +``` + +如果排查结果为证书未正确导入,则用户需要根据*用户证书导入场景*章节进行流程排查。 + +**步骤2:** 检查摘要列表携带签名信息: + +用户可通过如下命令查询当前系统中的摘要列表文件: + +```sh +ls /etc/ima/digest_lists | grep '_list-compact-' +``` + +对于每个摘要列表文件,需要检查存在**以下三种之一**的签名信息: + +(1) 检查该摘要列表文件存在对应的**RPM摘要列表文件**,且**RPM摘要列表文件**的ima扩展属性中包含签名值。以bash软件包的摘要列表为例,摘要列表文件路径为: + +```sh +/etc/ima/digest_lists/0-metadata_list-compact-bash-5.1.8-6.oe2203sp1.x86_64 +``` + +RPM摘要列表路径为: + +```sh +/etc/ima/digest_lists/0-metadata_list-rpm-bash-5.1.8-6.oe2203sp1.x86_64 +``` + +检查RPM摘要列表签名,即文件的`security.ima`扩展属性不为空: + +```sh +getfattr -n security.ima /etc/ima/digest_lists/0-metadata_list-rpm-bash-5.1.8-6.oe2203sp1.x86_64 +``` + +(2) 检查摘要列表文件的`security.ima`扩展属性不为空: + +```sh +getfattr -n security.ima /etc/ima/digest_lists/0-metadata_list-compact-bash-5.1.8-6.oe2203sp1.x86_64 +``` + +(3) 检查摘要列表文件的末尾包含了签名信息,可通过检查文件内容末尾是否包含`~Module signature appended~`魔鬼字符串进行判断(仅openEuler 24.03 LTS及之后版本支持的签名方式): + +```sh +tail -c 28 /etc/ima/digest_lists/0-metadata_list-compact-kernel-6.6.0-28.0.0.34.oe2403.x86_64 +``` + +如果排查结果为摘要列表未包含签名信息,则用户需要根据*摘要列表签名机制说明*章节进行流程排查。 + +**步骤3:** 检查摘要列表的签名信息正确: + +在确保摘要列表已携带签名信息的情况下,用户还需要确保摘要列表采用正确的私钥签名,即签名私钥和内核中的证书匹配。除用户自行进行私钥检查外,还可通过dmesg日志或audit日志(默认路径为`/var/log/audit/audit.log`)判断是否有签名校验失败的情况发生。典型的日志输出如下: + +```sh +type=INTEGRITY_DATA msg=audit(1722578008.756:154): pid=3358 uid=0 auid=0 ses=1 subj=unconfined_u:unconfined_r:haikang_t:s0-s0:c0.c1023 op=appraise_data cause=invalid-signature comm="bash" name="/root/0-metadata_list-compact-bash-5.1.8-6.oe2203sp1.x86_64" dev="dm-0" ino=785161 res=0 errno=0UID="root" AUID="root" +``` + +如果检查结果为签名信息错误,则用户需要根据*摘要列表签名机制说明*章节进行流程排查。 + +**步骤4:** 检查initrd中是否导入摘要列表文件: + +用户需要通过如下命令查询当前initrd中是否存在摘要列表文件: + +```sh +lsinitrd | grep 'etc/ima/digest_lists' +``` + +如果未查询到摘要列表文件,则用户需要重新制作initrd,并再次检查摘要列表导入成功: + +```sh +dracut -f -e xattr +``` + +**步骤5:** 检查IMA摘要列表和应用程序是否匹配: + +参考[问题2章节](#问题2开启IMA评估enforce模式后部分文件执行失败)。 + +## **问题2:开启IMA评估enforce模式后,部分文件执行失败** + +### 原因分析 + +开启IMA评估enforce模式后,对于配置IMA策略的文件访问,如果文件的内容或扩展属性设置有误(和导入的摘要列表不匹配),则可能会导致文件访问被拒绝。通常原因有: + +(1) 摘要列表未成功导入(可参考FAQ1); + +(2) 文件内容或属性被篡改。 + +### 解决方法 + + 对于出现文件执行失败的场景,首先需要确定摘要列表文件已经成功导入内核,用户可以检查摘要列表数量判断导入情况: + +```sh +cat /sys/kernel/security/ima/digests_count +``` + +然后用户可通过audit日志(默认路径为`/var/log/audit/audit.log`)判断具体哪个文件校验失败以及原因。典型的日志输出如下: + +```sh +type=INTEGRITY_DATA msg=audit(1722811960.997:2967): pid=7613 uid=0 auid=0 ses=1 subj=unconfined_u:unconfined_r:haikang_t:s0-s0:c0.c1023 op=appraise_data cause=IMA-signature-required comm="bash" name="/root/test" dev="dm-0" ino=814424 res=0 errno=0UID="root" AUID="root" +``` + +在确定校验失败的文件后,可对比TLV摘要列表确定文件被篡改的原因。对于未开启扩展属性校验的场景,仅对比文件SHA256哈希值和TLV摘要列表中的`IMA digest`项即可,对于开启扩展属性校验的场景,则还需要对比文件当前的属性和TLV摘要列表中显示扩展属性的区别。 + +在确定问题原因后,可通过还原文件的内容及属性,或对当前文件再次生成摘要列表,签名并导入内核的方式解决问题。 + +## **问题3:开启IMA评估模式后,跨openEuler 22.03 LTS SP版本安装软件包时出现报错信息** + +### 原因分析 + +开启IMA评估模式后,当安装不同版本的openEuler 22.03 LTS的软件包时,会自动触发IMA摘要列表的导入。其中包含对摘要列表的签名验证流程,即使用内核中的证书验证摘要列表的签名。由于openEuler在演进过程中,签名证书发生变化,因此部分跨版本安装场景存在后向兼容问题(无前向兼容问题,即新版本的内核可正常校验旧版本的IMA摘要列表文件)。 + +### 解决方法 + +建议用户确认当前内核中包含以下几本签名证书: + +```sh +# keyctl show %:.builtin_trusted_keys +Keyring + 566488577 ---lswrv 0 0 keyring: .builtin_trusted_keys + 383580336 ---lswrv 0 0 \_ asymmetric: openeuler b675600b + 453794670 ---lswrv 0 0 \_ asymmetric: private OBS b25e7f66 + 938520011 ---lswrv 0 0 \_ asymmetric: openeuler fb37bc6f +``` + +如缺少证书,建议将内核升级至最新版本。 + +```sh +yum update kernel +``` + +openEuler 24.03 LTS及之后版本已具备IMA专用证书,且支持证书链校验,证书生命周期可覆盖整个LTS版本。 + +## **问题4:开启IMA摘要列表评估模式后,IMA摘要列表文件签名正确,但是导入失败** + +### 原因分析 + +IMA摘要列表导入存在检查机制,如果某次导入过程中,摘要列表的签名校验失败,则会关闭摘要列表导入功能,从而导致后续即使正确签名的摘要列表文件也无法被导入。用户可检查dmesg日志中是否存在如下打印确认是否为该原因导致: + +```sh +# dmesg +ima: 0-metadata_list-compact-bash-5.1.8-6.oe2203sp1.x86_64 not appraised, disabling digest lists lookup for appraisal +``` + +如上述日志,则说明在开启IMA摘要列表评估模式的情况下,已经导入了一个签名错误的摘要列表文件,从而导致功能关闭。 + +### 解决方法 + +用户需要重启系统,并修复错误的摘要列表签名信息。 + +## **问题5:openEuler 24.03 LTS及之后版本导入用户自定义的IMA证书失败** + +Linux 6.6内核新增了对导入证书的字段校验限制,对于导入IMA密钥环的证书,需要满足如下约束(遵循X.509标准格式): + +- 为数字签名证书,即设置`keyUsage=digitalSignature`字段; +- 非CA证书,即不可设置`basicConstraints=CA:TRUE`字段; +- 非中间证书,即不可设置`keyUsage=keyCertSign`字段。 + +## **问题6:开启IMA评估模式后kdump服务启动失败** + +开启IMA评估enforce模式后,如果IMA策略中配置了如下KEXEC_KERNEL_CHECK规则,可能导致kdump服务启动失败。 + +```shell +appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig +``` + +原因是在该场景下,所有通过KEXEC加载的文件都需要经过完整性校验,因此内核限制kdump加载内核映像文件时必须使用kexec_file_load系统调用。可通过修改/etc/sysconfig/kdump配置文件的KDUMP_FILE_LOAD开启kexec_file_load系统调用。 + +```shell +KDUMP_FILE_LOAD="on" +``` + +同时,kexec_file_load系统调用自身也会执行文件的签名校验,因此要求被加载的内核映像文件必须包含正确的安全启动签名,而且当前内核中必须包含对应的验签证书。 + +## **问题7:RAS安装后无法启动** + +### 原因分析 + +因为在当前RAS的设计逻辑中,程序启动后需要从当前目录查找一份名为 `ecdsakey.pub` 的文件进行读取并作为之后访问该程序的身份验证码,若当前目录没有该文件,则RAS启动会报错。 + +### 解决方法 + +解决方法一:运行 `ras -T` 生成测试用token后会生成 `ecdsakey.pub` 。 + +解决方法二:自行部署oauth2认证服务后,将对应JWT token生成方对应的验证公钥保存为 `ecdsakey.pub` 。 + +## **问题8:RAS启动后,通过restapi无法访问** + +因为RAS默认以https模式启动,开发者需要向RAS提供合法的证书才能正常访问,而http模式下启动的RAS则不需要提供证书。 diff --git a/docs/en/25.03/Server/Security/TrustedComputing/trusted-computing.md b/docs/en/25.03/Server/Security/TrustedComputing/trusted-computing.md new file mode 100644 index 0000000000000000000000000000000000000000..73d88b12b203a3b58c18f11138f15112e446681d --- /dev/null +++ b/docs/en/25.03/Server/Security/TrustedComputing/trusted-computing.md @@ -0,0 +1,25 @@ +# 可信计算 + +## 可信计算基础 + +不同国际组织对可信(Trusted)做了不同的定义。 + +1. 可信计算组织(TCG)的定义: + + 一个实体是可信的,它的行为总是以预期的方式达到预期的目标。 + +2. 国际标准化组织与国际电子技术委员会定义(1999): + + 参与计算的组件、操作或过程在任意的条件下是可预测的,并能够抵御病毒和一定程度的物理干扰。 + +3. IEEE Computer Society Technical Committee on Dependable Computing 定义: + + 所谓可信,是指计算机系统所提供的服务是可被论证其是可信赖的,可信赖主要是指系统的可靠性和可用性。 + +简而言之,可信就是系统按照预定的设计和策略运行,不做其他事情。 + +一个可信计算系统由信任根、可信硬件平台、可信操作系统和可信应用组成,它的基本思想是首先创建一个安全信任根(TCB),然后建立从硬件平台、操作系统到应用的信任链,在这条信任链上从根开始,前一级认证后一级,实现信任的逐级扩展,从而实现一个安全可信的计算环境。 + +![](./figures/trusted_chain.png) + +相比于传统安全机制的“头痛医头,脚痛医脚”,发现一个病毒消灭一个病毒,可信计算采用的是白名单机制,即只允许经过认证的内核、内核模块、应用程序等在系统上运行,如果发现程序已发生更改(或本来就是一个未知的程序),就拒绝其执行。 diff --git a/docs/en/25.03/Server/Security/secGear/_menu.md b/docs/en/25.03/Server/Security/secGear/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..cec600771df1de47faddee1a37b5144f2271a2d7 --- /dev/null +++ b/docs/en/25.03/Server/Security/secGear/_menu.md @@ -0,0 +1,18 @@ +--- +label: 'secGear开发指南' +ismanual: 'Y' +description: '使用 secGear 统一机密计算编程框架开发应用程序,保障云端数据运行时的安全性' +children: + - label: '认识secGear' + href: './introduction-to-secGear.md' + - label: '安装与部署' + href: './secGear-installation.md' + - label: '接口说明' + href: './api-reference.md' + - label: '开发secGear应用程序' + href: './developer-guide.md' + - label: '使用secGear工具' + href: './using-the-secGear-tool.md' + - label: '应用场景' + href: './application-scenarios.md' +--- diff --git a/docs/en/25.03/Server/Security/secGear/api-reference.md b/docs/en/25.03/Server/Security/secGear/api-reference.md new file mode 100644 index 0000000000000000000000000000000000000000..0e4b58d9ca0248793ba81df9f8c6d8d0fe142714 --- /dev/null +++ b/docs/en/25.03/Server/Security/secGear/api-reference.md @@ -0,0 +1,327 @@ +# 接口说明 + +secGear 机密计算统一编程框架分为安全侧和非安全侧,这里给出用户开发应用程序所需的接口。除这些接口外,安全侧还继承了 ARM TrustZone 和 Intel SGX 的开源 POSIC 接口。 + +## cc_enclave_create + +创建 enclave 接口 + +**功能**: + +初始化接口,函数根据不同 type,调用不同的 TEE 创建函数,完成不同 TEE 方案关于 enclave 上下文初始化,由非安全侧调用 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 由于 Intel SGX 限制,多线程并发调用 cc_enclave_create 时存在内存映射的竞争关系,会导致创建 enclave 概率性失败。所以编码时要避免线程并发调用 cc_enclave_create。 + +**函数声明:** + +cc_enclave_result_t cc_enclave_create(const char*path, enclave_type_t type, uint32_t version,uint32_t flags,const enclave_features_t* features,uint32_t features_count, + cc_enclave_t ** enclave); + +**参数:** + +- Path:入参,要加载的 enclave 路径 +- Type:入参,用来指定 TEE 解决方案, 如 SGX_ENCLAVE_TYPE、GP_ENCLAVE_TYPE、AUTO_ENCLAVE_TYPE +- version:入参,指定的 enclave engine 的版本,目前只有一个版本,取值为 0。 +- Flags:入参,标志位,说明这个 enclave 运行状态,例如调试状态 SECGEAR_DEBUG_FLAG、模拟状态 SECGEAR_SIMULATE_FLAG(目前不支持) +- features:入参,用于设置一些关于 enclave 支持的特性,例如 SGX 的 PCL、 switchless 等。目前不支持,请设置为 NULL +- features_count:入参,入参 features 特性结构体的数量。目前不支持,请设置为 0 +- enclave:出参,创建的 enclave 上下文 + +**返回值:** + +- CE_SUCCESS:认证信息验证成功 +- CE_ERROR_INVALID_PARAMETER:输入参数有误 +- CE_ERROR_OUT_OF_MEMORY:无可用内存 +- CC_FAIL:通用错误 +- CC_ERROR_UNEXPECTED:不可预期错误 +- CC_ERROR_ENCLAVE_MAXIMUM:单个 app 创建的 enclave 数量达到最 +- CC_ERROR_INVALID_PATH:安全二进制路径无效 +- CC_ERROR_NO_FIND_REGFUNC:enclave 引擎搜索失败 + +## cc_enclave_destroy + +销毁 enclave 接口 + +**功能**: + +调用不同 TEE 的退出函数,释放已经创建的 enclave 实体,由非安全侧调用 + +**函数声明:** + +cc_enclave_result_t cc_enclave_destroy (cc_enclave_t ** enclave); + +**参数:** + +- enclave:入参,已经创建 enclave 的上下文 + +**返回值:** + +- CE_SUCCESS:认证信息验证成功 +- CE_ERROR_INVALID_PARAMETER:输入参数有误 +- CE_ERROR_OUT_OF_MEMORY:无可用内存 +- CC_ERROR_NO_FIND_UNREGFUNC:enclave引擎搜索失败 +- CC_FAIL:通用错误 +- CC_ERROR_UNEXPECTED:不可预期错误 + +## cc_malloc_shared_memory + +创建共享内存 + +**功能**: + +开启switchless特性后,创建安全环境与非安全环境可同时访问的共享内存,由非安全侧调用 + +**函数声明:** + +void *cc_malloc_shared_memory(cc_enclave_t*enclave, size_t size); + +**参数:** + +- enclave:入参,安全环境上下文句柄。因不同平台共享内存模型不同,同时为了保持接口跨平台一致性,该参数仅在ARM平台被使用,SGX平台该入参会被忽略 +- size:入参,共享内存大小 + +**返回值:** + +- NULL:共享内存申请失败 +- 其他:为创建的共享内存的首地址 + +## cc_free_shared_memory + +释放共享内存 + +**功能**: + +开启switchless特性后,释放共享内存,由非安全侧调用 + +**函数声明:** + +cc_enclave_result_t cc_free_shared_memory(cc_enclave_t *enclave, void*ptr); + +**参数:** + +- enclave:入参,安全环境上下文句柄。因不同平台共享内存模型不同,同时为了保持接口跨平台一致性,该参数仅在ARM平台被使用(该参数必须与调用cc_malloc_shared_memory接口时传入的enclave保持一致),SGX平台该入参会被忽略 +- ptr:入参,cc_malloc_shared_memory接口返回的共享内存地址 + +**返回值:** + +- CC_ERROR_BAD_PARAMETERS:入参非法 +- CC_ERROR_INVALID_HANDLE:无效enclave或者传入的enclave与ptr所对应的enclave不匹配(仅在ARM平台生效,SGX平台会忽略enclave,故不会对enclave进行检查) +- CC_ERROR_NOT_IMPLEMENTED:该接口未实现 +- CC_ERROR_SHARED_MEMORY_START_ADDR_INVALID:ptr不是cc_malloc_shared_memory接口返回的共享内存地址(仅在ARM平台生效) +- CC_ERROR_OUT_OF_MEMORY:内存不足(仅在ARM平台生效) +- CC_FAIL:一般性错误 +- CC_SUCCESS:成功 + +## cc_enclave_generate_random + +随机数生成 + +**功能**: + +用于在安全侧生成密码安全的随机数 + +**函数声明:** + +cc_enclave_result_t cc_enclave_generate_random(void *buffer, size_t size); + +**参数:** + +- *buffer:入参,生成随机数的缓冲区 +- size:入参,缓冲区的长度 + +**返回值:** + +- CE_OK:认证信息验证成功 +- CE_ERROR_INVALID_PARAMETER:输入参数有误 +- CE_ERROR_OUT_OF_MEMORY:无可用内存 + +## cc_enclave_seal_data + +数据持久化 + +**功能**: + +用于加密 enclave 内部数据,使数据可以在 enclave 外部持久化存储,由安全侧调用 + +**函数声明:** + +cc_enclave_result_t cc_enclave_seal_data(uint8_t *seal_data, uint32_t seal_data_len, + +​ cc_enclave_sealed_data_t *sealed_data, uint32_t sealed_data_len, + +​ uint8_t *additional_text, uint32_t additional_text_len); + +**参数:** + +- seal_data:入参,需要加密的数据 +- seal_data_len:入参,需要加密数据的长度 +- sealed_data:出参,加密后的数据处理句柄 +- sealed_data_len:出参,加密后的密文长度 +- additional_text:入参,加密所需的附加消息 +- additional_text_len:入参,附加消息长度 + +**返回值:** + +- CE_SUCCESS:数据加密成功 +- CE_ERROR_INVALID_PARAMETER:输入参数有误 +- CE_ERROR_OUT_OF_MEMORY:无可用内存 +- CC_ERROR_SHORT_BUFFER:传入的buffer过小 +- CC_ERROR_GENERIC:底层硬件通用错误 + +## cc_enclave_unseal_data + +数据解密 + +**功能**: + +用于解密 enclave 密封过的数据,用于将外部持久化数据重新导回 enclave 环境中,由安全侧调用 + +**函数声明:** + +`cc_enclave_result_t cc_enclave_unseal_data(cc_enclave_sealed_data_t *sealed_data, uint8_t *decrypted_data, uint32_t *decrypted_data_len,uint8_t *additional_text, uint32_t *additional_text_len);` + +**参数:** + +- sealed_data:入参,已加密数据的句柄 +- decrypted_data:出参,解密之后的密文数据buffer +- decrypted_data_len:出参,解密后密文长度 +- additional_text:出参,解密后附加消息 +- additional_text_len:出参,解密后附加消息长度 + +**返回值:** + +- CE_SUCCESS:数据解密成功 +- CE_ERROR_INVALID_PARAMETER:输入参数有误 +- CE_ERROR_OUT_OF_MEMORY:无可用内存 +- CC_ERROR_SHORT_BUFFER:传入的buffer过小 +- CC_ERROR_GENERIC:底层硬件通用错误 + +## cc_enclave_get_sealed_data_size + +获取加密数据的大小 + +**功能**: + +用于 sealed_data 数据的大小,主要用于分配解密后的数据空间,由安全侧与非安全侧皆可调用 + +**函数声明:** + +uint32_t cc_enclave_get_sealed_data_size(const uint32_t add_len, const uint32_t seal_data_len); + +**参数:** + +- add_len:入参,附加消息长度 +- sealed_data_len:入参,加密信息的长度 + +**返回值:** + +- UINT32_MAX:参数错误或函数执行错误 +- others:函数执行成功,返回值为当前 sealed_data 结构的大小 + +## cc_enclave_get_encrypted_text_size + +获取加密消息的长度 + +**功能**: + +获取加密数数据中加密消息的长度,由安全侧调用 + +**函数声明:** + +uint32_t cc_enclave_get_encrypted_text_size(const cc_enclave_sealed_data_t *sealed_data); + +**参数:** + +- sealed_data:入参,加密数据的句柄 + +**返回值:** + +- UINT32_MAX:参数错误或函数执行错误 +- others:函数执行成功,返回值为当前 sealed_data 中加密消息的长度 + +## cc_enclave_get_add_text_size + +获取附加消息的长度 + +**功能**: + +获取加密数数据中附加消息的长度,由安全侧调用 + +**函数声明:** + +uint32_t cc_enclave_get_add_text_size(const cc_enclave_sealed_data_t *sealed_data); + +**参数:** + +- sealed_data:入参,加密数据的句柄 + +**返回值:** + +- UINT32_MAX:参数错误或函数执行错误 +- others:函数执行成功,返回值为当前sealed_data中附加消息的长度 + +## cc_enclave_memory_in_enclave + +安全内存检查 + +**功能**: + +用于校验指定长度的内存地址是否都属于安全侧内存,由安全侧调用 + +**函数声明:** + +bool cc_enclave_memory_in_enclave(const void *addr, size_t size); + +**参数:** + +- *addr:入参,指定需要校验的内存地址 +- size:入参,自内存地址起需要校验的长度 + +**返回值:** + +- true:指定区域内存都在安全区范围内 +- false:指定区域的内存有部分或者全部不在安全范围内 + +## cc_enclave_memory_out_enclave + +安全内存检查 + +**功能**: + +用于校验指定长度的内存地址是否都属于非安全侧内存,由安全侧调用 + +**函数声明:** + +bool cc_enclave_memory_out_enclave(const void *addr, size_t size); + +**参数:** + +- *addr:入参,指定需要校验的内存地址 +- size:入参,自内存地址起需要校验的长度 + +**返回值:** + +- true:指定区域内存都在非安全区 +- false:指定区域的内存有部分或者全部在安全区 + +## PrintInfo + +消息打印 + +**功能**: + +用于安全侧日志的打印,本接口输出安全侧用户想打印的信息,输入日志保存在非安全侧/var/log/secgear/secgear.log中 + +**函数声明:** + +void PrintInfo(int level, const char *fmt, ...); + +**参数:** + +- level:入参,日志打印等级,可选项为PRINT_ERROR, PRINT_WARNING, PRINT_STRACE, PRINT_DEBUG +- fmt: 入参,需要输出的字符串 + +**返回值:** + +- 无 diff --git a/docs/en/25.03/Server/Security/secGear/application-scenarios.md b/docs/en/25.03/Server/Security/secGear/application-scenarios.md new file mode 100644 index 0000000000000000000000000000000000000000..bb5cd15caff6c837d29f2ab40a1bade1bdc3aae9 --- /dev/null +++ b/docs/en/25.03/Server/Security/secGear/application-scenarios.md @@ -0,0 +1,96 @@ +# 应用场景 + +本文通过举例介绍典型场景机密计算解决方案,帮助读者理解secGear的使用场景,进而结合自己的业务构建对应的机密计算解决方案。 + +## BJCA基于TEE的密码模块 + +在政策和业务的双驱动下,密码应用保障基础设施一直在向虚拟化演进,随着业务上云,密码服务支撑也需要构建全新的密码交付模式,实现密码、云服务与业务应用的融合,因此数字认证(BJCA)推出基于TEE的密码模块。数字认证既可以利用鲲鹏TEE环境构建合规的密码计算模块,支撑密码云服务平台,同时也可以基于鲲鹏主机构建“机密计算平台”,为云计算、隐私计算、边缘计算等各类场景提供“高速泛在、弹性部署、灵活调度”的密码服务支撑。基于鲲鹏处理器的内生式密码模块已经成为密码行业变革型的创新方案,并作为内生可信密码计算新起点。 + +### 现状 + +传统密码模块中算法协议以及处理的数据是隐私数据,密码模块上云存在安全风险。 + +### 解决方案 + +![](./figures/BJCA_Crypto_Module.png) + +基于TEE的密码模块方案如图所示,其中密码模块基于secGear机密计算开发框架拆分成两部分:管理服务、算法协议。 + +- 管理服务:运行在REE侧,负责对外提供密码服务,转发请求到TEE中处理。 +- 算法协议:运行在TEE侧,负责用户数据加/解密等处理。 + +由于密码服务可能存在高并发、大数据请求,此时REE与TEE存在频繁交互以及大数据拷贝,会导致性能直线下降,针对类似场景可使用secGear零切换特性优化,减少调用切换及数据拷贝次数,实现性能倍增。 + +## GaussDB基于TEE的全密态数据库 + +云数据库俨然已成为数据库业务未来重要的增长点,绝大多数的传统数据库服务厂商正在加速提供更优质的云数据库服务。然而云数据库所面临的风险相较于传统数据库更复杂多样,无论是应用程序漏洞、系统配置错误,还是恶意管理员都可能对数据安全与隐私保护造成巨大风险。 + +### 现状 + +云数据库的部署网络由“私有环境”向“开放环境”转变,系统运维管理角色被拆分为业务管理员和运维管理员。业务管理员拥有业务管理的权限,属于企业业务方,而运维管理员属于云服务提供商。数据库运维管理员虽然被定义成系统运维管理,其实际依旧享有对数据的完全使用权限,通过运维管理权限或提权来访问数据甚至篡改数据;再者,由于开放式的环境和网络边界的模糊化,用户数据在整个业务流程中被更充分的暴露给攻击者,无论是传输、存储、运维还是运行态,都有可能遭受来自攻击者的攻击。因此对于云数据库场景,如何解决第三方可信问题,如何更加可靠的保护数据安全相比传统数据库面临着更大挑战,其中数据安全、隐私不泄露是整个云数据库面临的首要安全挑战。 + +### 解决方案 + +面对上述挑战,基于TEE的GaussDB(openGauss)全密态数据库的设计思路是:用户自己持有数据加解密密钥,数据以密文形态存在于数据库服务侧的整个生命周期过程中,并在数据库服务端TEE内完成查询运算。 + +![](./figures/secret_gaussdb.png) + +基于TEE的全密态数据库解决方案如图所示,全密态数据库的特点如下: + +1. 数据文件以密文形式存储,不存储密钥明文信息。 +2. DB数据密钥保存在客户端。 +3. 客户端发起查询请求时,在服务端REE侧执行密态SQL语法得到相关密文记录,送入TEE中。 +4. 客户端通过secGear安全通道将DB数据密钥加密传输到服务端TEE中,在TEE中解密得到DB数据密钥,用DB数据密钥将密文记录解密得到明文记录,执行SQL语句,得到查询结果,再将DB数据密钥加密后的查询结果发送给客户端。 + +其中步骤3在数据库高并发请求场景下,会频繁触发REE-TEE之间调用以及大量的数据传输,导致性能直线下降,通过secGear零切换特性优化,减少调用切换及数据拷贝次数,实现性能倍增。 + +## openLooKeng基于TEE的联邦SQL + +openLooKeng联邦SQL是跨数据中心查询的一种,典型场景如下,有三个数据中心:中心数据中心A,边缘数据中心B和边缘数据中心C。openLooKeng集群部署在三个数据中心中,当数据中心A收到一次跨域查询请求时,会下发执行计划到各数据中心,在边缘数据中心B和C的openLookeng集群完成计算后,通过网络将结果传递给数据中心A中的openLookeng集群完成聚合计算。 + +### 现状 + +在以上方案中,计算结果在不同数据中心的openLookeng集群之间传递,避免了网络带宽不足,一定程度上解决了跨域查询问题。但是计算结果是从原始数据计算得到的,可能带有敏感信息,导致数据出域存在一定安全和合规风险。怎么保护聚合计算过程中边缘数据中心的计算结果,在中心数据中心实现 “可用而不可见”呢? + +### 解决方案 + +其基本思路是:数据中心A中,openLookeng集群将聚合计算逻辑及算子拆分出独立的模块,部署到鲲鹏TEE环境上中;其他边缘数据中心的计算结果通过安全通道传输到数据中心A的TEE中;所有数据最终在TEE中完成聚合计算,从而保护聚合计算过程中边缘数据中心的计算结果不会被数据中心A上REE侧特权程序或恶意程序获取、篡改。 + +![](./figures/openLooKeng.png) + +基于TEE的联邦SQL解决方案如图所示,具体查询流程如下: + +1. 用户在数据中心A下发跨域查询请求,openLooKeng的Coordinator根据查询SQL及数据源分布,拆解下发执行计划到本地工作节点以及边缘数据中心的coordinator,边缘数据中心的coordinator再下发到本地工作节点。 +2. 各工作节点执行计划,得到本地计算结果。 +3. 边缘数据中心通过secGear安全通道将本地计算结果加密后经网络传到数据中心A的REE侧,并中转到TEE中,在TEE中解密计算结果。 +4. 数据中心A在TEE中对数据中心A、B、C的计算结果执行聚合计算,得到最终执行结果,并返回给用户。 + +其中步骤4,在存在大量查询请求时,会频繁触发REE-TEE调用,并且有大量数据的拷贝,导致性能直线下降。通过secGear零切换特性优化,减少调用切换及数据拷贝次数,实现性能倍增。 + +## MindSpore基于TEE的纵向联邦特征保护 + +纵向联邦学习是联邦学习的一个重要分支,当不同的参与方拥有来自相同一批用户但属性不同的数据时,可以利用纵向联邦学习进行协同训练。 + +![](./figures/Mindspore_original.png) + +### 现状 + +传统方案如图所示,具体数据处理流程如下。 + +1. 拥有属性的参与方(Follower方)都会持有一个底层网络,参与方属性输入底层网络得到中间结果,再将中间结果发送给拥有标签的参与方(Leader方)。 +2. Leader方使用各参与方的中间结果和标签来训练顶层网络,再将计算得到的梯度回传给各参与方来训练底层网络。 + +此方案避免了Follower方直接上传自己的原始数据,保护原始数据不出域,一定程度上保护了隐私安全。然而,攻击者还是有可能从上传的中间结果反推出用户信息,导致存在隐私泄露风险。因此我们需要对训练时出域的中间结果和梯度提供更强的隐私保护方案,来满足安全合规要求。 + +### 解决方案 + +借鉴之前三个场景的安全风险及解决方案可以发现,想要达到中间结果出域后的“可用不可见”,正是机密计算的“拿手好戏”。 + +![](./figures/Mindspore.png) + +基于TEE的纵向联邦特征保护方案如图所示,具体数据处理流程如下。 + +1. Follower方的中间结果通过secGear的安全通道加密后传输到Leader方,Leader方非安全世界接收到加密的中间结果后中转到安全世界,在安全世界通过安全通道接口解密。 +2. 在安全世界中将中间结果输入到联邦拆分层计算模块,完成结果计算。 + +以上过程中Follower方的中间结果明文只存在于安全世界内存中,对Leader方来说就是黑盒子,无法访问。 diff --git a/docs/en/25.03/Server/Security/secGear/developer-guide.md b/docs/en/25.03/Server/Security/secGear/developer-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..52cd90c0612eec97fd6e8bc31631ab00c03a27a9 --- /dev/null +++ b/docs/en/25.03/Server/Security/secGear/developer-guide.md @@ -0,0 +1,93 @@ +# secGear 开发指南 + +这里给出使用 secGear 开发一个 C 语言程序 helloworld 的例子,方便用户理解使用 secGear 开发应用程序。 + +## 下载样例 + +```bash +git clone https://gitee.com/openeuler/secGear.git +``` + +## 目录结构说明 + +```shell +cd examples/helloworld + +#目录结构如下 +├── helloworld +│ ├── CMakeLists.txt +│ ├── enclave +│ │ ├── CMakeLists.txt +│ │ ├── Enclave.config.xml +│ │ ├── Enclave.lds +│ │ ├── hello.c +│ │ ├── manifest.txt +│ │ └── config_cloud.ini +│ ├── helloworld.edl +│ └── host +│ ├── CMakeLists.txt +│ └── main.c +``` + +代码主体分为三块: + +- 非安全侧程序(main.c) +- 非安全侧与安全侧调用接口头文件(helloworld.edl) +- 安全侧程序(hello.c) + +## 准备工作 + +除以上三部分主体代码外,还有编译工程文件(CMakeLists.txt)、开发者证书(SGX的Enclave.config.xml/Enclave.lds,鲲鹏的manifest.txt/config_cloud.ini)。 + +> ![](./public_sys-resources/icon-note.gif)说明: +> +> - 鲲鹏开发者证书需要向华为业务负责人[申请开发者证书](https://gitee.com/link?target=https%3A%2F%2Fwww.hikunpeng.com%2Fdocument%2Fdetail%2Fzh%2Fkunpengcctrustzone%2Ffg-tz%2Fkunpengtrustzone_04_0009.html)。 +> - SGX以Debug模式调试,暂时不用申请。如需正式商用并且用intel的远程证明服务,需要向Intel[申请License](https://gitee.com/link?target=https%3A%2F%2Fwww.intel.com%2Fcontent%2Fwww%2Fus%2Fen%2Fdeveloper%2Ftools%2Fsoftware-guard-extensions%2Frequest-license.html)。 + +申请成功后会得到开发者证书相关文件,需要放置到代码目录相应位置。 + +## 开发步骤 + +基于secGear做机密计算应用拆分改造,类似于独立功能模块提取,识别敏感数据处理逻辑,提取成独立的lib库,部署在可信执行环境中,对非安全侧提供的接口定义在EDL文件中。 + +开发步骤如下图所示。 + +1. 开发非安全侧main函数及接口,管理enclave并调用安全侧函数。 +2. 开发EDL文件(类似C语言头文件定义非安全侧与安全侧交互接口) +3. 开发安全侧接口实现 +4. 调用代码生成工具,根据EDL自动生成非安全侧与安全侧交互源码,并分别编译到非安全侧与安全侧二进制文件中,非安全侧逻辑直接调用安全侧对应的接口即可,无需关心自动的生成的交互代码,降低开发成本。 +5. 调用签名工具对安全侧二进制签名,实现安全侧程序可信启动。 + +![](./figures/develop_step.png) + +## 编译运行 + +### ARM环境 + +```shell +// clone secGear repository +git clone https://gitee.com/openeuler/secGear.git + +// build secGear and examples +cd secGear +source environment +mkdir debug && cd debug && cmake -DENCLAVE=GP .. && make && sudo make install + +// run helloworld +/vendor/bin/secgear_helloworld +``` + +### x86环境 + +```shell +// clone secGear repository +git clone https://gitee.com/openeuler/secGear.git + +// build secGear and examples +cd secGear +source /opt/intel/sgxsdk/environment && source environment +mkdir debug && cd debug && cmake .. && make && sudo make install + +// run helloworld +./examples/helloworld/host/secgear_helloworld +``` diff --git a/docs/en/25.03/Server/Security/secGear/figures/BJCA_Crypto_Module.png b/docs/en/25.03/Server/Security/secGear/figures/BJCA_Crypto_Module.png new file mode 100644 index 0000000000000000000000000000000000000000..68850639553841299d65c3a666a0b57cfa5500dc Binary files /dev/null and b/docs/en/25.03/Server/Security/secGear/figures/BJCA_Crypto_Module.png differ diff --git a/docs/en/25.03/Server/Security/secGear/figures/Mindspore.png b/docs/en/25.03/Server/Security/secGear/figures/Mindspore.png new file mode 100644 index 0000000000000000000000000000000000000000..b4e415062b7474fb4a5a1d4d02af2f16796da8b7 Binary files /dev/null and b/docs/en/25.03/Server/Security/secGear/figures/Mindspore.png differ diff --git a/docs/en/25.03/Server/Security/secGear/figures/Mindspore_original.png b/docs/en/25.03/Server/Security/secGear/figures/Mindspore_original.png new file mode 100644 index 0000000000000000000000000000000000000000..7812fd1803ceccb4b7a0e9b4debe6833f1a77280 Binary files /dev/null and b/docs/en/25.03/Server/Security/secGear/figures/Mindspore_original.png differ diff --git a/docs/en/25.03/Server/Security/secGear/figures/develop_step.png b/docs/en/25.03/Server/Security/secGear/figures/develop_step.png new file mode 100644 index 0000000000000000000000000000000000000000..4241739df0bcd015dc1589f023d5d1d44f839438 Binary files /dev/null and b/docs/en/25.03/Server/Security/secGear/figures/develop_step.png differ diff --git a/docs/en/25.03/Server/Security/secGear/figures/openLooKeng.png b/docs/en/25.03/Server/Security/secGear/figures/openLooKeng.png new file mode 100644 index 0000000000000000000000000000000000000000..2f810818c55f7913a95abfa0a7a4a7136b0d7a93 Binary files /dev/null and b/docs/en/25.03/Server/Security/secGear/figures/openLooKeng.png differ diff --git a/docs/en/25.03/Server/Security/secGear/figures/secGear_arch.png b/docs/en/25.03/Server/Security/secGear/figures/secGear_arch.png new file mode 100644 index 0000000000000000000000000000000000000000..d7639d138ddbcd154860fce45460e4d256b376a2 Binary files /dev/null and b/docs/en/25.03/Server/Security/secGear/figures/secGear_arch.png differ diff --git a/docs/en/25.03/Server/Security/secGear/figures/secret_gaussdb.png b/docs/en/25.03/Server/Security/secGear/figures/secret_gaussdb.png new file mode 100644 index 0000000000000000000000000000000000000000..05ab4c1b649751a76cdd0db9d47eefe57c44f180 Binary files /dev/null and b/docs/en/25.03/Server/Security/secGear/figures/secret_gaussdb.png differ diff --git a/docs/en/25.03/Server/Security/secGear/introduction-to-secGear.md b/docs/en/25.03/Server/Security/secGear/introduction-to-secGear.md new file mode 100644 index 0000000000000000000000000000000000000000..b809e9c2da60073788329366766dcfb197533804 --- /dev/null +++ b/docs/en/25.03/Server/Security/secGear/introduction-to-secGear.md @@ -0,0 +1,171 @@ +# 认识secGear + +## 概述 + +随着云计算的快速发展,越来越多的企业把计算业务部署到云上,面对第三方云基础设施,云上用户数据安全面临着巨大的挑战。机密计算是一种基于硬件可信执行环境的隐私保护技术,旨在依赖最底层硬件,构建最小信任依赖,将操作系统、Hypervisor、基础设施、系统管理员、服务提供商等都从信任实体列表中删除,视为未经授权的实体,从而减少潜在的风险,保护可信执行环境中数据的机密性、完整性。然而随着机密计算技术的兴起,业界机密计算技术种类繁多(如主流的Intel SGX、ARM Trustzone、RISC-V keystone等),各技术SDK也千差万别,给开发者带来较大的开发维护成本,长远考虑,还造成了机密计算应用生态隔离。为方便开发者快速构建保护云上数据安全的机密计算解决方案,openEuler推出机密计算统一开发框架secGear。 + +## 架构介绍 + +![](./figures/secGear_arch.png) + +secGear机密计算统一开发框架技术架构如图所示,主要包括三层,共同组成openEuler机密计算软件生态底座。 + +- Base Layer:机密计算SDK统一层,屏蔽TEE及SDK差异,实现不同架构共源码。 +- Middleware Layer:通用组件层,机密计算软件货架,无需从头造轮子,帮助用户快速构建机密计算解决方案。 +- Server Layer:机密计算服务层,提供典型场景机密计算解决方案。 + +## 关键特性 + +### 零切换 + +#### 客户痛点 + +传统应用做机密计算拆分改造后,REE侧逻辑存在频繁调用TEE侧逻辑时或REE与TEE存在频繁大块数据交互时。由于REE与TEE之间的每次调用,都需要经过REE用户态 、REE内核态、驱动、TEE内核态、TEE用户态之间的上下文切换,调用传递的大块数据也要经过多次拷贝,并且驱动底层数据块大小限制等因素,频繁的REE与TEE交互性能直线下降,严重影响机密计算应用的落地。 + +#### 解决方案 + +[零切换](https://gitee.com/openeuler/secGear#switchless%E7%89%B9%E6%80%A7)是一种通过共享内存减少REE与TEE上下文切换及数据拷贝次数,优化REE与TEE交互性能的技术。 + +#### 使用方法 + +1. 创建enclave时启用零切换 + + 零切换配置项及说明如下。 + + ```c + typedef struct { + uint32_t num_uworkers; + uint32_t num_tworkers; + uint32_t switchless_calls_pool_size; + uint32_t retries_before_fallback; + uint32_t retries_before_sleep; + uint32_t parameter_num; + uint32_t workers_policy; + uint32_t rollback_to_common; + cpu_set_t num_cores; + } cc_sl_config_t; + ``` + + | 配置项 | 说明 | + | -------------------------- | ------------------------------------------------------------ | + | num_uworkers | 非安全侧代理工作线程数,用于执行switchless OCALL,当前该字段仅在SGX平台生效,ARM平台可以配置,但是因ARM平台暂不支持OCALL,所以配置后不会生效。
规格:
ARM:最大值:512;最小值:1;缺省值:8(配置为0时)
SGX:最大值:4294967295;最小值:1 | + | num_tworkers | 安全侧代理工作线程数,用于执行switchless ECALL。
规格:
ARM:最大值:512;最小值:1;缺省值:8(配置为0时)
SGX:最大值:4294967295;最小值:1 | + | switchless_calls_pool_size | switchless调用任务池的大小,实际可容纳switchless_calls_pool_size * 64个switchless调用任务(例:switchless_calls_pool_size=1,可容纳64个switchless调用任务)。
规格:
ARM:最大值:8;最小值:1;缺省值:1(配置为0时)
SGX:最大值:8;最小值:1;缺省值:1(配置为0时) | + | retries_before_fallback | 执行retries_before_fallback次汇编pause指令后,若switchless调用仍没有被另一侧的代理工作线程执行,就回退到switch调用模式,该字段仅在SGX平台生效。
规格:SGX:最大值:4294967295;最小值:1;缺省值:20000(配置为0时) | + | retries_before_sleep | 执行retries_before_sleep次汇编pause指令后,若代理工作线程一直没有等到有任务来,则进入休眠状态,该字段仅在SGX平台生效。
规格: SGX:最大值:4294967295;最小值:1;缺省值:20000(配置为0时) | + | parameter_num | switchless函数支持的最大参数个数,该字段仅在ARM平台生效。
规格: ARM:最大值:16;最小值:0 | + | workers_policy | switchless代理线程运行模式,该字段仅在ARM平台生效。
规格: ARM: WORKERS_POLICY_BUSY:代理线程一直占用CPU资源,无论是否有任务需要处理,适用于对性能要求极高且系统软硬件资源丰富的场景; WORKERS_POLICY_WAKEUP:代理线程仅在有任务时被唤醒,处理完任务后进入休眠,等待再次被新任务唤醒 | + | rollback_to_common | 异步switchless调用失败时是否回退到普通调用,该字段仅在ARM平台生效。
规格: ARM:0:否,失败时仅返回相应错误码;其他:是,失败时回退到普通调用,此时返回普通调用的返回值 | + | num_cores | 用于设置安全侧线程绑核
规格: 最大值为当前环境CPU核数 | + +2. 定义EDL文件中接口时添加零切换标识transition_using_threads + + ```ocaml + enclave { + include "secgear_urts.h" + from "secgear_tstdc.edl" import *; + from "secgear_tswitchless.edl" import *; + trusted { + public int get_string([out, size=32]char *buf); + public int get_string_switchless([out, size=32]char *buf) transition_using_threads; + }; + }; + ``` + +### 安全通道 + +#### 客户痛点 + +数据拥有者在请求云上机密计算服务时,需要把待处理数据上传到云上TEE环境中处理,由于TEE没有网络,用户数据需要经过网络先传输到REE,REE接收到数据的明文后,再传入TEE中。用户数据的明文暴露在REE内存中,存在安全风险。 + +#### 解决方案 + +安全通道是一种结合机密计算远程证明,实现数据拥有者与云上TEE之间安全的密钥协商技术,协商出仅数据拥有者与云上TEE拥有的sessionkey,再通过sessionkey加密用户数据,网络传输的是sessionkey加密后的数据,REE接收到密文数据,再传入TEE中解密,处理。 + +#### 使用方法 + +安全通道以lib库方式提供,分为客户端、服务端host、服务端enclave三部分,分别由业务程序的客户端、服务端CA、服务端TA调用。 + +| 模块 | 头文件 | 库文件 | 依赖 | +|------------|--------------------------|-----------------------|---------| +| 客户端 | secure_channel_client.h | libcsecure_channel.so | openssl | +| 服务端host | secure_channel_host.h | libusecure_channel.so | openssl | +| 服务端enclave | secure_channel_enclave.h | libtsecure_channel.so | TEE及TEE软件栈 | + +##### 接口列表 + +| 接口名 | 所属头文件、库 | 功能 | 备注 | +|----------------------------------------------------------------------------------------------------------------------------------------------|-----------------------|--------------|----| +| cc_sec_chl_client_init | secure_channel_client.h libcsecure_channel.so | 安全通道客户端初始化 | 调用前需初始化参数ctx中网络连接和消息发送钩子函数 | +| cc_sec_chl_client_fini | secure_channel_client.h libcsecure_channel.so | 安全通道客户端销毁 | 通知服务端销毁本客户端的信息,销毁本地安全通道信息 | +| cc_sec_chl_client_callback | secure_channel_client.h libcsecure_channel.so | 安全通道协商消息处理函数 | 处理安全通道协商过程中,服务端发送给客户端的消息。在客户端消息接收处调用 | +| cc_sec_chl_client_encrypt | secure_channel_client.h libcsecure_channel.so | 安全通道客户端的加密接口 | 无 | +| cc_sec_chl_client_decrypt | secure_channel_client.h libcsecure_channel.so | 安全通道客户端的解密接口 | 无 | +| int (*cc_conn_opt_funcptr_t)(void*conn, void *buf, size_t count); | secure_channel.h | 消息发送钩子函数原型 | 由用户客户端和服务端实现,实现中指定安全通道协商消息类型,负责发送安全通道协商消息到对端 | +| cc_sec_chl_svr_init | secure_channel_host.h libusecure_channel.so | 安全通道服务端初始化 | 调用前需初始化ctx中enclave_ctx | +| cc_sec_chl_svr_fini | secure_channel_host.h libusecure_channel.so | 安全通道服务端销毁 | 销毁安全通道服务端以及所有客户端信息 | +| cc_sec_chl_svr_callback | secure_channel_host.h libusecure_channel.so | 安全通道协商消息处理函数 | 处理安全通道协商过程中,客户端发送给服务端的消息。在服务端消息接收处调用,调用前需初始化与客户端的网络连接和发送消息函数,详见[样例](https://gitee.com/openeuler/secGear/blob/master/examples/secure_channel/host/server.c#:~:text=conn_ctx.conn_kit.send)。 | +| cc_sec_chl_enclave_encrypt | secure_channel_enclave.h libtsecure_channel.so | 安全通道enclave中的加密接口 | 无 | +| cc_sec_chl_enclave_decrypt | secure_channel_enclave.h libtsecure_channel.so | 安全通道enclave中的解密接口 | 无 | + +##### 注意事项 + +安全通道仅封装密钥协商过程、加解密接口,不建立网络连接,协商过程复用业务的网络连接。其中客户端和服务端的网络连接由业务建立和维护,在安全通道客户端和服务端初始化时传入消息发送钩子函数和网络连接指针。 +详见[安全通道样例](https://gitee.com/openeuler/secGear/tree/master/examples/secure_channel)。 + +### 远程证明 + +#### 客户痛点 + +随着机密计算技术的发展,逐渐形成几大主流技术(如Arm Trustzone/CCA、Intel SGX/TDX、擎天Enclave、海光CSV等),产品解决方案中可能存在多种机密计算硬件,甚至不同TEE之间的协同,其中远程证明是任何一种机密计算技术信任链的重要一环,每种技术的远程证明报告格式及验证流程各有差异,用户对接不同的TEE,需要集成不同TEE证明报告的验证流程,增加了用户的集成负担,并且不利于扩展新的TEE类型。 + +#### 解决方案 + +secGear远程证明统一框架是机密计算远程证明相关的关键组件,屏蔽不同TEE远程证明差异,提供Attestation Agent和Attestation Service两个组件,Agent供用户集成获取证明报告,对接证明服务;Service可独立部署,支持iTrustee、virtCCA远程证明报告的验证。 + +#### 功能描述 + +远程证明统一框架聚焦机密计算相关功能,部署服务时需要的服务运维等相关能力由服务部署第三方提供。远程证明统一框架的关键技术如下: + +- 报告校验插件框架:支持运行时兼容iTrustee、vritCCA、CCA等不同TEE平台证明报告检验,支持扩展新的TEE报告检验插件。 +- 证书基线管理:支持对不同TEE类型的TCB/TA基线值管理及公钥证书管理,集中部署到服务端,对用户透明。 +- 策略管理:提供默认策略(易用)、用户定制策略(灵活)。 +- 身份令牌:支持对不同TEE签发身份令牌,由第三方信任背书,实现不同TEE类型相互认证。 +- 证明代理:支持对接证明服务/点对点互证,兼容TEE报告获取,身份令牌验证等,易集成,使用户聚焦业务。 + +根据使用场景,支持点对点验证和证明服务验证两种模式。 + +证明服务验证流程如下: + +1.用户(普通节点或TEE)对TEE平台发起挑战。 + +2.TEE平台通过证明代理获取TEE证明报告,并返回给用户。 + +3.用户端证明代理将报告转发到远程证明服务。 + +4.远程证明服务完成报告校验,返回由第三方信任背书的统一格式身份令牌。 + +5.证明代理验证身份令牌,并解析得到证明报告校验结果。 + +6.得到通过的校验结果后,建立安全连接。 + +点对点验证流程(无证明服务)如下: + +1.用户向TEE平台发起挑战,TEE平台返回证明报告给用户。 + +2.用户使用本地点对点TEE校验插件完成报告验证。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 点对点验证和远程证明服务验证时的证明代理不同,在编译时可通过编译选项,决定编译有证明服务和点对点模式的证明代理。 + +#### 应用场景 + +在金融、AI等场景下,基于机密计算保护运行中的隐私数据安全时,远程证明是校验机密计算环境及应用合法性的技术手段,远程证明统一框架提供了易集成、易部署的组件,帮助用户快速使能机密计算远程证明能力。 + +## 缩略语 + +| 缩略语 | 英文全名 | 中文解释 | +| ------ | ----------------------------- | ---------------- | +| REE | Rich Execution Environment | 富执行环境 | +| TEE | Trusted Execution Environment | 可信执行环境 | +| EDL | Enclave Description Language | 安全应用描述语言 | diff --git a/docs/en/25.03/Server/Security/secGear/public_sys-resources/icon-note.gif b/docs/en/25.03/Server/Security/secGear/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Server/Security/secGear/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Server/Security/secGear/secGear-installation.md b/docs/en/25.03/Server/Security/secGear/secGear-installation.md new file mode 100644 index 0000000000000000000000000000000000000000..e09cc33189491dfb96058cabc80f35f6443c9167 --- /dev/null +++ b/docs/en/25.03/Server/Security/secGear/secGear-installation.md @@ -0,0 +1,126 @@ +# 安装 secGear + +## ARM环境 + +### 环境要求 + +#### 硬件环境 + +| 项目 | 版本 | +| ------ | --------------------------------------------------- | +| 服务器 | TaiShan 200服务器(型号2280) | +| 主板 | 鲲鹏主板 | +| BMC | 1711单板(型号BC82SMMAB),固件版本不低于3.01.12.49 | +| CPU | 鲲鹏920处理器(型号7260、5250、5220) | +| 机箱 | 不限,建议8盘或12盘 | + +> ![img](./public_sys-resources/icon-note.gif)说明 +> +> - 要求服务器已经预置TrustZone特性套件,即预装TEE OS、TEE OS启动密钥、BMC、BIOS和License许可证。 +> - 普通服务器无法仅通过升级BMC、BIOS、TEE OS固件实现TrustZone特性使能。 +> - 带TrustZone特性的服务器出厂默认特性关闭,请参考BIOS设置使能服务器TrustZone特性。 + +#### 操作系统 + +openEuler 20.03 LTS SP2及以上 + +openEuler 22.09 + +openEuler 22.03 LTS及以上 + +### 环境准备 + + 参考鲲鹏官网[环境要求](https://www.hikunpeng.com/document/detail/zh/kunpengcctrustzone/fg-tz/kunpengtrustzone_20_0018.html)和[搭建步骤](https://www.hikunpeng.com/document/detail/zh/kunpengcctrustzone/fg-tz/kunpengtrustzone_20_0019.html)。 + +### 安装操作 + +1. 配置openEuler yum源,在线yum源或通过ISO挂载配置本地yum源,配置在线源如下(仅以22.03-LTS举例,其他版本需要使用版本对应的yum源)。 + + ```shell + vi /etc/yum.repo/openEuler.repo + [osrepo] + name=osrepo + baseurl=http://repo.openeuler.org/openEuler-22.03-LTS/everything/aarch64/ + enabled=1 + gpgcheck=1 + gpgkey=http://repo.openeuler.org/openEuler-22.03-LTS/everything/aarch64/RPM-GPG-KEY-openEuler + ``` + +2. 安装secGear + + ```shell + #安装编译工具 + yum install cmake ocaml-dune + + #安装secGear + yum install secGear-devel + + #检查是否安装成功。命令和回显如下表示安装成功。 + rpm -qa | grep -E 'secGear|itrustee|ocaml-dune' + itrustee_sdk-xxx + itrustee_sdk-devel-xxx + secGear-xxx + secGear-devel-xxx + ocaml-dune-xxx + ``` + +## X86环境 + +### 环境要求 + +#### 硬件环境 + +支持Intel SGX(Intel Software Guard Extensions) 特性的处理器。 + +#### 操作系统 + +openEuler 20.03 LTS SP2及以上 + +openEuler 22.09 + +openEuler 22.03 LTS及以上 + +### 环境准备 + +购买支持Intel SGX特性设备,参考对应设备BIOS配置手册,开启SGX特性。 + +### 安装操作 + +1. 配置openEuler yum源,在线yum源或通过ISO挂载配置本地yum源,配置在线源如下(仅以22.03-LTS举例,其他版本需要使用版本对应的yum源)。 + + ```shell + vi openEuler.repo + [osrepo] + name=osrepo + baseurl=http://repo.openeuler.org/openEuler-22.03-LTS/everything/x86_64/ + enabled=1 + gpgcheck=1 + gpgkey=http://repo.openeuler.org/openEuler-22.03-LTS/everything/x86_64/RPM-GPG-KEY-openEuler + ``` + +2. 安装secGear + + ```shell + #安装编译工具 + yum install cmake ocaml-dune + + #安装secGear + yum install secGear-devel + + #检查是否安装成功。命令和回显如下表示安装成功。 + rpm -qa | grep -E 'secGear|ocaml-dune|sgx' + secGear-xxx + secGear-devel-xxx + ocaml-dune-xxx + libsgx-epid-xxx + libsgx-enclave-common-xxx + libsgx-quote-ex-xxx + libsgx-aesm-launch-plugin-xxx + libsgx-uae-service-xxx + libsgx-ae-le-xxx + libsgx-urts-xxx + sgxsdk-xxx + sgx-aesm-service-xxx + linux-sgx-driver-xxx + libsgx-launch-xxx + ``` diff --git a/docs/en/25.03/Server/Security/secGear/secGear.md b/docs/en/25.03/Server/Security/secGear/secGear.md new file mode 100644 index 0000000000000000000000000000000000000000..cc36ca734bd0c308ad587af203ebf9e5d1516984 --- /dev/null +++ b/docs/en/25.03/Server/Security/secGear/secGear.md @@ -0,0 +1,5 @@ +# secGear 开发指南 + +本文档介绍openEuler机密计算统一开发框架secGear的架构、特性、安装、开发指导、落地应用场景等,帮助用户快速了解并使用secGear。 + +本文档适用于使用openEuler系统并希望了解和使用secGear的社区开发者、开源爱好者以及相关合作伙伴。使用人员需要具备基本的Linux操作系统知识。 diff --git a/docs/en/25.03/Server/Security/secGear/using-the-secGear-tool.md b/docs/en/25.03/Server/Security/secGear/using-the-secGear-tool.md new file mode 100644 index 0000000000000000000000000000000000000000..73d1425bb747c2dd69974d5d77b631f9fddec20c --- /dev/null +++ b/docs/en/25.03/Server/Security/secGear/using-the-secGear-tool.md @@ -0,0 +1,149 @@ +# 使用 secGear 工具 + +secGear 提供了一套工具集,方便用户开发应用程序。本章介绍相关工具及其使用方法。 + +## 代码生成工具 codegener + +### 简介 + +secGear codegener 是基于 intel SGX SDK edger8r 开发的工具,用于解析 EDL 文件生成中间 C 代码,即辅助生成安全侧与非安全侧文件互相调用的代码。 + +secGear codegener 定义的 EDL 文件格式与 intel SGX SDK edger8r 相同,但是不支持 Intel 的完整语法定义: + +- 只能在方法中使用 public,不加 public 的函数声明默认为 private +- 不支持从非安全侧到安全侧,以及安全侧到非安全侧的 Switchless Calls +- OCALL(Outside call) 不支持部分调用模式(如 cdecl,stdcall,fastcall) + +EDL 文件语法为类 C 语言语法,这里主要描述与 C 语言的差异部分: + +| 成员 | 含义 | +| ----------------------- | ------------------------------------------------------------ | +| include "my_type.h" | 使用外部包含文件中定义的类型 | +| trusted | 声明 TA(Trusted Application)侧可用安全函数 | +| untrusted | 声明 TA 侧可用不安全函数 | +| return_type | 定义返回值类型 | +| parameter_type | 定义参数类型 | +| [in, size = len] | 对ecall而言,表示该参数需要将数据从非安全侧传入安全侧,ocall反之(指针类型需要使用此参数,其中 size 表示实际使用的 buffer) | +| [out, size = len] | 对ecall而言,表示该参数需要将数据从安全侧传出到非安全侧,ocall反之(指针类型需要使用此参数,其中 size 表示实际使用的 buffer) | + +### 使用说明 + +#### **命令格式** + +codegen 的命令格式如下: + +- x86_64 架构: + +**codegen_x86_64** \< --trustzone | --sgx > [--trusted-dir \ | **--untrusted-dir** \| --trusted | --untrusted ] edlfile + +- ARM 架构: + +**codegen_arm64** \< --trustzone | --sgx > [--trusted-dir \ | **--untrusted-dir** \| --trusted | --untrusted ] edlfile + +#### **参数说明** + +各参数含义如下: + +| **参数** | 是否可选 | 参数含义 | +| ---------------------- | -------- | ------------------------------------------------------------ | +| --trustzone \| --sgx | 必选 | 只在当前运行命令目录下生成机密计算架构对应接口函数,不加参数默认生成 SGX 接口函数 | +| --search-path \ | 可选 | 用于指定被转译的edl文件所依赖文件的搜索路径 | +| --use-prefix | 可选 | 用于给代理函数名称加上前缀,前缀名为edl的文件名 | +| --header-only | 可选 | 指定代码生成工具只生成头文件 | +| --trusted-dir \ | 可选 | 指定生成安全侧辅助代码所在目录,不指定该参数默认为当前路径 | +| --untrusted-dir \ | 可选 | 指定生成非安全侧函数辅助代码所在目录 | +| --trusted | 可选 | 生成安全侧辅助代码 | +| --untrusted | 可选 | 生成非安全侧辅助代码 | +| edlfile | 必选 | 需要转译的 EDL 文件,例如 hello.edl | + +#### 示例 + +- 转译 *helloworld.edl* ,在 *enclave-directory* 下生成安全侧辅助代码,*host-directory* 下生成非安全辅助代码的命令示例如下: + +```shell +$ codegen_x86_64 --sgx --trusted-dir enclave-directory --untrusted-dir host-directory helloworld.edl +``` + +- 转译 *helloworld.edl* ,在当前目录生成安全侧辅助代码,不生成非安全辅助代码的命令示例如下: + +```shell +$ codegen_x86_64 --sgx --trusted helloworld.edl +``` + +- 转译 *helloworld.edl* ,在当前目录生成非安全侧辅助代码,不生成安全辅助代码的命令示例如下: + +```shell +$ codegen_x86_64 --sgx --untrusted helloworld.edl +``` + +- 转译 *helloworld.edl* ,在当前目录生成安全侧和非安全侧辅助代码的命令示例如下: + +```shell +$ codegen_x86_64 --sgx helloworld.edl +``` + +## 签名工具 sign_tool + +### 简介 + +secGear sign_tool 是一款命令行工具,包含编译工具链和签名工具,用于 enclave 签名。sign_tool 有两种签名形式: + +- 单步签名:仅适用于 debug 调试模式 +- 两步签名:商用场景。需要从第三方平台或者独立的安全设备获取签名私钥,对 enclave 进行签名 + +### 使用指导 + +#### **命令格式** + +sign_tool 包含 sign 指令(对 enclave 进行签名)和 digest 指令(生成摘要值)。命令格式为: + +**sign_tool.sh -d** [sign | digest] **-x** \ **-i** \ **-p** \ **-s** \ [OPTIONS] **–o** \ + +#### **参数说明** + +| sign 指令参数 | 参数含义 | 是否必选 | +| -------------- | -------------------------------------------------------------| -------------------------------------------- | +| -a \ | api_level,标识 iTrustee TA 的 GP API version,默认为 1 | 可选 | +| -c \ | 配置文件 | 可选 | +| -d \ | 指定签名工具要进行的操作( sign 或者 digest ) | 单步仅执行sign,两步需要先执行digest,再执行sign | +| -e \ | 设备的公钥证书,用于保护加密 rawdata 的 AES key (iTrustee必需) | 仅 iTrustee 类型必选 | +| -f \ | OTRP_FLAG,是否支持 OTRP 标准协议,默认为 0 | 可选 | +| -i \ | 待签名的库文件 | 必选 | +| -k \ | 单步签名所需私钥(pem文件) | 仅 SGX 类型必选 | +| -m \ | 安全配置文件 manifest.txt,由用户自行配置 | 仅 iTrustee 类型必选 | +| -o \ | 输出文件 | 必选 | +| -p \ | 两步签名所需的签名服务器公钥证书(pem文件) | 必选 | +| -s \ | 两步签名所需的已签名摘要值 | 必选 | +| -t \ | TA_TYPA,标识 iTrustee 的 TA 二进制格式,默认为 1 | 可选 | +| -x \ | encalve type(sgx 或 trustzone) | 必选 | +| -h | 打印帮助信息 | 可选 | + +#### **单步签名** + +enclave 类型为 SGX,给 test.enclave 签名,输出签名文件 signed.enclave 的示例如下: + +```shell +$ sign_tool.sh –d sign –x sgx –i test.enclave -k private_test.pem –o signed.enclave +``` + +#### **两步签名** + +以 SGX 为例,两步签名的操作步骤如下: + +1. 生成摘要值 + + 使用 sign_tool 签名,生成摘要值 digest.data 和临时中间文件 signdata(该文件在生成签名文件时使用,并在签名后自动删除)。参考命令如下: + + ```shell + $ sign_tool.sh –d digest –x sgx –i input –o digest.data + ``` + +2. 将 digest.data 发送至签名机构或平台,并获取对应签名。 + +3. 使用获取的签名生成签名后的动态库 signed.enclave。 + + ```shell + $ sign_tool.sh –d sign –x sgx–i input –p pub.pem –s signature –o signed.enclave + ``` + +说明:为发布 Intel SGX 支持的正式版本应用,需要申请 Intel 白名单。流程请参考 Intel 文档: diff --git a/docs/en/25.03/Server/_menu.md b/docs/en/25.03/Server/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..00bfb1fa416d6feaf28012ba366240a958451684 --- /dev/null +++ b/docs/en/25.03/Server/_menu.md @@ -0,0 +1,72 @@ +--- +label: '服务器' +children: + - label: '从这里开始' + children: + - reference: './Releasenotes/Releasenotes/_menu.md' + - reference: './Quickstart/Quickstart/_menu.md' + - label: '安装升级' + children: + - reference: './InstallationUpgrade/Installation/_menu.md' + - reference: './InstallationUpgrade/Upgrade/_menu.md' + - label: '系统管理' + children: + - reference: './Administration/Administrator/_menu.md' + - reference: './Administration/sysMaster/_menu.md' + - reference: './Administration/CompaCommand/_menu.md' + - label: '系统运维' + children: + - reference: './Maintenance/A-Ops/_menu.md' + - reference: './Maintenance/Gala/_menu.md' + - reference: './Maintenance/sysmonitor/_menu.md' + - reference: './Maintenance/KernelLiveUpgrade/_menu.md' + - reference: './Maintenance/SysCare/_menu.md' + - reference: './Maintenance/CommonSkills/_menu.md' + - reference: './Maintenance/CommonTools/_menu.md' + - reference: './Maintenance/Troubleshooting/_menu.md' + - label: '安全' + children: + - reference: './Security/SecHarden/_menu.md' + - reference: './Security/TrustedComputing/_menu.md' + - reference: './Security/secGear/_menu.md' + - reference: './Security/CVE-ease/_menu.md' + - reference: './Security/CertSignature/_menu.md' + - reference: './Security/Sbom/_menu.md' + - reference: './Security/ShangMi/_menu.md' + - label: '内存与存储' + children: + - reference: './MemoryandStorage/lvm/_menu.md' + - reference: './MemoryandStorage/etmem/_menu.md' + - reference: './MemoryandStorage/GMEM/_menu.md' + - reference: './MemoryandStorage/HSAK/_menu.md' + - label: '网络' + children: + - reference: './Network/NetworConfig/_menu.md' + - reference: './Network/Gazelle/_menu.md' + - label: '性能调优' + children: + - label: '概述' + children: + - reference: './Performance/Overall/systemResource/_menu.md' + - label: '调优框架' + children: + - reference: './Performance/TuningFramework/oeAware/_menu.md' + - label: 'CPU调优' + children: + - reference: './Performance/CPUOptimization/sysBoost/_menu.md' + - reference: './Performance/CPUOptimization/KAE/_menu.md' + - label: '系统调优' + children: + - reference: './Performance/SystemOptimization/A-Tune/_menu.md' + - label: '应用开发' + children: + - reference: './Development/ApplicationDev/_menu.md' + - reference: './Development/GCC/_menu.md' + - label: 'HA高可用' + children: + - reference: './HighAvailability/HA/_menu.md' + - label: '多样性算力' + children: + - reference: './DiversifiedComputing/DPUOffload/_menu.md' + - reference: './DiversifiedComputing/DPU-OS/_menu.md' +--- diff --git a/docs/en/25.03/Server/index.md b/docs/en/25.03/Server/index.md new file mode 100644 index 0000000000000000000000000000000000000000..5ca96954ed5fe35cf4f4056528de710c1d8ebb61 --- /dev/null +++ b/docs/en/25.03/Server/index.md @@ -0,0 +1,4 @@ +--- +title: 服务器 +overview: true +--- \ No newline at end of file diff --git a/docs/en/25.03/Tools/AI/AI_Container_Image_Userguide/_menu.md b/docs/en/25.03/Tools/AI/AI_Container_Image_Userguide/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..3684300c54e311a7021ed9f70f07fbd1e0a36174 --- /dev/null +++ b/docs/en/25.03/Tools/AI/AI_Container_Image_Userguide/_menu.md @@ -0,0 +1,8 @@ +--- +label: 'AI容器镜像用户指南' +ismanual: 'Y' +description: 'openEuler AI 容器镜像封装了 AI 框架等软件,提高 AI 应用开发或使用效率' +children: + - label: 'AI容器镜像用户指南' + href: './ai_container_image_user_guide.md' +--- diff --git a/docs/en/25.03/Tools/AI/AI_Container_Image_Userguide/ai_container_image_user_guide.md b/docs/en/25.03/Tools/AI/AI_Container_Image_Userguide/ai_container_image_user_guide.md new file mode 100644 index 0000000000000000000000000000000000000000..b433f2f4dcb8d609d014e8ecf3f77d37d5fe5773 --- /dev/null +++ b/docs/en/25.03/Tools/AI/AI_Container_Image_Userguide/ai_container_image_user_guide.md @@ -0,0 +1,101 @@ +# openEuler AI 容器镜像用户指南 + +## 简介 + +openEuler AI 容器镜像封装了不同硬件算力的 SDK 以及 AI 框架、大模型应用等软件,用户只需要在目标环境中加载镜像并启动容器,即可进行 AI 应用开发或使用,大大减少了应用部署和环境配置的时间,提升效率。 + +## 获取镜像 + +目前,openEuler 已发布支持 Ascend 和 NVIDIA 平台的容器镜像,获取路径如下: + +- [openeuler/cann](https://hub.docker.com/r/openeuler/cann) 存放 SDK 类镜像,在 openEuler 基础镜像之上安装 CANN 系列软件,适用于 Ascend 环境。 +- [openeuler/cuda](https://hub.docker.com/r/openeuler/cuda) 存放 SDK 类镜像,在 openEuler 基础镜像之上安装 CUDA 系列软件,适用于 NVIDIA 环境。 +- [openeuler/pytorch](https://hub.docker.com/r/openeuler/pytorch) 存放 AI 框架类镜像,在 SDK 镜像基础之上安装 PyTorch,根据安装的 SDK 软件内容区分适用平台。 +- [openeuler/tensorflow](https://hub.docker.com/r/openeuler/tensorflow) 存放 AI 框架类镜像,在 SDK 镜像基础之上安装 TensorFlow,根据安装的 SDK 软件内容区分适用平台。 +- [openeuler/llm](https://hub.docker.com/r/openeuler/tensorrt) 存放模型应用类镜像,在 AI 框架镜像之上包含特定大模型及工具链,根据安装的 SDK 软件内容区分适用平台。 + +详细的 AI 容器镜像分类和镜像 tag 的规范说明见[oEEP-0014](https://gitee.com/openeuler/TC/blob/master/oEEP/oEEP-0014%20openEuler%20AI容器镜像软件栈规范.md)。 + +由于 AI 容器镜像的体积一般较大,推荐用户在启动容器前先通过如下命令将镜像拉取到开发环境中。 + +```sh +docker pull image:tag +``` + +其中,`image`为仓库名,如`openeuler/cann`,`tag`为目标镜像的 TAG,待镜像拉取完成后即可启动容器。注意,使用`docker pull`命令需按照下文方法安装`docker`软件。 + +## 启动容器 + +1. 在环境中安装`docker`,官方安装方法见[Install Docker Engine](https://docs.docker.com/engine/install/),也可直接通过如下命令进行安装。 + + ```sh + yum install -y docker + ``` + + 或 + + ```sh + apt-get install -y docker + ``` + +2. NVIDIA环境安装`nvidia-container` + + 1)配置yum或apt repo + - 使用yum安装时,执行: + + ```sh + curl -s -L https://nvidia.github.io/libnvidia-container/stable/rpm/nvidia-container-toolkit.repo | \ + sudo tee /etc/yum.repos.d/nvidia-container-toolkit.repo + ``` + + - 使用apt安装时,执行: + + ```sh + curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg + ``` + + ```sh + curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \ + sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \ + sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list + ``` + + 2)安装`nvidia-container-toolkit`,`nvidia-container-runtime`,执行: + + ```sh + # yum安装 + yum install -y nvidia-container-toolkit nvidia-container-runtime + ``` + + ```sh + # apt安装 + apt-get install -y nvidia-container-toolkit nvidia-container-runtime + ``` + + 3)配置docker + + ```sh + nvidia-ctk runtime configure --runtime=docker + systemctl restart docker + ``` + + 非NVIDIA环境不执行此步骤。 + +3. 确保环境中安装`driver`及`firmware`,用户可从[NVIDIA](https://www.nvidia.com/)或[Ascend](https://www.hiascend.com/)官网获取正确版本进行安装。安装完成后 Ascend 平台使用`npu-smi`命令、NVIDIA 平台使用`nvidia-smi`进行测试,正确显示硬件信息则说明安装正常。 + +4. 完成上述操作后,即可使用`docker run`命令启动容器。 + +```sh +# Ascend环境启动容器 +docker run --rm --network host \ + --device /dev/davinci0:/dev/davinci0 \ + --device /dev/davinci_manager --device /dev/devmm_svm --device /dev/hisi_hdc \ + -v /usr/local/dcmi:/usr/local/dcmi -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ + -v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \ + -ti image:tag +``` + +```sh +# NVIDIA环境启动容器 +docker run --gpus all -d -ti image:tag +``` diff --git a/docs/en/25.03/Tools/AI/AI_Large_Model_Service_Images_Userguide/_menu.md b/docs/en/25.03/Tools/AI/AI_Large_Model_Service_Images_Userguide/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..2b0fe44bccfdcf0848fbe58cfe03e8a3ebf934ff --- /dev/null +++ b/docs/en/25.03/Tools/AI/AI_Large_Model_Service_Images_Userguide/_menu.md @@ -0,0 +1,8 @@ +--- +label: 'AI大模型服务镜像使用指南' +ismanual: 'Y' +description: '支持百川、chatglm、星火等AI大模型的容器化封装' +children: + - label: 'AI大模型服务镜像使用指南' + href: './llm_service_image_user_guide.md' +--- diff --git a/docs/en/25.03/Tools/AI/AI_Large_Model_Service_Images_Userguide/llm_service_image_user_guide.md b/docs/en/25.03/Tools/AI/AI_Large_Model_Service_Images_Userguide/llm_service_image_user_guide.md new file mode 100644 index 0000000000000000000000000000000000000000..c7c492b104b74e25ac87980c2d8580885a43df0e --- /dev/null +++ b/docs/en/25.03/Tools/AI/AI_Large_Model_Service_Images_Userguide/llm_service_image_user_guide.md @@ -0,0 +1,94 @@ +# 支持百川、chatglm、星火等AI大模型的容器化封装 + +已配好相关依赖,分为CPU和GPU版本,降低使用门槛,开箱即用。 + +## 拉取镜像(CPU版本) + +```bash +docker pull openeuler/llm-server:1.0.0-oe2203sp3 +``` + +## 拉取镜像(GPU版本) + +```bash +docker pull icewangds/llm-server:1.0.0 +``` + +## 下载模型, 并转换为gguf格式 + +```bash +# 安装huggingface +pip install huggingface-hub + +# 下载你想要部署的模型 +export HF_ENDPOINT=https://hf-mirror.com +huggingface-cli download --resume-download baichuan-inc/Baichuan2-13B-Chat --local-dir /root/models/Baichuan2-13B-Chat --local-dir-use-symlinks False + +# gguf格式转换 +cd /root/models/ +git clone https://github.com/ggerganov/llama.cpp.git +python llama.cpp/convert-hf-to-gguf.py ./Baichuan2-13B-Chat +# 生成的gguf格式的模型路径 /root/models/Baichuan2-13B-Chat/ggml-model-f16.gguf +``` + +## 启动方式 + +需要Docker v25.0.0及以上版本。 + +若使用GPU镜像,需要OS上安装nvidia-container-toolkit,安装方式见。 + +docker-compose.yaml: + +```yaml +version: '3' +services: + model: + image: : #镜像名称与tag + restart: on-failure:5 + ports: + - 8001:8000 #监听端口号,修改“8001”以更换端口 + volumes: + - /root/models:/models # 大模型挂载目录 + environment: + - MODEL=/models/Baichuan2-13B-Chat/ggml-model-f16.gguf # 容器内的模型文件路径 + - MODEL_NAME=baichuan13b # 自定义模型名称 + - KEY=sk-12345678 # 自定义API Key + - CONTEXT=8192 # 上下文大小 + - THREADS=8 # CPU线程数,仅CPU部署时需要 + deploy: # 指定GPU资源, 仅GPU部署时需要 + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [gpu] +``` + +```bash +docker-compose -f docker-compose.yaml up +``` + +docker run: + +```text +cpu部署: docker run -d --restart on-failure:5 -p 8001:8000 -v /root/models:/models -e MODEL=/models/Baichuan2-13B-Chat/ggml-model-f16.gguf -e MODEL_NAME=baichuan13b -e KEY=sk-12345678 openeuler/llm-server:1.0.0-oe2203sp3 + +gpu部署: docker run -d --gpus all --restart on-failure:5 -p 8001:8000 -v /root/models:/models -e MODEL=/models/Baichuan2-13B-Chat/ggml-model-f16.gguf -e MODEL_NAME=baichuan13b -e KEY=sk-12345678 icewangds/llm-server:1.0.0 +``` + +## 调用大模型接口测试,成功返回则表示大模型服务已部署成功 + +```bash +curl -X POST http://127.0.0.1:8001/v1/chat/completions \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer sk-12345678" \ + -d '{ + "model": "baichuan13b", + "messages": [ + {"role": "system", "content": "你是一个社区助手,请回答以下问题。"}, + {"role": "user", "content": "你是谁?"} + ], + "stream": false, + "max_tokens": 1024 + }' +``` diff --git a/docs/en/25.03/Tools/AI/_menu.md b/docs/en/25.03/Tools/AI/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..3b3f28be4cb12687b151ccc6b184bcdfc53d38ee --- /dev/null +++ b/docs/en/25.03/Tools/AI/_menu.md @@ -0,0 +1,7 @@ +--- +label: 'AI' +children: + - reference: './openEuler_Copilot_System/_menu.md' + - reference: './AI_Large_Model_Service_Images_Userguide/_menu.md' + - reference: './AI_Container_Image_Userguide/_menu.md' +--- diff --git a/docs/en/25.03/Tools/AI/index.md b/docs/en/25.03/Tools/AI/index.md new file mode 100644 index 0000000000000000000000000000000000000000..c816dbcef69ce63daedff57e91299aad652f0377 --- /dev/null +++ b/docs/en/25.03/Tools/AI/index.md @@ -0,0 +1,4 @@ +--- +title: AI +overview: true +--- \ No newline at end of file diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/README.md b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a638bb045dc491849703d639788f047d48b50484 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/README.md @@ -0,0 +1,42 @@ +# openEuler Copilot System + +## 功能描述 + +openEuler Copilot System 智能问答平台目前支持 Web 和智能 Shell 两个入口。 + +- Web 入口:操作简单,可咨询操作系统相关基础知识,openEuler 动态数据、openEuler 运维问题解决方案、openEuler 项目介绍与使用指导等等。 +- 智能 Shell 入口:自然语言和 openEuler 交互,启发式的运维。 + +## 应用场景 + +- 面向 openEuler 普通用户:深入了解 openEuler 相关知识和动态数据,比如咨询如何迁移到 openEuler。 +- 面向 openEuler 开发者:熟悉 openEuler 开发贡献流程、关键特性、相关项目的开发等知识。 +- 面向 openEuler 运维人员:熟悉 openEuler 常见或疑难问题的解决思路和方案、openEuler 系统管理知识和相关命令。 + +## 用户手册目录 + +### 部署手册 + +- [Web 端部署指南](#) + - [网络环境下部署指南](./deployment/deployment-guide-for-network-environment.md) + - [无网络环境下部署指南](./deployment/deployment-guide-for-offline-environment.md) + +- [插件部署指南](#) + - [智能调优](./deployment/plugin_deployment_guide/intelligent_tuning/plugin-intelligent-tuning-deployment-guide.md) + - [智能诊断](./deployment/plugin_deployment_guide/intelligent_diagnosis/plugin-intelligent-diagnosis-deployment-guide.md) + - [AI容器栈](./deployment/plugin_deployment_guide/ai_container_stack/plugin-ai-container-stack-deployment-guide.md) + +- [本地资产库构建指南](./deployment/local-asset-library-construction-guide.md) + +### 使用手册 + +- [Web 端 (Gitee AI) 使用手册](./usage_guide/online_service/foreword.md) + - [注册与登录](./usage_guide/online_service/registration-and-login.md) + - [智能问答](./usage_guide/online_service/intelligent-qa-usage-guide.md) + - [智能插件](./usage_guide/online_service/introduction-to-intelligent-plugins.md) + +- [智能 Shell 使用手册](./usage_guide/command_line_client/command-line-assistant-usage-guide.md) + - [准备工作:获取 API Key](./usage_guide/command_line_client/get-api-key.md) + - [智能插件](./usage_guide/command_line_client/command-line-assistant-usage-guide.md#智能插件) + - [智能调优](./usage_guide/command_line_client/intelligent-tuning.md) + - [智能诊断](./usage_guide/command_line_client/intelligent-diagnosis.md) diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/_menu.md b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..16063084b2fb94b175f2611ca7c374d4c8c07823 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/_menu.md @@ -0,0 +1,44 @@ +--- +label: 'openEuler Copilot System' +ismanual: 'Y' +description: '部署和使用 openEuler Copilot System 智能问答平台' +children: + - label: '使用指南' + children: + - label: '网页端' + children: + - label: '前言' + href: './usage_guide/online_service/foreword.md' + - label: '注册与登录' + href: './usage_guide/online_service/registration-and-login.md' + - label: '智能问答使用指南' + href: './usage_guide/online_service/intelligent-qa-usage-guide.md' + - label: '智能插件简介' + href: './usage_guide/online_service/introduction-to-intelligent-plugins.md' + - label: '命令行客户端' + children: + - label: '获取API Key' + href: './usage_guide/command_line_client/get-api-key.md' + - label: '命令行助手使用指南' + href: './usage_guide/command_line_client/command-line-assistant-usage-guide.md' + - label: '智能调优' + href: './usage_guide/command_line_client/intelligent-tuning.md' + - label: '智能诊断' + href: './usage_guide/command_line_client/intelligent-diagnosis.md' + - label: '部署指南' + children: + - label: '网络环境下部署指南' + href: './deployment/deployment-guide-for-network-environment.md' + - label: '无网络环境下部署指南' + href: './deployment/deployment-guide-for-offline-environment.md' + - label: '本地资产库构建指南' + href: './deployment/local-asset-library-construction-guide.md' + - label: '插件部署指南' + children: + - label: '智能调优' + href: './deployment/plugin_deployment_guide/intelligent_tuning/plugin-intelligent-tuning-deployment-guide.md' + - label: '智能诊断' + href: './deployment/plugin_deployment_guide/intelligent_diagnosis/plugin-intelligent-diagnosis-deployment-guide.md' + - label: 'AI容器栈' + href: './deployment/plugin_deployment_guide/ai_container_stack/plugin-ai-container-stack-deployment-guide.md' +--- diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/deployment-guide-for-network-environment.md b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/deployment-guide-for-network-environment.md new file mode 100644 index 0000000000000000000000000000000000000000..3c18fea39bf2b2c5324aecd4bb0661c80a8e6ecd --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/deployment-guide-for-network-environment.md @@ -0,0 +1,616 @@ +# 网络环境部署指南 + +## 介绍 + +openEuler Copilot System 是一款智能问答工具,使用 openEuler Copilot System 可以解决操作系统知识获取的便捷性,并且为OS领域模型赋能开发者及运维人员。作为获取操作系统知识,使能操作系统生产力工具 (如 A-Ops / A-Tune / x2openEuler / EulerMaker / EulerDevOps / StratoVirt / iSulad 等),颠覆传统命令交付方式,由传统命令交付方式向自然语义进化,并结合智能体任务规划能力,降低开发、使用操作系统特性的门槛。 + +### 组件介绍 + +| 组件 | 端口 | 说明 | +| ----------------------------- | --------------- | -------------------- | +| euler-copilot-framework | 8002 (内部端口) | 智能体框架服务 | +| euler-copilot-web | 8080 | 智能体前端界面 | +| euler-copilot-rag | 8005 (内部端口) | 检索增强服务 | +| euler-copilot-vectorize-agent | 8001 (内部端口) | 文本向量化服务 | +| mysql | 3306 (内部端口) | MySQL数据库 | +| redis | 6379 (内部端口) | Redis数据库 | +| postgres | 5432 (内部端口) | 向量数据库 | +| secret_inject | 无 | 配置文件安全复制工具 | + +## 环境要求 + +### 软件要求 + +| 类型 | 版本要求 | 说明 | +|------------| -------------------------------------|--------------------------------------| +| 操作系统 | openEuler 22.03 LTS 及以上版本 | 无 | +| K3s | >= v1.30.2,带有 Traefik Ingress 工具 | K3s 提供轻量级的 Kubernetes 集群,易于部署和管理 | +| Helm | >= v3.15.3 | Helm 是一个 Kubernetes 的包管理工具,其目的是快速安装、升级、卸载 openEuler Copilot System 服务 | +| python | >=3.9.9 | python3.9.9 以上版本为模型的下载和安装提供运行环境 | + +### 硬件要求 + +| 类型 | 硬件要求 | +|----------------| -----------------------------| +| 服务器 | 1台 | +| CPU | 鲲鹏或x86_64,>= 32 cores | +| RAM | >= 64GB | +| 存储 | >= 500 GB | +| GPU | Tesla V100 16GB,4张 | +| NPU | 910ProB、910B | + +注意: + +1. 若无 GPU 或 NPU 资源,建议通过调用 OpenAI 接口的方式来实现功能。(接口样例: 参考链接:[API-KEY的获取与配置](https://help.aliyun.com/zh/dashscope/developer-reference/acquisition-and-configuration-of-api-key?spm=a2c4g.11186623.0.0.30e7694eaaxxGa)) +2. 调用第三方 OpenAI 接口的方式不需要安装高版本的 python (>=3.9.9) +3. 英伟达 GPU 对 Docker 的支持必需要新版本 Docker (>= v25.4.0) +4. 如果k8s集群环境,则不需要单独安装k3s,要求version >= 1.28 + +### 部署视图 + +![部署图](./pictures/部署视图.png) + +## 获取 openEuler Copilot System + +- 从 openEuler Copilot System 的官方Git仓库 [euler-copilot-framework](https://gitee.com/openeuler/euler-copilot-framework) 下载最新的部署仓库 +- 如果您正在使用 Kubernetes,则不需要安装 k3s 工具。 + +```bash +# 下载目录以 home 为例 +cd /home +``` + +```bash +git clone https://gitee.com/openeuler/euler-copilot-framework.git +``` + +## 环境准备 + +设备需联网并符合 openEuler Copilot System 的最低软硬件要求。确认服务器、硬件、驱动等准备就绪后,即可开始环境准备工作。为了顺利进行后续操作,请按照指引,先进入我 +们的脚本部署目录,并且按照提供的操作步骤和脚本路径依次执行,以确保初始化成功。 + +```bash +# 进入部署脚本目录 +cd /home/euler-copilot-framework/euler-copilot-helm/scripts && tree +``` + +```bash +. +├── check_env.sh +├── download_file.sh +├── get_log.sh +├── install_tools.sh +└── prepare_docker.sh +``` + +| 序号 | 步骤内容 | 相关指令 | 说明 | +|-------------- |----------|---------------------------------------------|------------------------------------------ | +|1| 环境检查 | `bash check_env.sh` | 主要对服务器的主机名、DNS、防火墙设置、磁盘剩余空间大小、网络、检查SELinux的设置 | +|2| 文件下载 | `bash download_file.sh` | 模型bge-reranker-large、bge-mixed-mode下载 | +|3| 安装部署工具 | `bash install_tools.sh v1.30.2+k3s1 v3.15.3 cn` | 安装helm、k3s工具。注意:cn的使用是使用镜像站,可以去掉不用 | +|4| 大模型准备 | 提供第三方 OpenAI 接口或基于硬件本都部署大模型 | 本地部署大模型可参考附录部分 | + +## 安装 + +您的环境现已就绪,接下来即可启动 openEuler Copilot System 的安装流程。 + +- 下载目录以home为例,进入 openEuler Copilot System 仓库的 Helm 配置文件目录 + + ```bash + cd /home/euler-copilot-framework && ll + ``` + + ```bash + total 28 + drwxr-xr-x 3 root root 4096 Aug 28 17:45 docs/ + drwxr-xr-x 5 root root 4096 Aug 28 17:45 euler-copilot-helm/ + ``` + +- 查看euler-copilot-helm的目录 + + ```bash + tree euler-copilot-helm + ``` + + ```bash + euler-copilot-helm/chart + ├── databases + │   ├── Chart.yaml + │   ├── configs + │   ├── templates + │   └── values.yaml + ├── authhub + │   ├── Chart.yaml + │   ├── configs + │   ├── templates + │   └── values.yaml + └── euler_copilot + ├── Chart.yaml + ├── configs + ├── templates + │   ├── NOTES.txt + │   ├── rag + │   ├── vectorize + │   └── web + └── values.yaml + ``` + +### 1. 安装数据库 + +- 编辑 values.yaml + + ```bash + cd euler-copilot-helm/chart/databases + ``` + + 仅需修改镜像tag为对应架构,其余可不进行修改 + + ```bash + vim values.yaml + ``` + +- 创建命名空间 + + ```bash + kubectl create namespace euler-copilot + ``` + + 设置环境变量 + + ```bash + export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + ``` + +- 安装数据库 + + ```bash + helm install -n euler-copilot databases . + ``` + +- 查看 pod 状态 + + ```bash + kubectl -n euler-copilot get pods + ``` + + ```bash + pgsql-deploy-databases-86b4dc4899-ppltc 1/1 Running 0 17d + redis-deploy-databases-f8866b56-kj9jz 1/1 Running 0 17d + mysql-deploy-databases-57f5f94ccf-sbhzp 2/2 Running 0 17d + ``` + +- 若服务器之前部署过 mysql,则可预先清除下 pvc,再部署 databases。 + + ```bash + # 获取pvc + kubectl -n euler-copilot get pvc + ``` + + ```bash + # 删除pvc + kubectl -n euler-copilot delete pvc mysql-pvc + ``` + +### 2. 安装鉴权平台Authhub + +- 编辑 values.yaml + + ```bash + cd euler-copilot-helm/chart/authhub + ``` + + 请结合 YAML 中的注释中的[必填]项进行修改 + + ```bash + vim values.yaml + ``` + + - 注意: + 1. authHub 需要域名,可预先申请域名或在 'C:\Windows\System32\drivers\etc\hosts' 下配置。 + authhub和euler-copilot必须是同一个根域名的两个子域名, 例如authhub.test.com和 + eulercopilot.test.com + 2. 修改tag为对应架构的tag; + +- 安装 AuthHub + + ```bash + helm install -n euler-copilot authhub . + ``` + + AuthHub 默认账号 `administrator`, 密码 `changeme` + +- 查看 pod 状态 + + ```bash + kubectl -n euler-copilot get pods + ``` + + ```bash + NAME READY STATUS RESTARTS AGE + authhub-backend-deploy-authhub-64896f5cdc-m497f 2/2 Running 0 16d + authhub-web-deploy-authhub-7c48695966-h8d2p 1/1 Running 0 17d + pgsql-deploy-databases-86b4dc4899-ppltc 1/1 Running 0 17d + redis-deploy-databases-f8866b56-kj9jz 1/1 Running 0 17d + mysql-deploy-databases-57f5f94ccf-sbhzp 2/2 Running 0 17d + ``` + +- 登录 AuthHub + + AuthHub 的域名以 authhub.test.com 为例,浏览器输入, 登录界面如下图所示: + + ![部署图](./pictures/authhub登录界面.png) + +- 创建应用eulercopilot + + ![部署图](./pictures/创建应用界面.png) + 点击创建应用,输入应用名称、应用主页和应用回调地址(登录后回调地址),参考如下: + - 应用名称:eulercopilot + - 应用主页: + - 应用回调地址: + - 应用创建好后会生成 Client ID 和 Client Secret,将生成的 Client ID 和 Client Secret 配置到应用里,以 eulercopilot 为例,创建应用后在配置文件中添加配置 `euler-copilot-helm/chart/euler_copilot/values.yaml` 中添加配置 + + ![部署图](./pictures/创建应用成功界面.png) + +### 2. 安装 openEuler Copilot System + +- 编辑 values.yaml + + ```bash + cd euler-copilot-helm/chart/euler_copilot + ``` + + 请结合 YAML 中的注释中的[必填]项进行修改 + + ```bash + vim values.yaml + ``` + + - 注意: + 1. 查看系统架构,并修改values.yaml中的tag; + 2. 修改values.yaml中的globals的domain为EulerCopilot域名,并配置大模型的相关信息 + 3. 手动创建`docs_dir`、`plugin_dir`、`models`三个文件挂载目录 + 4. 修改values.yaml中framework章节的web_url和oidc设置 + 5. 如果部署插件,则需要配置用于Function Call的模型,此时必须有GPU环境用于部署sglang,可参考附件 + +- 安装 openEuler Copilot System + + ```bash + helm install -n euler-copilot service . + ``` + +- 查看 Pod 状态 + + ```bash + kubectl -n euler-copilot get pods + ``` + + 镜像拉取过程可能需要大约一分钟的时间,请耐心等待。部署成功后,所有 Pod 的状态应显示为 Running。 + + ```bash + NAME READY STATUS RESTARTS AGE + authhub-backend-deploy-authhub-64896f5cdc-m497f 2/2 Running 0 16d + authhub-web-deploy-authhub-7c48695966-h8d2p 1/1 Running 0 17d + pgsql-deploy-databases-86b4dc4899-ppltc 1/1 Running 0 17d + redis-deploy-databases-f8866b56-kj9jz 1/1 Running 0 17d + mysql-deploy-databases-57f5f94ccf-sbhzp 2/2 Running 0 17d + framework-deploy-service-bb5b58678-jxzqr 2/2 Running 0 16d + rag-deploy-service-5b7887644c-sm58z 2/2 Running 0 110m + vectorize-deploy-service-57f5f94ccf-sbhzp 2/2 Running 0 17d + web-deploy-service-74fbf7999f-r46rg 1/1 Running 0 2d + ``` + + 注意:如果 Pod 状态出现失败,建议按照以下步骤进行排查 + + 1. 查看 Kubernetes 集群的事件 (Events),以获取更多关于 Pod 失败的上下文信息 + + ```bash + kubectl -n euler-copilot get events + ``` + + 2. 查看镜像拉取是否成功 + + ```bash + k3s crictl images + ``` + + 3. 检查 RAG 的 Pod 日志,以确定是否有错误信息或异常行为。 + + ```bash + kubectl logs rag-deploy-service-5b7887644c-sm58z -n euler-copilot + ``` + + 4. 验证 Kubernetes 集群的资源状态,检查服务器资源或配额是否足够,资源不足常导致 Pod 镜像服拉取失败。 + + ```bash + df -h + ``` + + 5. 如果未拉取成且镜像大小为0,请检查是否是 k3s 版本未满足要求,低于 v1.30.2 + + ```bash + k3s -v + ``` + + 6. 确认 values.yaml 中 framework 的 OIDC 设置是否正确配置,以确保身份验证和授权功能正常工作。 + + ```bash + vim /home/euler-copilot-framework/euler-copilot-helm/chart/euler_copilot/values.yaml + ``` + +## 验证安装 + +恭喜您,openEuler Copilot System 的部署已完成!现在,您可以开启智能问答的非凡体验之旅了。 +请在浏览器中输入 (其中 port 默认值为8080,若更改则需相应调整)访问 openEuler Copilot System 网页,并尝试进行问答体验。 + +![Web 界面](./pictures/WEB界面.png) + +## 安装插件 + +详细信息请参考文档 [插件部署指南](../README.md#部署手册) + +## 构建专有领域智能问答 + +### 1. 构建 openEuler 专业知识领域的智能问答 + +1. 修改 values.yaml 的 pg 的镜像仓为 `pg-data` +2. 修改 values.yaml 的 rag 部分的字段 `knowledgebaseID: openEuler_2bb3029f` +3. 将 `vim euler-copilot-helm/chart/databases/templates/pgsql/pgsql-deployment.yaml` 的 volumes 相关字段注释 +4. 进入 `cd euler-copilot-helm/chart/databases`,执行更新服务 `helm upgrade -n euler-copilot databases .` +5. 进入 `cd euler-copilot-helm/chart/euler_copilot`,执行更新服务 `helm upgrade -n euler-copilot service .` +6. 进入网页端进行 openEuler 专业知识领域的问答 + +### 2. 构建项目专属知识领域智能问答 + +详细信息请参考文档 [本地资产库构建指南](./local-asset-library-construction-guide.md) + +## 附录 + +### 大模型准备 + +#### GPU 环境 + +参考以下方式进行部署 + +1. 下载模型文件: + + ```bash + huggingface-cli download --resume-download Qwen/Qwen1.5-14B-Chat --local-dir Qwen1.5-14B-Chat + ``` + +2. 创建终端 control + + ```bash + screen -S control + ``` + + ```bash + python3 -m fastchat.serve.controller + ``` + + - 按 Ctrl A+D 置于后台 + +3. 创建新终端 api + + ```bash + screen -S api + ``` + + ```bash + python3 -m fastchat.serve.openai_api_server --host 0.0.0.0 --port 30000 --api-keys sk-123456 + ``` + + - 按 Ctrl A+D 置于后台 + - 如果当前环境的 Python 版本是 3.12 或者 3.9 可以创建 python3.10 的 conda 虚拟环境 + + ```bash + mkdir -p /root/py310 + ``` + + ```bash + conda create --prefix=/root/py310 python==3.10.14 + ``` + + ```bash + conda activate /root/py310 + ``` + +4. 创建新终端 worker + + ```bash + screen -S worker + ``` + + ```bash + screen -r worker + ``` + + 安装 fastchat 和 vllm + + ```bash + pip install fschat vllm + ``` + + 安装依赖: + + ```bash + pip install fschat[model_worker] + ``` + + ```bash + python3 -m fastchat.serve.vllm_worker --model-path /root/models/Qwen1.5-14B-Chat/ --model-name qwen1.5 --num-gpus 8 --gpu-memory-utilization=0.7 --dtype=half + ``` + + - 按 Ctrl A+D 置于后台 + +5. 按照如下方式配置文件,并更新服务。 + + ```bash + vim euler-copilot-helm/chart/euler_copilot/values.yaml + ``` + + 修改如下部分 + + ```yaml + llm: + # 开源大模型,OpenAI兼容接口 + openai: + url: "http://$(IP):30000" + key: "sk-123456" + model: qwen1.5 + max_tokens: 8192 + ``` + +#### NPU 环境 + +NPU 环境部署可参考链接 [MindIE安装指南](https://www.hiascend.com/document/detail/zh/mindie/10RC2/whatismindie/mindie_what_0001.html) + +## FAQ + +### 1. huggingface 使用报错 + +```text +File "/usr/lib/python3.9/site-packages/urllib3/connection.py", line 186, in _new_conn +raise NewConnectionError( +urllib3.exceptions.eanconectionError: : Failed to establish a new conmection: [Errno 101] Network is unreachable +``` + +- 解决办法 + +```bash +pip3 install -U huggingface_hub +``` + +```bash +export HF_ENDPOINT=https://hf-mirror.com +``` + +### 2. 如何在 RAG 容器中调用获取问答结果的接口 + +- 请先进入到 RAG 对应 Pod + +```bash +curl -k -X POST "http://localhost:8005/kb/get_answer" -H "Content-Type: application/json" -d '{ \ + "question": "", \ + "kb_sn": "default_test", \ + "fetch_source": true }' +``` + +### 3. 执行 `helm upgrade` 报错 + +```text +Error: INSTALLATI0N FAILED: Kubernetes cluster unreachable: Get "http:/localhost:880/version": dial tcp [:1:8089: connect: connection refused +``` + +或者 + +```text +Error: UPGRADE FAILED: Kubernetes cluster unreachable: the server could not find the requested resource +``` + +- 解决办法 + +```bash +export KUBECONFIG=/etc/rancher/k3s/k3s.yaml +``` + +### 4. 无法查看 Pod 日志 + +```text +[root@localhost euler-copilot]# kubectl logs rag-deployservice65c75c48d8-44vcp-n euler-copilotDefaulted container "rag" out of: rag.rag-copy secret (init)Error from server: Get "https://172.21.31.11:10250/containerlogs/euler copilot/rag deploy"service 65c75c48d8-44vcp/rag": Forbidden +``` + +- 解决办法 + 如果设置了代理,需要将本机的网络 IP 从代理中剔除 + +```bash +cat /etc/systemd/system/k3s.service.env +``` + +```text +http_proxy="http://172.21.60.51:3128" +https_proxy="http://172.21.60.51:3128" +no_proxy=172.21.31.10 # 代理中剔除本机IP +``` + +### 5. GPU环境部署大模型时出现无法流式回复 + +在服务执行 curl 大模型失败,但是将 `"stream": true` 改为 `"stream": false`就可以 curl 通? + +```bash +curl http://localhost:30000/v1/chat/completions -H "Content-Type: application/json" -H "Authorization: Bearer sk-123456" -d '{ +"model": "qwen1.5", +"messages": [ +{ +"role": "system", +"content": "你是情感分析专家,你的任务是xxxx" +}, +{ +"role": "user", +"content": "你好" +} +], +"stream": true, +"n": 1, +"max_tokens": 32768 +}' +``` + +- 解决办法: + +```bash +pip install Pydantic=1.10.13 +``` + +### 6. 如何部署sglang + +```bash +# 1. 激活 Conda 环境, 并激活 Python 3.10 的 Conda 环境。假设你的环境名为 `myenv`: +conda activate myenv + +# 2. 在激活的环境中,安装 sglang[all] 和 flashinfer +pip install sglang[all]==0.3.0 +pip install flashinfer -i https://flashinfer.ai/whl/cu121/torch2.4/ + +# 3. 启动服务器 +python -m sglang.launch_server --served-model-name Qwen2.5-32B --model-path Qwen2.5-32B-Instruct-AWQ --host 0.0.0.0 --port 8001 --api-key sk-12345 --mem-fraction-static 0.5 --tp 8 +``` + +- 验证安装 + +```bash +pip show sglang +pip show flashinfer +``` + +- 注意: + +1. API Key:请确保 `--api-key` 参数中的 API 密钥是正确的 +2. 模型路径: 确保 `--model-path` 参数中的路径是正确的,并且模型文件存在于该路径下。 +3. CUDA 版本:确保你的系统上安装了 CUDA 12.1 和 PyTorch 2.4,因为 `flashinfer` 包依赖于这些特定版本。 +4. 线程池大小:根据你的GPU资源和预期负载调整线程池大小。如果你有 8 个 GPU,那么可以选择 --tp 8 来充分利用这些资源。 + +### 7. 如何 curl embedding + +```bash +curl -k -X POST http://$IP:8001/embedding \ + -H "Content-Type: application/json" \ + -d '{"texts": ["sample text 1", "sample text 2"]}' +# $IP为vectorize的Embedding的内网地址 +``` + +### 8. 如何生成证书 + +```bash +下载地址: https://github.com/FiloSottile/mkcert/releases +# 1. 下载 mkcert +# x86_64 +wget https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-amd64 +# arm64 +wget https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-arm64 +# 2. 执行下面的命令生成秘钥 +mkcert -install +# mkcert 可直接接域名或 IP, 生成证书和秘钥 +mkcert example.com +# 3. 将证书和秘钥拷贝到 `/home/euler-copilot-framework_openeuler/euler-copilot-helm/chart_ssl/traefik-secret.yaml` 中, 并执行下面命令使其生效。 +kubectl apply -f traefik-secret.yaml +``` diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/deployment-guide-for-offline-environment.md b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/deployment-guide-for-offline-environment.md new file mode 100644 index 0000000000000000000000000000000000000000..820020ca5508c4e36117c4b7d1b16ec49fe21890 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/deployment-guide-for-offline-environment.md @@ -0,0 +1,732 @@ +# 无网络环境下部署指南 + +## 介绍 + +openEuler Copilot System 是一款智能问答工具,使用 openEuler Copilot System 可以解决操作系统知识获取的便捷性,并且为OS领域模型赋能开发者及运维人员。作为获取操作系统知识,使能操作系统生产力工具 (如 A-Ops / A-Tune / x2openEuler / EulerMaker / EulerDevOps / StratoVirt / iSulad 等),颠覆传统命令交付方式,由传统命令交付方式向自然语义进化,并结合智能体任务规划能力,降低开发、使用操作系统特性的门槛。 + +### 组件介绍 + +| 组件 | 端口 | 说明 | +| ----------------------------- | --------------- | -------------------- | +| euler-copilot-framework | 8002 (内部端口) | 智能体框架服务 | +| euler-copilot-web | 8080 | 智能体前端界面 | +| euler-copilot-rag | 8005 (内部端口) | 检索增强服务 | +| euler-copilot-vectorize-agent | 8001 (内部端口) | 文本向量化服务 | +| mysql | 3306 (内部端口) | MySQL数据库 | +| redis | 6379 (内部端口) | Redis数据库 | +| postgres | 5432 (内部端口) | 向量数据库 | +| secret_inject | 无 | 配置文件安全复制工具 | + +## 环境要求 + +### 软件要求 + +| 类型 | 版本要求 | 说明 | +|------------| -------------------------------------|--------------------------------------| +| 操作系统 | openEuler 22.03 LTS 及以上版本 | 无 | +| K3s | >= v1.30.2,带有 Traefik Ingress 工具 | K3s 提供轻量级的 Kubernetes 集群,易于部署和管理 | +| Helm | >= v3.15.3 | Helm 是一个 Kubernetes 的包管理工具,其目的是快速安装、升级、卸载 openEuler Copilot System 服务 | +| python | >=3.9.9 | python3.9.9 以上版本为模型的下载和安装提供运行环境 | + +### 硬件要求 + +| 类型 | 硬件要求 | +|----------------| -----------------------------| +| 服务器 | 1台 | +| CPU | 鲲鹏或x86_64,>= 32 cores | +| RAM | >= 64GB | +| 存储 | >= 500 GB | +| GPU | Tesla V100 16GB,4张 | +| NPU | 910ProB、910B | + +注意: + +1. 若无 GPU 或 NPU 资源,建议通过调用 OpenAI 接口的方式来实现功能。(接口样例:) +2. 调用第三方 OpenAI 接口的方式不需要安装高版本的 python (>=3.9.9) +3. 英伟达 GPU 对 Docker 的支持必需要新版本 Docker (>= v25.4.0) + +### 部署视图 + +![部署图](./pictures/部署视图.png) + +## 获取 openEuler Copilot System + +- 从 openEuler Copilot System 的官方Git仓库 [euler-copilot-framework](https://gitee.com/openeuler/euler-copilot-framework) 下载最新的部署仓库 +- 如果您正在使用 Kubernetes,则不需要安装 k3s 工具。 + + ```bash + # 下载目录以 home 为例 + cd /home + ``` + + ```bash + git clone https://gitee.com/openeuler/euler-copilot-framework.git + ``` + +## 环境准备 + +如果您的服务器、硬件、驱动等全部就绪,即可启动环境初始化流程,以下部署步骤在无公网环境执行。 + +### 1. 环境检查 + +环境检查主要是对服务器的主机名、DNS、防火墙设置、磁盘剩余空间大小、网络、检查 SELinux 的设置。 + +- 主机名设置 + 在Shell中运行如下命令: + + ```bash + cat /etc/hostname + echo "主机名" > /etc/hostname + ``` + +- 系统DNS设置:需要给当前主机设置有效的DNS +- 防火墙设置 + + ```bash + # 查看防火墙状态 + systemctl status firewalld + # 查看防火墙列表 + firewall-cmd --list-all + # 关闭防火墙 + systemctl stop firewalld + systemctl disable firewalld + ``` + +- SELinux设置 + + ```bash + # 需要关闭selinux,可以临时关闭或永久关闭 + # 永久关闭SELinux + sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config + # 临时关闭 + setenforce 0 + ``` + +### 2. 文件下载 + +- 模型文件 bge-reranker-large、bge-mixed-model 下载 [模型文件下载链接](https://repo.oepkgs.net/openEuler/rpm/openEuler-22.03-LTS/contrib/EulerCopilot/) + + ```bash + mkdir -p /home/EulerCopilot/models + cd /home/EulerCopilot/models + # 将需要下载的bge文件放置在models目录 + wget https://repo.oepkgs.net/openEuler/rpm/openEuler-22.03-LTS/contrib/EulerCopilot/bge-mixed-model.tar.gz + wget https://repo.oepkgs.net/openEuler/rpm/openEuler-22.03-LTS/contrib/EulerCopilot/bge-reranker-large.tar.gz + ``` + +- 下载分词工具 text2vec-base-chinese-paraphrase [分词工具下载链接](https://repo.oepkgs.net/openEuler/rpm/openEuler-22.03-LTS/contrib/EulerCopilot/) + + ```bash + mkdir -p /home/EulerCopilot/text2vec + cd /home/EulerCopilot/text2vec + wget https://repo.oepkgs.net/openEuler/rpm/openEuler-22.03-LTS/contrib/EulerCopilot/text2vec-base-chinese-paraphrase.tar.gz + ``` + +- 镜像包下载 + - x86或arm架构的EulerCopilot服务的各组件镜像单独提供 + +### 3. 安装部署工具 + +#### 3.1 安装 Docker + +如需要基于 GPU/NPU 部署大模型,需要检查 Docker 版本是否满足>= v25.4.0 ,如不满足,请升级 Docker 版本 + +#### 3.2 安装 K3s 并导入镜像 + +- 安装 SELinux 配置文件 + + ```bash + yum install -y container-selinux selinux-policy-base + # packages里有k3s-selinux-0.1.1-rc1.el7.noarch.rpm的离线包 + rpm -i https://rpm.rancher.io/k3s-selinux-0.1.1-rc1.el7.noarch.rpm + ``` + +- x86 架构安装 k3s + + ```bash + # 在有网络的环境上获取k3s相关包,以v1.30.3+k3s1示例 + wget https://github.com/k3s-io/k3s/releases/download/v1.30.3%2Bk3s1/k3s + wget https://github.com/k3s-io/k3s/releases/download/v1.30.3%2Bk3s1/k3s-airgap-images-amd64.tar.zst + cp k3s /usr/local/bin/ + cd /var/lib/rancher/k3s/agent + mkdir images + cp k3s-airgap-images-arm64.tar.zst /var/lib/rancher/k3s/agent/images + # packages里有k3s-install.sh的离线包 + curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh + INSTALL_K3S_SKIP_DOWNLOAD=true ./k3s-install.sh + export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + ``` + +- arm 架构安装 k3s + + ```bash + # 在有网络的环境上获取k3s相关包,以v1.30.3+k3s1示例 + wget https://github.com/k3s-io/k3s/releases/download/v1.30.3%2Bk3s1/k3s-arm64 + wget https://github.com/k3s-io/k3s/releases/download/v1.30.3%2Bk3s1/k3s-airgap-images-arm64.tar.zst + cp k3s-arm64 /usr/local/bin/k3s + cd /var/lib/rancher/k3s/agent + mkdir images + cp k3s-airgap-images-arm64.tar.zst /var/lib/rancher/k3s/agent/images + # packages里有k3s-install.sh的离线包 + curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh + INSTALL_K3S_SKIP_DOWNLOAD=true ./k3s-install.sh + export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + ``` + +- 导入镜像 + + ```bash + # 导入已下载的镜像文件 + k3s ctr image import $(镜像文件) + ``` + +#### 3.3 安装 Helm 工具 + +- x86_64 架构 + + ```bash + wget https://get.helm.sh/helm-v3.15.0-linux-amd64.tar.gz + tar -xzf helm-v3.15.0-linux-amd64.tar.gz + mv linux-amd64/helm /usr/sbin + rm -rf linux-amd64 + ``` + +- arm64 架构 + + ```bash + wget https://get.helm.sh/helm-v3.15.0-linux-arm64.tar.gz + tar -xzf helm-v3.15.0-linux-arm64.tar.gz + mv linux-arm64/helm /usr/sbin + rm -rf linux-arm64 + ``` + +#### 3.4 大模型准备 + +提供第三方openai接口或基于硬件本都部署大模型,本地部署大模型可参考附录部分。 + +## 安装 + +您的环境现已就绪,接下来即可启动 openEuler Copilot System 的安装流程。 + +- 下载目录以home为例,进入 openEuler Copilot System 仓库的 Helm 配置文件目录 + + ```bash + cd /home/euler-copilot-framework && ll + ``` + + ```bash + total 28 + drwxr-xr-x 3 root root 4096 Aug 28 17:45 docs/ + drwxr-xr-x 5 root root 4096 Aug 28 17:45 euler-copilot-helm/ + ``` + +- 查看euler-copilot-helm的目录 + + ```bash + tree euler-copilot-helm + ``` + + ```bash + euler-copilot-helm/chart + ├── databases + │   ├── Chart.yaml + │   ├── configs + │   ├── templates + │   └── values.yaml + ├── authhub + │   ├── Chart.yaml + │   ├── configs + │   ├── templates + │   └── values.yaml + └── euler_copilot + ├── Chart.yaml + ├── configs + ├── templates + │   ├── NOTES.txt + │   ├── rag + │   ├── vectorize + │   └── web + └── values.yaml + ``` + +### 1. 安装数据库 + +- 编辑 values.yaml + + ```bash + cd euler-copilot-helm/chart/databases + ``` + + 仅需修改镜像tag为对应架构,其余可不进行修改 + + ```bash + vim values.yaml + ``` + +- 创建命名空间 + + ```bash + kubectl create namespace euler-copilot + ``` + + 设置环境变量 + + ```bash + export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + ``` + +- 安装数据库 + + ```bash + helm install -n euler-copilot databases . + ``` + +- 查看 pod 状态 + + ```bash + kubectl -n euler-copilot get pods + ``` + + ```bash + pgsql-deploy-databases-86b4dc4899-ppltc 1/1 Running 0 17d + redis-deploy-databases-f8866b56-kj9jz 1/1 Running 0 17d + mysql-deploy-databases-57f5f94ccf-sbhzp 2/2 Running 0 17d + ``` + +- 若服务器之前部署过 mysql,则可预先清除下 pvc,再部署 databases。 + + ```bash + # 获取pvc + kubectl -n euler-copilot get pvc + ``` + + ```bash + # 删除pvc + kubectl -n euler-copilot delete pvc mysql-pvc + ``` + +### 2. 安装鉴权平台Authhub + +- 编辑 values.yaml + + ```bash + cd euler-copilot-helm/chart/authhub + ``` + + 请结合 YAML 中的注释中的[必填]项进行修改 + + ```bash + vim values.yaml + ``` + + - 注意: + 1. authHub 需要域名,可预先申请域名或在 'C:\Windows\System32\drivers\etc\hosts' 下配置。 + authhub和euler-copilot必须是同一个根域名的两个子域名, 例如authhub.test.com和 + eulercopilot.test.com + 2. 修改tag为对应架构的tag; + +- 安装 AuthHub + + ```bash + helm install -n euler-copilot authhub . + ``` + + AuthHub 默认账号 `administrator`, 密码 `changeme` + +- 查看 pod 状态 + + ```bash + kubectl -n euler-copilot get pods + ``` + + ```bash + NAME READY STATUS RESTARTS AGE + authhub-backend-deploy-authhub-64896f5cdc-m497f 2/2 Running 0 16d + authhub-web-deploy-authhub-7c48695966-h8d2p 1/1 Running 0 17d + pgsql-deploy-databases-86b4dc4899-ppltc 1/1 Running 0 17d + redis-deploy-databases-f8866b56-kj9jz 1/1 Running 0 17d + mysql-deploy-databases-57f5f94ccf-sbhzp 2/2 Running 0 17d + ``` + +- 登录 AuthHub + + AuthHub 的域名以 authhub.test.com 为例,浏览器输入, 登录界面如下图所示: + + ![部署图](./pictures/authhub登录界面.png) + +- 创建应用eulercopilot + + ![部署图](./pictures/创建应用界面.png) + 点击创建应用,输入应用名称、应用主页和应用回调地址(登录后回调地址),参考如下: + - 应用名称:eulercopilot + - 应用主页: + - 应用回调地址: + - 应用创建好后会生成 Client ID 和 Client Secret,将生成的 Client ID 和 Client Secret 配置到应用里,以 eulercopilot 为例,创建应用后在配置文件中添加配置 `euler-copilot-helm/chart/euler_copilot/values.yaml` 中添加配置 + + ![部署图](./pictures/创建应用成功界面.png) + +### 2. 安装 openEuler Copilot System + +- 编辑 values.yaml + + ```bash + cd euler-copilot-helm/chart/euler_copilot + ``` + + 请结合 YAML 中的注释中的[必填]项进行修改 + + ```bash + vim values.yaml + ``` + + - 注意: + 1. 查看系统架构,并修改values.yaml中的tag; + 2. 修改values.yaml中的globals的domain为EulerCopilot域名,并配置大模型的相关信息 + 3. 手动创建`docs_dir`、`plugin_dir`、`models`三个文件挂载目录 + 4. 修改values.yaml中framework章节的web_url和oidc设置 + 5. 如果部署插件,则需要配置用于Function Call的模型,此时必须有GPU环境用于部署sglang,可参考附件 + +- 安装 openEuler Copilot System + + ```bash + helm install -n euler-copilot service . + ``` + +- 查看 Pod 状态 + + ```bash + kubectl -n euler-copilot get pods + ``` + + 镜像拉取过程可能需要大约一分钟的时间,请耐心等待。部署成功后,所有 Pod 的状态应显示为 Running。 + + ```bash + NAME READY STATUS RESTARTS AGE + authhub-backend-deploy-authhub-64896f5cdc-m497f 2/2 Running 0 16d + authhub-web-deploy-authhub-7c48695966-h8d2p 1/1 Running 0 17d + pgsql-deploy-databases-86b4dc4899-ppltc 1/1 Running 0 17d + redis-deploy-databases-f8866b56-kj9jz 1/1 Running 0 17d + mysql-deploy-databases-57f5f94ccf-sbhzp 2/2 Running 0 17d + framework-deploy-service-bb5b58678-jxzqr 2/2 Running 0 16d + rag-deploy-service-5b7887644c-sm58z 2/2 Running 0 110m + vectorize-deploy-service-57f5f94ccf-sbhzp 2/2 Running 0 17d + web-deploy-service-74fbf7999f-r46rg 1/1 Running 0 2d + ``` + + 注意:如果 Pod 状态出现失败,建议按照以下步骤进行排查 + + 1. 查看 Kubernetes 集群的事件 (Events),以获取更多关于 Pod 失败的上下文信息 + + ```bash + kubectl -n euler-copilot get events + ``` + + 2. 查看镜像拉取是否成功 + + ```bash + k3s crictl images + ``` + + 3. 检查 RAG 的 Pod 日志,以确定是否有错误信息或异常行为。 + + ```bash + kubectl logs rag-deploy-service-5b7887644c-sm58z -n euler-copilot + ``` + + 4. 验证 Kubernetes 集群的资源状态,检查服务器资源或配额是否足够,资源不足常导致 Pod 镜像服拉取失败。 + + ```bash + df -h + ``` + + 5. 如果未拉取成且镜像大小为0,请检查是否是 k3s 版本未满足要求,低于 v1.30.2 + + ```bash + k3s -v + ``` + + 6. 确认 values.yaml 中 framework 的 OIDC 设置是否正确配置,以确保身份验证和授权功能正常工作。 + + ```bash + vim /home/euler-copilot-framework/euler-copilot-helm/chart/euler_copilot/values.yaml + ``` + +## 验证安装 + +恭喜您,openEuler Copilot System 的部署已完成!现在,您可以开启智能问答的非凡体验之旅了。 +请在浏览器中输入 (其中 port 默认值为8080,若更改则需相应调整)访问 openEuler Copilot System 网页,并尝试进行问答体验。 + +![Web 界面](./pictures/WEB界面.png) + +## 安装插件 + +详细信息请参考文档 [插件部署指南](../README.md#部署手册) + +## 构建专有领域智能问答 + +### 1. 构建 openEuler 专业知识领域的智能问答 + +1. 修改 values.yaml 的 pg 的镜像仓为 `pg-data` +2. 修改 values.yaml 的 rag 部分的字段 `knowledgebaseID: openEuler_2bb3029f` +3. 将 `vim euler-copilot-helm/chart/databases/templates/pgsql/pgsql-deployment.yaml` 的 volumes 相关字段注释 +4. 进入 `cd euler-copilot-helm/chart/databases`,执行更新服务 `helm upgrade -n euler-copilot databases .` +5. 进入 `cd euler-copilot-helm/chart/euler_copilot`,执行更新服务 `helm upgrade -n euler-copilot service .` +6. 进入网页端进行 openEuler 专业知识领域的问答 + +### 2. 构建项目专属知识领域智能问答 + +详细信息请参考文档 [本地资产库构建指南](./local-asset-library-construction-guide.md) + +## 附录 + +### 大模型准备 + +#### GPU 环境 + +参考以下方式进行部署 + +1. 下载模型文件: + + ```bash + huggingface-cli download --resume-download Qwen/Qwen1.5-14B-Chat --local-dir Qwen1.5-14B-Chat + ``` + +2. 创建终端 control + + ```bash + screen -S control + ``` + + ```bash + python3 -m fastchat.serve.controller + ``` + + - 按 Ctrl A+D 置于后台 + +3. 创建新终端 api + + ```bash + screen -S api + ``` + + ```bash + python3 -m fastchat.serve.openai_api_server --host 0.0.0.0 --port 30000 --api-keys sk-123456 + ``` + + - 按 Ctrl A+D 置于后台 + - 如果当前环境的 Python 版本是 3.12 或者 3.9 可以创建 python3.10 的 conda 虚拟环境 + + ```bash + mkdir -p /root/py310 + ``` + + ```bash + conda create --prefix=/root/py310 python==3.10.14 + ``` + + ```bash + conda activate /root/py310 + ``` + +4. 创建新终端 worker + + ```bash + screen -S worker + ``` + + ```bash + screen -r worker + ``` + + 安装 fastchat 和 vllm + + ```bash + pip install fschat vllm + ``` + + 安装依赖: + + ```bash + pip install fschat[model_worker] + ``` + + ```bash + python3 -m fastchat.serve.vllm_worker --model-path /root/models/Qwen1.5-14B-Chat/ --model-name qwen1.5 --num-gpus 8 --gpu-memory-utilization=0.7 --dtype=half + ``` + + - 按 Ctrl A+D 置于后台 + +5. 按照如下方式配置文件,并更新服务。 + + ```bash + vim euler-copilot-helm/chart/euler_copilot/values.yaml + ``` + + 修改如下部分 + + ```yaml + llm: + # 开源大模型,OpenAI兼容接口 + openai: + url: "http://$(IP):30000" + key: "sk-123456" + model: qwen1.5 + max_tokens: 8192 + ``` + +#### NPU 环境 + +NPU 环境部署可参考链接 [MindIE安装指南](https://www.hiascend.com/document/detail/zh/mindie/10RC2/whatismindie/mindie_what_0001.html) + +## FAQ + +### 1. huggingface 使用报错 + +```text +File "/usr/lib/python3.9/site-packages/urllib3/connection.py", line 186, in _new_conn +raise NewConnectionError( +urllib3.exceptions.eanconectionError: : Failed to establish a new conmection: [Errno 101] Network is unreachable +``` + +- 解决办法 + +```bash +pip3 install -U huggingface_hub +``` + +```bash +export HF_ENDPOINT=https://hf-mirror.com +``` + +### 2. 如何在 RAG 容器中调用获取问答结果的接口 + +- 请先进入到 RAG 对应 Pod + +```bash +curl -k -X POST "http://localhost:8005/kb/get_answer" -H "Content-Type: application/json" -d '{ \ + "question": "", \ + "kb_sn": "default_test", \ + "fetch_source": true }' +``` + +### 3. 执行 `helm upgrade` 报错 + +```text +Error: INSTALLATI0N FAILED: Kubernetes cluster unreachable: Get "http:/localhost:880/version": dial tcp [:1:8089: connect: connection refused +``` + +或者 + +```text +Error: UPGRADE FAILED: Kubernetes cluster unreachable: the server could not find the requested resource +``` + +- 解决办法 + +```bash +export KUBECONFIG=/etc/rancher/k3s/k3s.yaml +``` + +### 4. 无法查看 Pod 日志 + +```text +[root@localhost euler-copilot]# kubectl logs rag-deployservice65c75c48d8-44vcp-n euler-copilotDefaulted container "rag" out of: rag.rag-copy secret (init)Error from server: Get "https://172.21.31.11:10250/containerlogs/euler copilot/rag deploy"service 65c75c48d8-44vcp/rag": Forbidden +``` + +- 解决办法 + 如果设置了代理,需要将本机的网络 IP 从代理中剔除 + +```bash +cat /etc/systemd/system/k3s.service.env +``` + +```text +http_proxy="http://172.21.60.51:3128" +https_proxy="http://172.21.60.51:3128" +no_proxy=172.21.31.10 # 代理中剔除本机IP +``` + +### 5. GPU环境部署大模型时出现无法流式回复 + +在服务执行 curl 大模型失败,但是将 `"stream": true` 改为 `"stream": false`就可以 curl 通? + +```bash +curl http://localhost:30000/v1/chat/completions -H "Content-Type: application/json" -H "Authorization: Bearer sk-123456" -d '{ +"model": "qwen1.5", +"messages": [ +{ +"role": "system", +"content": "你是情感分析专家,你的任务是xxxx" +}, +{ +"role": "user", +"content": "你好" +} +], +"stream": true, +"n": 1, +"max_tokens": 32768 +}' +``` + +- 解决办法: + +```bash +pip install Pydantic=1.10.13 +``` + +### 6. 如何部署sglang + +```bash +# 1. 激活 Conda 环境, 并激活 Python 3.10 的 Conda 环境。假设你的环境名为 `myenv`: +conda activate myenv + +# 2. 在激活的环境中,安装 sglang[all] 和 flashinfer +pip install sglang[all]==0.3.0 +pip install flashinfer -i https://flashinfer.ai/whl/cu121/torch2.4/ + +# 3. 启动服务器 +python -m sglang.launch_server --served-model-name Qwen2.5-32B --model-path Qwen2.5-32B-Instruct-AWQ --host 0.0.0.0 --port 8001 --api-key sk-12345 --mem-fraction-static 0.5 --tp 8 +``` + +- 验证安装 + +```bash +pip show sglang +pip show flashinfer +``` + +- 注意: + +1. API Key:请确保 `--api-key` 参数中的 API 密钥是正确的 +2. 模型路径: 确保 `--model-path` 参数中的路径是正确的,并且模型文件存在于该路径下。 +3. CUDA 版本:确保你的系统上安装了 CUDA 12.1 和 PyTorch 2.4,因为 `flashinfer` 包依赖于这些特定版本。 +4. 线程池大小:根据你的GPU资源和预期负载调整线程池大小。如果你有 8 个 GPU,那么可以选择 --tp 8 来充分利用这些资源。 + +### 7. 如何 curl embedding + +```bash +curl -k -X POST http://$IP:8001/embedding \ + -H "Content-Type: application/json" \ + -d '{"texts": ["sample text 1", "sample text 2"]}' +# $IP为vectorize的Embedding的内网地址 +``` + +### 8. 如何生成证书 + +```bash +下载地址: https://github.com/FiloSottile/mkcert/releases +# 1. 下载 mkcert +# x86_64 +wget https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-amd64 +# arm64 +wget https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-arm64 + +# 2. 执行下面的命令生成秘钥 +mkcert -install +# mkcert 可直接接域名或 IP, 生成证书和秘钥 +mkcert example.com + +# 3. 将证书和秘钥拷贝到 /home/euler-copilot-framework_openeuler/euler-copilot-helm/chart_ssl/traefik-secret.yaml 中, 并执行下面命令使其生效。 +kubectl apply -f traefik-secret.yaml +``` diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/local-asset-library-construction-guide.md b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/local-asset-library-construction-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..b5051ea9cc969bcf68942cfcb89c40724dacee4d --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/local-asset-library-construction-guide.md @@ -0,0 +1,406 @@ +# 本地资产库构建指南 + +- RAG 是一个检索增强的模块,该指南主要是为rag提供命令行的方式进行数据库管理、资产管理、资产库管理和语料资产管理; + 对于数据库管理提供了清空数据库、初始化数据库等功能; + 对于资产管理提供了资产创建、资产查询和资产删除等功能; + 对于资产库管理提供了资产库创建、资产库查询和资产库删除等功能; + 对于语料资产管理提供了语料上传、语料查询和语料删除等功能。 +- 当前指南面向管理员进行编写,对于管理员而言,可以拥有多个资产,一个资产包含多个资产库(不同资产库的使用的向量化模型可以不同),一个资产库对应一个语料资产。 +- 本地语料上传指南是用户构建项目专属语料的指导,当前支持 docx、pdf、markdown、txt 和 xlsx 文件上传,推荐使用 docx 格式上传。 + +## 准备工作 + +- RAG 中关于语料上传目录挂载的配置: + +将本地语料保存到服务器的目录,例如 /home/docs 目录,且将 /home/data 目录权限设置为755 + +```bash +# 设置本地存放文档目录权限为755 +chmod -R 755 /home/docs +``` + +将文件存放的源目录映射至 RAG 容器目标目录,源目录的配置在 中,下面是文件中具体配置映射源目录的配置方法: + +![配置映射源目录](./pictures/本地资产库构建/配置映射源目录.png) + +中间层的配置(链接源目录和目标目录的配置)在 中,下面是文件中具体映射中间层的配置方法: + +![配置映射中间层](./pictures/本地资产库构建/配置映射中间层.png) + +目标目录的配置在 中,下面是文件中具体映射目标目录的配置方法: + +![配置映射目标目录](./pictures/本地资产库构建/配置映射目标目录.png) + +- 更新 Copilot 服务: + + ```bash + root@openeuler:/home/EulerCopilot/euler-copilot-helm/chart# helm upgrade -n euler-copilot service . + # 请注意:service是服务名,可根据实际修改 + ``` + +- 进入到 RAG 容器: + + ```bash + root@openeuler:~# kubectl -n euler-copilot get pods + NAME READY STATUS RESTARTS AGE + framework-deploy-service-bb5b58678-jxzqr 2/2 Running 0 16d + mysql-deploy-service-c7857c7c9-wz9gn 1/1 Running 0 17d + pgsql-deploy-service-86b4dc4899-ppltc 1/1 Running 0 17d + rag-deploy-service-5b7887644c-sm58z 2/2 Running 0 110m + redis-deploy-service-f8866b56-kj9jz 1/1 Running 0 17d + vectorize-deploy-service-57f5f94ccf-sbhzp 2/2 Running 0 17d + web-deploy-service-74fbf7999f-r46rg 1/1 Running 0 2d + # 进入rag pod + root@openeuler:~# kubectl -n euler-copilot exec -it rag-deploy-service-5b7887644c-sm58z -- bash + ``` + +- 设置 PYTHONPATH + + ```bash + # 设置PYTHONPATH + export PYTHONPATH=$(pwd) + ``` + +## 上传语料 + +### 查看脚本帮助信息 + +```bash +python3 scripts/rag_kb_manager.pyc --help +usage: rag_kb_manager.pyc [-h] --method + {init_database_info,init_rag_info,init_database,clear_database,create_kb,del_kb,query_kb,create_kb_asset,del_kb_asset,query_kb_asset,up_corpus,del_corpus,query_corpus,stop_corpus_uploading_job} + [--database_url DATABASE_URL] [--vector_agent_name VECTOR_AGENT_NAME] [--parser_agent_name PARSER_AGENT_NAME] + [--rag_url RAG_URL] [--kb_name KB_NAME] [--kb_asset_name KB_ASSET_NAME] [--corpus_dir CORPUS_DIR] + [--corpus_chunk CORPUS_CHUNK] [--corpus_name CORPUS_NAME] [--up_chunk UP_CHUNK] + [--embedding_model {TEXT2VEC_BASE_CHINESE_PARAPHRASE,BGE_LARGE_ZH,BGE_MIXED_MODEL}] [--vector_dim VECTOR_DIM] + [--num_cores NUM_CORES] + +optional arguments: + -h, --help show this help message and exit + --method {init_database_info,init_rag_info,init_database,clear_database,create_kb,del_kb,query_kb,create_kb_asset,del_kb_asset,query_kb_asset,up_corpus,del_corpus,query_corpus,stop_corpus_uploading_job} + 脚本使用模式,有init_database_info(初始化数据库配置)、init_database(初始化数据库)、clear_database(清除数据库)、create_kb(创建资产)、 + del_kb(删除资产)、query_kb(查询资产)、create_kb_asset(创建资产库)、del_kb_asset(删除资产库)、query_kb_asset(查询 + 资产库)、up_corpus(上传语料,当前支持txt、html、pdf、docx和md格式)、del_corpus(删除语料)、query_corpus(查询语料)和 + stop_corpus_uploading_job(上传语料失败后,停止当前上传任务) + --database_url DATABASE_URL + 语料资产所在数据库的url + --vector_agent_name VECTOR_AGENT_NAME + 向量化插件名称 + --parser_agent_name PARSER_AGENT_NAME + 分词插件名称 + --rag_url RAG_URL rag服务的url + --kb_name KB_NAME 资产名称 + --kb_asset_name KB_ASSET_NAME + 资产库名称 + --corpus_dir CORPUS_DIR + 待上传语料所在路径 + --corpus_chunk CORPUS_CHUNK + 语料切割尺寸 + --corpus_name CORPUS_NAME + 待查询或者待删除语料名 + --up_chunk UP_CHUNK 语料单次上传个数 + --embedding_model {TEXT2VEC_BASE_CHINESE_PARAPHRASE,BGE_LARGE_ZH,BGE_MIXED_MODEL} + 初始化资产时决定使用的嵌入模型 + --vector_dim VECTOR_DIM + 向量化维度 + --num_cores NUM_CORES + 语料处理使用核数 +``` + +### 具体操作 + +以下出现的命令中带**初始化**字段需要在进行资产管理前按指南中出现的相对顺序进行执行,命令中带**可重复**执字段的在后续过程中可以反复执行,命令中带**注意**字段的需谨慎执行。 + +### 步骤1:配置数据库和 RAG 信息 + +- #### 配置数据库信息(初始化) + +```bash +python3 scripts/rag_kb_manager.pyc --method init_database_info --database_url postgresql+psycopg2://postgres:123456@{dabase_url}:{databse_port}/postgres +``` + +**注意:** + +**{dabase_url}**为 k8s 集群内访问 postgres 服务的 url,请根据具体情况修改,一般为 **{postgres_servive_name}-{{ .Release.Name }}.\.svc.cluster.local** 格式,其中 **{postgres_servive_name}** 可以从 找到: + +![k8s集群中postgres服务的名称](./pictures/本地资产库构建/k8s集群中postgres服务的名称.png) + +**{{ .Release.Name }}**和**\** 为部署服务时helm安装应用时指定的 **my-release-name** 以及 **my-namespace**,一条 helm 安装应用的命令如下所示: + +```bash +helm install my-release-name --namespace my-namespace path/to/chart +``` + +**database_port** 的信息可以在 中查看,以下为字段所在位置(一般为5432): + +![postgres服务端口](./pictures/本地资产库构建/postgres服务端口.png) + +数据库信息配置命令执行命令完成之后会在 scripts/config 下出现 database_info.json 文件,文件内容如下: + +```bash +{"database_url": "postgresql+psycopg2://postgres:123456@{dabase_url}:{databse_port}/postgres"} +``` + +下面是命令执行成功的截图: + +![数据库配置信息成功](./pictures/本地资产库构建/数据库配置信息成功.png) + +- #### 配置rag信息(初始化) + +```bash +python3 scripts/rag_kb_manager.pyc --method init_rag_info --rag_url http://{rag_url}:{rag_port} +``` + +**{rag_url}** 为 0.0.0.0,**{rag_port}** 可以从 中获取(一般为8005): + +![rag_port](./pictures/本地资产库构建/rag_port.png) + +数据库信息配置命令执行命令完成之后会在 scripts/config 下出现 rag_info.json 文件,文件内容如下: + +```bash +{"rag_url": "http://{rag_url}:{rag_port}"} +``` + +下面是命令执行成功的截图: + +![rag配置信息成功](./pictures/本地资产库构建/rag配置信息成功.png) + +### 步骤2:初始化数据库 + +- #### 初始化数据库表格 + +```bash +python3 scripts/rag_kb_manager.pyc --method init_database +# 注意: +# 对于特殊关系型数据库可指定插件参数'--vector_agent_name VECTOR_AGENT_NAME'和 '--parser_agent_name PARSER_AGENT_NAME';其中VECTOR_AGENT_NAME默认为vector, PARSER_AGENT_NAME默认为zhparser +``` + +命令执行完成之后可以进入数据库容器查看表格是否创建成功,首先获取命名空间中的所有节点名称: + +```bash +# 获取命名空间中的所有pod节点 +kubectl get pods -n euler-copilot +``` + +结果如下: + +![获取数据库pod名称](./pictures/本地资产库构建/获取数据库pod名称.png) + +使用下面命令进入数据库: + +```bash +kubectl exec -it pgsql-deploy-b4cc79794-qn8zd -n euler-copilot -- bash +``` + +进入容器后使用下面命令进入数据库: + +```bash +root@pgsql-deploy-b4cc79794-qn8zd:/tmp# psql -U postgres +``` + +再使用\dt查看数据库初始化情况,出现下面内容表示数据库初始化成功: + +![数据库初始化](./pictures/本地资产库构建/数据库初始化.png) + +- #### 清空数据库(注意) + + 假设您想清空 RAG 产生的所有数据库数据,可以使用下面命令(**此命令会清空整个数据库,需谨慎操作!**)。 + +```bash +python3 scripts/rag_kb_manager.pyc --method clear_database +# 清空数据库请谨慎操作 +``` + +### 步骤3:创建资产 + + 下列指令若不指定 kb_name,则默认资产名为 default_test(ps:Copilot 不允许存在两个同名的资产): + +- #### 创建资产(可重复) + +```bash +python3 scripts/rag_kb_manager.pyc --method create_kb --kb_name default_test +``` + +创建资产成功会有以下提示: + +![创建资产成功](./pictures/本地资产库构建/创建资产成功.png) + +创建同名资产会有以下提示: + +![重复创建资产失败](./pictures/本地资产库构建/重复创建资产失败.png) + +- #### 删除资产(可重复) + +```bash +python3 scripts/rag_kb_manager.pyc --method del_kb --kb_name default_test +``` + +删除资产成功会出现以下提示(会将资产下的所有资产库和语料资产全部删除): + +![删除资产成功](./pictures/本地资产库构建/删除资产成功.png) + +对于不存在的资产进行删除,会出现以下提示: + +![删除不存在的资产失败](./pictures/本地资产库构建/删除不存在的资产失败.png) + +- #### 查询资产(可重复) + +```bash +python3 scripts/rag_kb_manager.pyc --method query_kb +``` + +查询资产成功会出现下面内容: + +![查询资产](./pictures/本地资产库构建/查询资产.png) + +对于无资产的情况下查询资产会出现以下内容: + +![无资产时查询资产](./pictures/本地资产库构建/无资产时查询资产.png) + +### 步骤4:创建资产库 + +下列指令若不指定资产名(kb_name)和资产库名(kb_asset_name),则默认资产名为 default_test 和资产库名 default_test_asset(ps:Copilot 同一个资产下不允许存在两个同名的资产库): + +- #### 创建资产库(可重复) + +```bash +python3 scripts/rag_kb_manager.pyc --method create_kb_asset --kb_name default_test --kb_asset_name default_test_asset +# 创建属于default_test的资产库 +``` + +对于创建资产库成功会出现以下内容: + +![资产库创建成功](./pictures/本地资产库构建/资产库创建成功.png) + +对于指定不存在的资产库创建资产会出现以下内容: + +![指定不存在的资产创建资产库失败](./pictures/本地资产库构建/指定不存在的资产创建资产库失败.png) + +对于同一个资产下重复创建同名资产库会出现以下内容: + +![创建资产库失败由于统一资产下存在同名资产库](./pictures/本地资产库构建/创建资产库失败由于统一资产下存在同名资产库.png) + +- #### 删除资产库(可重复) + +```bash +python3 scripts/rag_kb_manager.pyc --method del_kb_asset --kb_name default_test --kb_asset_name default_test_asset +``` + +对于删除资产库成功会出现以下内容: + +![资产库删除成功](./pictures/本地资产库构建/资产库删除成功png.png) + +对于删除不存在的资产库失败会出现以下内容: + +![资产下不存在对应资产库](./pictures/本地资产库构建/删除资产库失败,资产下不存在对应资产库.png) + +对于删除不存在的资产下的资产库会出现以下内容: + +![不存在资产](./pictures/本地资产库构建/资产库删除失败,不存在资产.png) + +- #### 查询资产库(可重复) + +```bash +python3 scripts/rag_kb_manager.pyc --method query_kb_asset --kb_name default_test +# 注意:资产是最上层的,资产库属于资产,且不能重名 +``` + +对于查询资产库成功会出现以下内容: + +![资产下查询资产库成功](./pictures/本地资产库构建/资产下查询资产库成功.png) + +对于资产内无资产库的情况下查询资产库会出现以下内容: + +![资产下未查询到资产库](./pictures/本地资产库构建/资产下未查询到资产库.png) + +对于查询不存在的资产下的资产库会出现以下内容: + +![不存在资产](./pictures/本地资产库构建/资产库查询失败,不存在资产.png) + +### 步骤5:上传语料 + +下列指令若不指定资产名(kb_name)和资产库名(kb_asset_name),则默认资产名为 default_test 和资产库名 default_test_asset,对于删除语料命令需要指定完整的语料名称(语料统一为 docx 格式保存在数据库中,可以通过查询语料命令查看已上传的文档名称);对于查询语料命令可以不指定语料名称(corpus_name),此时默认查询所有语料,可以指定部分或者完整的语料名,此时通过模糊搜索匹配数据库内相关的语料名称。 + +- 上传语料 + +```bash +python3 scripts/rag_kb_manager.pyc --method up_corpus --corpus_dir ./scripts/docs/ --kb_name default_test --kb_asset_name default_test_asset +# 注意: +# 1. RAG容器用于存储用户语料的目录路径是'./scripts/docs/'。在执行相关命令前,请确保该目录下已有本地上传的语料。 +# 2. 若语料已上传但查询未果,请检查宿主机上的待向量化语料目录(位于/home/euler-copilot/docs)的权限设置。 +# 为确保无权限问题影响,您可以通过运行chmod 755 /home/euler-copilot/docs命令来赋予该目录最大访问权限。 +``` + +对于语料上传成功会出现以下内容: + +![语料上传成功](./pictures/本地资产库构建/语料上传成功.png) + +对于语料具体的分割和上传情况可以在 logs/app.log 下查看,内容如下: + +![查看文档产生片段总数和上传成功总数](./pictures/本地资产库构建/查看文档产生片段总数和上传成功总数.png) + +- 删除语料 + +```bash +python3 scripts/rag_kb_manager.pyc --method del_corpus --corpus_name abc.docx --kb_name default_test --kb_asset_name default_test_asset +# 上传的文件统一转换为docx +``` + +对于语料删除成功会出现以下内容: + +![删除语料](./pictures/本地资产库构建/删除语料.png) + +对于删除不存在的语料会出现以下内容: + +![语料删除失败](./pictures/本地资产库构建/语料删除失败,未查询到相关语料.png) + +- 查询语料 + +```bash +# 查询指定名称的语料: +python3 scripts/rag_kb_manager.pyc --method query_corpus --corpus_name 语料名.docx +# 查询所有语料: +python3 scripts/rag_kb_manager.pyc --method query_corpus +``` + +对于查询所有语料会出现以下内容: + +![查询全部语料](./pictures/本地资产库构建/查询全部语料.png) + +- 停止上传任务 + +```bash +python3 scripts/rag_kb_manager.pyc --method stop_corpus_uploading_job +``` + +对于某些极端条件下(例如内存受限),上传语料失败,需要执行上面shell命令用于清除语料上传失败的缓存。 + +## 网页端查看语料上传进度 + +您可以灵活设置端口转发规则,通过执行如下命令将容器端口映射到主机上的指定端口,并在任何设备上通过访问 [http://{主机IP}:{映射端口}](http://{主机IP}:{映射端口})(例如 )来查看语料上传的详细情况。 + +```bash +kubectl port-forward rag-deploy-service-5b7887644c-sm58z 3000:8005 -n euler-copilot --address=0.0.0.0 +# 注意: 3000是主机上的端口,8005是rag的容器端口,可修改映射到主机上的端口 +``` + +## 验证上传后效果 + +上传语料成功之后你可以通过以下命令直接与 RAG 交互,来观察语料是否上传成功。 + +```bash +curl -k -X POST "http://{rag_url}:{rag_port}/kb/get_answer" -H "Content-Type: application/json" -d '{ \ + "question": "question", \ + "kb_sn": "kb_name", \ + "fetch_source": true, \ + "top_k": 3 \ +}' +``` + +- `question`:问题 + +- `kb_sn`:资产库名称 + +- `fetch_source`:是否返回关联片段以及片段来源,`false` 代表不返回,`true` 代表返回 + +- `top_k`:关联语料片段个数,需要大于等于3 diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/WEB\347\225\214\351\235\242.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/WEB\347\225\214\351\235\242.png" new file mode 100644 index 0000000000000000000000000000000000000000..bb9be4e33ce470865fe5a07decbc056b9ee4e9bb Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/WEB\347\225\214\351\235\242.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/authhub\347\231\273\345\275\225\347\225\214\351\235\242.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/authhub\347\231\273\345\275\225\347\225\214\351\235\242.png" new file mode 100644 index 0000000000000000000000000000000000000000..341828b1b6f728888d1dd52eec755033680155da Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/authhub\347\231\273\345\275\225\347\225\214\351\235\242.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\345\210\233\345\273\272\345\272\224\347\224\250\346\210\220\345\212\237\347\225\214\351\235\242.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\345\210\233\345\273\272\345\272\224\347\224\250\346\210\220\345\212\237\347\225\214\351\235\242.png" new file mode 100644 index 0000000000000000000000000000000000000000..a871907f348317e43633cf05f5241cb978476fb4 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\345\210\233\345\273\272\345\272\224\347\224\250\346\210\220\345\212\237\347\225\214\351\235\242.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\345\210\233\345\273\272\345\272\224\347\224\250\347\225\214\351\235\242.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\345\210\233\345\273\272\345\272\224\347\224\250\347\225\214\351\235\242.png" new file mode 100644 index 0000000000000000000000000000000000000000..d82c736a94b106a30fd8d1f7b781f9e335bb441f Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\345\210\233\345\273\272\345\272\224\347\224\250\347\225\214\351\235\242.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/k8s\351\233\206\347\276\244\344\270\255postgres\346\234\215\345\212\241\347\232\204\345\220\215\347\247\260.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/k8s\351\233\206\347\276\244\344\270\255postgres\346\234\215\345\212\241\347\232\204\345\220\215\347\247\260.png" new file mode 100644 index 0000000000000000000000000000000000000000..473a0006c9710c92375e226a760c3a79989312f9 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/k8s\351\233\206\347\276\244\344\270\255postgres\346\234\215\345\212\241\347\232\204\345\220\215\347\247\260.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/postgres\346\234\215\345\212\241\347\253\257\345\217\243.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/postgres\346\234\215\345\212\241\347\253\257\345\217\243.png" new file mode 100644 index 0000000000000000000000000000000000000000..cfee6d88da56bc939886caece540f7de8cf77bbc Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/postgres\346\234\215\345\212\241\347\253\257\345\217\243.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/rag_port.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/rag_port.png" new file mode 100644 index 0000000000000000000000000000000000000000..b1d93f9c9d7587aa88a27d7e0bf185586583d438 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/rag_port.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/rag\351\205\215\347\275\256\344\277\241\346\201\257\346\210\220\345\212\237.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/rag\351\205\215\347\275\256\344\277\241\346\201\257\346\210\220\345\212\237.png" new file mode 100644 index 0000000000000000000000000000000000000000..fec3cdaa2b260e50f5523477da3e58a9e14e2130 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/rag\351\205\215\347\275\256\344\277\241\346\201\257\346\210\220\345\212\237.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\233\345\273\272\350\265\204\344\272\247\345\272\223\345\244\261\350\264\245\347\224\261\344\272\216\347\273\237\344\270\200\350\265\204\344\272\247\344\270\213\345\255\230\345\234\250\345\220\214\345\220\215\350\265\204\344\272\247\345\272\223.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\233\345\273\272\350\265\204\344\272\247\345\272\223\345\244\261\350\264\245\347\224\261\344\272\216\347\273\237\344\270\200\350\265\204\344\272\247\344\270\213\345\255\230\345\234\250\345\220\214\345\220\215\350\265\204\344\272\247\345\272\223.png" new file mode 100644 index 0000000000000000000000000000000000000000..624459821de4542b635eeffa115eeba780929a4e Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\233\345\273\272\350\265\204\344\272\247\345\272\223\345\244\261\350\264\245\347\224\261\344\272\216\347\273\237\344\270\200\350\265\204\344\272\247\344\270\213\345\255\230\345\234\250\345\220\214\345\220\215\350\265\204\344\272\247\345\272\223.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\233\345\273\272\350\265\204\344\272\247\346\210\220\345\212\237.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\233\345\273\272\350\265\204\344\272\247\346\210\220\345\212\237.png" new file mode 100644 index 0000000000000000000000000000000000000000..3104717bfa8f6615ad6726577a24938bc29884b2 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\233\345\273\272\350\265\204\344\272\247\346\210\220\345\212\237.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\240\351\231\244\344\270\215\345\255\230\345\234\250\347\232\204\350\265\204\344\272\247\345\244\261\350\264\245.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\240\351\231\244\344\270\215\345\255\230\345\234\250\347\232\204\350\265\204\344\272\247\345\244\261\350\264\245.png" new file mode 100644 index 0000000000000000000000000000000000000000..454b9fdfa4b7f209dc370f78677a2f4e71ea49be Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\240\351\231\244\344\270\215\345\255\230\345\234\250\347\232\204\350\265\204\344\272\247\345\244\261\350\264\245.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\240\351\231\244\350\257\255\346\226\231.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\240\351\231\244\350\257\255\346\226\231.png" new file mode 100644 index 0000000000000000000000000000000000000000..d52d25d4778f6db2d2ec076d65018c40cd1da4d3 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\240\351\231\244\350\257\255\346\226\231.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\240\351\231\244\350\265\204\344\272\247\345\272\223\345\244\261\350\264\245\357\274\214\350\265\204\344\272\247\344\270\213\344\270\215\345\255\230\345\234\250\345\257\271\345\272\224\350\265\204\344\272\247\345\272\223.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\240\351\231\244\350\265\204\344\272\247\345\272\223\345\244\261\350\264\245\357\274\214\350\265\204\344\272\247\344\270\213\344\270\215\345\255\230\345\234\250\345\257\271\345\272\224\350\265\204\344\272\247\345\272\223.png" new file mode 100644 index 0000000000000000000000000000000000000000..82ed79c0154bd8e406621440c4e4a7caaab7e06e Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\240\351\231\244\350\265\204\344\272\247\345\272\223\345\244\261\350\264\245\357\274\214\350\265\204\344\272\247\344\270\213\344\270\215\345\255\230\345\234\250\345\257\271\345\272\224\350\265\204\344\272\247\345\272\223.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\240\351\231\244\350\265\204\344\272\247\346\210\220\345\212\237.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\240\351\231\244\350\265\204\344\272\247\346\210\220\345\212\237.png" new file mode 100644 index 0000000000000000000000000000000000000000..7dd2dea945f39ada1d7dd053d150a995b160f203 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\210\240\351\231\244\350\265\204\344\272\247\346\210\220\345\212\237.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\273\272\347\253\213\350\265\204\344\272\247\345\272\223.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\273\272\347\253\213\350\265\204\344\272\247\345\272\223.png" new file mode 100644 index 0000000000000000000000000000000000000000..84737b4185ce781d7b32ab42d39b8d2452138dad Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\345\273\272\347\253\213\350\265\204\344\272\247\345\272\223.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\214\207\345\256\232\344\270\215\345\255\230\345\234\250\347\232\204\350\265\204\344\272\247\345\210\233\345\273\272\350\265\204\344\272\247\345\272\223\345\244\261\350\264\245.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\214\207\345\256\232\344\270\215\345\255\230\345\234\250\347\232\204\350\265\204\344\272\247\345\210\233\345\273\272\350\265\204\344\272\247\345\272\223\345\244\261\350\264\245.png" new file mode 100644 index 0000000000000000000000000000000000000000..be89bdfde2518bba3941eee5d475f52ad9124343 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\214\207\345\256\232\344\270\215\345\255\230\345\234\250\347\232\204\350\265\204\344\272\247\345\210\233\345\273\272\350\265\204\344\272\247\345\272\223\345\244\261\350\264\245.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\225\260\346\215\256\345\272\223\345\210\235\345\247\213\345\214\226.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\225\260\346\215\256\345\272\223\345\210\235\345\247\213\345\214\226.png" new file mode 100644 index 0000000000000000000000000000000000000000..27530840aaa5382a226e1ed8baea883895d9d75e Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\225\260\346\215\256\345\272\223\345\210\235\345\247\213\345\214\226.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\225\260\346\215\256\345\272\223\351\205\215\347\275\256\344\277\241\346\201\257\346\210\220\345\212\237.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\225\260\346\215\256\345\272\223\351\205\215\347\275\256\344\277\241\346\201\257\346\210\220\345\212\237.png" new file mode 100644 index 0000000000000000000000000000000000000000..aa04e6f7f0648adfca1240c750ca5b79b88da5f9 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\225\260\346\215\256\345\272\223\351\205\215\347\275\256\344\277\241\346\201\257\346\210\220\345\212\237.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\227\240\350\265\204\344\272\247\346\227\266\346\237\245\350\257\242\350\265\204\344\272\247.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\227\240\350\265\204\344\272\247\346\227\266\346\237\245\350\257\242\350\265\204\344\272\247.png" new file mode 100644 index 0000000000000000000000000000000000000000..74905172c0c0a0acc4c4d0e35efd2493dc421c4e Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\227\240\350\265\204\344\272\247\346\227\266\346\237\245\350\257\242\350\265\204\344\272\247.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\237\245\347\234\213\346\226\207\346\241\243\344\272\247\347\224\237\347\211\207\346\256\265\346\200\273\346\225\260\345\222\214\344\270\212\344\274\240\346\210\220\345\212\237\346\200\273\346\225\260.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\237\245\347\234\213\346\226\207\346\241\243\344\272\247\347\224\237\347\211\207\346\256\265\346\200\273\346\225\260\345\222\214\344\270\212\344\274\240\346\210\220\345\212\237\346\200\273\346\225\260.png" new file mode 100644 index 0000000000000000000000000000000000000000..432fbfcd02f6d2220e7d2a8512aee893d67be24d Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\237\245\347\234\213\346\226\207\346\241\243\344\272\247\347\224\237\347\211\207\346\256\265\346\200\273\346\225\260\345\222\214\344\270\212\344\274\240\346\210\220\345\212\237\346\200\273\346\225\260.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\237\245\350\257\242\345\205\250\351\203\250\350\257\255\346\226\231.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\237\245\350\257\242\345\205\250\351\203\250\350\257\255\346\226\231.png" new file mode 100644 index 0000000000000000000000000000000000000000..a4f4ea8a3999a9ab659ccd9ea39b80b21ff46e84 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\237\245\350\257\242\345\205\250\351\203\250\350\257\255\346\226\231.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\237\245\350\257\242\350\265\204\344\272\247.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\237\245\350\257\242\350\265\204\344\272\247.png" new file mode 100644 index 0000000000000000000000000000000000000000..675b40297363664007f96948fb21b1cb90d6beea Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\346\237\245\350\257\242\350\265\204\344\272\247.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\216\267\345\217\226\346\225\260\346\215\256\345\272\223pod\345\220\215\347\247\260.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\216\267\345\217\226\346\225\260\346\215\256\345\272\223pod\345\220\215\347\247\260.png" new file mode 100644 index 0000000000000000000000000000000000000000..8fc0c988e8b3830c550c6be6e42b88ac13448d1a Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\216\267\345\217\226\346\225\260\346\215\256\345\272\223pod\345\220\215\347\247\260.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\257\255\346\226\231\344\270\212\344\274\240\346\210\220\345\212\237.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\257\255\346\226\231\344\270\212\344\274\240\346\210\220\345\212\237.png" new file mode 100644 index 0000000000000000000000000000000000000000..5c897e9883e868bf5160d92cb106ea4e4e9bc356 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\257\255\346\226\231\344\270\212\344\274\240\346\210\220\345\212\237.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\257\255\346\226\231\345\210\240\351\231\244\345\244\261\350\264\245\357\274\214\346\234\252\346\237\245\350\257\242\345\210\260\347\233\270\345\205\263\350\257\255\346\226\231.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\257\255\346\226\231\345\210\240\351\231\244\345\244\261\350\264\245\357\274\214\346\234\252\346\237\245\350\257\242\345\210\260\347\233\270\345\205\263\350\257\255\346\226\231.png" new file mode 100644 index 0000000000000000000000000000000000000000..407e49b929b7ff4cf14703046a4ba0bfe1bb441e Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\257\255\346\226\231\345\210\240\351\231\244\345\244\261\350\264\245\357\274\214\346\234\252\346\237\245\350\257\242\345\210\260\347\233\270\345\205\263\350\257\255\346\226\231.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\257\255\346\226\231\346\237\245\350\257\242\346\210\220\345\212\237.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\257\255\346\226\231\346\237\245\350\257\242\346\210\220\345\212\237.png" new file mode 100644 index 0000000000000000000000000000000000000000..a4f4ea8a3999a9ab659ccd9ea39b80b21ff46e84 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\257\255\346\226\231\346\237\245\350\257\242\346\210\220\345\212\237.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\344\270\213\346\234\252\346\237\245\350\257\242\345\210\260\350\265\204\344\272\247\345\272\223.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\344\270\213\346\234\252\346\237\245\350\257\242\345\210\260\350\265\204\344\272\247\345\272\223.png" new file mode 100644 index 0000000000000000000000000000000000000000..45ab521ec5f5afbd81ad54f023aae3b7a867dbf2 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\344\270\213\346\234\252\346\237\245\350\257\242\345\210\260\350\265\204\344\272\247\345\272\223.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\344\270\213\346\237\245\350\257\242\350\265\204\344\272\247\345\272\223\346\210\220\345\212\237.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\344\270\213\346\237\245\350\257\242\350\265\204\344\272\247\345\272\223\346\210\220\345\212\237.png" new file mode 100644 index 0000000000000000000000000000000000000000..90ed5624ae93ff9784a750514c53293df4e961f0 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\344\270\213\346\237\245\350\257\242\350\265\204\344\272\247\345\272\223\346\210\220\345\212\237.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\345\272\223\345\210\233\345\273\272\346\210\220\345\212\237.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\345\272\223\345\210\233\345\273\272\346\210\220\345\212\237.png" new file mode 100644 index 0000000000000000000000000000000000000000..7b2cc38a931c9c236517c14c86fa93e3eb2b6dcd Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\345\272\223\345\210\233\345\273\272\346\210\220\345\212\237.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\345\272\223\345\210\240\351\231\244\345\244\261\350\264\245\357\274\214\344\270\215\345\255\230\345\234\250\350\265\204\344\272\247.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\345\272\223\345\210\240\351\231\244\345\244\261\350\264\245\357\274\214\344\270\215\345\255\230\345\234\250\350\265\204\344\272\247.png" new file mode 100644 index 0000000000000000000000000000000000000000..1365a8d69467dec250d3451ac63e2615a2194c18 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\345\272\223\345\210\240\351\231\244\345\244\261\350\264\245\357\274\214\344\270\215\345\255\230\345\234\250\350\265\204\344\272\247.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\345\272\223\345\210\240\351\231\244\346\210\220\345\212\237png.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\345\272\223\345\210\240\351\231\244\346\210\220\345\212\237png.png" new file mode 100644 index 0000000000000000000000000000000000000000..1bd944264baa9369e6f8fbfd04cabcd12730c0e9 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\345\272\223\345\210\240\351\231\244\346\210\220\345\212\237png.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\345\272\223\346\237\245\350\257\242\345\244\261\350\264\245\357\274\214\344\270\215\345\255\230\345\234\250\350\265\204\344\272\247.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\345\272\223\346\237\245\350\257\242\345\244\261\350\264\245\357\274\214\344\270\215\345\255\230\345\234\250\350\265\204\344\272\247.png" new file mode 100644 index 0000000000000000000000000000000000000000..58bcd320e145dd29d9e5d49cb6d86964ebb83b51 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\350\265\204\344\272\247\345\272\223\346\237\245\350\257\242\345\244\261\350\264\245\357\274\214\344\270\215\345\255\230\345\234\250\350\265\204\344\272\247.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\351\205\215\347\275\256\346\230\240\345\260\204\344\270\255\351\227\264\345\261\202.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\351\205\215\347\275\256\346\230\240\345\260\204\344\270\255\351\227\264\345\261\202.png" new file mode 100644 index 0000000000000000000000000000000000000000..809b785b999b6663d9e9bd41fed953925093d6bd Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\351\205\215\347\275\256\346\230\240\345\260\204\344\270\255\351\227\264\345\261\202.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\351\205\215\347\275\256\346\230\240\345\260\204\346\272\220\347\233\256\345\275\225.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\351\205\215\347\275\256\346\230\240\345\260\204\346\272\220\347\233\256\345\275\225.png" new file mode 100644 index 0000000000000000000000000000000000000000..62ba5f6615f18deb3d5a71fd68ee8c929638d814 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\351\205\215\347\275\256\346\230\240\345\260\204\346\272\220\347\233\256\345\275\225.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\351\205\215\347\275\256\346\230\240\345\260\204\347\233\256\346\240\207\347\233\256\345\275\225.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\351\205\215\347\275\256\346\230\240\345\260\204\347\233\256\346\240\207\347\233\256\345\275\225.png" new file mode 100644 index 0000000000000000000000000000000000000000..d32c672fafcb0ef665bda0bcfdce19d2df44db01 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\351\205\215\347\275\256\346\230\240\345\260\204\347\233\256\346\240\207\347\233\256\345\275\225.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\351\207\215\345\244\215\345\210\233\345\273\272\350\265\204\344\272\247\345\244\261\350\264\245.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\351\207\215\345\244\215\345\210\233\345\273\272\350\265\204\344\272\247\345\244\261\350\264\245.png" new file mode 100644 index 0000000000000000000000000000000000000000..a5ecd6b65abc97320e7467f00d82ff1fd9bf0e44 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\346\234\254\345\234\260\350\265\204\344\272\247\345\272\223\346\236\204\345\273\272/\351\207\215\345\244\215\345\210\233\345\273\272\350\265\204\344\272\247\345\244\261\350\264\245.png" differ diff --git "a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\351\203\250\347\275\262\350\247\206\345\233\276.png" "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\351\203\250\347\275\262\350\247\206\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..181bf1d2ddbe15cfd296c27df27d865bdbce8d69 Binary files /dev/null and "b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/pictures/\351\203\250\347\275\262\350\247\206\345\233\276.png" differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/Compatibility-AI-Infra/flows/get_all_docker_images_flow.yaml b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/Compatibility-AI-Infra/flows/get_all_docker_images_flow.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d1c4332203be24d3395d45eee2b1620b18d6f06c --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/Compatibility-AI-Infra/flows/get_all_docker_images_flow.yaml @@ -0,0 +1,15 @@ +name: get_all_supported_AI_docker_images +description: "获取所有支持的docker容器镜像,输入为空,输出为支持的AI容器镜像列表,包括名字、tag、registry、repository" +steps: + - name: start + call_type: api + params: + endpoint: GET /docker/images + next: list2markdown + - name: list2markdown + call_type: llm + params: + user_prompt: | + 当前已有的docker容器及tag为:{data}。请将这份内容输出为markdown表格,表头为registry、repository、image_name、tag,请注意如果一个容器镜像有多个tag版本,请分多行展示。 +next_flow: + - docker_pull_specified_AI_docker_images \ No newline at end of file diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/Compatibility-AI-Infra/flows/pull_images_flow.yaml b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/Compatibility-AI-Infra/flows/pull_images_flow.yaml new file mode 100644 index 0000000000000000000000000000000000000000..277677924f152672e5f0b02305733347900d4e4b --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/Compatibility-AI-Infra/flows/pull_images_flow.yaml @@ -0,0 +1,15 @@ +name: docker_pull_specified_AI_docker_images +description: "从dockerhub拉取指定的docker容器镜像,输入为容器镜像的名字和tag" +steps: + - name: start + call_type: api + params: + endpoint: POST /docker/pull + next: extract_key + - name: extract_key + call_type: extract + params: + keys: + - data.shell +next_flow: + - docker_run_specified_AI_docker_images \ No newline at end of file diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/Compatibility-AI-Infra/flows/run_images_flow.yaml b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/Compatibility-AI-Infra/flows/run_images_flow.yaml new file mode 100644 index 0000000000000000000000000000000000000000..54fe3ca39d9fe16b3c1bbcc506b7cf6f0e673ea9 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/Compatibility-AI-Infra/flows/run_images_flow.yaml @@ -0,0 +1,13 @@ +name: docker_run_specified_AI_docker_images +description: "运行指定的容器镜像,输入为容器镜像的名字和tag" +steps: + - name: start + call_type: api + params: + endpoint: POST /docker/run + next: extract_key + - name: extract_key + call_type: extract + params: + keys: + - data.shell diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/Compatibility-AI-Infra/openapi.yaml b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/Compatibility-AI-Infra/openapi.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b46bf07f044302169c6c02f4f61be22f2fb5657f --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/Compatibility-AI-Infra/openapi.yaml @@ -0,0 +1,190 @@ +openapi: 3.0.2 +info: + title: compatibility-ai-infra + version: 0.1.0 +servers: + - url: http://ai-infra-service.compatibility-ai-infra.svc.cluster.local:8101 +paths: + /docker/images: + get: + description: 获取所有支持的AI容器信息,返回容器名字和tag + responses: + '200': + description: Successful Response + content: + application/json: + schema: + $ref: '#/components/schemas/ResponseData' + /docker/pull: + post: + description: 输入容器镜像名字和容器镜像tag,返回拉取该容器的shell命令 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PullDockerImages' + required: true + responses: + '200': + description: Successful Response + content: + application/json: + schema: + $ref: '#/components/schemas/ResponseData' + '422': + description: Validation Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + /docker/run: + post: + description: 输入容器名字和tag,返回运行该容器的shell命令 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RunDockerImages' + required: true + responses: + '200': + description: Successful Response + content: + application/json: + schema: + $ref: '#/components/schemas/ResponseData' + '422': + description: Validation Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' +components: + schemas: + HTTPValidationError: + description: HTTP校验错误 + type: object + properties: + detail: + title: Detail + type: array + items: + $ref: '#/components/schemas/ValidationError' + PullDockerImages: + description: 生成容器拉取命令的接口的入参 + required: + - image_name + - image_tag + type: object + properties: + image_name: + description: 容器镜像的名字,不要包含转义符 + type: string + enum: + - cann + - oneapi-runtime + - oneapi-basekit + - llm-server + - mlflow + - llm + - tensorflow + - pytorch + - cuda + image_tag: + description: 容器镜像的tag,不要包含转义符 + type: string + enum: + - "8.0.RC1-oe2203sp4" + - "cann7.0.RC1.alpha002-oe2203sp2" + - "2024.2.0-oe2403lts" + - "1.0.0-oe2203sp3" + - "2.11.1-oe2203sp3" + - "2.13.1-oe2203sp3" + - "chatglm2_6b-pytorch2.1.0.a1-cann7.0.RC1.alpha002-oe2203sp2" + - "llama2-7b-q8_0-oe2203sp2" + - "chatglm2-6b-q8_0-oe2203sp2" + - "fastchat-pytorch2.1.0.a1-cann7.0.RC1.alpha002-oe2203sp2" + - "tensorflow2.15.0-oe2203sp2" + - "tensorflow2.15.0-cuda12.2.0-devel-cudnn8.9.5.30-oe2203sp2" + - "pytorch2.1.0-oe2203sp2" + - "pytorch2.1.0-cuda12.2.0-devel-cudnn8.9.5.30-oe2203sp2" + - "pytorch2.1.0.a1-cann7.0.RC1.alpha002-oe2203sp2" + - "cuda12.2.0-devel-cudnn8.9.5.30-oe2203sp2" + ResponseData: + description: 接口返回值的固定格式 + required: + - code + - message + - data + type: object + properties: + code: + description: 状态码 + type: integer + message: + description: 状态信息 + type: string + data: + description: 返回数据 + type: any + RunDockerImages: + description: 生成容器运行命令的接口的入参 + required: + - image_name + - image_tag + type: object + properties: + image_name: + description: 容器镜像的名字,不要包含转义符 + type: string + enum: + - cann + - oneapi-runtime + - oneapi-basekit + - llm-server + - mlflow + - llm + - tensorflow + - pytorch + - cuda + image_tag: + description: 容器镜像的tag,不要包含转义符 + type: string + enum: + - "8.0.RC1-oe2203sp4" + - "cann7.0.RC1.alpha002-oe2203sp2" + - "2024.2.0-oe2403lts" + - "1.0.0-oe2203sp3" + - "2.11.1-oe2203sp3" + - "2.13.1-oe2203sp3" + - "chatglm2_6b-pytorch2.1.0.a1-cann7.0.RC1.alpha002-oe2203sp2" + - "llama2-7b-q8_0-oe2203sp2" + - "chatglm2-6b-q8_0-oe2203sp2" + - "fastchat-pytorch2.1.0.a1-cann7.0.RC1.alpha002-oe2203sp2" + - "tensorflow2.15.0-oe2203sp2" + - "tensorflow2.15.0-cuda12.2.0-devel-cudnn8.9.5.30-oe2203sp2" + - "pytorch2.1.0-oe2203sp2" + - "pytorch2.1.0-cuda12.2.0-devel-cudnn8.9.5.30-oe2203sp2" + - "pytorch2.1.0.a1-cann7.0.RC1.alpha002-oe2203sp2" + - "cuda12.2.0-devel-cudnn8.9.5.30-oe2203sp2" + ValidationError: + description: 接口的入参校验错误时返回的内容格式 + required: + - loc + - msg + - type + type: object + properties: + loc: + title: Location + type: array + items: + anyOf: + - type: string + - type: integer + msg: + title: Message + type: string + type: + title: Error Type + type: string \ No newline at end of file diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/Compatibility-AI-Infra/plugin.json b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/Compatibility-AI-Infra/plugin.json new file mode 100644 index 0000000000000000000000000000000000000000..6136093d2313bd85ae2f2244adef96d48dad90bd --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/Compatibility-AI-Infra/plugin.json @@ -0,0 +1,6 @@ +{ + "id": "ai_docker_images", + "name": "AI容器镜像", + "description": "该插件接受用户的输入,检查当前支持哪些AI容器,拉取容器,运行容器", + "predefined_question": "查看当前支持哪些AI容器,拉取指定的容器,运行指定的容器" +} \ No newline at end of file diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/plugin-ai-container-stack-deployment-guide.md b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/plugin-ai-container-stack-deployment-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..8e5b7f412db868aadefd6707ac665e0c71456f59 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/ai_container_stack/plugin-ai-container-stack-deployment-guide.md @@ -0,0 +1,35 @@ +# AI容器栈部署指南 + +## 准备工作 + ++ 提前安装 [openEuler Copilot System 命令行(智能 Shell)客户端](../../../usage_guide/command_line_client/command-line-assistant-usage-guide.md) + ++ 修改 /xxxx/xxxx/values.yaml 文件的 `euler-copilot-tune` 部分,将 `enable` 字段改为 `True` + +```yaml +enable: True +``` + ++ 更新环境 + +```bash +helm upgrade euler-copilot . +``` + ++ 检查 Compatibility-AI-Infra 目录下的 openapi.yaml 中 `servers.url` 字段,确保AI容器服务的启动地址被正确设置 + ++ 获取 `$plugin_dir` 插件文件夹的路径,该变量位于 euler-copilot-helm/chart/euler_copilot/values.yaml 中的 `framework` 模块 + ++ 如果插件目录不存在,需新建该目录 + ++ 将该目录下的 Compatibility-AI-Infra 文件夹放到 `$plugin_dir` 中 + +```bash +cp -r ./Compatibility-AI-Infra $PLUGIN_DIR +``` + ++ 重建 framework pod,重载插件配置 + +```bash +kubectl delete pod framework-xxxx -n 命名空间 +``` diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/flows/demarcation.yaml b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/flows/demarcation.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6831bdea203e1ffd360f765e5f85ebdce704a437 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/flows/demarcation.yaml @@ -0,0 +1,18 @@ +name: demarcation +description: 该工具的作用为针对已知异常事件进行定界分析。需从上下文中获取start_time(开始时间),end_time(结束时间),container_id(容器ID) +steps: + - name: start + call_type: api + params: + endpoint: POST /demarcation + next: report_gen + - name: report_gen + call_type: llm + params: + system_prompt: 你是一个系统智能助手,擅长分析系统的故障现象,最终生成分析报告。 + user_prompt: | + 您是一个专业的运维人员,擅长分析系统的故障现象,最终生成分析报告。当前异常检测结果为{data}。 + 将root_causes_metric_top3内容输出为表格形式,并为每个根因指标进行标号。 + 整个分析报告应该符合markdown规范 +next_flow: + - detection \ No newline at end of file diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/flows/detection.yaml b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/flows/detection.yaml new file mode 100644 index 0000000000000000000000000000000000000000..836c71423d63248cd84fe20593d6f848c9b35363 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/flows/detection.yaml @@ -0,0 +1,10 @@ +name: detection +description: 该工具的作用为针对已知容器ID和指标,执行profiling分析任务,得到任务ID。需从上下文中获取container_id(容器ID)和三个metric(指标)的其中一个。 +steps: + - name: start + call_type: api + params: + endpoint: POST /detection + next: end + - name: end + call_type: none diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/flows/inspection.yaml b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/flows/inspection.yaml new file mode 100644 index 0000000000000000000000000000000000000000..afaefe31106c5ec2016fb3f030fb363950b62516 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/flows/inspection.yaml @@ -0,0 +1,16 @@ +name: inspection +description: 该工具的作用为在指定机器上对容器进行异常事件检测。需从上下文中获取start_time(开始时间),end_time(结束时间),machine_id(机器IP) +steps: + - name: start + call_type: api + params: + endpoint: POST /inspection + next: list2markdown + - name: list2markdown + call_type: llm + params: + user_prompt: | + 您是一个专业的运维人员,擅长分析系统的故障现象,最终生成分析报告。当前的异常检测结果为{data}。请将anomaly_events_times_list的信息,输出为表格形式。整个分析报告请符合markdown规范。 + +next_flow: + - demarcation \ No newline at end of file diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/flows/show_profiling.yaml b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/flows/show_profiling.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b82172eb272e6c0679dd32582e18e4ecda7dc2bf --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/flows/show_profiling.yaml @@ -0,0 +1,36 @@ +name: show_profiling +description: 根据已知的智能诊断任务ID(task_id),获取报告的原始数据。随后根据原始数据,生成详细的报告。 +steps: + - name: start + call_type: api + params: + endpoint: POST /show_profiling + next: report_gen + - name: report_gen + call_type: llm + params: + system_prompt: | + 你是一个数据分析和性能分析的专家,请按以下的模板分析出应用的性能瓶颈: + + 1.分析topStackSelf字段中自身耗时排名前3的函数调用栈,分析结果中应该包含函数的耗时信息、函数调用栈的解释说明。 + 2.分析topStackTotal字段中总耗时排名前3的函数调用栈,分析结果中应该包含函数的耗时信息、函数调用栈的解释说明。 + 3.总结前两步的分析结果,并给出影响应用性能的瓶颈所在,同时给出建议。 + user_prompt: | + 现有定界分析结果:{data} + 上面提供了一个JSON对象,它包含了应用程序的Profiling分析报告。该JSON对象包括如下几个字段: + + - traceEvents:它是一个事件列表,列表中的每一项表示一个事件,每个事件以字典格式存储,事件的主要内容解释如下: + - cat 字段:表示事件的分类,它的值包括 syscall、python_gc、sample、pthread_sync,oncpu。其中,syscall 表示这是一个系统调用事件;python_gc 表示这是一个Python垃圾回收事件;sample表示这是一个cpu调用栈采样事件;oncpu表示这是一个OnCPU事件,它说明了pid字段所代表的进程正在占用cpu。 + - name字段:表示事件的名称; + - pid字段:表示事件的进程ID; + - tid字段:表示事件所在的线程ID; + - ts字段:表示事件发生的开始时间,它是一个时间戳格式,单位是微秒; + - dur字段:表示事件的耗时,单位是微秒; + - sf字段:表示事件的函数调用栈,内容是以分号(;)分隔的函数名列表,分号左边是调用方的函数名,分号右边是被调用的函数名。 + - args字段:表示每个事件特有的信息,内容主要包括:count字段,表示事件发生的计数;thread.name字段,表示事件所在的线程的名称;cpu字段,表示采样的cpu编号。 + - topStackSelf:表示应用程序在执行CPU操作期间,自身耗时排名前10的函数调用栈列表。自身耗时是指函数调用栈自身的耗时。列表中的每一项内容说明如下: + - stack:用字符串表示的一个函数调用栈,内容是以分号(;)分隔的函数名列表,分号左边是调用方的函数名,分号右边是被调用的函数名。 + - self_time:stack表示的函数调用栈的自身耗时,单位是毫秒。 + - topStackTotal:表示应用程序在执行CPU操作期间,总耗时排名前10的函数调用栈列表,总耗时是指函数调用栈累积的耗时,它包含了自身耗时。列表中的每一项内容说明如下: + - stack:用字符串表示的一个函数调用栈,内容是以分号(;)分隔的函数名列表,分号左边是调用方的函数名,分号右边是被调用的函数名。 + - total_time:stack表示的函数调用栈的总耗时,单位是毫秒。 \ No newline at end of file diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/openapi.yaml b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/openapi.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9ebf2715d5ff61cd86150cfa9b208c2c48a2afa3 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/openapi.yaml @@ -0,0 +1,255 @@ +openapi: 3.0.2 +info: + title: 智能诊断 + version: 1.0.0 +servers: + - url: http://192.168.10.31:20030 +paths: + /inspection: + post: + description: 对指定机器进行异常检测,返回异常事件 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/InspectionRequestData' + required: true + responses: + '200': + description: Successful Response + content: + application/json: + schema: {} + '422': + description: Validation Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + /demarcation: + post: + description: 对指定容器进行异常定界 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/DemarcationRequestData' + required: true + responses: + '200': + description: Successful Response + content: + application/json: + schema: {} + '422': + description: Validation Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + /detection: + post: + description: 根据定界结果指标进行定位 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/DetectionRequestData' + required: true + responses: + '200': + description: Successful Response + content: + application/json: + schema: {} + '422': + description: Validation Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + /show_profiling: + post: + description: 根据任务ID,获取Profiling结果 + requestBody: + content: + application/json: + schema: + type: object + description: 请求数据 + required: + - task_id + properties: + task_id: + type: string + description: 任务ID,为UUID类型 + responses: + '200': + description: Successful Response + content: + application/json: + schema: + $ref: "#/components/schemas/ShowProfilingResponse" + '422': + description: Validation Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' +components: + schemas: + HTTPValidationError: + type: object + description: HTTP 校验错误 + properties: + detail: + type: array + items: + $ref: '#/components/schemas/ValidationError' + title: Detail + InspectionRequestData: + type: object + description: 巡检接口入参 + required: + - machine_id + - start_time + - end_time + properties: + machine_id: + description: 机器IP。如果给定的信息没有指定任何机器IP,则默认为“default_0.0.0.0”。 + type: string + title: Machine_ID + default: default_0.0.0.0 + start_time: + description: 根据给定的信息提取出开始时间,如果给定的信息不包含开始时间,开始时间可以设置为当前时间往前推2分钟,最终解析出的时间以'%Y-%m-%d %H:%M:%S'格式输出 + type: string + title: Start_Time + default: '' + end_time: + description: 根据给定的信息提取出结束时间,如果给定的信息不包含结束时间,结束时间可以设置为当前时间,最终解析出的时间以'%Y-%m-%d %H:%M:%S'格式输出 + type: string + title: End_Time + default: '' + DemarcationRequestData: + type: object + description: 定界接口入参 + required: + - start_time + - end_time + - container_id + properties: + start_time: + description: 根据给定的信息提取出开始时间,如果给定的信息不包含开始时间,开始时间可以设置为当前时间往前推2分钟,最终解析出的时间以'%Y-%m-%d %H:%M:%S'格式输出 + type: string + title: Start_Time + default: '' + end_time: + description: 根据给定的信息提取出结束时间,如果给定的信息不包含结束时间,结束时间可以设置为当前时间,最终解析出的时间以'%Y-%m-%d %H:%M:%S'格式输出 + type: string + title: End_Time + default: '' + container_id: + description: 结合问题中指定的具体异常事件,根据给定信息提取容器ID + type: string + title: Container_ID + default: '' + DetectionRequestData: + type: object + description: 定位接口入参 + required: + - container_id + - metric + properties: + container_id: + description: 结合问题中指定的具体指标或者指标号,根据给定信息提取容器ID + type: string + title: Container_ID + default: '' + metric: + description: 结合问题中的具体指标或者指标号,根据给定信息提取具体指标值作为metric + type: string + title: Metric + default: '' + ShowProfilingResponse: + type: object + description: show profiling 的返回结果 + properties: + traceEvents: + type: array + items: + type: object + properties: + cat: + type: string + description: Event category (syscall, python_gc, sample, pthread_sync, oncpu) + name: + type: string + description: Event name + pid: + type: integer + format: int32 + description: Process ID + tid: + type: integer + format: int32 + description: Thread ID + ts: + type: integer + format: int64 + description: Timestamp of the event start in microseconds + dur: + type: integer + format: int32 + description: Duration of the event in microseconds + sf: + type: string + description: Call stack represented as a list of function names separated by semicolons + args: + type: object + additionalProperties: true + description: Additional event-specific information such as count, thread.name, and cpu + topStackSelf: + type: array + items: + type: object + properties: + stack: + type: string + description: Call stack represented as a list of function names separated by semicolons + self_time: + type: number + format: int + description: Exclusive time spent in the call stack in milliseconds + topStackTotal: + type: array + items: + type: object + properties: + stack: + type: string + description: Call stack represented as a list of function names separated by semicolons + total_time: + type: number + format: int + description: Total inclusive time spent in the call stack in milliseconds + ValidationError: + type: object + required: + - loc + - msg + - type + title: ValidationError + properties: + loc: + type: array + items: + anyOf: + - type: string + - type: integer + title: Location + msg: + type: string + title: Message + type: + type: string + title: Error Type \ No newline at end of file diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/plugin.json b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/plugin.json new file mode 100644 index 0000000000000000000000000000000000000000..b0ef2fd7aa0c13ad626a01d0fc7a4bf010ab3178 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/euler-copilot-rca/plugin.json @@ -0,0 +1,5 @@ +{ + "id": "rca", + "name": "智能诊断", + "description": "该插件具备以下功能:巡检,定界,定位" +} \ No newline at end of file diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/plugin-intelligent-diagnosis-deployment-guide.md b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/plugin-intelligent-diagnosis-deployment-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..7611513b1adda72ed6fea95020fd7253a333358a --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_diagnosis/plugin-intelligent-diagnosis-deployment-guide.md @@ -0,0 +1,189 @@ +# 智能诊断部署指南 + +## 准备工作 + ++ 提前安装 [openEuler Copilot System 命令行(智能 Shell)客户端](../../../usage_guide/command_line_client/command-line-assistant-usage-guide.md) + ++ 被诊断机器不能安装 crictl 和 isula,只能有 docker 一个容器管理工具 + ++ 在需要被诊断的机器上安装 gala-gopher 和 gala-anteater + +## 部署 gala-gopher + +### 1. 准备 BTF 文件 + +**如果Linux内核支持 BTF,则不需要准备 BTF 文件。**可以通过以下命令来查看Linux内核是否已经支持 BTF: + +```bash +cat /boot/config-$(uname -r) | grep CONFIG_DEBUG_INFO_BTF +``` + +如果输出结果为`CONFIG_DEBUG_INFO_BTF=y`,则表示内核支持BTF。否则表示内核不支持BTF。 +如果内核不支持BTF,需要手动制作BTF文件。步骤如下: + +1. 获取当前Linux内核版本的 vmlinux 文件 + + vmlinux 文件存放在 `kernel-debuginfo` 包里面,存放路径为 `/usr/lib/debug/lib/modules/$(uname -r)/vmlinux`。 + + 例如,对于 `kernel-debuginfo-5.10.0-136.65.0.145.oe2203sp1.aarch64`,对应的vmlinux路径为`/usr/lib/debug/lib/modules/5.10.0-136.65.0.145.oe2203sp1.aarch64/vmlinux`。 + +2. 制作 BTF 文件 + + 基于获取到 vmlinux 文件来制作 BTF 文件。这一步可以在自己的环境里操作。首先,需要安装相关的依赖包: + + ```bash + # 说明:dwarves 包中包含 pahole 命令,llvm 包中包含 llvm-objcopy 命令 + yum install -y llvm dwarves + ``` + + 执行下面的命令行,生成 BTF 文件。 + + ```bash + kernel_version=4.19.90-2112.8.0.0131.oe1.aarch64 # 说明:这里需要替换成目标内核版本,可通过 uname -r 命令获取 + pahole -J vmlinux + llvm-objcopy --only-section=.BTF --set-section-flags .BTF=alloc,readonly --strip-all vmlinux ${kernel_version}.btf + strip -x ${kernel_version}.btf + ``` + + 生成的 BTF 文件名称为`.btf`格式,其中 ``为目标机器的内核版本,可通过 `uname -r` 命令获取。 + +### 2. 下载 gala-gopher 容器镜像 + +#### 在线下载 + +gala-gopher 容器镜像已归档到 仓库中,可通过如下命令获取。 + +```bash +# 获取 aarch64 架构的镜像 +docker pull hub.oepkgs.net/a-ops/gala-gopher-profiling-aarch64:latest +# 获取 x86_64 架构的镜像 +docker pull hub.oepkgs.net/a-ops/gala-gopher-profiling-x86_64:latest +``` + +#### 离线下载 + +若无法通过在线下载的方式下载容器镜像,可联系我(何秀军 00465007)获取压缩包。 + +拿到压缩包后,放到目标机器上,解压并加载容器镜像,命令行如下: + +```bash +tar -zxvf gala-gopher-profiling-aarch64.tar.gz +docker load < gala-gopher-profiling-aarch64.tar +``` + +### 3. 启动 gala-gopher 容器 + +容器启动命令: + +```shell +docker run -d --name gala-gopher-profiling --privileged --pid=host --network=host -v /:/host -v /etc/localtime:/etc/localtime:ro -v /sys:/sys -v /usr/lib/debug:/usr/lib/debug -v /var/lib/docker:/var/lib/docker -v /tmp/$(uname -r).btf:/opt/gala-gopher/btf/$(uname -r).btf -e GOPHER_HOST_PATH=/host gala-gopher-profiling-aarch64:latest +``` + +启动配置参数说明: + ++ `-v /tmp/$(uname -r).btf:/opt/gala-gopher/btf/$(uname -r).btf` :如果内核支持 BTF,则删除该配置即可。如果内核不支持 BTF,则需要将前面准备好的 BTF 文件拷贝到目标机器上,并将 `/tmp/$(uname -r).btf` 替换为对应的路径。 ++ `gala-gopher-profiling-aarch64-0426` :gala-gopher容器对应的tag,替换成实际下载的tag。 + +探针启动: + ++ `container_id` 为需要观测的容器 id ++ 分别启动 sli 和 container 探针 + +```bash +curl -X PUT http://localhost:9999/sli -d json='{"cmd":{"check_cmd":""},"snoopers":{"container_id":[""]},"params":{"report_period":5},"state":"running"}' +``` + +```bash +curl -X PUT http://localhost:9999/container -d json='{"cmd":{"check_cmd":""},"snoopers":{"container_id":[""]},"params":{"report_period":5},"state":"running"}' +``` + +探针关闭 + +```bash +curl -X PUT http://localhost:9999/sli -d json='{"state": "stopped"}' +``` + +```bash +curl -X PUT http://localhost:9999/container -d json='{"state": "stopped"}' +``` + +## 部署 gala-anteater + +源码部署: + +```bash +# 请指定分支为 930eulercopilot +git clone https://gitee.com/GS-Stephen_Curry/gala-anteater.git +``` + +安装部署请参考 +(请留意python版本导致执行setup.sh install报错) + +镜像部署: + +```bash +docker pull hub.oepkgs.net/a-ops/gala-anteater:2.0.2 +``` + +`/etc/gala-anteater/config/gala-anteater.yaml` 中 Kafka 和 Prometheus 的 `server` 和 `port` 需要按照实际部署修改,`model_topic`、`meta_topic`、`group_id` 自定义 + +```yaml +Kafka: + server: "xxxx" + port: "xxxx" + model_topic: "xxxx" # 自定义,与rca配置中保持一致 + meta_topic: "xxxx" # 自定义,与rca配置中保持一致 + group_id: "xxxx" # 自定义,与rca配置中保持一致 + # auth_type: plaintext/sasl_plaintext, please set "" for no auth + auth_type: "" + username: "" + password: "" + +Prometheus: + server: "xxxx" + port: "xxxx" + steps: "5" +``` + +gala-anteater 中模型的训练依赖于 gala-gopher 采集的数据,因此请保证 gala-gopher 探针正常运行至少24小时,在运行 gala-anteater。 + +## 部署 gala-ops + +每个中间件的大致介绍: + +kafka : 一个数据库中间件, 分布式数据分流作用, 可以配置为当前的管理节点。 + +prometheus:性能监控, 配置需要监控的生产节点 ip list。 + +直接通过yum install安装kafka和prometheus,可参照安装脚本 + +只需要参照其中 kafka 和 prometheus 的安装即可 + +## 部署 euler-copilot-rca + +镜像拉取 + +```bash +docker pull hub.oepkgs.net/a-ops/euler-copilot-rca:0.9.1 +``` + ++ 修改 `config/config.json` 文件,配置 gala-gopher 镜像的 `container_id` 以及 `ip`,Kafka 和 Prometheus 的 `ip` 和 `port`(与上述 gala-anteater 配置保持一致) + +```yaml +"gopher_container_id": "xxxx", # gala-gopher的容器id + "remote_host": "xxxx" # gala-gopher的部署机器ip + }, + "kafka": { + "server": "xxxx", + "port": "xxxx", + "storage_topic": "usad_intermediate_results", + "anteater_result_topic": "xxxx", + "rca_result_topic": "xxxx", + "meta_topic": "xxxx" + }, + "prometheus": { + "server": "xxxx", + "port": "xxxx", + "steps": 5 + }, +``` diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/euler-copilot-tune/flows/data_collection.yaml b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/euler-copilot-tune/flows/data_collection.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d2718f0dd059f3a8a34d02cbc67436c6fc274a28 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/euler-copilot-tune/flows/data_collection.yaml @@ -0,0 +1,15 @@ +name: data_collection +description: 采集某一指定ip主机的系统性能指标 +steps: + - name: start + call_type: api + params: + endpoint: POST /performance_metric + next: show_data + - name: show_data + call_type: llm + params: + user_prompt: | + 当前采集到系统性能指标为:{data}, 输出内容请符合markdown规范。 +next_flow: + - performance_analysis \ No newline at end of file diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/euler-copilot-tune/flows/performance_analysis.yaml b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/euler-copilot-tune/flows/performance_analysis.yaml new file mode 100644 index 0000000000000000000000000000000000000000..07e2a2ada9c54568be3f3bf13c5b2223e615037a --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/euler-copilot-tune/flows/performance_analysis.yaml @@ -0,0 +1,15 @@ +name: performance_analysis +description: 分析性能指标并生成性能分析报告 +steps: + - name: start + call_type: api + params: + endpoint: POST /performance_report + next: extract_key + - name: extract_key + call_type: extract + params: + keys: + - data.output +next_flow: + - performance_tuning \ No newline at end of file diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/euler-copilot-tune/flows/performance_tuning.yaml b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/euler-copilot-tune/flows/performance_tuning.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e938a0bf1bd83f971c4eaaff2d447a150fcf5560 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/euler-copilot-tune/flows/performance_tuning.yaml @@ -0,0 +1,13 @@ +name: performance_tuning +description: 基于性能能分析报告,生成操作系统和Mysql应用的性能优化建议,结果以shell脚本的形式返回 +steps: + - name: start + call_type: api + params: + endpoint: POST /optimization_suggestion + next: extract_key + - name: extract_key + call_type: extract + params: + keys: + - data.script \ No newline at end of file diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/euler-copilot-tune/openapi.yaml b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/euler-copilot-tune/openapi.yaml new file mode 100644 index 0000000000000000000000000000000000000000..18ede5a988fdc06c9de09ff0f2b7077554bedbff --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/euler-copilot-tune/openapi.yaml @@ -0,0 +1,147 @@ +openapi: 3.0.2 +info: + title: 智能诊断 + version: 1.0.0 +servers: + - url: http://euler-copilot-tune.euler-copilot.svc.cluster.local:8100 +paths: + /performance_metric: + post: + description: 对指定机器进行性能指标采集,返回指标值 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PerformanceMetricRequestData' + required: true + responses: + '200': + description: Successful Response + content: + application/json: + schema: {} + '422': + description: Validation Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + /performance_report: + post: + description: 基于采集到的指标,对指定机器进行性能诊断,生成性能分析报告 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PerformanceReportRequestData' + required: true + responses: + '200': + description: Successful Response + content: + application/json: + schema: {} + '422': + description: Validation Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + /optimization_suggestion: + post: + description: 根据性能分析报告,以及指定的机器应用信息,生成调优建议 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/OptimizationSuggestionRequestData' + required: true + responses: + '200': + description: Successful Response + content: + application/json: + schema: {} + '422': + description: Validation Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' +components: + schemas: + HTTPValidationError: + type: object + description: HTTP 校验错误 + properties: + detail: + type: array + items: + $ref: '#/components/schemas/ValidationError' + OptimizationSuggestionRequestData: + type: object + description: 生成优化建议的接口的入参 + required: + - app + - ip + properties: + app: + type: string + description: 应用名称 + default: mysql + enum: + - mysql + - none + ip: + type: string + description: 点分十进制的ipv4地址, 例如192.168.10.43 + example: "192.168.10.43" + PerformanceMetricRequestData: + type: object + description: 性能指标采集的接口的入参 + required: + - app + - ip + properties: + ip: + type: string + description: 点分十进制的ipv4地址, 例如192.168.10.43 + example: "192.168.10.43" + app: + type: string + description: App + default: none + enum: + - mysql + - none + PerformanceReportRequestData: + type: object + description: 生成性能报告接口的入参 + required: + - ip + properties: + ip: + type: string + description: 点分十进制的ipv4地址, 例如192.168.10.43 + example: "192.168.10.43" + ValidationError: + type: object + required: + - loc + - msg + - type + title: ValidationError + properties: + loc: + type: array + items: + anyOf: + - type: string + - type: integer + title: Location + msg: + type: string + title: Message + type: + type: string + title: Error Type \ No newline at end of file diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/euler-copilot-tune/plugin.json b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/euler-copilot-tune/plugin.json new file mode 100644 index 0000000000000000000000000000000000000000..c4b95f57e6169a93dcaf7c08e2d328f5be6bf893 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/euler-copilot-tune/plugin.json @@ -0,0 +1,6 @@ +{ + "id": "tune", + "name": "智能性能优化", + "description": "该插件具备以下功能:采集系统性能指标,分析系统性能,推荐系统性能优化建议", + "automatic_flow": false +} \ No newline at end of file diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/plugin-intelligent-tuning-deployment-guide.md b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/plugin-intelligent-tuning-deployment-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..1eac128f0f816c690cd1f5a281ab8cb5d30587cf --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/deployment/plugin_deployment_guide/intelligent_tuning/plugin-intelligent-tuning-deployment-guide.md @@ -0,0 +1,131 @@ +# 智能调优部署指南 + +## 准备工作 + ++ 提前安装 [openEuler Copilot System 命令行(智能 Shell)客户端](../../../usage_guide/command_line_client/command-line-assistant-usage-guide.md) + ++ 被调优机器需要为 openEuler 22.03 LTS-SP3 + ++ 在需要被调优的机器上安装依赖 + +```bash +yum install -y sysstat perf +``` + ++ 被调优机器需要开启 SSH 22端口 + +## 编辑配置文件 + +修改values.yaml文件的tune部分,将 `enable` 字段改为 `True` ,并配置大模型设置、 +Embedding模型文件地址、以及需要调优的机器和对应机器上的 mysql 的账号名以及密码 + +```bash +vim /home/euler-copilot-framework/euler-copilot-helm/chart/agents/values.yaml +``` + +```yaml +tune: + # 【必填】是否启用智能调优Agent + enabled: true + # 镜像设置 + image: + # 镜像仓库。留空则使用全局设置。 + registry: "" + # 【必填】镜像名称 + name: euler-copilot-tune + # 【必填】镜像标签 + tag: "0.9.1" + # 拉取策略。留空则使用全局设置。 + imagePullPolicy: "" + # 【必填】容器根目录只读 + readOnly: false + # 性能限制设置 + resources: {} + # Service设置 + service: + # 【必填】Service类型,ClusterIP或NodePort + type: ClusterIP + nodePort: + # 大模型设置 + llm: + # 【必填】模型地址(需要包含v1后缀) + url: + # 【必填】模型名称 + name: "" + # 【必填】模型API Key + key: "" + # 【必填】模型最大Token数 + max_tokens: 8096 + # 【必填】Embedding模型文件地址 + embedding: "" + # 待优化机器信息 + machine: + # 【必填】IP地址 + ip: "" + # 【必填】Root用户密码 + # 注意:必需启用Root用户以密码形式SSH登录 + password: "" + # 待优化应用设置 + mysql: + # 【必填】数据库用户名 + user: "root" + # 【必填】数据库密码 + password: "" +``` + +## 安装智能调优插件 + +```bash +helm install -n euler-copilot agents . +``` + +如果之前有执行过安装,则按下面指令更新插件服务 + +```bash +helm upgrade-n euler-copilot agents . +``` + +如果 framework未重启,则需要重启framework配置 + +```bash +kubectl delete pod framework-deploy-service-bb5b58678-jxzqr -n eulercopilot +``` + +## 测试 + ++ 查看 tune 的 pod 状态 + + ```bash + NAME READY STATUS RESTARTS AGE + authhub-backend-deploy-authhub-64896f5cdc-m497f 2/2 Running 0 16d + authhub-web-deploy-authhub-7c48695966-h8d2p 1/1 Running 0 17d + pgsql-deploy-databases-86b4dc4899-ppltc 1/1 Running 0 17d + redis-deploy-databases-f8866b56-kj9jz 1/1 Running 0 17d + mysql-deploy-databases-57f5f94ccf-sbhzp 2/2 Running 0 17d + framework-deploy-service-bb5b58678-jxzqr 2/2 Running 0 16d + rag-deploy-service-5b7887644c-sm58z 2/2 Running 0 110m + vectorize-deploy-service-57f5f94ccf-sbhzp 2/2 Running 0 17d + web-deploy-service-74fbf7999f-r46rg 1/1 Running 0 2d + tune-deploy-agents-5d46bfdbd4-xph7b 1/1 Running 0 2d + ``` + ++ pod启动失败排查办法 + + 检查 euler-copilot-tune 目录下的 openapi.yaml 中 `servers.url` 字段,确保调优服务的启动地址被正确设置 + + 检查 `$plugin_dir` 插件文件夹的路径是否配置正确,该变量位于 `euler-copilot-helm/chart/euler_copilot/values.yaml` 中的 `framework`模块,如果插件目录不存在,需新建该目录,并需要将该目录下的 euler-copilot-tune 文件夹放到 `$plugin_dir` 中。 + + 检查sglang的地址和key填写是否正确,该变量位于 `vim /home/euler-copilot-framework/euler-copilot-helm/chart/euler_copilot/values.yaml` + + ```yaml + # 用于Function Call的模型 + scheduler: + # 推理框架类型 + backend: sglang + # 模型地址 + url: "" + # 模型 API Key + key: "" + # 数据库设置 + ``` + ++ 命令行客户端使用智能调优 + + 具体使用可参考 [openEuler Copilot System 命令行(智能插件:智能调优)](../../../usage_guide/command_line_client/intelligent-tuning.md) diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/command-line-assistant-usage-guide.md b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/command-line-assistant-usage-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..d965d51e293c8304710c0469f1da4b605db7b32e --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/command-line-assistant-usage-guide.md @@ -0,0 +1,169 @@ +# 命令行助手使用指南 + +## 简介 + +openEuler Copilot System 命令行助手是一个命令行(Shell)AI 助手,您可以通过它来快速生成 Shell 命令并执行,从而提高您的工作效率。除此之外,基于 Gitee AI 在线服务的标准版本还内置了 openEuler 的相关知识,可以助力您学习与使用 openEuler 操作系统。 + +## 环境要求 + +- 操作系统:openEuler 22.03 LTS SP3,或者 openEuler 24.03 LTS 及以上版本 +- 命令行软件: + - Linux 桌面环境:支持 GNOME、KDE、DDE 等桌面环境的内置终端 + - 远程 SSH 链接:支持兼容 xterm-256 与 UTF-8 字符集的终端 + +## 安装 + +openEuler Copilot System 命令行助手支持通过 OEPKGS 仓库进行安装。 + +### 配置 OEPKGS 仓库 + +```bash +sudo dnf config-manager --add-repo https://repo.oepkgs.net/openeuler/rpm/`sed 's/release //;s/[()]//g;s/ /-/g' /etc/openEuler-release`/extras/`uname -m` +``` + +```bash +sudo dnf clean all +``` + +```bash +sudo dnf makecache +``` + +### 安装命令行助手 + +```bash +sudo dnf install eulercopilot-cli +``` + +若遇到 `Error: GPG check FAILED` 错误,使用 `--nogpgcheck` 跳过检查。 + +```bash +sudo dnf install --nogpgcheck eulercopilot-cli +``` + +## 初始化 + +```bash +copilot --init +``` + +然后根据提示输入 API Key 完成配置。 + +![shell-init](./pictures/shell-init.png) + +初次使用前请先退出终端或重新连接 SSH 会话使配置生效。 + +- **查看助手帮助页面** + + ```bash + copilot --help + ``` + + ![shell-help](./pictures/shell-help.png) + +## 使用 + +在终端中输入问题,按下 `Ctrl + O` 提问。 + +### 快捷键 + +- 输入自然语言问题后,按下 `Ctrl + O` 可以直接向 AI 提问。 +- 直接按下 `Ctrl + O` 可以自动填充命令前缀 `copilot`,输入参数后按下 `Enter` 即可执行。 + +### 智能问答 + +命令行助手初始化完成后,默认处于智能问答模式。 +命令提示符**左上角**会显示当前模式。 +若当前模式不是“智能问答”,执行 `copilot -c` (`copilot --chat`) 切换到智能问答模式。 + +![chat-ask](./pictures/shell-chat-ask.png) + +AI 回答完毕后,会根据历史问答生成推荐问题,您可以复制、粘贴到命令行中进行追问。输入追问的问题后,按下 `Enter` 提问。 + +![chat-next](./pictures/shell-chat-continue.png) + +![chat-next-result](./pictures/shell-chat-continue-result.png) + +智能问答模式下支持连续追问,每次追问最多可以关联3条历史问答的上下文。 + +输入 `exit` 可以退出智能问答模式,回到 Linux 命令行。 + +![chat-exit](./pictures/shell-chat-exit.png) + +- 若问答过程中遇到程序错误,可以按下 `Ctrl + C` 立即退出当前问答,再尝试重新提问。 + +### Shell 命令 + +AI 会根据您的问题返回 Shell 命令,openEuler Copilot System 命令行助手可以解释、编辑或执行这些命令,并显示命令执行结果。 + +![shell-cmd](./pictures/shell-cmd.png) + +命令行助手会自动提取 AI 回答中的命令,并显示相关操作。您可以通过键盘上下键选择操作,按下 `Enter` 确认。 + +![shell-cmd-interact](./pictures/shell-cmd-interact.png) + +#### 解释 + +如果 AI 仅返回了一条命令,选择解释后会直接请求 AI 解释命令,并显示回答。 +若 AI 回答了多条命令,选择后会显示命令列表,您每次可以选择**一条**请求 AI 解释。 + +![shell-cmd-explain-select](./pictures/shell-cmd-explain-select.png) + +完成解释后,您可以继续选择其他操作。 + +![shell-cmd-explain-result](./pictures/shell-cmd-explain-result.png) + +#### 编辑 + +![shell-cmd-edit](./pictures/shell-cmd-edit.png) + +选择一条命令进行编辑,编辑完成后按下 `Enter` 确认。 + +![shell-cmd-edit-result](./pictures/shell-cmd-edit-result.png) + +完成编辑后,您可以继续编辑其他命令或选择其他操作。 + +#### 执行 + +如果 AI 仅返回了一条命令,选择执行后会直接执行命令,并显示执行结果。 +若 AI 回答了多条命令,选择后会显示命令列表,您每次可以选择**多条**命令来执行。 + +您可以通过键盘上下键移动光标,按下 `空格键` 选择命令,按下 `Enter` 执行所选命令。 +被选中的命令会显示**蓝色高亮**,如图所示。 + +![shell-cmd-exec-multi-select](./pictures/shell-cmd-exec-multi-select.png) + +若不选择任何命令,直接按下 `Enter`,则会跳过执行命令,直接进入下一轮问答。 + +按下 `Enter` 后,被选中的命令会从上到下依次执行。 + +![shell-cmd-exec-result](./pictures/shell-cmd-exec-result.png) + +若执行过程中遇到错误,命令行助手会显示错误信息,并**终止执行命令**,进入下一轮问答。 +您可以在下一轮问答中提示 AI 更正命令,或要求 AI 重新生成命令。 + +### 智能插件 + +在 Linux 命令行中执行 `copilot -p` (`copilot --plugin`) 切换到智能插件模式。 + +![shell-plugin](./pictures/shell-plugin.png) + +输入问题并按下 `Ctrl + O` 提问后,从列表中选择插件,按下 `Enter` 调用插件回答问题。 + +![shell-plugin-select](./pictures/shell-plugin-select.png) + +![shell-plugin-result](./pictures/shell-plugin-result.png) + +## 卸载 + +```bash +sudo dnf remove eulercopilot-cli +``` + +然后使用以下命令删除配置文件。 + +```bash +rm ~/.config/eulercopilot/config.json +``` + +卸载完成后请重启终端或重新连接 SSH 会话使配置还原。 diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/get-api-key.md b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/get-api-key.md new file mode 100644 index 0000000000000000000000000000000000000000..01381a772743299de24d58a7a94bf0a180f77d29 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/get-api-key.md @@ -0,0 +1,28 @@ +# 获取 API Key + +## 前言 + +openEuler Copilot System 命令行助手使用 API Key 来验证用户身份,并获取 API 访问权限。 +因此,开始使用前,您需要先获取 API Key。 + +## 注意事项 + +- 请妥善保管您的 API Key,不要泄露给他人。 +- API Key 仅用于命令行助手与 DevStation 桌面端,不用于其他用途。 +- 每位用户仅可拥有一个 API Key,重复创建 API Key 将导致旧密钥失效。 +- API Key 仅在创建时显示一次,请务必及时保存。若密钥丢失,您需要重新创建。 +- 若您在使用过程中遇到“请求过于频繁”的错误,您的 API Key 可能已被他人使用,请及时前往官网刷新或撤销 API Key。 + +## 获取方法 + +1. 登录 [openEuler Copilot System (Gitee AI) 官网](https://eulercopilot.gitee.com)。 +2. 点击右上角头像,选择“API KEY”。 +3. 点击“新建”按钮。 +4. **请立即保存 API Key,它仅在创建时显示一次,请勿泄露给他人。** + +## 管理 API Key + +1. 登录 [openEuler Copilot System (Gitee AI) 官网](https://eulercopilot.gitee.com)。 +2. 点击右上角头像,选择“API KEY”。 +3. 点击“刷新”按钮,刷新 API Key;点击“撤销”按钮,撤销 API Key。 + - 刷新 API Key 后,旧密钥失效,请立即保存新生成的 API Key。 diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/intelligent-diagnosis.md b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/intelligent-diagnosis.md new file mode 100644 index 0000000000000000000000000000000000000000..eb999cb5483620450b2e2aea77a818382aeca2a4 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/intelligent-diagnosis.md @@ -0,0 +1,50 @@ +# 智能插件:智能诊断 + +部署智能诊断工具后,可以通过 openEuler Copilot System 智能体框架实现对本机进行诊断。 +在智能诊断模式提问,智能体框架服务可以调用本机的诊断工具诊断异常状况、分析并生成报告。 + +## 操作步骤 + +**步骤1** 切换到“智能插件”模式 + +```bash +copilot -p +``` + +![切换到智能插件模式](./pictures/shell-plugin-diagnose-switch-mode.png) + +**步骤2** 异常事件检测 + +```bash +帮我进行异常事件检测 +``` + +按下 `Ctrl + O` 键提问,然后在插件列表中选择“智能诊断”。 + +![异常事件检测](./pictures/shell-plugin-diagnose-detect.png) + +**步骤3** 查看异常事件详情 + +```bash +查看 XXX 容器的异常事件详情 +``` + +![查看异常事件详情](./pictures/shell-plugin-diagnose-detail.png) + +**步骤4** 执行异常事件分析 + +```bash +请对 XXX 容器的 XXX 指标执行 profiling 分析 +``` + +![异常事件分析](./pictures/shell-plugin-diagnose-profiling.png) + +**步骤5** 查看异常事件分析报告 + +等待 5 至 10 分钟,然后查看分析报告。 + +```bash +查看 对应的 profiling 报告 +``` + +![执行优化脚本](./pictures/shell-plugin-diagnose-report.png) diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/intelligent-tuning.md b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/intelligent-tuning.md new file mode 100644 index 0000000000000000000000000000000000000000..b5c40581668ae4f6074043e62a93b2c4b240e5b3 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/intelligent-tuning.md @@ -0,0 +1,53 @@ +# 智能插件:智能调优 + +部署智能调优工具后,可以通过 openEuler Copilot System 智能体框架实现对本机进行调优。 +在智能调优模式提问,智能体框架服务可以调用本机的调优工具采集性能指标,并生成性能分析报告和性能优化建议。 + +## 操作步骤 + +**步骤1** 切换到“智能调优”模式 + +```bash +copilot -t +``` + +![切换到智能调优模式](./pictures/shell-plugin-tuning-switch-mode.png) + +**步骤2** 采集性能指标 + +```bash +帮我进行性能指标采集 +``` + +![性能指标采集](./pictures/shell-plugin-tuning-metrics-collect.png) + +**步骤3** 生成性能分析报告 + +```bash +帮我生成性能分析报告 +``` + +![性能分析报告](./pictures/shell-plugin-tuning-report.png) + +**步骤4** 生成性能优化建议 + +```bash +请生成性能优化脚本 +``` + +![性能优化脚本](./pictures/shell-plugin-tuning-script-gen.png) + +**步骤5** 选择“执行命令”,运行优化脚本 + +![执行优化脚本](./pictures/shell-plugin-tuning-script-exec.png) + +- 脚本内容如图: + ![优化脚本内容](./pictures/shell-plugin-tuning-script-view.png) + +## 远程调优 + +如果需要对其他机器进行远程调优,请在上文示例的问题前面加上对应机器的 IP 地址。 + +例如:`请对 192.168.1.100 这台机器进行性能指标采集。` + +进行远程调优前请确保目标机器已部署智能调优工具,同时请确保 openEuler Copilot System 智能体框架能够访问目标机器。 diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-chat-ask.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-chat-ask.png new file mode 100644 index 0000000000000000000000000000000000000000..00d5cf5ecf894dd62366ec086bf96eae532f0b5d Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-chat-ask.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-chat-continue-result.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-chat-continue-result.png new file mode 100644 index 0000000000000000000000000000000000000000..f30f9fe7a015e775742bc184b8ac75790dc482fa Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-chat-continue-result.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-chat-continue.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-chat-continue.png new file mode 100644 index 0000000000000000000000000000000000000000..7e4801504fd53fab989574416e6220c4fa3f1d38 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-chat-continue.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-chat-exit.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-chat-exit.png new file mode 100644 index 0000000000000000000000000000000000000000..0bb81190a3039f6c5a311b365376ec230c1ad4b5 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-chat-exit.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-edit-result.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-edit-result.png new file mode 100644 index 0000000000000000000000000000000000000000..c5e6f8245e7d66cdbe5370f18d15a791a33a517a Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-edit-result.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-edit.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-edit.png new file mode 100644 index 0000000000000000000000000000000000000000..bb6209373a6d2a1881728bee352e7c3b46cc91d7 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-edit.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-exec-multi-select.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-exec-multi-select.png new file mode 100644 index 0000000000000000000000000000000000000000..2dda108a39af54fc15a4ff8c0dca107de38b9cf0 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-exec-multi-select.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-exec-result.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-exec-result.png new file mode 100644 index 0000000000000000000000000000000000000000..f4fff6a62b8b4220b52fdf55b133f2ba37850569 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-exec-result.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-explain-result.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-explain-result.png new file mode 100644 index 0000000000000000000000000000000000000000..707dd36aa7c7eadae4f29254cf5fc18ce877f597 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-explain-result.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-explain-select.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-explain-select.png new file mode 100644 index 0000000000000000000000000000000000000000..bf58b69e241ea11a6945f21e3fc69d22a401be2e Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-explain-select.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-interact.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-interact.png new file mode 100644 index 0000000000000000000000000000000000000000..00bb3a288fbd2fb962b08f34fbe90c733afe0343 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd-interact.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd.png new file mode 100644 index 0000000000000000000000000000000000000000..619172c8ed60a7b536364944a306fbf76fcbfb1f Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-cmd.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-help.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-help.png new file mode 100644 index 0000000000000000000000000000000000000000..97d0dedd3f7b1c749bc5fded471744923d766b8b Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-help.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-init.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-init.png new file mode 100644 index 0000000000000000000000000000000000000000..bbb2257eb1ff2bfec36110409fc6c55a26386c9e Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-init.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-diagnose-detail.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-diagnose-detail.png new file mode 100644 index 0000000000000000000000000000000000000000..7bd624e025eaae4b77c603d88bf1b9ad5e235fe7 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-diagnose-detail.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-diagnose-detect.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-diagnose-detect.png new file mode 100644 index 0000000000000000000000000000000000000000..2b38259ff0c1c7045dbff9abf64f36a109a3377b Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-diagnose-detect.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-diagnose-profiling.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-diagnose-profiling.png new file mode 100644 index 0000000000000000000000000000000000000000..0e63c01f35dbc291f805b56de749eac09e0a079d Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-diagnose-profiling.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-diagnose-report.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-diagnose-report.png new file mode 100644 index 0000000000000000000000000000000000000000..c16f0184a2ad3d2468466b33d0e861d2a31bc4e2 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-diagnose-report.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-diagnose-switch-mode.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-diagnose-switch-mode.png new file mode 100644 index 0000000000000000000000000000000000000000..165c6c453353b70c3e1e2cb07d7f43d5ee3525e3 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-diagnose-switch-mode.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-result.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-result.png new file mode 100644 index 0000000000000000000000000000000000000000..3e3f45a974a0700d209f7d30af89eb2050a392d6 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-result.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-select.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-select.png new file mode 100644 index 0000000000000000000000000000000000000000..13959203c77eaa9f41051897cf9e847ff3642a8a Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-select.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-metrics-collect.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-metrics-collect.png new file mode 100644 index 0000000000000000000000000000000000000000..4d5678b7f77b05d48552fcb9656f4a4372dbbe61 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-metrics-collect.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-report.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-report.png new file mode 100644 index 0000000000000000000000000000000000000000..01daaa9a84c13158a95afddffeb8a7e3303f1e76 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-report.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-script-exec.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-script-exec.png new file mode 100644 index 0000000000000000000000000000000000000000..0b694c3fba6918ef39cca977b2072b2913d12b95 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-script-exec.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-script-gen.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-script-gen.png new file mode 100644 index 0000000000000000000000000000000000000000..6e95551767e213f59669d03fd4cceba05801a983 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-script-gen.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-script-view.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-script-view.png new file mode 100644 index 0000000000000000000000000000000000000000..c82c77bf6f4e4e19f400395aaadc9f99dc8d373c Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-script-view.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-switch-mode.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-switch-mode.png new file mode 100644 index 0000000000000000000000000000000000000000..0f06c803ea3621a0f4fb83bbbe731e2bb4bba788 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin-tuning-switch-mode.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin.png new file mode 100644 index 0000000000000000000000000000000000000000..4c1afd306a6aee029f5bda38aa7b1fce57227e31 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/command_line_client/pictures/shell-plugin.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/foreword.md b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/foreword.md new file mode 100644 index 0000000000000000000000000000000000000000..3ac2fbeed54beeb5740d581f0ba359535e769d27 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/foreword.md @@ -0,0 +1,68 @@ +# 前言 + +## 概述 + +本文档介绍了 openEuler Copilot System 的使用方法,对 openEuler Copilot System 线上服务的 Web 界面的各项功能做了详细介绍,同时提供了常见的问题解答,详细请参考对应手册。 + +## 读者对象 + +本文档主要适用于 openEuler Copilot System 的使用人员。使用人员必须具备以下经验和技能: + +- 熟悉 openEuler 操作系统相关情况。 +- 有 AI 对话使用经验。 + +## 修改记录 + +| 文档版本 | 发布日期 | 修改说明 | +|--------|------------|----------------| +| 03 | 2024-09-19 | 更新新版界面。 | +| 02 | 2024-05-13 | 优化智能对话操作指引。 | +| 01 | 2024-01-28 | 第一次正式发布。 | + +## 介绍 + +### 免责声明 + +- 使用过程中涉及的非工具本身验证功能所用的用户名和密码,不作他用,且不会被保存在系统环境中。 +- 在您进行对话或操作前应当确认您为应用程序的所有者或已获得所有者的充足授权同意。 +- 对话结果中可能包含您所分析应用的内部信息和相关数据,请妥善管理。 +- 除非法律法规或双方合同另有规定,openEuler 社区对分析结果不做任何明示或暗示的声明和保证,不对分析结果的适销性、满意度、非侵权性或特定用途适用性等作出任何保证或者承诺。 +- 您根据分析记录所采取的任何行为均应符合法律法规的要求,并由您自行承担风险。 +- 未经所有者授权,任何个人或组织均不得使用应用程序及相关分析记录从事任何活动。openEuler 社区不对由此造成的一切后果负责,亦不承担任何法律责任。必要时,将追究其法律责任。 + +### openEuler Copilot System 简介 + +openEuler Copilot System 是一个基于 openEuler 操作系统的人工智能助手,可以帮助用户解决各种技术问题,提供技术支持和咨询服务。它使用了最先进的自然语言处理技术和机器学习算法,能够理解用户的问题并提供相应的解决方案。 + +### 场景内容 + +1. OS 领域通用知识:openEuler Copilot System 可以咨询 Linux 常规知识、上游信息和工具链介绍和指导。 +2. openEuler 专业知识:openEuler Copilot System 可以咨询 openEuler 社区信息、技术原理和使用指导。 +3. openEuler 扩展知识:openEuler Copilot System 可以咨询 openEuler 周边硬件特性知识和ISV、OSV相关信息。 +4. openEuler 应用案例:openEuler Copilot System 可以提供 openEuler 技术案例、行业应用案例。 +5. shell 命令生成:openEuler Copilot System 可以帮助用户生成单条 shell 命令或者复杂命令。 + +总之,openEuler Copilot System 可以应用于各种场景,帮助用户提高工作效率和了解 Linux、openEuler 等的相关知识。 + +### 访问和使用 + +openEuler Copilot System 通过网址访问 Web 网页进行使用。账号注册与登录请参考[注册与登录](./registration-and-login.md)。使用方法请参考[智能问答使用指南](./intelligent-qa-usage-guide.md)。 + +### 界面说明 + +#### 界面分区 + +openEuler Copilot System 界面主要由如图 1 所示的区域组成,各个区域的作用如表 1 所示。 + +- 图 1 openEuler Copilot System 界面 + +![Copilot 界面](./pictures/main-page-sections.png) + +- 表 1 openEuler Copilot System 首页界面分区说明 + +| 区域 | 名称 | 说明 | +|-----|------------|----------------------------------------------------------------| +| 1 | 设置管理区 | 提供账号登录和退出操作入口和明亮/黑暗模式切换功能 | +| 2 | 对话管理区 | 用于用户新建对话、对话历史记录管理和对话历史记录批量删除操作 | +| 3 | 对话区 | 用于用户和 openEuler Copilot System 的对话聊天 | +| 4 | 服务协议和隐私政策区 | 提供查看服务协议和隐私政策入口 | diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/intelligent-qa-usage-guide.md b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/intelligent-qa-usage-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..cace61003442834e5cf0f8b2327bb50992f1925c --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/intelligent-qa-usage-guide.md @@ -0,0 +1,134 @@ +# 智能问答使用指南 + +## 开始对话 + +在对话区下侧输入框即可输入对话想要提问的内容,输入 `Shift + Enter` 可进行换行,输入 `Enter` 即可发送对话提问内容,或者单击“发送”也可发送对话提问内容。 + +> **说明** +> 对话区位于页面的主体部分,如图 1 所示。 + +- 图 1 对话区 + ![对话区](./pictures/chat-area.png) + +### 多轮连续对话 + +openEuler Copilot System 智能问答支持多轮连续对话。只需要在同一个对话中继续追问即可使用,如图 2 所示。 + +- 图 2 多轮对话 + ![多轮对话](./pictures/context-support.png) + +### 重新生成 + +如遇到 AI 生成的内容有误或不完整的特殊情况,可以要求 AI 重新回答问题。单击对话回答左下侧的“重新生成”文字,可让 openEuler Copilot System 重新回答用户问题,重新回答后,在对话回答右下侧,会出现回答翻页的图标![向前翻页](./pictures/icon-arrow-prev.png)和![向后翻页](./pictures/icon-arrow-next.png),单击![向前翻页](./pictures/icon-arrow-prev.png)或![向后翻页](./pictures/icon-arrow-next.png)可查看不同的回答,如图 3 所示。 + +- 图 3 重新生成 + ![重新生成](./pictures/regenerate.png) + +### 推荐问题 + +在 AI 回答的下方,会展示一些推荐的问题,单击即可进行提问,如图 4 所示。 + +- 图 4 推荐问题 + ![推荐问题](./pictures/recommend-questions.png) + +## 管理对话 + +> **须知** +> +> 对话管理区页面左侧。 + +### 新建对话 + +单击“新建对话”按钮即可新建对话,如图 5 所示。 + +- 图 5 新建对话 + ![新建对话](./pictures/new-chat.png) + +### 对话历史记录搜索 + +在页面左侧历史记录搜索输入框输入关键词,然后单击![icon-search](./pictures/icon-search.png)即可进行对话历史记录搜索如图 6 所示。 + +- 图 6 对话历史记录搜索 + ![对话历史记录搜索](./pictures/search-history.png) + +### 对话历史记录单条管理 + +历史记录的列表位于历史记录搜索栏的下方,在每条对话历史记录的右侧,单击![编辑](./pictures/icon-edit.png)即可编辑对话历史记录的名字,如图 7 所示。 + +- 图 7 重命名历史记录 + ![重命名历史记录](./pictures/rename-session.png) + +在对话历史记录名字重新书写完成后,单击右侧![确认](./pictures/icon-confirm.png)即可完成重命名,或者单击右侧![取消](./pictures/icon-cancel.png)放弃本次重命名,如图 8 所示。 + +- 图 8 完成/取消重命名历史记录 + ![完成/取消重命名历史记录](./pictures/rename-session-confirmation.png) + +另外,单击对话历史记录右侧的删除图标,如图 9 所示,即可对删除单条对话历史记录进行二次确认,在二次确认弹出框,如图 10 所示,单击“确认”,可确认删除单条对话历史记录,或者单击“取消”,取消本次删除。 + +- 图 9 删除单条历史记录 + ![删除单条历史记录](./pictures/delete-session.png) + +- 图 10 删除单条历史记录二次确认 + ![删除单条历史记录二次确认](./pictures/delete-session-confirmation.png) + +### 对话历史记录批量删除 + +首先单击“批量删除”,如图 11 所示。 + +- 图 11 批量删除 + ![批量删除](./pictures/bulk-delete.png) + +然后可对历史记录进行选择删除,如图 12 所示。单击“全选”,即对所有历史记录选中,单击单条历史记录或历史记录左侧的选择框,可对单条历史记录进行选中。 + +- 图 12 批量删除历史记录选择 + ![批量删除历史记录选择](./pictures/bulk-delete-multi-select.png) + +最后需要对批量删除历史记录进行二次确认,如图 13 所示,单击“确认”,即删除,单击“取消”,即取消本次删除。 + +- 图 13 批量删除二次确认 + ![批量删除二次确认](./pictures/bulk-delete-confirmation.png) + +## 反馈与举报 + +在对话记录区,对话回答的右下侧,可进行对话回答反馈,如图 14 所示,单击![满意](./pictures/icon-thumb-up.png),可给对话回答点赞;单击![不满意](./pictures/icon-thumb-down.png),可以给对话回答反馈不满意的原因。 + +- 图 14 点赞和不满意反馈 + ![点赞和不满意反馈](./pictures/feedback.png) + +对于反馈不满意原因,如图 15 所示,在单击![不满意](./pictures/icon-thumb-down.png)之后,对话机器人会展示反馈内容填写的对话框,可选择相关的不满意原因的选项。 + +- 图 15 回答不满意反馈 + ![回答不满意反馈](./pictures/feedback-illegal.png) + +其中单击选择“存在错误信息”,需要填写参考答案链接和描述,如图 16 所示。 + +- 图 16 回答不满意反馈——存在错误信息 + ![回答不满意反馈——存在错误信息](./pictures/feedback-misinfo.png) + +### 举报 + +如果发现 AI 返回的内容中有违规信息,可以点击右下角按钮举报,如图 17 所示。点击举报后选择举报类型并提交,若没有合适的选项,请选择“其他”并输入原因,如图 18 所示。 + +- 图 17 举报按钮 + ![举报1](./pictures/report.png) + +- 图 18 选择举报类型 + ![举报2](./pictures/report-options.png) + +## 查看服务协议和隐私政策 + +单击文字“服务协议”,即可查看服务协议,单击文字“隐私政策”,即可查看隐私政策,如图 19、图 20 所示。 + +- 图 19 服务协议和隐私政策入口 + ![服务协议和隐私政策入口](./pictures/privacy-policy-entry.png) + +- 图 20 服务协议和隐私政策 + ![服务协议和隐私政策](./pictures/privacy-policy.png) + +## 附录 + +### 用户信息导出说明 + +#### 具体说明 + +openEuler Copilot System 后台存在用户信息导出功能,如用户需要,需主动通过 contact@openeuler.io 邮箱联系我们,运维会将导出的用户信息通过邮箱回送给用户。 diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/introduction-to-intelligent-plugins.md b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/introduction-to-intelligent-plugins.md new file mode 100644 index 0000000000000000000000000000000000000000..3a37dc9384dcc2080ceb7a687e94e9700e4513eb --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/introduction-to-intelligent-plugins.md @@ -0,0 +1,19 @@ +# 智能插件 + +## 使用方法 + +1. 如图所示,在输入框左上角可以选择插件,点击显示插件列表。 + + ![智能插件](./pictures/plugin-list.png) + +2. 勾选一个插件,然后提问。 + + ![智能插件](./pictures/plugin-selected.png) + +3. 等待服务响应,查看返回结果。 + + 智能插件模式下,推荐问题将置顶推荐的工作流,蓝色文字为对应插件名称,点击后可快捷追问。 + + ![智能插件](./pictures/plugin-suggestion.png) + + ![智能插件](./pictures/plugin-result.png) diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/bulk-delete-confirmation.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/bulk-delete-confirmation.png new file mode 100644 index 0000000000000000000000000000000000000000..33230200fbe9f1e0fa72c27f51b8786192aa14f2 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/bulk-delete-confirmation.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/bulk-delete-multi-select.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/bulk-delete-multi-select.png new file mode 100644 index 0000000000000000000000000000000000000000..96d8201681c4a7772c815a2b9183a0efca9179c2 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/bulk-delete-multi-select.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/bulk-delete.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/bulk-delete.png new file mode 100644 index 0000000000000000000000000000000000000000..929230cd06cc792b633ab183155225926d2c300d Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/bulk-delete.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/chat-area.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/chat-area.png new file mode 100644 index 0000000000000000000000000000000000000000..752f18ad4bd85aaa1132c50cc4c7b7dc159aec91 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/chat-area.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/context-support.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/context-support.png new file mode 100644 index 0000000000000000000000000000000000000000..0bd5f091d0eff34d9b5f36eec6df63b191656daa Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/context-support.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/delete-session-confirmation.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/delete-session-confirmation.png new file mode 100644 index 0000000000000000000000000000000000000000..efd07828e97de46c9660c162ef553362765d5577 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/delete-session-confirmation.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/delete-session.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/delete-session.png new file mode 100644 index 0000000000000000000000000000000000000000..596af33f7be41d456a57e6a297820530f8485f34 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/delete-session.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/feedback-illegal.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/feedback-illegal.png new file mode 100644 index 0000000000000000000000000000000000000000..b6e84ba45977d911db960da97bdff714624ba18c Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/feedback-illegal.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/feedback-misinfo.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/feedback-misinfo.png new file mode 100644 index 0000000000000000000000000000000000000000..cc5505226add1e6fbde7b93ff09877038e8cfdce Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/feedback-misinfo.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/feedback.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/feedback.png new file mode 100644 index 0000000000000000000000000000000000000000..9fe1c27acb57d4d24a26c8dde61ee4272f954e46 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/feedback.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/gitee-login-click2signup.jpg b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/gitee-login-click2signup.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dde8fbe201a44c116e58c3d435737f1a6a3f6f34 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/gitee-login-click2signup.jpg differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/gitee-login.jpg b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/gitee-login.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ac922094fd513e3f8642f885351f541200e6450b Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/gitee-login.jpg differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/gitee-signup.jpg b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/gitee-signup.jpg new file mode 100644 index 0000000000000000000000000000000000000000..57e473466cba423be0d6f76814b5a0656804a884 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/gitee-signup.jpg differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-arrow-next.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-arrow-next.png new file mode 100644 index 0000000000000000000000000000000000000000..1a36c84e0965f9dbf1f90e9a3daadcd1a2560951 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-arrow-next.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-arrow-prev.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-arrow-prev.png new file mode 100644 index 0000000000000000000000000000000000000000..eb667e93cc6d51aa191a0ac7607e72d4d6923cbc Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-arrow-prev.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-cancel.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-cancel.png new file mode 100644 index 0000000000000000000000000000000000000000..34d4454b6f92ee12db6841dafe0e94a12c3b9584 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-cancel.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-confirm.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-confirm.png new file mode 100644 index 0000000000000000000000000000000000000000..1d650f8192e04fae8f7b7c08cd527227c91b833a Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-confirm.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-edit.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-edit.png new file mode 100644 index 0000000000000000000000000000000000000000..f7b28aa605b5e899855a261d641d27a2674703eb Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-edit.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-search.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-search.png new file mode 100644 index 0000000000000000000000000000000000000000..7902923196c3394ae8eafaf5a2b6fdf7f19b1f40 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-search.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-thumb-down.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-thumb-down.png new file mode 100644 index 0000000000000000000000000000000000000000..cda14d196d92898da920ed64ad37fa9dd124c775 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-thumb-down.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-thumb-up.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-thumb-up.png new file mode 100644 index 0000000000000000000000000000000000000000..c75ce44bff456e24bc19040c18e4e644bbb77bd1 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-thumb-up.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-user.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-user.png new file mode 100644 index 0000000000000000000000000000000000000000..e6b06878b76d9e6d268d74070539b388129fa8c4 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/icon-user.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/login-popup.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/login-popup.png new file mode 100644 index 0000000000000000000000000000000000000000..4ac4116f72aa56c81affdb31b806325966331aa9 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/login-popup.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/logout.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/logout.png new file mode 100644 index 0000000000000000000000000000000000000000..e2288c35d89d598f3bb8d939bdf6a9d125bcae83 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/logout.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/main-page-sections.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/main-page-sections.png new file mode 100644 index 0000000000000000000000000000000000000000..155b68928177de0785f4705d2df14c0233b24743 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/main-page-sections.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/new-chat.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/new-chat.png new file mode 100644 index 0000000000000000000000000000000000000000..176bb3e1e932caa758a56540345218c57ee2ff20 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/new-chat.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/plugin-list.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/plugin-list.png new file mode 100644 index 0000000000000000000000000000000000000000..2745f7d82a21cd9eba139898f5ea0c5ab979037f Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/plugin-list.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/plugin-result.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/plugin-result.png new file mode 100644 index 0000000000000000000000000000000000000000..7056aebeecba8760e0ca2773348cce0a0b8167f1 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/plugin-result.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/plugin-selected.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/plugin-selected.png new file mode 100644 index 0000000000000000000000000000000000000000..9182ffa57db9da349cb36186a7b3cb035b51b8aa Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/plugin-selected.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/plugin-suggestion.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/plugin-suggestion.png new file mode 100644 index 0000000000000000000000000000000000000000..bb416881550349000f61b0c1bd3dd540878bd6ad Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/plugin-suggestion.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/privacy-policy-entry.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/privacy-policy-entry.png new file mode 100644 index 0000000000000000000000000000000000000000..d7efce3e6e8d477ef47a1bc8a9bba0d087cf8058 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/privacy-policy-entry.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/privacy-policy.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/privacy-policy.png new file mode 100644 index 0000000000000000000000000000000000000000..dc22c50de7f9d2dc3e0bf523175e7915c91c630f Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/privacy-policy.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/recommend-questions.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/recommend-questions.png new file mode 100644 index 0000000000000000000000000000000000000000..076ec7092af7fe7987e5dc7c864a6b9f8b2b1160 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/recommend-questions.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/regenerate.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/regenerate.png new file mode 100644 index 0000000000000000000000000000000000000000..655c9d5002df4a17aaf84e8780fff4a0118c6c01 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/regenerate.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/rename-session-confirmation.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/rename-session-confirmation.png new file mode 100644 index 0000000000000000000000000000000000000000..d64708bd57d53deafdc5ddbb70d9deaeaca0d132 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/rename-session-confirmation.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/rename-session.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/rename-session.png new file mode 100644 index 0000000000000000000000000000000000000000..73e7e19c5ac8e8035df0e4b553a9b78ff5c9a051 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/rename-session.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/report-options.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/report-options.png new file mode 100644 index 0000000000000000000000000000000000000000..8a54fd2598d51fc40b57052f404dd830cf621f4d Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/report-options.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/report.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/report.png new file mode 100644 index 0000000000000000000000000000000000000000..471bcbe8614fc8bab4dcc1805fa1bf4574990fc8 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/report.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/search-history.png b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/search-history.png new file mode 100644 index 0000000000000000000000000000000000000000..2239d14a7aa8bc13a7b8d3ec71ba9ed71b95e850 Binary files /dev/null and b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/pictures/search-history.png differ diff --git a/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/registration-and-login.md b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/registration-and-login.md new file mode 100644 index 0000000000000000000000000000000000000000..06e7b567e921119a31c6e4ec475b0dc51ac96da7 --- /dev/null +++ b/docs/en/25.03/Tools/AI/openEuler_Copilot_System/usage_guide/online_service/registration-and-login.md @@ -0,0 +1,73 @@ +# 登录 openEuler Copilot System + +本章节以 Windows 10 操作系统安装的 Chrome 121 浏览器为例介绍登录 openEuler Copilot System 界面的操作步骤。 + +## 浏览器要求 + +浏览器要求如表 1 所示。 + +- 表 1 浏览器要求 + +| 浏览器类型 | 最低版本 | 推荐版本 | +| ----- | ----- | ----- | +| Google Chrome | 72 | 121 或更高版本 | +| Mozilla Firefox | 89 | 122 或更高版本 | +| Apple Safari | 11.0 | 16.3 或更高版本 | + +## 申请访问权限 + +访问 openEuler Copilot System 在线环境,需要依照[【GITEE AI】openEuler Copilot System 在线环境体验申请教程](https://gitee.com/openeuler/euler-copilot-framework/issues/IARUWT?from=project-issue)申请访问权限 + +## 操作步骤 + +> **须知** +> openEuler Copilot System 线上服务 (Gitee AI) 账号和 Gitee 官网账号是通用的。 + +**步骤1** 打开本地 PC 机的浏览器,在地址栏输入 [https://ai.gitee.com/apps/zhengw99/openEulerCopilotSystem](https://ai.gitee.com/apps/zhengw99/openEulerCopilotSystem),按 `Enter`。在未登录状态,进入 openEuler Copilot System,会出现登录提示弹出框,如图 1 所示。 + +- 图 1 未登录 + +![未登录](./pictures/login-popup.png) + +**步骤2** 登录 openEuler Copilot System(已注册账号)。 + +打开登录界面,如图 2 所示。 + +- 图 2 登录 openEuler Copilot System + +![登录 openEuler Copilot System](./pictures/gitee-login.jpg) + +## 注册 openEuler Copilot System 账号 + +> **前提条件** +> 未注册 Gitee 账号。 + +**步骤1** 进入登录页,单击“点此注册”,如图 3 所示。 + +- 图 3 点此注册 + +![点此注册](./pictures/gitee-login-click2signup.jpg) + +**步骤2** 进入账号注册页,根据页面提示填写相关内容,如图 4 所示。 + +- 图 4 账号注册 + +![账号注册](./pictures/gitee-signup.jpg) + +**步骤3** 按页面要求填写账号信息后,单击“立即注册”,即可注册成功。注册后即可返回登录。 + +## 退出登录 + +> **前提条件** +> 已登录 openEuler Copilot System + +**步骤1** 单击![退出登录](./pictures/icon-user.png)后,会出现“退出登录”下拉框,如图 5 所示。 + +> **说明** +> 账号管理区位于页面的右上角部分,如图 5 所示。 + +- 图 5 账号管理区 + +![账号管理区](./pictures/logout.png) + +**步骤2** 单击“退出登录”即可退出登录,如图 5 所示。 diff --git a/docs/en/25.03/Tools/Cloud/CPDS/CPDS-introduction.md b/docs/en/25.03/Tools/Cloud/CPDS/CPDS-introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..b0c8b3a4f7177ecccf8c09da14a8de368a0f7206 --- /dev/null +++ b/docs/en/25.03/Tools/Cloud/CPDS/CPDS-introduction.md @@ -0,0 +1,57 @@ +# CPDS介绍 + +## 概述 + +CPDS (Container Problem Detect System) 容器故障检测系统,是由北京凝思软件股份有限公司设计并开发的容器集群故障检测系统,该软件系统实现了对容器TOP故障、亚健康检测的监测与识别。 + +## 软件功能 + + **1. 采集集群信息** + +在宿主机上实现节点代理,采用systemd、initv、ebpf等技术,对容器关键服务进行监控;对节点网络、内核、磁盘LVM等相关信息进行采集;对容器内的应用状态、资源消耗情况、关键系统函数执行情况、io执行状态等执行异常进行监控。 + +**2. 集群异常检测** + +采集各节点原始数据,基于异常规则对采集的原始数据进行异常检测,提取关键信息。同时基于异常规则对采集数据进行异常检测,后将检测结果数据和原始数据进行在线上传,并同步进行持久化操作。 + +**3. 节点、业务容器故障/亚健康诊断** + +基于异常检测数据,对节点、业务容器进行故障/亚健康诊断,将分析检测结果进行持久化存储,并提供UI层进行实时、历史的诊断数据查看。 + +## 软件架构 + +CPDS (Container Problem Detect System) 容器故障检测系统由4个组件组成,如下图所示,整体采用微服务架构,组件之间通过API进行通信。 + +![Architecture](images/architecture.png) + +* [cpds-agent](https://gitee.com/openeuler/cpds-agent):信息采集组件,负责采集集群各节点的容器和系统原始数据。 + +* [cpds-detector](https://gitee.com/openeuler/cpds-detector):异常检测组件,根据配置的异常规则对各节点原始数据进行分析,检测节点是否存在异常。 + +* [cpds-analyzer](https://gitee.com/openeuler/cpds-analyzer):故障/亚健康诊断组件,根据配置的诊断规则,对异常节点进行健康分析,计算出节点当前健康状态。 + +* [cpds-dashboard](https://gitee.com/openeuler/cpds-dashboard):用户交互组件,提供web页面,对集群内节点健康情况进行展示,支持诊断规则配置下发。 + +## 特性 + +CPDS支持对以下故障项进行检测。 + +| 序号 | 故障检测项 | +| ---- | ---------- | +| 1 | 容器服务是否正常 | +| 2 | 容器节点代理是否正常 | +| 3 | 容器组是否正常 | +| 4 | 节点健康检测是否正常 | +| 5 | 日志采集是否正常 | +| 6 | 磁盘用量占容量85% | +| 7 | 网络故障 | +| 8 | 内核Crash故障 | +| 9 | 残留LVM盘故障 | +| 10 | CPU使用率超过85% | +| 11 | 节点监控是否正常 | +| 12 | 容器内存申请失败 | +| 13 | 容器内存申请超时 | +| 14 | 容器网络响应超时 | +| 15 | 容器磁盘读写缓慢 | +| 16 | 容器应用僵尸子进程监测 | +| 17 | 容器应用占用子进程、线程创建失败监测 | diff --git a/docs/en/25.03/Tools/Cloud/CPDS/CPDS-user-guide.md b/docs/en/25.03/Tools/Cloud/CPDS/CPDS-user-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..24d9621d519abce0e82d522941d115c2a2983baf --- /dev/null +++ b/docs/en/25.03/Tools/Cloud/CPDS/CPDS-user-guide.md @@ -0,0 +1,3 @@ +# 概述 + +本文档介绍CPDS的安装部署和使用方法,以指导用户快速了解并使用CPDS。 diff --git a/docs/en/25.03/Tools/Cloud/CPDS/_menu.md b/docs/en/25.03/Tools/Cloud/CPDS/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..9fb148967401ca155293d3b21dd2e37b0a4dc738 --- /dev/null +++ b/docs/en/25.03/Tools/Cloud/CPDS/_menu.md @@ -0,0 +1,12 @@ +--- +label: 'CPDS用户指南' +ismanual: 'Y' +description: '使用 CPDS 监测容器故障及亚健康状态' +children: + - label: 'CPDS介绍' + href: './CPDS-introduction.md' + - label: '安装与部署' + href: './installation-and-deployment.md' + - label: '使用方法' + href: './userguide.md' +--- diff --git a/docs/en/25.03/Tools/Cloud/CPDS/images/architecture.png b/docs/en/25.03/Tools/Cloud/CPDS/images/architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..c92664dc42d195e60c46946d0ce224db3fc22dd9 Binary files /dev/null and b/docs/en/25.03/Tools/Cloud/CPDS/images/architecture.png differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\345\216\237\345\247\213\346\225\260\346\215\256\345\233\276\350\241\250.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\345\216\237\345\247\213\346\225\260\346\215\256\345\233\276\350\241\250.png" new file mode 100644 index 0000000000000000000000000000000000000000..3f3929f2cb29a8a211852af1d468322d52b6e1af Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\345\216\237\345\247\213\346\225\260\346\215\256\345\233\276\350\241\250.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\345\216\237\345\247\213\346\225\260\346\215\256\346\243\200\347\264\242.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\345\216\237\345\247\213\346\225\260\346\215\256\346\243\200\347\264\242.png" new file mode 100644 index 0000000000000000000000000000000000000000..da9ab5d92c314be3e97560c449b8e55ff6cc44aa Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\345\216\237\345\247\213\346\225\260\346\215\256\346\243\200\347\264\242.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\345\270\203\345\261\200.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\345\270\203\345\261\200.png" new file mode 100644 index 0000000000000000000000000000000000000000..be9a66c364e92b3376766c59f3cebeebe123daec Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\345\270\203\345\261\200.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\346\227\266\351\227\264\350\214\203\345\233\264\351\200\211\346\213\251.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\346\227\266\351\227\264\350\214\203\345\233\264\351\200\211\346\213\251.png" new file mode 100644 index 0000000000000000000000000000000000000000..f4abd49e0bf2f62b6bea4968bf13a131f859918a Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\346\227\266\351\227\264\350\214\203\345\233\264\351\200\211\346\213\251.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\346\237\245\347\234\213\345\216\237\345\247\213\346\225\260\346\215\256.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\346\237\245\347\234\213\345\216\237\345\247\213\346\225\260\346\215\256.png" new file mode 100644 index 0000000000000000000000000000000000000000..a6d27210ed11f2c2ae66068d0ebd74121fa62437 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\346\237\245\347\234\213\345\216\237\345\247\213\346\225\260\346\215\256.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\346\237\245\347\234\213\350\247\204\345\210\231.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\346\237\245\347\234\213\350\247\204\345\210\231.png" new file mode 100644 index 0000000000000000000000000000000000000000..f896cdb44a15c527fec3a8df8e6149673f194aeb Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\346\237\245\347\234\213\350\247\204\345\210\231.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\346\267\273\345\212\240\350\247\204\345\210\231.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\346\267\273\345\212\240\350\247\204\345\210\231.png" new file mode 100644 index 0000000000000000000000000000000000000000..599665e676bc623604bee376e883524838dd663a Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\346\267\273\345\212\240\350\247\204\345\210\231.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\345\201\245\345\272\267.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\345\201\245\345\272\267.png" new file mode 100644 index 0000000000000000000000000000000000000000..75adbc5d24a46edfe914b2c7e1297882388058fd Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\345\201\245\345\272\267.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\345\256\271\345\231\250\345\201\245\345\272\267\347\233\221\346\216\247.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\345\256\271\345\231\250\345\201\245\345\272\267\347\233\221\346\216\247.png" new file mode 100644 index 0000000000000000000000000000000000000000..9ba876561699f46b49f6bc0cc8815d0b5806087b Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\345\256\271\345\231\250\345\201\245\345\272\267\347\233\221\346\216\247.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\345\256\271\345\231\250\345\201\245\345\272\267\347\233\221\346\216\247\346\216\222\345\272\217.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\345\256\271\345\231\250\345\201\245\345\272\267\347\233\221\346\216\247\346\216\222\345\272\217.png" new file mode 100644 index 0000000000000000000000000000000000000000..a88de9fd4d87411ed5348a3cf43d4bfcd3ea4395 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\345\256\271\345\231\250\345\201\245\345\272\267\347\233\221\346\216\247\346\216\222\345\272\217.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\346\246\202\350\247\210-\346\214\211\351\222\256.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\346\246\202\350\247\210-\346\214\211\351\222\256.png" new file mode 100644 index 0000000000000000000000000000000000000000..e0ceb89269e6f8a161a2613ae9c542199161e1c8 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\346\246\202\350\247\210-\346\214\211\351\222\256.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\346\246\202\350\247\210.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\346\246\202\350\247\210.png" new file mode 100644 index 0000000000000000000000000000000000000000..6f5fd9a5728bb416638feba8174cfb499e5e8f7a Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\346\246\202\350\247\210.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\347\211\251\347\220\206\350\265\204\346\272\220\347\233\221\346\216\247.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\347\211\251\347\220\206\350\265\204\346\272\220\347\233\221\346\216\247.png" new file mode 100644 index 0000000000000000000000000000000000000000..c0253de34176db4b23e1491a86bb7892966a7c96 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\212\202\347\202\271\347\211\251\347\220\206\350\265\204\346\272\220\347\233\221\346\216\247.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\257\212\346\226\255\347\273\223\346\236\234.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\257\212\346\226\255\347\273\223\346\236\234.png" new file mode 100644 index 0000000000000000000000000000000000000000..ffec25e8ff163efc47c38b23fc180ce8188d38dc Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\350\257\212\346\226\255\347\273\223\346\236\234.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\351\233\206\347\276\244-\345\256\271\345\231\250\345\201\245\345\272\267\347\233\221\346\216\247.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\351\233\206\347\276\244-\345\256\271\345\231\250\345\201\245\345\272\267\347\233\221\346\216\247.png" new file mode 100644 index 0000000000000000000000000000000000000000..5924d73d2b659d92387a19521fd0692d07601046 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\351\233\206\347\276\244-\345\256\271\345\231\250\345\201\245\345\272\267\347\233\221\346\216\247.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\351\233\206\347\276\244\346\246\202\350\247\210.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\351\233\206\347\276\244\346\246\202\350\247\210.png" new file mode 100644 index 0000000000000000000000000000000000000000..351614ce5254748c4d233a2189f3f4a71d2f546a Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\351\233\206\347\276\244\346\246\202\350\247\210.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\351\233\206\347\276\244\347\211\251\347\220\206\350\265\204\346\272\220\347\233\221\346\216\247.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\351\233\206\347\276\244\347\211\251\347\220\206\350\265\204\346\272\220\347\233\221\346\216\247.png" new file mode 100644 index 0000000000000000000000000000000000000000..5256783e5f907232f3cbd3655b8ee81c03c0ffdd Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\351\233\206\347\276\244\347\211\251\347\220\206\350\265\204\346\272\220\347\233\221\346\216\247.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\351\233\206\347\276\244\347\212\266\346\200\201-\346\246\202\350\247\210.png" "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\351\233\206\347\276\244\347\212\266\346\200\201-\346\246\202\350\247\210.png" new file mode 100644 index 0000000000000000000000000000000000000000..751887e223d0a323feee7baef3202ed23e6ce5de Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/CPDS/images/cpds-page/\351\233\206\347\276\244\347\212\266\346\200\201-\346\246\202\350\247\210.png" differ diff --git a/docs/en/25.03/Tools/Cloud/CPDS/installation-and-deployment.md b/docs/en/25.03/Tools/Cloud/CPDS/installation-and-deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..4f90b7abae414f19a5ffb2826e6efe3424edaa0a --- /dev/null +++ b/docs/en/25.03/Tools/Cloud/CPDS/installation-and-deployment.md @@ -0,0 +1,258 @@ +# 安装与部署 + +本章介绍如何安装和部署CPDS。 + +## 安装CPDS + +本节介绍CPDS的安装方法。 + +安装cpds-agent。 + +> cpds-agent采集节点原始数据,可在多个节点上单独安装部署。 + +```shell +yum install cpds-agent +``` + +安装cpds-detector + +```shell +yum install cpds-detector +``` + +安装cpds-analyzer + +```shell +yum install cpds-analyzer +``` + +安装cpds-dashboard + +```shell +yum install cpds-dashboard +``` + +安装Cpds + +```shell +yum install Cpds +``` + +## 部署CPDS + +本节介绍CPDS的配置部署。 + +### 配置介绍 + +#### cpds-agent配置 + +cpds-agent采集节点网络信息是采用向指定ip发送icmp包的方式,即"net_diagnostic_dest"需要指定可连接的ip地址,不可指定本节点ip。建议节点指定master的ip,master指定任意一节点ip。 + +```bash +vim /etc/cpds/agent/config.json +``` + +```json +{ + "expose_port":"20001", # 需要监听的端口 + "log_cfg_file": "/etc/cpds/agent/log.conf", + "net_diagnostic_dest": "192.30.25.18" # 发送icmp包的目的ip +} +``` + +#### prometheus配置 + +CPDS 使用prometheus采集cpds-agent产生的原始数据。cpds-agent默认开放20001端口,需编辑prometheus配置文件,连接至cpds-agent以采集数据。 + +```bash +vim /etc/prometheus/prometheus.yml +``` + +```yaml +global: + scrape_interval: 2s + evaluation_interval: 3s +scrape_configs: + - job_name: "cpds" + static_configs: + - targets: ["cpds-agent1:port","cpds-agent2:port","..."] # 填入已部署cpds-agent的ip和端口号 +``` + +#### cpds-detector配置 + +```bash +vim /etc/cpds/detector/config.yml +``` + +```yaml +generic: + bindAddress: "127.0.0.1" # 需要监听的地址 + port: 19091 # 需要监听的端口 + +database: + host: "127.0.0.1" # 数据库 ip 地址 + port: 3306 # 数据库端口号 + username: root # 数据库用户名 + password: root # 数据库密码 + maxOpenConnections: 123 # 最大连接数 + +prometheus: + host: "127.0.0.1" #detector ip 地址 + port: 9090 #prometheus 端口号 + +log: + fileName: "/var/log/cpds/cpds-detector/cpds-detector.log" + level: "warn" + maxAge: 15 + maxBackups: 100 + maxSize: 100 + localTime: true + compress: true +``` + +#### cpds-analyzer配置 + +```bash +vim /etc/cpds/analyzer/config.yml +``` + +```yaml +generic: + bindAddress: "127.0.0.1" # 需要监听的地址 + port: 19091 # 需要监听的端口 + +database: + host: "127.0.0.1" # 数据库 ip 地址 + port: 3306 # 数据库端口号 + username: root # 数据库用户名 + password: root # 数据库密码 + maxOpenConnections: 123 # 最大连接数 + +detector: + host: "127.0.0.1" #detector ip 地址 + port: 19092 #detector 端口号 + +log: + fileName: "/var/log/cpds/cpds-analyzer/cpds-analyzer.log" + level: "warn" + maxAge: 15 + maxBackups: 100 + maxSize: 100 + localTime: true +``` + +#### cpds-dashboard配置 + +```bash +vim /etc/nginx/conf.d/cpds-ui.conf +``` + +```conf +server { + listen 10119; + + location / { + root /etc/cpds/cpds-ui/; + index index.html index.htm; + } + + location /api/ { + proxy_pass http://127.0.0.1:19091; # 后端 analyzer 的 ip 和端口 + } + + location /websocket/ { + proxy_pass http://127.0.0.1:19091; # 后端 analyzer 的 ip 和端口 + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto http; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + } +} +``` + +## 启动CPDS + +本节介绍CPDS的启动方法。 + +### 关闭防火墙 + +```shell +systemctl stop firewalld +systemctl disable firewalld +``` + +修改/etc/selinux/config文件中SELINUX状态为disabled。 + +```conf +SELINUX=disabled +``` + +再重启系统。 + +### 初始化数据库 + +1. 启动数据库 + + ```shell + systemctl start mariadb.service + systemctl enable mariadb.service + ``` + +2. 在root权限下初始化数据库 + + ```shell + /usr/bin/mysql_secure_installation + ``` + + > 命令执行过程中需要输入数据库的root设置的密码,若没有密码则直接按“Enter”。然后根据提示及实际情况进行设置。 + +3. 设置数据库连接权限 + + ```shell + mysql -u root -p + ``` + + 命令执行后提示输入密码。密码为2中设置的密码。 + + ```shell + GRANT ALL PRIVILEGES ON *.* TO 'username'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION; + ``` + + > 其中username为数据库用户名,password为该用户的密码。 + + 例如: + + ```shell + mysql -u root -p + Enter password: + Welcome to the MariaDB monitor. Commands end with ; or \g. + Your MariaDB connection id is 5 + Server version: 10.5.16-MariaDB MariaDB Server + + Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. + + Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + + MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION; + Query OK, 0 rows affected (0.014 sec) + ``` + +### 启动服务 + +```shell +systemctl start Cpds.service +systemctl enable Cpds.service +``` + +启动各节点上的cpds-agent。 + +```shell +systemctl start cpds-agent +systemctl enable cpds-agent +``` + +### 访问前端管理平台 + +上述服务启动成功后,打开浏览器,在浏览器导航栏中输入`http://localhost:10119`访问前端管理平台。 diff --git a/docs/en/25.03/Tools/Cloud/CPDS/userguide.md b/docs/en/25.03/Tools/Cloud/CPDS/userguide.md new file mode 100644 index 0000000000000000000000000000000000000000..3a28bcd38c07abd204355ebf72daab33e60f0b53 --- /dev/null +++ b/docs/en/25.03/Tools/Cloud/CPDS/userguide.md @@ -0,0 +1,266 @@ +# 使用手册 + + + +- [介绍](#介绍) +- [页面及功能说明](#页面及功能说明) + - [页面布局](#页面布局) + - [概览](#概览) + - [监控告警](#监控告警) + - [集群状态](#集群状态) + - [集群状态-概览](#集群状态-概览) + - [集群状态-物理资源监控](#集群状态-物理资源监控) + - [集群状态-容器健康监控](#集群状态-容器健康监控) + - [节点健康](#节点健康) + - [节点健康-概览](#节点健康-概览) + - [节点健康-物理资源监控](#节点健康-物理资源监控) + - [节点健康-容器健康监控](#节点健康-容器健康监控) + - [健康诊断](#健康诊断) + - [诊断结果](#诊断结果) + - [原始数据检索](#原始数据检索) + - [原始数据图表](#原始数据图表) + - [规则管理](#规则管理) + - [查看规则](#查看规则) + - [添加规则](#添加规则) + + + +## 介绍 + +CPDS(Container Problem Detect System)容器故障检测系统,是由北京凝思软件股份有限公司设计并开发的容器集群故障检测系统,该软件系统实现了对容器 TOP 故障、亚健康检测的监测与识别。 + +主要分为四个子模块: + +1. 信息采集组件 cpds-agent:本组件根据cpds-detetor(异常检测组件)需要的数据进行相应采集。 +2. 异常检测组件 cpds-detector:本组件根据cpds-analyzer(容器故障/亚健康诊断组件)下发的异常规则,对集群各节点原始数据进行分析,检测节点是否存在异常。 +3. 故障/亚健康诊断组件 cpds-analyzer:本组件根据cpds-dashboard(用户交互组件)下发的诊断规则,对cpds-detector(异常检测组件)收集的异常数据进行处理,判断集群节点是否处于容器故障/亚健康状态。 +4. 用户交互组件 cpds-dashboard:本组件从 cpds-analyzer(故障/亚健康诊断)组件中获取诊断结果数据,并以实时查看、离线查看的形式进行可视化诊断结果展示,便于容器集群运维人员进行分析与策略制定下发。 + +## 页面及功能说明 + +### 页面布局 + +CPDS页面布局分为导航栏、导航菜单、操作区。 + +页面布局如下图: + +![页面布局](./images/cpds-page/布局.png) + +| 序号 | 名称 | 说明 | +| ---- | ---- | ---- | +| 1 | 导航菜单 | 导航菜单包含 CPDS 所有功能,选择不同菜单项后,右侧操作区将显示对应的操作页面。| +| 2 | 导航栏 | 用于指示用户当前页面位于导航树的位置。 | +| 3 | 操作区 | 显示当前操作信息,提供操作功能。 | + +### 概览 + +概览页面可查看整个集群的状态信息,包括集群容器健康状态、集群节点状态、集资源用量、节点监控状态、诊断结果。查看概览流程如下图所示: + +![集群概览](./images/cpds-page/集群概览.png) + +| 名称 | 说明 | +| ---- | ---- | +| 容器健康状态 | 显示集群中运行中的容器个数占全部容器个数的百分比,并显示全部容器、运行中的容器、停止的容器的个数。 | +| 集群节点状态 | 显示在线节点占全部节点的百分比,并显示全部节点、在线节点、离线节点的个数。 | +| 集群资源用量 | 显示集群 CUP、内容、磁盘的使用的量、总量和使用百分比。 | +| 节点监控状态 | 显示集群节点的 ip 地址、节点状态、节点运行容器数量占比。点击下方的查看更多,会跳转至“监控告警-节点健康”,可以查看更详细的节点信息。 | +| 诊断结果 | 显示触发规则的名称、当前状态、规则第一次触发的时间,以及后续触发的最新时间。点击下方的查看更多,会跳转至“健康诊断-诊断结果”,查看更详细的诊断结果。 | + +### 监控告警 + +监控告警能够对集群、节点的物理资源、容器状态进行监控。 + +#### 集群状态 + +显示集群主机在线状态,提供物理资源监控和容器健康监控。 + +##### 集群状态-概览 + +查看集群信息和节点信息,集群信息包括集群容器健康状态、集群节点状态、集资源用量。查看集群信息流程如下所示: + +1. 点击左侧导航菜单“监控告警”→“集群状态”,选择“概览”标签页,进入概览页面。如下图所示: + +![集群状态-概览](./images/cpds-page/集群状态-概览.png) + +| 名称 | 说明 | +| ---- | ---- | +| 容器健康状态 | 显示集群中运行中的容器个数占全部容器个数的百分比,并显示全部容器、运行中的容器、停止的容器的个数。 | +| 集群节点状态 | 显示在线节点占全部节点的百分比,并显示全部节点、在线节点、离线节点的个数。 | +| 资源使用情况 | 显示集群 CUP、内容、磁盘的使用的量和总量。 | +| 节点监控状态 | 详见 [节点健康](#节点健康)。 | + +##### 集群状态-物理资源监控 + +点击左侧导航菜单“监控告警”→“集群状态”,选择“物理资源监控”标签页,物理资源监控页面内容如下图所示。 +![集群物理资源监控](./images/cpds-page/集群物理资源监控.png) + +其中点击查询时间范围按钮可选择查询数据的时间范围,如下图所示。 +![时间范围选择](./images/cpds-page/时间范围选择.png) + +下面将对物理资源监控内容进行说明。 + +| 名称 | 说明 | +| ---- | ---- | +| 集群总 CPU 使用率 | 集群 CPU 使用百分比 | +| 集群总内存使用率 | 集群内存使用百分比 | +| 集群总磁盘使用率 | 集群磁盘使用百分比 | +| 集群iowait | 集群CPU等待I/O设备完成输入输出操作而处于空闲状态的时间 | +| 网络iops | 集群网卡每秒接收和发送数据包总数 | +| 网络网速 | 集群网卡每秒接收和发送数据大小 | +| 网络丢包率 | 集群单位时间内网卡丢失数据包占总数据包的百分比 | +| 网络错误率 | 集群单位时间内网卡出现错误的数据包占总数据包的百分比 | +| 网络重传率 | 集群单位时间内重传数据包占总数据包的百分比 | +| 集群总磁盘吞吐速率 | 集群磁盘每秒完成读写操作的数据量 | +| 磁盘 iops | 集群磁盘每秒完成读写操作的次数 | + +##### 集群状态-容器健康监控 + +点击左侧导航菜单“监控告警”→“集群状态”,选择“容器健康监控”标签页,该页面显示集群容器健康监控信息如下图所示: +![集群-容器健康监控](./images/cpds-page/集群-容器健康监控.png) + +下面将对容器健康监控内容进行说明。 + +| 名称 | 说明 | +| ---- | ---- | +| 容器CPU使用率 | 容器 CPU 使用量占集群 CPU 总量的百分比 | +| 容器磁盘使用率 | 容器磁盘使用量占集群磁盘总量的百分比 | +| 容器流量 | 容器每秒网卡接收/发送的数据量 | +| 容器内存使用率 | 容器内存使用量占集群内存总量的百分比 | + +#### 节点健康 + +显示各节点主机在线状态及架构信息,提供物理资源监控和容器健康监控。 +> 节点健康主页面如下图所示: + +![节点健康](./images/cpds-page/节点健康.png) + +##### 节点健康-概览 + +点击左侧导航菜单“监控告警”→“节点健康”,点击表格中节点对应的 ip 地址进入节点概览页面。 +> 节点概览页面如下图所示: + +![节点概览](./images/cpds-page/节点概览.png) + +> 点击如下图三个组件,可刷新或切换曲线图展示的数据内容。 + +![节点概览-按钮](./images/cpds-page/节点概览-按钮.png) + +##### 节点健康-物理资源监控 + +点击左侧导航菜单“监控告警”→“节点健康”,点击表格中节点对应的 ip 地址进入节点概览页面,选择“物理资源监控”标签页,物理资源监控页面内容如下图所示: +![节点物理资源监控](./images/cpds-page/节点物理资源监控.png) + +下面将对物理资源监控内容进行说明。 + +| 名称 | 说明 | +| ---- | ---- | +| 节点 CPU 使用率 | 节点 CPU 使用百分比 | +| 节点内存使用率 | 节点内存使用百分比 | +| 节点磁盘使用率 | 节点磁盘使用百分比 | +| 节点iowait | 节点CPU等待I/O设备完成输入输出操作而处于空闲状态的时间 | +| 节点网络iops | 节点网卡每秒接收和发送数据包总数 | +| 节点网络网速 | 节点网卡每秒接收和发送数据大小 | +| 节点网络丢包率 | 节点单位时间内网卡丢失数据包占总数据包的百分比 | +| 节点网络错误率 | 节点单位时间内网卡出现错误的数据包占总数据包的百分比 | +| 节点网络重传率 | 节点单位时间内重传数据包占总数据包的百分比 | +| 节点磁盘吞吐速率 | 节点磁盘每秒完成读写操作的数据量 | +| 节点磁盘 iops | 节点磁盘每秒完成读写操作的次数 | + +##### 节点健康-容器健康监控 + +点击左侧导航菜单“监控告警”→“节点健康”,点击表格中节点对应的 ip 地址进入节点概览页面,选择“容器健康监控”标签页,容器健康监控页面如下图所示: +![节点容器健康监控](./images/cpds-page/节点容器健康监控.png) + +> 该页面可根据容器状态、容器名称进行排序。 + +节点容器健康监控数据说明如下表: + +| 名称 | 说明 | +| ---- | ---- | +| 容器名称 | 容器的完整id | +| 容器状态 | 容器的运行状态,包括:运行中、已创建、停止等待、暂停共四个状态 | +| CPU用量 | 容器CPU使用率 | +| 内存用量 | 容器内存用量 | +| 出站流量 | 容器网卡对外发送数据大小 | +| 如站流量 | 容器网卡对接收数据大小 | + +### 健康诊断 + +利用故障/亚健康检测规则,对各节点原始数据进行计算分析,得出诊断结果,提供诊断结果列表。支持诊断原始数据查看,显示诊断时所使用的原始数据,支持对时间进行过滤,显示不同时间段原始数据的值,并提供图表展示原始数据的变化规律。 + +#### 诊断结果 + +将规则列表中的规则拿来进行判断,满足判断条件的规则将被加入到诊断结果列表中。规则信息详见 [规则管理](#规则管理)。 +查看诊断结果列表流程如下: + +1. 点击左侧导航菜单“健康诊断”→“诊断结果”,进入诊断结果页面。如下图所示: + + ![诊断结果](./images/cpds-page/诊断结果.png) + +2. 可在左上角输入规则名称对诊断结果进行筛选。 + +3. 点击查看原始数据,可以查看最近 10 分钟内原始数据的变化规律,如下图所示: + + ![查看原始数据](./images/cpds-page/查看原始数据.png) + +4. 点击删除可以删除对应的诊断结果。 + +#### 原始数据检索 + +支持诊断原始数据查看,显示诊断时所使用的原始数据,支持对时间进行过滤,显示不同时间段原始数据的值,并提供图表展示原始数据的变化规律。页面布局如下图所示: +![原始数据检索](./images/cpds-page/原始数据检索.png) + +功能说明如下表所示: + +| 名称 | 说明 | +| ---- | ---- | +| 原始数据查询 | 利用表达式对原始数据进行查询,可以设置时间选择器对时间进行过滤。可以查询到一段时间内原始数据的变化规律。 | +| 容器状态 | 当利用表达式成功查询原始数据后,查询记录将被记录到表格中,如果超过 10 条不同表达式记录,最先查询的记录将被删除。如果是相同表达式,那么记录会被覆盖。 | + +##### 原始数据图表 + +原始数据图表如下图所示: +![原始数据图表](./images/cpds-page/原始数据图表.png) + +图表信息说明如下表: + +| 名称 | 说明 | +| ---- | ---- | +| 监控指标 | 显示内容为查询的表达式 | +| 原始数据曲线图 | 显示该表达式在一段时间内查询结果的变化规律 | +| 原始数据表格 | 显示当前时间,查询结果的字段以及值 | + +### 规则管理 + +#### 查看规则 + +支持故障/亚健康检测规则列表查看、创建、编辑、删除功能,列表包括规则名、表达式、告警级别和亚健康、故障比较规则值信息。查看规则流程如下: + +1. 点击左侧导航菜单“规则管理”→“查看规则”,进入规则列表页面,如下图所示: + + ![查看规则](./images/cpds-page/查看规则.png) + +2. 通过左上角输入规则名称,点击搜索可以对规则进行过滤。 +3. 点击删除可以删除对应规则。 + +#### 添加规则 + +点击左侧导航菜单“规则管理”→“查看规则”,进入规则列表页面,点击添加规则或者编辑,如下图所示: + +![添加规则](./images/cpds-page/添加规则.png) + +添加/编辑规则内容有如下几点限制: + +1. 规则名称,只能包含数字、英文字母、下划线。 +2. 表达式必须符合PromQL语法,参考[prometheus官方文档](https://prometheus.io/docs/prometheus/latest/querying/basics/)。 +3. 亚健康阈值只能输入数字类型。 +4. 故障康阈值只能输入数字类型。 + +> 阈值只能在对应的比较条件选择之后才能输入。 +> 当比较条件选择之后,对应的阈值必须填写入。 +> 亚健康比较条件、故障比较条件二者必须选择一个,或者两个都选。 + +## 注意事项 + +1. 默认规则,规则名称为node_etcd_service、node_kube_apiserver、node_kube_controller_manager、node_kube_proxynode_kube_scheduler的规则表达式中的ip需要自行更换为实际ip。 +2. 当前版本CPDS只支持对docker容器运行时的故障检测。 diff --git a/docs/en/25.03/Tools/Cloud/CTinspector/CTinspector-introduction.md b/docs/en/25.03/Tools/Cloud/CTinspector/CTinspector-introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..6e695dae1dabaf30ccc81e29160bb0449979b1dc --- /dev/null +++ b/docs/en/25.03/Tools/Cloud/CTinspector/CTinspector-introduction.md @@ -0,0 +1,46 @@ +# 认识CTinspector + +## 简介 + +CTinspector是天翼云科技有限公司基于ebpf指令集自主创新研发的语言虚拟机运行框架。基于CTinspector运行框架可以快速拓展其应用实例用于诊断网络性能瓶颈点,诊断存储IO处理的热点和负载均衡等,提高系统运行时诊断的稳定性和时效性。 + +CTinspector未引入云上环境基础底座系统运维与问题分析之前,OVS的运维与ACL的配置效率相对较低,且存在一些功能上不支持的问题: + +* 维人员想要使用的过滤字段正好没有实现,或者与或非的条件表达式不支持; + +* 系统中有很多命令都有类似的过滤需求,比如CT流表,openflow流表,卸载流表,如果针对每种流表开发各自的命令行参数,这是一个很重的开发任务; + +* 基于命令行参数的过滤无法实现有状态过滤:比如查看报文数命中最多的流表。传统的过滤规则都是针对单条流表的,无法建立多条流表间的关联关系。 + +## 架构 + +CTinspector采用一个ebpf指令集的语言虚拟机Packet VM,它最小只有256字节,包含所有虚拟机应有的部件:寄存器,堆栈段,代码段,数据段,页表。Packet VM支持自主的migration,即packet VM内的代码可以调用migrate kernel function,以将packet VM迁移至它自己指定的节点。Packaket VM同时支持断点续执行,即packet VM迁移至下一个节点后可以沿着上一个节点中断的位置继续执行下一条指令。 +  +![](./figures/CT-package-vm.png) +  +CTinspector框架总体架构如下图所示: +  +![](./figures/CTinspector-arch.png) +  +CTinspecto框架的主要部件包括: + +* ebpf compiler/JIT: + 将C代码编译为ebpf二进制码,JIT则负责将ebpf指令及时编译为机器码。 + +* ebpf linker/loader: + 负责加载和链接库函数即kernel functions。 + +* runner: + 执行ebpf VM,这包括加载寄存器,代码段,加载堆栈,映射数据段等。 + +* scheduler: + 决定何时执行ebpf VM,这包括判断VM的状态,需要等待的数据依赖条件等。 + +* basic kernel functions: + 基本库函数,包括迁移,映射内存,fork,join_meeting等核心基本功能。 + +* extended kernel functions: + 除了ebpf VM runner提供的核心基本功能外,应用程序的各个hook点都可以提供自定义的库函数。 + +* memory mapper: + 将应用程序数据映射进ebpf VM以方便ebpf程序读写应用数据。 diff --git a/docs/en/25.03/Tools/Cloud/CTinspector/_menu.md b/docs/en/25.03/Tools/Cloud/CTinspector/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..33764e795035be08eba381688d8c45b1ef6a0a7f --- /dev/null +++ b/docs/en/25.03/Tools/Cloud/CTinspector/_menu.md @@ -0,0 +1,12 @@ +--- +label: 'CTinspector用户指南' +ismanual: 'Y' +description: '使用 CTinspector 精准诊断系统运行时性能瓶颈与故障' +children: + - label: 'CTinspector介绍' + href: './CTinspector-introduction.md' + - label: '安装与部署' + href: './installation-and-deployment.md' + - label: '使用方法' + href: './usage.md' +--- diff --git a/docs/en/25.03/Tools/Cloud/CTinspector/figures/CT-package-vm.png b/docs/en/25.03/Tools/Cloud/CTinspector/figures/CT-package-vm.png new file mode 100644 index 0000000000000000000000000000000000000000..bb1ad48a6f28f39b73776b67804332036c32bdce Binary files /dev/null and b/docs/en/25.03/Tools/Cloud/CTinspector/figures/CT-package-vm.png differ diff --git a/docs/en/25.03/Tools/Cloud/CTinspector/figures/CTinspector-arch.png b/docs/en/25.03/Tools/Cloud/CTinspector/figures/CTinspector-arch.png new file mode 100644 index 0000000000000000000000000000000000000000..82f647b7c0a311c8af597ce3fabb3cdf93e5afcc Binary files /dev/null and b/docs/en/25.03/Tools/Cloud/CTinspector/figures/CTinspector-arch.png differ diff --git a/docs/en/25.03/Tools/Cloud/CTinspector/figures/migrate_node_1.png b/docs/en/25.03/Tools/Cloud/CTinspector/figures/migrate_node_1.png new file mode 100644 index 0000000000000000000000000000000000000000..3d7ddb16959cf83235703f564d002f95396f1963 Binary files /dev/null and b/docs/en/25.03/Tools/Cloud/CTinspector/figures/migrate_node_1.png differ diff --git a/docs/en/25.03/Tools/Cloud/CTinspector/figures/migrate_node_2.png b/docs/en/25.03/Tools/Cloud/CTinspector/figures/migrate_node_2.png new file mode 100644 index 0000000000000000000000000000000000000000..99448ced22a6cd34d393ea31cff0ef67d43ec028 Binary files /dev/null and b/docs/en/25.03/Tools/Cloud/CTinspector/figures/migrate_node_2.png differ diff --git a/docs/en/25.03/Tools/Cloud/CTinspector/installation-and-deployment.md b/docs/en/25.03/Tools/Cloud/CTinspector/installation-and-deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..d376cf1703c157f7e6d635ed15a892aa23d36918 --- /dev/null +++ b/docs/en/25.03/Tools/Cloud/CTinspector/installation-and-deployment.md @@ -0,0 +1,42 @@ +# 安装与部署 + +## 软件要求 + +* 操作系统:openEuler 23.09 + +## 硬件要求 + +* x86_64架构 + +## 环境准备 + +* 安装openEuler系统,安装方法参考 《[安装指南](../../../Server/InstallationUpgrade/Installation/installation.md)》。 + +* 安装CTinspector需要使用root权限。 + +## 安装CTinspector + +* 安装CTinspector框架软件包,参考命令如下: + +```shell +[root@openEuler ~]# yum install ctinspector +``` + +* 查看安装是否成功,参考命令如下,若回显有对应软件包,表示安装成功: + +```shell +[root@openEuler ~]# rpm -q ctinspector +``` + +* 查看CTinpsector框架包含的核心动态库libebpf_vm_executor.so与主程序vm_test是否安装成功,文件列表如下: + +```shell +[root@openEuler ~]# rpm -ql ctinspector +/usr/bin/vm_test +/usr/include/ctinspector/ebpf_vm_functions.h +/usr/include/ctinspector/ebpf_vm_simulator.h +/usr/include/ctinspector/ebpf_vm_transport_rdma.h +/usr/include/ctinspector/list.h +/usr/include/ctinspector/ub_list.h +/usr/lib64/libebpf_vm_executor.so +``` diff --git a/docs/en/25.03/Tools/Cloud/CTinspector/usage.md b/docs/en/25.03/Tools/Cloud/CTinspector/usage.md new file mode 100644 index 0000000000000000000000000000000000000000..b2a356ac049eec95acad55ab1da9b51fe35042ed --- /dev/null +++ b/docs/en/25.03/Tools/Cloud/CTinspector/usage.md @@ -0,0 +1,44 @@ +# 使用方法 + +## 网卡配置 + +```shell +# 修改网卡MTU +[root@openEuler ~]# ifconfig ens33 mtu 4200 + +# ens33上增加一个rxe接口,提供IB功能 +[root@openEuler ~]# rdma link add rxe_0 type rxe netdev ens33 + +``` + +## 开发应用实例 + +首先需要基于CTinspector框架,调用相应接口开发特定场景的应用。其次将该应用实例编译构建成基于ebpf指令集的二进制ELF文件。以CTinpsector自带的ebpf_example中vm_migrate为例进行说明,vm_migrate调用CTinpsector框架,可以在不同节点之间不断迁移packet VM,可以从上一个节点迁移时的运行位置在下一个节点接着运行。 + +```shell +# 编写Makefile并设置ebpf指令集 +CFLAGS=-O2 -fno-inline -emit-llvm -I/usr/include/ctinspector/ +LINKFLAGS=-march=bpf -filetype=obj + +all: vm_migrate.o + +vm_migrate.o: + clang $(CFLAGS) -c migrate.c -o - | llc $(LINKFLAGS) -o vm_migrate.o + +clean: + rm -f vm_migrate.o +``` + +```shell +# make进行编译构建 +[root@openEuler ~]# make +clang -O2 -fno-inline -emit-llvm -I/usr/include/ctinspector/ -c migrate.c -o - | llc -march=bpf -filetype=obj -o vm_migrate.o +``` + +## 运行应用实例 + +Node 1上运行vm_migrate +![](./figures/migrate_node_1.png) +  +Node 2上运行CTinpsect主程序 +![](./figures/migrate_node_2.png) diff --git a/docs/en/25.03/Tools/Cloud/PilotGo/_menu.md b/docs/en/25.03/Tools/Cloud/PilotGo/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..c48c86dedd4ec6ac010ed240e6eaa35759384366 --- /dev/null +++ b/docs/en/25.03/Tools/Cloud/PilotGo/_menu.md @@ -0,0 +1,10 @@ +--- +label: 'PilotGo用户指南' +ismanual: 'Y' +description: '使用 PilotGo 运维管理平台管理主机、权限和告警等' +children: + - label: '概述' + href: './pilotgo-introduction.md' + - label: '使用方法' + href: './usage.md' +--- diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/G\346\217\222\344\273\2661.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/G\346\217\222\344\273\2661.png" new file mode 100644 index 0000000000000000000000000000000000000000..5c7eaa4cde3364c70ca6bff24c768edad986a59c Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/G\346\217\222\344\273\2661.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/G\346\217\222\344\273\2662.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/G\346\217\222\344\273\2662.png" new file mode 100644 index 0000000000000000000000000000000000000000..45437297fb46749b9f840f45e38cc3e5c4d0d595 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/G\346\217\222\344\273\2662.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/G\346\217\222\344\273\2663.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/G\346\217\222\344\273\2663.png" new file mode 100644 index 0000000000000000000000000000000000000000..d120fdc034f2c588c222837e8316a33cda339e22 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/G\346\217\222\344\273\2663.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/G\346\217\222\344\273\2664.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/G\346\217\222\344\273\2664.png" new file mode 100644 index 0000000000000000000000000000000000000000..1e2ed031ac525d8a69c98c9f143b3edece72be77 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/G\346\217\222\344\273\2664.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/G\346\217\222\344\273\2665.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/G\346\217\222\344\273\2665.png" new file mode 100644 index 0000000000000000000000000000000000000000..b0f366b001a09dc1d1f4096ff5aa4f5ec6429087 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/G\346\217\222\344\273\2665.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/P\346\217\222\344\273\2661.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/P\346\217\222\344\273\2661.png" new file mode 100644 index 0000000000000000000000000000000000000000..f4a923729e62fb321931342ec56238b568dbf16e Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/P\346\217\222\344\273\2661.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/P\346\217\222\344\273\2662.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/P\346\217\222\344\273\2662.png" new file mode 100644 index 0000000000000000000000000000000000000000..d54a04a42afa0f0ae7d37fb2eef88943e4b402f5 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/P\346\217\222\344\273\2662.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/P\346\217\222\344\273\2663.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/P\346\217\222\344\273\2663.png" new file mode 100644 index 0000000000000000000000000000000000000000..a85aad4547a6dc8b6d55d50524c69c92668e54a6 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/P\346\217\222\344\273\2663.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/P\346\217\222\344\273\2664.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/P\346\217\222\344\273\2664.png" new file mode 100644 index 0000000000000000000000000000000000000000..c56bcc5248a53f9d5daeadaddb998d69ef154c4e Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/P\346\217\222\344\273\2664.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\345\257\206\347\240\2011.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\345\257\206\347\240\2011.png" new file mode 100644 index 0000000000000000000000000000000000000000..a51096f17e336fc0917bce7be08ff69ec2604562 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\345\257\206\347\240\2011.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\345\257\206\347\240\2012.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\345\257\206\347\240\2012.png" new file mode 100644 index 0000000000000000000000000000000000000000..f26d9ddf85da2d5955ce8f9d338fd1bb036b1132 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\345\257\206\347\240\2012.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\345\257\206\347\240\2013.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\345\257\206\347\240\2013.png" new file mode 100644 index 0000000000000000000000000000000000000000..b3ffd4507aab3a85b3ab8e775bc1ab4c1efcfda3 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\345\257\206\347\240\2013.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\350\212\202\347\202\2711.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\350\212\202\347\202\2711.png" new file mode 100644 index 0000000000000000000000000000000000000000..4a127fafef22d62f326e38075173f53f244acfa7 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\350\212\202\347\202\2711.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\350\212\202\347\202\2712.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\350\212\202\347\202\2712.png" new file mode 100644 index 0000000000000000000000000000000000000000..8a097306b1dbf7ce5c6cb14e9c84ff7f59079dfb Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\350\212\202\347\202\2712.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\350\212\202\347\202\2713.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\350\212\202\347\202\2713.png" new file mode 100644 index 0000000000000000000000000000000000000000..1e517062c17505a2ec0905863934e5e0a5e47c36 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\344\277\256\346\224\271\350\212\202\347\202\2713.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\211\271\346\254\2411.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\211\271\346\254\2411.png" new file mode 100644 index 0000000000000000000000000000000000000000..ee14b990e8ab6cf0c71bef1a40cb74cd2919e2fc Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\211\271\346\254\2411.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\211\271\346\254\2412.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\211\271\346\254\2412.png" new file mode 100644 index 0000000000000000000000000000000000000000..1f5a1658552227a88cf07f592e048c4bc1005286 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\211\271\346\254\2412.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\211\271\346\254\2413.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\211\271\346\254\2413.png" new file mode 100644 index 0000000000000000000000000000000000000000..4066752952e177ca2bb14b61a86d44ff1efc11f6 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\211\271\346\254\2413.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\211\271\346\254\2414.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\211\271\346\254\2414.png" new file mode 100644 index 0000000000000000000000000000000000000000..ade3fb143ac6a0186985b63c5505afef9666e57e Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\211\271\346\254\2414.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\226\207\344\273\2661.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\226\207\344\273\2661.png" new file mode 100644 index 0000000000000000000000000000000000000000..74889505efa10bf45d699d9c8ec19c81cd63ef4f Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\226\207\344\273\2661.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\226\207\344\273\2662.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\226\207\344\273\2662.png" new file mode 100644 index 0000000000000000000000000000000000000000..0a0f563aa9efd21a789058b76dc88e5e0208a996 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\226\207\344\273\2662.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\226\207\344\273\2663.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\226\207\344\273\2663.png" new file mode 100644 index 0000000000000000000000000000000000000000..e7dfcf189d030a4bffa1ce92885e27e3fab7ecde Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\233\345\273\272\346\226\207\344\273\2663.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\211\271\346\254\2411.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\211\271\346\254\2411.png" new file mode 100644 index 0000000000000000000000000000000000000000..e360587420e42233933a9bb27ad31a62557374f0 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\211\271\346\254\2411.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\211\271\346\254\2412.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\211\271\346\254\2412.png" new file mode 100644 index 0000000000000000000000000000000000000000..0efb93e8dd16f855b444d6a5891be38fdebe92c7 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\211\271\346\254\2412.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\211\271\346\254\2413.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\211\271\346\254\2413.png" new file mode 100644 index 0000000000000000000000000000000000000000..2263d7c359bc58451f9382693b98c15cae4fb273 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\211\271\346\254\2413.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\234\272\345\231\2501.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\234\272\345\231\2501.png" new file mode 100644 index 0000000000000000000000000000000000000000..74c10a8dee0fb08e4ac39d73c3389b9a2262c143 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\234\272\345\231\2501.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\234\272\345\231\2502.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\234\272\345\231\2502.png" new file mode 100644 index 0000000000000000000000000000000000000000..d4e467dd0b6fbd9d13a928deebfa8cca1a515c61 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\234\272\345\231\2502.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\234\272\345\231\2503.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\234\272\345\231\2503.png" new file mode 100644 index 0000000000000000000000000000000000000000..1bb38a09498d5a0d8c96aef1ce7b39f8bbb43207 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\346\234\272\345\231\2503.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\347\224\250\346\210\2671.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\347\224\250\346\210\2671.png" new file mode 100644 index 0000000000000000000000000000000000000000..c0599cd9d3679c2c16debcbf46b85b1328130104 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\347\224\250\346\210\2671.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\347\224\250\346\210\2672.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\347\224\250\346\210\2672.png" new file mode 100644 index 0000000000000000000000000000000000000000..96a3636ed380608616fccb672017ef363108d529 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\347\224\250\346\210\2672.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\212\202\347\202\2711.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\212\202\347\202\2711.png" new file mode 100644 index 0000000000000000000000000000000000000000..e278954b5422dff1a59ca4acd37b601c9f0ad24e Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\212\202\347\202\2711.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\212\202\347\202\2712.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\212\202\347\202\2712.png" new file mode 100644 index 0000000000000000000000000000000000000000..e739b14f7b60794065a9ec8a9b2478b2f0b37dd0 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\212\202\347\202\2712.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\212\202\347\202\2713.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\212\202\347\202\2713.png" new file mode 100644 index 0000000000000000000000000000000000000000..d8c8967d525a68515a7ce651f7d30169654bd784 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\212\202\347\202\2713.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\247\222\350\211\2621.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\247\222\350\211\2621.png" new file mode 100644 index 0000000000000000000000000000000000000000..cf3d51f7ab12f241f8a93223631406d0c1b99ab4 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\247\222\350\211\2621.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\247\222\350\211\2622.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\247\222\350\211\2622.png" new file mode 100644 index 0000000000000000000000000000000000000000..b41055b466720578ca9282ff31589b6e147e8ada Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\247\222\350\211\2622.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\247\222\350\211\2623.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\247\222\350\211\2623.png" new file mode 100644 index 0000000000000000000000000000000000000000..661ed75def31a49cbf6043493c1805d65c83a83b Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\210\240\351\231\244\350\247\222\350\211\2623.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\212\237\350\203\275\346\250\241\345\235\227.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\212\237\350\203\275\346\250\241\345\235\227.png" new file mode 100644 index 0000000000000000000000000000000000000000..86782bfc46f42a051b56f457cd46fad60cad3332 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\212\237\350\203\275\346\250\241\345\235\227.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\217\230\346\233\264\346\235\203\351\231\2201.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\217\230\346\233\264\346\235\203\351\231\2201.png" new file mode 100644 index 0000000000000000000000000000000000000000..e9344f19ded8c509b6ac1047d615d98f97dc4d12 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\217\230\346\233\264\346\235\203\351\231\2201.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\217\230\346\233\264\346\235\203\351\231\2202.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\217\230\346\233\264\346\235\203\351\231\2202.png" new file mode 100644 index 0000000000000000000000000000000000000000..c04eb7c5c9f14f5de2bf5f223a8ffbba9cdd599f Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\217\230\346\233\264\346\235\203\351\231\2202.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\217\230\346\233\264\351\203\250\351\227\2501.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\217\230\346\233\264\351\203\250\351\227\2501.png" new file mode 100644 index 0000000000000000000000000000000000000000..23c2d754679c0a374d89c26596669e9bbbebf2f6 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\217\230\346\233\264\351\203\250\351\227\2501.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\217\230\346\233\264\351\203\250\351\227\2502.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\217\230\346\233\264\351\203\250\351\227\2502.png" new file mode 100644 index 0000000000000000000000000000000000000000..0efb1384611e7f5b4cb1370e626a238908567dbb Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\345\217\230\346\233\264\351\203\250\351\227\2502.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\211\271\351\207\217\344\270\213\345\217\2211.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\211\271\351\207\217\344\270\213\345\217\2211.png" new file mode 100644 index 0000000000000000000000000000000000000000..387df3d4cd301fe677e663c6a919abf093efba87 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\211\271\351\207\217\344\270\213\345\217\2211.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\211\271\351\207\217\344\270\213\345\217\2212.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\211\271\351\207\217\344\270\213\345\217\2212.png" new file mode 100644 index 0000000000000000000000000000000000000000..ca5e64cbf7d0aeabcececacea125585484e873ca Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\211\271\351\207\217\344\270\213\345\217\2212.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\211\271\351\207\217\345\215\270\350\275\2751.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\211\271\351\207\217\345\215\270\350\275\2751.png" new file mode 100644 index 0000000000000000000000000000000000000000..4bc4ca6f620619fe10a81205a939535f83e772c2 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\211\271\351\207\217\345\215\270\350\275\2751.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\211\271\351\207\217\345\215\270\350\275\2752.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\211\271\351\207\217\345\215\270\350\275\2752.png" new file mode 100644 index 0000000000000000000000000000000000000000..68467232ca5bd65a03eccc4fc3fb8a5e95529ddf Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\211\271\351\207\217\345\215\270\350\275\2752.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\211\271\351\207\217\346\223\215\344\275\2341.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\211\271\351\207\217\346\223\215\344\275\2341.png" new file mode 100644 index 0000000000000000000000000000000000000000..5cee721e3c0ce14f666a85cd3acb27b57684f077 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\211\271\351\207\217\346\223\215\344\275\2341.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\344\270\213\345\217\2211.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\344\270\213\345\217\2211.png" new file mode 100644 index 0000000000000000000000000000000000000000..d5d54a3679b9a183dbc8eddacf881a8c30c0967b Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\344\270\213\345\217\2211.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\344\270\213\345\217\2212.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\344\270\213\345\217\2212.png" new file mode 100644 index 0000000000000000000000000000000000000000..d639180465474d529758cb83e98b8bd44c409e47 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\344\270\213\345\217\2212.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\344\270\213\345\217\2213.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\344\270\213\345\217\2213.png" new file mode 100644 index 0000000000000000000000000000000000000000..87082b54be5d405f859bd17b558b061e08565f0c Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\344\270\213\345\217\2213.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\210\240\351\231\2441.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\210\240\351\231\2441.png" new file mode 100644 index 0000000000000000000000000000000000000000..e292e6abbde7b787e8c5246fe0a754e8bd3f3277 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\210\240\351\231\2441.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\210\240\351\231\2442.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\210\240\351\231\2442.png" new file mode 100644 index 0000000000000000000000000000000000000000..eb643a896473ade847fd6091dd031eadc3444a4c Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\210\240\351\231\2442.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\210\240\351\231\2443.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\210\240\351\231\2443.png" new file mode 100644 index 0000000000000000000000000000000000000000..a8f2dd996fb826ace2a657ae330aaf36d7c1b884 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\210\240\351\231\2443.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\216\206\345\217\262\347\211\210\346\234\254.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\216\206\345\217\262\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..74f5e745836607702d69f97939b8629446dc0d71 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\216\206\345\217\262\347\211\210\346\234\254.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\233\236\346\273\2321.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\233\236\346\273\2321.png" new file mode 100644 index 0000000000000000000000000000000000000000..8a7e6dfd18608275d496de46cc157bdcfcc1ffa4 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\233\236\346\273\2321.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\233\236\346\273\2322.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\233\236\346\273\2322.png" new file mode 100644 index 0000000000000000000000000000000000000000..0ceef0dcacc27149d2feb2eff3a7902af1c13186 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\233\236\346\273\2322.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\233\236\346\273\2323.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\233\236\346\273\2323.png" new file mode 100644 index 0000000000000000000000000000000000000000..69b4cda58e7962c11e40bdac7555afb9428941b2 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\233\236\346\273\2323.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\233\236\346\273\2324.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\233\236\346\273\2324.png" new file mode 100644 index 0000000000000000000000000000000000000000..79281449c580ef3059dc30329416e6fb564fb5ae Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\345\233\236\346\273\2324.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\346\237\245\347\234\2131.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\346\237\245\347\234\2131.png" new file mode 100644 index 0000000000000000000000000000000000000000..14e91000f62a312b9004ab2108929d90ee49f1b1 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\346\237\245\347\234\2131.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\346\237\245\347\234\2132.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\346\237\245\347\234\2132.png" new file mode 100644 index 0000000000000000000000000000000000000000..517fd0fcdce1ccf35216bc0e98c4ea3127145d1b Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\226\207\344\273\266\346\237\245\347\234\2132.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\227\245\345\277\227\346\237\245\347\234\213.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\227\245\345\277\227\346\237\245\347\234\213.png" new file mode 100644 index 0000000000000000000000000000000000000000..d98ef2d084ccf737b7a69c168dac1f8e7ef6e49d Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\227\245\345\277\227\346\237\245\347\234\213.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250.png" new file mode 100644 index 0000000000000000000000000000000000000000..a65f27145edee0d8e10259a808a49c997bdbbb81 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\344\277\241\346\201\257.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\344\277\241\346\201\257.png" new file mode 100644 index 0000000000000000000000000000000000000000..e0be6aec62ea1de2de8f8a771a3b4f5f07d9ecea Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\344\277\241\346\201\257.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\345\206\205\346\240\2701.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\345\206\205\346\240\2701.png" new file mode 100644 index 0000000000000000000000000000000000000000..e1c722e66168c29fbc1aea72a24f90c05d23b459 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\345\206\205\346\240\2701.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\345\206\205\346\240\2702.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\345\206\205\346\240\2702.png" new file mode 100644 index 0000000000000000000000000000000000000000..cb4263a4961d75a687b0d073f6922af6e936970d Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\345\206\205\346\240\2702.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\345\206\205\346\240\270\344\277\256\346\224\2711.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\345\206\205\346\240\270\344\277\256\346\224\2711.png" new file mode 100644 index 0000000000000000000000000000000000000000..ae23a49e9ef1d9c2be390a4715f83457c05dce69 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\345\206\205\346\240\270\344\277\256\346\224\2711.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\345\206\205\346\240\270\344\277\256\346\224\2712.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\345\206\205\346\240\270\344\277\256\346\224\2712.png" new file mode 100644 index 0000000000000000000000000000000000000000..344f95e052c876e312043099b36267e4e9544e5c Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\345\206\205\346\240\270\344\277\256\346\224\2712.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\345\206\205\346\240\270\344\277\256\346\224\2713.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\345\206\205\346\240\270\344\277\256\346\224\2713.png" new file mode 100644 index 0000000000000000000000000000000000000000..1f108d6f224f30a5973b4ddbe7e8d551d8e1f9c5 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\345\206\205\346\240\270\344\277\256\346\224\2713.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\346\234\215\345\212\241\345\201\234\346\255\242.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\346\234\215\345\212\241\345\201\234\346\255\242.png" new file mode 100644 index 0000000000000000000000000000000000000000..c482e8389f10bca2f1ad43545af169d6dd26b1a5 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\346\234\215\345\212\241\345\201\234\346\255\242.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\346\234\215\345\212\241\345\220\257\345\212\250.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\346\234\215\345\212\241\345\220\257\345\212\250.png" new file mode 100644 index 0000000000000000000000000000000000000000..3d8674a65895b1138ca2826b2496f17c81e5818b Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\346\234\215\345\212\241\345\220\257\345\212\250.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\346\234\215\345\212\241\346\237\245\350\257\242.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\346\234\215\345\212\241\346\237\245\350\257\242.png" new file mode 100644 index 0000000000000000000000000000000000000000..95cf112c8e05a31b1f92861f91d76417d23d807c Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\346\234\215\345\212\241\346\237\245\350\257\242.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\346\234\215\345\212\241\351\207\215\345\220\257.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\346\234\215\345\212\241\351\207\215\345\220\257.png" new file mode 100644 index 0000000000000000000000000000000000000000..a77c72630b6ab284232f7584d4f688e243439960 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\346\234\215\345\212\241\351\207\215\345\220\257.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\347\224\250\346\210\267\344\277\241\346\201\257.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\347\224\250\346\210\267\344\277\241\346\201\257.png" new file mode 100644 index 0000000000000000000000000000000000000000..7b371c41d42349d6e7aaf900444034e6ee72ec0f Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\347\224\250\346\210\267\344\277\241\346\201\257.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\347\273\210\347\253\257.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\347\273\210\347\253\257.png" new file mode 100644 index 0000000000000000000000000000000000000000..2a7e5cbb1366030517ceeacc8a1459a764ac98eb Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\347\273\210\347\253\257.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\347\273\210\347\253\2571.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\347\273\210\347\253\2571.png" new file mode 100644 index 0000000000000000000000000000000000000000..d3130734e2fb884c74209411dbb647d88e575a8f Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\347\273\210\347\253\2571.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\347\275\221\347\273\234\351\205\215\347\275\256.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\347\275\221\347\273\234\351\205\215\347\275\256.png" new file mode 100644 index 0000000000000000000000000000000000000000..742c506ea550d649354a06010bb96b853bce02bf Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\347\275\221\347\273\234\351\205\215\347\275\256.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\350\275\257\344\273\266\345\214\205\345\215\270\350\275\275.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\350\275\257\344\273\266\345\214\205\345\215\270\350\275\275.png" new file mode 100644 index 0000000000000000000000000000000000000000..cc74a97dcf92ca3eb57b8cf7b2319e73cf10c099 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\350\275\257\344\273\266\345\214\205\345\215\270\350\275\275.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\350\275\257\344\273\266\345\214\205\345\256\211\350\243\2051.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\350\275\257\344\273\266\345\214\205\345\256\211\350\243\2051.png" new file mode 100644 index 0000000000000000000000000000000000000000..1801f6adbd2b2cf1c00fd279c720192915a34d55 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\350\275\257\344\273\266\345\214\205\345\256\211\350\243\2051.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\350\275\257\344\273\266\345\214\205\345\256\211\350\243\2052.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\350\275\257\344\273\266\345\214\205\345\256\211\350\243\2052.png" new file mode 100644 index 0000000000000000000000000000000000000000..b24a22cbafc042b7d4cb234708a161a4b6910048 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\350\275\257\344\273\266\345\214\205\345\256\211\350\243\2052.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\350\275\257\344\273\266\345\214\205\346\220\234\347\264\242.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\350\275\257\344\273\266\345\214\205\346\220\234\347\264\242.png" new file mode 100644 index 0000000000000000000000000000000000000000..d6119cf60ec4dfa952fcf4f16dec97ab6daf1863 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\234\272\345\231\250\350\275\257\344\273\266\345\214\205\346\220\234\347\264\242.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\246\202\350\247\210.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\246\202\350\247\210.png" new file mode 100644 index 0000000000000000000000000000000000000000..ca652711583c0c537df164621384e0cb251dac03 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\246\202\350\247\210.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\347\224\250\346\210\2671.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\347\224\250\346\210\2671.png" new file mode 100644 index 0000000000000000000000000000000000000000..e5f5631e6ca19f8498fa2b030613b0a75d7168f1 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\347\224\250\346\210\2671.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\347\224\250\346\210\2672.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\347\224\250\346\210\2672.png" new file mode 100644 index 0000000000000000000000000000000000000000..017c47fdc9974c3a9ee5758c05512eb0b01a929c Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\347\224\250\346\210\2672.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\350\212\202\347\202\2711.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\350\212\202\347\202\2711.png" new file mode 100644 index 0000000000000000000000000000000000000000..c7cb768fdd35d3c2a30e3f175157418e650f5c9a Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\350\212\202\347\202\2711.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\350\212\202\347\202\2712.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\350\212\202\347\202\2712.png" new file mode 100644 index 0000000000000000000000000000000000000000..45f82cb1d563356585b932aa1de6ae79b174b2eb Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\350\212\202\347\202\2712.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\350\247\222\350\211\2621.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\350\247\222\350\211\2621.png" new file mode 100644 index 0000000000000000000000000000000000000000..a51db5c136e8d6baf61187d8882d4b02758cb056 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\350\247\222\350\211\2621.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\350\247\222\350\211\2622.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\350\247\222\350\211\2622.png" new file mode 100644 index 0000000000000000000000000000000000000000..a352b27353c2513f55cad32d968b1095de96eb23 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\346\267\273\345\212\240\350\247\222\350\211\2622.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\224\250\346\210\267\345\257\274\345\205\2451.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\224\250\346\210\267\345\257\274\345\205\2451.png" new file mode 100644 index 0000000000000000000000000000000000000000..7b7c230d9942bd9fceaeb2fbb23b3e16255b2505 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\224\250\346\210\267\345\257\274\345\205\2451.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\224\250\346\210\267\345\257\274\345\205\2452.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\224\250\346\210\267\345\257\274\345\205\2452.png" new file mode 100644 index 0000000000000000000000000000000000000000..dad2779f6ddb6577a636fe8fb6050aeec69ee2ad Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\224\250\346\210\267\345\257\274\345\205\2452.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\224\250\346\210\267\345\257\274\345\205\2453.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\224\250\346\210\267\345\257\274\345\205\2453.png" new file mode 100644 index 0000000000000000000000000000000000000000..88d855f0e0f48d3da3523d59df9e2358fb49a92c Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\224\250\346\210\267\345\257\274\345\205\2453.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\224\250\346\210\267\345\257\274\345\207\2721.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\224\250\346\210\267\345\257\274\345\207\2721.png" new file mode 100644 index 0000000000000000000000000000000000000000..6198f25e96b6f782e042a1e1c36b0bef897ca064 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\224\250\346\210\267\345\257\274\345\207\2721.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\224\250\346\210\267\345\257\274\345\207\2722.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\224\250\346\210\267\345\257\274\345\207\2722.png" new file mode 100644 index 0000000000000000000000000000000000000000..c55645090a3475c117b2e5805b42bad57a90dfd0 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\224\250\346\210\267\345\257\274\345\207\2722.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\231\273\345\275\225.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\231\273\345\275\225.png" new file mode 100644 index 0000000000000000000000000000000000000000..6eb0106de32bd3d9da30d194035f129e3083791a Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\231\273\345\275\225.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\211\271\346\254\2411.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\211\271\346\254\2411.png" new file mode 100644 index 0000000000000000000000000000000000000000..068b66d65a0f63fabd9f4cd78b46aafbbd1eb8b7 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\211\271\346\254\2411.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\211\271\346\254\2412.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\211\271\346\254\2412.png" new file mode 100644 index 0000000000000000000000000000000000000000..b4485514201339dc8d3e59c466e57afdd7817c06 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\211\271\346\254\2412.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\211\271\346\254\2413.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\211\271\346\254\2413.png" new file mode 100644 index 0000000000000000000000000000000000000000..a469a8798beecb882e5823132f442ee1eaf5cb21 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\211\271\346\254\2413.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\226\207\344\273\2661.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\226\207\344\273\2661.png" new file mode 100644 index 0000000000000000000000000000000000000000..50b5f27cc9cecee17b7758683f61bf21544e8c3b Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\226\207\344\273\2661.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\226\207\344\273\2662.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\226\207\344\273\2662.png" new file mode 100644 index 0000000000000000000000000000000000000000..1362aac595643c19f924cf92098bf43abf75c78e Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\226\207\344\273\2662.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\226\207\344\273\2663.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\226\207\344\273\2663.png" new file mode 100644 index 0000000000000000000000000000000000000000..ffa2ed188539c7aa0f95cd6beb21d07c0ed6fc84 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\346\226\207\344\273\2663.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\347\224\250\346\210\2671.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\347\224\250\346\210\2671.png" new file mode 100644 index 0000000000000000000000000000000000000000..36cdb73c8cffc40e7e9d6831691183cdfb481649 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\347\224\250\346\210\2671.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\347\224\250\346\210\2672.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\347\224\250\346\210\2672.png" new file mode 100644 index 0000000000000000000000000000000000000000..7391fda93795f334f7674c98c811bf93919e99a0 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\347\224\250\346\210\2672.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\350\247\222\350\211\2621.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\350\247\222\350\211\2621.png" new file mode 100644 index 0000000000000000000000000000000000000000..d752d16e201a493d71feee178f6a9ca4541df5ed Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\350\247\222\350\211\2621.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\350\247\222\350\211\2622.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\350\247\222\350\211\2622.png" new file mode 100644 index 0000000000000000000000000000000000000000..25c650b0393a73ba5b40f3409a760e420881dcfe Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\347\274\226\350\276\221\350\247\222\350\211\2622.png" differ diff --git "a/docs/en/25.03/Tools/Cloud/PilotGo/figures/\351\207\215\347\275\256\345\257\206\347\240\2011.png" "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\351\207\215\347\275\256\345\257\206\347\240\2011.png" new file mode 100644 index 0000000000000000000000000000000000000000..0f33a7a9476814caf942edb428b55a8aa31e3d91 Binary files /dev/null and "b/docs/en/25.03/Tools/Cloud/PilotGo/figures/\351\207\215\347\275\256\345\257\206\347\240\2011.png" differ diff --git a/docs/en/25.03/Tools/Cloud/PilotGo/pilotgo-introduction.md b/docs/en/25.03/Tools/Cloud/PilotGo/pilotgo-introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..d1c8fd2b0b77879ac8762fadb08a2a9487151931 --- /dev/null +++ b/docs/en/25.03/Tools/Cloud/PilotGo/pilotgo-introduction.md @@ -0,0 +1,37 @@ +# PilotGo介绍 + +PilotGo 是 openEuler 社区原生孵化的运维管理平台,采用插件式架构设计,功能模块轻量化组合、独立迭代演进,同时保证核心功能稳定;同时使用插件来增强平台功能、并打通不同运维组件之间的壁垒,实现了全局的状态感知及自动化流程。 + +## 功能描述 + +PilotGo 核心功能模块包括: + +* 用户管理:支持按照组织结构分组管理,支持导入已有平台账号,迁移方便; + +* 权限管理:支持基于RBAC的权限管理,灵活可靠; + +* 主机管理:状态前端可视化、直接执行软件包管理、服务管理、内核参数调优、简单易操作; + +* 批次管理:支持运维操作并发执行,稳定高效; + +* 日志审计:跟踪记录用户及插件的变更操作,方便问题回溯及安全审计; + +* 告警管理:平台异常实时感知; + +* 插件功能:支持扩展平台功能,插件联动,自动化能力倍增,减少人工干预。 + +![本地路径](./figures/功能模块.png) + +当前OS发布版本还集成了以下插件: + +* Prometheus:托管Prometheus监控组件,自动化下发及配置node-exporter监控数据采集,对接平台告警功能; + +![本地路径](./figures/P插件3.png) + +* Grafana:集成Grafana可视化平台,提供美观易用的指标监控面板功能。 + +![本地路径](./figures/G插件4.png) + +## 应用场景 + +PiotGo可用于典型的服务器集群管理场景,支持大批量的服务器集群基本管理及监控;通过集成对应的业务功能插件,还可实现业务集群的统一平台管理,例如Mysql数据库集群、redis数据缓存集群、nginx网关集群等。 diff --git a/docs/en/25.03/Tools/Cloud/PilotGo/usage.md b/docs/en/25.03/Tools/Cloud/PilotGo/usage.md new file mode 100644 index 0000000000000000000000000000000000000000..a79a206a856c39deb55aee4ad46b32a4528dd5d0 --- /dev/null +++ b/docs/en/25.03/Tools/Cloud/PilotGo/usage.md @@ -0,0 +1,327 @@ +# PilotGo平台使用手册 + +PilotGo 是一个 openEuler 社区原生的运维管理平台,采用插件式开发,增强平台的扩展性、并打通不同运维组件之间的壁垒。PilotGo 核心功能包括:集群管理、批次管理、主机管理、用户管理、权限管理、主机监控、运维审计等。 + +## 1 PilotGo安装与配置 + +PilotGo可以单机部署也可以采用集群式部署。安装之前先关闭防火墙。 + +### 1.1 PilotGo-server 安装与配置 + +安装mysql; +安装redis,设置redis密码(修改),运行命令: + +`dnf install redis6` + +`vim /etc/redis/redis.conf` + +`#requirepass foobared去掉注释,foobared改为自己的密码` + +`bind 0.0.0.0` + +启动MySQL和redis服务,然后执行: + +`dnf install PilotGo-server` + +修改/opt/PilotGo/server/config_server.yaml里面mysql和redis的配置信息,启动服务: + +`systemctl start PilotGo-server` + +访问页面: + +### 1.2 PilotGo-agent安装与配置 + +执行以下命令进行安装: + +`dnf install PilotGo-agent` + +修改/opt/PilotGo/agent/config_agent.yaml里面的ip信息,启动服务: + +`systemctl start PilotGo-agent` + +### 1.3 PilotGo插件安装与配置 + +详情见3 插件使用手册 + +## 2 PilotGo平台使用说明 + +### 2.1 首次登录 + +#### 2.1.1 用户登录页面 + +用户登录页面如图所示,输入正确的用户名和密码登录系统。默认用户名为admin@123.com,默认密码为admin,首次登录之后建议先修改密码。![本地路径](./figures/登录.png) + +### 2.2 用户模块 + +#### 2.2.1 创建用户 + +创建用户的方式又两种,一种是手动创建单个用户,另外一种是批量导入多个用户。 + +##### 2.2.1.1 创建单个用户 + +1. 具有创建用户权限的用户成功登录之后点击左侧导航栏中的用户管理; +2. 点击页面右上角的添加按钮; +3. 在页面中输入用户名、密码、邮箱,选择部门和角色类型,并点击确定按钮;![本地路径](./figures/添加用户1.png) +4. 页面弹框提示“添加用户成功”,并显示新创建的用户信息,表示创建用户成功。![本地路径](./figures/添加用户2.png) + +##### 2.2.1.2 批量导入多个用户 + +1. 具有创建用户权限的用户成功登录之后点击左侧导航栏中的用户管理; +2. 击页面的批量导入按钮,选择文件点击打开按钮;![本地路径](./figures/用户导入1.png) +3. 显示用户信息则完成用户导入。![本地路径](./figures/用户导入2.png)![本地路径](./figures/用户导入3.png) + +#### 2.2.2 修改用户信息及密码 + +##### 2.2.2.1 修改用户信息 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的用户管理; +2. 找到用户信息,点击操作栏中的编辑按钮; +3. 在页面中输入要修改的用户信息,并点击确定按钮;![本地路径](./figures/编辑用户1.png) +4. 页面弹框提示“用户信息修改成功”,并显示修改后的用户信息。![本地路径](./figures/编辑用户2.png) + +##### 2.2.2.2 修改密码 + +修改密码有两种方式,第一是用户知道密码登录系统后自己修改,第二是用户忘记密码,由管理员登录系统后重置此用户密码,重置默认密码为邮箱@符号的前半部分。 + +###### 2.2.2.2.1 手动修改密码 + +1. 用户登录系统后点击右上角的人像图标和修改密码;![本地路径](./figures/修改密码1.png) +2. 连续输入两次新密码,点击确定按钮;![本地路径](./figures/修改密码2.png) +3. 页面弹框提示“修改成功”。![本地路径](./figures/修改密码3.png) + +###### 2.2.2.2.2 重置密码 + +1. 管理员登录成功后点击左侧导航栏中的用户管理; +2. 找到用户信息,点击操作栏中的重置密码按钮; +3. 用户使用默认密码可以登录系统。![本地路径](./figures/重置密码1.png) + +#### 2.2.3 删除用户 + +1. 管理员登录成功后点击左侧导航栏中的用户管理; +2. 点击页面小方块选择要删除的用户; +3. 点击页面右上角的删除按钮,并点击确定;![本地路径](./figures/删除用户1.png) +4. 页面弹框提示“用户删除成功”,并用户管理页面不显示删除用户的信息。![本地路径](./figures/删除用户2.png) + +#### 2.2.4 导出用户 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的用户管理; +2. 点击页面的导出按钮;![本地路径](./figures/用户导出1.png) +3. 浏览器显示下载进度,成功下载后打开xlsx文件查看信息。![本地路径](./figures/用户导出2.png) + +### 2.3 角色模块 + +#### 2.3.1 添加角色 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的角色管理; +2. 点击页面的添加按钮; +3. 输入角色名和描述信息,并点击确定按钮;![本地路径](./figures/添加角色1.png) +4. 页面弹框提示“新增角色成功”,并页面显示新添加的角色信息。![本地路径](./figures/添加角色2.png) + +### 2.3.2 修改角色 + +#### 2.3.2.1 修改角色信息 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的角色管理; +2. 点击对应角色的编辑按钮; +3. 输入新的角色名和描述信息,并点击确定按钮;![本地路径](./figures/添加角色1.png) +4. 页面弹框提示“角色信息修改成功”,并页面显示修改后的角色信息。![本地路径](./figures/编辑角色2.png) + +#### 2.3.2.2 修改角色权限 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的角色管理; +2. 点击对应角色的变更按钮; +3. 选择相应的权限,点击重置按钮可以清空所选权限,并点击确定按钮;![本地路径](./figures/编辑角色1.png) +4. 页面弹框提示“角色权限变更成功”。![本地路径](./figures/编辑角色2.png) + +### 2.3.3 删除角色 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的角色管理; +2. 点击对应角色的删除按钮,并点击确定;![本地路径](./figures/删除角色1.png)![本地路径](./figures/删除角色2.png) +3. 页面弹框提示“角色删除成功”,并不显示删除的角色信息。![本地路径](./figures/删除角色3.png) + +### 2.4 部门树模块 + +#### 2.4.1 修改部门节点 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的系统和机器列表; +2. 在部门节点对应位置点击修改符号,输入节点名字并点击确定;![本地路径](./figures/修改节点1.png)![本地路径](./figures/修改节点2.png) +3. 页面弹框提示“修改成功”,并显示修改后的部门节点信息。![本地路径](./figures/修改节点3.png) + +#### 2.4.2 删除部门节点 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的系统和机器列表; +2. 在部门节点对应位置点击删除符号并点击确定;![本地路径](./figures/修改节点1.png)![本地路径](./figures/删除节点2.png) +3. 页面弹框提示“删除成功”,并不显示删除节点的信息。![本地路径](./figures/删除节点3.png) + +### 2.5 配置库模块 + +#### 2.5.1 添加 repo 配置文件 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的库配置文件; +2. 点击页面的新增按钮;![本地路径](./figures/创建文件1.png) +3. 输入文件名、文件类型、文件路径、描述和内容等信息,文件名必须以.repo结尾,文件路径必须正确,文件内容要符合repo文件的格式,并点击确定按钮;![本地路径](./figures/创建文件2.png) +4. 页面弹框提示“文件保存成功”;并显示新增的repo配置文件信息。![本地路径](./figures/创建文件3.png) + +#### 2.5.2 修改 repo 配置文件 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的库配置文件; +2. 找到要修改的repo文件,点击对应的编辑按钮;![本地路径](./figures/编辑文件1.png) +3. 输入修改后的文件名、文件类型、文件路径、描述和内容等信息,并点击确定按钮;![本地路径](./figures/编辑文件2.png) +4. 页面弹框提示“配置文件修改成功”;并显示修改后的repo配置文件信息。![本地路径](./figures/编辑文件3.png) + +#### 2.5.3 删除 repo 配置文件 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的库配置文件; +2. 选择要删除的文件,点击页面的删除按钮,并点击确定;![本地路径](./figures/删除角色1.png)![本地路径](./figures/删除角色2.png) +3. 页面弹框提示“存储的文件已从数据库删除”,且页面不显示删除的repo配置文件信息。![本地路径](./figures/文件删除3.png) + +#### 2.5.4 下发 repo 配置文件 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的库配置文件; +2. 找到要下发的文件,点击页面的下发按钮,选择要下发的批次,并点击确定;![本地路径](./figures/文件下发1.png)![本地路径](./figures/文件下发2.png) +3. 页面弹框提示“配置文件下发成功”。![本地路径](./figures/文件下发3.png) + +#### 2.5.5 回滚 repo 配置文件历史版本 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的库配置文件; +2. 找到要回滚的文件,点击页面的历史版本按钮;![本地路径](./figures/文件历史版本.png) +3. 选择要回滚的版本,点击回滚按钮并点击确定;![本地路径](./figures/文件回滚1.png)![本地路径](./figures/文件回滚2.png) +4. 页面弹框提示“已回退到历史版本”,历史版本页面增加一条“-latest”记录。![本地路径](./figures/文件回滚3.png)![本地路径](./figures/文件回滚4.png) + +### 2.6 批次模块 + +#### 2.6.1 创建批次 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的系统和创建批次; +2. 点击机器所在的部门名字,在备选项中选择0个或多个机器ip(点击ip前面的方框),若选择一个或多个部门的所有机器可以点击部门列表的方框,并点击备选项中的部门名称,选择完成后点击向右的箭头;![本地路径](./figures/创建批次1.png) +3. 输入批次名称和描述,并点击创建按钮;![本地路径](./figures/创建批次2.png) +4. 页面弹框提示“批次入库成功”,并批次页面显示新创建的批次信息。![本地路径](./figures/创建批次3.png)![本地路径](./figures/创建批次4.png) + +#### 2.6.2 修改批次 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的批次; +2. 点击对应批次的编辑按钮;![本地路径](./figures/编辑批次1.png) +3. 输入新的批次名称和备注信息,并点击确定按钮;![本地路径](./figures/编辑文件2.png) +4. 页面弹框提示“批次修改成功”,并显示修改后的批次信息。![本地路径](./figures/编辑批次3.png) + +#### 2.6.3 删除批次 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的批次; +2. 选择要删除的批次,点击删除按钮并点击确定;![本地路径](./figures/删除批次1.png)![本地路径](./figures/删除批次2.png) +3. 页面弹框提示“批次删除成功”,并不显示删除批次的信息。![本地路径](./figures/删除批次3.png) + +#### 2.6.4 批量安装软件包 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的批次,并点击批次名称;![本地路径](./figures/批量操作1.png) +2. 点击右上角的rpm下发按钮,在搜索框输入软件包的名称,并点击下发按钮;![本地路径](./figures/批量下发1.png) +3. 页面弹框提示“软件包安装成功”,agent端可以查到下发的rpm包。![本地路径](./figures/批量下发2.png) + +#### 2.6.5 批量卸载软件包 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的批次,并点击批次名称;![本地路径](./figures/批量操作1.png) +2. 点击右上角的rpm卸载按钮,在搜索框输入软件包的名称,并点击卸载按钮;![本地路径](./figures/批量卸载1.png) +3. 页面弹框提示“软件包卸载成功”,agent端无此软件包。![本地路径](./figures/批量卸载2.png) + +### 2.7 机器模块 + +#### 2.7.1 删除机器 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的系统和机器列表; +2. 选择要删除的机器,点击删除按钮并点击确定;![本地路径](./figures/删除机器1.png)![本地路径](./figures/删除机器2.png) +3. 页面弹框提示“机器删除成功”,并不显示删除机器的信息。![本地路径](./figures/删除机器3.png) + +#### 2.7.2 变更机器部门 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的系统和机器列表; +2. 选择要变更部门的机器,点击变更部门按钮; +3. 核对变更部门机器ip的信息,选择新的部门,并点击确定;![本地路径](./figures/变更部门1.png) +4. 页面弹框提示“机器部门修改成功”,并显示变更后的信息。![本地路径](./figures/变更部门2.png) + +#### 2.7.3 修改机器内核参数 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的系统和机器列表; +2. 点击要查看信息的机器ip,并点击内核参数信息栏目;![本地路径](./figures/机器内核修改1.png) +3. 输入要查找的内核,点击修改,输入参数值并点击确定;![本地路径](./figures/机器内核修改2.png) +4. 页面显示修改进度,成功后显示100%。![本地路径](./figures/机器内核修改3.png) + +#### 2.7.4 启动机器服务 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的系统和机器列表; +2. 点击要查看信息的机器ip,并点击服务信息栏目; +3. 在搜索框输入要启动的服务名称,并点击启动按钮; +4. 页面显示软件包名、执行动作、执行结果进度条信息。![本地路径](./figures/机器服务启动.png) + +#### 2.7.5 重启机器服务 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的系统和机器列表; +2. 点击要查看信息的机器ip,并点击服务信息栏目; +3. 在搜索框输入要重启的服务名称,并点击重启按钮; +4. 页面显示软件包名、执行动作、执行结果进度条信息。![本地路径](./figures/机器服务重启.png) + +#### 2.7.6 停止机器服务 + +1. 具有该权限的用户成功登录,点击左侧导航栏中的系统和机器列表; +2. 点击要查看信息的机器ip,并点击服务信息栏目; +3. 在搜索框输入要启动的服务名称,并点击停止按钮; +4. 页面显示软件包名、执行动作、执行结果进度条信息。![本地路径](./figures/机器服务停止.png) + +#### 2.7.7 安装软件包 + +1. 有该权限的用户成功登录,点击左侧导航栏中的系统和机器列表; +2. 点击要查看信息的机器ip,并点击软件包信息栏目; +3. 在搜索框输入软件包的名称,并点击安装按钮; +4. 页面显示repo名称、repo地址信息,并页面显示软件包名、执行动作、结果等信息。![本地路径](./figures/机器软件包安装2.png) + +#### 2.7.8 卸载软件包 + +1. 有该权限的用户成功登录,点击左侧导航栏中的系统和机器列表; +2. 点击要查看信息的机器ip,并点击软件包信息栏目; +3. 在搜索框输入软件包的名称,并点击卸载按钮; +4. 页面显示repo名称、repo地址信息,并页面显示软件包名、执行动作、结果等信息。![本地路径](./figures/机器软件包卸载.png) + +#### 2.7.9 连接机器终端 + +1. 有该权限的用户成功登录,点击左侧导航栏中的系统和机器列表; +2. 点击要查看信息的机器ip,并点击终端信息栏目; +3. 输入ip地址和机器密码,点击连接按钮;![本地路径](./figures/机器终端1.png) +4. 页面显示终端窗口。![本地路径](./figures/机器终端.png) + +## 3 PilotGo平台插件使用说明 + +### 3.1 Grafana插件使用说明 + +1. 在任意一台服务器上执行dnf install PilotGo-plugin-grafana grafana; +2. 将/opt/PilotGo/plugin/grafana/config.yaml文件中ip地址修改为本机真实ip,修改/etc/grafana/grafana.ini文件一下信息: + + ```shell + root_url = http://真实ip:9999/plugin/grafana + + serve_from_sub_path = true + + allow_embedding = true + ``` + +3. 重启两个服务,执行以下命令: + + ```shell + systemctl restart grafana-server + + systemctl start PilotGo-plugin-grafana + ``` + +4. 成功登录pilotgo平台,点击左侧导航栏中的插件管理,点击添加插件按钮,填写插件名称和服务地址,并点击确定;![本地路径](./figures/G插件1.png) +5. 页面增加一条插件管理数据,导航栏增加一个插件按钮。![本地路径](./figures/G插件2.png)![本地路径](./figures/G插件3.png) + +### 3.2 Prometheus插件使用说明 + +1. 在任意一台服务器上执行dnf install PilotGo-plugin-prometheus; +2. 将/opt/PilotGo/plugin/prometheus/server/config.yml文件中ip地址修改为本机真实ip和mysql服务地址; +3. 重启服务,执行以下命令: + + ```shell + systemctl start PilotGo-plugin-prometheusX + ``` + +4. 成功登录pilotgo平台,点击左侧导航栏中的插件管理,点击添加插件按钮,填写插件名称和服务地址,并点击确定;![本地路径](./figures/P插件1.png) +5. 页面增加一条插件管理数据,导航栏增加一个插件按钮。![本地路径](./figures/P插件2.png)![本地路径](./figures/P插件3.png) +6. 在页面选择机器ip和监控时间,展示机器数据面板。![本地路径](./figures/P插件4.png) diff --git a/docs/en/25.03/Tools/Cloud/_menu.md b/docs/en/25.03/Tools/Cloud/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..b9abd3f5b03476036d78b1f489b1ac7426406ce2 --- /dev/null +++ b/docs/en/25.03/Tools/Cloud/_menu.md @@ -0,0 +1,7 @@ +--- +label: '云原生' +children: + - reference: './CTinspector/_menu.md' + - reference: './CPDS/_menu.md' + - reference: './PilotGo/_menu.md' +--- diff --git a/docs/en/25.03/Tools/Cloud/index.md b/docs/en/25.03/Tools/Cloud/index.md new file mode 100644 index 0000000000000000000000000000000000000000..7d3f4694f4b5e1bde97476c3ffd396573ed55d31 --- /dev/null +++ b/docs/en/25.03/Tools/Cloud/index.md @@ -0,0 +1,4 @@ +--- +title: 云原生 +overview: true +--- \ No newline at end of file diff --git a/docs/en/25.03/Tools/CommunityTools/ImageCustom/imageTailor/_menu.md b/docs/en/25.03/Tools/CommunityTools/ImageCustom/imageTailor/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..1418c08f60d6fb17ad50550fc2779216e87a3a83 --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/ImageCustom/imageTailor/_menu.md @@ -0,0 +1,8 @@ +--- +label: 'imageTailor 使用指南' +ismanual: 'Y' +description: '按需裁剪操作系统镜像中的包或文件' +children: + - label: 'imageTailor 使用指南' + href: './imageTailor-user-guide.md' +--- diff --git a/docs/en/25.03/Tools/CommunityTools/ImageCustom/imageTailor/figures/flowchart.png b/docs/en/25.03/Tools/CommunityTools/ImageCustom/imageTailor/figures/flowchart.png new file mode 100644 index 0000000000000000000000000000000000000000..e4fecb8b310f204d6cfd07449ccc3c93d1badd51 Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/ImageCustom/imageTailor/figures/flowchart.png differ diff --git a/docs/en/25.03/Tools/CommunityTools/ImageCustom/imageTailor/imageTailor-user-guide.md b/docs/en/25.03/Tools/CommunityTools/ImageCustom/imageTailor/imageTailor-user-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..779a638da06bbf015946d8ec42c53d1e2ec3b169 --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/ImageCustom/imageTailor/imageTailor-user-guide.md @@ -0,0 +1,886 @@ +# imageTailor 使用指南 + +## 简介 + +操作系统除内核外,还包含各种功能的外围包。通用操作系统包含较多外围包,提供了丰富的功能,但是这也带来了一些影响: + +- 占用资源(内存、磁盘、CPU 等)多,导致系统运行效率低 +- 很多功能用户不需要,增加了开发和维护成本 + +因此,openEuler 提供了 imageTailor 镜像裁剪定制工具。用户可以根据需求裁剪操作系统镜像中不需要的外围包,或者添加所需的业务包或文件。该工具主要提供了以下功能: + +- 系统包裁剪定制:用户可以选择默认安装以及裁剪的rpm,也支持用户裁剪定制系统命令、库、驱动。 +- 系统配置定制:用户可以配置主机名、启动服务、时区、网络、分区、加载驱动、版本号等。 +- 用户文件定制:支持用户添加定制文件到系统镜像中。 + +## 安装工具 + +本节以 openEuler 22.03 LTS 版本 AArch64 架构为例,说明安装方法。 + +### 软硬件要求 + +安装和运行 imageTailor 需要满足以下软硬件要求: + +- 机器架构为 x86_64 或者 AArch64 + +- 操作系统为 openEuler 22.03 LTS(该版本内核版本为 5.10,python 版本为 3.9,满足工具要求) + +- 运行工具的机器根目录 '/' 需要 40 GB 以上空间 + +- python 版本 3.9 及以上 + +- kernel 内核版本 5.10 及以上 + +- 关闭 SElinux 服务 + + ```shell + $ sudo setenforce 0 + $ getenforce + Permissive + ``` + +### 获取安装包 + +安装和使用 imageTailor 工具,首先需要下载 openEuler 发布件。 + +1. 获取 ISO 镜像文件和对应的校验文件。 + + 镜像必须为 everything 版本,此处假设存放在 root 目录,参考命令如下: + + ```shell + cd /root/temp + wget https://repo.openeuler.org/openEuler-22.03-LTS/ISO/aarch64/openEuler-22.03-LTS-everything-aarch64-dvd.iso + wget https://repo.openeuler.org/openEuler-22.03-LTS/ISO/aarch64/openEuler-22.03-LTS-everything-aarch64-dvd.iso.sha256sum + ``` + +2. 获取 sha256sum 校验文件中的校验值。 + + ```shell + cat openEuler-22.03-LTS-everything-aarch64-dvd.iso.sha256sum + ``` + +3. 计算 ISO 镜像文件的校验值。 + + ```shell + sha256sum openEuler-22.03-LTS-everything-aarch64-dvd.iso + ``` + +4. 对比上述 sha256sum 文件的检验值和 ISO 镜像的校验值,如果两者相同,说明文件完整性检验成功。否则说明文件完整性被破坏,需要重新获取文件。 + +### 安装 imageTailor + +此处以 openEuler 22.03 LTS 版本的 AArch64 架构为例,介绍如何安装 imageTailor 工具。 + +1. 确认机器已经安装操作系统 openEuler 22.03 LTS( imageTailor 工具的运行环境)。 + + ```shell + $ cat /etc/openEuler-release + openEuler release 22.03 LTS + ``` + +2. 创建文件 /etc/yum.repos.d/local.repo,配置对应 yum 源。配置内容参考如下,其中 baseurl 是用于挂载 ISO 镜像的目录: + + ```shell + [local] + name=local + baseurl=file:///root/imageTailor_mount + gpgcheck=0 + enabled=1 + ``` + +3. 使用 root 权限,挂载光盘镜像到 /root/imageTailor_mount 目录(请与上述 repo 文件中配置的 baseurl 保持一致,且建议该目录的磁盘空间大于 20 GB)作为 yum 源,参考命令如下: + + ```shell + mkdir /root/imageTailor_mount + sudo mount -o loop /root/temp/openEuler-22.03-LTS-everything-aarch64-dvd.iso /root/imageTailor_mount/ + ``` + +4. 使 yum 源生效: + + ```shell + yum clean all + yum makecache + ``` + +5. 使用 root 权限,安装 imageTailor 裁剪工具: + + ```shell + sudo yum install -y imageTailor + ``` + +6. 使用 root 权限,确认工具已安装成功。 + + ```shell + $ cd /opt/imageTailor/ + $ sudo ./mkdliso -h + ------------------------------------------------------------------------------------------------------------- + Usage: mkdliso -p product_name -c configpath [--minios yes|no|force] [-h] [--sec] + Options: + -p,--product Specify the product to make, check custom/cfg_yourProduct. + -c,--cfg-path Specify the configuration file path, the form should be consistent with custom/cfg_xxx + --minios Make minios: yes|no|force + --sec Perform security hardening + -h,--help Display help information + + Example: + command: + ./mkdliso -p openEuler -c custom/cfg_openEuler --sec + + help: + ./mkdliso -h + ------------------------------------------------------------------------------------------------------------- + ``` + +### 目录介绍 + +imageTailor 工具安装完成后,工具包的目录结构如下: + +```shell +[imageTailor] + |-[custom] + |-[cfg_openEuler] + |-[usr_file] // 存放用户添加的文件 + |-[usr_install] // 存放用户的 hook 脚本 + |-[all] + |-[conf] + |-[hook] + |-[cmd.conf] // 配置 ISO 镜像默认使用的命令和库 + |-[rpm.conf] // 配置 ISO 镜像默认安装的 RPM 包和驱动列表 + |-[security_s.conf] // 配置安全加固策略 + |-[sys.conf] // 配置 ISO 镜像系统参数 + |-[kiwi] // imageTailor 基础配置 + |-[repos] // RPM 源,制作 ISO 镜像需要的 RPM 包 + |-[security-tool] // 安全加固工具 + |-mkdliso // 制作 ISO 镜像的可执行脚本 +``` + +## 定制系统 + +本章介绍使用 imageTailor 工具将业务 RPM 包、自定义文件、驱动、命令和文件打包至目标 ISO 镜像。 + +### 总体流程 + +使用 imageTailor 工具定制系统的流程请参见下图: + +![](./figures/flowchart.png) + +各流程含义如下: + +- 检查软硬件环境:确认制作 ISO 镜像的机器满足软硬件要求。 + +- 定制业务包:包括添加 RPM 包(包括业务 RPM 包、命令、驱动、库文件)和添加文件(包括自定义文件、命令、驱动、库文件) + + - 添加业务 RPM 包:用户可以根据需要,添加 RPM 包到 ISO 镜像。具体要求请参见 [安装工具](#安装工具) 章节。 + - 添加自定义文件:若用户希望在目标 ISO 系统安装或启动时,能够进行自定义的硬件检查、系统配置检查、驱动安装等操作,可编写自定义文件,并打包到 ISO 镜像。 + - 添加驱动、命令、库文件:当 openEuler 的 RPM 包源未包含用户需要的驱动、命令或库文件时,可以使用 imageTailor 工具将对应驱动、命令或库文件打包至 ISO 镜像。 + +- 配置系统参数 + + - 配置主机参数:为了确保 ISO 镜像安装和启动成功,需要配置主机参数。 + - 配置分区:用户可以根据业务规划配置业务分区,同时可以调整系统分区。 + - 配置网络:用户可以根据需要配置系统网络参数,例如:网卡名称、IP 地址、子网掩码。 + - 配置初始密码:为了确保 ISO 镜像安装和启动成功,需要配置 root 初始密码和 grub 初始密码。 + - 配置内核参数:用户可以根据需求配置内核的命令行参数。 + +- 配置安全加固策略 + + imageTailor 提供了默认地安全加固策略。用户可以根据业务需要,通过编辑 security_s.conf 对系统进行二次加固(仅在系统 ISO 镜像定制阶段),具体的操作方法请参见 《 [安全加固指南](https://docs.openeuler.org/zh/docs/22.03_LTS/docs/SecHarden/secHarden.html) 》。 + +- 制作操作系统 ISO 镜像 + + 使用 imageTailor 工具制作操作系统 ISO 镜像。 + +### 定制业务包 + +用户可以根据业务需要,将业务 RPM 包、自定义文件、驱动、命令和库文件打包至目标 ISO 镜像。 + +#### 配置本地 repo 源 + +定制 ISO 操作系统镜像,必须在 /opt/imageTailor/repos/euler_base/ 目录配置 repo 源。本节主要介绍配置本地 repo 源的方法。 + +1. 下载 openEuler 发布的 ISO (必须使用 openEuler 发布 everything 版本镜像 的 RPM 包)。 + + ```shell + cd /opt + wget https://repo.openeuler.org/openEuler-22.03-LTS/ISO/aarch64/openEuler-22.03-LTS-everything-aarch64-dvd.iso + ``` + +2. 创建挂载目录 /opt/openEuler_repo ,并挂载 ISO 到该目录 。 + + ```shell + $ sudo mkdir -p /opt/openEuler_repo + $ sudo mount openEuler-22.03-LTS-everything-aarch64-dvd.iso /opt/openEuler_repo + mount: /opt/openEuler_repo: WARNING: source write-protected, mounted read-only. + ``` + +3. 拷贝 ISO 中的 RPM 包到 /opt/imageTailor/repos/euler_base/ 目录下。 + + ```shell + $ sudo rm -rf /opt/imageTailor/repos/euler_base && sudo mkdir -p /opt/imageTailor/repos/euler_base + $ sudo cp -ar /opt/openEuler_repo/Packages/* /opt/imageTailor/repos/euler_base + $ sudo chmod -R 644 /opt/imageTailor/repos/euler_base + $ sudo ls /opt/imageTailor/repos/euler_base|wc -l + 2577 + $ sudo umount /opt/openEuler_repo && sudo rm -rf /opt/openEuler_repo + $ cd /opt/imageTailor + ``` + +#### 添加文件 + +用户可以根据需要添加文件到 ISO 镜像,此处的文件类型可以是用户自定义文件、驱动、命令、库文件。用户只需要将文件放至 /opt/imageTailor/custom/cfg_openEuler/usr_file 目录下即可。 + +##### 注意事项 + +- 命令必须具有可执行权限,否则 imageTailor 工具无法将该命令打包至 ISO 中。 + +- 存放在 /opt/imageTailor/custom/cfg_openEuler/usr_file 目录下的文件,会生成在 ISO 根目录下,所以文件的目录结构必须是从根目录开始的完整路径,以便 imageTailor 工具能够将该文件放至正确的目录下。 + + 例如:假设希望文件 file1 在 ISO 的 /opt 目录下,则需要在 usr_file 目录下新建 opt 目录,再将 file1 文件拷贝至 opt 目录。如下: + + ```shell + $ pwd + /opt/imageTailor/custom/cfg_openEuler/usr_file + + $ tree + . + ├── etc + │   ├── default + │   │   └── grub + │   └── profile.d + │   └── csh.precmd + └── opt + └── file1 + + 4 directories, 3 files + ``` + +- 存放在 /opt/imageTailor/custom/cfg_openEuler/usr_file 目录下的目录必须是真实路径(例如路径中不包含软链接。可在系统中使用 `realpath` 或 `readlink -f` 命令查询真实路径)。 + +- 如果需要在系统启动或者安装阶段调用用户提供的脚本,即 hook 脚本,则需要将该文件放在 hook 目录下。 + +#### 添加 RPM 包 + +##### 操作流程 + +用户可以添加 RPM 包(驱动、命令或库文件)到 ISO 镜像,操作步骤如下: + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 下述 rpm.conf 和 cmd.conf 均在 /opt/imageTailor/custom/cfg_openEuler/ 目录下。 +> 下述 RPM 包裁剪粒度是指 sys_cut='no' 。裁剪粒度详情请参见 [配置主机参数](#配置主机参数) 。 +> 若没有配置本地 repo 源,请参见 [配置本地 repo 源](#配置本地-repo-源)进行配置。 + +1. 确认 /opt/imageTailor/repos/euler_base/ 目录中是否包含需要添加的 RPM 包。 + + - 是,请执行步骤 2 。 + - 否,请执行步骤 3 。 + +2. 在 rpm.conf 的 \ 字段配置该 RPM 包信息。 + + - 若为 RPM 包裁剪粒度,则操作完成。 + - 若为其他裁剪粒度,请执行步骤 4 。 + +3. 用户自己提供 RPM 包,放至 /opt/imageTailor/custom/cfg_openEuler/usr_rpm 目录下。如果 RPM 包依赖于其他 RPM 包,也必须将依赖包放至该目录,因为新增 RPM 包需要和依赖 RPM 包同时打包至 ISO 镜像。 + + - 若为用户 RPM 包文件裁剪,则执行 4 。 + - 其他裁剪粒度,则操作完成。 + +4. 请在 rpm.conf 和 cmd.conf 中配置该 RPM 包中要保留的驱动、命令和库文件。如果有要裁剪的普通文件,需要在 cmd.conf 文件中的 \\ 区域配置。 + +##### 配置文件说明 + +| 对象 | 对应配置文件 | 填写区域 | +| :----------- | :----------- | :----------------------------------------------------------- | +| 添加驱动 | rpm.conf | \
\
\

说明:其中驱动名称所在路径为 " /lib/modules/{内核版本号}/kernel/ " 的相对路径 | +| 添加命令 | cmd.conf | \
\
\
| +| 添加库文件 | cmd.conf | \
\
\
| +| 删除其他文件 | cmd.conf | \
\
\

说明:普通文件名称必须包含绝对路径 | + +**示例**如下 + +- 添加驱动 + + ```shell + + + + + ...... + + ``` + +- 添加命令 + + ```shell + + + + + ...... + + ``` + +- 添加库文件 + + ```shell + + + + + + ``` + +- 删除其他文件 + + ```shell + + + + + + ``` + +#### 添加 hook 脚本 + +hook 脚本由 OS 在启动和安装过程中调用,执行脚本中定义的动作。imageTailor 工具存放 hook 脚本的目录为 custom/cfg_openEuler/usr_install/hook,且其下有不同子目录,每个子目录代表 OS 启动或安装的不同阶段,用户根据脚本需要被调用的阶段存放,OS 会在对应阶段调用该脚本。用户可以根据需要存放自定义脚本到指定目录。 + +##### **脚本命名规则** + +用户可自定义脚本名称,必须 "S+数字(至少两位,个位数以0开头)" 开头,数字代表 hook 脚本的执行顺序。脚本名称示例:S01xxx.sh + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> hook 目录下的脚本是通过 source 方式调用,所以脚本中需要谨慎使用 exit 命令,因为调用 exit 命令之后,整个安装的脚本程序也同步退出了。 + +##### hook 子目录说明 + +| hook 子目录 | hook 脚本举例 | hook 执行点 | 说明 | +| :-------------------- | :---------------------| :------------------------------- | :----------------------------------------------------------- | +| insmod_drv_hook | 无 | 加载 OS 驱动之后 | 无 | +| custom_install_hook | S01custom_install.sh | 驱动加载完成后(即 insmod_drv_hook 执行后) | 用户可以自定义安装过程,不需要使用 OS 默认安装流程。 | +| env_check_hook | S01check_hw.sh | 安装初始化之前 | 初始化之前检查硬件配置规格、获取硬件类型。 | +| set_install_ip_hook | S01set_install_ip.sh | 安装初始化过程中,配置网络时 | 用户根据自身组网,自定义网络配置。 | +| before_partition_hook | S01checkpart.sh | 在分区前调用 | 用户可以在分区之前检查分区配置文件是否正确。 | +| before_setup_os_hook | 无 | 解压repo之前 | 用户可以进行自定义分区挂载操作。
如果安装包解压的路径不是分区配置中指定的根分区。则需要用户自定义分区挂载,并将解压路径赋值给传入的全局变量。 | +| before_mkinitrd_hook | S01install_drv.sh | 执行 mkinitrd 操作之前 | initrd 放在硬盘的场景下,执行 mkinitrd 操作之前的 hook。用户可以进行添加、更新驱动文件等自定义操作。 | +| after_setup_os_hook | 无 | 安装完系统之后 | 用户可以在安装完成之后进行系统文件的自定义操作,包括修改 grub.cfg 等 | +| install_succ_hook | 无 | 系统安装流程成功结束 | 用户执行解析安装信息,回传安装是否成功等操作。install_succ_hook 不可以设置为 install_break。 | +| install_fail_hook | 无 | 系统安装失败 | 用户执行解析安装信息,回传安装是否成功等操作。install_fail_hook 不可以设置为 install_break。 | + +### 配置系统参数 + +开始制作操作系统 ISO 镜像之前,需要配置系统参数,包括主机参数、初始密码、分区、网络、编译参数和系统命令行参数。 + +#### 配置主机参数 + + /opt/imageTailor/custom/cfg_openEuler/sys.conf 文件的 \ \ 区域用于配置系统的常用参数,例如主机名、内核启动参数等。 + +openEuler 提供的默认配置如下,用户可以根据需要进行修改: + +```shell + + sys_service_enable='ipcc' + sys_service_disable='cloud-config cloud-final cloud-init-local cloud-init' + sys_utc='yes' + sys_timezone='' + sys_cut='no' + sys_usrrpm_cut='no' + sys_hostname='Euler' + sys_usermodules_autoload='' + sys_gconv='GBK' + +``` + +配置中的各参数含义如下: + +- sys_service_enable + + 可选配置。OS 默认启用的服务,多个服务请以空格分开。如果用户不需要新增系统服务,请保持缺省值为 ipcc 。配置时请注意: + + - 只能在默认配置的基础上增加系统服务,不能删减系统服务。 + - 可以配置业务相关的服务,但是需要 repo 源中包含业务 RPM 包。 + - 默认只开启该参数中配置的服务,如果服务依赖其他服务,需要将被依赖的服务也配置在该参数中。 + +- sys_service_disable + + 可选配置。禁止服务开机自启动的服务,多个服务请以空格分开。如果用户没有需要禁用的系统服务,请修改该参数为空。 + +- sys_utc + + 必选配置。是否采用 UTC 时间。yes 表示采用,no 表示不采用,缺省值为 yes 。 + +- sys_timezone + + 可选配置。设置时区,即该单板所处的时区。可配置的范围为 openEuler 支持的时区,可通过 /usr/share/zoneinfo/zone.tab 文件查询。 + +- sys_cut + + 必选配置。是否裁剪 RPM 包。可配置为 yes、no 或者 debug 。yes 表示裁剪,no 表示不裁剪(仅安装 rpm.conf 中的 RPM 包),debug 表示裁剪但会保留 `rpm` 命令方便安装后定制。缺省值为 no 。 + + > ![](./public_sys-resources/icon-note.gif) 说明: + > imageTailor 工具会先安装用户添加的 RPM 包,再删除 cmd.conf中 \ 区域的文件,最后删除cmd.conf 和 rpm.conf 中未配置的命令、库和驱动。 + > sys_cut='yes' 时,imageTailor 工具不支持 `rpm` 命令的安装,即使在 rpm.conf 中配置了也不生效。 + +- sys_usrrpm_cut + + 必选配置。是否裁剪用户添加到 /opt/imageTailor/custom/cfg_openEuler/usr_rpm 目录下的 RPM 包。yes 表示裁剪,no 表示不裁剪。缺省值为 no 。 + + - sys_usrrpm_cut='yes' :imageTailor 工具会先安装用户添加的 RPM 包,然后删除 cmd.conf 中 \ 区域配置的文件,最后删除 cmd.conf 和 rpm.conf 中未配置的命令、库和驱动。 + + - sys_usrrpm_cut='no' :imageTailor 工具会安装用户添加的 RPM 包,不删除用户 RPM 包中的文件。 + +- sys_hostname + + 必选配置。主机名。大批量部署 OS 时,部署成功后,建议修改每个节点的主机名,确保各个节点的主机名不重复。 + + 主机名要求:字母、数字、"-" 的组合,首字母必须是字母或数字。字母支持大小写。字符个数不超过 63 。缺省值为 Euler 。 + +- sys_usermodules_autoload + + 可选配置。系统启动阶段加载的驱动,配置该参数时,不需要填写后缀 .ko 。如果有多个驱动,请以空格分开。默认为空,不加载额外驱动。 + +- sys_gconv + + 可选配置。该参数用于定制 /usr/lib/gconv, /usr/lib64/gconv ,配置取值为: + + - null/NULL:表示不配置。如果裁剪系统(sys_cut=“yes”),则/usr/lib/gconv 和 /usr/lib64/gconv 会被删除。 + - all/ALL:不裁剪 /usr/lib/gconv 和 /usr/lib64/gconv 。 + - xxx,xxx: 保留 /usr/lib/gconv 和 /usr/lib64/gconv 目录下对应的文件。若需要保留多个文件,可用 "," 分隔。 + +- sys_man_cut + + 可选配置。配置是否裁剪 man 文档。yes 表示裁剪,no 表示不裁剪。缺省值为 yes 。 + +> ![](./public_sys-resources/icon-note.gif) 说明: +> +> sys_cut 和 sys_usrrpm_cut 同时配置时,sys_cut 优先级更高,即遵循如下原则: +> +> **sys_cut='no'**: +> +> 无论 sys_usrrpm_cut='no' 还是 sys_usrrpm_cut='yes' ,都为系统 RPM 包裁剪粒度,即imageTailor 会安装 repo 源中的 RPM 包和 usr_rpm 目录下的 RPM 包,但不会裁剪 RPM 包中的文件。即使用户不需要这些 RPM 包中的部分文件,imageTailor 也不会进行裁剪。 +> +> **sys_cut='yes',sys_usrrpm_cut='no'**: +> +> 系统 RPM 包文件裁剪粒度:imageTailor 会根据用户配置,裁剪 repo 源中 RPM 包的文件。 +> +> **sys_cut='yes',sys_usrrpm_cut='yes'**: +> +> 系统和用户 RPM 包文件裁剪粒度:imageTailor 会根据用户的配置,裁剪 repo 源和 usr_rpm 目录中 RPM 包的文件。 +> + +#### 配置初始密码 + +操作系统安装时,必须具有 root 初始密码和 grub 初始密码,否则裁剪得到的 ISO 在安装后无法使用 root 帐号进行登录。本节介绍配置初始密码的方法。 + +> ![](./public_sys-resources/icon-note.gif)说明: +> +> root 初始密码和 grub 初始密码,必须由用户自行配置。 + +##### 配置 root 初始密码 + +###### 简介 + +root 初始密码保存在 "/opt/imageTailor/custom/cfg_openEuler/rpm.conf" 中,用户通过修改该文件配置 root 初始密码。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 若使用 `mkdliso` 命令制作 ISO 镜像时需要使用 --minios yes/force 参数(制作在系统安装时进行系统引导的 initrd),则还需要在 /opt/imageTailor/kiwi/minios/cfg_minios/rpm.conf 中填写相应信息。 + +/opt/imageTailor/custom/cfg_openEuler/rpm.conf 中 root 初始密码的默认配置如下,需要用户自行添加: + +```Conf + + + +``` + +各参数含义如下: + +- group:用户所属组。 +- pwd:用户初始密码的加密密文,加密算法为 SHA-512。${pwd} 需要替换成用户实际的加密密文。 +- home:用户的家目录。 +- name:需要配置用户的用户名。 + +###### 修改方法 + +用户在制作 ISO 镜像前需要修改 root 用户的初始密码,这里给出设置 root 初始密码的方法(需使用 root 权限): + +1. 添加用于生成密码的用户,此处假设 testUser。 + + ```shell + sudo useradd testUser + ``` + +2. 设置 testUser 用户的密码。参考命令如下,根据提示设置密码: + + ```shell + $ sudo passwd testUser + Changing password for user testUser. + New password: + Retype new password: + passwd: all authentication tokens updated successfully. + ``` + +3. 查看 /etc/shadow 文件,testUser 后的内容(两个 : 间的字符串)即为加密后的密码。 + + ``` shell script + $ sudo cat /etc/shadow | grep testUser + testUser:$6$YkX5uFDGVO1VWbab$jvbwkZ2Kt0MzZXmPWy.7bJsgmkN0U2gEqhm9KqT1jwQBlwBGsF3Z59heEXyh8QKm3Qhc5C3jqg2N1ktv25xdP0:19052:0:90:7:35:: + ``` + +4. 拷贝上述加密密码替换 /opt/imageTailor/custom/cfg_openEuler/rpm.conf 中的 pwd 字段,如下所示: + + ``` shell script + + + + ``` + +5. 若使用 `mkdliso` 命令制作 ISO 镜像时需要使用 --minios yes/force 参数,请修改 /opt/imageTailor/kiwi/minios/cfg_minios/rpm.conf 中对应用户的 pwd 字段。 + + ``` shell script + + + + ``` + +##### 配置 grub 初始密码 + +grub 初始密码保存在 /opt/imageTailor/custom/cfg_openEuler/usr_file/etc/default/grub 中,用户通过修改该文件配置 grub 初始密码。如果未配置 grub 初始密码,制作 ISO 镜像会失败。 + +> ![](./public_sys-resources/icon-note.gif)说明: +> +> - 配置 grub 初始密码需要使用 root 权限。 +> - grub 密码对应的默认用户为 root 。 +> +> - 系统中需有 grub2-set-password 命令,若不存在,请提前安装该命令。 + +1. 执行如下命令,根据提示设置 grub 密码: + + ```shell + $ sudo grub2-set-password -o ./ + Enter password: + Confirm password: + grep: .//grub.cfg: No such file or directory + WARNING: The current configuration lacks password support! + Update your configuration with grub2-mkconfig to support this feature. + ``` + +2. 命令执行完成后,会在当前目录生成 user.cfg 文件,grub.pbkdf2.sha512 开头的内容即 grub 加密密码。 + + ```shell + $ sudo cat user.cfg + GRUB2_PASSWORD=grub.pbkdf2.sha512.10000.CE285BE1DED0012F8B2FB3DEA38782A5B1040FEC1E49D5F602285FD6A972D60177C365F1 + B5D4CB9D648AD4C70CF9AA2CF9F4D7F793D4CE008D9A2A696A3AF96A.0AF86AB3954777F40D324816E45DD8F66CA1DE836DC7FBED053DB02 + 4456EE657350A27FF1E74429546AD9B87BE8D3A13C2E686DD7C71D4D4E85294B6B06E0615 + ``` + +3. 复制上述密文,并在 /opt/imageTailor/custom/cfg_openEuler/usr_file/etc/default/grub 文件中增加如下配置: + + ```shell + GRUB_PASSWORD="grub.pbkdf2.sha512.10000.CE285BE1DED0012F8B2FB3DEA38782A5B1040FEC1E49D5F602285FD6A972D60177C365F1 + B5D4CB9D648AD4C70CF9AA2CF9F4D7F793D4CE008D9A2A696A3AF96A.0AF86AB3954777F40D324816E45DD8F66CA1DE836DC7FBED053DB02 + 4456EE657350A27FF1E74429546AD9B87BE8D3A13C2E686DD7C71D4D4E85294B6B06E0615" + ``` + +#### 配置分区 + +若用户想调整系统分区或业务分区,可以通过修改 /opt/imageTailor/custom/cfg_openEuler/sys.conf 文件中的 \ 实现。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 系统分区:存放操作系统的分区 +> 业务分区:存放业务数据的分区 +> 差别:在于存放的内容,而每个分区的大小、挂载路径和文件系统类型都不是区分业务分区和系统分区的依据。 +> 配置分区为可选项,用户也可以在安装 OS 之后,手动配置分区 + + \ 的配置格式为: + +hd 磁盘号 挂载路径 分区大小 分区类型 文件系统类型 [二次格式化标志位] + +其默认配置如下: + +``` shell + +hd0 /boot 512M primary ext4 yes +hd0 /boot/efi 200M primary vfat yes +hd0 / 30G primary ext4 +hd0 - - extended - +hd0 /var 1536M logical ext4 +hd0 /home max logical ext4 + +``` + +各参数含义如下: + +- hd 磁盘号 + 磁盘的编号。请按照 hdx 的格式填写,x 指第 x 块盘。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 分区配置只在被安装机器的磁盘能被识别时才有效。 + +- 挂载路径 + 指定分区挂载的路径。用户既可以配置业务分区,也可以对默认配置中的系统分区进行调整。如果不挂载,则设置为 '-'。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 分区配置中必须有 '/' 挂载路径。其他的请用户自行调整。 + > 采用 UEFI 引导时,在 x86_64 的分区配置中必须有 '/boot' 挂载路径,在 AArch64 的分区配置中必须有 '/boot/efi' 挂载路径。 + +- 分区大小 + 分区大小的取值有以下四种: + + - G/g:指定以 GB 为单位的分区大小,例如:2G。 + - M/m:指定以 MB 为单位的分区大小,例如:300M。 + - T/t:指定以 TB 为单位的分区大小,例如:1T。 + - MAX/max:指定将硬盘上剩余的空间全部用来创建一个分区。只能在最后一个分区配置该值。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 分区大小不支持小数,如果是小数,请换算成其他单位,调整为整数的数值。例如:不能填写 1.5G,应填写为 1536M。 + > 分区大小取 MAX/max 值时,剩余分区大小不能超过支持文件系统类型的限制(默认文件系统类型 ext4,限制大小 16T)。 + +- 分区类型 + 分区有以下三种: + + - 主分区: primary + - 扩展分区:extended(该分区只需配置 hd 磁盘号即可) + - 逻辑分区:logical + +- 文件系统类型 + 目前支持的文件系统类型有:ext4、vfat + +- 二次格式化标志位 + 可选配置,表示二次安装时是否格式化: + + - 是:yes + - 否:no 。不配置默认为 no 。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 二次格式化是指本次安装之前,磁盘已安装过 openEuler 系统。当前一次安装跟本次安装的使用相同的分区表配置(分区大小,挂载点,文件类型)时,该标志位可以配置是否格式化之前的分区,'/boot' 和 '/' 分区除外,每次都会重新格式化。如果目标机器第一次安装,则该标志位不生效,所有指定了文件系统的分区都会进行格式化。 + +#### 配置网络 + +系统网络参数保存在 /opt/imageTailor/custom/cfg_openEuler/sys.conf 中,用户可以通过该文件的\\ 配置修改目标 ISO 镜像的网络参数,例如:网卡名称、IP地址、子网掩码。 + +sys.conf 中默认的网络配置如下,其中 netconfig-0 代表网卡 eth0。如果需要配置多块网卡,例如eth1,请在配置文件中增加 \\,并在其中填写网卡 eth1 的各项参数。 + +```shell + +BOOTPROTO="dhcp" +DEVICE="eth0" +IPADDR="" +NETMASK="" +STARTMODE="auto" + +``` + +各参数含义请参见下表: + +- | 参数名称 | 是否必配 | 参数值 | 说明 | + | :-------- | -------- | :------------------------------------------------ | :----------------------------------------------------------- | + | BOOTPROTO | 是 | none / static / dhcp | none:引导时不使用协议,不配地址
static:静态分配地址
dhcp:使用 DHCP 协议动态获取地址 | + | DEVICE | 是 | 如:eth1 | 网卡名称 | + | IPADDR | 是 | 如:192.168.11.100 | IP 地址
当 BOOTPROTO 参数为 static 时,该参数必配;其他情况下,该参数不用配置 | + | NETMASK | 是 | - | 子网掩码
当 BOOTPROTO 参数为 static 时,该参数必配;其他情况下,该参数不用配置 | + | STARTMODE | 是 | manual / auto / hotplug / ifplugd / nfsroot / off | 启用网卡的方法:
manual:用户在终端执行 ifup 命令启用网卡。
auto \ hotplug \ ifplug \ nfsroot:当 OS 识别到该网卡时,便启用该网卡。
off:任何情况下,网卡都无法被启用。
各参数更具体的说明请在制作 ISO 镜像的机器上执行 `man ifcfg` 命令查看。 | + +#### 配置内核参数 + +为了系统能够更稳定高效地运行,用户可以根据需要修改内核命令行参数。imageTailor 工具制作的 OS 镜像,可以通过修改 /opt/imageTailor/custom/cfg_openEuler/usr_file/etc/default/grub 中的 GRUB_CMDLINE_LINUX 配置实现内核命令行参数修改。 GRUB_CMDLINE_LINUX 中内核命令行参数的默认配置如下: + +```shell +GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0 crashkernel=512M oops=panic softlockup_panic=1 reserve_kbox_mem=16M crash_kexec_post_notifiers panic=3 console=tty0" +``` + +此处各配置含义如下(其余常见的内核命令行参数请查阅内核相关文档): + +- net.ifnames=0 biosdevname=0 + + 以传统方式命名网卡。 + +- crashkernel=512M + + 为 kdump 预留的内存空间大小为 512 MB。 + +- oops=panic panic=3 + + 内核 oops 时直接 panic,并且 3 秒后重启系统。 + +- softlockup_panic=1 + + 在检测到软死锁(soft-lockup)时让内核 panic。 + +- reserve_kbox_mem=16M + + 为 kbox 预留的内存空间大小为 16 MB。 + +- console=tty0 + + 指定第一个虚拟控制台的输出设备为 tty0。 + +- crash_kexec_post_notifiers + + 系统 crash 后,先调用注册到 panic 通知链上的函数,再执行 kdump。 + +### 制作系统 + +操作系统定制完成后,可以通过 mkdliso 脚本制作系统镜像文件。 imageTailor 制作的 OS 为 ISO 格式的镜像文件。 + +#### 命令介绍 + +##### 命令格式 + +mkdliso -p openEuler -c custom/cfg_openEuler [--minios yes|no|force] [--sec] [-h] + +##### 参数说明 + +| 参数名称 | 是否必选 | 参数含义 | 取值范围 | +| -------- | -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| -p | 是 | 设置产品名称 | openEuler | +| c | 是 | 指定配置文件的相对路径 | custom/cfg_openEuler | +| --minios | 否 | 制作在系统安装时进行系统引导的 initrd | 默认为 yes
yes:第一次执行命令时会制作 initrd,之后执行命令会判断 'usr_install/boot'
目录下是否存在 initrd(sha256 校验)。如果存在,就不重新制作 initrd,否则制作 initrd 。
no:不制作 initrd,采用原有方式,系统引导和运行使用的 initrd 相同。
force:强制制作 initrd,不管 'usr_install/boot' 目录下是否存在 initrd。 | +| --sec | 否 | 是否对生成的 ISO 进行安全加固
如果用户不输入该参数,则由此造成的安全风险由用户承担 | 无 | +| -h | 否 | 获取帮助信息 | 无 | + +#### 制作指导 + +使用 mkdliso 制作 ISO 镜像的操作步骤如下: + +> ![](./public_sys-resources/icon-note.gif) 说明: +> +> - mkdliso 所在的绝对路径中不能有空格,否则会导致制作 ISO 失败。 +> - 制作 ISO 的环境中,umask 的值必须设置为 0022。 +> - 命令需在/opt/imageTailor目录中执行 + +1. 使用 root 权限,执行 mkdliso 命令,生成 ISO 镜像文件。参考命令如下: + + ```shell + # cd /opt/imageTailor/ + # sudo mkdliso -p openEuler -c custom/cfg_openEuler --sec + ``` + + 命令执行完成后,制作出的新文件在 /opt/imageTailor/result/{日期} 目录下,包括 openEuler-aarch64.iso 和 openEuler-aarch64.iso.sha256 。 + +2. 验证 ISO 镜像文件的完整性。此处假设日期为 2022-03-21-14-48 。 + + ```shell + cd /opt/imageTailor/result/2022-03-21-14-48/ + sha256sum -c openEuler-aarch64.iso.sha256 + ``` + + 回显如下,表示 ISO 镜像文件完整,ISO 制作完成。 + + ```text + openEuler-aarch64.iso: OK + ``` + + 若回显如下,表示镜像不完整,说明 ISO 镜像文件完整性被破坏,需要重新制作。 + + ```shell + openEuler-aarch64.iso: FAILED + sha256sum: WARNING: 1 computed checksum did NOT match + ``` + +3. 查看日志 + + 镜像制作完成后,可以根据需要(例如制作出错时)查看日志。第一次制作镜像时,对应的日志和安全加固日志被压缩为一个 tar 包(日志的命名格式为:sys_custom_log_{*日期* }.tar.gz),存放在 result/log 目录下。该目录只保留最近时间的 50 个日志压缩包,超过 50 个时会对旧文件进行覆盖。 + +### 裁剪时区 + +定制完成的 ISO 镜像安装后,用户可以根据需求裁剪 openEuler 系统支持的时区。本节介绍裁剪时区的方法。 + +openEuler 操作系统支持的时区信息存放在时区文件夹 /usr/share/zoneinfo 下,可通过如下命令查看: + +```shell +$ ls /usr/share/zoneinfo/ +Africa/ America/ Asia/ Atlantic/ Australia/ Etc/ Europe/ +Pacific/ zone.tab +``` + +其中每个子文件夹代表一个 Area ,当前 Area 包括:大陆、海洋以及 Etc 。每个 Area 文件夹内部则包含了隶属于其的 Location 。一个 Location 一般为一座城市或者一个岛屿。 + +所有时区均以 Area/Location 的形式来表示,比如中国大陆南部使用北京时间,其时区为 Asia/Shanghai(Location 并不一定会使用首都)。对应的,其时区文件为: + +```text +/usr/share/zoneinfo/Asia/Shanghai +``` + +若用户希望裁剪某些时区,则只需将对应的时区文件删除即可。 + +### 定制示例 + +本节给出使用 imageTailor 工具定制一个 ISO 操作系统镜像的简易方案,方便用户了解制作的整体流程。 + +1. 检查制作 ISO 所在环境是否满足要求。 + + ``` shell + $ cat /etc/openEuler-release + openEuler release 22.03 LTS + ``` + +2. 确保根目录有 40 GB 以上空间。 + + ```shell + $ df -h + Filesystem Size Used Avail Use% Mounted on + ...... + /dev/vdb 196G 28K 186G 1% / + ``` + +3. 安装 imageTailor 裁剪工具。具体安装方法请参见 [安装工具](#安装工具) 章节。 + + ```shell + $ sudo yum install -y imageTailor + $ ll /opt/imageTailor/ + total 88K + drwxr-xr-x. 3 root root 4.0K Mar 3 08:00 custom + drwxr-xr-x. 10 root root 4.0K Mar 3 08:00 kiwi + -r-x------. 1 root root 69K Mar 3 08:00 mkdliso + drwxr-xr-x. 2 root root 4.0K Mar 9 14:48 repos + drwxr-xr-x. 2 root root 4.0K Mar 9 14:48 security-tool + ``` + +4. 配置本地 repo 源。 + + ```shell + $ wget https://repo.openeuler.org/openEuler-22.03-LTS/ISO/aarch64/openEuler-22.03-LTS-everything-aarch64-dvd.iso + $ sudo mkdir -p /opt/openEuler_repo + $ sudo mount openEuler-22.03-LTS-everything-aarch64-dvd.iso /opt/openEuler_repo + mount: /opt/openEuler_repo: WARNING: source write-protected, mounted read-only. + $ sudo rm -rf /opt/imageTailor/repos/euler_base && sudo mkdir -p /opt/imageTailor/repos/euler_base + $ sudo cp -ar /opt/openEuler_repo/Packages/* /opt/imageTailor/repos/euler_base + $ sudo chmod -R 644 /opt/imageTailor/repos/euler_base + $ sudo ls /opt/imageTailor/repos/euler_base|wc -l + 2577 + $ sudo umount /opt/openEuler_repo && sudo rm -rf /opt/openEuler_repo + $ cd /opt/imageTailor + ``` + +5. 修改 grub/root 密码 + + 以下 ${pwd} 的实际内容请参见 [配置初始密码](#配置初始密码) 章节生成并替换。 + + ```shell + $ cd /opt/imageTailor/ + $ sudo vi custom/cfg_openEuler/usr_file/etc/default/grub + GRUB_PASSWORD="${pwd1}" + $ + $ sudo vi kiwi/minios/cfg_minios/rpm.conf + + + + $ + $ sudo vi custom/cfg_openEuler/rpm.conf + + + + ``` + +6. 执行裁剪命令。 + + ```shell + $ sudo rm -rf /opt/imageTailor/result + $ sudo ./mkdliso -p openEuler -c custom/cfg_openEuler --minios force + ...... + Complete release iso file at: result/2022-03-09-15-31/openEuler-aarch64.iso + move all mkdliso log file to result/log/sys_custom_log_20220309153231.tar.gz + $ ll result/2022-03-09-15-31/ + total 889M + -rw-r--r--. 1 root root 889M Mar 9 15:32 openEuler-aarch64.iso + -rw-r--r--. 1 root root 87 Mar 9 15:32 openEuler-aarch64.iso.sha256 + ``` diff --git a/docs/en/25.03/Tools/CommunityTools/ImageCustom/imageTailor/public_sys-resources/icon-note.gif b/docs/en/25.03/Tools/CommunityTools/ImageCustom/imageTailor/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/ImageCustom/imageTailor/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/.markdownlint.json b/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/.markdownlint.json new file mode 100644 index 0000000000000000000000000000000000000000..9c8089adebd7e34b9fe5e295b539e5d4ca181292 --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/.markdownlint.json @@ -0,0 +1,26 @@ +{ + + "default":true, + "MD003":{"style":"atx"}, + "MD007":{"indent":4}, + "MD029":{"style":"ordered"}, + "MD009":false, + "MD013":false, + "MD014":false, + "MD020":false, + "MD021":false, + "MD024":false, + "MD025":false, + "MD033":false, + "MD036":false, + "MD042":false, + "MD043":false, + "MD044":false, + "MD045":false, + "MD048":false, + "MD049":false, + "MD050":false, + "MD051":false, + "MD052":false, + "MD053":false +} \ No newline at end of file diff --git a/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/_menu.md b/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..6cd63695dc058a95cf028f7d64b60256104885f3 --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/_menu.md @@ -0,0 +1,8 @@ +--- +label: 'isocut 使用指南' +ismanual: 'Y' +description: '对 openEuler 光盘镜像进行裁剪定制' +children: + - label: 'isocut 使用指南' + href: './isocut-user-guide.md' +--- \ No newline at end of file diff --git a/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/faqs.md b/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..a511946cdb05ef4af0811ea87a43dd9d46706db5 --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/faqs.md @@ -0,0 +1,46 @@ +# 常见问题与解决方法 + +## **问题1:默认 rpm 包列表安装系统失败** + +### 背景描述 + +用户使用 isocut 裁剪镜像时通过配置文件 /etc/isocut/rpmlist 指定需要安装的软件包。 + +由于不同版本会有软件包减少,可能导致裁剪镜像时出现缺包等问题。 +因此 /etc/isocut/rpmlist 中默认只包含 kernel 软件包。 +保证默认配置裁剪镜像必定成功。 + +### 问题描述 + +使用默认配置裁剪出来的 iso 镜像,能够裁剪成功,但是安装可能失败。 + +安装报错缺包,报错截图如下: + +![](./figures/lack_pack.png) + +### 原因分析 + +使用默认配置的 RPM 软件包列表,裁剪的 iso 镜像在安装时缺少必要的 RPM 包。 +缺少的包如报错的图示,并且在不同版本中,缺少的 RPM 包也可能是不同的,以安装时实际报错为准。 + +### 解决方案 + +1. 增加缺少的包 + + 1. 根据报错的提示整理缺少的 RPM 包列表 + 2. 将上述 RPM 包列表添加到配置文件 /etc/isocut/rpmlist 中。 + 3. 再次裁剪安装 iso 镜像 + + 以问题描述中的缺包情况为例,修改 rpmlist 配置文件如下: + + ```shell + $ cat /etc/isocut/rpmlist + kernel.aarch64 + lvm2.aarch64 + chrony.aarch64 + authselect.aarch64 + shim.aarch64 + efibootmgr.aarch64 + grub2-efi-aa64.aarch64 + dosfstools.aarch64 + ``` diff --git a/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/figures/lack_pack.png b/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/figures/lack_pack.png new file mode 100644 index 0000000000000000000000000000000000000000..a4b7f1da15da70f63a86aae360e89017c2b98f2d Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/figures/lack_pack.png differ diff --git a/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/isocut-user-guide.md b/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/isocut-user-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..cb81110b3ae9ee10acb95466900fc3b32f057f08 --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/isocut-user-guide.md @@ -0,0 +1,325 @@ +# isocut 使用指南 + +- [简介](#简介) +- [软硬件要求](#软硬件要求) +- [安装工具](#安装工具) +- [裁剪定制镜像](#裁剪定制镜像) + - [命令介绍](#命令介绍) + - [软件包来源](#软件包来源) + - [操作指导](#操作指导) + +## 简介 + +openEuler 光盘镜像较大,下载、传输镜像很耗时。另外,使用 openEuler 光盘镜像安装操作系统时,会安装镜像所包含的全量 RPM 软件包,用户无法只安装部分所需的软件包。 + +在某些场景下,用户不需要安装镜像提供的全量软件包,或者需要一些额外的软件包。因此,openEuler 提供了镜像裁剪定制工具。通过该工具,用户可以基于 openEuler 光盘镜像裁剪定制仅包含所需 RPM 软件包的 ISO 镜像。这些软件包可以来自原有 ISO 镜像,也可以额外指定,从而满足用户定制需求。 + +本文档介绍 openEuler 镜像裁剪定制工具的安装和使用方法,以指导用户更好的完成镜像裁剪定制。 + +## 软硬件要求 + +使用 openEuler 裁剪定制工具制作 ISO 所使用的机器需要满足如下软硬件要求: + +- CPU 架构为 AArch64 或者 x86_64 +- 操作系统为 openEuler 20.03 LTS SP3 +- 建议预留 30 GB 以上的磁盘空间(用于运行裁剪定制工具和存放 ISO 镜像) + +## 安装工具 + +此处以 openEuler 20.03 LTS SP3 版本的 AArch64 架构为例,介绍 ISO 镜像裁剪定制工具的安装操作。 + +1. 确认机器已安装操作系统 openEuler 20.03 LTS SP3(镜像裁剪定制工具的运行环境)。 + + ``` shell script + $ cat /etc/openEuler-release + openEuler release 20.03 (LTS-SP3) + ``` + +2. 下载对应架构的 ISO 镜像(必须是 everything 版本),并存放在任一目录(建议该目录磁盘空间大于 20 GB),此处假设存放在 /home/isocut_iso 目录。 + + AArch64 架构的镜像下载链接为: + + + + > **说明:** + > x86_64 架构的镜像下载链接为: + > + > + +3. 创建文件 /etc/yum.repos.d/local.repo,配置对应 yum 源。配置内容参考如下,其中 baseurl 是用于挂载 ISO 镜像的目录: + + ``` shell script + [local] + name=local + baseurl=file:///home/isocut_mount + gpgcheck=0 + enabled=1 + ``` + +4. 使用 root 权限,挂载光盘镜像到 /home/isocut_mount 目录(请与上述 repo 文件中配置的 baseurl 保持一致)作为 yum 源,参考命令如下: + + ```shell + sudo mount -o loop /home/isocut_iso/openEuler-20.03-LTS-SP3-everything-aarch64-dvd.iso /home/isocut_mount + ``` + +5. 使 yum 源生效: + + ```shell + yum clean all + yum makecache + ``` + +6. 使用 root 权限,安装镜像裁剪定制工具: + + ```shell + sudo yum install -y isocut + ``` + +7. 使用 root 权限,确认工具已安装成功。 + + ```shell + $ sudo isocut -h + Checking input ... + usage: isocut [-h] [-t temporary_path] [-r rpm_path] [-k file_path] source_iso dest_iso + + Cut openEuler iso to small one + + positional arguments: + source_iso source iso image + dest_iso destination iso image + + optional arguments: + -h, --help show this help message and exit + -t temporary_path temporary path + -r rpm_path extern rpm packages path + -k file_path kickstart file + ``` + +## 裁剪定制镜像 + +此处介绍如何使用镜像裁剪定制工具基于 openEuler 光盘镜像裁剪或添加额外 RPM 软件包制作新镜像的方法。 + +### 命令介绍 + +#### 命令格式 + +镜像裁剪定制工具通过 isocut 命令执行功能。命令的使用格式为: + +`isocut [ --help | -h ] [ -t <*temp_path*> ] [ -r <*rpm_path*> ] [ -k <*file_path*> ] < *source_iso* > < *dest_iso* >` + +#### 参数说明 + +| 参数 | 是否必选 | 参数含义 | +| ---------------- | -------- | ------------------------------------------------------------ | +| --help \| -h | 否 | 查询命令的帮助信息。 | +| -t \<*temp_path*> | 否 | 指定工具运行的临时目录 *temp_path*,其中 *temp_path* 为绝对路径。默认为 /tmp 。 | +| -r \<*rpm_path*> | 否 | 用户需要额外添加到 ISO 镜像中的 RPM 包路径。 | +| -k \<*file_path*> | 否 | 用户需要使用 kickstart 自动安装,指定 kickstart 模板路径。 | +| *source_iso* | 是 | 用于裁剪的 ISO 源镜像所在路径和名称。不指定路径时,默认当前路径。 | +| *dest_iso* | 是 | 裁剪定制生成的 ISO 新镜像存放路径和名称。不指定路径时,默认当前路径。 | + +### 软件包来源 + +新镜像的 RPM 包来源有: + +- 原有 ISO 镜像。该情况通过配置文件 /etc/isocut/rpmlist 指定需要安装的 RPM 软件包,配置格式为 "软件包名.对应架构",例如:kernel.aarch64 。 + +- 额外指定。执行 **isocut** 时使用 -r 参数指定软件包所在路径,并将添加的 RPM 包按上述格式添加到配置文件 /etc/isocut/rpmlist 中。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 裁剪定制镜像时,若无法找到配置文件中指定的 RPM 包,则镜像中不会添加该 RPM 包。 + > 若 RPM 包的依赖有问题,则裁剪定制镜像时可能会报错。 + +### kickstart 功能介绍 + +用户需要实现镜像自动化安装,可以通过 kickstart 的方式。在执行 **isocut** 时使用 -k 参数指定 kickstart 文件。 + +isocut 为用户提供了 kickstart 模板,路径是 /etc/isocut/anaconda-ks.cfg,用户可以基于该模板修改。 + +#### 修改 kickstart 模板 + +若用户需要使用 isocut 工具提供的 kickstart 模板,需要修改以下内容: + +- 必须在文件 /etc/isocut/anaconda-ks.cfg 中配置 root 和 grub2 的密码。否则镜像自动化安装会卡在设置密码的环节,等待用户手动输入密码。 +- 如果要添加额外 RPM 包,并使用 kickstart 自动安装,则在 /etc/isocut/rpmlist 和 kickstart 文件的 %packages 字段都要指定该 RPM 包。 + +接下来介绍 kickstart 文件详细修改方法。 + +##### 配置初始密码 + +###### 配置 root 初始密码 + +/etc/isocut/anaconda-ks.cfg 中 root 初始密码的默认配置如下,其中 ${pwd} 需要替换成用户实际的加密密文: + +```shell +rootpw --iscrypted ${pwd} +``` + +这里给出设置 root 初始密码的方法(需使用 root 权限): + +1. 添加用于生成密码的用户,此处假设 testUser。 + + ``` shell script + $ sudo useradd testUser + ``` + +2. 设置 testUser 用户的密码。参考命令如下,根据提示设置密码: + + ``` shell script + $ sudo passwd testUser + Changing password for user testUser. + New password: + Retype new password: + passwd: all authentication tokens updated successfully. + ``` + +3. 查看 /etc/shadow 文件,获取加密密码(用户 testUser 后,两个 : 间的字符串,此处使用 *** 代替)。 + + ``` shell script + $ sudo cat /etc/shadow | grep testUser + testUser:***:19052:0:90:7:35:: + ``` + +4. 拷贝上述加密密码替换 /etc/isocut/anaconda-ks.cfg 中的 pwd 字段,如下所示(请用实际内容替换 *** ): + + ``` shell script + rootpw --iscrypted *** + ``` + +###### 配置 grub2 初始密码 + +/etc/isocut/anaconda-ks.cfg 文件中添加以下配置,配置 grub2 初始密码。其中 ${pwd} 需要替换成用户实际的加密密文: + +```shell +%addon com_huawei_grub_safe --iscrypted --password='${pwd}' +%end +``` + +> ![](./public_sys-resources/icon-note.gif)说明: +> +> - 配置 grub 初始密码需要使用 root 权限。 +> - grub 密码对应的默认用户为 root 。 +> +> - 系统中需有 grub2-set-password 命令,若不存在,请提前安装该命令。 + +1. 执行如下命令,根据提示设置 grub2 密码: + + ```shell + $ sudo grub2-set-password -o ./ + Enter password: + Confirm password: + grep: .//grub.cfg: No such file or directory + WARNING: The current configuration lacks password support! + Update your configuration with grub2-mkconfig to support this feature. + ``` + +2. 命令执行完成后,会在当前目录生成 user.cfg 文件,grub.pbkdf2.sha512 开头的内容即 grub2 加密密码。 + + ```shell + $ sudo cat user.cfg + GRUB2_PASSWORD=grub.pbkdf2.sha512.*** + ``` + +3. 复制上述密文,并在 /etc/isocut/anaconda-ks.cfg 文件中增加如下配置: + + ```shell + %addon com_huawei_grub_safe --iscrypted --password='grub.pbkdf2.sha512.***' + %end + ``` + +##### 配置 %packages 字段 + +如果需要添加额外 RPM 包,并使用 kickstart 自动安装,需要在 /etc/isocut/rpmlist 和 kickstart 文件的 %packages 字段都指定该 RPM 包。 + +此处介绍在 /etc/isocut/anaconda-ks.cfg 文件中添加 RPM 包。 + +/etc/isocut/anaconda-ks.cfg 文件的 %packages 默认配置如下: + +```shell +%packages --multilib --ignoremissing +acl.aarch64 +aide.aarch64 +...... +NetworkManager.aarch64 +%end +``` + +将额外指定的 RPM 软件包添加到 %packages 配置中,需要遵循如下配置格式: + +"软件包名.对应架构",例如:kernel.aarch64 + +```shell +%packages --multilib --ignoremissing +acl.aarch64 +aide.aarch64 +...... +NetworkManager.aarch64 +kernel.aarch64 +%end +``` + +### 操作指导 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> 请不要修改或删除 /etc/isocut/rpmlist 文件中的默认配置项。 +> isocut 的所有操作需要使用 root 权限。 +> 待裁剪的源镜像可以为基础镜像,也可以是 everything 版镜像,例子中以基础版镜像 openEuler-20. 03-LTS-SP3-aarch64-dvd.iso 为例。 +> 例子中假设新生成的镜像名称为 new.iso,且存放在 /home/result 路径;运行工具的临时目录为 /home/temp;额外的 RPM 软件包存放在 /home/rpms 目录。 + +1. 修改配置文件 /etc/isocut/rpmlist,指定用户需要安装的 RPM 软件包(来自原有 ISO 镜像)。 + + ``` shell script + sudo vi /etc/isocut/rpmlist + ``` + +2. 确定运行镜像裁剪定制工具的临时目录空间大于 8 GB 。默认临时目录为 /tmp,也可以使用 -t 参数指定其他目录作为临时目录,该目录必须为绝对路径。本例中使用目录 /home/temp,由如下回显可知 /home 目录可用磁盘为 38 GB,满足要求。 + + ```shell + $ df -h + Filesystem Size Used Avail Use% Mounted on + devtmpfs 1.2G 0 1.2G 0% /dev + tmpfs 1.5G 0 1.5G 0% /dev/shm + tmpfs 1.5G 23M 1.5G 2% /run + tmpfs 1.5G 0 1.5G 0% /sys/fs/cgroup + /dev/mapper/openeuler_openeuler-root 69G 2.8G 63G 5% / + /dev/sda2 976M 114M 796M 13% /boot + /dev/mapper/openeuler_openeuler-home 61G 21G 38G 35% /home + ``` + +3. 执行裁剪定制。 + + **场景一**:新镜像的所有 RPM 包来自原有 ISO 镜像 + + ``` shell script + $ sudo isocut -t /home/temp /home/isocut_iso/openEuler-20.03-LTS-SP3-aarch64-dvd.iso /home/result/new.iso + Checking input ... + Checking user ... + Checking necessary tools ... + Initing workspace ... + Copying basic part of iso image ... + Downloading rpms ... + Finish create yum conf + finished + Regenerating repodata ... + Checking rpm deps ... + Getting the description of iso image ... + Remaking iso ... + Adding checksum for iso ... + Adding sha256sum for iso ... + ISO cutout succeeded, enjoy your new image "/home/result/new.iso" + isocut.lock unlocked ... + ``` + + 回显如上,说明新镜像 new.iso 定制成功。 + + **场景二**:新镜像的 RPM 包除来自原有 ISO 镜像,还包含来自 /home/rpms 的额外软件包 + + ```shell + sudo isocut -t /home/temp -r /home/rpms /home/isocut_iso/openEuler-20.03-LTS-SP3-aarch64-dvd.iso /home/result/new.iso + ``` + + **场景三**:使用 kickstart 文件实现自动化安装,需要修改 /etc/isocut/anaconda-ks.cfg 文件 + + ```shell + sudo isocut -t /home/temp -k /etc/isocut/anaconda-ks.cfg /home/isocut_iso/openEuler-20.03-LTS-SP3-aarch64-dvd.iso /home/result/new.iso + ``` diff --git a/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/public_sys-resources/icon-note.gif b/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/ImageCustom/isocut/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/_menu.md b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..311a5d3aa5249e7fc8c5875df9506099395355f0 --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/_menu.md @@ -0,0 +1,8 @@ +--- +label: 'Migration-tools用户指南' +ismanual: 'Y' +description: '从原系统(centos7、centos8)迁移到统信服务器操作系统' +children: + - label: 'Migration-tools用户指南' + href: './migration-tools-user-guide.md' +--- diff --git a/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/kernel.png b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/kernel.png new file mode 100644 index 0000000000000000000000000000000000000000..ecd5bbb3cf306e46da3448de46c4f9fc2e03eed2 Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/kernel.png differ diff --git a/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/migration-tools-conf.png b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/migration-tools-conf.png new file mode 100644 index 0000000000000000000000000000000000000000..80520c44a86172c9f18e3d50930e0fcc25f411bb Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/migration-tools-conf.png differ diff --git a/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/openeuler-migration-complete.png b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/openeuler-migration-complete.png new file mode 100644 index 0000000000000000000000000000000000000000..20c5a4afaf2b06fae865137b9d4efd53326a9611 Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/openeuler-migration-complete.png differ diff --git a/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/repo.png b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/repo.png new file mode 100644 index 0000000000000000000000000000000000000000..78437bbc839bff8906b535989bbac0c38a6263b7 Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/repo.png differ diff --git "a/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\346\217\220\347\244\272.png" "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\346\217\220\347\244\272.png" new file mode 100644 index 0000000000000000000000000000000000000000..224a79aece026a4fa2b003753f40fc0f1ebd4d0d Binary files /dev/null and "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\346\217\220\347\244\272.png" differ diff --git "a/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\347\216\257\345\242\203\346\243\200\346\265\213.png" "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\347\216\257\345\242\203\346\243\200\346\265\213.png" new file mode 100644 index 0000000000000000000000000000000000000000..b03c4da5ba24e345a3614cd2c7d7e3b52983ad1a Binary files /dev/null and "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\347\216\257\345\242\203\346\243\200\346\265\213.png" differ diff --git "a/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\347\224\250\346\210\267\346\243\200\346\265\213.png" "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\347\224\250\346\210\267\346\243\200\346\265\213.png" new file mode 100644 index 0000000000000000000000000000000000000000..8ec0b5518f37532eedb5897bc368d9b58a1ccafc Binary files /dev/null and "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\347\224\250\346\210\267\346\243\200\346\265\213.png" differ diff --git "a/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\256\270\345\217\257\345\215\217\350\256\256.png" "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\256\270\345\217\257\345\215\217\350\256\256.png" new file mode 100644 index 0000000000000000000000000000000000000000..41eb3b6aa755619b94965f8060a27c1940e6936e Binary files /dev/null and "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\256\270\345\217\257\345\215\217\350\256\256.png" differ diff --git "a/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\277\201\347\247\273\344\270\255.png" "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\277\201\347\247\273\344\270\255.png" new file mode 100644 index 0000000000000000000000000000000000000000..e5bae64aaa303a6e7950ec0fdeb46a66bfaa70a3 Binary files /dev/null and "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\277\201\347\247\273\344\270\255.png" differ diff --git "a/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\277\201\347\247\273\345\256\214\346\210\220.png" "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\277\201\347\247\273\345\256\214\346\210\220.png" new file mode 100644 index 0000000000000000000000000000000000000000..c832bb723ea5400aa2fe1f932f1f5dcb5a3d5065 Binary files /dev/null and "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\277\201\347\247\273\345\256\214\346\210\220.png" differ diff --git "a/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\277\201\347\247\273\345\274\200\345\247\213.png" "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\277\201\347\247\273\345\274\200\345\247\213.png" new file mode 100644 index 0000000000000000000000000000000000000000..d8a2b58cd5ce8e559bd82c14400e16b4635d0ec3 Binary files /dev/null and "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\277\201\347\247\273\345\274\200\345\247\213.png" differ diff --git "a/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\277\201\347\247\273\346\243\200\346\237\245.png" "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\277\201\347\247\273\346\243\200\346\237\245.png" new file mode 100644 index 0000000000000000000000000000000000000000..776e9cafdf7e569cd33e1abd47217aa47c86f134 Binary files /dev/null and "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\277\201\347\247\273\346\243\200\346\237\245.png" differ diff --git "a/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\277\201\347\247\273\347\241\256\350\256\244.png" "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\277\201\347\247\273\347\241\256\350\256\244.png" new file mode 100644 index 0000000000000000000000000000000000000000..69567eabd886befe43fb8a512e7b6cde87fd0937 Binary files /dev/null and "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\350\277\201\347\247\273\347\241\256\350\256\244.png" differ diff --git "a/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\351\205\215\347\275\256\346\226\207\344\273\266.png" "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\351\205\215\347\275\256\346\226\207\344\273\266.png" new file mode 100644 index 0000000000000000000000000000000000000000..aed6ce1cf37b1aad8d7bb037a422c726bb024d86 Binary files /dev/null and "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\351\205\215\347\275\256\346\226\207\344\273\266.png" differ diff --git "a/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\351\246\226\351\241\265.png" "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\351\246\226\351\241\265.png" new file mode 100644 index 0000000000000000000000000000000000000000..2fb66ae7dc8336d6e38437ba79175fe1c2207a5d Binary files /dev/null and "b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/figures/\351\246\226\351\241\265.png" differ diff --git a/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/migration-tools-user-guide.md b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/migration-tools-user-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..8246be9e075142cc82b595a8eeb8b5469ae13ea2 --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/Migration/migration-tools/migration-tools-user-guide.md @@ -0,0 +1,276 @@ +# migration-tools用户指南 + +## 介绍 + +本文主要介绍服务器迁移软件(以下简称“migration-tools”)的使用方法,帮助用户顺利从原系统(centos7、centos8)迁移到统信服务器操作系统。 +migration-tools 工具提供网页界面方式进行操作,以供使用者在图形化界面便捷的进行迁移操作。 + +### 部署方式 + +在安装 openeuler 23.09 服务器上部署服务端(server),在需要迁移的 centos7/centos8 服务器上部署客户端(agent)。 + +#### 支持迁移的系统 + +1. 支持将 AMD64 和 ARM64 架构的 CentOS 系列系统迁移到 UOS 系统,迁移前需自行准备目标系统的全量源。 + +2. openeuler迁移:目前仅支持 centos 7.4 cui 系统迁移至 openeuler 20.03-LTS-SP1。 + +3. 不建议对安装了 i686 架构的 rpm 包的原系统进行迁移,如果对这种原系统进行迁移会出现迁移失败的结果。 + +|原系统|目标系统|使用的软件源| +|---|---|---| +|centos 7.4 cui|openeuler 20.03-LTS-SP1|使用openeuler外网源| +|centos 7.0~7.7|UOS 1002a|UOS 1002a(全量源)| +|centos 8.0~8.2|UOS 1050a|UOS 1050a(全量源)| + +### 使用方法 + +#### 安装与配置 + +##### 安装 migration-tools-server 端 + +- 关闭防火墙。 + + ``` shell + + systemctl stop firewalld + + ``` + +- 安装 migration-tools-server。 + + ``` shell + yum install migration-tools-server -y + ``` + +- 修改配置文件。 + + ``` shell + + vim /etc/migration-tools/migration-tools.conf + + ``` + + ![配置文件](./figures/migration-tools-conf.png) + +- 重启 migration-tools-server 服务。 + + ``` shell + + systemctl restart migration-tools-server + + ``` + +- 分发 agent 软件包。 + +- 根据迁移系统的版本选择分发的软件包。 + + centos7系列: + + xx.xx.xx.xx表示迁移机器IP + + ``` shell + + scp -r /usr/lib/migration-tools-server/agent-rpm/el7 root@xx.xx.xx.xx:/root + + ``` + + centos8系列: + + ``` shell + + scp -r /usr/lib/migration-tools-server/agent-rpm/el8 root@xx.xx.xx.xx:/root + + ``` + +#### 迁移 openeuler 系统 + +>**注意:** openeuler 系统目前仅支持单独使用脚本迁移。 + +- 从 server 端分发迁移脚本至 agent 端。 + + ``` shell + + cd /usr/lib/migration-tools-server/ut-Migration-tools-0.1/centos7/ + scp openeuler/centos72openeuler.py root@10.12.23.106:/root + + ``` + +- 安装迁移所需依赖。 + + ``` shell + + yum install python3 dnf rsync yum-utils -y + + ``` + +- 开始迁移。 + + ``` shell + + python3 centos7/openeuler/centos72openeuler.py + + ``` + +- 迁移完成后系统会自动重启,重启完成后即迁移完成。 + + ![openeuler迁移完成](./figures/openeuler-migration-complete.png) + +#### 迁移 UOS 系统 + +##### 安装 migration-tools-agent 端 + +在准备迁移的 centos 机器上执行以下步骤: + +>**注意:** 目前 migration-tools 仅支持 centos7.4 cui 迁移至 openeuler 20.03-LTS-SP1。 + +- 关闭防火墙。 + + ``` shell + + systemctl stop firewalld + + ``` + +- 安装 epel-release(部分依赖包含在 epel 源中)。 + + ``` shell + + yum install epel-release -y + + ``` + +- 安装 migration-tools-agent 软件包(centos7 系列需安装对应架构的软件包)。 + + centos7: + + ``` shell + + cd /root/el7/x86_64 + yum install ./* -y + + ``` + + centos8 + + ``` shell + + cd /root/el8/ + yum install ./* -y + + ``` + +- 修改配置文件。 + + ``` shell + + vim /etc/migration-tools/migration-tools.conf + + ``` + + ![配置文件](./figures/migration-tools-conf.png) + +- 重启 migration-tools-agent 服务。 + + ``` shell + + systemctl restart migration-tools-agent + + ``` + +##### UOS系统迁移步骤 + +- 登录web端 + + 在 server 端和 agent 端服务均启动后,打开浏览器(建议使用:Chrome),在浏览器导航栏中输入`https://SERVER_IP:9999`即可。 + + ![首页](./figures/首页.png) + +- 点击“我已阅读并同意此协议”,然后点击“下一步”。 + ![许可协议](./figures/许可协议.png) + +- 迁移提示页面内容如下,点击“下一步”。 + ![提示](./figures/提示.png) + +- 环境检测页面会检查系统版本和系统剩余空间大小,在检测完成后点击“下一步”。 + +>**注意:** 如果出现检测长时间无反应,请检查 agent 防火墙是否关闭,server与agent 服务是否开启。 +> 如需重新检测,在浏览器中刷新即可。 + + ![环境检测](./figures/环境检测.png) + +- 用户检测页面会检查用户名以及密码,推荐使用 root 用户,点击“下一步”开始检测,检测完成后自动进入 repo 源配置页面。 + + ![用户检测](./figures/用户检测.png) + +repo 源配置页面: + +- 请根据要迁移的系统输入对应的repo源。 + + centos7:1002a,centos8:1050a + +- 确保使用的软件源为全量源,否则迁移会失败。 + +- 输入栏中只需输入1个软件仓库路径即可。 + +![repo](./figures/repo.png) + +- 输入完成后点击“下一步”,等待软件源连通性检测完毕后,进入 kernel 版本选择页面,选择 4.19 内核,点击“下一步”。 + + ![kernel](./figures/kernel.png) + +- 迁移环境检查界面可以对比迁移前后的软件包差异,并输出检测报告,检查完成后可以导出检测报告。 + + > **注意:** 检测时间大约为1个小时,请耐心等待。 + + ![迁移检查](./figures/迁移检查.png) + +- 检测完成后,点击“下一步”会弹出系统迁移“确认”窗口,请确保系统已做好备份,准备完成后点击确认开始系统迁移。 + + ![迁移确认](./figures/迁移确认.png) + +- 点击“确认”后,进入系统迁移页面。 + + ![迁移开始](./figures/迁移开始.png) + +- 可以点击“查看详情”,来查看迁移情况。 + + ![迁移中](./figures/迁移中.png) + +- 迁移完成后,页面会跳转至迁移完成页面,可在该页面导出迁移分析报告及迁移日志。 + +- 导出后,可在 server 端 /var/tmp/uos-migration/ 目录下找到报告和日志的压缩包,解压后即可查看。 + + ![迁移完成](./figures/迁移完成.png) + +- 迁移完成后,需手动重启 agent 机器,并验证是否迁移完成。 + +###### 验证步骤 + +执行以下命令,检查操作系统版本是否已迁移至目标操作系统。 + +``` shell +uosinfo +``` + +如显示以下信息表示迁移成功。 + +1002a: + +``` shell +################################################# +Release: UnionTech OS Server release 20 (kongli) +Kernel : 4.19.0-91.77.97.uelc20.x86_64 +Build : UnionTech OS Server 20 1002c 20211228 x86_64 +################################################# +``` + +1050a: + +``` shell +################################################# +Release: UnionTech OS Server release 20 (kongzi) +Kernel : 4.19.0-91.82.88.uelc20.x86_64 +Build : UnionTech OS Server 20 1050a 20220214 x86_64 +################################################# +``` diff --git a/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/_menu.md b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..26463c8a33eb72167054c85308149611eecfd9a2 --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/_menu.md @@ -0,0 +1,12 @@ +--- +label: 'EulerLauncher 用户指南' +ismanual: 'Y' +description: '为开发者提供在主流桌面操作系统上高性能的开发资源' +children: + - label: '概述' + href: './overall.md' + - label: '在Windows下安装与运行EulerLauncher' + href: './win-user-manual.md' + - label: '在MacOS下安装与运行EulerLauncher' + href: './mac-user-manual.md' +--- diff --git a/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/mac-content.jpg b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/mac-content.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4b9f101056fb7bde536342896b94a698e72889a2 Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/mac-content.jpg differ diff --git a/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/mac-install.jpg b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/mac-install.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b710de9b24b76c35017cee591bc704750855781d Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/mac-install.jpg differ diff --git a/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/mac-start.jpg b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/mac-start.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2805c6244da9d1409958e8c33fc5296b1e138856 Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/mac-start.jpg differ diff --git a/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/mac-terminal.jpg b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/mac-terminal.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d0f3082cc64658afd888a02ca578f76857578f83 Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/mac-terminal.jpg differ diff --git a/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/mac-visudo.jpg b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/mac-visudo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7466ef4fec0f928ca0c0255ba59b628251216eb1 Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/mac-visudo.jpg differ diff --git a/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/win-install.jpg b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/win-install.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e395f62c0eb29390c980853f1d51ceb09641001e Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/win-install.jpg differ diff --git a/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/win-terminal-1.jpg b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/win-terminal-1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5976bff82cd34b6195f11291d0a99341133cfce3 Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/win-terminal-1.jpg differ diff --git a/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/win-terminal-2.jpg b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/win-terminal-2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a831c6972f99a30355f68e34f30e09be237f0723 Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/images/win-terminal-2.jpg differ diff --git a/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/mac-user-manual.md b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/mac-user-manual.md new file mode 100644 index 0000000000000000000000000000000000000000..6a90501993b43b78f7b3cba88de476090bd7f275 --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/mac-user-manual.md @@ -0,0 +1,236 @@ +# 在MacOS下安装与运行EulerLauncher + +## 准备工作 + +### 安装Homebrew + +Homebrew是一款Mac OS平台下的软件包管理工具,拥有安装、卸载、更新、查看、搜索等很多实用的功能。简单的一条指令,就可以实现包管理,而不用你关心各种依赖和文件路径的情况,十分方便快捷。 + +在MacOS桌面下敲击 `command` + `shift` + `u` 组合键,打开`访达`中的`实用工具`,并找到`终端.app`。 + + +并根据网络情况输入以下命令进行安装。 + +可以使用以下命令安装Homebrew: + +``` Shell +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +``` + +由于国内网络原因,可能需要修改源到国内源以进行安装: + +``` Shell +/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" +``` + +### 安装Qemu及wget + +**EulerLauncher**在MacOS上运行依赖于`QEMU`,镜像下载依赖于`wget`,使用`Homebrew`可以非常方便的下载和管理此类软件,使用以下命令进行安装: + +``` Shell +brew install qemu +brew install wget +``` + +### 配置sudo免密码权限 + +**EulerLauncher**在MacOS上运行依赖于`QEMU`,为了使用户的网络体验更加优秀,因此采用了MacOS的[vmnet framework][1]来提供虚拟机的网络能力,当前`vmnet`使用时需要使用管理员权限,因此在使用`QEMU`后端创建带有`vmnet`类型网络设备的虚拟机时,需要启用管理员权限,EulerLauncher在启动时会自动使用`sudo`命令来实现这一过程,因此需要为当前用户配置`sudo`免密码使用权限,如您介意此配置,请停止使用EulerLauncher。 + +1. 在MacOS桌面下敲击 `command` + `shift` + `u` 组合键,打开`访达`中的`实用工具`,并找到`终端.app`。 + + +2. 在终端中输入`sudo visudo`修改sudo配置文件,注意,此步骤有可能要求输入密码,请按指示输入密码。 + +3. 找到并将`%admin ALL=(ALL) ALL`替换为 `%admin ALL=(ALL) NOPASSWD: ALL`。 + + +4. 敲击`ESC`,再输入`:wq`进行保存。 + +## 安装EulerLauncher + +**EulerLauncher**当前支持MacOS Ventura, 支持Apple Silicon芯片版及x86芯片版,前往[EulerLauncher最新版][1]下载MacOS版软件包并解压到期望的位置。 + +解压后的目录包含以下文件: + + + +其中`install`可执行文件为安装文件,用于将**EulerLauncher**所需支持文件安装到指定位置,`EulerLauncher.dmg`为主程序的磁盘映象。 + +1. 本操作需要sudo权限,请先完成[配置sudo免密码权限](#配置sudo免密码权限)操作。 + +2. 安装支持文件:双击`install`可执行文件,等待程序完成执行。 + +3. 配置**EulerLauncher**: + + - 查看`qemu`及`wget`所处位置,`qemu`二进制文件在不同架构下名称不同,请根据自身情况选择正确的名称(Apple Silicon: qemu-system-aarch64; Intel: qemu-system-x86_64): + + ``` Shell + which wget + which qemu-system-{host_arch} + ``` + + 参考输出: + + ```bash + /opt/homebrew/bin/wget + /opt/homebrew/bin/qemu-system-aarch64 + ``` + + 查看完成后,记录路径结果,在接下来的步骤中将会使用到。 + + - 打开`eulerlauncher.conf`并进行配置: + + ``` Shell + sudo vi /Library/Application\ Support/org.openeuler.eulerlauncher/eulerlauncher.conf + ``` + + EulerLauncher的配置如下: + + ```bash + [default] + log_dir = # 日志文件位置(xxx.log) + work_dir = # EulerLauncher工作目录,用于存储虚拟机镜像、虚拟机文件等 + wget_dir = # wget的可执行文件路径,请参考上一步的内容进行配置 + qemu_dir = # qemu的可执行文件路径,请参考上一步的内容进行配置 + debug = True + + [vm] + cpu_num = 1 # 配置虚拟机的CPU个数 + memory = 1024 # 配置虚拟机的内存大小,单位为M,M1用户请勿配置超过2048 + ``` + + 完成编辑后保存退出。 + +4. 安装**EulerLauncher.app**: + + 双击`EulerLauncher.dmg`,在弹出的窗口中用鼠标将`EulerLauncher.app`拖动到`Applications`中,即可完成安装,并可在应用程序中找到`EulerLauncher.app`。 + + + +## 使用EulerLauncher + +1. 在应用程序中找到`EulerLauncher.app`,单击启动程序。 + +2. EulerLauncher需要访问网络,在弹出如下窗口时点击`允许`: + + + +3. EulerLauncher当前仅支持命令行方式进行访问,请打开`终端.app`,使用命令行进行操作。 + +### 镜像操作 + +1. 获取可用镜像列表: + + ```Shell + + eulerlauncher images + + ``` + + **EulerLauncher**镜像有两种位置属性:1)远端镜像 2)本地镜像,只有处于本地且状态为 `Ready` 的镜像可以直接用来创建虚拟机,位于远端的镜像需要下载后才能够使用;你也可以加载已经预先下载好的本地镜像到**EulerLauncher**中,具体操作方法可以参考接下来的操作指导。 + +2. 下载远端镜像。 + + ```Shell + eulerlauncher download-image 23.09 + + Downloading: 23.09, this might take a while, please check image status with "images" command. + ``` + + 镜像下载请求是一个异步请求,具体的下载动作将在后台完成,具体耗时与你的网络情况相关,整体的镜像下载流程包括下载、解压缩、格式转换等相关子流程,在下载过程中可以通过 `image` 命令随时查看下载进展与镜像状态: + + ```Shell + eulerlauncher images + ``` + + 当镜像状态转变为 `Ready` 时,表示镜像下载完成,处于 `Ready` 状态的镜像可被用来创建虚拟机: + + ```Shell + eulerlauncher images + ``` + +3. 加载本地镜像。 + + 用户也可以加载自定义镜像或预先下载到本地的镜像到EulerLauncher中用于创建自定义虚拟机: + + ```Shell + eulerlauncher load-image --path {image_file_path} IMAGE_NAME + ``` + + 当前支持加载的镜像格式有 `xxx.qcow2.xz`,`xxx.qcow2`。 + + 例如: + + ```Shell + eulerlauncher load-image --path /opt/openEuler-23.09-x86_64.qcow2.xz 2309-load + + Loading: 2309-load, this might take a while, please check image status with "images" command. + ``` + + 将位于 `/opt` 目录下的 `openEuler-23.09-x86_64.qcow2.xz` 加载到EulerLauncher系统中,并命名为 `2309-load`,与下载命令一样,加载命令也是一个异步命令,用户需要用镜像列表命令查询镜像状态直到显示为 `Ready`, 但相对于直接下载镜像,加载镜像的速度会快很多: + + ```Shell + eulerlauncher images + + ...... + + eulerlauncher images + + ...... + ``` + +4. 删除镜像: + + 通过下面的命令将镜像从EulerLauncher系统中删除: + + ```Shell + eulerlauncher delete-image 2309-load + + Image: 2309-load has been successfully deleted. + ``` + +### 虚拟机操作 + +1. 获取虚拟机列表: + + ```shell + eulerlauncher list + + +----------+-----------+---------+---------------+ + | Name | Image | State | IP | + +----------+-----------+---------+---------------+ + | test1 | 2309-load | Running | 172.22.57.220 | + +----------+-----------+---------+---------------+ + | test2 | 2309-load | Running | N/A | + +----------+-----------+---------+---------------+ + ``` + + 若虚拟机IP地址显示为 `N/A` ,若这台虚拟机的状态为 `Running` 则表示这台虚拟机为新创建的虚拟机,网络还未配置完成,网络配置过程大概需要若干秒,请稍后重新尝试获取相关虚拟机信息。 + +2. 登录虚拟机: + + 若虚拟机已成功分配到IP地址,可以直接使用 `SSH` 命令进行登录: + + ```Shell + ssh root@{instance_ip} + ``` + + 若使用的是openEuler社区提供的官方镜像,则默认用户为 `root` 默认密码为 `openEuler12#$`。 + +3. 创建虚拟机。 + + ```Shell + eulerlauncher launch --image {image_name} {instance_name} + ``` + + 通过\-\-image指定镜像,同时指定虚拟机名称。 + +4. 删除虚拟机。 + + ```Shell + eulerlauncher delete-instance {instance_name} + ``` + + 根据虚拟机名称删除指定的虚拟机。 + +[1]: https://developer.apple.com/documentation/vmnet diff --git a/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/overall.md b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/overall.md new file mode 100644 index 0000000000000000000000000000000000000000..0317ab0158b57e56f008a0478633a06dcacdcddc --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/overall.md @@ -0,0 +1,18 @@ +# EulerLauncher + +**EulerLauncher**是由openEuler社区技术运营团队及基础设施团队孵化的开发者工具集,通过对主流桌面操作系统中的虚拟化技术(LXD、HyperV、Virtualization framework)等进行有机整合,使用openEuler社区官方发布的虚拟机、容器镜像,为开发者在Windows、MacOS、Linux上提供统一的开发资源(虚拟机、容器)发放和管理体验,提升主流桌面操作系统上openEuler开发环境使用的便利性和稳定性,有效提升开发者体验。 + +## 背景 & 简介 + +主流桌面操作系统上提供相关开发资源(虚拟机、容器等)的便利性和稳定性是影响openEuler开发者体验的重要因素,尤其是对开发资源受限的个人及高校开发者openEuler开发体验影响更为明显。当前常见的虚拟机管理平台有诸多局限性,如VirtualBox需要下载体积庞大的ISO镜像,同时需要进行操作系统安装等相关操作,WSL无法提供真实的openEuler内核,绝大多数虚拟机管理软件目前对Apple Sillicon芯片支持尚不完善且众多软件需要付费等,这些都极大的降低了开发者的工作效率。 + +**EulerLauncher**支持在Windows、MacOS及Linux(规划中)等主流桌面操作系统上提供方便、易用、统一体验的开发者工具集,硬件架构支持x86_64及Aarch64(包含Apple Sillicon系列芯片);并支持各平台对应的虚拟化硬件加速能力,为开发者提供高性能的开发资源。**EulerLauncher**支持使用openEuler社区发布的虚拟机、容器(规划中)镜像、openEuler社区提供的Daily Build镜像以及其他符合要求的自定义镜像,为开发者提供多种选择。 + +## 快速开始 + +**EulerLauncher** MacOS用户请参考[MacOS用户指导文档][1] + +**EulerLauncher** Windows用户请参考[Windows用户指导文档][2] + +[1]: ./mac-user-manual.md +[2]: ./win-user-manual.md diff --git a/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/win-user-manual.md b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/win-user-manual.md new file mode 100644 index 0000000000000000000000000000000000000000..b6b3bde718f80b3e62d2a7a6cdb2ba1ee5564916 --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/Virtualization/EulerLauncher/win-user-manual.md @@ -0,0 +1,159 @@ +# 在Windows下安装与运行EulerLauncher + +**EulerLauncher**当前支持Windows11/10,前往[EulerLauncher最新版下载][1]下载Windows版软件包并解压到期望的位置。 +右键点击 `config-env.bat` 并选择**以管理员身份运行**,该脚本将进行环境变量相关的配置,将当前目录添加到系统环境变量 `PATH`中,如果使用者掌握如何配置环境变量,或配置脚本出现问题,也可以进行手动配置,将当前脚本所在目录及 `qemu-img` 子目录添加至系统环境变量 `PATH` 中。 + +**EulerLauncher**在Windows上运行需要对接 `Hyper-V` 虚拟化后端,`Hyper-V` 是 Microsoft 的硬件虚拟化产品,可以为Windows上的虚拟机提供更为出色的性能。在运行**EulerLauncher**前,请先检查你的系统是否开启了 `Hyper-V`,具体检查及开启方法请参考[Hyper-V开启指导][2]或其他网络资源。 + +**EulerLauncher**解压后包含以下几个部分: + +- eulerlauncherd.exe:EulerLauncher的主进程,是运行在后台的守护进程,负责与各类虚拟化后端交互,管理虚拟机、容器以及镜像的生命周期,eulerlauncherd.exe是运行在后台的守护进程。 +- eulerlauncher.exe:EulerLauncher的CLI客户端,用户通过该客户端与eulerlauncherd守护进程交互,对虚拟机、镜像等进行相关操作。 +- eulerlauncher.conf:EulerLauncher配置文件,需与eulerlauncherd.exe放置于同一目录下,参考下面配置进行相应配置: + +```Conf +[default] +# 配置日志文件的存储目录 +log_dir = D:\eulerlauncher-workdir\logs +# 配置日志等级是否开启Debug +debug = True +# 配置EulerLauncher的工作目录 +work_dir = D:\eulerlauncher-workdir +# 配置EulerLauncher的镜像目录,镜像目录为对工作目录的相对目录 +image_dir = images +# 配置EulerLauncher的虚拟机文件目录,虚拟机文件目录为对工作目录的相对目录 +instance_dir = instances +``` + +配置完成后请右键点击eulerlauncherd.exe,选择以管理员身份运行,点击后omnivird.exe将以守护进程的形式在后台运行。 + +打开 `PowerShell` 或 `Terminal` ,准备进行对应的操作。 + +## Windows下退出eulerlauncherd后台进程 + +当eulerlauncherd.exe运行后,会在操作系统右下角托盘区域生成eulerlauncherd托盘图标,鼠标右键点击托盘图标,并选择 `Exit eulerlauncher` 即可退出eulerlauncherd后台进程。 + +## 镜像操作 + +1. 获取可用镜像列表。 + + ```PowerShell + eulerlauncher.exe images + + +-----------+----------+--------------+ + | Images | Location | Status | + +-----------+----------+--------------+ + | 22.03-LTS | Remote | Downloadable | + | 21.09 | Remote | Downloadable | + | 2203-load | Local | Ready | + +-----------+----------+--------------+ + ``` + + **EulerLauncher**镜像有两种位置属性:1)远端镜像 2)本地镜像,只有处于本地且状态为 `Ready` 的镜像可以直接用来创建虚拟机,位于远端的镜像需要下载后才能够使用;你也可以加载已经预先下载好的本地镜像到**EulerLauncher**中,具体操作方法可以参考接下来的操作指导。 + +2. 下载远端镜像。 + + ```PowerShell + eulerlauncher.exe download-image 23.09 + + Downloading: 23.09, this might take a while, please check image status with "images" command. + ``` + + 镜像下载请求是一个异步请求,具体的下载动作将在后台完成,具体耗时与你的网络情况相关,整体的镜像下载流程包括下载、解压缩、格式转换等相关子流程,在下载过程中可以通过 `image` 命令随时查看下载进展与镜像状态: + + ```PowerShell + eulerlauncher.exe images + ``` + + 当镜像状态转变为 `Ready` 时,表示镜像下载完成,处于 `Ready` 状态的镜像可被用来创建虚拟机: + + ```PowerShell + eulerlauncher.exe images + ``` + +3. 加载本地镜像。 + + 用户也可以加载自定义镜像或预先下载到本地的镜像到EulerLauncher中用于创建自定义虚拟机: + + ```PowerShell + eulerlauncher.exe load-image --path {image_file_path} IMAGE_NAME + ``` + + 当前支持加载的镜像格式有 `xxx.qcow2.xz`,`xxx.qcow2`。 + + 例如: + + ```PowerShell + eulerlauncher.exe load-image --path D:\openEuler-23.09-x86_64.qcow2.xz 2309-load + + Loading: 2309-load, this might take a while, please check image status with "images" command. + ``` + + 将位于 `D:\` 目录下的 `openEuler-23.09-x86_64.qcow2.xz` 加载到EulerLauncher系统中,并命名为 `2309-load`,与下载命令一样,加载命令也是一个异步命令,用户需要用镜像列表命令查询镜像状态直到显示为 `Ready`, 但相对于直接下载镜像,加载镜像的速度会快很多: + + ```PowerShell + eulerlauncher.exe images + + ...... + + eulerlauncher images + + ...... + ``` + +4. 删除镜像。 + +通过下面的命令将镜像从EulerLauncher系统中删除: + +```PowerShell +eulerlauncher.exe delete-image 2309-load + +Image: 2309-load has been successfully deleted. +``` + +## 虚拟机操作 + +1. 获取虚拟机列表。 + + ```Powershell + eulerlauncher.exe list + + +----------+-----------+---------+---------------+ + | Name | Image | State | IP | + +----------+-----------+---------+---------------+ + | test1 | 2309-load | Running | 172.22.57.220 | + +----------+-----------+---------+---------------+ + | test2 | 2309-load | Running | N/A | + +----------+-----------+---------+---------------+ + ``` + + 若虚拟机IP地址显示为 `N/A` ,若这台虚拟机的状态为 `Running` 则表示这台虚拟机为新创建的虚拟机,网络还未配置完成,网络配置过程大概需要若干秒,请稍后重新尝试获取相关虚拟机信息。 + +2. 登录虚拟机。 + + 若虚拟机已成功分配到IP地址,可以直接使用 `SSH` 命令进行登录: + + ```PowerShell + ssh root@{instance_ip} + ``` + + 若使用的是openEuler社区提供的官方镜像,则默认用户为 `root` 默认密码为 `openEuler12#$`。 + +3. 创建虚拟机。 + + ```PowerShell + eulerlauncher.exe launch --image {image_name} {instance_name} + ``` + + 通过\-\-image指定镜像,同时指定虚拟机名称。 + +4. 删除虚拟机。 + + ```PowerShell + eulerlauncher.exe delete-instance {instance_name} + ``` + + 根据虚拟机名称删除指定的虚拟机。 + +[1]: https://gitee.com/openeuler/eulerlauncher/releases +[2]: https://learn.microsoft.com/zh-cn/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v diff --git a/docs/en/25.03/Tools/CommunityTools/_menu.md b/docs/en/25.03/Tools/CommunityTools/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..bee6fbd3be3730710073cf4078cfe637c4d06de7 --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/_menu.md @@ -0,0 +1,25 @@ +--- +label: '社区工具' +children: + - label: '镜像构建' + children: + - reference: './ImageCustom/isocut/_menu.md' + - reference: './ImageCustom/imageTailor/_menu.md' + - label: '镜像构建' + children: + - reference: '../../Server/Development/GCC/_menu.md' + - label: '性能优化' + children: + - reference: '../../Server/Performance/SystemOptimization/A-Tune/_menu.md' + - reference: '../../Server/Performance/TuningFramework/oeAware/_menu.md' + - label: '迁移' + children: + - reference: './Migration/migration-tools/_menu.md' + - label: '虚拟化' + children: + - reference: './Virtualization/EulerLauncher/_menu.md' + - label: 'epkg软件包' + children: + - reference: './epkg/epkgUse/_menu.md' + - reference: './epkg/autopkg/_menu.md' +--- diff --git a/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/_menu.md b/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..336368f987f605fd85f235caab6e65da42624dfc --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/_menu.md @@ -0,0 +1,8 @@ +--- +label: 'autopkg用户指南' +ismanual: 'Y' +description: '高效地将软件源代码打包成适合 openEuler 系统使用的软件包' +children: + - label: 'autopkg用户指南' + href: './autopkg.md' +--- diff --git a/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/autopkg.md b/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/autopkg.md new file mode 100644 index 0000000000000000000000000000000000000000..e4e2895207db56dfcd4880599bec589a52b33850 --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/autopkg.md @@ -0,0 +1,166 @@ +# 概述 + +本软件服务于`openEuler`社区,将`github`等公共平台上的开源代码仓批量加包到`openEuler`平台上,实现软件包依赖自动检测并编译生成二进制文件,替代手工编写与维护,支持`cmake/autotools/meson/maven/python`等多种构建方式,显著提升加包端到端成功率。 + +# 安装与卸载 + +## 1. 安装 + +从源码仓中下载源码。 + +```bash +git clone https://gitee.com/qiu-tangke/autopkg.git -b ${branch} +``` + +切到代码仓目录下,使用`pip`安装软件,仅支持openeuler-22.03-lts及更高版本的openeuler系统(其他版本需自行安装python3.8以上的环境) + +```bash +pip install dist/autopkg-***-py3-none-any.whl +``` + +## 2. 卸载 + +```bash +pip uninstall autopkg +``` + +# 快速入门 + +## 1. 环境准备 + +使用该软件需要在宿主机上运行,并且需要能启动docker容器。 +预制`openEuler`系统的`docker`镜像,方法如下: + +### 方法1 直接下载源码中心仓的autopkg环境镜像 + +```bash +arch=$(uname -m) +if [ "$arch" == "aarch64" ]; then + wget https://cache-openeuler.obs.cn-north-4.myhuaweicloud.com/52f2b17e15ceeefecf5646d7711df7e94691ea1adb11884b926532ae52ab3c22/autopkg-latest_aarch64.tar.xz + docker load < autopkg-latest_aarch64.tar.xz +elif [ "$arch" == "x86_64" ]; then + wget https://cache-openeuler.obs.cn-north-4.myhuaweicloud.com/710a5f18188efc70bfa0119d0b35dcbb62cab911c9eb77b86dc6aebdbbfc69de/autopkg-latest_x86-64.tar.xz + docker load < autopkg-latest_x86-64.tar.xz +else + echo "Error: The system architecture is neither aarch64 nor x86_64, it is $arch." +fi +``` + +### 方法2 逐个使用命令生成镜像(方法1不成功时选择方法2) + +```bash +arch=$(uname -m) +wget "https://repo.huaweicloud.com/openeuler/openEuler-23.03/docker_img/${arch}/openEuler-docker.${arch}.tar.xz" +docker load < "openEuler-docker.${arch}.tar.xz" +docker run -dti --privileged --name=autopkg_working --network=host openEuler-23.03:latest +docker exec -ti ${container_id} bash # 以下命令在容器中执行 +yum install -y git make gcc cmake python3-pip ruby ruby-devel rubygems-devel npm maven automake perl wget curl meson +cat >> /root/phase.sh << EOF +#/usr/bin/env bash + +prep +build +install +EOF +exit # 退出容器 +docker commit ${container_id} > autopkg:latest # 保存容器操作 +docker tag ${new_image_id} autopkg:latest # 操作镜像的名称和标签 +``` + +## 2. 命令行 + +```bash +autopkg --help +-g,--git-url: 输入git仓库地址,形如'https://***.git' +-t,--tar-url: 输入tar包地址 +-d,--dir: 输入本地仓库路径 +-n,--name: 输入包名,仅用于接口请求信息时的输入 +-v,--version: 输入版本,输入name时配合的参数 +-l,--language: 输入语言,输入name时配合的参数 +-o,--output: 设置输出文件的路径 +-b,--build: 是否需要设置日志模式为debug +-c,--config: 设置可直接使用的配置信息 +``` + +## 3. 常用命令 + +### A. 输入本地仓库路径的形式 + +```bash +autopkg -d ${package_dir} -o ${output_path} +``` + +![](./images/dir_test.PNG) + +### B. 输入源码包地址的形式 + +```bash +autopkg -t ${tar_url} -o ${output_path} +``` + +![](./images/tar_url_test.PNG) + +### C. 输入包名且不编译的形式 + +```bash +autopkg -n ${name} -v ${version} -l ${language} -o ${output_path} +``` + +![](./images/name_test.PNG) + +# 输出文件说明 + +软件包编译完成后会生成`package.yaml`,`phase.sh`和`{package_name}.epkg`。不编译的情况下只生成`package.yaml`和`phase.sh`文件,输出路径为--output参数指定的路径,默认为`/tmp/autopkg/output` + +## 1. package.yaml (jekyll为例,ruby编译) + +记录软件包的基本信息参数 + +```yaml +meta: + summary: No detailed summary available + description: | + # [Jekyll](https://jekyllrb.com/) +name: jekyll +version: 4.3.3 +homepage: https://localhost:8080/jekyll-0.0.1.tar.gz +license: MIT +source: + '0': https://localhost:8080/jekyll-0.0.1.tar.gz # 输入本地仓库时,url会采用本地服务模拟的url +release: 0 +buildRequires: +- ruby +- ruby-devel +- rubygems-devel +``` + +## 2. phase.sh (jekyll为例,ruby编译) + +软件包的构建脚本 + +```bash +#!/usr/bin/env bash + +prep() { + cd /root/workspace +} + +build() { + if [ -f *.gemspec ]; then + gem build *.gemspec + fi + mkdir -p usr/ + gem install -V --local --build-root usr --force --document=ri,rdoc *.gem +} + +install() { + rm -rf /opt/buildroot + mkdir /opt/buildroot + cp -r usr/ /opt/buildroot +} +``` + +## 3. ***.epkg + +软件包的安装包 +![](./images/local_epkg.PNG) diff --git a/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/images/dir_test.PNG b/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/images/dir_test.PNG new file mode 100644 index 0000000000000000000000000000000000000000..3d223e1c3f7aca150b724746b43a931f77e6c6d9 Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/images/dir_test.PNG differ diff --git a/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/images/local_epkg.PNG b/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/images/local_epkg.PNG new file mode 100644 index 0000000000000000000000000000000000000000..7f5ecdf2948a661ab2d513f008ae72758706fe28 Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/images/local_epkg.PNG differ diff --git a/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/images/name_test.PNG b/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/images/name_test.PNG new file mode 100644 index 0000000000000000000000000000000000000000..95e5cbfc916919e0996172cd4c55433c55eed4c2 Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/images/name_test.PNG differ diff --git a/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/images/tar_url_test.PNG b/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/images/tar_url_test.PNG new file mode 100644 index 0000000000000000000000000000000000000000..80a49875c4eacbe74da42a859d7d9df251533fb8 Binary files /dev/null and b/docs/en/25.03/Tools/CommunityTools/epkg/autopkg/images/tar_url_test.PNG differ diff --git a/docs/en/25.03/Tools/CommunityTools/epkg/epkgUse/_menu.md b/docs/en/25.03/Tools/CommunityTools/epkg/epkgUse/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..96847184543af0a7fa5793545cb767eeb0fbd36c --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/epkg/epkgUse/_menu.md @@ -0,0 +1,8 @@ +--- +label: 'epkg包管理器使用指南' +ismanual: 'Y' +description: '使用 epkg 包管理器' +children: + - label: 'epkg包管理器使用指南' + href: './epkg-package-manager-usage-guide.md' +--- diff --git a/docs/en/25.03/Tools/CommunityTools/epkg/epkgUse/epkg-package-manager-usage-guide.md b/docs/en/25.03/Tools/CommunityTools/epkg/epkgUse/epkg-package-manager-usage-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..b838f10e3fc6fe3db98fddc467fcbcef6ddd8ed8 --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/epkg/epkgUse/epkg-package-manager-usage-guide.md @@ -0,0 +1,267 @@ +# epkg 使用指南 + +## 介绍 + +本文介绍EPKG包管理器工作环境如何初始化,以及基本功能如何使用。本文涉及操作结果示例均以非root用户为例。 +注意:目前epkg的软件包只适配了aarch64架构,后续会不断扩展其他架构 + +## 快速上手 + +下面的实例介绍了安装不同软件包版本的方式 + +```bash +# curl 方式安装epkg +# 安装时可选user/global安装模式,user模式仅当前安装用户可用,global模式全局用户可用 +# 仅root用户可使用global安装模式 +wget https://repo.oepkgs.net/openeuler/epkg/rootfs/epkg-installer.sh +sh epkg-installer.sh + +# 卸载epkg +wget https://repo.oepkgs.net/openeuler/epkg/rootfs/epkg-uninstaller.sh +sh epkg-uninstaller.sh + +# 初始化epkg +epkg init +bash // 重新执行.bashrc, 获得新的PATH + +# 创建环境1 +epkg env create t1 +epkg install tree +tree --version +which tree + +# 查看repo +[root@vm-4p64g ~]# epkg repo list +------------------------------------------------------------------------------------------------------------------------------------------------------ +channel | repo | url +------------------------------------------------------------------------------------------------------------------------------------------------------ +openEuler-22.03-LTS-SP3 | OS | https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-22.03-LTS-SP3/OS/aarch64/ +openEuler-24.09 | everything | https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64/ +openEuler-24.09 | OS | https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/OS/aarch64/ +------------------------------------------------------------------------------------------------------------------------------------------------------ + +# 创建环境2, 指定repo +epkg env create t2 --repo openEuler-22.03-LTS-SP3 +epkg install tree +tree --version +which tree + +# 切换回环境1 +epkg env activate t1 +``` + +## EPKG包管理器使用说明 + +```bash +Usage: + epkg install PACKAGE + epkg install [--env ENV] PACKAGE (开发中...) + epkg remove [--env ENV] PACKAGE (开发中...) + epkg upgrade [PACKAGE] (开发中...) + + epkg search PACKAGE (开发中...) + epkg list (开发中...) + + epkg env list + epkg env create|remove ENV + epkg env activate ENV + epkg env deactivate ENV + epkg env register|unregister ENV + epkg env history ENV (开发中...) + epkg env rollback ENV (开发中...) +``` + +软件包安装: + +```bash + epkg env create $env // 创建环境 + epkg install $package // 在环境中安装软件包 + epkg env create $env2 --repo $repo // 创建环境2,指定repo + epkg install $package // 在环境2中安装软件包 +``` + +软件包构建: + +```bash + epkg build ${yaml_path}/$pkg_name.yaml +``` + +### 安装软件 + +功能描述: + 在当前所在环境安装软件(建议操作前确认当前所在环境) + +命令: + epkg install ${package_name} + +返回示例: + +```bash +[root@2d785c36ee2e /]# epkg env activate t1 +Add common to path +Add t1 to path +Environment 't1' activated. +Environment 't1' activated. +[root@2d785c36ee2e /]# epkg install tree +EPKG_ENV_NAME: t1 +Caching repodata for: "OS" +Cache for "OS" already exists. Skipping... +Caching repodata for: "OS" +Cache for "OS" already exists. Skipping... +Caching repodata for: "everything" +Cache for "everything" already exists. Skipping... +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/FF/FFCRTKRFGFQ6S2YVLOSUF6PHSMRP7A2N__ncurses-libs__6.4__8.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/D5/D5BOEFTRBNV3E4EXBVXDSRNTIGLGWVB7__glibc-all-langpacks__2.38__34.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/VX/VX6SUOPGEVDWF6E5M2XBV53VS7IXSFM5__openEuler-repos__1.0__3.3.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/LO/LO6RYZTBB2Q7ZLG6SWSICKGTEHUTBWUA__libselinux__3.5__3.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/EP/EPIEEK2P5IUPO4PIOJ2BXM3QPEFTZUCT__basesystem__12__3.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/2G/2GYDDYVWYYIDGOLGTVUACSBHYVRCRJH3__setup__2.14.5__2.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/HC/HCOKXTWQQUPCFPNI7DMDC6FGSDOWNACC__glibc__2.38__34.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/OJ/OJQAHJTY3Y7MZAXETYMTYRYSFRVVLPDC__glibc-common__2.38__34.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/FJ/FJXG3K2TSUYXNU4SES2K3YSTA3AHHUMB__tree__2.1.1__1.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/KD/KDYRBN74LHKSZISTLMYOMTTFVLV4GPYX__readline__8.2__2.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/MN/MNJPSSBS4OZJL5EB6YKVFLMV4TGVBUBA__tzdata__2024a__2.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/S4/S4FBO2SOMG3GKP5OMDWP4XN5V4FY7OY5__bash__5.2.21__1.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/EJ/EJGRNRY5I6XIDBWL7H5BNYJKJLKANVF6__libsepol__3.5__3.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/TZ/TZRQZRU2PNXQXHRE32VCADWGLQG6UL36__bc__1.07.1__12.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/WY/WYMBYMCARHXD62ZNUMN3GQ34DIWMIQ4P__filesystem__3.16__6.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/KQ/KQ2UE3U5VFVAQORZS4ZTYCUM4QNHBYZ7__openEuler-release__24.09__55.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/HD/HDTOK5OTTFFKSTZBBH6AIAGV4BTLC7VT__openEuler-gpg-keys__1.0__3.3.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/EB/EBLBURHOKKIUEEFHZHMS2WYF5OOKB4L3__pcre2__10.42__8.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/YW/YW5WTOMKY2E5DLYYMTIDIWY3XIGHNILT__info__7.0.3__3.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start download https://repo.oepkgs.net/openeuler/epkg/channel/openEuler-24.09/everything/aarch64//store/E4/E4KCO6VAAQV5AJGNPW4HIXDHFXMR4EJV__ncurses-base__6.4__8.oe2409.epkg +############################################################################################################################################################################################################### 100.0% +start install FFCRTKRFGFQ6S2YVLOSUF6PHSMRP7A2N__ncurses-libs__6.4__8.oe2409 +start install D5BOEFTRBNV3E4EXBVXDSRNTIGLGWVB7__glibc-all-langpacks__2.38__34.oe2409 +start install VX6SUOPGEVDWF6E5M2XBV53VS7IXSFM5__openEuler-repos__1.0__3.3.oe2409 +start install LO6RYZTBB2Q7ZLG6SWSICKGTEHUTBWUA__libselinux__3.5__3.oe2409 +start install EPIEEK2P5IUPO4PIOJ2BXM3QPEFTZUCT__basesystem__12__3.oe2409 +start install 2GYDDYVWYYIDGOLGTVUACSBHYVRCRJH3__setup__2.14.5__2.oe2409 +start install HCOKXTWQQUPCFPNI7DMDC6FGSDOWNACC__glibc__2.38__34.oe2409 +start install OJQAHJTY3Y7MZAXETYMTYRYSFRVVLPDC__glibc-common__2.38__34.oe2409 +start install FJXG3K2TSUYXNU4SES2K3YSTA3AHHUMB__tree__2.1.1__1.oe2409 +start install KDYRBN74LHKSZISTLMYOMTTFVLV4GPYX__readline__8.2__2.oe2409 +start install MNJPSSBS4OZJL5EB6YKVFLMV4TGVBUBA__tzdata__2024a__2.oe2409 +start install S4FBO2SOMG3GKP5OMDWP4XN5V4FY7OY5__bash__5.2.21__1.oe2409 +start install EJGRNRY5I6XIDBWL7H5BNYJKJLKANVF6__libsepol__3.5__3.oe2409 +start install TZRQZRU2PNXQXHRE32VCADWGLQG6UL36__bc__1.07.1__12.oe2409 +start install WYMBYMCARHXD62ZNUMN3GQ34DIWMIQ4P__filesystem__3.16__6.oe2409 +start install KQ2UE3U5VFVAQORZS4ZTYCUM4QNHBYZ7__openEuler-release__24.09__55.oe2409 +start install HDTOK5OTTFFKSTZBBH6AIAGV4BTLC7VT__openEuler-gpg-keys__1.0__3.3.oe2409 +start install EBLBURHOKKIUEEFHZHMS2WYF5OOKB4L3__pcre2__10.42__8.oe2409 +start install YW5WTOMKY2E5DLYYMTIDIWY3XIGHNILT__info__7.0.3__3.oe2409 +start install E4KCO6VAAQV5AJGNPW4HIXDHFXMR4EJV__ncurses-base__6.4__8.oe2409 +``` + +### 列出环境列表 + +功能描述: + 列出当前epkg所有环境($EPKG_ENVS_ROOT目录下),及当前处于哪个环境 + +命令: + epkg env list + +返回示例: + [small_leek@19e784a5bc38 bin]# epkg env list + Available environments(sort by time): + w1 + main + common + You are in [main] now + +### 创建环境 + +功能描述: + 创建新环境(创建成功后,默认激活新环境,即切换进新环境;但是不全局注册) + +命令: + epkg env create ${env_name} + +返回示例: + [small_leek@b0e608264355 bin]# epkg env create work1 + YUM --installroot directory structure created successfully in: /root/.epkg/envs/work1/profile-1 + Environment 'work1' added to PATH. + Environment 'work1' activated. + Environment 'work1' created. + +### 激活环境 + +功能描述: + 激活指定环境,刷新EPKG_ENV_NAME和RPMDB_DIR(用于安装软件至指定环境时,指向--dbpath),刷新PATH,包含指定环境及common环境,并将指定环境设为第一优先级 + +命令: + epkg env activate ${env_name} + +返回示例: + [small_leek@9d991d463f89 bin]# epkg env activate main + Environment 'main' activated + +### 取消激活环境 + +功能描述: + 取消激活指定环境,刷新EPKG_ENV_NAME和RPMDB_DIR,刷新PATH,默认指向main环境 + +命令: + epkg env deactivate ${env_name} + +返回示例: + [small_leek@398ec57ce780 bin]# epkg env deactivate w1 + Environment 'w1' deactivated. + +### 注册环境 + +功能描述: + 注册指定环境,持久化刷新PATH,包含epkg所有已注册环境,并将指定环境设为第一优先级 + +命令: + epkg env register ${env_name} + +返回示例: + [small_leek@5042ae77dd75 bin]# epkg env register lkp + EPKG_ACTIVE_ENV: + Environment 'lkp' has been registered to PATH. + +### 取消注册环境 + +功能描述: + 去注册指定环境,持久化刷新PATH,包含除指定环境外的epkg所有已注册环境 + +命令: + epkg env unregister ${env_name} + +返回示例: + [small_leek@69393675945d /]# epkg env unregister w4 + EPKG_ACTIVE_ENV: + Environment 'w4' has been unregistered from PATH. + +### 编译epkg软件包 + +功能描述: + 根据autopkg提供的yaml编译epkg软件包 + +命令: + epkg build ${yaml_path}/$pkg_name.yaml + +返回示例: + [small_leek@69393675945d /]# epkg build /root/epkg/build/test/tree/package.yaml + pkg_hash: fbfqtsnza9ez1zk0cy23vyh07xfzsydh, dir: /root/.cache/epkg/build-workspace/result + Compress success: /root/.cache/epkg/build-workspace/epkg/fbfqtsnza9ez1zk0cy23vyh07xfzsydh__tree__2.1.1__0.oe2409.epkg diff --git a/docs/en/25.03/Tools/CommunityTools/index.md b/docs/en/25.03/Tools/CommunityTools/index.md new file mode 100644 index 0000000000000000000000000000000000000000..375695cbce5e4a4fe4b9c4d41d6334b320d87664 --- /dev/null +++ b/docs/en/25.03/Tools/CommunityTools/index.md @@ -0,0 +1,4 @@ +--- +title: 社区工具 +overview: true +--- \ No newline at end of file diff --git a/docs/en/25.03/Tools/DevOps/CodeManage/patch-tracking/_menu.md b/docs/en/25.03/Tools/DevOps/CodeManage/patch-tracking/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..92930ec4631195c49c21e496895d269895c7f91b --- /dev/null +++ b/docs/en/25.03/Tools/DevOps/CodeManage/patch-tracking/_menu.md @@ -0,0 +1,10 @@ +--- +label: 'patch-tracking' +ismanual: 'Y' +description: '对软件包进行补丁管理' +children: + - label: 'patch-tracking' + href: './patch-tracking.md' + - label: '常见问题与解决方法' + href: './faqs.md' +--- diff --git a/docs/en/25.03/Tools/DevOps/CodeManage/patch-tracking/faqs.md b/docs/en/25.03/Tools/DevOps/CodeManage/patch-tracking/faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..19593b6103c810b8e38a64e90f3eacded76b5b47 --- /dev/null +++ b/docs/en/25.03/Tools/DevOps/CodeManage/patch-tracking/faqs.md @@ -0,0 +1,19 @@ +# 常见问题与解决方法 + +## **问题1:访问 api.github.com Connection refused 异常** + +## 问题描述 + +patch-tracking 运行过程中,可能会出现如下报错: + +```sh + 9月 21 22:00:10 localhost.localdomain patch-tracking[36358]: 2020-09-21 22:00:10,812 - patch_tracking.util.github_api - WARNING - HTTPSConnectionPool(host='api.github.com', port=443): Max retries exceeded with url: /user (Caused by NewConnectionError(': Failed to establish a new connection: [Errno 111] Connection refused')) +``` + +## 原因分析 + +以上问题是 patch-tracking 与 GitHub API 服务之间网络访问不稳定导致。 + +## 解决方法 + +请确保在与 GitHub API 服务之间网络稳定的环境中(如使用[华为云ECS弹性云服务器](https://console.huaweicloud.com/))运行 patch-tracking。 diff --git a/docs/en/25.03/Tools/DevOps/CodeManage/patch-tracking/images/Maintainer.jpg b/docs/en/25.03/Tools/DevOps/CodeManage/patch-tracking/images/Maintainer.jpg new file mode 100644 index 0000000000000000000000000000000000000000..da0d5f1b5d928eca3a0d63795f59c55331136065 Binary files /dev/null and b/docs/en/25.03/Tools/DevOps/CodeManage/patch-tracking/images/Maintainer.jpg differ diff --git a/docs/en/25.03/Tools/DevOps/CodeManage/patch-tracking/images/PatchTracking.jpg b/docs/en/25.03/Tools/DevOps/CodeManage/patch-tracking/images/PatchTracking.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e12afd6227c18c333f289b9aa71abf608d8058a0 Binary files /dev/null and b/docs/en/25.03/Tools/DevOps/CodeManage/patch-tracking/images/PatchTracking.jpg differ diff --git a/docs/en/25.03/Tools/DevOps/CodeManage/patch-tracking/patch-tracking.md b/docs/en/25.03/Tools/DevOps/CodeManage/patch-tracking/patch-tracking.md new file mode 100644 index 0000000000000000000000000000000000000000..0c0eea8cf037434002e9f499e20519222ab544ad --- /dev/null +++ b/docs/en/25.03/Tools/DevOps/CodeManage/patch-tracking/patch-tracking.md @@ -0,0 +1,291 @@ +# patch-tracking + +## 简介 + +在 openEuler 发行版开发过程中,需要及时更新上游社区各个软件包的最新代码,修改功能 bug 及安全问题,确保发布的 openEuler 发行版尽可能避免缺陷和漏洞。 + +本工具主要功能是对软件包进行补丁管理,主动监控上游社区提交,自动生成补丁,并自动提交 issue 给对应的 maintainer,同时自动验证补丁基础功能,减少验证工作量支持 maintainer 快速决策。 + +## 架构 + +### C/S架构 + +patch-tracking采用 C/S 架构。 + +服务端(patch-tracking) :负责执行补丁跟踪任务,包括:维护跟踪项、识别上游仓库分支代码变更并形成补丁文件、向 Gitee 提交 issue 及 PR。同时 patch-tracking 提供 RESTful 接口,用于对跟踪项进行增删改查操作。 + +客户端:即命令行工具(patch-tracking-cli),通过调用 patch-tracking 的 RESTful 接口,实现对跟踪项的增删改查操作。 + +### 核心流程 + +a. 补丁跟踪服务流程 + +主要步骤: + +1. 通过命令行工具添加跟踪项。 +2. 自动从跟踪项配置的上游仓库(例如GitHub)获取补丁文件。 +3. 创建临时分支,将获取到的补丁文件提交到临时分支。 +4. 自动提交 issue 到对应仓库,并生成关联 issue 的 PR。 + +![PatchTracking](./images/PatchTracking.jpg) + +b. Maintainer对提交的补丁处理流程 + +主要步骤: + +1. Maintainer 分析 PR。 +2. 执行 CI,执行成功后判断是否合入 PR。 + +![Maintainer](./images/Maintainer.jpg) + +### 数据结构 + +* Tracking表 + +| 序号 | 名称 | 说明 | 类型 | 键 | 允许空 | +|:----:| ----| ----| ----| ----| ----| +| 1 | id | 自增补丁跟踪项序号 | int | - | NO | +| 2 | version_control | 上游SCM的版本控制系统类型 | String | - | NO | +| 3 | scm_repo | 上游SCM仓库地址 | String | - | NO | +| 4 | scm_branch | 上游SCM跟踪分支 | String | - | NO | +| 5 | scm_commit | 上游代码最新处理过的Commit ID | String | - | YES | +| 6 | repo | 包源码在Gitee的仓库地址 | String | Primary | NO | +| 7 | branch | 包源码在Gitee的仓库分支 | String | Primary | NO | +| 8 | enabled | 是否启动跟踪 | Boolean | -| NO | + +* Issue表 + +| 序号 | 名称 | 说明 | 类型 | 键 | 允许空 | +|:----:| ----| ----| ----| ----| ----| +| 1 | issue | issue编号 | String | Primary | NO | +| 2 | repo | 包源码在Gitee的仓库地址 | String | - | NO | +| 3 | branch | 包源码在Gitee的仓库分支 | String | - | NO | + +## 工具部署 + +### 软件下载 + +Repo 源地址:[https://repo.openeuler.org/](https://repo.openeuler.org/) + +rpm 包获取地址:[https://repo.openeuler.org/](https://repo.openeuler.org/),依次选择正确的版本号、everything、正确的架构、Packages,找到需要的rpm包,点击即可下载。 + +### 安装工具 + +方法1:从repo源安装 + +1. 使用 dnf 挂载 repo源(具体方法参考[应用开发指南](../../../../Server/Development/ApplicationDev/preparations-for-development-environment.md))。 +2. 执行以下命令安装`patch-tracking`及其依赖。 + +```shell +# dnf install patch-tracking +``` + +方法2:直接使用rpm安装 + +1. 首先安装相关依赖。 + + ```shell + # dnf install python3-uWSGI python3-flask python3-Flask-SQLAlchemy python3-Flask-APScheduler python3-Flask-HTTPAuth python3-requests python3-pandas + ``` + +2. 安装patch-tracking包。 + + ```shell + # rpm -ivh patch-tracking-xxx.rpm + ``` + +### 生成证书 + +执行如下命令生成证书。 + +```shell +# openssl req -x509 -days 3650 -subj "/CN=self-signed" -nodes -newkey rsa:4096 -keyout self-signed.key -out self-signed.crt +``` + +将生成的 `self-signed.key` 和 `self-signed.crt` 文件拷贝到 /etc/patch-tracking 目录。 + +### 配置参数 + +在配置文件中对相应参数进行配置,配置文件路径为 `/etc/patch-tracking/settings.conf`。 + +1. 配置服务监听地址。 + + ```text + LISTEN = "127.0.0.1:5001" + ``` + +2. GitHub Token, 用于访问托管在 GitHub 上游开源软件仓的仓库信息 , 生成 GitHub Token 的方法参考 [Creating a personal access token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) 。 + + ```text + GITHUB_ACCESS_TOKEN = "" + ``` + +3. 对于托管在gitee上的需要跟踪的仓库,配置一个有该仓库权限的gitee的token,用于提交patch文件,提交issue,提交PR等操作。 + + ```text + GITEE_ACCESS_TOKEN = "" + ``` + +4. 定时扫描数据库中是否有新增或修改的跟踪项,对扫描到的跟踪项执行获取上游补丁任务,在这里配置扫描的时间间隔,数字单位是秒。 + + ```text + SCAN_DB_INTERVAL = 3600 + ``` + +5. 命令行工具运行过程中,POST接口需要填写进行认证的用户名和口令哈希值。 + + ```text + USER = "admin" + PASSWORD = "" + ``` + + > `USER`默认值为`admin`。 + + 执行如下指令,获取口令的哈希值,其中Test@123为设置的口令。 + + ```shell + # generate_password Test@123 + ``` + + > `口令值`需要满足如下复杂度要求: + > + > * 长度大于等于6个字符 + > * 必须包含大写字母、小写字母、数字、特殊字符(~!@#%^*-_=+) + + 将口令的哈希值复制到`PASSWORD = ""`引号中。 + +### 启动补丁跟踪服务 + +* 使用systemd方式。 + + ```shell + # systemctl start patch-tracking + ``` + +* 直接执行可执行程序。 + + ```shell + # /usr/bin/patch-tracking + ``` + +## 工具使用 + +### 添加跟踪项 + +将需要跟踪的软件仓库和分支与其上游开源软件仓库与分支关联起来,可以通过以下方式实现。 + +* 命令行直接添加 + + 参数含义: + > --user :POST接口需要进行认证的用户名,同settings.conf中的USER参数 + > --password :POST接口需要进行认证的口令,为settings.conf中的PASSWORD哈希值对应的实际的口令字符串 + > --server :启动Patch Tracking服务的URL,例如:127.0.0.1:5001 + > --version_control :上游仓库版本的控制工具,只支持github + > --repo: 需要进行跟踪的仓库名称,格式:组织/仓库 + > --branch :需要进行跟踪的仓库的分支名称 + > --scm_repo :被跟踪的上游仓库的仓库名称,github格式:组织/仓库 + > --scm_branch: 被跟踪的上游仓库的仓库的分支 + > --scm_commit: 指定跟踪的起始commit,选填,默认从当前最新commit开始跟踪 + > --enabled :是否自动跟踪该仓库 + + 例如: + + ```shell + # patch-tracking-cli add --server 127.0.0.1:5001 --user admin --password Test@123 --version_control github --repo testPatchTrack/testPatch1 --branch master --scm_repo BJMX/testPatch01 --scm_branch test --enabled true + ``` + +* 指定文件添加 + + 参数含义: + >--server :启动Patch Tracking服务的URL,例如:127.0.0.1:5001 \ + --user :POST接口需要进行认证的用户名,同settings.conf中的USER参数 \ + --password :POST接口需要进行认证的口令,为settings.conf中的PASSWORD哈希值对应的实际的口令字符串 \ + --file :yaml文件路径 + + 将仓库、分支、版本管理工具、是否启动监控等信息写入yaml文件(例如tracking.yaml),文件路径作为`--file`的入参调用命令。 + + 例如: + + ```shell + # patch-tracking-cli add --server 127.0.0.1:5001 --user admin --password Test@123 --file tracking.yaml + ``` + + yaml文件内容格式如下,冒号左边的内容不可修改,右边内容根据实际情况填写。 + + ```text + version_control: github + scm_repo: xxx/xxx + scm_branch: master + repo: xxx/xxx + branch: master + enabled: true + ``` + + > version_control :上游仓库版本的控制工具,只支持github \ + > scm_repo :被跟踪的上游仓库的仓库名称,github格式:组织/仓库 \ + > scm_branch :被跟踪的上游仓库的仓库的分支 \ + > repo :需要进行跟踪的仓库名称,格式:组织/仓库 \ + > branch :需要进行跟踪的仓库的分支名称 \ + > enabled :是否自动跟踪该仓库 + +* 指定目录添加 + + 在指定的目录,例如`test_yaml`下放入多个`xxx.yaml`文件,执行如下命令,记录指定目录下所有yaml文件的跟踪项。 + + 参数含义: + >--user :POST接口需要进行认证的用户名,同settings.conf中的USER参数 \ + --password :POST接口需要进行认证的口令,为settings.conf中的PASSWORD哈希值对应的实际的口令字符串 \ + --server :启动Patch Tracking服务的URL,例如:127.0.0.1:5001 \ + --dir :存放yaml文件目录的路径 + + ```shell + # patch-tracking-cli add --server 127.0.0.1:5001 --user admin --password Test@123 --dir /home/Work/test_yaml/ + ``` + +### 查询跟踪项 + +参数含义: +>--server :必选参数,启动Patch Tracking服务的URL,例如:127.0.0.1:5001 \ +--table :必选参数,需要查询的表 \ +--repo :可选参数,需要查询的repo;如果没有该参数查询表中所有内容 \ +--branch :可选参数,需要查询的branch + +```shell +# patch-tracking-cli query --server SERVER --table tracking +``` + +例如: + +```shell +# patch-tracking-cli query --server 127.0.0.1:5001 --table tracking +``` + +### 查询生成的 Issue + +```shell +# patch-tracking-cli query --server SERVER --table issue +``` + +例如: + +```shell +# patch-tracking-cli query --server 127.0.0.1:5001 --table issue +``` + +### 删除跟踪项 + +```shell +# patch-tracking-cli delete --server SERVER --user USER --password PWD --repo REPO [--branch BRANCH] +``` + +例如: + +```shell +# patch-tracking-cli delete --server 127.0.0.1:5001 --user admin --password Test@123 --repo testPatchTrack/testPatch1 --branch master +``` + +> 可以删除指定repo和branch的单条数据;也可直接删除指定repo下所有branch的数据。 + +### 码云查看 issue 及 PR + +登录Gitee上进行跟踪的软件项目,在该项目的Issues和Pull Requests页签下,可以查看到名为`[patch tracking] TIME`,例如`[patch tracking] 20200713101548`的条目,该条目即是刚生成的补丁文件的issue和对应PR。 diff --git a/docs/en/25.03/Tools/DevOps/_menu.md b/docs/en/25.03/Tools/DevOps/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..7c83590c26d63130586f8ef0bfa89d333db82e76 --- /dev/null +++ b/docs/en/25.03/Tools/DevOps/_menu.md @@ -0,0 +1,10 @@ +--- +label: '社区服务' +children: + - label: '源码管理' + children: + - reference: './CodeManage/patch-tracking/_menu.md' + - label: '包管理' + children: + - reference: './packageManage/pkgship/_menu.md' +--- diff --git a/docs/en/25.03/Tools/DevOps/index.md b/docs/en/25.03/Tools/DevOps/index.md new file mode 100644 index 0000000000000000000000000000000000000000..89eb603c22d527639dfefee3cd9820aecfdefa02 --- /dev/null +++ b/docs/en/25.03/Tools/DevOps/index.md @@ -0,0 +1,4 @@ +--- +title: 社区服务 +overview: true +--- \ No newline at end of file diff --git a/docs/en/25.03/Tools/DevOps/packageManage/pkgship/_menu.md b/docs/en/25.03/Tools/DevOps/packageManage/pkgship/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..92b02ea067c2ad56808254c9b4cd36d882194947 --- /dev/null +++ b/docs/en/25.03/Tools/DevOps/packageManage/pkgship/_menu.md @@ -0,0 +1,8 @@ +--- +label: 'pkgship' +ismanual: 'Y' +description: '提供软件包依赖查询、生命周期管理、补丁查询等功能' +children: + - label: 'pkgship' + href: './pkgship.md' +--- diff --git a/docs/en/25.03/Tools/DevOps/packageManage/pkgship/images/packagemanagement.png b/docs/en/25.03/Tools/DevOps/packageManage/pkgship/images/packagemanagement.png new file mode 100644 index 0000000000000000000000000000000000000000..6d314e2c6ad6bafd321d9f76cd6aa5f17a8cb394 Binary files /dev/null and b/docs/en/25.03/Tools/DevOps/packageManage/pkgship/images/packagemanagement.png differ diff --git a/docs/en/25.03/Tools/DevOps/packageManage/pkgship/images/panel.png b/docs/en/25.03/Tools/DevOps/packageManage/pkgship/images/panel.png new file mode 100644 index 0000000000000000000000000000000000000000..150eb8c8229f9e8cb47706f3b82f07516a505076 Binary files /dev/null and b/docs/en/25.03/Tools/DevOps/packageManage/pkgship/images/panel.png differ diff --git a/docs/en/25.03/Tools/DevOps/packageManage/pkgship/pkgship.md b/docs/en/25.03/Tools/DevOps/packageManage/pkgship/pkgship.md new file mode 100644 index 0000000000000000000000000000000000000000..919444ffcc3fa0f4013bfd2090f7dfa1cdb4a507 --- /dev/null +++ b/docs/en/25.03/Tools/DevOps/packageManage/pkgship/pkgship.md @@ -0,0 +1,442 @@ +# pkgship + + + +- [pkgship](#pkgship) + - [介绍](#介绍) + - [架构](#架构) + - [软件下载](#软件下载) + - [运行环境](#运行环境) + - [安装工具](#安装工具) + - [配置参数](#配置参数) + - [服务启动和停止](#服务启动和停止) + - [工具使用](#工具使用) + - [日志查看和转储](#日志查看和转储) + - [扩展工具pkgship-panel](#扩展工具pkgship-panel) + + + +## 介绍 + +pkgship是一款管理OS软件包依赖关系,提供依赖和被依赖关系完整图谱的查询工具,pkgship提供软件包依赖查询、生命周期管理等功能。 + +1. 软件包基本信息查询:方便社区人员快速获取软件包的名称,版本,描述等基本信息。 +2. 软件包依赖查询:方便社区人员在软件包引入、更新和删除的时候了解软件的影响范围。 + +## 架构 + +系统采用flask-restful开发,架构如下图所示。 + +![avatar](./images/packagemanagement.png) + +## 在线使用 + +pkgship提供了公网地址 + +若需要定制查询数据源,可按照文档进行本地安装、配置、使用。 + +## 软件下载 + +- Repo源挂载正式发布地址: +- 源码获取地址: +- RPM包版本获取地址: + +## 运行环境 + +- 硬件配置: + +| 配置项 | 推荐规格 | +| -------- | ----------- | +| CPU | 8核 | +| 内存 | 32G,最小4G | +| 硬盘 | 20G | +| 网络带宽 | 300M | +| I/O | 375MB/sec | + +- 软件配置: + +| 软件名 | 版本和规格 | +| ------------- | ------------------------------------------ | +| Elasticsearch | 版本7.10.1;单机部署可用;有能力可部署集群 | +| Redis | 建议5.0.4及以上;建议大小配置为内存的3/4 | +| Python | 版本 3.8及以上 | + +## 安装工具 + +> 说明:该软件支持在docker下运行。目前在openEuler21.09版本下,由于环境条件限制,创建docker时请使用--privileged参数,不使用--privileged参数将会导致软件启动失败,后续适配后将更新该文档。 + +**1、pkgship工具安装** + + 工具安装可通过以下两种方式中的任意一种实现。 + +- 方法一:通过dnf挂载repo源实现。 + 先使用dnf挂载pkgship软件所在repo源(具体方法可参考[应用开发指南](https://openeuler.org/zh/docs/20.09/docs/ApplicationDev/%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87.html)),然后执行如下指令下载以及安装pkgship及其依赖。 + + ```bash + dnf install pkgship + ``` + +- 方法二:通过安装rpm包实现。 + 先下载pkgship的rpm包,然后执行如下命令进行安装(其中“x.x-x”表示版本号,请用实际情况代替)。 + + ```bash + rpm -ivh pkgship-x.x-x.oe1.noarch.rpm + ``` + + 或者 + + ```bash + dnf install pkgship-x.x-x.oe1.noarch.rpm + ``` + +**2、Elasticsearch和Redis安装** + + 如果环境没有安装Elasticsearch或者Redis,可以在pkgship安装之后执行自动化安装脚本。 + + 脚本路径默认为: + +```sh +/etc/pkgship/auto_install_pkgship_requires.sh +``` + + 执行方法为 + +```sh +/bin/bash auto_install_pkgship_requires.sh elasticsearch +``` + + 或者 + +```sh + /bin/bash auto_install_pkgship_requires.sh redis +``` + +>**说明:** +>以rpm包方式安装Elasticsearch默认为无密码模式,且pkgship需使用无密码设置的Elasticsearch,因此,当前建议Elasticsearch和pkgship需安装在同一服务器,通过网络隔离提高安全性。后续版本将支持Elasticsearch设置用户名密码。 + +**3、安装后添加用户** + +在安装pkgship软件后,会自动创建名为pkgshipuser的用户和名为pkgshipuser的用户组,无需手动创建,后续服务启动和运行时,都会以该用户角色操作。 + +## 配置参数 + +1.在配置文件中对相应参数进行配置,系统的默认配置文件存放在 /etc/pkgship/package.ini,请根据实际情况进行配置更改。 + +```sh +vim /etc/pkgship/package.ini +``` + +```ini +[SYSTEM-系统配置] +; 初始化数据库时导入的yaml文件存放位置,该yaml中记录导入的sqlite文件位置 +init_conf_path=/etc/pkgship/conf.yaml + +; 若部署为客户端-服务端方式,服务端需保证query_ip_addr为本机ip或者(0.0.0.0), +; 客户端可通过query_ip_addr和query_port访问服务端,或者通过设置映射的remote_host访问服务端 + +; 服务查询端口 +query_port=8090 + +; 服务查询ip +query_ip_addr=127.0.0.1 + +; 远程服务的地址,命令行可以直接调用远程服务来完成数据请求 +remote_host=https://api.openeuler.org/pkgmanage + +; 初始化和下载临时文件存放目录,不会长时间占用,建议可用空间至少1G +temporary_directory=/opt/pkgship/tmp/ + +[LOG-日志] +; 业务日志存放路径 +log_path=/var/log/pkgship/ + +; 打印日志级别,支持如下: +; INFO DEBUG WARNING ERROR CRITICAL +log_level=INFO + +; 单个业务日志文件最大容量,超过该值会自动压缩转储,默认为30M +max_bytes=31457280 + +; 备份日志保留的最大数量,默认为30 +backup_count=30 + +[UWSGI-Web服务器配置] +; 操作日志路径 +daemonize=/var/log/pkgship-operation/uwsgi.log +; 前后端传输数据大小 +buffer-size=65536 +; 网络连接超时时间 +http-timeout=600 +; 服务响应时间 +harakiri=600 + +[REDIS-缓存配置] +; Redis缓存服务器的地址可以是已发布的可以正常访问的域或IP地址 +;链接地址默认为127.0.0.1 +redis_host=127.0.0.1 + +;Redis缓存服务器的端口,默认为6379 +redis_port=6379 + +;Redis服务器一次允许的最大连接数 +redis_max_connections=10 + +[DATABASE-数据库] +;数据库访问地址,建议设置为本机地址 +database_host=127.0.0.1 + +;数据库访问端口,默认为9200 +database_port=9200 + +``` + +2.创建初始化数据库的yaml配置文件: +conf.yaml 文件默认存放在 /etc/pkgship/ 路径下,pkgship会通过该配置读取要建立的数据库名称以及需要导入的sqlite文件,也支持配置sqlite文件所在的repo地址。conf.yaml 示例如下所示。 + +```yaml +dbname: oe20.03 #数据库名称 +src_db_file: /etc/pkgship/repo/openEuler-20.03/src #源码包所在的本地路径 +bin_db_file: /etc/pkgship/repo/openEuler-20.03/bin #二进制包所在的本地路径 +priority: 1 #数据库优先级 + +dbname: oe20.09 +src_db_file: https://repo.openeuler.org/openEuler-20.09/source #源码包所在的repo源 +bin_db_file: https://repo.openeuler.org/openEuler-20.09/everything/aarch64 #二进制包所在的repo源 +priority: 2 +``` + +> 如需更改存放路径,请更改package.ini下的 init_conf_path 选项。 +> +> 不支持直接配置sqlite文件路径。 +> +> dbname请使用小写字母或者数字开头和结尾,支持括号内字符(. - _ +),不支持大写字母。 + +## 服务启动和停止 + +pkgship启动和停止方式有两种,systemctl方式和pkgshipd方式,其中systemctl方式启动可以有异常停止自启动的机制。两种方式的执行命令为: + +```shell +systemctl start pkgship.service 启动服务 + +systemctl stop pkgship.service 停止服务 + +systemctl restart pkgship.service 重启服务 +``` + +```sh +pkgshipd start 启动服务 + +pkgshipd stop 停止服务 +``` + +> 每次启停周期内仅支持一种方式,不允许两种操作同时使用。 +> +> pkgshipd启动方式只允许在pkgshipuser用户下操作。 +> +> docker环境下如果不支持systemctl命令,请使用pkgshipd启停方式。 + +## 工具使用 + +1. 数据库初始化。 + + > 使用场景:服务启动后,为了能查询对应的数据库(比如oe20.03,oe20.09)中的包信息及包依赖关系,需要将这些数据库通过createrepo生成的sqlite(分为源码库和二进制库)导入进服务内,生成对应的包信息json体然后插入Elasticsearch对应的数据库中。数据库名为根据conf.yaml中配置的dbname生成的dbname-source/binary。 + + ```bash + pkgship init [-filepath path] + ``` + + > 参数说明: + > -filepath:指定初始化配置文件config.yaml的路径,可以使用相对路径和绝对路径,不带参数则使用默认配置初始化,可选参数。 + +2. 单包查询。 + + 用户可查询源码包或者二进制包(packagename)在指定数据库表(database)中的具体信息。 + + > 使用场景:用户可查询源码包或者二进制包在指定数据库中的具体信息。 + + ```bash + pkgship pkginfo $packageName $database [-s] + ``` + + > 参数说明: + > packagename:指定要查询的软件包名,必传参数。 + > database:指定具体的数据库名称,必传参数。 + > + > -s: 指定`-s`将查询的是`src`源码包信息;若未指定 默认查询`bin`二进制包信息,可选参数。 + +3. 所有包查询。 + + 查询数据库下包含的所有包的信息。 + + > 使用场景:用户可查询指定数据库下包含的所有软件包信息。 + + ```bash + pkgship list $database [-s] + ``` + + > 参数说明: + > database:指定具体的数据库名称,必传参数。 + > -s: 指定`-s`将查询的是`src`源码包信息;若未指定 默认查询`bin`二进制包信息,可选参数。 + +4. 安装依赖查询。 + + 查询二进制包(binaryName)的安装依赖。 + + > 使用场景:用户需要安装某个二进制包A时,需要将该二进制包A的安装依赖B,及B的安装依赖C等等,直至所有的安装依赖全部安装到系统才能成功安装二进制包A。因此,在用户安装二进制包A之前,可能会需要查询二进制包A的所有安装依赖。该命令提供了此功能,允许用户根据平台默认的优先级在多个数据库之间进行查询;同时也支持用户自定义数据库查询优先级。 + + ```bash + pkgship installdep [$binaryName $binaryName1 $binaryName2...] [-dbs] [db1 db2...] [-level] $level + ``` + + > 参数说明: + > binaryName:需要查询安装的依赖的二进制包名字,支持传多个;必传参数。 + > + > -dbs:指定需要查询的database优先级,不传按照系统默认优先级搜索;可选参数。 + > + > -level:指定需要查询的依赖层级,不传默认为0,查询所有层级;可选参数。 + +5. 编译依赖查询。 + + 查询源码包(sourceName)的所有编译依赖。 + + > 使用场景:用户要编译某个源码包A的时候,需要安装源码包A的编译依赖B,要成功安装编译依赖B需要获取B的所有安装依赖。因此,在用户编译源码包A之前,可能会需要查询源码包的编译依赖以及这些编译依赖的所有安装依赖。该命令提供了此功能,允许用户根据平台默认的优先级在多个数据库之间进行查询;同时也支持用户自定义数据库查询优先级。 + + ```bash + pkgship builddep [$sourceName $sourceName1 $sourceName2..] -dbs [db1 db2 ..] [-level] $level + ``` + + > 参数说明: + > sourceName:需要查询编译依赖的源码包名字,支持多个查询;必传参数。 + > + > -dbs: 指定需要查询的database优先级,不传按照系统默认优先级搜索;可选参数。 + > + > -level:指定需要查询的依赖层级,不传默认为0,查询所有层级;可选参数。 + +6. 自编译自安装依赖查询。 + + 查询指定二进制包(binaryName)或源码包(sourceName )的安装及编译依赖,其中[pkgName]为查询的二进制包或者源码包的名称。当查询二进制包时,可以查询到该二进制包的所有安装依赖以及该二进制包对应的源码包的编译依赖,及这些编译依赖的所有安装依赖;当查询源码包时,可以查询该源码包的编译依赖,及这些编译依赖的所有安装依赖,并且查询该源码包生成的所有二进制包的所有安装依赖。同时,配合对应参数使用,该命令也支持查询软件包的自编译依赖查询,和包含子包的依赖查询。 + + > 使用场景:如果开发者想在现有的版本库的基础上引入新的软件包,应同时引入该软件包的所有编译、安装依赖。该命令提供开发者一个同时查询这两种依赖关系的功能,能让开发者知晓该软件包会引入哪些其他的包,该命令支持查询二进制包和源码包。 + + ```bash + pkgship selfdepend [$pkgName1 $pkgName2 $pkgName3 ..] [-dbs] [db1 db2..] [-b] [-s] [-w] + ``` + + > 参数说明: + > + > pkgName:需要查询安装的依赖的软件包名字,支持传多个;必传参数。 + > + > -dbs: 指定需要查询的database优先级,不传按照系统默认优先级搜索;可选参数。 + > + > -b:指定`-b`表示查询的包是二进制,不指定默认查询源码包;可选参数。 + > + > -s: 指定-s表示查询软件包的所有安装依赖和所有编译依赖(即编译依赖的源码包的编译依赖),以及所有编译依赖的安装依赖;如果不增加-s参数表示只查询软件包的所有安装依赖和一层编译依赖,以及一层编译依赖的所有安装依赖;可选参数。 + > + > -w:指定-w表示引入某个二进制包的时候,查询结果会显示出该二进制包对应的源码包以及该源码包生成的所有二进制包;如果不指定-w参数表示引入某个二进制包的时候,查询结果只显示对应的源码包;可选参数。 + +7. 被依赖查询。 + 查询软件包(pkgName)在某数据库(dbName)中被哪些包所依赖。 + + > 使用场景:针对软件包A,在升级或删除的情况下会影响哪些软件包,可通过该命令查询。该命令会显示源码包A(若为源码包)生成的所有二进制包(若输入为二进制包,那此处即为输入的二进制包)被哪些源码包(比如B)编译依赖,被哪些二进制包(比如C1)安装依赖;以及B生成的二进制包及C1被哪些源码包(比如D)编译依赖,被哪些二进制包(比如E1)安装依赖,以此类推,遍历这些二进制包的被依赖。 + + ```bash + pkgship bedepend dbName [$pkgName1 $pkgName2 $pkgName3] [-w] [-b] [-install/build] + ``` + + > 参数说明: + > + > dbName:需要查询依赖关系的仓库,不支持多个;必选参数。 + > + > pkgName:待查询的软件包名称,支持多个;必选参数。 + > + > -w :当不指定-w 时,查询结果默认不包含对应源码包的子包;当命令后指定配置参数[-w] 时,不仅会查询二进制包C1的被依赖关系,还会进一步去查询C1对应的源码包C生成的其他二进制包(比如:C2,C3)的被依赖关系;可选参数。 + > + > -b:指定`-b`表示查询的包是二进制,默认查询源码包;可选参数。 + > + > -install/build:指定`-install`表示查询的是安装被依赖,指定`-build`表示查询的是编译被依赖,默认查全部, 不能`-install`和`-build`同时存在;可选参数。 + +8. 数据库信息。 + + > 使用场景,查看Elasticsearch中初始化了哪些数据库,该功能会按照优先级顺序返回已经初始化的数据库列表。 + + `pkgship dbs` + +9. 获取版本号。 + + > 使用场景:获取pkgship软件的版本号。 + + `pkgship -v` + +## 日志查看和转储 + + **日志查看** + + pkgship服务在运行时会产生两种日志,业务日志和操作日志。 + + 1、业务日志: + + 路径:/var/log/pkgship/log_info.log(支持在package.ini中通过log_path字段自定义路径)。 + + 功能:主要记录代码内部运行的日志,方便问题定位。 + + 权限:路径权限755,日志文件权限644,普通用户可以查看。 + +2、操作日志: + +路径:/var/log/pkgship-operation/uwsgi.log (支持在package.ini中通过daemonize字段自定义路径)。 + +功能:记录使用者操作信息,包括ip,访问时间,访问url,访问结果等,方便后续查阅以及记录攻击者信息。 + +权限:路径权限700,日志文件权限644,只有root和pkgshipuser可以查看。 + +**日志转储** + +1、业务日志转储: + +- 转储机制 + + 使用python自带的logging内置函数的转储机制,按照日志大小来备份。 + +> 配置项,package.ini中配置每个日志的容量和备份数量 +> +> ```ini +> ; Maximum capacity of each file, the unit is byte, default is 30M +> max_bytes=31457280 +> +> ; Number of old logs to keep;default is 30 +> backup_count=30 +> ``` + +- 转储过程 + + 当某次日志写入后,日志文件大小超过配置的日志容量时,会自动压缩转储,压缩后文件名为log_info.log.x.gz, x是数字,数字越小为越新的备份。 + + 当备份日志数量到达配置的备份数量之后,最早的备份日志会被删除掉,然后备份一个最新的压缩日志文件。 + +2、操作日志转储: + +- 转储机制 + + 使用脚本进行转储,按照时间转储,每日转储一次,共保留30天,不支持自定义配置。 + + > 脚本位置:/etc/pkgship/uwsgi_logrotate.sh + +- 转储过程 + + pkgship启动时转储脚本后台运行,从启动时,每隔1天进行转储压缩,共保留30份压缩文件,压缩文件名称为uwsgi.log-20201010x.zip, x为压缩时的小时数。 + + pkgship停止后转储脚本停止,不再进行转储,再次启动时,转储脚本重新执行。 + +## 扩展工具pkgship-panel + +### 介绍 + +pkgship-panel旨在将软件包构建信息和维护信息集成到一起,方便版本维护人员可以快速识别构建异常软件包并快速邮件通知相关责任人去解决,保证构建工程稳定性,提高OS构建成功率。 + +### 架构 + +![](images/panel.png) + +### 工具使用 + +由于工具数据源不可配置,所以建议直接使用pkgship-panel官网: diff --git a/docs/en/25.03/Tools/Maintenance/_menu.md b/docs/en/25.03/Tools/Maintenance/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..5b88901ba322d85c58a72c74a63980c12ad441fa --- /dev/null +++ b/docs/en/25.03/Tools/Maintenance/_menu.md @@ -0,0 +1,10 @@ +--- +label: '系统运维' +children: + - label: '热补丁制作' + children: + - reference: '../../Server/Maintenance/SysCare/_menu.md' + - label: '系统监控' + children: + - reference: '../../Server/Maintenance/sysmonitor/_menu.md' +--- diff --git a/docs/en/25.03/Tools/Maintenance/index.md b/docs/en/25.03/Tools/Maintenance/index.md new file mode 100644 index 0000000000000000000000000000000000000000..aa350ef0351170691961524651824c0deb509a78 --- /dev/null +++ b/docs/en/25.03/Tools/Maintenance/index.md @@ -0,0 +1,4 @@ +--- +title: 系统运维 +overview: true +--- \ No newline at end of file diff --git a/docs/en/25.03/Tools/Security/_menu.md b/docs/en/25.03/Tools/Security/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..218409bbf09d73b61455afa05667576c7e954cf6 --- /dev/null +++ b/docs/en/25.03/Tools/Security/_menu.md @@ -0,0 +1,5 @@ +--- +label: '安全' +children: + - reference: '../../Server/Security/secGear/_menu.md' +--- diff --git a/docs/en/25.03/Tools/Security/index.md b/docs/en/25.03/Tools/Security/index.md new file mode 100644 index 0000000000000000000000000000000000000000..66ccc4b12dd15f16749c2e7320f45bb65d84f028 --- /dev/null +++ b/docs/en/25.03/Tools/Security/index.md @@ -0,0 +1,4 @@ +--- +title: 安全 +overview: true +--- \ No newline at end of file diff --git a/docs/en/25.03/Tools/_menu.md b/docs/en/25.03/Tools/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..58066d51e118811f623c5fcdd0577f99ca7bfed8 --- /dev/null +++ b/docs/en/25.03/Tools/_menu.md @@ -0,0 +1,11 @@ +--- +label: '工具' +children: + - reference: './CommunityTools/_menu.md' + - reference: './DevOps/_menu.md' + - reference: './AI/_menu.md' + - reference: './desktop/_menu.md' + - reference: './Cloud/_menu.md' + - reference: './Maintenance/_menu.md' + - reference: './Security/_menu.md' +--- diff --git a/docs/en/25.03/Tools/desktop/.keep b/docs/en/25.03/Tools/desktop/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/docs/en/25.03/Tools/desktop/DDE/DDE-user-guide.md b/docs/en/25.03/Tools/desktop/DDE/DDE-user-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..a9cff4367de5d01687779f2811de71ca42d836fe --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/DDE-user-guide.md @@ -0,0 +1,850 @@ +# DDE桌面环境用户手册 + +## 概述 + +DDE桌面环境是一款美观易用、安全可靠的图形化操作界面。桌面环境主要由桌面、任务栏、启动器、控制中心等组成,是您使用该操作系统的基础,主界面如下图所示。 + +![1|desk](./figures/43.jpg) + +### 欢迎 + +初次进入DDE桌面环境,会自动打开欢迎程序。您可以观看视频了解系统功能,选择桌面样式和图标主题,进一步了解该系统。 + +![welcome](./figures/64.png) + +## 桌面 + +桌面是您登录后看到的主屏幕区域。在桌面上,您可以新建文件/文件夹、排列文件、打开终端、设置壁纸和屏保等,还可以通过启动器 [发送到桌面](#设置快捷方式) 向桌面添加应用的快捷方式。 + +![0|rightbuttonmenu](./figures/41.png) + +### 新建文件夹/文档 + +在桌面新建文件夹或文档,也可以对文件进行常规操作,和在文件管理器中一样。 + +- 在桌面上,单击鼠标右键,单击 **新建文件夹**,输入新建文件夹的名称。 +- 在桌面上,单击鼠标右键,单击 **新建文档**,选择新建文档的类型,输入新建文档的名称。 + +在桌面文件或文件夹上,单击鼠标右键,您可以使用文件管理器的相关功能: + +| 功能 | 说明 | +| ----------- | -------------------------------------------------------- | +| 打开方式 | 选定系统默认打开方式,也可以选择其他关联应用程序来打开。 | +| 剪切 | 移动文件或文件夹。 | +| 复制 | 复制文件或文件夹。 | +| 重命名 | 重命名文件或文件夹。 | +| 删除 | 删除文件或文件夹。 | +| 创建链接 | 创建一个快捷方式。 | +| 标记信息 | 添加标记信息,以对文件或文件夹进行标签化管理。 | +| 压缩/解压缩 | 压缩文件或文件夹,或对压缩文件进行解压。 | +| 属性 | 查看文件或文件夹的基本信息,共享方式,及其权限。 | + +### 设置排列方式 + +您可以对桌面上的图标按照需要进行排序。 + +1. 在桌面上,单击鼠标右键。 +2. 单击 **排序方式**,您可以: + - 单击 **名称**,将按文件的名称顺序显示。 + - 单击 **大小**,将按文件的大小顺序显示。 + - 单击 **类型**,将按文件的类型顺序显示。 + - 单击 **修改时间**,文件将按最近一次的修改日期顺序显示。 + +> ![tips](./figures/icon125-o.svg)窍门:*您也可以勾选 **自动排列**,桌面图标将从上往下,从左往右按照当前排序规则排列,有图标被删除时后面的图标会自动向前填充。* + +### 调整图标大小 + +1. 在桌面上,单击鼠标右键。 +2. 单击 **图标大小**。 +3. 选择一个合适的图标大小。 + +> ![tips](./figures/icon125-o.svg)窍门:*您也可以用 **Ctrl** + ![=](./figures/icon134-o.svg)/![-](./figures/icon132-o.svg) 鼠标滚动来调整桌面和启动器中的图标大小。* + +### 设置显示器 + +从这里快速进入控制中心设置显示器的缩放比例、分辨率和亮度等。 + +1. 在桌面上,单击鼠标右键。 +2. 单击 **显示设置**,快速进入控制中心的显示设置界面。 + +> ![notes](./figures/icon99-o.svg)说明:*关于显示的设置,具体操作请参阅 [显示设置](#显示设置) 。* + +### 更改壁纸 + +您可以选择一些精美、时尚的壁纸来美化桌面,让您的电脑显示与众不同。 + +1. 在桌面上,单击鼠标右键。 +2. 单击 **壁纸与屏保**,在桌面底部预览所有壁纸。 +3. 选择某一壁纸后,壁纸就会在桌面和锁屏中生效。 +4. 您可以单击 **仅设置桌面** 、 **仅设置锁屏** 和 **同时设置** 来控制壁纸的生效范围。 + +![1|wallpaper](./figures/63.jpg) + +              + +> ![tips](./figures/icon125-o.svg)窍门: *您还可以在图片查看器中设置您喜欢的图片为桌面壁纸。* + +### 剪贴板 + +剪贴板展示当前用户登录系统后复制和剪切的所有文本、图片和文件。使用剪贴板可以快速复制其中的某项内容。注销或关机后,剪贴板会自动清空。 + +1. 使用快捷键 **Ctrl** + **Alt** + **V** 唤出剪贴板。 +2. 双击剪贴板内的某一区块,会快速复制当前内容, 且当前区块会被移动到剪贴板顶部。 +3. 选择目标位置粘贴。 +4. 鼠标移入剪贴板的某一区块,单击上方的![close](./figures/icon57-o.svg),删除当前内容;单击顶部的 **全部清除**,清空剪贴板。 + +![1|clipboard](./figures/40.png) + +## 任务栏 + +任务栏是指位于桌面底部的长条,主要由启动器、应用程序图标、托盘区、系统插件等组成。在任务栏,您可以打开启动器、显示桌面、进入工作区,对其上的应用程序进行打开、新建、关闭、强制退出等操作,还可以设置输入法,调节音量,连接网络,查看日历,进入关机界面等。 + +### 认识任务栏图标 + +任务栏图标包括启动器图标、应用程序图标、托盘区图标、系统插件图标等。 + +![1|fashion](./figures/45.png) + +| 图标 | 说明 | 图标 | 说明 | +| ------------------------------------------- | :------------------------------------------ | ------------------------------------------------ | ------------------------------------- | +| ![launcher](./figures/icon66-o.svg) | 启动器 - 点击查看所有已安装的应用。 | ![deepin-toggle-desktop](./figures/icon69-o.svg) | 显示桌面。 | +| ![dde-file-manager](./figures/icon63-o.svg) | 文件管理器 - 点击查看磁盘中的文件、文件夹。 | ![dde-calendar](./figures/icon62-o.svg) | 日历 - 查看日期、新建日程。 | +| ![controlcenter](./figures/icon58-o.svg) | 控制中心 - 点击进入系统设置。 | ![notification](./figures/icon101-o.svg) | 通知中心 - 显示所有系统和应用的通知。 | +| ![onboard](./figures/icon103-o.svg) | 屏幕键盘 - 点击使用虚拟键盘。 | ![shutdown](./figures/icon122-o.svg) | 电源 - 点击进入关机界面。 | +| ![trash](./figures/icon126-o.svg) | 回收站。 | | | + +              + +> ![tips](./figures/icon125-o.svg)窍门:*在高效模式下,单击任务栏最右侧可显示桌面。将鼠标指针移到任务栏上已打开窗口的图标时,会显示相应的预览窗口。* + +### 切换显示模式 + +任务栏提供两种显示模式:时尚模式和高效模式,显示不同的图标大小和应用窗口激活效果。 + +![1|fashion](./figures/46.png) + +![1|efficient](./figures/63.png) + +              + +您可以通过以下操作来切换显示模式: + +1. 右键单击任务栏。 +2. 在 **模式** 子菜单中选择一种显示模式。 + +### 设置任务栏位置 + +您可以将任务栏放置在桌面的任意方向。 + +1. 右键单击任务栏。 +2. 在 **位置** 子菜单中选择一个方向。 + +### 调整任务栏高度 + +鼠标拖动任务栏边缘,改变任务栏高度。 + +### 显示/隐藏插件 + +1. 右键单击任务栏。 +2. 在 **插件区域** 子菜单中勾选或取消勾选 **回收站、电源、显示桌面、屏幕键盘、通知中心、时间**,可以设置这些插件在任务栏上的显示和隐藏效果。 + +### 查看通知 + +当有系统或应用通知时,会在桌面上方弹出通知消息。若有按钮,单击按钮执行对应操作;若无按钮,单击关闭此消息。 + +![message](./figures/51.png) + +              + +您还可以单击任务栏上的 ![notification](./figures/icon101-o.svg), 打开通知中心,查看所有通知。 + +### 查看日期时间 + +- 鼠标指针悬停在任务栏的时间上,查看当前日期、星期和时间。 +- 单击时间,打开日历。 + +### 进入关机界面 + +您可以单击任务栏上的 ![shutdown](./figures/icon136-o.svg) 进入关机界面,也可以在启动器的小窗口模式中单击 ![poweroff_normal](./figures/icon136-o.svg)。 + +| 功能 | 说明 | +| ---------------------------------------------------------- | ------------------------------------------------------- | +| 关机![poweroff_normal](./figures/icon136-o.svg) | 关闭电脑。 | +| 重启![reboot_normal](./figures/icon110-o.svg) | 关机后再次重新运行您的电脑。 | +| 锁定![lock_normal](./figures/icon90-o.svg) | 锁定电脑,或按下键盘上的 **Super** + **L** 组合键锁定。 | +| 切换用户![userswitch_normal](./figures/icon128-o.svg) | 选择另一个用户帐户登录。 | +| 注销![logout_normal](./figures/icon92-o.svg) | 清除当前登录用户的信息。 | +| 启动系统监视器![deepin-system-monitor](./figures/icon68-o.svg) | 快速启动系统监视器。 | + +              + +> ![notes](./figures/icon99-o.svg)说明:*当系统存在多个帐户时才显示 ![userswitch_normal](./figures/icon128-o.svg)。* + +### 回收站 + +电脑中临时被删除的所有文件您都可以在回收站中找到,回收站中的文件可以被恢复或清空。 + +#### 还原文件 + +对于已删除的文件,您可以进入回收站进行还原,或使用 **Ctrl** + **Z** 还原刚删除的文件。 + +1. 在回收站中,选择要恢复的文件。 +2. 单击鼠标右键,选择 **还原**。 +3. 还原文件到原来的存储路径下。 + +> ![attention](./figures/icon52-o.svg)注意:*如果原来所在的文件夹已经删除,还原文件时会自动新建文件夹*。 + +#### 清空回收站 + +在回收站中,单击 **清空**,将彻底删除回收站的所有内容。 + +## 启动器 + +启动器 ![launcher](./figures/icon66-o.svg) 帮助您管理系统中已安装的所有应用,在启动器中使用分类导航或搜索功能可以快速找到您需要的应用程序。 + +> ![tips](./figures/icon125-o.svg)窍门:*您可以进入启动器查看新安装的应用。新安装应用的旁边会出现一个小蓝点提示*。 + +### 切换模式 + +启动器有全屏和小窗口两种模式。单击启动器界面右上角的图标来切换模式。 + +两种模式均支持搜索应用、设置快捷方式等操作。 + +小窗口模式还支持快速打开文件管理器,控制中心和进入关机界面等功能。 + +![1|fullscreen](./figures/47.jpg)![1|ini](./figures/52.png) + +### 排列应用 + +在全屏模式下,系统默认按照安装时间排列所有应用。 + +- 将鼠标悬停在应用图标上,按住鼠标左键不放,将应用图标拖拽到指定的位置自由排列。 +- 单击启动器界面左上角分类图标![category](./figures/icon56-o.svg)进行排列。 + +![1|sortapp](./figures/60.jpg) + +              + +在小窗口模式下,默认按照使用频率排列应用。 + +### 查找应用 + +在启动器中,您可以滚动鼠标滚轮或切换分类导航查找应用。 + +如果知道应用名称,直接在搜索框中输入关键字,快速定位到需要的应用。 + +### 设置快捷方式 + +快捷方式提供了一种简单快捷地启动应用的方法。 + +#### 创建快捷方式 + +将应用发送到桌面或任务栏上,方便您的后续操作。 + +在启动器中,右键单击应用图标,您可以: + +- 单击 **发送到桌面**,在桌面创建快捷方式。 + +- 单击 **发送到任务栏**,将应用固定到任务栏。 + +![0|sendto](./figures/58.png) + +> ![notes](./figures/icon99-o.svg)说明:*您还可以从启动器拖拽应用图标到任务栏上放置。但是当应用处于运行状态时您将无法拖拽固定,此时您可以右键单击任务栏上的应用图标,选择 **驻留** 将应用固定到任务栏,以便下次使用时从任务栏上快速打开。* + +#### 删除快捷方式 + +您既可以在桌面直接删除应用的快捷方式,也可以在任务栏和启动器中删除。 + +**从任务栏上删除** + +- 在任务栏上,按住鼠标左键不放,将应用图标拖拽到任务栏以外的区域移除快捷方式。 +- 当应用处于运行状态时您将无法拖拽移除,此时可以右键单击任务栏上的应用图标,选择 **移除驻留** 将应用从任务栏上移除。 + +**从启动器中删除** + +在启动器中,右键单击应用图标,您可以: + +- 单击 **从桌面上移除**,删除桌面快捷方式。 +- 单击 **从任务栏上移除**,将固定到任务栏上的应用移除。 + +> ![notes](./figures/icon99-o.svg)说明:*以上操作,只会删除应用的快捷方式,而不会卸载应用。* + +### 运行应用 + +对于已经创建了桌面快捷方式或固定到任务栏上的应用,您可以通过以下途径来打开应用。 + +- 双击桌面图标,或右键单击桌面图标选择 **打开**。 +- 直接单击任务栏上的应用图标,或右键单击任务栏上的应用图标选择 **打开**。 + +在启动器中,直接单击应用图标打开,或右键单击应用图标选择 **打开**。 + +> ![tips](./figures/icon125-o.svg)窍门:*对于经常使用的应用,您可以在启动器中,右键单击应用图标选择 **开机自动启动**。* + +## 控制中心 + +DDE桌面操作系统通过控制中心来管理系统的基本设置,包括帐户管理、网络设置、日期和时间、个性化设置、显示设置、系统信息查看等。当您进入桌面环境后,单击任务栏上的 ![controlcenter](./figures/icon58-o.svg) 即可打开控制中心窗口。 + +### 首页介绍 + +控制中心首页主要展示各个设置模块,方便日常查看和快速设置。 + +![2|dcchomepage](./figures/42.png) + +              + +打开控制中心的某一设置模块后,可以通过左侧导航栏快速切换到另一设置模块。 + +![2|cc-navigation](./figures/39.png) + +#### 标题栏 + +标题栏包含返回按钮,搜索框,主菜单及窗口按钮。 + +- 返回按钮:若要返回首页,单击 ![back](./figures/icon53-o.svg)。 +- 搜索框:输入关键字后,回车,搜索相应设置。 +- 主菜单:单击![menu](./figures/icon83-o.svg) 进入主菜单。在主菜单中,您可以设置窗口主题,查看版本,或退出控制中心。 + +### 帐户设置 + +在安装系统时您已经创建了一个帐户。在这里,您可以修改帐户设置或创建一个新帐户。 + +![0|account](./figures/38.png) + +#### 创建新帐户 + +1. 在控制中心首页,单击 ![account_normal](./figures/icon49-o.svg)。 +2. 单击![add](./figures/icon50-o.svg)。 +3. 输入用户名、密码和重复密码。 +4. 单击 **创建**。 +5. 在授权对话框输入当前帐户的密码,新帐户就会添加到帐户列表中。 + +#### 更改头像 + +1. 在控制中心首页,单击 ![account_normal](./figures/icon49-o.svg)。 +2. 单击列表中的帐户。 +3. 单击帐户头像,选择一个头像或添加本地头像,头像就替换完成了。 + +#### 设置全名 + +帐户全名会显示在帐户列表和系统登录界面,可根据需要设置。 + +1. 在控制中心首页,单击 ![account_normal](./figures/icon49-o.svg)。 +2. 单击列表中的帐户。 +3. 单击 **设置全名** 后的 ![edit](./figures/icon75-o.svg),输入帐户全名。 + +#### 修改密码 + +1. 在控制中心首页,单击 ![account_normal](./figures/icon49-o.svg)。 +2. 单击当前帐户。 +3. 单击 **修改密码**,进入修改密码页面。 +4. 输入当前密码、新密码和重复密码。 + +#### 删除帐户 + +1. 在控制中心首页,单击 ![account_normal](./figures/icon49-o.svg)。 +2. 单击其他未登录的帐户。 +3. 单击 **删除帐户** 。 +4. 在弹出的确认界面中单击 **删除**。 + +> ![attention](./figures/icon52-o.svg)注意: *已登录的帐户无法被删除。* + +#### 权限设置 + +除安装时的第一个帐户是管理员权限外,后面所添加的所有帐户都是普通用户。一个帐户可以在多个用户组内。 + +##### 设置组 + +添加或修改帐户时,可以: + +- 选择系统内已有的组。 +- 选择当前用户同名的组。 +- 选择之前添加帐户时和其他用户同名的组。 + +### 显示设置 + +设置显示器的分辨率、亮度、屏幕方向等,让您的电脑显示到达最佳状态。 + +![0|video](./figures/44.png) + +#### 单屏设置 + +##### 更改分辨率 + +1. 在控制中心首页,单击 ![display_normal](./figures/icon72-o.svg)。 +2. 单击 **分辨率**,进入分辨率设置界面。 +3. 在列表中选择合适的分辨率参数。 +4. 单击 **保存**。 + +##### 调节亮度 + +1. 在控制中心首页,单击 ![display_normal](./figures/icon72-o.svg)。 +2. 单击 **亮度**,进入亮度设置界面。 + + - 拖动亮度条滑块,调节屏幕亮度。 + - 打开 **自动调节色温** 开关,开启进入护眼模式,自动调节色温。 + - 打开 **手动调节** 亮度开关,可以调节屏幕亮度 。 + +##### 设置屏幕刷新率 + +1. 在控制中心首页,单击 ![display_normal](./figures/icon72-o.svg)。 +2. 单击 **刷新率**。 +3. 选择一个合适的刷新率,单击 **保存**。 + +##### 改变屏幕方向 + +1. 在控制中心首页,单击 ![display_normal](./figures/icon72-o.svg)。 +2. 单击 ![rotate](./figures/icon112-o.svg) 。 +3. 每单击一下鼠标左键,屏幕逆时针旋转90°。 +4. 要还原为之前的屏幕方向,单击鼠标右键退出;要使用当前屏幕方向,请按下组合键 **Ctrl** + **S** 保存。 + +#### 多屏设置 + +多屏显示,让您的视野无限延伸!使用VGA、HDMI、EDP等线缆将您的电脑和另一台显示器、投影仪等连接起来,同时在多个屏幕显示您电脑上的内容。 + +1. 在控制中心首页,单击 ![display_normal](./figures/icon72-o.svg)。 +2. 单击 **多屏显示模式**。 +3. 选择一种显示模式。 + - **复制**将主屏的显示内容复制到其他屏幕。 + - **扩展** 将主屏的显示内容扩展到其他屏幕,扩大桌面区域。 + - **自定义** 设置显示模式,主屏、分辨率、刷新率和屏幕旋转方向。 + +在多屏环境下,按下 **Super** + **P**调出多屏显示模式的OSD。 + +详细操作方法如下。 + +1. 按住 **Super** 不放,再按下 **P** 或鼠标单击来进行模式选择。 +2. 松开按键,确认选择,模式生效。 + +> ![notes](./figures/icon99-o.svg)说明:*当多屏显示模式为扩展模式时,仅主屏支持桌面图标显示、操作右键菜单等功能,而副屏不支持。* + +##### 自定义设置 + +1. 在控制中心首页,单击 ![display_normal](./figures/icon72-o.svg)。 +2. 单击 **多屏显示模式** > **自定义**。 +3. 单击 “识别”,查看屏幕名称。 +4. 选择“合并”或“拆分”,然后对多个屏幕进行设置,如主屏、分辨率、刷新率,旋转屏幕等。 +5. 单击 **保存**。 + +> ![notes](./figures/icon99-o.svg)说明:*合并即复制模式,拆分即扩展模式。* + +### 默认程序设置 + +当安装有多个功能相似的应用程序时,可以选择其中的一个应用作为对应文件类型的默认启动程序。 + +![0|default](./figures/39.png) + +#### 设置默认程序 + +1. 右键单击文件,选择 **打开方式** > **选择默认程序**。 +2. 选择一个应用,自动勾选"设为默认",单击 **确定**。 +3. 该应用将自动添加到控制中心的默认程序列表。 + +#### 更改默认程序 + +1. 在控制中心首页,单击 ![default_applications_normal](./figures/icon70-o.svg)。 +2. 选择一个文件类型进入默认程序列表。 +3. 在列表中选择另一个应用程序。 + +#### 添加默认程序 + +1. 在控制中心首页,单击 ![default_applications_normal](./figures/icon70-o.svg)。 +2. 选择文件类型进入默认程序列表。 +3. 单击列表下的![add](./figures/icon50-o.svg),选择desktop文件(一般在/usr/share/applications),或特定的二进制文件。 +4. 该程序将添加到列表,并自动设置为默认程序。 + +#### 删除默认程序 + +在默认程序列表中,您只能删除自己添加的应用程序,不能删除系统已经安装的应用。要删除系统已经安装的应用,只能卸载应用。卸载后该应用将自动从默认程序列表中删除。 + +可用以下方法删除自己添加的默认程序。 + +1. 在控制中心首页,单击 ![default_applications_normal](./figures/icon70-o.svg)。 +2. 选择文件类型进入默认程序列表。 +3. 单击程序后面的![close](./figures/icon57-o.svg),删除默认程序。 + +### 个性化设置 + +在这里,您可以设置系统主题、活动用色、字体等,改变桌面和窗口的外观,设置成您喜欢的显示风格。 + +![0|personalise](./figures/56.png) + +#### 设置窗口主题 + +1. 在控制中心首页,单击 ![personalization_normal](./figures/icon105-o.svg)。 +2. 单击 **通用**,选择一种窗口主题。 +3. 该主题即为系统窗口主题。 + +> ![tips](./figures/icon125-o.svg)窍门:*自动主题表示根据当前时区的时间,根据日出日落的时间自动更换窗口主题。日出后是浅色,日落后是深色。* + +#### 更改活动用色 + +活动用色是指选中某一选项时的强调色。 + +1. 在控制中心首页,单击 ![personalization_normal](./figures/icon105-o.svg)。 +2. 单击 **通用**。 +3. 单击 **活动用色** 下的一种颜色,可实时查看该颜色效果。 + +#### 设置图标主题 + +1. 在控制中心首页,单击 ![personalization_normal](./figures/icon105-o.svg)。 +2. 单击 **图标主题**,选择一款图标样式。 + +#### 设置光标主题 + +1. 在控制中心首页,单击 ![personalization_normal](./figures/icon105-o.svg)。 +2. 单击 **光标主题**,选择一款光标样式。 + +#### 更改系统字体 + +1. 在控制中心首页,单击 ![personalization_normal](./figures/icon105-o.svg)。 +2. 单击 **字体**,进入设置字体界面。 +3. 设置系统字号和字体。 + +### 网络设置 + +登录系统后,您需要连接网络,才能接收邮件、浏览新闻、下载文件、聊天、网上购物等。 + +> ![tips](./figures/icon125-o.svg)窍门:*您可以单击任务栏托盘区的网络图标,查看当前网络状态。* + +![0|network](./figures/54.png) + +#### 有线网络 + +有线网络安全快速稳定,是最常见的网络连接方式。当您设置好路由器后,把网线两端分别插入电脑和路由器,即可连接有线网络。 + +1. 将网线插入电脑上的网络插孔。 +2. 将网线的另一端插入路由器或网络端口。 +3. 在控制中心首页,单击 ![network_normal](./figures/icon97-o.svg)。 +4. 单击 **有线网络**,进入有线网络设置界面。 +5. 打开 **有线网卡**,开启有线网络连接功能。 +6. 当网络连接成功后,桌面右上角将弹出“已连接有线连接”的提示信息。 + +您还可以在有线网络的设置界面,编辑或新建有线网络设置。 + +#### 移动网络 + +当您处于一个没有网络信号的地方时,可以使用无线上网卡来上网。在有电话信号覆盖的任何地方,无线上网卡通过运营商的移动数据网络接入宽带服务。 + +1. 将移动网卡插入电脑上的USB接口中。 +2. 电脑将根据移动网卡和运营商信息,自动适配并自动连接网络。 +3. 在控制中心首页,单击 ![network_normal](./figures/icon97-o.svg)。 +4. 单击 **移动网络**,查看详细设置信息。 + +#### 拨号网络 + +拨号上网(DSL)是指通过本地电话拨号连接到网络的连接方式。配置好调制解调器,把电话线插入电脑的网络接口,创建宽带拨号连接,输入运营商提供的用户名和密码,即可拨号连接到Internet上。 + +##### 新建拨号连接 + +1. 在控制中心首页,单击 ![network_normal](./figures/icon97-o.svg)。 +2. 单击 **DSL**,单击 ![add](./figures/icon50-o.svg)。 +3. 输入宽带名称、帐户、密码。 +4. 单击 **保存**,系统自动创建宽带连接并尝试连接。 + +#### VPN + +VPN即虚拟专用网络,其主要功能是在公用网络上建立专用网络,进行加密通讯。无论您是在外地出差还是在家中办公,只要能上网就能利用VPN访问企业的内网资源。您还可以使用VPN加速访问其他国家的网站。 + +1. 在控制中心首页,单击 ![network_normal](./figures/icon97-o.svg)。 +2. 单击 **VPN**,选择 ![add](./figures/icon50-o.svg) 或 ![import](./figures/icon84-o.svg)。 +3. 选择VPN协议类型,并输入名称、网关、帐号、密码等信息。(导入VPN会自动填充信息) +4. 单击 **保存**,系统自动尝试连接VPN网络。 +5. 您可以将VPN设置导出,备用或共享给其他用户。 + +> ![notes](./figures/icon99-o.svg)说明:*打开 **仅用于相对应的网络上的资源** 开关,可以不将VPN设置为默认路由,只在特定的网络资源上生效。* + +#### 系统代理 + +1. 在控制中心首页,单击 ![network_normal](./figures/icon97-o.svg)。 +2. 单击 **系统代理**,进入系统代理界面。 + + - 单击 **无**,关闭代理服务器功能。 + - 单击 **手动**,输入代理服务器的地址和端口信息。 + - 单击 **自动**,输入URL,系统将自动配置代理服务器的信息。 + +#### 应用代理 + +1. 在控制中心首页,单击 ![network_normal](./figures/icon97-o.svg)。 +2. 单击 **应用代理**。 +3. 设置应用代理参数。 +4. 单击 **保存**。 + +> ![notes](./figures/icon99-o.svg)说明:*应用代理设置成功后,打开启动器,右键单击应用图标,可以选择 **使用代理**。* + +#### 网络详情 + +在网络详情界面,您可以查看MAC、IP地址、网关和其他网络信息。 + +1. 在控制中心首页,单击 ![network_normal](./figures/icon97-o.svg)。 +2. 单击 **网络详情**,进入网络信息界面。 +3. 查看当前有线网络或无线网络的信息。 + +### 声音设置 + +输入输出设备声音的设置(如设置扬声器和麦克风),让您听得更舒适,录音更清晰。 + +![0|sound](./figures/61.png) + +#### 输出设备 + +1. 在控制中心首页,单击 ![sound_normal](./figures/icon116-o.svg)。 +2. 单击 **输出**,进入输出设备配置界面,您可以: + - 在输出设备后面的下拉框中选择输出设备类型。 + - 通过拖曳滑块调节输出音量和左/右声道平衡。 + - 打开 **音量增强**,音量的可调节区间由0-100% 转变为0-150%。 + +#### 输入设备 + +1. 在控制中心首页,单击 ![sound_normal](./figures/icon116-o.svg)。 +2. 单击 **输入**,进入输入设备配置界面,您可以: + - 在输入设备后面的下拉框中选择输入设备类型。 + - 通过拖曳滑块调节输入音量。 + - 打开 **开启** 按钮,还可以设置 **噪音抑制** 功能。 + +> ![tips](./figures/icon125-o.svg)窍门:*通常,需要调大输入音量,确保能够听到声源的声音,但是音量不宜过大,因为这会导致声音失真。可以对着麦克风以正常说话的音量讲话,并观察反馈音量的变化,变化较明显,则说明输入音量合适。* + +#### 系统音效 + +1. 在控制中心首页,单击 ![sound_normal](./figures/icon116-o.svg)。 +2. 单击 **系统音效**,勾选选项,开启某一事件发生时的声音效果。 + +> ![tips](./figures/icon125-o.svg)窍门:*您可以单击试听音效。* + +### 时间日期 + +正确选择您所在的时区,一般即可显示正确的日期和时间。您也可以手动修改时间和日期。 + +![0|time](./figures/62.png) + +#### 修改时区 + +在您安装系统时,已选择了系统时区。若要修改系统时区,请按如下步骤设置。 + +1. 在控制中心首页,单击 ![time](./figures/icon124-o.svg)。 +2. 单击 **时区列表**。 +3. 单击 **修改系统时区**, 通过搜索或单击地图选择时区。 +4. 单击 **确定**。 + +#### 添加时区 + +您可以同时使用多个时区,以便查看另一时区的时间。 + +1. 在控制中心首页,单击 ![time](./figures/icon124-o.svg)。 +2. 单击 **时区列表**。 +3. 单击![add](./figures/icon50-o.svg),通过搜索或单击地图选择时区。 +4. 单击 **添加**。 + +#### 删除时区 + +1. 在控制中心首页,单击 ![time](./figures/icon124-o.svg)。 +2. 单击 **时区列表**。 +3. 单击时区列表后面的 **编辑**。 +4. 单击 ![delete](./figures/icon71-o.svg),删除已添加的时区。 + +#### 修改时间和日期 + +默认情况下,系统通过网络自动同步该时区的本地时间和日期。您也可以手动修改时间和日期。手动设置后,自动同步功能会被关闭。 + +1. 在控制中心首页,单击 ![time](./figures/icon124-o.svg)。 +2. 单击 **时间设置** 。 + - 开启或关闭自动同步配置。 + - 设置正确的时间和日期。 +3. 单击 **确定**。 + +#### 设置时间日期格式 + +支持即时设置时间日期的格式。 + +1. 在控制中心首页,单击 ![time](./figures/icon124-o.svg)。 +2. 单击 **格式设置**,可以设置星期、长短日期、长短时间等格式。 + +### 电源管理 + +对系统电源进行一些设置,让系统更安全。 + +![0|power](./figures/57.png) + +              + +#### 设置显示器关闭时间 + +1. 在控制中心首页,单击 ![power_normal](./figures/icon107-o.svg)。 +2. 单击 **使用电源**。 +3. 选择关闭显示器的时间。 + +#### 设置自动锁屏时间 + +1. 在控制中心首页,单击 ![power_normal](./figures/icon107-o.svg)。 +2. 单击 **使用电源**。 +3. 选择自动锁屏的时间。 + +#### 设置电源按钮 + +1. 在控制中心首页,单击 ![power_normal](./figures/icon107-o.svg)。 +2. 单击 **使用电源**。 +3. 选择电源按钮 **关机**、**关闭显示器** 或 **无任何操作**,更改电源设置。 + +更改设置后会即时生效,同时系统通知用户已修改电源设置。 + +### 鼠标 + +鼠标是计算机的常用输入设备。使用鼠标,可以使操作更加简便快捷。 + +![0|mouse](./figures/53.png) + +#### 通用设置 + +1. 在控制中心首页,单击 ![mouse_touchpad_normal](./figures/icon94-o.svg)。 +2. 单击 **通用**。 +3. 开启 **左手模式**,调节鼠标和触控板的**滚动速度**,**双击速度**。 + +> ![notes](./figures/icon99-o.svg)说明:*开启左手模式后,鼠标的左右键功能互换。* + +#### 鼠标设置 + +插入或连接鼠标后,在控制中心进行相关设置,让其更符合您的使用习惯。 + +1. 在控制中心首页,单击 ![mouse_touchpad_normal](./figures/icon94-o.svg)。 +2. 单击 **鼠标**。 +3. 调节 **指针速度**, 控制鼠标移动时指针移动的速度。 +4. 单击 **自然滚动** / **鼠标加速** 开关,开启相应功能。 + +> ![notes](./figures/icon99-o.svg)说明: +> +> - *开启鼠标加速,提高了指针精确度,鼠标指针在屏幕上的移动距离会根据移动速度的加快而增加。可以根据使用情况开启或关闭。* +> - *自然滚动开启后,鼠标滚轮向下滚动,内容会向下滚动;鼠标滚轮向上滚动,内容会向上滚动。* + +### 键盘和语言 + +在此模块,您可以设置键盘属性,以便符合您的输入习惯,还可以根据国家和语言调整键盘布局,设置系统语言,以及自定义快捷键。 + +![0|keyboard](./figures/59.png) + +#### 键盘属性 + +1. 在控制中心首页,单击 ![keyboard_normal](./figures/icon86-o.svg)。 +2. 单击 **通用**。 +3. 调节 **重复延迟**/**重复速度**。 +4. 单击“请在此测试”,按下键盘上的任意字符不松开,查看调节效果。 +5. 单击 **启用数字键盘**/**大写锁定提示** 开关,开启相应功能。 + +#### 键盘布局 + +设置键盘布局,可以为当前语言自定义键盘。按下键盘上的按键时,键盘布局会控制哪些字符显示在屏幕上。更改键盘布局后,屏幕上的字符可能与键盘按键上的字符不相符。 + +一般在安装系统时,就已经设置了键盘布局,您也可以添加其他的键盘布局。 + +![layout](./figures/50.png) + +##### 添加键盘布局 + +1. 在控制中心首页,单击 ![keyboard_normal](./figures/icon86-o.svg)。 +2. 单击 **键盘布局**,进入键盘布局界面。 +3. 单击![add](./figures/icon50-o.svg),单击某一键盘布局即可添加到列表。 + +##### 删除键盘布局 + +1. 在控制中心首页,单击 ![keyboard_normal](./figures/icon86-o.svg)。 +2. 单击 **键盘布局**,进入键盘布局界面。 +3. 单击”键盘布局“后的 **编辑**。 +4. 单击 ![delete](./figures/icon71-o.svg),删除该键盘布局。 + +##### 切换键盘布局 + +1. 在控制中心首页,单击 ![keyboard_normal](./figures/icon86-o.svg)。 +2. 单击 **键盘布局**,进入键盘布局界面。 +3. 选择一个键盘布局进行切换。 +4. 切换成功后,该键盘布局将标记为已选择。 + +> ![tips](./figures/icon125-o.svg)窍门:*您也可以选择一组或多组快捷键,按顺序切换已添加的键盘布局。选择 **切换方式**, 让切换后的键盘布局应用于整个系统或当前应用。* + +#### 系统语言 + +系统语言默认为您安装系统时所选择的语言,可以随时更改。 + +##### 添加系统语言 + +您可以添加多个语言到系统语言列表,以便切换系统语言。 + +1. 在控制中心首页,单击 ![keyboard_normal](./figures/icon86-o.svg)。 +2. 单击 **系统语言**,进入系统语言界面。 +3. 单击 ![add](./figures/icon50-o.svg) 进入语言列表。 +4. 选择语言,该语言将自动添加到系统语言列表。 + +##### 切换系统语言 + +1. 在控制中心首页,单击 ![keyboard_normal](./figures/icon86-o.svg)。 +2. 单击 **系统语言**,进入系统语言界面。 +3. 选择要切换的语言,系统将自动开始安装语言包。 +4. 语言包安装完成后,需要注销后重新登录,以便设置生效。 + +> ![attention](./figures/icon52-o.svg)注意:*更改系统语言后,键盘布局可能也会发生改变。重新登录时,请确保使用正确的键盘布局来输入密码。* + +#### 快捷键 + +快捷键列表显示了系统所有的快捷键。您可以在这里查看、修改和自定义快捷键。 + +![0|shortcut](./figures/59.png) + +##### 查看快捷键 + +1. 在控制中心首页,单击 ![keyboard_normal](./figures/icon86-o.svg)。 +2. 单击 **快捷键**,进入快捷键设置界面。 +3. 搜索或查看默认的系统快捷键、窗口快捷键和工作区快捷键。 + +##### 修改快捷键 + +1. 在控制中心首页,单击 ![keyboard_normal](./figures/icon86-o.svg)。 +2. 单击 **快捷键**,进入快捷键设置界面。 +3. 单击需要修改的快捷键。 +4. 使用键盘输入新的快捷键。 + +> ![tips](./figures/icon125-o.svg)窍门:*若要禁用快捷键,请按下键盘上的 ![Backspace](./figures/icon54-o.svg)。若要取消修改快捷键,按下键盘上 **Esc** 键, 或单击下方的”恢复默认”按钮。* + +##### 自定义快捷键 + +您可以为常用的应用自定义一个快捷键。 + +1. 在控制中心首页,单击 ![keyboard_normal](./figures/icon86-o.svg)。 +2. 单击 **快捷键**。 +3. 单击![add](./figures/icon50-o.svg),进入添加快捷键界面。 +4. 输入快捷键名称、命令和快捷键。 +5. 单击 **添加**。 +6. 添加成功后,单击”自定义快捷键“后的 **编辑**。 +7. 单击某个快捷键后 ![delete](./figures/icon71-o.svg), 删除自定义的快捷键。 + +> ![tips](./figures/icon125-o.svg)窍门:*若要修改快捷键,单击输入新的快捷键即可。若要修改自定义快捷键的名称和命令,单击“自定义快捷键”后的 **编辑** ,单击快捷键名称后的 ![edit](./figures/icon75-o.svg),进入修改页面。* + +### 系统信息 + +您可以查看系统版本、版本授权和电脑硬件等信息,以及该系统的一些协议。 + +![0|info](./figures/48.png) + +#### 关于本机 + +1. 在控制中心首页,单击 ![system_info_normal](./figures/icon120-o.svg)。 +2. 在 **关于本机** 下,您可以查看当前系统版本、版本授权及电脑硬件信息; +3. 若系统未激活,可在此页面单击 **激活**,进行系统激活。 + +#### 版本协议 + +1. 在控制中心首页,单击 ![system_info_normal](./figures/icon120-o.svg)。 +2. 在 **版本协议** 下,查看系统版本协议。 + +#### 最终用户许可协议 + +1. 在控制中心首页,单击 ![system_info_normal](./figures/icon120-o.svg)。 +2. 在 **最终用户许可协议** 下,查看最终用户许可协议。 + +## 键盘交互 + +您可以使用键盘在各个界面区域内切换,并选择对象,执行操作。 + +| 按键 | 功能 | +| :----------------------------------------------------------- | :----------------------------------------------------------- | +| **Tab** | 在不同区域或对话框按钮之间切换。 | +| ![Up](./figures/icon127-o.svg) ![Down](./figures/icon73-o.svg) ![Left](./figures/icon88-o.svg) ![Right](./figures/icon111-o.svg) | 在同区域内对不同的对象进行选择。使用 ![Right](./figures/icon111-o.svg) 进入下级菜单,使用 ![Left](./figures/icon88-o.svg) 返回上级菜单。使用![Up](./figures/icon127-o.svg)![Down](./figures/icon73-o.svg) 键进行上下切换 。 | +| **Enter** | 执行选定对象。 | +| **Space** | 在文件管理器中,预览选定对象;在影院和音乐中,开始/暂停播放;在下拉列表中,展开下拉选项(也可使用回车键)。 | +| **Ctrl**+**M** | 打开右键菜单。 | diff --git a/docs/en/25.03/Tools/desktop/DDE/_menu.md b/docs/en/25.03/Tools/desktop/DDE/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..4b5d381c3a6b01b92aa6bca6bdc97e9c3e2bd7f1 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/_menu.md @@ -0,0 +1,12 @@ +--- +label: 'DDE用户指南' +ismanual: 'Y' +description: '安装并使用 DDE 桌面环境' +children: + - label: '安装 DDE' + href: './installing-DDE.md' + - label: 'DDE 用户指南' + href: './DDE-user-guide.md' + - label: 'DDE 常见问题与解决方法' + href: './dde.md' +--- diff --git a/docs/en/25.03/Tools/desktop/DDE/dde.md b/docs/en/25.03/Tools/desktop/DDE/dde.md new file mode 100644 index 0000000000000000000000000000000000000000..d4f912d2c0cc7fb4b6bbe33641a7788f601e6caa --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/dde.md @@ -0,0 +1,19 @@ +# 常见问题与解决方法 + +## **问题1:安装DDE后,root帐户登录桌面无计算机和回收站图标** + +### 问题描述 + + 安装DDE后,root帐户登录桌面无计算机和回收站图标 + +![img](./figures/dde-1.png) + +### 问题原因 + + 由于root用户在安装DDE前已创建,而DDE在安装时不会对已经创建的用户进行新增桌面图标操作。DDE安装后新建用户无此问题。 + +### 解决方法 + + 用户可通过启动器中右键对应图标发送到桌面即可,无任何功能差异。 + + ![img](./figures/dde-2.png) diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/38.png b/docs/en/25.03/Tools/desktop/DDE/figures/38.png new file mode 100644 index 0000000000000000000000000000000000000000..838f5ff0616a83cdf42edb053f4e72b93bfa644e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/38.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/39.png b/docs/en/25.03/Tools/desktop/DDE/figures/39.png new file mode 100644 index 0000000000000000000000000000000000000000..12a379403d73a47b2fa564120a28fdb58d188963 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/39.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/40.png b/docs/en/25.03/Tools/desktop/DDE/figures/40.png new file mode 100644 index 0000000000000000000000000000000000000000..bf419894eab852b45604966c62fafa71f051c4df Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/40.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/41.png b/docs/en/25.03/Tools/desktop/DDE/figures/41.png new file mode 100644 index 0000000000000000000000000000000000000000..f94b0ee72e0d4e9277e9b44b4268cfbdb8402104 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/41.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/42.png b/docs/en/25.03/Tools/desktop/DDE/figures/42.png new file mode 100644 index 0000000000000000000000000000000000000000..3182e551c4e4b03885bad6339f1de514b3f55f8c Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/42.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/43.jpg b/docs/en/25.03/Tools/desktop/DDE/figures/43.jpg new file mode 100644 index 0000000000000000000000000000000000000000..26e9244f58ea9800081fd61ae135477f05b21b40 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/43.jpg differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/44.png b/docs/en/25.03/Tools/desktop/DDE/figures/44.png new file mode 100644 index 0000000000000000000000000000000000000000..c3abaecd6e053272d81e0ad9bd183c6858b4f3c5 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/44.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/45.png b/docs/en/25.03/Tools/desktop/DDE/figures/45.png new file mode 100644 index 0000000000000000000000000000000000000000..86b051acde857c88479714414f721a7f59cca483 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/45.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/46.png b/docs/en/25.03/Tools/desktop/DDE/figures/46.png new file mode 100644 index 0000000000000000000000000000000000000000..d8ec41c87628bf28c9905523f99ae93aebd13614 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/46.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/47.jpg b/docs/en/25.03/Tools/desktop/DDE/figures/47.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bf95f03c8ea0f84a878bc63af20972c9da71bc04 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/47.jpg differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/48.png b/docs/en/25.03/Tools/desktop/DDE/figures/48.png new file mode 100644 index 0000000000000000000000000000000000000000..ef21fa1ce1e2e9848a8dca16e692de673df7c6d7 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/48.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/50.png b/docs/en/25.03/Tools/desktop/DDE/figures/50.png new file mode 100644 index 0000000000000000000000000000000000000000..b86a55fe4363f56fc18befc9d27025a75ca427ad Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/50.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/51.png b/docs/en/25.03/Tools/desktop/DDE/figures/51.png new file mode 100644 index 0000000000000000000000000000000000000000..d427ac871dba9c32eb4ffe736d5352f8408da533 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/51.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/52.png b/docs/en/25.03/Tools/desktop/DDE/figures/52.png new file mode 100644 index 0000000000000000000000000000000000000000..0ca0a2db05c70bc25f9bb59e82d074f671cfc74e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/52.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/53.png b/docs/en/25.03/Tools/desktop/DDE/figures/53.png new file mode 100644 index 0000000000000000000000000000000000000000..76fbc34a1d5621b83c2d8c93222766acad33350d Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/53.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/54.png b/docs/en/25.03/Tools/desktop/DDE/figures/54.png new file mode 100644 index 0000000000000000000000000000000000000000..49ecae6f8941a118223f3765c23015df074c4983 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/54.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/56.png b/docs/en/25.03/Tools/desktop/DDE/figures/56.png new file mode 100644 index 0000000000000000000000000000000000000000..36fee795bfe593b6246c8d6c2bddea9386b06f45 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/56.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/57.png b/docs/en/25.03/Tools/desktop/DDE/figures/57.png new file mode 100644 index 0000000000000000000000000000000000000000..539d06b77b058a933cb154c43641d498050986e0 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/57.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/58.png b/docs/en/25.03/Tools/desktop/DDE/figures/58.png new file mode 100644 index 0000000000000000000000000000000000000000..396ca16d873e54505bcdbd41d669366eea7f5dee Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/58.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/59.png b/docs/en/25.03/Tools/desktop/DDE/figures/59.png new file mode 100644 index 0000000000000000000000000000000000000000..9b1de98ac4fe686937ca844d3e9481548a79ce63 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/59.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/60.jpg b/docs/en/25.03/Tools/desktop/DDE/figures/60.jpg new file mode 100644 index 0000000000000000000000000000000000000000..033c88aaadd04f7d4058ec2eb5b2c70498319bf7 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/60.jpg differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/61.png b/docs/en/25.03/Tools/desktop/DDE/figures/61.png new file mode 100644 index 0000000000000000000000000000000000000000..8df17062963a3baf92318a12ec34b1378122687b Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/61.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/62.png b/docs/en/25.03/Tools/desktop/DDE/figures/62.png new file mode 100644 index 0000000000000000000000000000000000000000..ec312d6c0c22018c1745dd866da71ce9be47fbda Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/62.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/63.jpg b/docs/en/25.03/Tools/desktop/DDE/figures/63.jpg new file mode 100644 index 0000000000000000000000000000000000000000..504f7cf59768f6fd1cd73a115d01fbc4e15a02e1 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/63.jpg differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/63.png b/docs/en/25.03/Tools/desktop/DDE/figures/63.png new file mode 100644 index 0000000000000000000000000000000000000000..86b051acde857c88479714414f721a7f59cca483 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/63.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/64.png b/docs/en/25.03/Tools/desktop/DDE/figures/64.png new file mode 100644 index 0000000000000000000000000000000000000000..cbbd2ede047e735c3766e08b04595f08cd72f5b2 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/64.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/dde-1.png b/docs/en/25.03/Tools/desktop/DDE/figures/dde-1.png new file mode 100644 index 0000000000000000000000000000000000000000..fb1d5177c39262ed182f10a57fdae850d007eeb1 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/dde-1.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/dde-2.png b/docs/en/25.03/Tools/desktop/DDE/figures/dde-2.png new file mode 100644 index 0000000000000000000000000000000000000000..be5d296937bd17b9646b32c80934aa76738027af Binary files /dev/null and b/docs/en/25.03/Tools/desktop/DDE/figures/dde-2.png differ diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon101-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon101-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..af1c5d3dc0277a6ea59e71efb6ca97bdfc782e8e --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon101-o.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon103-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon103-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..c06c885725c569ab8db1fe7d595a7c65f18c5142 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon103-o.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon105-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon105-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..36c49949fa569330b761c2d65518f36c10435508 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon105-o.svg @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon107-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon107-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..fb5a3ea756f6ccb7b3e5c31122a433347a908c96 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon107-o.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon110-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon110-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..7958e3f192061592e002e1e8a1bad06ffa86742c --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon110-o.svg @@ -0,0 +1,12 @@ + + + + reboot_normal + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon111-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon111-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..097d16a08d305a8b3f3b2268ab1ea8342e799377 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon111-o.svg @@ -0,0 +1,13 @@ + + + + Right + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon112-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon112-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..e51628c2b8b10495f3410d219814286696ea2fd5 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon112-o.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon116-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon116-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..4d79cd6dbbbfd3969f4e0ad0ad88e27398853505 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon116-o.svg @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon120-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon120-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..e895c347d16a200aea46b00428b0b9f1a3c94246 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon120-o.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon122-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon122-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..7fb014b5fd6097ca37a84d0b6a27dc982d675c8a --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon122-o.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon124-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon124-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..960c0ec096c925213f8953398f0e8e5db3cdaed3 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon124-o.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon125-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon125-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..011c05f4b8f296867cd408a339230323fcbb28dd --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon125-o.svg @@ -0,0 +1,9 @@ + + + tips + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon126-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon126-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..e0a43b6b8beb434090ac0dd3a8fd68c023f11fce --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon126-o.svg @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon127-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon127-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..bed95d35334a8d0151211054236c0bacddcc0dd3 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon127-o.svg @@ -0,0 +1,13 @@ + + + + Up + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon128-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon128-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..aa727f3f5d5883b3fb83a79c4b98e8b5bfe4ade6 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon128-o.svg @@ -0,0 +1,12 @@ + + + + userswitch_normal + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon132-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon132-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..588ba9d98864ba67a562fa9179f29405f7687aa0 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon132-o.svg @@ -0,0 +1,15 @@ + + + + - + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon134-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon134-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..784cf383eb0e8f5c7a57a602047be50ad0a3bc05 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon134-o.svg @@ -0,0 +1,15 @@ + + + + = + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon136-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon136-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..24aa139ab2fefaee20935551f1af5aef473719ed --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon136-o.svg @@ -0,0 +1,12 @@ + + + + poweroff_normal + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon49-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon49-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..72ffb173fdb95e1aff5b0001b08ed6b71122b7f2 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon49-o.svg @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon50-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon50-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..05026802be4718205065d6369e14cc0b6ef05bc7 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon50-o.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon52-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon52-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..23149c05873259cd39721b8ee9c3ab7db86d64c5 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon52-o.svg @@ -0,0 +1,9 @@ + + + attention + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon53-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon53-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..50e33489ce984b0acfd621da4a8ef837fdf048c1 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon53-o.svg @@ -0,0 +1,11 @@ + + + + previous + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon54-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon54-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..3b599aef4b822c707d2f646405bb00837aed96fd --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon54-o.svg @@ -0,0 +1,18 @@ + + + + Backspace + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon56-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon56-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..9f13b6861e3858deec8d57a5301c934acc247069 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon56-o.svg @@ -0,0 +1,19 @@ + + + + Slice 1 + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon57-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon57-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..e6fbfa1381b76ab3fcd45652b33267a7f6c69bb7 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon57-o.svg @@ -0,0 +1,11 @@ + + + + titlebutton/close_normal + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon58-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon58-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..9746dcacfc8e5d4c4b63233801e37418a190fc8f --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon58-o.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon62-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon62-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..09f61b446669df2e05a3351d40d8c30879c7b035 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon62-o.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon63-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon63-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..06c03ed99260ffadc681475dad35610aedf67f83 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon63-o.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon66-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon66-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..5793b3846b7fe6a5758379591215b16c7f9e1b52 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon66-o.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon68-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon68-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..a7748052dfa436116d8742dca28f7d90865231ed --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon68-o.svg @@ -0,0 +1,23 @@ + + + + deepin-system-monitor + Created with Sketch. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon69-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon69-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..e21dfd00a32a44ee1c8e3882b4ca8239be04690f --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon69-o.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon70-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon70-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..b5787a7ffa5ed9519a48c6937c60927fd11fd455 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon70-o.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon71-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon71-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..669a21f143b06cb45ea3f45f7f071809f2cbc8a8 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon71-o.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon72-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon72-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..79067ed9b9ff7912e1742183b461fa056601b9cc --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon72-o.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon73-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon73-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..cf6292387f5e790db6ebd66184aabcbb39257ee7 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon73-o.svg @@ -0,0 +1,13 @@ + + + + Down + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon75-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon75-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..ef6823ccc19858f57374f0b78ad31514e8311be3 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon75-o.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon83-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon83-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..35dd6eacc54a933dc9ebc3f3010edfa7363fecc0 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon83-o.svg @@ -0,0 +1,84 @@ + + + + + + image/svg+xml + + img_upload + + + + + + img_upload + Created with Sketch. + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon84-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon84-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..9bd11b9e7b45b506dd7e1c87d09d545d8f48af06 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon84-o.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon86-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon86-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..5da20233309c43d4fc7b315f441cde476c835c67 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon86-o.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon88-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon88-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..c2570c26575fd14cb5e9d9fe77831d2e8f6c9333 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon88-o.svg @@ -0,0 +1,13 @@ + + + + Left + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon90-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon90-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..79b5e0a141f7969a8f77ae61f4c240de7187afe9 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon90-o.svg @@ -0,0 +1,12 @@ + + + + lock_normal + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon92-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon92-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..21341b64a832e1935252aa82e7a4e0b083c16eae --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon92-o.svg @@ -0,0 +1,12 @@ + + + + logout_normal + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon94-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon94-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..a47044149a02101dbd24a3fdb2f3ead77efca6c1 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon94-o.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon97-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon97-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..4f4670de29d8c86885b5aa806b2c8cdc6fc16dcb --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon97-o.svg @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/25.03/Tools/desktop/DDE/figures/icon99-o.svg b/docs/en/25.03/Tools/desktop/DDE/figures/icon99-o.svg new file mode 100644 index 0000000000000000000000000000000000000000..e9a3aa60a51404c9390bfbea8d8ff09edc0e2e32 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/figures/icon99-o.svg @@ -0,0 +1,11 @@ + + + notes + + + + + + + + \ No newline at end of file diff --git a/docs/en/25.03/Tools/desktop/DDE/installing-DDE.md b/docs/en/25.03/Tools/desktop/DDE/installing-DDE.md new file mode 100644 index 0000000000000000000000000000000000000000..4a913456db07269b8eaf384150d06870ce36fbaf --- /dev/null +++ b/docs/en/25.03/Tools/desktop/DDE/installing-DDE.md @@ -0,0 +1,39 @@ +# 在 openEuler 上安装 DDE + +## 简介 + +DDE是统信软件团队研发的一款功能强大的桌面环境。包含数十款功能强大的桌面应用,是真正意义上的自主自研桌面产品。 + +## 安装方法 + +1. [下载](https://openeuler.org/zh/download/)openEuler ISO镜像并安装系统 +2. 更新软件源 + + ```bash + sudo dnf update + ``` + +3. 安装DDE + + ```bash + sudo dnf install dde + ``` + +4. 设置以图形界面的方式启动 + + ```bash + sudo systemctl set-default graphical.target + ``` + +5. 重启 + + ```bash + sudo reboot + ``` + +6. 在重启完成后,使用安装过程中创建的用户或openeuler用户登录桌面 + + > dde桌面无法使用root帐号登录 + > dde内置了openeuler用户,此用户的密码为openeuler + +现在您可以尽情的使用dde桌面了。 diff --git a/docs/en/25.03/Tools/desktop/Gnome/Gnome_userguide.md b/docs/en/25.03/Tools/desktop/Gnome/Gnome_userguide.md new file mode 100644 index 0000000000000000000000000000000000000000..6ecbf987518f00a18f0ce1f20a8eb03443ece90a --- /dev/null +++ b/docs/en/25.03/Tools/desktop/Gnome/Gnome_userguide.md @@ -0,0 +1,390 @@ +# Gnome 用户指南 + +## 一 概述 + +Gnome是运行在类Unix操作系统中最常用桌面环境。其目标是基于自由软件,为Unix或者类Unix操作系统构造一个功能完善、操作简单以及界面友好的桌面环境,是GNU计划的正式桌面。 + +Gnome提供了多个功能部件: + +ATK:可达性工具包。 + +Bonobo:复合文档技术。 + +GObject:用于C语言的面向对象框架。 + +GConf:保存应用软件设置。 + +GNOME VFS:虚拟文件系统。 + +GNOME Keyring:安全系统。 + +GNOME Print:GNOME软件打印文档。 + +GStreamer:GNOME软件的多媒体框架。 + +GTK+:构件工具包。 + +Cairo:复杂的2D图形库。 + +Human Interface Guidelines:Sun微系统公司提供的使得GNOME应用软件易于使用的研究和文档。 + +LibXML:为GNOME设计的XML库。 + +ORBit:使软件组件化的CORBAORB。 + +Pango:i18n文本排列和变换库。 + +Metacity:窗口管理器。 + +本文主要描述 Gnome 的使用。 + +界面如下图所示。 + +![图 1 桌面主界面-big](./figures/gnome-1.png) + +
+ +## 二 桌面 + +### 2.1 桌面 + +Gnome桌面比较干净,不摆放任何文件或者目录。桌面仅有顶部左、中、右三部分有入口选项。它们分别是活动程序入口、消息通知入口、系统状态入口。 + +![图 2 桌面顶部图标-big](./figures/gnome-2.png) + +### 2.2 右键菜单 + +在桌面空白处单击鼠标右键,出现的菜单如下图所示,为用户提供了一些快捷功能。 + +![图 3 右键菜单](./figures/gnome-3.png) + +选项说明如表。 + +| 选项 | 说明| +| :------------ | :------------ | +| 更换壁纸 | 更换桌面显示图像 | +| 显示设置 | 屏幕分辨率、屏幕旋转及夜间模式设置 | +| 设置 | 系统设置 | + +
+ +## 三 桌面顶部 + +### 3.1 活动程序 + +活动程序入口位于桌面左上角,其包括应用程序收藏夹、所有应用程序列表、活动程序列表、多视图切换、当前活动程序指示。 + +#### 3.1.1 应用程序收藏夹 + +![图 4 应用程序收藏夹-big](./figures/gnome-4.png) + +右键点击收藏夹内的应用程序图标,可以选择"从收藏夹中移除",从而把应用移出收藏夹。 + +#### 3.1.2 所有应用程序列表 + +点击应用程序收藏夹下面的九个小点"![](./figures/gnome-5.png)"——"显示应用程序",可打开所有应程序列表。 + +![图 5 所有应用程序列表1-big](./figures/gnome-6.png) + +右键点击列表内的应用程序图标,可以选择"添加到收藏夹",从而把应用加入收藏夹。 + +当应用程序很多并且知道其名字时,可以在搜索一栏输入应用名字进行搜索打开。 + +![图 6 所有应用程序列表2-big](./figures/gnome-7.png) + +#### 3.1.3 活动程序列表 + +当多个程序打开,即存在多个活动程序时,活动程序会在收藏夹内最后一个应用程序后逐个显示。打开的程序其下有个点表示已打开。 + +![图 7 活动程序列表-big](./figures/gnome-8.png) + +右键单击活动程序,可以弹出活动状态下此程序可以进行的一些操作,不同的程序可执行的操作不同。以"截图"程序为例,如图所示。 + +![图 8 活动程序右键菜单-big](./figures/gnome-9.png) + +#### 3.1.4 多视图切换 + +查看活动程序列表的同时,活动程序也以多视图方式显示在活动程序列表右侧。 + +![图 9 多视图切换1-big](./figures/gnome-10.png) + +鼠标移到多视图右侧,右侧竖条将会变宽,显示当前桌面处于顶层的活动程序窗口和桌面。点击桌面图像将会切换回桌面。 + +![图 10 多视图切换2-big](./figures/gnome-11.png) + +点击不属于当前活动程序的其他程序,则顶层切换到相应应用程序。 + +#### 3.1.5 当前活动程序指示 + +当前活动程序的指示会显示在活动程序入口右侧,并且点击可弹出活动状态下此程序可以进行的一些操作,不同的程序可执行的操作不同。以"终端"程序为例,如图所示。 + +![图 11 当前活动程序指示-big](./figures/gnome-12.png) + +点击"首选项"可对终端进行设置。 + +### 3.2 消息通知 + +消息通知入口位于桌面顶部中央,其包括消息通知、日历、时钟和天气。 + +![图 12 消息通知-big](./figures/gnome-13.png) + +#### 3.2.1 消息通知 + +当在"时钟"程序中设置闹钟和倒计时,定时到了后都会将消息通知到消息通知入口的左侧。在"日历"程序中设置的待办事项,详细信息也会显示到左侧消息通知,其概要信息将会显示到右侧日历下方。 + +![图 13 消息-big](./figures/gnome-14.png) + +点击"请勿打扰"可以关闭这些消息在外部(没有点击此入口之前)的弹窗通知。 + +#### 3.2.2 日历 + +如上图,右侧显示日历,对于有待办事项的日期,其下会有一个点。点击这些日期,可在日历下方看到待办事项概要信息。 + +#### 3.2.3 时钟和天气 + +可以把时钟和天气添加到右下角连同日历一并作信息显示。点击时钟位置将调用"时钟"程序并使用其"世界时钟"的功能,点击"天气"将调用"天气"程序。 + +![图 14 时钟和天气-big](./figures/gnome-15.png) + +### 3.3 系统状态 + +系统状态入口位于桌面右上角,其包括多个选项,部分说明如表。 + +| 选项 | 说明| +| :------------ | :------------ | +| 声音 | 音量调节 | +| 以太网 | 以太网卡及其连接状况 | +| 定位服务 | 系统所在设置 | +| 设置 | 系统设置 | +| 锁定 | 立即锁屏,再次打开需要密码 | +| 关机/注销 | 包括挂起、关机、重启、注销四种动作 | + +![图 15 系统状态-big](./figures/gnome-16.png) + +不同的设置和系统配置此处显示的系统状态也有所不同,例如wifi,蓝牙,电池。系统状态还可以由其他程序追加到右上角左侧,例如上图中输入源相关的显示。 + +#### 3.3.1 声音 + +快捷的音量调节设置。如要进一步设置声音需要打开系统设置。 + +#### 3.3.2 网络 + +快捷的网络禁用与否设置。如要进一步设置网络需要打开系统设置。 + +![图 16 网络状态-big](./figures/gnome-17.png) + +#### 3.3.3 定位服务 + +快捷的定位服务禁用与否设置。如要进一步设置定位需要打开系统设置。 + +![图 17 定位状态-big](./figures/gnome-18.png) + +#### 3.3.4 设置 + +便捷的系统设置入口之一。 + +![图 18 设置1-big](./figures/gnome-19.png) + +系统设置可以设置数量众多系统相关的选项,除了上图左侧已经展示的项,余下的项如下图左侧。 + +![图 19 设置2-big](./figures/gnome-20.png) + +设置项也是动态拓展的,例如当系统所在的硬件有wifi时,wifi的设置项将会出现在设置中。一些重要的设置项将在下文中举例。 + +#### 3.3.4 锁定 + +点击"锁定"将立即回到锁屏界面并黑屏,鼠标移动立马亮屏,点击任意按键进入登录界面,并需要用户密码输入以实现再次登录。以下是锁屏界面。 + +![图 20 锁屏界面-big](./figures/gnome-21.png) + +#### 3.3.4 关机/注销 + +包括挂起、关机、重启、注销四种动作。其中挂起和锁定的区别在于挂起后直接黑屏,需要使用键盘唤醒到登录界面,时间较锁屏久。注销是登出当前用户,退回到登录界面并且不黑屏,以选择另外的用户登录或者相同用户再次登录。 + +![图 21 关机_注销-big](./figures/gnome-22.png) + +以下是用户登录界面。 + +![图 22 登录界面-big](./figures/gnome-23.png) + +锁定和挂起唤醒后首先进入锁屏界面,再次的按钮或者按键才进入用户登录界面。注销和重启后直接进入登录界面。 + +
+ +## 四 常用系统设置和应用举例 + +### 4.1 系统设置举例 + +系统设置有四个个入口,分别是: + +桌面右键->设置 + +右上角系统状态入口->设置 + +左上角活动程序入口->设置 + +在终端中->执行gnome-control-center + +#### 4.1.1 网络 + +![图 23 网络设置1-big](./figures/gnome-19.png) + +这里显示有线网络,点击按钮可以打开和关闭网络。还可以设置vpn和网络代理。 + +点击以太网的某个连接右侧的小齿轮,可查看此连接的详细信息,也可对此连接进行修改,包括移除此连接。 + +![图 24 网络设置2-big](./figures/gnome-24.png) + +修改此连接名字。 + +![图 25 网络设置3-big](./figures/gnome-25.png) + +修改ip地址获取方式(自动,手动),添加DNS,添加路由等。 + +![图 26 网络设置4-big](./figures/gnome-26.png) + +点击小齿轮上的"+"号,可以从头创建一个连接,新连接的设置项和上图类似,前提是这个以太网口要存在。 + +#### 4.1.2 显示器 + +固定分辨率设置可在"显示器"一项进行配置,如果这里不包含你的硬件系统的分辨率,那么需要在命令设置好分辨率,再打开此处设置,新加入的分辨率将会显示在这里。 + +![图 27 分辨率设置-big](./figures/gnome-27.png) + +选择分辨率后点击弹出的"保留更改"以使设置生效。 + +![图 28 分辨率设置确认-big](./figures/gnome-28.png) + +有些显示器允许旋转以便竖向观察屏幕,例如文本可以一次查看到更底部的内容。这里的"方向"也提供支持。 + +![图 29 屏幕方向-big](./figures/gnome-29.png) + +#### 4.1.3 键盘快捷键 + +设置键盘快捷键可以执行快捷的操作,例如快速打开主目录,摄像头或者浏览器等。gnome没有为打开终端设置快捷键,可以考虑设置打开终端的默认快捷键。 + +已有的快捷键设置可以滚动查看也可以进行搜索。 + +![图 30 键盘快捷键-big](./figures/gnome-30.png) + +单击已禁用的项,例如主目录和网页浏览器,可以触发快捷键设置。 + +![图 31 快捷键设置-big](./figures/gnome-31.png) + +![图 32 快捷键设置反馈-big](./figures/gnome-32.png) + +设置成功后的效果。 + +![图 33 快捷键设置结果-big](./figures/gnome-33.png) + +拖动"键盘快捷键"设置到底部,点击"+"新加一个打开终端的快捷键。 + +![图 34 快捷键添加设置1-big](./figures/gnome-34.png) + +![图 35 快捷键添加设置2-big](./figures/gnome-35.png) + +![图 36 快捷键添加设置3-big](./figures/gnome-36.png) + +![图 37 快捷键添加设置结果-big](./figures/gnome-37.png) + +按住“ctrl+alt+t”可打开终端。主目录和网页浏览器与此相似。 + +![图 38 快捷键测试-big](./figures/gnome-38.png) + +#### 4.1.4 区域和语言 + +系统语言可以在多种语言间切换,即使安装系统时没有选择这种语言。 + +![图 39 区域和语言-big](./figures/gnome-39.png) + +点击语言和格式选择,可以把语言从中文换为英文,并反馈重启按钮,需要重新登录重启会话设置才能生效。 + +![图 40 语言设置-big](./figures/gnome-40.png) + +![图 41 格式设置-big](./figures/gnome-41.png) + +![图 42 语言和格式设置结果-big](./figures/gnome-42.png) + +点击"输入源"右侧的小齿轮可以查看到输入法的快捷键以及输入源选项设置。点击其下方的"+"可以添加输入源。 + +![图 43 输入设置-big](./figures/gnome-43.png) + +当使用快捷键切换输入法时,可以在右上角系统状态处查看到变化。 + +![图 44 输入切换结果查看-big](./figures/gnome-44.png) + +#### 4.1.5 用户 + +可以在图形界面添加和删除用户。使用非root用户登录时,此项功能需要点击"解锁",输入超级权限用户的密码才能显示完整。 + +![图 45 用户-big](./figures/gnome-45.png) + +点击密码可以修改当前用户的密码。 + +![图 46 修改用户密码-big](./figures/gnome-46.png) + +点击帐号活动可以看到本周的此用户的登录状况。 + +![图 47 用户活动记录-big](./figures/gnome-47.png) + +点击右上角添加用户可以添加一个新用户并在添加用户时设置密码或者在登录时设置密码。登录新用户需要先登出当前用户再选择新用户登录。新加的用户可以在"移除用户"移除,当然,不能移除当前登录的用户。 + +![图 48 添加新用户-big](./figures/gnome-48.png) + +### 4.2 应用举例 + +#### 4.2.1 文件 + +"文件"应用的二进制文件名为nautilus。可在"文件"所图形化显示的文件系统内创建、修改、移动、保存和删除文件等操作。 + +![图 49 文件系统主目录-big](./figures/gnome-49.png) + +#### 4.2.2 终端 + +运行的"终端"是gnome登录会话下的特殊进程,它相当于一个控制台,本质是一个新的会话。它几乎能完成控制台能完成的所有任务,这是没有图形界面的linux原本的样子。 + +![图 50 终端及其设置项-big](./figures/gnome-50.png) + +在其"配置文件首选项"中能对字体、字符间隔、主题背景等选项进行设置。 + +#### 4.2.3 软件 + +"软件"内能搜索安装许多开源免费的应用,也能查看和卸载当前已经安装的程序。 + +![图 51 软件-big](./figures/gnome-51.png) + +![图 52 已安装-big](./figures/gnome-52.png) + +#### 4.2.4 浏览器 + +gnome自带了名为"Web"的浏览器,其界面和功能较google或者firefox浏览器要简单,但是常见的书签、搜索引擎设置、历史记录、文件下载等均支持。 + +![图 53 浏览器-big](./figures/gnome-53.png) + +#### 4.2.5 系统监视器 + +相当于windows下的任务管理器,可以看到进程名字、用户、cpu和内存等资源的使用状况。这个是动态的,不过其变化效果远逊于top命令。 + +![图 54 进程-big](./figures/gnome-54.png) + +还可以看到cpu,内存,网络等重要部件的利用率走势。 + +![图 55 资源-big](./figures/gnome-55.png) + +#### 4.2.6 文本编辑器 + +创建、修改、保存文件等操作需要文本编辑器。在其菜单栏的"首选项"中可进行字体、制表符宽度、主题、插件等选项进行设置。 + +![图 56 文本编辑器-big](./figures/gnome-56.png) + +#### 4.2.7 Sysprof + +这是对系统包括软硬件的采样和呈现,这可以用来定位系统的性能问题,例如应用启动卡顿,系统响应延迟等。点击选择要跟踪的项目并点击"Record",便开始采样。 + +![图 57 采样对象选择-big](./figures/gnome-57.png) + +![图 58 开始记录-big](./figures/gnome-58.png) + +停止采样后,采样结果提供了非常丰富的信息,可用于诊断和分析。 + +![图 59 采样结果-big](./figures/gnome-59.png) diff --git a/docs/en/25.03/Tools/desktop/Gnome/_menu.md b/docs/en/25.03/Tools/desktop/Gnome/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..574d6312ada5c19697969e6ac618f26cca51e378 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/Gnome/_menu.md @@ -0,0 +1,10 @@ +--- +label: 'Gnome用户指南' +ismanual: 'Y' +description: '安装并使用 Gnome 桌面环境' +children: + - label: '安装 Gnome' + href: './installing-GNOME.md' + - label: 'Gnome 用户指南' + href: './Gnome_userguide.md' +--- diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-1.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-1.png new file mode 100644 index 0000000000000000000000000000000000000000..b33f802aa6dcf8b23a70fe451830015c614193b3 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-1.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-10.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-10.png new file mode 100644 index 0000000000000000000000000000000000000000..1c7b1465209c7a92db36d1b4c83445ce45e0d187 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-10.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-11.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-11.png new file mode 100644 index 0000000000000000000000000000000000000000..cc534ce5e1b250547dd9eb1db2b3f43a79c00409 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-11.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-12.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-12.png new file mode 100644 index 0000000000000000000000000000000000000000..65de953b821cac6b09b9f0d6623760dc339d867b Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-12.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-13.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-13.png new file mode 100644 index 0000000000000000000000000000000000000000..103370de2f2d81fe4e880f18bb9a3b4546d14840 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-13.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-14.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-14.png new file mode 100644 index 0000000000000000000000000000000000000000..13e1367d6ce006567e69fed8fd334aeb4810196c Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-14.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-15.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-15.png new file mode 100644 index 0000000000000000000000000000000000000000..fb86a36e2eb9c5ccfb3c53b0c49864e73c622ccf Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-15.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-16.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-16.png new file mode 100644 index 0000000000000000000000000000000000000000..9b375517e433740b7e2c27ede1159cda1eb986b8 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-16.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-17.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-17.png new file mode 100644 index 0000000000000000000000000000000000000000..ebfcc9c71afeda1d50b5355f23ec1ea422a17889 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-17.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-18.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-18.png new file mode 100644 index 0000000000000000000000000000000000000000..5d28c8372499dd2b9b71186dee7d4854b5320999 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-18.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-19.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-19.png new file mode 100644 index 0000000000000000000000000000000000000000..bea391d41386ab9b7953b269c44aec6cba4667c5 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-19.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-2.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-2.png new file mode 100644 index 0000000000000000000000000000000000000000..520df0228a38914ca7897dec6dc84e9639b757c0 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-2.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-20.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-20.png new file mode 100644 index 0000000000000000000000000000000000000000..d720a2c215de4172a8051d7e0554c7f6b3d6d043 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-20.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-21.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-21.png new file mode 100644 index 0000000000000000000000000000000000000000..dec78c390a65a1e707a5c9620fa3392e38124430 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-21.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-22.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-22.png new file mode 100644 index 0000000000000000000000000000000000000000..d8564596fd8ada47891a28b8fd97915722b28ff9 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-22.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-23.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-23.png new file mode 100644 index 0000000000000000000000000000000000000000..6fcb86d0b74acd102bc4e19bd483165fca0921bc Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-23.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-24.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-24.png new file mode 100644 index 0000000000000000000000000000000000000000..692929de10b612af7e15ddef689a611b7f4e8693 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-24.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-25.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-25.png new file mode 100644 index 0000000000000000000000000000000000000000..793a5a2d3ec63581902da5d4b8863f9ba33675b8 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-25.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-26.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-26.png new file mode 100644 index 0000000000000000000000000000000000000000..4d3f5418352e644f56a16099a9c77218045dabab Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-26.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-27.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-27.png new file mode 100644 index 0000000000000000000000000000000000000000..908998f4c4624e8b3317a311643123f690153325 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-27.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-28.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-28.png new file mode 100644 index 0000000000000000000000000000000000000000..8b47b2397fa8818dfecbc3c05341e31d4d70a940 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-28.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-29.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-29.png new file mode 100644 index 0000000000000000000000000000000000000000..fc90cb58691e6484b6e263f4e81a1046e3adbed1 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-29.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-3.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-3.png new file mode 100644 index 0000000000000000000000000000000000000000..4d423b13941604a29ff794817ed6fb1d6fea9c1e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-3.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-30.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-30.png new file mode 100644 index 0000000000000000000000000000000000000000..8f4ab5dcd8ebd61b05a1b129b4c90e342f97e0fd Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-30.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-31.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-31.png new file mode 100644 index 0000000000000000000000000000000000000000..93159341a996153105985451fa6d8391c358b52e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-31.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-32.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-32.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ca5695e67a4a585f0ff074cd3645a32a9e4e83 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-32.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-33.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-33.png new file mode 100644 index 0000000000000000000000000000000000000000..e0b166e013144ed7e5f26c2b7bd7e8a00ac6a57f Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-33.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-34.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-34.png new file mode 100644 index 0000000000000000000000000000000000000000..dc8653255f8782ab72b8a24eeadff8fe64f88bb1 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-34.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-35.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-35.png new file mode 100644 index 0000000000000000000000000000000000000000..595c8d76ddc857ed9e76d421cf1e755874a6cc4a Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-35.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-36.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-36.png new file mode 100644 index 0000000000000000000000000000000000000000..f5a22198f57d34fe05336d88c6e4b288ed78dc8e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-36.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-37.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-37.png new file mode 100644 index 0000000000000000000000000000000000000000..1a855eee24e959c3e8bfed371d2f74f93fceda3c Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-37.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-38.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-38.png new file mode 100644 index 0000000000000000000000000000000000000000..e80fcb9c25299130ca94bef2cdce9d5e7f9ba02c Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-38.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-39.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-39.png new file mode 100644 index 0000000000000000000000000000000000000000..29843d242f260cd1b722fdcc13cef645a3679e7f Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-39.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-4.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-4.png new file mode 100644 index 0000000000000000000000000000000000000000..04391e2e926d5195b21d7e05dc5322a0d7646ad6 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-4.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-40.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-40.png new file mode 100644 index 0000000000000000000000000000000000000000..8497bdd58dffe2210fca22d01912f82b5c39fd9c Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-40.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-41.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-41.png new file mode 100644 index 0000000000000000000000000000000000000000..a4357eb95c379dfecc1d627c59eb5da660d42d14 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-41.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-42.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-42.png new file mode 100644 index 0000000000000000000000000000000000000000..bc01808fe7c12d7d433dc1da9367e858027fcce9 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-42.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-43.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-43.png new file mode 100644 index 0000000000000000000000000000000000000000..467e52cf41a32df9c7207417817f906b518c54c3 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-43.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-44.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-44.png new file mode 100644 index 0000000000000000000000000000000000000000..71303b84fce85478ccba02b10f6c0358c5bdc2a0 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-44.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-45.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-45.png new file mode 100644 index 0000000000000000000000000000000000000000..a0927659af30d18715ab8b43266de3f54a3142a0 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-45.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-46.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-46.png new file mode 100644 index 0000000000000000000000000000000000000000..ad2093e67041d656c25a5674a6e4282c804ec6f2 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-46.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-47.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-47.png new file mode 100644 index 0000000000000000000000000000000000000000..9a67dd6b3b0081fa858b4beed0cc40708d5418e9 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-47.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-48.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-48.png new file mode 100644 index 0000000000000000000000000000000000000000..8789fcb96ee2143eae12131b07acf1cfbd82cf41 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-48.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-49.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-49.png new file mode 100644 index 0000000000000000000000000000000000000000..e5df514480c825a5c65b607721d80cf59642b4a1 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-49.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-5.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-5.png new file mode 100644 index 0000000000000000000000000000000000000000..b7148601f06fcee9517864aca19ba3cee863ba33 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-5.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-50.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-50.png new file mode 100644 index 0000000000000000000000000000000000000000..7b1f4678846cb691b144b26f24bc5570961a3d7d Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-50.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-51.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-51.png new file mode 100644 index 0000000000000000000000000000000000000000..10466de4bbd4c7b31654bb1369a9a85a20e88a27 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-51.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-52.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-52.png new file mode 100644 index 0000000000000000000000000000000000000000..16c8191ae59475d46cd7c275ad3841419544397d Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-52.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-53.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-53.png new file mode 100644 index 0000000000000000000000000000000000000000..b968bbd5c5df6148ef26c8cf292e040220987554 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-53.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-54.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-54.png new file mode 100644 index 0000000000000000000000000000000000000000..6f169f432a1ad4290b3fca12b1a835330d922ab0 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-54.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-55.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-55.png new file mode 100644 index 0000000000000000000000000000000000000000..e40794fbf2e23e3496ac7f9352abe84ac943cb8c Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-55.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-56.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-56.png new file mode 100644 index 0000000000000000000000000000000000000000..d66360c2865ba03e7f2959612b2e33061dfad39f Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-56.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-57.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-57.png new file mode 100644 index 0000000000000000000000000000000000000000..f2ffff79898f36e290bb133efc36c7439d089f57 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-57.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-58.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-58.png new file mode 100644 index 0000000000000000000000000000000000000000..2eb30604a6dc2a4194da688830f88d0e596c5be9 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-58.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-59.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-59.png new file mode 100644 index 0000000000000000000000000000000000000000..9b25d253604f353b0bd3ef0c153237d74459ccae Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-59.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-6.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-6.png new file mode 100644 index 0000000000000000000000000000000000000000..3c54d7f40cb5caab2c3cecb9945f9c89a1afe00e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-6.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-7.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-7.png new file mode 100644 index 0000000000000000000000000000000000000000..fa4b0e178fb0332d334d98e0106746b7bff65449 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-7.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-8.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-8.png new file mode 100644 index 0000000000000000000000000000000000000000..5c39bb44371d94a66c66e053a7f498b46d3a0937 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-8.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-9.png b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-9.png new file mode 100644 index 0000000000000000000000000000000000000000..00a9ad1a7c94054c9418795c39b29574bfe16bf0 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Gnome/figures/gnome-9.png differ diff --git a/docs/en/25.03/Tools/desktop/Gnome/installing-GNOME.md b/docs/en/25.03/Tools/desktop/Gnome/installing-GNOME.md new file mode 100644 index 0000000000000000000000000000000000000000..7c76091a2920036eb920da19e34628dfedd7fa42 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/Gnome/installing-GNOME.md @@ -0,0 +1,123 @@ +# 在 openEuler 上安装 Gnome + +GNOME是运行在类Unix操作系统中最常用桌面环境。是一个功能完善、操作简单,界面友好,集使用和开发为一身的桌面环境,是GNU计划的正式桌面。 + +从用户的角度看,GNOME是一个集成桌面环境和应用程序的套件。从开发者的角度看,它是一个应用程序开发框架(由数目众多的实用函数库组成)。即使用户不运行GNOME桌面环境,用GNOME编写的应用程序也可以正常运行。 + +GNOME既包含文件管理器,应用商店,文本编辑器等基础软件,也包含系统采样分析,系统日志,软件工程IDE,web浏览器,简洁虚拟机监视器,开发者文档浏览器等高级应用和工具。 + +安装时,建议新建一个管理员用户。 + +1. [下载](https://openeuler.org/zh/download/)openEuler ISO镜像并安装系统,更新软件源(需要配置Everything源,以及EPOL源,下面命令是在最小化安装系统的情况下安装GNOME)。 + + ```sh + sudo dnf update + ``` + +2. 安装字库。 + + ```sh + sudo dnf install dejavu-fonts liberation-fonts gnu-*-fonts google-*-fonts + ``` + +3. 安装Xorg。 + + ```sh + sudo dnf install xorg-* + ``` + + 这可能会安装很多没用的包,可以使用下面的命令安装必要的xorg相关包。 + + ```sh + sudo dnf install xorg-x11-apps xorg-x11-drivers xorg-x11-drv-ati \ + xorg-x11-drv-dummy xorg-x11-drv-evdev xorg-x11-drv-fbdev xorg-x11-drv-intel \ + xorg-x11-drv-libinput xorg-x11-drv-nouveau xorg-x11-drv-qxl \ + xorg-x11-drv-synaptics-legacy xorg-x11-drv-v4l xorg-x11-drv-vesa \ + xorg-x11-drv-vmware xorg-x11-drv-wacom xorg-x11-fonts xorg-x11-fonts-others \ + xorg-x11-font-utils xorg-x11-server xorg-x11-server-utils xorg-x11-server-Xephyr \ + xorg-x11-server-Xspice xorg-x11-util-macros xorg-x11-utils xorg-x11-xauth \ + xorg-x11-xbitmaps xorg-x11-xinit xorg-x11-xkb-utils + ``` + +4. 安装GNOME及组件。 + + ```sh + sudo dnf install adwaita-icon-theme atk atkmm at-spi2-atk at-spi2-core baobab \ + abattis-cantarell-fonts cheese clutter clutter-gst3 clutter-gtk cogl dconf \ + dconf-editor devhelp eog epiphany evince evolution-data-server file-roller folks \ + gcab gcr gdk-pixbuf2 gdm gedit geocode-glib gfbgraph gjs glib2 glibmm24 \ + glib-networking gmime30 gnome-autoar gnome-backgrounds gnome-bluetooth \ + gnome-boxes gnome-builder gnome-calculator gnome-calendar gnome-characters \ + gnome-clocks gnome-color-manager gnome-contacts gnome-control-center \ + gnome-desktop3 gnome-disk-utility gnome-font-viewer gnome-getting-started-docs \ + gnome-initial-setup gnome-keyring gnome-logs gnome-menus gnome-music \ + gnome-online-accounts gnome-online-miners gnome-photos gnome-remote-desktop \ + gnome-screenshot gnome-session gnome-settings-daemon gnome-shell \ + gnome-shell-extensions gnome-software gnome-system-monitor gnome-terminal \ + gnome-tour gnome-user-docs gnome-user-share gnome-video-effects \ + gnome-weather gobject-introspection gom grilo grilo-plugins \ + gsettings-desktop-schemas gsound gspell gssdp gtk3 gtk4 gtk-doc gtkmm30 \ + gtksourceview4 gtk-vnc2 gupnp gupnp-av gupnp-dlna gvfs json-glib libchamplain \ + libdazzle libgdata libgee libgnomekbd libgsf libgtop2 libgweather libgxps libhandy \ + libmediaart libnma libnotify libpeas librsvg2 libsecret libsigc++20 libsoup \ + mm-common mutter nautilus orca pango pangomm libphodav python3-pyatspi \ + python3-gobject rest rygel simple-scan sushi sysprof tepl totem totem-pl-parser \ + tracker3 tracker3-miners vala vte291 yelp yelp-tools \ + yelp-xsl zenity + ``` + +5. 启动gdm显示管理器。 + + ```sh + sudo systemctl enable gdm + ``` + +6. 设置系统默认以图形界面登录。 + + ```sh + sudo systemctl set-default graphical.target + ``` + + 重启验证。 + + ```sh + sudo reboot + ``` + +7. 当gdm不能工作 + + 如果默认安装了gdm,则停用gdm + + ```sh + sudo systemctl disable gdm + ``` + + 安装lightdm显示管理器替代 + + ```sh + sudo dnf install lightdm lightdm-gtk + ``` + + 设置默认桌面为GNOME,通过root权限用户设置 + + ```sh + echo 'user-session=gnome' >> /etc/lightdm/lightdm.conf.d/60-lightdm-gtk-greeter.conf + ``` + + 启动lightdm显示管理器 + + ```sh + sudo systemctl enable lightdm + ``` + + 设置系统默认以图形界面登录 + + ```sh + sudo systemctl set-default graphical.target + ``` + + 重启验证 + + ```sh + sudo reboot + ``` diff --git a/docs/en/25.03/Tools/desktop/Kiran/Kiran_userguide.md b/docs/en/25.03/Tools/desktop/Kiran/Kiran_userguide.md new file mode 100644 index 0000000000000000000000000000000000000000..c3ca4f6ace4bf9e3d65b3ec59bcc9a61229930f9 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/Kiran/Kiran_userguide.md @@ -0,0 +1,325 @@ +# Kiran桌面环境用户手册 + +## 1.概述 + +Kiran桌面是一款以用户和市场需求为主导的稳定、高效、易用的桌面环境,主要包括了桌面、任务栏、托盘、控制中心和窗口管理等组件。本文介绍了Kiran桌面的使用。 + +## 2.桌面 + +### 2.1.登录界面 + +安装完成后重启系统,系统启动后需要输入登录的用户名和密码才能进入系统,登录界面会显示时间日期,电源按钮,软键盘按钮。界面支持自适应调整,支持屏幕放缩,支持多屏显示,登录框可以跟随鼠标进行屏幕切换。 + +![图1-登录界面](figures/kiran-1.png) + +### 2.2.主界面 + +输入正确的用户名和密码后即可登录系统进入主界面,如下图所示: + +![图2-主界面](figures/kiran-2.png) + +桌面上放置有几个图标,如计算机、主文件夹、回收站等,位于屏幕底部的一个长条称为面板,从这里可以启动应用程序或在模拟桌面上切换。 +桌面是用户的工作区域,用户操作和程序运行都是在桌面上。桌面上还有用户希望能方便访问的文件和应用程序图标,用鼠标双击可以运行相应程序或打开文件。可以拖动、添加或删除桌面图标。使用桌面图标可以更加便捷地完成工作。 + +![图3-计算机](figures/kiran-3.png)计算机:双击可以显示从本计算机访问的所有本地和远程磁盘和文件夹。 + +![图4-主文件夹](figures/kiran-4.png)主文件夹:双击可以显示/root(家目录)下的内容。 + +![图5-回收站](figures/kiran-5.png)回收站:暂时存放已删除文件的地方。 + +桌面右键:提供了创建文件夹、创建启动器、创建文档、更改桌面背景、图标保持对齐等快捷方式。 + +创建文件夹:可以创建新的文件夹。 + +创建启动器:可以创建一个新的启动器。 + +创建文档:可以创建空的纯文本文档。 + +按名称组织桌面:按名称来进行排序桌面文件。 + +保持对齐:勾选了保持对齐,桌面图标会按照网格对齐排列。 + +打开终端:直接打开终端应用。 + +更改桌面背景:打开“背景”,以改变桌面或锁屏的背景图片。 + +### 2.3.面板 + +面板通常位于屏幕的底部,上面包括了开始菜单按钮、快速启动区域、经常使用的应用程序与桌面小程序图标和显示当前运行应用程序的任务条。 +将鼠标停在某个图标上呆几秒钟,会看到一个白色的弹出提示框,内容是对这个图标作用的描述。 + +![图6-系统面板](figures/kiran-6.png) + +## 3.任务栏 + +任务栏:显示正在运行的程序或打开的文档,点击任务条上某一项可以最大化或最小化被选中的程序。可以通过在对应项上点击鼠标右键对其运行窗口进行最大化、最小化或关闭等操作。 + +| 组件 | 说明 | +| :------------ | :------------ | +|![图7-开始菜单](figures/kiran-7.png)|开始菜单按钮:相当于Windows中的开始按钮,单击会弹出系统级联的开始菜单| +|![图8-工作区按钮](figures/kiran-8.png)|单机此按钮启动工作区| +|![图9-文件浏览器按钮](figures/kiran-9.png)|单击此按钮启动文件浏览器,可浏览管理文件| +|![图10-终端命令按钮](figures/kiran-10.png)|单击将启动终端| +|![图11-Web浏览器按钮](figures/kiran-11.png)|单击此按钮启动firefox浏览器| +|![图12-网络控制图标](figures/kiran-12.png)|显示当前网络状态,单击可修改系统的网络配置| +|![图13-时钟按钮](figures/kiran-13.png)|显示当前日期和时间,可以根据需要定制显示的样式| + +## 4.控制中心 + +### 4.1.开始菜单设置 + +选择“开始菜单”>“控制中心”>“开始菜单设置”。 +开始菜单可设置开始菜单样式,根据个人喜好设置开始菜单的显示模式与不透明度,如图所示: + +![图14-开始菜单设置](figures/kiran-14.png) + +开始菜单根据设置的透明度、显示模式而更改,如下图: + +![图15-开始菜单界面](figures/kiran-15.png) + +### 4.2.登录设置 + +选择“开始菜单”>“控制中心”>“登录设置”打开。 +在kiran桌面,用户可以通过选择控制中心中的登录设置对登录界面环境效果进行设置,其中包括登录界面背景图、是否自动登录、缩放比例、是否允许手动输入用户名登录、是否显示用户列表等,如图所示: + +![图16-登录设置](figures/kiran-16.png) + +还可以设置自动登录,设置自动登录的用户和延时,重启系统后会自动登录该用户,无需输入密码。 + +![图17-设置自动登录](figures/kiran-17.png) + +### 4.3.显示设置 + +定制显示属性是每个桌面系统所必备的,kiran桌面提供了强大的显示属性定制工具。您可以通过选择“开始菜单”>“控制中心”>“显示设置”进入显示设置界面,如下图所示: + +![图18-显示设置](figures/kiran-18.png) + +这里可以设置屏幕旋转、分辨率、刷新率、缩放率和旋转,设置完成后点击“应用”即可。 + +### 4.4.鼠标设置 + +用户可以通过选择控制中心中的“鼠标设置”对鼠标进行配置,可以修改鼠标手持模式为左手和右手模式,调整鼠标移动速度,可以设置是否自动滚动,是否同时按下左右键模拟中键功能。鼠标设置常见界面如图所示: + +![图19-鼠标设置](figures/kiran-19.png) + +### 4.5.账户管理工具 + +账户管理工具工具是对用户和组进行管理的一个简单易用工具,您可以通过这个工具对用户和组群进行配置和管理,主要包括: +1)增加用户,设置用户属性; +2)修改用户属性; +3)显示用户属性; +4)删除用户; +用户属性包括:账号、口令(密码)、登录 shell,用户组属性指在该组包含哪些用户。 + +#### 4.5.1.启动账户管理工具 + +在控制中心中选择启动“账户管理工具”选项即可启动账户管理工具,如图所示: + +![图20-账户管理工具](figures/kiran-20.png) + +在这个界面中您可以看到有左侧菜用户栏和右侧详细信息栏两个部分。目前在列出的是系统中的所有用户(除root用户除外)。点击左侧某个用户,详细信息栏将显示用户的基本信息(用户ID、用户类型等)。 +点击“创建用户”,在右侧出现页面,如下图所示,按照要求填写您要添加的用户名、用户类型、设置密码、头像。填写完毕后,单击“创建”即完成添加。 + +![图21-创建账户](figures/kiran-21.png) + +【注】:如果您已经设置了密码允许的最小位数(例如四位),则您在此处输入的密码位数要不小于 4 位,否则系统将不会接受该密码。 + +单击头像区域打开头像修改功能,系统预设了各种类型的头像供用户选择,用户也可以自己添加头像,点击“确认”后记得保存: + +![图22-修改头像](figures/kiran-22.png) + +#### 4.5.2.删除用户 + +首先在左侧信息栏里的欲删除的用户上单击,选中该用户,然后在右侧工具栏上点击“删除”按钮,如下图所示: + +![图23-删除用户](figures/kiran-23.png) + +![图24-删除确认提示](figures/kiran-24.png) + +在弹出上图所示的对话框中单击“否”撤消删除,单击“是”确认删除。 + +#### 4.5.3.高级设置 + +选择“创建新用户”>“输入账号密码”>“高级设置”,打开一个对话框,如下图所示,可以设置用户的登录shell、指定用户ID和指定用户目录。 + +![图25-高级设置](figures/kiran-25.png) + +### 4.6.外观 + +定制显示属性是每个桌面系统所必备的,Kiran桌面为您提供了强大的显示属性定制工具。外观是一个对系统的桌面背景,主题,字体三个方面提供统一配置和管理的工具。 +选择“开始菜单”>“控制中心”>“外观”,显示的界面如下图所示: + +![图26-外观设置](figures/kiran-26.png) + +#### 4.6.1.主题 + +主题可以对系统的对话框风格,菜单风格,系统面板风格,图标风格进行统一设置或者也可以根据用户的喜好定制。 + +1)主题设置 +系统中默认已提供了多套主题,可以在主题浏览对话框中浏览主题的相关信息。点击主题浏览对话框中的主题,即可设置系统主题,如图所示: +![图27-主题设置](figures/kiran-27.png) + +2)自定义主题 +用户可以通过点击“自定义”按钮,来根据用户的喜好定制系统主题,如下图所示:自定义主题包括: +a.控制; +b.色彩; +c.窗口边框; +d.图标; +e.指针; + +![图28-自定义主题](figures/kiran-28.png) + +#### 4.6.2.背景 + +用户可以对桌面背景进行设置,可以修改颜色、样式。 +1)背景图片设置 +如下图所示,点击壁纸文件浏览对话框中的壁纸,即可将桌面设置为此壁纸。 + +![图29-背景设置](figures/kiran-29.png) + +2)样式 +用户可以根据自己的喜好通过样式下拉式选择框来调整壁纸填充桌面背景时的方式。填充方式有以下五种方式: + +a.平铺; +b.缩放; +c.居中; +d.比例放大; +e.伸展; +f.适合宽度。 + +3)壁纸的添加与删除 +用户可以通过“添加”按钮添加自己喜欢的壁纸,如下图所示: + +![图30-添加壁纸](figures/kiran-30.png) + +点击“打开”即可添加壁纸。 +同时可以点击“删除”按钮来删除用户不喜欢的壁纸。具体步骤:选择壁纸,点击“删除”。 + +4)桌面背景色彩填充设置 +用户如果不喜欢用壁纸来设置桌面背景,也可以用色彩来设置背景,在壁纸选择对话框中选择无壁纸选项,即可使用色彩来填充桌面背景。 +填充色彩的方式有三种: + +a.纯色; +b.水平梯度; +c.垂直梯度。 + +![图31-背景图片色彩填充](figures/kiran-31.png) + +#### 4.6.3.字体 + +1)字体设置 +用户可以通过字体设置来设置系统图形界面的各种类型的字体,字体类型包括以下五种类型: + +a.应用程序字体; +b.文档字体; +c.桌面字体; +d.窗口标题字体; +e.等宽字体。 + +![图32-字体设置](figures/kiran-32.png) + +2)字体效果设置与详情设置 +字体渲染效果设置 +用户可以通过字体渲染效果设置来设置系统图形界面的以下四种类型的字体效果: + +a.单色; +b.最佳形状; +c.最佳对比; +d.次像素平滑; +系统默认使用的最佳形状的字体渲染效果,如下图所示: + +![图33-字体渲染设置](figures/kiran-33.png) + +3)字体细节设置 +字体效果的一些详情设置可以通过“细节”按钮进行设置。详情设置包括: + +a.字体分辨率; +b.字体平滑度; +c.字体微调; +d.字体次像素排序。 + +![图34-字体细节设置](figures/kiran-34.png) + +4)用户可以设置界面,选择是否在菜单显示图标和在按钮中显示图标: + +![图35-显示图标与否设置](figures/kiran-35.png) + +## 5.桌面应用 + +### 5.1.文本编辑器 + +要启动文本编辑器,点击“开始菜单”>“所有应用”>“工具”>“pluma”。也可以在shell提示符下键入pluma启动文本编辑器。 +文本编辑器是所有计算机系统中最常用的一种工具。用户在使用计算机时,往往需要创建自己的文件,无论是一般的文字文件、资料文件,还是编写源程序,这些工作都离不开编辑器。它用于查看和修改纯文本文件,纯文本文件是不包含应用字体或风格格式的普通文本文件,如系统日志和配置文件: + +![图36-文本编辑器](figures/kiran-36.png) + +### 5.2.终端 + +在桌面环境下,可以利用终端程序进入传统的命令操作界面,启动命令行终端的方法是:选择“开始菜单”>“所有应用”>“工具”>“终端”或者桌面面板上的图标: + +![图37-终端](figures/kiran-37.png) + +### 5.3.Firefox火狐浏览器 + +要启动Firefox火狐浏览器,点击“开始菜单”>“所有应用”>“互联网”>“Firefox火狐浏览器”。 +Firefox火狐浏览器,是一个自由及开放源代码网页浏览器,使用Gecko排版引擎,支持多种操作系统,如Windows、Mac OS X及GNU/Linux等。它体积小速度快,还有其他一些高级特征,主要特性有:标签式浏览、使用网上冲浪更快、可以禁止弹出式窗口、自定制工具栏、扩展管理、更好的搜索特性、快速而方便的侧栏: + +![图38-firefox浏览器](figures/kiran-38.png) + +### 5.4.截图工具 + +选择“开始菜单”>“所有应用”>“图像”>“截图工具”,可以启动截图工具。 +截图工具是kiranz桌面的一款小巧灵活的屏幕捕捉软件,操作界面简洁、使用极为方便。该软件启动时会在托盘处添加截图工具图标,如下图所示: + +![图39-托盘区截图图标](figures/kiran-39.png) + +点击该图标后,直接弹出屏幕捕捉界面,可自行选择截图范围。可通过有击该图标打开“打开启动器”,可选择需要抓取的范围是整个桌面,或者方形区域,可设置截图延迟时间,如下图所示: + +![图40-截图界面](figures/kiran-40.png) + +![图41-启动器界面](figures/kiran-41.png) + +在弹出的对话框中,点击“√”,即可保存至桌面,如想自定义保存位置,点击“选项”>勾选“自定义保存位置”即可。如下图所示: + +![图42-截图过程](figures/kiran-42.png) + +### 5.5.网络设置 + +Kiran桌面采用了NetworkManager作为网络配置工具,NetworkManager是用来设定、配置和管理各种网络类型的桌面工具,NetworkManager提供了对移动宽带设备、蓝牙、IPv6 提供改进的支持。通过点击“开始菜单-控制中心-网络连接”打开,或者通过点击桌面右下角网络图标选择编辑连接打开,如图所示: + +![图43-网络连接工具](figures/kiran-43.png) + +设置有线连接: +设备选择当前的网卡,如“ens160”是当前系统的网卡,选中该网卡,点击“编辑”按钮,弹出网卡编辑对话框: + +![图44-编辑网络](figures/kiran-44.png) + +“IPv4设置”是用户常用到的设置,这里选择了DHCP的方式获取IP和DNS服务器,系统会自动给用户分配IP地址。 +有些时候用户会碰到需要手动填写IP地址的情况,这就需要在IPv4设置的上方“方法”下拉菜单中选择“手动”,如下图所示: + +![图45-设置IPV4](figures/kiran-45.png) + +接下来点击“添加”按钮依次输入IP地址、子网掩码和网关,并填写DNS服务器,如下图: + +![图46-设置网络ip和dns等](figures/kiran-46.png) + +填写ip地址、子网掩码、网关和DNS后保存,点击桌面右下角网络图标断开网络后重新连接。 + +### 5.6.时间和日期管理 + +要对系统的日期和时间进行设置,您可以在控制中心中选择“时间和日期管理”选项,也可以通过点击桌面右下角日期区域,系统将弹出如图所示的界面: + +![图47-时间和日期管理工具](figures/kiran-47.png) + +自动同步日期和时间:打开“自动同步”并连接外网可以自动同步时间。 +设置时区:点击“更改时区”按钮,右侧显示如下图所示时区设置对话框,点击需要更改的时区后保存即可修改时区。 + +![图48-修改时区](figures/kiran-48.png) + +手动设置时间:关闭自动同步按钮,点击手动设置时间,可以手动调整年份、月份、日以及时间,修改完成后保存。 + +![图49-手动设置时间](figures/kiran-49.png) + +修改日期格式:点击日期时间格式设置可以修改显示的日期格式,可以设置长日期显示格式、短日期显示格式、时间格式、以及是否显示秒: + +![图50-修改日期格式](figures/kiran-50.png) diff --git a/docs/en/25.03/Tools/desktop/Kiran/_menu.md b/docs/en/25.03/Tools/desktop/Kiran/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..f2635a3af8e7288989a8dfa6b389424fea5ad008 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/Kiran/_menu.md @@ -0,0 +1,10 @@ +--- +label: 'Kiran用户指南' +ismanual: 'Y' +description: '安装并使用 Kiran 桌面环境' +children: + - label: '安装 Kiran' + href: './install-kiran.md' + - label: 'Kiran 用户指南' + href: './Kiran_userguide.md' +--- diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-1.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-1.png new file mode 100644 index 0000000000000000000000000000000000000000..59b632062ba3ff6e26c550567e858eb4dfdfc780 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-1.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-10.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-10.png new file mode 100644 index 0000000000000000000000000000000000000000..18cfa3074af1f4b8d49d064a77b016f24ab8c17c Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-10.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-11.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-11.png new file mode 100644 index 0000000000000000000000000000000000000000..b58fbb7ce8a798d5355855a4ac0638540df74d9e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-11.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-12.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-12.png new file mode 100644 index 0000000000000000000000000000000000000000..920d0c7112be6bed509773413de36506d748b822 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-12.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-13.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-13.png new file mode 100644 index 0000000000000000000000000000000000000000..f6632732bd2e8a10d0cda2bd0550f43741a7ba97 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-13.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-14.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-14.png new file mode 100644 index 0000000000000000000000000000000000000000..52eae7cc40fe4f7c6b2a8fe9744209a1fcbc30d8 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-14.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-15.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-15.png new file mode 100644 index 0000000000000000000000000000000000000000..5496c56ca72983780b9785d2d15c4008fb73aeef Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-15.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-16.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-16.png new file mode 100644 index 0000000000000000000000000000000000000000..6125b257245aa89f9b6592ed5b14a95d5699076e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-16.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-17.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-17.png new file mode 100644 index 0000000000000000000000000000000000000000..d8a4cb88017efe9f41f78ffc2f9de06dedcc1b23 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-17.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-18.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-18.png new file mode 100644 index 0000000000000000000000000000000000000000..0cb0c50d15597998fbd4cf3db2d1d0f9ec3c920e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-18.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-19.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-19.png new file mode 100644 index 0000000000000000000000000000000000000000..58ef2d33a52cf6404ea03b6a2d37f8d8b8391539 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-19.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-2.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-2.png new file mode 100644 index 0000000000000000000000000000000000000000..088bf53c1e763924e7cee46d0cdac98ad0a9d5e2 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-2.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-20.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-20.png new file mode 100644 index 0000000000000000000000000000000000000000..e8608485553033eb2ae141162e4300fa48c578cd Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-20.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-21.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-21.png new file mode 100644 index 0000000000000000000000000000000000000000..4d4c0ff304bdfbc8e715d2e756315a005c008336 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-21.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-22.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-22.png new file mode 100644 index 0000000000000000000000000000000000000000..6778d5a40a82e699da9531f4727a196d1442b9ae Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-22.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-23.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-23.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1d5e284eb299a771c5abbfdff611270ddf2449 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-23.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-24.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-24.png new file mode 100644 index 0000000000000000000000000000000000000000..a3ed57f9e9c300a65f867d29a44f287405a0509c Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-24.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-25.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-25.png new file mode 100644 index 0000000000000000000000000000000000000000..694e6173dfbf1fda8d07670a8e3daf4fbeb263ac Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-25.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-26.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-26.png new file mode 100644 index 0000000000000000000000000000000000000000..3b6ae2eeff3aae39107f15b60c5bb14ffc787cd8 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-26.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-27.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-27.png new file mode 100644 index 0000000000000000000000000000000000000000..3b6ae2eeff3aae39107f15b60c5bb14ffc787cd8 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-27.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-28.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-28.png new file mode 100644 index 0000000000000000000000000000000000000000..01ff3a8f47248d96c714e78b80fd81cd1ed16e0f Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-28.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-29.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-29.png new file mode 100644 index 0000000000000000000000000000000000000000..c5ad5b4438eae441f6086ce5e1aae2e6755aa12a Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-29.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-3.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-3.png new file mode 100644 index 0000000000000000000000000000000000000000..e1399424c52eee8804f9433c9e9bf203950008c6 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-3.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-30.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-30.png new file mode 100644 index 0000000000000000000000000000000000000000..c1efc1e3931a129affd5dfcea9e319556e492f04 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-30.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-31.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-31.png new file mode 100644 index 0000000000000000000000000000000000000000..c5ad5b4438eae441f6086ce5e1aae2e6755aa12a Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-31.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-32.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-32.png new file mode 100644 index 0000000000000000000000000000000000000000..fd900ec891b09313a7c558c61213b1816b803034 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-32.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-33.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-33.png new file mode 100644 index 0000000000000000000000000000000000000000..64ba70b08ed63c6e0942478d61e36a8c443f0604 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-33.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-34.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-34.png new file mode 100644 index 0000000000000000000000000000000000000000..4b869e7d172e2f2889d487157b92204a28a8dc4e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-34.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-35.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-35.png new file mode 100644 index 0000000000000000000000000000000000000000..9b383f3c84964b4fc34c4d8e75400325f93908bc Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-35.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-36.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-36.png new file mode 100644 index 0000000000000000000000000000000000000000..0b16632852c5024e2c6ec4fbd49513e3b7a2b146 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-36.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-37.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-37.png new file mode 100644 index 0000000000000000000000000000000000000000..2be3cc3b2528260c579b59f529e7a5663f1cc779 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-37.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-38.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-38.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1ffaf3aa920f922357f6d48700f42974600d77 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-38.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-39.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-39.png new file mode 100644 index 0000000000000000000000000000000000000000..fd0e5add782b6c9cf4a8b9f6473c96641c39bd1d Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-39.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-4.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-4.png new file mode 100644 index 0000000000000000000000000000000000000000..bd318280b403912ab4846b694592d580b9e5d242 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-4.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-40.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-40.png new file mode 100644 index 0000000000000000000000000000000000000000..083031058ff47dc1550881d3a9f189861d3e8563 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-40.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-41.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-41.png new file mode 100644 index 0000000000000000000000000000000000000000..582893929e2c10a96c49696411bbed3ea9fd7c55 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-41.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-42.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-42.png new file mode 100644 index 0000000000000000000000000000000000000000..eede1243506ccd309ee707465f56c31581dd8554 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-42.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-43.0.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-43.0.png new file mode 100644 index 0000000000000000000000000000000000000000..caacc027322d4b7480e6508d4a1b4a13eefcf788 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-43.0.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-43.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-43.png new file mode 100644 index 0000000000000000000000000000000000000000..4ea9f45ed8f327fce426352c4ae7fbf06cbefc84 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-43.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-44.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-44.png new file mode 100644 index 0000000000000000000000000000000000000000..c86a100005f89dbb9b24055e42d716205d47399e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-44.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-45.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-45.png new file mode 100644 index 0000000000000000000000000000000000000000..c5b5d75f972e594587f3393c8d384dcd76e7477e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-45.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-46.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-46.png new file mode 100644 index 0000000000000000000000000000000000000000..e9a28632c62de95d8ea2d436ba9bc705ff980991 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-46.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-47.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-47.png new file mode 100644 index 0000000000000000000000000000000000000000..a3606e3c899f944eb84d206d98cedc3377197c97 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-47.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-48.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-48.png new file mode 100644 index 0000000000000000000000000000000000000000..b69202c9a83bfc2c835ab166ef0fc2455bb4bcd3 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-48.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-49.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-49.png new file mode 100644 index 0000000000000000000000000000000000000000..d739e6107fd80ecd741dacaaf9dfb868afc61e37 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-49.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-5.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-5.png new file mode 100644 index 0000000000000000000000000000000000000000..154dd54d43b5b98682eb798518046e72fc7e3f83 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-5.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-50.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-50.png new file mode 100644 index 0000000000000000000000000000000000000000..96957676afc9f66bcc4b63c5e39eb8890f108015 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-50.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-6.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-6.png new file mode 100644 index 0000000000000000000000000000000000000000..927b475d6687d60f04fed8a535b2225a8f4b23f7 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-6.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-7.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-7.png new file mode 100644 index 0000000000000000000000000000000000000000..254ef11f36d958f6ef7c70853e5f61032f825463 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-7.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-8.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-8.png new file mode 100644 index 0000000000000000000000000000000000000000..29b5845d2fa94cba92719b8649a5e86c926ea911 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-8.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-9.png b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-9.png new file mode 100644 index 0000000000000000000000000000000000000000..46bcfdd0e1e88ad0f0ade4a3990c3ac5d66060e7 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/Kiran/figures/kiran-9.png differ diff --git a/docs/en/25.03/Tools/desktop/Kiran/install-kiran.md b/docs/en/25.03/Tools/desktop/Kiran/install-kiran.md new file mode 100644 index 0000000000000000000000000000000000000000..d3076e1d4304d4706a66b32d15c234fea280046a --- /dev/null +++ b/docs/en/25.03/Tools/desktop/Kiran/install-kiran.md @@ -0,0 +1,37 @@ +# 在 openEuler 上安装 Kiran + +## 简介 + +kiran 桌面是湖南麒麟信安团队以用户和市场需求为导向,研发的一个安全、稳定、高效、易用的桌面环境。Kiran 可以支持 x86 和 aarch64 架构。 + +## 安装方法 + +安装时建议使用 root 用户或者新建一个管理员用户。 + +1.下载 openEuler 23.09 镜像并安装系统。 + +2.更新软件源: + +```sh + +sudo dnf update + +``` + +3.安装 kiran-desktop: + +```sh + +sudo dnf -y install kiran-desktop + +``` + +4.设置以图形界面的方式启动,并重启(`reboot`)。 + +```sh + +systemctl set-default graphical.target + +``` + +重启系统即可通过 Kiran 桌面登录,您就可以尽情使用 Kiran 桌面了。 diff --git a/docs/en/25.03/Tools/desktop/UKUI/UKUI-user-guide.md b/docs/en/25.03/Tools/desktop/UKUI/UKUI-user-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..46c6a9c7b891bf4d65a0e4950a1bdca736499c2b --- /dev/null +++ b/docs/en/25.03/Tools/desktop/UKUI/UKUI-user-guide.md @@ -0,0 +1,391 @@ +# UKUI 用户指南 + +## 概述 + +桌面是用户进行图形界面操作的基础,UKUI提供了多个功能部件,包括任务栏、开始菜单等,本文主要描述 UKUI 的使用。 + +主界面如下图所示。 + +![图 1 桌面主界面-big](./figures/1.png) + +## 桌面 + +### 桌面图标 + +系统默认放置了计算机、回收站、主文件夹三个图标,鼠标左键双击即可打开页面,功能如下表。 + +| 图标 | 说明 | +| :------------ | :------------ | +| ![](./figures/icon1.png) | 计算机:显示连接到本机的驱动器和硬件| +| ![](./figures/icon2.png) | 回收站:显示移除的文件| +| ![](./figures/icon3.png) | 主文件夹:显示个人主目录| + +另外,右键单击“计算机”,选择“属性”,可显示当前系统版本、内核版本等相关信息。 + +![图 2 “计算机”-“属性”-big](./figures/2.png) + +### 右键菜单 + +在桌面空白处单击鼠标右键,出现的菜单如下图所示,为用户提供了一些快捷功能。 + +![图 3 右键菜单](./figures/3.png) + +部分选项说明如表 2。 + +| 选项 | 说明| +| :------------ | :------------ | +| 新建 | 可新建文件夹、文本文档、WPS文件 | +| 视图类型 | 提供四种视图类型:小图标、中图标、大图标、超大图标 | +| 排序方式 | 提供根据文件名称、文件类型、文件大小、修改日期排列的四种方式| + +
+ +## 任务栏 + +### 基本功能 + +任务栏位于底部,包括开始菜单、多视图切换、文件浏览器、Firefox网络浏览器、WPS、托盘菜单。 + +![图 4 任务栏](./figures/4.png) + +| 组件 | 说明 | +| :------------ | :------------ | +|![](./figures/icon4.png)| 开始菜单,用于弹出系统菜单,可查找应用和文件 | +|![](./figures/icon5.png)| 多视图切换,可在多个工作区互不干扰进行操作| +|![](./figures/icon6.png)| 文件浏览器,可浏览和管理系统中的文件| +|![](./figures/icon7.png)| Firefox网页浏览器,提供便捷安全的上网方式| +|![](./figures/icon8.png)| WPS办公套件,可以实现办公软件最常用的文字、表格、演示等多种功能| +|窗口显示区 |横条中间空白部分;显示正在运行的程序或打开的文档,可进行关闭窗口、窗口置顶操作。| +|![](./figures/icon9.png)| 托盘菜单,包含了对声音、麒麟天气、网络连接、输入法、通知中心、日期、夜间模式的设置| +|显示桌面| 按钮位于最右侧;最小化桌面的所有窗口,返回桌面;再次单击将恢复窗口| + +
+ +#### 多视图切换 + +点击任务栏“![](./figures/icon5.png)”图标,即可进入如下图所示界面,在多个工作区内选择当下需要工作的操作区。 + +![图 5 多视图切换-big](./figures/5.png) + +#### 预览窗口 + +用户将鼠标移动到任务栏的应用图标上,会对该应用打开的窗口进行小窗口预览,悬停在指定窗口如下图所示为悬停状态,该窗口会微微呈现毛玻璃效果(左),其余窗口为默认状态(右)。 + +![图 6 任务栏预览窗口](./figures/6.png) + +用户通过鼠标右键点击任务栏的应用图标,可关闭该应用。 + +![图 7 任务栏右键预览](./figures/7.png) + +#### 侧边栏 + +侧边栏位于整个桌面的右侧,点击任务栏托盘菜单中的“![](./figures/icon11-o.png)”图标打开收纳菜单,点击侧边栏“![](./figures/icon12-o.png)”图标,弹出侧边栏如下图所示。 + +侧边栏由两部分构成:通知中心、剪切板和小插件。 + +![图 8 侧边栏无消息状态-big](./figures/8.png) + +##### 通知中心 + +通知中心将会显示近期最新的重要信息列表,选择右上角“清空”可将信息列表清空;用户可通过选择右上角“设置”跳转进入控制面板的通知设置界面,能设置显示信息的应用,以及信息的数量。 + +![图 9 通知中心-big](./figures/9.png) + +右侧工作区可设置为按应用折叠的模式。 + +![图 10 按应用折叠通知消息-big](./figures/10.png) + +侧边栏右上角“![](./figures/icon13-o.png)”图标可收纳不重要信息,可以打开不重要的和已被设置为收纳的应用软件信息,消息超过999+后显示成![](./figures/icon14-o.png)的形式表示无穷大。 + +![图 11 消息收纳箱](./figures/11.png) + +##### 剪切板 + +剪切板可保存近期选择复制或剪切的内容,同时可通过表上说明的图标进行相应操作。 + +其中点击“![](./figures/icon15-o.png)”图标,可对剪切板的内容进行编辑。 + +|图标| 说明| 图标 |说明 | +| :------------ | :------------ | :------------ | :------------ | +|![](./figures/icon16.png)| 复制剪切板上的该内容 |![](./figures/icon18.png)| 编辑剪切板上的该内容 | +|![](./figures/icon17.png)| 删除剪切板上的该内容 | | | + +
+ +![图 12 剪切板](./figures/12.png) + +![图 13 编辑选中实的剪切板内容](./figures/13.png) + +剪切板的第二个标签为小插件,插件包含:闹钟、麒麟便签本、用户反馈,可供用户快捷选择。 + +![图 14 小插件](./figures/14.png) + +#### 托盘菜单 + +##### 收纳菜单 + +点击任务栏托盘菜单中的“![](./figures/icon19-o.png)”图标打开收纳菜单,收纳菜单中可收纳麒麟天气、输入法、蓝牙、u盘等小工具。 + +![图 15 收纳菜单](./figures/15.png) + +##### 输入法 + +任务栏输入法默认为搜狗输入法,使用快捷键“Ctrl+Space”可切换出来,“Shift”按键切换中英文模式。 + +![图 16 输入法](./figures/16.png) + +##### U盘 + +U盘插入主机后,自动读取U盘数据,点击任务栏中U盘“![](./figures/icon26-o.png)”图标弹窗如下图所示。 + +需要卸载U盘时仅需点击弹出“![](./figures/icon27-o.png)”图标即可。 + +![图 17 U盘状态窗口](./figures/17.png) + +##### 电源 + +没有检测到电源设备时,用户通过点击鼠标左键任务栏中电源“![](./figures/icon28-o.png)”图标。 + +![图 18 无电源设备](./figures/18.png) + +若检测到接入的电源设备,用户通过点击鼠标左键任务栏中电源“![](./figures/icon29-o.png)”图标。 + +![图 19 电源管理器窗口](./figures/19.png) + +用户通过点击鼠标右键任务栏中电源“![](./figures/icon30-o.png)”图标,弹出电源管理器设置菜单,设置调整屏幕亮度、设置电源和休眠两项。 + +![图 20 电源管理器设置](./figures/20.png) + +若电源管理器弹出“电池电量不足”的弹窗后,用户可点击开启节能模式,电源管理器则即刻将本机设为节能模式运行。 + +![图 21 电池电量不足开启节能模式](./figures/21.png) + +##### 网络 + +用户通过鼠标左键点击任务栏上的网络“![](./figures/icon31-o.png)”图标,可根据需要选择有线和无线两种网络连接方式。 + +|图标 |说明| 图标 |说明 | +| :------------ | :------------ | :------------ | :------------ | +|![](./figures/icon32.png)| 网络已连接 |![](./figures/icon37.png)| 网络未连接 | +|![](./figures/icon33.png)| 网络连接受限 |![](./figures/icon38.png)| 网络已上锁 | +|![](./figures/icon34.png)| 网络正在连接 |![](./figures/icon39.png)| Wifi已连接 | +|![](./figures/icon35.png)| Wifi未连接 |![](./figures/icon40.png)| Wifi连接受限 | +|![](./figures/icon36.png)| Wifi已上锁 |![](./figures/icon41.png)| Wifi正在连接 | + +
+ +![图 22 网络连接界面](./figures/22.png) + +- 有线网络 + + 在有线网络连接界面,点击有线网络方案即可展开,查看网络的详细信息。 + + ![图 23 有线网络连接](./figures/23.png) + +- 无线网络 + + 无线网络连接,点击右上角开关按钮打开无线网络连接,并在可用无线网络列表中选择需要连接的WiFi,并键入密码即可通过WiFi上网。 + + ![图 24 无线网络连接](./figures/24.png) + +- 网络设置窗口 + + 用户通过鼠标右键点击任务栏上的网络“![](./figures/icon42-o.png)”图标,弹出网络设置菜单。 + + ![图 25 有线网络设置](./figures/25.png) + + 点击设置网络,即刻进入网络设置窗口。 + + ![图 26 网络设置窗口](./figures/26.png) + +##### 音量 + +用户通过鼠标左键点击任务栏上的音量“![](./figures/icon43-o.png)”图标,打开声音界面。 + +- mini模式 + + 音量mini模式,仅显示扬声器的音量。 + + ![图 27 音量mini模式](./figures/27.png) + +- 按设备 + 音量按设备标签包括输出设备、输入设备。 + + ![图 28 按设备音量列表](./figures/28.png) +- 按应用 + 音量按应用标签包括系统音量、其他应用音量。 + + ![图 29 按应用音量列表](./figures/29.png) + +##### 日历 + +用户通过鼠标左键点击任务栏上的时间日期弹出日历窗口,查看日历、月历、年历窗口。 + +用户可通过筛选年 > 月 > 日查看一日信息,会以大字显示当日日期,并有当日的时间、星期、节气、农历,点击下方宜忌勾选可查看。 + +![图 30 日历查看-big](./figures/30.png) + +##### 夜间模式 + +用户通过鼠标左键点击任务栏上的夜间模式“![](./figures/icon44-o.png)”图标,可设置为夜间模式。 + +#### 高级设置 + +右键单击任务栏,出现的菜单。 + +![图 31 任务栏右键菜单](./figures/31.png) + +用户可对任务栏的布局进行设定,在“设置任务栏”中可进行相关设置。 + +
+ +## 窗口 + +### 窗口管理器 + +窗口管理器为用户提供了如表所示的功能。 + +|功能 |说明 | +| :--------| :----------| +|窗口标题栏| 显示当前窗口的标题名称 | +|最小化/最大化/关闭 |标题栏右侧的三个图标按钮,分别对应最小化窗口、最大化窗口、关闭窗口的功能 | +|侧边滑动 |在窗口右侧提供滑动条,可上下滚动查看页面 | +|窗口堆叠| 允许窗口之间产生重叠 | +|窗口拖拽 |在窗口标题栏长按鼠标左键,可移动窗口到任意位置 | +|窗口大小调整 |将鼠标移至窗口四角,长按左键,可任意调整窗口大小 | + +
+ +### 窗口切换 + +用户有三种方式可以切换: + +- 在任务栏上点击窗口标题; + +- 在桌面上点击不同窗口; + +- 使用快捷键\< Alt > + \< Tab >; + +
+ +## 开始菜单 + +### 基本功能 + +单击“开始菜单”按钮,菜单具备滑动条功能。 + +![图 32 开始菜单主界面](./figures/32.png) + +#### 右侧分类菜单 + +用户将鼠标停留在开始菜单右侧,会出现一个右侧预展开的提示栏,点击展开,即在右侧默认显示三个分类:“常用软件”、“字母分类”、“功能分类”,其中: + +- 所有软件:列出所有软件,近期使用过的软件将会在此页面置顶显示。 + +- 字母分类:列出系统根据首字母进行分类显示所有软件。 + +- 功能分类:列出系统根据功能进行分类显示所有软件。 + +用户可通过点击右上角开始菜单的全屏图标,查看全屏菜单。 + +![图 33 全屏开始菜单-big](./figures/33.png) + +#### 右侧功能键 + +右下侧显示用户头像、计算机、设置和电源四个选项。 + +##### 用户头像 + +点击“![](./figures/icon45-o.png)”图标,进入控制面板查看用户信息。 + +##### 计算机 + +点击“![](./figures/icon46-o.png)”图标进入计算机:个人主文件夹。 + +##### 设置 + +点击“![](./figures/icon47-o.png)”图标进入控制面板。 + +##### 电源 + +###### 锁定屏幕 + +当用户暂时不需要使用计算机时,可以选择锁屏(不会影响系统当前的运行状态),防止误操作;用户返回后,输入密码即可重新进入系统。 + +在默认设置下,系统在一段空闲时间后,将自动锁定屏幕。 + +锁屏界面如下图所示。 + +![图 34 锁屏界面-big](./figures/34.png) + +###### 切换用户和注销 + +当要选择其他用户登录使用计算机时,可选择“注销”或“切换用户”。 + +此时,系统会关闭所有正在运行的应用;所以,在执行此操作前,请先保存当前工作。 + +###### 关机与重启 + +有两种操作方式: + +1)“开始菜单” > “电源” > “关机” + +会弹出对话框,用户可根据需要选择重启或关机。 + +![图 35 关闭系统对话框-big](./figures/35.png) + +2)“开始菜单” > “关机” 按钮右边菜单 > “关机”/“重启” + +系统将直接关机/重启,不再弹出对话框。 + +### 高级设置 + +右键单击开始菜单图标,提供锁屏、切换用户、注销、重启、关闭五个快捷选项。 + +### 应用 + +用户可以在搜索框中,通过关键字搜索应用。如下图所示,可输入中文,如:搜索用户手册,查询结果会随着输入自动显示出来。 + +![图 36 搜索应用](./figures/36.png) + +通过右键点击开始菜单中的某个应用,弹出右键菜单,可将选中应用固定到“所有软件”、任务栏,可添加该应用到桌面方式,可快捷卸载该应用。 + +![图 37 应用的右键菜单](./figures/37.png) + +各个选项说明如下表。 + +|选项 |说明 | +| :------| :-------- +|固定到所有用软件 |将选中软件在所有软件列表中置顶 | +|固定到任务栏 |在任务栏上生成应用的图标 | +|添加到桌面快捷方式| 在桌面生成应用的快捷方式图标 | +|卸载| 卸载软件 | + +
+ +## 常见问题 + +### 锁屏后无法登录系统 + +- 通过Ctrl + Alt + F2切换到字符终端。 + +- 输入用户名和密码后登录。 + +- 执行命令“sudo rm -rf ~/.Xauthority”。 + +- 通过Ctrl + Alt + F1切回图形界面,输入用户密码登录。 + +
+ +## 附录 + +### 快捷键 + +|快捷键 |功能 | +| :------ | :----- | +|F5| 刷新桌面 | +|F1 |打开用户手册 | +|Alt + Tab |切换窗口 | +|win |打开开始菜单 | +|Ctrl + Alt + L| 锁屏 | +|Ctrl + Alt + Delete| 注销 | diff --git a/docs/en/25.03/Tools/desktop/UKUI/_menu.md b/docs/en/25.03/Tools/desktop/UKUI/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..9ffeeaa2fe8c113f76a6076a3c882cfdc4da1486 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/UKUI/_menu.md @@ -0,0 +1,10 @@ +--- +label: 'UKUI用户指南' +ismanual: 'Y' +description: '安装并使用 UKUI 桌面环境' +children: + - label: '安装 UKUI' + href: './installing-UKUI.md' + - label: 'UKUI 用户指南' + href: './UKUI-user-guide.md' +--- diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/1.png b/docs/en/25.03/Tools/desktop/UKUI/figures/1.png new file mode 100644 index 0000000000000000000000000000000000000000..40af4242eebb440a76c749a8d970d50cd7b89bf4 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/1.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/10.png b/docs/en/25.03/Tools/desktop/UKUI/figures/10.png new file mode 100644 index 0000000000000000000000000000000000000000..e588ffbe3d8d7b66d92ae8f2b4bcec7c80d0592c Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/10.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/11.png b/docs/en/25.03/Tools/desktop/UKUI/figures/11.png new file mode 100644 index 0000000000000000000000000000000000000000..1989a5bb08155f920363e154e68bb148715c7e9e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/11.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/12.png b/docs/en/25.03/Tools/desktop/UKUI/figures/12.png new file mode 100644 index 0000000000000000000000000000000000000000..cb6346161182d2cfeaf3818d5ec518ddb11c732e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/12.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/13.png b/docs/en/25.03/Tools/desktop/UKUI/figures/13.png new file mode 100644 index 0000000000000000000000000000000000000000..0a7def1fb66c90da62acde799eaffca97e3b5396 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/13.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/14.png b/docs/en/25.03/Tools/desktop/UKUI/figures/14.png new file mode 100644 index 0000000000000000000000000000000000000000..3a27a66d57e284775420d467f90dcc02889bbffe Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/14.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/15.png b/docs/en/25.03/Tools/desktop/UKUI/figures/15.png new file mode 100644 index 0000000000000000000000000000000000000000..370bea32abcaa8a2b06a1a61c1455d4b35f43474 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/15.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/16.png b/docs/en/25.03/Tools/desktop/UKUI/figures/16.png new file mode 100644 index 0000000000000000000000000000000000000000..812ee462669c5263ef4bffc49ca4f9b6af4541c6 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/16.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/17.png b/docs/en/25.03/Tools/desktop/UKUI/figures/17.png new file mode 100644 index 0000000000000000000000000000000000000000..36e524b806874fa3788f5e4dcd78350686281107 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/17.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/18.png b/docs/en/25.03/Tools/desktop/UKUI/figures/18.png new file mode 100644 index 0000000000000000000000000000000000000000..51b32442980aa60646f77dabd53ade74f55891fe Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/18.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/19.png b/docs/en/25.03/Tools/desktop/UKUI/figures/19.png new file mode 100644 index 0000000000000000000000000000000000000000..c9457d09aa9f1662b2c9e4550cdbdb9f57dd020e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/19.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/2.png b/docs/en/25.03/Tools/desktop/UKUI/figures/2.png new file mode 100644 index 0000000000000000000000000000000000000000..97917cc245484a43bec8562757d920a06f123121 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/2.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/20.png b/docs/en/25.03/Tools/desktop/UKUI/figures/20.png new file mode 100644 index 0000000000000000000000000000000000000000..b0943189920d7a541d35da27340593ea93f92a17 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/20.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/21.png b/docs/en/25.03/Tools/desktop/UKUI/figures/21.png new file mode 100644 index 0000000000000000000000000000000000000000..e590c22c0ea28906b5f4ea7ccbc6ab11e47ad173 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/21.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/22.png b/docs/en/25.03/Tools/desktop/UKUI/figures/22.png new file mode 100644 index 0000000000000000000000000000000000000000..03a548b1ffb1f0ad53cfa5387af2721af90bca81 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/22.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/23.png b/docs/en/25.03/Tools/desktop/UKUI/figures/23.png new file mode 100644 index 0000000000000000000000000000000000000000..834c492094715cde1c02c91752ecabfe7921ed62 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/23.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/24.png b/docs/en/25.03/Tools/desktop/UKUI/figures/24.png new file mode 100644 index 0000000000000000000000000000000000000000..1881e868b74a60888b319576fa38fb4af92ba75c Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/24.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/25.png b/docs/en/25.03/Tools/desktop/UKUI/figures/25.png new file mode 100644 index 0000000000000000000000000000000000000000..f38839725d27a3486984d152e5d9de305364fbd2 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/25.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/26.png b/docs/en/25.03/Tools/desktop/UKUI/figures/26.png new file mode 100644 index 0000000000000000000000000000000000000000..6d7957119133ecb98b1b6b104e54a3a4647ec2a5 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/26.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/27.png b/docs/en/25.03/Tools/desktop/UKUI/figures/27.png new file mode 100644 index 0000000000000000000000000000000000000000..3e4733717fdc5172d6479b393005219e65e96df4 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/27.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/28.png b/docs/en/25.03/Tools/desktop/UKUI/figures/28.png new file mode 100644 index 0000000000000000000000000000000000000000..a77772e818e3f6c11acac3b9cfa18bad14a0a48c Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/28.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/29.png b/docs/en/25.03/Tools/desktop/UKUI/figures/29.png new file mode 100644 index 0000000000000000000000000000000000000000..c4f58ffe5855295268298448744e5aadbdc55276 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/29.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/3.png b/docs/en/25.03/Tools/desktop/UKUI/figures/3.png new file mode 100644 index 0000000000000000000000000000000000000000..fbb76b336957020ed6867d908e0a8bdcfc953c52 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/3.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/30.png b/docs/en/25.03/Tools/desktop/UKUI/figures/30.png new file mode 100644 index 0000000000000000000000000000000000000000..d91adefba1753959e90ccf4aa1501ac08d7144bd Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/30.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/31.png b/docs/en/25.03/Tools/desktop/UKUI/figures/31.png new file mode 100644 index 0000000000000000000000000000000000000000..0abef09ab438f5f8cfb68090993f55c493b8c15e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/31.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/32.png b/docs/en/25.03/Tools/desktop/UKUI/figures/32.png new file mode 100644 index 0000000000000000000000000000000000000000..d567cfbacc07a9eb46ff2c54a68432f45e034e94 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/32.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/33.png b/docs/en/25.03/Tools/desktop/UKUI/figures/33.png new file mode 100644 index 0000000000000000000000000000000000000000..7b5896e2884520672c0bd88d68471b45a09c56fe Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/33.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/34.png b/docs/en/25.03/Tools/desktop/UKUI/figures/34.png new file mode 100644 index 0000000000000000000000000000000000000000..81bc9480fbbd81a97c559d7a6a74274deeab2bd1 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/34.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/35.png b/docs/en/25.03/Tools/desktop/UKUI/figures/35.png new file mode 100644 index 0000000000000000000000000000000000000000..ab2399847a643a87279337704e23fea7609bb211 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/35.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/36.png b/docs/en/25.03/Tools/desktop/UKUI/figures/36.png new file mode 100644 index 0000000000000000000000000000000000000000..536981609b9ae5d32be56bec612f2b3446146184 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/36.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/37.png b/docs/en/25.03/Tools/desktop/UKUI/figures/37.png new file mode 100644 index 0000000000000000000000000000000000000000..e39aa03587642dc1f8622fff515b05a9a3085b28 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/37.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/4.png b/docs/en/25.03/Tools/desktop/UKUI/figures/4.png new file mode 100644 index 0000000000000000000000000000000000000000..5078e36aca713706d2cf08a3ebecdc3769951899 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/4.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/5.png b/docs/en/25.03/Tools/desktop/UKUI/figures/5.png new file mode 100644 index 0000000000000000000000000000000000000000..2976a745cfaede26594d6daa01cfc18d18b1de8b Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/5.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/6.png b/docs/en/25.03/Tools/desktop/UKUI/figures/6.png new file mode 100644 index 0000000000000000000000000000000000000000..275c23872f2353f007371672714902babcc3db53 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/6.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/7.png b/docs/en/25.03/Tools/desktop/UKUI/figures/7.png new file mode 100644 index 0000000000000000000000000000000000000000..4d397959ac7f6d166ef5a3b7084bd5c3c93b475f Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/7.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/8.png b/docs/en/25.03/Tools/desktop/UKUI/figures/8.png new file mode 100644 index 0000000000000000000000000000000000000000..8ade274092d7b3e461c96d7909a9d89d3a944f09 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/8.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/9.png b/docs/en/25.03/Tools/desktop/UKUI/figures/9.png new file mode 100644 index 0000000000000000000000000000000000000000..f7b2215404929346f1a814b0b1d6d482559c08b5 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/9.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon1.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon1.png new file mode 100644 index 0000000000000000000000000000000000000000..9bac00355cf4aa57d32287fd4271404f6fd3fd4d Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon1.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon11-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon11-o.png new file mode 100644 index 0000000000000000000000000000000000000000..47a1f2cb7f99b583768c7cbd7e05a57f302dbe8a Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon11-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon12-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon12-o.png new file mode 100644 index 0000000000000000000000000000000000000000..f1f0f59dd3879461a0b5bc0632693a4a4124def3 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon12-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon13-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon13-o.png new file mode 100644 index 0000000000000000000000000000000000000000..c05a981b29d8ad11c6682f796f79b4cafd0f088b Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon13-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon14-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon14-o.png new file mode 100644 index 0000000000000000000000000000000000000000..b21deee4d98593d93fb5f72158d2d78f3d3f1cb9 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon14-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon15-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon15-o.png new file mode 100644 index 0000000000000000000000000000000000000000..1827a20e9da4d28e35e8ab2eae739b2fec37b385 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon15-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon16.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon16.png new file mode 100644 index 0000000000000000000000000000000000000000..f271594dda9d3ad0f038c9d719dd68c3e82c59f1 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon16.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon17.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon17.png new file mode 100644 index 0000000000000000000000000000000000000000..dbe58b89347c857920bce25f067fbd11c308e502 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon17.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon18.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon18.png new file mode 100644 index 0000000000000000000000000000000000000000..1827a20e9da4d28e35e8ab2eae739b2fec37b385 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon18.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon19-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon19-o.png new file mode 100644 index 0000000000000000000000000000000000000000..47a1f2cb7f99b583768c7cbd7e05a57f302dbe8a Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon19-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon2.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon2.png new file mode 100644 index 0000000000000000000000000000000000000000..9101e4b386df065a87d422bc5a0b287528ea5ec7 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon2.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon26-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon26-o.png new file mode 100644 index 0000000000000000000000000000000000000000..2293a893caf6d89c3beb978598fe7f281e68e7d5 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon26-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon27-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon27-o.png new file mode 100644 index 0000000000000000000000000000000000000000..abbab8e40f7e3ca7c2a6f28ff78f08f15117828e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon27-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon28-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon28-o.png new file mode 100644 index 0000000000000000000000000000000000000000..e40d45fc0a9d2af93280ea14e01512838bb3c3dc Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon28-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon29-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon29-o.png new file mode 100644 index 0000000000000000000000000000000000000000..e40d45fc0a9d2af93280ea14e01512838bb3c3dc Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon29-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon3.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon3.png new file mode 100644 index 0000000000000000000000000000000000000000..930ee8909e89e3624c581f83d713af271cd96c75 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon3.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon30-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon30-o.png new file mode 100644 index 0000000000000000000000000000000000000000..e40d45fc0a9d2af93280ea14e01512838bb3c3dc Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon30-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon31-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon31-o.png new file mode 100644 index 0000000000000000000000000000000000000000..25959977f986f433ddf3d66935f8d2c2bc6ed86b Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon31-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon32.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon32.png new file mode 100644 index 0000000000000000000000000000000000000000..25959977f986f433ddf3d66935f8d2c2bc6ed86b Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon32.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon33.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon33.png new file mode 100644 index 0000000000000000000000000000000000000000..88ed145b25f6f025ad795ceb012500e0944cb54c Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon33.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon34.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon34.png new file mode 100644 index 0000000000000000000000000000000000000000..8247f52a3424c81b451ceb318f4a7979a5eddece Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon34.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon35.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon35.png new file mode 100644 index 0000000000000000000000000000000000000000..7c656e9030b94809a57c7e369921e6a585f3574c Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon35.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon36.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon36.png new file mode 100644 index 0000000000000000000000000000000000000000..7d29d173e914dfff48245d3d3a4d42575ce2d1db Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon36.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon37.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon37.png new file mode 100644 index 0000000000000000000000000000000000000000..58be4c621b6638115153e361801deb9ee06634d8 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon37.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon38.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon38.png new file mode 100644 index 0000000000000000000000000000000000000000..0c861ccb891f4fb5e533eb7f7151a8fce1571f17 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon38.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon39.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon39.png new file mode 100644 index 0000000000000000000000000000000000000000..b1ba1f347452d0cd1c06c6c51d2cdf5aea5e490b Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon39.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon4.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon4.png new file mode 100644 index 0000000000000000000000000000000000000000..548dc8b648edb73ff1dd8a0266e8479203e72ca0 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon4.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon40.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon40.png new file mode 100644 index 0000000000000000000000000000000000000000..9c29dd1e9a1bf22c36abf51cb18fa9e47b455fab Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon40.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon41.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon41.png new file mode 100644 index 0000000000000000000000000000000000000000..9e8aea527a2119433fffec5a8800ebfa4fa5062f Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon41.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon42-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon42-o.png new file mode 100644 index 0000000000000000000000000000000000000000..25959977f986f433ddf3d66935f8d2c2bc6ed86b Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon42-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon42.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon42.png new file mode 100644 index 0000000000000000000000000000000000000000..25959977f986f433ddf3d66935f8d2c2bc6ed86b Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon42.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon43-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon43-o.png new file mode 100644 index 0000000000000000000000000000000000000000..284bdd551baf25beb4143013402e77a1a4c60ccb Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon43-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon44-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon44-o.png new file mode 100644 index 0000000000000000000000000000000000000000..810f4d784ee140dbf562e67a0d3fd391272626a5 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon44-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon45-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon45-o.png new file mode 100644 index 0000000000000000000000000000000000000000..3e528ce2c98284f020ae4912a853f5864526396b Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon45-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon46-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon46-o.png new file mode 100644 index 0000000000000000000000000000000000000000..ec6a3ca0fe57016f3685981ed518493ceea1c855 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon46-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon47-o.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon47-o.png new file mode 100644 index 0000000000000000000000000000000000000000..6eeaba98d908775bd363a8ffcec27c3b6a214013 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon47-o.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon5.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon5.png new file mode 100644 index 0000000000000000000000000000000000000000..e4206b7b584bf0702c7cb2f03a3a41e20bfba844 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon5.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon6.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon6.png new file mode 100644 index 0000000000000000000000000000000000000000..88ced3587e9a42b145fe11393726f40aba9d1b2c Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon6.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon7.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon7.png new file mode 100644 index 0000000000000000000000000000000000000000..05fe8aa38c84ca0c0c99b0b005ddec2f2ba42f4a Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon7.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon8.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon8.png new file mode 100644 index 0000000000000000000000000000000000000000..01543c3e0f5e96a023b4e1f0859a03e3a0dafd56 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon8.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/figures/icon9.png b/docs/en/25.03/Tools/desktop/UKUI/figures/icon9.png new file mode 100644 index 0000000000000000000000000000000000000000..a07c9ab8e51decd9a3bca8c969d2ae95bd68512c Binary files /dev/null and b/docs/en/25.03/Tools/desktop/UKUI/figures/icon9.png differ diff --git a/docs/en/25.03/Tools/desktop/UKUI/installing-UKUI.md b/docs/en/25.03/Tools/desktop/UKUI/installing-UKUI.md new file mode 100644 index 0000000000000000000000000000000000000000..4eafe5558405c645a92af731e7f183d23095a66a --- /dev/null +++ b/docs/en/25.03/Tools/desktop/UKUI/installing-UKUI.md @@ -0,0 +1,28 @@ +# 在 openEuler 上安装 UKUI + +UKUI是麒麟软件团队历经多年打造的一款Linux 桌面,主要基于 GTK 和 QT开发。与其他UI界面相比,UKUI更加注重易用性和敏捷度,各元件相依性小,可以不依赖其他套件而独自运行,给用户带来亲切和高效的使用体验。 + +UKUI支持x86_64和aarch64两种架构。 + +安装时,建议新建一个管理员用户。 + +1. 下载 openEuler ISO 镜像并安装系统。 + + ```sh + # sudo dnf update + ``` + +2. 安装UKUI。 + + ```sh + # sudo dnf install ukui + ``` + +3. 在确认正常安装后,如果希望以图形界面的方式启动,请在命令行运行以下代码,并重启(`reboot`)。 + + ```sh + # systemctl set-default graphical.target + ``` + +目前UKUI版本还在不断的更新,最新的安装方法请查阅: +[https://gitee.com/openeuler/ukui](https://gitee.com/openeuler/ukui) diff --git a/docs/en/25.03/Tools/desktop/XFCE/Xfce_userguide.md b/docs/en/25.03/Tools/desktop/XFCE/Xfce_userguide.md new file mode 100644 index 0000000000000000000000000000000000000000..9a90c6f5841d6d5ae8ac5dcbf8f25c7c426f6610 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/XFCE/Xfce_userguide.md @@ -0,0 +1,244 @@ +# Xfce 用户指南 + +## 一 概述 + +Xfce是运行在类Unix操作系统中的一款轻量级桌面环境。Xfce提供了多个功能部件,包括 所有应用程序 等,本文主要描述 Xfce 的使用。 + +界面如下图所示。 + +![图 1 桌面主界面-big](./figures/xfce-1.png) + +
+ +## 二 桌面 + +### 2.1 桌面图标 + +系统默认放置了文件系统、主文件夹、挂载目录等图标,鼠标左键双击即可打开页面。 + +![图 2 主界面默认图标-big](./figures/xfce-2.png) + +### 2.2 右键菜单 + +在桌面空白处单击鼠标右键,出现的菜单如下图所示,为用户提供了一些快捷功能。 + +![图 3 右键菜单](./figures/xfce-3.png) + +部分选项说明如表。 + +| 选项 | 说明| +| :------------ | :------------ | +| 在新窗口中打开 | 打开对应登录用户的Desktop目录 | +| 创建启动器 | 启动器的自行创建 | +| 创建URL链接 | URL链接的自行创建 | +| 创建文件夹 | 新建文件夹 | +| 创建文档 | 新建文本文档 | +| Open Terminal Here | 新建终端 | +| 排列桌面图标 | 自动排列桌面图标 | +| 桌面设置 | 提供关于背景、菜单、图标的设置 | +| 属性 | 提供关于Desktop的一般、徽标、权限等属性设置 | +| 应用程序 | 所有应用程序 | + +
+ +## 三 任务栏 + +### 3.1 基本功能 + +任务栏位于顶部,包括所有应用程序菜单、窗口显示区、多视图切换、托盘菜单。 + +![图 4 任务栏](./figures/xfce-4.png) + +| 组件 | 说明 | +| :------------ | :------------ | +| 所有应用程序 | 用于弹出所有程序以及设置,可查找应用和设置。| +| 窗口显示区 | 横条中间空白部分;显示正在运行的程序或打开的文档,可进行最小化、最大化、关闭窗口、窗口置顶等操作。| +| 多视图切换 | 可在多个工作区互不干扰进行操作。 | +| 托盘 | 包含了对网络连接、声音、电源、通知中心、日历、登录用户动作的设置。| + +#### 3.1.1 所有应用程序 + +![图 5 所有应用程序-big](./figures/xfce-5.png) + +#### 3.1.2 窗口显示区 + +![图 6 窗口显示区-big](./figures/xfce-6.png) + +#### 3.1.3 多视图切换 + +点击任务栏“![](./figures/xfce-7.png)”中的每个区域图标,即可进入对应的工作区域。 + +例如,通过鼠标在多个工作区内切换选择当下需要工作的操作区。 + +![图 7 多视图切换-big](./figures/xfce-71.png) + +#### 3.1.4 托盘 + +![图 8 托盘菜单-big](./figures/xfce-8.png) + +##### 3.1.4.1 网络 + +用户通过鼠标左键点击任务栏上的网络“![](./figures/xfce-81.png)”图标,可根据需要选择网络连接方式。 + +![图 9 网络连接界面](./figures/xfce-811.png) + +网络设置窗口 + +用户通过鼠标右键点击任务栏上的网络“![](./figures/xfce-81.png)”图标,弹出网络设置菜单。 + +![图 10 网络设置](./figures/xfce-812.png) + +点击 编辑连接,即刻进入网络设置窗口。 + +![图 11 网络设置窗口](./figures/xfce-813.png) + +双击 指定的网络连接 ,例如enp1s0,进入该连接的设置界面。 + +![图 12 有线网络设置窗口](./figures/xfce-814.png) + +##### 3.1.4.2 音量 + +用户通过鼠标左键点击任务栏上的音量“![](./figures/xfce-82.png)”图标,打开声音界面。 + +![图 13 音量设置窗口](./figures/xfce-821.png) + +##### 3.1.4.3 电源 + +用户通过点击鼠标左键任务栏中电源“![](./figures/xfce-83.png)”图标。 + +![图 14 电源设备](./figures/xfce-831.png) + +用户通过点击 电源管理器设置 进行 显示、节点 等配置。 + +![图 15 电源管理器设置](./figures/xfce-832.png) + +##### 3.1.4.4 通知中心 + +用户通过点击鼠标左键任务栏中通知“![](./figures/xfce-84.png)”图标。 + +![图 16 通知中心-big](./figures/xfce-841.png) + +用户可通过选择“请勿打扰”关闭通知。 + +通知中心将会显示重要的近期最新的重要信息列表,选择“清除日志”可将信息列表清空。 + +用户可通过选择“通知设置”跳转进入控制面板的通知设置界面,能设置显示信息的应用,以及信息的数量。 + +![图 17 通知中心-big](./figures/xfce-842.png) + +##### 3.1.4.5 日历 + +用户通过鼠标左键点击任务栏上的时间日期弹出日历窗口,查看日历、月历、年历窗口。 + +用户可通过筛选年 > 月 > 日查看一日信息。 + +![图 18 日历-big](./figures/xfce-85.png) + +用户通过鼠标右键点击任务栏上的时间日期,点击 属性 进行时间设置。 + +![图 19 日期设置-big](./figures/xfce-851.png) + +##### 3.1.4.6 高级设置 + +右键单击任务栏,出现的菜单中点击 面板。 + +![图 20 任务栏右键菜单](./figures/xfce-86.png) + +用户可对任务栏的布局进行设定,可进行项目的添加、删除等相关设置。 + +![图 21 任务栏右键菜单](./figures/xfce-861.png) + +##### 3.1.4.7 登录用户动作 + +用户通过鼠标左键点击任务栏上的登录用户,查看相关动作。 + +![图 22 登录用户动作](./figures/xfce-87.png) + +###### 3.1.4.7.1 锁屏 + +当用户暂时不需要使用计算机时,可以选择锁屏(不会影响系统当前的运行状态),防止误操作;用户返回后,输入密码即可重新进入系统。 + +在默认设置下,系统在一段空闲时间后,将自动锁定屏幕。 + +###### 3.1.4.7.2 切换用户 + +选择其他用户登录使用计算机时,可选择“切换用户”。 + +此时,系统会关闭所有正在运行的应用;所以,在执行此操作前,请先保存当前工作。 + +###### 3.1.4.7.3 挂起 + +处于环保节能考虑,可选择“挂起”。 + +此时,相关数据读入内存,注意不能切换电源。 + +###### 3.1.4.7.3 关机 + +用户选择关闭计算机时,可以选择“关机”。 + +在执行此操作前,建议先保存当前工作。 + +###### 3.1.4.7.3 注销 + +选择退出本次图形界面登录时,可选择“注销”。 + +此时,系统会关闭所有正在运行的应用;所以,在执行此操作前,请先保存当前工作。 + +
+ +## 四 快捷操作栏 + +### 4.1 基本功能 + +快捷操作栏位于底部,包括所有显示桌面、终端、文件管理器、网络浏览器、应用程序查找、用户家目录。 + +![图 23 快捷操作栏](./figures/xfce-9.png) + +| 组件 | 说明 | +| :------------ | :------------ | +| 显示桌面 | 最小化桌面的所有窗口,返回桌面;再次单击将恢复窗口 | +| 终端 | 快速打开一个终端 | +| 文件管理器 | 快速打开一个文件管理器 | +| 网络浏览器 | 快速打开一个网络浏览器 | +| 应用程序查找 | 快速打开应用程序查找窗口 | +| 用户家目录 | 快速打开登录用户的家目录 | + +#### 4.1.1 显示桌面 + +用户通过鼠标左键点击快捷操作栏上的“![](./figures/xfce-91.png)”图标,执行 显示桌面 相关操作。 + +![图 24 显示桌面-big](./figures/xfce-911.png) + +#### 4.1.2 终端 + +用户通过鼠标左键点击快捷操作栏上的“![](./figures/xfce-92.png)”图标,打开一个终端。 + +![图 25 终端-big](./figures/xfce-921.png) + +#### 4.1.3 文件管理器 + +用户通过鼠标左键点击快捷操作栏上的“![](./figures/xfce-93.png)”图标,打开一个文件管理器。 + +![图 26 文件管理器-big](./figures/xfce-931.png) + +#### 4.1.4 网络浏览器 + +用户通过鼠标左键点击快捷操作栏上的“![](./figures/xfce-94.png)”图标,打开一个网络浏览器。 + +![图 27 网络浏览器-big](./figures/xfce-941.png) + +#### 4.1.5 应用程序查找 + +用户通过鼠标左键点击快捷操作栏上的“![](./figures/xfce-95.png)”图标,打开一个应用程序查找界面。 + +![图 28 应用程序查找-big](./figures/xfce-951.png) + +#### 4.1.6 用户家目录 + +用户通过鼠标左键点击快捷操作栏上的“![](./figures/xfce-96.png)”图标,点击 打开文件,打开一个用户家目录界面。 + +![图 29 用户家目录-big](./figures/xfce-961.png) + +用户通过鼠标左键点击快捷操作栏上的“![](./figures/xfce-96.png)”图标,点击 在终端中打开,打开一个终端,当前目录为用户家目录。 + +![图 30 用户家目录-big](./figures/xfce-962.png) diff --git a/docs/en/25.03/Tools/desktop/XFCE/_menu.md b/docs/en/25.03/Tools/desktop/XFCE/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..b93da97b12e58992c1f16f9e4175319d6e42fea3 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/XFCE/_menu.md @@ -0,0 +1,12 @@ +--- +label: 'XFCE用户指南' +ismanual: 'Y' +description: '安装并使用 XFCE 桌面环境' +children: + - label: '安装 XFCE' + href: './installing-Xfce.md' + - label: 'XFCE 用户指南' + href: './Xfce_userguide.md' + - label: 'XFCE 常见问题与解决方法' + href: './xfce.md' +--- diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-1.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-1.png new file mode 100644 index 0000000000000000000000000000000000000000..0e478b9f10ddf3210d5f5fada2e45329e2d1d028 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-1.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-2.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-2.png new file mode 100644 index 0000000000000000000000000000000000000000..33a946d988d499a1e98cb43968b72119bd48d7a5 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-2.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-3.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-3.png new file mode 100644 index 0000000000000000000000000000000000000000..020356f0c981fac2aafe33c8e997efbf01af9253 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-3.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-4.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-4.png new file mode 100644 index 0000000000000000000000000000000000000000..21369e366322955023b427e7a2ae63fd29b387e5 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-4.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-5.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-5.png new file mode 100644 index 0000000000000000000000000000000000000000..1f7807877f775fe6aa32652a29ef833e48e1a6ee Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-5.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-6.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-6.png new file mode 100644 index 0000000000000000000000000000000000000000..e5376fcfd1737234a885d4d95649cd996005cf0c Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-6.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-7.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-7.png new file mode 100644 index 0000000000000000000000000000000000000000..b7a94df356b7b9f7dca3d305d066ec854406aaab Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-7.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-71.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-71.png new file mode 100644 index 0000000000000000000000000000000000000000..11d1618c907d4bb18de1eb68e42e9b98d92d91c3 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-71.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-8.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-8.png new file mode 100644 index 0000000000000000000000000000000000000000..f6f97d9a173105cb6a72e4b8c48deab25ecac898 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-8.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-81.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-81.png new file mode 100644 index 0000000000000000000000000000000000000000..b97c9a81c2a07efe361e6dc6ee8bed5db445ecfa Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-81.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-811.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-811.png new file mode 100644 index 0000000000000000000000000000000000000000..58233638eca203d917081d6a9ac5003474cbf60b Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-811.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-812.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-812.png new file mode 100644 index 0000000000000000000000000000000000000000..0fc975f75da95dce8a3e5a098d024578335c9426 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-812.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-813.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-813.png new file mode 100644 index 0000000000000000000000000000000000000000..4d399468c74355cbaa765380720cb9561e95f834 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-813.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-814.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-814.png new file mode 100644 index 0000000000000000000000000000000000000000..c09fd6524a20ba04e0fca30307d35fa05e79c1f4 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-814.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-82.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-82.png new file mode 100644 index 0000000000000000000000000000000000000000..170deb5fb43f4e924d5ba4eba94a02c341d31515 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-82.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-821.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-821.png new file mode 100644 index 0000000000000000000000000000000000000000..c5c1f3567dccda3d0d49ae445612d5b9ba27e09a Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-821.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-83.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-83.png new file mode 100644 index 0000000000000000000000000000000000000000..95e4844c0ece09819d3e9f1e8457bbf371b1282e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-83.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-831.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-831.png new file mode 100644 index 0000000000000000000000000000000000000000..6456dd02f0281a5ec8d752ba5b95be581bcbfa09 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-831.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-832.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-832.png new file mode 100644 index 0000000000000000000000000000000000000000..2932aaacf71fa53f1d0c10340df3aebcc016e991 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-832.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-84.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-84.png new file mode 100644 index 0000000000000000000000000000000000000000..e0435c2edf9f68d193cff036215f32c259d378f0 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-84.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-841.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-841.png new file mode 100644 index 0000000000000000000000000000000000000000..c2c06346d4a296bfbe7836139cd943baa1ce6ea5 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-841.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-842.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-842.png new file mode 100644 index 0000000000000000000000000000000000000000..101bf6923e3780617d33dde04b92232ca7f87b42 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-842.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-85.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-85.png new file mode 100644 index 0000000000000000000000000000000000000000..21b39638fe4c83e0da5cdc69ecad9b7a22718a55 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-85.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-851.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-851.png new file mode 100644 index 0000000000000000000000000000000000000000..893064ca10399a683afbcb3752266d93b0a79a51 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-851.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-86.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-86.png new file mode 100644 index 0000000000000000000000000000000000000000..35e8a99e31e4a49eb64b24cfbab825111e40f709 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-86.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-861.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-861.png new file mode 100644 index 0000000000000000000000000000000000000000..affc46c874991a3b289e15072e06ba6566c099b1 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-861.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-87.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-87.png new file mode 100644 index 0000000000000000000000000000000000000000..47524c21d57c887c3398ea53a675f89e9f92113f Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-87.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-9.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-9.png new file mode 100644 index 0000000000000000000000000000000000000000..5586c4f62cc161665b91a56ad23b2320901901c0 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-9.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-91.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-91.png new file mode 100644 index 0000000000000000000000000000000000000000..ee69879bb4ad66405b045af5e3965e275fe8eabf Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-91.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-911.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-911.png new file mode 100644 index 0000000000000000000000000000000000000000..b49416558e9ab844fda2026b76e2e900ac106842 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-911.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-92.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-92.png new file mode 100644 index 0000000000000000000000000000000000000000..78dd6313c603aad9ebd37fe68e06f98b2a3b331e Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-92.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-921.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-921.png new file mode 100644 index 0000000000000000000000000000000000000000..5eb6f40df9ca73e11b9b9fa5079496ac0c36857b Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-921.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-93.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-93.png new file mode 100644 index 0000000000000000000000000000000000000000..06ac80c152fefbe1ad2ba1c989f6acfbbaf1a992 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-93.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-931.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-931.png new file mode 100644 index 0000000000000000000000000000000000000000..a156e5cf14ae154b93e845ff1bd5bc6ba12c9beb Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-931.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-94.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-94.png new file mode 100644 index 0000000000000000000000000000000000000000..f48064ff5902c4ea740ccba9a1640cbca27b5b72 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-94.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-941.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-941.png new file mode 100644 index 0000000000000000000000000000000000000000..f7904da12dc807836acfb9d6f24b8d9b976a2fdc Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-941.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-95.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-95.png new file mode 100644 index 0000000000000000000000000000000000000000..bda965b15a859e4cccf4b80f62875f79eb3470fd Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-95.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-951.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-951.png new file mode 100644 index 0000000000000000000000000000000000000000..6521a28275d2b63c12b47604c7afc926f7938697 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-951.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-96.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-96.png new file mode 100644 index 0000000000000000000000000000000000000000..29ce24923477065b98cacf603f185113e9959069 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-96.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-961.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-961.png new file mode 100644 index 0000000000000000000000000000000000000000..874fa200f4e63b690261d7827f3c73cf70861b32 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-961.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-962.png b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-962.png new file mode 100644 index 0000000000000000000000000000000000000000..bb84e35e43e992bc68b053a0da760bd5aa8b0270 Binary files /dev/null and b/docs/en/25.03/Tools/desktop/XFCE/figures/xfce-962.png differ diff --git a/docs/en/25.03/Tools/desktop/XFCE/installing-Xfce.md b/docs/en/25.03/Tools/desktop/XFCE/installing-Xfce.md new file mode 100644 index 0000000000000000000000000000000000000000..42c042b70c08829179749a8005af760cf7993944 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/XFCE/installing-Xfce.md @@ -0,0 +1,72 @@ +# 在 openEuler 上安装 XFCE + +XFCE是一款轻量级 Linux 桌面,当前版本已经将所有部件从 GTK2 更新到 GTK3,从D-Dbus Glib更新到GDBus,大部分组件支持Object Introspection(简称 GI,用于产生与解析 C 程序库 API 元信息,以便于动态语言(或托管语言)绑定基于 C + GObject 的程序库)。优化用户体验,加入新特性,并修补大量BUG。与其他UI界面(GNOME、KDE)相比,XFCE占用的内存和CPU使用量非常小,给用户带来亲切和高效的使用体验。 + +XFCE支持x86_64和aarch64两种架构。 + +安装时,建议新建一个管理员用户。 + +1. [下载](https://openeuler.org/zh/download/)openEuler ISO镜像并安装系统,更新软件源(需要配置Everything源,以及EPOL源,下面命令是在最小化安装系统的情况下安装XFCE) + + ```sh + # sudo dnf update + ``` + +2. 安装字库 + + ```sh + # sudo dnf install dejavu-fonts liberation-fonts gnu-*-fonts google-*-fonts + ``` + +3. 安装Xorg + + ```sh + # sudo dnf install xorg-* + ``` + +4. 安装XFCE及组件 + + ```sh + # sudo dnf install xfwm4 xfdesktop xfce4-* xfce4-*-plugin network-manager-applet *fonts + ``` + +5. 安装登录管理器 + + ```sh + # sudo dnf install lightdm lightdm-gtk + ``` + +6. 设置默认桌面为XFCE + 通过root权限用户设置 + + ```sh + # echo 'user-session=xfce' >> /etc/lightdm/lightdm.conf.d/60-lightdm-gtk-greeter.conf + ``` + +7. 使用登录管理器登录XFCE + + ```sh + # sudo systemctl start lightdm + ``` + + 登录管理器启动后,在右上角左侧选择"xfce-session" + 输入用户名、密码登录 + +8. 设置开机自启动图形界面 + + ```sh + # sudo systemctl enable lightdm + # sudo systemctl set-default graphical.target + ``` + + 如果默认安装了gdm,建议停用gdm + + ```sh + # systemctl disable gdm + ``` + + 重启验证 + + ```sh + # sudo reboot + ``` diff --git a/docs/en/25.03/Tools/desktop/XFCE/xfce.md b/docs/en/25.03/Tools/desktop/XFCE/xfce.md new file mode 100644 index 0000000000000000000000000000000000000000..8cfb01ed0b26518a2b040f81ab77dc03f7a50b97 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/XFCE/xfce.md @@ -0,0 +1,8 @@ +# 常见问题与解决方法 + +## **问题1:lightdm登录界面背景是黑色的** + +原因: 登录界面是黑色的是因为lightdm-gtk默认配置文件/etc/lightdm/lightdm-gtk-greeter.conf中没有设置background。 + +解决方法:可以在该配置文件最后的[greeter]段中设置 background=/usr/share/backgrounds/xfce/xfce-blue.jpg +然后使用“systemctl restart lightdm”命令就可以看到背景了。 diff --git a/docs/en/25.03/Tools/desktop/_menu.md b/docs/en/25.03/Tools/desktop/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..153517dcd918373974fae094a3ba82e525bbf0c6 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/_menu.md @@ -0,0 +1,8 @@ +--- +label: '图形桌面使用' +children: + - reference: './Gnome/_menu.md' + - reference: './UKUI/_menu.md' + - reference: './DDE/_menu.md' + - reference: './Kiran/_menu.md' +--- diff --git a/docs/en/25.03/Tools/desktop/index.md b/docs/en/25.03/Tools/desktop/index.md new file mode 100644 index 0000000000000000000000000000000000000000..7c3b6d7b39e81cfc91b3cb1034753b0cce836327 --- /dev/null +++ b/docs/en/25.03/Tools/desktop/index.md @@ -0,0 +1,4 @@ +--- +title: 图形桌面使用 +overview: true +--- \ No newline at end of file diff --git a/docs/en/25.03/Tools/index.md b/docs/en/25.03/Tools/index.md new file mode 100644 index 0000000000000000000000000000000000000000..b77f1e8c39acdc82d75585033103140bc92046fe --- /dev/null +++ b/docs/en/25.03/Tools/index.md @@ -0,0 +1,5 @@ + +--- +overview: true +--- + \ No newline at end of file diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/_menu.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..a40129de87dfb9c7f824a9a53dbb26829bcfd4b5 --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/_menu.md @@ -0,0 +1,29 @@ +--- +label: 'OpenStack 用户手册' +ismanual: 'Y' +description: '一个开源的云计算管理平台项目' +children: + - label: 'OpenStack SIG' + href: './index.md' + - label: '贡献指导' + href: './contribute/rpm-packaging-reference.md' + children: + - label: 'RPM开发流程' + href: './contribute/rpm-packaging-reference.md' + - label: '安装指导' + children: + - label: 'devstack' + href: './install/devstack.md' + - label: 'antelope' + href: './install/antelope.md' + - label: '自研特性' + children: + - label: '虚拟机高低优先级' + href: './spec/priority_vm.md' + - label: '流量分散' + href: './spec/distributed-traffic.md' + - label: '操作及管理指导' + children: + - label: '安全指南' + href: './security/security-guide.md' +--- diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/contribute/rpm-packaging-reference.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/contribute/rpm-packaging-reference.md new file mode 100644 index 0000000000000000000000000000000000000000..4fbb1dd0c211e8bc70eb752821a8bcc9e1d2c058 --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/contribute/rpm-packaging-reference.md @@ -0,0 +1,147 @@ +# SIG RPM 编包流程梳理 + +OpenStack SIG 有一项长期开发工作是进行 OpenStack 各版本相关 RPM 软件包的打包维护。为了方便新加入 SIG 的开发者更快了解 SIG 编包流程,在此对 SIG 编包流程进行梳理,以供参考。 + +## Excel表格说明 + +SIG 编包时,会以共享表格的形式,将需要处理的软件包整理出来,供开发者协同处理。当前表格格式如下: + +| Project Name | openEuler Repo | SIG | Repo version | Required (Min) Version | lt Version | ne Version | Upper Version | Status | Requires | Depth | Author | PR link | PR status | +|:------------:|:--------------:|:---:|:------------:|:----------------------:|:----------:|:----------:|:-------------:|:------:|:--------:|:-----:|:------:|:-------:|:---------:| +| pyrsistent| python-pyrsistent | sig-python-modules | 0.18.0 | 0.18.1 | | [] | 0.18.1 | Need Upgrade | [] | 13 | | | | +| ... | | | | | | | | | | | | | | + +“Project Name”列为软件项目名。“openEuler Repo”列为此项目在 openEuler gitee 上的仓库名,同时也是此项目在openEuler系统中的软件包名。所有 openEuler 的软件包仓库均存放于 SIG。 + +处理时首先查看“Status”列,该列表示软件包状态。软件包共有6种状态,开发者需要根据“Status”进行相应处理。 + +1. “OK”:当前版本直接可用,不需要处理。 +2. “Need Create Repo”:openEuler 系统中没有此软件包,需要在 Gitee 中的 src-openeuler repo 仓新建仓库。流程可参考社区指导文档:[新增软件包](https://gitee.com/openeuler/community/blob/master/zh/contributors/create-package.md)。创建并初始化仓库后,将软件包放入需要的 OBS 工程。 +3. “Need Create Branch”:仓库中没有所需分支,需要开发者创建并初始化。 +4. “Need Init Branch”:需要初始化分支并将此分支软件包放入需要的 OBS 工程。表明分支存在,但是里面并没有任何版本的源码包,开发者需要对此分支进行初始化,上传所需版本源码包及 spec 文件等。以22.09开发周期适配 Yoga 版本为例,此任务直接在 master 分支工作。get_gitee_project_version 项目状态为“Need Init Branch””,它对应的“python-neutron-tempest-plugin”仓库的master分支,在处理前,只有 README.md 和 README.en.md 两个文件,需要开发者初始化分支。 +5. “Need Downgrade”:降级软件包。此种情况靠后处理,与 SIG 确认后再操作。 +6. “Need Upgrade”:升级软件包。 + +确定好软件包对应的处理类型后,需要根据版本信息进行处理。“Repo version”列为当前仓库中对应分支的软件包版本。“Required (Min) Version”则是需要的最小版本,如果其后有"(Must)"标识,则表示必须使用此版本。“Upper Version”为可以使用的最高版本。如果“Required (Min) Version”和“Upper Version”不同,优先使用“Required (Min) Version”。比如升级软件包,优先升级到“Required (Min) Version”。 + +“Requires”列为软件包的依赖。“Depth”列表示软件包依赖层级。“Depth”为1的是“Depth”为0的软件包的依赖,以此类推,“Depth”高的软件包为“Depth”低的软件包的依赖。处理时应优先处理“Depth”高的行。但如果某个包,没有依赖(“Requires”为[]),也可直接处理。如果某些包需要优先处理,应按照其“Requires”,优先处理其依赖。 + +处理一个软件包时,应首先在“Author”列标注自己的名字,以告诉其他开发者此包已有人处理。pr(pull request)提交后,将 pr 链接贴到“PR link”列。pr 合并后,应在“PR status”列标注“Done”。 + +## SIG 处理编包问题流程 + +目前 SIG 处理编包问题主要使用 SIG 自己编写的 oos 工具。oos 工具细节参考 [oos README](https://gitee.com/openeuler/openstack/blob/master/tools/oos/README.md)。不同“Status”处理时涉及的“升级”、“初始化分支”、“软件包放入 OBS 工程”等操作,oos 工具有对应实现。 + +以 Yoga 版本升级 python-pyrsistent 软件包为例,演示编包流程,帮助开发者熟悉 OpenStack SIG 基于 oos 工具的打包相关流程。在了解基础流程后,开发者可通过[oos README](https://gitee.com/openeuler/openstack/blob/master/tools/oos/README.md)了解其余操作。python-pyrsistent 软件包信息参见上文表格。该软件包需要从0.18.0版本升级到0.18.1版本。Yoga 版本是在22.09版本开发规划中,当前为22年5月,直接提交到master分支即可。 + +### 签署 CLA + +在 openEuler 社区提交贡献需要签署 [CLA](https://clasign.osinfra.cn/sign/Z2l0ZWUlMkZvcGVuZXVsZXI=)。 + +对于初次参与 openEuler 社区的开发者,可首先查看[openEuler 贡献攻略](https://www.openeuler.org/zh/community/contribution/),概览整体贡献情况。 + +### 环境准备 + +```shell +dnf install rpm-build rpmdevtools git + +# 生成~/rpmbuild目录,oos默认工作路径也为此 +rpmdev-setuptree + +pip install openstack-sig-tool==1.0.6 +``` + +说明:openstack-sig-tool 在 1.1.0 版本对 `oos spec` 命令进行了[重构](https://gitee.com/openeuler/openstack/commit/9083ba741acdea4d986cb2a58069156693832d09)。如下流程涉及 `oos spec` 命令的操作对应 1.0.6 版本。建议安装新版 [oos](https://gitee.com/openeuler/openstack/tree/master/tools/oos), 并参考对应 [README](https://gitee.com/openeuler/openstack/blob/master/tools/oos/README.md) 使用。 + +### 生成个人 Gitee 帐户的 pat(personal access token) + +首先进入 Gitee 帐户的“设置”界面。 + +![设置](../img/contribute/rpm-packaging-reference/setting.png) + +选择“私人令牌”,然后点击“生成新令牌”。生成后单独保存好自己的私人令牌(pat),Gitee 上无法再次查看,如果丢失只能重新生成。 + +![私人令牌](../img/contribute/rpm-packaging-reference/pat.png) + +### 生成 python-pyrsistent 包的 spec 并提交 + +```shell +export GITEE_PAT= +oos spec push --name python-pyrsistent --version 0.18.1 -dp + +-dp, --do-push + [可选] 指定是否执行push到gitee仓库上并提交PR,如果不指定则只会提交到本地的仓库中 +``` + +注意此处 `--name` 参数为表格中的“Project Name”列。 + +`oos spec push` 命令会自动进行如下流程: + +1. fork `--name` 对应仓库到 pat 对应的 gitee 帐户。 +2. 将仓库 clone 到本地,默认路径为 `~/rpmbuild/src-repos`。 +3. 根据 `--name` 和 `--version` 下载源码包,并生成 spec 文件(读取仓库中原有 changelog)。此阶段默认路径为 `~/rpmbuild`。 +4. 本地运行 rpm 包构建。本地运行通过后,会自动将 spec 文件及源码包更新到 git 仓库。如果有 `-dp` 参数则自动进行 push 及创建 pr 操作。如果本地构建时失败,则停止流程。 + +如果本地构建失败,则可以修改生成的 spec 文件。然后执行: + +```shell +oos spec push --name python-pyrsistent --version 0.18.1 -dp -rs + +-rs, --reuse-spec + [可选] 复用已存在的spec文件,不再重新生成。 +``` + +如此循环,直至上传成功。 + +注1:升级时要通过 `oos spec push` 命令生成 spec 文件,不要使用 `oos spec build` 命令,push 命令会保留仓库中 现有 spec 的 changelog,build 命令则直接生成新的 changelog。 + +注2:处理错误时,可以参考仓库中现有的 spec 文件;当前 spec 除了 changelog 部分,其余为 oos 工具重新生成,前人遇到的错误,此处仍可能遇到,可参考前人操作结果问题。 + +注3:oos 命令还支持批量处理,可以参考 oos 的 [README](https://gitee.com/openeuler/openstack/blob/master/tools/oos/README.md) 自行尝试。 + +### PR 门禁检查 + +此时在自己的 gitee 帐户中可以看到 fork 过来的仓库。进入自己帐号中的仓库,可通过点击如下框起位置,可进入原仓库。 + +![访问原仓库](../img/contribute/rpm-packaging-reference/redirect_git_repo.png) + +原仓库中可以看到自动提交的 pr。Pr 中可以看到 openeuler-ci-bot 的评论: + +![门禁结果](../img/contribute/rpm-packaging-reference/gateway.png) + +openEuler 在 gitee 上托管的代码,提交 pr 会自动触发门禁。本地构建通过的,也有可能在门禁检查中构建失败。比如上图中此次提交便构建失败,可以点击框起部分,查看对应架构的 build details。 + +此时可以根据 build details 中日志中报错信息,对本地 spec 进行修改,而后再次执行: + +```shell +oos spec push --name python-pyrsistent --version 0.18.1 -dp -rs +``` + +线上会自动重新执行测试。 + +门禁详细信息及各项结果含义参考社区的[《门禁功能指导手册》](https://www.openeuler.org/zh/blog/zhengyaohui/2022-03-21-ci_guild.html)。 + +### PR 检视 + +当一个 pr 通过门禁检查后,需要由软件仓库所属 SIG 的 maintainer 进行 review。为了加速进程,门禁通过后,可以手动 @ 对应的 maintainer,请求帮忙检视。在 pr 提交后,openeuler-ci-bot 会有如下图所示评论,其中被 @ 的人即为当前仓库所属 SIG 的 maintainer。 + +![maintainer](../img/contribute/rpm-packaging-reference/maintainer.png) + +## 注意事项 + +这里对一些可能遇到的特殊问题进行记录。 + +### 测试未执行问题 + +oos 自动生成的 spec 文件中,%check 部分默认为 `%{__python3} setup.py test`。但是在有些包中,这样并不会真正执行测试,但门禁结果也显示通过。需要开发者人工辨别。参考方法如下: + +1. 如果是此前已有 spec 文件,可以参考之前的 spec 中 %check 部分如何书写。如果以前写的不是 `%{__python3} setup.py test`,便需要重点注意。 +2. 进入门禁的 build details(参见上文“PR 门禁检查”部分),查看构建日志的 %check 部分。下图为进入 build details,然后选择“文本方式查看”的日志显示截图。可以看到显示实际运行测试数为0。 + +![check_log](../img/contribute/rpm-packaging-reference/check_log.png) + +### 包名不一致问题 + +小部分软件包可能会碰到,oos 自动生成的 spec 所使用的的包名与现有包名不一致。比如一个使用`-`,一个使用下划线`_`。此处以原本使用的包名为准,不修改原有包名。 + +作为临时的处理,开发者可以手动将 spec 文件相关地方改为原有包名。与此同时,oos 拥有 mapping 修正功能,开发者可以提交 issue,SIG 将在 oos 中进行修复。 diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/check_log.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/check_log.png new file mode 100644 index 0000000000000000000000000000000000000000..5bcc020fcc6411a6b79dc117cbe262181c56bd63 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/check_log.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/gateway.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/gateway.png new file mode 100644 index 0000000000000000000000000000000000000000..a3553b6b7a2e45f8d64c025efb72e99d7fa92154 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/gateway.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/maintainer.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/maintainer.png new file mode 100644 index 0000000000000000000000000000000000000000..7ae5f77b2b25063e9c111df8c38373b42bc6ad9e Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/maintainer.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/pat.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/pat.png new file mode 100644 index 0000000000000000000000000000000000000000..9eaa84d9ab487ebd247d81dec6377aaaa2014276 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/pat.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/redirect_git_repo.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/redirect_git_repo.png new file mode 100644 index 0000000000000000000000000000000000000000..702c63d95a5111c7725bb9cdcfa00f42c95fd9ee Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/redirect_git_repo.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/setting.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/setting.png new file mode 100644 index 0000000000000000000000000000000000000000..5f5784ee4ae6087a3ef11f2be4cfbb2dcb212728 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/contribute/rpm-packaging-reference/setting.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/install/ironic-err.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/install/ironic-err.png new file mode 100644 index 0000000000000000000000000000000000000000..1edfa4fee7013d859ff85a4afdd81e7cbbfda2a8 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/install/ironic-err.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/install/topology1.PNG b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/install/topology1.PNG new file mode 100644 index 0000000000000000000000000000000000000000..1a23d5dbd20f230cb22420a77647b06c370ebe87 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/install/topology1.PNG differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/install/topology2.PNG b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/install/topology2.PNG new file mode 100644 index 0000000000000000000000000000000000000000..847e82a6f92a13986487a5f3967df5ecf9e791c7 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/install/topology2.PNG differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/install/topology3.PNG b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/install/topology3.PNG new file mode 100644 index 0000000000000000000000000000000000000000..b0b4d37933d79377b7273ca6f4167793580231aa Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/install/topology3.PNG differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/install/wechat_group_assistant.jpg b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/install/wechat_group_assistant.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a07ac046cb721fae6dc36d3dcdd04231f16f7e96 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/install/wechat_group_assistant.jpg differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/openEuler.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/openEuler.png new file mode 100644 index 0000000000000000000000000000000000000000..0a242257486a45f292c96ee500ef82788dd75da8 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/openEuler.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/spec/l3_scheduler.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/spec/l3_scheduler.png new file mode 100644 index 0000000000000000000000000000000000000000..79c3429a6e5bb395b3c4fcc5c5be11b02b074e88 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/spec/l3_scheduler.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/spec/router_1.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/spec/router_1.png new file mode 100644 index 0000000000000000000000000000000000000000..69bb45752768f143e91d068986bc77314443abb4 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/spec/router_1.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/spec/router_2.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/spec/router_2.png new file mode 100644 index 0000000000000000000000000000000000000000..12ff927ee38407e0f6c5d41c9c1cfa1252165375 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/spec/router_2.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/spec/router_3.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/spec/router_3.png new file mode 100644 index 0000000000000000000000000000000000000000..344fe2aeda7a6d94596b6cb1c8887edca7a4b129 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/img/spec/router_3.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/index.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/index.md new file mode 100644 index 0000000000000000000000000000000000000000..6e4cffb85a3531a4d50674394a22938cba3f2a41 --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/index.md @@ -0,0 +1,176 @@ +# openEuler OpenStack SIG + +## SIG 工作目标和范围 + +- 在openEuler之上提供原生的OpenStack,构建开放可靠的云计算技术栈。 +- 定期召开会议,收集开发者、厂商诉求,讨论OpenStack社区发展。 + +## 组织会议 + +公开的会议时间:月度例会,每月中下旬的某个周三下午3:00-4:00(北京时间) + +会议链接:通过微信群消息和邮件列表发出 + +会议纪要: + +## OpenStack版本支持列表 + +OpenStack SIG通过用户反馈等方式收集OpenStack版本需求,经过SIG组内成员公开讨论决定OpenStack的版本演进路线。规划中的版本可能因为需求更变、人力变动等原因进行调整。OpenStack SIG欢迎更多开发者、厂商参与,共同完善openEuler的OpenStack支持。 + +● - 已支持 +○ - 规划中/开发中 +▲ - 部分openEuler版本支持 + +| | Queens | Rocky | Train | Ussuri | Victoria | Wallaby | Xena | Yoga | Antelope | +|:-----------------------:|:------:|:-----:|:-----:|:------:|:--------:|:-------:|:----:|:----:|:--------:| +| openEuler 20.03 LTS SP1 | | | ● | | | | | | | +| openEuler 20.03 LTS SP2 | ● | ● | | | | | | | | +| openEuler 20.03 LTS SP3 | ● | ● | ● | | | | | | | +| openEuler 20.03 LTS SP4 | | | ● | | | | | | | +| openEuler 21.03 | | | | | ● | | | | | +| openEuler 21.09 | | | | | | ● | | | | +| openEuler 22.03 LTS | | | ● | | | ● | | | | +| openEuler 22.03 LTS SP1 | | | ● | | | ● | | | | +| openEuler 22.03 LTS SP2 | | | ● | | | ● | | | | +| openEuler 22.03 LTS SP3 | | | ● | | | ● | | | | +| openEuler 22.03 LTS SP4 | | | ● | | | ● | | | | +| openEuler 22.09 | | | | | | | | ● | ● | +| openEuler 24.03 LTS | | | | | | ● | | | ● | +| openEuler 24.03 LTS SP1 | | | | | | ● | | | ● | +| openEuler 25.03 | | | | | | | | | ● | + +| | Queens | Rocky | Train | Victoria | Wallaby | Yoga | Antelope | +|:---------: |:------:|:-----:|:-----:|:--------:|:-------:|:----:|:--------:| +| Keystone | ● | ● | ● | ● | ● | ● | ● | +| Glance | ● | ● | ● | ● | ● | ● | ● | +| Nova | ● | ● | ● | ● | ● | ● | ● | +| Cinder | ● | ● | ● | ● | ● | ● | ● | +| Neutron | ● | ● | ● | ● | ● | ● | ● | +| Tempest | ● | ● | ● | ● | ● | ● | ● | +| Horizon | ● | ● | ● | ● | ● | ● | ● | +| Ironic | ● | ● | ● | ● | ● | ● | ● | +| Placement | | | ● | ● | ● | ● | ● | +| Trove | ● | ● | ● | | ● | ● | ● | +| Kolla | ● | ● | ● | | ● | ● | ● | +| Rally | ▲ | ▲ | | | | | | +| Swift | | | ● | | ● | ● | ● | +| Heat | | | ● | | ▲ | ● | ● | +| Ceilometer | | | ● | | ▲ | ● | ● | +| Aodh | | | ● | | ▲ | ● | ● | +| Cyborg | | | ● | | ▲ | ● | ● | +| Gnocchi | | | ● | | ● | ● | ● | +| OpenStack-helm | | | | | | ● | ● | +| Barbican | | | | | ▲ | | ● | +| Octavia | | | | | ▲ | | ● | +| Designate | | | | | ▲ | | ● | +| Manila | | | | | ▲ | | ● | +| Masakari | | | | | ▲ | | ● | +| Mistral | | | | | ▲ | | ● | +| Senlin | | | | | ▲ | | ● | +| Zaqar | | | | | ▲ | | ● | + +Note: + +1. openEuler 20.03 LTS SP2不支持Rally +2. Heat、Ceilometer、Swift、Aodh和Cyborg只在22.03 LTS以上版本支持 +3. Barbican、Octavia、Designate、Manila、Masakari、Mistral、Senlin和Zaqar只在22.03 LTS SP2以上版本支持 + +## oepkg软件仓地址列表 + +Queens、Rocky、Train版本的支持放在SIG官方认证的第三方软件平台oepkg: + +- 20.03-LTS-SP1 Train: + + 该Train版本不是纯原生代码,包含了智能网卡支持的相关代码,用户使用前请自行评审 + +- 20.03-LTS-SP2 Rocky: + +- 20.03-LTS-SP3 Rocky: + +- 20.03-LTS-SP2 Queens: + +- 20.03-LTS-SP3 Rocky: + +另外,20.03-LTS-SP1虽然有Queens、Rocky版本的软件包,但未经过验证,请谨慎使用: + +- 20.03-LTS-SP1 Queens: + +- 20.03-LTS-SP1 Rocky: + +## Maintainer的加入和退出 + +秉承开源开放的理念,OpenStack SIG在maintainer成员的加入和退出方面也有一定的规范和要求。 + +### 如何成为maintainer + +maintainer作为SIG的直接负责人,拥有代码合入、路标规划、提名maintainer等方面的权利,同时也有软件质量看护、版本开发的义务。如果您想成为OpenStack SIG的一名maintainer,需要满足以下几点要求: + +1. 持续参与OpenStack SIG开发贡献,不小于一个openEuler release周期(一般为3个月) +2. 持续参与OpenStack SIG代码检视,review排名应不低于SIG平均量 +3. 定时参加OpenStack SIG例会(一般为双周一次),一个openEuler release周期一般包括6次例会,缺席次数应不大于2次 + +加分项: + +1. 积极参加OpenStack SIG组织的各种活动,比如线上分享、线下meetup或峰会等。 +2. 帮助SIG扩展运营范围,进行联合技术创新,例如主动开源新项目,吸引新的开发者、厂商加入SIG等。 + +SIG maintainer每个季度会组织闭门会议,审视当前贡献数据,根据贡献者满足相关要求,经讨论达成一致后并且贡献者愿意担任maintainer一职时,SIG会向openEuler TC提出相关申请 + +### maintainer的退出 + +当SIG maintainer因为自身原因(工作变动、业务调整等原因),无法再担任maintainer一职时,可主动申请退出。 + +SIG maintainer每半年也会例行审视当前maintainer列表,如果发现有不再适合担任maintainer的贡献者(贡献不足、不再活跃等原因),经讨论达成一致后,会向openEuler TC提出相关申请。 + +### Maintainer列表 + +|姓名|Gitee ID|邮箱|公司| +|---|---|---|---| +|陈硕|[joec88](https://gitee.com/joec88)||中国联通| +|李昆山|[liksh](https://gitee.com/liksh)||中国联通| +|黄填华|[huangtianhua](https://gitee.com/huangtianhua)||华为| +|王玺源|[xiyuanwang](https://gitee.com/xiyuanwang)||华为| +|张帆|[zh-f](https://gitee.com/zh-f)||中国电信| +|张迎|[zhangy1317](https://gitee.com/zhangy1317)||中国联通| +|韩光宇|[han-guangyu](https://gitee.com/han-guangyu)||统信软件| +|王东兴|[desert-sailor](https://gitee.com/desert-sailor)||创达奥思维| +|郑挺|[tzing_t](https://gitee.com/tzing_t)||华为| + +## 如何贡献 + +OpenStack SIG秉承OpenStack社区4个Open原则(Open source、Open Design、Open Development、Open Community),欢迎开发者、用户、厂商以各种开源方式参与SIG贡献,包括但不限于: + +1. [提交Issue](https://gitee.com/openeuler/openstack/issues/new) + 如果您在使用OpenStack时遇到了任何问题,可以向SIG提交ISSUE,包括不限于使用疑问、软件包BUG、特性需求等等。 +2. 参与技术讨论 + 通过邮件列表、微信群、在线例会等方式,与SIG成员实时讨论OpenStack技术。 +3. 参与SIG的软件开发测试工作 + 1. OpenStack SIG跟随openEuler版本开发的节奏,每几个月对外发布不同版本的OpenStack,每个版本包含了几百个RPM软件包,开发者可以参与到这些RPM包的开发工作中。 + 2. OpenStack SIG包括一些来自厂商捐献、自主研发的项目,开发者可以参与相关项目的开发工作。 + 3. openEuler新版本发布后,用户可以测试试用对应的OpenStack,相关BUG和问题可以提交到SIG。 + 4. OpenStack SIG还提供了一系列提高开发效率的工具和文档,用户可以帮忙优化、完善。 +4. 技术预言、联合创新 + OpenStack SIG欢迎各种形式的联合创新,邀请各位开发者以开源的方式、以SIG为平台,创造属于国人的云计算新技术。如果您有idea或开发意愿,欢迎加入SIG。 + +当然,贡献形式不仅包含这些,其他任何与OpenStack相关、与开源相关的事务都可以带到SIG中。OpenStack SIG欢迎您的参与。 + +## 项目清单 + +SIG包含的全部项目: + +OpenStack包含项目众多,为了方便管理,设置了统一入口项目,用户、开发者对OpenStack SIG以及各OpenStack子项目有任何问题,可以在该项目中提交Issue。 + +- + +SIG同时联合各大厂商、开发者,创建了一系列自研项目: + +- +- +- +- +- + +## 交流群 + +添加小助手回复"加群"进入openEuler sig-OpenStack交流群 +![assistant](img/install/wechat_group_assistant.jpg) diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/install/antelope.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/install/antelope.md new file mode 100644 index 0000000000000000000000000000000000000000..1749e7fd01954ec82d7a8459e6886ad9ff606528 --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/install/antelope.md @@ -0,0 +1,3720 @@ +# OpenStack Antelope 部署指南 + +[TOC] + +本文档是 openEuler OpenStack SIG 编写的基于 |openEuler 25.03 的 OpenStack 部署指南,内容由 SIG 贡献者提供。在阅读过程中,如果您有任何疑问或者发现任何问题,请[联系](https://gitee.com/openeuler/openstack#%E8%81%94%E7%B3%BB%E6%96%B9%E5%BC%8F)SIG维护人员,或者直接[提交issue](https://gitee.com/openeuler/openstack/issues) + +**约定** + +本章节描述文档中的一些通用约定。 + +| 名称 | 定义 | +|:----:|:----:| +| RABBIT_PASS | rabbitmq的密码,由用户设置,在OpenStack各个服务配置中使用 | +| CINDER_PASS | cinder服务keystone用户的密码,在cinder配置中使用| +| CINDER_DBPASS | cinder服务数据库密码,在cinder配置中使用| +| KEYSTONE_DBPASS | keystone服务数据库密码,在keystone配置中使用| +| GLANCE_PASS | glance服务keystone用户的密码,在glance配置中使用| +| GLANCE_DBPASS | glance服务数据库密码,在glance配置中使用| +| HEAT_PASS | 在keystone注册的heat用户密码,在heat配置中使用| +| HEAT_DBPASS | heat服务数据库密码,在heat配置中使用 | +| CYBORG_PASS | 在keystone注册的cyborg用户密码,在cyborg配置中使用| +| CYBORG_DBPASS | cyborg服务数据库密码,在cyborg配置中使用 | +| NEUTRON_PASS | 在keystone注册的neutron用户密码,在neutron配置中使用| +| NEUTRON_DBPASS | neutron服务数据库密码,在neutron配置中使用 | +| PROVIDER_INTERFACE_NAME | 物理网络接口的名称,在neutron配置中使用 | +| OVERLAY_INTERFACE_IP_ADDRESS | Controller控制节点的管理ip地址,在neutron配置中使用 | +| METADATA_SECRET | metadata proxy的secret密码,在nova和neutron配置中使用 | +| PLACEMENT_DBPASS | placement服务数据库密码,在placement配置中使用 | +| PLACEMENT_PASS | 在keystone注册的placement用户密码,在placement配置中使用 | +| NOVA_DBPASS | nova服务数据库密码,在nova配置中使用 | +| NOVA_PASS | 在keystone注册的nova用户密码,在nova,cyborg,neutron等配置中使用 | +| IRONIC_DBPASS | ironic服务数据库密码,在ironic配置中使用 | +| IRONIC_PASS | 在keystone注册的ironic用户密码,在ironic配置中使用 | +| IRONIC_INSPECTOR_DBPASS | ironic-inspector服务数据库密码,在ironic-inspector配置中使用| +| IRONIC_INSPECTOR_PASS | 在keystone注册的ironic-inspector用户密码,在ironic-inspector配置中使用 | + +OpenStack SIG 提供了多种基于 openEuler 部署 OpenStack 的方法,以满足不同的用户场景,请按需选择。 + +## 基于RPM部署 + +### 环境准备 + +本文档基于OpenStack经典的三节点环境进行部署,三个节点分别是控制节点(Controller)、计算节点(Compute)、存储节点(Storage),其中存储节点一般只部署存储服务,在资源有限的情况下,可以不单独部署该节点,把存储节点上的服务部署到计算节点即可。 + +首先准备三个|openEuler 25.03环境,根据您的环境,下载对应的镜像并安装即可:[ISO镜像]、[qcow2镜像]。 + +下面的安装按照如下拓扑进行: + +```shell +controller:192.168.0.2 +compute: 192.168.0.3 +storage: 192.168.0.4 +``` + +如果您的环境IP不同,请按照您的环境IP修改相应的配置文件。 + +本文档的三节点服务拓扑如下图所示(只包含Keystone、Glance、Nova、Cinder、Neutron这几个核心服务,其他服务请参考具体部署章节): + +![topology1](../img/install/topology1.PNG) +![topology2](../img/install/topology2.PNG) +![topology3](../img/install/topology3.PNG) + +在正式部署之前,需要对每个节点做如下配置和检查: + +1. 配置 |openEuler 25.03 官方 yum 源,需要启用 EPOL 软件仓以支持 OpenStack + + ```shell + yum update + yum install openstack-release-antelope + yum clean all && yum makecache + ``` + + **注意**:如果你的环境的YUM源没有启用EPOL,需要同时配置EPOL,确保EPOL已配置,如下所示。 + + ```shell + vi /etc/yum.repos.d/openEuler.repo + + [EPOL] + name=EPOL + baseurl=http://repo.openeuler.org/openEuler-24.03-LTS-SP1/EPOL/main/$basearch/ + enabled=1 + gpgcheck=1 + gpgkey=http://repo.openeuler.org/openEuler-24.03-LTS-SP1/OS/$basearch/RPM-GPG-KEY-openEuler + EOF + ``` + +2. 修改主机名以及映射 + + 每个节点分别修改主机名,以controller为例: + + ```shell + hostnamectl set-hostname controller + + vi /etc/hostname + 内容修改为controller + ``` + + 然后修改每个节点的`/etc/hosts`文件,新增如下内容: + + ```shell + 192.168.0.2 controller + 192.168.0.3 compute + 192.168.0.4 storage + ``` + +#### 时钟同步 + +集群环境时刻要求每个节点的时间一致,一般由时钟同步软件保证。本文使用`chrony`软件。步骤如下: + +**Controller节点**: + +1. 安装服务 + + ```shell + dnf install chrony + ``` + +2. 修改`/etc/chrony.conf`配置文件,新增一行 + + ```shell + # 表示允许哪些IP从本节点同步时钟 + allow 192.168.0.0/24 + ``` + +3. 重启服务 + + ```shell + systemctl restart chronyd + ``` + +**其他节点** + +1. 安装服务 + + ```shell + dnf install chrony + ``` + +2. 修改`/etc/chrony.conf`配置文件,新增一行 + + ```shell + # NTP_SERVER是controller IP,表示从这个机器获取时间,这里我们填192.168.0.2,或者在`/etc/hosts`里配置好的controller名字即可。 + server NTP_SERVER iburst + ``` + + 同时,要把`pool pool.ntp.org iburst`这一行注释掉,表示不从公网同步时钟。 + +3. 重启服务 + + ```shell + systemctl restart chronyd + ``` + +配置完成后,检查一下结果,在其他非controller节点执行`chronyc sources`,返回结果类似如下内容,表示成功从controller同步时钟。 + +```ini +MS Name/IP address Stratum Poll Reach LastRx Last sample +=============================================================================== +^* 192.168.0.2 4 6 7 0 -1406ns[ +55us] +/- 16ms +``` + +#### 安装数据库 + +数据库安装在控制节点,这里推荐使用mariadb。 + +1. 安装软件包 + + ```shell + dnf install mysql-config mariadb mariadb-server python3-PyMySQL + ``` + +2. 新增配置文件`/etc/my.cnf.d/openstack.cnf`,内容如下 + + ```shell + [mysqld] + bind-address = 192.168.0.2 + default-storage-engine = innodb + innodb_file_per_table = on + max_connections = 4096 + collation-server = utf8_general_ci + character-set-server = utf8 + ``` + +3. 启动服务器 + + ```shell + systemctl start mariadb + ``` + +4. 初始化数据库,根据提示进行即可 + + ```shell + mysql_secure_installation + ``` + + 示例如下: + + ```shell + NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB + SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY! + + In order to log into MariaDB to secure it, we'll need the current + password for the root user. If you've just installed MariaDB, and + haven't set the root password yet, you should just press enter here. + + Enter current password for root (enter for none): + + #这里输入密码,由于我们是初始化DB,直接回车就行 + + OK, successfully used password, moving on... + + Setting the root password or using the unix_socket ensures that nobody + can log into the MariaDB root user without the proper authorisation. + + You already have your root account protected, so you can safely answer 'n'. + + # 这里根据提示输入N + + Switch to unix_socket authentication [Y/n] N + + Enabled successfully! + Reloading privilege tables.. + ... Success! + + + You already have your root account protected, so you can safely answer 'n'. + + # 输入Y,修改密码 + + Change the root password? [Y/n] Y + + New password: + Re-enter new password: + Password updated successfully! + Reloading privilege tables.. + ... Success! + + + By default, a MariaDB installation has an anonymous user, allowing anyone + to log into MariaDB without having to have a user account created for + them. This is intended only for testing, and to make the installation + go a bit smoother. You should remove them before moving into a + production environment. + + # 输入Y,删除匿名用户 + + Remove anonymous users? [Y/n] Y + ... Success! + + Normally, root should only be allowed to connect from 'localhost'. This + ensures that someone cannot guess at the root password from the network. + + # 输入Y,关闭root远程登录权限 + + Disallow root login remotely? [Y/n] Y + ... Success! + + By default, MariaDB comes with a database named 'test' that anyone can + access. This is also intended only for testing, and should be removed + before moving into a production environment. + + # 输入Y,删除test数据库 + + Remove test database and access to it? [Y/n] Y + - Dropping test database... + ... Success! + - Removing privileges on test database... + ... Success! + + Reloading the privilege tables will ensure that all changes made so far + will take effect immediately. + + # 输入Y,重载配置 + + Reload privilege tables now? [Y/n] Y + ... Success! + + Cleaning up... + + All done! If you've completed all of the above steps, your MariaDB + installation should now be secure. + ``` + +5. 验证,根据第四步设置的密码,检查是否能登录mariadb + + ```shell + mysql -uroot -p + ``` + +#### 安装消息队列 + +消息队列安装在控制节点,这里推荐使用rabbitmq。 + +1. 安装软件包 + + ```shell + dnf install rabbitmq-server + ``` + +2. 启动服务 + + ```shell + systemctl start rabbitmq-server + ``` + +3. 配置openstack用户,`RABBIT_PASS`是openstack服务登录消息队里的密码,需要和后面各个服务的配置保持一致。 + + ```shell + rabbitmqctl add_user openstack RABBIT_PASS + rabbitmqctl set_permissions openstack ".*" ".*" ".*" + ``` + +#### 安装缓存服务 + +缓存服务安装在控制节点,这里推荐使用Memcached。 + +1. 安装软件包 + + ```shell + dnf install memcached python3-memcached + ``` + +2. 修改配置文件`/etc/sysconfig/memcached` + + ```shell + OPTIONS="-l 127.0.0.1,::1,controller" + ``` + +3. 启动服务 + + ```shell + systemctl start memcached + ``` + +### 部署服务 + +#### Keystone + +Keystone是OpenStack提供的鉴权服务,是整个OpenStack的入口,提供了租户隔离、用户认证、服务发现等功能,必须安装。 + +1. 创建 keystone 数据库并授权 + + ``` sql + mysql -u root -p + + MariaDB [(none)]> CREATE DATABASE keystone; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' \ + IDENTIFIED BY 'KEYSTONE_DBPASS'; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' \ + IDENTIFIED BY 'KEYSTONE_DBPASS'; + MariaDB [(none)]> exit + ``` + + ***注意*** + + **替换 `KEYSTONE_DBPASS`,为 Keystone 数据库设置密码** + +2. 安装软件包 + + ```shell + dnf install openstack-keystone httpd mod_wsgi + ``` + +3. 配置keystone相关配置 + + ```shell + vim /etc/keystone/keystone.conf + + [database] + connection = mysql+pymysql://keystone:KEYSTONE_DBPASS@controller/keystone + + [token] + provider = fernet + ``` + + ***解释*** + + [database]部分,配置数据库入口 + + [token]部分,配置token provider + +4. 同步数据库 + + ```shell + su -s /bin/sh -c "keystone-manage db_sync" keystone + ``` + +5. 初始化Fernet密钥仓库 + + ```shell + keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone + keystone-manage credential_setup --keystone-user keystone --keystone-group keystone + ``` + +6. 启动服务 + + ```shell + keystone-manage bootstrap --bootstrap-password ADMIN_PASS \ + --bootstrap-admin-url http://controller:5000/v3/ \ + --bootstrap-internal-url http://controller:5000/v3/ \ + --bootstrap-public-url http://controller:5000/v3/ \ + --bootstrap-region-id RegionOne + ``` + + ***注意*** + + **替换 `ADMIN_PASS`,为 admin 用户设置密码** + +7. 配置Apache HTTP server + + - 打开httpd.conf并配置 + + ```shell + #需要修改的配置文件路径 + vim /etc/httpd/conf/httpd.conf + + #修改以下项,如果没有则新添加 + ServerName controller + ``` + + - 创建软链接 + + ```shell + ln -s /usr/share/keystone/wsgi-keystone.conf /etc/httpd/conf.d/ + ``` + + ***解释*** + + 配置 `ServerName` 项引用控制节点 + + ***注意*** + **如果 `ServerName` 项不存在则需要创建** + +8. 启动Apache HTTP服务 + + ```shell + systemctl enable httpd.service + systemctl start httpd.service + ``` + +9. 创建环境变量配置 + + ```shell + cat << EOF >> ~/.admin-openrc + export OS_PROJECT_DOMAIN_NAME=Default + export OS_USER_DOMAIN_NAME=Default + export OS_PROJECT_NAME=admin + export OS_USERNAME=admin + export OS_PASSWORD=ADMIN_PASS + export OS_AUTH_URL=http://controller:5000/v3 + export OS_IDENTITY_API_VERSION=3 + export OS_IMAGE_API_VERSION=2 + EOF + ``` + + ***注意*** + + **替换 `ADMIN_PASS` 为 admin 用户的密码** + +10. 依次创建domain, projects, users, roles + + - 需要先安装python3-openstackclient + + ```shell + dnf install python3-openstackclient + ``` + + - 导入环境变量 + + ```shell + source ~/.admin-openrc + ``` + + - 创建project `service`,其中 domain `default` 在 keystone-manage bootstrap 时已创建 + + ```shell + openstack domain create --description "An Example Domain" example + ``` + + ```shell + openstack project create --domain default --description "Service Project" service + ``` + + - 创建(non-admin)project `myproject`,user `myuser` 和 role `myrole`,为 `myproject` 和 `myuser` 添加角色`myrole` + + ```shell + openstack project create --domain default --description "Demo Project" myproject + openstack user create --domain default --password-prompt myuser + openstack role create myrole + openstack role add --project myproject --user myuser myrole + ``` + +11. 验证 + + - 取消临时环境变量OS_AUTH_URL和OS_PASSWORD: + + ```shell + source ~/.admin-openrc + unset OS_AUTH_URL OS_PASSWORD + ``` + + - 为admin用户请求token: + + ```shell + openstack --os-auth-url http://controller:5000/v3 \ + --os-project-domain-name Default --os-user-domain-name Default \ + --os-project-name admin --os-username admin token issue + ``` + + - 为myuser用户请求token: + + ```shell + openstack --os-auth-url http://controller:5000/v3 \ + --os-project-domain-name Default --os-user-domain-name Default \ + --os-project-name myproject --os-username myuser token issue + ``` + +#### Glance + +Glance是OpenStack提供的镜像服务,负责虚拟机、裸机镜像的上传与下载,必须安装。 + +**Controller节点**: + +1. 创建 glance 数据库并授权 + + ```sql + mysql -u root -p + + MariaDB [(none)]> CREATE DATABASE glance; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' \ + IDENTIFIED BY 'GLANCE_DBPASS'; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' \ + IDENTIFIED BY 'GLANCE_DBPASS'; + MariaDB [(none)]> exit + ``` + + ***注意:*** + + **替换 `GLANCE_DBPASS`,为 glance 数据库设置密码** + +2. 初始化 glance 资源对象 + + - 导入环境变量 + + ```shell + source ~/.admin-openrc + ``` + + - 创建用户时,命令行会提示输入密码,请输入自定义的密码,下文涉及到`GLANCE_PASS`的地方替换成该密码即可。 + + ```shell + openstack user create --domain default --password-prompt glance + User Password: + Repeat User Password: + ``` + + - 添加glance用户到service project并指定admin角色: + + ```shell + openstack role add --project service --user glance admin + ``` + + - 创建glance服务实体: + + ```shell + openstack service create --name glance --description "OpenStack Image" image + ``` + + - 创建glance API服务: + + ```shell + openstack endpoint create --region RegionOne image public http://controller:9292 + openstack endpoint create --region RegionOne image internal http://controller:9292 + openstack endpoint create --region RegionOne image admin http://controller:9292 + ``` + +3. 安装软件包 + + ```shell + dnf install openstack-glance + ``` + +4. 修改 glance 配置文件 + + ```shell + vim /etc/glance/glance-api.conf + + [database] + connection = mysql+pymysql://glance:GLANCE_DBPASS@controller/glance + + [keystone_authtoken] + www_authenticate_uri = http://controller:5000 + auth_url = http://controller:5000 + memcached_servers = controller:11211 + auth_type = password + project_domain_name = Default + user_domain_name = Default + project_name = service + username = glance + password = GLANCE_PASS + + [paste_deploy] + flavor = keystone + + [glance_store] + stores = file,http + default_store = file + filesystem_store_datadir = /var/lib/glance/images/ + ``` + + ***解释:*** + + [database]部分,配置数据库入口 + + [keystone_authtoken] [paste_deploy]部分,配置身份认证服务入口 + + [glance_store]部分,配置本地文件系统存储和镜像文件的位置 + +5. 同步数据库 + + ```shell + su -s /bin/sh -c "glance-manage db_sync" glance + ``` + +6. 启动服务: + + ```shell + systemctl enable openstack-glance-api.service + systemctl start openstack-glance-api.service + ``` + +7. 验证 + + - 导入环境变量 + + ```shell + source ~/.admin-openrcu + ``` + + - 下载镜像 + + ```shell + x86镜像下载: + wget http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img + + arm镜像下载: + wget http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-aarch64-disk.img + ``` + + ***注意*** + + **如果您使用的环境是鲲鹏架构,请下载aarch64版本的镜像;已对镜像cirros-0.5.2-aarch64-disk.img进行测试。** + + - 向Image服务上传镜像: + + ```shell + openstack image create --disk-format qcow2 --container-format bare \ + --file cirros-0.4.0-x86_64-disk.img --public cirros + ``` + + - 确认镜像上传并验证属性: + + ```shell + openstack image list + ``` + +#### Placement + +Placement是OpenStack提供的资源调度组件,一般不面向用户,由Nova等组件调用,安装在控制节点。 + +安装、配置Placement服务前,需要先创建相应的数据库、服务凭证和API endpoints。 + +1. 创建数据库 + + - 使用root用户访问数据库服务: + + ```shell + mysql -u root -p + ``` + + - 创建placement数据库: + + ```sql + MariaDB [(none)]> CREATE DATABASE placement; + ``` + + - 授权数据库访问: + + ```sql + MariaDB [(none)]> GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'localhost' \ + IDENTIFIED BY 'PLACEMENT_DBPASS'; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'%' \ + IDENTIFIED BY 'PLACEMENT_DBPASS'; + ``` + + 替换`PLACEMENT_DBPASS`为placement数据库访问密码。 + + - 退出数据库访问客户端: + + ```shell + exit + ``` + +2. 配置用户和Endpoints + + - source admin凭证,以获取admin命令行权限: + + ```shell + source ~/.admin-openrc + ``` + + - 创建placement用户并设置用户密码: + + ```shell + openstack user create --domain default --password-prompt placement + + User Password: + Repeat User Password: + ``` + + - 添加placement用户到service project并指定admin角色: + + ```shell + openstack role add --project service --user placement admin + ``` + + - 创建placement服务实体: + + ```shell + openstack service create --name placement \ + --description "Placement API" placement + ``` + + - 创建Placement API服务endpoints: + + ```shell + openstack endpoint create --region RegionOne \ + placement public http://controller:8778 + openstack endpoint create --region RegionOne \ + placement internal http://controller:8778 + openstack endpoint create --region RegionOne \ + placement admin http://controller:8778 + ``` + +3. 安装及配置组件 + + - 安装软件包: + + ```shell + dnf install openstack-placement-api + ``` + + - 编辑`/etc/placement/placement.conf`配置文件,完成如下操作: + + - 在`[placement_database]`部分,配置数据库入口: + + ```ini + [placement_database] + connection = mysql+pymysql://placement:PLACEMENT_DBPASS@controller/placement + ``` + + 替换`PLACEMENT_DBPASS`为placement数据库的密码。 + + - 在`[api]`和`[keystone_authtoken]`部分,配置身份认证服务入口: + + ```ini + [api] + auth_strategy = keystone + + [keystone_authtoken] + auth_url = http://controller:5000/v3 + memcached_servers = controller:11211 + auth_type = password + project_domain_name = Default + user_domain_name = Default + project_name = service + username = placement + password = PLACEMENT_PASS + ``` + + 替换`PLACEMENT_PASS`为placement用户的密码。 + + - 数据库同步,填充Placement数据库: + + ```shell + su -s /bin/sh -c "placement-manage db sync" placement + ``` + +4. 启动服务 + + 重启httpd服务: + + ```shell + systemctl restart httpd + ``` + +5. 验证 + + - source admin凭证,以获取admin命令行权限 + + ```shell + source ~/.admin-openrc + ``` + + - 执行状态检查: + + ```shell + placement-status upgrade check + ``` + + ```ini + +----------------------------------------------------------------------+ + | Upgrade Check Results | + +----------------------------------------------------------------------+ + | Check: Missing Root Provider IDs | + | Result: Success | + | Details: None | + +----------------------------------------------------------------------+ + | Check: Incomplete Consumers | + | Result: Success | + | Details: None | + +----------------------------------------------------------------------+ + | Check: Policy File JSON to YAML Migration | + | Result: Failure | + | Details: Your policy file is JSON-formatted which is deprecated. You | + | need to switch to YAML-formatted file. Use the | + | ``oslopolicy-convert-json-to-yaml`` tool to convert the | + | existing JSON-formatted files to YAML in a backwards- | + | compatible manner: https://docs.openstack.org/oslo.policy/ | + | latest/cli/oslopolicy-convert-json-to-yaml.html. | + +----------------------------------------------------------------------+ + ``` + + 这里可以看到``Policy File JSON to YAML Migration``的结果为Failure。这是因为在Placement中,JSON格式的policy文件从Wallaby版本开始已处于`deprecated`状态。可以参考提示,使用[oslopolicy-convert-json-to-yaml](https://docs.openstack.org/oslo.policy/latest/cli/oslopolicy-convert-json-to-yaml.html)工具 将现有的JSON格式policy文件转化为YAML格式。 + + ```shell + oslopolicy-convert-json-to-yaml --namespace placement \ + --policy-file /etc/placement/policy.json \ + --output-file /etc/placement/policy.yaml + mv /etc/placement/policy.json{,.bak} + ``` + + 注:当前环境中此问题可忽略,不影响运行。 + + - 针对placement API运行命令: + + - 安装osc-placement插件: + + ```shell + dnf install python3-osc-placement + ``` + + - 列出可用的资源类别及特性: + + ```shell + openstack --os-placement-api-version 1.2 resource class list --sort-column name + +----------------------------+ + | name | + +----------------------------+ + | DISK_GB | + | FPGA | + | ... | + + openstack --os-placement-api-version 1.6 trait list --sort-column name + +---------------------------------------+ + | name | + +---------------------------------------+ + | COMPUTE_ACCELERATORS | + | COMPUTE_ARCH_AARCH64 | + | ... | + ``` + +#### Nova + +Nova是OpenStack的计算服务,负责虚拟机的创建、发放等功能。 + +**Controller节点** + +在控制节点执行以下操作。 + +1. 创建数据库 + + - 使用root用户访问数据库服务: + + ```shell + mysql -u root -p + ``` + + - 创建`nova_api`、`nova`和`nova_cell0`数据库: + + ```sql + MariaDB [(none)]> CREATE DATABASE nova_api; + MariaDB [(none)]> CREATE DATABASE nova; + MariaDB [(none)]> CREATE DATABASE nova_cell0; + ``` + + - 授权数据库访问: + + ```sql + MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'localhost' \ + IDENTIFIED BY 'NOVA_DBPASS'; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'%' \ + IDENTIFIED BY 'NOVA_DBPASS'; + + MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' \ + IDENTIFIED BY 'NOVA_DBPASS'; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' \ + IDENTIFIED BY 'NOVA_DBPASS'; + + MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'localhost' \ + IDENTIFIED BY 'NOVA_DBPASS'; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'%' \ + IDENTIFIED BY 'NOVA_DBPASS'; + ``` + + 替换`NOVA_DBPASS`为nova相关数据库访问密码。 + + - 退出数据库访问客户端: + + ```sql + exit + ``` + +2. 配置用户和Endpoints + + - source admin凭证,以获取admin命令行权限: + + ```shell + source ~/.admin-openrc + ``` + + - 创建nova用户并设置用户密码: + + ```shell + openstack user create --domain default --password-prompt nova + + User Password: + Repeat User Password: + ``` + + - 添加nova用户到service project并指定admin角色: + + ```shell + openstack role add --project service --user nova admin + ``` + + - 创建nova服务实体: + + ```shell + openstack service create --name nova \ + --description "OpenStack Compute" compute + ``` + + - 创建Nova API服务endpoints: + + ```shell + openstack endpoint create --region RegionOne \ + compute public http://controller:8774/v2.1 + openstack endpoint create --region RegionOne \ + compute internal http://controller:8774/v2.1 + openstack endpoint create --region RegionOne \ + compute admin http://controller:8774/v2.1 + ``` + +3. 安装及配置组件 + + - 安装软件包: + + ```shell + dnf install openstack-nova-api openstack-nova-conductor \ + openstack-nova-novncproxy openstack-nova-scheduler + ``` + + - 编辑`/etc/nova/nova.conf`配置文件,完成如下操作: + + - 在`[default]`部分,启用计算和元数据的API,配置RabbitMQ消息队列入口,使用controller节点管理IP配置my_ip,显式定义log_dir: + + ```ini + [DEFAULT] + enabled_apis = osapi_compute,metadata + transport_url = rabbit://openstack:RABBIT_PASS@controller:5672/ + my_ip = 192.168.0.2 + log_dir = /var/log/nova + state_path = /var/lib/nova + ``` + + 替换`RABBIT_PASS`为RabbitMQ中openstack账户的密码。 + + - 在`[api_database]`和`[database]`部分,配置数据库入口: + + ```ini + [api_database] + connection = mysql+pymysql://nova:NOVA_DBPASS@controller/nova_api + + [database] + connection = mysql+pymysql://nova:NOVA_DBPASS@controller/nova + ``` + + 替换`NOVA_DBPASS`为nova相关数据库的密码。 + + - 在`[api]`和`[keystone_authtoken]`部分,配置身份认证服务入口: + + ```ini + [api] + auth_strategy = keystone + + [keystone_authtoken] + auth_url = http://controller:5000/v3 + memcached_servers = controller:11211 + auth_type = password + project_domain_name = Default + user_domain_name = Default + project_name = service + username = nova + password = NOVA_PASS + ``` + + 替换`NOVA_PASS`为nova用户的密码。 + + - 在`[vnc]`部分,启用并配置远程控制台入口: + + ```ini + [vnc] + enabled = true + server_listen = $my_ip + server_proxyclient_address = $my_ip + ``` + + - 在`[glance]`部分,配置镜像服务API的地址: + + ```ini + [glance] + api_servers = http://controller:9292 + ``` + + - 在`[oslo_concurrency]`部分,配置lock path: + + ```ini + [oslo_concurrency] + lock_path = /var/lib/nova/tmp + ``` + + - [placement]部分,配置placement服务的入口: + + ```ini + [placement] + region_name = RegionOne + project_domain_name = Default + project_name = service + auth_type = password + user_domain_name = Default + auth_url = http://controller:5000/v3 + username = placement + password = PLACEMENT_PASS + ``` + + 替换`PLACEMENT_PASS`为placement用户的密码。 + + - 数据库同步: + + - 同步nova-api数据库: + + ```shell + su -s /bin/sh -c "nova-manage api_db sync" nova + ``` + + - 注册cell0数据库: + + ```shell + su -s /bin/sh -c "nova-manage cell_v2 map_cell0" nova + ``` + + - 创建cell1 cell: + + ```shell + su -s /bin/sh -c "nova-manage cell_v2 create_cell --name=cell1 --verbose" nova + ``` + + - 同步nova数据库: + + ```shell + su -s /bin/sh -c "nova-manage db sync" nova + ``` + + - 验证cell0和cell1注册正确: + + ```shell + su -s /bin/sh -c "nova-manage cell_v2 list_cells" nova + ``` + +4. 启动服务 + + ```shell + systemctl enable \ + openstack-nova-api.service \ + openstack-nova-scheduler.service \ + openstack-nova-conductor.service \ + openstack-nova-novncproxy.service + + systemctl start \ + openstack-nova-api.service \ + openstack-nova-scheduler.service \ + openstack-nova-conductor.service \ + openstack-nova-novncproxy.service + ``` + +**Compute节点** + +在计算节点执行以下操作。 + +1. 安装软件包 + + ```shell + dnf install openstack-nova-compute + ``` + +2. 编辑`/etc/nova/nova.conf`配置文件 + + - 在`[default]`部分,启用计算和元数据的API,配置RabbitMQ消息队列入口,使用Compute节点管理IP配置my_ip,显式定义compute_driver、instances_path、log_dir: + + ```ini + [DEFAULT] + enabled_apis = osapi_compute,metadata + transport_url = rabbit://openstack:RABBIT_PASS@controller:5672/ + my_ip = 192.168.0.3 + compute_driver = libvirt.LibvirtDriver + instances_path = /var/lib/nova/instances + log_dir = /var/log/nova + ``` + + 替换`RABBIT_PASS`为RabbitMQ中openstack账户的密码。 + + - 在`[api]`和`[keystone_authtoken]`部分,配置身份认证服务入口: + + ```ini + [api] + auth_strategy = keystone + + [keystone_authtoken] + auth_url = http://controller:5000/v3 + memcached_servers = controller:11211 + auth_type = password + project_domain_name = Default + user_domain_name = Default + project_name = service + username = nova + password = NOVA_PASS + ``` + + 替换`NOVA_PASS`为nova用户的密码。 + + - 在`[vnc]`部分,启用并配置远程控制台入口: + + ```ini + [vnc] + enabled = true + server_listen = $my_ip + server_proxyclient_address = $my_ip + novncproxy_base_url = http://controller:6080/vnc_auto.html + ``` + + - 在`[glance]`部分,配置镜像服务API的地址: + + ```ini + [glance] + api_servers = http://controller:9292 + ``` + + - 在`[oslo_concurrency]`部分,配置lock path: + + ```ini + [oslo_concurrency] + lock_path = /var/lib/nova/tmp + ``` + + - [placement]部分,配置placement服务的入口: + + ```ini + [placement] + region_name = RegionOne + project_domain_name = Default + project_name = service + auth_type = password + user_domain_name = Default + auth_url = http://controller:5000/v3 + username = placement + password = PLACEMENT_PASS + ``` + + 替换`PLACEMENT_PASS`为placement用户的密码。 + +3. 确认计算节点是否支持虚拟机硬件加速(x86_64) + + 处理器为x86_64架构时,可通过运行如下命令确认是否支持硬件加速: + + ```shell + egrep -c '(vmx|svm)' /proc/cpuinfo + ``` + + 如果返回值为0则不支持硬件加速,需要配置libvirt使用QEMU而不是默认的KVM。编辑`/etc/nova/nova.conf`的`[libvirt]`部分: + + ```ini + [libvirt] + virt_type = qemu + ``` + + 如果返回值为1或更大的值,则支持硬件加速,不需要进行额外的配置。 + +4. 确认计算节点是否支持虚拟机硬件加速(arm64) + + 处理器为arm64架构时,可通过运行如下命令确认是否支持硬件加速: + + ```shell + virt-host-validate + # 该命令由libvirt提供,此时libvirt应已作为openstack-nova-compute依赖被安装,环境中已有此命令 + ``` + + 显示FAIL时,表示不支持硬件加速,需要配置libvirt使用QEMU而不是默认的KVM。 + + ```shell + QEMU: Checking if device /dev/kvm exists: FAIL (Check that CPU and firmware supports virtualization and kvm module is loaded) + ``` + + 编辑`/etc/nova/nova.conf`的`[libvirt]`部分: + + ```ini + [libvirt] + virt_type = qemu + ``` + + 显示PASS时,表示支持硬件加速,不需要进行额外的配置。 + + ```shell + QEMU: Checking if device /dev/kvm exists: PASS + ``` + +5. 配置qemu(仅arm64) + + 仅当处理器为arm64架构时需要执行此操作。 + + - 编辑`/etc/libvirt/qemu.conf`: + + ```ini + nvram = ["/usr/share/AAVMF/AAVMF_CODE.fd: \ + /usr/share/AAVMF/AAVMF_VARS.fd", \ + "/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw: \ + /usr/share/edk2/aarch64/vars-template-pflash.raw"] + ``` + + - 编辑`/etc/qemu/firmware/edk2-aarch64.json` + + ```json + { + "description": "UEFI firmware for ARM64 virtual machines", + "interface-types": [ + "uefi" + ], + "mapping": { + "device": "flash", + "executable": { + "filename": "/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw", + "format": "raw" + }, + "nvram-template": { + "filename": "/usr/share/edk2/aarch64/vars-template-pflash.raw", + "format": "raw" + } + }, + "targets": [ + { + "architecture": "aarch64", + "machines": [ + "virt-*" + ] + } + ], + "features": [ + + ], + "tags": [ + + ] + } + ``` + +6. 启动服务 + + ```shell + systemctl enable libvirtd.service openstack-nova-compute.service + systemctl start libvirtd.service openstack-nova-compute.service + ``` + +**Controller节点** + +在控制节点执行以下操作。 + +1. 添加计算节点到openstack集群 + + - source admin凭证,以获取admin命令行权限: + + ```shell + source ~/.admin-openrc + ``` + + - 确认nova-compute服务已识别到数据库中: + + ```shell + openstack compute service list --service nova-compute + ``` + + - 发现计算节点,将计算节点添加到cell数据库: + + ```shell + su -s /bin/sh -c "nova-manage cell_v2 discover_hosts --verbose" nova + ``` + + 结果如下: + + ```ini + Modules with known eventlet monkey patching issues were imported prior to eventlet monkey patching: urllib3. This warning can usually be ignored if the caller is only importing and not executing nova code. + Found 2 cell mappings. + Skipping cell0 since it does not contain hosts. + Getting computes from cell 'cell1': 6dae034e-b2d9-4a6c-b6f0-60ada6a6ddc2 + Checking host mapping for compute host 'compute': 6286a86f-09d7-4786-9137-1185654c9e2e + Creating host mapping for compute host 'compute': 6286a86f-09d7-4786-9137-1185654c9e2e + Found 1 unmapped computes in cell: 6dae034e-b2d9-4a6c-b6f0-60ada6a6ddc2 + ``` + +2. 验证 + + - 列出服务组件,验证每个流程都成功启动和注册: + + ```shell + openstack compute service list + ``` + + - 列出身份服务中的API端点,验证与身份服务的连接: + + ```shell + openstack catalog list + ``` + + - 列出镜像服务中的镜像,验证与镜像服务的连接: + + ```shell + openstack image list + ``` + + - 检查cells是否运作成功,以及其他必要条件是否已具备。 + + ```shell + nova-status upgrade check + ``` + +#### Neutron + +Neutron是OpenStack的网络服务,提供虚拟交换机、IP路由、DHCP等功能。 + +**Controller节点** + +1. 创建数据库、服务凭证和 API 服务端点 + + - 创建数据库: + + ```sql + mysql -u root -p + + MariaDB [(none)]> CREATE DATABASE neutron; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' IDENTIFIED BY 'NEUTRON_DBPASS'; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' IDENTIFIED BY 'NEUTRON_DBPASS'; + MariaDB [(none)]> exit; + ``` + + - 创建用户和服务,并记住创建neutron用户时输入的密码,用于配置NEUTRON_PASS: + + ```shell + source ~/.admin-openrc + openstack user create --domain default --password-prompt neutron + openstack role add --project service --user neutron admin + openstack service create --name neutron --description "OpenStack Networking" network + ``` + + - 部署 Neutron API 服务: + + ```shell + openstack endpoint create --region RegionOne network public http://controller:9696 + openstack endpoint create --region RegionOne network internal http://controller:9696 + openstack endpoint create --region RegionOne network admin http://controller:9696 + ``` + +2. 安装软件包 + + ```shell + dnf install -y openstack-neutron openstack-neutron-linuxbridge ebtables ipset openstack-neutron-ml2 + ``` + +3. 配置Neutron + + - 修改/etc/neutron/neutron.conf + + ```ini + [database] + connection = mysql+pymysql://neutron:NEUTRON_DBPASS@controller/neutron + + [DEFAULT] + core_plugin = ml2 + service_plugins = router + allow_overlapping_ips = true + transport_url = rabbit://openstack:RABBIT_PASS@controller + auth_strategy = keystone + notify_nova_on_port_status_changes = true + notify_nova_on_port_data_changes = true + + [keystone_authtoken] + www_authenticate_uri = http://controller:5000 + auth_url = http://controller:5000 + memcached_servers = controller:11211 + auth_type = password + project_domain_name = Default + user_domain_name = Default + project_name = service + username = neutron + password = NEUTRON_PASS + + [nova] + auth_url = http://controller:5000 + auth_type = password + project_domain_name = Default + user_domain_name = Default + region_name = RegionOne + project_name = service + username = nova + password = NOVA_PASS + + [oslo_concurrency] + lock_path = /var/lib/neutron/tmp + + [experimental] + linuxbridge = true + ``` + + - 配置ML2,ML2具体配置可以根据用户需求自行修改,本文使用的是provider network + linuxbridge** + + - 修改/etc/neutron/plugins/ml2/ml2_conf.ini + + ```shell + [ml2] + type_drivers = flat,vlan,vxlan + tenant_network_types = vxlan + mechanism_drivers = linuxbridge,l2population + extension_drivers = port_security + + [ml2_type_flat] + flat_networks = provider + + [ml2_type_vxlan] + vni_ranges = 1:1000 + + [securitygroup] + enable_ipset = true + ``` + + - 修改/etc/neutron/plugins/ml2/linuxbridge_agent.ini + + ```ini + [linux_bridge] + physical_interface_mappings = provider:PROVIDER_INTERFACE_NAME + + [vxlan] + enable_vxlan = true + local_ip = OVERLAY_INTERFACE_IP_ADDRESS + l2_population = true + + [securitygroup] + enable_security_group = true + firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver + ``` + + - 配置Layer-3代理 + + - 修改/etc/neutron/l3_agent.ini + + ```shell + [DEFAULT] + interface_driver = linuxbridge + ``` + + 配置DHCP代理 + 修改/etc/neutron/dhcp_agent.ini + + ```ini + [DEFAULT] + interface_driver = linuxbridge + dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq + enable_isolated_metadata = true + ``` + + - 配置metadata代理 + + - 修改/etc/neutron/metadata_agent.ini + + ```shell + [DEFAULT] + nova_metadata_host = controller + metadata_proxy_shared_secret = METADATA_SECRET + ``` + +4. 配置nova服务使用neutron,修改/etc/nova/nova.conf + + ```ini + [neutron] + auth_url = http://controller:5000 + auth_type = password + project_domain_name = default + user_domain_name = default + region_name = RegionOne + project_name = service + username = neutron + password = NEUTRON_PASS + service_metadata_proxy = true + metadata_proxy_shared_secret = METADATA_SECRET + ``` + +5. 创建/etc/neutron/plugin.ini的符号链接 + + ```shell + ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini + ``` + +6. 同步数据库 + + ```shell + su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head" neutron + ``` + +7. 重启nova api服务 + + ```shell + systemctl restart openstack-nova-api + ``` + +8. 启动网络服务 + + ```shell + systemctl enable neutron-server.service neutron-linuxbridge-agent.service \ + neutron-dhcp-agent.service neutron-metadata-agent.service neutron-l3-agent.service + systemctl start neutron-server.service neutron-linuxbridge-agent.service \ + neutron-dhcp-agent.service neutron-metadata-agent.service neutron-l3-agent.service + ``` + +**Compute节点** + +1. 安装软件包 + + ```shell + dnf install openstack-neutron-linuxbridge ebtables ipset -y + ``` + +2. 配置Neutron + + - 修改/etc/neutron/neutron.conf + + ```ini + [DEFAULT] + transport_url = rabbit://openstack:RABBIT_PASS@controller + auth_strategy = keystone + + [keystone_authtoken] + www_authenticate_uri = http://controller:5000 + auth_url = http://controller:5000 + memcached_servers = controller:11211 + auth_type = password + project_domain_name = Default + user_domain_name = Default + project_name = service + username = neutron + password = NEUTRON_PASS + + [oslo_concurrency] + lock_path = /var/lib/neutron/tmp + ``` + + - 修改/etc/neutron/plugins/ml2/linuxbridge_agent.ini + + ```ini + [linux_bridge] + physical_interface_mappings = provider:PROVIDER_INTERFACE_NAME + + [vxlan] + enable_vxlan = true + local_ip = OVERLAY_INTERFACE_IP_ADDRESS + l2_population = true + + [securitygroup] + enable_security_group = true + firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver + ``` + + - 配置nova compute服务使用neutron,修改/etc/nova/nova.conf + + ```ini + [neutron] + auth_url = http://controller:5000 + auth_type = password + project_domain_name = default + user_domain_name = default + region_name = RegionOne + project_name = service + username = neutron + password = NEUTRON_PASS + ``` + +3. 重启nova-compute服务 + + ```shell + systemctl restart openstack-nova-compute.service + ``` + +4. 启动Neutron linuxbridge agent服务 + + ```shell + systemctl enable neutron-linuxbridge-agent + systemctl start neutron-linuxbridge-agent + ``` + +#### Cinder + +Cinder是OpenStack的存储服务,提供块设备的创建、发放、备份等功能。 + +**Controller节点**: + +1. 初始化数据库 + + `CINDER_DBPASS`是用户自定义的cinder数据库密码。 + + ```sql + mysql -u root -p + + MariaDB [(none)]> CREATE DATABASE cinder; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'localhost' IDENTIFIED BY 'CINDER_DBPASS'; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'%' IDENTIFIED BY 'CINDER_DBPASS'; + MariaDB [(none)]> exit + ``` + +2. 初始化Keystone资源对象 + + ```shell + source ~/.admin-openrc + + #创建用户时,命令行会提示输入密码,请输入自定义的密码,下文涉及到`CINDER_PASS`的地方替换成该密码即可。 + openstack user create --domain default --password-prompt cinder + + openstack role add --project service --user cinder admin + openstack service create --name cinderv3 --description "OpenStack Block Storage" volumev3 + + openstack endpoint create --region RegionOne volumev3 public http://controller:8776/v3/%\(project_id\)s + openstack endpoint create --region RegionOne volumev3 internal http://controller:8776/v3/%\(project_id\)s + openstack endpoint create --region RegionOne volumev3 admin http://controller:8776/v3/%\(project_id\)s + ``` + +3. 安装软件包 + + ```shell + dnf install openstack-cinder-api openstack-cinder-scheduler + ``` + +4. 修改cinder配置文件`/etc/cinder/cinder.conf` + + ```ini + [DEFAULT] + transport_url = rabbit://openstack:RABBIT_PASS@controller + auth_strategy = keystone + my_ip = 192.168.0.2 + + [database] + connection = mysql+pymysql://cinder:CINDER_DBPASS@controller/cinder + + [keystone_authtoken] + www_authenticate_uri = http://controller:5000 + auth_url = http://controller:5000 + memcached_servers = controller:11211 + auth_type = password + project_domain_name = Default + user_domain_name = Default + project_name = service + username = cinder + password = CINDER_PASS + + [oslo_concurrency] + lock_path = /var/lib/cinder/tmp + ``` + +5. 数据库同步 + + ```shell + su -s /bin/sh -c "cinder-manage db sync" cinder + ``` + +6. 修改nova配置`/etc/nova/nova.conf` + + ```ini + [cinder] + os_region_name = RegionOne + ``` + +7. 启动服务 + + ```shell + systemctl restart openstack-nova-api + systemctl start openstack-cinder-api openstack-cinder-scheduler + ``` + +**Storage节点**: + +Storage节点要提前准备至少一块硬盘,作为cinder的存储后端,下文默认storage节点已经存在一块未使用的硬盘,设备名称为`/dev/sdb`,用户在配置过程中,请按照真实环境信息进行名称替换。 + +Cinder支持很多类型的后端存储,本指导使用最简单的lvm为参考,如果您想使用如ceph等其他后端,请自行配置。 + +1. 安装软件包 + + ```shell + dnf install lvm2 device-mapper-persistent-data scsi-target-utils rpcbind nfs-utils openstack-cinder-volume openstack-cinder-backup + ``` + +2. 配置lvm卷组 + + ```shell + pvcreate /dev/sdb + vgcreate cinder-volumes /dev/sdb + ``` + +3. 修改cinder配置`/etc/cinder/cinder.conf` + + ```ini + [DEFAULT] + transport_url = rabbit://openstack:RABBIT_PASS@controller + auth_strategy = keystone + my_ip = 192.168.0.4 + enabled_backends = lvm + glance_api_servers = http://controller:9292 + + [keystone_authtoken] + www_authenticate_uri = http://controller:5000 + auth_url = http://controller:5000 + memcached_servers = controller:11211 + auth_type = password + project_domain_name = default + user_domain_name = default + project_name = service + username = cinder + password = CINDER_PASS + + [database] + connection = mysql+pymysql://cinder:CINDER_DBPASS@controller/cinder + + [lvm] + volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver + volume_group = cinder-volumes + target_protocol = iscsi + target_helper = lioadm + + [oslo_concurrency] + lock_path = /var/lib/cinder/tmp + ``` + +4. 配置cinder backup (可选) + + cinder-backup是可选的备份服务,cinder同样支持很多种备份后端,本文使用swift存储,如果您想使用如NFS等后端,请自行配置,例如可以参考[OpenStack官方文档](https://docs.openstack.org/cinder/2023.1/admin/nfs-backend.html)对NFS的配置说明。 + + 修改`/etc/cinder/cinder.conf`,在`[DEFAULT]`中新增 + + ```ini + [DEFAULT] + backup_driver = cinder.backup.drivers.swift.SwiftBackupDriver + backup_swift_url = SWIFT_URL + ``` + + 这里的`SWIFT_URL`是指环境中swift服务的URL,在部署完swift服务后,执行`openstack catalog show object-store`命令获取。 + +5. 启动服务 + + ```shell + systemctl start openstack-cinder-volume target + systemctl start openstack-cinder-backup (可选) + ``` + +至此,Cinder服务的部署已全部完成,可以在controller通过以下命令进行简单的验证 + +```shell +source ~/.admin-openrc +openstack storage service list +openstack volume list +``` + +#### Horizon + +Horizon是OpenStack提供的前端页面,可以让用户通过网页鼠标的操作来控制OpenStack集群,而不用繁琐的CLI命令行。Horizon一般部署在控制节点。 + +1. 安装软件包 + + ```shell + dnf install openstack-dashboard + ``` + +2. 修改配置文件`/etc/openstack-dashboard/local_settings` + + ```ini + OPENSTACK_HOST = "controller" + ALLOWED_HOSTS = ['*', ] + OPENSTACK_KEYSTONE_URL = "http://controller:5000/v3" + SESSION_ENGINE = 'django.contrib.sessions.backends.cache' + CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', + 'LOCATION': 'controller:11211', + } + } + OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True + OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = "Default" + OPENSTACK_KEYSTONE_DEFAULT_ROLE = "member" + WEBROOT = '/dashboard' + POLICY_FILES_PATH = "/etc/openstack-dashboard" + + OPENSTACK_API_VERSIONS = { + "identity": 3, + "image": 2, + "volume": 3, + } + ``` + +3. 重启服务 + + ```shell + systemctl restart httpd + ``` + +至此,horizon服务的部署已全部完成,打开浏览器,输入`http://192.168.0.2/dashboard`,打开horizon登录页面。 + +#### Ironic + +Ironic是OpenStack的裸金属服务,如果用户需要进行裸机部署则推荐使用该组件。否则,可以不用安装。 + +在控制节点执行以下操作。 + +1. 设置数据库 + + 裸金属服务在数据库中存储信息,创建一个**ironic**用户可以访问的**ironic**数据库,替换**IRONIC_DBPASS**为合适的密码 + + ```sql + mysql -u root -p + + MariaDB [(none)]> CREATE DATABASE ironic CHARACTER SET utf8; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON ironic.* TO 'ironic'@'localhost' \ + IDENTIFIED BY 'IRONIC_DBPASS'; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON ironic.* TO 'ironic'@'%' \ + IDENTIFIED BY 'IRONIC_DBPASS'; + MariaDB [(none)]> exit + Bye + ``` + +2. 创建服务用户认证 + + - 创建Bare Metal服务用户 + + 替换`IRONIC_PASS`为ironic用户密码,`IRONIC_INSPECTOR_PASS`为ironic_inspector用户密码。 + + ```shell + openstack user create --password IRONIC_PASS \ + --email ironic@example.com ironic + openstack role add --project service --user ironic admin + openstack service create --name ironic \ + --description "Ironic baremetal provisioning service" baremetal + + openstack service create --name ironic-inspector --description "Ironic inspector baremetal provisioning service" baremetal-introspection + openstack user create --password IRONIC_INSPECTOR_PASS --email ironic_inspector@example.com ironic-inspector + openstack role add --project service --user ironic-inspector admin + ``` + + - 创建Bare Metal服务访问入口 + + ```shell + openstack endpoint create --region RegionOne baremetal admin http://192.168.0.2:6385 + openstack endpoint create --region RegionOne baremetal public http://192.168.0.2:6385 + openstack endpoint create --region RegionOne baremetal internal http://192.168.0.2:6385 + openstack endpoint create --region RegionOne baremetal-introspection internal http://192.168.0.2:5050/v1 + openstack endpoint create --region RegionOne baremetal-introspection public http://192.168.0.2:5050/v1 + openstack endpoint create --region RegionOne baremetal-introspection admin http://192.168.0.2:5050/v1 + ``` + +3. 安装组件 + + ```shell + dnf install openstack-ironic-api openstack-ironic-conductor python3-ironicclient + ``` + +4. 配置ironic-api服务 + + 配置文件路径/etc/ironic/ironic.conf + + - 通过**connection**选项配置数据库的位置,如下所示,替换**IRONIC_DBPASS**为**ironic**用户的密码,替换**DB_IP**为DB服务器所在的IP地址: + + ```ini + [database] + + # The SQ LAlchemy connection string used to connect to the + # database (string value) + # connection = mysql+pymysql://ironic:IRONIC_DBPASS@DB_IP/ironic + connection = mysql+pymysql://ironic:IRONIC_DBPASS@controller/ironic + ``` + + - 通过以下选项配置ironic-api服务使用RabbitMQ消息代理,替换**RPC_\***为RabbitMQ的详细地址和凭证 + + ```ini + [DEFAULT] + + # A URL representing the messaging driver to use and its full + # configuration. (string value) + # transport_url = rabbit://RPC_USER:RPC_PASSWORD@RPC_HOST:RPC_PORT/ + transport_url = rabbit://openstack:RABBIT_PASS@controller:5672/ + ``` + + 用户也可自行使用json-rpc方式替换rabbitmq + + - 配置ironic-api服务使用身份认证服务的凭证,替换**PUBLIC_IDENTITY_IP**为身份认证服务器的公共IP,替换**PRIVATE_IDENTITY_IP**为身份认证服务器的私有IP,替换 **IRONIC_PASS**为身份认证服务中**ironic**用户的密码,替换**RABBIT_PASS**为RabbitMQ中openstack账户的密码。: + + ```ini + [DEFAULT] + + # Authentication strategy used by ironic-api: one of + # "keystone" or "noauth". "noauth" should not be used in a + # production environment because all authentication will be + # disabled. (string value) + + auth_strategy=keystone + host = controller + memcache_servers = controller:11211 + enabled_network_interfaces = flat,noop,neutron + default_network_interface = noop + enabled_hardware_types = ipmi + enabled_boot_interfaces = pxe + enabled_deploy_interfaces = direct + default_deploy_interface = direct + enabled_inspect_interfaces = inspector + enabled_management_interfaces = ipmitool + enabled_power_interfaces = ipmitool + enabled_rescue_interfaces = no-rescue,agent + isolinux_bin = /usr/share/syslinux/isolinux.bin + logging_context_format_string = %(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(global_request_id)s %(request_id)s % (user_identity)s] %(instance)s%(message)s + + [keystone_authtoken] + # Authentication type to load (string value) + auth_type=password + # Complete public Identity API endpoint (string value) + # www_authenticate_uri=http://PUBLIC_IDENTITY_IP:5000 + www_authenticate_uri=http://controller:5000 + # Complete admin Identity API endpoint. (string value) + # auth_url=http://PRIVATE_IDENTITY_IP:5000 + auth_url=http://controller:5000 + # Service username. (string value) + username=ironic + # Service account password. (string value) + password=IRONIC_PASS + # Service tenant name. (string value) + project_name=service + # Domain name containing project (string value) + project_domain_name=Default + # User's domain name (string value) + user_domain_name=Default + + [agent] + deploy_logs_collect = always + deploy_logs_local_path = /var/log/ironic/deploy + deploy_logs_storage_backend = local + image_download_source = http + stream_raw_images = false + force_raw_images = false + verify_ca = False + + [oslo_concurrency] + + [oslo_messaging_notifications] + transport_url = rabbit://openstack:RABBIT_PASS@controller:5672/ + topics = notifications + driver = messagingv2 + + [oslo_messaging_rabbit] + amqp_durable_queues = True + rabbit_ha_queues = True + + [pxe] + ipxe_enabled = false + pxe_append_params = nofb nomodeset vga=normal coreos.autologin ipa-insecure=1 + image_cache_size = 204800 + tftp_root=/var/lib/tftpboot/cephfs/ + tftp_master_path=/var/lib/tftpboot/cephfs/master_images + + [dhcp] + dhcp_provider = none + ``` + + - 创建裸金属服务数据库表 + + ```shell + ironic-dbsync --config-file /etc/ironic/ironic.conf create_schema + ``` + + - 重启ironic-api服务 + + ```shell + sudo systemctl restart openstack-ironic-api + ``` + +5. 配置ironic-conductor服务 + + 如下为ironic-conductor服务自身的标准配置,ironic-conductor服务可以与ironic-api服务分布于不同节点,本指南中均部署与控制节点,所以重复的配置项可跳过。 + + - 替换使用conductor服务所在host的IP配置my_ip: + + ```ini + [DEFAULT] + + # IP address of this host. If unset, will determine the IP + # programmatically. If unable to do so, will use "127.0.0.1". + # (string value) + # my_ip=HOST_IP + my_ip = 192.168.0.2 + ``` + + - 配置数据库的位置,ironic-conductor应该使用和ironic-api相同的配置。替换**IRONIC_DBPASS**为**ironic**用户的密码: + + ```ini + [database] + + # The SQLAlchemy connection string to use to connect to the + # database. (string value) + connection = mysql+pymysql://ironic:IRONIC_DBPASS@controller/ironic + ``` + + - 通过以下选项配置ironic-api服务使用RabbitMQ消息代理,ironic-conductor应该使用和ironic-api相同的配置,替换**RABBIT_PASS**为RabbitMQ中openstack账户的密码: + + ```ini + [DEFAULT] + + # A URL representing the messaging driver to use and its full + # configuration. (string value) + transport_url = rabbit://openstack:RABBIT_PASS@controller:5672/ + ``` + + 用户也可自行使用json-rpc方式替换rabbitmq + + - 配置凭证访问其他OpenStack服务 + + 为了与其他OpenStack服务进行通信,裸金属服务在请求其他服务时需要使用服务用户与OpenStack Identity服务进行认证。这些用户的凭据必须在与相应服务相关的每个配置文件中进行配置。 + + ```shell + [neutron] - 访问OpenStack网络服务 + [glance] - 访问OpenStack镜像服务 + [swift] - 访问OpenStack对象存储服务 + [cinder] - 访问OpenStack块存储服务 + [inspector] - 访问OpenStack裸金属introspection服务 + [service_catalog] - 一个特殊项用于保存裸金属服务使用的凭证,该凭证用于发现注册在OpenStack身份认证服务目录中的自己的API URL端点 + ``` + + 简单起见,可以对所有服务使用同一个服务用户。为了向后兼容,该用户应该和ironic-api服务的[keystone_authtoken]所配置的为同一个用户。但这不是必须的,也可以为每个服务创建并配置不同的服务用户。 + + 在下面的示例中,用户访问OpenStack网络服务的身份验证信息配置为: + + ```ini + 网络服务部署在名为RegionOne的身份认证服务域中,仅在服务目录中注册公共端点接口 + + 请求时使用特定的CA SSL证书进行HTTPS连接 + + 与ironic-api服务配置相同的服务用户 + + 动态密码认证插件基于其他选项发现合适的身份认证服务API版本 + ``` + + 替换IRONIC_PASS为ironic用户密码。 + + ```ini + [neutron] + + # Authentication type to load (string value) + auth_type = password + # Authentication URL (string value) + auth_url=https://IDENTITY_IP:5000/ + # Username (string value) + username=ironic + # User's password (string value) + password=IRONIC_PASS + # Project name to scope to (string value) + project_name=service + # Domain ID containing project (string value) + project_domain_id=default + # User's domain id (string value) + user_domain_id=default + # PEM encoded Certificate Authority to use when verifying + # HTTPs connections. (string value) + cafile=/opt/stack/data/ca-bundle.pem + # The default region_name for endpoint URL discovery. (string + # value) + region_name = RegionOne + # List of interfaces, in order of preference, for endpoint + # URL. (list value) + valid_interfaces=public + + # 其他参考配置 + [glance] + endpoint_override = http://controller:9292 + www_authenticate_uri = http://controller:5000 + auth_url = http://controller:5000 + auth_type = password + username = ironic + password = IRONIC_PASS + project_domain_name = default + user_domain_name = default + region_name = RegionOne + project_name = service + + [service_catalog] + region_name = RegionOne + project_domain_id = default + user_domain_id = default + project_name = service + password = IRONIC_PASS + username = ironic + auth_url = http://controller:5000 + auth_type = password + ``` + + 默认情况下,为了与其他服务进行通信,裸金属服务会尝试通过身份认证服务的服务目录发现该服务合适的端点。如果希望对一个特定服务使用一个不同的端点,则在裸金属服务的配置文件中通过endpoint_override选项进行指定: + + ```ini + [neutron] + endpoint_override = + ``` + + - 配置允许的驱动程序和硬件类型 + + 通过设置enabled_hardware_types设置ironic-conductor服务允许使用的硬件类型: + + ```ini + [DEFAULT] + enabled_hardware_types = ipmi + ``` + + 配置硬件接口: + + ```ini + enabled_boot_interfaces = pxe + enabled_deploy_interfaces = direct,iscsi + enabled_inspect_interfaces = inspector + enabled_management_interfaces = ipmitool + enabled_power_interfaces = ipmitool + ``` + + 配置接口默认值: + + ```ini + [DEFAULT] + default_deploy_interface = direct + default_network_interface = neutron + ``` + + 如果启用了任何使用Direct deploy的驱动,必须安装和配置镜像服务的Swift后端。Ceph对象网关(RADOS网关)也支持作为镜像服务的后端。 + + - 重启ironic-conductor服务 + + ```shell + sudo systemctl restart openstack-ironic-conductor + ``` + +6. 配置ironic-inspector服务 + + - 安装组件 + + ```shell + dnf install openstack-ironic-inspector + ``` + + - 创建数据库 + + ```sql + # mysql -u root -p + + MariaDB [(none)]> CREATE DATABASE ironic_inspector CHARACTER SET utf8; + + MariaDB [(none)]> GRANT ALL PRIVILEGES ON ironic_inspector.* TO 'ironic_inspector'@'localhost' \ + IDENTIFIED BY 'IRONIC_INSPECTOR_DBPASS'; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON ironic_inspector.* TO 'ironic_inspector'@'%' \ + IDENTIFIED BY 'IRONIC_INSPECTOR_DBPASS'; + MariaDB [(none)]> exit + Bye + ``` + + - 配置`/etc/ironic-inspector/inspector.conf` + + 通过**connection**选项配置数据库的位置,如下所示,替换**IRONIC_INSPECTOR_DBPASS**为**ironic_inspector**用户的密码 + + ```ini + [database] + backend = sqlalchemy + connection = mysql+pymysql://ironic_inspector:IRONIC_INSPECTOR_DBPASS@controller/ironic_inspector + min_pool_size = 100 + max_pool_size = 500 + pool_timeout = 30 + max_retries = 5 + max_overflow = 200 + db_retry_interval = 2 + db_inc_retry_interval = True + db_max_retry_interval = 2 + db_max_retries = 5 + ``` + + - 配置消息队列通信地址 + + ```ini + [DEFAULT] + transport_url = rabbit://openstack:RABBIT_PASS@controller:5672/ + ``` + + - 设置keystone认证 + + ```ini + [DEFAULT] + + auth_strategy = keystone + timeout = 900 + rootwrap_config = /etc/ironic-inspector/rootwrap.conf + logging_context_format_string = %(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(global_request_id)s %(request_id)s % (user_identity)s] %(instance)s%(message)s + log_dir = /var/log/ironic-inspector + state_path = /var/lib/ironic-inspector + use_stderr = False + + [ironic] + api_endpoint = http://IRONIC_API_HOST_ADDRRESS:6385 + auth_type = password + auth_url = http://PUBLIC_IDENTITY_IP:5000 + auth_strategy = keystone + ironic_url = http://IRONIC_API_HOST_ADDRRESS:6385 + os_region = RegionOne + project_name = service + project_domain_name = Default + user_domain_name = Default + username = IRONIC_SERVICE_USER_NAME + password = IRONIC_SERVICE_USER_PASSWORD + + [keystone_authtoken] + auth_type = password + auth_url = http://controller:5000 + www_authenticate_uri = http://controller:5000 + project_domain_name = default + user_domain_name = default + project_name = service + username = ironic_inspector + password = IRONICPASSWD + region_name = RegionOne + memcache_servers = controller:11211 + token_cache_time = 300 + + [processing] + add_ports = active + processing_hooks = $default_processing_hooks,local_link_connection,lldp_basic + ramdisk_logs_dir = /var/log/ironic-inspector/ramdisk + always_store_ramdisk_logs = true + store_data =none + power_off = false + + [pxe_filter] + driver = iptables + + [capabilities] + boot_mode=True + ``` + + - 配置ironic inspector dnsmasq服务 + + ```ini + # 配置文件地址:/etc/ironic-inspector/dnsmasq.conf + port=0 + interface=enp3s0 #替换为实际监听网络接口 + dhcp-range=192.168.0.40,192.168.0.50 #替换为实际dhcp地址范围 + bind-interfaces + enable-tftp + + dhcp-match=set:efi,option:client-arch,7 + dhcp-match=set:efi,option:client-arch,9 + dhcp-match=aarch64, option:client-arch,11 + dhcp-boot=tag:aarch64,grubaa64.efi + dhcp-boot=tag:!aarch64,tag:efi,grubx64.efi + dhcp-boot=tag:!aarch64,tag:!efi,pxelinux.0 + + tftp-root=/tftpboot #替换为实际tftpboot目录 + log-facility=/var/log/dnsmasq.log + ``` + + - 关闭ironic provision网络子网的dhcp + + ```shell + openstack subnet set --no-dhcp 72426e89-f552-4dc4-9ac7-c4e131ce7f3c + ``` + + - 初始化ironic-inspector服务的数据库 + + ```shell + ironic-inspector-dbsync --config-file /etc/ironic-inspector/inspector.conf upgrade + ``` + + - 启动服务 + + ```shell + systemctl enable --now openstack-ironic-inspector.service + systemctl enable --now openstack-ironic-inspector-dnsmasq.service + ``` + +7. 配置httpd服务 + + - 创建ironic要使用的httpd的root目录并设置属主属组,目录路径要和/etc/ironic/ironic.conf中[deploy]组中http_root 配置项指定的路径要一致。 + + ```shell + mkdir -p /var/lib/ironic/httproot + chown ironic.ironic /var/lib/ironic/httproot + ``` + + - 安装和配置httpd服务 + + - 安装httpd服务,已有请忽略 + + ```shell + dnf install httpd -y + ``` + + - 创建/etc/httpd/conf.d/openstack-ironic-httpd.conf文件,内容如下: + + ```ini + Listen 8080 + + + ServerName ironic.openeuler.com + + ErrorLog "/var/log/httpd/openstack-ironic-httpd-error_log" + CustomLog "/var/log/httpd/openstack-ironic-httpd-access_log" "%h %l %u %t \"%r\" %>s %b" + + DocumentRoot "/var/lib/ironic/httproot" + + Options Indexes FollowSymLinks + Require all granted + + LogLevel warn + AddDefaultCharset UTF-8 + EnableSendfile on + + ``` + + 注意监听的端口要和/etc/ironic/ironic.conf里[deploy]选项中http_url配置项中指定的端口一致。 + + - 重启httpd服务。 + + ```shell + systemctl restart httpd + ``` + +8. deploy ramdisk镜像下载或制作 + + 部署一个裸机节点总共需要两组镜像:deploy ramdisk images和user images。Deploy ramdisk images上运行有ironic-python-agent(IPA)服务,Ironic通过它进行裸机节点的环境准备。User images是最终被安装裸机节点上,供用户使用的镜像。 + + ramdisk镜像支持通过ironic-python-agent-builder或disk-image-builder工具制作。用户也可以自行选择其他工具制作。若使用原生工具,则需要安装对应的软件包。 + + 具体的使用方法可以参考[官方文档](https://docs.openstack.org/ironic/2023.1/install/deploy-ramdisk.html),同时官方也有提供制作好的deploy镜像,可尝试下载。 + + 下文介绍通过ironic-python-agent-builder构建ironic使用的deploy镜像的完整过程。 + + - 安装 ironic-python-agent-builder + + ```shell + dnf install python3-ironic-python-agent-builder + + 或 + pip3 install ironic-python-agent-builder + dnf install qemu-img git + ``` + + - 制作镜像 + + 基本用法: + + ```shell + usage: ironic-python-agent-builder [-h] [-r RELEASE] [-o OUTPUT] [-e ELEMENT] [-b BRANCH] + [-v] [--lzma] [--extra-args EXTRA_ARGS] + [--elements-path ELEMENTS_PATH] + distribution + + positional arguments: + distribution Distribution to use + + options: + -h, --help show this help message and exit + -r RELEASE, --release RELEASE + Distribution release to use + -o OUTPUT, --output OUTPUT + Output base file name + -e ELEMENT, --element ELEMENT + Additional DIB element to use + -b BRANCH, --branch BRANCH + If set, override the branch that is used for ironic-python-agent + and requirements + -v, --verbose Enable verbose logging in diskimage-builder + --lzma Use lzma compression for smaller images + --extra-args EXTRA_ARGS + Extra arguments to pass to diskimage-builder + --elements-path ELEMENTS_PATH + Path(s) to custom DIB elements separated by a colon + ``` + + 操作实例: + + ```shell + # -o选项指定生成的镜像名 + # ubuntu指定生成ubuntu系统的镜像 + ironic-python-agent-builder -o my-ubuntu-ipa ubuntu + ``` + + 可通过设置`ARCH`环境变量(默认为amd64)指定所构建镜像的架构。如果是`arm`架构,需要添加: + + ```shell + export ARCH=aarch64 + ``` + + - 允许ssh登录 + + 初始化环境变量,设置用户名、密码,启用`sodo`权限;并添加`-e`选项使用相应的DIB元素。制作镜像操作如下: + + ```shell + export DIB_DEV_USER_USERNAME=ipa \ + export DIB_DEV_USER_PWDLESS_SUDO=yes \ + export DIB_DEV_USER_PASSWORD='123' + ironic-python-agent-builder -o my-ssh-ubuntu-ipa -e selinux-permissive -e devuser ubuntu + ``` + + - 指定代码仓库 + + 初始化对应的环境变量,然后制作镜像: + + ```shell + # 直接从gerrit上clone代码 + DIB_REPOLOCATION_ironic_python_agent=https://opendev.org/openstack/ironic-python-agent + DIB_REPOREF_ironic_python_agent=stable/2023.1 + + # 指定本地仓库及分支 + DIB_REPOLOCATION_ironic_python_agent=/home/user/path/to/repo + DIB_REPOREF_ironic_python_agent=my-test-branch + + ironic-python-agent-builder ubuntu + ``` + + 参考:[source-repositories](https://docs.openstack.org/diskimage-builder/latest/elements/source-repositories/README.html)。 + +9. 注意 + + 原生的openstack里的pxe配置文件的模版不支持arm64架构,需要自己对原生openstack代码进行修改: + 在W版中,社区的ironic仍然不支持arm64位的uefi pxe启动,表现为生成的grub.cfg文件(一般位于/tftpboot/下)格式不对而导致pxe启动失败。 + + 生成的错误配置文件: + + ![ironic-err](../img/install/ironic-err.png) + + 如上图所示,arm架构里寻找vmlinux和ramdisk镜像的命令分别是linux和initrd,上图所示的标红命令是x86架构下的uefi pxe启动。 + + 需要用户对生成grub.cfg的代码逻辑自行修改。 + + ironic向ipa发送查询命令执行状态请求的tls报错: + + 当前版本的ipa和ironic默认都会开启tls认证的方式向对方发送请求,跟据官网的说明进行关闭即可。 + + - 修改ironic配置文件(/etc/ironic/ironic.conf)下面的配置中添加ipa-insecure=1: + + ```ini + [agent] + verify_ca = False + [pxe] + pxe_append_params = nofb nomodeset vga=normal coreos.autologin ipa-insecure=1 + ``` + + - ramdisk镜像中添加ipa配置文件/etc/ironic_python_agent/ironic_python_agent.conf并配置tls的配置如下: + + /etc/ironic_python_agent/ironic_python_agent.conf (需要提前创建/etc/ ironic_python_agent目录) + + ```ini + [DEFAULT] + enable_auto_tls = False + ``` + + 设置权限: + + ```shell + chown -R ipa.ipa /etc/ironic_python_agent/ + ``` + + - ramdisk镜像中修改ipa服务的服务启动文件,添加配置文件选项 + + 编辑/usr/lib/systemd/system/ironic-python-agent.service文件 + + ```ini + [Unit] + Description=Ironic Python Agent + After=network-online.target + [Service] + ExecStartPre=/sbin/modprobe vfat + ExecStart=/usr/local/bin/ironic-python-agent --config-file /etc/ ironic_python_agent/ironic_python_agent.conf + Restart=always + RestartSec=30s + [Install] + WantedBy=multi-user.target + ``` + +#### Trove + +Trove是OpenStack的数据库服务,如果用户使用OpenStack提供的数据库服务则推荐使用该组件。否则,可以不用安装。 + +**Controller节点** + +1. 创建数据库。 + + 数据库服务在数据库中存储信息,创建一个trove用户可以访问的trove数据库,替换TROVE_DBPASS为合适的密码。 + + ```sql + CREATE DATABASE trove CHARACTER SET utf8; + GRANT ALL PRIVILEGES ON trove.* TO 'trove'@'localhost' IDENTIFIED BY 'TROVE_DBPASS'; + GRANT ALL PRIVILEGES ON trove.* TO 'trove'@'%' IDENTIFIED BY 'TROVE_DBPASS'; + ``` + +2. 创建服务凭证以及API端点。 + + 创建服务凭证。 + + ```shell + # 创建trove用户 + openstack user create --domain default --password-prompt trove + # 添加admin角色 + openstack role add --project service --user trove admin + # 创建database服务 + openstack service create --name trove --description "Database service" database + ``` + + 创建API端点。 + + ```shell + openstack endpoint create --region RegionOne database public http://controller:8779/v1.0/%\(tenant_id\)s + openstack endpoint create --region RegionOne database internal http://controller:8779/v1.0/%\(tenant_id\)s + openstack endpoint create --region RegionOne database admin http://controller:8779/v1.0/%\(tenant_id\)s + ``` + +3. 安装Trove。 + + ```shell + dnf install openstack-trove python-troveclient + ``` + +4. 修改配置文件。 + + 编辑/etc/trove/trove.conf。 + + ```ini + [DEFAULT] + bind_host=192.168.0.2 + log_dir = /var/log/trove + network_driver = trove.network.neutron.NeutronDriver + network_label_regex=.* + management_security_groups = + nova_keypair = trove-mgmt + default_datastore = mysql + taskmanager_manager = trove.taskmanager.manager.Manager + trove_api_workers = 5 + transport_url = rabbit://openstack:RABBIT_PASS@controller:5672/ + reboot_time_out = 300 + usage_timeout = 900 + agent_call_high_timeout = 1200 + use_syslog = False + debug = True + + [database] + connection = mysql+pymysql://trove:TROVE_DBPASS@controller/trove + + [keystone_authtoken] + auth_url = http://controller:5000/v3/ + auth_type = password + project_domain_name = Default + project_name = service + user_domain_name = Default + password = trove + username = TROVE_PASS + + [service_credentials] + auth_url = http://controller:5000/v3/ + region_name = RegionOne + project_name = service + project_domain_name = Default + user_domain_name = Default + username = trove + password = TROVE_PASS + + [mariadb] + tcp_ports = 3306,4444,4567,4568 + + [mysql] + tcp_ports = 3306 + + [postgresql] + tcp_ports = 5432 + ``` + + **解释:** + + > `[Default]`分组中`bind_host`配置为Trove控制节点的IP。\ + > `transport_url` 为`RabbitMQ`连接信息,`RABBIT_PASS`替换为RabbitMQ的密码。\ + > `[database]`分组中的`connection` 为前面在mysql中为Trove创建的数据库信息。\ + > Trove的用户信息中`TROVE_PASSWORD`替换为实际trove用户的密码。 + + 编辑/etc/trove/trove-guestagent.conf。 + + ```ini + [DEFAULT] + log_file = trove-guestagent.log + log_dir = /var/log/trove/ + ignore_users = os_admin + control_exchange = trove + transport_url = rabbit://openstack:RABBIT_PASS@controller:5672/ + rpc_backend = rabbit + command_process_timeout = 60 + use_syslog = False + debug = True + + [service_credentials] + auth_url = http://controller:5000/v3/ + region_name = RegionOne + project_name = service + password = TROVE_PASS + project_domain_name = Default + user_domain_name = Default + username = trove + + [mysql] + docker_image = your-registry/your-repo/mysql + backup_docker_image = your-registry/your-repo/db-backup-mysql:1.1.0 + ``` + + **解释:** + + > `guestagent`是trove中一个独立组件,需要预先内置到Trove通过Nova创建的虚拟机镜像中,在创建好数据库实例后,会起guestagent进程,负责通过消息队列(RabbitMQ)向Trove上报心跳,因此需要配置RabbitMQ的用户和密码信息。\ + > `transport_url` 为`RabbitMQ`连接信息,`RABBIT_PASS`替换为RabbitMQ的密码。\ + > Trove的用户信息中`TROVE_PASSWORD`替换为实际trove用户的密码。\ + > 从Victoria版开始,Trove使用一个统一的镜像来跑不同类型的数据库,数据库服务运行在Guest虚拟机的Docker容器中。 + +5. 数据库同步。 + + ```shell + su -s /bin/sh -c "trove-manage db_sync" trove + ``` + +6. 完成安装。 + + ```shell + # 配置服务自启 + systemctl enable openstack-trove-api.service openstack-trove-taskmanager.service \ + openstack-trove-conductor.service + + # 启动服务 + systemctl start openstack-trove-api.service openstack-trove-taskmanager.service \ + openstack-trove-conductor.service + ``` + +#### Swift + +Swift 提供了弹性可伸缩、高可用的分布式对象存储服务,适合存储大规模非结构化数据。 + +**Controller节点** + +1. 创建服务凭证以及API端点。 + + 创建服务凭证。 + + ```shell + # 创建swift用户 + openstack user create --domain default --password-prompt swift + # 添加admin角色 + openstack role add --project service --user swift admin + # 创建对象存储服务 + openstack service create --name swift --description "OpenStack Object Storage" object-store + ``` + + 创建API端点。 + + ```shell + openstack endpoint create --region RegionOne object-store public http://controller:8080/v1/AUTH_%\(project_id\)s + openstack endpoint create --region RegionOne object-store internal http://controller:8080/v1/AUTH_%\(project_id\)s + openstack endpoint create --region RegionOne object-store admin http://controller:8080/v1 + ``` + +2. 安装Swift。 + + ```shell + dnf install openstack-swift-proxy python3-swiftclient python3-keystoneclient \ + python3-keystonemiddleware memcached + ``` + +3. 配置proxy-server。 + + Swift RPM包里已经包含了一个基本可用的proxy-server.conf,只需要手动修改其中的ip和SWIFT_PASS即可。 + + ```ini + vim /etc/swift/proxy-server.conf + + [filter:authtoken] + paste.filter_factory = keystonemiddleware.auth_token:filter_factory + www_authenticate_uri = http://controller:5000 + auth_url = http://controller:5000 + memcached_servers = controller:11211 + auth_type = password + project_domain_id = default + user_domain_id = default + project_name = service + username = swift + password = SWIFT_PASS + delay_auth_decision = True + service_token_roles_required = True + ``` + +**Storage节点** + +1. 安装支持的程序包。 + + ```shell + dnf install openstack-swift-account openstack-swift-container openstack-swift-object + dnf install xfsprogs rsync + ``` + +2. 将设备/dev/sdb和/dev/sdc格式化为XFS。 + + ```shell + mkfs.xfs /dev/sdb + mkfs.xfs /dev/sdc + ``` + +3. 创建挂载点目录结构。 + + ```shell + mkdir -p /srv/node/sdb + mkdir -p /srv/node/sdc + ``` + +4. 找到新分区的UUID。 + + ```shell + blkid + ``` + +5. 编辑/etc/fstab文件并将以下内容添加到其中。 + + ```shell + UUID="" /srv/node/sdb xfs noatime 0 2 + UUID="" /srv/node/sdc xfs noatime 0 2 + ``` + +6. 挂载设备。 + + ```shell + mount /srv/node/sdb + mount /srv/node/sdc + ``` + + ***注意*** + + **如果用户不需要容灾功能,以上步骤只需要创建一个设备即可,同时可以跳过下面的rsync配置。** + +7. (可选)创建或编辑/etc/rsyncd.conf文件以包含以下内容: + + ```ini + [DEFAULT] + uid = swift + gid = swift + log file = /var/log/rsyncd.log + pid file = /var/run/rsyncd.pid + address = MANAGEMENT_INTERFACE_IP_ADDRESS + + [account] + max connections = 2 + path = /srv/node/ + read only = False + lock file = /var/lock/account.lock + + [container] + max connections = 2 + path = /srv/node/ + read only = False + lock file = /var/lock/container.lock + + [object] + max connections = 2 + path = /srv/node/ + read only = False + lock file = /var/lock/object.lock + ``` + + **替换MANAGEMENT_INTERFACE_IP_ADDRESS为存储节点上管理网络的IP地址** + + 启动rsyncd服务并配置它在系统启动时启动: + + ```shell + systemctl enable rsyncd.service + systemctl start rsyncd.service + ``` + +8. 配置存储节点。 + + 编辑/etc/swift目录的account-server.conf、container-server.conf和object-server.conf文件,替换bind_ip为存储节点上管理网络的IP地址。 + + ```ini + [DEFAULT] + bind_ip = 192.168.0.4 + ``` + + 确保挂载点目录结构的正确所有权。 + + ```shell + chown -R swift:swift /srv/node + ``` + + 创建recon目录并确保其拥有正确的所有权。 + + ```shell + mkdir -p /var/cache/swift + chown -R root:swift /var/cache/swift + chmod -R 775 /var/cache/swift + ``` + +**Controller节点创建并分发环** + +1. 创建账号环。 + + 切换到`/etc/swift`目录。 + + ```shell + cd /etc/swift + ``` + + 创建基础`account.builder`文件。 + + ```shell + swift-ring-builder account.builder create 10 1 1 + ``` + + 将每个存储节点添加到环中。 + + ```shell + swift-ring-builder account.builder add --region 1 --zone 1 \ + --ip STORAGE_NODE_MANAGEMENT_INTERFACE_IP_ADDRESS \ + --port 6202 --device DEVICE_NAME \ + --weight 100 + ``` + + > 替换STORAGE_NODE_MANAGEMENT_INTERFACE_IP_ADDRESS为存储节点上管理网络的IP地址。\ + > 替换DEVICE_NAME为同一存储节点上的存储设备名称。 + + ***注意*** + + **对每个存储节点上的每个存储设备重复此命令** + + 验证账号环内容。 + + ```shell + swift-ring-builder account.builder + ``` + + 重新平衡账号环。 + + ```shell + swift-ring-builder account.builder rebalance + ``` + +2. 创建容器环。 + + 切换到`/etc/swift`目录。 + + 创建基础`container.builder`文件。 + + ```shell + swift-ring-builder container.builder create 10 1 1 + ``` + + 将每个存储节点添加到环中。 + + ```shell + swift-ring-builder container.builder add --region 1 --zone 1 \ + --ip STORAGE_NODE_MANAGEMENT_INTERFACE_IP_ADDRESS + --port 6201 --device DEVICE_NAME \ + --weight 100 + ``` + + > 替换STORAGE_NODE_MANAGEMENT_INTERFACE_IP_ADDRESS为存储节点上管理网络的IP地址。\ + > 替换DEVICE_NAME为同一存储节点上的存储设备名称。 + + ***注意*** + + **对每个存储节点上的每个存储设备重复此命令** + + 验证容器环内容。 + + ```shell + swift-ring-builder container.builder + ``` + + 重新平衡容器环。 + + ```shell + swift-ring-builder container.builder rebalance + ``` + +3. 创建对象环。 + + 切换到`/etc/swift`目录。 + + 创建基础`object.builder`文件。 + + ```shell + swift-ring-builder object.builder create 10 1 1 + ``` + + 将每个存储节点添加到环中。 + + ```shell + swift-ring-builder object.builder add --region 1 --zone 1 \ + --ip STORAGE_NODE_MANAGEMENT_INTERFACE_IP_ADDRESS \ + --port 6200 --device DEVICE_NAME \ + --weight 100 + ``` + + > 替换STORAGE_NODE_MANAGEMENT_INTERFACE_IP_ADDRESS为存储节点上管理网络的IP地址。\ + > 替换DEVICE_NAME为同一存储节点上的存储设备名称。 + + ***注意*** + + **对每个存储节点上的每个存储设备重复此命令** + + 验证对象环内容。 + + ```shell + swift-ring-builder object.builder + ``` + + 重新平衡对象环。 + + ```shell + swift-ring-builder object.builder rebalance + ``` + +4. 分发环配置文件。 + + 将`account.ring.gz`,`container.ring.gz`以及 `object.ring.gz`文件复制到每个存储节点和运行代理服务的任何其他节点上的`/etc/swift`目录。 + +5. 编辑配置文件/etc/swift/swift.conf。 + + ```ini + [swift-hash] + swift_hash_path_suffix = test-hash + swift_hash_path_prefix = test-hash + + [storage-policy:0] + name = Policy-0 + default = yes + ``` + + **用唯一值替换 test-hash** + + 将swift.conf文件复制到/etc/swift每个存储节点和运行代理服务的任何其他节点上的目录。 + + 在所有节点上,确保配置目录的正确所有权。 + + ```shell + chown -R root:swift /etc/swift + ``` + +6. 完成安装 + + 在控制节点和运行代理服务的任何其他节点上,启动对象存储代理服务及其依赖项,并将它们配置为在系统启动时启动。 + + ```shell + systemctl enable openstack-swift-proxy.service memcached.service + systemctl start openstack-swift-proxy.service memcached.service + ``` + + 在存储节点上,启动对象存储服务并将它们配置为在系统启动时启动。 + + ```shell + systemctl enable openstack-swift-account.service \ + openstack-swift-account-auditor.service \ + openstack-swift-account-reaper.service \ + openstack-swift-account-replicator.service \ + openstack-swift-container.service \ + openstack-swift-container-auditor.service \ + openstack-swift-container-replicator.service \ + openstack-swift-container-updater.service \ + openstack-swift-object.service \ + openstack-swift-object-auditor.service \ + openstack-swift-object-replicator.service \ + openstack-swift-object-updater.service + + systemctl start openstack-swift-account.service \ + openstack-swift-account-auditor.service \ + openstack-swift-account-reaper.service \ + openstack-swift-account-replicator.service \ + openstack-swift-container.service \ + openstack-swift-container-auditor.service \ + openstack-swift-container-replicator.service \ + openstack-swift-container-updater.service \ + openstack-swift-object.service \ + openstack-swift-object-auditor.service \ + openstack-swift-object-replicator.service \ + openstack-swift-object-updater.service + ``` + +#### Cyborg + +Cyborg为OpenStack提供加速器设备的支持,包括 GPU, FPGA, ASIC, NP, SoCs, NVMe/NOF SSDs, ODP, DPDK/SPDK等等。 + +**Controller节点** + +1. 初始化对应数据库 + + ```sql + mysql -u root -p + + MariaDB [(none)]> CREATE DATABASE cyborg; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON cyborg.* TO 'cyborg'@'localhost' IDENTIFIED BY 'CYBORG_DBPASS'; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON cyborg.* TO 'cyborg'@'%' IDENTIFIED BY 'CYBORG_DBPASS'; + MariaDB [(none)]> exit; + ``` + +2. 创建用户和服务,并记住创建cybory用户时输入的密码,用于配置CYBORG_PASS + + ```shell + source ~/.admin-openrc + openstack user create --domain default --password-prompt cyborg + openstack role add --project service --user cyborg admin + openstack service create --name cyborg --description "Acceleration Service" accelerator + ``` + +3. 使用uwsgi部署Cyborg api服务 + + ```shell + openstack endpoint create --region RegionOne accelerator public http://controller/accelerator/v2 + openstack endpoint create --region RegionOne accelerator internal http://controller/accelerator/v2 + openstack endpoint create --region RegionOne accelerator admin http://controller/accelerator/v2 + ``` + +4. 安装Cyborg + + ```shell + dnf install openstack-cyborg + ``` + +5. 配置Cyborg + + 修改`/etc/cyborg/cyborg.conf` + + ```ini + [DEFAULT] + transport_url = rabbit://openstack:RABBIT_PASS@controller:5672/ + use_syslog = False + state_path = /var/lib/cyborg + debug = True + + [api] + host_ip = 0.0.0.0 + + [database] + connection = mysql+pymysql://cyborg:CYBORG_DBPASS@controller/cyborg + + [service_catalog] + cafile = /opt/stack/data/ca-bundle.pem + project_domain_id = default + user_domain_id = default + project_name = service + password = CYBORG_PASS + username = cyborg + auth_url = http://controller:5000/v3/ + auth_type = password + + [placement] + project_domain_name = Default + project_name = service + user_domain_name = Default + password = password + username = PLACEMENT_PASS + auth_url = http://controller:5000/v3/ + auth_type = password + auth_section = keystone_authtoken + + [nova] + project_domain_name = Default + project_name = service + user_domain_name = Default + password = NOVA_PASS + username = nova + auth_url = http://controller:5000/v3/ + auth_type = password + auth_section = keystone_authtoken + + [keystone_authtoken] + memcached_servers = localhost:11211 + signing_dir = /var/cache/cyborg/api + cafile = /opt/stack/data/ca-bundle.pem + project_domain_name = Default + project_name = service + user_domain_name = Default + password = CYBORG_PASS + username = cyborg + auth_url = http://controller:5000/v3/ + auth_type = password + ``` + +6. 同步数据库表格 + + ```shell + cyborg-dbsync --config-file /etc/cyborg/cyborg.conf upgrade + ``` + +7. 启动Cyborg服务 + + ```shell + systemctl enable openstack-cyborg-api openstack-cyborg-conductor openstack-cyborg-agent + systemctl start openstack-cyborg-api openstack-cyborg-conductor openstack-cyborg-agent + ``` + +#### Aodh + +Aodh可以根据由Ceilometer或者Gnocchi收集的监控数据创建告警,并设置触发规则。 + +**Controller节点** + +1. 创建数据库。 + + ```sql + CREATE DATABASE aodh; + GRANT ALL PRIVILEGES ON aodh.* TO 'aodh'@'localhost' IDENTIFIED BY 'AODH_DBPASS'; + GRANT ALL PRIVILEGES ON aodh.* TO 'aodh'@'%' IDENTIFIED BY 'AODH_DBPASS'; + ``` + +2. 创建服务凭证以及API端点。 + + 创建服务凭证。 + + ```shell + openstack user create --domain default --password-prompt aodh + openstack role add --project service --user aodh admin + openstack service create --name aodh --description "Telemetry" alarming + ``` + + 创建API端点。 + + ```shell + openstack endpoint create --region RegionOne alarming public http://controller:8042 + openstack endpoint create --region RegionOne alarming internal http://controller:8042 + openstack endpoint create --region RegionOne alarming admin http://controller:8042 + ``` + +3. 安装Aodh。 + + ```shell + dnf install openstack-aodh-api openstack-aodh-evaluator \ + openstack-aodh-notifier openstack-aodh-listener \ + openstack-aodh-expirer python3-aodhclient + ``` + +4. 修改配置文件。 + + ```ini + vim /etc/aodh/aodh.conf + + [database] + connection = mysql+pymysql://aodh:AODH_DBPASS@controller/aodh + + [DEFAULT] + transport_url = rabbit://openstack:RABBIT_PASS@controller + auth_strategy = keystone + + [keystone_authtoken] + www_authenticate_uri = http://controller:5000 + auth_url = http://controller:5000 + memcached_servers = controller:11211 + auth_type = password + project_domain_id = default + user_domain_id = default + project_name = service + username = aodh + password = AODH_PASS + + [service_credentials] + auth_type = password + auth_url = http://controller:5000/v3 + project_domain_id = default + user_domain_id = default + project_name = service + username = aodh + password = AODH_PASS + interface = internalURL + region_name = RegionOne + ``` + +5. 同步数据库。 + + ```shell + aodh-dbsync + ``` + +6. 完成安装。 + + ```shell + # 配置服务自启 + systemctl enable openstack-aodh-api.service openstack-aodh-evaluator.service \ + openstack-aodh-notifier.service openstack-aodh-listener.service + + # 启动服务 + systemctl start openstack-aodh-api.service openstack-aodh-evaluator.service \ + openstack-aodh-notifier.service openstack-aodh-listener.service + ``` + +#### Gnocchi + +Gnocchi是一个开源的时间序列数据库,可以对接Ceilometer。 + +**Controller节点** + +1. 创建数据库。 + + ```sql + CREATE DATABASE gnocchi; + GRANT ALL PRIVILEGES ON gnocchi.* TO 'gnocchi'@'localhost' IDENTIFIED BY 'GNOCCHI_DBPASS'; + GRANT ALL PRIVILEGES ON gnocchi.* TO 'gnocchi'@'%' IDENTIFIED BY 'GNOCCHI_DBPASS'; + ``` + +2. 创建服务凭证以及API端点。 + + 创建服务凭证。 + + ```shell + openstack user create --domain default --password-prompt gnocchi + openstack role add --project service --user gnocchi admin + openstack service create --name gnocchi --description "Metric Service" metric + ``` + + 创建API端点。 + + ```shell + openstack endpoint create --region RegionOne metric public http://controller:8041 + openstack endpoint create --region RegionOne metric internal http://controller:8041 + openstack endpoint create --region RegionOne metric admin http://controller:8041 + ``` + +3. 安装Gnocchi。 + + ```shell + dnf install openstack-gnocchi-api openstack-gnocchi-metricd python3-gnocchiclient + ``` + +4. 修改配置文件。 + + ```ini + vim /etc/gnocchi/gnocchi.conf + [api] + auth_mode = keystone + port = 8041 + uwsgi_mode = http-socket + + [keystone_authtoken] + auth_type = password + auth_url = http://controller:5000/v3 + project_domain_name = Default + user_domain_name = Default + project_name = service + username = gnocchi + password = GNOCCHI_PASS + interface = internalURL + region_name = RegionOne + + [indexer] + url = mysql+pymysql://gnocchi:GNOCCHI_DBPASS@controller/gnocchi + + [storage] + # coordination_url is not required but specifying one will improve + # performance with better workload division across workers. + # coordination_url = redis://controller:6379 + file_basepath = /var/lib/gnocchi + driver = file + ``` + +5. 同步数据库。 + + ```shell + gnocchi-upgrade + ``` + +6. 完成安装。 + + ```shell + # 配置服务自启 + systemctl enable openstack-gnocchi-api.service openstack-gnocchi-metricd.service + + # 启动服务 + systemctl start openstack-gnocchi-api.service openstack-gnocchi-metricd.service + ``` + +#### Ceilometer + +Ceilometer是OpenStack中负责数据收集的服务。 + +**Controller节点** + +1. 创建服务凭证。 + + ```shell + openstack user create --domain default --password-prompt ceilometer + openstack role add --project service --user ceilometer admin + openstack service create --name ceilometer --description "Telemetry" metering + ``` + +2. 安装Ceilometer软件包。 + + ```shell + dnf install openstack-ceilometer-notification openstack-ceilometer-central + ``` + +3. 编辑配置文件/etc/ceilometer/pipeline.yaml。 + + ```yaml + publishers: + # set address of Gnocchi + # + filter out Gnocchi-related activity meters (Swift driver) + # + set default archive policy + - gnocchi://?filter_project=service&archive_policy=low + ``` + +4. 编辑配置文件/etc/ceilometer/ceilometer.conf。 + + ```ini + [DEFAULT] + transport_url = rabbit://openstack:RABBIT_PASS@controller + + [service_credentials] + auth_type = password + auth_url = http://controller:5000/v3 + project_domain_id = default + user_domain_id = default + project_name = service + username = ceilometer + password = CEILOMETER_PASS + interface = internalURL + region_name = RegionOne + ``` + +5. 数据库同步。 + + ```shell + ceilometer-upgrade + ``` + +6. 完成控制节点Ceilometer安装。 + + ```shell + # 配置服务自启 + systemctl enable openstack-ceilometer-notification.service openstack-ceilometer-central.service + # 启动服务 + systemctl start openstack-ceilometer-notification.service openstack-ceilometer-central.service + ``` + +**Compute节点** + +1. 安装Ceilometer软件包。 + + ```shell + dnf install openstack-ceilometer-compute + dnf install openstack-ceilometer-ipmi # 可选 + ``` + +2. 编辑配置文件/etc/ceilometer/ceilometer.conf。 + + ```ini + [DEFAULT] + transport_url = rabbit://openstack:RABBIT_PASS@controller + + [service_credentials] + auth_url = http://controller:5000 + project_domain_id = default + user_domain_id = default + auth_type = password + username = ceilometer + project_name = service + password = CEILOMETER_PASS + interface = internalURL + region_name = RegionOne + ``` + +3. 编辑配置文件/etc/nova/nova.conf。 + + ```ini + [DEFAULT] + instance_usage_audit = True + instance_usage_audit_period = hour + + [notifications] + notify_on_state_change = vm_and_task_state + + [oslo_messaging_notifications] + driver = messagingv2 + ``` + +4. 完成安装。 + + ```shell + systemctl enable openstack-ceilometer-compute.service + systemctl start openstack-ceilometer-compute.service + systemctl enable openstack-ceilometer-ipmi.service # 可选 + systemctl start openstack-ceilometer-ipmi.service # 可选 + + # 重启nova-compute服务 + systemctl restart openstack-nova-compute.service + ``` + +#### Heat + +Heat是 OpenStack 自动编排服务,基于描述性的模板来编排复合云应用,也称为`Orchestration Service`。Heat 的各服务一般安装在`Controller`节点上。 + +**Controller节点** + +1. 创建**heat**数据库,并授予**heat**数据库正确的访问权限,替换**HEAT_DBPASS**为合适的密码 + + ```sql + mysql -u root -p + + MariaDB [(none)]> CREATE DATABASE heat; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON heat.* TO 'heat'@'localhost' IDENTIFIED BY 'HEAT_DBPASS'; + MariaDB [(none)]> GRANT ALL PRIVILEGES ON heat.* TO 'heat'@'%' IDENTIFIED BY 'HEAT_DBPASS'; + MariaDB [(none)]> exit; + ``` + +2. 创建服务凭证,创建**heat**用户,并为其增加**admin**角色 + + ```shell + source ~/.admin-openrc + + openstack user create --domain default --password-prompt heat + openstack role add --project service --user heat admin + ``` + +3. 创建**heat**和**heat-cfn**服务及其对应的API端点 + + ```shell + openstack service create --name heat --description "Orchestration" orchestration + openstack service create --name heat-cfn --description "Orchestration" cloudformation + openstack endpoint create --region RegionOne orchestration public http://controller:8004/v1/%\(tenant_id\)s + openstack endpoint create --region RegionOne orchestration internal http://controller:8004/v1/%\(tenant_id\)s + openstack endpoint create --region RegionOne orchestration admin http://controller:8004/v1/%\(tenant_id\)s + openstack endpoint create --region RegionOne cloudformation public http://controller:8000/v1 + openstack endpoint create --region RegionOne cloudformation internal http://controller:8000/v1 + openstack endpoint create --region RegionOne cloudformation admin http://controller:8000/v1 + ``` + +4. 创建stack管理的额外信息 + + 创建 **heat** domain + + ```shell + openstack domain create --description "Stack projects and users" heat + ``` + + 在 **heat** domain下创建 **heat_domain_admin** 用户,并记下输入的密码,用于配置下面的`HEAT_DOMAIN_PASS` + + ```shell + openstack user create --domain heat --password-prompt heat_domain_admin + ``` + + 为 **heat_domain_admin** 用户增加 **admin** 角色 + + ```shell + openstack role add --domain heat --user-domain heat --user heat_domain_admin admin + ``` + + 创建 **heat_stack_owner** 角色 + + ```shell + openstack role create heat_stack_owner + ``` + + 创建 **heat_stack_user** 角色 + + ```shell + openstack role create heat_stack_user + ``` + +5. 安装软件包 + + ```shell + dnf install openstack-heat-api openstack-heat-api-cfn openstack-heat-engine + ``` + +6. 修改配置文件`/etc/heat/heat.conf` + + ```ini + [DEFAULT] + transport_url = rabbit://openstack:RABBIT_PASS@controller + heat_metadata_server_url = http://controller:8000 + heat_waitcondition_server_url = http://controller:8000/v1/waitcondition + stack_domain_admin = heat_domain_admin + stack_domain_admin_password = HEAT_DOMAIN_PASS + stack_user_domain_name = heat + + [database] + connection = mysql+pymysql://heat:HEAT_DBPASS@controller/heat + + [keystone_authtoken] + www_authenticate_uri = http://controller:5000 + auth_url = http://controller:5000 + memcached_servers = controller:11211 + auth_type = password + project_domain_name = default + user_domain_name = default + project_name = service + username = heat + password = HEAT_PASS + + [trustee] + auth_type = password + auth_url = http://controller:5000 + username = heat + password = HEAT_PASS + user_domain_name = default + + [clients_keystone] + auth_uri = http://controller:5000 + ``` + +7. 初始化**heat**数据库表 + + ```shell + su -s /bin/sh -c "heat-manage db_sync" heat + ``` + +8. 启动服务 + + ```shell + systemctl enable openstack-heat-api.service openstack-heat-api-cfn.service openstack-heat-engine.service + systemctl start openstack-heat-api.service openstack-heat-api-cfn.service openstack-heat-engine.service + ``` + +#### Tempest + +Tempest是OpenStack的集成测试服务,如果用户需要全面自动化测试已安装的OpenStack环境的功能,则推荐使用该组件。否则,可以不用安装。 + +**Controller节点**: + +1. 安装Tempest + + ```shell + dnf install openstack-tempest + ``` + +2. 初始化目录 + + ```shell + tempest init mytest + ``` + +3. 修改配置文件。 + + ```shell + cd mytest + vi etc/tempest.conf + ``` + + tempest.conf中需要配置当前OpenStack环境的信息,具体内容可以参考[官方示例](https://docs.openstack.org/tempest/latest/sampleconf.html) + +4. 执行测试 + + ```shell + tempest run + ``` + +5. 安装tempest扩展(可选) + OpenStack各个服务本身也提供了一些tempest测试包,用户可以安装这些包来丰富tempest的测试内容。在Antelope中,我们提供了Cinder、Glance、Keystone、Ironic、Trove的扩展测试,用户可以执行如下命令进行安装使用: + + ```shell + dnf install python3-cinder-tempest-plugin python3-glance-tempest-plugin python3-ironic-tempest-plugin python3-keystone-tempest-plugin python3-trove-tempest-plugin + ``` + +## 基于OpenStack SIG开发工具oos部署 + +`oos`(openEuler OpenStack SIG)是OpenStack SIG提供的命令行工具。其中`oos env`系列命令提供了一键部署OpenStack (`all in one`或三节点`cluster`)的ansible脚本,用户可以使用该脚本快速部署一套基于 openEuler RPM 的 OpenStack 环境。`oos`工具支持对接云provider(目前仅支持华为云provider)和主机纳管两种方式来部署 OpenStack 环境,下面以对接华为云部署一套`all in one`的OpenStack环境为例说明`oos`工具的使用方法。 + +1. 安装`oos`工具 + + ```shell + yum install openstack-sig-tool + ``` + +2. 配置对接华为云provider的信息 + + 打开`/usr/local/etc/oos/oos.conf`文件,修改配置为您拥有的华为云资源信息,AK/SK是用户的华为云登录密钥,其他配置保持默认即可(默认使用新加坡region),需要提前在云上创建对应的资源,包括: + + - 一个安全组,名字默认是`oos` + - 一个openEuler镜像,名称格式是openEuler-%(release)s-%(arch)s,例如`openEuler-25.03-arm64` + - 一个VPC,名称是`oos_vpc` + - 该VPC下面两个子网,名称是`oos_subnet1`、`oos_subnet2` + + ```ini + [huaweicloud] + ak = + sk = + region = ap-southeast-3 + root_volume_size = 100 + data_volume_size = 100 + security_group_name = oos + image_format = openEuler-%%(release)s-%%(arch)s + vpc_name = oos_vpc + subnet1_name = oos_subnet1 + subnet2_name = oos_subnet2 + ``` + +3. 配置 OpenStack 环境信息 + + 打开`/usr/local/etc/oos/oos.conf`文件,根据当前机器环境和需求修改配置。内容如下: + + ```shell + [environment] + mysql_root_password = root + mysql_project_password = root + rabbitmq_password = root + project_identity_password = root + enabled_service = keystone,neutron,cinder,placement,nova,glance,horizon,aodh,ceilometer,cyborg,gnocchi,kolla,heat,swift,trove,tempest + neutron_provider_interface_name = br-ex + default_ext_subnet_range = 10.100.100.0/24 + default_ext_subnet_gateway = 10.100.100.1 + neutron_dataplane_interface_name = eth1 + cinder_block_device = vdb + swift_storage_devices = vdc + swift_hash_path_suffix = ash + swift_hash_path_prefix = has + glance_api_workers = 2 + cinder_api_workers = 2 + nova_api_workers = 2 + nova_metadata_api_workers = 2 + nova_conductor_workers = 2 + nova_scheduler_workers = 2 + neutron_api_workers = 2 + horizon_allowed_host = * + kolla_openeuler_plugin = false + ``` + + **关键配置** + + | 配置项 | 解释 | + |---|---| + | enabled_service | 安装服务列表,根据用户需求自行删减 | + | neutron_provider_interface_name | neutron L3网桥名称 | + | default_ext_subnet_range | neutron私网IP段 | + | default_ext_subnet_gateway | neutron私网gateway | + | neutron_dataplane_interface_name | neutron使用的网卡,推荐使用一张新的网卡,以免和现有网卡冲突,防止all in one主机断连的情况 | + | cinder_block_device | cinder使用的卷设备名 | + | swift_storage_devices | swift使用的卷设备名 | + | kolla_openeuler_plugin | 是否启用kolla plugin。设置为True,kolla将支持部署openEuler容器(只在openEuler LTS上支持) | + +4. 华为云上面创建一台|openEuler 25.03的x86_64虚拟机,用于部署`all in one` 的 OpenStack + + ```shell + # sshpass在`oos env create`过程中被使用,用于配置对目标虚拟机的免密访问 + dnf install sshpass + oos env create -r 25.03 -f small -a x86 -n test-oos all_in_one + ``` + + 具体的参数可以使用`oos env create --help`命令查看 + +5. 部署OpenStack `all in one` 环境 + + ```shell + oos env setup test-oos -r antelope + ``` + + 具体的参数可以使用`oos env setup --help`命令查看 + +6. 初始化tempest环境 + + 如果用户想使用该环境运行tempest测试的话,可以执行命令`oos env init`,会自动把tempest需要的OpenStack资源自动创建好 + + ```shell + oos env init test-oos + ``` + +7. 执行tempest测试 + + 用户可以使用oos自动执行: + + ```shell + oos env test test-oos + ``` + + 也可以手动登录目标节点,进入根目录下的`mytest`目录,手动执行`tempest run` + +如果是以主机纳管的方式部署 OpenStack 环境,总体逻辑与上文对接华为云时一致,1、3、5、6步操作不变,跳过第2步对华为云provider信息的配置,在第4步改为纳管主机操作。 + +被纳管的虚机需要保证: + +- 至少有一张给oos使用的网卡,名称与配置保持一致,相关配置`neutron_dataplane_interface_name` +- 至少有一块给oos使用的硬盘,名称与配置保持一致,相关配置`cinder_block_device` +- 如果要部署swift服务,则需要新增一块硬盘,名称与配置保持一致,相关配置`swift_storage_devices` + +```shell +# sshpass在`oos env create`过程中被使用,用于配置对目标主机的免密访问 +dnf install sshpass +oos env manage -r 25.03 -i TARGET_MACHINE_IP -p TARGET_MACHINE_PASSWD -n test-oos +``` + +替换`TARGET_MACHINE_IP`为目标机ip、`TARGET_MACHINE_PASSWD`为目标机密码。具体的参数可以使用`oos env manage --help`命令查看。 diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/install/devstack.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/install/devstack.md new file mode 100644 index 0000000000000000000000000000000000000000..187b8716ad433d62391722b328b186a7d83410fc --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/install/devstack.md @@ -0,0 +1,176 @@ +# 使用Devstack安装OpenStack + +[TOC] + +目前OpenStack原生Devstack项目已经支持在openEuler上安装OpenStack,其中openEuler 20.03 LTS SP2已经过验证,并且有上游官方CI保证质量。其他版本的openEuler需要用户自行测试(2022-04-25 openEuler master分支已验证)。 + +## 安装步骤 + +准备一个openEuler环境, 20.03 LTS SP2[虚拟机镜像地址](https://repo.openeuler.org/openEuler-20.03-LTS-SP2/virtual_machine_img/), master[虚拟机镜像地址](http://121.36.84.172/dailybuild/openEuler-Mainline/) + +1. 配置yum源 + + **openEuler 20.03 LTS SP2**: + + openEuler官方源中缺少了一些OpenStack需要的RPM包,因此需要先配上OpenStack SIG在oepkg中准备好的RPM源 + + ```shell + vi /etc/yum.repos.d/openeuler.repo + + [openstack] + name=openstack + baseurl=https://repo.oepkgs.net/openEuler/rpm/openEuler-20.03-LTS-SP2/budding-openeuler/openstack-master-ci/aarch64/ + enabled=1 + gpgcheck=0 + ``` + + **openEuler master**: + + 使用master的RPM源: + + ```shell + vi /etc/yum.repos.d/openeuler.repo + + [mainline] + name=mainline + baseurl=http://119.3.219.20:82/openEuler:/Mainline/standard_aarch64/ + gpgcheck=false + + [epol] + name=epol + baseurl=http://119.3.219.20:82/openEuler:/Epol/standard_aarch64/ + gpgcheck=false + ``` + +2. 前期准备 + + **openEuler 20.03 LTS SP2**: + + 在一些版本的openEuler官方镜像的默认源中,EPOL-update的URL可能配置不正确,需要修改 + + ```shell + vi /etc/yum.repos.d/openEuler.repo + + # 把[EPOL-UPDATE]URL改成 + baseurl=http://repo.openeuler.org/openEuler-20.03-LTS-SP2/EPOL/update/main/$basearch/ + ``` + + **openEuler master**: + + ```shell + yum remove python3-pip # 系统的pip与devstack pip冲突,需要先删除 + # master的虚机环境缺少了一些依赖,devstack不会自动安装,需要手动安装 + yum install iptables tar wget python3-devel httpd-devel iscsi-initiator-utils libvirt python3-libvirt qemu memcached + ``` + +3. 下载devstack + + ```shell + yum update + yum install git + cd /opt/ + git clone https://opendev.org/openstack/devstack.git + ``` + +4. 初始化devstack环境配置 + + ```shell + # 创建stack用户 + /opt/devstack/tools/create-stack-user.sh + # 修改目录权限 + chown -R stack:stack /opt/devstack + chmod -R 755 /opt/devstack + chmod -R 755 /opt/stack + # 切换到要部署的openstack版本分支,以yoga为例,不切换的话,默认安装的是master版本的openstack + git checkout stable/yoga + ``` + +5. 初始化devstack配置文件 + + ```shell + 切换到stack用户 + su stack + 此时,请确认stack用户的PATH环境变量是否包含了`/usr/sbin`,如果没有,则需要执行 + PATH=$PATH:/usr/sbin + 新增配置文件 + vi /opt/devstack/local.conf + + [[local|localrc]] + DATABASE_PASSWORD=root + RABBIT_PASSWORD=root + SERVICE_PASSWORD=root + ADMIN_PASSWORD=root + OVN_BUILD_FROM_SOURCE=True + ``` + + openEuler没有提供OVN的RPM软件包,因此需要配置`OVN_BUILD_FROM_SOURCE=True`, 从源码编译OVN + + 另外如果使用的是arm64虚拟机环境,则需要配置libvirt嵌套虚拟化,在`local.conf`中追加如下配置: + + ```shell + [[post-config|$NOVA_CONF]] + [libvirt] + cpu_mode=custom + cpu_model=cortex-a72 + ``` + + 如果安装Ironic,需要提前安装依赖: + + ```bash + sudo dnf install syslinux-nonlinux + ``` + + **openEuler master的特殊配置**: 由于devstack还没有适配最新的openEuler,我们需要手动修复一些问题: + + 1. 修改devstack源码 + + ```shell + vi /opt/devstack/tools/fixup_stuff.sh + 把fixup_openeuler方法中的所有echo语句删掉 + (echo '[openstack-ci]' + echo 'name=openstack' + echo 'baseurl=https://repo.oepkgs.net/openEuler/rpm/openEuler-20.03-LTS-SP2/budding-openeuler/openstack-master-ci/'$arch'/' + echo 'enabled=1' + echo 'gpgcheck=0') | sudo tee -a /etc/yum.repos.d/openstack-master.repo > /dev/null + ``` + + 2. 修改requirements源码 + + Yoga版keystone的依赖`setproctitle`的devstack默认版本不支持python3.10,需要升级,手动下载requirements项目并修改 + + ```shell + cd /opt/stack + git clone https://opendev.org/openstack/requirements --branch stable/yoga + vi /opt/stack/requirements/upper-constraints.txt + setproctitle===1.2.3 + ``` + + 3. OpenStack horizon有BUG,无法正常安装。这里我们暂时不安装horizon,修改`local.conf`,新增一行: + + ```shell + [[local|localrc]] + disable_service horizon + ``` + + 如果确实有对horizon的需求,则需要解决以下问题: + + ```shell + # 1. horizon依赖的pyScss默认为1.3.7版本,不支持python3.10 + # 解决方法:需要提前clone`requirements`项目并修改代码 + vi /opt/stack/requirements/upper-constraints.txt + pyScss===1.4.0 + + # 2. horizon依赖httpd的mod_wsgi插件,但目前openEuler的mod_wsgi构建异常(2022-04-25)(解决后yum install mod_wsgi即可),无法从yum安装 + # 解决方法:手动源码build mod_wsgi并配置,该过程较复杂,这里略过 + ``` + + 4. dstat服务依赖的`pcp-system-tools`构建异常(2022-04-25)(解决后yum install pcp-system-tools即可),无法从yum安装,暂时先不安装dstat + + ```shell + [[local|localrc]] + disable_service dstat + ``` + +6. 部署OpenStack + + 进入devstack目录,执行`./stack.sh`,等待OpenStack完成安装部署。 diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/security/security-guide.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/security/security-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..6c3a9a838c1fe05a32ccc2cb6afd97760db23e46 --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/security/security-guide.md @@ -0,0 +1,9425 @@ +# OpenStack安全指南 + +本文翻译自[上游安全指南](https://gitee.com/link?target=https%3A%2F%2Fdocs.openstack.org%2Fsecurity-guide%2F) + +[TOC] + +## 摘要 + +本书提供了有关保护OpenStack云的最佳实践和概念信息。 + +本指南最后一次更新是在Train发布期间,记录了OpenStack Train、Stein和Rocky版本。它可能不适用于EOL版本(例如Newton)。我们建议您在计划为您的OpenStack云实施安全措施时,自行阅读本文。本指南仅供参考。OpenStack安全团队基于OpenStack社区的自愿贡献。您可以在OFTC IRC上的#OpenStack-Security频道中直接联系安全社区,或者通过向OpenStack-Discussion邮件列表发送主题标题中带有[Security]前缀的邮件来联系。 + +## 内容 + +- 约定 + + - 通知 + - 命令提示符 + +- 介绍 + + - 确定 + - 我们为什么以及如何写这本书 + - OpenStack简介 + - 安全边界和威胁 + - 选择支持软件 + +- 系统文档 + + - 系统文档要求 + +- 管理 + + - 持续的系统管理 + - 完整性生命周期 + - 管理界面 + +- 安全通信 + + - TLS和SSL简介 + - TLS代理和HTTP服务 + - 安全参考架构 + +- 端点 + + - APL端点配置建议 + +- 身份 + + - 认证 + - 身份验证方法 + - 授权 + - 政策 + - 令牌 + - 域 + - 联合梯形失真 + - 清单 + +- 仪表板 + + - 域名、仪表板升级和基本Web服务器配置 + - HTTPS、HSTS、XSS和SSRF + - 前端缓存和会话后端 + - 静态媒体 + - 密码 + - 密钥 + - 网站数据 + - 跨域资源共享 (CORS) + - 调试 + - 检查表 + +- 计算 + + - 虚拟机管理程序选择 + - 强化虚拟化层 + - 强化计算部署 + - 漏洞意识 + - 如何选择虚拟控制台 + - 检查表 + +- 块存储 + + - 音量擦除 + - 检查表 + +- 图像存储 + + - 检查表 + +- 共享文件系统 + + - 介绍 + - 网络和安全模型 + - 安全服务 + - 共享访问控制 + - 共享类型访问控制 + - 政策 + - 检查表 + +- 联网 + + - 网络架构 + - 网络服务 + - 网络服务安全最佳做法 + - 保护 OpenStack 网络服务 + - 检查表 + +- 对象存储 + + - 网络安全 + - 一般事务安全 + - 保护存储服务 + - 保护代理服务 + - 对象存储身份验证 + - 其他值得注意的项目 + +- 机密管理 + + - 现有技术摘要 + - 相关 Openstack 项目 + - 使用案例 + - 密钥管理服务 + - 密钥管理接口 + - 常见问题解答 + - 检查表 + +- 消息队列 + + - 邮件安全 + +- 数据处理 + + - 数据处理简介 + - 部署 + - 配置和强化 + +- 数据库 + + - 数据库后端注意事项 + - 数据库访问控制 + - 数据库传输安全性 + +- 租户数据隐私 + + - 数据隐私问题 + - 数据加密 + - 密钥管理 + +- 实例安全管理 + + - 实例的安全服务 + +- 监视和日志记录 + + - 取证和事件响应 + +- 合规 + + - 合规性概述 + - 了解审核流程 + - 合规活动 + - 认证和合规声明 + - 隐私 + +- 安全审查 + + - 体系结构页面指南 + +- 安全检查表 +- 附录 + + - 社区支持 + - 词汇表 + +## 约定 + +OpenStack 文档使用了几种排版约定。 + +### 注意事项 + +**注意** + +```shell +带有附加信息的注释,用于解释文本的某一部分。 +``` + +**重要** + +```shell +在继续之前,您必须注意这一点。 +``` + +**提示** + +```shell +一个额外但有用的实用建议。 +``` + +**警示** + +```shell +防止用户犯错误的有用信息。 +``` + +**警告** + +```shell +有关数据丢失风险或安全问题的关键信息。 +``` + +### 命令提示符 + +```shell +$ command +``` + +任何用户(包括root用户)都可以运行以$提示符为前缀的命令。 + +```shell +# command +``` + +root用户必须运行前缀为#提示符的命令。您还可以在这些命令前面加上sudo命令(如果可用),以运行这些命令。 + +## 介绍 + +《OpenStack 安全指南》是许多人经过五天协作的成果。本文档旨在提供部署安全 OpenStack 云的最佳实践指南。它旨在反映OpenStack社区的当前安全状态,并为由于复杂性或其他特定于环境的细节而无法列出特定安全控制措施的决策提供框架。 + +- 致谢 +- 我们为什么以及如何写这本书 + + - 目标 + - 如何 + +- OpenStack 简介 + + - 云类型 + - OpenStack 服务概述 + +- 安全边界和威胁 + + - 安全域 + - 桥接安全域 + - 威胁分类、参与者和攻击媒介 + +- 选择支持软件 + + - 团队专长 + - 产品或项目成熟度 + - 通用标准 + - 硬件问题 + +### 致谢 + +OpenStack 安全组要感谢以下组织的贡献,他们为本书的出版做出了贡献。这些组织是: + +![../_images/book-sprint-all-logos.png](https://docs.openstack.org/security-guide/_images/book-sprint-all-logos.png) + +### 我们为什么以及如何写这本书 + +随着 OpenStack 的普及和产品成熟,安全性已成为重中之重。OpenStack 安全组已经认识到需要一个全面而权威的安全指南。《OpenStack 安全指南》旨在概述提高 OpenStack 部署安全性的安全最佳实践、指南和建议。作者带来了他们在各种环境中部署和保护 OpenStack 的专业知识。 + +本指南是对《OpenStack 操作指南》的补充,可用于强化现有的 OpenStack 部署或评估 OpenStack 云提供商的安全控制。 + +#### 目标 + +- 识别 OpenStack 中的安全域 +- 提供保护 OpenStack 部署的指导 +- 强调当今 OpenStack 中的安全问题和潜在的缓解措施 +- 讨论即将推出的安全功能 +- 为知识获取和传播提供社区驱动的设施 + +#### 写作记录 + +与《OpenStack 操作指南》一样,我们遵循了本书的冲刺方法。书籍冲刺过程允许快速开发和制作大量书面作品。OpenStack 安全组的协调员重新邀请了 Adam Hyde 作为协调人。该项目在俄勒冈州波特兰市的OpenStack峰会上正式宣布。 + +由于该小组的一些关键成员离得很近,该团队聚集在马里兰州安纳波利斯。这是公共部门情报界成员、硅谷初创公司和一些大型知名科技公司之间的非凡合作。该书的冲刺在2013年6月的最后一周进行,第一版在五天内完成。 + +该团队包括: + +- Bryan D. Payne,星云 + Bryan D. Payne 博士是 Nebula 的安全研究总监,也是 OpenStack 安全组织 (OSSG) 的联合创始人。在加入 Nebula 之前,他曾在桑迪亚国家实验室、国家安全局、BAE Systems 和 IBM 研究院工作。他毕业于佐治亚理工学院计算机学院,获得计算机科学博士学位,专攻系统安全。Bryan 是《OpenStack 安全指南》的编辑和负责人,负责该指南在编写后的两年中持续增长。 + +- Robert Clark,惠普 + + Robert Clark 是惠普云服务的首席安全架构师,也是 OpenStack 安全组织 (OSSG) 的联合创始人。在被惠普招募之前,他曾在英国情报界工作。Robert 在威胁建模、安全架构和虚拟化技术方面拥有深厚的背景。Robert 拥有威尔士大学的软件工程硕士学位。 + +- Keith Basil ,红帽 + + Keith Basil 是红帽 OpenStack 的首席产品经理,专注于红帽的 OpenStack 产品管理、开发和战略。在美国公共部门,Basil 带来了为联邦民用机构和承包商设计授权、安全、高性能云架构的经验。 + +- Cody Bunch,拉克空间 + + Cody Bunch 是 Rackspace 的私有云架构师。Cody 与人合著了《The OpenStack Cookbook》的更新以及有关 VMware 自动化的书籍。 + +- Malini Bhandaru,英特尔 + + Malini Bhandaru 是英特尔的一名安全架构师。她拥有多元化的背景,曾在英特尔从事平台功能和性能方面的工作,在 Nuance 从事语音产品方面的工作,在 ComBrio 从事远程监控和管理工作,在 Verizon 从事网络商务工作。她拥有马萨诸塞大学阿默斯特分校的人工智能博士学位。 + +- Gregg Tally,约翰霍普金斯大学应用物理实验室 + + Gregg Tally 是 JHU/APL 网络系统部门非对称运营部的总工程师。他主要从事系统安全工程方面的工作。此前,他曾在斯巴达、迈克菲和可信信息系统公司工作,参与网络安全研究项目。 + +- Eric Lopez, 威睿 + + Eric Lopez 是 VMware 网络和安全业务部门的高级解决方案架构师,他帮助客户实施 OpenStack 和 VMware NSX(以前称为 Nicira 的网络虚拟化平台)。在加入 VMware(通过公司收购 Nicira)之前,他曾在 Q1 Labs、Symantec、Vontu 和 Brightmail 工作。他拥有加州大学伯克利分校的电气工程/计算机科学和核工程学士学位和旧金山大学的工商管理硕士学位。 + +- Shawn Wells,红帽 + + Shawn Wells 是红帽创新项目总监,专注于改进美国政府内部采用、促进和管理开源技术的流程。此外,Shawn 还是 SCAP 安全指南项目的上游维护者,该项目与美国军方、NSA 和 DISA 一起制定虚拟化和操作系统强化策略。Shawn曾是NSA的平民,利用大型分布式计算基础设施开发了SIGINT收集系统。 + +- Ben de Bont,惠普 + + Ben de Bont 是惠普云服务的首席战略官。在担任现职之前,Ben 领导 MySpace 的信息安全小组和 MSN Security 的事件响应团队。Ben 拥有昆士兰科技大学的计算机科学硕士学位。 + +- Nathanael Burton,国家安全局 + + 纳塔内尔·伯顿(Nathanael Burton)是美国国家安全局(National Security Agency)的计算机科学家。他在该机构工作了 10 多年,从事分布式系统、大规模托管、开源计划、操作系统、安全、存储和虚拟化技术方面的工作。他拥有弗吉尼亚理工大学的计算机科学学士学位。 + +- Vibha Fauver + + Vibha Fauver,GWEB,CISSP,PMP,在信息技术领域拥有超过15年的经验。她的专业领域包括软件工程、项目管理和信息安全。她拥有计算机与信息科学学士学位和工程管理硕士学位,专业和系统工程证书。 + +- Eric Windisch,云缩放 + + Eric Windisch 是 Cloudscaling 的首席工程师,他为 OpenStack 贡献了两年多。埃里克(Eric)在网络托管行业拥有十多年的经验,一直在敌对环境的战壕中,建立了租户隔离和基础设施安全性。自 2007 年以来,他一直在构建云计算基础设施和自动化。 + +- Andrew Hay,云道 + + Andrew Hay 是 CloudPassage, Inc. 的应用安全研究总监,负责领导该公司及其专为动态公有云、私有云和混合云托管环境构建的服务器安全产品的安全研究工作。 + +- Adam Hyde + + 亚当促成了这个 Book Sprint。他还创立了 Book Sprint 方法论,并且是最有经验的 Book Sprint 促进者。Adam 创立了 FLOSS Manuals,这是一个由 3,000 人组成的社区,致力于开发关于自由软件的自由手册。他还是 Booktype 的创始人和项目经理,Booktype 是一个用于在线和印刷书籍编写、编辑和出版的开源项目。 + +在冲刺期间,我们还得到了 Anne Gentle、Warren Wang、Paul McMillan、Brian Schott 和 Lorin Hochstein 的帮助。 + +这本书是在为期 5 天的图书冲刺中制作的。图书冲刺是一个高度协作、促进的过程,它将一个小组聚集在一起,在 3-5 天内制作一本书。这是一个由亚当·海德(Adam Hyde)创立和发展的特定方法的有力促进过程。有关更多信息,请访问BookSprints的Book Sprint网页。 + +#### 如何为本书做贡献 + +本书的最初工作是在一间空调过高的房间里进行的,该房间是整个文档冲刺期间的小组办公室。 + +要了解有关如何为 OpenStack 文档做出贡献的更多信息,请参阅 OpenStack 文档贡献者指南。 + +### OpenStack 简介 + +本指南提供了对 OpenStack 部署的安全见解。目标受众是云架构师、部署人员和管理员。此外,云用户会发现该指南在提供商选择方面既有教育意义又有帮助,而审计人员会发现它作为参考文档很有用,可以支持他们的合规性认证工作。本指南也推荐给任何对云安全感兴趣的人。 + +每个 OpenStack 部署都包含各种各样的技术,包括 Linux 发行版、数据库系统、消息队列、OpenStack 组件本身、访问控制策略、日志记录服务、安全监控工具等等。所涉及的安全问题同样多种多样也就不足为奇了,对这些问题的深入分析需要一些指南。我们努力寻找平衡点,提供足够的背景信息来理解OpenStack安全问题及其处理,并为进一步的信息提供外部参考。该指南可以从头到尾阅读,也可以像参考一样使用。 + +我们简要介绍了云的种类(私有云、公有云和混合云),然后在本章的其余部分概述了 OpenStack 组件及其相关的安全问题。 + +在整本书中,我们提到了几种类型的OpenStack云用户:管理员、操作员和用户。我们使用这些术语来标识每个角色具有的安全访问级别,尽管实际上,我们知道不同的角色通常由同一个人担任。 + +#### 云类型 + +OpenStack是采用云技术的关键推动因素,并具有几个常见的部署用例。这些模型通常称为公共模型、专用模型和混合模型。以下各节使用美国国家标准与技术研究院 (NIST) 对云的定义来介绍这些适用于 OpenStack 的不同类型的云。 + +#### 公有云 + +根据NIST的说法,公共云是基础设施向公众开放供消费的云。OpenStack公有云通常由服务提供商运行,可供个人、公司或任何付费客户使用。除了多种实例类型外,公有云提供商还可能公开一整套功能,例如软件定义网络或块存储。 + +就其性质而言,公有云面临更高的风险。作为公有云的使用者,您应该验证所选提供商是否具有必要的认证、证明和其他法规注意事项。作为公有云提供商,根据您的目标客户,您可能需要遵守一项或多项法规。此外,即使不需要满足法规要求,提供商也应确保租户隔离,并保护管理基础结构免受外部攻击。 + +#### 私有云 + +在频谱的另一端是私有云。正如NIST所定义的那样,私有云被配置为由多个消费者(如业务部门)组成的单个组织独占使用。云可能由组织、第三方或它们的某种组合拥有、管理和运营,并且可能存在于本地或外部。私有云用例多种多样,因此,它们各自的安全问题各不相同。 + +#### 社区云 + +NIST 将社区云定义为其基础结构仅供具有共同关注点(例如,任务、安全要求、策略或合规性注意事项)的组织的特定消费者社区使用。云可能由社区中的一个或多个组织、第三方或它们的某种组合拥有、管理和运营,并且它可能存在于本地或外部。 + +#### 混合云 + +NIST将混合云定义为两个或多个不同的云基础设施(如私有云、社区云或公共云)的组合,这些云基础设施仍然是唯一的实体,但通过标准化或专有技术绑定在一起,从而实现数据和应用程序的可移植性,例如用于云之间负载平衡的云爆发。例如,在线零售商可能会在允许弹性配置的公有云上展示其广告和目录。这将使他们能够以灵活、具有成本效益的方式处理季节性负载。一旦客户开始处理他们的订单,他们就会被转移到一个更安全的私有云中,该私有云符合PCI标准。 + +在本文档中,我们以类似的方式对待社区和混合云,仅从安全角度明确处理公有云和私有云的极端情况。安全措施取决于部署在私有公共连续体上的位置。 + +### OpenStack 服务概述 + +OpenStack 采用模块化架构,提供一组核心服务,以促进可扩展性和弹性作为核心设计原则。本章简要回顾了 OpenStack 组件、它们的用例和安全注意事项。 + +[![../_images/marketecture-diagram.png](https://docs.openstack.org/security-guide/_images/marketecture-diagram.png)](https://docs.openstack.org/security-guide/_images/marketecture-diagram.png) + +### 计算 + +OpenStack Compute 服务 (nova) 提供的服务支持大规模管理虚拟机实例、托管多层应用程序的实例、开发或测试环境、处理 Hadoop 集群的“大数据”或高性能计算。 + +计算服务通过与支持的虚拟机监控程序交互的抽象层来促进这种管理(我们稍后会更详细地讨论这个问题)。 + +在本指南的后面部分,我们将重点介绍虚拟化堆栈,因为它与虚拟机管理程序相关。 + +有关功能支持的当前状态的信息,请参阅 OpenStack Hypervisor 支持矩阵。 + +计算安全性对于OpenStack部署至关重要。强化技术应包括对强实例隔离的支持、计算子组件之间的安全通信以及面向公众的 API 终结点的复原能力。 + +#### 对象存储 + +OpenStack 对象存储服务 (swift) 支持在云中存储和检索任意数据。对象存储服务提供本机 API 和亚马逊云科技 S3 兼容 API。该服务通过数据复制提供高度的复原能力,并且可以处理 PB 级的数据。 + +请务必了解对象存储不同于传统的文件系统存储。对象存储最适合用于静态数据,例如媒体文件(MP3、图像或视频)、虚拟机映像和备份文件。 + +对象安全应侧重于传输中和静态数据的访问控制和加密。其他问题可能与系统滥用、非法或恶意内容存储以及交叉身份验证攻击媒介有关。 + +#### 块存储 + +OpenStack 块存储服务 (cinder) 为计算实例提供持久性块存储。块存储服务负责管理块设备的生命周期,从创建卷和附加到实例,再到释放。 + +块存储的安全注意事项与对象存储的安全注意事项类似。 + +#### 共享文件系统 + +共享文件系统服务(马尼拉)提供了一组用于管理多租户云环境中的共享文件系统的服务,类似于 OpenStack 通过 OpenStack 块存储服务项目提供基于块的存储管理的方式。使用共享文件系统服务,您可以创建远程文件系统,将文件系统挂载到实例上,然后从实例读取和写入文件系统中的数据。 + +#### 网络 + +OpenStack 网络服务(neutron,以前称为量子)为云用户(租户)提供各种网络服务,例如 IP 地址管理、DNS、DHCP、负载均衡和安全组(网络访问规则,如防火墙策略)。此服务为软件定义网络 (SDN) 提供了一个框架,允许与各种网络解决方案进行可插拔集成。 + +OpenStack Networking 允许云租户管理其访客网络配置。网络服务的安全问题包括网络流量隔离、可用性、完整性和机密性。 + +#### 仪表板 + +OpenStack 仪表板 (horizon) 为云管理员和云租户提供了一个基于 Web 的界面。使用此界面,管理员和租户可以预配、管理和监视云资源。仪表板通常以面向公众的方式部署,具有公共 Web 门户的所有常见安全问题。 + +#### 身份鉴别服务 + +OpenStack Identity 服务 (keystone) 是一项共享服务,可在整个云基础架构中提供身份验证和授权服务。Identity 服务具有对多种身份验证形式的可插入支持。 + +Identity 服务的安全问题包括对身份验证的信任、授权令牌的管理以及安全通信。 + +#### 镜像服务 + +OpenStack 镜像服务(glance)提供磁盘镜像管理服务,包括镜像发现、注册和根据需要向计算服务交付服务。 + +需要受信任的进程来管理磁盘映像的生命周期,以及前面提到的与数据安全有关的所有问题。 + +#### 数据处理服务 + +数据处理服务 (sahara) 提供了一个平台,用于配置、管理和使用运行常用处理框架的群集。 + +数据处理的安全注意事项应侧重于数据隐私和与预置集群的安全通信。 + +#### 其他配套技术 + +消息传递用于多个 OpenStack 服务之间的内部通信。默认情况下,OpenStack 使用基于 AMQP 的消息队列。与大多数 OpenStack 服务一样,AMQP 支持可插拔组件。现在,实现后端可以是 RabbitMQ、Qpid 或 ZeroMQ。 + +由于大多数管理命令都流经消息队列系统,因此消息队列安全性是任何 OpenStack 部署的主要安全问题,本指南稍后将对此进行详细讨论。 + +有几个组件使用数据库,尽管它没有显式调用。保护数据库访问是另一个安全问题,因此在本指南后面将更详细地讨论。 + +### 安全边界和威胁 + +云可以抽象为逻辑组件的集合,因为它们的功能、用户和共享的安全问题,我们称之为安全域。威胁参与者和向量根据其动机和对资源的访问进行分类。我们的目标是根据您的风险/漏洞保护目标,让您了解每个域的安全问题。 + +#### 安全域 + +安全域包括用户、应用程序、服务器或网络,它们在系统中具有共同的信任要求和期望。通常,它们具有相同的身份验证和授权 (AuthN/Z) 要求和用户。 + +尽管您可能希望进一步细分这些域(我们稍后将讨论在哪些方面可能合适),但我们通常指的是四个不同的安全域,它们构成了安全部署任何 OpenStack 云所需的最低限度。这些安全域包括: + +1. 公共域 +2. 访客域 +3. 管理域 +4. 数据域 + +我们之所以选择这些安全域,是因为它们可以独立映射,也可以组合起来,以表示给定 OpenStack 部署中大多数可能的信任区域。例如,某些部署拓扑可能由一个物理网络上的来宾域和数据域的组合组成,而其他拓扑则将这些域分开。在每种情况下,云操作员都应注意适当的安全问题。安全域应针对特定的 OpenStack 部署拓扑进行映射。域及其信任要求取决于云实例是公有云实例、私有云实例还是混合云实例。 + +![../_images/untrusted_trusted.png](https://docs.openstack.org/security-guide/_images/untrusted_trusted.png) + +#### 公共 + +公共安全域是云基础架构中完全不受信任的区域。它可以指整个互联网,也可以简单地指您无权访问的网络。任何具有机密性或完整性要求传输此域的数据都应使用补偿控制进行保护。 + +此域应始终被视为不受信任。 + +#### 访客 + +访客安全域通常用于计算实例到实例的流量,它处理由云上的实例生成的计算数据,但不处理支持云操作的服务,例如 API 调用。 + +如果公有云和私有云提供商对实例使用没有严格控制,也不允许对虚拟机进行不受限制的 Internet 访问,则应将此域视为不受信任的域。私有云提供商可能希望将此网络视为内部网络,并且只有在实施适当的控制以断言实例和所有关联租户都是可信的时。 + +#### 管理 + +管理安全域是服务交互的地方。有时称为“控制平面”,此域中的网络传输机密数据,例如配置参数、用户名和密码。命令和控制流量通常驻留在此域中,这需要强大的完整性要求。对此域的访问应受到高度限制和监视。同时,此域仍应采用本指南中描述的所有安全最佳做法。 + +在大多数部署中,此域被视为受信任的域。但是,在考虑 OpenStack 部署时,有许多系统将此域与其他域桥接起来,这可能会降低您可以对该域的信任级别。有关更多信息,请参阅桥接安全域。 + +#### 数据 + +数据安全域主要关注与OpenStack中的存储服务有关的信息。通过该网络传输的大多数数据都需要高度的完整性和机密性。在某些情况下,根据部署类型,可能还会有很强的可用性要求。 + +此网络的信任级别很大程度上取决于部署决策,因此我们不会为其分配任何默认的信任级别。 + +#### 桥接安全域 + +网桥是存在于多个安全域中的组件。必须仔细配置桥接具有不同信任级别或身份验证要求的安全域的任何组件。这些网桥通常是网络架构中的薄弱环节。桥接应始终配置为满足它所桥接的任何域的最高信任级别的安全要求。在许多情况下,由于攻击的可能性,桥接器的安全控制应该是主要关注点。 + +![../_images/bridging_security_domains_1.png](https://docs.openstack.org/security-guide/_images/bridging_security_domains_1.png) + +上图显示了桥接数据和管理域的计算节点;因此,应将计算节点配置为满足管理域的安全要求。同样,此图中的 API 端点正在桥接不受信任的公共域和管理域,应将其配置为防止从公共域传播到管理域的攻击。 + +![../_images/bridging_domains_clouduser.png](https://docs.openstack.org/security-guide/_images/bridging_domains_clouduser.png) + +在某些情况下,部署人员可能希望考虑将网桥保护到比它所在的任何域更高的标准。鉴于上述 API 端点示例,攻击者可能会从公共域以 API 端点为目标,利用它来入侵或访问管理域。 + +OpenStack的设计使得安全域的分离是很困难的。由于核心服务通常至少桥接两个域,因此在对它们应用安全控制时必须特别考虑。 + +#### 威胁分类、参与者和攻击向量 + +大多数类型的云部署(公有云或私有云)都会受到某种形式的攻击。在本章中,我们将对攻击者进行分类,并总结每个安全域中的潜在攻击类型。 + +#### 威胁参与者 + +威胁参与者是一种抽象的方式,用于指代您可能尝试防御的一类对手。参与者的能力越强,成功缓解和预防攻击所需的安全控制就越昂贵。安全性是成本、可用性和防御之间的权衡。在某些情况下,不可能针对我们在此处描述的所有威胁参与者保护云部署。那些部署OpenStack云的人将不得不决定其部署/使用的平衡点在哪里。 + +##### 情报机构 + +本指南认为是最有能力的对手。情报部门和其他国家行为者可以为目标带来巨大的资源。他们拥有超越任何其他参与者的能力。如果没有极其严格的控制措施,无论是人力还是技术,都很难防御这些行为者。 + +##### 严重有组织犯罪 + +能力强且受经济驱动的攻击者群体。能够资助内部漏洞开发和目标研究。近年来,俄罗斯商业网络(Russian Business Network)等组织的崛起,一个庞大的网络犯罪企业,已经证明了网络攻击如何成为一种商品。工业间谍活动属于严重的有组织犯罪集团。 + +##### 高能力的团队 + +这是指“黑客行动主义者”类型的组织,他们通常没有商业资助,但可能对服务提供商和云运营商构成严重威胁。 + +##### 有动机的个人 + +这些攻击者单独行动,以多种形式出现,例如流氓或恶意员工、心怀不满的客户或小规模的工业间谍活动。 + +##### 脚本攻击者 + +自动漏洞扫描/利用。非针对性攻击。通常,只有这些行为者之一的滋扰、妥协才会对组织的声誉构成重大风险。 + +![../_images/threat_actors.png](https://docs.openstack.org/security-guide/_images/threat_actors.png) + +#### 公有云和私有云注意事项 + +私有云通常由企业或机构在其网络内部和防火墙后面部署。企业将对允许哪些数据退出其网络有严格的政策,甚至可能为特定目的使用不同的云。私有云的用户通常是拥有云的组织的员工,并且能够对其行为负责。员工通常会在访问云之前参加培训课程,并且可能会参加定期安排的安全意识培训。相比之下,公有云不能对其用户、云用例或用户动机做出任何断言。对于公有云提供商来说,这会立即将客户机安全域推入完全不受信任的状态。 + +公有云攻击面的一个显着区别是,它们必须提供对其服务的互联网访问。实例连接、通过 Internet 访问文件以及与云控制结构(如 API 端点和仪表板)交互的能力是公有云的必备条件。 + +公有云和私有云用户的隐私问题通常是截然相反的。在私有云中生成和存储的数据通常由云运营商拥有,他们能够部署数据丢失防护 (DLP) 保护、文件检查、深度数据包检查和规范性防火墙等技术。相比之下,隐私是采用公有云基础设施的主要障碍之一,因为前面提到的许多控制措施并不存在。 + +#### 出站攻击和声誉风险 + +应仔细考虑云部署中潜在的出站滥用。无论是公有云还是私有云,云往往都有大量可用资源。通过黑客攻击或授权访问在云中建立存在点的攻击者(例如流氓员工)可以使这些资源对整个互联网产生影响。具有计算服务的云是理想的 DDoS 和暴力引擎。对于公有云来说,这个问题更为紧迫,因为它们的用户在很大程度上是不负责任的,并且可以迅速启动大量一次性实例进行出站攻击。如果一家公司因托管恶意软件或对其他网络发起攻击而闻名,可能会对公司的声誉造成重大损害。预防方法包括出口安全组、出站流量检查、客户教育和意识,以及欺诈和滥用缓解策略。 + +#### 攻击类型 + +该图显示了上一节中描述的参与者可能预期的典型攻击类型。请注意,此图不排除有不可预期的攻击类型。 + +![../_images/high-capability.png](https://docs.openstack.org/security-guide/_images/high-capability.png) + +攻击类型 + +每种攻击形式的规范性防御超出了本文档的范围。上图可以帮助您就应防范哪些类型的威胁和威胁参与者做出明智的决定。对于商业公有云部署,这可能包括预防严重犯罪。对于那些为政府使用部署私有云的人来说,应该建立更严格的保护机制,包括精心保护的设施和供应链。相比之下,那些建立基本开发或测试环境的人可能需要限制较少的控制(中间)。 + +### 选择支持软件 + +您选择的支持软件(如消息传递和负载平衡)可能会对云产生严重的安全影响。为组织做出正确的选择非常重要。本节提供了选择支持软件的一些一般准则。 + +为了选择最佳支持软件,请考虑以下因素: + +- 团队专业知识 +- 产品或项目成熟度 +- 通用标准 +- 硬件问题 + +#### 团队专业知识 + +团队越熟悉特定产品、其配置和特殊性,就越少会出现配置错误。此外,将员工的专业知识分散到整个组织中可以增加系统的可用性,允许分工,并在团队成员不可用时减轻问题。 + +#### 产品或项目成熟度 + +给定产品或项目的成熟度对您的安全状况至关重要。部署云后,产品成熟度会产生许多影响: + +- 专业知识的可用性 +- 活跃的开发人员和用户社区 +- 更新的及时性和可用性 +- 事件响应 + +#### 通用标准 + +通用标准是一个国际标准化的软件评估过程,政府和商业公司使用它来验证软件技术的性能是否如宣传的那样。 + +#### 硬件问题 + +考虑运行软件的硬件的可支持性。此外,请考虑硬件中可用的其他功能,以及您选择的软件如何支持这些功能。 + +## 系统文档 + +OpenStack 云部署的系统文档应遵循组织中企业信息技术系统的模板和最佳实践。组织通常有合规性要求,这可能需要一个整体的系统安全计划来清点和记录给定系统的架构。整个行业都面临着与记录动态云基础架构和保持信息最新相关的共同挑战。 + +- 系统文档要求 + + - 系统角色和类型 + - 系统清单 + - 网络拓扑 + - 服务、协议和端口 + +### 系统文档要求 + +#### 系统角色和类型 + +通常构成 OpenStack 安装的两种广义节点类型是: + +##### 基础设施节点 + +运行与云相关的服务,例如 OpenStack Identity 服务、消息队列服务、存储、网络以及支持云运行所需的其他服务。 + +##### 计算、存储或其他资源节点 + +为云提供存储容量或虚拟机。 + +#### 系统清单 + +文档应提供OpenStack环境的一般描述,并涵盖使用的所有系统(例如,生产、开发或测试)。记录系统组件、网络、服务和软件通常提供全面覆盖和考虑安全问题、攻击媒介和可能的安全域桥接点所需的鸟瞰图。系统清单可能需要捕获临时资源,例如虚拟机或虚拟磁盘卷,否则这些资源将成为传统 IT 系统中的持久性资源。 + +#### 硬件清单 + +对书面文档没有严格合规性要求的云可能会受益于配置管理数据库 (CMDB)。CMDB通常用于硬件资产跟踪和整体生命周期管理。通过利用 CMDB,组织可以快速识别云基础设施硬件,例如计算节点、存储节点或网络设备。CMDB可以帮助识别网络上存在的资产,这些资产可能由于维护不足、保护不足或被取代和遗忘而存在漏洞。如果底层硬件支持必要的自动发现功能,则 OpenStack 置备系统可以提供一些基本的 CMDB 功能。 + +#### 软件清单 + +与硬件一样,OpenStack 部署中的所有软件组件都应记录在案。示例包括: + +- 系统数据库,例如 MySQL 或 mongoDB +- OpenStack 软件组件,例如 Identity 或 Compute +- 支持组件,例如负载均衡器、反向代理、DNS 或 DHCP 服务 + +在评估库、应用程序或软件类别中泄露或漏洞的影响时,软件组件的权威列表可能至关重要。 + +#### 网络拓扑 + +应提供网络拓扑,并突出显示安全域之间的数据流和桥接点。网络入口和出口点应与任何 OpenStack 逻辑系统边界一起标识。可能需要多个图表来提供系统的完整视觉覆盖。网络拓扑文档应包括系统代表租户创建的虚拟网络,以及 OpenStack 创建的虚拟机实例和网关。 + +#### 服务、协议和端口 + +了解有关组织资产的信息通常是最佳做法。资产表可以帮助验证安全要求,并帮助维护标准安全组件,例如防火墙配置、服务端口冲突、安全修正区域和合规性。此外,该表还有助于理解 OpenStack 组件之间的关系。该表可能包括: + +- OpenStack 部署中使用的服务、协议和端口。 +- 云基础架构中运行的所有服务的概述。 + +强烈建议 OpenStack 部署记录与此类似的信息。该表可以根据从 CMDB 派生的信息创建,也可以手动构建。 + +下面提供了一个表格示例: + +| 服务 | 协议 | 端口 | 目的 | 使用者 | 安全域 | +| -------- | ----- | -------- | ------------------------------ | --------- | ------------------------------------ | +| beam.smp | AMQP | 5672/tcp | AMQP 消息服务 | RabbitMQ | 管理域 | +| tgtd | iSCSI | 3260/tcp | iSCSI 发起程序服务 | iSCSI | 私有(数据网络) | +| sshd | ssh | 22/tcp | 允许安全登录到节点和来宾虚拟机 | Various | 按需配置作用于管理域、公共域和访客域 | +| mysqld | mysql | 3306/tcp | 数据库服务 | Various | 管理域 | +| apache2 | http | 443/tcp | 仪表板 | Tenants | 公共域 | +| dnsmasq | dns | 53/tcp | DNS 服务 | Guest VMs | 访客域 | + +## 管理 + +云部署是一个不断变化的系统。机器老化和故障,软件过时,漏洞被发现。当配置中出现错误或遗漏时,或者必须应用软件修复时,必须以安全但方便的方式进行这些更改。这些更改通常通过配置管理来解决。 + +保护云部署不被恶意实体配置或操纵非常重要。由于云中的许多系统都采用计算和网络虚拟化,因此 OpenStack 面临着明显的挑战,必须通过完整性生命周期管理来解决这些挑战。 + +管理员必须对云执行命令和控制,以实现各种操作功能。理解和保护这些指挥和控制设施非常重要。 + +- 持续的系统管理 + + - 漏洞管理 + - 配置管理 + - 安全备份和恢复 + - 安全审计工具 + +- 完整性生命周期 + + - 安全引导 + - 运行时验证 + - 服务器加固 + +- 管理界面 + + - 仪表板 + - OpenStack 接口 + - 安全外壳 (SSH) + - 管理实用程序 + - 带外管理接口 + +### 持续的系统管理 + +云系统总会存在漏洞,其中一些可能是安全问题。因此,准备好应用安全更新和常规软件更新至关重要。这涉及到配置管理工具的智能使用,下面将对此进行讨论。这还涉及了解何时需要升级。 + +#### 漏洞管理 + +有关安全相关更改的公告,请订阅 OpenStack Announce 邮件列表。安全通知还会通过下游软件包发布,例如,通过您可能作为软件包更新的一部分订阅的 Linux 发行版。 + +OpenStack组件只是云中软件的一小部分。与所有这些其他组件保持同步也很重要。虽然某些数据源是特定于部署的,但云管理员必须订阅必要的邮件列表,以便接收适用于组织环境的任何安全更新的通知。通常,这就像跟踪上游 Linux 发行版一样简单。 + +**注意** + +```shell +OpenStack 通过两个渠道发布安全信息。 + +- OpenStack 安全公告 (OSSA) 由 OpenStack 漏洞管理团队 (VMT) 创建。它们与核心OpenStack服务中的安全漏洞有关。有关 VMT 的更多信息,请参阅漏洞管理流程。 +- OpenStack 安全说明 (OSSN) 由 OpenStack 安全组 (OSSG) 创建,以支持 VMT 的工作。OSSN解决了支持软件和常见部署配置中的问题。本指南中引用了它们。安全说明存档在OSSN上。 +``` + +##### 分类 + +收到安全更新通知后,下一步是确定此更新对给定云部署的重要性。在这种情况下,拥有预定义的策略很有用。现有的漏洞评级系统(如通用漏洞评分系统 (CVSS))无法正确考虑云部署。 + +在此示例中,我们引入了一个评分矩阵,该矩阵将漏洞分为三类:权限提升、拒绝服务和信息泄露。了解漏洞的类型及其在基础架构中发生的位置将使您能够做出合理的响应决策。 + +权限提升描述了用户使用系统中其他用户的权限进行操作的能力,绕过适当的授权检查。来宾用户执行的操作允许他们以管理员权限执行未经授权的操作,这是此类漏洞的一个示例。 + +拒绝服务是指被利用的漏洞,可能导致服务或系统中断。这既包括使网络资源不堪重负的分布式攻击,也包括通常由资源分配错误或输入引起的系统故障缺陷引起的单用户攻击。 + +信息泄露漏洞会泄露有关您的系统或操作的信息。这些漏洞的范围从调试信息泄露到关键安全数据(如身份验证凭据和密码)的暴露。 + +| | 攻击者位置/权限级别 | | | | +| -------------------- | ------------------- | ------- | -------- | -------- | +| | 外部 | 云用户 | 云管理员 | 控制平面 | +| 权限提升(3 级) | 紧急 | n/a | n/a | n/a | +| 权限提升(2 个级别) | 紧急 | 紧急 | n/a | n/a | +| 特权提升(1 级) | 紧急 | 紧急 | 紧急 | n/a | +| 拒绝服务 | 高 | 中 | 低 | 低 | +| 信息披露 | 紧急/高 | 紧急/高 | 中/低 | 低 | + +该表说明了一种通用方法,该方法根据漏洞在部署中发生的位置和影响来衡量漏洞的影响。例如,计算 API 节点上的单级权限提升可能允许 API 的标准用户升级为具有与节点上的 root 用户相同的权限。 + +我们建议云管理员使用此表作为模型,以帮助定义要针对各种安全级别执行的操作。例如,关键级别的安全更新可能需要快速升级云,而低级别的更新可能需要更长的时间才能完成。 + +##### 测试更新 + +在生产环境中部署任何更新之前,应对其进行测试。通常,这需要有一个单独的测试云设置,该设置首先接收更新。在软件和硬件方面,此云应尽可能接近生产云。应在性能影响、稳定性、应用程序影响等方面对更新进行全面测试。特别重要的是验证更新理论上解决的问题(例如特定漏洞)是否已实际修复。 + +##### 部署更新 + +完全测试更新后,可以将其部署到生产环境。应使用下面所述的配置管理工具完全自动化此部署。 + +#### 配置管理 + +生产质量的云应始终使用工具来自动执行配置和部署。这消除了人为错误,并允许云更快地扩展。自动化还有助于持续集成和测试。 + +在构建 OpenStack 云时,强烈建议在设计和实现时考虑配置管理工具或框架。通过配置管理,您可以避免在构建、管理和维护像 OpenStack 这样复杂的基础架构时固有的许多陷阱。通过生成配置管理实用程序所需的清单、说明书或模板,您可以满足许多文档和法规报告要求。此外,配置管理还可以作为业务连续性计划 (BCP) 和数据恢复 (DR) 计划的一部分,您可以在其中将节点或服务重建回 DR 事件中的已知状态或给定的妥协状态。 + +此外,当与 Git 或 SVN 等版本控制系统结合使用时,您可以跟踪环境随时间推移而发生的更改,并重新调解可能发生的未经授权的更改。例如,文件 `nova.conf` 或其他配置文件不符合您的标准,您的配置管理工具可以还原或替换该文件,并将您的配置恢复到已知状态。最后,配置管理工具也可用于部署更新;简化安全补丁流程。这些工具具有广泛的功能,在该领域非常有用。保护云的关键点是选择一种配置管理工具并使用它。 + +有许多配置管理解决方案;在撰写本文时,市场上有两个在支持 OpenStack 环境方面非常强大的公司:Chef 和 Puppet。下面提供了此空间中的工具的非详尽列表: + +- Chef +- Puppet +- Salt Stack +- Ansible + +##### 策略更改 + +每当更改策略或配置管理时,最好记录活动并备份新集的副本。通常,此类策略和配置存储在受版本控制的存储库(如 Git)中。 + +#### 安全备份和恢复 + +在整个系统安全计划中包括备份过程和策略非常重要。有关 OpenStack 备份和恢复功能和过程的概述,请参阅有关备份和恢复的 OpenStack 操作指南。 + +- 确保只有经过身份验证的用户和备份客户端才能访问备份服务器。 +- 使用数据加密选项来存储和传输备份。 +- 使用专用且强化的备份服务器。备份服务器的日志必须每天进行监视,并且只有少数人可以访问。 +- 定期测试数据恢复选项,包括存储在安全备份中的镜像,是确保灾难恢复准备的关键部分。在发生安全漏洞或受损时,终止运行中的实例并从已知的安全镜像备份中重新启动实例确实是最佳做法。这有助于确保受损的实例被消除,并且可以迅速从备份的镜像中重新部署干净、可信赖的版本。 + +#### 安全审计工具 + +安全审核工具可以补充配置管理工具。安全审核工具可自动执行验证给定系统配置是否满足大量安全控制的过程。这些工具有助于弥合从安全配置指南文档(例如,STIG 和 NSA 指南)到特定系统安装的差距。例如,SCAP 可以将正在运行的系统与预定义的配置文件进行比较。SCAP 输出一份报告,详细说明配置文件中的哪些控件已满足,哪些控件未通过,哪些控件未选中。 + +将配置管理和安全审计工具相结合,形成了一个强大的组合。审核工具将突出显示部署问题。配置管理工具简化了更改每个系统的过程,以解决审计问题。以这种方式一起使用,这些工具有助于维护满足从基本强化到合规性验证等安全要求的云环境。 + +配置管理和安全审计工具将给云带来另一层复杂性。这种复杂性带来了额外的安全问题。考虑到其安全优势,我们认为这是一种可接受的风险权衡。对于这些工具的操作安全性保障超出了本指南的范围。 + +### 完整性生命周期 + +我们将完整性生命周期定义为一个深思熟虑的过程,它确保我们始终在整个云中以预期的配置运行预期的软件。此过程从安全引导开始,并通过配置管理和安全监控进行维护。本章就如何处理完整性生命周期过程提供了建议。 + +#### 安全引导 + +云中的节点,包括计算、存储、网络、服务和混合节点,应该有一个自动化的配置过程。这确保了节点的一致和正确配置。这也便于安全补丁、升级、故障修复和其他关键变更。由于这个过程安装了在云中具有最高特权级别的新软件,因此验证安装正确的软件非常重要,包括启动过程的最早阶段。 + +有多种技术可以验证这些早期启动阶段。这些通常需要硬件支持,例如可信平台模块 (TPM)、英特尔可信执行技术 (TXT)、动态信任根测量 (DRTM) 和统一可扩展固件接口 (UEFI) 安全启动。在本书中,我们将所有这些统称为安全启动技术。我们建议使用安全启动,同时承认部署此启动所需的许多部分需要高级技术技能才能为每个环境自定义工具。与本指南中的许多其他建议相比,使用安全启动需要更深入的集成和自定义。TPM 技术虽然在大多数商务级笔记本电脑和台式机中很常见数年,但现在已与支持的 BIOS 一起在服务器中可用。正确的规划对于成功的安全启动部署至关重要。 + +有关安全启动部署的完整教程超出了本书的范围。相反,我们在这里提供了一个框架,用于将安全启动技术与典型的节点预配过程集成。有关更多详细信息,云架构师应参考相关规范和软件配置手册。 + +##### 节点配置 + +节点应使用预引导执行环境(PXE)进行配置。这大大减少了重新部署节点所需的工作量。典型的过程涉及节点从服务器接收各种引导阶段(即执行的软件逐渐复杂)。 + +![../_images/node-provisioning-pxe.png](https://docs.openstack.org/security-guide/_images/node-provisioning-pxe.png) + +我们建议在管理安全域中使用单独的隔离网络进行置备。此网络将处理所有 PXE 流量,以及上面描述的后续启动阶段下载。请注意,节点引导过程从两个不安全的操作开始:DHCP 和 TFTP。然后,引导过程使用 TLS 下载部署节点所需的其余信息。这可能是操作系统安装程序、由 Chef 或 Puppet 管理的基本安装,甚至是直接写入磁盘的完整文件系统映像。 + +虽然在 PXE 启动过程中使用 TLS 更具挑战性,但常见的 PXE 固件项目(如 iPXE)提供了这种支持。通常,这涉及在了解允许的 TLS 证书链的情况下构建 PXE 固件,以便它可以正确验证服务器证书。这通过限制不安全的纯文本网络操作的数量来提高攻击者的门槛。 + +##### 验证启动 + +通常,有两种不同的策略来验证启动过程。传统的安全启动将验证在过程中的每个步骤运行的代码,并在代码不正确时停止启动。启动证明将记录在每个步骤中运行的代码,并将此信息提供给另一台计算机,以证明启动过程按预期完成。在这两种情况下,第一步都是在运行之前测量每段代码。在这种情况下,测量实际上是代码的 SHA-1 哈希值,在执行之前获取。哈希存储在 TPM 的平台配置寄存器 (PCR) 中。 + +**注意** + +```shell +此处使用 SHA-1,因为这是 TPM 芯片支持的内容。 +``` + +每个 TPM 至少有 24 个 PCR。2005 年 3 月的 TCG 通用服务器规范 v1.0 定义了启动时完整性测量的 PCR 分配。下表显示了典型的PCR配置。上下文指示这些值是根据节点硬件(固件)还是根据节点上置备的软件确定的。某些值受固件版本、磁盘大小和其他低级信息的影响。因此,在配置管理方面采取良好的做法非常重要,以确保部署的每个系统都完全按照预期进行配置。 + +| 注册 | 测量内容 | 上下文 | +| ---------------- | ------------------------------------------------- | ------ | +| PCR-00 | 核心信任根测量 (CRTM)、BIOS 代码、主机平台扩展 | 硬件 | +| PCR-01 | 主机平台配置 | 硬件 | +| PCR-02 | 选项 ROM 代码 | 硬件 | +| PCR-03 | 选项 ROM 配置和数据 | 硬件 | +| PCR-04 | 初始程序加载程序 (IPL) 代码。例如,主引导记录。 | 软件 | +| PCR-05 | IPL 代码配置和数据 | 软件 | +| PCR-06 | 状态转换和唤醒事件 | 软件 | +| PCR-07 | 主机平台制造商控制 | 软件 | +| PCR-08 | 特定于平台,通常是内核、内核扩展和驱动程序 | 软件 | +| PCR-09 | 特定于平台,通常是 Initramfs | 软件 | +| PCR-10 至 PCR-23 | 特定于平台 | 软件 | + +安全启动可能是构建云的一个选项,但需要在硬件选择方面进行仔细规划。例如,确保您具有 TPM 和英特尔 TXT 支持。然后验证节点硬件供应商如何填充 PCR 值。例如,哪些值可用于验证。通常,上表中软件上下文下列出的 PCR 值是云架构师可以直接控制的值。但即使这些也可能随着云中软件的升级而改变。配置管理应链接到 PCR 策略引擎,以确保验证始终是最新的。 + +每个制造商都必须为其服务器提供 BIOS 和固件代码。不同的服务器、虚拟机监控程序和操作系统将选择填充不同的 PCR。在大多数实际部署中,不可能根据已知的良好数量(“黄金测量”)验证每个PCR。经验表明,即使在单个供应商的产品线中,给定PCR的测量过程也可能不一致。建议为每个服务器建立基线,并监视 PCR 值以查找意外更改。第三方软件可能可用于协助 TPM 预配和监视过程,具体取决于所选的虚拟机监控程序解决方案。 + +初始程序加载程序 (IPL) 代码很可能是 PXE 固件,假设采用上述节点部署策略。因此,安全启动或启动证明过程可以测量所有早期启动代码,例如 BIOS、固件、PXE 固件和内核映像。确保每个节点都安装了这些部件的正确版本,为构建节点软件堆栈的其余部分奠定了坚实的基础。 + +根据所选的策略,在发生故障时,节点将无法启动,或者它可以将故障报告给云中的另一个实体。为了实现安全引导,节点将无法引导,管理安全域中的置备服务必须识别这一点并记录事件。对于启动证明,当检测到故障时,节点将已经在运行。在这种情况下,应通过禁用节点的网络访问来立即隔离节点。然后,应分析事件的根本原因。无论哪种情况,策略都应规定在失败后如何继续。云可能会自动尝试重新配置节点一定次数。或者,它可能会立即通知云管理员调查问题。此处的正确策略是特定于部署和故障模式的。 + +##### 节点加固 + +此时,我们知道节点已使用正确的内核和底层组件启动。下一步是强化操作系统,它从一组行业公认的强化控件开始。以下指南是很好的示例: + +安全技术实施指南 (STIG) + +国防信息系统局 (DISA)(隶属于美国国防部)发布适用于各种操作系统、应用程序和硬件的 STIG 内容。这些控件在未附加任何许可证的情况下发布。 + +互联网安全中心 (CIS) 基准测试 + +CIS 会定期发布安全基准以及自动应用这些安全控制的自动化工具。这些基准测试是在具有一些限制的知识共享许可下发布的。 + +这些安全控制最好通过自动化方法应用。自动化确保每次对每个系统都以相同的方式应用控制,并且它们还提供了一种用于审核现有系统的快速方法。自动化有多种选择: + +OpenSCAP + +OpenSCAP 是一个开源工具,它采用 SCAP 内容(描述安全控制的 XML 文件)并将该内容应用于各种系统。目前可用的大多数内容都适用于 Red Hat Enterprise Linux 和 CentOS,但这些工具适用于任何 Linux 或 Windows 系统。 + +ansible 加固 + +ansible-hardening 项目提供了一个 Ansible 角色,可将安全控制应用于各种 Linux 操作系统。它还可用于审核现有系统。仔细检查每个控制措施,以确定它是否可能对生产系统造成损害。这些控件基于 Red Hat Enterprise Linux 7 STIG。 + +完全加固的系统是一个具有挑战性的过程,可能需要对某些系统进行大量更改。其中一些更改可能会影响生产工作负载。如果系统无法完全加固,强烈建议进行以下两项更改,以便在不造成重大中断的情况下提高安全性: + +###### 强制访问控制 (MAC) + +强制访问控制会影响系统上的所有用户,包括 root,内核的工作是根据当前安全策略审查活动。如果活动不在允许的策略范围内,则会被阻止,即使对于 root 用户也是如此。有关更多详细信息,请查看下面关于 sVirt、SELinux 和 AppArmor 的讨论。 + +###### 删除软件包并停止服务 + +确保系统安装的软件包数量尽可能少,并且运行的服务数量尽可能少。删除不需要的软件包可以更轻松地进行修补,并减少系统上可能导致违规的项目数量。停止不需要的服务会缩小系统上的攻击面,并使攻击更加困难。 + +我们还建议对生产节点执行以下附加步骤: + +###### 只读文件系统 + +尽可能使用只读文件系统。确保可写文件系统不允许执行。这可以使用 `noexec` 中的 、 `nosuid` 和 `nodev` 挂载选项来处理 `/etc/fstab` 。 + +###### 系统验证 + +最后,节点内核应该有一种机制来验证节点的其余部分是否以已知的良好状态启动。这提供了从引导验证过程到验证整个系统的必要链接。执行此操作的步骤将特定于部署。例如,内核模块可以在使用 dm-verity 挂载文件系统之前验证组成文件系统的块的哈希值。 + +#### 运行时验证 + +一旦节点运行,我们需要确保它随着时间的推移保持良好的状态。从广义上讲,这包括配置管理和安全监控。这些领域中每个领域的目标都不同。通过检查这两者,我们可以更好地确保系统按预期运行。我们将在管理部分讨论配置管理,并在下面讨论安全监控。 + +##### 入侵检测系统 + +基于主机的入侵检测工具对于自动验证云内部也很有用。有各种各样的基于主机的入侵检测工具可用。有些是免费提供的开源项目,而另一些则是商业项目。通常,这些工具会分析来自各种来源的数据,并根据规则集和/或训练生成安全警报。典型功能包括日志分析、文件完整性检查、策略监控和 rootkit 检测。更高级(通常是自定义)工具可以验证内存中进程映像是否与磁盘上的可执行文件匹配,并验证正在运行的进程的执行状态。 + +对于云架构师来说,一个关键的策略决策是如何处理安全监控工具的输出。实际上有两种选择。首先是提醒人类进行调查和/或采取纠正措施。这可以通过在云管理员的日志或事件源中包含安全警报来完成。第二种选择是让云自动采取某种形式的补救措施,以及记录事件。补救措施可能包括从重新安装节点到执行次要服务配置的任何内容。但是,由于可能存在误报,自动补救措施可能具有挑战性。 + +当安全监视工具为良性事件生成安全警报时,会发生误报。由于安全监控工具的性质,误报肯定会不时发生。通常,云管理员可以调整安全监控工具以减少误报,但这也可能同时降低整体检测率。在云中设置安全监控系统时,必须了解并考虑这些经典的权衡。 + +基于主机的入侵检测工具的选择和配置具有高度的部署特异性。我们建议从探索以下开源项目开始,这些项目实现了各种基于主机的入侵检测和文件监控功能。 + +- OSSEC +- Samhain +- Tripwire +- AIDE + +网络入侵检测工具是对基于主机的工具的补充。OpenStack 没有内置特定的网络 IDS,但 OpenStack Networking 提供了一种插件机制,可以通过 Networking API 启用不同的技术。此插件体系结构将允许租户开发 API 扩展,以插入和配置自己的高级网络服务,例如防火墙、入侵检测系统或虚拟机之间的 VPN。 + +与基于主机的工具类似,基于网络的入侵检测工具的选择和配置是特定于部署的。Snort 是领先的开源网络入侵检测工具,也是了解更多信息的良好起点。 + +对于基于网络和主机的入侵检测系统,有一些重要的安全注意事项。 + +- 重要的是要考虑将网络 IDS 放置在云上(例如,将其添加到网络边界和/或敏感网络周围)。放置位置取决于您的网络环境,但请确保监控 IDS 可能对您的服务产生的影响,具体取决于您选择添加的位置。网络 IDS 通常无法检查加密流量(如 TLS)的内容。但是,网络 IDS 在识别网络上的异常未加密流量方面仍可能提供一些好处。 +- 在某些部署中,可能需要在安全域网桥上的敏感组件上添加基于主机的 IDS。基于主机的 IDS 可能会通过组件上遭到入侵或未经授权的进程来检测异常活动。IDS 应在管理网络上传输警报和日志信息。 + +#### 服务器加固 + +云环境中的服务器,包括 undercloud 和 overcloud 基础架构,应实施强化最佳实践。由于操作系统和服务器强化很常见,因此此处不涵盖适用的最佳实践,包括但不限于日志记录、用户帐户限制和定期更新,但应应用于所有基础结构。 + +##### 文件完整性管理(FIM) + +文件完整性管理 (FIM) 是确保敏感系统或应用程序配置文件等文件不会损坏或更改以允许未经授权的访问或恶意行为的方法。这可以通过实用程序(如 Samhain)来完成,该实用程序将创建指定资源的校验和哈希,然后定期验证该哈希,或者通过 DMVerity 等工具来完成,该工具可以获取块设备的哈希值,并在系统访问这些哈希值时对其进行验证,然后再将其呈现给用户。 + +这些应该放在适当的位置,以监控和报告对系统、虚拟机管理程序和应用程序配置文件(如 和 `/etc/keystone/keystone.conf` )以及内核模块(如 `/etc/pam.d/system-auth` virtio)的更改。最佳做法是使用 lsmod 命令来显示系统上定期加载的内容,以帮助确定 FIM 检查中应包含或不应包含的内容。 + +### 管理界面 + +管理员需要对云执行命令和控制,以实现各种操作功能。理解和保护这些指挥和控制设施非常重要。 + +OpenStack 为运维人员和租户提供了多种管理界面: + +- OpenStack 仪表板 (horizon) +- OpenStack 接口 +- 安全外壳 (SSH) +- OpenStack 管理实用程序,例如 nova-manage 和 glance-manage +- 带外管理接口,如 IPMI + +#### 仪表板 + +OpenStack 仪表板 (horizon) 为管理员和租户提供了一个基于 Web 的图形界面,用于置备和访问基于云的资源。仪表板通过调用 OpenStack API 与后端服务进行通信。 + +##### 功能 + +- 作为云管理员,仪表板提供云大小和状态的整体视图。您可以创建用户和租户/项目,将用户分配给租户/项目,并对可供他们使用的资源设置限制。 +- 仪表板为租户用户提供了一个自助服务门户,用于在管理员设置的限制范围内预配自己的资源。 +- 仪表板为路由器和负载平衡器提供 GUI 支持。例如,仪表板现在实现了所有主要的网络功能。 +- 它是一个可扩展的 Django Web 应用程序,允许轻松插入第三方产品和服务,例如计费、监控和其他管理工具。 +- 仪表板还可以为服务提供商和其他商业供应商打造品牌。 + +##### 安全注意事项 + +- 仪表板要求在 Web 浏览器中启用 Cookie 和 JavaScript。 +- 托管仪表板的 Web 服务器应配置为使用 TLS,以确保数据已加密。 +- Horizon Web Service 及其用于与后端通信的 OpenStack API 都容易受到 Web 攻击媒介(如拒绝服务)的攻击,因此必须对其进行监控。 +- 现在可以通过仪表板将镜像文件直接从用户的硬盘上传到 OpenStack 镜像服务(尽管存在许多部署/安全隐患)。对于多 GB 的映像,仍强烈建议使用 `glance` CLI 进行上传。 +- 通过仪表盘创建和管理安全组。安全组允许对安全策略进行 L3-L4 数据包筛选,以保护虚拟机。 + +##### 参考书目 + +OpenStack.org,ReleaseNotes/Liberty。2015. OpenStack Liberty 发行说明 + +#### OpenStack 接口 + +OpenStack API 是一个 RESTful Web 服务端点,用于访问、配置和自动化基于云的资源。操作员和用户通常通过命令行实用程序(例如, `nova` 或)、特定于语言的库或 `glance` 第三方工具访问 API。 + +##### 功能 + +- To the cloud administrator, the API provides an overall view of the size and state of the cloud deployment and allows the creation of users, tenants/projects, assigning users to tenants/projects, and specifying resource quotas on a per tenant/project basis. + 对于云管理员来说,API 提供了云部署大小和状态的整体视图,并允许创建用户、租户/项目、将用户分配给租户/项目,以及为每个租户/项目指定资源配额。 +- The API provides a tenant interface for provisioning, managing, and accessing their resources. + API 提供了一个租户接口,用于预配、管理和访问其资源。 + +##### 安全注意事项 + +- 应为 TLS 配置 API 服务,以确保数据已加密。 +- 作为 Web 服务,OpenStack API 容易受到熟悉的网站攻击媒介的影响,例如拒绝服务攻击。 + +#### 安全外壳 (SSH) + +使用安全外壳 (SSH) 访问来管理 Linux 和 Unix 系统已成为行业惯例。SSH 使用安全的加密原语进行通信。鉴于 SSH 在典型 OpenStack 部署中的范围和重要性,了解部署 SSH 的最佳实践非常重要。 + +##### 主机密钥指纹 + +经常被忽视的是 SSH 主机的密钥管理需求。由于 OpenStack 部署中的大多数或所有主机都将提供 SSH 服务,因此对与这些主机的连接充满信心非常重要。不能低估的是,未能提供合理安全且可访问的方法来验证 SSH 主机密钥指纹是滥用和利用的成熟时机。 + +所有 SSH 守护程序都具有专用主机密钥,并在连接时提供主机密钥指纹。此主机密钥指纹是未签名公钥的哈希值。在与这些主机建立 SSH 连接之前,必须知道这些主机密钥指纹。验证主机密钥指纹有助于检测中间人攻击。 + +通常,在安装 SSH 守护程序时,将生成主机密钥。在主机密钥生成过程中,主机必须具有足够的熵。主机密钥生成期间的熵不足可能导致窃听 SSH 会话。 + +生成 SSH 主机密钥后,主机密钥指纹应存储在安全且可查询的位置。一个特别方便的解决方案是使用 RFC-4255 中定义的 SSHFP 资源记录的 DNS。为了安全起见,有必要部署 DNSSEC。 + +#### 管理实用程序 + +OpenStack Management Utilities 是进行 API 调用的开源 Python 命令行客户端。每个 OpenStack 服务都有一个客户端(例如,nova、glance)。除了标准的 CLI 客户端之外,大多数服务都具有管理命令行实用程序,用于直接调用数据库。这些专用管理实用程序正在慢慢被弃用。 + +##### 安全注意事项 + +- 在某些情况下,专用管理实用程序 (*-manage) 使用直接数据库连接。 +- 确保包含凭据信息的 .rc 文件是安全的。 + +##### 参考书目 + +OpenStack.org,“OpenStack 最终用户指南”部分。2016. OpenStack 命令行客户端概述。 + +OpenStack.org,使用 OpenStack RC 文件设置环境变量。2016. 下载并获取 OpenStack RC 文件。 + +#### 带外管理接口 + +OpenStack 管理依赖于带外管理接口(如 IPMI 协议)来访问运行 OpenStack 组件的节点。IPMI 是一种非常流行的规范,用于远程管理、诊断和重新启动服务器,无论操作系统正在运行还是系统崩溃。 + +##### 安全注意事项 + +- 使用强密码并保护它们,或使用客户端 TLS 身份验证。 +- 确保网络接口位于其自己的专用(管理或单独的)网络上。使用防火墙或其他网络设备隔离管理域。 +- 如果您使用 Web 界面与 BMC/IPMI 交互,请始终使用 TLS 接口,例如 HTTPS 或端口 443。此 TLS 接口不应使用自签名证书(通常是默认的),但应具有使用正确定义的完全限定域名 (FQDN) 的受信任证书。 +- 监控管理网络上的流量。与繁忙的计算节点相比,异常可能更容易跟踪。 + +带外管理界面通常还包括图形计算机控制台访问。这些接口通常可以加密,但不一定是默认的。请参阅系统软件文档以加密这些接口。 + +##### 参考书目 + +SANS 技术研究所,InfoSec Handlers 日记博客。2012. 黑客攻击已关闭的服务器。 + +## 安全通信 + +设备间通信是一个严重的安全问题。在大型项目错误(如 Heartbleed)或更高级的攻击(如 BEAST 和 CRIME)之间,通过网络进行安全通信的方法变得越来越重要。但是,应该记住,加密应该作为更大的安全策略的一部分来应用。端点的入侵意味着攻击者不再需要破坏所使用的加密,而是能够在系统处理消息时查看和操纵消息。 + +本章将回顾有关配置 TLS 以保护内部和外部资源的几个功能,并指出应特别注意的特定类别的系统。 + +- TLS 和 SSL 简介 + + - 证书颁发机构 + - TLS 库 + - 加密算法、密码模式和协议 + - 总结 + +- TLS 代理和 HTTP 服务 + + - 例子 + - HTTP 严格传输安全性 + - 完美前向保密 + +- 安全参考架构 + + - SSL/TLS 代理在前面 + - SSL/TLS 与 API 端点位于同一物理主机上 + - 负载均衡器上的 SSL/TLS + - 外部和内部环境的加密分离 + +### TLS 和 SSL 简介 + +在某些情况下,需要安全来确保 OpenStack 部署中网络流量的机密性或完整性。这通常是使用加密措施实现的,例如传输层安全性 (TLS) 协议。 + +在典型部署中,通过公共网络传输的所有流量都是安全的,但安全最佳实践要求内部流量也必须得到保护。仅仅依靠安全域分离进行保护是不够的。如果攻击者获得对虚拟机监控程序或主机资源的访问权限,破坏 API 端点或任何其他服务,则他们一定无法轻松注入或捕获消息、命令或以其他方式影响云的管理功能。 + +所有域都应使用 TLS 进行保护,包括管理域服务和服务内通信。TLS 提供了确保用户与 OpenStack 服务之间以及 OpenStack 服务本身之间通信的身份验证、不可否认性、机密性和完整性的机制。 + +由于安全套接字层 (SSL) 协议中已发布的漏洞,我们强烈建议优先使用 TLS 而不是 SSL,并且在任何情况下都禁用 SSL,除非需要与过时的浏览器或库兼容。 + +公钥基础设施 (PKI) 是用于保护网络通信的框架。它由一组系统和流程组成,以确保在验证各方身份的同时可以安全地发送流量。此处描述的 PKI 配置文件是由 PKIX 工作组开发的 Internet 工程任务组 (IETF) 公钥基础结构 (PKIX) 配置文件。PKI的核心组件包括: + +**数字证书** + +签名公钥证书是具有实体的可验证数据、其公钥以及其他一些属性的数据结构。这些证书由证书颁发机构 (CA) 颁发。由于证书由受信任的 CA 签名,因此一旦验证,与实体关联的公钥将保证与所述实体相关联。用于定义这些证书的最常见标准是 X.509 标准。X.509 v3 是当前的标准,在 RFC5280 中进行了详细描述。证书由 CA 颁发,作为证明在线实体身份的机制。CA 通过从证书创建消息摘要并使用其私钥对摘要进行加密,对证书进行数字签名。 + + **结束实体** + +作为证书主题的用户、进程或系统。最终实体将其证书请求发送到注册机构 (RA) 进行审批。如果获得批准,RA 会将请求转发给证书颁发机构 (CA)。证书颁发机构验证请求,如果信息正确,则生成证书并签名。然后,此签名证书将发送到证书存储库。 + +**信赖方** + +接收数字签名证书的终结点,该证书可参考证书上列出的公钥进行验证。信赖方应能够验证证书的链上,确保它不存在于 CRL 中,并且还必须能够验证证书的到期日期。 + +**证书颁发机构 (CA)** + +CA 是受信任的实体,无论是最终方还是依赖证书进行证书策略、管理处理和证书颁发的一方。 + +**注册机构 (RA)** + +CA 将某些管理功能委派给的可选系统,这包括在 CA 颁发证书之前对终端实体进行身份验证等功能。 + +**证书吊销列表 (CRL)** + +证书吊销列表 (CRL) 是已吊销的证书序列号列表。在 PKI 模型中,不应信任提供这些证书的最终实体。吊销可能由于多种原因而发生,例如密钥泄露、CA 泄露。 + +**CRL 发行人** + +CA 将证书吊销列表的发布委托给的可选系统。 + +**证书存储库** + +存储和查找最终实体证书和证书吊销列表的位置 - 有时称为证书捆绑包。 + +PKI 构建了一个框架,用于提供加密算法、密码模式和协议,以保护数据和身份验证。强烈建议使用公钥基础结构 (PKI) 保护所有服务,包括对 API 终结点使用 TLS。仅靠传输或消息的加密或签名是不可能解决所有这些问题的。主机本身必须是安全的,并实施策略、命名空间和其他控制措施来保护其私有凭据和密钥。但是,密钥管理和保护的挑战并没有减少这些控制的必要性,也没有降低它们的重要性。 + +#### 证书颁发机构 + +许多组织都建立了公钥基础设施,其中包含自己的证书颁发机构 (CA)、证书策略和管理,他们应该使用这些证书为内部 OpenStack 用户或服务颁发证书。公共安全域面向 Internet 的组织还需要由广泛认可的公共 CA 签名的证书。对于通过管理网络进行的加密通信,建议不要使用公共 CA。相反,我们期望并建议大多数部署部署自己的内部 CA。 + +建议 OpenStack 云架构师考虑对内部系统和面向客户的服务使用单独的 PKI 部署。这使云部署人员能够保持对其 PKI 基础设施的控制,并且使内部系统的证书请求、签名和部署变得更加容易。高级配置可以对不同的安全域使用单独的 PKI 部署。这允许部署人员保持环境的加密隔离,确保颁发给一个环境的证书不被另一个环境识别。 + +用于在面向 Internet 的云端点(或客户接口,其中客户预计不会安装除标准操作系统提供的证书捆绑包以外的任何内容)上支持 TLS 的证书应使用安装在操作系统证书捆绑包中的证书颁发机构进行预配。典型的知名供应商包括 Let's Encrypt、Verisign 和 Thawte,但还有许多其他供应商。 + +在创建和签署证书方面存在管理、策略和技术方面的挑战。在这个领域,云架构师或操作员可能希望寻求行业领导者和供应商的建议,以及此处推荐的指导。 + +#### TLS 库 + +OpenStack 生态系统中的组件、服务和应用程序或 OpenStack 的依赖项已实现或可以配置为使用 TLS 库。OpenStack 中的 TLS 和 HTTP 服务通常使用 OpenSSL 实现,OpenSSL 具有已针对 FIPS 140-2 验证的模块。但是,请记住,每个应用程序或服务在使用 OpenSSL 库的方式上仍可能引入弱点。 + +#### 加密算法、密码模式和协议 + +建议至少使用 TLS 1.2。旧版本(如 TLS 1.0、1.1 和所有版本的 SSL(TLS 的前身)容易受到多种公开已知的攻击,因此不得使用。TLS 1.2 可用于广泛的客户端兼容性,但在启用此协议时要小心。仅当存在强制性兼容性要求并且您了解所涉及的风险时,才启用 TLS 版本 1.1。 + +使用 TLS 1.2 并同时控制客户端和服务器时,密码套件应限制为 `ECDHE-ECDSA-AES256-GCM-SHA384` .在不控制这两个终结点并使用 TLS 1.1 或 1.2 的情况下,更通用 `HIGH:!aNULL:!eNULL:!DES:!3DES:!SSLv3:!TLSv1:!CAMELLIA` 的是合理的密码选择。 + +但是,由于本书并不打算全面介绍密码学,因此我们不希望规定在OpenStack服务中应该启用或禁用哪些特定的算法或密码模式。我们想推荐一些权威的参考资料,以提供更多信息: + +- 国家安全局,Suite B 密码学 +- OWASP密码学指南 +- OWASP 传输层保护备忘单 +- SoK:SSL 和 HTTPS:重温过去的挑战并评估证书信任模型增强功能 +- 世界上最危险的代码:在非浏览器软件中验证SSL证书 +- OpenSSL 和 FIPS 140-2 + +#### 总结 + +鉴于 OpenStack 组件的复杂性和部署可能性的数量,您必须注意确保每个组件都获得 TLS 证书、密钥和 CA 的适当配置。后续部分将讨论以下服务: + +- 计算 API 端点 +- 身份 API 端点 +- 网络 API 端点 +- 存储 API 端点 +- 消息服务器 +- 数据库服务器 +- 仪表板 + +### TLS 代理和 HTTP 服务 + +OpenStack的终端是提供API给公共网络上的终端用户和管理网络上的其他OpenStack服务的HTTP服务。强烈建议所有这些请求,无论是内部还是外部,都使用TLS进行操作。为了实现这个目标,API服务必须部署在TLS代理后面,该代理能够建立和终止TLS会话。下表提供了可用于此目的的开源软件的非详尽列表: + +- Pound + +- Stud + +- Nginx + +- Apache httpd + +在软件终端性能不足的情况下,硬件加速器可能值得探索作为替代选项。请务必注意任何选定的 TLS 代理将处理的请求的大小。 + +#### 示例 + +下面我们提供了一些更流行的 Web 服务器/TLS 终结器中启用 TLS 的推荐配置设置示例。 + +在深入研究配置之前,我们简要讨论密码的配置元素及其格式。有关可用密码和 OpenSSL 密码列表格式的更详尽处理,请参阅:密码。 + +```shell +ciphers = "HIGH:!RC4:!MD5:!aNULL:!eNULL:!EXP:!LOW:!MEDIUM" +``` + +或 + +```shell +ciphers = "kEECDH:kEDH:kRSA:HIGH:!RC4:!MD5:!aNULL:!eNULL:!EXP:!LOW:!MEDIUM" +``` + +密码字符串选项由 “:” 分隔,而 “!” 提供紧接着的元素的否定。元素顺序指示首选项,除非被限定符(如 HIGH)覆盖。让我们仔细看看上面示例字符串中的元素。 + +**kEECDH:kEDH** + +临时椭圆曲线 Diffie-Hellman(缩写为 EECDH 和 ECDHE)。 + +Ephemeral Diffie-Hellman(缩写为 EDH 或 DHE)使用素数场群。 + +这两种方法都提供完全前向保密 (PFS)。有关正确配置 PFS 的更多讨论,请参阅完全前向保密。 + +临时椭圆曲线要求服务器配置命名曲线,并提供比主字段组更好的安全性和更低的计算成本。但是,主要字段组的实现范围更广,因此通常两者都包含在列表中。 + +**kRSA** + +分别使用 RSA 交换、身份验证或两者之一的密码套件。 + +**HIGH** + +在协商阶段选择可能的最高安全密码。这些密钥通常具有长度为 128 位或更长的密钥。 + +**!RC4** + +没有 RC4。RC4 在 TLS V3 的上下文中存在缺陷。请参阅 TLS 和 WPA 中 RC4 的安全性。 + +**!MD5** + +没有 MD5。MD5 不具有防冲突功能,因此不接受消息验证码 (MAC) 或签名。 + +**!aNULL:!eNULL** + +Disallows clear text. 不允许明文。 + +**!EXP** + +不允许导出加密算法,这些算法在设计上往往很弱,通常使用 40 位和 56 位密钥。 + +美国对密码学系统的出口限制已被取消,不再需要支持。 + +**!LOW:!MEDIUM** + +不允许使用低(56 或 64 位长密钥)和中等(128 位长密钥)密码,因为它们容易受到暴力攻击(示例 2-DES)。此规则仍允许三重数据加密标准 (Triple DES),也称为三重数据加密算法 (TDEA) 和高级加密标准 (AES),每个标准都具有大于等于 128 位的密钥,因此更安全。 + +**Protocols** + +协议通过SSL_CTX_set_options启用/禁用。建议禁用 SSLv2/v3 并启用 TLS。 + +##### Pound + +此 Pound 示例启用 `AES-NI` 加速,这有助于提高具有支持此功能的处理器的系统的性能。默认配置文件位于 `/etc/pound/pound.cfg` Ubuntu、RHEL、CentOS、 `/etc/pound.cfg` openSUSE 和 SUSE Linux Enterprise 上。 + +```shell +## see pound(8) for details +daemon 1 +###################################################################### +## global options: +User "swift" +Group "swift" +#RootJail "/chroot/pound" +## Logging: (goes to syslog by default) +## 0 no logging +## 1 normal +## 2 extended +## 3 Apache-style (common log format) +LogLevel 0 +## turn on dynamic scaling (off by default) +# Dyn Scale 1 +## check backend every X secs: +Alive 30 +## client timeout +#Client 10 +## allow 10 second proxy connect time +ConnTO 10 +## use hardware-acceleration card supported by openssl(1): +SSLEngine "aesni" +# poundctl control socket +Control "/var/run/pound/poundctl.socket" +###################################################################### +## listen, redirect and ... to: +## redirect all swift requests on port 443 to local swift proxy +ListenHTTPS + Address 0.0.0.0 + Port 443 + Cert "/etc/pound/cert.pem" + ## Certs to accept from clients + ## CAlist "CA_file" + ## Certs to use for client verification + ## VerifyList "Verify_file" + ## Request client cert - don't verify + ## Ciphers "AES256-SHA" + ## allow PUT and DELETE also (by default only GET, POST and HEAD)?: + NoHTTPS11 0 + ## allow PUT and DELETE also (by default only GET, POST and HEAD)?: + xHTTP 1 + Service + BackEnd + Address 127.0.0.1 + Port 80 + End + End +End +``` + +##### Stud + +密码行可以根据您的需要进行调整,但这是一个合理的起点。默认配置文件位于目录中 `/etc/stud` 。但是,默认情况下不提供它。 + +```shell +# SSL x509 certificate file. +pem-file = " +# SSL protocol. +tls = on +ssl = off +# List of allowed SSL ciphers. +# OpenSSL's high-strength ciphers which require authentication +# NOTE: forbids clear text, use of RC4 or MD5 or LOW and MEDIUM strength ciphers +ciphers = "HIGH:!RC4:!MD5:!aNULL:!eNULL:!EXP:!LOW:!MEDIUM" +# Enforce server cipher list order +prefer-server-ciphers = on +# Number of worker processes +workers = 4 +# Listen backlog size +backlog = 1000 +# TCP socket keepalive interval in seconds +keepalive = 3600 +# Chroot directory +chroot = "" +# Set uid after binding a socket +user = "www-data" +# Set gid after binding a socket +group = "www-data" +# Quiet execution, report only error messages +quiet = off +# Use syslog for logging +syslog = on +# Syslog facility to use +syslog-facility = "daemon" +# Run as daemon +daemon = off +# Report client address using SENDPROXY protocol for haproxy +# Disabling this until we upgrade to HAProxy 1.5 +write-proxy = off +``` + +##### Nginx + +此 Nginx 示例需要 TLS v1.1 或 v1.2 才能获得最大的安全性。可以根据您的需要调整生产线 `ssl_ciphers` ,但这是一个合理的起点。缺省配置文件为 `/etc/nginx/nginx.conf` 。 + +```shell +server { + listen : ssl; + ssl_certificate ; + ssl_certificate_key ; + ssl_protocols TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!RC4:!MD5:!aNULL:!eNULL:!EXP:!LOW:!MEDIUM + ssl_session_tickets off; + + server_name _; + keepalive_timeout 5; + + location / { + + } +} +``` + +##### Apache + +默认配置文件位于 `/etc/apache2/apache2.conf` Ubuntu、RHEL 和 CentOS、 `/etc/httpd/conf/httpd.conf` `/etc/apache2/httpd.conf` openSUSE 和 SUSE Linux Enterprise 上。 + +```shell +:80> + ServerName + RedirectPermanent / https:/// + +:443> + ServerName + SSLEngine On + SSLProtocol +TLSv1 +TLSv1.1 +TLSv1.2 + SSLCipherSuite HIGH:!RC4:!MD5:!aNULL:!eNULL:!EXP:!LOW:!MEDIUM + SSLCertificateFile /path/.crt + SSLCACertificateFile /path/.crt + SSLCertificateKeyFile /path/.key + WSGIScriptAlias / + WSGIDaemonProcess horizon user= group= processes=3 threads=10 + Alias /static + > + # For http server 2.2 and earlier: + Order allow,deny + Allow from all + + # Or, in Apache http server 2.4 and later: + # Require all granted + + +``` + +Apache 中的计算 API SSL 端点,必须与简短的 WSGI 脚本配对。 + +```shell +:8447> + ServerName + SSLEngine On + SSLProtocol +TLSv1 +TLSv1.1 +TLSv1.2 + SSLCipherSuite HIGH:!RC4:!MD5:!aNULL:!eNULL:!EXP:!LOW:!MEDIUM + SSLCertificateFile /path/.crt + SSLCACertificateFile /path/.crt + SSLCertificateKeyFile /path/.key + SSLSessionTickets Off + WSGIScriptAlias / + WSGIDaemonProcess osapi user= group= processes=3 threads=10 + > + # For http server 2.2 and earlier: + Order allow,deny + Allow from all + + # Or, in Apache http server 2.4 and later: + # Require all granted + + +``` + +#### HTTP 严格传输安全 + +建议所有生产部署都使用 HTTP 严格传输安全性 (HSTS)。此标头可防止浏览器在建立单个安全连接后建立不安全的连接。如果您已将 HTTP 服务部署在公共域或不受信任的域上,则 HSTS 尤为重要。要启用 HSTS,请将 Web 服务器配置为发送包含所有请求的标头,如下所示: + +```shell +Strict-Transport-Security: max-age=31536000; includeSubDomains +``` + +在测试期间从 1 天的短暂停开始,并在测试表明您没有给用户带来问题后将其提高到一年。请注意,一旦此标头设置为较大的超时,它(根据设计)就很难禁用。 + +#### 完全前向保密 + +配置 TLS 服务器以实现完美的前向保密需要围绕密钥大小、会话 ID 和会话票证进行仔细规划。此外,对于多服务器部署,共享状态也是一个重要的考虑因素。上面的 Apache 和 Nginx 示例配置禁用了会话票证选项,以帮助缓解其中一些问题。实际部署可能希望启用此功能以提高性能。这可以安全地完成,但需要特别考虑密钥管理。此类配置超出了本指南的范围。我们建议阅读 ImperialViolet 的 How to botch TLS forward secrecy 作为理解问题空间的起点。 + +### 安全参考架构 + +建议在 TLS 代理和 HTTP 服务的公用网络和管理网络上使用 SSL/TLS。但是,如果实际在任何地方部署 SSL/TLS 太困难,我们建议您评估您的 OpenStack SSL/TLS 需求,并遵循此处讨论的架构之一。 + +在评估其 OpenStack SSL/TLS 需求时,应该做的第一件事是识别威胁。您可以将这些威胁分为外部攻击者和内部攻击者类别,但由于 OpenStack 的某些组件在公共和管理网络上运行,因此界限往往会变得模糊。 + +对于面向公众的服务,威胁非常简单。用户将使用其用户名和密码对 Horizon 和 Keystone 进行身份验证。用户还将使用其 keystone 令牌访问其他服务的 API 端点。如果此网络流量未加密,则攻击者可以使用中间人攻击截获密码和令牌。然后,攻击者可以使用这些有效凭据执行恶意操作。所有实际部署都应使用 SSL/TLS 来保护面向公众的服务。 + +对于部署在管理网络上的服务,由于安全域与网络安全的桥接,威胁并不那么明确。有权访问管理网络的管理员总是有可能决定执行恶意操作。在这种情况下,如果允许攻击者访问私钥,SSL/TLS 将无济于事。当然,并不是管理网络上的每个人都被允许访问私钥,因此使用 SSL/TLS 来保护自己免受内部攻击者的攻击仍然很有价值。即使允许访问您的管理网络的每个人都是 100% 受信任的,仍然存在未经授权的用户通过利用错误配置或软件漏洞访问您的内部网络的威胁。必须记住,用户在 OpenStack Compute 节点中的实例上运行自己的代码,这些节点部署在管理网络上。如果漏洞允许他们突破虚拟机管理程序,他们将可以访问您的管理网络。在管理网络上使用 SSL/TLS 可以最大程度地减少攻击者可能造成的损害。 + +#### SSL/TLS 代理在前面 + +人们普遍认为,最好尽早加密敏感数据,并尽可能晚地解密。尽管有这种最佳实践,但在OpenStack服务前面使用SSL / TLS代理并在之后使用清晰的通信似乎是很常见的,如下所示: + +![../_images/secure-arch-ref-1.png](https://docs.openstack.org/security-guide/_images/secure-arch-ref-1.png) + +如上图所示,使用 SSL/TLS 代理的一些问题: + +- OpenStack 服务中的原生 SSL/TLS 的性能/扩展性不如 SSL 代理(特别是对于像 Eventlet 这样的 Python 实现)。 +- OpenStack 服务中的原生 SSL/TLS 没有像更成熟的解决方案那样经过仔细审查/审计。 +- 本机 SSL/TLS 配置很困难(没有很好的文档记录、测试或跨服务保持一致)。 +- 权限分离(OpenStack 服务进程不应直接访问用于 SSL/TLS 的私钥)。 +- 流量检查需要负载均衡。 + +以上所有问题都是有道理的,但它们都不能阻止在管理网络上使用 SSL/TLS。让我们考虑下一个部署模型。 + +#### 与 API 端点位于同一物理主机上的 SSL/TLS + +![../_images/secure-arch-ref-2.png](https://docs.openstack.org/security-guide/_images/secure-arch-ref-2.png) + +这与前面的 SSL/TLS 代理非常相似,但 SSL/TLS 代理与 API 端点位于同一物理系统上。API 端点将配置为仅侦听本地网络接口。与 API 端点的所有远程通信都将通过 SSL/TLS 代理进行。通过此部署模型,我们将解决 SSL/TLS 代理中的许多要点:将使用性能良好的经过验证的 SSL 实现。所有服务都将使用相同的 SSL 代理软件,因此 API 端点的 SSL 配置将是一致的。OpenStack 服务进程将无法直接访问用于 SSL/TLS 的私钥,因为您将以不同的用户身份运行 SSL 代理,并使用权限限制访问(以及使用 SELinux 之类的额外强制访问控制)。理想情况下,我们会让 API 端点在 Unix 套接字上监听,这样我们就可以使用权限和强制访问控制来限制对它的访问。不幸的是,根据我们的测试,这在 Eventlet 中目前似乎不起作用。这是一个很好的未来发展目标。 + +#### SSL/TLS负载平衡器 + +需要检查流量的高可用性或负载均衡部署会怎样?以前的部署模型(与 API 端点位于同一物理主机上的 SSL/TLS)不允许进行深度数据包检测,因为流量是加密的。如果仅出于基本路由目的而需要检查流量,则负载均衡器可能没有必要访问未加密的流量。HAProxy 能够在握手期间提取 SSL/TLS 会话 ID,然后可以使用该 ID 来实现会话亲和性(会话 ID 配置详细信息 此处 )。HAProxy还可以使用TLS服务器名称指示(SNI)扩展来确定应将流量路由到的位置(SNI配置详细信息请在此处)。这些功能可能涵盖了一些最常见的负载均衡器需求。在这种情况下,HAProxy 将能够将 HTTPS 流量直接传递到 API 端点系统: + +![../_images/secure-arch-ref-3.png](https://docs.openstack.org/security-guide/_images/secure-arch-ref-3.png) + +#### 外部和内部环境的加密分离 + +如果您希望对外部和内部环境进行加密分离,该怎么办?公有云提供商可能希望其面向公众的服务(或代理)使用由 CA 颁发的证书,该证书链接到受信任的根 CA,该根 CA 分布在流行的 SSL/TLS Web 浏览器软件中。对于内部服务,可能希望改用自己的 PKI 来颁发 SSL/TLS 证书。可以通过在网络边界终止 SSL,然后使用内部颁发的证书重新加密来实现这种加密分离。流量将在面向公众的 SSL/TLS 代理上短时间内未加密,但永远不会以明文形式通过网络传输。如果负载均衡器上确实需要深度数据包检测,也可以使用用于实现加密分离的相同重新加密方法。下面是此部署模型的样子:下面是此部署模型的外观: + +![../_images/secure-arch-ref-4.png](https://docs.openstack.org/security-guide/_images/secure-arch-ref-4.png) + +与大多数事情一样,需要权衡取舍。主要的权衡是在安全性和性能之间。加密是有代价的,但被黑客入侵也是有代价的。每个部署的安全性和性能要求都会有所不同,因此如何使用 SSL/TLS 最终将由个人决定。 + +## API 端点 + +使用 OpenStack 云的过程是通过查询 API 端点开始的。虽然公共和专用终结点面临不同的挑战,但这些是高价值资产,如果遭到入侵,可能会带来重大风险。 + +本章建议对面向公共和私有的 API 端点进行安全增强。 + +- API 端点配置建议 + + - 内部 API 通信 + - 粘贴件和中间件 + - API 端点进程隔离和策略 + - API 终端节点速率限制 + +### API 端点配置建议 + +#### 内部 API 通信 + +OpenStack 提供面向公众和私有的 API 端点。默认情况下,OpenStack 组件使用公开定义的端点。建议将这些组件配置为在适当的安全域中使用 API 端点。 + +服务根据 OpenStack 服务目录选择各自的 API 端点。这些服务可能不遵守列出的公共或内部 API 端点值。这可能会导致内部管理流量路由到外部 API 终结点。 + +##### 在身份服务目录中配置内部 URL + +Identity 服务目录应了解您的内部 URL。虽然默认情况下不使用此功能,但可以通过配置来利用它。此外,一旦此行为成为默认行为,它应该与预期的更改向前兼容。 + +要为终结点注册内部 URL,请执行以下操作: + +```shell +$ openstack endpoint create identity \ + --region RegionOne internal \ + https://MANAGEMENT_IP:5000/v3 +``` + +替换为 `MANAGEMENT_IP` 控制器节点的管理 IP 地址。 + +##### 为内部 URL 配置应用程序 + +您可以强制某些服务使用特定的 API 端点。因此,建议必须将每个与另一个服务的 API 通信的 OpenStack 服务显式配置为访问正确的内部 API 端点。 + +每个项目都可能呈现定义目标 API 端点的不一致方式。OpenStack 的未来版本试图通过一致地使用身份服务目录来解决这些不一致问题。 + +**配置示例 #1:nova** + +```shell +cinder_catalog_info='volume:cinder:internalURL' +glance_protocol='https' +neutron_url='https://neutron-host:9696' +neutron_admin_auth_url='https://neutron-host:9696' +s3_host='s3-host' +s3_use_ssl=True +``` + +**配置示例 #2:cinder** + +```shell +glance_host = 'https://glance-server' +``` + +#### 粘贴和中间件 + +OpenStack 中的大多数 API 端点和其他 HTTP 服务都使用 Python Paste Deploy 库。从安全角度来看,此库允许通过应用程序的配置来操作请求筛选器管道。此链中的每个元素都称为中间件。更改管道中筛选器的顺序或添加其他中间件可能会产生不可预知的安全影响。 + +通常,实现者会添加中间件来扩展 OpenStack 的基本功能。我们建议实现者仔细考虑将非标准软件组件添加到其 HTTP 请求管道中可能带来的风险。 + +有关粘贴部署的更多信息,请参阅 Python 粘贴部署文档。 + +#### API 端点进程隔离和策略 + +您应该隔离 API 端点进程,尤其是那些位于公共安全域中的进程,应尽可能隔离。在部署允许的情况下,API 端点应部署在单独的主机上,以增强隔离性。 + +##### 命名空间 + +现在,许多操作系统都提供分区化支持。Linux 支持命名空间将进程分配到独立的域中。本指南的其他部分更详细地介绍了系统区隔。 + +##### 网络策略 + +由于 API 端点通常桥接多个安全域,因此您必须特别注意 API 进程的划分。有关此区域的其他信息,请参阅桥接安全域。 + +通过仔细建模,您可以使用网络 ACL 和 IDS 技术在网络服务之间强制实施显式点对点通信。作为一项关键的跨域服务,这种显式强制执行对 OpenStack 的消息队列服务非常有效。 + +要实施策略,您可以配置服务、基于主机的防火墙(例如 iptables)、本地策略(SELinux 或 AppArmor)以及可选的全局网络策略。 + +##### 强制访问控制 + +您应该将 API 端点进程彼此隔离,并隔离计算机上的其他进程。这些进程的配置不仅应通过任意访问控制,还应通过强制访问控制来限制这些进程。这些增强的访问控制的目标是帮助遏制和升级 API 端点安全漏洞。通过强制访问控制,此类违规行为会严重限制对资源的访问,并针对此类事件提供早期警报。 + +#### API 端点速率限制 + +速率限制是一种控制基于网络的应用程序接收事件频率的方法。如果不存在可靠的速率限制,则可能导致应用程序容易受到各种拒绝服务攻击。对于 API 尤其如此,因为 API 的本质是旨在接受高频率的类似请求类型和操作。 + +在 OpenStack 中,建议通过速率限制代理或 Web 应用程序防火墙为所有端点(尤其是公共端点)提供额外的保护层。 + +在配置和实现任何速率限制功能时,运营商必须仔细规划并考虑其 OpenStack 云中用户和服务的个人性能需求,这一点至关重要。 + +提供速率限制的常见解决方案是 Nginx、HAProxy、OpenPose 或 Apache 模块,例如 mod_ratelimit、mod_qos 或 mod_security。 + +## 身份鉴别 + +Keystone身份服务为OpenStack系列服务专门提供身份、令牌、目录和策略服务。身份服务组织为一组内部服务,通过一个或多个端点暴露。这些服务中的许多是由前端以组合方式使用的。例如,身份验证调用通过身份服务验证用户和项目凭据。如果成功,它将使用令牌服务创建并返回令牌。更多信息可以在Keystone开发者文档中找到。 + +- 认证 + + - 无效的登录尝试 + - 多因素认证 + +- 认证方法 + + - 内部实施的认证方法 + - 外部认证方法 + +- 授权 + + - 建立正式的访问控制策略 + - 服务授权 + - 管理原用户 + - 终端用户 + +- 策略 +- 令牌 + + - Fernet 令牌 + - JWT 令牌 + +- 域 +- 联合 Keystone + + - 为什么要使用联合鉴别 + +- 检查表 + + - Check-Identity-01:配置文件的用户/组所有权是否设置为 keystone? + - Check-Identity-02:是否为身份配置文件设置了严格权限 + - Check-Identity-03:是否为 Identity 启用了 TLS? + - Check-Identity-04:(已过时) + - Check-Identity-05:是否 max_request_body_size 设置为默认值 (114688)? + - check-identity-06:禁用/etc/keystone/keystone.conf中的管理令牌 + - check-identity-07:/etc/keystone/keystone.conf中的不安全_调试为假 + - check-identity-08:使用/etc/keystone/keystone.conf中的Fernet令牌 + +### 认证 + +身份认证是任何实际OpenStack部署中不可或缺的一部分,因此应该仔细考虑系统设计的这一方面。本主题的完整处理超出了本指南的范围,但是以下各节介绍了一些关键主题。 + +从根本上说,身份认证是确认身份的过程 - 用户实际上是他们声称的身份。一个熟悉的示例是在登录系统时提供用户名和密码。 + +OpenStack 身份鉴别服务(keystone)支持多种身份验证方法,包括用户名和密码、LDAP 和外部身份验证方法。身份认证成功后,身份鉴别服务会向用户提供用于后续服务请求的授权令牌。 + +传输层安全性 (TLS) 使用 X.509 证书在服务和人员之间提供身份验证。尽管 TLS 的默认模式是仅服务器端身份验证,但证书也可用于客户端身份验证。 + +#### 无效的登录尝试 + +从 Newton 版本开始,身份鉴别服务可以在多次登录尝试失败后限制对帐户的访问。重复失败登录尝试的模式通常是暴力攻击的指标(请参阅攻击类型)。这种类型的攻击在公有云部署中更为普遍。 + +对于需要此功能的旧部署,可以使用外部身份验证系统进行预防,该系统在配置的登录尝试失败次数后锁定帐户。然后,只有通过进一步的侧信道干预才能解锁该帐户。 + +如果无法预防,则可以使用检测来减轻损害。检测涉及频繁查看访问控制日志,以识别未经授权的帐户访问尝试。可能的补救措施包括检查用户密码的强度,或通过防火墙规则阻止攻击的网络源。Keystone 服务器上限制连接数的防火墙规则可用于降低攻击效率,从而劝阻攻击者。 + +此外,检查帐户活动是否存在异常登录时间和可疑操作,并采取纠正措施(如禁用帐户)也很有用。通常,信用卡提供商采用这种方法进行欺诈检测和警报。 + +#### 多因素身份验证 + +采用多重身份验证对特权用户帐户进行网络访问。身份鉴别服务通过可提供此功能的 Apache Web 服务器支持外部身份验证服务。服务器还可以使用证书强制执行客户端身份验证。 + +此建议可防止暴力破解、社会工程以及可能泄露管理员密码的狙击和大规模网络钓鱼攻击。 + +### 身份验证方法 + +#### 内部实现的认证方式 + +身份认证服务可以将用户凭据存储在 SQL 数据库中,也可以使用符合 LDAP 的目录服务器。身份数据库可以与其他 OpenStack 服务使用的数据库分开,以降低存储凭据泄露的风险。 + +当您使用用户名和密码进行身份验证时,身份服务不会强制执行 NIST Special Publication 800-118(草案)中推荐的有关密码强度、过期或失败身份验证尝试的策略。希望执行更严格密码策略的组织应考虑使用身份服务的扩展或外部认证服务。 + +LDAP 简化了身份认证与组织现有目录服务和用户帐户管理流程的集成。 + +OpenStack 中的身份验证和授权策略可以委托给其他服务。一个典型的用例是寻求部署私有云的组织,并且已经在 LDAP 系统中拥有员工和用户的数据库。使用此身份验证机构,将对身份服务的请求委托给 LDAP 系统,然后 LDAP 系统将根据其策略进行授权或拒绝。身份验证成功后,身份鉴别服务会生成一个令牌,用于访问授权服务。 + +请注意,如果 LDAP 系统具有为用户定义的属性,例如 admin、finance、HR 等,则必须将这些属性映射到身份鉴别中的角色和组,以供各种 OpenStack 服务使用。该文件 `/etc/keystone/keystone.conf` 将 LDAP 属性映射到身份属性。 + +不得允许身份服务写入用于 OpenStack 部署之外的身份验证的 LDAP 服务,因为这将允许具有足够权限的 keystone 用户对 LDAP 目录进行更改。这将允许在更广泛的组织内进行权限升级,或促进对其他信息和资源的未经授权的访问。在这样的部署中,用户配置将超出 OpenStack 部署的范围。 + +**注意** + +```shell +有一个关于 keystone.conf 权限的 OpenStack 安全说明 (OSSN)。 + +有一个关于潜在 DoS 攻击的 OpenStack 安全说明 (OSSN)。 +``` + +#### 外部认证方式 + +本组织可能希望实现外部身份验证,以便与现有身份验证服务兼容,或强制实施更强的身份验证策略要求。尽管密码是最常见的身份验证形式,但它们可以通过多种方法泄露,包括击键记录和密码泄露。外部身份验证服务可以提供替代形式的身份验证,以最大程度地降低弱密码带来的风险。 + + 这些包括: + +**密码策略实施** + +要求用户密码符合长度、字符多样性、过期或登录尝试失败的最低标准。在外部身份验证方案中,这将是原始身份存储上的密码策略。 + +**多因素身份验证** + +身份验证服务要求用户根据他们拥有的内容(如一次性密码令牌或 X.509 证书)和他们知道的内容(如密码)提供信息。 + +**Kerberos** + +一种使用“票证”进行双向认证的网络协议,用于保护客户端和服务器之间的通信。Kerberos 票证授予票证可安全地为特定服务提供票证。 + +### 授权 + +身份服务支持组和角色的概念。用户属于组,而组具有角色列表。OpenStack 服务引用尝试访问该服务的用户的角色。OpenStack 策略执行器中间件会考虑与每个资源关联的策略规则,然后考虑用户的组/角色和关联,以确定是否允许访问所请求的资源。 + +策略实施中间件支持对 OpenStack 资源进行细粒度的访问控制。策略中深入讨论了策略的行为。 + +#### 建立正式的访问控制策略 + +在配置角色、组和用户之前,请记录 OpenStack 安装所需的访问控制策略。这些策略应与组织的任何法规或法律要求保持一致。将来对访问控制配置的修改应与正式策略保持一致。策略应包括创建、删除、禁用和启用帐户以及为帐户分配权限的条件和过程。定期查看策略,并确保配置符合批准的策略。 + +#### 服务授权 + +云管理员必须为每个服务定义一个具有管理员角色的用户,如《OpenStack 管理员指南》中所述。此服务帐户为服务提供对用户进行身份验证的授权。 + +可以将计算和对象存储服务配置为使用身份服务来存储身份验证信息。存储身份验证信息的其他选项包括使用“tempAuth”文件,但不应将其部署在生产环境中,因为密码以纯文本形式显示。 + +身份鉴别服务支持对 TLS 进行客户端身份验证,该身份验证可能已启用。除了用户名和密码之外,TLS 客户端身份验证还提供了额外的身份验证因素,从而提高了用户标识的可靠性。当用户名和密码可能被泄露时,它降低了未经授权访问的风险。但是,向用户颁发证书会产生额外的管理开销和成本,这在每次部署中都可能不可行。 + +**注意** + +```shell +我们建议您将客户端身份验证与 TLS 结合使用,以便对身份鉴别服务进行身份验证。 +``` + +云管理员应保护敏感的配置文件免遭未经授权的修改。这可以通过强制性访问控制框架(如 SELinux)来实现,包括 `/etc/keystone/keystone.conf` X.509 证书。 + +使用 TLS 的客户端身份验证需要向服务颁发证书。这些证书可以由外部或内部证书颁发机构签名。默认情况下,OpenStack 服务会根据受信任的 CA 检查证书签名的有效性,如果签名无效或 CA 不可信,连接将失败。云部署人员可以使用自签名证书。在这种情况下,必须禁用有效性检查,或者应将证书标记为受信任。若要禁用自签名证书的验证,请在 `/etc/nova/api.paste.ini` 文件的 `[filter:authtoken]` “部分”中进行设置 `insecure=False` 。此设置还会禁用其他组件的证书。 + +#### 管理员用户 + +我们建议管理员用户使用身份服务和支持 2 因素身份验证的外部身份验证服务(例如证书)进行身份验证。这样可以降低密码可能被泄露的风险。此建议符合 NIST 800-53 IA-2(1) 指南,即使用多重身份验证对特权帐户进行网络访问。 + +#### 终端用户 + +身份鉴别服务可以直接提供最终用户身份验证,也可以配置为使用外部身份验证方法以符合组织的安全策略和要求。 + +### 政策 + +每个 OpenStack 服务都在关联的策略文件中定义其资源的访问策略。例如,资源可以是 API 访问、附加到卷或启动实例的能力。策略规则以 JSON 格式指定,文件称为 `policy.json` .此文件的语法和格式在配置参考中进行了讨论。 + +云管理员可以修改或更新这些策略,以控制对各种资源的访问。确保对访问控制策略的任何更改都不会无意中削弱任何资源的安全性。另请注意,对 `policy.json` 文件的更改会立即生效,并且不需要重新启动服务。 + +以下示例显示了该服务如何将创建、更新和删除资源的访问权限限制为仅具有角色 `cloud_admin` 的用户,该角色已定义为 `role = admin` 和 `domain_id = admin_domain_id` 的结合,而 get 和 list 资源可供角色为 `cloud_admin` 或 `admin` 的用户使用。 + +```shell +{ + "admin_required": "role:admin", + "cloud_admin": "rule:admin_required and domain_id:admin_domain_id", + "service_role": "role:service", + "service_or_admin": "rule:admin_required or rule:service_role", + "owner" : "user_id:%(user_id)s or user_id:%(target.token.user_id)s", + "admin_or_owner": "(rule:admin_required and domain_id:%(target.token.user.domain.id)s) or rule:owner", + "admin_or_cloud_admin": "rule:admin_required or rule:cloud_admin", + "admin_and_matching_domain_id": "rule:admin_required and domain_id:%(domain_id)s", + "service_admin_or_owner": "rule:service_or_admin or rule:owner", + + "default": "rule:admin_required", + + "identity:get_service": "rule:admin_or_cloud_admin", + "identity:list_services": "rule:admin_or_cloud_admin", + "identity:create_service": "rule:cloud_admin", + "identity:update_service": "rule:cloud_admin", + "identity:delete_service": "rule:cloud_admin", + + "identity:get_endpoint": "rule:admin_or_cloud_admin", + "identity:list_endpoints": "rule:admin_or_cloud_admin", + "identity:create_endpoint": "rule:cloud_admin", + "identity:update_endpoint": "rule:cloud_admin", + "identity:delete_endpoint": "rule:cloud_admin", + +} +``` + +### 令牌 + +用户通过身份验证后,将生成一个令牌,用于授权和访问 OpenStack 环境。代币可以具有可变的生命周期;但是,expiry 的默认值为 1 小时。建议的过期值应设置为较低的值,以便内部服务有足够的时间完成任务。如果令牌在任务完成之前过期,云可能会变得无响应或停止提供服务。例如,计算服务将磁盘映像传输到虚拟机监控程序以进行本地缓存所需的时间。允许在使用有效的服务令牌时提取过期的令牌。 + +令牌通常在 Identity 服务响应的较大上下文的结构中传递。这些响应还提供了各种 OpenStack 服务的目录。列出了每个服务的名称、内部访问、管理员访问和公共访问的访问终结点。 + +可以使用标识 API 吊销令牌。 + +在 Stein 版本中,有两种受支持的令牌类型:fernet 和 JWT。 + +fernet 和 JWT 令牌都不需要持久性。Keystone 令牌数据库不再因身份验证的副作用而遭受膨胀。过期令牌的修剪会自动进行。也不再需要跨多个节点进行复制。只要每个 keystone 节点共享相同的存储库,就可以在所有节点上立即创建和验证令牌。 + +#### Fernet 令牌 + +Fernet 令牌是 Stein 支持的令牌提供程序(默认)。Fernet 是一种安全的消息传递格式,专门设计用于 API 令牌。它们是轻量级的(范围在 180 到 240 字节之间),并减少了运行云所需的运营开销。身份验证和授权元数据被整齐地捆绑到消息打包的有效负载中,然后对其进行加密并作为 fernet 令牌登录。 + +#### JWT 令牌 + +JSON Web 签名 (JWS) 令牌是在 Stein 版本中引入的。与fernet相比,JWS通过限制需要共享对称加密密钥的主机数量,为运营商提供了潜在的好处。这有助于防止可能已在部署中站稳脚跟的恶意参与者扩散到其他节点。 + +有关这些令牌提供程序之间差异的更多详细信息,请参阅此处 + +### 域 + +域是项目、用户和组的高级容器。因此,它们可用于集中管理所有基于 keystone 的身份组件。随着帐户域的引入,服务器、存储和其他资源现在可以在逻辑上分组到多个项目(以前称为租户)中,这些项目本身可以分组到类似主帐户的容器下。此外,可以在一个帐户域中管理多个用户,并为每个项目分配不同的角色。 + +Identity V3 API 支持多个域。不同域的用户可能在不同的身份验证后端中表示,甚至具有不同的属性,这些属性必须映射到一组角色和权限,这些角色和权限在策略定义中用于访问各种服务资源。 + +如果规则可以仅指定对管理员用户和属于租户的用户的访问权限,则映射可能很简单。在其他情况下,云管理员可能需要批准每个租户的映射例程。 + +特定于域的身份验证驱动程序允许使用特定于域的配置文件为多个域配置标识服务。启用驱动程序并设置特定于域的配置文件位置发生在 `keystone.conf` 文件 `[identity]` 部分中: + +```shell +[identity] +domain_specific_drivers_enabled = True +domain_config_dir = /etc/keystone/domains +``` + +任何没有特定于域的配置文件的域都将使用主 `keystone.conf` 文件中的选项。 + +### 联合鉴权 + +重要定义: + +**服务提供商 (SP)** + +向委托人或其他系统实体提供服务的系统实体,在本例中,OpenStack Identity 是服务提供者。 + +**身份提供商 (IdP)** + +目录服务(如 LDAP、RADIUS 和 Active Directory)允许用户使用用户名和密码登录,是身份提供商处身份验证令牌(例如密码)的典型来源。 + +联合鉴权是一种在 IdP 和 SP 之间建立信任的机制,在本例中,是在身份提供者和 OpenStack Cloud 提供的服务之间建立信任。它提供了一种安全的方法,可以使用现有凭据跨多个端点访问云资源,例如服务器、卷和数据库。凭证由用户的 IdP 维护。 + +#### 为什么要使用联合身份? + +两个根本原因: + +1. 降低复杂性使部署更易于保护。 +2. 它为您和您的用户节省了时间。 + +- 集中管理帐户,防止 OpenStack 基础架构内部的重复工作。 +- 减轻用户负担。单点登录允许使用单一身份验证方法来访问许多不同的服务和环境。 +- 将密码恢复过程的责任转移到 IdP。 + +进一步的理由和细节可以在 Keystone 关于联合的文档中找到。 + +### 检查表 + +#### Check-Identity-01:配置文件的用户/组所有权是否设置为 keystone? + +配置文件包含组件平稳运行所需的关键参数和信息。如果非特权用户有意或无意地修改或删除任何参数或文件本身,则会导致严重的可用性问题,从而导致对其他最终用户的拒绝服务。因此,此类关键配置文件的用户和组所有权必须设置为该组件所有者。此外,包含目录应具有相同的所有权,以确保正确拥有新文件。 + +运行以下命令: + +```shell +$ stat -L -c "%U %G" /etc/keystone/keystone.conf | egrep "keystone keystone" +$ stat -L -c "%U %G" /etc/keystone/keystone-paste.ini | egrep "keystone keystone" +$ stat -L -c "%U %G" /etc/keystone/policy.json | egrep "keystone keystone" +$ stat -L -c "%U %G" /etc/keystone/logging.conf | egrep "keystone keystone" +$ stat -L -c "%U %G" /etc/keystone/ssl/certs/signing_cert.pem | egrep "keystone keystone" +$ stat -L -c "%U %G" /etc/keystone/ssl/private/signing_key.pem | egrep "keystone keystone" +$ stat -L -c "%U %G" /etc/keystone/ssl/certs/ca.pem | egrep "keystone keystone" +$ stat -L -c "%U %G" /etc/keystone | egrep "keystone keystone" +``` + +**通过:**如果所有这些配置文件的用户和组所有权都设置为 keystone。上述命令显示 keystone keystone 的输出。 + +**失败:**如果上述命令未返回任何输出,因为用户或组所有权可能已设置为除 keystone 以外的任何用户。 + +推荐于:内部实现的身份验证方法。 + +#### Check-Identity-02:是否为 Identity 配置文件设置了严格权限? + +与前面的检查类似,建议对此类配置文件设置严格的访问权限。 + +运行以下命令: + +```shell +$ stat -L -c "%a" /etc/keystone/keystone.conf +$ stat -L -c "%a" /etc/keystone/keystone-paste.ini +$ stat -L -c "%a" /etc/keystone/policy.json +$ stat -L -c "%a" /etc/keystone/logging.conf +$ stat -L -c "%a" /etc/keystone/ssl/certs/signing_cert.pem +$ stat -L -c "%a" /etc/keystone/ssl/private/signing_key.pem +$ stat -L -c "%a" /etc/keystone/ssl/certs/ca.pem +$ stat -L -c "%a" /etc/keystone +``` + +还可以进行更广泛的限制:如果包含目录设置为 750,则保证此目录中新创建的文件具有所需的权限。 + +**通过:**如果权限设置为 640 或更严格,或者包含目录设置为 750。 + +**失败:**如果权限未设置为至少 640/750。 + +推荐于:内部实现的身份验证方法。 + +#### Check-Identity-03:是否为 Identity 启用了 TLS? + +OpenStack 组件使用各种协议相互通信,通信可能涉及敏感或机密数据。攻击者可能会尝试窃听频道以访问敏感信息。因此,所有组件都必须使用安全通信协议(如 HTTPS)相互通信。 + +如果将 HTTP/WSGI 服务器用于标识,则应在 HTTP/WSGI 服务器上启用 TLS。 + +**通过:**如果在 HTTP 服务器上启用了 TLS。 + +**失败:**如果 HTTP 服务器上未启用 TLS。 + +推荐于:安全通信。 + +#### Check-Identity-04:(已过时) + +#### Check-Identity-05:是否 `max_request_body_size` 设置为默认值 (114688)? + +该参数 `max_request_body_size` 定义每个请求的最大正文大小(以字节为单位)。如果未定义最大大小,攻击者可以构建任意大容量请求,导致服务崩溃,最终导致拒绝服务攻击。分配最大值可确保阻止任何恶意的超大请求,从而确保组件的持续可用性。 + +**通过:**如果参数 `max_request_body_size` in `/etc/keystone/keystone.conf` 的值设置为默认值 (114688) 或根据您的环境设置的某个合理值。 + +**失败:**如果未设置参数 `max_request_body_size` 值。 + +#### check-identity-06:禁用/etc/keystone/keystone.conf中的管理令牌 + +管理员令牌通常用于引导 Identity。此令牌是最有价值的标识资产,可用于获取云管理员权限。 + +**通过:**如果 `admin_token` under `[DEFAULT]` section in `/etc/keystone/keystone.conf` 被禁用。并且, `AdminTokenAuthMiddleware` under `[filter:admin_token_auth]` 从 `/etc/keystone/keystone-paste.ini` + +**失败:**如果 `admin_token` 设置了 under `[DEFAULT]` 部分并 `AdminTokenAuthMiddleware` 存在于 `keystone-paste.ini` 中。 + +**建议** + +```shell +禁用 `admin_token` 意味着它的值为 `` 。 +``` + +#### check-identity-07:/etc/keystone/keystone.conf中的不安全_调试为假 + +如果 `insecure_debug` 设置为 true,则服务器将在 HTTP 响应中返回信息,这些信息可能允许未经身份验证或经过身份验证的用户获取比正常情况更多的信息,例如有关身份验证失败原因的其他详细信息。 + +**通过:**如果 `insecure_debug` under `[DEFAULT]` section in `/etc/keystone/keystone.conf` 为 false。 + +**失败:**如果 `insecure_debug` under `[DEFAULT]` section in `/etc/keystone/keystone.conf` 为 true。 + +#### check-identity-08:使用/etc/keystone/keystone.conf中的Fernet令牌 + +OpenStack Identity 服务提供 `uuid` 和 `fernet` 作为令牌提供者。 `uuid` 令牌必须持久化,并被视为不安全。 + +**通过:**如果 section in `/etc/keystone/keystone.conf` 下的 `[token]` 参数 `provider` 值设置为 fernet。 + +**失败:**如果 section 下的 `[token]` 参数 `provider` 值设置为 uuid。 + +## 仪表板 + +Dashboard (horizon) 是 OpenStack 仪表板,它为用户提供了一个自助服务门户,以便在管理员设置的限制范围内配置自己的资源。其中包括预置用户、定义实例变种、上传虚拟机 (VM) 映像、管理网络、设置安全组、启动实例以及通过控制台访问实例。 + +仪表板基于 Django Web 框架,确保 Django 的安全部署实践直接应用于 Horizon。本指南提供了一组 Django 安全建议。更多信息可以通过阅读 Django 文档找到。 + +仪表板附带默认安全设置,并具有部署和配置文档。 + +- 域名、仪表板升级和基本 Web 服务器配置 + + - 域名 + - 基本 Web 服务器配置 + - 允许的主机 + - 映像上传 + +- HTTPS、HSTS、XSS 和 SSRF + + - 跨站点脚本 (XSS) + - 跨站点请求伪造 (CSRF) + - 跨帧脚本 (XFS) + - HTTPS协议 + - HTTP 严格传输安全 (HSTS) + +- 前端缓存和会话后端 + + - 前端缓存 + - 会话后端 + +- 静态媒体 +- 密码 +- 密钥 +- 网站数据 +- 跨域资源共享 (CORS) +- 调试 +- 检查表 + + - Check-Dashboard-01:用户/配置文件组是否设置为 root/horizon? + - Check-Dashboard-02:是否为 Horizon 配置文件设置了严格权限? + - Check-Dashboard-03:参数是否 DISALLOW_IFRAME_EMBED 设置为 True ? + - Check-Dashboard-04:参数是否 CSRF_COOKIE_SECURE 设置为 True ? + - Check-Dashboard-05:参数是否 SESSION_COOKIE_SECURE 设置为 True ? + - Check-Dashboard-06:参数是否 SESSION_COOKIE_HTTPONLY 设置为 True ? + - Check-Dashboard-07: PASSWORD_AUTOCOMPLETE 设置为 False ? + - Check-Dashboard-08: DISABLE_PASSWORD_REVEAL 设置为 True ? + - Check-Dashboard-09: ENFORCE_PASSWORD_CHECK 设置为 True ? + - Check-Dashboard-10:是否 PASSWORD_VALIDATOR 已配置? + - Check-Dashboard-11:是否 SECURE_PROXY_SSL_HEADER 已配置? + +### 域名、仪表板升级和基本 Web 服务器配置 + +#### 域名 + +许多组织通常在总体组织域的子域中部署 Web 应用程序。用户很自然地期望 `openstack.example.org` .在此上下文中,通常存在部署在同一个二级命名空间中的应用程序。此名称结构非常方便,并简化了名称服务器的维护。 + +我们强烈建议将仪表板部署到二级域,例如 ,而不是在任何级别的共享子域上部署仪表板,例如 `https://example.com` `https://openstack.example.org` 或 `https://horizon.openstack.example.org` 。我们还建议不要部署到裸内部域,例如 `https://horizon/` .这些建议基于浏览器同源策略的限制。 + +如果将仪表板部署在还托管用户生成内容的域中,则本指南中提供的建议无法有效防范已知攻击,即使此内容驻留在单独的子域中也是如此。用户生成的内容可以包含任何类型的脚本、图像或上传内容。大多数主要的 Web 存在(包括 googleusercontent.com、fbcdn.com、github.io 和 twimg.co)都使用这种方法将用户生成的内容与 Cookie 和安全令牌隔离开来。 + +如果您不遵循有关二级域的建议,请避免使用 Cookie 支持的会话存储,并采用 HTTP 严格传输安全 (HSTS)。当部署在子域上时,仪表板的安全性等同于部署在同一二级域上的安全性最低的应用程序。 + +#### 基本的 Web 服务器配置 + +仪表板应部署为 HTTPS 代理(如 Apache 或 Nginx)后面的 Web 服务网关接口 (WSGI) 应用程序。如果 Apache 尚未使用,我们建议使用 Nginx,因为它是轻量级的,并且更容易正确配置。 + +使用 Nginx 时,我们建议 gunicorn 作为 WSGI 主机,并具有适当数量的同步工作线程。使用 Apache 时,我们建议 `mod_wsgi` 托管仪表板。 + +#### 允许的主机 + +使用 OpenStack 仪表板提供的完全限定主机名配置设置 `ALLOWED_HOSTS` 。提供此设置后,如果传入 HTTP 请求的“Host:”标头中的值与此列表中的任何值都不匹配,则将引发错误,并且请求者将无法继续。如果未能配置此选项,或者在指定的主机名中使用通配符,将导致仪表板容易受到与虚假 HTTP 主机标头关联的安全漏洞的影响。 + +有关更多详细信息,请参阅 Django 文档。 + +#### Horizon 镜像上传 + +我们建议实施者禁用HORIZON_IMAGES_ALLOW_UPLOAD,除非他们已实施防止资源耗尽和拒绝服务的计划。 + +### HTTPS、HSTS、XSS 和 SSRF + +#### 跨站脚本 (XSS) + +与许多类似的系统不同,OpenStack 仪表板允许在大多数字段中使用整个 Unicode 字符集。这意味着开发人员犯错误的自由度较小,这些错误为跨站点脚本 (XSS) 打开了攻击媒介。 + +Dashboard 为开发人员提供了避免创建 XSS 漏洞的工具,但它们只有在开发人员正确使用它们时才有效。审核任何自定义仪表板,特别注意 `mark_safe` 函数的使用、与自定义模板标记的使用 `is_safe` 、 `safe` 模板标记的使用、关闭自动转义的任何位置,以及任何可能评估不当转义数据的 JavaScript。 + +#### 跨站请求伪造 (CSRF) + +Django 有专门的中间件用于跨站请求伪造 (CSRF)。有关更多详细信息,请参阅 Django 文档。 + +OpenStack 仪表板旨在阻止开发人员在引入线程时使用自定义仪表板引入跨站点脚本漏洞。应审核使用多个 JavaScript 实例的仪表板是否存在漏洞,例如不当使用 `@csrf_exempt` 装饰器。在放宽限制之前,应仔细评估任何不遵循这些建议的安全设置的仪表板。 + +#### 跨帧脚本 (XFS) + +传统浏览器仍然容易受到跨帧脚本 (XFS) 漏洞的攻击,因此 OpenStack 仪表板提供了一个选项 `DISALLOW_IFRAME_EMBED` ,允许在部署中不使用 iframe 的情况下进行额外的安全强化。 + +#### HTTPS 函数 + +使用来自公认的证书颁发机构 (CA) 的有效受信任证书,将仪表板部署在安全 HTTPS 服务器后面。仅当信任根预安装在所有用户浏览器中时,私有组织颁发的证书才适用。 + +配置对仪表板域的 HTTP 请求,以重定向到完全限定的 HTTPS URL。 + +#### HTTP 严格传输安全 (HSTS) + +强烈建议使用 HTTP 严格传输安全 (HSTS)。 + +**注意** + +```shell +如果您在 Web 服务器前面使用 HTTPS 代理,而不是使用具有 HTTPS 功能的 HTTP 服务器,请修改该 `SECURE_PROXY_SSL_HEADER` 变量。有关修改 `SECURE_PROXY_SSL_HEADER` 变量的信息,请参阅 Django 文档。 +``` + +有关 HTTPS 配置(包括 HSTS 配置)的更具体建议和服务器配置,请参阅“安全通信”一章。 + +### 前端缓存和会话后端 + +#### 前端缓存 + +我们不建议在仪表板中使用前端缓存工具。仪表板正在渲染直接由 OpenStack API 请求生成的动态内容,前端缓存层(如 varnish)可能会阻止显示正确的内容。在 Django 中,静态媒体直接从 Apache 或 Nginx 提供,并且已经受益于 Web 主机缓存。 + +#### 会话后端 + +Horizon 的默认会话后端 `django.contrib.sessions.backends.signed_cookies` 将用户数据保存在浏览器中存储的已签名但未加密的 Cookie 中。由于每个仪表板实例都是无状态的,因此前面提到的方法提供了实现最简单的会话后端扩展的能力。 + +应该注意的是,在这种类型的实现中,敏感的访问令牌将存储在浏览器中,并将随着每个请求的发出而传输。后端确保会话数据的完整性,即使传输的数据仅通过 HTTPS 加密。 + +如果您的架构允许共享存储,并且您正确配置了缓存,我们建议您将其设置为 `SESSION_ENGINE` `django.contrib.sessions.backends.cache` 并用作基于缓存的会话后端,并将 memcached 作为缓存。Memcached 是一种高效的内存键值存储,用于存储数据块,可在高可用性和分布式环境中使用,并且易于配置。但是,您需要确保没有数据泄漏。Memcached 利用备用 RAM 来存储经常访问的数据块,就像重复访问信息的内存缓存一样。由于 memcached 使用本地内存,因此不会产生数据库和文件系统使用开销,从而导致直接从 RAM 而不是从磁盘访问数据。 + +我们建议使用 memcached 而不是本地内存缓存,因为它速度快,数据保留时间更长,多进程安全,并且能够在多个服务器上共享缓存,但仍将其视为单个缓存。 + +要启用 memcached,请执行以下命令: + +```shell +SESSION_ENGINE = 'django.contrib.sessions.backends.cache' +CACHES = { + 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache' +} +``` + +有关更多详细信息,请参阅 Django 文档。 + +### 静态媒体 + +仪表板的静态媒体应部署到仪表板域的子域,并由 Web 服务器提供服务。使用外部内容分发网络 (CDN) 也是可以接受的。此子域不应设置 Cookie 或提供用户提供的内容。媒体也应使用 HTTPS 提供。 + +Django 媒体设置记录在 Django 文档中。 + +Dashboard 的默认配置使用 django_compressor 来压缩和缩小 CSS 和 JavaScript 内容,然后再提供这些内容。此过程应在部署仪表板之前静态完成,而不是使用默认的请求内动态压缩,并将生成的文件与已部署的代码一起复制到 CDN 服务器。压缩应在非生产生成环境中完成。如果这不可行,我们建议完全禁用资源压缩。不应在生产计算机上安装联机压缩依赖项(较少,Node.js)。 + +### 密码 + +密码管理应该是云管理计划不可或缺的一部分。关于密码的权威教程超出了本书的范围;但是,云管理员应参考 NIST 企业密码管理特别出版物指南第 4 章中推荐的最佳实践。 + +无论是通过仪表板还是其他应用程序,基于浏览器的 OpenStack 云访问都会引入额外的注意事项。现代浏览器都支持某种形式的密码存储和自动填充记住的站点的凭据。这在使用不容易记住或键入的强密码时非常有用,但如果客户端的物理安全性受到威胁,可能会导致浏览器成为薄弱环节。如果浏览器的密码存储本身不受强密码保护,或者如果允许密码存储在会话期间保持解锁状态,则很容易获得对系统的未经授权的访问。 + +KeePassX 和 Password Safe 等密码管理应用程序非常有用,因为大多数应用程序都支持生成强密码和定期提醒生成新密码。最重要的是,密码存储仅短暂保持解锁状态,从而降低了密码泄露和通过浏览器或系统入侵进行未经授权的资源访问的风险。 + +### 密钥 + +仪表板依赖于某些安全功能的共享 `SECRET_KEY` 设置。密钥应为随机生成的字符串,长度至少为 64 个字符,必须在所有活动仪表板实例之间共享。泄露此密钥可能允许远程攻击者执行任意代码。轮换此密钥会使现有用户会话和缓存失效。请勿将此密钥提交到公共存储库。 + +### Cookies + +会话Cookies应设置为 HTTPONLY: + +```shell +SESSION_COOKIE_HTTPONLY = True +``` + +切勿将 CSRF 或会话 Cookie 配置为具有带前导点的通配符域。使用 HTTPS 部署时,应保护 Horizon 的会话和 CSRF Cookie: + +```shell +CSRF_COOKIE_SECURE = True +SESSION_COOKIE_SECURE = True +``` + +### 跨域资源共享 (CORS) + +将 Web 服务器配置为在每次响应时发送限制性 CORS 标头,仅允许仪表板域和协议: + +```shell +Access-Control-Allow-Origin: https://example.com/ +``` + +永远不允许通配符来源。 + +### 调试 + +建议在生产环境中将 `DEBUG` 该设置设置为 `False` 。如果 `DEBUG` 设置为 True,则当抛出异常时,Django 将显示堆栈跟踪和敏感的 Web 服务器状态信息。 + +### 检查表 + +#### Check-Dashboard-01:用户/配置文件组是否设置为 root/horizon? + +配置文件包含组件平稳运行所需的关键参数和信息。如果非特权用户有意或无意地修改或删除任何参数或文件本身,则会导致严重的可用性问题,从而导致对其他最终用户的拒绝服务。因此,此类关键配置文件的用户所有权必须设置为 root,组所有权必须设置为 horizon。 + +运行以下命令: + +```shell +$ stat -L -c "%U %G" /etc/openstack-dashboard/local_settings.py | egrep "root horizon" +``` + +通过:如果配置文件的用户和组所有权分别设置为 root 和 horizon。上面的命令显示了根地平线的输出。 + +失败:如果上述命令未返回任何输出,因为用户和组所有权可能已设置为除 root 以外的任何用户或除 Horizon 以外的任何组。 + +#### Check-Dashboard-02:是否为 Horizon 配置文件设置了严格权限? + +与前面的检查类似,建议对此类配置文件设置严格的访问权限。 + +运行以下命令: + +```shell +$ stat -L -c "%a" /etc/openstack-dashboard/local_settings.py +``` + +通过:如果权限设置为 640 或更严格。640 的权限转换为所有者 r/w、组 r,而对其他人没有权限,即“u=rw,g=r,o=”。请注意,使用 Check-Dashboard-01 时:用户/配置文件组是否设置为 root/horizon?权限设置为 640,则 root 用户具有读/写访问权限,Horizon 具有对这些配置文件的读取访问权限。也可以使用以下命令验证访问权限。仅当此命令支持 ACL 时,它才在您的系统上可用。 + +```shell +$ getfacl --tabular -a /etc/openstack-dashboard/local_settings.py +getfacl: Removing leading '/' from absolute path names +# file: etc/openstack-dashboard/local_settings.py +USER root rw- +GROUP horizon r-- +mask r-- +other --- +``` + +失败:如果权限未设置为至少 640。 + +#### Check-Dashboard-03:参数是否 `DISALLOW_IFRAME_EMBED` 设置为 `True` ? + +`DISALLOW_IFRAME_EMBED` 可用于防止 OpenStack Dashboard 嵌入到 iframe 中。 + +旧版浏览器仍然容易受到跨帧脚本 (XFS) 漏洞的影响,因此此选项允许在部署中未使用 iframe 的情况下进行额外的安全强化。 + +默认设置为 True。 + +通过:如果参数 `DISALLOW_IFRAME_EMBED` in `/etc/openstack-dashboard/local_settings.py` 的值设置为 `True` 。 + +失败:如果参数 `DISALLOW_IFRAME_EMBED` in `/etc/openstack-dashboard/local_settings.py` 的值设置为 `False` 。 + +推荐用于:HTTPS、HSTS、XSS 和 SSRF。 + +#### Check-Dashboard-04:参数是否 `CSRF_COOKIE_SECURE` 设置为 `True` ? + +CSRF(跨站点请求伪造)是一种攻击,它迫使最终用户在他/她当前经过身份验证的 Web 应用程序上执行未经授权的命令。成功的 CSRF 漏洞可能会危及最终用户的数据和操作。如果目标最终用户具有管理员权限,这可能会危及整个 Web 应用程序。 + +通过:如果参数 `CSRF_COOKIE_SECURE` in `/etc/openstack-dashboard/local_settings.py` 的值设置为 `True` 。 + +失败:如果参数 `CSRF_COOKIE_SECURE` in `/etc/openstack-dashboard/local_settings.py` 的值设置为 `False` 。 + +推荐于:Cookies。 + +#### Check-Dashboard-05:参数是否 `SESSION_COOKIE_SECURE` 设置为 `True` ? + +“SECURE”cookie 属性指示 Web 浏览器仅通过加密的 HTTPS (SSL/TLS) 连接发送 cookie。此会话保护机制是强制性的,以防止通过 MitM(中间人)攻击泄露会话 ID。它确保攻击者无法简单地从 Web 浏览器流量中捕获会话 ID。 + +通过:如果参数 `SESSION_COOKIE_SECURE` in `/etc/openstack-dashboard/local_settings.py` 的值设置为 `True` 。 + +失败:如果参数 `SESSION_COOKIE_SECURE` in `/etc/openstack-dashboard/local_settings.py` 的值设置为 `False` 。 + +推荐于:Cookies。 + +#### Check-Dashboard-06:参数是否 `SESSION_COOKIE_HTTPONLY` 设置为 `True` ? + +“HTTPONLY”cookie 属性指示 Web 浏览器不允许脚本(例如 JavaScript 或 VBscript)通过 DOM `document.cookie` 对象访问 cookie。此会话 ID 保护是必需的,以防止通过 XSS 攻击窃取会话 ID。 + +通过:如果参数 `SESSION_COOKIE_HTTPONLY` in `/etc/openstack-dashboard/local_settings.py` 的值设置为 `True` 。 + +失败:如果参数 `SESSION_COOKIE_HTTPONLY` in `/etc/openstack-dashboard/local_settings.py` 的值设置为 `False` 。 + +推荐于:Cookies。 + +#### Check-Dashboard-07: `PASSWORD_AUTOCOMPLETE` 设置为 `False` ? + +应用程序用于为用户提供便利的常见功能是将密码本地缓存在浏览器中(在客户端计算机上),并在所有后续请求中“预先键入”。虽然此功能对普通用户来说非常友好,但同时,它引入了一个缺陷,因为在客户端计算机上使用相同帐户的任何人都可以轻松访问用户帐户,从而可能导致用户帐户受损。 + +通过:如果参数 `PASSWORD_AUTOCOMPLETE` in `/etc/openstack-dashboard/local_settings.py` 的值设置为 `off` 。 + +失败:如果参数 `PASSWORD_AUTOCOMPLETE` in `/etc/openstack-dashboard/local_settings.py` 的值设置为 `on` 。 + +#### Check-Dashboard-08: `DISABLE_PASSWORD_REVEAL` 设置为 `True` ? + +与之前的检查类似,建议不要显示密码字段。 + +通过:如果参数 `DISABLE_PASSWORD_REVEAL` in `/etc/openstack-dashboard/local_settings.py` 的值设置为 `True` 。 + +失败:如果参数 `DISABLE_PASSWORD_REVEAL` in `/etc/openstack-dashboard/local_settings.py` 的值设置为 `False` 。 + +**注意** + +```shell +此选项是在 Kilo 版本中引入的。 +``` + +#### Check-Dashboard-09: `ENFORCE_PASSWORD_CHECK` 设置为 `True` ? + +设置为 `ENFORCE_PASSWORD_CHECK` True 将在“更改密码”窗体上显示“管理员密码”字段,以验证是否确实是管理员登录的要更改密码。 + +通过:如果参数 `ENFORCE_PASSWORD_CHECK` in `/etc/openstack-dashboard/local_settings.py` 的值设置为 `True` 。 + +失败:如果参数 `ENFORCE_PASSWORD_CHECK` in `/etc/openstack-dashboard/local_settings.py` 的值设置为 `False` 。 + +#### Check-Dashboard-10:是否 `PASSWORD_VALIDATOR` 已配置? + +允许正则表达式验证用户密码的复杂性。 + +通过:如果参数 `PASSWORD_VALIDATOR` in `/etc/openstack-dashboard/local_settings.py` 的值设置为 defaul 之外的任何值,则允许所有 “regex”: '.*', + +失败:如果参数 `PASSWORD_VALIDATOR` in `/etc/openstack-dashboard/local_settings.py` 的值设置为允许所有 “regex”: '.*' + +#### Check-Dashboard-11:是否 `SECURE_PROXY_SSL_HEADER` 已配置? + +如果 OpenStack Dashboard 部署在代理后面,并且代理从所有传入请求中剥离 `X-Forwarded-Proto` 标头,或者设置标头 `X-Forwarded-Proto` 并将其发送到 Dashboard,但仅适用于最初通过 HTTPS 传入的请求,那么您应该考虑配置 `SECURE_PROXY_SSL_HEADER` + +更多信息可以在 Django 文档中找到。 + +通过:如果参数 `SECURE_PROXY_SSL_HEADER` in `/etc/openstack-dashboard/local_settings.py` 的值设置为 `'HTTP_X_FORWARDED_PROTO', 'https'` + +失败:如果参数 `SECURE_PROXY_SSL_HEADER` in `/etc/openstack-dashboard/local_settings.py` 的值未设置为 `'HTTP_X_FORWARDED_PROTO', 'https'` 或注释掉。 + +## 计算 + +OpenStack 计算服务 (nova) 在整个云中的许多位置运行,并与各种内部服务进行交互。OpenStack 计算服务提供了多种配置选项,这些选项可能是特定于部署的。 + +在本章中,我们将介绍有关计算安全性的一般最佳实践,以及可能导致安全问题的特定已知配置。 `nova.conf` 文件和 `/var/lib/nova` 位置应受到保护。应实施集中式日志记录、 `policy.json` 文件和强制访问控制框架等控制措施。 + +- 虚拟机管理程序选择 + + - OpenStack 中的虚拟机管理程序 + - 纳入排除标准 + - 团队专长 + - 产品或项目成熟度 + - 认证和证明 + - 通用标准 + - 加密标准 + - FIPS 140-2 + - 硬件问题 + - 虚拟机管理程序与裸机 + - 虚拟机管理程序内存优化 + - KVM 内核 Samepage 合并 + - XEN透明页面共享 + - 内存优化的安全注意事项 + - 其他安全功能 + - 书目 + +- 强化虚拟化层 + + - 物理硬件(PCI 直通) + - 虚拟硬件 (QEMU) + - 最小化 QEMU 代码库 + - 编译器强化 + - 安全加密虚拟化 + - 强制访问控制 + - sVirt:SELinux 和虚拟化 + - 标签和类别 + - SELinux 用户和角色 + - 布尔值 + +- 强化计算部署 + + - OpenStack 漏洞管理团队 + - OpenStack 安全说明 + - OpenStack-dev 邮件列表 + - 虚拟机管理程序邮件列表 + +- 漏洞意识 + + - OpenStack 漏洞管理团队 + - OpenStack 安全说明 + - OpenStack-讨论邮件列表 + - 虚拟机管理程序邮件列表 + +- 如何选择虚拟控制台 + + - 虚拟网络计算机 (VNC) + - 独立计算环境的简单协议 (SPICE) + +- 检查表 + + - Check-Compute-01:配置文件的用户/组所有权是否设置为 root/nova? + - Check-Compute-02:是否为配置文件设置了严格的权限? + - Check-Compute-03:Keystone 是否用于身份验证? + - Check-Compute-04:是否使用安全协议进行身份验证? + - Check-Compute-05:Nova 与 Glance 的通信是否安全? + +### 虚拟机管理程序选择 + +#### OpenStack 中的虚拟机管理程序 + +无论OpenStack是部署在私有数据中心内,还是作为公共云服务部署,底层虚拟化技术都能在可扩展性、资源效率和正常运行时间方面提供企业级功能。虽然在许多 OpenStack 支持的虚拟机管理程序技术中通常都具有这种高级优势,但每个虚拟机管理程序的安全架构和功能都存在显著差异,尤其是在考虑弹性 OpenStack 环境特有的安全威胁向量时。随着应用程序整合到单个基础架构即服务 (IaaS) 平台中,虚拟机管理程序级别的实例隔离变得至关重要。安全隔离的要求在商业、政府和军事社区中都适用。 + +在 OpenStack 框架中,您可以在众多虚拟机管理程序平台和相应的 OpenStack 插件中进行选择,以优化您的云环境。在本指南的上下文中,重点介绍了虚拟机管理程序选择注意事项,因为它们与对安全性至关重要的功能集有关。但是,这些注意事项并不意味着对特定虚拟机管理程序的优缺点进行详尽的调查。NIST 在特别出版物 800-125“完整虚拟化技术安全指南”中提供了其他指导。 + +#### 选择标准 + +作为虚拟机管理程序选择过程的一部分,您必须考虑许多重要因素,以帮助改善您的安全状况。具体来说,您必须熟悉以下方面: + +- 团队专长 +- 产品或项目成熟度 +- 通用标准 +- 认证和证明 +- 硬件问题 +- 虚拟机管理程序与裸机 +- 其他安全功能 + +此外,强烈建议在为 OpenStack 部署选择虚拟机管理程序时评估以下与安全相关的标准: *虚拟机管理程序是否经过通用标准认证?如果是这样,达到什么水平?* 底层密码学是否经过第三方认证? + +#### 团队专长 + +最有可能的是,在选择虚拟机管理程序时,最重要的方面是您的员工在管理和维护特定虚拟机管理程序平台方面的专业知识。您的团队对给定产品、其配置及其怪癖越熟悉,配置错误就越少。此外,在给定的虚拟机管理程序上将员工专业知识分布在整个组织中可以提高系统的可用性,允许职责分离,并在团队成员不可用时缓解问题。 + +#### 产品或项目成熟度 + +给定虚拟机管理程序产品或项目的成熟度对您的安全状况也至关重要。部署云后,产品成熟度会产生许多影响:给定虚拟机管理程序产品或项目的成熟度对您的安全状况也至关重要。部署云后,产品成熟度会产生许多影响: + +- 专业知识的可用性 +- 活跃的开发人员和用户社区 +- 更新的及时性和可用性 +- 发病率响应 + +虚拟机管理程序成熟度的最大指标之一是围绕它的社区的规模和活力。由于这涉及安全性,因此如果您需要额外的云操作员,社区的质量会影响专业知识的可用性。这也表明了虚拟机管理程序的广泛部署,进而导致任何参考架构和最佳实践的战备状态。 + +此外,社区的质量,因为它围绕着KVM或Xen等开源虚拟机管理程序,对错误修复和安全更新的及时性有直接影响。在调查商业和开源虚拟机管理程序时,您必须查看它们的发布和支持周期,以及发布错误或安全问题与补丁或响应之间的时间差。最后,OpenStack 计算支持的功能因所选的虚拟机管理程序而异。请参阅 OpenStack Hypervisor Support Matrix,了解 Hypervisor 对 OpenStack 计算功能的支持。 + +#### 认证和证明 + +选择虚拟机管理程序时,另一个考虑因素是各种正式认证和证明的可用性。虽然它们可能不是特定组织的要求,但这些认证和证明说明了特定虚拟机管理程序平台所经过的测试的成熟度、生产准备情况和彻底性。 + +#### 通用标准 + +通用标准是一个国际标准化的软件评估过程,政府和商业公司使用它来验证软件技术是否如宣传的那样。在政府部门,NSTISSP 第 11 号规定美国政府机构只能采购已通过通用标准认证的软件,该政策自 2002 年 7 月起实施。 + +**注意** + +OpenStack尚未通过通用标准认证,但许多可用的虚拟机管理程序都经过了认证。 + +除了验证技术能力外,通用标准流程还评估技术的开发方式。 + +- 如何进行源代码管理? +- 如何授予用户对构建系统的访问权限? +- 该技术在分发前是否经过加密签名? + +KVM 虚拟机管理程序已通过美国政府和商业发行版的通用标准认证。这些已经过验证,可以将虚拟机的运行时环境彼此分离,从而提供基础技术来实施实例隔离。除了虚拟机隔离之外,KVM 还通过了通用标准认证: + +```shell +"...provide system-inherent separation mechanisms to the resources of virtual +machines. This separation ensures that large software component used for +virtualizing and simulating devices executing for each virtual machine +cannot interfere with each other. Using the SELinux multi-category +mechanism, the virtualization and simulation software instances are +isolated. The virtual machine management framework configures SELinux +multi-category settings transparently to the administrator." +``` + +虽然许多虚拟机管理程序供应商(如 Red Hat、Microsoft 和 VMware)已获得通用标准认证,但其基础认证功能集有所不同,但我们建议评估供应商声明,以确保它们至少满足以下要求: + +| | | +| ------------------ | ------------------------------------------------------------ | +| 审计 | 该系统提供了审核大量事件的功能,包括单个系统调用和受信任进程生成的事件。审计数据以 ASCII 格式收集在常规文件中。系统提供了一个用于搜索审计记录的程序。系统管理员可以定义一个规则库,以将审核限制为他们感兴趣的事件。这包括将审核限制为特定事件、特定用户、特定对象或所有这些的组合的能力。审计记录可以传输到远程审计守护程序。 | +| 自主访问控制 | 自主访问控制 (DAC) 限制对基于 ACL 的文件系统对象的访问,这些对象包括用户、组和其他人员的标准 UNIX 权限。访问控制机制还可以保护 IPC 对象免受未经授权的访问。该系统包括 ext4 文件系统,它支持 POSIX ACL。这允许定义对此类文件系统中文件的访问权限,精确到单个用户的粒度。 | +| 强制访问控制 | 强制访问控制 (MAC) 根据分配给主体和对象的标签来限制对对象的访问。敏感度标签会自动附加到进程和对象。使用这些标签强制实施的访问控制策略派生自 Bell-LaPadula 模型。SELinux 类别附加到虚拟机及其资源。如果虚拟机的类别与所访问资源的类别相同,则使用这些类别强制实施的访问控制策略将授予虚拟机对资源的访问权限。TOE 实现非分层类别来控制对虚拟机的访问。 | +| 基于角色的访问控制 | 基于角色的访问控制 (RBAC) 允许角色分离,无需全能的系统管理员。 | +| 对象重用 | 文件系统对象、内存和 IPC 对象在被属于其他用户的进程重用之前会被清除。 | +| 安全管理 | 系统安全关键参数的管理由管理用户执行。一组需要 root 权限(或使用 RBAC 时需要特定角色)的命令用于系统管理。安全参数存储在特定文件中,这些文件受系统的访问控制机制保护,防止非管理用户未经授权的访问。 | +| 安全通信 | 系统支持使用 SSH 定义可信通道。支持基于密码的身份验证。在评估的配置中,这些协议仅支持有限数量的密码套件。 | +| 存储加密 | 系统支持加密块设备,通过 `dm_crypt` 提供存储机密性。 | +| TSF 保护 | 在运行时,内核软件和数据受到硬件内存保护机制的保护。内核的内存和进程管理组件确保用户进程无法访问内核存储或属于其他进程的存储。非内核 TSF 软件和数据受 DAC 和进程隔离机制保护。在评估的配置中,保留用户 ID root 拥有定义 TSF 配置的目录和文件。通常,包含内部 TSF 数据的文件和目录(如配置文件和批处理作业队列)也受到 DAC 权限的保护,不会被读取。系统以及硬件和固件组件需要受到物理保护,以防止未经授权的访问。系统内核调解对硬件机制本身的所有访问,但程序可见的 CPU 指令函数除外。此外,还提供了防止堆栈溢出攻击的机制。 | + +#### 密码学标准 + +OpenStack 中提供了多种加密算法,用于识别和授权、数据传输和静态数据保护。选择虚拟机管理程序时,我们建议采用以下算法和实现标准: + +| 算法 | 密钥长度 | 预期目的 | 安全功能 | 执行标准 | +| -------------------------------- | --------------------- | ------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | +| AES | 128、192 或 256 位 | 加密/解密 | 受保护的数据传输,保护静态数据 | [RFC 4253](http://www.ietf.org/rfc/rfc4253.txt) | +| TDES | 168 位 | 加密/解密 | 受保护的数据传输 | [RFC 4253](http://www.ietf.org/rfc/rfc4253.txt) | +| RSA | 1024、2048 或 3072 位 | 身份验证、密钥交换 | 识别和身份验证,受保护的数据传输 | [U.S. NIST FIPS PUB 186-3](http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf) | +| DSA | L=1024,N=160位 | 身份验证、密钥交换 | 识别和身份验证,受保护的数据传输 | [U.S. NIST FIPS PUB 186-3](http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf) | +| Serpent | 128、192 或 256 位 | 加密/解密 | 静态数据保护 | | +| Twofish | 128、192 或 256 位 | 加密/解密 | 静态数据保护 | | +| SHA-1 | | 消息摘要 | 保护静态数据,受保护的数据传输 | [U.S. NIST FIPS PUB 180-3](http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf) | +| SHA-2(224、256、384 或 512 位) | | 消息摘要 | Protection for data at rest, identification and authentication 保护静态数据、识别和身份验证 | [U.S. NIST FIPS PUB 180-3](http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf) | + +#### FIPS 140-2 + +在美国,美国国家科学技术研究院 (NIST) 通过称为加密模块验证计划的过程对加密算法进行认证。NIST 认证算法符合联邦信息处理标准 140-2 (FIPS 140-2),确保: + +```shell +"... Products validated as conforming to FIPS 140-2 are accepted by the Federal +agencies of both countries [United States and Canada] for the protection of +sensitive information (United States) or Designated Information (Canada). +The goal of the CMVP is to promote the use of validated cryptographic +modules and provide Federal agencies with a security metric to use in +procuring equipment containing validated cryptographic modules." +``` + +在评估基本虚拟机管理程序技术时,请考虑虚拟机管理程序是否已通过 FIPS 140-2 认证。根据美国政府政策,不仅强制要求符合 FIPS 140-2,而且正式认证表明已对加密算法的给定实现进行了审查,以确保符合模块规范、加密模块端口和接口;角色、服务和身份验证;有限状态模型;人身安全;操作环境;加密密钥管理;电磁干扰/电磁兼容性(EMI/EMC);自检;设计保证;以及缓解其他攻击。 + +#### 硬件问题 + +在评估虚拟机管理程序平台时,请考虑运行虚拟机管理程序的硬件的可支持性。此外,请考虑硬件中可用的其他功能,以及您在 OpenStack 部署中选择的虚拟机管理程序如何支持这些功能。为此,每个虚拟机管理程序都有自己的硬件兼容性列表 (HCL)。在选择兼容的硬件时,从安全角度来看,提前了解哪些基于硬件的虚拟化技术是重要的,这一点很重要。 + +| 描述 | 科技 | 解释 | +| ------------------ | ------------------- | ----------------------------------- | +| I/O MMU | VT-d / AMD-Vi | 保护 PCI 直通所必需的 | +| 英特尔可信执行技术 | Intel TXT / SEM | 动态证明服务是必需的 | +| PCI-SIG I/O 虚拟化 | SR-IOV, MR-IOV, ATS | 需要允许安全共享 PCI Express 设备 | +| 网络虚拟化 | VT-c | 提高虚拟机管理程序上的网络 I/O 性能 | + +#### 虚拟机管理程序与裸机 + +重要的是要认识到使用 Linux 容器 (LXC) 或裸机系统与使用 KVM 等虚拟机管理程序之间的区别。具体来说,本安全指南的重点主要基于拥有虚拟机管理程序和虚拟化平台。但是,如果您的实现需要使用裸机或 LXC 环境,则必须注意该环境部署方面的特殊差异。 + +在重新预配之前,请确保最终用户已正确清理节点的数据。此外,在重用节点之前,必须保证硬件未被篡改或以其他方式受到损害。 + +**注意** + +虽然OpenStack有一个裸机项目,但对运行裸机的特殊安全影响的讨论超出了本书的范围。 + +由于书本冲刺的时间限制,该团队选择在我们的示例实现和架构中使用 KVM 作为虚拟机管理程序。 + +**注意** + +有一个关于在计算中使用 LXC 的 OpenStack 安全说明。 + +#### Hypervisor 内存优化 + +许多虚拟机监控程序使用内存优化技术将内存过量使用到来宾虚拟机。这是一项有用的功能,可用于部署非常密集的计算群集。实现此目的的一种方法是通过重复数据消除或共享内存页。当两个虚拟机在内存中具有相同的数据时,让它们引用相同的内存是有好处的。 + +通常,这是通过写入时复制 (COW) 机制实现的。这些机制已被证明容易受到侧信道攻击,其中一个 VM 可以推断出另一个 VM 的状态,并且可能不适用于并非所有租户都受信任或共享相同信任级别的多租户环境。 + +#### KVM 内核同页合并 + +在版本 2.6.32 中引入到 Linux 内核中,内核相同页合并 (KSM) 在 Linux 进程之间整合了相同的内存页。由于 KVM 虚拟机管理程序下的每个客户机虚拟机都在自己的进程中运行,因此 KSM 可用于优化虚拟机之间的内存使用。 + +#### XEN 透明页面共享 + +XenServer 5.6 包含一个名为透明页面共享 (TPS) 的内存过量使用功能。TPS 扫描 4 KB 区块中的内存以查找任何重复项。找到后,Xen 虚拟机监视器 (VMM) 将丢弃其中一个重复项,并记录第二个副本的引用。 + +#### 内存优化的安全注意事项 + +传统上,内存重复数据消除系统容易受到侧信道攻击。KSM 和 TPS 都已被证明容易受到某种形式的攻击。在学术研究中,攻击者能够通过分析攻击者虚拟机上的内存访问时间来识别相邻虚拟机上运行的软件包和版本,以及软件下载和其他敏感信息。 + +如果云部署需要强租户分离(如公有云和某些私有云的情况),部署人员应考虑禁用 TPS 和 KSM 内存优化。 + +#### 其他安全功能 + +选择虚拟机管理程序平台时要考虑的另一件事是特定安全功能的可用性。特别是功能。例如,Xen Server 的 XSM 或 Xen 安全模块、sVirt、Intel TXT 或 AppArmor。 + +下表按常见虚拟机管理程序平台列出了这些功能。 + +| | XSM | sVirt | TXT | AppArmor | cgroups | MAC 策略 | +| ------- | ---- | ----- | ---- | -------- | ------- | -------- | +| KVM | | X | X | X | X | X | +| Xen | X | | X | | | | +| ESXi | | | X | | | | +| Hyper-V | | | | | | | + +**注意** + +```shell +此表中的功能可能不适用于所有虚拟机管理程序,也可能无法在虚拟机管理程序之间直接映射。 +``` + +#### 参考书目 + +- Sunar、Eisenbarth、Inci、Gorka Irazoqui Apecechea。对 Xen 和 VMware 进行细粒度跨虚拟机攻击是可能的!2014。 +- Artho、Yagi、Iijima、Kuniyasu Suzaki。内存重复数据删除对客户机操作系统的威胁。2011 年。 +- KVM:基于内核的虚拟机。内核相同页合并。2010。 +- Xen 项目,Xen 安全模块:XSM-FLASK。2014。 +- SELinux 项目,SVirt。2011。 +- Intel.com,采用英特尔可信执行技术 (Intel TXT) 的可信计算池。 +- AppArmor.net,AppArmor 主页。2011。 +- Kernel.org,CGroups。2004。 +- 计算机安全资源中心。完整虚拟化技术安全指南。2011。 +- 国家信息保障伙伴关系,国家安全电信和信息系统安全政策。2003。 + +### 加固虚拟化层 + +在本章的开头,我们将讨论实例对物理和虚拟硬件的使用、相关的安全风险以及缓解这些风险的一些建议。然后,我们将讨论如何使用安全加密虚拟化技术来加密支持该技术的基于 AMD 的机器上的虚拟机的内存。在本章的最后,我们将讨论 sVirt,这是一个开源项目,用于将 SELinux 强制访问控制与虚拟化组件集成。 + +#### 物理硬件(PCI直通) + +许多虚拟机管理程序都提供一种称为 PCI 直通的功能。这允许实例直接访问节点上的硬件。例如,这可用于允许实例访问提供计算统一设备架构 (CUDA) 以实现高性能计算的视频卡或 GPU。此功能存在两种类型的安全风险:直接内存访问和硬件感染。 + +直接内存访问 (DMA) 是一种功能,它允许某些硬件设备访问主机中的任意物理内存地址。视频卡通常具有此功能。但是,不应向实例授予任意物理内存访问权限,因为这将使其能够全面了解主机系统和在同一节点上运行的其他实例。在这些情况下,硬件供应商使用输入/输出内存管理单元 (IOMMU) 来管理 DMA 访问。我们建议云架构师应确保虚拟机监控程序配置为使用此硬件功能。 + +KVM: KVM: + +如何在 KVM 中使用 VT-d 分配设备 + +Xen: Xen: + +Xen VTd Howto Xen VTd 贴士指南 + +**注意** + +IOMMU 功能由 Intel 作为 VT-d 销售,由 AMD 以 AMD-Vi 销售。 + +当实例对固件或设备的某些其他部分进行恶意修改时,就会发生硬件感染。由于此设备由其他实例或主机操作系统使用,因此恶意代码可能会传播到这些系统中。最终结果是,一个实例可以在其安全域之外运行代码。这是一个重大的漏洞,因为重置物理硬件的状态比重置虚拟硬件更难,并且可能导致额外的暴露,例如访问管理网络。 + +硬件感染问题的解决方案是特定于域的。该策略是确定实例如何修改硬件状态,然后确定在使用硬件完成实例时如何重置任何修改。例如,一种选择可能是在使用后重新刷新固件。需要平衡硬件寿命和安全性,因为某些固件在大量写入后会出现故障。安全引导中所述的 TPM 技术是一种用于检测未经授权的固件更改的解决方案。无论选择哪种策略,都必须了解与此类硬件共享相关的风险,以便针对给定的部署方案适当缓解这些风险。 + +由于与 PCI 直通相关的风险和复杂性,默认情况下应禁用它。如果为特定需求启用,则需要制定适当的流程,以确保硬件在重新发行之前是干净的。 + +#### 虚拟硬件 (QEMU) + +运行虚拟机时,虚拟硬件是为虚拟机提供硬件接口的软件层。实例使用此功能提供可能需要的网络、存储、视频和其他设备。考虑到这一点,环境中的大多数实例将专门使用虚拟硬件,少数实例需要直接硬件访问。主要的开源虚拟机管理程序使用 QEMU 来实现此功能。虽然 QEMU 满足了对虚拟化平台的重要需求,但它已被证明是一个非常具有挑战性的软件项目。QEMU 中的许多功能都是通过大多数开发人员难以理解的低级代码实现的。QEMU 虚拟化的硬件包括许多传统设备,这些设备有自己的一套怪癖。综上所述,QEMU 一直是许多安全问题的根源,包括虚拟机管理程序突破攻击。 + +采取积极主动的措施来强化 QEMU 非常重要。我们建议执行三个具体步骤: + +- 最小化代码库。 +- 使用编译器强化。 +- 使用强制访问控制,例如 sVirt、SELinux 或 AppArmor。 + +确保您的 iptables 具有过滤网络流量的默认策略,并考虑检查现有规则集以了解每个规则并确定是否需要扩展该策略。 + +#### 最小化 QEMU 代码库 + +我们建议通过从系统中删除未使用的组件来最小化 QEMU 代码库。QEMU 为许多不同的虚拟硬件设备提供支持,但给定实例只需要少量设备。最常见的硬件设备是 virtio 设备。某些旧实例将需要访问特定硬件,这些硬件可以使用 glance 元数据指定: + +```shell +$ glance image-update \ +--property hw_disk_bus=ide \ +--property hw_cdrom_bus=ide \ +--property hw_vif_model=e1000 \ +f16-x86_64-openstack-sda +``` + +云架构师应决定向云用户提供哪些设备。任何不需要的东西都应该从 QEMU 中删除。此步骤需要在修改传递给 QEMU 配置脚本的选项后重新编译 QEMU。要获得最新选项的完整列表,只需从 QEMU 源目录中运行 ./configure --help。确定部署所需的内容,并禁用其余选项。 + +#### 编译器加固 + +使用编译器强化选项强化 QEMU。现代编译器提供了多种编译时选项,以提高生成的二进制文件的安全性。这些功能包括只读重定位 (RELRO)、堆栈金丝雀、从不执行 (NX)、位置无关可执行文件 (PIE) 和地址空间布局随机化 (ASLR)。 + +许多现代 Linux 发行版已经在构建启用编译器强化的 QEMU,我们建议在继续操作之前验证现有的可执行文件。可以帮助您进行此验证的一种工具称为 checksec.sh + +RELocation 只读 (RELRO) + +强化可执行文件的数据部分。gcc 支持完整和部分 RELRO 模式。对于QEMU来说,完整的RELLO是您的最佳选择。这将使全局偏移表成为只读的,并在生成的可执行文件中将各种内部数据部分放在程序数据部分之前。 + +栈保护 + +将值放在堆栈上并验证其是否存在,以帮助防止缓冲区溢出攻击。 + +从不执行 (NX) + +也称为数据执行保护 (DEP),确保无法执行可执行文件的数据部分。 + +位置无关可执行文件 (PIE) + +生成一个独立于位置的可执行文件,这是 ASLR 所必需的。 + +地址空间布局随机化 (ASLR) + +这确保了代码和数据区域的放置都是随机的。当使用 PIE 构建可执行文件时,由内核启用(所有现代 Linux 内核都支持 ASLR)。 + +编译 QEMU 时,建议对 GCC 使用以下编译器选项: + +```shell +CFLAGS="-arch x86_64 -fstack-protector-all -Wstack-protector \ +--param ssp-buffer-size=4 -pie -fPIE -ftrapv -D_FORTIFY_SOURCE=2 -O2 \ +-Wl,-z,relro,-z,now" +``` + +我们建议在编译 QEMU 可执行文件后对其进行测试,以确保编译器强化正常工作。 + +大多数云部署不会手动构建软件,例如 QEMU。最好使用打包来确保该过程是可重复的,并确保最终结果可以轻松地部署在整个云中。下面的参考资料提供了有关将编译器强化选项应用于现有包的一些其他详细信息。 + +DEB 封装: + +硬化指南 + +RPM 包: + +如何创建 RPM 包 + +#### 安全加密虚拟化 + +安全加密虚拟化 (SEV) 是 AMD 的一项技术,它允许使用 VM 唯一的密钥对 VM 的内存进行加密。SEV 在 Train 版本中作为技术预览版提供,在某些基于 AMD 的机器上提供 KVM 客户机,用于评估技术。 + +nova 配置指南的 KVM 虚拟机管理程序部分包含配置计算机和虚拟机管理程序所需的信息,并列出了 SEV 的几个限制。 + +SEV 为正在运行的 VM 使用的内存中的数据提供保护。但是,虽然 SEV 与 OpenStack 集成的第一阶段支持虚拟机加密内存,但重要的是它不提供 SEV 固件提供的 `LAUNCH_MEASURE` or `LAUNCH_SECRET` 功能。这意味着受 SEV 保护的 VM 使用的数据可能会受到控制虚拟机监控程序的有动机的对手的攻击。例如,虚拟机监控程序计算机上的恶意管理员可以为具有后门和间谍软件的租户提供 VM 映像,这些后门和间谍软件能够窃取机密,或者替换 VNC 服务器进程以窥探发送到 VM 控制台或从 VM 控制台发送的数据,包括解锁全磁盘加密解决方案的密码。 + +为了减少恶意管理员未经授权访问数据的机会,使用 SEV 时应遵循以下安全做法: + +- VM 应使用完整磁盘加密解决方案。 +- 应在 VM 上使用引导加载程序密码。 + +此外,应将标准安全最佳做法用于 VM,包括以下内容: + +- VM 应得到良好的维护,包括定期进行安全扫描和修补,以确保 VM 持续保持强大的安全态势。 +- 与 VM 的连接应使用加密和经过身份验证的协议,例如 HTTPS 和 SSH。 +- 应考虑使用其他安全工具和流程,并将其用于适合数据敏感度级别的 VM。 + +#### 强制访问控制 + +编译器加固使攻击 QEMU 进程变得更加困难。但是,如果攻击者得逞,则需要限制攻击的影响。强制访问控制通过将 QEMU 进程上的权限限制为仅需要的权限来实现此目的。这可以通过使用 sVirt、SELinux 或 AppArmor 来实现。使用 sVirt 时,SELinux 配置为在单独的安全上下文下运行每个 QEMU 进程。AppArmor 可以配置为提供类似的功能。我们在以下 sVirt 和实例隔离部分中提供了有关 sVirt 和实例隔离的更多详细信息:SELinux 和虚拟化。 + +特定的 SELinux 策略可用于许多 OpenStack 服务。CentOS 用户可以通过安装 selinux-policy 源码包来查看这些策略。最新的策略出现在 Fedora 的 selinux-policy 存储库中。rawhide-contrib 分支包含以 `.te` 结尾的文件,例如 `cinder.te` ,这些文件可以在运行 SELinux 的系统上使用。 + +OpenStack 服务的 AppArmor 配置文件当前不存在,但 OpenStack-Ansible 项目通过将 AppArmor 配置文件应用于运行 OpenStack 服务的每个容器来处理此问题。 + +#### sVirt:SELinux 和虚拟化 + +凭借独特的内核级架构和国家安全局 (NSA) 开发的安全机制,KVM 为多租户提供了基础隔离技术。安全虚拟化 (sVirt) 技术的发展起源于 2002 年,是 SELinux 对现代虚拟化的应用。SELinux 旨在应用基于标签的分离控制,现已扩展为在虚拟机进程、设备、数据文件和代表它们执行操作的系统进程之间提供隔离。 + +OpenStack 的 sVirt 实现旨在保护虚拟机管理程序主机和虚拟机免受两个主要威胁媒介的侵害: + +虚拟机监控程序威胁 + +在虚拟机中运行的受损应用程序会攻击虚拟机监控程序以访问底层资源。例如,当虚拟机能够访问虚拟机监控程序操作系统、物理设备或其他应用程序时。此威胁向量存在相当大的风险,因为虚拟机监控程序上的入侵可能会感染物理硬件并暴露其他虚拟机和网段。 + +虚拟机(多租户)威胁 + +在 VM 中运行的受损应用程序会攻击虚拟机监控程序,以访问或控制另一个虚拟机及其资源。这是虚拟化特有的威胁向量,存在相当大的风险,因为大量虚拟机文件映像可能因单个应用程序中的漏洞而受到损害。这种虚拟网络攻击是一个主要问题,因为用于保护真实网络的管理技术并不直接适用于虚拟环境。 + +每个基于 KVM 的虚拟机都是一个由 SELinux 标记的进程,从而有效地在每个虚拟机周围建立安全边界。此安全边界由 Linux 内核监视和强制执行,从而限制虚拟机访问其边界之外的资源,例如主机数据文件或其他 VM。 + +无论虚拟机内运行的客户机操作系统如何,都会提供 sVirt 隔离。可以使用 Linux 或 Windows VM。此外,许多 Linux 发行版在操作系统中提供 SELinux,使虚拟机能够保护内部虚拟资源免受威胁。 + +#### 标签和类别 + +基于 KVM 的虚拟机实例使用其自己的 SELinux 数据类型进行标记,称为 `svirt_image_t` 。内核级保护可防止未经授权的系统进程(如恶意软件)操纵磁盘上的虚拟机映像文件。关闭虚拟机电源后,映像的存储 `svirt_image_t` 方式如下所示: + +```shell +system_u:object_r:svirt_image_t:SystemLow image1 +system_u:object_r:svirt_image_t:SystemLow image2 +system_u:object_r:svirt_image_t:SystemLow image3 +system_u:object_r:svirt_image_t:SystemLow image4 +``` + +该 `svirt_image_t` 标签唯一标识磁盘上的图像文件,允许 SELinux 策略限制访问。当基于 KVM 的计算映像通电时,sVirt 会将随机数字标识符附加到映像中。sVirt 能够为每个虚拟机管理程序节点最多分配 524,288 个虚拟机的数字标识符,但大多数 OpenStack 部署极不可能遇到此限制。 + +此示例显示了 sVirt 类别标识符: + +```shell +system_u:object_r:svirt_image_t:s0:c87,c520 image1 +system_u:object_r:svirt_image_t:s0:419,c172 image2 +``` + +#### SELinux 用户和角色 + +SELinux 管理用户角色。可以通过 `-Z` 标志或使用 semanage 命令查看这些内容。在虚拟机管理程序上,只有管理员才能访问系统,并且应该围绕管理用户和系统上的任何其他用户具有适当的上下文。有关更多信息,请参阅 SELinux 用户文档。 + +#### 布尔值 + +为了减轻管理 SELinux 的管理负担,许多企业 Linux 平台利用 SELinux 布尔值来快速改变 sVirt 的安全态势。 + +基于 Red Hat Enterprise Linux 的 KVM 部署使用以下 sVirt 布尔值: + +| sVirt SELinux 布尔值 | 描述 | +| -------------------- | ----------------------------------- | +| virt_use_common | 允许 virt 使用串行或并行通信端口。 | +| virt_use_fusefs | 允许 virt 读取 FUSE 挂载的文件。 | +| virt_use_nfs | 允许 virt 管理 NFS 挂载的文件。 | +| virt_use_samba | 允许 virt 管理 CIFS 挂载的文件。 | +| virt_use_sanlock | 允许受限的虚拟访客与 sanlock 交互。 | +| virt_use_sysfs | 允许 virt 管理设备配置 (PCI)。 | +| virt_use_usb | 允许 virt 使用 USB 设备。 | +| virt_use_xserver | 允许虚拟机与 X Window 系统交互。 | + +### 加固计算部署 + +任何OpenStack部署的主要安全问题之一是围绕敏感文件(如 `nova.conf` 文件)的安全性和控制。此配置文件通常包含在 `/etc` 目录中,包含许多敏感选项,包括配置详细信息和服务密码。应为所有此类敏感文件授予严格的文件级权限,并通过文件完整性监视 (FIM) 工具(如 iNotify 或 Samhain)监视更改。这些实用程序将获取处于已知良好状态的目标文件的哈希值,然后定期获取该文件的新哈希值,并将其与已知良好的哈希值进行比较。如果发现警报被意外修改,则可以创建警报。 + +可以检查文件的权限,我移动到文件所在的目录并运行 ls -lh 命令。这将显示有权访问文件的权限、所有者和组,以及其他信息,例如上次修改文件的时间和创建时间。 + +该 `/var/lib/nova` 目录用于保存有关给定计算主机上的实例的详细信息。此目录也应被视为敏感目录,并具有严格强制执行的文件权限。此外,应定期备份它,因为它包含与该主机关联的实例的信息和元数据。 + +如果部署不需要完整的虚拟机备份,建议排除该 `/var/lib/nova/instances` 目录,因为它的大小将与该节点上运行的每个 VM 的总空间一样大。如果部署确实需要完整 VM 备份,则需要确保成功备份此目录。 + +监视是 IT 基础结构的关键组件,我们建议监视和分析计算日志文件,以便可以创建有意义的警报。 + +#### OpenStack 漏洞管理团队 + +我们建议在发布安全问题和建议时及时了解它们。OpenStack 安全门户是一个中央门户,可以在这里协调建议、通知、会议和流程。此外,OpenStack 漏洞管理团队 (VMT) 门户通过将 Bug 标记为“此 bug 是安全漏洞”来协调 OpenStack 项目内的补救措施,以及调查负责任地(私下)向 VMT 披露的报告 bug 的过程。VMT 流程页面中概述了更多详细信息,并生成了 OpenStack 安全公告 (OSSA)。此 OSSA 概述了问题和修复程序,并链接到原始错误和补丁托管位置。 + +#### OpenStack 安全注意事项 + +报告的安全漏洞被发现是配置错误的结果,或者不是严格意义上的 OpenStack 的一部分,这些漏洞将被起草到 OpenStack 安全说明 (OSSN) 中。这些问题包括配置问题,例如确保身份提供程序映射以及非 OpenStack,但关键问题(例如影响 OpenStack 使用的平台的 Bashbug/Ghost 或 Venom 漏洞)。当前的 OSSN 集位于安全说明 wiki 中。 + +#### OpenStack-dev 邮件列表 + +所有错误、OSSA 和 OSSN 都通过 openstack-discuss 邮件列表公开发布,主题行中带有 [security] 主题。我们建议订阅此列表以及邮件过滤规则,以确保不会遗漏 OSSN、OSSA 和其他重要公告。openstack-discuss 邮件列表通过 OpenStack Development Mailing List 进行管理。openstack-discuss 使用《项目团队指南》中定义的标记。 + +#### 虚拟机管理程序邮件列表 + +在实施OpenStack时,核心决策之一是使用哪个虚拟机管理程序。我们建议您了解与您选择的虚拟机管理程序相关的公告。以下是几个常见的虚拟机管理程序安全列表: + +Xen: + + + +VMWare: + + + +其他(KVM 等): + + + +### 漏洞意识 + +#### OpenStack 漏洞管理团队 + +我们建议在发布安全问题和建议时及时了解它们。OpenStack 安全门户是一个中央门户,可以在这里协调建议、通知、会议和流程。此外,OpenStack 漏洞管理团队 (VMT) 门户协调 OpenStack 内部的补救措施,以及调查负责任地(私下)向 VMT 披露的报告错误的过程,方法是将错误标记为“此错误是安全漏洞”。VMT 流程页面中概述了更多详细信息,并生成了 OpenStack 安全公告 (OSSA)。此 OSSA 概述了问题和修复程序,并链接到原始错误和补丁托管位置。 + +#### OpenStack 安全注意事项 + +报告的安全漏洞被发现是配置错误的结果,或者不是严格意义上的 OpenStack 的一部分,将被起草到 OpenStack 安全说明 (OSSN) 中。这些问题包括配置问题,例如确保身份提供商映射,以及非 OpenStack 但关键的问题,例如影响 OpenStack 使用的平台的 Bashbug/Ghost 或 Venom 漏洞。当前的 OSSN 集位于安全说明 wiki 中。 + +#### OpenStack-discuss 邮件列表 + +所有 bug、OSSA 和 OSSN 都通过 openstack-discuss 邮件列表公开发布,主题行中包含 [security] 主题。我们建议订阅此列表以及邮件过滤规则,以确保不会遗漏 OSSN、OSSA 和其他重要公告。openstack-discuss 邮件列表通过 进行管理。openstack-discuss 使用《项目团队指南》中定义的标记。 + +#### 虚拟机管理程序邮件列表 + +在实施OpenStack时,核心决策之一是使用哪个虚拟机管理程序。我们建议您了解与您选择的虚拟机管理程序相关的公告。以下是几个常见的虚拟机管理程序安全列表: + +- Xen: + + + +- VMWare: + + + +- 其他(KVM 等): + + + +### 如何选择虚拟控制台 + +云架构师需要做出的有关计算服务配置的一个决定是使用 VNC 还是 SPICE。 + +#### 虚拟网络计算机 (VNC) + +OpenStack 可以配置为使用虚拟网络计算机 (VNC) 协议为租户和管理员提供对实例的远程桌面控制台访问。 + +##### 功能 + +1. OpenStack Dashboard (horizon) 可以使用 HTML5 noVNC 客户端直接在网页上为实例提供 VNC 控制台。这要求 `nova-novncproxy` 服务从公用网络桥接到管理网络。 +2. `nova` 命令行实用程序可以返回 VNC 控制台的 URL,以供 nova Java VNC 客户端访问。这要求 `nova-xvpvncproxy` 服务从公用网络桥接到管理网络。 + +##### 安全注意事项 + +1. 默认情况下, `nova-novncproxy` 和 `nova-xvpvncproxy` 服务会打开经过令牌身份验证的面向公众的端口。 +2. 默认情况下,远程桌面流量未加密。可以启用 TLS 来加密 VNC 流量。请参阅 TLS 和 SSL 简介以获取适当的建议。 + +##### 参考书目 + +1. blog.malchuk.ru, OpenStack VNC Security. 2013. [Secure Connections to VNC ports](http://blog.malchuk.ru/2013/05/21/47) + blog.malchuk.ru,OpenStack VNC 安全性。2013. 与 VNC 端口的安全连接 +2. OpenStack Mailing List, [OpenStack] nova-novnc SSL configuration - Havana. 2014. [OpenStack nova-novnc SSL Configuration](http://lists.openstack.org/pipermail/openstack/2014-February/005357.html) + OpenStack 邮件列表,[OpenStack] nova-novnc SSL 配置 - 哈瓦那。2014. OpenStack nova-novnc SSL配置 +3. Redhat.com/solutions,在 OpenStack 中使用 SSL 加密 nova-novacproxy。2014. OpenStack nova-novncproxy SSL加密 + +#### 独立计算环境的简单协议 (SPICE) + +作为 VNC 的替代方案,OpenStack 使用独立计算环境的简单协议 (SPICE) 协议提供对客户机虚拟机的远程桌面访问。 + +##### 功能 + +1. OpenStack Dashboard (horizon) 直接在实例网页上支持 SPICE。这需要服务 `nova-spicehtml5proxy` 。 +2. nova 命令行实用程序可以返回 SPICE 控制台的 URL,以供 SPICE-html 客户端访问。 + +##### 限制 + +1. 尽管 SPICE 与 VNC 相比具有许多优势,但 spice-html5 浏览器集成目前不允许管理员利用这些优势。为了利用 多显示器、USB 直通等 SPICE 功能,我们建议管理员在管理网络中使用独立的 SPICE 客户端。 + +##### 安全注意事项 + +1. 默认情况下,该 `nova-spicehtml5proxy` 服务会打开经过令牌身份验证的面向公众的端口。 +2. 功能和集成仍在不断发展。我们将在下一个版本中访问这些功能并提出建议。 +3. 与 VNC 的情况一样,目前我们建议从管理网络使用 SPICE,此外还限制使用少数人。 + +##### 参考书目 + +1. OpenStack 管理员指南。SPICE控制台。SPICE控制台。 +2. bugzilla.redhat.com, Bug 913607 - RFE: 支持通过 websockets 隧道传输 SPICE。2013. RedHat 错误913607。 + +### 检查表 + +#### Check-Compute-01:配置文件的用户/组所有权是否设置为 root/nova? + +配置文件包含组件平稳运行所需的关键参数和信息。如果非特权用户有意或无意地修改或删除任何参数或文件本身,则会导致严重的可用性问题,从而导致拒绝向其他最终用户提供服务。此类关键配置文件的用户所有权必须设置为 `nova` , `root` 并且组所有权必须设置为 。此外,包含目录应具有相同的所有权,以确保正确拥有新文件。 + +运行以下命令: + +```shell +$ stat -L -c "%U %G" /etc/nova/nova.conf | egrep "root nova" +$ stat -L -c "%U %G" /etc/nova/api-paste.ini | egrep "root nova" +$ stat -L -c "%U %G" /etc/nova/policy.json | egrep "root nova" +$ stat -L -c "%U %G" /etc/nova/rootwrap.conf | egrep "root nova" +$ stat -L -c "%U %G" /etc/nova | egrep "root nova" +``` + +通过:如果所有这些配置文件的用户和组所有权分别设置为 `root` 和 `nova` 。上述命令显示 的 `root nova` 输出。 + +失败:如果上述命令未返回任何输出,则用户和组所有权可能已设置为除 以外的任何用户或除 `nova` 以外的 `root` 任何组。 + +推荐于:计算。 + +#### Check-Compute-02:是否为配置文件设置了严格的权限? + +与前面的检查类似,我们建议为此类配置文件设置严格的访问权限。 + +运行以下命令: + +```shell +$ stat -L -c "%a" /etc/nova/nova.conf +$ stat -L -c "%a" /etc/nova/api-paste.ini +$ stat -L -c "%a" /etc/nova/policy.json +$ stat -L -c "%a" /etc/nova/rootwrap.conf +``` + +还可以进行更广泛的限制:如果包含目录设置为 750,则保证此目录中新创建的文件具有所需的权限。 + +通过:如果权限设置为 640 或更严格,或者包含目录设置为 750。640/750 的权限转换为所有者 r/w、组 r,而对其他人没有权限。例如,“u=rw,g=r,o=”。 + +**注意** + +```shell +如果 Check-Compute-01:配置文件的用户/组所有权是否设置为 root/nova?权限设置为 640,root 具有读/写访问权限,nova 具有对这些配置文件的读取访问权限。也可以使用以下命令验证访问权限。仅当此命令支持 ACL 时,它才在您的系统上可用。 +``` + +```shell +$ getfacl --tabular -a /etc/nova/nova.conf +getfacl: Removing leading '/' from absolute path names +# file: etc/nova/nova.conf +USER root rw- +GROUP nova r-- +mask r-- +other --- +``` + +失败:如果权限未设置为至少 640/750。 + +推荐于:计算。 + +#### Check-Compute-03:Keystone 是否用于身份验证? + +**注意** + +```shell +此项仅适用于 OpenStack 版本 Rocky 及之前版本,因为 `auth_strategy` Stein 中已弃用。 +``` + +OpenStack 支持各种身份验证策略,如 noauth 和 keystone。如果使用 noauth 策略,那么用户无需任何身份验证即可与 OpenStack 服务进行交互。这可能是一个潜在的风险,因为攻击者可能会获得对 OpenStack 组件的未经授权的访问。我们强烈建议所有服务都必须使用其服务帐户通过 keystone 进行身份验证。 + +在Ocata之前: + +通过:如果 section in 下的参数 `auth_strategy` 设置为 `keystone` 。 `[DEFAULT]` `/etc/nova/nova.conf` + +失败:如果 section 下的 `[DEFAULT]` 参数 `auth_strategy` 值设置为 `noauth` 或 `noauth2` 。 + +在Ocata之后: + +通过:如果 under `[api]` 或 `[DEFAULT]` section in `/etc/nova/nova.conf` 的参数 `auth_strategy` 值设置为 `keystone` 。 + +失败:如果 or `[DEFAULT]` 部分下的 `[api]` 参数 `auth_strategy` 值设置为 `noauth` 或 `noauth2` 。 + +#### Check-Compute-04:是否使用安全协议进行身份验证? + +OpenStack 组件使用各种协议相互通信,通信可能涉及敏感或机密数据。攻击者可能会尝试窃听频道以访问敏感信息。所有组件必须使用安全通信协议相互通信。 + +通过:如果 section in `/etc/nova/nova.conf` 下的参数值设置为 Identity API 端点开头, `https://` 并且 same `/etc/nova/nova.conf` 中同一 `[keystone_authtoken]` 部分下的 `[keystone_authtoken]` 参数 `www_authenticate_uri` `insecure` 值设置为 `False` 。 + +失败:如果 in `/etc/nova/nova.conf` 部分下的 `[keystone_authtoken]` 参数 `www_authenticate_uri` 值未设置为以 开头的身份 API 端点, `https://` 或者同一 `/etc/nova/nova.conf` 部分中的参数 `insecure` `[keystone_authtoken]` 值设置为 `True` 。 + +#### Check-Compute-05:Nova 与 Glance 的通信是否安全? + +OpenStack 组件使用各种协议相互通信,通信可能涉及敏感或机密数据。攻击者可能会尝试窃听频道以访问敏感信息。所有组件必须使用安全通信协议相互通信。 + +通过:如果 section in 下的参数值设置为 `False` ,并且 section in `/etc/nova/nova.conf` `/etc/nova/nova.conf` 下的 `[glance]` `[glance]` 参数 `api_insecure` `api_servers` 值设置为以 `https://` 开头的值。 + +失败:如果 in `/etc/nova/nova.conf` 节下的参数值设置为 `True` ,或者 in `/etc/nova/nova.conf` 节下的 `[glance]` `[glance]` 参数 `api_insecure` `api_servers` 值设置为不以 `https://` 开头的值。 + +## 块存储 + +OpenStack Block Storage (cinder) 是一项服务,它提供软件(服务和库)来自助管理持久性块级存储设备。这将创建对块存储资源的按需访问,以便与 OpenStack 计算 (nova) 实例一起使用。通过将块存储池虚拟化到各种后端存储设备(可以是软件实现或传统硬件存储产品),通过抽象创建软件定义存储。其主要功能是管理块设备的创建、附加和分离。消费者不需要知道后端存储设备的类型或它的位置。 + +计算实例通过行业标准存储协议(如 iSCSI、以太网 ATA 或光纤通道)存储和检索块存储。这些资源通过 OpenStack 原生标准 HTTP RESTful API 进行管理和配置。有关 API 的更多详细信息,请参阅 OpenStack 块存储文档。 + +- 卷擦除 +- 检查表 + - Check-Block-01:配置文件的用户/组所有权是否设置为 root/cinder? + - Check-Block-02:是否为配置文件设置了严格的权限? + - Check-Block-03:Keystone 是否用于身份验证? + - Check-Block-04:是否启用了 TLS 进行身份验证? + - Check-Block-05:cinder 是否通过 TLS 与 nova 通信? + - Check-Block-06:cinder 是否通过 TLS 与 glance 通信? + - Check-Block-07: NAS 是否在安全的环境中运行? + - Check-Block-08:请求正文的最大大小是否设置为默认值 (114688)? + - Check-Block-09:是否启用了卷加密功能? + +**注意** + +```shell +虽然本章目前对具体指南的介绍很少,但预计将遵循标准的强化实践。本节将扩展相关信息。 +``` + +### 卷擦除 + +有几种方法可以擦除块存储设备。传统的方法是将 `lvm_type` 设置为 `thin` ,如果使用 LVM 后端,则使用 `volume_clear` 该参数。或者,如果使用卷加密功能,则在删除卷加密密钥时不需要卷擦除。有关设置的详细信息,请参阅卷加密部分中的 OpenStack 配置参考文档,以及有关密钥删除的 Castellan 使用文档 + +**注意** + +```shell +在较旧的 OpenStack 版本中, `lvm_type=default` 用于表示擦除。虽然此方法仍然有效,但 `lvm_type=default` 不建议用于设置安全删除。 +``` + +该 `volume_clear` 参数可以设置为 `zero` 。该 `zero` 参数将向设备写入一次零传递。 + +有关该 `lvm_type` 参数的更多信息,请参阅 cinder 项目文档的精简置备中的 LVM 和超额订阅部分。 + +有关该 `volume_clear` 参数的详细信息,请参阅 cinder 项目文档的 Cinder 配置选项部分。 + +#### 检查表 + +#### Check-Block-01:配置文件的用户/组所有权是否设置为 root/cinder? + +配置文件包含组件平稳运行所需的关键参数和信息。如果非特权用户有意或无意地修改或删除任何参数或文件本身,则会导致严重的可用性问题,从而导致拒绝向其他最终用户提供服务。因此,此类关键配置文件的用户所有权必须设置为 root,组所有权必须设置为 cinder。此外,包含目录应具有相同的所有权,以确保正确拥有新文件。 + +运行以下命令: + +```shell +$ stat -L -c "%U %G" /etc/cinder/cinder.conf | egrep "root cinder" +$ stat -L -c "%U %G" /etc/cinder/api-paste.ini | egrep "root cinder" +$ stat -L -c "%U %G" /etc/cinder/policy.json | egrep "root cinder" +$ stat -L -c "%U %G" /etc/cinder/rootwrap.conf | egrep "root cinder" +$ stat -L -c "%U %G" /etc/cinder | egrep "root cinder" +``` + +通过:如果所有这些配置文件的用户和组所有权分别设置为 root 和 cinder。上面的命令显示了根煤渣的输出。 + +失败:如果上述命令未返回任何输出,因为用户和组所有权可能已设置为除 root 以外的任何用户或除 cinder 以外的任何组。 + +#### Check-Block-02:是否为配置文件设置了严格的权限? + +与前面的检查类似,我们建议为此类配置文件设置严格的访问权限。 + +运行以下命令: + +```shell +$ stat -L -c "%a" /etc/cinder/cinder.conf +$ stat -L -c "%a" /etc/cinder/api-paste.ini +$ stat -L -c "%a" /etc/cinder/policy.json +$ stat -L -c "%a" /etc/cinder/rootwrap.conf +$ stat -L -c "%a" /etc/cinder +``` + +还可以进行更广泛的限制:如果包含目录设置为 750,则保证此目录中新创建的文件具有所需的权限。 + +通过:如果权限设置为 640 或更严格,或者包含目录设置为 750。640/750 的权限转换为所有者 r/w、组 r,而对其他人没有权限,即“u=rw,g=r,o=”。请注意,使用 Check-Block-01 时:配置文件的用户/组所有权是否设置为 root/cinder?权限设置为 640,root 具有读/写访问权限,cinder 具有对这些配置文件的读取访问权限。也可以使用以下命令验证访问权限。仅当此命令支持 ACL 时,它才在您的系统上可用。 + +```shell +$ getfacl --tabular -a /etc/cinder/cinder.conf +getfacl: Removing leading '/' from absolute path names +# file: etc/cinder/cinder.conf +USER root rw- +GROUP cinder r-- +mask r-- +other --- +``` + +失败:如果权限未设置为至少 640。 + +#### Check-Block-03:Keystone 是否用于身份验证? + +**注意** + +```shell +此项仅适用于 OpenStack 版本 Rocky 及之前版本,因为 `auth_strategy` Stein 中已弃用。 +``` + +OpenStack 支持各种身份验证策略,如 noauth、keystone 等。如果使用“noauth”策略,那么用户无需任何身份验证即可与OpenStack服务进行交互。这可能是一个潜在的风险,因为攻击者可能会获得对 OpenStack 组件的未经授权的访问。因此,我们强烈建议所有服务都必须使用其服务帐户通过 keystone 进行身份验证。 + +通过:如果 section in 下的参数 `auth_strategy` 设置为 `keystone` 。 `[DEFAULT]` `/etc/cinder/cinder.conf` + +失败:如果 section 下的 `[DEFAULT]` 参数 `auth_strategy` 值设置为 `noauth` 。 + +#### Check-Block-04:是否启用了 TLS 进行身份验证? + +OpenStack 组件使用各种协议相互通信,通信可能涉及敏感/机密数据。攻击者可能会尝试窃听频道以访问敏感信息。因此,所有组件都必须使用安全的通信协议相互通信。 + +通过:如果 section in `/etc/cinder/cinder.conf` 下的参数值设置为 Identity API 端点开头, `https://` 并且 same `/etc/cinder/cinder.conf` 中同一 `[keystone_authtoken]` 部分下的 `[keystone_authtoken]` 参数 `www_authenticate_uri` `insecure` 值设置为 `False` 。 + +失败:如果 in `/etc/cinder/cinder.conf` 部分下的 `[keystone_authtoken]` 参数 `www_authenticate_uri` 值未设置为以 开头的身份 API 端点, `https://` 或者同一 `/etc/cinder/cinder.conf` 部分中的参数 `insecure` `[keystone_authtoken]` 值设置为 `True` 。 + +#### Check-Block-05:cinder 是否通过 TLS 与 nova 通信? + +OpenStack 组件使用各种协议相互通信,通信可能涉及敏感/机密数据。攻击者可能会尝试窃听频道以访问敏感信息。因此,所有组件都必须使用安全的通信协议相互通信。 + +通过:如果 section in 下的参数 `nova_api_insecure` 设置为 `False` 。 `[DEFAULT]` `/etc/cinder/cinder.conf` + +失败:如果 section in 下的参数 `nova_api_insecure` 设置为 `True` 。 `[DEFAULT]` `/etc/cinder/cinder.conf` + +#### Check-Block-06:cinder 是否通过 TLS 与 glance 通信? + +与之前的检查(Check-Block-05:cinder 是否通过 TLS 与 nova 通信?)类似,我们建议所有组件使用安全通信协议相互通信。 + +通过:如果 in 部分下的 `[DEFAULT]` 参数值设置为 `False` 并且参数 `glance_api_servers` `glance_api_insecure` 值设置为以 `https://` 开头 `/etc/cinder/cinder.conf` 的值。 + +失败:如果将 section in 下的参数值设置为 `True` 或参数 `glance_api_servers` `glance_api_insecure` 值设置为不以 `https://` 开头的值。 `[DEFAULT]` `/etc/cinder/cinder.conf` + +#### Check-Block-07: NAS 是否在安全的环境中运行? + +Cinder 支持 NFS 驱动程序,其工作方式与传统的块存储驱动程序不同。NFS 驱动程序实际上不允许实例在块级别访问存储设备。相反,文件是在 NFS 共享上创建的,并映射到模拟块储存设备的实例。Cinder 通过在创建 Cinder 卷时控制文件权限来支持此类文件的安全配置。Cinder 配置还可以控制是以 root 用户身份还是当前 OpenStack 进程用户身份运行文件操作。 + +通过:如果 section in 下的参数 `nas_secure_file_permissions` 设置为 `auto` 。 `[DEFAULT]` `/etc/cinder/cinder.conf` 如果设置为 `auto` ,则在 cinder 启动期间进行检查以确定是否存在现有的 cinder 卷,任何卷都不会将选项设置为 `True` ,并使用安全文件权限。检测现有卷会将选项设置为 `False` ,并使用当前不安全的方法来处理文件权限。如果 section in 下的参数 `nas_secure_file_operations` 设置为 `auto` 。 `[DEFAULT]` `/etc/cinder/cinder.conf` 当设置为“auto”时,在 cinder 启动期间进行检查以确定是否存在现有的 cinder 卷,任何卷都不会将选项设置为 `True` ,安全且不以 `root` 用户身份运行。对现有卷的检测会将选项设置为 `False` ,并使用当前方法以 `root` 用户身份运行操作。对于新安装,会编写一个“标记文件”,以便随后重新启动 cinder 将知道原始确定是什么。 + +失败:如果 section in 下的参数值设置为 `False` ,并且 section in `/etc/cinder/cinder.conf` `/etc/cinder/cinder.conf` 下的 `[DEFAULT]` `[DEFAULT]` 参数 `nas_secure_file_permissions` `nas_secure_file_operations` 值设置为 `False` 。 + +#### Check-Block-08:请求正文的最大大小是否设置为默认值 (114688)? + +如果未定义每个请求的最大正文大小,攻击者可以构建任意较大的osapi请求,导致服务崩溃,最终导致拒绝服务攻击。分配最大值可确保阻止任何恶意超大请求,从而确保服务的持续可用性。 + +通过:如果 section in 下的参数值设置为 `114688` `114688` ,或者 section in `/etc/cinder/cinder.conf` `/etc/cinder/cinder.conf` 下的 `[oslo_middleware]` `[DEFAULT]` 参数 `osapi_max_request_body_size` `max_request_body_size` 值设置为 。 + +失败:如果 section in 下的参数值未设置为 `114688` , `114688` 或者 section in `/etc/cinder/cinder.conf` `/etc/cinder/cinder.conf` 下的 `[oslo_middleware]` `[DEFAULT]` 参数 `osapi_max_request_body_size` `max_request_body_size` 值未设置为 。 + +#### Check-Block-09:是否启用了卷加密功能? + +未加密的卷数据使卷托管平台成为攻击者特别高价值的目标,因为它允许攻击者读取许多不同 VM 的数据。此外,物理存储介质可能会被窃取、重新装载和从另一台计算机访问。加密卷数据可以降低这些风险,并为卷托管平台提供深度防御。块存储 (cinder) 能够在将卷数据写入磁盘之前对其进行加密,因此建议开启卷加密功能。有关说明,请参阅 Openstack Cinder 服务配置文档的卷加密部分。 + +通过:如果 1) 设置了 in `[key_manager]` 部分下的参数值,2) 设置了 in 下的 `[key_manager]` 参数 `backend` `backend` 值,以及 3) 如果正确遵循了 `/etc/cinder/cinder.conf` `/etc/nova/nova.conf` 上述文档中的说明。 + +若要进一步验证,请在完成卷加密设置并为 LUKS 创建卷类型后执行这些步骤,如上述文档中所述。 + +1. 创建 VM: + + ```shell + $ openstack server create --image cirros-0.3.1-x86_64-disk --flavor m1.tiny TESTVM + ``` + +2. 创建加密卷并将其附加到 VM: + + ```shell + $ openstack volume create --size 1 --type LUKS 'encrypted volume' + $ openstack volume list + $ openstack server add volume --device /dev/vdb TESTVM 'encrypted volume' + ``` + +3. 在 VM 上,将一些文本发送到新附加的卷并同步它: + + ```shell + # echo "Hello, world (encrypted /dev/vdb)" >> /dev/vdb + # sync && sleep 2 + ``` + +4. 在托管 cinder 卷服务的系统上,同步以刷新 I/O 缓存,然后测试是否可以找到字符串: + + ```shell + # sync && sleep 2 + # strings /dev/stack-volumes/volume-* | grep "Hello" + ``` + +搜索不应返回写入加密卷的字符串。 + +失败:如果未设置 in 部分下的参数值,或者未设置 in `/etc/cinder/cinder.conf` `/etc/nova/nova.conf` 部分下的 `[key_manager]` `[key_manager]` 参数 `backend` `backend` 值,或者未正确遵循上述文档中的说明。 + +## 图像存储 + +OpenStack Image Storage (glance) 是一项服务,用户可以在其中上传和发现旨在与其他服务一起使用的数据资产。这目前包括图像和元数据定义。 + +映像服务包括发现、注册和检索虚拟机映像。Glance 有一个 RESTful API,允许查询 VM 映像元数据以及检索实际映像。 + +有关该服务的更多详细信息,请参阅 OpenStack Glance 文档。 + +- 检查表 + - Check-Image-01:配置文件的用户/组所有权是否设置为 root/glance? + - Check-Image-02:是否为配置文件设置了严格的权限? + - Check-Image-03:Keystone 是否用于身份验证? + - Check-Image-04:是否启用了 TLS 进行身份验证? + - Check-Image-05:是否阻止了屏蔽端口扫描? + +**注意** + +```shell +虽然本章目前对具体指南的介绍很少,但预计将遵循标准的强化实践。本节将扩展相关信息。 +``` + +### 检查表 + +#### Check-Image-01:配置文件的用户/组所有权是否设置为 root/glance? + +配置文件包含组件平稳运行所需的关键参数和信息。如果非特权用户有意或无意地修改或删除任何参数或文件本身,则会导致严重的可用性问题,从而导致拒绝向其他最终用户提供服务。因此,必须将此类关键配置文件的用户所有权设置为 `glance` , `root` 并且必须将组所有权设置为 。此外,包含目录应具有相同的所有权,以确保正确拥有新文件。 + +运行以下命令: + +```shell +$ stat -L -c "%U %G" /etc/glance/glance-api-paste.ini | egrep "root glance" +$ stat -L -c "%U %G" /etc/glance/glance-api.conf | egrep "root glance" +$ stat -L -c "%U %G" /etc/glance/glance-cache.conf | egrep "root glance" +$ stat -L -c "%U %G" /etc/glance/glance-manage.conf | egrep "root glance" +$ stat -L -c "%U %G" /etc/glance/glance-registry-paste.ini | egrep "root glance" +$ stat -L -c "%U %G" /etc/glance/glance-registry.conf | egrep "root glance" +$ stat -L -c "%U %G" /etc/glance/glance-scrubber.conf | egrep "root glance" +$ stat -L -c "%U %G" /etc/glance/glance-swift-store.conf | egrep "root glance" +$ stat -L -c "%U %G" /etc/glance/policy.json | egrep "root glance" +$ stat -L -c "%U %G" /etc/glance/schema-image.json | egrep "root glance" +$ stat -L -c "%U %G" /etc/glance/schema.json | egrep "root glance" +$ stat -L -c "%U %G" /etc/glance | egrep "root glance" +``` + +通过:如果所有这些配置文件的用户和组所有权分别设置为 root 和 glance。上面的命令显示了 root glance 的输出。 + +失败:如果上述命令不返回任何输出。 + +#### Check-Image-02:是否为配置文件设置了严格的权限? + +与前面的检查类似,我们建议您为此类配置文件设置严格的访问权限。 + +运行以下命令: + +```shell +$ stat -L -c "%a" /etc/glance/glance-api-paste.ini +$ stat -L -c "%a" /etc/glance/glance-api.conf +$ stat -L -c "%a" /etc/glance/glance-cache.conf +$ stat -L -c "%a" /etc/glance/glance-manage.conf +$ stat -L -c "%a" /etc/glance/glance-registry-paste.ini +$ stat -L -c "%a" /etc/glance/glance-registry.conf +$ stat -L -c "%a" /etc/glance/glance-scrubber.conf +$ stat -L -c "%a" /etc/glance/glance-swift-store.conf +$ stat -L -c "%a" /etc/glance/policy.json +$ stat -L -c "%a" /etc/glance/schema-image.json +$ stat -L -c "%a" /etc/glance/schema.json +$ stat -L -c "%a" /etc/glance +``` + +还可以进行更广泛的限制:如果包含目录设置为 750,则保证此目录中新创建的文件具有所需的权限。 + +通过:如果权限设置为 640 或更严格,或者包含目录设置为 750。640/750 的权限转换为所有者 r/w、组 r,而对其他人没有权限。例如, `u=rw,g=r,o=` . + +**注意** + +```shell +使用 Check-Image-01: Devices / Group Ownership of config files 是否设置为 root/glance?,权限设置为 640,则 root 具有读/写访问权限,glance 具有对这些配置文件的读取访问权限。也可以使用以下命令验证访问权限。仅当此命令支持 ACL 时,它才在您的系统上可用。 +``` + +```shell +$ getfacl --tabular -a /etc/glance/glance-api.conf +getfacl: Removing leading '/' from absolute path names +# file: /etc/glance/glance-api.conf +USER root rw- +GROUP glance r-- +mask r-- +other --- +``` + +失败:如果权限未设置为至少 640。 + +#### Check-Image-03:Keystone 是否用于身份验证? + +**注意** + +```shell +此项仅适用于 OpenStack 版本 Rocky 及之前版本,因为 `auth_strategy` Stein 中已弃用。 +``` + +OpenStack 支持各种身份验证策略,包括 noauth 和 keystone。如果使用该 `noauth` 策略,则用户无需任何身份验证即可与 OpenStack 服务进行交互。这可能是一个潜在的风险,因为攻击者可能会获得对 OpenStack 组件的未经授权的访问。我们强烈建议所有服务都必须使用其服务帐户通过 keystone 进行身份验证。 + +通过:如果 section in 下的参数值设置为 , `keystone` 并且 section in `/etc/glance/glance-api.conf` `/etc/glance /glance-registry.conf` 下的 `[DEFAULT]` `[DEFAULT]` 参数 `auth_strategy` `auth_strategy` 值设置为 `keystone` 。 + +失败:如果 section in 下的参数值设置为 `noauth` 或 section in `/etc/glance/glance-api.conf` `/etc/glance/glance- registry.conf` 下的 `[DEFAULT]` `[DEFAULT]` 参数 `auth_strategy` `auth_strategy` 值设置为 `noauth` 。 + +#### Check-Image-04:是否启用了 TLS 进行身份验证? + +OpenStack 组件使用各种协议相互通信,通信可能涉及敏感或机密数据。攻击者可能会尝试窃听频道以访问敏感信息。所有组件必须使用安全的通信协议相互通信。 + +通过:如果 section in 下的参数值设置为以 开头的 Identity API 端点 `https://` ,并且该参数 `insecure` `www_authenticate_uri` 的值位于 same `/etc/glance/glance-registry.conf` 中的同一 `[keystone_authtoken]` 部分下,则设置为 `False` 。 `[keystone_authtoken]` `/etc/glance/glance-api.conf` + +失败:如果 中的 `/etc/glance/glance-api.conf` 部分下的 `[keystone_authtoken]` 参数 `www_authenticate_uri` 值未设置为以 `https://` 开头的标识 API 端点,或者同一 `/etc/glance/glance-api.conf` 部分中的参数 `insecure` `[keystone_authtoken]` 值设置为 `True` 。 + +#### Check-Image-05:是否阻止了屏蔽端口扫描? + +Glance 提供的映像服务 API v1 中的 `copy_from` 功能可允许攻击者执行屏蔽的网络端口扫描。如果启用了 v1 API,则应将此策略设置为受限值。 + +通过:如果参数 `copy_from` in `/etc/glance/policy.json` 的值设置为受限值,例如 `role:admin` . + +失败:未设置参数 `copy_from` in `/etc/glance/policy.json` 的值。 + +## 共享文件系统 + +共享文件系统服务(manila)提供了一组服务,用于管理多租户云环境中的共享文件系统。它类似于OpenStack通过OpenStack块存储服务(cinder)项目提供基于块的存储管理的方式。使用共享文件系统服务,您可以创建共享文件系统并管理其属性,例如可见性、可访问性和使用配额。 + +共享文件系统服务适用于使用以下共享文件系统协议的各种存储提供程序:NFS、CIFS、GlusterFS 和 HDFS。 + +共享文件系统服务的用途与 Amazon Elastic File System (EFS) 相同。 + +- 介绍 + - 一般安全信息 +- 网络和安全模型 + - 共享后端模式 + - 扁平化网络与分段化网络 + - 网络插件 +- 安全服务 + - 安全服务简介 + - 安全服务管理 +- 共享访问控制 +- 共享类型访问控制 +- 政策 +- 检查表 + - Check-Shared-01:配置文件的用户/组所有权是否设置为 root/manila? + - Check-Shared-02:是否为配置文件设置了严格的权限? + - Check-Shared-03:OpenStack Identity 是否用于身份验证? + - Check-Shared-04:是否启用了 TLS 进行身份验证? + - Check-Shared-05:共享文件系统是否通过 TLS 与计算联系? + - Check-Shared-06:共享文件系统是否通过 TLS 与网络联系? + - Check-Shared-07:共享文件系统是否通过 TLS 与块存储联系? + - Check-Shared-08:请求正文的最大大小是否设置为默认值 (114688)? + +### 介绍 + +共享文件系统服务(马尼拉)旨在在单节点或跨多个节点运行。共享文件系统服务由四个主要服务组成,它们类似于块存储服务: + +- `manila-api` +- `manila-scheduler` +- `manila-share` +- `manila-data` + +manila-api + +提供稳定 RESTful API 的服务。该服务在整个共享文件系统服务中对请求进行身份验证和路由。有 python-manilaclient 可以与 API 交互。有关共享文件系统 API 的更多详细信息,请参阅 OpenStack 共享文件系统 API。 + +manila-share + +负责管理共享文件服务设备,特别是后端设备。 + +manila-scheduler + +负责安排请求并将其路由到相应的 `manila-share` 服务。它通过选择一个后端,同时过滤除一个后端之外的所有后端来实现这一点。 + +manila-data + +此服务负责管理数据操作,如果不单独处理,可能需要很长时间才能完成,并阻止其他服务。 + +共享文件系统服务使用基于 SQL 的中央数据库,该数据库由系统中的所有共享文件系统服务共享。它可以使用 ORM SQLALcvery 支持的任何 SQL 方言,但仅使用 MySQL 和 PostgreSQL 数据库进行测试。 + +使用 SQL,共享文件系统服务类似于其他 OpenStack 服务,可以与任何 OpenStack 部署一起使用。有关 API 的更多详细信息,请参阅 OpenStack 共享文件系统 API 说明。有关 CLI 用法和配置的更多详细信息,请参阅共享文件系统云管理指南。 + +下图中,您可以看到共享文件系统服务的不同部分如何相互交互。 + +![../_images/manila-intro.png](https://docs.openstack.org/security-guide/_images/manila-intro.png) + +除了已经描述的服务之外,您还可以在图像上看到另外两个实体: `python-manilaclient` 和 `storage controller` 。 + +python-manilaclient + +命令行界面,用于通过 `manila-api` 与共享文件系统服务进行交互,以及用于以编程方式与共享文件系统服务交互的 Python 模块。 + +Storage controller + +通常是一个金属盒,带有旋转磁盘、以太网端口和某种软件,允许网络客户端在磁盘上读取和写入文件。还有一些在任意硬件上运行的纯软件存储控制器,群集控制器可能允许多个物理设备显示为单个存储控制器,或纯虚拟存储控制器。 + +共享是远程的、可装载的文件系统。您可以一次将共享装载到多个主机,也可以由多个用户从多个主机访问共享。 + +共享文件系统服务可以使用不同的网络类型:扁平网络、VLAN、VXLAN 或 GRE,并支持分段网络。此外,还有不同的网络插件,它们提供了与 OpenStack 提供的网络服务的各种集成方法。 + +不同供应商创建了大量共享驱动程序,这些驱动程序支持不同的硬件存储解决方案,例如 NetApp 集群模式 Data ONTAP ( cDOT )驱动程序,华为 NAS 驱动程序或 GlusterFS 驱动程序。每个共享驱动程序都是一个 Python 类,可以为后端设置并在后端运行以管理共享操作,其中一些操作可能是特定于供应商的。后端是 manila-share 服务的一个实例。 + +客户端用于身份验证和授权的配置数据可以由安全服务存储。可以配置和使用 LDAP、Kerberos 或 Microsoft Active Directory 身份验证服务等协议。 + +除非未在 `policy.json` 中显式更改,否则管理员或拥有共享的租户都能够管理对共享的访问。访问管理是通过创建访问规则来完成的,该规则通过 IP 地址、用户、组或 TLS 证书进行身份验证。可用的身份验证方法取决于您配置和使用的共享驱动程序和安全服务。 + +**注意** + +```shell +不同的驱动程序支持不同的访问选项,具体取决于使用的共享文件系统协议。支持的共享文件系统协议包括 NFS、CIFS、GlusterFS 和 HDFS。例如,通用(块存储作为后端)驱动程序不支持用户和证书身份验证方法。它还不支持任何安全服务,例如 LDAP、Kerberos 或 Active Directory。有关不同驱动程序支持的功能的详细信息,请参阅马尼拉共享功能支持映射。 +``` + +作为管理员,您可以创建共享类型,使计划程序能够在创建共享之前筛选后端。共享类型具有额外的规范,您可以为计划程序设置这些规范,以筛选和权衡后端,以便为请求创建共享的用户选择适当的共享类型。共享和共享类型可以创建为公共或私有。此可见性级别定义其他租户是否能够看到这些对象并对其进行操作。管理员可以为身份服务中的特定用户或租户添加对专用共享类型的访问权限。因此,您授予访问权限的用户可以看到可用的共享类型,并使用它们创建共享。 + +不同用户及其角色的 API 调用权限由策略决定,就像在其他 OpenStack 服务中一样。 + +标识服务可用于共享文件系统服务中的身份验证。请参阅“身份”部分中的身份服务安全性的详细信息。 + +#### 一般安全信息 + +与其他 OpenStack 项目类似,共享文件系统服务已注册到 Identity 服务,因此您可以使用 manila endpoints 命令查找共享服务 v1 和 v2 的 API 端点: + +```shell +$ manila endpoints ++-------------+-----------------------------------------+ +| manila | Value | ++-------------+-----------------------------------------+ +| adminURL | http://172.18.198.55:8786/v1/20787a7b...| +| region | RegionOne | +| publicURL | http://172.18.198.55:8786/v1/20787a7b...| +| internalURL | http://172.18.198.55:8786/v1/20787a7b...| +| id | 82cc5535aa444632b64585f138cb9b61 | ++-------------+-----------------------------------------+ + ++-------------+-----------------------------------------+ +| manilav2 | Value | ++-------------+-----------------------------------------+ +| adminURL | http://172.18.198.55:8786/v2/20787a7b...| +| region | RegionOne | +| publicURL | http://172.18.198.55:8786/v2/20787a7b...| +| internalURL | http://172.18.198.55:8786/v2/20787a7b...| +| id | 2e8591bfcac4405fa7e5dc3fd61a2b85 | ++-------------+-----------------------------------------+ +``` + +默认情况下,共享文件系统 API 服务仅侦听 `tcp6` 类型同时支持 IPv4 和 IPv6 的端口 `8786` 。 + +**注意** + +该端口是共享文件系统服务的默认端口 `8786` 。它可以更改为任何其他端口,但此更改也应在配置文件中的 选项中进行,该选项 `osapi_share_listen_port` 默认为 `8786` 。 + +在 `/etc/manila/` 目录中,您可以找到几个配置文件: + +```shell +api-paste.ini +manila.conf +policy.json +rootwrap.conf +rootwrap.d + +./rootwrap.d: +share.filters +``` + +建议您将共享文件系统服务配置为在非 root 服务帐户下运行,并更改文件权限,以便只有系统管理员才能修改它们。共享文件系统服务要求只有管理员才能写入配置文件,而服务只能通过其在组中的 `manila` 组成员身份读取它们。其他人一定无法读取这些文件,因为这些文件包含不同服务的管理员密码。 + +应用检查 Check-Shared-01:配置文件的用户/组所有权是否设置为 root/manila?和 Check-Shared-02:是否为配置文件设置了严格的权限?从清单中验证权限设置是否正确。 + +**注意** + +```shell +文件中的 manila-rootwrap 配置和文件中 `rootwrap.conf` `rootwrap.d/share.filters` 共享节点的 manila-rootwrap 命令过滤器应归 root 用户所有,并且只能由 root 用户写入。 +``` + +**建议** + +```shell +manila 配置文件 `manila.conf` 可以放置在任何位置。默认情况下,该路径 `/etc/manila/manila.conf` 是必需的。 +``` + +### 网络和安全模型 + +共享文件系统服务中的共享驱动程序是一个 Python 类,可以为后端设置并在其中运行以管理共享操作,其中一些操作是特定于供应商的。后端是 manila-share 服务的实例。共享文件系统服务中有许多由不同供应商创建的共享驱动程序。每个共享驱动程序都支持一种或多种后端模式:共享服务器和无共享服务器。管理员通过在配置文件中 `manila.conf` 指定模式来选择使用哪种模式。它使用了一个选项 `driver_handles_share_servers` 。 + +共享服务器模式可以配置为扁平网络,也可以配置分段网络。这取决于网络提供商。 + +如果您想使用不同的配置,则可以为不同的模式使用相同的硬件使用单独的驱动程序。根据选择的模式,管理员可能需要通过配置文件提供更多配置详细信息。 + +#### 共享后端模式 + +每个共享驱动程序至少支持一种可能的驱动程序模式: + +- 共享服务器模式 +- 无共享服务器模式 + +设置共享服务器模式或无共享服务器模式的 `manila.conf` 配置选项是 `driver_handles_share_servers` 选项。它指示驱动程序是自行处理共享服务器,还是期望共享文件系统服务执行此操作。 + +| 模式 | 配置选项 | 描述 | +| ------------ | ----------------------------------- | ------------------------------------------------------------ | +| 共享服务器 | driver_handles_share_servers =True | 共享驱动程序创建共享服务器并管理或处理共享服务器生命周期。 | +| 无共享服务器 | driver_handles_share_servers =False | 管理员(而不是共享驱动程序)使用某些网络接口(而不是共享服务器的存在)管理裸机存储。 | + +无共享服务器模式 + +在这种模式下,驱动程序基本上没有任何网络要求。假定由驱动程序管理的存储控制器具有所需的所有网络接口。共享文件系统服务将期望驱动程序直接设置共享,而无需事先创建任何共享服务器。此模式对应于某些现有驱动程序已在执行的操作,但它使管理员可以明确选择。在此模式下,共享创建时不需要共享网络,也不得提供共享网络。 + +**注意** + +```shell +在无共享服务器模式下,共享文件系统服务将假定所有租户都已可访问用于导出任何共享的网络接口。 +``` + +在无共享服务器模式下,共享驱动程序不处理存储生命周期。管理员应处理存储、网络接口和其他主机配置。在此模式下,管理员可以将存储设置为导出共享的主机。此模式的主要特征是存储不由共享文件系统服务处理。租户中的用户共享公共网络、主机、处理器和网络管道。如果管理员或代理之前配置的存储没有正确的平衡调整,它们可能会相互阻碍。在公有云中,所有网络容量可能都由一个客户端使用,因此管理员应注意不要发生这种情况。平衡调整可以通过任何方式完成,而不一定是使用 OpenStack 工具。 + +共享服务器模式 + +在此模式下,驱动程序能够创建共享服务器并将其插入现有网络。提供新的共享服务器时,驱动程序需要来自共享文件系统服务的 IP 地址和子网。 + +与无共享服务器模式不同,在共享服务器模式下,用户具有一个共享网络和一个为每个共享网络创建的共享服务器。因此,所有用户都有单独的 CPU、CPU 时间、网络、容量和吞吐量。 + +您还可以在共享服务器和无共享服务器后端模式下配置安全服务。但是,如果没有共享服务器后端模式,管理员应在主机上手动设置所需的身份验证服务。在共享服务器模式下,可以使用共享驱动程序支持的任何现有安全服务自动配置共享文件系统服务。 + +#### 扁平化与分段化网络 + +共享文件系统服务允许使用不同类型的网络: + +- `flat` +- `GRE` +- `VLAN` +- `VXLAN` + +**注意** + +```shell +共享文件系统服务只是将有关网络的信息保存在数据库中,而真正的网络则由网络提供商提供。在OpenStack中,它可以是传统网络(nova-network)或网络(neutron)服务,但共享文件系统服务甚至可以在OpenStack之外工作。这是允许的, `StandaloneNetworkPlugin` 可以与任何网络平台一起使用,并且不需要OpenStack中的某些特定网络服务,如Networking或Legacy网络服务。您可以在其配置文件中设置网络参数。 +``` + +在共享服务器后端模式下,共享驱动程序为每个共享网络创建和管理共享服务器。此模式可分为两种变体: + +- 共享服务器后端模式下的扁平网络 +- 共享服务器后端模式下的分段网络 + +最初,在创建共享网络时,您可以设置 OpenStack Networking (neutron) 的网络和子网,也可以设置 Legacy 网络 (nova-network) 服务网络。第三种方法是在没有旧版网络和网络服务的情况下配置网络。 `StandaloneNetworkPlugin` 可与任何网络平台一起使用。您可以在其配置文件中设置网络参数。 + +**建议** + +```shell +所有使用 OpenStack Compute 服务的共享驱动程序都不使用网络插件。在 Mitaka 版本中,它是 Windows 和通用驱动程序。这些共享驱动器具有其他选项并使用不同的方法。 +``` + +创建共享网络后,共享文件系统服务将检索由网络提供商确定的网络信息:网络类型、分段标识符(如果网络使用分段)和 CIDR 表示法中的 IP 块,以便从中分配网络。 + +共享服务器后端模式下的扁平网络 + +在此模式下,某些存储控制器可以创建共享服务器,但由于物理或逻辑网络的各种限制,所有共享服务器都必须位于扁平网络上。在此模式下,共享驱动程序需要一些东西来为共享服务器预配 IP 地址,但 IP 将全部来自同一子网,并且假定所有租户都可以访问该子网本身。 + +共享网络的安全服务部分指定安全要求,例如 AD 或 LDAP 域或 Kerberos 域。共享文件系统服务假定安全服务中引用的任何主机都可以从创建共享服务器的子网访问,这限制了可以使用此模式的情况数。 + +共享服务器后端模式下的分段网络 + +在此模式下,共享驱动程序能够创建共享服务器并将其插入到现有的分段网络。共享驱动程序期望共享文件系统服务为每个新的共享服务器提供子网定义。此定义应包括分段类型、分段 ID 以及与分段类型相关的任何其他信息。 + +**注意** + +```shell +某些共享驱动程序可能不支持所有类型的分段,有关详细信息,请参阅正在使用的驱动程序的规范。 +``` + +#### 网络插件 + +共享文件系统服务体系结构定义了用于网络资源调配的抽象层。它允许管理员从不同的选项中进行选择,以决定如何将网络资源分配给其租户的网络存储。有几个网络插件提供了与OpenStack提供的网络服务的各种集成方法。 + +网络插件允许使用 OpenStack Networking 和 Legacy 网络服务的任何功能、配置。可以使用网络服务支持的任何网络分段,也可以使用传统网络 (nova-network) 服务的扁平网络或 VLAN 分段网络,也可以使用插件来独立于 OpenStack 网络服务指定网络。有关如何使用不同网络插件的详细信息,请参阅共享文件系统服务网络插件。 + +### 安全服务 + +对于客户端的身份验证和授权,可以选择使用不同的网络身份验证协议配置共享文件系统存储服务。支持的身份验证协议包括 LDAP、Kerberos 和 Microsoft Active Directory 身份验证服务。 + +#### 安全服务介绍 + +创建共享并获取其导出位置后,用户无权装载该共享并处理文件。共享文件系统服务需要显式授予对新共享的访问权限。 + +用于身份验证和授权 (AuthN/AuthZ) 的客户机配置数据可以通过 存储 `security services` 。如果使用的驱动程序和后端支持 LDAP、Kerberos 或 Microsoft Active Directory,则共享文件系统服务可以使用它们。身份验证服务也可以在没有共享文件系统服务的情况下进行配置。 + +**注意** + +```shell +在某些情况下,需要显式指定其中一项安全服务,例如,NetApp、EMC 和 Windows 驱动程序需要 Active Directory 才能创建与 CIFS 协议的共享。 +``` + +#### 安全服务管理 + +安全服务是共享文件系统服务(马尼拉)实体,它抽象出一组选项,这些选项为特定共享文件系统协议(如 Active Directory 域或 Kerberos 域)定义安全域。安全服务包含共享文件系统创建加入给定域的服务器所需的所有信息。 + +使用 API,用户可以创建、更新、查看和删除安全服务。安全服务的设计基于以下假设: + +- 租户提供安全服务的详细信息。 +- 管理员关心安全服务:他们配置此类安全服务的服务器端。 +- 在共享文件系统 API 中,a `security_service` 与 `share_networks` 关联。 +- 共享驱动程序使用安全服务中的数据来配置新创建的共享服务器。 + +创建安全服务时,可以选择以下身份验证服务之一: + +| 身份验证服务 | 描述 | +| ------------ | ------------------------------------------------------------ | +| LDAP | 轻量级目录访问协议。用于通过 IP 网络访问和维护分布式目录信息服务的应用程序协议。 | +| Kerberos | 网络身份验证协议,它基于票证工作,允许通过非安全网络进行通信的节点以安全的方式相互证明其身份。 | +| 活动目录 | Microsoft 为 Windows 域网络开发的目录服务。使用 LDAP、Microsoft 的 Kerberos 版本和 DNS。 | + +共享文件系统服务允许您使用以下选项配置安全服务: + +- 租户网络内部使用的 DNS IP 地址。 +- 安全服务的 IP 地址或主机名。 +- 安全服务的域。 +- 租户使用的用户名或组名。 +- 如果指定用户名,则需要一个用户密码。 + +现有安全服务实体可以与共享网络实体相关联,这些实体通知共享文件系统服务一组共享的安全性和网络配置。您还可以查看指定共享网络的所有安全服务的列表,并取消它们与共享网络的关联。 + +有关通过 API 管理安全服务的详细信息,请参阅安全服务 API。您还可以通过 python-manilaclient 管理安全服务,请参阅安全服务 CLI 管理。 + +管理员和作为共享所有者的用户可以通过创建访问规则,并通过 IP 地址、用户、组或 TLS 证书进行身份验证来管理对共享的访问。身份验证方法取决于您配置和使用的共享驱动程序和安全服务。 + +因此,作为管理员,您可以将后端配置为通过网络使用特定的身份验证服务,它将存储用户。身份验证服务可以在没有共享文件系统和标识服务的客户端上运行。 + +**注意** + +```shell +不同的共享驱动程序支持不同的身份验证服务。有关不同驱动程序支持功能的详细信息,请参阅马尼拉共享功能支持映射。驱动程序对特定身份验证服务的支持并不意味着可以使用任何共享文件系统协议对其进行配置。支持的共享文件系统协议包括 NFS、CIFS、GlusterFS 和 HDFS。有关特定驱动程序及其安全服务配置的信息,请参阅驱动程序供应商的文档。 +``` + +某些驱动程序支持安全服务,而其他驱动程序不支持上述任何安全服务。例如,具有 NFS 或 CIFS 共享文件系统协议的通用驱动程序仅支持通过 IP 地址的身份验证方法。 + +**建议** + +```shell +- 在大多数情况下,支持 CIFS 共享文件系统协议的驱动程序可以配置为使用 Active Directory 并通过用户身份验证管理访问。 +- 支持 GlusterFS 协议的驱动程序可以通过 TLS 证书进行身份验证。 +- 使用支持 NFS 协议的驱动程序,通过 IP 地址进行身份验证是唯一受支持的选项。 +- 由于 HDFS 共享文件系统协议使用 NFS 访问,因此也可以将其配置为通过 IP 地址进行身份验证。 + +但请注意,通过 IP 进行的身份验证是最不安全的身份验证类型。 +``` + +共享文件系统服务实际使用情况的建议配置是使用 CIFS 共享协议创建共享,并向其添加 Microsoft Active Directory 目录服务。在此配置中,您将获得集中式数据库以及将Kerberos和LDAP方法结合在一起的服务。这是一个真实的用例,对于生产共享文件系统来说很方便。 + +### 共享访问控制 + +共享文件系统服务允许授予或拒绝其他客户端对服务的不同实体的访问。 + +将共享作为文件系统的可远程挂载实例,可以管理对指定共享的访问,并列出指定共享的权限。 + +共享可以是公共的,也可以是私有的。这是共享的可见性级别,用于定义其他租户是否可以看到共享。默认情况下,所有共享都创建为专用共享。创建共享时,请使用密钥 `--public` 将共享公开,供其他租户查看共享列表并查看其详细信息。 + +根据 policy.json 文件,管理员和作为共享所有者的用户可以通过创建访问规则来管理对共享的访问。使用 manila access-allow、manila access-deny 和 manila access-list 命令,您可以相应地授予、拒绝和列出对指定共享的访问权限。 + +**建议** + +```shell +默认情况下,当创建共享并具有其导出位置时,共享文件系统服务期望任何人都无法通过装载共享来访问该共享。请注意,您使用的共享驱动程序可以更改此配置,也可以直接在共享存储上更改。要确保访问共享,请检查导出协议的挂载配置。 +``` + +刚创建共享时,没有与之关联的默认访问规则和装载权限。这可以在正在使用的导出协议的挂载配置中看到。例如,存储上有一个 NFS 命令 `exportfs` 或 `/etc/exports` 文件,用于控制每个远程共享并定义可以访问它的主机。如果没有人可以挂载共享,则为空。对于远程 CIFS 服务器,有一个 `net conf list` 显示配置的命令。 `hosts deny` 参数应由共享驱动程序设置 `0.0.0.0/0` ,这意味着任何主机都被拒绝挂载共享。 + +使用共享文件系统服务,可以通过指定以下支持的共享访问级别之一来授予或拒绝对共享的访问: + +- rw。读取和写入 (RW) 访问。这是默认值。 +- ro。只读 (RO) 访问。 + +**建议** + +```shell +当管理员为某些特定编辑者或贡献者提供读写 (RW) 访问权限并为其余用户(查看者)提供只读 (RO) 访问权限时,RO 访问级别在公共共享中会很有帮助。 +``` + +您还必须指定以下受支持的身份验证方法之一: + +- ip。通过实例的 IP 地址对实例进行身份验证。有效格式为 XX.XX.XX.XX 或 XX.XX.XX.XX/XX。例如,0.0.0.0/0。 +- cert。通过 TLS 证书对实例进行身份验证。将 TLS 标识指定为 IDENTKEY。有效值是证书公用名 (CN) 中长度不超过 64 个字符的任何字符串。 +- user。按指定的用户名或组名进行身份验证。有效值是一个字母数字字符串,可以包含一些特殊字符,长度为 4 到 32 个字符。 + +**注意** + +```shell +支持的身份验证方法取决于您配置和使用的共享驱动程序、安全服务和共享文件系统协议。支持的共享文件系统协议包括 NFS、CIFS、GlusterFS 和 HDFS。支持的安全服务包括 LDAP、Kerberos 协议或 Microsoft Active Directory 服务。有关不同驱动程序支持功能的详细信息,请参阅马尼拉共享功能支持映射。 +``` + +下面是与通用驱动程序共享的 NFS 示例。创建共享后,它具有导出位置 `10.254.0.3:/shares/share-b2874f8d-d428-4a5c-b056-e6af80a995de` 。如果您尝试使用 `10.254.0.4` IP 地址将其挂载到主机上,您将收到“权限被拒绝”消息。 + +```shell +# mount.nfs -v 10.254.0.3:/shares/share-b2874f8d-d428-4a5c-b056-e6af80a995de /mnt +mount.nfs: timeout set for Mon Oct 12 13:07:47 2015 +mount.nfs: trying text-based options 'vers=4,addr=10.254.0.3,clientaddr=10.254.0.4' +mount.nfs: mount(2): Permission denied +mount.nfs: access denied by server while mounting 10.254.0.3:/shares/share-b2874f8d-... +``` + +作为管理员,您可以通过 SSH 连接到具有 IP 地址的 `10.254.0.3` 主机,检查其 `/etc/exports` 上的文件并查看它是否为空: + +```shell +# cat /etc/exports +# +``` + +我们在示例中使用的通用驱动程序不支持任何安全服务,因此使用 NFS 共享文件系统协议,我们只能通过 IP 地址授予访问权限: + +```shell +$ manila access-allow Share_demo2 ip 10.254.0.4 ++--------------+--------------------------------------+ +| Property | Value | ++--------------+--------------------------------------+ +| share_id | e57c25a8-0392-444f-9ffc-5daadb9f756c | +| access_type | ip | +| access_to | 10.254.0.4 | +| access_level | rw | +| state | new | +| id | 62b8e453-d712-4074-8410-eab6227ba267 | ++--------------+--------------------------------------+ +``` + +规则进入状态 `active` 后,我们可以再次连接到 `10.254.0.3` 主机并检查 `/etc/exports` 文件,并查看是否添加了带有规则的行: + +```shell +# cat /etc/exports +/shares/share-b2874f8d-d428-4a5c-b056-e6af80a995de 10.254.0.4(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,anonuid=65534,anongid=65534,sec=sys,rw,root_squash,no_all_squash) +``` + +现在,我们可以使用 IP 地址 `10.254.0.4` 在主机上挂载共享,并拥有 `rw` 共享权限: + +```shell +# mount.nfs -v 10.254.0.3:/shares/share-b2874f8d-d428-4a5c-b056-e6af80a995de /mnt +# ls -a /mnt +. .. lost+found +# echo "Hello!" > /mnt/1.txt +# ls -a /mnt +. .. 1.txt lost+found +# +``` + +### 共享类型访问控制 + +共享类型是管理员定义的“服务类型”,由租户可见描述和租户不可见键值对列表(额外规范)组成。manila-scheduler 使用额外的规范来做出调度决策,驱动程序控制共享创建。 + +管理员可以创建和删除共享类型,还可以管理在共享文件系统服务中赋予它们含义的额外规范。租户可以列出共享类型,并可以使用它们创建新共享。有关管理共享类型的详细信息,请参阅共享文件系统 API 和共享类型管理文档。 + +共享类型可以创建为公共和私有。这是共享类型的可见性级别,用于定义其他租户是否可以在共享类型列表中看到它,并使用它来创建新共享。 + +默认情况下,共享类型创建为公共类型。创建共享类型时,请使用 `--is_public` 参数集 设置为 `False` 私有共享类型,这将防止其他租户在共享类型列表中看到它并使用它创建新共享。另一方面,公共共享类型可供云中的每个租户使用。 + +共享文件系统服务允许管理员授予或拒绝对租户的专用共享类型的访问权限。还可以获取有关指定专用共享类型的访问权限的信息。 + +**建议** + +```shell +由于共享类型由于其额外的规范而有助于在用户创建共享之前筛选或选择后端,因此使用对共享类型的访问权限,可以限制客户端选择特定的后端。 +``` + +例如,作为管理员租户中的管理员用户,可以创建名为 `my_type` 的专用共享类型,并在列表中查看它。在控制台示例中,省略了登录和注销,并提供了环境变量以显示当前登录的用户。 + +```shell +$ env | grep OS_ +... +OS_USERNAME=admin +OS_TENANT_NAME=admin +... +$ manila type-list --all ++----+--------+-----------+-----------+-----------------------------------+-----------------------+ +| ID | Name | Visibility| is_default| required_extra_specs | optional_extra_specs | ++----+--------+-----------+-----------+-----------------------------------+-----------------------+ +| 4..| my_type| private | - | driver_handles_share_servers:False| snapshot_support:True | +| 5..| default| public | YES | driver_handles_share_servers:True | snapshot_support:True | ++----+--------+-----------+-----------+-----------------------------------+-----------------------+ +``` + +`demo` 租户中的 `demo` 用户可以列出类型,并且命名 `my_type` 的专用共享类型对他不可见。 + +```shell +$ env | grep OS_ +... +OS_USERNAME=demo +OS_TENANT_NAME=demo +... +$ manila type-list --all ++----+--------+-----------+-----------+----------------------------------+----------------------+ +| ID | Name | Visibility| is_default| required_extra_specs | optional_extra_specs | ++----+--------+-----------+-----------+----------------------------------+----------------------+ +| 5..| default| public | YES | driver_handles_share_servers:True| snapshot_support:True| ++----+--------+-----------+-----------+----------------------------------+----------------------+ +``` + +管理员可以授予对租户 ID 等于 df29a37db5ae48d19b349fe947fada46 的演示租户的专用共享类型的访问权限: + +```shell +$ env | grep OS_ +... +OS_USERNAME=admin +OS_TENANT_NAME=admin +... +$ openstack project list ++----------------------------------+--------------------+ +| ID | Name | ++----------------------------------+--------------------+ +| ... | ... | +| df29a37db5ae48d19b349fe947fada46 | demo | ++----------------------------------+--------------------+ +$ manila type-access-add my_type df29a37db5ae48d19b349fe947fada46 +``` + +因此,现在演示租户中的用户可以看到专用共享类型,并在共享创建中使用它: + +```shell +$ env | grep OS_ +... +OS_USERNAME=demo +OS_TENANT_NAME=demo +... +$ manila type-list --all ++----+--------+-----------+-----------+-----------------------------------+-----------------------+ +| ID | Name | Visibility| is_default| required_extra_specs | optional_extra_specs | ++----+--------+-----------+-----------+-----------------------------------+-----------------------+ +| 4..| my_type| private | - | driver_handles_share_servers:False| snapshot_support:True | +| 5..| default| public | YES | driver_handles_share_servers:True | snapshot_support:True | ++----+--------+-----------+-----------+-----------------------------------+- +``` + +要拒绝对指定项目的访问,请使用 manila type-access-remove 命令。 + +**建议** + +```shell +一个真实的生产用例显示了共享类型的用途和对它们的访问,当你有两个后端时:廉价的 LVM 作为公共存储,昂贵的 Ceph 作为私有存储。在这种情况下,可以向某些租户授予访问权限,并使用 `user/group` 身份验证方法进行访问。 +``` + +### 政策 + +共享文件系统服务有自己的基于角色的访问策略。它们确定哪个用户可以以哪种方式访问哪些对象,并在服务的 `policy.json` 文件中定义。 + +**建议** + +```shell +配置文件 `policy.json` 可以放置在任何位置。默认情况下,该路径 `/etc/manila/policy.json` 是必需的。 +``` + +每当对共享文件系统服务进行 API 调用时,策略引擎都会使用相应的策略定义来确定是否可以接受该调用。 + +策略规则确定在什么情况下允许 API 调用。当 `/etc/manila/policy.json` 规则为空字符串时,该文件具有始终允许操作的规则: `""` ;基于用户角色或规则的规则;带有布尔表达式的规则。下面是共享文件系统服务 `policy.json` 的文件片段。从一个OpenStack版本到另一个OpenStack版本,可以对其进行更改。 + +```shell +{ + "context_is_admin": "role:admin", + "admin_or_owner": "is_admin:True or project_id:%(project_id)s", + "default": "rule:admin_or_owner", + "share_extension:quotas:show": "", + "share_extension:quotas:update": "rule:admin_api", + "share_extension:quotas:delete": "rule:admin_api", + "share_extension:quota_classes": "", +} +``` + +必须将用户分配到策略中引用的组和角色。当使用用户管理命令时,服务会自动完成此操作。 + +**注意** + +```shell +任何更改 `/etc/manila/policy.json` 都会立即生效,这允许在共享文件系统服务运行时实施新策略。手动修改策略可能会产生意想不到的副作用,因此不鼓励这样做。有关详细信息,请参阅 policy.json 文件。 +``` + +### 检查表 + +#### Check-Shared-01:配置文件的用户/组所有权是否设置为 root/manila? + +配置文件包含组件平稳运行所需的关键参数和信息。如果非特权用户有意或无意地修改或删除任何参数或文件本身,则会导致严重的可用性问题,从而导致拒绝向其他最终用户提供服务。因此,此类关键配置文件的用户所有权必须设置为 root,组所有权必须设置为 manila。此外,包含目录应具有相同的所有权,以确保正确拥有新文件。 + +运行以下命令: + +```shell +$ stat -L -c "%U %G" /etc/manila/manila.conf | egrep "root manila" +$ stat -L -c "%U %G" /etc/manila/api-paste.ini | egrep "root manila" +$ stat -L -c "%U %G" /etc/manila/policy.json | egrep "root manila" +$ stat -L -c "%U %G" /etc/manila/rootwrap.conf | egrep "root manila" +$ stat -L -c "%U %G" /etc/manila | egrep "root manila" +``` + +通过:如果所有这些配置文件的用户和组所有权分别设置为 root 和 manila。上面的命令显示了根马尼拉的输出。 + +失败:如果上述命令未返回任何输出,因为用户和组所有权可能已设置为除 root 以外的任何用户或马尼拉以外的任何组。 + +#### Check-Shared-02:是否为配置文件设置了严格的权限? + +与前面的检查类似,建议对此类配置文件设置严格的访问权限。 + +运行以下命令: + +```shell +$ stat -L -c "%a" /etc/manila/manila.conf +$ stat -L -c "%a" /etc/manila/api-paste.ini +$ stat -L -c "%a" /etc/manila/policy.json +$ stat -L -c "%a" /etc/manila/rootwrap.conf +$ stat -L -c "%a" /etc/manila +``` + +还可以进行更广泛的限制:如果包含目录设置为 750,则保证此目录中新创建的文件具有所需的权限。 + +通过:如果权限设置为 640 或更严格,或者包含目录设置为 750。640 的权限转换为所有者 r/w、组 r,而对其他人没有权限,即“u=rw,g=r,o=”。请注意,使用 Check-Shared-01:配置文件的用户/组所有权是否设置为 root/manila?权限设置为 640,root 具有读/写访问权限,manila 具有对这些配置文件的读取访问权限。也可以使用以下命令验证访问权限。仅当此命令支持 ACL 时,它才在您的系统上可用。 + +```shell +$ getfacl --tabular -a /etc/manila/manila.conf +getfacl: Removing leading '/' from absolute path names +# file: etc/manila/manila.conf +USER root rw- +GROUP manila r-- +mask r-- +other --- +``` + +失败:如果权限未设置为至少 640。 + +#### Check-Shared-03:OpenStack Identity 是否用于身份验证? + +**注意** + +```shell +此项仅适用于 OpenStack 版本 Rocky 及之前版本,因为 `auth_strategy` Stein 中已弃用。 +``` + +OpenStack 支持各种身份验证策略,如 noauth 和 keystone。如果使用 ' `noauth` ' 策略,则用户无需任何身份验证即可与 OpenStack 服务进行交互。这可能是一个潜在的风险,因为攻击者可能会获得对 OpenStack 组件的未经授权的访问。因此,强烈建议所有服务都必须使用其服务帐户通过 keystone 进行身份验证。 + +通过:如果 section in 下的参数 `auth_strategy` 设置为 `keystone` 。 `[DEFAULT]` `manila.conf` + +失败:如果 section 下的 `[DEFAULT]` 参数 `auth_strategy` 值设置为 `noauth` 。 + +#### Check-Shared-04:是否启用了 TLS 进行身份验证? + +OpenStack 组件使用各种协议相互通信,通信可能涉及敏感或机密数据。攻击者可能会尝试窃听频道以访问敏感信息。所有组件必须使用安全通信协议相互通信。 + +通过:如果 section in `/etc/manila/manila.conf` 下的参数值设置为 Identity API 端点开头, `https://` 并且 same `/etc/manila/manila.conf` 中同一 `[keystone_authtoken]` 部分下的 `[keystone_authtoken]` 参数 `www_authenticate_uri` `insecure` 值设置为 `False` 。 + +失败:如果 in `/etc/manila/manila.conf` 部分下的 `[keystone_authtoken]` 参数 `www_authenticate_uri` 值未设置为以 开头的身份 API 端点, `https://` 或者同一 `/etc/manila/manila.conf` 部分中的参数 `insecure` `[keystone_authtoken]` 值设置为 `True` 。 + +#### Check-Shared-05:共享文件系统是否通过 TLS 与计算联系? + +**注意** + +```shell +此项仅适用于 OpenStack 版本 Train 及之前版本,因为 `auth_strategy` Ussuri 中已弃用。 +``` + +OpenStack 组件使用各种协议相互通信,通信可能涉及敏感或机密数据。攻击者可能会尝试窃听频道以访问敏感信息。因此,所有组件都必须使用安全的通信协议相互通信。 + +通过:如果 section in 下的参数 `nova_api_insecure` 设置为 `False` 。 `[DEFAULT]` `manila.conf` + +失败:如果 section in 下的参数 `nova_api_insecure` 设置为 `True` 。 `[DEFAULT]` `manila.conf` + +#### Check-Shared-06:共享文件系统是否通过 TLS 与网络联系? + +**注意** + +```shell +此项仅适用于 OpenStack 版本 Train 及之前版本,因为 `auth_strategy` Ussuri 中已弃用。 +``` + +与之前的检查(Check-Shared-05:共享文件系统是否通过 TLS 与计算联系?)类似,建议所有组件必须使用安全通信协议相互通信。 + +通过:如果 section in 下的参数 `neutron_api_insecure` 设置为 `False` 。 `[DEFAULT]` `manila.conf` + +失败:如果 section in 下的参数 `neutron_api_insecure` 设置为 `True` 。 `[DEFAULT]` `manila.conf` + +#### Check-Shared-07:共享文件系统是否通过 TLS 与块存储联系? + +**注意** + +```shell +此项仅适用于 OpenStack 版本 Train 及之前版本,因为 `auth_strategy` Ussuri 中已弃用。 +``` + +与之前的检查(Check-Shared-05:共享文件系统是否通过 TLS 与计算联系?)类似,建议所有组件必须使用安全通信协议相互通信。 + +通过:如果 section in 下的参数 `cinder_api_insecure` 设置为 `False` 。 `[DEFAULT]` `manila.conf` + +失败:如果 section in 下的参数 `cinder_api_insecure` 设置为 `True` 。 `[DEFAULT]` `manila.conf` + +#### Check-Shared-08:请求正文的最大大小是否设置为默认值 (114688)? + +如果未定义每个请求的最大正文大小,攻击者可以构建任意较大的OSAPI请求,导致服务崩溃,最终导致拒绝服务攻击。分配最大值可确保阻止任何恶意超大请求,从而确保服务的持续可用性。 + +通过:如果 in 节下的参数值设置为 ,或者 in `manila.conf` `manila.conf` 节下的 `[oslo_middleware]` `[DEFAULT]` 参数 `max_request_body_size` `osapi_max_request_body_size` 值设置为 `114688` 。 `114688` 下面的 `[DEFAULT]` 参数 `osapi_max_request_body_size` 已弃用,最好使用 [oslo_middleware]/ `max_request_body_size` 。 + +失败:如果 in `manila.conf` 节下的参数值未设置为 `114688` ,或者 in `manila.conf` 节下的 `[DEFAULT]` `[oslo_middleware]` 参数 `max_request_body_size` `osapi_max_request_body_size` 值未设置为 `114688` 。 + +## 联网 + +OpenStack 网络服务 (neutron) 使最终用户或租户能够定义、利用和使用网络资源。OpenStack Networking 提供了一个面向租户的 API,用于定义云中实例的网络连接和 IP 寻址,以及编排网络配置。随着向以 API 为中心的网络服务的过渡,云架构师和管理员应考虑最佳实践来保护物理和虚拟网络基础架构和服务。 + +OpenStack Networking 采用插件架构设计,通过开源社区或第三方服务提供 API 的可扩展性。在评估架构设计要求时,确定 OpenStack Networking 核心服务中有哪些功能、第三方产品提供的任何其他服务以及需要在物理基础架构中实现哪些补充服务非常重要。 + +本节简要概述了在实现 OpenStack Networking 时应考虑哪些流程和最佳实践。 + +- 网络架构 + - 在物理服务器上放置 OpenStack Networking 服务 +- 网络服务 + - 使用 VLAN 和隧道的 L2 隔离 + - 网络服务 + - 网络服务扩展 + - 网络服务限制 +- 网络服务安全最佳做法 + - OpenStack Networking 服务配置 + +- 保护 OpenStack 网络服务 + - 项目网络服务工作流程 + - 网络资源策略引擎 + - 安全组 + - 配额 + - 缓解 ARP 欺骗 + +- 检查表 + - Check-Neutron-01:配置文件的用户/组所有权是否设置为 root/neutron? + - Check-Neutron-02:是否为配置文件设置了严格的权限? + - Check-Neutron-03:Keystone是否用于身份验证? + - Check-Neutron-04:是否使用安全协议进行身份验证? + - Check-Neutron-05:Neutron API 服务器上是否启用了 TLS? + +### 网络架构 + +OpenStack Networking 是一个独立的服务,通常在多个节点上部署多个进程。这些进程彼此交互,并与其他 OpenStack 服务交互。OpenStack Networking 服务的主要进程是 neutron-server,这是一个 Python 守护进程,它公开 OpenStack Networking API,并将租户请求传递给一组插件进行额外处理。 + +OpenStack Networking 组件包括: + +neutron 服务器(neutron-server 和 neutron-*-plugin) + +此服务在网络节点上运行,为网络 API 及其扩展提供服务。它还强制执行每个端口的网络模型和 IP 寻址。neutron-server 需要间接访问持久性数据库。这是通过插件实现的,插件使用 AMQP(高级消息队列协议)与数据库进行通信。 + +插件代理 (neutron-*-agent) + +在每个计算节点上运行,以管理本地虚拟交换机 (vswitch) 配置。您使用的插件决定了运行哪些代理。此服务需要消息队列访问,并取决于所使用的插件。一些插件,如 OpenDaylight(ODL) 和开放虚拟网络 (OVN),在计算节点上不需要任何 python 代理。 + +DHCP 代理 (neutron-dhcp-agent) + +为租户网络提供DHCP服务。此代理在所有插件中都是相同的,并负责维护 DHCP 配置。neutron-dhcp-agent 需要消息队列访问。可选,具体取决于插件。 + +L3 代理(neutron-L3-agent) + +为租户网络上的虚拟机提供 L3/NAT 转发。需要消息队列访问权限。可选,具体取决于插件。 + +网络提供商服务(SDN 服务器/服务) + +为租户网络提供其他网络服务。这些 SDN 服务可以通过 REST API 等通信通道与 neutron-server、neutron-plugin 和 plugin-agents 进行交互。 + +下图显示了 OpenStack Networking 组件的架构和网络流程图: + +[![../_images/sdn-connections.png](https://docs.openstack.org/security-guide/_images/sdn-connections.png)](https://docs.openstack.org/security-guide/_images/sdn-connections.png) + +#### OpenStack Networking 服务在物理服务器上的放置 + +本指南重点介绍一个标准架构,其中包括一个云控制器主机、一个网络主机和一组用于运行 VM 的计算虚拟机监控程序。 + +##### 物理服务器的网络连接 + +[![../_images/1aa-network-domains-diagram.png](https://docs.openstack.org/security-guide/_images/1aa-network-domains-diagram.png)](https://docs.openstack.org/security-guide/_images/1aa-network-domains-diagram.png) + +标准的 OpenStack Networking 设置最多有四个不同的物理数据中心网络: + +- 管理网络 + + 用于 OpenStack 组件之间的内部通信。此网络上的 IP 地址应只能在数据中心内访问,并被视为管理安全域。 + +- 访客网络 + + 用于云部署中的 VM 数据通信。此网络的 IP 寻址要求取决于所使用的 OpenStack Networking 插件以及租户对虚拟网络所做的网络配置选择。此网络被视为客户机安全域。 + +- 外部网络 + + 用于在某些部署方案中为 VM 提供 Internet 访问权限。Internet 上的任何人都可以访问此网络上的 IP 地址。此网络被视为属于公共安全域。 + +- API网络 + + 向租户公开所有 OpenStack API,包括 OpenStack 网络 API。Internet 上的任何人都可以访问此网络上的 IP 地址。这可能与外部网络是同一网络,因为可以为使用 IP 分配范围的外部网络创建一个子网,以便仅使用 IP 块中小于全部范围的 IP 地址。此网络被视为公共安全域。 + +有关更多信息,请参阅《OpenStack 管理员指南》。 + +### 网络服务 + +在设计 OpenStack 网络基础架构的初始架构阶段,确保提供适当的专业知识来协助设计物理网络基础架构,确定适当的安全控制和审计机制非常重要。 + +OpenStack Networking 增加了一层虚拟化网络服务,使租户能够构建自己的虚拟网络。目前,这些虚拟化服务还没有传统网络的成熟。在采用这些虚拟化服务之前,请考虑这些服务的当前状态,因为它决定了您可能需要在虚拟化和传统网络边界上实现哪些控制。 + +#### 使用 VLAN 和隧道的 L2 隔离 + +OpenStack Networking 可以采用两种不同的机制对每个租户/网络组合进行流量隔离:VLAN(IEEE 802.1Q 标记)或使用 GRE 封装的 L2 隧道。OpenStack 部署的范围和规模决定了您应该使用哪种方法进行流量隔离或隔离。 + +##### VLANs + +VLAN 在特定物理网络上实现为数据包,其中包含具有特定 VLAN ID (VID) 字段值的 IEEE 802.1Q 标头。共享同一物理网络的 VLAN 网络在 L2 上彼此隔离,甚至可以有重叠的 IP 地址空间。每个支持 VLAN 网络的不同物理网络都被视为一个单独的 VLAN 中继,具有不同的 VID 值空间。有效的 VID 值为 1 到 4094。 + +VLAN 配置的复杂性取决于您的 OpenStack 设计要求。为了让 OpenStack Networking 能够有效地使用 VLAN,您必须分配一个 VLAN 范围(每个租户一个),并将每个计算节点物理交换机端口转换为 VLAN 中继端口。 + +**注意** + +```shell +如果您打算让您的网络支持超过 4094 个租户,则 VLAN 可能不是您的正确选择,因为需要多个“黑客”才能将 VLAN 标记扩展到超过 4094 个租户。 +``` + +##### L2 隧道 + +网络隧道使用唯一的“tunnel-id”封装每个租户/网络组合,该 ID 用于标识属于该组合的网络流量。租户的 L2 网络连接与物理位置或基础网络设计无关。通过将流量封装在 IP 数据包中,该流量可以跨越第 3 层边界,无需预配置 VLAN 和 VLAN 中继。隧道为网络数据流量增加了一层混淆,从监控的角度降低了单个租户流量的可见性。 + +OpenStack Networking 目前支持 GRE 和 VXLAN 封装。 + +提供 L2 隔离的技术选择取决于将在部署中创建的租户网络的范围和大小。如果您的环境的 VLAN ID 可用性有限或将具有大量 L2 网络,我们建议您使用隧道。 + +#### 网络服务 + +租户网络隔离的选择会影响租户服务的网络安全和控制边界的实现方式。以下附加网络服务已经可用或目前正在开发中,以增强 OpenStack 网络架构的安全态势。 + +##### 访问控制列表 + +OpenStack 计算在与旧版 nova-network 服务一起部署时直接支持租户网络流量访问控制,或者可以将访问控制推迟到 OpenStack Networking 服务。 + +请注意,旧版 nova-network 安全组使用 iptables 应用于实例上的所有虚拟接口端口。 + +安全组允许管理员和租户指定流量类型以及允许通过虚拟接口端口的方向(入口/出口)。安全组规则是有状态的 L2-L4 流量过滤器。 + +使用网络服务时,建议在此服务中启用安全组,并在计算服务中禁用安全组。 + +##### L3 路由和 NAT + +OpenStack Networking 路由器可以连接多个 L2 网络,并且还可以提供连接一个或多个私有 L2 网络到共享外部网络(例如用于访问互联网的公共网络)的网关。 + +L3 路由器在将路由器上行链路到外部网络的网关端口上提供基本的网络地址转换 (NAT) 功能。默认情况下,此路由器会 SNAT(静态 NAT)所有流量,并支持浮动 IP,这会创建从外部网络上的公共 IP 到连接到路由器的其他子网上的专用 IP 的静态一对一映射。 + +我们建议利用每个租户的 L3 路由和浮动 IP 来实现租户 VM 的更精细连接。 + +##### 服务质量 (QoS) + +默认情况下,服务质量 (QoS) 策略和规则由云管理员管理,这会导致租户无法创建特定的 QoS 规则,也无法将特定端口附加到策略。在某些用例中,例如某些电信应用程序,管理员可能信任租户,因此允许他们创建自己的策略并将其附加到端口。这可以通过修改 `policy.json` 文件和特定文档来实现。将与扩展一起发布。 + +网络服务 (neutron) 支持 Liberty 及更高版本中的带宽限制 QoS 规则。此 QoS 规则已命名 `QosBandwidthLimitRule` ,它接受两个非负整数,以千比特/秒为单位: + +- `max-kbps` :带宽 +- `max-burst-kbps` :突发缓冲区 + +已 `QoSBandwidthLimitRule` 在 neutron Open vSwitch、Linux 网桥和单根输入/输出虚拟化 (SR-IOV) 驱动程序中实现。 + +在 Newton 中,添加了 QoS 规则 `QosDscpMarkingRule` 。此规则在 IPv4 (RFC 2474) 上的服务标头类型和 IPv6 上的流量类标头中标记差分服务代码点 (DSCP) 值,这些值适用于应用规则的虚拟机的所有流量。这是一个 6 位标头,具有 21 个有效值,表示数据包在遇到拥塞时穿过网络时的丢弃优先级。防火墙还可以使用它来将有效或无效流量与其访问控制列表进行匹配。 + +端口镜像服务涉及将进入或离开一个端口的数据包副本发送到另一个端口,该端口通常与被镜像数据包的原始目的地不同。Tap-as-a-Service (TaaS) 是 OpenStack 网络服务 (neutron) 的扩展。它为租户虚拟网络提供远程端口镜像功能。此服务主要旨在帮助租户(或云管理员)调试复杂的虚拟网络,并通过监视与其关联的网络流量来了解其 VM。TaaS 遵循租户边界,其镜像会话能够跨越多个计算和网络节点。它是一个必不可少的基础设施组件,可用于向各种网络分析和安全应用程序提供数据。 + +##### 负载均衡 + +OpenStack Networking 的另一个特性是负载均衡器即服务 (LBaaS)。LBaaS 参考实现基于 HA-Proxy。OpenStack Networking 中的扩展正在开发第三方插件,以便为虚拟接口端口提供广泛的 L4-L7 功能。 + +##### 防火墙 + +FW-as-a-Service(FWaaS)被认为是OpenStack Networking的Kilo版本的实验性功能。FWaaS 满足了管理和利用典型防火墙产品提供的丰富安全功能的需求,这些产品通常比当前安全组提供的要全面得多。飞思卡尔和英特尔都开发了第三方插件作为OpenStack Networking的扩展,以在Kilo版本中支持此组件。有关 FWaaS 管理的更多详细信息,请参阅《OpenStack 管理员指南》中的防火墙即服务 (FWaaS) 概述。 + +在设计 OpenStack Networking 基础架构时,了解可用网络服务的当前特性和局限性非常重要。了解虚拟网络和物理网络的边界将有助于在您的环境中添加所需的安全控件。 + +#### 网络服务扩展 + +开源社区或使用 OpenStack Networking 的 SDN 公司提供的已知插件列表可在 OpenStack neutron 插件和驱动程序 wiki 页面上找到。 + +#### 网络服务限制 + +OpenStack Networking 具有以下已知限制: + +重叠的 IP 地址 + +如果运行 neutron-l3-agent 或 neutron-dhcp-agent 的节点使用重叠的 IP 地址,则这些节点必须使用 Linux 网络命名空间。默认情况下,DHCP 和 L3 代理使用 Linux 网络命名空间,并在各自的命名空间中运行。但是,如果主机不支持多个命名空间,则 DHCP 和 L3 代理应在不同的主机上运行。这是因为 L3 代理和 DHCP 代理创建的 IP 地址之间没有隔离。 + +如果不存在网络命名空间支持,则 L3 代理的另一个限制是仅支持单个逻辑路由器。 + +多主机 DHCP 代理 + +OpenStack Networking 支持多个具有负载均衡功能的 L3 和 DHCP 代理。但是,不支持虚拟机位置的紧密耦合。换言之,在创建虚拟机时,默认虚拟机调度程序不会考虑代理的位置。 + +L3 代理不支持 IPv6 + +neutron-l3-agent 被许多插件用于实现 L3 转发,仅支持 IPv4 转发。 + +### 网络服务安全最佳做法 + +要保护 OpenStack Networking,您必须了解如何将租户实例创建的工作流过程映射到安全域。 + +有四个主要服务与 OpenStack Networking 交互。在典型的 OpenStack 部署中,这些服务映射到以下安全域: + +- OpenStack 仪表板:公共和管理 +- OpenStack Identity:管理 +- OpenStack 计算节点:管理和客户端 +- OpenStack 网络节点:管理、客户端,以及可能的公共节点,具体取决于正在使用的 neutron-plugin。 +- SDN 服务节点:管理、访客和可能的公共服务,具体取决于使用的产品。 + +[![../_images/1aa-logical-neutron-flow.png](https://docs.openstack.org/security-guide/_images/1aa-logical-neutron-flow.png)](https://docs.openstack.org/security-guide/_images/1aa-logical-neutron-flow.png) + +要隔离 OpenStack Networking 服务与其他 OpenStack 核心服务之间的敏感数据通信,请将这些通信通道配置为仅允许通过隔离的管理网络进行通信。 + +#### OpenStack Networking 服务配置 + +##### 限制 API 服务器的绑定地址:neutron-server + +要限制 OpenStack Networking API 服务为传入客户端连接绑定网络套接字的接口或 IP 地址,请在 neutron.conf 文件中指定 bind_host 和 bind_port,如下所示: + +```shell +# Address to bind the API server +bind_host = IP ADDRESS OF SERVER + +# Port the bind the API server to +bind_port = 9696 +``` + +##### 限制 OpenStack Networking 服务的 DB 和 RPC 通信 + +OpenStack Networking 服务的各种组件使用消息队列或数据库连接与 OpenStack Networking 中的其他组件进行通信。 + +对于需要直接数据库连接的所有组件,建议您遵循数据库身份验证和访问控制中提供的准则。 + +建议您遵循队列身份验证和访问控制中提供的准则,适用于需要 RPC 通信的所有组件。 + +### 保护 OpenStack 网络服务 + +本节讨论 OpenStack Networking 配置最佳实践,因为它们适用于 OpenStack 部署中的项目网络安全。 + +#### 项目网络服务工作流 + +OpenStack Networking 为用户提供网络资源和配置的自助服务。云架构师和运维人员必须评估其设计用例,以便为用户提供创建、更新和销毁可用网络资源的能力。 + +#### 网络资源策略引擎 + +OpenStack Networking 中的策略引擎及其配置文件 `policy.json` 提供了一种方法,可以对用户在项目网络方法和对象上提供更细粒度的授权。OpenStack Networking 策略定义会影响网络可用性、网络安全和整体 OpenStack 安全性。云架构师和运维人员应仔细评估其对用户和项目访问网络资源管理的策略。有关 OpenStack Networking 策略定义的更详细说明,请参阅《OpenStack 管理员指南》中的“身份验证和授权”部分。 + +**注意** + +```shell +请务必查看默认网络资源策略,因为可以修改此策略以适合您的安全状况。 +``` + +如果您的 OpenStack 部署为不同的安全域提供了多个外部访问点,那么限制项目将多个 vNIC 连接到多个外部访问点的能力非常重要,这将桥接这些安全域,并可能导致不可预见的安全危害。通过利用 OpenStack Compute 提供的主机聚合功能,或者将项目虚拟机拆分为具有不同虚拟网络配置的多个项目项目,可以降低这种风险。 + +#### 安全组 + +OpenStack Networking 服务使用比 OpenStack Compute 中内置的安全组功能更灵活、更强大的机制提供安全组功能。因此,在使用 OpenStack Network 时,应始终禁用内置安全组, `nova.conf` 并将所有安全组调用代理到 OpenStack Networking API。如果不这样做,将导致两个服务同时应用冲突的安全策略。要将安全组代理到 OpenStack Networking,请使用以下配置值: + +- `firewall_driver` 必须设置为 `nova.virt.firewall.NoopFirewallDriver` ,以便 nova-compute 本身不执行基于 iptables 的过滤。 +- `security_group_api` 必须设置为 `neutron` 以便将所有安全组请求代理到 OpenStack Networking 服务。 + +安全组是安全组规则的容器。安全组及其规则允许管理员和项目指定允许通过虚拟接口端口的流量类型和方向(入口/出口)。在 OpenStack Networking 中创建虚拟接口端口时,该端口与安全组相关联。有关端口安全组默认行为的更多详细信息,请参阅网络安全组行为文档。可以将规则添加到默认安全组,以便根据每个部署更改行为。 + +使用 OpenStack Compute API 修改安全组时,更新后的安全组将应用于实例上的所有虚拟接口端口。这是因为 OpenStack Compute 安全组 API 是基于实例的,而不是基于端口的,如 OpenStack Networking 中所示。 + +#### 配额 + +配额提供了限制项目可用的网络资源数量的功能。您可以对所有项目强制实施默认配额。包括 `/etc/neutron/neutron.conf` 以下配额选项: + +```shell +[QUOTAS] +# resource name(s) that are supported in quota features +quota_items = network,subnet,port + +# default number of resource allowed per tenant, minus for unlimited +#default_quota = -1 + +# number of networks allowed per tenant, and minus means unlimited +quota_network = 10 + +# number of subnets allowed per tenant, and minus means unlimited +quota_subnet = 10 + +# number of ports allowed per tenant, and minus means unlimited +quota_port = 50 + +# number of security groups allowed per tenant, and minus means unlimited +quota_security_group = 10 + +# number of security group rules allowed per tenant, and minus means unlimited +quota_security_group_rule = 100 + +# default driver to use for quota checks +quota_driver = neutron.quota.ConfDriver +``` + +OpenStack Networking 还通过配额扩展 API 支持每个项目的配额限制。要启用每个项目的配额,必须在 中设置选项 `quota_driver` `neutron.conf` 。 + +```shell +quota_driver = neutron.db.quota.driver.DbQuotaDriver +``` + +#### 缓解 ARP 欺骗 + +使用扁平网络时,不能假定共享同一第 2 层网络(或广播域)的项目彼此完全隔离。这些项目可能容易受到 ARP 欺骗的攻击,从而有可能遭受中间人攻击。 + +如果使用支持 ARP 字段匹配的 Open vSwitch 版本,则可以通过启用 Open vSwitch 代理 `prevent_arp_spoofing` 选项来帮助降低此风险。此选项可防止实例执行欺骗攻击;它不能保护他们免受欺骗攻击。请注意,此设置预计将在 Ocata 中删除,该行为将永久处于活动状态。 + +例如,在 `/etc/neutron/plugins/ml2/openvswitch_agent.ini` : + +```shell +prevent_arp_spoofing = True +``` + +除 Open vSwitch 外,其他插件也可能包含类似的缓解措施;建议您在适当的情况下启用此功能。 + +**注意** + +```shell +即使启用 `prevent_arp_spoofing` 了扁平网络,也无法提供完整的项目隔离级别,因为所有项目流量仍会发送到同一 VLAN。 +``` + +### 检查表 + +#### Check-Neutron-01:配置文件的用户/组所有权是否设置为 root/neutron? + +配置文件包含组件平稳运行所需的关键参数和信息。如果非特权用户有意或无意地修改或删除任何参数或文件本身,则会导致严重的可用性问题,从而导致对其他最终用户的拒绝服务。因此,此类关键配置文件的用户所有权必须设置为 root,组所有权必须设置为 neutron。此外,包含目录应具有相同的所有权,以确保正确拥有新文件。 + +运行以下命令: + +```shell +$ stat -L -c "%U %G" /etc/neutron/neutron.conf | egrep "root neutron" +$ stat -L -c "%U %G" /etc/neutron/api-paste.ini | egrep "root neutron" +$ stat -L -c "%U %G" /etc/neutron/policy.json | egrep "root neutron" +$ stat -L -c "%U %G" /etc/neutron/rootwrap.conf | egrep "root neutron" +$ stat -L -c "%U %G" /etc/neutron | egrep "root neutron" +``` + +通过:如果所有这些配置文件的用户和组所有权分别设置为 root 和 neutron。上面的命令显示了根中子的输出。 + +失败:如果上述命令未返回任何输出,因为用户和组所有权可能已设置为除 root 以外的任何用户或除 neutron 以外的任何组。 + +#### Check-Neutron-02:是否为配置文件设置了严格的权限? + +与前面的检查类似,建议对此类配置文件设置严格的访问权限。 + +运行以下命令: + +```shell +$ stat -L -c "%a" /etc/neutron/neutron.conf +$ stat -L -c "%a" /etc/neutron/api-paste.ini +$ stat -L -c "%a" /etc/neutron/policy.json +$ stat -L -c "%a" /etc/neutron/rootwrap.conf +$ stat -L -c "%a" /etc/neutron +``` + +还可以进行更广泛的限制:如果包含目录设置为 750,则保证此目录中新创建的文件具有所需的权限。 + +通过:如果权限设置为 640 或更严格,或者包含目录设置为 750。640 的权限转换为所有者 r/w、组 r,而对其他人没有权限,即“u=rw,g=r,o=”。 + +请注意,使用 Check-Neutron-01:配置文件的用户/组所有权是否设置为 root/neutron?权限设置为 640,root 具有读/写访问权限,neutron 具有对这些配置文件的读取访问权限。也可以使用以下命令验证访问权限。仅当此命令支持 ACL 时,它才在您的系统上可用。 + +```shell +$ getfacl --tabular -a /etc/neutron/neutron.conf +getfacl: Removing leading '/' from absolute path names +# file: etc/neutron/neutron.conf +USER root rw- +GROUP neutron r-- +mask r-- +other --- +``` + +失败:如果权限没有设置至少为640。 + +#### Check-Neutron-03:Keystone是否用于身份验证? + +**注意** + +```shell +此项仅适用于 OpenStack 版本 Rocky 及之前版本,因为 `auth_strategy` Stein 中已弃用。 +``` + +OpenStack 支持各种身份验证策略,如 noauth、keystone 等。如果使用“noauth”策略,那么用户无需任何身份验证即可与OpenStack服务进行交互。这可能是一个潜在的风险,因为攻击者可能会获得对 OpenStack 组件的未经授权的访问。因此,强烈建议所有服务都必须使用其服务帐户通过 keystone 进行身份验证。 + +通过:如果 section in 下的参数 `auth_strategy` 设置为 `keystone` 。 `[DEFAULT]` `/etc/neutron/neutron.conf` + +失败:如果 section 下的 `[DEFAULT]` 参数 `auth_strategy` 值设置为 `noauth` 或 `noauth2` 。 + +#### Check-Neutron-04:是否使用安全协议进行身份验证? + +OpenStack 组件使用各种协议相互通信,通信可能涉及敏感/机密数据。攻击者可能会尝试窃听频道以访问敏感信息。因此,所有组件都必须使用安全的通信协议相互通信。 + +通过:如果 section in `/etc/neutron/neutron.conf` 下的参数值设置为 Identity API 端点开头, `https://` 并且 same `/etc/neutron/neutron.conf` 中同一 `[keystone_authtoken]` 部分下的 `[keystone_authtoken]` 参数 `www_authenticate_uri` `insecure` 值设置为 `False` 。 + +失败:如果 in `/etc/neutron/neutron.conf` 部分下的 `[keystone_authtoken]` 参数 `www_authenticate_uri` 值未设置为以 开头的身份 API 端点, `https://` 或者同一 `/etc/neutron/neutron.conf` 部分中的参数 `insecure` `[keystone_authtoken]` 值设置为 `True` 。 + +#### Check-Neutron-05:Neutron API 服务器上是否启用了 TLS? + +与之前的检查类似,建议在 API 服务器上启用安全通信。 + +通过:如果 section in 下的参数 `use_ssl` 设置为 `True` 。 `[DEFAULT]` `/etc/neutron/neutron.conf` + +失败:如果 section in 下的参数 `use_ssl` 设置为 `False` 。 `[DEFAULT]` `/etc/neutron/neutron.conf` + +## 对象存储 + +OpenStack 对象存储 (swift) 服务提供通过 HTTP 存储和检索数据的软件。对象(数据 blob)存储在组织层次结构中,该层次结构提供匿名只读访问、ACL 定义的访问,甚至临时访问。对象存储支持通过中间件实现的多种基于令牌的身份验证机制。 + +应用程序通过行业标准的 HTTP RESTful API 在对象存储中存储和检索数据。对象存储的后端组件遵循相同的 RESTful 模型,尽管某些 API(例如管理持久性的 API)对集群是私有的。有关 API 的更多详细信息,请参阅 OpenStack Storage API。 + +对象存储的组件分为以下主要组: + +1. 代理服务 +2. 身份验证服务 +3. 存储服务 + - 账户服务 + - 容器服务 + - 对象服务 + +[![_images/swift_network_diagram-1.png](https://docs.openstack.org/security-guide/_images/swift_network_diagram-1.png)](https://docs.openstack.org/security-guide/_images/swift_network_diagram-1.png) + +OpenStack 对象存储管理指南 (2013) 中的示例图 + +**注意** + +```shell +对象存储安装不必位于 Internet 上,也可以是私有云,其中公共交换机是组织内部网络基础架构的一部分。 +``` + +### 网络安全 + +要保护对象存储服务,首先要保护网络组件。如果您跳过了网络章节,请返回到网络部分。 + +rsync 协议用于在存储服务节点之间复制数据以实现高可用性。此外,在客户端端点和云环境之间来回中继数据时,代理服务会与存储服务进行通信。 + +**警告** + +```shell +对象存储不对节点间通信进行加密或身份验证。这就是您在体系结构图中看到专用交换机或专用网络 ([V]LAN) 的原因。这个数据域也应该与其他OpenStack数据网络分开。有关安全域的进一步讨论,请参阅安全边界和威胁。 +``` + +**建议** + +```shell +对数据域中的存储节点使用专用 (V)LAN 网段。 +``` + +这需要代理节点具有双接口(物理或虚拟): + +1. 一个作为消费者访问的公共界面。 +2. 另一个作为可以访问存储节点的专用接口。 + +下图演示了一种可能的网络体系结构。 + +[![_images/swift_network_diagram-2.png](https://docs.openstack.org/security-guide/_images/swift_network_diagram-2.png)](https://docs.openstack.org/security-guide/_images/swift_network_diagram-2.png) + +具有管理节点(OSAM)的对象存储网络架构 + +### 一般服务安全 + +#### 以非 root 用户身份运行服务 + +我们建议您将对象存储服务配置为在非 root (UID 0) 服务帐户下运行。一个建议是 `swift` 具有主组 `swift` 的用户名。例如, `proxy-server` 对象存储服务包括、、 `container-server` `account-server` 。有关设置和配置的详细步骤,请参阅《安装指南》的“添加对象存储”一章的 OpenStack 文档索引。 + +**注意** + +```shell +上面的链接默认为Ubuntu版本。 +``` + +##### 文件权限 + +该 `/etc/swift` 目录包含有关环形拓扑和环境配置的信息。建议使用以下权限: + +```shell +# chown -R root:swift /etc/swift/* +# find /etc/swift/ -type f -exec chmod 640 {} \; +# find /etc/swift/ -type d -exec chmod 750 {} \; +``` + +这将限制只有 root 用户能够修改配置文件,同时允许服务通过其 `swift` 在组中的组成员身份读取它们。 + +#### 保护存储服务 + +以下是各种存储服务的默认侦听端口: + +| 服务名称 | 港口 | 类型 | +| -------- | ---- | ---- | +| 账户服务 | 6002 | TCP | +| 容器服务 | 6001 | TCP | +| 对象服务 | 6000 | TCP | +| 同步 [1] | 873 | TCP | + +如果使用 ssync 而不是 rsync,则使用对象服务端口来维护持久性。 + +**重要** + +```shell +在存储节点上不进行身份验证。如果能够在其中一个端口上连接到存储节点,则无需身份验证即可访问或修改数据。为了防止此问题,您应该遵循之前给出的有关使用专用存储网络的建议。 +``` + +##### 对象存储帐户术语 + +对象存储帐户不是用户帐户或凭据。下面对这些关系进行说明: + +| 对象存储帐户 | 容器的收集;不是用户帐户或身份验证。哪些用户与该帐户相关联以及他们如何访问该帐户取决于所使用的身份验证系统。请参阅对象存储身份验证。 | +| ------------ | ------------------------------------------------------------ | +| 对象存储容器 | 对象的集合。容器上的元数据可用于 ACL。ACL 的含义取决于所使用的身份验证系统。 | +| 对象存储对象 | 实际数据对象。对象级别的 ACL 也可以与元数据一起使用,并且取决于所使用的身份验证系统。 | + +在每个级别,您都有 ACL,用于指示谁拥有哪种类型的访问权限。ACL 是根据正在使用的身份验证系统进行解释的。最常用的两种身份验证提供程序类型是 Identity service (keystone) 和 TempAuth。自定义身份验证提供程序也是可能的。有关更多信息,请参阅对象存储身份验证。 + +#### 保护代理服务 + +代理节点应至少具有两个接口(物理或虚拟):一个公共接口和一个专用接口。防火墙或服务绑定可能会保护公共接口。面向公众的服务是一个 HTTP Web 服务器,用于处理端点客户端请求、对其进行身份验证并执行相应的操作。专用接口不需要任何侦听服务,而是用于建立与专用存储网络上的存储节点的传出连接。 + +##### HTTP 监听端口 + +如前所述,您应该将 Web 服务配置为非 root(无 UID 0)用户 `swift` 。需要使用大于 1024 的端口才能轻松完成此操作,并避免以 root 身份运行 Web 容器的任何部分。通常,使用 HTTP REST API 并执行身份验证的客户端会自动从身份验证响应中检索所需的完整 REST API URL。OpenStack 的 REST API 允许客户端对一个 URL 进行身份验证,然后被告知对实际服务使用完全不同的 URL。例如,客户端向 进行身份验证,并获取其身份验证密钥和存储 URL(代理节点或负载均衡器的 URL) 响应。 + +将 Web 服务器配置为以非 root 用户身份启动和运行的方法因 Web 服务器和操作系统而异。 + +##### 负载均衡器 + +如果使用 Apache 的选项不可行,或者为了提高性能,您希望减轻 TLS 工作,则可以使用专用的网络设备负载平衡器。这是在使用多个代理节点时提供冗余和负载平衡的常用方法。 + +如果选择卸载 TLS,请确保负载均衡器和代理节点之间的网络链路位于专用 (V)LAN 网段上,以便网络上的其他节点(可能已泄露)无法窃听(嗅探)未加密的流量。如果发生此类违规行为,攻击者可以访问端点客户端或云管理员凭据并访问云数据。 + +您使用的身份验证服务(例如身份服务(keystone)或TempAuth)将决定如何在对端点客户端的响应中配置不同的URL,以便它们使用负载平衡器而不是单个代理节点。 + +#### 对象存储身份验证 + +对象存储使用 WSGI 模型来提供中间件功能,该功能不仅提供通用可扩展性,还用于端点客户端的身份验证。身份验证提供程序定义存在的角色和用户类型。有些使用传统的用户名和密码凭据,而另一些则可能利用 API 密钥令牌甚至客户端 x.509 证书。自定义提供程序可以集成到使用自定义中间件中。 + +对象存储默认自带两个认证中间件模块,其中任何一个模块都可以作为开发自定义认证中间件的示例代码。 + +##### TempAuth 函数 + +TempAuth 是对象存储的默认身份验证。与 Identity 相比,它将用户帐户、凭据和元数据存储在对象存储本身中。有关更多信息,请参阅对象存储 (swift) 文档的身份验证系统部分。 + +##### Keystone + +Keystone 是 OpenStack 中常用的身份提供程序。它还可用于对象存储中的身份验证。Identity 中已提供保护 keystone 的覆盖范围。 + +#### 其他值得注意的事项 + +在 中 `/etc/swift` ,在每个节点上,都有一个设置和一个 `swift_hash_path_prefix` `swift_hash_path_suffix` 设置。提供这些是为了减少存储对象发生哈希冲突的可能性,并避免一个用户覆盖另一个用户的数据。 + +此值最初应使用加密安全的随机数生成器进行设置,并在所有节点上保持一致。确保它受到适当的 ACL 保护,并且您有备份副本以避免数据丢失。 + +## 机密管理 + +操作员通过使用各种加密应用程序来保护云部署中的敏感信息。例如,对静态数据进行加密或对映像进行签名以证明其未被篡改。在所有情况下,这些加密功能都需要某种密钥材料才能运行。 + +机密管理描述了一组旨在保护软件系统中的关键材料的技术。传统上,密钥管理涉及硬件安全模块 (HSM) 的部署。这些设备已经过物理强化,可防止篡改。 + +随着技术的进步,需要保护的秘密物品的数量已经从密钥材料增加到包括证书对、API 密钥、系统密码、签名密钥等。这种增长产生了对更具可扩展性的密钥管理方法的需求,并导致创建了许多提供可扩展动态密钥管理的软件服务。本章介绍了目前存在的服务,并重点介绍了那些能够集成到OpenStack云中的服务。 + +- 现有技术摘要 +- 相关 Openstack 项目 +- 使用案例 + - 镜像签名验证 + - 卷加密 + - 临时磁盘加密 + - Sahara + - Magnum + - Octavia/LBaaS + - Swift + - 配置文件中的密码 +- Barbican + - 概述 + - 加密插件 + - 简单的加密插件 + - PKCS#11加密插件 + - 密钥商店插件 + - KMIP插件 + - Dogtag 插件 + - Vault 插件 +- Castellan + - 概述 +- 常见问题解答 +- 检查表 + - Check-Key-Manager-01:配置文件的所有权是否设置为 root/barbican? + - Check-Key-Manager-02:是否为配置文件设置了严格的权限? + - Check-Key-Manager-03:OpenStack Identity 是否用于身份验证? + - Check-Key-Manager-04:是否启用了 TLS 进行身份验证? + +### 现有技术摘要 + +在OpenStack中,有两种推荐用于机密管理的解决方案,即Barbican和Castellan。本章将概述不同的方案,以帮助操作员选择使用哪个密钥管理器。 + +第三种不受支持的方法是固定/硬编码密钥。众所周知,某些 OpenStack 服务可以选择在其配置文件中指定密钥。这是最不安全的操作方式,我们不建议在任何类型的生产环境中使用。 + +其他解决方案包括 KeyWhiz、Confidant、Conjur、EJSON、Knox 和 Red October,但在本文档的讨论范围之外,无法涵盖所有可用的 Key Manager。 + +对于机密的存储,强烈建议使用硬件安全模块 (HSM) 。HSM 可以有多种形式。传统设备是机架式设备,如以下博客文章中所示。 + +### 相关 Openstack 项目 + +Castellan 是一个库,它提供了一个简单的通用接口来存储、生成和检索机密。大多数 Openstack 服务都使用它进行机密管理。作为一个图书馆,Castellan 本身并不提供秘密存储。相反,需要部署后端实现。 + +请注意,Castellan 不提供任何身份验证。它只是通过身份验证凭据(例如Keystone令牌)传递到后端。 + +Barbican 是一个 OpenStack 服务,为 Castellan 提供后端。Barbican 需要并验证 keystone 身份验证令牌,以识别访问或存储密钥的用户和项目。然后,它应用策略来确定是否允许访问。它还提供了许多额外的有用功能来改进密钥管理,包括配额、每个密钥的 ACL、跟踪密钥使用者以及密钥容器中的密钥分组。例如,明锐直接与巴比肯(而不是卡斯特拉兰)集成,以利用其中一些功能。 + +Barbican 有许多后端插件,可用于将机密安全地存储在本地数据库或 HSM 中。 + +目前,Barbican 是 Castellan 唯一可用的后端。然而,有几个后端正在开发中,包括 KMIP、Dogtag、Hashicorp Vault 和 Custodia。对于那些不希望部署 Barbican 并且密钥管理需求相对简单的部署人员来说,使用这些后端之一可能是一个可行的替代方案。但是,在检索密钥时,缺少的是多租户和租户策略的实施,以及上面提到的任何额外功能。 + +### 使用案例 + +#### 镜像签名验证 + +验证镜像签名可确保镜像自原始上传以来不会被替换或更改。镜像签名验证功能使用 Castellan 作为其密钥管理器来存储加密签名。镜像签名和证书 UUID 将与镜像一起上传到镜像 (glance) 服务。Glance 在从密钥管理器检索证书后验证签名。启动镜像时,计算服务 (nova) 在从密钥管理器检索证书后验证签名。 + +有关更多详细信息,请参阅可信映像文档。 + +#### 卷加密 + +卷加密功能使用 Castellan 提供静态数据加密。当用户创建加密卷类型并使用该类型创建卷时,块存储 (cinder) 服务会请求密钥管理器创建要与该卷关联的密钥。当卷附加到实例时,nova 会检索密钥。 + +有关详细信息,请参阅数据加密部分。和卷加密。 + +#### 临时磁盘加密 + +临时磁盘加密功能可解决数据隐私问题。临时磁盘是虚拟主机操作系统使用的临时工作空间。如果不加密,可以在此磁盘上访问敏感的用户信息,并且在卸载磁盘后可能会保留残留信息。 + +临时磁盘加密功能可以通过安全包装器与密钥管理服务交互,并通过按租户提供临时磁盘加密密钥来支持数据隔离。建议使用后端密钥存储以增强安全性(例如,HSM 或 KMIP 服务器可用作 barbican 后端密钥存储)。 + +有关详细信息,请参阅临时磁盘加密文档。 + +#### Sahara + +Sahara在操作过程中生成并存储多个密码。为了加强Sahara对密码的使用,可以指示它使用外部密钥管理器来存储和检索这些密钥。要启用此功能,必须首先在堆栈中部署一个 OpenStack Key Manager 服务。 + +在堆栈上部署密钥管理器服务后,必须将 sahara 配置为启用密钥的外部存储。Sahara 使用 Castellan 库与 OpenStack Key Manager 服务进行交互。此库提供对密钥管理器的可配置访问。 + +有关详细信息,请参阅 Sahara 高级配置指南。 + +#### Magnum + +为了使用本机客户端( `docker` 或 `kubectl` 分别)提供对 Docker Swarm 或 Kubernetes 的访问,magnum 使用 TLS 证书。要存储证书,建议使用 Barbican 或 Magnum 数据库 ( `x590keypair` )。 + +也可以使用本地目录 ( `local` ),但被认为是不安全的,不适合生产环境。 + +有关为 Magnum 设置证书管理器的更多详细信息,请参阅容器基础架构管理服务文档。 + +#### Octavia/LBaaS + +Neutron 和 Octavia 项目的 LBaaS(负载均衡器即服务)功能需要证书及其私钥来为 TLS 连接提供负载均衡。Barbican 可用于存储此敏感信息。 + +有关详细信息,请参阅如何创建 TLS 负载均衡器和部署以 TLS 结尾的 HTTPS 负载均衡器。 + +#### Swift + +对称密钥可用于加密 Swift 容器,以降低用户数据被读取的风险,如果未经授权的一方要获得对磁盘的物理访问权限。 + +有关更多详细信息,请参阅官方 swift 文档中的对象加密部分。 + +#### 配置文件中的密码 + +OpenStack 服务的配置文件包含许多纯文本密码。例如,这些包括服务用户用于向 keystone 进行身份验证以验证 keystone 令牌的密码。 + +目前没有对这些密码进行模糊处理的解决方案。建议通过文件权限适当地保护这些文件。 + +目前正在努力将这些密钥存储在 Castellan 后端,然后让 oslo.config 使用 Castellan 来检索这些密钥。 + +### Barbican + +#### 概述 + +Barbican 是一个 REST API,旨在安全存储、配置和管理密码、加密密钥和 X.509 证书等机密。它旨在对所有环境都有用,包括大型短暂云。 + +Barbican 与多个 OpenStack 功能集成,可以直接集成,也可以作为 Castellan 的后端集成。 + +Barbican 通常用作密钥管理系统,以实现图像签名验证、卷加密等用例。这些用例在用例中进行了概述 + +##### Barbican 基于角色的访问控制 + +待定 + +##### 机密存储后端 + +Key Manager 服务具有插件架构,允许部署程序将密钥存储在一个或多个密钥存储中。机密存储可以是基于软件的(如软件令牌),也可以是基于硬件设备(如硬件安全模块 (HSM))的。本节介绍当前可用的插件,并讨论每个插件的安全状况。插件已启用并使用配置文件中的 `/etc/barbican/barbican.conf` 设置进行配置。 + +有两种类型的插件:加密插件和机密存储插件。 + +#### 加密插件 + +加密插件将机密存储为 Barbican 数据库中的加密 blob。调用该插件来加密密钥存储上的密钥,并在密钥检索时解密密钥。目前有两种类型的存储插件可用:Simple Crypto 插件和 PKCS#11 加密插件。 + +#### 简单的加密插件 + +默认情况下,在 中 `barbican.conf` 配置了简单的加密插件。该插件使用单个对称密钥(KEK - 或“密钥加密密钥”),该密钥以纯文本形式存储在 `barbican.conf` 文件中,以加密和解密所有机密。此插件被认为是不太安全的选项,仅适用于开发和测试,因为主密钥以纯文本形式存储在配置文件中,因此不建议在生产部署中使用。 + +#### PKCS#11 加密插件 + +PKCS#11 加密插件可用于与使用 PKCS#11 协议的硬件安全模块 (HSM) 连接。机密由项目特定的密钥加密密钥 (KEK) 加密 (并在检索时解密) 。KEK 受主 KEK (MKEK) 保护(加密)。MKEK 与 HMAC 一起驻留在 HSM 中。由于每个项目都使用不同的 KEK,并且由于 KEK 以加密形式(而不是配置文件中的明文)存储在数据库中,因此 PKCS#11 插件比简单的加密插件安全得多。它是 Barbican 部署中最受欢迎的后端。 + +#### 机密存储插件 + +密钥存储插件与安全存储系统接口,以将密钥存储在这些系统中。密钥存储插件有三种类型:KMIP 插件、Dogtag 插件和 Vault 插件。 + +#### KMIP 插件 + +密钥管理互操作性协议 (KMIP) 密钥存储插件用于与启用了 KMIP 的设备(如硬件安全模块 (HSM))进行通信。密钥直接安全地存储在启用了 KMIP 的设备中,而不是存储在 Barbican 数据库中。Barbican 数据库维护对密钥位置的引用,以供以后检索。该插件可以配置为使用用户名和密码或使用客户端证书向启用了 KMIP 的设备进行身份验证。此信息存储在 Barbican 配置文件中。 + +#### Dogtag 插件 + +Dogtag 秘密存储插件用于与 Dogtag 通信。Dogtag 是对应于 Red Hat 证书系统的上游项目,Red Hat Certificate System 是一个通用标准/FIPS 认证的 PKI 解决方案,包含证书管理器 (CA) 和密钥恢复机构 (KRA),用于安全存储机密。KRA 将机密作为加密的 blob 存储在其内部数据库中,主加密密钥存储在基于软件的 NSS 安全数据库中,或存储在硬件安全模块 (HSM) 中。基于软件的 NSS 数据库配置为不希望使用 HSM 的部署提供了安全选项。KRA 是 FreeIPA 的一个组件,因此可以使用 FreeIPA 服务器配置插件。以下博客文章中提供了有关如何使用 FreeIPA 设置 Barbican 的更详细说明。 + +#### Vault 插件 + +Vault 是 Hashicorp 开发的秘密存储,用于安全访问机密和其他对象,例如 API 密钥、密码或证书。保险柜为任何机密提供统一的界面,同时提供严格的访问控制并记录详细的审核日志。Vault 企业版还允许与 HSM 集成以进行自动解封、提供 FIPS 密钥存储和熵增强。但是,Vault 插件的缺点是它不支持多租户,因此所有密钥都将存储在同一个键/值密钥引擎下。挂载点。 + +##### 威胁分析 + +Barbican 团队与 OpenStack 安全项目合作,对最佳实践 Barbican 部署进行了安全审查。安全审查的目的是识别服务设计和体系结构中的弱点和缺陷,并提出解决这些问题的控制或修复措施。 + +巴比肯威胁分析确定了八项安全发现和两项建议,以提高巴比肯部署的安全性。这些结果可以在安全分析存储库中查看,以及 Barbican 体系结构图和体系结构描述页。 + +### Castellan + +#### 概述 + +Castellan 是由 Barbican 团队开发的通用密钥管理器界面。它使项目能够使用可配置的密钥管理器,该管理器可以特定于部署。 + +### 常见问题解答 + +​ 1.在 OpenStack 中安全存储密钥的推荐方法是什么? + +在OpenStack中安全地存储和管理密钥的推荐方法是使用Barbican。 + +​ 2.我为什么要使用Barbican? + +Barbican 是一种 OpenStack 服务,它支持多租户,并使用 Keystone 令牌进行身份验证。这意味着对密钥的访问是通过租户和 RBAC 角色的 OpenStack 策略来控制的。 + +Barbican 具有多个可插拔后端,可以使用 PKCS#11 或 KMIP 与基于软件和硬件的安全模块进行通信。 + +​ 3.如果我不想使用Barbican怎么办? + +在 Openstack 上下文中,需要管理两种类型的密钥 - 需要密钥失真令牌才能访问的密钥,以及不需要密钥验证令牌的密钥。 + +需要 keystone 身份验证的密钥的一个示例是特定项目拥有的密码和密钥。例如,这些包括项目加密煤渣卷的加密密钥或项目概览图像的签名密钥。 + +不需要 keystone 令牌即可访问的密钥示例包括服务配置文件中服务用户的密码或不属于任何特定项目的加密密钥。 + +需要 keystone 令牌的机密应使用 Barbican 进行存储。 + +不需要 keystone 身份验证的密钥可以存储在任何密钥存储中,该密钥存储实现了通过 Castellan 公开的简单密钥存储 API。这也包括巴比肯。 + +​ 4.如何使用 Vault、Keywhiz、Custodia 等...? + +如果已为该密钥管理器编写了 Castellan 插件,则您选择的密钥管理器可以与该密钥管理器一起使用。一旦该插件被编写出来,直接使用该插件或在 Barbican 后面使用该插件是相对微不足道的。 + +目前,Vault 和 Custodia 插件正在为 Queens 周期开发。 + +### 检查表 + +#### Check-Key-Manager-01:配置文件的所有权是否设置为 root/barbican? + +配置文件包含组件平稳运行所需的关键参数和信息。如果非特权用户有意或无意地修改或删除任何参数或文件本身,则会导致严重的可用性问题,从而导致拒绝向其他最终用户提供服务。此类关键配置文件的用户所有权必须设置为 root,组所有权必须设置为 barbican。此外,包含目录应具有相同的所有权,以确保正确拥有新文件。 + +运行以下命令: + +```shell +$ stat -L -c "%U %G" /etc/barbican/barbican.conf | egrep "root barbican" +$ stat -L -c "%U %G" /etc/barbican/barbican-api-paste.ini | egrep "root barbican" +$ stat -L -c "%U %G" /etc/barbican/policy.json | egrep "root barbican" +$ stat -L -c "%U %G" /etc/barbican | egrep "root barbican" +``` + +通过:如果所有这些配置文件的用户和组所有权分别设置为 root 和 barbican。上面的命令显示了 root / barbican 的输出。 + +失败:如果上述命令未返回任何输出,则用户和组所有权可能已设置为除 root 以外的任何用户或除 barbican 以外的任何组。 + +#### Check-Key-Manager-02:是否为配置文件设置了严格的权限? + +与前面的检查类似,我们建议为此类配置文件设置严格的访问权限。 + +运行以下命令: + +```shell +$ stat -L -c "%a" /etc/barbican/barbican.conf +$ stat -L -c "%a" /etc/barbican/barbican-api-paste.ini +$ stat -L -c "%a" /etc/barbican/policy.json +$ stat -L -c "%a" /etc/barbican +``` + +还可以进行更广泛的限制:如果包含目录设置为 750,则保证此目录中新创建的文件具有所需的权限。 + +通过:如果权限设置为 640 或更严格,或者包含目录设置为 750。640 的权限转换为所有者 r/w、组 r,而对其他人没有权限,例如“u=rw,g=r,o=”。 + +**注意** + +```shell +使用 Check-Key-Manager-01:配置文件的所有权是否设置为 root/barbican?权限设置为 640,root 具有读/写访问权限,Barbican 具有对这些配置文件的读取访问权限。也可以使用以下命令验证访问权限。仅当此命令支持 ACL 时,它才在您的系统上可用。 +``` + +```shell +$ getfacl --tabular -a /etc/barbican/barbican.conf +getfacl: Removing leading '/' from absolute path names +# file: etc/barbican/barbican.conf +USER root rw- +GROUP barbican r-- +mask r-- +other --- +``` + +失败:如果权限设置大于 640。 + +#### Check-Key-Manager-03:OpenStack Identity 是否用于身份验证? + +OpenStack 支持各种身份验证策略,如 `noauth` 和 `keystone` 。如果使用该 `noauth` 策略,则用户无需任何身份验证即可与 OpenStack 服务进行交互。这可能是一个潜在的风险,因为攻击者可能会获得对 OpenStack 组件的未经授权的访问。我们强烈建议所有服务都必须使用其服务帐户通过 keystone 进行身份验证。 + +通过:如果参数 `authtoken` 列在 中的 `pipeline:barbican-api-keystone` `barbican-api-paste.ini` 部分下。 + +失败:如果 中的 `pipeline:barbican-api-keystone` `barbican-api-paste.ini` 部分下缺少该参数 `authtoken` 。 + +#### Check-Key-Manager-04:是否启用了 TLS 进行身份验证? + +OpenStack 组件使用各种协议相互通信,通信可能涉及敏感或机密数据。攻击者可能会尝试窃听频道以访问敏感信息。所有组件必须使用安全通信协议相互通信。 + +通过:如果 section in `/etc/barbican/barbican.conf` 下的参数值设置为 Identity API 端点开头, `https://` 并且 same `/etc/barbican/barbican.conf` 中同一 `[keystone_authtoken]` 部分下的 `[keystone_authtoken]` 参数 `www_authenticate_uri` `insecure` 值设置为 `False` 。 + +失败:如果 in `/etc/barbican/barbican.conf` 部分下的 `[keystone_authtoken]` 参数 `www_authenticate_uri` 值未设置为以 开头的身份 API 端点, `https://` 或者同一 `/etc/barbican/barbican.conf` 部分中的参数 `insecure` `[keystone_authtoken]` 值设置为 `True` 。 + +## 消息队列 + +消息队列服务促进了 OpenStack 中的进程间通信。OpenStack 支持以下消息队列服务后端: + +- RabbitMQ +- Qpid +- ZeroMQ 或 0MQ + +RabbitMQ 和 Qpid 都是高级消息队列协议 (AMQP) 框架,它们为点对点通信提供消息队列。队列实现通常部署为集中式或分散式队列服务器池。ZeroMQ 通过 TCP 套接字提供直接的点对点通信。 + +消息队列有效地促进了跨 OpenStack 部署的命令和控制功能。一旦允许访问队列,就不会执行进一步的授权检查。可通过队列访问的服务会验证实际消息负载中的上下文和令牌。但是,您必须注意令牌的到期日期,因为令牌可能可重播,并且可以授权基础结构中的其他服务。 + +OpenStack 不支持消息级别的安全性,例如消息签名。因此,您必须对消息传输本身进行安全和身份验证。对于高可用性 (HA) 配置,您必须执行队列对队列的身份验证和加密。 + +通过 ZeroMQ 消息传递,IPC 套接字在单个机器上使用。由于这些套接字容易受到攻击,因此请确保云运营商已保护它们。 + +- 消息安全 + - 消息传输安全 + - 队列身份验证和访问控制 + - 消息队列进程隔离和策略 + +### 消息安全 + +本节讨论 OpenStack 中使用的三种最常见的消息队列解决方案的安全强化方法:RabbitMQ、Qpid 和 ZeroMQ。 + +#### 消息传输安全 + +基于 AMQP 的解决方案(Qpid 和 RabbitMQ)支持使用 TLS 的传输级安全性。ZeroMQ 消息传递本身不支持 TLS,但使用标记的 IPsec 或 CIPSO 网络标签可以实现传输级安全性。 + +我们强烈建议为您的消息队列启用传输级加密。将 TLS 用于消息传递客户端连接可以保护通信在传输到消息传递服务器的过程中不被篡改和窃听。以下是有关如何为两个常用消息传递服务器 Qpid 和 RabbitMQ 配置 TLS 的指南。在配置消息传递服务器用于验证客户机连接的可信证书颁发机构 (CA) 捆绑软件时,建议仅将其限制为用于节点的 CA,最好是内部管理的 CA。受信任的 CA 捆绑包将确定哪些客户端证书将获得授权,并通过设置 TLS 连接的客户端-服务器验证步骤。请注意,在安装证书和密钥文件时,请确保文件权限受到限制,例如使用 `chmod 0600` ,并且所有权限制为消息传递服务器守护程序用户,以防止消息传递服务器上的其他进程和用户进行未经授权的访问。 + +##### RabbitMQ 服务器 SSL 配置 + +应将以下行添加到系统范围的 RabbitMQ 配置文件中,通常 `/etc/rabbitmq/rabbitmq.config` : + +```shell +[ + {rabbit, [ + {tcp_listeners, [] }, + {ssl_listeners, [{"", 5671}] }, + {ssl_options, [{cacertfile,"/etc/ssl/cacert.pem"}, + {certfile,"/etc/ssl/rabbit-server-cert.pem"}, + {keyfile,"/etc/ssl/rabbit-server-key.pem"}, + {verify,verify_peer}, + {fail_if_no_peer_cert,true}]} + ]} +]. +``` + +请注意,该 `tcp_listeners` 选项设置为 `[]` 阻止它侦听非 SSL 端口。应将该 `ssl_listeners` 选项限制为仅在管理网络上侦听服务。 + +有关 RabbitMQ SSL 配置的更多信息,请参阅: + +- RabbitMQ 配置 +- RabbitMQ SSL协议 + +##### Qpid 服务器 SSL 配置 + +Apache 基金会为 Qpid 提供了消息传递安全指南。请参阅: + +- Apache Qpid SSL + +#### 队列认证和访问控制 + +RabbitMQ 和 Qpid 提供身份验证和访问控制机制,用于控制对队列的访问。ZeroMQ 不提供此类机制。 + +简单身份验证和安全层 (SASL) 是 Internet 协议中用于身份验证和数据安全的框架。RabbitMQ 和 Qpid 都提供 SASL 和其他可插入的身份验证机制,而不仅仅是简单的用户名和密码,从而可以提高身份验证安全性。虽然 RabbitMQ 支持 SASL,但 OpenStack 中的支持目前不允许请求特定的 SASL 身份验证机制。OpenStack 中的 RabbitMQ 支持允许通过未加密的连接进行用户名和密码身份验证,或者将用户名和密码与 X.509 客户端证书结合使用,以建立安全的 TLS 连接。 + +我们建议在所有 OpenStack 服务节点上配置 X.509 客户端证书,以便客户端连接到消息传递队列,并在可能的情况下(目前仅 Qpid)使用 X.509 客户端证书执行身份验证。使用用户名和密码时,应按服务和节点创建帐户,以便对队列的访问进行更精细的可审核性。 + +在部署之前,请考虑排队服务器使用的 TLS 库。Qpid 使用 Mozilla 的 NSS 库,而 RabbitMQ 使用 Erlang 的 TLS 模块,该模块使用 OpenSSL。 + +##### 身份验证配置示例:RabbitMQ + +在 RabbitMQ 服务器上,删除默认 `guest` 用户: + +```shell +# rabbitmqctl delete_user guest +``` + +在 RabbitMQ 服务器上,对于与消息队列通信的每个 OpenStack 服务或节点,请设置用户帐户和权限: + +```shell +# rabbitmqctl add_user compute01 RABBIT_PASS +# rabbitmqctl set_permissions compute01 ".*" ".*" ".*" +``` + +将RABBIT_PASS替换为合适的密码。 + +有关其他配置信息,请参阅: + +- RabbitMQ 访问控制 +- RabbitMQ 身份验证 +- RabbitMQ 插件 +- RabbitMQ SASL 外部身份验证 + +##### OpenStack 服务配置:RabbitMQ + +```shell +[DEFAULT] +rpc_backend = nova.openstack.common.rpc.impl_kombu +rabbit_use_ssl = True +rabbit_host = RABBIT_HOST +rabbit_port = 5671 +rabbit_user = compute01 +rabbit_password = RABBIT_PASS +kombu_ssl_keyfile = /etc/ssl/node-key.pem +kombu_ssl_certfile = /etc/ssl/node-cert.pem +kombu_ssl_ca_certs = /etc/ssl/cacert.pem +``` + +##### 身份验证配置示例:Qpid + +有关配置信息,请参阅: + +- Apache Qpid 身份验证 +- Apache Qpid 授权 + +##### OpenStack 服务配置:Qpid + +```shell +[DEFAULT] +rpc_backend = nova.openstack.common.rpc.impl_qpid +qpid_protocol = ssl +qpid_hostname = +qpid_port = 5671 +qpid_username = compute01 +qpid_password = QPID_PASS +``` + +(可选)如果将 SASL 与 Qpid 一起使用,请通过添加以下内容来指定正在使用的 SASL 机制: + +```shell +qpid_sasl_mechanisms = +``` + +#### 消息队列进程隔离和策略 + +每个项目都提供了许多发送和使用消息的服务。每个发送消息的二进制文件都应该使用队列中的消息,如果只是回复的话。 + +消息队列服务进程应彼此隔离,并应与计算机上的其他进程隔离。 + +##### 命名空间 + +强烈建议在 OpenStack Compute Hypervisor 上运行的所有服务使用网络命名空间。这将有助于防止 VM 来宾和管理网络之间的网络流量桥接。 + +使用 ZeroMQ 消息传递时,每个主机必须至少运行一个 ZeroMQ 消息接收器,以接收来自网络的消息并通过 IPC 将消息转发到本地进程。在 IPC 命名空间中为每个项目运行一个独立的消息接收器是可能的,也是可取的,以及同一项目中的其他服务。 + +##### 网络策略 + +队列服务器应仅接受来自管理网络的连接。这适用于所有实现。这应通过服务配置来实现,并可选择通过全局网络策略强制实施。 + +使用 ZeroMQ 消息传递时,每个项目都应在专用于属于该项目的服务的端口上运行单独的 ZeroMQ 接收方进程。这相当于 AMQP 的控制交换概念。 + +##### 强制访问控制 + +使用强制访问控制 (MAC) 和自由访问控制 (DAC) 将进程的配置限制为仅这些进程。此限制可防止这些进程与在同一台计算机上运行的其他进程隔离。 + +## 数据处理 + +数据处理服务(sahara)提供了一个平台,用于使用Hadoop和Spark等处理框架来配置和管理实例集群。通过 OpenStack Dashboard 或 REST API,用户能够上传和执行框架应用程序,这些应用程序可以访问对象存储或外部提供程序中的数据。数据处理控制器使用编排服务 (heat) 创建实例集群,这些集群可以作为长期运行的组存在,这些组可以根据请求进行扩展和收缩,也可以作为为单个工作负载创建的瞬态组存在。 + +- 数据处理简介 + - 架构 + - 涉及的技术 + - 用户对资源的访问权限 +- 部署 + - 控制器对集群的网络访问 +- 配置和强化 + - TLS + - 基于角色的访问控制策略 + - 安全组 + - 代理域 + - 自定义网络拓扑 + - 间接访问 + - 根包装 + - 日志记录 + - 参考书目 + +### 数据处理简介 + +数据处理服务控制器将负责创建、维护和销毁为其集群创建的任何实例。控制器将使用网络服务在自身和集群实例之间建立网络路径。它还将管理要在集群上运行的用户应用程序的部署和生命周期。集群中的实例包含框架处理引擎的核心,数据处理服务提供了多个选项来创建和管理与这些实例的连接。 + +数据处理资源(群集、作业和数据源)按身份服务中定义的项目进行分隔。这些资源在项目中共享,了解使用该服务的人员的访问需求非常重要。通过使用基于角色的访问控制,可以进一步限制项目中的活动(例如启动集群、上传作业等)。 + +在本章中,我们将讨论如何评估数据处理用户对其应用程序、他们使用的数据以及他们在项目中的预期功能的需求。我们还将演示服务控制器及其集群的一些强化技术,并提供各种控制器配置和用户管理方法的示例,以确保足够的安全和隐私级别。 + +#### 架构 + +下图显示了数据处理服务如何适应更大的 OpenStack 生态系统的概念视图。 + +![../_images/data_processing_architecture.png](https://docs.openstack.org/security-guide/_images/data_processing_architecture.png) + +数据处理服务在集群配置过程中大量使用计算、编排、镜像和块存储服务。它还将使用在群集创建期间提供的由网络服务创建的一个或多个网络来管理实例。当用户运行框架应用程序时,控制器和集群将访问对象存储服务。鉴于这些服务用法,我们建议按照系统文档中概述的说明对安装的所有组件进行编目。 + +#### 涉及的技术 + +数据处理服务负责部署和管理多个应用程序。为了全面了解所提供的安全选项,我们建议操作员大致熟悉这些应用程序。突出显示的技术列表分为两部分:第一部分,对安全性影响较大的高优先级应用程序,第二部分,支持影响较小的应用程序。 + +更高的影响 + +- Hadoop +- Hadoop安全模式文档 +- HDFS +- Spark +- Spark 安全 +- Storm +- Zookeeper + +较低的影响 + +- Oozie +- Hive +- Pig + +这些技术构成了与数据处理服务一起部署的框架的核心。除了这些技术之外,该服务还包括第三方供应商提供的捆绑框架。这些捆绑框架是使用上述相同核心部分以及供应商包含的配置和应用程序构建的。有关第三方框架捆绑包的更多信息,请参阅以下链接: + +- Cloudera CDH +- Hortonworks Data Platform +- MapR + +#### 用户访问资源 + +数据处理服务的资源(集群、作业和数据源)在项目范围内共享。尽管单个控制器安装可以管理多组资源,但这些资源的范围将限定为单个项目。鉴于此限制,我们建议密切监视项目中的用户成员身份,以保持资源的适当隔离。 + +由于部署此服务的组织的安全要求会根据其特定需求而有所不同,因此我们建议运营商将重点放在数据隐私、集群管理和最终用户应用程序上,作为评估用户需求的起点。这些决策将有助于指导配置用户对服务的访问的过程。有关数据隐私的扩展讨论,请参阅租户数据隐私。 + +数据处理安装的默认假设是用户将有权访问其项目中的所有功能。如果需要更精细的控制,数据处理服务会提供策略文件(如策略中所述)。这些配置将高度依赖于安装组织的需求,因此没有关于其使用的一般建议:有关详细信息,请参阅基于角色的访问控制策略。 + +### 部署 + +与许多其他 OpenStack 服务一样,数据处理服务被部署为在连接到堆栈的主机上运行的应用程序。从 Kilo 版本开始,它能够以分布式方式部署多个冗余控制器。与其他服务一样,它也需要一个数据库来存储有关其资源的信息。请参阅数据库。请务必注意,数据处理服务将需要管理多个标识服务信任,直接与业务流程和网络服务通信,并可能在代理域中创建用户。由于这些原因,控制器将需要访问控制平面,因此我们建议将其与其他服务控制器一起安装。 + +数据处理直接与多个 OpenStack 服务交互: + +- 计算 +- 身份验证 +- 联网 +- 对象存储 +- 配器 +- 块存储(可选) + +建议记录这些服务与数据处理控制器之间的所有数据流和桥接点。请参阅系统文档。 + +数据处理服务使用对象存储服务来存储作业二进制文件和数据源。希望访问完整数据处理服务功能的用户将需要在他们正在使用的项目中存储对象。 + +网络服务在群集的配置中起着重要作用。在预配之前,用户应为群集实例提供一个或多个网络。关联网络的操作类似于通过仪表板启动实例时分配网络的过程。控制器使用这些网络对其集群的实例和框架进行管理访问。 + +另外值得注意的是身份服务。数据处理服务的用户需要在其项目中具有适当的角色,以允许为其集群预置实例。使用代理域配置的安装需要特别注意。请参阅代理域。具体而言,数据处理服务将需要能够在代理域中创建用户。 + +#### 控制器对集群的网络访问 + +数据处理控制器的主要任务之一是与其生成的实例进行通信。这些实例是预置的,然后根据所使用的框架进行配置。控制器和实例之间的通信使用安全外壳 (SSH) 和 HTTP 协议。 + +在预配集群时,将在用户提供的网络中为每个实例提供一个 IP 地址。第一个网络通常称为数据处理管理网络,实例可以使用网络服务为此网络分配的固定 IP 地址。控制器还可以配置为除了固定地址之外,还对实例使用浮动 IP 地址。与实例通信时,控制器将首选浮动地址(如果启用)。 + +对于固定和浮动 IP 地址无法提供所需功能的情况,控制器可以通过两种替代方法提供访问:自定义网络拓扑和间接访问。自定义网络拓扑功能允许控制器通过配置文件中提供的 shell 命令访问实例。间接访问用于指定用户在集群置备期间可用作代理网关的实例。这些选项通过配置和强化中的用法示例进行讨论。 + +### 配置和强化 + +有多个配置选项和部署策略可以提高数据处理服务的安全性。服务控制器通过主配置文件和一个或多个策略文件进行配置。使用数据局部性功能的安装还将具有两个附加文件,用于指定计算节点和对象存储节点的物理位置。 + +#### TLS系统 + +与许多其他 OpenStack 控制器一样,数据处理服务控制器可以配置为需要 TLS 连接。 + +Pre-Kilo 版本将需要 TLS 代理,因为控制器不允许直接 TLS 连接。TLS 代理和 HTTP 服务中介绍了如何配置 TLS 代理,我们建议按照其中的建议创建此类安装。 + +从 Kilo 版本开始,数据处理控制器允许直接 TLS 连接,我们建议这样做。启用此行为需要对控制器配置文件进行一些小的调整。 + +**例。配置对控制器的 TLS 访问** + +```shell +[ssl] +ca_file = cafile.pem +cert_file = certfile.crt +key_file = keyfile.key +``` + +#### 基于角色的访问控制策略 + +数据处理服务使用策略文件(如策略中所述)来配置基于角色的访问控制。使用策略文件,操作员可以限制组对特定数据处理功能的访问。 + +执行此操作的原因将根据安装的组织要求而更改。通常,这些细粒度控件用于操作员需要限制数据处理服务资源的创建、删除和检索的情况。需要限制项目内访问的操作员应充分意识到,需要有其他方法让用户访问服务的核心功能(例如,配置集群)。 + +**例。允许所有用户使用所有方法(默认策略)** + +```shell +{ + "default": "" +} +``` + +**例。禁止对非管理员用户进行映像注册表操作** + +```shell +{ + "default": "", + + "data-processing:images:register": "role:admin", + "data-processing:images:unregister": "role:admin", + "data-processing:images:add_tags": "role:admin", + "data-processing:images:remove_tags": "role:admin" +} +``` + +#### 安全组 + +数据处理服务允许将安全组与为其集群预置的实例相关联。无需其他配置,该服务将对预置集群的任何项目使用默认安全组。如果请求,可以使用不同的安全组,或者存在一个自动选项,该选项指示服务根据所访问框架指定的端口创建安全组。 + +对于生产环境,我们建议手动控制安全组,并创建一组适合安装的组规则。通过这种方式,操作员可以确保默认安全组将包含所有适当的规则。有关安全组的扩展讨论,请参阅安全组。 + +#### 代理域 + +将对象存储服务与数据处理结合使用时,需要添加存储访问凭据。使用代理域,数据处理服务可以改用来自标识服务的委派信任,以允许通过域中创建的临时用户进行存储访问。要使此委派机制起作用,必须将数据处理服务配置为使用代理域,并且操作员必须为代理用户配置身份域。 + +数据处理控制器保留为对象存储访问提供的用户名和密码的临时存储。使用代理域时,控制器将为代理用户生成此对,并且此用户的访问将仅限于身份信任的访问。我们建议在控制器或其数据库具有与公共网络之间的路由的任何安装中使用代理域。 + +**示例:为名为“dp_proxy”的代理域进行配置** + +```shell +[DEFAULT] +use_domain_for_proxy_users = true +proxy_user_domain_name = dp_proxy +proxy_user_role_names = Member +``` + +#### 自定义网络拓扑 + +数据处理控制器可以配置为使用代理命令来访问其集群实例。通过这种方式,可以为不使用网络服务直接提供的网络的安装创建自定义网络拓扑。对于需要限制控制器和实例之间访问的安装,我们建议使用此选项。 + +**示例:通过指定的中继机访问实例** + +```shell +[DEFAULT] +proxy_command='ssh relay-machine-{tenant_id} nc {host} {port}' +``` + +**示例:通过自定义网络命名空间访问实例** + +```shell +[DEFAULT] +proxy_command='ip netns exec ns_for_{network_id} nc {host} {port}' +``` + +#### 间接访问 + +对于控制器对集群所有实例的访问权限有限的安装,由于对浮动 IP 地址或安全规则的限制,可以配置间接访问。这允许将某些实例指定为集群其他实例的代理网关。 + +只有在定义将构成数据处理集群的节点组模板时,才能启用此配置。它作为运行时选项提供,可在群集置备过程中启用。 + +#### Rootwrap + +在为网络访问创建自定义拓扑时,可能需要允许非 root 用户运行代理命令。对于这些情况,oslo rootwrap 软件包用于为非 root 用户提供运行特权命令的工具。此配置要求与数据处理控制器应用程序关联的用户位于 sudoers 列表中,并在配置文件中启用该选项。或者,可以提供备用 rootwrap 命令。 + +**示例:启用 rootwrap 用法并显示默认命令** + +```shell +[DEFAULT] +use_rootwrap=True +rootwrap_command=’sudo sahara-rootwrap /etc/sahara/rootwrap.conf’ +``` + +关于 rootwrap 项目的更多信息,请参考官方文档: + +#### 日志 + +监视服务控制器的输出是一个强大的取证工具,如监视和日志记录中更详细地描述的那样。数据处理服务控制器提供了几个选项来设置日志记录的位置和级别。 + +**示例:将日志级别设置为高于警告并指定输出文件。** + +```shell +[DEFAULT] +verbose = true +log_file = /var/log/data-processing.log +``` + +#### 参考书目 + +OpenStack.org,欢迎来到Sahara!2016.Sahara项目文档 + +Apache 软件基金会,欢迎来到 Apache Hadoop!2016. Apache Hadoop 项目 + +Apache 软件基金会,安全模式下的 Hadoop。2016. Hadoop 安全模式文档 + +Apache 软件基金会,HDFS 用户指南。2016. Hadoop HDFS 文档 + +Apache 软件基金会,Spark。2016. Spark项目 + +Apache 软件基金会,Spark Security。2016. Spark 安全文档 + +Apache 软件基金会,Apache Storm。2016. Storm 项目 + +Apache 软件基金会,Apache Zookeeper。2016. Zookeeper 项目 + +Apache 软件基金会,Apache Oozie Workflow Scheduler for Hadoop。2016. Oozie项目 + +Apache 软件基金会,Apache Hive。2016. Hive + +Apache 软件基金会,欢迎来到 Apache Pig。2016.Pig + +Apache 软件基金会,Cloudera 产品文档。2016. Cloudera CDH 文档 + +Hortonworks,Hortonworks。2016. Hortonworks 数据平台文档 + +MapR Technologies,用于 MapR 融合数据平台的 Apache Hadoop。2016. MapR 项目 + +## 数据库 + +数据库服务器的选择是 OpenStack 部署安全性的一个重要考虑因素。在决定使用数据库服务器时,应考虑多种因素,但在本本书的范围内,将只讨论安全注意事项。OpenStack 支持多种数据库类型。有关更多信息,请参阅《OpenStack 管理员指南》。 + +《安全指南》目前主要针对 PostgreSQL 和 MySQL。 + +- 数据库后端注意事项 + - 数据库后端的安全参考 +- 数据库访问控制 + - OpenStack 数据库访问模型 + - 数据库身份验证和访问控制 + - 要求用户帐户需要 SSL 传输 + - 使用 X.509 证书进行身份验证 + - OpenStack 服务数据库配置 + - Nova-conductor +- 数据库传输安全性 + - 数据库服务器 IP 地址绑定 + - 数据库传输 + - MySQL SSL配置 + - PostgreSQL SSL 配置 + +### 数据库后端注意事项 + +PostgreSQL 具有许多理想的安全功能,例如 Kerberos 身份验证、对象级安全性和加密支持。PostgreSQL 社区在提供可靠的指导、文档和工具以促进积极的安全实践方面做得很好。 + +MySQL拥有庞大的社区,被广泛采用,并提供高可用性选项。MySQL还能够通过插件身份验证机制提供增强的客户端身份验证。MySQL社区中的分叉发行版提供了许多可供考虑的选项。根据对安全态势的全面评估和为给定发行版提供的支持级别,选择MySQL的特定实现非常重要。 + +#### 数据库后端的安全参考 + +建议部署 MySQL 或 PostgreSQL 的用户参考现有的安全指南。下面列出了一些参考资料: + +MySQL数据库: + +- OWASP MySQL强化 + +- MySQL 可插入身份验证 +- MySQL中的安全性 + +PostgreSQL格式: + +- OWASP PostgreSQL 强化 +- PostgreSQL 数据库中的总体安全性 + +### 数据库访问控制 + +每个核心 OpenStack 服务(计算、身份、网络、块存储)都将状态和配置信息存储在数据库中。在本章中,我们将讨论当前在OpenStack中使用数据库的方式。我们还探讨了安全问题,以及数据库后端选择的安全后果。 + +#### OpenStack 数据库访问模型 + +OpenStack 项目中的所有服务都访问单个数据库。目前没有用于创建基于表或行的数据库访问限制的参考策略。 + +在OpenStack中,没有对数据库操作进行精细控制的一般规定。访问权限和特权的授予仅基于节点是否有权访问数据库。在这种情况下,有权访问数据库的节点可能具有 DROP、INSERT 或 UPDATE 函数的完全权限。 + +##### 精细访问控制 + +默认情况下,每个 OpenStack 服务及其进程都使用一组共享凭据访问数据库。这使得审核数据库操作和撤消服务及其进程对数据库的访问权限变得特别困难。 + +![../_images/databaseusername.png](https://docs.openstack.org/security-guide/_images/databaseusername.png) + +##### Nova-conductor + +计算节点是 OpenStack 中最不受信任的服务,因为它们托管租户实例。引入该 `nova-conductor` 服务作为数据库代理,充当计算节点和数据库之间的中介。我们将在本章后面讨论其后果。 + +我们强烈建议: + +- 所有数据库通信都与管理网络隔离 +- 使用 TLS 保护通信 +- 为每个 OpenStack 服务端点创建唯一的数据库用户帐户(如下图所示) + +![../_images/databaseusernamessl.png](https://docs.openstack.org/security-guide/_images/databaseusernamessl.png) + +#### 数据库认证和访问控制 + +考虑到访问数据库的风险,我们强烈建议为每个需要访问数据库的节点创建唯一的数据库用户帐户。这样做有助于更好地进行分析和审核,以确保合规性,或者在节点遭到入侵时,通过在检测到该节点时删除该节点对数据库的访问来隔离受感染的主机。创建这些每个服务终结点数据库用户帐户时,应注意确保将其配置为需要 TLS。或者,为了提高安全性,建议除了用户名和密码外,还使用 X.509 证书身份验证来配置数据库帐户。 + +##### 权限 + +应创建并保护一个单独的数据库管理员 (DBA) 帐户,该帐户具有创建/删除数据库、创建用户帐户和更新用户权限的完全权限。这种简单的责任分离方法有助于防止意外配置错误,降低风险并缩小危害范围。 + +为 OpenStack 服务和每个节点创建的数据库用户帐户的权限应仅限于与该节点所属的服务相关的数据库。 + +#### 要求用户帐户需要 SSL 传输 + +##### 配置示例 #1:(MySQL) + +```shell +GRANT ALL ON dbname.* to 'compute01'@'hostname' IDENTIFIED BY 'NOVA_DBPASS' REQUIRE SSL; +``` + +##### 配置示例 #2:(PostgreSQL) + +在文件中 `pg_hba.conf` : + +```shell +hostssl dbname compute01 hostname md5 +``` + +请注意,此命令仅添加通过 SSL 进行通信的功能,并且是非独占的。应禁用可能允许未加密传输的其他访问方法,以便 SSL 是唯一的访问方法。 + +该 `md5` 参数将身份验证方法定义为哈希密码。我们在以下部分中提供了一个安全身份验证示例。 + +##### OpenStack 服务数据库配置 + +如果数据库服务器配置为使用 TLS 传输,则需要指定用于 SQLAlchemy 查询中的初始连接字符串的证书颁发机构信息。 + +###### MySQL `:sql_connection` 的字符串示例 + +```shell +sql_connection = mysql://compute01:NOVA_DBPASS@localhost/nova?charset=utf8&ssl_ca=/etc/mysql/cacert.pem +``` + +#### 使用 X.509 证书进行身份验证 + +通过要求使用 X.509 客户端证书进行身份验证,可以增强安全性。以这种方式对数据库进行身份验证可以为与数据库建立连接的客户端提供更好的身份保证,并确保通信是加密的。 + +##### 配置示例 #1:(MySQL) + +```shell +GRANT ALL on dbname.* to 'compute01'@'hostname' IDENTIFIED BY 'NOVA_DBPASS' REQUIRE SUBJECT +'/C=XX/ST=YYY/L=ZZZZ/O=cloudycloud/CN=compute01' AND ISSUER +'/C=XX/ST=YYY/L=ZZZZ/O=cloudycloud/CN=cloud-ca'; +``` + +##### 配置示例 #2:(PostgreSQL) + +```shell +hostssl dbname compute01 hostname cert +``` + +#### OpenStack 服务数据库配置 + +如果数据库服务器配置为需要 X.509 证书进行身份验证,则需要为数据库后端指定相应的 SQLAlchemy 查询参数。这些参数指定用于初始连接字符串的证书、私钥和证书颁发机构信息。 + +MySQL 的 X.509 证书身份验证 `:sql_connection` 字符串示例: + +```shell +sql_connection = mysql://compute01:NOVA_DBPASS@localhost/nova? +charset=utf8&ssl_ca = /etc/mysql/cacert.pem&ssl_cert=/etc/mysql/server-cert.pem&ssl_key=/etc/mysql/server-key.pem +``` + +#### Nova-conductor + +OpenStack Compute 提供了一个称为 nova-conductor 的子服务,用于代理数据库连接,其主要目的是让 nova 计算节点与 nova-conductor 连接以满足数据持久性需求,而不是直接与数据库通信。 + +Nova-conductor 通过 RPC 接收请求并代表调用服务执行操作,而无需授予对数据库、其表或其中数据的精细访问权限。Nova-conductor 实质上将直接数据库访问从计算节点中抽象出来。 + +这种抽象的优点是将服务限制为使用参数执行方法,类似于存储过程,从而防止大量系统直接访问或修改数据库数据。这是在不在数据库本身的上下文或范围内存储或执行这些过程的情况下完成的,这是对典型存储过程的常见批评。 + +![../_images/novaconductor.png](https://docs.openstack.org/security-guide/_images/novaconductor.png) + +遗憾的是,此解决方案使更细粒度的访问控制和审核数据访问的能力的任务复杂化。由于 nova-conductor 服务通过 RPC 接收请求,因此它突出了提高消息传递安全性的重要性。任何有权访问消息队列的节点都可以执行 nova-conductor 提供的这些方法,并有效地修改数据库。 + +请注意,由于 nova-conductor 仅适用于 OpenStack Compute,因此对于其他 OpenStack 组件(如 Telemetry(云高计)、网络和块存储)的运行,可能仍然需要从计算主机直接访问数据库。 + +若要禁用 nova-conductor,请将以下内容放入 `nova.conf` 文件中(在计算主机上): + +```shell +[conductor] +use_local = true +``` + +### 数据库传输安全性 + +本章介绍与数据库服务器之间的网络通信相关的问题。这包括 IP 地址绑定和使用 TLS 加密网络流量。 + +#### 数据库服务器 IP 地址绑定 + +若要隔离服务和数据库之间的敏感数据库通信,强烈建议将数据库服务器配置为仅允许通过隔离的管理网络与数据库进行通信。这是通过限制数据库服务器为传入客户端连接绑定网络套接字的接口或 IP 地址来实现的。 + +##### 限制 MySQL 的绑定地址 + +在 `my.cnf` : + +```shell +[mysqld] +... +bind-address +``` + +##### 限制 PostgreSQL 的监听地址 + +在 `postgresql.conf` : + +```shell +listen_addresses = +``` + +#### 数据库传输 + +除了将数据库通信限制为管理网络外,我们还强烈建议云管理员将其数据库后端配置为需要 TLS。将 TLS 用于数据库客户端连接可保护通信不被篡改和窃听。正如下一节将讨论的那样,使用 TLS 还提供了通过 X.509 证书(通常称为 PKI)执行数据库用户身份验证的框架。以下是有关如何为两个流行的数据库后端 MySQL 和 PostgreSQL 配置 TLS 的指南。 + +**注意** + +```shell +安装证书和密钥文件时,请确保文件权限受到限制,例如 `chmod 0600` ,所有权限制为数据库守护程序用户,以防止数据库服务器上的其他进程和用户进行未经授权的访问。 +``` + +#### MySQL SSL配置 + +应在系统范围的MySQL配置文件中添加以下行: + +在 `my.cnf` : + +```shell +[[mysqld]] +... +ssl-ca = /path/to/ssl/cacert.pem +ssl-cert = /path/to/ssl/server-cert.pem +ssl-key = /path/to/ssl/server-key.pem +``` + +(可选)如果您希望限制用于加密连接的 SSL 密码集。有关密码列表和用于指定密码字符串的语法,请参阅密码: + +```shell +ssl-cipher = 'cipher:list' +``` + +#### PostgreSQL SSL 配置 + +应在系统范围的 PostgreSQL 配置文件中添加以下行。 `postgresql.conf` + +```shell +ssl = true +``` + +(可选)如果您希望限制用于加密连接的 SSL 密码集。有关密码列表和用于指定密码字符串的语法,请参阅密码: + +```shell +ssl-ciphers = 'cipher:list' +``` + +服务器证书、密钥和证书颁发机构 (CA) 文件应放在以下文件的 $PGDATA 目录中: + +- `$PGDATA/server.crt` - 服务器证书 +- `$PGDATA/server.key` - 私钥对应于 `server.crt` +- `$PGDATA/root.crt` - 可信证书颁发机构 +- `$PGDATA/root.crl` - 证书撤销列表 + +## 租户数据隐私 + +OpenStack旨在支持多租户,这些租户很可能有不同的数据要求。作为云构建者或运营商,您必须确保您的 OpenStack 环境能够解决数据隐私问题和法规。在本章中,我们将讨论与 OpenStack 实现相关的数据驻留和处置。 + +- 数据隐私问题 + - 数据驻留 + - 数据处置 +- 数据加密 + - 卷加密 + - 临时磁盘加密 + - 对象存储对象 + - 块存储性能和后端 + - 网络数据 +- 密钥管理 + - 参考书目: + +### 数据隐私问题 + +#### 数据驻留 + +在过去几年中,数据的隐私和隔离一直被认为是采用云的主要障碍。过去,对谁拥有云中数据以及云运营商是否可以最终信任这些数据的保管人的担忧一直是重大问题。 + +许多 OpenStack 服务维护属于租户的数据和元数据或参考租户信息。 + +存储在 OpenStack 云中的租户数据可能包括以下项目: + +- 对象存储对象 +- 计算实例临时文件系统存储 +- 计算实例内存 +- 块存储卷数据 +- 用于计算访问的公钥 +- 映像服务中的虚拟机映像 +- 计算机快照 +- 传递给 OpenStack Compute 的配置驱动器扩展的数据 + +OpenStack 云存储的元数据包括以下非详尽项目: + +- 组织名称 +- 用户的“真实姓名” +- 正在运行的实例、存储桶、对象、卷和其他配额相关项目的数量或大小 +- 运行实例或存储数据的小时数 +- 用户的 IP 地址 +- 内部生成的用于计算映像捆绑的私钥 + +#### 数据处置 + +OpenStack运营商应努力提供一定程度的租户数据处置保证。最佳实践建议操作员在处置、释放组织控制或释放以供重复使用之前对云系统介质(数字和非数字)进行清理。鉴于信息的特定安全域和敏感性,清理方法应实现适当级别的强度和完整性。 + +“清理过程会从介质中删除信息,因此无法检索或重建信息。清理技术,包括清除、清除、加密擦除和销毁,可防止在重复使用或释放处置此类介质时向未经授权的个人披露信息。NIST 特别出版物 800-53 修订版 4 + +NIST建议的安全控制措施中采用的一般数据处置和清理指南。云运营商应: + +1. 跟踪、记录和验证介质清理和处置操作。 +2. 测试清理设备和程序以验证其性能是否正常。 +3. 在将便携式可移动存储设备连接到云基础架构之前,先对其进行清理。 +4. 销毁无法清理的云系统介质。 + +在 OpenStack 部署中,您需要解决以下问题: + +- 安全数据擦除 +- 实例内存清理 +- 块存储卷数据 +- 计算实例临时存储 +- 裸机服务器清理 + +##### 数据未安全删除 + +在OpenStack中,某些数据可能会被删除,但在上述NIST标准的上下文中不会被安全删除。这通常适用于存储在数据库中的大多数或全部上述定义的元数据和信息。这可以通过数据库和/或系统配置进行自动吸尘和定期可用空间擦除来修复。 + +##### 实例内存清理 + +特定于各种虚拟机管理程序的是实例内存的处理。OpenStack Compute 中没有定义此行为,尽管通常期望 hypervisor 在删除实例和/或创建实例时尽最大努力清理内存。 + +Xen 显式地为实例分配专用内存区域,并在实例(或 Xen 术语中的域)销毁时清理数据。KVM 在很大程度上依赖于 Linux 页面管理;KVM 文档中定义了一组与 KVM 分页相关的复杂规则。 + +需要注意的是,使用 Xen 内存气球功能可能会导致信息泄露。我们强烈建议避免使用此功能。 + +对于这些和其他虚拟机管理程序,我们建议参考特定于虚拟机管理程序的文档。 + +##### Cinder 卷数据 + +强烈建议使用 OpenStack 卷加密功能。下面“卷加密”下的“数据加密”部分对此进行了讨论。使用此功能时,通过安全地删除加密密钥来完成数据销毁。最终用户可以在创建卷时选择此功能,但请注意,管理员必须先执行卷加密功能的一次性设置。有关此设置的说明,请参阅“配置参考”的“块存储”部分的“卷加密”下。 + +如果不使用 OpenStack 卷加密功能,那么其他方法通常更难启用。如果使用后端插件,则可能存在独立的加密方法或非标准覆盖解决方案。OpenStack Block Storage 的插件将以多种方式存储数据。许多插件特定于供应商或技术,而其他插件则更多地是围绕文件系统(如 LVM 或 ZFS)的 DIY 解决方案。安全销毁数据的方法因插件而异,因供应商的解决方案而异,也因文件系统而异。 + +一些后端(如 ZFS)将支持写入时复制,以防止数据泄露。在这些情况下,从未写入块中读取将始终返回零。其他后端(如 LVM)可能本身不支持此功能,因此块存储插件负责在将之前写入的块交给用户之前覆盖它们。请务必查看所选卷后端提供哪些保证,并查看哪些中介可用于未提供的保证。 + +##### 镜像服务延时删除功能 + +OpenStack 镜像服务具有延迟删除功能,该功能将在定义的时间段内等待镜像的删除。如果存在安全问题,建议通过编辑 `etc/glance/glance-api.conf` 文件并将 `delayed_delete` 选项设置为 False 来禁用此功能。 + +##### 计算软删除功能 + +OpenStack Compute 具有软删除功能,该功能使被删除的实例在定义的时间段内处于软删除状态。实例可以在此时间段内恢复。若要禁用软删除功能,请编辑 `etc/nova/nova.conf` 文件并将该 `reclaim_instance_interval` 选项留空。 + +##### 计算实例临时存储 + +请注意,OpenStack 临时磁盘加密功能提供了一种改进临时存储隐私和隔离的方法,无论是在主动使用期间还是在销毁数据时。与加密块存储一样,只需删除加密密钥即可有效地销毁数据。 + +在创建和销毁临时存储时,提供数据隐私的替代措施将在一定程度上取决于所选的虚拟机管理程序和 OpenStack 计算插件。 + +用于计算的 libvirt 插件可以直接在文件系统上或 LVM 中维护临时存储。文件系统存储通常不会在删除数据时覆盖数据,但可以保证不会向用户提供脏盘区。 + +当使用 LVM 支持的基于块的临时存储时,OpenStack 计算软件必须安全地擦除块以防止信息泄露。过去曾存在与不当擦除的临时块存储设备相关的信息泄露漏洞。 + +文件系统存储对于临时块存储设备来说是一种比 LVM 更安全的解决方案,因为无法为用户提供脏盘区。但是,需要注意的是,用户数据不会被破坏,因此建议对后备文件系统进行加密。 + +##### 裸机服务器清理 + +用于计算的裸机服务器驱动程序正在开发中,此后已转移到一个名为 ironic 的单独项目中。在撰写本文时,具有讽刺意味的是,似乎没有解决驻留在物理硬件中的租户数据的清理问题。 + +此外,裸机系统的租户可以修改系统固件。安全引导中所述的 TPM 技术提供了一种用于检测未经授权的固件更改的解决方案。 + +### 数据加密 + +该选项可供实施者加密租户数据,无论这些数据存储在磁盘上或通过网络传输,例如下面描述的 OpenStack 卷加密功能。这超出了用户在将自己的数据发送给提供商之前加密自己的数据的一般建议。 + +代表租户加密数据的重要性很大程度上与提供商承担的攻击者可能访问租户数据的风险有关。政府可能有要求,也有每个策略的要求,私有合同,甚至与公共云提供商的私有合同有关的判例法。建议在选择租户加密策略之前进行风险评估和法律顾问。 + +按实例或按对象加密比按项目、按租户、按主机和按云聚合降序进行加密更可取。这项建议与实施的复杂性和难度相反。目前,在某些项目中,很难或不可能实现像每个租户一样松散的加密。我们建议实现者尽最大努力加密租户数据。 + +通常,数据加密与可靠地销毁租户和每个实例数据的能力呈正相关,只需丢弃密钥即可。应该指出的是,在这样做时,以可靠和安全的方式销毁这些密钥变得非常重要。 + +Opportunities to encrypt data for users are present: +存在为用户加密数据的机会: + +- 对象存储对象 +- 网络数据 + +#### 卷加密 + +OpenStack 中的卷加密功能支持基于每个租户的隐私保护。从 Kilo 版本开始,支持以下功能: + +- 创建和使用加密卷类型,通过仪表板或命令行界面启动 + - 启用加密并选择加密算法和密钥大小等参数 +- iSCSI 数据包中包含的卷数据已加密 +- 如果原始卷已加密,则支持加密备份 +- 仪表板指示卷加密状态。包括卷已加密的指示,并包括算法和密钥大小等加密参数 +- 通过安全包装器与密钥管理服务交互 + - 后端密钥存储支持卷加密,以增强安全性(例如,硬件安全模块 (HSM) 或 KMIP 服务器可用作 barbican 后端密钥存储) + +#### 临时磁盘加密 + +临时磁盘加密功能可解决数据隐私问题。临时磁盘是虚拟主机操作系统使用的临时工作空间。如果不加密,可以在此磁盘上访问敏感的用户信息,并且在卸载磁盘后可能会保留残留信息。从 Kilo 版本开始,支持以下临时磁盘加密功能: + +- 创建和使用加密的 LVM 临时磁盘(注意:目前 OpenStack 计算服务仅支持 LVM 格式的加密临时磁盘) + - 计算配置 , `nova.conf` 在“[ephemeral_storage_encryption]”部分中具有以下默认参数 + - 选项:“密码 = AES-XTS-plain64” + - 此字段设置用于加密临时存储的密码和模式。NIST建议将AES-XTS专门用于磁盘存储,该名称是使用XTS加密模式的AES加密的简写。可用的密码取决于内核支持。在命令行中,输入“cryptsetup benchmark”以确定可用选项(并查看基准测试结果),或转到 /proc/crypto + - 选项: 'enabled = false' + - 要使用临时磁盘加密,请设置选项:“enabled = true” + - 选项:“key_size = 512” + - 请注意,后端密钥管理器可能存在密钥大小限制,可能需要使用“key_size = 256”,这仅提供 128 位的 AES 密钥大小。除了 AES 所需的加密密钥外,XTS 还需要自己的“调整密钥”。这通常表示为单个大键。在这种情况下,使用 512 位设置,AES 将使用 256 位,XTS 将使用 256 位。(见NIST) +- 通过安全包装器与密钥管理服务交互 + - 密钥管理服务将通过为每个租户提供临时磁盘加密密钥来支持数据隔离 + - 后端密钥存储支持临时磁盘加密,以增强安全性(例如,HSM 或 KMIP 服务器可用作 barbican 后端密钥存储) + - 使用密钥管理服务时,当不再需要临时磁盘时,只需删除密钥即可取代覆盖临时磁盘存储区域 + +#### 对象存储对象 + +对象存储 (swift) 支持对存储节点上的静态对象数据进行可选加密。对象数据的加密旨在降低在未经授权的一方获得对磁盘的物理访问权限时读取用户数据的风险。 + +静态数据加密由中间件实现,中间件可能包含在代理服务器 WSGI 管道中。该功能是 swift 集群内部的,不通过 API 公开。客户端不知道 swift 服务内部的此功能对数据进行了加密;内部加密的数据不应通过 swift API 返回给客户端。 + +以下数据在 swift 中静态时被加密: + +- 对象内容。例如,对象 PUT 请求正文的内容 +- 具有非零内容的对象的实体标记 (ETag) +- 所有自定义用户对象元数据值。例如,使用 `X-Object-Meta-` 带有 PUT 或 POST 请求的前缀标头发送的元数据 + +上述列表中未包含的任何数据或元数据均未加密,包括: + +- 帐户、容器和对象名称 +- 帐户和容器自定义用户元数据值 +- 所有自定义用户元数据名称 +- 对象内容类型值 +- 对象大小 +- 系统元数据 + +有关对象存储加密的部署、操作或实施的更多信息,请参阅有关对象加密的 swift 开发人员文档。 + +#### 块存储性能和后端 + +启用操作系统时,可以使用 Intel 和 AMD 处理器中当前可用的硬件加速功能来增强 OpenStack Volume Encryption 性能。OpenStack 卷加密功能和 OpenStack 临时磁盘加密功能都用于 `dm-crypt` 保护卷数据。 `dm-crypt` 是 Linux 内核版本 2.6 及更高版本中的透明磁盘加密功能。启用卷加密后,加密数据将通过 iSCSI 发送到块存储,从而同时保护传输中的数据和静态数据。使用硬件加速时,这两种加密功能对性能的影响都会降到最低。 + +虽然我们建议使用 OpenStack 卷加密功能,但块存储支持多种替代后端来提供可挂载卷,其中一些还可能提供卷加密。由于后端如此之多,并且必须从每个供应商处获取信息,因此指定在任何一个供应商中实施加密的建议超出了本指南的范围。 + +#### 网络数据 + +计算的租户数据可以通过 IPsec 或其他隧道进行加密。这在OpenStack中并不常见或标准,但对于有动力和感兴趣的实现者来说,这是一个选项。 + +同样,加密数据在通过网络传输时将保持加密状态。 + +### 密钥管理 + +为了解决经常提到的租户数据隐私和限制云提供商责任的问题,OpenStack社区对使数据加密更加普遍的兴趣越来越大。对于最终用户来说,在将数据保存到云之前对其进行加密相对容易,这是租户对象(如媒体文件、数据库存档等)的可行路径。在某些情况下,客户端加密用于加密虚拟化技术保存的数据,这需要客户端交互(例如提供密钥)来解密数据以供将来使用。为了无缝地保护数据并使其可访问,而无需给客户带来管理其密钥的负担,并以交互方式向他们提供 OpenStack 中的密钥管理服务。作为OpenStack的一部分,提供加密和密钥管理服务可以简化静态数据安全采用,并解决客户对隐私或数据滥用的担忧,同时也限制了云提供商的责任。这有助于减少提供商在多租户公有云中的事件调查期间处理租户数据时的责任。 + +卷加密和临时磁盘加密功能依赖于密钥管理服务(例如,barbican)来创建和安全存储密钥。密钥管理器是可插入的,以方便需要第三方硬件安全模块 (HSM) 或使用密钥管理交换协议 (KMIP) 的部署,该协议由名为 PyKMIP 的开源项目支持。 + +#### 参考书目 + +- OpenStack.org,欢迎来到 barbican 的开发者文档!2014。Barbican 开发者文档 +- oasis-open.org,OASIS 密钥管理互操作性协议 (KMIP)。2014年。KMIP +- PyKMIP 库 +- 机密管理 机密管理 + +## 实例安全管理 + +在虚拟化环境中运行实例的优点之一是,它为安全控制开辟了新的机会,而这些控制在部署到裸机上时通常不可用。有几种技术可以应用于虚拟化堆栈,为云租户带来更好的信息保障。 + +具有强烈安全要求的 OpenStack 部署人员或用户可能需要考虑部署这些技术。并非所有情况都适用。在某些情况下,由于规范性业务需求,可能会排除在云中使用技术。同样,某些技术会检查实例数据,例如运行状态,这对系统用户来说可能是不希望的。 + +在本章中,我们将探讨这些技术,并描述它们可用于增强实例或底层实例安全性的情况。我们还试图强调可能存在隐私问题的地方。这些包括数据传递、内省或提供熵源。在本节中,我们将重点介绍以下附加安全服务: + +- 实例的熵 +- 将实例调度到节点 +- 受信任的映像 +- 实例迁移 +- 监控、警报和报告 +- 更新和补丁 +- 防火墙和其他基于主机的安全控制 +- 实例的安全服务 + - 实例的熵 + - 将实例调度到节点 + - 受信任的映像 + - 实例迁移 + - 监控、警报和报告 + - 更新和补丁 + - 防火墙和其他基于主机的安全控制 + +### 实例的安全服务 + +#### 实例的熵 + +我们认为熵是指实例可用的随机数据的质量和来源。加密技术通常严重依赖随机性,需要高质量的熵池才能从中汲取。虚拟机通常很难获得足够的熵来支持这些操作,这称为熵饥饿。熵饥饿可以表现为看似无关的事情。例如,启动时间慢可能是由于实例等待 ssh 密钥生成造成的。熵饥饿还可能促使用户在实例中使用质量较差的熵源,从而使在云中运行的应用程序整体安全性降低。 + +幸运的是,云架构师可以通过为云实例提供高质量的熵源来解决这些问题。这可以通过在云中拥有足够的硬件随机数生成器 (HRNG) 来支持实例来实现。在这种情况下,“足够”在某种程度上是特定于域的。对于日常操作,现代 HRNG 可能会产生足够的熵来支持 50-100 个计算节点。高带宽 HRNG(例如英特尔 Ivy Bridge 和更新的处理器提供的 RdRand 指令)可能会处理更多节点。对于给定的云,架构师需要了解应用程序要求,以确保有足够的熵可用。 + +Virtio RNG 是一个随机数生成器,默认情况下用作 `/dev/random` 熵源,但可以配置为使用硬件 RNG 或熵收集守护程序 (EGD) 等工具,以提供一种通过分布式系统公平安全地分配熵的方法。Virtio RNG 是使用用于创建实例的元数据的 `hw_rng` 属性启用的。 + +#### 将实例调度到节点 + +在创建实例之前,必须选择用于镜像实例化的主机。此选择由 `nova-scheduler` 确定如何分派计算和卷请求的 执行。 + +这是 `FilterScheduler` OpenStack Compute的默认调度程序,尽管存在其他调度程序(请参阅 OpenStack Configuration Reference 中的 Scheduling 部分)。这与“过滤器提示”协同工作,以决定实例的启动位置。此主机选择过程允许管理员满足许多不同的安全性和合规性要求。例如,根据云部署类型,如果数据隔离是主要问题,则可以选择尽可能让租户实例驻留在相同的主机上。相反,出于可用性或容错原因,可以尝试将租户的实例驻留在尽可能多的不同主机上。 + +筛选器计划程序分为四大类: + +基于资源的筛选器 + +这些筛选器将根据虚拟机监控程序主机集的利用率创建实例,并可以在可用或使用的属性(如 RAM、IO 或 CPU 利用率)上触发。 + +基于映像的过滤器 + +这将根据使用的映像(例如 VM 的操作系统或使用的映像类型)委派实例创建。 + +基于环境的过滤器 + +此筛选器将基于外部详细信息创建实例,例如在特定 IP 范围内、跨可用区或与其他实例位于同一主机上。 + +自定义条件 + +此筛选器将根据用户或管理员提供的条件(如信任或元数据分析)委派实例创建。 + +可以同时应用多个筛选器,例如,筛选器用于确保在一组特定主机的成员上创建实例,以及 `ServerGroupAntiAffinity` 用于确保不会在另一组特定主机上创建同一实例的筛选器 `ServerGroupAffinity` 。应仔细分析这些筛选器,以确保它们不会相互冲突,并导致阻止创建实例的规则。 + +![../_images/filteringWorkflow1.png](https://docs.openstack.org/security-guide/_images/filteringWorkflow1.png) + +`GroupAffinity` 和 `GroupAntiAffinity` 筛选器冲突,不应同时启用。 + +筛选器 `DiskFilter` 能够超额订阅磁盘空间。虽然通常不是问题,但对于精简预配的存储设备来说,这可能是一个问题,并且此筛选器应与应用经过充分测试的配额一起使用。 + +我们建议您禁用过滤器,这些过滤器可以分析用户提供的内容或可操作的内容,例如元数据。 + +#### 可信镜像 + +在云环境中,用户使用预安装的映像或他们自己上传的映像。在这两种情况下,用户都应该能够确保他们正在使用的图像没有被篡改。验证图像的能力是安全性的基本要求。从映像源到使用映像的目标需要信任链。这可以通过对从受信任来源获取的映像进行签名并在使用前验证签名来实现。下面将讨论获取和创建已验证图像的各种方法,然后介绍图像签名验证功能。 + +##### 镜像创建过程 + +OpenStack 文档提供了有关如何创建映像并将其上传到映像服务的指导。此外,假定您有一个安装和强化操作系统的过程。因此,以下各项将提供有关如何确保将映像安全地传输到 OpenStack 中的额外指导。有多种选项可用于获取图像。每个步骤都有特定的步骤,有助于验证图像的出处。 + +第一个选项是从受信任的来源获取启动媒体。 + +```shell +$ mkdir -p /tmp/download_directorycd /tmp/download_directory +$ wget http://mirror.anl.gov/pub/ubuntu-iso/CDs/precise/ubuntu-12.04.2-server-amd64.iso +$ wget http://mirror.anl.gov/pub/ubuntu-iso/CDs/precise/SHA256SUMS +$ wget http://mirror.anl.gov/pub/ubuntu-iso/CDs/precise/SHA256SUMS.gpg +$ gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 0xFBB75451 +$ gpg --verify SHA256SUMS.gpg SHA256SUMSsha256sum -c SHA256SUMS 2>&1 | grep OK +``` + +第二种选择是使用 OpenStack 虚拟机映像指南。在这种情况下,您需要遵循组织的操作系统强化准则或受信任的第三方(如 Linux STIG)提供的准则。 + +最后一种选择是使用自动映像生成器。以下示例使用 Oz 映像生成器。OpenStack 社区最近创建了一个值得研究的新工具:disk-image-builder。我们尚未从安全角度评估此工具。 + +RHEL 6 CCE-26976-1 示例,这将有助于在 OZ 中实施 NIST 800-53 第 AC-19(d)节。 + +```shell + +``` + +建议避免手动映像构建过程,因为它很复杂且容易出错。此外,使用 Oz 等自动化系统进行映像构建,或使用 Chef 或 Puppet 等配置管理实用程序进行启动后映像强化,使您能够生成一致的映像,并跟踪基础映像在一段时间内是否符合其各自的强化准则。 + +如果订阅公有云服务,则应与云提供商联系,了解用于生成其默认映像的过程的概述。如果提供商允许您上传自己的映像,则需要确保在使用映像创建实例之前能够验证映像是否未被修改。为此,请参阅以下有关图像签名验证的部分,如果无法使用签名,请参阅以下段落。 + +映像从节点上的映像服务传输到计算服务。应通过通过 TLS 运行来保护此传输。映像位于节点上后,将使用基本校验和对其进行验证,然后根据要启动的实例的大小扩展其磁盘。如果稍后在此节点上以相同的实例大小启动同一映像,则会从同一扩展映像启动该映像。由于此扩展映像在启动前默认不会重新验证,因此它可能已被篡改。除非在生成的映像中对文件执行手动检查,否则用户不会意识到篡改。 + +##### 映像签名验证 + +OpenStack 中现在提供了一些与映像签名相关的功能。从 Mitaka 版本开始,映像服务可以验证这些已签名的映像,并且为了提供完整的信任链,计算服务可以选择在映像启动之前执行映像签名验证。在映像启动之前成功进行签名验证可确保已签名的映像未更改。启用此功能后,可以检测到未经授权的映像修改(例如,修改映像以包含恶意软件或 rootkit)。 + +管理员可以通过在文件中将 `verify_glance_signatures` 标志设置为来 `True` 启用实例签名 `/etc/nova/nova.conf` 验证。启用后,计算服务会在从影像服务检索签名实例时自动对其进行验证。如果此验证失败,则不会启动。《OpenStack 操作指南》提供了有关如何创建和上传签名映像以及如何使用此功能的指导。有关更多信息,请参阅《操作指南》中的添加签名映像。 + +#### 实例迁移 + +OpenStack 和底层虚拟化层提供在 OpenStack 节点之间实时迁移映像,使您能够无缝地执行 OpenStack 计算节点的滚动升级,而无需实例停机。但是,实时迁移也存在重大风险。若要了解所涉及的风险,以下是在实时迁移期间执行的高级步骤: + +1. 在目标主机上启动实例 +2. 传输内存 +3. 停止客户机和同步磁盘 +4. 传输状态 +5. 启动客户机 + +##### 实时迁移风险 + +在实时迁移过程的各个阶段,实例运行时、内存和磁盘的内容以纯文本形式通过网络传输。因此,在使用实时迁移时需要解决一些风险。以下详尽列表详细介绍了其中的一些风险: + +- 拒绝服务 (DoS):如果在迁移过程中出现故障,实例可能会丢失。 +- 数据泄露:必须安全地处理内存或磁盘传输。 +- 数据操纵:如果内存或磁盘传输未得到安全处理,则攻击者可以在迁移过程中操纵用户数据。 +- 代码注入:如果内存或磁盘传输未得到安全处理,则攻击者可以在迁移期间操纵磁盘或内存中的可执行文件。 + +##### 实时迁移缓解措施 + +有几种方法可以缓解与实时迁移相关的一些风险,以下列表详细介绍了其中的一些方法: + +- 禁用实时迁移 +- I隔离的迁移网络 +- 加密实时迁移 + +##### 禁用实时迁移 + +目前,OpenStack 中默认启用实时迁移。可以通过向 nova `policy.json` 文件添加以下行来禁用实时迁移: + +```shell +{ + "compute_extension:admin_actions:migrate": "!", + "compute_extension:admin_actions:migrateLive": "!", +} +``` + +##### 迁移网络 + +一般做法是,实时迁移流量应限制在管理安全域内,请参阅安全边界和威胁。对于实时迁移流量,由于其纯文本性质以及您正在传输正在运行的实例的磁盘和内存内容,因此建议您进一步将实时迁移流量分离到专用网络上。将流量隔离到专用网络可以降低暴露风险。 + +##### 加密实时迁移 + +如果有足够的业务案例来保持实时迁移的启用状态,则 libvirtd 可以为实时迁移提供加密隧道。但是,此功能目前尚未在 OpenStack Dashboard 或 nova-client 命令中公开,只能通过手动配置 libvirtd 来访问。然后,实时迁移过程将更改为以下高级步骤: + +1. 实例数据从虚拟机管理程序复制到 libvirtd。 +2. 在源主机和目标主机上的 libvirtd 进程之间创建加密隧道。 +3. 目标 libvirtd 主机将实例复制回底层虚拟机管理程序。 + +#### 监控、告警和报告 + +由于 OpenStack 虚拟机是能够跨主机复制的服务器映像,因此日志记录的最佳实践同样适用于物理主机和虚拟主机。应记录操作系统级和应用程序级事件,包括对主机和数据的访问事件、用户添加和删除、权限更改以及环境规定的其他事件。理想情况下,您可以将这些日志配置为导出到日志聚合器,该聚合器收集日志事件,将它们关联起来进行分析,并存储它们以供参考或进一步操作。实现此目的的一个常见工具是 ELK 堆栈,即 Elasticsearch、Logstash 和 Kibana。 + +应定期查看这些日志,例如由网络运营中心 (NOC) 实时查看,或者如果环境不够大而不需要 NOC,则日志应定期进行日志审查过程。 + +很多时候,有趣的事件会触发警报,该警报将发送给响应方以采取行动。通常,此警报采用包含相关消息的电子邮件形式。一个有趣的事件可能是重大故障,也可能是挂起故障的已知运行状况指示器。用于管理告警的两个常见实用程序是 Nagios 和 Zabbix。 + +#### 更新和补丁 + +虚拟机监控程序运行独立的虚拟机。此虚拟机管理程序可以在操作系统中运行,也可以直接在硬件上运行(称为裸机)。对虚拟机监控程序的更新不会向下传播到虚拟机。例如,如果部署使用的是 XenServer,并且具有一组 Debian 虚拟机,则对 XenServer 的更新不会更新 Debian 虚拟机上运行的任何内容。 + +因此,我们建议分配虚拟机的明确所有权,并由这些所有者负责虚拟机的强化、部署和持续功能。我们还建议定期部署更新。这些补丁应在尽可能接近生产环境的环境中进行测试,以确保补丁背后的问题的稳定性和解决方案。 + +#### 防火墙和其他基于主机的安全控制 + +最常见的操作系统包括基于主机的防火墙,以提高安全性。虽然我们建议虚拟机运行尽可能少的应用程序(如果可能的话,达到单一用途实例的程度),但应分析虚拟机上运行的所有应用程序,以确定应用程序需要访问哪些系统资源、运行所需的最低特权级别,以及将进出虚拟机的预期网络流量。此预期流量应作为允许的流量(或列入白名单)添加到基于主机的防火墙中,以及任何必要的日志记录和管理通信,例如 SSH 或 RDP。应在防火墙配置中明确拒绝所有其他流量。 + +在 Linux 虚拟机上,上述应用程序配置文件可以与 audit2allow 等工具结合使用,以构建 SELinux 策略,以进一步保护大多数 Linux 发行版上的敏感系统信息。SELinux 使用用户、策略和安全上下文的组合来划分应用程序运行所需的资源,并将其与其他不需要的系统资源区分开来。 + +OpenStack 为主机和网络提供安全组,以增加对给定项目中虚拟机的深度防御。这些规则类似于基于主机的防火墙,因为它们根据端口、协议和地址允许或拒绝传入流量,但安全组规则仅适用于传入流量,而基于主机的防火墙规则能够应用于传入和传出流量。主机和网络安全组规则也可能发生冲突并拒绝合法流量。我们建议确保为正在使用的网络正确配置安全组。有关详细信息,请参阅本指南中的安全组。 + +## 监视和日志记录 + +在云环境中,硬件、操作系统、虚拟机管理器、OpenStack 服务、云用户活动(例如创建实例和附加存储)、网络以及使用在各种实例上运行的应用程序的最终用户混合在一起。 + +日志记录的基础知识:配置、设置日志级别、日志文件的位置、如何使用和自定义日志,以及如何集中收集日志,这些在 OpenStack 操作指南中都有很好的介绍。 + +- 取证和事件响应 + - 监控用例 + - 参考书目 + +### 取证和事件响应 + +日志的生成和收集是安全监控 OpenStack 基础架构的重要组成部分。日志提供对管理员、租户和来宾日常操作的可见性,以及计算、网络和存储以及构成 OpenStack 部署的其他组件中的活动。 + +日志不仅对主动安全和持续合规性活动很有价值,而且也是调查和响应事件的宝贵信息源。 + +例如,分析身份服务或其替代身份验证系统的访问日志会提醒我们登录失败、频率、源 IP、事件是否仅限于选择帐户和其他相关信息。日志分析支持检测。 + +可以采取措施来缓解潜在的恶意活动,例如将 IP 地址列入黑名单、建议加强用户密码或停用被视为休眠的用户帐户。 + +#### 监控用例 + +事件监控是一种更主动的方法,可以保护环境,提供实时检测和响应。有几种工具可以帮助进行监控。 + +对于OpenStack云实例,我们需要监控硬件、OpenStack服务和云资源使用情况。后者源于希望具有弹性,以适应用户的动态需求。 + +以下是在实施日志聚合、分析和监控时需要考虑的几个重要用例。这些用例可以通过各种应用程序、工具或脚本来实现和监控。有开源和商业解决方案,一些运营商开发自己的内部解决方案。这些工具和脚本可以生成事件,这些事件可以通过电子邮件发送给管理员或在集成仪表板中查看。请务必考虑可能适用于您的特定网络的其他用例,以及您可能认为的异常行为。 + +- 检测日志生成缺失是一个具有很高价值的事件。此类事件将表明服务失败,甚至表示入侵者暂时关闭了日志记录或修改了日志级别以隐藏其踪迹。 +- 应用程序事件(如计划外的启动或停止事件)也是要监视和检查可能的安全隐患的事件。 +- OpenStack 服务机器上的操作系统事件(如用户登录或重新启动)也为系统的正确和不当使用提供了有价值的见解。 +- 能够检测OpenStack服务器上的负载还可以通过引入其他服务器进行负载平衡来做出响应,以确保高可用性。 +- 其他可操作的事件包括网络网桥关闭、计算节点上的 IP 表被刷新,以及随之而来的对实例的访问丢失,导致客户不满意。 +- 为了降低在身份服务中删除用户、租户或域时孤立实例的安全风险,我们讨论了在系统中生成通知,并让 OpenStack 组件适当地响应这些事件,例如终止实例、断开连接的卷、回收 CPU 和存储资源等。 + +云将托管许多虚拟实例,并且监视这些实例超出了可能仅包含 CRUD 事件的硬件监视和日志文件。 + +安全监控控制(如入侵检测软件、防病毒软件以及间谍软件检测和删除实用程序)可以生成日志,显示攻击或入侵发生的时间和方式。在云计算机上部署这些工具可提供价值和保护。云用户,即在云上运行实例的用户,可能也希望在其实例上运行此类工具。 + +#### 参考书目 + +Siwczak, Piotr,在 OpenStack 云中进行监控的一些实际注意事项。2012. + +blog.sflow.com, sflow:主机 sFlow 分布式代理。2012. + +blog.sflow.com,sflow:LAN 和 WAN。2009. + +blog.sflow.com、sflow:快速检测大流量 sFlow 与 NetFlow/IPFIX。2013. + +## 合规 + +OpenStack 部署可能需要出于多种目的进行合规性活动,例如法规和法律要求、客户需求、隐私注意事项和安全最佳实践。合规功能对企业及其客户很重要。合规意味着遵守法规、规范、标准和法律。它还用于描述有关评估、审核和认证的组织状态。如果操作得当,合规性可以统一和加强本指南中讨论的其他安全主题。 + +本章有几个目标: + +- 查看常见的安全原则。 +- 讨论常见的控制框架和认证资源,以实现行业认证或监管机构认证。 +- 在评估 OpenStack 部署时,可作为审计人员的参考。 +- 介绍特定于 OpenStack 和云环境的隐私注意事项。 +- 合规性概述 + - 安全原则 + - 常见控制框架 + - 审核参考 +- 了解审核流程 + - 确定审计范围 + - 审计阶段 + - 内部审计 + - 准备外部审计 + - 外部审计 + - 合规性维护 +- 合规活动 + - 信息安全管理系统(ISMS) + - 风险评估 + - 访问和日志审查 + - 备份和灾难恢复 + - 安全培训 + - 安全审查 + - 漏洞管理 + - 数据分类 + - 异常过程 +- 认证和合规声明 + - 商业标准 + - 政府标准 +- 隐私 + +### 合规性概述 + +#### 安全原则 + +行业标准安全原则为合规性认证和证明提供了基准。如果在整个 OpenStack 部署过程中考虑和引用这些原则,则可以简化认证活动。 + +##### 分层防御 + +确定云架构中存在风险的位置,并应用控制措施来降低风险。在重大关注领域,分层防御提供多种互补控制,将风险管理到可接受的水平。例如,为了确保云租户之间的充分隔离,我们建议强化 QEMU,使用支持 SELinux 的虚拟机管理程序,实施强制访问控制策略,并减少整体攻击面。基本原则是用多层防御来强化关注区域,这样,如果任何一层受到损害,其他层将存在以提供保护并最大限度地减少暴露。 + +##### 安全失败 + +在发生故障的情况下,系统应配置为在关闭的安全状态中失败。例如,如果TLS证书验证未通过,即CNAME与服务器的DNS名称不匹配,应通过切断网络连接来安全失败。在这种情况下,软件通常会以开放方式失败,允许连接在没有CNAME匹配的情况下继续进行,这样不够安全,也不建议。 + +##### 最小权限 + +仅授予用户和系统服务的最低访问级别。这种访问基于角色、职责和工作职能。这种最小特权安全原则已写入多个国际政府安全策略中,例如美国境内的 NIST 800-53 第 AC-6 节。 + +##### 分隔 + +系统应以这样一种方式隔离,即如果一台计算机或系统级服务受到损害,其他系统的安全性将保持不变。实际上,SELinux 的启用和正确使用有助于实现这一目标。 + +##### 促进隐私 + +应尽量减少可以收集的有关系统及其用户的信息量。 + +##### 日志记录能力 + +实施适当的日志记录以监控未经授权的使用、事件响应和取证。我们强烈建议选定的审计子系统通过通用标准认证,该标准在大多数国家/地区提供不可证明的事件记录。 + +#### 常用控制框架 + +以下是组织可用于构建其安全控制的控制框架列表。 + +云安全联盟 (CSA) 通用控制矩阵 (CCM) + +CSA CCM 专门用于提供基本的安全原则,以指导云供应商并帮助潜在的云客户评估云提供商的整体安全风险。CSA CCM 提供了一个跨 16 个安全域保持一致的控制框架。云控制矩阵的基础在于其与其他行业标准、法规和控制框架的定制关系,例如:ISO 27001:2013、COBIT 5.0、PCI:DSS v3、AICPA 2014 信任服务原则和标准,并增强了服务组织控制报告证明的内部控制方向。 + +CSA CCM 通过减少云中的安全威胁和漏洞来加强现有的信息安全控制环境,提供标准化的安全和运营风险管理,并寻求规范化安全期望、云分类和术语以及在云中实施的安全措施。 + +ISO 27001/2:2013 ISO 27001/2:2013 认证 + +ISO 27001 信息安全标准和认证多年来一直用于评估和区分组织是否符合信息安全最佳实践。该标准由两部分组成:定义信息安全管理系统 (ISMS) 的强制性条款和包含按领域组织的控制列表的附录 A。 + +信息安全管理系统通过应用风险管理流程来保持信息的机密性、完整性和可用性,并使相关方相信风险得到充分管理。 + +可信安全原则 + +信托服务是一套基于一套核心原则和标准的专业认证和咨询服务,用于解决 IT 系统和隐私计划的风险和机遇。通常称为 SOC 审计,这些原则定义了要求是什么,组织有责任定义满足要求的控制措施。 + +#### 审计参考 + +OpenStack在许多方面都是创新的,但是用于审计OpenStack部署的过程相当普遍。审核员将根据两个标准评估流程:控制是否有效设计以及控制是否有效运行。了解审计师如何评估控制措施是否有效设计和运行,将在“了解审计过程”一节中讨论。 + +用于审核和评估云部署的最常见框架包括前面提到的 ISO 27001/2 信息安全标准、ISACA 的信息和相关技术控制目标 (COBIT) 框架、特雷德韦委员会赞助组织委员会 (COSO) 和信息技术基础设施库 (ITIL)。审计通常包括一个或多个这些框架中的重点领域。幸运的是,这些框架之间有很多重叠,因此采用框架的组织将在审计时处于有利地位。 + +### 了解审核流程 + +信息系统安全合规性依赖于两个基本流程的完成: + +安全控制的实施和操作 + +使信息系统与范围内的标准和法规保持一致涉及内部任务,这些任务必须在正式评估之前进行。审核员可能会参与此状态,以进行差距分析,提供指导,并增加成功认证的可能性。 + +独立验证和确认 + +在许多信息系统获得认证状态之前,需要向中立的第三方证明系统安全控制已实施并有效运行,符合范围内的标准和法规。许多认证需要定期审核,以确保持续认证,这被认为是总体持续监控实践的一部分。 + +#### 确定审计范围 + +确定审计范围,特别是需要哪些控制措施,以及如何设计或修改OpenStack部署以满足这些控制措施,应该是最初的规划步骤。 + +在出于合规性目的确定 OpenStack 部署范围时,应优先考虑对敏感服务的控制,例如命令和控制功能以及基本虚拟化技术。这些设施的妥协可能会影响整个 OpenStack 环境。 + +缩小范围有助于确保 OpenStack 架构师建立针对特定部署量身定制的高质量安全控制,但最重要的是确保这些实践不会遗漏安全强化中的区域或功能。一个常见的例子是PCI-DSS准则,其中与支付相关的基础设施可能会受到安全问题的审查,但支持服务被忽视,并且容易受到攻击。 + +在解决合规性问题时,您可以通过确定适用于多个认证的常见领域和标准来提高效率并减少工作量。本书中讨论的许多审计原则和准则将有助于确定这些控制措施,此外,一些外部实体提供了全面的清单。以下是一些示例: + +云安全联盟云控制矩阵 (CCM) 可帮助云提供商和消费者评估云提供商的整体安全性。CSA CMM 提供了一个控制框架,该框架映射到许多行业公认的标准和法规,包括 ISO 27001/2、ISACA、COBIT、PCI、NIST、Jericho Forum 和 NERC CIP。 + +《SCAP 安全指南》是另一个有用的参考。这仍然是一个新兴的来源,但我们预计这将发展成为一个工具,其控件映射更侧重于美国联邦政府的认证和建议。例如,SCAP 安全指南目前包含安全技术实施指南 (STIG) 和 NIST-800-53 的一些映射。 + +这些控制映射将有助于识别跨认证的通用控制标准,并为审核员和被审核方提供对特定合规性认证和证明的控制集中问题区域的可见性。 + +#### 审计的阶段 + +审计有四个不同的阶段,尽管大多数利益相关者和控制所有者只会参与一两个阶段。四个阶段是规划、实地考察、报告和总结。下面将讨论这些阶段中的每一个。 + +规划阶段通常在实地工作开始前两周到六个月进行。在此阶段,将讨论并最终确定时间范围、时间表、要评估的控制措施和控制所有者等审计项目。对资源可用性、公正性和成本的担忧也得到了解决。 + +实地考察阶段是审计中最明显的部分。这是审计员在现场的地方,与控制所有者面谈,记录现有的控制措施,并确定任何问题。需要注意的是,审计师将使用两部分流程来评估现有的控制措施。第一部分是评估控制的设计有效性。在这里,审计员将评估控制是否能够有效地预防或检测和纠正弱点和缺陷。控件必须通过此测试才能在第二阶段进行评估。这是因为对于设计无效的控件,没有必要考虑它是否有效运行。第二部分是运营效率。操作有效性测试将确定如何应用控制措施,应用控制措施的一致性以及由谁或以何种方式应用控制措施。一项控制可能依赖于其他控制(间接控制),如果它们依赖于其他控制,则审计师可能需要额外的证据来证明这些间接控制的运作有效性,以确定控制的整体运作有效性。 + +在报告阶段,管理层将对在实地工作阶段发现的任何问题进行验证。出于后勤目的,一些活动(例如问题验证)可能会在实地工作阶段执行。管理层还需要提供补救计划来解决问题,并确保它们不会再次发生。将向利益攸关方和管理层分发一份总体报告草稿,供其审查。商定的修改被纳入,更新后的草案将送交高级管理层审查和批准。一旦高级管理层批准报告,该报告就会定稿并分发给执行管理层。任何问题都会输入到组织使用的问题跟踪或风险跟踪机制中。 + +总结阶段是审计正式终止的地方。此时,管理层将开始整改活动。使用过程和通知确保将任何与审计相关的信息都被移至安全存储库0。 + +#### 内部审计 + +部署云后,就该进行内部审计了。现在是时候将上面确定的控件与云中使用的设计、功能和部署策略进行比较了。目标是了解每个控件的处理方式以及存在差距的位置。记录所有发现以备将来参考。 + +在审计OpenStack云时,了解OpenStack架构固有的多租户环境是很重要的。需要关注的一些关键领域包括数据处置、虚拟机管理程序安全性、节点强化和身份验证机制。 + +#### 准备外部审计 + +一旦内部审计结果看起来不错,就该为外部审计做准备了。在此阶段需要采取几项关键行动,这些行动概述如下: + +- 保持内部审计的良好记录。这些将在外部审计期间证明很有用,因此您可以准备好回答有关将合规性控制映射到特定部署的问题。 +- 部署自动化测试工具,确保云长期保持合规。 +- 选择审计员。 + +选择审计师可能具有挑战性。理想情况下,您正在寻找具有云合规性审核经验的人。OpenStack经验是另一大优势。通常,最好咨询经历过此过程的人进行转诊。成本可能会因参与范围和所考虑的审计公司而有很大差异。 + +#### 外部审计 + +这是正式的审计过程。审计员将测试特定认证范围内的安全控制措施,并要求提供证据要求,以证明这些控制措施在审计窗口内也已到位(例如,SOC 2 审计通常在 6-12 个月内评估安全控制措施)。任何控制失败都会被记录下来,并将记录在外部审计师的最终报告中。根据 OpenStack 部署的类型,客户可能会查看这些报告,因此避免控制失败非常重要。这就是为什么审计准备如此重要的原因。 + +#### 合规性维护 + +该过程不会因单一的外部审计而结束。大多数认证都需要持续的合规活动,这意味着要定期重复审核过程。我们建议将自动合规性验证工具集成到云中,以确保其始终合规。除了其他安全监控工具之外,还应该这样做。请记住,目标既是安全性,也是合规性。如果在上述任何一项方面都失败,将使未来的审计变得非常复杂。 + +### 合规活动 + +有许多标准活动将极大地帮助合规过程。本章概述了一些最常见的合规性活动。这些并不是OpenStack所特有的,但是本书中提供了相关章节的参考资料,作为有用的上下文。 + +#### 信息安全管理系统 (ISMS) + +信息安全管理系统 (ISMS) 是组织创建和维护的一套全面的策略和流程,用于管理信息资产的风险。云部署最常见的 ISMS 是 ISO/IEC 27001/2,它为安全控制和实践奠定了坚实的基础,以实现更严格的合规性认证。该标准于 2013 年进行了更新,以反映云服务的日益使用,并更加强调衡量和评估组织的 ISMS 性能。 + +#### 风险评估 + +风险评估框架可识别组织或服务中的风险,并指定这些风险的所有权,以及实施和缓解策略。风险适用于服务的所有领域,从技术控制到环境灾难场景和人为因素。例如,恶意内部人员。可以使用多种机制对风险进行评级。例如,可能性与影响。OpenStack 部署风险评估可以包括控制差距。 + +#### 访问和日志审查 + +需要定期访问和日志审查,以确保服务部署中的身份验证、授权和问责制。有关这些主题的 OpenStack 的具体指南在监控和日志记录中进行了深入讨论。 + +OpenStack Identity 服务支持云审计数据联合 (CADF) 通知,提供审计数据以符合安全性、操作和业务流程。有关更多信息,请参阅 Keystone 开发人员文档。 + +#### 备份和灾难恢复 + +灾难恢复 (DR) 和业务连续性规划 (BCP) 计划是 ISMS 和合规性活动的常见要求。这些计划必须定期测试并记录在案。在 OpenStack 中,关键区域位于管理安全域中,以及任何可以识别单点故障 (SPOF) 的地方。 + +#### 安全培训 + +针对特定角色的年度安全培训是几乎所有合规性认证和证明的强制性要求。为了优化安全培训的有效性,一种常见的方法是提供特定于角色的培训,例如向开发人员、操作人员和非技术人员提供培训。基于此强化指南的其他云安全或 OpenStack 安全培训将是理想的选择。 + +#### 安全审查 + +由于OpenStack是一个流行的开源项目,因此许多代码库和架构已经过个人贡献者、组织和企业的审查。从安全角度来看,这可能是有利的,但是对于服务提供商来说,安全审查的需求仍然是一个关键的考虑因素,因为部署各不相同,而且安全性并不总是贡献者的主要关注点。全面的安全审查过程可能包括架构审查、威胁建模、源代码分析和渗透测试。有许多用于进行安全审查的技术和建议,可以在公开发布中找到。一个经过充分测试的例子是 Microsoft SDL,它是作为 Microsoft 可信计算计划的一部分创建的。 + +#### 漏洞管理 + +安全更新对于任何 IaaS 部署(无论是私有部署还是公共部署)都至关重要。易受攻击的系统扩大了攻击面,是攻击者的明显目标。常见的扫描技术和漏洞通知服务可以帮助缓解这种威胁。重要的是,扫描要经过身份验证,并且缓解策略要超越简单的外围强化。OpenStack 等多租户架构特别容易受到虚拟机管理程序漏洞的影响,因此这是漏洞管理系统的关键部分。 + +#### 数据分类 + +数据分类定义了一种对信息进行分类和处理的方法,通常用于保护客户信息免遭意外或故意盗窃、丢失或不当披露。最常见的情况是,这涉及将信息分类为敏感或非敏感信息,或个人身份信息 (PII)。根据部署的上下文,可以使用各种其他分类标准(政府、医疗保健)。基本原则是明确定义和使用数据分类。最常见的保护机制包括行业标准加密技术。 + +#### 异常过程 + +异常过程是 ISMS 的重要组成部分。当某些操作不符合组织定义的安全策略时,必须记录这些操作。需要包括适当的理由、描述和缓解细节,并由有关当局签署。OpenStack 默认配置在满足各种合规性标准方面可能会有所不同,应记录不符合合规性要求的区域,并考虑潜在的修复程序以对社区做出贡献。 + +### 认证和合规声明 + +合规性和安全性不是排他性的,必须一起解决。如果不进行安全强化,OpenStack 部署不太可能满足合规性要求。下面的列表提供了 OpenStack 架构师的基础知识和指导,以实现对商业和政府认证和标准的合规性。 + +#### 商业标准 + +对于OpenStack的商业部署,我们建议将SOC 1/2与ISO 2700 1/2相结合,作为OpenStack认证活动的起点。这些认证规定的所需安全活动有助于为安全最佳实践和通用控制标准奠定基础,从而有助于实现更严格的合规性活动,包括政府证明和认证。 + +完成这些初始认证后,其余认证将更加特定于部署。例如,处理信用卡交易的云需要 PCI-DSS,存储医疗保健信息的云需要 HIPAA,联邦政府内部的云可能需要 FedRAMP/FISMA 和 ITAR 认证。 + +##### SOC 1 (SSAE 16) / ISAE 3402 + +服务组织控制 (SOC) 标准由美国注册会计师协会 (AICPA) 定义。SOC 控制评估服务提供商的相关财务报表和断言,例如是否遵守《萨班斯-奥克斯利法案》。 SOC 1 取代了审计准则第 70 号声明 (SAS 70) II 类报告。这些控制措施通常包括范围内的物理数据中心。 + +有两种类型的 SOC 1 报告: + +- 类型 1 - 报告管理层对服务组织系统的描述的公允性,以及控制设计是否适合实现截至指定日期的描述中包含的相关控制目标。 +- 类型 2 - 报告管理层对服务组织系统的描述的公允性,以及控制措施的设计和运营有效性是否适合在特定时期内实现描述中包含的相关控制目标 + +有关详细信息,请参阅AICPA关于与用户实体财务报告内部控制相关的服务组织控制的报告。 + +##### SOC 2 函数 + +服务组织控制 (SOC) 2 是对影响服务组织用于处理用户数据的系统的安全性、可用性和处理完整性以及这些系统处理的信息的机密性和隐私性的控制的自我证明。用户示例包括负责服务组织治理的人员、服务组织的客户、监管机构、业务合作伙伴、供应商以及了解服务组织及其控制措施的其他人员。 + +有两种类型的 SOC 2 报告: + +- 类型 1 - 报告管理层对服务组织系统的描述的公允性,以及控制设计是否适合实现截至指定日期的描述中包含的相关控制目标。 +- 类型 2 - 报告管理层对服务组织系统的描述的公允性,以及控制的设计和运营有效性的适用性,以在特定时期内实现描述中包含的相关控制目标。 + +有关详细信息,请参阅 AICPA 关于服务组织中与安全性、可用性、处理完整性、机密性或隐私相关的控制的报告。 + +##### SOC 3 函数 + +服务组织控制 (SOC) 3 是服务组织的信任服务报告。这些报告旨在满足以下用户的需求:这些用户希望确保服务组织中与安全性、可用性、处理完整性、机密性或隐私相关的控制措施,但没有有效使用 SOC 2 报告所需的知识。这些报告是根据 AICPA/加拿大特许会计师协会 (CICA) 关于安全性、可用性、处理完整性、机密性和隐私的信托服务原则、标准和插图编写的。由于 SOC 3 报告是通用报告,因此可以作为印章自由分发或发布在网站上。 + +有关详细信息,请参阅服务组织的 AICPA 信任服务报告。 + +##### ISO 27001/2 认证 + +ISO/IEC 27001/2 标准取代了 BS7799-2,是信息安全管理体系 (ISMS) 的规范。ISMS 是组织为管理信息资产风险而创建和维护的一整套策略和过程。这些风险基于用户信息的机密性、完整性和可用性 (CIA)。中央情报局的安全三合会已被用作本书大部分章节的基础。 + +有关详细信息,请参阅 ISO 27001。 + +##### HIPAA / HITECH + +健康保险流通与责任法案 (HIPAA) 是美国国会的一项法案,用于管理患者健康记录的收集、存储、使用和销毁。该法案规定,受保护的健康信息(PHI)必须对未经授权的人员“不可用、不可读或无法破译”,并且应解决“静态”和“动态”数据的加密问题。 + +HIPAA 不是认证,而是保护医疗保健数据的指南。与 PCI-DSS 类似,PCI 和 HIPPA 最重要的问题是不会发生信用卡信息和健康数据泄露的情况。在发生违规行为时,将仔细审查云提供商是否符合 PCI 和 HIPPA 控制措施。如果证明合规,提供商将立即实施补救控制、违规通知责任以及用于额外合规活动的大量支出。如果不合规,云提供商可能会面临现场审计团队、罚款、潜在的商家 ID (PCI) 丢失以及巨大的声誉影响。 + +拥有 PHI 的用户或组织必须支持 HIPAA 要求,并且是 HIPAA 涵盖的实体。如果实体打算使用某项服务,或者在本例中,使用可能使用、存储或访问该 PHI 的 OpenStack 云,则必须签署业务伙伴协议 (BAA)。BAA 是 HIPAA 涵盖的实体与 OpenStack 服务提供商之间的合同,要求提供商根据 HIPAA 要求处理该 PHI。如果服务提供商不处理 PHI,例如安全控制和强化,那么他们将受到 HIPAA 的罚款和处罚。 + +OpenStack 架构师解释和响应 HIPAA 声明,数据加密仍然是核心实践。目前,这将要求使用行业标准加密算法对 OpenStack 部署中包含的任何受保护的健康信息进行加密。未来潜在的OpenStack项目,如对象加密,将促进HIPAA准则的遵守。 + +有关详细信息,请参阅《健康保险流通与责任法案》。 + +##### PCI-DSS + +支付卡行业数据安全标准 (PCI DSS) 由支付卡行业标准委员会定义,旨在加强对持卡人数据的控制,以减少信用卡欺诈。年度合规性验证由外部合格安全评估机构 (QSA) 进行评估,该评估机构会根据持卡人的交易量创建合规报告 (ROC),或通过自我评估问卷 (SAQ) 进行评估。 + +存储、处理或传输支付卡详细信息的 OpenStack 部署在 PCI-DSS 的范围内。所有未从处理支付数据的系统或网络中正确分割的 OpenStack 组件都属于 PCI-DSS 的准则。PCI-DSS 上下文中的分段不支持多租户,而是物理分离(主机/网络)。 + +有关详细信息,请参阅 PCI 安全标准。 + +#### 政府标准 + +##### FedRAMP + +“联邦风险和授权管理计划 (FedRAMP) 是一项政府范围的计划,它为云产品和服务的安全评估、授权和持续监控提供了一种标准化方法”。NIST 800-53 是 FISMA 和 FedRAMP 的基础,后者要求专门选择安全控制以在云环境中提供保护。由于安全控制的特殊性以及满足政府标准所需的文档量,FedRAMP 可能非常密集。 + +有关详细信息,请参阅 FedRAMP。 + +##### ITAR + +《国际武器贸易条例》(ITAR) 是一套美国政府法规,用于控制美国军需品清单 (USML) 和相关技术数据中与国防相关的物品和服务的进出口。ITAR通常被云提供商视为“操作一致性”,而不是正式认证。这通常涉及按照 FISMA 要求,遵循基于 NIST 800-53 框架的做法实施隔离的云环境,并辅以限制仅访问“美国人”和背景筛选的额外控制措施。 + +有关详细信息,请参阅《国际武器贸易条例》(ITAR)。 + +##### FISMA + +《联邦信息安全管理法》要求政府机构制定一项全面的计划,以实施众多政府安全标准,并在 2002 年的《电子政务法》中颁布。FISMA概述了一个过程,该过程利用多个NIST出版物,准备了一个信息系统来存储和处理政府数据。 + +此过程分为三个主要类别: + +系统分类: + +信息系统将收到联邦信息处理标准出版物 199 (FIPS 199) 中定义的安全类别。这些类别反映了系统入侵的潜在影响。 + +控件选择: + +根据 FIPS 199 中定义的系统安全类别,组织利用 FIPS 200 来确定信息系统的特定安全控制要求。例如,如果系统被归类为“中等”,则可能会引入强制要求“安全密码”的要求。 + +控制定制: + +一旦确定了系统安全控制措施,OpenStack 架构师将利用 NIST 800-53 来提取量身定制的控制措施选择。例如,规范什么是“安全密码”。 + +### 隐私 + +隐私是合规计划中越来越重要的元素。客户对企业的要求越来越高,他们越来越有兴趣从隐私的角度了解他们的数据是如何被处理的。 + +OpenStack部署可能需要证明符合组织的隐私政策,以及美国-欧盟。安全港框架、ISO/IEC 29100:2011 隐私框架或其他特定于隐私的准则。在美国,美国注册会计师协会(AICPA)已经定义了10个隐私重点领域,在商业环境中部署OpenStack可能希望证明其中的部分或全部原则。 + +为了帮助 OpenStack 架构师保护个人数据,我们建议 OpenStack 架构师查看 NIST 出版物 800-122,标题为“保护个人身份信息 (PII) 机密性指南”。本指南逐步完成保护过程: + +> "...由机构维护的有关个人的任何信息,包括 (1) 可用于区分或追踪个人身份的任何信息,例如姓名、社会安全号码、出生日期和地点、母亲的婚前姓氏或生物识别记录;(2)与个人有联系或可联系的任何其他信息,如医疗、教育、财务和就业信息......” + +全面的隐私管理需要大量的准备、思考和投资。在构建全球OpenStack云时,还引入了额外的复杂性,例如,在美国和更严格的欧盟隐私法之间的差异中导航。此外,在处理敏感的 PII 时需要格外小心,其中可能包括信用卡号或医疗记录等信息。这些敏感数据不仅受隐私法的约束,还受监管和政府法规的约束。通过遵循既定的最佳实践,包括政府发布的最佳实践,可以为OpenStack部署创建和实践一个全面的隐私管理政策。 + +## 安全审查 + +OpenStack社区安全审查的目标是识别OpenStack项目设计或实现中的弱点。虽然这些弱点很少见,但可能会对OpenStack部署的安全性产生灾难性的影响,因此应该努力将这些缺陷在已发布项目中的可能性降到最低。在安全审查过程中,应了解并记录以下内容: + +- 系统的所有入口点 +- 风险资产 +- 数据持久化的位置 +- 数据如何在系统组件之间传输 +- 数据格式和转换 +- 项目的外部依赖项 +- 一组商定的调查结果和/或缺陷 +- 项目如何与外部依赖项交互 + +对 OpenStack 可交付存储库执行安全审查的一个常见原因是协助漏洞管理团队 (VMT) 监督。OpenStack VMT 列出了受监督的存储库,其中漏洞的报告接收和披露由 VMT 管理。虽然不是严格的要求,但某种形式的安全审查、审计或威胁分析可以帮助每个人更轻松地查明系统更容易出现漏洞的区域,并在它们成为用户问题之前解决它们。 + +OpenStack VMT 建议,对项目推荐的部署进行架构审查是一种适当的安全审查形式,在审查需求与 OpenStack 规模的项目资源需求之间取得平衡。安全架构审查通常也称为威胁分析、安全分析或威胁建模。在OpenStack安全审查的背景下,这些术语是架构安全审查的同义词,它可以识别项目或参考架构设计中的缺陷,并可能导致进一步的调查工作来验证部分实现。 + +对于新项目以及第三方未进行安全审查或无法共享其结果的情况,预计安全审查将是正常途径。需要安全审查的项目的信息将在即将到来的安全审查过程中提供。 + +如果第三方已经执行了安全审查,或者项目更喜欢使用第三方来执行审查,则在即将到来的第三方安全审查过程中将提供有关如何获取该第三方审查的输出并将其提交验证的信息。 + +无论哪种情况,对文档工件的要求都是相似的 - 项目必须提供最佳实践部署的架构图。虽然强烈建议作为所有团队开发周期的一部分,但漏洞扫描和静态分析扫描不足以作为第三方审查的证据。 + +- 架构页面指南 + - 标题、版本信息、联系方式 + - 项目描述和目的 + - 主要用户和用例 + - 外部依赖关系和关联的安全假设 + - 组件 + - 服务架构图 + - 数据资产 + - 数据资产影响分析 + - 接口 + - 资源 + +### 架构页面指南 + +架构页面的目的是记录服务或项目的体系结构、用途和安全控制。它应该记录该项目的最佳实践部署。 + +架构页面有一些关键部分,下面将更详细地解释这些部分: + +- 标题、版本信息、联系方式 +- 项目描述和目的 +- 主要用户和用例 +- 外部依赖关系和关联的安全假设 +- 组件 +- 架构图 +- 数据资产 +- 数据资产影响分析 +- 接口 + +#### 标题、版本信息、联系方式 + +本部分为架构页面添加标题,提供评审状态(草稿、准备评审、已审核),并捕获项目的发布和版本(如果相关)。它还记录了项目的 PTL、负责生成架构页面、图表和完成评审的项目架构师(这可能是也可能不是 PTL)和安全评审员。 + +#### 项目描述和目的 + +本节将包含项目的简要说明,以向第三方介绍该服务。这应该是一两个段落,可以从 wiki 或其他文档中剪切/粘贴。包括相关演示文稿和更多文档的链接(如果有)。 + +例如: + +“Anchor 是一种公钥基础设施 (PKI) 服务,它使用自动证书请求验证来自动做出颁发决策。证书的颁发时间很短(通常为 12-48 小时),以避免与 CRL 和 OCSP 相关的有缺陷的吊销问题。 + +#### 主要用户和用例 + +已实现架构的预期主要用户及其用例的列表。“用户”可以是 OpenStack 中的参与者或其他服务。 + +例如: + +1. 最终用户将使用系统来存储敏感数据,例如密码、加密密钥等。 +2. 云管理员将使用管理 API 来管理资源配额。 + +#### 外部依赖和相关的安全假设 + +外部依赖项是服务操作所需的不受控制的项,如果它们受到威胁或变得不可用,可能会影响服务。这些项目通常不在开发人员的控制范围内,但在部署者的控制范围内,或者它们可能由第三方操作。设备应被视为外部依赖项。 + +例如: + +- Nova 计算服务依赖于外部身份验证和授权服务。在典型部署中,此依赖关系将由 keystone 服务实现。 +- Barbican 依赖于硬件安全模块 (HSM) 设备的使用。 + +#### 组件 + +已部署项目的组件列表,不包括外部实体。每个组件都应命名并简要描述其用途,并使用使用的主要技术(例如 Python、MySQL、RabbitMQ)进行标记。 + +例如: + +- keystone 监听器进程 (Python):使用 keystone 服务发布的 keystone 事件的 Python 进程。 +- 数据库 (MySQL):MySQL 数据库,用于存储与其托管实体及其元数据相关的巴比肯状态数据。 + +#### 服务架构图 + +架构图显示了系统的逻辑布局,以便安全审阅者可以与项目团队一起逐步完成架构。它是一个逻辑图,显示组件如何交互、它们如何连接到外部实体以及通信跨越信任边界的位置。有关架构图的更多信息,包括符号键,将在即将发布的架构图指南中给出。可以在任何可以生成使用键中符号的图表的工具中绘制图表,但强烈建议 draw.io。 + +此示例显示了 barbican 架构图: + +![../_images/security_review_barbican_architecture.png](https://docs.openstack.org/security-guide/_images/security_review_barbican_architecture.png) + +#### 数据资产 + +数据资产是攻击者可能针对的用户数据、高价值数据、配置项、授权令牌或其他项。数据项集因项目而异,但一般而言,应将其视为对项目预期操作至关重要的类别。所需的详细程度在某种程度上取决于上下文。数据通常可以分组,例如“用户数据”、“机密数据”或“配置文件”,但也可以是单数,例如“管理员身份令牌”或“用户身份令牌”或“数据库配置文件”。 + +数据资产应包括该资产持久化位置的声明。 + +例如: + +- 机密数据 - 密码、加密密钥、RSA 密钥 - 保留在数据库 [PKCS#11] 或 HSM [KMIP] 或 [KMIP、Dogtag] 中 +- RBAC 规则集 - 保留在 policy.json 中 +- RabbitMQ 凭证 - 保留在 barbican.conf 中 +- keystone 事件队列凭据 - 保留在 barbican.conf 中 +- 中间件配置 - 保留在粘贴 .ini 中 + +#### 数据资产影响分析 + +数据资产影响分析分解了每个数据资产的机密性、完整性或可用性损失的影响。项目架构师应该尝试完成这项工作,因为他们最详细地了解他们的项目,但 OpenStack 安全项目 (OSSP) 将在安全审查期间与项目一起解决这 个问题,并可能添加或更新影响细节。 + +例如: + +- RabbitMQ 凭据: + - 完整性故障影响:barbican 和 Workers 无法再访问队列。拒绝服务。 + - 机密性故障影响:攻击者可以将新任务添加到队列中,这些任务将由工作人员执行。攻击者可能耗尽用户配额。拒绝服务。用户将无法创建真正的机密。 + - 可用性故障影响:如果没有对队列的访问权限,barbican 无法再创建新密钥。 +- Keystone 凭据: + - 完整性故障影响:barbican 将无法验证用户凭据并失败。拒绝服务。 + - 机密性故障影响:恶意用户可能会滥用其他 OpenStack 服务(取决于 keystone 角色配置),但 barbican 不受影响。如果用于令牌验证的服务帐户也具有 barbican 管理员权限,则恶意用户可以操纵 barbican 管理员功能。 + - 可用性故障影响:barbican 将无法验证用户凭据并失败。拒绝服务。 + +#### 接口 + +接口列表捕获了审查范围内的接口。这包括架构图上跨越信任边界或不使用行业标准加密协议(如 TLS 或 SSH)的模块之间的连接。对于每个接口,将捕获以下信息: + +> - 使用的协议 +> - 通过该接口传输的任何数据资产 +> - 有关用于连接到该接口的身份验证的信息 +> - 接口用途的简要说明。 + +记录格式如下: + +从>到[传输方式]: + +- 动态资产 +- 身份认证? +- 描述 + +例如: + +1. 客户端>API 进程 [TLS]: + - 传输中的资产:用户密钥失真凭据、明文密钥、HTTP 谓词、密钥 ID、路径 + - 对 keystone 凭据或明文机密的访问被视为系统的完全安全故障 - 此接口必须具有强大的机密性和完整性控制。 + +#### 资源 + +列出与项目相关的资源,例如描述其部署和用法的 Wiki 页面,以及指向代码存储库和相关演示文稿的链接。 + +## 安全检查表 + +- 身份服务检查表 +- 仪表板检查表 +- 计算服务检查表 +- 块存储服务检查表 +- 共享文件系统服务检查表 +- 网络服务检查表 + +## 附录 + +- 社区支持 +- 词汇表 + +### 社区支持 + +以下资源可帮助您运行和使用 OpenStack。OpenStack社区不断改进和增加OpenStack的主要功能,但如果您有任何问题,请随时提问。使用以下资源获取 OpenStack 支持并对安装进行故障排除。 + +#### 文档 + +有关可用的 OpenStack 文档,请参阅 docs.openstack.org。 + +以下指南解释了如何安装概念验证 OpenStack 云及其相关组件: + +- Rocky 安装指南 + +以下书籍介绍了如何配置和运行 OpenStack 云: + +- 架构设计指南 +- Rocky 管理员指南 +- Rocky 配置指南 +- Rocky 网络指南 +- 高可用性指南 +- 安全指南 +- 虚拟机映像指南 + +以下书籍介绍了如何使用命令行客户端: + +- Rocky API 绑定 + +以下文档提供了 OpenStack API 的参考和指导信息: + +- API 文档 + +以下指南提供了有关如何为 OpenStack 文档做出贡献的信息: + +- 文档贡献者指南 + +#### OpenStack wiki + +OpenStack wiki 包含广泛的主题,但有些信息可能很难找到或只有几页深。幸运的是,Wiki 搜索功能使您能够按标题或内容进行搜索。如果您搜索特定信息,例如有关网络或 OpenStack 计算的信息,您可以找到大量相关材料。更多内容一直在添加,因此请务必经常回来查看。您可以在任何 OpenStack wiki 页面的右上角找到搜索框。 + +#### Launchpad bug 区域 + +OpenStack 社区重视您的设置和测试工作,并希望得到您的反馈。要记录bug,您必须注册一个 Launchpad 帐户。您可以在 Launchpad bug 区域中查看现有bug并报告bug。使用搜索功能确定bug是否已报告或已修复。如果您的bug似乎仍未报告,请填写bug报告。 + +一些提示: + +- 给出一个清晰、简洁的总结。 +- 在描述中提供尽可能多的详细信息。粘贴命令输出或堆栈跟踪、屏幕截图链接以及可能有用的任何其他信息。 +- 请务必包括您正在使用的软件和软件包版本,尤其是在使用开发分支(如 `"Kilo release" vs git commit bc79c3ecc55929bac585d04a03475b72e06a3208` . +- 任何特定于部署的信息都很有用,例如您使用的是 Ubuntu 14.04 还是正在执行多节点安装。 + +以下 Launchpad Bug 区域可用: + +- Bugs:OpenStack 块存储 (cinder) +- Bugs:OpenStack 计算(nova) +- Bugs:OpenStack 仪表板(horizon) +- Bugs:OpenStack 身份认证(keystone) +- Bugs:OpenStack 镜像服务 (glance) +- Bugs:OpenStack 网络(neutron) +- Bugs:OpenStack 对象存储 (swift) +- Bugs:应用程序目录 (murano) +- Bugs:裸机服务(ironic) +- Bugs:集群服务(senlin) +- Bugs:容器基础架构管理服务(magnum) +- Bugs:数据处理服务(sahara) +- Bugs:数据库服务 (trove) +- Bugs:DNS服务(designate) +- Bugs:密钥管理服务(barbican) +- Bugs:监控 (monasca) +- Bugs:编排 (heat) +- Bugs:评级 (cloudkitty) +- Bugs:共享文件系统 (manila) +- Bugs:遥测(ceilometer) +- Bugs:遥测v3 (gnocchi) +- Bugs:工作流服务 (mistral) +- Bugs:消息传递服务 (zaqar) +- Bugs:容器服务 (zun) +- Bugs:OpenStack API 文档 (developer.openstack.org) +- Bugs:OpenStack 文档 (docs.openstack.org) + +#### 文档反馈 + +要提供有关文档的反馈,请加入我们在 OFTC IRC 网络上的 IRC 频道 `#openstack-doc` ,或在 Launchpad 中报告错误并选择文档所属的特定项目。 + +#### OpenStack IRC 频道 + +OpenStack 社区位于 OFTC 网络上的 #openstack IRC 频道中。您可以在这里提问,获取即时反馈,解决紧急问题。要安装 IRC 客户端或使用基于浏览器的客户端,请访问 (Mac OS X)、mIRC (Windows) 或 XChat (Linux)。当您在 IRC 频道中并且想要共享代码或命令输出时,通常接受的方法是使用 Paste Bin。OpenStack 项目有一个Paste网站。只需将较长的文本或日志粘贴到 Web 表单中,即可获得一个URL,可以将其粘贴到频道中。OpenStack IRC 频道处于 `#openstack` . `irc.oftc.net` 您可以在 wiki 的 IRC 页面上找到所有 OpenStack IRC 频道的列表。 + +#### OpenStack 邮件列表 + +获得答案和见解的一个好方法是将您的问题或有问题的场景发布到 OpenStack 邮件列表中。您可以向可能遇到类似问题的其他人学习和提供帮助。要订阅或查看存档,请访问一般的 OpenStack 邮件列表。如果您对特定项目或开发的其他邮件列表感兴趣,请参阅邮件列表。 + +#### OpenStack 发行包 + +以下 Linux 发行版为 OpenStack 提供社区支持的软件包: + +- **CentOS, Fedora, and Red Hat Enterprise Linux:** +- **openSUSE and SUSE Linux Enterprise Server:** +- **Ubuntu:** + +### 词汇表 + +本词汇表提供了一系列术语和定义,用于定义 OpenStack 相关概念的词汇表。 + +要添加到 OpenStack 术语表,请克隆 openstack/openstack-manuals 存储库,并通过 OpenStack 贡献过程更新源文件 `doc/common/glossary.rst` 。 + +#### 0-9 + +- 2023.1 Antelope + + OpenStack 第 27 版的代号。此版本是基于“年”之后形成的新版本标识过程的第一个版本。年内释放计数“,Antelope是一种敏捷而亲切的动物,也是一种蒸汽机车的类型。 + +- 2023.2 Bobcat + + OpenStack 第 28 版的代号。 + +- 2024.1 Caracal + + OpenStack 第 29 版的代号。 + +- 6to4 + + 一种允许 IPv6 数据包通过 IPv4 网络传输的机制,提供迁移到 IPv6 的策略。 + +#### A + +绝对限制 + +客户机虚拟机的不可逾越限制。 设置包括总 RAM 大小、最大 vCPU 数和最大磁盘大小。 + +访问控制列表(ACL) + +附加到对象的权限列表。ACL 指定哪些用户或系统进程有权访问对象。它还定义可以对指定对象执行哪些操作。典型 ACL 中的每个条目都指定一个主题和一个操作。例如,文件的 ACL 条目 `(Alice, delete)` 授予 Alice 删除该文件的权限。 + +访问密钥 + +Amazon EC2 访问密钥的替代术语。请参阅 EC2 访问密钥。 + +账户 + +对象存储中账户的上下文。不要与身份验证服务中的用户帐户混淆,例如 Active Directory、/etc/passwd、OpenLDAP、OpenStack Identity 等。 + +账户审核员 + +通过对后端 SQLite 数据库运行查询,检查指定对象存储帐户中缺少的副本以及不正确或损坏的对象。 + +账户数据库 + +一个 SQLite 数据库,其中包含对象存储帐户和相关元数据,并且帐户服务器可以访问该数据库。 + +账户回收器 + +一个对象存储工作线程,用于扫描和删除帐户数据库,并且帐户服务器已标记为删除。 + +账户服务器 + +列出对象存储中的容器,并将容器信息存储在帐户数据库中。 + +账户服务 + +对象存储组件,提供列表、创建、修改、审计等账号服务。不要与 OpenStack Identity 服务、OpenLDAP 或类似的用户帐户服务混淆。 + +会计 + +计算服务通过事件通知和系统使用情况数据工具提供会计信息。 + +活动目录 + +Microsoft 基于 LDAP 的身份验证和身份服务。在 OpenStack 中受支持。 + +主/主配置 + +在具有主/主配置的高可用性设置中,多个系统一起分担负载,如果其中一个系统发生故障,则负载将分配给其余系统。 + +主/备配置 + +在具有主/备配置的高可用性设置中,系统设置为使其他资源联机以替换那些出现故障的资源。 + +地址池 + +分配给项目的一组固定和/或浮动 IP 地址,可由项目中的 VM 实例使用或分配给项目。 + +地址解析协议 (ARP) + +将三层IP地址解析为二层链路本地地址的协议。 + +管理员 API + +授权管理员可访问的 API 调用子集,最终用户或公共 Internet 通常无法访问这些调用。它们可以作为单独的服务 (keystone) 存在,也可以是另一个 API (nova) 的子集。 + +管理员服务器 + +在 Identity 服务的上下文中,提供对管理 API 的访问的工作进程。 + +管理员 + +负责安装、配置和管理 OpenStack 云的人员。 + +高级消息队列协议 (AMQP) + +OpenStack 组件用于服务内部通信的开放标准消息传递协议,由 RabbitMQ、Qpid 或 ZeroMQ 提供。 + +高级 RISC 机器 (ARM) + +低功耗 CPU 常见于移动和嵌入式设备中。由 OpenStack 支持。 + +警报 + +计算服务可以通过其通知系统发送警报,该系统包括用于创建自定义通知驱动程序的工具。警报可以发送到并在仪表板上显示。 + +分配 + +从地址池中获取浮动 IP 地址,以便将其与来宾 VM 实例上的固定 IP 相关联的过程。 + +Amazon 内核映像 (AKI) + +VM 容器格式和磁盘格式。受Image服务支持。 + +Amazon 系统映像 (AMI) + +VM 容器格式和磁盘格式。受Image服务支持。 + +Amazon Ramdisk 映像 (ARI) + +VM 容器格式和磁盘格式。受Image服务支持。 + +Anvil + +将名为 DevStack 的基于 shell 脚本的项目移植到 Python 的项目。 + +AODH + +OpenStack 遥测服务的一部分;提供报警功能。 + +Apache + +Apache 软件基金会支持 Apache 开源软件项目的 Apache 社区。这些项目为公共利益提供软件产品。 + +Apache 许可证 2.0 + +所有 OpenStack 核心项目都是根据 Apache License 2.0 许可证的条款提供的。 + +Apache Web 服务器 + +目前在 Internet 上使用的最常用的 Web 服务器软件。 + +API 端点 + +客户端为访问 API 而与之通信的守护程序、工作程序或服务。API 终结点可以提供任意数量的服务,例如身份验证、销售数据、性能指标、计算 VM 命令、人口普查数据等。 + +API 扩展 + +扩展某些 OpenStack 核心 API 的自定义模块。 + +API 扩展插件 + +网络插件或网络 API 扩展的替代术语。 + +API 密钥 + +API 令牌的替代术语。 + +API 服务器 + +运行提供 API 端点的守护程序或工作线程的任何节点。 + +API 令牌 + +传递给 API 请求并由 OpenStack 用于验证客户端是否有权运行请求的操作。 + +API 版本 + +在 OpenStack 中,项目的 API 版本是 URL 的一部分。例如, `example.com/nova/v1/foobar` . + +小应用程序 + +可以嵌入到网页中的 Java 程序。 + +应用程序目录服务(murano) + +提供应用程序目录服务的项目,以便用户可以在管理应用程序生命周期的同时,在应用程序抽象级别上编写和部署复合环境。 + +应用程序编程接口(API) + +用于访问服务、应用程序或程序的规范集合。包括服务调用、每个调用的必需参数以及预期的返回值。 + +应用服务器 + +一种软件,它使另一种软件在网络上可用。 + +应用服务提供者商(ASP) + +租用专用应用程序的公司,这些应用程序可帮助企业和组织以更低的成本提供附加服务。 + +可分配 + +用于维护 Linux 内核防火墙模块中的地址解析协议数据包过滤规则的工具。在计算中与 iptables、ebtables 和 ip6tables 一起使用,为 VM 提供防火墙服务。 + +关联 + +将计算浮动 IP 地址与固定 IP 地址关联的过程。 + +异步 JavaScript 和 XML (AJAX) + +一组相互关联的 Web 开发技术,用于在客户端创建异步 Web 应用程序。在地平线中广泛使用。 + +以太网 ATA (AoE) + +在以太网中建立隧道的磁盘存储协议。 + +附加 + +在网络中将 VIF 或 vNIC 连接到 L2 网络的过程。在计算上下文中,此过程将存储卷连接到实例。 + +附件(网络) + +接口 ID 与逻辑端口的关联。将接口插入端口。 + +审计 + +通过系统使用情况数据工具在计算中提供。 + + 审计员 + +验证对象存储对象、容器和帐户完整性的工作进程。审核员是对象存储帐户审计员、容器审计员和对象审计员的统称。 + +Austin + +OpenStack 初始版本的代号。首届设计峰会在美国德克萨斯州奥斯汀举行。 + +auth 节点 + +对象存储授权节点的替代术语。 + +身份验证 + +通过私钥、秘密令牌、密码、指纹或类似方法确认用户、进程或客户端确实是他们所说的人的过程。 + +身份验证令牌 + +身份验证后提供给客户端的文本字符串。必须由用户或进程在对 API 端点的后续请求中提供。 + +AuthN + +提供身份验证服务的标识服务组件。 + +授权 + +验证用户、进程或客户端是否有权执行操作的行为。 + +授权节点 + +提供授权服务的对象存储节点。 + +AuthZ + +提供高级授权服务的身份组件。 + +自动确认 + +RabbitMQ 中的配置设置,用于启用或禁用消息确认。默认启用。 + +自动声明 + +一个 Compute RabbitMQ 设置,用于确定在程序启动时是否自动创建消息交换。 + +可用区 + +用于容错的隔离区域的 Amazon EC2 概念。不要与 OpenStack Compute 区域或单元混淆。 + +AWS CloudFormation 模板 + +AWS CloudFormation 允许 Amazon Web Services (AWS) 用户创建和管理相关资源的集合。编排服务支持与 CloudFormation 兼容的格式 (CFN)。 + +#### B + +后端 + +对用户进行模糊处理的交互和进程,例如计算卷挂载、守护程序向 iSCSI 目标传输数据或对象存储对象完整性检查。 + +后端目录 + +身份服务目录服务用于存储和检索有关客户端可用的 API 端点的信息的存储方法。示例包括 SQL 数据库、LDAP 数据库或 KVS 后端。 + +后端存储 + +用于保存和检索服务信息的持久性数据存储,例如对象存储对象列表、客户机虚拟机的当前状态、用户名列表等。此外,映像服务用于获取和存储 VM 映像的方法。选项包括对象存储、本地挂载的文件系统、RADOS 块设备、VMware 数据存储和 HTTP。 + +备份、恢复和灾难恢复服务(freezer) + +提供用于备份、还原和恢复文件系统、实例或数据库备份的集成工具的项目。 + +带宽 + +通信资源(如 Internet)使用的可用数据量。表示用于下载内容的数据量或可供下载的数据量。 + +barbican + +Key Manager 服务的代号。 + +裸机 + +映像服务容器格式,指示 VM 映像不存在容器。 + +裸机服务(ironic) + +OpenStack 服务,它提供服务和关联的库,能够以安全感知和容错的方式管理和配置物理机。 + +基础映像 + +OpenStack 提供的映像。 + +Bell-LaPadula 模型 + +一种安全模型,侧重于数据机密性和对机密信息的受控访问。该模型将实体分为主体和客体。将主体的许可与主体的分类进行比较,以确定主体是否被授权用于特定的访问模式。间隙或分类方案用晶格表示。 + +基准服务(反弹) + +OpenStack项目,为单个OpenStack组件的性能分析和基准测试以及完整的生产OpenStack云部署提供了一个框架。 + +Bexar + +2011 年 2 月发布的与 OpenStack 相关的项目的分组版本。它仅包括计算 (nova) 和对象存储 (swift)。Bexar 是 OpenStack 第二个版本的代号。设计峰会在美国德克萨斯州圣安东尼奥举行,这里是贝克萨尔县的县城。 + +二进制 + +仅由 1 和 0 组成的信息,这是计算机的语言。 + +位 + +位是以 2 为基数的个位数(0 或 1)。带宽使用量以每秒位数为单位。 + +每秒比特数 (BPS) + +通用测量数据从一个地方传输到另一个地方的速度。 + +块设备 + +一种以块的形式移动数据的设备。这些设备节点连接设备,例如硬盘、CD-ROM 驱动器、闪存驱动器和其他可寻址内存区域。 + +区块迁移 + +KVM 使用的一种虚拟机实时迁移方法,用于在用户启动的切换期间将实例从一台主机撤离到另一台主机,停机时间非常短。不需要共享存储。由计算支持。 + +块存储 API + +单独终结点上的 API,用于为计算 VM 附加、分离和创建块存储。 + +块存储服务(cinder) + +OpenStack 服务,它实现了服务和库,通过在其他块存储设备之上的抽象和自动化,提供对块存储资源的按需自助访问。 + +BMC(基板管理控制器) + +IPMI架构中的智能,它是一种专用的微控制器,嵌入在计算机主板上并充当服务器。管理系统管理软件和平台硬件之间的接口。 + +可启动磁盘映像 + +一种 VM 映像类型,以单个可启动文件的形式存在。 + +Bootstrap 协议 (BOOTP) + +网络客户端用于从配置服务器获取 IP 地址的网络协议。在使用 FlatDHCP 管理器或 VLAN 管理器网络管理器时,通过 dnsmasq 守护程序进行计算中提供。 + +边界网关协议 (BGP) + +边界网关协议是一种连接自治系统的动态路由协议。该协议被认为是互联网的骨干,将不同的网络连接起来,形成一个更大的网络。 + +浏览器 + +使计算机或设备能够访问 Internet 的任何客户端软件。 + +构建器文件 + +包含对象存储用于重新配置环或在发生严重故障后从头开始重新创建环的配置信息。 + +扩展 + +在主环境资源受限时,利用辅助环境按需弹性构建实例的做法。 + +按钮类 + +地平线中的一组相关按钮类型。用于启动、停止和挂起 VM 的按钮位于一个类中。用于关联和取消关联浮动 IP 地址的按钮位于另一个类中,依此类推。 + +字节 + +构成单个字符的位集;一个字节通常有 8 位。 + +#### C + +缓存修剪器 + +将映像服务虚拟机映像缓存保持在或低于其配置的最大大小的程序。 + +Cactus + +2011 年春季发布的 OpenStack 项目分组版本。它包括计算 (nova)、对象存储 (swift) 和图像服务 (glance)。Cactus 是美国德克萨斯州的一个城市,是 OpenStack 第三个版本的代号。当OpenStack版本从3个月延长到6个月时,该版本的代号发生了变化,以匹配最接近上一次峰会的地理位置。 + +调用 + +OpenStack 消息队列软件使用的 RPC 原语之一。发送消息并等待响应。 + +能力 + +定义单元的资源,包括 CPU、存储和网络。可以应用于一个单元或整个单元内的特定服务。 + +容量缓存 + +计算后端数据库表,其中包含当前工作负载、可用 RAM 量以及每个主机上运行的 VM 数。用于确定 VM 在哪个主机上启动。 + +容量更新程序 + +监视 VM 实例并根据需要更新容量缓存的通知驱动程序。 + +投射 + +OpenStack 消息队列软件使用的 RPC 原语之一。发送消息,不等待响应。 + +目录 + +用户在使用 Identity 服务进行身份验证后可用的 API 端点列表。 + +目录服务 + +一种身份服务,列出用户在使用 Identity 服务进行身份验证后可用的 API 端点。 + +测高仪 + +OpenStack Telemetry 服务的一部分;收集和存储来自其他 OpenStack 服务的指标。 + +单元格 + +在子关系和父关系中提供计算资源的逻辑分区。如果父单元无法提供请求的资源,则请求将从父单元传递到子单元。 + +单元格转发 + +一个“计算”选项,该选项使父单元能够在父单元无法提供所请求的资源时将资源请求传递给子单元。 + +单元格管理器 + +计算组件,其中包含单元中每个主机的当前功能列表,并根据需要路由请求。 + +CentOS 操作系统 + +与 OpenStack 兼容的 Linux 发行版。 + +Ceph 函数 + +可大规模扩展的分布式存储系统,由对象存储、块存储和兼容 POSIX 的分布式文件系统组成。与OpenStack兼容。 + +CephFS + +Ceph 提供的符合 POSIX 标准的文件系统。 + +证书颁发机构 (CA) + +在密码学中,颁发数字证书的实体。数字证书通过证书的指定主体证明公钥的所有权。这使其他人(依赖方)能够依赖与认证公钥相对应的私钥所做的签名或断言。在这种信任关系模型中,CA 是证书主体(所有者)和依赖证书的一方的受信任第三方。CA 是许多公钥基础结构 (PKI) 方案的特征。在 OpenStack 中,Compute 为 cloudpipe VPN 和 VM 映像解密提供了一个简单的证书颁发机构。 + +挑战握手身份验证协议 (CHAP) + +计算支持的 iSCSI 身份验证方法。 + +机会调度器 + +计算使用的一种计划方法,用于从池中随机选择可用主机。 + +自上次更改以来 + +一个计算 API 参数,该参数允许下载自上次请求以来对所请求项的更改,而不是下载一组新的数据并将其与旧数据进行比较。 + +Chef + +支持 OpenStack 部署的操作系统配置管理工具。 + +子单元格 + +如果请求的资源(如 CPU 时间、磁盘存储或内存)在父单元中不可用,则该请求将转发到其关联的子单元。如果子单元可以满足请求,则它确实可以。否则,它会尝试将请求传递给其任何子级。 + +cinder + +块存储服务的代号。 + +CirrOS + +一个最小的 Linux 发行版,设计用作云(如 OpenStack)上的测试映像。 + +Cisco neutron 插件 + +适用于 Cisco 设备和技术(包括 UCS 和 Nexus)的网络插件。 + +云架构师 + +计划、设计和监督云创建的人。 + +云审计数据联邦 (CADF) + +Cloud Auditing Data Federation (CADF) 是用于审核事件数据的规范。CADF 受 OpenStack Identity 支持。 + +云计算 + +一种模型,支持访问可配置计算资源(如网络、服务器、存储、应用程序和服务)的共享池,这些资源可以快速配置和发布,只需最少的管理工作或服务提供商交互。 + +云计算基础设施 + +支持云计算模型的计算要求所需的硬件和软件组件,例如服务器、存储、网络和虚拟化软件。 + +云计算平台软件 + +通过互联网提供不同的服务。这些资源包括数据存储、服务器、数据库、网络和软件等工具和应用程序。只要电子设备可以访问网络,它就可以访问数据和运行它的软件程序。 + +云计算服务架构 + +云服务体系结构定义了在企业业务网络边界内和跨企业业务网络边界实施的整体云计算服务和解决方案。考虑核心业务需求,并将其与可能的云解决方案相匹配。 + +云控制器 + +表示云全局状态的计算组件的集合;通过队列与服务(例如身份认证、对象存储和节点/存储工作线程)进行通信。 + +云控制器节点 + +运行网络、卷、API、调度程序和映像服务的节点。每个服务都可以分解为单独的节点,以实现可伸缩性或可用性。 + +云数据管理接口(CDMI) + +SINA标准定义了一个RESTful API,用于管理云中的对象,目前在OpenStack中不受支持。 + +云基础设施管理接口(CIMI) + +正在进行的云管理规范。目前在 OpenStack 中不受支持。 + +云技术 + +云是由管理和自动化软件编排的虚拟源工具。这包括原始处理能力、内存、网络、基于云的应用程序的存储。 + +cloud-init 函数 + +通常安装在 VM 映像中的包,用于在启动后使用从元数据服务检索到的信息(如 SSH 公钥和用户数据)执行实例的初始化。 + +cloudadmin + +计算 RBAC 系统中的默认角色之一。授予完整的系统访问权限。 + +Cloudbase-初始化 + +提供来宾初始化功能的 Windows 项目,类似于 cloud-init。 + +cloudpipe + +一种基于每个项目创建 VPN 的计算服务。 + +CloudPipe 镜像 + +作为 cloudpipe 服务器的预制 VM 镜像。从本质上讲,OpenVPN运行在Linux上。 + +集群服务(senlin) + +实现集群服务和库的项目,用于管理由其他 OpenStack 服务公开的同构对象组。 + +命令过滤器 + +列出计算 rootwrap 工具中允许的命令。 + +命令行界面 (CLI) + +一个基于文本的客户端,可帮助您创建脚本以与 OpenStack 云进行交互。 + +通用 Internet 文件系统 (CIFS) + +文件共享协议。它是 Microsoft 开发和使用的原始服务器消息块 (SMB) 协议的公共或开放变体。与 SMB 协议一样, CIFS 在更高级别运行并使用 TCP/IP 协议。 + +公共库 (oslo) + +生成一组 python 库的项目,其中包含 OpenStack 项目共享的代码。这些库提供的 API 应该是高质量、稳定、一致、有文档记录的和普遍适用的。 + +社区项目 + +一个没有得到OpenStack技术委员会正式认可的项目。如果项目足够成功,它可能会被提升为孵化项目,然后被提升为核心项目,或者它可能与主代码主干合并。 + +压缩 + +通过特殊编码减小文件大小,文件可以再次解压缩为原始内容。OpenStack 支持 Linux 文件系统级别的压缩,但不支持对对象存储对象或镜像服务虚拟机映像等内容进行压缩。 + +计算 API (nova API) + +nova-api 守护程序提供对 nova 服务的访问。可以与其他 API 通信,例如 Amazon EC2 API。 + +计算控制器 + +计算组件,用于选择要在其上启动 VM 实例的合适主机。 + +计算主机 + +专用于运行计算节点的物理主机。 + +计算节点 + +运行 nova-compute 守护程序的节点,该守护程序管理提供各种服务(如 Web 应用程序和分析)的 VM 实例。 + +计算服务 (nova) + +OpenStack 核心项目,用于实现服务和相关库,以提供对计算资源(包括裸机、虚拟机和容器)的大规模可扩展、按需、自助访问。 + +计算工作进程 + +在每个计算节点上运行并管理 VM 实例生命周期的计算组件,包括运行、重新启动、终止、附加/分离卷等。由 nova-compute 守护程序提供。 + +串联对象 + +对象存储组合并发送到客户端的一组分段对象。 + +导体 + +在计算中,conductor 是代理来自计算进程的数据库请求的进程。使用 conductor 可以提高安全性,因为计算节点不需要直接访问数据库。 + +congress + +治理服务的代码名称。 + +一致性窗口 + +所有客户端都可以访问新的对象存储对象所需的时间。 + +控制台日志 + +包含计算中 Linux VM 控制台的输出。 + +容器 + +在对象存储中组织和存储对象。类似于 Linux 目录的概念,但不能嵌套。影像服务容器格式的替代术语。 + +容器审核员 + +通过对 SQLite 后端数据库的查询,检查指定对象存储容器中缺少副本或不正确的对象。 + +容器数据库 + +存储对象存储容器和容器元数据的 SQLite 数据库。容器服务器访问此数据库。 + +容器格式 + +映像服务使用的包装器,其中包含 VM 映像及其关联的元数据,例如计算机状态、OS 磁盘大小等。 + +容器基础设施管理服务(magnum) + +该项目提供一组用于预配、扩展和管理容器编排引擎的服务。 + +容器服务器 + +管理容器的对象存储服务器。 + +容器服务 + +提供创建、删除、列表等容器服务的对象存储组件。 + +内容分发网络 (CDN) + +内容分发网络是用于将内容分发到客户端的专用网络,通常位于客户端附近以提高性能。 + +持续交付 + +一种软件工程方法,团队在短周期内生产软件,确保软件可以随时可靠地发布,并且在发布软件时手动发布。 + +持续部署 + +一种软件发布过程,该过程使用自动化测试来验证对代码库的更改是否正确且稳定,以便立即自主部署到生产环境。 + +持续集成 + +每天多次将所有开发人员的工作副本合并到共享主线的做法。 + +控制器节点 + +云控制器节点的替代术语。 + +核心 API + +根据上下文,核心 API 可以是 OpenStack API 或特定核心项目的主 API,例如计算、网络、映像服务等。 + +核心服务 + +由 Interop 工作组定义为核心的官方 OpenStack 服务。目前由块存储服务(cinder)、计算服务(nova)、身份服务(keystone)、镜像服务(glance)、网络服务(neutron)和对象存储服务(swift)组成。 + +成本 + +在计算分布式计划程序下,这是通过查看每个主机相对于所请求的 VM 实例的风格的功能来计算的。 + +凭证 + +只有用户知道或可访问的数据,用于验证用户是否是他所说的人。在身份验证期间,将凭据提供给服务器。示例包括密码、密钥、数字证书和指纹。 + +CRL 函数 + +PKI 模型中的证书吊销列表 (CRL) 是已吊销的证书列表。不应信任提供这些证书的最终实体。 + +跨域资源共享 (CORS) + +一种机制,允许从资源来源域之外的另一个域请求网页上的许多资源(例如,字体、JavaScript)。特别是,JavaScript 的 AJAX 调用可以使用 XMLHttpRequest 机制。 + +Crowbar + +SUSE 的开源社区项目,旨在提供所有必要的服务,以快速部署和管理云。 + +当前工作负载 + +计算容量缓存的一个元素,根据给定主机上当前正在进行的生成、快照、迁移和调整大小操作的数量进行计算。 + +客户 + +项目的替代术语。 + +自定义模块 + +用户创建的 Python 模块,由 horizon 加载,用于更改仪表板的外观。 + +#### D + +守护进程 + +在后台运行并等待请求的进程。可能侦听也可能不侦听 TCP 或 UDP 端口。不要与工人混淆。 + +仪表板(horizon) + +OpenStack 项目,为所有 OpenStack 服务提供可扩展的、统一的、基于 Web 的用户界面。 + +数据加密 + +镜像服务和计算都支持加密的虚拟机 (VM) 镜像(但不支持实例)。OpenStack 支持使用 HTTPS、SSL、TLS 和 SSH 等技术进行传输中数据加密。对象存储不支持应用程序级别的对象加密,但可能支持使用磁盘加密的存储。 + +数据丢失防护(DLP) 软件 + +用于保护敏感信息并通过检测和拒绝数据传输来防止其泄漏到网络边界之外的软件程序。 + +数据处理服务(sahara) + +OpenStack 项目,提供可扩展的数据处理堆栈和关联的管理接口。 + +数据存储 + +数据库服务支持的数据库引擎。 + +数据库 ID + +为对象存储数据库的每个副本指定的唯一 ID。 + +数据库复制器 + +一个对象存储组件,用于将帐户、容器和对象数据库中的更改复制到其他节点。 + +数据库服务(trove) + +一个集成项目,为关系和非关系数据库引擎提供可扩展且可靠的云数据库即服务功能。 + +解除分配 + +删除浮动 IP 地址和固定 IP 地址之间的关联的过程。删除此关联后,浮动 IP 将返回到地址池。 + +Debian + +与 OpenStack 兼容的 Linux 发行版。 + +重复数据删除 + +在磁盘块、文件和/或对象级别查找重复数据以最大程度地减少存储使用的过程 - 目前在 OpenStack 中不受支持。 + +默认面板 + +用户访问仪表板时显示的默认面板。 + +默认项目 + +如果在创建用户时未指定任何项目,则会将新用户分配给此项目。 + +默认令牌 + +一个标识服务令牌,该令牌不与特定项目关联,并交换为作用域内令牌。 + +延迟删除 + +影像服务中的一个选项,用于在预定义的秒数后删除影像,而不是立即删除影像。 + +交付方式 + +Compute RabbitMQ消息投递模式的设置;可以设置为瞬态或持久性。 + +拒绝服务 (DoS) + +拒绝服务 (DoS) 是拒绝服务攻击的简称。这是阻止合法用户使用服务的恶意尝试。 + +已弃用的身份验证 + +计算中的一个选项,使管理员能够通过 `nova-manage` 命令创建和管理用户,而不是使用标识服务。 + +指定 + +DNS 服务的代号。 + +桌面即服务 + +一个平台,它提供了一套桌面环境,用户可以通过访问这些环境从任何位置接收桌面体验。这可以提供通用、开发甚至同构测试环境。 + +开发者 + +计算 RBAC 系统中的默认角色之一,也是分配给新用户的默认角色。 + +设备 ID + +将对象存储分区映射到物理存储设备。 + +设备权重 + +根据每个设备的存储容量,在对象存储设备之间按比例分配分区。 + +开发堆栈 + +使用 shell 脚本快速构建完整 OpenStack 开发环境的社区项目。 + +DHCP代理 + +为虚拟网络提供 DHCP 服务的 OpenStack Networking 代理。 + +Diablo + +2011 年秋季发布的与 OpenStack 相关的项目的分组版本,是 OpenStack 的第四个版本。它包括计算 (nova 2011.3)、对象存储 (swift 1.4.3) 和镜像服务 (glance)。Diablo是OpenStack第四个版本的代号。设计峰会在美国加利福尼亚州圣克拉拉附近的湾区举行,Diablo是附近的城市。 + +直接消费者 + +Compute RabbitMQ 的一个元素,在执行 RPC 调用时生效。它通过唯一的独占队列连接到直接交换,发送消息,然后终止。 + +直接交换 + +RPC 调用期间在 Compute RabbitMQ 中创建的路由表;为每个调用的 RPC 调用创建一个。 + +直接发布者 + +RabbitMQ 的元素,用于提供对传入 MQ 消息的响应。 + +解除关联 + +删除浮动 IP 地址和固定 IP 之间的关联,从而将浮动 IP 地址返回到地址池的过程。 + +自主访问控制 (DAC) + +控制使用者访问对象的能力,同时使用户能够做出策略决策并分配安全属性。传统的用户、组和读-写-执行权限的 UNIX 系统就是 DAC 的一个示例。 + +磁盘加密 + +能够在文件系统、磁盘分区或整个磁盘级别加密数据。在计算 VM 中受支持。 + +磁盘格式 + +VM 的磁盘映像在映像服务后端存储中存储的基础格式。例如,AMI、ISO、QCOW2、VMDK 等。 + +分散 + +在对象存储中,用于测试和确保对象和容器分散以确保容错的工具。 + +分布式虚拟路由器 (DVR) + +使用 OpenStack Networking (neutron) 时实现高可用性多主机路由的机制。 + +Django + +在地平线中广泛使用的 Web 框架。 + +DNS 记录 + +指定有关特定域并属于该域的信息的记录。 + +DNS服务(指定) + +OpenStack 项目,以与技术无关的方式提供对权威 DNS 服务的可扩展、按需、自助访问。 + +dnsmasq + +为虚拟网络提供 DNS、DHCP、BOOTP 和 TFTP 服务的守护程序。 + +域 + +标识 API v3 实体。表示项目、组和用户的集合,用于定义用于管理 OpenStack Identity 实体的管理边界。在 Internet 上,将网站与其他网站分开。通常,域名有两个或多个部分,用点分隔。例如,yahoo.com、usa.gov、harvard.edu 或 mail.yahoo.com。此外,域是包含一条或多条记录的所有 DNS 相关信息的实体或容器。 + +域名系统(DNS) + +用于确定 Internet 域名到地址和地址到名称解析的系统。DNS 通过将 IP 地址转换为更易于记忆的地址来帮助浏览 Internet。例如,将 111.111.111.1 转换为 \。所有域及其组件(如邮件服务器)都利用 DNS 解析到适当的位置。DNS服务器通常设置在主从关系中,以便主服务器故障调用从服务器。还可以对 DNS 服务器进行群集或复制,以便对一个 DNS 服务器所做的更改自动传播到其他活动服务器。在计算中,支持将 DNS 条目与浮动 IP 地址、节点或单元相关联,以便主机名在重新启动时保持一致。 + +下载 + +将数据(通常以文件的形式)从一台计算机传输到另一台计算机。 + +持久交换 + +服务器重新启动时保持活动状态的 Compute RabbitMQ 消息交换。 + +持久队列 + +一个 Compute RabbitMQ 消息队列,在服务器重新启动时保持活动状态。 + +动态主机配置协议 (DHCP) + +一种网络协议,用于配置连接到网络的设备,以便它们可以使用 Internet 协议 (IP) 在该网络上进行通信。该协议在客户端-服务器模型中实现,其中 DHCP 客户端从 DHCP 服务器请求配置数据,例如 IP 地址、默认路由以及一个或多个 DNS 服务器地址。一种在引导时自动为主机配置网络的方法。由网络和计算提供。 + +动态超文本标记语言 (DHTML) + +使用 HTML、JavaScript 和级联样式表使用户能够与网页交互或显示简单动画的页面。 + +#### E + +东西向流量 + +同一云或数据中心中的服务器之间的网络流量。另请参阅南北向流量。 + +EBS 启动卷 + +包含可启动 VM 映像的 Amazon EBS 存储卷,OpenStack 目前不支持该映像。 + +ebtables + +用于 Linux 桥接防火墙的过滤工具,支持过滤通过 Linux 桥接的网络流量。在计算中与 arptables、iptables 和 ip6tables 一起使用,以确保网络通信的隔离。 + +EC2 函数 + +Amazon 商业计算产品,类似于计算。 + +EC2 访问密钥 + +与 EC2 私有密钥一起使用以访问计算 EC2 API。 + +EC2 API + +OpenStack 支持通过计算访问 Amazon EC2 API。 + +EC2 兼容性 API + +使 OpenStack 能够与 Amazon EC2 通信的计算组件。 + +EC2 私有密钥 + +与计算 EC2 API 通信时与 EC2 访问密钥一起使用;用于对每个请求进行数字签名。 + +边缘计算 + +在云中运行更少的进程,并将这些进程移动到本地。 + +弹性块存储 (EBS) + +Amazon 商业块存储产品。 + +封装 + +将一种数据包类型置于另一种数据包类型中,以提取或保护数据。示例包括 GRE、MPLS 或 IPsec。 + +加密 + +OpenStack支持HTTPS、SSH、SSL、TLS、数字证书、数据加密等加密技术。 + +端点 + +请参阅 API 端点。 + +端点注册表 + +身份服务目录的替代术语。 + +端点模板 + +URL 和端口号端点列表,指示可以访问服务(如对象存储、计算、标识等)的位置。 + +企业云计算 + +位于防火墙后面的计算环境,为企业提供软件、基础设施和平台服务。 + +实体 + +任何想要连接到网络(网络连接服务)提供的网络服务的硬件或软件。实体可以通过实现 VIF 来利用网络。 + +临时映像 + +不保存对其卷所做的更改并在实例终止后将其恢复到原始状态的 VM 映像。 + +临时卷 + +不保存对其所做的更改并在当前用户放弃控制权时恢复到其原始状态的卷。 + +Essex + +2012 年 4 月发布的与 OpenStack 相关的项目的分组版本,是 OpenStack 的第五个版本。它包括计算(nova 2012.1)、对象存储(swift 1.4.8)、图像(glance)、身份(keystone)和仪表板(horizon)。Essex 是 OpenStack 第五个版本的代号。设计峰会在美国马萨诸塞州波士顿举行,Essex是附近的城市。 + +ESXi + +支持 OpenStack 的虚拟机管理程序。 + +ETag 函数 + +对象存储中对象的 MD5 哈希值,用于确保数据完整性。 + +euca2ools + +用于管理 VM 的命令行工具集合;大多数都与OpenStack兼容。 + +Eucalyptus Kernel Image (EKI) + +与 ERI 一起使用以创建 EMI。 + +Eucalyptus机器映像 (EMI) + +映像服务支持的虚拟机镜像容器格式。 + +Eucalyptus Ramdisk 镜像 (ERI) + +与 EKI 一起使用以创建 EMI。 + +撤离 + +将一个或所有虚拟机 (VM) 实例从一台主机迁移到另一台主机的过程,与共享存储实时迁移和块迁移兼容。 + +交换 + +RabbitMQ 消息交换的替代术语。 + +交换类型 + +Compute RabbitMQ 中的路由算法。 + +独占队列 + +由 RabbitMQ 中的直接使用者连接到 - 计算,消息只能由当前连接使用。 + +扩展属性 (xattr) + +文件系统选项,用于存储所有者、组、权限、修改时间等以外的其他信息。底层对象存储文件系统必须支持扩展属性。 + +扩展 + +API 扩展或插件的替代术语。在 Identity 服务的上下文中,这是特定于实现的调用,例如添加对 OpenID 的支持。 + +外部网络 + +通常用于 Internet 访问的网段。 + +额外规格 + +指定计算确定从何处开始新实例时的其他要求。示例包括最小网络带宽或 GPU 量。 + +#### F + +FakeLDAP + +创建用于测试身份和计算的本地 LDAP 目录的简单方法。需要 Redis。 + +fan-out交换 + +在 RabbitMQ 和 Compute 中,调度程序服务使用消息传递接口从计算、卷和网络节点接收功能消息。 + +联合身份 + +一种在身份提供商和 OpenStack 云之间建立信任的方法。 + +Fedora + +与 OpenStack 兼容的 Linux 发行版。 + +光纤通道 + +存储协议在概念上类似于 TCP/IP;封装 SCSI 命令和数据。 + +以太网光纤通道 (FCoE) + +光纤通道协议在以太网内通过隧道传输。 + +填充优先调度器 + +计算计划方法,尝试用 VM 填充主机,而不是在各种主机上启动新 VM。 + +过滤器 + +计算计划过程中的步骤,当无法运行 VM 的主机被淘汰且未被选中时。 + +防火墙 + +用于限制主机和/或节点之间的通信,在计算中使用 iptables、arptables、ip6tables 和 ebtables 实现。 + +防火墙即服务 (FWaaS) + +提供外围防火墙功能的网络扩展。 + +固定 IP 地址 + +每次启动实例时都与同一实例关联的 IP 地址通常不对最终用户或公共 Internet 访问,并用于管理实例。 + +平面管理器 + +计算组件为授权节点提供 IP 地址,并假定 DHCP、DNS 以及路由配置和服务由其他设备提供。 + +平面模式注入 + +一种计算网络方法,在实例启动之前将操作系统网络配置信息注入到 VM 映像中。 + +平面网络 + +虚拟网络类型,不使用VLAN或隧道来分隔项目流量。每个平面网络通常需要定义由桥接映射定义的单独的底层物理接口。但是,平面网络可以包含多个子网。FlatDHCP 管理器 + +提供 dnsmasq(DHCP、DNS、BOOTP、TFTP)和 radvd(路由)服务的计算组件。 + +规格 + +VM 实例类型的替代术语 + +规格ID + +每种计算或映像服务虚拟机规格或实例类型的 UUID。 + +浮动 IP 地址 + +项目可以与 VM 关联的 IP 地址,以便实例在每次启动时都具有相同的公有 IP 地址。您可以创建一个浮动 IP 地址池,并在实例启动时将其分配给实例,以保持一致的 IP 地址以维护 DNS 分配。 + +Folsom + +2012 年秋季发布的与 OpenStack 相关的项目的分组版本,是 OpenStack 的第六个版本。它包括计算 (nova)、对象存储 (swift)、身份 (keystone)、网络 (neutron)、映像服务 (glance) 以及卷或块存储 (cinder)。Folsom 是 OpenStack 第六个版本的代号。设计峰会在美国加利福尼亚州旧金山举行,福尔瑟姆是附近的城市。 + +FormPost + +对象存储中间件,通过网页上的表单上传(发布)图像。 + +freezer + +备份、还原和灾难恢复服务的代号。 + +前端 + +用户与服务交互的点;可以是 API 端点、仪表板或命令行工具。 + +#### G + +网关 + +通常分配给路由器的 IP 地址,用于在不同网络之间传递网络流量。 + +通用接收卸载 (GRO) + +某些网络接口驱动程序的功能,在传送到内核 IP 堆栈之前,将许多较小的接收数据包合并为一个大数据包。 + +通用路由封装 (GRE) + +在虚拟点对点链路中封装各种网络层协议的协议。 + +glance + +影像服务的代号。 + +glance API 服务器 + +图像 API 的替代名称。 + +glance 注册表 + +映像服务映像注册表的替代术语。 + +全局端点模板 + +包含可用于所有项目的服务的标识服务终结点模板。 + +GlusterFS + +一个旨在聚合 NAS 主机的文件系统,与 OpenStack 兼容。 + +gnocchi + +OpenStack Telemetry 服务的一部分;提供索引器和时序数据库。 + +golden映像 + +一种操作系统安装方法,其中创建最终的磁盘映像,然后由所有节点使用,无需修改。 + +治理服务(大会) + +该项目在任何云服务集合中提供治理即服务,以便监视、实施和审核动态基础结构上的策略。 + +图形交换格式 (GIF) + +一种通常用于网页上的动画图像的图像文件。 + +图形处理单元 (GPU) + +OpenStack 目前不支持根据 GPU 的存在来选择主机。 + +绿色线程 + +Python 使用的协作线程模型;减少争用条件,并且仅在进行特定库调用时进行上下文切换。每个 OpenStack 服务都是它自己的线程。 + +Grizzly + +OpenStack 第七个版本的代号。设计峰会在美国加利福尼亚州圣地亚哥举行,Grizzly是加利福尼亚州州旗的一个元素。 + +分组 + +Identity v3 API 实体。表示特定域所拥有的用户集合。 + +客户机操作系统 + +在虚拟机监控程序的控制下运行的操作系统实例。 + +#### H + +Hadoop + +Apache Hadoop 是一个开源软件框架,支持数据密集型分布式应用程序。 + +Hadoop 分布式文件系统 (HDFS) + +一种分布式、高度容错的文件系统,设计用于在低成本商用硬件上运行。 + +交接 + +对象存储中的一种对象状态,其中由于驱动器故障而自动创建对象的新副本。 + +HAProxy 函数 + +为基于 TCP 和 HTTP 的应用程序提供负载平衡器,将请求分散到多个服务器。 + +硬重启 + +一种重新启动类型,其中按下物理或虚拟电源按钮,而不是正常、正确地关闭操作系统。 + +Havana + +OpenStack 第八版的代号。设计峰会在美国俄勒冈州波特兰市举行,Havana是俄勒冈州的一个非法人社区。 + +健康监视器 + +确定 VIP 池的后端成员是否可以处理请求。一个池可以有多个与之关联的运行状况监视器。当池有多个与之关联的监视器时,所有监视器都会检查池的每个成员。所有监视器都必须声明成员运行状况良好,才能保持活动状态。 + +heat + +业务流程服务的代号。 + +Heat 编排模板 (HOT) + +以 OpenStack 原生格式的 Heat 输入。 + +高可用性 (HA) + +高可用性系统设计方法和相关服务实施可确保在合同测量期间达到预先安排的运营绩效水平。高可用性系统力求最大限度地减少系统停机时间和数据丢失。 + +horizon + +仪表板的代号。 + +Horizon 插件 + +OpenStack Dashboard (horizon) 的插件。 + +主机 + +物理计算机,而不是 VM 实例(节点)。 + +主机聚合 + +一种将可用性区域进一步细分为虚拟机管理程序池(公共主机的集合)的方法。 + +主机总线适配器 (HBA) + +插入 PCI 插槽(如光纤通道或网卡)的设备。 + +混合云 + +混合云是由两个或多个云(私有云、社区云或公有云)组成的,这些云仍然是不同的实体,但绑定在一起,提供多种部署模型的优势。混合云还意味着能够将主机托管、托管和/或专用服务与云资源连接起来。 + +混合云计算 + +混合了本地、私有云和第三方公有云服务,并在两个平台之间进行编排。 + +Hyper-V + +OpenStack 支持的虚拟机管理程序之一。 + +超链接 + +包含指向其他网站的链接的任何类型的文本,常见于单击一个或多个单词会打开其他网站的文档中。 + +超文本传输协议 (HTTP) + +用于分布式、协作式、超媒体信息系统的应用协议。它是万维网数据通信的基础。超文本是在包含文本的节点之间使用逻辑链接(超链接)的结构化文本。HTTP是交换或传输超文本的协议。 + +安全超文本传输协议 (HTTPS)一种加密通信协议,用于通过计算机网络进行安全通信,在 Internet 上的部署特别广泛。从技术上讲,它本身不是一个协议;相反,它是简单地将超文本传输协议 (HTTP) 分层在 TLS 或 SSL 协议之上的结果,从而将 TLS 或 SSL 的安全功能添加到标准 HTTP 通信中。大多数 OpenStack API 端点和许多组件间通信都支持 HTTPS 通信。 + +虚拟机管理程序 + +仲裁和控制 VM 对实际底层硬件的访问的软件。 + +虚拟机管理程序池 + +通过主机聚合组合在一起的虚拟机管理程序的集合。 + +#### I + +Icehouse + +OpenStack 第九个版本的代号。设计峰会在香港举行,Ice House是该市的一条街道的名字。 + +身份证号码 + +与身份中的每个用户关联的唯一数字 ID,在概念上类似于 Linux 或 LDAP UID。 + +身份验证 API + +Identity 服务 API 的替代术语。 + +身份验证后端 + +Identity 服务用于检索用户信息的源;例如,OpenLDAP 服务器。 + +身份提供者 + +一种目录服务,允许用户使用用户名和密码登录。它是身份验证令牌的典型来源。 + +身份服务(keystone) + +促进 API 客户端身份验证、服务发现、分布式多项目授权和审计的项目。它提供了一个用户映射到他们可以访问的 OpenStack 服务的中央目录。它还为 OpenStack 服务注册端点,并充当通用身份验证系统。 + +身份服务 API + +用于访问通过 keystone 提供的 OpenStack Identity 服务的 API。 + +IETF (英语) + +Internet 工程任务组 (IETF) 是一个开放标准组织,负责制定 Internet 标准,尤其是与 TCP/IP 相关的标准。 + +映像 + +用于创建或重建服务器的特定操作系统 (OS) 的文件集合。OpenStack 提供预构建的映像。您还可以从已启动的服务器创建自定义映像或快照。自定义映像可用于数据备份,或用作其他服务器的“黄金”映像。 + +映像API + +用于管理 VM 映像的映像服务 API 终结点。处理客户端对 VM 的请求,更新注册表服务器上的映像服务元数据,并与存储适配器通信以从后端存储上传 VM 映像。 + +映像缓存 + +由图像服务用于获取本地主机上的图像,而不是在每次请求图像时从图像服务器重新下载图像。 + +映像 ID + +URI 和 UUID 的组合,用于通过镜像 API 访问镜像服务虚拟机镜像。 + +映像成员 + +可以在映像服务中访问给定 VM 映像的项目列表。 + +映像所有者 + +拥有镜像服务虚拟机镜像的项目。 + +映像注册表 + +可通过映像服务获取的 VM 映像的列表。 + +映像服务(glance) + +OpenStack 服务,它提供服务和关联的库来存储、浏览、共享、分发和管理可启动磁盘映像、与初始化计算资源密切相关的其他数据以及元数据定义。 + +映像状态 + +镜像服务中虚拟机镜像的当前状态,不要与正在运行的实例的状态混淆。 + +映像存储 + +映像服务用于存储虚拟机映像的后端存储,选项包括对象存储、本地挂载的文件系统、RADOS 块设备、VMware 数据存储或 HTTP。 + +映像 UUID + +映像服务用于唯一标识每个 VM 映像的 UUID。 + +孵化项目 + +社区项目可以提升到此状态,然后提升为核心项目 + +基础设施优化服务(观察者) + +OpenStack项目,旨在为基于OpenStack的多项目云提供灵活且可扩展的资源优化服务。 + +基础架构即服务 (IaaS) + +IaaS 是一种配置模型,在这种模型中,组织外包数据中心的物理组件,例如存储、硬件、服务器和网络组件。服务提供商拥有设备,并负责设备的安装、操作和维护。客户通常按使用量付费。IaaS 是一种提供云服务的模型。 + +Ingress 过滤 + +筛选传入网络流量的过程。由计算支持。 + +INI 格式 + +OpenStack 配置文件使用 INI 格式来描述选项及其值。它由部分和键值对组成。 + +注入 + +在启动实例之前将文件放入虚拟机映像的过程。 + +每秒输入/输出操作数 (IOPS) + +IOPS 是一种常见的性能度量,用于对计算机存储设备(如硬盘驱动器、固态驱动器和存储区域网络)进行基准测试。 + +实例 + +正在运行的 VM 或处于已知状态(如挂起)的 VM,可以像硬件服务器一样使用。 + +实例ID + +例如UUID的替代术语。 + +实例状态 + +来宾虚拟机映像的当前状态。 + +实例隧道网络 + +用于计算节点和网络节点之间的实例流量隧道的网段。 + + 实例类型 + +描述可供用户使用的各种虚拟机映像的参数;包括 CPU、存储和内存等参数。风味的替代术语。 + +实例类型 ID + +特定实例 ID 的替代术语。 + +实例 UUID + +分配给每个来宾 VM 实例的唯一 ID。 + +智能平台管理接口(IPMI) + +IPMI 是系统管理员用于计算机系统带外管理和监控其操作的标准化计算机系统接口。通俗地说,它是一种使用直接网络连接管理计算机的方法,无论它是否打开;连接到硬件,而不是操作系统或登录 shell。 + +接口 + +提供与其他设备或介质的连接的物理或虚拟设备。 + +接口 ID + +UUID 形式的网络 VIF 或 vNIC 的唯一 ID。 + +互联网控制消息协议 (ICMP) + +网络设备用于控制消息的网络协议。例如,ping 使用 ICMP 来测试连接。 + +互联网协议 (IP) + +Internet 协议套件中的主要通信协议,用于跨网络边界中继数据报。 + +互联网服务提供商 (ISP) + +任何向个人或企业提供互联网访问的企业。 + +互联网小型计算机系统接口(iSCSI) + +封装 SCSI 帧以通过 IP 网络传输的存储协议。受计算、对象存储和镜像服务支持。 + +IO + +输入和输出的缩写。 + +IP 地址 + +Internet 上每个计算机系统唯一的编号。地址使用了两个版本的 Internet 协议 (IP):IPv4 和 IPv6。 + +IP 地址管理 (IPAM) + +自动执行 IP 地址分配、解除分配和管理的过程。目前由 Compute、melange 和 Networking 提供。 + +ip6tables + +用于在 Linux 内核中设置、维护和检查 IPv6 数据包过滤规则表的工具。在 OpenStack 计算中,ip6tables 与 arptables、ebtables 和 iptables 一起使用,为节点和虚拟机创建防火墙。 + +ipset + +对 iptables 的扩展,允许创建同时匹配整个 IP 地址“集”的防火墙规则。这些集驻留在索引数据结构中以提高效率,尤其是在具有大量规则的系统上。 + +iptables + +iptables 与 arptables 和 ebtables 一起使用,可在 Compute 中创建防火墙。iptables 是 Linux 内核防火墙(作为不同的 Netfilter 模块实现)提供的表及其存储的链和规则。目前不同的内核模块和程序用于不同的协议:iptables 适用于 IPv4,ip6tables 适用于 IPv6,arptables 适用于 ARP,ebtables 用于以太网帧。需要 root 权限才能操作。 + +ironic + +裸机服务的代号。 + +iSCSI 限定名称 (IQN) + +IQN 是最常用的 iSCSI 名称格式,用于唯一标识 iSCSI 网络中的节点。所有 IQN 都遵循 iqn.yyyy-mm.domain:identifier 模式,其中“yyyy-mm”是域名注册的年份和月份,“domain”是颁发组织的反向域名,“identifier”是一个可选字符串,使同一域名下的每个 IQN 都是唯一的。例如,“iqn.2015-10.org.openstack.408ae959bce1”。 + +ISO9660 + +镜像服务支持的虚拟机镜像磁盘格式之一。 + +ITSEC 函数 + +计算 RBAC 系统中的默认角色,可以隔离任何项目中的实例。 + +#### J + +Java + +一种编程语言,用于创建通过网络涉及多台计算机的系统。 + +JavaScript + +一种用于生成网页的脚本语言。 + +JavaScript 对象表示法 (JSON) + +OpenStack 中支持的响应格式之一。 + +框架的形状 + +现代以太网网络中的功能,支持高达约 9000 字节的帧。 + +Juno + +OpenStack 第十版的代号。设计峰会在美国佐治亚州亚特兰大举行,Juno是佐治亚州的一个非法人社区。 + +#### K + +Kerberos + +一种基于票证的网络身份验证协议。Kerberos 允许节点通过非安全网络进行通信,并允许节点以安全的方式相互证明其身份。 + +基于内核的虚拟机 (KVM) + +支持 OpenStack 的虚拟机管理程序。KVM 是适用于 Linux on x86 硬件的完整虚拟化解决方案,包含虚拟化扩展(Intel VT 或 AMD-V)、ARM、IBM Power 和 IBM zSeries。它由一个可加载的内核模块组成,该模块提供核心虚拟化基础架构和特定于处理器的模块。 + +密钥管理器服务(barbican) + +该项目产生一个秘密存储和生成系统,能够为希望启用加密功能的服务提供密钥管理。 + +keystone + +Identity 服务的代号。 + +快速启动 + +用于在基于 Red Hat、Fedora 和 CentOS 的 Linux 发行版上自动进行系统配置和安装的工具。 + +Kilo + +OpenStack 第 11 版的代号。设计峰会在法国巴黎举行。由于名称选择的延迟,该版本仅被称为 K。由于 `k` kilo 是单位符号,而 kilogram 参考工件存放在巴黎附近的塞夫尔 Pavillon de Breteuil 中,因此社区选择了 Kilo 作为版本名称。 + +L + +大对象 + +Object Storage 中大于 5 GB 的对象。 + +启动板 + +OpenStack 的协作站点。 + + 二层(L2)代理 + +为虚拟网络提供第 2 层连接的 OpenStack Networking 代理。 + +二层网络 + +OSI 网络体系结构中用于数据链路层的术语。数据链路层负责媒体访问控制、流量控制以及检测和纠正物理层中可能发生的错误。 + +三层 (L3) 代理 + +OpenStack Networking 代理,为虚拟网络提供第 3 层(路由)服务。 + +三层网络 + +在 OSI 网络体系结构中用于网络层的术语。网络层负责数据包转发,包括从一个节点到另一个节点的路由。 + +Liberty + +OpenStack 第 12 版的代号。设计峰会在加拿大温哥华举行,Liberty是加拿大萨斯喀彻温省一个村庄的名字。 + +libvirt + +OpenStack 用来与许多受支持的虚拟机管理程序进行交互的虚拟化 API 库。 + +轻量级目录访问协议 (LDAP) + +用于通过 IP 网络访问和维护分布式目录信息服务的应用程序协议。 + +Linux 操作系统 + +类Unix计算机操作系统,在自由和开源软件开发和分发的模式下组装。 + +Linux桥接 + +使多个 VM 能够在计算中共享单个物理 NIC 的软件。 + +Linux Bridge neutron 插件 + +使 Linux 网桥能够理解网络端口、接口连接和其他抽象。 + +Linux 容器 (LXC) + +支持 OpenStack 的虚拟机管理程序。 + +实时迁移 + +计算中能够将正在运行的虚拟机实例从一台主机移动到另一台主机,在切换期间仅发生少量服务中断。 + +负载均衡器 + +负载均衡器是属于云帐户的逻辑设备。它用于根据定义为其配置一部分的条件在多个后端系统或服务之间分配工作负载。 + +负载均衡 + +在两个或多个节点之间分散客户端请求以提高性能和可用性的过程。 + +负载均衡器即服务(LBaaS) + +使网络能够在指定实例之间均匀分配传入请求。 + +负载均衡服务(octavia) + +该项目旨在以与技术无关的方式提供对负载均衡器服务的可扩展、按需、自助服务访问。 + +逻辑卷管理器 (LVM) + +提供一种在大容量存储设备上分配空间的方法,该方法比传统的分区方案更灵活。 + +#### M + +magnum + +容器基础结构管理服务的代号。 + +管理 API + +管理 API 的替代术语。 + +管理网络 + +用于管理的网段,公共 Internet 无法访问。 + +管理器 + +相关代码的逻辑分组,例如块存储卷管理器或网络管理器。 + +清单 + +用于跟踪对象存储中大型对象的段。 + +manifest 对象 + +一个特殊的对象存储对象,其中包含大型对象的清单。 + +manila + +OpenStack 共享文件系统服务的代号。 + +manila分享 + +负责管理共享文件系统服务设备,特别是后端设备。 + +最大传输单元 (MTU) + +特定网络介质的最大帧或数据包大小。以太网通常为 1500 字节。 + +机制驱动 程序 + +模块化第 2 层 (ML2) neutron 插件的驱动程序,为虚拟实例提供第 2 层连接。单个 OpenStack 安装可以使用多个机制驱动程序。 + +melange + +OpenStack Network Information Service 的项目名称。将与网络合并。 + +成员关系 + +镜像服务虚拟机镜像与项目之间的关联。允许与指定项目共享图像。 + +成员列表 + +可以在映像服务中访问给定 VM 映像的项目列表。 + +内存缓存 + +对象存储用于缓存的分布式内存对象缓存系统。 + +内存过量分配 + +能够根据主机的实际内存使用情况启动新的 VM 实例,而不是根据每个正在运行的实例认为其可用的 RAM 量来做出决定。也称为 RAM 过量使用。 + +消息代理 + +用于在计算中提供 AMQP 消息传递功能的软件包。默认包为 RabbitMQ。 + +消息总线 + +所有 AMQP 消息用于计算中的云间通信的主要虚拟通信线路。 + +消息队列 + +将来自客户端的请求传递给相应的工作线程,并在作业完成后将输出返回给客户端。 + +消息服务 (zaqar) + +该项目提供消息传递服务,该服务以高效、可扩展和高度可用的方式提供各种分布式应用程序模式,并创建和维护关联的 Python 库和文档。 + +元数据服务器 (MDS) + +存储 CephFS 元数据。 + +元数据代理 + +为实例提供元数据服务的 OpenStack Networking 代理。 + +迁移 + +将 VM 实例从一台主机移动到另一台主机的过程。 + +mistral + +工作流服务的代号。 + +Mitaka + +OpenStack 第 13 版的代号。设计峰会在日本东京举行。Mitaka是东京的一座城市。 + +模块化第 2 层 (ML2)neutron插件 + +可以在网络中同时使用多种二层网络技术,如802.1Q和VXLAN。 + +monasca + +OpenStack 监控的代号。 + +监控 (LBaaS) + +LBaaS 功能,使用 `ping` 命令、TCP 和 HTTP/HTTPS GET 提供可用性监控。 + +监视器 (Mon) + +一个 Ceph 组件,用于与外部客户端通信、检查数据状态和一致性以及执行仲裁功能。 + +监控 (monasca) + +OpenStack 服务,为指标、复杂事件处理和日志记录提供多项目、高度可扩展、高性能、容错的监控即服务解决方案。为高级监控服务构建一个可扩展的平台,运营商和项目都可以使用该平台来获得运营洞察力和可见性,确保可用性和稳定性。 + +多云计算 + +在单个网络架构中使用多种云计算和存储服务。 + +多云 SDK + +提供多云抽象层并包含对 OpenStack 的支持的 SDK。这些 SDK 非常适合编写需要使用多种类型的云提供商的应用程序,但可能会公开一组更有限的功能。 + +多因素身份验证 + +使用两个或多个凭据(如密码和私钥)的身份验证方法。目前在 Identity 中不受支持。 + +多主机 + +传统 (nova) 网络的高可用性模式。每个计算节点处理 NAT 和 DHCP,并充当其上所有 VM 的网关。一个计算节点上的网络故障不会影响其他计算节点上的 VM。 + +multinic 函数 + +计算中的工具,允许每个虚拟机实例连接多个 VIF。 + +murano + +应用程序目录服务的代号。 + +#### N + +Nebula + +NASA 于 2010 年以开源形式发布,是 Compute 的基础。 + +网络管理员 + +计算 RBAC 系统中的默认角色之一。允许用户为实例分配可公开访问的 IP 地址并更改防火墙规则。 + +NetApp 卷驱动程序 + +使计算能够通过 NetApp OnCommand 配置管理器与 NetApp 存储设备进行通信。 + +网络 + +在实体之间提供连接的虚拟网络。例如,共享网络连接的虚拟端口的集合。在网络术语中,网络始终是第 2 层网络。 + +网络地址转换 (NAT) + +在传输过程中修改 IP 地址信息的过程。由计算和网络支持。 + +网络控制器 + +一个计算守护程序,用于协调节点的网络配置,包括 IP 地址、VLAN 和桥接。还管理公共网络和专用网络的路由。 + +网络文件系统 (NFS) + +一种使文件系统在网络上可用的方法。由 OpenStack 支持。 + +网络 ID + +分配给网络中每个网段的唯一 ID。与网络 UUID 相同。 + +网络管理器 + +用于管理各种网络组件(如防火墙规则、IP 地址分配等)的计算组件。 + +网络命名空间 + +Linux 内核功能,在单个主机上提供独立的虚拟网络实例,具有单独的路由表和接口。类似于物理网络设备上的虚拟路由和转发 (VRF) 服务。 + +网络节点 + +运行 Network Worker 守护程序的任何计算节点。 + +网络段 + +表示网络中虚拟的隔离 OSI 第 2 层子网。 + +网络服务标头 (NSH) + +提供沿实例化服务路径进行元数据交换的机制。 + +网络时间协议 (NTP) + +通过与可信、准确的时间源通信来保持主机或节点时钟正确的方法。 + +网络 UUID + +网络网段的唯一 ID。 + +网络工作进程 + +`nova-network` worker 守护进程;提供诸如为启动的 nova 实例提供 IP 地址等服务。 + +网络 API(Neutron API) + +用于访问 OpenStack Networking 的 API。提供可扩展的体系结构以启用自定义插件创建。 + +网络服务(neutron) + +OpenStack 项目,它实现了服务和相关库,以提供按需、可扩展且与技术无关的网络抽象。 + +neutron + +OpenStack Networking 服务的代号。 + +neutron API + +网络 API 的替代名称。 + +Neutron 管理器 + +启用计算和网络集成,使网络能够对来宾 VM 执行网络管理。 + +Neutron 插件 + +网络中的接口,使组织能够为高级功能(如 QoS、ACL 或 IDS)创建自定义插件。 + +Newton + +OpenStack 第 14 版的代号。设计峰会在美国德克萨斯州奥斯汀举行。该版本以位于德克萨斯州奥斯汀市第九街 1013 号的“Newton House”命名。被列入国家史迹名录。 + +Nexenta 卷驱动程序 + +为计算中的 NexentaStor 设备提供支持。 + +NFV 编排服务(tacker) + +OpenStack 服务,旨在实现网络功能虚拟化 (NFV) 编排服务和库,用于网络服务和虚拟网络功能 (VNF) 的端到端生命周期管理。 + +Nginx 函数 + +HTTP 和反向代理服务器、邮件代理服务器和通用 TCP/UDP 代理服务器。 + +无 ACK + +在 Compute RabbitMQ 中禁用服务器端消息确认。提高性能但降低可靠性。 + +节点 + +在主机上运行的 VM 实例。 + +非持久交换 + +服务重新启动时清除的消息交换。其数据不会写入持久性存储。 + +非持久队列 + +服务重新启动时清除的消息队列。其数据不会写入持久性存储。 + +非持久化卷 + +临时卷的替代术语。 + +南北向流量 + +用户或客户端(北)与服务器(南)之间的网络流量,或进入云(南)和云外(北)的流量。另请参阅东西向流量。 + +nova + +OpenStack 计算服务的代号。 + +Nova API 接口 + +计算 API 的替代术语。 + +nova-network (新星网络) + +一个计算组件,用于管理 IP 地址分配、防火墙和其他与网络相关的任务。这是旧版网络选项,也是网络的替代方法。 + +#### O + +对象 + +对象存储保存的数据的 BLOB;可以是任何格式。 + +对象审计器 + +打开对象服务器的所有对象,并验证每个对象的 MD5 哈希、大小和元数据。 + +对象过期 + +Object Storage 中的一个可配置选项,用于在经过指定时间或达到特定日期后自动删除对象。 + +对象哈希 + +对象存储对象的唯一 ID。 + +对象路径哈希 + +对象存储用于确定对象在环中的位置。将对象映射到分区。 + +对象复制器 + +一个对象存储组件,用于将对象复制到远程分区以实现容错。 + +对象服务器 + +负责管理对象的对象存储组件。 + +对象存储 API + +用于访问 OpenStack 对象存储的 API。 + +对象存储设备 (OSD) + +Ceph 存储守护进程。 + +对象存储服务(swift) + +OpenStack 核心项目,为固定数字内容提供最终一致性和冗余的存储和检索。 + +对象版本控制 + +允许用户在对象存储容器上设置标志,以便对容器内的所有对象进行版本控制。 + +Ocata + +OpenStack 第 15 版的代号。设计峰会在西班牙巴塞罗那举行。Ocata是巴塞罗那北部的一个海滩。 + +Octavia + +负载平衡服务的代号。 + +Oldie + +长时间运行的对象存储进程的术语。可以指示挂起的进程。 + +开放云计算接口(OCCI) + +用于管理计算、数据和网络资源的标准化接口,目前在 OpenStack 中不受支持。 + +开放虚拟化格式 (OVF) + +打包 VM 映像的标准。在 OpenStack 中受支持。 + +打开 vSwitch + +Open vSwitch 是在开源 Apache 2.0 许可证下获得许可的生产质量的多层虚拟交换机。它旨在通过编程扩展实现大规模网络自动化,同时仍支持标准管理接口和协议(例如 NetFlow、sFlow、SPAN、RSPAN、CLI、LACP、802.1ag)。 + +Open vSwitch(OVS)代理 + +为网络插件提供底层 Open vSwitch 服务的接口。 + +打开 vSwitch neutron 插件 + +在网络中提供对 Open vSwitch 的支持。 + +OpenDev + +OpenDev 是一个协作开源软件开发的空间。 + +OpenDev 的使命是为开源软件项目提供项目托管、持续集成工具和虚拟协作空间。OpenDev 本身是自托管在这套工具上,包括代码审查、持续集成、etherpad、wiki、代码浏览等。这意味着 OpenDev 本身就像一个开源项目一样运行,您可以加入我们并帮助运行系统。此外,运行的所有服务本身都是开源软件。 + +OpenStack 项目是使用 OpenDev 的最大项目。 + +OpenLDAP + +开源 LDAP 服务器。受计算和标识支持。 + +OpenStack + +OpenStack 是一个云操作系统,可控制整个数据中心的大型计算、存储和网络资源池,所有这些资源都通过仪表板进行管理,该仪表板使管理员能够进行控制,同时授权用户通过 Web 界面配置资源。OpenStack 是一个根据 Apache License 2.0 许可的开源项目。 + +OpenStack 代码名称 + +每个 OpenStack 版本都有一个代号。代号按字母顺序排列:Austin, Bexar, Cactus, Diablo, Essex, Folsom, Grizzly, Havana, Icehouse, Juno, Kilo, Liberty, Mitaka, Newton, Ocata, Pike, Queens, Rocky, Stein, Train, Ussuri, Victoria, Wallaby, Xena, Yoga, Zed。 + +Wallaby 是新策略选择的第一个代号:代号由社区按照字母顺序选择,有关详细信息,请参阅发布名称标准。 + +维多利亚的名字是姓氏,其中代号是靠近相应OpenStack设计峰会举办地的城市或县。一个例外,称为沃尔登例外,被授予州旗中听起来特别酷的元素。代号由大众投票选出。 + +与此同时,随着OpenStack发行版的字母表用完,技术委员会改变了命名过程,将发行号和发行版名称作为识别码。版本号将是主要标识符:“year”。年内发布计数“,该名称将主要用于营销目的。第一个这样的版本是 2023.1 Antelope。紧随其后的是 2023.2 Bobcat、2024.1 Caracal。 + +openSUSE + +与 OpenStack 兼容的 Linux 发行版。 + +操作员 + +负责规划和维护 OpenStack 安装的人员。 + +可选服务 + +由 Interop 工作组定义为可选的官方 OpenStack 服务。目前,由 Dashboard (horizon)、Telemetry 服务 (Telemetry)、Orchestration 服务 (heat)、Database 服务 (trove)、Bare Metal 服务 (ironic) 等组成。 + +编排服务(heat) + +OpenStack 服务,它通过 OpenStack 原生 REST API 使用声明性模板格式编排复合云应用程序。 + +orphan + +在对象存储的上下文中,这是一个在升级、重新启动或重新加载服务后不会终止的过程。 + +Oslo + +Common Libraries 项目的代号。 + +#### P + +panko + +OpenStack Telemetry 服务的一部分;提供事件存储。 + +父单元格 + +如果请求的资源(如 CPU 时间、磁盘存储或内存)在父单元中不可用,则该请求将转发到关联的子单元。 + +分区 + +对象存储中用于存储对象的存储单元。它存在于设备之上,并被复制以实现容错。. + +分区索引 + +包含环内所有对象存储分区的位置。 + +分区偏移值 + +对象存储用于确定数据应驻留在哪个分区上。 + +路径 MTU 发现 (PMTUD) + +IP 网络中用于检测端到端 MTU 并相应地调整数据包大小的机制。 + +暂停 + +未发生任何更改(内存未更改、网络通信停止等)的 VM 状态;VM 已冻结,但未关闭。 + +PCI直通 + +为客户机虚拟机提供对 PCI 设备的独占访问权限。目前在 OpenStack Havana 及更高版本中受支持。 + +持久消息 + +存储在内存和磁盘上的消息。失败或重新启动后,消息不会丢失。 + +持久卷 + +将保存对这些类型的磁盘卷所做的更改。 + +个性文件 + +用于自定义 Compute 实例的文件。它可用于注入 SSH 密钥或特定的网络配置。 + +Pike + +OpenStack 第 16 版的代号。OpenStack峰会在美国马萨诸塞州波士顿举行。该版本以马萨诸塞州收费公路命名,通常缩写为马萨诸塞州收费公路,这是 90 号州际公路最东端的路段。 + +平台即服务(PaaS) + +为使用者提供操作系统,通常还为语言运行时和库(统称为“平台”)提供,消费者可以在其上运行自己的应用程序代码,而无需提供对底层基础结构的任何控制。平台即服务提供商的示例包括 Cloud Foundry 和 OpenShift。 + +插件 + +为网络 API 或计算 API 提供实际实现的软件组件,具体取决于上下文。 + +策略服务 + +标识组件,提供规则管理接口和基于规则的授权引擎。 + +基于策略的路由 (PBR) + +提供一种机制,用于根据网络管理员定义的策略实现数据包转发和路由。 + +池 + +一组逻辑设备,例如 Web 服务器,您可以将其组合在一起以接收和处理流量。负载平衡功能选择池中的哪个成员处理在 VIP 地址上收到的新请求或连接。每个VIP都有一个游泳池。 + +池成员 + +在负载平衡系统中的后端服务器上运行的应用程序。 + +端口 + +网络中的虚拟网络端口;VIF / vNIC 连接到端口。 + +端口 UUID + +网络端口的唯一 ID。 + +预置 + +在基于 Debian 的 Linux 发行版上自动进行系统配置和安装的工具。 + +私有云 + +一个企业或组织独占使用的计算资源。 + +私有映像 + +仅对指定项目可用的映像服务虚拟机映像。 + +私有 IP 地址 + +用于管理和管理的 IP 地址,不可用于公共 Internet。 + +专用网络 + +网络控制器提供虚拟网络,使计算服务器能够相互交互以及与公用网络交互。所有计算机都必须具有公共和专用网络接口。专用网络接口可以是平面网络接口,也可以是 VLAN 网络接口。扁平化网络接口由具有扁平化管理器的flat_interface控制。VLAN 网络接口由带有 VLAN 管理器的 `vlan_interface` 选件控制。 + +项目 + +项目代表了OpenStack中“所有权”的基本单位,因为OpenStack中的所有资源都应该由特定项目拥有。在 OpenStack Identity 中,项目必须由特定域拥有。 + +项目 ID + +Identity 服务分配给每个项目的唯一 ID。 + +项目 VPN + +cloudpipe 的替代术语。 + +混杂模式 + +使网络接口将其接收的所有流量传递到主机,而不是仅传递寻址到它的帧。 + +受保护的属性 + +通常,只有云管理员才能访问的映像服务映像上的额外属性。限制哪些用户角色可以对该属性执行 CRUD 操作。云管理员可以将任何映像属性配置为受保护。 + +提供者 + +有权访问所有主机和实例的管理员。 + +代理节点 + +提供Object Storage代理服务的节点。 + +代理服务器 + +对象存储的用户通过代理服务器与服务进行交互,代理服务器又在环内查找所请求数据的位置,并将结果返回给用户。 + +公共 API + +用于服务到服务通信和最终用户交互的 API 终结点。 + +公有云 + +许多用户可通过 Internet 访问的数据中心。 + +公共镜像 + +可供所有项目使用的镜像服务虚拟机镜像。 + +公网 IP 地址 + +最终用户可访问的 IP 地址。 + +公钥认证 + +使用密钥而不是密码的身份验证方法。 + +公网 + +网络控制器提供虚拟网络,使计算服务器能够相互交互以及与公用网络交互。所有计算机都必须具有公共和专用网络接口。公用网络接口由该 `public_interface` 选项控制。 + +Puppet + +OpenStack支持的操作系统配置管理工具。 + +Python 模型 + +OpenStack中广泛使用的编程语言。 + +#### Q + +QEMU 写入时复制 2 (QCOW2) + +镜像服务支持的虚拟机镜像磁盘格式之一。 + +Qpid + +penStack支持的消息队列软件;RabbitMQ 的替代品。 + +服务质量 (QoS) + +保证某些网络或存储要求以满足应用程序提供商和最终用户之间的服务级别协议 (SLA) 的能力。通常包括网络带宽、延迟、抖动校正和可靠性等性能要求,以及每秒输入/输出操作数 (IOPS) 中的存储性能、限制协议和峰值负载下的性能预期。 + +隔离 + +如果对象存储发现对象、容器或帐户已损坏,则会将其置于此状态,不会被复制,客户端无法读取,并且会重新复制正确的副本。 + +Queens + +OpenStack 第 17 版的代号。OpenStack峰会在澳大利亚悉尼举行。该版本以新南威尔士州南海岸地区的皇后庞德河命名。 + +Quick EMUlator (QEMU) (快速 EMUlator) + +QEMU 是一个通用的开源机器仿真器和虚拟化器。OpenStack 支持的虚拟机管理程序之一,通常用于开发目的。 + +配额 + +在计算和块存储中,能够基于每个项目设置资源限制。 + +#### R + +RabbitMQ 模型 + +OpenStack 使用的默认消息队列软件。 + +Rackspace 云文件 + +2010 年由 Rackspace 开源发布;对象存储的基础。 + +RADOS 块设备 (RBD) + +Ceph 组件,使 Linux 块设备能够在多个分布式数据存储上进行条带化。 + +radvd + +路由器通告守护程序,由计算 VLAN 管理器和 FlatDHCP 管理器用于为 VM 实例提供路由服务。 + +rally + +Benchmark 服务的代号。 + +RAM过滤器 + +启用或禁用 RAM 过量分配的计算设置。 + +RAM 过量分配 + +能够根据主机的实际内存使用情况启动新的 VM 实例,而不是根据每个正在运行的实例认为其可用的 RAM 量来做出决定。也称为内存过量使用。 + +速率限制 + +对象存储中的可配置选项,用于限制每个帐户和/或每个容器的数据库写入。 + +原始 + +映像服务支持的虚拟机映像磁盘格式之一;非结构化磁盘映像。 + +重新平衡 + +在环中的所有驱动器之间分配对象存储分区的过程;在初始环创建期间和环重新配置后使用。 + +重启 + +对服务器进行软重启或硬重启。通过软重启,操作系统会发出重新启动信号,从而可以正常关闭所有进程。硬重启相当于重启服务器。虚拟化平台应确保重新启动操作已成功完成,即使在基础域/VM 暂停或停止/停止的情况下也是如此。 + +重建 + +删除服务器上的所有数据,并将其替换为指定的映像。服务器 ID 和 IP 地址保持不变。 + +侦察 + +用于收集计量的对象存储组件。 + +记录 + +属于特定域,用于指定有关该域的信息。有几种类型的 DNS 记录。每种记录类型都包含用于描述该记录用途的特定信息。示例包括邮件交换 (MX) 记录,它指定特定域的邮件服务器;和名称服务器 (NS) 记录,用于指定域的权威名称服务器。 + +记录 ID + +数据库中的一个数字,每次进行更改时都会递增。对象存储在复制时使用。 + +Red Hat Enterprise Linux (RHEL) (英语) + +与 OpenStack 兼容的 Linux 发行版。 + +参考架构 + +OpenStack 云的推荐架构。 + +区域 + +具有专用 API 端点的离散 OpenStack 环境,通常仅与其他区域共享身份 (keystone)。 + +注册表 + +影像服务注册表的替代术语。 + +注册表服务器 + +向客户端提供虚拟机镜像元数据信息的镜像服务。 + +可靠、自主的分布式对象存储 + +(雷达) + +在 Ceph 中提供对象存储的组件集合。类似于 OpenStack Object Storage。 + +远程过程调用 (RPC) + +计算RabbitMQ 用于服务内通信的方法。 + +副本 + +通过创建对象存储对象、帐户和容器的副本来提供数据冗余和容错,以便在底层存储发生故障时不会丢失它们。 + +副本数量 + +对象存储环中数据的副本数。 + +复制 + +将数据复制到单独的物理设备以实现容错和性能的过程。 + +复制器 + +对象存储后端进程,用于创建和管理对象副本。 + +请求 ID + +分配给发送到计算的每个请求的唯一 ID。 + +救援映像 + +一种特殊类型的 VM 映像,在将实例置于救援模式时启动。允许管理员挂载实例的文件系统以更正问题。 + +调整大小 + +将现有服务器转换为其他风格,从而扩展或缩减服务器。保存原始服务器以在出现问题时启用回滚。必须测试并明确确认所有调整大小,此时将删除原始服务器。 + +RESTful + +一种使用 REST 或具象状态传输的 Web 服务 API。REST是用于万维网的超媒体系统的架构风格 + +环 + +将对象存储数据映射到分区的实体。每个服务(例如帐户、对象和容器)都存在一个单独的环。 + +环构建器 + +在对象存储中构建和管理环,为设备分配分区,并将配置推送到其他存储节点。 + +Rocky + +OpenStack 第 18 版的代号。OpenStack峰会在加拿大温哥华举行。该版本以落基山脉命名。 + +角色 + +用户为执行一组特定操作而假定的个性。角色包括一组权限和特权。担任该角色的用户将继承这些权利和特权。 + +基于角色的访问控制 (RBAC) + +提供用户可以执行的操作的预定义列表,例如启动或停止 VM、重置密码等。在标识和计算中均受支持,可以使用仪表板进行配置。 + +角色 ID + +分配给每个身份服务角色的字母数字 ID。 + +根本原因分析(RCA)服务(Vitrage) + +OpenStack项目旨在组织、分析和可视化OpenStack警报和事件,深入了解问题的根本原因,并在直接检测到问题之前推断出它们的存在。 + +rootwrap + +计算的一项功能,允许非特权“nova”用户以 Linux root 用户身份运行指定的命令列表。 + +循环调度器 + +在可用主机之间均匀分配实例的计算计划程序的类型。 + +路由器 + +在不同网络之间传递网络流量的物理或虚拟网络设备。 + +路由密钥 + +计算直接交换、扇出交换和主题交换使用此密钥来确定如何处理消息;处理方式因 Exchange 类型而异。 + +RPC 驱动程序 + +模块化系统,允许更改 Compute 的底层消息队列软件。例如,从 RabbitMQ 到 ZeroMQ 或 Qpid。 + +rsync + +由对象存储用于推送对象副本。 + +RXTX 限 制 + +计算 VM 实例可以发送和接收的网络流量的绝对限制。 + +RXTX 配额 + +对计算 VM 实例可以发送和接收的网络流量的软限制。 + +#### S + +sahara + +数据处理服务的代号。 + +SAML 断言 + +包含标识提供者提供的有关用户的信息。这表示用户已通过身份验证。 + +沙盒 + +一个虚拟空间,可以在其中安全地运行新的或未经测试的软件。 + +调度器管理器 + +一个计算组件,用于确定 VM 实例的启动位置。采用模块化设计,支持多种调度程序类型。 + +作用域令牌 + +与特定项目关联的身份服务 API 访问令牌。 + +洗涤器 + +检查并删除未使用的虚拟机;实现延迟删除的影像服务组件。 + +密钥 + +只有用户知道的文本字符串;与访问密钥一起使用,以向计算 API 发出请求。 + +安全启动 + +系统固件验证启动过程中涉及的代码的真实性的过程。 + +安全外壳 (SSH) + +用于通过加密通信通道访问远程主机的开源工具,计算支持 SSH 密钥注入。 + +安全组 + +应用于计算实例的一组网络流量筛选规则。 + +分段对象 + +已分解为多个部分的对象存储大型对象。重新组合的对象称为串联对象。 + +自助服务 + +对于 IaaS,常规(非特权)帐户能够在不涉及管理员的情况下管理虚拟基础架构组件(如网络)。 + +SELinux 函数 + +Linux 内核安全模块,提供用于支持访问控制策略的机制。 + +senlin + +群集服务的代码名称。 + +服务器 + +为该系统上运行的客户端软件提供显式服务的计算机,通常管理各种计算机操作。服务器是计算系统中的 VM 实例。风格和图像是创建服务器时的必要元素。 + +服务器映像 + +VM 映像的替代术语。 + +服务器 UUID + +分配给每个来宾 VM 实例的唯一 ID。 + +服务 + +OpenStack 服务,例如计算、对象存储或映像服务。提供一个或多个端点,用户可以通过这些端点访问资源和执行操作。 + +服务目录 + +Identity 服务目录的替代术语。 + +服务功能链 (SFC) + +对于给定的服务,SFC 是所需服务功能及其应用顺序的抽象视图。 + +服务 ID + +分配给 Identity 服务目录中可用的每个服务的唯一 ID。 + +服务水平协议 (SLA) + +确保服务可用性的合同义务。 + +服务项目 + +包含目录中列出的所有服务的特殊项目。 + +服务提供者 + +向其他系统实体提供服务的系统。在联合身份的情况下,OpenStack 身份是服务提供者。 + +服务注册 + +一种身份服务功能,使服务(如计算)能够自动注册到目录。 + +服务令牌 + +管理员定义的令牌,由计算用于与身份服务进行安全通信。 + +会话后端 + +Horizon 用于跟踪客户端会话的存储方法,例如本地内存、Cookie、数据库或 memcached。 + +会话持久化 + +负载平衡服务的一项功能。只要某个服务处于联机状态,它就会尝试强制将服务的后续连接重定向到同一节点。 + +会话存储 + +用于存储和跟踪客户端会话信息的 Horizon 组件。通过 Django 会话框架实现。 + +共享 + +共享文件系统服务上下文中的远程可挂载文件系统。您可以一次将共享装载到多个主机,也可以由多个用户从多个主机访问共享。 + +共享网络 + +共享文件系统服务上下文中的实体,用于封装与网络服务的交互。如果所选驱动程序在需要此类交互的模式下运行,则需要指定共享网络以创建共享。 + +共享文件系统 API + +提供稳定 RESTful API 的共享文件系统服务。该服务在整个共享文件系统服务中对请求进行身份验证和路由。有 python-manilaclient 可以与 API 交互。 + +共享文件系统服务(manila) + +该服务提供一组服务,用于管理多项目云环境中的共享文件系统,类似于 OpenStack 通过 OpenStack Block Storage 服务项目提供基于块的存储管理。使用共享文件系统服务,您可以创建远程文件系统并将文件系统挂载到您的实例上。您还可以在文件系统中读取和写入实例中的数据。 + +共享 IP 地址 + +可分配给共享 IP 组中的 VM 实例的 IP 地址。公共 IP 地址可以在多个服务器之间共享,以便在各种高可用性方案中使用。当 IP 地址共享到另一台服务器时,将修改云网络限制,使每个服务器都能侦听和响应该 IP 地址。您可以选择指定修改目标服务器网络配置。共享 IP 地址可以与许多标准检测信号工具(如 keepalive)一起使用,这些工具可监视故障并管理 IP 故障转移。 + +共享 IP 组 + +可以与组的其他成员共享 IP 的服务器集合。组中的任何服务器都可以与组中的任何其他服务器共享一个或多个公共 IP。除了共享 IP 组中的第一台服务器外,服务器必须启动到共享 IP 组中。一台服务器只能是一个共享 IP 组的成员。 + +共享存储 + +可由多个客户端同时访问的块存储,例如 NFS。 + +Sheepdog + +面向 QEMU 的分布式块存储系统,由 OpenStack 提供支持。 + +简单云身份管理 (SCIM) + +用于在云中管理身份的规范,目前不受 OpenStack 支持。 + +独立计算环境的简单协议 (SPICE) + +SPICE 提供对客户机虚拟机的远程桌面访问。它是 VNC 的替代品。OpenStack支持SPICE。 + +单根 I/O 虚拟化 (SR-IOV) + +当由物理 PCIe 设备实现时,该规范使其能够显示为多个单独的 PCIe 设备。这使多个虚拟化客户机能够共享对物理设备的直接访问,从而提供比等效虚拟设备更高的性能。目前在 OpenStack Havana 及更高版本中受支持。 + +SmokeStack + +针对核心 OpenStack API 运行自动化测试;用 Rails 编写。 + +快照 + +OpenStack 存储卷或映像的时间点副本。使用存储卷快照备份卷。使用映像快照来备份数据,或作为其他服务器的“黄金”映像。 + +软重启 + +通过操作系统命令正确重启 VM 实例的受控重启。 + +软件开发工具包 (SDK) + +包含代码、示例和文档,您可以使用这些代码、示例和文档以所选语言创建应用程序。 + +软件开发生命周期自动化服务(solum) + +OpenStack项目,旨在通过自动化从源到映像的过程,并简化以应用程序为中心的部署,使云服务更易于使用并与应用程序开发过程集成。 + +软件定义网络 (SDN) + +为网络管理员提供一种方法,通过抽象较低级别的功能来管理计算机网络服务。 + +SolidFire 卷驱动程序 + +SolidFire iSCSI 存储设备的块存储驱动程序。 + +solum + +软件开发生命周期自动化服务的代号。 + +点差优先调度器 + +计算 VM 计划算法,尝试以最小的负载在主机上启动新 VM。 + +SQLAlchemy + +用于 Python 的开源 SQL 工具包,用于 OpenStack。 + +SQLite + +一个轻量级的 SQL 数据库,在许多 OpenStack 服务中用作默认的持久化存储方法。 + +堆栈 + +由编排服务根据给定模板(AWS CloudFormation 模板或 Heat 编排模板 (HOT))创建和管理的一组 OpenStack 资源。 + +StackTach + +捕获计算 AMQP 通信的社区项目;对调试很有用。 + +静态 IP 地址 + +固定 IP 地址的替代术语。 + +静态网页 + +对象存储的 WSGI 中间件组件,将容器数据作为静态网页提供。 + +Stein + +OpenStack 第 19 版的代号。OpenStack峰会在德国柏林举行。该版本以柏林的 Steinstraße 街命名。 + +存储后端 + +服务用于持久性存储的方法,例如 iSCSI、NFS 或本地磁盘。 + +存储管理器 + +一个 XenAPI 组件,它提供可插入接口以支持各种持久性存储后端。 + +存储管理器后端 + +XenAPI 支持的持久性存储方法,例如 iSCSI 或 NFS。 + +存储节点 + +提供容器服务、账户服务和对象服务的对象存储节点;控制帐户数据库、容器数据库和对象存储。 + +存储服务 + +提供容器服务、账户服务和对象服务的对象存储节点;控制帐户数据库、容器数据库和对象存储。 + +存储服务 + +对象存储对象服务、容器服务和帐户服务的集合名称。 + +策略 + +指定镜像服务或身份使用的认证源。在数据库服务中,它是指为数据存储实现的扩展。 + +子域 + +父域中的域。无法注册子域。子域使您能够委派域。子域本身可以有子域,因此可以进行三级、四级、五级和更深级别的嵌套。 + +子网 + +IP 网络的逻辑细分。 + +SUSE Linux Enterprise Server (SLES) (英语) + +与 OpenStack 兼容的 Linux 发行版。 + +挂起 + +虚拟机实例将暂停,其状态将保存到主机的磁盘中。 + +交换 + +操作系统使用的基于磁盘的虚拟内存,用于提供比系统上实际可用的内存更多的内存。 + +swift + +OpenStack 对象存储服务的代号。 + +swift 多合一 (SAIO) + +Swift 中间件 + +提供附加功能的对象存储组件的统称。 + +Swift 代理服务器 + +充当对象存储的网守,并负责对用户进行身份验证。 + +Swift 存储节点 + +运行对象存储帐户、容器和对象服务的节点。 + +同步点 + +自上次容器和帐户数据库在对象存储中的节点之间同步以来的时间点。 + +系统管理员 + +计算 RBAC 系统中的默认角色之一。使用户能够将其他用户添加到项目中,与与项目关联的 VM 映像进行交互,以及启动和停止 VM 实例。 + +系统使用情况 + +一个计算组件,它与通知系统一起收集计量和使用情况信息。此信息可用于计费。 + +#### T + +Tacker + +NFV 编排服务的代码名称 + +遥测服务(telemetry) + +OpenStack项目收集包含已部署云的物理和虚拟资源利用率的测量值,保留此数据以供后续检索和分析,并在满足定义的条件时触发操作。 + +TempAuth 函数 + +Object Storage中的一种身份验证工具,使Object Storage本身能够执行身份验证和授权。经常用于测试和开发。 + +Tempest + +自动化软件测试套件,旨在针对 OpenStack 核心项目的主干运行。 + +TempURL + +一个对象存储中间件组件,用于创建用于临时对象访问的 URL。 + +租户 + +一组用户;用于隔离对计算资源的访问。项目的替代术语。 + +租户 API + +项目可访问的 API。 + +租户端点 + +与一个或多个项目关联的身份服务 API 端点。 + +租户 ID + +项目 ID 的替代术语。 + +令牌 + +用于访问 OpenStack API 和资源的字母数字文本字符串。 + +令牌服务 + +一个身份服务组件,用于在用户或项目通过身份验证后管理和验证令牌。 + +逻辑删除 + +用于标记已删除的对象存储对象;确保对象在删除后不会在另一个节点上更新。 + +主题发布者 + +执行 RPC 调用时创建的进程;用于将消息推送到主题交换。 + +Torpedo + +用于针对 OpenStack API 运行自动化测试的社区项目。 + +Train + +OpenStack 第 20 版的代号。OpenStack 基础架构峰会在美国科罗拉多州丹佛市举行。 + +丹佛的两次项目团队聚会会议在从市中心到机场的火车线旁边的一家酒店举行。那里的交叉信号灯过去曾出现过某种故障,导致它们在火车正常驶来时没有停下车厢。因此,火车在经过该地区时必须鸣喇叭。显然,住在酒店里,乘坐火车24/7吹喇叭,不太理想。结果,出现了许多关于丹佛和火车的笑话——因此这个版本被称为火车。 + +交易 ID + +分配给每个对象存储请求的唯一 ID;用于调试和跟踪。 + +瞬态 + +非耐用品的替代术语。 + +瞬态交换 + +非持久交换的替代术语。 + +瞬态消息 + +存储在内存中并在服务器重新启动后丢失的消息。 + +瞬态队列 + +非持久队列的替代术语。 + +TripleO + +OpenStack-on-OpenStack 程序。OpenStack Deployment 程序的代号。 + +Trove + +OpenStack 数据库服务的代号。 + +可信平台模块(TPM) + +专用微处理器,用于将加密密钥整合到设备中,以验证和保护硬件平台。 + +#### U + +Ubuntu + +基于 Debian 的 Linux 发行版。 + +无作用域令牌 + +Identity 服务默认令牌的替代术语。 + +更新器 + +一组对象存储组件的统称,用于处理容器和对象的排队和失败的更新。 + +用户 + +在 OpenStack Identity 中,实体代表单个 API 使用者,并由特定域拥有。在 OpenStack 计算中,用户可以与角色和/或项目相关联。 + +用户数据 + +用户在启动实例时可以指定的数据 Blob。实例可以通过元数据服务或配置驱动器访问此数据。通常用于传递实例在启动时运行的 shell 脚本。 + +用户模式 Linux (UML) + +支持 OpenStack 的虚拟机管理程序。 + +Ussuri + +OpenStack 第 21 版的代号。OpenStack基础设施峰会在中华人民共和国上海举行。该版本以乌苏里河命名。 + +#### V + +Victoria + +OpenStack 第 22 版的代号。OpenDev + PTG 计划在加拿大不列颠哥伦比亚省温哥华举行。该版本以不列颠哥伦比亚省首府维多利亚命名。 + +由于 COVID-19,现场活动被取消。该事件正在虚拟化。 + +VIF UUID + +分配给每个网络 VIF 的唯一 ID。 + +虚拟中央处理器 (vCPU) + +细分物理 CPU。然后,实例可以使用这些分区。 + +虚拟磁盘映像 (VDI) + +映像服务支持的虚拟机映像磁盘格式之一。 + +虚拟可扩展局域网 (VXLAN) + +一种网络虚拟化技术,试图减少与大型云计算部署相关的可伸缩性问题。它使用类似 VLAN 的封装技术将以太网帧封装在 UDP 数据包中。 + +虚拟硬盘 (VHD) + +镜像服务支持的虚拟机镜像磁盘格式之一。 + +虚拟 IP 地址 (VIP) + +在负载平衡器上配置的 Internet 协议 (IP) 地址,供连接到负载平衡服务的客户端使用。传入连接将根据负载均衡器的配置分发到后端节点。 + +虚拟机 (VM) + +在虚拟机监控程序上运行的操作系统实例。多个 VM 可以在同一物理主机上同时运行。 + +虚拟网络 + +网络中的 L2 网段。 + +虚拟网络计算 (VNC) + +用于远程控制台访问 VM 的开源 GUI 和 CLI 工具。 + +虚拟网络接口 (VIF) + +插入网络网络中的端口的接口。通常属于 VM 的虚拟网络接口。 + +虚拟网络 + +使用物理网络基础架构上的虚拟机和覆盖网络组合实现网络功能虚拟化(如交换、路由、负载平衡和安全性)的通用术语。 + +虚拟端口 + +虚拟接口连接到虚拟网络的连接点。 + +虚拟专用网络 (VPN) + +由 Compute 以 cloudpipes 的形式提供,这些专用实例用于按项目创建 VPN。 + +虚拟服务器 + +VM 或来宾的替代术语。 + +虚拟交换机 (vSwitch) + +在主机或节点上运行并提供基于硬件的网络交换机的特性和功能的软件。 + +虚拟 VLAN + +虚拟网络的替代术语。 + +VirtualBox + +支持 OpenStack 的虚拟机管理程序。 + +Vitrage + +Root Cause Analysis服务的代码名称。 + +VLAN 管理器 + +一个 Compute 组件,它提供 dnsmasq 和 radvd,并设置与 cloudpipe 实例之间的转发。 + +VLAN 网络 + +网络控制器提供虚拟网络,使计算服务器能够相互交互以及与公用网络交互。所有计算机都必须具有公共和专用网络接口。VLAN 网络是一个专用网络接口,由 VLAN 管理器 `vlan_interface` 选项控制。 + +虚拟机磁盘(VMDK) + +镜像服务支持的虚拟机镜像磁盘格式之一。 + +虚拟机映像 + +映像的替代术语。 + +虚拟机远程控制 (VMRC) + +使用 Web 浏览器访问 VM 实例控制台的方法。由计算支持。 + +VMware API 接口 + +支持在计算中与 VMware 产品进行交互。 + +VMware NSX Neutron 插件 + +在 Neutron 中提供对 VMware NSX 的支持。 + +VNC 代理 + +一个计算组件,允许用户通过 VNC 或 VMRC 访问其 VM 实例的控制台。 + +卷 + +基于磁盘的数据存储通常表示为具有支持扩展属性的文件系统的 iSCSI 目标;可以是持久的,也可以是短暂的。 + +卷 API + +块存储 API 的替代名称。 + +卷控制器 + +一个块存储组件,用于监督和协调存储卷操作。 + +卷驱动程序 + +卷插件的替代术语。 + +卷 ID + +应用于块存储控制下每个存储卷的唯一 ID。 + +卷管理器 + +用于创建、附加和分离持久性存储卷的块存储组件。 + +卷节点 + +运行 cinder-volume 守护程序的块存储节点。 + +卷插件 + +为块存储卷管理器提供对新型和专用后端存储类型的支持。 + +卷工作器 + +一个 cinder 组件,它与后端存储交互,以管理卷的创建和删除以及计算卷的创建,由 cinder-volume 守护程序提供。 + +vSphere + +支持 OpenStack 的虚拟机管理程序。 + +#### W + +Wallaby + +OpenStack 第 23 版的代号。小袋鼠原产于澳大利亚,在这个命名期开始时,澳大利亚正在经历前所未有的野火。 + +Watcher + +基础结构优化服务的代号。 + +权重 + +对象存储设备用于确定哪些存储设备适合作业。设备按大小加权。 + +加权成本 + +决定在计算中启动新 VM 实例的位置时所使用的每个成本的总和。 + +加权 + +一个计算过程,用于确定 VM 实例是否适合特定主机的作业。例如,主机上的 RAM 不足、主机上的 CPU 过多等。 + +工作者 + +侦听队列并执行任务以响应消息的守护程序。例如, cinder-volume worker 管理存储阵列上的卷创建和删除。 + +工作流服务 (mistral) + +OpenStack服务提供了一种基于YAML的简单语言来编写工作流(任务和转换规则),以及一种允许上传、修改、大规模和高度可用的方式运行它们、管理和监控工作流执行状态和单个任务状态的服务。 + +#### X + +X.509 + +X.509 是定义数字证书的最广泛使用的标准。它是一种数据结构,包含主题(实体)可识别信息,例如其名称及其公钥。证书还可以包含一些其他属性,具体取决于版本。X.509 的最新标准版本是 v3。 + +Xen + +Xen 是一个使用微内核设计的虚拟机管理程序,它提供的服务允许多个计算机操作系统在同一计算机硬件上同时执行。 + +Xen API + +Xen 管理 API,受 Compute 支持。 + +Xen 云平台 (XCP) + +支持 OpenStack 的虚拟机管理程序。 + +Xen Storage Manager 卷驱动程序 + +支持与 Xen Storage Manager API 进行通信的块存储卷插件。 + +Xena + +OpenStack 第 24 版的代号。该版本以虚构的战士公主命名。 + +XenServer + +An OpenStack-supported hypervisor. 支持 OpenStack 的虚拟机管理程序。 + +XFS 函数 + +由 Silicon Graphics 创建的高性能 64 位文件系统。在并行 I/O 操作和数据一致性方面表现出色。 + +#### Y + +Yoga + +OpenStack 第 25 版的代号。该版本以来自印度的一所哲学学校命名,该学校具有心理和身体实践。 + +#### Z + +Yoga + +消息服务的代号。 + +Zed + +OpenStack 第 26 版的代号。该版本以字母 Z 的发音命名。 + +ZeroMQ + +OpenStack 支持的消息队列软件。RabbitMQ 的替代品。也拼写为 0MQ。 + +Zuul + +Zuul 是一个开源 CI/CD 平台,专门用于在登陆单个补丁之前跨多个系统和应用程序进行门控更改。 + +Zuul 用于 OpenStack 开发,以确保只有经过测试的代码才会被合并。 diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/spec/distributed-traffic.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/spec/distributed-traffic.md new file mode 100644 index 0000000000000000000000000000000000000000..91d742f9238c9fc8d89f606dc8801239455e9776 --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/spec/distributed-traffic.md @@ -0,0 +1,309 @@ +# 流量分散 + +## 概述 + +OpenStack为用户提供计算和网络服务。用户创建虚拟机并连接Router可以访问外部网络,同时可以开启浮动IP的端口映射,让外部网络的设备访问虚拟机内部的服务。但与此同时,随着虚拟机和浮动IP +端口映射的数量的增多,网络节点的压力也越来越大,必须找到分散网络节点流量,疏解网络节点压力的方法。本方案实现了在OpenStack环境中将网络节点流量分散,保证兼容支持L3 +HA和DVR,同时又将网络资源使用最小化。 + +## 背景 + +用户创建虚拟机并连接Router的基本流程如下。 + +1. 用户提前创建内部网络和外部网络。 +2. 创建Router时指定External Gateway为提前创建的外部网络。 +3. 将Router和创建好的内部网络进行连接。 +4. 创建虚拟机实例时指定内部网络。 +5. 利用创建的外部网络创建浮动IP。 +6. 为虚拟机实例开启浮动IP端口映射。 + +经过上面的操作,用户创建的虚拟机实例可以访问到外部网络,外部网络的设备也可以根据浮动IP指定的端口访问虚拟机实例内部的服务。 + +在一个基本的OpenStack环境中虚拟机实例的流量走向如下所示。 + +![单个虚拟机网络流量](../img/spec/router_1.png) + +在用户创建完多个实例后,虚拟机实例可能会均匀分布在各个计算节点,虚拟机的流量走向可能如下图所示。 + +![多个虚拟机网络流量](../img/spec/router_2.png) + +可以看到,不论虚拟机的东西流量还是南北流量都会经过Network-1节点,这无疑加大了网络节点的负载,同时当网络节点发生故障时不能很好的进行故障恢复。 +那么是否可以将同一子网绑定多个Router,在OpenStack中同一子网可以绑定多个Router,但是子网在绑定Router时默认会将子网的网关地址绑定到Router上,一个子网只有一个网关地址,同时这个网关地址又会在DHCP服务中用到,用于给虚拟机实例提供下一跳的网关地址,于是乎即使将子网绑定到多个Router上,虚拟机内部下一跳的网关地址还会是子网的网关地址,而且Router选择的网络节点用户是不可控的,难免会出现虽然子网绑定了两个Router,但是这两个Router在同一个网络节点上的尴尬场面。 + +为了分散流量OpenStack有应对的策略,可以将neutron的DVR功能打开,为预防网络节点的单点故障也可以打开neutron的L3 +HA,但是上述方法也有它们的局限性。 + +DVR的流量分散有比较大的局限性,原因有以下几点。 +DVR只是作用于同一Router下不同计算节点的虚拟机实例之间的东西流量,已经绑定浮动IP虚拟机的南北流量,对于未绑定浮动IP的虚拟机访问外部网络依据需要经过网络节点。 + +生产环境下,给每个虚拟机都绑定浮动IP是不切实际的,但是可以通过开启浮动IP的端口映射,让多台虚拟机对应一个浮动IP,但在目前的OpenStack版本中,不论是否开启DVR,浮动IP的端口映射的实现都是在网络节点的网络命名空间中完成的。 +最后一点,DVR模式下,为了让虚拟机的南北流量不经过网络节点,从计算节点上直接走出,都会在每个计算节点上生成一个fip开头的网络命名空间,即使虚拟机不会绑定浮动IP。而这个fip网络命名空间中会占用一个外部网络的IP地址,这无疑会加大网络资源的消耗。 + +L3 HA也有几点不足,开启L3 HA后,Router利用keepalived会在几个网络节点之间进行选择,只有Keepalived的状态为Master +的网络节点才会担任真正的流量运输的任务,而对于网络节点选择,用户无权干涉。虽然neutron中给出了Router的默认调度策略,也就是最少Router数,Router会调度到Router个数最少的网络节点上。而且在底层keepalived开启的模式是非抢占的,也就是当vip发生漂移后,即使主服务器恢复正常,也不会自动将资源从备用服务器手中抢占回来,这又增加了对于真正运行Router的网络节点的不确定性。 + +总结一下,现有的技术方案做不到真正的流量分发,即使在开启DVR后,一方面会有一些额外网络资源的损耗,同时又因为Router的网络节点的不确定性,导致虚拟机的南北流量无法做到很好的分发。 + +## 需要解决的问题 + +实现DVR模式和L3 HA模式下以及Legacy模式下网络分发。首先要解决以下几个技术问题: + +1. Router可以指定网络节点,不论是否开启L3 HA。 +2. 同一子网绑定多个Router时,DHCP服务能为不同计算节点的虚拟机提供不同的路由方式。 +3. 在用户使用端口映射时,可以将Router的External Gateway的IP地址作为外部网络的地址。 + +## 实现方案 + +### 解决指定L3 agent的问题 + +首先修改Router的底层数据库为其添加一个configurations字段,用于存储Router的相关配置信息,configurations的格式如下所示。 + +```json +{ + "configurations": { + "preferred_agent": "network-1" + } +} +``` + +在未开启L3 HA时,preferred_agent字段用于指定Router位于的网络节点。 +在开启L3 HA时,configurations的格式如下所示。 + +```json +{ + "configurations": { + "slave_agents": [ + "compute-1" + ], + "master_agent": "network-1" + } +} +``` + +master_agent用于指定Master角色的网络节点,slave_agents用于指定Slave角色的网络节点数组。 + +然后要修改Router的创建逻辑,需要为Router新增一个调度方法。Neutron中router_scheduler_driver默认是LeastRoutersScheduler(最少Router个数的网络节点),继承该类新增调度方法,可以根据Router的configurations字段选择指定的网络节点。 + +![L3 Scheduler](../img/spec/l3_scheduler.png) + +最后需要修改neutron-l3-agent的Router更新的逻辑代码,由于neutron-l3-agent启动时会初始化一个资源队列用于更新资源状态,同时开启一个守护线程用于读取资源队列,每次网络资源状态有变化(创建、删除或者更新)时,就会添加到该队列中,最后根据资源的类型和状态确定将要执行的动作。 +这里Router创建完后,neutron-l3-agent最后会执行_process_added_router方法,先调用RouterInfo的initialize方法,再调用process方法。 +initialize方法主要涉及到Router信息的一些初始化,包括网络命名空间的创建、port的创建、keepalived进程的初始化等等。 +process方法中会做下面几个操作。 + +1. 设置内部的Port,用于连接内部网络; +2. 设置外部Port,用于连接外部网络; +3. 更新路由表; +4. 对于开启L3 HA的Router,需要设置HA的Port,然后开启keepalived进程。 +5. 对于开启DVR的Router,还需要设置一下fip命名空间中的Port。 + +这里只需要考虑L3 HA开启的情况,因为在未开启L3 +HA时,neutron-server创建完Router后,经过新的调度方法选择特定的网络节点,RPC调用直接发送给特定网络节点的neutron-l3-agent服务。开启L3 +HA时,调度方法会选择出master和slave网络节点,并且RPC调用会发送给这些网络节点上的neutron-l3-agent服务。 +neutron-l3-agent会为每个Router启动一个keepalived进程用于L3 +HA,所以需要在keepalived初始化时,将keepalived启动逻辑修改。利用configurations字段的信息,获取master和slave网络节点,同时和当前网络节点的信息判断,确定网络节点的角色。最后,因为指定了master和slave节点,避免出现master网络节点宕机恢复后,vip依旧在slave节点的情况,要把keepalived的模式改为抢占模式。 + +### 解决路由问题 + +解决同一子网绑定多个Router后,虚拟机实例的路由问题。DHCP协议功能不仅包括和DNS服务器分配还包括网关地址分配,也就是可以通过DHCP协议将路由信息传给虚拟机实例。在OpenStack中,虚拟机实例的DHCP由neutron-dhcp-agent提供,neutron-dhcp-agent的核心功能基本由dnsmasq完成。 + +dnsmasq中提供tag标签,可以为指定IP地址添加标签,然后可以根据标签下发配置。 +dnsmasq的host配置文件如下所示。 + +```bash +fa:16:3e:28:a5:0a,host-172-16-0-1.openstacklocal,172.16.0.1,set:subnet-6a4db541-e563-43ff-891b-aa8c05c988c5 +fa:16:3e:2b:dd:88,host-172-16-0-10.openstacklocal,172.16.0.10,set:subnet-6a4db541-e563-43ff-891b-aa8c05c988c5 +fa:16:3e:a1:96:fc,host-172-16-0-207.openstacklocal,172.16.0.207,set:compute-1-subnet-6a4db541-e563-43ff-891b-aa8c05c988c5 +fa:16:3e:45:b4:1a,host-172-16-10-1.openstacklocal,172.16.10.1,set:subnet-faeec4d1-2c0c-4f7a-bc9b-0af562694902 +``` + +dnsmasq的option配置文件如下所示。 + +```bash +tag:subnet-faeec4d1-2c0c-4f7a-bc9b-0af562694902,option:dns-server,8.8.8.8 +tag:subnet-faeec4d1-2c0c-4f7a-bc9b-0af562694902,option:classless-static-route,172.16.0.0/24,0.0.0.0,169.254.169.254/32,172.16.0.2,0.0.0.0/0,172.16.0.1 +tag:subnet-faeec4d1-2c0c-4f7a-bc9b-0af562694902,249,172.16.0.0/24,0.0.0.0,169.254.169.254/32,172.16.0.2,0.0.0.0/0,172.16.0.1 +tag:subnet-faeec4d1-2c0c-4f7a-bc9b-0af562694902,option:router,172.16.0.1 +tag:compute-1-subnet-6a4db541-e563-43ff-891b-aa8c05c988c5,option:classless-static-route,172.16.10.0/24,0.0.0.0,169.254.169.254/32,172.16.0.2,0.0.0.0/0,172.16.0.10 +tag:compute-1-subnet-6a4db541-e563-43ff-891b-aa8c05c988c5,249,172.16.0.0/24,0.0.0.0,169.254.169.254/32,172.16.0.2,0.0.0.0/0,172.16.0.10 +tag:compute-1-subnet-6a4db541-e563-43ff-891b-aa8c05c988c5,option:router,172.16.0.10 +``` + +可以看到IP172.16.0.207被打上了compute-1开头的tag,匹配到option文件后,172.16.0.207的虚拟机的默认路由网关地址就会从172.16.0.1变为172.16.0.10。当然这一切的前提子网需要绑定多个Router。 +同时为neutron-dhcp-agent提供可供管理员修改的配置项,用于指定计算节点和网络节点的关系,可以是一对一,可以是多对一。 + +### 解决Router Gateway端口转发的问题 + +将原本基于浮动IP的端口映射改为基于Router的External Gateway的方式。原因有二: + +1. 基于浮动IP的端口映射,对于原本就要使用Router的External Gateway的用户就会多占用一个外部网络的IP,为减少外部网络IP的使用改用External + Gateway的方式进行端口映射。 +2. 基于浮动IP的端口映射,依赖Router的网络命名空间来做NAT,不开启L3 + HA时,同一子网在绑定多个Router后,由于端口映射创建的逻辑,NAT会发生在子网网关地址所在的Router的网络命名空间中(特定的网络节点),不会分散在各个Router的网络命名空间中(每个网络节点)。这样在端口映射时,会增加网络节点的压力。 + 实现方式和基于浮动IP的端口映射类似,与之不同的是External Gateway不需要选择Router,因为External + Gateway本来和Router就是相关联的。基于浮动IP的端口映射在选择Router时,选择的是子网的网关地址所在的Router。 + +最后,在实现上面三个部分后,用户实现流量分散的步骤如下。 + +1. 用户修改neutron-dhcp-agent的配置文件,修改计算节点和网络节点的映射关系。例如三个网络节点、三个计算节点,配置compute-1走network-1节点,compute-2和compute-3走network-2节点。 +2. 利用neutron的API创建多个Router并指定网络节点,并将Router绑定到同一子网。 +3. 利用子网网络创建多个虚拟机实例。 + +虚拟机实例的网络流量的流向如下图所示。 + +![网络流量](../img/spec/router_3.png) + +可以看到,VM-1访问外部网络经过的是network-1节点,VM-2和VM-3访问外部网络经过的是network-2节点。同时VM-1、VM-2和VM-3又是在同一个子网下,可以互相访问。 + +# API + +## 查看路由器网关端口转发列表 + +```text +GET /v2.0/routers/{router_id}/gateway_port_forwardings + +Response +{ + "gateway_port_forwardings": [ + { + "id": "67a70b09-f9e7-441e-bd49-7177fe70bb47", + "external_port": 34203, + "protocol": "tcp", + "internal_port_id": "b671c61a-95c3-49cd-89f2-b7e817d1f486", + "internal_ip_address": "172.16.0.196", + "internal_port": 518, + "gw_ip_address": "192.168.57.234" + } + ] +} +``` + +## 查看路由器网关端口转发 + +```text +GET /v2.0/routers/{router_id}/gateway_port_forwardings/{port_forwarding_id} + +Response +{ + "gateway_port_forwarding": { + "id": "67a70b09-f9e7-441e-bd49-7177fe70bb47", + "external_port": 34203, + "protocol": "tcp", + "internal_port_id": "b671c61a-95c3-49cd-89f2-b7e817d1f486", + "internal_ip_address": "172.16.0.196", + "internal_port": 518, + "gw_ip_address": "192.168.57.234" + } +} +``` + +## 创建路由器网关端口转发 + +```text +POST /v2.0/routers/{router_id}/gateway_port_forwardings +Request Body +{ + "gateway_port_forwarding": { + "external_port": int, + "internal_port": int, + "internal_ip_address": "string", + "protocol": "tcp", + "internal_port_id": "string" + } +} + +Response +{ + "gateway_port_forwarding": { + "id": "da554833-b756-4626-9900-6256c361f94b", + "external_port": 14122, + "protocol": "tcp", + "internal_port_id": "b671c61a-95c3-49cd-89f2-b7e817d1f486", + "internal_ip_address": "172.16.0.196", + "internal_port": 3634, + "gw_ip_address": "192.168.57.234" + } +} +``` + +## 更新路由器网关端口转发 + +```text +PUT /v2.0/routers/{router_id}/gateway_port_forwardings/{port_forwarding_id} +Request Body +{ + "gateway_port_forwarding": { + "external_port": int, + "internal_port": int, + "internal_ip_address": "string", + "protocol": "tcp", + "internal_port_id": "string" + } +} + +Response +{ + "gateway_port_forwarding": { + "id": "da554833-b756-4626-9900-6256c361f94b", + "external_port": 14122, + "protocol": "tcp", + "internal_port_id": "b671c61a-95c3-49cd-89f2-b7e817d1f486", + "internal_ip_address": "172.16.0.196", + "internal_port": 3634, + "gw_ip_address": "192.168.57.234" + } +} +``` + +## 删除路由器网关端口转发 + +```text +DELETE /v2.0/routers/{router_id}/gateway_port_forwardings/{port_forwarding_id} +``` + +## 新建路由器 + +```text +POST /v2.0/routers +Request Body +{ + "router": { + "name": "string", + "admin_state_up": true, + "configurations": { + "preferred_agent": "string", + "master_agent": "string", + "slave_agents": [ + "string" + ] + } + } +} +``` + +## 更新路由器 + +```text +PUT /v2.0/routers/{router_id} +Request Body +{ + "router": { + "name": "string", + "admin_state_up": true, + "configurations": { + "preferred_agent": "string", + "master_agent": "control01", + "slave_agents": [ + "control01" + ] + } + } +} +``` + +# 开发节奏 + +* 2023-07-28到2023-08-30 完成开发 +* 2023-09-01到2023-11-15 测试、问题修复 +* 2023-11-30引入openEuler 20.03 LTS SP4版本 +* 2023-12-30引入openEuler 22.03 LTS SP3版本 diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/spec/openkite.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/spec/openkite.md new file mode 100644 index 0000000000000000000000000000000000000000..13fb9725ba39cd96bdf8c106d057a53a9cba8269 --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/spec/openkite.md @@ -0,0 +1,322 @@ +# 1、前序 + +## 1.1、 软件许可协议 + +本软件基于LGPL V3协议,请用户和开发者注意LGPL协议的要求,其中最重要的一点是**不允许fork项目闭源**。 + +## 1.2、 软件用途 + +## 1.3、 开发人员名单 + +## 1.4、 生命开发周期 + +## 1.5、 功能开发顺序 + +# 2、开发规范约定 + +## 2.1、 窗体控件命名规范 + +- 控件原名称\_窗体\_控件名称组合体首字母大写 +- 示例: + + ```cpp + 按钮原名称:pushButton 主窗体 菜单按钮 + 命名规范:pushButton_MainWindow_Menu + + 按钮原名称:toolButton 主窗体 上传按钮 + 命名规范:toolButton_MainWindow_UpLoad + ``` + +## 2.2、 后台功能实现命名规范 + +- 变量、常量、函数、类、容器等 + +## 2.3、 软件包文件名命名规范 + +## 2.4、 文件命名规范 + +## 2.5、 标注 + +- 删除、移动、改名、权限设置 + +# 3、窗口主体控件名称、尺寸、用途 + +## 3.1、菜单功能大类 + +- PushButton控件用于菜单大类调用窗口 +- 控件尺寸: + - 固定尺寸 80*25 + +| 控件中文名 | 控件种类 | 控件名 | 用途 | +|-----------|-----------|-------------------------------------|----------------| +| 菜单 |PushButton| pushButton_MainWindow_Menu | 调出菜单窗口 | +| 帮助 |PushButton| pushButton_MainWindow_Help | 调出帮助窗口 | +| 工具 |PushButton| pushButton_MainWindow_Tool | 调出工具窗口 | +| 报错分析 |PushButton| pushButton_MainWindow_ErrorAnalysis | 调出报错分析窗口 | +| 监控 |PushButton| pushButton_MainWindow_Monitor | 调出监控窗口 | +| 运维日志 |PushButton| pushButton_MainWindow_OperationLog | 调出运维日志窗口 | + +### 3.1.1、菜单子类 + +- 设置 +- 软件主题 + +### 3.1.2、帮助类 + +- 社区 +- 版本更新 +- 使用手册 + +### 3.1.3、工具类 + +- 插件仓库 +- img镜像工具 +- MD5校验工具 +- OpenStack模块功能测试 +- 压力测试 + +### 3.1.4、报错分析类 + +- 系统报错(节点报错分析) +- OpenStack报错 +- K8S报错 + +### 3.1.5、监控类 + +- OPS监控状态与性能使用分析 +- K8S监控状态与性能使用分析 + +### 3.1.6、运维日志类 + +- 查看历史运维日志 +- 日志导出 + +## 3.2、数据可视化类 + +### 3.2.1、计算机硬件信息类 + +- ProgressBar控件显示计算机硬件性能占用比 +- 控件尺寸: + - 最小尺寸 116*27 + - 高度尺寸固定 + +| 控件中文名 | 控件种类 | 控件名 | 用途 | +|-----------|-----------|--------------------------------------|-----------------------| +| 本机CPU |ProgressBar| progressBar_MainWindow_LocalCPU | 显示本地CPU使用率 | +| 目标CPU |ProgressBar| progressBar_MainWindow_TargetCPU | 显示目标CPU使用率 | +| 本机RAM |ProgressBar| progressBar_MainWindow_LocalRAM | 显示本机RAM使用率 | +| 目标RAM |ProgressBar| progressBar_MainWindow_TargetRAM | 显示目标RAM使用率 | +| 本机网络 |ProgressBar| progressBar_MainWindow_LocalNetwork | 显示本机网络带宽使用率 | +| 目标网络 |ProgressBar| progressBar_MainWindow_TargetNetwork | 显示目标网络带宽使用率 | +| 本机磁盘 |ProgressBar| progressBar_MainWindow_LocalDisk | 显示本机磁盘IO使用率 | +| 目标磁盘 |ProgressBar| progressBar_MainWindow_TargetDisk | 显示目标磁盘IO使用率 | + +### 3.2.2、计算机软件信息类 + +- Label控件显示系统IP与DNS +- 控件尺寸: + - 固定尺寸 110*27 + +| 控件中文名 |控件种类| 控件名 | 用途 | +|-----------|-------|----------------------------|------------| +| 本机IP |Label | label_MainWindow_LocalIP | 显示本机IP | +| 目标IP |Label | label_MainWindow_TargetIP | 显示目标IP | +| 本机DNS |Label | label_MainWindow_LocalNDS | 显示本机DNS | +| 目标DNS |Label | label_MainWindow_TargetNDS | 显示目标DNS | + +- ListWidget控件显示系统必要信息项说明 +- 控件尺寸: + - 固定尺寸 200*111 + +| 控件中文名 | 控件种类 | 控件名 | 用途 | +|-------------|-------------|---------------------------------|----------------| +| 系统信息显示 | ListWidgets | listWidget_MainWidow_SystemShow | 显示系统必要信息 | + +- 系统必要信息显示所用变量的API接口 + +| 中文名 | 变量类型 | 变量名 | 用途 | +|---------|-------------|---------------------|---------------------| +| 发行版 | QStringList | systemNameShow | linux发行版名称 | +| 版本号 | QStringList | systemVersion | linux发行版版本号 | +| 内核号 | QStringList | systemKernel | linux发行版内核版本 | +| 管理权限 | QStringList | systemAdminPower | 当前账号操作权限 | +| 服务名称 | QStringList | systemServiceName | 当前运维软件服务名称 | +| 服务版本 | QStringList | systemServicVersion | 当前运维软件版本 | + +- Label与ProgressBar控件显示当前运行命令及进度 +- 控件尺寸: + - 当前运行命令控件尺寸: + - 最小尺寸:500*31 + - 高度尺寸固定 + - 当前命令进度控件尺寸: + - 最小尺寸:171*31 + - 高度尺寸固定 + +|中文名|控件种类|控件名|用途| +|------|-------|-----|----| +|当前运行命令|Label|label_MainWindow_ShowCurrentCommand|显示当前集群或节点正在运行的命令| +|当前命令进度|ProgressBar|progressBar_MainWindow_ShowCommandProgress|显示当前集群或节点正在运行的命令的进度| + +## 3.3、添加集群类 + +### 3.3.1、 集群添加类 + +- ToolButton控件添加集群节点信息 +- 控件尺寸: + - 固定尺寸:300*31 + +|中文名|控件类型|控件名|用途| +|------|-------|------|----| +|添加集群/节点|ToolButton|toolButton_MainWindow_AddNode|弹出窗口添加集群或节点| + +- 单节点添加 +- 批量节点添加 +- 集群添加 + +### 3.3.2、集群显示类 + +- TreeWidget控件显示集群信息 +- 控件尺寸: + - 最小尺寸:200*438 + - 宽度尺寸固定 + +| 中文名 |控件类型|控件名|用途| +|------|-------|------|---| +|节点信息|TreeWidget|treeWidget_MainWindow_ShowNode|用于显示集群与节点信息或点击信息后创建SSH远程窗口界面| + +- 集群名称 +- 节点名称 +- 节点IP地址 + +### 3.4、脚本与部署类 + +- TerrWidget控件弹窗 +- 控件尺寸: + - 上传、脚本按钮固定尺寸:63*31 + - 部署按钮固定尺寸:65*31 + +| 中文名 | 控件类型 | 控件名 | 用途 | +|--------|------------|------------------------------|-----------------------| +| 上传 | terrWidget | toolButton_MainWindow_UpLoad | 弹出上传窗体:load.ui | +| 脚本 | terrWidget | toolButton_MainWindow_Shell | 弹出脚本窗体:shell.ui | +| 部署 | terrWidget | toolButton_MainWindow_Deploy | 弹出部署窗体:deploy.ui | + +### 3.4.1、上传与下载功能类 + +- 脚本编译器 + - yaml编译器 + - 脚本编译器 +- 加载本地策略 + - 加载集群配置策略 + - 加载节点配置策略 +- 上传文件到目标计算机 + - 单节点 + - 多节点 +- 下载文件到本地计算机 + - 单节点 + - 多节点 +- 目标计算机文件互传 + - 点对点互传 + - 点对多互传 + +### 3.4.2、脚本类 + +- 编辑 + - 编辑子模块脚本 + - 编辑集群模块脚本 +- 查看 + - 查看子模块脚本 + - 查看集群模块脚本 +- 导出 + - 导出子模块脚本 + - 导出集群模块脚本 + - 导出所有脚本 + +### 3.4.3、部署类 + +- 部署 + - 可批量选择节点部署不同功能脚本 + - 可集群部署不同节点不同功能脚本 + - 可单节点部署不同功能脚本 +- 终止 + - 可批量多节点、单节点、集群终止当前部署 + +### 3.5、功能插件类 + +### 3.5.1、基础运维类 + +- 修改服务器计算机名 +- 修改服务器用户名 +- 修改服务器密码 +- 修改防火墙配置 +- 修改host +- 修改DNS +- 修改网关 +- 修改IP +- 部署时间服务 +- 部署DNS服务 + +### 3.5.2、其他功能插件类 + +- OpenStack插件类 +- K8S插件类 +- Ceph插件类 + +## 3.6、ssh远程显示类 + +- 可复制粘贴命令,中文显示综合端口 + +### 3.6.1、集群SSH远程显示类 + +- 综合端口显示,点对多ssh远程 + +### 3.6.2、单节点SSH远程显示类 + +- 点对点ssh远程 + +# 4、窗口主体功能插件添加方式、规范、API与功能注释 + +## 4.1、工具类 + +- 开发规范: +- API接口: +- 功能注释: +- 面板添加方式: +- 后台功能模块添加方式: +- 文件夹位置: + +## 4.2、功能插件类 + +- 开发规范: +- API接口: +- 功能注释: +- 面板添加方式: +- 后台功能模块添加方式: +- 文件夹位置: + +# 5、后台API调用、规范与使用说明 + +## 5.1、计算机硬件 + +### 5.1.1、CPU + +### 5.1.2、RAM + +## 5.2、计算机软件 + +### 5.2.1、本地软件包 + +### 5.2.2、源软件包 + +# 6、开发思路备注 + +- 在各种操作前进行判断本地网络与目标网络是否连同 +- 在目标网络无法连通时提示:目标IP网络不通 +- 在集群节点都无法联通时,集群节点字体灰色 +- 在集群操作或多节点操作时提示无法连接的目标信息,并提示确实是否继续,如继续则屏蔽无法连接的节点去进行批量部署 +- 界面信息刷新频率 + - 软硬件信息刷新频率 + - cpu、内存等占比显示信息的刷新频率为0.5s + - ssh界面刷屏频率为实时刷新 + - 集群显示信息为实时刷新 + - 系统必要信息显示区域为实时刷新 diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/spec/openstack-sig-tool-requirement.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/spec/openstack-sig-tool-requirement.md new file mode 100644 index 0000000000000000000000000000000000000000..a0c09017a9bf0d142268e9d1d0ec772dd501cba6 --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/spec/openstack-sig-tool-requirement.md @@ -0,0 +1,157 @@ +# openEuler OpenStack开发平台需求说明书 + +## 背景 + +目前,随着SIG的不断发展,我们明显的遇到了以下几类问题: +1. OpenStack技术复杂,涉及云IAAS层的计算、网络、存储、镜像、鉴权等方方面面的技术,开发者很难全知全会,提交的**代码逻辑、质量堪忧**。 +2. OpenStack是由python编写的,python软件的依赖问题难以处理,以OpenStack Wallaby版本为例,涉及核心python软件包400+, 每个软件的依赖层级、依赖版本**错综复杂,选型困难**,难以形成闭环。 +3. OpenStack软件包众多,RPM Spec编写开发量巨大,并且随着openEuler、OpenStack本身版本的不断演进,N:N的适配关系会导致**工作量成倍增长,人力成本越来越大**。 +4. OpenStack测试门槛过高,不仅需要开发人员熟悉OpenStack,还要对虚拟化、虚拟网桥、块存储等Linux底层技术有一定了解与掌握,部署一套OpenStack环境耗时过长,功能测试难度巨大。并且测试场景多,比如X86、ARM64架构测试,裸机、虚机种类测试,OVS、OVN网桥测试,LVM、Ceph存储测试等等,更加加重了**人力成本以及技术门槛**。 + +针对以上问题需要在openEuler OpenStack提供一个开发平台,解决开发过程遇到的以上痛点问题。 + +## 目标 + +设计并开发一个OpenStack强相关的openEuler开源开发平台,通过规范化、工具化、自动化的方式,满足SIG开发者的日常开发需求,降低开发成本,减少人力投入成本,降低开发门槛,从而提高开发效率、提高SIG软件质量、发展SIG生态、吸引更多开发者加入SIG。 + +## 范围 + +**用户范围**:openEuler OpenStack SIG开发者 + +**业务范围**:openEuler OpenStack SIG日常开发活动 + +**编程语言**:Python、Ansible、Jinja、JavaScript + +**IT技术**:Web服务、RestFul规范、CLI规范、前端GUI、数据库使用 + +## 功能 + +OpenStack开发平台整体采用C/S架构,以SIG对外提供平台能力,client端面向指定用户白名单开放。 + +为方便白名单以外用户使用,本平台还提供CLI模式,在此模式下不需要额外服务端通信,在本地即可开箱即用。 + +1. 输出OpenStack服务类软件、依赖库软件的RPM SPEC开发规范,开发者及Reviewer需要严格遵守规范进行开发实施。 +2. 提供OpenStack python软件依赖分析功能,一键生成依赖拓扑与结果,保证依赖闭环,避免软件依赖风险。 +3. 提供OpenStack RPM spec生成功能,针对通用性软件,提供一键生成 RPM spec的功能,缩短开发时间,降低投入成本。 +4. 提供自动化部署、测试平台功能,实现一键在任何openEuler版本上部署指定OpenStack版本的能力,快速测试、快速迭代。 +5. 提供openEuler Gitee仓库自动化处理能力,满足批量修改软件的需求,比如创建代码分支、创建仓库、提交Pull Request等功能。 + +### SPEC开发规范制定 + +【功能点】 + + 1. 约束OpenStack服务级项目SPEC格式与内容规范 + 2. 规定OpenStack依赖库级别项目SPEC的框架。 + +【先决条件】:OpenStack SIG全体Maintainer达成一致,参与厂商没有分歧。 + +【参与方】:中国电信、中国联通、统信软件 + +【输入】:RPM SPEC编写标准 + +【输出】:服务级、依赖库级SPEC模板;软件分层规范。 + +【对其他功能的影响】:本功能是以下软件功能的前提,下述如`SPEC自动生成功能`需遵循本规范执行。 + +### 依赖分析需求 + +【功能点】 + + 1. 自动生成基于指定openEuler版本的OpenStack依赖表。 + 2. 能处理依赖成环、版本缺省、名称不一致等依赖常见问题。 + +【先决条件】:N/A + +【参与方】:OpenStack SIG核心开发者 + +【输入】:openEuler版本号、OpenStack版本号、目标依赖范围(核心/测试/文档) + +【输出】:指定OpenStack版本的全量依赖库信息,包括最小/最大依赖版本、所属openEuler SIG、RPM包名、依赖层级、子依赖树等内容,可以以Excel表格的方式输出。 + +【对其他功能的影响】:N/A + +### Spec自动生成需求 + +【功能点】 + + 1. 一键生成OpenStack依赖库类软件的RPM SPEC + 2. 支持各种Python软件构建系统,比如setuptools、pyproject等。 + +【先决条件】:需遵守`SPEC开发规范` + +【参与方】:OpenStack SIG核心开发者 + +【输入】:指定软件名及目标版本 + +【输出】:对应软件的RPM SPEC文件 + +【对其他功能的影响】:生成的SPEC可以通过下述`代码提交功能`一键push到openEuler社区。 + +### 自动化部署、测试需求 + +【功能点】 + + 1. 一键快速部署指定OpenStack版本、拓扑、功能的OpenStack单/多节点环境 + 2. 一键基于已部署OpenStack环境进行资源预配置与功能测试。 + 3. 支持多云、主机纳管功能,支持插件自定义功能。 + +【先决条件】:N/A + +【参与方】:OpenStack SIG核心开发者、各个云平台相关开发者 + +【输入】:目标OpenStack版本、计算/网络/存储的driver场景 + +【输出】:一个可以一键执行OpenStack Tempest测试的OpenStack环境;Tempest测试报告。 + +【对其他功能的影响】: N/A + +### 一键代码处理需求 + +【功能点】 + + 1. 一键针对openEuler OpenStack所属项目的Repo、Branch、PR执行各种操作。 + 2. 操作包括:建立/删除源码仓;建立/删除openEuler分支;提交软件Update PR;在PR中添加评审意见。 + +【先决条件】:提交PR功能依赖上述`SPEC生成`功能 + +【参与方】:OpenStack SIG核心开发者 + +【输入】:指定软件名、openEuler release名、目标Spec文件、评审意见内容。 + +【输出】:软件建仓PR;软件创建分支PR;软件升级PR;PR新增评审意见。 + +【对其他功能的影响】:N/A + +## 非功能需求 + +### 测试需求 + +1. 对应软件代码需包含单元测试,覆盖率不低于80%。 +2. 需提供端到端功能测试,覆盖上述所有接口,以及核心的场景测试。 +3. 基于openEuler社区CI,构建CI/CD流程,所有Pull Request要有CI保证代码质量,定期发布release版本,软件发布间隔不大于3个月。 + +### 安全 + +1. 数据安全:软件全程不联网,持久存储中不包含用户敏感信息。 +2. 网络安全:OOS在REST架构下使用http协议通信,但软件设计目标实在内网环境中使用,不建议暴露在公网IP中,如必须如此,建议增加访问IP白名单限制。 +3. 系统安全:基于openEuler安全机制,定期发布CVE修复或安全补丁。 +4. 应用层安全:不涉及,不提供应用级安全服务,例如密码策略、访问控制等。 +5. 管理安全:软件提供日志生成和周期性备份机制,方便用户定期审计。 + +### 可靠性 + +本软件面向openEuler社区OpenStack开发行为,不涉及服务上线或者商业生产落地,所有代码公开透明,不涉及私有功能及代码。因此不提供例如节点冗余、容灾备份能功能。 + +### 开源合规 + +本平台采用Apache2.0 License,不限制下游fork软件的闭源与商业行为,但下游软件需标注代码来源以及保留原有License。 + +## 实施计划 +| 时间 | 内容 | +|:-----------------:|:-----------:| +| 2021.06 | 完成软件整体框架编写,实现CLI Built-in机制,至少一个API可用 | +| 2021.12 | 完成CLI Built-in机制的全量功能可用 | +| 2022.06 | 完成质量加固,保证功能,在openEuler OpenStack社区开发流程中正式引入OOS | +| 2022.12 | 不断完成OOS,保证易用性、健壮性,自动化覆盖度超过80%,降低开发人力投入 | +| 2023.06 | 补齐REST框架、CI/CD流程,丰富Plugin机制,引入更多backend支持 | +| 2023.12 | 完成前端GUI功能 | diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/spec/openstack-sig-tool.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/spec/openstack-sig-tool.md new file mode 100644 index 0000000000000000000000000000000000000000..88406e48ef2d685f5d63dd59494f61a163fc88ab --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/spec/openstack-sig-tool.md @@ -0,0 +1,932 @@ + +# openEuler OpenStack 开发平台 + +openEuler OpenStack SIG成立于2021年,是由中国联通、中国电信、华为、统信等公司的开发者共同投入并维护的SIG小组,旨在openEuler之上提供原生的OpenStack,构建开放可靠的云计算技术栈,是openEuler的标杆SIG。但OpenStack本身技术复杂、包含服务众多,开发门槛较高,对贡献者的技术能力要求也较高,人力成本高居不下,在实际开发与贡献中存在各种各样的问题。为了解决SIG面临的问题,亟需一个openEuler+OpenStack解决方案,从而降低开发者门槛,降低投入成本,提高开发效率,保证SIG的持续活跃与可持续发展。 + +## 1. 概述 + +### 1.1 当前现状 + +目前,随着SIG的不断发展,我们明显的遇到了以下几类问题: +1. OpenStack技术复杂,涉及云IAAS层的计算、网络、存储、镜像、鉴权等方方面面的技术,开发者很难全知全会,提交的代码逻辑、质量堪忧。 +2. OpenStack是由python编写的,python软件的依赖问题难以处理,以OpenStack Wallaby版本为例,涉及核心python软件包400+, 每个软件的依赖层级、依赖版本错综复杂,选型困难,难以形成闭环。 +3. OpenStack软件包众多,RPM Spec编写开发量巨大,并且随着openEuler、OpenStack本身版本的不断演进,N:N的适配关系会导致工作量成倍增长,人力成本越来越大。 +4. OpenStack测试门槛过高,不仅需要开发人员熟悉OpenStack,还要对虚拟化、虚拟网桥、块存储等Linux底层技术有一定了解与掌握,部署一套OpenStack环境耗时过长,功能测试难度巨大。并且测试场景多,比如X86、ARM64架构测试,裸机、虚机种类测试,OVS、OVN网桥测试,LVM、Ceph存储测试等等,更加加重了人力成本以及技术门槛。 + + +### 1.2 解决方案 + +针对以上目前SIG遇到的问题,规范化、工具化、自动化的目标势在必行。本篇设计文档旨在在openEuler OpenStack SIG中提供一个端到端可用的开发解决方案,从技术规范到技术实现,提出严格的标准要求与设计方案,满足SIG开发者的日常开发需求,降低开发成本,减少人力投入成本,降低开发门槛,从而提高开发效率、提高SIG软件质量、发展SIG生态、吸引更多开发者加入SIG。主要动作如下: +1. 输出OpenStack服务类软件、依赖库软件的RPM SPEC开发规范,开发者及Reviewer需要严格遵守规范进行开发实施。 +2. 提供OpenStack python软件依赖分析功能,一键生成依赖拓扑与结果,保证依赖闭环,避免软件依赖风险。 +3. 提供OpenStack RPM spec生成功能,针对通用性软件,提供一键生成 RPM spec的功能,缩短开发时间,降低投入成本。 +4. 提供自动化部署、测试平台功能,实现一键在任何openEuler版本上部署指定OpenStack版本的能力,快速测试、快速迭代。 +5. 提供openEuler Gitee仓库自动化处理能力,满足批量修改软件的需求,比如创建代码分支、创建仓库、提交Pull Request等功能。 + +以上解决方法可以统一到一个系统平台中,我们称作OpenStack SIG Tool(以下简称oos),即就是openEuler OpenStack开发平台,具体架构如下: +``` + ┌────────────────────┐ ┌─────────────────────┐ + │ CLI │ │ GUI │ + └─────┬─────────┬────┘ └──────────┬──────────┘ + │ │ │ + Built-in│ └───────────┬────────────┘ + │ │REST +┌─────────────────▼─────────────────────▼────────────────────────────────┐ +│ OpenStack Develop Platform │ +└───────────────────────────────────┬────────────────────────────────────┘ + │ + ┌────────────────────┬────┴─────────────┬────────────────┐ + │ │ │ │ +┌─────────▼─────────┐ ┌───────▼───────┐ ┌───────▼───────┐ ┌─────▼─────┐ +│Dependency Analysis│ │SPEC Generation│ │Deploy and Test│ │Code Action│ +└───────────────────┘ └───────────────┘ └───────────────┘ └───────────┘ +``` +该架构主要有以下两种模式: +1. Client/Server模式 + 在这种模式下,oos部署成Web Server形式,Client通过REST方式调用oos。 + - 优点:提供异步调用能力,支持并发处理,支持记录持久化。 + + - 缺点:有一定安装部署成本,使用方式较为死板。 + +2. Built-in模式 + 在这种模式下,oos无需部署,以内置CLI的方式对外提供服务,用户通过cli直接调用各种功能。 + - 优点:无需部署,随时随地可用。 + + - 缺点:没有持久化能力,不支持并发,单人单用。 + +## 2. 详细设计 + +### 2.1 OpenStack Spec规范 + +Spec规范是一个或多个spec模板,针对RPM spec的每个关键字及构建章节,严格规定相关内容,开发者在编写spec时,必须满足规范要求,否则代码不允许被合入。规范内容由SIG maintainer公开讨论后形成结论,并定期审视更新。任何人都有权利提出对规范的质疑和建议, maintainer负责解释与刷新。规范目前包括两类: +1. 服务类软件规范 + 此类软件以Nova、Neutron、Cinder等OpenStack核心服务为例,它们一般定制化要求高,内容区别大,必要人为手动编写。规范需清晰规定软件的分层方法、构建方法、软件包组成内容、测试方法、版本号规则等内容。 + +2. 通用依赖类软件规范 + 此类软件一般定制化低,内容结构区别小,适合自动化工具一键生成,我们只需要在规范中定义相关工具的生成规则即可。 + +#### 2.1.1 服务类软件规范 + +OpenStack每个服务通常包含若干子服务,针对这些子服务,我们在打包的时候也要做拆包处理,分成若干个子RPM包。本章节规定了openEuler SIG对OpenStack服务的RPM包拆分的原则。 + +##### 2.1.1.1 通用原则 + +采用分层架构,RPM包结构如下图所示,以openstack-nova为例: + +``` +Level | Package | Example + | | + ┌─┐ | ┌──────────────┐ ┌────────────────────────┐ | ┌────────────────────┐ ┌────────────────────────┐ + │1│ | │ Root Package │ │ Doc Package (Optional) │ | │ openstack-nova.rpm │ │ openstack-nova-doc.rpm │ + └─┘ | └────────┬─────┘ └────────────────────────┘ | └────────────────────┘ └────────────────────────┘ + | │ | + | ┌─────────────────────┼───────────────────────────┐ | + | │ │ | | + ┌─┐ | ┌────────▼─────────┐ ┌─────────▼────────┐ | | ┌────────────────────────────┐ ┌────────────────────────┐ + │2│ | │ Service1 Package │ │ Service2 Package │ | | │ openstack-nova-compute.rpm │ │ openstack-nova-api.rpm │ + └─┘ | └────────┬─────────┘ └────────┬─────────┘ | | └────────────────────────────┘ └────────────────────────┘ + | | | | | + | └──────────┬─────────┘ | | + | | | | + ┌─┐ | ┌───────▼────────┐ | | ┌───────────────────────────┐ + │3│ | │ Common Package │ | | │ openstack-nova-common.rpm │ + └─┘ | └───────┬────────┘ | | └───────────────────────────┘ + | │ | | + | │ | | + | │ | | + ┌─┐ | ┌────────▼────────┐ ┌────────────────▼────────────────┐ | ┌──────────────────┐ ┌────────────────────────┐ + │4│ | │ Library Package ◄------------| Library Test Package (Optional) │ | │ python2-nova.rpm │ │ python2-nova-tests.rpm │ + └─┘ | └─────────────────┘ └─────────────────────────────────┘ | └──────────────────┘ └────────────────────────┘ +``` + +如图所示,分为4级 + +1. Root Package为总RPM包,原则上不包含任何文件。只做服务集合用。用户可以使用该RPM一键安装所有子RPM包。 + 如果项目有doc相关的文件,也可以单独成包(可选) +2. Service Package为子服务RPM包,包含该服务的systemd服务启动文件、自己独有的配置文件等。 +3. Common Package是共用依赖的RPM包,包含各个子服务依赖的通用配置文件、系统配置文件等。 +4. Library Package为python源码包,包含了该项目的python代码。 + 如果项目有test相关的文件,也可以单独成包(可选) + +涉及本原则的项目有: + +* openstack-nova +* openstack-cinder +* openstack-glance +* openstack-placment +* openstack-ironic + +##### 2.1.1.2 特殊情况 + +有些openstack组件本身只包含一个服务,不存在子服务的概念,这种服务则只需要分为两级: + +``` + Level | Package | Example + | | + ┌─┐ | ┌──────────────┐ ┌────────────────────────┐ | ┌────────────────────────┐ ┌────────────────────────────┐ + │1│ | │ Root Package │ │ Doc Package (Optional) │ | │ openstack-keystone.rpm │ │ openstack-keystone-doc.rpm │ + └─┘ | └───────┬──────┘ └────────────────────────┘ | └────────────────────────┘ └────────────────────────────┘ + | | | + | ┌────────────┴───────────────────┐ | + ┌─┐ | ┌───────▼─────────┐ ┌────────────────▼────────────────┐ | ┌──────────────────────┐ ┌────────────────────────────┐ + │2│ | │ Library Package ◄-----| Library Test Package (Optional) │ | │ python2-keystone.rpm │ │ python2-keystone-tests.rpm │ + └─┘ | └─────────────────┘ └─────────────────────────────────┘ | └──────────────────────┘ └────────────────────────────┘ +``` + +1. Root Package RPM包包含了除python源码外的其他所有文件,包括服务启动文件、项目配置文件、系统配置文件等等。 + 如果项目有doc相关的文件,也可以单独成包(可选) +2. Library Package为python源码包,包含了该项目的python代码。 + 如果项目有test相关的文件,也可以单独成包(可选) + +涉及本原则的项目有: + +* openstack-keystone +* openstack-horizon + +还有些项目虽然有若干子RPM包,但这些子RPM包是互斥的,则这种服务的结构如下: + +``` +Level | Package | Example + | | + ┌─┐ | ┌──────────────┐ ┌────────────────────────┐ | ┌───────────────────────┐ ┌───────────────────────────┐ + │1│ | │ Root Package │ │ Doc Package (Optional) │ | │ openstack-neutron.rpm │ │ openstack-neutron-doc.rpm │ + └─┘ | └────────┬─────┘ └────────────────────────┘ | └───────────────────────┘ └───────────────────────────┘ + | │ | + | ┌─────────────────────┴───────────────────────────────┐ | + | │ | | + ┌─┐ | ┌────────▼─────────┐ ┌──────────────────┐ ┌──────────────────┐ | | ┌──────────────────────────────┐ ┌───────────────────────────────────┐ ┌───────────────────────────────────┐ + │2│ | │ Service1 Package │ │ Service2 Package │ │ Service3 Package │ | | │ openstack-neutron-server.rpm │ │ openstack-neutron-openvswitch.rpm │ │ openstack-neutron-linuxbridge.rpm │ + └─┘ | └────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘ | | └──────────────────────────────┘ └───────────────────────────────────┘ └───────────────────────────────────┘ + | | | | | | + | └────────────────────┼────────────────────┘ | | + | | | | + ┌─┐ | ┌───────▼────────┐ | | ┌──────────────────────────────┐ + │3│ | │ Common Package │ | | │ openstack-neutron-common.rpm │ + └─┘ | └───────┬────────┘ | | └──────────────────────────────┘ + | │ | | + | │ | | + | │ | | + ┌─┐ | ┌────────▼────────┐ ┌────────────────▼────────────────┐ | ┌─────────────────────┐ ┌───────────────────────────┐ + │4│ | │ Library Package ◄------| Library Test Package (Optional) │ | │ python2-neutron.rpm │ │ python2-neutron-tests.rpm │ + └─┘ | └─────────────────┘ └─────────────────────────────────┘ | └─────────────────────┘ └───────────────────────────┘ +``` + +如图所示,Service2和Service3互斥。 + +1. Root包只包含不互斥的子包,互斥的子包单独提供。 + 如果项目有doc相关的文件,也可以单独成包(可选) +2. Service Package为子服务RPM包,包含该服务的systemd服务启动文件、自己独有的配置文件等。 + 互斥的Service包不被Root包所包含,用户需要单独安装。 +3. Common Package是共用依赖的RPM包,包含各个子服务依赖的通用配置文件、系统配置文件等。 +4. Library Package为python源码包,包含了该项目的python代码。 + 如果项目有test相关的文件,也可以单独成包(可选) + +涉及本原则的项目有: + +* openstack-neutron + +#### 2.1.2 通用依赖类软件规范 + +一个依赖库一般只包含一个RPM包,不需要做拆分处理。 + +``` + Level | Package | Example + | | + ┌─┐ | ┌─────────────────┐ ┌────────────────────────┐ | ┌──────────────────────────┐ ┌───────────────────────────────┐ + │1│ | │ Library Package │ │ Help Package (Optional)│ | │ python2-oslo-service.rpm │ │ python2-oslo-service-help.rpm │ + └─┘ | └─────────────────┘ └────────────────────────┘ | └──────────────────────────┘ └───────────────────────────────┘ +``` + +**NOTE** + +openEuler社区对python2和python3 RPM包的命名有要求,python2的包前缀为*python2-*,python3的包前缀为*python3-*。因此,OpenStack要求开发者在打Library的RPM包时,也要遵守openEuler社区规范。 + +### 2.2 软件依赖功能 + +软件依赖分析功能为用户提供一键分析目标OpenStack版本包含的全量python软件依赖拓扑及对应软件版本的能力。并自动与目标openEuler版本进行比对,输出对应的软件包开发建议。本功能包含两个子功能: +- 依赖分析 + + 对OpenStack python包的依赖树进行解析,拆解依赖拓扑。依赖树本质上是对有向图的遍历,理论上,一个正常的python依赖树是一个有向无环图,有向无环图的解析方法很多,这里采用常用的广度优先搜索方法即可。但在某些特殊场景下,python依赖树会变成有向有环图,例如:Sphinx是一个文档生产项目,但它自己的文档生成也依赖Sphinx,这就导致了依赖环的形成。针对这种问题,我们只需要把环上的特定节点手动断开即可。类似的还有一些测试依赖库。另一种规避方法是跳过文档、测试这种非核心库,这样不仅避免了依赖环的形成,也会极大减少软件包的数量,降低开发工作量。以OpenStack Wallaby版本为例,全量依赖包大概在700+以上,去掉文档、测试后,依赖包大概是300+左右。因此我们引入`core`核心的概念,用户根据自己的需求,选择要分析的软件范围。另外虽然OpenStack包含服务几十个,但用户可能只需要其中的某些服务,因此我们另外引入`projects`过滤器,用户可以根据自己的需求,指定分析的软件依赖范围。 + +- 依赖比对 + 依赖分析完后,还要有对应的openEuler开发动作,因此我们还要提供基于目标openEuler版本的RPM软件包开发建议。openEuler与OpenStack版本之间有N:N的映射关系,一个openEuler版本可以支持多个OpenStack版本,一个OpenStack版本可以部署在多个openEuler版本上。用户在指定了目标openEuler版本和OpenStack版本后,本功能自动遍历openEuler软件库,分析并输出OpenStack涉及的全量软件包需要进行了操作,例如需要初始化仓库、创建openEuler分支、升级软件包等等。为开发者后续的开发提供指导。 + +#### 2.2.1 版本匹配规范 + +- 依赖分析 + + 输入:目标OpenStack版本、目标OpenStack服务列表、是否只分析核心软件 + + 输出:所有涉及的软件包及每个软件包的对应内容。格式如下: + + ``` + └──{OpenStack版本名}_cached_file + └──packageA.yaml + └──packageB.yaml + └──packageC.yaml + ...... + ``` + + 每个软件内容格式如下: + + ``` + { + "name": "packageA", + "version_dict": { + "version": "0.3.7", + "eq_version": "", + "ge_version": "0.3.5", + "lt_version": "", + "ne_version": [], + "upper_version": "0.3.7"}, + "deep": { + "count": 1, + "list": ["packageB", "packageC"]}, + "requires": {} + } + ``` + + 关键字说明 + | Key | Description | + |:-----------------:|:-----------:| + | name | 软件包名 | + | version_dict | 软件版本要求,包括等于、大于等于、小于、不等于,等等 | + | version_dict.deep | 表示该软件在全量依赖树的深度,以及深度遍历的路径 | + | requires | 包含本软件的依赖软件列表 | + + +- 依赖比对 + 输入:依赖分析结果、目标openEuler版本以及base比对基线 + + 输出:一个表格,包含每个软件的分析结果及处理建议,每一行表示一个软件,所有列名及定义规范如下: + + | Column | Description | + |:-----------------:|:-----------:| + | Project Name | 软件包名 | + | openEuler Repo | 软件在openEuler上的源码仓库名 | + | Repo version | openEuler上的源码版本 | + | Required (Min) Version | 要求的最小版本 | + | lt Version | 要求小于的版本| + | ne Version |要求的不等于版本| + | Upper Version |要求的最大版本| + | Status | 开发建议| + | Requires | 软件的依赖列表| + | Depth |软件的依赖树深度| + + 其中`Status`包含的建议有: + - “OK”:当前版本直接可用,不需要处理。 + - “Need Create Repo”:openEuler 系统中没有此软件包,需要在 Gitee 中的 src-openeuler repo 仓新建仓库。 + - “Need Create Branch”:仓库中没有所需分支,需要开发者创建并初始化。 + - “Need Init Branch”:表明分支存在,但是里面并没有任何版本的源码包,开发者需要对此分支进行初始化。 + - “Need Downgrade”:降级软件包。 + - “Need Upgrade”:升级软件包。 + + 开发者根据`Status`的建议进行后续开发动作。 + +#### 2.2.2 API和CLI定义 + +1. 创建依赖分析 + - CLI: `oos dependence analysis create` + + - endpoint: `/dependence/analysis` + + - type: POST + + - sync OR async: async + + - request body: + ``` + { + "release"[required]: Enum("OpenStack Relase"), + "runtime"[optional][Default: "3.10"]: Enum("Python version"), + "core"[optional][Default: False]: Boolean, + "projects"[optional][Default: None]: List("OpenStack service") + } + ``` + - response body: + ``` + { + "ID": UUID, + "status": Enum("Running", "Error") + } + ``` +2. 获取依赖分析 + - CLI: `oos dependence analysis show`、`oos dependence analysis list` + + - endpoint: `/dependence/analysis/{UUID}`、`/dependence/analysis` + + - type: GET + + - sync OR async: sync + + - request body: None + + - response body: + ``` + { + "ID": UUID, + "status": Enum("Running", "Error", "OK") + } + ``` + +3. 删除依赖分析 + - CLI: `oos dependence analysis delete` + + - endpoint: `/dependence/analysis/{UUID}` + + - type: DELETE + + - sync OR async: sync + + - request body: None + + - response body: + ``` + { + "ID": UUID, + "status": Enum("Error", "OK") + } + ``` + +4. 创建依赖比对 + - CLI: `oos dependence generate` + + - endpoint: `/dependence/generate` + + - type: POST + + - sync OR async: async + + - request body: + ``` + { + "analysis_id"[required]: UUID, + "compare"[optional][Default: None]: { + "token"[required]: GITEE_TOKEN_ID, + "compare-from"[optional][Default: master]: Enum("openEuler project branch"), + "compare-branch"[optional][Default: master]: Enum("openEuler project branch") + + } + } + ``` + - response body: + ``` + { + "ID": UUID, + "status": Enum("Running", "Error") + } + ``` + +5. 获取依赖比对 + - CLI: `oos dependence generate show`、`oos dependence generate list` + + - endpoint: `/dependence/generate/{UUID}`、`/dependence/generate` + + - type: GET + + - sync OR async: sync + + - request body: None + + - response body: + ``` + { + "ID": UUID, + "data" RAW(result data file) + } + ``` + +6. 删除依赖比对 + - CLI: `oos dependence generate delete` + + - endpoint: `/dependence/generate/{UUID}` + + - type: DELETE + + - sync OR async: sync + + - request body: None + + - response body: + ``` + { + "ID": UUID, + "status": Enum("Error", "OK") + } + ``` + +### 2.3 软件SPEC生成功能 +OpenStack依赖的大量python库是面向开发者的,这种库不对外提供用户服务,只提供代码级调用,其RPM内容构成单一、格式固定,适合使用工具化方式提高开发效率。 + +#### 2.3.1 SPEC生成规范 + +SPEC编写一般分为几个阶段,每个阶段有对应的规范要求: +1. 常规项填写,包括Name、Version、Release、Summary、License等内容,这些内容由目标软件的pypi信息提供 +2. 子软件包信息填写,包括软件包名、编译依赖、安装依赖、描述信息等。这些内容也由目标软件的pypi信息提供。其中软件包名需要有明显的python化显示,比如以`python3-`为前缀。 +3. 构建过程信息填写,包括%prep、%build %install %check内容,这些内容形式固定,生成对应rpm宏命令即可。 +4. RPM包文件封装阶段,本阶段通过文件搜索方式,把bin、lib、doc等内容分别放到对应目录即可。 + +**NOTE**:在通用规范外,也有一些例外情况,需要特殊说明: +1. 软件包名如果本身已包含`python`这样的字眼,不再需要添加`python-`或`python3-`前缀。 +2. 软件构建和安装阶段,根据软件本身的安装方式不同,宏命令包括`%py3_build`或`pyproject_build`,需要人工审视。 +3. 如果软件本身包含C语言等编译类代码,则需要移除`BuildArch: noarch`关键字,并且在%file阶段注意RPM宏`%{python3_sitelib}`和`%{python3_sitearch}`的区别。 + +#### 2.3.2 API和CLI定义 + +1. 创建SPEC + - CLI: `oos spec create` + + - endpoint: `/spec` + + - type: POST + + - sync OR async: async + + - request body: + ``` + { + "name"[required]: String, + "version"[optional][Default: "latest"]: String, + "arch"[optional][Default: False]: Boolean, + "check"[optional][Default: True]: Boolean, + "pyproject"[optional][Default: False]: Boolean, + } + ``` + - response body: + ``` + { + "ID": UUID, + "status": Enum("Running", "Error") + } + ``` + +2. 获取SPEC + - CLI: `oos spec show`、`oos spec list` + + - endpoint: `/spec/{UUID}`、 `/spec/` + + - type: GET + + - sync OR async: sync + + - request body: None + + - response body: + ``` + { + "ID": UUID, + "status": Enum("Running", "Error", "OK") + } + ``` + +3. 更新SPEC + - CLI: `oos spec update` + + - endpoint: `/spec/{UUID}` + + - type: POST + + - sync OR async: async + + - request body: + ``` + { + "name"[required]: String, + "version"[optional][Default: "latest"]: String, + } + ``` + + - response body: + ``` + { + "ID": UUID, + "status": Enum("Running", "Error") + } + ``` + +4. 删除SPEC + - CLI: `oos spec delete` + + - endpoint: `/spec/{UUID}` + + - type: DELETE + + - sync OR async: sync + + - request body: None + + - response body: + ``` + { + "ID": UUID, + "status": Enum("Error", "OK") + } + ``` + +### 2.4 自动化部署、测试功能 + +OpenStack的部署场景多样、部署流程复杂、部署技术门槛较高,为了解决门槛高、效率低、人力多的问题,openEuler OpenStack开发平台需要提供自动化部署、测试功能。 + +- 自动化部署 + + 提供基于openEuler的OpenStack的一键部署能力,包括支持不同架构、不同服务、不同场景的部署功能,提供基于不同环境快速发放、配置openEuler环境的能力。并提供`插件化`能力,方便用户扩展支持的部署后端和场景。 + +- 自动化测试 + + 提供基于openEuler的OpenStack的一键测试能力,包括支持不同场景的测试,提供用户自定义测试的能力,并规范测试报告,以及支持对测试结果上报和持久化的能力。 + +#### 2.4.1 自动化部署 + +自动化部署主要包括两部分:openEuler环境准备和OpenStack部署。 + +- openEuler环境准备 + + 提供快速发放openEuler环境的能力,支持的发放方式包括`创建公有云资源`和`纳管已有环境`,具体设计如下: + + ``` + **NOTE** + openEuler的OpenStack支持以RPM + systemd的方式为主,暂不支持容器方式。 + ``` + + - 创建公有云资源 + + 创建公有云资源以虚拟机支持为主(裸机在云上操作负责,生态满足度不足,暂不做支持)。采用插件化方式,提供多云支持的能力,以华为云为参考实现,优先实现。其他云的支持根据用户需求,持续推进。根据场景,支持all in one和三节点拓扑。 + 1. 创建环境 + - CLI: `oos env create` + + - endpoint: `/environment` + + - type: POST + + - sync OR async: async + + - request body: + ``` + { + "name"[required]: String, + "type"[required]: Enmu("all-in-one", "cluster"), + "release"[required]: Enmu("openEuler_Release"), + "flavor"[required]: Enmu("small", "medium", "large"), + "arch"[required]: Enmu("x86", "arm64"), + } + ``` + + - response body: + ``` + { + "ID": UUID, + "status": Enum("Running", "Error") + } + ``` + + 2. 查询环境 + - CLI: `oos env list` + + - endpoint: `/environment` + + - type: GET + + - sync OR async: async + + - request body: None + + - response body: + ``` + { + "ID": UUID, + "Provider": String, + "Name": String, + "IP": IP_ADDRESS, + "Flavor": Enmu("small", "medium", "large"), + "openEuler_release": String, + "OpenStack_release": String, + "create_time": TIME, + } + ``` + 3. 删除环境 + - CLI: `oos env delete` + + - endpoint: `/environment/{UUID}` + + - type: DELETE + + - sync OR async: sync + + - request body: None + + - response body: + ``` + { + "ID": UUID, + "status": Enum("Error", "OK") + } + ``` + + - 纳管已有环境 + + 用户还可以直接使用已有的openEuler环境进行OpenStack部署,需要把已有环境纳管到平台中。纳管后,环境与创建的项目,可以直接查询或删除。 + 1. 纳管环境 + - CLI: `oos env manage` + + - endpoint: `/environment/manage` + + - type: POST + + - sync OR async: sync + + - request body: + ``` + { + "name"[required]: String, + "ip"[required]: IP_ADDRESS, + "release"[required]: Enmu("openEuler_Release"), + "password"[required]: String, + } + ``` + + - response body: + ``` + { + "ID": UUID, + "status": Enum("Error", "OK") + } + ``` + +- OpenStack部署 + + 提供在已创建/纳管的openEuler环境上部署指定OpenStack版本的能力。 + 1. 部署OpenStack + - CLI: `oos env setup` + + - endpoint: `/environment/setup` + + - type: POST + + - sync OR async: async + + - request body: + ``` + { + "target"[required]: UUID(environment), + "release"[required]: Enmu("OpenStack_Release"), + } + ``` + + - response body: + ``` + { + "ID": UUID, + "status": Enum("Running", "Error") + } + ``` + + 2. 初始化OpenStack资源 + - CLI: `oos env init` + + - endpoint: `/environment/init` + + - type: POST + + - sync OR async: async + + - request body: + ``` + { + "target"[required]: UUID(environment), + } + ``` + + - response body: + ``` + { + "ID": UUID, + "status": Enum("Running", "Error") + } + ``` + + 3. 卸载已部署OpenStack + - CLI: `oos env clean` + + - endpoint: `/environment/clean` + + - type: POST + + - sync OR async: async + + - request body: + ``` + { + "target"[required]: UUID(environment), + } + ``` + + - response body: + ``` + { + "ID": UUID, + "status": Enum("Running", "Error") + } + ``` + +#### 自动化测试 + +环境部署成功后,SIG开发平台提供基于已部署OpenStack环境的自动化测试功能。主要包含以下几个重要内容: + +OpenStack本身提供一套完善的测试框架。包括`单元测试`和`功能测试`,其中`单元测试`在`2.3章节`中已经由RPM spec包含,spec的%check阶段可以定义每个项目的单元测试方式,一般情况下只需要添加`pytest`或`stestr`即可。`功能测试`由OpenStack Tempest服务提供,在上文所述的自动化部署`oos env init`阶段,oos会自动安装Tempest并生成默认的配置文件。 +- CLI: `oos env test` + +- endpoint: `/environment/test` + +- type: POST + +- sync OR async: async + +- request body: + ``` + { + "target"[required]: UUID(environment), + } + ``` + +- response body: + ``` + { + "ID": UUID, + "status": Enum("Running", "Error") + } + ``` + +测试执行完后,oos会输出测试报告,默认情况下,oos使用`subunit2html `工具,生成html格式的Tempest测试结果文件。 + +### 2.5 openEuler自动化开发功能 + +OpenStack涉及软件包众多,随着版本不断地演进、支持服务不断的完善,SIG维护的软件包列表会不断刷新,为了降低重复的开发动作,oos还封装了一些易用的代码开发平台自动化能力,比如基于Gitee的自动代码提交能力。功能如下: +``` + ┌───────────────────────────────────────────────────┐ + │ Code Action │ + └─────────────────────┬─────────────────────────────┘ + │ + ┌───────────────┼───────────────────┐ + │ │ │ + ┌─────▼─────┐ ┌──────▼──────┐ ┌─────────▼─────────┐ + │Repo Action│ │Branch Action│ │Pull Request Action│ + └───────────┘ └─────────────┘ └───────────────────┘ +``` + + +1. `Repo Action`提供与软件仓相关的自动化功能: + + 1. 自动建仓 + - CLI: `oos repo create` + + - endpoint: `/repo` + + - type: POST + + - sync OR async: async + + - request body: + ``` + { + "project"[required]: String, + "repo"[required]: String, + "push"[optional][Default: "False"]: Boolean, + } + ``` + + - response body: + ``` + { + "ID": UUID, + "status": Enum("Running", "Error") + } + ``` + + +2. `Branch Action`提供与软件分支相关的自动化功能: + + 1. 自动创建分支 + - CLI: `oos repo branch-create` + + - endpoint: `/repo/branch` + + - type: POST + + - sync OR async: async + + - request body: + ``` + { + "branches"[required]: { + "branch-name"[required]: String, + "branch-type"[optional][Default: "None"]: Enum("protected"), + "parent-branch"[required]: String + } + } + ``` + + - response body: + ``` + { + "ID": UUID, + "status": Enum("Running", "Error") + } + ``` + +3. `Pull Request Action`提供与代码PR相关的自动化功能: + + 1. 新增PR评论,方便用户执行类似`retest`、`/lgtm`等常规化评论。 + - CLI: `oos repo pr-comment` + + - endpoint: `/repo/pr/comment` + + - type: POST + + - sync OR async: sync + + - request body: + ``` + { + "repo"[required]: String, + "pr_number"[required]: Int, + "comment"[required]: String + } + ``` + + - response body: + ``` + { + "ID": UUID, + "status": Enum("OK", "Error") + } + ``` + + 2. 获取SIG所有PR,方便maintainer获取当前SIG的开发现状,提高评审效率。 + - CLI: `oos repo pr-fetch` + + - endpoint: `/repo/pr/fetch` + + - type: POST + + - sync OR async: async + + - request body: + ``` + { + "repo"[optional][Default: "None"]: List[String] + } + ``` + + - response body: + ``` + { + "ID": UUID, + "status": Enum("Running", "Error") + } + ``` + +## 3. 质量、安全与合规 +SIG开源软件需要符合openeEuler社区对其中软件的各种要求,并且也要符合OpenStack社区软件的出口标准。 + +### 3.1 质量与安全 + +- 软件质量(可服务性) + 1. 对应软件代码需包含单元测试,覆盖率不低于80%。 + 2. 需提供端到端功能测试,覆盖上述所有接口,以及核心的场景测试。 + 3. 基于openEuler社区CI,构建CI/CD流程,所有Pull Request要有CI保证代码质量,定期发布release版本,软件发布间隔不大于3个月。 + 4. 基于Gitee ISSUE系统处理用户发现并反馈的问题,闭环率大于80%,闭环周期不超过1周。 + +- 软件安全 + 1. 数据安全:软件全程不联网,持久存储中不包含用户敏感信息。 + 2. 网络安全:OOS在REST架构下使用http协议通信,但软件设计目标实在内网环境中使用,不建议暴露在公网IP中,如必须如此,建议增加访问IP白名单限制。 + 3. 系统安全:基于openEuler安全机制,定期发布CVE修复或安全补丁。 + 4. 应用层安全:不涉及,不提供应用级安全服务,例如密码策略、访问控制等。 + 5. 管理安全:软件提供日志生成和周期性备份机制,方便用户定期审计。 + +- 可靠性 + + 本软件面向openEuler社区OpenStack开发行为,不涉及服务上线或者商业生产落地,所有代码公开透明,不涉及私有功能及代码。因此不提供例如节点冗余、容灾备份能功能。 + +### 3.2 合规 +1. License合规 + + 本平台采用Apache2.0 License,不限制下游fork软件的闭源与商业行为,但下游软件需标注代码来源以及保留原有License。 + +2. 法务合规 + + 本平台由开源开发者共同开发维护,不涉及商业公司的秘密以及非公开代码。所有贡献者需遵守openEuler社区贡献准则,确保自身的贡献合规合法。SIG及社区本身不承担相应责任。 + + 如发现不合规的源码,SIG无需获取贡献者的允许,有权利及义务及时删除。并有权禁止不合规代码或开发者继续贡献。 + + 开发者如果有非公开代码需要贡献,则要先遵守本公司的开源流程与规定,并按照openEuler社区开源规范公开贡献代码。 + +## 4. 实施计划 + +| 时间 | 内容 | 状态| +|:-----------------:|:-----------:|:-----------:| +| 2021.06 | 完成软件整体框架编写,实现CLI Built-in机制,至少一个API可用 | Done | +| 2021.12 | 完成CLI Built-in机制的全量功能可用 | Done | +| 2022.06 | 完成质量加固,保证功能,在openEuler OpenStack社区开发流程中正式引入OOS | Done | +| 2022.12 | 不断完成OOS,保证易用性、健壮性,自动化覆盖度超过80%,降低开发人力投入 | Done | +| 2023.06 | 补齐REST框架、CI/CD流程,丰富Plugin机制,引入更多backend支持 | Working in progress | +| 2023.12 | 完成前端GUI功能 | Planning | diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/spec/priority_vm.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/spec/priority_vm.md new file mode 100644 index 0000000000000000000000000000000000000000..3599799f01f21125eaaf64dce67f4ac86060ea2f --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/OpenStack/spec/priority_vm.md @@ -0,0 +1,129 @@ + +# 高低优先级虚拟机混部 + +虚拟机混合部署是指把对CPU、IO、Memory等资源有不同需求的虚拟机通过调度方式部署、迁移到同一个计算节点上,从而使得节点的资源得到充分利用。在单机的资源调度分配上,区分出高低优先级,即高优先级虚机和低优先级虚机发生资源竞争时,资源优先分配给前者,严格保障其QoS。 + +虚拟机混合部署的场景有多种,比如通过动态资源调度满足节点资源的动态调整;根据用户使用习惯动态调整节点虚拟机分布等等。而虚拟机高低优先级调度也是其中的一种实现方法。 + +在OpenStack Nova中引入虚拟机高低优先级技术,可以一定程度上满足虚拟机的混合部署要求。本文档主要针对OpenStack Nova虚拟机创建功能,介绍虚拟机高低优先级调度的设计与实现。 + +## 实现方案 + +在Nova的虚拟机创建、迁移流程中引入高低优先级概念,虚拟机对象新增高低优先级属性。高优先级虚拟机在调度的过程中,会尽可能的调度到资源充足的节点,这样的节点需要至少满足内存不超卖、高优先级虚拟机所用CPU不超卖的要求。 + +本特性的实现基于OpenStack Yoga版本,承载于openEuler 22.09创新版本中。同时引入openEuler 22.03 LTS SP1的Train版本。 + +### 总体架构 + +用户创建flavor或创建虚机时,可指定其优先级属性。但优先级属性不影响Nova现有的资源模型及节点调度策略,即Nova仍按正常流程选取计算节点及创建虚机。 + +虚机高低优先级特性主要影响虚机创建后单机层面的资源调度分配策略。高优先级虚机和低优先级虚机发生资源竞争时,资源优先分配给前者,严格保障其QoS。 + +Nova针对虚机高低优先级特性有以下改变: +1. VM对象和flavor新增高低优先级属性配置。同时结合业务场景,约束高优先级属性只能设置给绑核类型虚机,低优先级属性只能设置给非绑核类虚机。 +2. 对于具有优先级属性的虚机,需修改libvirt XML配置,让单机上的QoS管理组件(名为Skylark)感知,从而自动进行资源分配和QoS管理。 +3. 低优先级虚机的绑核范围有改变,以充分利用高优先级虚机空闲的资源。 + +### 资源模型 + +* VM对象新增可选属性`priority`,`priority`可被设置成`high`或`low`,分别表示高低优先级。 + +* flavor extra_specs新增`hw:cpu_priority`字段,标识为高低优先级虚拟机规格,值为`high`或`low`。 + +参数限制及规则: + +1. `priority=high`必须与`hw:cpu_policy=dedicated`配套使用,否则报错。 +2. `priority=low`必须与`hw:cpu_policy=shared`(默认值)配套使用,否则报错。 +3. VM对象的优先级配置和flavor的优先级配置都为可选,都不配置时代表是普通VM,都配置时以VM对象的优先级属性为准。 + +普通VM可与具有优先级属性的VM共存,因为优先级属性不影响Nova现有的资源模型及节点调度策略。当普通VM与高优先级VM发生资源竞争时,Skylark组件不会干预。当普通VM与低优先级VM发生资源竞争时,Skylark组件会优先保障普通VM的资源分配。 + +### API + +创建虚拟机API中可选参数`os:scheduler_hints.priority`可被设置成`high`或`low`,用于设置VM对象的优先级。 + +``` +POST v2/servers (v2.1默认版本) +{ + "OS-SCH-HNT:scheduler_hints": {"priority": "high"} +} +``` + +### Scheduler + +保持不变 + +### Compute + +#### 资源上报 + +保持不变 + +#### 资源分配绑定 + +高低优先级机器创建按照priority标志分配CPU: + +* 高优先级虚拟机只能是绑核类型虚机,一对一绑定`cpu_dedicated_set`中指定CPU +* 低优先级虚拟机只能是非绑核类型虚机,默认范围绑定`cpu_shared_set`中指定的CPU。 + +此外,`nova.conf`的`compute`块中新增配置项`cpu_priority_mix_enable`,默认值为False。设置为True后,低优先级虚拟机可使用高优先级的虚拟机绑定的CPU,即低优先级虚拟机可范围绑定`cpu_shared_set`与`cpu_dedicated_set`指定的CPU。 + +#### 虚拟机xml + +高低优先级机器创建按照priority标志,对虚拟机进行标识。 + +* Libvirt XML中新增属性``片段,包括 `/high_prio_machine`、`/low_prio_machine`两种值,分别表示高低优先级虚拟机。该片段本身在Nova中没有任何作用,只是为`Skylark`QoS服务指明VM的高低优先级属性。 + + +### 举例 + +假设一个compute节点拥有14个core,设置cpu_dedicated_set=0-11,一共12个核,cpu_shared_set=12-13,一共2个核心,cpu_allocation_ratio=8 则: + +1. 高优VM在scheduler视角可用core为12,compute视角可绑核core也是12,与Nova原有逻辑一致。 +2. 低优VM在scheduler视角可用core为2 \* 8 = 16,compute视角可绑核core为2(当cpu_priority_mix_enable=False),与Nova原有逻辑一致。 +3. 低优VM在scheduler视角可用core为2 \* 8 = 16,compute视角可绑核core为2+12(当cpu_priority_mix_enable=True),与Nova原有逻辑有差异。 + +### 参数配置建议 + +先确定全局超分比和极端超分比。 + + 全局超分比的定义:所有可分配vCPU数量(高和低总和)与所有可用物理core数量的比值,这是一个计算出来的理论值,比如上述举例中,全局超分比为 (12 + 2 \* 8) / 14 = 2。 + 全局超分比的意义:在高低优先级场景下,全局超分比主要影响低优先级虚机一般条件下(高优先级虚机vCPU没有同时冲高)的QoS。设置合理的全局超分比可以减少底层资源充足但调度失败的情况出现。 + + 极端超分比的定义:即cpu_allocation_ratio。只影响share核心的超分能力。 + 极端超分比的意义:在高低优先级场景下,极端超分比主要影响低优先级虚机极端条件下(所有高优先级虚机vCPU同时冲高)的QoS。 + +用户结合业务特征及QoS目标,选择合适的全局超分比和极端超分比后,然后按照下面的计算公式,配置合理的cpu_dedicated_set及cpu_shared_set。 + 计算公式: + + ``` + 用户期望的全局超分比 = (极端超分比 * shared核心数 + dedicated核心数) / compute所有核心数 + ``` + + 还是以上述compute节点为例,compute所有核心数为14,假设极端超分比为8,则计算可得: + + ``` + 当dedicated核心数为12时,shared核心数为2时,用户期望的全局超分 = (8*2+12)/14 = 2 + + 当dedicated核心数为4时,shared核心数为10时,用户期望的全局超分 = (8*10+4)/14 = 6 + ``` + + +## 开发节奏 + +开发者: + +* 王玺源 +* 郭雷 +* 马干林 +* 韩光宇 +* 张迎 +* 张帆 + +时间点: + +* 2022-04-01到2022-05-30 完成开发 +* 2022-06-01到2022-07-30 测试、联调、刷新代码 +* 2022-08-01到2022-08-30 完成RPM包构建 +* 2022-09-30引入openEuler 22.09 Yoga版本 +* 2022-12-30引入openEuler 22.03 LTS SP1 Train版本 diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/Install_StratoVirt.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/Install_StratoVirt.md new file mode 100644 index 0000000000000000000000000000000000000000..2f7484246f5d6cb02564cb647e69980ce05b3121 --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/Install_StratoVirt.md @@ -0,0 +1,32 @@ +# 安装StratoVirt + +## 软硬件要求 + +### 最低硬件要求 + +- 处理器架构:仅支持AArch64和x86_64处理器架构。AArch64需要ARMv8及更高版本且支持虚拟化扩展;x86_64支持VT-x。 + +- 2核CPU +- 4GiB内存 +- 16GiB可用磁盘空间 + +### 软件要求 + +操作系统:openEuler 21.03 + +## 安装组件 + +使用StratoVirt虚拟化,需要安装StratoVirt。安装前,请确保已经配置了openEuler yum源。 + +1. 使用root权限,安装StratoVirt组件,参考命令如下。 + + ```shell + # yum install stratovirt + ``` + +2. 查看是否安装成功。 + + ```shell + $ stratovirt -version + StratoVirt 2.1.0 + ``` diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/Interconnect_libvirt.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/Interconnect_libvirt.md new file mode 100644 index 0000000000000000000000000000000000000000..d0afd0f4f75a3d67890f17f1b3b540d0895858cf --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/Interconnect_libvirt.md @@ -0,0 +1,683 @@ +# 对接 libvirt + +## 概述 + +libvirt 是一个管理 hypervisor 的上层软件,它通过不同的驱动统一管理不同类型的 hypervisor ,并对外提供统一、稳定的应用程序接口。 + +在云场景中,业内广泛使用 libvirt 管理大规模的虚拟机。为了方便地对大规模的 StratoVirt 虚拟机进行部署、编排和管理,StratoVirt 标准虚拟化支持对接 libvirt,打通了 libvirt 北向接口。用户可以通过 libvirt 对应的 XML 文件描述一个虚拟机,包括虚拟机名称、CPU、磁盘等。 + +本章介绍 StratoVirt 平台支持的 XML 配置,以及如何使用 virsh 命令管理虚拟机。 + +## 前提条件 + +StratoVirt 对接 libvirt,主机需要满足如下条件: + +- 已正确配置 yum 源 +- 已正确安装并启动 libvirt +- 已正确安装 StratoVirt + +## 虚拟机配置 + +libvirt 工具采用 XML 格式的文件描述一个虚拟机特征,包括虚拟机名称、CPU、内存、磁盘、网卡等信息。用户可以通过修改配置文件,对虚拟机进行管理。 + +StratoVirt 对接 libvirt 之前,需要先配置 XML 文件。本小节介绍 StratoVirt 对接 libvirt 时支持的 XML 配置项以及配置方式。 + +> ![](./public_sys-resources/icon-note.gif)**说明** +> +> 使用 libvirt 管理 StratoVirt 虚拟机前,应该注意到 StratoVirt 当前支持的特性、特性之间的互斥关系、特性的配置前提条件、规格等,详细信息请参见命令行方式的 "虚拟机配置”章节。 + +### 虚拟机描述 + +虚拟机 XML 文件必须包含描述虚拟机的最基本元素: domain 和 name 。 + +#### 元素介绍 + +- domain : 虚拟机配置的根元素,用于配置运行 StratoVirt 虚拟机的 hypervisor 类型。 + + 属性 type :domain 的类型,在 StratoVirt 虚拟化中,该值为 kvm 。 + +- name :虚拟机名称。 + + 虚拟机名称是一个长度不超过 255 字符的字符串。同一个主机上的虚拟机名称不能重复,虚拟机名称必须由数字、字母、“_”、“-”、“:” 组成。 + +#### 配置示例 + +假设配置虚拟机名称为 StratoVirt ,示例为: + +```xml + + StratoVirt + ... + +``` + +### 虚拟CPU和内存 + +本节介绍虚拟 CPU 和虚拟内存的配置。 + +#### 元素介绍 + +- vcpu:虚拟处理器的个数。 + +- memory:虚拟内存大小。 + + 属性 unit :指定内存单位,属性值支持 KiB(210 字节)、MiB(220 字节)、GiB(230 字节)、TiB(240 字节)等。 + + > ![](./public_sys-resources/icon-note.gif)**说明** + > + > StratoVirt 暂不支持 CPU 拓扑结构,请勿配置该项。 + +#### 配置示例 + +配置 8GiB 内存,4 个虚拟处理器的示例如下: + +```xml + + ... + 4 + 8 + ... + +``` + +### 虚拟机设备 + +本节介绍如何使用 XML 文件配置虚拟机设备:磁盘,网卡,rng,balloon,console,vsock 设备。 + +#### 磁盘 + +##### 元素介绍 + +- 属性 type :指定后端存储介质类型,在 StratoVirt 虚拟化中,该值为 file 。 + + 属性 device:呈现给虚拟机的存储介质类型,在 StratoVirt 虚拟化中,该值为 disk 。 + +- driver:指定后端驱动的详细信息。 + + 属性 type :磁盘的格式类型,在 StratoVirt 虚拟化中,该值为 raw 。StratoVirt 当前只支持 raw 格式的磁盘。 + + 属性 iothread:为磁盘配置 iothread ,取值为 iothread 编号。在配置磁盘的 iothread 之前,需使用 iothread 元素配置 iothread 的个数。 + +- source: 指定后端存储介质。 + + 属性 file:指定磁盘路径。 + +- target:指定后端驱动的详细信息。 + + 属性 dev:指定磁盘名称。 + + 属性 bus:指定磁盘设备的类型,在 StratoVirt 虚拟化中,该值为 virtio 。 + +- iotune: 指定磁盘 IO 特性。 + + 属性 total_iops_sec:设置磁盘 iops 的值。 + +- address:用于设置设备所要挂载的总线属性。 + + 属性 type:总线类型,在 StratoVirt 虚拟化中,该值为 pci 。 + + 属性 domain:虚拟机的域。 + + 属性 bus:设备将要挂载的 bus 号。 + + 属性 slot:设备将要挂载的 slot 号,取值范围为:[0, 31] 。 + + 属性 function:设备将要挂载的 function 号,取值范围为:[0, 7] 。 + +##### 配置示例 + +配置磁盘路径为:`/home/openEuler-21.09-stratovirt.img`,配置 1 个 iothread,并且磁盘 iothread 配置为 iothread1 ,iops 为 10000,并将其挂载在 bus 为 1、slot 为 0,function 为 0 的 PCI 总线上,示例为: + +```xml + + ... + 1 + + + + + + + 10000 + +
+ + ... + + +``` + +#### 网络设备 + +##### 元素介绍 + +- interface:网络接口 + + 属性 type:指定网络设备类型。 + +- mac:虚拟网卡地址 + + 属性 address:虚拟网卡地址。 + +- source: 指定后端网桥 + + 属性 bridge:指定网桥。 + +- target:指定后端网卡 + + 属性 dev:指定后端的 tap 设备。 + +- model: 虚拟网卡类型 + + 属性 type: 虚拟网卡类型,在 StratoVirt 虚拟化中,该值为 virtio。 + +- driver:用来指定是否开启 vhost 。 + + 属性 name:如果设置 name 为 qemu 则使用 virtio-net 设备,如果不配置 driver 或者 name 值为 vhost ,则使用 vhost-net 设备。 + +##### 配置示例 + +配置网络前请参考 [配置linux网桥](https://docs.openeuler.org/zh/docs/20.03_LTS_SP2/docs/Virtualization/%E5%87%86%E5%A4%87%E4%BD%BF%E7%94%A8%E7%8E%AF%E5%A2%83.html#%E5%87%86%E5%A4%87%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%BD%91%E7%BB%9C),配置好 Linux 网桥。配置 mac 地址为:`de:ad:be:ef:00:01`,网桥为配置好的 br0 ,使用 virtio-net 设备,并将其挂载在 bus 为 2、slot 为 0,function 为 0 的 PCI 总线上,示例为: + +```xml + + ... + + + + + + +
+ + ... + + +``` + +#### balloon 设备 + +##### 元素介绍 + +- memballoon:balloon 设备类型 + + 属性 model :指定 balloon 设备类型,在 StratoVirt 虚拟化中,该值为 virtio 。 + +- alias:balloon 设备的别名 + + 属性 name :balloon 设备的 id 。 + + 属性 autodeflate :设置 auto deflate(自动收缩)特性,可选值为:`on` 、`off` 。 + +##### 配置示例 + +配置 balloon 设备,开启 autodeflate 特性,并将其挂载在 bus 为 3、slot 为 0,function 为 0 的 PCI 总线上,示例为: + +```xml + + ... + + + + +
+ + ... + + +``` + +#### console 设备 + +由于 console 设备挂载在 virtio-serial 下的总线上,所以在创建 console 设备时,需要创建 virtio-serial 设备。 + +> ![](./public_sys-resources/icon-note.gif)**说明** +> +> StratoVirt 的 console 设备暂时不支持多端口特性,每个虚拟机只能配置一个 console 设备。 + +##### 元素介绍 + +- controller:控制器 + + 属性 type:控制器类型,此处值为 virtio-serial 。 + +- alias:别名 + + 属性 name:设备的 id。 + +- console:console 设备 + + 属性 type:指定 console 设备的重定向方式。支持的重定向方式有:pty , file 和 unix 。 + +- target:配置 console 设备。 + + 属性 type:指定 console 设备类型,在 StratoVirt 虚拟化中,该值为 virtio 。 + +##### 配置示例 + +配置重定向方式为 pty ,并将其挂载在 bus 为 4、slot 为 0,function 为 0 的 PCI 总线上,示例为: + +```xml + + ... + + + +
+ + + + + + ... + + +``` + +#### rng 设备 + +##### 元素介绍 + +- rng:rng 设备 + + 属性 model:指定 rng 设备类型,在 StratoVirt 虚拟化中,该值为 virtio 。 + +- rate:rng 设备产生随机数速率 + + 属性 period :用于设置随机数产生周期,单位为毫秒,当前 StratoVirt 不支持设置周期值,缺省值为 1000 毫秒,请将该值设置为 1000。 + + 属性 bytes :周期内产生的最大字节数。 + +- backend:设置 rng 设备后端,值为 host 中 rng 设备的路径 + + 属性 model:用于指定后端设备类型,在 StratoVirt 虚拟化中,该值为 random 。 + +##### 配置示例 + +配置周期为 1000ms 内最多产生 1234 字节,rng 设备在 host 中路径为 `/dev/random` ,并将其挂载在 bus 为 5、slot 为 0,function 为 0 的 PCI 总线上,示例为: + +```xml + + ... + + + + /dev/random +
+ + ... + + +``` + +#### vsock 设备 + +##### 元素介绍 + +- vsock:vsock 设备 + + 属性 model:指定 vsock 设备类型,在 StratoVirt 虚拟化中,该值为 virtio 。 + +- cid :设置 vsock 设备的 cid + + 属性 address:用于设置 cid 的值 + +##### 配置示例 + +配置 cid 为 8,并将其挂载在 bus 为 6、slot 为 0,function 为 0 的 PCI 总线上,示例为: + +```xml + + ... + + + +
+ + ... + + +``` + +#### 体系架构相关配置 + +XML 中还有一些体系架构相关的配置,如 pflash、主板等。 + +##### 元素介绍 + +- os:定义虚拟机启动参数 + + 子元素 type :指定虚拟机类型,属性 arch 表示架构,属性 machine 表示主板类型,在 StratoVirt 虚拟化中,AArch64 架构只支持 virt 主板,x86_64 架构只支持 Q35 主板。 + + 子元素 kernel :用于指定 kernel 路径。 + + 子元素 cmdline :指定命令行启动参数。 + + 子元素 loader :指定加载固件,属性 readonly 表示是否只读;属性 type 表示类型,在 StratoVirt 虚拟化中,该值为 pflash 。 + +- features:hypervisor 支持的以下特性 + + 子元素 acpi :是否支持 ACPI,在 StratoVirt 虚拟化中使用了 ACPI 特性,所以该特性必须配置。 + + 子元素 gic :ARM 处理器指定中断处理器,属性 version 表示 GIC 的版本,在 StratoVirt 虚拟化中,该值为 3 。 + +##### 配置示例 + +配置虚拟机 CPU 架构 ARM,主板为 virt ,启动命令行为:`console=ttyAMA0 root=/dev/vda reboot=k panic=1 rw` 。pflash 路径为:`/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw`,属性为只读。 kernel 路径为:`/home/std-vmlinuxz`。示例为: + +```xml + + ... + + hvm + /home/std-vmlinuxz + console=ttyAMA0 root=/dev/vda reboot=k panic=1 rw + `/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw` + + ... + +``` + +#### 内存大页 + +##### 元素介绍 + +- memoryBacking:表示配置内存相关的信息 + +- hugepages :配置内存大页 + +- page :大页配置 + + 属性 size :内存大页的大小 + + 属性 unit :大页大小的单位 + +##### 配置示例 + +配置 2MiB 大页示例如下: + +```xml + + ... + + + + + + ... + +``` + +### 配置示例 + +#### x86 配置示例 + +配置一台名为 StratoVirt ,内存 8GiB ,配置 1GiB 单位的内存大页,4 个虚拟 CPU,架构为 x86_64 ,主板类型为 Q35 ,对应 XML 文件的配置示例如下: + +```xml + + StratoVirt + 8 + + + + + + + 4 + + 1 + + hvm + /path/to/standard_vm_kernel + console=hvc0 root=/dev/vda reboot=k panic=1 rw + /path/to/pflash + /path/to/OVMF_VARS + + + + + + /path/to/StratoVirt_binary_file + + + + + + + + + + + + + + + + 1000 + +
+ + + + + + +
+ + + + +
+ + + + + + + + +
+ + + + + /path/to/random_file +
+ + + + +
+ + + +``` + +#### ARM 配置示例 + +如果想要配置一台名为 StratoVirt ,内存 8GiB,配置 1GiB 单位大页,4 个虚拟 CPU,架构为 aarch64 ,主板类型为 virt ,对应 XML 文件的配置示例如下: + +```xml + + StratoVirt + 8 + + + + + + + 4 + + 1 + + hvm + /path/to/standard_vm_kernel + console=ttyAMA0 root=/dev/vda reboot=k panic=1 rw + /path/to/pflash + + + + + + + /path/to/StratoVirt_binary_file + + + + + + +
+ + 1000 + + + + + + + +
+ + + + +
+ + + + + + + + +
+ + + + + /path/to/random_file +
+ + + + +
+ + + +``` + +## 管理虚拟机 + +libvirt 使用 virsh 命令来管理虚拟机,当 StratoVirt 平台和 libvirt 对接时,仅支持以下与 StratoVirt 交互的命令: + +- create:创建虚拟机 + +- suspend:挂起虚拟机 + +- resume:恢复虚拟机 + +- destroy:销毁虚拟机 + +- console:通过 console 登录虚拟机 + +- define:根据 xml 配置创建一个虚拟机 + +- undefine:删除一个已定义的虚拟机 + +- start:启动一个关闭状态的虚拟机 + +> ![](./public_sys-resources/icon-note.gif)**说明** +> +> 目前已经在 libvirt 中实现对接 StratoVirt 的接口(暂不支持关机,重启等命令)。使用 virsh -c stratovirt:///system 'command' 即可调用 libvirt 中的 StratoVirt_driver 接口,同时,可以使用 virsh -c stratovirt:///system 进入 virsh 命令行,此时连接为 stratovirt_driver 。 + +### 管理虚拟机生命周期 + +假设用户已经按照需要完成一个名为 StratoVirt 的虚拟机配置文件 st.xml ,则对应生命周期管理的命令如下: + +- 创建虚拟机 + + ```shell + virsh create st.xml + /// + virsh -c stratovirt:///system create st.xml + ``` + + 虚拟机创建完成后,可以通过 **virsh list**/**virsh -c stratovirt:///system list** 命令查看,会存在一个名为 StratoVirt 且状态为 running 的虚拟机。 + +- 根据 xml 配置创建一个虚拟机 + + ```shell + virsh define st.xml + /// + virsh -c stratovirt:///system define st.xml + ``` + + 虚拟机创建完成后,可以通过 **virsh list**/**virsh -c stratovirt:///system list** 命令查看,会存在一个名为 StratoVirt 且状态为 shut off 的虚拟机。 + +- 启动一个关闭状态的虚拟机 + + ```shell + virsh start StratoVirt + /// + virsh -c stratovirt:///system start StratoVirt + ``` + + 虚拟机启动后,可以通过 **virsh list**/**virsh -c stratovirt:///system list** 命令查看,虚拟机 StratoVirt 的状态从 shut off 变为 running。 + +- 挂起虚拟机 + + ```shell + virsh suspend StratoVirt + /// + virsh -c stratovirt:///system suspend StratoVirt + ``` + + 虚拟机挂起后,虚拟机暂停运行。可以通过 **virsh list**/**virsh -c stratovirt:///system list** 命令查看,虚拟机 StratoVirt 的状态为 paused 。 + +- 恢复虚拟机 + + ```shell + virsh resume StratoVirt + /// + virsh -c stratovirt:///system resume StratoVirt + ``` + + 虚拟机恢复后,可以通过 **virsh list**/**virsh -c stratovirt:///system list** 命令查看,虚拟机 StratoVirt 的状态为 running 。 + +- 销毁虚拟机 + + ```shell + virsh destroy StratoVirt + /// + virsh -c stratovirt:///system destroy StratoVirt + ``` + + 虚拟机销毁后,使用 **virsh list**/**virsh -c stratovirt:///system list** 查看虚拟机,发现虚拟机 StratoVirt 不存在。 + +- 删除一个已定义的虚拟机 + + ```shell + virsh undefine StratoVirt + /// + virsh -c stratovirt:///system undefine StratoVirt + ``` + + 删除一个已定义的虚拟机后,使用 **virsh list**/**virsh -c stratovirt:///system list** 查看虚拟机,shut off 状态的虚拟机 StratoVirt 不存在,如果虚拟机 StratoVirt 为 running 状态,则在销毁虚拟机 StratoVirt 后,虚拟机 StratoVirt 不再进入 shut off 状态。 + +### 登录虚拟机 + +虚拟机创建完成后,可以通过 **virsh console**/**virsh -c stratovirt:///system console** 登录虚拟机内部操作虚拟机。假设虚拟机名称为 StratoVirt,参考命令如下: + +```shell +virsh console StratoVirt +/// +virsh -c stratovirt:///system console StratoVirt +``` + +> ![](./public_sys-resources/icon-note.gif)**说明** +> +> 为了可以正常使用 virsh console 命令,需要在 XML 中配置 console 设备的重定向类型为 pty 。 diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/Prepare_env.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/Prepare_env.md new file mode 100644 index 0000000000000000000000000000000000000000..f0d90e4ce597d59807a7a0a51230b1a4eecc657f --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/Prepare_env.md @@ -0,0 +1,166 @@ +# 准备环境 + +## 使用说明 + +- StratoVirt仅支持运行于x86_64和AArch64处理器架构下并启动相同架构的Linux虚拟机。 +- 建议在 openEuler 22.03 LTS 版本编译、调测和部署该版本 StratoVirt。 +- StratoVirt支持以非root权限运行。 + +## 环境要求 + +运行StratoVirt需要具备如下环境: + +- /dev/vhost-vsock设备(用于实现mmio) +- nmap工具 +- Kernel镜像和rootfs镜像 + +## 准备设备和工具 + +- StratoVirt运行需要实现mmio设备,所以运行之前确保存在设备`/dev/vhost-vsock` + + 查看该设备是否存在: + + ```shell + $ ls /dev/vhost-vsock + /dev/vhost-vsock + ``` + + 若该设备不存在,请执行如下命令生成/dev/vhost-vsock设备。 + + ```shell + $ modprobe vhost_vsock + ``` + +- 为了能够使用QMP命令,需要安装nmap工具,在配置yum源的前提下,可执行如下命令安装nmap。 + + ```shell + # yum install nmap + ``` + +## 准备镜像 + +### 制作kernel镜像 + +当前版本的StratoVirt仅支持x86_64和AArch64平台的PE格式内核镜像。此格式内核映像可通过以下方法生成。 + +1. 获取openEuler的kernel源代码,参考命令如下: + + ```shell + $ git clone https://gitee.com/openeuler/kernel.git + $ cd kernel + ``` + +2. 查看并切换kernel的版本到openEuler-22.03-LTS,参考命令如下: + + ```shell + $ git checkout openEuler-22.03-LTS + ``` + +3. 配置并编译Linux kernel。目前有两种方式可以生成配置文件:1. 使用推荐配置([获取配置文件](https://gitee.com/openeuler/stratovirt/tree/master/docs/kernel_config)),将指定版本的推荐文件复制到kernel路径下并重命名为`.config`, 并执行命令`make olddefconfig`更新到最新的默认配置(否则后续编译可能有选项需要手动选择)。2. 通过以下命令进行交互,根据提示完成kernel配置,可能会提示缺少指定依赖,按照提示使用`yum install`命令进行安装。 + + ```shell + $ make menuconfig + ``` + +4. 使用下面的命令制作并转换kernel镜像为PE格式,转化后的镜像为vmlinux.bin。 + + ```shell + $ make -j vmlinux && objcopy -O binary vmlinux vmlinux.bin + ``` + +5. 如果想在x86平台使用bzImage格式的kernel,可以使用如下命令进行编译。 + + ```shell + $ make -j bzImage + ``` + + ​ + +## 制作rootfs镜像 + +rootfs镜像是一种文件系统镜像,在StratoVirt启动时可以装载带有init的ext4格式的镜像。下面是制作ext4 rootfs镜像的简单方法。 + +1. 准备一个大小合适的文件(例如在/home中创建10GiB空间大小的文件)。 + + ```shell + $ cd /home + $ dd if=/dev/zero of=./rootfs.ext4 bs=1G count=10 + ``` + +2. 在此文件上创建空的ext4文件系统。 + + ```shell + $ mkfs.ext4 ./rootfs.ext4 + ``` + +3. 挂载文件镜像。创建/mnt/rootfs,使用root权限,将rootfs.ext4挂载到/mnt/rootfs目录。 + + ```shell + $ mkdir /mnt/rootfs + # 返回刚刚创建文件系统的目录(如/home) + $ cd /home + $ sudo mount ./rootfs.ext4 /mnt/rootfs && cd /mnt/rootfs + ``` + +4. 获取对应处理器架构的最新alpine-mini rootfs。 + + - 对于AArch64处理器架构,从[alpine](http://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/)网站获取最新alpine-mini rootfs,例如:alpine-minirootfs-3.21.0-aarch64.tar.gz ,参考命令如下: + + ```shell + $ wget http://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/aarch64/alpine-minirootfs-3.21.0-aarch64.tar.gz + $ tar -zxvf alpine-minirootfs-3.21.0-aarch64.tar.gz + $ rm alpine-minirootfs-3.21.0-aarch64.tar.gz + ``` + + - 对于x86_64处理器架构,从[alpine](http://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/)网站获取指定架构最新alpine-mini rootfs,例如:alpine-minirootfs-3.21.0-x86_64.tar.gz,参考命令如下: + + ```shell + $ wget http://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/x86_64/alpine-minirootfs-3.21.0-x86_64.tar.gz + $ tar -zxvf alpine-minirootfs-3.21.0-x86_64.tar.gz + $ rm alpine-minirootfs-3.21.0-x86_64.tar.gz + ``` + +5. 为ext4文件镜像制作一个简单的/sbin/init,参考命令如下: + + ```shell + $ rm sbin/init; touch sbin/init && cat > sbin/init < /sys/bus/pci/devices/0000:03:00.0/driver/unbind + ``` + + 最后将该 PCI 设备重新绑定到 vfio-pci 驱动。 + + ```shell + lspci -ns 0000:03:00.0 |awk -F':| ' '{print 5" "6}' > /sys/bus/pci/drivers/vfio-pci/new_id + ``` + + 将网卡绑定到 vfio-pci 驱动后,在主机上无法查询到对应网卡信息,只能查询到对应的 PCI 设备信息。 + +### VFIO 设备直通 + +#### 简介 + +VFIO(Virtual Function I/O) 是内核提供的一种用户态设备驱动方案。VFIO 驱动可以安全地把设备 I/O,中断,DMA 等能力呈现给用户空间。StratoVirt 虚拟化平台使用 VFIO 设备直通方案后,在虚拟机可以极大限度地提升 I/O 性能。 + +#### 使用 VFIO 直通 + +StratoVirt 支持 libvirt 管理,可以使用 XML 文件配置虚拟机。以下内容介绍通过修改虚拟机 XML 文件的方式,使用 VFIO 设备直通功能。 + +一、修改 XML 文件 + +1. 在主机上执行如下命令,查询 CPU 架构信息 + + ```shell + # uname -m + ``` + +2. aarch64 和 x86_64 架构分别[下载](https://gitee.com/openeuler/stratovirt/tree/master/docs) StratoVirt 自带的 XML 文件 stratovirt_aarch64.xml 或 stratovirtvirt_x86.xml,并存放到任一目录,例如 /home: + + ```shell + # cp stratovirt/docs/stratovirt_$arch.xml /home + ``` + +3. 根据实际需求,修改XML文件中的VFIO配置。 bus,slot,function 为上述绑定到 vfio-pci 驱动的 PCI 设备。相关配置如下: + + ```shell + + + + +
+ + + ``` + + 上例中,设备类型为 PCI 设备,managed='yes' 表示 libvirt 将把 PCI 设备从主机解绑,并重新绑定到 vfio-pci 驱动。source 项配置了需要作为 VFIO 直通设备的 domain,bus,slot,function 信息。 + +二、使用 libvirt 命令行创建并登录虚拟机 + +```shell +# virsh create stratovirt_$arch.xml +# virsh list --all +Id Name State +-------------------- +1 StratoVirt running +# virsh console 1 +``` + +三、在虚拟机内查看并使用 VFIO 直通网卡。 + +1. 配置前查看网卡信息 + + ```shell + # ip a + 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + inet 127.0.0.1/8 scope host lo + valid_lft forever preferred_lft forever + 2: enp1s0: mtu 1500 qdisc noop state DOWN group default qlen 1000 + link/ether 72:b8:51:9d:d1:27 brd ff:ff:ff:ff:ff:ff + ``` + +2. 动态配置网卡的 IP 地址 + + ```shell + # dhclient + ``` + +3. 查询 IP 是否配置成功 + + ```shell + # ip a + 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + inet 127.0.0.1/8 scope host lo + valid_lft forever preferred_lft forever + 2: enp1s0: mtu 1500 qdisc mq state UP group default qlen 1000 + link/ether 72:b8:51:9d:d1:27 brd ff:ff:ff:ff:ff:ff + inet 192.168.1.3/16 brd 192.168.255.255 scope global dynamic enp1s0 + valid_lft 86453sec preferred_lft 86453sec + ``` + + 如上回显可知,成功分配了 IP 地址 192.168.1.3,虚拟机可以直接使用配置的网卡 + + 说明:使用的直通网卡如果没有连接物理网络,将获取不到网络信息。 + +#### 解绑 VFIO 驱动 + +如果需要将直通给虚拟机使用的网卡解除绑定,可以登录主机,执行如下命令,将网卡设备重新绑定到主机上。其中,hinic是对应网卡设备驱动的类型: + +```shell +# echo 0000:03:00.0 > /sys/bus/pci/drivers/vfio-pci/unbind +# echo 0000:03:00.0 > /sys/bus/pci/drivers/hinic/bind +``` + +说明:绑定 VFIO 驱动前,可以再主机上执行 ethtool -i enp0 命令,获取网卡设备驱动类型。enp0 为对应网卡名称。 + +### SR-IOV 直通 + +#### 简介 + +使用 VFIO 设备直通时,虚拟机能直接访问硬件,但每个设备只能被一个虚拟机独占。SR-IOV 直通技术支持将一个 PF(Physical Function) 虚拟出多个 VF (Virtual Function),并直通给不同虚拟机,解决了设备直通的独占问题,增加可用的设备。 + +#### 操作步骤 + +1. 创建多个 VF: + + sriov_numvfs 文件用于描述 SR-IOV 提供的 VF 个数,存放在 /sys/bus/pci/devices/domain\:bus\:slot.function/ 路径下,例如上述例子中的 bus 号 03,slot 号 00,function 号 0 的设备,可以使用如下命令创建4个 VF: + + ```shell + # echo 4 > /sys/bus/pci/devices/0000\:03\:00.0/sriov_numvfs + ``` + +2. 确认 VF 设备创建成功 + + ```shell + # lspci -v | grep "Eth" | grep 1822 + ``` + + 回显如下,说明成功创建了4个 VF 03:00.1、03:00.2、03:00.3、03:00.4: + + ```shell + 03:00.0 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family (4*25GE) (rev 45) + 03:00.1 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.2 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.3 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.4 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + ``` + +3. 上述创建的 VF 设备均可以直通给虚拟机,使用 SR-IOV 设备的方法与普通 PCI 设备的直通方法相同。 diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/StratoVirt_introduction.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/StratoVirt_introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..d83c172b8ac2c919a9b334deab28d52afc8e4d03 --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/StratoVirt_introduction.md @@ -0,0 +1,48 @@ +# StratoVirt介绍 + +## 概述 + +StratoVirt是计算产业中面向云数据中心的企业级虚拟化平台,实现了一套架构统一支持虚拟机、容器、Serverless三种场景。StratoVirt在轻量低噪、软硬协同、Rust语言级安全等方面具备关键技术竞争优势。 +StratoVirt在架构设计和接口上预留了组件化拼装的能力和接口,StratoVirt可以按需灵活组装高级特性直至演化到支持标准虚拟化,在特性需求、应用场景和轻快灵巧之间找到最佳的平衡点。 + +## 架构说明 + +StratoVirt核心架构自顶向下分为三层: + +- 外部接口:兼容QMP(QEMU Monitor Protocol)协议,具有完备的OCI兼容能力,同时支持对接libvirt。 +- BootLoader:轻量化场景下抛弃传统BIOS+GRUB的启动模式实现快速启动,同时标准虚拟化场景下支持UEFI启动。 +- 模拟主板: + - microvm: 充分利用软硬协同能力,精简化设备模型,低时延资源伸缩能力。 + - 标准机型:提供ACPI表实现UEFI启动,支持添加virtio-pci以及VFIO直通设备等,极大提高虚拟机的I/O性能。 + +整体架构视图如**图1**所示。 + +**图1** StratoVirt整体架构图 + +![](./figures/StratoVirt_architecture.jpg) + +## 特性 + +- 基于硬件的高隔离能力; +- 快速冷启动:得益于极简设计,StratoVirt可以在50ms内启动microvm机型; +- 低内存开销: StratoVirt的内存占用小于4MB ; +- IO增强: StratoVirt提供普通IO能力与极简IO设备仿真; +- OCI兼容性:StratoVirt与isula和kata容器配合使用,可以完美融入Kubernetes生态系统; +- 多平台支持:全面支持Intel和ARM平台; +- 可扩展性:StratoVirt保留接口和设计,用于导入更多特性,甚至扩展到标准虚拟化支持; +- 安全性:运行时系统调用数小于46; + +## 实现 + +### 运行架构 + +- StratoVirt虚拟机是Linux中一个独立的进程。进程有三种线程:主线程、VCPU线程、I/O线程: + - 主线程是异步收集和处理来自外部模块(如VCPU线程)的事件的循环; + - 每个VCPU都有一个线程处理本VCPU的trap事件; + - 可以为I/O设备配置iothread提升I/O性能; + +### 约束 + +- 仅支持Linux操作系统; +- 虚拟机操作系统仅支持Linux; +- 最大支持254个CPU; diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/VM_configuration.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/VM_configuration.md new file mode 100644 index 0000000000000000000000000000000000000000..16b118c961c951ef41e36337f614b5701d33dc5d --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/VM_configuration.md @@ -0,0 +1,686 @@ +# 虚拟机配置 + +## 概述 + +使用 StratoVirt 时,可以通过命令行参数指定虚拟机配置,也支持对接 libvirt ,通过 XML 文件配置。本章介绍命令行方式的配置方式。 + +> ![](./public_sys-resources/icon-note.gif)**说明** +> +> 本文中的 /path/to/socket 为用户自定义路径下的 socket 文件。 +> +> 从 openEuler 21.09 版本开始,取消了对 json 文件的支持。 + +## 规格说明 + +StratoVirt 支持启动轻量级虚拟机和标准虚拟机。 + +- 轻量级虚拟机使用轻量级 microVM 主板,以及 mmio 总线。 +- 标准虚拟机支持标准启动,在 x86 平台使用 Q35 主板,AArch64 架构下使用 virt 主板以及 PCI 总线。 + +### 轻量级虚拟机 + +- 虚拟机 CPU 个数:[1, 254] +- 虚拟机内存大小:[128 MiB, 512 GiB],默认内存配置256MiB +- 虚拟机磁盘个数(包括热插的磁盘):[0, 6] +- 虚拟机网卡个数(包括热插的网卡):[0, 2] +- 虚拟机 console 设备仅支持单路连接 +- 主机 CPU 架构为 x86_64 时,最多可以配置 11 个 mmio 设备,但是除了磁盘和网卡,建议最多配置 2 个其他设备; AArch64 平台,最多可以配置 160 个 mmio 设备,但是除了磁盘和网卡,建议最多配置 12 个其他设备。 + +### 标准虚拟机 + +- 虚拟机 CPU 个数:[1, 254] +- 虚拟机内存大小:[128 MiB, 512 GiB],默认内存配置256MiB +- 虚拟机 console 设备仅支持单路连接 +- 只支持 1 个 console 设备 +- 最多支持 32 个 PCI 设备 +- PCI 设备挂载的 PCI 总线 slot 取值范围: [0, 32);function 取值范围 [0, 8) + +## 最小配置 + +StratoVirt 能够运行的最小配置为: + +- PE 格式或 bzImage 格式(仅 x86_64)的 Linux 内核镜像 +- 将 rootfs 镜像设置成 virtio-blk 设备,并添加到内核参数中 +- 使用 QMP 控制 StratoVirt +- 如果要使用串口登录,添加一个串口到内核启动命令行,AArch64平台标准机型为ttyAMA0,其他情况为ttyS0. + +## 配置介绍 + +### **命令格式** + +使用 cmdline 配置的命令格式如下: + +**$ /path/to/stratovirt** *-[参数1] [参数选项] -[参数2] [参数选项] ...* + +### **使用说明** + +1. 首先,为确保可以创建 QMP 需要的 socket,可以参考如下命令清理环境: + + ```sh + # rm [参数] [用户自定义socket文件路径] + ``` + +2. 然后,运行 cmdline 命令。 + + ```sh + # /path/to/stratovirt -[参数1] [参数选项] -[参数2] [参数选项] ... + ``` + +### 基本信息配置 + +基本配置信息如下表所示: + +| 参数 | 参数选项 | 说明 | +| ---------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| -name | *VMname* | 配置虚拟机名称(字符长度:1-255字符) | +| -kernel | /path/to/vmlinux.bin | 配置内核镜像 | +| -append | console=ttyS0 root=/dev/vda reboot=k panic=1 rw | 配置内核命令行参数,轻量级虚拟机固定配置为console=ttyS0(与架构平台无关)。标准虚拟化X86_64平台默认使用console=ttyS0,AArch64平台默认使用console=ttyAMA0。在配置了virtio-console设备但是没有配置serial串口设备时,需要配置为console=hvc0(与架构平台无关) | +| -initrd | /path/to/initrd.img | 配置initrd文件 | +| -smp | [cpus=]n[,maxcpus=,sockets=,dies=,clusters=,cores=,threads=] | cpus:配置cpu个数,范围[1, 254]。maxcpus:最大cpu个数,范围[1,254]。sockets:socket的个数,如果不设置它的值依赖于maxcpus;die:die的个数;cluster:cluster的个数;core:core的个数,如果不设置它的值依赖于maxcpus;thread:thread的个数,如果不设置它的值依赖于maxcpus;maxcpus=sockets *dies* clusters *cores* threads | +| -m | 内存大小MiB、内存大小GiB,默认单位MiB | 配置内存大小,范围[128 MiB, 512 GiB],默认内存配置256MiB | +| -qmp | unix:/path/to/socket,server,nowait | 配置QMP,运行前须保证socket文件不存在 | +| -D | /path/to/logfile | 配置日志文件 | +| -pidfile | /path/to/pidfile | 配置pid文件,必须和-daemonize一起使用。运行前须保证pid文件不存在 | +| -disable-seccomp | NA | 关闭Seccomp,默认打开 | +| -daemonize | NA | 开启进程daemon化 | + +### 虚拟机类型 + +通过-machine参数来指定启动的虚拟机的类型。 + +参数说明 + +- type:启动虚拟机的类型(轻量级虚拟化为“MicroVm”类型,标准虚拟化在x86_64平台为”q35“,在aarch64平台为”virt”)。 +- dump-guest-core:进程panic时,是否dump虚拟机内存(可选配置)。 +- mem-share:是否与其他进程共享内存(可选配置)。 + +### 磁盘配置 + +虚拟机磁盘配置包含以下配置项 + +- drive_id: 磁盘的id。 +- path_on_host: 磁盘的路径。 +- serial_num: 磁盘的串号(可选配置)。 +- read_only: 是否只读(可选配置)。 +- direct: 是否以“O_DIRECT”模式打开(可选配置)。 +- iothread: 配置iothread属性(可选配置)。 +- throttling.iops-total: 配置磁盘QoS,以限制磁盘的io操作(可选配置)。 +- if:driver的类型,block设备为“none”(可选配置,缺省值为“none”) +- bus:设备要挂载的bus。 +- addr:设备要挂载的slot和function号。 +- multifunction:是否开启pci多功能。(可选配置) +- bootindex:配置启动优先级属性,如果没有设置,默认最低优先级。配置范围从0到255,数字越小,优先级越高。(可选配置,只支持标准机型) + +#### 磁盘配置方式 + +磁盘的配置分为两步:driver的配置和block设备的配置 + +轻量虚拟机配置格式为: + +```Conf +-drive id=drive_id,file=path_on_host[,readonly=off][,direct=off][,throttling.iops-total=200][,if=none] +-device virtio-blk-device,drive=drive_id[,iothread=iothread1][,serial=serial_num] +``` + +标准虚拟机配置格式为: + +```Conf +-drive id=drive_id,file=path_on_host[,readonly=off][,direct=off][,throttling.iops-total=200][,if=none] +-device virtio-blk-pci,drive=drive_id,bus=pcie.0,addr=0x3.0x0[,iothread=iothread1,][serial=serial_num][,multifunction=on][,bootindex=1] +``` + +下面对throttling.iops-total和iothread两个配置项进行详细说明: + +#### 磁盘QoS + +##### 简介 + +QoS(Quality of Service)是服务质量的意思。在云场景中,单主机内会启动多台虚拟机,当某台虚拟机对磁盘访问压力大时,由于同主机的磁盘访问总带宽有限,这会挤占其他虚拟机的访问带宽,从而造成对其他虚拟机IO影响。为了降低影响,可以为虚拟机配置QoS属性,限制它们对磁盘访问的速率,从而降低对彼此的影响。 + +##### 注意事项 + +- 当前QoS支持配置磁盘的iops。 +- iops的设定范围是[0, 1000000],0为不限速;实际iops不会超过设定值,并且不会超过后端磁盘实际性能的上限。 +- 只能限制平均iops,无法限速瞬时的突发流量。 + +##### 配置方式 + +用法: + +**命令行** + +```Conf +-drive xxx,throttling.iops-total=200 +``` + +参数: + +- throttling.iops-total:当配置了iops后,本磁盘在虚拟机内部的IO下发速度,不会超过此配置值。 +- xxx:表示磁盘的其他设置。 + +#### iothread + +iothread配置细节见[iothread配置](#iothread配置) + +### 网卡配置 + +虚拟机网卡的配置包含以下配置项: + +- id:唯一的设备 id。 +- tap:指定 tap 设备。 +- ifname:host 上的 tap 设备名。 +- mac:设置虚拟机 mac 地址(可选配置)。 +- iothread:配置磁盘的 iothread 属性(可选配置)。网卡 iothread 配置详见 [iothread配置](#iothread配置) 。 + +#### 配置方式 + +> ![](./public_sys-resources/icon-note.gif)**说明** +> +> 使用网络前请先使用如下命令配置好 host 网桥和 tap 设备。 +> +> ```sh +> # brctl addbr qbr0 +> # ip tuntap add tap0 mode tap +> # brctl addif qbr0 tap0 +> # ifconfig qbr0 up; ifconfig tap0 up +> # ifconfig qbr0 192.168.0.1 +> ``` + +1. 配置 virtio-net(本文中 [] 表示可选参数) + + 轻量级虚拟机: + + ```Conf + -netdev tap,id=netdevid,ifname=host_dev_name[,vhostfd=2] + -device virtio-net-device,netdev=netdevid,id=netid[,iothread=iothread1,mac=12:34:56:78:9A:BC] + ``` + + 标准虚拟机: + + ```Conf + -netdev tap,id=netdevid,ifname=host_dev_name[,vhostfd=2] + -device virtio-net-pci,netdev=netdevid,id=netid,bus=pcie.0,addr=0x2.0x0[,multifunction=on,iothread=iothread1,mac=12:34:56:78:9A:BC] + ``` + +2. 配置 vhost-net + + 轻量级虚拟机: + + ```Conf + -netdev tap,id=netdevid,ifname=host_dev_name,vhost=on[,vhostfd=2] + -device virtio-net-device,netdev=netdevid,id=netid[,iothread=iothread1,mac=12:34:56:78:9A:BC] + ``` + + 标准虚拟机: + + ```Conf + -netdev tap,id=netdevid,ifname=host_dev_name,vhost=on[,vhostfd=2] + -device virtio-net-pci,netdev=netdevid,id=netid,bus=pcie.0,addr=0x2.0x0[,multifunction=on,iothread=iothread1,mac=12:34:56:78:9A:BC] + ``` + +### chardev 配置 + +将来自 Guest 的 I/O 重定向到宿主机的 chardev。chardev 后端的类型可以是:stdio、pty、socket 和 file。其中 file 仅支持输出时设置。配置项: + +- id:唯一的设备 id。 +- backend:重定向的类型。 +- path:设备重定向文件路径。仅 socket 和 file 类型的设备需要此参数。 +- server:将 chardev 作为服务器运行。仅 socket 类型的设备需要此参数。 +- nowait:预期状态为断开连接。仅 socket 类型的设备需要此参数。 + +使用 chardev 时,会创建并使用 console 文件,所以启动 stratovirt 之前,请确保 console 文件不存在。 + +#### 配置方式 + +```Conf +-chardev backend,id=chardev_id[,path=path,server,nowait] +``` + +### 串口配置 + +串口是虚拟机的设备,用于主机和虚拟机之间传送数据。使用串口时,kernel 命令行中配置 console=ttyS0 ,在 AArch64 平台上标准启动时,配置 console=ttyAMA0 。配置项: + +- chardev:重定向的 chardev 设备 +- backend、path、server、nowait:这些参数的含义与 chardev 中的相同。 + +#### 配置方式 + +```Conf +-serial chardev:chardev_id +``` + +或者: + +```Conf +-chardev backend[,path=path,server,nowait] +``` + +### console 设备配置 + +virtio-console 是通用的串口设备,用于主机和虚拟机之间传送数据。当只配 console 并通过 console 进行 I/O 操作时,kernel 启动参数中配置 console=hvc0。console 设备有如下配置项: + +- id: 设备的 id。 +- path:virtio console 文件路径。 +- socket:以 socket 的方式重定向。 +- chardev:重定向的 chardev 设备。 + +#### 配置方式 + +console 配置分为三步:首先指定 virtio-serial,然后创建字符设备,最后创建 virtconsole 设备。 + +轻量级虚拟机: + +```Conf +-device virtio-serial-device[,id=virtio-serial0] +-chardev socket,path=socket_path,id=virtioconsole1,server,nowait +-device virtconsole,chardev=virtioconsole1,id=console_id +``` + +标准虚拟机: + +```Conf +-device virtio-serial-pci,bus=pcie.0,addr=0x1.0x0[,multifunction=on,id=virtio-serial0] +-chardev socket,path=socket_path,id=virtioconsole1,server,nowait +-device virtconsole,chardev=virtioconsole1,id=console_id +``` + +### vsock 设备配置 + +vsock 也是主机和虚拟机之间通信的设备,类似于 console,但具有更好的性能。配置项: + +- id: 唯一的设备 id。 +- guest_cid: 唯一的 context id 。 + +#### 配置方式 + +轻量级虚拟机: + +```Conf +-device vhost-vsock-device,id=vsock_id,guest-cid=3 +``` + +标准虚拟机: + +```Conf +-device vhost-vsock-pci,id=vsock_id,guest-cid=3,bus=pcie.0,addr=0x1.0x0[,multifunction=on] +``` + +### 内存大页配置 + +#### 概述 + +StratoVirt 支持为虚拟机配置内存大页,相比传统的 4KiB 内存分页模式,大页内存可以有效减少 TLB Miss 次数和缺页中断次数,能够显著提升内存密集型业务性能。 + +#### 注意事项 + +- 指定的大页挂载的目录,必须是绝对路径。 +- 仅支持在启动时配置。 +- 仅支持静态大页。 +- 使用大页前, 在Host上需要配置好大页。 +- 使用大页特性, 指定虚拟机内存规格必须是**大页页面大小的整数倍**。 + +#### 互斥特性 + +- 内存大页和 ballon 特性互斥,同时配置时,balloon 特性无效。 + +#### 配置方式 + +##### 配置Host上大页 + +###### 挂载 + +将大页文件系统挂载到指定目录上,其中 `/path/to/hugepages`为用户自定义的空目录。 + +```sh +# mount -t hugetlbfs hugetlbfs /path/to/hugepages +``` + +###### 设置大页数目 + +- 设置静态大页数目, `num`为指定的大页数目 + + ```sh + # sysctl vm.nr_hugepages=num + ``` + +- 查询大页统计信息 + + ```sh + # cat /proc/meminfo | grep Hugepages + ``` + + 如果需要查看其他页面大小的大页统计信息, 可以查看 `/sys/kernel/mm/hugepages/hugepages-*/`目录下相关信息。 + +> ![](./public_sys-resources/icon-note.gif)**说明** +> +> 请根据大页使用情况,配置StratoVirt内存规格和大页。如果大页资源不足,虚拟机会启动失败。 + +#### 启动StratoVirt时添加大页配置 + +- 命令行 + + ```Conf + -mem-path /page/to/hugepages + ``` + + 其中 `/page/to/hugepages`为大页文件系统挂载的目录,仅支持绝对路径。 + +> ![](./public_sys-resources/icon-note.gif)**说明** +> +> **典型配置:**指定StratoVirt命令行中的mem-path项为:**大页文件系统挂载的目录**。 推荐使用典型配置使用StratoVirt大页特性。 + +### 配置iothread + +#### 简介 + +当StratoVirt启动了带iothread配置的虚拟机后,会在主机上启动独立于主线程的单独线程,这些单独线程可以用来处理设备的IO请求,一方面提升设备的IO性能,另一方面降低对管理面消息处理的影响。 + +#### 注意事项 + +- 支持配置最多8个iothread线程 +- 支持磁盘和网卡配置iothread属性 +- iothread线程会占用主机CPU资源,在虚拟机内部大IO压力情况下,单个iothread占用的CPU资源取决于磁盘的访问速度,例如普通的SATA盘会占用20%以内CPU资源。 + +#### 创建iothread线程 + +**命令行:** + +```shell +-object iothread,id=iothread1 -object iothread,id=iothread2 +``` + +参数: + +- id:用于标识此iothread线程,该id可以被设置到磁盘或网卡的iothread属性。当启动参数配置了iothread线程信息,虚拟机启动后会在主机上启动相应id名的线程。 + +#### 配置磁盘或网卡的iothread属性 + +**命令行配置** + +轻量虚拟机: + +磁盘 + +```Conf +-device virtio-blk-device xxx,iothread=iothread1 +``` + +网卡 + +```Conf +-device virtio-net-device xxx,iothread=iothread2 +``` + +标准虚拟机: + +磁盘 + +```Conf +-device virtio-blk-pci xxx,iothread=iothread1 +``` + +网卡 + +```Conf +-device virtio-net-pci xxx,iothread=iothread2 +``` + +参数: + +1. iothread:设置成 iothread 线程的 id,指明处理本设备 I/O 的线程。 +2. xxx: 表示磁盘或者网卡的其他配置 + +### 配置balloon设备 + +#### 简介 + +在虚拟机运行过程中,由虚拟机里的balloon驱动来动态占用或释放内存,从而动态改变这台虚拟机当前可用内存,达到内存弹性的效果。 + +#### 注意事项 + +- 启用balloon前须确保guest和host的页面大小相同。 +- guest内核须开启balloon特性支持。 +- 开启内存弹性时,有可能造成虚拟机内部轻微卡顿、内存性能下降。 + +#### 互斥特性 + +- 大页内存互斥。 +- 在x86下,由于中断数量有限,所以balloon设备和其他virtio的数量(默认使用6个block设备,2个net设备和1个串口设备)总和不得超过11个。 + +#### 规格 + +- 每个VM只能配置1个balloon设备。 + +#### 配置方式 + +轻量级虚拟机: + +```Conf +-device virtio-balloon-device[,deflate-on-oom=true|false][,free-page-reporting=true|false] +``` + +标准虚拟机: + +```Conf +-device virtio-balloon-pci,bus=pcie.0,addr=0x4.0x0[,deflate-on-oom=true|false][,free-page-reporting=true|false][,multifunction=on|off] +``` + +![](./public_sys-resources/icon-note.gif)**说明** + +1. deflate-on-oom的取值为bool类型,表示是否开启auto deflate特性。开启时,如果balloon已经回收部分内存,当guest需要内存时,balloon设备会自动放气,归还内存给guest。不开启则不会自动归还。 +2. free-page-reporting的取值为bool类型,表示是否开启free page reporting特性。开启时,如果guest内核向balloon设备发送了free pages,balloon将释放free pages所占用的内存。不开启则guest内核不会向balloon设备发送free pages。 +3. 使用qmp命令回收虚拟机内存时,应确保回收后虚拟机仍然有足够的内存来保持最基本的运行。否则可能会出现一些操作超时,以及导致虚拟机内部无法申请到空闲内存等现象。 +4. 如果虚拟机内部开启内存大页,balloon不能回收大页占用内存。 + +> deflate-on-oom=false时,当Guest中内存不足时,balloon不会自动放气并归还内存,可能会引起Guest内部OOM,进程被Kill,甚至虚拟机无法正常运行。 + +### 配置RNG设备 + +#### 简介 + +Virtio RNG是半虚拟化的随机数生成器设备,用于为guest提供硬件随机数生成能力。 + +#### 配置方式 + +Virtio RNG可配置为Virtio mmio设备或者virtio PCI设备,Virtio RNG配置为Virtio mmio设备时,命令行参数如下: + +```Conf +-object rng-random,id=objrng0,filename=/path/to/random_file +-device virtio-rng-device,rng=objrng0,max-bytes=1234,period=1000 +``` + +Virtio RNG配置为Virtio PCI设备时,命令行参数如下: + +```Conf +-object rng-random,id=objrng0,filename=/path/to/random_file +-device virtio-rng-pci,rng=objrng0,max-bytes=1234,period=1000,bus=pcie.0,addr=0x1.0x0,id=rng-id[,multifunction=on] +``` + +参数: + +- filename:在host上用于生成随机数的字符设备路径,例如/dev/random; +- period:限制随机数字符速率的定时周期,单位为毫秒; +- max-bytes:在period时间内字符设备生成随机数的最大字节数; +- bus:Virtio RNG设备挂载的总线名称; +- addr:Virtio RNG设备地址,参数格式为addr=[slot].[function],分别表示设备的slot号和function号,均使用十六进制表示,其中Virtio RNG设备的function号为0x0。 + +#### 注意事项 + +- 如不配置period和max-bytes,则不对随机数字符读取速率进行限制; +- 如配置限速,则max-bytes/period\*1000的设定范围为[64, 1000000000],建议不应设置过小,以防获取随机数字符速率过慢; +- 只能限制平均随机数字符数,无法限制瞬间的突发流量; +- guest如需使用Virtio RNG设备,guest内核需要使能配置:CONFIG_HW_RANDOM=y,CONFIG_HW_RANDOM_VIA=y,CONFIG_HW_RANDOM_VIRTIO=y; +- 用户在配置Virtio RNG设备时,请检查熵池是否足够,以免引起虚拟机卡顿问题,例如配置字符设备路径为/dev/random,当前熵池大小可通过/proc/sys/kernel/random/entropy_avail查看,熵池满时的大小为4096,通常应该大于1000。 + +### 配置VNC + +#### 简介 + +用户可以通过VNC客户端登录虚拟机,输入鼠标键盘事件,并通过VNC显示的桌面完成与远程虚拟机系统的交互。 + +#### 注意事项 + +- 当前只有标准虚拟机支持VNC特性。 +- 目前只支持RFB3.3-3.8版本客户端连接。 +- 目前只支持单个客户端连接,暂不支持多个客户端同时连接。多个客户端连接会返回连接失败。 +- 目前仅支持在ARM环境上使用。 + +#### 互斥特性 + +- VNC特性暂不支持热迁移。 + +#### 规格 + +- 每个虚拟机只支持配置一个VNC Server。 + +#### 配置方式 + +标准虚拟机: + +```shell +-vnc 0.0.0.0:11 +``` + +![](./public_sys-resources/icon-note.gif)**说明** + +1. 图像渲染用到`pixman`库,需要在虚拟机运行环境中安装`pixman.rpm`和`pixman-devel.rpm`两个包。 +2. 鼠标键盘输入需要配置一个`USB`控制器,以及鼠标键盘设备。 +3. 需要配置一个显示设备,如`virtio-gpu`、`ramfb`。 + +### 配置 USB 键盘和 USB 鼠标 + +#### 简介 + +StratoVirt 支持配置 USB 键盘和 USB 鼠标,用户可以通过 VNC 远程连接虚拟机,通过 USB 键盘鼠标对虚拟机进行图形化操作。USB 设备需要挂载在 USB 控制器上,因此需要提前在命令行里配置 USB 控制器。 + +#### 注意事项 + +- 当前只有标准虚拟机支持 USB 键盘鼠标。 + +#### 互斥特性 + +- USB 键盘鼠标暂不支持热迁移。 + +#### 规格 + +- 每个 VM 只能配置 1 个 USB 控制器 +- 每个 VM 只能配置 1 个 USB 键盘 +- 每个 VM 只能配置 1 个 USB 鼠标 + +#### 配置方式 + +USB 控制器在启动 StratoVirt 时命令行配置: + +```Conf +-device nec-usb-xhci,id=xhci,bus=pcie.0,addr=0xa.0x0 +``` + +参数: + +- id:唯一的设备 id。 +- bus:设备要挂载的 bus。 +- addr:设备要挂载的 slot 和 function 号。 + +注意需要合理配置设备的 bus 和 addr 参数,不能和其他配置的 PCI 设备冲突,否则可能会导致虚拟机启动失败。 + +USB 键盘在启动 StratoVirt 时命令行配置: + +```Conf +-device usb-bkd,id=kbd +``` + +参数: + +- id:唯一的设备 id。 + +USB 鼠标在启动 StratoVirt 时命令行配置: + +```Conf +-device usb-tablet,id=tablet +``` + +参数: + +- id:唯一的设备 id。 + +### 配置virtio-gpu设备 + +#### 简介 + +标准虚拟机可支持配置virtio-gpu显卡用于显示。 + +#### 注意事项 + +- 目前仅支持2D。 +- max_hostmem(即在host侧可占用内存)建议不小于256MiB,否则影响分辨率配置。 +- max_outputs(即支持的屏幕数量)配置不可大于16。 +- 不支持热迁移。 + +#### 规格 + +- 每个VM只能配置1个virtio-gpu设备。 + +#### 配置方式 + +标准虚拟机: + +```Conf +-device virtio-gpu-pci,id=XX,bus=pcie.0,addr=0x2.0x0[,max_outputs=XX][,edid=true|false][,xres=XX][,yres=XX][,max_hostmem=XX] +``` + +参数: + +1. max_outputs:当前显卡需要支持的屏幕数量,建议配置为1,最大值不超过16。 +2. edid:当前显卡是否支持edid,建议配置为true,虚拟机内核会检查显卡是否支持edid。 +3. xres/yres:登录窗口的横向/纵向大小。 +4. max_hostmem: 显卡最大可占用host侧内存, 以Byte为单位。 + +## 配置示例 + +### 轻量级虚拟机 + +此处给出创建一个轻量级虚拟机的最小配置示例。 + +1. 登录主机,删除 socket 文件,确保可以创建 QMP。 + + ```sh + # rm -f /tmp/stratovirt.socket + ``` + +2. 运行 StratoVirt 。 + + ```sh + # /path/to/stratovirt \ + -kernel /path/to/vmlinux.bin \ + -append console=ttyS0 root=/dev/vda rw reboot=k panic=1 \ + -drive file=/home/rootfs.ext4,id=rootfs,readonly=false \ + -device virtio-blk-device,drive=rootfs \ + -qmp unix:/tmp/stratovirt.socket,server,nowait \ + -serial stdio + ``` + + 运行成功后,将根据指定的配置参数创建并启动虚拟机。 + +### 标准虚拟机 + +此处给出在 ARM 平台创建一个标准虚拟机的最小配置示例。 + +1. 删除 socket 文件,确保可以创建 QMP 。 + + ```sh + # rm -f /tmp/stratovirt.socket + ``` + +2. 运行 StratoVirt 。 + + ```sh + # /path/to/stratovirt \ + -kernel /path/to/vmlinux.bin \ + -append console=ttyAMA0 root=/dev/vda rw reboot=k panic=1 \ + -drive file=/path/to/edk2/code_storage_file,if=pflash,unit=0[,readonly=true] \ + -drive file=/path/to/edk2/data_storage_file,if=pflash,unit=1, \ + -drive file=/home/rootfs.ext4,id=rootfs,readonly=false \ + -device virtio-blk-device,drive=rootfs,bus=pcie.0,addr=0x1 \ + -qmp unix:/tmp/stratovirt.socket,server,nowait \ + -serial stdio + ``` diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/VM_management.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/VM_management.md new file mode 100644 index 0000000000000000000000000000000000000000..43973f17d1fd2809e6a3bb1a8763cfff72c259c8 --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/VM_management.md @@ -0,0 +1,741 @@ +# 管理虚拟机 + +## 概述 + +StratoVirt可以查询虚拟机信息并对虚拟机的资源和生命周期进行管理。由于StratoVirt使用QMP管理虚拟机,所以查询虚拟机信息,也需要先连接到虚拟机。 + +## 查询虚拟机信息 + +### 简介 + +StratoVirt可以查询虚拟机状态、vCPU拓扑信息、vCPU上线情况等。 + +### 查询状态 + +使用query-status命令查询虚拟机的运行状态。 + +- 用法: + + **{ "execute": "query-status" }** + +- 示例: + +```shell +<- { "execute": "query-status" } +-> { "return": { "running": true,"singlestep": false,"status": "running" } +``` + +### 查询拓扑 + +使用query-cpus命令查询所有CPU的拓扑结构。 + +- 用法: + +**{ "execute": "query-cpus" }** + +- 示例: + +```shell +<- { "execute": "query-cpus" } +-> {"return":[{"CPU":0,"arch":"x86","current":true,"halted":false,"props":{"core-id":0,"socket-id":0,"thread-id":0},"qom_path":"/machine/unattached/device[0]","thread_id":8439},{"CPU":1,"arch":"x86","current":true,"halted":false,"props":{"core-id":0,"socket-id":1,"thread-id":0},"qom_path":"/machine/unattached/device[1]","thread_id":8440}]} +``` + +### 查询vCPU上线情况 + +使用query-hotpluggable-cpus命令查询所有vCPU的online/offline情况。 + +- 用法: + +**{ "execute": "query-hotpluggable-cpus" }** + +- 示例: + +```shell +<- { "execute": "query-hotpluggable-cpus" } +-> {"return":[{"props":{"core-id":0,"socket-id":0,"thread-id":0},"qom-path":"/machine/unattached/device[0]","type":"host-x86-cpu","vcpus-count":1},{"props":{"core-id":0,"socket-id":1,"thread-id":0},"qom-path":"/machine/unattached/device[1]","type":"host-x86-cpu","vcpus-count":1}]} +``` + +其中,online的vCPU具有`qom-path`项,offline的vCPU则没有。 + +## 管理虚拟机生命周期 + +### 简介 + +StratoVirt可以对虚拟机进行启动、暂停、恢复、退出等生命周期进行管理。 + +### 创建并启动虚拟机 + +通过命令行参数指定虚拟机配置,创建并启动虚拟机。 + +- 使用命令行参数给出虚拟机配置,创建并启动虚拟机的命令如下: + +```shell +$ /path/to/stratovirt -[参数1] [参数选项] -[参数2] [参数选项] ... +``` + +> ![](./public_sys-resources/icon-note.gif)说明: +> +> 轻量虚拟启动后,内部会有eth0和eth1两张网卡。这两张网卡预留用于网卡热插拔。热插的第一张网卡是eth0,热插的第二张网卡是eth1,目前只支持热插两张virtio-net网卡。 + +### 连接虚拟机 + +StratoVirt当前采用QMP管理虚拟机,暂停、恢复、退出虚拟机等操作需要通过QMP连接到虚拟机进行管理。 + +在主机上打开新的命令行窗口B,并使用root权限进行api-channel连接,参考命令如下: + +```shell +# ncat -U /path/to/socket +``` + +连接建立后,会收到来自StratoVirt的问候消息,如下所示: + +```shell +{"QMP":{"version":{"qemu":{"micro":1,"minor":0,"major":4},"package":""},"capabilities":[]}} +``` + +现在,可以在窗口B中输入QMP命令来管理虚拟机。 + +> ![](./public_sys-resources/icon-note.gif)说明: +> +> QMP提供了stop、cont、quit和query-status等来管理和查询虚拟机状态。 +> +> 管理虚拟机的QMP命令均在窗口B中进行输入。符号:`<-`表示命令输入,`->`表示QMP结果返回。 + +### 暂停虚拟机 + +QMP提供了stop命令用于暂停虚拟机,即暂停虚拟机所有的vCPU。命令格式如下: + +**{"execute":"stop"}** + +**示例:** + +使用stop暂停该虚拟机的命令和回显如下: + +```shell +<- {"execute":"stop"} +-> {"event":"STOP","data":{},"timestamp":{"seconds":1583908726,"microseconds":162739}} +-> {"return":{}} +``` + +### 恢复虚拟机 + +QMP提供了cont命令用于恢复处于暂停状态suspend的虚拟机,即恢复虚拟机所有vCPU的运行。命令格式如下: + +**{"execute":"cont"}** + +**示例:** + +使用cont恢复该虚拟机的命令和回显如下: + +```shell +<- {"execute":"cont"} +-> {"event":"RESUME","data":{},"timestamp":{"seconds":1583908853,"microseconds":411394}} +-> {"return":{}} +``` + +### 退出虚拟机 + +QMP提供了quit命令用于退出虚拟机,即退出StratoVirt进程。命令格式如下: + +**{"execute":"quit"}** + +**示例:** + +```shell +<- {"execute":"quit"} +-> {"return":{}} +-> {"event":"SHUTDOWN","data":{"guest":false,"reason":"host-qmp-quit"},"timestamp":{"ds":1590563776,"microseconds":519808}} +``` + +## 管理虚拟机资源 + +### 热插拔磁盘 + +StratoVirt支持在虚拟机运行过程中调整磁盘数量,即在不中断业务前提下,增加或删除虚拟机磁盘。 + +**注意事项** + +- 对于标准机型,需要虚拟机内核开启 CONFIG_HOTPLUG_PCI_PCIE=y 配置。 + +- 对于标准机型,目前支持热插拔设备到 Root Port 设备,Root Port 设备需要在虚拟机启动前配置。 + +- 不建议在虚拟机启动、关闭、内部高压力等状态下进行设备热插拔,可能会因为虚拟机内驱动没有及时响应导致虚拟机出现异常。 + +#### 热插磁盘 + +**用法:** + +轻量机型: + +```shell +{"execute": "blockdev-add", "arguments": {"node-name": "drive-0", "file": {"driver": "file", "filename": "/path/to/block"}, "cache": {"direct": true}, "read-only": false}} +{"execute": "device_add", "arguments": {"id": "drive-0", "driver": "virtio-blk-mmio", "addr": "0x1"}} +``` + +标准机型: + +```shell +{"execute": "blockdev-add", "arguments": {"node-name": "drive-0", "file": {"driver": "file", "filename": "/path/to/block"}, "cache": {"direct": true}, "read-only": false}} +{"execute":"device_add", "arguments":{"id":"drive-0", "driver":"virtio-blk-pci", "drive": "drive-0", "addr":"0x0", "bus": "pcie.1"}} +``` + +**参数** + +- 对于轻量机型,blockdev-add 中的 node-name 要和 device_add 中的 id 一致,如上都是 drive-0。 + +- 对于标准机型 drive 参数需要和 blockdev-add 中的 node-name 一致。 + +- /path/to/block 是被热插磁盘的镜像路径,不能是启动 rootfs 的磁盘镜像。 + +- 对于轻量机型,addr 参数从 0x0 开始与虚拟机的 vda 映射,0x1 与 vdb 映射,以此类推。为了兼容 QMP 协议,"addr" 也可以用 "lun" 代替,但是 lun=0 与客户机的 vdb 映射。对于标准机型,目前 addr 参数需要指定为 0x0。 + +- 对于标准机型,bus 为设备要挂载的总线名称,目前只支持热插到 Root Port 设备,需要和 Root Port 的 id 保持一致。 + +- 对于轻量机型,StratoVirt 支持的最大 virtio-blk 磁盘数量是6个,热插磁盘时请注意规格约束。对于标准机型,热插磁盘的数量取决于 Root Port 设备的数量。 + +**示例** + +轻量机型: + +```shell +<- {"execute": "blockdev-add", "arguments": {"node-name": "drive-0", "file": {"driver": "file", "filename": "/path/to/block"}, "cache": {"direct": true}, "read-only": false}} +-> {"return": {}} +<- {"execute": "device_add", "arguments": {"id": "drive-0", "driver": "virtio-blk-mmio", "addr": "0x1"}} +-> {"return": {}} +``` + +标准机型: + +```shell +<- {"execute": "blockdev-add", "arguments": {"node-name": "drive-0", "file": {"driver": "file", "filename": "/path/to/block"}, "cache": {"direct": true}, "read-only": false}} +-> {"return": {}} +<- {"execute":"device_add", "arguments":{"id":"drive-0", "driver":"virtio-blk-pci", "drive": "drive-0", "addr":"0x0", "bus": "pcie.1"}} +-> {"return": {}} +``` + +#### 热拔磁盘 + +**用法:** + +轻量机型: + +```shell +{"execute": "device_del", "arguments": {"id":"drive-0"}} +``` + +标准机型: + +```shell +{"execute": "device_del", "arguments": {"id":"drive-0"}} +{"execute": "blockdev-del", "arguments": {"node-name": "drive-0"}} +``` + +**参数:** + +- id 为热拔磁盘的 ID 号。 +- node-name 为磁盘后端名称。 + +**示例** + +轻量机型: + +```shell +<- {"execute": "device_del", "arguments": {"id": "drive-0"}} +-> {"event":"DEVICE_DELETED","data":{"device":"drive-0","path":"drive-0"},"timestamp":{"seconds":1598513162,"microseconds":367129}} +-> {"return": {}} +``` + +标准机型: + +```shell +<- {"execute": "device_del", "arguments": {"id":"drive-0"}} +-> {"return": {}} +-> {"event":"DEVICE_DELETED","data":{"device":"drive-0","path":"drive-0"},"timestamp":{"seconds":1598513162,"microseconds":367129}} +<- {"execute": "blockdev-del", "arguments": {"node-name": "drive-0"}} +-> {"return": {}} +``` + +当收到 DEVICE_DELETED 事件时,表示设备在 StratoVirt 侧被移除。 + +### 热插拔网卡 + +StratoVirt支持在虚拟机运行过程中调整网卡数量,即在不中断业务前提下,给虚拟机增加或删除网卡。 + +**注意事项** + +- 对于标准机型,需要虚拟机内核开启 CONFIG_HOTPLUG_PCI_PCIE=y 配置。 + +- 对于标准机型,目前支持热插拔设备到 Root Port 设备,Root Port 设备需要在虚拟机启动前配置。 + +- 不建议在虚拟机启动、关闭、内部高压力等状态下进行设备热插拔,可能会因为虚拟机内驱动没有及时响应导致虚拟机出现异常。 + +#### 热插网卡 + +**准备工作(需要使用root权限)** + +1. 创建并启用Linux网桥,例如网桥名为 qbr0 的参考命令如下: + + ```shell + # brctl addbr qbr0 + # ifconfig qbr0 up + ``` + +2. 创建并启用 tap 设备,例如设备名为 tap0 的参考命令如下: + + ```shell + # ip tuntap add tap0 mode tap + # ifconfig tap0 up + ``` + +3. 添加 tap 设备到网桥: + + ```shell + # brctl addif qbr0 tap0 + ``` + +**用法** + +轻量机型: + +```shell +{"execute":"netdev_add", "arguments":{"id":"net-0", "ifname":"tap0"}} +{"execute":"device_add", "arguments":{"id":"net-0", "driver":"virtio-net-mmio", "addr":"0x0"}} +``` + +标准机型: + +```shell +{"execute":"netdev_add", "arguments":{"id":"net-0", "ifname":"tap0"}} +{"execute":"device_add", "arguments":{"id":"net-0", "driver":"virtio-net-pci", "addr":"0x0", "netdev": "net-0", "bus": "pcie.1"}} +``` + +**参数** + +- 对于轻量机型,netdev_add 中的 id 应该和 device_add 中的 id 一致,ifname 是后端的 tap 设备名称。 + +- 对于标准机型,netdev 参数需要和 netdev_add 中的 id 一致。 + +- 对于轻量机型,addr 参数从 0x0 开始与虚拟机的 eth0 映射,0x1 和虚拟机的 eth1 映射。对于标准机型,目前 addr 参数需要指定为 0x0。 + +- 对于标准机型,bus 为设备要挂载的总线名称,目前只支持热插到 Root Port 设备,需要和 Root Port 的 id 保持一致。 + +- 对于轻量机型,由于 StratoVirt 支持的最大 virtio-net 数量为2个,热插网卡时请注意规格约束。对于标准机型,热插磁盘的数量取决于 Root Port 设备的数量。 + +**示例** + +轻量机型: + +```shell +<- {"execute":"netdev_add", "arguments":{"id":"net-0", "ifname":"tap0"}} +-> {"return": {}} +<- {"execute":"device_add", "arguments":{"id":"net-0", "driver":"virtio-net-mmio", "addr":"0x0"}} +-> {"return": {}} +``` + +其中,addr:0x0,对应虚拟机内部的eth0。 + +标准机型: + +```shell +<- {"execute":"netdev_add", "arguments":{"id":"net-0", "ifname":"tap0"}} +-> {"return": {}} +<- {"execute":"device_add", "arguments":{"id":"net-0", "driver":"virtio-net-pci", "addr":"0x0", "netdev": "net-0", "bus": "pcie.1"}} +-> {"return": {}} +``` + +#### 热拔网卡 + +**用法** + +轻量机型: + +```shell +{"execute": "device_del", "arguments": {"id": "net-0"}} +``` + +标准机型: + +```shell +{"execute": "device_del", "arguments": {"id":"net-0"}} +{"execute": "netdev_del", "arguments": {"id": "net-0"}} +``` + +**参数** + +- id:网卡的ID号,例如 net-0。 + +- netdev_del 中的 id 是网卡后端的名称。 + +**示例** + +轻量机型: + +```shell +<- {"execute": "device_del", "arguments": {"id": "net-0"}} +-> {"event":"DEVICE_DELETED","data":{"device":"net-0","path":"net-0"},"timestamp":{"seconds":1598513339,"microseconds":97310}} +-> {"return": {}} +``` + +标准机型: + +```shell +<- {"execute": "device_del", "arguments": {"id":"net-0"}} +-> {"return": {}} +-> {"event":"DEVICE_DELETED","data":{"device":"net-0","path":"net-0"},"timestamp":{"seconds":1598513339,"microseconds":97310}} +<- {"execute": "netdev_del", "arguments": {"id": "net-0"}} +-> {"return": {}} +``` + +当收到 DEVICE_DELETED 事件时,表示设备在 StratoVirt 侧被移除。 + +### 热插拔直通设备 + +StratoVirt 标准机型支持在虚拟机运行过程中调整直通设备数量,即在不中断业务前提下,给虚拟机增加或删除直通设备。 + +**注意事项** + +- 需要虚拟机内核开启 CONFIG_HOTPLUG_PCI_PCIE=y 配置。 + +- 目前支持热插拔设备到 Root Port 设备,Root Port 设备需要在虚拟机启动前配置。 + +- 不建议在虚拟机启动、关闭、内部高压力等状态下进行设备热插拔,可能会因为虚拟机内驱动没有及时响应导致虚拟机出现异常。 + +#### 热插直通设备 + +**用法** + +```shell +{"execute":"device_add", "arguments":{"id":"vfio-0", "driver":"vfio-pci", "bus": "pcie.1", "addr":"0x0", "host": "0000:1a:00.3"}} +``` + +**参数** + +- id 为热插设备的 ID 号。 + +- bus 为设备要挂载的总线名称。 + +- addr 为设备要挂载的 slot 和 function 号,目前 addr 参数需要指定为 0x0。 + +- host 为直通设备在主机上的 domain 号, bus 号, slot 号和 function 号。 + +**示例** + +```shell +<- {"execute":"device_add", "arguments":{"id":"vfio-0", "driver":"vfio-pci", "bus": "pcie.1", "addr":"0x0", "host": "0000:1a:00.3"}} +-> {"return": {}} +``` + +#### 热拔直通设备 + +**用法** + +```shell +{"execute": "device_del", "arguments": {"id": "vfio-0"}} +``` + +**参数** + +- id 为热拔设备的 ID 号。在热插设备时指定。 + +**示例** + +```shell +<- {"execute": "device_del", "arguments": {"id": "vfio-0"}} +-> {"return": {}} +-> {"event":"DEVICE_DELETED","data":{"device":"vfio-0","path":"vfio-0"},"timestamp":{"seconds":1614310541,"microseconds":554250}} +``` + +当收到 DEVICE_DELETED 事件时,表示设备在 StratoVirt 侧被移除。 + +## Ballon设备使用 + +使用balloon设备可以从虚拟机回收空闲的内存。Balloon通过qmp命令来调用。qmp命令使用如下: + +**用法:** + +```shell +{"execute": "balloon", "arguments": {"value": 2147483648‬}} +``` + +**参数:** + +- value: 想要设置的guest内存大小值,单位为字节。如果该值大于虚拟机启动时配置的内存值,则以启动时配置的内存值为准。 + +**示例:** + +启动时配置的内存大小为4GiB,在虚拟机内部通过free命令查询虚拟机空闲内存大于2GiB,那么可以通过qmp命令设置guest内存大小为2147483648字节。 + +```shell +<- {"execute": "balloon", "arguments": {"value": 2147483648‬}} +-> {"return": {}} +``` + +查询虚拟机的当前实际内存: + +```shell +<- {"execute": "query-balloon"} +-> {"return":{"actual":2147483648}} +``` + +## 虚拟机内存快照 + +### 简介 + +虚拟机内存快照是指将虚拟机的设备状态和内存信息保存在快照文件中。当虚拟机系统损坏时,可以使用内存快照将虚拟机恢复到快照对应时间点,从而提升系统的可靠性。 + +StratoVirt 支持对处于暂停状态(suspend)的虚拟机制作快照,并且支持虚拟机以快照文件为虚拟机模板批量创建新的虚拟机。只要制作快照的时间点在虚拟机启动完成并进入用户态之后,快速启动就能够跳过内核启动阶段和用户态服务初始化阶段,在毫秒级完成虚拟机启动。 + +### 互斥特性 + +虚拟机配置了如下设备或使用了如下特性时,不能制作和使用内存快照: + +- vhost-net 设备 +- vfio 直通设备 +- balloon 设备 +- 大页内存 +- mem-shared 特性 +- 配置了内存后端文件 mem-path + +### 制作快照 + +针对 StratoVirt 虚拟机,可以参考如下步骤制作存储快照: + +1. 创建并启动虚拟机。 + +2. 在 Host 上执行 QMP 命令暂停虚拟机: + + ```shell + <- {"execute":"stop"} + -> {"event":"STOP","data":{},"timestamp":{"seconds":1583908726,"microseconds":162739}} + -> {"return":{}} + + ``` + +3. 确认虚拟机处于暂停状态: + + ```shell + <- {"execute":"query-status"} + -> {"return":{"running":true,"singlestep":false,"status":"paused"}} + + ``` + +4. 执行如下 QMP 命令,在任一指定的绝对路径下创建虚拟机快照,例如 /path/to/template 路径,参考命令如下: + + ```shell + <- {"execute":"migrate", "arguments":{"uri":"file:/path/to/template"}} + -> {"return":{}} + + ``` + +5. 确认快照是否创建成功。 + + ```shell + <- {"execute":"query-migrate"} + + ``` + + 如果回显 {"return":{"status":"completed"}} ,说明快照创建成功。 + + 快照创建成功,会在指定路径 /path/to/template 生成 memory 和 state 两个目录。`state`文件包含虚拟机设备状态的信息,`memory`文件包含虚拟机内存的数据信息,memory 文件大小接近配置的虚拟机内存。 + +### 查询快照状态 + +当前在整个快照过程中,存在5种状态: + +- `None`: 快照资源没有准备完成 +- `Setup`: 快照资源准备完成,可以进行快照 +- `Active`: 处于制作快照状态中 +- `Completed`: 快照制作成功 +- `Failed`: 快照制作失败 + +可以通过在 Host 执行`query-migrate`qmp 命令查询当前快照的状态,如当虚拟机快照制作成功时查询: + +```shell +<- {"execute":"query-migrate"} +-> {"return":{"status":"completed"}} +``` + +### 恢复虚拟机 + +#### 注意事项 + +- 快照以及从快照启动特性支持的机型包括: + - microvm + - q35(x86_64) + - virt(aarch64平台) +- 在使用快照恢复时,配置的设备必须与制作快照时保持一致 +- 当使用 microvm 机型,并且在快照前使用了磁盘/网卡的热插特性,在恢复时需要将热插的磁盘/网卡配置进启动命令行 + +#### 从快照文件中恢复虚拟机 + +**命令格式** + +```shell +stratovirt -incoming URI + +``` + +**参数说明** + +URI:快照的路径,当前版本只支持 `file` 类型,后加上快照文件的绝对路径 + +**示例** + +假设制作快照所使用的虚拟机是通过以下命令创建的: + +```shell +$ stratovirt \ + -machine microvm \ + -kernel /path/to/kernel \ + -smp 1 -m 1024 \ + -append "console=ttyS0 pci=off reboot=k quiet panic=1 root=/dev/vda" \ + -drive file=/path/to/rootfs,id=rootfs,readonly=off,direct=off \ + -device virtio-blk-device,drive=rootfs \ + -qmp unix:/path/to/socket,server,nowait \ + -serial stdio + +``` + +那么,使用快照恢复虚拟机的参考命令如下(此处假设快照存放的路径为 /path/to/template ): + +```shell +$ stratovirt \ + -machine microvm \ + -kernel /path/to/kernel \ + -smp 1 -m 1024 \ + -append "console=ttyS0 pci=off reboot=k quiet panic=1 root=/dev/vda" \ + -drive file=/path/to/rootfs,id=rootfs,readonly=off,direct=off \ + -device virtio-blk-device,drive=rootfs \ + -qmp unix:/path/to/another_socket,server,nowait \ + -serial stdio \ + -incoming file:/path/to/template + +``` + +## 虚拟机热迁移 + +### 简介 + +StratoVirt 提供了虚拟机热迁移能力,也就是在虚机业务不中断的情况下,将虚拟机从一台服务器迁移到另一台服务器。 + +下列情形,可以使用虚拟机热迁移: + +- 当服务器负载过重时,可以使用虚拟机热迁移技术,将虚拟机迁移到另一台物理服务器上,达到负载均衡的目的。 +- 如果需要维护服务器,该服务器上的虚拟机可以在不中断业务的情形下,迁移到另一台物理服务器上。 +- 服务器出现故障,需要更换硬件或者调整组网时,为了避免虚拟机业务中断,可以将运行的虚拟机迁移到另一台物理机上。 + +### 热迁移操作 + +此处介绍热迁移虚拟机的操作方法,供用户参考。 + +**准备热迁移** + +1.使用 `root` 帐号,登录源端虚拟机所在的主机,执行如下命令(命令行参数,请根据实际情况修改),启动源端虚拟机。 + +```shell +./stratovirt \ + -machine q35 \ + -kernel ./vmlinux.bin \ + -append "console=ttyS0 pci=off reboot=k quiet panic=1 root=/dev/vda" \ + -drive file=path/to/rootfs,id=rootfs,readonly=off,direct=off \ + -device virtio-blk-pci,drive=rootfs,id=rootfs,bus=pcie.0,addr=0 \ + -qmp unix:path/to/socket1,server,nowait \ + -serial stdio \ +``` + +2.使用 `root` 帐号,登录目的端虚拟机所在的主机,执行如下命令(命令行参数需要和启动源端虚拟机保持一致),启动目的端虚拟机。 + +```shell +./stratovirt \ + -machine q35 \ + -kernel ./vmlinux.bin \ + -append "console=ttyS0 pci=off reboot=k quiet panic=1 root=/dev/vda" \ + -drive file=path/to/rootfs,id=rootfs,readonly=off,direct=off \ + -device virtio-blk-pci,drive=rootfs,id=rootfs,bus=pcie.0,addr=0 \ + -qmp unix:path/to/socket2,server,nowait \ + -serial stdio \ + -incoming tcp:192.168.0.1:4446 \ +``` + +> ![](./public_sys-resources/icon-note.gif)**说明** +> +> - 目的端虚拟机的启动命令行参数需要与源端虚拟机命令行保持一致。 +> - 如果需要将热迁移数据传输模式从 `TCP` 网络协议改为 `UNIX socket` 通信协议, + 只需要将目的端虚拟机的命令行 `-incoming tcp:192.168.0.1:4446`,改为 `-incoming unix:/tmp/stratovirt-migrate.socket`。但 `UNIX socket` 协议只支持单物理主机的不同虚拟机之间热迁移。 + +**开始热迁移** + +在源端虚拟机所在的主机,执行如下命令,启动虚拟机热迁移任务。 + +```shell +$ ncat -U path/to/socket1 +-> {"QMP":{"version":{"StratoVirt":{"micro":1,"minor":0,"major":0},"package":""},"capabilities":[]}} +<- {"execute":"migrate", "arguments":{"uri":"tcp:192.168.0.1:4446"}} +-> {"return":{}} +``` + +> ![](./public_sys-resources/icon-note.gif)**说明** +> +> 如果热迁移传输协议为 `UNIX socket` 通信协议,只需要将 QMP 命令中的 `"uri":"tcp:192.168.0.1:4446"`,改为 `"uri":"unix:/tmp/stratovirt-migrate.socket"`。 + +**结束热迁移** + +当执行上述迁移 `QMP` 命令后,虚拟机热迁移任务就开始执行。如果没有热迁移错误日志,则源端的虚拟机就迁移到了目的端,源端虚拟机会自动销毁。 + +### 取消热迁移 + +在热迁移过程中,可能出现迁移时间较长,或目的端虚拟机所在的主机负载发生变化,需要调整迁移策略。StratoVirt 提供了取消热迁移操作的特性。 + +取消热迁移的操作如下: +登录源端虚拟机所在的主机,执行如下 `QMP` 命令: + +```shell +$ ncat -U path/to/socket1 +-> {"QMP":{"version":{"StratoVirt":{"micro":1,"minor":0,"major":0},"package":""},"capabilities":[]}} +<- {"execute":"migrate_cancel"} +-> {"return":{}} +``` + +如果目的端虚拟机退出热迁移任务,并在日志提示取消热迁移,表示热迁移任务取消成功。 + +### 查询热迁移状态 + +热迁移存在如下几种状态: + +- `None`: 热迁移 vCPU,内存,设备等资源没有准备完成 +- `Setup`: 热迁移资源准备完成,可以进行热迁移 +- `Active`: 处于制作热迁移过程中 +- `Completed`: 热迁移完成 +- `Failed`: 热迁移失败 + +以下 `QMP` 命令表示查询当前热迁移处于完成状态: + +```shell +$ ncat -U path/to/socket +-> {"QMP":{"version":{"StratoVirt":{"micro":1,"minor":0,"major":0},"package":""},"capabilities":[]}} +<- {"execute":"query-migrate"} +-> {"return":{"status":"completed"}} +``` + +### 约束与限制 + +StratoVirt 只支持标准虚机主板热迁移: + +- q35 (x86_64平台) +- virt (aarch64平台) + +以下设备和特性不支持热迁移: + +- vhost-net 设备 +- vhost-user-net 设备 +- virtio balloon 设备 +- vfio 设备 +- 共享后端存储 +- 共享内存,后端内存特性 + +以下启动源端和目的端虚拟机命令行参数必须保持一致: + +- virtio-net: MAC 地址 +- device: BDF 号 +- smp +- m diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/_menu.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..351a4a7c8211379e6795b75fab0c5d237c8da33d --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/_menu.md @@ -0,0 +1,23 @@ +--- +label: 'StratoVirt用户指南' +ismanual: 'Y' +href: './StratoVirt_guidence.md' +description: 'StratoVirt是计算产业中面向云数据中心的企业级虚拟化平台,实现了一套架构支持虚拟机、容器、Serverless三种场景' +children: + - label: 'StratoVirt介绍' + href: './StratoVirt_introduction.md' + - label: '安装StratoVirt' + href: './Install_StratoVirt.md' + - label: '准备使用环境' + href: './Prepare_env.md' + - label: '虚拟机配置' + href: './VM_configuration.md' + - label: '虚拟机管理' + href: './VM_management.md' + - label: '对接iSula安全容器' + href: './interconnect_isula.md' + - label: '对接libvirt' + href: './Interconnect_libvirt.md' + - label: 'StratoVirt VFIO 使用说明' + href: './StratoVirt_VFIO_instructions.md' +--- \ No newline at end of file diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/figures/StratoVirt_architecture.jpg b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/figures/StratoVirt_architecture.jpg new file mode 100644 index 0000000000000000000000000000000000000000..93f1697131dd2a6f8c010def9f42ad067b9b0bd9 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/figures/StratoVirt_architecture.jpg differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/interconnect_isula.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/interconnect_isula.md new file mode 100644 index 0000000000000000000000000000000000000000..cbeded1d6d47ce3605c80bb03cbdc5b46d8e1662 --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/interconnect_isula.md @@ -0,0 +1,220 @@ +# 对接iSula安全容器 + +## 概述 + +为了给容器提供更好的隔离环境,提高系统安全性,可以使用 iSula 安全容器,即将 StratoVirt 对接 iSula 安全容器。 + +## 对接iSula安全容器 + +### **前提条件** + +已安装 iSulad 和 kata-containers,并确保 iSulad 支持 containerd-kata-shim-v2 容器运行时和 devicemapper 存储驱动。 + +此处给出安装 iSulad 和 kata-containers 并进行相应配置的参考方法。 + +1. 配置 yum 源,使用 root 权限安装 iSulad 和 kata-containers : + + ```shell + # yum install iSulad + # yum install kata-containers + ``` + +2. 制作并配置存储 Storage: + + 需要用户规划好磁盘如/dev/sdxx,该磁盘会被格式化。 + + ```shell + # pvcreate /dev/sdxx + # vgcreate isulaVG0 /dev/sdxx + # lvcreate --wipesignatures y -n thinpool isulaVG0 -l 95%VG + # lvcreate --wipesignatures y -n thinpoolmeta isulaVG0 -l 1%VG + # lvconvert -y --zero n -c 512K --thinpool isulaVG0/thinpool --poolmetadata isulaVG0/thinpoolmeta + ``` + + 在配置文件 /etc/lvm/profile/isulaVG0-thinpool.profile 中添加如下: + + ```conf + activation { + thin_pool_autoextend_threshold=80 + thin_pool_autoextend_percent=20 + } + ``` + + 更改配置文件/etc/isulad/daemon.json中的storage-driver 和 storage-opts 如下:将默认存储驱动类型 overlay 配置成 devicemapper 。 + + ```conf + "storage-driver": "devicemapper", + "storage-opts": [ + "dm.thinpooldev=/dev/mapper/isulaVG0-thinpool", + "dm.fs=ext4", + "dm.min_free_space=10%" + ], + ``` + +3. 重启 isulad : + + ```shell + # systemctl daemon-reload + # systemctl restart isulad + ``` + +4. 确认 iSula 存储驱动是否配置成功: + + ```shell + # isula info + ``` + + 若回显有如下信息,说明配置成功。 + + ```shell + Storage Driver: devicemapper + ``` + +### **对接指导** + +StratoVirt 通过对接 kata-containers来接入 isula 容器生态,此处给出对接 kata-containers 的操作指导。 + +#### 对接轻量虚拟机 + +1. 修改 kata 配置文件(默认路径为 /usr/share/defaults/kata-containers/configuration.toml,也可以参考同一目录下的configration-stratovirt.toml进行配置) 。将安全容器的 hypervisor 类型修改为 stratovirt,kernel 修改为 kata-containers 的 kernel 镜像绝对路径,initrd 修改为 kata-containers 的 initrd 镜像文件(使用 yum 安装 kata-containers 时,默认会下载这两个镜像文件并存放在 /var/lib/kata/ 目录,配置时也可以使用其他镜像 )。 + + 替换的配置内容参考如下: + + ```conf + [hypervisor.stratovirt] + path = "/usr/bin/stratovirt" + kernel = "/var/lib/kata/kernel" + initrd = "/var/lib/kata/kata-containers-initrd.img" + machine_type = "microvm" + block_device_driver = "virtio-mmio" + use_vsock = true + enable_netmon = true + internetworking_model="tcfilter" + sandbox_cgroup_with_emulator = false + disable_new_netns = false + disable_block_device_use = false + disable_vhost_net = true + ``` + +2. 使用 root 权限和 **isula** 命令运行 busybox 安全容器,完成 StratoVirt 和 安全容器的对接。 + + ```shell + # isula run -tid --runtime "io.containerd.kata.v2" --net=none --name test busybox:latest sh + ``` + +3. 使用 **isula ps** 确认安全容器 test 正常运行,然后通过以下命令进入 test 容器。 + + ```shell + # isula exec -ti test sh + ``` + +4. 通过虚拟机快照加速安全容器的启动速度,降低虚拟机内存开销。 + + 修改 kata 配置文件 configuration.toml,将配置项 enable_template 设置为 true,即允许虚拟机通过制作快照方式进行启动: + + ```conf + [factory] + # VM templating support. Once enabled, new VMs are created from template + # using vm cloning. They will share the same initial kernel, initramfs and + # agent memory by mapping it readonly. It helps speeding up new container + # creation and saves a lot of memory if there are many kata containers running + # on the same host. + # + # When disabled, new VMs are created from scratch. + # + # Note: Requires "initrd=" to be set ("image=" is not supported). + # + # Default false + enable_template = true + ``` + + 配置项 enable_template 设置为 true 后,kata-containers 创建安全容器时,将会检查默认路径(/run/vc/vm/template)下是否存在快照文件,如果存在,直接以该快照文件启动虚拟机,如果不存在,则会创建虚拟机快照,创建完成后,以该快照文件启动虚拟机。 + +5. 通过安全组件 ozone 进一步增强安全容器的隔离性。 + + 修改 kata 配置文件 configuration.toml,将配置项 ozone_path 设置为 ozone 可执行文件的路径(如果使用 yum 安装 stratovirt,ozone 可执行文件默认在 /usr/bin 目录下)。配置该项后,将打开 ozone 安全沙箱功能,作为虚拟化层隔离被攻击者突破后的保险,进一步增强 StratoVirt 安全容器的隔离性: + + ```conf + # Path for the ozone specific to stratovirt + # If the ozone path is set, stratovirt will be launched in + # ozone secure environment. It is disabled by default. + ozone_path = "/usr/bin/ozone" + ``` + + 至此,可以在 test 容器内运行容器命令。 + +#### 对接标准虚拟机 + +使用 StratoVirt 标准虚拟机作为安全容器的 sandbox,需要额外修改少量配置。具体步骤如下: + +1. 配置参考如下: + + ```conf + [hypervisor.stratovirt] + path = "/usr/bin/stratovirt" + kernel = "/var/lib/kata/kernel" + initrd = "/var/lib/kata/kata-containers-initrd.img" + # x86_64 架构 + machine_type = "q35" + # aarch64 架构 + machine_type = "virt" + block_device_driver = "virtio-blk" + pcie_root_port = 2 + use_vsock = true + enable_netmon = true + internetworking_model = "tcfilter" + sandbox_cgroup_with_emulator = false + disable_new_netns = false + disable_block_device_use = false + disable_vhost_net = true + ``` + + 上述配置中,需要根据主机架构,修改对应的虚拟机机型。需要将 block_device_driver 驱动类型改为 virtio-blk。另外,StratoVirt 只支持将设备热插到root port,根据需要热插的设备数量,合理设置 pcie_root_port 值。 + +2. 安装启动标准虚拟机需要的固件 + + x86_64 架构: + + ```shell + # yum install -y edk2-ovmf + ``` + + aarch64 架构: + + ```shell + # yum install -y edk2-aarch64 + ``` + +3. 编译替换为 kata-containers 2.x 版本二进制 + + 当前只为 kata-containers 2.x 版本(对应 kata-containers 源码仓的 openEuler-21.09 分支)适配了 StratoVirt 标准虚拟机作为 sandbox。因此,需要手动下载 kata-containers 源码,编译并替换 `/usr/bin` 目录下的 containerd-shim-kata-v2 二进制文件。 + + ```shell + # mkdir -p /root/go/src/github.com/ + # cd /root/go/src/github.com/ + # git clone https://gitee.com/src-openeuler/kata-containers.git + # cd kata-containers + # git checkout openEuler-21.09 + # ./apply-patches + # cd src/runtime + # make + ``` + + 编译出的二进制位 containerd-shim-kata-v2,需要将默认 `/usr/bin/` 目录的 kata 二进制备份后替换: + + ```shell + # cp /usr/bin/containerd-shim-kata-v2 /usr/bin/containerd-shim-kata-v2.bk + # cp containerd-shim-kata-v2 /usr/bin/containerd-shim-kata-v2 + ``` + +4. 使用 root 权限 和 **isula** 命令运行 busybox 安全容器,完成 StratoVirt 和 安全容器的对接。 + + ```shell + # isula run -tid --runtime "io.containerd.kata.v2" --net=none --name test busybox:latest sh + ``` + +5. 使用 **isula ps** 确认安全容器 test 正常运行,然后通过以下命令进入 test 容器。 + + ```shell + # isula exec -ti test sh + ``` diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/public_sys-resources/icon-note.gif b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/StratoVirt/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/LibcarePlus.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/LibcarePlus.md new file mode 100644 index 0000000000000000000000000000000000000000..3f74c301f0e8843468835381f24ddfd6c0a8fbfa --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/LibcarePlus.md @@ -0,0 +1,487 @@ +# LibcarePlus + +- [概述](#概述) +- [软硬件要求](#软硬件要求) +- [注意事项和约束](#注意事项和约束) +- [安装 LibcarePlus](#安装-libcareplus) +- [制作 LibcarePlus 热补丁](#制作-libcareplus-热补丁) +- [应用 LibcarePlus 热补丁](#应用-libcareplus-热补丁) +- [使用 LibcarePlus 工具制作 qemu 热补丁](#使用-libcareplus-工具制作-qemu-热补丁) + +## 概述 + +LibcarePlus 是一个用户态进程热补丁框架,可以在不重启进程的情况下对 Linux 系统上运行的目标进程进行热补丁操作。热补丁可以应用于 CVE 漏洞修复,也可以应用于不中断应用服务的紧急 bug 修复。 + +## 软硬件要求 + +在 openEuler 上使用 LibcarePlus,需要满足一定的软硬件要求: + +- 当前LibcarePlus支持 x86 体系架构和arm64体系架构。 +- LibcarePlus 可以在任何支持安装 **libunwind**、 **elfutils** 以及 **binutils** 的 Linux 发行版系统上运行。 +- LibcarePlus 使用ptrace()系统调用,需要对应Linux发行版本的相关编译选项支持。 +- LibcarePlus 制作热补丁时,依赖原可执行文件的符号表,因此,请勿过早将符号表strip掉。 +- 对于开启selinux的Linux系统,需要自行适配对应的selinux规则。 + +## 注意事项和约束 + +使用 LibcarePlus,需遵循以下热补丁规范和约束: + +- 仅支持对 C 语言编写的代码,不支持汇编语言等。 +- 代码文件名必须符合 C 语言标识符命名规范:由字母(A-Z,a-z)、数字 (0-9)、下划线“_”组成;并且首字符不能是数字,但可以是字母或者下划线;不能包含“-”、“$”等特殊符号。 +- 支持增量补丁,即支持对进程打多个补丁,但补丁加卸载管理需使用者执行设计,一般遵循FILO规则。 +- 不支持补丁自动加载,对于特定进程,需使用者自行设计。 +- 支持补丁查询功能。 +- 静态函数补丁受限于系统中能找到该函数的符号表。 +- 热补丁为进程粒度,即动态库热补丁只能对调用这个动态库的进程打补丁。 +- 单个进程支持的补丁数受限于跳转指令的跳转范围和虚拟内存地址空洞大小,一般支持[1, 512]。 +- 对于TLS变量,仅支持修改IE模式的TLS变量。 +- 后续补丁不能使用之前补丁中定义的符号。 +- 以下场景不支持热补丁: + - 死循环函数、不退出函数、inline 函数、初始化函数、NMI 中断处理函数 + - 替换全局变量 + - 小于5字节的短函数 + - 修改头文件 + - 增加和删除目标函数的出参和入参 + - 数据结构成员变化(新增、删除、修改) + - 修改包含 __LINE__ , __FILE__ 等gcc编译宏的 C 文件 + - 修改 intel 矢量汇编指令 + +## 安装 LibcarePlus + +### 安装软件依赖 + +LibcarePlus 运行依赖于 **libunwind**、 **elfutils** 和 **binutils**,在配置了 yum 源的 openEuler 系统上,可以参考如下命令安装 LibcarePlus 的依赖软件。 + +``` shell +# yum install -y binutils elfutils elfutils-libelf-devel libunwind-devel +``` + +#### 安装 LibcarePlus + +```shell +# yum install libcareplus libcareplus-devel -y +``` + +查看安装是否成功: + +``` shell +# libcare-ctl -h +usage: libcare-ctl [options] [args] + +Options: + -v - verbose mode + -h - this message + +Commands: + patch - apply patch to a user-space process + unpatch- unapply patch from a user-space process + info - show info on applied patches + +``` + +## 制作 LibcarePlus 热补丁 + +### 概述 + +LibcarePlus 支持如下方式制作热补丁: + +- 手动制作 +- 通过脚本制作 + +手动制作热补丁的过程繁琐,对于代码量较大的工程,例如QEMU,手动制作热补丁极其困难。建议使用 LibcarePlus 自带脚本一键式地生成热补丁文件。 + +#### 手动制作 + +本节以原文件 foo.c 和补丁文件 bar.c 为例,给出手动制作热补丁的指导。 + +1. 准备 C 语言编写的原文件和补丁文件。例如原文件 foo.c 和补丁文件 bar.c 。 + +
+ 点击展开 foo.c +

+ + ``` c + // foo.c + #include + #include + + void print_hello(void) + { + printf("Hello world!\n"); + } + + int main(void) + { + while (1) { + print_hello(); + sleep(1); + } + } + ``` + +

+
+ +
+ 点击展开 bar.c +

+ + ``` c + // bar.c + #include + #include + + void print_hello(void) + { + printf("Hello world %s!\n", "being patched"); + } + + int main(void) + { + while (1) { + print_hello(); + sleep(1); + } + } + ``` + +

+
+ +2. 编译得到原文件和补丁文件的汇编文件 **foo.s** 和 **bar.s**,参考命令如下: + + ``` shell + # gcc -S foo.c + # gcc -S bar.c + # ls + bar.c bar.s foo.c foo.s + ``` + +3. 使用 **kpatch_gensrc** 对比 foo.s 和 bar.s 差异,生成包含原文件的汇编内容和差异内容的 foobar.s,参考命令如下: + + ``` shell + # sed -i 's/bar.c/foo.c/' bar.s + # kpatch_gensrc --os=rhel6 -i foo.s -i bar.s -o foobar.s --force-global + ``` + + 由于 **kpatch_gensrc** 默认对同一 C 语言原文件进行对比,所以对比前需要使用 sed 命令将补丁汇编文件 bar.s 中的 bar.c 改为原文件名称 foo.c。随后调用 **kpatch_gensrc**,指定输入文件为 foo.s 与 bar.s,输出文件为 foobar.s。 + +4. 编译原文件的汇编文件 foo.s 和生成的汇编文件 foobar.s,得到可执行文件 foo 和 foobar,参考命令如下: + + ``` shell + # gcc -o foo foo.s + # gcc -o foobar foobar.s -Wl,-q + ``` + + 链接选项 **-Wl, -q** 将保留foobar中的重定位节。 + +5. 利用 **kpatch_strip** 去除可执行程序 foo 和 foobar 的相同内容,保留制作热补丁所需要的内容。 + + ``` shell + # kpatch_strip --strip foobar foobar.stripped + # kpatch_strip --rel-fixup foo foobar.stripped + # strip --strip-unneeded foobar.stripped + # kpatch_strip --undo-link foo foobar.stripped + ``` + + 上述命令中的各参数含义为: + + - **--strip** 用于去除 foobar 中对于补丁制作无用的 section; + - **--rel-fixup** 用于修复补丁内所访问的变量以及函数的地址; + - **strip --strip-unneeded** 用于去除对于热补丁重定位操作无用的符号信息; + - **--undo-link** 用于将补丁内符号的地址从绝对地址更改为相对地址。 + +6. 制作热补丁文件。 + + 通过以上操作,已经得到了热补丁制作所需的主要内容。接下来需要使用 **kpatch_make** 将原可执行文件的 **Build ID** 以及 **kpatch_strip** 的输出文件 **foobar.stripped** 作为参数传递给 **kpatch_make**,最终生成热补丁文件,参考命令如下: + + ``` shell + # str=$(readelf -n foo | grep 'Build ID') + # substr=${str##* } + # kpatch_make -b $substr -i 0001 foobar.stripped -o foo.kpatch + # ls + bar.c bar.s foo foobar foobar.s foobar.stripped foo.c foo.kpatch foo.s + ``` + + 至此,就得到了patch ID为0001的热补丁文件 foo.kpatch。 + +#### 通过脚本制作 + +本节介绍如何利用 LibcarePlus 自带的 **libcare-patch-make** 脚本制作热补丁文件,仍以原文件 foo.c 和补丁文件 bar.c 为例。 + +1. 利用 diff 命令生成 foo.c 和 bar.c 的对比文件,命令如下所示: + + ``` shell + # diff -up foo.c bar.c > foo.patch + ``` + + foo.patch 文件内容如下所示: + +
+ 点击展开 foo.patch +

+ + ``` diff + --- foo.c 2020-12-09 15:39:51.159632075 +0800 + +++ bar.c 2020-12-09 15:40:03.818632220 +0800 + @@ -1,10 +1,10 @@ + -// foo.c + +// bar.c + #include + #include + + void print_hello(void) + { + - printf("Hello world!\n"); + + printf("Hello world %s!\n", "being patched"); + } + + int main(void) + ``` + +

+
+ +2. 编写编译 foo.c 的 Makefile 文件,具体如下所示: + +
+ 点击展开 Makefile +

+ + ``` makefile + all: foo + + foo: foo.c + $(CC) -o $@ $< + + clean: + rm -f foo + + install: foo + mkdir $$DESTDIR || : + cp foo $$DESTDIR + ``` + +

+
+ +3. 编写好 Makefile 之后,直接调用 **libcare-patch-make** 即可。若 **libcare-patch-make** 询问选择哪个文件进行打补丁操作,输入原文件名即可,具体如下所示: + + ``` shell + # libcare-patch-make --clean -i 0001 foo.patch + rm -f foo + BUILDING ORIGINAL CODE + /usr/local/bin/libcare-cc -o foo foo.c + INSTALLING ORIGINAL OBJECTS INTO /libcareplus/test/lpmake + mkdir $DESTDIR || : + cp foo $DESTDIR + applying foo.patch... + can't find file to patch at input line 3 + Perhaps you used the wrong -p or --strip option? + The text leading up to this was: + -------------------------- + |--- foo.c 2020-12-10 09:43:04.445375845 +0800 + |+++ bar.c 2020-12-10 09:48:36.778379648 +0800 + -------------------------- + File to patch: foo.c + patching file foo.c + BUILDING PATCHED CODE + /usr/local/bin/libcare-cc -o foo foo.c + INSTALLING PATCHED OBJECTS INTO /libcareplus/test/.lpmaketmp/patched + mkdir $DESTDIR || : + cp foo $DESTDIR + MAKING PATCHES + Fixing up relocation printf@@GLIBC_2.2.5+fffffffffffffffc + Fixing up relocation print_hello+0 + patch for /libcareplus/test/lpmake/foo is in /libcareplus/test/patchroot/700297b7bc56a11e1d5a6fb564c2a5bc5b282082.kpatch + ``` + + 执行成功之后,输出显示:热补丁文件位于当前目录的 **patchroot** 目录下,可执行文件则在 **lpmake** 目录下。脚本生成的热补丁文件默认是采用 Build ID 作为热补丁文件的文件名。 + +## 应用 LibcarePlus 热补丁 + +本节以原文件 **foo.c** 和补丁文件 **bar.c** 为例,介绍 LibcarePlus 热补丁的应用指导。 + +### 前期准备 + +应用 LibcarePlus 热补丁之前,需要提前准备好原可执行程序 foo、以及热补丁文件 foo.kpatch。 + +### 加载热补丁 + +本节介绍应用 LibcarePlus 热补丁的具体流程。 + +1. 首先在第一个 shell 窗口运行需要打补丁的可执行程序,如下所示: + + ``` shell + # ./lpmake/foo + Hello world! + Hello world! + Hello world! + ``` + +2. 随后在第二个 shell 窗口运行 **libcare-ctl** 应用热补丁,命令如下所示: + + ``` shell + # libcare-ctl -v patch -p $(pidof foo) ./patchroot/BuildID.kpatch + ``` + + 若此时热补丁应用成功,第二个 shell 窗口会有如下输出: + + ``` shell + 1 patch hunk(s) have been successfully applied to PID '10999' + ``` + + 而第一个 shell 窗口内运行的目标进程则会出现如下输出: + + ``` shell + Hello world! + Hello world! + Hello world being patched! + Hello world being patched! + ``` + +### 查询补丁 + +本节介绍查询LibcarePlus热补丁的具体流程。 + +1. 在第二个shell窗口执行如下命令: + + ```shell + # libcare-ctl info -p $(pidof foo) + + ``` + + 此时若进程存在已经加载的热补丁,则第二个shell窗口会有如下输出: + + ```shell + Pid: 551763 + Target: foo + Build id: df05a25bdadd282812d3ee5f0a460e69038575de + Applied patch number: 1 + Patch id: 0001 + ``` + +### 卸载热补丁 + +本节介绍卸载 LibcarePlus 热补丁的具体流程。 + +1. 在第二个 shell 窗口执行如下命令: + + ``` shell + # libcare-ctl unpatch -p $(pidof foo) -i 0001 + ``` + + 此时若热补丁卸载成功,第二个 shell 窗口会有如下输出: + + ``` shell + 1 patch hunk(s) were successfully cancelled from PID '10999' + ``` + +2. 第一个 shell 窗口内运行的目标进程则会出现如下输出: + + ``` shell + Hello world being patched! + Hello world being patched! + Hello world! + Hello world! + ``` + +## 使用 LibcarePlus 工具制作 qemu 热补丁 + +制作方法如下: + +### 1.下载qemu制品仓代码,保持代码版本与openEuler环境中qemu版本一致 + + ```shell +# 下载qemu源码并解压 +yum download --source qemu +rpm2cpio qemu-8.2.0-13.oe2403.src.rpm | cpio -id + ``` + +### 2.编译qemu制品仓代码 + +- 将解压后的qemu源码挪至/root/rpmbuild/SOURCES(由多个patch、一个qemu.spec、一个qemu-8.2.0.tar.xz组成) + +- 编译qemu.spec + + ```shell + rpmbuild -ba qemu.spec + ``` + +有两份成果物: + +- /root/rpmbuild/BUILD/qemu-8.2.0中生成中间代码,为编译qemu对应代码。将代码拷贝到/home/abuild/rpmbuild/BUILD/qemu-8.2.0,编译环境的路径也会影响补丁地址的偏移。 +- /root/rpmbuild/RPMS/中生成qemu相关的rpm包。 + +### 3.制作热补丁所需的patch文件 + + 使用git format-patch指令制作patch即可。 + + ```shell + # cat 0001-hack-hmp-qtree-info.patch + From bb2f4e6fe43ca7b3d73026966ac3411b2d8342b9 Mon Sep 17 00:00:00 2001 + From: zhangsan + Date: Mon, 7 Mar 2022 20:53:41 +0800 + Subject: [PATCH 1/3] hack hmp qtree info + + --- + softmmu/qdev-monitor.c | 1 + + 1 file changed, 1 insertion(+) + + diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c + index 05e1d88d99..96fd596c2e 100644 + --- a/softmmu/qdev-monitor.c + +++ b/softmmu/qdev-monitor.c + @@ -833,6 +833,7 @@ static void qbus_print(Monitor *mon, BusState *bus, int indent) + + void hmp_info_qtree(Monitor *mon, const QDict *qdict) + { + + fprintf(stderr, "---------------you hack me---------------------"); + if (sysbus_get_default()) + qbus_print(mon, sysbus_get_default(), 0); + } + -- + 2.33.0 + + ``` + +### 4.配置/etc/libcare.conf + + /etc/libcare.conf填上patch文件修改的函数,用于后续制作补丁时,过滤掉不相关的函数; + 当前修改内容如下: + + ```shell + # cat /etc/libcare.conf + hmp_info_qtree + ``` + +### 5.查看qemu buildID + + ```shell + # whereis qemu-kvm + qemu-kvm: /usr/bin/qemu-kvm /usr/libexec/qemu-kvm + # file /usr/libexec/qemu-kvm + /usr/libexec/qemu-kvm: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=68f4ec13e140d3a688f3e0fb93442b8c7a86be8b, for GNU/Linux 3.7.0, stripped + ``` + +注:需保持制作热补丁的环境和制作qemu包环境一致,buildID可作为二者是否一致的判定标准。因用户无qemu版本的制作环境,故可以自行编包并安装,使用自编包中的/usr/libexec/qemu-kvm的buildID。 + +### 6.制作热补丁 + +在/home/abuild/rpmbuild/BUILD/qemu-8.2.0/build中执行热补丁制作指令,**注意是build目录!!!** + +```shell +# libcare-patch-make --clean -s ../ 0002-patch-hello-qdm.patch -i 0001 --buildid=68f4ec13e140d3a688f3e0fb93442b8c7a86be8b -j 64 +``` + +参数说明: + +--clean 类似make clean + +-s ../ 指定源文件夹,这里是上层目录 + +-i 0001 热补丁id + +buildid=xxx 保持和系统中qemu-kvm buildid一致 + +-j 64 多线程编译 diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/Skylark.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/Skylark.md new file mode 100644 index 0000000000000000000000000000000000000000..687960d8e2538601ba58ef40c952faf64e2ef62a --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/Skylark.md @@ -0,0 +1,201 @@ +# Skylark + + + +- [Skylark概述](#skylark概述) +- [架构及特性](#架构及特性) +- [安装Skylark](#安装skylark) +- [配置Skylark](#配置skylark) +- [使用Skylark](#使用skylark) +- [最佳实践](#最佳实践) + + + +## Skylark概述 + +### 问题背景 + +随着云计算市场规模的快速增长,各云厂商基础设施投入也不断增加。资源利用率低是行业普遍存在的问题,在上述背景下,提升资源利用率已经成为了一个重要的技术课题。本文档介绍 openEuler Skylark 组件,并给出安装方法及使用指导。 + +### 总体介绍 + +将业务区分优先级混合部署(下文简称混部)是典型有效的资源利用率提升手段。业务可根据时延敏感性分为高优先级业务和低优先级业务。当高优先级业务和低优先级业务发生资源竞争时,需优先保障高优先级业务的资源供给。因此,业务混部的核心技术是资源隔离控制,主要涉及内核态基础资源隔离技术及用户态 QoS 控制技术。 + +本文描述的对象为用户态 QoS 控制技术,由 openEuler Skylark 组件承载,首发于 openEuler 22.09 版本。在 Skylark 视角下,优先级粒度为虚拟机级别,即给虚拟机新增高低优先级属性,以虚拟机为粒度进行资源的隔离和控制。Skylark 是一种混部场景下的 QoS 感知的资源调度器,在保障高优先级虚拟机 QoS 前提下提升物理机资源利用率。 + +在实际应用场景中如何更好地利用 Skylark 的高低优先级特性,请参考[最佳实践](#最佳实践)章节。 + +## 架构及特性 + +### 总体实现框架 + +Skylark 核心类为`QoSManager`,类成员包括数据收集类实例、QoS 分析类实例、QoS 控制类实例、以及任务调度类实例: + +- `DataCollector`:数据收集类,有`HostInfo`和`GuestInfo`两个成员,分别用于收集主机信息和虚拟机信息。 +- `PowerAnalyzer`:功耗分析类,用于分析功耗干扰以及需要限制的低优先级虚拟机。 +- `CpuController`:CPU 带宽控制类,用于限制低优先级虚拟机的 CPU 带宽。 +- `CacheMBWController`:LLC 及内存带宽控制类,用于限制低优先级虚拟机的 LLC 和内存带宽。 +- `BackgroundScheduler`:任务调度类,用于周期性驱动以上模块,持续进行 QoS 管理。 + +Skylark 检查主机环境后,创建守护进程。守护进程有两种线程:主调度线程和 Job 线程: + +- 主调度线程是唯一的,首先连接 Libvirt,然后创建并初始化`QosManager`类实例,最后开始驱动 Job 线程。 +- Job 线程可能不止一个,每个 Job 线程负责周期性执行某个 QoS 管理任务。 + +### 功耗干扰控制 + +相比非混部情况,混部后主机利用率更高,高利用率意味着高功耗,服务器功耗在超过 TDP 时会触发 CPU 降频。Skylark 支持当功耗超过预设的 TDP 阈值(即出现 TDP 热点)时,通过对低优先级虚拟机的 CPU 带宽进行限制,以此达到降低整机功耗的同时保障高优先级虚拟机 QoS。 + +Skylark 初始化时,根据[配置Skylark](#配置skylark)中相关配置值,设置功耗干扰控制属性。在每个控制周期,综合分析主机信息和控制属性,判断是否出现 TDP 热点。如果出现热点,进一步根据虚拟机信息分析出需要对哪些低优先级虚拟机进行 CPU 带宽的限制。 + +### LLC/MB干扰控制 + +Skylark 支持对低优先级虚拟机的 LLC 和内存带宽进行限制,当前仅支持静态分配。Skylark 通过操作系统提供的`/sys/fs/resctrl`接口来限制低优先级虚拟机的 LLC 和内存带宽。 + +1. Skylark 在`/sys/fs/resctrl`目录下建立`low_prio_machine`文件夹,并将低优先级虚拟机的 pid 写入`/sys/fs/resctrl/low_prio_machine/tasks`文件中。 +2. Skylark 根据[配置Skylark](#配置skylark)章节中 LLC/MB 相关配置项对低优先级虚拟机的 LLC ways 和内存带宽进行分配,配置项写入`/sys/fs/resctrl/low_prio_machine/schemata`文件中。 + +### CPU干扰控制 + +混部场景下,低优先级虚拟机会对高优先级虚拟机产生 CPU 时间片干扰和 SMT(硬件超线程)干扰。 + +- 当高低优先级虚拟机相关线程在同一个最小 CPU 拓扑单元(core 或 SMT)上同时处于可运行状态时,会竞争 CPU 时间片。 +- 当高低优先级虚拟机相关线程在同一个 CPU core 的不同 SMT 上同时处于可运行状态时,会竞争 SMT 共享的 core 内资源。 + +CPU 干扰控制分为 CPU 时间片干扰控制及 SMT 干扰控制,分别基于内核提供的 `QOS_SCHED` 及 `SMT_EXPELLER` 特性实现。 + +- `QOS_SCHED` 特性实现了单个 CPU core 或 SMT 上高优先级虚拟机对低优先级虚拟机的绝对压制,解决了 CPU 时间片干扰问题。 +- `SMT_EXPELLER` 特性实现了同一个 CPU core 的不同 SMT 上高优先级虚拟机对低优先级虚拟机的绝对压制,解决了 SMT 干扰问题。 + +Skylark 初始化时,会把 Cgroup CPU 子控制器下低优先级虚拟机对应 slice 层级的`cpu.qos_level`字段设置为 -1,以使能上述内核特性,后续就由内核实现对 CPU 相关干扰的控制,Skylark 无需介入。 + +## 安装Skylark + +### 硬件要求 + +处理器架构:仅支持 AArch64 和 Intel x86_64 处理器架构。 + +- Intel 处理器需支持 RDT 功能。 +- AArch64 当前仅支持 Kunpeng920,且需将 bios 升级到 1.79 及以上以支持 MPAM 功能。 + +### 软件要求 + +- 依赖 python3、python3-APScheduler、python3-libvirt 等 python 组件。 +- 依赖 systemd 组件,版本 >= 249-32 +- 依赖 libvirt 组件,版本 >= 1.0.5 +- 依赖 openEuler 内核,版本 >= 5.10.0 + +### 安装方法 + +推荐使用 yum 安装 Skylark 组件,因为 yum 会自动处理上述软件依赖: + +```shell +# yum install -y skylark +``` + +检查 Skylark 是否安装成功,若安装成功则会显示 skylarkd 后台服务状态: + +```shell +# systemctl status skylarkd +``` + +设置 Skylark 服务开机自启动(可选): + +```shell +# systemctl enable skylarkd +``` + +## 配置Skylark + +安装好 Skylark 组件后,若默认配置不满足需求,可修改配置文件。Skylark 的配置文件路径为`/etc/sysconfig/skylarkd`,下面对该配置文件包含的配置项作详细说明。 + +### 日志 + +- `LOG_LEVEL`用于设置最小日志级别,类型为字符串。所有可设置的日志级别及其关系为`critical > error > warning > info > debug`。级别小于`LOG_LEVEL`的日志将不会输出到日志文件。日志文件路径为`/var/log/skylark.log`。Skylark 会每 7 天备份一次日志,最多备份 4 次(当次数超限时,会删除最旧的日志)。备份的日志路径为`/var/log/skylark.log.%Y-%m-%d`。 + +### 功耗干扰控制 + +- `POWER_QOS_MANAGEMENT`用于控制是否打开功耗 QoS 管理功能,类型为布尔。当前仅 x86 支持该功能。如果主机上虚拟机的 CPU 利用率能被很好地限制,该功能可选。 + +- `TDP_THRESHOLD`用于控制虚拟机可达到的最大功耗。当主机功耗超过`TDP * TDP_THRESHOLD`时,将判断为出现 TDP 热点,触发功耗控制操作。类型为 float,可接受的输入范围为 0.8-1,默认值为 0.98。 + +- `FREQ_THRESHOLD`用于控制当主机出现 TDP 热点时,CPU 运行的最低频率。类型为 float,可接受的输入范围为 0.9-1,默认值为 0.98。 + 1. 当存在某些 CPU 的频率低于`max_freq * FREQ_THRESHOLD`时,Skylark 会限制在这些 CPU 上运行的低优先级虚拟机的 CPU 带宽。 + 2. 当找不到这样的 CPU,则 Skylark 也会根据低优先级虚拟机的 CPU 利用率情况,选择性限制某些低优先级虚拟机的 CPU 带宽。 + +- `QUOTA_THRESHOLD`用于控制低优先级虚拟机被限制后所能获得的 CPU 带宽(限制前的 CPU 带宽 * `QUOTA_THRESHOLD`)。类型为 float,可接受的输入范围为 0.8-1,默认值为 0.9。 + +- `ABNORMAL_THRESHOLD`用于控制低优先级虚拟机被限制的周期。类型为 int,可接受的输入范围为 1-5,默认值为 3。 + 1. 在每个功耗控制周期内,如果某个低优先级虚拟机被限制,其剩余被限制周期刷新为`ABNORMAL_THRESHOLD`。 + 2. 否则其剩余被限制周期减 1。当虚拟机的剩余被限制周期等于 0 时,其 CPU 带宽恢复为被限制前的值。 + +### LLC/MB干扰控制 + +Skylark 对 LLC/MB 的干扰控制依赖于硬件使能 RDT/MPAM 功能,Intel x86_64 架构处理器需在内核 cmdline 配置`rdt=cmt,mbmtotal,mbmlocal,l3cat,mba`,Kunpeng920 处理器需在内核 cmdline 配置`mpam=acpi`。 + +- `MIN_LLC_WAYS_LOW_VMS`用于控制低优先级虚拟机可访问的 LLC ways。类型为 int,可接受的输入范围为 1-3,默认值为 2。Skylark 会在初始化时,限制低优先级虚拟机的 LLC ways 为该值。 + +- `MIN_MBW_LOW_VMS`用于控制低优先级虚拟机可访问的内存带宽比例。类型为 float,可接受的输入范围为 0.1~0.2,默认值为 0.1。Skylark 会在初始化时,限制低优先级虚拟机的内存带宽为该值。 + +## 使用Skylark + +### 启动服务 + +初次启动: + +```shell +# systemctl start skylarkd +``` + +重新启动(修改配置文件后需重启): + +```shell +# systemctl restart skylarkd +``` + +### 创建虚拟机 + +Skylark 借助虚拟机 XML 配置文件的`partition`标签标识虚拟机优先级属性。 + +创建低优先级虚拟机,其 XML 需做如下配置: + +```xml + + ... + + /low_prio_machine + + ... + +``` + +创建高优先级虚拟机,其 XML 需做如下配置: + +```xml + + ... + + /high_prio_machine + + ... + +``` + +后续创建虚拟机流程和一般流程无异。 + +### 虚拟机运行 + +Skylark 能感知到虚拟机创建事件,纳管所有高、低优先级虚拟机,并围绕 CPU、功耗、LLC/MB 等资源做自动化 QoS 管理。 + +## 最佳实践 + +### 虚拟机业务推荐 + +- 高优先级虚拟机业务推荐:时延敏感类业务,如 web 服务、高性能数据库、实时渲染、机器学习推理等。 +- 低优先级虚拟机业务推荐:非时延敏感类业务,如视频编码、大数据处理、离线渲染、机器学习训练等。 + +### 虚拟机绑核配置 + +为了让高优先级虚拟机达到最佳性能,推荐高优先级虚拟机 vCPU 与物理 CPU 一对一绑核。为了让低优先级虚拟机充分利用空闲物理资源,推荐低优先级虚拟机 vCPU 范围绑核,且绑核范围覆盖高优先级虚拟机绑核范围。 + +同时为了防止出现因高优先级虚拟机长时间占满 CPU 导致低优先级虚拟机无法被调度的情况,需要预留少量低优先级虚拟机专用的 CPU,该部分 CPU 不可让高优先级虚拟机绑定,且要求让低优先级虚拟机绑定。 diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/_menu.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/_menu.md new file mode 100644 index 0000000000000000000000000000000000000000..64354bf945ac07e2e5b1754c2b02836bddb87f1e --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/_menu.md @@ -0,0 +1,40 @@ +--- +label: '虚拟化用户指南' +ismanual: 'Y' +href: './virtualization.md' +description: '在openEuler系统中使用虚拟化技术创建和管理虚拟机' +children: + - label: '认识虚拟化' + href: './introduction-to-virtulization.md' + - label: '安装虚拟化组件' + href: './virtualization-installation.md' + - label: '准备使用环境' + href: './environment-preparation.md' + - label: '虚拟机配置' + href: './vm-configuration.md' + - label: '管理虚拟机' + href: './managing-vms.md' + - label: '热迁移虚拟机' + href: './vm-live-migration.md' + - label: '管理系统资源' + href: './system-resource-management.md' + - label: '管理设备' + href: './managing-devices.md' + - label: '管理虚拟机可维护性' + href: './vm-maintainability-managment.md' + - label: '最佳实践' + href: './best-practices.md' + - label: '工具使用指南' + href: './tool-guide.md' + children: + - label: 'vmtop' + href: './vmtop.md' + - label: 'LibcarePlus' + href: './LibcarePlus.md' + - label: 'Skylark虚拟机混部' + href: './Skylark.md' + - label: '常见问题与解决办法' + href: './faq.md' + - label: '附录' + href: './appendix.md' +--- \ No newline at end of file diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/appendix.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/appendix.md new file mode 100644 index 0000000000000000000000000000000000000000..51a2185ce6f2d7beedd6a78798c367d4b63f8bef --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/appendix.md @@ -0,0 +1,140 @@ +# 附录 + +## 术语和缩略语 + +文档中使用的术语和缩略语请分别参见[表1](#table201236162279)和[表2](#table1423422319271)。 + +**表 1** 术语表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

术语

+

含义

+

AArch64

+

AArch64 是 ARMv8 架构的一种执行状态。AArch64不仅仅是32位 ARM 构架的扩展,而是ARMv8内全新的构架,完全使用全新的 A64 指令集

+

Domain

+

资源的一个可配置集合,包括内存、虚拟CPU,网络设备和磁盘设备。在 Domain 中运行虚拟机。一个 Domain 被分配虚拟资源,可以独立地被启动、停止和重启。

+

Libvirt

+

一套用于管理虚拟化平台的工具集,可用于管理KVM、QEMU、Xen及其他虚拟化。

+

Guest OS

+

即客户机操作系统,指运行在虚拟机上的操作系统。

+

Host OS

+

即宿主机操作系统,指被虚拟的物理机的操作系统。

+

Hypervisor

+

即虚拟机监视器VMM,是一种运行在基础物理服务器和操作系统之间的中间软件层,可允许多个操作系统和应用共享硬件。

+

虚拟机

+

使用虚拟化技术,通过软件模拟完整的计算机硬件系统功能,构造出的完整虚拟计算机系统。

+
+ +**表 2** 缩略语表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

缩略语

+

英文全称

+

中文全称

+

含义

+

NUMA

+

Non-Uniform Memory Access Architecture

+

非统一内存访问架构

+

NUMA是一种为多处理器计算机设计的内存架构。在NUMA下,处理器访问它自己的本地内存的速度比非本地内存(内存位于另一个处理器,或者是处理器之间共享的内存)快一些。

+

KVM

+

Kernel-based Virtual Machine

+

基于内核的虚拟机

+

KVM是基于内核的虚拟机,是Linux的一个内核模块,该模块使得Linux成为一个hypervisor

+

OVS

+

Open vSwitch

+

开放虚拟交换标准

+

OVS是一个高质量的多层虚拟交换机,使用开源Apache2.0许可协议。

+

QEMU

+

Quick Emulator

+

快速模拟器

+

QEMU是一个通用的可执行硬件虚拟化的开源模拟器。

+

SMP

+

Symmetric Multi-Processor

+

对称多处理

+

SMP是一种多处理器的计算机硬件架构。现在多数的处理器系统都采用对称多处理器架构。该架构系统拥有多个处理器,各处理器共享内存子系统和总线结构。

+

UEFI

+

Unified Extensible Firmware Interface

+

统一的可扩展固件接口

+

一种详细描述全新类型接口的标准。该接口用于操作系统自动从预启动的操作环境,加载到一种操作系统上。

+

VM

+

Virtual Machine

+

虚拟机

+

使用虚拟化技术,通过软件模拟完整的计算机硬件系统功能,构造出的完整虚拟计算机系统。

+

VMM

+

Virtual Machine Monitor

+

虚拟机监视器

+

是一种运行在基础物理服务器和操作系统之间的中间软件层,可允许多个操作系统和应用共享硬件。

+
diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/best-practices.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/best-practices.md new file mode 100644 index 0000000000000000000000000000000000000000..1fc8d5608823b852a752cb883f60fe95abaac04c --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/best-practices.md @@ -0,0 +1,694 @@ +# 最佳实践 + +## 性能最佳实践 + +### halt-polling + +#### 概述 + +在计算资源充足的情况下,为使虚拟机获得接近物理机的性能,可以使用halt-polling特性。没有使用halt-polling特性时,当vCPU空闲退出后,主机会把CPU资源分配给其他进程使用。当主机开启halt-polling特性时,虚拟机vCPU处于空闲时会polling一段时间,polling的时间由具体配置决定。若该vCPU在polling期间被唤醒,可以不从主机侧调度而继续运行,减少了调度流程的开销,从而在一定程度上提高了虚拟机系统的性能。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> halt-polling的机制保证虚拟机的vCPU线程的及时响应,但在虚拟机空载的时候,主机侧也会polling,导致主机看到vCPU所在CPU占用率比较高,而实际虚拟机内部CPU占用率并不高。 + +#### 操作指导 + +系统默认开启了halt-polling特性,polling的时间默认为500000ns。用户可以通过文件halt\_poll\_ns内容动态修改vCPU用于halt-polling的时间,单位为ns。 + +例如设置polling时间为400000,使用root用户执行命令如下: + +```Shell +# echo 400000 > /sys/module/kvm/parameters/halt_poll_ns +``` + +### IOThread配置 + +#### 概述 + +KVM平台上,对虚拟磁盘的读写在后端默认由QEMU主线程负责处理。这样会造成如下问题: + +- 虚拟机的I/O请求都由一个QEMU主线程进行处理,因此单线程的CPU利用率成为虚拟机I/O性能的瓶颈。 +- 虚拟机I/O在QEMU主线程处理时会持有QEMU全局锁\(qemu\_global\_mutex\),一旦I/O处理耗时较长,QEMU主线程长时间占有全局锁,会导致虚拟机vCPU无法正常调度,影响虚拟机整体性能及用户体验。 + +可以为virtio-blk磁盘或者virtio-scsi控制器配置IOThread属性,在QEMU后端单独开辟IOThread线程处理虚拟磁盘读写请求,IOThread线程和virtio-blk磁盘或virtio-scsi控制器可配置成一对一的映射关系,尽可能地减少对QEMU主线程的影响,提高虚拟机整体I/O性能,提升用户体验。 + +#### 配置说明 + +使用IOThread线程处理虚拟机磁盘读写请求,需要修改虚拟机配置,这里给出具体的配置说明。 + +- 配置虚拟机高性能虚拟磁盘的总数。例如通过配置IOThread线程的总数为4: + + ```Conf + + VMName + 4194304 + 4194304 + 4 + 4 + ``` + +- 给virtio-blk磁盘配置IOThread属性。**<**iothread**\>**表示IOThread线程编号,编号从1开始配置,最大为的配置值,且编号不能重复使用。例如将编号为2的IOThread配置给virtio-blk磁盘使用: + + ```Conf + + + + +
+ + ``` + +- 给virtio-scsi控制器配置IOThread属性。例如将编号为2的IOThread配置给virtio-scsi控制器使用: + + ```Conf + + + +
+ + ``` + +- IOThread线程绑定物理CPU + + 虚拟磁盘IOThread线程的绑核配置,将IOThread线程绑定到用户指定的物理CPU范围内,不影响vCPU线程的资源占用诉求。表示IOThread线程编号,表示绑定的物理CPU编号。 + + ```Conf + + + + + ``` + +### 裸设备映射 + +#### 概述 + +配置虚拟机存储设备时,除了将文件配置给虚拟机作为虚拟磁盘使用外,还可以将块设备(物理LUN、逻辑卷等)直接配置给虚拟机使用,从而提升存储性能。该配置方式称为裸设备映射。在该配置方式下,虚拟磁盘向虚拟机呈现为一个SCSI设备,且支持大部分SCSI命令。 + +裸设备映射根据后端实现特点,分为虚拟裸设备映射和物理裸设备映射,物理裸设备映射相对虚拟裸设备映射具有更优秀的性能和更丰富的SCSI命令,但物理裸设备映射需要将整块SCSI磁盘挂载给虚拟机使用,如果使用分区、逻辑卷等方式配置,虚拟机将无法识别。 + +#### 配置示例 + +裸设备映射需要修改虚拟机配置文件,这里给出配置示例。 + +- 虚拟裸设备映射 + + 将主机上存在的SCSI磁盘“/dev/sdc”挂载给虚拟机作为虚拟裸设备的配置示例如下: + + ```Conf + + + ... + + + + + +
+ + ... + + + ``` + +- 物理裸设备映射 + + 将主机上存在的SCSI磁盘“/dev/sdc”挂载给虚拟机作为物理裸设备的配置示例如下: + + ```Conf + + + ... + + + + + +
+ + ... + + + ``` + +### kworker隔离绑定 + +#### 概述 + +kworker是Linux内核实现的per-CPU线程,用来执行系统中的workqueue请求。kworker线程会和vCPU线程争抢物理核资源,导致虚拟化业务性能抖动。为了使虚拟机能够稳定的运行,减少kworker线程对虚拟机的干扰,可以将主机上的kworker线程绑定到特定的CPU上运行。 + +#### 操作步骤 + +用户可以通过修改/sys/devices/virtual/workqueue/cpumask文件,将workqueue中的任务绑定到cpumask中指定的CPU上。cpumask中的掩码以十六进制表示,例如将kworker绑定到CPU0\~CPU7上,对应掩码为ff,使用root用户执行命令如下: + +```Shell +# echo ff > /sys/devices/virtual/workqueue/cpumask +``` + +### 内存大页 + +#### 概述 + +相比传统的4K内存分页,openEuler也支持2MB/1GB的大内存分页。内存大页可以有效减少TLB miss,显著提升内存访问密集型业务的性能。openEuler使用两种技术来实现内存大页。 + +- 静态大页 + + 静态大页要求宿主机操作系统在加载前提前预留一个静态大页池,虚拟机创建时通过修改xml配置文件的方式,指定虚拟机的内存从静态大页池中分配。静态大页能保证虚拟机的所有内存在host上始终以大页形式存在,保证物理连续,但增加了部署的困难,修改静态大页池的页面大小后需要重启host才能生效。静态大页的页面大小支持2M或1G。 + +- 透明大页 + + 如果开启透明大页模式THP(Transparent Huge Pages),虚拟机分配内存时自动选择可用的2M连续页,同时自动完成大页的拆分合并,当没有可用的2M连续页时,它会选择可用的64K(AArch64架构)或4K(x86_64架构)页面进行分配。透明大页的好处是不需要用户感知,同时能尽量使用2M大页以提升内存访问性能。 + +在虚拟机完全使用静态大页的场景下,可以通过关闭透明大页的方法,减少宿主机操作系统的开销,以便虚拟机获得更稳定的性能。 + +#### 操作指导 + +- 使用静态大页 + + 在创建虚拟机之前通过修改XML的方式,为虚拟机配置使用静态大页。 + + ```Conf + + + + + + ``` + + 以上XML片段表示为虚拟机配置1G静态大页。 + + ```Conf + + + + + + ``` + + 以上XML片段表示为虚拟机配置2M静态大页。 + +- 使用透明大页 + + 通过sysfs可以动态开启使用透明大页: + + ```Shell + # echo always > /sys/kernel/mm/transparent_hugepage/enabled + ``` + + 动态关闭使用透明大页: + + ```Shell + # echo never > /sys/kernel/mm/transparent_hugepage/enabled + ``` + +### PV-qspinlock + +#### 概述 + +PV-qspinlock主要是针对虚拟化CPU超分场景自旋锁的优化,允许hypervisor将处于锁上下文中的vCPU置于block状态,并在锁释放后将对应的vCPU唤醒,在超分场景下能够更好地利用pCPU资源,对于编译的应用场景有一定的优化,可以减少编译应用的时长。 + +#### 操作指导 + +修改虚拟机/boot/efi/EFI/openEuler/grub.cfg配置文件,在命令行启动参数添加arm_pvspin,重启虚拟机后生效。PV-qspinlock生效后,虚拟机内部使用dmesg命令可以查到如下日志打印: + +```text +[ 0.000000] arm-pv: PV qspinlocks enabled +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> PV-qspinlock仅限于宿主机和虚拟机操作系统均为openEuler 20.09及以上版本支持,且虚拟机内核编译选项需要配置CONFIG_PARAVIRT_SPINLOCKS=y(openEuler默认配置)。 + +### Guest-Idle-Haltpoll + +#### 概述 + +为了保证公平性及降低功耗,当虚拟机vCPU空闲时,虚拟机将执行WFx/HLT指令退出到宿主机中,并触发上下文切换。宿主机将决定在物理CPU上调度其他进程或vCPU,或进入节能模式。但是,虚拟机和宿主机之间的切换、额外的上下文切换以及唤醒IPI中断开销较大,在频繁睡眠和唤醒的业务中该问题尤为突出。Guest-Idle-Haltpoll技术是指当虚拟机vCPU空闲时,不立刻执行WFx/HLT并发生VM-exit,而是在虚拟机内部轮询(polling)一段时间。在该时间段内,其他共享LLC的vCPU在该vCPU上的任务被唤醒不需要发送IPI中断,减少了发送和接收处理IPI的开销及虚拟机陷出(VM-exit)的开销,从而降低任务唤醒的时延。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 由于vCPU在虚拟机内部执行idle-haltpoll会增加vCPU在宿主机的CPU开销,所以开启该特性建议vCPU在宿主机独占物理核。 + +#### 操作指导 + +Guest-Idle-Haltpoll特性默认关闭,这里给出开启该特性的操作指导。 + +1. 使能Guest-Idle-Haltpoll特性。 + - 若宿主机处理器架构为x86,可以在宿主机的虚拟机XML中配置“hint-dedicated”使能该特性,通过虚拟机XML配置将vCPU独占物理核的状态传递给虚拟机。vCPU独占物理核的状态由宿主机保证。 + + ```Conf + + ... + + + ... + + + + ... + + ``` + + 或者在虚拟机内核启动参数中配置“cpuidle\_haltpoll.force=Y”强制开启,该方法不依赖宿主机配置vCPU独占物理核。 + + ```Conf + cpuidle_haltpoll.force=Y + ``` + + - 若宿主机处理器架构为AArch64,只支持在虚拟机内核启动参数中配置“cpuidle\_haltpoll.force=Y haltpoll.enable=Y”的方式使能该特性。 + + ```Conf + cpuidle_haltpoll.force=Y haltpoll.enable=Y + ``` + +2. 确认Guest-Idle-Haltpoll特性是否生效。在虚拟机中执行如下命令,若返回haltpoll,说明特性已经生效。 + + ```Shell + # cat /sys/devices/system/cpu/cpuidle/current_driver + ``` + +3. (可选)配置Guest-Idle-Haltpoll参数。 + 虚拟机的/sys/module/haltpoll/parameters/路径下提供了如下配置文件,用于调整配置参数,用户可以根据业务特点选择调整。 + + - guest\_halt\_poll\_ns: 全局参数,指vCPU空闲后polling的最大时长,缺省值为200000(单位ns)。 + - guest\_halt\_poll\_shrink: 当唤醒事件发生在全局guest\_halt\_poll\_ns时间之后,用于收缩当前vCPU guest\_halt\_poll\_ns的除数因子,缺省值为2。 + - guest\_halt\_poll\_grow: 当唤醒事件发生在当前vCPU guest\_halt\_poll\_ns之后且在全局guest\_halt\_poll\_ns之前,用于扩展当前vCPU guest\_halt\_poll\_ns的乘数因子,缺省值为2。 + - guest\_halt\_poll\_grow\_start: 当系统空闲时,每个vCPU的guest\_halt\_poll\_ns最终会达到零。该参数用于设置当前vCPU guest\_halt\_poll\_ns的初始值,以便vCPU polling时长的收缩和扩展。缺省值为50000(单位ns)。 + - guest\_halt\_poll\_allow\_shrink: 允许每个vCPU guest\_halt\_poll\_ns收缩的开关,缺省值是Y(Y表示允许收缩,N表示禁止收缩)。 + + 可以使用root权限,参考如下命令修改参数值。其中 _value_ 表示需要设置的参数值, _configFile_ 为对应的配置文件。 + + ```Shell + # echo value > /sys/module/haltpoll/parameters/configFile + ``` + + 例如设置全局guest\_halt\_poll\_ns为200000ns的命令如下: + + ```Shell + # echo 200000 > /sys/module/haltpoll/parameters/guest_halt_poll_ns + ``` + +### Nvme磁盘直通 + +#### 概述 + +设备直通技术是一种基于硬件的虚拟化解决方案,通过该技术,虚拟机可以直接连接到指定的物理直通设备上。对于用户来说,如果需要提升虚拟机存储性能,可以采用将 Nvme 磁盘通过 PCI 直通技术直通给虚拟机的办法,从而获得更高的性能表现。 + +#### 操作指导 + +1. 使用前准备 + + - 确认 Guest OS 内安装 Nvme 磁盘供应商所提供的驱动程序,否则 Nvme 磁盘无法正常工作。 + - 确认 Host OS 开启CPU的 VT-d 和 VT-x 支持。 + - 确认 Host OS 开启内核的 IOMMU 功能。 + - 确认 Host OS 开启内核的中断重映射功能。 + +2. 获取 Nvme 磁盘的 PCI BDF 信息 + + 在Host上通过 **lspci** 命令获取主机上pci设备的资源列表,具体命令如下所示。 + + ```Shell + # lspci -vmm + Slot: 81:00.1 + Class: Non-Volatile memory controller + ... + ``` + + 命令回显其中的 **Slot** 选项及对应了 Nvme 磁盘的 PCI BDF 号,以上方命令为例,每个值的对应关系即81-bus号,00-slot号,1-function号。 + +3. 挂载 PCI 直通 Nvme 磁盘至虚拟机中 + + 创建虚拟机时,在其对应的 xml 配置文件中加入 PCI Nvme 磁盘直通的配置选项。具体配置文件如下所示 + + ```Conf + + +
+ + + ``` + + - hostdev.source.address.domain: Host OS 上 PCI 设备的 domain 号。 + - hostdev.source.address.bus: Host OS 上 PCI 设备的 bus 号。 + - hostdev.source.address.slot: Host OS 上 PCI 设备的 slot 号。 + - hostdev.source.address.function: Host OS 上 PCI 设备的 function 号。 + +4. 指定 Nvme 磁盘的 PCI bar 空间 + + 为了进一步将 Nvme 磁盘的性能发挥到极致,需要指定直通 Nvme 磁盘在 Guest OS 内 PCI MSI-X 中断的 Bar 空间。具体配置如下。 + + ```Conf + + +
+ + +
+ + + + + + ``` + + 以上xml配置将直通的 Nvme 磁盘的中断信息处理指定在第2号 Bar 上,增加该项配置可以使 Guest OS 内的 Nvme 磁盘性能达到与 Host OS 上的 Nvme 磁盘性能几乎一致。 + +## 安全最佳实践 + +### Libvirt鉴权 + +#### 简介 + +用户使用libvirt远程调用功能时,如果不进行任何鉴权校验,所有连接到主机所在网络的第三方程序都可以通过libvirt的远程调用操作虚拟机,存在安全隐患。为了提升系统安全性,openEuler提供了libvirt鉴权功能,即用户通过libvirt远程调用操作虚拟机前,必须经过身份校验,只有特定用户允许访问虚拟机,从而保护组网中的虚拟机。 + +#### 开启libvirt鉴权 + +openEuler默认关闭libvirt远程调用功能,这里给出开启libvirt远程调用和libvirt鉴权功能的方法。 + +1. 使用root用户登录主机。 +2. 修改libvirt服务配置文件/etc/libvirt/libvirtd.conf,开启libvirt远程调用和libvirt鉴权功能。例如使用基于SASL(Simple Authentication and Security Layer)协议的TCP远程调用配置参考如下: + + ```Conf + # 传输层安全协议,0表示关闭,1表示开启,由用户自行配置 + listen_tls = 0 + # 开启基于TCP的远程调用,开启libvirt远程调用和libvirt鉴权功能必须配置为1 + listen_tcp = 1 + # TCP远程调用所使用的协议,由用户自行配置,此处以sasl为例 + auth_tcp = "sasl" + ``` + +3. 修改/etc/sasl2/libvirt.conf配置文件,设置SASL认证机制和sasldb数据库。 + + ```Conf + # sasl协议的认证机制 + mech_list: digest-md5 + # 存放用户和用户密码的数据库 + sasldb_path: /etc/libvirt/passwd.db + ``` + +4. 添加用于SASL验证的用户并设置其密码,假设用户名为userName,命令参考如下: + + ```Shell + # saslpasswd2 -a libvirt userName + Password: + Again (for verification): + ``` + +5. 修改/etc/sysconfig/libvirtd配置文件,开启libvirt侦听选项。 + + ```Conf + LIBVIRTD_ARGS="--listen" + ``` + +6. 重启libvirtd服务,使修改生效。 + + ```Shell + # systemctl restart libvirtd + ``` + +7. 确认libvirt远程调用的鉴权功能是否生效。根据提示输入用户名和密码能够成功连接libvirt服务,说明开启成功。 + + ```Shell + # virsh -c qemu+tcp://192.168.0.1/system + Please enter your authentication name: openeuler + Please enter your password: + Welcome to virsh, the virtualization interactive terminal. + + Type: 'help' for help with commands + 'quit' to quit + + virsh # + ``` + +#### 管理SASL + +这里给出管理SASL用户的操作,请使用root用户操作。 + +- 查询数据库中存在的用户 + + ```Shell + # sasldblistusers2 -f /etc/libvirt/passwd.db + user@localhost.localdomain: userPassword + ``` + +- 从数据库中删除用户user + + ```Shell + # saslpasswd2 -a libvirt -d user + ``` + +### qemu-ga + +#### 概述 + +qemu-ga(Qemu Guest Agent)它是运行在虚拟机内部的守护进程,它允许用户在host OS上通过QEMU提供带外通道实现对guest OS的多种管理操作:包括文件操作(open、read、write、close,seek、flush等)、内部关机、虚拟机休眠(suspend-disk、suspend-ram、suspend-hybrid),获取虚拟机内部的信息(包括内存,CPU,网卡,OS等相关信息 )等。 + +在一些对安全要求较高的使用场景,为了防止虚拟机内部信息泄露,qemu-ga提供了黑名单功能,用户可以通过黑名单选择性屏蔽qemu-ga提供的部分功能。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> qemu-ga对应的安装包是qemu-guest-agent-xx.rpm,openEuler默认不安装。xx为实际版本号。 + +#### 操作方法 + +请使用root用户按照如下操作步骤添加qemu-ga黑名单: + +1. 登录虚拟机,确定qemu-guest-agent服务存在且处于运行状态。 + + ```Shell + # systemctl status qemu-guest-agent |grep Active + Active: active (running) since Wed 2018-03-28 08:17:33 CST; 9h ago + ``` + +2. 查询qemu-ga哪些命令可以加入黑名单: + + ```Shell + # qemu-ga --blacklist ? + guest-sync-delimited + guest-sync + guest-ping + guest-get-time + guest-set-time + guest-info + ... + ``` + +3. 设置黑名单。通过修改/usr/lib/systemd/system/qemu-guest-agent.service,将需要屏蔽的命令添加到该文件的--blacklist中,不同命令使用空格分隔。例如将guest-file-open和guest-file-close命令加入黑名单的配置参考如下: + + ```Conf + [Service] + ExecStart=-/usr/bin/qemu-ga \ + --blacklist=guest-file-open guest-file-close + ``` + +4. 重启qemu-guest-agent服务: + + ```Shell + # systemctl daemon-reload + # systemctl restart qemu-guest-agent + ``` + +5. 确认虚拟机开启qemu-ga黑名单功能是否生效,即qemu-ga进程配置的参数--blacklist是否正确。 + + ```Shell + # ps -ef|grep qemu-ga|grep -E "blacklist=|b=" + root 727 1 0 08:17 ? 00:00:00 /usr/bin/qemu-ga --method=virtio-serial --path=/dev/virtio-ports/org.qemu.guest_agent.0 --blacklist=guest-file-open guest-file-close guest-file-read guest-file-write guest-file-seek guest-file-flush -F/etc/qemu-ga/fsfreeze-hook + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > + > 更多关于qemu-ga的资料可以参见[https://wiki.qemu.org/Features/GuestAgent](https://wiki.qemu.org/Features/GuestAgent)。 + +### sVirt保护 + +#### 概述 + +在只使用自由访问控制DAC(Discretionary Access Control)策略的虚拟化环境中,主机上运行的恶意虚拟机可能存在攻击hypervisor或其他虚拟机的情况。为了提升虚拟化场景的安全性,openEuler使用了sVirt保护。sVirt是基于SELinux,适用于KVM虚拟化场景的安全防护技术。虚拟机本质是主机操作系统上的普通进程,sVirt机制在hypervisor将虚拟机对应的QEMU进程进行SELinux标记分类,除了使用type表示虚拟化专有进程和文件,还用不同的category(在seclevel区间)表示不同虚拟机,每个虚拟机只能访问自身相同category的文件设备,防止虚拟机访问非授权的主机或其他虚拟机的文件和设备,从而防止虚拟机逃逸,提升主机和虚拟机的安全性。 + +#### 开启sVirt保护 + +##### 一、使用root用户按照如下操作步骤开启主机的SELinux + +1. 登录主机。 +2. 开启主机SELinux功能。 + 1. 修改系统启动的grub.cfg,将selinux设置为1。 + + ```Conf + selinux=1 + ``` + + 2. 修改/etc/selinux/config,将SELINUX模式设置为enforcing。 + + ```Conf + SELINUX=enforcing + ``` + +3. 重启主机。 + + ```Shell + # reboot + ``` + +##### 二、创建开启sVirt功能的虚拟机 + +1. 虚拟机配置文件中添加如下配置: + + ```Conf + + ``` + + 或确认没有下述配置: + + ```Conf + + ``` + +2. 创建虚拟机。 + + ```Shell + # virsh define openEulerVM.xml + ``` + +##### 三、确认sVirt开启成功 + +执行下述命令检查运行中的虚拟机QEMU进程是否已经启用sVirt防护,若存在"svirt\_t:s0:c"表示已经启用sVirt防护。 + +```Shell +# ps -eZ|grep qemu |grep "svirt_t:s0:c" +system_u:system_r:svirt_t:s0:c200,c947 11359 ? 00:03:59 qemu-kvm +system_u:system_r:svirt_t:s0:c427,c670 13790 ? 19:02:07 qemu-kvm +``` + +### 虚拟机可信启动 + +#### 概述 + +可信启动包含度量启动和远程证明。其中虚拟化组件主要提供度量启动功能,远程证明由用户自己在虚拟机中安装相关软件(RA client)及搭建远程证明服务器(RA server)进行使能。 + +度量启动的两个基本要素是信任根和信任链,其基本思想是首先在计算机系统中建立一个信任根,信任根的可信性由物理安全、技术安全和管理安全共同确保,即CRTM(Core Root of Trust for Measurement)。然后建立一条信任链,从信任根开始到BIOS/BootLoader、操作系统、再到应用,一级度量认证一级,一级信任一级,最终把这种信任扩展到整个系统。上述过程看起来如同一根链条一样环环相扣,因此称之为“信任链”。 + +CRTM是度量启动的根,是系统启动的首个组件,没有其他代码来检查CRTM本身的完整性。所以,作为信任链的起点,必须保证它是绝对可信的信任源。因此,技术上需要将CRTM设计成一段只读或更新严格受限的代码,抵御BIOS攻击,防止远程注入恶意代码或在操作系统上层修改启动代码。通常物理主机中由CPU中的微码作为CRTM,在虚拟化环境中,一般选择vBIOS的sec部分为CRTM。 + +启动过程中,前一个部件度量(计算HASH值)后一个部件,然后把度量值扩展入可信存储区例如TPM的PCR中。CRTM度量BootLoader把度量值扩展到PCR中,BootLoader度量OS把度量值扩展到PCR中。 + +#### 配置vTPM设备,使能度量启动 + +##### 一、安装swtpm和libtpms软件 + +swtpm提供了一个可集成到虚拟化环境中的TPM仿真器(TPM1.2和TPM2.0)。到目前为止,他已经集成到了QEMU中,同时也作为RunC中的原型系统。swtpm是利用libtpms来提供TPM1.2和TPM2.0的模拟功能。 +目前openEuler 21.03 版本中提供了libtpms和swtpm的源,可以直接使用yum命令安装。 + +```Shell +# yum install libtpms swtpm swtpm-devel swtpm-tools +``` + +##### 二、虚拟机配置vTPM设备 + +1. 虚拟机配置文件中添加如下配置: + + ```Conf + + ... + + ... + + + + ... + + ... + + ``` + + > ![](public_sys-resources/icon-note.gif) **说明:** + > + > 目前,openEuler 20.09 版本 AArch64 架构上的虚拟机可信启动不支持 ACPI 特性,所以虚拟机请勿配置 ACPI 特性,否则启动虚拟机后无法识别 vTPM 设备。AArch64 架构在openEuler 22.03 LTS 之前的版本,tpm model 配置为 \。 + +2. 创建虚拟机。 + + ```Shell + # virsh define MeasuredBoot.xml + ``` + +3. 启动虚拟机 + + 启动虚拟机前需要使用chmod命令给目录/var/lib/swtpm-localca/赋予如下权限,否则libvirt无法拉起swtpm。 + + ```Shell + # chmod -R 777 /var/lib/swtpm-localca/ + # + # virsh start MeasuredbootVM + ``` + +##### 三、确认度量启动使能成功 + +度量启动功能使能与否由vBIOS决定,目前 openEuler 21.03 版本中的vBIOS已经具备了度量启动的能力。若宿主机采用其他版本的edk2组件,请确认其是否支持度量启动功能。 + +使用root用户登录虚拟机,确认虚拟机中是否安装了tpm驱动,tpm2-tss协议栈及tpm2-tools工具。 +openEuler 21.03 版本中默认安装了tpm驱动(tpm_tis.ko),tpm2-tss协议栈和tpm2-tools工具。若使用其他操作系统,可以使用如下命令检查是否安装了驱动和相关工具。 + +```Shell +# lsmod |grep tpm +# tpm_tis 16384 0 +# +# yum list installed | grep -E 'tpm2-tss|tpm2-tools' +# +# yum install tpm2-tss tpm2-tools +``` + +可以使用tpm2_pcrread(低版本tpm2_tools中使用tpm2_pcrlist)命令列出所有的pcr值。 + +```Shell +# tpm2_pcrread +sha1 : + 0 : fffdcae7cef57d93c5f64d1f9b7f1879275cff55 + 1 : 5387ba1d17bba5fdadb77621376250c2396c5413 + 2 : b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236 + 3 : b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236 + 4 : e5d40ace8bb38eb170c61682eb36a3020226d2c0 + 5 : 367f6ea79688062a6df5f4737ac17b69cd37fd61 + 6 : b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236 + 7 : 518bd167271fbb64589c61e43d8c0165861431d8 + 8 : af65222affd33ff779780c51fa8077485aca46d9 + 9 : 5905ec9fb508b0f30b2abf8787093f16ca608a5a + 10 : 0000000000000000000000000000000000000000 + 11 : 0000000000000000000000000000000000000000 + 12 : 0000000000000000000000000000000000000000 + 13 : 0000000000000000000000000000000000000000 + 14 : 0000000000000000000000000000000000000000 + 15 : 0000000000000000000000000000000000000000 + 16 : 0000000000000000000000000000000000000000 + 17 : ffffffffffffffffffffffffffffffffffffffff + 18 : ffffffffffffffffffffffffffffffffffffffff + 19 : ffffffffffffffffffffffffffffffffffffffff + 20 : ffffffffffffffffffffffffffffffffffffffff + 21 : ffffffffffffffffffffffffffffffffffffffff + 22 : ffffffffffffffffffffffffffffffffffffffff + 23 : 0000000000000000000000000000000000000000 +sha256 : + 0 : d020873038268904688cfe5b8ccf8b8d84c1a2892fc866847355f86f8066ea2d + 1 : 13cebccdb194dd916f2c0c41ec6832dfb15b41a9eb5229d33a25acb5ebc3f016 + 2 : 3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969 + 3 : 3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969 + 4 : 07f9074ccd4513ef1cafd7660f9afede422b679fd8ad99d25c0659eba07cc045 + 5 : ba34c80668f84407cd7f498e310cc4ac12ec6ec43ea8c93cebb2a688cf226aff + 6 : 3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969 + 7 : 65caf8dd1e0ea7a6347b635d2b379c93b9a1351edc2afc3ecda700e534eb3068 + 8 : f440af381b644231e7322babfd393808e8ebb3a692af57c0b3a5d162a6e2c118 + 9 : 54c08c8ba4706273f53f90085592f7b2e4eaafb8d433295b66b78d9754145cfc + 10 : 0000000000000000000000000000000000000000000000000000000000000000 + 11 : 0000000000000000000000000000000000000000000000000000000000000000 + 12 : 0000000000000000000000000000000000000000000000000000000000000000 + 13 : 0000000000000000000000000000000000000000000000000000000000000000 + 14 : 0000000000000000000000000000000000000000000000000000000000000000 + 15 : 0000000000000000000000000000000000000000000000000000000000000000 + 16 : 0000000000000000000000000000000000000000000000000000000000000000 + 17 : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + 18 : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + 19 : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + 20 : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + 21 : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + 22 : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + 23 : 0000000000000000000000000000000000000000000000000000000000000000 +``` diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/environment-preparation.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/environment-preparation.md new file mode 100644 index 0000000000000000000000000000000000000000..54385f082d9f61a4a3e2ea0bfc82b782cc9dfafb --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/environment-preparation.md @@ -0,0 +1,379 @@ +# 准备使用环境 + +## 准备虚拟机镜像 + +### 概述 + +虚拟机镜像是一个文件,包含了已经完成安装并且可启动操作系统的虚拟磁盘。虚拟机镜像具有不同格式,常见的有raw格式和qcow2格式。与raw格式镜像相比,qcow2格式镜像占用更小的空间,支持快照、Copy-On-Write、AES加密、zlib压缩等特性,但性能略逊于raw格式镜像。镜像文件的制作借助于qemu-img工具,本节以qcow2格式镜像文件为例,介绍虚拟机镜像制作过程。 + +### 制作镜像 + +制作qcow2格式镜像文件的操作步骤如下: + +1. 使用root用户安装qemu-img软件包。 + + ```sh + yum install -y qemu-img + ``` + +2. 使用qemu-img工具的create命令,创建镜像文件,命令格式为: + + ```sh + qemu-img create -f -o + ``` + + 其中,各参数含义如下: + + - _imgFormat_:镜像格式,取值为raw, qcow2等。 + - _fileOption_:文件选项,用于设置镜像文件的特性,如指定后端镜像文件,压缩,加密等特性。 + - _fileName_:文件名称。 + - _diskSize_:磁盘大小,用于指定块磁盘设备的大小,支持的单位有K、M、G、T,分别代表KiB、MiB、GiB、TiB。 + + 例如,创建一个磁盘设备大小为4GB、格式为qcow2的镜像文件openEuler-image.qcow2,命令和回显如下: + + ```sh + $ qemu-img create -f qcow2 openEuler-image.qcow2 4G + Formatting 'openEuler-image.qcow2', fmt=qcow2 size=4294967296 cluster_size=65536 lazy_refcounts=off refcount_bits=16 + ``` + +### 修改镜像磁盘空间大小 + +当虚拟机需要更大的磁盘空间时,可以使用qemu-img工具,修改虚拟机镜像磁盘空间的大小,修改方法如下。 + +1. 查询当前虚拟机镜像磁盘空间大小,命令如下: + + ```sh + qemu-img info + ``` + + 例如,查询openEuler-image.qcow2镜像磁盘空间大小的命令和回显如下,说明该镜像磁盘空间大小为4GiB。 + + ```sh + $ qemu-img info openEuler-image.qcow2 + image: openEuler-image.qcow2 + file format: qcow2 + virtual size: 4.0G (4294967296 bytes) + disk size: 196K + cluster_size: 65536 + Format specific information: + compat: 1.1 + lazy refcounts: false + refcount bits: 16 + corrupt: false + ``` + +2. 修改镜像磁盘空间大小,命令如下,其中 _imgFiLeName_ 为镜像名称,“+”和“-”分别表示需要增加或减小的镜像磁盘空间大小,单位为K、M、G、T,代表KiB、MiB、GiB、TiB。 + + ```sh + qemu-img resize [+|-] + ``` + + 例如,将上述openEuler-image.qcow2镜像磁盘空间大小扩展到24GiB,即在原来4GiB基础上增加20GiB,命令和回显如下: + + ```sh + $ qemu-img resize openEuler-image.qcow2 +20G + Image resized. + ``` + +3. 查询修改后的镜像磁盘空间大小,确认是否修改成功,命令如下: + + ```sh + qemu-img info + ``` + + 例如,上述openEuler-image.qcow2镜像磁盘空间已扩展到24GiB,命令和回显如下: + + ```sh + $ qemu-img info openEuler-image.qcow2 + image: openEuler-image.qcow2 + file format: qcow2 + virtual size: 24G (25769803776 bytes) + disk size: 200K + cluster_size: 65536 + Format specific information: + compat: 1.1 + lazy refcounts: false + refcount bits: 16 + corrupt: false + ``` + +## 准备虚拟机网络 + +### 概述 + +为了使虚拟机可以与外部进行网络通信,需要为虚拟机配置网络环境。KVM虚拟化支持Linux网桥、Open vSwitch网桥等多种类型的网桥。如[图1](#fig1785384714917)所示,数据传输路径为“虚拟机 -\> 虚拟网卡设备 -\> Linux网桥或Open vSwitch网桥 -\> 物理网卡”。创建网桥,除了为虚拟机配置虚拟网卡设备外,为主机创建网桥是连接虚拟化网络的关键。 + +本节给出搭建Linux网桥和Open vSwitch网桥的方法,使虚拟机连接到网络,用户可以根据情况选择搭建网桥的类型。 + +**图 1** 虚拟网络结构图 +![](./figures/virtual-network-structure.png) + +### 搭建Linux网桥 + +以物理网卡eth0绑定到Linux网桥br0的操作为例,使用root用户执行如下命令搭建Linux网桥: + +1. 安装bridge-utils软件包。 + + Linux网桥通常通过brctl工具管理,其对应的安装包为bridge-utils,安装命令如下: + + ```sh + yum install -y bridge-utils + ``` + +2. 创建网桥br0。 + + ```sh + brctl addbr br0 + ``` + +3. 将物理网卡eth0绑定到Linux网桥。 + + ```sh + brctl addif br0 eth0 + ``` + +4. eth0与网桥连接后,不再需要IP地址,将eth0的IP设置为0.0.0.0。 + + ```sh + yum install -y net-tools + ifconfig eth0 0.0.0.0 + ``` + +5. 设置br0的IP地址。 + - 如果有DHCP服务器,可以通过dhclient设置动态IP地址。 + + ```sh + dhclient br0 + ``` + + - 如果没有DHCP服务器,给br0配置静态IP,例如设置静态IP为192.168.1.2,子网掩码为255.255.255.0。 + + ```sh + ifconfig br0 192.168.1.2 netmask 255.255.255.0 + ``` + +### 搭建Open vSwitch网桥 + +Open vSwitch网桥,具有更便捷的自动化编排能力。搭建Open vSwitch网桥需要安装网络虚拟化组件,这里介绍总体操作。 + +#### 一、安装Open vSwitch组件 + +使用Open vSwitch提供虚拟网络,需要安装Open vSwitch网络虚拟化组件,使用root用户执行如下命令: + +1. 安装Open vSwitch组件。 + + ```sh + # yum install -y openvswitch + ``` + +2. 启动Open vSwitch服务。 + + ```sh + # systemctl start openvswitch + ``` + +#### 二、确认安装是否成功 + +确认Open vSwitch组件是否安装成功。 + +1. 确认openvswitch组件是否安装成功。若安装成功,可以看到软件包相关信息,命令和回显如下: + + ```sh + $ rpm -qi openvswitch + Name : openvswitch + Version : 2.11.1 + Release : 1 + Architecture: aarch64 + Install Date: Thu 15 Aug 2019 05:08:35 PM CST + Group : System Environment/Daemons + Size : 6051185 + License : ASL 2.0 + Signature : (none) + Source RPM : openvswitch-2.11.1-1.src.rpm + Build Date : Thu 08 Aug 2019 05:24:46 PM CST + Build Host : armbuild10b247b121b105 + Relocations : (not relocatable) + Vendor : Nicira, Inc. + URL : http://www.openvswitch.org/ + Summary : Open vSwitch daemon/database/utilities + Description : + Open vSwitch provides standard network bridging functions and + support for the OpenFlow protocol for remote per-flow control of + traffic. + ``` + +2. 查看Open vSwitch服务是否启动成功。若服务处于“Active”状态,说明服务启动成功,可以正常使用Open vSwitch提供的命令行工具,命令和回显如下: + + ```sh + $ systemctl status openvswitch + ● openvswitch.service - LSB: Open vSwitch switch + Loaded: loaded (/etc/rc.d/init.d/openvswitch; generated) + Active: active (running) since Sat 2019-08-17 09:47:14 CST; 4min 39s ago + Docs: man:systemd-sysv-generator(8) + Process: 54554 ExecStart=/etc/rc.d/init.d/openvswitch start (code=exited, status=0/SUCCESS) + Tasks: 4 (limit: 9830) + Memory: 22.0M + CGroup: /system.slice/openvswitch.service + ├─54580 ovsdb-server: monitoring pid 54581 (healthy) + ├─54581 ovsdb-server /etc/openvswitch/conf.db -vconsole:emer -vsyslog:err -vfile:info --remote=punix:/var/run/openvswitch/db.sock --private-key=db:Open_vSwitch,SSL,private_key --certificate> + ├─54602 ovs-vswitchd: monitoring pid 54603 (healthy) + └─54603 ovs-vswitchd unix:/var/run/openvswitch/db.sock -vconsole:emer -vsyslog:err -vfile:info --mlockall --no-chdir --log-file=/var/log/openvswitch/ovs-vswitchd.log --pidfile=/var/run/open> + ``` + +#### 三、搭建Open vSwitch网桥 + +以创建Open vSwitch一层网桥br0为例,介绍搭建方法,使用root用户执行如下命令: + +1. 创建Open vSwitch网桥br0。 + + ```sh + ovs-vsctl add-br br0 + ``` + +2. 将物理网卡eth0添加到br0。 + + ```sh + ovs-vsctl add-port br0 eth0 + ``` + +3. eth0与网桥连接后,不再需要IP地址,将eth0的IP设置为0.0.0.0。 + + ```sh + ifconfig eth0 0.0.0.0 + ``` + +4. 为OVS网桥br0分配IP。 + - 如果有DHCP服务器,可以通过dhclient设置动态IP地址。 + + ```sh + dhclient br0 + ``` + + - 如果没有DHCP服务器,给br0配置静态IP,例如192.168.1.2。 + + ```sh + ifconfig br0 192.168.1.2 + ``` + +## 准备引导固件 + +### 概述 + +针对不同的架构,引导的方式有所差异。x86支持UEFI(Unified Extensible Firmware Interface)和BIOS方式启动,AArch64仅支持UEFI方式启动。openEuler默认已安装BIOS启动对应的引导文件,不需要用户额外操作。所以这里仅介绍UEFI启动方式的安装方法。 + +统一的可扩展固件接口UEFI是一种全新类型的接口标准,用于开机自检、引导操作系统的启动,是传统BIOS的一种替代方案。EDK II是一套实现了UEFI标准的开源代码,在虚拟化场景中,通常利用EDK II工具集,通过UEFI的方式启动虚拟机。使用EDK II工具需要在虚拟机启动之前安装对应的软件包 ,本节介绍EDK II的安装方法。 + +### 安装方法 + +如果使用UEFI方式引导,需要安装工具集EDK II,AArch64架构对应的安装包为edk2-aarch64,x86架构对应的安装包为edk2-ovmf。这里以AArch64架构为例,给出具体的安装方法,x86架构仅需将edk2-aarch64替换为edk2-ovmf。 + +1. 安装edk软件包,使用root用户执行如下命令: + + 在AArch64架构下edk2的包名为edk2-aarch64 + + ```sh + yum install -y edk2-aarch64 + ``` + + 在x86\_64架构下edk2的包名为edk2-ovmf + + ```sh + yum install -y edk2-ovmf + ``` + +2. 查询edk软件是否安装成功,命令如下: + + 在AArch64架构下查询如下 + + ```sh + rpm -qi edk2-aarch64 + ``` + + 若edk软件安装成功,回显类似如下: + + ```text + Name : edk2-aarch64 + Version : 20180815gitcb5f4f45ce + Release : 1.oe3 + Architecture: noarch + Install Date: Mon 22 Jul 2019 04:52:33 PM CST + Group : Applications/Emulators + ``` + + 在x86\_64架构下查询如下 + + ```sh + # rpm -qi edk2-ovmf + ``` + + 若edk软件安装成功,回显类似如下: + + ```text + Name : edk2-ovmf + Version : 201908 + Release : 6.oe1 + Architecture: noarch + Install Date: Thu 19 Mar 2020 09:09:06 AM CST + ``` + +## 非root用户配置 + +### 概述 + +openEuler虚拟化使用virsh管理虚拟机。如果希望在非root用户使用virsh命令管理虚拟机,在使用之前需要进行相关配置,这里给出配置指导。 + +### 操作指导 + +允许非root用户使用virsh命令管理虚拟机的配置操作如下,以下命令中的userName请改为实际的非root用户名称: + +1. 使用root用户登录主机。 + +2. 将非root用户添加到libvirt用户组。 + + ```sh + usermod -a -G libvirt userName + ``` + +3. 切换到非root用户。 + + ```sh + su userName + ``` + +4. 配置非root用户的环境变量。使用vim打开~/.bashrc文件: + + ```sh + vim ~/.bashrc + ``` + + 并在末尾加上如下内容后保存。 + + ```sh + export LIBVIRT_DEFAULT_URI="qemu:///system" + ``` + + 执行如下命令,使配置生效。 + + ```sh + source ~/.bashrc + ``` + +5. 在虚拟机XML配置文件中的domain根元素中添加如下内容,使qemu-kvm进程可以访问磁盘镜像文件。 + + 执行如下命令查询当前运行的虚拟机 + + ```sh + virsh list + ``` + + 使用如下命令编辑对应虚拟机的XML,name参数为上一步查询到的需要修改的目标虚拟机名称 + + ```sh + virsh edit + ``` + + 添加如下配置,编辑后保存即可生效 + + ```xml + + ``` diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/faq.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/faq.md new file mode 100644 index 0000000000000000000000000000000000000000..b50a7913d900e34f4a16e2fc1ef40f8824c1fae6 --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/faq.md @@ -0,0 +1,17 @@ +# 常见问题与解决办法 + +## **问题1:使用libcareplus工具制作的qemu热补丁无法加载** + +原因:qemu版本和热补丁版本不一致。 + +解决方法:下载qemu对应版本的源码,同时需保持制作热补丁的环境和制作qemu包环境一致,buildID可作为二者是否一致的判定标准。因用户无qemu版本的制作环境,故可以 **自行编包并安装** ,使用自编包中的/usr/libexec/qemu-kvm的buildID。 + +## **问题2:使用libcareplus工具制作的热补丁已加载但未生效** + +原因:不支持死循环、不退出、递归的函数,不支持对初始化函数、inline 函数以及小于5字节的短函数。 + +解决方法:查看补丁所在函数是否在约束限制中。 + +## **问题3:使用kvmtop工具第一次显示的结果为间隔0.05秒的两次采样计算得到的结果,波动较大** + +此为开源top框架缺陷导致,暂无解决方案。 diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP1.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP1.png new file mode 100644 index 0000000000000000000000000000000000000000..536e0618a3ab5b70937292205242a08237e34712 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP1.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP2.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP2.png new file mode 100644 index 0000000000000000000000000000000000000000..0557c8782960188dbe9d84a1d0e66c9b45d2b303 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP2.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP3.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP3.png new file mode 100644 index 0000000000000000000000000000000000000000..326fcf1e8d5e3c795ebcde286d8e0fef14bec7d1 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP3.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP4.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP4.png new file mode 100644 index 0000000000000000000000000000000000000000..bc77c038e1e3a5ec30d7ba4f805ca937792e9327 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP4.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP5.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP5.png new file mode 100644 index 0000000000000000000000000000000000000000..0f22b3cbd84f7c93f74898a926bc3e32f231667f Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP5.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP6.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP6.png new file mode 100644 index 0000000000000000000000000000000000000000..08235013ca71f1ec51e9af2f143629d1a6132fe9 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP6.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP7.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP7.png new file mode 100644 index 0000000000000000000000000000000000000000..f934521d59dd4a75449fcb2ca8abc54045b9102b Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP7.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP8.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP8.png new file mode 100644 index 0000000000000000000000000000000000000000..9a8158e3378bf25dee05b892cc60f424542455d7 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/CertEnrollP8.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/OSBootFlow.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/OSBootFlow.png new file mode 100644 index 0000000000000000000000000000000000000000..f9c03c86df145636015efaeab4dc076f62754cd9 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/OSBootFlow.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/SecureBootFlow.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/SecureBootFlow.png new file mode 100644 index 0000000000000000000000000000000000000000..e76a800931ed6da2af3515d3d9d44388e3d11c01 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/SecureBootFlow.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/kvm-architecture.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/kvm-architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..62b13a899ef6eb7ab3e6b2d4a754396734e3b6b3 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/kvm-architecture.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/status-transition-diagram.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/status-transition-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..9135ef9ecb11e1bf6a8fe3aacbded418fe809bda Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/status-transition-diagram.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/virtual-network-structure.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/virtual-network-structure.png new file mode 100644 index 0000000000000000000000000000000000000000..7feec03aa9434c7b5ed4479cbae3f76e4d44f86b Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/virtual-network-structure.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/virtualized-architecture.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/virtualized-architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..bd90a00d1fbe4d8356ec0dec3106c10dafd46950 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/virtualized-architecture.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/zh-cn_image_0218587435.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/zh-cn_image_0218587435.png new file mode 100644 index 0000000000000000000000000000000000000000..d245d48dc07e2b01734e21ec1952e89fa9269bdb Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/zh-cn_image_0218587435.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/zh-cn_image_0218587436.png b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/zh-cn_image_0218587436.png new file mode 100644 index 0000000000000000000000000000000000000000..a32856aa08e459ed0f51f8fcf4c2f51511c12095 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/figures/zh-cn_image_0218587436.png differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/introduction-to-virtulization.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/introduction-to-virtulization.md new file mode 100644 index 0000000000000000000000000000000000000000..90ac4d3489bada9c4e2bf63ecd9fa6ba634d2250 --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/introduction-to-virtulization.md @@ -0,0 +1,80 @@ +# 认识虚拟化 + +## 简介 + +在计算机技术中,虚拟化是一种资源管理技术,它将计算机的各种实体资源(处理器、内存、磁盘、网络适配器等)予以抽象、转换后呈现,并可分割、组合为一个或多个计算机配置环境。这种资源管理技术打破了实体结构不可分割的障碍,使这些资源在虚拟化后不受现有资源的架设方式、地域或物理配置限制,从而让用户可以更好地应用计算机硬件资源,提高资源利用率。 + +虚拟化使得一台物理服务器上可以运行多台虚拟机,虚拟机共享物理机的处理器、内存、I/O设备等资源,但逻辑上虚拟机之间是互相隔离的。在虚拟化技术中,通常将这个物理服务器称为宿主机,宿主机上运行的虚拟机也叫客户机,虚拟机内部运行的操作系统称为客户机操作系统。在宿主机和虚拟机之间存在一层叫虚拟化层的软件,用于实现虚拟硬件的模拟,通常这个虚拟化层被称为虚拟机监视器,如下图所示: + +**图 1** 虚拟化架构 +![](./figures/virtualized-architecture.png) + +## 虚拟化架构 + +当前的主流虚拟化技术按照VMM(Virtual Machine Monitor)实现结构不同分为两种: + +- Hypervisor模型 + + 在这种模型中,VMM被看做是一个完备的操作系统,同时还具备虚拟化功能,VMM直接管理所有的物理资源,包括处理器,内存和I/O设备等。 + +- 宿主模型 + + 这种模型中,物理资源是由宿主机操作系统管理,宿主机操作系统是传统的操作系统,如Linux,Windows等,宿主机操作系统不提供虚拟化能力,提供虚拟化能力的VMM作为系统的一个驱动或者软件运行在宿主操作系统上,VMM通过调用host OS的服务获得资源,实现处理器,内存和I/O设备的模拟,这种模型的虚拟化实现有KVM、Virtual Box等。 + +KVM(Kernel-based Virtual Machine)即基于内核的虚拟机,是Linux的一个内核模块,该内核模块使Linux成为一个hypervisor。KVM架构如[图2](#fig310953013541)所示。KVM本身未模拟任何硬件设备,它用于使能硬件提供的虚拟化能力,比如Intel VT-x, AMD-V, ARM virtualization extensions等。主板、内存及I/O等设备的模拟由用户态的QEMU完成。用户态QEMU配合内核KVM模块共同完成虚拟机的硬件模拟,客户机操作系统运行在QEMU和KVM模拟的硬件上。 + +**图 2** KVM架构图 +![](./figures/kvm-architecture.png) + +## 虚拟化组件 + +openEuler软件包中提供的虚拟化相关组件: + +- KVM:提供核心的虚拟化基础设施,使Linux系统成为一个hypervisor,支持多个虚拟机同时在该主机上运行。 +- QEMU:模拟处理器并提供一组设备模型,配合KVM实现基于硬件的虚拟化模拟加速。 +- Libvirt:为管理虚拟机提供工具集,主要包含统一、稳定、开放的应用程序接口(API)、守护进程 (Libvirtd)和一个默认命令行管理工具(virsh)。 +- Open vSwitch:为虚拟机提供虚拟网络的工具集,支持编程扩展,以及标准的管理接口和协议(如NetFlow, sFlow,IPFIX, RSPAN, CLI, LACP, 802.1ag)。 + +## 虚拟化特点 + +业界普遍认可虚拟化有以下特点: + +- 分区 + + 虚拟化可以对一台物理服务器进行软件逻辑分割,实现运行多台不同规格的虚拟机(虚拟服务器)。 + +- 隔离 + + 虚拟化能够模拟虚拟硬件,为虚拟机运行完整操作系统提供硬件条件,每个虚拟机内部操作系统都是独立的,互相隔离的。例如一台虚拟机的操作系统由于故障或者受到恶意破坏而崩溃,其他虚拟机内部的操作系统和应用不会受到任何影响。 + +- 封装性 + + 以虚拟机为粒度封装,优秀的封装性使得虚拟机比物理机更灵活,可以实现虚拟机的热迁移、快照、克隆等功能,实现数据中心的快速部署和自动化运维。 + +- 硬件无关 + + 经过虚拟化层的抽象后,虚拟机与底层的硬件没有直接的绑定关系,可以在其他服务器上不加修改地运行虚拟机。 + +## 虚拟化优势 + +虚拟化为数据中心的基础设施带来了众多优势: + +- 灵活性和可扩展性 + + 用户可以根据需求进行动态资源分配和回收,满足动态变化的业务需求,同时也可以根据不同的产品需求,规划不同的虚拟机规格,在不改变物理资源配置的情况下进行规模调整。 + +- 更高的可用性和更好的运维手段 + + 虚拟化提供热迁移、快照、热升级、容灾自动恢复等运维手段,可以在不影响用户的情况下对物理资源进行删除、升级或变更,提高了业务连续性,同时可以实现自动化运维。 + +- 提高安全性 + + 虚拟化提供了操作系统级的隔离,同时实现基于硬件提供的处理器操作特权级控制,相比简单的共享机制具有更高的安全性,可实现对数据和服务进行可控和安全的访问。 + +- 更高的资源利用率 + + 虚拟化可支持实现物理资源和资源池的动态共享,提高资源利用率。 + +## openEuler虚拟化 + +openEuler提供了支持AArch64和x86_64处理器架构的KVM虚拟化组件。 diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/managing-devices.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/managing-devices.md new file mode 100644 index 0000000000000000000000000000000000000000..58fe862fc688d46bf48991523e431b570c83976a --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/managing-devices.md @@ -0,0 +1,730 @@ +# 管理设备 + +## 配置虚拟机PCIe控制器 + +### 概述 + +虚拟机内部的网卡、磁盘控制器、PCIe直通设备都需要挂接到PCIe Root Port下面,每个Root Port对应一个PCIe插槽。Root Port的下挂设备支持热插拔,但是Root Port本身不支持热插拔,因此需要用户考虑设备热插的需求,规划虚拟机需要预留的最大PCIe Root Port数量,在虚拟机启动之前完成Root Port的静态配置。 + +### 配置PCIe Root、PCIe Root Port和PCIe-PCI-Bridge + +虚拟机PCIe控制器通过XML文件进行配置,PCIe Root、PCIe Root Port和PCIe-PCI-Bridge对应XML中的model分别为pcie-root、pcie-root-port、pcie-to-pci-bridge。 + +- 简化配置方法 + + 在虚拟机的XML文件中写入以下内容,controller的其他属性由libvirt自动填充: + + ```Conf + + + + + + + ``` + + 其中:由于pcie-root和pcie-to-pci-bridge分别占用1个index,因此最终的index等于需要的Root Port数量+1。 + +- 完整配制方法 + + 在虚拟机的XML文件中写入以下内容: + + ```Conf + + + + +
+ + + +
+ + + + +
+ + + ``` + + 其中: + + - Root Port的chassis和port属性必须依次递增,由于中间插入一个PCIe-PCI-Bridge,chassis编号跳过2,但是port编号仍然连续。 + - Root Port的address function的取值范围为0x0\~0x7。 + - 每个slot最多下挂8个function,挂满之后需要递增slot编号。 + + 由于完整配置方法相对复杂,建议采用简化配置方法。 + +## 管理虚拟磁盘 + +### 概述 + +虚拟磁盘类型主要包含virtio-blk、virtio-scsi、vhost-scsi等。virtio-blk模拟的是一种block设备,virtio-scsi和vhost-scsi模拟的是一种scsi设备。 + +- virtio-blk:普通系统盘和数据盘可用,该种配置下虚拟磁盘在虚拟机内部呈现为vd\[a-z\]或vd\[a-z\]\[a-z\]。 +- virtio-scsi:普通系统盘和数据盘建议选用,该种配置下虚拟磁盘在虚拟机内部呈现为sd\[a-z\]或sd\[a-z\]\[a-z\]。 +- vhost-scsi:对性能要求高的虚拟磁盘建议选用,该种配置下虚拟磁盘在虚拟机内部呈现为sd\[a-z\]或sd\[a-z\]\[a-z\]。 + +### 操作步骤 + +虚拟磁盘的配置步骤,请参见“虚拟机配置 > 存储设备”。本节以virtio-scsi磁盘为例,介绍挂载和卸载虚拟磁盘的简单方法。 + +- 挂载virtio-scsi磁盘: + + 使用virsh attach-device命令挂载virtio-scsi虚拟磁盘: + + ```sh + # virsh attach-device + ``` + + 上述命令可以为虚拟机在线挂载磁盘,其中磁盘信息由attach-device.xml文件指定。下面是一个attach-device.xml文件的例子: + + ```Conf + ### attach-device.xml ### + + + + +
+ + ``` + + 通过上述命令挂载的磁盘,在虚拟机关机重启后失效。如果需要为虚拟机持久化挂载虚拟磁盘,需要使用带--config参数的virsh attach-device命令。 + +- 卸载virtio-scsi磁盘: + + 通过在线挂载的磁盘,如果不需要再使用,可以通过virsh detach-device命令动态卸载: + + ```sh + # virsh detach-device + ``` + + 其中,detach-device.xml指定了需要卸载的磁盘的XML信息,与动态挂载时的XML信息保持一致。 + +## 管理虚拟网卡 + +### 概述 + +虚拟网卡类型主要包含virtio-net、vhost-net、vhost-user等。用户在创建虚拟机后,可能会有挂载或者卸载虚拟网卡的需求。openEuler提供了网卡热插拔的功能,通过网卡热插拔,能够改变网络的吞吐量,提高系统的灵活性和扩展性。 + +### 操作步骤 + +虚拟网卡的配置步骤,请参见“虚拟机配置 > 网络设备”。本节以vhost-net网卡为例,介绍挂载和卸载虚拟网卡的简单方法。 + +- 挂载vhost-net网卡: + + 使用virsh attach-device命令挂载vhost-net虚拟网卡: + + ```sh + # virsh attach-device + ``` + + 上述命令可以为虚拟机在线挂载vhost-net网卡,其中网卡信息由attach-device.xml文件指定。下面是一个attach-device.xml文件的例子: + + ```Conf + ### attach-device.xml ### + + + + + + + + ``` + + 通过上述命令挂载的vhost-net网卡,在虚拟机关机重启后失效。如果需要为虚拟机持久化挂载虚拟网卡,需要使用带--config参数的virsh attach-device命令。 + +- 卸载vhost-net网卡: + + 通过在线挂载的网卡,如果不需要再使用,可以通过virsh detach命令动态卸载: + + ```sh + # virsh detach-device + ``` + + 其中,detach-device.xml指定了需要卸载虚拟网卡的XML信息,与动态挂载时的XML信息保持一致。 + +## 配置虚拟串口 + +### 概述 + +在虚拟化环境下,由于管理和业务的需求,虚拟机与宿主机需要互相通信。但在云管理系统复杂的网络架构下,运行在管理平面的服务与运行在业务平面的虚拟机之间,不能简单的进行三层网络互相通信,导致服务部署和信息收集不够快速。因此需要提供虚拟串口,来达到虚拟机与宿主机之间互相通信的目的。 通过在虚拟机的XML配置文件中增加相应串口的配置项,可以实现虚拟机与宿主机之间的互相通信。 + +### 操作步骤 + +Linux虚拟机串口控制台,即虚拟机串口连接到宿主机的一个伪终端设备,通过宿主机的设备间接实现对虚拟机的交互式操作。在该场景下串口需配置为pty类型,本节介绍pty型串口的配置方法。 + +- 在虚拟机的XML配置文件中"devices"节点下添加如下所示的虚拟串口配置项: + + ```Conf + + + + + + ``` + +- 使用virsh console命令连接到正在运行的虚拟机的pty串口。 + + ```sh + # virsh console + ``` + +- 如果要确保没有遗漏任何串口消息,请在启动虚拟机时使用--console选项连接到串口。 + + ```sh + # virsh start --console + ``` + +## 管理设备直通 + +设备直通技术是指将host上的物理设备直接呈现给一台虚拟机,虚拟机可以直接访问该设备资源的一种使用方式。使用设备直通的方式可以让虚拟机获得良好的I/O性能。 + +当前设备直通使用的是VFIO方式,按照直通的设备类型可以分为PCI直通和SR-IOV直通两种类型。 + +### PCI直通 + +PCI直通是指将host上的物理PCI设备直接呈现给一台虚拟机,供虚拟机直接访问的一种使用方式。PCI直通使用了vfio设备直通方式,为虚拟机配置PCI直通的xml配置如下: + +```Conf + + + +
+ + +
+ +``` + +**表 1** PCI直通设备配置项 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数名

+

说明

+

取值

+

hostdev.source.address.domain

+

host OS上的PCI设备的domain号。

+

>=0

+

hostdev.source.address.bus

+

host OS上的PCI设备bus号。

+

>=1

+

hostdev.source.address.slot

+

host OS上的PCI设备的device号。

+

>=0

+

hostdev.source.address.function

+

host OS上的PCI设备的function号。

+

>=0

+

hostdev.driver.name

+

可选配置项,指定PCI直通的后端驱动。

+

vfio(默认配置项)

+

hostdev.rom

+

直通设备的ROM是否呈现给虚拟机。

+

可以配置为“on/off”,默认为“on”。

+
  • on:表示直通设备的ROM呈现给虚拟机,例如:直通网卡虚拟机需要从该网卡的PXE启动时,可以将该选项配置为“on”,HBA卡直通虚拟机需要从ROM中启动时可以将该选项配置为“on”。
  • off:表示直通设备的ROM不呈现给虚拟机。
+

hostdev.address type

+

PCI设备呈现的Guest内bdf号。

+

[0x03-0x1e] (./s`lot范围)

+

说明:

+
  • domain为域信息,bus为总线号,slot为插槽号,function为功能
  • 除了slot插槽号,这里其余均默认为0。
  • 第一个slot插槽号0x00被系统占用,第二个slot号0x01被IDE控制器和USB控制器占用,第三个slot号0x02被video占用。
  • 最后一个slot号0x1f被pvchannel占用。
+
+ +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> VFIO直通方式的最小直通单位是iommu\_group,host根据硬件上的ACS位,来划分iommu\_group。同一个iommu\_group中的设备只允许直通给同一台虚拟机(一个PCI设备上的若干个function,如果属于同一个iommu\_group,只允许直通给一个虚拟机使用)。 + +### SR-IOV直通 + +#### 概述 + +SR-IOV(Single Root I/O Virtualization)是一种基于硬件的虚拟化解决方案,通过SR-IOV技术可以将一个PF(Physical Function)虚拟成多个VF(Virtual Function),每个VF都可以单独被直通给一个虚拟机,极大地提升了硬件资源利用率和虚拟机的I/O性能。一种典型的应用场景就是网卡SR-IOV设备直通,利用SR-IOV技术可以将一个物理网卡(PF)虚拟成多个VF网卡,再把VF直通给虚拟机使用。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> - SR-IOV需要物理硬件支持,使用SR-IOV前请确保要直通的硬件设备支持该能力,并且Host侧的设备驱动程序工作在SR-IOV模式下。 +> - 查询网卡具体型号的办法如下: +> 例如下述回显,第一列为网卡的PCI号,19e5:1822为网卡的厂商号设备号。 +> +> ```sh +> # lspci | grep Ether +> 05:00.0 Ethernet controller: Device 19e5:1822 (rev 45) +> 07:00.0 Ethernet controller: Device 19e5:1822 (rev 45) +> 09:00.0 Ethernet controller: Device 19e5:1822 (rev 45) +> 0b:00.0 Ethernet controller: Device 19e5:1822 (rev 45) +> 81:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01) +> 81:00.1 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01) +> ``` + +#### 操作方法 + +请使用root用户按照如下操作步骤配置SR-IOV直通网卡: + +1. 开启网卡的SR-IOV模式。 + 1. 请确保Guest OS有网卡供应商提供的VF驱动支持,否则Guest OS内VF无法正常工作。 + 2. 在host OS的BIOS中开启SMMU/IOMMU的支持。不同厂家服务器的开启方式可能不同,请参考各服务器的帮助文档。 + 3. HOST驱动配置,开启SR-IOV的VF模式。这里以Hi1822网卡为例,开启16个VF。 + + ```sh + # echo 16 > /sys/class/net/ethX/device/sriov_numvfs + ``` + +2. 获取PF和VF的PCI BDF信息。 + 1. 获取当前单板上的网卡资源列表,参考命令如下: + + ```sh + # lspci | grep Eth + 03:00.0 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family (4*25GE) (rev 45) + 04:00.0 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family (4*25GE) (rev 45) + 05:00.0 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family (4*25GE) (rev 45) + 06:00.0 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family (4*25GE) (rev 45) + 7d:00.0 Ethernet controller: Huawei Technologies Co., Ltd. Device a222 (rev 20) + 7d:00.1 Ethernet controller: Huawei Technologies Co., Ltd. Device a222 (rev 20) + 7d:00.2 Ethernet controller: Huawei Technologies Co., Ltd. Device a221 (rev 20) + 7d:00.3 Ethernet controller: Huawei Technologies Co., Ltd. Device a221 (rev 20) + ``` + + 2. 查看VF的PCI BDF信息,参考命令如下: + + ```sh + # lspci | grep "Virtual Function" + 03:00.1 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.2 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.3 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.4 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.5 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.6 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.7 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:01.0 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:01.1 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:01.2 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + ``` + + 3. 选择一个可用的VF,根据其BDF信息将其配置写入虚拟机的配置文件中。以03:00.1设备为例,对应的bus号是03,slot号是00,function号是1。 + +3. 识别和管理PF/VF对应关系。 + 1. 识别PF对应的VF关系,以PF 03.00.0为例: + + ```sh + # ls -l /sys/bus/pci/devices/0000\:03\:00.0/ + ``` + + 可显示如下的软链接信息,根据信息可以获得其对应的VF编号(virtfnX)和PCI BDF号。 + + 2. 识别VF对应的PF关系,以VF 03:00.1为例: + + ```sh + # ls -l /sys/bus/pci/devices/0000\:03\:00.1/ + ``` + + 可显示下述软链接信息,即可获得其对应PF的PCI BDF号。 + + ```text + lrwxrwxrwx 1 root root 0 Mar 28 22:44 physfn -> ../0000:03:00.0 + ``` + + 3. 获知PF/VF对应的网卡设备名称,例如: + + ```sh + # ls /sys/bus/pci/devices/0000:03:00.0/net + eth0 + ``` + + 4. 设置VF的mac/vlan/qos信息,确保VF在直通之前处于UP状态。以VF 03:00.1为例,假设PF为eth0,VF编号为0。 + + ```sh + # ip link set eth0 vf 0 mac 90:E2:BA:21:XX:XX # 设置mac地址 + # ifconfig eth0 up + # ip link set eth0 vf 0 rate 100 # 设置VF出口速率,单位Mbps + # ip link show eth0 # 查看mac/vlan/qos信息,确认设置成功 + ``` + +4. 挂载SR-IOV网卡到虚拟机中。 + + 创建虚拟机时,在虚拟机配置文件中增加SR-IOV直通的配置项。 + + ```Conf + + + +
+ + + + + + ``` + + **表 1** SR-IOV配置选项说明 + + + + + + + + + + + + + + + + + + + + + + + + +

参数名

+

说明

+

取值

+

hostdev.managed

+

libvirt处理PCI设备的两种模式。

+

no:默认配置,表示直通设备由用户自行管理。

+

yes:表示直通设备由libvirt管理。SR-IOV直通场景需要配置为yes。

+

hostdev.source.address.bus

+

host OS上的PCI设备bus号。

+

>=1

+

hostdev.source.address.slot

+

host OS上的PCI设备device号。

+

>=0

+

hostdev.source.address.function

+

host OS上的PCI设备function号。

+

>=0

+
+ + 关闭SR-IOV功能: + 在虚拟机使用完毕后(虚拟机关机,所有的VF均没有在使用中的时候),若要关闭SR-IOV功能。执行操作如下: + 这里以Hi1822网卡(eth0对应PF的网口名称)为例: + + ```shell + echo 0 > /sys/class/net/eth0/device/sriov_numvfs + ``` + +#### HPRE加速器SR-IOV直通 + +加速器引擎是TaiShan 200服务器基于Kunpeng 920处理器提供的硬件加速解决方案。HPRE加速器用于加速SSL/TLS应用,可以显著降低处理器消耗,提高处理器效率。 +在鲲鹏服务器上,需要把主机Host上的HPRE加速器的VF直通给虚拟机,供虚拟机内部业务使用。 + +**表 1** HPRE加速器说明 + +| 项目 | 说明 | +|-------------|-----------------------------------------------------------------------------------------------------| +| 设备名称 | Hi1620 on-chip RSA/DH security algorithm accelerator (HPRE engine) | +| 功能 | 模幂运算、RSA密钥对运算、DH计算、部分大数辅助运算(模幂、模乘、取模、乘法、模逆、素数测试、互质测试) | +| VendorID | 0x19E5 | +| PF DeviceID | 0xA258 | +| VF DeviceID | 0xA259 | +| 最大VF数量 | 一个HPRE PF最多支持创建63个VF | + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 当虚拟机正在使用VF设备时,不允许卸载Host上的驱动,加速器不支持热插拔。 +> VF操作(VFNUMS为0表示关闭VF,hpre_num用来标识具体的加速器设备): +> +> ```sh +> echo $VFNUMS > /sys/class/uacce/hisi_hpre-$hpre_num/device/sriov_numvfs +> ``` + +## 管理虚拟机USB + +为了方便在虚拟机内部使用USBkey设备、USB海量存储设备等USB设备,openEuler提供了USB设备直通的功能。用户可以通过USB直通和热插拔相关接口给虚拟机配置直通USB设备、或者在虚拟机处于运行的状态下热插/热拔USB设备。 + +### 配置USB控制器 + +#### 概述 + +USB控制器是为虚拟机上的USB设备提供具体USB功能的虚拟控制器设备,在虚拟机内部使用USB设备必须给虚拟机配置USB控制器。当前openEuler支持如下三种USB控制器: + +- UHCI(Universal Host Controller Interface):通用主机控制器接口,也称为USB 1.1主机控制器规范。 +- EHCI(Enhanced Host Controller Interface):增强主机控制器接口,也称为USB 2.0主机控制器规范。 +- xHCI(eXtensible Host Controller Interface):可扩展主机控制器接口,也称为USB 3.0主机控制器规范。 + +#### 注意事项 + +- 主机服务器上需存在支持USB 1.1、USB 2.0和USB 3.0标准的USB控制器硬件和模块。 +- 为虚拟机配置USB控制器时,请按照USB 1.1、USB 2.0到USB 3.0的顺序来配置。 +- 一个xHCI控制器有8个端口,最多可以挂载4个USB 3.0设备和4个USB 2.0设备。一个EHCI控制器有6个端口,最多可以挂载6个USB2.0设备。一个UHCI控制器有2个端口,最多可以挂载2个USB 1.1设备。 +- 每台虚拟机最多支持配置一个相同类型的USB控制器。 +- 不支持热插拔USB控制器。 +- 若虚拟机没有安装USB 3.0的驱动,可能无法识别xHCI控制器,USB 3.0驱动下载和安装方法请参见对应OS发行商官方说明。 +- 为了不影响操作系统的兼容性,为虚拟机配置USB接口的tablet设备时,请指定USB控制器bus号为0(默认挂载到USB 1.1控制器上)。 + +#### 配置方法 + +这里介绍为虚拟机配置USB控制器的配置内容说明。建议同时配置USB 1.1、USB 2.0和USB 3.0,做到同时兼容三种设备。 + +USB 1.1控制器(UHCI)的XML配置项为: + +```Conf + + +``` + +USB 2.0控制器(EHCI)的XML配置为: + +```Conf + + +``` + +USB 3.0控制器(xHCI)的XML配置为: + +```Conf + + +``` + +### 配置USB直通设备 + +#### 概述 + +当虚拟机配置好USB控制器后,就可以通过设备直通的方式将主机上的物理USB设备挂载到虚拟机内部供虚拟机使用。在虚拟化场景下,除了支持静态配置以外还同时支持USB设备的热插/拔操作,即在虚拟机处于运行状态的时候挂载/卸载USB设备。 + +#### 注意事项 + +- 一个USB设备只能直通给一台虚拟机使用 +- 配置了直通USB设备的虚拟机不支持热迁移 +- 虚拟机配置文件中直通的USB设备不存在时,虚拟机会创建失败 +- 对一个正在读写的USB存储设备进行强制热拔操作有可能会损坏USB设备内的文件 + +#### 配置说明 + +这里介绍为虚拟机配置USB设备的配置内容说明。 + +USB设备的XML描述: + +```Conf + + +
+ +
+ +``` + +- `
`,其中,m表示该USB设备在主机上的bus地址,n表示device ID编号。 +- `
` 表示该USB设备要挂载到虚拟机指定的USB控制器。其中x表示控制器ID,与虚拟机所配置的USB控制器index编号相对应,y表示port地址。用户配置直通USB设备的时候需要配置这个字段,确保设备挂载的控制器与预期相符。 + +#### 配置方法 + +配置USB直通的步骤如下: + +1. 为虚拟机配置USB控制器,配置方法请参见“虚拟机配置 > 配置USB控制器”。 +2. 查询主机上的USB设备信息。 + + 通过lsusb命令(需要安装usbutils软件包)查询主机上的USB设备信息,包含bus地址、device地址、设备厂商ID、设备ID和产品描述信息等。例如: + + ```sh + # lsusb + Bus 008 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub + Bus 007 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub + Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub + Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub + Bus 006 Device 002: ID 0bda:0411 Realtek Semiconductor Corp. + Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub + Bus 005 Device 003: ID 136b:0003 STEC + Bus 005 Device 002: ID 0bda:5411 Realtek Semiconductor Corp. + Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub + Bus 001 Device 003: ID 12d1:0003 Huawei Technologies Co., Ltd. + Bus 001 Device 002: ID 0bda:5411 Realtek Semiconductor Corp. + Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub + Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub + ``` + +3. 准备USB设备的XML描述文件,注意在设备热拔之前,请确保USB设备当前不在使用当中,否则可能造成数据丢失。 +4. 执行热插、热拔命令。 + + 假设虚拟机名称为openEulerVM,对应的配置文件为usb.xml。 + + - 热插USB设备,只对当前运行的虚拟机有效,虚拟机冷重启后需要重新配置。 + + ```sh + # virsh attach-device openEulerVM usb.xml --live + ``` + + - 热插USB设备,持久化该配置,即该虚拟机重启后该设备会自动直通给该虚拟机使用。 + + ```sh + # virsh attach-device openEulerVM usb.xml --config + ``` + + - 热拔USB设备,只对当前运行的虚拟机有效,持久化配置的USB设备在虚拟机重启后USB设备会自动直通给该虚拟机。 + + ```sh + # virsh detach-device openEulerVM usb.xml --live + ``` + + - 热拔USB设备,持久化该配置。 + + ```sh + # virsh detach-device openEulerVM usb.xml --config + ``` + +## 管理快照 + +### 概述 + +虚拟机在使用过程中可能由于病毒对系统的破坏、系统文件被误删除或误格式化等原因造成虚拟机系统损坏导致系统无法启动。为了使损坏的系统快速恢复,openEuler提供了存储快照功能。openEuler可以在用户不感知的情况下制作虚拟机在某一时刻的快照(制作通常指需要几秒钟),该快照能帮助用户将磁盘快速恢复到某一时刻的状态,例如系统损坏后能快速恢复系统,从而提升系统可靠性。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 当前存储快照只支持raw、qcow2格式镜像,不支持block块设备。 + +### 操作步骤 + +制作虚拟机存储快照的操作步骤如下: + +1. 登录主机,通过virsh domblklist命令查询虚拟机使用的磁盘。 + + ```sh + $ virsh domblklist openEulerVM + Target Source + --------------------------------------------- + vda /mnt/openEuler-image.qcow2 + ``` + +2. 创建虚拟机磁盘快照_openEuler-snapshot1.qcow2_,命令及回显如下: + + ```sh + $ virsh snapshot-create-as --domain openEulerVM --disk-only --diskspec vda,snapshot=external,file=/mnt/openEuler-snapshot1.qcow2 --atomic + Domain snapshot 1582605802 created + ``` + +3. 磁盘快照查询操作。 + + ```sh + $ virsh snapshot-list openEulerVM + Name Creation Time State + --------------------------------------------------------- + 1582605802 2020-02-25 12:43:22 +0800 disk-snapshot + ``` + +## 配置磁盘IO悬挂 + +### 总体介绍 + +#### 概述 + +存储故障(比如存储断链)场景下,物理磁盘的IO错误,通过虚拟化层传给虚拟机前端,虚拟机内部收到IO错误,可能导致虚拟机内部的用户文件系统变成read-only状态,需要重启虚拟机或者用户手动恢复,这给用户带来额外的工作量。 + +这种情况下,虚拟化平台提供了一种磁盘IO悬挂的能力,即当存储故障时,虚拟机IO下发到主机侧时将IO悬挂住,在悬挂时间内不对虚拟机内部返回IO错误,这样虚拟机内部的文件系统就不会因为IO错误而变为只读状态,而是呈现为Hang住;同时虚拟机后端按指定的悬挂间隔对IO进行重试。如果存储故障在悬挂时间内恢复正常,悬挂住的IO即可恢复落盘,虚拟机内部文件系统自动恢复运行,不需要重启虚拟机;如果存储故障在悬挂时间内未能恢复正常,则上报错误给虚拟机内部,通知给用户。 + +#### 应用场景 + +使用可能会发生存储面链路断链的云盘作为虚拟磁盘后端的场景。 + +#### 注意事项和约束限制 + +- 磁盘IO悬挂仅支持virtio-blk或virtio-scsi类型的虚拟磁盘。 + +- 磁盘IO悬挂的虚拟磁盘后端一般为可能会发生存储面链路断链的云盘。 + +- 磁盘IO悬挂可对读写IO错误分别使能,同一磁盘的读写IO错误重试间隔和超时时间使用相同配置。 + +- 磁盘IO悬挂重试间隔不包含主机侧实际读写IO的开销,即两次IO重试操作实际间隔会大于配置的IO错误重试间隔。 + +- 磁盘IO悬挂无法区分IO错误的具体类型(如存储断链、扇区坏道、预留冲突等),只要硬件返回IO错误,都会进行悬挂处理。 + +- 磁盘IO悬挂时,虚拟机内部IO不会返回,fdisk等访问磁盘的系统命令会卡住,虚拟机内部依赖该命令返回的业务也会一直卡住。 + +- 磁盘IO悬挂时,IO无法正常落盘,可能会导致虚拟机无法优雅关机,需要强制关机。 + +- 磁盘IO悬挂时,无法读取磁盘数据,会造成虚拟机无法正常重启,需要先将虚拟机强制关机,等待存储故障恢复后在重新启动虚拟机。 + +- 存储故障发生后,虽然存在磁盘IO悬挂,依然解决不了以下问题: + + 1. 存储相关高级特性执行失败 + 高级特性包括:虚拟磁盘热插、虚拟磁盘热拔、创建虚拟磁盘、虚拟机启动、虚拟机关机、虚拟机强制关机、虚拟机休眠、虚拟机唤醒、虚拟机存储热迁移、虚拟机存储热迁移取消、虚拟机创建存储快照、虚拟机存储快照合并、查询虚拟机磁盘容量、磁盘在线扩容、插入虚拟光驱、弹出虚拟机光驱。 + + 2. 虚拟机生命周期执行失败 + +- 配置了磁盘IO悬挂的虚拟机发起热迁移时,应该在目的端磁盘的XML配置中带上与源端相同的磁盘IO悬挂配置。 + +### 磁盘IO悬挂配置 + +#### Qemu命令行配置 + +磁盘IO悬挂功能通过在虚拟磁盘设备上指定`werror=retry` `rerror=retry`进行使能,使用`retry_interval`和`retry_timeout`进行重试策略的配置。`retry_interval`为IO错误重试的间隔,配置范围为0-MAX_LONG,单位为毫秒,未配置时使用缺省值1000ms;`retry_timeout`为IO错误重试超时时间,配置范围为0-MAX_LONG,0值表示不会发生超时,单位为毫秒,未配置时使用缺省值0。 + +virtio-blk磁盘的磁盘IO悬挂配置如下: + +```shell +-drive file=/path/to/your/storage,format=raw,if=none,id=drive-virtio-disk0,cache=none,aio=native \ +-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x6,\ +drive=drive-virtio-disk0,id=virtio-disk0,write-cache=on,\ +werror=retry,rerror=retry,retry_interval=2000,retry_timeout=10000 +``` + +virtio-scsi磁盘的磁盘IO悬挂配置如下: + +```shell +-drive file=/path/to/your/storage,format=raw,if=none,id=drive-scsi0-0-0-0,cache=none,aio=native \ +-device scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,\ +device_id=drive-scsi0-0-0-0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0,write-cache=on,\ +werror=retry,rerror=retry,retry_interval=2000,retry_timeout=10000 +``` + +#### xml配置方式 + +磁盘IO悬挂功能通过在磁盘xml配置中指定`error_policy='retry'` `rerror_policy='retry'`进行使能。主要是配置上`retry_interval`和`retry_timeout`的值。`retry_interval`为IO错误重试的间隔,配置范围为0-MAX_LONG,单位为毫秒,未配置时使用缺省值1000ms;`retry_timeout`为IO错误重试超时时间,配置范围为0-MAX_LONG,0值表示不会发生超时,单位为毫秒,未配置时使用缺省值0。 + +virtio-blk磁盘的磁盘IO悬挂xml配置如下: + +```xml + + + + + +``` + +virtio-scsi磁盘的磁盘IO悬挂xml配置如下: + +```xml + + + + +
+ +``` diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/managing-vms.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/managing-vms.md new file mode 100644 index 0000000000000000000000000000000000000000..5a18b7dc6c7071cf109b5596d782ed0991fcb151 --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/managing-vms.md @@ -0,0 +1,788 @@ +# 管理虚拟机 + +## 虚拟机生命周期 + +### 总体介绍 + +#### 概述 + +为了更好地利用硬件资源,降低成本,用户需要合理地管理虚拟机。本节介绍虚拟机生命周期过程中的基本操作,包括虚拟机创建、使用、删除等,指导用户更好地管理虚拟机。 + +#### 虚拟机状态 + +虚拟机主要有如下几种状态: + +- 未定义(undefined):虚拟机未定义或未创建,即libvirt认为该虚拟机不存在。 +- 关闭状态(shut off):虚拟机已经被定义但未运行,或者虚拟机被终止。 +- 运行(running):虚拟机处于运行状态。 +- 暂停(paused):虚拟机运行被挂起,其运行状态被临时保存在内存中,可以恢复到运行状态。 +- 保存(saved):与暂停(paused)状态类似,其运行状态被保存在持久性存储介质中,可以恢复到运行状态。 +- 崩溃(crashed):通常是由于内部错误导致虚拟机崩溃,不可恢复到运行状态。 + +#### 状态转换 + +虚拟机不同状态之间可以相互转换,但必须满足一定规则。虚拟机不同状态之间的转换常用规则如[图1](#fig671014583483)所示。 + +**图 1** 状态转换图 +![](./figures/status-transition-diagram.png) + +#### 虚拟机标识 + +在libvirt中,完成创建的虚拟机实例称做一个“domain”,其描述了虚拟机的CPU、内存、网络设备、存储设备等各种资源的配置信息。在同一个主机上,每个domain具有唯一标识,通过虚拟机名称Name、UUID、Id表示,对应含义请参见[表1](#table84397266483)。在虚拟机生命周期期间,可以通过虚拟机标识对特定虚拟机进行操作。 + +**表 1** domain标识说明 + + + + + + + + + + + + + + + + +

标识

+

含义

+

Name

+

虚拟机名称

+

UUID

+

通用唯一识别码

+

Id

+

虚拟机运行标识

+
说明:

关闭状态的虚拟机无此标识。

+
+
+ +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 可通过virsh命令查询虚拟机Id和UUID,操作方法请参见[查询虚拟机信息](#查询虚拟机信息)章节内容。 + +### 管理命令 + +#### 概述 + +用户可以使用virsh命令工具管理虚拟机生命周期。本节介绍生命周期相关的命令以指导用户使用。 + +#### 前提条件 + +- 执行虚拟机生命周期操作之前,需要查询虚拟机状态以确定可以执行对应操作。状态之间的基本转换关系请参见"总体介绍"中的"状态转换"的内容。 +- 具备管理员权限。 +- 准备好虚拟机XML配置文件。 + +#### 命令使用说明 + +用户可以使用virsh命令管理虚拟机生命周期,命令格式为: + +```bash +virsh +``` + +各参数含义如下: + +- _operate_:管理虚拟机生命周期对应操作,例如创建、销毁、启动等。 +- _obj_:命令操作对象,如指定需要操作的虚拟机。 +- _options_:命令选项,该参数可选。 + +虚拟机生命周期管理各命令如[表1](#table389518422611)所示。其中VMInstance为虚拟机名称、虚拟机ID或者虚拟机UUID,XMLFile是虚拟机XML配置文件,DumpFile为转储文件,请根据实际情况修改。 + +**表 2** 虚拟机生命周期管理命令 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

含义

+

virsh define <XMLFile>

+

定义持久化虚拟机,定义完成后虚拟机处于关闭状态,虚拟机被看作为一个domian实例

+

virsh create <XMLFile>

+

创建一个临时性虚拟机,创建完成后虚拟机处于运行状态

+

virsh start <VMInstance>

+

启动虚拟机

+

virsh shutdown <VMInstance>

+

关闭虚拟机。启动虚拟机关机流程,若关机失败可使用强制关闭

+

virsh destroy <VMInstance>

+

强制关闭虚拟机

+

virsh reboot <VMInstance>

+

重启虚拟机

+

virsh save <VMInstance> <DumpFile>

+

将虚拟机的运行状态转储到文件中

+

virsh restore <DumpFile>

+

从虚拟机状态转储文件恢复虚拟机

+

virsh suspend <VMInstance>

+

暂停虚拟机的运行,使虚拟机处于paused状态

+

virsh resume <VMInstance>

+

唤醒虚拟机,将处于paused状态的虚拟机恢复到运行状态

+

virsh undefine <VMInstance>

+

销毁持久性虚拟机,虚拟机生命周期完结,不能继续对该虚拟机继续操作

+
+ +### 示例 + +本节给出虚拟机生命周期管理相关命令的示例。 + +- 创建虚拟机 + + 虚拟机XML配置文件为openEulerVM.xml,命令和回显如下: + + ```bash + # virsh define openEulerVM.xml + Domain openEulerVM defined from openEulerVM.xml + ``` + +- 启动虚拟机 + + 启动名称为openEulerVM的虚拟机,命令和回显如下: + + ```bash + # virsh start openEulerVM + Domain openEulerVM started + ``` + +- 重启虚拟机 + + 重启名称为openEulerVM的虚拟机,命令和回显如下: + + ```bash + # virsh reboot openEulerVM + Domain openEulerVM is being rebooted + ``` + +- 关闭虚拟机 + + 关闭名称为openEulerVM的虚拟机,命令和回显如下: + + ```bash + # virsh shutdown openEulerVM + Domain openEulerVM is being shutdown + ``` + +- 销毁虚拟机 + - 若虚拟机启动时未使用nvram文件,销毁虚拟机命令如下: + + ```bash + # virsh undefine + ``` + + - 若虚拟机启动时使用了nvram文件,销毁该虚拟机需要指定nvram的处理策略,命令如下: + + ```bash + # virsh undefine + ``` + + 其中\为销毁虚拟机的策略,可取值: + + nvram:销毁虚拟机的同时删除其对应的nvram文件。 + + keep-nvram:销毁虚拟机,但保留其对应的nvram文件。 + + 例如,删除虚拟机openEulerVM及其nvram文件,命令和回显如下: + + ```bash + # virsh undefine openEulerVM --nvram + Domain openEulerVM has been undefined + ``` + +## 在线修改虚拟机配置 + +### 概述 + +虚拟机创建之后用户可以修改虚拟机的配置信息,称为在线修改虚拟机配置。在线修改配置以后,新的虚拟机配置文件会被持久化,并在虚拟机关闭、重新启动后生效。 + +修改虚拟机配置命令格式如下: + +```bash +virsh edit +``` + +virsh edit命令通过编辑“domain”对应的XML配置文件,完成对虚拟机配置的更新。virsh edit使用vi程序作为默认的编辑器,可以通过修改环境变量“EDITOR”或“VISUAL”指定编辑器类型。virsh edit默认优先使用“VISUAL”环境变量指定的文本编辑器。 + +### 操作步骤 + +1. (可选)设置virsh edit命令的编辑器为vim。 + + ```shell + # export VISUAL=vim + ``` + +2. 使用virsh edit打开虚拟机名称为openEulerVM对应的XML配置文件。 + + ```shell + # virsh edit openEulerVM + ``` + +3. 修改虚拟机配置文件。 +4. 保存虚拟机配置文件并退出。 +5. 关闭虚拟机。 + + ```bash + # virsh shutdown openEulerVM + ``` + +6. 启动虚拟机使配置修改生效。 + + ```bash + # virsh start openEulerVM + ``` + +## 查询虚拟机信息 + +### 概述 + +管理员在管理虚拟机的过程中经常需要知道一些虚拟机信息,libvirt提供了一套命令行工具用于查询虚拟机的相关信息。本章介绍相关命令的使用方法,便于管理员来获取虚拟机的各种信息。 + +### 前提条件 + +查询虚拟机信息需要: + +- libvirtd服务处于运行状态。 + +- 命令行操作需要拥有管理员权限。 + +### 查询主机上的虚拟机信息 + +- 查询主机上处于运行和暂停状态的虚拟机列表。 + + ```bash + # virsh list + ``` + + 例如,下述回显说明当前主机上存在3台虚拟机,其中openEulerVM01、openEulerVM02处于运行状态,openEulerVM03处于暂停状态。 + + ```txt + Id Name State + ---------------------------------------------------- + 39 openEulerVM01 running + 40 openEulerVM02 running + 69 openEulerVM03 paused + ``` + +- 查询主机上已经定义的所有虚拟机信息列表。 + + ```bash + # virsh list --all + ``` + + 例如,下述回显说明当前主机上定义了4台虚拟机,其中虚拟机openEulerVM01处于运行状态,openEulerVM02处于暂停状态,openEulerVM03和openEulerVM04处于关机状态。 + + ```bash + Id Name State + ---------------------------------------------------- + 39 openEulerVM01 running + 69 openEulerVM02 paused + - openEulerVM03 shut off + - openEulerVM04 shut off + ``` + +### 查询虚拟机基本信息 + +Libvirt组件提供了一组查询虚拟机状态信息的命令,包括虚拟机运行状态、设备信息或者调度属性等,使用方法请参见[表1](#table10582103963816)。 + +**表 3** 查询虚拟机基本信息 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

查询的信息内容

+

命令行

+

说明

+

基本信息

+

virsh dominfo <VMInstance>

+

包括虚拟机ID、UUID,虚拟机规格等信息。

+

当前状态

+

virsh domstate <VMInstance>

+

可以使用--reason选项查询虚拟机变为当前状态的原因。

+

调度信息

+

virsh schedinfo <VMInstance>

+

包括vCPU份额信息。

+

vCPU数目

+

virsh vcpucount <VMInstance>

+

查询虚拟机vCPU的个数。

+

虚拟块设备状态

+

virsh domblkstat <VMInstance>

+

查询块设备名称可以使用virsh domblklist命令。

+

虚拟网卡状态

+

virsh domifstat <VMInstance> <interface>

+

查询网卡名称可以使用virsh domiflist命令。

+

I/O线程

+

virsh iothreadinfo <VMInstance>

+

查询虚拟机I/O线程及其CPU亲和性信息

+
+ +### 示例 + +- 使用virsh dominfo查询一个创建好的虚拟机的基本信息,从查询结果可知,虚拟机ID为5,UUID为ab472210-db8c-4018-9b3e-fc5319a769f7,内存大小为8GiB,vCPU数目为4个等。 + + ```bash + # virsh dominfo openEulerVM + Id: 5 + Name: openEulerVM + UUID: ab472210-db8c-4018-9b3e-fc5319a769f7 + OS Type: hvm + State: running + CPU(s): 4 + CPU time: 6.8s + Max memory: 8388608 KiB + Used memory: 8388608 KiB + Persistent: no + Autostart: disable + Managed save: no + Security model: none + Security DOI: 0 + ``` + +- 使用virsh domstate查询虚拟机的当前状态,从查询结果可知,虚拟机openEulerVM当前处于运行状态。 + + ```bash + # virsh domstate openEulerVM + running + ``` + +- 使用virsh schedinfo查询虚拟机的调度信息,从查询结果可知,虚拟机CPU预留份额为1024。 + + ```bash + # virsh schedinfo openEulerVM + Scheduler : posix + cpu_shares : 1024 + vcpu_period : 100000 + vcpu_quota : -1 + emulator_period: 100000 + emulator_quota : -1 + global_period : 100000 + global_quota : -1 + iothread_period: 100000 + iothread_quota : -1 + ``` + +- 使用virsh vcpucount查询虚拟机的vCPU数目,从查询结果可知,虚拟机有4个CPU。 + + ```bash + # virsh vcpucount openEulerVM + maximum live 4 + current live 4 + ``` + +- 使用virsh domblklist查询虚拟机磁盘设备信息,从查询结果可知,虚拟机有2个磁盘,sda是qcow2格式的虚拟磁盘,sdb是一个cdrom设备。 + + ```bash + # virsh domblklist openEulerVM + Target Source + --------------------------------------------------------------------- + sda /home/openeuler/vm/openEuler_aarch64.qcow2 + sdb /home/openeuler/vm/openEuler-20.09-aarch64-dvd.iso + ``` + +- 使用virsh domiflist查询虚拟机网卡信息,从查询结果可知,虚拟机有1张网卡,对应的后端是vnet0在主机br0网桥上,MAC地址为00:05:fe:d4:f1:cc。 + + ```bash + # virsh domiflist openEulerVM + Interface Type Source Model MAC + ------------------------------------------------------- + vnet0 bridge br0 virtio 00:05:fe:d4:f1:cc + ``` + +- 使用virsh iothreadinfo查询虚拟机I/O线程信息,从查询结果可知虚拟机有5个I/O线程,在物理CPU7-10上进行调度。 + + ```bash + # virsh iothreadinfo openEulerVM + IOThread ID CPU Affinity + --------------------------------------------------- + 3 7-10 + 4 7-10 + 5 7-10 + 1 7-10 + 2 7-10 + ``` + +## 登录虚拟机 + +本章介绍使用VNC登录虚拟机的方法。 + +### 使用VNC密码登录 + +#### 概述 + +当虚拟机操作系统安装部署完成之后,用户可以通过VNC协议远程登录虚拟机,从而对虚拟机进行管理操作。 + +#### 前提条件 + +使用RealVNC、TightVNC等客户端登录虚拟机,在登录虚拟机之前需要获取如下信息: + +- 虚拟机所在主机的IP地址。 +- 确保客户端所在的环境可以访问到主机的网络。 +- 虚拟机的VNC侦听端口,该端口一般在客户机启动时自动分配,一般为5900 + x(x为正整数,按照虚拟机启动的顺序递增,且5900对用户不可见)。 +- 如果VNC设置了密码,还需要获取虚拟机的VNC密码。 + +为虚拟机VNC配置密码,需要编辑虚拟机XML配置文件,即为graphics元素新增一个passwd属性,属性的值为要配置的密码。例如,将虚拟机的VNC密码配置为n8VfjbFK的XML配置参考如下: + +```shell + + + +``` + +#### 操作步骤 + +1. 查询虚拟机使用的VNC端口号。例如名称为openEulerVM的虚拟机,命令如下: + + ```bash + # virsh vncdisplay openEulerVM + :3 + ``` + + 登录 VNC 需要配置防火墙规则,允许 VNC 端口的连接。参考命令如下,其中X为数值“5900 + 端口号” ,例如本例中为5903。 + + ```shell + firewall-cmd --zone=public --add-port=X/tcp + ``` + +2. 打开VncViewer软件,输入主机IP和端口号。格式为“主机IP:端口号”,例如:“10.133.205.53:3”。 +3. 单击“确定”输入VNC密码(可选),登录到虚拟机VNC进行操作。 + +### 配置VNC-TLS登录 + +#### 概述 + +VNC服务端和客户端默认采用明文方式进行数据传输,因此通信内容可能被第三方截获。为了提升安全性,openEuler支持VNC服务端配置TLS模式进行加密认证。TLS(Transport Layer Security)即传输层安全,可以实现VNC服务端和客户端之间加密通信,从而防止通信内容被第三方截获。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> - 使用TLS加密认证模式需要VNC客户端支持TLS模式(例如TigerVNC),否则无法连接到VNC客户端。 +> - TLS加密认证模式配置粒度为主机服务器级别,开启该特性后,主机上正在运行的所有虚拟机对应的VNC客户端都将开启TLS加密认证模式。 + +#### 操作步骤 + +VNC开启TLS加密认证模式的操作步骤如下: + +1. 登录VNC服务端所在主机登录VNC服务端所在主机,开启或修改服务端配置文件/etc/libvirt/qemu.conf中对应的配置项。相关配置内容如下所示: + + ```conf + vnc_listen = "x.x.x.x" # "x.x.x.x"为VNC的侦听地址,请用户根据实际配置,VNC服务端只允许该地址或地址段范围内的客户端连接请求 + vnc_tls = 1 # 配置为1,表示开启VNC TLS支持 + vnc_tls_x509_cert_dir = "/etc/pki/libvirt-vnc" #指定证书存放的路径为/etc/pki/libvirt-vnc + vnc_tls_x509_verify = 1 #配置为1,表示TLS认证使用X509证书 + ``` + +2. 为VNC创建证书和私钥文件。此处以GNU TLS为例进行说明。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > 使用GNU TLS,请提前安装好gnu-utils软件包。 + + 1. 制作证书颁发机构CA(Certificate Authority)的证书文件。 + + ```shell + # certtool --generate-privkey > ca-key.pem + ``` + + 2. 制作自签名的CA证书公私钥。其中Your organization name为机构名,由用户指定。 + + ```shell + # cat > ca.info< server.info< server-key.pem + # certtool --generate-certificate \ + --load-ca-certificate ca-cert.pem \ + --load-ca-privkey ca-key.pem \ + --load-privkey server-key.pem \ + --template server.info \ + --outfile server-cert.pem + ``` + + 上述生成文件,server-key.pem是VNC服务端的私钥,server-cert.pem是VNC服务端的公钥。 + + 4. 为VNC客户端颁发证书。 + + ```shell + # cat > client.info< client-key.pem + # certtool --generate-certificate \ + --load-ca-certificate ca-cert.pem \ + --load-ca-privkey ca-key.pem \ + --load-privkey client-key.pem \ + --template client.info \ + --outfile client-cert.pem + ``` + + 上述生成文件,client-key.pem是VNC客户端的私钥,client-cert.pem是VNC客户端的公钥,生成的公私钥对需要拷贝到VNC客户端。 + +3. 关闭需要被登录的虚拟机,重启VNC服务端所在主机的libvirtd服务。 + + ```shell + # systemctl restart libvirtd + ``` + +4. 将生成的服务端证书放置到VNC服务端指定目录并将证书的权限改为只允许当前用户读写。 + + ```shell + # sudo mkdir -m 750 /etc/pki/libvirt-vnc + # cp ca-cert.pem /etc/pki/libvirt-vnc/ca-cert.pem + # cp server-cert.pem /etc/pki/libvirt-vnc/server-cert.pem + # cp server-key.pem /etc/pki/libvirt-vnc/server-key.pem + # chmod 0600 /etc/pki/libvirt-vnc/* + ``` + +5. 将生成的客户端证书ca-cert.pem,client-cert.pem和client-key.pem拷贝到VNC客户端。配置VNC客户端的TLS证书后即可使用VNC TLS登录。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > VNC客户端证书的配置请参见各客户端对应的使用说明,由用户自行配置。 + > 登录虚拟机的方式请参见“使用VNC密码登录”。 + +## 虚拟机安全启动 + +### 总体介绍 + +#### 概述 + +安全启动(Secure Boot)就是利用公私钥对启动部件进行签名和验证。启动过程中,前一个部件验证后一个部件的数字签名,验证通过后,运行后一个部件,验证不通过则启动失败。安全启动的作用是检测设备启动阶段固件(Firmware)以及软件是否被篡改,防止恶意软件侵入和修改。通过安全启动可以保证系统启动过程中各个部件的完整性,防止没有经过认证的部件被加载运行,从而防止对系统及用户数据产生安全威胁。安全启动是在UEFI启动方式上实现的,Legacy启动方式不支持安全启动。根据UEFI规定,主板出厂的时候可以内置一些可靠的公钥。任何想要在这块主板上加载的操作系统或者硬件驱动程序,都必须通过这些公钥的认证。物理机上的安全启动由物理BIOS完成,虚拟机的安全启动通过软件模拟。虚拟机安全启动流程与host安全启动流程一致,都遵循开源UEFI规范。虚拟化平台上的UEFI由edk组件提供,虚拟机启动时qemu将UEFI镜像映射到内存中,为虚拟机模拟固件启动流程,安全启动正是虚拟机启动过程中edk提供的一个安全保护能力,用来保护虚拟机OS内核不被篡改。安全启动验签顺序:UEFI BIOS->shim->grub->vmlinuz(依次验签通过并加载)。 + +| 中文 | 英文 | 缩略语 | 中文定义/描述 | +| :-----| :----- | :----- | :----- | +| 安全启动 | Secure boot | Secure boot | 安全启动就是启动过程中,前一个部件验证后一个部件的数字签名,验证通过后,运行后一个部件,验证不通过就停下来。通过安全启动可以保证系统启动过程中各个部件的完整性。 | +| 平台密钥 | Platform key | PK | OEM厂商所有,必须为 RSA 2048 或更强,PK为平台拥有者和平台固件之间建立可信关系。平台拥有者将PK的公钥部分PKpub注册到平台固件中,平台拥有者可以使用PK的私有部分PKpriv来改变平台的拥有权或者注册KEK密钥。 | +| 密钥交换密钥 | Key exchange key | KEK | KEK为平台固件和OS之间创建可信关系。每一个操作系统和与平台固件通信的第三方应用在平台固件中注册KEK密钥的公共部分KEKpub。 | +| 签名数据库 | Database white list | DB | 存储验证shim、grub、vmlinuz等组件的密钥。 | +| 签名吊销数据库 | Database black list | DBx | 存储吊销的密钥。 | + +#### 功能说明 + +本次实现的虚拟机安全启动特性基于edk开源项目。非安全启动模式下,Linux基本流程如下: + +**图 1** 系统启动流程图 + +![](./figures/OSBootFlow.png) + +安全启动模式下UEFI BIOS启动后加载的首个组件是系统镜像中的shim,shim与UEFI BIOS进行交互获取存储在UEFI BIOS变量db里面的密钥对grub进行验证,加载grub后同样调用密钥和认证接口对kernel进行验证。Linux启动流程如下: + +**图 2** 安全启动流程图 + +![](./figures/SecureBootFlow.png) + +从整体处理流程上来看,安全启动特性包含多个关键场景,根据场景分析和系统分解,安全启动特性涉及以下几个子系统:UEFI BIOS校验shim,shim校验grub,grub校验kernel。UEFI BIOS对shim进行验证,验证通过则启动shim,不通过则提示错误,无法启动。Shim需要在镜像编译制作过程中使用私钥进行签名,公钥证书导入UEFI BIOS变量区DB中。Shim启动后验证启动grub,验证通过则启动grub,不通过则提示错误,无法启动。Grub需要在镜像编译制作过程中进行签名,使用和shim一样的公私钥对。Grub启动后检查调用shim注册在UEFI BIOS的认证接口和密钥对kernel进行验证,通过则启动内核,不通过则提示错误,grub需要在镜像编译制作过程中进行签名,使用和shim一样的公私钥对。 + +#### 约束限制 + +- 在不支持安全启动的UEFI BIOS上运行,对现有功能没有影响,业务无感知。 +- 安全启动特性依赖UEFI BIOS,必须在UEFI支持此功能的条件下才能发挥作用。 +- 在UEFI BIOS开启安全启动的情况下,如果相关部件没有签名或签名不正确,则无法正常启动系统。 +- 在UEFI BIOS关闭安全启动的情况下,启动过程的验证功能都会被关闭。 +- 安全启动验证链后半段,即shim->grub->kernel引导内核启动这部分的验证链由操作系统镜像实现,若操作系统不支持引导内核安全启动过程,则虚拟机安全启动失败。 +- 当前不提供x86架构使用nvram文件配置虚拟机安全启动 + +### 安全启动实践 + +虚拟机安全启动依赖于UEFI BIOS的实现,UEFI BIOS镜像通过edk rpm包安装,本节以AArch64为例对虚拟机安全启动进行配置。 + +#### 虚拟机配置 + +edk rpm包中的组件安装于/usr/share/edk2/aarch64目录下,包括`QEMU_EFI-pflash.raw`和`vars-template-pflash.raw`。虚拟机启动UEFI BIOS部分xml配置如下: + +```xml + + hvm + /usr/share/edk2/aarch64/QEMU_EFI-pflash.raw + /path/to/QEMU-VARS.fd + +``` + +其中/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw为UEFI BIOS镜像路径。/usr/share/edk2/aarch64/vars-template-pflash.raw为nvram镜像模板路径,/path/to/QEMU-VARS.fd为当前虚拟机nvram镜像文件路径,用于保存UEFI BIOS系统中的环境变量。 + +#### 证书导入 + +虚拟机安全启动时的证书从BIOS界面导入,在证书导入前需要将证书文件导入到虚拟机中。可以通过挂载磁盘的方式将证书文件所在目录挂载到虚拟机中,例如制作包含证书的镜像,并在虚拟机的配置文件xml中配置挂载该镜像: + +制作证书文件镜像 + +```shell +dd of='/path/to/data.img' if='/dev/zero' bs=1M count=64 +mkfs.vfat -I /path/to/data.img +mkdir /path/to/mnt +mount path/to/data.img /path/to/mnt/ +cp -a /path/to/certificates/* /path/to/mnt/ +umount /path/to/mnt/ +``` + +其中,/path/to/certificates/为证书文件所在路径,/path/to/data.img为证书文件镜像所在路径,/path/to/mnt/为镜像挂载路径。 + +在虚拟机xml文件中配置挂载该镜像 + +```xml + + + + + + + + + + +``` + +启动虚拟机,导入PK证书,流程如下(KEK证书,DB证书导入方式相同): + +虚拟机启动后,点击F2进入bios界面 + +**图 1** 进入bios界面 + +![](./figures/CertEnrollP1.png) + +**图 2** 进入Device Manager + +![](./figures/CertEnrollP2.png) + +**图 3** 进入Custom Secure Boot Options + +![](./figures/CertEnrollP3.png) + +**图 4** 进入PK Options + +![](./figures/CertEnrollP4.png) + +**图 5** Enroll PK + +![](./figures/CertEnrollP5.png) + +在File Explorer界面可以看到很多磁盘目录,其中包括我们通过磁盘挂载的证书文件目录 + +**图 6** File Explorer + +![](./figures/CertEnrollP6.png) + +在磁盘目录中选择要导入的PK证书 + +**图 7** 进入证书所在磁盘 + +![](./figures/CertEnrollP7.png) + +**图 8** 选择Commit Changes and Exit保存导入证书 + +![](./figures/CertEnrollP8.png) + +导入证书后,UEFI BIOS将证书信息以及安全启动属性写入nvram配置文件/path/to/QEMU-VARS.fd中,虚拟机下一次启动时会从/path/to/QEMU-VARS.fd文件中读取相关配置并初始化证书信息以及安全启动属性,自动导入证书并开启安全启动。同样,我们可以将/path/to/QEMU-VARS.fd作为其他相同配置虚拟机的UEFI BIOS启动配置模板文件,通过修改nvram template字段使其他虚拟机启动时自动导入证书并开启安全启动选项,虚拟机xml配置修改如下: + +```xml + + hvm + /usr/share/edk2/aarch64/QEMU_EFI-pflash.raw + + +``` + +#### 安全启动观测 + +正确配置虚拟机并导入PK、KEK、DB证书后,虚拟机将以安全启动的方式运行。可以通过在虚拟机配置文件xml中配置串口日志文件观测虚拟机是否为安全启动,串口日志文件的配置方式如: + +```xml + + + +``` + +虚拟机加载系统镜像成功后,当串口日志文件中出现"UEFI Secure Boot is enabled"信息时,表明虚拟机当前为安全启动。 diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-caution.gif b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-caution.gif differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-danger.gif b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-danger.gif differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-note.gif b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-note.gif differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-notice.gif b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-notice.gif differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-tip.gif b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-tip.gif differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-warning.gif b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/public_sys-resources/icon-warning.gif differ diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/system-resource-management.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/system-resource-management.md new file mode 100644 index 0000000000000000000000000000000000000000..1c972b473fa96b561fbdaf15f700cd09083d1f01 --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/system-resource-management.md @@ -0,0 +1,491 @@ +# 管理系统资源 + +## 总体说明 + +openEuler 虚拟化使用libvirt命令来管理虚拟机的系统资源,如vCPU、虚拟内存资源等。 + +在开始前: + +- 确保主机上运行了libvirtd守护进程。 +- 用virsh list --all命令确认虚拟机已经被定义。 + +## 管理虚拟CPU + +### CPU份额 + +#### 概述 + +虚拟化环境下,同一主机上的多个虚拟机竞争使用物理CPU。为了防止某些虚拟机占用过多的物理CPU资源,影响相同主机上其他虚拟机的性能,需要平衡虚拟机vCPU的调度,避免物理CPU的过度竞争。 + +CPU份额表示一个虚拟机竞争物理CPU计算资源的能力大小总和。用户通过调整cpu\_shares值能够设置虚拟机抢占物理CPU资源的能力。cpu\_shares值无单位,是一个相对值。虚拟机获得的CPU计算资源,是与其他虚拟机的CPU份额,按相对比例,瓜分物理CPU除预留外可用计算资源。通过调整CPU份额来保证虚拟机CPU计算资源服务质量。 + +#### 操作步骤 + +通过修改分配给虚拟机的运行时间的cpu\_shares值,来平衡vCPU之间的调度。 + +- 查看虚拟机的当前CPU份额: + + ```bash + $ virsh schedinfo + Scheduler : posix + cpu_shares : 1024 + vcpu_period : 100000 + vcpu_quota : -1 + emulator_period: 100000 + emulator_quota : -1 + global_period : 100000 + global_quota : -1 + iothread_period: 100000 + iothread_quota : -1 + ``` + +- 在线修改:修改处于running状态的虚拟机的当前CPU份额,使用带 **--live** 参数的virsh schedinfo命令: + + ```bash + $ virsh schedinfo --live cpu_shares= + ``` + + 比如将正在运行的虚拟机openEulerVM的CPU份额从1024改为2048: + + ```bash + $ virsh schedinfo openEulerVM --live cpu_shares=2048 + Scheduler : posix + cpu_shares : 2048 + vcpu_period : 100000 + vcpu_quota : -1 + emulator_period: 100000 + emulator_quota : -1 + global_period : 100000 + global_quota : -1 + iothread_period: 100000 + iothread_quota : -1 + ``` + + 对cpu\_shares值的修改立即生效,虚拟机_openEulerVM_能得到的运行时间将是原来的2倍。但是这一修改将在虚拟机关机并重新启动后失效。 + +- 持久化修改:在libvirt内部配置中修改虚拟机的CPU份额,使用带 **--config** 参数的virsh schedinfo命令: + + ```bash + $ virsh schedinfo --config cpu_shares= + ``` + + 比如将虚拟机openEulerVM的CPU份额从1024改为2048: + + ```bash + $ virsh schedinfo openEulerVM --config cpu_shares=2048 + Scheduler : posix + cpu_shares : 2048 + vcpu_period : 0 + vcpu_quota : 0 + emulator_period: 0 + emulator_quota : 0 + global_period : 0 + global_quota : 0 + iothread_period: 0 + iothread_quota : 0 + ``` + + 对cpu\_shares值的修改不会立即生效,在虚拟机openEulerVM下一次启动后才生效,并持久生效。虚拟机openEulerVM能得到的运行时间将是原来的2倍。 + +### 绑定QEMU进程至物理CPU + +#### 概述 + +QEMU主进程绑定特性是将QEMU主进程绑定到特定的物理CPU范围内,从而保证了运行不同业务的虚拟机不会干扰到邻位虚拟机。例如在一个典型的云计算场景中,一台物理机上会运行多台虚拟机,而每台虚拟机的业务不同,造成了不同程度的资源占用,为了避免存储IO密集的虚拟机对邻位虚拟机的干扰,需要将不同虚拟机处理IO的存储进程完全隔离,由于QEMU主进程是处理前后端的主要服务进程,故需要实现隔离。 + +#### 操作步骤 + +通过virsh emulatorpin命令可以绑定QEMU主进程到物理CPU。 + +- 查看QEMU进程当前绑定的物理CPU范围: + + ```bash + $ virsh emulatorpin openEulerVM + emulator: CPU Affinity + ---------------------------------- + *: 0-63 + ``` + + 这说明虚拟机_openEulerVM_对应的QEMU主进程可以在主机的所有物理CPU上调度。 + +- 在线绑定:修改处于running状态的虚拟机对应的QEMU进程的绑定关系,使用带 **--live** 参数的vcpu emulatorpin命令: + + ```bash + $ virsh emulatorpin openEulerVM --live 2-3 + + $ virsh emulatorpin openEulerVM + emulator: CPU Affinity + ---------------------------------- + *: 2-3 + ``` + + 以上命令把虚拟机_open__Euler__VM_对应的QEMU进程绑定到物理CPU2、3上,即限制了QEMU进程只在这两个物理CPU上调度。这一绑定关系的调整立即生效,但在虚拟机关机并重新启动后失效。 + +- 持久化绑定:在libvirt内部配置中修改虚拟机对应的QEMU进程的绑定关系,使用带 **--config** 参数的virsh emulatorpin命令: + + ```bash + $ virsh emulatorpin openEulerVM --config 0-3,^1 + + $ virsh emulatorpin openEulerVM --config + emulator: CPU Affinity + ---------------------------------- + *: 0,2-3 + ``` + + 以上命令把虚拟机_open__Euler__VM_对应的QEMU进程绑定到物理CPU0、2、3上,即限制了QEMU进程只在这三个物理CPU上调度。**这一绑定关系的调整不会立即生效,在虚拟机下一次启动后才生效,并持久生效**。 + +### 调整虚拟CPU绑定关系 + +#### 概述 + +把虚拟机的vCPU绑定在物理CPU上,即vCPU只在绑定的物理CPU上调度,在特定场景下达到提升虚拟机性能的目的。比如在NUMA系统中,把vCPU绑定在同一个NUMA节点上,可以避免vCPU跨节点访问内存,避免影响虚拟机运行性能。如果未绑定,默认vCPU可在任何物理CPU上调度。具体的绑定策略由用户来决定。 + +#### 操作步骤 + +通过virsh vcpupin命令可以调整vCPU和物理CPU的绑定关系。 + +- 查看虚拟机的当前vCPU绑定信息: + + ```bash + $ virsh vcpupin openEulerVM + VCPU CPU Affinity + ---------------------- + 0 0-63 + 1 0-63 + 2 0-63 + 3 0-63 + ``` + + 这说明虚拟机_openEulerVM_的所有vCPU可以在主机的所有物理CPU上调度。 + +- 在线调整:修改处于running状态的虚拟机的当前vCPU绑定关系,使用带 **--live** 参数的vcpu vcpupin命令: + + ```bash + $ virsh vcpupin openEulerVM --live 0 2-3 + + $ virsh vcpupin openEulerVM + VCPU CPU Affinity + ---------------------- + 0 2-3 + 1 0-63 + 2 0-63 + 3 0-63 + ``` + + 以上命令把虚拟机_open__Euler__VM_的vCPU0绑定到PCPU2、3上,即限制了vCPU0只在这两个物理CPU上调度。这一绑定关系的调整立即生效,但在虚拟机关机并重新启动后失效。 + +- 持久化调整:在libvirt内部配置中修改虚拟机的vCPU绑定关系,使用带 **--config** 参数的virsh vcpupin命令: + + ```bash + $ virsh vcpupin openEulerVM --config 0 0-3,^1 + + $ virsh vcpupin openEulerVM --config + VCPU CPU Affinity + ---------------------- + 0 0,2-3 + 1 0-63 + 2 0-63 + 3 0-63 + ``` + + 以上命令把虚拟机_open__Euler__VM_的vCPU0绑定到物理CPU0、2、3上,即限制了vCPU0只在这三个物理CPU上调度。**这一绑定关系的调整不会立即生效,在虚拟机下一次启动后才生效,并持久生效**。 + +### CPU热插拔 + +#### 概述 + +在线增加或减少(热插拔)虚拟机CPU是指在虚拟机处于运行状态下,为虚拟机热插拔CPU而不影响虚拟机正常运行的方案。当虚拟机内部业务压力不断增大,会出现所有CPU均处于较高负载的情形。为了不影响虚拟机内的正常业务运行,可以使用CPU热插功能(在不关闭虚拟机情况下增加虚拟机的CPU数目),提升虚拟机的计算能力。当虚拟机内部业务压力下降时,可以使用CPU热拔功能(在不关闭虚拟机情况下减少虚拟机的CPU数目)去除多余的计算能力,降低业务成本。 + +注意:从2403版本开始,AArch64架构新增了CPU热拔功能,但实现上采用了新的主线社区方案,和之前版本的CPU热插协议不兼容。Guest版本和Host版本需匹配,即2403及将来版本的Guest需搭配2403及将来版本的Host,2403之前版本的Guest需搭配2403之前版本的Host,才能正常使用CPU热插(拔)功能。 + +#### 约束限制 + +- 如果处理器为AArch64架构,创建虚拟机时指定的虚拟机芯片组类型\(machine\)需为virt-4.2或virt更高版本。如果处理器为x86\_64架构,创建虚拟机时指定的虚拟机芯片组类型\(machine\)需为pc-i440fx-1.5或pc更高版本。 +- 对于AArch64架构虚拟机,初始启动时就存在的CPU不支持热插拔。 +- 在配置Guest NUMA的场景中,必须把属于同一个socket的vcpu配置在同一vNode中,否则热插拔CPU后可能导致虚拟机softlockup,进而可能导致虚拟机panic。 +- 虚拟机在迁移、休眠唤醒、快照过程中均不支持CPU热插拔。 +- 虚拟机CPU热插是否自动上线取决于虚拟机操作系统自身逻辑,虚拟化层不保证热插CPU自动上线。 +- CPU热插同时受限于Hypervisor和GuestOS支持的最大CPU数目。 +- 虚拟机启动、关闭、重启过程中可能出现热插CPU失效的情况,但再次重启会生效。 +- 虚拟机启动、关闭、重启过程中可能出现热拔CPU超时失败的情况,需等虚拟机回到正常运行状态重试。 +- 热插拔虚拟机CPU的时候,如果新增CPU数目不是虚拟机CPU拓扑配置项中Cores的整数倍,可能会导致虚拟机内部看到的CPU拓扑是混乱的,建议每次新增或减少的CPU数目为Cores的整数倍。 +- 若需要热插拔CPU在线生效且在虚拟机重启后仍有效,virsh setvcpus接口中需要同时传入--config和--live选项, 将热插拔CPU动作持久化。 + +#### 操作步骤 + +**一、配置虚拟机XML** + +1. 使用CPU热插拔功能,需要在创建虚拟机时配置虚拟机当前的CPU数目、虚拟机所支持的最大CPU数目,以及虚拟机芯片组类型(对于AArch64架构,需为virt-4.2及以上版本。对于x86\_64架构,需为pc-i440fx-1.5及以上版本)。这里以AArch64架构虚拟机为例,配置模板如下: + + ```shell + + ... + n + + hvm + + ... + + ``` + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > placement的值必须是static。 + > m为虚拟机当前CPU数目,即虚拟机启动后默认的CPU数目。n为虚拟机支持热插到的最大CPU数目,该值不能超过Hypervisor支持的虚拟机最大CPU规格及GuestOS支持的最大CPU规格。n大于或等于m。 + + 例如,配一个虚拟机当前CPU数目为4,最大支持的热插CPU上限为64的XML配置为: + + ```shell + + …… + 64 + + hvm + + …… + + ``` + +**二、热插并上线CPU** + +1. 如果热插CPU后需要自动上线热插的CPU,可以使用root权限在虚拟机内部创建udev rules文件/etc/udev/rules.d/99-hotplug-cpu.rules,并在其中定义udev规则,内容参考如下: + + ```shell + # automatically online hot-plugged cpu + ACTION=="add", SUBSYSTEM=="cpu", ATTR{online}="1" + ``` + + 如果没有使用udev rules自动上线热插CPU,可以在热插CPU后,使用root权限,参考如下命令手动上线: + + ```shell + for i in `grep -l 0 /sys/devices/system/cpu/cpu*/online` + do + echo 1 > $i + done + ``` + +2. 利用virsh工具进行虚拟机CPU热插操作。例如给虚拟机openEulerVM热插CPU到6,且在线生效的参考命令如下: + + ```bash + virsh setvcpus openEulerVM 6 --live + ``` + + virsh setvcpus 进行虚拟机CPU热插操作的格式如下: + + ```bash + virsh setvcpus [--config] [--live] + ``` + + - domain: 参数,必填。指定虚拟机名称。 + - count: 参数,必填。指定目标CPU数目,即热插后虚拟机CPU数目。 + - --config: 选项,选填。虚拟机下次启动时仍有效。 + - --live: 选项,选填。在线生效。 + +**三、热拔CPU** + +利用virsh工具进行虚拟机CPU热拔操作。例如给虚拟机openEulerVM热拔CPU到4,参考命令如下: + +```bash +virsh setvcpus openEulerVM 4 --live +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> virsh setvcpus 进行虚拟机CPU热插操作的格式如下: +> +> ```bash +> virsh setvcpus [--config] [--live] +> ``` +> +> - domain: 参数,必填。指定虚拟机名称。 +> - count: 参数,必填。指定目标CPU数目,即热拔后虚拟机CPU数目。 +> - --config: 选项,选填。虚拟机下次启动时仍有效。 +> - --live: 选项,选填。在线生效。 + +## 管理虚拟内存 + +### NUMA简介 + +传统的多核运算使用SMP(Symmetric Multi-Processor)模式:将多个处理器与一个集中的存储器和I/O总线相连。所有处理器只能访问同一个物理存储器,因此SMP系统也被称为一致存储器访问(UMA)系统。一致性指无论在什么时候,处理器只能为内存的每个数据保持或共享唯一一个数值。很显然,SMP的缺点是可伸缩性有限,因为在存储器和I/O接口达到饱和的时候,增加处理器并不能获得更高的性能。 + +NUMA(Non Uniform Memory Access Architecture) 模式是一种分布式存储器访问方式,处理器可以同时访问不同的存储器地址,大幅度提高并行性。 NUMA模式下,处理器被划分成多个“节点”(NODE), 每个节点分配一块本地存储器空间。所有节点中的处理器都可以访问全部的物理存储器,但是访问本节点内的存储器所需要的时间,比访问某些远程节点内的存储器所花的时间要少得多。 + +### 配置Host-NUMA + +为提升虚拟机性能,在虚拟机启动前,用户可以通过虚拟机XML配置文件为虚拟机指定主机的NUMA节点,使虚拟机内存分配在指定的NUMA节点上。本特性一般与vCPU绑定一起使用,从而避免vCPU远端访问内存。 + +#### 操作步骤 + +- 查看host的NUMA拓扑结构: + + ```shell + $ numactl -H + available: 4 nodes (0-3) + node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + node 0 size: 31571 MB + node 0 free: 17095 MB + node 1 cpus: 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + node 1 size: 32190 MB + node 1 free: 28057 MB + node 2 cpus: 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 + node 2 size: 32190 MB + node 2 free: 10562 MB + node 3 cpus: 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 + node 3 size: 32188 MB + node 3 free: 272 MB + node distances: + node 0 1 2 3 + 0: 10 15 20 20 + 1: 15 10 20 20 + 2: 20 20 10 15 + 3: 20 20 15 10 + ``` + +- 在虚拟机XML配置文件中添加numatune字段,创建并启动虚拟机。例如使用主机上的NUMA node 0给虚拟机分配内存,配置参数如下: + + ```shell + + + + ``` + + 假设虚拟机的vCPU也绑定在NODE0的物理CPU上,就可以避免由于vCPU访问远端内存带来的性能下降。 + + > ![](./public_sys-resources/icon-note.gif) **说明:** + > + > - 分配给虚拟机的内存不要超过该NUMA节点剩余的可用内存,否则可能导致虚拟机启动失败。 + > - 建议虚拟机内存和vCPU都绑定在同一NUMA节点,避免vCPU访问远端内存造成性能下降。例如将上例中vCPU也绑定在NUMA node 0上。 + +### 配置Guest-NUMA + +虚拟机中运行的很多业务软件都针对NUMA架构进行了性能优化,尤其是对于大规格虚拟机,这种优化的作用更明显。openEuler提供了Guest NUMA特性,在虚拟机内部呈现出NUMA拓扑结构。用户可以通过识别这个结构,对业务软件的性能进行优化,从而保证业务更好的运行。 + +配置Guest NUMA时可以指定vNode的内存在HOST上的分配位置,实现内存的分块绑定,同时配合vCPU绑定,使vNode上的vCPU和内存在同一个物理NUMA node上。 + +#### 操作步骤 + +在虚拟机的XML配置文件中,配置了Guest NUMA后,就可以在虚拟机内部查看NUMA拓扑结构。``项是Guest NUMA的必配项。 + +```shell + + + + + + + + + + + + + + + + + + + + [...] + + + + + + + +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> - 项提供虚拟机内部呈现NUMA拓扑功能,“cell id”表示vNode编号,“cpus”表示vCPU编号,“memory”表示对应vNode上的内存大小。 +> - 如果希望通过Guest NUMA提供更好的性能,则需要配置,使vCPU和对应的内存分布在同一个物理NUMA NODE上: +> - 中的“cellid”和中的“cell id”是对应的;“mode”可以配置为“strict”(严格从指定node上申请内存,内存不够则失败)、“preferred”(优先从某一node上申请内存,如果不够则从其他node上申请)、“interleave”(从指定的node上交叉申请内存);“nodeset”表示指定物理NUMA NODE。 +> - 中需要将同一cell id中的vCPU绑定到与memnode相同的物理NUMA NODE上。 + +### 内存热插 + +#### 概述 + +在虚拟化场景下,虚拟机的内存、CPU、外部设备都是软件模拟呈现的,因此可以在虚拟化底层为虚拟机提供内存在线调整的能力。当前openEuler版本支持在线给虚拟机添加内存,当虚拟机出现物理内存不足又无法关闭虚拟机的时候,可以使用此特性增加虚拟机的物理内存资源。 + +#### 约束限制 + +- 创建虚拟机的时候,AArch64平台上指定的主板类型(machine)需为virt-4.1或更高virt以上,x86平台上指定的主板类型需要为pc-i440fx-1.5以上版本。 +- 内存热插特性依赖于Guest NUMA,虚拟机必须配置Guest NUMA,否则无法完成内存热插流程。 +- 热插内存时候必须指定新增内存所属的Gust NUMA node编号,否则内存热插失败。 +- 虚拟机内核必须支持内存热插能力,否则虚拟机无法识别新增内存或者无法上线内存。 +- 配置使用大页的虚拟机,热插内存的容量必须是系统hugepagesz的整数倍,否则会导致热插失败。 +- 热插内存的大小必须为Guest物理内存块大小block_size_bytes的整数倍,否则无法正常上线。在Guest内部执行lsmem可以获取block_size_bytes大小。 +- 配置n个virtio-net网卡后,最大可热插次数取值为min{max_slot, 64 - n},因为要给网卡预留slot。 +- vhost-user设备和内存热插特性互斥。配置了vhost-user设备的虚拟机不支持内存热插;内存热插后,不支持虚拟机热插vhost-user设备。 +- 如果虚拟机操作系统为Linux系列,请确保初始内存大于等于4GB。 +- 如果虚拟机操作系统为Windows类型,第一次热插内存必须指定到Guest NUMA node0上,否则热插内存无法被虚拟机识别。 +- 在直通场景下,由于需要预先分配内存,因此启动和热插内存都比普通虚拟机要慢(尤其是大规格虚拟机),属于正常现象。 +- 建议虚拟机可用内存与热插内存的比例至少为1:32,即热插32G内存虚拟机至少需要有1G可用内存,如果低于该比例可能会导致虚拟机卡死。 +- 热插内存是否自动上线取决于虚拟机操作系统自身逻辑,可以手动上线或者配置udev规则自动上线。 + +#### 操作步骤 + +**一、配置虚拟机XML** + +1. 使用内存热插功能,需要在创建虚拟机时配置可热插内存的最大范围、预留槽位号,并配置Guest NUMA拓扑结构。 + + 例如,为虚拟机配置32GiB初始内存,预留256个槽位号,最大支持1TiB内存上限,2个NUMA node的配置为: + + ```shell + + 32 + 1024 + + + + + + + + .... + ``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 其中: +> maxMemory字段中slots号表示预留的内存插槽,最大取值为256。 +> maxMemory表示虚拟机支持的最大物理内存上限。 +> Guest NUMA配置请参见“配置Guest NUMA”相关章节。 + +**二、热插并上线内存** + +1. 如果热插内存后需要自动上线热插的内存,可以使用root权限在虚拟机内部创建udev rules文件/etc/udev/rules.d/99-hotplug-memory.rules,并在其中定义udev规则,内容参考如下: + + ```shell + # automatically online hot-plugged memory + ACTION=="add", SUBSYSTEM=="memory", ATTR{state}="online" + ``` + +2. 根据需要热插的内存大小和虚拟机Guest NUMA Node创建内存描述xml文件。 + + 例如,热插1GiB内存到NUMA node0上: + + ```shell + + + 1024 + 0 + + + ``` + +3. 使用virsh attach-device命令为虚拟机热插内存。其中openEulerVM为虚拟机名称,memory.xml为热插内存的描述文件,--live表示热插内存在线生效,也可以使用--config 将热插内存持久化到虚拟机xml文件中。 + + ```bash + # virsh attach-device openEulerVM memory.xml --live + ``` + + 如果没有使用udev rules自动上线热插内存,也可以使用root权限,参考如下命令手动上线: + + ```shell + for i in `grep -l offline /sys/devices/system/memory/memory*/state` + do + echo online > $i + done + ``` diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/tool-guide.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/tool-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..1260d88fcd6593e04b4fc99d460b8b72d72ed9de --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/tool-guide.md @@ -0,0 +1,3 @@ +# 工具使用指南 + +为了方便用户更好地使用虚拟化,openEuler 提供了一系列工具,包括 vmtop、LibcarePlus 等。本章介绍这些工具的安装和使用指导。 diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/virtualization-installation.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/virtualization-installation.md new file mode 100644 index 0000000000000000000000000000000000000000..786095a8401ff5a90bf9578f8b8cde43925cc8bc --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/virtualization-installation.md @@ -0,0 +1,144 @@ +# 安装虚拟化组件 + +本章介绍在openEuler中安装虚拟化组件的方法。 + +## 最低硬件要求 + +在openEuler系统中安装虚拟化组件,最低硬件要求: + +- AArch64处理器架构:ARMv8以上并且支持虚拟化扩展 +- x86\_64处理器架构:支持VT-x +- 2核CPU +- 4GB的内存 +- 16GB可用磁盘空间 + +## 安装虚拟化核心组件 + +### 安装方法 + +#### 前提条件 + +- 已经配置yum源。配置方式请参见《openEuler 21.03 管理员指南》。 +- 安装操作需要root用户权限。 + +#### 安装步骤 + +1. 安装QEMU组件。 + + ``` shell + # yum install -y qemu + ``` + + > ![](./public_sys-resources/icon-caution.gif) **注意:** + > + > QEMU组件默认以用户qemu和用户组qemu运行,如果您不了解Linux用户组、用户的权限管理,后续创建和启动虚拟机时可能会遇到权限不足问题,以下有两种解决方法: + > 第一种方法:修改QEMU配置文件。使用以下命令打开QEMU配置文件,`sudo vim /etc/libvirt/qemu.conf`,找到以下两个字段,`user = "root"`和`group = "root"`,取消注释(即删除前面的`#`号),保存并退出。 + > 第二种方法:修改虚拟机文件的所有者。首先需要保证用户qemu拥有访问存放虚拟机文件的文件夹权限,使用以下命令修改文件的所有者,`sudo chown qemu:qemu xxx.qcow2`,修改所有需要读写的虚拟机文件即可。 + +2. 安装libvirt组件。 + + ``` shell + # yum install -y libvirt + ``` + +3. 启动libvirtd服务。 + + ``` shell + # systemctl start libvirtd + ``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> KVM模块已经集成在openEuler内核中,因此不需要单独安装。 + +### 验证安装是否成功 + +1. 查看内核是否支持KVM虚拟化,即查看/dev/kvm和/sys/module/kvm文件是否存在,命令和回显如下: + + ``` shell + $ ls /dev/kvm + /dev/kvm + ``` + + ``` shell + $ ls /sys/module/kvm + parameters uevent + ``` + + 若上述文件存在,说明内核支持KVM虚拟化。若上述文件不存在,则说明系统内核编译时未开启KVM虚拟化,需要更换支持KVM虚拟化的Linux内核。 + +2. 确认QEMU是否安装成功。若安装成功则可以看到QEMU软件包信息,命令和回显如下: + + ``` shell + $ rpm -qi qemu + Name : qemu + Epoch : 2 + Version : 4.0.1 + Release : 10 + Architecture: aarch64 + Install Date: Wed 24 Jul 2019 04:04:47 PM CST + Group : Unspecified + Size : 16869484 + License : GPLv2 and BSD and MIT and CC-BY + Signature : (none) + Source RPM : qemu-4.0.0-1.src.rpm + Build Date : Wed 24 Jul 2019 04:03:52 PM CST + Build Host : localhost + Relocations : (not relocatable) + URL : http://www.qemu.org + Summary : QEMU is a generic and open source machine emulator and virtualizer + Description : + QEMU is a generic and open source processor emulator which achieves a good + emulation speed by using dynamic translation. QEMU has two operating modes: + + * Full system emulation. In this mode, QEMU emulates a full system (for + example a PC), including a processor and various peripherals. It can be + used to launch different Operating Systems without rebooting the PC or + to debug system code. + * User mode emulation. In this mode, QEMU can launch Linux processes compiled + for one CPU on another CPU. + + As QEMU requires no host kernel patches to run, it is safe and easy to use. + ``` + +3. 确认libvirt是否安装成功。若安装成功则可以看到libvirt软件包信息,命令和回显如下: + + ``` shell + $ rpm -qi libvirt + Name : libvirt + Version : 5.5.0 + Release : 1 + Architecture: aarch64 + Install Date: Tue 30 Jul 2019 04:56:21 PM CST + Group : Unspecified + Size : 0 + License : LGPLv2+ + Signature : (none) + Source RPM : libvirt-5.5.0-1.src.rpm + Build Date : Mon 29 Jul 2019 08:14:57 PM CST + Build Host : 71e8c1ce149f + Relocations : (not relocatable) + URL : https://libvirt.org/ + Summary : Library providing a simple virtualization API + Description : + Libvirt is a C toolkit to interact with the virtualization capabilities + of recent versions of Linux (and other OSes). The main package includes + the libvirtd server exporting the virtualization support. + ``` + +4. 查看libvirt服务是否启动成功。若服务处于“Active”状态,说明服务启动成功,可以正常使用libvirt提供的virsh命令行工具,命令和回显如下: + + ``` shell + $ systemctl status libvirtd + ● libvirtd.service - Virtualization daemon + Loaded: loaded (/usr/lib/systemd/system/libvirtd.service; enabled; vendor preset: enabled) + Active: active (running) since Tue 2019-08-06 09:36:01 CST; 5h 12min ago + Docs: man:libvirtd(8) + https://libvirt.org + Main PID: 40754 (libvirtd) + Tasks: 20 (limit: 32768) + Memory: 198.6M + CGroup: /system.slice/libvirtd.service + ─40754 /usr/sbin/libvirtd + + ``` diff --git a/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/vm-configuration.md b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/vm-configuration.md new file mode 100644 index 0000000000000000000000000000000000000000..7bbef241fcd608315db5807f17cd8bee7f4d849e --- /dev/null +++ b/docs/en/25.03/Virtualization/VirtualizationPlatform/Virtualization/vm-configuration.md @@ -0,0 +1,883 @@ +# 虚拟机配置 + +## 总体介绍 + +### 概述 + +Libvirt工具采用XML格式的文件描述一个虚拟机特征,包括虚拟机名称、CPU、内存、磁盘、网卡、鼠标、键盘等信息。用户可以通过修改配置文件,对虚拟机进行管理。本章介绍XML配置文件各个元素的含义,指导用户完成虚拟机配置。 + +#### 基本格式 + +虚拟机XML配置文件以domain为根元素,domain根元素中包含多个其他元素。XML配置文件中的部分元素可以包含对应属性和属性值,用以详细地描述虚拟机信息,同一元素的不同属性使用空格分开。 + +XML配置文件的基本格式如下,其中label代表具体标签名,attribute代表属性,value代表属性值,需要根据实际情况修改。 + +```xml + + VMName + 8 + 4 + + + + + +``` + +#### 配置流程 + +1. 创建一个根元素为domain的XML配置文件。 +2. 使用标签name,根据命名规则指定唯一的虚拟机名称。 +3. 配置虚拟CPU和虚拟内存等系统资源。 +4. 配置虚拟设备。 + 1. 配置存储设备。 + 2. 配置网络设备。 + 3. 配置外部总线结构。 + 4. 配置鼠标等外部设备。 + +5. 保存XML配置文件。 + +## 虚拟机描述 + +### 概述 + +本节介绍虚拟机domain根元素和虚拟机名称的配置。 + +### 元素介绍 + +- domain:虚拟机XML配置文件的根元素,用于配置运行此虚拟机的hypervisor的类型。 + + 属性type:虚拟化中domain的类型。openEuler虚拟化中属性值为kvm。 + +- name:虚拟机名称。 + + 虚拟机名称为一个字符串,同一个主机上的虚拟机名称不能重复,虚拟机名称必须由数字、字母、“\_”、“-”、“:”组成,但不支持全数字的字符串,且虚拟机名称不超过64个字符。 + +### 配置示例 + +例如,虚拟机名称为openEuler的配置如下: + +```xml + + openEuler + ... + +``` + +## 虚拟CPU和虚拟内存 + +### 概述 + +本节介绍虚拟CPU和虚拟内存的常用配置。 + +### 元素介绍 + +- vcpu:虚拟处理器的个数。 +- memory:虚拟内存的大小。 + + 属性unit:指定内存单位,属性值支持KiB(210 字节),MiB(220 字节),GiB(230 字节),TiB(240 字节)等。 + +- cpu:虚拟处理器模式。 + + 属性mode:表示虚拟CPU的模式。 + + - host-passthrough:表示虚拟CPU的架构和特性与主机保持一致。 + + - custom:表示虚拟CPU的架构和特性由此cpu元素控制。 + + 子元素topology:元素cpu的子元素,用于描述虚拟CPU模式的拓扑结构。 + + - 子元素topology的属性socket、cores、threads分别描述了虚拟机具有多少个cpu socket,每个cpu socket中包含多少个处理核心(core),每个处理器核心具有多少个超线程(threads),属性值为正整数且三者的乘积等于虚拟CPU的个数。 + - ARM架构支持虚拟超线程, 虚拟CPU热插与虚拟超线程功能互斥。 + + 子元素model:元素cpu的子元素,当mode为custom时用于描述CPU的模型。 + + 子元素feature:元素cpu的子元素,当mode为custom时用于描述某一特性的使能情况。其中,属性name表示特性的名称,属性policy表示这一特性的使能控制策略: + + - force:表示强制使能该特性,无论主机CPU是否支持该特性。 + + - require:表示使能该特性,当主机CPU不支持该特性并且hypervisor不支持模拟该特性时,创建虚拟机失败。 + + - optional:表示该特性的使能情况与主机上该特性的使能情况保持一致。 + + - disable:禁用该特性。 + + - forbid:禁用该特性,当主机支持该特性时创建虚拟机失败。 + +### 配置示例 + +例如,虚拟CPU个数为4,处理模式为host-passthrough,虚拟内存为8GiB,4个CPU分布在两个CPU socket中,且不支持超线程的配置如下: + +```xml + + ... + 4 + 8 + + + +... + +``` + +虚拟内存为8GiB,虚拟CPU个数为4,处理模式为custom,model为Kunpeng-920,且禁用pmull特性的配置如下: + +```xml + + ... + 4 + 8 + + Kunpeng-920 + + + ... + +``` + +## 配置虚拟设备 + +虚拟机XML配置文件使用devices元素配置虚拟设备,包括存储设备、网络设备、总线、鼠标等,本节介绍常用的虚拟设备如何配置。 + +### 存储设备 + +#### 概述 + +XML配置文件可以配置虚拟存储设备信息,包括软盘、磁盘、光盘等存储介质及其存储类型等信息,本节介绍存储设备的配置方法。 + +#### 元素介绍 + +XML配置文件使用disk元素配置存储设备,disk常见的属性如[表1](#table14200183410353)所示,常见子元素及子元素属性如[表2](#table4866134925114)所示。 + +**表 1** 元素disk的常用属性 + + + + + + + + + + + + + + + + + + +

元素

+

属性

+

含义

+

属性值及其含义

+

disk

+

type

+

指定后端存储介质类型。

+

block:块设备

+

file:文件设备

+

dir:目录路径

+

network:网络磁盘

+

device

+

指定呈现给虚拟机的存储介质。

+

disk:磁盘(默认)

+

floppy:软盘

+

cdrom:光盘

+
+ +**表 2** 元素disk的常用子元素及属性说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

子元素

+

子元素含义

+

属性说明

+

source

+

指定后端存储介质,与disk元素的属性“type”指定类型相对应。

+

· file:对应file类型,值为对应文件的完全限定路径。

+

· dev:对应block类型,值为对应主机设备的完全限定路径。

+

· dir:对应dir类型,值为用作磁盘目录的完全限定路径。

+

· protocol:使用的协议。

+

· name: rbd磁盘名称,格式为:$pool/$volume。

+

· host name:mon地址。

+

· port:mon地址的端口。

+ +

driver

+

指定后端驱动的详细信息。

+

· type:磁盘格式的类型,常用的有“raw”和“qcow2”,需要与source的格式一致。

+

· io:磁盘IO模式,支持“native”和“threads”选项。

+

· cache:磁盘的cache模式,可选项有“none”、“writethrough”、“writeback”、“directsync”等。

+

· iothread:指定为磁盘分配的IO线程。

+

· error_policy:IO写错误发生时的处理策略,可选项有“stop”、“report”、“ignore”、“enospace"、"retry"等。

+

· rerror_policy:IO读错误发生时的处理策略,可选项有“stop”、“report”、“ignore”、“enospac”、“retry"等。

+

· retry_interval:IO错误重试间隔,范围为0-MAX_INT,单位为毫秒,仅error_policy=“retry”或rerror_policy=“retry”时可配置。

+

· retry_timeout:IO错误重试超时时间,范围为0-MAX_INT,单位为毫秒,仅error_policy=“retry”或rerror_policy=“retry”时可配置。

+

target

+

指磁盘呈现给虚拟机的总线和设备。

+

· dev:指定磁盘的逻辑设备名称,如SCSI、SATA、USB类型总线常用命令习惯为sd[a-p],IDE类型设备磁盘常用命名习惯为hd[a-d]。

+

· bus:指定磁盘设备的类型,常见的有“scsi”、“usb”、“sata”、“virtio”等类型。

+

boot

+

表示此磁盘可以作为启动盘使用。

+

· order:指定磁盘的启动顺序。

+

readonly

+

表示磁盘具有只读属性,磁盘内容不可以被虚拟机修改,通常与光驱结合使用。

+

-

+
+ +#### 配置示例 + +按照“准备虚拟机镜像”操作完成虚拟机镜像准备后,可以使用如下XML配置文件示例,为虚拟机配置虚拟磁盘。 + +例如,该示例为虚拟机配置了两个IO线程,一个块磁盘设备,一个光盘设备和一个rbd磁盘,第一个IO线程分配给块磁盘设备使用。该块磁盘设备的后端介质为qcow2格式,且被作为优先启动盘。 +在使用rbd磁盘前请确保已经安装qemu-block-rbd驱动,如未安装,请在root下使用如下命令进行安装: + +```bash +# yum install qemu-block-rbd +``` + +配置实例: + +```xml + + ... + 2 + + + + + + + + + + + + + + + + + + + + + + ... + + +``` + +### 网络设备 + +#### 概述 + +XML配置文件可以配置虚拟网络设备,包括ethernet模式、bridge模式、vhostuser模式等,本节介绍虚拟网卡设备的配置方法。 + +#### 元素介绍 + +XML配置文件中使用元素“interface”,其属性“type”表示虚拟网卡的模式,可选的值有“ethernet”、“bridge”、“vhostuser”等,下面以“bridge”模式虚拟网卡为例介绍其子元素以及对应的属性。 + +**表 3** bridge模式虚拟网卡常用子元素 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

子元素

+

子元素含义

+

属性及含义

+

mac

+

虚拟网卡的mac地址

+

address:指定mac地址,若不配置,会自动生成。

+

target

+

后端虚拟网卡名

+

dev:创建的后端tap设备的名称。

+

source

+

指定虚拟网卡后端

+

bridge:与bridge模式联合使用,值为网桥名称。

+

boot

+

表示此网卡可以作为远程启动

+

order:指定网卡的启动顺序。

+

model

+

表示虚拟网卡的类型

+

type:bridge模式网卡通常使用virtio。

+

virtualport

+

端口类型

+

type:若使用OVS网桥,需要配置为openvswitch。

+

driver

+

后端驱动类型

+

name:驱动名称,通常取值为vhost。

+

queues:网卡设备队列数。

+
+ +#### 配置示例 + +- 按照“准备虚拟机网络”创建了Linux网桥br0后,配置一个桥接在br0网桥上的virtio类型的虚拟网卡设备,对应的XML配置如下: + + ```xml + + ... + + + + + + ... + + + ``` + +- 如果按照“准备虚拟机网络”创建了OVS网桥,配置一个后端使用vhost驱动,且具有四个队列的virtio虚拟网卡设备。 + + ```xml + + ... + + + + + + + + ... + + + ``` + +### 总线配置 + +#### 概述 + +总线是计算机各个部件之间进行信息通信的通道。外部设备需要挂载到对应的总线上,每个设备都会被分配一个唯一地址(由子元素address指定),通过总线网络完成与其他设备或中央处理器的信息交换。常见的设备总线有ISA总线、PCI总线、USB总线、SCSI总线、PCIe总线。 + +PCIe总线是一种典型的树结构,具有比较好的扩展性,总线之间通过控制器关联,这里以PCIe总线为例介绍如何为虚拟机配置总线拓扑。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 总线的配置相对比较繁琐,若不需要精确控制设备拓扑结构,可以使用libvirt自动生成的缺省总线配置。 + +#### 元素介绍 + +在libvirt的XML配置中,每个控制器元素(使用controller元素表示)可以表示一个总线,根据虚拟机架构的不同,一个控制器上通常可以挂载一个或多个控制器或设备。这里介绍常用属性和子元素。 + +controller:控制器元素,表示一个总线。 + +- 属性type:控制器必选属性,表示总线类型。常用取值有“pci”、“usb”、“scsi”、“virtio-serial”、“fdc”、“ccid”。 +- 属性index:控制器必选属性,表示控制器的总线“bus”编号(编号从0开始),可以在地址元素“address”元素中使用。 +- 属性model:控制器必选属性,表示控制器的具体型号,其可选择的值与控制器类型“type”的值相关,对应关系及含义请参见[表4](#table191911761111)。 +- 子元素address:为设备或控制器指定其在总线网络中的挂载位置。 + - 属性type:设备地址类型。常用取值有“pci”、“usb”、“drive”。address的type类型不同, 对应的属性也不同,常用type属性值及其该取值下address的属性请参见[表5](#table1200165711314)。 + +- 子元素model:控制器具体型号的名称。 + - 属性name:指定控制器具体型号的名称,和父元素controller中的属性model对应。 + +**表 4** controller属性type常用取值和model取值对应关系 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

type属性值

+

model属性值

+

简介

+

pci

+

pcie-root

+

PCIe根节点,可挂载PCIe设备或控制器

+

pcie-root-port

+

只有一个slot,可以挂载PCIe设备或控制器

+

pcie-to-pci-bridge

+

PCIe转PCI桥控制器,可挂载PCI设备

+

usb

+

ehci

+

USB 2.0控制器,可挂载USB 2.0设备

+

nec-xhci

+

USB 3.0控制器,可挂载USB 3.0设备

+

scsi

+

virtio-scsi

+

virtio类型SCSI控制器,可以挂载块设备,如磁盘,光盘等

+

virtio-serial

+

virtio-serial

+

virtio类型串口控制器,可挂载串口设备,如pty串口

+
+ +**表 5** address元素不同设备类型下的属性说明 + + + + + + + + + + + + + + + + + + + + +

类型type属性值

+

含义

+

对应地址属性

+

pci

+

地址类型为PCI地址,表示该设备在PCI总线网络中的挂载位置。

+

domain:PCI设备的域号

+

bus:PCI设备的bus号

+

slot:PCI设备的device号

+

function:PCI设备的function号

+

multifunction:controller元素可选,是否开启multifunction功能

+

usb

+

地址类型为USB地址,表示该设备在USB总线中的位置。

+

bus:USB设备的bus号

+

port:USB设备的port号

+

drive

+

地址类型存储设备地址,表示所属的磁盘控制器,及其在总线中的位置。

+

controller:指定所属控制器号

+

bus:设备输出的channel号

+

target:存储设备target号

+

unit:存储设备lun号

+
+ +#### 配置示例 + +该示例给出一个PCIe总线的拓扑结构。PCIe根节点(BUS 0)下挂载了三个PCIe-Root-Port控制器。第一个PCIe-Root-Port控制器(BUS 1)开启了multifunction功能,并在其下挂载一个PCIe-to-PCI-bridge控制器,形成了一个PCI总线(BUS 3),该PCI总线上挂载了一个virtio-serial设备和一个USB 2.0控制器。第二个PCIe-Root-Port控制器(BUS 2)下挂载了一个SCSI控制器。第三个PCIe-Root-Port控制器(BUS 0)下无挂载设备。配置内容如下: + +```xml + + ... + + + +
+ + +
+ + + +
+ + +
+ + +
+ + +
+ + +
+ + ... + + +``` + +### 其他常用设备 + +#### 概述 + +除存储设备、网络设备外,XML配置文件中还需要指定一些其他外部设备,本节介绍这些元素的配置方法。 + +#### 元素介绍 + +- serial:串口设备 + + 属性type:用于指定串口类型。常用属性值为pty、tcp、pipe、file。 + +- video:媒体设备 + + 属性type:媒体设备类型。AArch64架构常用属性值为virtio,x86\_64架构通常使用属性值为vga或cirrus。 + + 子元素model:video的子元素,用于指定媒体设备类型。 + + 在model元素中,type属性为vga表示配置VGA类型显卡,vram属性代表显存大小,单位默认为KB。 + + 例如:给x86\_64架构虚拟机配置16MB的VGA类型的显卡,XML示例如下,其中vram属性代表显存大小,单位默认为KB: + + ```xml + + ``` + +- input:输出设备 + + 属性type:指定输出设备类型。常用属性值为tabe、keyboard,分别表示输出设备为写字板、键盘。 + + 属性bus:指定挂载的总线。常用属性值为USB。 + +- emulator:模拟器应用路径 +- graphics:图形设备 + + 属性type:指定图形设备类型。常用属性值为vnc。 + + 属性listen:指定侦听的IP地址。 + +#### 配置示例 + +例如,在下面的示例中,配置了虚拟机的模拟器路径,pty串口、virtio媒体设备、USB写字板、USB键盘以及VNC图形设备。 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> graphics的type配置为VNC时,建议配置属性passwd,即使用VNC登录时的密码。 + +```xml + + ... + + /usr/libexec/qemu-kvm + + + + + + ... + + +``` + +## 体系架构相关配置 + +### 概述 + +XML中还有一部分体系架构相关的配置,这部分配置包括主板,CPU,一些与体系架构相关的feature,本章节主要介绍它们的配置和含义。 + +### 元素介绍 + +- os:定义虚拟机启动参数。 + + 子元素type:指定虚拟机类型,属性arch表示架构类型,如aarch64,属性machine表示虚拟机的芯片组类型,虚拟机支持的芯片组可以通过 **qemu-kvm -machine ?** 命令查询,如AArch64结构使用“virt”类型。 + + 子元素loader:指定加载固件 ,如配置EDK提供的UEFI文件,属性readonly表示是否是只读文件,值为“yes”或“no”,属性type表示loader的类型,常用的值有“rom”、“pflash”。 + + 子元素nvram:指定nvram文件路径,用于存储UEFI启动配置。 + +- features:hypervisor支持控制一些虚拟机CPU/machine的特性,如高级电源管理接口“acpi”,ARM处理器指定GICv3中断控制器等。 + +### AArch64架构配置示例 + +虚拟机的类型为AArch64结构,使用virt芯片组,利用UEFI启动的虚拟机配置如下: + +```xml + + ... + + hvm + /usr/share/edk2/aarch64/QEMU_EFI-pflash.raw + /var/lib/libvirt/qemu/nvram/openEulerVM.fd + + ... + +``` + +为虚拟机配置ACPI和GIC V3中断控制器特性。 + +```xml + + + + +``` + +### x86\_64架构配置示例 + +x86\_64架构支持BIOS和UEFI两种启动方式,如果不配置loader,则使用默认启动方式BIOS。这里给出启动方式为UEFI、芯片组为q35的配置参考。 + +```xml + + ... + + hvm + /usr/share/edk2/ovmf/OVMF.fd + + ... + +``` + +## 其他常见配置项 + +### 概述 + +除系统资源和虚拟设备外,XML配置文件还需要配置一些其他元素,本节介绍这些元素的配置方法。 + +#### 元素介绍 + +- iothreads:指定iothread数量,可以用于加速存储设备性能。 + +- on\_poweroff:虚拟机关闭时采取的动作。 +- on\_reboot:虚拟机重启时采取的动作。 +- on\_crash:虚拟机崩溃时采取的动作。 +- clock:采用的时钟类型。 + + 属性offset:设置虚拟机时钟的同步类型,可选的值有“localtime”、“utc”、“timezone”、“variable”等。 + +#### 配置示例 + +为虚拟机配置两个iothread,用于加速存储设备性能。 + +```xml +2 +``` + +虚拟机关闭时,销毁虚拟机。 + +```xml +destroy +``` + +虚拟机重启时,重新启动虚拟机。 + +```xml +restart +``` + +虚拟机崩溃时,重新启动虚拟机。 + +```xml +restart +``` + +时钟采用“utc”的同步方式。 + +```xml + +``` + +## XML配置文件示例 + +### 概述 + +本节给出一个基本的AArch64虚拟机和一个x86\_64虚拟机的XML配置文件示例,供用户参考。 + +### 示例一 + +一个包含基本元素的AArch64架构虚拟机的XML配置文件,其内容示例如下: + +```xml + + openEulerVM + 8 + 4 + + hvm + /usr/share/edk2/aarch64/QEMU_EFI-pflash.raw + /var/lib/libvirt/qemu/nvram/openEulerVM.fd + + + + + + + + + 1 + + destroy + restart + restart + + /usr/libexec/qemu-kvm + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +#### 示例二 + +一个包含基本元素及总线元素x86\_64架构虚拟机的XML配置文件,其配置示例如下: + +```conf + + openEulerVM + 8388608 + 8388608 + 4 + 1 + + hvm + + + + + + + + + destroy + restart + restart + + /usr/libexec/qemu-kvm + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + + + + +