docker镜像的制作

本文介绍了Dockerfile中的关键指令如COPY、ADD和ENTRYPOINT,并通过实例演示了如何使用busybox和Go语言编译的代码创建镜像。还详细讲解了镜像分层的概念以及如何优化镜像大小和共享资源。
摘要由CSDN通过智能技术生成

镜像的制作

dockerfile是制作镜像的配置文件

dockerfile指令:
COPY、ADD:复制宿主机里的文件或目录到容器里的某个目录下
ADD:如果复制的是.tar.gz压缩文件,拷贝到容器里会自动解压
CMD:启动容器的时候运行命令的,启动容器的时候会自动运行cmd里面的程序

ENTRYPOINT指令:
set指令能设置所使用shell的执行方式,可以依照不同的需求来做设置
参数:
-e:若指令传回值不等于0,则立即退出shell
-u:当执行时使用到未定义过的变量,则显示错误信息
-x:执行指令后,会显示该指令的执行过程及参数

案例1 – busybox

使用busybox作为基础镜像+自己编写一个脚本作为业务核心代码=完成自己的一个镜像

  1. 编写一个shell脚本,做镜像里的核心代码

    mkdir /Dockerfile
    cd /Dockerfile/
    
    [root@sc-docker Dockerfile]# cat while.sh 
    #!/bin/bash
    
    i=1
    while true
    do
    	echo "hello,sanchuang$i"
    	let i++
    	sleep 1
    done
    
  2. 编辑dockerfile文件

    [root@sc-docker Dockerfile]# cat Dockerfile 
    # 指定基础镜像
    FROM busybox
    # 指定进入容器的时候,进入哪个文件夹 docker exec 能看到效果
    WORKDIR /
    # 复制宿主机当前目录下的所有文件和文件夹到容器的/目录下 = docker up
    COPY . /
    # 制作镜像的时候需要执行的命令,这些文件会留在做好的镜像里
    RUN touch sc.txt && mkdir sanchuang && sleep 10
    # 指定容器启动的时候需要执行的命令
    # 相当于/bin/sh while.sh
    ENTRYPOINT ["/bin/sh","/while.sh"]
    
    
  3. 构建镜像

    docker build -t scbusybox:1.0 .
    

    -t:指定镜像的名字 scbusybox,1.0版本

    .:表示在当前文件夹下制作

  4. 查看制作好的镜像

    docker images
    
  5. 使用制作好的镜像

    docker run -it --rm --name scbusybox-1 scbusybox:1.0 
    

案例2 – 使用go语言编译好的代码制作镜像

  1. 编写一个简单的web服务器代码server.go

    [root@sc-docker go]# cat server.go 
    package main
    
    //server.go是主运行文件
    
    import (
        "net/http"
        "github.com/gin-gonic/gin"
    )
    
    //gin-->go中的web框架
    
    //入口函数
    func main(){
        //创建一个web服务器
        r:=gin.Default()
        // 当访问/sc=>返回{"message":"hello, sanchuang"}
        r.GET("/",func(c *gin.Context){
            //200,返回的数据
            c.JSON(http.StatusOK,gin.H{
                "message":"hello,sanchuanger 2023 nice",
            })
        })
    
        //运行web服务
        r.Run()
    }
    
    
  2. 安装go语言的环境

    yum install epel-release -y
    yum install golang -y
    
  3. 开始编译server.go成一个二进制文件

    [root@sc-docker go]# pwd
    /Dockerfile/go
    
    go mod init web
    go env -w GOPROXY=https://goproxy.cn,direct
    go mod tidy
    
    # 运行代码,默认监听的是8080端口,测试server.go文件能否正常运行
    go run server.go
    
    # 编译server.go成hnweb二进制文件
    # . 表示在当前文件目录下找
    go build -o hnweb .
    # 编译完成之后就可以使用./hnweb执行
    
  4. 编写Dockerfile

    [root@sc-docker go]# cat Dockerfile 
    FROM centos:7
    WORKDIR /go
    COPY . /go
    RUN ls /go && pwd
    ENTRYPOINT ["/go/hnweb"]
    
  5. 制作镜像

    docker build -t hnweb:1.0 .
    
  6. 启动容器

    docker run -d --name hnweb-1 -p 7788:8080 hnweb:1.0
    

    -d:后台运行

  7. 去宿主机的浏览器里访问http://192.168.232.152:7788

镜像分层

一个镜像由很多层数据组成

所有容器底层都是用宿主机的内核

base镜像
base镜像提供的是最小安装的Linux发行版
scratch是一个空的镜像,可以用于构建busybox等超小镜像,可以说是真正的从开始构建属于自己的镜像
bootfs – 容器启动的时候需要的内容
rootfs – 容器内部的操作系统

如何让制作的镜像比较小?

  1. 使用较小的基础镜像
  2. 减少使用RUN、COPY、ADD、WORKDIR的次数
  3. 使用镜像启动容器之后,再在里面安装软件,使用卷挂载数据

使用WORKDIR命令时,如果指定的目录是/,那么不会增加层数

容器启动的时候,内核启动bootfs后直接将基础镜像加载,然后一层一层加载(自下而上)
容器运行后访问文件的时候,从上而下,从可写层,一层一层往下访问

所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中。
只有容器层是可写的,容器层下面的所有镜像层都是只读的
1.添加文件
在容器中创建文件时,新文件被添加到容器层中。
2.读取文件
在容器中读取某个文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,打开并读入内存。
3.修改文件
在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之。
4.删除文件
在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作。

分层的好处在于共享资源,比如说有很多的镜像,可以从base镜像构建而来,那么docker host当中只需要在硬盘上保存一份base镜像即可,同时内存当中也只需要加载一份base镜像即可,也就是说我开多少的相同的镜像,内存在上涨值并不明显,就可以给所有的使用该base镜像的容器提供服务,而且镜像的每一层可以被单独的共享,也就是这一层如果跟其他的镜像重复的话,这一层就可以单独拿出来进行共享。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值