写在前面
系统环境:centos 7
一、Docker如何创建镜像
镜像的来源有两种:
- 从镜像仓库下载镜像;
- 自己创建新的镜像。创建分为两种:(1)基于已有镜像创建;(2)使用Dockerfile创建。
1.1 基于已有镜像创建
基于已有容器构建镜像主要是通过 docker commit 命令来构建新的镜像。构建步骤主要分为三步:(1)运行容器;(2)修改容器;(3)将容器保存为新的镜像。
运行容器
docker run -it ubuntu # 运行容器
修改容器
这里我们往容器里添加了 hello.c 文件
touch hello.c ## 修改容器,
exit # 退出容器
保存为新的容器
docker commit -a "panda" -m "commit test" 7f77678f7782 ubuntu-hello # 保存为新的容器
docker images # 查看
可以看到已经有了 ubuntu-hello 镜像。启动新的镜像,查看是否存在 hello.c 文件。
1.2 使用Dockerfile创建
1.2.1 构建镜像步骤分为三步:
- 将上下文发送到守护进程;
- 守护进程拿到上下文,向docker server发送http请求,构建镜像
- docker server 拿到上下文,按照docerfile要求创建镜像,构建过程可能会用到缓存
1.2.2 Dockerfile 关键字
FROM #设置镜像使用的基础镜像
MAINTAINER #设置镜像的作者
RUN #编译镜像时,要执行的命令
CMD #设置容器的启动命令
LABEL #设置镜像标签
EXPOSE #设置镜像暴露的端口
ENV #设置容器的环境变量
ADD # 编译镜像时复制上下文中文件到镜像中
COPY # 编译镜像时复制上下文中文件到镜像中
ENRYPOINT # 设置容器的入口程序
VOLUME # 设置容器的挂载卷
USER # 设置 RUN CMD ENTRYPOINT 的用户名
WORKER 设置RUN CMD ENTRYPOINT COPY ADD 指令的工作目录
ARG 设置编译镜像时加入的参数
ONBUILD 设置镜像的 ONBUILD 指令
STOPSIGNAL 设置容器退出时候的信号量
Add 和 copy的区别
COPY ./hello.c ./
ADD ./nginx.tar.gz ./
ADD http://www.panda.com/nginx.tar.gz
ADD可以在拷贝压缩文件的时候回直接进行解压,如果ADD后面跟的是网址,可从网站直接下载文件,这里就是单纯的下载文件了,不解压!
1.2.2 Dockerfile实战:以hello.c 为例,创建Dockerfile
创建 hello.c 源文件
#include <stdio.h>
int main()
{
printf("hello, world\n");
return 0;
}
创建 Dockerfile 文件
FROM gcc 指定基础镜像,如果是go程序 则 FROM golang:1.18,如果不指定版本,默认最新版本。注意:pwd是在构建过程中执行的,并不是在容器中执行。
FROM gcc
MAINTAINER panda
COPY ./hello.c ./
RUN pwd
LABEL myhello 1.0.0
LABEL env prod
RUN gcc hello.c -o hello
CMD ["./hello"]
构建镜像
docker build -t myhellc .
运行镜像
docker run -it myhelloc
细心的小伙伴可能发现了,我们的代码实际上就写了一行。但是,构建出来的镜像却有1.27个g,很明显是不合理的。此时,就需要多阶段构建。
二、Docker镜像管理
2.1 Hub官方仓库使用
Docker Hub是目前Docker官方维护的一个公共仓库,它用来保存我们的镜像其中包括海量镜像,如:nginx、redis、ubuntu等,跟github作用类似。
2.1.1 使用Hub官方仓库需要用户名、密码和邮箱来注册账号。注册完登录成功,就可以开始搭建自己的仓库了。
2.1.2 登录验证
注意:默认登录使用的是官方仓库,登出也是。
docker login -u panbamboo # 直接使用-u 默认登录的是官方仓库
2.1.3 镜像推送验证
我们将第一部分生成的myhelloc镜像重新打个tag( hello是镜像名称,tag为1.0.0 )上传到我们刚建的公有仓库。
# 打tag
docker tag myhelloc:latest panbamboo/hello:1.0.0
# 推送到公有仓库
docker push panbamboo/hello:1.0.0
推送完成,刷新下界面就能看下途中红色框中的镜像已经成功上传了。
现在我们可以删除本地panbamboo/hello:1.0.0镜像,docker images 查看本地已经没有该镜像。
docker rmi panbamboo/hello:1.0.0 #
再从远端仓库拉取镜像。
到这里我们就掌握使用官方Hub仓库推送和拉取镜像了,是不是很简单~
2.2 搭建私有仓库
官方给我们提供了一个 registry 的镜像来帮助我们搭建私有镜像注册中心。在首页搜索 registry ,然后复制 红色框命令,准备拉取镜像。私有仓库如果是公司内网访问的话,用户名密码也可以考虑省略。
2.2.1 拉取 registry 镜像
docker pull registry
2.2.2 安装 apache2-utils
apache2-utils 是用来生成用户名和密码,安装命令如下:
# ubuntu
sudo apt-get install apache2-utils
# centos
sudo yum -y install httpd-tools
2.2.3 创建存储目录
因为是注册中心,用来存放镜像,所以先创建一个位置来存放我们的镜像。
注意:创建前先使用echo $HOME 查看下自己的HOME路径是什么,否则你创建完都不知道自己创建的目录在什么位置
echo $HOME
/root # $HOME 的值
mkdir -p $HOME/registry
mkdir -p $HOME/registry/auth
mkdir -p $HOME/registry/data
将用户名密码写入 /root/registry/auth/ 目录下 htpasswd 文件,密码是加密后的形式。
# 用户名和密码都是:panda
htpasswd -Bbn panda panda > $HOME/registry/auth/htpasswd
2.2.4 运行docker
docker run -d -p 5000:5000 --name registry --restart=always -v $HOME/registry/data:/var/lib/registry -v $HOME/registry/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry:2
使用 docker ps 看到 registry 表明启动完成。
补充:还可以使用docker inspect registry 查看目录挂载情况(Mounts字段)
2.2.5 修改 docker.service 配置文件
在如下位置后面添加:–insecure-registry localhost:5000,localhost:5000 是用户名,可以任意起名。
vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
--insecure-registry localhost:5000
到这里,我们的私有注册中心就构建完成了。
2.2.6 私有中心推送和拉取验证
因为我们目前使用的官方仓库,所以,我们需要先登出,才能登录私有注册中心。
注册中心切换
docker logout
docker login localhost:5000 # 这里写你自己的
docker tag myhelloc:latest localhost:5000/hello:1.0.0
推送验证
docker push localhost:5000/hello:1.0.0 ## 等待推送成功即可
拉取验证
docker images # 找到localhost:5000/hello:1.0.0 对应的 IMAGE ID a62b4a7b6bfc
docker rmi -f a62b4a7b6bfc # -f 强制删除该镜像
docker pull localhost:5000/hello:1.0.0 ## 拉取镜像
2.3 docker save/load 命令
docker save可以保存本地已有镜像到 xxx.tar 文件,再通过 docker load -i xxx.tar 加载本地镜像
docker save -o nginx.tar nginx:latest # 将nginx镜像保存到本地 nginx.tar 文件
tar -xvf nginx.tar -C tmp/ # 将镜像解压到tmp目录,有兴趣的可以看看里面有什么,实际上还是分层存储
docker load -i nginx.tar # 从本地加载镜像
与docker import/ export 的区别:
docker load 在加载的时候是无法修改镜像的名称以及tag的,docker import/ export可以。