kubernetes(六)—service详解(工作模式&类型)


文章目录

  • kubernetes(六)---service详解(工作模式&类型)
  • 1.service是什么?
  • 2.service的类型
  • 3.Service如何实现?
  • 4.集群内部访问pod
  • 5.ClusterIP方式创建service
  • 6.Headless Service无头服务
  • 7.IPVS模式的service
  • 8.Flannel vxlan跨主机通信原理


1.service是什么?

Service可以看作是一组提供相同服务的Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡。
service默认只支持4层负载均衡能力,没有7层功能。(可以通过Ingress实现)

2.service的类型

  • ClusterIP:默认值,k8s系统给service自动分配的虚拟IP,只能在集群内部访问。
  • NodePort:将Service通过指定的Node上的端口暴露给外部,访问任意一个NodeIP:nodePort都将路由到ClusterIP。
  • LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到 :NodePort,此模式只能在云服务器上使用。
  • ExternalName:将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定)。

3.Service如何实现?

Service 是由 kube-proxy 组件,加上 iptables 来共同实现的
==kube-proxy 通过 iptables 处理 Service 的过程,需要在宿主机上设置相当多的 iptables 规则,如果宿主机有大量的Pod,不断刷新iptables规则,会消耗大量的CPU资

IPVS模式的service,可以使K8s集群支持更多量级的Pod。

开启kube-proxy的ipvs模式:

yum install -y ipvsadm 			//所有节点安装

$ kubectl edit cm kube-proxy -n kube-system	//修改IPVS模式
mode: "ipvs"

$ kubectl get pod -n kube-system |grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}'		//更新kube-proxy pod

4.集群内部访问pod

vim deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: myapp:v1
        ports:
        - containerPort: 80

kubectl apply -f deployment.yaml 

kubectl get pod -o wide
kubectl get svc 
kubectl describe svc myservice

运行一个容器,访问后端的两个pod:

kubectl run test -it --image=busyboxplus
curl 10.244.3.12
curl 10.244.1.15

可以访问,这是因为在创建集群时就创建了一个覆盖型的网络
那么如果我们想要外部主机来访问pod呢?此时我们就可以通过创建service使外部主机访问

5.ClusterIP方式创建service

vim service.yaml
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector:
      app: nginx
  type: ClusterIP

kubectl apply -f service.yaml
kubectl get svc
kubectl describe svc web-service

目前该web-service还没有后端

创建两个后端的pod:
注意:标签必须和web-service的保持一致 app: nginx

\vi de.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-nginx
spec:
  replicas: 2
  selector:
    matchLabels:
        app: nginx
  template:
    metadata:
      labels: 
        app: nginx 
    spec: 
      containers: 
      - name: nginx 
        image: reg.westos.org/k8s/myapp:v1 
        ports: 
        - containerPort: 80 
kubectl apply -f de.yaml
kubectl get pod

此时我们的web-service有了两个后端:

kubectl describe svc web-service

连接并访问:

kubectl attch test -it
curl 10.101.22.15

pod间内部通过访问ClusterIP分配的虚拟VIP负载到了后端的两个pod容器
ClusterIP:通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的 ServiceType

6.Headless Service无头服务

Headless Service不需要分配一个VIP,而是直接以DNS记录的方式解析出被代理Pod的IP地址。
域名格式:(servicename).(servicename).(namespace).svc.cluster.local

\vi headless.yaml
apiVersion: v1 
kind: Service 
metadata: 
  name: nginx-svc 
spec: 
  ports: 
    - name: http 
      port: 80 
      targetPort: 80 
  selector: 
      app: nginx 
  clusterIP: None

kubectl apply -f headless.yaml
kubectl get svc
kubectl describe svc nginx-svc

以DNS记录的方式解析出被代理Pod的IP地址:
使用域名访问:

kubectl attch test -it
nslookup nginx-svc

通过这种方式实现访问,即使在后端pod滚动更新之后依然可以通过DNS进行解析

7.IPVS模式的service

iptables -t nat -nL | grep 10.101.22.15

我们可以看到这些策略,是在service创建时增加的

当pod创建的越来越多时,iptables的刷新频率就会越来越大,刷新策略会对cpu造成一定的压力,我们可以使用lvs来实现pod的负载均衡,直接使用linux内核

在所有节点安装ipvsadm(master+node):

yum install -y ipvsadm
ipvsadm -l	#没有任何策略
kubectl -n kube-system get cm
kubectl -n kube-system edit cm kube-proxy

更新kube-proxy pod:

kubectl get pod -n kube-system |grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}'
ipvsadm -ln

8.Flannel vxlan跨主机通信原理

kubenertes service 获取客户端真实IP kubernetes的service_Pod