Docker

打印 上一主题 下一主题

主题 555|帖子 555|积分 1665

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、如果之前安装过老版本需要卸载

  1. yum remove docker \
  2.                   docker-client \
  3.                   docker-client-latest \
  4.                   docker-common \
  5.                   docker-latest \
  6.                   docker-latest-logrotate \
  7.                   docker-logrotate \
  8.                   docker-engine
复制代码
2、安装gcc相关

  1. yum -y install gcc
  2. yum -y install gcc-c++
复制代码
3、安装yum工具包

  1. yum -y install yum-utils
复制代码
4、配置仓库资源

  1. # 1. 默认使用国外源,非常非常非常慢!
  2. yum-config-manager \
  3.     --add-repo \
  4.     https://download.docker.com/linux/centos/docker-ce.repo
  5. # 2. 推荐用国内源,丝滑!
  6. yum-config-manager \
  7.     --add-repo \
  8.     http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
复制代码
5、更新yum软件包索引(可做可不做)

  1. yum makecache fast
复制代码
6、安装Docker

  1. yum install docker-ce docker-ce-cli containerd.io
复制代码
7、启动Docker

  1. systemctl start docker
复制代码
8、查看是否安装乐成

  1. // 查看docker版本
  2. docker version
  3. // 查看是否安装成功,要先从远程仓库拉取镜像
  4. docker pull hello-world
  5. docker run hello-world
复制代码
9、配置阿里云镜像加速

  1. sudo mkdir -p /etc/docker
  2. sudo tee /etc/docker/daemon.json <<-'EOF'
  3. {
  4.   "registry-mirrors": ["https://8oizdfoz.mirror.aliyuncs.com"]
  5. }
  6. EOF
  7. sudo systemctl daemon-reload
  8. sudo systemctl restart docker
复制代码
10、卸载Docker

  1. systemctl stop docker
  2. yum remove docker-ce docker-ce-cli containerd.io
  3. rm -rf /var/lib/docker
  4. 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

  1. dokcer pull registry
复制代码
2、运行私有库Docker Registry

相称于当地有个docker hub,默认情况下,仓库被创建在/var/lib/registry目次下,建议自行用容器卷映射,方便与宿主机联调
  1. docker run -d -p 5000:5000 -v /zly/myRegistry/:/tmp/registry --privileged=true registry
  2. * -d 后台运行
  3. * -p 端口映射
  4. * -v
  5. * -- privileged
复制代码
3、创建一个新镜像

案例演示,Ubuntu安装ifconfig指令,天生新的镜像
  1. ifconfig指令1、docker pull ubuntu:下载Ubuntu镜像
  2. 2、docker run -it ubuntu:以交互式启动Ubuntu镜像
  3. 3、apt-get update:Ubuntu容器内部包的更新
  4. 4、apt-get install net-tools:Ubuntu容器内部安装ifconfig指令
  5. 5、Ctrl + p + q:退出当前容器,但不会使容器停止
  6. 6、docker commit -m="first commit" -a="zly" 容器Id 要创建的目标镜像名:[标签名]:提交并生成新的镜像
复制代码
4、查看私有库里有什么镜像

  1. curl -XGET http://124.222.32.135:5000/v2/_catalog
  2. 结果:{"repositories":[""]}
复制代码
5、将新镜像名称修改成符合私服规范的tag

  1. docker tag myubuntuifconfig:1.0 124.222.32.135:5000/myubuntuifconfig:1.0
复制代码
6、修改docker配置文件使之支持http

修改完成后如果不生效,则重启docker
  1. vim /etc/docker/daemon.json    修改配置文件
  2. 添加 "insecure-registries": ["124.222.32.135:5000"]
  3. 修改后:
  4. {
  5.   "registry-mirrors": ["https://8oizdfoz.mirror.aliyuncs.com"],
  6.   "insecure-registries": ["124.222.32.135:5000"]
  7. }
复制代码
7、推送镜像

  1. docker pull 124.222.32.135:5000/myubuntuifconfig:1.0
复制代码
8、查看私有库里是否有推送的镜像

  1. curl -XGET http://124.222.32.135:5000/v2/_catalog
  2. 结果:{"repositories":["myubuntuifconfig"]}
复制代码
9、pull到当地并运行

  1. docker pull 124.222.32.135:5000/myubuntuifconfig:1.0
  2. 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不会在删除容器时山区其挂载的数据卷。
