构建wezzer平台!
redis
部署
[root@k8s-master redis]# ls
namespace.yaml redis-config.yaml redis-master.yaml redis-slave.yaml
[root@k8s-master redis]# cat namespace.yaml
apiVersion: v1
kind: Namespace
metadata:name: redis
[root@k8s-master redis]# cat redis-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: redis-confignamespace: redis
data:redis-master.conf: |port 6379bind 0.0.0.0protected-mode nodaemonize notimeout 0save ""appendonly nomaxmemory 1gbmaxmemory-policy allkeys-lruredis-slave.conf: |port 6379bind 0.0.0.0protected-mode nodaemonize notimeout 0save ""appendonly nomaxmemory 1gbmaxmemory-policy allkeys-lruslaveof redis-master-0.redis-master.redis.svc.cluster.local 6379slave-read-only yes
mysql
[root@k8s-master mysql]# ls
aaa_mysql.sh configmap.yaml init-scripts.yaml master.yaml mysql.yaml secret.yaml slave.yaml
[root@k8s-master mysql]# cat mysql.yaml
apiVersion: v1
kind: Namespace
metadata:name: mysql
[root@k8s-master mysql]# cat secret.yaml
apiVersion: v1
kind: Secret
metadata:name: mysql-secretsnamespace: mysql
type: Opaque
data:root-password: MTIzLmNvbQ== # 解码后:123.com
[root@k8s-master mysql]# cat init-scripts.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: mysql-init-scriptsnamespace: mysql
data:master-init.sql: |# 从环境变量获取密码(避免明文)CREATE USER IF NOT EXISTS 'rsyncuser'@'%' IDENTIFIED BY '123.com';GRANT REPLICATION SLAVE ON *.* TO 'rsyncuser'@'%';CREATE DATABASE IF NOT EXISTS discuz;CREATE USER IF NOT EXISTS 'discuz'@'%' IDENTIFIED BY '123.com';GRANT ALL PRIVILEGES ON discuz.* TO 'discuz'@'%';CREATE DATABASE IF NOT EXISTS biyesheji;CREATE USER IF NOT EXISTS 'tomcat'@'%' IDENTIFIED BY '123.com';GRANT ALL PRIVILEGES ON biyesheji.* TO 'tomcat'@'%';FLUSH PRIVILEGES;slave-init.sql: |CHANGE MASTER TOMASTER_HOST = 'mysql-master-0.mysql-master.mysql.svc.cluster.local',MASTER_PORT = 3306,MASTER_USER = 'rsyncuser',MASTER_PASSWORD = '123.com', # 从环境变量获取MASTER_AUTO_POSITION = 1;START SLAVE;
[root@k8s-master mysql]# cat configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: mysql-confignamespace: mysql
data:master.cnf: |[mysqld]server-id=10log_bin=/var/lib/mysql/mysql-bin.logread_only=0bind-address=0.0.0.0gtid_mode=ONenforce_gtid_consistency=ONdefault_authentication_plugin=mysql_native_passwordslave1.cnf: |[mysqld]server-id=20relay_log=/var/lib/mysql/mysql-relay-bin.loglog_bin=/var/lib/mysql/mysql-bin.logread_only=1bind-address=0.0.0.0gtid_mode=ONenforce_gtid_consistency=ONdefault_authentication_plugin=mysql_native_password
[root@k8s-master mysql]# cat master.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:name: mysql-masternamespace: mysql
spec:serviceName: mysql-masterreplicas: 1selector:matchLabels:app: mysql-mastertemplate:metadata:labels:app: mysql-masterspec:containers:- name: mysqlimage: mysql:8.0ports:- containerPort: 3306env:- name: MYSQL_ROOT_PASSWORDvalueFrom:secretKeyRef:name: mysql-secretskey: root-passwordvolumeMounts:- name: mysql-configmountPath: /etc/mysql/conf.d/master.cnfsubPath: master.cnf- name: master-init-script # 仅挂载主库脚本mountPath: /docker-entrypoint-initdb.d/master-init.sqlsubPath: master-init.sql # 明确指定脚本名volumes:- name: mysql-configconfigMap:name: mysql-configitems:- key: master.cnfpath: master.cnf- name: master-init-script # 关联 ConfigMap 中的主库脚本configMap:name: mysql-init-scriptsitems:- key: master-init.sqlpath: master-init.sql---
apiVersion: v1
kind: Service
metadata:name: mysql-masternamespace: mysql
spec:ports:- port: 3306name: mysqlclusterIP: Noneselector:app: mysql-master[root@k8s-master mysql]# cat slave.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:name: mysql-slavenamespace: mysql
spec:serviceName: mysql-slavereplicas: 1 selector:matchLabels:app: mysql-slavetemplate:metadata:labels:app: mysql-slavespec:containers:- name: mysqlimage: mysql:8.0ports:- containerPort: 3306env:- name: MYSQL_ROOT_PASSWORDvalueFrom:secretKeyRef:name: mysql-secretskey: root-passwordvolumeMounts:- name: mysql-configmountPath: /etc/mysql/conf.d/slave.cnfsubPath: slave1.cnf- name: init-scriptmountPath: /docker-entrypoint-initdb.dvolumes:- name: mysql-configconfigMap:name: mysql-configitems:- key: slave1.cnfpath: slave1.cnf- name: init-scriptconfigMap:name: mysql-init-scripts---
apiVersion: v1
kind: Service
metadata:name: mysql-slavenamespace: mysql
spec:ports:- port: 3306name: mysqlclusterIP: Noneselector:app: mysql-slave
web-nginx
构建自定义镜像
配置文件
nginx
server {listen 80;server_name localhost;root /var/www/html;index index.php index.html index.htm;access_log /var/log/nginx/discuz_access.log;error_log /var/log/nginx/discuz_error.log;location / {try_files $uri $uri/ /index.php?$query_string;}location ~ \.php$ {fastcgi_pass unix:/run/php/php83-fpm.sock;fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;include fastcgi_params;}location ~ /\.ht {deny all;}
}
php-fpm
[www]
user = nginx
group = nginx
listen = /run/php/php83-fpm.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3php_admin_value[error_log] = /var/log/php83/www-error.log
php_admin_flag[log_errors] = on
Dockerfile
FROM alpine:latest
RUN apk update && apk add --no-cache \php83 php83-fpm php83-mysqlnd php83-gd php83-mbstring \php83-curl php83-json php83-openssl php83-xml \php83-mysqli php83-tokenizer php83-pdo php83-pdo_mysql \nginx php83-redis vim
RUN mkdir -p \/run/nginx \/var/www/html \/run/php &&\chown -R nginx:nginx /var/www/html /run/nginx && \chmod 755 /var/www/html
#nginx配置
COPY discuz.conf /etc/nginx/http.d/default.conf
#php配置
COPY www.conf /etc/php83/php-fpm.d/www.conf
#暴露端口
EXPOSE 80
#运行
CMD ["sh","-c","php-fpm83 --nodaemonize & nginx -g 'daemon off;'"]
启动容器
编写测试文件
index.html
web-nginxinfo.php
<?phpphpinfo();
?>
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$host = 'mysql-master-0.mysql-master.mysql.svc.cluster.local'; // 数据库主机地址
$user = 'discuz'; // MySQL 用户名
$pass = '123.com'; // MySQL 用户密码
$dbname = 'discuz'; // 要连接的数据库名// 尝试连接 MySQL
$conn = new mysqli($host, $user, $pass, $dbname);// 检查连接错误
if ($conn->connect_error) {// 连接失败时终止脚本并输出错误die('连接失败:' . $conn->connect_error);
}// 连接成功,输出数据库版本信息
echo "MySQL 连接成功!数据库版本:" . $conn->server_info;
?>
<?php
$redis = new Redis();
try {// 连接Master(替换为你的实际地址和端口)$conn = $redis->connect('redis-master.redis.svc.cluster.local', 6379, 2); if ($conn) {echo "连接成功!";echo "Redis响应:" . $redis->ping(); // 测试服务响应} else {echo "连接失败(无错误信息)";}
} catch (RedisException $e) {// 打印具体错误(如:连接超时、拒绝连接、认证失败等)echo "Redis连接错误:" . $e->getMessage();
}
导入dicuz文件
docker cp ./ c37e6292ca17:/var/www/html/
修改属主
修改discuz默认配置(upload/config/)
config_global_default.php
数据库
从库
redis数据库
config_ucenter_default.php
镜像导出
[root@k8s-master web-nginx]# docker commit 9fbf6304f924 web-nginx:latest
sha256:79c04b1494346f3e4111229e2d902c40ee73c8beb1ad9d65df2111c0906fa73b
[root@k8s-master web-nginx]# docker save -o web-nginx.tar web-nginx:latest
镜像导入每个节点
部署web-nginx
编写 启动文件

