Skip to content

Index

jenkins

jenkins 主要用来做持续集成

安装

docker-compose 搭建

version: '3.1'
services:
  jenkins:
    image: jenkins/jenkins:lts
    volumes:
      - ./data/var/jenkins_home:/var/jenkins_home
    ports:
      - "8081:8080"
    expose:
      - "8080"
      - "50000"
    privileged: true
    user: root
    restart: always
    container_name: jenkins
    environment:
      JAVA_OPTS: '-Djava.util.logging.config.file=/var/jenkins_home/log.properties'

从节点

#docker 运行jenkins-slave示例,使用jnlp方式进行连接,即是agent主动连接master
docker run jenkins/jnlp-slave -url http://jenkins-server:port -workDir=<workdir> <secret> <agent name>
#比如创建好节点后,他会提示如下命令运行,这是java方式直接运行
java -jar slave.jar -jnlpUrl http://192.168.11.241/computer/slave%2002%20node/slave-agent.jnlp -secret 57901575cac903e95a15598d00f5a1c97101d766a5c70933cf5c26f41abxxxxx
#这个是使用docker容器里运行jenkins-slave示例,关键点是把http,workdir, <secret> <agent name>等参数对应填写好
orkdir是在jenkins新增节点时候填写的
docker run --name jenkins-slave02 -d --restart=unless-stopped jenkins/jnlp-slave  -url  http://192.168.11.241:8080 -workDir=<workdir> <secretKey> slave02

配置更新中心

网页中中文更新中心地址可能过时,去 https://www.jenkins-zh.cn/tutorial/management/plugin/update-center/ 获取最新地址设置

目录介绍

# 配置文件
config.xml 
# 作业节点
nodes/
# 插件
plugins/
# 秘钥信息
secret*
# 插件更新目录
updates/
# 用户目录
userContent/
# 所有用户
users/
# 项目作业
jobs/
# 默认工作目录
workspace/

流水线

构建触发器

轮询 SCM

轮询gitlab(类似版本管理中心)版本是否变更,变更后触发

  • 一般不使用,太被动,一般代码版本变动了直接去触发jenkins就行
触发远程构建

可请求对应远程地址来构建

权限

下载插件 Role-based Authorization Strategy

k3d

install

windows

scoop install k3d

快速文档

https://k3d.io/v5.6.0/

常用命令

k3d cluster create

克隆 https://github.com/k3d-io/k3d-demo

# windows 版本映射 volume 中路径需用 反斜杠
k3d cluster create demo --api-port 6550 --servers 1 --agents 3 --port 18080:80@loadbalancer --volume "D:\my\refs\k3d-demo\sample":"/src@all" --wait

# 不带路径版
k3d cluster create demo --api-port 6550 --servers 1 --agents 3 --port 18080:80@loadbalancer --wait

也可用 yaml文件 来创建

创建 demo.yml 文件

apiVersion: k3d.io/v1alpha5
kind: Simple
metadata:
  name: demo
servers: 1
agents: 2
kubeAPI: 
  hostPort: "6445"
image: rancher/k3s:v1.27.4-k3s1
ports:
  - port: 18080:80 # same as `--port '8080:80@loadbalancer'`
    nodeFilters:
      - loadbalancer
volumes: # repeatable flags are represented as YAML lists
  - volume: /data/Apps/k3d/data:/src # same as `--volume '/my/host/path:/path/in/node@server:0;agent:*'`
    nodeFilters:
      - server:0
options:
  k3d: # k3d runtime settings
    wait: true
# 即可运行
$ k3d cluster create --config demo.yaml

k3d cluster list

#查看集群信息
$ k3d cluster list
NAME   SERVERS   AGENTS   LOADBALANCER
demo   1/1       3/3      true

下载 kubetrl

如果没有对应工具去 https://kubernetes.io/docs/tasks/tools/ 下载

k3s 环境搭建

环境准备

  • 3台 centos7.9 镜像,均为2核2G,一台为 k8s-master 另外2台 为 k8s-worker1 和 k8s-worker2 来源:https://mirrors.tuna.tsinghua.edu.cn/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso
  • k3s 二进制文件 和 k3s-airgap-images-amd64.tar.gz image文件 install.sh 文件 来源:https://github.com/k3s-io/k3s

eg: linux服务器信息, 设置对应主机名