容器卷的特点:



  • 数据卷可以在容器之间共享或重用数据
  • 卷中数据的更改可以直接实时生效
  • 数据卷的修改不会包含在镜像的更新中
  • 数据卷的生命周期会不停持续到没有容器使用它为止
  1. docker run -v /宿主机路径:/docker容器内路径 --privileged=true 容器名
  2. docker run -v /宿主机路径:/docker容器内路径:ro --privileged=true 容器名  限制容器内只能读取,不能写,read-only
  3. docker run --privileged=true --volumes-from u1 --name u2 容器名 容器u2继承u1的数据卷,u1和u2是相互独立的,一主二从
复制代码
八、Docker上安装软件

1、安装MySQL(单机版)

  1. 1、拉取MySQL镜像
  2.         docker pull mysql:5.7
  3. 2、运行MySQL镜像
  4.         docker run -d -p 3306:3306 --privileged=true \
  5.          -v /zly/mysql/log:/var/log/mysql \
  6.          -v /zly/mysql/data:/var/lib/mysql \
  7.          -v /zly/mysql/conf:/etc/mysql/conf.d \
  8.          -e MYSQL_ROOT_PASSWORD=123456 \
  9.          --name mysql mysql:5.7
  10. 3、在文件夹/zly/mysql/conf下新建my.cnf的MySQL配置文件,并写入一下内容
  11.         [client]
  12.     default_character_set=utf8
  13.     [mysqld]
  14.     collation_server=utf8_general_ci
  15.     character_set_server=utf8
  16. 4、设置docker启动时启动mysql
  17.         docker update mysql --restart=always
  18. 5、重启MySQL
  19.         docker restart 容器ID
  20. 6、进入mysql容器内部
  21.         docker exec -it mysql /bin/bash
  22. 7、登录mysql
  23.         mysql -uroot -p    回车后输入密码
复制代码
2、安装Redis

  1. 1、拉取Redis镜像
  2.         docker pull redis
  3. 2、redis.conf
  4.         # 绑定IP地址
  5.         #解除本地限制 注释bind 127.0.0.1  
  6.         #bind 127.0.0.1  
  7.         # 服务器端口号  
  8.         port 6379
  9.         #配置密码,不要可以删掉
  10.         #requirepass syf133618
  11.         #这个配置不要会和docker -d 命令 冲突
  12.         # 服务器运行模式,Redis以守护进程方式运行,默认为no,改为yes意为以守护进程方式启动,可后台运行,除非kill进程,改为yes会使配置文件方式启动redis失败,如果后面redis启动失败,就将这个注释掉
  13.         daemonize no
  14.         #当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定(自定义)
  15.         #pidfile /data/dockerData/redis/run/redis6379.pid  
  16.         #默认为no,redis持久化,可以改为yes
  17.         appendonly yes
  18.         #当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
  19.         timeout 60
  20.         # 服务器系统默认配置参数影响 Redis 的应用
  21.         maxclients 10000
  22.         tcp-keepalive 300
  23.         #指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合(分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改)
  24.         save 900 1
  25.         save 300 10
  26.         save 60 10000
  27.         # 按需求调整 Redis 线程数
  28.         tcp-backlog 511
  29.         # 设置数据库数量,这里设置为16个数据库  
  30.         databases 16
  31.         # 启用 AOF, AOF常规配置
  32.         appendonly yes
  33.         appendfsync everysec
  34.         no-appendfsync-on-rewrite no
  35.         auto-aof-rewrite-percentage 100
  36.         auto-aof-rewrite-min-size 64mb
  37.         # 慢查询阈值
  38.         slowlog-log-slower-than 10000
  39.         slowlog-max-len 128
  40.         # 是否记录系统日志,默认为yes  
  41.         syslog-enabled yes  
  42.         #指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose
  43.         loglevel notice
  44.         # 日志输出文件,默认为stdout,也可以指定文件路径  
  45.         logfile stdout
  46.         # 日志文件
  47.         #logfile /var/log/redis/redis-server.log
  48.         # 系统内存调优参数   
  49.         # 按需求设置
  50.         hash-max-ziplist-entries 512
  51.         hash-max-ziplist-value 64
  52.         list-max-ziplist-entries 512
  53.         list-max-ziplist-value 64
  54.         set-max-intset-entries 512
  55.         zset-max-ziplist-entries 128
  56.         zset-max-ziplist-value 64
  57. 3、运行Redis镜像
  58. docker run -p 6379:6379 --name redis --privileged=true \
  59.      -v /zly/redis/redis.conf:/etc/redis/redis.conf \
  60.      -v /zly/redis/data:/data \
  61.      -d redis redis-server /etc/redis/redis.conf
  62. 4、进入Redis容器
  63.         docker exec -it redis /bin/bash
  64. 5、进入客户端
  65.         redis-cli
