美文网首页Docker
五、Docker搭建项目实战

五、Docker搭建项目实战

作者: Suny____ | 来源:发表于2020-03-13 23:41 被阅读0次

1、数据持久化

实战前还有一个知识点需要补充,就是持久化。

项目是部署在容器里的,产生的数据也是在容器里的,那如果容器挂了,数据该怎么存,是如何保证持久化的呢?

  • Volume

    Docker中数据的持久化就是通过 volume 来实现,将容器中存储数据的目录映射到宿主机中,这样即使容器挂了,数据还是在宿主机中存在的。

我们看 mysql 的Dockerfile,里面就使用了 volume 来映射目录。

FROM debian:buster-slim

# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN groupadd -r mysql && useradd -r -g mysql mysql

# ...省略...

# 这个命令会将 /var/lib/mysql 目录映射到宿主机
VOLUME /var/lib/mysql

COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]

EXPOSE 3306 33060
CMD ["mysqld"]

映射文件目录查看:

# 启动mysql容器
[root@10 ~]# docker run -d --name mysql01 -p 3301:3306 -e MYSQL_ROOT_PASSWORD=root --privileged mysql
6e491f8d4177fe71ff2e6a243f63fa2fffc7ee7249e56a7d61d042104e2b1df7

# 进入mysql容器,查看映射的数据目录
[root@10 ~]# docker exec -it mysql01 bash
root@6e491f8d4177:/# cd /var/lib/mysql/

# 这里就是mysql的数据文件
root@6e491f8d4177:/var/lib/mysql# ls -n
total 178200
drwxr-x---. 2 999 999      187 Mar 13 13:05 '#innodb_temp'
-rw-r-----. 1 999 999       56 Mar 13 13:05  auto.cnf
-rw-r-----. 1 999 999  3101251 Mar 13 13:05  binlog.000001
-rw-r-----. 1 999 999      155 Mar 13 13:05  binlog.000002
-rw-r-----. 1 999 999       32 Mar 13 13:05  binlog.index
-rw-------. 1 999 999     1680 Mar 13 13:05  ca-key.pem
-rw-r--r--. 1 999 999     1112 Mar 13 13:05  ca.pem
-rw-r--r--. 1 999 999     1112 Mar 13 13:05  client-cert.pem
-rw-------. 1 999 999     1676 Mar 13 13:05  client-key.pem
-rw-r-----. 1 999 999     5402 Mar 13 13:05  ib_buffer_pool
-rw-r-----. 1 999 999 50331648 Mar 13 13:05  ib_logfile0
-rw-r-----. 1 999 999 50331648 Mar 13 13:05  ib_logfile1
-rw-r-----. 1 999 999 12582912 Mar 13 13:05  ibdata1
-rw-r-----. 1 999 999 12582912 Mar 13 13:05  ibtmp1
drwxr-x---. 2 999 999      143 Mar 13 13:05  mysql
-rw-r-----. 1 999 999 30408704 Mar 13 13:05  mysql.ibd
drwxr-x---. 2 999 999     8192 Mar 13 13:05  performance_schema
-rw-------. 1 999 999     1676 Mar 13 13:05  private_key.pem
-rw-r--r--. 1 999 999      452 Mar 13 13:05  public_key.pem
-rw-r--r--. 1 999 999     1112 Mar 13 13:05  server-cert.pem
-rw-------. 1 999 999     1680 Mar 13 13:05  server-key.pem
drwxr-x---. 2 999 999       28 Mar 13 13:05  sys
-rw-r-----. 1 999 999 12582912 Mar 13 13:05  undo_001
-rw-r-----. 1 999 999 10485760 Mar 13 13:05  undo_002

# 在宿主机中查看映射文件
[root@10 ~]# docker volume ls
DRIVER              VOLUME NAME
local               af5e05da43fad820680e5e734c97ddda5021973457e4c5dbcc51dc2ca8906ee8

# 通过查看映射文件的详情,可以看到映射目录在什么位置
[root@10 ~]# docker volume inspect af5e05da43fad820680e5e734c97ddda5021973457e4c5dbcc51dc2ca8906ee8
[
    {
        "CreatedAt": "2020-03-13T13:05:27Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/af5e05da43fad820680e5e734c97ddda5021973457e4c5dbcc51dc2ca8906ee8/_data",
        "Name": "af5e05da43fad820680e5e734c97ddda5021973457e4c5dbcc51dc2ca8906ee8",
        "Options": null,
        "Scope": "local"
    }
]

# 进入宿主机中的目录
[root@10 ~]# cd /var/lib/docker/volumes/af5e05da43fad820680e5e734c97ddda5021973457e4c5dbcc51dc2ca8906ee8/_data

