在CSDN学Golang云原生(Kubernetes Service)

一,service的定义与基本用法

在 Kubernetes 中,Service 是一种抽象概念,用于定义一组 Pod 并为它们提供访问入口。通过 Service,您可以将多个 Pod 组合成一个逻辑单元,并使用标签选择器来确定哪些 Pod 属于该 Service。

下面是一个简单的 Service 定义示例:

复制代码
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app # 标签选择器,用于确定哪些 Pod 属于该 Service
  ports:
    - name: http
      port: 80 # 外部暴露的端口
      targetPort: 9376 # 绑定的 Pod 端口

在上面的示例中,我们创建了一个名为 my-service 的 Service,并指定了一个标签选择器 app=my-app 来确定哪些 Pod 属于该 Service。此外,我们还指定了一个绑定端口(端口号为 80),并将其绑定到后端 Pod 的某个端口(这里为 9376)。

使用此配置文件部署该服务后,Kubernetes 将自动创建一个负载均衡器,并分配给该服务一个稳定的 IP 地址和 DNS 名称。其他应用程序可以使用这个 IP 地址或 DNS 名称来访问该服务。

需要注意的是,在 Kubernetes 中,Service 可以有不同类型:ClusterIP、NodePort、LoadBalancer 和 ExternalName。每种类型都有不同的用途和配置方式。

下面是一些常见的 Service 使用示例:

  1. ClusterIP Service:将一组 Pod 组成一个逻辑单元,并在集群内部提供访问入口。

    apiVersion: v1
    kind: Service
    metadata:
    name: my-service-clusterip
    spec:
    selector:
    app: my-app # 标签选择器,用于确定哪些 Pod 属于该 Service
    ports:
    - name: http
    port: 80 # 外部暴露的端口
    targetPort: 9376 # 绑定的 Pod 端口

  2. NodePort Service:除了提供 ClusterIP Service 的功能外,还可以在每个节点上绑定一个静态端口号,从而允许外部流量进入 Kubernetes 集群。

    apiVersion: v1
    kind: Service
    metadata:
    name: my-service-nodeport
    spec:
    selector:
    app: my-app # 标签选择器,用于确定哪些 Pod 属于该 Service
    ports:
    - name: http
    port: 80 # 外部暴露的端口(在所有节点上都会监听此端口)
    targetPort: 9376 # 绑定的 Pod 端口(Pod 内容器监听此端口)
    nodePort: 30001 # 在每个节点上绑定的静态端口号(范围为:30000-32767)

  3. LoadBalancer Service:除了提供 NodePort Service 的功能外,还可以使用云供应商提供的负载均衡器来平衡流量,从而允许外部流量进入 Kubernetes 集群。

    apiVersion: v1
    kind: Service
    metadata:
    name: my-service-loadbalancer
    spec:
    selector:
    app: my-app # 标签选择器,用于确定哪些 Pod 属于该 Service
    ports:
    - name: http
    port: 80 # 外部暴露的端口(在所有节点上都会监听此端口)
    targetPort: 9376 # 绑定的 Pod 端口(Pod 内容器监听此端口)
    type: LoadBalancer # 指定为 LoadBalancer 类型的 Service

  4. ExternalName Service:将一个服务映射到集群外部的另一个服务或域名,从而允许集群内部使用相同的 DNS 名称来访问集群外部服务。

    apiVersion: v1
    kind: Service
    metadata:
    name: my-service-externalname
    spec:
    externalName: some.api.com # 将该 Service 映射到 some.api.com 域名或 IP 地址上

这里仅列出了一些常见的示例。

二,service 4种发布类型

在 Kubernetes 中,Service 可以有不同的发布类型,常见的包括以下四种:

  1. ClusterIP:默认类型。将 Service 暴露在集群内部,并分配一个虚拟 IP 地址(Cluster IP)给该 Service。其他 Pod 和 Service 可以使用这个 IP 地址来访问该 Service。
  2. NodePort:除了提供 ClusterIP 的功能外,还会在每个节点上绑定一个静态端口号,并将流量转发到该端口号。这允许外部流量进入 Kubernetes 集群并访问该 Service。
  3. LoadBalancer:除了提供 NodePort 的功能外,还可以使用云服务提供商的负载均衡器来平衡流量。当您创建一个 LoadBalancer 类型的 Service 时,Kubernetes 会自动创建一个负载均衡器,并将其配置为将请求转发到后端 Pod 上。
  4. ExternalName:将一个服务映射到集群外部的另一个服务或域名,从而允许集群内部使用相同的 DNS 名称来访问集群外部服务。与其他类型不同,ExternalName 不需要选择任何 Pod 或 Endpoint。

