jjzjj

【云原生 | 15】Dockerfile构建镜像实战

小鹏linux 2024-04-22 原文

🍁博主简介
        🏅云计算领域优质创作者
        🏅2022年CSDN新星计划python赛道第一名

        🏅2022年CSDN原力计划优质作者
        🏅阿里云ACE认证高级工程师
        🏅阿里云开发者社区专家博主

💊交流社区CSDN云计算交流社区欢迎您的加入!

目录

1.使用Dockerfile创建镜像

1.1 创建工作目录

1.2 编写run.sh脚本和authorized_keys文件

1.3 编写Dockerfile 

1.4 创建镜像 

 1.5 测试镜像,运行容器

2. 镜像的多级构建

3. Docker image Build 高级

3.1 镜像 Cache 机制

3.2 Cache 机制的注意事项

3.3 命名方式的 stage 

3.4 Google 内部精简镜像 


Dockerfile被认为是构建Docker镜像的标准方式。人们常常会疑惑Dockerfile对于配置管理意味着什么。读者也可能会有许多疑问(尤其是在对一些其他配置管理工具有些经验的时候),例如:
🩸如果基础镜像更改会发生什么?
🩸如果更改要安装的包然后重新构建会发生什么?
🩸它会取代Chef/Puppet/Ansible吗?
事实上,Dockerfile很简单:从给定的镜像开始,Dockerfile为Docker指定一系列的shell命令和元指令,从而产出最终所需的镜像。
Dockerfile提供了一个普通、简单和通用的语言来配置Docker镜像。使用 Dockerfile,用户可以使用任何偏好的方式来达到所期望的最终状态。用户可以调用Puppet,可以从其他脚本里复制,甚至可以从一个完整的文件系统复制!
并不推荐使用 docker commit 的方法来构建镜像。相反,推荐使用被称为Dockerfile 的定义文件和 docker build 命令来构建镜像。Dockerfile使用基本的基于DSL(Domain Specific Language))语法的指令来构建一个Docker镜像,我们推荐使用Dockerfile 方法来代替docker commit ,因为通过前者来构建镜像更具备可重复性、透明性以及幂等性。

1.使用Dockerfile创建镜像

1.1 创建工作目录

首先,创建一个sshd_ubuntu工作目录:
$ mkdir sshd_ubuntu 
$ ls 
sshd_ubuntu
在其中,创建Dockerfile和run.sh文件:
$ cd sshd_ubuntu/ 
$ touch Dockerfile run.sh 
$ ls 
Dockerfile run.sh

1.2 编写run.sh脚本和authorized_keys文件

脚本文件run.sh的内容与前面一致:
#!/bin/bash 
/usr/sbin/sshd -D
在宿主主机上生成SSH密钥对,并创建authorized_keys文件:
$ ssh-keygen -t rsa 
... 
$ cat ~/.ssh/id_rsa.pub >authorized_keys

1.3 编写Dockerfile 

下面是Dockerfile的内容及各部分的注释,可以对比上一节中利用docker commit命令创建镜像过程,所进行的操作基本一致:
#设置继承镜像
FROM ubuntu:14.04 
#提供一些作者的信息
MAINTAINER docker_user (user@docker.com) 
#下面开始运行更新命令
RUN apt-get update 
#安装ssh服务
RUN apt-get install -y openssh-server 
RUN mkdir -p /var/run/sshd 
RUN mkdir -p /root/.ssh 
#取消pam限制
RUN sed -ri 's/session required pam_loginuid.so/#session required pam_loginuid.so/g' /etc/pam.d/sshd 
#复制配置文件到相应位置,并赋予脚本可执行权限
ADD authorized_keys /root/.ssh/authorized_keys 
ADD run.sh /run.sh 
RUN chmod 755 /run.sh 
#开放端口
EXPOSE 22 
#设置自启动命令
CMD ["/run.sh"]

1.4 创建镜像 

在sshd_ubuntu目录下,使用docker build命令来创建镜像。这里需要注意最后还有一个“.”,表示使用当前目录中的Dockerfile:
$ cd sshd_ubuntu 
$ docker build -t sshd:Dockerfile .
如果大家使用Dockerfile创建自定义镜像,那么需要注意的是Docker会自动删除中间临时创建的层,还需要注意每一步的操作和编写的 Dockerfile中命令的对应关系。
命令执行完毕后,如果读者可见“Successfully built XXX”字样,则说明镜像创建成功。可以看到,以上命令生成的镜像ID是 570c26a9de68。
在本地查看sshd:Dockerfile镜像已存在:
$ docker images 
REPOSITORY       TAG         IMAGE ID         CREATED         VIRTUAL SIZE 
sshd             Dockerfile  570c26a9de68     4 minutes ago   246.5 MB 
sshd             ubuntu      7aef2cd95fd0     12 hours ago    255.2 MB 
busybox          latest      e72ac664f4f0     3 weeks ago     2.433 MB 
ubuntu           14.04       ba5877dc9bec     3 months ago    192.7 MB 
ubuntu           latest      ba5877dc9bec     3 months ago    192.7 MB

 1.5 测试镜像,运行容器

使用刚才创建的sshd:Dockerfile镜像来运行一个容器。
直接启动镜像,映射容器的22端口到本地的10122端口:
$ docker run -d -p 10122:22 sshd:Dockerfile 890c04ff8d769b604386ba4475253ae8c21fc92d60083759afa77573bf4e8af1 
$ docker ps 
CONTAINER ID     IMAGE     COMMAND     CREATED     STATUS     PORTS     NAMES 
890c04ff8d76     sshd:Dockerfile "/run.sh" 4 seconds ago Up 3 seconds   0.0.0.0:10122->22/tcp high_albattani
在宿主主机新打开一个终端,连接到新建的容器:
$ ssh 192.168.1.200 -p 10122 
root@890c04ff8d76:~#
效果与前面一致,镜像创建成功。

2. 镜像的多级构建

Dockerfile > 镜像(写Dockerfile文件,然后docker build -t 镜像名 Dockerfile文件路径 =镜像)

17.09以后的版本才支持,此版本之后的Ddockerfile文件中可以添加多个FROM,多级,前几级都只是充当基础

编译型语言才能支持多级构建,如:golong语言,java语言等。解释性语言如php,ruby,python等不支持多级构建

即:如何制作镜像时将 镜像做到最小。

安装 Docker 最新版软件

yum install -y yum-utils device-mapper-persistent-data lvm2	#先安装最新版docker所需的依赖及工具
yum-config-manager  --add-repo  http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo		#配置yum源
yum install -y docker-ce	#安装软件
mkdir /etc/docker		#创建 /etc/docker 目录
配置 daemon.注入以下内容:
cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "insecure-registries": ["harbor.hongfu.com"],
  "registry-mirrors": ["https://kfp63jaj.mirror.aliyuncs.com"]
}
EOF
mkdir -p /etc/systemd/system/docker.service.d
systemctl daemon-reload && systemctl restart docker  #重启docker服务
systemctl enable docker		#设为开机自启

写Dockerfile文件,在文件中可以写多个FROM调用镜像,还可以给每个被调用的镜像重命名,方便后续的FROM调用前面的FROM

例如:Dockerfile文件

FROM golang:1.7.3
WORKDIR /go/src/github.com/sparkdevo/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go    .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/sparkdevo/href-counter/app .		#--from=0即调用第一个FROM
CMD ["./app"]

3. Docker image Build 高级

3.1 镜像 Cache 机制

Docker Daemnon 通过 Dockerfile 构建镜像时,当发现即将新构建出的镜像与已有的某镜像重复时,可以选择放弃构建新的镜像, 而是选用已有的镜像作为构建结果,也就是采取本地已经 cache 的镜像作为结果

3.2 Cache 机制的注意事项

