案例: 使用持久卷和CM等部署 WordPress和 MySQL
在kubernetes 部署 wordpress,要安装以下组件
- kubernetes
- flannel
- metallb
- NFS StorageClass
- ingress-nginx
wordpress 需求
- 独立部署deployment实现两个wordpress Pod实例实现负载均衡和高可用
- 它们使用NFS StorageClass 存储卷存储用户上传的图片或文件等数据;以ConfigMap和Secret提供必要的配置
- 部署一个MySQL数据库,使用NFS StorageClass 存储卷存储,以ConfigMap和Secret提供必要的配置
- service 暴露 wordpress 的服务
- 基于www.ming.org 域名结合ingress 暴露 wordpress 的服务
部署 Metallb 的 LoadBalancer 服务
[root@master1 metallb]# kubectl get node NAME STATUS ROLES AGE VERSION master1.org Ready control-plane 12d v1.35.4 node1.org Ready <none> 12d v1.35.4 node2.org Ready <none> 12d v1.35.4 node3.org Ready <none> 12d v1.35.4
#下载指定版本
METALLB_VERSION='v0.15.3'
wget https://raw.githubusercontent.com/metallb/metallb/${METALLB_VERSION}/config/manifests/metallb-native.yaml
kubectl apply -f metallb-native.yaml
#指定IP地址池
[root@master1 metallb]# cat service-metallb-IPAddressPool.yaml apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata:name: localip-poolnamespace: metallb-system spec:addresses:- 192.168.3.10-192.168.3.50autoAssign: trueavoidBuggyIPs: true
[root@master1 metallb]# cat service-metallb-L2Advertisement.yaml apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata:name: localip-pool-l2anamespace: metallb-system spec:ipAddressPools:- localip-poolinterfaces:- ens33
kubectl apply -f service-metallb-IPAddressPool.yaml
kubectl apply -f service-metallb-L2Advertisement.yaml
kubectl get all -n metallb-system
[root@master1 ~]# kubectl get all -n metallb-system NAME READY STATUS RESTARTS AGE pod/controller-7f475568c5-kdjph 1/1 Running 2 (3h18m ago) 40h pod/speaker-hhwb4 1/1 Running 4 (28h ago) 41h pod/speaker-rxq95 1/1 Running 5 (3h18m ago) 41h pod/speaker-x729x 1/1 Running 5 (3h18m ago) 41h pod/speaker-zqbkg 1/1 Running 5 (3h18m ago) 41hNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/metallb-webhook-service ClusterIP 10.110.45.159 <none> 443/TCP 41hNAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset.apps/speaker 3 3 3 3 3 kubernetes.io/os=linux 41hNAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/controller 1/1 1 1 41hNAME DESIRED CURRENT READY AGE replicaset.apps/controller-7f475568c5 1 1 1 41h
root@master1 ~]# kubectl get IPAddressPool -n metallb-system NAME AUTO ASSIGN AVOID BUGGY IPS ADDRESSES localip-pool true true ["192.168.3.10-192.168.3.50"]
准备基于NFS的 StorageClass
创建 NFS 服务
#NFS服务器软件安装
# 安装 nfs-utils(包含 nfs-server 服务)
dnf install -y nfs-utils
# 启动并设置开机自启
systemctl enable --now nfs-server
# 验证状态
systemctl status nfs-server
mkdir -p /data/sc-nfs/
#授权worker节点的网段可以挂载
[root@master1 ~]# cat /etc/exports #/data/nfsshare 192.168.3.0/24(rw,sync,no_root_squash) #/nfsdata *(rw,no_root_squash) /data/sc-nfs *(rw,no_root_squash)
[root@master1 ~]# exportfs -r [root@master1 ~]# exportfs -v /data/sc-nfs <world>(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,no_root_squash,no_all_squash)
#并在所有worker节点安装NFS客户端
dnf install -y nfs-utils
#在所有节点节点添加nfs..org的域名解析指定NFS服务器的地址
[root@node1 ~]# [root@node1 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.3.60 kubeapi.org kubeapi 192.168.3.60 master1.org master1 192.168.3.60 nfs.org master1 192.168.3.61 master2.org master2 192.168.3.62 master3.org master3 192.168.3.63 node1.org node1 192.168.3.64 node2.org node2 192.168.3.65 node3.org node3 192.168.3.66 ha1.org ha1 192.168.3.67 ha2.org ha2
创建 ServiceAccount 并授权
#建议创建独立的名称空间
kubectl create ns sc-nfs
[root@master1 sc-nfs]# cat rbac.yaml apiVersion: v1 kind: ServiceAccount metadata:name: nfs-client-provisioner# replace with namespace where provisioner is deployed#namespace: defaultnamespace: sc-nfs --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata:name: nfs-client-provisioner-runner rules:- apiGroups: [""]resources: ["nodes"]verbs: ["get", "list", "watch"]- apiGroups: [""]resources: ["persistentvolumes"]verbs: ["get", "list", "watch", "create", "delete"]- apiGroups: [""]resources: ["persistentvolumeclaims"]verbs: ["get", "list", "watch", "update"]- apiGroups: ["storage.k8s.io"]resources: ["storageclasses"]verbs: ["get", "list", "watch"]- apiGroups: [""]resources: ["events"]verbs: ["create", "update", "patch"] --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata:name: run-nfs-client-provisioner subjects:- kind: ServiceAccountname: nfs-client-provisioner# replace with namespace where provisioner is deployed#namespace: defaultnamespace: sc-nfs roleRef:kind: ClusterRolename: nfs-client-provisioner-runnerapiGroup: rbac.authorization.k8s.io --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata:name: leader-locking-nfs-client-provisioner# replace with namespace where provisioner is deployed#namespace: defaultnamespace: sc-nfs rules:- apiGroups: [""]resources: ["endpoints"]verbs: ["get", "list", "watch", "create", "update", "patch"] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata:name: leader-locking-nfs-client-provisioner# replace with namespace where provisioner is deployed#namespace: defaultnamespace: sc-nfs subjects:- kind: ServiceAccountname: nfs-client-provisioner# replace with namespace where provisioner is deployed#namespace: defaultnamespace: sc-nfs roleRef:kind: Rolename: leader-locking-nfs-client-provisionerapiGroup: rbac.authorization.k8s.io
kubectl apply -f rbac.yaml
[root@master1 sc-nfs-1]# kubectl get sa -n sc-nfs NAME AGE default 3d8h nfs-client-provisioner 3d8h
部署 NFS-Subdir-External-Provisioner 对应的 Deployment
[root@master1 sc-nfs-1]# cat nfs-client-provisioner.yaml apiVersion: apps/v1 kind: Deployment metadata:name: nfs-client-provisionerlabels:app: nfs-client-provisioner# replace with namespace where provisioner is deployed#namespace: defaultnamespace: sc-nfs spec:replicas: 1strategy:type: Recreateselector:matchLabels:app: nfs-client-provisionertemplate:metadata:labels:app: nfs-client-provisionerspec:serviceAccountName: nfs-client-provisionercontainers:- name: nfs-client-provisionerimage: registry.cn-beijing.aliyuncs.com/wangxiaochun/nfs-subdir-external-provisioner:v4.0.2#image: wangxiaochun/nfs-subdir-external-provisioner:v4.0.2#image: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2imagePullPolicy: IfNotPresentvolumeMounts:- name: nfs-client-rootmountPath: /persistentvolumesenv:- name: PROVISIONER_NAMEvalue: k8s-sigs.io/nfs-subdir-external-provisioner #名称确保与 nfs-StorageClass.yaml文件中的provisioner名称保持一致- name: NFS_SERVERvalue: nfs.org # NFS SERVER_IP - name: NFS_PATHvalue: /data/sc-nfs # NFS 共享目录volumes:- name: nfs-client-rootnfs:server: nfs.org # NFS SERVER_IP path: /data/sc-nfs # NFS 共享目录
通过第三方软件管理实现nfs动态置备功能
需要设置环境变量
通过第三方软件管理nfs服务器 /data/sc-nfs下的子目录 每个子目录自动创建对应pv
kubectl apply -f nfs-client-provisioner.yaml
[root@master1 sc-nfs]# kubectl get pod -n sc-nfs -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-d5dc647db-w8gxw 1/1 Running 0 28s 10.244.2.187 node2.org <none> <none>
#注意:如果失败,检查是否worker节点安装了nfs-client
创建 NFS 资源的 StorageClass
StorageClass 作用声明使用第三方置备软件管理pv
[root@master1 sc-nfs-1]# cat nfs-StorageClass.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata:name: sc-nfs annotations:storageclass.kubernetes.io/is-default-class: "true" # 是否设置为默认的storageclass provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME' parameters:archiveOnDelete: "true" # 设置为"false"时删除PVC不会保留数据,"true"则保留数据
#应用
kubectl apply -f nfs-StorageClass.yaml
#查看是否创建
[root@master1 sc-nfs-1]# kubectl get sc -n sc-nfs NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE sc-nfs (default) k8s-sigs.io/nfs-subdir-external-provisioner Delete Immediate false 3d8h
#提前准备名为sc-nfs的storage Class
部署 MySQL的相关资源
[root@master1 sc-nfs-1]# cat storage-wordpress-mysql.yaml apiVersion: v1 kind: Secret metadata:name: mysql-pass type: kubernetes.io/basic-auth #type: Opaque #也可以用Opaque类型 data:root_password: MTIzNDU2 #key名称:password,value为123456user_password: MTIzNDU2 #key名称:password,value为123456--- apiVersion: v1 kind: Service metadata:name: mysqllabels:app: mysql spec:ports:- port: 3306selector:app: wordpresstier: mysqlclusterIP: None --- apiVersion: v1 kind: PersistentVolumeClaim metadata:name: mysql-pv-claimlabels:app: wordpress spec:#storageClassName: sc-nfs #需要和前面创建的storageClass名称相同,如果是默认的storageClass,此项可选accessModes:- ReadWriteOnceresources:requests:storage: 20Gi --- apiVersion: apps/v1 kind: Deployment metadata:name: mysqllabels:app: wordpress spec:selector:matchLabels:app: wordpresstier: mysqlstrategy:type: Recreatetemplate:metadata:labels:app: wordpresstier: mysqlspec:containers:- image: registry.cn-beijing.aliyuncs.com/wangxiaochun/mysql:8.0.29-oraclename: mysqlenv:- name: MYSQL_ROOT_PASSWORDvalueFrom:secretKeyRef:name: mysql-passkey: root_password- name: MYSQL_DATABASEvalue: wordpress- name: MYSQL_USERvalue: wordpress- name: MYSQL_PASSWORDvalueFrom:secretKeyRef:name: mysql-passkey: user_passwordports:- containerPort: 3306name: mysqlvolumeMounts:- name: mysql-persistent-storagemountPath: /var/lib/mysqlvolumes:- name: mysql-persistent-storagepersistentVolumeClaim:claimName: mysql-pv-claim
kubectl apply -f storage-wordpress-mysql.yaml
[root@master1 sc-nfs-1]# kubectl apply -f storage-wordpress-mysql.yaml service/mysql created persistentvolumeclaim/mysql-pv-claim created deployment.apps/mysql created The Secret "mysql-pass" is invalid: * data[username]: Required value * data[password]: Required value
修复方案:改用 Opaque 类型(推荐)
root_password / user_password,直接用 Opaque 类型:两种 Secret 类型的区别
| 类型 | 强制 key | 适用场景 |
| -------------------------- | --------------------- | --------------- |
| `kubernetes.io/basic-auth` | `username`、`password` | HTTP Basic Auth |
| `Opaque` | 无限制 | 任意自定义 key-value |
先删除失败的 Secret,再重建
kubectl delete -f storage-wordpress-mysql.yaml
加上ConfigMap(MySQL 配置)
把secret拆出来放在清单文件
[root@master1 sc-nfs-1]# cat mysql-configmap.yaml apiVersion: v1 kind: ConfigMap metadata:name: mysql-configlabels:app: wordpress data:MYSQL_DATABASE: "wordpress"MYSQL_USER: "wordpress"
secret清单文件
[root@master1 sc-nfs-1]# cat mysql-secret.yaml apiVersion: v1 kind: Secret metadata:name: mysql-pass #type: kubernetes.io/basic-auth type: Opaque #也可以用Opaque类型 data:root_password: MTIzNDU2 #key名称:password,value为123456user_password: MTIzNDU2 #key名称:password,value为123456
部署 MySQL的相关资源
[root@master1 sc-nfs-1]# cat storage-wordpress-mysql.yaml apiVersion: v1 kind: Service metadata:name: mysqllabels:app: mysql spec:ports:- port: 3306selector:app: wordpresstier: mysqlclusterIP: None --- apiVersion: v1 kind: PersistentVolumeClaim metadata:name: mysql-pv-claimlabels:app: wordpress spec:#storageClassName: sc-nfs #需要和前面创建的storageClass名称相同,如果是默认的storageClass,此项可选accessModes:- ReadWriteOnceresources:requests:storage: 20Gi --- apiVersion: apps/v1 kind: Deployment metadata:name: mysqllabels:app: wordpress spec:selector:matchLabels:app: wordpresstier: mysqlstrategy:type: Recreatetemplate:metadata:labels:app: wordpresstier: mysqlspec:containers:- image: registry.cn-beijing.aliyuncs.com/wangxiaochun/mysql:8.0.29-oraclename: mysqlenv:- name: MYSQL_ROOT_PASSWORDvalueFrom:secretKeyRef:name: mysql-passkey: root_password- name: MYSQL_DATABASEvalueFrom:configMapKeyRef:name: mysql-configkey: MYSQL_DATABASE- name: MYSQL_USERvalueFrom:configMapKeyRef:name: mysql-configkey: MYSQL_USER- name: MYSQL_PASSWORDvalueFrom:secretKeyRef:name: mysql-passkey: user_passwordports:- containerPort: 3306name: mysqlvolumeMounts:- name: mysql-persistent-storagemountPath: /var/lib/mysqlvolumes:- name: mysql-persistent-storagepersistentVolumeClaim:claimName: mysql-pv-claim
部署 wordpress 相关资源
[root@master1 sc-nfs-1]# cat storage-wordpress-wordpress.yaml apiVersion: v1 kind: Service metadata:name: wordpresslabels:app: wordpress spec:ports:- port: 80selector:app: wordpresstier: frontendtype: LoadBalancer#type: ClusterIPsessionAffinity: ClientIP #会话保持#externalTrafficPolicy: Local #DNAT #type: ClusterIP #如何部署了ingress可以使用此项 --- apiVersion: v1 kind: PersistentVolumeClaim metadata:name: wp-pv-claimlabels:app: wordpress spec:#storageClassName: sc-nfs #需要和前面创建的storageClass名称相同,如果是默认的storageClass,此项可选accessModes:- ReadWriteManyresources:requests:storage: 20Gi --- apiVersion: apps/v1 kind: Deployment metadata:name: wordpresslabels:app: wordpress spec:replicas: 2selector:matchLabels:app: wordpresstier: frontendstrategy:type: Recreatetemplate:metadata:labels:app: wordpresstier: frontendspec:containers:- image: registry.cn-beijing.aliyuncs.com/wangxiaochun/wordpress:php8.2-apachename: wordpressenv:- name: WORDPRESS_DB_HOSTvalue: mysql- name: WORDPRESS_DB_PASSWORDvalueFrom:secretKeyRef:name: mysql-passkey: user_password- name: WORDPRESS_DB_USERvalueFrom:configMapKeyRef:name: mysql-configkey: MYSQL_USER- name: WORDPRESS_DB_NAMEvalueFrom:configMapKeyRef:name: mysql-configkey: MYSQL_DATABASEports:- containerPort: 80name: wordpressvolumeMounts:- name: wordpress-persistent-storage#mountPath: /var/www/html #此方式性能较差mountPath: /var/www/html/wp-content/uploads #此方式性能较好,wordpress的配置不能实现多个Pod同步volumes:- name: wordpress-persistent-storagepersistentVolumeClaim:claimName: wp-pv-claim
创建 Ingress
使用ingress暴露wordpress服务
[root@master1 sc-nfs-1]# cat ingress-wordpress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: ingress-wordpressnamespace: wordpress#annotations:# kubernetes.io/ingress.class: "nginx" ,k8s-v1.32.0不支持 spec:ingressClassName: nginx #新版建议使用此项指定controller类型rules:- host: www.ming.orghttp:paths:- path: /pathType: Prefixbackend:service:name: wordpressport: number: 80
#创建独立的名称空间
kubectl create ns wordpress
kubectl apply -f ingress-wordpress.yaml
[root@master1 sc-nfs-1]# kubectl get ingress -n wordpress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-wordpress nginx www.ming.org 192.168.3.10 80 20s
#应用
kubectl apply -f mysql-configmap.yaml -n wordpress
kubectl appy -f mysql-secret.yaml -n wordpress
kubectl apply -f storage-wordpress-mysql.yaml -f storage-wordpress-wordpress.yaml -n wordpress
[root@master1 sc-nfs-1]# kubectl get secret -n wordpress NAME TYPE DATA AGE mysql-pass Opaque 2 6m14s [root@master1 sc-nfs-1]# [root@master1 sc-nfs-1]# kubectl get cm -n wordpress NAME DATA AGE kube-root-ca.crt 1 12m mysql-config 2 5m43s
[root@master1 sc-nfs-1]# kubectl get svc -n wordpress NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mysql ClusterIP None <none> 3306/TCP 11s wordpress LoadBalancer 10.99.208.119 192.168.3.11 80:32171/TCP 11s
[root@master1 sc-nfs-1]# kubectl get all -n wordpress NAME READY STATUS RESTARTS AGE pod/mysql-5c7868554-ldk6w 1/1 Running 0 86s pod/wordpress-6cb86cfc7f-5d6kf 1/1 Running 0 86s pod/wordpress-6cb86cfc7f-nr299 1/1 Running 0 86sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/mysql ClusterIP None <none> 3306/TCP 86s service/wordpress LoadBalancer 10.99.208.119 192.168.3.11 80:32171/TCP 86sNAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/mysql 1/1 1 1 86s deployment.apps/wordpress 2/2 2 2 86sNAME DESIRED CURRENT READY AGE replicaset.apps/mysql-5c7868554 1 1 1 86s replicaset.apps/wordpress-6cb86cfc7f 2 2 2 86s
#通过SVC直接访问
http://192.168.3.11/

