一、Harbor 仓库
https://goharbor.io/
https://goharbor.io/

1.Harbor仓库简介
- "Harbor" 是一个用于管理和部署容器化应用程序的开源仓库管理系统,主要用于存储、管理和分发 Docker 容器镜像。
- 它提供了一个企业级的 Docker 镜像仓库,支持多种安全特性、镜像管理和访问控制。
2.安装需求

服务器配置需求
有两种安装方式,在线安装和离线安装

下载安装包,注意rc是预售版本,还不完善


3.安装Harbor仓库
(1)解压软件包
[root@localhost ~]# tar xvf harbor-offline-installer-v2.13.2.tgz -C /usr/local/
[root@localhost ~]# cd /usr/local/harbor/
[root@localhost harbor]# ll
总用量 659252
-rw-r--r-- 1 root root 3646 7月 31 10:48 common.sh
-rw-r--r-- 1 root root 675032342 7月 31 10:48 harbor.v2.13.2.tar.gz
-rw-r--r-- 1 root root 14688 7月 31 10:48 harbor.yml.tmpl
-rwxr-xr-x 1 root root 1975 7月 31 10:48 install.sh
-rw-r--r-- 1 root root 11347 7月 31 10:48 LICENSE
-rwxr-xr-x 1 root root 2211 7月 31 10:48 prepare
common.sh # 共用脚本
harbor.v2.13.2.tar.gz # Harbor 离线镜像
harbor.yml.tmpl # template 模板
harbor.yml # 配置文件
install.sh # 脚本 安装 Harbor , 执行一次
LICENSE
prepare # 脚本 harbor.yml
(2)修改yml配置文件
[root@localhost harbor]# mkdir -p /data/registry
[root@localhost harbor]# mv harbor.yml.tmpl harbor.yml
[root@localhost harbor]# vi harbor.yml
# 可以改成域名或ip,但建议使用域名,这样内网外网用户都可以访问
hostname: reg.xxhf.com
# 先注释掉这里,不配置公钥
# https related config
# https:
# https port for harbor, default is 443
# port: 443
# The path of cert and key files for nginx
# certificate: /your/certificate/path
# private_key: /your/private/key/path
# enable strong ssl ciphers (default: false)
# strong_ssl_ciphers: false
# 设置账户密码,这里的密码最好用复杂密码
harbor_admin_password: "*id,4g5EPuB@B@xwEhYsISEn4JIS"
# 设置数据库密码,最好和账户密码不一致
database:
# The password for the user('postgres' by default) of Harbor DB. Change this before any production use.
password: uNIloGyBmezYl0f@SKosjOlbyL4DWUDtEjzuSvYn
# 修改镜像存储位置,生产环境要挂载一块较大的磁盘
data_volume: /data/registry
设置复杂密码(可以调整位数)
[root@localhost harbor]# pwmake 128
*id,4g5EPuB@B@xwEhYsISEn4JIS
[root@localhost harbor]# pwmake 192
uNIloGyBmezYl0f@SKosjOlbyL4DWUDtEjzuSvYn
(3)执行安装脚本
# 直到所有容器都启动成功,才可以访问harbor
[root@localhost harbor]# ./install.sh
注:记得将域名注册到真实机的hosts文件当中
192.168.5.100 reg.xxhf.cc
(4)通过域名访问web服务
注:访问时需要注意,目前的浏览器大多都默认使用https协议,而我们搭建的harbor仓库目前使用的是http协议,因此在使用域名访问时记得检查使用正确的协议http

(5)上传镜像
# 连接harbor仓库时,可以使用服务器,也可以使用客户端,客户端需要安装docker服务
[root@localhost ~]# echo "192.168.5.100 reg.xxhf.cc" >> /etc/hosts
[root@localhost ~]# vi /etc/docker/daemon.json
# 将域名注册到不安全的仓库当中
"insecure-registries": ["reg.xxhf.cc"]
[root@localhost harbor]# systemctl restart docker
# 重启docker之后,harbor仓库可能会掉线,需要重新启动
# 登录
[root@localhost ~]# docker login reg.xxhf.cc
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credential-stores
Login Succeeded
[root@localhost ~]# docker tag nginx:1.22.1 reg.xxhf.cc/xxhf/nginx:v1
# 上传镜像,域名+地址+容器名(需要提前设置)
[root@localhost ~]# docker push reg.xxhf.cc/xxhf/nginx:v1
The push refers to repository [reg.xxhf.cc/xxhf/nginx]
9543dec06aa8: Pushed
ccf4f419ba49: Pushed
21f8452ebfb1: Pushed
25bbf4633bb3: Pushed
a4f34e6fb432: Pushed
3af14c9a24c9: Pushed
v1: digest: sha256:9081064712674ffcff7b7bdf874c75bcb8e5fb933b65527026090dacda36ea8b size: 1570
4.配置harbor-https协议
注:若想要使harbor仓库支持https协议,那么它的域名(reg.xxhf.cc)就需要有对应的证书和私钥
(1)证书申请
注:阿里云和腾讯云都可以申请免费的证书

