Kubernetes 服务概述

Kubernetes 服务概述

了解不同类型的 Kubernetes 服务和 Ingress 控制器

在 Kubernetes 环境中,您可以拥有数百个甚至数千个临时 Pod。无论是因为节点缩减、pod 副本缩减,还是 pod 被重新调度到新节点,pod 的 IP 地址永远无法保证相同。

Pod 的 IP 地址是在它被调度到特定节点之后并且在它被引导之前分配的。鉴于我们处于云原生环境中,我们希望能够水平扩展 pod。因此,跟踪我们所有应用程序的所有 IP 地址将是一项非常困难的任务。

Kubernetes 有一种资源类型可以解决这个不断变化的 pod IP 的问题,称为服务。

Kubernetes 服务允许您创建一个单一的常量 IP 地址,其中包含一组包含相同服务的 Pod 的 IP 地址。这非常有用,因为服务 IP 保持静态,而 Pod 的 IP 可以不断变化。您永远不必担心没有正确的 IP 地址。

服务如何运作

要想了解服务如何运作?首先配置一个service开始。

让我们首先创建一个包含三个 nginx pod 实例的部署。

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx

应用部署清单后,我们可以看到我们有三个使用 IP 运行的 nginx 实例10.244.242.66, 10.244.242.67, 10.244.230,199。另外,请注意我们为这些 pod 分配的标签,app=nginx这对于服务如何监控这些 pod 至关重要。

~ kubectl get pods -owide - show-labels
NAME READY STATUS RESTARTS AGE IP NODE LABELS
nginx-8f458dc5b-6vcxt 1/1 Running 0 2m27s 10.244.242.66 nodepool-a-95e9c8e86208 app=nginx,pod-template-hash=8f458dc5b
nginx-8f458dc5b-ktvtf 1/1 Running 0 2m27s 10.244.242.67 nodepool-a-95e9c8e86208 app=nginx,pod-template-hash=8f458dc5b
nginx-8f458dc5b-mlkwd 1/1 Running 0 2m27s 10.244.230.199 nodepool-a-11aa1dc199fa app=nginx,pod-template-hash=8f458dc5b

现在,让我们定义我们的服务清单,它在下面定义,并对定义的内容进行细分。

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  selector:
    app: nginx
  type: ClusterIP
  ports:
  - name: 80-80
    port: 80
    protocol: TCP
    targetPort: 80

当我们开始分解这个清单时,我们注意到类型是Service. 接下来,元数据部分应该很熟悉,因为它与其他 Kubernetes 资源上的元数据字段相同。规范部分是我们定义我们的服务将如何交互以及与之交互的地方。字段selector 您可以在该字段中定义希望该服务监控哪些 pod。这是通过标签匹配完成的。

你会注意到这selector有一个定义app: nginx。如果您还记得这些是我们在部署清单中为我们的 pod 定义的标签。通过这个选择器定义,我们声明任何带有标签的 pod 都app=nginx将成为该服务的一部分。

接下来,我们有type字段。这定义了我们将成为该服务的一部分希望它成为什么样的服务。稍后我们将更深入地研究服务类型,但现在我们将其定义为ClusterIP.

最后,我们有ports字段。在这里,我们定义流量将如何以及在何处流经服务。请注意,此字段接受一个数组,因此您可以定义多个条目。让我们细分端口中的每个字段:

现在我们对服务清单的作用以及它如何与 pod 交互有了基本的了解,我们部署清单并检查服务。

 ~  kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1               443/TCP   90m
nginx        ClusterIP   10.108.176.62           80/TCP    18m

☁  ~  kubectl describe svc nginx
Name:              nginx
Namespace:         default
Labels:            app=nginx
Annotations:       
Selector:          app=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.108.176.62
IPs:               10.108.176.62
Port:              80-80  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.230.199:80,10.244.242.66:80,10.244.242.67:80
Session Affinity:  None
Events:            

describe 命令中的所有内容都应与清单定义一致,除了两个字段“IP”和“Endpoints”。

该IP字段定义服务 IP 地址。这是可用于访问服务后面的 pod 的静态 IP。

