kubernetes中文手册
  • 前言
    • 序言
  • 云原生
    • 云原生(Cloud Native)的定义
    • 云原生的设计哲学
    • Kubernetes 的诞生
    • Kubernetes 与云原生应用概览
    • 云原生应用之路 —— 从 Kubernetes 到云原生
    • 定义云原生应用
      • OAM
        • Workload
        • Component
        • Trait
        • Application Scope
        • Application Configuration
      • Crossplane
    • 云原生编程语言
      • 云原生编程语言 Ballerina
      • 云原生编程语言 Pulumi
    • 云原生的未来
  • 快速入门
    • 云原生新手入门指南
    • Play with Kubernetes
    • 快速部署一个云原生本地实验环境
    • 使用 Rancher 在阿里云上部署 Kubenretes 集群
  • 概念与原理
    • Kubernetes 架构
      • 设计理念
      • Etcd 解析
      • 开放接口
        • CRI - Container Runtime Interface(容器运行时接口)
        • CNI - Container Network Interface(容器网络接口)
        • CSI - Container Storage Interface(容器存储接口)
      • 资源对象与基本概念解析
    • Pod 状态与生命周期管理
      • Pod 概览
      • Pod 解析
      • Init 容器
      • Pause 容器
      • Pod 安全策略
      • Pod 的生命周期
      • Pod Hook
      • Pod Preset
      • Pod 中断与 PDB(Pod 中断预算)
    • 集群资源管理
      • Node
      • Namespace
      • Label
      • Annotation
      • Taint 和 Toleration(污点和容忍)
      • 垃圾收集
    • 控制器
      • Deployment
      • StatefulSet
      • DaemonSet
      • ReplicationController 和 ReplicaSet
      • Job
      • CronJob
      • Horizontal Pod Autoscaling
        • 自定义指标 HPA
      • 准入控制器(Admission Controller)
    • 服务发现与路由
      • Service
      • 拓扑感知路由
      • Ingress
        • Traefik Ingress Controller
      • Kubernetes Service API
        • Service API 简介
    • 身份与权限控制
      • ServiceAccount
      • 基于角色的访问控制(RBAC)
      • NetworkPolicy
    • 网络
      • Kubernetes 中的网络解析 —— 以 flannel 为例
      • Kubernetes 中的网络解析 —— 以 calico 为例
      • 具备 API 感知的网络和安全性管理开源软件 Cilium
        • Cilium 架构设计与概念解析
    • 存储
      • Secret
      • ConfigMap
        • ConfigMap 的热更新
      • Volume
      • 持久化卷(Persistent Volume)
      • Storage Class
      • 本地持久化存储
    • 集群扩展
      • 使用自定义资源扩展 API
      • 使用 CRD 扩展 Kubernetes API
      • Aggregated API Server
      • APIService
      • Service Catalog
    • 多集群管理
      • 多集群服务 API(Multi-Cluster Services API)
      • 集群联邦(Cluster Federation)
    • 资源调度
      • 服务质量等级(QoS)
  • 用户指南
    • 用户指南概览
    • 资源对象配置
      • 配置 Pod 的 liveness 和 readiness 探针
      • 配置 Pod 的 Service Account
      • Secret 配置
      • 管理 namespace 中的资源配额
    • 命令使用
      • Docker 用户过渡到 kubectl 命令行指南
      • kubectl 命令概览
      • kubectl 命令技巧大全
      • 使用 etcdctl 访问 Kubernetes 数据
    • 集群安全性管理
      • 管理集群中的 TLS
      • kubelet 的认证授权
      • TLS Bootstrap
      • 创建用户认证授权的 kubeconfig 文件
      • IP 伪装代理
      • 使用 kubeconfig 或 token 进行用户身份认证
      • Kubernetes 中的用户与身份认证授权
      • Kubernetes 集群安全性配置最佳实践
    • 访问 Kubernetes 集群
      • 访问集群
      • 使用 kubeconfig 文件配置跨集群认证
      • 通过端口转发访问集群中的应用程序
      • 使用 service 访问群集中的应用程序
      • 从外部访问 Kubernetes 中的 Pod
      • Cabin - Kubernetes 手机客户端
      • Lens - Kubernetes IDE/桌面客户端
      • Kubernator - 更底层的 Kubernetes UI
    • 在 Kubernetes 中开发部署应用
      • 适用于 Kubernetes 的应用开发部署流程
      • 迁移传统应用到 Kubernetes 中 —— 以 Hadoop YARN 为例
      • 使用 StatefulSet 部署用状态应用
  • 最佳实践
    • 最佳实践概览
    • 在 CentOS 上部署 Kubernetes 集群
      • 创建 TLS 证书和秘钥
      • 创建 kubeconfig 文件
      • 创建高可用 etcd 集群
      • 安装 kubectl 命令行工具
      • 部署 master 节点
      • 安装 flannel 网络插件
      • 部署 node 节点
      • 安装 kubedns 插件
      • 安装 dashboard 插件
      • 安装 heapster 插件
      • 安装 EFK 插件
    • 生产级的 Kubernetes 简化管理工具 kubeadm
      • 使用 kubeadm 在 Ubuntu Server 16.04 上快速构建测试集群
    • 服务发现与负载均衡
      • 安装 Traefik ingress
      • 分布式负载测试
      • 网络和集群性能测试
      • 边缘节点配置
      • 安装 Nginx ingress
      • 安装配置 DNS
        • 安装配置 Kube-dns
        • 安装配置 CoreDNS
    • 运维管理
      • Master 节点高可用
      • 服务滚动升级
      • 应用日志收集
      • 配置最佳实践
      • 集群及应用监控
      • 数据持久化问题
      • 管理容器的计算资源
    • 存储管理
      • GlusterFS
        • 使用 GlusterFS 做持久化存储
        • 使用 Heketi 作为 Kubernetes 的持久存储 GlusterFS 的 external provisioner
        • 在 OpenShift 中使用 GlusterFS 做持久化存储
      • GlusterD-2.0
      • Ceph
        • 用 Helm 托管安装 Ceph 集群并提供后端存储
        • 使用 Ceph 做持久化存储
        • 使用 rbd-provisioner 提供 rbd 持久化存储
      • OpenEBS
        • 使用 OpenEBS 做持久化存储
      • Rook
      • NFS
        • 利用 NFS 动态提供 Kubernetes 后端存储卷
    • 集群与应用监控
      • Heapster
        • 使用 Heapster 获取集群和对象的 metric 数据
      • Prometheus
        • 使用 Prometheus 监控 Kubernetes 集群
        • Prometheus 查询语言 PromQL 使用说明
      • 使用 Vistio 监控 Istio 服务网格中的流量
    • 分布式追踪
      • OpenTracing
    • 服务编排管理
      • 使用 Helm 管理 Kubernetes 应用
      • 构建私有 Chart 仓库
    • 持续集成与发布
      • 使用 Jenkins 进行持续集成与发布
      • 使用 Drone 进行持续集成与发布
    • 更新与升级
      • 手动升级 Kubernetes 集群
      • 升级 dashboard
    • 扩展控制器
      • OpenKruise
        • 原地升级
    • 安全策略
      • 开放策略代理(OPA)
      • 云原生安全
  • 服务网格
    • 服务网格(Service Mesh)
    • 企业级服务网格架构
      • 服务网格基础
      • 服务网格技术对比
      • 服务网格对比 API 网关
      • 采纳和演进
      • 定制和集成
      • 总结
    • Istio
      • 使用 Istio 前需要考虑的问题
      • Istio 中 sidecar 的注入规范及示例
      • 如何参与 Istio 社区及注意事项
      • Istio 免费学习资源汇总
      • Sidecar 的注入与流量劫持
      • Envoy Sidecar 代理的路由转发
      • Istio 如何支持虚拟机
      • Istio 支持虚拟机的历史
    • Envoy
      • Envoy 的架构与基本术语
      • Envoy 作为前端代理
      • Envoy mesh 教程
  • 领域应用
    • 领域应用概览
    • 微服务架构
      • 微服务中的服务发现
      • 使用 Java 构建微服务并发布到 Kubernetes 平台
        • Spring Boot 快速开始指南
    • 大数据
      • Spark 与 Kubernetes
        • Spark standalone on Kubernetes
        • 运行支持 Kubernetes 原生调度的 Spark 程序
    • Serverless 架构
      • 理解 Serverless
      • FaaS(函数即服务)
        • OpenFaaS 快速入门指南
      • Knative
    • 边缘计算
    • 人工智能
    • 可观察性
  • 开发指南
    • 开发指南概览
    • SIG 和工作组
    • 开发环境搭建
      • 本地分布式开发环境搭建(使用 Vagrant 和 Virtualbox)
    • 单元测试和集成测试
    • client-go 示例
      • client-go 中的 informer 源码分析
    • Operator
      • operator-sdk
    • kubebuilder
      • 使用 kubebuilder 创建 operator 示例
    • 高级开发指南
    • 社区贡献
    • Minikube
  • 社区及生态
    • 云原生计算基金会(CNCF)
      • CNCF 章程
      • CNCF 特别兴趣小组(SIG)说明
      • 开源项目加入 CNCF Sandbox 的要求
      • CNCF 中的项目治理
      • CNCF Ambassador
    • 认证及培训
      • 认证 Kubernetes 服务提供商(KCSP)说明
      • 认证 Kubernetes 管理员(CKA)说明
  • 附录
    • 附录说明
    • Kubernetes 中的应用故障排查
    • Kubernetes 相关资讯和情报链接
    • Docker 最佳实践
    • Kubernetes 使用技巧
    • Kubernetes 相关问题记录
    • Kubernetes 及云原生年度总结及展望
      • Kubernetes 与云原生 2017 年年终总结及 2018 年展望
      • Kubernetes 与云原生 2018 年年终总结及 2019 年展望
    • CNCF 年度报告解读
      • CNCF 2018 年年度报告解读
      • CNCF 2020 年年度报告解读
