一切福田,不離方寸,從心而覓,感無不通。

Category Archives: Docker

spring boot服务docker镜像优化之旅

缘由 我们在使用spring boot开发的服务中,一般会选择打包成单体的fatjar来发布服务,这在传统的部署方式下是非常方便的,但是当我们选择使用docker这种容器化的方式来部署应用的时候,却有一点点的不便之处,因为这个单体的jar一般都比较大,每次镜像push到仓库和从仓库拉取都需要比较长的时间。 原因是什么了? docker的一大特色就是镜像的存储是分层的,参考下面这张官图 我们在Dockerfile中的每一个指令会对应到镜像的每一层,docker在更新镜像时,只会推送变更过的层,当它计算出来这一层的摘要和之前的版本一致时,会复用上一次打包镜像时的缓存,会极大的提高打包镜像以及镜像push/pull操作的速度。 那么问题来了,当我们springboot打包出来的单体jar的时候,每次编译这个jar都会发生变化,对应的存储层也会发生变化,push和pull操作时都需要重新推送,而且这个jar一般都不小,一个典型的应用会在100M左右,对应用部署和发布的速度会有比较大的影响。 稍作思考,很容易就能发现这个肥大的jar文件里面,大部分其实都是固定不变的各种依赖库,我们真正每次编译会变化的业务代码部分其实很小很小,可能也就只有几百KB,只要能将这两部分分离,变成docker镜像中的两层,一定能极大的提升镜像发布的速度 牛刀小试 首先拿来动手尝试的是一个springboot admin的项目,项目的结构是这样的: 使用最常见的打包方式:

会生成一个32M的jar文件,优化之前的Dockerfile非常简单:

  可以看到这种方式在构建v2版本的镜像时,会重新copy整个完整的jar 如果要拆开这个单体的jar,有两种方式,一是修改mvn打包的配置,将lib包放在独立的文件夹下,在这里我们考虑到项目众多,尽量减少修改,选择了在Docker打包镜像时,解压打包出来的jar包,将其中的内容分开来copy,修改后的Dockerfile如下:

  看看修改后的效果: 在copy lib目录时,是直接using cache的。来看看push的时候效果对比 首先是优化前的push: 可以看到在push v2的时候还是会push一个33MB的层,虽然其实我们一行代码没有修改。 然后是优化后的: 可以看到这一次仅仅只推送了一个13KB的层,推送的速度快了非常多,同理也可以想象的到,我们在拉取镜像更新版本时速度会快很多。 路遇荆棘 在针对springboot-admin这个最简单的项目的优化取得很好的效果之后,就开始准备照搬到其他的项目中,没想到同样的方式怎么折腾都无效,分离之后的lib目录依然会每次需要全量重新push。出问题的项目结构大概是这样的: 一个常见的多模块mvn项目,有common,domain,rest-client,rest-server 这4个子模块,其中rest-server会依赖common和domain这两个子模块,打包出来的jar是在rest-server这个模块中。 究竟是什么鬼了? 终得正果 苦苦思索一番之后,lib目录既然不能复用上一次的cache,那一定是因为里面的内容有变化,遂将jar包解压,进到lib目录,真凶果然在此: 项目自身的3个子模块在每次编译的时候也会做为jar包放到lib目录下,这3个jar包每次编译都会有变化,所以导致这一层的cache失效。 找到问题之后,解决的思路就很简单了,将这种jar单独copy到一个目录下即可,修改后的Dockerfile如下:

  这样修改之后效果就和上面单模块的项目一样了,至此,基本完成了springboot项目的docker镜像优化,在jenkins的流水线上可以将原来镜像push的时间从1分钟以上优化到10s左右 未来之路 在整个优化的过程中,发现springboot2.3 M1版本已经有针对性的优化方案,增加了LAYERED_JAR的打包格式,未来可期。 具体可参考下文: www.jdon.com/53738 注: 本文中举例的两个项目案例,可在github上找到:github.com/yishh/sprin… 作者:thor_lee 链接:https://juejin.cn/post/6844904119338008583 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

龙生   18 Jun 2021
View Details

docker springboot项目镜像优化

