本文大量参考b站kuangshen的Docker视频

Docker的常用命令

帮助命令

1
2
3
docker version     # 显示docker的版本信息
docker info # 显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help # 帮助命令

帮助文档的地址:https://docs.docker.com/engine/reference/commandline/build/

镜像命令

docker images

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@localhost /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 5 months ago 13.3kB

#解释
REPOSITORY 镜像的仓库源
TAG 镜像标签
IMAGE ID 镜像id
CREATED 镜像的创建时间
SIZE 镜像的大小

#可选项
Options:
-a, --all # 列出所有镜像
-q, --quiet # 只显示镜像id

docker search 搜索镜像

1
2
3
4
5
6
7
8
9
10
11
[root@localhost /]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 9604 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3490 [OK]

#可选项,通过收藏来过滤
--filter=STARS=3000 #搜索出来的镜像就是STARS大于3000的
[root@localhost /]# docker search mysql --filter=STARS=3000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 9604 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3490 [OK]

docker pull 下载镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 下载镜像 docker pull 镜像名[:tag]
[root@localhost /]# docker pull mysql
Using default tag: latest # 如果不写 tag,默认就是latest
latest: Pulling from library/mysql
8559a31e96f4: Pull complete # 分层下载,docker image的核心 联合文件系统
d51ce1c2e575: Pull complete
c2344adc4858: Pull complete
fcf3ceff18fc: Pull complete
16da0c38dc5b: Pull complete
b905d1797e97: Pull complete
4b50d1c6b05c: Pull complete
c75914a65ca2: Pull complete
1ae8042bdd09: Pull complete
453ac13c00a3: Pull complete
9e680cd72f08: Pull complete
a6b5dc864b6c: Pull complete
Digest: sha256:8b7b328a7ff6de46ef96bcf83af048cb00a1c86282bfca0cb119c84568b4caf6 # 签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址

docker pull mysql 等价于: docker pull docker.io/library/mysql:latest

# 指定版本下载
[root@localhost /]# docker pull mysql:5.7
5.7: Pulling from library/mysql
8559a31e96f4: Already exists # 联合文件系统的好处:上面下载过的MySQL与5.7版本的MySQL有相同的文件时不需要重复下载
d51ce1c2e575: Already exists
c2344adc4858: Already exists
fcf3ceff18fc: Already exists
16da0c38dc5b: Already exists
b905d1797e97: Already exists
4b50d1c6b05c: Already exists
d85174a87144: Pull complete
a4ad33703fa8: Pull complete
f7a5433ce20d: Pull complete
3dcd2a278b4a: Pull complete
Digest: sha256:32f9d9a069f7a735e28fd44ea944d53c61f990ba71460c5c183e610854ca4854
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O5oXLHZ6-1607516885224)(Docker%E6%A6%82%E8%BF%B0(1)].assets%5Cimage-20200610165130055.png)

docker rmi 删除镜像

rm——remove i——images

1
2
3
[root@localhost /]# docker rmi -f 镜像id  				 #删除指定镜像
[root@localhost /]# docker rmi -f 镜像id 镜像id 镜像id #删除多个镜像
[root@localhost /]# docker rmi -f $(docker images -aq) #删除全部镜像

容器命令

说明:有了镜像才可以创建容器,linux,下载一个centos镜像来学习

1
docker pull centos

新建容器并启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
docker run [可选参数] image

# 参数说明
--name="Name" 容器名字 tomcat01 tomcat02 ,用来区分容器
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器的端口 -p 8080:80
-p ip:主机(即宿主机)端口:容器端口
-p 主机端口:容器端口 #这种方式常用
-p 容器端口
容器端口P
-P 随机指定端口(大写P)

# 测试,启动并进入容器
[root@localhost /]# docker run -it centos /bin/bash
[root@8b4c74381205 /]# ls #查看容器内的centos,基础版本,很多命令都是不完善的!
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr

# 从容器中退回主机
[root@8b4c74381205 /]# exit
exit
[root@localhost /]# ls
123 bin dev home lib64 mnt proc run srv tmp var
222 boot etc lib media opt root sbin sys usr

