首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何搭建可用于生产环境的Kubernetes基础设施?

11月14日,我们发布了Pulumi Crosswalk for Kubernetes,其中包括开源工具、库和使用手册,帮助开发人员和操作人员一起将Kubernetes引入他们的组织。这其中囊括了过去一年,我们与组织合作从零开始为他们的基础设施和应用程序工作负载引入Kubernetes的经验教训。我们希望通过以开源的方式发布这些内容,帮助企业在Kubernetes项目中获得成功。

如何将基础设施即代码用于Kubernetes

一年多前,我们启动了使用Pulumi的开源基础设施即代码工具来管理Kubernetes资源的支持。除了Helm 、Charts的整个生态系统之外,你可以在自己选择的语言中使用所有受支持版本的全部Kubernetes对象模型——包括JavaScript、TypeScript和Python。这为新发布的Kubernetes版本提供了100%的API资源兼容和当日支持。

通过利用通用语言,你可以获得丰富的功能,如for循环、函数和类、共享和重用最佳实践的能力(消除复制和粘贴),以及使用你喜欢的工具(包括编辑器、测试框架和静态分析工具)。

这对于我们中任何一个与“YAML或JSON之墙”作斗争的人来说都是令人兴奋的——但这还不是全部。

统一的基础设施即代码方法提供了健壮的交付工作流,不仅支持跨Kubernetes资源管理配置,还支持跨任何集群的底层公有或私有云基础设施,包括AWS、Azure、Google Cloud、vSphere等。

当时,我们没有意识到这种统一的方法会有多么强大。例如,正确地配置一个Amazon EKS集群不仅需要在AWS上编排部署,还需要来回使用Kubernetes资源。我们设计了Pulumi,让你可以使用一个一致的平台和工作流来完成这项工作,从而取代了通常需要集成多个工具的“大量Bash”。

这是一个令人兴奋的开始,我们有许多终端用户和组织,他们很快就找上门来,在我们的帮助下采用Kubernetes。

为什么在生产环境中使用Kubernetes很困难

下面是我们面临的以及我们努力帮助解决的挑战:

Kubernetes基础设施不是一座孤岛。尽管AWS、Azure和GCP提供了托管的Kubernetes服务,但是大多数拥有成熟基础设施的组织发现很难配置和管理集群基础设施。这通常是因为要投入生产应用,就需要将集群连接到许多周围的基础设施——包括IAM、网络、加密服务、私有Docker注册中心等等。特定于kubernets的工具只能帮助解决部分问题并且会创建筒仓。

赋能整个组织非常困难。大多数采用Kubernetes的组织都试图协调“房子的两边”——开发人员和运营人员。基础设施运营团队负责管理集群和底层基础设施,而开发人员则尝试向集群交付应用程序和服务(通常还使用其他公共云服务,如对象存储)。尽管Kubernetes的体系结构非常适合这一点,但是团队很难在基础设施和应用程序交付方面标准化工具、工作流和实践。

第二阶段比第一阶段更难。许多团队决定在Kubernetes上“全力以赴”,结果却发现,保护、扩展和实施Kubernetes比他们想象的要复杂得多。你可以执行零停机升级吗?如何在区域之间执行故障转移?将新的容器镜像从dev提升到staging,再提升到数十个生产集群的速度有多快?

更复杂的是,这些挑战会因为你的目标云环境而有所不同。尽管Kubernetes帮助你标准化了容器计算层,以及扩展负载均衡服务,但是它并没有抽象出云之间的所有基础设施功能,比如IAM、容器注册中心和数据服务。

在过去的一年中,我们与许多客户有过这样的直接接触。我们致力于为客户开发三个特定领域的全套解决方案:

  • 基础设施操作手册
  • 使Kubernetes更便于开发人员使用
  • 大规模交付和可观测性洞察

接下来让我们逐条说明。

开发集群基础设施操作手册

大多数实践者只能自己去寻找Kubernetes基础设施中最困难的问题的解决方案。在帮助数十个客户使用AWS EKS、Azure AKS、谷歌Cloud GKE和Kubernetes内部基础设施进行生产之后,我们决定将最佳实践开发成一套操作手册。这有助于组织避免重复劳动,以及减少安全、可靠性和可维护性方面的潜在缺陷。