复制代码
3、安装MySQL(集群版)

安装主服务器容器实例

(1)、启动容器实例:3307
  1. docker run -d -p 3307:3306 --privileged --name mysql-master \
  2.         -v /zly/mysql-cluster/mysql-master/log:/var/log/mysql \
  3.         -v /zly/mysql-cluster/mysql-master/data:/var/lib/mysql \
  4.         -v /zly/mysql-cluster/mysql-master/conf:/etc/mysql \
  5.         -e MYSQL_ROOT_PASSWORD=root \
  6.         mysql:5.7
复制代码
(2)、进入/zly/mysql-cluster/mysql-master/conf下新建my.cnf配置文件
  1. [mysqld]
  2. ## 设置server_id, 同一个局域网中需要唯一
  3. server_id=101
  4. ## 指定不需要同步的数据库名称
  5. binlog-ignore-db=mysql
  6. ## 开启二进制日志功能
  7. log-bin=mall-mysql-bin
  8. ## 设置二进制日志使用内存大小(事务)
  9. binlog_cache_size=1M
  10. ## 设置使用的二进制日志格式(mixed,statement,row)
  11. binlog_format=mixed
  12. ## 二进制日志过期清理时间。默认值为0,表示不自动清理
  13. expire_logs_days=7
  14. ## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断
  15. ## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
  16. slave_skip_errors=1062
复制代码
(3)、重启容器实例
  1. docker restart mysql-master
复制代码
(4)、进入mysql-master容器实例内部
  1. docker exec -it mysql-master /bin/bash
  2. mysql -uroot -proot
复制代码
(5)、在mysql-master主数据库中创建数据同步用户
  1. // 创建用户
  2. create user 'slave'@'%' identified by '123456';
  3. // 授权
  4. grant replication slave, replication client on *.* to 'slave'@'%';
复制代码
安装从服务器容器实例

(1)、启动容器实例:3308
  1. docker run -d -p 3308:3306 --privileged --name mysql-slave \
  2.         -v /zly/mysql-cluster/mysql-slave/log:/var/log/mysql \
  3.         -v /zly/mysql-cluster/mysql-slave/data:/var/lib/mysql \
  4.         -v /zly/mysql-cluster/mysql-slave/conf:/etc/mysql \
  5.         -e MYSQL_ROOT_PASSWORD=root \
  6.         mysql:5.7
复制代码
(2)、进入/zly/mysql-cluster/mysql-slave/conf下新建my.cnf配置文件
  1. [mysqld]
  2. ## 设置server_id, 同一个局域网内需要唯一
  3. server_id=102
  4. ## 指定不需要同步的数据库名称
  5. binlog-ignore-db=mysql
  6. ## 开启二进制日志功能,以备slave作为其它数据库实例的Master时使用
  7. log-bin=mall-mysql-slave1-bin
  8. ## 设置二进制日志使用内存大小(事务)
  9. binlog_cache_size=1M
  10. ## 设置使用的二进制日志格式(mixed,statement,row)
  11. binlog_format=mixed
  12. ## 二进制日志过期清理时间。默认值为0,表示不自动清理
  13. expire_logs_days=7
  14. ## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断
  15. ## 如:1062错误是指一些主键重复,1032是因为主从数据库数据不一致
  16. slave_skip_errors=1062
  17. ## relay_log配置中继日志
  18. relay_log=mall-mysql-relay-bin
  19. ## log_slave_updates表示slave将复制事件写进自己的二进制日志
  20. log_slave_updates=1
  21. ## slave设置只读(具有super权限的用户除外)
  22. read_only=1
复制代码
(3)、重启容器实例
  1. docker restart mysql-slave
复制代码
在主数据库中查看主从同步状态

  1. docker exec -it mysql-master /bin/bash
  2. mysql -uroot -p
  3. show master status
复制代码
主要查看返回结果的文件名File、当前位置Position
在从数据库中配置主从复制

(1)、进入从服务器
  1. docker exec -it mysql-master /bin/bash
  2. mysql -uroot -p
复制代码
(2)、配置主从复制
  1. 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;
  2. 解释:
  3. change master to master_host='宿主机ip',
  4. master_user='主数据库配置的主从复制用户名',
  5. master_password='主数据库配置的主从复制用户密码',
  6. master_port=宿主机主数据库端口,
  7. master_log_file='主数据库主从同步状态的文件名File',
  8. master_log_pos=主数据库主从同步状态的Position,
  9. master_connect_retry=连接失败重试时间间隔(秒);
复制代码
(3)、查看主从同步状态
  1. # \G 可以将横向的结果集表格转换成纵向展示。
  2. # slave status的字段比较多,纵向展示比友好
  3. show slave status \G;
