docker容器总结

docker容器

官网:http://www.docker.com

仓库: https://hub.docker.com/

Docker的基本组成(三要素):镜像(image),容器(container),仓库(repository)

镜像:Docker 镜像(Image)就是一个只读的模板。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器

容器:Docker 利用容器(Container)独立运行的一个或一组应用,应用程序或服务运行在容器里面,容器就类似于一个虚拟化的运行环境,容器是用镜像创建的运行实例

仓库:仓库(Repository)是集中存放镜像文件的场所。

Maven仓库,存放各种jar包的地方; ​ github仓库,存放各种git项目的地方; ​ Docker公司提供的官方registry被称为Docker Hub,存放各种镜像模板的地方。

1.安装

1.安装

讲解:Docker必须部署在linux内核的系统上,如图架构

要求:CentOS发行版本中的内核支持Docker,Docker运行在CentOS(64-bit)上,要求系统为64位,Linux系统内核版本为3.8以上,当然,你不知道你系统,以下命令可以查看

cat  /etc/redhat-release
​
uname -r

1:安装gcc(准备工作)

yum -y install gcc
yum -y install gcc-c++

2:安装需要的软件包

yum install -y yum-utils

3:设置stable镜像仓库

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

4:更新yum软件包索引

yum makecache fast

5:安装docker

yum -y install docker-ce docker-ce-cli containerd.io

6:启动docker

systemctl start docker

7:测试docker

docker -version
ps -ef|grep docker

2.卸载

1.停止docker

systemctl  stop docker 

2.删除

yum  remove docker-ce  docker-ce-cli containerd.io

3.删除文件

rm -rf /var/lib/docker
rm -rf /var/lib/containerd

3.配置镜像加速器

1.准备镜像环境

这里以华为云为例,当然阿里云,其他云是同样的道理(前提,你们自己用自己的,不要用我的)

找到容器镜像服务

2.创建目录

mkdir -p /etc/docker

3.写镜像地址

vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://0c2661ef30bf49cc929e63cbf7f72e4c.mirror.swr.myhuaweicloud.com"]
}

为什么Docker会比VM虚拟机快(了解)

2.常用命令

为了好记忆,分为三类:

帮助启动类命令

启动:systemctl start docker

停止:systemctl stop docker

重启:systemctl restart docker

查看状态:systemctl status docker

开机启动:systemctl enable docker

查看概要信息:systemctl info

查看总体帮助文档:docker --help

查看命令帮助文档:docker 命令 --help

镜像命令

docker image -a: 列出本地所有的镜像(含历史镜像) -q:只显示镜像ID

docker search 某个XXX镜像的名字

docker pull 某个XXX镜像的名字 下载镜像

docker system df 查看镜像/容器/数据卷所占的空间

docker rmi 容器id -f 强制删除

面试题

容器命令

新建+启动容器:docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

--name="容器新名字为容器指定一个名称; ​ -d: 后台运行容器并返回容器ID,也即启动守护式容器(后台运行);

-i: 以交互模式运行容器,通常与 -t 同时使用: ​ -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用:也即启动交互式容器(前台有伪终端,等待交互); ​ -P: 随机端口映射,大写P ​ -p: 指定端口映射,小写p

列出当前所有正在运行的容器:docker ps [OPTIONS]

退出容器:exit或者ctrl+p+q

启动已停止运行的容器:docker start 容器ID或者容器名

重启容器:docker restart 容器ID或者容器名

停止容器:docker stop 容器ID或者容器名

强制停止容器:docker kill 容器ID或容器名

删除已停止的容器:docker rm 容器ID

重点

启动(在强调一遍):docker run -d 容器名

查看容器日志:docker logs 容器ID

查看容器内运行的进程:docker top 容器ID

查看容器内部细节:docker inspect 容器ID

进入正在运行的容器并以命令行交互:docker exec -it 容器ID bashShell

重新进入docker attach 容器ID

上述两个区别:attach 直接进入容器启动命令的终端,不会启动新的进程 用exit退出,会导致容器的停止。

exec 是在容器中打开新的终端,并且可以启动新的进程用exit退出,不会导致容器的停止。(推荐用)

从容器内拷贝文件到主机上(容器---->主机):docker cp 容器ID:容器内路径 目的主机路径

导入和导出容器:export 导出容器的内容留作为一个tar归档文件[对应import命令]

import 从tar包中的内容创建一个新的文件系统再导入为镜像[对应export]

例子:docker export 容器ID > 文件名.tar

cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号

3.Docker镜像

是什么:是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。

只有通过这个镜像文件才能生成Docker容器实例(类似Java中new出来一个对象)。

分层的镜像:以我们的pull为例,在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载

UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

Docker镜像加载原理:docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。 bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是引导文件系统bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。

rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。 。 平时我们安装进虚拟机的CentOS都是好几个G,为什么docker这里才200M??

对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供 rootfs 就行了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。

为什么 Docker 镜像要采用这种分层结构呢:镜像分层最大的一个好处就是共享资源,方便复制迁移,就是为了复用。

比如说有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像; 同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