遇到的问题: 公司java项目按老的方式打包出来一个fat jar,100MB, 推送到腾讯云镜像仓库很慢,8分钟。。。走的是公网,专线暂时还没配置好 以前是内网harbor,速度还不明显。 归根究底,一次推送100MB是个不合理的事情 思路: 了解spring boot打包,期望将依赖的libs 和 业务代码拆分 优化dockerfile,充分利用缓存   解决问题: 先修改spring-boot-maven-plugin,只打包业务代码。网上有些是配置exclude,我试了,恶心到了。。那么多包挨个找

  新增maven-dependency-plugin,将依赖移到libs目录下

  优化dockerfile 参考 https://medium.com/@nieldw/caching-maven-dependencies-in-a-docker-build-dca6ca7ad612 ,牛逼

  搞定。最终代码变化每次推送也就1MB多 启动命令 java -Dloader.path="libs/" -jar app.jar 作者:小猋_a8f1 链接:https://www.jianshu.com/p/32456eea0488 来源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

龙生   18 Jun 2021
View Details

优化 ASP.NET Core Docker 镜像的大小

在这容器化的世界里,我们已经很少直接通过文件发布来运行asp.net core程序了。现在大多数情况下,我们都会使用docker来运行程序。在使用docker之前,我们往往需要打包我们的应用程序。asp.net core程序的镜像打包,网上有很多教程,其中大多数是使用sdk这个镜像来直接打包。打出来的包有好几百MB,3.1 SDK打出来的包甚至超过了1GB。那么有什么办法来缩小我们打出来的镜像吗?最小能缩小到多少呢?这篇文章就来介绍下如何缩小asp.net core 打包出来镜像的大小。 新建asp.net core 程序 新建一个asp.net core应用程序,用来演示打包。首先我们演示下如果使用dotnet sdk5.0来打包 docker 镜像。 sdk:5.0

  在项目根目录下新建一个Dockerfile文件,文件内容如上。这个Dockerfile比较简单,使用dotnet sdk:5.0最为底层包来构建,这也是最傻瓜的打包方式。那么看看这个镜像打出来有多大吧。

  使用docker build命令进行打包。

  使用docker images命令来查看镜像列表,我们发现我们打出来的镜像居然有643MB,真的很大。如果是内网还好一点,如果在镜像存在docker hub等第三方仓库,这得下半天。显然这个镜像太大了,接下来看我们如何进行优化。 sdk:5.0-buster-slim 最新的VisualStudio内置了docker工具,可以自动为我们生成Dockerfile文件。我们来看看它生成的镜像文件有多大。 右键解决方案=>添加=>Docker支持=>Linux 。 选择完成后VS会为我们自动添加一个Dockerfile在根目录。

  这个自动生成的Dockerfile使用了sdk:5.0-buster-slim这个镜像进行build跟publish,使用aspnet:5.0-buster-slim这个runtime级别的镜像做为final底包。从名字来看,很明显slim代表着轻量。让我们试试这个Dockerfile打出来的包有多大。

  使用docker build命令进行打包。使用docker images命令查看镜像的大小,这个镜像的大小为210MB。果然比上面的镜像小了很多。那么是否还能继续缩小镜像的大小呢?继续往下看。 5.0-alpine 除了使用buster-slim镜像,我们还可以选择更加小巧的alpine镜像来打包。alpine镜像是继续alpine linux创建的镜像,所以它更加轻量级更加小巧。 关于alpine linux可以查看这篇:Alpine Linux 与 CentOS 有什么区别? 。

  修改Dockerfile使用aspnet:5.0-alpine及sdk:5.0-alpine来构建这个镜像。

  使用docker build命令进行打包。使用docker images命令查看镜像的大小,这个镜像的大小为108MB。现在这个镜像已经比我们第一次打包减少了500多MB了。那么还能更小吗?请往下看。 runtime-deps:5.0-alpine 最新的.net core程序支持自宿主及单文件发布。如果采用以上发布形式,那么我们可以选择使用runtime-deps:5.0-alpine做为最终底包来打包我们的镜像。

  修改Dockerfile,使用/runtime-deps:5.0-alpine做为final镜像。

使用docker build命令进行打包。使用docker images命令查看镜像的大小,这个镜像的大小为54.6MB。 总结 通过以上演示,我们的镜像大小从一开始的600多MB缩小到了54MB。一般生产我主要选择buster-slim这个镜像来打包。如果选择runtime-deps打包,打出来的包是最小的,虽然演示项目是可以运行的,但是本人没有在生产使用过,还请谨慎使用。 代码在这:CoreDockerImageSizeTest   from:https://www.cnblogs.com/kklldog/p/netcore-docker-image-size.html