列出所有运行的容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# docker ps 命令
(不加) # 列出当前正在运行的容器
-a # 列出当前正在运行的容器 + 带出历史运行过的容器
-n=? # 显示最近创建的容器
-q # 只显示当前容器的编号
[root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8b4c74381205 centos "/bin/bash" 4 minutes ago Exited (0) About a minute ago epic_wilson
fb87667bbc19 bf756fb1ae65 "/hello" 2 hours ago Exited (0) 2 hours ago awesome_banach
[root@localhost /]# docker ps -a -n=1
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8b4c74381205 centos "/bin/bash" 9 minutes ago Exited (0) 6 minutes ago epic_wilson
[root@localhost /]# docker ps -aq
8b4c74381205
fb87667bbc19

退出容器

1
2
exit   # 直接退出容器
Ctrl + p + q # 容器不停止退出

删除容器

1
2
3
docker rm 容器id				   # 删除指定容器,不能删除正在运行的容器,如果要强制删除 rm -f
docker rm -f $(docker ps -aq) # 删除所有容器
docker ps -a -q|xargs docker rm # 删除所有容器

启动和停止容器的操作

1
2
3
4
docker start 容器id     # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前正在运行的容器

常用其他命令

后台启动容器

1
2
3
4
5
6
7
8
9
10
11
# 命令 docker run -d 镜像名

[root@localhost /]# docker run -d centos
e9d60f206fa19963203db6c42c2f83c5120eb90eeee2b7ba9fdc4589370fd6b6
[root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

# 问题docker ps,发现 centos 停止了

# 常见的坑,docker 容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
# nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了

查看日志

1
2
3
4
5
6
docker logs -f -t --tail 数字 容器id

# 显示日志
-tf # 显示日志
--tail # 要显示的日志条数
[root@localhost /]# docker logs -tf --tail 10 ce989f90023d

查看容器中进程信息

1
2
3
4
# 命令 docker top 容器id
[root@localhost /]# docker top ce989f90023d
UID PID PPID C STIME TTY TIME
root 12249 12232 0 22:44 pts/0 00:00:00

查看镜像的元数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# 命令
docker inspect 容器id

# 测试
[root@localhost /]# docker inspect ce989f90023d
[
{
"Id": "ce989f90023dedc0b3f39c057b91f5c0b17180b3aef7aea0df8c93731e724244",
"Created": "2020-06-10T14:44:45.025360147Z",
"Path": "/bin/bash",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 12249,
"ExitCode": 0,
"Error": "",
"StartedAt": "2020-06-10T14:44:45.770227584Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:470671670cac686c7cf0081e0b37da2e9f4f768ddc5f6a26102ccd1c6954c1ee",
"ResolvConfPath": "/var/lib/docker/containers/ce989f90023dedc0b3f39c057b91f5c0b17180b3aef7aea0df8c93731e724244/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/ce989f90023dedc0b3f39c057b91f5c0b17180b3aef7aea0df8c93731e724244/hostname",
"HostsPath": "/var/lib/docker/containers/ce989f90023dedc0b3f39c057b91f5c0b17180b3aef7aea0df8c93731e724244/hosts",
"LogPath": "/var/lib/docker/containers/ce989f90023dedc0b3f39c057b91f5c0b17180b3aef7aea0df8c93731e724244/ce989f90023dedc0b3f39c057b91f5c0b17180b3aef7aea0df8c93731e724244-json.log",
"Name": "/nifty_johnson",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Capabilities": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/bce8b2400427de29dd406d54ec08b3c07dc95530e80d37977a156ca971b37641-init/diff:/var/lib/docker/overlay2/d4cd3bedb1e7340e62bb292c1e0d5ae37b1d1689ffc1640da67b2a8325facc21/diff",
"MergedDir": "/var/lib/docker/overlay2/bce8b2400427de29dd406d54ec08b3c07dc95530e80d37977a156ca971b37641/merged",
"UpperDir": "/var/lib/docker/overlay2/bce8b2400427de29dd406d54ec08b3c07dc95530e80d37977a156ca971b37641/diff",
"WorkDir": "/var/lib/docker/overlay2/bce8b2400427de29dd406d54ec08b3c07dc95530e80d37977a156ca971b37641/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "ce989f90023d",
"Domainname": "",
"User": "",
"AttachStdin": true,
"AttachStdout": true,
"AttachStderr": true,
"Tty": true,
"OpenStdin": true,
"StdinOnce": true,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash"
],
"Image": "centos",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.label-schema.build-date": "20200114",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS",
"org.opencontainers.image.created": "2020-01-14 00:00:00-08:00",
"org.opencontainers.image.licenses": "GPL-2.0-only",
"org.opencontainers.image.title": "CentOS Base Image",
"org.opencontainers.image.vendor": "CentOS"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "74d140bbc60432c5fdce865fa48f78c1138923dd292e708a25c4de17de812d56",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/74d140bbc604",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "3580dd1064b07f434c61e316f14cb7d7b53a3d6d7c9c0f77eb6570f1781623bc",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "58fd9703e96d12128c30f244be3205e3fe31fc7d1fb7fffdddba72d981e782f4",
"EndpointID": "3580dd1064b07f434c61e316f14cb7d7b53a3d6d7c9c0f77eb6570f1781623bc",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03",
"DriverOpts": null
}
}
}
}
]