# 可以看到这里的文件与容器中是一致的
[root@10 _data]# ls -n
total 178200
-rw-r-----. 1 999 999       56 Mar 13 13:05 auto.cnf
-rw-r-----. 1 999 999  3101251 Mar 13 13:05 binlog.000001
-rw-r-----. 1 999 999      155 Mar 13 13:05 binlog.000002
-rw-r-----. 1 999 999       32 Mar 13 13:05 binlog.index
-rw-------. 1 999 999     1680 Mar 13 13:05 ca-key.pem
-rw-r--r--. 1 999 999     1112 Mar 13 13:05 ca.pem
-rw-r--r--. 1 999 999     1112 Mar 13 13:05 client-cert.pem
-rw-------. 1 999 999     1676 Mar 13 13:05 client-key.pem
-rw-r-----. 1 999 999     5402 Mar 13 13:05 ib_buffer_pool
-rw-r-----. 1 999 999 12582912 Mar 13 13:05 ibdata1
-rw-r-----. 1 999 999 50331648 Mar 13 13:05 ib_logfile0
-rw-r-----. 1 999 999 50331648 Mar 13 13:05 ib_logfile1
-rw-r-----. 1 999 999 12582912 Mar 13 13:05 ibtmp1
drwxr-x---. 2 999 999      187 Mar 13 13:05 #innodb_temp
drwxr-x---. 2 999 999      143 Mar 13 13:05 mysql
-rw-r-----. 1 999 999 30408704 Mar 13 13:05 mysql.ibd
drwxr-x---. 2 999 999     8192 Mar 13 13:05 performance_schema
-rw-------. 1 999 999     1676 Mar 13 13:05 private_key.pem
-rw-r--r--. 1 999 999      452 Mar 13 13:05 public_key.pem
-rw-r--r--. 1 999 999     1112 Mar 13 13:05 server-cert.pem
-rw-------. 1 999 999     1680 Mar 13 13:05 server-key.pem
drwxr-x---. 2 999 999       28 Mar 13 13:05 sys
-rw-r-----. 1 999 999 12582912 Mar 13 13:05 undo_001
-rw-r-----. 1 999 999 10485760 Mar 13 13:05 undo_002

上面已经演示了mysql容器映射目录到宿主机,如果容器挂了,可以在将该目录映射给容器,这样就达到了容器持久化数据的目的了。

也来演示一下,在mysql容器中创建一个数据库,之后删除容器:

[root@10 _data]# docker exec -it mysql01 bash
root@6e491f8d4177:/# mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.19 MySQL Community Server - GPL

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database db_test;
Query OK, 1 row affected (0.01 sec)

# db_test 数据库已经创建成功
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| db_test            |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

删除mysql容器,重新将文件映射回容器,需要使用参数 -v 指定映射目录

[root@10 _data]# docker rm -f mysql01
mysql01

# 将之前的mysql数据目录映射到mysql容器
[root@10 _data]# docker run -d --name mysql01 -p 3301:3306 -v af5e05da43fad820680e5e734c97ddda5021973457e4c5dbcc51dc2ca8906ee8:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --privileged mysql
9f6f9eec1e448f5c3b665dc925bed8d236cb1ab976d3884be7643eeb3982ae39
[root@10 _data]# docker exec -it mysql01 bash
root@9f6f9eec1e44:/# mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.19 MySQL Community Server - GPL

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

# 可以看到 db_test 数据库还在
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| db_test            |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

大家可能也发现了,映射文件的名称太长,而且如果容器多了,我们根本不知道那个映射文件是对应哪个容器的。

所以也有解决办法,就是在启动容器的时候,就指定一个容易辨识的映射文件名称。

# 指定 mysql01 容器使用 mysql01-volume 映射
[root@10 _data]# docker run -d --name mysql01 -p 3301:3306 -v mysql01-volume:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --privileged mysql
025caf2cf7c9cb129c14451c539d59dab311c747c01dff53c88fe1048348b419

# 创建出来的volume名称就很容易识别了
[root@10 _data]# docker volume ls
DRIVER              VOLUME NAME
local               mysql01-volume

[root@10 _data]# docker volume inspect mysql01-volume
[
    {
        "CreatedAt": "2020-03-13T13:22:31Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/mysql01-volume/_data",
        "Name": "mysql01-volume",
        "Options": null,
        "Scope": "local"
    }
]

2、Nginx + Spring Boot项目 + MySQL 实战

2.1 容器规划

搭建的容器为 1 个Nginx 容器,3个 Spring Boot 容器,1个 Mysql 容器。

  • 网络模式
    • 使用自建 brige 网络模式,使用指定的 ip 段,以实现通过容器名称连接目标机器。
    • docker network create --subnet=172.18.0.0/24 pro-net
  • IP分配
    • Nginx Container
      • 172.18.0.10
    • Mysql Container
      • 172.18.0.6
    • Spring Boot Container
      • 172.18.0.11~172.18.0.13
  • 映射文件
    • Mysql
      • mysql-volume
image.png

2.2 开始搭建容器

  • 创建 network、volume
# 自建 brige 网络模式
[root@10 _data]# docker network create --subnet=172.18.0.0/24 pro-net
4a210633167015f7f37df5744b81a58e5acfe3255bd865113c09ef8f180202d8

