zoukankan      html  css  js  c++  java
  • k8s

    类型ExternalName

    类型为 ExternalName 的服务将服务映射到 DNS 名称,而不是典型的选择器,例如 my-service 或者 cassandra。 您可以使用 spec.externalName 参数指定这些服务。

    例如,以下 Service 定义将 prod 名称空间中的 my-service 服务映射到 my.database.example.com

    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
      namespace: prod
    spec:
      type: ExternalName
      externalName: my.database.example.com
    说明: ExternalName 接受 IPv4 地址字符串,但作为包含数字的 DNS 名称,而不是 IP 地址。 类似于 IPv4 地址的外部名称不能由 CoreDNS 或 ingress-nginx 解析,因为外部名称旨在指定规范的 DNS 名称。 要对 IP 地址进行硬编码,请考虑使用 [headless Services](#headless-services)。

    当查找主机 my-service.prod.svc.cluster.local 时,群集DNS服务返回 CNAME 记录,其值为 my.database.example.com。 访问 my-service 的方式与其他服务的方式相同,但主要区别在于重定向发生在 DNS 级别,而不是通过代理或转发。 如果以后您决定将数据库移到群集中,则可以启动其 Pod,添加适当的选择器或端点以及更改服务的类型

    以下文章引用: https://www.qedev.com/cloud/244937.html

    ExternalName 介绍

    记得很多年前大陆流行音乐刚开始流行,李春波的一首《小芳》风靡大街小巷,正处于青春懵懂期的少男,顷刻间就被它的旋律捕获了,于是小芳就是初恋,初恋就是小芳.

    后来上了大学,读了计算机系,学到了很多基于控制台的命令,但是不知道为什么,每当我敲打 ln 命令的时候,都会想起小芳,那时我天真地认为,只要找到了小芳,我就可以找到幸福,于是我向一个情场老手讨教全年级最好记的女生姓名叫什么?他想都没想,脱口而出——“殷静”、“史珍香”。

            后来学了 k8s,知道了常用的 k8s service 类型—— ClusterIP、NodePort、LoadBalancer,唯独对 externalName 置若罔闻,直到有一天在学习 Istio Sidecar 这种 API 资源的时候,才突然领悟了 ExternalName 这种 k8s service 类型是使用场景。

     ExternalName 这种 service 类型的作用类似软链或者快捷方式。下面举一个具体的例子。

     该样例目的是让处于 default 命名空间下的 httpd-pod 访问到处于 nginx-ns 命名空间下的 nginx-svc,不像以往 svc-name.ns-name.svc.cluster.local 方式跨命名空间访问的方式,这里我们使用 ExternalName 方式。

     jiuxi-client.yaml

     jiuxi-client-svc.yaml

     关键点就在这个文件,该文件中指定了到 nginx-svc 的软链,这么做的好处是对使用者做到了透明,让使用者感觉就好像调用自己命名空间的服务一样。

    jiuxi-nginx.yaml

     

    jiuxi-nginx-svc.yaml

    jiuxi-ns.yaml

    自此整个样例代码编写完毕。

    首先创建 jiuxi-ns.yaml 命名空间,然后再应用其他资源文件,如下命令所示:

    kubectl apply -f jiuxi-ns.yaml

    kubectl apply -f jiuxi-client.yaml

    kubectl apply -f jiuxi-client-svc.yaml

    kubectl apply -f jiuxi-nginx.yaml

    kubectl apply -f jiuxi-nginx-svc.yaml

         

    验证样例

    所有 pod 都争取运行之后,登录 client,然后执行如下语句:

    wget -q -O - http://jiuxi-client-svc

    wget -q -O - http://jiuxi-nginx-svc.nginx-ns.svc.cluster.local

            发现两种方式都可以正常访问。

    扩展阅读 

    K8S 最佳实践-映射外部服务

    场景 1:具有 IP 地址的集群外数据库

    其中一个常见场景是在集群外部托管自己的数据库,例如在 Google 计算引擎实例中。如果您在 Kubernetes 内部和外部分别运行一些服务,或者需要在 Kubernetes 允许的基础上获得更多定制或控制,通常可采用上述这种方式。

    希望未来某个时候您可以将所有服务都移入集群内,但在此之前将是“内外混用”的状态。幸运的是,您可以使用静态 Kubernetes 服务来缓解上述痛点。

    在本例中,我使用 Cloud Launcher 创建了一个 MongoDB 服务器。由于此服务器在与 Kubernetes 集群相同的网络(或 VPC)中创建,因此可以使用高性能的内部 IP 地址访问。在 Google Cloud 中,这是默认设置,因此无需进行任何特殊配置。

    现在我们有了 IP 地址,那么第一步就是创建服务:

    kind: Service

    apiVersion: v1

    metadata:

    name: mongo

    Spec:

    type: ClusterIP

    ports:

    – port: 27017

    targetPort: 27017

    您可能会注意到此服务没有 Pod 选择器。此操作将创建一个服务,但它不知道往哪里发送流量。这样一来,您可以手动创建一个将从此服务接收流量的 Endpoints 对象。

    kind: Endpoints

    apiVersion: v1

    metadata:

    name: mongo

    subsets:

    – addresses:

    – ip: 10.240.0.4

    ports:

    – port: 27017

    您可以看到 Endpoints 手动定义了数据库的 IP 地址,并且使用的名称与服务名称相同。Kubernetes 将 Endpoints 中定义的所有 IP 地址视为与常规 Kubernetes Pod 一样。现在您可以用一个简单的连接字符串访问数据库:

    mongodb://mongo

    > 根本不需要在代码中使用 IP 地址!如果以后 IP 地址发生变化,您可以为端点更新 IP 地址,而应用无需进行任何更改。

    场景 2:具有 URI 的远程托管数据库

    如果您使用的是来自第三方的托管数据库服务,它们可能会为您提供可用于连接的统一资源标识符 (URI)。如果它们为您提供 IP 地址,则可以使用场景 1 中的方法。

    在本例中,我在 mLab 上托管了两个 MongoDB 数据库。一个是我的开发数据库,另一个是生产数据库。

    这些数据库的连接字符串如下所示:

    mongodb://<dbuser>:<dbpassword>@ds149763.mlab.com:49763/devmongodb://<dbuser>:<dbpassword>@ds145868.mlab.com:45868/prodmLab

    为您提供了动态 URI 和动态端口,您可以看到两者都不同。我们来使用 Kubernetes 基于这些差异创建一个抽象层。在本例中,我们将连接开发数据库。

    您可以创建一个 “ExternalName” Kubernetes 服务,此服务为您提供将流量重定向到外部服务的静态 Kubernetes 服务。此服务在内核级别执行简单的 CNAME 重定向,因此对性能的影响非常小。

    服务的 YAML 如下所示:

    kind: Service

    apiVersion: v1

    metadata:

    name: mongo

    spec:

    type: ExternalName

    externalName: ds149763.mlab.com

    现在,您可以使用更简化的连接字符串:

    mongodb://<dbuser>:<dbpassword>@mongo:<port>/dev

    由于 “ExternalName” 使用 CNAME 重定向,因此无法执行端口重映射。对于使用静态端口的服务来说,这可能不成问题,然而本例中使用的是动态端口。mLab 免费版为您提供了动态端口号,并且不允许更改。这意味着您需要对开发和生产数据库使用其他连接字符串。

    但如果您可以获取 IP 地址,就可以执行端口重映射,关于此内容,我将在下一部分进行介绍。

    场景 3:具有 URI 和端口重映射功能的远程托管数据库

    CNAME 重定向对于每个环境均使用相同端口的服务非常有效,但如果每个环境的不同端点使用不同的端口,CNAME 重定向就略显不足。幸运的是我们可以使用一些基本工具来解决这个问题。

    第一步是从 URI 获取 IP 地址。

    对 URI 运行 nslookup、hostname 或 ping 命令即可获取数据库的 IP 地址。

    您现在可以创建一个重新映射 mLab 端口的服务,并为此 IP 地址创建端点。

    kind: Service

    apiVersion: v1

    metadata:

    name: mongo

    spec:

    ports:

    – port: 27017

    targetPort: 49763

    kind: Endpoints

    apiVersion: v1

    metadata:

    name: mongo

    subsets:

    – addresses:

    – ip: 35.188.8.12

    ports:

    – port: 49763

    注:URI 可以使用 DNS 在多个 IP 地址之间进行负载平衡,因此,如果 IP 地址发生变化,这个方法可能会有风险!如果您通过上述命令获取多个 IP 地址,则可以将所有这些地址都包含在 Endpoints YAML 中,并且 Kubernetes 会在所有 IP 地址之间进行流量的负载平衡。

    通过这种方式,您无需指定端口即可连接到远程数据库。Kubernetes 服务重映射端口的过程完全透明!

    mongodb://<dbuser>:<dbpassword>@mongo/dev

    结论

    将外部服务映射到内部服务可让您未来灵活地将这些服务纳入集群,同时最大限度地减少重构工作。即使您今天不打算将服务加入集群,以后可能也会这样做!而且,这样一来,您可以更轻松地管理和了解组织所使用的外部服务。

    如果外部服务具有有效域名,并且您不需要重新映射端口,那么使用 “ExternalName” 服务类型将外部服务映射到内部服务十分简便、快捷。如果您没有域名或需要执行端口重映射,只需将 IP 地址添加到端点并使用即可。

    实例 

    ExternalName
    apiVersion: v1
    kind: Service
    metadata:
      name: "baiducom" # 设置 IP 14.215.177.39和www.baidu.com 错误,不允许'.'
    spec:
      type: ExternalName
      externalName: "www.baidu.com" # 设置 IP 14.215.177.39 无效
    
    # 所以 externalName 的意义就是为域名设置一个别名,如上 为 www.baidu.com 设置别名 baiducom,以便 pod 内容器使用
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: busybox
      labels:
        app: busybox
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: busybox
      template:
        metadata:
          labels:
            app: busybox
        spec:
          containers:
            - name: busybox
              image: busybox
              command: ["/bin/sh", "-c", "sleep 3600"]

    - 外部 IP 链接

    ip.yaml 外部访问:

    182.254.186.198:81
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      labels:
        run: nginx
    spec:
      type: NodePort
      ports:
        - port: 80
          targetPort: 80
          protocol: TCP
          name: http
          nodePort: 81
      selector:
        run: nginx
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx
    spec:
      selector:
        matchLabels:
          run: nginx
      replicas: 1
      template:
        metadata:
          labels:
            run: nginx
        spec:
          containers:
            - name: nginx
              image: nginx
              ports:
                - containerPort: 80

    kubectl apply -f ip.yaml

    创建服务 ips.yaml

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-ip
    spec:
      ports:
        - protocol: TCP
          port: 88
          targetPort: 81
    ---
    apiVersion: v1
    kind: Endpoints
    metadata:
      name: nginx-ip
    subsets:
      - addresses:
          - ip: 182.254.186.198
        ports:
          - port: 81 # IP相关的端口,可以是外部连接端口,也可以是内部容器连接端口

    kubectl apply -f ips.yaml

     -

     

  • 相关阅读:
    .Net 加密原理,HVM核心的实现原理(八)
    .Net中的数字类型四则运算的有趣问题
    DNGuard HVM 中文版 V2.80 发布,优惠活动
    买烟(古龙版)
    .Net的混淆属性以及ildasm限制的简单解除方法
    方程式
    silverlight学习网站
    .NET精品文章系列(一)
    VS 2008 + .NET 3.5系列
    Expression Blend学习网站
  • 原文地址:https://www.cnblogs.com/microestc/p/13255086.html
Copyright © 2011-2022 走看看