当前位置: 首页 > article >正文

【docker】容器卷综合讲解,以及go实现的企业案例

容器卷(Volumes)基础讲解:

  1. 容器概念
    容器卷(Volumes)是 Docker 提供的一种持久化存储机制,允许容器持久化数据,即使容器被删除或重新创建,数据仍然可以保留。
    卷是独立于容器的,跨容器可以共享。

  2. 容器卷的特点

  • 数据持久化:卷可以将数据存储在指定的目录中,避免容器重启或删除后数据丢失。
  • 跨容器共享:多个容器可以共享同一个卷,以实现容器间的数据共享。
  • 高效存储:卷存储在宿主机的文件系统中,性能较高。
  • 备份和恢复:卷可以方便地备份和恢复数据。
  1. 创建和使用卷
    创建卷:
    使用 docker volume create 命令来创建一个卷:
docker volume create my_volume

使用卷:
使用 -v--mount 标志将卷挂载到容器内。挂载时,格式如下:

docker run -d -v my_volume:/path/in/container my_image

解释:
my_volume:容器卷的名称。
/path/in/container:容器内的挂载路径。

  1. 容器卷的生命周期
  • 容器创建时创建卷:如果容器使用的卷不存在,Docker 会自动创建一个卷。
  • 容器删除时,卷不被删除:容器删除后,卷仍然会存在。如果不再需要卷,可以手动删除。

查看所有卷:

docker volume ls

查看特定卷的详细信息:

docker volume inspect my_volume
  1. 共享卷
    不同的容器可以共享同一个卷。假设我们有两个容器,它们都需要访问同一个数据:
docker run -d -v shared_volume:/path/in/container1 my_image
docker run -d -v shared_volume:/path/in/container2 my_image

这两个容器都会共享名为 shared_volume 的卷中的数据。

  1. 读写规则
    在 Docker 中,可以控制卷的读写权限。
    只读卷
    如果我们只希望容器能够读取卷中的数据,而不能修改它,可以将卷挂载为只读模式:
docker run -d -v my_volume:/path/in/container:ro my_image

:ro 表示卷是只读的。

默认读写模式
默认情况下,卷是可读写的。如果没有指定 rorw,则卷的挂载是读写模式:

docker run -d -v my_volume:/path/in/container my_image
  1. 卷的继承与共享
    Docker 允许多个容器共享同一个卷。为了支持这个功能,容器需要使用相同的卷名称或挂载相同的宿主机目录路径。这样,容器之间就能够共享数据。
    继承和共享的案例
    假设我们有三个容器,分别是 Web 容器、数据库容器和缓存容器,它们之间需要共享卷:

启动数据库容器并挂载卷:

docker run -d --name db-container -v db-volume:/var/lib/mysql mysql

启动 Web 容器并挂载同一个卷:

docker run -d --name web-container -v db-volume:/data/web-data my_web_image

启动缓存容器并挂载同一个卷:

docker run -d --name cache-container -v db-volume:/data/cache-data my_cache_image

在这个例子中,三个容器都挂载了同一个卷 db-volume,从而共享数据。

  1. 使用宿主机目录共享数据
    除了使用 Docker 卷,我们还可以直接挂载宿主机上的目录来进行数据共享。比如:
docker run -d -v /myhostdir:/path/in/container my_image

此时,容器将挂载宿主机的 /myhostdir 目录,而不是 Docker 卷。

  1. 卷与宿主机文件系统的不同
  • 卷是由 Docker 管理的,并且具有更好的性能、可靠性和迁移性。
  • 一个宿主机目录只是宿主机上的普通文件夹,没有 Docker 的管理和优化,性能上可能不如卷。
  1. 数据备份与恢复
    Docker 卷提供了非常可靠的备份和恢复功能,尤其是对于数据库类应用,卷非常重要。

备份卷数据
可以将卷的数据拷贝到宿主机目录或其他位置进行备份:

docker run --rm -v my_volume:/volume -v /myhost/backup:/backup ubuntu tar cvf /backup/backup.tar /volume

该命令将 my_volume 卷中的数据传输到宿主机的 /myhost/backup 目录下。

恢复卷数据
将备份文件恢复到卷中:

docker run --rm -v my_volume:/volume -v /myhost/backup:/backup ubuntu tar xvf /backup/backup.tar -C /volume
  1. 卷与容器网络
    尽管 Docker 卷与容器网络不直接相关,但在多容器应用中,卷通常是跨网络共享的。不同的容器可以通过 Docker 网络互联,并共享相同卷的数据。比如:
docker network create my_network
docker run -d --name container1 --network my_network -v shared_volume:/data my_image
docker run -d --name container2 --network my_network -v shared_volume:/data my_image

总结

容器卷是 Docker 中非常重要的功能,它不仅实现了容器数据的持久化、跨容器共享,
还支持数据备份和恢复。在企业级应用中,合理使用卷可以提升数据管理的效率,
并确保容器化应用的数据不会因容器重启或删除而丢失。


企业级案例:Go Web 应用与数据库服务

假设我们正在开发一个企业级 Web 应用,该应用使用 Go 语言编写,并且依赖 MySQL 数据库。
我们希望将这个 Go 应用和 MySQL 数据库容器化,同时利用 Docker 卷来持久化数据库数据,
并利用 Docker 网络实现容器间的通信。

案例需求

  1. Go Web 应用:负责提供 Web 服务,接收用户请求,处理数据,并与 MySQL 数据库进行交互。
  2. MySQL 数据库:存储 Web 应用所需的用户数据。
  3. 容器卷(Volumes):MySQL 数据库的持久化存储,确保数据库数据在容器重启或删除后仍然存在。
  4. Docker 网络:用于不同容器间的通信,确保 Web 应用和 MySQL 数据库可以正常通信。

步骤 1:编写 Go Web 应用

首先,我们编写一个简单的 Go Web 应用,这个应用将连接到 MySQL 数据库并提供基本的用户数据处理功能。

main.go:

package main

import (
	"database/sql"
	"fmt"
	"log"
	"net/http"
	"github.com/go-sql-driver/mysql"
)

var db *sql.DB

// 初始化数据库连接
func initDB() {
	var err error
	dsn := "root:root@tcp(db:3306)/mydb"
	db, err = sql.Open("mysql", dsn)
	if err != nil {
		log.Fatal("Error opening database: ", err)
	}
}

// 处理首页请求
func handler(w http.ResponseWriter, r *http.Request) {
	rows, err := db.Query("SELECT name FROM users")
	if err != nil {
		fmt.Fprintf(w, "Error querying database: %v", err)
		return
	}
	defer rows.Close()

	fmt.Fprintf(w, "Users List:\n")
	for rows.Next() {
		var name string
		if err := rows.Scan(&name); err != nil {
			fmt.Fprintf(w, "Error scanning row: %v", err)
			return
		}
		fmt.Fprintf(w, "%s\n", name)
	}
}

// 启动 Web 服务
func main() {
	initDB()
	defer db.Close()

	http.HandleFunc("/", handler)
	log.Fatal(http.ListenAndServe(":8080", nil))
}

步骤 2:编写 Dockerfile

接下来,我们为 Go 应用编写 Dockerfile,将其容器化。

Dockerfile:

# 使用官方 Go 镜像作为基础镜像
FROM golang:1.20 AS builder

# 设置工作目录
WORKDIR /app

# 将 Go 代码复制到容器内
COPY . .

# 编译 Go 应用
RUN go mod tidy && go build -o myapp .

# 使用轻量级的 Alpine 镜像作为运行时环境
FROM alpine:3.17

# 安装 MySQL 客户端(用于与 MySQL 数据库通信)
RUN apk --no-cache add mysql-client

# 将编译好的 Go 应用从 builder 镜像中复制过来
COPY --from=builder /app/myapp /usr/local/bin/myapp

# 容器启动时执行 Go 应用
CMD ["/usr/local/bin/myapp"]

步骤 3:编写 Docker Compose 文件

为了方便管理多个容器,我们使用 Docker Compose 来编排 Go 应用和 MySQL 数据库容器。

docker-compose.yml:

version: "3.8"

services:
  # MySQL 容器
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: mydb
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - mynetwork

  # Go Web 应用容器
  web:
    build: .
    ports:
      - "8080:8080"
    depends_on:
      - db
    networks:
      - mynetwork

volumes:
  db_data:   # 用于存储 MySQL 数据的持久化卷

networks:
  mynetwork:  # 定义自定义网络,使容器能够互相通信

