“顺着上篇的巷子往里走,客官搬好小板凳 —— 这就开讲“
目录
制作镜像
1 镜像特性
-
镜像的分层:docker的镜像通过联合文件系统将各层文件系统叠加在一起,最上面是可写层,下面的都只读;分层存储(union FS)
- 镜像存放位置:/var/lib/docker/overlay2 (通常)
-
docker和 mysql数据存放一样,建议单独挂载一个磁盘,当数据磁盘 操作如下:
-
mkdir -p /data/docker====>单独挂一块磁盘
cp -r /var/lib/docker/* /data/docker/
mv /var/lib/docker /var/lib/docker.bak
ln -s /data/docker/ /var/lib/docker
systemctl restart docker
2 创建镜像的方法
(1)docker commit
优点:方便 快捷
缺点:镜像臃肿,生成的镜像也被称为 黑箱镜像,不建议用;适用于被入侵后保存现场
docker run -it centos:7 #先启动一个容器
执行一些操作 例如安装软件等,另起窗户不退出容器
docker ps
docker commit CONTAINER ID centos7:tag # 新镜像名:标签
docker images centos7:p1 # 查看是否制作成功
docker run -it centos7:p1 # 运行测试
(2)Dockerfile
- 镜像的定制实际上就是把每一层所修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像
优点:任意封装自己需要的 镜像小巧
缺点:构建上下文时需要提前规划好镜像分层
构建上下文:当 docker build 运行时,首先会构建上下文(当前目录下所有的东西)传输给 docker daemon,把没用的文件包含在构建上下文时,会导致传输时间长,构建需要的资源多,构建出的镜像大等问题。构建上下文建议创建一个单独的目录放置Dockerfile和相应的包;如果不能创建单独的目录,使用.dockerignore文件,告诉 Docker 哪些文件或文件夹不应该被复制到镜像中
3 Dckerfile 详解
(1)Dockerfile 基本结构
> 基础镜像信息 Base image(大多数用docker官方的)
例:FROM centos:7
> 维护者信息
例:LABEL maintainer 打倒苦瓜蛋<xx@xxcom>
> 镜像操作指令
例:RUN yum -y install tree telnet lrzsz && yum clean all
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
> 容器启动时执行的指令
例:CMD ["/bin/bash"]
构建镜像
docker build -t 镜像名 -f ./Dockerfile
查看镜像层
docker history 镜像名
(2)配置指令
- FORM:指定创建镜像的基础镜像(大多数是docker官方)
例 $ FROM centos:7
- LABEL:为生成的镜像添加元数据标签信息(日期、维护者信息等)
例:
LABEL maintainer "打倒苦瓜蛋" # 维护者信息
LABEL date="2023-10-1" # 日期
LABEL description="This is a nginx image that based on centos7." # 说明
查看
docker inspect image:tag
- ARG:创建镜像过程中使用的变量(仅在镜像构建过程中有效)
在构建时通过--build-arg传参来动态修改,在容器内不能查看该环境变量
例:
# dockerfile 中
ARG APP_PORT
# 构建
docker build --build-arg APP_PORT=8080 -t myapp -f ./Dockerfile .
- ENV:环境变量
在构建时不能传参,在容器内可以查看该环境变量
例1:
ENV APP_ENV production
例2:结合使用
ARG VERSION=1.0
ENV APP_VERSION=$VERSION # 将构建参数传入环境变量
# 这样既可以构建时通过--build-arg VERSION=2.0动态修改,又能让容器运行时访问到APP_VERSION变量
- EXPOSE:声明镜像内服务监听的端口
例1:结合AVG使用,动态修改服务端口
ARG APP_PORT
EXPOSE $APP_PORT
例2
EXPOSE 8080
- ENTRYPOINT:指定镜像的默认入口命令(两种形式)
1️⃣ exec形式(推荐):调用执行,在当前shell执行;
ENTRYPOINT ["可执行文件", "参数1", "参数2"]
例:
ENTRYPOINT ["python3", "-u"] # 构建后 最终执行 python3 -u
2️⃣ shell 形式:会新建一个子shell执行
ENTRYPOINT 命令 参数1 参数2
例:
ENTRYPOINT python3 -u # 构建后 最终执行 /bin/sh -c "python3 -u"
# PID=1 实际是 /bin/sh,它再启动 python3 -u 作为子进程
- CMD:指定镜像的默认入口命令(三种形式)
1️⃣ exec形式(推荐):调用执行,在当前shell执行;CMD和ENTRYPOINT单独存在时用法同上⬆️
2️⃣ shell 形式:会新建一个子shell执行;CMD和ENTRYPOINT单独存在时用法同上⬆️
3️⃣ 提供给 ENTRYPOINT 的默认参数:CMD和ENTRYPOINT同时存在时,CMD会作为ENTRYPOINT的参数执行
例:
ENTRYPOINT ["curl", "-s"]
CMD ["https://example.com"]
默认运行
docker run mycurl
# 实际运行 curl -s https://example.com
传新的参数,会覆盖 CMD
docker run mycurl https://example2.com
# 实际运行 curl -s https://example2.com
- VOLUME:创建一个数据卷挂载点
例:
FROM mysql:8.0
VOLUME ["/var/lib/mysql"]
# 表示 /var/lib/mysql 里的数据会被存放在卷里,保证 MySQL 容器删除后数据还在
- USER:指定运行容器时的用户名或 UID,后续的 RUN 等指令也会使用指定的用户身份
例:
FROM python:3.9
RUN useradd -m appuser
USER appuser
# Python 应用会用 appuser 身份启动
- WORKDIR:切换工作目录;推荐WORKDIR指令中只使用绝对路径
例:
WORKDIR /data/mysql # 相当于mkdir /data/mysql && cd /data/mysql
COPY mysql.conf . # 声明该命令在 /data/mysql 下执行
- HEALTHCHECK:配置所启动容器如何进行健康检查
HEALTHCHECK [OPTIONS] CMD command
【OPTIONS】
--interval=DURATION :两次检查的间隔,默认 30s
--timeout=DURATION :每次检查的超时时间,默认 30s
--start-period=DURATION :容器启动后宽限时间(这段时间内失败不会计入),默认 0s
--retries=N :连续失败多少次判定为 unhealthy,默认 3 次
例:HEALTHCHECK --interval=30s --timeout=5s --retries=3 CMD curl -f http://127.0.0.1:80/ || exit 1
# curl -f 如果能拿到 2xx/3xx 响应就返回0,如果失败则返回非0,每30s检查一次,超时5s,连续失败3次就标记为 unhealthy
(3)操作指令
- RUN:运行指定命令
例:
RUN yum -y install telnet lrzsz iproute && yum clean all
- COPY:复制内容到镜像(场景:普通拷贝文件/目录)
COPY <源路径> <容器目标路径>
- ADD:添加内容到镜像;支持自动解压 tar;支持 URL(场景:需要自动解压或下载远程文件)
ADD <源路径> <容器内目标路径>
例1:
ADD nginx-1.22.1.tar.gz /usr/local/src/nginx-1.22.1
# nginx-1.22.1.tar.gz 自动解压到目标路径
例2:
ADD https://nginx.org/download/nginx-1.22.1.tar.gz /usr/local/src
# 添加远程文件并解压放到目标路径
例3:
ADD nginx-1.22.1 /usr/local/src/nginx-1.22.1
# nginx-1.22.1 整个目录copy到目标路径
接下来 该你们自己去大展身手了😎😎😎
➕ 蛋蛋不迷路~ 有疑问随时留言哦😯 不定时更新!
下文持续更新 harbor 仓库相关详解 敬请期待....
1639

被折叠的 条评论
为什么被折叠?



