VOLUME
bash
[root@master30 ~ 10:39:56]# kubectl create ns storage
Error from server (AlreadyExists): namespaces "storage" already exists
[root@master30 ~ 10:40:24]# kubectl config set-context --current --namespace storage
Context "kubernetes-super-admin@kubernetes" modified.
Volume 类型
Kubernetes支持Volume类型有:
- emptyDir
- hostPath
- gcePersistentDisk
- awsElasticBlockStore
- nfs
- iscsi
- fc (fibre channel)
- flocker
- glusterfs
- rbd
- cephfs
- gitRepo
- secret
- persistentVolumeClaim
- downwardAPI
- projected
- azureFileVolume
- azureDisk
- vsphereVolume
- Quobyte
- PortworxVolume
- ScaleIO
- StorageOS
- local
emptyDir
默认情况下,当Pod分配到Node上时,将会创建emptyDir,只要Node上的Pod一直运行,Volume就会一直存。当Pod(不管任何原因)从Node上被删除时,emptyDir也同时会删除,存储的数据也将永久删除。
bash
[root@master30 ~ 10:42:25]# kubectl apply -f pod-with-emptyDir.yaml
pod/busybox created
[root@master30 ~ 11:06:55]# kubectl describe pod busybox |grep Node:
Node: worker32.my.cloud/10.1.8.32
[root@master30 ~ 11:07:07]# kubectl exec busybox -c busybox1 -- touch /data/b1-f1
[root@master30 ~ 11:10:22]# kubectl exec busybox -c busybox2 -- ls /data
b1-f1
[root@master30 ~ 11:10:30]# kubectl describe pod busybox |grep Node:
Node: worker32.my.cloud/10.1.8.32
[root@master30 ~ 11:12:22]# kubectl describe pod busybox |egrep -o 'Container ID.*//.{12}'
Container ID: containerd://36fb0dadfa81
Container ID: containerd://d7f6b052ce70
[root@worker32 ~ 11:12:02]# crictl inspect 36fb0dadfa81|grep datavolume
"hostPath": "/var/lib/kubelet/pods/eadb379a-65f9-47bf-9d0c-a0e66af33341/volumes/kubernetes.io~empty-dir/datavolume",
"host_path": "/var/lib/kubelet/pods/eadb379a-65f9-47bf-9d0c-a0e66af33341/volumes/kubernetes.io~empty-dir/datavolume"
"source": "/var/lib/kubelet/pods/eadb379a-65f9-47bf-9d0c-a0e66af33341/volumes/kubernetes.io~empty-dir/datavolume",
[root@worker32 ~ 11:13:05]# ls /var/lib/kubelet/pods/eadb379a-65f9-47bf-9d0c-a0e66af33341/volumes/kubernetes.io~empty-dir/datavolume
b1-f1
[root@worker32 ~ 11:15:36]# ls /var/lib/kubelet/pods/eadb379a-65f9-47bf-9d0c-a0e66af33341/volumes/kubernetes.io~empty-dir/datavolume
ls: cannot access '/var/lib/kubelet/pods/eadb379a-65f9-47bf-9d0c-a0e66af33341/volumes/kubernetes.io~empty-dir/datavolume': No such file or directory
hostPath
bash
[root@master30 ~ 11:15:12]# vim pod-with-hostPath.yaml
[root@master30 ~ 11:17:01]# kubectl apply -f pod-with-hostPath.yaml
pod/busybox created
[root@master30 ~ 11:17:07]# kubectl describe pod busybox |egrep -o 'Container ID.*//.{12}'
Container ID: containerd://f339b36a4589
Container ID: containerd://1854b7e63a26
[root@master30 ~ 11:17:16]# kubectl describe pod busybox |grep Node:
Node: worker32.my.cloud/10.1.8.32
[root@master30 ~ 11:17:26]# kubectl exec busybox -c busybox1 -- touch /data/b1-f1
[root@master30 ~ 11:18:27]# kubectl delete pod busybox --force
Warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "busybox" force deleted
[root@worker32 ~ 11:16:04]# crictl inspect f339b36a4589|grep busyboxdir
"hostPath": "/busyboxdir",
"host_path": "/busyboxdir"
"source": "/busyboxdir",
[root@worker32 ~ 11:18:10]# ls /busyboxdir/
b1-f1
[root@worker32 ~ 11:18:37]# ls /busyboxdir/
b1-f1
NFS存储
bash
[root@master30 ~ 11:18:45]# apt install -y nfs-kernel-server
[root@master30 ~ 11:20:24]# mkdir -m 777 /nfsshares
[root@master30 ~ 11:21:07]# echo hello 伊良波五月 > /nfsshares/index.html
[root@master30 ~ 11:21:35]# cat << EOF > /etc/exports
/nfsshares *(rw)
EOF
[root@master30 ~ 11:21:52]# systemctl restart nfs-server.service
[root@master30 ~ 11:21:58]# vim pod-with-nfs.yaml
[root@master30 ~ 11:23:07]# kubectl apply -f pod-with-nfs.yaml
pod/nginx created
[root@master30 ~ 11:23:14]# kubectl describe pod nginx |egrep -o 'Container ID.*//.{12}'
[root@master30 ~ 11:23:20]# kubectl describe pod nginx |egrep -o 'Container ID.*//.{12}'
[root@master30 ~ 11:23:37]# kubectl describe pod nginx |egrep -o 'Container ID.*//.{12}'
Container ID: containerd://fecfa77e7f73
[root@master30 ~ 11:23:51]# kubectl describe pod nginx |grep Node:
Node: worker32.my.cloud/10.1.8.32
[root@master30 ~ 11:24:02]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 97s 10.224.125.132 worker32.my.cloud <none> <none>
[root@master30 ~ 11:25:11]# curl 10.224.125.132
hello 伊良波五月
[root@worker31 ~ 11:22:35]# apt install -y nfs-kernel-server
[root@worker32 ~ 11:22:35]# apt install -y nfs-kernel-server
[root@worker32 ~ 11:22:23]# crictl inspect fecfa77e7f73|grep /usr/share/nginx/html
"containerPath": "/usr/share/nginx/html",
"container_path": "/usr/share/nginx/html",
"destination": "/usr/share/nginx/html",
持久性存储
学习参考:持久卷
Kubernetes 使用 persistent volume(PV)架构为集群提供永久存储。
PV 和 PVC 架构
创建PV
bash
[root@master30 ~ 11:37:46]# vim pv.yaml
[root@master30 ~ 11:42:06]# kubectl apply -f pv.yaml
persistentvolume/web created
[root@master30 ~ 11:42:11]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
web 5Gi RWO Retain Available <unset> 4s
创建PVC
bash
[root@master30 ~ 11:42:15]# vim pvc.yaml
[root@master30 ~ 11:43:17]# kubectl apply -f pvc.yaml
persistentvolumeclaim/webclaim created
[root@master30 ~ 11:43:23]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
webclaim Bound web 5Gi RWO <unset> 5s
创建Pod使用PV
bash
[root@master30 ~ 11:43:28]# vim pod-with-pvc.yaml
[root@master30 ~ 11:44:20]# kubectl apply -f pod-with-pvc.yaml
pod/web created
[root@master30 ~ 11:44:28]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 21m 10.224.125.132 worker32.my.cloud <none> <none>
web 0/1 ContainerCreating 0 5s <none> worker31.my.cloud <none> <none>
[root@master30 ~ 11:44:33]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 21m 10.224.125.132 worker32.my.cloud <none> <none>
web 1/1 Running 0 21s 10.224.15.65 worker31.my.cloud <none> <none>
[root@master30 ~ 11:44:49]# curl http://10.224.15.65
hello 伊良波五月
[root@master30 ~ 11:45:02]# echo hello 黑川美佳子 > /nfsshares/test.html
[root@master30 ~ 11:46:32]# curl http://10.224.15.65
hello 伊良波五月
[root@master30 ~ 11:46:43]# curl http://10.224.15.65/test.html
hello 黑川美佳子
[root@master30 ~ 11:47:13]# kubectl delete pod web --force
Warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "web" force deleted
Retain
bash
[root@master30 ~ 13:44:29]# vim pv-pvc-Retain.yaml
[root@master30 ~ 13:55:08]# kubectl apply -f pv-pvc-Retain.yaml
persistentvolume/web unchanged
persistentvolumeclaim/webclaim unchanged
[root@master30 ~ 13:55:17]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
web 5Gi RWO Retain Bound storage/webclaim <unset> 133m
[root@master30 ~ 13:55:22]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
webclaim Bound web 5Gi RWO <unset> 132m
ConfigMap
bash
[root@master30 ~ 13:30:19]# kubectl get all,pv,pvc
NAME READY STATUS RESTARTS AGE
pod/nginx 1/1 Running 1 (14m ago) 141m
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
persistentvolume/web 5Gi RWO Retain Bound storage/webclaim <unset> 122m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
persistentvolumeclaim/webclaim Bound web 5Gi RWO <unset> 121m
[root@master30 ~ 13:44:29]# vim pv-pvc-Retain.yaml
[root@master30 ~ 13:55:08]# kubectl apply -f pv-pvc-Retain.yaml
persistentvolume/web unchanged
persistentvolumeclaim/webclaim unchanged
[root@master30 ~ 13:55:17]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
web 5Gi RWO Retain Bound storage/webclaim <unset> 133m
[root@master30 ~ 13:55:22]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
webclaim Bound web 5Gi RWO <unset> 132m
[root@master30 ~ 13:55:28]# vim pod-cm-env.yaml
[root@master30 ~ 14:39:40]# kubectl apply -f pod-cm-env.yaml
pod/mysql created
[root@master30 ~ 14:39:47]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql 0/1 ContainerCreating 0 5s <none> worker31.my.cloud <none> <none>
nginx 1/1 Running 1 (70m ago) 3h16m 10.224.125.133 worker32.my.cloud <none> <none>
[root@master30 ~ 14:39:52]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql 0/1 ContainerCreating 0 25s <none> worker31.my.cloud <none> <none>
nginx 1/1 Running 1 (70m ago) 3h16m 10.224.125.133 worker32.my.cloud <none> <none>
[root@master30 ~ 14:40:12]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql 0/1 ContainerCreating 0 54s <none> worker31.my.cloud <none> <none>
nginx 1/1 Running 1 (70m ago) 3h17m 10.224.125.133 worker32.my.cloud <none> <none>
[root@master30 ~ 14:40:41]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql 0/1 ContainerCreating 0 117s <none> worker31.my.cloud <none> <none>
nginx 1/1 Running 1 (71m ago) 3h18m 10.224.125.133 worker32.my.cloud <none> <none>
[root@master30 ~ 14:41:44]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql 0/1 ContainerCreating 0 2m51s <none> worker31.my.cloud <none> <none>
nginx 1/1 Running 1 (72m ago) 3h19m 10.224.125.133 worker32.my.cloud <none> <none>
[root@master30 ~ 14:42:38]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql 0/1 ContainerCreating 0 4m12s <none> worker31.my.cloud <none> <none>
nginx 1/1 Running 1 (74m ago) 3h20m 10.224.125.133 worker32.my.cloud <none> <none>
[root@master30 ~ 14:43:59]# kubectl create ns configure
namespace/configure created
[root@master30 ~ 14:44:05]# kubectl config set-context --current --namespace configure
Context "kubernetes-admin@kubernetes" modified.
[root@master30 ~ 14:44:11]# kubectl delete ns storage
namespace "storage" deleted
[root@master30 ~ 14:44:37]# kubectl apply -f pod-cm-env.yaml
pod/mysql created
[root@master30 ~ 14:44:54]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql 0/1 CreateContainerConfigError 0 11s 10.224.15.67 worker31.my.cloud <none> <none>
[root@master30 ~ 14:45:05]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql 0/1 CreateContainerConfigError 0 33s 10.224.15.67 worker31.my.cloud <none> <none>
[root@master30 ~ 14:45:27]# kubectl describe pod mysql
Name: mysql
Namespace: configure
Priority: 0
Service Account: default
Node: worker31.my.cloud/10.1.8.31
Start Time: Thu, 25 Jun 2026 14:44:54 +0800
Labels: name=mysql
Annotations: cni.projectcalico.org/containerID: aaa300afb7152a6abb45ee2b4a831b174728cd165163d42d8fcf5a48551d644f
cni.projectcalico.org/podIP: 10.224.15.67/32
cni.projectcalico.org/podIPs: 10.224.15.67/32
Status: Pending
IP: 10.224.15.67
IPs:
IP: 10.224.15.67
Containers:
mysql:
Container ID:
Image: docker.io/library/mysql:latest
Image ID:
Port: 3306/TCP
Host Port: 0/TCP
State: Waiting
Reason: CreateContainerConfigError
Ready: False
Restart Count: 0
Environment:
MYSQL_ROOT_PASSWORD: <set to the key 'password' of config map 'mysql'> Optional: false
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-g2x4w (ro)
Conditions:
Type Status
PodReadyToStartContainers True
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
kube-api-access-g2x4w:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 66s default-scheduler Successfully assigned configure/mysql to worker31.my.cloud
Normal Pulled 1s (x8 over 65s) kubelet Container image "docker.io/library/mysql:latest" already present on machine
Warning Failed 1s (x8 over 65s) kubelet Error: configmap "mysql" not found
[root@master30 ~ 14:46:00]# vim pod-cm-env.yaml
[root@master30 ~ 14:46:40]# kubectl create configmap mysql --from-literal=password redhat -n configure
error: exactly one NAME is required, got 2
See 'kubectl create configmap -h' for help and examples
[root@master30 ~ 14:47:28]# kubectl create configmap mysql --from-literal=password=redhat -n configure
configmap/mysql created
[root@master30 ~ 14:47:45]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql 1/1 Running 0 3m22s 10.224.15.67 worker31.my.cloud <none> <none>
[root@master30 ~ 14:48:16]# kubectl exec -it mysql -- bash -c 'echo $MYSQL_ROOT_PASSWORD'
redhat
[root@master30 ~ 14:48:27]# apt install -y mysql-client
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
mysql-client-8.0 mysql-client-core-8.0 mysql-common
The following NEW packages will be installed:
mysql-client mysql-client-8.0 mysql-client-core-8.0 mysql-common
0 upgraded, 4 newly installed, 0 to remove and 258 not upgraded.
Need to get 2778 kB of archives.
After this operation, 61.8 MB of additional disk space will be used.
Get:1 http://mirrors.huaweicloud.com/ubuntu noble-updates/main amd64 mysql-client-core-8.0 amd64 8.0.46-0ubuntu0.24.04.3 [2740 kB]
Get:2 http://mirrors.huaweicloud.com/ubuntu noble/main amd64 mysql-common all 5.8+1.1.0build1 [6746 B]
Get:3 http://mirrors.huaweicloud.com/ubuntu noble-updates/main amd64 mysql-client-8.0 amd64 8.0.46-0ubuntu0.24.04.3 [22.4 kB]
Get:4 http://mirrors.huaweicloud.com/ubuntu noble-updates/main amd64 mysql-client all 8.0.46-0ubuntu0.24.04.3 [9414 B]
Fetched 2778 kB in 8s (358 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package mysql-client-core-8.0.
(Reading database ... 76946 files and directories currently installed.)
Preparing to unpack .../mysql-client-core-8.0_8.0.46-0ubuntu0.24.04.3_amd64.deb ...
Unpacking mysql-client-core-8.0 (8.0.46-0ubuntu0.24.04.3) ...
Selecting previously unselected package mysql-common.
Preparing to unpack .../mysql-common_5.8+1.1.0build1_all.deb ...
Unpacking mysql-common (5.8+1.1.0build1) ...
Selecting previously unselected package mysql-client-8.0.
Preparing to unpack .../mysql-client-8.0_8.0.46-0ubuntu0.24.04.3_amd64.deb ...
Unpacking mysql-client-8.0 (8.0.46-0ubuntu0.24.04.3) ...
Selecting previously unselected package mysql-client.
Preparing to unpack .../mysql-client_8.0.46-0ubuntu0.24.04.3_all.deb ...
Unpacking mysql-client (8.0.46-0ubuntu0.24.04.3) ...
Setting up mysql-common (5.8+1.1.0build1) ...
update-alternatives: using /etc/mysql/my.cnf.fallback to provide /etc/mysql/my.cnf (my.cnf) in auto mode
Setting up mysql-client-core-8.0 (8.0.46-0ubuntu0.24.04.3) ...
Setting up mysql-client-8.0 (8.0.46-0ubuntu0.24.04.3) ...
Setting up mysql-client (8.0.46-0ubuntu0.24.04.3) ...
Scanning processes...
Scanning linux images...
Running kernel seems to be up-to-date.
No services need to be restarted.
No containers need to be restarted.
No user sessions are running outdated binaries.
No VM guests are running outdated hypervisor (qemu) binaries on this host.
[root@master30 ~ 14:49:13]# mysql -u root -predhat -h 10.224.15.67
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 9.7.1 MySQL Community Server - GPL
Copyright (c) 2000, 2026, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
mysql> exit
Bye
[root@master30 ~ 14:50:11]# kubectl exec -it mysql -- bash
bash-5.1# echo $MYSQL_ROOT_PASSWORD
redhat
haproxy+web
bash
[root@master30 ~ 15:24:06]# kubectl create cm webapp-1 \
--from-literal=index.html="hello webapp-1" \
--from-literal=error.html="sorry, error."
configmap/webapp-1 created
[root@master30 ~ 15:24:11]# vim pod-webapp-1.yaml
[root@master30 ~ 15:24:27]# kubectl apply -f pod-webapp-1.yaml
pod/webapp-1 created
[root@master30 ~ 15:24:32]# kubectl create cm webapp-2 \
--from-literal=index.html="hello webapp-2" \
--from-literal=error.html="sorry, error."
configmap/webapp-2 created
[root@master30 ~ 15:24:36]# vim pod-webapp-2.yaml
[root@master30 ~ 15:25:05]# kubectl apply -f pod-webapp-2.yaml
pod/webapp-2 created
[root@master30 ~ 15:25:08]# kubectl get pods -o wide | grep webapp
webapp-1 1/1 Running 0 41s 10.224.15.68 worker31.my.cloud <none> <none>
webapp-2 1/1 Running 0 5s 10.224.125.135 worker32.my.cloud <none> <none>
[root@master30 ~ 15:25:13]# vim haproxy.cfg
[root@master30 ~ 15:25:47]# cat > haproxy.cfg <<EOF
global
daemon
maxconn 256
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend http-in
bind *:8080
default_backend servers
backend servers
> server app1 10.224.15.68 80:80 check
> server app2 10.224.125.135^C
[root@master30 ~ 15:26:54]# cat > haproxy.cfg <<EOF
global
daemon
maxconn 256
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend http-in
bind *:8080
default_backend servers
backend servers
server app1 10.224.15.68:80 check
server app2 10.224.125.135:80 check
> EOF
[root@master30 ~ 15:27:34]# kubectl create cm haproxy.cfg --from-file=haproxy.cfg=./haproxy.cfg
configmap/haproxy.cfg created
[root@master30 ~ 15:27:42]# vim haproxy.yaml
[root@master30 ~ 15:27:57]# kubectl apply -f haproxy.yaml
pod/haproxy created
[root@master30 ~ 15:28:01]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
haproxy 0/1 ContainerCreating 0 6s <none> worker31.my.cloud <none> <none>
webapp-1 1/1 Running 0 3m35s 10.224.15.68 worker31.my.cloud <none> <none>
webapp-2 1/1 Running 0 2m59s 10.224.125.135 worker32.my.cloud <none> <none>
[root@master30 ~ 15:28:07]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
haproxy 1/1 Running 0 27s 10.224.15.69 worker31.my.cloud <none> <none>
webapp-1 1/1 Running 0 3m56s 10.224.15.68 worker31.my.cloud <none> <none>
webapp-2 1/1 Running 0 3m20s 10.224.125.135 worker32.my.cloud <none> <none>
[root@master30 ~ 15:28:28]# curl http://10.224.15.69:8080
hello webapp-1[root@master30 ~ 15:28:46]# curl http://10.224.15.69:8080
hello webapp-2[root@master30 ~ 15:28:48]#
Secret
bash
[root@master30 ~ 15:44:19]# kubectl create ns blog
namespace/blog created
[root@master30 ~ 16:39:31]# kubectl create secret generic mysql-secret -n blog \
--from-literal=MYSQL_ROOT_PASSWORD=rootpass \
--from-literal=MYSQL_DATABASE=wordpress \
--from-literal=MYSQL_USER=wpuser \
--from-literal=MYSQL_PASSWORD=wppass
secret/mysql-secret created
[root@master30 ~ 16:40:24]# openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=blog.example.com"
kubectl create secret tls wordpress-tls -n blog \
--cert=tls.crt --key=tls.key
.+..............+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*....+...+......+.........+...+...+.......+..+.+......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*......+.................+....+.....+............+....+......+..+...............+............+...+......+.+...+..+.+...........................+.....+...+...+.......+...+.........+..+.+...+...............+.....+....+..+...+......+....+..+.+.....+...+......+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.+.....+.+.....+......+.........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.......+........+.......+..+....+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+...........+.+..+.+...........+...+...+.......+...+.........+.....+....+.....+.+......+........+.+...+...........+.......+.....+...+..........+.........+..+.........+.+........+.+.....+.......+..+............+.+...+..+...+.........+...+....+.........+.....+..........+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----
secret/wordpress-tls created
[root@master30 ~ 16:40:39]# cat > wordpress.conf <<EOF
<VirtualHost *:80>
ServerName blog.example.com
Redirect permanent / https://blog.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName blog.example.com
DocumentRoot /var/www/html
SSLEngine on
SSLCertificateFile /etc/ssl/certs/tls.crt
SSLCertificateKeyFile /etc/ssl/private/tls.key
<Directory /var/www/html>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
EOF
kubectl create configmap wordpress-vhost -n blog --from-file=wordpress.conf
configmap/wordpress-vhost created
[root@master30 ~ 16:41:27]# vim mysql-deploy.yaml
[root@master30 ~ 16:42:23]# vim mysql-svc.yaml
[root@master30 ~ 16:42:51]# kubectl apply -f mysql-deploy.yaml
kubectl apply -f mysql-svc.yaml
deployment.apps/mysql created
service/mysql created
[root@master30 ~ 16:42:55]# vim wordpress-deploy.yaml
[root@master30 ~ 16:44:12]# vim wordpress-svc.yaml
[root@master30 ~ 16:44:45]# kubectl apply -f wordpress-deploy.yaml
kubectl apply -f wordpress-svc.yaml
deployment.apps/wordpress created
service/wordpress created
[root@master30 ~ 16:44:48]# kubectl get pods -n blog
NAME READY STATUS RESTARTS AGE
mysql-6b88dd5775-hcz8l 1/1 Running 0 118s
wordpress-89749f487-bbxt5 0/1 ContainerCreating 0 5s
[root@master30 ~ 16:44:53]# kubectl get pods -n blog
NAME READY STATUS RESTARTS AGE
mysql-6b88dd5775-hcz8l 1/1 Running 0 2m57s
wordpress-89749f487-bbxt5 0/1 ContainerCreating 0 64s
[root@master30 ~ 16:45:52]# kubectl get pods -n blog
NAME READY STATUS RESTARTS AGE
mysql-6b88dd5775-hcz8l 1/1 Running 0 3m57s
wordpress-89749f487-bbxt5 0/1 Error 1 (14s ago) 2m4s
[root@master30 ~ 16:46:52]# kubectl describe pod wordpress-89749f487-bbxt5 -n blog
Name: wordpress-89749f487-bbxt5
Namespace: blog
Priority: 0
Service Account: default
Node: worker31.my.cloud/10.1.8.31
Start Time: Thu, 25 Jun 2026 16:44:48 +0800
Labels: app=wordpress
pod-template-hash=89749f487
Annotations: cni.projectcalico.org/containerID: 44b70b318e86de39945163bc8a96208f1f6fd6d070a0ce26d14c83285f2da6a2
cni.projectcalico.org/podIP: 10.224.15.70/32
cni.projectcalico.org/podIPs: 10.224.15.70/32
Status: Running
IP: 10.224.15.70
IPs:
IP: 10.224.15.70
Controlled By: ReplicaSet/wordpress-89749f487
Containers:
wordpress:
Container ID: containerd://64b9d6799c8f93960fefe451f08dbbb245b56ca5e3edc08f3c5b4223923a8c72
Image: wordpress:latest
Image ID: docker.io/library/wordpress@sha256:6d37018d26165824c0dfb5d612e205c70adf760fed9c614187d18091646c9e31
Ports: 80/TCP, 443/TCP
Host Ports: 0/TCP, 0/TCP
State: Terminated
Reason: Error
Exit Code: 1
Started: Thu, 25 Jun 2026 16:46:53 +0800
Finished: Thu, 25 Jun 2026 16:46:54 +0800
Last State: Terminated
Reason: Error
Exit Code: 1
Started: Thu, 25 Jun 2026 16:46:40 +0800
Finished: Thu, 25 Jun 2026 16:46:41 +0800
Ready: False
Restart Count: 2
Environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_USER: <set to the key 'MYSQL_USER' in secret 'mysql-secret'> Optional: false
WORDPRESS_DB_PASSWORD: <set to the key 'MYSQL_PASSWORD' in secret 'mysql-secret'> Optional: false
WORDPRESS_DB_NAME: <set to the key 'MYSQL_DATABASE' in secret 'mysql-secret'> Optional: false
Mounts:
/etc/apache2/sites-enabled/000-default.conf from vhost-config (ro,path="wordpress.conf")
/etc/ssl/certs/tls.crt from tls-certs (ro,path="tls.crt")
/etc/ssl/private/tls.key from tls-certs (ro,path="tls.key")
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-d64cb (ro)
/var/www/html from wordpress-storage (rw)
Conditions:
Type Status
PodReadyToStartContainers True
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
vhost-config:
Type: ConfigMap (a volume populated by a ConfigMap)
Name: wordpress-vhost
Optional: false
tls-certs:
Type: Secret (a volume populated by a Secret)
SecretName: wordpress-tls
Optional: false
wordpress-storage:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
SizeLimit: <unset>
kube-api-access-d64cb:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m14s default-scheduler Successfully assigned blog/wordpress-89749f487-bbxt5 to worker31.my.cloud
Normal Pulling 2m13s kubelet Pulling image "wordpress:latest"
Normal Pulled 26s kubelet Successfully pulled image "wordpress:latest" in 1m46.655s (1m46.655s including waiting). Image size: 268956550 bytes.
Normal Created 9s (x3 over 26s) kubelet Created container wordpress
Normal Started 9s (x3 over 26s) kubelet Started container wordpress
Normal Pulled 9s (x2 over 22s) kubelet Container image "wordpress:latest" already present on machine
Warning BackOff 8s (x2 over 21s) kubelet Back-off restarting failed container wordpress in pod wordpress-89749f487-bbxt5_blog(759ee9a0-a63c-49b2-8d3d-91fa2080cb0f)
[root@master30 ~ 16:47:02]# kubectl exec -it mysql-6b88dd5775-hcz8l -n blog -- mysql -uroot -prootpass -e "SHOW DATABASES;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| wordpress |
+--------------------+
[root@master30 ~ 16:48:06]# kubectl logs wordpress-89749f487-bbxt5 -n blog
AH00526: Syntax error on line 10 of /etc/apache2/sites-enabled/000-default.conf:
Invalid command 'SSLEngine', perhaps misspelled or defined by a module not included in the server configuration
[root@master30 ~ 16:49:01]# vim wordpress-deploy.yaml [root@master30 ~ 16:51:37]# kubectl apply -f wordpress-deploy.yaml -n blog
kubectl delete pod -l app=wordpress -n blog
deployment.apps/wordpress configured
pod "wordpress-58ffdb8874-t2mvj" deleted
pod "wordpress-89749f487-bbxt5" deleted
[root@master30 ~ 16:51:46]# kubectl get pods -n blog -l app=wordpress
NAME READY STATUS RESTARTS AGE
wordpress-58ffdb8874-djw95 1/1 Running 0 22s
[root@master30 ~ 16:52:06]# kubectl get svc -n blog
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mysql ClusterIP 10.100.232.214 <none> 3306/TCP 9m48s
wordpress NodePort 10.109.27.168 <none> 80:30080/TCP,443:30443/TCP 7m55s
[root@master30 ~ 16:52:43]# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
master30.my.cloud Ready control-plane 2d5h v1.30.2 10.1.8.30 <none> Ubuntu 24.04 LTS 6.8.0-31-generic containerd://1.7.20
worker31.my.cloud Ready <none> 2d5h v1.30.2 10.1.8.31 <none> Ubuntu 24.04 LTS 6.8.0-31-generic containerd://1.7.20
worker32.my.cloud Ready <none> 2d5h v1.30.2 10.1.8.32 <none> Ubuntu 24.04 LTS 6.8.0-31-generic containerd://1.7.20
[root@master30 ~ 16:54:28]# curl -s http://10.1.8.31:30080 | head -10
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://blog.example.com/">here</a>.</p>
<hr>
<address>Apache/2.4.67 (Debian) Server at 10.1.8.31 Port 30080</address>
</body></html>
[root@master30 ~ 16:55:13]# curl -s http://10.1.8.30:30080 | head -10
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://blog.example.com/">here</a>.</p>
<hr>
<address>Apache/2.4.67 (Debian) Server at 10.1.8.30 Port 30080</address>
</body></html>
[root@master30 ~ 16:58:26]#
运行结果
dy>
Moved Permanently
The document has moved here.
Apache/2.4.67 (Debian) Server at 10.1.8.31 Port 30080 root@master30 \~ 16:55:13# curl -s http://10.1.8.30:30080 | head -10 301 Moved Permanently
Moved Permanently
The document has moved here.
Apache/2.4.67 (Debian) Server at 10.1.8.30 Port 30080 root@master30 \~ 16:58:26# ~~~
运行结果