(2)安装证书
# 下载证书到本机
[root@localhost ~]# ls
anaconda-ks.cfg cat.sh dockerfile-example.tgz harbor-offline-installer-v2.13.2.tgz reg.xxhf.cc_nginx.zip
[root@localhost ~]# unzip reg.xxhf.cc_nginx.zip
[root@localhost ~]# cd /usr/local/harbor/
[root@localhost harbor]# mkdir certs
[root@localhost harbor]# mv /root/reg.xxhf.cc_nginx/reg.xxhf.cc_bundle.crt certs/
[root@localhost harbor]# mv /root/reg.xxhf.cc_nginx/reg.xxhf.cc.key certs/
# 在配置文件中添加证书
[root@localhost harbor]# vi harbor.yml
# https related config
https:
# https port for harbor, default is 443
port: 443
# The path of cert and key files for nginx
certificate: /usr/local/harbor/certs/reg.xxhf.cc_bundle.crt
private_key: /usr/local/harbor/certs/reg.xxhf.cc.key
# enable strong ssl ciphers (default: false)
# strong_ssl_ciphers: false
# 使配置生效
[root@localhost harbor]# ./prepare
# 重启服务
[root@localhost harbor]# docker compose down
[root@localhost harbor]# docker compose up -d
注:如果过程报错,可以通过查看日志纠错
[root@localhost harbor]# docker compose logs -f
补充:如何查看文件内容是否一致?
# diff命令测试,如果一致则没有任何反应
[root@localhost reg.xxhf.cc_nginx]# diff reg.xxhf.cc_bundle.crt reg.xxhf.cc_bundle.pem
# md5sum命令测试,如果哈希值一致,则内容一致
[root@localhost reg.xxhf.cc_nginx]# md5sum reg.xxhf.cc_bundle.crt
e7ad2c8d1157cd63b60d0e4f088708b3 reg.xxhf.cc_bundle.crt
[root@localhost reg.xxhf.cc_nginx]# md5sum reg.xxhf.cc_bundle.pem
e7ad2c8d1157cd63b60d0e4f088708b3 reg.xxhf.cc_bundle.pem
(3)再次访问web服务
注:可以发现此时的harbor仓库已经支持https协议了


二、Harbor仓库常用功能
1.定时删除镜像
注:根据要求配置保留最近几个版本的镜像,配置定时执行周期即可


2.实现高可用
注:通过复制管理,创建复制,在复数的harbor仓库上推送镜像,实现高可用


3.漏洞扫描
注:在镜像上传的时候,扫描镜像的漏洞(在安装时添加trivy,也可以在配置文件中修改)

三、镜像制作
1.镜像的分层
- 容器创建时需要指定镜像,每一个镜像都有唯一的镜像ID
- Docker的镜像通过联合文件系统(UFS)将各层文件系统叠加在一起(这一点在下载镜像的过程中就可以体现出来)

2.镜像特性

注:已有的分层只能读、不能修改;上层镜像优先级大于底层镜像;容器和宿主机共用bootfs
3.Docker commit制作镜像
# 添加命令工具
[root@localhost ~]# docker run -it rockylinux:9
[root@0f3aed80969d /]# dnf -y install wget iproute
# 另开一个窗口,将添加命令后的容器制作镜像
[root@localhost ~]# docker commit 3782b435f6ac rocky9:v1
sha256:2647e88790d1b8921b015ba87108f8e57b4ebfd198fcfe03324324729c27071c
[root@localhost ~]# docker images rocky9:v1
REPOSITORY TAG IMAGE ID CREATED SIZE
rocky9 v1 2647e88790d1 22 seconds ago 213MB
# 查看原来的镜像,可以发现数据变多了
[root@localhost ~]# docker images rockylinux:9
REPOSITORY TAG IMAGE ID CREATED SIZE
rockylinux 9 9cc24f05f309 23 months ago 176MB

