• 尚硅谷Docker学习笔记



    参考资料: 尚硅谷docker2022版教程
    学习五部曲:
    1、是什么?
    2、能干嘛?
    3、去哪下?
    4、怎么玩?
    5、helloworld

    1.docker简介(基础篇)

    (a)为什么会有docker出现?
    在传统的开发中,当代码结束开发和测试,要交给运维部署时,开发团队也得准备完整的部署文件,让维运团队得以部署应用程式,开发需要清楚的告诉运维部署团队,用的全部配置文件+所有软件环境。不过,即便如此,仍然常常发生部署失败的状况。 所以就出现了docker,从根本上解决环境配置的问题,安装的时候,把原始环境一模一样地复制过来。开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题。

    一句话:从原来的搬家,变成整栋楼一起搬,一次镜像,处处运行
    在这里插入图片描述

    (b)容器与虚拟机比较
    在我们之前的学习中,我们有用到过vmware和centos来搭建linux虚拟机,但是,这种方式有一个缺点,就是我们在开启一个虚拟机,就需要一个完整的镜像文件,资源占用多,冗余步骤多,启动慢

    Docker 和传统虚拟化方式的不同之处:

    • 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
    • 容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
    • 每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。

    在这里插入图片描述

    (c)docker能干嘛?
    在这里插入图片描述
    在这里插入图片描述

    (d)docker官网介绍
    docker官网:http://www.docker.com
    Docker Hub官网(安装docker镜像的仓库):https://hub.docker.com/

    (e)docker三要素
    1、镜像
    Docker 镜像(Image)就是一个只读的模板(我们把应用程序和配置依赖打包好形成一个可交付的运行环境)。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器,docker镜像文件类似于Java的类模板,而docker容器实例类似于java中new出来的实例对象。
    在这里插入图片描述

    2、容器
    Docker 利用容器独立运行的一个或一组应用,应用程序或服务运行在容器里面,容器就类似于一个虚拟化的运行环境,容器是用镜像创建的运行实例。就像是Java中的类和实例对象一样,镜像是静态的定义,容器是镜像运行时的实体。容器为镜像提供了一个标准的和隔离的运行环境,它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台

    可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

    3、仓库
    仓库是集中存放镜像文件的场所。
    最大的公开仓库是 Docker Hub(https://hub.docker.com/),
    存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云 、网易云

    (f)docker工作架构
    Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上, 然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。
    在这里插入图片描述

    2.docker的安装

    (a)前提说明

    • docker必须部署在linux内核的系统上,如果其他系统想部署docker就必须安装一个虚拟linux环境
    • 技术选型:centos7

    (b)centos7安装docker
    https://docs.docker.com/engine/install/centos/
    (1)在官网的docs中,点击下载的选项,然后依次点击下面的,就可以找到教程
    在这里插入图片描述
    (2)根据官网提示,卸载旧版本
    在这里插入图片描述
    (3)yum安装gcc相关环境

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

    (4)安装需要的软件包,并设置稳定的镜像仓库
    官网说明,我们采用第一种,设置存储库的方式
    在这里插入图片描述
    这些命令也来自于官网,第二条命令为可选项,但是问题在于他是国外的网址,很可能会连接超时,所以不推荐执行

     yum install -y yum-utils
     
     # 不推荐
    yum-config-manager \
        --add-repo \
        https://download.docker.com/linux/centos/docker-ce.repo
    
    #国内推荐使用阿里云
    yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    

    (5)更新yum软件包索引(可选,推荐执行)

    yum makecache fast
    

    (6)安装DOCKER CE(docker引擎)
    下面的所有命令都来自于docker官网

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

    (7)启动docker并测试

    systemctl start docker
    
    #查看情况
    ps -ef | grep docker
    #查看版本
    docker version
    #helloworld
    

    在这里插入图片描述
    下面简单的了解一下run的原理~
    在这里插入图片描述

    (8)卸载docker(别真去卸载了)

    systemctl stop docker 	
    yum remove docker-ce docker-ce-cli containerd.io
    rm -rf /var/lib/docker
    rm -rf /var/lib/containerd
    

    (c)注册一个属于自己的阿里云账户(可复用淘宝账号)
    (1)去下面的网址注册一个账号
    https://promotion.aliyun.com/ntms/act/kubernetes.html
    (2)进入容器镜像服务在这里插入图片描述
    (3)获取你自己的镜像加速地址
    在这里插入图片描述
    (4)点击centos,复制里面的代码到你的centos中执行即可

    在这里插入图片描述

    3.docker的常用命令

    3.1帮助启动类命令

    #启动docker
    systemctl start docker
    #停止docker
    systemctl stop docker
    #重启docker
    systemctl restart docker
    #查看docker状态
    systemctl status docker
    #开机启动
    systemctl enable docker
    #查看概要信息
    docker info
    #查看docker总体帮助文档
    docker --help 
    #查看docker命令帮助文档
    docker 具体命令 --help
    

    3.2镜像命令

    (a)docker images

    列出本地主机上的所有镜像

    在这里插入图片描述
    在这里插入图片描述
    同一仓库源可以有多个 TAG版本,代表这个仓库源的不同个版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。

    通过3.1中的命令,我们也可以发现这个命令是有参数的
    在这里插入图片描述
    (b)docker search [OPTIONS] 镜像名字
    在远程库中查询某个镜像
    在这里插入图片描述
    在这里插入图片描述

    (c)docker pull XX镜像名字
    从远程库中下载镜像

    #不写tag,默认就是latest
    docker pull 镜像名字:TAG
    

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

    (e)docker rmi XX镜像名字ID
    看到rm,就应该想到删除了

    删除使用镜像ID或者镜像名:TAG都可以

    #删除单个,-f是强制的意思
    docker rmi  -f 镜像ID
    #删除多个
    docker rmi -f 镜像名1:TAG 镜像名2:TAG 
    #删除全部,其实就是先查询再删除(慎用!)
    docker rmi -f $(docker images -qa)
    

    (f)面试题:什么是docker虚悬镜像
    在这里插入图片描述

    单独查看所有的虚悬镜像的命令

    docker image ls -f dangling=true
    

    3.3容器命令

    有镜像才能创建容器,这是根本前提,所以我们先准备一个Ubuntu镜像,以这个镜像为例子
    docker pull ubuntu

    (a)新建+启动容器docker run [OPTIONS] IMAGE [COMMAND] [ARG…]
    OPTIONS说明:

    更加具体的options请使用–help学习,这里只列出最常用的

    –name=“容器新名字” 为容器指定一个名称(没有指定系统会随机分配);
    -d: 后台运行容器并返回容器ID,也即启动守护式容器(后台运行);

    -i:以交互模式运行容器,通常与 -t 同时使用;(i就是交互的意思
    -t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;
    也即启动交互式容器(前台有伪终端,等待交互);

    (下面这两个后面再说,先混个眼熟)
    -P: 随机端口映射,大写P
    -p: 指定端口映射,小写p(通过主机的端口映射冬奥docker容器的端口)
    在这里插入图片描述

    接下来我们启动一个交互式的容器

    docker run -it ubuntu /bin/bash
    

    在这里插入图片描述
    (b)列出当前所有正在运行的容器docker ps [OPTIONS]
    OPTIONS:
    -a :列出当前所有正在运行的容器+历史上运行过的
    -l :显示最近创建的容器。
    -n:显示最近n个创建的容器。
    -q :静默模式,只显示容器编号。

    (c)删除停止容器相关命令

    #run进去容器,exit退出,容器停止
    exit
    
    #run进去容器,ctrl+p+q退出,容器不停止
    ctrl+p+q
    
    #启动已停止运行的容器
    docker restart 容器ID或者容器名
    
    #重启容器
    docker restart 容器ID或者容器名
    
    #停止容器
    docker stop 容器ID或者容器名
    
    # 强制停止容器
    docker kill 容器ID或容器名
    
    #删除已经停止的容器,容器未停止,需要在rm后加上-f
    docker rm 容器ID
    
    #删除多个容器(慎用!),类似于先查询出所有容器的id,然后一起删除
    docker rm -f $(docker ps -a -q)
    docker ps -a -q | xargs docker rm
    

    (d)其他重要的命令

    有镜像才能创建容器,这里以redis6.0.8的镜像为例来玩一玩~

    (1)启动守护式容器(后台服务器)
    我们可以通过-d,来指定容器的后台运行模式

    docker run -d 容器名
    

    问题:有些时候,使用后台守护进程启动然后docker ps -a 进行查看, 会发现容器已经退出
    原因:Docker容器后台运行,就必须有一个前台进程.容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的。

    (2)查看容器日志

    docker logs 容器ID
    

    (3)查看容器内运行的进程

    docker top 容器ID
    

    (4)查看容器内部细节

    docker inspect 容器ID
    

    (5)进入正在运行的容器并以命令行交互
    当我们使用Ctrl+q+p后台运行容器后,怎么再进入呢?

    docker exec -it 容器ID bashShell
    

    在这里插入图片描述
    还有另一种方式

    docker attach 容器ID
    

    两者区别,推荐使用exec
    在这里插入图片描述
    一般用-d后台启动的程序,再用exec进入对应容器实例

    (5)从容器内拷贝文件到主机上
    有时候,我们需要把容器内的重要数据拷贝到主机上,那么应该怎么操作呢?

    docker cp  容器ID:容器内路径 目的主机路径
    

    (6)导入和导出容器
    这个和5类似,也是备份的一种,这点就是我们直接把容器做备份

    #export 导出容器的内容留作为一个tar归档文件,保存位置就是你输入这行命令时主机的位置
    docker export 容器ID > 文件名.tar
    
    #import 从tar包中的内容创建一个新的文件系统再导入为镜像,之后可以用这个镜像再生成对应的容器
    cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号
    

    4.对docker镜像的深入理解

    回顾一下镜像,到目前为止,我们都是直接pull的别人的镜像,从而创建容器,但对于镜像本身,也需要深入了解。

    4.1镜像的一些重要概念

    (a)镜像的分层
    以我们的pull为例,在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载
    在这里插入图片描述

    (b)联合文件系统

    使用联合文件系统,目的就是为了复用!

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

    一句话:以tomcat为例,我们对外只能看见一个tomcat文件镜像,但是我们在下载时,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

    (c)docker镜像加载原理
    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等等。

    思考:为什么我们的镜像可以做到比之前单独学习时小好几倍呢?
    rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了
    就比如说linux系统Ubuntu和centos,bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs
    当我们需要使用rootfs包含之外的指令时,直接在容器层添加即可

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

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

    4.2docker镜像commit操作案例

    一句话:提交容器副本使之成为一个新的镜像

    案例:我们在docker中pull下来的Ubuntu,是不带vim指令的,但是正好我们需要呢?那么接下来,我们就用之前镜像创建的容器,在里面添加vim指令,然后再commit,使其成为一个全新的镜像

    在Ubuntu中添加vim:

    #更新包管理工具
    apt-get update
    #安装vim
    apt-get -y install vim
    

    安装完成后,commit我们自己的新镜像
    代码公式:

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

    在这里插入图片描述
    接下来我们就可以通过这个镜像,来创建有vim功能的容器啦~ 其实就类似于java中的继承

    4.3本地镜像发布到阿里云/私有库

    这里就是使用我们上面的带有vim的Ubuntu

    (a)流程简介
    在这里插入图片描述

    (b)发布到阿里云
    和我们之前一样,到这个网址阿里云,找到镜像容器服务。

    选择个人版,没有建一个
    在这里插入图片描述
    创建一个命名空间
    在这里插入图片描述
    创建一个仓库镜像在这里插入图片描述
    在这里插入图片描述
    进入仓库的管理页面,即可获得脚本,复制黏贴里面的代码即可上传镜像或者把镜像拉倒本地
    在这里插入图片描述

    (b)发布到私有库Docker Registry
    Dockerhub、阿里云这样的公共镜像仓库可能不太方便,涉及机密的公司不可能提供镜像给公网,所以需要创建一个本地私人仓库供给团队使用,基于公司内部项目构建镜像。

    (1)下载镜像Docker Registry

    docker pull registry 
    

    (2)运行私有库Registry,相当于本地有个私有Docker hub
    下面的命令使用了容器卷参数,后面会讲,先混个眼熟

    #默认情况,仓库被创建在容器的/var/lib/registry目录下,建议自行用容器卷映射,方便于宿主机联调,
    docker run -d -p 5000:5000  -v /zzyyuse/myregistry/:/tmp/registry --privileged=true registry
    

    (3)创建一个新的Ubuntu容器,此次我们在里面安装ifconfig

    docker run -it ubuntu bash
    
    #更新包,加快安装速度
    apt-get update
    #安装ifconfig
    apt-get install net-tools
    

    (4)commit我们的新镜像
    提交后就可以使用docker images查看我们提交的镜像,已提交至本地

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

    (5)curl验证私服库上有什么镜像
    镜像仓库的地址部署在虚拟机上,所以这里写你虚拟机的ip地址,结果发现啥也没有
    这里的:5000,因为我们启动时,传了一个-p参数,映射我们主机的5000端口

    curl -XGET http://你的虚拟机ip:5000/v2/_catalog
    

    (6)将新镜像zzyyubuntu:1.2(第4步提交的)修改符合私服规范的Tag

    docker   tag   镜像:Tag   Host:Port/Repository:Tag
    

    在这里插入图片描述
    (7)修改配置文件使之支持http

    vim /etc/docker/daemon.json
    #下面是添加内容
    "insecure-registries": ["你的ip:5000"]
    

    在这里插入图片描述
    (8)重启docker,重新运行registry

    (9)push推送到私服库

    docker push 你的ip:5000/zzyyubuntu:1.2
    

    (10)第二次用相同的curl验证,发现多了个镜像

    (11)从私有库把镜像拉下来

    docker pull 你的ip:5000/zzyyubuntu:1.2
    

    5.docker容器数据卷(实现持久化)

    首先先来看一个小坑:
    Docker挂载主机目录访问如果出现cannot open directory .: Permission denied
    解决办法:在挂载目录后多加一个–privileged=true参数即可
    使用该参数container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限

    (a)是什么?
    我们在上一个知识点中,已经使用过一个参数v在这里插入图片描述
    一句话概括一下:将docker容器内的数据保存进宿主机的磁盘中,类似于我们redis中的aof和rdb文件
    在这里插入图片描述

    (b)能干嘛?
    Docker容器产生的数据,如果不备份,那么当容器实例删除后,容器内的数据自然也就没有了。
    为了能保存数据在docker中我们使用卷。

    特点:
    1:数据卷可在容器之间共享或重用数据
    2:卷中的更改可以直接实时生效,爽(容器里写的东西可以实时同步到卷中)
    3:数据卷中的更改不会包含在镜像的更新中
    4:数据卷的生命周期一直持续到没有容器使用它为止

    (c)宿主vs容器之间映射添加容器卷
    如果宿主机绝对目录不存在,会自己新建一个(前提是开放了写的权限)
    注:-v可以有多个

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

    经过测试,容器和宿主机是双向同步的,在双方任意一边修改,都会同步给另一方 ,并且假如容器停了后在主机中修改,容器重启后,会重新同步~

    (d)查看数据卷是否挂载成功
    docker inspect 容器ID
    在这里插入图片描述

    (e)读写规则映射添加说明
    在上面,我们并没有写读写规则,所以我们发现默认是可以读写的

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

    但是有时候,我们想让容器中的内容是只读的,怎么办,就要设置为ro

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

    在这里插入图片描述
    但此时如果宿主机写入内容,可以同步给容器内,容器可以读取到。

    (f)卷的继承和共享
    假设我们现在有一个容器1完成和宿主机的映射,并且容器2要继承容器1的卷规则

    docker run -it  --privileged=true --volumes-from 父类(容器名)  --name u2 ubuntu
    

    集成测试,继承成功~并且如果u2继承的u1挂了,u2的继承关系依然在

    6.docker常规安装简介(基础篇结束,恭喜入门~)

    总体步骤:搜索镜像->拉取镜像->查看镜像->启动镜像->停止容器->移除容器

    在这里插入图片描述

    6.1tomcat

    #搜
    docker search tomcat
    #拉
    docker pull tomcat
    #查
    docker images
    #启(小写p的意思:通过访问宿主机的8080端口,可以映射到docker的8080)
    docker run -it -p 8080:8080 --name t1 tomcat
    

    注:新版的tomcat,webapps中是没有页面的,页面在webapps.dist中,如果需要访问主页,需要删掉webapps并且将webapps.dist改名为webapps
    在这里插入图片描述
    然后再虚拟机的浏览器中输入网址就能访问主页啦~
    在这里插入图片描述

    #停
    docker stop t1
    #删
    docker rm -f  t1
    

    如果说,我们希望拉下来tomcat就能不修改直接访问首页,可以拉取别的版本

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

    6.2mysql

    #搜
    docker search mysql
    #拉
    docker pull mysql:5.7
    #查
    docker images
    #启,命令可以参考官网
    docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
    #查
    docker ps
    #进
    docker exec -it 容器ID /bin/bash
    #登
    mysql -uroot -p
    

    剩下的基本操作就和我们之前学的mysql完全一致,并且在本机使用mysql工具输入虚拟机的ip地址后也可以连接并使用数据库

    坑:插入中文数据报错
    在这里插入图片描述

    上文只是最基础的mysql的安装,那么现在还存在问题:中文乱码以及备份问题,那么接下来,就来看一下实战版

    #新建容器,使用容器数据卷持久化,备份很关键!
    docker run -d -p 3306:3306 --privileged=true -v /opt/mysql/log:/var/log/mysql -v /opt/mysql/data:/var/lib/mysql -v /opt/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456  --name mysql mysql:5.7
    

    接下来解决中文乱码,在我们备份conf的位置,写一个.cnf文件(注意不是.conf!),把下面的东西复制进去

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

    重启mysql,进入后查看字符编码, SHOW VARIABLES LIKE ‘character%’,成功解决中文乱码
    在这里插入图片描述

    并且我们已经使用容器卷进行了同步数据至本机,所有即使我们不小心删除了mysql容器,再新建容器时,数据依然存在。

    6.3redis

    #拉
    docker pull redis:6.0.8
    #启
    docker run -d -p 6379:6379 redis:6.0.8
    docker exec -it 7aca9383d458 bash
    

    然后通过redis-cli即可连接,不过这只是最基础的,同样的和mysql一样的问题,我们怎么持久化?redis的配置文件怎么办?
    首先是持久化
    我们想要把redis持久化进/opt/redis,首先现在该文件夹中准备一份原始的redis.conf,然后先修改
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    docker run  -p 6379:6379 --name myr3 --privileged=true -v /opt/redis/redis.conf:/etc/redis/redis.conf -v /opt/redis/data:/data -d redis:6.0.8 redis-server /etc/redis/redis.conf
    docker exec -it myr3 bash
    

    上面的代码,我们启动类redis,并且使用数据卷完成了持久化,并且使用redis-server,使用我们修改过的配置文件来运行redis,因为我们设置了/opt/redis/redis.conf同步给/etc/redis/redis.conf

    7.mysql主从复制docker版(高级篇开始)

    (a)新建主服务器实例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
    

    进入/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
    

    修改完配置后重启master实例

    docker restart mysql-master
    

    进入mysql-master容器

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

    创建数据的同步用户

    #建立用户
    CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
    #给用户授权
    GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
    

    (b)新建从服务器实例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
    

    进入/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
    

    重启slave实例

    docker restart mysql-slave
    

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

    show master status;
    

    在这里插入图片描述

    进入mysql-slave容器

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

    在从数据库中配置主从复制

    change master to master_host='宿主机ip', master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-bin.000001', master_log_pos=617, master_connect_retry=30;
    

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

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

    show slave status \G;
    

    在这里插入图片描述

    在从数据库中开启主从同步

    start slave;
    

    重新查看主从同步状态,发现已经yes,至此,主从配置完成~

    8.redis集群docker版(三主三从)

    8.1基础配置

    整体架构如下,首先做好准备工作,关掉虚拟机的防火墙(因为是学习所以就直接关了)+启动docker服务
    在这里插入图片描述

    (a)新建6个docker容器redis实例
    按照这个为例,修改最后的端口即可,新建六个redis实例

    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
    

    在这里插入图片描述
    在这里插入图片描述

    (b)进入容器redis-node-1并为6台机器构建集群关系

    #一定要先进入容器
    docker exec -it redis-node-1 /bin/bash
    #换成你的ip地址即可,这个在redis中已经学习过,--cluster-replicas 1 表示为每个master创建一个slave节点
    redis-cli --cluster create 192.168.111.147:6381 192.168.111.147:6382 192.168.111.147:6383 192.168.111.147:6384 192.168.111.147:6385 192.168.111.147:6386 --cluster-replicas 1
    

    可以看到系统为我们分配的插槽,redis一个有16384个插槽,这些都是redis的知识,这里就不再赘述,且系统已经为我们分配好了主从关系
    在这里插入图片描述

    三主三从搞定~

    (c)链接进入6381作为切入点,查看集群状态

    #以集群的方式连接
    redis-cli -p 6381 -c
    #查看集群信息
    cluster info
    #查看集群有哪些节点
    cluster nodes
    

    注意,这里需要以集群的方式连接,加一个-c,具体是为什么,redis中已经学过,因为redis将槽平均分配给了主机,不以集群启动,就只能存对应主机槽的数据了,以集群启动,就可以在6381,6382,6383中持续切换了
    在这里插入图片描述
    查看集群信息

    redis-cli --cluster check 192.168.111.147:6381
    

    (d)容错切换迁移

    由于每次开启集群,主从都会有所变化,在本次的案例中
    主:1 2 3
    从:6 4 5

    接下来我们使6381宕机,发现6386上位,成为了主机
    在这里插入图片描述
    接下来重启6381,发现6381变成了从机
    在这里插入图片描述

    8.2主从扩容/缩容

    (a)主从扩容案例

    如果说我们刚刚的三主单从不够了呢?就需要增加,假设我们需要变成四主四从,加入主机6387和从机6388
    重点:哈希槽的重新分配

    新建6387、6388两个节点

    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
    

    进入6387容器实例内部,将新增的6387节点(空槽号)作为master节点加入原集群

    docker exec -it redis-node-7 /bin/bash
    redis-cli --cluster add-node 自己实际IP地址:6387 自己实际IP地址:6381
    

    6387 就是将要作为master新增节点
    6381 就是原来集群节点里面的领路人,相当于6387拜拜6381的码头从而找到组织加入集群

    使用redis-cli --cluster check 192.168.111.147:6381,发现主机已加入,但是没有槽位
    在这里插入图片描述
    重新分配槽号

    redis-cli --cluster reshard IP地址:端口号
    

    在这里插入图片描述
    redis-cli --cluster check 真实ip地址:6381,第二次查看集群
    在这里插入图片描述
    为主节点6387分配从节点6388

    redis-cli --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id 新主机节点的容器ID
    

    redis-cli --cluster check 真实ip地址:6381,第三次查看集群,发现四主四从成功~

    (b)主从缩容案例

    目的:6387和6388下线,注意最好从从机开始删

    redis-cli --cluster check 你的ip:6382,检查集群情况1获得6388的节点ID
    在这里插入图片描述

    从集群中删除四号从节点6388

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

    将6387的槽号清空,重新分配,本例将清出来的槽号都给6381

    #以81为落脚点操作整个集群
    redis-cli --cluster reshard 你的ip:6381
    

    在这里插入图片描述
    执行后
    在这里插入图片描述
    将6387删除

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

    再次输入redis-cli --cluster check 你的ip:6382检查集群情况,发现又恢复到了三主三从~

    9.DockerFile

    官网:https://docs.docker.com/engine/reference/builder/

    Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本
    在之前的学习中,我们已经学习了使用commit来提交docker镜像,这种方式没有问题,但是如果镜像一直在变化呢?反复的进行commit会很麻烦,那么就需要我们接下来要学的dockerfile知识了,他就像是一个清单,列举了所有我们需要安装的环境。

    构建三部曲:编写Dockerfile文件->docker build命令构建镜像->docker run依镜像运行容器实例

    9.1一些重要的概念

    (a)基础知识
    1:每条保留字指令都必须为大写字母且后面要跟随至少一个参数
    在这里插入图片描述
    2:指令按照从上到下,顺序执行

    3:#表示注释

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

    (b)Docker执行Dockerfile的大致流程
    在这里插入图片描述
    在这里插入图片描述

    9.2dockerfile常用保留字

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

    2、MAINTAINER
    镜像维护者的姓名和邮箱地址

    3、RUN
    容器构建时需要运行的命令(也就是从dockerfile build成镜像时),有shell和exec两种格式,这里以shell为例
    在这里插入图片描述
    例:RUN yum -y install vim

    4、EXPOSE
    当前容器对外暴露出的端口

    5、WORKDIR
    指定在创建容器后,终端默认登陆(docker run的-it参数)的进来工作目录,一个落脚点

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

    7、ENV
    用来在构建镜像过程中设置环境变量
    在这里插入图片描述

    8、VOLUME
    容器数据卷,用于数据保存和持久化工作,相当于原来的-v

    9、COPY
    拷贝文件和目录到镜像中。
    在这里插入图片描述

    10、ADD
    将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包
    相当于COPY+解压

    11、CMD
    指定容器启动后的要干的事情,Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换

    以官网tomcat的dockerfile为例
    在这里插入图片描述
    在这里插入图片描述

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

    注:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
    在这里插入图片描述

    13、小总结
    在这里插入图片描述

    9.3案例

    需求Centos7镜像具备vim+ifconfig+jdk8(自己安装)

    在开始之前,先准备一个java8的tar包https://mirrors.yangxingzhen.com/jdk/
    1、然后创建一个文件夹,myfile,把tar放进去,在这个文件夹下,准备编写Dockerfile文件

    vim Dockerfile
    
    #Dockerfile里的内容
    FROM centos:7.6.1810  #不要用latest,8版本停止维护了,会报错!
    MAINTAINER zzyy.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
    

    2、准备构建

    #注意,TAG后面有个空格,有个点
    docker build -t 新镜像名字:TAG .
    

    然后再输入docker images,发现我们的镜像已经添加到本地

    3、运行

    docker run -it 新镜像名字:TAG 
    

    经过测试,发现我们添加的三个功能都存在,测试成功~

    10.docker微服务实战

    (a)通过IDEA新建一个普通微服务模块
    1、建module:docker_boot

    2、改pom

    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0modelVersion>
        <parent>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-parentartifactId>
            <version>2.5.6version>
            <relativePath/>
        parent>
    
        <groupId>com.atguigu.dockergroupId>
        <artifactId>docker_bootartifactId>
        <version>0.0.1-SNAPSHOTversion>
    
        <properties>
            <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
            <maven.compiler.source>1.8maven.compiler.source>
            <maven.compiler.target>1.8maven.compiler.target>
            <junit.version>4.12junit.version>
            <log4j.version>1.2.17log4j.version>
            <lombok.version>1.16.18lombok.version>
            <mysql.version>5.1.47mysql.version>
            <druid.version>1.1.16druid.version>
            <mapper.version>4.1.5mapper.version>
            <mybatis.spring.boot.version>1.3.0mybatis.spring.boot.version>
        properties>
    
        <dependencies>
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-actuatorartifactId>
            dependency>
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-testartifactId>
                <scope>testscope>
            dependency>
        dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.bootgroupId>
                    <artifactId>spring-boot-maven-pluginartifactId>
                plugin>
                <plugin>
                    <groupId>org.apache.maven.pluginsgroupId>
                    <artifactId>maven-resources-pluginartifactId>
                    <version>3.1.0version>
                plugin>
            plugins>
        build>
    
    project>
    

    3、写yml

    server:
      port: 6001
    

    4、主启动,普通的主启动类即可

    5、业务类

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.UUID;
    
    /**
     * @auther zzyy
     * @create 2021-10-25 17:43
     */
    @RestController
    public class OrderController
    {
        @Value("${server.port}")
        private String port;
    
        @RequestMapping("/order/docker")
        public String helloDocker()
        {
            return "hello docker"+"\t"+port+"\t"+ UUID.randomUUID().toString();
        }
    
        @RequestMapping(value ="/order/index",method = RequestMethod.GET)
        public String index()
        {
            return "服务端口号: "+"\t"+port+"\t"+UUID.randomUUID().toString();
        }
    }
    
    

    (b)通过dockerfile发布微服务部署到docker容器
    1、首先在idea工具中,将其打包成jar包
    在这里插入图片描述
    2、然后把这个jar包导进linux虚拟机中
    在这里插入图片描述

    3、在jar包的目录下编写Dockerfile

    vim Dockerfile
    
    # 基础镜像使用java
    FROM java:8
    # 作者
    MAINTAINER zzyy
    # VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
    VOLUME /tmp
    # 将jar包添加到容器中并更名为zzyy_docker.jar
    ADD docker_boot-0.0.1-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 run -d -p 6001:6001 a969763df521
    

    6、访问测试

    经过测试,访问成功,在docker中部署微服务成功~

    11.docker网络

    11.1基础简介

    (a)是什么
    在这里插入图片描述
    启动docker后,他会默认创建三大网络模式
    在这里插入图片描述
    (b)常用命令
    在这里插入图片描述
    (c)能干嘛
    1、容器间的互联和通信以及端口映射
    2、容器IP变动时候可以通过服务名直接网络通信而不受到影响

    (d)几种网络模式介绍
    在这里插入图片描述

    (e)容器实例内默认网络IP生产规则
    我们先启动两个Ubuntu容器实例u11和u12,发现他们人手一个ip
    在这里插入图片描述

    接下来删除u12,新建一个u13,发现原来u12的IP地址给u13了,这说明容器的ip是会变化的,所以ip不能写死
    在这里插入图片描述

    11.2五种网络模式的案例(bridge,host,none,container,自定义)

    (a)bridge

    Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),该桥接网络的名称为docker0,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信

    在这里插入图片描述
    接下来代码验证一下,先启动两个tomcat容器

    docker run -d -p 8081:8080   --name tomcat81 billygoo/tomcat8-jdk8
    docker run -d -p 8082:8080   --name tomcat82 billygoo/tomcat8-jdk8
    

    在这里插入图片描述
    两两匹配验证成功~

    (b)host

    直接使用宿主机的 IP 地址与外界进行通信,不再需要额外进行NAT 转换,容器将不会虚拟出自己的网卡而是使用宿主机的IP和端口。

    在这里插入图片描述

    案例,注意,因为是host,所以-p参数就没有意义了,会抛出警告,可以直接无视,或者不写

    docker run -d --network host --name tomcat83 billygoo/tomcat8-jdk8
    

    进入容器,使用ip addr,发现没有网桥和网关了
    在这里插入图片描述
    如果想访问,直接用主机ip:8080即可

    (c)none

    在none模式下,并不为Docker容器进行任何网络配置。
    也就是说,这个Docker容器没有网卡、IP、路由等信息,只有一个lo(本地链路回环地址)
    需要我们自己为Docker容器添加网卡、配置IP等。

    docker run -d -p 8084:8080 --network none --name tomcat84 billygoo/tomcat8-jdk8
    

    在这里插入图片描述
    (d)container

    新建的容器和已经存在的一个容器共享一个网络ip配置而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。

    在这里插入图片描述

    案例,注,这里不能用tomcat,因为tomcat公用8080,会冲突,所以换了一个镜像

    docker run -it --name alpine1  alpine /bin/sh
    
    docker run -it --network container:alpine1 --name alpine2  alpine /bin/sh
    

    在这里插入图片描述
    此时,如果我们关掉alpine2共用网卡的alpine1呢?此时发现又只剩一个lo了
    在这里插入图片描述

    (e)自定义

    在前面的案例中,我们的容器ping其他容器的ip是可以ping通的,但是并不能按照服务名ping,上文也说过,容器的ip地址是会变的,我们不能把ip地址写死,那么这个时候,就需要自定义网络了。

    1、自定义桥接网络,自定义网络默认使用的是桥接网络bridge

    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、互相ping试试
    在这里插入图片描述
    自定义网络本身就维护好了主机名和ip的对应关系(ip和域名都能通)

    12.Docker-compose容器编排

    官网https://docs.docker.com/compose/compose-file/compose-file-v3/

    12.1核心概念与安装

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

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

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

    下面我们类比spring,spring是对bean的管理,而我们现在学的compose,是对容器的管理(一键启动,一键stop
    在这里插入图片描述
    (c)下载安装
    官网下载:https://docs.docker.com/compose/install/linux/
    注:新版本官网可能有所不同,但大体都是一致的

    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
    

    查看在docker官网中查看安装与卸载步骤,不同的版本会有差别,因为是学习,所以使用和周阳老师一致的版本~
    在这里插入图片描述

    (d)核心概念
    一文件:docker-compose.yml

    两要素:
    在这里插入图片描述
    (e)三个步骤
    在这里插入图片描述
    其中,docker-compose up相当于一次执行了多个docker run

    (e)常用操作

    docker compose --help
    

    在这里插入图片描述

    12.2Compose编排微服务实例

    还记得第十章中我们微服务实战做过一个镜像吗~
    在这里插入图片描述
    现在假设,我们运行这个镜像生成容器时,必须先有redis和mysql

    (a)不使用compose

    先来看看如果头铁,不用docker compose

    那就是依次docker run啦~

    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
    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
     docker run -d -p 6001:6001 zzyy_docker:1.6
    

    上述操作存在的问题
    在这里插入图片描述

    (b)使用compose
    1、编写docker-compose.yml文件

    version: "3"
     
    services:
      #下面相当于 docker run -d -p 6001:6001 -V /app/microService:/data --network atguigu_net --name ms01 zzyy_docker:1.6
      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: 'db2021'
          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 #解决外部无法访问
     
     #创建三个容器的网段,指定了这个网络以后,我们的微服务就不用写死ip了,可以通过redis和mysql这两个服务名来访问两个微服务
    networks: 
       atguigu_net: 
    
    

    2、执行 docker-compose up或者执行 docker-compose up -d
    在这里插入图片描述
    注:使用docker-compose config -q可以检查从docker-compose的语法是否有误

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

    官网:https://www.portainer.io/
    安装指导:https://docs.portainer.io/v/ce-2.9/start/install/server/docker/linux

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

    (a)安装步骤
    首先使用docker命令安装
    –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
    

    第一次登录需要创建admin,访问地址:linux虚拟机ip地址:9000

    设置完后选择local,监控本地,然后进入
    在这里插入图片描述
    在这里插入图片描述
    其中的stack是有多少组compose编排的容器

    (b)常规操作
    在container中,点击下面四个按钮,依次是查看日志,容器情况,容器占用的资源,以及进入容器
    在这里插入图片描述
    并且,可以在图形化界面,直接创建容器,并且没有的话也会自动去拉取镜像
    在这里插入图片描述
    其他的操作也大同小异,有了前面的基础,这个只是把我们的代码变成了可视化界面而已~

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

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

    (a)是什么?
    CAdvisor负责收集和分析数据
    在这里插入图片描述
    InfluxDB负责数据的存储
    在这里插入图片描述
    Granfana负责可视化界面
    在这里插入图片描述

    (b)compose容器编排一键搭建监控平台
    1、新建一个文件夹,在这个文件夹中新建新建3件套组合的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 up启动docker-compose文件(没有-d参数就是直接前台启动)

    3、docker ps查看三个服务是否启动
    在这里插入图片描述

    (c)测试
    1、浏览cAdvisor收集服务,http://ip:8080/
    注:第一次启动会比较慢,在这里可以浏览数据的收集~

    2、浏览influxdb存储服务,http://ip:8083/

    3、浏览grafana展现服务,http://ip:3000
    账号密码初始都是admin

    为他配置一个数据源,选择influxdb
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    然后添加一个控制面板
    在这里插入图片描述
    选择一个图形
    在这里插入图片描述
    填充数据
    在这里插入图片描述
    这里我们选择监控cpu
    在这里插入图片描述
    点击save,到这里cAdvisor+InfluxDB+Grafana容器监控系统就部署完成了~

  • 相关阅读:
    接口复习总结
    电子科大软件系统架构设计——系统架构设计
    Python语言这么火热,其实具有以下特点
    iconfont
    torch.distributed.launch 指定端口rdzv_endpoint
    使用OpenFlow和Ryu控制器实现网络交换机的软件定义网络(SDN)控制
    Linux下通过service服务管理用户进程
    云服务器 宝塔部署SpringBoot前后端分离项目
    echarts静态饼图
    C++ 拷贝构造函数
  • 原文地址:https://blog.csdn.net/qq_28356977/article/details/126789071