name ip cmd
k8s-master 192.168.8.130 hostnamectl set-hostname k8s-master
k8s-work1 192.168.8.131 hostnamectl set-hostname k8s-worker1
k8s-work2 192.168.8.132 hostnamectl set-hostname k8s-worker2

安装步骤

公共

# 关闭防火墙
systemctl disable firewalld --now

# 设置selinux
yum install -y container-selinux selinux-policy-base
yum install -y https://rpm.rancher.io/k3s/latest/common/centos/7/noarch/k3s-selinux-0.2-1.el7_8.noarch.rpm

# k3s移入
mv k3s /usr/local/bin
chmod +x /usr/local/bin/k3s

# 移动image
mkdir -p /var/lib/rancher/k3s/agent/images/
cp ./k3s-airgap-images-amd64.tar.gz /var/lib/rancher/k3s/agent/images/

master

#修改权限
chmod +x install.sh
#离线安装
INSTALL_K3S_SKIP_DOWNLOAD=true ./install.sh
#安装完成后,查看节点状态, 一般稚嫩在 master 节点来观测
kubectl get node
# 每隔1s观察一次状态
watch -n 1 kubectl get node 
#查看token
cat /var/lib/rancher/k3s/server/node-token
#K10fd15a1d2f9e9bdd409ad20c5efa3cb2dcee5a947829c9d437e1adf59bde9e7f1::server:cf09ddd6dfc047a8936a11c0983f402c

workers

INSTALL_K3S_SKIP_DOWNLOAD=true \
K3S_URL=https://192.168.8.130:6443 \
K3S_TOKEN=K10fd15a1d2f9e9bdd409ad20c5efa3cb2dcee5a947829c9d437e1adf59bde9e7f1::server:cf09ddd6dfc047a8936a11c0983f402c \
./install.sh

k3s 配置文件

K3s会自动生成containerd的配置文件/var/Iib/rancher/k3s/agent/etc/containerd/config.toml,不要直接修改这个文 件,k3s重启后修改会丢失。 K3s通过/etc/rancher/k3s/registries.yaml文件来配置镜像仓库,K3s会在启动时检查这个文件是否存在。 配置如下

mirrors:
  docker.io:
    endpoint:
      - "http://fsp2sfpr.mirror.aliyuncs.com/"

重启

# master 重启 k3s
systemctl restart k3s
# worker 重启 k3s-agent
systemctl restart k3s-agent
# 重启后 /var/Iib/rancher/k3s/agent/etc/containerd/config.toml 中的源也更新了

创建和管理 pod

kubectl run mynginx --image=nginx
# 查看Pod
kubectl get pod
# 描述
kubectl describe pod mynginx
# 查看Pod的运行日志
kubectl logs mynginx

# 显示pod的IP和运行节点信息
kubectl get pod -owide
# 使用Pod的ip+pod里面运行容器的端口
curl 10.42.1.3

#在容器中执行
kubectl exec mynginx -it -- /bin/bash

kubectl get po --watch
# -it 交互模式 
# --rm 退出后删除容器,多用于执行一次性任务或使用客户端
kubectl run mynginx --image=nginx -it --rm -- /bin/bash 

# 删除
kubectl delete pod mynginx
# 强制删除
kubectl delete pod mynginx --force

部署和副本

#创建deployment,部署3个运行nginx的Pod
kubectl create deployment nginx-deployment --image=nginx:1.22 --replicas=3
#查看deployment
kubectl get deploy
#查看replicaSet
kubectl get rs 
#删除deployment
kubectl delete deploy nginx-deployment

缩放

手动缩放

#将副本数量调整为5
kubectl scale deployment/nginx-deployment --replicas=5
kubectl get deploy

自动缩放

#自动缩放
kubectl autoscale deployment/nginx-auto --min=3 --max=10 --cpu-percent=75 
#查看自动缩放
kubectl get hpa
#删除自动缩放
kubectl delete hpa nginx-deployment

滚动更新

#查看版本和Pod
kubectl get deployment/nginx-deployment -owide
kubectl get pods

#更新容器镜像
kubectl set image deployment/nginx-deployment nginx=nginx:1.23
#滚动更新
kubectl rollout status deployment/nginx-deployment
#查看过程
kubectl get rs --watch

版本回滚

