文章目录

docker容器-基础篇

详见超详细docker基础教程(全)

docker容器-高级篇

1、docker复杂安装详说

1.1 mysql主从复制原理

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

拉取mysql镜像

docker pull mysql:5.7

运行MySQL到3307端口

docker run -p 3307:3306 --name mysql-master -v/mydata/mysql-master/log:/var/log/mysql -v/mydata/mysql-master/data:/var/lib/mysql -v /mydata/mysql-master/conf:/etc/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
2. 进入/mydata/mysql-master/conf 目录下新建配置
[mysqld]
## 设置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

3. 修改完配置后重启实例

重启后重新进入mysql数据库

docker restart mysql-master

4. 为容器实例内创建数据同步用户

mysql安全加固建立一个用户

CREATE USER 'slave'@'%' IDENTIFIED BY '123456';

授权

GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
5. 启动从数据 3308端口
docker run -p 3308:3306 --name mysql-slave -v /mydata/mysql-slave/log:/var/log/mysql -v /mydata/mysql-slave/data:/var/lib/mysql -v /mydata/mysql-slave/conf:/etc/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

按照之前配置主数据库的办法 配置从数据库

6. 在主数据库中查看主从数据库配置状态
docker exec -it mysql-master /bin/bash
mysql -uroot -proot
show master status;

7. 进入mysql-slave 容器 配置主从复制
# 进入容器
docker exec -it mysql-slave /bin/bash
mysql -uroot -proot

# 主从复制命令
change master to master_host='192.168.2.120', master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-slave1-bin.000001', master_log_pos=617, master_connect_retry=30;

主从复制命令参数说明

master host:主数据库的lP地址;
master port:主数据库的运行端口;
master user:在主数据库创建的用于同步数据的用户账号;
master_password:在主数据库创建的用于同步数据的用户密码:
master_Iog_ile:指定从数据库要复制数据的日志文件,通过查看主数据的状态,获取File参数;
master_log_pos:指定从数据库从哪个位置开始复制数据,通过查看主数据的状态,获取Position参数;
master_connect_retry:连接失败重试的时间间隔,单位为秒。

查看数据库主从同步状态

show slave status \G;

发现没有同步后、开启同步

start slave;

当俩个No 都变成yes后 表示配置成功(如果没有请修改从数据库的server_id、不让它和主数据库一样。然后重启容器实例) (出现Connecting的请查看防火墙是否关闭了)解决方案

8. 主从复制测试

在主机中新建表和 插入数据

查看从机上的数据、发现已经同步!

2、集群存储算法

2.1 分布式存储算法

分布式存储的常见算法:

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

1. 哈希取余算法

算法描述:hash(key) % N(其中,key是要存入Redis的键名,N是Redis集群的机器台数)。用户每次读写操作,都是根据传入的键名经过哈希运算,对机器台数取余决定该键存储在哪台服务器上。

优点:简单直接有效,只需要预估好数据规划好节点,就能保证一段时间的数据支撑。使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡+分而治之的作用。

缺点:原来规划好的节点,如果进行了扩容或者缩容,导致节点有变动,映射关系需要重新进行计算。在服务器个数固定不变时没问题,如果需要弹性扩容或者故障停机的情况下,原来取模公式中的 N就会发生变化,此时经过取模运算的结果就会发生很大变化,导致根据公式获取的服务器变得不可控。

2. 一致性哈希算法

算法背景:一致性哈希算法是为了解决哈希取余算法中的分布式缓存数据变动和映射问题。当服务器个数发生变化时,尽量减少影响到客户端与服务器的映射关系。

算法描述:

一致性哈希算法必然有个hash函数并按照算法产生Hash值,这个算法的所有可能哈希值会构成一个全量集,这个集合可以成为一个Hash区间[0, 2^32 - 1],这是一个线性空间。但是在这个算法中,我们通过适当的逻辑控制将它首尾相连(0 = 2^32),这样让它逻辑上形成了一个环形空间。