ADD 命令与 COPY 命令:Dockerfile 没有发生任何改变,但是命令ADD run.sh / 中 Dockerfile 当前目录下的 run.sh 却发生了 变化,从而将直接导致镜像层文件系统内容的更新,原则上不应该再使用cache。那么,判断 ADD 命令或者 COPY 命令后 紧接 的文件是否发生变化,则成为是否延用cache 的重要依据。Docker 采取的策略是:获取 Dockerfile 下内容(包括文件 的部分 inode 信息),计算出一个唯一的 hash 值,若 hash 值未发生变化,则可以认为文件内容没有发生变化,可以使 用 cache 机制;反之亦然
RUN 命令存在外部依赖:一旦 RUN 命令存在外部依赖,如RUN apt-get update,那么随着时间的推移,基于同一个基础镜像, 一年的 apt-get update 和一年后的 apt-get update, 由于软件源软件的更新,从而导致产生的镜像理论上应该不同。如果继 续使用cache 机制,将存在不满足用户需求的情况。Docker 一开始的设计既考虑了外部依赖的问题,用户可以使用参数 --no-cache 确保获取最新的外部依赖,命令为docker build --no-cache -t="my_new_image" .
树状的镜像关系决定了,一次新镜像的成功构建将导致后续的 cache 机制全部失效:这一点很好理解,一旦产生一个新的镜 像,同时意味着产生一个新的镜像 ID,而当前宿主机环境中肯定不会存在一个镜像,此镜像ID的父镜像 ID 是新产生镜像 的ID。这也是为什么,书写 Dockerfile 时,应该将更多静态的安装、配置命令尽可能地放在 Dockerfile 的较前位置

3.3 命名方式的 stage 

命名方式的 stage: 旧版本的 docker 是不支持 multi-stage 的,只有 17.05 以及之后的版本才开始支持
FROM golang:1.7.3 as builder
WORKDIR /go/src/github.com/sparkdevo/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go    .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/sparkdevo/href-counter/app .
CMD ["./app"]

3.4 Google 内部精简镜像 

git clone https://github.com/GoogleContainerTools/distroless	#访问不到用下方地址代理
hub.fastgit.org/GoogleContainerTools/distroless

  👑👑👑结束语👑👑👑

为大家推荐一款刷题神奇 点击链接访问牛客网https://www.nowcoder.com/link/jihexinliang260

各大互联网大厂面试真题。基础题库到进阶题库等各类面试题应有尽有!

牛客网面经合集,满足大厂面试技术深度,快速构建Java核心知识体系大厂面试官亲授,备战面试与技能提升,主要考点+主流场景+内功提升+真题解析