#查看历史版本
kubectl rollout history deployment/nginx-deployment
#查看指定版本的信息
kubectl rollout history deployment/nginx-deployment --revision=2
#回滚到历史版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2

service

创建service 对象

ServiceType 取值

ClusterIP:将服务公开在集群内部。kubernetes会给服务分配一个集群内部的 IP,集群内的所有主机都可以通过这个Cluster-IP访问服务。集群内部的Pod可以通过service名称访问服务。

NodePort:通过每个节点的主机IP 和静态端口(NodePort)暴露服务。 集群的外部主机可以使用节点IP和NodePort访问服务。

ExternalName:将集群外部的网络引入集群内部。

LoadBalancer:使用云提供商的负载均衡器向外部暴露服务。

ClusterIP
# 会自动生成 service 对象及其IP
kubectl expose deploy/nginx-deploy --name=nginx-service --port=8080 --target-port=80
# 与上面等效
kubectl expose deploy/nginx-deploy --name=nginx-service --port=8080 --type=ClusterIP --target-port=80

# 获取service 信息
kubectl get service

NodePort

kubectl expose deploy/nginx-deploy --name=nginx-outside --type=NodePort --port=8081 --target-port=80

命名空间

管理命名空间

#创建命名空间
kubectl create namespace dev
#查看命名空间
kubectl get ns

#在命名空间内运行Pod --namespace 可缩写为 -ns
kubectl run nginx --image=nginx --namespace=dev
kubectl run my-nginx --image=nginx -n=dev

#查看命名空间内的Pod
kubectl get pods -n=dev

#查看命名空间内所有对象
kubectl get all
# 删除命名空间会删除命名空间下的所有内容
kubectl delete ns dev

切换当前命名空间

#查看当前上下文
kubectl config current-context

#将dev设为当前命名空间,后续所有操作都在此命名空间下执行。
kubectl config set-context $(kubectl config current-context) --namespace=dev

管理对象

  • 命令行指令 例如,使用kubectl命令来创建和管理 Kubernetes 对象。 命令行就好比口头传达,简单、快速、高效。 但它功能有限,不适合复杂场景,操作不容易追溯,多用于开发和调试。

  • 声明式配置 kubernetes使用yaml文件来描述 Kubernetes 对象。 声明式配置就好比申请表,学习难度大且配置麻烦。 好处是操作留痕,适合操作复杂的对象,多用于生产。

常用对象缩写

名称 缩写 Kind
namespaces ns Namespace
nodes no Node
pods po Pod
services srv Service
deployments deploy Deployment
replicasets rs ReplicaSet
statefulsets sts StatefulSet

声明式对象配置

Pod 配置模板 (https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/)

apiVersion: v1
kind: Pod
metadata:
  name: my-nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.22
    ports:
    - containerPort: 80

yaml文件管理

#创建对象
kubectl apply -f my-pod.yaml
#编辑对象
kubectl edit nginx
#删除对象
kubectl delete -f my-pod.yaml

标签和选择器

https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set

apiVersion: v1
kind: Pod
metadata:
  name: label-demo
  labels: #定义Pod标签
    environment: test
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.22
    ports:
    - containerPort: 80
设置后

kubectrl apply -f label-demo.yml

设置service

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  selector: #与Pod的标签一致
    environment: test
    app: nginx
  ports:
      # 默认情况下,为了方便起见,`targetPort` 被设置为与 `port` 字段相同的值。
    - port: 80
      targetPort: 80
      # 可选字段
      # 默认情况下,为了方便起见,Kubernetes 控制平面会从某个范围内分配一个端口号(默认:30000-32767)
      nodePort: 30007

设置后启动 label-demo service,并选择了前面的 app为 nginx的pod暴露端口

kubectrl apply -f label-demo.yml


# -l 参数可以过滤标签
kubectrl get pod -l "app=nginx" -owide

目前有等值选择和集合选择两种

  • 等值选择
selector:
  matchLabels: # component=redis && version=7.0
    component: redis
    version: 7.0
  • 集合选择
selector:
  matchExpressions: # tier in (cache, backend) && environment not in (dev, prod)
    - {key: tier, operator: In, values: [cache, backend]}
    - {key: environment, operator: NotIn, values: [dev, prod]}

容器运行时(cri)

crictl 命令和 docker命令类似,只是没有导入导出

可借助 ctr 命令来导入导出

