Bazel - 在 Monorepo 中构建、推送、部署 Docker 容器到 Kubernetes

flo*_*olu 7 docker kubernetes bazel monorepo google-cloud-build

我有一个带有一些后端(Node.js)和前端(Angular)服务的 monorepo 。目前我的部署过程如下所示:

  1. 检查测试是否通过
  2. 为我的服务构建 docker 镜像
  3. 将 docker 镜像推送到容器注册表
  4. 将更改应用于Kubernetes集群(GKE)与kubectl

我的目标是在BazelCloud Build的帮助下自动化所有这些步骤。但我真的很难开始使用 Bazel:

为了使它工作,我可能需要为我自己的包/服务添加一个WORKSPACE包含外部依赖项的文件和多个BUILD文件?我需要实际实施方面的帮助:

  1. 如何使用 Bazel 构建我的 Dockerfiles?
  2. 如何将这些图像推送到注册表(最好是GCR)?
  3. 如何自动将更改应用到 Google Kubernetes Engine?
  4. 如何将此工具链与 Google Cloud Build 集成?

有关该项目的更多信息

我整理了一个小样本 monorepo来展示我的用例

结构

??? kubernetes
??? packages
?   ??? enums
?   ??? utils
??? services
    ??? gateway
Run Code Online (Sandbox Code Playgroud)

一般的

  • Gateway服务取决于enumsutils
  • 一切都是用打字稿写的
  • 每个服务/包都是一个 Node 模块
  • 文件夹Dockerfile里面有一个gateway,我想建
  • Kubernetes 配置位于kubernetes文件夹中。
  • 请注意,我不想发布任何npm包!

red*_*cky 6

我们想要的是一个便携式 Docker 容器,它包含我们的 Angular 应用程序及其服务器以及它需要的任何机器映像,我们可以在任何云提供商上提供它,我们将创建一个完整的管道以进行增量。“Docker 规则”很快。本质上,它通过添加新的 Docker 层来提供工具,因此您对应用程序所做的更改是唯一通过线路发送到云主机的内容。此外,由于 Docker 镜像带有 SHA 标记,我们只重新部署更改的镜像。为了管理我们的生产部署,我们将使用 Kubernetes,为此也存在 Bazel 规则。据我所知,使用 Bazel 从 Dockerfile 构建 docker 镜像是不可能的,因为由于 Dockerfile 的非密封性,设计不允许这样做。(来源: https://blog.bazel.build/2015/07/28/docker_build.html )

作为源代码的一部分所做的更改将部署在 Kubernetes 集群中,这是使用 Bazel 实现以下目标的一种方法。

  1. 我们必须将 Bazel 置于监视模式,Deploy replace 告诉 Kubernetes 集群更新应用程序的部署版本。一种。

    命令:ibazel 运行:deploy.replace

  2. 如果有任何源代码更改,请在 angular 中进行。

  3. Bazel 仅以增量方式重新构建依赖于更改文件的构建图部分,在这种情况下,包括更改的 ng_module、包含该模块的 Angular 应用程序以及保存服务器的 Docker nodejs_image。正如我们要求更新部署一样,构建完成后,它将新的 Docker 容器推送到 Google Container Registry,Kubernetes Engine 实例开始为其提供服务。Bazel 了解构建图,它只会重新构建更改的内容。

这里有一些代码段级别的提示,它们实际上可以提供帮助。

工作区文件:

创建一个 Bazel 工作区文件,WORKSPACE 文件告诉 Bazel 这个目录是一个“工作区”,就像一个项目根。下面列出了要在 Bazel 工作区中完成的事情。• 工作区的名称应与我们发布的 npm 包匹配,以便在引用已发布的包时这些导入也有意义。• 使用“http_archive”提及Bazel 工作区中的所有规则,当我们使用角度和节点时,应提及rxjs、angular、angular_material、io_bazel_rules_sass、angular-version、build_bazel_rules_typescript、build_bazel_rules_nodejs 的规则。• -接下来我们必须使用“load”加载依赖项。sass_repositories、ts_setup_workspace、angular_material_setup_workspace、ng_setup_workspace, • 也加载 docker 基础镜像,

“BUILD.bazel”文件。

• 加载已下载的 ng_module 模块、项目模块等。 • 使用“default_visibility”设置默认可见性 • 如果您有任何 Jasmine 测试,请使用 ts_config 并提及其中的依赖关系。• ng_module(此处应提及资产、来源和依赖项) • 如果您有任何延迟加载脚本,请将其作为包的一部分提及 • 提及 web_package 中的根目录。• 最后提及数据和欢迎页面/默认页面。

示例片段:

load("@angular//:index.bzl", "ng_module")
ng_module(
    name = "src",
    srcs = glob(["*.ts"]),
    tsconfig = ":tsconfig.json",
    deps = ["//src/hello-world"],
)
load("@build_bazel_rules_nodejs//:future.bzl", "rollup_bundle")
rollup_bundle(
  name = "bundle",
  deps = [":src"]
  entry_point = "angular_bazel_example/src/main.js"
)
Run Code Online (Sandbox Code Playgroud)

使用下面的命令构建捆绑包。

bazel build :bundle
Run Code Online (Sandbox Code Playgroud)

管道:通过詹金斯

通过 Jenkins 创建管道并运行管道有几个阶段。每个阶段执行单独的任务,但在我们的例子中,我们使用阶段使用 BaZel Run 发布图像。

pipeline {
  agent any
  stages {
    stage('Publish image') {
      steps {
        sh 'bazel run //src/server:push'
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

笔记 :

bazel run :dev.apply
Run Code Online (Sandbox Code Playgroud)
  1. Dev Apply 映射到 kubectl apply,这将创建或替换现有配置。(有关更多信息,请参阅 kubectl 文档。)这将应用已解析的模板,其中包括重新发布图像。此操作旨在成为快速迭代开发(重建/重新发布/重新部署)的主力。

  2. 如果您想使用 workpsace 文件拉取容器,请使用以下标签

    container_pull( name = "debian_base",digest = "sha256:**", registry = "gcr.io", repository = "google-appengine/debian9", )

如果使用 GKE,则需要安装 gcloud sdk,因为我们使用的是 GKE(Google Contianer Enginer),可以使用以下方法对其进行身份验证。

gcloud container clusters get-credentials <CLUSTER NAME>
Run Code Online (Sandbox Code Playgroud)

Deploymnet 对象应以以下格式提及:

load("@io_bazel_rules_k8s//k8s:object.bzl", "k8s_object")

k8s_object(
  name = "dev",
  kind = "deployment",
  template = ":deployment.yaml",
  images = {
    "gcr.io/rules_k8s/server:dev": "//server:image"
  },
)
Run Code Online (Sandbox Code Playgroud)

来源: