Bazel - 在 Monorepo 中构建、推送、部署 Docker 容器到 Kubernetes
Bazel - Build, Push, Deploy Docker Containers to Kubernetes within Monorepo
我有一个带有一些后端 (Node.js) and frontend (Angular) 服务的 monorepo。目前我的部署过程是这样的:
我的目标是在 Bazel and Cloud Build 的帮助下自动执行所有这些步骤。但我真的很难开始使用 Bazel:
为了让它工作,我可能需要添加一个 WORKSPACE
文件和我自己的 packages/services 的外部依赖项和多个 BUILD
文件? 我需要实际实施方面的帮助:
- 如何使用 Bazel 构建我的 Dockerfile?
- 如何将这些图像推送到注册表中(最好是 GCR)?
- 如何自动将更改应用到 Google Kubernetes Engine?
- 如何将此工具链与 Google Cloud Build 集成?
有关该项目的更多信息
I've put together a tiny sample monorepo to showcase my use-case
结构
├── kubernetes
├── packages
│ ├── enums
│ ├── utils
└── services
├── gateway
一般
Gateway
服务依赖于 enums
和 utils
- 一切都是用 Typescript 写的
- 每个 service/package 都是一个节点模块
gateway
文件夹里面有个Dockerfile
,我要建
- Kubernetes 配置位于
kubernetes
文件夹中。
- 请注意,我不想发布任何
npm
个包!
我们想要的是一个便携式 Docker 容器,其中包含我们的 Angular 应用程序及其服务器以及它需要的任何机器映像,我们可以在任何云提供商上启动,我们将要创建一个完整的管道是增量的。 “Docker 规则”很快。从本质上讲,它通过添加新的 Docker 层来提供工具,因此您对应用程序所做的更改是唯一通过网络发送到云主机的内容。此外,由于 Docker 图像使用 SHA 标记,我们仅重新部署已更改的图像。为了管理我们的生产部署,我们将使用 Kubernetes,据我所知,Bazel 规则还 exist.Build docker 来自 Docker 文件的图像使用 Bazel 是不可能的,因为
由于 Docker 文件的非密封性质,它在设计上是不允许的。(来源:
https://blog.bazel.build/2015/07/28/docker_build.html)
作为源代码的一部分所做的更改将部署在 Kubernetes 集群中,这是使用 Bazel 实现以下目标的一种方法。
我们必须将 Bazel 置于监视模式,Deploy replace 告诉 Kubernetes 集群更新已部署的应用程序版本。
一.
命令:ibazel 运行:deploy.replace
如果有任何源代码更改,请在 angular.
中进行
Bazel 仅增量地重新构建依赖于已更改文件的构建图的部分,在本例中,包括已更改的 ng_module、Angular 包含该模块的应用程序,以及包含服务器的 Docker nodejs_image。正如我们要求更新部署一样,构建完成后,它将新的 Docker 容器推送到 Google Container Registry,Kubernetes Engine 实例开始为其提供服务。 Bazel 了解构建图,它只会重新构建更改的内容。
这里有一些 Snippet 级别的提示,可以提供实际帮助。
工作空间文件:
创建一个Bazel工作区文件,WORKSPACE文件告诉Bazel这个目录是一个“工作区”,就像一个项目根目录。下面列出了在 Bazel 工作区内要做的事情。
• 工作区的名称应该与我们发布的npm 包相匹配,以便这些导入在引用已发布的包时也有意义。
• 使用“http_archive”提及 Bazel 工作区中的所有规则,因为我们正在使用 angular 和节点,因此应提及 rxjs、angular、angular_material、 io_bazel_rules_sass,angular-版本,build_bazel_rules_typescript,build_bazel_rules_nodejs。
• -接下来我们必须使用“load”加载依赖项。 sass_repositories, ts_setup_workspace,angular_material_setup_workspace,ng_setup_workspace,
• 加载 docker 基本图像,在我们的例子中是“@io_bazel_rules_docker//nodejs:image.bzl”,
• 不要忘记提及浏览器和网络测试存储库
web_test_repositories()
browser_repositories(
铬 = 真,
火狐=真,
)
"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"
)
使用 Below 命令构建 Bundle。
bazel build :bundle
管道:通过 Jenkins
通过 Jenkins 创建管道和 运行 管道有几个阶段。每个阶段都有单独的任务,但在我们的例子中,我们使用阶段使用 BaZel 运行.
发布图像
pipeline {
agent any
stages {
stage('Publish image') {
steps {
sh 'bazel run //src/server:push'
}
}
}
}
注:
bazel run :dev.apply
Dev Apply maps to kubectl apply,这将创建或替换现有配置。(有关更多信息,请参阅 kubectl 文档。)这将应用已解析的模板,其中包括重新发布图像。此操作旨在成为快速迭代开发(重建/重新发布/重新部署)的主力军。
如果您想使用 workpsace 文件拉取容器,请使用以下标签
container_pull(
名称 = "debian_base",
摘要 = "sha256:**",
注册表 = "gcr.io",
存储库 = "google-appengine/debian9",
)
如果使用GKE,需要安装gcloud sdk,因为我们使用的是GKE(Google Contianer Enginer),可以通过下面的方式进行认证。
gcloud container clusters get-credentials <CLUSTER NAME>
应按以下格式提及 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"
},
)
来源:
- https://docs.bazel.build/versions/0.19.1/be/workspace.html
- https://github.com/thelgevold/angular-bazel-example
- https://medium.com/@Jakeherringbone/deploying-an-angular-app-to-kubernetes-using-bazel-preview-91432b8690b5
- https://github.com/bazelbuild/rules_docker
- https://github.com/GoogleCloudPlatform/gke-bazel-demo
- https://github.com/bazelbuild/rules_k8s#update
- https://codefresh.io/howtos/local-k8s-draft-skaffold-garden/
- https://github.com/bazelbuild/rules_k8s
几个月后,我在整个过程中走得比较远。
在这里发布每个细节会太多了!
所以这是实现了大部分要求的开源项目:https://github.com/flolu/fullstack-bazel
如有具体问题,请随时与我联系! :)
祝你好运
Flo,您是否考虑过使用 terraform 和 makefile 来自动构建集群?
在我最近的项目中,我使用 make 和 terraform 实现端到端的基础架构自动化。从本质上讲,该方法构建整个集群,在 3 到 5 分钟内通过一个命令构建和部署整个项目。取决于给定日期的 gcp 速度。
有一个 google 示例项目展示了这个想法,尽管 terraform 配置已经过时并且需要替换为符合当前 0.13 / 0/14 语法的配置。
https://github.com/GoogleCloudPlatform/gke-bazel-demo#build--deploy-with-bazel
启用单命令端到端自动化的 makefile:
https://github.com/GoogleCloudPlatform/gke-bazel-demo/blob/master/Makefile
再次为您的项目替换或自定义脚本;我实际上又写了两个脚本,一个用于检查/安装客户端要求,即 git / kubctl & gcloud,另一个用于检查或配置和验证 gcloud,以防它尚未配置和验证。从那里,terraform 脚本接管并构建整个集群,一旦完成,通常的自动部署就会开始。
我发现分层改造 Terraform 和 bazel 以实现端到端自动化的想法非常棒。
我有一个带有一些后端 (Node.js) and frontend (Angular) 服务的 monorepo。目前我的部署过程是这样的:
我的目标是在 Bazel and Cloud Build 的帮助下自动执行所有这些步骤。但我真的很难开始使用 Bazel:
为了让它工作,我可能需要添加一个 WORKSPACE
文件和我自己的 packages/services 的外部依赖项和多个 BUILD
文件? 我需要实际实施方面的帮助:
- 如何使用 Bazel 构建我的 Dockerfile?
- 如何将这些图像推送到注册表中(最好是 GCR)?
- 如何自动将更改应用到 Google Kubernetes Engine?
- 如何将此工具链与 Google Cloud Build 集成?
有关该项目的更多信息
I've put together a tiny sample monorepo to showcase my use-case
结构
├── kubernetes
├── packages
│ ├── enums
│ ├── utils
└── services
├── gateway
一般
Gateway
服务依赖于enums
和utils
- 一切都是用 Typescript 写的
- 每个 service/package 都是一个节点模块
gateway
文件夹里面有个Dockerfile
,我要建- Kubernetes 配置位于
kubernetes
文件夹中。 - 请注意,我不想发布任何
npm
个包!
我们想要的是一个便携式 Docker 容器,其中包含我们的 Angular 应用程序及其服务器以及它需要的任何机器映像,我们可以在任何云提供商上启动,我们将要创建一个完整的管道是增量的。 “Docker 规则”很快。从本质上讲,它通过添加新的 Docker 层来提供工具,因此您对应用程序所做的更改是唯一通过网络发送到云主机的内容。此外,由于 Docker 图像使用 SHA 标记,我们仅重新部署已更改的图像。为了管理我们的生产部署,我们将使用 Kubernetes,据我所知,Bazel 规则还 exist.Build docker 来自 Docker 文件的图像使用 Bazel 是不可能的,因为 由于 Docker 文件的非密封性质,它在设计上是不允许的。(来源: https://blog.bazel.build/2015/07/28/docker_build.html)
作为源代码的一部分所做的更改将部署在 Kubernetes 集群中,这是使用 Bazel 实现以下目标的一种方法。
我们必须将 Bazel 置于监视模式,Deploy replace 告诉 Kubernetes 集群更新已部署的应用程序版本。 一.
命令:ibazel 运行:deploy.replace
如果有任何源代码更改,请在 angular.
中进行Bazel 仅增量地重新构建依赖于已更改文件的构建图的部分,在本例中,包括已更改的 ng_module、Angular 包含该模块的应用程序,以及包含服务器的 Docker nodejs_image。正如我们要求更新部署一样,构建完成后,它将新的 Docker 容器推送到 Google Container Registry,Kubernetes Engine 实例开始为其提供服务。 Bazel 了解构建图,它只会重新构建更改的内容。
这里有一些 Snippet 级别的提示,可以提供实际帮助。
工作空间文件:
创建一个Bazel工作区文件,WORKSPACE文件告诉Bazel这个目录是一个“工作区”,就像一个项目根目录。下面列出了在 Bazel 工作区内要做的事情。 • 工作区的名称应该与我们发布的npm 包相匹配,以便这些导入在引用已发布的包时也有意义。 • 使用“http_archive”提及 Bazel 工作区中的所有规则,因为我们正在使用 angular 和节点,因此应提及 rxjs、angular、angular_material、 io_bazel_rules_sass,angular-版本,build_bazel_rules_typescript,build_bazel_rules_nodejs。 • -接下来我们必须使用“load”加载依赖项。 sass_repositories, ts_setup_workspace,angular_material_setup_workspace,ng_setup_workspace, • 加载 docker 基本图像,在我们的例子中是“@io_bazel_rules_docker//nodejs:image.bzl”, • 不要忘记提及浏览器和网络测试存储库 web_test_repositories() browser_repositories( 铬 = 真, 火狐=真, )
"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"
)
使用 Below 命令构建 Bundle。
bazel build :bundle
管道:通过 Jenkins
通过 Jenkins 创建管道和 运行 管道有几个阶段。每个阶段都有单独的任务,但在我们的例子中,我们使用阶段使用 BaZel 运行.
发布图像pipeline {
agent any
stages {
stage('Publish image') {
steps {
sh 'bazel run //src/server:push'
}
}
}
}
注:
bazel run :dev.apply
Dev Apply maps to kubectl apply,这将创建或替换现有配置。(有关更多信息,请参阅 kubectl 文档。)这将应用已解析的模板,其中包括重新发布图像。此操作旨在成为快速迭代开发(重建/重新发布/重新部署)的主力军。
如果您想使用 workpsace 文件拉取容器,请使用以下标签
container_pull( 名称 = "debian_base", 摘要 = "sha256:**", 注册表 = "gcr.io", 存储库 = "google-appengine/debian9", )
如果使用GKE,需要安装gcloud sdk,因为我们使用的是GKE(Google Contianer Enginer),可以通过下面的方式进行认证。
gcloud container clusters get-credentials <CLUSTER NAME>
应按以下格式提及 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"
},
)
来源:
- https://docs.bazel.build/versions/0.19.1/be/workspace.html
- https://github.com/thelgevold/angular-bazel-example
- https://medium.com/@Jakeherringbone/deploying-an-angular-app-to-kubernetes-using-bazel-preview-91432b8690b5
- https://github.com/bazelbuild/rules_docker
- https://github.com/GoogleCloudPlatform/gke-bazel-demo
- https://github.com/bazelbuild/rules_k8s#update
- https://codefresh.io/howtos/local-k8s-draft-skaffold-garden/
- https://github.com/bazelbuild/rules_k8s
几个月后,我在整个过程中走得比较远。 在这里发布每个细节会太多了!
所以这是实现了大部分要求的开源项目:https://github.com/flolu/fullstack-bazel
如有具体问题,请随时与我联系! :)
祝你好运
Flo,您是否考虑过使用 terraform 和 makefile 来自动构建集群?
在我最近的项目中,我使用 make 和 terraform 实现端到端的基础架构自动化。从本质上讲,该方法构建整个集群,在 3 到 5 分钟内通过一个命令构建和部署整个项目。取决于给定日期的 gcp 速度。
有一个 google 示例项目展示了这个想法,尽管 terraform 配置已经过时并且需要替换为符合当前 0.13 / 0/14 语法的配置。
https://github.com/GoogleCloudPlatform/gke-bazel-demo#build--deploy-with-bazel
启用单命令端到端自动化的 makefile:
https://github.com/GoogleCloudPlatform/gke-bazel-demo/blob/master/Makefile
再次为您的项目替换或自定义脚本;我实际上又写了两个脚本,一个用于检查/安装客户端要求,即 git / kubctl & gcloud,另一个用于检查或配置和验证 gcloud,以防它尚未配置和验证。从那里,terraform 脚本接管并构建整个集群,一旦完成,通常的自动部署就会开始。
我发现分层改造 Terraform 和 bazel 以实现端到端自动化的想法非常棒。