diff --git a/docs/.DS_Store b/docs/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a6b5050c1e32fb2e4407d9e43e82cda0cf906f81 Binary files /dev/null and b/docs/.DS_Store differ diff --git a/docs/en/.DS_Store b/docs/en/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..d1e9353dd3a4121bdee57a0f9095c40026508a5c Binary files /dev/null and b/docs/en/.DS_Store differ diff --git a/docs/zh/.DS_Store b/docs/zh/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ca03f18d0304260da20d5109a851064494eed432 Binary files /dev/null and b/docs/zh/.DS_Store differ diff --git a/docs/zh/cloud/.DS_Store b/docs/zh/cloud/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..51e6f471b80ef74e0dafe4f8c2ad42d0ab93923b Binary files /dev/null and b/docs/zh/cloud/.DS_Store differ diff --git a/docs/zh/cloud/_toc.yaml b/docs/zh/cloud/_toc.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8866d3def01887954fcb599179933f1a99038011 --- /dev/null +++ b/docs/zh/cloud/_toc.yaml @@ -0,0 +1,27 @@ +label: 云原生 +sections: + - label: 容器引擎 + sections: + - href: ./container_engine/isula_container_engine/_toc.yaml + - href: ./container_engine/docker_engine/_toc.yaml + - label: 容器形态 + sections: + - href: ./container_form/secure_container/_toc.yaml + - href: ./container_form/system_container/_toc.yaml + - label: 容器镜像构建工具 + sections: + - href: ./image_builder/isula_build/_toc.yaml + - label: 云原生操作系统 + sections: + - href: ./kubeos/kubeos/_toc.yaml + - label: 云底座操作系统 + sections: + - href: ./nestos/nestos/_toc.yaml + - label: 混合部署 + sections: + - href: ./hybrid_deployment/rubik/_toc.yaml + - href: ./hybrid_deployment/oncn_bwm/_toc.yaml + - label: 集群部署 + sections: + - href: ./cluster_deployment/kubernetes/_toc.yaml + - href: ./cluster_deployment/isulad+k8s/_toc.yaml diff --git a/docs/zh/cloud/cluster_deployment/isulad+k8s/_toc.yaml b/docs/zh/cloud/cluster_deployment/isulad+k8s/_toc.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a8afc8956b7d8a6b7d67eecf24ed5e97e4f9a226 --- /dev/null +++ b/docs/zh/cloud/cluster_deployment/isulad+k8s/_toc.yaml @@ -0,0 +1,12 @@ +label: iSulad+k8s集群部署指南 +isManual: true +description: 在openEuler环境,基于iSulad容器引擎搭建Kubernetes集群 +sections: + - label: 概述 + href: ./overview.md + - label: iSulad+k8s环境部署 + href: ./isulad+k8s_environment_deploy.md + - label: gitlab部署 + href: ./gitlab_deploy.md + - label: gitlab runner部署 + href: ./gitlab_runner_deploy.md diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/1.\346\237\245\347\234\213\351\234\200\350\246\201\351\225\234\345\203\217.png" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/1.\346\237\245\347\234\213\351\234\200\350\246\201\351\225\234\345\203\217.png" new file mode 100644 index 0000000000000000000000000000000000000000..74cdae5726cec83d5d74b0b8bd01694fd388e342 Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/1.\346\237\245\347\234\213\351\234\200\350\246\201\351\225\234\345\203\217.png" differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/10.\350\207\252\345\256\232\344\271\211\351\241\271\347\233\256\345\220\215\347\247\260.jpg" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/10.\350\207\252\345\256\232\344\271\211\351\241\271\347\233\256\345\220\215\347\247\260.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..2062c62a6aae63e9700f6ceedf73daea0876eb44 Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/10.\350\207\252\345\256\232\344\271\211\351\241\271\347\233\256\345\220\215\347\247\260.jpg" differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/11.\350\256\276\347\275\256-cicd-runner.png" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/11.\350\256\276\347\275\256-cicd-runner.png" new file mode 100644 index 0000000000000000000000000000000000000000..838cf1b6625439e44c7d09162fb71edbe1eaf3d3 Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/11.\350\256\276\347\275\256-cicd-runner.png" differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/12.\350\256\260\344\270\213runner\345\234\260\345\235\200\344\270\216\344\273\244\347\211\214.jpg" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/12.\350\256\260\344\270\213runner\345\234\260\345\235\200\344\270\216\344\273\244\347\211\214.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..d3aaaf9ff4b66e4b536bc0afaa33c121bc6b53f6 Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/12.\350\256\260\344\270\213runner\345\234\260\345\235\200\344\270\216\344\273\244\347\211\214.jpg" differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/13.\346\237\245\347\234\213\350\257\201\344\271\246\351\205\215\347\275\256\346\226\207\344\273\266.png" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/13.\346\237\245\347\234\213\350\257\201\344\271\246\351\205\215\347\275\256\346\226\207\344\273\266.png" new file mode 100644 index 0000000000000000000000000000000000000000..8e9ce44af5a01670add1b8b2f5a7223a8bd0f35d Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/13.\346\237\245\347\234\213\350\257\201\344\271\246\351\205\215\347\275\256\346\226\207\344\273\266.png" differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/14.\350\257\201\344\271\246\345\257\274\345\205\245\346\226\207\344\273\266.png" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/14.\350\257\201\344\271\246\345\257\274\345\205\245\346\226\207\344\273\266.png" new file mode 100644 index 0000000000000000000000000000000000000000..2a1fdb24d6f5c1c9d44cbce08276289adc5c876c Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/14.\350\257\201\344\271\246\345\257\274\345\205\245\346\226\207\344\273\266.png" differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/15.\346\263\250\345\206\214gitlab-runner.jpg" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/15.\346\263\250\345\206\214gitlab-runner.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..896f13bdc6411b719283f30d9973973950f27a1c Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/15.\346\263\250\345\206\214gitlab-runner.jpg" differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/16.web\347\253\257\345\267\262\345\212\240\345\205\245_LI.jpg" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/16.web\347\253\257\345\267\262\345\212\240\345\205\245_LI.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..fd8ae15ef7bce7120c7ba24b6240b33dbcf610b8 Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/16.web\347\253\257\345\267\262\345\212\240\345\205\245_LI.jpg" differ diff --git a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/17.png b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/17.png new file mode 100644 index 0000000000000000000000000000000000000000..86f90a67185f532b362f4710ce8f7615cf40c9e1 Binary files /dev/null and b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/17.png differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/18.dns\351\205\215\347\275\256.png" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/18.dns\351\205\215\347\275\256.png" new file mode 100644 index 0000000000000000000000000000000000000000..46b85396db34577b67679da759b6160ee707dec5 Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/18.dns\351\205\215\347\275\256.png" differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/19.CICD\347\225\214\351\235\242.png" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/19.CICD\347\225\214\351\235\242.png" new file mode 100644 index 0000000000000000000000000000000000000000..f8193e005253eb4a6bd036ec8afdf6566f9fd6d2 Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/19.CICD\347\225\214\351\235\242.png" differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/2.calico\351\205\215\347\275\256.png" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/2.calico\351\205\215\347\275\256.png" new file mode 100644 index 0000000000000000000000000000000000000000..d656f86d8ce5e110cf240a58e58b05b42aba8c15 Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/2.calico\351\205\215\347\275\256.png" differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/20.yaml\346\226\207\344\273\266.png" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/20.yaml\346\226\207\344\273\266.png" new file mode 100644 index 0000000000000000000000000000000000000000..9e7ec858abc2da72c7815a483f3011bf1225ec0f Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/20.yaml\346\226\207\344\273\266.png" differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/21.\346\265\201\346\260\264\347\272\277\347\212\266\346\200\201.png" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/21.\346\265\201\346\260\264\347\272\277\347\212\266\346\200\201.png" new file mode 100644 index 0000000000000000000000000000000000000000..fff7063f17fd203390302a6245a8ce4a16cf428e Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/21.\346\265\201\346\260\264\347\272\277\347\212\266\346\200\201.png" differ diff --git a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/3.png b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/3.png new file mode 100644 index 0000000000000000000000000000000000000000..7394b5f21821ce8d352c2f935c3ea3e490dc0519 Binary files /dev/null and b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/3.png differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/4.gitlab\347\275\221\351\241\265\345\205\245\345\217\243.jpg" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/4.gitlab\347\275\221\351\241\265\345\205\245\345\217\243.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..d3eb0d59d6dee5051470621a4969651668687789 Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/4.gitlab\347\275\221\351\241\265\345\205\245\345\217\243.jpg" differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/5.\346\237\245\350\257\242\345\257\206\347\240\201.jpg" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/5.\346\237\245\350\257\242\345\257\206\347\240\201.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..2e3902815108e9e91a07c382a4aae090b7cc6fe9 Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/5.\346\237\245\350\257\242\345\257\206\347\240\201.jpg" differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/6.\347\231\273\345\275\225\345\220\216\351\241\265\351\235\242.png" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/6.\347\231\273\345\275\225\345\220\216\351\241\265\351\235\242.png" new file mode 100644 index 0000000000000000000000000000000000000000..5f4d2c2a9a8bf337263028e859e49499155920b0 Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/6.\347\231\273\345\275\225\345\220\216\351\241\265\351\235\242.png" differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/7.\351\225\234\345\203\217.png" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/7.\351\225\234\345\203\217.png" new file mode 100644 index 0000000000000000000000000000000000000000..26c811ae616d2fe86e7b8b75c78ef88aff83616b Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/7.\351\225\234\345\203\217.png" differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/8.\346\226\260\345\273\272\351\241\271\347\233\256.png" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/8.\346\226\260\345\273\272\351\241\271\347\233\256.png" new file mode 100644 index 0000000000000000000000000000000000000000..0c56662e6bdedcc78dea32b6e2afada466193096 Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/8.\346\226\260\345\273\272\351\241\271\347\233\256.png" differ diff --git "a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/9.\345\210\233\345\273\272\347\251\272\347\231\275\351\241\271\347\233\256.png" "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/9.\345\210\233\345\273\272\347\251\272\347\231\275\351\241\271\347\233\256.png" new file mode 100644 index 0000000000000000000000000000000000000000..117da11ee289d88b51539e027606cc9da526936a Binary files /dev/null and "b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/9.\345\210\233\345\273\272\347\251\272\347\231\275\351\241\271\347\233\256.png" differ diff --git a/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/public_sys-resources/icon-note.gif b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/docs/zh/cloud/cluster_deployment/isulad+k8s/figures/public_sys-resources/icon-note.gif differ diff --git a/docs/zh/cloud/cluster_deployment/isulad+k8s/gitlab_deploy.md b/docs/zh/cloud/cluster_deployment/isulad+k8s/gitlab_deploy.md new file mode 100644 index 0000000000000000000000000000000000000000..b8727f7606f9f2f30b350665392a891e33141200 --- /dev/null +++ b/docs/zh/cloud/cluster_deployment/isulad+k8s/gitlab_deploy.md @@ -0,0 +1,314 @@ +# gitlab部署 + +## 文档说明 + +gitlab部署 是场景一(基于gitlab-ci从“0”开始构建欧拉原生开发CICD部署)所需步骤,场景二(欧拉原生开发执行机集群被gitlab-ci纳管)可跳过此步骤进入gitlab-runner部署。 + +## 准备服务器 + +需准备1台openEuler机器,建议在openEuler-22.03及以上版本运行。 + +## 启动gitlab + +将需要的yaml文件拷贝至/home目录,并启动对应的pod。 +> [!NOTE]说明 +> 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/zh/cloud/cluster_deployment/isulad+k8s/gitlab_runner_deploy.md b/docs/zh/cloud/cluster_deployment/isulad+k8s/gitlab_runner_deploy.md new file mode 100644 index 0000000000000000000000000000000000000000..b83f304da6dcb0bcedd897180a407d215d4a5519 --- /dev/null +++ b/docs/zh/cloud/cluster_deployment/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容器。 + + > [!NOTE]说明 + > + > 导入容器需查看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/zh/cloud/cluster_deployment/isulad+k8s/isulad+k8s_environment_deploy.md b/docs/zh/cloud/cluster_deployment/isulad+k8s/isulad+k8s_environment_deploy.md new file mode 100644 index 0000000000000000000000000000000000000000..475b8ab16bf07d3a759d39a195145d288ece4fd3 --- /dev/null +++ b/docs/zh/cloud/cluster_deployment/isulad+k8s/isulad+k8s_environment_deploy.md @@ -0,0 +1,386 @@ +# 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. 软件包下载地址: +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 < [!NOTE]说明 + > + > 以下所下载的镜像版本均为示例,具体版本号以上条命令返回结果为准,下同。 + + ```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。 + +## 安装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/zh/cloud/cluster_deployment/isulad+k8s/overview.md b/docs/zh/cloud/cluster_deployment/isulad+k8s/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..26e15fd33956852fe2ecb4f729dcdd6baedf8378 --- /dev/null +++ b/docs/zh/cloud/cluster_deployment/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 部署和测试。 + +> [!NOTE]说明 +> +> 本文档所有操作均使用root权限执行。 diff --git a/docs/zh/cloud/cluster_deployment/kubernetes/_toc.yaml b/docs/zh/cloud/cluster_deployment/kubernetes/_toc.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4f9cad1eef1a5e5b7dcecfcbca8192cf83a32808 --- /dev/null +++ b/docs/zh/cloud/cluster_deployment/kubernetes/_toc.yaml @@ -0,0 +1,34 @@ +label: Kubernetes集群部署指南 +isManual: true +description: 在openEuler环境,为搭建稳定高效Kubernetes集群提供基本的操作指引 +sections: + - label: 概述 + href: ./overview.md + - label: 准备虚拟机 + href: ./preparing_vms.md + - label: 手动部署集群 + href: ./deploying_a_kubernetes_cluster_manually.md + sections: + - 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 + sections: + - 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 + + diff --git a/docs/zh/cloud/cluster_deployment/kubernetes/deploying_a_kubernetes_cluster_manually.md b/docs/zh/cloud/cluster_deployment/kubernetes/deploying_a_kubernetes_cluster_manually.md new file mode 100644 index 0000000000000000000000000000000000000000..833e149dd1b395a4b288e728abec78fd67cfc1a5 --- /dev/null +++ b/docs/zh/cloud/cluster_deployment/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/zh/cloud/cluster_deployment/kubernetes/deploying_a_node_component.md b/docs/zh/cloud/cluster_deployment/kubernetes/deploying_a_node_component.md new file mode 100644 index 0000000000000000000000000000000000000000..2fdb807b7be3116f3ac71a075ce9e57b9b28d67a --- /dev/null +++ b/docs/zh/cloud/cluster_deployment/kubernetes/deploying_a_node_component.md @@ -0,0 +1,378 @@ +# 部署 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/zh/cloud/cluster_deployment/kubernetes/deploying_control_plane_components.md b/docs/zh/cloud/cluster_deployment/kubernetes/deploying_control_plane_components.md new file mode 100644 index 0000000000000000000000000000000000000000..9b07d047d93a573aa67add575b0fe4fbf20d784d --- /dev/null +++ b/docs/zh/cloud/cluster_deployment/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 < [!NOTE]说明 +> +> - 删除集群会删除整个集群的数据,且无法恢复,请谨慎操作。 +> - 当前,拆除集群不会清理容器和容器镜像,但若部署 Kubernetes 集群时,配置了需要安装容器引擎,则会清除容器引擎,这可能导致容器运行异常。 +> - 拆除集群过程中可能会打印一些错误信息,一般是由于清理过程中操作集群时反馈了错误的结果导致,集群仍然能够正常拆除 +> + +可以使用命令行方式删除整个集群。例如,删除 k8s-cluster 集群的参考命令如下: + +```shell +$ eggo -d cleanup --id k8s-cluster +``` diff --git a/docs/zh/cloud/cluster_deployment/kubernetes/eggo_tool_introduction.md b/docs/zh/cloud/cluster_deployment/kubernetes/eggo_tool_introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..7902450ee67b365b1733b80cab3bbcb1558fb2ab --- /dev/null +++ b/docs/zh/cloud/cluster_deployment/kubernetes/eggo_tool_introduction.md @@ -0,0 +1,429 @@ +# 工具介绍 + +本章介绍自动化部署工具的相关内容,建议用户在部署前阅读。 + +## 部署方式 + +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 机器场景下需要配置 + > [!NOTE]说明 + > + > 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 文件路径。不指定时,默认使用部署集群时缓存的集群配置。正常情况下,建议不配置该选项,仅异常情况下配置。 | + +> [!NOTE]说明 +> +> - 建议使用部署集群时缓存的集群配置删除集群,即正常情况下,不建议配置 --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/zh/cloud/cluster_deployment/kubernetes/figures/advertiseAddress.png b/docs/zh/cloud/cluster_deployment/kubernetes/figures/advertiseAddress.png new file mode 100644 index 0000000000000000000000000000000000000000..94e8913c6a87ea32adb7a28f60acaab50d77e4b4 Binary files /dev/null and b/docs/zh/cloud/cluster_deployment/kubernetes/figures/advertiseAddress.png differ diff --git a/docs/zh/cloud/cluster_deployment/kubernetes/figures/arch.png b/docs/zh/cloud/cluster_deployment/kubernetes/figures/arch.png new file mode 100644 index 0000000000000000000000000000000000000000..f616315bb1a94cac2dba2f7a94d25d8d759345d8 Binary files /dev/null and b/docs/zh/cloud/cluster_deployment/kubernetes/figures/arch.png differ diff --git a/docs/zh/cloud/cluster_deployment/kubernetes/figures/flannelConfig.png b/docs/zh/cloud/cluster_deployment/kubernetes/figures/flannelConfig.png new file mode 100644 index 0000000000000000000000000000000000000000..44bfdadfc570a93bc821fb3708a1403d8af5b1ce Binary files /dev/null and b/docs/zh/cloud/cluster_deployment/kubernetes/figures/flannelConfig.png differ diff --git a/docs/zh/cloud/cluster_deployment/kubernetes/figures/name.png b/docs/zh/cloud/cluster_deployment/kubernetes/figures/name.png new file mode 100644 index 0000000000000000000000000000000000000000..f9edd3b6d2759ce33f991404f4e91969cb141540 Binary files /dev/null and b/docs/zh/cloud/cluster_deployment/kubernetes/figures/name.png differ diff --git a/docs/zh/cloud/cluster_deployment/kubernetes/figures/podSubnet.png b/docs/zh/cloud/cluster_deployment/kubernetes/figures/podSubnet.png new file mode 100644 index 0000000000000000000000000000000000000000..1712801f53d1fc62d71b8d06fc0b0207e84b835e Binary files /dev/null and b/docs/zh/cloud/cluster_deployment/kubernetes/figures/podSubnet.png differ diff --git a/docs/zh/cloud/cluster_deployment/kubernetes/installing_etcd.md b/docs/zh/cloud/cluster_deployment/kubernetes/installing_etcd.md new file mode 100644 index 0000000000000000000000000000000000000000..375f9b87072bf03a867d006658ecd4be6e84ceca --- /dev/null +++ b/docs/zh/cloud/cluster_deployment/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/zh/cloud/cluster_deployment/kubernetes/installing_the_kubernetes_software_package.md b/docs/zh/cloud/cluster_deployment/kubernetes/installing_the_kubernetes_software_package.md new file mode 100644 index 0000000000000000000000000000000000000000..061b195e773397e7e3558fe908244a37bffe8fac --- /dev/null +++ b/docs/zh/cloud/cluster_deployment/kubernetes/installing_the_kubernetes_software_package.md @@ -0,0 +1,13 @@ +# 安装 Kubernetes 软件包 + +通过dnf安装k8s所需要的依赖工具包。 + +```bash +dnf install -y docker conntrack-tools socat +``` + +配置EPOL源之后,可以直接通过 dnf 安装 K8S。 + +```bash +dnf install kubernetes +``` diff --git a/docs/zh/cloud/cluster_deployment/kubernetes/overview.md b/docs/zh/cloud/cluster_deployment/kubernetes/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..8420bde6c3da261d47f476345b387147222f795b --- /dev/null +++ b/docs/zh/cloud/cluster_deployment/kubernetes/overview.md @@ -0,0 +1,12 @@ +# Kubernetes 集群部署指南 + +本文档介绍在 openEuler 操作系统上,通过二进制部署 K8S 集群的一个参考方法。 + +说明:本文所有操作均使用 `root`权限执行。 + +## 集群状态 + +本文所使用的集群状态如下: + +- 集群结构:6 个 openEuler 系统的虚拟机,3 个 master 和 3 个 node 节点 +- 物理机:openEuler 的 `x86/ARM`架构服务器 diff --git a/docs/zh/cloud/cluster_deployment/kubernetes/preparing_certificates.md b/docs/zh/cloud/cluster_deployment/kubernetes/preparing_certificates.md new file mode 100644 index 0000000000000000000000000000000000000000..fbd3c1607d35749161816318712a836d60b32253 --- /dev/null +++ b/docs/zh/cloud/cluster_deployment/kubernetes/preparing_certificates.md @@ -0,0 +1,412 @@ +# 准备证书 + +**声明:本文使用的证书为自签名,不能用于商用环境** + +部署集群前,需要生成集群各组件之间通信所需的证书。本文使用开源 CFSSL 作为验证部署工具,以便用户了解证书的配置和集群组件之间证书的关联关系。用户可以根据实际情况选择合适的工具,例如 OpenSSL 。 + +## 编译安装 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" < + 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/zh/cloud/cluster_deployment/kubernetes/running_the_test_pod.md b/docs/zh/cloud/cluster_deployment/kubernetes/running_the_test_pod.md new file mode 100644 index 0000000000000000000000000000000000000000..b8006ebb84fad354db79f4a191386ce339610fc7 --- /dev/null +++ b/docs/zh/cloud/cluster_deployment/kubernetes/running_the_test_pod.md @@ -0,0 +1,42 @@ +# 运行测试 pod + +## 配置文件 + +```bash +$ cat nginx.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment + labels: + app: nginx +spec: + replicas: 3 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 +``` + +## 启动 pod + +通过kubectl命令运行nginx.yaml文件。 + +```bash +$ kubectl apply -f nginx.yaml +deployment.apps/nginx-deployment created +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +nginx-deployment-66b6c48dd5-6rnwz 1/1 Running 0 33s +nginx-deployment-66b6c48dd5-9pq49 1/1 Running 0 33s +nginx-deployment-66b6c48dd5-lvmng 1/1 Running 0 34s +``` diff --git a/docs/zh/cloud/container_engine/docker_engine/_toc.yaml b/docs/zh/cloud/container_engine/docker_engine/_toc.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a6cb6f0f696397e11d14db28212129bfb0015c79 --- /dev/null +++ b/docs/zh/cloud/container_engine/docker_engine/_toc.yaml @@ -0,0 +1,24 @@ +label: Docker容器 +isManual: true +description: Docker是一个开源的容器引擎项目,用以实现应用的快速打包、部署和交付 +sections: + - 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 + sections: + - label: 容器引擎 + href: ./container_engine.md + - label: 容器管理 + href: ./container_management_2.md + - label: 镜像管理 + href: ./image_management_2.md + - label: 统计信息 + href: ./statistics.md + diff --git a/docs/zh/cloud/container_engine/docker_engine/command_reference.md b/docs/zh/cloud/container_engine/docker_engine/command_reference.md new file mode 100644 index 0000000000000000000000000000000000000000..35483fad78e18adb17749e55558fa74c0759769c --- /dev/null +++ b/docs/zh/cloud/container_engine/docker_engine/command_reference.md @@ -0,0 +1,3 @@ +# 命令行参考 + +本章介绍 Docker 容器相关的命令行。 diff --git a/docs/zh/cloud/container_engine/docker_engine/container_engine.md b/docs/zh/cloud/container_engine/docker_engine/container_engine.md new file mode 100644 index 0000000000000000000000000000000000000000..8dbd3be0109e097d00e01c624f992bf5896d33f3 --- /dev/null +++ b/docs/zh/cloud/container_engine/docker_engine/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/zh/cloud/container_engine/docker_engine/container_management_1.md b/docs/zh/cloud/container_engine/docker_engine/container_management_1.md new file mode 100644 index 0000000000000000000000000000000000000000..98c3c5a428b66d150f1efd3ace0bb2a94f711e5a --- /dev/null +++ b/docs/zh/cloud/container_engine/docker_engine/container_management_1.md @@ -0,0 +1,698 @@ +# 容器管理 + +## 创建容器 + +### 下载镜像 + +运行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": "" + }, + ...... +} +``` + +> [!NOTE]说明 +> +> - 容器内健康检查的状态信息最多保存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/zh/cloud/container_engine/docker_engine/container_management_2.md b/docs/zh/cloud/container_engine/docker_engine/container_management_2.md new file mode 100644 index 0000000000000000000000000000000000000000..20357d89e2a5bc0c891ff30e3149b0051f1672fa --- /dev/null +++ b/docs/zh/cloud/container_engine/docker_engine/container_management_2.md @@ -0,0 +1,1282 @@ +# 容器管理 + +# 总体说明 + +当前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 + +示例: + +```sh +$ 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 +```sh + +## commit + +用法:**docker commit \[OPTIONS\] CONTAINER \[REPOSITORY\[:TAG\]\]** + +功能:由一个容器创建一个新的image + +选项: + +-a, \--author="" 指定作者 + +-m, \--message="" 提交的信息 + +-p, \--pause=true 在提交过程中暂停容器 + +示例: + +运行一个容器,然后将这个容器提交成一个新的image + +```sh +$ 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目录中 + +```sh +$ 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命令启动。 + +```sh +$ sudo docker create -ti --name=busybox busybox /bin/bash +``` + +## diff + +用法:**docker diff CONTAINER** + +功能:检视容器的差异,相比于容器刚创建时做了哪些改变 + +选项:无 + +示例: + +```sh +$ sudo docker diff registry +C /root +A /root/.bash_history +A /test +``` + +## exec + +### 接口原型 + +```sh +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包中: + +```sh +$ 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. 返回一个容器的信息 + + ```sh + $ 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地址 + + ```sh + $ 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服务 + + ```sh + $ 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容器的日志信息 + + ```sh + $ 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容器 + + ```sh + $ sudo docker run -d --name pause_test -p 5000:5000 registry + ``` + + 此时可以用curl命令访问这个服务,请求状态码会返回200 OK。 + + ```sh + $ sudo curl -v 127.0.0.1:5000 + ``` + +2. 暂停这个容器内的进程 + + ```sh + $ sudo docker pause pause_test + ``` + + 此时用curl命令访问这个服务将阻塞,等待服务开启。 + +3. 恢复运行这个容器内的进程 + + ```sh + $ sudo docker unpause pause_test + ``` + + 此时步骤2中的curl访问将恢复运行,请求状态码返回200 OK。 + +## port + +用法:**docker port CONTAINER \[PRIVATE\_PORT\[/PROTO\]\]** + +功能:列出容器的端口映射,或者查找指定端口在主机的哪个端口 + +选项:无 + +示例: + +1. 列出容器所有的端口映射 + + ```sh + $ sudo docker port registry + 5000/tcp -> 0.0.0.0.:5000 + ``` + +2. 查找容器指定端口的映射 + + ```sh + $ 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. 列出正在运行的容器 + + ```sh + $ sudo docker ps + ``` + +2. 列出所有的容器 + + ```sh + $ sudo docker ps -a + ``` + +## rename + +用法:**docker rename OLD\_NAME NEW\_NAME** + +功能:重命名容器 + +示例: + +示例中,用docker run创建并启动一个容器,使用docker rename对容器重命名,并查看容器名是否改变。 + +```sh +$ 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秒。 + +示例: + +```sh +$ sudo docker restart busybox +``` + +>![NOTE]说明 +>容器在restart过程中,如果容器内存在D状态或Z状态的进程,可能会导致容器重启失败,这需要进一步分析导致容器内进程D状态或Z状态的原因,待容器内进程D状态或Z状态解除后,再进行容器restart操作。 + +## rm + +用法:**docker rm \[OPTIONS\] CONTAINER \[CONTAINER...\]** + +功能:删除一个或多个容器 + +选项: + +-f, \--force=false 强制删除运行中的容器 + +-l, \--link=false 删除指定的链接,而不是底层容器 + +-v, \--volumes=false 删除与容器关联的卷 + +示例: + +1. 删除一个停止运行的容器 + + ```sh + $ sudo docker rm test + ``` + +2. 删除一个正在运行的容器 + + ```sh + $ 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 + +```sh +$ 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选项,容器将在后台启动。 + +```sh +$ sudo docker start -i -a busybox +``` + +## stats + +用法:**docker stats \[OPTIONS\] \[CONTAINER...\]** + +功能:持续监控并显示指定容器(若不指定,则默认全部容器)的资源占用情况 + +选项: + +-a, \--all 显示所有容器(默认仅显示运行状态的容器) + +\--no-stream 只显示第一次的结果,不持续监控 + +示例: + +示例中,用docker run创建并启动一个容器,docker stats将输出容器的资源占用情况。 + +```sh +$ 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 + +示例: + +```sh +$ sudo docker stop -t=15 busybox +``` + +## top + +用法:**docker top CONTAINER \[ps OPTIONS\]** + +功能:显示一个容器内运行的进程 + +选项:无 + +示例: + +先运行了一个名为top\_test的容器,并在其中执行了top指令 + +```sh +$ 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。 + +```sh +$ sudo docker update --cpu-shares 512 --cpuset-cpus=0,3 --memory 512m ubuntu +``` + +## wait + +用法:**docker wait CONTAINER \[CONTAINER...\]** + +功能:等待一个容器停止,并打印出容器的退出码 + +选项:无 + +示例: + +先开启一个名为busybox的容器 + +```sh +$ sudo docker start -i -a busybox +``` + +执行docker wait + +```sh +$ sudo docker wait busybox +0 +``` + +将阻塞等待busybox容器的退出,退出busybox容器后将看到打印退出码“0”。 diff --git a/docs/zh/cloud/container_engine/docker_engine/image_management_1.md b/docs/zh/cloud/container_engine/docker_engine/image_management_1.md new file mode 100644 index 0000000000000000000000000000000000000000..3d686fc23c16f4db7201c3ac1a77c16e4f634b1d --- /dev/null +++ b/docs/zh/cloud/container_engine/docker_engine/image_management_1.md @@ -0,0 +1,57 @@ +# 镜像管理 + +## 创建镜像 + +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镜像失败。 + +## 查看镜像 + +查看本地镜像列表: + +```sh +docker images +``` + +## 删除镜像 + +删除镜像(image处为具体镜像名): + +```sh +docker rmi image +``` + +### 注意事项 + +禁止使用docker rmi -f XXX删除镜像。如果使用强制删除,docker rmi会忽略过程中的错误,可能导致容器或者镜像元数据残留。如果使用普通删除,如果删除过程出错,则会删除失败,不会导致元数据残留。 diff --git a/docs/zh/cloud/container_engine/docker_engine/image_management_2.md b/docs/zh/cloud/container_engine/docker_engine/image_management_2.md new file mode 100644 index 0000000000000000000000000000000000000000..419ca1afac9cb18af5315da487f6730c4612c391 --- /dev/null +++ b/docs/zh/cloud/container_engine/docker_engine/image_management_2.md @@ -0,0 +1,450 @@ +# 镜像管理 + +## 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 + +```txt +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 + + ```sh + $ sudo docker build -t busybox:latest + ``` + +2. 通过以下命令可以看到这个生成的image: + + ```sh + docker images | grep busybox + ``` + +## history + +用法:**docker history \[OPTIONS\] IMAGE** + +功能:显示一个image的变化历史 + +选项: + +-H, \--human=true + +\--no-trunc=false 不对输出进行删减 + +-q, \--quiet=false 只显示ID + +示例: + +```sh +$ 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 + +示例: + +```sh +$ 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 + +```sh +$ 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="" + +示例: + +```sh +$ 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时,默认登录到index.docker.io/v1/。 + +选项: + +-e, \--email="" Email + +-p, \--password="" 密码 + +-u, \--username="" 用户名 + +示例: + +```sh +$ sudo docker login +``` + +## logout + +用法:**docker logout \[SERVER\]** + +功能:从一个镜像服务器中登出,没有指定server时,默认登出index.docker.io/v1/。 + +选项:无 + +示例: + +```sh +$ 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镜像 + + ```sh + $ 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: + + ```sh + $ 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 + + ```sh + $ sudo docker tag ubuntu:sshd 192.168.1.110:5000/busybox:sshd + ``` + +3. 将打好标签的镜像推送到私有镜像库中 + + ```sh + $ sudo docker push 192.168.1.110:5000/busybox:sshd + ``` + + 推送的时候会自动检测所依赖的层在镜像库中是否已存在,如果以存在,跳过该层。 + +## rmi + +用法:**docker rmi \[OPTIONS\] IMAGE \[IMAGE...\]** + +功能:删除一个或多个镜像,如果一个镜像在镜像库中有多个标签,删除镜像的时候只是进行untag操作,当删除的是只有一个标签的镜像时,将依次删除所依赖的层。 + +选项: + +-f, \--force=false 强制删除image + +\--no-prune=false 不删除没有标签的父镜像 + +示例: + +```sh +$ sudo docker rmi 192.168.1.110:5000/busybox:sshd +``` + +## save + +用法:**docker save \[OPTIONS\] IMAGE \[IMAGE...\]** + +功能:保存一个image到一个tar包,输出默认是到STDOUT + +选项: + +-o, \--output="" 输出到文件中而不是STDOUT + +示例: + +```sh +$ 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 + + ```sh + $ 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,在私有镜像库中搜寻时要加上私有镜像库的地址 + + ```sh + $ sudo docker search 192.168.1.110:5000/busybox + ``` + +## tag + +用法:**docker tag \[OPTIONS\] IMAGE\[:TAG\] \[REGISTRYHOST/\]\[USERNAME/\]NAME\[:TAG\]** + +功能:将一个镜像打标签到一个库中 + +选项: + +-f, \--force=false 如果存在相同的tag名将强制替换原来的image + +示例: + +```sh +$ sudo docker tag busybox:latest busybox:test +``` diff --git a/docs/zh/cloud/container_engine/docker_engine/installation_and_configuration_3.md b/docs/zh/cloud/container_engine/docker_engine/installation_and_configuration_3.md new file mode 100644 index 0000000000000000000000000000000000000000..ef7014f547d67d5b95d8d82003d66f06d7fb5b63 --- /dev/null +++ b/docs/zh/cloud/container_engine/docker_engine/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等),可能会存在目录冲突,或文件属性变换,对应用的正常使用造成影响。 + +> [!TIP]须知 +> +> 用户指定的目录或文件应为docker专用,避免冲突导致的文件属性变化带来安全问题。 + +- 以--graph为例,当我们使用/new/path/作为daemon新的Root Dir时,如果/new/path/下已经存在文件,且目录或文件名与docker需要使用的目录或文件名冲突(例如: containers、hooks、tmp等目录)时,docker可能会更新原有目录或文件的属性,包括属主、权限等为自己的属主和权限。 + +> [!TIP]须知 +> +> 从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。 + +> [!TIP]须知 +> +> 如果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 +``` + +> [!NOTE]说明 +> +> -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中保存的元数据。 + + > [!NOTE]说明 + > + > 用户若选择采用手动清理恢复环境的方式,可通过配置环境变量“DISABLE\_CRASH\_FILES\_DELETE=true”屏蔽daemon掉电重启时db文件清理功能。 diff --git a/docs/zh/cloud/container_engine/docker_engine/overview.md b/docs/zh/cloud/container_engine/docker_engine/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..1165f0be4852b483e41f77e85a9b585e781ab213 --- /dev/null +++ b/docs/zh/cloud/container_engine/docker_engine/overview.md @@ -0,0 +1,6 @@ +# Docker容器 + +Docker是一个开源的Linux容器引擎项目, 用以实现应用的快速打包、部署和交付。Docker的英文本意是码头工人,码头工人的工作就是将商品打包到container\(集装箱\)并且搬运container、装载container。 对应到Linux中,Docker就是将app打包到container,通过container实现app在各种平台上的部署、运行。Docker通过Linux Container技术将app变成一个标准化的、可移植的、自管理的组件,从而实现应用的“一次构建,到处运行”。Docker技术特点就是:应用快速发布、部署简单、管理方便,应用密度更高。 + +>[!NOTE]说明 +>Docker容器的安装和使用需要root权限。 diff --git a/docs/zh/cloud/container_engine/docker_engine/statistics.md b/docs/zh/cloud/container_engine/docker_engine/statistics.md new file mode 100644 index 0000000000000000000000000000000000000000..d688f5d71f965a0b05ab2225f0845525c4c277e2 --- /dev/null +++ b/docs/zh/cloud/container_engine/docker_engine/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/zh/cloud/container_engine/isula_container_engine/_toc.yaml b/docs/zh/cloud/container_engine/isula_container_engine/_toc.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6470f036fe73c0d3606536c9f77a22f4480887aa --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/_toc.yaml @@ -0,0 +1,45 @@ +label: iSula容器引擎 +isManual: true +description: 在iSula是使用C/C++实现的容器引起,具有轻、灵、巧、快的特点 +sections: + +- label: 概述 + href: ./overview.md +- label: 安装、升级与卸载 + href: ./installation_upgrade_uninstallation.md + sections: + - label: 安装与配置 + href: ./installation_configuration.md + - label: 升级 + href: ./upgrade_methods.md + - label: 卸载 + href: ./uninstallation.md +- label: 使用指南 + href: ./application_scenarios.md + sections: + - 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接口 + href: ./cri.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: 附录 + href: ./appendix.md diff --git a/docs/zh/cloud/container_engine/isula_container_engine/appendix.md b/docs/zh/cloud/container_engine/isula_container_engine/appendix.md new file mode 100644 index 0000000000000000000000000000000000000000..86a2268af9021521e5496e72d69bbdc9cf76201c --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/appendix.md @@ -0,0 +1,881 @@ +# 附录 + +## 命令行参数说明 + +**表 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/zh/cloud/container_engine/isula_container_engine/application_scenarios.md b/docs/zh/cloud/container_engine/isula_container_engine/application_scenarios.md new file mode 100644 index 0000000000000000000000000000000000000000..93f2b26a314ab35ff6d2e65d15f8ca53b56cba3f --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/application_scenarios.md @@ -0,0 +1,6 @@ +# 使用指南 + +本章介绍iSula容器引擎的使用方法。 + +> !![NOTE]说明 +> iSulad的所有使用操作均需要使用root权限。 diff --git a/docs/zh/cloud/container_engine/isula_container_engine/checking_the_container_health_status.md b/docs/zh/cloud/container_engine/isula_container_engine/checking_the_container_health_status.md new file mode 100644 index 0000000000000000000000000000000000000000..c217b43f6bc904f826b46d12ee4b64e1f4fba1d0 --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/checking_the_container_health_status.md @@ -0,0 +1,61 @@ +# 容器健康状态检查 + +## 场景说明 + +在实际的生产环境中,开发者提供的应用程序或者平台提供的服务难免存在bug,因此,一套管理系统对运行的应用程序进行周期性的健康检查和修复就是不可或缺的。容器健康检查机制便添加了用户定义的对容器进行健康检查的功能。在容器创建时配置\--health-cmd选项,在容器内部周期性地执行命令,通过命令的返回值来监测容器的健康状态。 + +## 配置方法 + +在容器启动时的配置: + +```sh +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/zh/cloud/container_engine/isula_container_engine/container_management.md b/docs/zh/cloud/container_engine/isula_container_engine/container_management.md new file mode 100644 index 0000000000000000000000000000000000000000..c697a7fb4980c3ebfad8e720904e261173d9a186 --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/container_management.md @@ -0,0 +1,2472 @@ +# 容器管理 + +## 创建容器 + +### 描述 + +isula create 命令用于创建一个新的容器。容器引擎会使用指定的容器镜像创建容器读写层,或者使用指定的本地rootfs作为容器的运行环境。创建完成后,会将容器的ID输出到标准输出,后续可以使用isula start 命令启动该容器。新创建的容器状态为**inited**状态。 + +### 用法 + +```sh +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 + ] + } + ``` + +### 示例 + +创建一个新容器 + +```sh +# 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命令用于启动一个或多个容器。 + +### 用法 + +```sh +isula start [OPTIONS] CONTAINER [CONTAINER...] +``` + +### 参数 + +start命令支持参数参考下表。 + +**表 1** start命令参数列表 + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