它也是按照使用取模的方式。前面的哈希取余算法是对节点个数进行取模,而一致性哈希算法是对 2^32取模。

简单来说,一致性Hash算法将整个哈希值空间组成一个虚拟的圆环。如假设某个哈希函数H的值空间为 0到2^32 - 1(即哈希值是一个32位无符号整形),整个哈希环如下图:整个空间按顺时针方向组织,圆环的正上方的点代表0,0点右侧的第一个点代表1,以此类推,2、3、4…直到2^32 - 1,也就是说0点左侧的第一个点代表 2^32 - 1。0 和 2^32 - 1在零点钟方向重合,我们把这个由 2^32个点组成的圆环称为Hash环。

hash01.jpg

有了哈希环之后,还需要进行节点映射,将集群中各个IP节点映射到环上的某一个位置。

将各个服务器使用Hash进行一个哈希,具体可以选择服务器的IP或主机名作为关键字进行哈希。这样每台机器就能确定其在哈希环上的位置。

假如4个节点NodeA、B、C、D,经过IP地址的哈希函数计算(hash(ip)),使用IP地址哈希值后在环空间的位置如下:

hash02.jpg

key落到服务器的落键规则。当我们需要存储一个key键值对时,首先计算key的hash值(hash(key)),将这个key使用相同的函数hash,计算出哈希值并确定此数据在环上的位置,从此位置沿环顺时针“行走”,第一台遇到的服务器就是其应该定位到的服务器,并将该键值对存储字该节点上。

假如我们有ObjectA、B、C、D四个数据对象,经过哈希计算后,在环空间上的位置如下:根据一致性hash算法,数据A会被定位到NodeA上,B被定位到NodeB上,C被定位到NodeC上,D被定位到NodeD上。

hash03.jpg

假设NodeC宕机,可以看到此时对象A、B、D不会受到影响,只有C对象被重新定位到NodeD。

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

即:假设NodeC宕机,只会影响到Hash定位到NodeB到NodeC之间的数据,并且这些数据会被转移到NodeD进行存储。

hash04.jpg

假如需要扩容增加一台节点NodeX,NodeX的hash(ip)位于NodeB和NodeC之间,那受到影响的就是NodeB 到 NodeX 之间的数据。重新将B到X的数据录入到X节点上即可,不会导致Hash取余全部数据重新洗牌的后果。

hash05.jpg

但是Hash环会存在数据倾斜问题。

一致性Hash算法在服务节点太少时,容易因为节点分布不均匀而造成数据倾斜(被缓存的对象都集中到某一台或某几台服务器)。

hash06.webp
为了解决数据倾斜问题,一致性哈希算法引入了虚拟节点机制。

对每一个服务节点计算多个哈希,每个计算结果位置都放置一个此服务节点,称为虚拟节点。具体做法可以先确定每个物理节点关联的虚拟节点数量,然后在IP或主机名后面加上编号。

例如,可以对NodeA节点虚拟出 NodeA#1、NodeA#2、NodeA#3,对NodeB虚拟出NodeB#1、NodeB#2、NodeB#3的节点,形成六个虚拟节点。

hash07.jpg

优点:加入和删除节点时,只会影响哈希环中顺时针方向相邻节点,对其他节点无影响。

缺点:数据的分布和节点的位置有关,因为这些节点不是均匀分布在哈希环上的,所以在数据进行存储时达不到均匀部分的效果。

3. 哈希槽分区

哈希槽分区是为了解决一致性哈希算法的数据倾斜问题。

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

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

slot01.png

槽解决的是粒度问题,相当于把粒度变大了,这样便于数据移动。

哈希解决的是映射问题,使用key的哈希值来计算所在的槽,便于数据分配。

一个集群只能有 16394个槽,编号 0 - 16383(2^14 - 1)。这些槽会分配给集群中所有的主节点,分配策略没有要求。可以指定哪些编号的槽分配给哪个主节点,集群会记录节点和槽的对应关系。

