什么是service?

service是pod的一个逻辑分组,是pod服务的对外入口抽象。service同样也通过pod的标签来选择pod,与控制器一致。
image.png
service提供pod的负载均衡的能力,但是只提供4层负载均衡的能力,而没有7层功能,只能到ip层面。

service的几种类型

ClusterIP

  • 默认类型,自动分配一个仅可在内部访问的虚拟IP。应用方式:内部服务访问 ```shell

    创建deployment nginx2个pod副本

    [root@k8s-master service]# pwd /root/service

[root@k8s-master service]# cat nginx-dep.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-dep spec: selector: matchLabels: app: nginx replicas: 2 template: metadata: labels: app: nginx spec: containers:

  1. - name: nginx
  2. image: daocloud.io/library/nginx:1.12.0-alpine
  3. ports:
  4. - containerPort: 80

[root@k8s-master service]# kubectl create -f nginx-dep.yaml

![image.png](https://cdn.nlark.com/yuque/0/2022/png/23214851/1654677929088-1d179838-f49b-43db-844d-ab774eaec9be.png#clientId=u7ef92b6f-f0ce-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=151&id=ufad0094b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=189&originWidth=840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=66645&status=done&style=none&taskId=u74bfbaa4-a5c3-42d0-bf70-6b1f92ab6db&title=&width=672)
```shell
# 创建一个ClusterIP类型的Service
[root@k8s-master service]# cat nginx-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc-clusterip
spec:
  type: ClusterIP
  selector:
    # 选择app=nginx标签的pod
    app: nginx
  ports:
    - protocol: TCP
      # service对外提供的端口
      port: 80
      # 代理的容器的端口 
      targetPort: 80
[root@k8s-master service]# kubectl create -f nginx-svc.yaml

image.png

测试ClusterIP

# 创建1个带有curl命令的pod
[root@k8s-master service]# cat centos.yaml 
---
apiVersion: v1
kind: Pod
metadata:
 name: website
 labels:
  app: website
spec:
  containers:
   - name: test-website
     image: daocloud.io/library/nginx
     ports:
       - containerPort: 80
[root@k8s-master service]# kubectl create -f centos.yaml

image.png
进入到第一个nginx的pod中,修改默认页面。与另外一个不同即可;为了看效果而已;

[root@k8s-master service]# kubectl exec -it nginx-dep-86df8bbd5-65ldp /bin/sh
# cd /usr/share/nginx/html/
/usr/share/nginx/html # echo "hello1" > index.html

image.png
进入到带有curl命令的pod中。用curl访问ClusterIP的80端口;

[root@k8s-master service]# kubectl exec -it website /bin/bash

image.png这是第一个pod页面
image.png这是第二个pod页面;

