K8S的service类型

概述
• 防止Pod失联(服务发现)
• 定义一组Pod的访问策略(负载均衡)
•支持ClusterIP,NodePort以及LoadBalancer三种类型
• Service的底层实现主要有iptables和ipvs二种网络模式
如果要确保每次都将来自特定客户端的连接传递到同一Pod,可以通过设置service.spec.sessionAffinity为“ClientIP”(默认为“None”),根据客户端的IP地址选择会话关联。您还可以通过service.spec.sessionAffinityConfig.clientIP.timeoutSeconds适当设置来设置最大会话粘贴时间(默认值为10800,可达3小时)。

1. Pod与Service的关系

• 通过label-selector相关联
• 通过Service实现Pod的负载均衡( TCP/UDP 4层)
K8S的service类型_第1张图片

2. Service类型

(1)ClusterIP
分配一个内部集群IP地址,只能在集群内部访问(同Namespace内的Pod),默认ServiceType。 ClusterIP 模式的 Service 为你提供的,就是一个 Pod 的稳定的 IP 地址,即 VIP。
K8S的service类型_第2张图片

(2)NodePort
分配一个内部集群IP地址,并在每个节点上启用一个端口来暴露服务,可以在集群外部访问。 访问地址:: node端口范围30000-32067
Client→NodeIP:NodePort→ClusterIP:ServicePort→PodIP:containerPort
K8S的service类型_第3张图片

apiVersion: v1
kind: Service
metadata:
  name: nginx-2
  namespace: default
spec:
  type: NodePort
  selector:
    app: nginx
  sessionAffinity: ClientIP  #默认为None  开启以后有会话保持
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800
  ports:
  - name: http           
    protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30002
  - name: http        #如果pod的容器需要暴露多个端口可以制定多个端口并设定名字
    protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30002

(3)LoadBalancer:分配一个内部集群IP地址,并在每个节点上启用一个端口来暴露服务。 除此之外,Kubernetes会请求底层云平台上的负载均衡器,将每个Node([NodeIP]:[NodePort])作为后端添加进去
K8S的service类型_第4张图片

ClusterIP、NodePort、LoadBalancer每一个都是前者的加强版,也就意味着ClusterIP是最基础的,如果一个service没有IP,那么就叫Headless
Service(无头服务),可以直接解析到后端的PodIP,如果不是无头service那么解析的是ServiceIP

3. Service代理模式

K8S的service类型_第5张图片K8S的service类型_第6张图片

最早期userspace(已经被淘汰)kube-proxy作为代理转发,效率极低 优缺点 Iptables VS IPVS
Iptables:
• 灵活,功能强大
• 规则遍历匹配和更新,呈线性时延
• 可扩展性
IPVS:
• 工作在内核态,有更好的性能
• 调度算法丰富:rr,wrr,lc,wlc,ip hash…

4.自建service和endpoint(代理内部或者外部服务)

apiVersion: v1
kind: Service
metadata: 
  name: nginx               #没有标签选择的service
spec:
  ports:
    - protocol: TCP          #TCP
      port: 80                #service的端口是80`在这里插入代码片`
      targetPort: 9376      #目标端口是9376这里只是声明
apiVersion: v1
kind: Endpoints
metadata: 
  name: nginx 
subsets:
  - addresses:
      - ip: 192.168.74.200                   #后方转发的ip
    ports:
      - port: 666                          #后方转发的端口

这样子就是访问service他可以代理到192.168.74.200:666,
如果使用iptables就是iptables如果是ipvs那么就是ipvs4层转发,

5更改service代理模式的方法

(1)加入内核参数
modprobe – ip_vs
modprobe – ip_vs_rr
modprobe – ip_vs_wrr
modprobe – ip_vs_sh
modprobe – nf_conntrack_ipv4
(2)查看是否加入成功
lsmod|grep ip_vs
(3)修改proxy中的configmap
kubectl edit configmap kube-proxy -n kube-system
把mode: ""改为mode: “ipvs” 默认走iptables,想走ipvs只能自己修改
(4)改完并不是立即生效,需要重启proxy的pod,每个节点都会对应一个proxy可以先重启修改完毕的节点的proxy
kubectl get pod -n kube-system -o wide | grep proxy
#查看proxy对应的node节点或者master节点
kubectl delete pod -n kube-system kube-proxy-zqx2l
kubectl get pod -n kube-system -o wide | grep proxy
查看是否重启成功
(5)安装ipvxadm并查看是否修改成功
ipvsadm -L -n

6. DNS

DNS服务监视Kubernetes API,为每一个Service创建DNS记录用于域名解析。
ClusterIP A记录格式:..svc.cluster.local 示例:my-svc.my-namespace.svc.cluster.local

在容器中可以直接解析service,如果需要数据对接,之类的IP可能变动,但是service的名称不会变,所以通过service的名称访问,k8s也有dns解析支持
Nslookup service-nginx #service创建的时候名字叫service-nginx
如果需要跨命名空间的话需要在后面加命名空间,不然默认找当前命名空间下
Nslookuo service-nginx.default #service名称.命名空间
资源记录
SVC_NAME.NS_NAME.DOMAIN.LTD.
svc.cluster.local.
redis.default.svc.cluster.local.

小结

  1. 采用NodePort对外暴露应用,前面加一个LB实现统一访问入口
  2. 优先使用IPVS代理模式
  3. 集群内应用采用DNS名称访问

你可能感兴趣的:(kubernetes)