解决了节点和槽的关系后,接下来就需要对key求哈希值,然后对16384取余,根据余数决定key落到哪个槽里。

以槽为单位移动数据,因为槽的数目是固定的,处理起来比较容易,这样数据移动问题就解决了。

Redis集群存储策略

Redis集群使用的就是哈希槽。Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置在哪个槽,集群的每个节点负责一部分hash槽。

哈希槽数量16384(2^14)的决定原因:

CRC16算法产生的hash值有 16bit,该算法可以产生 2^16 = 65536个值。但是为了心跳方便和数据传输最大化,槽的数量只能有 2^14个。

1 如果槽位数量为65535个,那么发送心跳信息的消息头将达到 8k,发送的心跳包过于庞大。在消息头中最占空间的是 myslots[CLUSTER_SLOTS/8]。当槽位为65536时,这块的大小是 :
Plain Text复制代码165536 ÷ 8 ÷ 1024 = 8Kb
每秒中redis节点需要发送一定数量的ping消息作为心跳,如果槽位为65536,那么这个ping消息头就会太大浪费带宽。
2 redis集群的主节点数量基本不可能超过1000个。集群节点越多,心跳包的消息体内携带的数据越多。如果节点超过1000个,也会导致网络拥堵。因此redis作者不建议redis cluster节点超过1000个。对于节点数在1000以内的redis cluster集群,16384个槽位足够了,没有必要扩展到65536个。
3 槽位越小,节点少的情况下压缩比越高,容易传输。Redis主节点的配置信息中它锁负责的哈希槽是通过一张bitmap的形式来保存的,在传输过程中会对bitmap进行压缩,但是如果bitmap的填充率 slots / N(N为节点数)很高的话,bitmap的压缩率就很低。如果节点数很少,而哈希槽数很多的话,bitmap的压缩率就很低。

原文:

正常的心跳数据包带有节点的完整配置,使得可以用幂等方式用旧的节点替换旧节点,以便更新旧的配置。这意味着它们包含原始节点的插槽配置,该节点使用 2k 的空间和 16k 的插槽,而不是使用 8k 的空间(使用65k的插槽)。

同时,因为其他设计折衷,Redis集群的主节点不太可能扩展到1000个以上

Redis集群中内置了16384个哈希槽,redis会根据节点数量大致均等的将哈希槽映射到不同的节点。当需要在Redis集群中放置一个Key-Value时,redis先对key使用 CRC16 算法算出一个结果,然后把结果对 16384 取余,这样每个key都会对应一个编号在0-16383之间的哈希槽,也就是映射到某个节点上。

slot02.png

2.2 3主3从redis集群 -初始化配置

1. 新建6个容器实例

–cluster-enabled yes 开启集群

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

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

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

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

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

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

随便进入一台redis 服务器

docker exec -it redis-node-1 /bin/bash
2. 构建主从关系

// 注意,进入docker容器后才能执行一下命令,且注意自己的真实IP地址 (centos的ip)

redis-cli --cluster create 192.168.2.120:6381 192.168.2.120:6382 192.168.2.120:6383 192.168.2.120:6384 192.168.2.120:6385 192.168.2.120:6386 --cluster-replicas 1

输入命令以后、会让你输入yes or no 输入yes 当出现以下信息说明配置成功

从上图中可以看到、端口为6381、6382、6383的都是主端口,其余的是从端口。

3. 查看集群状态

进入redis 1

redis-cli -p 6381

查看分配情况

cluster info

查看主从关系

cluster nodes

通过上图信息可以知道 主从关系

M   S 
1   6
2   4
3   5

2.3 主从容错切换迁移

需求:主机宕机了、从机可以顶上

1. 数据读写存储

首先连接redis数据库 、进入集群 加上-c命令 优化路由

redis-cli -p 6381 -c

清空数据

FLUSHALL

新增key

set k1 v1

查看集群信息

redis-cli --cluster check 192.168.2.120:6381
2. 容错切换迁移