k8s 镜像都在 k8s.io 命名空间中

ctr -n=k8s.io images import {{image.tar}} --platform linux/amd64

# 完成后查看
crictl images

# 导出镜像
ctr -n=k8s.io images export {{image.tar}} {{image}} --platform linux/amd64

金丝雀发布

发布v1版本的应用,镜像使用nginx:1.22,数量为 3。

创建Namespace Namespace配置模版

创建Deployment Deployment配置模版

创建外部访问的Service Service配置模版

如下 用 --- 分隔配置

apiVersion: v1
kind: Namespace
metadata:
  name: dev
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment-v1
  namespace: dev
  labels:
    app: nginx-deployment-v1
spec:
  replicas: 3
  selector:
    matchLabels: # 跟template.metadata.labels一致
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.22
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: canary-demo
  namespace: dev
spec:
  type: NodePort
  selector: # 更Deployment中的selector一致
    app: nginx
  ports:
      # By default and for convenience, the `targetPort` is set to the same value as the `port` field.
    - port: 80
      targetPort: 80
      # Optional field
      # By default and for convenience, the Kubernetes control plane will allocate a port from a range (default: 30000-32767)
      nodePort: 30008
  • 创建Canary Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment-canary
  namespace: dev
  labels:
    app: nginx-deployment-canary
spec:
  replicas: 1
  selector:
    matchLabels: # 跟template.metadata.labels一致
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
        track: canary
    spec:
      containers:
        - name: new-nginx
          image: docker/getting-started
          ports:
            - containerPort: 80
  • 分配流量 查看服务 kubectl describe svc canary-demo --namespace=dev

  • 调整比例 待稳定运行一段时间后,扩大试用范围,将部署的v2版本数量调整为3,v1和v2的数量都是3个。

kubectl scale deployment/deploy-v2-canary --replicas=3 -n=dev
  • 下线旧版本 最后下线所有v1版本,所有服务升级为v2版本。
kubectl scale deployment/deploy-v1 --replicas=0 -n=dev
  • 清空环境
  • 使用namespace可以方便的清空环境:
    kubectl delete all --all -n=dev
    

有状态应用集

StatefulSet

如果我们需要部署多个MySQL实例,就需要用到StatefulSet。 StatefulSet 是用来管理有状态的应用。一般用于管理数据库、缓存等。 与 Deployment 类似, StatefulSet用来管理 Pod 集合的部署和扩缩。 Deployment用来部署无状态应用。StatefulSet用来有状态应用。

创建 StatefulSet

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql-sts
spec:
  selector:
    matchLabels:
      app: mysql # 必须匹配 .spec.template.metadata.labels
  serviceName: mysql-svc
  replicas: 3 # 默认值是 1
  minReadySeconds: 10 # 默认值是 0
  template:
    metadata:
      labels:
        app: mysql # 必须匹配 .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: mysql
          image: mysql:5.7
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: "123456"
          ports:
            - containerPort: 3306
          volumeMounts:
            - mountPath: /var/lib/mysql #容器中的目录
              name: data-volume
  volumeClaimTemplates: # 持久卷声明模板
    - metadata:
        name: data-volume
      spec:
        accessModes:
          - ReadWriteOnce
        storageClassName: local-path
        resources:
          requests:
            storage: 2Gi

稳定的存储

在 StatefulSet 中使用 VolumeClaimTemplate,为每个 Pod 创建持久卷声明(PVC)。 每个 Pod 将会得到基于local-path 存储类动态创建的持久卷(PV)。 Pod 创建(或重新调度)时,会挂载与其声明相关联的持久卷。 请注意,当 Pod 或者 StatefulSet 被删除时,持久卷声明和关联的持久卷不会被删除。

Pod 标识

在具有 N 个副本的 StatefulSet中,每个 Pod 会被分配一个从 0 到 N-1 的整数序号,该序号在此 StatefulSet 上是唯一的。 StatefulSet 中的每个 Pod 主机名的格式为StatefulSet名称-序号。 上例将会创建三个名称分别为 mysql-0、mysql-1、mysql-2 的 Pod。

部署和扩缩保证

