ToB企服应用市场:ToB评测及商务社交产业平台

标题: 制作Docker镜像 [打印本页]

作者: 风雨同行    时间: 2024-5-29 10:21
标题: 制作Docker镜像
目次

一、Docker构建镜像的原理

1、镜像分层原理

Docker镜像是由一系列只读的层(layers)构成的,每个层代表了一组文件系统的更改。这些更改可以是添加文件、删除文件、修改文件等操纵。镜像的最底层通常是一个基础镜像,比如基于CentOS、Ubuntu、Alpine等操纵系统。往上每一层代表了Dockerfile中每个指令的执行结果。重要的是,每一层都是不可变的,一旦创建就不会被修改,新的更改会在其上新建一层。
2、Docker的镜像结构


docker的分层镜像结构如图所示,镜像的最底层必须是一个启动文件系统(bootfs)的镜像层。bootfs的上层镜像称为根镜像(rootfs)大概基础镜像(Base Image),它一般是操纵系统,比如centos、debian大概Ubuntu。
用户的镜像必须构建在基础镜像之上。如图所示,emacs镜像层就是在基础镜像上安装emacs创建出来的镜像,在此基础上安装apache又创建了新的镜像层。利用这个新的镜像层启动的容器里运行的是一个已经安装好emacs和apache的Debian系统。
3、分层存储原理

Docker镜像采取UnionFS(团结文件系统,如AUFS、OverlayFS等)实现分层存储。UnionFS允许将多个文件系统层次叠加以形成一个单一的归并视图。对于Docker镜像来说,每个层都是只读的,除了最顶层的可写层(在容器运行时创建)。
4、构建命令与层的关系

5、最终镜像的创建

构建过程的最后,Docker将全部这些层组合起来,并为这个组合赋予一个唯一的ID,这就是最终的Docker镜像。这个镜像可以被打上标签(tag),便于辨认和后续的拉取、推送操纵。
二、docker commit 构建镜像

1、利用场景

2、手动制作yum版的nginx镜像

2.1、启动一个centos容器,安装好常用的软件以及nginx
  1. [root@localhost ~]# docker run -it --name centos-v1 centos:7 bash
  2. [root@95ef0464ffb2 /]# yum install -y epel-release
  3. [root@95ef0464ffb2 /]# yum install -y nginx
  4. [root@95ef0464ffb2 /]# yum install -y wget vim pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop
复制代码
2.2、关闭nginx配景运行
  1. [root@95ef0464ffb2 /]# sed -i '/^pid \/run\/nginx.pid;$/a daemon off;' /etc/nginx/nginx.conf
  2. [root@95ef0464ffb2 /]# egrep -v "^$|^#" /etc/nginx/nginx.conf | head -5
  3. user nginx;
  4. worker_processes auto;
  5. error_log /var/log/nginx/error.log;
  6. pid /run/nginx.pid;
  7. daemon off;
复制代码
2.3、自界说web页面
  1. [root@95ef0464ffb2 /]# echo 'hello yum_nginx' > /usr/share/nginx/html/index.html
复制代码
2.4、提交为镜像
  1. docker commit -m "my first nginx image v1" centos-v1 centos_nginx:v1
复制代码

2.5、从自己的镜像启动容器
  1. docker run -d -p 8080:80 --name my_centos_nginx centos_nginx:v1 /usr/sbin/nginx
复制代码

三、DockerFile

1、什么是DockerFile

DockerFile 是一个用于自动构建 Docker 镜像的文本文件,其中包罗了用户可以给出的全部构建镜像所需的指令和参数。
这个文件按照从上至下的次序界说了一系列构建镜像的步骤,每个指令通常对应于镜像中的一个层。
DockerFile 的设计使得镜像的创建过程高度可编程、可重复及可共享,有利于实现持续集成和持续摆设(CI/CD)的工作流程。
2、DockerFile构建镜像过程