龙生   17 Jun 2021
View Details

2020 docker 安装报Error: moby-containerd conflicts with containerd.io-1.4.4-3.1.el7.x86_64

此问题中缺少的一个关键信息是使用Azure。因为aspnetcore是在Azure devops管道中发布程序包所必需的,所以可能要使用微软的源或者更新一些配置: 故此通过 curl https://packages.microsoft.com/config/rhel/7/prod.repo > ./microsoft-prod.repo sudo cp ./microsoft-prod.repo /etc/yum.repos.d/ yum update -y 可以解决。 ———————————————— 版权声明:本文为CSDN博主「Zero_77」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/Zero_77/article/details/115902042

龙生   26 May 2021
View Details

Install Docker Engine on CentOS

To get started with Docker Engine on CentOS, make sure you meet the prerequisites, then install Docker. Prerequisites OS requirements To install Docker Engine, you need a maintained version of CentOS 7 or 8. Archived versions aren’t supported or tested. The centos-extras repository must be enabled. This repository is enabled by default, but if you have disabled it, you need to re-enable it. The overlay2 storage driver is recommended. Uninstall old versions Older versions of Docker were called docker or docker-engine. If these are installed, uninstall them, along with associated dependencies.

  It’s OK if yum reports that none […]

龙生   25 May 2021
View Details

containerd简述

containerd是容器虚拟化技术,从docker中剥离出来,形成开放容器接口(OCI)标准的一部分。 docker对容器的管理和操作基本都是通过containerd完成的。Containerd 是一个工业级标准的容器运行时,它强调简单性、健壮性和可移植性。Containerd 可以在宿主机中管理完整的容器生命周期:容器镜像的传输和存储、容器的执行和管理、存储和网络等。详细点说,Containerd 负责干下面这些事情: •管理容器的生命周期(从创建容器到销毁容器) •拉取/推送容器镜像 •存储管理(管理镜像及容器数据的存储) •调用 runC 运行容器(与 runC 等容器运行时交互) •管理容器网络接口及网络 注意:Containerd 被设计成嵌入到一个更大的系统中,而不是直接由开发人员或终端用户使用。 我们可以从下面几点来理解为什么需要独立的 containerd: •继续从整体 docker 引擎中分离出的项目(开源项目的思路) •可以被 Kubernets CRI 等项目使用(通用化) •为广泛的行业合作打下基础(就像 runC 一样) docker安装后containerd默认已安装,containerd包含如下命令组件: •containerd:高性能容器运行时。 •ctr:containerd的命令行客户端。 •runc:运行容器的命令行工具。 docker、containerd、docker-shim、runC关系: docker:docker本身而言,包括了docker client和dockerd,dockerd实属是对容器相关操作的api的最上层封装,直接面向操作用户。 containerd:dockerd实际真实调用的还是containerd的api接口(rpc方式实现),containerd是dockerd和runC之间的一个中间交流组件。 docker-shim:一个真实运行容器的载体,每启动一个容器都会起一个新的docker-shim的进程。它通过指定三个参数:容器ID、boundle目录(containerd对应某个容器生成目录)、运行时二进制(默认是runC)来调用runC的api创建一个容器。 runC:一个命令行工具端,根据OCI的标准来创建和运行容器。 containerd应用 docker镜像和containerd镜像通用,但组织方式和存放目录不同,导致docker与ctr命令不通用,各自管理自己的镜像和容器。 此外k8s还有客户端命令crictl,用法与docker基本相同,可crictl -h查看用法。 containerd的默认配置文件为/etc/containerd/config.toml,可通过命令:

输出默认配置,可参考文档https://github.com/containerd/containerd/blob/master/docs/ops.md

root键值用于存储containerd持久化数据。 state键值用于存储containerd临时性数据,设备重启后数据丢失。 显示containerd镜像

拉取hello-world镜像

注:必须全路径,从dockerhub上下载默认hello-world镜像。 运行容器

  参考: 1.https://github.com/containerd/containerd 2.https://containerd.io/docs/getting-started/ 3.Containerd 简介 4.Docker组件介绍(一):runc和containerd   from:https://www.cnblogs.com/embedded-linux/p/10850491.html