对于包含 N 个 副本的 StatefulSet,当部署 Pod 时,它们是依次创建的,顺序为 0..N-1。 当删除 Pod 时,它们是逆序终止的,顺序为 N-1..0。 在将扩缩操作应用到 Pod 之前,它前面的所有 Pod 必须是 Running 和 Ready 状态。 在一个 Pod 终止之前,所有的继任者必须完全关闭。

在上面的mysql示例被创建后,会按照 mysql-0、mysql-1、mysql-2 的顺序部署三个 Pod。
在 mysql-0 进入 Running 和 Ready 状态前不会部署 mysql-1。
在 mysql-1 进入 Running 和 Ready 状态前不会部署 mysql-2。 
如果 mysql-1 已经处于 Running 和 Ready 状态,而 mysql-2 尚未部署,在此期间发生了 mysql-0 运行失败,那么 mysql-2 将不会被部署,要等到 mysql-0 部署完成并进入 Running 和 Ready 状态后,才会部署 mysql-2。
如果用户想将示例中的 StatefulSet 扩缩为 replicas=1,首先被终止的是 mysql-2。 
在 mysql-2 没有被完全停止和删除前,mysql-1 不会被终止。 
当 mysql-2 已被终止和删除、mysql-1 尚未被终止,如果在此期间发生 mysql-0 运行失败, 那么就不会终止 mysql-1,必须等到 mysql-0 进入 Running 和 Ready 状态后才会终止 web-1。

Headless Service(无头服务)

k3s 部署

  • 清空flannel
ifconfig flannel.1 down

linux 正则

前言

由于历史原因,正则表达式分为了两个流派,分别是 POSIX 流派和 PCRE 流派。其中,POSIX 流派有两个标准,分别是 BRE 标准和 ERE 标准 目前,Linux 和 Mac 在原生集成 GUN 套件(例如 grep 命令)时,遵循了 POSIX 标准,并弱化了 GNU BRE 和 GNU ERE 之间的区别。

GNU BRE 和 GNU ERE 的差别主要体现在一些语法字符是否需要转义上

各种标准区别

BRE

echo "addf" | grep 'd\{1,3\}'

ERE

echo "addf" | grep -E 'd{1,3}'
echo  "11d23a" | grep -E '[[:digit:]]+'

PCRE

echo  "11d23a" | grep -P '\d+'

当代程序基本使用此标准, eg

  • vim
  • golang 默认正则

swap使用

linux 有 交换分区交换文件 两种方式扩展内存 一般建议交换内存为物理内存的 1~2倍

交换分区

一般是系统安装时配置

交换文件

交换文件添加

eg: 可以按照以下步骤在 /data/swaps/ 路径下创建一个 2GB 的交换文件:

  1. 使用 fallocatedd 命令创建一个 2GB 的交换文件。例如:
sudo fallocate -l 2G /data/swaps/swapfile

sudo dd if=/dev/zero of=/data/swaps/swapfile bs=1M count=2048

这将在 /data/swaps/ 目录下创建一个名为 swapfile 的 2GB 交换文件。

  1. 设置文件权限,确保只有 root 用户可以读写:
sudo chmod 600 /data/swaps/swapfile
  1. 将文件转换为交换空间:
sudo mkswap /data/swaps/swapfile
  1. 启用新的交换文件:
sudo swapon /data/swaps/swapfile
  1. 如果你希望系统在重新启动后仍然使用这个交换文件,需要将它添加到 /etc/fstab 文件中。编辑 /etc/fstab 并添加以下行:
/data/swaps/swapfile none swap sw 0 0

这会告诉系统在启动时启用这个新的交换文件。

最后,你可以使用 swapon --show 命令来确保新的交换文件已启用并提供额外的 2GB 交换空间。这将增加系统的交换空间,帮助处理内存不足的情况。

交换文件删除

要安全地删除一个交换文件,你可以按照以下步骤进行操作:

  1. 禁用交换文件:在删除交换文件之前,首先要禁用它。使用以下命令禁用交换文件:
sudo swapoff /path/to/swapfile

替换 /path/to/swapfile 为你的交换文件的完整路径。

  1. 删除交换文件:一旦交换文件被禁用,你可以安全地删除它。使用 rm 命令进行删除:
sudo rm /path/to/swapfile