进入当前正在运行的容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置

# 命令
docker exec -it 容器id bashShell

# 测试
[root@localhost /]# docker exec -it ce989f90023d /bin/bash
[root@ce989f90023d /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@ce989f90023d /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 14:44 pts/0 00:00:00 /bin/bash
root 15 0 0 15:19 pts/1 00:00:00 /bin/bash
root 29 15 0 15:20 pts/1 00:00:00 ps -ef

# 方式二
docker attach 容器id
# 测试
[root@localhost /]# docker attach ce989f90023d
正在执行当前的代码...

# docker exec # 进入容器后开启一个新的终端,可以在里面操作(常用)
# docker attach # 进入容器正在执行的终端,不会启动新的进程(进入的是正在运行的命令行,而不是新的窗口)

从容器内拷贝文件到主机上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
docker cp 容器id:容器内目标文件路径  目的主机路径

# 查看当前主机目录
[root@localhost home]# ls
ztx

# 进入docker容器内部
[root@localhost home]# docker attach ce989f90023d
[root@ce989f90023d /]# cd /home/
[root@ce989f90023d home]# ls

# 在容器内新建一个文件
[root@ce989f90023d home]# touch test.java
[root@ce989f90023d home]# exit
exit
[root@localhost home]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ce989f90023d centos "/bin/bash" 44 minutes ago Exited (0) 46 seconds ago nifty_johnson

# 将docker内文件拷贝到主机上
[root@localhost home]# docker cp ce989f90023d:/home/test.java /home
[root@localhost home]# ls
test.java ztx
[root@localhost home]#

# 拷贝是一个手动过程,未来我们使用 -v 卷的技术,可以实现自动同步

小结

在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
attach      Attach to a running container 	      # 当前shell下attach连接指定运行的镜像
build Build an image from a Dockerfile # 通过Dockerfile定制镜像
commit Create a new image from a container changes #提交当前容器为新的镜像
cp Copy files/folders between a container and the local filesystem #从容器中拷贝指定文件或目录到宿主机中
create Create a new container # 创建一个新的容器,同run,但不启动容器
diff Inspect changes to files or directories on a container's filesystem #查看docker容器的变化
events Get real time events from the server # 从docker服务获取容器实时事件
exec Run a command in a running container # 在已存在的容器上运行命令
export Export a container filesystem as a tar archive # 导出容器的内容流作为一个tar归档文件[对应import]
history Show the history of an image # 展示一个镜像形成历史
images List images # 列出系统当前的镜像
import Import the contents from a tarball to create a filesystem image # 从tar包中的内容创建一个新的文件系统镜像[对应export]
info Display system-wide information # 显示系统相关信息
inspect Return low-level information on Docker objects # 查看容器详细信息
kill Kill one or more running containers # 杀死指定的docker容器
load Load an image from a tar archive or STDIN # 从一个tar包加载一个镜像[对应save]
login Log in to a Docker registry # 注册或者登录一个docker源服务器
logout Log out from a Docker registry # 从当前Docker registry退出
logs Fetch the logs of a container # 输出当前容器日志信息
pause Pause all processes within one or more containers # 暂停容器
port List port mappings or a specific mapping for the container # 查看映射端口对应容器内部源端口
ps List containers # 列出容器列表
pull Pull an image or a repository from a registry # 从docker镜像源服务器拉取指定镜像或库镜像
push Push an image or a repository to a registry # 推送指定镜像或者库镜像至docker源服务器
rename Rename a container # 给docker容器重新命名
restart Restart one or more containers # 重启运行的容器
rm Remove one or more containers # 移除一个或者多个容器
rmi Remove one or more images # 移除一个或者多个镜像[无容器使用该镜像时才可删除,否则需删除相关容器才可继续或 -f 强制删除]
run Run a command in a new container # 创建一个新的容器并运行一个命令
save Save one or more images to a tar archive (streamed to STDOUT by default) # 保存一个镜像为一个tar包[对应load]
search Search the Docker Hub for images # 在docker hub中搜索镜像
start Start one or more stopped containers # 启动容器
stats Display a live stream of container(s) resource usage statistics # 实时显示容器资源使用统计
stop Stop one or more running containers # 停止容器
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE # 给源中镜像打标签
top Display the running processes of a container # 查看容器中运行的进程信息
unpause Unpause all processes within one or more containers # 取消暂停容器
update Update configuration of one or more containers # 更新一个或多个容器配置
version Show the Docker version information # 查看docker版本号
wait Block until one or more containers stop, then print their exit codes # 截取容器停止时的退出状态值

Docker镜像讲解

镜像是什么

镜像是一种轻量级、可执行的独立软件保,用来打包软件运行环境和基于运行环境开发的软件,他包含运行某个软件所需的所有内容,包括代码、运行时库、环境变量和配置文件。

所有应用,直接打包docker镜像,就可以直接跑起来!

如何得到镜像

  • 从远程仓库下载
  • 别人拷贝给你
  • 自己制作一个镜像 DockerFile

Docker镜像加载原理

UnionFs (联合文件系统)

UnionFs(联合文件系统):Union文件系统(UnionFs)是一种分层、轻量级并且高性能的文件系统,他支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下( unite several directories into a single virtual filesystem)。Union文件系统是 Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

Docker镜像加载原理

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。

boots(boot file system)主要包含 bootloader和 Kernel, bootloader主要是引导加载 kernel, Linux刚启动时会加载bootfs文件系统,在 Docker镜像的最底层是 boots。这一层与我们典型的Linux/Unix系统是一样的,包括bootloader和 Kernel。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs转交给内核,此时系统也会卸载bootfs。

rootfs(root file system),在 bootfs之上。包含的就是典型 Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。 rootfs就是各种不同的操作系统发行版,比如 Ubuntu, Centos等等。
在这里插入图片描述
平时我们安装进虚拟机的CentOS都是好几个G,为什么Docker这里才200M?
在这里插入图片描述
对于个精简的OS, rootfs可以很小,只需要包合最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的Linux发行版, boots基本是一致的, rootfs会有差別,因此不同的发行版可以公用bootfs.

虚拟机是分钟级别,容器是秒级!

分层理解

分层的镜像

我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层层的在下载!
在这里插入图片描述
思考:为什么Docker镜像要采用这种分层的结构呢?

最大的好处,我觉得莫过于资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。

查看镜像分层的方式可以通过docker image inspect 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
➜  / docker image inspect redis          
[
{
"Id": "sha256:f9b9909726890b00d2098081642edf32e5211b7ab53563929a47f250bcdc1d7c",
"RepoTags": [
"redis:latest"
],
"RepoDigests": [
"redis@sha256:399a9b17b8522e24fbe2fd3b42474d4bb668d3994153c4b5d38c3dafd5903e32"
],
"Parent": "",
"Comment": "",
"Created": "2020-05-02T01:40:19.112130797Z",
"Container": "d30c0bcea88561bc5139821227d2199bb027eeba9083f90c701891b4affce3bc",
"ContainerConfig": {
"Hostname": "d30c0bcea885",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"6379/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GOSU_VERSION=1.12",
"REDIS_VERSION=6.0.1",
"REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.0.1.tar.gz",
"REDIS_DOWNLOAD_SHA=b8756e430479edc162ba9c44dc89ac394316cd482f2dc6b91bcd5fe12593f273"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"redis-server\"]"
],
"ArgsEscaped": true,
"Image": "sha256:704c602fa36f41a6d2d08e49bd2319ccd6915418f545c838416318b3c29811e0",
"Volumes": {
"/data": {}
},
"WorkingDir": "/data",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {}
},
"DockerVersion": "18.09.7",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"6379/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GOSU_VERSION=1.12",
"REDIS_VERSION=6.0.1",
"REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.0.1.tar.gz",
"REDIS_DOWNLOAD_SHA=b8756e430479edc162ba9c44dc89ac394316cd482f2dc6b91bcd5fe12593f273"
],
"Cmd": [
"redis-server"
],
"ArgsEscaped": true,
"Image": "sha256:704c602fa36f41a6d2d08e49bd2319ccd6915418f545c838416318b3c29811e0",
"Volumes": {
"/data": {}
},
"WorkingDir": "/data",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": null
},
"Architecture": "amd64",
"Os": "linux",
"Size": 104101893,
"VirtualSize": 104101893,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/adea96bbe6518657dc2d4c6331a807eea70567144abda686588ef6c3bb0d778a/diff:/var/lib/docker/overlay2/66abd822d34dc6446e6bebe73721dfd1dc497c2c8063c43ffb8cf8140e2caeb6/diff:/var/lib/docker/overlay2/d19d24fb6a24801c5fa639c1d979d19f3f17196b3c6dde96d3b69cd2ad07ba8a/diff:/var/lib/docker/overlay2/a1e95aae5e09ca6df4f71b542c86c677b884f5280c1d3e3a1111b13644b221f9/diff:/var/lib/docker/overlay2/cd90f7a9cd0227c1db29ea992e889e4e6af057d9ab2835dd18a67a019c18bab4/diff",
"MergedDir": "/var/lib/docker/overlay2/afa1de233453b60686a3847854624ef191d7bc317fb01e015b4f06671139fb11/merged",
"UpperDir": "/var/lib/docker/overlay2/afa1de233453b60686a3847854624ef191d7bc317fb01e015b4f06671139fb11/diff",
"WorkDir": "/var/lib/docker/overlay2/afa1de233453b60686a3847854624ef191d7bc317fb01e015b4f06671139fb11/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:c2adabaecedbda0af72b153c6499a0555f3a769d52370469d8f6bd6328af9b13",
"sha256:744315296a49be711c312dfa1b3a80516116f78c437367ff0bc678da1123e990",
"sha256:379ef5d5cb402a5538413d7285b21aa58a560882d15f1f553f7868dc4b66afa8",
"sha256:d00fd460effb7b066760f97447c071492d471c5176d05b8af1751806a1f905f8",
"sha256:4d0c196331523cfed7bf5bafd616ecb3855256838d850b6f3d5fba911f6c4123",
"sha256:98b4a6242af2536383425ba2d6de033a510e049d9ca07ff501b95052da76e894"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]