将6381 端口的redis 停止、重新查看reids存活情况、会发现原来redis1的从数据库变成了master、成为了主数据库、顶替了它的位置!

切换迁移

当我们将原来的redis镜像重新启动的时候、会发现它依旧是从数据库、无法回到主数据库。

这个时候我们需要按照想要的顺序进行停止容器、启动实例、让它们回到想要的主从关系中。

docker stop redis-node-1 
docker stop redis-node-6
docker start redis-node-1
docker start redis-node-6

2.4 主从扩容

当我们发现3主3从的数据库结构、无法满足现在所需求的数据量、需要添加新的主从数据库进来。

1. 新建6387、6388两个节点+新建后启动+查看是否8节点。
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

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

docker ps

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

4. 检查集群情况第1次
redis-cli --cluster check 192.168.2.120:6381

5. 重新分派槽号
redis-cli --cluster reshard 192.168.2.120:6381

显示准备分配多少给这个槽位 计算之后 发现 4096是平均数 输入 4096

随后显示要分配给谁的提示 输入该数据库的id号、在上图信息中有、一个未分配的数据库。

随后显示 输入all 全部分配

最后确认yes 即可以重新分配

6. 检查集群情况第2次
redis-cli --cluster check 192.168.2.120:6381

可以发现 第四个主数据库是从之前的三个数据库中分别匀出的一部分组成的4096个槽位

7. 为主节点6387分配从节点6388

reids-cli --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id

新主机节点ID

redis-cli --cluster add-node 192.168.2.120:6388 192.168.2.120:6387 --cluster-slave --cluster-master-id 2012a6e5adf0f18b3e37ee9edca64d27f761d0fb

8. 检查集群情况第3次
redis-cli --cluster check 192.168.2.120:6381

2.5 主从缩容

高峰期过了、想要继续恢复原来的三主三从数据结构、现在需要删除掉新增的6387和6388数据库。

1. 从集群中将4号从系欸但6388删除
redis-cli --cluster del-node 192.168.2.120:6388 a3b04e2e78c549ec4f68dde2737e8d9439379572

2. 将6387的槽号清空,重新分配,本例将清出来的槽号都给6381
redis-cli --cluster reshard 192.168.2.120:6381

按照之前的操作 重新分配槽位为 4096

3. 检查集群情况
redis-cli --cluster check 192.168.2.120:6381

4. 删除6387
redis-cli --cluster del-node 192.168.2.120:6387 2012a6e5adf0f18b3e37ee9edca64d27f761d0fb
5. 检查集群情况

3、DockerFile

Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。 因为随时变化、需要多次提交。我们想一次性搞定。

  • 官网 https://docs.docker.com/engine/reference/builder/
  • 构建三步
  • 编写Dockerfile文件
  • docker build命令构建镜像
  • docker run依镜像运行容器实例

dockerfile 是软件的原材料、docker镜像是软件的交付品、docker容器是部署与运维。

3.1 dockerfile保留字

  • FROM
    • 基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是from
  • MAINTAINER
    • 镜像维护作者的邮箱地址和姓名
  • RUN
    • 容器构建时需要运行的命令
    • 两种格式
      • shell格式
      • exec格式
    • run是在docker build时运行
  • EXPOSE
    • 当前容器对外暴露的端口
  • WORKDIR
    • 指定在创建容器后,终端默认的落脚点
  • USER
    • 指定该镜像以什么样的用户去执行,如果都不指定,默认是root
  • ENV
    • 用来在构建镜像过程中设置环境变量
  • ADD
    • 将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包
  • COPY
    • 类似add,拷贝文件和目录到镜像中。将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置
    • COPY src dest
    • COPY [“src”,“dest”]
    • <src源路径>:源文件或者源目录
    • <dest目标路径>:容器内的指定路径,该路径会自动创建。
  • VOLUME
    • 容器数据卷、用于数据保存和持久工作
  • CMD
    • 指定容器启动后要干的事情 (shell,exec)
    • dockerfile 中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换。
    • 它和前面RUN命令的区别
      • cmd 是在docker run时运行
      • run 是在docker build时运行
  • ENTRYPOINT
    • 也是用来指定一个容器启动时要运行的命令
    • 类似于CMD指令,但是ENTRYPOINT不会被docker run后面的命令覆盖,而且这些命令行参数会被当做参数送给ENTRYPOINT指令指定的程序

