一,制作个性化镜像
根据公司的技术栈和技术选型,项目有个性化偏好,需要定制镜像,如:环境配置、软件版本等;
制作个性化镜像,无需每次都进行重复的配置环境,实现开箱即用;
制作个性化镜像有两种方式:
基于 commit 制作
根据 Dockerfile 构建
1,第一种:基于 commit 制作镜像
根据镜像启动容器,在容器内完成环境安装后,基于新的容器提交成为新的镜像,后续基于新镜像启动容器即可;
1,根据 ubuntu 镜像启动容器,添加新的文件,退出
// 启动容器并进入容器内部
BravedeMacBook-Pro:~ brave$ docker run -it ubuntu /bin/bash
// 创建文件
root@9ae402815828:/# cd /root
root@9ae402815828:~# touch my.txt
// 退出容器
root@9ae402815828:~# exit
exit
复制代码
2,将新的容器提交成为新的镜像
// 将指定容器提交为镜像
BravedeMacBook-Pro:~ brave$ docker container commit -m"my ubuntu" -a"brave" 9ae402815828 brave/myubuntu:v1
sha256:23ed9c6a0c37e3648f995dd96c319e37d56631e6be1c7c0c37c97485be54baf5
// 查看本地镜像列表
BravedeMacBook-Pro:~ brave$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
brave/myubuntu v1 23ed9c6a0c37 34 seconds ago 72.8MB
myroot latest 45a3985181e6 17 hours ago 72.8MB
nginx latest f652ca386ed1 46 hours ago 141MB
ubuntu latest ba6acccedd29 7 weeks ago 72.8MB
brave/centos v1 feb5d9fea6a5 2 months ago 13.3kB
hello-world latest feb5d9fea6a5 2 months ago 13.3kB
centos 6 5bf9684f4720 2 months ago 194MB
centos latest 5d0da3dc9764 2 months ago 231MB
// 根据新镜像,启动容器
BravedeMacBook-Pro:~ brave$ docker run -it 23ed9c6a0c37 /bin/bash
root@625496544fa9:/# cd /root
root@625496544fa9:~# ls
my.txt
// 结论,基于新镜像启动的容器中,包含了新容器中的自定义内容
复制代码
基于 commit 制作镜像,优点是直观,但不好管理;
2,第二种:根据 Dockerfile 构建
通过一个文件描述改变和操作,描述一个镜像的构建过程
比如,制作一个 express 的镜像文件
// todo 添加详细实例
3,提交、发布镜像
// 注册并登录 docker
docker login
// tag
docker image tag [imageName] [username]/[repository]:[tag]
// build
docker image build -t [username]/[repository]:[tag] .
// tag
docker tag express-demo zhangrenyang/express-demo:v1
// 推送
docker push zhangrenyang/express-demo:v1
复制代码
数据盘
介绍
根据镜像创建一个容器,相当于在底层镜像上添加了一个读写层(就是容器),这样就可以改东西了;
如果将容器 rm 删掉了,就意味着整个都没了,即:整个镜像和容器层都没了;
那样的话,容器中存储的内容也就都丢掉了;
实际开发总,服务的日志需要保留;
mysql 容器删除后,数据不能丢失;
那么,可以将日志放到宿主机上;
这里需要使用 docker 的数据盘:
为容器创建数据盘:
三种方式:
bind mount 挂载点
volume 数据卷
tmpfs mount
备注:tmpfs mount 是挂载到内存中,很少用到;
volumes 数据卷
准备工作:删除所有容器
// 停掉所有容器 stop 比较优雅相对慢一些,kill 比较快
BravedeMacBook-Pro:~ brave$ docker container stop $(docker container ps -a -q)
625496544fa9
9ae402815828
9c68a087624c
4e7e482c7938
d0f4ff488427
86dfeaa9638c
f08109d1269d
7f87bc954787
// 删除所有容器
BravedeMacBook-Pro:~ brave$ docker container rm $(docker container ps -a -q)
625496544fa9
9ae402815828
9c68a087624c
4e7e482c7938
d0f4ff488427
86dfeaa9638c
f08109d1269d
7f87bc954787
// 查看所有容器
BravedeMacBook-Pro:~ brave$ docker container ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
复制代码
创建数据卷
查看 volume 命令
BravedeMacBook-Pro:~ brave$ docker volume --help
Usage: docker volume COMMAND
Manage volumes
Commands:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes
Run 'docker volume COMMAND --help' for more information on a command.
复制代码
创建数据卷
创建数据卷存放 nginx 日志
BravedeMacBook-Pro:~ brave$ docker volume create nginx-logger
nginx-logger
复制代码
在宿主机硬盘上的哪个位置?
/var/lib/docker/volumes/nginx-logger/_data
// 查看数据卷列表
BravedeMacBook-Pro:~ brave$ docker volume ls
DRIVER VOLUME NAME
local nginx-logger
// 查看指定数据卷的详情
BravedeMacBook-Pro:~ brave$ docker volume inspect nginx-logger
[
{
"CreatedAt": "2021-12-04T12:38:33Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/nginx-logger/_data",
"Name": "nginx-logger",
"Options": {},
"Scope": "local"
}
]
复制代码
如何使用数据卷?
挂载数据卷
再创建一个数据卷
BravedeMacBook-Pro:~ brave$ docker volume create nginx-html
nginx-html
复制代码
将容器中的某个位置挂载到数据卷
根据 nginx 镜像创建一个后台运行的 nginx 容器,命名为 nginx1
将 nginx 的根目录(/usr/share/nginx/html)挂载到数据卷 nginx-html(宿主机的 /var/lib/docker/volumes/nginx-logger/_data)
BravedeMacBook-Pro:~ brave$ docker run -d --name nginx1 --mount src=nginx-html,dst=/usr/share/nginx/html nginx
0f4d6a172bc863765f3c0b32605339d87992aea1d9b91ed34eb003a3ed889dca
nginx-html 数据卷
/usr/share/nginx/html 是 nginx 的根目录
将 nginx 的根目录挂载到了数据卷 nginx-html 上,即 nginx 的根目录指向宿主机的nginx-html目录:"/var/lib/docker/volumes/nginx-logger/_data"
复制代码
启动后,查看数据卷内的数据
解决 MAC OS 问题
https://blog.csdn.net/qq_45673036/article/details/117901509
https://blog.csdn.net/qq_36457702/article/details/101030793
BravedeMacBook-Pro:~ brave$ docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
Unable to find image 'debian:latest' locally
latest: Pulling from library/debian
5e0b432e8ba9: Pull complete
Digest: sha256:45ee40a844048c2f6d0105899c1a17733530b56d481612608aab5e2e4048570b
Status: Downloaded newer image for debian:latest
/ # ls
bin dev home media proc sbin tmp
boot etc init mnt root srv usr
containers grpcfuse.ko lib opt run sys var
// 进入 docker 目录
/ # cd /var/lib/docker/
/var/lib/docker # ls
buildkit containers image network overlay2 plugins runtimes swarm tmp trust volumes
// 查看 docker 卷
/var/lib/docker # cd volumes/
/var/lib/docker/volumes # ls
backingFsBlockDev metadata.db nginx-html nginx-logger
// 进入 nginx-html/_data/
/var/lib/docker/volumes # cd nginx-html/_data/
/var/lib/docker/volumes/nginx-html/_data # ls
50x.html index.html
复制代码
还可以再进入到容器中的 nginx 根目录(此时容器内 nginx 的根目录与宿主机 nginx-html 数据卷已同步)
BravedeMacBook-Pro:~ brave$ docker container exec -it 0f4d6a172bc863 /bin/bash
root@0f4d6a172bc8:/# cd /usr/share/nginx/html
root@0f4d6a172bc8:/usr/share/nginx/html# ls
50x.html index.html
复制代码
在容器内创建一个文件(看数据卷会不会同步)
root@0f4d6a172bc8:/usr/share/nginx/html# touch test.html
复制代码
宿主机看一下,文件已经同步:
/var/lib/docker/volumes/nginx-html/_data # ls
50x.html index.html test.html
复制代码
在宿主机创建一个文件
/var/lib/docker/volumes/nginx-html/_data # touch test1.html
复制代码
在容器内查看,已同步:
root@0f4d6a172bc8:/usr/share/nginx/html# ls
50x.html index.html test.html test1.html
复制代码
挂载有两种方法,上边讲的是第一种,很啰嗦
docker run -d --name nginx1 --mount src=nginx-html,dst=/usr/share/nginx/html nginx
复制代码
第二种,路径的映射可以简写
做 volume 映射 数据卷名称:容器目录
BravedeMacBook-Pro:~ brave$ docker run -d --name nginx2 -v nginx-html:/usr/share/nginx/html nginx
2bb332f19311592bea94715f3494bbfc2ddb2e4c1c1ca017d8b4c6d43241dc83
复制代码
没有映射端口,都是 80,会不会冲突?
相当于两台机器,相互独立,与外部的宿主机没有关系;
进去目录看看,内容是一样的:
BravedeMacBook-Pro:~ brave$ docker container exec -it 2bb332f19311 /bin/bash
root@2bb332f19311:/# cd /usr/share/nginx/html
root@2bb332f19311:/usr/share/nginx/html# ls
50x.html index.html test.html test1.html
复制代码
删除数据卷
BravedeMacBook-Pro:~ brave$ docker volume rm nginx-html
Error response from daemon: remove nginx-html: volume is in use - [0f4d6a172bc863765f3c0b32605339d87992aea1d9b91ed34eb003a3ed889dca, 2bb332f19311592bea94715f3494bbfc2ddb2e4c1c1ca017d8b4c6d43241dc83]
复制代码
有两个容器正在使用,不能删除,想要删除需要先把这两个容器停掉
BravedeMacBook-Pro:~ brave$ docker container ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2bb332f19311 nginx "/docker-entrypoint.…" 24 hours ago Up 24 hours 80/tcp nginx2
0f4d6a172bc8 nginx "/docker-entrypoint.…" 25 hours ago Up 25 hours 80/tcp nginx1
BravedeMacBook-Pro:~ brave$ docker container kill 2bb332f19311 0f4d6a172bc8
2bb332f19311
0f4d6a172bc8
复制代码
两个容器已经停掉了,再删除发现还是不行
BravedeMacBook-Pro:~ brave$ docker volume rm nginx-html
Error response from daemon: remove nginx-html: volume is in use - [0f4d6a172bc863765f3c0b32605339d87992aea1d9b91ed34eb003a3ed889dca, 2bb332f19311592bea94715f3494bbfc2ddb2e4c1c1ca017d8b4c6d43241dc83]
复制代码
这是因为,两个容器挂载了数据卷
可以把容器删掉
// 查看数据卷列表
BravedeMacBook-Pro:~ brave$ docker volume ls
DRIVER VOLUME NAME
local nginx-html
local nginx-logger
// -f dangling=true 过滤悬挂的,即查看没有任何容器引用的数据卷
BravedeMacBook-Pro:~ brave$ docker volume ls -f dangling=true
DRIVER VOLUME NAME
local nginx-logger
这种是可以直接通过 docker volume rm 删掉的
docker volume rm nginx-logger
也可以一次将所有没有引用的数据卷都删掉
docker volume prune
复制代码
bind mount 数据卷
如果 var/lib/docker/volumes 空间太小不够,就要放到其他地方,此时就不能用 volume 了
需要使用绑定挂载
docker run -v /mnt:/mnt -it --name logs centos bash
将宿主机的/mnt 目录映射为这个容器的 /mnt 目录
复制代码
注意个 volume -v 的区别:
docker run -d --name nginx2 -v nginx-html:/usr/share/nginx/html nginx
这个-v nginx-html:/usr/share/nginx/html
冒号左侧是数据卷名
复制代码
BravedeMacBook-Pro:~ brave$ docker run -v /mnt:/mnt -it --name logs centos bash
docker: Error response from daemon: Mounts denied:
The path /mnt is not shared from the host and is not known to Docker.
You can configure shared paths from Docker -> Preferences... -> Resources -> File Sharing.
See https://docs.docker.com/desktop/mac for more info.
复制代码
创建容器后,在容器的/mnt 目录创建一个 txt 文件,
宿主机的/mnt 会同步出现 txt 文件
这样就不会收到 docker/volumes 的限制,想吧数据放在哪就可以挂载到哪里
可以两个容器用一个数据盘 比如负载情况,日志可以写到一起去
创建容器
BravedeMacBook-Pro:~ brave$ docker create -v /Users/brave/logger:/logger --name logger centos
c86fb1eb39ba1b87b84af741818b51d6e65e705934382fd3cc206e2d79f82fc1
BravedeMacBook-Pro:~ brave$ docker container ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
06531bf11e91 centos "/bin/bash" 43 seconds ago Created logger
复制代码
docker create 和 docker run 的区别是创建容器但不启动
我们创建它的作用不是用来启动的,而是数据挂载策略:用宿主机的/logger,挂载容器中的 /logger
继承容器:
--volumes-from:从哪个容器继承数据卷(logger 挂载了数据卷)
// logger_test1 继承 logger 容器的数据卷
BravedeMacBook-Pro:~ brave$ docker run --volumes-from logger --name logger_test1 -it centos bash
[root@4ce4b9717b5c /]#
复制代码
在 logger_test1 容器内,即/logger 目录下创建一个文件
同理再创建一个 logger_test2,/logger 目录下存在刚刚 logger_test1 创建的文件
logger_test2 进入/logger 目录创建文件,logger_test1 也能看到
退出后,宿主机也能看到
优势,不需要知道数据卷的配置,只需要知道继承就好了
评论