• docker学习进阶篇


    一、dockerfile解析

    官方文档: Dockerfile reference | Docker Docs

    1.1、dockfile是什么?

    dockerfile是用来构建docker镜像的文本文件,由一条条构建镜像所需的指令和参数构成的脚本。
    之前我们介绍过通过具体容器反射构建镜像(docker commit)的方法;这里就是第二种直接构建镜像的方法。

    构建三部曲:
    (1)编写Dockerfile文件
    (2)docker build命令构建镜像
    (3)docker run镜像运行容器实例


    1.2、dockerfile构建过程

    1.2.1、 dockerfile基础知识

    (1)每条保留字指令都必须为大写字母且后面要跟随至少一个参数;
    (2)指令按照从上到下,顺序执行
    (3)#表示注释;
    (4)每条指令都会创建一个新的镜像层并对镜像进行提交;

    注:官网上的诸如ADD/CMD/COPY/FROM等关键字,也称保留字。

    1.2.2、docker执行dockerfile的大致流程

    (1)docker从基础镜像运行一个容器;
    (2)执行一条指令并对容器作出修改;
    (3)执行类似docker commit的操作提交一个新的镜像层;
    (4)docker在基于刚提交的镜像运行一个新容器;
    (5)执行dockerfile中的下一条指令直到所有指令都执行完成;


    1.2.3、小总结

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

    • Dockerfile是软件的原材料
    • Docker镜像是软件的交付品
    • Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例

    Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。

    1. Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;
    2. Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时会真正开始提供服务;
    3. Docker容器,容器是直接提供服务的。

    1.3、dockerfile常用保留字指令

    1.3.1、dockerfile直观认识

    hub.docker.com 搜tomcat(随便搜啥都行)。都会有个"Dockerfile links",我们打开就可以看到其对应的dockerfile。

    1.3.2、dockerfile常用指令

    FROM:

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

    MAINTAINER:

    镜像维护者的姓名和邮箱地址。

    RUN:

    RUN是在容器构建(docker build)时需要运行的命令。有两种格式:
    (1)shell
    RUN <命令行命令>
    # <命令行命令>等同于,在终端操作的shell命令。
    #举个例子:我需要在build的时候安装一个vim,就可以按如下写:
    RUN yum -y install vim

    (2)exec
    RUN ["可执行文件", "参数1", "参数2"]
    #例如:
    RUN ["./test.php", "dev", "offline"]等价于 ./test.php dev offline

    注:感觉比价鸡肋,用shell的方式其实就好了。

    EXPOSE 

    指定当前容器对外暴露的端口。

    1. EXPOSE 80/tcp
    2. EXPOSE 80/udp

    WORDIR

    指定在创建容器后,终端默认登陆进来的工作目录(就是登陆容器的默认落脚路径)。

    USER

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

    ENV

    用来在构建镜像过程中设置环境变量。就理解为定义了一个变量名(key)。
    #举个例子:就是定义了一个环境变量"MY_HOME"并使用。
    ENV MY_HOME /usr/local/tomcat 
    WORKDIR $MY_HOME

    ADD

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

    COPY

    将宿主机目录下的文件拷贝进镜像(不解压)。显然,用ADD更好。


    VOLUME

    容器数据卷,用于数据保存和持久化。其实就是和 -v 选项平齐。


    CMD

    作用:指定容器启动后要干的事情。

    CMD指令的格式和 RUN 相似,也是两种格式:

    (1)shell格式: CMD <命令>
    (2)exec格式: CMD["可执行文件", "参数1", "参数2" ……]

    注意: Dockerfile中可以有多个CMD指令但只有最后一个生效; 另外CMD会被docker run之后的参数替换。啥意思呢?这里解释一下。对于 tomcat 的dockerfile的最后两句如下:

    1.     EXPOSE 8080    #暴露8080端口
    2.     CMD ["catalina.sh", "run"]   #执行tomcat的启动脚本catalina.sh

            如果docker run不加参数的启动。 docker run -it -p 8080:8080 镜像id 就是按照dockerfile来执行。但是如果变成了 "docker run -it -p 8080:8080 镜像id /bin/bash",那么上述的 CMD ["catalina.sh", "run"] 就会失效。
            实际执行的效果变成了 CMD ["/bin/bash", "run"]; 此时容器确实是启动了,但是tomcat本身确没有正常启动,显然也不通。

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

    ENTRYPOINT

    作用: 也是用来指定一个容器启动时要运行的命令。
    类似于CMD指令,但是 ENTRYPOINT 不会被docker run后面的命令覆盖;而且这些命令行参数会被当做参数送给ENTRYPOINT指令指定的程序。

    1. #命令格式
    2. ENTRYPOINT ["executeable", "param1", "param2",……]

    ENTRYPOINT可以和CMD一起用,一般是变参才会使用CMD,这里的CMD等于是在给ENTRYPOINT传参。当指定ENTRYPOINT后CMD的含义就发生了变化,不再是直接运行其明星而是将CMD的内容作为参数传递给ENTRYPOINT指令,他两个组合会变成 ""

    看个具体的案例。假设已经通过Dockerfile构建了 nginx:test 镜像:

    FROM nginx
    ENTRYPOINT ["nginx", "-c"] #定参
    CMD ["/etc/nginx/nginx.conf"] #变参

    如果执行:

    • docker run nginx:test  则容器启动后,会执行 nginx -c /etc/nginx/nginx.conf
    • docker run nginx:test /app/nginx/new.conf  则容器启动后,会执行 nginx -c /app/nginx/new.conf

    1.3、实际案例

    1.3.1、自定义镜像mycentosjava8

    目标:docker原始的centos不具备vim、ifconfig、java等功能;现在要做的事情就是在原有centos镜像的基础上构建出具有这些功能的镜像。

    (0)前期准备
    #建立一个工作目录
    mkdir myfile  

    下载jdk8的tar包放在此目录
    jdk-8u171-linux-x64.tar.gz

    (1)编写Dockerfile文件

    注:文件名必须是 "Dockerfile"。

    创建 Dockerfile 文件,并粘贴如下内容。

    1. FROM centos
    2. MAINTAINER zs<zs@126.com>
    3. ENV MYPATH /usr/local
    4. WORKDIR $MYPATH
    5. #必须要添加这一坨,否则会报错
    6. #参照:https://blog.csdn.net/weixin_51689532/article/details/127533832
    7. RUN cd /etc/yum.repos.d/
    8. RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
    9. RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
    10. RUN yum update -y
    11. #安装vim编辑器
    12. RUN yum -y install vim
    13. #安装ifconfig命令查看网络IP
    14. RUN yum -y install net-tools
    15. #安装java8及lib库
    16. RUN yum -y install glibc.i686
    17. RUN mkdir /usr/local/java
    18. #ADD 是相对路径jar,把jdk-8u171-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置
    19. ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/
    20. #配置java环境变量
    21. ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
    22. ENV JRE_HOME $JAVA_HOME/jre
    23. ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
    24. ENV PATH $JAVA_HOME/bin:$PATH
    25. EXPOSE 80
    26. CMD echo $MYPATH
    27. CMD echo "success--------------ok"
    28. CMD /bin/bash

    (2)构建镜像

    1. #格式如下
    2. docker build -t 新镜像名字:TAG .
    3. #具体执行指令如下
    4. docker build -t centosjava8:1.5 .
    5. 注:完整的执行过程有点久,主要是"yum update -y"花了很多时间。

    执行完毕后我们就可以通过 docker images查看到生成的镜像了。 

    (3)运行镜像

    docker run -it centosjava8:1.5

    (4)验证确实含有java/vim/ifconfig命令

    java -version
    1.3.2、虚悬镜像

    虚悬镜像:仓库名、标签名都是的镜像,称为dangling images(虚悬镜像)。
    一般都是在镜像构建或删除出错导致出现虚悬镜像,这种镜像占用资源但是是没有意义的要予以删除。

    (1)构建一个虚悬镜像。
    创建包含如下内容的 Dockerfile,并构建。

    from ubuntu
    CMD echo 'action is success'

    1. #构建
    2. docker build .

    (2)列出docker中的虚悬镜像

    docker image ls -f dangling=true

    (3)删除虚悬镜像:

    docker image prune

    1.3.3、自定义镜像myubuntu

    二、docker微服务实战

     2.1、java微服务的玩法

      (0)编写java源码并构建jar包

    得到 docker_boot-1.0-SNAPSHOT.jar ; java的玩法不做介绍。

    (1)编写Dockerfile

    1. FROM openjdk:8-oracle
    2. MAINTAINER lee
    3. # 在主机 /var/lib/docker目录下创建一个临时文件,并链接到容器的 /tmp
    4. VOLUME /tmp
    5. # 将jar包添加到容器中,并命名为 springboot_docker.jar
    6. ADD docker_boot-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项目配置的端口号为6001,需要将6001暴露出去
    11. EXPOSE 6001

    (2)构建镜像

    docker build -t springboot_docker:1.0 .

    (3)启动容器

    docker run -d -p 6001:6001 --name springboot springboot_docker:1.0

    2.2、mongo_proxy打镜像

    注:mongo_proxy为作者本人实现的一个访问mongodb存储的trpcgo服务,读者看看流程就好。

    此处要实现的效果是将mongo_proxy服务打成一个镜像并部署实例化的容器;此外还会在宿主器上启动一个mongodb的容器。期望的效果就是外界工具脚本通过访问mongo_proxy暴露的接口实现mongodb数据的增删改查。

    2.2.1、mongodb容器

    (1)启动mongodb容器

    1. docker run -d -p 27017:27017 --name=zsmongodb \
    2.     -e MONGO_INITDB_ROOT_USERNAME=root \
    3.     -e MONGO_INITDB_ROOT_PASSWORD=123456 \
    4.     mongo:4.0


    (2)连接mongodb并插入一条测试数据

    1. docker exec -it zsmongodb /bin/bash
    2. mongo --host 127.0.0.1 -u root -p 123456
    3. use db_call_track
    4. db.coll_1.save({
    5.         "_id" : ObjectId("64af6d368350f30cc6fb1fbb"),
    6.         "ext1" : "{\"callid\":\"7085095277245292544\",\"has_third_call\":0,\"legid\":\"70850952772452925441\"}\n",
    7.         "ext2" : "",
    8.         "key" : "call_2885715001_+8615731633538",
    9.         "kfext" : 3007552478,
    10.         "kfuin" : 2885715001,
    11.         "status" : 0,
    12.         "call_source" : 5,
    13.         "display_type" : 3,
    14.         "ext3" : "",
    15.         "phonenumer" : "+8615731633538",
    16.         "time" : 1689218355954380,
    17.         "direction" : 2,
    18.         "duration" : 0
    19. })

    (3)查看mongodb容器分配的ip(记录下来为172.17.0.2)

    docker inspect 3454673b0961 | tail -n 25 
    2.2.2、mongo_proxy服务镜像制作部署 —— 写死ip访问

    (1)准备物料

    新建mongo_proxy目录,将mongo_proxy_svr.tar.gz、trpc_go.yaml、start.sh三个文件复制进来。

     start.sh 内容如下:

    1. #!/bin/sh
    2. cd /data/app/bin
    3. chmod +x mongo_proxy_svr
    4. ./mongo_proxy_svr -conf ../conf/trpc_go.yaml > /data/app/log/stdout.log 2>&1

    trpc_go.yaml 如下,其中基于原服务修改了

    (1)bid10对应的配置如下(其中172.17.0.2是mongodb镜像被分配的ip)
        - name: trpc.mongodb.online.instance9
          target: mongodb://root:123456@172.17.0.2:27017/?readPreference=secondaryPreferred
          timeout: 3000     
    (2)把最下面的metrix相关配置删掉

    1. global: #全局配置
    2. namespace: Development #环境类型,分正式production和非正式development两种类型
    3. env_name: test #环境名称,非正式环境下多环境的名称
    4. server: #服务端配置
    5. app: test #业务的应用名
    6. server: TimelineProxyService #进程服务名
    7. bin_path: /usr/local/trpc/bin/ #二进制可执行文件和框架配置文件所在路径
    8. conf_path: /usr/local/trpc/conf/ #业务配置文件所在路径
    9. data_path: /usr/local/trpc/data/ #业务数据文件所在路径
    10. filter: #针对所有service处理函数前后的拦截器列表
    11. - simpledebuglog
    12. - recovery #拦截框架创建的业务处理协程panic
    13. service: #业务服务提供的service,可以有多个
    14. - name: inner.track.timeline.TimelineProxyService #service的路由名称
    15. #ip: 127.0.0.1 #服务监听ip地址 可使用占位符 ${ip},ip和nic二选一,优先ip
    16. nic: eth0
    17. port: 21187 #服务监听端口 可使用占位符 ${port}
    18. network: udp #网络监听类型 tcp udp
    19. protocol: inner #应用层协议 trpc http
    20. timeout: 1000 #请求最长处理时间 单位 毫秒
    21. - name: trpc.track.timeline.TimelineProxyService #service的路由名称
    22. #ip: 127.0.0.1 #服务监听ip地址 可使用占位符 ${ip},ip和nic二选一,优先ip
    23. nic: eth0
    24. port: 21187 #服务监听端口 可使用占位符 ${port}
    25. network: tcp #网络监听类型 tcp udp
    26. protocol: inner #应用层协议 trpc http
    27. timeout: 1000 #请求最长处理时间 单位 毫秒
    28. #client: #客户端调用的后端配置
    29. # timeout: 1000 #针对所有后端的请求最长处理时间
    30. # namespace: Development #针对所有后端的环境
    31. # filter: #针对所有后端调用函数前后的拦截器列表
    32. # service: #针对单个后端的配置
    33. # - name: trpc.track.timeline.TimelineProxyService #后端服务的service name
    34. # namespace: Development #后端服务的环境
    35. # network: tcp #后端服务的网络类型 tcp udp 配置优先
    36. # protocol: trpc #应用层协议 trpc http
    37. # target: ip://127.0.0.1:8000 #请求服务地址
    38. # timeout: 1000 #请求最长处理时间
    39. #yaml文件格式必须正确;如同统一加一行空格之中都是不行的!!!
    40. client:
    41. service:
    42. - name: trpc.mongodb.online.instance8 #对应bid9,验证访问容器名是否ok
    43. target: mongodb://root:123456@zsmongodb:27017/?readPreference=secondaryPreferred
    44. timeout: 3000
    45. - name: trpc.mongodb.online.instance9 #对应bid10,验证访问分配ip是否ok
    46. target: mongodb://root:123456@172.17.0.2:27017/?readPreference=secondaryPreferred
    47. timeout: 3000
    48. - name: trpc.mongodb.online.instance10 #对应bid11,验证访问本机是否ok
    49. target: mongodb://root:123456@127.0.0.1:27017/?readPreference=secondaryPreferred
    50. timeout: 3000
    51. - name: trpc.track.timeline.TimelineProxyService #后端服务的service name
    52. namespace: Development #后端服务的环境
    53. network: tcp #后端服务的网络类型 tcp udp 配置优先
    54. protocol: trpc #应用层协议 trpc http
    55. target: ip://9.134.50.94:8000 #请求服务地址
    56. timeout: 1000 #请求最长处理时间
    57. plugins: #插件配置
    58. log: #日志配置
    59. default: #默认日志的配置,可支持多输出
    60. - writer: file #本地文件日志
    61. level: debug #本地文件滚动日志的级别
    62. writer_config:
    63. filename: ../log/trpc_water.log #本地文件滚动日志存放的路径
    64. max_size: 20 #本地文件滚动日志的大小 单位 MB
    65. max_backups: 20 #最大日志文件数
    66. max_age: 7 #最大日志保留天数
    67. compress: false #日志文件是否压缩
    68. - writer: uls #ULS日志
    69. level: debug #日志级别
    70. remote_config:
    71. app_id: 0x950009 #业务的AppId,由系统管理员分配,必填字段
    72. water_id: 70 #iWaterDestID: 流水日志需要发送到的日志中心ID(流水日志中心可能有多套,每套一个ID)
    73. color_id: 2 #iColorDestID: 染色日志需要发送到的日志中心ID(染色日志中心可能有多套,每套一个ID)
    74. log_path: ../log/trpc #szLogFilePath:本地磁盘log文件的绝对路径,本地的流水日志和染色日志都记录在该路径下,不能传入空指针,否则函数调用出错
    75. svr_configed: 1 #iSvrConfiged:是否启用远程记录流水日志,0:不启用, 1:启用
    76. color_svr_configed: 0 #iColorSvrConfiged:是否启用远程记录染色日志,0:不启用, 1:启用
    77. msg_port: 0 #可指定发送远程日志所绑定的端口,为0则随机端口
    78. relay_port: 0 #可指定转发包所绑定的端口,为0则随机端口
    79. user_def_1: 3 #初始化用户自定义字段1,由调用者自己填写,自己解释
    80. agent_local_log: 0 #是否由Agent来负责记录本地log,业务进程不再记录
    81. w_log_level: 5 #cWLogLevel:本地流水日志的日志记录级别(取值范围0-5,请参考"日志级别定义"),小于等于该级别的都记录到本地
    82. w_log_msg_level: 5 #cWLogMsgLevel:流水日志中心的日志记录级别(取值范围0-5,请参考"日志级别定义"),小于等于该级别的都发送到流水日志中心, 一般设置为_LC_WARNING_
    83. t_log_level: 5 #cTLogLevel:本地染色日志的日志记录级别(取值范围0-5,请参考"日志级别定义"),小于等于该级别的都记录到本地
    84. t_log_msg_level: 5 #cTLogMsgLevel:染色日志中心的日志记录级别(取值范围0-5,请参考"日志级别定义"),小于等于该级别的都发送到染色日志中心, 一般设置为_LC_WARNING_
    85. relay_log_level: 3 #cRelayLogLevel:转发包的记录级别(取值范围0-5,请参考"日志级别定义"),小于等于该级别并且染色配置命中,会转发到指定的ip:port
    86. log_size: 10000000 #iLogSize:本地磁盘log文件单个文件的大小
    87. log_num: 10 #iLogNum:本地磁盘log文件的最大个数
    88. call_depth: 7 #必须是7才能打印正确的文件名和函数名

    (2)新建Dockerfile,内容如下

    1. FROM centos
    2. MAINTAINER zs<zs@126.com>
    3. ENV MYPATH /data/app
    4. WORKDIR $MYPATH
    5. RUN mkdir -p /data/app/bin
    6. RUN mkdir -p /data/app/conf
    7. RUN mkdir -p /data/app/log
    8. RUN cd /data/app/log
    9. RUN touch stdout.log
    10. ADD mongo_proxy_svr $MYPATH/bin
    11. RUN chmod +x $MYPATH/bin/mongo_proxy_svr
    12. ADD trpc_go.yaml $MYPATH/conf
    13. ADD start.sh $MYPATH/bin
    14. RUN chmod +x /data/app/bin/start.sh
    15. ENTRYPOINT ["/data/app/bin/start.sh"]
    16. EXPOSE 21187/udp
    17. EXPOSE 21187/tcp

    (3)构建镜像

    docker build -t mongo_proxy:1.0 .

    (4)确认镜像已经存在

    docker images

    (5)利用此镜像启动容器

    docker run -d --name my_mongoproxy -p 21187:21187/tcp -p 21187:21187/udp  mongo_proxy:1.0

    (6)进入容器验证服务进程正常运行

    (7)用脚本工具向宿主机的21187端口发送如下请求

    1. inner_timeline_read_req {
    2. uint32_bid: 10
    3. str_db_name: "db_call_track"
    4. str_table_name: "coll_1"
    5. str_req_args: "{\"filter\": {\"key\": \"call_2885715001_+8615731633538\", \"time\": {\"$gte\": 1673402312430230}}, \"sort\": {\"time\": -1}, \"limit\": 2}"
    6. }
    7. #其中str_req_args为:
    8. findArgs = {
    9. "filter" : {
    10. "key" : "call_2885715001_+8615731633538",
    11. "time" : {
    12. "$gte" : 1673402312430230
    13. }
    14. },
    15. "limit" : 2,
    16. "sort" : {
    17. "time" : -1
    18. }
    19. }
    20. #./303294.py -e 6 -k 2355128746 -x 3008819490

    可以看到有数据返回。显然都通了!!!

    2.2.3、mongo_proxy服务镜像制作部署 —— host模式

    上述mongo_proxy访问mongodb的时候采用写死ip的方式显然是不行的,即此处要进行网络规划。

    此处直接采用host模式,理论上讲访问mongodb数据库的时候把连接串ip换成127.0.0.1就行了。

    预期:预期bid11能通。。

    (1)启动mongodb数据库

    1. docker run -d --name=zsmongodb \
    2. --net host \
    3. -e MONGO_INITDB_ROOT_USERNAME=root \
    4. -e MONGO_INITDB_ROOT_PASSWORD=123456 \
    5. mongo:4.0

    (2)启动mongo_proxy_svr

    docker run -d --name my_mongoproxy --net host  mongo_proxy:1.0
    

    (3)是通的,符合预期

    2.2.4、mongo_proxy服务镜像制作部署 —— 自定义网络模式

    预期:预期bid9,即直接用名字zsmongodb代替ip的连接方式是能通的。

    (1)创建一个网络

    docker network create my_network

    (2)启动mongodb容器并加入此网络

    1. docker run -d -p 27017:27017 --name=zsmongodb \
    2.     --network my_network \
    3.     -e MONGO_INITDB_ROOT_USERNAME=root \
    4.     -e MONGO_INITDB_ROOT_PASSWORD=123456 \
    5.     mongo:4.0

    (3)启动mongo_proxy服务容器并加入此网络

    docker run -d --name my_mongoproxy --network my_network -p 21187:21187/tcp -p 21187:21187/udp  mongo_proxy:1.0
    

    (4)向mongodb数据库中插入测试数据

    1. docker exec -it zsmongodb /bin/bash
    2. mongo --host 127.0.0.1 -u root -p 123456
    3. use db_call_track
    4. db.coll_1.save({
    5. "_id" : ObjectId("64af6d368350f30cc6fb1fbb"),
    6. "ext1" : "{\"callid\":\"7085095277245292544\",\"has_third_call\":0,\"legid\":\"70850952772452925441\"}\n",
    7. "ext2" : "",
    8. "key" : "call_2885715001_+8615731633538",
    9. "kfext" : 3007552478,
    10. "kfuin" : 2885715001,
    11. "status" : 0,
    12. "call_source" : 5,
    13. "display_type" : 3,
    14. "ext3" : "",
    15. "phonenumer" : "+8615731633538",
    16. "time" : 1689218355954380,
    17. "direction" : 2,
    18. "duration" : 0
    19. })

    (5)外部脚本访问效果如下,显然符合预期

    2.3、mongo_proxy镜像上传腾讯云

    按照 上一篇文章 的方法将此镜像上传腾讯云。

    由于名字发生了变更,所以将docker-compose.yml稍微改下以后就可以随时服用mongo_proxy + mongodb这对组合了。

    1. # docker-compose文件版本号
    2. version: "3"
    3. # 配置各个容器服务
    4. services:
    5. mongo_proxy_svr:
    6. image: ccr.ccs.tencentyun.com/shuozhuo/mongo_proxy:1.0
    7. container_name: my_mongoproxy # 容器名称,如果不指定,会生成一个服务名加上前缀的容器名
    8. ports:
    9. - "21187:21187/tcp"
    10. - "21187:21187/udp"
    11. volumes:
    12. - /data/app/mongo_proxy_svr/log:/data/app/log
    13. networks:
    14. - my_network
    15. depends_on: # 配置该容器服务所依赖的容器服务
    16. - zsmongodb
    17. zsmongodb:
    18. image: mongo:4.0
    19. environment:
    20. MONGO_INITDB_ROOT_USERNAME: 'root'
    21. MONGO_INITDB_ROOT_PASSWORD: '123456'
    22. ports:
    23. - "27017:27017"
    24. volumes:
    25. - /data/app/mongodb/data:/data/db
    26. networks:
    27. - my_network
    28. networks:
    29. # 创建 my_network 网桥网络
    30. my_network:

    2.4、q的玩法

    稍晚补充

    三、docker网络

    3.1、docker network简介

      先简单比对下没启动docker和启动docker后的主机的网络情况。

    1. #没有docker执行ifconfig:
    2. ens33/eth0: 这个标识宿主机的地址
    3. lo: 回环地址 127.0.0.1
    4. vibri0:
    5. #启动docker后执行ifconfig:
    6. docker0
    7. eth0
    8. lo
    9. virbro

    可以看到多了个docker0。这是因为docker启动后会产生一个名为docker0的虚拟网桥。

    docker就是通过docker0这个网桥进行容器↔宿主机、容器→容器间的网络通信。

    Docker 服务默认会创建一个docker0网桥(其上有一个docker0内部接口),该桥接网络的名称为 docker0,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。

    Docker默认指定了docker0接口的IP地址和子网掩码,让主机和容器之间可以通过网桥互相通信。

    查看bridge网络的详细信息,并通过grep获取名称:

    docker network inspect bridge | grep name

    可以看到其名称为docker0

    3.2、docker network常用命令

    1.  (1)列出当前网络
    2. docker network ls
    3. 注:主要用的是brige、其次是host,第三个none几乎不用。
    4. (2)创建一个网络
    5. docker network create my_network
    6. (3)删除一个网络
    7. docker network rm my_network
    8. (4)查看网络元数据
    9. docker network inspect bridge

    3.3、docker network能干啥

    (1)容器间的互联和通讯以及端口映射;
    (2)容器ip变动的时候可以通过服务名直接网络通信而不受到影响(而不是写死ip);

    其实就是名字服务的意思。docker1去访问docker2的mysql你绝对不能直接写死ip地址,而应该写的是访问mysql。因为重启后mysql所在的容器的ip地址是会变的!!!!!。

    3.4、验证示例内默认网络ip生成规则

    默认启动ubuntu系统得到u1和u2。(记得通过win+p+q退出,否则容器也随之退出了)

    1. docker run -it --name u1 ubuntu bash
    2. docker run -it --name u2 ubuntu bash

    #查看网络情况

    1. docker inspect 6302d5f329b3 | tail -n 25
    2. docker inspect ffd05fb83ff1 | tail -n 25

    其中bridge即表示网络模式;IPAddress即为容器的ip地址。
    可以看到u1的ip是172.17.0.2,u2的ip是172.17.0.3;显然两个容器的IPAddress彼此独立。

    我们现在将u2删除,然后启动u3,并查看u3的ip。

    1. docker rm -f u2
    2. docker run -it --name u3 ubuntu bash
    3. docker inspect u3 | tail -n 25

    发现u3的ip是172.17.0.3了(此ip之前被u2占有),显然ip是不能表征某个具体的容器的。

    结论:docker容器内部的ip是可能发生改变的,ip不能用于表征具体容器。在访问的时候也就不能根据ip进行访问。

    3.5、docker network网络模式有哪几种

    总共有如下五种模式。主流就是bridge、host、none三种;其中bridge最常用、host次之。其他平时不怎么用。
    ps: 分别使用 --network bridge / --network host / --network none  指定。

    网络模式

    简介

    使用方式

    bridge

    为每一个容器分配、设置IP等,并将容器连接到一个docker0

    虚拟网桥,默认为该模式

    --network bridge

    host

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

    --network host

    none

    容器有独立的 Network namespace,但并没有对齐进行任何网络设置,如分配 veth pari

    和 网桥连接、IP等

    --network none

    container

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

    --network container:NAME或者容器ID

    自定义就是bridge模式,理解为自定义的bridge(可以实现访问名字)/
    3.5.1、bridge模式(默认)

            Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一个宿主机内的容器接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。

        docker run的时候,没有指定--network的话,默认使用的网桥模式就是bridge,使用的就是docker0。在宿主机ifconfig就苦役看到docker0和自己createnetwork

            网桥docker0创建一对对等虚拟设备接口,一个叫veth,另一个叫eth0,成对匹配:

            整个宿主机的网桥模式都是docker0,类似一个交换机有一堆接口。其中docker0就交换器;veth就是交换机上的插槽;运行的容器就视为一个精简后的linux,系统的eth0网卡就插在veth上。就称为veth pair。显然通过这种方式就可以实现容器和宿主机、容器与容器间的网络通信。

            我们分别在宿主机和容器内执行"ip addr"可以看到匹配情况。

    3.5.2、host模式

     直接使用宿主机的 IP 地址与外界进行通信,不再需要额外进行 NAT 转换。

    容器不会获得独立的Network Namespace,而是和宿主机公用一个Network Namespace。容器也不会虚拟出自己的网卡(eth0)而是使用宿主机的ip和端口。

    如果在 docker run 命令中同时使用了 --network host 和 -p端口映射,例如:

    1. docker run -d -p 8083:8080 --network host --name tomcat83 tomcat
    2. #不指定网址启动tomcat82
    3. docker run -d -p 8082:8080 --name tomcat82 tomcat

    执行如下指令会出现警告:

    WARNING: Published ports are discarded when using host network mode

    因为此时已经使用了host模式,本身就是直接使用的宿主机的IP和端口,此时的-p端口映射就没有了意义,也不会生效,端口号还是会以主机端口号为主。

    正确做法是:不再进行-p端口映射,或者改用bridge模式

    显然tomcat82和83的区别如下:

    查看tomcat83的内部信息,因为和宿主机公用IP、端口,所以就没有自己独立的了。 

    docker inspect tomcat83 | tail -n 25

    同理进入容器后执行“ip addr”的返回信息也和宿主机执行差不多。

    此时访问tomcat的ip就是宿主机的ip,port就是默认的8080;其效果就类似于在宿主机上装了一个tomcat。

    3.5.3、none模式

    禁用网络功能。

    none模式下,并不为docker容器进行任何网络配置。进入容器内,使用 ip addr查看网卡信息,只能看到 lo(本地回环网络127.0.0.1网卡)。

    3.5.4、container模式

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

    实例

    docker run -it --name alpine1 alpine /bin/sh

    # 指定和 alpine1 容器共享网络
    docker run -it --netrowk container:alpine1 --name alpine2 alpine /bin/sh

    注:这个alpine是一个轻量、功能相对完备的Linux发行版本。由于小巧且功能完备,非常适合用作基础镜像。

    3.5.5、自定义网络

    自定义网络本身就维护好了主机名和ip的对应关系(ip和域名都能通)!!

    注:这里使用 billygoo/tomcat8-jdk8 是因为这个镜像有"ip addr"/"ping"等指令(官方认证的tomcat没有这些指令所以没用)。

    不用自定义网络,按照IP地址去ping是ok的,即容器1去ping容器2的ip能通,反之亦然。但是按照服务名去ping就是不通的。如下:

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

    #通过一下指令直到81的ip是 172.17.0.2, 82的ip是 172.17.0.3

    1. docker inspect tomcat81 | tail -n 25
    2. docker inspect tomcat82 | tail -n 25

    #进入两个容器ping对方的ip发现都是通的,但是尝试ping对方名字(tomcat81、tomcat82)发现都是不通的。

    1. docker exec -it tomcat81 /bin/bash
    2. ping 172.17.0.3
    3. ping tomcat82
    4. docker exec -it tomcat82 /bin/bash
    5. ping 172.17.0.2
    6. ping tomcat81

    前面我们知道随着容器的销毁创建ip是会变的(即ip代表不了容器),但是直接访问名字又不通,那要怎么办呢?—— 自定义网络就可以解决这个问题。


    自定义桥接网络,自定义网络默认使用的就是桥接网络bridge。
     

    自定义网络效果演示:

    1. 新建自定义网络:
    2. docker network create zszs_network
    3. docker network ls
    4. #新建的容器加入上一步新建的自定义网络。
    5. docker run -d -p 8081:8080 --network zszs_network --name tomcat81 billygoo/tomcat8-jdk8
    6. docker run -d -p 8082:8080 --network zszs_network --name tomcat82 billygoo/tomcat8-jdk8
    7. #进入容器ping对方的名字,发现可以ping通
    8. docker exec -it tomcat81 /bin/bash

    #然后在进入tomcat81,tomcat82看看名字能不能ping通。果然可以ping通了。

    注意:docker多容器的集群规划一定要访问名字不能直接粗暴访问ip。

    四、docker-compose容器编排

    官网: https://docs.docker.com/compose/
     

    4.1、docker-compose是什么?能干什么?


    一句话:容器太多(集群),而且容器之间涉及启动顺序、网络调用、一键部署、一键重启等诉求所以需要一个大总管管理起来。

    compose是docker公司推出的一个工具软件,用于管理多个Docker容器组成的一个大的应用。通过定义一个yaml格式的配置文件docker-compose.yml写好容器之间的调用关系。然后,只要一个命令就能同时启动/关闭这个大规模容器集群。

    docker建议我们每一个容器中只运行一个服务,因为docker容器本身占用的资源极少。这种细粒度的划分显然就会让整体流程更加繁琐。
    举个例子:我的一个web微服务可能依赖redis、mongodb、kafka、es,还可能需要注册中心、负载均衡等等;显然执行N遍docker run就太傻了。

    compose运行用户通过一个单独的docker-compose.yml模板文件来定义一组相关联的应用容器为一个项目。然后就可以很容易的用一个配置文件定义一个多容器的应用。一条指令就可以完成这个项目的所有依赖并完成构建。它解决了容器与容器之间的管理编排问题。

    4.2、下载与安装

    安装简介参照这里: https://docs.docker.com/compose/install/

    我们这里选择 "Scenario two: Install the Compose plugin" 的 “Downloading and installing manually”。

    步骤如下。

    1、To download and install the Compose CLI plugin, run:

    DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
    mkdir -p $DOCKER_CONFIG/cli-plugins
    curl -SL https://github.com/docker/compose/releases/download/v2.24.6/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose

    注: wget太慢的话就手动下载然后在上传到 $DOCKER_CONFIG/cli-plugins 路径,并重命名为"docker-compose"。

    2、Apply executable permissions to the binary:

    chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose

    3、测试安装

    docker compose version

    总结下来就是把docker-compose下载下来,然后放到$DOCKER_CONFIG/cli-plugins路径下就可以了。

    卸载方式参见:  https://docs.docker.com/compose/install/uninstall/
     

    4.3、compose使用步骤

    (1)一个文件: docker-compose.yml
    (2)两个要素: 
    1)服务(service):一个个应用容器实例,比如业务微服务、mysql容器、nginx容器或redis容器。
    2)工程(project):由一组关联的应用容器组成的一个完成业务单元,在docker-compose.yml文件中定义。

    (3)compose使用的三个步骤
    首先,编写Dockerfile定义各个微服务应用并构建出对应的镜像文件;
    使用 docker-compose.yml定义一个完整业务单元,安排好整体应用中的各个容器服务。
    最后,执行docker-compose.yml命令来启动并运行整个工程,完成一键部署上线。

    4.4、compose常用命令

    注:我这个版本是“docker compose”,有的是“docker-compse” 

    docker compose -h     #查看帮助
    docker compose up     #启动所有docker-compose服务
    docker compose up -d  #启动所有docker-compose服务并后台运行
    docker compose down   #停止并删除容器、网络、卷、镜像
    docker compose exec yml里面的服务id   #进入容器实例内部
    docker compose ps     #展示当前docker-compose编排过的运行的所有容器
    docker compose top    #展示当前docker-compose编排过的容器进程

    docker compose logs yml里面的服务id   #查看容器输出日志
    docker compose config      #检查配置
    docker compose config -q   #检查配置,有问题才有输出
    docker compose restart     #重启服务
    docker compose start       #启动服务
    docker compose stop        #停止服务


    4.5、compose编排微服务

    还是上面mongo_proxy访问mongodb的例子,我们编排2.2.4(自定义网络)的工程。

    (1)首先编写如下docker-compose.yml文件

    注:以后写docker-compose.yml就是拿现成的过来改,而不是从头自己写(总体比较直观)!!

    1. # docker-compose文件版本号
    2. version: "3"
    3. # 配置各个容器服务
    4. services:
    5. mongo_proxy_svr: #第一个启动的容器的容器名为mongo_proxy_svr
    6. image: mongo_proxy:1.0 #其依赖的镜像是 mongo_proxy:1.0
    7. container_name: my_mongoproxy # 指定容器名。如果不指定,会生成一个服务名加上前缀的容器名
    8. ports:
    9. - "21187:21187/tcp" #指定端口映射,相当于-p
    10. - "21187:21187/udp" #指定端口映射,相当于-p
    11. volumes: #指定容器数据卷,相当于-v
    12. - /data/app/mongo_proxy_svr/log:/data/app/log
    13. networks: #指定要加入的网络,相当于--net
    14. - my_network
    15. depends_on: #配置该容器服务所依赖的容器服务(依赖zsmongodb这个容器)
    16. - zsmongodb
    17. zsmongodb:
    18. image: mongo:4.0
    19. environment: #指定环境变量(对应docker run中指定环境环境变量)
    20. MONGO_INITDB_ROOT_USERNAME: 'root'
    21. MONGO_INITDB_ROOT_PASSWORD: '123456'
    22. ports:
    23. - "27017:27017"
    24. volumes:
    25. - /data/app/mongodb/data:/data/db
    26. networks:
    27. - my_network
    28. networks:
    29. # 创建 my_network 自定义网桥网络
    30. my_network:

    (2)进行检查

    没有输出说明语法等都没有问题。 

    docker compose config -q

    (3)启动

    docker compose up -d

    (4)自测也都符合预期!!!!

    (5)一键停止

    docker compose stop
    

    (5)总结。显然我们就实现了一键部署、一键停止。

    使用compose后对于三五十个容器的编排完全不在话下,不过如果规模继续增大就需要k8s了。

    4.6、更多容器编排案例

    1、官网上有些案例   Sample apps with Compose | Docker Docs

    其中有很多常用的搭配,例如下面这些。以后需要可以上来看看。

    Elasticsearch / Logstash / Kibana - Sample Elasticsearch, Logstash, and Kibana stack.
    NGINX / Flask / MongoDB - Sample Python/Flask application with Nginx proxy and a Mongo database.

    2、也可以网上直接搜。 

    3、此处在提供一个案例如下。

    1. # docker-compose文件版本号
    2. version: "3"
    3. # 配置各个容器服务
    4. services:
    5. microService:
    6. image: springboot_docker:1.0
    7. container_name: ms01 # 容器名称,如果不指定,会生成一个服务名加上前缀的容器名
    8. ports:
    9. - "6001:6001"
    10. volumes:
    11. - /app/microService:/data
    12. networks:
    13. - springboot_network
    14. depends_on: # 配置该容器服务所依赖的容器服务
    15. - redis
    16. - mysql
    17. redis:
    18. image: redis:6.0.8
    19. ports:
    20. - "6379:6379"
    21. volumes:
    22. - /app/redis/redis.conf:/etc/redis/redis.conf
    23. - /app/redis/data:data
    24. networks:
    25. - springboot_network
    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: 'db_springboot'
    33. MYSQL_USER: 'springboot'
    34. MYSQL_PASSWORD: 'springboot'
    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. - springboot_network
    43. command: --default-authentication-plugin=mysql_native_password # 解决外部无法访问
    44. networks:
    45. # 创建 springboot_network 网桥网络
    46. springboot_network:

    五、docker轻量级可视化工具Portainer

    5.1、是什么?

    Protainer是一款轻量级的应用,提供了图形化的界面,用于方便地管理Docker环境。

    5.2、安装与使用

    1、官网 https://www.portainer.io/

    2、Resources → install →  Community Edition → Set up a new Portainer CE Server installation
    → Docker Standalone → Install Portainer CE with Docker on Linux。

    进入此链接,对照着安装即可。  https://docs.portainer.io/start/install-ce/server/docker/linux

    (1)First, create the volume that Portainer Server will use to store its database:

    docker volume create portainer_data

    (2)Then, download and install the Portainer Server container:

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

    注:如果是云服务器记得在安全组规则上放开9443/8000端口。
    注:--restart=always 的意思是,如果整个docker重启了,此容器也跟着重启。

    (3)检查是否起来了

    docker ps

    (4)连接portainer的web服务器(ip为宿主机外网ip)
    https://118.xx.xx.69:9443    #浏览器直接输入

    首次进入的话会有一个初始化的过程,其实就是定义用户名密码,按操作就好。

    1. username: admin
    2. password: abcdefg123456

    (5)之后出现了如下提示,按提示我们重启portainer即可。
    “Your Portainer instance timed out for security purposes. To re-enable your Portainer instance, you will need to restart Portainer.”

    sudo docker restart portainer

    重新登陆后就进来后就可以看到如下界面。

    连接local后就可以看到当前宿主机的监控情况了,如下:

    注:其中“Stack”表示容器编排,其他各项就顾名思义了。

    六、docker容器监控CAdvisor+InflusDB+Granfana(CIG)

    6.1、原生命名 docker stats

    占了多少cpu、找了多少内存、网络io是多少? 说到这里肯定会立马想到之前介绍过的 docker stats命令。

    他可以方便的看到当前宿主机上的所有容器的cpu、内存及网络流量等数据。
    但是,docker stats统计的只是当前宿主机的全部容器,且数据资料没有落地存储、没有健康指标过线预警等功能。

    6.2、容器监控三剑客(CIG)

    一句话:CAdvisor监控收集 + InfluxDB存储数据 + Grafana展示图表

    1、CAdvisor: CAdvisor是一个容器资源监控工具,包括容器的内存,CPU,网络IO,磁盘IO等监控。但是它默认只存储2分钟的数据,而且只针对单物理机。不过CAdvisor提供了很多数据集成接口,支持Influxdb,
    redis,kafka,elasticsearch等集成,可以加上对应配置将监控数据发往这些数据库存储起来。
    总的来讲,CAdvisor收集信息很强。

    2、InfluxDB: 是一款基于go语言编写的分布式时序数据库。为了持久化存储数据和统一收集展示监控数据,
    需要将数据存储到Influxdb中。Influxdb是一个时序数据库,专门用于存储时序相关数据。而且CAdvisor本身
    提供了Influxdb的集成方法,启动容器时指定配置即可。

    3、Grafana: Grafana是一个开源的数据监控分析可视化平台。


    6.3、docker compose一键部署

    编写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)我们在influxdb中创建了一个数据库 cadvisor ,这个后面选数据源的时候会用到。

    (2)

    (3)

    执行部署命令

    docker compose up -d

    部署完了后分别进行测试。注:这三个软件都有对外暴露专门的图形化界面,这里分别看下。

    ①浏览CAdvisor收集服务,http://ip:8080
            注: 第一次比较慢,稍微等等。

    ②浏览Influxdb存储服务,http://ip:8083
            注:可以查询,创建数据库、删除数据库等。
    ③浏览grafana展现服务, http://ip:3000
            注:默认用户名(密码)是admin(admin),然后login更改密码为123456

    三个都ok后就可以继续了。。

    6.4、配置grafana

    6.4.1、配置数据源

    Configuration → DATA source → Add data source。

    可以看到支持很多数据库,我们这里就选择Influxdb作为数据源。进入配置先配置URL,如下:

    注: “http://InfluxDB:8086”这里是尽量用名字去调用,而不是写死ip(应该就是Name)。

    然后再 配置数据库、用户名(默认root)、密码(默认root),如下:

    点击 Save&test后出现如下绿色,就说明通了。

    6.4.2、创建仪表盘(dashboard)并添加面板(panel)

    首先创建仪表盘。  Create → Dashboard 

    然后添加面板。 → Add a new panel

    接下来进入如下页面。首选 选择监控样式(柱状图/折线图/指针图等)。  → Time series

    选择一个自己想要的,此处选了折线图 Graph(old)。

    注:选了之后在其下方“panel option”有诸多属性配置,试试就会用了。

    此处简单配置下这个面板(panel)的 Title、Description,如下:

    然后点击save,输入下dashboard的名字,面板就弄出来了,如下:

    可以看到此时并没有数据,接下来我们需要添加数据。

    6.4.3、为panel添加数据

    下箭头 → Edit

    如下图所示 大方框中就可以配置一个指标。如果有多个指标点击“+ Query”继续添加即可。

    接下重点看看如何配置一个具体的监控指标。

    (1)红框处:就是我们之前配置的数据源,没有任何问题;

    (2)蓝框处:选择具体哪张表(influxdb叫measurements),此处选择“memory_usage”;

    (3)绿框处:“memory_usage”这张表中具体字段即筛选值;

    (4)黄框处:给我的指标重新命令一下。

    注意1:蓝框处出现的选项其实就是选择那个数据库,influxdb中可以直接看到。

    注意2:选择 memory_usage 后后面的where条件的key-value值都是根据数据库中的字段来的。

    如下图。memory_usage表中有两个可选字段分别是 container_name 和 machine;后面具体的value也都是数据库中实际有的value。

    好了后,点击右上角 Apply即可。

    6.4.3、效果演示

    如下图配置了两个监控指标,分别监控influxdb、grafana、Cadvisor三个容器的内存使用情况。

    我们还可以在这个dashboard下继续添加panel,如下箭头所示。

    然后我又添加了一个cpu监控的panel,最终效果如下:

  • 相关阅读:
    第一个实例:QT实现汽车电子仪表盘
    win11自带矩形块截屏、录屏、视频编辑等功能
    SpringBoot整合RabbitMQ实现六种工作模式
    在CentOS7系统中安装MySQL5.7
    web打印页面加载数据耗时
    Java架构师常见基础面试题(附答案)
    java+ssm基于微信小程序的高校新生自助报到迎新系统 uniapp 小程序
    区间查找题解(优先队列+二分)
    扬州大学858程序设计与数据结构专业课(资料篇)
    《SpringCloud》系列文章目录
  • 原文地址:https://blog.csdn.net/mijichui2153/article/details/136487018