编译型语言的Docker镜像构建小技巧

news2024/11/15 21:33:58

最近公司需要将一个底层服务打包成docker镜像,作为征战docker一年的小白当然不能错过这次练手的好机会。简单介绍一下这个项目:该项目为一个纯restful风格的后端项目,后端由java开发、worker节点由python开发、管理员使用的命令行工具由rust开发。当完成这份工作后记录下了整个过程中的心得体会

从标题也可以看出,主要是针对编译型语言的docker镜像构建小技巧,下文则分别对java、rust构建过程中的总结

一、整体思路

对于构建docekr镜像的优化技巧无非就是漏洞足够少、体积足够小。对于项目代码或依赖的包的漏洞不在本次讨论的范围类,除去这类漏洞本文主要关心docker镜像基于的liunx内核漏洞,因此一个安全、无漏洞的linux基础镜像是很有必要,这里给几个我常用的基础镜像

镜像名镜像大小包管理
amazonlinux194MByum
alpine5MBapk

amazonlinux是AWS提供的一个注重安全、稳定和高性能的执行环境来开发和运行云应用程序,完全免费且长期更新;alpine操作系统是一个面向安全的轻型Linux发行版,由非商业组织维护的,相比于其他Docker镜像,它的容量非常小,仅仅只有 5 MB 左右,且拥有非常友好的包管理机制。使用这类基础镜像构建出来的应用具备镜像下载速度加快,镜像安全性提高,主机之间的切换更方便,占用更少磁盘空间等。

对于镜像的漏洞则可以通过桌面版的Docker(Docker Desktop)更方便的查看,例如:

amazonlinux

image-20230129134246461

alpine

image-20230129134347337

而对于编译型语言开发的项目往往最终产物就是一个二进制文件,那么构建的思路则是将编译好的二进制文件放到相关的由alpine等镜像提供最基础依赖环境中即可,用到的就仅仅是docker的分层构建。下面则分别对java和rust构建的心得体会

二、构建 java 程序

公司java项目使用的包管理工具是maven,因此对于一个maven项目通常的构建流程就是:mvn package打包、java -jar运行,完成这两步最小依赖环境是java和maven,应用分层构建的思路第一步使用一个具备java和maven环境的基础镜像编译源代码,第二步拷贝第一步jar包到由alpine构建的jre镜像中运行。

很幸运阿里为我们提供了一个具备java和maven环境且使用阿里源的镜像,下载方式

docker pull registry.cn-hangzhou.aliyuncs.com/acs/maven:3-jdk-8

注:截止到文章发布,该镜像并没有支持jdk11已经更高的LTS版本

第一步编译源代码的Dockerfile如下

FROM registry.cn-hangzhou.aliyuncs.com/acs/maven:3-jdk-8 AS build-env

ENV MY_HOME=/app
RUN mkdir -p $MY_HOME
COPY . $MY_HOME

WORKDIR $MY_HOME/gateway

RUN ["/usr/local/bin/mvn-entrypoint.sh","mvn","package"]

第二步将需要拷贝第一步的jar

FROM openjdk:8-jre-alpine

# 更新内核
RUN apk update && apk upgrade