该Endpoints字段定义当前分配给此服务的 pod IP。您注意到这些 IP 是来自我们的 nginx 部署的 IP。

在我们继续其他服务类型之前,让我们展示缩减 nginx 部署并查看该服务将如何处理此更改。

 kubectl scale deployment/nginx --replicas 1
deployment.apps/nginx scaled

☁  kubectl get pods -owide
NAME                    READY   STATUS    RESTARTS   AGE   IP               NODE                      NOMINATED NODE   READINESS GATES
nginx-8f458dc5b-mlkwd   1/1     Running   0          43m   10.244.230.199   nodepool-a-11aa1dc199fa              

☁  kubectl describe service nginx | grep Endpoints  
Endpoints:         10.244.230.199:80

☁  kubectl scale deployment/nginx --replicas 5
deployment.apps/nginx scaled

☁  kubectl get pods -owide
NAME                    READY   STATUS    RESTARTS   AGE    IP               NODE                      NOMINATED NODE   READINESS GATES
nginx-8f458dc5b-9pmhb   1/1     Running   0          108s   10.244.242.69    nodepool-a-95e9c8e86208              
nginx-8f458dc5b-mlkwd   1/1     Running   0          47m    10.244.230.199   nodepool-a-11aa1dc199fa              
nginx-8f458dc5b-r2pcp   1/1     Running   0          108s   10.244.242.70    nodepool-a-95e9c8e86208              
nginx-8f458dc5b-vgwv6   1/1     Running   0          108s   10.244.242.68    nodepool-a-95e9c8e86208              
nginx-8f458dc5b-x6thl   1/1     Running   0          108s   10.244.230.200   nodepool-a-11aa1dc199fa              

☁  kubectl describe service nginx | grep Endpoints
Endpoints:         10.244.230.199:80,10.244.230.200:80,10.244.242.68:80 + 2 more...

您可以看到向上和向下扩展 pod 会立即反映在允许单个静态 IP 访问 pod 的服务中。

服务种类

在服务资源中,存在三种不同的类型。它们如下:

  1. 集群IP
  2. 节点端口
  3. 负载均衡器

这些都有自己的行为和特定的用例,因此知道何时使用它们很重要。在接下来的部分中,我们将对其中的每一个进行更深入的探讨。

集群IP

ClusterIP 是最“基本”的服务类型。它将创建一个静态 IP 地址,该地址位于与 pod IP 范围不同的子网上,并将通过标签选择器监视一组 pod。

ClusterIP 允许 pod 轻松地相互通信,因为 pod 可以将请求发送到静态 IP 或使用 Kubernetes DNS 将请求发送到{service-name}.{namespace}. 在前面的示例中,我们部署的 DNS 应该是nginx.default. 使用 ClusterIP 有一些限制。最大的一个是没有办法向外界公开这项服务。这是服务类型nodePort和loadBalancer应该使用的地方。

节点端口

该NodePort服务建立在类型之上ClusterIP。它ClusterIP通过在工作节​点上打开一个端口来转发流量来向外界公开。这意味着,如果您有 50 个工作节点,即使 pod 不在该工作节点上,每个工作节点也会侦听分配的端口。

要创建NodePort服务,唯一的区别是定义Type为NodePort.

kind: Service
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  ports:
  - name: 80-80
    port: 80
    protocol: TCP
    targetPort: 80
    # nodePort: 30001
  selector:
    app: nginx
  type: NodePort

您可能会注意到 被nodePort注释掉了,这是因为如果您没有nodePort在该ports部分中定义,Kubernetes 会自动从 range 中分配一个随机端口30000–32767。如果你想定义一个特定的端口,它必须从这个范围内完成。部署 NodePort 服务清单并让我们检查它。

  kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1               443/TCP        135m
nginx        NodePort    10.98.246.253           80:30828/TCP   5s

☁  kubectl describe svc nginx
Name:                     nginx
Namespace:                default
Labels:                   app=nginx
Annotations:              
Selector:                 app=nginx
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.98.246.253
IPs:                      10.98.246.253
Port:                     80-80  80/TCP
TargetPort:               80/TCP
NodePort:                 80-80  30828/TCP
Endpoints:                10.244.230.199:80,10.244.230.200:80,10.244.242.68:80 + 2 more...
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   