NodePort

  • 在ClusterIP的基础之上,为集群内的每台物理机绑定一个端口,外网通过任意节点的物理机IP:端口来访问服务。应用方式:外服访问服务

    [root@k8s-master service]# cat nginx-nodeport-svc.yaml
    apiVersion: v1
    kind: Service
    metadata:
    name: service-nodeport
    spec:
    type: NodePort
    selector:
      app: nginx
    ports:
      - protocol: TCP
        # service对外提供的端口
        port: 80
        # 代理的容器的端口 
        targetPort: 80
        # 在物理机上开辟的端口,从30000开始
        nodePort: 32138
    [root@k8s-master service]# kubectl create -f nginx-nodeport-svc.yaml
    

    测试NodePort

    image.png
    清下缓存,继续访问另外一个node
    image.png

    LoadBalance

  • 在NodePort基础之上,提供外部负载均衡器与外网统一IP,此IP可以将请求转发到对应服务上。这个是各个云厂商提供的服务。应用方式:外服访问服务

    apiVersion: v1
    kind: Service
    metadata:
    name: loadbalance-test
    spec:
    ports:
    - name: loadbalance-port
      #service对外提供的端口
      port: 80
      # 代理的容器的端口 
      targetPort: 80
      # 在物理机上开辟的端口,从30000开始
      nodePort: 32138
    selector:
      app: nginx
    type: LoadBalancer
    status:
    loadBalancer:
      ingress:
      - ip:  云厂商LoadbalanceIP
    
    [root@ master ~]# kubectl get  svc -n test
    NAME                TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
    loadbalance-test    LoadBalancer   172.21.10.152   LoadbalanceIP 80:32138/TCP   4m
    

    ExternalName

  • 引入集群外部的服务,可以在集群内部通过别名方式访问(通过 serviceName.namespaceName.svc.cluster.local访问)

    [root@k8s-master service]# cat nginx-externalName.yaml 
    apiVersion: v1
    kind: Service
    metadata:
    name: service-ext
    spec:
    type: ExternalName
    # 引入外部服务
    externalName: baidu.com
    

    image.png
    任意找个pod来访问服务,通过kubectl exec -it podname sh 来对pod执行sh命令,这样可以进入容器内部
    image.png

    [root@k8s-master service]# kubectl exec -it nginx-dep-86df8bbd5-65ldp /bin/sh
    

    image.png
    image.png
    所以ExternalName也就是给另外一个网站的域名,起了一个内部使用的别名而已;

ingress是干嘛的?

service只能提供4层负载均衡的能力,虽然service可以通过NodePort的方式来服务,但是随着服务的增多,会在物理机上开辟太多端口,管理起来混乱。
那么我们换一种思路来暴露服务,创建一个具有N个副本的nginx服务,在nginx服务内配置各个服务的域名与集群内部的服务的IP,这些nginx服务再通过NodePort的方式来暴露。外部服务通过域名:Nginx NodePort端口来访问nginx,nginx再通过域名反向代理到真实服务。
上面的这个流程就是ingress做的事,ingress分为ingress controller与ingress配置。ingress controller是反向代理服务器,对外通过NodePort(或者其他方式)来暴露,ingress配置是抽象出来的域名代理配置。

上面我们提到有一个叫作 LoadBalancer 类型的 Service,它会为你在 Cloud Provider(比如:Google Cloud 或者 OpenStack)里创建一个与该 Service 对应的负载均衡服务。但是,相信你也应该能感受到,由于每个 Service 都要有一个负载均衡服务,所以这个做法实际上既浪费成本又高。作为用户,我其实更希望看到 Kubernetes 为我内置一个全局的负载均衡器。然后,通过我访问的 URL,把请求转发给不同的后端 Service。这种全局的、为了代理不同后端 Service 而设置的负载均衡服务,就是 Kubernetes 里的 Ingress 服务。
Ingress 的功能其实很容易理解:所谓 Ingress 就是 Service 的“Service”,这就是它们两者的关系。
internet | [ Ingress ] —|——-|— [ Services ]
通过使用 Kubernetes 的 Ingress 来创建一个统一的负载均衡器,从而实现当用户访问不同的域名时,访问后端不同的服务
image.png
image.png
Ingress 负载均衡
可以将 Ingress 配置为服务提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及提供基于名称的虚拟主机等能力。 Ingress 控制器 通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。
你必须具有 Ingress 控制器 才能满足 Ingress 的要求。 仅创建 Ingress 资源本身没有任何效果。你可能需要部署 Ingress 控制器,例如 ingress-nginx。 你可以从许多 Ingress 控制器 中进行选择。
假如我现在有这样一个站点:https://cafe.example.com。其中 https://cafe.example.com/coffee,对应的是“咖啡点餐系统”。而 https://cafe.example.com/tea,对应的则是“茶水点餐系统”。这两个系统,分别由名叫 coffee 和 tea 这样两个 Deployment 来提供服务,可以看到这是一种经典的扇出(fanout)行为。

参考原文章:https://www.jianshu.com/p/06a3153021ca