简体   繁体   English

本地开发最佳实践:Java、Docker、Kubernetes

[英]Local Development Best Practices: Java, Docker, Kubernetes

I am trying to figure out the ultimate best practices for using Java in Docker containers deployed using Kubernetes on local environments or while developing code .我试图找出在本地环境中使用 Kubernetes 部署的 Docker 容器中或在开发代码时使用 Java 的最终最佳实践。 In the ideal state, Java developers should be able to move as fast as python/javascript developers, but I am having a hard time matching the speed (or even coming close).在理想状态下,Java 开发人员应该能够像 python/javascript 开发人员一样快速移动,但我很难匹配速度(甚至接近)。

At the moment, I have a working, manually deployed k8's cluster.目前,我有一个手动部署的 k8 集群。 My Java Spring project is built by maven after a build command is run manually ( mvn clean install ), then I run a script to make an image, after that I run a script to run minkube (if its not already running) and finally I have to apply a deployments manifest file (which launches the containers into the pods).我的 Java Spring 项目是在手动运行构建命令后由 Maven 构建的( mvn clean install ),然后我运行一个脚本来制作图像,之后我运行一个脚本来运行 minkube(如果它还没有运行),最后我必须apply部署清单文件(将容器启动到 pod 中)。

What I am missing:我缺少什么:

  1. All of this is done manually (there is clear room to automate the process of building an image after code is built and to have k8s update using the new image).所有这一切都是手动完成的(在构建代码之后,自动构建镜像的过程以及使用新镜像更新 k8s 的过程有很大的空间)。
  2. Builds are manually specified (python relaunches on code save. No hot reloading to my knowledge in the java world).构建是手动指定的(python 在代码保存时重新启动。据我所知,在 Java 世界中没有热重新加载)。
  3. I have yet to see an integration between a local development environment and a cloud hosted k8's cluster.我还没有看到本地开发环境和云托管的 k8 集群之间的集成。 Ideally, a dev would test locally until they are ready to deploy to the cloud.理想情况下,开发人员会在本地进行测试,直到他们准备好部署到云中。 When they are ready, it would be awesome to click a button and have a cluster read from a remote registry that could pick up the docker image changes and reload.当它们准备好时,点击一个按钮并从远程注册表读取一个集群可以获取 docker 镜像更改并重新加载,这将是非常棒的。

Sadly, Skaffold , the tool that I would be excited to use does not work natively with Java.遗憾的是, Skaffold是我很乐意使用的工具,但它本身不能与 Java 一起使用。 Is there another tool that Java Devs are using to make their local deployments super fast and competitive with the DUCK languages (py, js)? Java 开发人员是否正在使用另一种工具来使他们的本地部署超快并与 DUCK 语言(py、js)竞争?

You can build a docker image directly from maven with docker-maven-plugin .您可以使用docker-maven-plugin直接从 maven 构建 docker 镜像。 Add to your pom.xml :添加到您的pom.xml

<build>
  <plugins>
    ...
    <plugin>
      <groupId>com.spotify</groupId>
      <artifactId>docker-maven-plugin</artifactId>
      <version>VERSION GOES HERE</version>
      <configuration>
        <imageName>example</imageName>
        <dockerDirectory>docker</dockerDirectory>
        <resources>
           <resource>
             <targetPath>/</targetPath>
             <directory>${project.build.directory}</directory>
             <include>${project.build.finalName}.jar</include>
           </resource>
        </resources>
      </configuration>
    </plugin>
    ...
  </plugins>
</build>

I don't know precisely your use case, but deploying a k8's cluster in your dev machine is maybe overkill.我不太清楚您的用例,但是在您的开发机器上部署 k8 的集群可能有点过头了。 You can test your docker images with Docker compose您可以使用Docker compose测试您的 docker 镜像

My take on your development workflow:我对您的开发工作流程的看法:

  • Like @Ortomala Lokni mentioned, Use docker-maven-plugin to build direct docker images from your maven build.就像@Ortomala Lokni 提到的那样,使用 docker docker-maven-plugin从您的 maven 构建构建直接的 docker 镜像。
  • You can use https://github.com/fabric8io/fabric8-maven-plugin to push directly to a kubernetes cluster.您可以使用https://github.com/fabric8io/fabric8-maven-plugin直接推送到 kubernetes 集群。
  • If your cluster is hosted in the cloud, your build machine should be able to reach the k8s API Server.如果您的集群托管在云中,您的构建机器应该能够访问 k8s API 服务器。 And for that you might need to use SSH tunnels and Bastions , depending on whether your cloud k8s clusters' API Server is publicly available or not.为此,您可能需要使用 SSH 隧道和堡垒,具体取决于您的云 k8s 集群的 API 服务器是否公开可用。
  • Look at minikube for a local k8s test cluster, even latest versions of docker for desktop now have a simple k8s server built in.查看用于本地 k8s 测试集群的 minikube,即使是桌面版docker 的最新版本现在也内置了一个简单的 k8s 服务器。
  • Have not used Skaffold, but a basic looking at the document suggests that it should also work for you as it takes over basic functions of watching your code, kicking off a docker build and deploying to k8s.没有使用过 Skaffold,但对文档的基本查看表明它也应该对你有用,因为它接管了观察你的代码、启动 docker 构建和部署到 k8s 的基本功能。 These functions remain the same across languages.这些功能在不同语言中保持不变。 Having said that the above two plugins integrate the build docker image and deploy to k8s into your maven workflow.话虽如此,以上两个插件将构建 docker 镜像并部署到 k8s 集成到您的 maven 工作流程中。