重点理解:Docker镜像层都是只读的,容器层是可写的当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。

Docker镜像commit操作案例

理论(这一节这个命令就是一个重点,其它没有卵用):docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]

这里就是一个小例子,熟悉一下commit命令

需求:1.下载一个ubuntu (没有含vim)

2.在ubuntu中下载vim

3.生成镜像下次用

1.下载ubuntu

docker pull ubuntu

2.启动ubuntu(没有vim)

docker run -it ubuntu /bin/bash

3.下载vim包

apt-get update
apt-get install vim

4.打包成镜像(已经有vim)

docker commit -m="vim cmd add ok" -a="yjh" d4f50e5a9ece yjh/myubuntu1.0

4.本地镜像发布到云

1.发布到阿里云

1.准备(先创建命名空间----->在创建镜像仓库)

推送:

docker images
docker login --username=aliyun2696456324 registry.cn-hangzhou.aliyuncs.com
docker tag 52ce82fa78ab registry.cn-hangzhou.aliyuncs.com/atguiguyjh/yjh:1.0
docker push registry.cn-hangzhou.aliyuncs.com/atguiguyjh/yjh:1.0

拉取:

docker pull registry.cn-hangzhou.aliyuncs.com/atguiguyjh/yjh:1.0

2.发布到华为云

将容器上传到华为云中的容器镜像服务(SWR)

1.前提准备

安装好docker,docker中有容器,例如:

图片中已经有一个mysql容器,版本是5.7的

华为云准备:

 

2.先绑定

 

将你的上面的命令放在linux中运行一次,就算绑定

3.上传

按照这个命令生成一次,例如:

docker tag mysql:5.7 swr.cn-north-4.myhuaweicloud.com/docker-yjh/mysql:5.7

查看容器名称和版本的命令:

docker images
--REPOSITORY  : 容器名称
--TAG :版本

推送:

docker push swr.cn-north-4.myhuaweicloud.com/docker-yjh/mysql:5.7

当然,推送就可以拉取:拉取的命令

docker  pull  swr.cn-north-4.myhuaweicloud.com/docker-yjh/mysql:5.7

5.本地镜像发布到私有库

需求:1.下载一个ubuntu(不携带ifconfig命令)

2.在ubuntu中安装ifconfig命令

3.上传到私有库中

1.下载registry

docker pull registry
docker pull ubuntu

2.安装registry

docker run -d -p 5000:5000 -v /zzyyuse/myregistry/:/tmp/registry --privileged=true registry

3.启动ubuntu

docker run -it ubuntu /bin/bash

4.在ubuntu安装ifconfig命令

apt-get update
apt-get install net-tools

5.提交到私有库

命令模板:docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]

docker commit -m="ifconfig cim add" -a="yjh" 7322cb56c2d1 yjhubuntu:1.1

6.查看你私有库的镜像有哪些(现在查看应该没有才对)(ip地址写自己的,不要跟着我抄)

curl -XGET http://121.37.94.218:5000/v2/_catalog

7.打包(ip地址写自己的,不要跟着我抄)

docker tag yjhubuntu:1.1 121.37.94.218:5000/yjhubuntu:1.1

8.修改配置文件使之支持http(ip地址写自己的,不要跟着我抄)

vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://0c2661ef30bf49cc929e63cbf7f72e4c.mirror.swr.myhuaweicloud.com"],
"insecure-registries": ["121.37.94.218:5000"]
}

9.重启Docker和重启registry

systemctl restart docker
docker start 6845eb9625ee

10.推送

docker push 121.37.94.218:5000/yjhubuntu:1.1

11.查看仓库(现在应该看见yjhubuntu镜像)

curl -XGET http://121.37.94.218:5000/v2/_catalog

12.拉取命令

docker pull 121.37.94.218:5000/yjhubuntu:1.1

6.Docker容器数据卷

理论:在启动容器的时候,记住:

1.加上 -v 选项,表示映射,将容器中的目录映射到linux中

2.加上 --privileged=true,开启权限

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

总结:说白了,这个数据卷就是将容器中的数据,配置文件等映射linux中(持久化),主要是防止误删docker容器,如果设置了数据卷,误删docker容器后,至少你们大数据还在,明白?(容器和宿主机之间数据共享)

1.读写规则映射添加说明

默认:(一般没有特殊要求,默认就OK了)

命令: docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:rw 镜像名 (rw指的是可读,可写)

默认情况下:-v的时候,宿主机与容器的数据是绑定关系,宿主机改动,容器也会改动,假如容器改动,宿主机也会改动,说白了,就是可逆的(都有读写权限)

需求:我想宿主机有写权限而容器没有写权限(都有读权限)怎么操作?如下

命令: docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:ro 镜像名 (ro指的是可读)

2.卷的继承和共享

命令:docker run -it --privileged=true --volumes-from 父类 --name u2 ubuntu (父类指的是,被一个容器的名字(--name后面的))

总结:继承和共享:比如,容器1继承容器2,他两个的数据共享,如果容器1挂了,容器2改动,等容器1启动后,数据还在,容器2改动的数据,容器1也改动(一句话描述:两个容器永远保持一致)

