1. Service 相关概念

1.1 svc 服务的概念

svc 的是什么:

  • 将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。

  • Kubernetes 为 Pods 提供自己的 IP 地址,并为一组 Pod 提供相同的 DNS 名,也就是服务名, 并且可以在它们之间进行负载平衡。这就是服务

svc 的原理:

  • 逻辑上的一组 Pod, 称为微服务

  • 这组 Pod 能够通过 Service 访问到,通常是通过 标签选择器

  • svc 发现这组服务后,会根据负载均衡规则,将负载发给每一个 Pod

  • svc 本质就是一个 负载均衡器

  • svc 将负载转发给后端的 Pod ,是通过 kube-proxy 转发的

1.2 svc 服务的创建

  1. 通过命令行的形式创建 svc

    • 如果没有指明 svc 的名字,svc 的名字是控制器的名字

    • –selector 选项用来指明,该 svc 控制哪些 Pod 做负载均衡,如果没指定,则是根据控制器的 标签 来选择

    • 只要新启动的 Pod 的标签与 svc 管理 Pod 的标签相同,那么这个新建的 Pod 也会被该 svc 管理。

    • port 是暴露在 clusterIP 上的端口,供集群内部使用,targetPort 是容器内部的端口,nodePort 是暴露在 Node 节点上的端口,供外部访问 svc

    • 例如:kubectl expose deployment web1 --name=mysvc --target-port=80 --port=80

Copy to Clipboard
  1. 通过 yaml 文件的形式创建 svc

    • 模板为:

Copy to Clipboard

2. Service 服务发现

2.1 服务发现的分类

服务发现概念:

  • 当 kubentes 中的一个 Pod 要访问 另一个服务的时候,这时候就要用到服务发现。

  • 这个服务有可能是一个 Pod ,也可能是一组 Pod

  • 这个服务就需要 让 Pod 能够访问到,因此称为服务发现

服务发现的类型有

  • clusterIP

  • 环境变量

  • DNS(推荐)

2.2 ClusterIP

方法:

  • 在创建出服务后,默认的服务类型为 ClusterIP,可以通过 ClusterIP:Port 来访问对应的 svc 服务。

  • ClusterIP 方式的服务发现,可以跨 namespace 。

缺点

  • 服务需要先创建,才能查看 clsterIP

  • 服务如果重建,ip 会变化,那么后面需要访问该服务的所有 Pod 都需要改变 clsterIP

例如:

  1. 一组 nginx 的 deployment ,通过 svc 服务管理

Copy to Clipboard
  1. 新建一个 Pod ,镜像为 busybox ,在 Pod 中,通过 ClusterIP 来访问该服务

Copy to Clipboard
  1. 可以看到,可以通过 ClusterIP 来访问服务

2.3 环境变量

当 Pod 运行在 Node 上,kubelet 会为每个活跃的 Service 添加一组环境变量。

常用的 svc 的环境变量有:

  • {SVCNAME}_SERVICE_HOST : 表示服务的 ClusterIP

  • {SVCNAME}_SERVICE_PORT : 表示服务的 Port

缺点:

  • Pod 只能发现同一个命名空间里的服务

  • Pod 想要访问的任何 Service 必须在 Pod 自己之前被创建,否则这些环境变量就不会被赋值

例如:

  1. nginx 的服务为:

Copy to Clipboard
  1. 在同一个命名空间下,创建 busybox,来查看环境变量:

Copy to Clipboard

2.4 DNS(推荐)

原理

  • 在 kube-system 命名空间中,创建了coredns,可以自动发现所有命名空间中服务的 clusterIP

  • 只要创建了一个服务,不管该服务在哪个命名空间中创建的,都回自动向 kube-system 命名空间下的 coredns 注册

  • 因此,在同一个命名空间中,一个服务访问另一个服务的时候,可以直接通过服务名来访问

  • 如果是不同命名空间,一个服务访问另一个服务的时候,可以通过 服务名.命名空间名 来访问

例如:

  1. nginx 的 服务为:

Copy to Clipboard
  1. 在同一个命名空间下,创建 busybox pod,通过 服务名,来直接访问该服务:

Copy to Clipboard
  1. 在不同的命名空间下,创建 busybox pod,通过 服务名.命名空间名,来访问服务

    • 注意: nginx 的服务是在 gsh 命名空间中,而 新建的 busybox 是在 default 命名空间中

Copy to Clipboard

3. Service 服务发布

服务发布:对一些应用(如 Frontend)的某些部分,可能希望通过外部(Kubernetes 集群外部)IP 地址暴露 Service。

ServiceTypes 允许指定一个需要的类型的 Service,默认是 ClusterIP 类型。

ServiceTypes 服务发布的类型有:

  • ClusterIP通过集群的内部 IP 暴露服务

    • 选择该值,服务只能够在集群内部可以访问

    • ClusterIP 是默认的 ServiceType。

  • NodePort通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。

    • NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。

    • 通过请求 <NodeIP>:<NodePort>,可以从集群的外部访问一个 NodePort 服务。

  • LoadBalancer使用云提供商的负载均衡器,可以向外部暴露服务

    • 外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务。

  • ExternalName通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容(例如, foo.bar.example.com)

    • 没有任何类型代理被创建,这只有 Kubernetes 1.7 或更高版本的 kube-dns 才支持。