3.2 dockerfile 案例

1. 自定义镜像mycentosjava8

拉取centos镜像

docker pull centos

下载jdk镜像地址

linux版的任意一个 .tar.gz 压缩包

https://mirrors.yangxingzhen.com/jdk/
2. 编写

准备编写dockerfile文件 大写字母D

将下载好的包导入my file目录下

cd /
mkdir myfile
cd myfile
cp '/home/soupgod/下载/jdk-8u171-linux-x64.tar.gz' /myfile/
或者 使用 wget 直接下载url链接下的压缩包到该目录

自建docker file文件

vim Dockerfile

写入相关配置

FROM centos:7
MAINTAINER soupgod<940015073@qq.com>
 
ENV MYPATH /usr/local
WORKDIR $MYPATH
 
#安装vim编辑器
RUN yum -y install vim
#安装ifconfig命令查看网络IP
RUN yum -y install net-tools
#安装java8及lib库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
#ADD 是相对路径jar,把jdk-8u171-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置
ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
 
EXPOSE 80
 
CMD echo $MYPATH
CMD echo "success--------------ok"
CMD /bin/bash

3. 构建

docker build -t 新镜像名字:TAG .

注意:TAG后面有一个点

build -t centosjava8:1.5 .

进入镜像测试一波、发现功能可以正常使用

docker run -it de3c9744b7be /bin/bash

3.3 虚悬镜像

新建一个文件夹 存放配置文件

vim Dockerfile
rom ubuntu
CMD echo 'ation is success'

docker build .

发现出现了一个为的镜像。这个就是虚悬镜像。这种镜像是有问题的需要删除。

查看虚悬镜像

docker image ls -f dangling=true

删除虚悬镜像

docker image prune

4、docker微服务实战

4.1 通过IDEA新建一个普通微服务模块

演示案例:python flask 通过flask写一个简单的程序

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "hello world,端口号6001"

if __name__ == '__main__':
    app.run(host='0.0.0.0',port=6001)

通过网址localhost:6001 可以访问成功。第一步部署完成!

4.2 通过docker file发布微服务部署到docker容器

在当前目录中配置docker file文件 (记得先拉取python镜像 docker pull python:3.9)

# 基础镜像,python3.9
FROM python:3.9       
MAINTAINER Zhao    # 镜像作者信息
WORKDIR /app		   
# 工作目录,这个目录对应于镜像内的工作目录,后面的所有涉及到路径的操作都可以
# 使用WORKDIR的相对路径来指定

COPY requirements.txt requirements.txt  
# 拷贝requirements.txt 到 镜像中/app/requirements.txt  

RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# 安装pip包
COPY . . 
# 将当前文件中的目录复制到/app目录下

ENV FLASK_APP app 
# 设置环境变量,让flask run 命令能够找到启动文件的位置

CMD ["python","manage.py"]
# 执行启动命名 

上传requirements文件、执行build打包镜像

docker build -t flask_demo:1.0 .  

编译成后 通过 docker images 查看镜像是否正确安装

运行镜像

docker run --name flask_test1 -p 6001:6001 flask_demo:1.0

通过浏览器 访问ip地址 发现启动成功、至此flask部署到docker镜像完成!

5、docker网络

5.1 常用基本命令

当我们开启docker以后 会自动创建一个docker网桥 用于和宿主机的沟通和联系。

查看docker网络情况

docker network ls 

创建一个新的docker网络

docker network create aa_network

删除一个docker网络

docker network rm aa_network

查看网络信息

tail -n 20 查看后20行的信息

docker inspect u2|tail -n 20

5.2 docker网络能干什么