由 GitBook 提供支持
在本页
  • 为什么要支持虚拟机?
  • Istio 支持虚拟机的历史
  • Istio mesh 扩张
  • 新增资源抽象
  • 智能 DNS 代理
  • 总结
  1. 服务网格
  2. Istio

Istio 支持虚拟机的历史

上一页Istio 如何支持虚拟机下一页Envoy

最后更新于3年前

Istio 1.8 新增了 WorkloadGroup 及,这使得如虚拟机这样的非 Kubernetes 工作负载可以在 Istio 中成为像 Pod 一样的一等公民。

不论有没有为虚拟机安装 sidecar,虚拟机通常情况下无法直接访问 Kubernetes 集群中的 DNS 服务器以解析 Kubernetes 服务的 Cluster IP 的(虽然你也许可以通过一些黑客的手段做到),这是在 Istio 中集成虚拟的最后一块短板,终于在 Istio 1.8 中完成了突破。

为什么要支持虚拟机?

在我们将应用在迁移到云原生架构,不断容器化的过程中,将经历三个阶段,如下图所示。

  • 阶段一:应用全部部署在虚拟机上

  • 阶段二:应用既部署在虚拟机上也部署在容器里,正在从虚拟机向容器中迁移,并使用 Kubernetes 管理容器

  • 阶段三:所有的应用优先部署在容器里,使用 Kubernetes 管理容器,使用 Istio 管理应用间的通信