#删除Pod,自动创建新的Pod,仍可以继续访问
[root@master1 sc-nfs-1]# kubectl delete pod wordpress-6cb86cfc7f-5d6kf wordpress-6cb86cfc7f-nr299 -n wordpress
pod "wordpress-6cb86cfc7f-5d6kf" deleted from wordpress namespace
pod "wordpress-6cb86cfc7f-nr299" deleted from wordpress namespace
#Pod所在主机宕机后,等待几分钟后会在其它主机节点重建Pod
[root@master1 sc-nfs-1]# kubectl get pod -n wordpress NAME READY STATUS RESTARTS AGE mysql-5c7868554-ldk6w 1/1 Running 0 7m6s wordpress-6cb86cfc7f-rchxp 1/1 Running 0 18s wordpress-6cb86cfc7f-sp72j 1/1 Running 0 18s
[root@master1 sc-nfs-1]# kubectl get pod -n wordpress -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES mysql-5c7868554-ldk6w 1/1 Running 0 7m36s 10.244.2.25 node2.org <none> <none> wordpress-6cb86cfc7f-rchxp 1/1 Running 0 48s 10.244.1.27 node1.org <none> <none> wordpress-6cb86cfc7f-sp72j 1/1 Running 0 48s 10.244.2.27 node2.org <none> <none>
自动创建pv,自动绑定pvc
[root@master1 sc-nfs-1]# kubectl get pv,pvc NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE persistentvolume/pvc-cb11b33e-d4a6-4406-8e67-253b3da2e388 20Gi RWX Delete Bound wordpress/wp-pv-claim sc-nfs <unset> 10m persistentvolume/pvc-e1fe023c-6035-4395-aba6-da4a95183479 20Gi RWO Delete Bound wordpress/mysql-pv-claim sc-nfs <unset> 10m
[root@master1 sc-nfs-1]# ll /data/sc-nfs/ total 20 drwxrwxrwx 7 systemd-coredump root 4096 May 28 01:04 archived-default-mysql-pv-claim-pvc-00f478c7-221a-462b-827f-47793bf76ae5 drwxrwxrwx 7 systemd-coredump root 4096 May 28 00:34 archived-default-mysql-pv-claim-pvc-58ebcff0-e82e-48ab-be6e-2a9a275b1d63 drwxrwxrwx 2 root root 6 May 28 00:11 archived-default-mysql-pv-claim-pvc-715c3a3d-d111-45bd-85c6-44b5b830eb59 drwxrwxrwx 6 systemd-coredump root 4096 May 24 19:08 archived-default-mysql-pv-claim-pvc-95692727-c5b5-4bec-b212-af8864bd69a6 drwxrwxrwx 2 root root 6 May 24 16:15 archived-default-pvc-nfs-sc2-pvc-5c72627d-d450-4c24-be17-d854c427694e drwxrwxrwx 2 root root 24 May 24 16:05 archived-default-pvc-nfs-sc-pvc-7e0e1845-0edd-4e25-ba23-4079c167eaca drwxrwxrwx 2 root root 6 May 28 01:13 archived-wordpress-mysql-pv-claim-pvc-11eaae95-5222-4eb3-adfd-eed1833427c8 drwxrwxrwx 7 systemd-coredump root 4096 May 28 01:22 archived-wordpress-mysql-pv-claim-pvc-f86f34ee-332b-4729-a136-ffdef0bcf97c drwxrwxrwx 2 root root 6 May 28 01:17 archived-wordpress-wp-pv-claim-pvc-90f3a06a-ef90-4de6-a95a-291c5db6e921 drwxrwxrwx 2 root root 6 May 28 01:13 archived-wordpress-wp-pv-claim-pvc-915e4cd7-bbcb-44f6-8490-4eb3dd904136 drwxrwxrwx 7 systemd-coredump root 4096 May 28 01:22 wordpress-mysql-pv-claim-pvc-e1fe023c-6035-4395-aba6-da4a95183479 drwxrwxrwx 2 root root 6 May 28 01:22 wordpress-wp-pv-claim-pvc-cb11b33e-d4a6-4406-8e67-253b3da2e388
[root@master1 wordpress-mysql-pv-claim-pvc-e1fe023c-6035-4395-aba6-da4a95183479]# lsauto.cnf ca-key.pem '#ib_16384_0.dblwr' ib_logfile0 mysql private_key.pem sysbinlog.000001 ca.pem '#ib_16384_1.dblwr' ib_logfile1 mysql.ibd public_key.pem undo_001binlog.000002 client-cert.pem ib_buffer_pool ibtmp1 mysql.sock server-cert.pem undo_002binlog.index client-key.pem ibdata1 '#innodb_temp' performance_schema server-key.pem wordpress
基于www.wang.org 域名结合ingress 暴露 wordpress 的服务
域名解析 www.ming.org 192.168.3.10