1、起首,创建一个目次用于存放应用程序以及构建过程中利用到的各个文件等;
2、然后,在这个目次下创建一个Dockerfile文件,一般发起Dockerfile的文件名就是Dockerfile;
3、编写Dockerfile文件,编写指令,如,利用FROM 指令指定基础镜像,COPY指令复制文件,RUN指令指定要运行的命令,ENV设置环境变量,EXPOSE指定容器要暴露的端口,WORKDIR设置当前工作目次,CMD容器启动时运行命令,等等指令构建镜像;
4、Dockerfile编写完成就可以构建镜像了,利用docker build -t 镜像名:tag . 命令来构建镜像,最后一个点是表示当前目次,docker会默认寻找当前目次下的Dockerfile文件来构建镜像,假如不利用默认,可以利用-f参数来指定dockerfile文件,如:docker build -t 镜像名:tag -f /xx/xxx/Dockerfile ;
5、利用docker build命令构建之后,docker就会将当前目次下全部的文件发送给docker daemon,次序执行Dockerfile文件里的指令,在这过程中会生成临时容器,在临时容器内里安装RUN指定的命令,安装乐成后,docker底层会利用类似于docker commit命令来将容器保存为镜像,然后删除临时容器,以此类推,一层层的构建镜像,运行临时容器安装软件,直到最后的镜像构建乐成。
四、DockerFile的常用指令

官方文档
1、FROM

指定基础镜像,必须为第一个命令
1.1、指令格式
  1. FROM [--platform=<platform>] <image> [AS <name>]
  2. FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
  3. FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
复制代码

1.2、示例
  1. ARG  CODE_VERSION=latest
  2. FROM base:${CODE_VERSION}
  3. CMD  /code/run-app
  4. FROM extras:${CODE_VERSION}
  5. CMD  /code/run-extras
复制代码
2、ARG

界说创建镜像过程中利用的变量
ARG是唯一可以位于FROM指令之前的指令
2.1、指令格式
  1. ARG <name>[=<default value>]
复制代码
是变量名,[=]是可选的默认值。
2.2、作用域

ARG变量的界说从其在Dockerfile中的界说行开始生效,并在构建阶段结束时失效。
要在多个构建阶段利用雷同的ARG,每个阶段都需要重新声明ARG。
2.3、预界说ARG

Docker预界说了一系列ARG变量,如HTTP_PROXY、HTTPS_PROXY等,这些可以在构建时不需在Dockerfile中声明,直接通过命令行的--build-arg利用。
2.4、示例
  1. FROM busybox
  2. ARG user1
  3. ARG buildno=1
复制代码
在这个例子中,user1没有默认值,而buildno的默认值是1。
3、LABEL

为生成的镜像添加元数据标签信息
这些元数据以键值对的情势存在
3.1、指令格式
  1. LABEL <key>=<value> <key>=<value> <key>=<value> ...
复制代码
3.2、示例
  1. LABEL "com.example.vendor"="ACME Incorporated"
  2. LABEL com.example.label-with-value="foo"
  3. LABEL version="1.0"
  4. LABEL description="This text illustrates \
  5. that label-values can span multiple lines."
复制代码
3.3、多个标签

可以在单行或多行上指定多个标签,尽管这样做在Docker 1.10版本后不再减少最终镜像的大小,但仍旧是一种组织代码的可选方式
3.4、单行多标签
  1. LABEL multi.label1="value1" multi.label2="value2" other="value3"
复制代码
3.5、多行多标签(保举)
  1. LABEL multi.label1="value1" \
  2.       multi.label2="value2" \
  3.       other="value3"
复制代码
利用双引号而非单引号:当值中包罗环境变量插值等需要分析的元素时,必须利用双引号,因为单引号会阻止变量睁开。
假如基础镜像(即FROM指令指定的镜像)中已经包罗了某些标签,那么这些标签会被继承。假如有雷同键的标签在新镜像的Dockerfile中被重新界说,那么新界说的值将覆盖原有的值。
3.6、查看镜像标签
  1. docker image inspect --format='{{json .Config.Labels}}' myimage
