五.docker环境搭建实例

五.docker环境搭建实例

一个docker的常用命令文档:
https://blog.csdn.net/qq_45392321/article/details/124218816

安装步骤:

  • 搜索镜像
  • 拉取镜像
  • 查看镜像
  • 启动镜像-服务端口映射
  • 停止容器
  • 移除容器

1.安装tomcat

  1. docker hub上查找tomcat镜像(目前中国由于网络限制不可访问)

    bash 复制代码
    docker search tomcat
  2. 拉取tomcat镜像到本地

    bash 复制代码
    docker pull tomcat
  3. 查看镜像

    bash 复制代码
    docker images
  4. 通过镜像创建实例

    bash 复制代码
    docker run -it -p 8080:8080 tomcat 退出就停止
    docker run -d -p 8080:8080 tomcat 后台运行

    -p小写,主机端口:docker容器端口

    -P大写,随机分配端口

    -i:交互

    t:终端

    d:后台

  5. 访问

    解决

    • 端口未映射或未开通端口防火墙

    • 将webapps.dist重命名为webapps

      后台运行镜像:

      bash 复制代码
      docker run -d -p 8080:8080 tomcat

      进入容器终端交互:

      bash 复制代码
      docker exec -it 10cb17c6b899 /bin/bash

      替换:

      重新访问:

    为什么docker中tomcat需要执行mv webapps.dist webapps后才可正常访问?

    官方 Tomcat Docker 镜像为了安全和灵活性,默认情况下:

    webapps(用作部署应用的目录) 目录是空的,

    实际的示例应用放在 webapps.dist 目录中,

    这样做是为了避免默认部署不必要的应用

2.jdk安装

  1. 在oracle官网下载对应jdk的Linux版本:jdk-8-linux-x64.tar.gz
    https://www.oracle.com/java/technologies/downloads/

  2. 通过secureCRT工具连上服务器,创建/root/programme/docker/jdk目录并上传下载好的jdk

    mkdir jdk 创建jdk文件夹

    rz 上传本地文件到服务器

  3. 在上传的jdk文件同级目录创建Dockerfile

    vim Dockerfile 创建文件并编辑

    bash 复制代码
    FROM centos:7
    #2、指明该镜像的作者
    MAINTAINER liumingyong
    #3、在构建镜像时,指定镜像的工作目录,之后的命令都是基于此工作目录,如果不存在,则会创建目录  
    RUN mkdir -p /root/programme/jdk
    WORKDIR /root/programme/jdk
    #4、一个复制命令,把jdk安装文件复制到镜像中,语法 ADD SRC DEST ,ADD命令具有自动解压功能   
    ADD jdk-8-linux-x64.tar.gz /root/programme/jdk
    #5、配置环境变量,此处目录为tar.gz包解压后的名称,需提前解压知晓:    
    ENV JAVA_HOME=/root/programme/jdk/jdk1.8.0_301
    ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV PATH=$JAVA_HOME/bin:$PATH
    #6、设置启动命令     
    CMD ["java","-version"]
  4. 构建jdk1.8的镜像

    docker build -t jdk:jdk1.8 . 构建jdk镜像

    注意:

    • 构建jdk镜像docker build -t jdk1.8 .
      若在Dockerfile文件所在目录执行则后面需要有一个点(.),否则要跟Dockerfile所在路径
  5. 查看镜像文件是否构建成功

    docker images

  6. 通过镜像构建容器并后台启动,run具备create和start的功能。

    bash 复制代码
    docker run -itd --name jdk_container jdk:jdk1.8 /bin/bash
  7. 查看已运行容器列表

    docker ps -a

  8. 查看jdk在容器内部是否生效,需进入容器内部执行

    bash 复制代码
    docker exec -it 77b1b05ca0bc /bin/bash

    到此jdk就安装好了!

