Docker
一、Docker简介
1、简介
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖到一个可抑的容器中,然后发布到任何流行的Linux平台上,也可以实现虚拟化。容器完全使用沙盒机制,相互之间不会存在任何接口,几乎没有性能消耗,可以很容易的在机器和数据中心运行。最重要的是它不需要依赖任何的语言、框架或者包装系统。
简单的说:Docker解决了运行环境和配置问题的软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术。
2、Docker的三要素
-
镜像(image)
Docker镜像就是一个只读的模板。镜像可以用来创建docker容器,一个镜像可以创建很多个容器。
它也相当于一个root文件系统。比如官方镜像centOS7,就包含了一整套最小的root文件系统。
相当于容器的源代码,docker镜像文件类似于Java的类模板,而docker容器实例类似于Java通过new出来实例的对象。
-
容器(container)
- 从面向对象的角度,Docker利用容器独立运行一个或者一组应用,应用程序或服务运行在容器里面,容器就类似于一个虚拟化的运行环境,容器是用镜像创建的实例,就像Java里的类和实例对象一样,镜像是静态的定义,容器是镜像运行的实体。容器为镜像提供了一个标准的和隔离的运行环境,它可以被启动、运行、暂停、删除。每个容器都是相互隔离的,保证安全的平台。
- 从镜像的角度,可以把容器看作一个简易的Linux环境和运行在其中的程序。
-
仓库(repository)
是集中存放镜像的场所。类似于maven存放各种jar包,GitHub存放各种Git项目,docker hub是存放各种镜像模板的地方。
二、Docker安装
1、如果之前安装过老版本需要卸载
yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine
2、安装gcc相关
yum -y install gcc
yum -y install gcc-c++
3、安装yum工具包
yum -y install yum-utils
4、配置仓库资源
# 1. 默认使用国外源,非常非常非常慢!
yum-config-manager \--add-repo \https://download.docker.com/linux/centos/docker-ce.repo# 2. 推荐用国内源,丝滑!
yum-config-manager \--add-repo \http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
5、更新yum软件包索引(可做可不做)
yum makecache fast
6、安装Docker
yum install docker-ce docker-ce-cli containerd.io
7、启动Docker
systemctl start docker
8、查看是否安装成功
// 查看docker版本
docker version// 查看是否安装成功,要先从远程仓库拉取镜像
docker pull hello-world
docker run hello-world
9、配置阿里云镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{"registry-mirrors": ["https://8oizdfoz.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
10、卸载Docker
systemctl stop docker
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
三、Docker的常用指令
1、帮助启动类命令
-
启动docker:
systemctl start docker
-
关闭docker:
systemctl stop docker
-
重启docker:
systemct restart docker
-
查看docker状态:
systemctl status docker
-
开机自启动docker:
systemctl enable docker
-
查看docker概要信息:
docker info
-
查看docker总体帮助文档:
docker help
-
查看docker指定命令文档:
docker [指令] help
2、镜像指令
docker images
:列出本主机上的所有镜像- -a 列出本地所有镜像(包括历史映像层)
- -q 只显示镜像Id
docker search [镜像名]
:从镜像仓库查找镜像- docker search --limit 5 redis 从镜像仓库里查找排名前五的名为Redis的镜像
docker pull [镜像名]
:下载镜像docker pull [镜像名] [TAG]
:下载指定版本的镜像,没有写就是最新的
docker system df
:查看镜像、容器、数据卷所占用的空间docker rmi [镜像名/镜像Id]
:删除镜像docker rmi -f [镜像名/镜像Id]
:强制删除docker rmi -f [镜像名]:[TAG] [镜像名]:[TAG]
:删除多个镜像docker rmi -f $(docker image -qa)
:删除所有镜像,其中指令 “docker image -qa” 查询所有镜像Id
3、容器命令
docker run [OPTIONS] IMAGE [COMMAND] [ARG]
:新增或启动容器[OPTIONS]
说明:有时“-”,有时“–”,常用- –name:为容器指定一个名称
- -d:后台运行容器并返回容器Id
- -i:以交互模式运行容器,常与 -t 一起使用
- -t:为容器重新分配一个伪命令终端,常与 -i 一起使用
- -it:启动交互式容器,前台有伪终端,等待交互
- -P:随机端口映射
- -p:指定端口映射
[COMMAND]
说明:指令,如/bin/bash
docker ps [OPTIONS]
:列举容器中正在运行的镜像[OPTIONS]
说明:- -a:列出当前正在运行的容器 + 历史运行过的容器
- -l:显示最近创建的容器
- -n:显示最近创建的n个容器
- -q:静默模式,只显示容器编号
- 在容器中退出容器:
exit
:退出并停止当前容器Ctrl + p + q
:退出,但当前容器并不终止
docker start [容器Id/容器名]
:启动已经停止的容器/容器名docker restart [容器Id/容器名]
:重启容器/容器名docker stop [容器Id/容器名]
:停止容器/容器名docker kill [容器Id/容器名]
:强制停止容器/容器名docker rm [容器Id/容器名]
:删除容器/容器名,注意区分docker rmi [镜像Id]
,删除- 启动守护式容器:
docker run -d [容器ID/容器名]
- 查看容器日志:
docker logs [容器ID]
- 查看容器内部运行的进程:
docker ps,docker top [容器ID]
- 查看容器内部细节:
docker inspect [容器ID]
- 进入正在运行的容器并以命令行交互:
docker exec -it [容器ID] bashShell
,在容器中打开新的终端,启动新的进程,exit
退出时,不会导致容器停止docker attach [容器ID]
,直接进入容器启动命令终端,不会启动新的进程,exit退出时,会导致容器的停止- 例:
docker exec -it [容器ID] /bin/bash
,redis-cli -p 6379
- 从容器中拷贝文件到当前主机上:
docker ps [容器ID]:容器内路径 目的主机路径
- 导出和导出容器:
- 导出容器:
docker export [容器ID] > 文件名.tar
- 导入容器:
cat 文件名.tar | docker import - 镜像用户/镜像名: 镜像保本号
- 导出容器:
四、镜像
1、何为镜像?
是一种轻量级的、可执行的独立软件包,它包含某些软件所需的所有内容,我们把应用程序和配置依赖打包好成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。
Docker镜像层是只读的,容器层是可写的。当容器启动时,一个新的可写层被加载到镜像的底部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
2、UnionFS(联合文件系统)
是一种分层的、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同的目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
3、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等等。
4、镜像分层
docker commit
:提交一个容器副本使之成为一个新的镜像docker commit -m="提交的描述信息" -a="作者" 容器Id 要创建的目标镜像名:[标签名]
案例:Ubuntu安装vim文本编辑器
- 从Docker Hub上下载Ubuntu镜像到本地运行(原始的Ubuntu镜像是不带vim命令的)
- 外网联通的情况下,安装vim
- 安装完成后,commit提交Ubuntu容器副本使之成为一个新的Ubuntu镜像
- 启动我们的新镜像,和原来的做对比
总结
Docker中的镜像分层,支持通过现有的镜像,创建新的镜像。类似于Java中的继承,基于一个Base类,按需扩展成想要的类。新镜像是从base镜像一层层叠加生成的,每安装一个软件,就是在现有的镜像基础上加一层。
五、本地镜像发布到阿里云
略
六、本地镜像推送到私有库
1、下载镜像Docker Registry
dokcer pull registry
2、运行私有库Docker Registry
相当于本地有个docker hub,默认情况下,仓库被创建在/var/lib/registry
目录下,建议自行用容器卷映射,方便与宿主机联调
docker run -d -p 5000:5000 -v /zly/myRegistry/:/tmp/registry --privileged=true registry
* -d 后台运行
* -p 端口映射
* -v
* -- privileged
3、创建一个新镜像
案例演示,Ubuntu安装ifconfig指令,生成新的镜像
ifconfig指令1、docker pull ubuntu:下载Ubuntu镜像
2、docker run -it ubuntu:以交互式启动Ubuntu镜像
3、apt-get update:Ubuntu容器内部包的更新
4、apt-get install net-tools:Ubuntu容器内部安装ifconfig指令
5、Ctrl + p + q:退出当前容器,但不会使容器停止
6、docker commit -m="first commit" -a="zly" 容器Id 要创建的目标镜像名:[标签名]:提交并生成新的镜像
4、查看私有库里有什么镜像
curl -XGET http://124.222.32.135:5000/v2/_catalog
结果:{"repositories":[""]}
5、将新镜像名称修改成符合私服规范的tag
docker tag myubuntuifconfig:1.0 124.222.32.135:5000/myubuntuifconfig:1.0
6、修改docker配置文件使之支持http
修改完成后如果不生效,则重启docker
vim /etc/docker/daemon.json 修改配置文件添加 "insecure-registries": ["124.222.32.135:5000"]
修改后:
{"registry-mirrors": ["https://8oizdfoz.mirror.aliyuncs.com"],"insecure-registries": ["124.222.32.135:5000"]
}
7、推送镜像
docker pull 124.222.32.135:5000/myubuntuifconfig:1.0
8、查看私有库里是否有推送的镜像
curl -XGET http://124.222.32.135:5000/v2/_catalog
结果:{"repositories":["myubuntuifconfig"]}
9、pull到本地并运行
docker pull 124.222.32.135:5000/myubuntuifconfig:1.0
docker run -it 124.222.32.135:5000/myubuntuifconfig:1.0
七、Docker容器数据卷
1、–privileged=true详解
Centos7的安全模块比之前的系统版本进行了加强,不安全的会先安全禁止,所以目录挂载会被认为是不安全的操作。在SELinux里挂载目录被禁止掉了,如果要开启,我们一般添加 --privileged=true
指令,扩大容器权限,解决目录挂载没有权限的问题。也即使用该参数,container容器内的root拥有了真正的root权限,否则,container内部的root权限只是外部的普通用户权限。
当Docker挂载主机目录访问如果出现cannot open dictionary .: Permission denied
,可使用 --privileged=true
指令解决
2、Docker容器数据卷是什么
有点类似于Redis中的RDB和AOF文件,将Docker容器内的数据保存到宿主机的磁盘中
卷是目录或者文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System 提供一些用于持续存储或共享数据的特性。卷设计的目的就是为了数据的持久化,完全独立于容器的生命周期,因此Docker不会在删除容器时山区其挂载的数据卷。
容器卷的特点:
- 数据卷可以在容器之间共享或重用数据
- 卷中数据的更改可以直接实时生效
- 数据卷的修改不会包含在镜像的更新中
- 数据卷的生命周期会一直持续到没有容器使用它为止
docker run -v /宿主机路径:/docker容器内路径 --privileged=true 容器名
docker run -v /宿主机路径:/docker容器内路径:ro --privileged=true 容器名 限制容器内只能读取,不能写,read-only
docker run --privileged=true --volumes-from u1 --name u2 容器名 容器u2继承u1的数据卷,u1和u2是相互独立的,一主二从
八、Docker上安装软件
1、安装MySQL(单机版)
1、拉取MySQL镜像docker pull mysql:5.7
2、运行MySQL镜像docker run -d -p 3306:3306 --privileged=true \-v /zly/mysql/log:/var/log/mysql \-v /zly/mysql/data:/var/lib/mysql \-v /zly/mysql/conf:/etc/mysql/conf.d \-e MYSQL_ROOT_PASSWORD=123456 \--name mysql mysql:5.73、在文件夹/zly/mysql/conf下新建my.cnf的MySQL配置文件,并写入一下内容[client]default_character_set=utf8[mysqld]collation_server=utf8_general_cicharacter_set_server=utf84、设置docker启动时启动mysqldocker update mysql --restart=always5、重启MySQLdocker restart 容器ID6、进入mysql容器内部docker exec -it mysql /bin/bash7、登录mysqlmysql -uroot -p 回车后输入密码
2、安装Redis
1、拉取Redis镜像docker pull redis
2、redis.conf# 绑定IP地址#解除本地限制 注释bind 127.0.0.1 #bind 127.0.0.1 # 服务器端口号 port 6379 #配置密码,不要可以删掉#requirepass syf133618#这个配置不要会和docker -d 命令 冲突# 服务器运行模式,Redis以守护进程方式运行,默认为no,改为yes意为以守护进程方式启动,可后台运行,除非kill进程,改为yes会使配置文件方式启动redis失败,如果后面redis启动失败,就将这个注释掉daemonize no#当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定(自定义)#pidfile /data/dockerData/redis/run/redis6379.pid #默认为no,redis持久化,可以改为yesappendonly yes#当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能timeout 60# 服务器系统默认配置参数影响 Redis 的应用maxclients 10000tcp-keepalive 300#指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合(分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改)save 900 1save 300 10save 60 10000# 按需求调整 Redis 线程数tcp-backlog 511# 设置数据库数量,这里设置为16个数据库 databases 16# 启用 AOF, AOF常规配置appendonly yesappendfsync everysecno-appendfsync-on-rewrite noauto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mb# 慢查询阈值slowlog-log-slower-than 10000slowlog-max-len 128# 是否记录系统日志,默认为yes syslog-enabled yes #指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verboseloglevel notice# 日志输出文件,默认为stdout,也可以指定文件路径 logfile stdout# 日志文件#logfile /var/log/redis/redis-server.log# 系统内存调优参数 # 按需求设置hash-max-ziplist-entries 512hash-max-ziplist-value 64list-max-ziplist-entries 512list-max-ziplist-value 64set-max-intset-entries 512zset-max-ziplist-entries 128zset-max-ziplist-value 64
3、运行Redis镜像
docker run -p 6379:6379 --name redis --privileged=true \-v /zly/redis/redis.conf:/etc/redis/redis.conf \-v /zly/redis/data:/data \-d redis redis-server /etc/redis/redis.conf
4、进入Redis容器docker exec -it redis /bin/bash
5、进入客户端redis-cli
3、安装MySQL(集群版)
安装主服务器容器实例
(1)、启动容器实例:3307
docker run -d -p 3307:3306 --privileged --name mysql-master \-v /zly/mysql-cluster/mysql-master/log:/var/log/mysql \-v /zly/mysql-cluster/mysql-master/data:/var/lib/mysql \-v /zly/mysql-cluster/mysql-master/conf:/etc/mysql \-e MYSQL_ROOT_PASSWORD=root \mysql:5.7
(2)、进入/zly/mysql-cluster/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
(3)、重启容器实例
docker restart mysql-master
(4)、进入mysql-master
容器实例内部
docker exec -it mysql-master /bin/bash
mysql -uroot -proot
(5)、在mysql-master
主数据库中创建数据同步用户
// 创建用户
create user 'slave'@'%' identified by '123456';
// 授权
grant replication slave, replication client on *.* to 'slave'@'%';
安装从服务器容器实例
(1)、启动容器实例:3308
docker run -d -p 3308:3306 --privileged --name mysql-slave \-v /zly/mysql-cluster/mysql-slave/log:/var/log/mysql \-v /zly/mysql-cluster/mysql-slave/data:/var/lib/mysql \-v /zly/mysql-cluster/mysql-slave/conf:/etc/mysql \-e MYSQL_ROOT_PASSWORD=root \mysql:5.7
(2)、进入/zly/mysql-cluster/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
(3)、重启容器实例
docker restart mysql-slave
在主数据库中查看主从同步状态
docker exec -it mysql-master /bin/bash
mysql -uroot -p
show master status
主要查看返回结果的文件名File
、当前位置Position
在从数据库中配置主从复制
(1)、进入从服务器
docker exec -it mysql-master /bin/bash
mysql -uroot -p
(2)、配置主从复制
change master to master_host='124.222.32.135', master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-bin.000001', master_log_pos=617, master_connect_retry=30;
解释:
change master to master_host='宿主机ip',
master_user='主数据库配置的主从复制用户名',
master_password='主数据库配置的主从复制用户密码',
master_port=宿主机主数据库端口,
master_log_file='主数据库主从同步状态的文件名File',
master_log_pos=主数据库主从同步状态的Position,
master_connect_retry=连接失败重试时间间隔(秒);
(3)、查看主从同步状态
# \G 可以将横向的结果集表格转换成纵向展示。
# slave status的字段比较多,纵向展示比友好
show slave status \G;
除了展示刚刚配置的主数据库信息外,主要关注 Slave_IO_Running
、Slave_SQL_Running
。目前两个值应该都为 No
,表示还没有开始。
(4)、开启主从同步
start slave;
(5)、查看主从同步状态
主从复制测试:
(1)、 在主数据库上新建库、使用库、新建表、插入数据
create database db01;
use db01;
create table t1 (id int, name varchar(20));
insert into t1 values (1, 'abc');
(2)、 在从数据库上使用库、查看记录
show databases;
use db01;
select * from t1;
4、3主3从Redis集群
(1)、启动6台Redis节点
# 启动第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 /zly/redis-cluster/share/redis-node-1:/data redis --cluster-enabled yes --appendonly yes --port 6381# 启动第2台节点
docker run -d --name redis-node-2 --net host --privileged=true -v /zly/redis-cluster/share/redis-node-2:/data redis --cluster-enabled yes --appendonly yes --port 6382# 启动第3台节点
docker run -d --name redis-node-3 --net host --privileged=true -v /zly/redis-cluster/share/redis-node-3:/data redis --cluster-enabled yes --appendonly yes --port 6383# 启动第4台节点
docker run -d --name redis-node-4 --net host --privileged=true -v /zly/redis-cluster/share/redis-node-4:/data redis --cluster-enabled yes --appendonly yes --port 6384# 启动第5台节点
docker run -d --name redis-node-5 --net host --privileged=true -v /zly/redis-cluster/share/redis-node-5:/data redis --cluster-enabled yes --appendonly yes --port 6385# 启动第6台节点
docker run -d --name redis-node-6 --net host --privileged=true -v /zly/redis-cluster/share/redis-node-6:/data redis --cluster-enabled yes --appendonly yes --port 6386
(2)、构建主从关系
1. 进入节点1(或其中任意一个节点): docker exec -it redis-node-1 /bin/bash
2. 构建主从关系:redis-cli --cluster create 124.222.32.135:6381 124.222.32.135:6382 124.222.32.135:6383 124.222.32.135:6384 \124.222.32.135:6385 124.222.32.135:6386 --cluster-replicas 1
3. redis尝试自动进行主从节点分配
4. 因为我们的docker容器IP相同,所以会出现警告,可以直接忽略该警告,[WARNING] Some slaves are in the same host as their master
5. redis自动分配结果完成后,需要输入 Yes 确认配置信息
6. 输入Yes确认后,redis会向其他节点发送信息加入集群,并分配哈希槽:
(3)、查看集群状态:
1. 进入容器节点1(或集群中其他节点): docker exec -it redis-node-1 /bin/bash
2. 使用redis-cli连接到6381节点: redis-cli -p 6381
3. 使用redis的相关命令查看集群状态: cluster info其中,分配的哈希槽数量 cluster_slots_assigned为16384,集群节点数量cluster_known_nodes为6
4. 查看集群节点信息 cluster nodes
(4)、Redis集群读写出错
当使用 redis-cli连接redis集群时,需要添加 -c参数,否则可能会出现读写出错。示例:
1. 进入容器节点1 docker exec -it redis-node-1 /bin/bash
2. 使用redis-cli连接,不加-c参数时 redis-cli -p 6381
3. 此时向redis中添加键值对,可能会成功,也可能会失败 set k1 v1报错:k1经过计算得到的哈希槽为12706,但是当前连接的redis-server为6381(即节点1),它的哈希槽为:[0,5460](在创建构建主从关系时redis有提示,也可以通过 cluster nodes查看),所以会因为存不进去而报错。 执行 set k2 v2可以成功,因为k2计算出的哈希槽在[0-5460]区间中。
4. 使用-c参数的redis-cli命令连接即可 redis-cli -p 6381 -c
5. 此时可以正常的插入所有数据 set k1 v1会有提示信息,哈希槽为12706,重定向到6383(即节点3,哈希槽[10923, 16383]):
(5)、集群信息检查
# 输入任意一台主节点地址都可以进行集群检查
redis-cli --cluster check 124.222.32.135:6381
(6)、主从扩容
假如因为业务量激增,需要向当前3主3从的集群中再加入1主1从两个节点。
1、启动2台新的容器节点 docker run -d --name redis-node-7 --net host --privileged=true -v /zly/redis-cluster/share/redis-node-7:/data redis --cluster-enabled yes --appendonly yes --port 6387docker run -d --name redis-node-8 --net host --privileged=true -v /zly/redis-cluster/share/redis-node-8:/data redis --cluster-enabled yes --appendonly yes --port 63882、进入6387(节点7)容器内部 docker exec -it redis-node-7 /bin/bash3、将6387作为master加入集群 # redis-cli --cluster add-node 本节点地址 要加入的集群中的其中一个节点地址redis-cli --cluster add-node 124.222.32.135:6387 124.222.32.135:63814、检查当前集群状态 redis-cli --cluster check 124.222.32.135:6381可以发现,6371节点已经作为master加入了集群,但是该节点没有被分配槽位。
5、重新分配集群的槽位 redis-cli --cluster reshard 124.222.32.135:6381redis经过槽位检查后,会提示需要分配的槽位数量: 例如,我们现在是4台master,我们想要给node7分配4096个槽位,这样每个节点都是4096个槽位。输入4096后,会让输入要接收这些哈希槽的节点ID,填入node7的节点ID即可。(就是节点信息中很长的一串十六进制串)。然后会提示,询问要从哪些节点中拨出一部分槽位凑足4096个分给Node7。一般选择 all,即将之前的3个主节点的槽位都均一些给Node7,这样可以使得每个节点的槽位数相等均衡。输入all之后,redis会列出一个计划,内容是自动从前面的3台master中拨出一部分槽位分给Node7的槽位,需要确认一下分配的计划。输入yes确认后,redis便会自动重新洗牌,给Node7分配槽位。 重新分配完成后,可以进行集群信息检查,查看分配结果:redis-cli --cluster check 124.222.32.135:6381可以发现重新洗牌后的槽位分配为:节点1:[1365-5460](供4096个槽位),,,分配前为[0-5460](共5461个槽位)节点2:[6827-10922](共4096个槽位),,,分配前为[5461-10922](共5461个槽位)节点3:[12288-16383](共4096个槽位),,,分配前为[10923-16383](共5462个槽位)节点7:[0-1364],[5461-6826],[10923-12287](共4096个槽位),从每个节点中匀出来了一部分给了节点7因为可能有些槽位中已经存储了key,完全的重新洗牌重新分配的成本过高,所以redis选择从前3个节点中匀出来一部分给节点7
6、为主节点6387分配从节点6388:redis-cli --cluster add-node 124.222.32.135:6388 124.222.32.135:6381 --cluster-slave --cluster-master-id node7节点的十六进制编号字符串redis便会向6388发送消息,使其加入集群并成为6387的从节点。
7、检查集群当前状态redis-cli --cluster check 124.222.32.135:6381
(7)、主从缩容
假如业务高峰期过去,需要将4主4从重新缩容到3主3从。即从集群中移除node8和node7.
1、进入容器节点1 docker exec -it redis-node-1 /bin/bash2、检查容器状态,获取6388的节点编号 redis-cli --cluster check 124.222.32.135:63813、将6388从集群中移除 redis-cli --cluster del-node 124.222.32.135:6388 6388节点编号4、对node7重新分配哈希槽:redis-cli --cluster reshard 124.222.32.135:6381redis经过槽位检查后,会提示需要分配的槽位数量: How many slots do you want to move (from 1 to 16384)?如果我们想直接把node7的4096个哈希槽全部分给某个节点,可以直接输入4096。输入4096后,会让输入要接收这些哈希槽的节点ID。假如我们想把这4096个槽都分给Node1,直接输入node1节点的编号即可。然后会提示,询问要从哪些节点中拨出一部分槽位凑足4096个分给Node1。这里我们输入node7的节点编号,回车后输入done。 node7上面没有了哈希槽,此时便可以将node7从集群中移除。(如果node7上面有哈希槽,直接从集群中移除会报错)
redis-cli --cluster del-node 124.222.32.135:6387 node7节点编号
九、DockerFile解析
1、概述
DockerFile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。
构建步骤
- 编写DockerFile文件
docker build
命令构建镜像docker run
运行镜像容器实例
2、DockerFile文件构建过程解析
a、DockerFile文件基础知识
- 每条保留字指令都必须为大写字母且后面至少要跟一个参数
- 指令按照从上到下顺序执行
- #表示注释
- 每条指令都会创建一个新的镜像,并对镜像进行提交
b、docker执行Dockerfile的大致流程
- docker从基础镜像运行一个容器
- 执行一条命令并对容器做出修改
- 执行类似
docker commit
的操作提交一个新的镜像层 - docker 再基于刚刚提交的镜像运行一个新的容器
- 执行dockerfile中的下一条指令,直至所有指令都执行完成
总结
从应用软件的角度来看,dockerfile
,docker镜像
,docker容器
分别代表软件的三个阶段:
- dockerFile是软件的原材料
- docker镜像是软件的交付品
- docker容器则是软件镜像的运行态,也即依照镜像运行的容器实例
dockerfile面向开发,docker镜像成为交付的标准,docker容器则涉及部署与运维,三者缺一不可,合力充当docker体系的基石。
3、dockerfile常用保留字
- FROM:基础镜像,当前镜像是基于哪个镜像的,指一个已经存在的镜像模板,在dockerfile文件的第一行
- MAINTAINER:镜像维护者的姓名和邮箱
- RUN:容器构建时需要运行的命令,在
docker build
时运行,一般有两种格式- shell格式:
RUN <命令行命令>
- exec格式:
RUN ["可执行文件", "参数1", "参数2"]
- shell格式:
- EXPOSE:当前容器对外暴露的端口
- WORKDIR:指定在容器创建后,终端默认进入容器内的工作目录,一个落脚点
- USER:指定该镜像以什么样的用户去执行,如果都不指定,则默认
root
- ENV:用于构建镜像过程中设置环境变量
- ADD:将宿主机下的文件拷贝进镜像,且会自动处理
URL
和解压tar
压缩包 - COPY:
- 类似
ADD
,拷贝文件和目录到镜像中。将从构建上下文目录中<源路径>
的文件目录复制到新的一层镜像内的<目标路径>
位置。COPY src dest
COPY ["src", "dest"]
- VOLUME:容器数据卷,用于数据保存和持久化操作
- CMD:指定容器启动后要做什么事情,如果有多个
CMD
指令,只有最后一个会生效,CMD
会被docker run
后面的参数替代 - ENTRYPOINT:
- 用来指定一个容器启动时要运行的命令。
- 类似于
CMD
命令,但是ENTRYPOINT
不会被docker run
后面的命令覆盖,这些命令参数会被当做参数送给ENTRYPOINT
指令指定的程序。 ENTRYPOINT
可以和CMD
一起用,一般是可变参数才会使用CMD
,这里的CMD
等于是在给ENTRYPOINT
传参。- 当指定了
ENTRYPOINT
后,CMD
的含义就发生了变化,不再是直接运行期命令,而是将CMD
的内容作为参数传递给ENTRYPOINT
指令,它们两个组合会变成<ENTRYPOINT> "<CMD>"
。
4、构建镜像
a、新建dockerfile文件
FROM centos
MAINTAINER zly@1163977538@qq.com
ENV MYPATH /usr/local
WORKDIR $MYPATH
#CentOS8 yum源配置
RUN rm -f /etc/yum.repos.d/*.repo
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-8.repo
#安装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-8u271-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置
ADD jdk-8u271-linux-x64.tar.gz /usr/local/java/
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_271
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
b、下载jdk
下载jdk-8u271-linux-x64.tar.gz并把其放入和Dockerfile文件在同一位置
c、构建镜像
# 注意:定义的TAG后面有个空格,空格后面有个点
# docker build -t 新镜像名字:TAG .
docker build -t centosjava8:1.0.1 .
d、启动镜像
docker run -it 810641de7ec0 /bin/bash
e、测试
1、进入后在 /usr/local 文件夹下
2、测试vim 编辑器
3、测试 ifconfig
4、测试 java -version
十、Docker运行微服务
1、在idea中升成jar包
把项目在Maven下 docker-test -> Lifecycle -> package -> 生成docker-test-1.0-SNAPSHOT.jar
将jar包放在和Dockerfile文件同一目录下
2、在Linux目录下编写Dockerfile文件
FROM openjdk:11-jre
MAINTAINER zly@1163977538@qq.com# 在主机 /var/lib/docker目录下创建一个临时文件,并链接到容器的 /tmp
VOLUME /tmp# 将jar包添加到容器中,并命名为 springboot_docker.jar
ADD docker-test-1.0-SNAPSHOT.jar /springboot_docker.jar
# 运行jar包
RUN bash -c 'touch /springboot_docker.jar'
ENTRYPOINT ["java", "-jar", "/springboot_docker.jar"]# SpringBoot项目配置的端口号为9876,需要将9876暴露出去
EXPOSE 9876
3、构建镜像
# 注意:定义的TAG后面有个空格,空格后面有个点(可能需要先拉取镜像openjdk:11-jre)
# docker build -t 新镜像名字:TAG .
docker build -t docker-spring-boot-test:1.0 .
4、启动容器
docker run -d -p 9876:9876 docker-spring-boot-test:1.0
5、测试
http://124.222.32.135:9876/docker/index
十一、Docker network
1、概述
docker安装并成功启动后,会在宿主机添加一个虚拟网卡docker0
作用:
- 容器之间的互联和通信,以及端口映射
- 容器ip变动的时候,可以通过服务名直接网络通信而不受到影响
docker容器的网络隔离是通过Linux内核特性namespace
和cgroup
实现的
2、常用指令
使用 --help 查询
docker network --helpconnect Connect a container to a networkcreate Create a networkdisconnect Disconnect a container from a networkinspect Display detailed information on one or more networksls List networksprune Remove all unused networksrm Remove one or more networks
3、网络模式
网络模式 | 简介 |
---|---|
bridge | 为每一个容器分配、设置 IP 等,并将容器连接到一个docker0 ,虚拟网桥,默认为该模式 |
host | 容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口 |
none | 容器有独立的NetWork NameSpace,并没有对其进行网络配置,入分配veth pair 和网桥连接,IP 等 |
container | 新建的容器不会虚拟出自己的网卡,配置自己的 IP 等,而是和一个指定的容器共享 IP 、端口范围等 |
docker0
Docker 服务默认会创建一个docker0
网桥(其上有一个docker0
内部接口),该桥接网络的名称为 docker0
,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。
Docker默认指定了docker0
接口的IP地址和子网掩码,让主机和容器之间可以通过网桥互相通信。
查看bridge
网络的详细信息,并通过grep
获取名称:
docker network inspect bridge | grep name
可以看到其名称为docker0
。
bridge模式
Docker使用Linux桥接,在宿主机虚拟一个Docker
容器网桥(docker0
),Docker启动一个容器时会根据Docker
网桥的网段分配给容器一个IP地址,称为Container-IP
,同时Docker网桥是每个容器的默认网关。因为在同一个宿主机内的容器接入同一个网桥,这样容器之间就能够通过容器的Container-IP
直接通信。
docker run
的时候,没有指定--network
的话,默认使用的网桥模式就是bridge
,使用的就是docker0
。在宿主机ifconfig
就苦役看到docker0
和自己create
的network
。
网桥docker0
创建一对对等虚拟设备接口,一个叫veth
,另一个叫eth0
,成对匹配:
整个宿主机的网桥模式都是docker0
,类似一个交换机有一堆接口,每个接口叫 veth
,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫做 veth pair
)。
每个容器实例内部也有一块网卡,容器内的网卡接口叫做eth0
。
docker0
上面的每个veth
匹配某个容器实例内部的eth0
,两两配对,一一匹配。
例如:
启动tomcat容器,进入tomcat容器后,执行 ip addr
,可以看到其网卡信息:
1: lo ..................容器内的网卡为 eth0
@符号后面就是宿主机上对应的veth网卡的编号28
27: eth0@if28 ...............................
在宿主机执行 ip addr
查看宿主机网卡信息:
每个veth都有个编号:vethXXXXXX
@符号后面对应就是容器内的eth0网卡编号2728: vethXXXXXX@if27 ................
host模式
直接使用宿主机的 IP 地址与外界进行通信,不再需要额外进行 NAT 转换。
容器将不会获得一个独立的 Network Namespace,而是和宿主机共用一个 Network space。
容器将不会虚拟出自己的网卡,而是直接使用宿主机的 IP 和端口。
如果在 docker run
命令中同时使用了 --network host
和 -p
端口映射,例如:
docker run -p 8082:8080 --network host tomcat
那么会出现一个警告:
WARNING: Published ports are discarded when using host network mode
因为此时已经使用了host
模式,本身就是直接使用的宿主机的IP和端口,此时的-p
端口映射就没有了意义,也不会生效,端口号还是会以主机端口号为主。
正确做法是:不再进行-p
端口映射,或者改用bridge
模式
none模式
禁用网络功能。
在none
模式下,并不为docker容器进行任何网络配置。进入容器内,使用 ip addr
查看网卡信息,只能看到 lo
(本地回环网络127.0.0.1
网卡)。
container模式
新建的容器和已经存在的一个容器共享网络IP配置,而不是和宿主机共享。
新创建的容器不会创建自己的网卡、IP,而是和一个指定的容器共享IP、端口范围。两个容器除了网络共享,其他的如文件系统、进程列表依然是隔离的。
示例:
docker run -it --name alpine1 alpine /bin/sh# 指定和 alpine1 容器共享网络
docker run -it --network container:alpine1 --name alpine2 alpine /bin/sh
此时使用 ip addr
查看两台容器的网络,会发现两台容器的eth0
网卡内的IP等信息完全相同。
如果关掉了alpine1
容器,因为alpine2
的网络使用的alpine1
共享网络,所以关掉alpin1
后,alpine2
的eth0
网卡也随之消失了。
自定义网络
容器间的互联和通信以及端口映射。
容器 IP 变动时候可以通过服务名直接网络通信而不受影响。(类似Eureka,通过服务名直接互相通信,而不是写死IP地址)。
docker中还有一个 --link
进行容器网络互联,但是已经被标记为过时的,可能会在将来的版本中移除这个功能。推荐使用自定义网络替换link。
自定义桥接网络(自定义网络默认使用的是桥接网络 bridge
):
- 新建自定义网络
docker network create tomcat_network
- 查看网络列表
docker network ls
- 创建容器时,指定加入我们自定义的网络中
docker run -d -p 8081:8080 --network tomcat_network --name tomcat1 tomcat:8.5-jdk8-correttodocker run -d -p 8082:8080 --network tomcat_network --name tomcat2 tomcat:8.5-jdk8-corretto
- 此时进入
tomcat1
中,使用ping
命令测试连接tomcat2
容器名,发现可以正常连通
# 安装ifconfig命令
yum install -y net-tools
# 安装ip addr命令
yum install -y iproute
# 安装ping命令
yum install -y iputils# 直接ping容器名,不需要ping IP地址
ping tomcat2
十二、Docker-compose容器编排
1、概述
Docker-Compose
是 Docker 官方的开源项目,负责实现对Docker容器集群的快速编排。
Docker-Compose
可以管理多个Docker容器组成一个应用。需要定义一个yaml格式的配置文件 docker-compose.yml
,配置好多个容器之间的调用关系,然后只需要一个命令就能同时启动/关闭这些容器。
2、安装Docker-Compose
Docker-Compose
的版本需要和Docker引擎版本对应,可以参照官网上的对应关系。
安装Compose:
# 例如从github下载 2.5.0版本的docker-compose
# 下载下来的文件放到 /usr/local/bin目录下,命名为 docker-compose
curl -L https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose# 添加权限
chmod +x /usr/local/bin/docker-compose# 验证
docker-compose version
卸载Compose:直接删除 usr/local/bin/docker-compose
文件即可
3、核心概念
-
服务(
service
):一个个应用容器实例 -
工程(
project
):由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml
中定义
4、使用步骤
- 编写 Dockerfile 定义各个应用容器,并构建出对应的镜像文件
- 编写
docker-compose.yml
,定义一个完整的业务单元,安排好整体应用中的各个容器服务 - 执行
docker-compose up
命令,其创建并运行整个应用程序,完成一键部署上线
5、常用命令
docker-compose -h 查看帮助docker-compose up 创建并启动docker-compose服务
docker-compose up -d # 后台运行docker-compose down 停止并删除容器、网络、卷、镜像ocker-compose exec <yml里面的服务id> /bin/bash 进入容器实例内部docker-compose ps 展示当前docker-compose编排过的运行的所有容器
docker-compose top 展示当前docker-compose编排过的容器进程docker-compose log <yml里面的服务id> 查看容器输出日志docker-compose config 检查配置
docker-compose config -q # 有问题才输出docker-compose restart 重启服务
docker-compose start 启动服务
docker-compose stop 停止服务
6、部署微服务(mysql+redis+微服务)
1、启动MySQL,详见第八章第一节 安装MySQL(单机版)
2、启动redis,详见第八章第二节 安装Redis
3、构建镜像,运行微服务
上述方法的弊端:
- 容器启动先后顺序固定,必须先启动mysql+redis
- 多个run指令,操作复杂
- 容器间的启停或宕机,有可能导致IP地址对应的容器实例发生变化,映射出错,要么生产IP写死(不推荐),要么通过服务调用
7、compose编排服务
a. 编写docker-compose.yml文件
# docker-compose文件版本号
version: "3"# 配置各个容器服务
services:microService:image: docker-compose:1.0container_name: docker-compose # 容器名称,如果不指定,会生成一个服务名加上前缀的容器名ports:- "6001:6001"volumes:- /app/microService:/datanetworks:- docker_compose_netdepends_on: # 配置该容器服务所依赖的容器服务- redis- mysqlredis:image: redisports:- "6379:6379"volumes:- /app/redis/redis.conf:/etc/redis/redis.conf- /app/redis/data:datanetworks:- docker_compose_netcommand: redis-server /etc/redis/redis.confmysql:image: mysql:5.7environment:MYSQL_ROOT_PASSWORD: '123456'MYSQL_ALLOW_EMPTY_PASSWORD: 'no'MYSQL_DATABASE: 'docker_compose'MYSQL_USER: 'dev'MYSQL_PASSWORD: 'dev'ports:- "3306:3306"volumes:- /app/mysql/db:/var/lib/mysql- /app/mysql/conf/my.cnf:/etc/my.cnf- /app/mysql/init:/docker-entrypoint-initdb.dnetworks:- docker_compose_netcommand: --default-authentication-plugin=mysql_native_password # 解决外部无法访问networks:# 创建 docker_compose_net 网桥网络docker_compose_net:
b.将项目yml文件中的IP替换为服务名
spring:datasource:username: rootpassword: 123456
# url: jdbc:mysql://124.222.32.135:3306/docker_compose?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghaiurl: jdbc:mysql://mysql:3306/docker_compose?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghaidriver-class-name: com.mysql.cj.jdbc.Driverredis:
# host: 124.222.32.135 host: redis port: 6379 password:database: 0 timeout: 1800000 lettuce:pool:max-active: 20 max-wait: -1max-idle: 5min-idle: 0
c. 构建镜像
docker build -t docker-compose:1.0 .
d.语法检查
docker-compose config -q
e.以docker-compose.yml文件启动项目
docker-compose up -d
十三、Portainer可视化工具
1、概述
Portainer是一款轻量级的应用,它提供了图形化界面,用于方便的管理docker环境,包括单机环境和集群环境。
2、安装
# 旧版镜像地址为portainer/portainer,从2022年1月标记为过期
# 新版镜像地址为portainer/portainer-ce# --restart=always 如果Docker引擎重启了,那么这个容器实例也会在Docker引擎重启后重启,类似开机自启
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-ce
启动之后,便可以在浏览器中进行访问:http://xxx.xxx.xxx.xxx:9000
首次进来时,需要创建 admin 的用户名(默认admin
)、密码(必须满足校验规则,例如portainer.io123
)。
选择 local
管理本地docker,即可看到本地Docker的详细信息,包括其中的镜像(images)、容器(containers)、网络(networks)、容器卷(volumes)、compose编排(stacks)等等。
十四、CIG重量级监控
1、CIG
通过docker stats
命令可以很方便的查看当前宿主机上所有容器的CPU、内存、网络流量等数据,可以满足一些小型应用。
但是 docker stats
统计结果只能是当前宿主机的全部容器,数据资料是实时的,没有地方存储、没有健康指标过线预警等功能。
CAdvisor(监控收集) + InfluxDB(存储数据) + Granfana(展示图表),合称 CIG
。
2、CAdvisor
CAdvisor是一个容器资源监控工具,包括容器的内存、CPU、网络IO、磁盘IO等监控,同时提供了一个Web页面用于查看容器的实时运行状态。
CAdvisor默认存储2分钟的数据,而且只是针对单物理机。不过CAdvisor提供了很多数据集成接口,支持 InfluxDB、Redis、Kafka、Elasticsearch等集成,可以加上对应配置将监控数据发往这些数据库存储起来。
CAdvisor主要功能:
-
展示Host和容器两个层次的监控数据
-
展示历史变化数据
3、InfluxDB
InfluxDB是用Go语言编写的一个开源分布式时序、事件和指标数据库,无需外部依赖。
CAdvisor默认只在本机保存2分钟的数据,为了持久化存储数据和统一收集展示监控数据,需要将数据存储到InfluxDB中。InfluxDB是一个时序数据库,专门用于存储时序相关数据,很适合存储 CAdvisor 的数据。而且 CAdvisor本身已经提供了InfluxDB的集成方法,在启动容器时指定配置即可。
InfluxDB主要功能:
-
基于时间序列,支持与时间有关的相关函数(如最大、最小、求和等)
-
可度量性,可以实时对大量数据进行计算
-
基于事件,支持任意的事件数据
4、Granfana
Grafana是一个开源的数据监控分析可视化平台,支持多种数据源配置(支持的数据源包括InfluxDB、MySQL、Elasticsearch、OpenTSDB、Graphite等)和丰富的插件及模板功能,支持图表权限控制和报警。
Granfana主要功能:
-
灵活丰富的图形化选项
-
可以混合多种风格
-
支持白天和夜间模式
-
多个数据源
5、安装部署
- 编写
docker-compose.yml
服务编排文件
version: '3.1'volumes:grafana_data: {}services:influxdb:# tutum/influxdb 相比influxdb多了web可视化视图。但是该镜像已被标记为已过时image: tutum/influxdb:0.9restart: alwaysenvironment:- PRE_CREATE_DB=cadvisorports:- "8083:8083" # 数据库web可视化页面端口- "8086:8086" # 数据库端口volumes:- ./data/influxdb:/datacadvisor:image: google/cadvisor:v0.32.0links:- influxdb:influxsrvcommand:- -storage_driver=influxdb- -storage_driver_db=cadvisor- -storage_driver_host=influxsrv:8086restart: alwaysports:- "8080:8080"volumes:- /:/rootfs:ro- /var/run:/var/run:rw- /sys:/sys:ro- /var/lib/docker/:/var/lib/docker:rografana:image: grafana/grafana:8.5.2user: '104'restart: alwayslinks:- influxdb:influxsrvports:- "3000:3000"volumes:- grafana_data:/var/lib/grafanaenvironment:- HTTP_USER=admin- HTTP_PASS=admin- INFLUXDB_HOST=influxsrv- INFLUXDB_PORT=8086
- 检查语法
docker-compose config -q
- 创建并启动容器
docker-compose up -d
容器启动之后:
- 在浏览器打开InfluxDB数据库的页面: http://xxx.xxx.xxx.xxx:8083,使用命令查看当前数据库中的数据库实例:
SHOW DATABASES
查看其中是否自动创建了我们在配置文件中配置的 cadvisor
数据库实例
- 在浏览器打开CAdvisor页面:http://xxx.xxx.xxx.xxx8080/,查看当前docker中的cpu、内存、网络IO等统计信息
- 在浏览器打开Grafana页面:http://xxx.xxx.xxx.xxx:3000/,默认用户名密码是:
admin
/admin
。
6、Grafana配置
添加数据源
在Configuration
(小齿轮)选项卡中,选择Data Sources
,添加一个InfluxDB数据源:
-
name:自定义一个数据源名称,例如
InfluxDB
-
Query Language:查询语言,默认
InfluxQL
即可 -
URL:根据compose中的容器服务名连接,
http://influxdb:8086
-
database:我们在InfluxDB中创建的数据库实例,
cadvisor
-
User:InfluxDB的默认用户,
root
-
Password:
root
保存并测试,可以连通即可
添加工作台
-
在
Create
(加号)选项卡中,选择创建Dash Board
工作台。右上角配置中可以配置创建出来的工作台的标题、文件夹等信息。 -
在创建出来的工作台中,选择
Add panel
中的Add a new panel
添加一个新的面板。 -
- 在右上角
Time series
(时序图)位置可以切换展示的图表样式(柱状图、仪表盘、表格、饼图等等) - 右侧边栏为该图表配置相关信息:标题、描述
- 图表下方可以配置该图表展示的数据的查询语句,例如:
- 在右上角
-
-
- FROM:
cpu_usage_total
(Grafana会自动获取InfluxDB数据库中的元数据,可以直接选择对应表名)
- FROM:
-
-
-
- WHERE:添加一个条件,
container_name=cig-cadvisor-1
- WHERE:添加一个条件,
-
-
-
- ALIAS:配置一个别名,
CPU使用情况汇总
- ALIAS:配置一个别名,
-
十五、面试题
1、为什么Docker比VM虚拟机要快?
-
Docker有比虚拟机更少的抽象层
由于Docker不需要虚拟机实现硬件资源虚拟化,运行在Docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存的应用率上Docker更有优势。
-
Docker利用的是宿主机内核,而不需要加载操作系统OS内核
当新建一个容器时,Docker不需要和虚拟机一样重新加载一个操作系统的内核。进而避免引寻、加载操作系统内核返回等比较费时、费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载OS,返回新建过程是分钟级别的。而Docker由于直接利用宿主机操作系统省略了返回过程,因此新建一个Docker是秒级的。
Docker容器 | VM虚拟机 | |
---|---|---|
操作系统 | 与宿主机共享OS | 宿主机OS上运行虚拟机OS |
存储大小 | 镜像小,便于存储和传输 | 镜像庞大(vmdk、vdi等) |
运行性能 | 几乎无额外性能损失 | 操作系统额外的CPU、内存消耗 |
移植性 | 轻便、灵活、适用于Linux | 笨重,与虚拟化技术耦合度高 |
硬件亲和性 | 面向软件开发者 | 面向硬件运维者 |
部署速度 | 快速,秒级 | 较慢,分钟级 |
2、谈谈什么是虚悬镜像
仓库名、标签的值都是的镜像称之为虚悬镜像,一般删除,例:
-
Query Language:查询语言,默认
InfluxQL
即可 -
URL:根据compose中的容器服务名连接,
http://influxdb:8086
-
database:我们在InfluxDB中创建的数据库实例,
cadvisor
-
User:InfluxDB的默认用户,
root
-
Password:
root
保存并测试,可以连通即可
添加工作台
-
在
Create
(加号)选项卡中,选择创建Dash Board
工作台。右上角配置中可以配置创建出来的工作台的标题、文件夹等信息。 -
在创建出来的工作台中,选择
Add panel
中的Add a new panel
添加一个新的面板。 -
- 在右上角
Time series
(时序图)位置可以切换展示的图表样式(柱状图、仪表盘、表格、饼图等等) - 右侧边栏为该图表配置相关信息:标题、描述
- 图表下方可以配置该图表展示的数据的查询语句,例如:
- 在右上角
-
-
- FROM:
cpu_usage_total
(Grafana会自动获取InfluxDB数据库中的元数据,可以直接选择对应表名)
- FROM:
-
-
-
- WHERE:添加一个条件,
container_name=cig-cadvisor-1
- WHERE:添加一个条件,
-
-
-
- ALIAS:配置一个别名,
CPU使用情况汇总
- ALIAS:配置一个别名,
-
本文档参考:
1、尚硅谷Docker实战教程(docker教程天花板)
2、云原生开发