背景

在之前的文章中介绍如何用docker编译前端项目,docker编译项目的有点前面已经说的很清楚了这边就不在赘述,后端开发语言较多,我们就以java为例,介绍如何用maven镜像进行编译

实现

  • 我们准备一个java项目,使用maven进行包管理
  • 执行以下命令进行编译
docker run -it --rm --name my-maven-project -v "/you/path/app":/usr/app -w /usr/app maven:3.8.1-openjdk-8-slim mvn clean package

将项目挂载到容器文件系统路径/usr/app下,-w将工作目录指定到/usr/app下,–rm可以保证编译完删除镜像,避免占用空间。

首次编译因为本地没有下载依赖所以会先下载依赖包,再执行编译打包命令,这个结果不是我们想要的,如果一个工程依赖的包很多,每次都要重新下载效率会非常低,其实只要把maven的repository目录映射出来就行

Read the rest of this entry

介绍

nodejs官方提供docker镜像,并且镜像自带npm工具,也就是说,完全可以用docker镜像编译本地前端项目,那相比本地安装nodejs编译,docker编译有哪些优势呢

  • 可以安装多个版本nodejs,可以选择指定版本nodejs进行编译,如果你是要搭建一个构建平台,这是个非常好的方案
  • 免安装,如果需要安装多版本nodejs,这个优势就很明显了
  • 不会污染本地环境

如果你是个人开发,使用docker编译项目相对有点极客行为,在个人开发上并没有太大的优势,但是如果你是要搭建一个构建系统,那么docker镜像的方案是你最好的选择。

实现

虽然nodejs官方提供了镜像但实践下来如果直接用官方的镜像,无法达到想要的效果,原因有以下几点

Read the rest of this entry

介绍

nodejs官方提供docker镜像,并且镜像自带npm工具,也就是说,完全可以用docker镜像编译本地前端项目,那相比本地安装nodejs编译,docker编译有哪些优势呢

  • 可以安装多个版本nodejs,可以选择指定版本nodejs进行编译,如果你是要搭建一个构建平台,这是个非常好的方案
  • 免安装,如果需要安装多版本nodejs,这个优势就很明显了
  • 不会污染本地环境

如果你是个人开发,使用docker编译项目相对有点极客行为,在个人开发上并没有太大的优势,但是如果你是要搭建一个构建系统,那么docker镜像的方案是你最好的选择。

实现

虽然nodejs官方提供了镜像但实践下来如果直接用官方的镜像,无法达到想要的效果,原因有以下几点

  • nodejs项目初衷是用javascript作为后端预言,所以镜像主要是用于后端服务
  • 镜像虽然自带了npm工具,但因为WORKDIR的关系无法正常编译,尝试过多种方法还是无法顺利编译
  • 基于官方的镜像做二次构建成本很低,所以建议根据自己的需求做二次构建

我们先实现一个npm install功能的镜像

Read the rest of this entry

如果客户提出一个需求要在网页打开计算器,你可千万别以为是很简单的事,事实上,如果不借助“外力”是根本办不到。

背景

某项目客户提了这么一个需求

  • 需要在chrome浏览器中打开IE和firefox
  • 需要在firefox中打开IE和chrome
  • 需要在IE中打开firefox和chrome

总结下就是能在任意浏览器中打开任意浏览器,乍听之下觉得很扯是不是,觉得是个傻逼需求是不是,事实上,我的第一反应也是这样的,但了解事情背景后发现这是个很合理的需求,背景是客户有几个个遗留的老系统,其中核心业务系统只能运行在IE上,某BI系统只能运行在firefox上,你可能觉得很奇怪,只支持IE这个可以理解,只支持firefox这个有点匪夷所思,但事实确实如此,我们也不必去深究,现在客户要做门户,需要在门户上单点到所有系统,那么就有了上面的需求。

沙盒模型

想象一下如果javascript能读写本地文件会发生什么事

  • 打开百度你的资料可能就全部泄漏了
  • 打开百度可能就给你悄悄装上全家桶了
  • 打开百度你的盘可能就被格式化了
  • …..

Read the rest of this entry

背景

客户有一个java应用比较耗内存,在kubernetes上对cpu和内存进行了限制,但效果不大好,应用经常被kill掉,由于该应用属于核心应用,后面就解除限制,在jvm上对堆内存进行了限制,因为没有配置kubernetes资源请求限制,kubernetes在调度上就无法灵活调度,经常将多个副本调度到同一节点,多个大内存应用运行在同一个节点,内存很容易就被耗尽导致jvm gc频繁,频繁的gc又导致了服务器cpu负载过大,最终应用挂掉无法访问。如果kubernetes能将应用多个副本调度到不同节点那么至少能保证一个节点挂掉,其他节点应用还可以继续服务。

方案

  • DaemonSet

首先想到的是DaemonSet,DaemonSet能保证应用跑在不同的节点,但DaemonSet应用场景一般是作为守护进程或者日志收集,并且每个节点都会部署一个副本,这并不是我们想要的结果,因此不考虑DaemonSet。

Read the rest of this entry

背景

客户通过Jenkins流水线构建镜像上传harbor部署到kubernetes,经过不断的CI/CD,harbor占用空间不断增大,但旧的镜像其实是可以删除掉,保留最新的几个版本供回滚就可以,因此需要制定删除策略,目前情况如下

  • 保留每个镜像最新3个版本即可
  • 用户通过tag区分环境,比如 definesys/hr:dev.20210601,definesys/hr:uat.20210601,这样就导致如果保留最新3个镜像,有可能都保留了dev.xxx,其他环境的都被删除,因此也要考虑按照环境做分组,只保留每个分组内的最新3个版本即可

harbor本身并没有提供类似的功能,但是harbor有完善的restapi,因此可以自己写工具去实现以上需求。

方案

  • java开发清理程序,打包为jar包,通过Main运行
  • 通过jenkins打包应用并执行清理动作

之所以选择jenkins运行jar包,是因为jenkins可以提供配置参数界面,可以将清理程序的一些配置项通过jenkins传入,省的再去开发界面,而且jenkins有定时调度的功能,可以实现定时清理的功能。

Read the rest of this entry

,

背景

某客户kubernetes集群新加了一个节点,新节点部署应用后,应用会间歇性unavaliable,用户访问报503,没有事件消息,主机状态也正常。

排查

初步怀疑是新节点问题,在系统日志/var/log/messagedmesg中都未发现相关错误信息,在kubelet中发现以下日志

kubernetes集群时通过rke进行安装,可以在节点上直接执行命令docker logs -f --tail=30 kubelet查看kubelet日志
E0602 03:18:27.766726    1301 controller.go:136] failed to ensure node lease exists, will retry in 7s, error: an error on the server ("") has prevented the request from succeeding (get leases.coordination.k8s.io k8s-node-dev-6)
E0602 03:18:34.847254    1301 reflector.go:178] k8s.io/client-go/informers/factory.go:135: Failed to list *v1.CSIDriver: an error on the server ("") has prevented the request from succeeding (get csidrivers.storage.k8s.io)
I0602 03:18:39.176996    1301 streamwatcher.go:114] Unexpected EOF during watch stream event decoding: unexpected EOF
E0602 03:18:43.771023    1301 controller.go:136] failed to ensure node lease exists, will retry in 7s, error: an error on the server ("") has prevented the request from succeeding (get leases.coordination.k8s.io k8s-node-dev-6)

Read the rest of this entry

,