k8s- HPA+ PV + Ingress 策略 + 客户端访问
介绍一下ingress
Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。
Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。
Ingress 公开从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。
下面是一个将所有流量都发送到同一 Service 的简单 Ingress 示例:
Ingress 可为 Service 提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及基于名称的虚拟托管。 Ingress 控制器 通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。
Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的 Service。
介绍一下Ingress Controller
你必须拥有一个 Ingress 控制器 才能满足 Ingress 的要求。 仅创建 Ingress 资源本身没有任何效果。
你可能需要部署 Ingress 控制器,例如 ingress-nginx。 你可以从许多 Ingress 控制器 中进行选择。
实际上,Ingress相当于一个7层的负载均衡器,是kubernetes对反向代理的一个抽象,它的工作原理类似于Nginx,可以理解成在Ingress里建立诸多映射规则,Ingress Controller通过监听这些配置规则并转化成Nginx的反向代理配置 , 然后对外部提供服务。在这里有两个核心概念:
- ingress:kubernetes中的一个对象,作用是定义请求如何转发到service的规则
- ingress controller:具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发,实现方式有很多,比如Nginx, Contour, Haproxy等等
Ingress(以Nginx为例)的工作原理如下:
- 用户编写Ingress规则,说明哪个域名对应kubernetes集群中的哪个Service
- Ingress控制器动态感知Ingress服务规则的变化,然后生成一段对应的Nginx反向代理配置
- Ingress控制器会将生成的Nginx配置写入到一个运行着的Nginx服务中,并动态更新
- 到此为止,其实真正在工作的就是一个Nginx了,内部配置了用户定义的请求转发规则
1 环境准备 搭建ingress环境
###########打上标签
[root@master ingress-nginx]# kubectl label node node1 role=ingress-nginx-controller
node/node1 labeled
[root@master ingress-nginx]# kubectl label node node2 role=ingress-nginx-controller
node/node2 labeled
[root@master ingress-nginx]# kubectl label node node3 role=ingress-nginx-controller
[root@master ~]# mkdir ingress-controller
[root@master ingress-controller]# wget https://gitee.com/after399/kubernetes-project/blob/master/kubernetes-ingress/ingress-controller/nginx-ingress-contoller.yaml #####好像git不能单独拉取一个文件?直接去网页复制吧
[root@master ingress-controller]# kubectl apply -f nginx-ingress-contoller.yaml
namespace/nginx-ingress created
serviceaccount/nginx-ingress created
clusterrole.rbac.authorization.k8s.io/nginx-ingress created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress created
secret/default-server-secret created
configmap/nginx-config created
deployment.apps/nginx-ingress created
2 准备一个nfs存储
NFS是一个网络文件存储系统,可以搭建一台NFS服务器,然后将Pod中的存储直接连接到NFS系统上,这样的话,无论Pod在节点上怎么转移,只要Node跟NFS的对接没问题,数据就可以成功访问。
1)首先要准备nfs的服务器,这里为了简单,直接是master节点做nfs服务器
# 在nfs上安装nfs服务
[root@mster ~]# yum install nfs-utils -y
# 准备一个共享目录
[root@master ~]# mkdir /root/data/nfs -pv
# 将共享目录以读写权限暴露给192.168.2.0/24网段中的所有主机
[root@master ~]# vim /etc/exports
[root@master ~]# more /etc/exports
/root/data/nfs 192.168.2.0/24(rw,no_root_squash)
# 启动nfs服务
[root@master ~]# systemctl restart nfs
2)接下来,要在的每个node节点上都安装下nfs,这样的目的是为了node节点可以驱动nfs设备
# 在node上安装nfs服务,注意不需要启动
[root@master ~]# yum install nfs-utils -y
3 创建pv进行存储
使用NFS作为存储,来演示PV的使用,创建1个PV,对应NFS中的1个暴露的路径。
由于kubernetes支持的存储系统有很多,要求客户全都掌握,显然不现实。为了能够屏蔽底层存储实现的细节,方便用户使用, kubernetes引入PV和PVC两种资源对象。
-
PV(Persistent Volume)是持久化卷的意思,是对底层的共享存储的一种抽象。一般情况下PV由kubernetes管理员进行创建和配置,它与底层具体的共享存储技术有关,并通过插件完成与共享存储的对接。
-
PVC(Persistent Volume Claim)是持久卷声明的意思,是用户对于存储需求的一种声明。换句话说,PVC其实就是用户向kubernetes系统发出的一种资源需求申请。
使用了PV和PVC之后,工作可以得到进一步的细分:
- 存储:存储工程师维护
- PV: kubernetes管理员维护
- PVC:kubernetes用户维护
- 准备NFS环境
# 创建目录
[root@nfs ~]# mkdir /root/data/pv1 -pv
# 暴露服务
[root@nfs ~]# more /etc/exports
/root/data/pv1 192.168.2.0/24(rw,no_root_squash)
# 重启服务
[root@nfs ~]# systemctl restart nfs
- 创建pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /root/data/pv1
server: 192.168.2.200
[root@master ingress-controller]# kubectl apply -f pv.yaml
创建pvc.yaml,申请pv
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc1
namespace: dev #指定namespace
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
# 创建pvc
[root@master ~]# kubectl create -f pvc.yaml
persistentvolumeclaim/pvc1 created
4 准备使用HPA进行动态扩容
安装metrics-server
metrics-server可以用来收集集群中的资源使用情况
# 安装git
[root@master ~]# yum install git -y
# 获取metrics-server, 注意使用的版本
[root@master ~]# git clone -b v0.3.6 https://github.com/kubernetes-incubator/metrics-server
# 修改deployment, 注意修改的是镜像和初始化参数
[root@master ~]# cd /root/metrics-server/deploy/1.8+/
[root@master 1.8+]# vim metrics-server-deployment.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: metrics-server
namespace: kube-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: metrics-server
namespace: kube-system
labels:
k8s-app: metrics-server
spec:
selector:
matchLabels:
k8s-app: metrics-server
template:
metadata:
name: metrics-server
labels:
k8s-app: metrics-server
spec:
hostNetwork: true
serviceAccountName: metrics-server
volumes:
# mount in tmp so we can safely use from-scratch images and/or read-only containers
- name: tmp-dir
emptyDir: {}
containers:
- name: metrics-server
image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server-amd64:v0.3.6
imagePullPolicy: Always
args:
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP
volumeMounts:
- name: tmp-dir
mountPath: /tmp
# 安装metrics-server
[root@master 1.8+]# kubectl apply -f ./
# 查看pod运行情况
[root@master 1.8+]# kubectl get pod -n kube-system
metrics-server-6b976979db-2xwbj 1/1 Running 0 90s
# 使用kubectl top node 查看资源使用情况
[root@master 1.8+]# kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
master 289m 14% 1582Mi 54%
node1 81m 4% 1195Mi 40%
node2 72m 3% 1211Mi 41%
[root@master 1.8+]# kubectl top pod -n kube-system
NAME CPU(cores) MEMORY(bytes)
coredns-6955765f44-7ptsb 3m 9Mi
coredns-6955765f44-vcwr5 3m 8Mi
etcd-master 14m 145Mi
...
# 至此,metrics-server安装完成
5 准备service和pod
创建tomcat-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: dev
spec:
strategy: # 策略
type: RollingUpdate # 滚动更新策略
replicas: 3
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
volumeMounts:
- name: logs-volume
mountPath: /var/log/nginx
resources: # 资源配额
limits: # 限制资源(上限)
cpu: "1" # CPU限制,单位是core数
requests: # 请求资源(下限)
cpu: "100m" # CPU限制,单位是core数
volumes:
- name: logs-volume
persistentVolumeClaim:
claimName: pvc1
readOnly: false
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-deployment
namespace: dev
spec:
replicas: 1
selector:
matchLabels:
app: tomcat-pod
template:
metadata:
labels:
app: tomcat-pod
spec:
containers:
- name: tomcat
image: tomcat:8.5-jre10-slim
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: dev
spec:
selector:
app: nginx-pod
clusterIP: 10.97.97.97
type: ClusterIP
ports:
- port: 80
targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-service
namespace: dev
spec:
selector:
app: tomcat-pod
clusterIP: 10.97.97.98
type: ClusterIP
ports:
- port: 8080
targetPort: 8080
[root@master tomcat-nginx]# vim tomcat-nginx.yaml
[root@master tomcat-nginx]# kubectl apply -f tomcat-nginx.yaml
deployment.apps/nginx-deployment created
deployment.apps/tomcat-deployment created
service/nginx-service created
service/tomcat-service created
[root@master tomcat-nginx]# kubectl get svc -n dev #此时tomcat和nginx服务已经部署好了
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service ClusterIP 10.97.97.97 <none> 80/TCP 40s
tomcat-service ClusterIP 10.97.97.98 <none> 8080/TCP 40s
6 创建hpa策略
创建pc-hpa.yaml文件,内容如下:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: pc-hpa
namespace: dev
spec:
minReplicas: 1 #最小pod数量
maxReplicas: 10 #最大pod数量
targetCPUUtilizationPercentage: 3 # CPU使用率指标
scaleTargetRef: # 指定要控制的nginx信息
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
# 创建hpa
[root@master 1.8+]# kubectl create -f pc-hpa.yaml
horizontalpodautoscaler.autoscaling/pc-hpa created
# 查看hpa
[root@master 1.8+]# kubectl get hpa -n dev
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
pc-hpa Deployment/nginx 0%/3% 1 10 1 62s
7 创建ingress服务
[root@master 1.8+]# vim ingress-http.yaml
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mywebsite-ingress
spec:
rules:
- host: duan.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: nginx-service
port:
number: 80
- host: duantomcat.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: nginx-service
port:
number: 8080
############注意!!!!!!!!
######这里的如果使用/url匹配同时也会在容器内部匹配url,所以需要在html文件下创建index.html文件,并且输入内容,才能查看到网页
####而且可以在nginx-ingress-controller中的/etc/nginx/conf.d中的*******.conf查看具体的配置
访问这个controller所在的node
并且将这个node的ip地址,在主机的/etc/hosts用域名解析进行访问,就可以了,或者将master的ip用域名解析,同时查看nginx-service的端口号,使用端口号来访问
同时查看 pv下
[root@master ingress-controller]# cd ~
[root@master ~]# ls
anaconda-ks.cfg data hpa ingress-controller kube-flannel.yml metrics-server tomcat-nginx
[root@master ~]# cd data
[root@master data]# ls
nfs pv1
[root@master data]# cd pv1
[root@master pv1]# ls
access.log error.log
[root@master pv1]# cat access.log
10.244.2.2 - - [08/Aug/2022:07:12:01 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" "192.168.2.15"
10.244.2.2 - - [08/Aug/2022:07:12:01 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://nginx.duan.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" "192.168.2.15"
数据存储也成功了
8 使用ab进行压力测试
[root@master pv1]# kubectl get pods -n dev -w
NAME READY STATUS RESTARTS AGE
nginx-deployment-65c886b84-2prd7 1/1 Running 0 33s
nginx-deployment-65c886b84-7klvd 1/1 Running 0 33s
nginx-deployment-65c886b84-9cstk 1/1 Running 0 106m
nginx-deployment-65c886b84-bctn4 1/1 Running 0 33s
nginx-deployment-65c886b84-bq7ws 1/1 Running 0 3s
nginx-deployment-65c886b84-ffg4p 1/1 Running 0 18s
nginx-deployment-65c886b84-h7hq9 1/1 Running 0 18s
nginx-deployment-65c886b84-j5ldr 1/1 Running 0 3s
nginx-deployment-65c886b84-lpnlq 0/1 ContainerCreating 0 18s
nginx-deployment-65c886b84-p8d8z 0/1 ContainerCreating 0 18s
效果非常明显