注:新添加的命令变成了分层,这就是镜像分层的概念;优点是创建简单,缺点是创建好的层无法修改,需要重新制作镜像
4.Dockerfile制作镜像
(1)Dockerfile简介
- Dockerfile 是一个文本格式的配置文件,我们可以使用Dockerfile来快速创建自定义的镜像
- Dockerfile模版包在上传的资源中
(2)创建Dockerfile
[root@localhost ~]# vim Dockerfile
# Base image
FROM rockylinux:9
LABEL authors="chijinjing@xinxianghf.com"
RUN dnf -y install wget iproute && dnf clean all #这里做了缓存的清除
CMD /usr/sbin/nginx
(3)制作镜像
[root@localhost ~]# docker build -t rocky9:v2 .
[root@localhost ~]# docker images rocky9:v2
REPOSITORY TAG IMAGE ID CREATED SIZE
rocky9 v2 cf533c72574a 33 seconds ago 186MB
注:可以看到制作出来的镜像要比之前制作的要小上一些,是因为清除了缓存
(4)修改配置文件
[root@localhost ~]# vim Dockerfile
# Base image
FROM rockylinux:9
LABEL authors="chijinjing@xinxianghf.com"
RUN dnf -y install wget iproute
RUN dnf clean all
CMD /usr/sbin/nginx
[root@localhost ~]# docker build -t rocky9:v3 .
[root@localhost ~]# docker images rocky9:v3
REPOSITORY TAG IMAGE ID CREATED SIZE
rocky9 v3 c6d239ac0de5 17 seconds ago 213MB
注:可以看到在查看镜像时又恢复到了原来的体积
原因:镜像是分层的,已有的分层只能读,不能修改,而每运行一条 RUN 指令,镜像添加新的一层,并提交
(5)指令说明

(6)ARG&&ENV
- ARG:定义创建镜像过程中使用的变量(只能在构建时使用,变成容器就没有了,支持在构建时传参数)
- **ENV:**声明镜像内服务监听的端口(生命周期较长 , 在构建时可以使用 ,变成容器还可以使用,不支持在构建时传参)
需求:安装 nginx-1:1.26.1 ,不允许 修改 Dockerfile 文件
当前配置文件
[root@localhost dockerfile-arg-env]# pwd
/root/dockerfile-example/dockerfile-arg-env
[root@localhost dockerfile-arg-env]# vi Dockerfile
[root@localhost ~]# vi Dockerfile
# Base image
FROM rockylinux:9
# Maintainer
LABEL authors="chijinjing@xinxianghf.com"
ARG VERSION=1.26.0
ENV NGINX_VERSION=1.26.1
#EXPOSE 80
WORKDIR /data
# Add nginx yum repo
COPY nginx.repo /etc/yum.repos.d/nginx.repo
# Install nginx
RUN dnf -y install nginx-1:$VERSION-1.el9.ngx.x86_64 && dnf clean all
#RUN yum -y install nginx-1:$NGINX_VERSION-1.el9.ngx.x86_64 && yum clean all
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
# Start nginx daemon
CMD ["/usr/sbin/nginx"]
执行命令
[root@localhost dockerfile-arg-env]# docker build -t nginx-arg:1.26.1 --build-arg VERSION=1.26.1 .

5.指定环境变量
(1)运行mysql容器
[root@localhost ~]# docker run -d mysql
0f0684eb9a38219265e0a35e77b8ed31cb4012f62c64b91913ba1d70815e24f8
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2c3987c8d9a3 nginx "/docker-entrypoint...." 16 minutes ago Up 16 minutes 80/tcp gracious_shannon
3782b435f6ac rockylinux:9 "/bin/bash" About an hour ago Up About an hour sweet_blackwell
a647f85bc327 redis "docker-entrypoint.s..." 2 hours ago Up 2 hours 6379/tcp gracious_blackburn
注:发现容器并没有启动,我们查看日志发现需要配置环境变量