龙生   18 Feb 2021
View Details

docker从容器里面拷文件到宿主机或从宿主机拷文件到docker容器里面

1、从容器里面拷文件到宿主机? 答:在宿主机里面执行以下命令 docker cp 容器名:要拷贝的文件在容器里面的路径       要拷贝到宿主机的相应路径 示例: 假设容器名为testtomcat,要从容器里面拷贝的文件路为:/usr/local/tomcat/webapps/test/js/test.js,  现在要将test.js从容器里面拷到宿主机的/opt路径下面,那么命令应该怎么写呢? 答案:在宿主机上面执行命令

2、从宿主机拷文件到容器里面 答:在宿主机里面执行如下命令 docker cp 要拷贝的文件路径 容器名:要拷贝到容器里面对应的路径 示例:假设容器名为testtomcat,现在要将宿主机/opt/test.js文件拷贝到容器里面的/usr/local/tomcat/webapps/test/js路径下面,那么命令该怎么写呢? 答案:在宿主机上面执行如下命令

3、在这里在记录一个问题,怎么看容器名称? 执行命令:docker ps,出现如图所示,其中NAMES就是容器名了。 4.需要注意的是,不管容器有没有启动,拷贝命令都会生效。   from:https://www.cnblogs.com/areyouready/p/8973495.html

龙生   15 Jan 2021
View Details

Docker Toolbox替换默认docker machine的存储位置

一直想试试docker,但是docker高度依赖Linux内核,Windows7的机子用起来比较麻烦,由于某些契机还是用了起来。Windows想用docker的话,需要借助虚拟机,Windows7不像Windows10自带Hyper虚拟机,所以要用docker只有Docker Toolbox这个选择了。具体安装过程就不具体说了,官网也有详细的教程,不过让我最气的是联想的本本一直进入不了bios,最后Fn+F2进入bios启用虚拟设置。 Docker ToolBox安装 1、安装前,需要去bios启用虚拟设置,这样虚拟机才能运行。 2、安装,安装可选的工具: Kitematic,docker的界面化,没什么太大需要 Git,本来已安装的话也不用安装 3、修改 Docker QuickStart 快捷方式,将里面的Git的位置换成你的Git的安装位置(或者可以直接Git进入Docker Toolbox安装位置,运行./start.sh) 替换默认docker machine的存储位置 我相信大部分人都是直接安装官网的教程或者上面的安装方式直接安装的,但是将虚拟机安装在系统盘可能会带来各种问题,所以趁docker的镜像还没膨胀的时候赶快迁移吧。下面步骤可以在安装前做,这样可以减少删除已安装的default docker虚拟机。 1、在Windows的系统环境添加MACHINE_STORAGE_PATH ,指向虚拟机的位置(我推荐D:\VM\machines) 2、复制boot2docker.iso到虚拟机的位置同级目录cache上(D:\VM\cache),如果不是最新的话需要下载最新。 下面分两种情况: 如果还没安装default docker虚拟机,可以进入Docker QuickStart直接安装。 已安装了default docker虚拟机,需要先删除原来的,再安装到指定位置。 删除default docker虚拟机 1、进入Docker QuickStart命令行(Docker QuickStart不能进的话,用Git命令行) 2、运行docker-machine stop default,停止运行中的虚拟机 3、运行docker-machine rm default,删除默认的虚拟机 创建docker虚拟机 1、运行docker-machine create --driver=virtualbox default,等待创建完成 2、创建完成后,运行docker run hello-world测试。可以看到出现问题了:

  3、运行docker-machine env default,可以看到docker server的变量,copy变量在命令行中运行。 4、再次运行docker run hello-world测试,这次应该没问题。 修改docker 的配置 嫌弃官网的docker源太慢需要使用国内的源加速的话,要怎么配置呢? 1、运行docker-machine ssh default连接虚拟机 2、修改

  3、退出ssh,重启docker-machine restart default   from:https://www.cnblogs.com/ginponson/p/8601320.html

龙生   14 Jan 2021
View Details

docker安装kafka

  from:https://www.cnblogs.com/linjiqin/p/11891776.html

龙生   02 Nov 2020
View Details
1 3 4 5 8