理解:

所有的 Docker镜像都起始于一个基础镜像层,当进行修改或培加新的内容时,就会在当前镜像层之上,创建新的镜像层。

举一个简单的例子,假如基于 Ubuntu Linux16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。

该镜像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。
在这里插入图片描述
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而整体的大镜像包含了来自两个镜像层的6个文件。
在这里插入图片描述
上图中的镜像层跟之前图中的略有区別,主要目的是便于展示文件。

下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版。
在这里插入图片描述

这种情況下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。

Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。

Linux上可用的存储引撃有AUFS、 Overlay2、 Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于 Linux中对应的文件系统或者块设备技术,井且每种存储引擎都有其独有的性能特点。

Docker在 Windows上仅支持 windowsfilter 一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW [1]。

特点

Docker 镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部!

这一层就是我们通常说的容器层,容器之下的都叫镜像层!
在这里插入图片描述
如何提交一个自己的镜像?

commit镜像

1
2
3
4
docker commit 提交容器成为一个新的副本

# 命令和git原理类似
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[版本TAG]

实战测试

1
2
3
4
5
6
7
#1、启动一个默认的tomcat

#2、发现这个默认的tomcat是没有webapps应用的,镜像的原因。官方的镜像默认webapps下面是没有文件的!

#3、我自己将webapp.dist下文件拷贝至webapps下