容器间的互联和通信以及端口映射

容器IP变动时候可以通过服务名直接网络通信而不受到影响

5.3 docker网络模式

1. 总体介绍
  • bridge 为每一个容器分配、设置IP等,并将容器连接到一个docker0,虚拟网桥,默认为该模式 (默认使用docker0)
    • –network bridge
  • host 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口
    • –network host
  • none 容器有独立的Network namespace 但并没有对其进行任何网络设置,如分配 veth pair和网络桥接,ip等
    • –network none
  • container 新创建的容器不会创建自己的网卡和配置自己的ip,而是和一个指定的容器共享IP,端口范围。
    • –network container:NAME或容器ID
2. 容器实例内默认网络IP生产规则

容器实例内默认网络IP生产规则 、docker容器内部的ip是有可能会发生改变的()

3. bridge网桥模式

整个宿主机的网桥模式都是docker0,类似一个交换机有一堆接口,每个接口叫veth,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫veth pair)

每个容器实例内部也有一块网卡,每个接口叫eth0

docker0上面的每个veth匹配某个容器实例内部的eth0,两两配对,一一匹配。

4. host模式

直接用宿主机的ip地址与外界通信 不再需要网桥的模式。

容器将不会获得一个独立的Network Namespace 而是和宿主机共用一个network Namespace。

同样启动容器实例的时候 也不要加上-p 去指定端口 否则会暴出一个警告。

docker run -d --name flask_test1 --network host flask_demo:1.0

那么没有端口号 那该怎么进行访问呢?那就直接访问该服务会启动的端口、直接访问。

5. none网络模式 (基本不用)

在none模式下,并不为Docker容器进行任何网络配置。

也就是说,这个Docker容器没有网卡、IP、路由等信息,只有一个IO

需要我们自己为Docker容器添加网卡、配置IP

6. container网络模式

container 新创建的容器不会创建自己的网卡和配置自己的ip,而是和一个指定的容器共享IP,端口范围。同样除了网络方面,还有文件系统、进程列表等还是隔离的。

7. 自定义网络模式

先启动两个tomcat容器实例。方面后面的测试使用。

docker netowrk create zzyy_network
·docker run -d -p 8081:8080 --network zzyy_network  --name tomcat81 billygoo/tomcat8-jdk8
·docker run -d -p 8082:8080 --network zzyy_network  --name tomcat82 billygoo/tomcat8-jdk8

分别进入两个容器内部(多开终端)

docker exec -it tomcat81 bash
docker exec -it tomcat82 bash

· 互相ping测试

· 问题结论

· 自定义网络本身就维护好了主机名和ip的对应关系(ip和域名都能通)

· 自定义网络本身就维护好了主机名和ip的对应关系(ip和域名都能通)

· 自定义网络本身就维护好了主机名和ip的对应关系(ip和域名都能通)

6、Docker容器编排

6.1 是什么

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

Docker-Compose是Docker官方的开源项目, 负责实现对Docker容器集群的快速编排。

6.2 能干什么

docker建议我们每一个容器中只运行一个服务,因为docker容器本身占用资源极少,所以最好是将每个服务单独的分割开来但是这样我们又面临了一个问题?

如果我需要同时部署好多个服务,难道要每个服务单独写Dockerfile然后在构建镜像,构建容器,这样累都累死了,所以docker官方给我们提供了docker-compose多服务部署的工具

例如要实现一个Web微服务项目,除了Web服务容器本身,往往还需要再加上后端的数据库mysql服务容器,redis服务器,注册中心eureka,甚至还包括负载均衡容器等等。。。。。。

Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。

可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose 解决了容器与容器之间如何管理编排的问题。

6.3 去哪里下载

官网

https://docs.docker.com/compose/compose-file/compose-file-v3/
https://docs.docker.com/compose/install/

安装步骤

curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --version

卸载步骤

rm /usr/local/bin/docker-compose

6.4 Compose核心概念

一文件

docker-compose.yml

两要素