在这里,我们看到一个名为的新字段NodePort,其值为30828/TCP。这是分配给该服务的端口和协议。现在,如果我们要向具有该端口的任何工作节点 IP 地址发送请求,请求将被发送到服务,然后服务被发送到我们的 pod。

☁  kubectl get nodes -owide
NAME                      STATUS   ROLES    AGE    VERSION   INTERNAL-IP   EXTERNAL-IP     OS-IMAGE                       KERNEL-VERSION    CONTAINER-RUNTIME
nodepool-a-11aa1dc199fa   Ready       140m   v1.24.4   10.1.96.5     45.77.152.173   Debian GNU/Linux 10 (buster)   4.19.0-22-amd64   containerd://1.6.8
nodepool-a-95e9c8e86208   Ready       140m   v1.24.4   10.1.96.4     140.82.44.105   Debian GNU/Linux 10 (buster)   4.19.0-22-amd64   containerd://1.6.8
☁  curl 140.82.44.105:30828



Welcome to nginx!

☁  curl 45.77.152.173:30828



Welcome to nginx!

虽然这是向外界公开我们的服务的一种有用方式,但它的扩展性并不好。在高度自动扩展的 Kubernetes 集群中,工作节点可能是短暂的,因为它们可能会不断地上下旋转。这给我们留下了一个与 pod 类似的问题,我们可以在 pod 中找到 IP 是什么,但这并不意味着它们将永远存在。如果您的服务需要静态外部 IP 地址,则LoadBalancer服务类型将满足该需求。

负载均衡器

NodePort与构建于 之上的方式类似ClusterIP,该LoadBalancer服务构建于 之上NodePort。通过该LoadBalancer服务,每个工作节点继续拥有分配给特定服务的唯一端口。但是,现在部署了 L4 并将其配置为路由到特定的工作节点和端口。高级请求流程如下:一个请求被发送到负载均衡器,它被转发到特定的工作节点nodeport,然后被传递到特定的服务,最后被发送到一个 pod。注意:部署的负载均衡器取决于您运行 Kubernetes 的云提供商。

如果需要,配置LoadBalancer服务会涉及更多。一个非常简单的配置可以如下所示,只需将type字段更改为LoadBalancer.

apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  ports:
  - name: 80-80
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  type: LoadBalancer

例如,如果您希望更改您的负载均衡器以强制 SSL 重定向、配置防火墙规则、使用 HTTPS 而不是 HTTP,或者使用不同的平衡算法,那么这将需要在您的服务上进行定义Annotations。这是一个LoadBalancer使用 Vultrs Load Balancer 集成的示例清单。

apiVersion: v1
kind: Service
metadata:
  annotations:
    service.beta.kubernetes.io/vultr-loadbalancer-protocol: "http"
    service.beta.kubernetes.io/vultr-loadbalancer-https-ports: "443"
    # You will need to have created a TLS Secret and pass in the name as the value
    service.beta.kubernetes.io/vultr-loadbalancer-ssl: "ssl-secret"
    service.beta.kubernetes.io/vultr-loadbalancer-algorithm: "least_connections"
    service.beta.kubernetes.io/vultr-loadbalancer-ssl-redirect: "true"
    service.beta.kubernetes.io/vultr-loadbalancer-firewall-rules: "0.0.0.0/80;0.0.0.0/443"
  labels:
    app: nginx
  name: nginx
spec:
  ports:
    - port: 80
      name: "http"
    - port: 443
      name: "https"
  selector:
    app: nginx
  type: LoadBalancer

可在此处找到可与 Vultr 负载均衡器一起使用的所有可用注释的列表。请检查您的特定云提供商以获取配置选项。首次部署LoadBalancer服务时,您会看到该EXTERNAL-IP部分是pending

 kubectl get svc
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1                443/TCP        150m
nginx        LoadBalancer   10.103.252.120        80:30092/TCP   4s