复制代码
除了展示刚刚配置的主数据库信息外,主要关注 Slave_IO_Running、Slave_SQL_Running。现在两个值应该都为 No,表示还没有开始。
(4)、开启主从同步
  1. start slave;
复制代码
(5)、查看主从同步状态
主从复制测试:

(1)、 在主数据库上新建库、使用库、新建表、插入数据
  1. create database db01;
  2. use db01;
  3. create table t1 (id int, name varchar(20));
  4. insert into t1 values (1, 'abc');
复制代码
(2)、 在从数据库上使用库、查看记录
  1. show databases;
  2. use db01;
  3. select * from t1;
复制代码
4、3主3从Redis集群

(1)、启动6台Redis节点
  1. # 启动第1台节点
  2. # --net host 使用宿主机的IP和端口,默认
  3. # --cluster-enabled yes 开启redis集群
  4. # --appendonly yes 开启redis持久化
  5. # --port 6381 配置redis端口号
  6. 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
  7. # 启动第2台节点
  8. 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
  9. # 启动第3台节点
  10. 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
  11. # 启动第4台节点
  12. 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
  13. # 启动第5台节点
  14. 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
  15. # 启动第6台节点
  16. 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. 进入节点1(或其中任意一个节点):
  2.         docker exec -it redis-node-1 /bin/bash
  3. 2. 构建主从关系:
  4.         redis-cli --cluster create 124.222.32.135:6381 124.222.32.135:6382 124.222.32.135:6383 124.222.32.135:6384 \
  5.     124.222.32.135:6385 124.222.32.135:6386 --cluster-replicas 1
  6. 3. redis尝试自动进行主从节点分配
  7. 4. 因为我们的docker容器IP相同,所以会出现警告,可以直接忽略该警告,
  8.         [WARNING] Some slaves are in the same host as their master
  9. 5. redis自动分配结果完成后,需要输入 Yes 确认配置信息
  10. 6. 输入Yes确认后,redis会向其他节点发送信息加入集群,并分配哈希槽:
复制代码
(3)、查看集群状态:
  1. 1. 进入容器节点1(或集群中其他节点):
  2.         docker exec -it redis-node-1 /bin/bash
  3. 2. 使用redis-cli连接到6381节点:
  4.         redis-cli -p 6381
  5. 3. 使用redis的相关命令查看集群状态:
  6.         cluster info
  7.         其中,分配的哈希槽数量 cluster_slots_assigned为16384,集群节点数量cluster_known_nodes为6
  8. 4. 查看集群节点信息
  9.         cluster nodes
复制代码
(4)、Redis集群读写堕落
  1. 当使用 redis-cli连接redis集群时,需要添加 -c参数,否则可能会出现读写出错。
  2. 示例:
  3. 1. 进入容器节点1
  4.         docker exec -it redis-node-1 /bin/bash
  5. 2. 使用redis-cli连接,不加-c参数时
  6.         redis-cli -p 6381
  7. 3. 此时向redis中添加键值对,可能会成功,也可能会失败
  8.         set k1 v1
  9.     报错:k1经过计算得到的哈希槽为12706,但是当前连接的redis-server为6381(即节点1),它的哈希槽为:[0,5460](在创建构建主从关系时redis有提示,也可以通过 cluster nodes查看),所以会因为存不进去而报错。
  10.     执行 set k2 v2可以成功,因为k2计算出的哈希槽在[0-5460]区间中。
  11. 4.  使用-c参数的redis-cli命令连接即可
  12.         redis-cli -p 6381 -c
  13. 5.  此时可以正常的插入所有数据
  14.         set k1 v1
  15.         会有提示信息,哈希槽为12706,重定向到6383(即节点3,哈希槽[10923, 16383]):  
复制代码
(5)、集群信息检查
  1. # 输入任意一台主节点地址都可以进行集群检查
  2. redis-cli --cluster check 124.222.32.135:6381
