k8s的云原生应用部署-mysql和wordpress
在已经建立有k8s集群的前提下,使用deploy,部署一个单独pod的单点mysql,部署一个4pod的wordpress应用。
应用的数据库使用mysql,mysql和应用都做集群外服务暴露。
通过该应用部署的练习,了解中等难度应用程序如何做云原生状态下的部署,并掌握以下k8s资源-APIServer的使用:
NameSpace、PV、ConfigMap、Secret、PVC、Deployment、NodePort类型的Service。
进行该练习的背景知识,有:
(1)能够独立搭建一套1master、3worker的k8s集群;
(2)能够在k8s上部署一个简单无状态的nginx应用;
(3)对NFS存储有一定的了解。
完成练习后,本练习中创建的数据库+网站应用,可以作为后续练习的基础和背景板。
一、规划
1 节点规划
5个节点:1个master,3个worker,1个独立的NFS server。
基础OS为Ubuntu22.04.3,版本代号jammy,内核5.15.0-91-generic。
节点的统一域名为beety.com。
假设整套k8s环境上已经装好k8s,各项功能运转正常;nfs server已经建立,k8s集群的worker可以正产挂载目录。
假设全部5个节点,主机长名、短名互相可见(使用DNS或绑定hosts表均可)
角色 | IP | 主机名 | 主机长名 | 功能 | 配置 |
---|---|---|---|---|---|
master01 | 192.168.172.141 | m01 | m01.beety.com | kubelet、etcd、apiserver、controller-manager、scheduler | 2vc4G40G |
worker01 | 192.168.172.151 | w01 | w01.beety.com | kubelet、proxy、应用pod | 4vc4G40G |
worker02 | 192.168.172.152 | w02 | w02.beety.com | kubelet、proxy、应用pod | 4vc4G40G |
worker03 | 192.168.172.153 | w03 | w03.beety.com | kubelet、proxy、应用pod | 4vc4G40G |
nfs repository | 192.168.172.144 | repo01 | repo01.beety.com | nfs server,提供容量5GB的共享文件系统 | 2vc2G40G |
2 应用版本规划
k8s:containerd 1.6.26, kubernetes 1.28.2,flannel cniVersion 0.3.1
nfs:操作系统级别,Ubuntu22.04.3的镜像源提供的nfs-kernel-server(服务器端)、nfs-common(客户端)
nfs协议:需要nfs server支持NFS4.1版本的协议。
mysql:MySQL Community Server 8.0.19官方docker镜像
wordpress:6-apache(2023年12月31日的latest,wordpress版本6.4.2),官方docker镜像
3 存储规划
nfs server提供共享目录:
repo01.beety.com:/data/nfs/share01,该目录供mysql存放数据文件使用。
repo01.beety.com:/data/nfs/share02,该目录共wordpress存放网页文件使用。
4 k8s资源规划
(1)公用
已经建立好一个k8s集群环境。
使用独立的namespace做本次应用部署,取名mywebapp。
建立一个k8s全局级别的PersistentVolume(PV),nfspv01,指向上面的nfs share01目录。
建立一个k8s全局级别的PersistentVolume(PV),nfspv02,指向上面的nfs share02目录。
(2)mysql
主配置文件my.cnf,配置为ConfigMap。
root口令配置为secret。
为mysql创建一个PersistentVolumeClaim(PVC),指向全局PV nfspv01,用于存放数据库文件。
为mysql应用创建一个pod,引用上面的ConfigMap、secret、PVC,另外为了统一时区,引用pod所在节点本地的/etc/localtime。
pod的东西向访问端口3306,南北向访问端口30336。使用NodePort类型的service资源在南北方向暴露该端口。
(3)wordpress
mysql中数据库db02,用户wordpress给与db02全库权限,口令123456,用来存放wordpress基础数据。
wordpress调用的mysql URL、用户名、口令,使用secret存储。
一个PersistentVolumeClaim(PVC),指向第二个全局PV nfspv02,用于存放网页文件。
为wordpress应用deploy 4个pod,引用上面的secret、PVC。
pod的东西向访问端口80,南北向访问端口30080。使用NodePort类型的service资源在南北方向暴露该端口。
二、验证NFS可用
首先确认worker的3个节点作为nfs client,可以使用nfs server。nfs server的安装配置以及client的挂载方法,参考本文附件一。
能够使用的前提,是worker3节点能够访问nfs server的111、2049两个端口。
注意后面在让pod使用nfs时,并不会在worker节点上直接挂载,而是通过PV、PVC的定义,让pod使用,因此这里只是验证,挂载成功后需要摘掉并删除挂载目录。
在任意或全部worker节点上:
showmount -e repo01.beety.com
###正确回显
Export list for repo01.beety.com:
Export list for localhost:
/data/nfs/share02 *
/data/nfs/share01 *
###回显完
mkdir /tmp001
mount -t nfs -o soft,timeo=200,retrans=3,retry=1 repo01.beety.com:/data/nfs/share01 /tmp001
df -h | grep repo01.beety.com #(确保成功挂载)
umount /tmp001
rm -r /tmp001
三、准备工作
1 目录准备
在m01节点上为后续各个资源的yaml声明文件做目录准备,mysql和wordpress各一个
mkdir -p ~/k8sapp01/20231229/{global,mysql,wordpress}
全局PV的声明放在global中,mysql和wordpress对应的声明存放在各自目录中,后面不在赘述。
2 独立的命名空间
为本次部署创建独立的namespace:mywebapp
kubectl create namespace mywebapp
后面所有为此次部署而apply的k8s资源,除了无namespace分隔的PV,其他都会创建在mywebapp这个namespace中。
3 全局PV
声明global_pv.yaml
## 第一个PV
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfspv01
labels:
app: nfspv01 #设置 pv 的 label 标签
spec:
capacity:
storage: 2Gi #设置 pv 存储资源大小
accessModes:
- ReadWriteOnce
mountOptions:
- soft
- nfsvers=4.1
nfs: #指定使用 NFS 存储驱动
server: repo01.beety.com #指定 NFS 服务器 IP 地址
path: /data/nfs/share01 #指定 NFS 共享目录的位置
persistentVolumeReclaimPolicy: Retain
---
## 第二个PV
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfspv02
labels:
app: nfspv02 #设置 pv 的 label 标签
spec:
capacity:
storage: 1Gi #设置 pv 存储资源大小
accessModes:
- ReadWriteMany #相比上一个PV这里可以多路读写
mountOptions:
- soft
- nfsvers=4.1
nfs: #指定使用 NFS 存储驱动
server: repo01.beety.com #指定 NFS 服务器 IP 地址
path: /data/nfs/share02 #指定 NFS 共享目录的位置
persistentVolumeReclaimPolicy: Retain
直接apply,应用该声明,创建PV
kubectl apply -f global_pv.yaml --dry-run=client
kubectl apply -f global_pv.yaml
kubectl get pv
#回显
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
nfspv01 2Gi RWO Retain Available 5s
nfspv02 1Gi RWX Retain Available 5s
四、mysql应用
1 ConfigMap声明
按照规划,将mysql的主配置文件my.cnf,作为ConfigMap资源,放在etcd中。
mysql-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
labels:
app: mysql
data:
my.cnf: |-
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
[mysqld]
innodb_file_per_table=ON
max_connections = 2000
secure_file_priv=/var/lib/mysql
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
这里的mysql-config作为一个ConfigMap资源,会被后面的deploy引用。
2 secret声明
按照规划,制作base64的暗文,声明secret。
echo -n "root" | base64
#回显base加密后的用户名密文
cm9vdA==
echo -n "123456" | base64
#回显base64加密后的口令密文
MTIzNDU2
mysql-root-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysql-root-secret
type: Opaque
data:
username: cm9vdA==
password: MTIzNDU2
后面声明deploy的yaml中,将引用mysql-root-secret这个secretKeyRef,并指定获取key=password这个变量的值。
3 Storage声明
按照规划,创建一个PVC,指向PV nfspv01。
mysql-storage.yaml
## PVC
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mysqlpvc
spec:
resources:
requests:
storage: 2Gi #设置 pvc 存储资源大小
accessModes:
- ReadWriteOnce
selector:
matchLabels:
app: nfspv01 #根据 Label 选择对应 PV
这里的mysqlpvc作为一个PVC资源,会被后面的deploy引用。
4 deploy声明
按照规划配置pod
mysql-deploy.yaml
## Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql01
labels:
app: mysql01
spec:
replicas: 1
selector:
matchLabels:
app: mysql01
template:
metadata:
labels:
app: mysql01
spec:
containers:
- name: mysqlcontainer
image: mysql:8.0.19
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-root-secret
key: password
resources:
limits:
cpu: 2000m
memory: 512Mi
requests:
cpu: 2000m
memory: 512Mi
livenessProbe:
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
exec:
command: ["mysqladmin", "-uroot", "-p${MYSQL_ROOT_PASSWORD}", "ping"]
readinessProbe:
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
exec:
command: ["mysqladmin", "-uroot", "-p${MYSQL_ROOT_PASSWORD}", "ping"]
volumeMounts:
- name: data
mountPath: /var/lib/mysql
- name: config
mountPath: /etc/mysql/conf.d/my.cnf
subPath: my.cnf
- name: localtime
readOnly: true
mountPath: /etc/localtime
volumes:
- name: data
persistentVolumeClaim:
claimName: mysqlpvc
- name: config
configMap:
name: mysql-config
- name: localtime
hostPath:
type: File
path: /etc/localtime
5 service声明
按照规划为mysql建立一个NodePort类型的SVC。
## Service
apiVersion: v1
kind: Service
metadata:
name: mysqlsvc
labels:
app: mysqlsvc
spec:
type: NodePort
ports:
- name: mysql
port: 3306
targetPort: 3306
nodePort: 30336
selector:
app: mysql01
6 apply执行
ConfigMap:
kubectl apply -f mysql-config.yaml -n mywebapp --dry-run=client
kubectl apply -f mysql-config.yaml -n mywebapp
kubectl -n mywebapp get ConfigMap
#回显
NAME DATA AGE
kube-root-ca.crt 1 3m9s
mysql-config 1 2m49s
Secret:
kubectl apply -f mysql-root-secret.yaml -n mywebapp --dry-run=client
kubectl apply -f mysql-root-secret.yaml -n mywebapp
kubectl -n mywebapp get secret
#回显
NAME TYPE DATA AGE
mysql-root-secret Opaque 2 8s
Storage:
kubectl apply -f mysql-storage.yaml -n mywebapp --dry-run=client
kubectl apply -f mysql-storage.yaml -n mywebapp
kubectl -n mywebapp get pvc
#回显
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysqlpvc Bound nfspv01 2Gi RWO 59s
deploy:
kubectl apply -f mysql-deploy.yaml -n mywebapp --dry-run=client
kubectl apply -f mysql-deploy.yaml -n mywebapp
kubectl -n mywebapp get pod -o wide
#回显
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql01-695cf548cd-5zjbr 0/1 ContainerCreating 0 17s 10.244.2.26 w02 <none> <none>
#创建完成后回显
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql01-695cf548cd-5zjbr 0/1 Running 0 11s 10.244.2.26 w02 <none> <none>
查看apply deploy pod的日志
#查看pod和container日志
kubectl -n mywebapp logs mysql01-695cf548cd-5zjbr -c mysqlcontainer
service:
kubectl apply -f mysql-service.yaml -n mywebapp --dry-run=client
kubectl apply -f mysql-service.yaml -n mywebapp
kubectl -n mywebapp get service
#回显
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mysqlsvc NodePort 10.107.108.12 <none> 3306:30336/TCP 7s
测试南北向暴露的端口
#在m01节点和任意worker节点上,使用iptable查看暴露的30336端口:
iptables -tnat -L | grep 30336
#回显
KUBE-EXT-W3WR2O63YWU7PI6D tcp -- anywhere anywhere /* mywebapp/mysqlsvc:mysql */ tcp dpt:30336
至此,mysql数据库在K8S集群上部署完毕,可以使用了。
7 创建mysql基本对象
为mysql数据库创建基本的数据库、用户对象
#进入pod
kubectl -n mywebapp exec -it mysql01-695cf548cd-5zjbr -- /bin/bash
#测试mysqld的状态
mysqladmin -uroot -p123456 ping
###回显:
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
mysqld is alive
#以mysql的root用户进入mysql的sql命令控制台
mysql -uroot -p123456
#建立一系列基本数据库对象:
CREATE USER user01@'%' identified BY 'passw0rd';
CREATE USER user01@'localhost' identified BY 'passw0rd';
CREATE DATABASE db01;
GRANT ALL PRIVILEGES ON db01.* to user01;
FLUSH PRIVILEGES;
#退出sql命令控制台
quit;
#退出pod
exit
8 验证数据库访问
使用DataGrid等任意支持mysql的SQL客户端,建立到下面的连接
jdbc:mysql://192.168.172.141:30336/db01
用户名user01
口令123456
成功连接后,建立库内数据对象
create table db01.department
(
dptid int auto_increment
primary key,
dptname varchar(20) not null
);
insert into db01.department(dptid, dptname) values (1, "市场部");
commit;
select * from db01.department;
确保数据库正常访问。
五、wordpress应用
1 mysql建立wordpress独立数据库和用户
为wordpress建立专用的数据库、用户,并为用户授权
#进入pod
kubectl -n mywebapp exec -it mysql01-695cf548cd-5zjbr -- /bin/bash
#以mysql的root用户进入mysql的sql命令控制台
mysql -uroot -p123456
#建立数据库db02、用户wordpress:
CREATE USER wordpress@'%' identified BY 'passw0rd';
CREATE USER wordpress@'localhost' identified BY 'passw0rd';
CREATE DATABASE db02;
GRANT ALL PRIVILEGES ON db02.* to wordpress;
FLUSH PRIVILEGES;
#退出sql命令控制台
quit;
#退出pod
exit
查看mysql的接入信息
#查看mysql的pod ip信息:
kubectl get pod -n mywebapp -o wide
#回显
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql01-695cf548cd-5zjbr 1/1 Running 0 44h 10.244.2.26 w02 <none> <none>
###这里的10.244.2.26就是mysql01这个pod的ip,但是为了防止变化,需要找到服务地址
kubectl get service -n mywebapp -o wide
#回显
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
mysqlsvc NodePort 10.107.108.12 <none> 3306:30336/TCP 44h app=mysql01
#集群默认全局域名为cluster.local,之前为mysql和wordpress建立的额ns为mywebapp,mysql服务名为mysqlsvc
#按照集群内部的名称规则,服务的访问入口为<service_name>.<namespace_name>.svc.<domainname>
#因此应为: mysqlsvc.mywebapp.svc.cluster.local
集群内mysql01的端口号为3306,因此可以得出以下mysql访问信息:
host: mysqlsvc.mywebapp.svc.cluster.local:3306
dbname: db02
dbuser: wordpress
dbpwd: passw0rd
2 secret声明
制作base64的暗文,声明secret,包含mysql连接信息,即host、dbuser、dbpwd的值。
echo -n "mysqlsvc.mywebapp.svc.cluster.local:3306" | base64
echo -n "db02" | base64
echo -n "wordpress" | base64
echo -n "passw0rd" | base64
#分别回显base加密后的密文
bXlzcWxzdmMubXl3ZWJhcHAuc3ZjLmNsdXN0ZXIubG9jYWw6MzMwNg==
ZGIwMg==
d29yZHByZXNz
cGFzc3cwcmQ=
wordpress-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: wordpress-secret
type: Opaque
data:
host: bXlzcWxzdmMubXl3ZWJhcHAuc3ZjLmNsdXN0ZXIubG9jYWw6MzMwNg==
dbname: ZGIwMg==
dbuser: d29yZHByZXNz
dbpwd: cGFzc3cwcmQ=
3 storage声明
wordpress-storage.yaml
## PVC
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: wordpresspvc
spec:
resources:
requests:
storage: 900Mi #设置 pvc 存储资源大小
accessModes:
- ReadWriteMany
selector:
matchLabels:
app: nfspv02 #根据 Label 选择对应 PV
这里的wordpresspvc作为一个PVC资源,会被后面的deploy引用。
4 deploy声明
按照规划配置pod
wordpress-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpressdpy
labels:
app: wordpress01dpy
spec:
replicas: 4
selector:
matchLabels:
app: wordpress01
template:
metadata:
labels:
app: wordpress01
spec:
containers:
- name: wordpresscontainer
image: wordpress:6-apache
env:
- name: WORDPRESS_DB_HOST
valueFrom:
secretKeyRef:
name: wordpress-secret
key: host
- name: WORDPRESS_DB_NAME
valueFrom:
secretKeyRef:
name: wordpress-secret
key: dbname
- name: WORDPRESS_DB_USER
valueFrom:
secretKeyRef:
name: wordpress-secret
key: dbuser
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: wordpress-secret
key: dbpwd
- name: WORDPRESS_DEBUG
value: "true"
volumeMounts:
- mountPath: /var/www/html
name: wp-data
volumes:
- name: wp-data
persistentVolumeClaim:
claimName: wordpresspvc
- name: localtime
hostPath:
type: File
path: /etc/localtime
如果想要直观一点方便调试,env部分也可以先把数据库相关环境变量写成明文
env:
- name: WORDPRESS_DB_HOST
value: "mysqlsvc.mywebapp.svc.cluster.local:3306"
- name: WORDPRESS_DB_NAME
value: "db02"
- name: WORDPRESS_DB_USER
value: "wordpress"
- name: WORDPRESS_DB_PASSWORD
value: "passw0rd"
5 service声明
wordpress-service.yaml
## Service
apiVersion: v1
kind: Service
metadata:
name: wordpresssvc
labels:
app: wordpresssvc
spec:
type: NodePort
ports:
- name: wordpress
port: 80
targetPort: 80
nodePort: 30080
selector:
app: wordpress01
6 apply执行
Secret:
kubectl apply -f wordpress-secret.yaml -n mywebapp --dry-run=client
kubectl apply -f wordpress-secret.yaml -n mywebapp
kubectl -n mywebapp get secret
#回显
NAME TYPE DATA AGE
mysql-root-secret Opaque 2 45h
wordpress-secret Opaque 3 6s
Storage:
kubectl apply -f wordpress-storage.yaml -n mywebapp --dry-run=client
kubectl apply -f wordpress-storage.yaml -n mywebapp
kubectl -n mywebapp get pvc
#回显
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysqlpvc Bound nfspv01 2Gi RWO 45h
wordpresspvc Bound nfspv02 1Gi RWX 7s
###通过回显,看到已经按照既定规划,两个PVC处于Bound状态,绑定到既定的PV之上了
deploy:
kubectl apply -f wordpress-deploy.yaml -n mywebapp --dry-run=client
kubectl apply -f wordpress-deploy.yaml -n mywebapp
kubectl -n mywebapp get pod -o wide
#回显
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql01-695cf548cd-5zjbr 1/1 Running 0 45h 10.244.2.26 w02 <none> <none>
wordpressdpy-7f795b898d-4kx7k 0/1 ContainerCreating 0 8m54s <none> w02 <none> <none>
wordpressdpy-7f795b898d-97pml 0/1 ContainerCreating 0 8m54s <none> w03 <none> <none>
wordpressdpy-7f795b898d-g59tk 0/1 ContainerCreating 0 8m54s <none> w01 <none> <none>
wordpressdpy-7f795b898d-q4m5m 0/1 ContainerCreating 0 8m54s <none> w03 <none> <none>
#创建成功后的回显
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql01-695cf548cd-5zjbr 1/1 Running 0 46h 10.244.2.26 w02 <none> <none>
wordpressdpy-7f795b898d-4kx7k 1/1 Running 0 56m 10.244.2.27 w02 <none> <none>
wordpressdpy-7f795b898d-97pml 1/1 Running 0 56m 10.244.3.24 w03 <none> <none>
wordpressdpy-7f795b898d-g59tk 1/1 Running 0 56m 10.244.1.28 w01 <none> <none>
wordpressdpy-7f795b898d-q4m5m 1/1 Running 0 56m 10.244.3.25 w03 <none> <none>
查看apply deploy pod的日志
#查看pod和container日志
kubectl -n mywebapp logs wordpressdpy-7f795b898d-4kx7k -c wordpresscontainer
#回显
WordPress not found in /var/www/html - copying now...
Complete! WordPress has been successfully copied to /var/www/html
No 'wp-config.php' found in /var/www/html, but 'WORDPRESS_...' variables supplied; copying 'wp-config-docker.php' (WORDPRESS_DB_HOST WORDPRESS_DB_PASSWORD WORDPRESS_DB_USER)
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 10.244.2.27. Set the 'ServerName' directive globally to suppress this message
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 10.244.2.27. Set the 'ServerName' directive globally to suppress this message
[Tue Jan 02 15:56:40.049660 2024] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.57 (Debian) PHP/8.2.14 configured -- resuming normal operations
[Tue Jan 02 15:56:40.049730 2024] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
service:
kubectl apply -f wordpress-service.yaml -n mywebapp --dry-run=client
kubectl apply -f wordpress-service.yaml -n mywebapp
kubectl -n mywebapp get service
#回显
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mysqlsvc NodePort 10.107.108.12 <none> 3306:30336/TCP 46h
wordpresssvc NodePort 10.98.60.145 <none> 80:30080/TCP 7s
7 验证wordpress可用
集群外,浏览器中,访问http://192.168.172.141:30080/,出现语言选择的内容,则意味着wordpress已经可以使用,且和数据库连接成功。按照步骤提示,创建应用用户,并开启自己的博客。初始化后,会在mysql的db02中,初始化12张表。
wp_commentmeta
wp_comments
wp_links
wp_options
wp_postmeta
wp_posts
wp_term_relationships
wp_term_taxonomy
wp_termmeta
wp_terms
wp_usermeta
wp_users
至此,wordpress应用部署成功。
六、环境清理
1 清除wordpress所有资源
kubectl -n mywebapp delete service wordpresssvc
kubectl -n mywebapp delete deploy wordpressdpy
kubectl -n mywebapp delete pvc wordpresspvc
kubectl -n mywebapp delete secret wordpress-secret
2 清除mysql所有资源
kubectl -n mywebapp delete service mysqlsvc
kubectl -n mywebapp delete deploy mysql01
kubectl -n mywebapp delete pvc mysqlpvc
kubectl -n mywebapp delete secret mysql-root-secret
kubectl -n mywebapp delete cm mysql-config
delete deploy时,可以同时监控pod日志
kubectl -n mywebapp logs mysql01-8545bf88cf-52xv5 -c mysqlcontainer -f
确认删除deploy时,mysql退出。
3 清除公共资源
至此,所有在mywebapp这个namespace下的资源都应该被清掉了,用下面的命令验证
kubectl get all -n mywebapp
清除namespace
kubectl delete namespace mywebapp
清除全局资源PV
kubectl delete pv nfspv01
kubectl delete pv nfspv02
别忘了清理NFS上的数据文件
#repo01节点上
cd /data/nfs/share01
rm -rf *
cd /data/nfs/share02
rm -rf *
附件
附件一 NFS服务器和客户端
(1)配置独立逻辑卷(可选)
lvcreate -L 5G -n lvdata vg00
mkfs.xfs /dev/vg00/lvdata
mkdir /data
echo "/dev/disk/by-uuid/6f709e18-61d4-4d27-b844-9c9349b5e3e9 /boot xfs defaults 0 1" >> /etc/fstab
mount -a
df -h
mkdir -p /data/nfs/share01
其中,第4行写入fstab中的卷uuid,到/dev/disk/by-uuid目录下,找到和/dev/disk/by-id下,dm-name-vg00-lvdata指向同一个dm的逻辑卷uuid,就是。
后续,将把/data/nfs/share01目录共享出去,作为mysql的数据存储卷。
(2)安装并配置nfs-server
ubuntu中的nfs-server的安装包为nfs-kernel-server,安装后服务为nfs-server,安装后会连带让rpcbind服务监听111端口。
同apt安装的其他带服务的软件一样,nfs-server安装后会自动启动且为开机启动。
ubuntu的nfs-server和其他linux分发版本完全一致,主配置文件/etc/exports,使用showmount命令查看某节点共享的nfs目录。
apt install nfs-kernel-server
cp /etc/exports /etc/exports.bak
echo "/data/nfs/share01 *(rw,sync,no_subtree_check,no_root_squash)" >> /etc/exports
systemctl restart nfs-server
(3)查看nfs支持的协议版本
这里专指nfs协议版本,非nfs-kernel-server包的ubuntu定义版本
cat /proc/fs/nfsd/versions
###回显
-2 +3 +4 +4.1 +4.2
#这里可以看到,ubuntu20+的操作系统中,默认不支持(减号)nfs2,支持(加号)3、4、4.1、4.2
nfs server支持的不同的nfs协议版本,在客户端挂载时,在参数选择上有较大差别,这个后面再客户端配置时会简单说明。
(4)验证nfs-server有效
#netstat验证111端口已经处于监听状态
netstat -tunpl | grep 111
#查看本机的共享出去的目录
showmount -e localhost
###回显
/data/nfs/share01 *
#查看nfsstat状态
nfsstat
(5)客户端
客户端只要保证能够连通服务器端的111端口和2049端口,这是前提。
mkdir /sharefs
apt install nfs-common
showmount -e <服务器端IP或主机名>
mount -t nfs <服务器端IP或主机名>:/data/nfs/share01 /sharefs
df -h | grep share01
umount /sharefs
正常情况下,通过上面的mount命令,无参数挂载服务器端/data/nfs/share01目录到客户端/share01下。注意这里尝试后,umount掉了。
如果客户端需要长期挂载nfs,包括开机就挂载,则需要慎重考虑带参数挂载,因为nfs挂载参数将很大程度上决定是客户端程序重要,还是数据存储重要。
下面给带参数的挂载命令作为参考。
mount -t nfs -o soft,timeo=200,retrans=3,retry=1 <服务器端IP或主机名>:/data/nfs/share01 /sharefs
###注意这里使用了soft软挂载方式,soft和hard(默认)哪种好的争议由来已久
###下面以nfs v4为基础,简要给出-o中的参数解释
soft - 软挂载,非默认值,默认值为hard。选择soft后,当nfs server宕机后,soft模式client不会一直试图连接server,不会把自己的其他FS夯死。
- 但选择soft,也就意味着server宕机后,有些等待中的数据传输被放弃了。
timeo - 数据传输失败的超时时间,单位0.1秒,默认600即60秒。这里设为20秒,即20秒服务器端不响应,则放弃本次传输,转而找retrans参数的重试次数。
retrans - 重试连接server的次数,默认为2。这里设为3,在soft模式下,重试3次后,client和server彻底断连,不再试图重试。
retry - 在mount时的重试时间,单位分钟,默认为2分钟。这里设为1,即重试1分钟的mount后还连不上则放弃,如果是开机就启动连接,则这种配置不耽误开机时间。
- 注意该参数容易和retrans混淆,retry是mount时的重试次数,retrans是建立mount以后如何应对服务器无响应的重试次数。
由于nfs v2、v3、v4版本差异较大,很多网上的攻略的配置参数还是基于v2版的,和现在主流的linux版本的nfs已经不兼容。
生产环境一定要再客户端中,使用man nfs,查看参数说明,谨慎选择参数。
开机就有nfs的挂载,可以将nfs挂载固定到fstab中
#与上面相同参数的fstab挂载
echo "<服务器端IP或主机名>:/data/nfs/share01 /sharefs nfs soft,timeo=200,retrans=3,retry=1 0 0" >> /etc/fstab
附件二 deploy环境变量和secret
本次应用部署中,使用了secret资源+在deploy mysql时调用secret资源获取环境变量的方式。这种调用有以下三种选择。
(1)deploy中直接写环境变量的值
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
这种直接给出password的值的方式,最直观,也最不安全。
(2)deploy中环境变量使用从secret中获得的某个提前定义的密文的明文值
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-root-secret
key: password
正文中就是采取这种方式,value改为了valueFrom,调用secretKeyRef的name为mysql-root-secret,从里面拿到key password的value,作为password。
这种方式相比第一种安全了一些。前提是要先创建一个secret资源。创建该secret资源的方式,在正文中有详细给出,这里不再给。
这里给出手工生成secret声明的yaml内容的方式
kubectl create secret generic mysql-root-secret --from-literal=username=root --from-literal=password=123456 -o yaml
#回显
apiVersion: v1
data:
password: MTIzNDU2
username: cm9vdA==
kind: Secret
metadata:
creationTimestamp: "2023-12-31T17:06:29Z"
name: mysql-root-secret
namespace: default
resourceVersion: "961623"
uid: cae5bd15-5428-4a1f-9c6e-2f0149745a39
type: Opaque
实际上正文的mysql-root-secret.yaml,就是在这个输出的基础上改的。
(3)同(2),但使用kubectl create手工生成时,不想写明文被操作系统history记录,则可以采用--from-file的方式
kubectl create secret generic try-secret --from-literal=username=root --from-file=password=./password.txt --dry-run=client -o yaml
#回显
apiVersion: v1
data:
password: MTIzNDU2Cg==
username: cm9vdA==
kind: Secret
metadata:
creationTimestamp: "2024-01-01T16:07:38Z"
name: try-secret
namespace: default
resourceVersion: "1094469"
uid: 4c30a7d4-d50d-40bd-94c9-ccb86a620d33
type: Opaque
之后再组织yaml即可。from file方式也可以用于将私钥文件、证书文件等进行加密。
注:使用base64编码解码
#编码
echo "Welcome to Linux" | base64
#解码
echo "MTIzNDU2Cg==" | base64 --decode
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