请小心,确保你删除的是正确的文件,因为这个操作是不可恢复的。

  1. 更新 /etc/fstab(可选):如果你在 /etc/fstab 文件中为交换文件添加了条目,确保在删除文件后也将该条目从文件中删除。

  2. 重新启用交换分区或文件:如果你需要仍然需要交换空间,你可以使用已存在的交换分区或文件,或者创建一个新的。如果你删除了一个交换文件,你可以创建一个新的交换文件并启用它,如之前的步骤所示。

在进行这些操作之前,请确保你的系统没有任何活动的进程或任务依赖于交换文件,以避免不必要的问题。并且请小心确保你删除的是正确的文件,因为删除后无法恢复。

gitbook

http://www.zhaowenyu.com/gitbook-doc

环境

node 10

安装

npm install -g gitbook-cli

其他命令

# 测试页面
gitbook serve
# 生成页面
gitbook build

常用插件

https://www.zhaowenyu.com/gitbook-doc/plugins/cat-article-content.html

https://www.jianshu.com/p/09bf890ec8f6

https://juejin.cn/post/6844903865146441741

插件开发教程

https://snowdreams1006.github.io/gitbook-official/en/plugins/testing.html

hide-element 隐藏元素

{
    "plugins": [
        "hide-element"
    ],
    "pluginsConfig": {
        "hide-element": {
            "elements": [".gitbook-link"]
        }
    }
}

splitter 侧边栏宽度可调节

{
    "plugins": [
        "splitter"
    ]
}

search-pro 高级搜索

{
    "plugins": [
          "-lunr", 
          "-search", 
          "search-pro"
    ]
}

插件

plantuml

集成 plantuml 插件

参考 http://skyao.github.io/2015/11/25/gitbook-plantuml-plugin/

安装gitbook-plugin-plantuml

修改package.json文件,增加一个gitbook-plugin-plantuml插件.

“gitbook-plugin-plantuml”: “~0.0.15”

"devDependencies": {
    ......
    "gitbook-plugin-plantuml":  "~0.0.15"
},
然后执行命令:

npm install .

也可以一次性执行命令:

npm install gitbook-plugin-plantuml –save

设置book.json

在book.json中增加plugins设置:

{
    "plugins": ["plantuml"],
}
下载plantuml.jar

从官网download页面下载到plantuml.jar文件, 放到项目根目录下

创建目录/assets/images/uml

使用插件
在需要插入planttuml图片的地方, 插入plantuml内容 (注意要放在类型为uml的代码块中):


@startuml
a -> b
@enduml
之后执行gitbook server或者grunt test命令, 生成gitbook的html内容时, 这里的plantuml内容就会被转换为uml图片,然后替换对应的plantuml文本内容.

这样我们就可以在文章内容中直接书写plantuml内容, 然后自动得到对应的图片, 非常方便.

子页面不能显示原因分析及解决

打开插件index.js

此段代码表示只能解析一二级目录的图片

assetPath = '../assets/images/uml/' + chapterPath + '/'

稍作修改使之能解析多级

let assetPathPre = '../'.repeat(pathToken.length - 1)
assetPath = assetPathPre + 'assets/images/uml/' + chapterPath + '/'

现在下面的示例就能显示了

示例

@startuml
a -> b
@enduml

为什么不能用?

@startuml

    Class Stage
    Class Timeout {
        +constructor:function(cfg)
        +timeout:function(ctx)
        +overdue:function(ctx)
        +stage: Stage
    }
    Stage <|-- Timeout

@enduml

bug

Error: ENOENT: no such file or directory, stat ‘C:\Users\Lenovo\www\mdspg\md\mybook_book\gitbook\gitbook-plugin-fontsettings\fontsettings.js’

解决方式

用户目录下找到以下文件。 .gitbook\versions\3.2.3\lib\output\website\copyPluginAssets.js

Replace all

confirm: true

with

confirm: false

常用插件

+-- gitbook-plugin-import@0.0.4
+-- gitbook-plugin-3-ba@0.9.0
+-- gitbook-plugin-anchor-navigation-ex@1.0.14
+-- gitbook-plugin-back-to-top-button@0.1.4
+-- gitbook-plugin-code@0.1.0
+-- gitbook-plugin-disqus@0.1.0
+-- gitbook-plugin-ga@1.0.1
+-- gitbook-plugin-github@2.0.0
`-- gitbook-plugin-search-plus@1.0.3

拓展阅读

  • 如何开发插件g https://snowdreams1006.github.io/gitbook-official/en/plugins/create.html