(2)指定环境变量
注:我们可以在启动容器的时候指定环境变量的值,这次可以成功启动
[root@localhost ~]# docker run -e MYSQL_ROOT_PASSWORD=123456 -d mysql
2b001bfb03470ca8d34530489b43f119982405ad14dc619ef8a4077fa5083c98
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2b001bfb0347 mysql "docker-entrypoint.s..." 5 seconds ago Up 5 seconds 3306/tcp, 33060/tcp epic_allen
2c3987c8d9a3 nginx "/docker-entrypoint...." 21 minutes ago Up 21 minutes 80/tcp gracious_shannon
3782b435f6ac rockylinux:9 "/bin/bash" About an hour ago Up About an hour sweet_blackwell
a647f85bc327 redis "docker-entrypoint.s..." 2 hours ago Up 2 hours 6379/tcp gracious_blackburn
6.Dockerfile指令诠释
(1)FROM
- 指定所创建镜像的 基础镜像
- 格式为
FROM <image> [AS <name>]或FROM <image>:<tag> [AS <name>]或FROM <image>@<digest> [AS <name>] 任何 Dockerfile 中第一条指令必须为FROM指令
配置文件:
[root@localhost dockerfile-from]# pwd
/root/dockerfile-example/dockerfile-from
[root@localhost dockerfile-from]# vi Dockerfile
# Base image
FROM rockylinux:9
# Maintainer
LABEL authors="chijinjing@xinxianghf.com"
# Install tools
RUN dnf -y install telnet wget
RUN dnf clean all
CMD ["/bin/bash"]
制作镜像:
[root@localhost dockerfile-from]# docker build -t centos7 .
[root@localhost dockerfile-from]# docker run -it centos7
[root@875049732e95 /]#
(2)ARG
- 定义创建镜像过程中使用的变量。
- 格式为
ARG <name>[=<default value>] - 在执行 docker build 时,可以通过
--build-arg [=]来为变量赋值。当镜像编译成功后,ARG 指定的变量将不再存在(ENV 指定的变量将在镜像中保留)
配置文件:
[root@localhost dockerfile-arg-env]# pwd
/root/dockerfile-example/dockerfile-arg-env
[root@localhost dockerfile-arg-env]# vi Dockerfile
# Base image
FROM rockylinux:9
# Maintainer
LABEL authors="chijinjing@xinxianghf.com"
ARG VERSION=1.26.0
ENV NGINX_VERSION=1.26.1
#EXPOSE 80
WORKDIR /data
# Add nginx yum repo
COPY nginx.repo /etc/yum.repos.d/nginx.repo
# Install nginx
RUN dnf -y install nginx-1:$VERSION-1.el9.ngx.x86_64 && dnf clean all
#RUN yum -y install nginx-1:$NGINX_VERSION-1.el9.ngx.x86_64 && yum clean all
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
# Start nginx daemon
CMD ["/usr/sbin/nginx"]
制作镜像:
-
ARG 的变量可以在
docker build的过程中使用--build-arg参数修改变量的值[root@localhost dockerfile-arg-env]# docker build -t nginx:1.26.2 --build-arg VERSION=1.26.1 .
[root@localhost dockerfile-arg-env]# docker run -it nginx:1.26.1 /bin/bash
[root@160f4b765b88 data]# nginx -v
nginx version: nginx/1.26.1
(3)LABEL
- LABEL 指令可以为生成的镜像添加元数据标签信息。
- 格式为LABEL <key>=<value> <key>=<value> <key>=<value> ...
配置文件:
[root@localhost dockerfile-label]# pwd
/root/dockerfile-example/dockerfile-label
[root@localhost dockerfile-label]# vi Dockerfile
# Base image
FROM rockylinux:9
# Maintainer
LABEL authors="chijinjing@xinxianghf.com"
LABEL date="2025-02-06"
LABEL description="This is a demo image that based on Rockylinux9."
CMD ["/bin/bash"]
制作镜像:
[root@localhost dockerfile-label]# docker build -t nginx-label:v1 .
[root@localhost dockerfile-label]# docker inspect nginx-label:v1
"Labels": {
"authors": "chijinjing@xinxianghf.com",
"date": "2025-02-06",
"description": "This is a demo image that based on Rockylinux9."
}
(4)EXPOSE
- 声明镜像内服务监听的端口。
- 该指令只是起到 声明作用,并不会自动完成端口映射
- 格式为
EXPOSE <port> [<port>/<protocol>...]
例如:
EXPOSE 80 443
(5)ENV
- 指定环境变量,在镜像生成过程中会被后续RUN指令使用,在镜像启动的容器中也会存在
- 指令指定的环境变量在运行时可以被覆盖掉,如 docker run --env <key>=<value> image_name
- 格式为
ENV <key>=<value> ...
配置文件:
[root@localhost dockerfile-arg-env]# vi Dockerfile
# Base image
FROM rockylinux:9
# Maintainer
LABEL authors="chijinjing@xinxianghf.com"
ARG VERSION=1.26.0
ENV NGINX_VERSION=1.26.1
EXPOSE 80
WORKDIR /data
# Add nginx yum repo
COPY nginx.repo /etc/yum.repos.d/nginx.repo
# Install nginx
#RUN dnf -y install nginx-1:$VERSION-1.el9.ngx.x86_64 && dnf clean all
RUN yum -y install nginx-1:$NGINX_VERSION-1.el9.ngx.x86_64 && yum clean all
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
# Start nginx daemon
CMD ["/usr/sbin/nginx"]
制作镜像:
[root@localhost dockerfile-arg-env]# docker build -t nginx-env:1.26.3 .
# 未修改前
[root@localhost dockerfile-arg-env]# docker run -it nginx-env:1.26.3 bash
[root@c8a57df52d88 data]# echo $nginx-env
-env
[root@c8a57df52d88 data]# echo $NGINX_VERSION
1.26.1
[root@c8a57df52d88 data]# exit
exit
# 修改后
[root@localhost dockerfile-arg-env]# docker run -it --env NGINX_VERSION=1.26.3 nginx-env:1.26.3 bash
[root@8f1cd0620779 data]# echo $NGINX_VERSION
1.26.3
(6)ENTRYPOINT
- 指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执行,所有传入值作为该命令的参数。
- 支持两种格式:
ENTRYPOINT ["executable", "param1", "param2"]: 使用 exec 执行; 建议使用这种方式ENTRYPOINT command param1 param2: 在 shell 终端中执行。
- 每个Dockerfile中只能有一个ENTRYPOINT,当指定多个时,只有最后一个起效
在Shell中执行:
[root@localhost dockerfile-entrypoint]# pwd
/root/dockerfile-example/dockerfile-entrypoint
[root@localhost dockerfile-entrypoint]# ls
Dockerfile Dockerfile2 Dockerfile2-cmd Dockerfile-cmd nginx.repo
[root@localhost dockerfile-entrypoint]# vi Dockerfile
# Base image
FROM rockylinux:9
# Maintainer
LABEL authors="chijinjing@xinxianghf.com"
ENV NGINX_VERSION=1.26.1
# Add nginx yum repo
COPY nginx.repo /etc/yum.repos.d/nginx.repo
# Install nginx
RUN dnf -y install nginx-1:$NGINX_VERSION-1.el9.ngx.x86_64 && yum clean all
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
# Start nginx daemon
ENTRYPOINT /usr/sbin/nginx
制作镜像:
[root@localhost dockerfile-entrypoint]# docker build -t entrypoint-shell .