需要注意的是,在进行发布之前,请确保已经创建了相关的 Deployment 或 StatefulSet 等资源,并且已经正确标记了相关的 Pod 和 Endpoint。否则,即使正确配置了发布类型和其他参数,Service 也无法正常工作。

三,service 无选择符service

在 Kubernetes 中,Service 有一个叫做选择器(selector)的属性,用于定义该 Service 所要代理的 Pod。但是有些时候我们需要将 Service 直接映射到外部 IP 或者 DNS 名称,而不是 Kubernetes 内部的 Pod,这时就可以使用无选择符(selector-less)Service。

无选择符 Service 的作用主要有两个:

  1. 将外部服务(如数据库或缓存)的访问与应用程序解耦,从而更容易地进行管理和维护。
  2. 在没有合适的标签或注释来匹配目标 Pod 的情况下,仍然可以使用 Service 进行暴露和路由。

注意:由于无选择符 Service 不涉及任何 Pod,并且不能通过 IP 地址进行流量分配,因此它只能使用 NodePort 或 LoadBalancer 类型。

四,service HeadLess Service

在 Kubernetes 中,Headless Service 是一种特殊类型的 Service,它没有 Cluster IP,也没有负载均衡器。相反,它返回一个由 Pod IP 地址组成的集合。

Headless Service 的作用是将服务发现和负载均衡交给应用程序自己来处理。这样一来,客户端可以直接连接到服务中的任何一个 Pod 上,并且不需要经过 Service 层进行代理或转发。

Headless Service 常用于以下场景:

  1. StatefulSet:StatefulSet 控制器需要为每个 Pod 分配唯一标识符和网络主机名。如果使用 ClusterIP 类型的 Service,则所有 Pod 共享同一个 DNS 名称和 IP 地址,无法满足这个需求。因此,在 StatefulSet 控制器中通常使用 Headless Service 来提供服务发现功能。
  2. 数据库集群:数据库集群通常需要使用 DNS 名称或 IP 地址来定位节点。如果使用 ClusterIP 类型的 Service,则只能将流量转发到单个节点上,不能实现负载均衡和故障恢复。因此,在数据库集群中通常使用 Headless Service 来提供服务发现功能。
  3. 自定义网络拓扑:某些场景下需要控制容器之间的网络拓扑结构,这时候就可以通过 Headless Service 将容器之间的连接直接暴露出去,并且由应用程序自己进行管理和调度。

需要注意的是,由于 Headless Service 没有 Cluster IP 和负载均衡器,所以不能使用 NodePort 或 LoadBalancer 类型。并且,在访问 Headless Service 时需要使用完整的 DNS 名称或 IP 地址来定位 Pod。

五,service 环境变量与DNS服务发现

Kubernetes中,Service是一个抽象的逻辑概念,用于定义一组后端Pod的访问方式。当创建一个Service时,Kubernetes会自动在集群内部创建一个虚拟IP(Cluster IP),并将该IP绑定到Service上。这样,在集群内部可以通过该虚拟IP来访问Service所代表的一组Pod。

对于运行在容器中的应用程序,可以通过环境变量或DNS服务发现来访问其他服务。

  1. 环境变量

当我们创建一个Service时,Kubernetes会自动为该Service中所有Pod设置一些环境变量。其中包括:

  • SERVICE_HOST:Service所绑定的虚拟IP地址。
  • SERVICE_PORT:Service所监听的端口号。

使用这些环境变量,我们就可以在容器中直接访问同一个Service中的其他Pod了。

  1. DNS服务发现

除了使用环境变量外,Kubernetes还提供了DNS服务发现机制。每个 Service 都有一个 DNS 名称,默认情况下是"servicename.namespace.svc.cluster.local"。通过DNS名称解析,就可以轻松地实现跨命名空间和跨节点的服务发现和通信。

