OpenYurt: 在边缘场景无缝运行使用InClusterConfig的业务Pod

简介: ### 1. 背景介绍OpenYurt是业界首个非侵入的边缘计算云原生开源项目,通过边缘自治,云边协同,边缘单元化,边缘流量闭环等能力为用户提供云边一体化的使用体验。OpenYurt不少用户,经常需要把存量的使用InClusterConfig访问kube-apsierver的Pod通过OpenYurt迁移到边缘环境中。如下图所示:![](https://ata2-img.oss-cn-zhan

1. 背景介绍

OpenYurt是业界首个非侵入的边缘计算云原生开源项目,通过边缘自治,云边协同,边缘单元化,边缘流量闭环等能力为用户提供云边一体化的使用体验。OpenYurt不少用户,经常需要把存量的使用InClusterConfig访问kube-apsierver的Pod通过OpenYurt迁移到边缘环境中。如下图所示:

在OpenYurt集群中,提供了使用InClusterConfig的业务Pod零修改就可以运行在边缘环境的能力。

2. 面临挑战

使用InClusterConfig的业务Pod在边缘环境中运行,需要解决如下问题:

  • 问题一:Pod通过InClusterConfig地址访问kube-apiserver,节点上默认网络规则(iptables/ipvs)将会把请求转发到kube-apiserver的Pod IP,同时云端与边缘位于不同网络平面,边缘是无法访问到云端的Pod IP。所以边缘业务Pod无法通过InClusterConfig访问到kube-apiserver。

  • 问题二:在解决问题一后,如果云边网络断开时业务Pod容器出现重启等状况,边缘Pod将无法从kube-apiserver获取到业务配置,这会影响到业务Pod的重启运行。

3. 解决方案

从上述问题可以看出,我们需要需要无感知的调整边缘Pod的访问地址,同时需要在边缘环境中缓存业务配置,保证云边断网时也可以利用边缘缓存来获取业务Pod的配置信息。具体解决方案如下:

3.1 边缘Pod访问的云端endpoint优化

  • Pod通过InClusterConfig访问kube-apiserver,源码如下:
func InClusterConfig() (*Config, error) {
    const (
        tokenFile  = "/var/run/secrets/kubernetes.io/serviceaccount/token"
        rootCAFile = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
    // 通过Kuberentes service对应的环境变量来获取访问地址
    host, port := os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT")
    if len(host) == 0 || len(port) == 0 {
        return nil, ErrNotInCluster
    }
  
  // skip some code...
  
  return &Config{
        Host:            "https://" + net.JoinHostPort(host, port),
        TLSClientConfig: tlsClientConfig,
        BearerToken:     string(token),
        BearerTokenFile: tokenFile,
    }, nil
}
  • 因此想无感知调整边缘Pod访问的云端endpoint,只需要无侵入修改Pod的KUBERNETES_SERVICE_HOST和KUBERNETES_SERVICE_PORT两个环境变量或者修改kubernetes service地址。解决方案如下:

    • 解决方案一: 增加一个admission controller

在边缘Pod创建时把kube-apiserver的公网地址自动注入到Pod的环境变量KUBERNETES_SERVICE_HOST和KUBERNETES_SERVICE_PORT

  • 解决方案二: 边缘数据过滤框架中增加一个filter

yurthub的边缘数据过滤框架类似于admission controller,专门用于边缘场景下在边缘应用无感知的状态下,无侵入的修改或者过滤云端返回的数据。目前支持的过滤器有: masterservice, servicetopology, discardcloudservice等
● 解决方案对比:

解决方案一 解决方案二
实现方案 增加一个admission controller 边缘数据过滤框架中增加一个filter
复杂度 高(需要区别Pod运行在边缘还是云端)
显式修改数据 Pod中增加环境变量配置

综合实现复杂度,非侵入等设计理念,在OpenYurt中我们选择了解决方案二. 如下图所示:

3.2 业务Pod的边缘自治

在云边网络断开状态下,业务Pod重启时,将无法从云端kube-apiserver获取到业务配置信息,因此需要在边缘本地缓存Pod的业务数据。而在OpenYurt中的Yurthub组件正是用于解决这个问题的,想看详细设计的同学可以看[这篇文章](https://mp.weixin.qq.com/s/4BLfvMJJA623ZwRSgUE69A)。因此边缘Pod只需要通过Yurthub来访问kube-apiserver,就可以自然的解决云边断网时业务Pod重启的问题。如下图所示:

- 说明1: 业务Pod通过yurthub访问kube-apiserver,也意味[3.1 边缘Pod访问的云端endpoint优化] 章节中提到的KUBERNETES_SERVICE_HOST和KUBERNETES_SERVICE_PORT环境变量被修改为yurthub https endpoint(169.254.2.1:10268)。
- 说明2: 如果业务Pod的大量list/watch操作导致大量本地cache,可能会造成本地磁盘压力。因此yurthub对业务Pod的缓存能力默认是关闭的,用户可以通过yurt-hub-cfg configmap的cache_agents字段中增加User-Agent信息来打开对应Pod的数据缓存。例如:
apiVersion: v1
kind: ConfigMap
metadata:
  name: yurt-hub-cfg
  namespace: kube-system
data:
  # 缓存边缘ingress-controller pod访问kube-apiserver的数据
  cache_agents: "ingress-controller"

4. 总结

  • 如果存量Pod无需访问kube-apiserver或者通过InClusterConfig访问kube-apiserver,这些类型Pod可以零修改运行到OpenYurt集群的边缘环境上。通过其他方式访问kube-apiserver的业务Pod目前无法保证零修改运行到边缘环境。
  • 边缘业务Pod是否正常访问kube-apiserver,首先可以查看业务Pod的环境变量是否正常:KUBERNETES_SERVICE_HOST=127.0.0.1或者169.254.2.1,KUBERNETES_SERVICE_PORT=10268。然后可以查看yurthub组件的日志看是否有业务Pod相关的请求日志。当然也可以查询业务Pod的日志是否正常。最后可以确认/etc/kubernetes/cache目录是否有相关组件的缓存数据,如果没有可以再确认kube-system/yurt-hub-cfg configmap是否已经配置。
  • 使用InClusterConfig的Pod零修改运行到边缘环境的能力,整体实现由yurthub组件承载,没有给OpenYurt架构增加额外的负担,同时用户在使用过程中对该能力也基本无感知,对原生业务Pod无侵入。
  1. 参考链接
相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
7月前
|
Kubernetes 物联网 数据中心
大规模 IoT 边缘容器集群管理的几种架构 -2-HashiCorp 解决方案 Nomad
大规模 IoT 边缘容器集群管理的几种架构 -2-HashiCorp 解决方案 Nomad
|
4月前
|
存储 边缘计算 Kubernetes
边缘计算问题之YurtControllerManager 接管原生 Kubernetes 的调度如何解决
边缘计算问题之YurtControllerManager 接管原生 Kubernetes 的调度如何解决
38 1
|
4月前
|
边缘计算 Kubernetes Cloud Native
边缘计算问题之OpenYurt 确保 Kubernetes 能力在边缘的一致性如何解决
边缘计算问题之OpenYurt 确保 Kubernetes 能力在边缘的一致性如何解决
41 1
|
7月前
|
存储 边缘计算 Kubernetes
大规模 IoT 边缘容器集群管理的几种架构 -6- 个人体验及推荐
大规模 IoT 边缘容器集群管理的几种架构 -6- 个人体验及推荐
|
7月前
|
运维 Kubernetes 物联网
大规模 IoT 边缘容器集群管理的几种架构 -5- 总结
大规模 IoT 边缘容器集群管理的几种架构 -5- 总结
|
7月前
|
边缘计算 运维 Kubernetes
大规模 IoT 边缘容器集群管理的几种架构 -4-Kubeedge
大规模 IoT 边缘容器集群管理的几种架构 -4-Kubeedge
|
7月前
|
Kubernetes 安全 物联网
大规模 IoT 边缘容器集群管理的几种架构 -3-Portainer
大规模 IoT 边缘容器集群管理的几种架构 -3-Portainer
|
7月前
|
运维 Kubernetes 物联网
大规模 IoT 边缘容器集群管理的几种架构 -1-Rancher+K3s
大规模 IoT 边缘容器集群管理的几种架构 -1-Rancher+K3s
|
7月前
|
边缘计算 Kubernetes 物联网
大规模 IoT 边缘容器集群管理的几种架构 -0- 边缘容器及架构简介
大规模 IoT 边缘容器集群管理的几种架构 -0- 边缘容器及架构简介
|
Kubernetes Cloud Native 测试技术
在云计算平台上部署Kubernetes:无缝管理和弹性扩展
Kubernetes已成为云计算平台上部署和管理容器化应用程序的首选解决方案。无论您选择使用Google Cloud Platform(GCP)、Amazon Web Services(AWS)、Microsoft Azure或其他云计算提供商,Kubernetes都为您提供了一种灵活、可移植且可扩展的方式来管理容器化应用程序。本文将深入探讨如何在云计算平台上部署Kubernetes,并为您提供一些实际的示例。
163 1