☁  kubectl describe service nginx
Name:                     nginx
Namespace:                default
Labels:                   app=nginx
Annotations:              
Selector:                 app=nginx
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.103.252.120
IPs:                      10.103.252.120
Port:                     80-80  80/TCP
TargetPort:               80/TCP
NodePort:                 80-80  30092/TCP
Endpoints:                10.244.230.199:80,10.244.230.200:80,10.244.242.68:80 + 2 more...
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type     Reason                  Age               From                Message
  ----     ------                  ----              ----                -------
  Normal   EnsuringLoadBalancer    8s (x4 over 44s)  service-controller  Ensuring load balancer
  Warning  SyncLoadBalancerFailed  8s (x4 over 44s)  service-controller  Error syncing load balancer: failed to ensure load balancer: load-balancer is not yet active - current status: pending

您会注意到 Kubernetes 在这里部署了一个负载均衡器,并且不断进行通信以检查负载均衡器是否已配置并分配了 IP。一旦 Load Balancer 已配置并准备好进行流量,您将在该EXTERNAL-IP字段中看到一个分配的 IP 地址,并且 LB 已被“确保”。这意味着 Kubernetes 现在可以控制相应地监控和更新负载均衡器。另外,请注意nodeport分配了唯一性。

kubectl get svc
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP    PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1                 443/TCP        154m
nginx        LoadBalancer   10.103.252.120   45.63.15.140   80:30092/TCP   4m9s

☁  kubectl describe service nginx
Name:                     nginx
Namespace:                default
Labels:                   app=nginx
Annotations:              
Selector:                 app=nginx
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.103.252.120
IPs:                      10.103.252.120
LoadBalancer Ingress:     45.63.15.140
Port:                     80-80  80/TCP
TargetPort:               80/TCP
NodePort:                 80-80  30092/TCP
Endpoints:                10.244.230.199:80,10.244.230.200:80,10.244.242.68:80 + 2 more...
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type     Reason                  Age                    From                Message
  ----     ------                  ----                   ----                -------
  Warning  SyncLoadBalancerFailed  2m21s (x5 over 3m37s)  service-controller  Error syncing load balancer: failed to ensure load balancer: load-balancer is not yet active - current status: pending
  Normal   EnsuringLoadBalancer    61s (x6 over 3m37s)    service-controller  Ensuring load balancer
  Normal   EnsuredLoadBalancer     60s                    service-controller  Ensured load balancer

EXTERNAL-IP为了验证我们的负载均衡器是否正常工作,我们可以向负载均衡器的公共 IP 地址发送请求。

curl 45.63.15.140



Welcome to nginx!

您可以将LoadBalancer服务类型视为一个绝妙的解决方案。但是,它们有一个缺点;您不能定义任何类型的 URL 路径,它不允许灵活性或将其路由到多个服务。该LoadBalancer服务与单个服务相关联,因此如果您想从集群中公开另一个应用程序,您将部署另一个负载均衡器,如果您有多个应用程序,它会快速增加成本。

这个问题的解决方案不是另一种服务类型,而是一种不同的 Kubernetes 资源,称为ingress.

请求入口

ingress 资源是一种更灵活的方式来定义您的服务以供外界访问。这里最大的卖点之一是您可以定义单个入口资源,并在您定义的子域、端口或 URL 路径下使用此路由到您的所有服务。它们还提供了大量其他功能,例如速率限制、身份验证、自动 TLS、加权路由等等。所有这些都可以通过单个负载均衡器完成,因为Ingress资源与服务类型一起工作,LoadBalancer唯一的区别是部署负载均衡器充当代理,将所有流量发送到“Ingress”资源,该资源充当 L7 负载均衡器簇。

入口控制器这里唯一需要注意的是 Kubernetes 没有自带入口控制器。

社区有各种入口控制器,都具有不同类型的功能。

最终,在决定安装哪个入口控制器之前,这取决于您的需求和场景。

展开阅读全文

页面更新:2024-03-12

标签:均衡器   节点   字段   负载   端口   清单   定义   类型   地址   工作

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top