例如,在Python代码中使用requests库调用另一个 Service:

复制代码
import requests

url = "http://otherservice.default.svc.cluster.local:8080/api/v1/getdata"
response = requests.get(url)

这里,"default"是命名空间名称,"otherservice"是Service名称,"svc.cluster.local"是默认的Kubernetes集群域名。

Kubernetes中的Service提供了一种高效、灵活、可靠的服务发现和通信机制,能够满足微服务架构下各个组件之间的调用需求。

六,service TLS

在Kubernetes中,我们可以使用Service来暴露一组Pod作为一个服务。当需要对服务进行加密通信时,可以通过在Service和Pod之间添加TLS层来实现。

以下是一些步骤:

  1. 创建证书和私钥

首先,我们需要创建用于加密通信的证书和私钥。这里假设已经有了自签名证书和私钥。

  1. 创建Secret对象

然后,将证书和私钥打包到一个Kubernetes Secret对象中:

复制代码
$ kubectl create secret tls mytlssecret --cert=server.crt --key=server.key

这里创建了一个名为"mytlssecret"的Secret对象,并将"server.crt"和"server.key"两个文件打包成为该对象的数据部分。

  1. 修改Service定义

接着,在Service定义中添加如下部分:

复制代码
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - name: https
    port: 443
    targetPort: 80
  selector:
    app: myapp
  type: ClusterIP
  tls:
  - hosts:
    - myservice.example.com 
    secretName: mytlssecret

其中,"hosts"指定了该TLS配置所要绑定的域名,"secretName"指定了上一步创建的Secret对象名称。

  1. 更新应用程序

最后,在应用程序中更新相关代码,使其支持HTTPS协议即可。如果使用HTTP客户端库(如requests)调用其他服务时,也需要相应地修改代码以支持HTTPS协议。

需要注意的是,在使用Service TLS时,我们还需要考虑证书和私钥的管理、更新和分发等问题。可以使用工具如cert-manager来自动化这些任务,使TLS证书管理更加便捷和安全。

七,ingress http 7层路由机制

Kubernetes Ingress是一种可以将HTTP和HTTPS流量路由到集群中不同服务的API对象,通常用于实现七层(应用层)路由。

在Ingress配置中,可以定义多个规则(Rule),每个规则包含一个Host名称和若干条Path规则。对于每条Path规则,可以指定要将请求转发到哪个Service上。因此,在使用Ingress时,需要先定义好所需的Service,并将它们标记为需要通过Ingress暴露出来的服务。

Ingress主要有以下几种类型:

  1. Nginx Ingress:使用Nginx作为负载均衡器实现七层路由。
  2. Traefik Ingress:使用Traefik作为负载均衡器实现七层路由。
  3. Istio Ingress Gateway:基于Istio实现网关功能,并支持灰度发布、流量控制等高级特性。

当客户端发送请求时,Ingress会根据请求中的Host和Path信息匹配对应的规则,并将请求转发给相应的后端Service。如果没有匹配到任何规则,则会返回404错误。

总之,Kubernetes Ingress提供了一种方便易用的方式来管理应用程序的入口流量,并支持多种七层路由机制和高级特性。

八,ingress Controller 安装

安装Kubernetes Ingress Controller可以使用多种不同的方案,这里介绍一些常见的方法:

  1. 使用官方提供的Nginx Ingress Controller

    kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.46.0/deploy/static/provider/cloud/deploy.yaml

  2. 使用Helm安装Nginx Ingress Controller

    helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
    helm install my-release ingress-nginx/ingress-nginx

  3. 使用官方提供的Traefik Ingress Controller

    kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v2.4/examples/k8s/traefik-deployment.yaml
    kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v2.4/examples/k8s/ui.yaml

  4. 使用Helm安装Traefik Ingress Controller

    helm repo add traefik https://helm.traefik.io/traefik
    helm install my-release traefik/traefik

需要注意的是,在部署Ingress Controller之前,需要确保已经正确设置了Kubernetes集群中的网络插件,并且Node节点都已经正确配置和准备好。

九,ingress转发策略配置

