加速云原生的 Java 开发
今天来说说日常在Kubernetes开发Java项目遇到的问题.
当我们新建一个项目的时候, 总是面临需要新建manifest, 平时都是copy+paste+modify
. 能否以变成的方式来生成?
开发时的步骤也比较繁琐: docker build
, docker push
, kubectl apple
, kubectl delete pod
. 对于一个Java应用来说还多了一步编译. 操作一次还ok, 但是一天十几次总会有想吐的感觉. 这些步骤能否简化成一个命令, 甚至修改了代码自动就完成上面一系列的操作?
实现这些我们需要几个工具: dekorate, Jib, Skaffold. 其中Jib也在上一篇文章使用Jib为Java应用构建镜像中介绍过.
dekorate
Dekorate is a collection of Java compile-time generators and decorators for Kubernetes/OpenShift manifests. Dekorate是Java编译时生成和装饰Kubernetes/OpenShift的manifests的工具
快速开始
1. 通过使用Spring Initializer生成一个项目(Spring Boot 2.2.2), 并加入依赖:
<dependency>
<groupId>io.dekorate</groupId>
<artifactId>kubernetes-spring-starter</artifactId>
<version>0.10.0</version>
</dependency>
2. 加入一个简单的Controller
:
/**
* @author Addo.Zhang
* @date 2019/12/22
*/
@RestController
public class DekorateExampleController {
@GetMapping
public String hi() {
return "Hello World";
}
}
3. 执行命令mvn clean install
, 然后在target/classes/META-INF/dekorate
目录下可以找到kubernetes.json
和kubernetes.yml
两个文件.
kubernetes.yml
的内容:
---
apiVersion: "v1"
kind: "Service"
metadata:
labels:
app: "dekorate-example"
version: "0.0.1-SNAPSHOT"
group: "addo"
name: "dekorate-example"
spec:
ports:
- name: "http"
port: 8081
targetPort: 8081
selector:
app: "dekorate-example"
version: "0.0.1-SNAPSHOT"
group: "addo"
type: "ClusterIP"
---
apiVersion: "apps/v1"
kind: "Deployment"
metadata:
labels:
app: "dekorate-example"
version: "0.0.1-SNAPSHOT"
group: "addo"
name: "dekorate-example"
spec:
replicas: 1
selector:
matchLabels:
app: "dekorate-example"
version: "0.0.1-SNAPSHOT"
group: "addo"
template:
metadata:
labels:
app: "dekorate-example"
version: "0.0.1-SNAPSHOT"
group: "addo"
spec:
containers:
- env:
- name: "KUBERNETES_NAMESPACE"
valueFrom:
fieldRef:
fieldPath: "metadata.namespace"
image: "addo/dekorate-example:0.0.1-SNAPSHOT"
imagePullPolicy: "IfNotPresent"
livenessProbe:
failureThreshold: 3
httpGet:
path: "/actuator/info"
port: 8081
scheme: "HTTP"
initialDelaySeconds: 0
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
name: "dekorate-example"
ports:
- containerPort: 8081
name: "http"
protocol: "TCP"
readinessProbe:
failureThreshold: 3
httpGet:
path: "/actuator/health"
port: 8081
scheme: "HTTP"
initialDelaySeconds: 0
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
yml中包含了Service
和Deployment
两部分, dekorate完美兼容的Spring:
app: dekorate-example
: 项目名version: 0.0.1-SNAPSHOT
: 项目当前版本group: addo
: 是我系统当前用户名/actuator/health
: Spring Boot 2.2后actuator的health endpoint, 作为readinessProbe
/actuator/info
: Spring Boot 2.2后actuator的endpoint, 作为livenessProbe
进阶
前面yml的内容都是自动生成的, 假如有些特殊的需求. 比如修改镜像的repository
即这里的group
, 如何操作?
dekorate.kubernetes.group = addozhang
结果:
或者修改Service的类型为NodePort
dekorate.kubernetes.service-type = NodePort
配置
dekoration提供了丰富的配置来个性化manifest.
除了上面使用的配置文件(properties/yaml)的方式, 还提供了Annotation
注解配置方式.
import io.dekorate.kubernetes.annotation.Env;
import io.dekorate.kubernetes.annotation.KubernetesApplication;
@KubernetesApplication(envVars = @Env(name = "key1", value = "var1"))
public class Main {
public static void main(String[] args) {
//Your code goes here
}
}
Jib
Jib的说明请看上一篇文章:使用Jib为Java应用构建镜像
插件配置
下面是针对该项目添加的配置:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>1.8.0</version>
<configuration>
<container>
<jvmFlags>
<jvmFlag>-Xmx128m</jvmFlag>
<jvmFlag>-Xms64m</jvmFlag>
</jvmFlags>
<labels>
<Author>Addo.Zhang</Author>
</labels>
<creationTime>USE_CURRENT_TIMESTAMP</creationTime>
</container>
<from>
<image>openjdk:8-jdk-alpine</image>
</from>
<to>
<image>addo/dekorate-example</image>
<tags>
<tag>latest</tag>
</tags>
</to>
<allowInsecureRegistries>true</allowInsecureRegistries>
</configuration>
</plugin>
执行命令mvn compile jib:dockerBuild
便可以编译代码, 构建镜像并推送到镜像仓库.
Skaffold
Skaffold也是GoogleContainerTools中的一个工具.
Skaffold is a command line tool that facilitates continuous development for Kubernetes applications. You can iterate on your application source code locally then deploy to local or remote Kubernetes clusters. Skaffold handles the workflow for building, pushing and deploying your application. It also provides building blocks and describe customizations for a CI/CD pipeline. Skaffold是一个命令行工具, 可促进Kubernetes应用程序的持续开发. 可以在本地迭代应用程序源代码, 然后部署到本地或远程Kubernetes集群. Skaffold处理构建, 推送和部署应用程序的工作流程. 它还提供了构建块并描述了CI/CD管道的自定义.
在我们这个例子中, 通过与Jib的联动, 完成编译代码, 构建镜像, 推送镜像, 部署一系列操作.
![Run](https://raw.githubusercontent.com/addozhang/oss/master/blog/upload/2019-12-23 15.12.24.gif)
截屏中的操作, 因为没有代码改动而不续构建镜像, Skaffold直接从cache中获取镜像并部署到Kubernetes中.
Skaffold操作
1. 执行命令skaffold init --XXenableJibInit
并在提示出输入y
2. 该命令会生成一个名为skaffold.yaml
的文件
由于dekorate
同时生成了json
和yaml
格式的manifest, 被skaffold
检测到. 实际操作中只需要其中一个即可.
apiVersion: skaffold/v1
kind: Config
metadata:
name: dekorate-example
build:
artifacts:
- image: addo/dekorate-example
jib: {}
deploy:
kubectl:
manifests:
- target/classes/META-INF/dekorate/kubernetes.json
- target/classes/META-INF/dekorate/kubernetes.yml
3. 执行skaffold run
4. pod启动完成后, 通过kubectl port-forward PODNAME-HERE 8081
5. 请求http http://localhost:8081
进阶
Skaffold的功能强大, 目前个人使用的有限, 有时间新开一篇来学习一下.
CLI
➜ ~ skaffold help
A tool that facilitates continuous development for Kubernetes applications.
Find more information at: https://skaffold.dev/docs/getting-started/
End-to-end pipelines:
run Run a pipeline
dev Run a pipeline in development mode
debug [beta] Run a pipeline in debug mode
Pipeline building blocks for CI/CD:
build Build the artifacts
deploy Deploy pre-built artifacts
delete Delete the deployed application
render [alpha] Perform all image builds, and output rendered Kubernetes manifests
Getting started with a new project:
init [alpha] Generate configuration for deploying an application
fix Update old configuration to newest schema version
Other Commands:
completion Output shell completion for the given shell (bash or zsh)
config Interact with the Skaffold configuration
credits Export third party notices to given path (./skaffold-credits by default)
diagnose Run a diagnostic on Skaffold
version Print the version information
Usage:
skaffold [flags] [options]
Use "skaffold <command> --help" for more information about a given command.
Use "skaffold options" for a list of global command-line options (applies to all commands).
Yaml配置
总结
文章的开头我们提到如何做到修改代码后自动完成一些列的操作, 通过skaffold dev
就可以实现.
文章中使用的dekoration-example
可在GitHub上找到.