#4、将我们操作过的容器通过commit提交为一个镜像!我们以后就可以使用我们修改过的镜像了,这就是我们自己的一个修改的镜像

在这里插入图片描述
如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们我们使用虚拟机的快照。
到了这里就算是入门Docker了!

容器数据卷

什么是容器数据卷

docker的理念回顾

将应用和环境打包成一个镜像!

数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!==需求:数据可以持久化==

MySQL,容器删除了,删库跑路!==需求:MySQL数据可以存储在本地!==

容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!

这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!
在这里插入图片描述
总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!

使用数据卷

方式一:直接使用命令来挂载

1
2
3
4
5
6
docker run -it -v 主机目录:容器目录

# 测试
[root@localhost home]# docker run -it -v /home/ceshi:/home centos /bin/bash

# 启动起来的时候,我们可以通过docker inspect 容器id 来查看挂载情况:(见下图)

在这里插入图片描述
在容器内指定目录下添加或修改一个文件,会同步到主机指定目录下!反之,在主机目录下做相关操作,也会同步到容器对应的目录下!

再来测试!

1、停止容器

2、宿主机修改文件

3、启动容器

4、容器内的数据依旧是同步的!

好处:我们以后修改只需要在本地修改即可,容器内会自动同步!

两个路径保持完全的同步!!!双向绑定,一边发生变化,另一边也会随之变化!