You mention python/js as being fast, but do note, that for even those languages the basic steps remain the same, build a docker image, push to repository, update k8s deployment.您提到 python/js 速度快,但请注意,即使是这些语言,基本步骤也保持不变,即构建 docker 镜像、推送到存储库、更新 k8s 部署。

Also hot deployment has worked with Java, even in things like eclipse say with a spring boot based microservice you can use the spring-dev-tools to do live reloads and auto restarts.热部署也适用于 Java,即使在 eclipse 之类的事情中,比如使用基于 Spring Boot 的微服务,您也可以使用spring-dev-tools进行实时重新加载和自动重启。 However I am not aware of anything that will help you handle live changes to a docker container and I would ask you to shy away from it docker containers are supposed to be immutable.但是,我不知道有什么可以帮助您处理 docker 容器的实时更改,我会要求您避开它 docker 容器应该是不可变的。

Sorry if I'm late, I'll try to give an answer for future readers, or maybe still for you!抱歉,如果我迟到了,我会尽力为未来的读者提供答案,或者仍然为您提供答案!

First of all, docker build and deploy on kubernetes cluster are two totally different phases of your software supply chain, let's keep them as separate discourses首先,docker 在 kubernetes 集群上构建和部署是软件供应链的两个完全不同的阶段,让我们将它们作为单独的论述

  1. The build process should be already automated: if you need to run manually mvn clean install it means that you are loosing one of the advantages of Docker: build repeatable, immutable software packages that can be delivered everywhere.构建过程应该已经自动化了:如果您需要手动运行 mvn clean install 这意味着您正在失去 Docker 的一项优势:构建可以随处交付的可重复、不可变的软件包。 Just add RUN mvn clean install to your Dockerfile (yes, you need to put maven in your image before, but there are some base images around that does the job for you).只需将RUN mvn clean install添加到您的 Dockerfile 中(是的,您之前需要将 maven 放入您的映像中,但是周围有一些基本映像可以为您完成这项工作)。 Now you should just set up a CI server that builds and pushes images at every repository check-in (I am intentionally skipping any quality gate and pipeline workflow , they're up to you to automate).现在您应该只设置一个 CI 服务器,在每次存储库签入时构建和推送图像(我有意跳过任何质量门和管道工作流,它们由您来自动化)。 Also deploy can be managed by CI servers, there are two main approaches也可以通过 CI 服务器管理部署,主要有两种方法

a) create a config repository with all the k8s manifests and run kubectl apply from you CI server at every push a) 创建一个包含所有 k8s 清单的配置存储库,并在每次推送时从 CI 服务器运行 kubectl apply

b) put config along with the interested microservice, tag the fresh built image with the commit hash and at the end of the pipeline kubectl apply env.yaml && kubectl set image myregistry.com/myimage:${commitHash} (just be sure to tag also as "latest" and include the latest tag in you deployment spec, it helps to reconstruct the current situation after a remove-and-apply configuration) b) 将配置与感兴趣的微服务一起放置,使用提交哈希标记新构建的镜像,并在管道的末尾 kubectl apply env.yaml && kubectl set image myregistry.com/myimage:${commitHash} (请务必也标记为“最新”并在您的部署规范中包含最新标记,这有助于在删除和应用配置后重建当前情况)

c) deploy with helm charts. c) 使用掌舵图进行部署。 It's similar to the previous but you can leverage all the advantages of the dependency management and deployment templateization它与前一个类似,但您可以利用依赖项管理和部署模板化的所有优势

  1. Hot reloads are nice when you do your tdd development but useless when the code is about to be delivered, neither with node/python microservices you will use it because once your code is containerized, you should shoot with an AK47 every developer that tries to touch it.当你进行 tdd 开发时,热重载很好,但在代码即将交付时没用,无论是 node/python 微服务,你都不会使用它,因为一旦你的代码被容器化,你应该用 AK47 拍摄每个试图接触的开发人员它。 The real big thing here is to automate your integration/delivery/deployment.这里真正重要的是自动化您的集成/交付/部署。 In my team we just need to open and accept a PR, and the magic happens在我的团队中,我们只需要打开并接受 PR,奇迹就会发生

  2. You need to do some debugging/integration between microservices on your laptop.您需要在笔记本电脑上的微服务之间进行一些调试/集成。 I would not discourage this practice, but is something that has to be done at a frequency for which speed is not so important for productivity.我不会阻止这种做法,但必须以速度对生产力不那么重要的频率进行。 But if you want to do it, you can do it building a "laptop" or "dev" environment with docker compose, pulling your dependencies from the registry (to reproduce the current "online" situation) and then build your microservice with its own configuration.但是如果你想这样做,你可以用 docker compose 构建一个“笔记本电脑”或“开发”环境,从注册表中提取你的依赖项(重现当前的“在线”情况),然后用自己的微服务构建你的微服务配置。 Another way is to use port forwarding a k8s capability to pretend that a pod is connected with your local machine exposing a well-known port, but is an headache if there are many dependencies.另一种方法是使用 k8s 功能的端口转发来假装一个 pod 与您的本地机器连接并公开一个众所周知的端口,但如果有很多依赖项,那就很头疼了。 A third way is to use tools like https://www.telepresence.io/ that promises to run a pod locally and connect to the cluster with a pair of proxies in both directions第三种方法是使用https://www.telepresence.io/ 之类的工具,它承诺在本地运行一个 pod 并使用一对双向代理连接到集群

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM