K8s如何实现服务发现与配置管理

发表于:2021-7-12 09:59

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:小码哥Damon    来源:掘金

分享:
  K8s如何实现服务注册与发现
  我们一直在说K8s具备服务发现以及配置管理的能力,K8s是如何实现服务的注册与发现,然后如何做到服务的转发、实现负载均衡的。
  其实服务在K8s中,也定义了一种资源:Service,Service,顾名思义是一个服务,什么样的服务呢?它是定义了一个服务的多种 pod 的逻辑合集以及一种访问 pod 的策略。
  service 的类型有四种:
  · ExternalName:创建一个 DNS 别名指向 service name,这样可以防止 service name 发生变化,但需要配合 DNS 插件使用。
  · NodePort:基于 ClusterIp,用于为集群外部访问 Service 后面 Pod 提供访问接入端口。
  · LoadBalancer:它是基于 NodePort。
  · ClusterIP:默认的类型,用于为集群内 Pod 访问时,提供的固定访问地址,默认是自动分配地址,可使用 ClusterIP 关键字指定固定 IP。
  从上面讲的 Service,我们可以看到一种场景:所有的微服务在一个局域网内,或者说在一个 K8s 集群下,那么可以通过 Service 用于集群内 Pod 的访问,这就是 Service 默认的一种类型 ClusterIP,ClusterIP 这种的默认会自动分配地址。
  那么问题来了,既然可以通过上面的 ClusterIp 来实现集群内部的服务访问,那么如何注册服务呢?其实 K8s 并没有引入任何的注册中心,使用的就是 K8s 的 kube-dns 组件。然后 K8s 将 Service 的名称当做域名注册到 kube-dns 中,每一个Service在kube-dns中都有一条DNS记录,同时,如果有服务的ip更换,kube-dns自动会同步,对服务来说是不需要改动的。通过 Service 的名称就可以访问其提供的服务。那么问题又来了,如果一个服务的 pod 对应有多个,那么如何实现 LB?其实,最终通过 kube-proxy,实现负载均衡。也就是说kube-dns通过 servicename 找到指定 clusterIP,kube-proxy完成通过 clusterIP 到 PodIP 的过程。
  说到这,我们来看下 Service 的服务发现与负载均衡的策略,Service 负载分发策略有两种:
  · RoundRobin:轮询模式,即轮询将请求转发到后端的各个 pod 上,其为默认模式。
  · SessionAffinity:基于客户端 IP 地址进行会话保持的模式,类似 IP Hash 的方式,来实现服务的负载均衡。
  下面写一个很简单的例子:
  apiVersion: v1
  kind: Service
  metadata:
    name: cas-server-service
    namespace: default
  spec:
    ports:
    - name: cas-server01
      port: 2000
      targetPort: cas-server01
    selector:
      app: cas-server
  可以看到执行 kubectl apply -f service.yaml 后:
  root@ubuntu:~$ kubectl get svc
  NAME                          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)              AGE
  admin-web-service             ClusterIP   10.16.129.24    <none>        2001/TCP              84d
  cas-server-service            ClusterIP   10.16.230.167   <none>        2000/TCP               67d
  cloud-admin-service-service   ClusterIP   10.16.25.178    <none>        1001/TCP         190d
  这样,我们可以看到默认的类型是 ClusterIP,用于为集群内 Pod 访问时,可以先通过域名来解析到多个服务地址信息,然后再通过 LB 策略来选择其中一个作为请求的对象。
  K8s 如何处理微服务中常用的配置
  接下来我们看看微服务中场景的居多配置该如何来利用K8s实现统一管理。其实,在K8s中,定义了一种资源:ConfigMap,我们来看看这种资源。
  ConfigMap,看到这个名字可以理解:它是用于保存配置信息的键值对,可以用来保存单个属性,也可以保存配置文件。对于一些非敏感的信息,比如应用的配置信息,则可以使用 ConfigMap。
  创建一个 ConfigMap 有多种方式如下。
  1.key-value 字符串创建
  kubectl create configmap test-config --from-literal=baseDir=/usr
  上面的命令创建了一个名为 test-config,拥有一条 key 为 baseDir,value 为 "/usr" 的键值对数据。
  2.根据 yml 描述文件创建
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: test-config
  data:
    baseDir: /usr
  也可以这样,创建一个 yml 文件,选择不同的环境配置不同的信息:
  kind: ConfigMap
  apiVersion: v1
  metadata:
    name: cas-server
  data:
    application.yaml: |-
      greeting:
        message: Say Hello to the World
      ---
      spring:
        profiles: dev
      greeting:
        message: Say Hello to the Dev
      spring:
        profiles: test
      greeting:
        message: Say Hello to the Test
      spring:
        profiles: prod
      greeting:
        message: Say Hello to the Prod
  注意点:
  ·ConfigMap 必须在 Pod 使用其之前创建。
  ·Pod 只能使用同一个命名空间的 ConfigMap。
  当然,还有其他更多用途,具体可以参考官网(kubernetes.io/zh/docs/con…
  前面讲述了几种创建ConfigMap的方式,其中有一种在 Java 中常常用到:通过创建 yml 文件来实现配置管理。比如:
  kind: ConfigMap
  apiVersion: v1
  metadata:
    name: cas-server
  data:
    application.yaml: |-
      greeting:
        message: Say Hello to the World
      ---
      spring:
        profiles: dev
      greeting:
        message: Say Hello to the Dev
      spring:
        profiles: test
      greeting:
        message: Say Hello to the Test
      spring:
        profiles: prod
      greeting:
        message: Say Hello to the Prod
  这样,当我们启动容器时,通过 --spring.profiles.active=dev 来指定当前容器的活跃环境,即可获取 ConfigMap 中对应的配置。是不是感觉跟 Java 中的 Config 配置多个环境的配置有点类似呢?但是,我们不用那么复杂,这些统统可以交给 K8s 来处理。只需要你启动这一命令即可,是不是很简单?

      本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号