上图仅是对以上三个阶段的最简化描述,实际上还会有多混合云、多机房、多集群等情况,且阶段三只是个理想化的阶段,容器和虚拟机将是长期共存的,但是容器化趋势不变。

在阶段二中,人们通常会将新业务和少量应用率先实现容器化,并部署到 Kubernetes 中,在应用尚未完全实现容器化的时候,处于过度状态时会遇到很多问题,如何让应用与部署在虚拟机中的服务交互?虚拟机如何访问容器中的服务?在服务迁移的过程中如何保证稳定无缝?是否可以将容器和虚拟机纳入一个统一的控制平面来管理?Istio 从开源初期就考虑并着手解决这一问题。

Istio 支持虚拟机的历史

Istio 对于虚拟机的支持是个漫长的过程,堪称是一部奥德赛。

Istio mesh 扩张

  • 虚拟机必须可以通过 IP 地址直接访问到应用的 Pod,这就要求容器与 VM 之间通过 VPC 或者 VPN 建立扁平网络,虚拟机不需要访问 Cluster IP,直接对服务的 Endpoint 端点访问即可。

  • 虚拟机必须可以访问到 Istio 的控制平面服务(Pilot、Mixer、CA,现在已正整合为 Istiod),可以通过在 Istio Mesh 中部署负载均衡器将控制平面端点暴露给虚拟机。

  • (可选)虚拟机可以访问到 Mesh 内部的(部署在 Kubernetes 中)的 DNS server。

