目录挂载

问题:续上期docker基本命令后,发现容器只要一启动,就相当于启动了一个自己的进程方法空间;只要一销毁,就会丢失所有数据;且修改容器的配置文件,默认页面啥的很不方便

解决办法:目录挂载,将容器内部的文件映射到自己创建的文件

docker run -d -p 80:80 -v /app/nghtml:/usr/share/nginx/html --name myapp01 nginx

目录挂载命令 -v  /app/nghtml为要映射的外部文件(没有的话会自动创建), /user/share/nginx/html为外部文件映射的内部文件(即docker hub上该镜像介绍的文件),这样在该容器删除后,外部的容器不会被删,下次可以直接再映射这个文件。且 -v 命令可以重复使用即可同时映射多个文件


卷映射

有时只是想将拉取到的镜像文件映射到本地一个文件,并以镜像文件中的初始值为这个文件的初始值(现在好像不是用镜像文件中的初始值了,默认情况下被映射的文件如果不存在的话会自动创建一个空文件,如果卷已经存在就不会改变卷里的内容)

docker run -d -p 80:80 -v /app/nghtml:/usr/share/nginx/html  -v ngconf:/etc/nginx  --name myapp01 nginx

卷映射命令 -v 加名字,注意不是路径,直接写名字。-v可以重复写;在docker中,卷的存放地址统一在 /var/lib/docker/volumes/<volumes-name>中

docker volume ls 查看所有的卷

docker volume create <volume-name> 创建一个卷

docker volume inspect <volume-name> 查看一个卷的详情

网络

问题:docker run起来后在外部可以通过虚拟机ip加端口访问到,但是同时启动多个容器,在多个容器间相互访问还是通过虚拟机ip加端口访问就太麻烦了

docker 在启动容器时会为每个容器分配唯一ip且加入网络docker0,使用容器ip + 容器端口80 就可以访问到了。

唯一ip:使用 ip a 可以看到,有一个docker0 的 ip 为172.17.0.1;使用 docker inspect name 可以看到进行中的容器会有一个网关和一个跟docker0 的ip一样地址。

"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",

可以通过这个独一无二的IPAddress加80端口(容器内部端口,不走外部端口)进行容器内访问其他容器

进入一个容器:docker exec -it myapp2 bash

访问其他容器:curl http://172.17.0.3:80

问题:但是ip一直在变,每次关闭再次开启可能就会变一次,怎么办呢?

可以使用域名进行访问,docker0默认不支持主机域名,我们就可以创建自定义网络,容器名就是稳定的域名

创建自定义网络:docker network create mynet

启动容器1:docker run -d -p 88:80 --name app1 --network mynet nginx

启动容器2:docker run -d -p 99:80 --name app2 --network mynet nginx

再次查看容器细节就发现了他的唯一id不在是docker0的ip了

"Gateway": "172.18.0.1",

"IPAddress": "172.18.0.2",
 

进入一个容器:docker exec -it app1 bash

使用域名(容器名加端口访问):curl http://app2:80 

访问成功

案例:redis主从同步集群;读写分离两台机器,更耐造

由于要进行一些环境变量等的配置,使用redis官方镜像需要修改配置文件会很麻烦,这里采用bitenami的redis镜像

docker run -d -p 6379:6379 \
> -v /app/rd1:/bitnami/redis/data \
> -e REDIS_REPLICATION_MODE=master \
> -e REDIS_PASSWORD=123456 \
> --network mynet --name redis01 \
> bitnami/redis

\ 代表换行,当一个命令较多时可以将参数换行来写

-e 代表配置环境变量


启动容器后执行 docker ps 会发现没有运行这个容器,查看报错为

Can't open or create append-only dir appendonlydir: Permission denied

是因为我们映射的目录 /app/rd1/ 权限是root,redis内部的容器不可能是主机的root用户

进入app文件夹,并执行 ll 查看当前目录发现

[root@localhost app]# ll
总计 0
drwxr-xr-x. 2 root root 24  9月 3日 17:39 myhtml
drwxr-xr-x. 2 root root  6  9月 4日 19:38 nghtml
drwxr-xr-x. 2 root root  6  9月16日 20:39 rd1

此时需要我们将这个目录的权限改成可读可写可执行

chmod -R 777 rd1
-R 表示递归,即将rd1文件夹中的所有文件权限都修改成这个

777 这是权限数字表示法: 7 = 4+2+1 → rwx 所以 777 = rwxrwxrwx

然后 docker restart redis01 重启就成功启动了

第二步,启动另外一个redis服务

docker run -d -p 6380:6379 \
> -v /app/rd2:/bitnami/redis/data \
> -e REDIS_REPLICATION_MODE=slave \
> -e REDIS_MASTER_HOST=redis01 \
> -e  REDIS_MASTER_PORT_NUMBER=6379 \
> -e REDIS_MASTER_PASSWORD=123456 \
> -e REDIS_PASSWORD=123456 \
> --network mynet --name redis02 \
> bitnami/redis

由于配置了环境变量,在 redis manager 中分别连接两个redis可以发现在master中添加kv在slave中自动就得到了,至此就实现了一个非常简单的redis的主从集群

from 尚硅谷bilibili课程

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