Docker是管理容器的引擎,为应用打包、部署平台,而非单纯的虚拟化技术
它具有以下几个重要特点和优势:
-
轻量级虚拟化:Docker 容器相较于传统的虚拟机更加轻量和高效,能够快速启动和停止,节省系统资源。
例如,启动一个 Docker 容器可能只需要几秒钟,而启动一个虚拟机则可能需要几分钟。
-
一致性:确保应用程序在不同的环境中(如开发、测试、生产)具有一致的运行表现。
无论在本地还是云端,应用的运行环境都能保持相同,减少了因环境差异导致的问题。
-
可移植性:可以轻松地将 Docker 容器从一个平台迁移到另一个平台,无需担心依赖和环境配置的差异。
比如,在本地开发的容器可以无缝部署到云服务器上。
-
高效的资源利用:多个 Docker 容器可以共享主机的操作系统内核,从而更有效地利用系统资源。
-
易于部署和扩展:能够快速部署新的应用实例,并且可以根据需求轻松地进行水平扩展。
总之,Docker 极大地简化了应用程序的开发、部署和管理流程,提高了开发效率和运维的便利性。它在现代软件开发和云计算领域得到了广泛的应用。
docker与虚拟化的对比

一、部署docker
配置软件仓库并安装docker-ce
bash
#利用阿里云部署软件仓库
[root@docker-node1 ~]# cat > /etc/yum.repos.d/docker.repo << EOF
[docker]
name = docker
baseurl = https://mirrors.aliyun.com/docker-ce/linux/rhel/9.6/x86_64/stable/
gpgcheck = 0
EOF
[root@docker-node1 ~]# dnf makecache
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 "rhc" 或 "subscription-manager" 进行注册。
docker 7.3 kB/s | 46 kB 00:06
AppStream 3.1 MB/s | 3.2 kB 00:00
BaseOS 2.7 MB/s | 2.7 kB 00:00
元数据缓存已建立。
[root@docker-node1 ~]# dnf search docker
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 "rhc" 或 "subscription-manager" 进行注册。
上次元数据过期检查:0:00:13 前,执行于 2026年03月14日 星期六 14时55分07秒。
==================================== 名称 和 概况 匹配:docker =====================================
docker-buildx-plugin.x86_64 : Docker Buildx plugin for the Docker CLI
docker-ce-rootless-extras.x86_64 : Rootless support for Docker
docker-compose-plugin.x86_64 : Docker Compose plugin for the Docker CLI
docker-model-plugin.x86_64 : Docker Model Runner plugin for the Docker CLI
pcp-pmda-docker.x86_64 : Performance Co-Pilot (PCP) metrics from the Docker daemon
podman-docker.noarch : Emulate Docker CLI using podman
======================================== 名称 匹配:docker =========================================
docker-ce.x86_64 : The open-source application container engine
docker-ce-cli.x86_64 : The open-source application container engine
[root@docker-node1 ~]# dnf install docker-ce -y
[root@docker-node1 ~]# vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=true
[root@docker-node1 ~]# echo br_netfilter > /etc/modules-load.d/docker_mod.conf
[root@docker-node1 ~]# modprobe -a br_netfilter
[root@docker-node1 ~]# cat > /etc/sysctl.d/docker.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
[root@docker-node1 ~]# sysctl --system
[root@docker-node1 ~]# systemctl enable --now docker
二、docker的常规使用方法
1.配置docker加速器
bash
[root@docker-node1 ~]# cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["https://docker.1ms.run"]
}
EOF
[root@docker-node1 ~]# systemctl restart docker
[root@docker-node1 ~]# docker info
Registry Mirrors:
https://docker.1ms.run/
2.docker常用命令
bash
#镜像查看
[root@docker-node1 ~]# docker images IMAGE ID DISK USAGE CONTENT SIZE EXTRA
#搜索镜像
[root@docker-node1 ~]# docker search nginx
NAME DESCRIPTION STARS OFFICIAL
nginx Official build of Nginx. 21206
#下载镜像
[root@docker-node1 ~]# docker pull nginx
[root@docker-node1 ~]# docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
61dfb50712f5: Pull complete
96cfb76e59bd: Download complete
Digest: sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd76f
Status: Downloaded newer image for busybox:latest
docker.io/library/busybox:latest
#查看镜像提交历史
[root@docker-node1 ~]# docker history busybox:latest
IMAGE CREATED CREATED BY SIZE COMMENT
b3255e7dfbcd 17 months ago BusyBox 1.37.0 (glibc), Debian 13 4.49MB
[root@docker-node1 ~]# docker images
i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
busybox:latest b3255e7dfbcd 6.7MB 2.22MB
nginx:1.26 41b194461e4b 279MB 75.2MB
#导出镜像
[root@docker-node1 ~]# docker save -o game2048-latest.tar timinglee/game2048:latest
#删除镜像
[root@docker-node1 ~]# docker rmi timinglee/mario:latest
#导入镜像
[root@docker-node1 ~]# docker load -i game2048-latest.tar
#运行镜像
[root@docker-node1 ~]# docker run -d --name web nginx:1.26
f3e369725fab95d48779eaa556941b735aae841efe09bb1d28bca89923c44ee4
#查看运行容器
[root@docker-node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f3e369725fab nginx:1.26 "/docker-entrypoint...." 2 seconds ago Up 2 seconds 80/tcp web
#查看所有容器
[root@docker-node1 ~]# docker ps -a
#交互模式运行容器
[root@docker-node1 ~]# docker run -it --name busybox busybox:latest
#交互运行容器默认退出后会停止
[root@docker-node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d1b27167a247 busybox:latest "sh" 50 seconds ago Exited (0) 19 seconds ago busybox
#运行停止的容器
[root@docker-node1 ~]# docker start busybox
root@docker-node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d1b27167a247 busybox:latest "sh" 2 minutes ago Up 1 second busybox
#退出交互容器不对其停止
[root@docker-node1 ~]# docker attach busybox
/ # [ctrl]+[p]+[q] #按键
[root@docker-node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d1b27167a247 busybox:latest "sh" 3 minutes ago Up About a minute busybox
#查看容器信息
[root@docker-node1 ~]# docker inspect busybox
#容器控制
[root@Docker-node1 ~]# docker stop busybox #停止容器
[root@Docker-node1 ~]# docker kill busybox #杀死容器,可以使用信号
[root@Docker-node1 ~]# docker start busybox #开启停止的容器
#在已经运行的容器中执行指定命令
[root@docker-node1 ~]# docker exec busybox touch /root/haha #非交互
[root@docker-node1 ~]# docker exec busybox ls /root
file1
file2
haha
[root@docker-node1 ~]# docker exec -it web /bin/bash #交互的
root@f3e369725fab:/#
#容器删除
[root@docker-node1 ~]# docker rm -f busybox
busybox
[root@docker-node1 ~]# docker stop web
web
[root@docker-node1 ~]# docker rm web
web
#内容提交
[root@docker-node1 ~]# docker run -it --name test busybox:latest
/ # touch /root/file
/ # ls /root/
file
ctrl+qp 退出当前环境并继续运行容器
[root@docker-node1 ~]# docker commit -m "add file" test busybox-file:latest
sha256:31a32089d241d025a5a54f144f15319cc6fb55be1b41d049f8905a472d5a028e
[root@docker-node1 ~]# docker images
i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
busybox-file:latest 31a32089d241 6.71MB 2.21MB
[root@docker-node1 ~]# docker run -it --name test busybox-file:latest
#文件在镜像中的复制
[root@docker-node1 ~]# docker run -it --name test busybox-file:latest
root@docker-node1 ~]# docker cp test:/root/file /mnt
Successfully copied 1.54kB to /mnt
[root@docker-node1 ~]# ls /mnt/
file hgfs
[root@docker-node1 ~]# docker cp /etc/passwd test:/root/
Successfully copied 3.07kB to test:/root/
[root@docker-node1 ~]# docker exec test ls /root
file
passwd
三、容器外部网络访问
在 Docker 环境中,容器默认运行在独立的网络命名空间中,外部无法直接访问容器内部服务。本实验通过端口映射、容器生命周期管理等操作,验证 Docker 容器网络的连通性与端口发布机制,最终实现从宿主机 / 外部浏览器访问容器内的 Nginx 和马里奥游戏服务。
- 桥接网络(bridge) :默认网络模式,容器获得独立 IP,通过
docker0网桥与宿主机通信。 - 端口映射(-p) :将宿主机端口与容器端口绑定,格式为
宿主机端口:容器端口,实现外部访问。 - 容器名唯一性:容器名在 Docker 守护进程中全局唯一,即使容器停止,名字仍被占用,需手动删除才能复用
内部访问:容器在桥接网络中拥有独立 IP,宿主机可通过容器 IP 直接访问内部服务。
bash
[root@docker-node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@docker-node1 ~]# docker run -d --name web nginx:latest
6332a6ffaccd45a063f697e24aa3b6e7cf50cd64c4a967bd6598a4954063277f
[root@docker-node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6332a6ffaccd nginx:latest "/docker-entrypoint...." 7 seconds ago Up 7 seconds 80/tcp web
[root@docker-node1 ~]# docker inspect web
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"DriverOpts": null,
"GwPriority": 0,
"NetworkID": "2a18b88a321ddca8ebc971e306bfe0801d44c7c499f9661576ff5d1de2e823cd",
"EndpointID": "4b115130c11936090fb2d1ceafd3c5af240166ed30fb5de01bfd0d6140df881f",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2", #这个地址
"MacAddress": "f6:0c:eb:35:75:96",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"DNSNames": null
}
}
},
[root@docker-node1 ~]# curl "172.17.0.2"
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, nginx is successfully installed and working.
Further configuration is required for the web server, reverse proxy,
API gateway, load balancer, content cache, or other features.</p>
<p>For online documentation and support please refer to
<a href="https://nginx.org/">nginx.org</a>.<br/>
To engage with the community please visit
<a href="https://community.nginx.org/">community.nginx.org</a>.<br/>
For enterprise grade support, professional services, additional
security features and capabilities please refer to
<a href="https://f5.com/nginx">f5.com/nginx</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@docker-node1 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:87:10:6a brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 192.168.170.10/24 brd 192.168.170.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe87:106a/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether b6:3e:cf:75:4c:c4 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::b43e:cfff:fe75:4cc4/64 scope link
valid_lft forever preferred_lft forever
4: vethcb13646@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 8e:76:ae:0a:1f:f8 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::8c76:aeff:fe0a:1ff8/64 scope link
valid_lft forever preferred_lft forever
[root@docker-node1 ~]# docker rm -f web
web
[root@docker-node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b531d3a8fe10 busybox-file:latest "sh" 11 hours ago Exited (255) 6 minutes ago test
[root@docker-node1 ~]# docker rm -f test
test
[root@docker-node1 ~]# docker run -d --name test -p 80:80 nginx:latest
bc92a53c1f61cf4916fa6dea00bf8dd2baf2b0454f2a0cefa24407e19ef0c7d1

外部访问 :必须通过 -p 参数映射宿主机端口,才能让外部网络访问容器服务。
bash
[root@docker-node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bc92a53c1f61 nginx:latest "/docker-entrypoint...." 2 minutes ago Up 2 minutes 0.0.0.0:80->80/tcp, [::]:80->80/tcp test
[root@docker-node1 ~]# docker images
i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
busybox-file:latest 01f73887b4ee 6.71MB 2.21MB
busybox:latest b3255e7dfbcd 6.7MB 2.22MB
nginx:latest dec7a90bd097 237MB 65.8MB U
timinglee/game2048:latest 8a34fb9cb168 77.2MB 17.8MB
timinglee/mario:latest 7758988210df 298MB 73.7MB
#冲突处理:端口冲突和容器名冲突是 Docker 常见问题,需通过 docker rm -f 强制清理残留资源
[root@docker-node1 ~]# docker rm -f test
test
[root@docker-node1 ~]# docker run -d --name mario -p 80:8080 timinglee/mario:latest
8db6250ff93212bfc10ac1e9f765afdc53b802836700c23cdc938e66a55f2112
[root@docker-node1 ~]# docker history timinglee/mario:latest
IMAGE CREATED CREATED BY SIZE COMMENT
7758988210df 10 years ago /bin/sh -c #(nop) CMD ["python3" "-m" "http.... 0B
<missing> 10 years ago /bin/sh -c #(nop) EXPOSE 8080/tcp #由此可知是8080端口 0B
<missing> 10 years ago /bin/sh -c #(nop) WORKDIR /app 0B
<missing> 10 years ago /bin/sh -c #(nop) COPY dir:02930d36f63824e72... 10.1MB
<missing> 10 years ago /bin/sh -c apt-get install -y python3 0B
<missing> 10 years ago /bin/sh -c #(nop) MAINTAINER Pavel 'PK' Kami... 0B
<missing> 10 years ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 10 years ago /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$... 4.1kB
<missing> 10 years ago /bin/sh -c echo '#!/bin/sh' > /usr/sbin/poli... 229kB
<missing> 10 years ago /bin/sh -c #(nop) ADD file:5a3f9e9ab88e725d6... 214MB

总结:Docker 容器网络访问的核心是端口映射 ,而资源冲突的本质是端口与容器名的全局唯一性。
四、容器镜像构建
Docker 镜像采用分层、只读、联合挂载 的结构,核心是镜像层(Layer)+ 配置元数据。
- 分层结构(UnionFS)
-
镜像由多个只读层(Read-only Layer)叠加而成
-
每层对应 Dockerfile 中的一条指令(
FROM/RUN/COPY等) -
层与层之间复用、共享,相同层只存储一份,节省空间与传输带宽
- 层的顺序
底层 → 上层:基础OS层 → 运行时层 → 应用依赖层 → 应用层 → 配置层
- 关键特性
-
只读:镜像本身所有层均不可写
-
写时复制(CoW):容器启动时在最上层加一个可写容器层,修改仅作用于该层
-
哈希唯一:每层用内容哈希标识,保证跨环境一致性
- 组成部分
-
Layer 数据:实际文件系统内容
-
Manifest:描述文件,记录层顺序、哈希、配置信息
-
Config:镜像元数据(环境变量、启动命令、暴露端口等)
一句话概括:
Docker 镜像 = 堆叠的只读分层文件系统 + 元数据,层复用、哈希唯一,容器基于镜像添加可写层运行。
熟悉镜像构建是用到的参数
bash
#建立构建目录
[root@docker-node1 ~]# mkdir docker
[root@docker-node1 ~]# cd docker/
#编写构建规则文件
[root@docker-node1 docker]# vim Dockerfile
#FROM
FROM busybox:latest
#COPY
[root@docker-node1 docker]# echo timinglee > timinglee
[root@docker-node1 docker]# cat timinglee
timinglee
[root@docker-node1 docker]# vim Dockerfile
FROM busybox:latest
COPY timinglee /root
#构建命令
[root@docker-node1 docker]# docker build -t timinglee:v1 .
[+] Building 0.2s (7/7) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 78B 0.0s
=> [internal] load metadata for docker.io/library/busybox:latest 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 46B 0.0s
=> [1/2] FROM docker.io/library/busybox:latest@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac9 0.0s
=> => resolve docker.io/library/busybox:latest@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac9 0.0s
=> [2/2] COPY timinglee /root 0.0s
=> exporting to image 0.1s
=> => exporting layers 0.0s
=> => exporting manifest sha256:3e240075ea92a386ccc7b8249faf4fbc049465ac3e490ddb9c0b6c759a35a2be 0.0s
=> => exporting config sha256:16a6f0015605d0df6a11f1c609afba2c28bdf3d984305922b440e52cd76f9dc2 0.0s
=> => exporting attestation manifest sha256:74b85b3b7cbdaa72964271d4d7c0fc371c7e267bbf6070df2628f 0.0s
=> => exporting manifest list sha256:0a7e32bc130bf9dbfc457442d8bc653987c1a642f86858f6bc233dc120d6 0.0s
=> => naming to docker.io/library/timinglee:v1 0.0s
=> => unpacking to docker.io/library/timinglee:v1
[root@docker-node1 docker]# docker images
i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
busybox:latest b3255e7dfbcd 6.7MB 2.22MB U
nginx:latest dec7a90bd097 237MB 65.8MB
timinglee/game2048:latest 8a34fb9cb168 77.2MB 17.8MB
timinglee/mario:latest 7758988210df 298MB 73.7MB
timinglee:v1 b3942daf067c 6.71MB 2.21MB
[root@docker-node1 docker]# docker rm -f busybox
busybox
[root@docker-node1 docker]# docker history timinglee:v1
IMAGE CREATED CREATED BY SIZE COMMENT
b3942daf067c 2 minutes ago COPY timinglee /root # buildkit 4.1kB buildkit.dockerfile.v0
<missing> 17 months ago BusyBox 1.37.0 (glibc), Debian 13 4.49MB

五 、构建centos可用仓库
bash
[root@docker-node1 docker]# vim Dockerfile
FROM centos:7
LABEL Creater=lee
RUN ["/bin/bash","-c","rm -fr /etc/yum.repos.d/*"]
COPY centos7.repo /etc/yum.repos.d/centos7.repo
[root@docker-node1 docker]# vim centos7.repo
[centos7]
name = centos7
baseurl = https://mirrors.aliyun.com/centos-vault/7.9.2009/os/x86_64/
gpgcheck = 0
[root@docker-node1 docker]# docker build -t centos-7:repo .
[+] Building 2.2s (8/8) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 170B 0.0s
=> [internal] load metadata for docker.io/library/centos:7 0.9s
=> [internal] load .dockerignore 0.1s
=> => transferring context: 2B 0.1s
=> [1/3] FROM docker.io/library/centos:7@sha256:be65f488b7764ad3638f236b7b515b36 0.1s
=> => resolve docker.io/library/centos:7@sha256:be65f488b7764ad3638f236b7b515b36 0.1s
=> [internal] load build context 0.0s
=> => transferring context: 33B 0.0s
=> CACHED [2/3] RUN ["/bin/bash","-c","rm -fr /etc/yum.repos.d/*"] 0.0s
=> [3/3] COPY centos7.repo /etc/yum.repos.d/centos7.repo 0.1s
=> exporting to image 0.6s
=> => exporting layers 0.2s
=> => exporting manifest sha256:b611ff8c7a2875902ab74b0544ba699bd7de7d8491612444 0.0s
=> => exporting config sha256:5efdefe691b412244cf8642fca370d167092c428383d5b45cb 0.0s
=> => exporting attestation manifest sha256:4ed081d90a00d19b8a08dc2c256c56060316 0.1s
=> => exporting manifest list sha256:5bd80adf8be9cb8faccb173dde288197ce695d61d66 0.0s
=> => naming to docker.io/library/centos-7:repo 0.0s
=> => unpacking to docker.io/library/centos-7:repo 0.1s
[root@docker-node1 docker]# docker run -it --rm --name centos centos-7:repo /bin/bash
[root@1be965c87d6a /]# yum install gcc -y
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
centos7 | 3.6 kB 00:00:00
(1/2): centos7/group_gz | 153 kB 00:00:01
(2/2): centos7/primary_db | 6.1 MB 00:00:09
Resolving Dependencies
--> Running transaction check
......
Complete!
[root@docker-node1 docker]# docker save -o centos7.tar centos:7
[root@docker-node1 docker]# docker rmi centos:7
Untagged: centos:7
Deleted: sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4
[root@docker-node1 docker]# docker images
i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
busybox:latest b3255e7dfbcd 6.7MB 2.22MB
centos-7:repo 5bd80adf8be9 299MB 76.1MB
nginx:latest dec7a90bd097 237MB 65.8MB
timinglee/game2048:latest 8a34fb9cb168 77.2MB 17.8MB
timinglee/mario:latest 7758988210df 298MB 73.7MB
[root@docker-node1 docker]# docker load -i centos7.tar
Loaded image: centos:7
[root@docker-node1 docker]# docker images
i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
busybox:latest b3255e7dfbcd 6.7MB 2.22MB
centos-7:repo 5bd80adf8be9 299MB 76.1MB
centos:7 be65f488b776 299MB 76.1MB
nginx:latest dec7a90bd097 237MB 65.8MB
timinglee/game2048:latest 8a34fb9cb168 77.2MB 17.8MB
timinglee/mario:latest 7758988210df 298MB 73.7MB
六、镜像构建的优化方案
方法1.缩减镜像层
[root@server1 docker]# vim Dockerfile
FROM centos:7 AS build
ADD nginx-1.23.3.tar.gz /mnt
WORKDIR /mnt/nginx-1.23.3
RUN yum install -y gcc make pcre-devel openssl-devel && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --with-http_ssl_module --with-http_stub_status_module && make && make install && cd .. && rm -fr nginx-1.23.3 && yum clean all
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t webserver:v1 .
[root@server1 docker]# docker build -t webserver:v2 .
[root@server1 docker]# docker images webserver
REPOSITORY TAG IMAGE ID CREATED SIZE
webserver v2 caf0f80f2332 4 seconds ago 317MB
webserver v1 bfd6774cc216 About an hour ago 494MB
方法2.多阶段构建
[root@server1 docker]# vim Dockerfile
FROM centos:7 AS build
ADD nginx-1.23.3.tar.gz /mnt
WORKDIR /mnt/nginx-1.23.3
RUN yum install -y gcc make pcre-devel openssl-devel && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --with-http_ssl_module --with-http_stub_status_module && make && make install && cd .. && rm -fr nginx-1.23.3 && yum clean all
FROM centos:7
COPY --from=build /usr/local/nginx /usr/local/nginx
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t webserver:v3 .
[root@server1 docker]# docker images webserver
REPOSITORY TAG IMAGE ID CREATED SIZE
webserver v3 1ac964f2cefe 29 seconds ago 205MB
webserver v2 caf0f80f2332 3 minutes ago 317MB
webserver v1 bfd6774cc216 About an hour ago 494MB
方法3.使用最精简镜像
使用google提供的最精简镜像
下载地址:
https://github.com/GoogleContainerTools/distroless
下载镜像:docker pull gcr.io/distroless/base
利用最精简镜像构建
[root@server1 ~]# mkdir new
[root@server1 ~]# cd new/
[root@server1 new]# vim Dockerfile
FROM nginx:1.23 AS base
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
ARG TIME_ZONE
RUN mkdir -p /opt/var/cache/nginx && \
cp -a --parents /usr/lib/nginx /opt && \
cp -a --parents /usr/share/nginx /opt && \
cp -a --parents /var/log/nginx /opt && \
cp -aL --parents /var/run /opt && \
cp -a --parents /etc/nginx /opt && \
cp -a --parents /etc/passwd /opt && \
cp -a --parents /etc/group /opt && \
cp -a --parents /usr/sbin/nginx /opt && \
cp -a --parents /usr/sbin/nginx-debug /opt && \
cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libpcre* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \
cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime
FROM gcr.io/distroless/base-debian11
COPY --from=base /opt /
EXPOSE 80 443
ENTRYPOINT ["nginx", "-g", "daemon off;"]
[root@server1 new]# docker build -t webserver:v4 .
[root@docker-node1 docker]# docker run -d --name webserver --rm websever:v4
de3c25e7708bcb46c4a4cc347e6284601250220c427ba17ba8c00f39660fceb5

七、官方仓库使用
[root@docker-node1 ~]# scp /etc/modules-load.d/docker_mod.conf root@192.168.170.20:/etc/modules-load.d/docker_mod.conf
docker_mod.conf 100% 13 19.9KB/s 00:00
[root@docker-node1 ~]# scp /etc/sysctl.d/docker.conf root@192.168.170.20:/etc/sysctl.d/docker.conf
docker.conf
[root@docker-node1 ~]# scp /etc/yum.repos.d/docker.repo root@192.168.170.20:/etc/yum.repos.d/docker.repo
docker.repo
[root@docder-node2 yum.repos.d]# cat /etc/modules-load.d/docker_mod.conf
br_netfilter
[root@docder-node2 yum.repos.d]# modprobe -a br_netfilter
[root@docder-node2 yum.repos.d]# sysctl --system
[root@docker harbor]# docker login reg.timinglee.org
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@docker-node1 ~]# docker tag websever:v4 timinglee/webserver:v4
[root@docker-node1 ~]# docker push timinglee/webserver:v4
The push refers to repository [docker.io/timinglee/webserver]
[root@docder-node2 yum.repos.d]# systemctl enable --now docker
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /usr/lib/systemd/system/docker.service.
[root@docder-node2 ~]# docker search timinglee
[root@docder-node2 ~]# docker pull timinglee/webserver:v4

八、非加密仓库构建
#1.下载Registry镜像
[root@docker-node1 docker]# docker pull registry
[root@docker-node1 docker]# ls
centos7.repo centos7.tar Dockerfile nginx-1.28.2.tar.gz registry.tar timinglee
[root@docker-node1 docker]# docker load -i registry.tar
Loaded image: registry:latest
#2.开启Registry
[root@docker-node1 docker]# docker run -d -p 5000:5000 --restart=always --name registry registry
c65fe776f38d25d802f69e0cff8030826cfd9da815c347b292fc9eefad9c9252
[root@docker-node1 docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c65fe776f38d registry "/entrypoint.sh /etc..." About a minute ago Up About a minute 0.0.0.0:5000->5000/tcp, [::]:5000->5000/tcp registry
#3.上传镜像到仓库中
#docker在上传的过程中默认使用https,但是我们并没有建立https认证需要的认证文件所以会报错
[root@docker-node1 docker]# docker push 192.168.170.10:5000/busybox:latest
The push refers to repository [192.168.170.10:5000/busybox]
Get "https://192.168.170.10:5000/v2/": dial tcp 192.168.170.10:5000: connect: connection refused
#给要上传的经镜像大标签
[root@docker-node1 docker]# docker tag websever:v4 192.168.170.10:5000/webserver:v4
#配置非加密端口,node1和node2都需要
[root@docker-node1 docker]# vim /etc/docker/daemon.json
{
"insecure-registries" : ["http://192.168.170.10:5000"]
}
[root@docker-node1 docker]# systemctl restart docker
#上传镜像
[root@docker-node1 docker]# docker push 192.168.170.10:5000/webserver:v4
The push refers to repository [192.168.170.10:5000/webserver]
bff4d5c5e548: Pushed
af5aa97ebe6c: Pushed
2388d21e8e2b: Pushed
5342a2647e87: Pushed
577c8ee06f39: Pushed
4d049f83d9cf: Pushed
8451c71f8c1e: Pushed
ac805962e479: Pushed
bbb6cacb8c82: Pushed
2a92d6ac9e4f: Pushed
1a73b54f556b: Pushed
24aacbf97031: Pushed
32d43d8d70c9: Pushed
9ed498e122b2: Pushed
c048279a7d9f: Pushed
6835249f577a: Pushed
v4: digest: sha256:f1ec8f6bef49ebe29c3e59d66ffffe9001c16bb4fd4c8643e0691f9f299b8415 size: 856
#查看镜像上传
[root@docker-node1 docker]# curl 192.168.170.10:5000/v2/_catalog
{"repositories":["webserver"]}
node2主机可以通过node1主机的镜像仓库直接下载

九、仓库的加密传输及用户认证
为Registry提加密传输
[root@docker-node1 ~]# docker rm -f registry
registry
[root@docker-node1 ~]# vim /etc/docker/daemon.json #清空,node12都需要完成
[root@docker-node1 ~]# systemctl restart docker
[root@docker-node1 ~]# mkdir /etc/docker/certs
[root@docker-node1 ~]# openssl req -newkey rsa:4096 \
> -nodes -sha256 -keyout /etc/docker/certs/timinglee.org.key \
> -addext "subjectAltName = DNS:reg.timinglee.org" \ #指定备用名称
> -x509 -days 365 -out /etc/docker/certs/timinglee.org.crt
#查看证书信息
[root@docker-node1 ~]# openssl x509 -in /etc/docker/certs/timinglee.org.crt -noout -text
启动registry仓库
[root@docker-node1 ~]# docker run -d -p 443:443 --restart=always --name registry -v /opt/registry:/var/lib/registry -v /etc/docker/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/timinglee.org.crt -e REGISTRY_HTTP_TLS_KEY=/certs/timinglee.org.key registry
8a39d5b47776b442e03ec1b0aec2cc7b7ae271b53634623ab34073089d867b85
[root@docker-node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8a39d5b47776 registry "/entrypoint.sh /etc..." 11 seconds ago Up 11 seconds 0.0.0.0:443->443/tcp, [::]:443->443/tcp, 5000/tcp registry
[root@docker-node1 ~]# ll /opt/registry/
总用量 0
[root@docker-node1 ~]# vim /etc/hosts #node12都需要
192.168.170.20 docder-node2 reg.timinglee.org
测试:
[root@docker docker]# docker push reg.timinglee.org/busybox:latest #docker客户端没有key和证书
Error response from daemon: Get "https://reg.timinglee.org/v2/": tls: failed to verify certificate: x509: certificate signed by unknown authority
[root@docker-node1 ~]# docker tag websever:v4 reg.timinglee.org/webserver:v4
#为客户端建立证书
[root@docker-node1 ~]# mkdir /etc/docker/certs.d/reg.timinglee.org -p
[root@docker-node1 ~]# cp /etc/docker/certs/timinglee.org.crt /etc/docker/certs.d/reg.t
iminglee.org/ca.crt
[root@docker-node1 ~]# systemctl restart docker
[root@docker-node1 ~]# docker push reg.timinglee.org/webserver:v4
The push refers to repository [reg.timinglee.org/webserver]
32d43d8d70c9: Pushed
bbb6cacb8c82: Pushed
2a92d6ac9e4f: Pushed
8451c71f8c1e: Pushed
6835249f577a: Pushed
577c8ee06f39: Pushed
9ed498e122b2: Pushed
4d049f83d9cf: Pushed
c048279a7d9f: Pushed
bff4d5c5e548: Pushed
5342a2647e87: Pushed
af5aa97ebe6c: Pushed
ac805962e479: Pushed
1a73b54f556b: Pushed
2388d21e8e2b: Pushed
24aacbf97031: Pushed
v4: digest: sha256:f1ec8f6bef49ebe29c3e59d66ffffe9001c16bb4fd4c8643e0691f9f299b8415 size: 856
[root@docker-node1 ~]# dnf install httpd-tools -y
[root@docker-node1 ~]# mkdir /etc/docker/auth/
[root@docker-node1 ~]# htpasswd -Bc /etc/docker/auth/htpasswd lee
New password:
Re-type new password:
Adding password for user lee
[root@docker-node1 ~]# docker run -d -p 443:443 --restart=always --name registry \
-v/opt/registry:/var/lib/registry \
-v /root/certs:/certs \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/timinglee.org.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/timinglee.org.key \
> -v /etc/docker/auth:/auth \
> -e "REGISTRY_AUTH=htpasswd" \
> -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
> -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
registry
98973a66a613adad7dc06aaaf91274c7ee7fa283d19a389958a4c96ec55b43f0
[root@docker-node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
98973a66a613 registry "/entrypoint.sh /etc..." 5 seconds ago Restarting (1) 1 second ago registry
登陆测试:
[root@docker ~]# docker login reg.timinglee.org
Username: lee
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