start

+

-H, --host

+

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

+

-a, --attach

+

连接到容器的STDOUT和STDERR

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+
+ +### 示例 + +启动一个新容器 + +```sh +# isula start fd7376591a9c3d8ee9a14f5d2c2e5255b02cc44cddaabca82170efd4497510e1 +``` + +## 运行容器 + +### 描述 + +isula run命令命令用于创建一个新的容器。会使用指定的容器镜像创建容器读写层,并且为运行指定的命令做好准备。创建完成后,使用指定的命令启动该容器。run命令相当于create然后start容器。 + +### 用法 + +```sh +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的值作为命令行参数传给容器 + + ```sh + # echo ls | isula run -i busybox /bin/sh + + + ^C + # + ``` + + 上述命令出现客户端卡死现象,这是由于上述命令相当于往stdin输入ls,随后EOF被读取,客户端不再发送数据,等待服务端退出,但是服务端无法区分客户端是否需要继续发送数据,因而服务端卡在read数据上,最终导致双方均卡死。 + + 正确的执行方式为: + + ```sh + # 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

+
+ + >![WARNING]注意 + >第一种情况,先挂载/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选项会导致容器权限过大,影响宿主机配置。 + + >![WARNING]注意 + >- 高并发场景(并发启动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即可。 + +### 示例 + +运行一个新容器 + +```sh +# isula run -itd busybox +9c2c13b6c35f132f49fb7ffad24f9e673a07b7fe9918f97c0591f0d7014c713b +``` + +## 停止容器 + +### 描述 + +isula stop命令用于停止一个或多个运行中的容器。首先向容器中的首进程会发送**SIGTERM**信号,在指定时间(默认为10s)内容器未停止时,会发送**SIGKILL**。 + +### 用法 + +```sh +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一直卡住。 + +### 示例 + +停止一个容器 + +```sh +# isula stop fd7376591a9c3d8ee9a14f5d2c2e5255b02cc44cddaabca82170efd4497510e1 +fd7376591a9c3d8ee9a14f5d2c2e5255b02cc44cddaabca82170efd4497510e1 +``` + +## 强制停止容器 + +### 描述 + +isula kill命令用于强制停止一个或多个运行中的容器。 + +### 用法 + +```sh +isula kill [OPTIONS] CONTAINER [CONTAINER...] +``` + +### 参数 + +kill命令支持参数参考下表。 + +**表 1** kill命令参数列表 + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

kill

+

-H, --host

+

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

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+

-s, --signal

+

发送给容器的信号

+
+ +### 示例 + +杀掉一个容器 + +```sh +# isula kill fd7376591a9c3d8ee9a14f5d2c2e5255b02cc44cddaabca82170efd4497510e1 +fd7376591a9c3d8ee9a14f5d2c2e5255b02cc44cddaabca82170efd4497510e1 +``` + +## 删除容器 + +### 描述 + +isula rm命令用于删除一个或多个容器。 + +### 用法 + +```sh +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 \} 秒钟。 + +### 示例 + +删除一个停止状态的容器 + +```sh +# isula rm fd7376591a9c3d8ee9a14f5d2c2e5255b02cc44cddaabca82170efd4497510e1 +fd7376591a9c3d8ee9a14f5d2c2e5255b02cc44cddaabca82170efd4497510e1 +``` + +## 接入容器 + +### 描述 + +isula attach命令用于将当前终端的标准输入、标准输出和标准错误连接到正在运行的容器。 + +### 用法 + +```sh +isula attach [OPTIONS] CONTAINER +``` + +### 参数 + +attach命令支持参数参考下表。 + +**表 1** attach命令参数列表 + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

attach

+

--help

+

打印帮助信息

+

-H, --host

+

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

+

-D, --debug

+

开启debug模式

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

命令

+

参数

+

说明

+

rename

+

--help

+

打印帮助信息

+

-H, --host

+

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

+

-D, --debug

+

开启debug模式

+
+ +### 示例 + +重命名一个容器 + +```sh +# isula rename my_container my_new_container +``` + +## 在容器中执行新命令 + +### 描述 + +isula exec命令用于正在运行的容器中运行一个新命令。新执行的命令将在容器的默认目录中运行。如果基础镜像指定了自定义目录,则将使用该目录。 + +### 用法 + +```sh +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,导致终端卡死 + + ```markdown + 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(两行) + + ```sh + # 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 执行命令,在容器中执行管道操作。 + + ```sh + # isula exec -it container /bin/sh -c "ls /test | grep "xx" | wc -l" + 15 + # + ``` + +- 禁止使用echo的方式向exec命令的stdin输入数据,会导致客户端卡死。应该直接将echo的值作为命令行参数传给容器 + + ```sh + # echo ls | isula exec 38 /bin/sh + + + ^C + # + ``` + + 上述命令可能出现客户端卡死现象,这是由于上述命令相当于往stdin输入ls,随后EOF被读取,客户端不再发送数据,等待服务端退出,但是服务端无法区分客户端是否需要继续发送数据,因而服务端卡在read数据上,最终导致双方均卡死。 + + 正确的执行方式为: + + ```sh + # isula exec 38 ls + bin dev etc home proc root sys tmp usr var + ``` + +### 示例 + +在运行中的容器中,执行echo命令 + +```sh +# isula exec c75284634bee echo "hello,world" +hello,world +``` + +## 查询单个容器信息 + +### 描述 + +isula inspect提供了容器的详细信息。 + +### 用法 + +```sh +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查询容器信息会一直等待,直到获取容器信息成功后返回。

+
+ +### 示例 + +查询容器信息 + +```sh +# 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 用于查询所有容器的信息。 + +### 用法 + +```sh +isula ps [OPTIONS] +``` + +### 参数 + +ps命令支持参数参考下表。 + +**表 1** ps命令参数列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

ps

+

  

+

  

+

  

+

  

+

-a, --all

+

显示所有的容器

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+

-H, --host

+

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

+

-q, --quiet

+

只显示容器名字

+

-f, --filter

+

增加筛选过滤条件

+

--format

+

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

+

--no-trunc

+

不对容器ID进行截断打印

+
+ +### 示例 + +查询所有容器信息 + +```sh +# 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 用于重启一个或者多个容器。 + +### 用法 + +```sh +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一直卡住。 + +### 示例 + +重启单个容器 + +```sh +# isula restart c75284634beeede3ab86c828790b439d16b6ed8a537550456b1f94eb852c1c0a + c75284634beeede3ab86c828790b439d16b6ed8a537550456b1f94eb852c1c0a +``` + +## 等待容器退出 + +### 描述 + +isula wait用于等待一个或者多个容器退出。仅支持runtime类型为lcr的容器。 + +### 用法 + +```sh +isula wait [OPTIONS] CONTAINER [CONTAINER...] +``` + +### 参数 + +wait命令支持参数参考下表。 + +**表 1** wait命令参数列表 + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

wait

+

-H, --host

+

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

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

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

命令

+

参数

+

说明

+

top

+

  

+

-H, --host

+

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

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+
+ +### 示例 + +查询容器中进程信息 + +```sh +# 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用于实时显示资源使用的统计信息。 + +### 用法 + +```sh +isula stats [OPTIONS] [CONTAINER...] +``` + +### 参数 + +stats命令支持参数参考下表。 + +**表 1** stats命令参数列表 + + + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

stats

+

  

+

  

+

-H, --host

+

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

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+

-a, --all

+

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

+

--no-stream

+

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

+

--original

+

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

+
+ +### 示例 + +显示资源使用的统计信息 + +```sh +# 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用于获取容器的日志。 + +### 用法 + +```sh +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 关闭。 + +### 示例 + +获取容器日志 + +```sh +# isula logs 6a144695f5dae81e22700a8a78fac28b19f8bf40e8827568b3329c7d4f742406 +hello, world +hello, world +hello, world +``` + +## 容器与主机之间数据拷贝 + +### 描述 + +isula cp 用于容器与主机之间的数据拷贝,仅支持runtime类型为lcr的容器。 + +### 用法 + +```sh +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,所以对这些文件的拷贝使用的是镜像中的原始文件,而不是真实容器中的文件。 + + ```sh + # isula cp b330e9be717a:/etc/hostname /tmp/hostname + # cat /tmp/hostname + # + ``` + +- iSulad在解压文件时,不会对文件系统中即将被覆盖的文件或文件夹做类型判断,而是直接覆盖,所以在拷贝时,如果源为文件夹,同名的文件会被强制覆盖为文件夹;如果源为文件,同名的文件夹会被强制覆盖为文件。 + + ```sh + # 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目录下。 + +```sh +isula cp /test/host 21fac8bb9ea8:/test +``` + +将容器21fac8bb9ea8的/www目录拷贝到主机的/tmp目录中。 + +```sh +isula cp 21fac8bb9ea8:/www /tmp/ +``` + +## 暂停容器中所有的进程 + +### 描述 + +isula pause用于暂停一个或者多个容器中的所有进程。 + +### 用法 + +```sh +isula pause [OPTIONS] CONTAINER [CONTAINER...] +``` + +### 参数 + + + + + + + + + + + + + + + + + +

命令

+

参数

+

说明

+

pause

+

-H, --host

+

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

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

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

命令

+

参数

+

说明

+

pause

+

-H, --host

+

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

+

-D, --debug

+

开启调试模式

+

--help

+

打印帮助信息

+
+ +### 约束限制 + +- 只有状态为paused的容器可以被执行unpause操作 + +### 示例 + +恢复一个被暂停的容器,命令示例如下: + +```sh +# isula unpause 8fe25506fb5883b74c2457f453a960d1ae27a24ee45cdd78fb7426d2022a8bac + 8fe25506fb5883b74c2457f453a960d1ae27a24ee45cdd78fb7426d2022a8bac +``` + +## 从服务端实时获取事件消息 + +### 描述 + +isula events用于从服务端获取实时事件。 + +### 用法 + +```sh +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。 + +### 示例 + +从服务端实时获取事件消息,命令示例如下: + +```sh +# isula events +``` diff --git a/docs/zh/cloud/container_engine/isula_container_engine/container_resource_management.md b/docs/zh/cloud/container_engine/isula_container_engine/container_resource_management.md new file mode 100644 index 0000000000000000000000000000000000000000..a86c40a332d363535e8a0061b60ffdb1eb5e4aac --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/container_resource_management.md @@ -0,0 +1,741 @@ +# 容器资源管理 + +## 描述 + +可以通过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。 + +>![NOTE]说明 +>当使用与主机共享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: 即可,如: + +```sh +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 即可,如: + +```sh +isula run -tid --cpuset-cpus 0,2-3 busybox sh +``` + +>![NOTE]说明 +>是否设置成功,请参见“查询单个容器信息”章节。 + +## 限制运行时的内存 + +### 描述 + +可以通过参数限制容器的各项内存值上限。 + +### 用法 + +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 \[\]即可,如: + +```sh +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 每秒,则命令如下: + +```sh +isula run -tid --device-write /dev/sda:1mb busybox sh +``` + +限制写速度的命令如下: + +```sh +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中增加如下配置 + + ```sh + -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 + + ```sh + # 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\]?,在不带单位的时候默认单位是字节。 + +```sh +# 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=时都将报错。 + + ```sh + # 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启动失败。 + + ```sh + # 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'. + ``` + + 轻量级容器不报错,正常启动 + + ```sh + # 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存在,轻量级容器启动一样会报错。 + + ```sh + # 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相同。 + + >![NOTE]说明 + >切换数据盘时需要保证/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 即可,如: + +```sh +isula run -ti --files-limit 1024 busybox bash +``` + +### 约束 + +1. 使用--files-limit参数传入一个很小的值,如1,可能导致容器启动失败。 + + ```sh + # 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。 + + ```sh + # 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 即可,如: + +```sh +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 =\[:\]即可,如: + +```sh +isula create/run -tid --ulimit nofile=1024:2048 busybox sh +``` + +### 约束 + +不能在daemon.json和/etc/sysconfig/iSulad文件(或isulad命令行)中同时配置ulimit限制,否则isulad启动会报错。 diff --git a/docs/zh/cloud/container_engine/isula_container_engine/cri.md b/docs/zh/cloud/container_engine/isula_container_engine/cri.md new file mode 100644 index 0000000000000000000000000000000000000000..6f5421a7391bb3fd37a8b07409c2c5b541454b4c --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/cri.md @@ -0,0 +1,1977 @@ +# CRI接口 + +## 描述 + +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略有出入,以本文档描述的接口为准。 + +> [!NOTE]说明 +> +> 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/zh/cloud/container_engine/isula_container_engine/figures/zh-cn_image_0183048952.png b/docs/zh/cloud/container_engine/isula_container_engine/figures/zh-cn_image_0183048952.png new file mode 100644 index 0000000000000000000000000000000000000000..fe9074f8fba969795f1e1d40fb879e21d5fc2a7c Binary files /dev/null and b/docs/zh/cloud/container_engine/isula_container_engine/figures/zh-cn_image_0183048952.png differ diff --git a/docs/zh/cloud/container_engine/isula_container_engine/image_management.md b/docs/zh/cloud/container_engine/isula_container_engine/image_management.md new file mode 100644 index 0000000000000000000000000000000000000000..df14898899ee847c67ed2e55e2607a0406a1b319 --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/image_management.md @@ -0,0 +1,475 @@ +# 镜像管理 + +## docker镜像管理 + +### 登录到镜像仓库 + +#### 描述 + +isula login命令用于登录到镜像仓库。登录成功后可以使用isula pull命令从该镜像仓库拉取镜像。如果镜像仓库不需要密码,则拉取镜像前不需要执行该命令。 + +#### 用法 + +```sh +isula login [OPTIONS] SERVER +``` + +#### 参数 + +login命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表1 表1-20 login命令参数列表" 。 + +#### 示例 + +```sh +$ isula login -u abc my.csp-edge.com:5000 + +Login Succeeded +``` + +### 从镜像仓库退出登录 + +#### 描述 + +isula logout命令用于从镜像仓库退出登录。退出登录成功后再执行isula pull命令从该镜像仓库拉取镜像会因为未认证而拉取失败。 + +#### 用法 + +```sh +isula logout SERVER +``` + +#### 参数 + +logout命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表2 logout命令参数列表"。 + +#### 示例 + +```sh +$ isula logout my.csp-edge.com:5000 +Logout Succeeded +``` + +### 从镜像仓库拉取镜像 + +#### 描述 + +从镜像仓库拉取镜像到本地。 + +#### 用法 + +```sh +isula pull [OPTIONS] NAME[:TAG] +``` + +#### 参数 + +login命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表3 pull命令参数列表"。 + +#### 示例 + +```sh +$ isula pull localhost:5000/official/busybox +Image "localhost:5000/official/busybox" pulling +Image "localhost:5000/official/busybox@sha256:bf510723d2cd2d4e3f5ce7e93bf1e52c8fd76831995ac3bd3f90ecc866643aff" pulled +``` + +### 删除镜像 + +#### 描述 + +删除一个或多个镜像。 + +#### 用法 + +```sh +isula rmi [OPTIONS] IMAGE [IMAGE...] +``` + +#### 参数 + +rmi命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表4 rmi命令参数列表"。 + +#### 示例 + +```sh +$ isula rmi rnd-dockerhub.huawei.com/official/busybox +Image "rnd-dockerhub.huawei.com/official/busybox" removed +``` + +### 添加镜像标签 + +#### 描述 + +tag命令用于添加镜像标签 + +#### 用法 + +```sh +isula tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG] +``` + +#### 参数 + +tag命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表8 tag命令参数列表"。 + +#### 示例 + +```sh +$ isula tag busybox:latest test:latest +``` + +### 加载镜像 + +#### 描述 + +从一个tar包加载镜像。该tar包必须是使用docker save命令导出的tar包或格式一致的tar包。 + +#### 用法 + +```sh +isula load [OPTIONS] +``` + +#### 参数 + +load命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表5 load命令参数列表"。 + +#### 示例 + +```sh +$ isula load -i busybox.tar +Load image from "/root/busybox.tar" success +``` + +### 列出镜像 + +#### 描述 + +列出当前环境中所有镜像。 + +#### 用法 + +```sh +isula images [OPTIONS] +``` + +#### 参数 + +images命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表6 images命令参数列表"。 + +#### 示例 + +```sh +$ isula images +REPOSITORY TAG IMAGE ID CREATED SIZE +busybox latest beae173ccac6 2021-12-31 03:19:41 1.184MB +``` + +### 检视镜像 + +#### 描述 + +返回该镜像的配置信息。可以使用-f参数过滤出需要的信息。 + +#### 用法 + +```sh +isula inspect [options] CONTAINER|IMAGE [CONTAINER|IMAGE...] +``` + +#### 参数 + +inspect命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表7 inspect命令参数列表"。 + +#### 示例 + +```sh +$ 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时携带参数: + +```sh +isulad --use-decrypted-key=false +``` + +#### 示例 + +配置use-decrypted-key参数为false + +```sh +$ 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 +} +``` + +将证书放到对应的目录下 + +```sh +$ pwd +/etc/isulad/certs.d/my.csp-edge.com:5000 +$ ls +ca.crt tls.cert tls.key +``` + +重启isulad + +```sh +$ systemctl restart isulad +``` + +执行pull命令从仓库下载镜像 + +```sh +$ 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包进行导入。 + +#### 用法 + +```sh +isula import file REPOSITORY[:TAG] +``` + +导入成功后打印的字符串是导入的rootfs生成的镜像id + +#### 参数 + +import命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表9 import命令参数列表"。 + +#### 示例 + +```sh +$ 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功能重新导入成镜像。 + +#### 用法 + +```sh +isula export [OPTIONS] [ID|NAME] +``` + +#### 参数 + +export命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表10 export命令参数列表"。 + +#### 示例 + +```sh +$ isula run -tid --name container_test test sh +d7e601c2ef3eb8d378276d2b42f9e58a2f36763539d3bfcaf3a0a77dc668064b +$ isula export -o rootfs.tar d7e601c +$ ls +rootfs.tar +``` + +## embedded镜像管理 + +### 加载镜像 + +#### 描述 + +根据embedded镜像的manifest加载镜像。注意--type的值必须填写embedded。 + +#### 用法 + +```sh +isula load [OPTIONS] --input=FILE --type=TYPE +``` + +#### 参数 + +load命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表5 load命令参数列表"。 + +#### 示例 + +```sh +$ isula load -i test.manifest --type embedded +Load image from "/root/work/bugfix/tmp/ci_testcase_data/embedded/img/test.manifest" success +``` + +### 列出镜像 + +#### 描述 + +列出当前环境中所有镜像。 + +#### 用法 + +```sh +isula images [OPTIONS] +``` + +#### 参数 + +images命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表6 images命令参数列表"。 + +#### 示例 + +```sh +$ isula images +REPOSITORY TAG IMAGE ID CREATED SIZE +busybox latest beae173ccac6 2021-12-31 03:19:41 1.184MB +``` + +### 检视镜像 + +#### 描述 + +返回该镜像的配置信息。可以使用-f参数过滤出需要的信息。 + +#### 用法 + +```sh +isula inspect [options] CONTAINER|IMAGE [CONTAINER|IMAGE...] +``` + +#### 参数 + +inspect命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表7 inspect命令参数列表"。 + +#### 示例 + +```sh +$ isula inspect -f "{{json .created}}" test:v1 +"2018-03-01T15:55:44.322987811Z" +``` + +### 删除镜像 + +#### 描述 + +删除一个或多个镜像。 + +#### 用法 + +```sh +isula rmi [OPTIONS] IMAGE [IMAGE...] +``` + +#### 参数 + +rmi命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表4 rmi命令参数列表"。 + +#### 示例 + +```sh +$ isula rmi test:v1 +Image "test:v1" removed +``` + +### 添加名称 + +#### 描述 + +给镜像添加一个名称。 + +#### 用法 + +```sh +isula tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG] +``` + +#### 参数 + +tag命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表8 tag命令参数列表"。 + +#### 示例 + +```sh +$ isula tag test:v1 test:v2 +``` + +### 导入镜像 + +#### 描述 + +将tar格式的rootfs导入生成一个新的镜像,该tar包必须是通过export命令导出的tar包。 + +#### 用法 + +```sh +isula export [command options] [ID|NAME] +``` + +#### 参数 + +export命令支持参数请参见"附录 > 命令行参数说明" 章节的 "表9 export命令参数列表"。 + +#### 示例 + +```sh +$ isula export -o test.tar containername +``` diff --git a/docs/zh/cloud/container_engine/isula_container_engine/installation_configuration.md b/docs/zh/cloud/container_engine/isula_container_engine/installation_configuration.md new file mode 100644 index 0000000000000000000000000000000000000000..9758f2a60e227ae6bcb47476676a7892ba899783 --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/installation_configuration.md @@ -0,0 +1,1022 @@ +# 安装与配置 + +本章介绍iSulad的安装、安装后配置,以及升级和卸载的方法。 +> [!NOTE]说明 +> +> 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,优先级从高到低是:命令行方式\>配置文件\>代码中默认配置。 + +> [!NOTE]说明 +> +> 如果采用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 integrity 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" + } + } + + ``` + + > [!TIP]须知 + > + > 默认配置文件/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专用,避免冲突导致的文件属性变化以及带来的安全问题。 + +- 日志文件管理: + + > [!TIP]须知 + > + > 日志功能对接: 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。 + +> [!TIP]须知 +> +> - 采用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/zh/cloud/container_engine/isula_container_engine/installation_upgrade_uninstallation.md b/docs/zh/cloud/container_engine/isula_container_engine/installation_upgrade_uninstallation.md new file mode 100644 index 0000000000000000000000000000000000000000..f6d55640a1c0df735a3d9cdd8e698d47960e1cd0 --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/installation_upgrade_uninstallation.md @@ -0,0 +1,3 @@ +# 安装、升级与卸载 + +本章介绍 iSulad 的安装、安装后配置,以及升级和卸载的方法。 diff --git a/docs/zh/cloud/container_engine/isula_container_engine/interconnecting_isula_shim_v2_with_stratovirt.md b/docs/zh/cloud/container_engine/isula_container_engine/interconnecting_isula_shim_v2_with_stratovirt.md new file mode 100644 index 0000000000000000000000000000000000000000..845b80fe757a570d4423da89cb668122891bb009 --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/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 + ``` + + 若回显有如下信息,说明配置成功。 + + ```sh + 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 配置参数保持一致或者保持缺省值。 + + ```sh + 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 repo](https://repo.openeuler.org/): + + ```bash + $ cd /var/lib/kata + $ wget https://dl-cdn.openeuler.openatom.cn/openEuler-24.03-LTS-SP1/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/zh/cloud/container_engine/isula_container_engine/interconnection_with_the_cni_network.md b/docs/zh/cloud/container_engine/isula_container_engine/interconnection_with_the_cni_network.md new file mode 100644 index 0000000000000000000000000000000000000000..8ceda130d345fb5c219e186449a4ed5380d16c03 --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/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网络的接口,清理网络相关的资源。 + +>[!NOTE]说明 +> +> - 在调用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/zh/cloud/container_engine/isula_container_engine/local_volume_management.md b/docs/zh/cloud/container_engine/isula_container_engine/local_volume_management.md new file mode 100644 index 0000000000000000000000000000000000000000..3c0ecf073ec38451ad4c2956df22d771afc1fe6b --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/local_volume_management.md @@ -0,0 +1,200 @@ +# 本地卷管理 + +## 概述 + +iSula 管理的容器销毁后,容器内自身所有的数据都会被销毁。如果用户希望容器销毁后依然保留数据,则需要有一种持久化数据的机制。iSula 允许将主机上的文件、目录或卷在容器运行时挂载到容器内。用户可以将需要持久化的数据写入容器内的挂载点。则容器销毁后,主机上的文件、目录、卷依然保留。如果用户需要销毁主机上的文件、目录、卷,可以手动删除文件、目录或者执行 iSula 的相关命令删除卷。对于卷的管理目前 iSula 只支持本地卷,本地卷又分为有名卷和匿名卷。由用户指定名称生产的卷叫有名卷,用户没有指定卷名称,由 iSula 自动生成卷名(一个64位的随机数)的卷为匿名卷。 + +本章介绍通过 iSula 管理本地卷的使用方法。 + +## 注意事项 + +- 卷名称长度2-64个字符,符合正则表达式:^[a-zA-Z0-9][a-zA-Z0-9_.-]{1,63}$,即卷名称首字符必须为字母或者数字,从第二个字符开始可以为字母、数字或者"_"、"."、"-"这几个字符。 +- 创建容器时,如果卷对应的容器内的挂载点存在数据,则默认会拷贝到卷里。如果拷贝过程中出现了 iSula 崩溃重启或者系统掉电之类的异常,则卷内的数据可能是不完整的,这时需要手动删除卷或者卷内数据,确保数据的正确完整。 + +## 使用方法 + +### 使用-v参数挂载数据 + +#### **命令格式** + +```shell +isula run -v [SRC:]DST[:MODE,MODE...] IMAGE +``` + +#### **功能描述** + +使用 create / run 创建并运行容器时,使用 -v/--volume 参数将主机上的文件、目录或者卷挂载到容器内用于数据持久化。 + +#### **参数说明** + +- SRC: 用于挂载的文件、目录或者卷在主机上的路径,当值为绝对路径时,表示挂载主机上的文件或者文件夹。当值为卷名时,表示挂载卷。当省略该项时,表示挂载匿名卷。当文件夹或者卷不存在时,iSula会先创建一个新的文件夹/卷,再进行挂载操作。 +- DST: 容器内的挂载路径,必须为绝对路径。 +- MODE: 当挂载的源是目录或者文件时,合法的参数是ro/rw/z/Z/private/rprivate/slave/rslave/shared/rshared。同类型的参数只能配置一个。当挂载的源是卷时,合法的参数是ro/rw/z/Z/nocopy,同类型的参数只能配置一个。多个属性之间使用","连接。参数含义如下: + +| 参数 | 参数含义 | +| -------- | -----------------------------------------------| +| ro | 容器内挂载点挂载为只读属性 | +| rw | 容器内挂载点挂载为读写属性 | +| z | 如果开启了SELinux,则挂载时添加SELinux共享标签 | +| Z | 如果开启了SELinux,则挂载时添加SELinux私有标签 | +| private | 容器内挂载点挂载为私有传播属性 | +| rprivate | 容器内挂载点递归挂载为私有传播属性 | +| slave | 容器内挂载点挂载为从属传播属性 | +| rslave | 容器内挂载点递归挂载为从属传播属性 | +| shared | 容器内挂载点挂载为共享传播属性 | +| rshared | 容器内挂载点递归挂载为共享传播属性 | +| nocopy | 不拷贝挂载点内的数据,该参数不进行配置时默认会拷贝数据。另外,如果卷里已经有数据了,也不会进行拷贝 | + +#### **示例** + +基于 busybox 运行容器并创建/挂载名称为 vol 的卷到容器的 /vol 目录,同时配置挂载点为只读,并且如果容器中对应挂载点有数据也不进行拷贝。 + +```shell +isula run -v vol:/vol:ro,nocopy busybox +``` + +### 使用--mount参数挂载数据 + +#### **命令格式** + +```shell +isula run --mount [type=TYPE,][src=SRC,]dst=DST[,KEY=VALUE] busybox +``` + +#### **功能描述** + +使用 create / run 创建并运行容器时,使用 --mount 参数将主机上的文件、目录、卷或者文件系统挂载到容器内用于数据持久化。 + +#### **参数说明** + +- type: 挂载到容器中的数据的类型,类型可以是 bind、volume、squashfs、tmpfs, 省略该项时默认为volume类型。 +- src: 用于挂载的文件、目录或者卷在主机上的路径。当值为绝对路径时,表示挂载主机上的文件或者目录。当值为卷名时,表示挂载卷。当省略该项时,表示匿名卷。当文件夹或者卷不存在时,iSula会先创建一个新的文件/卷,再进行挂载操作。该项的关键字 src 也可以写成 source。 +- dst: 容器内的挂载路径,必须为绝对路径。该项的关键字 dst 也可以写成 destination 或者 target。 +- KEY=VALUE: 表示 --mount 的参数,可以取如下值: + +| KEY 值 | VALUE | +| ------------------------------ | --------------------------------------------------------------------------- | +| selinux-opts/bind-selinux-opts | z或者Z。z表示如果开启了SElinux,则挂载时添加SElinux共享标签;Z表示如果开启了SElinux,则挂载时添加SElinux私有标签 | +| ro/readonly | 0/false 表示挂载成读写属性,1/true 表示挂载成只读属性。该项的值可以省略表示挂载成只读。该项只在 type=bind 时支持配置该参数 | +| bind-propagation | 值为private/rprivate/slave/rslave/shared/rshared,含义同上面-v参数中对应的值。只在type=bind时支持该参数 | +| volume-nocopy | 不拷贝挂载点内的数据,该参数不进行配置时默认会拷贝数据。另外,如果卷里已经有数据了,也不会进行拷贝。只在 type=volume 时支持该参数 | +| tmpfs-size | 挂载tmpfs时指定挂载的tmpfs空间的最大值,默认无限制 | +| tmpfs-mode | 挂载tmpfs时指定挂载的权限,默认1777 | + +#### **示例** + +基于 busybox 运行容器并创建/挂载名称为 vol 的卷到容器的 /vol 目录,同时配置挂载点为只读,并且如果容器中对应挂载点有数据也不进行拷贝。 + +```shell +isula run --mount type=volume,src=vol,dst=/vol,ro=true,volume-nocopy=true busybox +``` + +### 复用其他容器中的挂载配置 + +#### **命令格式** + +```shell +isula run --volumes-from CON1[:MODE] busybox +``` + +#### **功能描述** + +使用 create / run 创建并运行容器时,使用 --volumes-from 参数表示挂载点配置包括CON1容器的挂载点配置。可以配置多个 --volumes-from 参数。 + +#### **参数说明** + +- CON1: 被复用挂载点的容器的名称或者ID。 +- MODE: 值为ro表示复用的挂载点挂载为只读属性,值为rw表示复用的挂载点挂载为读写属性。 + +#### **示例** + +假设已经有名称为 container1 的容器配置了卷 vol1 到容器目录 /vol1,名称为 container2 的容器配置了卷 vol2 到容器目录 /vol2。现在运行一个新的容器复用 container1 和 container2 的挂载配置,即卷 vol1 挂载到容器的 /vol1 目录,vol2 挂载到容器的 /vol2 目录。 + +```shell +isula run --volumes-from container1 --volumes-from container2 busybox +``` + +### 使用镜像中的匿名卷 + +使用镜像中的匿名卷不需要用户做任何配置。如果镜像中配置了匿名卷,则在运行容器时 iSula 会自动创建一个匿名卷并挂载到镜像中指定的路径供用户使用。用户可以往容器中的匿名卷挂载点写入数据进行数据持久化。 + +### 卷的查询 + +#### **命令格式** + +```shell +isula volume ls [OPTIONS] +``` + +#### **功能描述** + +查询 iSula 管理的所有卷。 + +#### **参数说明** + +OPTIONS 可选参数: + +- -q,--quiet: 如果不加这个参数,默认只会查询到卷的驱动信息和卷的名称,添加该参数表示只查询卷的名称。 + +#### **示例** + +查询 iSula 管理的所有卷,只返回卷名称。 + +```shell +isula volume ls -q +``` + +### 卷的删除 + +#### **命令格式** + +```shell +isula volume rm [OPTIONS] VOLUME [VOLUME...] +isula volume prune [OPTIONS] +``` + +#### **功能描述** + +- rm 命令:删除指定的卷,如果卷被容器使用了,则会删除失败。 +- prune 命令:删除所有未被容器使用的卷。 + +#### **参数说明** + +prune 命令的 OPTIONS 可选参数: + +- -f,--force: 表示不弹出“确认是否要删除”的提示,默认会有风险提示,需要输入 y 才能继续执行。 + +#### **示例** + +删除卷 vol1 和卷 vol2 + +```shell +isula volume rm vol1 vol2 +``` + +删除所有未被使用的卷,不弹出风险提示,格式如下: + +```shell +isula volume prune -f +``` + +### 注意事项 + +#### 冲突合并规则 + +如果卷的挂载点有冲突,则按照如下规则处理: + +- -v 和 --mount 的配置冲突,则返回失败。 +- --volumes-from 里获取的配置,如果和 -v/--mount 配置有冲突,则丢弃。 +- 镜像中的匿名卷配置,如果和 -v/--mount/--volumes-from 配置有冲突,则丢弃。 + +#### iSula和Docker的差异 + +| iSula行为 | Docker行为 | +| ------------------------------------------- | ------------------------------------------- | +| 卷名称最长64个字符 | 卷名称长度没有限制 | +| --mount 参数,如果挂载的源不存在,则会创建 | --mount 参数,如果挂载的源不存在,则会报错 | +| --mount 参数,支持 bind-selinux-opts 和 selinux-opts 参数配置 z/Z | --mount 参数,不支持 bind-selinux-opts 和 selinux-opts 参数 | +| 挂载点冲突合并规则,不做特殊处理 | 挂载点冲突合并规则,将 -v 指定的匿名卷当成镜像中的匿名卷一样处理 | +| volume prune 命令,提示回收了多少空间 | volume prune 命令,不会提示回收了多少空间 | +| -v/--mount/--volumes-from 配置在 hostconfig 中,匿名卷配置在 config 中 | -v 配置的匿名卷放在 config 配置中,其他配置在 hostconfig 中 | diff --git a/docs/zh/cloud/container_engine/isula_container_engine/overview.md b/docs/zh/cloud/container_engine/isula_container_engine/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..96ab83963a85046b70ef201904af2c5873bb8f1c --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/overview.md @@ -0,0 +1,9 @@ +# iSula容器引擎 + +iSula通用容器引擎相比Docker,是一种新的容器解决方案,提供统一的架构设计来满足CT和IT领域的不同需求。相比Golang编写的Docker,轻量级容器使用C/C++实现,具有轻、灵、巧、快的特点,不受硬件规格和架构的限制,底噪开销更小,可应用领域更为广泛。 + +容器统一架构如[图1](#zh-cn_topic_0182207099_fig10763114141217)所示。 + +**图 1** 容器统一架构 + +![](./figures/zh-cn_image_0183048952.png) diff --git a/docs/zh/cloud/container_engine/isula_container_engine/privileged_container.md b/docs/zh/cloud/container_engine/isula_container_engine/privileged_container.md new file mode 100644 index 0000000000000000000000000000000000000000..e4bc715ca59a3981014bcd8385b428af54ec80ee --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/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给容器添加特权模式,在非必要情况下,不要给容器添加特权,遵循最小特权原则,减少存在的安全风险。 + +```sh +isula run --rm -it --privileged busybox +``` diff --git a/docs/zh/cloud/container_engine/isula_container_engine/querying_information.md b/docs/zh/cloud/container_engine/isula_container_engine/querying_information.md new file mode 100644 index 0000000000000000000000000000000000000000..6db09f38a9f16217da428d01a5318422afdb9497 --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/querying_information.md @@ -0,0 +1,89 @@ +# 查询信息 + +## 查询服务版本信息 + +### 描述 + +isula version 命令用于查询iSulad服务的版本信息。 + +### 用法 + +```shell +isula version +``` + +### 实例 + +查询版本信息 + +```shell +isula version +``` + +如果isulad服务正常运行,则可以查看到客户端、服务端以及OCI config的版本等信息。 + +```shell +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服务未运行,则仅仅查询到客户端的信息,并提示无法连接到服务端。 + +```shell +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命令用于对系统级信息,以及容器和镜像数目等信息的查询。 + +### 用法 + +```shell +isula info +``` + +### 示例 + +查询系统级信息,可以展示容器数目,镜像数目,内核版本、操作系统等信息 + +```shell +# isula info +Containers: 2 + Running: 0 + Paused: 0 + Stopped: 2 +Images: 8 +Server Version: 1.0.31 +Logging Driver: json-file +Cgroup Driver: 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/zh/cloud/container_engine/isula_container_engine/security_features.md b/docs/zh/cloud/container_engine/isula_container_engine/security_features.md new file mode 100644 index 0000000000000000000000000000000000000000..b43a097b44023e8357bfbe63a8c70a90689d682a --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/security_features.md @@ -0,0 +1,243 @@ +# 安全特性 + +## 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 +``` + +> [!NOTE]说明 +> +> - 创建容器时通过--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 +} +] +} +``` + +> [!TIP]须知 +> +> - 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的子目录。 + +> [!NOTE]说明 +> +> - 目前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/zh/cloud/container_engine/isula_container_engine/supporting_oci_hooks.md b/docs/zh/cloud/container_engine/isula_container_engine/supporting_oci_hooks.md new file mode 100644 index 0000000000000000000000000000000000000000..1c60bab92905d93a42d41fa4f983a7564b0d59b2 --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/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/zh/cloud/container_engine/isula_container_engine/uninstallation.md b/docs/zh/cloud/container_engine/isula_container_engine/uninstallation.md new file mode 100644 index 0000000000000000000000000000000000000000..55f883df1feb05e657d475351ea2faed7297e970 --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/uninstallation.md @@ -0,0 +1,22 @@ +# 卸载 + +卸载iSulad的操作步骤如下: + +1. 卸载iSulad及其依赖软件包 + - 若使用yum方式安装,卸载的参考命令如下: + + ```sh + # yum remove iSulad + ``` + + - 若使用rpm方式安装,需卸载iSulad及其依赖包,卸载单个RPM包的参考命令如下: + + ```sh + # rpm -e iSulad-xx.xx.xx-YYYYmmdd.HHMMSS.gitxxxxxxxx.aarch64.rpm + ``` + +2. 镜像、容器、volumes以及相关配置文件不会自动删除,需要手动删除。参考命令如下: + + ```sh + # rm -rf /var/lib/iSulad + ``` diff --git a/docs/zh/cloud/container_engine/isula_container_engine/upgrade_methods.md b/docs/zh/cloud/container_engine/isula_container_engine/upgrade_methods.md new file mode 100644 index 0000000000000000000000000000000000000000..959624d090e49a493898ccc4af2e6257e890016a --- /dev/null +++ b/docs/zh/cloud/container_engine/isula_container_engine/upgrade_methods.md @@ -0,0 +1,32 @@ +# 升级 + +- 若为相同大版本之间的升级,例如从2.x.x版本升级到2.x.x版本,请执行如下命令: + + ```sh + # sudo yum update -y iSulad + ``` + +- 若为不同大版本之间的升级,例如从1.x.x版本升级到2.x.x版本,请先保存当前的配置文件/etc/isulad/daemon.json,并卸载已安装的iSulad软件包,然后安装待升级的iSulad软件包,随后恢复配置文件。 + +>![NOTE]说明 +> +> - 可通过**sudo rpm -qa |grep iSulad** 或 **isula version** 命令确认当前iSulad的版本号。 +> - 相同大版本之间,如果希望手动升级,请下载iSulad及其所有依赖的RPM包进行升级,参考命令如下: +> +> ```sh +> # sudo rpm -Uhv iSulad-xx.xx.xx-YYYYmmdd.HHMMSS.gitxxxxxxxx.aarch64.rpm +> ``` +> +> 若升级失败,可通过--force选项进行强制升级,参考命令如下: +> +> ```sh +> # sudo rpm -Uhv --force iSulad-xx.xx.xx-YYYYmmdd.HHMMSS.gitxxxxxxxx.aarch64.rpm +> ``` +> +> - 如若iSulad依赖的libisula组件发生升级,iSulad应该与对应版本的libisula一起升级,参考命令如下: +> +> ```sh +> # sudo rpm -Uvh libisula-xx.xx.xx-YYYYmmdd.HHMMSS.gitxxxxxxxx.aarch64.rpm iSulad-xx.xx.xx-YYYYmmdd.HHMMSS.gitxxxxxxxx.aarch64.rpm +> ``` +> +> - iSulad在openeuler 22.03-LTS-SP3之前的版本使用lcr作为默认容器运行时。因此,跨此版本升级时,在升级之前创建的容器仍是使用lcr作为容器运行时,只有在升级之后创建的容器才会采用新版本的默认运行时runc。若在新版本中仍需使用lcr容器运行时,需要修改isulad默认配置文件(默认为/etc/isulad/daemon.json)中的default-runtime为lcr或者在运行容器时指定容器运行时为lcr(--runtime lcr), 在升级时若对应的lcr、lxc版本发生升级,同样应该与iSulad一起升级。 diff --git a/docs/zh/cloud/container_form/secure_container/_toc.yaml b/docs/zh/cloud/container_form/secure_container/_toc.yaml new file mode 100644 index 0000000000000000000000000000000000000000..40d025ba0335dc32c86aa384d3c895442bddca59 --- /dev/null +++ b/docs/zh/cloud/container_form/secure_container/_toc.yaml @@ -0,0 +1,21 @@ +label: 安全容器 +isManual: true +description: 安全容器结合了虚拟化技术和容器技术,具有更好的隔离性 +sections: + - label: 概述 + href: ./overview.md + - label: 安装与配置 + href: ./installation_and_deployment_2.md + - label: 使用方法 + href: ./application_scenarios_2.md + sections: + - label: 管理安全容器的生命周期 + href: ./managing_the_lifecycle_of_a_secure_container.md + - label: 为安全容器配置资源 + href: ./configuring_resources_for_a_secure_container.md + - label: 为安全容器配置网络 + href: ./configuring_network_for_a_secure_container.md + - label: 监控安全容器 + href: ./monitoring_secure_containers.md + - label: 附录 + href: ./appendix_2.md diff --git a/docs/zh/cloud/container_form/secure_container/appendix_2.md b/docs/zh/cloud/container_form/secure_container/appendix_2.md new file mode 100644 index 0000000000000000000000000000000000000000..4fd2bf3ad64a83f21dd902cd39a5d253dbb278fa --- /dev/null +++ b/docs/zh/cloud/container_form/secure_container/appendix_2.md @@ -0,0 +1,484 @@ +# 附录 + +## configuration-toml配置说明 + +> [!NOTE]说明 +> +> 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/zh/cloud/container_form/secure_container/application_scenarios_2.md b/docs/zh/cloud/container_form/secure_container/application_scenarios_2.md new file mode 100644 index 0000000000000000000000000000000000000000..8e7f74d9d9cc150a8be98731787b0b398bee8e23 --- /dev/null +++ b/docs/zh/cloud/container_form/secure_container/application_scenarios_2.md @@ -0,0 +1,5 @@ +# 使用方法 + +本章介绍安全容器的使用方法。 +>![NOTE]说明 +>安全容器的使用需要root权限。 diff --git a/docs/zh/cloud/container_form/secure_container/configuring_network_for_a_secure_container.md b/docs/zh/cloud/container_form/secure_container/configuring_network_for_a_secure_container.md new file mode 100644 index 0000000000000000000000000000000000000000..a3705b1a4770054bf375b8a4761ed1c9ba272384 --- /dev/null +++ b/docs/zh/cloud/container_form/secure_container/configuring_network_for_a_secure_container.md @@ -0,0 +1,340 @@ +# 为安全容器配置网络 + +## tap设备网络支持 + +安全容器技术是基于Qemu VM实现的,对于物理机系统来说,安全容器就相当于是一个VM,所以安全容器可以在Neutron网络中将VM通过TAP技术接入外部网络。我们这里不需要关心TAP设备的创建和网桥对接等问题,只需要将指定的TAP设备(host已经存在)热插进pause容器的VM,并更新网卡信息即可。 + +相关命令行如下: + +1. **为已经启动的容器添加一个tap网卡(interface)** + + ```sh + $ cat ./test-iface.json | kata-runtime kata-network add-iface 6ec7a98 - + ``` + + 其中:6ec7a98是容器ID的截断,test-iface.json是描述网卡信息的文件,举例如下: + + ```conf + { + "device": "tap-test", + "name": "eth-test", + "IPAddresses": [ + { + "address": "172.16.0.3", + "mask": "16" + } + ], + "hwAddr":"02:42:20:6f:a3:69", + "mtu": 1500, + "vhostUserSocket":"/usr/local/var/run/openvswitch/vhost-user1", + "queues":5 + } + ``` + + 上述json文件中各个字段的含义说明如下: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

字段

+

是否可选

+

说明

+

device

+

必选

+

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

+

name

+

必选

+

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

+

IPAddresses

+

可选

+

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

+

hwAddr

+

必选

+

设置网卡的mac地址值。

+

mtu

+

必选

+

设置网卡的mtu值。允许范围为[46, 9600]之间。

+

vhostUserSocket

+

可选

+

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

+

queues

+

可选

+

设置网卡多队列的队列数目。如果不配置,默认为0。

+
+ + kata-runtime kata-network add-iface添加网卡命令执行返回结果说明: + + - 命令执行成功:从**命令的标准输出**返回json格式插入网卡的信息,json格式内容和传入的网卡信息相同。 + + 例如: + + ```sh + $ kata-runtime kata-network add-iface net.json + {"device":"tap_test","name":"eth-test","IPAddresses":[{"Family":2,"Address":"173.85.100.1","Mask":"24"}],"mtu":1500,"hwAddr":"02:42:20:6e:03:01","pciAddr":"01.0/00"} + ``` + + - 命令执行失败:从**命令的标准输出**返回字符串null。 + + 例如: + + ```sh + $ kata-runtime kata-network add-iface netbad.json 2>/dev/null + null + ``` + + >![NOTE]说明 + >当网卡添加成功时,如果为其指定了IP地址,则kata会为新添加的网卡添加一条destination为同网段地址的默认路由,如上例中添加网卡之后容器内有如下路由被添加: + > + >```conf + >[root@6ec7a98 /]# ip route + >172.16.0.0/16 dev eth-test proto kernel scope link src 172.16.0.3 + >``` + +2. **列出已经添加的网卡** + + ```sh + $ kata-runtime kata-network list-ifaces 6ec7a98 + [{"name":"eth-test","mac":"02:42:20:6f:a3:69","ip":["172.16.0.3/16"],"mtu":1500}] + ``` + + 可以查询到我们刚才添加的网卡信息。 + + kata-runtime kata-network list-ifaces列出已添加网卡命令执行返回结果说明: + + - 命令执行成功:从**命令的标准输出**返回json格式的Pod中所有插入网卡的信息。 + + 如果Pod中插入了多个网卡设备,返回的是一个json数组格式的网卡信息。 + + ```sh + $ kata-runtime kata-network list-ifaces + [{"name":"container_eth","mac":"02:42:20:6e:a2:59","ip":["172.17.25.23/8"],"mtu":1500},{"name":"container_eth_2","mac":"02:90:50:6b:a2:29","ip":["192.168.0.34/24"],"mtu":1500}] + ``` + + 如果Pod中没有插入任何网卡设备,从**命令的标准输出**返回字符串null。 + + ```sh + $ kata-runtime kata-network list-ifaces + null + ``` + + - 命令执行失败:从**命令的标准输出**返回字符串null,从**命令的标准错误输出**返回错误描述信息。 + + 例如: + + ```sh + $ kata-runtime kata-network list-ifaces + null + ``` + +3. **为指定网卡添加一条路由** + + ```sh + $ cat ./test-route.json | kata-runtime kata-network add-route 6ec7a98 - + [{"dest":"default","gateway":"172.16.0.1","device":"eth-test"}] + ``` + + kata-runtime kata-network add-route为指定网卡添加一条路由命令执行返回结果说明: + + - 命令执行成功:从**命令的标准输出**返回json格式的添加的路由信息。 + + 例如: + + ```sh + $ kata-runtime kata-network add-route route.json + [{"dest":"177.17.0.0/24","gateway":"177.17.25.1","device":"netport_test_1"}] + ``` + + - 命令执行失败:从**命令的标准输出**返回字符串null,从**命令的标准错误输出**返回错误描述信息。 + + 例如: + + ```sh + $ kata-runtime kata-network add-route routebad.json 2>/dev/null + null + ``` + + 字段说明如下: + + - dest:设置路由对应的网段。格式为/必选。分如下3种情况: + 1. 配置/; + 2. 只配置,则默认掩码为32; + 3. 若配置了"dest":"default",默认无dest,需传入gateway。 + + - gateway:设置路由的下一跳网关。设置"dest":"default"时,gateway必选;其他情况可选。 + - device:必选。设置路由对应的网卡名称,最长支持15字符。 + + > [!NOTE]说明 + >如果为容器内的回环设备lo添加路由时,路由配置文件中的"device"字段对应的设备名称为"lo"。 + +4. **删除指定路由** + + ```sh + $ cat ./test-route.json | kata-runtime kata-network del-route 6ec7a98 - + ``` + + test-route.json字段与添加路由输入json文件的字段相同。 + + kata-runtime kata-network del-route删除指定路由命令执行返回结果说明: + + - 命令执行成功:从**命令的标准输出**返回json格式的添加的路由信息。 + + 例如: + + ```sh + $ kata-runtime kata-network del-route route.json + [{"dest":"177.17.0.0/24","gateway":"177.17.25.1","device":"netport_test_1"}] + ``` + + - 命令执行失败:从**命令的标准输出**返回字符串null,从**命令的标准错误输出**返回错误描述信息。 + + 例如: + + ```sh + $ kata-runtime kata-network del-route routebad.json 2>/dev/null + null + ``` + + > [!NOTE]说明 + >- 输入字段中dest为必选,device/gateway均为可选。kata根据不同字段进行模糊匹配,删除对应的路由规则。例如指定了dest为某个IP,则所有该IP的规则都会被删除。 + >- 如果删除的是容器内回环设备lo的路由时,路由配置文件中的"device"字段对应的设备名称为"lo"。 + +5. **删除已经添加的网卡** + + ```sh + $ cat ./test-iface.json | kata-runtime kata-network del-iface 6ec7a98 - + ``` + + > [!NOTE]说明 + >删除网卡时,仅根据网卡容器内名称(name字段)来删除。即便填写其他字段,kata也不会使用。 + + kata-runtime kata-network del-iface删除网卡命令执行返回结果说明: + + - 命令执行成功:从**命令标准输出**返回null字符串。 + + 例如: + + ```sh + $ kata-runtime kata-network del-iface net.json + null + ``` + + - 命令执行失败:从**命令标准输出**返回删除失败网卡json格式的信息,从**命令的标准错误输出**返回错误描述信息。 + + 例如: + + ```sh + $ kata-runtime kata-network del-iface net.json + {"device":"tapname_fun_012","name":"netport_test_1","IPAddresses":[{"Family":0,"Address":"177.17.0.1","Mask":"8"}],"mtu":1500,"hwAddr":"02:42:20:6e:a2:59","linkType":"tap"} + ``` + +以上为常用场景和命令行示例,具体命令行接口请参见“附录 > 接口列表”。 + +## kata IPVS子系统 + +安全容器提供添加ipvs命令的接口,支持对容器设置ipvs规则。功能包含对虚拟服务的添加/编辑/删除、对真实服务器的添加/编辑/删除、查询ipvs服务信息、设置连接超时、清理系统连接缓存,并支持对规则的批量导入。 + +1. 为容器添加一个虚拟服务地址 + + ```sh + kata-runtime kata-ipvs ipvsadm --parameters "--add-service --tcp-service 172.17.0.7:80 --scheduler rr --persistent 3000" + ``` + +2. 修改容器虚拟服务参数 + + ```sh + kata-runtime kata-ipvs ipvsadm --parameters "--edit-service --tcp-service 172.17.0.7:80 --scheduler rr --persistent 5000" + ``` + +3. 删除容器虚拟服务地址 + + ```sh + kata-runtime kata-ipvs ipvsadm --parameters "--delete-service --tcp-service 172.17.0.7:80" + ``` + +4. 为虚拟服务地址添加一个真实服务器 + + ```sh + kata-runtime kata-ipvs ipvsadm --parameters "--add-server --tcp-service 172.17.0.7:80 --real-server 172.17.0.4:80 --weight 100" + ``` + +5. 修改容器真实服务器参数 + + ```sh + kata-runtime kata-ipvs ipvsadm --parameters "--edit-server --tcp-service 172.17.0.7:80 --real-server 172.17.0.4:80 --weight 200" + ``` + +6. 删除容器真实服务器 + + ```sh + kata-runtime kata-ipvs ipvsadm --parameters "--delete-server --tcp-service 172.17.0.7:80 --real-server 172.17.0.4:80" + ``` + +7. 查询服务信息 + + ```sh + kata-runtime kata-ipvs ipvsadm --parameters "--list" + ``` + +8. 逐条导入耗时太久,可将规则写入文件后,批量导入 + + ```sh + kata-runtime kata-ipvs ipvsadm --restore - < <规则文件路径> + ``` + + > [!NOTE]说明 + >单条添加时默认使用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 + +9. 清理系统连接缓存 + + ```sh + kata-runtime kata-ipvs cleanup --parameters "--orig-dst 172.17.0.4 --protonum tcp" + ``` + +10. 为tcp/tcpfin/udp连接设置超时 + + ```sh + kata-runtime kata-ipvs ipvsadm --parameters "--set 100 100 200" + ``` + + > [!NOTE]说明 + >1. 每个容器支持iptables规则数量最大为20000条(5k service,3个server/service),add-service和add-server都算作规则。 + >2. 批量导入前需清空已有规则。 + >3. 不存在并发测试场景。 + >4. 以上为常用命令示例,具体命令行接口请参见“附录 > 接口列表”。 diff --git a/docs/zh/cloud/container_form/secure_container/configuring_resources_for_a_secure_container.md b/docs/zh/cloud/container_form/secure_container/configuring_resources_for_a_secure_container.md new file mode 100644 index 0000000000000000000000000000000000000000..c822271b5a639adc13fa9491a10bf56d971b30d6 --- /dev/null +++ b/docs/zh/cloud/container_form/secure_container/configuring_resources_for_a_secure_container.md @@ -0,0 +1,31 @@ +# 为安全容器配置资源 + +安全容器运行于虚拟化隔离的轻量级虚拟机内,因此资源的配置应分为两部分:对轻量级虚拟机的资源配置,即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/zh/cloud/container_form/secure_container/figures/kata-arch.png b/docs/zh/cloud/container_form/secure_container/figures/kata-arch.png new file mode 100644 index 0000000000000000000000000000000000000000..60fbb602d94cf7a8e13bd6ecb520c99e574037e6 Binary files /dev/null and b/docs/zh/cloud/container_form/secure_container/figures/kata-arch.png differ diff --git a/docs/zh/cloud/container_form/secure_container/figures/zh_cn_image_0221924928.png b/docs/zh/cloud/container_form/secure_container/figures/zh_cn_image_0221924928.png new file mode 100644 index 0000000000000000000000000000000000000000..df046870b3dfbcbe4acb4a91f509ba8b26fa7c80 Binary files /dev/null and b/docs/zh/cloud/container_form/secure_container/figures/zh_cn_image_0221924928.png differ diff --git a/docs/zh/cloud/container_form/secure_container/installation_and_deployment_2.md b/docs/zh/cloud/container_form/secure_container/installation_and_deployment_2.md new file mode 100644 index 0000000000000000000000000000000000000000..6934b46c60855536478767ab5da3fdc4cc4f0859 --- /dev/null +++ b/docs/zh/cloud/container_form/secure_container/installation_and_deployment_2.md @@ -0,0 +1,114 @@ +# 安装与配置 + +## 安装方法 + +### 前提条件 + +- 安全容器的安装需要使用root权限。 +- 为了获取更好的性能体验,安全容器需要运行在裸金属服务器上,**暂不支持安全容器运行在虚拟机内**。 +- 安全容器运行依赖以下组件,请确保环境上已安装所需版本的依赖组件。以下组件来自配套的openEuler版本。如果使用iSula容器引擎,请参考iSula容器引擎的[安装与配置](../../container_engine/isula_container_engine/installation_configuration.md)章节安装iSulad。 + - docker-engine + - qemu + +### 安装操作 + +安全容器发布组件集成在同一个kata-containers-<_version_\>.rpm包中,使用rpm命令可以直接安装对应的软件,其中version为版本号。 + +```sh +rpm -ivh kata-containers-.rpm +``` + +## 配置方法 + +### docker-engine容器引擎的配置 + +为了让docker-engine容器引擎支持新的容器运行时kata-runtime,需要通过以下步骤对docker-engine容器引擎进行配置: + +1. 请保证环境上所有的软件包(docker-engine、kata-containers)都已经安装完毕。 +2. 停止docker-engine。 + + ```sh + 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。 + + ```sh + systemctl start docker + ``` + +### iSula容器引擎的配置 + +与docker-engine容器引擎类似,为了让iSula容器引擎支持新的容器运行时kata-runtime,需要通过以下步骤对iSula容器引擎进行配置: + +1. 请保证环境上所有的软件包(iSulad、kata-containers)都已经安装完毕。 +2. 停止isulad。 + + ```sh + systemctl stop isulad + ``` + +3. 修改iSula容器引擎的配置文件/etc/isulad/daemon.json,并新增如下配置: + + ```sh + { + "runtimes": { + "kata-runtime": { + "path": "/usr/bin/kata-runtime", + "runtime-args": [ + "--kata-config", + "/usr/share/defaults/kata-containers/configuration.toml" + ] + } + } + } + ``` + +4. 重新启动isulad。 + + ```sh + 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/zh/cloud/container_form/secure_container/managing_the_lifecycle_of_a_secure_container.md b/docs/zh/cloud/container_form/secure_container/managing_the_lifecycle_of_a_secure_container.md new file mode 100644 index 0000000000000000000000000000000000000000..4e9158c26468e9c830d17d88cba650d4d9886187 --- /dev/null +++ b/docs/zh/cloud/container_form/secure_container/managing_the_lifecycle_of_a_secure_container.md @@ -0,0 +1,93 @@ +# 管理安全容器的生命周期 + +## 启动安全容器 + +用户可以使用docker-engine或者iSulad作为安全容器的容器引擎,两者的调用方式类似,请用户自行选择一种方式启动安全容器。 + +启动安全容器的操作步骤如下: + +1. 确保安全容器组件已经正确安装部署。 +2. 准备容器镜像。假设容器镜像为busybox,使用docker-engine和iSula容器引擎下载容器镜像的命令分别如下: + + ```sh + docker pull busybox + ``` + + ```sh + isula pull busybox + ``` + +3. 启动一个安全容器。使用docker-engine和iSula容器引擎启动安全容器的命令分别如下: + + ```sh + docker run -tid --runtime kata-runtime --network none busybox + ``` + + ```sh + isula run -tid --runtime kata-runtime --network none busybox + ``` + + >![NOTE]说明 + >安全容器网络使用仅支持CNI网络,不支持CNM网络,不支持使用-p和--expose暴露容器端口,使用安全容器时需指定参数--net=none。 + +4. 启动一个Pod + 1. 启动pause容器并根据回显获取pod的sandbox-id。使用docker-engine和iSula容器引擎启动的命令分别如下: + + ```sh + docker run -tid --runtime kata-runtime --network none --annotation io.kubernetes.docker.type=podsandbox + ``` + + ```sh + isula run -tid --runtime kata-runtime --network none --annotation io.kubernetes.cri.container-type=sandbox + ``` + + 2. 创建业务容器并加入到这个pod中。使用docker-engine和iSula容器引擎创建的命令分别如下: + + ```sh + docker run -tid --runtime kata-runtime --network none --annotation io.kubernetes.docker.type=container --annotation io.kubernetes.sandbox.id= busybox + ``` + + ```sh + 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引擎则不提供。 + +## 停止安全容器 + +- 停止一个安全容器。 + + ```sh + docker stop + ``` + +- 停止一个Pod。 + + Pod停止需要注意顺序,pause容器与Pod生命周期相同,因此先停止业务容器后再停止pause容器。 + +## 删除安全容器 + +删除前请确保容器已经停止: + +```sh +docker rm +``` + +如果需要强制删除一个正在运行的容器,可以使用**-f**强制删除: + +```sh +docker rm -f +``` + +## 在容器中执行一条新的命令 + +由于pause容器仅作为占位容器,如果启动一个Pod时,请在业务容器内执行新的命令,pause容器并没有相应的指令;如果只启动一个容器时,则可以直接执行新增命令: + +```sh +docker exec -ti +``` + +>![NOTE]说明 +> +> - 如遇到docker exec -ti进入容器的同时,另一终端执行docker restart或者docker stop命令造成exec界面卡住的情况,可使用Ctrl+P+Q退出docker exec操作界面。 +> - 如果使用-d参数则命令在后台执行,不会打印错误信息,其退出码也不能作为命令执行是否正确的判断依据。 diff --git a/docs/zh/cloud/container_form/secure_container/monitoring_secure_containers.md b/docs/zh/cloud/container_form/secure_container/monitoring_secure_containers.md new file mode 100644 index 0000000000000000000000000000000000000000..85c3f185fb6cb6a3e08f2aa67d2c51ccb12efc92 --- /dev/null +++ b/docs/zh/cloud/container_form/secure_container/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。 + +## 用法 + +```sh +kata-runtime metrics +``` + +## 前置条件 + +sandbox id为长id,要查询的容器状态必须为running,否则报错:`Get " unix /run/vc/\/shim-monitor : connect : connection refused` + +当使用annotation指定容器类型为运行在某个sandbox中的容器时,用kata-runtime metrics查询该容器会失败,只能去查询该容器对应的sandbox。 + +该命令只支持查询监控一个sandbox的状态。 + +## 示例 + +```shell +$ 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/zh/cloud/container_form/secure_container/overview.md b/docs/zh/cloud/container_form/secure_container/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..0d2f9ea8469bbc05c8e2dcb5992ef6e5486528a1 --- /dev/null +++ b/docs/zh/cloud/container_form/secure_container/overview.md @@ -0,0 +1,26 @@ +# 概述 + +安全容器是虚拟化技术和容器技术的有机结合,相比普通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) + +>![NOTE]说明 +>安全容器的安装和使用需要使用root权限。 diff --git a/docs/zh/cloud/container_form/system_container/_toc.yaml b/docs/zh/cloud/container_form/system_container/_toc.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3cde0247cdb375e51542177ff446a8ca7d41c8ea --- /dev/null +++ b/docs/zh/cloud/container_form/system_container/_toc.yaml @@ -0,0 +1,36 @@ +label: 系统容器 +isManual: true +description: 解决在重计算、高性能、大并发的场景下,重型应用和业务云化的问题 +sections: + +- label: 概述 + href: ./overview.md +- label: 安装指导 + href: ./installation_guideline.md +- label: 使用指南 + href: ./usage_guide.md + sections: + - 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 diff --git a/docs/zh/cloud/container_form/system_container/appendix_1.md b/docs/zh/cloud/container_form/system_container/appendix_1.md new file mode 100644 index 0000000000000000000000000000000000000000..ef017b6b1415e120119e6d90ee372b38f70f49c7 --- /dev/null +++ b/docs/zh/cloud/container_form/system_container/appendix_1.md @@ -0,0 +1,89 @@ +# 附录 + +## 命令行接口列表 + +此处仅列出系统容器与普通容器的差异命令,其他命令用户可以查阅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/environment。
+

--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/zh/cloud/container_form/system_container/configurable_cgroup_path.md b/docs/zh/cloud/container_form/system_container/configurable_cgroup_path.md new file mode 100644 index 0000000000000000000000000000000000000000..3465df9c44432586b677e065b072acd6eafebfe1 --- /dev/null +++ b/docs/zh/cloud/container_form/system_container/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参数: + +```sh +[root@localhost ~]# isula run -tid --cgroup-parent /lxc/cgroup123 --system-container --external-rootfs /root/myrootfs none init +115878a4dfc7c5b8c62ef8a4b44f216485422be9a28f447a4b9ecac4609f332e +``` + +查看容器init进程的cgroup信息: + +```sh +[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/zh/cloud/container_form/system_container/dynamically_loading_the_kernel_module.md b/docs/zh/cloud/container_form/system_container/dynamically_loading_the_kernel_module.md new file mode 100644 index 0000000000000000000000000000000000000000..d479fab66c3a5fbf58a611cd3a4d3803730b8afe --- /dev/null +++ b/docs/zh/cloud/container_form/system_container/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模块被成功加载到内核中。 + +```sh +[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 +``` + +> [!NOTE]说明 +> +> - 宿主机需要安装syscontainer-tools。 +> - 需要指定--hooks-spec为syscontainer hooks。 diff --git a/docs/zh/cloud/container_form/system_container/dynamically_managing_container_resources_syscontainer_tools.md b/docs/zh/cloud/container_form/system_container/dynamically_managing_container_resources_syscontainer_tools.md new file mode 100644 index 0000000000000000000000000000000000000000..9f0e91a1c8b08654ddbe2567d711dc7fc537ff07 --- /dev/null +++ b/docs/zh/cloud/container_form/system_container/dynamically_managing_container_resources_syscontainer_tools.md @@ -0,0 +1,475 @@ +# 容器资源动态管理 + +普通容器无法支持对容器内的资源进行管理,例如添加一个块设备到容器、插入一块物理/虚拟网卡到容器。系统容器场景下,通过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 + ``` + + >[!NOTE]说明 + >添加虚拟网卡或物理网卡时,请确保网卡处于空闲状态,添加正在使用的网卡会导致系统网络断开。 + +## 路由管理 + +### 功能描述 + +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/zh/cloud/container_form/system_container/environment_variable_persisting.md b/docs/zh/cloud/container_form/system_container/environment_variable_persisting.md new file mode 100644 index 0000000000000000000000000000000000000000..7eeeb5c53da90134577f0627716f615c91907bc0 --- /dev/null +++ b/docs/zh/cloud/container_form/system_container/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参数: + +```sh +[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/zh/cloud/container_form/system_container/installation_guideline.md b/docs/zh/cloud/container_form/system_container/installation_guideline.md new file mode 100644 index 0000000000000000000000000000000000000000..9d0b906c29d3846e3b3fac6ea83919db1e0e2a5a --- /dev/null +++ b/docs/zh/cloud/container_form/system_container/installation_guideline.md @@ -0,0 +1,29 @@ +# 安装指导 + +>[!NOTE]说明 +>系统容器的安装需要使用root权限。 + +1. 首先需要安装iSulad容器引擎。 + + ```sh + # yum install iSulad + ``` + +2. 安装系统容器依赖包。 + + ```sh + # yum install syscontainer-tools authz lxcfs-tools lxcfs + ``` + +3. 查看iSulad是否已经启动。 + + ```sh + # systemctl status isulad + ``` + +4. 开启lxcfs和authz服务。 + + ```sh + # systemctl start lxcfs + # systemctl start authz + ``` diff --git a/docs/zh/cloud/container_form/system_container/maximum_number_of_handles.md b/docs/zh/cloud/container_form/system_container/maximum_number_of_handles.md new file mode 100644 index 0000000000000000000000000000000000000000..4b2a928cde8b5e1a3597f33cba4c6e3eafb3aafc --- /dev/null +++ b/docs/zh/cloud/container_form/system_container/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,可以执行以下命令查看: + +```sh +[root@localhost ~]# cat /proc/1/cgroup | grep files +10:files:/ +``` + +结果显示files,说明内核支持files cgroup。 + +容器启动指定--files-limit参数,并检查files.limit参数是否成功写入: + +```sh +[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/zh/cloud/container_form/system_container/overview.md b/docs/zh/cloud/container_form/system_container/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..c1126a1c3c3cd3900ff1452ac9a973f013d25732 --- /dev/null +++ b/docs/zh/cloud/container_form/system_container/overview.md @@ -0,0 +1,3 @@ +# 系统容器 + +系统容器主要应对在重计算、高性能、大并发的场景下,重型应用和业务云化的问题。相比较虚拟机技术,系统容器可直接继承物理机特性,同时具备性能更优良,较少overhead的优点。从系统资源分配来看,系统容器在有限资源上相比虚拟机可分配更多计算单元,降低成本,通过系统容器可以构建产品的差异化竞争力,提供计算密度更高,价格更便宜,性能更优良的计算单元实例。 diff --git a/docs/zh/cloud/container_form/system_container/reboot_or_shutdown_in_a_container.md b/docs/zh/cloud/container_form/system_container/reboot_or_shutdown_in_a_container.md new file mode 100644 index 0000000000000000000000000000000000000000..10d6944a56e2cf9bfea0bfcf1e73c7c586c873a5 --- /dev/null +++ b/docs/zh/cloud/container_form/system_container/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参数,示例如下: + + ```sh + [root@localhost ~]# isula run -tid --restart on-reboot --system-container --external-rootfs /root/myrootfs none init + 106faae22a926e22c828a0f2b63cf5c46e5d5986ea8a5b26de81390d0ed9714f + ``` + +- 进入容器执行reboot命令: + + ```sh + [root@localhost ~]# isula exec -it 10 bash + [root@localhost /]# reboot + ``` + + 查看容器是否重启: + + ```sh + [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命令: + + ```sh + [root@localhost ~]# isula exec -it 10 bash + [root@localhost /]# shutdown -h now + [root@localhost /]# [root@localhost ~]# + ``` + + 检查容器是否停止: + + ```sh + [root@localhost ~]# isula exec -it 10 bash + Error response from daemon: Exec container error;Container is not running:106faae22a926e22c828a0f2b63cf5c46e5d5986ea8a5b26de81390d0ed9714f + ``` diff --git a/docs/zh/cloud/container_form/system_container/security_and_isolation.md b/docs/zh/cloud/container_form/system_container/security_and_isolation.md new file mode 100644 index 0000000000000000000000000000000000000000..c26febe0c0d8d37957a6c86513d4cc4a3a47f1cb --- /dev/null +++ b/docs/zh/cloud/container_form/system_container/security_and_isolation.md @@ -0,0 +1,337 @@ +# 安全性和隔离性 + +## 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不能同时使用。 + +### 使用指导 + +>[!NOTE]说明 +>指定--user-remap参数前,请先将rootfs下所有目录和文件的uid和gid做整体偏移,偏移量为--user-remap指定uid和gid的偏移量。 +>例如将dev目录的uid和gid整体uid和gid偏移100000的参考命令为: +>chown 100000:100000 dev + +系统容器启动指定--user-remap参数: + +```sh +[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进程信息: + +```sh +[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: + +```sh +[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插件服务命令如下: + + ```sh + [root@localhost ~]# yum install authz + [root@localhost ~]# systemctl start authz + ``` + +2. 要启动该功能,首先需要配置容器引擎和用户的TLS证书。可以使用OPENSSL来生成需要的证书,具体步骤如下: + + ```sh + #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端配置如下: + + ```con + { + "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 \}。 + + >[!NOTE]说明 + >- 配置中匹配action支持正则表达式。 + >- users不支持正则表达式。 + >- users不能有重复用户,即同一用户不能被多条规则匹配。 + +5. 配置并更新完之后,客户端配置TLS参数连接容器引擎,即是以受限的权限访问。 + + ```sh + [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)。 + + ```sh + [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命令行格式如下: + +```sh +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服务。 + + ```sh + [root@localhost ~]# yum install lxcfs lxcfs-tools + [root@localhost ~]# systemctl start lxcfs + ``` + +2. 容器启动完成之后查看容器内是否存在lxcfs挂载点。 + + ```sh + [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资源配置,然后查看容器资源。根据如下回显可知,容器资源视图显示的是容器真实资源数据而不是宿主机的数据。 + + ```sh + [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/zh/cloud/container_form/system_container/shared_memory_channels.md b/docs/zh/cloud/container_form/system_container/shared_memory_channels.md new file mode 100644 index 0000000000000000000000000000000000000000..68e9a48c29dbd9b465cc74491a4ee6e2f8877c67 --- /dev/null +++ b/docs/zh/cloud/container_form/system_container/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参数: + +```sh +[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 +``` + +> [!NOTE]说明 +> +> - 使用--host-channel大小限制时,若在容器内创建共享文件,则会受到容器内的内存配额限制(在容器内存使用达到极限时可能会产生oom)。 +> - 若用户在主机端创建共享文件,则不受容器内的内存配额限制。 +> - 若用户需要在容器内创建共享文件,且业务为内存密集型,可以通过设置容器内存配额为在原本基础上加上--host-channel配置的大小来消除影响。 diff --git a/docs/zh/cloud/container_form/system_container/specifying_rootfs_to_create_a_container.md b/docs/zh/cloud/container_form/system_container/specifying_rootfs_to_create_a_container.md new file mode 100644 index 0000000000000000000000000000000000000000..fff0d4299ac5a1e06a50a407a83e3d4243593a9d --- /dev/null +++ b/docs/zh/cloud/container_form/system_container/specifying_rootfs_to_create_a_container.md @@ -0,0 +1,45 @@ +# 指定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,那么启动一个系统容器的命令如下: + +```sh +# isula run -tid --system-container --external-rootfs /root/myrootfs none init +``` + +>[!NOTE]说明 +>rootfs为自定义的文件系统,请用户自行准备。例如容器镜像的tar包解压后,即为一个rootfs。 diff --git a/docs/zh/cloud/container_form/system_container/usage_guide.md b/docs/zh/cloud/container_form/system_container/usage_guide.md new file mode 100644 index 0000000000000000000000000000000000000000..5ea4272b07a6ef1262c4d2a1ddcaf605f5c7311c --- /dev/null +++ b/docs/zh/cloud/container_form/system_container/usage_guide.md @@ -0,0 +1,20 @@ +# 使用指南 + +系统容器基于iSula容器引擎进行功能增强,提供系统容器相关功能。系统容器提供的容器管理功能和iSula容器引擎保持一致,其命令格式和功能与iSula容器引擎相同。 + +本文档仅描述系统容器提供的增强功能对应的使用方式,其他命令行操作请参考 "iSula容器引擎" 章节。 + +系统容器功能仅涉及isula create/run命令行,后续未特别说明,各功能均使用此命令行。其命令行格式如下所示: + +```sh +# isula create/run [OPTIONS] [COMMAND] [ARG...] +``` + +其中: + +- OPTIONS:命令参数,可以一个或者多个,可选参数请参见 "iSula容器引擎 > 附录 > 命令行参数说明"。 +- COMMAND:系统容器启动后执行的命令。 +- ARG:系统容器启动后执行命令对应的参数。 + +>[!NOTE]说明 +>系统容器的使用需要root权限。 diff --git a/docs/zh/cloud/container_form/system_container/using_systemd_to_start_a_container.md b/docs/zh/cloud/container_form/system_container/using_systemd_to_start_a_container.md new file mode 100644 index 0000000000000000000000000000000000000000..f1532c28c7a6071cfb02126b2d15fde74d331373 --- /dev/null +++ b/docs/zh/cloud/container_form/system_container/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/zh/cloud/container_form/system_container/writable_namespace_kernel_parameters.md b/docs/zh/cloud/container_form/system_container/writable_namespace_kernel_parameters.md new file mode 100644 index 0000000000000000000000000000000000000000..3b98553c97c20155a4d7c24d5f707b2e9c83f6d8 --- /dev/null +++ b/docs/zh/cloud/container_form/system_container/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: + +```sh +[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: + +```sh +[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/zh/cloud/hybrid_deployment/oncn_bwm/_toc.yaml b/docs/zh/cloud/hybrid_deployment/oncn_bwm/_toc.yaml new file mode 100644 index 0000000000000000000000000000000000000000..99b9aebd47c782de78a20f4496c348a59543dfe9 --- /dev/null +++ b/docs/zh/cloud/hybrid_deployment/oncn_bwm/_toc.yaml @@ -0,0 +1,6 @@ +label: oncn-bwm用户指南 +isManual: true +description: 混合业务场景下的Pod带宽管理方案 +sections: + - label: 概述 + href: ./overview.md diff --git a/docs/zh/cloud/hybrid_deployment/oncn_bwm/overview.md b/docs/zh/cloud/hybrid_deployment/oncn_bwm/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..7a40932682f4da3576b79769d23ba8c443f29379 --- /dev/null +++ b/docs/zh/cloud/hybrid_deployment/oncn_bwm/overview.md @@ -0,0 +1,239 @@ +# oncn-bwm用户指南 + +## 简介 + +随着云计算、大数据、人工智能、5G、物联网等技术的迅速发展,数据中心的建设越来越重要。然而,数据中心的服务器资源利用率很低,造成了巨大的资源浪费。为了提高服务器资源利用率,oncn-bwm应运而生。 + +oncn-bwm是一款适用于在、离线业务混合部署场景的Pod带宽管理工具,它会根据QoS分级对节点内的网络资源进行合理调度,保障在线业务服务体验的同时,大幅提升节点整体的网络带宽利用率。 + +oncn-bwm工具支持如下功能: + +- 使能/去除/查询Pod带宽管理 +- 设置Pod网络优先级 +- 设置离线业务带宽范围和在线业务水线 +- 内部统计信息查询 + +## 安装 + +### 环境要求 + +操作系统为openEuler 22.03-LTS-SP4,且配置了22.03-LTS-SP4的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** | 查询一个主机/虚拟机的在线业务水线。 | + +> [!NOTE]说明 +> +> - 当一个主机上所有在线业务的总带宽高于水线时,会限制离线业务可以使用的带宽,反之当一个主机上所有在线业务的总带宽低于水线时,会提高离线业务可以使用的带宽。 +> - 判断在线业务的总带宽是否超过/低于设置的水线的时机:每10ms判断一次,根据每个10ms内统计的在线带宽是否高于水线来决定对离线业务采用的带宽限制。 + +##### 使用示例 + +- 设置在线业务水线为20mb + + ```shell + # bwmcli -s waterline 20mb + set waterline success + ``` + +- 查询在线业务水线 + + ```shell + # bwmcli -p waterline + waterline is 20971520(B) + ``` + +#### 统计信息 + +##### 命令和功能 + +| 命令格式 | 功能 | +| ------------------- | ------------------ | +| **bwmcli -p stats** | 查询内部统计信息。 | + +> [!NOTE]说明 +> +> - 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 # 配置在线业务的水线 +``` + +### 约束限制 + +1. 仅允许root用户执行bwmcli命令行。 +2. 本特性当前仅支持设置两档网络QoS优先级:离线和在线。 +3. 某个网卡上已经设置过tc qdisc规则的情况下,对此网卡使能网络QoS功能会失败。 +4. 网卡被插拔重新恢复后,原来设置的QoS规则会丢失,需要手动重新配置网络QoS功能。 +5. 用一条命令同时使能/去使能多张网卡的时候,如果中间有网卡执行失败,则终止对后面网卡的执行。 +6. 环境上开启SELinux的情况下,未对bwmcli程序配置SELinux策略可能导致部分命令(例如水线,带宽,优先级的设置或查询)失败,可在SELinux日志中确认。此情况可以通过关闭SELinux或对bwmcli程序配置SELinux策略解决。 +7. 升级包不会影响升级前的使能状态,卸载包会关闭对所有设备的使能。 +8. 网卡名仅支持数字、英文字母、中划线“-” 和下划线“_”这四类字符类型,包含其他字符类型的网卡不被识别。 +9. 实际使用过程中,带宽限速有可能造成协议栈内存积压,此时依赖传输层协议自行反压,对于udp等无反压机制的协议场景,可能出现丢包、ENOBUFS、限速有偏差等问题。 diff --git a/docs/zh/cloud/hybrid_deployment/rubik/_toc.yaml b/docs/zh/cloud/hybrid_deployment/rubik/_toc.yaml new file mode 100644 index 0000000000000000000000000000000000000000..dfea60acb246e0db7f6b6d89463aa4632211b419 --- /dev/null +++ b/docs/zh/cloud/hybrid_deployment/rubik/_toc.yaml @@ -0,0 +1,16 @@ +label: 云原生混合部署rubik用户指南 +isManual: true +description: 在业务混合部署的场景下,根据QoS分级,对资源进行合理调度 +sections: + - label: 概述 + href: ./overview.md + - label: 安装与部署 + href: ./installation_and_deployment.md + - label: 特性介绍 + href: ./feature_introduction.md + - label: 配置文档 + href: configuration.md + - label: 混部隔离示例 + href: ./example_of_isolation_for_hybrid_deployed_services.md + - label: 附录 + href: ./appendix.md diff --git a/docs/zh/cloud/hybrid_deployment/rubik/appendix.md b/docs/zh/cloud/hybrid_deployment/rubik/appendix.md new file mode 100644 index 0000000000000000000000000000000000000000..047c30c0d80464d4c9825b83af27a0089355a845 --- /dev/null +++ b/docs/zh/cloud/hybrid_deployment/rubik/appendix.md @@ -0,0 +1,252 @@ +# 附录 + +## DaemonSet 配置模板 + +```yaml +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: rubik +rules: + - apiGroups: [""] + resources: ["pods"] + verbs: ["list", "watch"] + - apiGroups: [""] + resources: ["pods/eviction"] + verbs: ["create"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: rubik +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: rubik +subjects: + - kind: ServiceAccount + name: rubik + namespace: kube-system +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: rubik + namespace: kube-system +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: rubik-config + namespace: kube-system +data: + config.json: | + { + "agent": { + "logDriver": "stdio", + "logDir": "/var/log/rubik", + "logSize": 1024, + "logLevel": "info", + "cgroupRoot": "/sys/fs/cgroup", + "enabledFeatures": [ + "preemption" + ] + }, + "preemption": { + "resource": [ + "cpu" + ] + } + } +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: rubik-agent + namespace: kube-system + labels: + k8s-app: rubik-agent +spec: + selector: + matchLabels: + name: rubik-agent + template: + metadata: + namespace: kube-system + labels: + name: rubik-agent + spec: + serviceAccountName: rubik + hostPID: true + containers: + - name: rubik-agent + image: hub.oepkgs.net/cloudnative/rubik:latest + imagePullPolicy: IfNotPresent + env: + - name: RUBIK_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + securityContext: + capabilities: + add: + - SYS_ADMIN + resources: + limits: + memory: 200Mi + requests: + cpu: 100m + memory: 200Mi + volumeMounts: + - name: rubiklog + mountPath: /var/log/rubik + readOnly: false + - name: runrubik + mountPath: /run/rubik + readOnly: false + - name: sysfs + mountPath: /sys/fs + readOnly: false + - name: devfs + mountPath: /dev + readOnly: false + - name: config-volume + mountPath: /var/lib/rubik + terminationGracePeriodSeconds: 30 + volumes: + - name: rubiklog + hostPath: + path: /var/log/rubik + - name: runrubik + hostPath: + path: /run/rubik + - name: sysfs + hostPath: + path: /sys/fs + - name: devfs + hostPath: + path: /dev + - name: config-volume + configMap: + name: rubik-config + items: + - key: config.json + path: config.json +``` + +## Dockerfile 模板 + +```dockerfile +FROM scratch +COPY ./build/rubik /rubik +ENTRYPOINT ["/rubik"] +``` + +## 镜像构建脚本 + +```bash +#!/bin/bash +set -e + +CURRENT_DIR=$(cd "$(dirname "$0")" && pwd) +BINARY_NAME="rubik" + +RUBIK_FILE="${CURRENT_DIR}/build/rubik" +DOCKERFILE="${CURRENT_DIR}/Dockerfile" +YAML_FILE="${CURRENT_DIR}/rubik-daemonset.yaml" + +# Get version and release number of rubik binary +VERSION=$(${RUBIK_FILE} -v | grep ^Version | awk '{print $NF}') +RELEASE=$(${RUBIK_FILE} -v | grep ^Release | awk '{print $NF}') +IMG_TAG="${VERSION}-${RELEASE}" + +# Get rubik image name and tag +IMG_NAME_AND_TAG="${BINARY_NAME}:${IMG_TAG}" + +# Build container image for rubik +docker build -f "${DOCKERFILE}" -t "${IMG_NAME_AND_TAG}" "${CURRENT_DIR}" + +echo -e "\n" +# Check image existence +docker images | grep -E "REPOSITORY|${BINARY_NAME}" + +# Modify rubik-daemonset.yaml file, set rubik image name +sed -i "/image:/s/:.*/: ${IMG_NAME_AND_TAG}/" "${YAML_FILE}" +``` + +## 通信矩阵 + +- rubik 服务进程作为客户端通过 List/Watch 机制与 kubernetes API Server 进行通信,从而获取 Pod 等信息 + +|源IP|源端口|目的IP|目标端口|协议|端口说明|侦听端口是否可更改|认证方式| +|----|----|----|----|----|----|----|----| +|rubik所在节点机器|32768-61000|api-server所在服务器|443|tcp|kubernetes对外提供的访问资源的端口|不可更改|token| + +## 文件与权限 + +- rubik 所有的操作均需要使用 root 权限。 + +- 涉及文件及权限如下表所示: + +|文件路径|文件/文件夹权限|说明| +|----|----|----| +|/var/lib/rubik|750|rpm 安装完成后生成目录,存放 rubik 相关文件| +|/var/lib/rubik/build|550|存放 rubik 二进制文件的目录| +|/var/lib/rubik/build/rubik|550|rubik 二进制文件| +|/var/lib/rubik/rubik-daemonset.yaml|640|rubik daemon set 配置模板,供 k8s 部署使用| +|/var/lib/rubik/Dockerfile|640|Dockerfile 模板| +|/var/lib/rubik/build_rubik_image.sh|550|rubik 容器镜像构建脚本| +|/var/log/rubik|700|rubik 日志存放目录(需开启 logDriver=file 后使能)| +|/var/log/rubik/rubik.log*|600|rubik 日志文件| + +## 约束限制 + +### 规格 + +- 磁盘:1GB+ + +- 内存:100MB+ + +## 运行时 + +- 每个 k8s 节点只能部署一个 rubik,多个 rubik 会冲突 + +- rubik 不接收任何命令行参数,若添加参数启动会报错退出 + +- 如果 rubik 进程进入 T、D 状态,则服务端不可用,此时服务不会响应,需恢复异常状态之后才可继续使用 + +### Pod 优先级设置 + +- 禁止低优先级往高优先级切换。如业务 A 先被设置为低优先级(-1),接着设置为高优先级(0),rubik 报错 + +- 用户添加注解、修改注解、修改 Pod yaml 中的注解并重新 apply 等操作不会触发 Pod 重建。rubik 会通过 List/Watch 机制感知 Pod 注解变化情况 + +- 禁止将任务从在线组迁移到离线组后再迁移回在线组,此操作会导致该任务 QoS 异常 + +- 禁止将重要的系统服务和内核线程加入到离线组中,否则可能导致调度不及时,进而导致系统异常 + +- CPU 和 memory 的在线、离线配置需要统一,否则可能导致两个子系统的 QoS 冲突 + +- 使用混部后,原始的 CPU share 功能存在限制。具体表现为: + - 若当前 CPU 中同时存放在线任务和离线任务,则离线任务的 CPU share 无法生效 + - 若当前 CPU 中只有在线任务或只有离线任务,CPU share 能生效 + - 建议离线业务 Pod 优先级配置为 best effort + +- 用户态的优先级反转、smt、cache、numa 负载均衡、离线任务的负载均衡,当前不支持 + +### 其他 + +禁止用户直接手动修改 Pod 对应 cgroup 或 resctrl 参数,否则可能出现数据不一致情况。 + +- CPU cgroup 目录, 如:`/sys/fs/cgroup/cpu/kubepods/burstable//` + - cpu.qos_level + - cpu.cfs_burst_us + +- memory cgroup 目录,如:`/sys/fs/cgroup/memory/kubepods/burstable//` + - memory.qos_level + - memory.soft_limit_in_bytes + - memory.force_empty + - memory.limit_in_bytes + - memory.high + +- RDT 控制组目录,如:`/sys/fs/resctrl` diff --git a/docs/zh/cloud/hybrid_deployment/rubik/configuration.md b/docs/zh/cloud/hybrid_deployment/rubik/configuration.md new file mode 100644 index 0000000000000000000000000000000000000000..0ac09bc8bbcecc7d586560b91c5863c922e57ab1 --- /dev/null +++ b/docs/zh/cloud/hybrid_deployment/rubik/configuration.md @@ -0,0 +1,228 @@ +# Rubik配置说明 + +rubik执行程序由Go语言实现,并编译为静态可执行文件,以便尽可能与系统依赖解耦。 + +## 命令 + +Rubik仅支持 使用`-v` 参数查询版本信息,不支持其他参数。 +版本信息输出示例如下所示,该信息中的内容和格式可能随着版本发生变化。 + +```bash +$ ./rubik -v +Version: 2.0.1 +Release: 2.oe2403sp1 +Go Version: go1.22.1 +Git Commit: bcaace8 +Built: 2024-12-10 +OS/Arch: linux/amd64 +``` + +## 配置 + +执行rubik二进制时,rubik首先会解析配置文件,配置文件的路径固定为`/var/lib/rubik/config.json`。 + +> [!NOTE]说明 +> +> - 为避免配置混乱,暂不支持指定其他路径。 +> - ubik支持以daemonset形式运行在kubernetes集群中。我们提供了yaml脚本(`hack/rubik-daemonset.yaml`),并定义了`ConfigMap`作为配置。因此,以daemonset形式运行rubik时,应修改`hack/rubik-daemonset.yaml`中的相应配置。 + +配置文件采用json格式,字段键采用驼峰命名规则,且首字母小写。 +配置文件示例内容如下: + +```json +{ + "agent": { + "logDriver": "stdio", + "logDir": "/var/log/rubik", + "logSize": 2048, + "logLevel": "info", + "cgroupRoot": "/sys/fs/cgroup", + "enabledFeatures": [ + "preemption", + "dynCache", + "ioLimit", + "ioCost", + "quotaBurst", + "quotaTurbo", + "psi", + "cpuevict", + "memoryevict" + ] + }, + "preemption": { + "resource": [ + "cpu", + "memory" + ] + }, + "quotaTurbo": { + "highWaterMark": 50, + "syncInterval": 100 + }, + "dynCache": { + "defaultLimitMode": "static", + "adjustInterval": 1000, + "perfDuration": 1000, + "l3Percent": { + "low": 20, + "mid": 30, + "high": 50 + }, + "memBandPercent": { + "low": 10, + "mid": 30, + "high": 50 + } + }, + "ioCost": [ + { + "nodeName": "k8s-single", + "config": [ + { + "dev": "sdb", + "enable": true, + "model": "linear", + "param": { + "rbps": 10000000, + "rseqiops": 10000000, + "rrandiops": 10000000, + "wbps": 10000000, + "wseqiops": 10000000, + "wrandiops": 10000000 + } + } + ] + } + ], + "psi": { + "interval": 10, + "resource": [ + "cpu", + "memory", + "io" + ], + "avg10Threshold": 5.0 + }, + "cpuevict": { + "threshold": 60, + "interval": 1, + "windows": 2, + "cooldown": 20 + }, + "memoryevict": { + "threshold": 60, + "interval": 1, + "cooldown": 4 + } +} +``` + +Rubik配置分为两类:通用配置和特性配置。通用配置由agent关键字标识,用于保存全局的配置。特性配置按服务类型区分,应用于各个子特性。特性配置必须在通用配置的`enabledFeatures`字段中声明方可使用。 + +### agent + +`agent`配置用于记录保存rubik运行的通用配置,例如日志、cgroup挂载点等信息。 + +| 配置键[=默认值] | 类型 | 描述 | 可选值 | +| ------------------------- | ---------- | -------------------------------------- | --------------------------- | +| logDriver=stdio | string | 日志驱动,支持标准输出和文件 | stdio, file | +| logDir=/var/log/rubik | string | 日志保存目录 | 可读可写的目录 | +| logSize=1024 | int | 日志限额,单位MB,仅logDriver=file生效 | [10, $2^{20}$] | +| logLevel=info | string | 输出日志级别 | debug,info,warn,error | +| cgroupRoot=/sys/fs/cgroup | string | 系统cgroup挂载点路径 | 系统cgroup挂载点路径 | +| enabledFeatures=[] | string数组 | 需要使能的rubik特性列表 | rubik支持特性,参见特性介绍 | + +### preemption + +`preemption`字段用于标识绝对抢占特性配置。目前,Preemption特性支持CPU和内存的绝对抢占,用户可以按需配置该字段,单独或组合使用资源的绝对抢占。 + +| 配置键[=默认值] | 类型 | 描述 | 可选值 | +| --------------- | ---------- | -------------------------------- | ----------- | +| resource=[] | string数组 | 资源类型,声明何种资源需要被访问 | cpu, memory | + +### dynCache + +`dynCache`字段用于标识支持Pod访存带宽和LLC限制特性配置。`l3Percent`字段用于标识最后一级缓存(LLC)水位控制线,`memBandPercent`字段用于标识访存带宽(MB)水位控制线。 + +| 配置键[=默认值] | 类型 | 描述 | 可选值 | +| ----------------------- | ------ | ------------------ | --------------- | +| defaultLimitMode=static | string | dynCache的控制模式 | static, dynamic | +| adjustInterval=1000 | int | dynCache动态控制间隔时间,单位ms| [10, 10000] | +| perfDuration=1000 | int | dynCache性能perf执行时长,单位ms | [10, 10000] | +| l3Percent | map | dynCache控制中L3各级别对应水位(%)| / | +| .low=20 | int | L3 Cache低水位组控制线 | [10, 100] | +| .mid=30 | int | L3 Cache中水位组控制线 | [low, 100] | +| .high=50 | int | L3 Cache高水位组控制线 | [mid, 100]| +| memBandPercent | map | dynCache控制中MB各级别对应水位(%)|/| +| .low=10 | int | MB(访存带宽)低水位组控制线 | [10, 100]| +| .mid=30 | int | MB中水位组控制线 | [low, 100] | +| .high=50 | int | MB高水位组控制线 | [mid, 100] | + +### quotaTurbo + +`quotaTurbo`字段用于标识支持弹性限流技术(用户态)配置。 + +| 配置键[=默认值] | 类型 | 描述 | 可选值 | +| ----------------- | ------ | -------------------------------- | -------------------- | +| highWaterMark=60 | int | CPU负载的高水位值 |\[0,警戒水位) | +| alarmWaterMark=80 | int | CPU负载的警戒水位 | (高水位,100\] | +| syncInterval=100 | int | 触发容器quota值更新的间隔(单位:毫秒) | [100,10000] | + +### ioCost + +`ioCost`字段用于标识支持iocost对IO权重控制特性配置。其类型为数组,数组中的每一个元素由节点名称`nodeName`和设备参数数组`config`组成。 + +| 配置键 | 类型 | 描述 | 可选值 | +| ----------------- | ------ | -------------------------------- | -------------------- | +| nodeName | string | 节点名称 | kubernetes中节点名称 | +| config | 数组 | 单个设备的配置信息 | / | + +单个块设备配置`config`参数: + +| 配置键[=默认值] | 类型 | 描述 | 可选值 | +| --------------- | ------ | --------------------------------------------- | -------------- | +| dev | string | 块设备名称,仅支持物理设备 | / | +| model | string | iocost模型名 | linear | +| param | / | 设备参数,根据不同模型有不同参数 | / | + +模型为linear时,`param`字段支持如下参数: + +| 配置键[=默认值] | 类型 | 描述 | 可选值 | +| --------------- | ---- | ---- | ------ | +|rbps | int64 | 块设备最大读带宽 | (0, $2^{63}$) | +| rseqiops | int64 | 块设备最大顺序读iop | (0, $2^{63}$) | +| rrandiops | int64 | 块设备最大随机读iops | (0, $2^{63}$) | +| wbps | int64 | 块设备最大写带宽 | (0, $2^{63}$) | +| wseqiops | int64 | 块设备最大顺序写iops | (0, $2^{63}$) | +| wrandiops | int64 | 块设备最大随机写iops | (0, $2^{63}$) | + +### psi + +`psi`字段用于标识基于psi指标的干扰检测特性配置。目前,psi特性支持监测CPU、内存和I/O资源,用户可以按需配置该字段,单独或组合监测资源的PSI取值。 + +| 配置键[=默认值] | 类型 | 描述 | 可选值 | +| --------------- | ---------- | -------------------------------- | ----------- | +| interval=10 |int|psi指标监测间隔(单位:秒)| [10,30]| +| resource=[] | string数组 | 资源类型,声明何种资源需要被访问 | cpu, memory, io | +| avg10Threshold=5.0 | float | psi some类型资源平均10s内的压制百分比阈值(单位:%),超过该阈值则驱逐离线业务 | [5.0,100]| + +### CPU驱逐水位线控制 + +`cpuevict`字段用于标识CPU驱逐水位线控制特性配置。该特性依照指定采样间隔采集节点CPU利用率,并统计指定窗口内的CPU平均利用率。若CPU平均利用率大于驱逐水位线,则驱逐离线Pod。一旦rubik驱逐离线Pod,则在冷却时间内不再驱逐Pod。 + +| 配置键[=默认值] | 类型 | 描述 | 可选值 | +| --------------- | ---------- | -------------------------------- | ----------- | +| threshold=60 | int | 窗口期内平均CPU利用率的阈值(%),超过该阈值,则驱逐离线Pod | [1,99]| +| interval=1 | int | 节点CPU利用率采集间隔(s) | [1, 3600] | +| windows=2 | int | 节点平均CPU利用率的窗口时间(s)。窗口必须大于interval。若未设置windows,则windows设置为interval的两倍 | [1, 3600]| +| cooldown=20 | int | 冷却时间(s),两次驱逐之间至少需要间隔冷却时间 | [1, 9223372036854775806]| + +### 内存驱逐水位线控制 + +`memoryevict`字段用于标识内存驱逐水位线控制特性配置。该特性依照指定采样间隔采集节点内存利用率。若节点内存利用率大于驱逐水位线,则驱逐离线Pod。一旦rubik驱逐离线Pod,则在冷却时间内不再驱逐Pod。 + +| 配置键[=默认值] | 类型 | 描述 | 可选值 | +| --------------- | ---------- | -------------------------------- | ----------- | +| threshold | int | 内存利用率的阈值(%),超过该阈值,则驱逐离线Pod。若不指定该值,则无法使用本功能。 | [1,99]| +| interval=1 | int | 节点CPU利用率采集间隔(s) | [1, 3600] | +| cooldown=4 | int | 冷却时间(s),两次驱逐之间至少需要间隔冷却时间 | [1, 9223372036854775806]| diff --git a/docs/zh/cloud/hybrid_deployment/rubik/example_of_isolation_for_hybrid_deployed_services.md b/docs/zh/cloud/hybrid_deployment/rubik/example_of_isolation_for_hybrid_deployed_services.md new file mode 100644 index 0000000000000000000000000000000000000000..531a3a7b03330bf638ae40dee610cd04191232fe --- /dev/null +++ b/docs/zh/cloud/hybrid_deployment/rubik/example_of_isolation_for_hybrid_deployed_services.md @@ -0,0 +1,230 @@ +# 混部隔离示例 + +## 环境准备 + +查看内核是否支持混部隔离功能。 + +```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.325 + API version: 1.39 + Go version: go1.17.3 + Git commit: ce4ae23 + Built: Mon Jun 26 12:56:54 2023 + OS/Arch: linux/arm64 + Experimental: false + +Server: + Engine: + Version: 18.09.0 + EulerVersion: 18.09.0.325 + API version: 1.39 (minimum version 1.12) + Go version: go1.17.3 + Git commit: ce4ae23 + Built: Mon Jun 26 12:56:10 2023 + OS/Arch: linux/arm64 + 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 launched." +} + +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/zh/cloud/hybrid_deployment/rubik/feature_introduction.md b/docs/zh/cloud/hybrid_deployment/rubik/feature_introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..54a0e95b263907e87b5a5cfc9d54119aee281cf9 --- /dev/null +++ b/docs/zh/cloud/hybrid_deployment/rubik/feature_introduction.md @@ -0,0 +1,510 @@ +# 特性介绍 + +## preemption 绝对抢占 + +rubik支持业务优先级配置,针对在离线业务混合部署的场景,确保在线业务相对离线业务的资源抢占。目前仅支持CPU资源和内存资源。 + +使用该特性,用户需开启rubik的绝对抢占特性。 + +```yaml +... + "agent": { + "enabledFeatures": [ + "preemption" + ] + }, + "preemption": { + "resource": [ + "cpu", + "memory" + ] + } +... +``` + +配置参数详见[配置文档](./configuration.md#preemption)。 + +同时,用户需要在pod的yaml注解中增加`volcano.sh/preemptable`字段来指定业务优先级。业务优先级配置示例如下: + +```yaml +annotations: + volcano.sh/preemptable: true +``` + +> [!NOTE]说明 +> +> 在rubik中,所有特性均通过识别`volcano.sh/preemptable`注解作为业务在离线标志。true代表业务为离线业务,false代表业务为在线业务。 + +### CPU绝对抢占 + +针对在离线业务混合部署的场景,确保在线业务相对离线业务的CPU资源抢占。 + +**前置条件** + +- 内核支持针对cgroup的cpu优先级配置,cpu子系统存在接口`cpu.qos_level`。建议使用内核版本openEuler-22.03+。 + +**内核接口** + +- /sys/fs/cgroup/cpu 目录下容器的 cgroup 中,如`/sys/fs/cgroup/cpu/kubepods/burstable//`目录。 +- cpu.qos_level:开启 CPU 优先级配置,默认值为 0, 有效值为 0 和-1。 + - 0:标识为在线业务。 + - -1:标识为离线业务。 + +### 内存绝对抢占 + +针对在离线业务混合部署的场景,确保系统内存不足时优先杀死离线业务。 + +**前置条件** + +- 内核支持针对cgroup的memory优先级配置,memory子系统存在接口`memory.qos_level`。建议使用内核版本openEuler-22.03+。 +- 开启内存优先级支持: `echo 1 > /proc/sys/vm/memcg_qos_enable` + +**内核接口** + +- /proc/sys/vm/memcg_qos_enable:开启内存优先级特性,默认值为 0,有效值为 0 和 1。开启命令为:`echo 1 > /proc/sys/vm/memcg_qos_enable`。 + - 0:表示关闭特性。 + - 1:表示开启特性。 + +- /sys/fs/cgroup/memory 目录下容器的 cgroup 中,如`/sys/fs/cgroup/memory/kubepods/burstable//`目录 + - memory.qos_level:开启内存优先级配置,默认值为 0,有效值为 0 和-1。 + - 0:标识为在线业务。 + - -1:标识为离线业务。 + +## dynCache 访存带宽和LLC限制 + +rubik 支持业务的 Pod 访存带宽(memory bandwidth)和 LLC(Last Level Cache)限制,通过限制离线业务的访存带宽/LLC 使用,减少其对在线业务的干扰。 + +**前置条件**: + +- cache/访存限制功能仅支持物理机,不支持虚拟机。 + - X86 物理机,需要 OS 支持且开启 intel RDT 的 CAT 和 MBA 功能,内核启动项 cmdline 需要添加`rdt=l3cat,mba` + - ARM 物理机,需要 OS 支持且开启 mpam 功能,内核启动项需要添加`mpam=acpi`。 +- 由于内核限制,RDT mode 当前不支持 pseudo-locksetup 模式。 +- 用户需手动挂载目录`/sys/fs/resctrl`。 rubik 需要读取和设置`/sys/fs/resctrl` 目录下的文件,该目录需在 rubik 启动前挂载,且需保障在 rubik 运行过程中不被卸载。 +- rubik运行依赖SYS_ADMIN权限. 设置主机`/sys/fs/resctrl` 目录下的文件需要 rubik 容器被赋有 SYS_ADMIN 权限。 +- rubik 需要获取业务容器进程在主机上的 pid,所以 rubik 容器需与主机共享 pid namespace。 + +**rubik rdt 控制组**: + +rubik 在 RDT resctrl 目录(默认为 /sys/fs/resctrl)下创建 5 个控制组,分别为 rubik_max、rubik_high、rubik_middle、rubik_low、rubik_dynamic。rubik 启动后,将水位线写入对应控制组的 schemata。其中,low、middle、high 的水位线可在 dynCache 中配置;max 控制组为默认最大值,dynamic 控制组初始水位线和 low 控制组一致。 + +**rubik dynamic 控制组**: + +当存在 level 为 dynamic 的离线 Pod 时,rubik 通过采集当前节点在线业务 Pod 的 cache miss 和 llc miss 指标,调整 rubik_dynamic 控制组的水位线,实现对 dynamic 控制组内离线应用 Pod 的动态控制。 + +### 为Pod设置访存带宽和LLC限制 + +rubik支持两种方式为业务Pod配置访存带宽和LLC控制组: + +- 全局方式 + 用户可在rubik的全局参数中配置`defaultLimitMode`字段,rubik会自动为离线业务Pod(即绝对抢占特性中的注解`volcano.sh/preemptable`)配置控制组。 + - 取值为`static`时,pod将被加入到`rubik_max`控制组。 + - 取值为`dynamic`时,pod将被加入到`rubik_dynamic`控制组。 + +- 手动指定 + 用户可手动通过为业务Pod增加注解`volcano.sh/cache-limit`设置其 cache level, 并被加入到指定的控制组中。如下列配置的pod将被加入rubik_low控制组: + + ```yaml + annotations: + volcano.sh/cache-limit: "low" + ``` + +> [!NOTE]说明 +> +> - cache限制只针对离线业务。 +> +> - 手动指定注解优先于全局方式。即,若用户在rubik的全局参数中配置了`defaultLimitMode`字段,并且在业务 Pod yaml 中指定了cache level,则dynCache限制将以Pod yaml中的注解为准。 + +### dynCache 内核接口 + +- /sys/fs/resctrl: 在该目录下创建 5 个控制组目录,并修改其 schemata 和 tasks 文件。 + +### dynCache 配置详解 + +dynCache 功能相关的配置如下: + +```json +"agent": { + "enabledFeatures": [ + "dynCache" + ] +}, +"dynCache": { + "defaultLimitMode": "static", + "adjustInterval": 1000, + "perfDuration": 1000, + "l3Percent": { + "low": 20, + "mid": 30, + "high": 50 + }, + "memBandPercent": { + "low": 10, + "mid": 30, + "high": 50 + } +} +``` + +配置参数详见[配置文档](./configuration.md#dyncache)。 + +- l3Percent 和 memBandPercent: + + 通过 l3Percent 和 memBandPercent 配置 low, mid, high 控制组的水位线。 + + 比如当环境的`rdt bitmask=fffff, numa=2`时,rubik_low 的控制组将根据 l3Percent low=20 和 memBandPercent low=10 两个参数,将为/sys/fs/resctrl/rubik_low 控制组配置: + + ```bash + L3:0=f;1=f + MB:0=10;1=10 + ``` + +- defaultLimitMode: + + 如果离线 Pod 未指定`volcano.sh/cache-limit`注解,将根据 dynCache 的 defaultLimitMode 来决定 Pod 将被加入哪个控制组。 +- adjustInterval: + + dynCache 动态调整 rubik_dynamic 控制组的间隔时间,单位 ms,默认 1000ms。 +- perfDuration: + + dynCache 性能 perf 执行时长,单位 ms,默认 1000ms。 + +### dynCache 注意事项 + +- dynCache 仅针对离线 Pod,对在线业务不生效。 +- 若业务容器运行过程中被手动重启(容器 ID 不变但容器进程 PID 变化),针对该容器的 dynCache 无法生效。 +- 业务容器启动并已设置 dynCache 级别后,不支持对其限制级别进行修改。 +- 动态限制组的调控灵敏度受到 rubik 配置文件内 adjustInterval、perfDuration 值以及节点在线业务 Pod 数量的影响,每次调整(若干扰检测结果为需要调整)间隔在区间[adjustInterval+perfDuration, adjustInterval+perfDuration*Pod 数量]内波动,用户可根据灵敏度需求调整配置项。 + +## dynMemory 内存异步分级回收 + +rubik 中支持多种内存策略。针对不同场景使用不同的内存分配方案,以解决多场景内存分配。目前仅支持fssr策略。 + +### fssr 策略 + +fssr策略是基于内核 cgroup 的动态水位线快压制慢恢复策略。memory.high 是内核提供的 memcg 级的水位线接口,rubik 动态检测内存压力,动态调整离线应用的 memory.high 上限,实现对离线业务的内存压制,保障在线业务的服务质量。 + +其核心为: + +- rubik启动时计算预留内存,默认为总内存的10%,如果总内存的10%超过10G,则为10G。 +- 配置离线容器的cgroup级别水位线,内核提供`memory.high`和`memory.high_async_ratio`两个接口,分别配置cgroup的软上限和警戒水位线。启动rubik时默认配置`memory.high`为`total_memory`(总内存)`*`80%。 +- 获取剩余内存free_memory。 +- free_memory小于预留内存reserved_memory时降低离线的memory.high,每次降低总内存的10%,total_memory`*`10%。 +- 持续一分钟free_memory>2`*`reserved_memory时提高离线的memory.high,每次提升总内存的1%,total_memory`*`1%。 + +**内核接口** + +- memory.high + +### dynMemory 配置详解 + +rubik 提供 dynMemory 的指定策略,在`dynMemory`中 + +```json +"dynMemory": { + "policy": "fssr" +} +``` + +- policy 为 memory 的策略名称,支持 fssr 选项。 + +## 支持弹性限流 + +为有效解决由业务CPU限流导致QoS下降的问题,rubik容器提供了弹性限流功能,允许容器使用额外的CPU资源,从而保证业务的平稳运行。弹性限流方案包括内核态和用户态配置两种。二者不可同时使用。 + +用户态通过Linux内核提供的`CFS bandwidth control`能力实现,在保障整机负载水位安全稳定及不影响其他业务运行的前提下,通过双水位机制允许业务容器自适应调整CPU限制,缓解CPU资源瓶颈,提高业务的运行性能。 + +内核态通过Linux内核提供的`CPU burst`能力,允许容器短时间内突破其cpu使用限制。内核态配置需要用户手动设置和修改每个pod的burst值的大小,rubik不作自适应调整。 + +### quotaTurbo 用户态解决方案 + +用户手动为需要自适应调整CPU限额的业务Pod指定“volcano.sh/quota-turbo="true"”注解,(仅针对限额Pod生效,即yaml中指定CPULimit)。 +弹性限流用户态策略根据当前整机CPU负载和容器运行情况定时调整白名单容器的CPU quota,并在启停rubik时自动检验并恢复全部容器的quota值 (本节描述的CPU quota指容器当前的cpu.cfs_quota_us参数)。调整策略包括: + +1. 整机CPU负载低于警戒水位时,若白名单容器在当前周期受到CPU压制,则rubik按照压制情况缓慢提升容器CPU quota。单轮容器Quota提升总量最多不超过当前节点总CPU quota的1%。 +2. 整机CPU负载高于高水位时,若白名单容器在当前周期未受到CPU压制,则rubik依据水位慢速回调容器quota值。 +3. 整机CPU负载高于警戒水位时,若白名单容器当前Quota值超过配置值,则rubik快速回落所有容器CPU quota值,尽力保证负载低于警戒水位。 +4. 容器最大可调整CPU quota不超过2倍用户配置值(例如Pod yaml中指定CPUlimit参数),但不应小于用户配置值。 +5. 容器在60个同步间隔时间内的整体CPU利用率不得超过用户配置值。 +6. 若节点在1分钟内整体 CPU 利用率超过10%,则本轮不提升容器配额。 + +**内核接口** + +/sys/fs/cgroup/cpu 目录下容器的 cgroup 中,如`/sys/fs/cgroup/cpu,cpuacct/kubepods/burstable//`目录,涉及下列文件中: + +- cpu.cfs_quota_us +- cpu.cfs_period_us +- cpu.stat + +#### quotaTurbo配置详解 + +quotaTurbo 功能相关的配置如下: + +```json +"agent": { + "enabledFeatures": [ + "quotaTurbo" + ] + }, +"quotaTurbo": { + "highWaterMark": 60, + "alarmWaterMark": 80, + "syncInterval": 100 +} +``` + +配置参数详见[配置文档](./configuration.md#quotaturbo)。 + +- highWaterMark是CPU负载的高水位值。 +- alarmWaterMark是CPU负载的警戒水位值。 +- syncInterval是触发容器quota值更新的间隔(单位:毫秒)。 + +用户手动为需要业务Pod指定`volcano.sh/quota-turbo="true"`注解。示例如下: + +```yaml +metadata: + annotations: + # true表示列入quotaturbo特性的白名单中 + volcano.sh/quota-turbo : "true" +``` + +### quotaBurst 内核态解决方案 + +quotaBurst通过配置容器的`cpu.cfs_burst_us`内核接口,允许容器在其 cpu 使用量低于 quota 时累积 cpu 资源,并在 cpu 使用量超过 quota 时,使用容器累积的 cpu 资源。 + +**内核接口** + +/sys/fs/cgroup/cpu 目录下容器的 cgroup 中,如`/sys/fs/cgroup/cpu/kubepods/burstable//`目录,注解的值将被写入下列文件中: + +- cpu.cfs_burst_us + +> [!NOTE]说明 +> +> 内核态通过内核接口cpu.cfs_burst_us实现。支持内核态配置需要确认cgroup的cpu子系统目录下存在cpu.cfs_burst_us文件,其值约束如下: +> +> - 当cpu.cfs_quota_us的值不为-1时,需满足cfs_burst_us + cfs_quota_us <= $2^{44}$-1 且 cfs_burst_us <= cfs_quota_us。 +> - 当cpu.cfs_quota_us的值为-1时,CPU burst功能不生效,cfs_burst_us默认为0,不支持配置其他任何值。 + +#### quotaBurst配置详解 + +quotaBurst 功能相关的配置如下: + +```json +"agent": { + "enabledFeatures": [ + "quotaBurst" + ] +} +``` + +用户手动为需要业务Pod指定`volcano.sh/quota-burst-time`注解,或者在 Pod 运行期间通过 kubectl annotate 进行动态的修改。 + +- 创建时:在 yaml 文件中 + + ```yaml + metadata: + annotations: + # 默认单位是 microseconds + volcano.sh/quota-burst-time : "2000" + ``` + +- 修改注解: 可通过 kubectl annotate 动态修改,如: + + ```bash + kubectl annotate --overwrite pods volcano.sh/quota-burst-time='3000' + ``` + +### 约束限制 + +- 用户态通过CFS bandwidth control调整cpu.cfs_period_us和cpu.cfs_quota_us参数实现CPU带宽控制。因此用户态约束如下: + - 禁止第三方更改CFS bandwidth control相关参数(包括但不限于cpu.cfs_quota_us、cpu.cfs_period_us等文件),以避免未知错误。 + - 禁止与具有限制CPU资源功能的同类产品同时使用,否则导致用户态功能无法正常使用。 + - 若用户监控CFS bandwidth control相关指标,使用本特性可能会破坏监测指标的一致性。 +- 内核态约束如下: + - 用户应使用k8s接口设置pod的busrt值,禁止用户手动直接修改容器的cpu cgroup目录下的cpu.cfs_burst_us文件。 +- 禁止用户同时使能弹性限流用户态和内核态方案。 + +## ioCost 支持iocost对IO权重控制 + +为了有效解决由离线业务IO占用过高,导致在线业务QoS下降的问题,rubik容器提供了基于cgroup v1 iocost的IO权重控制功能。 +资料参见: +[iocost内核相关功能介绍](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html#io:~:text=correct%20memory%20ownership.-,IO,-%C2%B6)。 + +**前置条件** + +rubik 支持通过在 cgroup v1 下的 iocost 控制不同 Pod 的 io 权重分配。因此需要内核支持如下特性: + +- 内核支持 cgroup v1 blkcg iocost +- 内核支持 cgroup v1 writeback + +即在 blkcg 根系统文件下存在`blkio.cost.qos`和`blkio.cost.model`两个文件接口。实现方式和接口说明可以访问 openEuler 内核文档。 + +### ioCost实现说明 + +![iocost implement](./figures/iocost.PNG) + +步骤如下: + +- 部署 rubik 时,rubik 解析配置并设置 iocost 相关参数。 +- rubik 注册检测事件到 k8s api-server。 +- Pod 被部署时将 Pod 配置信息等回调到 rubik。 +- rubik 解析 Pod 配置信息,并根据 qos level 配置 Pod iocost 权重。 + +### ioCost配置说明 + +```json +"agent": { + "enabledFeatures": [ + "ioCost" + ] +} +"ioCost": [{ + "nodeName": "k8s-single", + "config": [ + { + "dev": "sdb", + "enable": true, + "model": "linear", + "param": { + "rbps": 10000000, + "rseqiops": 10000000, + "rrandiops": 10000000, + "wbps": 10000000, + "wseqiops": 10000000, + "wrandiops": 10000000 + } + } + ] +}] +``` + +配置参数详见[配置文档](./configuration.md#iocost)。 + +> [!NOTE]说明 +> +> iocost linear 模型相关参数可以通过 iocost_coef_gen.py 脚本获取,可以从[此链接](https://github.com/torvalds/linux/blob/master/tools/cgroup/iocost_coef_gen.py)获得。 + +## PSI 支持基于PSI指标的干扰检测 + +rubik支持观察在线Pod的PSI指标判断当前在线业务的压力,并通过驱逐离线Pod、日志告警等手段预警。rubik以`some avg10`作为指标。它表示任一任务在10s内的平均阻塞时间占比。用户可按需选择对CPU、内存、IO资源进行监测,并设置相应阈值。若阻塞占比超过该阈值,则rubik按照一定策略驱逐离线Pod,释放相应资源。若在线Pod的CPU和内存利用率偏高,rubik会驱逐当前占用CPU资源/内存资源最多的离线业务。若离线业务I/O高,则会选择驱逐CPU资源占用最多的离线业务。 + +在离线业务由注解`volcano.sh/preemptable="true"/"false"`标识。 + +```yaml +annotations: + volcano.sh/preemptable: true +``` + +**前置条件** + +rubik 依赖于 cgroup v1 下的 psi 特性。openEuler 2203及以上版本支持psi cgroup v1接口。 +通过如下方法查看当前内核是否开启cgroup v1的psi接口: + +```bash +cat /proc/cmdline | grep "psi=1 psi_v1=1" +``` + +若无,则为内核启动命令行新增参数: + +```bash +# 查看内核版本号 +uname -a +# 配置内核的boot文件 +grubby --update-kernel="$(grubby --default-kernel)" --args="psi=1 psi_v1=1" +# 重启 +reboot +``` + +**内核接口** + +/sys/fs/cgroup/cpuacct 目录下容器的 cgroup 中,如`/sys/fs/cgroup/cpu,cpuacct/kubepods/burstable//`目录,涉及下列文件中: + +- cpu.pressure +- memory.pressure +- io.pressure + +### psi配置说明 + +```json +"agent": { + "enabledFeatures": [ + "psi" + ] +} +"psi": { + "interval": 10, + "resource": [ + "cpu", + "memory", + "io" + ], + "avg10Threshold": 5.0 +} +``` + +配置参数详见[配置文档](./configuration.md#psi)。 + +## CPU驱逐水位线控制 + +rubik支持通过根据节点CPU利用率驱逐离线Pod从而避免节点CPU资源过载。用户可以配置CPU驱逐水位线,rubik会统计指定窗口期间节点的平均CPU利用率。若窗口期内平均CPU利用率大于CPU驱逐水位线,则rubik则驱逐资源利用率高且运行时间较短的离线Pod,释放相应资源。 + +> [!NOTE]说明 +> +> 在离线业务由注解`volcano.sh/preemptable="true"/"false"`标识。 +> +> ```yaml +> annotations: +> volcano.sh/preemptable: true +> ``` + +**配置说明** + +```json +{ + "agent": { + "enabledFeatures": [ + "cpuevict" + ] + } + "cpuevict": { + "threshold": 60, + "interval": 1, + "windows": 2, + "cooldown": 20 + } +} +``` + +配置参数详见[配置文档](./configuration.md#cpu驱逐水位线控制)。 + +## 内存驱逐水位线控制 + +rubik支持通过根据节点内存利用率驱逐离线Pod从而避免节点内存资源过载。用户可以配置内存驱逐水位线。若节点内存利用率大于内存驱逐水位线,则rubik则驱逐资源利用率高且运行时间较短的离线Pod,释放相应资源。 + +> [!NOTE]说明 +> +> 在离线业务由注解`volcano.sh/preemptable="true"/"false"`标识。 +> +> ```yaml +> annotations: +> volcano.sh/preemptable: true +> ``` + +**配置说明** + +```json +{ + "agent": { + "enabledFeatures": [ + "memoryevict" + ] + } + "memoryevict": { + "threshold": 60, + "interval": 1, + "cooldown": 4 + } +} +``` + +配置参数详见[配置文档](./configuration.md#内存驱逐水位线控制)。 diff --git a/docs/zh/cloud/hybrid_deployment/rubik/figures/icon-note.gif b/docs/zh/cloud/hybrid_deployment/rubik/figures/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..eebb838c275843dfaf5b402c550e64eb887c1035 Binary files /dev/null and b/docs/zh/cloud/hybrid_deployment/rubik/figures/icon-note.gif differ diff --git a/docs/zh/cloud/hybrid_deployment/rubik/figures/iocost.PNG b/docs/zh/cloud/hybrid_deployment/rubik/figures/iocost.PNG new file mode 100644 index 0000000000000000000000000000000000000000..c3eae863ad15d79d7e36c44799fc4dc946e8ca26 Binary files /dev/null and b/docs/zh/cloud/hybrid_deployment/rubik/figures/iocost.PNG differ diff --git a/docs/zh/cloud/hybrid_deployment/rubik/installation_and_deployment.md b/docs/zh/cloud/hybrid_deployment/rubik/installation_and_deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..ca2514fca6af45dc99952068bdab5fddf0e3215c --- /dev/null +++ b/docs/zh/cloud/hybrid_deployment/rubik/installation_and_deployment.md @@ -0,0 +1,156 @@ +# 安装与部署 + +## 概述 + +本章节主要介绍 rubik 组件的安装以及部署方式,以openEuler 24.03-LTS-SP1版本为例进行部署。 + +## 软硬件要求 + +### 硬件要求 + +* 当前仅支持 x86、aarch64 架构。 +* rubik 磁盘使用需求:配额 1GB 及以上。 +* rubik 内存使用需求:配额 100MB 及以上。 + +### 软件要求 + +* 操作系统:openEuler 24.03-LTS-SP1。 +* 内核:openEuler 24.03-LTS-SP1 版本内核。 + +### 环境准备 + +* 安装 openEuler 系统。 +* 安装并部署 kubernetes。 +* 安装 docker 或 containerd 容器引擎。 + +## 安装 rubik + +rubik 以`DaemonSet`形式部署在 k8s 的每一个节点上,故需要在每一个节点上使用以下步骤安装 rubik rpm 包。 + +1. 配置 yum 源:rubik组件位于openEuler EPOL源中,以openEuler 24.03-LTS-SP1版本为例,参考如下: + + ```sh + # openEuler 24.03-LTS-SP1 官方发布源 + name=openEuler24.03-LTS-SP1 + baseurl=https://repo.openeuler.org/openEuler-24.03-LTS-SP1/everything/$basearch/ + enabled=1 + gpgcheck=1 + gpgkey=https://repo.openeuler.org/openEuler-24.03-LTS-SP1/everything/$basearch/RPM-GPG-KEY-openEuler + ``` + + ```sh + # openEuler 24.03-LTS-SP1:Epol 官方发布源 + name=openEuler24.03-LTS-SP1-Epol + baseurl=https://repo.openeuler.org/openEuler-24.03-LTS-SP1/EPOL/$basearch/ + enabled=1 + gpgcheck=1 + gpgkey=https://repo.openeuler.org/openEuler-24.03-LTS-SP1/everything/$basearch/RPM-GPG-KEY-openEuler + ``` + +2. 使用 root 权限安装 rubik: + + ```shell + sudo yum install -y rubik + ``` + +> [!NOTE]说明 +> +> rubik 工具相关文件会安装在/var/lib/rubik 目录下。 + +## 部署 rubik + +rubik 以容器形式运行在混合部署场景下的 k8s 集群中,用于对不同优先级业务进行资源隔离和限制,避免离线业务对在线业务产生干扰,在提高资源总体利用率的同时保障在线业务的服务质量。当前 rubik 支持对 CPU、内存资源进行隔离和限制等特性,需配合 openEuler 24.03-LTS-SP1 版本的内核使用。若用户想要开启内存优先级特性(即针对不同优先级业务实现内存资源的分级),需要通过设置/proc/sys/vm/memcg_qos_enable 开关,有效值为 0 和 1,其中 0 为默认值表示关闭特性,1 表示开启特性。 + +```bash +sudo echo 1 > /proc/sys/vm/memcg_qos_enable +``` + +### 部署 rubik daemonset + +1. 构建rubik镜像:使用`/var/lib/rubik/build_rubik_image.sh`脚本自动构建或者直接使用 docker容器引擎构建 rubik 镜像。由于 rubik 以 daemonSet 形式部署,故每一个节点都需要 rubik 镜像。用户可以在一个节点构建镜像后使用 docker save/load 功能将 rubik 镜像 load 到 k8s 的每一个节点,也可以在各节点上都构建一遍 rubik 镜像。以 docker 为例,其构建命令如下: + + ```sh + docker build -f /var/lib/rubik/Dockerfile -t rubik:2.0.1-2 . + ``` + +2. 在 k8s master 节点,修改`/var/lib/rubik/rubik-daemonset.yaml`文件中的 rubik 镜像名,与上一步构建出来的镜像名保持一致。 + + ```yaml + ... + containers: + - name: rubik-agent + image: rubik_image_name_and_tag # 此处镜像名需与上一步构建的 rubik 镜像名一致 + imagePullPolicy: IfNotPresent + ... + ``` + +3. 在 k8s master 节点,使用 kubectl 命令部署 rubik daemonset,rubik 会自动被部署在 k8s 的所有节点: + + ```sh + kubectl apply -f /var/lib/rubik/rubik-daemonset.yaml + ``` + +4. 使用`kubectl get pods -A`命令查看 rubik 是否已部署到集群每一个节点上(rubik-agent 数量与节点数量相同且均为 Running 状态): + + ```sh + [root@localhost rubik]# kubectl get pods -A | grep rubik + 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 实现。以下介绍几个常见配置,其他配置详见 [配置文档](./configuration.md)。 + +### Pod 绝对抢占特性 + +用户在开启了 rubik 绝对抢占特性后,仅需在部署业务 Pod 时在 yaml 中通过 annotation 指定其优先级。部署后 rubik 会自动感知当前节点 Pod 的创建与更新,并根据用户配置的优先级设置 Pod 优先级。对于已经启动的或者更改注解的Pod, rubik 会自动更正Pod的优先级配置。 + +```yaml +... + "agent": { + "enabledFeatures": [ + "preemption" + ] + }, + "preemption": { + "resource": [ + "cpu", + "memory" + ] + } +... +``` + +> [!NOTE]说明 +> +> 优先级配置仅支持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" +``` diff --git a/docs/zh/cloud/hybrid_deployment/rubik/overview.md b/docs/zh/cloud/hybrid_deployment/rubik/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..99b4cd50047e36a9e67f7e500d143cd82b45305a --- /dev/null +++ b/docs/zh/cloud/hybrid_deployment/rubik/overview.md @@ -0,0 +1,27 @@ +# rubik 使用指南 + +## 概述 + +如何改善服务器资源利用率低的现状一直是业界公认的难题,随着云原生技术的发展,将在线(高优先级)、离线(低优先级)业务混合部署成为了当下提高资源利用率的有效手段。 + +rubik 容器调度在业务混合部署的场景下,根据 QoS 分级,对资源进行合理调度,从而实现在保障在线业务服务质量的前提下,大幅提升资源利用率。 + +rubik 当前支持如下特性: + +- [preemption 绝对抢占](./feature_introduction.md#preemption-绝对抢占) + - [CPU绝对抢占](./feature_introduction.md#cpu绝对抢占) + - [内存绝对抢占](./feature_introduction.md#内存绝对抢占) +- [dynCache 访存带宽和LLC限制](./feature_introduction.md#dyncache-访存带宽和llc限制) +- [dynMemory 内存异步分级回收](./feature_introduction.md#dynmemory-内存异步分级回收) +- [支持弹性限流](./feature_introduction.md#支持弹性限流) + - [quotaBurst 支持弹性限流内核态解决方案](./feature_introduction.md#quotaburst-内核态解决方案) + - [quotaTurbo 支持弹性限流用户态解决方案](./feature_introduction.md#quotaturbo-用户态解决方案) +- [ioCost 支持iocost对IO权重控制](./feature_introduction.md#iocost-支持iocost对io权重控制) +- [PSI 支持基于PSI指标的干扰检测](./feature_introduction.md#psi-支持基于psi指标的干扰检测) +- [CPU驱逐水位线控制](./feature_introduction.md#cpu驱逐水位线控制) +- [内存驱逐水位线控制](./feature_introduction.md#内存驱逐水位线控制) + +本文档适用于使用 openEuler 系统并希望了解和使用 rubik 的社区开发者、开源爱好者以及相关合作伙伴。使用人员需要具备以下经验和技能: + +- 熟悉 Linux 基本操作 +- 熟悉 kubernetes 和 docker/iSulad 基本操作 diff --git a/docs/zh/cloud/image_builder/.DS_Store b/docs/zh/cloud/image_builder/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 Binary files /dev/null and b/docs/zh/cloud/image_builder/.DS_Store differ diff --git a/docs/zh/cloud/image_builder/isula_build/_toc.yaml b/docs/zh/cloud/image_builder/isula_build/_toc.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f04f29c2e9abd15e65fd875697c32fd5032cd755 --- /dev/null +++ b/docs/zh/cloud/image_builder/isula_build/_toc.yaml @@ -0,0 +1,10 @@ +label: 容器镜像构建 +isManual: true +description: 支持通过Dockerfile文件快速构建容器镜像 +sections: + - label: 概述 + href: ./overview.md + - label: 使用指南 + href: ./isula_build.md + - label: 附录 + href: ./isula_build_appendix.md diff --git a/docs/zh/cloud/image_builder/isula_build/figures/isula-build_arch.png b/docs/zh/cloud/image_builder/isula_build/figures/isula-build_arch.png new file mode 100644 index 0000000000000000000000000000000000000000..911a9ae6f46988586ab49f15de282948f5470c37 Binary files /dev/null and b/docs/zh/cloud/image_builder/isula_build/figures/isula-build_arch.png differ diff --git a/docs/zh/cloud/image_builder/isula_build/isula_build.md b/docs/zh/cloud/image_builder/isula_build/isula_build.md new file mode 100644 index 0000000000000000000000000000000000000000..4863ee279bf62c838f86c5882637de87f05ad867 --- /dev/null +++ b/docs/zh/cloud/image_builder/isula_build/isula_build.md @@ -0,0 +1,935 @@ +# 安装 + +## 环境准备 + +为了确保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 + ``` + +> [!NOTE]说明 +> +> 安装完成后,需要手工启动isula-build服务。启动请参见[管理服务](#管理服务)。 + +# 配置与管理服务 + +## 配置服务 + +在安装完 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策略文件。当前不支持对其进行配置。 + +> [!NOTE]说明 +> +> * 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 服务端软件。 + +>[!NOTE]说明 +> +> 同一个节点上不可以同时启动多个 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。 + +>[!NOTE]说明 +> +> 当命令行启动参数中传递了与配置文件相同的配置选项时,优先使用命令行参数启动。 + +启动 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 +``` + +>[!NOTE]说明 +> +> 用户需保证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列表。 + +>[!NOTE]说明 +> +> * 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 +``` + +> [!NOTE]说明 +> +> * 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 +--------------------------------------- ----------- ----------------- ------------------------ ------------ +``` + +> [!NOTE]说明 +> +> 通过`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 +--------------------------------------- ----------- ----------------- ------------------------ ------------ +``` + +>[!NOTE]说明 +> +> 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 +``` + +>[!NOTE]说明 +> +> * 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] +``` + +>[!NOTE]说明 +> +> * 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 +``` + +>[!NOTE]说明 +> +> 推送镜像时,需要先登录对应的镜像仓库 + +## 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子命令。 +> [!NOTE]说明 +> +> 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 +``` + +> [!NOTE]说明 +> +> * 要求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 +``` + +> [!NOTE]说明 +> +> 要求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/reference/dockerfile/),但仍然和`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/zh/cloud/image_builder/isula_build/isula_build_appendix.md b/docs/zh/cloud/image_builder/isula_build/isula_build_appendix.md new file mode 100644 index 0000000000000000000000000000000000000000..35b0fbcc9e4ad33ac420f0706a2c35acdaefa780 --- /dev/null +++ b/docs/zh/cloud/image_builder/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/zh/cloud/image_builder/isula_build/overview.md b/docs/zh/cloud/image_builder/isula_build/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..8301d42c65af9bac8ea82ae5a573831edb80d2b4 --- /dev/null +++ b/docs/zh/cloud/image_builder/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) + +> [!NOTE]说明 +> +> 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/zh/cloud/kubeos/.DS_Store b/docs/zh/cloud/kubeos/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 Binary files /dev/null and b/docs/zh/cloud/kubeos/.DS_Store differ diff --git a/docs/zh/cloud/kubeos/kubeos/_toc.yaml b/docs/zh/cloud/kubeos/kubeos/_toc.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1a6979dc0ffe805123535c3ebbd854659413bccf --- /dev/null +++ b/docs/zh/cloud/kubeos/kubeos/_toc.yaml @@ -0,0 +1,14 @@ +label: 容器OS升级用户指南 +isManual: true +description: KubeOS是专为容器化业务涉及的轻量级操作系统,支持原子化升级,确保版本一致性,降低运维复杂性 +sections: + - 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 diff --git a/docs/zh/cloud/kubeos/kubeos/about_kubeos.md b/docs/zh/cloud/kubeos/kubeos/about_kubeos.md new file mode 100644 index 0000000000000000000000000000000000000000..f70e17fd3aa1cf96cb5c4715adeb6d29d8f2b047 --- /dev/null +++ b/docs/zh/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/zh/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/zh/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/zh/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/zh/cloud/kubeos/kubeos/figures/\345\256\271\345\231\250OS\346\236\266\346\236\204.png" "b/docs/zh/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/zh/cloud/kubeos/kubeos/figures/\345\256\271\345\231\250OS\346\236\266\346\236\204.png" differ diff --git a/docs/zh/cloud/kubeos/kubeos/installation_and_deployment.md b/docs/zh/cloud/kubeos/kubeos/installation_and_deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..029f71a6f3fb9d270a6b6559425e60b1b65e29e6 --- /dev/null +++ b/docs/zh/cloud/kubeos/kubeos/installation_and_deployment.md @@ -0,0 +1,181 @@ +# 安装与部署 + +本章介绍如何安装和部署容器 OS 升级工具。 + +## 软硬件要求 + +### 硬件要求 + +* 当前仅支持 x86和 AArch64 架构 + +### 软件要求 + +* 操作系统:openEuler 24.03-LTS-SP1 + +### 环境准备 + +* 安装 openEuler 系统,安装方法参考《[安装指南](../../../server/installation_upgrade/installation/installation_on_servers.md)》 +* 安装 qemu-img,bc,parted,tar,yum,docker,dosfstools + +## 安装容器OS升级工具 + +安装容器 OS 升级工具的操作步骤如下: + +1. 配置 openEuler 24.03-LTS-SP1 yum 源: + + ```sh + [openEuler24.03-LTS-SP1] # openEuler 24.03-LTS-SP1 官方发布源 + name=openEuler24.03-LTS-SP1 + baseurl=http://repo.openeuler.org/openEuler-24.03-LTS-SP1/everything/$basearch/ + enabled=1 + gpgcheck=1 + gpgkey=http://repo.openeuler.org/openEuler-24.03-LTS-SP1/everything/$basearch/RPM-GPG-KEY-openEuler + ``` + +2. 使用 root 帐户安装容器 OS 升级工具: + + ```shell + yum install KubeOS KubeOS-scripts -y + ``` + +> [!NOTE]说明 +> +> 容器 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示例如下 + + ```dockerfile + FROM your_baseimage + COPY ./bin/proxy /proxy + ENTRYPOINT ["/proxy"] + ``` + + ```dockerfile + 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镜像制作指导](./kubeos_image_creation.md)》。 +* 制作容器OS 镜像需要使用 root 权限。 +* 容器OS 镜像制作工具的 rpm 包源为 openEuler 具体版本的 everything 仓库和 EPOL 仓库。制作镜像时提供的 repo 文件中,yum 源建议同时配置 openEuler 具体版本的 everything 仓库和 EPOL 仓库。 +* 使用默认 rpmlist 制作的容器OS虚拟机镜像,默认保存在调用`kbimg`路径下的`scripts-auto`文件夹内,该分区至少有 25GiB 的剩余磁盘空间。 +* 制作容器 OS 镜像时,不支持用户自定义配置挂载文件。 + +#### 操作步骤 + +制作容器OS 虚拟机镜像使用 kbimg,命令详情请见《[容器OS镜像制作指导](./kubeos_image_creation.md)》。 + +制作容器OS 虚拟机镜像的步骤如下: + +1. 进入执行目录: + + ```shell + cd /opt/kubeOS/scripts + ``` + +2. 执行 kbming 制作容器OS,参考命令如下: + + ```shell + ./kbimg create -f ./kbimg.toml vm-img + ``` + + 容器 OS 镜像制作完成后,会在 /opt/kubeOS/scripts/scripts-auto 目录下生成: + + * raw格式的系统镜像system.img,system.img大小默认为20G,支持的根文件系统分区大小<2560MiB,持久化分区<15GB。 + * qcow2 格式的系统镜像 system.qcow2。 + * 可用于升级的根文件系统 kubeos.tar。 + + 制作出来的容器 OS 虚拟机镜像目前只能用于 CPU 架构为 x86 和 AArch64 的虚拟机场景,不支持 x86 架构的虚拟机使用 legacy 启动模式启动。 + +### 部署CRD,operator和proxy + +#### 注意事项 + +* 请先部署 Kubernetes 集群,部署方法参考[《openEuler 24.03-LTS-SP1 Kubernetes 集群部署指南》](../../cluster_deployment/kubernetes/overview.md)。 + +* 集群中准备进行升级的 Worker 节点的 OS 需要为使用上一节方式制作出来的容器 OS,如不是,请用 system.qcow2重新部署虚拟机,虚拟机部署请见[《openEuler 24.03-LTS-SP1 虚拟化用户指南》](../../../virtualization/virtualization_platform/virtualization/introduction_to_virtualization.md),Master节点目前不支持容器 OS 升级,请用openEuler 24.03-LTS-SP1部署Master节点。 +* 部署 OS 的 CRD(CustomResourceDefinition),os-operator,os-proxy 以及 RBAC (Role-based access control) 机制的 YAML 需要用户自行编写。 +* operator 和 proxy 部署在 kubernetes 集群中,operator 应部署为 deployment,proxy 应部署为daemonset。 +* 尽量部署好 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/zh/cloud/kubeos/kubeos/kubeos_image_creation.md b/docs/zh/cloud/kubeos/kubeos/kubeos_image_creation.md new file mode 100644 index 0000000000000000000000000000000000000000..ef33e989086a2975b6f8a88297ece8a030f04350 --- /dev/null +++ b/docs/zh/cloud/kubeos/kubeos/kubeos_image_creation.md @@ -0,0 +1,503 @@ +# 容器OS镜像制作指导 + +## 简介 + +kbimg是KubeOS部署和升级所需的镜像制作工具,可以使用kbimg制作KubeOS docker,虚拟机和物理机镜像。 + +## 命令介绍 + +### 命令格式 + +kbimg - CLI tool for generating various types of image for KubeOS + +```text +Usage: kbimg [OPTIONS] + +Commands: + create Create a new KubeOS image + help Print this message or the help of the given subcommand(s) + +Options: + -d, --debug Enable debug mode, generate the scripts without execution + -h, --help Print help + -V, --version Print version +``` + +kbimg-create - Create a new KubeOS image + +```text +Usage: kbimg create --file + +Arguments: + [possible values: vm-img, pxe-img, upgrade-img, admin-container] + +Options: + -f, --file Path to the toml configuration file + -h, --help Print help +``` + +### 配置文件说明 + +#### from_repo + +从 repo 创建升级容器镜像、虚拟机镜像或PXE物理机镜像 + + | 参数 | 描述 | + | --- | --- | + | agent_path | os-agent 二进制的路径 | + | legacy_bios | 目前仅支持设置为`false`,即UEFI引导 | + | repo_path | repo 文件的路径,repo 文件中配置制作镜像所需要的 yum 源 | + | root_passwd | root 用户密码,与/etc/shadow文件内密码格式一致,可使用`openssl passwd -6 -salt $(head -c18 /dev/urandom \| openssl base64)`命令生成 | + | version | KubeOS 镜像的版本,将写入/etc/os-release文件内作为OS标识 | + | rpmlist | 期望安装进镜像内的rpm包列表 | + | upgrade_img | [可选项]指定生成的升级容器镜像的镜像名(制作升级容器镜像必需) | + +#### admin_container + +制作admin运维容器 + + | 参数 | 描述 | + | --- | --- | + | hostshell | hostshell二进制路径,可在项目根目录下通过`make hostshell`编译 | + | img_name | 指定生成的容器镜像名 | + +#### pxe_config + +在制作PXE物理机镜像时,配置该参数用于PXE安装。制作PXE物理机镜像时必需。 + + | 参数 | 描述 | + | --- | --- | + | server_ip | 用于下载根文件系统 tar 包的 HTTP 服务器地址 | + | rootfs_name | 放置于 HTTP 服务器的文件系统 tar 包名称 | + | disk | 安装 KubeOS 系统的目标磁盘名 | + | route_ip | 配置目标机器网卡的路由 IP | + | dhcp | [可选项] 是否启用 DHCP 模式配置网络,默认为 false | + | local_ip | [可选项] 配置目标机器网卡的 IP,dhcp 为 false 时必需 | + | net_name | [可选项] 配置目标机器网卡名,dhcp 为 false 时必需 | + | netmask | [可选项] 配置目标机器网卡的子网掩码,dhcp 为 false 时必需 | + +**注意**:`pxe_config`下的配置参数无法进行校验,需要用户自行确认其正确性。 + +#### users + +[可选项] 添加用户 + + | 参数 | 描述 | + | --- | --- | + | name | 用户名 | + | passwd | 密码 | + | primary_groups | [可选项] 用户主组(默认为用户同名组) | + | groups | [可选项] 用户附加组 | + +**注意**:添加用户会默认创建用户同名组,配置用户附加组时,若组不存在会报错失败。若有特殊配置需求,用户可通过[chroot_script](#chroot_script)脚本自行实现。 + +#### copy_files + +[可选项] 拷贝文件到rootfs内指定目录 + + | 参数 | 描述 | + | --- | --- | + | dst | 目标路径 | + | src | 源文件路径 | + | create_dir | [可选项]拷贝前创建文件夹 | + +**注意**:拷贝文件无法保留权限,如果需要特殊权限,可借助[chroot_script](#chroot_script)脚本自行实现。 + +#### grub + +[可选项] grub配置,配置dm-verity时必需 + + | 参数 | 描述 | + | --- | --- | + | passwd | grub 明文密码 | + +#### systemd_service + +[可选项] 配置 systemd 服务开机自启 + + | 参数 | 描述 | + | --- | --- | + | name | systemd 服务名 | + +#### chroot_script + +[可选项] 自定义 chroot 脚本 + + | 参数 | 描述 | + | --- | --- | + | path | 脚本路径 | + | rm | [可选项]执行完毕后是否删除该脚本,配置`true`删除,`false`或空保留 | + +#### disk_partition + +[可选项] 自定义分区大小和镜像大小 + + | 参数 | 描述 | + | --- | --- | + | root | root分区大小, 单位为MiB,默认2560MiB | + | img_size | [可选项]镜像大小,单位为GB,默认20GB | + +#### persist_mkdir + +[可选项] persist 分区新建目录 + + | 参数 | 描述 | + | --- | --- | + | name | 目录名 | + +#### dm_verity + +[可选项] 制作启用dm-verity功能的虚拟机或升级镜像 + + | 参数 | 描述 | + | --- | --- | + | efi_key | efi明文口令 | + | grub_key | grub明文口令 | + | keys_dir |[可选项]可指定密钥文件夹,复用先前制作镜像创建的密钥 | + +## 使用说明 + +### 注意事项 + +* kbimg 执行需要 root 权限。 +* 当前仅支持 x86和 AArch64 架构使用。 +* 不支持并发执行。如果使用脚本`&`连续执行可能会出现异常情况。制作过程中碰到异常掉电或中断后无法清理环境时,可参考[异常退出清理方法](#异常退出清理方法)清理后重新制作。 +* 容器 OS 镜像制作工具的 rpm 包源为 openEuler 具体版本的 everything 仓库和 EPOL 仓库。制作镜像时提供的 repo 文件中,yum 源建议同时配置 openEuler 具体版本的 everything 仓库和 EPOL 仓库。 +* dm-verity使用说明: + * 仅支持虚拟机场景,暂不支持物理机环境。 + * 不支持通过 HTTP/HTTPS 服务器下载升级镜像进行系统升级。仅支持从容器镜像仓库下载升级镜像进行升级。 + * 启动虚拟机时,必须配置使用 virtio 类型设备。 + * 启用dm-verity功能的升级容器镜像不可用于升级未开启dm-verity的容器OS。同理,未启动dm-verity功能的升级容器镜像不可用于升级开启dm-verity功能的容器OS。在集群内,部分节点开启dm-verity功能,部分未开启,需要用户控制下发对应的升级镜像。 + * 制作升级容器镜像和虚拟机镜像时,推荐使用相同的密钥(配置`keys_dir`为先前制作镜像时创建的密钥文件路径。配置`efi_key`或`grub_key`一致不能保证密钥文件是一模一样的)。若密钥不一致,在切换备用分区时可能导致证书校验失败,从而无法启动系统。出现证书校验失败问题时,需要重新导入备用分区证书进行修复。 + +### KubeOS OCI 镜像制作 + +#### 注意事项 + +* 制作出的 OCI 镜像仅用于后续的虚拟机/物理机镜像升级使用,不支持启动容器。 +* 使用默认 rpmlist 进行容器OS镜像制作时所需磁盘空间至少为6G,若使用自定义 rpmlist 可能会超过6G。 + +#### 使用示例 + +* 配置文件示例 + +```toml +[from_repo] +agent_path = "./bin/rust/release/os-agent" +legacy_bios = false +repo_path = "/etc/yum.repos.d/openEuler.repo" +root_passwd = "$1$xyz$RdLyKTL32WEvK3lg8CXID0" # default passwd: openEuler12#$ +rpmlist = [ + "NetworkManager", + "cloud-init", + "conntrack-tools", + "containerd", + "containernetworking-plugins", + "cri-tools", + "dhcp", + "ebtables", + "ethtool", + "iptables", + "kernel", + "kubernetes-kubeadm", + "kubernetes-kubelet", + "openssh-server", + "passwd", + "rsyslog", + "socat", + "tar", + "vi", +] +upgrade_img = "kubeos-upgrade:v1" +version = "v1" +``` + +* 结果说明 + * 制作完成后,通过`docker images`查看制作出来的KubeOS容器镜像 + * update-boot.img/update-root.img/update-hash.img: 仅在dm-verity模式下生成,可忽略。 + +### KubeOS 虚拟机镜像制作 + +#### 注意事项 + +* 制作出来的容器 OS 虚拟机镜像目前只能用于 CPU 架构为 x86 和 AArch64 的虚拟机。 +* 容器 OS 目前不支持 x86 架构的虚拟机使用 legacy 启动模式启动。 +* 默认root密码为openEuler12#$ +* 使用默认rpmlist进行容器OS镜像制作时所需磁盘空间至少为25G,若使用自定义rpmlist可能会超过25G。 + +#### 使用示例 + +* 配置文件示例 + +```toml +[from_repo] +agent_path = "./bin/rust/release/os-agent" +legacy_bios = false +repo_path = "/etc/yum.repos.d/openEuler.repo" +root_passwd = "$1$xyz$RdLyKTL32WEvK3lg8CXID0" # default passwd: openEuler12#$ +rpmlist = [ + "NetworkManager", + "cloud-init", + "conntrack-tools", + "containerd", + "containernetworking-plugins", + "cri-tools", + "dhcp", + "ebtables", + "ethtool", + "iptables", + "kernel", + "kubernetes-kubeadm", + "kubernetes-kubelet", + "openssh-server", + "passwd", + "rsyslog", + "socat", + "tar", + "vi", +] +version = "v1" +``` + +* 结果说明 + 容器 OS 镜像制作完成后,会在 ./scripts-auto 目录下生成 + * system.qcow2: 用于启动虚拟机的qcow2 格式的系统镜像,大小默认为 20GiB,支持的根文件系统分区大小 \< 2560 MiB,持久化分区 \< 15GB。 + * system.img: 用于启动虚拟机的img 格式的系统镜像,大小默认为 20GiB,支持的根文件系统分区大小 < 2560 MiB,持久化分区 < 15GB。 + * kubeos.tar: 用于升级的根文件系统tar包。 + * update-boot.img/update-root.img/update-hash.img: 仅在dm-verity模式下生成,可忽略。 + +### KubeOS 物理机安装所需镜像及文件制作 + +#### 注意事项 + +* 制作出来的容器 OS 物理安装所需的镜像目前只能用于 CPU 架构为 x86 和 AArch64 的物理机安装。 +* `pxe_config`配置中指定的ip为安装时使用的临时ip,请在系统安装启动后请参考[《openEuler 24.03-LTS-SP1 管理员指南-配置网络》](../../../server/network/network_config/network_configuration.md)进行网络配置。 +* 不支持多个磁盘都安装KubeOS,可能会造成启动失败或挂载紊乱。 +* 容器OS 目前不支持 x86 架构的物理机使用 legacy 启动模式启动。 +* 使用默认rpmlist进行镜像制作时所需磁盘空间至少为5G,如自已定义 rpmlist 可能会超过5G。 +* PXE物理机镜像制作不支持dm-verity功能 +* 在 PXE 安装阶段,需要从 HTTP 服务器的根目录下载根分区 tar 包(tar包名称为toml配置文件中配置的名称)。请确保机器拥有足够的内存空间以存储根分区 tar 包及临时中间文件。 + +#### 使用示例 + +* 首先需要修改```kbimg.toml```中```pxe_config```的配置,对相关参数进行配置,详细参数可见[参数说明](#pxe_config),ip目前仅支持ipv4,配置示例如下 + + ```toml + [pxe_config] + dhcp = false + # rootfs file name + rootfs_name = "kubeos.tar" + # select the target disk to install kubeOS + disk = "/dev/vda" + # pxe server ip address where stores the rootfs on the http server + server_ip = "192.168.122.50" + # target machine ip + local_ip = "192.168.122.100" + # target machine route + route_ip = "192.168.122.1" + # target machine netmask + netmask = "255.255.255.0" + # target machine netDevice name + net_name = "eth0" + ``` + +* 如需进行DNS配置,请先自定义```resolv.conf```文件,并启用```copy_files```字段将配置文件拷贝到```/etc```目录 + + ```toml + [[copy_files]] + dst = "/etc" + src = "" + ``` + +* KubeOS物理机安装所需镜像制作,及pxe_config配置全示例 + + ```toml + [from_repo] + agent_path = "./bin/rust/release/os-agent" + legacy_bios = false + repo_path = "/etc/yum.repos.d/openEuler.repo" + root_passwd = "$1$xyz$RdLyKTL32WEvK3lg8CXID0" # default passwd: openEuler12#$ + rpmlist = [ + "NetworkManager", + "cloud-init", + "conntrack-tools", + "containerd", + "containernetworking-plugins", + "cri-tools", + "dhcp", + "ebtables", + "ethtool", + "iptables", + "kernel", + "kubernetes-kubeadm", + "kubernetes-kubelet", + "openssh-server", + "passwd", + "rsyslog", + "socat", + "tar", + "vi", + "coreutils", + "dosfstools", + "dracut", + "gawk", + "hwinfo", + "net-tools", + "parted", + ] + version = "v1" + + [pxe_config] + dhcp = true + rootfs_name = "kubeos.tar" + disk = "/dev/vda" + server_ip = "192.168.122.50" + route_ip = "192.168.122.1" + #local_ip = "192.168.1.100" + #netmask = "255.255.255.0" + #net_name = "eth0" + ``` + +* 结果说明 + * initramfs.img: 用于pxe启动用的 initramfs 镜像 + * kubeos.tar: pxe安装所用的根分区文件系统 + +## 附录 + +### 异常退出清理方法 + +1.若在使用`kbimg`制作镜像过程中,异常退出,无法清理环境,可使用如下方法进行清理: + + ```bash + function unmount_dir() { + local dir=$1 + if [ -L "${dir}" ] || [ -f "${dir}" ]; then + echo "${dir} is not a directory, please check it." + return 1 + fi + if [ ! -d "${dir}" ]; then + return 0 + fi + local real_dir=$(readlink -e "${dir}") + local mnts=$(awk '{print $2}' < /proc/mounts | grep "^${real_dir}" | sort -r) + for m in ${mnts}; do + echo "Unmount ${m}" + umount -f "${m}" || true + done + return 0 + } + ls -l ./scripts-auto/test.lock && rm -rf ./scripts-auto/test.lock + unmount_dir ./scripts-auto/rootfs/proc + unmount_dir ./scripts-auto/rootfs/sys + unmount_dir ./scripts-auto/rootfs/dev/pts + unmount_dir ./scripts-auto/rootfs/dev + unmount_dir ./scripts-auto/mnt/boot/grub2 + unmount_dir ./scripts-auto/mnt + rm -rf ./scripts-auto/rootfs ./scripts-auto/mnt + ``` + +2.如果执行以上命令仍然无法删除目录,可尝试先调用如下命令,再重新执行第一步的命令。 + + ```bash + fuser -kvm ./scripts-auto/rootfs + fuser -kvm ./scripts-auto/mnt + ``` + +### 详细toml配置文件示例 + +请根据需求和[配置文件说明](#配置文件说明),修改如下示例配置文件,生成所需镜像。 + +```toml +[from_repo] +agent_path = "./bin/rust/release/os-agent" +legacy_bios = false +repo_path = "/etc/yum.repos.d/openEuler.repo" +root_passwd = "$1$xyz$RdLyKTL32WEvK3lg8CXID0" # default passwd: openEuler12#$, use "openssl passwd -6 -salt $(head -c18 /dev/urandom | openssl base64)" to generate your passwd +rpmlist = [ + "NetworkManager", + "cloud-init", + "conntrack-tools", + "containerd", + "containernetworking-plugins", + "cri-tools", + "dhcp", + "ebtables", + "ethtool", + "iptables", + "kernel", + "kubernetes-kubeadm", + "kubernetes-kubelet", + "openssh-server", + "passwd", + "rsyslog", + "socat", + "tar", + "vi", + # Below packages are required for pxe-image. Uncomment them if you want to generate pxe-image. + # "coreutils", + # "dosfstools", + # "dracut", + # "gawk", + # "hwinfo", + # "net-tools", + # "parted", +] +upgrade_img = "kubeos-upgrade:v1" +version = "v1" + +# [admin_container] +# img_name = "kubeos-admin-container:v1" +# hostshell = "./bin/hostshell" + +# [pxe_config] +# dhcp = false +# disk = "/dev/vda" +# local_ip = "192.168.1.100" +# net_name = "eth0" +# netmask = "255.255.255.0" +# rootfs_name = "kubeos.tar" +# route_ip = "192.168.1.1" +# server_ip = "192.168.1.50" + +# [[users]] +# groups = ["admin", "wheel"] +# name = "foo" +# passwd = "foo" +# primary_group = "foo" + +# [[users]] +# groups = ["example"] +# name = "bar" +# passwd = "bar" + +# [[copy_files]] +# create_dir = "/root/test" +# dst = "/root/test/foo.txt" +# src = "/root/KubeOS/foo.txt" + +# [[copy_files]] +# dst = "/etc/bar.txt" +# src = "../bar.txt" + +# [grub] +# passwd = "foo" + +# [systemd_service] +# name = ["containerd", "kubelet"] + +# [chroot_script] +# path = "./my_chroot.sh" +# rm = true + +# [disk_partition] +# img_size = 30 # GB +# root = 3000 # MiB + +# [persist_mkdir] +# name = ["bar", "foo"] + +# [dm_verity] +# efi_key = "foo" +# grub_key = "bar" +# keys_dir = "./keys" +``` diff --git a/docs/zh/cloud/kubeos/kubeos/overview.md b/docs/zh/cloud/kubeos/kubeos/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..27e75e27e6fc717c2bb5558484f84f4e98703dcd --- /dev/null +++ b/docs/zh/cloud/kubeos/kubeos/overview.md @@ -0,0 +1,8 @@ +# 容器OS升级指南 + +本文档介绍基于openEuler系统的容器OS升级特性的安装部署和使用方法,容器OS升级是使OS可以通过标准扩展方式接入调度系统,通过调度系统管理集群内节点的OS的升级。 + +本文档适用于使用openEuler系统并希望了解和使用容器OS的社区开发者、开源爱好者以及相关合作伙伴。使用人员需要具备以下经验和技能: + +* 熟悉Linux基本操作。 +* 对kubernetes和docker有一定了解。 diff --git a/docs/zh/cloud/kubeos/kubeos/usage_instructions.md b/docs/zh/cloud/kubeos/kubeos/usage_instructions.md new file mode 100644 index 0000000000000000000000000000000000000000..1d95780b6ca5eb031443166bc222e2b166419c79 --- /dev/null +++ b/docs/zh/cloud/kubeos/kubeos/usage_instructions.md @@ -0,0 +1,601 @@ +# 使用方法 + +## 注意事项 + +* 公共注意事项 + * 仅支持虚拟机和物理机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.03-LTS-SP1 版本与历史版本不兼容。 + * 使用从http/https服务器下载升级镜像功能需要同步使用对应版本镜像制作工具。 + +* 配置注意事项 + * 用户自行指定配置内容,用户需保证配置内容安全可靠 ,尤其是持久化配置(kernel.sysctl.persist、grub.cmdline.current、grub.cmdline.next、kubernetes.kubelet、container.containerd、pam.limits),KubeOS不对参数有效性进行检验。 + * opstype=config时,若osversion与当前集群节点的OS版本不一致,配置不会进行。 + * 当前仅支持kernel参数临时配置(kernel.sysctl)、持久化配置(kernel.sysctl.persist)和grub cmdline配置(grub.cmdline.current和grub.cmdline.next)、kubelet配置(kubernetes.kubelet)、containerd配置(container.containerd)和pam limits配置(pam.limits)。 + * 持久化配置会写入persist持久化分区,升级重启后配置保留;kernel参数临时配置重启后不保留。 + * 配置grub.cmdline.current或grub.cmdline.next时,如为单个参数(非key=value格式参数),请指定key为该参数,value为空。 + * 进行配置删除(operation=delete)时,key=value形式的配置需保证key、value和实际配置一致。 + * 配置不支持回退,如需回退,请修改配置版本和配置内容,重新下发配置。 + * 配置出现错误,节点状态陷入config时,请将配置版本恢复成上一版本并重新下发配置,从而使节点恢复至idle状态。 但是请注意:出现错误前已经配置完成的参数无法恢复。 + * 在配置grub.cmdline.current或grub.cmdline.next时,若需要将已存在的“key=value”格式的参数更新为只有key无value格式,比如将“rd.info=0”更新成rd.info,需要先删除“key=value”,然后在下一次配置时,添加key。不支持直接更新或者更新删除动作在同一次完成。 + +## OS CR参数说明 + +在集群中创建类别为OS的定制对象,设置相应字段。类别OS来自于[安装和部署章节](./installation_and_deployment.md)创建的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 + + ``` yaml + 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' + ``` + +> [!NOTE]说明 +> +> 如果后续需要再次升级,与上面相同对 upgrade_v1alpha1_os.yaml 的 相应字段进行相应修改。 + +## 配置(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修改完成后执行更新命令,在集群中更新定制对象后,节点会根据配置的字段信息进行回退 + + ```shell + 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 + ``` + + * 在dm-verity模式下,grub.cmdline配置下发无效。 + + * 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 + ``` + +#### kubelet配置 + +* kubernetes.kubelet: 配置节点kubelet的配置文件中的参数,参数说明和约束如下: + * 仅支持```KubeletConfiguration```中的配置参数。 + * 节点kubelet配置文件需要为yaml格式的文件。 + * 如不指定configpath,默认配置文件路径为```/var/lib/kubelet/config.yaml```,并且需要注意的是配置文件的路径需要与kubelet启动时的```-- config```参数指定的路径一致才能生效,用户需保证配置文件路径有效。 + * kubelet配置的value参数类型支持为空/null、int、float、string、boolean和数组。当为数组时,数组元素允许重复,数组参数进行更新时会追加到已有数组中。如需修改数组中的元素,需要先删除数组,再新增数组来完成修改。 + * 如配置存在嵌套,则通过```'.'```连接嵌套的key值,例如如果修改如下yaml示例中```cacheAuthorizedTTL```参数为1s。 + + ```yaml + authorization: + mode: Webhook + webhook: + cacheAuthorizedTTL: 0s + ``` + + 参数配置示例如下: + + ```yaml + configs: + - model: kubernetes.kubelet + configpath: /etc/test.yaml + contents: + - key: authorization.webhook.cacheAuthorizedTTL + value: 1s + ``` + + * kubernetes.kubelet进行删除时,不对value与配置文件中的值进行比较。 + +#### containerd配置 + +* container.containerd: 配置节点上containerd的配置文件中的参数,参数说明和约束如下: + * containerd需要配置文件为toml格式,所以key为toml中该参数的表头.键名,例如希望修改如下toml示例中```no_shim```为true。 + + ```toml + [plugins."io.containerd.runtime.v1.linux"] + no_shim=false + runtime="runc" + runtime_root=" + ``` + + 参数配置示例如下: + + ```yaml + configs: + - model: container.containerd + configpath: /etc/test.toml + contents: + - key: plugins."io.containerd.runtime.v1.linux".no_shim + value: true + ``` + + * toml使用```.```分割键,os-agent识别时与toml保持一致,所以当键名中包含```.```时,该键名需要使用```""```,例如上例中的```"io.containerd.runtime.v1.linux"```为一个键 + * 如不指定configpath,默认配置文件路径为```/etc/containerd/config.toml```,用户需要保证配置文件路径有效。 + * container.conatainerd配置的key和value均不能为空,value参数类型支持int、float、string、boolean和数组。当为数组时,数组元素允许重复,数组参数进行更新时会追加到已有数组中。如需修改数组中的元素,需要先删除数组,再新增数组来完成修改。 + * container.containerd进行删除时,不对value与配置文件中的值进行比较。 + +#### Pam Limits配置 + +* pam.limits:配置节点上/etc/security/limits.conf文件 + * key为domain值,value的格式需要为type.item.value(limits.conf文件要求每行格式为:\ \ \ \),例如: + + ```yaml + configs: + - model: pam.limits + contents: + - key: ftp + value: soft.core.0 + ``` + + * 更新时,如不需要对type/item/value更新时,可以使用```_```,忽略对此参数的更新,但value必须为点隔的三段式,例如: + + ```yaml + configs: + - model: pam.limits + contents: + - key: ftp + value: hard._.1 + ``` + + * pam.limits新增时,value中不允许包含```_``` + * pam.limits删除时,会对value进行校验,当value与配置文件中的值不同时,删除失败 + * pam.limits配置的key和value均不能为空 diff --git a/docs/zh/cloud/nestos/nestos/_toc.yaml b/docs/zh/cloud/nestos/nestos/_toc.yaml new file mode 100644 index 0000000000000000000000000000000000000000..08b5a310a3ee82655bdd31747ac03d9582970f1a --- /dev/null +++ b/docs/zh/cloud/nestos/nestos/_toc.yaml @@ -0,0 +1,12 @@ +label: NestOS用户指南 +isManual: true +description: NestOS是为容器化设计的轻量级操作系统,采用双分区院子更新,确保安全可靠 +sections: + - label: 概述 + href: ./overview.md + - label: 安装与部署 + href: ./installation_and_deployment.md + - label: 使用方法 + href: ./usage.md + - label: 功能特性描述 + href: ./feature_description.md diff --git a/docs/zh/cloud/nestos/nestos/feature_description.md b/docs/zh/cloud/nestos/nestos/feature_description.md new file mode 100644 index 0000000000000000000000000000000000000000..d6050c398e33731f272dbaa6051d568a2768630c --- /dev/null +++ b/docs/zh/cloud/nestos/nestos/feature_description.md @@ -0,0 +1,103 @@ +# 功能特性描述 + +## 容器技术 + +NestOS通过容器化 (containerized) 的运算环境向应用程序提供运算资源,应用程序之间共享系统内核和资源,但是彼此之间又互不可见。这意味着应用程序将不会再被直接安装到操作系统中,而是通过 Docker 运行在容器中。大大降低了操作系统、应用程序及运行环境之间的耦合度。相对于传统的应用程序部署方式而言,在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中新的默认文件,这是一个非常关键的特性。 + +OSTree旨在可以并行安装多个独立操作系统的版本。OSTree需要新建一个顶级目录“ostree”。然而实际上,OSTree支持在现有操作系统或发行版本的根目录(/)上,并行安装其他操作系统版本。每台客户机和每组部署都存储在 /ostree/deploy/STATEROOT/CHECKSUM 上,而且还有一个OSTree存储库存储在 /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和rpm-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 会阻止机器成功启动。 + +(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/zh/cloud/nestos/nestos/figures/figure1.png b/docs/zh/cloud/nestos/nestos/figures/figure1.png new file mode 100644 index 0000000000000000000000000000000000000000..b4eb9017ed202e854c076802492d8561942dfc88 Binary files /dev/null and b/docs/zh/cloud/nestos/nestos/figures/figure1.png differ diff --git a/docs/zh/cloud/nestos/nestos/figures/figure2.png b/docs/zh/cloud/nestos/nestos/figures/figure2.png new file mode 100644 index 0000000000000000000000000000000000000000..90049769c04e2bd494533da1613e38a5199da3d7 Binary files /dev/null and b/docs/zh/cloud/nestos/nestos/figures/figure2.png differ diff --git a/docs/zh/cloud/nestos/nestos/installation_and_deployment.md b/docs/zh/cloud/nestos/nestos/installation_and_deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/docs/zh/cloud/nestos/nestos/overview.md b/docs/zh/cloud/nestos/nestos/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..3a88a59874f2213ea5e11295c15094bb2b5722b6 --- /dev/null +++ b/docs/zh/cloud/nestos/nestos/overview.md @@ -0,0 +1,3 @@ +# NestOS用户指南 + +本文介绍云底座操作系统NestOS的安装部署与各个特性说明和使用方法,使用户能够快速了解并使用NestOS。NestOS搭载了docker、iSulad、podman、cri-o等常见容器引擎,将ignition配置、rpm-ostree、OCI支持、SElinux强化等技术集成在一起,采用基于双系统分区、容器技术和集群架构的设计思路,可以适配云场景下多种基础运行环境。同时NestOS针对Kubernetes进行优化,在IaaS生态构建方面,针对openStack、oVirt等平台提供支持;在PaaS生态构建方面,针对OKD、Rancher等平台提供支持,使系统具备十分便捷的集群组件能力,可以更安全的运行大规模的容器化工作负载。 diff --git a/docs/zh/cloud/nestos/nestos/usage.md b/docs/zh/cloud/nestos/nestos/usage.md new file mode 100644 index 0000000000000000000000000000000000000000..77d1064ed2001b34136f15ce2bd1dac0fd488775 --- /dev/null +++ b/docs/zh/cloud/nestos/nestos/usage.md @@ -0,0 +1,483 @@ +# K8S+iSulad 搭建 + +**除非特别说明,以下步骤在master节点和node节点均需执行**,本教程以master为例。 + +## 开始之前 + +需准备如下内容: + +- NestOS-22.03-date.x86_64.iso。 +- 一台主机用作master,一台主机用作node。 + +## 组件下载 + +编辑源文件,添加k8s的阿里云源: + +```shell +vi /etc/yum.repos.d/openEuler.repo +``` + +添加如下内容: + +```script +[kubernetes] +name=Kubernetes +baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ +enabled=1 +gpgcheck=1 +repo_gpgcheck=1 +gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg +``` + +下载k8s组件以及同步系统时间所用组件: + +```shell +rpm-ostree install kubelet kubeadm kubectl ntp ntpdate wget +``` + +重启生效。 + +```shell +systemctl reboot +``` + +选择最新的版本分支进入系统。 + +## 配置环境 + +### 修改主机名,以master为例 + +```shell +hostnamectl set-hostname k8s-master +sudo -i +``` + +编辑/etc/hosts + +```shell +vi /etc/hosts +``` + +添加如下内容,ip为主机ip + +```script +192.168.237.133 k8s-master +192.168.237.135 k8s-node01 +``` + +### 同步系统时间 + +```shell +ntpdate time.windows.com +systemctl enable ntpd +``` + +NestOS默认无swap分区,默认关闭防火墙。 +关闭selinux如下: + +```shell +vi /etc/sysconfig/selinux +修改为SELINUX=disabled +``` + +### 网络配置,开启相应的转发机制 + +创建配置文件。 + +```shell +vi /etc/sysctl.d/k8s.conf +``` + +添加如下内容: + +```script +net.bridge.bridge-nf-call-iptables=1 +net.bridge.bridge-nf-call-ip6tables=1 +net.ipv4.ip_forward=1 +``` + +使配置生效: + +```shell +modprobe br_netfilter +sysctl -p /etc/sysctl.d/k8s.conf +``` + +## 配置iSula + +查看k8s需要的系统镜像,需注意pause的版本号。 + +```shell +kubeadm config images list +``` + +修改daemon配置文件。 + +```shell +vi /etc/isulad/daemon.json +``` + +```script +##关于添加项的解释说明## +registry-mirrors 设置为"docker.io" +insecure-registries 设置为"rnd-dockerhub.huawei.com" +pod-sandbox-image 设置为"registry.aliyuncs.com/google_containers/pause:3.5"(使用阿里云,pause版本可在上一步查看) +network-plugin 设置为"cni"。 +cni-bin-dir 设置为"/opt/cni/bin"; +cni-conf-dir 设置为"/etc/cni/net.d" +``` + +修改后的完整文件如下 + +```script +{"group": "isula", +"default-runtime": "runc", +"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", +"container-log": { +"driver": "json-file" +}, +"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": "registry.aliyuncs.com/google_containers/pause:3.5", +"native.umask": "secure", +"network-plugin": "cni", +"cni-bin-dir": "/opt/cni/bin", +"cni-conf-dir": "/etc/cni/net.d", +"image-layer-check": false, +"use-decrypted-key": true, +"insecure-skip-verify-enforce": false +} +``` + +启动相关服务。 + +```shell +systemctl restart isulad +systemctl enable isulad +systemctl enable kubelet +``` + +**以上为master,node节点均需执行的操作。** + +## master节点初始化 + +**该部分仅master节点执行。** +初始化,在这一步会拉取镜像,需等待一小段时间。也可在该步骤之前手动拉取镜像。 + +```shell +kubeadm init --kubernetes-version=1.22.2 --apiserver-advertise- +address=192.168.237.133 --cri-socket=/var/run/isulad.sock --image-repository +registry.aliyuncs.com/google_containers --service-cidr=10.10.0.0/16 --pod- +network-cidr=10.122.0.0/16 +``` + +```shell +##关于初始化参数的解释说明## +kubernetes-version 为当前安装的版本 +apiserver-advertise-address 为master节点ip +cri-socket 指定引擎为isulad +image-repository 指定镜像源为阿里云,可省去修改tag的步骤 +service-cidr 指定service分配的ip段 +pod-network-cidr 指定pod分配的ip段 +``` + +初始化成功后,复制最后两行内容方便后续node节点加入使用。 + +```shell +kubeadm join 192.168.237.133:6443 --token j7kufw.yl1gte0v9qgxjzjw --discovery- +token-ca-cert-hash +sha256:73d337f5edd79dd4db997d98d329bd98020b712f8d7833c33a85d8fe44d0a4f5 --cri- +socket=/var/run/isulad.sock +``` + +**注意**:添加--cri-socket=/var/run/isulad.sock以使用isulad为容器引擎。 + +查看下载好的镜像。 + +```shell +isula images +``` + +按照初始化成功所提示,配置集群。 + +```shell +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 +source /etc/profile +``` + +查看健康状态。 + +```shell +kubectl get cs +``` + +可能存在controller-manager,scheduler状态为unhealthy的情况,解决方法如下: +编辑相关配置文件。 + +```shell +vi /etc/kubernetes/manifests/kube-controller-manager.yaml +``` + +```shell +注释如下内容: +--port=0 +修改hostpath: +将所有/usr/libexec/kubernetes/kubelet-plugins/volume/exec 修改为/opt/libexec/... +``` + +```shell +vi /etc/kubernetes/manifests/kube-scheduler.yaml +注释如下内容: +--port=0 +``` + +修改完成后,再次查看健康状态。 + +## 配置网络插件 + +仅需要在master节点配置网络插件,但是要在**所有节点**提前拉取镜像,拉取镜像指令如下: + +```shell +isula pull calico/node:v3.19.3 +isula pull calico/cni:v3.19.3 +isula pull calico/kube-controllers:v3.19.3 +isula pull calico/pod2daemon-flexvol:v3.19.3 +``` + +**以下步骤仅在master节点执行** +获取配置文件。 + +```shell +wget https://docs.projectcalico.org/v3.19/manifests/calico.yaml +``` + +编辑calico.yaml 修改所有/usr/libexec/... 为 /opt/libexec/... +然后执行如下命令完成calico的安装: + +```shell +kubectl apply -f calico.yaml +``` + +通过kubectl get pod -n kube-system查看calico是否安装成功。 +通过kubectl get pod -n kube-system查看是否所有pod状态都为running。 + +## node节点加入集群 + +在node节点执行如下指令,将node节点加入集群。 + +```shell +kubeadm join 192.168.237.133:6443 --token j7kufw.yl1gte0v9qgxjzjw --discovery- +token-ca-cert-hash +sha256:73d337f5edd79dd4db997d98d329bd98020b712f8d7833c33a85d8fe44d0a4f5 --cri- +socket=/var/run/isulad.sock +``` + +通过kubectl get node 查看master,node节点状态是否为ready。 + +至此,k8s部署成功。 + +# rpm-ostree使用 + +## rpm-ostree安装软件包 + +安装wget + +```shell +rpm-ostree install wget +``` + +重启系统,可在启动时通过键盘上下按键选择rpm包安装完成后或安装前的系统状态,其中【ostree:0】为安装之后的版本。 + +```shell +systemctl reboot +``` + +查看wget是否安装成功。 + +```shell +rpm -qa | grep wget +``` + +## rpm-ostree 手动更新升级 NestOS + +在NestOS中执行命令可查看当前rpm-ostree状态,可看到当前版本号。 + +```shell +rpm-ostree status +``` + +执行检查命令查看是否有升级可用,发现存在新版本。 + +```shell +rpm-ostree upgrade --check +``` + +预览版本的差异 + +```shell +rpm-ostree upgrade --preview +``` + +在最新版本中,我们将nano包做了引入。 +执行如下指令会下载最新的ostree和RPM数据,不需要进行部署。 + +```shell +rpm-ostree upgrade --download-only +``` + +重启NestOS,重启后可看到系统的新旧版本两个状态,选择最新版本的分支进入。 + +```shell +rpm-ostree upgrade --reboot +``` + +## 比较NestOS版本差别 + +检查状态,确认此时ostree有两个版本,分别为LTS.20210927.dev.0和LTS.20210928.dev.0。 + +```shell +rpm-ostree status +``` + +根据commit号比较2个ostree的差别。 + +```shell +rpm-ostree db diff 55eed9bfc5ec fe2408e34148 +``` + +## 系统回滚 + +当一个系统更新完成,之前的NestOS部署仍然在磁盘上,如果更新导致了系统出现问题,可以使用之前的部署回滚系统。 + +### 临时回滚 + +要临时回滚到之前的OS部署,在系统启动过程中按住shift键,当引导加载菜单出现时,在菜单中选择相关的分支。 + +### 永久回滚 + +要永久回滚到之前的操作系统部署,需要登录到目标节点,运行rpm-ostree rollback,此操作将使用之前的系统部署作为默认部署,并重新启动到其中。 +执行命令,回滚到更新前的系统。 + +```shell +rpm-ostree rollback +``` + +## 切换版本 + +在上一步将NestOS回滚到了旧版本,可以通过命令切换当前 NestOS 使用的rpm-ostree版本,将旧版本切换为新版本。 + +```shell +rpm-ostree deploy -r 22.03.20220325.dev.0 +``` + +重启后确认目前NestOS已经使用的是新版本的ostree了。 + +# zincati自动更新使用 + +zincati负责NestOS的自动更新,zincati通过cincinnati提供的后端来检查当前是否有可更新版本,若检测到有可更新版本,会通过rpm-ostree进行下载。 + +目前系统默认关闭zincati自动更新服务,可通过修改配置文件设置为开机自动启动自动更新服务。 + +```shell +vi /etc/zincati/config.d/95-disable-on-dev.toml +``` + +将updates.enabled设置为true,同时增加配置文件,修改cincinnati后端地址。 + +```shell +vi /etc/zincati/config.d/update-cincinnati.toml +``` + +添加如下内容: + +```script +[cincinnati] +base_url="http://nestos.org.cn:8080" +``` + +重新启动zincati服务。 + +```shell +systemctl restart zincati.service +``` + +当有新版本时,zincati会自动检测到可更新版本,此时查看rpm-ostree状态,可以看到状态是“busy”,说明系统正在升级中。 + +一段时间后NestOS将自动重启,此时再次登录NestOS,可以再次确认rpm-ostree的状态,其中状态转为"idle",而且当前版本已经是“20220325”,这说明rpm-ostree版本已经升级了。 + +查看zincati服务的日志,确认升级的过程和重启系统的日志。另外日志显示的"auto-updates logic enabled"也说明更新是自动的。 + +# 定制NestOS + +我们可以使用nestos-installer 工具对原始的NestOS ISO文件进行加工,将Ignition文件打包进去从而生成定制的 NestOS ISO文件。使用定制的NestOS ISO文件可以在系统启动完成后自动执行NestOS的安装,因此NestOS的安装会更加简单。 + +在开始定制NestOS之前,需要做如下准备工作: + +- 下载 NestOS ISO +- 准备 config.ign文件 + +## 生成定制NestOS ISO文件 + +### 设置参数变量 + +```shell +$ export COREOS_ISO_ORIGIN_FILE=nestos-22.03.20220324.x86_64.iso +$ export COREOS_ISO_CUSTOMIZED_FILE=my-nestos.iso +$ export IGN_FILE=config.ign +``` + +### ISO文件检查 + +确认原始的NestOS ISO文件中是没有包含Ignition配置。 + +```shell +$ nestos-installer iso ignition show $COREOS_ISO_ORIGIN_FILE + +Error: No embedded Ignition config. +``` + +### 生成定制NestOS ISO文件 + +将Ignition文件和原始NestOS ISO文件打包生成定制的NestOS ISO文件。 + +```shell +$ nestos-installer iso ignition embed $COREOS_ISO_ORIGIN_FILE --ignition-file $IGN_FILE $COREOS_ISO_ORIGIN_FILE --output $COREOS_ISO_CUSTOMIZED_FILE +``` + +### ISO文件检查 + +确认定制NestOS ISO 文件中已经包含Ignition配置了。 + +```shell +$ nestos-installer iso ignition show $COREOS_ISO_CUSTOMIZED_FILE +``` + +执行命令,将会显示Ignition配置内容。 + +## 安装定制NestOS ISO文件 + +使用定制的 NestOS ISO 文件可以直接引导安装,并根据Ignition自动完成NestOS的安装。在完成安装后,我们可以直接在虚拟机的控制台上用nest/password登录NestOS。