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

简介: Dockerfile提供了一个普通、简单和通用的语言来配置Docker镜像。使用 Dockerfile,用户可以使用任何偏好的方式来达到所期望的最终状态。用户可以调用Puppet,可以从其他脚本里复制,甚至可以从一个完整的文件系统复制!..................

 🍁作者简介:🏅云计算领域优质创作者🏅新星计划第三季python赛道TOP1🏅 阿里云ACE认证高级工程师🏅

✒️个人主页:小鹏linux

💊个人社区:小鹏linux(个人社区)欢迎您的加入!

目录

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

image.gif

在其中,创建Dockerfile和run.sh文件:

$ cd sshd_ubuntu/ 
$ touch Dockerfile run.sh 
$ ls 
Dockerfile run.sh

image.gif

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

脚本文件run.sh的内容与前面一致:

#!/bin/bash 
/usr/sbin/sshd -D

image.gif

在宿主主机上生成SSH密钥对,并创建authorized_keys文件:

$ ssh-keygen -t rsa 
... 
$ cat ~/.ssh/id_rsa.pub >authorized_keys

image.gif

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"]

image.gif

1.4 创建镜像


在sshd_ubuntu目录下,使用docker build命令来创建镜像。这里需要注意最后还有一个“.”,表示使用当前目录中的Dockerfile:

$ cd sshd_ubuntu 
$ docker build -t sshd:Dockerfile .

image.gif


如果大家使用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

image.gif

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

image.gif

在宿主主机新打开一个终端,连接到新建的容器:

$ ssh 192.168.1.200 -p 10122 
root@890c04ff8d76:~#

image.gif

效果与前面一致,镜像创建成功。

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 目录

image.gif

配置 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

image.gif

mkdir -p /etc/systemd/system/docker.service.d
systemctl daemon-reload && systemctl restart docker  #重启docker服务
systemctl enable docker   #设为开机自启

image.gif


写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"]

image.gif

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"]

image.gif

3.4 Google 内部精简镜像

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

image.gif

👑👑👑结束语👑👑👑

为大家推荐一款刷题神奇

网络异常,图片无法展示
|

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

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

image.gif

目录
相关文章
|
2月前
|
边缘计算 Cloud Native 安全
构建灵活高效的下一代应用架构 随着企业数字化转型的加速,云原生技术正逐渐成为构建现代化应用程序的关键支柱。
随着企业数字化转型加速,云原生技术逐渐成为构建现代化应用的关键。本文探讨了云原生的核心概念(如容器化、微服务、DevOps)、主要应用场景(如金融、电商、IoT)及未来发展趋势(如无服务器计算、边缘计算、多云架构),并分析了面临的挑战,如架构复杂性和安全问题。云原生技术为企业提供了更灵活、高效的应用架构,助力数字化转型。
68 4
|
17天前
|
Kubernetes Cloud Native Ubuntu
庆祝 .NET 9 正式版发布与 Dapr 从 CNCF 毕业:构建高效云原生应用的最佳实践
2024年11月13日,.NET 9 正式版发布,Dapr 从 CNCF 毕业,标志着云原生技术的成熟。本文介绍如何使用 .NET 9 Aspire、Dapr 1.14.4、Kubernetes 1.31.0/Containerd 1.7.14、Ubuntu Server 24.04 LTS 和 Podman 5.3.0-rc3 构建高效、可靠的云原生应用。涵盖环境准备、应用开发、Dapr 集成、容器化和 Kubernetes 部署等内容。
42 5
|
29天前
|
Cloud Native 持续交付 云计算
云原生技术深度探索:构建现代化应用的基石####
【10月更文挑战第21天】 本文将深入探讨云原生技术的核心概念、关键技术及其在现代软件开发中的应用。我们将从容器化、微服务架构、持续集成/持续部署(CI/CD)、无服务器架构等关键方面展开,揭示这些技术如何共同作用,帮助企业实现高效、弹性且易于维护的应用部署与管理。通过实例分析,展现云原生技术在实际项目中的显著优势,为读者提供一套全面理解并应用云原生技术的指南。 ####
34 2
|
20天前
|
监控 Cloud Native 微服务
云端漫步:探索云原生应用的构建与部署
【10月更文挑战第32天】在数字时代的浪潮中,云原生技术如同一艘航船,承载着企业的梦想驶向未知的海洋。本文将带你领略云原生应用的魅力,从基础概念到实战操作,我们将一步步揭开云原生的神秘面纱,体验它如何简化开发、加速部署,并提升系统的可扩展性与可靠性。让我们一起启航,探索云原生的世界!
|
2月前
|
Cloud Native Devops 云计算
云原生技术:构建现代应用的新基石
【10月更文挑战第12天】 本文深入探讨了云原生技术的核心理念、关键技术和实践方法,揭示了其在现代应用开发和运维中的重要地位。通过分析云原生技术的发展趋势和面临的挑战,本文为读者提供了全面而深入的理解,旨在帮助读者更好地利用云原生技术构建高效、灵活和可扩展的现代应用。
37 0
|
13天前
|
Cloud Native 安全 数据安全/隐私保护
云原生架构下的微服务治理与挑战####
随着云计算技术的飞速发展,云原生架构以其高效、灵活、可扩展的特性成为现代企业IT架构的首选。本文聚焦于云原生环境下的微服务治理问题,探讨其在促进业务敏捷性的同时所面临的挑战及应对策略。通过分析微服务拆分、服务间通信、故障隔离与恢复等关键环节,本文旨在为读者提供一个关于如何在云原生环境中有效实施微服务治理的全面视角,助力企业在数字化转型的道路上稳健前行。 ####
|
14天前
|
运维 Kubernetes Cloud Native
云原生技术:容器化与微服务架构的完美结合
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术以其灵活性和高效性成为企业的新宠。本文将深入探讨云原生的核心概念,包括容器化技术和微服务架构,以及它们如何共同推动现代应用的发展。我们将通过实际代码示例,展示如何在Kubernetes集群上部署一个简单的微服务,揭示云原生技术的强大能力和未来潜力。
|
16天前
|
消息中间件 存储 Cloud Native
云原生架构下的数据一致性挑战与应对策略####
本文探讨了在云原生环境中,面对微服务架构的广泛应用,数据一致性问题成为系统设计的核心挑战之一。通过分析云原生环境的特点,阐述了数据不一致性的常见场景及其对业务的影响,并深入讨论了解决这些问题的策略,包括采用分布式事务、事件驱动架构、补偿机制以及利用云平台提供的托管服务等。文章旨在为开发者提供一套系统性的解决方案框架,以应对在动态、分布式的云原生应用中保持数据一致性的复杂性。 ####
|
9天前
|
Cloud Native 云计算 Docker
云原生技术的崛起:从容器化到微服务架构
云原生技术的崛起:从容器化到微服务架构
|
12天前
|
Cloud Native 安全 API
云原生架构下的微服务治理策略与实践####
—透过云原生的棱镜,探索微服务架构下的挑战与应对之道 本文旨在探讨云原生环境下,微服务架构所面临的关键挑战及有效的治理策略。随着云计算技术的深入发展,越来越多的企业选择采用云原生架构来构建和部署其应用程序,以期获得更高的灵活性、可扩展性和效率。然而,微服务架构的复杂性也带来了服务发现、负载均衡、故障恢复等一系列治理难题。本文将深入分析这些问题,并提出一套基于云原生技术栈的微服务治理框架,包括服务网格的应用、API网关的集成、以及动态配置管理等关键方面,旨在为企业实现高效、稳定的微服务架构提供参考路径。 ####
39 5
下一篇
无影云桌面