使用现成镜像的好处除了省去自己做镜像的工作量外,更重要的是可以利用前人的经验。特别是使用那些官方镜像,因为Docker的工程师知道如何更好地在容器中运行软件。
当然,某些情况下我们也不得不自己构建镜像,比如:(1)找不到现成的镜像,比如自己开发的应用程序。(2)需要在镜像中加入特定的功能,比如官方镜像几乎都不提供ssh。
Docker提供了两种构建镜像的方法: docker commit命令与Dockerfile构建文件。
● 在base镜像基础上运行容器。
● 修改容器。
● 将容器保存为新的镜像。
# 创建一个名为temp-nginx-container的新容器,并使用Ubuntu基础镜像启动一个交互式的bash会话:
# -it: 分配一个伪终端并保持标准输入打开
sudo docker run -it --name temp-nginx-container ubuntu /bin/bash
# 在新创建的容器中,安装Nginx:
# -y: 这是一个选项,表示在安装过程中自动回答 yes,即在提示时自动选择“是”。
apt update
apt install -y nginx
# 安装完成后,可以退出容器的bash会话,并停止该容器:
exit
sudo docker stop temp-nginx-container
# 使用docker commit命令将修改后的容器保存为新的镜像:
# 创建一个名为my-nginx-image的新镜像,其中包含了你在temp-nginx-container容器中所做的修改
sudo docker commit temp-nginx-container my-nginx-image
# 使用以下命令来查看新创建的镜像:
sudo docker images
(1)这是一种手工创建镜像的方式,容易出错,效率低且可重复性弱。比如要在debian base镜像中也加入vi,还得重复前面的所有步骤。
(2)更重要的:使用者并不知道镜像是如何创建出来的,里面是否有恶意程序。也就是说无法对镜像进行审计,存在安全隐患。
但是,即便是用Dockerfile(推荐方法)构建镜像,底层也是docker commit一层一层构建新镜像的。学习docker commit能够帮助我们更加深入地理解构建过程和镜像的分层结构。
Dockerfile是一个文本文件,记录了镜像构建的所有步骤。
当谈到Shell和Exec格式时,通常是指在编写脚本或命令时使用的两种不同的语法格式。这两种格式在编写脚本或命令时有着不同的特点和用途。
Shell格式:
Exec格式:
ls
命令,你可以使用ls -l
来列出详细信息,这里的-l
就是ls
命令的选项之一,遵循了ls
命令的Exec格式。总的来说,Shell格式主要用于编写Shell脚本,其中包含了Shell解释器的语法和特性,而Exec格式则主要用于编写可执行程序或直接在命令行中执行的命令,其中包含了特定命令或程序的语法和选项。两者在语法和用途上有所不同,但都是在编写和执行命令时常用的格式。
# 使用Shell格式的RUN命令,在容器中执行Shell命令
RUN apt update && apt install -y nginx
# 使用Shell格式的CMD命令,在容器启动时执行Shell命令
CMD service nginx start
# 使用Exec格式的ENTRYPOINT命令,指定容器启动时执行的可执行程序
ENTRYPOINT ["nginx", "-g", "daemon off;"]
通常来说,对于需要执行复杂的Shell命令或包含逻辑操作符的命令,可以使用Shell格式的命令;而对于需要指定可执行程序及其参数的情况,可以使用Exec格式的命令。
(1)使用RUN指令安装应用和软件包,构建镜像。
(2)如果Docker镜像的用途是运行应用程序或服务,比如运行一个MySQL,应该优先使用Exec格式的ENTRYPOINT指令。CMD可为ENTRYPOINT提供额外的默认参数,同时可利用docker run命令行替换默认参数。
(3)如果想为容器设置默认的启动命令,可使用CMD指令。用户可在docker run命令行中替换此默认命令。
mkdir nginx-image
cd nginx-image
touch Dockerfile
# 使用官方的Ubuntu镜像作为基础镜像
FROM ubuntu
# 更新Ubuntu软件包列表并安装Nginx
RUN apt update && apt install -y nginx
# 暴露Nginx的80端口
EXPOSE 80
# 启动Nginx服务
CMD ["nginx", "-g", "daemon off;"]
这将使用Dockerfile中的指令构建一个新的Docker镜像,并将其命名为my-nginx-image。
docker build
: 使用 Dockerfile 构建一个新的镜像。
-t my-nginx-image
: 为构建的镜像指定一个名称为 my-nginx-image。
.
: 表示 Docker 在当前目录中查找 Dockerfile 来构建镜像。
sudo docker build -t my-nginx-image .
sudo docker images
sudo docker run -d -p 80:80 my-nginx-image
(1)用相同的Dockerfile在其他host构建镜像。
(2)将镜像上传到公共Registry(比如Docker Hub), Host直接下载使用。
(3)搭建私有的Registry供本地Host使用。
Docker Hub是Docker公司维护的公共Registry。用户可以将自己的镜像保存到Docker Hub免费的repository中。如果不希望别人访问自己的镜像,也可以购买私有repository。
安装Docker Registry
docker run -d -p 5000:5000 --restart=always --name my-registry registry:2
配置Docker客户端: 接下来,你需要配置Docker客户端,以便它能够与本地的Registry进行交互。你可以通过编辑Docker配置文件(通常是/etc/docker/daemon.json)来添加Registry的地址,将your-registry-domain替换为你的Registry所在的域名或IP地址。
{
"insecure-registries" : ["your-registry-domain:5000"]
}
使用docker push命令将本地构建的镜像推送到你的Registry中,也可以使用docker pull命令从Registry中拉取镜像。
docker tag my-image your-registry-domain:5000/my-image:v1.0
docker push your-registry-domain:5000/my-image:v1.0
docker pull your-registry-domain:5000/my-image:v1.0
docker tag
: 这是用于给 Docker 镜像打标签的命令。
my-image
: 这是要被标记的现有镜像的名称或 ID。
your-registry-domain:5000/my-image:v1.0.
: 这是新的名称,指定了镜像的目标位置、名称、版本。
注意:镜像一定要按照规范(host:port/镜像名)命名,否则push会被拒绝。
当使用Docker时,有一些常用的镜像命令可以帮助你管理和操作Docker镜像。以下是一些常用的Docker镜像命令及其功能:
docker images:
docker images
docker pull:
docker pull ubuntu:latest
docker build:
docker build -t my-image .
docker tag:
docker tag my-image my-registry-domain:5000/my-image:v1.0
docker push:
docker push my-registry-domain:5000/my-image:v1.0
docker rmi:
docker rmi my-image
docker inspect:
docker inspect my-image
docker history:
docker history my-image
docker save 和 docker load:
docker save
用于将一个或多个镜像保存为tar归档文件。docker load
用于从tar归档文件中加载镜像。docker save -o my-images.tar my-image
和 docker load -i my-images.tar
这些命令可以帮助你管理Docker镜像,包括拉取、构建、推送、删除、查看详细信息等操作。通过熟练掌握这些命令,你可以更好地管理和使用Docker镜像。