复制代码
(6)、主从扩容
假如由于业务量激增,需要向当前3主3从的集群中再加入1主1从两个节点。
  1. 1、启动2台新的容器节点
  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 6387
  3.         docker 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 6388
  4.        
  5. 2、进入6387(节点7)容器内部
  6.         docker exec -it redis-node-7 /bin/bash
  7.        
  8. 3、将6387作为master加入集群
  9.         # redis-cli --cluster add-node 本节点地址 要加入的集群中的其中一个节点地址
  10.         redis-cli --cluster add-node 124.222.32.135:6387 124.222.32.135:6381
  11. 4、检查当前集群状态
  12.         redis-cli --cluster check 124.222.32.135:6381
  13.         可以发现,6371节点已经作为master加入了集群,但是该节点没有被分配槽位。
  14. 5、重新分配集群的槽位
  15.         redis-cli --cluster reshard 124.222.32.135:6381
  16.     redis经过槽位检查后,会提示需要分配的槽位数量:
  17.     例如,我们现在是4台master,我们想要给node7分配4096个槽位,这样每个节点都是4096个槽位。
  18.     输入4096后,会让输入要接收这些哈希槽的节点ID,填入node7的节点ID即可。(就是节点信息中很长的一串十六进制串)。
  19.     然后会提示,询问要从哪些节点中拨出一部分槽位凑足4096个分给Node7。一般选择 all,即将之前的3个主节点的槽位都均一些给Node7,这样可以使得每个节点的槽位数相等均衡。
  20.     输入all之后,redis会列出一个计划,内容是自动从前面的3台master中拨出一部分槽位分给Node7的槽位,需要确认一下分配的计划。
  21.     输入yes确认后,redis便会自动重新洗牌,给Node7分配槽位。
  22.     重新分配完成后,可以进行集群信息检查,查看分配结果:
  23.                 redis-cli --cluster check 124.222.32.135:6381
  24.         可以发现重新洗牌后的槽位分配为:
  25.         节点1:[1365-5460](供4096个槽位),,,分配前为[0-5460](共5461个槽位)
  26.         节点2:[6827-10922](共4096个槽位),,,分配前为[5461-10922](共5461个槽位)
  27.         节点3:[12288-16383](共4096个槽位),,,分配前为[10923-16383](共5462个槽位)
  28.         节点7:[0-1364],[5461-6826],[10923-12287](共4096个槽位),从每个节点中匀出来了一部分给了节点7
  29.         因为可能有些槽位中已经存储了key,完全的重新洗牌重新分配的成本过高,所以redis选择从前3个节点中匀出来一部分给节点7
  30. 6、为主节点6387分配从节点6388:
  31.         redis-cli --cluster add-node 124.222.32.135:6388 124.222.32.135:6381 --cluster-slave --cluster-master-id node7节点的十六进制编号字符串
  32.         redis便会向6388发送消息,使其加入集群并成为6387的从节点。
  33. 7、检查集群当前状态
  34.         redis-cli --cluster check 124.222.32.135:6381