COPY --from=build-env /app/gateway/target/*.jar /gateway.jar

EXPOSE 1081

CMD ["java","-jar","/gateway.jar"]

注:

  1. apk update && apk upgrade主要是在构建过程中尝试更新一下内核,可能会存在一些比较新的漏洞,开源社区对这类漏洞已经提供了补丁,但镜像并没有及时更新发布,这就需要我们手动更新一下
  2. --from=build-env的作用就是分层构建的核心命令,只将我们需要的文件拷贝过来,最大化的减少镜像体积。同时复制过来的文件越少理论上漏洞越小

最终的Dockerfile文件如下

FROM registry.cn-hangzhou.aliyuncs.com/acs/maven:3-jdk-8 AS build-env

ENV MY_HOME=/app
RUN mkdir -p $MY_HOME
COPY . $MY_HOME

WORKDIR $MY_HOME/gateway

RUN ["/usr/local/bin/mvn-entrypoint.sh","mvn","package"]

####################################################################################################
## Final image
####################################################################################################
FROM openjdk:8-jre-alpine

# 更新内核
RUN apk update && apk upgrade

COPY --from=build-env /app/gateway/target/*.jar /gateway.jar

EXPOSE 1081

CMD ["java","-jar","/gateway.jar"]

构建完成后检查镜像漏洞信息

8f829ae39dbfd926079465ca9edd9b0c

其漏洞基本都是spring相关的漏洞不用管(提给后端同学让他们去修即可,大概率都是升级版本),且镜像的大小只有区区200MB不到

三、构建 rust 程序

rust程序的产物就是一个可执行的二进制程序,如果使用alpine来执行编译后的二进制程序大概率是报错的,因为alpine使用musl libc,其glibc在alpine不可用表现出来的现象就是缺少核心依赖,类比java就是没有把依赖打入jar中。因此rust在编译过程中需要使用x86_64-unknown-linux-musl以静态链接到rust程序中,而这部分和rust交叉编译是殊途同归的(在聊一聊我的第一个开源项目最后的交叉编译有涉及)。

FROM rust:latest as builder

RUN rustup target add x86_64-unknown-linux-musl

RUN apt update && apt upgrde && apt install -y musl-tools musl-dev

WORKDIR /

COPY . .

WORKDIR auth

RUN cargo build --target x86_64-unknown-linux-musl --release

####################################################################################################
## Final image
####################################################################################################
FROM alpine:latest

WORKDIR /auth

# Import from builder.
COPY --from=builder /auth/target/x86_64-unknown-linux-musl/release/auth ./

CMD ["echo","version:1.0.0 by superlab group"]

构建完成后检查镜像漏洞信息

ae9b93e39b6d6b9f0dca9b84c15a4af1

小而安全

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/184949.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

wpa_supplicant EAP状态机分析

EAP状态机分析RFC4137协议状态机设计原理模块划分SM状态定义SM状态转换SM使用到的变量及函数定义变量1.SM与LL交互使用到的变量列表2.SM与EM交互使用到的变量3.SM内部使用的变量函数wpas代码RFC4137协议 RFC4137:“State Machine for Extensible Authentication Pr…

强化学习笔记-01多臂老虎机问题

本文是博主对《Reinforcement Learning- An introduction》的阅读笔记,不涉及内容的翻译,主要为个人的理解和思考。 1. 多臂老虎机问题 多臂老虎机问题是指存在K个老虎机,每个老虎机的获胜金额是一个未知的概率分布且相互独立,假设…

一文解决Opencv四大经典算子——sobel算子、scharr算子、laplacian算子、canny算子

Opencv四大算子 Sobel算子Scharr算子laplacian算子canny算子总结边缘是像素值发生跃迁的位置,是图像的显著特征之一,在图像特征提取,对象检测,模式识别等方面都有重要的作用! Sobel算子 sobel算子对图像求一阶导数。一阶导数越大,说明像素在该方向的变化越大,边缘信号越…

python链接池和pymysql批量入库——从0实现大规模异步爬虫框架项目4

我将这个链接池和批量入库封装了一个工具类上传了pypi,可以直接import使用 使用也较为简单,导入PooledDBhelper的DBhelper,调用DBhelper.PooledDBhelper()方法传入数据库链接信息创建一个链接池即可 pip install PooledDBhelper1.0.0 -----------------…

虚析构函数的作用

类的析构函数是为了释放内存资源,析构函数不被调用的话就会造成内存泄漏。虚析构函数定义为虚析构函数是为了当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用。但并不是要把所有类的析构函数都写成虚函数。只有当一个类被用来作为基…

信息论复习—卷积码

目录 卷积码的基本概念: 卷积码与分组码的不同特点: 卷积码的构造与表示方法: 卷积码编码器的结构: 卷积码(3,1,3): 卷积码的卷积关系: 卷积码的生成矩阵: 卷积码的多项式: 系统码结构的卷积码: 卷积码的监督矩阵: 卷积…

Pipenv使用指南:轻量级虚拟环境管理工具详解

前言 终于能够挤出一点时间来总结最近学到的一些技术知识点了,博主这两周被居家隔离-集中隔离-居家隔离来回折腾,现在终于是得到解放能够空出的时间来写写博客了,但是项目又催的紧,写博文的时间还是有限,这周我会尽量…

正则语言的性质

正则语言的性质 一、正则语言的性质 1.正则语言的泵引理 设LLL是正则语言,则存在与LLL相关的常数nnn满足:对于任何LLL中的串www,如果∣w∣≥n|w|\geq n∣w∣≥n,则我们就能把www打断为三个串wxyzwxyzwxyz使得: y̸ϵ…

2011年专业408

文章目录0 结果1 题目2 思路2.1 思路1(暴力解:排序)2.2 思路2(较优解:归并合并数组)2.3 思路3(较优解:数组指针后移)2.4 思路4(最优解:两个数组的…

ARM BTI指令介绍

目录 一、JOP 二、BTI 三、启用BTI 四、BTI是怎么实现的 一、JOP JOP(Jump-oriented programming)类似于ROP(Return-Oriented Programming)。在 ROP 攻击中,会扫描出useful gadgets(易被攻击的一段代码…

【数据结构】顺序队列的原理及实现

1.什么是队列 队列是一种比较特殊的线性表,特殊就在于它只允许在表的前端来进行删除,在表的后端来进行插入,队列它是一种操作受限制的线性表。插入的一端称为队尾,删除的一端称为队头,队列里没有元素就称它为空队列。…

快速使用代码编辑工具vim+ctags+cscope快捷使用itop3568开发板

当以上配置全部完成后,每当拿到新的工程代码,进入相关代码目录,利用 vim ./命令打 开当前目录, 然后 crtl 生成插件所需文件,最后使用命令:qa!退出 vim。此步只需进行一 次。 在此目录中打开任意代码文件或任意子目录…

jdk8新特性-日期时间

1、介绍 日期时间类在Java开发中是必不可少的,前后端如何传递时间参数、数据库的时间在Java中对应什么类型、Java中时间转换的各种方式有哪些? 2、Date类 Date类是JDK1.0时期推出来的第一代时间类,位于java.util包下,是最常用的…

unctf easy_serialize反序列化字符逃逸

&#xfeff;ctf题目平台&#xff1a;UNCTF - HACKING 4 FUN。web题难度适中 easy_serialize 题目源码&#xff1a; <?php include "function.php"; $action $_POST[action]; $name $_POST[name]; $pass $_POST[pass]; $email $_POST[email]; ​ function …

南京小米java面经(一面)

目录1.java支持多继承吗2.线程的生命周期3.线程和进程的区别4.单例模式有几种5.写一下双重锁的单例6.jvm有哪些区域7.jvm哪些区域是线程共享的&#xff0c;哪些是线程私有的8.gc中判断对象可回收的方式有哪些9.gc垃圾回收算法有哪些10.哪些对象可以作为gc root11.gc中的引用计数…

软件设计师教程(四)程序设计语言基础知识

软件设计师教程 软件设计师教程&#xff08;一&#xff09;计算机系统知识-计算机系统基础知识 软件设计师教程&#xff08;二&#xff09;计算机系统知识-计算机体系结构 软件设计师教程&#xff08;三&#xff09;计算机系统知识-计算机体系结构 程序设计语言知识软件设计师…

工资管理系统

一、系统简介 工资管理涉及企业管理的多个方面&#xff0c;如员工基本信息、员工在职离岗、员工考勤、员工加班等等。根据这些信息&#xff0c;在每个月的固定时间&#xff0c;生成全体员工的月工资&#xff0c;部门月工资以及全厂月工资。对于月工资&#xff0c;能够实现按照员…

机器学习【西瓜书/南瓜书】--- 第五章 神经网络

1.神经元模型 1.1 M-P神经元模型 输出函数&#xff1a; 其中θ为阈值&#xff0c; ω i为第i个神经元的连接权重&#xff0c; xi为来自第i个神经元的输入。 1.2 激活函数 阶跃函数&#xff1a; 理论上我们使用阶跃函数。将输入值映射为输出值为0/1&#xff0c;显然1为神经元…

Windows下编译安装OpenCASCADE

OpenCASCADE (以下简称OCC)是一套开源的几何建模系统&#xff0c;提供了曲面、实体等建模方式&#xff0c;已经广泛应用在CAD、CAE、CAM等软件开发。 OpenCASCADE官网已经提供OpenCASCADE的编译安装方法&#xff0c;本文结合实操过程&#xff0c;简述其过程。 零、环境 操作系…

Databend v0.9.0 版本发布

各位社区小伙伴们&#xff0c;历经数月开发&#xff0c;Databend 于 2023 年 1 月 13 日迎来了 v0.9.0 版本的正式发布&#xff01; 这次新版本是 Databend 迈向 1.0 版本的最后一个大版本&#xff0c;也是迄今为止我们对核心代码重构幅度最大的一个版本&#xff01;相较于 v0…