7.Docker常规安装

总体步骤

1.搜索镜像

2.拉取镜像

3.查看镜像

4.启动镜像

5.停止镜像

6.移除镜像

安装Tomcat

1.搜索镜像

docker search tomcat

2.拉取镜像

docker pull tomcat

3.查看镜像

docker images

4.启动镜像

docker run -d -p 8080:8080 --name t1 tomcat

5.访问Tomcat

在浏览器中输入自己的ip访问,如:cAdvisor - /

卧槽:发现报错,404错 ????????

为什么呢,难道安装有问题?????

6.bug修复(这是因为高版本才有这个bug,低版本没有)

进入到容器中:

docker exec -it e423c6934e94 /bin/bash
ls -l

原因在这里:webapps文件是空的,所以访问不了,然后进行修改

rm -r webapps
mv webapps.dist/ webapps

7.再次访问cAdvisor - /

OK,应该猫出现了

看见没有(9.0.43)版本,所有上面有那个bug

当然,你说公司不需要版本怎么高,你可以安装低版本

Tomcat8安装

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

直接运行,如果仓库里面没有tomcat8,会从远程自动拉取,会自动拉取,自动运行,安装好直接访问就好了

安装mysql

1.查看是否有mysql

docker search mysql

2.拉取的命令

docker pull mysql:5.7

注意:docker pull mysql 这个是拉取最新的版本,所以建议在后面指定版本号

3.检查拉取是否成功

docker images mysql:5.7

4.安装

docker run -d -p 3306:3306 --privileged=true -v /zzyyuse/mysql/log:/var/log/mysql -v /zzyyuse/mysql/data:/var/lib/mysql -v /zzyyuse/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7

注意:linux中已经有3306的mysql的,所以docker中的mysql就要映射重新的端口,设置为3307

-v: 映射路径

-p:是你的端口号 -p 3306:3306 第一个3306是linux的,第二个3306是容器的,比如,我将容器3306映射到linux的3307应该这样写: -p 3307:3306

-e:是你的容器名字,123456是mysql的密码

-d:是mysql的版本

--name 容器的名字

5.修改语言

注意:如果你不修改,中文有乱码,所以一定要修改,ok!

cd /zzyyuse/mysql/conf
vim my.cnf

添加下面的内容:

[client]
default_character_set=utf8
[mysqld]
collation_server = utf8_general_ci
character_set_server = utf8

当然,如果你要用到binlog文件,还可以加一下配置
server-id=1
log-bin=mysql-bin
binlog_format=row
binlog-do-db=db01

查看语言命令

SHOW VARIABLES LIKE 'character%';

6.查看

docker ps

查看出来的结果应该有如下的形式:4802a8bfca90 这个是id号,每个人都不一样

7.重启容器

docker restart 4802a8bfca90

6.进入mysql

docker exec -it 4802a8bfca90 /bin/bash

注意:上面的命令 4802a8bfca90 这个是id号,每个人的都不一样,你看看你的第五步是什么,复制用你的

mysql -uroot -p123456

安装Redis

1.下载镜像

docker pull  redis:6.2.1

2.准备数据卷

mkdir /zzyyuse/redis
mkdir /zzyyuse/redis/data
vim /zzyyuse/redis/redis.conf

这里需要一个原生的redis的配置文件,在文件夹里

修改配置文件

bind 127.0.0.1 -::1
daemonize no
protecte-mode no

3.启动容器

docker run -p 6379:6379 --name myr3 --privileged=true -v /zzyyuse/redis/redis.conf:/etc/redis/redis.conf -v /zzyyuse/redis/data:/data -d redis:6.2.1 redis-server /etc/redis/redis.conf

4.进入容器

docker exec -it myr3 /bin/bash
redis-cli

Docker基础篇到此结束,如果你能看到这里,可以加联系方式qq:2091312274

8.Docker复杂安装详说

安装mysql主从复制

说明:3307的mysql为主服务器,3308的mysql为从服务器

1.拉取

docker  pull  mysql:5.7

2.启动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=123456 -d mysql:5.7

3.配置

vim  /mydata/mysql-master/conf/my.cnf
[mysqld]
## 设置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

4.重启

docker restart 6d44fe94f16f

5.进入mysql

docker exec -it 6d44fe94f16f /bin/bash
mysql -uroot -p123456

添加用户,设置权限(mysql中)

CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';

6.启动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

7.配置