复制代码
(7)、主从缩容
假如业务高峰期已往,需要将4主4从重新缩容到3主3从。即从集群中移除node8和node7.
  1. 1、进入容器节点1
  2.         docker exec -it redis-node-1 /bin/bash
  3. 2、检查容器状态,获取6388的节点编号
  4.         redis-cli --cluster check 124.222.32.135:6381
  5. 3、将6388从集群中移除
  6.         redis-cli --cluster del-node 124.222.32.135:6388 6388节点编号
  7. 4、对node7重新分配哈希槽:
  8.     redis-cli --cluster reshard 124.222.32.135:6381
  9.     redis经过槽位检查后,会提示需要分配的槽位数量:
  10.     How many slots do you want to move (from 1 to 16384)?
  11.     如果我们想直接把node7的4096个哈希槽全部分给某个节点,可以直接输入4096。
  12.     输入4096后,会让输入要接收这些哈希槽的节点ID。假如我们想把这4096个槽都分给Node1,直接输入node1节点的编号即可。
  13.     然后会提示,询问要从哪些节点中拨出一部分槽位凑足4096个分给Node1。这里我们输入node7的节点编号,回车后输入done。
  14.     node7上面没有了哈希槽,此时便可以将node7从集群中移除。(如果node7上面有哈希槽,直接从集群中移除会报错)
  15. 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"]

  • 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文件

  1. FROM centos
  2. MAINTAINER zly@1163977538@qq.com
  3. ENV MYPATH /usr/local
  4. WORKDIR $MYPATH
  5. #CentOS8 yum源配置
  6. RUN rm -f /etc/yum.repos.d/*.repo
  7. RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-8.repo
  8. #安装vim编辑器
  9. RUN yum -y install vim
  10. #安装ifconfig命令查看网络IP
  11. RUN yum -y install net-tools
  12. #安装java8及lib库
  13. RUN yum -y install glibc.i686
  14. RUN mkdir /usr/local/java
  15. #ADD 是相对路径jar,把jdk-8u271-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置
  16. ADD jdk-8u271-linux-x64.tar.gz /usr/local/java/
  17. #配置java环境变量
  18. ENV JAVA_HOME /usr/local/java/jdk1.8.0_271
  19. ENV JRE_HOME $JAVA_HOME/jre
  20. ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
  21. ENV PATH $JAVA_HOME/bin:$PATH
  22. EXPOSE 80
  23. CMD echo $MYPATH
  24. CMD echo "success--------------ok"
  25. CMD /bin/bash
复制代码
b、下载jdk

  1. 下载jdk-8u271-linux-x64.tar.gz并把其放入和Dockerfile文件在同一位置
复制代码
c、构建镜像

  1. # 注意:定义的TAG后面有个空格,空格后面有个点
  2. # docker build -t 新镜像名字:TAG .
  3. docker build -t centosjava8:1.0.1 .
复制代码
d、启动镜像

  1. docker run -it 810641de7ec0 /bin/bash
复制代码
e、测试

  1. 1、进入后在 /usr/local 文件夹下
  2. 2、测试vim 编辑器
  3. 3、测试 ifconfig
  4. 4、测试 java -version
复制代码
十、Docker运行微服务

1、在idea中升成jar包

  1. 把项目在Maven下 docker-test  ->  Lifecycle  ->  package  ->  生成docker-test-1.0-SNAPSHOT.jar
  2. 将jar包放在和Dockerfile文件同一目录下
复制代码
2、在Linux目次下编写Dockerfile文件

  1. FROM openjdk:11-jre
  2. MAINTAINER zly@1163977538@qq.com
  3. # 在主机 /var/lib/docker目录下创建一个临时文件,并链接到容器的 /tmp
  4. VOLUME /tmp
  5. # 将jar包添加到容器中,并命名为 springboot_docker.jar
  6. ADD docker-test-1.0-SNAPSHOT.jar /springboot_docker.jar
  7. # 运行jar包
  8. RUN bash -c 'touch /springboot_docker.jar'
  9. ENTRYPOINT ["java", "-jar", "/springboot_docker.jar"]
  10. # SpringBoot项目配置的端口号为9876,需要将9876暴露出去
  11. EXPOSE 9876
复制代码
3、构建镜像

  1. # 注意:定义的TAG后面有个空格,空格后面有个点(可能需要先拉取镜像openjdk:11-jre)
  2. # docker build -t 新镜像名字:TAG .
  3. docker build -t docker-spring-boot-test:1.0 .
复制代码
4、启动容器

  1. docker run -d -p 9876:9876 docker-spring-boot-test:1.0
复制代码
5、测试

  1. http://124.222.32.135:9876/docker/index
复制代码
十一、Docker network

1、概述

docker安装并乐成启动后,会在宿主机添加一个假造网卡docker0
作用:


  • 容器之间的互联和通信,以及端口映射
  • 容器ip变更的时间,可以通过服务名直接网络通信而不受到影响
docker容器的网络隔离是通过Linux内核特性namespace和cgroup实现的
2、常用指令

  1. 使用 --help 查询
  2. docker network --help
  3.   connect     Connect a container to a network
  4.   create      Create a network
  5.   disconnect  Disconnect a container from a network
  6.   inspect     Display detailed information on one or more networks
  7.   ls          List networks
  8.   prune       Remove all unused networks
  9.   rm          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获取名称:
  1. 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. 1: lo ..................
  2. 容器内的网卡为 eth0
  3. @符号后面就是宿主机上对应的veth网卡的编号28
  4. 27: eth0@if28 ...............................
复制代码
在宿主机执行 ip addr 查看宿主机网卡信息:
  1. 每个veth都有个编号:vethXXXXXX
  2. @符号后面对应就是容器内的eth0网卡编号27
  3. 28: vethXXXXXX@if27  ................
复制代码
host模式

直接使用宿主机的 IP 地址与外界进行通信,不再需要额外进行 NAT 转换。
容器将不会得到一个独立的 Network Namespace,而是和宿主机共用一个 Network space。
容器将不会假造出自己的网卡,而是直接使用宿主机的 IP 和端口。

如果在 docker run 命令中同时使用了 --network host 和 -p端口映射,例如:
  1. docker run -p 8082:8080 --network host tomcat
复制代码
那么会出现一个警告:
  1. 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、端口范围。两个容器除了网络共享,其他的如文件系统、进程列表依然是隔离的。

示例:
  1. docker run -it --name alpine1 alpine /bin/sh
  2. # 指定和 alpine1 容器共享网络
  3. 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):

  • 新建自界说网络
  1. docker network create tomcat_network
复制代码

  • 查看网络列表
  1. docker network ls
复制代码

  • 创建容器时,指定加入我们自界说的网络中
  1. docker run -d -p 8081:8080 --network tomcat_network --name tomcat1 tomcat:8.5-jdk8-corretto
  2. docker run -d -p 8082:8080 --network tomcat_network --name tomcat2 tomcat:8.5-jdk8-corretto
复制代码

  • 此时进入tomcat1中,使用ping命令测试连接tomcat2容器名,发现可以正常连通
  1. # 安装ifconfig命令
  2. yum install -y net-tools
  3. # 安装ip addr命令
  4. yum install -y iproute
  5. # 安装ping命令
  6. yum install -y iputils
  7. # 直接ping容器名,不需要ping IP地址
  8. ping tomcat2
复制代码
十二、Docker-compose容器编排

1、概述

Docker-Compose 是 Docker 官方的开源项目,负责实现对Docker容器集群的快速编排。
Docker-Compose可以管理多个Docker容器构成一个应用。需要界说一个yaml格式的配置文件 docker-compose.yml,配置好多个容器之间的调用关系,然后只需要一个命令就能同时启动/关闭这些容器。
2、安装Docker-Compose

Docker-Compose的版本需要和Docker引擎版本对应,可以参照官网上的对应关系。
安装Compose:
  1. # 例如从github下载 2.5.0版本的docker-compose
  2. # 下载下来的文件放到 /usr/local/bin目录下,命名为 docker-compose
  3. curl -L https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
  4. # 添加权限
  5. chmod +x /usr/local/bin/docker-compose
  6. # 验证
  7. docker-compose version
复制代码
卸载Compose:直接删除 usr/local/bin/docker-compose文件即可
3、核心概念



  • 服务(service):一个个应用容器实例
  • 工程(project):由一组关联的应用容器构成的一个完整业务单位,在docker-compose.yml中界说
4、使用步骤


  • 编写 Dockerfile 界说各个应用容器,并构建出对应的镜像文件
  • 编写 docker-compose.yml,界说一个完整的业务单位,安排好团体应用中的各个容器服务
  • 执行 docker-compose up 命令,其创建并运行整个应用程序,完成一键部署上线
5、常用命令

  1. docker-compose -h 查看帮助
  2. docker-compose up 创建并启动docker-compose服务
  3. docker-compose up -d
  4. # 后台运行
  5. docker-compose down 停止并删除容器、网络、卷、镜像
  6. ocker-compose exec <yml里面的服务id> /bin/bash  进入容器实例内部
  7. docker-compose ps  展示当前docker-compose编排过的运行的所有容器
  8. docker-compose top        展示当前docker-compose编排过的容器进程
  9. docker-compose log <yml里面的服务id>  查看容器输出日志
  10. docker-compose config  检查配置
  11. docker-compose config -q
  12.    # 有问题才输出
  13. docker-compose restart        重启服务
  14. docker-compose start        启动服务
  15. docker-compose stop                停止服务
复制代码
6、部署微服务(mysql+redis+微服务)

  1. 1、启动MySQL,详见第八章第一节 安装MySQL(单机版)
  2. 2、启动redis,详见第八章第二节 安装Redis
  3. 3、构建镜像,运行微服务
复制代码
上述方法的弊端:


  • 容器启动先后顺序固定,必须先启动mysql+redis
  • 多个run指令,操作复杂
  • 容器间的启停或宕机,有可能导致IP地址对应的容器实例发生变化,映射堕落,要么生产IP写死(不保举),要么通过服务调用
7、compose编排服务

a. 编写docker-compose.yml文件

  1. # docker-compose文件版本号
  2. version: "3"
  3. # 配置各个容器服务
  4. services:
  5.   microService:
  6.     image: docker-compose:1.0
  7.     container_name: docker-compose  # 容器名称,如果不指定,会生成一个服务名加上前缀的容器名
  8.     ports:
  9.       - "6001:6001"
  10.     volumes:
  11.       - /app/microService:/data
  12.     networks:
  13.       - docker_compose_net
  14.     depends_on:  # 配置该容器服务所依赖的容器服务
  15.       - redis
  16.       - mysql
  17.   redis:
  18.     image: redis
  19.     ports:
  20.       - "6379:6379"
  21.     volumes:
  22.       - /app/redis/redis.conf:/etc/redis/redis.conf
  23.       - /app/redis/data:data
  24.     networks:
  25.       - docker_compose_net
  26.     command: redis-server /etc/redis/redis.conf
  27.   mysql:
  28.     image: mysql:5.7
  29.     environment:
  30.       MYSQL_ROOT_PASSWORD: '123456'
  31.       MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
  32.       MYSQL_DATABASE: 'docker_compose'
  33.       MYSQL_USER: 'dev'
  34.       MYSQL_PASSWORD: 'dev'
  35.     ports:
  36.       - "3306:3306"
  37.     volumes:
  38.       - /app/mysql/db:/var/lib/mysql
  39.       - /app/mysql/conf/my.cnf:/etc/my.cnf
  40.       - /app/mysql/init:/docker-entrypoint-initdb.d
  41.     networks:
  42.       - docker_compose_net
  43.     command: --default-authentication-plugin=mysql_native_password # 解决外部无法访问
  44. networks:
  45.   # 创建 docker_compose_net 网桥网络
  46.   docker_compose_net:
复制代码
b.将项目yml文件中的IP替换为服务名

  1. spring:
  2.   datasource:
  3.     username: root
  4.     password: 123456
  5. #    url: jdbc:mysql://124.222.32.135:3306/docker_compose?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
  6.     url: jdbc:mysql://mysql:3306/docker_compose?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
  7.     driver-class-name: com.mysql.cj.jdbc.Driver
  8.   redis:
  9. #    host: 124.222.32.135
  10.     host: redis
  11.     port: 6379
  12.     password:
  13.     database: 0
  14.     timeout: 1800000
  15.     lettuce:
  16.       pool:
  17.         max-active: 20
  18.         max-wait: -1
  19.         max-idle: 5
  20.         min-idle: 0
复制代码
c. 构建镜像

  1. docker build -t docker-compose:1.0 .
复制代码
d.语法检查

  1. docker-compose config -q
复制代码
e.以docker-compose.yml文件启动项目

  1. docker-compose up -d
复制代码
十三、Portainer可视化工具

1、概述

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

  1. # 旧版镜像地址为portainer/portainer,从2022年1月标记为过期
  2. # 新版镜像地址为portainer/portainer-ce
  3. # --restart=always 如果Docker引擎重启了,那么这个容器实例也会在Docker引擎重启后重启,类似开机自启
  4. docker run -d -p 8000:8000 -p 9000:9000 --name portainer --restart=always \
  5.         -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服务编排文件
  1. version: '3.1'
  2. volumes:
  3.   grafana_data: {}
  4. services:
  5.   influxdb:
  6.         # tutum/influxdb 相比influxdb多了web可视化视图。但是该镜像已被标记为已过时
  7.     image: tutum/influxdb:0.9
  8.     restart: always
  9.     environment:
  10.       - PRE_CREATE_DB=cadvisor
  11.     ports:
  12.       - "8083:8083"         # 数据库web可视化页面端口
  13.       - "8086:8086"         # 数据库端口
  14.     volumes:
  15.       - ./data/influxdb:/data
  16.   cadvisor:
  17.     image: google/cadvisor:v0.32.0
  18.     links:
  19.       - influxdb:influxsrv
  20.     command:
  21.       - -storage_driver=influxdb
  22.       - -storage_driver_db=cadvisor
  23.       - -storage_driver_host=influxsrv:8086
  24.     restart: always
  25.     ports:
  26.       - "8080:8080"
  27.     volumes:
  28.       - /:/rootfs:ro
  29.       - /var/run:/var/run:rw
  30.       - /sys:/sys:ro
  31.       - /var/lib/docker/:/var/lib/docker:ro
  32.   grafana:
  33.     image: grafana/grafana:8.5.2
  34.     user: '104'
  35.     restart: always
  36.     links:
  37.       - influxdb:influxsrv
  38.     ports:
  39.       - "3000:3000"
  40.     volumes:
  41.       - grafana_data:/var/lib/grafana
  42.     environment:
  43.       - HTTP_USER=admin
  44.       - HTTP_PASS=admin
  45.       - INFLUXDB_HOST=influxsrv
  46.       - INFLUXDB_PORT=8086
复制代码

  • 检查语法
  1. docker-compose config -q
复制代码

  • 创建并启动容器
  1. docker-compose up -d
复制代码
容器启动之后:

  • 在欣赏器打开InfluxDB数据库的页面: http://xxx.xxx.xxx.xxx:8083,使用命令查看当前数据库中的数据库实例:
  1. 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数据库中的元数据,可以直接选择对应表名)






      • WHERE:添加一个条件,container_name=cig-cadvisor-1






      • ALIAS:配置一个别名,CPU使用情况汇总


十五、口试题

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数据库中的元数据,可以直接选择对应表名)






      • WHERE:添加一个条件,container_name=cig-cadvisor-1






      • ALIAS:配置一个别名,CPU使用情况汇总


本文档参考:
1、尚硅谷Docker实战教程(docker教程天花板)
2、云原生开发

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

愛在花開的季節

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表