本文已超过一年。较旧的文章可能包含过时内容。请检查页面信息自发布以来是否发生变化。

我们如何在 Yahoo! JAPAN 大规模 OpenStack 上设计和运行 Kubernetes

编者注:今天的帖子来自 Yahoo! JAPAN 的基础设施工程团队,讲述了他们如何在 Kubernetes 上运行 OpenStack。经授权,本文已翻译和编辑以符合语境 -- 原文发表在 Yahoo! JAPAN 工程博客上。 

简介
本文概述了 Yahoo! JAPAN 如何在 Google 和 Solinea 的帮助下,构建了一套自动化工具链,实现在 OpenStack 上运行的 Kubernetes 上进行“一键”代码部署。 

我们还将涵盖为确保生产就绪所需的基本安全、网络、存储和性能需求。 

最后,我们将讨论用于构建 CI/CD 流水线的生态系统工具、作为 VM/裸金属部署平台的 Kubernetes,以及 Kubernetes 架构概览,以帮助您设计和部署自己的集群。 

前言
自我们公司在 2012 年开始使用 OpenStack 以来,内部环境迅速变化。我们虚拟化硬件的最初目标已通过 OpenStack 实现。然而,随着云和容器技术的发展,我们需要在各种平台发布服务的能力。本文将提供我们将 OpenStack 上运行的应用移植到 Kubernetes 的案例。

编码生命周期
本项目的目标是根据一个应用代码为所有所需平台创建镜像,并将这些镜像部署到每个平台。例如,当代码注册库中的代码发生变化时,CI(持续集成)工具会创建裸金属镜像、Docker 容器和 VM 镜像,推送到我们的镜像注册库,然后部署到各基础设施平台。

我们在 CI/CD 流水线中使用以下产品

功能产品
代码注册库GitHub Enterprise
CI 工具Jenkins
镜像注册库Artifactory
Bug 跟踪系统JIRA
裸金属平台部署OpenStack Ironic
VM 平台部署OpenStack
容器平台部署Kubernetes

镜像创建。每个镜像创建流程如下图所示。

VM 镜像创建 :

  1. 1. 推送代码到 GitHub
  2. 2. Hook 到 Jenkins master
  3. 3. 在 Jenkins slave 启动 Job 
  4. 4. 检出 Packer 仓库
  5. 5. 运行 Service Job
  6. 6. 通过构建脚本执行 Packer
  7. 7. Packer 启动 OpenStack Glance 的 VM 
  8. 8. 配置 VM 并安装所需应用
  9. 9. 创建快照并注册到 Glance 10.10. 从 Glance 下载新创建的镜像 11.11. 将镜像上传到 Artifactory

裸金属镜像创建

  1. 1. 推送代码到 GitHub
  2. 2. Hook 到 Jenkins master
  3. 3. 在 Jenkins slave 启动 Job 
  4. 4. 检出 Packer 仓库
  5. 5. 运行 Service Job
  6. 6. 通过构建脚本下载基础裸金属镜像
  7. 7. 构建脚本使用 Packer 执行 diskimage-builder 创建裸金属镜像
  8. 8. 将新创建的镜像上传到 Glance
  9. 9. 将镜像上传到 Artifactory

容器镜像创建

  1. 1. 推送代码到 GitHub
  2. 2. Hook 到 Jenkins master
  3. 3. 在 Jenkins slave 启动 Job 
  4. 4. 检出 Dockerfile 仓库
  5. 5. 运行 Service Job
  6. 6. 从 Artifactory 下载基础 Docker 镜像
  7. 7. 如果 Artifactory 中没有 Docker 镜像,则从 Docker Hub 下载
  8. 8. 执行 docker build 并创建镜像 
  9. 9. 将镜像上传到 Artifactory

平台架构。

让我们重点关注容器工作流,了解我们如何使用 Kubernetes 作为部署平台。平台架构如下。

功能产品
基础设施服务OpenStack
容器宿主机CentOS
容器集群管理器Kubernetes
容器网络Project Calico
容器引擎Docker
容器注册库Artifactory
服务注册etcd
源代码管理GitHub Enterprise
CI 工具Jenkins
基础设施供应Terraform
日志Fluentd, Elasticsearch, Kibana
度量Heapster, Influxdb, Grafana
服务监控Prometheus

我们使用 CentOS 作为容器宿主机(OpenStack 实例),并安装 Docker、Kubernetes、Calico、etcd 等等。当然,可以在 Kubernetes 上运行各种容器应用。事实上,我们将 OpenStack 作为其中一个应用运行。没错,在 OpenStack 上的 Kubernetes 上运行 OpenStack。我们目前拥有超过 30 个 OpenStack 集群,管理和运维起来很快就变得困难。因此,我们希望创建一个简单、基础的 OpenStack 集群,为 Kubernetes 提供所需的基本功能,并使我们的 OpenStack 环境更容易管理。