复制代码
  1. {
  2.   "com.example.vendor": "ACME Incorporated",
  3.   "com.example.label-with-value": "foo",
  4.   "version": "1.0",
  5.   "description": "This text illustrates that label-values can span multiple lines.",
  6.   "multi.label1": "value1",
  7.   "multi.label2": "value2",
  8.   "other": "value3"
  9. }
复制代码
4、EXPOSE

声明镜像内服务监听的端口

4.1、指令格式
  1. EXPOSE <port> [<port>/<protocol>...]
复制代码
4.2、示例:同时监听TCP和UDP协议的端口
  1. EXPOSE 80/tcp
  2. EXPOSE 80/udp
复制代码
  1. docker run -p 80:80/tcp -p 80:80/udp ...
复制代码
5、ENV

用于设置环境变量
5.1、指令格式
  1. ENV <key>=<value> ...
复制代码
5.2、示例
  1. ENV MY_NAME="John Doe"
  2. ENV MY_DOG=Rex\ The\ Dog
  3. ENV MY_CAT=fluffy
复制代码
  1. ENV MY_NAME="John Doe" MY_DOG=Rex\ The\ Dog \
  2.     MY_CAT=fluffy
  3.    
  4. #批量设置
复制代码
5.3、持续性

5.4、注意事项

6、ADD

用于将文件、目次或远程文件URL添加到镜像的文件系统中
6.1、指令格式
  1. ADD [OPTIONS] <src> ... <dest>
  2. ADD [OPTIONS] ["<src>", "<dest>"]
复制代码
6.2、选项

--keep-git-dir: 保留远程Git仓库中的.git目次。
--checksum: 验证资源的校验签。
--chown: 设置文件权限。
--link:硬链接处理。
--exclude:排除模式匹配的文件或目次。
6.3、示例

1、通配符匹配
  1. ADD hom* /mydir/
  2. #添加以"hom"开头的所有文件到mydir目录中
  3. ADD hom?.txt /mydir/
  4. #单字符匹配
复制代码
2、相对路径

是相对路径,它会相对于当前的WORKDIR
  1. ADD test.txt relativeDir/
  2. #将test.txt添加到relativeDir内
复制代码
3、绝对路径

若以斜杠开头,它是绝对路径。
  1. ADD test.txt /absoluteDir/
  2. #将test.txt添加到absoluteDir根目录下
复制代码
4、特殊字符处理

假如文件名包罗如方括号等特殊字符,需要按照Go语言规则转义路径
  1. ADD arr[[]0].txt /mydir/
复制代码
7、COPY

编写Dockerfile的时候copy宿主机文件到镜像中。
7.1、指令格式
  1. COPY [OPTIONS] <src> ... <dest>
  2. COPY [OPTIONS] ["<src>", ... "<dest>"]
复制代码
7.2、选项

7.3、COPY --from

允许从一个已有的镜像、构建阶段大概其他命名的上下文中复制文件
  1. FROM alpine AS build
  2. COPY . .
  3. RUN apk add clang
  4. RUN clang -o /hello hello.c
  5. FROM scratch
  6. COPY --from=build /hello /
复制代码
在一个多阶段构建中,可以指定从名为build的构建阶段复制文件
  1. COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf
  2. #也可以直接从其他镜像复制文件,比如从官方的Nginx镜像中复制配置文件
复制代码
7.4、COPY --chown 和 COPY --chmod
  1. COPY [--chown=<用户>:<组>] [--chmod=<权限>...] <源路径>... <目标路径>
复制代码
  1. COPY --chown=55:mygroup files* /somedir/
  2. COPY --chown=bin files* /somedir/
  3. COPY --chown=1 files* /somedir/
  4. COPY --chown=10:11 files* /somedir/
  5. COPY --chown=myuser:mygroup --chmod=644 files* /somedir/
复制代码
7.5、COPY --link
  1. COPY [--link[=<布尔值>]] <源路径> ... <目标路径>
复制代码
  1. # syntax=docker/dockerfile:1
  2. FROM alpine
  3. COPY --link /foo /bar
复制代码
相称于
  1. FROM alpine
  2. # 第一个构建
  3. FROM scratch
  4. COPY /foo /bar
  5. # 第二个构建,并将两个镜像的所有层合并在一起
