Docker_学习记录2

本篇随笔为Docker学习记录(2),所有内容均参考尚硅谷Docker实战教程以及云原生开发


安装mysql主从复制

  1. 新建主服务器容器实例3307

    docker run -p 3307:3306 \
    		   --name mysql-master \
    		   --privileged=true \
    		   -v /yiran/mysql-master/log:/var/log/mysql \
    		   -v /yiran/mysql-master/data:/var/lib/mysql \
    		   -v /yiran/mysql-master/conf:/etc/mysql/conf.d \
    		   -e MYSQL_ROOT_PASSWORD=root \
    		   -d mysql:5.7
    

    image

  2. 进入/mydata/mysqI--master/conf目录下新建配置文件,my.cnf
    image

  3. 修改完配置,重启mysql-master实例 docker restart mysql-master

  4. 进入 mysql-master 容器
    image

  5. master容器实例内创建数据同步用户

    1. 创建用户:create user 'slave'@'%' identified by '123456';
    2. 用户授权:grant replication slave, replication client on *.* to 'slave'@'%';
  6. 新建主服务器容器实例3308
    image

  7. 进入/mydata/mysq-slave/conf目录下新建my.cnf

  8. 修改完配置后重启slave实例docker restart mysql-slave

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

  10. 进入mysql--slave容器
    image

  11. 在从数据库中配置主从复制
    change master to master_host='192.168.38.128',master_user='slave',master_password='123456',master_port=3307,master_log_file='mall-mysql-bin.000001',master_log_pos=154,master_connect_retry=30;
    image

  12. 在从数据库中查看主从同步状态
    show slave status \G;
    image

  13. 在从数据库中开启主从同步
    start slave;

  14. 查看从数据库状态,发现已经同步
    show slave status \G;
    image

  15. 主从复制测试
    image




分布式存储

问题引入

12亿条数据需要缓存,请问如何设计这个存储案例?答:采用分布式存储

分布式存储的3种哈希方式:

  • 哈希取余分区
  • 一致性哈希算法分区
  • 哈希槽分区

哈希取余

image.png
优点:分而治之+分布均衡
缺点:由于余数确定,扩容或缩容(故障)后,需要重新确定余数,哈希规则需要重新确定

一致性哈希算法

算法背景:一致性哈希算法在1997年由麻省理工学院中提出的,设计目标是为了解决分布式缓存数据交动和映射问题,某个机器宕机了,分母数量改变了,自然取余数不OK了。

实现思路

  1. 算法构建一致性哈希
  2. 服务器IP节点映射

image.png

  1. key落到哈希环上,向前走落到服务器上

优缺点
优点:容错性(一台宕机,只影响下一台机器),扩张性(方便扩张,不需要重新计算哈希)
缺点:数据倾斜(可引入虚拟节点来解决,参考ScyllaDB的设计原则)

哈希槽分区

  1. 为什么出现?

解决一致性哈希算法的数据倾斜问题
哈希槽实质是一个数组,数组[0 , 2^14 -1]形成的hash slot空间。

  1. 能干什么?

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

  1. 深入理解:

解决的是粒度问题,相当于把粒度变大了,便于数据移动。
哈希解决的是映射问题,使用key的哈希值来计算所在的槽,便于数据分配。

  1. 多少个hash槽

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

案例:3主3从Redis集群配置

操作步骤:

  1. 关闭防火墙+启动docker后台服务
  2. 新建6个docker容器实例
  3. 进入容器redis-node-1,并为6台机器构建集群关系
  4. 链接进入6381作为切入点,查看集群状态

image.png

新建6个docker容器实例:命令分步解释

# 启动第1台节点
# --net host 使用宿主机的IP和端口,默认
# --cluster-enabled yes 开启redis集群
# --appendonly yes 开启redis持久化
# --port 6381 配置redis端口号
docker run -d --name redis-node-1 --net host --privileged=true -v /app/redis-cluster/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381

