欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

k8s service

程序员文章站 2022-03-12 11:49:55
...

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


k8s service

提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

定义

service是一种将运行在一组pod上的应用暴露为网络服务的抽象方法,定义了一组逻辑的pod以及一种访问他们的策略,是客户端和后端pod之间的一个抽象层。

作用

  1. 提供稳定的ip地址和端口
    pod作为一种非持久化,动态的资源,会经常随着集群状态销毁或新增,因此pod的ip也是会变动,导致客户端 发现后端应用比较困难,因此k8s设计了一个抽象层,用来屏蔽后端pod的变化。
  2. 可以为其匹配的后端pod提供负载均衡
    工作在四层,提供四层负载均衡功能,支持三种协议TCP,UDP,SCTP

类型

ClusterIp

Cluster IP是默认类型,自动分配集群内部可以访问的虚IP——Cluster IP。Cluster IP的主要作用是方便集群内Pod到Pod之间的调用。集群外部的客户端无法通过Cluster IP访问Service。
Cluster IP主要在每个node节点使用iptables,将发向Cluster IP对应端口的数据转发到后端Pod中

yaml声明

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

其中:
port:表示service暴露的服务端口,也是客户端访问用的端口
targetPort:是后端应用程序实际监听pod内流量的端口,从port上到来的数据,最终会进过kube-proxy流入后端pod的targetPort进入容器。

LoadBalancer

Load Balancer(简称LB)类型的Service需要Cloud Provider的支持。Kubernetes原生支持的Cloud Provider有GCE和AWS,因此和不同云平台的网络方案耦合较大,而且只能在特定的云平台上使用,局限性也较大。
如果要在集群内访问Load Balancer类型的Service,则Kube-proxy用iptables或ipvs实现云服务提供商Load Balancer(一般都是L7的)的部分功能:L4转发、安全组规则等。
yaml声明

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  clusterIP: 10.0.171.239
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 192.0.2.127

NodePort

NodePort为Service在Kubernetes集群的每个节点上分配一个真实的端口,即NodePort。集群内/外部可基于集群内任何一个节点的IP:NodePort的形式访问Service。
NodePort支持TCP、UDP、SCTP,默认端口范围是30000-32767,Kubernetes在创建NodePort类型Service对象时会随机选取一个。用户也可以在Service的spec.ports.nodePort中自己指定一个NodePort端口,就像指定Cluster IP那样。

yaml声明

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  selector:
    app: MyApp
  ports:
      # By default and for convenience, the `targetPort` is set to the same value as the `port` field.
    - port: 80
      targetPort: 80
      # Optional field
      # By default and for convenience, the Kubernetes control plane will allocate a port from a range (default: 30000-32767)
      nodePort: 30007

其中:
通常默认情况port和targetPort指定同一端口号。

NodePort的实现机制是Kube-proxy会创建一个iptables规则,所有访问本地NodePort的网络包都会被直接转发至后端Port。
NodePort是解决服务对外暴露的最简单方法,对于那些没有打通容器网络和主机网络的用户,NodePort成了他们从外部访问Service的首选。但NodePort的问题集中体现在性能和可对宿主机端口占用方面。一旦服务多起来,NodePort在每个节点上开启的端口会变得非常庞大且难以维护

headless service

headless service是一种特殊的服务,其yaml声明中.spec.clusterIP指定为none,不会分配clusterip。
特点:

  1. 可以自定义服务发现接口,选择不绑定k8s平台的服务发现机制
  2. 由于没有clusterip,kube-proxy不会操作这些service,没有负载均衡和代理的功能
  3. 访问服务时,会返回所有关联后端pod ip(service指定了selector),可以自定义负载均衡策略
apiVersion: v1
kind: Service
metadata:
  name: mysql-balance-svc
  namespace: mysql-space
  labels:
    name: mysql-balance-svc
spec:
  ports:
  - port: 3308
    protocol: TCP
    targetPort: 3306
  clusterIP: None
  selector:
    name: mysql-balance-pod

服务发现

k8s提供两种主要的服务发现方法:

  1. 环境变量
  2. dns

环境变量

Kubelet创建每个Pod时,会把系统当前所有服务的IP和端口信息都通过环境变量的方式注入容器。这样Pod中的应用可以通过读取环境变量获取所需服务的地址信息。
缺点:

  1. 容易环境变量洪泛,Docker启动参数过长会影响性能,甚至直接导致容器启动失败
  2. Pod想要访问的任何Service必须在Pod自己被创建之前创建,否则这些环境变量就不会被注入

dns

k8s通过dns服务记录集群中发布服务的域名,即假设Service(my-svc)在namespace(my-ns)中,暴露名为http的TCP端口,那么在Kubernetes的DNS服务器中会生成两种记录,分别是A记录:域名(my-svc.my-ns)到Cluster IP的映射和SRV记录,例如_http._tcp.my-svc.my-ns到一个http端口号的映射。这样应用能够直接使用服务的名字,不需要关心它实际的IP地址,中间的转换能够自动完成。名字和IP之间的转换通过DNS。

如何访问服务

集群内

可以直接是用ClusterIP:Port的方式访问服务,也可以使用域名+端口的方式访问

集群外

前面提到的LoadBlancer和NodePort方式都可以为集群外的客户端提供访问。k8s还提供一种方式:Ingress

Kubernetes的Ingress资源对象是指授权入站连接到达集群内服务的规则集合。Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。
通常情况下,Service和Pod仅可在集群内部网络中通过IP地址访问。所有到达边界路由的流量或被丢弃或被转发到其他地方。
Ingress的作用就是在边界路由处开个口子,放外部流量进来。因此,Ingress是建立在Service之上的L7访问入口,它支持通过URL的方式将Service暴露到k8s集群外;支持自定义Service的访问策略;提供按域名访问的虚拟主机功能;支持TLS通信。
定义ingress资源

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /testpath
        pathType: Prefix
        backend:
          service:
            name: test
            port:
              number: 80

其中:
Ingress 对象的命名必须是合法的 DNS 子域名名称;
Ingress 规则 提供了配置负载均衡器或者代理服务器所需的所有信息。 最重要的是,其中包含与所有传入请求匹配的规则列表。 Ingress 资源仅支持用于转发 HTTP 流量的规则。