复制代码
8、USER

用于设置后续当前构建阶段中默认利用的用户名(或 UID)以及可选的用户组(或 GID)。
假如所指定的用户没有主组,那么镜像(或之后的指令)将会以根组(root group)的身份运行。
8.1、指令格式
  1. USER <user>[:<group>]
  2. USER <UID>[:<GID>]
复制代码
8.2、示例
  1. FROM microsoft/windowsservercore
  2. # 在容器中创建 Windows 用户
  3. RUN net user /add patrick
  4. # 为后续指令设置用户 patrick
  5. USER patrick
复制代码
9、WORKDIR

用于为 Dockerfile 中随后的 RUN, CMD, ENTRYPOINT, COPY, 和 ADD 指令设置工作目次。
假如指定的工作目次不存在,纵然之后的 Dockerfile 指令未利用到它,也会被创建。
9.1、指令格式
  1. WORKDIR /path/to/workdir
复制代码
9.2、示例
  1. WORKDIR /a
  2. WORKDIR b
  3. WORKDIR c
  4. RUN pwd
复制代码
Dockerfile 中可以多次利用 WORKDIR 指令。假如给出的是相对路径,它将是相对于前一个 WORKDIR 指令的路径。
最后的 pwd 命令的输出将是 /a/b/c。
10、VOLUME

创建一个数据卷挂载点
10.1、指令格式
  1. VOLUME ["/data"]
复制代码
10.2、示例
  1. FROM ubuntu
  2. RUN mkdir /myvol
  3. RUN echo "hello world" > /myvol/greeting
  4. VOLUME /myvol
复制代码
这个 Dockerfile 将生成一个镜像,使得执行 docker run 时会在 /myvol 创建一个新的挂载点,并将 greeting 文件复制到新创建的卷里。
10.3、注意事项

11、ENTRYPOINT

指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执行,全部传入值作为该命令的参数
每个DockerFile中只能有一个ENTRYPOINT,当指定多个时只有最后一个起效
11.1、指令格式
  1. ENTRYPOINT ["executable", "param1", "param2"]
  2. #exec形式
  3. ENTRYPOINT command param1 param2
  4. #shell形式
复制代码
11.2、示例
  1. FROM ubuntu
  2. ENTRYPOINT ["top", "-b"]
  3. CMD ["-c"]
复制代码
当你运行这个容器时,可以看到top是唯一的进程:
  1. docker run -it --rm --name test top -H
复制代码
12、RUN

运行指定命令
每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像层
当命令较长时可以利用\来换行
12.1、指令格式
  1. RUN [OPTIONS] <command> ...
  2. #shell形式
  3. RUN [OPTIONS] [ "<command>", ... ]
  4. #exec形式
复制代码
12.2、示例:缓存Go包
  1. # syntax=docker/dockerfile:1
  2. FROM golang
  3. RUN --mount=type=cache,target=/root/.cache/go-build \
  4.   go build ...
复制代码
12.3、示例:缓存apt包
  1. # syntax=docker/dockerfile:1
  2. FROM ubuntu
  3. RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
  4. RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
  5.   --mount=type=cache,target=/var/lib/apt,sharing=locked \
  6.   apt update && apt-get --no-install-recommends install -y gcc
复制代码
12.4、示例:访问GitLab
  1. # syntax=docker/dockerfile:1
  2. FROM alpine
  3. RUN apk add --no-cache openssh-client
  4. RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan gitlab.com >> ~/.ssh/known_hosts
  5. RUN --mount=type=ssh \
  6.   ssh -q -T git@gitlab.com 2>&1 | tee /hello
  7. # "Welcome to GitLab, @GITLAB_USERNAME_ASSOCIATED_WITH_SSHKEY" should be printed here
  8. # with the type of build progress is defined as `plain`.
复制代码
  1. eval $(ssh-agent)
  2. ssh-add ~/.ssh/id_rsa
  3. (Input your passphrase here)
  4. docker buildx build --ssh default=$SSH_AUTH_SOCK .
