引言

Kubernetes服务是应用程序的抽象层,为在集群中运行的多个Pod提供了通信机制。本文将深入探讨在Kubernetes中创建服务、连接外部服务,以及如何将服务暴露给外部客户端的关键概念。

1. 创建Kubernetes服务

1.1. 服务类型

Kubernetes支持不同类型的服务,包括ClusterIP、NodePort、LoadBalancer和ExternalName。每种类型服务都有其独特的用途和行为。

apiVersion: v1
kind: Service
metadata:
  name: example-service
spec:
  selector:
    app: example-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: ClusterIP
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

在这个示例中,example-service 是一个 ClusterIP 类型的服务。它通过选择器将流量路由到带有 app: example-app 标签的 Pod。这个服务只能在 Kubernetes 集群内部使用,其他外部系统无法直接访问它。

1.2. 选择器和端口定义

  • selector字段定义服务关联的Pod的标签选择器。
  • ports字段定义服务的端口映射,包括协议、服务端口和Pod端口。
apiVersion: v1
kind: Service
metadata:
  name: my-service  # 服务的名称
spec:
  selector:
    app: my-app  # 标签选择器,关联的Pod需要包含这个标签
  ports:
    - protocol: TCP  # 使用的协议,可以是TCP或UDP
      port: 80       # 服务端口,外部访问的端口
      targetPort: 8080  # Pod端口,服务将流量转发到Pod的这个端口
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

在上述示例中,selector字段定义了一个标签选择器,要求关联的Pod必须包含标签app: my-app。而ports字段定义了服务的端口映射,包括协议(TCP)、服务端口(80)和Pod端口(8080)。

2. 连接内部和外部服务

2.1. 服务发现

Kubernetes通过DNS服务发现机制允许在集群内部轻松访问服务。服务名称将被解析为关联Pod的ClusterIP。

$nslookup example-service
  • 1.

2.2. ClusterIP服务

ClusterIP服务仅在集群内部可用,适用于服务间通信。通过服务名和端口访问:

$curl http://example-service:80
  • 1.

2.3. NodePort服务

NodePort服务通过在每个节点上开放一个端口,将服务暴露到集群外部。这样,可以通过节点的IP和NodePort访问服务。

apiVersion: v1
kind: Service
metadata:
  name: example-nodeport-service
spec:
  selector:
    app: example-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: NodePort
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

在这个示例中,example-nodeport-service 是一个 NodePort 类型的服务。它通过选择器将流量路由到带有 app: example-app 标签的 Pod。此服务在集群内部分配一个随机端口,并且可以通过任何节点的 IP 地址和此端口从外部访问。

2.4. LoadBalancer服务

LoadBalancer服务通过云提供商的负载均衡器将服务暴露给外部。适用于需要外部访问和负载均衡的场景。

apiVersion: v1
kind: Service
metadata:
  name: example-lb-service
spec:
  selector:
    app: example-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: LoadBalancer
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

在这个示例中,example-lb-service 是一个 LoadBalancer 类型的服务。根据你的云提供商,Kubernetes 将与云提供商的负载均衡器集成,并分配一个外部 IP 地址。流量将通过该 IP 地址路由到带有 app: example-app 标签的 Pod。这是一种用于公开服务的常见方式,特别是在生产环境中。

2.5. Ingress资源

Ingress是用于管理外部访问的Kubernetes资源。它定义了规则,将HTTP和HTTPS路由到服务。

HTTP Ingress 示例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-http-ingress
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-http-service
            port:
              number: 80
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

上述示例中,rules字段定义了Ingress规则。这个Ingress规则指定了当请求的主机是myapp.example.com且路径为/时,将流量路由到名为my-http-service的Service的端口80

HTTPS Ingress 示例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-https-ingress
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-https-service
            port:
              number: 443
  tls:
  - hosts:
    - myapp.example.com
    secretName: my-tls-secret
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.

在上述HTTPS的Ingress示例中,tls字段被添加用于配置HTTPS。hosts字段指定了Ingress规则适用的主机,而secretName字段指定了存储TLS证书和密钥的Secret的名称(my-tls-secret)。这个Secret包含了用于加密通信的TLS证书和密钥。

结论

Kubernetes服务是构建分布式应用程序的核心组件之一。通过选择适当的服务类型,并使用NodePort、LoadBalancer和Ingress等机制,可以在集群内外实现灵活的服务连接和访问。深入理解这些概念将有助于构建高度可用、可伸缩且对内外部可见的应用程序。在实践中,根据需求选择合适的服务类型,并合理配置服务发现和网络策略,将有助于确保Kubernetes集群的顺畅运行。