exec 调用执行:
[root@localhost dockerfile-entrypoint]# vi Dockerfile2
# Base image
FROM rockylinux:9
# Maintainer
LABEL authors="chijinjing@xinxianghf.com"
ENV NGINX_VERSION=1.26.1
# Add nginx yum repo
COPY nginx.repo /etc/yum.repos.d/nginx.repo
# Install nginx
RUN dnf -y install nginx-1:$NGINX_VERSION-1.el9.ngx.x86_64 && dnf clean all
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
# Start nginx daemon
ENTRYPOINT ["/usr/sbin/nginx"]
制作镜像:
[root@localhost dockerfile-entrypoint]# docker build -t entrypoint-exec -f Dockerfile2 .
比较两者区别:
[root@localhost dockerfile-entrypoint]# docker run -d entrypoint-shell
a9582643491afb0e5bdf158fde5b7380ab75ce3c8be426d4c4ced44ac28ccc5a
[root@localhost dockerfile-entrypoint]# docker run -d entrypoint-exec
b9f92a4d842b1721fc51ff2840287594a526ef9b028d0d324df838aa437ae980
[root@localhost dockerfile-entrypoint]# docker ps --no-trunc
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b9f92a4d842b1721fc51ff2840287594a526ef9b028d0d324df838aa437ae980 entrypoint-exec "/usr/sbin/nginx" 27 seconds ago Up 26 seconds festive_brattain
a9582643491afb0e5bdf158fde5b7380ab75ce3c8be426d4c4ced44ac28ccc5a entrypoint-shell "/bin/sh -c /usr/sbin/nginx" 36 seconds ago Up 35 seconds gallant_raman
(7)VOLUME 卷
- 创建一个数据卷挂载点
- 格式为
VOLUME ["/data"] - 运行容器时可以从本地主机或其他容器挂载数据卷,一般用来存放数据库和需要保持的数据
(8)USER
- 指定运行容器时的用户名或 UID,后续的 RUN 等指令也会使用指定的用户身份
- 格式为
USER daemon - 当服务不需要管理员权限时,可以通过该命令指定运行用户,并且可以在Dockerfile中创建所需要的用户
配置文件:
[root@localhost dockerfile-user]# pwd
/root/dockerfile-example/dockerfile-user
[root@localhost dockerfile-user]# vi Dockerfile
# Base image
FROM rockylinux:9
# Maintainer
LABEL authors="chijinjing@xinxianghf.com"
# Add user
RUN groupadd -r redis && useradd -r -g redis redis
USER redis
CMD ["/bin/bash"]
制作镜像:
[root@localhost dockerfile-user]# docker build -t user-redis .
[root@localhost dockerfile-user]# docker run -it user-redis whoami
redis
(9)WORKDIR
- 为 RUN、CMD、ENTRYPOINT 指令配置工作目录
- 格式为
WORKDIR /path/to/workdir - 可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径
例如:
WORKDIR /a # mkdir /a && cd /a
WORKDIR b # mkdir b && cd b /a/b
WORKDIR c
RUN pwd # /a/b/c
最终路径为/a/b/c。
因此,为了避免出错,推荐WORKDIR指令中只使用绝对路径。
配置文件:
[root@localhost dockerfile-workdir]# pwd
/root/dockerfile-example/dockerfile-workdir
[root@localhost dockerfile-workdir]# vi Dockerfile
# Base image
FROM rockylinux:9
# Maintainer
LABEL authors="chijinjing@xinxianghf.com"
WORKDIR /data
COPY app.json .
WORKDIR /data/app/
COPY app.jar .
WORKDIR /data/applog/
CMD ["/bin/bash"]
制作镜像:
[root@localhost dockerfile-workdir]# docker build -t workdir:v1 .
[root@localhost dockerfile-workdir]# docker run -it workdir:v1 pwd
/data/applog
(10)ONBUILD
- 指定当基于所生成镜像创建子镜像时,自动执行的操作指令。
- 格式为 ONBUILD [INSTRUCTION]
- 使用 docker build 命令创建子镜像 ChildImage 时(FROM ParentImage),会首先执行 ParentImage 中配置的 ONBUILD 指令
- ONBUILD 指令在自动编译、检查等操作的基础镜像时,十分有用
配置文件:
[root@localhost dockerfile-onbuild]# ls
Dockerfile-child Dockerfile-parent
# 父镜像配置
[root@localhost dockerfile-onbuild]# vi Dockerfile-parent
# Base image
FROM rockylinux:9
# Maintainer
LABEL authors="chijinjing@xinxianghf.com"
# Install tools
ONBUILD RUN yum -y install telnet lrzsz iproute && yum clean all
WORKDIR /data/applog/
CMD ["/bin/bash"]
# 子镜像配置
[root@localhost dockerfile-onbuild]# vi Dockerfile-child
# Base image
FROM rocky-onbuild
# Maintainer
LABEL authors="chijinjing@xinxianghf.com"
WORKDIR /data/applog/
CMD ["/bin/bash"]
制作镜像:
[root@localhost dockerfile-onbuild]# docker build -t rocky-onbuild -f Dockerfile-parent .
[root@localhost dockerfile-onbuild]# docker run -d rocky-onbuild
[root@localhost dockerfile-onbuild]# docker run -it rocky-onbuild bash
[root@9d86ad43bfd2 applog]# telnet
bash: telnet: command not found
[root@localhost dockerfile-onbuild]# docker build -t rocky-child -f Dockerfile-child .
[root@localhost dockerfile-onbuild]# docker run -it rocky-child bash
[root@3774c819533f applog]# telnet
telnet>
(11)STOPSIGNAL
- 指定容器接收退出的信号值
配置文件:
[root@localhost dockerfile-stopsignal]# pwd
/root/dockerfile-example/dockerfile-stopsignal
[root@localhost dockerfile-stopsignal]# ls
Dockerfile nginx.repo
[root@localhost dockerfile-stopsignal]# vi Dockerfile
# Base image
FROM rockylinux:9
# Maintainer
LABEL authors="chijinjing@xinxianghf.com"
ENV NGINX_VERSION=1.26.1
STOPSIGNAL SIGTERM
EXPOSE 80
# Add nginx yum repo
COPY nginx.repo /etc/yum.repos.d/nginx.repo
# Install nginx
RUN yum -y install nginx-1:$NGINX_VERSION-1.el9.ngx.x86_64 && yum clean all
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
# Start nginx daemon
CMD ["/usr/sbin/nginx"]
制作镜像:
[root@localhost dockerfile-stopsignal]# docker build -t nginx-signal .
测试:
[root@localhost dockerfile-stopsignal]# docker run -d --name nginx-01 nginx-signal
659d55e6d3fd91faa353113f296854592258fc3ad1410e23910bedb14f722b41
[root@localhost dockerfile-stopsignal]# docker run -d --name nginx-02 nginx-signal
e4cb66a30510593d4a22bbabe2755f8f1271b319ddf8ca05727c915b260f2003
[root@localhost dockerfile-stopsignal]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e4cb66a30510 nginx-signal "/usr/sbin/nginx" 13 seconds ago Up 12 seconds 80/tcp nginx-02
659d55e6d3fd nginx-signal "/usr/sbin/nginx" 17 seconds ago Up 16 seconds 80/tcp nginx-01
[root@localhost dockerfile-stopsignal]# docker stop nginx-01
nginx-01
[root@localhost dockerfile-stopsignal]# docker inspect -f '{{.State.ExitCode}}' nginx-01
0
[root@localhost dockerfile-stopsignal]# docker kill nginx-02
nginx-02
[root@localhost dockerfile-stopsignal]# docker inspect -f '{{.State.ExitCode}}' nginx-02
137
(12)HEALTHCHECK
- 配置所启动容器如何进行健康检查(如何判断健康与否),自Docker 1.12开始支持。
- 有两种格式:
-
HEALTHCHECK [OPTIONS] CMD command:根据所执行命令返回值是否为 0 来判断; -
HEALTHCHECK NONE:禁止基础镜像中的健康检查
OPTION支持如下参数:
--ATION (default: 30s):过多久检查一次;
--timeout=DURATION (default: 30s):每次检查等待结果的超时;
--retries=N (default: 3):如果失败了,重试几次才最终确定失败。
配置文件:
[root@localhost dockerfile-healthcheck]# ls
Dockerfile http-demo
[root@localhost dockerfile-healthcheck]# vi Dockerfile
# Base image
FROM rockylinux:9
# Maintainer
LABEL authors="chijinjing@xinxianghf.com"
WORKDIR /usr/local/app
COPY http-demo .
HEALTHCHECK --interval=30s --timeout=3s --retries=3\
CMD curl -fs http://localhost:8080/
CMD ["./http-demo"]
制作镜像:
[root@localhost dockerfile-healthcheck]# docker build -t http-good .
测试:
[root@localhost dockerfile-healthcheck]# docker run -d http-good
c6b787942f3df40ec7fe34f3c51511c6129af60d3190c67764ac1b0efc64d7f3
[root@localhost dockerfile-healthcheck]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c6b787942f3d http-good "./http-demo" 19 seconds ago Up 18 seconds (health: starting) strange_archimedes
# 等待一点时间后重新查看STATUS
[root@localhost dockerfile-healthcheck]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c6b787942f3d http-good "./http-demo" About a minute ago Up About a minute (healthy) strange_archimedes
异常示例------
配置文件:
[root@localhost dockerfile-healthcheck]# vi Dockerfile-bad
# Base image
FROM rockylinux:9
# Maintainer
LABEL authors="chijinjing@xinxianghf.com"
WORKDIR /usr/local/app
COPY http-demo .
HEALTHCHECK --interval=10s --timeout=1s --retries=1\
CMD curl -fs http://localhost:8081/
CMD ["./http-demo"]
制作镜像:
[root@localhost dockerfile-healthcheck]# docker build -t http-bad -f Dockerfile-bad .
测试:
[root@localhost dockerfile-healthcheck]# docker run -d http-bad
ef015b2eb4b04b0d4e4f18bb5ad538be12a10473bebec136d86da6c6be5a2e26
[root@localhost dockerfile-healthcheck]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ef015b2eb4b0 http-bad "./http-demo" 5 seconds ago Up 5 seconds (health: starting) happy_kowalevski
# 过一会儿后再次检查STATUS
[root@localhost dockerfile-healthcheck]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ef015b2eb4b0 http-bad "./http-demo" 21 seconds ago Up 20 seconds (unhealthy) happy_kowalevski
(13)SHELL
- 指定其他命令使用 shell 时的默认shell类型:
SHELL ["executable", "parameters"]- 默认值为["/bin/sh", "-c"]
(14)RUN
- 运行指定命令。
- 格式为
-
RUN <command>在 shell 终端中执行 -
RUN ["executable", "param1", "param2"]使用 exec 执行
- 每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像层。当命令较长时可以使用
\来换行
例如:
RUN dnf -y install telnet lrzsz iproute \
&& dnf clean all
(15)CMD
- CMD 指令用来指定启动容器时默认执行的命令。
- 支持三种格式:
-
CMD ["executable", "param1", "param2"]:相当于执行 executable param1 param2,推荐方式; -
CMD command param1 param2:在默认的 Shell 中执行,提供给需要交互的应用; -
CMD ["param1", "param2"]:提供给 ENTRYPOINT 的默认参数。
- 每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。
- 如果用户启动容器时候手动指定了运行的命令(作为 run 命令的参数),则会覆盖掉 CMD 指定的命令
CMD 与 ENTRYPOINT 的区别:
相同点:ENTRYPOINT目的和CMD一样,都是指定容器启动程序及参数。- 不同点:当指定了
ENTRYPOINT后,CMD的含义就发生了改变,不再是直接的运行其命令,而是将CMD的内容作为参数传给ENTRYPOINT指令,实际执行时,将变为:<ENTRYPOINT> "<CMD>"
(16)ADD
- 添加内容到镜像。
- 格式为
ADD <src> <dest> - 该命令将复制指定的 <src> 路径下内容到容器中的 <dest> 路径下。
- 其中 <src> 可以是 Dockerfile 所在目录的一个相对路径(文件或目录);也可以是一个 URL;还可以是一个tar 文件(自动解压为目录)<dest> 可以是镜像内绝对路径,或者相对于工作目录(WORKDIR)的相对路径
配置文件:
[root@localhost dockerfile-example]# cd dockerfile-add/
[root@localhost dockerfile-add]# ls
Dockerfile-v1 Dockerfile-v2 Dockerfile-v3 nginx-1.22.1 nginx-1.22.1.tar.gz
[root@localhost dockerfile-add]# vi Dockerfile-v1
# Base image
FROM rockylinux:9
# Maintainer
LABEL authors="chijinjing@xinxianghf.com"
# Add directory
ADD nginx-1.22.1 /usr/local/src/nginx-1.22.1
# 添加远程文件到容器内
# ADD https://nginx.org/download/nginx-1.22.1.tar.gz /usr/local/src
# 添加压缩文件到容器内
# ADD nginx-1.22.1.tar.gz /usr/local/src
CMD ["/bin/bash"]
制作镜像:
[root@localhost dockerfile-add]# docker build -t add:v1 -f Dockerfile-v1 .
[root@localhost dockerfile-add]# docker run --rm add:v1 ls /usr/local/src
nginx-1.22.1
(17)COPY
- 复制内容到镜像。
- 格式为
COPY <src> <dest> - 复制本地主机的 <src>(为Dockerfile所在目录的相对路径,文件或目录)下内容到镜像中的 <dest>。目标路径不存在时,会自动创建。
- 路径同样支持正则格式
COPY&&ADD
COPY的语义很明确,就是复制文件而已- 而
ADD则包含了更复杂的功能,其行为也不一定很清晰 - 最适合使用
ADD的场合,就是需要自动解压缩的场合