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

时间:2018-10-09 17:19:33

标签: java docker kubernetes

我试图找出在本地环境或开发代码时使用Kubernetes部署的Docker容器中使用Java的最终最佳实践。在理想状态下,Java开发人员应该能够像python / javascript开发人员一样快地移动,但是我很难适应这种速度(甚至接近)。

目前,我有一个正在工作的手动部署的k8集群。我的Java Spring项目是在手动运行构建命令(mvn clean install)之后由maven构建的,然后我运行脚本来制作映像,此后我运行脚本来运行minkube(如果尚未运行)并且最后,我必须apply一个部署清单文件(将容器启动到容器中)。

我所缺少的:

  1. 所有这些操作都是手动完成的(在创建代码后,有足够的空间来自动化构建图像的过程,并使用新图像更新k8s)。
  2. 手动指定内部版本(python在代码保存时重新启动。据我所知,在Java世界中没有热加载)。
  3. 我还没有看到本地开发环境与托管k8集群的云之间的集成。理想情况下,开发人员将在本地进行测试,直到他们准备将其部署到云中为止。准备就绪后,单击按钮并从远程注册表中读取群集可能会很棒,该群集可以获取docker映像更改并重新加载。

遗憾的是,Skaffold,我很高兴使用的工具不适用于Java。 Java开发人员是否使用另一种工具来使其本地部署超级快速并与DUCK语言(py,js)竞争?

3 个答案:

答案 0 :(得分:2)

您可以使用docker-maven-plugin直接从maven构建docker映像。添加到您的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>

我不太清楚您的用例,但是在您的开发机器上部署k8集群可能会过头了。您可以使用Docker compose

测试docker映像

答案 1 :(得分:1)

我对您的开发工作流程的看法:

  • 就像@Ortomala Lokni所述,使用docker-maven-plugin从您的Maven构建中构建直接的Docker映像。
  • 您可以使用https://github.com/fabric8io/fabric8-maven-plugin直接推送到kubernetes集群。
  • 如果您的集群托管在云中,则您的构建计算机应该能够访问k8s API服务器。为此,您可能需要使用SSH隧道和Bastions,具体取决于您的k8s集群的API服务器是否公开可用。
  • 在minikube上查看本地k8s测试集群,even latest versions of docker for desktop现在内置了一个简单的k8s服务器。
  • 还没有使用Skaffold,但是从基本的角度看文档表明它也应该为您工作,因为它接管了观看代码,启动docker构建并部署到k8s的基本功能。这些功能在各种语言中保持不变。话虽如此,以上两个插件都集成了构建docker映像并将其部署到k8s到您的maven工作流程中。

您提到python / js很快,但是要注意,即使对于那些语言,基本步骤也保持不变,构建docker映像,推送到存储库,更新k8s部署。

热部署也已与Java一起使用,即使在诸如eclipse之类的事情中,基于Spring Boot的微服务也可以使用spring-dev-tools进行实时重载和自动重启。 但是我不知道有什么能帮助您处理对Docker容器的实时更改,我想请您回避它,因为Docker容器应该是不变的。

答案 2 :(得分:0)

对不起,如果我迟到了,我会尽力为将来的读者提供答案,或者也许还是给您!

首先,在kubernetes集群上构建和部署docker是您软件供应链的两个完全不同的阶段,让我们将其作为单独的论述来讨论

  1. 构建过程应该已经自动化:如果您需要手动运行mvn clean install,这意味着您失去了Docker的优势之一:构建可在任何地方交付的可重复,不变的软件包。只需在您的Dockerfile中添加 RUN mvn clean install (是的,您需要先在映像中放入Maven,但是周围有一些基本映像可以为您完成工作)。现在,您应该只设置一个CI服务器,该服务器在每次存储库检入时生成并推送图像(我有意跳过任何质量门控和管道工作流程,这取决于您来实现自动化)。 CI服务器也可以管理部署,主要有两种方法

a)创建包含所有k8s清单的配置存储库,并在每次推送时从您的CI服务器运行kubectl apply

b)将配置和感兴趣的微服务一起放置,用提交哈希标记新构建的映像,并在管道的末尾 kubectl apply env.yaml && kubectl设置映像myregistry.com/myimage:${commitHash } (只需确保也将其标记为“最新”,并在您的部署规范中包括最新的标记,它有助于在删除并应用配置后重建当前状况)

c)使用头盔图表进行部署。与之前的相似,但是您可以利用依赖管理和部署模板化的所有优势

  1. 当您进行tdd开发时,热重装非常好,但是在代码即将交付时却毫无用处,因为node / python微服务都不能使用它,因为一旦将代码容器化,就应该使用AK47进行拍摄每个试图触碰它的开发人员。这里真正的大事是自动化您的集成/交付/部署。在我的团队中,我们只需要打开并接受PR,魔术就会发生

  2. 您需要在便携式计算机上的微服务之间进行一些调试/集成。我不会阻止这种做法,但是必须以一种频率来进行工作,而这种速度对于生产率而言并不那么重要。但是,如果您想这样做,则可以使用docker compose构建“笔记本电脑”或“开发”环境,从注册表中提取依赖项(以重现当前的“在线”情况),然后使用自己的微服务来构建它。组态。另一种方法是使用端口转发k8s功能来假装一个Pod与您的本地计算机相连,从而暴露了一个众所周知的端口,但是如果存在许多依赖关系,这将是令人头疼的事情。第三种方法是使用https://www.telepresence.io/之类的工具,它们承诺将在本地运行Pod并通过双向的一对代理连接到集群