用 Skaffold 搭一个 Kubernetes & Spring Boot CI/CD 工作流


现在的前端开发越来越复杂,于是出现了诸如 webpack 这类的构建工具;而后端引入 Kubernetes 生态后,复杂程度也变得更甚以往了。

那么问题来了,后端好用的构建、部署工具是什么?

Skaffold 吧!

(注,这样的类比也许并不合适,但有助于理解。)


开发人员应该把主要精力放在编写代码上,而不是项目的编译、打包、部署等。引入 Docker 和 Kubernetes 后,项目的发布流程更长、更复杂,占据了开发人员不少的精力。而 Skaffold 为应对这个问题,对这些工具进行了整合并提供了更加简化的操作方式。

Skaffold 的优点

后端开发常常比较,尤其是涉及到 Kubernetes 时。但 Skaffold 却有以下优点:

  • 单纯是个客户端工具,不需要服务端做额外配合,维护成本低。
  • 易于分享:一个 Skaffold 管理的项目,只需要 git clone && skaffold run 就能跑起来。
  • 简化开发:以前,项目要部署到 k8s 上,你起码要 compile / build / push / deploy 四连,而这又涉及了不同的命令(mvn / docker / kubectl / blah blah)。有了 skaffold,你只需要 skaffold runscaffold dev。虽然这仍要依赖于上面那些命令,但整合后整个过程显然变得简单了。

1Skaffold 实战

前提条件

要完成本任务,你需要先:

  1. 安装 Skaffold
  2. 安装 Docker Desktop for Mac,并启用 Kubernetes
  3. 安装 kubectl

如果你用的是 Mac 并且安装了 brew,你只需要:

# 老版本的 brew 用这个命令安装 docker
# brew cask install docker

brew install homebrew/cask/docker
brew install kubectl skaffold

使用其它 OS 的同学请参考相关官方指导进行安装。

开始实战

Skaffold 的运行需要一个 skaffold.yaml 的文件,它可以由 skaffold init 命令生成。

skaffold init 命令需要一些特定的参数:

  1. 指定打包工具。

Skaffold 支持 Docker、Jib(--XXenableJibInit) (见我的另一篇文章: 使用 Jib 代替 Docker CLI 打包一个 Spring Boot 应用) 和 Buildpacks(--XXenableBuildpacksInit)等打包方式。

  1. 有效的 Kubernetes manifest 文件(deployment、pod、service等),放在项目根目录的 k8s 文件夹下。

我们先创建一个 deployment:

# 使用的是上篇文章里提供的镜像
kubectl create deploy jib-demo --image=registry.cn-hangzhou.aliyuncs.com/xxx/jib-demo --dry-run -oyaml

把上述命令的输出保存到 k8s/deployment.ymal 文件下,其内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: jib-demo
  name: jib-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jib-demo
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: jib-demo
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/xxx/jib-demo
        name: jib-demo
        resources: {}
status: {}

再创建一个 service:

kubectl expose deployment jib-demo --type=NodePort --port=8080 --dry-run -oyaml

将输出保存到 k8s/service.yaml 文件下:

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: jib-demo
  name: jib-demo
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: jib-demo
  type: NodePort
status:
  loadBalancer: {}

可以执行 skaffold init 操作了:

# 我们使用 jib 进行打包,见上一篇文章
skaffold init --XXenableJibInit

得到如下输出:

apiVersion: skaffold/v2beta12
kind: Config
metadata:
  name: jib-demo
build:
  artifacts:
  - image: registry.cn-hangzhou.aliyuncs.com/xxx/jib-demo
    jib:
      project: com.example:jib-demo
deploy:
  kubectl:
    manifests:
    - k8s/deployment.yaml
    - k8s/service.yaml

? Do you want to write this configuration to skaffold.yaml? (y/N) y
? Do you want to write this configuration to skaffold.yaml? Yes
Configuration skaffold.yaml was written
You can now run [skaffold build] to build the artifacts
or [skaffold run] to build and deploy
or [skaffold dev] to enter development mode, with auto-redeploy

打开项目,可以看到根目录下多了一个 skaffold.yaml 的文件。

准备工作已经完成,要启动 CI/CD 工作流,只需要运行 skaffold dev:

➜  jib-demo skaffold dev
Listing files to watch...
 - registry.cn-hangzhou.aliyuncs.com/xxx/jib-demo
Generating tags...
 - registry.cn-hangzhou.aliyuncs.com/xxx/jib-demo -> registry.cn-hangzhou.aliyuncs.com/xxx/jib-demo:latest
Some taggers failed. Rerun with -vdebug for errors.
Checking cache...
 - registry.cn-hangzhou.aliyuncs.com/xxx/jib-demo: Found Locally
Tags used in deployment:
 - registry.cn-hangzhou.aliyuncs.com/xxx/jib-demo -> registry.cn-hangzhou.aliyuncs.com/xxx/jib-demo:c9dbc70d39ff63ded37e5e82e5d3c99e7eaa60175247b294938f421a6cd15c3e
Starting deploy...
 - deployment.apps/jib-demo created
 - service/jib-demo created
Waiting for deployments to stabilize...
 - deployment/jib-demo is ready.
Deployments stabilized in 3.385 seconds
Press Ctrl+C to exit
Watching for changes...
[jib-demo]
[jib-demo]   .   ____          _            __ _ _
[jib-demo]  /\ / ___'_ __ _ _(_)_ __  __ _    
[jib-demo] ( ( )___ | '
_ | '_| | '_ / _` |    
[jib-demo]  \/  ___)| |_)| | | | | || (_| |  ) ) ) )
[jib-demo]   '  |____| .__|_| |_|_| |___, | / / / /
[jib-demo]  =========|_|==============|___/=/_/_/_/
[jib-demo]  :: Spring Boot ::                (v2.4.5)

可以看到跑起来了~。使用 kubectl 再检查一遍:

➜  ~ k get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
jib-demo     NodePort    10.100.39.118   <none>        8080:32220/TCP   109s
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          48m

完美!

试试热部署,把 k8s/deployment.yamlreplicas 由 1 改为 2,会发现项目会自动重新部署,kubectl 命令也显示有2个 jib-demo 的实例:

➜  ~ k get po
NAME                       READY   STATUS    RESTARTS   AGE
jib-demo-ffdff55d6-8b2gp   1/1     Running   0          6m24s
jib-demo-ffdff55d6-lkb99   1/1     Running   0          3m6s

除了 skaffold dev 命令,还有 skaffold run ,前者会在项目文件有变动时自动打包部署,而后者只会部署一次。

当使用 ctrl c 关掉 skaffold dev 进程时,它所创建的 k8s 对象也会全部销毁。


以上仅是 Skaffold 的简单入门,更灵活、强大的配置和使用,请移步官方文档。

文章参考自 CI/CD Workflow for Spring Boot Applications on Kubernetes via Skaffold[1] 以及 Skaffold Documentation[2]

参考资料

[1]

CI/CD Workflow for Spring Boot Applications on Kubernetes via Skaffold: https://medium.com/javarevisited/skaffolding-springboot-application-dbfbc463e558

[2]

Skaffold Documentation: https://skaffold.dev/docs/

原文始发于微信公众号(背井):用 Skaffold 搭一个 Kubernetes & Spring Boot CI/CD 工作流

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/246624.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!