Service概念
Kubernetes Pod是有生命周期的,它们可以被创建,也可以被销毁,然而一旦被销毁生命就永远结束,
每个 Pod 都会获取它自己的 IP 地址,可一旦销毁后,重新创建后,IP地址会产生改变。
这时候我们通过 k8s中的Service 访问整个pod集群,只要Service不被销毁,pod不断发生变化 入口访问的ip总是固定。
Service资源用于为pod对象提供一个固定、统一的访问接口及负载均衡的能力,并借助新一代DNS系统的服务发现功能,解决客户端发现并访问容器化应用的问题。
kubernetes中的service是一种逻辑概念。它定义了一个pod逻辑集合以及访问它们的策略,service与pod的关联同样是通过label完成的。service的目标是提供一种桥梁,他会为访问者提供一个固定的访问IP地址,用于在访问时重定向到相应的后端。
Service 实现对pod 负载均衡
labels 标签 来管理 pod集群的
Service类型
1.ClusterIP:默认值,k8s系统给service自动分配的虚拟IP,只能在集群内部访问。一个Service可能对应多个EndPoint(Pod),client访问的是Cluster IP,通过iptables规则转到Real Server,从而达到负载均衡的效果
2.NodePort:将Service通过指定的Node上的端口暴露给外部,访问任意一个
3.NodeIP:nodePort都将路由到ClusterIP。
4.LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到:NodePort,此模式只能在云服务器上使用。
5.ExternalName:将服务通过 DNS CNAME记录方式转发到指定的域名(通过 spec.externlName 设定)
Service案例演示
Service环境准备
1.在同一个命名空间下启动三个不同的pod
2.修改每个pod里面的 nginx 容器信息 例如 nginx 1 nginx2 nginx3
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-service01.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mayikt-deployment
namespace: mayikt-sit
spec:
replicas: 3
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.9
ports:
- containerPort: 80
kubectl get pods -n mayikt-sit
为了方便测试查看的效果 修改每个nginx中 index.html 页面 为对应的ip地址
kubectl get pod -n mayikt-sit -o wide --show-labels
kubectl describe pods -n mayikt-sit
修改 pod1
kubectl exec -it mayikt-deployment-97b5dbd78-2wcd8 -n mayikt-sit /bin/sh
echo “167节点 172.17.0.4” > /usr/share/nginx/html/index.html
修改 pod2
kubectl exec -it mayikt-deployment-97b5dbd78-q9nt2 -n mayikt-sit /bin/sh
echo “167节点 172.17.0.3” > /usr/share/nginx/html/index.html
修改 pod3
kubectl exec -it mayikt-deployment-97b5dbd78-qrrsb -n mayikt-sit /bin/sh
echo “177节点 172.17.0.3” > /usr/share/nginx/html/index.html
ClusterIP(集群内部访问)
默认值,k8s系统给service自动分配的虚拟IP,只能在集群内部访问。一个Service可能对应多个EndPoint(Pod),client访问的是Cluster IP,通过iptables规则转到Real Server,从而达到负载均衡的效果
Service 是由 kube-proxy 组件,加上 iptables 来共同实现的
kubectl create -f mayikt-service02.yml
kubectl get svc mayikt-clusterip -n mayikt-sit
kubectl get svc service的名称 -n 命名空间名称
kubectl describe svc mayikt-clusterip -n mayikt-sit
apiVersion: v1
kind: Service
metadata:
name: mayikt-clusterip
namespace: mayikt-sit
spec:
selector:
app: nginx-pod
clusterIP: # service的ip地址, 如果不写默认会生成一个随机的IP
type: ClusterIP
ports:
- port: 80 # Service端口
targetPort: 80 # pod端口
在177节点上执行
curl 10.101.197.248
kubectl describe svc mayikt-clusterip -n mayikt-sit
kubectl get endpoints -n mayikt-sit -o wide
每隔1s 访问nginx 集群的ip
while true ;do curl 10.103.216.229 ; sleep 1;done;
分发策略:
默认是随机或者轮询
自定义 改成固定ip访问 即来自同一个客户端发起的所有请求都会转发到固定的一个Pod上
先删除之前集群ip
kubectl delete -f mayikt-service02.yml
kubectl create -f mayikt-service03.yml
sessionAffinity: ClientIP
apiVersion: v1
kind: Service
metadata:
name: mayikt-clusterip
namespace: mayikt-sit
spec:
selector:
app: nginx-pod
clusterIP: # service的ip地址, 如果不写默认会生成一个随机的IP
type: ClusterIP
ports:
- port: 80 # Service端口
targetPort: 80 # pod端口
sessionAffinity: ClientIP
kubectl describe svc mayikt-clusterip -n mayikt-sit
循环测试访问:
while true ;do curl 10.105.124.70:80 ; sleep 1;done;
iptables
iptables
kubectl describe svc mayikt-clusterip -n mayikt-sit
iptables -t nat -nL |grep 80
查看iptables的规则:iptables -t nat -nL |grep 80,iptables 使用NAT等技术将virtualIP的流量转至endpoint中,容器内暴露的端口是80
kube-proxy 通过 iptables 处理 Service 的过程,需要在宿主机上设置相当多的 iptables规则,如果宿主机有大量的Pod,不断刷新iptables规则,会消耗大量的CPU资源。
ipvs
IPVS模式的service,可以使K8s集群支持更多量级的Pod
pod和service通信: 通过iptables或ipvs实现通信,ipvs取代不了iptables,因为ipvs只能做负载均衡,而做不了nat转换
Endpoint(端点)
Endpoint 类似我们在之前所学习的 服务注册中心 (eureka、nacos)
Endpoint是kubernetes中的一个资源对象,存储在etcd中,用于记录一个service对应的所有pod的访问地址
一个Service由一组Pod组成,这些Pod通过Endpoints暴露出来,Endpoints是实现实际服务的端点集合。
通俗易懂总结:kubernetes 中的 Service与Endpoints通讯获取实际服务地址,在路由转发到具体pod上。
kubectl describe svc mayikt-clusterip -n mayikt-sit
kubectl get endpoints -n mayikt-sit -o wide
原理:
1.启动我们的pod集群(给每个pod打上标签nginx-pod);
2.创建我们service的时候 配置对应选择器selector标签 知道
service管理哪些pod集群;
NodePort
将我们的service端口映射到node节点上的一个端口,让后我们就可以通过 node节点ip:node节点端口访问接口。
kubectl delete -f mayikt-service03.yml
访问顺序:
1.通过工作节点的端口 访问到service端口
2.在通过service端口路由转发到pod端口
apiVersion: v1
kind: Service
metadata:
name: mayikt-service
namespace: mayikt-sit
spec:
selector:
app: nginx-pod
type: NodePort # service类型
ports:
- port: 80
nodePort: 30008 #指定绑定的node的端口(默认的取值范围是: 30000-32767), 如果不指定,会默认分配
targetPort: 80
kubectl create -f mayikt-service04.yml
kubectl get service mayikt-service -n mayikt-sit -o wide
外部访问:http://192.168.75.177:30008/
LoadBalance
在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到:NodePort,此模式只能在云服务器上使用。
例如 f5 dns 轮询解析
1.k8s部署springboot项目原理
2.使用k8s部署项目还需要nginx吗?
3.如何构建企业内部私有镜像仓库
4.实战基于K8S部署SpringBoot项目
5.什么ingress、ingress的原理
20点25分准时开始
Ingress
因为在pod多的时候,NodePort性能会急剧下降,如果你的k8s集群有成百上千的服务那岂不是要管理成百上千个NodePort
Ingress和我们之前提到的Service、Deployment也是一个k8s的资源类型,Ingress是用于实现用域名的方式访问k8s集群的内部应用,ingress受命名空间隔离。
搭建Ingress环境
1./usr/local/mayikt
2.mkdir mayikt-ingress-controller
3.cd mayikt-ingress-controller
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
如果无法下载 可以将这两个文件直接上传
📎mandatory.yaml📎service-nodeport.yaml
kubectl apply -f ./
(注意如果执行有报错:)
直接 kubectl delete ns ingress-nginx 即可
kubectl get pod -n ingress-nginx
执行
kubectl get svc -n ingress-nginx
31183_ 是为http协议端口
30396是为 https协议端口
环境准备
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-ingress.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mayikt-deployment
namespace: mayikt-sit
spec:
replicas: 3
selector:
matchLabels:
app: nx-pod
template:
metadata:
labels:
app: nx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.9
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-deployment
namespace: mayikt-sit
spec:
replicas: 3
selector:
matchLabels:
app: tc-pod
template:
metadata:
labels:
app: tc-pod
spec:
containers:
- name: tomcat
image: tomcat:9
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: mayikt-sit
spec:
selector:
app: nx-pod
clusterIP: None
type: ClusterIP
ports:
- port: 80
targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-service
namespace: mayikt-sit
spec:
selector:
app: tc-pod
clusterIP: None
type: ClusterIP
ports:
- port: 8080
targetPort: 8080
kubectl get svc -n mayikt-sit
配置http代理
https://kubernetes.io/zh/docs/concepts/services-networking/ingress-controllers/
kubectl create -f mayikt-ingress02.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-http
namespace: mayikt-sit
spec:
rules:
- host: nginx.mayikt.com
http:
paths:
- path: /
backend:
serviceName: nginx-service
servicePort: 80
- host: tomcat.mayikt.com
http:
paths:
- path: /
backend:
serviceName: tomcat-service
servicePort: 8080
kubectl describe ing ingress-http -n mayikt-sit
执行
kubectl get svc -n ingress-nginx
为了看了效果 在我们的电脑上 配置host文件
C:\Windows\System32\drivers\etc
192.168.75.177 nginx.mayikt.com
192.168.75.177 tomcat.mayikt.com
分别访问:
http://tomcat.mayikt.com:31183/
http://nginx.mayikt.com:31183/