Docker(二)自定义镜像与仓库
一、自定义镜像
1.docker commit
使用官方的镜像创建的容器只有很少的linux命令可用,可否自己创建一个镜像呢?
宿主机:
[root@docker1 ~]# docker run -it docker.io/centos bash #将centos镜像作为后端盘创建并运行一个新容器
容器:
[root@f7831a24daf0 ~]# rm -rf /etc/yum.repos.d/*
[root@f7831a24daf0 ~]# vi /etc/yum.repos.d/local.repo #给容器配置一个yum源(阿里源)
[BaseOS]
name=CentOS-$releasever - Base
baseurl=http://mirrors.aliyun.com/centos/$releasever/BaseOS/$basearch/os/
gpgcheck=0
[AppStream]
name=CentOS-$releasever - AppStream
baseurl=http://mirrors.aliyun.com/centos/$releasever/AppStream/$basearch/os/
gpgcheck=0
[root@f7831a24daf0 ~]# yum install -y net-tools vim python39 #安装软件包(ifconfig命令来自于net-tools软件包)
[root@f7831a24daf0 ~]# exit
宿主机:
[root@docker1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7831a24daf0 docker.io/centos:latest "/bin/bash" About an hour ago Exited (0) 7 seconds ago berserk_babbage
[root@docker1 ~]# docker commit 11f2fc2d6fd2 myos:latest #将刚刚创建的容器和底层centos镜像一起制作成新的镜像myos
sha256:6a4a596a3f909549be7f1e3d1362cca1ee89cd69613c88a005b348eb592d2064
[root@docker1 ~]# docker rm f7831a24daf0 #删除之前创建的容器
f7831a24daf0
[root@docker1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myos latest 6a4a596a3f90 About a minute ago 347.5 MB
docker.io/nginx latest f9c14fe76d50 2 weeks ago 142.5 MB
docker.io/redis latest 0ec8ab59a35f 2 weeks ago 117.1 MB
docker.io/busybox latest 8135583d97fe 2 weeks ago 4.863 MB
docker.io/centos latest 5d0da3dc9764 21 months ago 231.2 MB
[root@docker1 ~]# docker run -it myos:latest #使用自己制作的镜像myos创建一个容器
[root@77fbe92ace61 /]# ifconfig #可以看到用myos镜像创建的容器有ifconfig命令了
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe11:2 prefixlen 64 scopeid 0x20<link>
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 7 bytes 578 (578.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 7 bytes 578 (578.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
2.Dockerfile
Dockerfile是生成镜像脚本的应答文件,Dockerfile是比commit更强大的镜像编排方式
Dockerfile语法格式:
FROM:基础镜像
MAINTAINER:镜像创建者信息
EXPOSE:开放的端口
ENV:设置变量
ADD:复制文件到镜像
RUN:制作镜像时执行的命令,可以有多个
WORKDIR:定义容器默认工作目录
CMD:容器启动时执行的命令,仅可以有一条CMD
#演示1:FROM、RUN、ADD
[root@docker1 ~]# mkdir work
[root@docker1 ~]# cd work/
[root@docker1 work]# vim Dockerfile
FROM docker.io/centos:latest #基础镜像为docker.io/centos
RUN rm -f /etc/yum.repos.d/*
ADD local.repo /etc/yum.repos.d/local.repo #将当前路径下的local.repo复制到容器的/etc/yum.repos.d/local.repo
RUN yum install -y vim net-tools python39
[root@docker1 work]# vim local.repo #创建local.repo文件
[BaseOS]
name=CentOS-$releasever - Base
baseurl=http://mirrors.aliyun.com/centos/$releasever/BaseOS/$basearch/os/
gpgcheck=0
[AppStream]
name=CentOS-$releasever - AppStream
baseurl=http://mirrors.aliyun.com/centos/$releasever/AppStream/$basearch/os/
gpgcheck=0
[root@docker1 work]# ls #当前路径必须包含Dockerfile
Dockerfile local.repo
[root@docker1 work]# docker build -t myos:test . #使用当前路径下的配置创建镜像(注意:"."代表当前路径)
[root@docker1 work]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myos test ed8b711aef58 10 seconds ago 347.4 MB
myos latest 6a4a596a3f90 28 minutes ago 347.5 MB
docker.io/nginx latest f9c14fe76d50 2 weeks ago 142.5 MB
docker.io/redis latest 0ec8ab59a35f 2 weeks ago 117.1 MB
docker.io/busybox latest 8135583d97fe 2 weeks ago 4.863 MB
docker.io/centos latest 5d0da3dc9764 21 months ago 231.2 MB
#演示2:CMD
[root@docker1 work1]# vim Dockerfile
FROM myos:latest
CMD ["/usr/bin/python3"] #CMD的语法是["指令"],如果指令有参数用逗号分隔,如["/bin/ls","-l","-a"]
[root@docker1 work1]# docker build -t myos:python .
[root@docker1 work1]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myos python 5a4286358e42 7 seconds ago 347.5 MB
myos test ed8b711aef58 11 minutes ago 347.4 MB
myos latest 6a4a596a3f90 39 minutes ago 347.5 MB
docker.io/nginx latest f9c14fe76d50 2 weeks ago 142.5 MB
docker.io/redis latest 0ec8ab59a35f 2 weeks ago 117.1 MB
docker.io/busybox latest 8135583d97fe 2 weeks ago 4.863 MB
docker.io/centos latest 5d0da3dc9764 21 months ago 231.2 MB
[root@docker1 work1]# docker run -it myos:python
Python 3.9.6 (default, Aug 25 2021, 16:22:38)
[GCC 8.5.0 20210514 (Red Hat 8.5.0-3)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> #可以看到一进入容器就已经在python环境下了
#演示3:制作一个带有sshd服务的镜像
[root@docker1 work2]# vim Dockerfile #创建Dockerfile文件
FROM myos:latest #以myos:latest镜像为模板
RUN yum install -y openssh-server initscripts passwd #安装sshd服务软件包依赖包和passwd命令的软件包
RUN ssh-keygen -A #生成密钥-A为选择默认
RUN sed -i 's/^#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config #修改配置文件允许root访问
RUN echo "000000"|passwd --stdin root #修改root密码为000000
EXPOSE 22 #打开22端口
CMD ["/usr/sbin/sshd","-D"] #开机启动sshd服务
[root@docker1 work2]# docker build -t myos:sshd . #根据当前目录下的Dockerfile文件创建新镜像myos:sshd
[root@docker1 work2]# docker images #myos:sshd为新创建的镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
myos sshd 6c32f5314416 8 seconds ago 367.6 MB
myos python 5a4286358e42 About an hour ago 347.5 MB
myos test ed8b711aef58 About an hour ago 347.4 MB
myos latest 6a4a596a3f90 2 hours ago 347.5 MB
docker.io/nginx latest f9c14fe76d50 2 weeks ago 142.5 MB
docker.io/redis latest 0ec8ab59a35f 2 weeks ago 117.1 MB
docker.io/busybox latest 8135583d97fe 2 weeks ago 4.863 MB
docker.io/centos latest 5d0da3dc9764 21 months ago 231.2 MB
[root@docker1 work2]# docker run -itd myos:sshd #使用myos:sshd镜像创建并启动一个容器,-d表示后台运行
[root@docker1 work2]# docker inspect 46733b715de7 #docker inspect+容器ID 可以查看容器信息,里面包含IP:"IPAddress": "172.17.0.2"
[root@docker1 work2]# ssh root@172.17.0.2 #输入容器root用户的密码000000
[root@46733b715de7 ~]#
#演示4:制作一个带有httpd服务的镜像
[root@docker1 work3]# vim Dockerfile
FROM myos:latest
MAINTAINER vorn #镜像作者vorn
RUN yum install -y httpd iproute #安装http服务和相关工具
ADD index.html /var/www/html/ #将index.html复制到容器html下
EXPOSE 80
EXPOSE 443 #如果发布的是https服务则需要443端口
ENV PS1='[web@\h \W]\$ ' #修改容器主机名为web
WORKDIR /var/www/html #默认工作目录,到时候进入这个镜像默认就会在/var/www/html下
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"] #启动httpd服务
#使用set|grep -i ps1命令可以得到PS1='[\u@\h \W]\$ ' 可见bash中显示的主机名由@前一个字符控制,因此设置PS1='[web@\h \W]\$ '就可以将bash显示的主机名由当前用户名称改为web
[root@docker1 work3]# vim index.html
hello world
[root@docker1 work3]# docker build -t myos:httpd .
[root@docker1 work3]# docker run -itd myos:httpd
[root@docker1 work3]# curl 172.17.0.3 #可以使用docker inspect+容器ID 查询容器IP
hello world
[root@docker1 work3]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3b90c21d1602 myos:httpd "/usr/sbin/httpd -D F" 19 seconds ago Up 18 seconds 80/tcp, 443/tcp compassionate_gates
46733b715de7 myos:sshd "/usr/sbin/sshd -D" 30 minutes ago Up 30 minutes 22/tcp goofy_ride
[root@docker1 work3]# docker exec -it 3b90c21d1602 bash
[web@3b90c21d1602 html]# pwd #由于设置了ENV PS1='[web@\h \W]\$ ',可以看到一进入容器主机名显示为web;由于设置了WORKDIR /var/www/html,一进入容器就在html目录
/var/www/html
#演示5:CMD有且只有一条,如果多条的话后一条RUN会覆盖前一条RUN,如果想启动两个服务怎么办呢
[root@docker1 work4]# vim Dockerfile
FROM myos:sshd #以myos:sshd镜像为模板可以减少sshd服务的配置步骤
MAINTAINER vorn
RUN yum install -y httpd iproute
ADD index.html /var/www/html/
EXPOSE 22 #多了sshd服务因此还需开启22端口
EXPOSE 80
EXPOSE 443
ENV PS1='[web@\h \W]\$ '
WORKDIR /var/www/html
ADD run.sh /etc/init.d/run.sh #复制run.sh脚本
CMD ["/etc/init.d/run.sh"] #将sshd、httpd服务启动命令放到run.sh中,容器启动时执行这个脚本即可启动两个服务
[root@docker1 work4]# vim index.html
hello world
[root@docker1 work4]# vim run.sh
#!/bin/bash
/usr/sbin/sshd -D &
/usr/sbin/httpd -D FOREGROUND
[root@docker1 work4]# chmod 755 run.sh #给脚本执行权限
[root@docker1 work4]# docker build -t myos:sshd_httpd . #创建myos:sshd_httpd镜像
[root@docker1 work4]# docker run -itd myos:sshd_httpd
[root@docker1 work4]# curl 172.17.0.4
hello world
[root@docker1 work4]# ssh root@172.17.0.4
[root@840c75dca026 ~]#
总结:也可以将一切配置写到脚本中,然后通过以下Dockerfile创建镜像
# 基础镜像
FROM centos:8
# 安装所需软件包
RUN yum update -y && \
yum install -y wget curl git
# 复制脚本文件
ADD start.sh /start.sh
# 执行脚本
CMD ["/bin/bash", "/start.sh"]
二、自定义镜像仓库
环境信息:
node1:192.168.0.30
docker1:192.168.0.31
docker2:192.168.0.32
1.创建镜像仓库
docker-distribution服务:
配置文件:/etc/docker-distribution/registry/config.yml
数据目录(存放镜像的目录):/var/lib/registry/
服务端口:5000
[root@node1 ~]# yum install -y docker-distribution
[root@node1 ~]# systemctl start docker-distribution
[root@node1 ~]# systemctl enable docker-distribution
2.给仓库上传镜像
[root@docker1 ~]# vim /etc/sysconfig/docker #修改docker配置文件
13 ADD_REGISTRY='--add-registry 192.168.0.30:5000' #镜像仓库地址
24 INSECURE_REGISTRY='--insecure-registry 192.168.0.30:5000' #允许非加密方式访问仓库
[root@docker1 ~]# systemctl restart docker #重启docker服务,注意重启前需先停止所有容器
[root@docker1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myos sshd_httpd 664d022ad254 21 hours ago 395 MB
myos httpd 45ba6d985096 21 hours ago 374.2 MB
myos sshd 6c32f5314416 22 hours ago 367.6 MB
myos python 5a4286358e42 23 hours ago 347.5 MB
myos test ed8b711aef58 23 hours ago 347.4 MB
myos latest 6a4a596a3f90 24 hours ago 347.5 MB
docker.io/nginx latest f9c14fe76d50 2 weeks ago 142.5 MB
docker.io/redis latest 0ec8ab59a35f 2 weeks ago 117.1 MB
docker.io/busybox latest 8135583d97fe 2 weeks ago 4.863 MB
docker.io/centos latest 5d0da3dc9764 21 months ago 231.2 MB
[root@docker1 ~]# docker tag busybox:latest 192.168.0.30:5000/busybox:latest #上传镜像的时候是根据镜像标签中的网址识别传到哪个仓库的,因此需要修改镜像标签为node1节点的镜像仓库网址
[root@docker1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myos sshd_httpd 664d022ad254 21 hours ago 395 MB
myos httpd 45ba6d985096 21 hours ago 374.2 MB
myos sshd 6c32f5314416 22 hours ago 367.6 MB
myos python 5a4286358e42 23 hours ago 347.5 MB
myos test ed8b711aef58 23 hours ago 347.4 MB
myos latest 6a4a596a3f90 24 hours ago 347.5 MB
docker.io/nginx latest f9c14fe76d50 2 weeks ago 142.5 MB
docker.io/redis latest 0ec8ab59a35f 2 weeks ago 117.1 MB
192.168.0.30:5000/busybox latest 8135583d97fe 2 weeks ago 4.863 MB
docker.io/busybox latest 8135583d97fe 2 weeks ago 4.863 MB
docker.io/centos latest 5d0da3dc9764 21 months ago 231.2 MB
[root@docker1 ~]# docker push 192.168.0.30:5000/busybox:latest #上传镜像
The push refers to a repository [192.168.0.30:5000/busybox]
9547b4c33213: Pushed
latest: digest: sha256:3e87b537a51c2c1361b9fea28ee1163e665f86009e074ff6157cf233c9daca0a size: 528
[root@docker1 ~]# for i in sshd_httpd httpd sshd python test latest
> do
> docker tag myos:${i} 192.168.0.30:5000/myos:${i}
> docker push 192.168.0.30:5000/myos:${i}
> done #上传镜像
root@docker1 ~]# curl http://192.168.0.30:5000/v2/_catalog #查看镜像仓库中的镜像名称
{"repositories":["busybox","myos"]}
[root@docker1 ~]# curl http://192.168.0.30:5000/v2/myos/tags/list #查看myos仓库的标签
{"name":"myos","tags":["sshd_httpd","httpd","sshd","python","test","latest"]}
3.使用镜像仓库
[root@docker2 ~]# vim /etc/sysconfig/docker #修改docker配置文件
13 ADD_REGISTRY='--add-registry 192.168.0.30:5000' #镜像仓库地址
24 INSECURE_REGISTRY='--insecure-registry 192.168.0.30:5000' #允许非加密方式访问仓库
[root@docker2 ~]# systemctl restart docker #重启docker服务,注意重启前需先停止所有容器
[root@docker2 ~]# docker run -it 192.168.0.30:5000/busybox:latest #可以直接创建并启动容器,镜像会自动下载,192.168.0.30:5000/可以省略,因为这部分在配置文件中有配置过
Unable to find image '192.168.0.30:5000/busybox:latest' locally
Trying to pull repository 192.168.0.30:5000/busybox ...
latest: Pulling from 192.168.0.30:5000/busybox
a28583f6916d: Pull complete
Digest: sha256:3e87b537a51c2c1361b9fea28ee1163e665f86009e074ff6157cf233c9daca0a
/ #
[root@docker2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.0.30:5000/busybox latest 8135583d97fe 2 weeks ago 4.863 MB
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具