中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

KubeSphere中如何部署Wiki系統wiki.js并啟用中文全文檢索

發布時間:2022-07-08 14:03:16 來源:億速云 閱讀:368 作者:iii 欄目:開發技術

今天小編給大家分享一下KubeSphere中如何部署Wiki系統wiki.js并啟用中文全文檢索的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

    背景

    wiki.js 是優秀的開源 Wiki 系統,相較于 xwiki ,功能目前性上比 xwiki 不夠完善,但也在不斷進步。 Wiki 寫作、分享、權限管理功能還是有的,勝在 UI 設計很漂亮,能滿足小團隊的基本知識管理需求。

    以下工作是在 KubeSphere 3.2.1 + Helm 3 已經部署好的情況下進行的。

    準備 storageclass

    我們使用 OpenEBS 作為存儲,OpenEBS 默認安裝的 Local StorageSlass 在 Pod 銷毀后自動刪除,不適合用于我的 MySQL 存儲,我們在 Local StorageClass 基礎上稍作修改,創建新的 StorageClass,允許 Pod 銷毀后,PV 內容繼續保留,手動決定怎么處理。

    apiVersion: v1
    items:
    - apiVersion: storage.k8s.io/v1
      kind: StorageClass
      metadata:
        annotations:
          cas.openebs.io/config: |
            - name: StorageType
              value: "hostpath"
            - name: BasePath
              value: "/var/openebs/localretain/"
          openebs.io/cas-type: local
          storageclass.beta.kubernetes.io/is-default-class: "false"
          storageclass.kubesphere.io/supported-access-modes: '["ReadWriteOnce"]'
        name: localretain
      provisioner: openebs.io/local
      reclaimPolicy: Retain
      volumeBindingMode: WaitForFirstConsumer
    kind: List
    metadata:
      resourceVersion: ""
      selfLink: ""

    部署 PostgreSQL 數據庫

    我們團隊其他項目中也需要使用 PostgreSQL, 為了提高 PostgreSQL 數據庫的利用率和統一管理,我們獨立部署 PostgreSQL,并在安裝 wiki.js 時,配置為使用外部數據庫。

    準備用戶名密碼配置

    我們使用 Secret 保存 PostgreSQL 用戶密碼等敏感信息。

    kind: Secret
    apiVersion: v1
    metadata:
      name: postgres-prod
    data:
      POSTGRES_PASSWORD: xxxx
    type: Opaque

    以上 POSTGRES_PASSWORD 自行準備,為 base64 編碼的數據。

    準備數據庫初始化腳本

    使用 ConfigMap 保存數據庫初始化腳本,在 數據庫創建時,將 ConfigMap 中的數據庫初始化腳本掛載到 /docker-entrypoint-initdb.d, 容器初始化時會自動執行該腳本。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: wikijs-postgres-init
    data:
      init.sql: |-
        CREATE DATABASE wikijs;
        CREATE USER wikijs with password 'xxxx';
        GRANT CONNECT ON DATABASE wikijs to wikijs;
        GRANT USAGE ON SCHEMA public TO wikijs;
        GRANT SELECT,update,INSERT,delete ON ALL TABLES IN SCHEMA public TO wikijs;
        ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO wikijs;

    以上 wikijs 用戶的密碼自行準備,明文保存。

    準備存儲

    我們使用 KubeSphere 默認安裝的 OpenEBS 來提供存儲服務。可以通過創建 PVC 來提供持久化存儲。

    這里聲明一個 10G 的 PVC。

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: postgres-prod-data
      finalizers:
        - kubernetes.io/pvc-protection
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 10Gi
      storageClassName: localretain
      volumeMode: Filesystem

    部署 PostgreSQL 數據庫

    在前面的步驟準備好各種配置信息和存儲后,就可以開始部署 PostgreSQL 服務了。

    我們的 Kubernetes 沒有配置存儲陣列,使用的是 OpenEBS 作為存儲,采用 Deployment 方式部署 PostgreSQL。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: postgres-prod
      name: postgres-prod
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: postgres-prod
      template:
        metadata:
          labels:
            app: postgres-prod
        spec:
          containers:
            - name: db
              imagePullPolicy: IfNotPresent
              image: 'abcfy2/zhparser:12-alpine'
              ports:
                - name: tcp-5432
                  protocol: TCP
                  containerPort: 5432
              envFrom:
              - secretRef:
                  name: postgres-prod
              volumeMounts:
                - name: postgres-prod-data
                  readOnly: false
                  mountPath: /var/lib/postgresql/data
                - name: wikijs-postgres-init
                  readOnly: true
                  mountPath: /docker-entrypoint-initdb.d
          volumes:
            - name: postgres-prod-data
              persistentVolumeClaim:
                claimName: postgres-prod-data
            - name: wikijs-postgres-init
              configMap:
                name: wikijs-postgres-init

    創建供其他 Pod 訪問的 Service

    apiVersion: v1
    kind: Service
    metadata:
      name: postgres-prod
    spec:
      selector:
        app: postgres-prod
      ports:
        - protocol: TCP
          port: 5432
          targetPort: tcp-5432

    完成 PostgreSQL 部署

    測試略

    部署 wiki.js

    準備用戶名密碼配置

    我們使用 Secret 保存 wiki.js 用于連接數據庫的用戶名密碼等敏感信息。

    apiVersion: v1
    kind: Secret
    metadata:
      name: wikijs
    data:
      DB_USER: d2lraWpz
      DB_PASS: xxxx
    type: Opaque

    以上 DB_PASS 自行準備,為 base64 編碼的數據。

    準備數據庫連接配置

    我們使用 ConfigMap 保存 wiki.js 的數據庫連接信息。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: wikijs
    data:
      DB_TYPE: postgres
      DB_HOST: postgres-prod.infra
      DB_PORT: "5432"
      DB_NAME: wikijs
      HA_ACTIVE: "true"

    創建數據庫用戶和數據庫

    如果 PostgreSQL 數據庫里沒有創建 wikijs 用戶和數據 ,需要手工完成一下工作:

    通過『數據庫工具』連接 PostgreSQL 數據庫,執行一下 SQL 語句,完成數據庫和用戶的創建、授權。

    CREATE DATABASE wikijs;
    CREATE USER wikijs with password 'xxxx';
    GRANT CONNECT ON DATABASE wikijs to wikijs;
    GRANT USAGE ON SCHEMA public TO wikijs;
    GRANT SELECT,update,INSERT,delete ON ALL TABLES IN SCHEMA public TO wikijs;
    ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO wikijs;

    以上 wikijs 的密碼自行修改。

    準備 wiki.js 的 yaml 部署文件

    采用 Deployment 方式 部署 wiki.js 的 yaml 文件如下:

    # wikijs-deploy.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: wikijs
      name: wikijs
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: wikijs
      template:
        metadata:
          labels:
            app: wikijs
        spec:
          containers:
            - name: wikijs
              image: 'requarks/wiki:2'
              ports:
                - name: http-3000
                  protocol: TCP
                  containerPort: 3000
              envFrom:
              - secretRef:
                  name: wikijs
              - configMapRef:
                  name: wikijs

    創建集群內訪問 wiki.js 的 Service

    # wikijs-svc.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: wikijs
    spec:
      selector:
        app: wikijs
      ports:
        - protocol: TCP
          port: 3000
          targetPort: http-3000

    創建集群外訪問的 Ingress

    # wikijs-ing.yaml
    kind: Ingress
    apiVersion: networking.k8s.io/v1
    metadata:
      name: wikijs
    spec:
      ingressClassName: nginx
      rules:
        - host: wiki.xxxx.cn
          http:
            paths:
              - path: /
                pathType: ImplementationSpecific
                backend:
                  service:
                    name: wikijs
                    port:
                      number: 3000

    以上 host 域名需要自行配置。

    執行部署

    $ kubectl apply -f wikijs-deploy.yaml
    $ kubectl apply -f wikijs-svc.yaml
    $ kubectl apply -f wikijs-ing.yaml

    配置 wiki.js 支持中文全文檢索

    wiki.js 的全文檢索支持基于 PostgreSQL 的檢索,也支持 Elasticsearch 等,相對來說, PostgreSQL 比較輕量級,本項目中,我們使用 PostgreSQL 的全文檢索。

    但是,因為 PostgreSQL 不支持中文分詞,需要額外安裝插件并配置啟用中文分詞,下面描述了為 wiki.js 啟動基于 PostgreSQL 數據庫中文分詞的全文檢索。

    授予 wikijs 用戶臨時超管權限

    通過數據庫管理工具登錄有超管權限的 PostgreSQL 用戶,臨時授予 wiki.js 用戶臨時超管權限,便于啟動中文分詞功能。

    ALTER USER wikijs WITH SUPERUSER;

    啟用數據庫的中文分詞能力

    使用數據庫管理工具登錄 PostgreSQL 數據庫的 wikijs 用戶,執行以下命令,啟動數據庫的中文分詞功能。

    CREATE EXTENSION pg_trgm;
    CREATE EXTENSION zhparser;
    CREATE TEXT SEARCH CONFIGURATION pg_catalog.chinese_zh (PARSER = zhparser);
    ALTER TEXT SEARCH CONFIGURATION chinese_zh ADD MAPPING FOR n,v,a,i,e,l WITH simple;
    -- 忽略標點影響
    ALTER ROLE wikijs SET zhparser.punctuation_ignore = ON;
    -- 短詞復合
    ALTER ROLE wikijs SET zhparser.multi_short = ON;
    -- 測試一下
    select ts_debug('chinese_zh', '青春是最美好的年歲,青春是最燦爛的日子。每一個人的青春都無比寶貴,寶貴的青春只有與奮斗為伴才最閃光、最出彩。');

    取消 wikijs 用戶的臨時超管權限

    登錄 PostgreSQL 數據庫 wikijs 用戶,取消 wikijs 用戶的超管權限。

    ALTER USER wikijs WITH NOSUPERUSER;

    創建支持中文分詞的配置 ConfigMap

    # zh-parse.yaml
    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: wikijs-zhparser
    data:
      definition.yml: |-
        key: postgres
        title: Database - PostgreSQL
        description: Advanced PostgreSQL-based search engine.
        author: requarks.io
        logo: https://static.requarks.io/logo/postgresql.svg
        website: https://www.requarks.io/
        isAvailable: true
        props:
          dictLanguage:
            type: String
            title: Dictionary Language
            hint: Language to use when creating and querying text search vectors.
            default: english
            enum:
              - simple
              - danish
              - dutch
              - english
              - finnish
              - french
              - german
              - hungarian
              - italian
              - norwegian
              - portuguese
              - romanian
              - russian
              - spanish
              - swedish
              - turkish
              - chinese_zh
            order: 1
      engine.js: |-
        const tsquery = require('pg-tsquery')()
        const stream = require('stream')
        const Promise = require('bluebird')
        const pipeline = Promise.promisify(stream.pipeline)
        /* global WIKI */
        module.exports = {
          async activate() {
            if (WIKI.config.db.type !== 'postgres') {
              throw new WIKI.Error.SearchActivationFailed('Must use PostgreSQL database to activate this engine!')
            }
          },
          async deactivate() {
            WIKI.logger.info(`(SEARCH/POSTGRES) Dropping index tables...`)
            await WIKI.models.knex.schema.dropTable('pagesWords')
            await WIKI.models.knex.schema.dropTable('pagesVector')
            WIKI.logger.info(`(SEARCH/POSTGRES) Index tables have been dropped.`)
          },
          /**
           * INIT
           */
          async init() {
            WIKI.logger.info(`(SEARCH/POSTGRES) Initializing...`)
            // -> Create Search Index
            const indexExists = await WIKI.models.knex.schema.hasTable('pagesVector')
            if (!indexExists) {
              WIKI.logger.info(`(SEARCH/POSTGRES) Creating Pages Vector table...`)
              await WIKI.models.knex.schema.createTable('pagesVector', table => {
                table.increments()
                table.string('path')
                table.string('locale')
                table.string('title')
                table.string('description')
                table.specificType('tokens', 'TSVECTOR')
                table.text('content')
              })
            }
            // -> Create Words Index
            const wordsExists = await WIKI.models.knex.schema.hasTable('pagesWords')
            if (!wordsExists) {
              WIKI.logger.info(`(SEARCH/POSTGRES) Creating Words Suggestion Index...`)
              await WIKI.models.knex.raw(`
                CREATE TABLE "pagesWords" AS SELECT word FROM ts_stat(
                  'SELECT to_tsvector(''simple'', "title") || to_tsvector(''simple'', "description") || to_tsvector(''simple'', "content") FROM "pagesVector"'
                )`)
              await WIKI.models.knex.raw('CREATE EXTENSION IF NOT EXISTS pg_trgm')
              await WIKI.models.knex.raw(`CREATE INDEX "pageWords_idx" ON "pagesWords" USING GIN (word gin_trgm_ops)`)
            }
            WIKI.logger.info(`(SEARCH/POSTGRES) Initialization completed.`)
          },
          /**
           * QUERY
           *
           * @param {String} q Query
           * @param {Object} opts Additional options
           */
          async query(q, opts) {
            try {
              let suggestions = []
              let qry = `
                SELECT id, path, locale, title, description
                FROM "pagesVector", to_tsquery(?,?) query
                WHERE (query @@ "tokens" OR path ILIKE ?)
              `
              let qryEnd = `ORDER BY ts_rank(tokens, query) DESC`
              let qryParams = [this.config.dictLanguage, tsquery(q), `%${q.toLowerCase()}%`]
              if (opts.locale) {
                qry = `${qry} AND locale = ?`
                qryParams.push(opts.locale)
              }
              if (opts.path) {
                qry = `${qry} AND path ILIKE ?`
                qryParams.push(`%${opts.path}`)
              }
              const results = await WIKI.models.knex.raw(`
                ${qry}
                ${qryEnd}
              `, qryParams)
              if (results.rows.length < 5) {
                const suggestResults = await WIKI.models.knex.raw(`SELECT word, word <-> ? AS rank FROM "pagesWords" WHERE similarity(word, ?) > 0.2 ORDER BY rank LIMIT 5;`, [q, q])
                suggestions = suggestResults.rows.map(r => r.word)
              }
              return {
                results: results.rows,
                suggestions,
                totalHits: results.rows.length
              }
            } catch (err) {
              WIKI.logger.warn('Search Engine Error:')
              WIKI.logger.warn(err)
            }
          },
          /**
           * CREATE
           *
           * @param {Object} page Page to create
           */
          async created(page) {
            await WIKI.models.knex.raw(`
              INSERT INTO "pagesVector" (path, locale, title, description, "tokens") VALUES (
                ?, ?, ?, ?, (setweight(to_tsvector('${this.config.dictLanguage}', ?), 'A') || setweight(to_tsvector('${this.config.dictLanguage}', ?), 'B') || setweight(to_tsvector('${this.config.dictLanguage}', ?), 'C'))
              )
            `, [page.path, page.localeCode, page.title, page.description, page.title, page.description, page.safeContent])
          },
          /**
           * UPDATE
           *
           * @param {Object} page Page to update
           */
          async updated(page) {
            await WIKI.models.knex.raw(`
              UPDATE "pagesVector" SET
                title = ?,
                description = ?,
                tokens = (setweight(to_tsvector('${this.config.dictLanguage}', ?), 'A') ||
                setweight(to_tsvector('${this.config.dictLanguage}', ?), 'B') ||
                setweight(to_tsvector('${this.config.dictLanguage}', ?), 'C'))
              WHERE path = ? AND locale = ?
            `, [page.title, page.description, page.title, page.description, page.safeContent, page.path, page.localeCode])
          },
          /**
           * DELETE
           *
           * @param {Object} page Page to delete
           */
          async deleted(page) {
            await WIKI.models.knex('pagesVector').where({
              locale: page.localeCode,
              path: page.path
            }).del().limit(1)
          },
          /**
           * RENAME
           *
           * @param {Object} page Page to rename
           */
          async renamed(page) {
            await WIKI.models.knex('pagesVector').where({
              locale: page.localeCode,
              path: page.path
            }).update({
              locale: page.destinationLocaleCode,
              path: page.destinationPath
            })
          },
          /**
           * REBUILD INDEX
           */
          async rebuild() {
            WIKI.logger.info(`(SEARCH/POSTGRES) Rebuilding Index...`)
            await WIKI.models.knex('pagesVector').truncate()
            await WIKI.models.knex('pagesWords').truncate()
            await pipeline(
              WIKI.models.knex.column('path', 'localeCode', 'title', 'description', 'render').select().from('pages').where({
                isPublished: true,
                isPrivate: false
              }).stream(),
              new stream.Transform({
                objectMode: true,
                transform: async (page, enc, cb) => {
                  const content = WIKI.models.pages.cleanHTML(page.render)
                  await WIKI.models.knex.raw(`
                    INSERT INTO "pagesVector" (path, locale, title, description, "tokens", content) VALUES (
                      ?, ?, ?, ?, (setweight(to_tsvector('${this.config.dictLanguage}', ?), 'A') || setweight(to_tsvector('${this.config.dictLanguage}', ?), 'B') || setweight(to_tsvector('${this.config.dictLanguage}', ?), 'C')), ?
                    )
                  `, [page.path, page.localeCode, page.title, page.description, page.title, page.description, content,content])
                  cb()
                }
              })
            )
            await WIKI.models.knex.raw(`
              INSERT INTO "pagesWords" (word)
                SELECT word FROM ts_stat(
                  'SELECT to_tsvector(''simple'', "title") || to_tsvector(''simple'', "description") || to_tsvector(''simple'', "content") FROM "pagesVector"'
                )
              `)
            WIKI.logger.info(`(SEARCH/POSTGRES) Index rebuilt successfully.`)
          }
        }

    更新 wikijs 的 Deployment

    wiki.js 的基于 PostgreSQL 的全文檢索引擎配置位于 /wiki/server/modules/search/postgres ,我們將前面配置的 ConfigMap 加載到這個目錄。

    # wikijs-zh.yaml
    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: wikijs
      labels:
        app: wikijs
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: wikijs
      template:
        metadata:
          labels:
            app: wikijs
        spec:
          volumes:
            - name: volume-dysh5f
              configMap:
                name: wikijs-zhparser
                defaultMode: 420
          containers:
            - name: wikijs
              image: 'requarks/wiki:2'
              ports:
                - name: http-3000
                  containerPort: 3000
                  protocol: TCP
              envFrom:
                - secretRef:
                    name: wikijs
                - configMapRef:
                    name: wikijs
              volumeMounts:
                - name: volume-dysh5f
                  readOnly: true
                  mountPath: /wiki/server/modules/search/postgres

    配置 wiki.js ,啟用基于 PostgreSQL 的全文檢索

    • 重新 apply 新的 Delployment 文件后

    $ kubectl apply -f zh-parse.yaml
    $ kubectl apply -f wikijs-zh.yaml
    • 打開 wiki.js 管理

    • 點擊搜索引擎

    • 選擇 Database - PostgreSQL

    • 在 Dictionary Language 的下拉菜單里選擇 chinese_zh。

    • 點擊應用,并重建索引。

    • 完成配置。

    以上就是“KubeSphere中如何部署Wiki系統wiki.js并啟用中文全文檢索”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    平潭县| 襄城县| 牡丹江市| 岳西县| 华宁县| 正镶白旗| 延津县| 琼海市| 营山县| 新津县| 海盐县| 武平县| 忻州市| 天峻县| 蒲城县| 芜湖县| 阿荣旗| 甘孜县| 长沙市| 海兴县| 合阳县| 灵山县| 冀州市| 井研县| 迁安市| 托克托县| 永州市| 杂多县| 南华县| 柳林县| 黑龙江省| 石台县| 新余市| 瓦房店市| 盖州市| 邯郸市| 平罗县| 桐城市| 秦皇岛市| 攀枝花市| 信宜市|