一起学docker(四)| 数据卷 + 简单应用部署(MySQL,Tomcat,Nginx,Redis)

Docker 容器数据卷

Docker容器产生的数据,如果不备份,那么当容器实例删除后,容器内的数据也就消失了。需要对数据进行持久化

为了保存docker中的数据,可以使用数据卷。

是什么

卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性。

卷的设计目的就是数据的持久化,完全独立于容器的生命周期,因此Docker不会在容器删除时删除其挂载的数据卷。

通俗来说,就是将docker容器内的数据保存进宿主机的磁盘中。

docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名

–privileged=true???

  • Docker挂载主机目录访问如果出现cannot open directory .: Permission denied

    解决办法:在挂载目录后多加一个–privileged=true参数即可

如果是CentOS7,安全模块会比之前系统版本加强,不安全的会先禁止,所以目录挂载的情况被默认为不安全的行为,在SELinux里面挂载目录被禁止掉了,如果要开启,我们一般使用–privileged=true命令,扩大容器的权限解决挂载目录没有权限的问题,也就是使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限。

特点:

  • 数据卷可在容器间共享或重用数据
  • 数据卷更改实时生效
  • 数据卷的更改不会包含在镜像的更新中
  • 数据卷的生命周期一直持续到没有容器使用它为止
添加数据卷

