目录
一.基础篇
1.1Docker安装
- 1.执行Docker官方自动安装脚本
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
- 2.开启自启动
systemctl restart docker
- 3.安装Docker-compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
二、高级篇
1.安装mysql主从配置
2.安装Redis
地址
1~2亿条数据需要缓存,请问如何设计这个存储案例
2亿条数据就是2亿个k,v,我们单机不行必须要分布式多机,假设有3台及其构成一个集群,用户每次读写操作都是根据公式:hash(key)%N个机器台数,计算出哈希值,用来决定数据映射到哪一个节点上。
优点
简单粗暴,直接有效,只需要预估好数据规划好节点,例如3台、8台、10台,就能保证一段时间的数据支撑,使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡+分而治之的作用。
缺点
原来规划好的节点,进行扩容或者缩容就比较麻烦了,不管扩缩,每次数据变动导致节点有变动,映射关系需要重新计算,在服务器个数固定不变时没有问题,如果需要弹性扩容或故障停机的情况下,原来的取模公式就会发生变化,Hsah(key)/3就会变成Hask(key)/7,此时地址经过每个redis机器宕机了,由于台数数量有限,会导致hash取余全部数据重新洗牌。
一致性hash算法
步骤:
(1)算法构建一致性哈希环:
一致性哈希算法必然有个hash函数并按照算法产生hash值,这个算法的所有可能hash值会构成一个全量集,这个集合可以成为一个hash空间【0,2^32-1】,这个是一个线性空间,但是在算法中,我们通过适当的逻辑控制将它首尾相连,这样让它逻辑上形成一个环形空间。具体算法就对2的32次方取模。
(2)结点映射
将集群中各个IP结点映射到环上的某一个位置。
将各个服务器使用Hash进行一个哈希,具体可以选择服务器的IP或主机名作为关键字进行哈希,这样每台机器就i能确定其在哈希环上的位置。例如,4个节点NodeA,B,C,D,经过IP地址的hash函数计算,使用IP地址哈希后再换空间的位置如下:
(3)key落到服务器的落键规则
当我们需要储存一个kv键值对是,首先计算key的value值,hash(key),将这个key使用相同的函数Hash计算出哈希值并确定此数据再环上的位置,从此位置沿顺时针“行走“,第一台遇到的服务器就是其应该定位到的服务器,并将该键值对储存到该节点上。
优点
容错性:如果某台宕机了,只会影响部分数据
扩展性:增加了某台服务器,不会对其余服务器影响。
缺点
一致性Hash算法在服务节点太少时,容易因为节点分布不均匀而造成数据倾斜问题(被缓存的对象缓存到某一台服务器上)问题,例如系统中只有两台服务器;
3.哈希槽分区
概念
哈希槽实质就是一个数组,数组【0,2^14 -1】形成一个hash slot空间。能够解决均匀分配的问题,在数据和节点上又加上了一层,把这层称为哈希槽,用于管理数据和节点之间的关系,现在相当于节点上放的是槽,槽里放的是数据。
一个集群只能有16384个槽,编号0-16383(0-2^14-1)。这些槽会分配给集群中的所有主节点,分配策略没有要求。可以指定哪些编号的槽分配给哪个主节点。集群会记录节点和槽的对应关系。解决了节点和槽的关系后,接下来就需要对key求哈希值,然后对16384取余余数是几key就落入对应的槽里。slot = CRC16(key)% 16384。以槽为单位移动数据,因为槽的数目是固定的,处理起来比较容易,这样数据移动问题就解决了。
3.Dockerfile文件
用于构建镜像的命令
注意点
1.ockerfile中所用的所有文件一定要和Dockerfile文件在同一级父级目录
2.Dockerfile中的关键字写为大写
3.Dockerfile中一定要惜字如金,能写到一行的指令,一定要写到一行,原因是分层构建,联合挂载这个特性
关键字
FROM
指定基础镜像,并且必须是第一条指令,如果不以任何镜像为基础,那么写法为:FROM scratch
语法
FROM <image>
FROM <image>:<tag>
FROM<image>:<digest>
三种写法,其中<tag>和<digest>是可选项,如果没有选择,那么默认值为latest
MAINTAINER
指定作者
语法
MAINTAINER <name>
新版已经被LABEL指明
LABEL
功能是为镜像指明标签,汇集成基础镜像中的LABEL,如遇到Key相同,则值覆盖。
语法
LABEL <key>=<value> <key>=<value> <key>=<value> ...
一个Dockerfile种可以有多个LABEL,如下:
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
但是并不建议这样写,最好就写成一行,如太长需要换行的话则使用\符号
如下:
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
ADD
复制文件,如果文件是tag压缩包或者url,会解压或解析
语法
ADD test relativeDir/
ADD test /relativeDir
ADD http://example.com/foobar /
COPY
复制文件,不能解压或解析
语法
COPY <src>... <dest>
COPY ["<src>",... "<dest>"]
EXPOSE
暴露容器运行时的监听端口给外部,但是不会与主机有映射关系,如果想要有映射关系,必须创建容器时,加上-P映射
语法
EXPOSE <port>/<tcp/udp>
ENV
设置环境变量
语法
# 第一种是一次设置一个,第二种是一次设置多个
ENV <key> <value>
ENV <key>=<value> ...
如何使用变量
RUN
运行指令
语法
1. RUN <command>
2. RUN ["executable", "param1", "param2"]
CMD
容器启动时默认命令或者参数
语法
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
#参数的一定要用双引号,就是",不能是单引号。千万不能写成单引号。原因是参数传递后,docker解析的是一个JSON array
CMD command param1 param2
第一种和第二种是可执行文件加上参数的形式,第三种和shell文件类似。
举例
CMD [ "sh", "-c", "echo $HOME"
CMD [ "echo", "$HOME" ]
ENTRYPOINT
容器运行时命令
语法
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
VOLUME
可实现挂载功能,可以将宿主机目录挂载到容器中
语法
VOLUME ["/var/log/"]
VOLUME /var/log
VOLUME /var/log /var/db
USER
设置启动容器的用户,一般不设置,默认为root
WORKDIR
设置创建容器后的工作目录
例子(创建携带Vim,net-tools的java8镜像)
FROM centos:7
MAINTAINER wys<workversion@outlook.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
#ADD 是相对路径jar,把jdk-8u202-linux-i586.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置
ADD jdk-8u202-linux-i586.tar.gz /usr/local/java/
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_202
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
悬壶镜像
由于Dockerfile文件的语法错误,会出现镜像名和标签都为none的镜像
删除悬壶镜像
docker image prune
Dockerfile部署微服务
1.打包项目,上传jar文件
2.创建Dockerfile文件,生成镜像
#基础镜像使用java:8
FROM java:8
#作者
MAINTAINER wys
#VOLUME指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp
#将jar包添加到容器中,改变名字
ADD test-docker-0.0.1-SNAPSHOT.jar /test-docker.jar
# 运行jar包
RUN bash -c 'touch /test-docker.jar'
#暴露6001端口作为微服务
EXPOSE 6001
#配置容器启动后执行的命令
ENTRYPOINT ["java","-jar","-Dserver.port=6001","/test-docker.jar"]
3.打包成镜像
docker build -t 镜像名:标签名 .
3.生成容器,测试
4.network
bridge(默认)
Docker服务默认会创建一个docker0网桥(其上有一个docker0内部接口),该桥接网络的名称为docker0,他在内核层联通了其他的物理或虚拟网卡,这就将所有的容器和本地主机都放到了同一个物理网络,Docker默认制定了dokcer0接口的IP地址和子网掩码,让主机和容器之间可以通过网桥相互通信。
- 整个宿主机的网桥模式都是docker0,类似于一个交换机有一堆接口,每个接口叫veth,在本地主机和容器内分别创建一给你接口,并让他们彼此联通
- 每个容器内部也有一块网卡,每个接口叫eth0;
- docker0上面的每个veth匹配某个容器实力内部的eth0,两两配对,一一匹配
host
直接使用宿主机的IP地址与外界进行通信,不再需要额外进行NAT转换,镜像定义的暴露端口为多少,此时容器的端口就为多少,不再进行端口映射
none
禁用网络功能,只有lo表示(就是127.0.0.1,只能本地回环)
container
新建的容器和已经存在的一个容器共享一个网络IP配置而不适合宿主机共享,新创建的容器不会创建自己的网卡,培植自己的IP,而是和一个指定容器共享IP、端口范围等,同样,两个容器处理网络方面,其他的如文件系统、进程列表等还是隔离的
5.Docker-compose容器编排
Docker-Compose是Docker官网的开源项目,负责实现对Docker容器集群的快速编排,写好多个荣期间的调用关系,然后只要一个命令,就能同时启动和关闭这些容器。
Docker-compose的安装
下载插件
curl -SL https://github.com/docker/compose/releases/download/v2.10.2/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
赋权
chmod +x /usr/local/bin/docker-compose
核心概念
一文件,两要素。一文件指的是docker-compose.yml文件,两要素指的是服务和工程,服务是一个个应用容器实例,工程是由一组关联的应用容器组成的一个完整业务单元。
使用步骤
1.编写Dockerfile定义各个微服务应用并构建出对应的镜像
2.使用docker-compose.yml定义一个完整业务单元,安排好整体应用中的各个容器
3.最后执行docker-compose up命令来启动并运行整个应用程序,完成一键部署上线。
常用命令
一键创建redis mysql
version: "3"
services:
microService:
image: docker-compose:1.0
container_name: ms01
ports:
- "6001:6001"
volumes:
- /home/docker/microService:/data
networks:
- at_net
depends_on:
- redis
- mysql
redis:
image: redis:6.0.8
ports:
- "16379:6379"
volumes:
- /home/docker/redis/redis.conf:/etc/redis/redis.conf
- /home/docker/redis/data:/data
networks:
- at_net
command: redis-server /etc/redis/redis.conf
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: '123456'
MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
ports:
- "3306:3306"
volumes:
- /home/docker/mysql/db:/var/lib/mysql
- /home/docker/mysql/conf/my.cnf:/etc/my.cnf
- /home/docker/mysql/init:/docker-entrypoint-initdb.d
networks:
- at_net
command: --default-authentication-plugin=mysql_native_password
networks:
at_net:
检查docker-compose文件是否出错:
docker-compose up -d
创建所有的容器:
docker-compose up -d
6.Portainer的下载与使用
6.1概念
Portainer是一款轻量级的应用,它提供了图形化界面,用于方便地管理Docker环境,包括单机环境和集群环境。
6.2安装
docker run -d -p 9000:9000 --privileged=true --restart=always -v /var/run/docker.sock:/var/run/docker.sock --name prtainer portainer/portainer
7.CIG
了解即可,用的时候再学习