# 启动第2台节点
docker run -d --name redis-node-2 --net host --privileged=true -v /app/redis-cluster/share/redis-node-2:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382

# 启动第3台节点
docker run -d --name redis-node-3 --net host --privileged=true -v /app/redis-cluster/share/redis-node-3:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383

# 启动第4台节点
docker run -d --name redis-node-4 --net host --privileged=true -v /app/redis-cluster/share/redis-node-4:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384

# 启动第5台节点
docker run -d --name redis-node-5 --net host --privileged=true -v /app/redis-cluster/share/redis-node-5:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385

# 启动第6台节点
docker run -d --name redis-node-6 --net host --privileged=true -v /app/redis-cluster/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386

image.png

构建主从关系

  1. 进入redis-node-01:docker exec -it redis-node-1 /bin/bash
  2. 构建主从关系: redis-cli --cluster create 192.168.xxx.xxx:6381 192.168.xxx.xxx:6382 192.168.xxx.xxx:6383 192.168.xxx.xxx:6384 192.168.xxx.xxx:6385 192.168.xxx.xxx:6386 --cluster-replicas 1

image.png
自动分配主从服务器:6381-6384;6382-6385;6383-6386
image.png

查看集群状态

  1. 进入redis-node-1,使用redis-cli连接到6381节点:redis-cli -p 6381
  2. 查看cluster信息:cluster info

image.png

  1. 查看cluster中Node信息:cluster nodes

image.png

案例:主从容错切换迁移

image.png

数据读写存储

image.png

  1. 以单机的方式进行启动redis-cli -p 6381

image.png
set k1 v1后,报错:需要跳转到 12706 6386上上

  1. 以集群的方式进行启动redis-cli -p 6381 -c

image.png
成功:redirected - 重定向到slot[12706] -- 12706对应6386机器

  1. 进入redis的docker容器,redis-cli --cluster check IP地址:端口号查询当前集群的信息

image.png

容错切换迁移:测试主机宕机后,从机能否正常工作

image.png

  1. 主机6381停机,模拟宕机场景

image.png

  1. docker 进入redis-node-2,查看集群信息,发现6381 slave, fail

image.png

  1. 还原原来宕机的机器,宕机前:主机 --》 恢复后:从机

image.png

案例:主从扩容/缩容

主从扩容(3主3从 --> 4主4从)

需求:Redis集群,增加6387(主)和6388(从),变为4主4从

  1. 新建6387,6388两个节点+新建后启动+查看是否有8个节点
# 新建6387以及6388节点
# 6387
docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/share/redis-node-7:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6387

# 6388
docker run -d --name redis-node-8 --net host --privileged=true -v /data/redis/share/redis-node-8:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6388

image.png

  1. 进入6387容器实例内部 docker exec -it redis-node-7 /bin/bash
  2. 将新增的6387节点(空槽号)作为master节点加入原集群

redis-cli --cluster add-node 192.168.38.128:6387 192.168.38.128:6381
image.png

  1. 检查集群情况(第1次)redis-cli --cluster check 192.168.38.128:6381

image.png
加入集群,未分配哈希槽,未分配从机

  1. 重新分派槽号 redis-cli --cluster reshard 192.168.38.130:6381
  • 输入给6387分配多少slot槽
    • image.png
  • 输入接收这些槽位的节点ID,即6387的ID
    • image.png
    • image.png
  1. 检查集群情况(第2次)redis-cli --cluster check 192.168.38.128:6381
  • 分配4096个槽给6387
    • image.png
  • 三个主机每个匀一部分给6387
    • image.png
    • 优点:对原先的节点影响较小
  1. 为主节点6387分配从节点6388
  • redis-cli --cluster add-node 192.168.38.128:6388 192.168.38.128:6387 --cluster-slave --cluster-master-id 0fd50de894dfc8eab1f53124444c6a8b912b1f23(6387的ID)
  • image.png
  1. 检查集群情况(第3次)redis-cli --cluster check 192.168.38.128:6381
  • 主:6387 -- 从:6388
  • image.png
  • image.png