Kubernetes Ingress资源可以使用不同的策略来实现请求转发。这里列出一些常见的Ingress转发策略:

  1. Path-Based Routing:根据请求URL路径进行路由,可使用nginx ingress或traefik ingress实现

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
    name: example-ingress
    spec:
    rules:

    • host: example.com
      http:
      paths:
      • path: /v1
        backend:
        serviceName: service-v1
        servicePort: 80
      • path: /v2
        backend:
        serviceName: service-v2
        servicePort: 80
  2. Host-Based Routing:根据请求的主机名(host)进行路由,可使用nginx ingress或traefik ingress实现

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
    name: my-ingress
    spec:
    rules:
    - host: foo.bar.com
    http:
    paths:
    - path: /path/to/service
    backend:
    serviceName: my-service
    servicePort : my-service-port

  3. TCP/UDP routing:将TCP/UDP流量路由到特定服务的端口,通过MetalLB等负载均衡器实现

    apiVersion : v1
    kind : Service
    metadata :
    name : mysql-svc
    labels :
    app : mysql-db
    spec :
    ports :
    - port : 3306
    targetPort : mysql
    selector :
    app : mysql-db


    apiVersion : networking.k8s.io/v1beta1
    kind : Ingress
    metadata :
    name : mysql-ingress
    spec :
    rules:
    - host: mysql.example.com
    http:
    paths:
    - path: /
    backend:
    serviceName: mysql-svc
    servicePort: 3306

  4. Fanout:将请求路由到多个服务,可使用traefik ingress实现

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
    name: fanout-ingress
    spec:
    rules:
    - host: example.com
    http:
    paths:
    - path: /serviceA/*
    backend:
    serviceName: service-a
    servicePort: 80
    - path: /serviceB/*
    backend:
    serviceName: service-b
    servicePort: 80

需要根据实际需求选择合适的Ingress转发策略。

十,ingress TLS 配置

Kubernetes Ingress可以配置TLS证书,提供HTTPS服务。下面是一个简单的Ingress TLS配置示例:

  1. 生成TLS证书和私钥

    $ openssl req -x509 -nodes -days 365 -newkey rsa:2048
    -out /path/to/tls.crt
    -keyout /path/to/tls.key
    -subj "/CN=example.com"

  2. 创建k8s secret

    $ kubectl create secret tls example-tls --cert=/path/to/tls.crt --key=/path/to/tls.key

  3. 配置Ingress规则

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
    name: example-ingress
    spec:
    tls:

    • hosts:
      • example.com
        secretName: example-tls #引用上一步创建的secret名称
        rules:
    • host: example.com
      http:
      paths:
      • path: /
        backend:
        serviceName: service-name
        servicePort : service-port

在这个例子中,我们使用了tls字段来配置TLS证书信息。我们指定了hosts为example.com,并且将之前创建的名为example-tls的secret用于TLS证书。

需要注意的是,此处只给出了一个简单的TLS配置示例,请根据实际需求进行相应修改。同时,还需要确保您的域名和证书匹配。

相关推荐
那明眸似水3 小时前
云原生项目三:Docker秒级启动NextCloud个人网盘存储办公系统
linux·运维·docker·云原生·容器
腾飞开源4 小时前
03_Kubernetes 核心概念拆解:从 Spec/Status 收敛到工作负载控制器的设计逻辑
云原生·容器·kubernetes
知已难寻15 小时前
Docker 入门:容器技术与 Docker 基础
java·运维·服务器·docker·云原生·容器
阿里云云原生20 小时前
生产更可信,订阅更耐用丨Higress 社区进展报告
云原生
阿里云云原生1 天前
如何用 STAROps Elasticsearch 智能助手看穿“搜索变慢”
云原生
kuroomi1 天前
Git入门
git·kubernetes
雾时之林1 天前
国内Docker 镜像加速器配置
云原生·eureka
我是koten1 天前
【运维杂谈】K8s遇到Terminating的名称空间删除不了怎么办?(解决方案亲测有效)
linux·运维·服务器·云原生·kubernetes·k8s·名称空间
RuoyiOffice2 天前
KubeSphere 容器云实践:从管理 K8s 到建设企业 PaaS,还需要哪些能力
spring boot·kubernetes·kubesphere·jenkins·paas·微服务部署·ruoyi office
风吹稻子2 天前
etcd备份与恢复:删了 etcd.yaml,容器为什么还在跑?——一次 K8s 控制面死锁排查实录
kubernetes