vim /mydata/mysql-slave/conf/my.cnf
[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

8.重启

docker restart mysql-slave

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

注意:是主服务器(3307)不用弄错了,看图,红色框里很重要,后面会用

show master status;

10.进入从数据库

注意:是从数据库(3308)

docker exec -it mysql-slave /bin/bash
mysql -uroot -proot

11.在从数据库中配置主从复制(3308)

change master to master_host='121.37.94.218', master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-bin.000005', master_log_pos=154, master_connect_retry=30;

命令解析:change master to master_host='宿主机ip', master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-bin.000005', master_log_pos=154, master_connect_retry=30;

注意:mall-mysql-bin.000005这个是第9点图上的,不要弄错了

154也是第9点图上的,不要弄错了

12.在从数据库中查看主从同步状态(3308)

show slave status \G;

如图所示,主要是看红色框的参数,现在都是No,说明没有开启主从复制

13:在从数据库中开启主从同步(3308)

start slave;

14.查看从数据库状态(3308)

show slave status \G;

如图所示,也该为Yes就ok了

15.测试

在主数据库上执行下列代码(3307)

create database db01;
use db01;
create table t1 (id int ,name varchar(20));
insert into t1 values(1,'z2');

观察从数据库(3308)

redis的3主3从,扩容,缩容(理论)

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

回答:单机单台100%不可能,肯定是分布式存储,用redis如何落地?

3种解决方案:

1.哈希取余分区

2亿条记录就是2亿个k,v,我们单机不行必须要分布式多机,假设有3台机器构成一个集群,用户每次读写操作都是根据公式:hash(key) % N个机器台数,计算出哈希值,用来决定数据映射到哪一个节点上。

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

缺点: 原来规划好的节点,进行扩容或者缩容就比较麻烦了额,不管扩缩,每次数据变动导致节点有变动,映射关系需要重新进行计算,在服务器个数固定不变时没有问题,如果需要弹性扩容或故障停机的情况下,原来的取模公式就会发生变化:Hash(key)/3会变成Hash(key) /?。此时地址经过取余运算的结果将发生很大变化,根据公式获取的服务器也会变得不可控。某个redis机器宕机了,由于台数数量变化,会导致hash取余全部数据重新洗牌。

2.一致性哈希算法分区

一致性哈希环:

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

	它也是按照使用取模的方法,前面笔记介绍的节点取模法是对节点(服务器)的数量进行取模。而一致性Hash算法是对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环。

节点映射

	将集群中各个IP节点映射到环上的某一个位置。
	将各个服务器使用Hash进行一个哈希,具体可以选择服务器的IP或主机名作为关键字进行哈希,这样每台机器就能确定其在哈希环上的位置。假如4个节点NodeA、B、C、D,经过IP地址的哈希函数计算(hash(ip)),使用IP地址哈希后在环空间的位置如下:  

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

如我们有Object A、Object B、Object C、Object D四个数据对象,经过哈希计算后,在环空间上的位置如下:根据一致性Hash算法,数据A会被定为到Node A上,B被定为到Node B上,C被定为到Node C上,D被定为到Node D上。

优点:

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

容错性:假设Node C宕机,可以看到此时对象A、B、D不会受到影响,只有C对象被重定位到Node D。一般的,在一致性Hash算法中,如果一台服务器不可用,则受影响的数据仅仅是此服务器到其环空间中前一台服务器(即沿着逆时针方向行走遇到的第一台服务器)之间数据,其它不会受到影响。简单说,就是C挂了,受到影响的只是B、C之间的数据,并且这些数据会转移到D进行存储。

缺点:

Hash环的数据倾斜问题,一致性Hash算法在服务节点太少时,容易因为节点分布不均匀而造成数据倾斜(被缓存的对象大部分集中缓存在某一台服务器上)问题, 例如系统中只有两台服务器:

总结:

为了在节点数目发生改变时尽可能少的迁移数据

将所有的存储节点排列在收尾相接的Hash环上,每个key在计算Hash后会顺时针找到临近的存储节点存放。 而当有节点加入或退出时仅影响该节点在Hash环上顺时针相邻的后续节点。

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

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

哈希槽分区:

1 为什么出现

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

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

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

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

哈希槽计算:Redis 集群中内置了 16384 个哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。当需要在 Redis 集群中放置一个 key-value时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,也就是映射到某个节点上。如下代码,key之A 、B在Node2, key之C落在Node3上

安装redis3主3从

前面讲的都是理论,记住:小厂用哈希取余分区,大厂用哈希槽分区,现在搭建的就是哈希槽分区

规划

1.安装6台redis

docker run -d --name redis-node-1 --net host --privileged=true -v /data/redis/share/redis-node-1:/data redis:6.2.1 --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.2.1 --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.2.1 --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.2.1 --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.2.1 --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.2.1 --cluster-enabled yes --appendonly yes --port 6386

2.进入一台服务器

docker exec -it redis-node-1 /bin/bash
redis-cli --cluster create 121.37.94.218:6381 121.37.94.218:6382 121.37.94.218:6383 121.37.94.218:6384 121.37.94.218:6385 121.37.94.218:6386 --cluster-replicas 1

注意:上面的ip地址写自己的

看图说话:6381,6382,6383是主机,6384,6385,6386是从机

3.查看安装情况

redis-cli -p 6381
cluster info
cluster nodes

看图说话:

主 从

1 4

2 5

3 6

注意:每一次分配的不一样,每个人都不一样,看图说话的就行

4查看运行情况

docker exec -it redis-node-1 /bin/bash
redis-cli -p 6381 -c

注意:启动的时候不能用redis-cli -p 6381这个命令,一定要加-c选项,-c选项是加上路由的意思,可以跳转

记忆:redis-cli --cluster check 121.37.94.218:6381

记忆:假如6381宕机了,6384会补上,当6381重新启动后,6384它还是master

Redis的扩容操作

从3主3从扩容到4主4从

1.安装redis

docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/share/redis-node-7:/data redis:6.2.1 --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.2.1 --cluster-enabled yes --appendonly yes --port 6388

2.加入集群(ip是自己的)

命令模板:redis-cli --cluster add-node 自己实际IP地址:6387 自己实际IP地址:6381

docker exec -it redis-node-7 /bin/bash
redis-cli --cluster add-node 121.37.94.218:6387 121.37.94.218:6381

3.测试(ip是自己的)

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

redis-cli --cluster check 121.37.94.218:6381

看图说话:要有是个M

4.分配槽

重新分派槽号命令:redis-cli --cluster reshard IP地址:端口号

redis-cli --cluster reshard 192.168.111.147:6381

redis-cli --cluster reshard 121.37.94.218:6381

16384/4=4094所以填4094

4094

写6387的id(每一次一样)

7b396b5b2a5614b4aeba1feabe2eb3b5fbfde64f
all
yes

5.查看

redis-cli --cluster check 121.37.94.218:6381

看图说话:新添加的机器分配的时候,是每一个机器都匀了一点给6387,而并不是从0开始从新排序


6.添加从机

命令模板:redis-cli --cluster add-node 192.168.111.147:6388 192.168.111.147:6387 --cluster-slave --cluster-master-id e4781f644d4a4e4d4b4d107157b9ba8144631451-------这个是6387的编号,按照自己实际情况

7.查看

redis-cli --cluster check 121.37.94.218:6381

看图说话:四主四从

Redis的缩容操作

1.先下线从服务器(6388)

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

redis-cli --cluster del-node 121.37.94.218:6388 d366589159d786b6a96badb3b44ddab1b9e6fa70
redis-cli --cluster check 121.37.94.218:6381

看图说话:只有3个S

2.缩容

redis-cli --cluster reshard 121.37.94.218:6381
4096
132f7d3b7a15f53a291e0a6b76a84742f367d865  注意: (6381)
7b396b5b2a5614b4aeba1feabe2eb3b5fbfde6f4  注意: (6387)
done
yes
redis-cli --cluster check 121.37.94.218:6381

看图说话:6387虽然还在,但是已经没有槽了

3.删除6387

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

redis-cli --cluster del-node 121.37.94.218:6387 7b396b5b2a5614b4aeba1feabe2eb3b5fbfde6f4

4.查看

redis-cli --cluster check 121.37.94.218:6381

看图说话:现在是不是已经缩容到3主3从

9.DockerFile解析

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

官网:Dockerfile reference | Docker Documentation

构建三步骤

1.编写Dockerfile文件

2.docker build命令构建镜像

3.docker run依镜像运行容器实例

Dockerfile内容基础知识

1:每条保留字指令都必须为大写字母且后面要跟随至少一个参数

2:指令按照从上到下,顺序执行

3:#表示注释

4:每条指令都会创建一个新的镜像层并对镜像进行提交

Docker执行Dockerfile的大致流程

(1)docker从基础镜像运行一个容器

(2)执行一条指令并对容器作出修改

(3)执行类似docker commit的操作提交一个新的镜像层

(4)docker再基于刚提交的镜像运行一个新容器

(5)执行dockerfile中的下一条指令直到所有指令都执行完成

总结

从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,

  • Dockerfile是软件的原材料

  • Docker镜像是软件的交付品

  • Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例 Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。

1 Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;

2 Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时会真正开始提供服务;

3 Docker容器,容器是直接提供服务的。

DockerFile常用保留字指令

理论:

FROM(from):基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是from

MAINTAINER(maintainer):镜像维护者的姓名和邮箱地址

RUN(run):容器构建时需要运行的命令

两种格式:shell格式:RUN yum -y install vim

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

RUN是在docker build时运行

EXPOSE(expose):当前容器对外暴露出的端口

WORKDIR(workdir):指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点

USER(user):指定该镜像以什么样的用户去执行,如果都不指定,默认是root

ENV(env): 用来在构建镜像过程中设置环境变量

ADD(add): 将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包

COPY(copy): 类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中 <源路径> 的文件/目录复制到新的 一层的镜像内的 <目标路径> 位置

add和copy是一组的:add功能更强大,如果是tar包它可以拷贝到镜像中并且解压,copy就只有单纯的拷贝

VOLUME(volume):容器数据卷,用于数据保存和持久化工作

CMD(cmd): 指定容器启动后的要干的事情

它和前面RUN命令的区别: CMD是在docker run 时运行。

RUN是在 docker build时运行。

ENTRYPOINT(entrypoint) : 也是用来指定一个容器启动时要运行的命令

类似于 CMD 指令,但是ENTRYPOINT不会被docker run后面的命令覆盖,而且 这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序

cmd和entrypoint总结:如果只出现cmd:cmd指定容器启动后的要干的事情,但是如果你在运行命令都后面加入参数,这cmd的参数会被替代,如果cmd和entrypoint都出现,entrypoint的优先级高,entrypoint指定一个容器启动时要运行的命令,cmd变成entrypoint的参数

实操:

需求:写一个镜像:centos+vim+ifconfig+jdk8 (使用dockerfile方式)

提供jdk下载地址:小柒博客 | 开源软件镜像站

实现:

下载centos镜像:

docker pull centos
docker ps images
mkdir /myfile

写dockerfile文件

FROM centos
MAINTAINER zzyy<zzyybs@126.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 $MYPATHCMD echo "success--------------ok"
CMD /bin/bash

上传jdk

运行

docker build  -t  centosjava8:1.5 .

注意:可能会报错,报错为:Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorl 解决方案

FROM centos
MAINTAINER zzyy<zzyybs@126.com> 

ENV MYPATH /usr/local
WORKDIR $MYPATH 

RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*

#安装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-8u212-linux-x64.tar.gz /usr/local/java/
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_212
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 $MYPATHCMD echo "success--------------ok"
CMD /bin/bash

虚悬镜像

什么叫虚悬镜像:repository和tag都为none的时候为虚悬镜像

造成的原因:在构建和删除的时候发生了错误

查看虚悬镜像:

docker images ls -f dangling=true

删除命令:

docker image prune

在生产环境中,最好不要用虚悬镜像

10.Docker微服务实战

1.写一个简单的springboot程序(我已经准备好了)

docker学习需要的程序: docker学习需要的程序,测试用

2.打包上传

3.写dockerfile

vim Dockerfile
# 基础镜像使用java
FROM java:8
# 作者
MAINTAINER zzyy
# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名为zzyy_docker.jar
ADD docker_boot-1.0-SNAPSHOT.jar zzyy_docker.jar
# 运行jar包
RUN bash -c 'touch /zzyy_docker.jar'
ENTRYPOINT ["java","-jar","/zzyy_docker.jar"]
#暴露6001端口作为微服务
EXPOSE 6001

4.打包

docker build -t zzyy_docker:1.6 .

5.运行

docker images

docker run -d -p 6001:6001 zzyy_docker

6.访问(找到你自己linux ip地址)

http://192.168.10.103:6001/order/docker

11.Docker网络

常用基本命令

查看网络:docker network ls

查看网络源数据:docker network inspect XXX网络名字

创建网络:docker network create xxx网路名称

删除网络:docker network rm XXX网络名字

网络模式

bridge: 为每一个容器分配、设置IP 等,并将容器连接到一个 docker0虚拟网桥,默认为该模式。

host: 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP 和端口.

none: 容器有独立的 Network namespace,但并没有对其进行任何网络设置,如分配 veth pair 和网桥连接,IP 等。

container: 新创建的容器不会创建自己的网卡和配置自己的IP,而是和一个指定的容器共享IP、端口范围等

查看容器ip

docker pull ubuntu
docker run -it --name u3 ubuntu bash
docker inspect u3

注意:docker容器内部的ip是有可能会发生改变的

实际运用命令:--network host

docker run -d -p 8083:8080 --network host --name tomcat83 billygoo/tomcat8-jdk8

自定义网络

解决痛点:如果你不使用自定义网络,会出现,ip ping的通而服务名ping 不通的情况,所以要想服务名ping的通,建议使用自定义网络

案例

1.创建网络:

docker network create zzyy_network

2.创建容器

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

3.测试

在tomcat81上:

docker exec -it tomcat81 bash
ip addr
ping 172.18.0.3
ping tomcat82

在tomcat82上:

docker exec -it tomcat82 bash
ip addr
ping 172.18.0.2
ping tomcat81

结果:

12.Docker-compose容器编排

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

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

安装

1.下载docker-compose(网不好,多试几下)

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

2.改权限

chmod +x /usr/local/bin/docker-compose

3.测试

docker-compose --version

卸载命令(不用卸载)

rm /usr/local/bin/docker-compose

Compose核心概念

一文件:docker-compose.yml

两要素:服务(service):一个个应用容器实例,比如订单微服务、库存微服务、mysql容器、nginx容器或者redis容器

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

Compose使用的三个步骤

1.编写Dockerfile定义各个微服务应用并构建出对应的镜像文件

2.使用 docker-compose.yml 定义一个完整业务单元,安排好整体应用中的各个容器服务。

3.最后,执行docker-compose up命令 来启动并运行整个应用程序,完成一键部署上线

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 # 停止服务

不用Compose启动微服务

1.安装mysql(改字符集请看第七节中详细安装mysql)

docker run -p 3306:3306 --name mysql57 --privileged=true -v /zzyyuse/mysql/conf:/etc/mysql/conf.d -v /zzyyuse/mysql/logs:/logs -v /zzyyuse/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
80d3f711827fcd854c6e762a723d260bda832178bca053e7da8162048424f182

2.在mysql中创建表

docker exec -it 80d3f711827f /bin/bash
create database db2023;
use db2023;
CREATE TABLE `t_user` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL DEFAULT '' COMMENT '用户名',
  `password` varchar(50) NOT NULL DEFAULT '' COMMENT '密码',
  `sex` tinyint(4) NOT NULL DEFAULT '0' COMMENT '性别 0=女 1=男 ',
  `deleted` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '删除标志,默认0不删除,1删除',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户表';

3.安装redis

docker run -p 6379:6379 --name redis608 --privileged=true -v /app/redis/redis.conf:/etc/redis/redis.conf -v /app/redis/data:/data -d redis:6.0.8 redis-server /etc/redis/redis.conf

4.编写简单的微服务(先在本地打通,在打包)需要改yaml中的ip

程序下载地址:docker学习需要的程序: docker学习需要的程序,测试用

微服务功能描述:就写一个简单的旁路缓存

http://localhost:6001/swagger-ui.html#/ swagger的地址

http://localhost:6001/user/add 向mysql中添加3条数据,用postman测试,是post方法

http://localhost:6001/user/find/1 查询单条数据

5.打包上传

6.构建镜像

docker build -t zzyy_docker:1.6 .

7.运行

docker run -d -p 6001:6001 zzyy_docker:1.6

使用Compose启动多个微服务

1.微服务准备

程序下载地址:docker学习需要的程序: docker学习需要的程序,测试用

代码与上面代码相同,唯一不同的在yaml中修改为服务名

2.打包上传

3.构建镜像

docker build -t zzyy_docker:1.6 .

4.编写docker-compose.yml文件

vim docker-compose.yml
version: "3"
services:
  microService:
    image: zzyy_docker:1.6
    container_name: ms01
    ports:
      - "6001:6001"
    volumes:
      - /app/microService:/data
    networks:
      - atguigu_net
    depends_on:
      - redis
      - mysql
  redis:
    image: redis:6.0.8
    ports:
      - "6379:6379"
    volumes:
      - /app/redis/redis.conf:/etc/redis/redis.conf
      - /app/redis/data:/data
    networks:
      - atguigu_net
    command: redis-server /etc/redis/redis.conf
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: '123456'
      MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
      MYSQL_DATABASE: 'db2023'
      MYSQL_USER: 'zzyy'
      MYSQL_PASSWORD: 'zzyy123'
    ports:
      - "3306:3306"
    volumes:
      - /app/mysql/db:/var/lib/mysql
      - /app/mysql/conf/my.cnf:/etc/my.cnf
      - /app/mysql/init:/docker-entrypoint-initdb.d
    networks:
      - atguigu_net
    command: --default-authentication-plugin=mysql_native_password #解决外部无法访问
networks:
  atguigu_net:

5.检查文件是否写对

docker-compose config -q

6.执行

docker-compose up -d

7.在mysql中创建表

docker exec -it d31ff8ebb90e bash
mysql -uroot -p123456
CREATE TABLE `t_user` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL DEFAULT '' COMMENT '用户名',
  `password` varchar(50) NOT NULL DEFAULT '' COMMENT '密码',
  `sex` tinyint(4) NOT NULL DEFAULT '0' COMMENT '性别 0=女 1=男 ',
  `deleted` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '删除标志,默认0不删除,1删除',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户表';

8.停止

docker-compose stop

13.Docker轻量级可视化工具Portainer

是什么:docker的可视化工具

官网:Portainer: Docker and Kubernetes Management Platform

https://docs.portainer.io/v/ce-2.9/start/install/server/docker/linux

安装

docker run -d -p 8000:8000 -p 9000:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer

--restart=always:指的是docker启动,可视化也启动

登录:Portainer

14.Docker容器监控CAdvisor+InfluxDB+Granfana

CAdvisor:(收集和分析)CAdvisor是一个容器资源监控工具包括容器的内存,CPU,网络10,磁盘IO等监控,同时提供了一个WEB页面用于查看容器的实时运行状态。CAdvisor默认存储2分钟的数据,而且只是针对单物理机。不过,CAdvisor提供了很多数据集成接口,支持InfluxDB,Redis,Kafka,Elasticsearch等集成,可以加上对应配置将监控数据发往这些数据库存储起来 CAdvisor功能主要有两点: 展示Host和容器两个层次的监控数据. 展示历史变化数据。

InfluxDB:(存储)lnfluxDB是用Go语言编写的一个开源分布式时序、事件和指标数据库,无需外部依赖。 CAdvisor默认只在本机保存最近2分钟的数据,为了持久化存储数据和统一收集展示监控数据,需要将数据存储到influxDB中。InfluxDB是一个时序数据库,专门用于存储时序相关数据,很适合存储CAdvisor的数据。而且,CAdvisor本身已经提供了InfluxDB的集成方法,丰启动容器时指定配置即可。 InfluxDB主要功能: 基于时间序列,支持与时间有关的相关函数(如最大、最小、求和等); 可度量性:你可以实时对大量数据进行计算: 基于事件:它支持任意的事件数据:

Granfana:(展示)Grafana是一个开源的数据监控分析可视化平台,支持多种数据源配置(支持的数据源包括InfluxDB,MysQL,ElasticsearcrOpenTSDB,Graphite等)和丰富的插件及模板功能支持图表权限控制和报警。 Grafan主要特性 灵活丰富的图形化选项 可以混合多种风格 支持白天和夜间模式 多个数据源

安装

1.编写docker-compose

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

2.语法检查

docker-compose-config -q

3.启动

docker-compose up

4.访问

cadvisor: cAdvisor - /

influxdb: InfluxDB - Admin Interface

grafana: Grafana

15.大保健

1 请谈谈Docker的优势?

Docker的优势包括提高应用程序开发和部署的速度、降低复杂度和成本、减少依赖的问题、提高应用程序的可移植性和可重复性等。

2 Docker的核心组件是什么?

Docker的核心组件包括Docker引擎、Docker客户端、Docker Hub、Docker Registry、Docker Compose等。Docker引擎是Docker的核心技术,负责管理容器的生命周期和资源管理。Docker客户端是Docker的命令行工具,用于与Docker引擎进行交互。Docker Hub是Docker的公共仓库,包含了大量的Docker镜像,Docker Compose用于管理多个Docker容器的编排工具。

3 Docker和虚拟机有什么区别?

Docker与传统虚拟机的不同之处在于,虚拟机模拟了整个操作系统,而Docker只是模拟了容器。这种容器化技术可以避免虚拟机的资源浪费和分布式环境下难以部署的问题,容器在系统层面上隔离,运行在同一系统内,但是不会干扰到其他容器和主机。

4 如何实现Docker的自动化部署?

Docker可以通过使用自动化部署工具,例如Docker Compose、Docker Swarm、Kubernetes和AWS Elastic Beanstalk等。这些工具可以快速、简单和可控的部署和管理多个Docker容器的编排。

5 Docker的镜像是什么?

Docker镜像是Docker容器运行所需的一切,是一个独立的软件包,包含了应用程序、本地库、其他依赖项和预配置设置等。Docker镜像可以轻松地创建、部署、共享和存储,可以通过Docker Hub或私有仓库共享给其他用户或团队。

6 Docker的卷是什么?

卷是Docker用于持久化存储的一种方式,它的作用是将数据存储在容器之外,使得数据不会随着容器的删除而丢失。Docker的卷可以是本地文件系统、网络文件系统、内存文件系统等。

7 如何优化Docker容器的性能?

在优化Docker容器性能方面,可以从多个角度入手。例如,通过优化容器的资源管理、调整Docker内核参数、使用基于Docker的容器优化工具等。另外还可以使用Docker多阶段构建、构建高效的Dockerfile等方式提高容器性能。

8 如何保证Docker容器的安全性?

为了保证Docker容器的安全性,可以采取多种措施,包括做好基础安全工作、使容器具有最小化的特权、使用Docker安全检测工具、检查容器镜像、实现安全的Docker容器编排等。

9 如何维护Docker容器?

维护Docker容器需要考虑多个因素,包括容器的生命周期管理、容器的日志和监控、容器网络的管理和安全等。常用的维护方法包括Docker重启策略、容器日志管理、定期清理容器、使用Docker监控工具等。

10 请谈谈Docker Compose的作用?

Docker Compose是一款用于管理多个Docker容器的工具,可以帮助您定义和管理Docker应用程序的多个组件。Docker Compose支持通过配置文件轻松定义容器、网络和存储卷,并可以使用Docker Compose命令行工具轻松启动、停止和管理应用程序的多个容器。

11.什么是Docker?

Docker是一个开源的容器化平台,用于构建、打包和运行应用程序。

12.Docker和虚拟机有什么区别?

虚拟机将整个操作系统隔离在虚拟硬件上,而Docker容器只需隔离应用程序和其依赖。这使得Docker容器更轻量、更快速而且更易于部署。

13.Docker镜像和容器有何区别?

Docker镜像是一个只读的模板,用于创建容器实例。容器是Docker镜像的运行实例。

14.如何创建Docker容器?

使用Dockerfile定义应用程序的环境和依赖关系,然后使用docker build命令构建镜像,最后使用docker run命令创建并启动容器。

15.如何将容器与主机进行交互?

可以通过将容器的端口映射到主机的端口,或者使用Docker网络创建连接到容器的网络。

16.如何在Docker容器中安装软件?

可以在Dockerfile中使用适当的包管理器(如apt-get、yum)来安装所需的软件。

17.如何将文件复制到Docker容器中?

可以使用Dockerfile的COPY或ADD命令将本地文件复制到容器中。

18.如何查看Docker容器的日志?

使用docker logs命令可以查看容器的日志。

19.如何创建Docker镜像?

可以使用Dockerfile和docker build命令来创建自定义的Docker镜像。

20.如何通过Docker提高应用程序的扩展性?

可以使用Docker容器来部署和管理多个实例的应用程序,以提高应用程序的可扩展性。

21.Docker有哪些优点?

Docker可以提供更高的应用程序密度、更快的部署和启动时间、更好的资源利用率、更轻量的虚拟化解决方案等优点。

22.Docker有哪些缺点?

Docker在启动速度、容器间隔离性等方面可能略逊于传统虚拟机。此外,使用Docker可能需要一些学习和配置成本。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值