集成虚拟机的步骤如下:

  1. 为 Istio 控制平面服务及 Kubernetes 集群的 DNS 服务创建 Internal 负载均衡器;

  2. 生成 Istio Service CIDR、Service Account token、安全证书、Istio 控制平面服务的 IP(通过 Internal 负载均衡器暴露出来的 IP)的配置文件并发送给虚拟机;

  3. (可选)在虚拟机中安装、配置并启动 Istio 的组件、dnsmaq(用于DNS 发现),此时虚拟机可以使用 FQDN 访问 mesh 中的服务了,这一步是为了保证虚拟机可以正确解析出 mesh 中服务的 Cluster IP;

  4. 若要在虚拟机中运行服务,需要配置 sidecar,新增需要拦截的 inbound 端口,然后重启 istio,还需要运行 istioctl 为服务注册

下图展示的从集成虚拟机到在 mesh 中访问虚拟机中服务的详细流程。

  1. DNS 被虚拟机中部署的 dnsmasq 劫持,这使得它可以正确的获取 Istio 服务、Kubernetes 内置 DNS 的端点 IP;

  2. 访问 Kubernetes 的内置 DNS 服务(该服务已通过 Internal 负载均衡器暴露到集群外,可以直接访问);

  3. 返回 productpage.bookinfo.svc.cluster.local 被解析出来的 Cluster IP,注意该 IP 地址无法直接访问,但是如果无法被 DNS 解析的话将导致 VM 对该服务的请求失败;

  4. 虚拟机对 mesh 中服务的访问被 sidecar proxy 劫持;

  5. 要想在 mesh 中访问 VM 中的服务,需要使用 istioctl register 命令手动将 VM 中的服务添加到 mesh 中,这本质上是将 VM 中的服务,注册到 Kubernetes 中的 service 和 endpoint;

  6. mesh 中的服务可以使用 VM 注册的服务名称(FQDN,例如 mysql.vm.svc.cluster.local)来访问;

Istio 1.5 中增加了 istioctl experimental add-to-mesh 命令,可以将虚拟机中的服务添加到 mesh 中,其功能与 istioctl register 一样。

新增资源抽象

下面是虚拟机与 Kubernetes 中负载的资源抽象层级对比。

对比项
Kubernetes
虚拟机

基础调度单位

Pod

WorkloadEntry

编排组合

Deployment

WorkloadGroup

服务注册与发现

Service

ServiceEntry

从上面的图表中我们可以看到,对于虚拟机工作负载是可以与 Kubernetes 中的负载一一对对应的。

通过配置虚拟机本地 /etc/hosts 访问 mesh 内服务的流程,如下图所示。

  1. 将虚拟机中的服务注册到 mesh 中;

  2. 将要访问的服务的域名、Cluster IP 对手动写入虚拟机本地的 /etc/hosts 文件中;

  3. 虚拟机获得访问服务的 Cluster IP;

  4. 流量被 sidecar proxy 拦截并解析出要访问的服务的端点地址;

  5. 访问服务的指定端点;

在 Kubernetes 中我们一般使用 Service 对象来实现服务的注册和发现,每个服务都有一个独立的 DNS 名称,应用程序可以使用服务名称来互相调用。我们可以使用 ServiceEntry 将虚拟机中的服务注册到 Istio 的服务注册表中,但是在 Kubernetes 集群中的 DNS server 无法对 mesh 外部暴露的情况下,虚拟机无法访问 Kubernetes 集群中的 DNS 服务以获取服务的 Cluster IP,从而导致虚拟机访问 mesh 中的服务失败。如果能在虚拟机中增加一个 sidecar 可以透明地拦截 DNS 请求,可获取 mesh 内所有服务的 ClusterIP,类似于图一中的 dnsmasq 的角色,这样不就可以解决问题了吗?

