Docker目录挂载和多容器通信

  • 使用 Docker 运行后,我们改了项目代码不会立刻生效,需要重新buildrun,很是麻烦。
  • 容器里面产生的数据,例如 log 文件,数据库备份文件,容器删除后就丢失了。
目录挂载解决以上问题

几种挂载方式

Docker提供了多种挂载方式,以下是三种主要的挂载方式及其使用方法和推荐:

  1. 绑定挂载(Bind Mounts)
  • 使用方式:通过-v--mount参数将主机上的文件或目录挂载到容器中。例如:docker run -v /host/path:/container/path image_name
  • 特点:允许容器与主机之间共享文件和目录,对其中一个的更改会直接影响到另一个。
  • 推荐场景:当需要容器与主机之间实时同步文件或目录,或者需要在容器外部直接操作容器内部文件时,绑定挂载是一个很好的选择。
  1. 卷挂载(Volume Mounts)
  • 使用方式:通过-v参数将Docker数据卷挂载到容器中。例如:docker run -v volume_name:/container/path image_name
  • 特点:Docker卷是一个可供容器使用的特殊目录,它绕过了联合文件系统,因此对其的I/O操作效率更高。卷挂载允许在容器之间共享和重用数据,并且它们的生命周期可以独立于容器。
  • 推荐场景:当需要在多个容器之间共享数据,或者希望数据的生命周期独立于容器时,卷挂载是一个很好的选择。
  1. 临时文件系统(tmpfs)挂载
  • 使用方式:通过--tmpfs参数将临时文件系统挂载到容器的指定路径。
  • 特点:临时文件系统挂载的数据不会持久化到磁盘,仅存在于容器的运行期间。
  • 推荐场景:当需要为容器提供临时的、非持久化的存储空间时,可以使用tmpfs挂载。

推荐

  • 如果需要实时同步主机与容器之间的文件或目录,或者需要在容器外部直接操作容器内部文件,推荐使用绑定挂载
  • 如果需要在多个容器之间共享数据,或者希望数据的生命周期独立于容器,推荐使用卷挂载

请注意,不同的挂载方式有其特定的使用场景和优缺点,在选择时需要根据实际需求进行权衡。同时,为了确保数据的安全性和一致性,建议在使用挂载功能时谨慎操作,并遵循Docker的最佳实践。

文档参考:https://docs.docker.com/storage/

挂载方式

挂载演示

1. 绑定挂载(Bind Mounts)

绑定挂载允许你将主机上的文件或目录挂载到容器中

1
docker run -v /host/path:/container/path ubuntu

上面的命令会将/host/path目录挂载到容器的/container/path目录

其他:比如Flask

1
2
3
4
5
6
docker run -d \  # -d 在后台运行容器。
-p 8000:8000 \ # 将容器的8000端口映射到主机的8000端口
-v $(pwd)/flask_app:/app \ # 将当前目录下的flask_app目录挂载到容器的/app目录
--name my-flask-app \ # 给容器指定一个名字:my-flask-app
python:3.8 \ # 使用Python 3.8镜像作为基础镜像
python /app/app.py # 在容器内运行Flask应用

2. 卷挂载(Volume Mounts)

Docker卷是一个可供容器使用的特殊目录,它绕过了联合文件系统,提供了更高效的I/O操作

首先,创建一个Docker卷:

1
docker volume create my-volume

然后,将卷挂载到容器中:

1
docker run -v my-volume:/container/path ubuntu 

上面的命令会将my-volume卷挂载到容器的/container/path目录

其他:比如Flask

1
2
3
4
5
6
7
docker volume create flask-volume	# 创建一个Docker卷
docker run -d \
-p 8000:8000 \
--name my-flask-volume \
-v flask-volume:/app \
python:3.8 \
python /app/app.py

3. 临时文件系统(tmpfs)挂载

tmpfs挂载创建的是一个临时文件系统,数据不会持久化到磁盘