# 创建 Mysql 数据映射文件
[root@10 _data]# docker volume create mysql-volume
mysql-volume
  • 创建Mysql容器
# 创建Mysql容器,指定 volume、network、ip
[root@10 _data]# docker run -d --name mysql01 -v mysql-volume:/var/lib/mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root --net=pro-net --ip 172.18.0.6 mysql
06a4ced69b7d45dc58ce548c6fdcdb7cc46a5c0bca7958d4df1da7098be1e648

SQL

-- 建表语句
create schema db_test collate utf8mb4_0900_ai_ci;
use db_test;
create table t_user (
    id int not null primary key,
    username varchar(50) not null
);

-- 基础数据
INSERT INTO db_test.t_user (id, username) VALUES (1, 'sunny');
  • 准备Spring Boot项目
    • 数据库连接地址直接写 容器名称
image.png
  • Controller
image.png
  • 本地测试

    注意本地测试时 项目配置文件中的数据库地址要改成 docker 宿主机的 ip 和 端口

image.png
  • 将项目打成 jar 包

  • 上传 jar 包到Linux中

  • 编写 Dockerfile 文件

    FROM openjdk:8-jre-alpine
    
    MAINTAINER sunny
    
    LABEL name="springboot-mybatis" version="1.0" author="sunny"
    
    COPY springboot-mybatis-0.0.1-SNAPSHOT.jar springboot-mybatis.jar
    
    CMD ["java","-jar","springboot-mybatis.jar"]
    
  • 构建 image 镜像

    [root@10 test]# docker build -t springboot-mybatis .
    Sending build context to Docker daemon  21.59MB
    Step 1/5 : FROM openjdk:8-jre-alpine
    8-jre-alpine: Pulling from library/openjdk
    e7c96db7181b: Pull complete
    f910a506b6cb: Pull complete
    b6abafe80f63: Pull complete
    Digest: sha256:f362b165b870ef129cbe730f29065ff37399c0aa8bcab3e44b51c302938c9193
    Status: Downloaded newer image for openjdk:8-jre-alpine
     ---> f7a292bbb70c
    Step 2/5 : MAINTAINER sunny
     ---> Running in 1ed297ae107d
    Removing intermediate container 1ed297ae107d
     ---> e2fd8988f05a
    Step 3/5 : LABEL name="springboot-mybatis" version="1.0" author="sunny"
     ---> Running in 707fbebabd33
    Removing intermediate container 707fbebabd33
     ---> 383323324c94
    Step 4/5 : COPY springboot-mybatis-0.0.1-SNAPSHOT.jar springboot-mybatis.jar
     ---> 95be99409a9e
    Step 5/5 : CMD ["java","-jar","springboot-mybatis.jar"]
     ---> Running in 4e0645b2946b
    Removing intermediate container 4e0645b2946b
     ---> 8cd79100689b
    Successfully built 8cd79100689b
    Successfully tagged springboot-mybatis:latest
    
  • 创建 3 个容器

    # 指定 network、ip
    docker run -d --name springboot-mybatis-01 -p 8081:8080 --net=pro-net --ip 172.18.0.11 springboot-mybatis
    
    # 指定 network、ip
    docker run -d --name springboot-mybatis-02 -p 8082:8080 --net=pro-net --ip 172.18.0.12 springboot-mybatis
    
    # 指定 network、ip
    docker run -d --name springboot-mybatis-03 -p 8083:8080 --net=pro-net --ip 172.18.0.13 springboot-mybatis
    
  • 准备 Nginx 容器

    • 准备配置文件

      • 创建目录 /tmp/nginx ,创建 nginx.conf 文件
      user nginx;
      worker_processes 1;
      
      events {
          worker_connections 1024;
      }
      
      http {
          include /etc/nginx/mime.types;
          default_type application/octet-stream;
          sendfile on;
          keepalive_timeout 65;
      
          server {
             listen 80;
             location / {
                # 使用负载均衡 
                proxy_pass http://balance;
             }
          }
      
          # 配置负载均衡的项目地址
          upstream balance{ 
             server 172.18.0.11:8080;
             server 172.18.0.12:8080;
             server 172.18.0.13:8080;
          }
          include /etc/nginx/conf.d/*.conf;
      }
      
      
    • 启动Nginx

      # 本地没有镜像会自动拉取, 映射宿主机的 /tmp/nginx/nginx.conf  到容器中的 /etc/nginx/nginx.conf,指定 network、ip
      docker run -d --name nginx01 -p 80:80 -v
      /tmp/nginx/nginx.conf:/etc/nginx/nginx.conf --network=pro-net --ip 172.18.0.10
      nginx
      
  • 通过 Nginx 访问 Spring Boot项目

image.png
最终测试成功,容器搭建项目实战全部完成!其他的一些业务场景就各位自己去玩吧!!!

相关文章

网友评论

    本文标题:五、Docker搭建项目实战

    本文链接:https://www.haomeiwen.com/subject/ukmushtx.html