智能 DNS 代理

DNS proxy 是用 Go 编写的 Istio sidecar 代理。Sidecar 上的 Istio agent 将附带一个由 Istiod 动态编程的缓存 DNS 代理。来自应用程序的 DNS 查询会被 pod 或 VM 中的 Istio 代理透明地拦截和服务,该代理会智能地响应 DNS 查询请求,可以实现虚拟机到服务网格的无缝多集群访问。

至此,Istio 1.8 中引入的 WordloadGroup 及智能 DNS 代理,补足了 Istio 对虚拟机支持的最后一块短板,使得部署在虚拟机中的遗留应用可以跟 Kubernetes 中的 Pod 一样完全等同看待。

总结

Istio 从 0.2 版本开始通过 将虚拟机加入的 Mesh 中,但是需要满足以下前提条件:

因为 proxy 已连接 Istio 控制平面,可通过 xDS 查询到该服务的端点,因此流量将被转发到其中的一个端点。关于这一步的详细过程请参考 ;

以上 Istio 对虚拟机支持的方式一直延续到 Istio 1.0,在 Istio 1.1 的时候引入了新的 API ,使用它可以在 Istio 的内部服务注册表中添加额外的条目,这样 mesh 中的服务就可以访问/路由到这些手动指定的服务了,不再需要运行 istioctl register 命令,而且该命令在 Istio 1.9 中将被废弃。

Istio 从 开始在中引入了新的资源类型 ,用以将虚拟机进行抽象,使得虚拟机在加入 mesh 后可以作为与 Kubernetes 中的 Pod 等同的负载,具备流量管理、安全管理、可视化等能力。通过 WorkloadEntry 可以简化虚拟机的网格化配置过程。WorkloadEntry 对象可以根据服务条目中指定的标签选择器选择多个工作负载条目和 Kubernetes pod。

Istio 1.8 中增加了 的资源对象,它提供了一个规范,可以同时包括虚拟机和 Kubernetes 工作负载,旨在模仿现有的用于 Kubernetes 工作负载的 sidecar 注入和部署规范模型来引导 Istio 代理。

此时看似一切都比较完美了,但是直接将 Kubernetes 集群中的 DNS server 暴露出来会带来很大的,因此我们一般手动将虚拟机需要访问的服务的域名和 Cluster IP 对写到本机的 /etc/hosts 中,但是对于一个节点数量庞大的分布式集群来说,这种做法又有些不现实。

Istio 1.8 中引入了,虚拟机访问 mesh 内服务无需再配置 /ect/hosts,如下图所示。

在这部 Istio 支持虚拟机的奥德赛中,我们可以看到:从最初的将 mesh 中的 DNS server 暴露给外部,在虚拟机中安装配置 dnsmasq,到最后的使用智能 DNS 代理,并使用 WorkloadEntry、WorkloadGroup 和 ServiceEntry 等资源抽象,逐步实现了虚拟机和 pod 的统一管理。本文仅仅是针对单集群的情况,在实际的生产中使用还远远不够,我们还需要处理安全、多集群、多租户等诸多问题,欢迎关注 Tetrate 的旗舰产品 了解更多关于 Istio 应用在生产上的最佳实践。

Istio Mesh Expansion
Istio Handbook 中的 sidecar 流量路由机制分析 一节
ServiceEntry
1.6 版本
流量管理
WorkloadEntry
WorkloadGroup
安全风险
智能 DNS 代理
Tetrate Service Bridge
智能 DNS 代理
云原生应用的三个阶段
图一:从集成虚拟机到在 mesh 中访问虚拟机中服务的详细流程
图二:通过配置虚拟机本地 /etc/hosts 访问 mesh 内服务的流程
图三:引入了智能 DNS 代理后虚拟机访问 mesh 内服务的流程