3.mysql安装主从复制

  1. 直接用docker拉去镜像

    bash 复制代码
    docker pull mysql:8.0.11      #写版本号,则拉取确定的版本,不写则最新
  2. 查看拉取的镜像

    bash 复制代码
    docker images              #查看当前所有的镜像
  3. 通过镜像构建容器并后台启动

    bash 复制代码
    docker run -d -p 3307:3306 --privileged=true --name mysql-master -v /usr/local/docker/mysql/log:/var/log/mysql -v /usr/local/docker/mysql/data:/var/lib/mysql -v /usr/local/docker/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root --restart=on-failure:5 mysql:8.0.11


    注意:

    a) 命令执行时在一行执行,否则多行执行可能会有空格执行失败

    b) /usr/local/docker/mysql/conf:/etc/mysql 适用于mysql低版本镜像

    /usr/local/docker/mysql/conf:/etc/mysql/conf.d 适用于mysql高版本镜像

    因为mysql8.0以上的配置位置在 /etc/mysql/conf.d

    markup 复制代码
    docker run:在docker中启动一个容器实例
    -d:该容器在后台运行
    -p 3306:3306:容器与主机映射端口为,主机3306,容器3306
    --privileged=true:开启在容器中拥有root权限
    --name mysql:容器运行后的名称
    -v /root/programme/mysql/log:/var/log/mysql:将容器/var/log/mysql目录下的数据,备份到主机的 /root/programme/mysql/log目录下
    -v /root/programme/mysql/data:/var/lib/mysql:将容器/var/lib/mysql目录下的数据,备份到主机的 /root/programme/mysql/data目录下
    -v /root/programme/mysql/conf:/etc/mysql/conf.d:将容器/etc/mysql/conf.d目录下的数据,备份到主机的 /root/programme/mysql/conf目录下
    -e MYSQL_ROOT_PASSWORD=root:设置当前mysql实例的密码为root
    mysql:8.0.11:需要运行的容器名称以及版本号
  4. 切换到上述命令配置的主机/usr/local/docker/mysql/conf下创建 my.cnf文件

    bash 复制代码
    cd /usr/local/docker/mysql/conf
    vim  my.cnf

    my.cnf内容:在docker中安装的mysql默认字符集是latin1,需要改成utf8

    bash 复制代码
    [client]
    default_character_set=utf8
    [mysqld]
    # 监听所有网络接口,允许来自任何 IP 地址的连接
    bind-address = 0.0.0.0
    collation_server = utf8_general_ci
    character_set_server = utf8
    ## 设置server_id,同一局域网中需要唯一
    server_id=101 
    ## 指定不需要同步的数据库名称
    binlog-ignore-db=mysql  
    ## 开启二进制日志功能
    log-bin=mall-mysql-bin  
    ## 设置二进制日志使用内存大小(事务)
    binlog_cache_size=1M  
    ## 设置使用的二进制日志格式(mixed,statement,row)
    binlog_format=mixed  
    ## 二进制日志过期清理时间。默认值为0,表示不自动清理。
    expire_logs_days=7  
    ## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
    ## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
    slave_skip_errors=1062
  5. 重启mysql容器实例,让刚才的配置文件生效

    bash 复制代码
    docker restart  mysql-master
  6. 查看mysql容器是否成功正常运行

    bash 复制代码
    docker ps -a
  7. 进入mysql-master容器

    bash 复制代码
    docker exec -it mysql-master /bin/bash
    mysql -uroot -proot
  8. master容器创建的用户可以用于MySQL主从复制配置中的从服务器连接

    bash 复制代码
    # 创建用户并使用强密码
    CREATE USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
    # 授予复制相关权限
    GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
    # 刷新权限使设置生效
    FLUSH PRIVILEGES;
  9. 新建从服务器容器实例3308

    bash 复制代码
    docker run -d -p 3308:3306 --privileged=true --name mysql-slave -v /usr/local/docker/mysql-slave/log:/var/log/mysql -v /usr/local/docker/mysql-slave/data:/var/lib/mysql -v /usr/local/docker/mysql-slave/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root --restart=on-failure:5 mysql:8.0.11
  10. 进入/usr/local/docker/mysql-slave/conf创建my.cnf

    bash 复制代码
    [client]
    default_character_set=utf8
    [mysqld]
    collation_server = utf8_general_ci
    character_set_server = utf8
    ## 设置server_id,同一局域网中需要唯一
    server_id=102
    ## 指定不需要同步的数据库名称
    binlog-ignore-db=mysql  
    ## 开启二进制日志功能,以备Slave作为其它数据库实例的Master时使用
    log-bin=mall-mysql-slave1-bin  
    ## 设置二进制日志使用内存大小(事务)
    binlog_cache_size=1M  
    ## 设置使用的二进制日志格式(mixed,statement,row)
    binlog_format=mixed  
    ## 二进制日志过期清理时间。默认值为0,表示不自动清理。
    expire_logs_days=7  
    ## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
    ## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
    slave_skip_errors=1062  
    ## relay_log配置中继日志
    relay_log=mall-mysql-relay-bin  
    ## log_slave_updates表示slave将复制事件写进自己的二进制日志
    log_slave_updates=1  
    ## slave设置为只读(具有super权限的用户除外)
    read_only=1
    # 添加以下行以解决认证问题
    default_authentication_plugin=mysql_native_password
  11. 重启slave实例

    bash 复制代码
    docker restart mysql-slave
  12. 进入master数据库查看主从同步状态

    bash 复制代码
    show master status;
  13. 进入mysql-slave容器

    bash 复制代码
    docker exec -it mysql-slave /bin/bash
    mysql -uroot -proot
  14. 在从数据库中配置主从复制

    bash 复制代码
    change master to master_host='192.168.31.30', master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-bin.000003', master_log_pos=155, master_connect_retry=30;

    主从复制命令参数说明:

    master_host:主数据库的IP地址,一定要是宿主机ip;

    master_port:主数据库的运行端口;

    master_user:在主数据库创建的用于同步数据的用户账号;

    master_password:在主数据库创建的用于同步数据的用户密码;

    master_log_file:指定从数据库要复制数据的日志文件,通过查看主数据的状态,获取File参数;

    master_log_pos:指定从数据库从哪个位置开始复制数据,通过查看主数据的状态,获取Position参数;

    master_connect_retry:连接失败重试的时间间隔,单位为秒。

  15. 在从数据库中查看主从同步状态

    bash 复制代码
    show slave status \G
  16. 在从数据库中开启主从同步

    bash 复制代码
    start slave;

    再次查看从数据库状态发现已经同步

  17. 主从复制测试

    创建数据库:

    bash 复制代码
    CREATE DATABASE IF NOT EXISTS testdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

    使用库:use testdb;

    创建表

    数据插入

    主库查询

    从库查询

