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

我们在雅虎日本如何大规模地在 OpenStack 上构建和运行 Kubernetes

编者按:今天的文章由 Yahoo! JAPAN 的基础设施工程团队撰写,介绍了他们在 Kubernetes 上运行 OpenStack 的方式。这篇文章经过翻译和编辑,并获得了许可,以更好地理解上下文——最初发布在 Yahoo! JAPAN 工程博客上。

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

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

最后,我们将讨论用于构建 CI/CD 管道的生态系统工具、作为虚拟机/裸机部署平台的 Kubernetes,以及 Kubernetes 架构的概述,以帮助您设计和部署自己的集群。

前言
自从我们公司在 2012 年开始使用 OpenStack 以来,我们的内部环境发生了快速变化。我们最初使用 OpenStack 实现硬件虚拟化的目标已经达成。然而,由于云和容器技术的进步,我们需要在各种平台上启动服务的能力。本文将提供我们将运行在 OpenStack 上的应用程序移植到 Kubernetes 的示例。

代码生命周期
这个项目的目标是从一个应用程序代码为所有需要的平台创建镜像,并将这些镜像部署到每个平台上。例如,当在代码注册表中更改代码时,CI(持续集成)工具会创建裸机镜像、Docker 容器和虚拟机镜像,并将其推送到我们的镜像注册表中,然后部署到每个基础设施平台上。

我们在 CICD 管道中使用以下产品

功能产品
代码注册表GitHub 企业版
CI 工具Jenkins
镜像注册表Artifactory
缺陷跟踪系统JIRA
部署裸机平台OpenStack Ironic
部署虚拟机平台OpenStack
部署容器平台Kubernetes

镜像创建。下一个图表显示了每个镜像创建工作流程。

虚拟机镜像创建 :

  1. 1.将代码推送到 GitHub
  2. 2.挂钩到 Jenkins 主服务器
  3. 3.在 Jenkins 从服务器上启动作业
  4. 4.检出 Packer 存储库
  5. 5.运行服务作业
  6. 6.通过构建脚本执行 Packer
  7. 7.Packer 启动用于 OpenStack Glance 的虚拟机
  8. 8.配置虚拟机并安装所需的应用程序
  9. 9.创建快照并注册到 glance 10.10.从 Glance 下载新创建的镜像 11.11.将镜像上传到 Artifactory

裸机镜像创建

  1. 1.将代码推送到 GitHub
  2. 2.挂钩到 Jenkins 主服务器
  3. 3.在 Jenkins 从服务器上启动作业
  4. 4.检出 Packer 存储库
  5. 5.运行服务作业
  6. 6.通过构建脚本下载基本裸机镜像
  7. 7.构建脚本使用 Packer 执行 diskimage-builder 以创建裸机镜像
  8. 8.将新创建的镜像上传到 Glance
  9. 9.将镜像上传到 Artifactory

容器镜像创建

  1. 1.将代码推送到 GitHub
  2. 2.挂钩到 Jenkins 主服务器
  3. 3.在 Jenkins 从服务器上启动作业
  4. 4.检出 Dockerfile 存储库
  5. 5.运行服务作业
  6. 6.从 Artifactory 下载基本 docker 镜像
  7. 7.如果在 Artifactory 中找不到 docker 镜像,则从 Docker Hub 下载
  8. 8.执行 docker build 并创建镜像
  9. 9.将镜像上传到 Artifactory

平台架构。

让我们专注于容器工作流程,以了解我们如何将 Kubernetes 用作部署平台。此平台架构如下所示。

功能产品
基础设施服务OpenStack
容器主机CentOS
容器集群管理器Kubernetes
Kubernetes容器网络
Project Calico容器引擎
DockerArtifactory
容器注册表Artifactory
服务注册表GitHub 企业版
etcdJenkins
源代码管理GitHub 企业版
CI 工具Jenkins
基础设施配置Terraform
日志记录Fluentd、Elasticsearch、Kibana

指标

Heapster、Influxdb、Grafana

服务监控

Prometheus

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

Kubernetes 架构

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

| 产品 | 描述 | | OpenStack Keystone | Kubernetes 身份验证和授权 | | OpenStack Cinder | Pod(多个容器的组合)使用的外部卷 | | kube-apiserver | 通过 REST API 配置和验证 Pod 或 Services 等对象(容器中服务访问的定义)| | kube-scheduler | 将 Pod 分配到每个节点 | | kube-controller-manager | 执行状态管理,管理复制控制器 | | kubelet | 在每个节点上作为代理运行并管理 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 服务器时添加 Keystone 的 authURL,我们可以使用 OpenStack OS_USERNAME 和 OS_PASSWORD 进行身份验证。 授权 我们目前使用 Kubernetes 授权的 ABAC(基于属性的访问控制)模式。我们与咨询公司 Solinea 合作,该公司帮助创建了一个实用程序,用于将 OpenStack Keystone 用户和租户信息转换为 Kubernetes JSON 策略文件,该文件将 Kubernetes ABAC 用户和命名空间信息映射到 OpenStack 租户。然后在启动 Kubernetes API 服务器时指定该策略文件。此实用程序还会根据租户信息创建命名空间。这些配置使 Kubernetes 能够使用 OpenStack Keystone 进行身份验证,并在授权的命名空间中运行。 卷和数据持久性 Kubernetes 提供“持久卷”子系统,该子系统用作 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 广播用于内部服务负载均衡(从集群内部访问服务)的集群 IP 的解决方案,这几乎满足了我们的要求,从而可以在集群外部的第 4 层实现外部负载均衡。