完成上篇Ghost/SQLite搭建,现在继续试验Wikijs:
本案例使用:wikijs.wuushu.cn
- 将wikijs.wuushu.cn域名解析到CNAME的alb-***.cn-hongkong.alb.aliyuncs.com
- 进入ASK-ALLINONE集群,点击【命名空间与配额】,点击【创建】,创建namespace为wikijs的ns空间。
- 因为我们之前的项目已在同一个集群创建过【存储】下的pv-mntnas-ghost【存储卷】,存储卷类型:NAS,所以本项目不再创建PV。
- 【配置管理】>【保密字典】,创建PostgreSQL的secret
- 点击【使用YAML创建资源】
-
apiVersion: v1 data: POSTGRES_PASSWORD: d2lraWpzcm9ja3M= kind: Secret metadata: name: wikijs-postgres-prod-secrets namespace: wikijs type: Opaque
- d2lraWpzcm9ja3M= 这个是64base编码。
- 转换密码编码可以到Base64 Encode and Decode,可以encode密码wikijsrocks,取消默认勾选的Perform URL-safe encoding,否则密码encode后[可能]没有最后的等号=,阿里云ASK里不认。
- 不想麻烦也可以先创建:
-
apiVersion: v1 kind: Secret metadata: name: wikijs-postgres-prod-secrets namespace: wikijs type: Opaque
- 然后在条目编辑这条secret,手工添加密码名称POSTGRES_PASSWORD和值wikijsrocks,保存后点开YAML可以看到密码自动变成64base编码的d2lraWpzcm9ja3M=
- 点击【配置管理】下【配置项】,创建PostgreSQL的Configmap,用来初始化数据库。
-
apiVersion: v1 data: init.sql: |- CREATE DATABASE wikijs; CREATE USER wikijs with password 'wikijsrocks'; 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; kind: ConfigMap metadata: name: wikijs-postgres-prod-init namespace: wikijs
创建PostgresSQL的部署
点击【工作负载】下的【无状态】,切换命名空间为【wikijs】,点击【使用镜像创建】
- 应用名称:【wikijs-postgres-prod】
- 副本数量:1
- 类型:无状态
- 点击【下一步】
- 镜像名称:【postgres】
- 镜像Tag:【14.4-alpine】
- 所需资源:0.5核1GB
- 端口新增:名称prosgres-port,容器端口5432,TCP
- 环境变量:点击【从镜像元数据中获取】,会出现四个键值:LANG,PG_MAJOR,PG_SHA256,PGDATA
- 点击【新增】,保密字典类型,变量名称POSTGRES_PASSWORD,选择变量/变量引用:wikijs-prostgres-prod-secrets/POSTGRES_PASSWORD
- 点击【新增】两个自定义类型,变量名称POSTGRES_DB和POSTGRES_USER,变量/变量引用都为wikijs
- 在下方数据卷,增加本地存储,存储卷类型为配置项,挂载源选择wikijs-prostgres-prod-init,容器路径为/docker-entrypoint-initdb.d,子路径留空
- 在数据卷,增加NAS
名称:wikijs-postgres-prod-data
NAS地址:***.cn-hongkong.extreme.nas.aliyuncs.com
主机路径:/base/wikijs/postgresql/data
容器路径:/var/lib/postgresql/data
记得提前用宝塔ECS在NAS数据盘创建文件夹/mntNAS/base/wikijs/postgresql/data
点击【下一步】
创建【服务】wikijs-postgres-prod-svc,虚拟集群ip,端口名称svcpostgresport,服务端口5432,容器端口5432,协议TCP,点击【创建】
用宝塔ECS查看NAS目录/mntNAS/base/wikijs/postgresql/data,看到初始数据创建成功。
Wikijs镜像上传
因为阿里云集群镜像没有wikijs,先将镜像推送到我们在阿里云的容器镜像服务(我用的个人版)
在宝塔ECS的软件商店安装好Docker管理器3.9.1,进入终端,拉取最新镜像到本地,并查看镜像id。
docker pull ghcr.io/requarks/wiki:2
docker images
登录阿里云容器镜像服务器并输入密码:
docker login --username=电邮地址 registry-intl.cn-hongkong.aliyuncs.com
标识镜像:
docker tag 1c41907b9dcd registry-intl.cn-hongkong.aliyuncs.com/我的空间/wikijs-prod:2
将本地镜像推送到阿里云容器镜像服务中心:
docker push registry-intl.cn-hongkong.aliyuncs.com/我的空间/wikijs-prod:2
创建Wikijs的部署
准备工作:创建配置项Configmap
apiVersion: v1
data:
DB_HOST: 使用上面创建的wikijs-postgres-prod-svc服务的集群ip
DB_NAME: wikijs
DB_USER: wikijs
DB_PASS: wikijsrocks
DB_PORT: '5432'
DB_TYPE: postgres
HA_ACTIVE: 'true'
kind: ConfigMap
metadata:
name: wikijs-prod-cm
namespace: wikijs
点击【工作负载】下的【无状态】,命名空间为【wikijs】,点击【使用镜像创建】
- 应用名称:【wikijs-prod】
- 副本数量:1
- 类型:无状态
- 点击【下一步】
- 镜像名称:【registry-intl-vpc.cn-hongkong.aliyuncs.com/我的空间/wikijs-prod】
- 镜像Tag:【2】
- 所需资源:0.5核1GB
- 端口新增:名称wikijs-port,容器端口3000,协议TCP
- 环境变量:点击【新增】七个配置项类型,变量名称分别为:DB_HOST,DB_NAME,DB_PORT,DB_TYPE,HA_ACTIVE,DB_USER,DB_PASS,变量/变量引用都为wikijs-prod-cm,最后一个下拉菜单选择对应项,点击【下一步】
注:我也尝试用新增两个保密字典DB_USER和DB_PASS,但是貌似传到数据库的编码有问题,不能验证密码,连不上DB,所以DB用户密码直接配置在Configmap。(下文更新后记解决了这个问题,用YAML)
创建【服务】wikijs-prod-svc,虚拟集群ip,端口名称svcwikijsport,服务端口80,容器端口3000,协议TCP,点击【创建】
点击【网络】下【路由】,点击【创建ALB Ingress】
- 名称:wikijs-prod-albingress
- 域名:wikijs.wuushu.cn
- 路径:/*
- 服务名称选择wikijs-prod-svc,端口80,勾选开启TLS因为阿里云有证书自动发现功能,所以不用配置ssl,勾选TLS后记得加上自定义注解:alb.ingress.kubernetes.io/ssl-redirect 为 true
这个首次配置时,不像ghost只能http,可以选择https作为site url,不会无限重定向。至此,集群的Wikijs的维基词条系统就搭建好了,可自由伸缩;我们下面在ASK集群建立:Wordpress,Php8.1,MySQL8.0.4
上面的数据库创建的是无状态,我们可以将其先缩减为0,然后用yaml创建一个有状态的pod,记的先清空postgresdb的文件夹:/base/wikijs/postgresql/data
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: wikijs-postgres-prod
name: wikijs-postgres-prod
namespace: wikijs
spec:
selector:
matchLabels:
app: wikijs-postgres-prod
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: wikijs-postgres-prod
spec:
containers:
- env:
- name: LANG
value: en_US.utf8
- name: PG_MAJOR
value: '14'
- name: PG_SHA256
value: c23b6237c5231c791511bdc79098617d6852e9e3bdf360efd8b5d15a1a3d8f6a
- name: PGDATA
value: /var/lib/postgresql/data
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
key: POSTGRES_PASSWORD
name: wikijs-postgres-prod-secrets
- name: POSTGRES_DB
value: wikijs
- name: POSTGRES_USER
value: wikijs
image: 'postgres:14.4-alpine'
imagePullPolicy: IfNotPresent
name: wikijs-postgres-prod
ports:
- containerPort: 5432
name: prosgres-port
protocol: TCP
resources:
requests:
cpu: 500m
memory: 1Gi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /docker-entrypoint-initdb.d
name: volume-***
- mountPath: /var/lib/postgresql/data
name: wikijs-postgre-prod-data
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- configMap:
defaultMode: 420
name: wikijs-postgres-prod-init
name: volume-***
- name: wikijs-postgre-prod-data
nfs:
path: /base/wikijs/postgresql/data
server: ***.nas.aliyuncs.com
成功后,将之前无状态且缩减为零的有状态数据库pod删除,删除的时候会问要不要删除关联的服务svc,不要删除。
==========================
后记:在阿里云用YAML配置Wikijs
Wikijs PostgreSQL Secret
apiVersion: v1
data:
POSTGRES_PASSWORD: cm9vdHBhc3N3b3Jk(这个是root password 的 base64)
kind: Secret
metadata:
name: prod-wikijs-postgres-secrets
namespace: prod-wikijs
type: Opaque
Wikijs APP Secret
apiVersion: v1
data:
DB_PASS: eW91ci1kYi1wYXNzd29yZA==(这个是your-db-password 的 base64)
kind: Secret
metadata:
name: prod-wikijs-secrets
namespace: prod-wikijs
type: Opaque
Wikijs PostgreSQL Configmap
apiVersion: v1
data:
init.sql: |-
CREATE DATABASE dbname;
CREATE USER dbuser with password 'your-db-password';
GRANT CONNECT ON DATABASE dbname to dbuser;
GRANT USAGE ON SCHEMA public TO dbuser;
GRANT SELECT,update,INSERT,delete ON ALL TABLES IN SCHEMA public TO dbuser;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO dbname;
kind: ConfigMap
metadata:
name: prod-wikijs-postgres-cm-sqlinit
namespace: prod-wikijs
Wikijs APP Configmap
apiVersion: v1
data:
DB_HOST: 1.1.1.1
DB_PORT: '5432'
DB_TYPE: postgres
HA_ACTIVE: 'true'
DB_NAME: dbname
DB_USER: dbuser
kind: ConfigMap
metadata:
name: prod-wikijs-configmap
namespace: prod-wikijs
Wikijs Postgres Stateful POD
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: prod-wikijs-postgres
name: prod-wikijs-postgres
namespace: prod-wikijs
spec:
replicas: 1
selector:
matchLabels:
app: prod-wikijs-postgres
template:
metadata:
labels:
app: prod-wikijs-postgres
spec:
containers:
- env:
- name: LANG
value: en_US.utf8
- name: PG_MAJOR
value: '14'
- name: PG_SHA256
value: c23b6237c5231c791511bdc79098617d6852e9e3bdf360efd8b5d15a1a3d8f6a
- name: PGDATA
value: /var/lib/postgresql/data
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
key: POSTGRES_PASSWORD
name: prod-wikijs-postgres-secrets
image: 'postgres:14.4-alpine'
imagePullPolicy: IfNotPresent
name: prod-wikijs-postgres
ports:
- containerPort: 5432
name: prosgres-port
protocol: TCP
resources:
requests:
cpu: 500m
memory: 1Gi
volumeMounts:
- mountPath: /docker-entrypoint-initdb.d
name: volume-initsql
- mountPath: /var/lib/postgresql/data
name: prod-wikijs-postgres-data
dnsPolicy: ClusterFirst
restartPolicy: Always
volumes:
- configMap:
defaultMode: 420
name: prod-wikijs-postgres-cm-sqlinit
name: volume-initsql
- name: prod-wikijs-postgres-data
nfs:
path: /base/prod-wikijs-postgres
server: ***.nas.aliyuncs.com
Wikijs Postgres Service
apiVersion: v1
kind: Service
metadata:
name: prod-svc-wikijs-postgres
namespace: prod-wikijs
spec:
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: svcpostgresport
port: 5432
protocol: TCP
targetPort: 5432
selector:
app: prod-wikijs-postgres
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
注:将configmap创建后生成的service ip替换之前的DB_HOST: 1.1.1.1
Wikijs APP Stateful POD
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: prod-wikijs
name: prod-wikijs
namespace: prod-wikijs
spec:
replicas: 1
selector:
matchLabels:
app: prod-wikijs
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: prod-wikijs
spec:
containers:
- env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
key: DB_HOST
name: prod-wikijs-configmap
- name: DB_NAME
valueFrom:
configMapKeyRef:
key: DB_NAME
name: prod-wikijs-configmap
- name: DB_PORT
valueFrom:
configMapKeyRef:
key: DB_PORT
name: prod-wikijs-configmap
- name: DB_TYPE
valueFrom:
configMapKeyRef:
key: DB_TYPE
name: prod-wikijs-configmap
- name: HA_ACTIVE
valueFrom:
configMapKeyRef:
key: HA_ACTIVE
name: prod-wikijs-configmap
- name: DB_USER
valueFrom:
configMapKeyRef:
key: DB_USER
name: prod-wikijs-configmap
- name: DB_PASS
valueFrom:
secretKeyRef:
key: DB_PASS
name: prod-wikijs-secrets
image: 'registry***.aliyuncs.com/***/wikijs-prod:2'
imagePullPolicy: IfNotPresent
name: prod-wikijs
ports:
- containerPort: 3000
name: wikijs-port
protocol: TCP
resources:
requests:
cpu: 500m
memory: 1Gi
dnsPolicy: ClusterFirst
restartPolicy: Always
Wikijs APP Service
apiVersion: v1
kind: Service
metadata:
name: prod-svc-wikijs
namespace: prod-wikijs
spec:
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: svcwikijsport
port: 80
protocol: TCP
targetPort: 3000
selector:
app: prod-wikijs
type: ClusterIP
status:
loadBalancer: {}
ALB Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/ssl-redirect: 'true'
alb.ingress.kubernetes.io/backend-protocol: "HTTPS"
kubernetes.io/ingress.class: alb
finalizers:
- ingress.k8s.alibaba/resources
generation: 1
name: prod-albingress-wikijs
namespace: prod-wikijs
spec:
rules:
- host: a.b.c 域名,不带https或http
http:
paths:
- backend:
service:
name: prod-svc-wikijs
port:
number: 80
path: /*
pathType: ImplementationSpecific
tls:
- hosts:
- a.b.c 域名,不带https或http
成功
需要集群安装CoreDNS组件,才能用service名称替换集群虚拟ip,否则只能用service集群虚拟ip
DB_HOST: prod-svc-wikijs-postgres
因此可以删除之前两个svc,在svc的yaml的spec下加入headless,这样就不用ip链接数据库
spec:
clusterIP: None
clusterIPs:
- None
后后记:
同上一篇ghost,用PVC代替直连PV