复制代码
13、CMD

CMD指令用来指定启动容器时默认执行的命令
13.1、指令格式
  1. CMD ["executable","param1","param2"]
  2. #相当于执行executable param1 param2
  3. CMD ["param1","param2"]
  4. #提供给ENTRYPOINT的默认参数
  5. CMD command param1 param2
  6. #在默认的shell中执行,提供给需要交互的应用
复制代码
每个Dockerfile 只能有一条CMD命令。假如指定了多条命令,只有最后一条会被执行
13.2、注意事项

假如利用CMD为ENTRYPOINT指令提供默认参数,那么CMD和ENTRYPOINT指令都应该以exec情势指定。
RUN实际上运行一个命令并提交结果;CMD在构建时不执行任何操纵,但指定了镜像的预期命令。
五、DockerFile制作镜像(制作nginx镜像)

1、下载centos镜像
  1. docker pull centos:7
复制代码
2、创建对应目次
  1. mkdir -pv dockerfile/{web/{nginx,apache},system/{centos,ubuntu}}
复制代码

3、进入指定目次下载源码包
  1. [root@localhost ~]# cd dockerfile/web/nginx/
  2. [root@localhost nginx]# pwd
  3. /root/dockerfile/web/nginx
  4. [root@localhost nginx]# wget http://nginx.org/download/nginx-1.20.1.tar.gz
  5. [root@localhost nginx]# ls
  6. nginx-1.20.1.tar.gz
复制代码
4、编写DockerFile
  1. [root@localhost nginx]# vim Dockerfile
  2. FROM centos:7
  3. MAINTAINER misakivv 2830909671@qq.com
  4. RUN yum install -y vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop
  5. ADD nginx-1.20.1.tar.gz /usr/local/src/
  6. RUN cd /usr/local/src/nginx-1.20.1 \
  7. && ./configure --prefix=/usr/local/nginx --with-http_sub_module \
  8. && make \
  9. && make install \
  10. && cd /usr/local/nginx
  11. # ADD nginx.conf /usr/local/nginx/conf/nginx.conf
  12. RUN useradd -s /sbin/nologin nginx \
  13. && ln -sv /usr/local/nginx/sbin/nginx /usr/sbin/nginx \
  14. && echo 'test nginx !' > /usr/local/nginx/html/index.html
  15. EXPOSE 80 443
  16. CMD ["nginx", "-g", "daemon off;"]
复制代码
4.1、分析

5、构建镜像
  1. [root@localhost nginx]# docker build -t nginx:v1 .
  2. [root@localhost nginx]# docker images | grep v1
  3. nginx        v1        e5d32f022cdc   56 seconds ago   650MB
复制代码

6、测试验证
  1. [root@localhost nginx]# docker run -itd -p 8088:80 nginx:v1
  2. 0c2810cb9b168890b59264a1990dcc5b5e8782e337a757c99d42dc061cb08a7c
复制代码

六、镜像上传

1、阿里云仓库

阿里云容器镜像服务
1.1、注册账户


1.2、创建个人版实例

1.3、设置Registry登录密码


1.4、创建镜像仓库

1.5、登录阿里云Docker Registry
  1. docker login --username=misaki0 registry.cn-hangzhou.aliyuncs.com
复制代码

用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。
您可以在访问凭证页面修改凭证密码。
1.6、将镜像推送到Registry
  1. docker tag nginx:v1 registry.cn-hangzhou.aliyuncs.com/misaki_nginx/my_nginx:v1
  2. #将本地nginx:v1镜像创建标签并归属到阿里云镜像服务的指定仓库中
  3. docker push registry.cn-hangzhou.aliyuncs.com/misaki_nginx/my_nginx:v1
  4. #将重新标记的镜像推送到阿里云的容器镜像仓库中
复制代码


2、Docker Hub上传镜像

现在我还没注册,暂时写不了这部分的镜像上传
但基本思路还是注册登录账户--> 本地登录仓库--> 给需要上传的镜像tag标签 --> docker push -->官网验证即可

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4