docker run -it --privileged=true -v /宿主机目录:/容器内目录 镜像名

  • 添加数据卷docker run -it --name="ubuntu-j" --privileged=true -v /dockerbackup/ubuntu:/tmp/ubuntu f706429da9df /bin/bash

    [root@VM-4-9-centos /]# docker images
    REPOSITORY                    TAG       IMAGE ID       CREATED         SIZE
    121.4.126.115:5000/ubuntu-j   1.0       f706429da9df   5 hours ago     186MB
    mysql                         latest    f6360852d654   4 days ago      565MB
    redis                         latest    7e89539dd8bd   2 weeks ago     130MB
    [root@VM-4-9-centos /]# docker run -it --name="ubuntu-j" --privileged=true -v /dockerbackup/ubuntu:/tmp/ubuntu f706429da9df /bin/bash
    root@74221444a50b:/# 
    
  • 查看数据卷是否挂载成功docker inspect 容器id

    [root@VM-4-9-centos ubuntu]# docker ps
    CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS          PORTS                                                           NAMES
    74221444a50b   f706429da9df          "/bin/bash"              13 minutes ago   Up 13 minutes                                                                   ubuntu-j
    f5346aab9063   registry              "/entrypoint.sh /etc…"   6 hours ago      Up 3 hours      0.0.0.0:5000->5000/tcp, :::5000->5000/tcp                       ecstatic_goldwasser
    3bb8baf477a0   portainer/portainer   "/portainer"             2 days ago       Up 3 hours      8000/tcp, 9443/tcp, 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp   mystifying_knuth
    [root@VM-4-9-centos ubuntu]# docker inspect 74221444a50b
    ......
            "Mounts": [
                {
                    "Type": "bind",
                    "Source": "/dockerbackup/ubuntu",
                    "Destination": "/tmp/ubuntu",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                }
    ......
    [root@VM-4-9-centos ubuntu]# 
    
  • 测试1:

    • 在容器相应目录新建a.txt文件

      root@74221444a50b:/tmp/ubuntu# pwd
      /tmp/ubuntu
      root@74221444a50b:/tmp/ubuntu# touch a.txt
      root@74221444a50b:/tmp/ubuntu# ls
      a.txt
      
    • 查看宿主机相应目录

      [root@VM-4-9-centos ~]# ls /dockerbackup/ubuntu/
      a.txt
      
  • 测试2:

    • 在宿主机相应目录新建b.txt

      [root@VM-4-9-centos ubuntu]# pwd
      /dockerbackup/ubuntu
      [root@VM-4-9-centos ubuntu]# touch b.txt
      [root@VM-4-9-centos ubuntu]# ls
      a.txt  b.txt
      
    • 查看容器相应目录

      root@74221444a50b:/tmp/ubuntu# pwd
      /tmp/ubuntu
      root@74221444a50b:/tmp/ubuntu# ls
      a.txt  b.txt
      
读写规则映射添加说明
读写(默认)

docker run -it --privileged=true -v /宿主机目录:/容器内目录:rw 镜像名

  • rw:read+write
  • 默认(不写rw)就是具备读写的
只读

docker run -it --privileged=true -v /宿主机目录:/容器内目录:ro 镜像名

  • ro:read only
  • 此时如果宿主机写,可以同步到容器,容器可以读取到,但是容器不支持写
  1. 添加数据卷

    [root@VM-4-9-centos /]# docker run -it --name="ubuntu-j2" --privileged=true -v /dockerbackup/ubuntu:/tmp/ubuntu:ro f706429da9df /bin/bash 
    root@99c6b59ff576:/# cd tmp/ubuntu/
    root@99c6b59ff576:/tmp/ubuntu# ls
    a.txt  b.txt
    root@99c6b59ff576:/tmp/ubuntu# 
    
  2. 测试1:

    • 宿主机写c.txt

      [root@VM-4-9-centos ubuntu]# pwd
      /dockerbackup/ubuntu
      [root@VM-4-9-centos ubuntu]# touch c.txt
      [root@VM-4-9-centos ubuntu]# ls
      a.txt  b.txt  c.txt
      [root@VM-4-9-centos ubuntu]# 
      
    • 查看容器相应目录

      root@99c6b59ff576:/tmp/ubuntu# ls
      a.txt  b.txt  c.txt
      root@99c6b59ff576:/tmp/ubuntu# 
      
  3. 测试2:

    • 容器写d.txt(发现不能写,只读)

      root@99c6b59ff576:/tmp/ubuntu# touch d.txt
      touch: cannot touch 'd.txt': Read-only file system
      root@99c6b59ff576:/tmp/ubuntu# 
      
卷的继承和共享
  1. 容器1完成和宿主机的卷映射

    docker run -it --name="ubuntu-j2" --privileged=true -v /dockerbackup/ubuntu:/tmp/ubuntu:ro f706429da9df /bin/bash

  2. 容器2继承容器1的卷规则

    docker run -it --name="ubuntu-j3" --privileged=true --volumes-from ubuntu-j2 f706429da9df /bin/bash

  3. 测试

    • 查看容器2信息

      [root@VM-4-9-centos ~]# docker ps
      CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS          PORTS                                                           NAMES
      30045c2c0dbd   f706429da9df          "/bin/bash"              29 seconds ago   Up 28 seconds                                                                   ubuntu-j3
      99c6b59ff576   f706429da9df          "/bin/bash"              14 minutes ago   Up 14 minutes                                                                   ubuntu-j2
      f5346aab9063   registry              "/entrypoint.sh /etc…"   7 hours ago      Up 3 hours      0.0.0.0:5000->5000/tcp, :::5000->5000/tcp                       ecstatic_goldwasser
      3bb8baf477a0   portainer/portainer   "/portainer"             2 days ago       Up 4 hours      8000/tcp, 9443/tcp, 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp   mystifying_knuth
      [root@VM-4-9-centos ~]# docker inspect 30045c2c0dbd
      ......
              "Mounts": [
                  {
                      "Type": "bind",
                      "Source": "/dockerbackup/ubuntu",
                      "Destination": "/tmp/ubuntu",
                      "Mode": "",
                      "RW": false,
                      "Propagation": "rprivate"
                  }
              ],
      ......
      [root@VM-4-9-centos ~]# 
      
    • 查看容器2内相应目录

      root@30045c2c0dbd:/# cd tmp/ubuntu/
      root@30045c2c0dbd:/tmp/ubuntu# ls
      a.txt  b.txt  c.txt
      root@30045c2c0dbd:/tmp/ubuntu# 
      
    • 宿主机写e.txt

      [root@VM-4-9-centos ubuntu]# pwd
      /dockerbackup/ubuntu
      [root@VM-4-9-centos ubuntu]# ls
      a.txt  b.txt  c.txt
      [root@VM-4-9-centos ubuntu]# touch e.txt
      [root@VM-4-9-centos ubuntu]# ls
      a.txt  b.txt  c.txt  e.txt
      [root@VM-4-9-centos ubuntu]# 
      
    • 查看容器2

      root@30045c2c0dbd:/tmp/ubuntu# ls
      a.txt  b.txt  c.txt  e.txt
      root@30045c2c0dbd:/tmp/ubuntu# 
      
    • 查看容器1

      root@99c6b59ff576:/tmp/ubuntu# ls
      a.txt  b.txt  c.txt  e.txt
      root@99c6b59ff576:/tmp/ubuntu# 
      

简单应用部署

1、部署MySQL
  1. 搜索mysql镜像
docker search mysql
  1. 拉取mysql镜像
docker pull mysql:5.7
  1. 创建容器,设置端口映射、目录映射
# 在/root目录下创建mysql目录用于存储mysql数据信息
mkdir ~/mysql
cd ~/mysql
docker run -id \
-p 3307:3306 \
--name=c_mysql \
--privileged=true \
-v $PWD/conf:/etc/mysql/conf.d \
-v $PWD/logs:/logs \
-v $PWD/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=admin \
mysql:5.7
  • 参数说明:
    • -p 3307:3306:将容器的 3306 端口映射到宿主机的 3307 端口。
    • -v $PWD/conf:/etc/mysql/conf.d:将主机当前目录下的 conf/my.cnf 挂载到容器的 /etc/mysql/my.cnf。配置目录
    • -v $PWD/logs:/logs:将主机当前目录下的 logs 目录挂载到容器的 /logs。日志目录
    • -v $PWD/data:/var/lib/mysql :将主机当前目录下的data目录挂载到容器的 /var/lib/mysql 。数据目录
    • **-e MYSQL_ROOT_PASSWORD=123456:**初始化 root 用户的密码。
  1. 进入容器,操作mysql
docker exec –it c_mysql /bin/bash
  1. 使用外部机器连接容器中的mysql

一起学docker(四)| 数据卷 + 简单应用部署(MySQL,Tomcat,Nginx,Redis)_第1张图片

中文乱码问题:

  1. 进入docker容器中的mysql查看编码SHOW VARIABLES LIKE 'character%';

    mysql> SHOW VARIABLES LIKE 'character%';
    +--------------------------+----------------------------+
    | Variable_name            | Value                      |
    +--------------------------+----------------------------+
    | character_set_client     | latin1                     |
    | character_set_connection | latin1                     |
    | character_set_database   | latin1                     |
    | character_set_filesystem | binary                     |
    | character_set_results    | latin1                     |
    | character_set_server     | latin1                     |
    | character_set_system     | utf8                       |
    | character_sets_dir       | /usr/share/mysql/charsets/ |
    +--------------------------+----------------------------+
    8 rows in set (0.00 sec)
    
    mysql> 
    
  2. character_set_client和character_set_database都是latin1编码,需将其改为utf-8,否则会引起中文乱码问题。

    • 通过容器卷同步配置给mysql容器实例

      [root@VM-4-9-centos conf]# pwd
      /root/mysql/conf
      [root@VM-4-9-centos conf]# vim my.cnf
      [root@VM-4-9-centos conf]# cat my.cnf
      [client]
      default_character_set=utf8
      [mysqld]
      collation_server = utf8_general_ci
      character_set_server = utf8
      [root@VM-4-9-centos conf]# 
      
    • 查看容器实例字符编码

      mysql> SHOW VARIABLES LIKE 'character%';
      +--------------------------+----------------------------+
      | Variable_name            | Value                      |
      +--------------------------+----------------------------+
      | character_set_client     | utf8                       |
      | character_set_connection | utf8                       |
      | character_set_database   | utf8                       |
      | character_set_filesystem | binary                     |
      | character_set_results    | utf8                       |
      | character_set_server     | utf8                       |
      | character_set_system     | utf8                       |
      | character_sets_dir       | /usr/share/mysql/charsets/ |
      +--------------------------+----------------------------+
      8 rows in set (0.00 sec)
      
      mysql> 
      
2、部署Tomcat

最新版首页需修改,可以使用8版本:

docker pull billygoo/tomcat8-jdk8

docker run -d -p 8080:8080 --name mytomcat8 billygoo/tomcat8-jdk8

最新版:

  1. 搜索tomcat镜像
docker search tomcat
  1. 拉取tomcat镜像
docker pull tomcat
  1. 创建容器,设置端口映射、目录映射
# 在/root目录下创建tomcat目录用于存储tomcat数据信息
mkdir ~/tomcat
cd ~/tomcat
docker run -id --name=c_tomcat \
-p 8080:8080 \
-v $PWD:/usr/local/tomcat/webapps \
tomcat 
  • 参数说明:

    • **-p 8080:8080:**将容器的8080端口映射到主机的8080端口

      **-v $PWD:/usr/local/tomcat/webapps:**将主机中当前目录挂载到容器的webapps

  1. 使用外部机器访问tomcat

一起学docker(四)| 数据卷 + 简单应用部署(MySQL,Tomcat,Nginx,Redis)_第2张图片

3、部署Nginx
  1. 搜索nginx镜像
docker search nginx
  1. 拉取nginx镜像
docker pull nginx
  1. 创建容器,设置端口映射、目录映射
# 在/root目录下创建nginx目录用于存储nginx数据信息
mkdir ~/nginx
cd ~/nginx
mkdir conf
cd conf
# 在~/nginx/conf/下创建nginx.conf文件,粘贴下面内容
vim nginx.conf
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}


