searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Kubernetes之深入掌握 Service

2024-06-24 09:35:41
2
0

深入掌握 Service

spec.type Service 的类型, 指定 Service 的访问方式, 默认值为 ClusterIP:

  • ClusterIP: 虚拟的服务 IP 地址. 该地址用于 Kubernetes 集群内部的 Pod 访问, 在 Node 上 kube-proxy 通过设置的 iptables 规则进行转发
  • NodePort: 使用宿主机的端口. 使得能够访问各 Node 的外部客户端通过 Node 的 IP 地址和端口号就能访问服务
  • LoadBalancer: 使用外部负载均衡器完成到服务的负载分发, 需要在 spec.status.loadBalancer 字段指定外部负载均衡器的 IP 地址, 并同时定义 nodePort 和 clusterIP, 用于公有云环境

可以通过 kubectl expose 命令来创建 Service: $ kubectl expose <pod/svc/rc/deploy/rs> <对应控制器的name>

可以使用 yaml 文件来声明 Service:

apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  ports:
  - port: 8081
    targetPort: 8080
  selector:
    app: webapp

port 定义了 Service 自己的端口号

targetPort 定义了Pod提供服务的端口号

目前 Kubernetes 提供了两种负载分发策略:

  • RoundRobin: 轮询模式
  • SessionAffinity: 基于客户端 IP 地址进行会话保持的模式, 之后从相同的客户端发起的请求都将被转发到相同的 Pod 上

默认使用 RoundRobin

多端口服务

Service 支持设置将多个端口对应到多个应用服务

外部服务 Service

在某些环境中, 应用系统需要将一个外部数据库作为后端服务进行连接, 或将另一个集群或 namespace 中的服务作为服务的后端

这时可以通过创建一个 Label Selector 的 Service 来实现

 

apiVersion: v1
kind: Service
metadata:
  name: external-service
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

 

由于没有 Label Selector, 所以无法选择后端的 Pod, 所以系统不会自动创建 Endpoint

因此需要手动创建一个和该 Service 同名的 Endpoint, 用于指向实际的后端访问地址:

 

apiVersion: v1
kind: Endpoints
metadata:
  name: external-service
subsets:
- addresss:
  - ip: 1.2.3.4
  ports:
  - port: 80

 

Headless Service

如果希望自己控制负载均衡的策略, 或者应用程序希望知道属于同组服务的其他实例

Kubernetes 提供了 Headless Service 来实现这种功能, 即不为 Service 设置 ClusterIP (入口 IP 地址), 仅通过 Label Selector 将后端的 Pod 列表返回给调用的客户端:

 

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
  clusterIP: None # 重点!
  selector:
    app: nginx

 

这样, Service 就不具有一个特定的 ClusterIP 地址, 对其进行访问将获得包含 Label app: nginx 的全部 Pod 列表, 然后客户端程序自行决定如何处理这个 Pod 列表

从集群外部访问 Pod 或 Service

将容器应用的端口号映射到物理机

(1) 通过设置容器级别的 hostPort, 将容器应用的端口号映射到物理机上:

 

apiVersion: v1
kind: Pod
metadata:
  name: webapp
  labels:
    app: webapp
spec:
  containers:
  - name: webapp
    image: tomcat
    ports:
    - containerPort: 8080
      hostPort: 8081      # 重点!

 

将容器的 8080 端口映射到物理宿主机的 8081 端口

通过物理宿主机的 IP + 8081 即可访问到这个容器的 8080 端口

(2) 通过设置Pod级别的 spec.hostNetwork=true, 该 Pod 中所有容器的端口号都将被直接映射到物理宿主机上; hostPort 默认等于 containerPort

将 Service 的端口号映射到物理机

(1) 设置 nodePort 映射到物理机, 同时设置 Service 的类型为 NodePort:

 

apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: 8080
    nodePort: 8081    # 重点!
  selector:
    app: webapp

 

(2) 通过设置 LoadBalancer 映射到云服务提供商提供的 LoadBalancer 地址

这种用法仅用于在公有云服务提供商的云平台上设置 Service 的场景

DNS 服务搭建和配置指南

在集群内需要能够通过服务名服务进行访问, 通过一个集群范围内的 DNS 服务来完成从服务名 (Service name)到ClusterIP的解析

Ingress (HTTP 7 层 路由机制)

Service 的表现形式为 IP:Port, 即工作在 TCP/IP 层

对于基于 HTTP 的服务来说, 不同的 URL 地址经常对应到不同的后端服务 或者虚拟服务器

这些应用层的转发机制仅通过 Service 机制是无法实现的

使用 Ingress 资源对象, 可以将不同的 URL 的访问请求转发到后端不同的Service, 以实现 HTTP 层的业务路由机制

Kubernetes 使用了一个 Ingress 策略定义和一个具体的 Ingress Controller, 两者结合并实现了一个完整的 Ingress 负载均衡器

Ingress Controller 基于Ingress 规则将客户端请求直接转发到 Service 对应的后端 Endpoint (Pod) 上

这样会跳过 kube-proxy 的转发功能, kube-proxy 不再起作用

如果 Ingress Controller 提供的是对外服务, 则实际上实现的是边缘路由器的功能

要使用 Ingress, 需要创建 Ingress Controller (带一个默认 backend 服务) 和 Ingress 策略配置

创建 Ingress Controller 和默认的 backend 服务

在 Kubernetes 中, Ingress Controller 将以 Pod 的形式运行, 监控 API Server 的 /ingress 接口后端的 backend services, 如果 Service 发生变化, 则 Ingress Controller 应自动更新其转发规则

使用第三方提供的 nginx-ingress-controller image来创建 Ingress Controller. 该 Ingress Controller 以 daemonSet 的形式进行创建, 在每个 Node 上都将启动一个 Nginx 服务

为这个 Nginx 容器设置 hostPort, 将容器监听的 80 和 443 端口映射到物理机上

使得客户端可以通过 URL 地址 ://物理机IP:80 或者 ://物理机IP:443 来访问该 Ingress Controller

这使得 Nginx 类似于通过 NodePort 映射到物理机的 Service, 成为代替 kube-proxy 的 HTTP 层的 Load Balancer

Ingress 的策略配置技巧

  1. 转发到单个后端服务上
  2. 同一域名下, 不同的 URL 路径被转发到不同的服务上
  3. 不同的域名 (虚拟主机名) 被转发到不同的服务上
  4. 不使用域名的转发规则

Ingress 的 TLS 安全设置

可以为 Ingress 中的域名进行 TLS 安全证书的设置:

  1. 创建自签名的密钥和 SSL 证书文件
  2. 将证书保存到 Kubernetes 中的一个 Secret 资源对象中
  3. 将该 Secret 对象设置到 Ingress 中

使用 OpenSSL 工具生成密钥和证书文件

 

 

0条评论
0 / 1000
李****灏
3文章数
0粉丝数
李****灏
3 文章 | 0 粉丝