svc 服务发布的另一种形式:Ingress

  • Ingress 不是服务类型,但它充当集群的入口点。

  • Ingress 可以将路由规则整合到一个资源中,因为它可以在同一IP地址下公开多个服务。

3.1 ClusterIP 类型

ClusterIP 类型 只能是在集群内部访问,多用于服务发现。

3.2 NodePort 类型

NodePort 类型,是将 容器 暴露出的端口 targetPort 映射到 node (worker)节点上,名为 nodePort,是的可以通过 nodeIP:NodePort 来访问 服务。

Kubernetes 控制平面将在 –service-node-port-range 标志指定的范围内分配端口(默认值:30000-32767)

模板为:

Copy to Clipboard

注意:

  • targetPort : 容器需要暴露出来的端口

  • port : 表示用于集群内部使用的 端口,一般与 targetPort 相同

  • nodePort : 表示 容器端口映射到 node 节点的 端口,范围:30000-32767

3.3 LoadBalancer 类型

LoadBalancer 类型,需要从运行商获取到公网地址,也就是暴露在互联网上 ip 地址,这样才能够为外部访问,通过将 svc 绑定一个公网 ip,用户就可以通过这个公网 ip 来直接访问服务。

LoadBalancer 类型需要借助第三方工具来实现,可以通过 MetalLB 这个工具实现,官网地址为:https://metallb.universe.tf/

安装方法:

  • 创建命名空间:

    • kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/namespace.yaml

  • 创建 secret

    • kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"

  • 创建 MetalLB 的相关 Pod

    • kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yaml

配置使用方法:

  • 创建 地址池 的 yaml 文件:(简单示例,使用 Layer 2 Configuration)

Copy to Clipboard
  • 创建 svc 类型为 loadbalancer

    • kubectl expose deployment web1 --name=mysvc --type=LoadBalancer --port=80

    • 创建 loadBalancer 类型的 svc 后,可以看到 该 svc 服务与一个地址池中的公网 ip 绑定

    • 并且可以直接通过 公网 ip 来直接访问 服务

Copy to Clipboard

3.4 Ingress 类型(推荐)

3.4.1 Ingress 概念

Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。

Ingress 相当于一个 nginx 反向代理,通过不同的 path 指定到不同的 pod 上。

Copy to Clipboard

注意:

  • 可以将 Ingress 配置为服务提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及提供基于名称的虚拟主机等能力。

  • Ingress 控制器 通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。

  • Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的服务。

3.4.2 安装方法

Ingress 的安装方法:

  • 安装 ingress-nginx controller 用来做代理

    • wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml -O ingress-nginx.yaml

    • kubectl apply -f ingress-nginx.yaml

  • 在 ingress-nginx 命名空间中,创建 deployment 的服务 svc ,将 deployment 暴露出去,这样外部才可以通过这个代理访问服务

    • kubectl expose -n ingress-nginx deployment nginx-ingress-controller --name=ingress --port=80 --type=NodePort

3.4.3 使用教程

ingress 其实就是个路由器,通过不同的 网址站点以及 path 转发给不同的 service

ingress 通过 yaml 文件创建,模板为:

Copy to Clipboard

说明:

  • host : 可选的,

    • 如果未指定 host,表示通过指定 IP 地址的所有入站 HTTP 通信。 如果提供了 host,则 rules 适用于该 host。

  • paths : 路径列表

    • 例如,/testpath, 每个路径都有一个由 serviceName 和 servicePort 定义的关联后端。

    • 在负载均衡器将流量定向到引用的服务之前,主机和路径都必须匹配传入请求的内容。

  • backend : 后端

    • 服务和端口名称的组合。 与规则的 host 和 path 匹配的对 Ingress 的 HTTP(和 HTTPS )请求将发送到列出的 backend。

    • backend 也就是对应的 service

  • pathType : 路径类型

    • ImplementationSpecific : 匹配方法取决于 IngressClass。 具体实现可以将其作为单独的 pathType 处理或者与 Prefix 或 Exact 类型作相同处理。

    • Exact : 精确匹配 URL 路径,且区分大小写。

    • Prefix : 基于以 / 分隔的 URL 路径前缀匹配。区分大小写,并且对路径中的元素逐个完成。

示例:

  1. 创建 nginx pod 和 服务svc:

Copy to Clipboard
  1. 可以看到,通过不同的服务,可以访问不同的 内容

Copy to Clipboard
  1. 创建 ingress yaml 文件

Copy to Clipboard
  1. 创建 ingress,并且测试正确性, 通过 ingress-nginx 创建的 svc 来访问不同的 path

    • 查看 ingress-nginx 创建的 svc 的 端口

    • 在 /etc/hosts 中添加 dns 映射

    • 通过 域名:端口 访问不同的 svc

Copy to Clipboard