主从缩容

需求:Redis集群,删除6387和6388(6387和6388下线),恢复3主3从

  1. 检查集群情况1获得6388的节点id
  • redis-cli --cluster check 192.168.38.128:6381
  • image.png
  1. 将6388删除,从集群中将4号从节点6388删除
  • redis-cli --cluster del-node 192.168.38.128:6388 8d6caf02849b6c0087296c5e7e013fa0b129972f(6388的ID)
  • image.png
  1. 将6387的槽号清空,重新分配,本例将清出来的槽号都给6384
  • 集群重新分配槽位
  • redis-cli --cluster reshard 192.168.38.128:6381
  • image.png
  • 移动4096个槽位 -- 谁接收槽位(6384的ID) -- 从何处来(6387的槽位)
  1. 检查集群情况第二次
  • image.png
  • 6384的槽位从原先的4096变为8192(4096+分配的4096)
  1. 将6387删除
  • redis-cli --cluster del-node 192.168.38.128:6387 0fd50de894dfc8eab1f53124444c6a8b912b1f23(6387的ID)
  • image.png
  1. 检查集群情况第三次
  • image.png



是什么?

定义

Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。
image.png
image.png

构建步骤:

编写Dockerfile -- docker build构建镜像 -- docker run 形成新的容器

DockersFile构建过程解析

  1. DockerFile内容基础知识:
  • 每条保留字指令都必须为大写字母,且后面要跟随至少一个参数
  • 指令按照从上到下,顺序执行
  • # 表示注释
  • 每条指令都会创建一个新的镜像层并对镜像进行提交
  1. Docker执行Dockerfile的大致流程
  • docker从基础镜像运行一个容器
  • 执行一条指令并对容器作出修改
  • 执行类似docker commit的操作提交一个新的镜像层
  • docker再基于刚提交的镜像,运行一·个新容器
  • 执行dockerfile中的下一条指令,直到所有指令都执行完成
  1. 总结
  • 从应用软件的角度看,Dockerfile是软件的原材料,Docker image 是软件的交付品,Docker container 是按照镜像运行的容器实例
  • image.png
  • Dockerfile:定义了进程需要的一切东西,涉及的内容包括代码、文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程……
  • Docker 镜像:在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行Dockert镜像时,会真正开始提供服务
  • Docker 容器:直接提供服务

DockerFile常用保留字指令

  • FROM:基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板
  • MAINTAINER:镜像维护者的姓名和邮箱地址
  • RUN:容器构建时需要运行的命令
    • shell格式:run <命令行工具>
# 等同于在终端操作的shell命令
# 格式:RUN <命令行命令>
RUN yum -y install vim
  • exec格式:RUN ["可执行文件", "arg1", "arg2", ……]
# 格式:RUN ["可执行文件" , "参数1", "参数2"]
RUN ["./test.php", "dev", "offline"]  # 等价于 RUN ./test.php dev offline
  • EXPOSE:向外暴漏的端口号,-p, -P
  • WORKDIR:指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点
  • USER:指定该镜像以什么样的用户去执行,如果都不指定,默认是root
  • ENV:用来在构建镜像过程中设置环境变量【可理解为全局变量】
    • image.png
  • ADD:将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包【COPY+tar解压】
  • COPY:类似于 docker cp
  • VOLUME:容器数据卷
  • CMD:指定容器启动后的要干的事情
# CMD 指令的格式和 RUN 相似,也是两种格式:
# shell格式:
CMD <命令>

# exec格式:
CMD["可执行文件","参数1","参数2"...]

# 参数列表格式:CMD["可执行文件","参数1","参数2"...]
# 若制定了ENTRYPOINT指令,则用CMD指定具体参数
  • 注意:Dockerfile中可以有多个CMD指令但只有最后一个生效,CMD会被docker run之后的参数替换
