背景 团队计划基于 kubernetes 搭建一套云原生的开发平台,集成项目管理、需求管理、 BUG 管理、在线 IDE 、 gitops 、代码检查 、 自动测试、知识库等功能。 xwiki 是优秀的开源 wiki 系统,基于 java 开发,目前更新还比较活跃, 正好需要一个 wiki 来做知识库管理,决定选他了。 以下工作是在 kubernetes 1.23.0 已经部署好的情况下进行的。部署 kubernetes 可以参考我另外的文章 "kubesphere 多节点集群安装"准备storageclass 我们使用 openebs作为存储,openebs默认安装的 local storageclass 在 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: "" 部署 mysql 在 kubernetes 环境下,因为 pod 都是动态创建的,采用传统的 ENV 环境变量来传递信息,存在敏感信息泄露的风险,推荐使用 secret 来保存敏感的配置信息,同时也可以方便动态绑定到 pod。 推荐使用 configmap 保存 pod 需要的其他配置信息。这样可以跟 pod 更好的配合。准备用户名密码配置 我们使用 secret 保存 mysql 用户名密码等敏感信息。kind: Secret apiVersion: v1 metadata: name: xwiki-mysql data: MYSQL_DATABASE: eHdpa2k= MYSQL_PASSWORD: 自行填写 MYSQL_USER: eHdpa2k= MYSQL_ROOT_PASSWORD: 自行填写 type: Opaque 创建 configmap 我们使用 configmap 保存 mysql 的配置文件,以及数据库初始化文件。apiVersion: v1 kind: ConfigMap metadata: name: xwiki-mysql-cnf data: xwiki.cnf: |- [client] default-character-set = utf8mb4 [mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_bin explicit_defaults_for_timestamp = 1 [mysql] default-character-set = utf8mb4 --- apiVersion: v1 kind: ConfigMap metadata: name: xwiki-mysql-init data: init.sql: |- grant all privileges on *.* to xwiki@"%" 准备存储 我们使用 openesb 来提供存储服务。可以通过 创建 pvc 来提供持久化存储。 这里声明一个 10G 的 pvc--- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: xwiki-db-data finalizers: - kubernetes.io/pvc-protection spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: localretain volumeMode: Filesystem 部署 mysql 数据库 在前面的步骤准备好各种配置信息和存储后,就可以开始部署 mysql 服务了。 我们的 kubernetes 没有配置 存储阵列,使用的是 openesb 作为存储,我们使用 deployment 来部署 mysql 服务。apiVersion: apps/v1 kind: Deployment metadata: labels: app: xwiki-db name: xwiki-db spec: replicas: 1 selector: matchLabels: app: xwiki-db template: metadata: labels: app: xwiki-db spec: containers: - name: db imagePullPolicy: IfNotPresent image: "mysql:5.7" ports: - name: tcp-3306 protocol: TCP containerPort: 3306 envFrom: - secretRef: name: xwiki-mysql volumeMounts: - name: xwiki-db-data readOnly: false mountPath: /var/lib/mysql - name: xwiki-mysql-cnf readOnly: true mountPath: /etc/mysql/conf.d - name: xwiki-mysql-init readOnly: true mountPath: /docker-entrypoint-initdb.d volumes: - name: xwiki-db-data persistentVolumeClaim: claimName: xwiki-db-data - name: xwiki-mysql-cnf configMap: name: xwiki-mysql-cnf - name: xwiki-mysql-init configMap: name: xwiki-mysql-init 创建供 xwiki 访问的 serviceapiVersion: v1 kind: Service metadata: name: xwiki-db spec: selector: app: xwiki-db ports: - protocol: TCP port: 3306 targetPort: tcp-3306 完成 mysql 部署。 测试略部署 xwiki准备用户名密码配置 我们使用 secret 保存 xwiki 用于连接数据库的用户名密码等敏感信息。apiVersion: v1 kind: Secret apiVersion: v1 metadata: name: xwiki-web data: DB_HOST: eHdpa2ktZGI= DB_PASSWORD: 自行填写 DB_USER: eHdpa2k= type: Opaque 准备存储pvc 我们使用 openesb 来提供存储服务。可以通过 创建 pvc 来提供持久化存储。 这里声明一个 50G 的 pvckind: PersistentVolumeClaim apiVersion: v1 metadata: name: xwiki-web-data finalizers: - kubernetes.io/pvc-protection spec: accessModes: - ReadWriteOnce resources: requests: storage: 50Gi storageClassName: localretain volumeMode: Filesystem 部署 xwiki 在前面的步骤准备好各种配置信息和存储后,就可以开始部署 xwiki 服务了。apiVersion: apps/v1 kind: Deployment metadata: labels: app: xwiki name: xwiki spec: replicas: 1 selector: matchLabels: app: xwiki template: metadata: labels: app: xwiki spec: containers: - name: xwiki image: "xwiki:mysql-tomcat" ports: - name: http-8080 protocol: TCP containerPort: 8080 envFrom: - secretRef: name: xwiki-web volumeMounts: - name: xwiki-web-data readOnly: false mountPath: /usr/local/xwiki volumes: - name: xwiki-web-data persistentVolumeClaim: claimName: xwiki-web-data 创建供 xwiki 的 serviceapiVersion: v1 kind: Service metadata: name: xwiki spec: selector: app: xwiki ports: - protocol: TCP port: 8080 targetPort: http-8080 创建集群外访问的 Ingresskind: Ingress apiVersion: networking.k8s.io/v1 metadata: name: xwiki spec: ingressClassName: nginx rules: - host: xwiki.ipincloud.cn http: paths: - path: / pathType: ImplementationSpecific backend: service: name: xwiki port: number: 8080 完整的 yaml 文件 以下是完整的通过 deployment 部署 mysql 数据库和 xwiki 的 yaml 文件,保存为 xwiki.yaml 。apiVersion: v1 kind: Secret apiVersion: v1 metadata: name: xwiki-web data: DB_HOST: eHdpa2ktZGI= DB_PASSWORD: 自行填写 DB_USER: eHdpa2k= type: Opaque --- kind: Secret apiVersion: v1 metadata: name: xwiki-mysql data: MYSQL_DATABASE: eHdpa2k= MYSQL_PASSWORD: 自行填写 MYSQL_USER: eHdpa2k= MYSQL_ROOT_PASSWORD: 自行填写 type: Opaque --- apiVersion: v1 kind: ConfigMap metadata: name: xwiki-mysql-cnf data: xwiki.cnf: |- [client] default-character-set = utf8mb4 [mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_bin explicit_defaults_for_timestamp = 1 [mysql] default-character-set = utf8mb4 --- apiVersion: v1 kind: ConfigMap metadata: name: xwiki-mysql-init data: init.sql: |- grant all privileges on *.* to xwiki@"%" --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: xwiki-web-data finalizers: - kubernetes.io/pvc-protection spec: accessModes: - ReadWriteOnce resources: requests: storage: 50Gi storageClassName: localretain volumeMode: Filesystem --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: xwiki-db-data finalizers: - kubernetes.io/pvc-protection spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: localretain volumeMode: Filesystem --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: xwiki-db name: xwiki-db spec: replicas: 1 selector: matchLabels: app: xwiki-db template: metadata: labels: app: xwiki-db spec: containers: - name: db imagePullPolicy: IfNotPresent image: "mysql:5.7" ports: - name: tcp-3306 protocol: TCP containerPort: 3306 envFrom: - secretRef: name: xwiki-mysql volumeMounts: - name: xwiki-db-data readOnly: false mountPath: /var/lib/mysql - name: xwiki-mysql-cnf readOnly: true mountPath: /etc/mysql/conf.d - name: xwiki-mysql-init readOnly: true mountPath: /docker-entrypoint-initdb.d volumes: - name: xwiki-db-data persistentVolumeClaim: claimName: xwiki-db-data - name: xwiki-mysql-cnf configMap: name: xwiki-mysql-cnf - name: xwiki-mysql-init configMap: name: xwiki-mysql-init --- apiVersion: v1 kind: Service metadata: name: xwiki-db spec: selector: app: xwiki-db ports: - protocol: TCP port: 3306 targetPort: tcp-3306 --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: xwiki name: xwiki spec: replicas: 1 selector: matchLabels: app: xwiki template: metadata: labels: app: xwiki spec: containers: - name: xwiki image: "xwiki:mysql-tomcat" ports: - name: http-8080 protocol: TCP containerPort: 8080 envFrom: - secretRef: name: xwiki-web volumeMounts: - name: xwiki-web-data readOnly: false mountPath: /usr/local/xwiki volumes: - name: xwiki-web-data persistentVolumeClaim: claimName: xwiki-web-data --- apiVersion: v1 kind: Service metadata: name: xwiki spec: selector: app: xwiki ports: - protocol: TCP port: 8080 targetPort: http-8080 --- kind: Ingress apiVersion: networking.k8s.io/v1 metadata: name: xwiki spec: ingressClassName: nginx rules: - host: xwiki.ipincloud.cn http: paths: - path: / pathType: ImplementationSpecific backend: service: name: xwiki port: number: 8080 直接执行可以创建好 xwikikubectl apply -f xwiki.yaml