1
docker run --tmpfs /tmp:rw,size=1024 ubuntu

上面的命令会在容器内创建一个/tmp目录,并将其挂载为tmpfs文件系统

注意:在使用挂载功能时,请确保主机上的目录或文件权限设置正确,以便容器可以访问它们。此外,对于敏感数据或重要文件,请谨慎使用挂载功能,以避免潜在的安全风险。

在实际应用中,你可以根据具体需求选择适合的挂载方式,并根据需要进行调整和扩展。

多容器通信

项目往往都不是独立运行的,需要数据库、缓存这些东西配合运作。

这节我们把前面的 Django 项目增加一个 MariaDB 依赖,多跑一个 MariaDB 容器,演示如何多容器之间的通信。

创建虚拟网络

要想多容器之间互通,从 Django 容器访问 MariaDB 容器,我们只需要把他们放到同个网络中就可以了。

文档参考:https://docs.docker.com/engine/reference/commandline/network/

举例

使用Docker网络

Docker提供了内置的网络功能,使得容器之间可以相互通信。当你启动Docker时,它会自动创建一个名为bridge的默认网络。你可以将容器连接到这个网络,或者使用docker network create命令创建自定义网络,并将容器连接到这个自定义网络。一旦容器连接到了同一个网络,它们就可以通过容器名称或IP地址相互通信。

例如,创建自定义网络:

1
docker network create my-custom-network

将容器连接到自定义网络:

1
2
docker run -d --network==my-custom-network --name container1 ...  
docker run -d --network==my-custom-network --name container2 ...

容器间通信:

1
docker exec -it container1 ping container2

示例

  1. 下载镜像
1
2
3
4
5
6
# mariadb
docker search mariadb # 搜索镜像
docker pull mariadb # 下载镜像
# django
# 首先编辑好你自定义的Dockerfile 和 django项目文件
docker build -t myproject-django .

我的Dockerfile如下,仅供参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 使用官方Python 3.10.13镜像作为基础镜像
FROM python:3.10.13

# 维护者信息
LABEL maintainer="jerry <jerry@qq.com>"

# 设置工作目录
WORKDIR /app

# 将当前目录内容复制到容器的/app内
COPY . /app

# 更新pip
RUN pip install --upgrade pip
# 设置为阿里云的源
RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
# 安装任何需要的包
RUN pip install --no-cache-dir -r requirements.txt

# 容器启动时运行的命令
CMD ["python", "manage.py","runserver","0.0.0.0:8000"]
  1. 生成容器
1
2
3
4
5
6
7
8
# 创建自定义网络
docker network create myproject-network

# mariadb 宿主机3369映射到容器3306 DevOpsDB容器名字 mariadb镜像名字 --network 指定网络
docker run -d --name DevOpsDB --network=myproject-network -p 3369:3306 -e MYSQL_ROOT_PASSWORD=你的数据库密码 mariadb

# django myproject-django-container容器名字 --network 指定网络 myproject-django镜像名字
docker run --name myproject-django-container -p 8000:8000 --network=myproject-network myproject-django
  1. 修改Django数据库配置文件
1
2
3
4
5
6
7
8
9
10
DATABASES = {  
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '你的数据库名字-不是容器名字',
'USER': 'root',
'PASSWORD': '你的数据库密码',
'HOST': 'DevOpsDB', # 使用MariaDB容器的名称作为主机名
'PORT': '3306', # 使用MariaDB容器的默认MySQL端口
}
}

4.Django数据库初始化

1
2
3
4
5
6
docker exec -it myproject-django-container /bin/bash
# 进入bash后 执行数据库迁移
python manage.py makemigrations
python manage.py migrate
# 创建超级用户(如果需要)
python manage.py createsuperuser

文笔流畅美,点赞纷至来;

内容引入胜,分享乐开怀;

佳作值得赏,打赏表心怀。