docker run -id --name=c_nginx \
-p 80:80 \
-v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf \
-v $PWD/logs:/var/log/nginx \
-v $PWD/html:/usr/share/nginx/html \
nginx
  • 参数说明:
    • -p 80:80:将容器的 80端口映射到宿主机的 80 端口。
    • -v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf:将主机当前目录下的 /conf/nginx.conf 挂载到容器的 :/etc/nginx/nginx.conf。配置目录
    • -v $PWD/logs:/var/log/nginx:将主机当前目录下的 logs 目录挂载到容器的/var/log/nginx。日志目录
  1. 使用外部机器访问nginx

一起学docker(四)| 数据卷 + 简单应用部署(MySQL,Tomcat,Nginx,Redis)_第3张图片

4、部署Redis
  1. 搜索redis镜像
docker search redis
  1. 拉取redis镜像
docker pull redis:6.0.8
  1. 创建容器,置端口映射、目录映射
# 在/app目录下创建redis目录用于存储redis数据信息
mkdir -p /app/redis
cd /app/redis

# 将一份redis.conf文件模板拷贝到宿主机挂载目录下,并修改一些配置
[root@VM-4-9-centos redis]# pwd
/app/redis
[root@VM-4-9-centos redis]# ls
redis.conf
[root@VM-4-9-centos redis]# vim redis.conf 

# 开启登录验证 可选
requirepass 123

# 允许redis外地连接  必须
# 注释掉 bind 127.0.0.1

# 将daemonize yes注释起来或者 daemonize no设置,因为该配置和docker run中-d参数冲突,会导致容器一直启动失败
daemonize no

# 开启aof 可选
appendonly yes
docker run -d \
-p 6380:6379 \
--name myredis \
--privileged=true \
-v /app/redis/redis.conf:/etc/redis/redis.conf \
-v /app/redis/data:/data \
redis:6.0.8 redis-server /etc/redis/redis.conf
  1. 使用外部机器连接redis
./redis-cli.exe -h 121.4.126.115 -p 6380

你可能感兴趣的:(docker,docker,mysql,tomcat,redis)