4.redis安装(集群模式)-哈希槽分区

1~2亿条数据需要缓存,如何设计这个存储案例?

---单机单台100%不可能,肯定是分布式存储,用redis如何落地?一般如下3种方法:

  • 哈希取余分区

    hash(key) % N个机器台数,计算出哈希值,用来决定数据映射到哪一个节点上。

    优点:

    简单粗暴,直接有效,只需要预估好数据规划好节点。每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡+分而治之的作用。

    缺点:

    原来规划好的节点,进行扩容或者缩容就比较麻烦。如果需要弹性扩容或故障停机的情况下,会导致hash取余全部数据重新洗牌。

  • 一致性Hash算法分区

    提出一致性Hash解决方案。目的是当服务器个数发生变动时,尽量减少影响客户端到服务器的映射关系

    一致性哈希算法必然有个hash函数并按照算法产生hash值,使这些hash值首尾相连逻辑上形成一个环形空间。把这个虚拟圆环称为Hash环。

    将集群中服务器的IP或主机名作为关键字进行哈希,这样每台机器就能确定其在哈希环上的位置。

    当我们需要存储一个kv键值对时,将这个key使用相同的函数Hash计算出哈希值并确定此数据在环上的位置,从此位置沿环顺时针"行走",第一台遇到的服务器就是其应该定位到的服务器。

    优点:

    i) 容错性

    如果一台服务器不可用,则受影响的数据仅仅是此服务器到其环空间中前一台服务器(即沿着逆时针方向行走遇到的第一台服务器)之间数据,其它不会受到影响。

    ii) 扩展性

    增加一台节点NodeX,X的位置在A和B之间,那收到影响的也就是A到X之间的数据,重新把A到X的数据录入到X上即可,不会导致hash取余全部数据重新洗牌。

    缺点:

    节点太少时,容易因为节点分布不均匀而造成数据倾斜(被缓存的对象大部分集中缓存在某一台服务器上)问题

  • 哈希槽分区

    哈希槽实质就是一个数组,数组[0,2^14 -1]形成hash slot空间。

    解决一致性哈希算法数据倾斜均匀分配的问题,在数据和节点之间又加入了一层,把这层称为哈希槽(slot),用于管理数据和节点之间的关系,现在就相当于节点上放的是槽,槽里放的是数据。

    一个集群只能有16384个槽,编号0-16383(0-2^14-1)。这些槽会分配给集群中的所有主节点,分配策略没有要求。可以指定哪些编号的槽分配给哪个主节点。redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。集群会记录节点和槽的对应关系。接下来就需要对key求哈希值,然后对16384取余,余数是几key就落入对应的槽里。以槽为单位移动数据,因为槽的数目是固定的,处理起来比较容易,这样数据移动问题就解决了。

    3主3从redis集群配置:

    1)镜像拉取

    bash 复制代码
    docker pull redis:6.2.14

    2)创建挂载目录及配置文件

    配置内容:不同节点只需改端口和集群配置文件名,集群中各个节点密码需一致

    bash 复制代码
    #端口
    port 6381
    #开启redis集群
    cluster-enabled yes
    #集群配置文件
    cluster-config-file nodes-6381.conf
    #节点超时时间(5秒)
    cluster-node-timeout 5000
    #开启持久化
    appendonly yes
    #客户端连接Redis时需要的密码
    requirepass 123456
    #从节点连接主节点时使用的密码
    masterauth 123456

    3)新建6个redis容器

    bash 复制代码
    # 启动6个节点容器
    docker run -d --name redis-node-1 --net host --privileged=true --restart=on-failure:5 -v /usr/local/docker/redis/redis-node-1:/data -v /usr/local/docker/redis/configs/redis-node1.conf:/usr/local/etc/redis/redis.conf redis:6.2.14 /usr/local/etc/redis/redis.conf

    4) 进入容器redis-node-1并为6个节点构建集群关系

    bash 复制代码
    docker exec -it redis-node-1 /bin/bash

    构建集群主从关系:

    bash 复制代码
    redis-cli --cluster create 192.168.31.30:6381 192.168.31.30:6382 192.168.31.30:6383 192.168.31.30:6384 192.168.31.30:6385 192.168.31.30:6386 --cluster-replicas 1 -a 123456

    --cluster-replicas 1 表示为每个master创建一个slave节点

    5)链接进入6381查看集群状态

    bash 复制代码
    redis-cli -p 6381 -a 123456
    cluster info
    cluster nodes

    6) 数据读写存储

    在 redis-cli 命令中,需加-c 参数开启集群模式自动路由

    因为是集群模式哈希槽分区,进入任意节点执行命令都会路由到相应节点

    查看集群信息:

    bash 复制代码
    redis-cli --cluster check 192.168.31.30:6381 -a 123456

    7) 主从容错切换迁移案例:

    初始节点状态

    bash 复制代码
    redis-cli -p 6382 -a 123456 -c
    cluster nodes

    主机6381和对应从机切换,先停止主机6381,对应从机6385将自动切换为主机

    bash 复制代码
    quit
    exit
    docker stop redis-node-1
    docker exec -it redis-node-2 /bin/bash
    redis-cli -p 6382 -a 123456 -c
    cluster nodes

    还原之前的3主3从

    先启6381,6381将成为6385从节点:

    bash 复制代码
    docker start redis-node-1

    再停6385,6381将重新变成主节点:

    bash 复制代码
    docker stop redis-node-5

    再启6385,6385将成为6381从节点:

    bash 复制代码
    docker start redis-node-5

    查看集群信息:

    bash 复制代码
    redis-cli --cluster check 192.168.31.30:6381 -a 123456

    8) 主从扩容案例

    新建6387、6388两个节点+新建后启动+查看是否8节点

    bash 复制代码
    docker run -d --name redis-node-7 --net host --privileged=true --restart=on-failure:5 -v /usr/local/docker/redis/redis-node-7:/data -v /usr/local/docker/redis/configs/redis-node7.conf:/usr/local/etc/redis/redis.conf redis:6.2.14 /usr/local/etc/redis/redis.conf
    bash 复制代码
    docker run -d --name redis-node-8 --net host --privileged=true --restart=on-failure:5 -v /usr/local/docker/redis/redis-node-8:/data -v /usr/local/docker/redis/configs/redis-node8.conf:/usr/local/etc/redis/redis.conf redis:6.2.14 /usr/local/etc/redis/redis.conf

    进入6837容器内部

    bash 复制代码
    docker exec -it redis-node-7 /bin/bash

    将新增的6387作为master节点加入集群

    命令:

    redis-cli --cluster add-node 实际IP地址:6387 实际IP地址:6381

    6387 就是将要作为master的新增节点端口

    6381 就是原来集群节点里面的任意节点端口

    bash 复制代码
    redis-cli --cluster add-node 192.168.31.30:6387 192.168.31.30:6381 -a 123456

    查看集群情况

    命令:redis-cli --cluster check 真实ip地址:6381

    bash 复制代码
    redis-cli --cluster check 192.168.31.30:6381 -a 123456

    重新分派槽位

    命令:redis-cli --cluster reshard IP地址:端口号

    bash 复制代码
    redis-cli --cluster reshard 192.168.31.30:6381 -a 123456

    查看集群情况

    命令:redis-cli --cluster check 真实ip地址:6381

    bash 复制代码
    redis-cli --cluster check 192.168.31.30:6381 -a 123456

    6387的槽位是3个新的区间,之前的还是连续的原因是:重新分配成本太高,将旧主节点槽位各自匀出来一部分给6387。之前在6381set的值也随槽位移动到6387了。

    为主节点6387分配从节点6388

    命令:redis-cli --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id 新主节点ID

    bash 复制代码
    redis-cli --cluster add-node 192.168.31.30:6388 192.168.31.30:6387 --cluster-slave --cluster-master-id 7500a80741403108f98eea7167a855c2a665f4c2 -a 123456

    查看集群情况

    命令:redis-cli --cluster check 真实ip地址:6381

    bash 复制代码
    redis-cli --cluster check 192.168.31.30:6381 -a 123456

    9) 主从缩容案例

    缩容即将主从节点下线,如6387,6388

    检查集群情况1获得6388的节点ID

    bash 复制代码
    redis-cli --cluster check 192.168.31.30:6382 -a 123456

    从集群中将从节点6388删除

    命令:redis-cli --cluster del-node ip:从机端口 从机6388节点ID

    bash 复制代码
    redis-cli --cluster del-node 192.168.31.30:6388 ef26aa0463455ac4d4fe6c64ce719e6b573d9cee -a 123456
    redis-cli --cluster check 192.168.31.30:6382 -a 123456

    将6387的槽位清空,重新分配,本例将清出来的槽号都给6381

    bash 复制代码
    redis-cli --cluster reshard 192.168.31.30:6381 -a 123456


    检查集群情况1获得6388的节点ID

    bash 复制代码
    redis-cli --cluster check 192.168.31.30:6382 -a 123456

    将6387删除

    命令:redis-cli --cluster del-node ip:端口 6387节点ID

    bash 复制代码
    redis-cli --cluster del-node 192.168.31.30:6387 7500a80741403108f98eea7167a855c2a665f4c2 -a 123456

    检查集群情况1获得6388的节点ID

    bash 复制代码
    redis-cli --cluster check 192.168.31.30:6382 -a 123456
相关推荐
凯子坚持 c16 小时前
Docker 容器实战:从镜像管理到私有仓库构建深度解析
java·docker·eureka
Radan小哥1 天前
Docker学习笔记—day007
笔记·学习·docker
howard20051 天前
Docker实战 - 将Web项目打成war包部署到tomcat容器里运行
docker·容器化部署web项目
p***c9491 天前
Docker机器学习实战
机器学习·docker·容器
pumpkin845141 天前
Docker 参考手册
chrome·docker·容器
三天不学习1 天前
GitLab Docker 安装完整配置项说明
docker·容器·gitlab
北冥有鱼被烹1 天前
【微知】Ubuntu中如何安装docker?
ubuntu·docker
幻灭行度1 天前
docker镜像导入到K8S的containerd中
java·docker·kubernetes
虎头金猫1 天前
随时随地处理图片文档!Reubah 加cpolar的实用体验
linux·运维·人工智能·python·docker·开源·visual studio
哈里谢顿2 天前
Docker 中快速启动 Prometheus + Grafana操作指南(二)
docker