服务(service)

一个个应用容器实例,比如订单微服务、库存微服务、mysql容器、nginx容器或者redis容器

工程(project)

由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。

6.5 Compose常用命令

Compose常用命令
docker-compose -h                           # 查看帮助
docker-compose up                           # 启动所有docker-compose服务
docker-compose up -d                        # 启动所有docker-compose服务并后台运行
docker-compose down                         # 停止并删除容器、网络、卷、镜像。
docker-compose exec  yml里面的服务id                 # 进入容器实例内部  docker-compose exec docker-compose.yml文件中写的服务id /bin/bash
docker-compose ps                      # 展示当前docker-compose编排过的运行的所有容器
docker-compose top                     # 展示当前docker-compose编排过的容器进程
 
docker-compose logs  yml里面的服务id     # 查看容器输出日志
docker-compose config     # 检查配置
docker-compose config -q  # 检查配置,有问题才有输出
docker-compose restart   # 重启服务
docker-compose start     # 启动服务
docker-compose stop      # 停止服务

6.6 flask打包运行案例

7、docker轻量级可视化工具Portainer

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

7.1 安装

拉取

docker pull portainer/portainer

下载汉化文件

链接: https://pan.baidu.com/s/1CJj5AYRW2fjhTojPh5WFgA 提取码: cdq6

解压到复制到根 目录 (通过远程ftp或者其余工具上传文件)

[root@zjj101 public]# pwd
/public
[root@zjj101 public]# ls
css  fonts  ico  images  index.html  js
[root@zjj101 public]#
docker run -d -p 9000:9000 --restart=always  -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data -v /public:/public --name prtainer-test  portainer/portainer

–restart=always 自启动! 重启docker也可以重启

7.2 登录

第一次登录需创建admin,访问地址:xxx.xxx.xxx.xxx:9000 自己创建一个密码

随后选择管理Local 管理本地的docker引擎。点击连接

点击local(在线) 进入控制台

ok 大功告成(瞬间感觉前面白学了(doge))

7.3 用portainer 安装nginx

在容器界面 点击添加容器

在浏览器访问ip地址

访问成功!nginx配置成功

8、docker容器监控 cig

普通命令

docker stats

docker stats统计结果只能是当前宿主机的全部容器,数据资料是实时的,没有地方存储、没有健康指标等。

8.1 创建目录

cd /myfile/mydocker
mkdir cig
cd cig

8.2 新建3件套的组合 docker-compose .yml

vim docker-compose.yml
version: '3.1'
 
volumes:
  grafana_data: {}
 
services:
 influxdb:
  image: tutum/influxdb:0.9
  restart: always
  environment:
    - PRE_CREATE_DB=cadvisor
  ports:
    - "8083:8083"
    - "8086:8086"
  volumes:
    - ./data/influxdb:/data
 
 cadvisor:
  image: google/cadvisor
  links:
    - influxdb:influxsrv
  command: -storage_driver=influxdb -storage_driver_db=cadvisor -storage_driver_host=influxsrv:8086
  restart: always
  ports:
    - "8080:8080"
  volumes:
    - /:/rootfs:ro
    - /var/run:/var/run:rw
    - /sys:/sys:ro
    - /var/lib/docker/:/var/lib/docker:ro
 
 grafana:
  user: "104"
  image: grafana/grafana
  user: "104"
  restart: always
  links:
    - influxdb:influxsrv
  ports:
    - "3000:3000"
  volumes:
    - grafana_data:/var/lib/grafana
  environment:
    - HTTP_USER=admin
    - HTTP_PASS=admin
    - INFLUXDB_HOST=influxsrv
    - INFLUXDB_PORT=8086
    - INFLUXDB_NAME=cadvisor
    - INFLUXDB_USER=root
    - INFLUXDB_PASS=root

启动docker

Logo

一起探索未来云端世界的核心,云原生技术专区带您领略创新、高效和可扩展的云计算解决方案,引领您在数字化时代的成功之路。

更多推荐