这些操作手册涵盖了许多领域,比如包括下面这样的主题:

控制平面。每个Kubernetes集群都有一个由控制器、状态管理和其他集中服务组成的控制平面。每个提供商都提供了创建、部署和管理控制平面的独有方法。

工作节点。每个集群还需要工作节点来实际运行计算。根据你的计算、存储和安全需求,这些节点(通常使用多个节点池)的配置和管理有很大的不同。正确处理这一问题对于在成本和性能之间取得良好的平衡至关重要。

身份标识。所有这些还需要与团队的安全策略集成,包括身份和访问管理(IAM)以及基于角色的访问控制(RBAC)。如果你在AWS上,你无疑想要连接到AWS IAM;如果你在Azure中,你想利用现有的ActiveDirectory设置;如果你在GCP中,你会想要使用GCP IAM;如果你使用的是自定义配置,那就更复杂了。这是在组织内部署Kubernetes的一个重要部分。

集群服务。每个集群都需要部署到集群中的集群范围内的服务,包括性能和监视服务(AWS CloudWatch、Azure日志分析和监视、Datadog、Prometheus等)、服务网格、容器注册中心、CRD和操作人员。

应用程序交付。应用程序需要进行容器化、打包并部署到私有容器注册中心,然后部署到集群,通常是连续不断的。

应用程序服务。除了应用程序本身之外,云原生应用程序通常还需要额外的服务。这包括进入控制器、DNS和证书管理服务等。升级集群。最后,同样重要的是,集群升级是整个操作的重要组成部分。Kubernetes发展很快,所以经常需要升级,但是要自信地部署升级并不总是很容易,特别是当你要考虑零停机和持久化工作负载时。

这种层次结构如下图所示:

我们相信,任何希望在任何公有云中甚或是本地创建可生产使用的基础设施的人,都将受益于这份资料。它也是开源的,所以我们希望在未来几周内与社区合作来改进和完善它。

开发人员如何使用Kubernetes

除了必须翻过YAML这堵墙之外,还需要重复进行大量惯用的Kubernetes配置。事实上,它常常让人感觉手工编写Kubernetes YAML类似于用汇编语言编写软件,而不是用高级语言。

Pulumi公开了全部的Kubernetes API,这意味着你可以使用现代语言实践来驯服这些低级的混乱。但是,在Crosswalk中提供的新的库结构通过消除常见的样板模式将这一问题提升到了另一个层次。

例如,YAML这堵墙:

apiVersion: v1
kind: ConfigMap
data:
  config: very important data
metadata:
  name: app-config
---
apiVersion: v1
kind: Secret
data:
  app-password: JikkMz9mK2hIRDo3
  database-password: Y29uZmlnLmRhdGFiYXNlUGFzc3dvcmQ=
metadata:
  name: app-secrets
type: Opaque
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - env:
            - name: APP_CONFIG_PATH
              value: /app/config
            - name: APP_USER
              value: config.user
            - name: APP_PASSWORD
              valueFrom:
                secretKeyRef:
                  key: app-password
                  name: app-secrets
            - name: APP_DATABASE_PASSWORD
              valueFrom:
                secretKeyRef:
                  key: database-password
                  name: app-secrets
          image: nginx
          imagePullPolicy: Always
          name: nginx
          ports:
            - containerPort: 80
              name: http
          volumeMounts:
            - mountPath: /app/config
              name: app-config-rsg88x4g
      restartPolicy: Always
      volumes:
        - configMap:
            name: app-config
          name: app-config
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector:
    app: nginx
  type: LoadBalancer

提炼出它的精髓,少了许多繁琐和重复:

// 定义应用程序配置和秘密
const configs = new kx.ConfigMap("app-config", {
    data: { "config": "very important data" }
});
const secrets = new kx.Secret("app-secrets", {
    stringData: {
        "app-password": new kx.RandomPassword("app-password"),
        "database-password": config.databasePassword
    }
});
// 定义应用程序Pod.
const appConfigPath = "/app/config";
const appPod = new kx.PodBuilder({
    containers: [{
        image: "app:1.0.0",
        env: {
            "APP_CONFIG_PATH": appConfigPath,
            "APP_USER": config.user,
            "APP_PASSWORD": secrets.asEnvValue("app-password"),
            "APP_DATABASE_PASSWORD": secrets.asEnvValue("database-password"),
        },
        volumeMounts: [
            configs.mount(appConfigPath)
        ],
    }],
});
// 使用之前的Pod定义创建一个Kubernetes部署
const deployment = new kx.Deployment("nginx", {
    spec: appPod.asDeploymentSpec({ replicas: 3 }),
});
// 使用Kubernetes Service通过负载均衡器暴露部署
const service = deployment.createService({
    type: kx.types.ServiceType.LoadBalancer,
});

这些库扩展被设计为与现有的Kubernetes配置共存,这样你就可以逐渐减少复杂性,而结果仍然是熟悉且完整统一的。 除了以这些方式使Kubernetes配置更容易访问之外,我们还看到了应用程序配置的其他好处,这包括:

数据服务。对于我们许多人来说,在Kubernetes中管理持续的工作负载是不值得的。虽然可以管理污染、移除和迁移的复杂过程,但我们的许多客户都依赖于托管的数据存储产品——比如Amazon S3、RDS、Azure Cosmos DB或谷歌的Cloud BigTable——以及Kubernetes无状态计算。使用托管服务带来了扩展、备份和管理等固有的优点,而且不会很麻烦。Pulumi允许你混合使用Kubernetes和公有云基础设施即代码。

容器注册。大多数最终用户需要使用私有容器注册中心来承载应用程序镜像。此外,我们大多数人都希望使用云提供商的原生产品,比如Amazon弹性容器注册中心、Azure容器注册中心或谷歌容器注册中心,因为它集成了IAM。使用Pulumi,与支持应用程序基础设施相比,你不需要单独的容器部署管道。

无服务器。如果你想要使用最好且最经济的无服务器功能,那么你可能想要使用AWS Lambda、Azure函数或谷歌云函数。我们看到终端用户一直在使用无服务器扩展增强基于容器的应用程序。

架构即代码。由于Pulumi将真正的语言用于基础设施即代码,最终用户能够将复杂性抽象并封装成可重用的形式,例如函数和类。这甚至可以帮助你在Kx解决的基本Kubernetes配置挑战之外,将云原生架构中重复出现的模式编成代码。

除此之外,我们一直在努力开发一种新的试验性“观看模式”功能,与上述功能相结合,以一种全新的方式将所有Kubernetes内容展示给你。我们很高兴下周能在KubeCon的展位上展示这个!

如何实现大规模交付?

在掌握了基础设施和应用程序编写的挑战之后,困难就转移到第二阶段及后续的工作中。在这个阶段,组织需要弄清楚如何持续地向不断增加的环境交付变更。

自从去年我们首次发布以来,我们已经添加了许多不同的CI/CD集成,包括对GitLab、Codefresh、Azure DevOps、Octopus Deploy、GitHub Action等等的支持。这使全球范围的交付成为可能。事实上,我们的一个客户不断地部署横跨开发和基础设施运营团队的80个不同的环境。

最后,我们很高兴能够在这个预览版中发布一项新技术、一个新的查询命令和Kubernetes查询库,它利用Pulumi对象模型来请求关于集群及其应用程序的操作查询。这包括“在我的集群中运行了多少个不同版本的MySQL?”,“哪些Pod通过负载平衡服务暴露在了互联网上?”等等。

例如,这个查询显示了集群中不同版本的MySQL:

import * as kq from "@pulumi/query-kubernetes";
// 找出集群中运行的所有不同版本的MySQL
const mySqlVersions = kq
    .list("v1", "Pod")
    .flatMap(pod => pod.spec.containers)
    .map(container => container.image)
    .filter(imageName => imageName.includes("mysql"))
    .distinct();
mySqlVersions.forEach(console.log);

CQL还支持实时流查询,CLI将实时显示查询结果。

原文链接:

https://www.pulumi.com/blog/crosswalk-kubernetes/

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/YAKfd2Z5moVa0ZYqL0ep
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券