具名和匿名挂载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx


# 查看所有卷的情况
[root@localhost data]# docker volume ls
DRIVER VOLUME NAME
local 2dd0379216c9ee4441ed56f8ce53461c19abe78b8cfd024ac5fbe07c3b8f09ba

# 这里发现,这种就是匿名挂载,我们在 -v 后只写了容器内的路径,没有写容器外的路径!

# 具名挂载
[root@localhost home]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
5ba5708389bf71b2156fdbcedc50a62b16ac27adb2a3dfac42c52e9da5ace79f
[root@localhost home]# docker volume ls
DRIVER VOLUME NAME
local juming-nginx

# 通过 -v 卷名:容器内路径
# 查看一下这个卷 # 先找到卷所在路径 docker volume inspect 卷名,如下图:

在这里插入图片描述
所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxxx/_data下!
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况使用 具名挂载

1
2
3
4
# 如何确定是具名挂载还是匿名挂载,还是指定路径挂载!
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载!

拓展:

1
2
3
4
5
6
7
8
9
10
# 通过 -v 容器内路径:ro 或 rw   改变读写权限
ro #readonly 只读
rw #readwrite 可读可写

# 一旦创建容器时设置了容器权限,容器对我们挂载出来的内容就有限定了!
docker run -d -P --name nginx05 -v juming:/etc/nginx:ro nginx
docker run -d -P --name nginx05 -v juming:/etc/nginx:rw nginx

# 默认是 rw
# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!

初始Dockerfile

Dockerfile 就是用来构建 docker镜像的构建文件!命令脚本! 先体验一下!

通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个个的命令,每个命令都是最终镜像的一层!

1
2
3
4
5
6
7
8
9
10
11
12
13
# 创建一个dockerfile文件,名字可以随机,建议 dockerfile

[root@localhost docker-test-volume]# vim dockerfile
# 文件中的内容:指令(大写) 参数
FROM centos

VOLUME ["volume01","volume02"]

CMD echo"----end----"

CMD /bin/bash

# 这里的每个命令,就是镜像的一层!

在这里插入图片描述
注意:我们这里的 dockerfile 是我们编写的文件名哦!
在这里插入图片描述
这两个卷和外部一定有两个同步的目录!
在这里插入图片描述
查看一下卷挂载在主机上的路径

docker inspect 容器id
在这里插入图片描述
测试一下刚才的文件是否同步出去了!

这种方式我们未来使用十分的多,因为我们通常会构建自己的镜像!

假设构建镜像的时候没有挂在卷,要手动镜像挂载即可: (参考上文==具名和匿名挂载==)

1
-v 卷名:容器内路径

数据卷容器(多个容器之间同步数据 )

多个mysql同步数据!
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在docker03下创建docker03文件后,进入docker01发现也依旧会同步过来:
在这里插入图片描述

1
2
3
4
5
# 测试1:删除docker01后,docker02和docker03是否还可以访问原来docker01下创建的的文件?
# 测试1的结果为:依旧可以访问!!!

# 测试2:删除docker01后,docker02和docker03之间是否可以相互同步文件?
# 测试2的结果为:docket02和docker03之间一九可以完成同步!!! 见下图:

在这里插入图片描述
在这里插入图片描述
多个mysql实现数据共享

1
2
3
➜  ~ docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
➜ ~ docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
# 这个时候,可以实现两个容器数据同步!

结论:

容器之间的配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。

但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!

DockerFile

DockerFile介绍

dockerfile是用来构建docker镜像的文件!命令参数脚本!

构建步骤:

1、 编写一个dockerfile文件

2、 docker build 构建称为一个镜像

3、 docker run运行镜像

4、 docker push发布镜像(DockerHub 、阿里云仓库)

查看官方是怎么做的!

DockerFile构建过程

基础知识:

1、每个保留关键字(指令)都是必须是大写字母

2、执行从上到下顺序

3、# 表示注释

4、每一个指令都会创建提交一个新的镜像层,并提交!
在这里插入图片描述
Dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!

Docker镜像逐渐成企业交付的标准,必须要掌握!

DockerFile:构建文件,定义了一切的步骤,源代码

DockerImages:通过DockerFile构建生成的镜像,最终发布和运行产品。