Kubernetes 架构

让我更详细地解释一下 Kubernetes 架构。架构图如下。

|产品 |描述 | |OpenStack Keystone|Kubernetes 认证和授权 | |OpenStack Cinder |Pod(多个容器的集合)使用的外部卷 | |kube-apiserver |通过 REST API 配置和验证 Pod 或 Service(容器中服务访问的定义)等对象| |kube-scheduler |将 Pod 分配给每个节点 | |kube-controller-manager |执行状态管理,管理 Replication Controller | |kubelet |作为 Agent 在每个节点上运行并管理 Pod | |calico |使用 BGP 启用 Pod 间连接 | |kube-proxy |配置 iptable NAT 表以配置 IP 和负载均衡 (ClusterIP) | |etcd |分发 KVS 以存储 Kubernetes 和 Calico 信息 | |etcd-proxy |在每个节点上运行并将客户端请求转发到 etcd 集群|

租户隔离 为了实现类似 OpenStack 的多租户使用,我们利用 OpenStack Keystone 进行认证和授权。

认证 通过 Kubernetes 插件,OpenStack Keystone 可以用于认证。在启动 Kubernetes API server 时添加 Keystone 的 authURL,我们可以使用 OpenStack OS_USERNAME 和 OS_PASSWORD 进行认证。 授权 我们目前使用 Kubernetes Authorization 的 ABAC(Attribute-Based Access Control)模式。我们与咨询公司 Solinea 合作,他们帮助创建了一个工具,将 OpenStack Keystone 用户和租户信息转换为 Kubernetes JSON 策略文件,该文件将 Kubernetes ABAC 用户和 Namespace 信息映射到 OpenStack 租户。然后在启动 Kubernetes API Server 时指定该策略文件。该工具还从租户信息创建 Namespace。这些配置使得 Kubernetes 可以通过 OpenStack Keystone 进行认证并在授权的 Namespace 中操作。 卷和数据持久性 Kubernetes 提供了“持久卷(Persistent Volumes)”子系统,作为 Pod 的持久存储。“持久卷”能够支持云提供商存储,可以通过使用 OpenStack 作为云提供商来利用 OpenStack cinder-volume。 网络 Flannel 和各种网络方案都存在作为 Kubernetes 的网络模型,我们为本项目使用了 Project Calico。Yahoo! JAPAN 推荐构建纯 L3 网络的数据中心,如重分布 ARP 验证或 IP CLOS 网络,Project Calico 与这个方向相符。当我们应用 Flannel 等叠加模型时,我们无法从 Kubernetes 集群外部访问 Pod IP。但 Project Calico 使这成为可能。我们也将 Project Calico 用于后面描述的负载均衡。

在 Project Calico 中,通过在 Kubernetes 每个节点上启动的 BIRD 容器(OSS 路由软件)工作的 BGP 广播生产 IP。默认情况下,它仅在集群内广播。通过设置集群外部的对等路由器,可以从集群外部访问 Pod。 外部服务负载均衡

对于 Kubernetes 的外部服务负载均衡(从集群外部访问服务),有多种选择,例如 NodePort、LoadBalancer 和 Ingress。我们未能找到完全符合我们需求的解决方案。然而,我们找到了一个几乎符合我们需求的解决方案,即使用 Project Calico BGP 广播用于内部服务负载均衡(从集群内部访问服务)的 Cluster IP,从而实现从集群外部的 Layer 4 外部负载均衡。

服务发现

通过使用 SkyDNS 插件,可以在 Kubernetes 中进行服务发现。它作为集群内部服务提供,可以在集群内部像 ClusterIP 一样访问。通过 BGP 广播 ClusterIP,名称解析可以在集群外部工作。结合镜像创建流程和 Kubernetes,我们构建了以下工具链,使得从代码推送到底部署变得容易。

总结

总而言之,通过结合镜像创建流程和 Kubernetes,Yahoo! JAPAN 在 GoogleSolinea 的帮助下,成功构建了一个自动化工具链,使得从代码推送到部署变得容易,同时考虑了多租户、认证/授权、存储、网络、服务发现以及其他生产部署所需的因素。我们希望您对用于构建 CI/CD 流水线的生态系统工具、作为 VM/裸金属部署平台的 Kubernetes 以及 Kubernetes 架构概览的讨论对您设计和部署自己的集群有所帮助。感谢所有帮助本项目的人。--Norifumi Matsuya、Hirotaka Ichikawa、Masaharu Miyamoto 和 Yuta Kinoshita。 经授权,本文已翻译和编辑以符合语境 -- 原文发表在 Yahoo! JAPAN 工程博客上,该博客是专注于 Kubernetes 系列文章的一部分。