启动
访问
默认即可
问题
出现这个页面时,将redi缓存清理就ok
taomcat
自定义镜像
下载镜像
docker pull tomcat:8
生成测试镜像
docker run -itd --name tomcat -v /root/xm/tomcat/shangcheng/:/usr/local/tomcat/webapps/ --restart=always tomcat:8
sql文件拷贝给mysql库
注入sql语句
将复制的 sql文件内容拷贝到 configmap.yaml 文件中
主配置 匹配cofihmap
volumeMounts:- name: biyesheji-sqlmountPath: /docker-entrypoint-initdb.d/biyesheji.sqlsubPath: biyesheji.sqlvolumes:- name: biyesheji-sqlconfigMap:name: mysql-configitems:- key: biyesheji.sqlpath: biyesheji.sql
验证
编写镜像

修改商城默认配置
vim WEB-INF/classes/jdbc.properties
vim /usr/local/tomcat/webapps/biyesheji/WEB-INF/classes/jdbc.properties
docker commit d44d4163 shangcheng:v1docker save -o shangcheng.tar a4e0365
将镜像拷给各节点
docker tag a4e036 shangcheng:v1如果
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> a4e0365f328b 6 minutes ago 208MB
部署商城
apiVersion: v1
kind: Namespace
metadata:name: web
---
apiVersion: apps/v1
kind: Deployment
metadata:name: dep-tomcatnamespace: web
spec:replicas: 1selector:matchLabels:app: web-tomcattemplate:metadata:labels:app: web-tomcatspec:containers:- name: tomcatimage: shangcheng:v1 # 使用你的镜像imagePullPolicy: IfNotPresentports:- containerPort: 8080 # 容器内暴露的端---
apiVersion: v1
kind: Service
metadata:name: svc-tomcatnamespace: web # 指定命名空间为 discuz
spec:type: NodePortports:- port: 8080 # 集群内访问端口targetPort: 8080 # 容器内端口nodePort: 30808 # 对外暴露的节点端口selector:app: web-tomcat # 匹配 Deployment 的标签
启动
结论
访问成功(/biyesheji/fore/foreIndex/)
discuz与nginx基于域名访问
拷贝镜像并导入
解压并提交
loadbalance模式
kubectl -n ingress-nginx edit svc ingress-nginx-controller
创建ip池
cat >IPAddressPool.yaml<<EOF
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:name: planip-pool #这里与下面的L2Advertisement的ip池名称需要一样namespace: metallb-system
spec:addresses:- 192.168.111.140-192.168.11.170 #自定义ip段
EOF
关联IP池
cat >L2Advertisement.yaml<<EOF
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:name: planip-poolnamespace: metallb-system
spec:ipAddressPools:- planip-pool #这里需要跟上面ip池的名称保持一致
EOF
提交
kubectl apply -f IPAddressPool.yaml
kubectl apply -f L2Advertisement.yaml
添加规则
kubectl apply -f ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress # 创建一个类型为Ingress的资源
metadata:name: nginx-ingress # 这个资源的名字为 nginx-ingressnamespace: web
spec:ingressClassName: nginx # 使用nginxrules:- host: nginx.wezzer.com # 访问此内容的域名http:paths:- backend:service:name: svc-discuz # 对应nginx的服务名字,该规则的namespace必须与service的一致port:number: 80 # 访问的端口path: / # 匹配规则pathType: Prefix # 匹配类型,这里为前缀匹配- host: tomcat.wezzer.com # 访问此内容的域名http:paths:- backend:service:name: svc-tomcat # 对应nginx的服务名字,该规则的namespace必须与service的一致port:number: 8080 # 访问的端口path: / # 匹配规则pathType: Prefix # 匹配类型,这里为前缀匹配