有关【云原生 | 15】Dockerfile构建镜像实战的更多相关文章

  1. ruby - 在 Ruby 中构建长字符串的简洁方法 - 2

    在编写Ruby(客户端脚本)时,我看到了三种构建更长字符串的方法,包括行尾,所有这些对我来说“闻起来”有点难看。有没有更干净、更好的方法?变量递增。ifrender_quote?quote="NowthatthereistheTec-9,acrappyspraygunfromSouthMiami."quote+="ThisgunisadvertisedasthemostpopularguninAmericancrime.Doyoubelievethatshit?"quote+="Itactuallysaysthatinthelittlebookthatcomeswithit:themo

  2. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  3. ruby - 使用 rbenv 和 ruby​​-build 构建 ruby​​ 失败,出现 undefined symbol : SSLv2_method - 2

    我正在尝试在配备ARMv7处理器的SynologyDS215j上安装ruby​​2.2.4或2.3.0。我用了optware-ng安装gcc、make、openssl、openssl-dev和zlib。我根据README中的说明安装了rbenv(版本1.0.0-19-g29b4da7)和ruby​​-build插件。.这些是随optware-ng安装的软件包及其版本binutils-2.25.1-1gcc-5.3.0-6gconv-modules-2.21-3glibc-opt-2.21-4libc-dev-2.21-1libgmp-6.0.0a-1libmpc-1.0.2-1libm

  4. ruby-on-rails - 如何构建复杂的 Rails 系统 - 2

    关闭。这个问题需要更多focused.它目前不接受答案。想改进这个问题吗?更新问题,使其只关注一个问题editingthispost.关闭8年前。Improvethisquestion我们有以下(以及更多)系统,我们将数据从一个应用推送/拉取到另一个:托管CRM(InsideSales.com)Asterisk电话系统(内部)横幅广告系统(openx,我们托管)潜在客户生成系统(自行开发)电子商务商店(spree,我们托管)工作板(本土)一些工作网站抓取+入站工作提要电子邮件传送系统(如Mailchimp,自主开发)事件管理系统(如eventbrite,自主开发)仪表板系统(大量图表和

  5. ruby-on-rails -/usr/local/lib/libz.1.dylib,文件是为 i386 构建的,它不是被链接的体系结构 (x86_64) - 2

    在我的mac上安装几个东西时遇到这个问题,我认为这个问题来自将我的豹子升级到雪豹。我认为这个问题也与macports有关。/usr/local/lib/libz.1.dylib,filewasbuiltfori386whichisnotthearchitecturebeinglinked(x86_64)有什么想法吗?更新更具体地说,这发生在安装nokogirigem时日志看起来像:xslt_stylesheet.c:127:warning:passingargument1of‘Nokogiri_wrap_xml_document’withdifferentwidthduetoproto

  6. 【云原生】SpringCloud-Spring Boot Starter使用测试 - 2

    目录SpringBootStarter是什么?以前传统的做法使用SpringBootStarter之后starter的理念:starter的实现: 创建SpringBootStarter步骤在idea新建一个starter项目、直接执行下一步即可生成项目。 在xml中加入如下配置文件:创建proterties类来保存配置信息创建业务类:创建AutoConfiguration测试如下:SpringBootStarter是什么? SpringBootStarter是在SpringBoot组件中被提出来的一种概念、简化了很多烦琐的配置、通过引入各种SpringBootStarter包可以快速搭建出一

  7. ruby - Ruby 语言可以用来构建操作系统吗? - 2

    Ruby语言是否可以用于创建全新的移动操作系统或桌面操作系统,即是否可以用于系统编程? 最佳答案 嗯,现在有一些操作系统使用比C更高级的语言。基本上,ruby解释器本身需要用一些低级的东西来编写,并且需要一些引导加载代码将功能齐全的ruby​​解释器作为独立内核加载到内存中。一旦ruby​​解释器被引导并以内核模式(或innerrings之一)运行,就没有什么可以阻止您在其上构建整个操作系统。不幸的是,它可能会很慢。每个操作系统功能的垃圾收集可能会相当引人注目。ruby解释器将负责任务调度和网络堆栈等基本事情,使用垃圾收集框架会大大

  8. ruby-on-rails - 无法构建 gem native 扩展 (mkmf (LoadError)) - Ubuntu 12.04 - 2

    这个问题在这里已经有了答案:Unabletoinstallgem-Failedtobuildgemnativeextension-cannotloadsuchfile--mkmf(LoadError)(17个答案)关闭9年前。嘿,我正在尝试在一台新的ubuntu机器上安装rails。我安装了ruby​​和rvm,但出现“无法构建gemnative扩展”错误。这是什么意思?$sudogeminstallrails-v3.2.9(没有sudo表示我没有权限)然后它会输出很多“获取”命令,最终会出现这个错误:Buildingnativeextensions.Thiscouldtakeawhi

  9. ruby-on-rails - 如何使用 ruby​​ on rails 构建 openid 提供程序 - 2

    我尝试了一些关于ruby​​onrails中openid利用率的搜索。然而,尽管出现了一组选项,例如omniauth、authlogic等,但这些gem通常用于构建接受openid身份验证的站点。换句话说,它们用于openid消费者设置。我也想构建自己的openid服务器。AssuggestedhereinOpenIdsite我发现了像Masquerade和local-openid这样的东西,不幸的是,它们不是非常活跃的项目,下载量很少。自建openidprovider服务器有没有其他设施可以推荐?非常感谢!!干杯,叶 最佳答案 虽

  10. ruby - 使用 Ruby 构建聊天应用程序 - 2

    我正在尝试构建一个纯粹使用Ruby的聊天应用程序。有一个similarquestion较早发布,但我有不同的相关查询。我看过thisexample(与之前发布类似问题的人所提到的相同)。示例中的代码似乎对我不起作用。在终端上运行ruby​​脚本,并连接到url:http://localhost:1234在我的浏览器中,我无限期地遇到“正在从本地主机传输数据...”消息。此处的1234是所提供示例中使用的端口号。我无法弄清楚我运行失败的原因是什么。可能是我需要在执行脚本时在命令行中指定一些东西,或者我应该通过其他地方(可能是浏览器)开始聊天(输入输出)。我无法弄清楚到底该做什么。你能帮我

随机推荐