Docker容器:容器就是镜像运行起来提供服务。

DockerFile的指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FROM			# 基础镜像,一切从这里开始构建   centos
MAINTAINER # 镜像是谁写的,姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤:tomcat镜像,这个tomcat压缩包! 添加内容,每添加会成一层
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 暴露端口配置,跟 -p 是一个道理
CMD # 指定这个容器启动时要执行的命令,只有最后一个命令会生效,可被替代
ENTRYPOINT # 指定这个容器启动的时候要执行的命令,可以追加命令
ONBUILD # 当构建一个被继承DockerFile 这个时候就会运行ONBUILD的指令。触发指令
COPY # 类似ADD,将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量,跟 -e 是一个意思

# CMD 和 ENTRYPOINT 的区别说明:(后面也会介绍)
# 若CMD 和 ENTRYPOINT 后跟的都是 ls -a 这个命令,当docker run 一个容器时,添加了 -l 选项,则CMD里的ls -a 命令就会被替换成-l;而ENTRYPOINT中的 ls -a会追加-l变成 ls -a -l

在这里插入图片描述

实战测试

Docker Hub中99%镜像都是从这个基础镜像过来的( FROM scratch ),然后配置需要的软件和配置来构建。

创建一个自己的 centos

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 1、编写DockerFile文件,内容如下:
[root@localhost dockerfile]# cat mydockerfile-centos
FROM centos
MAINTAINER ztx<123456@qq.com>

ENV MYPATH /usr/local #centos中的工作目录
WORKDIR $MYPATH

RUN yum -y install vim
RUN yum -y install net-tools #ifconfig的相关命令

EXPOSE 80

CMD echo $MYPATH
CMD echo "----end----"
CMD /bin/bash

# 2、通过这个文件构建镜像
# 命令docker build -f dockerfile文件路径 -t 镜像名:[tag] .
[root@localhost dockerfile]# docker build -f mydockerfile-centos -t mycentos:0.1 .
....
Successfully built c987078b06cb
Successfully tagged mycentos:0.1

# 3、测试运行

生成命令:

1
docker build -f mydockerfile-centos -t mycentos:0.1 .

==通过build命令,用写好的mydockerfile-centos文件来构建target(-t 目标)名为mycentos:0.1 .的镜像 [tag]为版本号==

其中from的centos是本地从hub上pull过的镜像(docker images),如果没有 则会自动去pull下载

测试运行:
在这里插入图片描述
运行的时候带上版本号 否则获取最新版本

对比:

之前的原生的centos
在这里插入图片描述
我们增加之后的镜像
在这里插入图片描述
注:net-tools 包含一系列程序,构成了 Linux 网络的基础。

我们可以列出本地镜像的变更历史:
在这里插入图片描述
我们平时拿到一个镜像,可以研究一下它是怎么做的!

CMD 和 ENTRYPOINT 的区别

测试CMD

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 编写dockerfile文件
$ vim dockerfile-test-cmd
FROM centos
CMD ["ls","-a"]
# 构建镜像
$ docker build -f dockerfile-test-cmd -t cmd-test:0.1 .
# 运行镜像
$ docker run cmd-test:0.1
.
..
.dockerenv
bin
dev

# 想追加一个命令 -l 成为ls -al
$ docker run cmd-test:0.1 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\":
executable file not found in $PATH": unknown.
ERRO[0000] error waiting for container: context canceled
# cmd的情况下 -l 替换了CMD["ls","-l"]。 而-l 不是命令,所以报错

测试ENTRYPOINT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 编写dockerfile文件
$ vim dockerfile-test-entrypoint
FROM centos
ENTRYPOINT ["ls","-a"]
$ docker run entrypoint-test:0.1
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found ...
# 我们的命令,是直接拼接在我们的ENTRYPOINT命令后面的
$ docker run entrypoint-test:0.1 -l
total 56
drwxr-xr-x 1 root root 4096 May 16 06:32 .
drwxr-xr-x 1 root root 4096 May 16 06:32 ..
-rwxr-xr-x 1 root root 0 May 16 06:32 .dockerenv
lrwxrwxrwx 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x 5 root root 340 May 16 06:32 dev
drwxr-xr-x 1 root root 4096 May 16 06:32 etc
drwxr-xr-x 2 root root 4096 May 11 2019 home
lrwxrwxrwx 1 root root 7 May 11 2019 lib -> usr/lib
lrwxrwxrwx 1 root root 9 May 11 2019 lib64 -> usr/lib64 ....