# Dockerfile
EXPOSE 8080
CMD ["catalina.sh", "run"]

# 执行时
docker run -it -p 8080:8080 imageID /bin/bash

# 相当于替换CMD["catalina.sh", "run"] --> CMD["/bin/bash", "run"]
  • 与RUN命令的区别:CMD在docker run时运行,RUN在docker build时运行
  • ENTRYPOINT:也是用来指定一个容器启动时要运行的命令
    • 类似于CMD指令,但是ENTRYPOINT不会被docker run后面的命令覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序
    • 命令格式:ENTRYPOINT["<executable>", "<parael1>", "<parael2>", ……]
    • ENTRYPOINT 与 CMD 命令一起使用时,相当于CMD给ENTRYPOINT传参,等价于 ""
    • 案例:image.png

Dockerfile构建案例

构建自定义镜像 my_centos_java8

  1. 从dockerhub上获取centos,并启动

image.png

  1. 新建/myfile,在该目录下,下载jdk-8u191-linux-x64.tar.gz

image.png
wget https://mirrors.yangxingzhen.com/jdk/jdk-8u191-linux-x64.tar.gz

  1. 新建Dockerfile:vim Dockerfile
FROM ubuntu
MAINTAINER lee<lee@xxx.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH

RUN apt-get update
RUN apt-get install net-tools

EXPOSE 80

CMD echo $MYPATH
CMD echo "install ifconfig cmd into ubuntu success ....."
CMD /bin/bash
  1. 构建 docker build -t ubuntu:1.0.1 .
    image.png

  2. 运行 docker run ubuntu:1.0.1

虚悬镜像

仓库名、标签名都是 的镜像,称为 dangling images(虚悬镜像)。
在构建或者删除镜像时可能由于一些错误导致出现虚悬镜像。

# 列出docker中的虚悬镜像:
docker image ls -f dangling=true

# 虚悬镜像一般是因为一些错误而出现的,没有存在价值,可以删除:
# 删除所有的虚悬镜像
docker image prune

总结

image.png




Docker微服务

【待补充】




Docker网络

虚拟网桥 virbr0

  • 在cenos7的安装过程中如果有选择相关虚拟化的服务安装系统后,启动网卡时会发现有一个以网桥连接的私网地址的virbr0网卡(virbr0网卡:它还有一个固定的默认IP地址192.168.122.1),是做虚拟机网桥使用的。其作用是为连接其上的虚拟网卡提供NAT访同外网的功能。
  • 我们之前学习linux安装,勾选安装系统的时候附带了libvirt服务才会生成的一个东西,如果不需要可以直接将libvirt服务卸载yum remove libvirt-libs.x86_64
  • 启动docker后,另外会出现一个虚拟网桥docker0

常用命令

  1. 查看docker网络模式docker network ls

image.png

  1. 创建 docker network create aa_network
  2. 删除 docker network rm aa_network

image.png

  1. 检查network的信息 docker network inspect bridge

image.png

network作用

  • 容器间的互联和通信以及端口映射
  • 容器IP变动时,可以通过服务名直接进行网络通信,不会受到影响

网络模式

总体介绍

网络模式 简介 命令
bridge 为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,默认为该模式。 --network bridge,默认使用docker0
host 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。 --network host
none 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair和网桥连接,IP等。 --network none
container 新创建的容器不会创建自己的网卡和配置自己的IP,而是和一个指定的容器共享IP、端口范围等。 --network container:NAME或容器ID

容器实例内默认网络IP生产规则

docker容器内部的 IP 会发生变化【一个容器宕机了,IP 会进行回收,以便下一次重新分配】

Bridge模式

image.png

host模式

image.png

none模式

禁用网络功能。
none模式下,并不为docker容器进行任何网络配置。进入容器内,使用ip addr查看网卡信息,只能看到lo(本地回环网络127.0.0.1网卡)。