解释

  • MySQL 服务:使用官方 mysql:8.0 镜像,并设置环境变量来配置数据库用户、密码和数据库名。
    使用 Docker 卷 db_data 来持久化数据库数据。
  • Go Web 应用服务:通过 build 指令从当前目录构建 Go 应用的镜像。
    容器将映射到宿主机的 8080 端口,依赖于 MySQL 容器。
  • 自定义网络mynetwork 网络确保 Go Web 应用容器能够与 MySQL 容器通信。

步骤 4:构建和启动容器

现在,我们可以使用 Docker Compose 来构建和启动所有容器。

docker-compose up --build

该命令将构建 Docker 镜像并启动 Go Web 应用容器和 MySQL 容器。构建完成后,
你的 Go Web 应用将在 localhost:8080 上提供服务。

步骤 5:测试 Web 应用

打开浏览器,访问 http://localhost:8080,如果一切配置正确,
你将看到数据库中所有用户的列表。

步骤 6:管理数据持久化

当你使用 docker-compose 启动容器时,MySQL 容器的数据库数据会被存储在宿主机的卷中,
db_data 卷。即使容器被删除,数据仍然会被保留。当你重新启动容器时,数据将自动恢复。

步骤 7:备份和恢复 MySQL 数据

备份 MySQL 数据

docker run --rm -v db_data:/db -v /path/to/backup:/backup alpine \
    tar czf /backup/db_backup.tar.gz /db

这条命令会将 MySQL 数据备份到宿主机的 /path/to/backup/db_backup.tar.gz 文件。

恢复 MySQL 数据

docker run --rm -v db_data:/db -v /path/to/backup:/backup alpine \
    tar xzf /backup/db_backup.tar.gz -C /db

此命令将备份的数据库数据恢复到 db_data 卷中。

步骤 8:容器网络和容器间通信

容器间的网络通信是通过 Docker 网络实现的。上面创建的 mynetwork 网络允许 Go Web 应用容器和 MySQL 容器在同一个网络中相互通信。

  • Go 应用通过 db 主机名来连接 MySQL 数据库(在 docker-compose.yml 中定义)。这是因为 Docker 会自动为每个服务分配一个主机名,并在网络内解析服务名。

总结

通过上述步骤,我们成功地容器化了一个 Go Web 应用,并使用 Docker Compose 将其与 MySQL 数据库容器集成。
同时,通过 Docker 卷,我们确保了数据库的数据持久化。这样,我们不仅提高了应用的可移植性,
还确保了数据在容器重启或删除后的持久性。

这个企业级案例展示了如何使用 Docker 来部署 Go 应用和数据库服务,并结合容器卷和网络进行数据持久化和容器间的通信。
这种架构非常适用于需要高可用性和数据一致性的企业应用。


http://www.kler.cn/a/418455.html

相关文章:

  • 【热门主题】000072 分布式数据库:开启数据管理新纪元
  • 3. STM32_串口
  • 蓝队基础(泷羽sec)
  • 二分搜索(三)x的平方根
  • 用c语言完成俄罗斯方块小游戏
  • LeetCode 动态规划 爬楼梯
  • Javascript 图片懒加载
  • AcWing 1245. 特别数的和
  • 两道数据结构编程题
  • 聊一聊汽车网络安全
  • 腾讯微众银行前端面试题及参考答案
  • 侯捷STL标准库和泛型编程
  • 使用Gradle编译前端的项目
  • 【大数据学习 | Spark】Spark on hive与 hive on Spark的区别
  • buuctf-[SUCTF 2019]EasySQL 1解题记录
  • C#tabcontrol如何指定某个tabItem为默认页
  • 量化交易系统开发-实时行情自动化交易-8.4.MT4/MT5平台
  • 触觉智能亮相OpenHarmony人才生态大会2024
  • k8s--pod创建、销毁流程
  • 【学术投稿】Imagen:重塑图像生成领域的革命性突破
  • 反向传播、梯度下降与学习率:深度学习中的优化艺术
  • kafka消息在client是怎么写入的
  • 探索未来:深入人工智能学习框架的奥秘与实践
  • 设计有一个 “分布式软总线“ 系统,跨平台
  • 基于Java Springboot生鲜食品订购微信小程序
  • Next.js - app 路由器之动态路由与并行路由