Dockerfile中很多命令都十分的相似,我们需要了解它们的区别,我们最好的学习就是对比他们然后测试效果!

实战:Tomcat镜像

1、准备镜像文件tomcat压缩包,jdk压缩包!
2、编写Dockerfile文件,官方命名: Dockerfile ,build会自动寻找这个文件,就不要 -f 指定了!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
FROM centos
MAINTAINER kuangshen<123456@qq.com>

COPY readme.txt /usr/local/readme.txt

ADD jdk-8u161-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.0.53.tar.gz /usr/local

RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH


ENV JAVA_HOME /usr/local/jdk1.8.0_161
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.0.53
ENV CATALINA_BASH /usr/local/apache-tomcat-8.0.53
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-8.0.53/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.0.53/bin/logs/catalina.out

ADD命令会自动解压压缩包

3、构建镜像

1
# docker build -t diytomcat .     diytomcat是定义的镜像名

4、启动镜像,创建容器

1
# docker run -d -p 9090:8080 --name kuangshentomcat02 -v /home/kuangshen/build/tomcat/test:/usr/local/apache-tomcat-8.0.53/webapps/test -v /home/kuangshen/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-8.0.53/logs diytomcat

5、访问测试
在这里插入图片描述
6、发布项目(由于做了卷挂载,我们就可以直接在本地发布项目了)

在/home/kuangshen/build/tomcat/test目录下创建WEB-INF目录,在里面创建web.xml文件:

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">

</web-app>

在回到test目录,添加一个index.jsp页面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello kuangshen</title>vim
</head>
<body>
Hello World!<br/>
<%
System.out.println("---my test web logs---");
%>
</body>
</html>

发现:test项目部署成功,可以直接访问!

1
[root@localhost tomcatlogs]# cat catalina.out

在这里插入图片描述
之前一直访问失败是web.xml配置有问题,最后也是查看该日志提示,才得以解决!!!

我们以后开发的步骤:需要掌握Dockerfile的编写!我们之后的一切都是使用docker镜像来发布运行!

发布自己的镜像

Docker Hub

1、地址 https://hub.docker.com/

2、确定这个账号可以登录

3、在我们服务器上提交自己的镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@localhost tomcat]# docker login --help

Usage: docker login [OPTIONS] [SERVER]

Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.

Options:
-p, --password string Password
--password-stdin Take the password from stdin
-u, --username string Username

# 登录dockerhub
[root@localhost tomcat]# docker login -u ztx115
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/#credentials-store

Login Succeeded

4、登录完毕后就可以提交镜像了,就是一步 docker push

1
2
3
4
5
6
7
8
9
10
11
12
13
# push自己的镜像到服务器上!
[root@localhost tomcat]# docker push diytomcat
The push refers to repository [docker.io/library/diytomcat]
c5593011cd68: Preparing
d3ce40b8178e: Preparing
02084c67dcc9: Preparing
2b7c1c6c89c5: Preparing
0683de282177: Preparing
denied: requested access to the resource is denied # 拒绝

# push镜像的问题?
# 解决:增加一个tag docker tag 指定镜像的id dockerhub的用户名/镜像重命名:[tag]
[root@localhost tomcat]# docker tag bb64ab96b432 ztx115/tomcat:1.0

在这里插入图片描述
注意:镜像的重命名前一定要加当前的dockerhub的用户名,否则将会push失败!!!!(如:把ztx115改成ztx, push一定失败!)

1
2
3
4
5
6
7
8
9
# docekr push上去即可!  自己平时发布的镜像尽量带上版本号
[root@localhost tomcat]# docker push ztx115/tomcat:1.0
The push refers to repository [docker.io/ztx115/tomcat]
c5593011cd68: Pushed
d3ce40b8178e: Pushed
02084c67dcc9: Pushed
2b7c1c6c89c5: Pushed
0683de282177: Pushed
1.0: digest: sha256:b6733deccf85ad66c6f4302215dd9ea63e1579817f15a099b5858785708ed408 size: 1372

在这里插入图片描述
发现,提交时也是按照镜像的层级来进行提交的!

发布到阿里云镜像服务上(狂神视频截图)

1、登录阿里云

2、找到容器镜像服务

3、创建命名空间
在这里插入图片描述
4、创建容器镜像仓库
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
5、浏览阿里云
在这里插入图片描述
使用阿里云容器镜像的参考官方指南即可!!!(即上图)

小结

在这里插入图片描述