出现问题


创建了账号 密码 登录出现重定向
浏览器访问的是 www.ming.org,但登录后还是被重定向到 www.ming.org 然后又跳回登录页。这说明 Cookie 设置有问题,可能是两个 WordPress Pod 之间的 Session 不同步导致的

[root@master1 sc-nfs-1]# kubectl get pod -o wide -n wordpress NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES mysql-5c7868554-4lmrb 1/1 Running 0 17m 10.244.1.36 node1.org <none> <none> wordpress-6cb86cfc7f-l2wsw 1/1 Running 0 17m 10.244.1.35 node1.org <none> <none> wordpress-6cb86cfc7f-l5b5q 1/1 Running 0 17m 10.244.2.34 node2.org <none> <none>
根本原因
有 2 个 WordPress 副本(replicas: 2),分别跑在 node1 和 node2:
Ingress-NGINX 默认是 轮询负载均衡,第一次请求到 Pod A,登录后 Cookie 存在 Pod A,第二次请求到 Pod B,Pod B 不认识这个 Session,所以认为没登录,又跳回登录页
那就需要在 Ingress 层启用 Cookie-based Session Affinity,让同一个用户的请求始终落到同一个 Pod 上
[root@master1 sc-nfs-1]# cat ingress-wordpress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: ingress-wordpressnamespace: wordpressannotations:nginx.ingress.kubernetes.io/affinity: "cookie"nginx.ingress.kubernetes.io/session-cookie-name: "wordpress_route"nginx.ingress.kubernetes.io/session-cookie-expires: "172800"nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"nginx.ingress.kubernetes.io/session-cookie-path: "/" spec:ingressClassName: nginxrules:- host: www.ming.orghttp:paths:- path: /pathType: Prefixbackend:service:name: wordpressport:number: 80
kubectl apply -f ingress-wordpress.yaml
可以登录

