参考文档:
Kubernetes 部署metrics-server - 简书 (jianshu.com)
Kubernetes 部署metrics-server - 简书 (jianshu.com)
k8s-v1.22安装metrics-server_zhangdd的博客-CSDN博客
仅提供参考。
如有问题请点击页脚(联系博主)反馈
目的:本次实验是使用kubernets平台部署WordPress博客系统,最终可对外提供访问。
需求:
1、可提供持久化存储的MySQL;
2、配置探针检测应用是否存活;
3、 配置 HPA,让应用能够自动应对流量高峰期。
4、增加滚动更新策略,这样可以保证在更新应用的时候,服务不会被中断。
5、把部署的应用整合到一个 YAML 文件 wordpress-all.yaml 中;
6、端口映射,外部可访问。
注意:使用pv存储要事先搭建好NFS服务,本文不涉及NFS搭建。
主机 | IP |
---|---|
Master | 192.168.30.30 |
Node1 | 192.168.30.31 |
kubectl create namespace blog //创建一个命名空间,名称为blog
新建一个WordPress文件夹,用于存放相关yaml文件
mkdir /root/wordpress
编写PVyaml文件
#####master#####
mkdir -p /nfs/pv1
vim /root/wordpress/pv1.yaml
#####pv的yaml文件(注意修改)
apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv
namespace: blog
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /nfs/pv1
server: 192.168.30.30
//namespace使用创建的blog
//ReadWriteOnce 可读写但只能被一个节点挂载
//path: /nfs/pv 挂载到本机/nfs/pv目录,需要事先创建好此目录
//server: 192.168.30.30 NFS服务器的地址,根据自己实际情况填写
kubectl apply -f /root/wordpress/pv1.yaml
vim /root/wordpress/pvc1.yaml
#pvc的yaml文件
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc
namespace: blog
spec:
accessModes:
- ReadWriteOnce
volumeName: mypv
resources:
requests:
storage: 1Gi
kubectl apply -f /root/wordpress/pvc1.yaml
#####master#####
vim /root/wordpress/mysql-db.yaml
#mysql的deploymnet的文件
//注:
//namespace使用上一步自己创建的命名空间
//创建wordpress时,mysql相关参数需与此处创建mysql时保存一致
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deploy
namespace: blog
labels:
apps: mysql
spec:
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.6
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
name: dbport
env:
- name: MYSQL_ROOT_PASSWORD
value: rootPassWord
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wordpress
- name: MYSQL_PASSWORD
value: wordpress
volumeMounts:
- name: db-pv
mountPath: /var/lib/mysql
volumes:
- name: db-pv
persistentVolumeClaim:
claimName: mypvc
kubectl apply -f mysql-db.yaml
#创建mysql的service.yaml文件
vim /root/wordpress/mysql-service.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: blog
spec:
selector:
app: mysql
ports:
- name: mysqlport
protocol: TCP
port: 3306
targetPort: 3306
kubectl apply -f /root/wordpress/mysql-service.yaml
对 pod 增加 liveness probe 和 rediness probe 两个探针,每 10s 检测一次应用是否可读,每 3s 检测一次应用是否存活。
存活探针liveness采用tcpSocket端口探测方式,每3s一次检测80端口是否存活;就绪探针readiness采用httpGet方式每10s一次探测wardpress主页的http返回值是否正常。
编辑wordpress的yaml文件
#####master#####
vim /root/wordpress/wordpressdeploy.yaml
#wordpress的deploymnet的文件
//注:
//namespace使用上一步自己创建的命名空间
//密码都要与MySQL密码相匹配
//host填MySQL的虚拟IP
//resources里定义资源的上限和下限
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-deploy
namespace: blog
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 50%
maxUnavailable: 0
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: wordpress
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: wdport
env:
- name: WORDPRESS_DB_HOST
value: mysql:3306
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_PASSWORD
value: wordpress
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 100m
memory: 500Mi
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 3
periodSeconds: 3
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 5
periodSeconds: 10
kubectl apply -f wordpressdeploy.yaml
注:如果部署后访问wordpress的web界面显示连接不上数据库,则该k8s环境的DNS有问题,只需将以上指向Mysql的值(mysql:3306)改为(mysql服务的IP地址:3306)跳过DNS即可,如果可以连上则不用改。
![在这里插入图片描述](https://img-blog.csdnimg.cn/6e732bc78d684e418fc65355feb77deb.png)
#创建wordpress的service.yaml文件
vim /root/wordpress/wordpress-service.yaml
//NodePort属性映射端口,提供外部访问
apiVersion: v1
kind: Service
metadata:
name: wordpress
namespace: blog
spec:
type: NodePort
selector:
app: wordpress
ports:
- name: wordpressport
protocol: TCP
port: 80
targetPort: wdport
kubectl apply -f /root/wordpress/wordpress-service.yaml
HPA需要metrics-server进行资源监控,如没部署,可参考第四点进行部署。
kubectl autoscale deployment wordpress-deploy --cpu-percent=10 --min=1 --max=10 -n blog
HPA创建完毕,现在进行HPA的负载测试,查看是否能够进行自动横向扩展
#启动一个用于测试的容器
kubectl run v1 -it --image=busybox /bin/sh
#登录到容器执行如下命令
while true; do wget -q -O- http://wordpress服务的IP:端口; done
此容器会不停的去访问去获取wordpress的界面
#重开一个终端执行以下命令
kubectl get hpa -n blog -w
kubectl get pod -n blog
几分钟后可以看到,自动横向拓展了8个pod,当我停止了curl命令,不一会儿pod数量又恢复了
所以HPA成功。
此IP是节点的IP,端口通过kubectl get svc -n blog,对应查询
http://192.168.30.30:端口/
已经可以访问,进行安装操作,填入对应数据库的信息,wordpress就搭建完成。
#将wordpressdeploy.yaml中wordpress的image版本改为5.8
image: wordpress:5.8
#再次部署,
kubectl apply -f wordpressdeploy.yaml
#查看滚动更新状态,同时不同的访问web界面是否存在影响。
可以看到滚动更新成功,web界面依然一直可以访问,并不受影响。
在使用HPA的时候,k8s系统需要进行资源监控,才能使HPA生效,所有需要部署metrics-server用于监测node,pod等的CPU,内存使用情况。
vim /etc/kubernetes/manifests/kube-apiserver.yaml
········
- --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
- --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
- --requestheader-allowed-names=aggregator
- --requestheader-extra-headers-prefix=X-Remote-Extra-
- --requestheader-group-headers=X-Remote-Group
- --requestheader-username-headers=X-Remote-User
- --runtime-config=api/all=true
- --enable-aggregator-routing=true
······
#重启
systemctl restart kubelet.service
因为部署文件中image地址指向的是国外的镜像,如果可以访问外网则可以直接拉取,否则手动拉取镜像。
######在node1节点手动拉取镜像
docker pull registry.cn-shanghai.aliyuncs.com/szr0728/metrics-server:v0.5.0
docker tag registry.cn-shanghai.aliyuncs.com/szr0728/metrics-server:v0.5.0 k8s.gcr.io/metrics-server/metrics-server:v0.5.0
######在master节点
yum install wget -y
cd
wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.5.0/components.yaml
#在components.yaml文件中添加如下参数
- --kubelet-insecure-tls
kubectl apply -f components.yaml
#查看状态是否为running
kubectl -n kube-system get pods -l k8s-app=metrics-server
#查看是否有报错
kubectl -n kube-system logs -l k8s-app=metrics-server -f
#查看资源监控能否正常显示
kubectl top node
#删除前面步骤创建的资源
kubectl delete deploy wordpress-deploy mysql-deploy -n blog
kubectl delete hpa wordpress-deploy -n blog
kubectl delete svc wordpress mysql -n blog
kubectl delete pvc mypvc -n blog
kubectl delete pv mypv
rm -rf /nfs/pv1/*
#wordpress-all.yaml文件
#vim wordpress-all.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv
namespace: blog
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /nfs/pv1
server: 192.168.30.30
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc
namespace: blog
spec:
accessModes:
- ReadWriteOnce
volumeName: mypv
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deploy
namespace: blog
labels:
apps: mysql
spec:
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.6
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
name: dbport
env:
- name: MYSQL_ROOT_PASSWORD
value: rootPassWord
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wordpress
- name: MYSQL_PASSWORD
value: wordpress
volumeMounts:
- name: db-pv
mountPath: /var/lib/mysql
volumes:
- name: db-pv
persistentVolumeClaim:
claimName: mypvc
---
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: blog
spec:
selector:
app: mysql
ports:
- name: mysqlport
protocol: TCP
port: 3306
targetPort: 3306
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-deploy
namespace: blog
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 50%
maxUnavailable: 0
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: wordpress
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: wdport
env:
- name: WORDPRESS_DB_HOST
value: mysql:3306
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_PASSWORD
value: wordpress
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 100m
memory: 500Mi
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 3
periodSeconds: 3
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 5
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: wordpress
namespace: blog
spec:
type: NodePort
selector:
app: wordpress
ports:
- name: wordpressport
protocol: TCP
port: 80
targetPort: wdport
---
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: wordpress-hpa
namespace: blog
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: wordpress-deploy
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: memory
targetAverageUtilization: 50
kubectl apply -f wordpress-all.yaml
部署完成后,查看pod和HPA状态,查看svc的NodePort端口,访问web。
问题:ScalingActive False FailedGetResourceMetric the HPA was unable to compute the replica count: failed to get cpu utilization: unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: an error on the server (“Internal Server Error: “/apis/metrics.k8s.io/v1beta1/namespaces/blog/pods?labelSelector=app%!D(MISSING)wordpress”: the server could not find the requested resource”) has prevented the request from succeeding (get pods.metrics.k8s.io)
通过排查发现metrics-server服务没有running,查看日志:Failed to make webhook authorizer request: the server could not find the requested resource E1121 12:53:58.3613851 errors.go:77] the server could not find the requested resource
解决方法:查看自己环境的k8s版本,如果是1.21+,部署metrics-server:v0.5.0以下的则会报错,只需部署0.5版本以上即可解决,部署方法详见上文。