container模式

image.png

自定义网络

集群环境下,多台docker容器,需要自定义网络

  • ping IP地址(能通,但IP地址可能变化)
  • ping 容器名(推荐)



Docker-compose容器编排

是什么?

Compose是Docker公司推出的一个工具软件,可以管理多个Docker容器组成一个应用,你需要定义一个YAML格式的配置文件docker-compose.yml,写好多个容器之间的调用关系。然后,只要一个命令,就能同时启动/关闭这些容器

image.png

docker-compose的作用

  • docker 资源占用少,如果需要同时部署好多个服务,针对每个服务单独写Dockerfile,再构建?
    • 操作繁琐,麻烦 --》 docker compose多服务部署
  • Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML格式)来定义一组相关联的应用容器为一个项目(project)。
  • Docker-compose解决了容器与容器之间如何管理编排的问题

下载

参考官网Install Compose standalone操作步骤:
curl -SL [https://github.com/docker/compose/releases/download/v2.24.6/docker-compose-linux-x86_64](https://github.com/docker/compose/releases/download/v2.24.6/docker-compose-linux-x86_64) -o /usr/local/bin/docker-compose

compose核心概念

一个文件:docker-compose.yml
两个要素:

  • 服务(service):一个个应用容器实例,比如订单微服务、库存微服务、mysql容器
  • 工程(project):由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml文件中定义。

使用docker-compose的三个基本步骤

  1. 编写Dockerfile定义各个微服务应用并构建出对应的镜像文件
  2. 使用docker-compose.yml,定义一个完整业务单元,安排好整体应用中的各个容器服务
  3. 最后,执行docker-compose up命令来启动并运行整个应用程序,完成一键部署上线

Compose常用命令

image.png
关注:检查yaml配置文件,docker-compose config -q

Compose编排微服务

改造升级微服务工程docker_boot

【待补充】

不使用compose

  1. 单独的mysql容器实例
    1. 新建mysql容器实例
    2. 进入mysql容器实例并新建库db01+新建表t_user
  2. 单独的redis容器实例
  3. 微服务工程
  4. 上面三个容器实例依次顺序启动成功
  5. swagger测试:http://localhost:服务端口/swagger-ui.html#/

出现了哪些问题?

  • 先后顺序要求固定,先启动mysql,再启动redis,最后启动微服务
  • 多个run命令……
  • 容器间的启停或宕机,有可能导致 IP 地址对应的容器实例变化,映射出错,要么生产 IP 写死(可以但是不推荐),要么通过服务调用

image.png

使用Compose

image.png




Docker容器的监控与统计

轻量级监控工具

查看当前docker的状态:docker system df

Portainer是一款轻量级的应用,它提供了图形化界面,用于方便地管理Docker环境,包括单机环境和集群环境。

安装:www.potainer.io
image.png

复杂监控工具

原生命令

操作:docker status
问题:通过docker stats命令可以很方便的看到当前宿主机上所有容器的CPU,内存以及网络流量等数据,一般小公司够用了…… 但是,docker stats统计结果只能是当前宿主机的全部容器,数据资料是实时的,没有地方存储、没有指标预警等功能

作用

容器监控:CAdvisor监控收集+InfluxDB存储数据+Granfana展示图表
image.png

compose容器编排

# 新建目录
mkdir cig

# 新建yaml文件
vim docker-compose.yml

# 检查yaml文件
docker-compose config -q

# 启动docker-compose
docker-compose up

# 查看三个服务容器是否启动
docker ps

# 测试
# 浏览CAdvisor收集服务,http://ip:8080/
# 浏览Influxdb存储服务,http://ip:8083/
# 浏览Grafana展现服务,http://ip:3000
posted @ 2024-02-27 16:14  是你亦然  阅读(1)  评论(0编辑  收藏  举报