DevOps概要

DevOps的概念太过庞大,每个角色都有不同的理解。
对于码农来说就是CI/CD。
一边开发程序,一边进行代码仓库的编译,执行代码检测,自动,推送到测试及生产环境,自动流畅升级。同时结合根据版本动态负载均衡和注册中心的策略。打通这些环节。
Docker的轻量级,同时将代码和配置装入容器中,一次编译,到处运行,与环境无关。
Docker能够配合各种分布式网络框架实现最便捷的租户隔离,适合在多项目混杂开发的公司使用

Docker容器代码挂载机制

主流的方式分为静态导入和动态导入

静态导入

  • 编写Dockerfile
vim staticDockerfile
From docker.io/tomcat:8.5.73-jdk8-corretto
copy /usr/local/src/webapps  /usr/local/tomcat/webapps/hello/

该脚本说明把宿主机的/usr/local/src/webapps目录拷贝到镜像/usr/local/tomcat/webapps/hello/中

  • 构建镜像
    image.png

  • 启动镜像
    docker run -id -p 60013:8080 statictomcat:1.0

  • 验证结果
    1.进入容器内部查看
    image.png
    2.访问页面,可以直接访问到静态资源staticDockerfile
    image.png

  • 优势:
    一次编译到处执行,复合DevOps思想,无缝迁移

  • 劣势:
    生成镜像文件较大

动态导入

  • 编写Dockerfile
    RUN mkdir -p /usr/local/tomcat/webapps/mytest
    VOLUME /usr/local/tomcat/webapps/mytest
  • 构建镜像
    docker build -f dynamicDockerfile -t dynamictomcat:1.0 .
  • 启动镜像及验证
    image.png
  • 优势:
    镜像文件小,镜像和代码分离,每次部署只需要重新启动Docker
  • 劣势:
    不符合Docker哲学,不能做到无缝迁移

Docker与服务发现

Docker容器的生命周期短,IP地址经常变化,基于Docker容器在服务注册中心实现自发现,以及在负载均衡上实现服务自发现是较为重要的

  • Docker容器的IP地址都是动态获取的,这些IP地址往往是Docker内部虚拟网络的地址,在服务链条上不同网段的应用流畅通信会有一定的难度。

服务发现与注册中心

  • 服务发现
    让新的实例可以嵌入现有的应用环境中,不需要人为干预
  • 服务发现一般用全局可以访问的存储信息注册表来实现,存储当前正在运行的实例或者服务信息。为了使配置具有容错与扩展能力,这个工具会分布式地存储在基础设置中的多个宿主机上
  • 容器配置服务发现工具,可以查询预配置信息并调整
  • 服务注册信息以k-v形式持久化,采用HTTP协议交互
  • 服务上线后会通过服务发现工具来注册自身信息
  • 服务消费者上线后,负载均衡地与服务者交互
    不想写了。。。。看
    http://jtao.work/archives/fu-wu-zhu-ce-yu-fa-xian

Dockerfile

Docker的治理与Dockerfile分不开
官方的Dockerfile reference
https://docs.docker.com/engine/reference/builder/
image.png

Dockerfile的基本思想

  • 容器精简,无状态
    容器可以销毁或暂停,也可以构建出一个新的容器。
    相关DB型数据库则不适用,Oracle、Mysql、Redis、MQ这些中间件则不适合
  • 使用.Dockerignore文件
    添加.Dockerignore文件。减少image的build大小,避免无用文件编译进Docker镜像中
  • 使用多段构建
    在一个Dockerfile中编写多个FROM。
    避免编译A镜像之后,再根据A镜像编译B镜像
  • 避免安装非必要的软件包
    降低构建复杂度、软件依赖度、image大小,及build时间
  • 每个容器只能运行一个进程
    每个容器只安排一个进程,避免在一个容器中运行多个进程。如果一个容器中有多个进程,很难对容器中的一个进程进行横向扩展

Dockerfile的基本

  • FROM:定制的镜像都是基于 FROM 的镜像
    应该使用官方offical镜像。可以使用精简镜像alpline(只有5MB)、Debian作为baseimage,而不是一定要使用centOS
  • RUN:docker镜像image构建的时候执行后面跟着的命令行命令
    Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。
    为了保持Dockerfile的高可读性、易于理解、方便维护的特性,将多条命令用“\”连接起来。以 && 符号连接命令,这样执行后,只会创建 1 层镜像
FROM centos
RUN yum -y install wget \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
    && tar -xvf redis.tar.gz
  • CMD 在docker容器run之后执行
    1.CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖
    2.如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效
  • EXPOSE 端口
    定义容器监听连接者的端口,对于外部访问可使用docker run -p
  • ENV 设置环境变量
    在Dockerfile声明构建的容器中的环境变量
  • ADD、COPY 拷贝(建议使用COPY)
    功能类似,拷贝文件,ADD还支持URL和tar包。官方建议使用COPY
  • ENTRYPOINT
    类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
  • VOLUME
    挂载,用于导出数据库存储区域、配置文件存储区域,以及容器内部App创建的目录或文件
    在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点
  • WORKDIR 指定工作目录
    用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。
    最好使用绝对路径比较清晰

Dockerfile编写及集成

  • 基础的Dockerfile由架构组、运维负责编写
  • 每个应用的Dockerfile由项目组技术经理、高级研发负责编写
  • Dockerfile应该是程序的一部分,应该将其和代码一起存放在Git上的项目根目录下

Docker与日志

Docker运行轻便,但生命周期短,收集、查看、分析容器日志也十分重要

  • docker logs [OPTIONS] CONTAINER
    选项:
    --details显示提供给日志的额外细节
    -f,--follow跟踪日志输出
    --since string 显示自时间戳以来的日志
    -t,--timestamps显示时间戳
    image.png

容器外收集

将宿主机的目录挂在为容器的日志目录,在宿主机上收集。
把Volume卷轴挂载到宿主机磁盘,把日志写入该卷轴中,再使用Logstach读取进程。
https://www.elastic.co/cn/logstash/
image.png
需要考虑不同的Docker容器之间的log是否会覆盖

容器内收集

在每一个容器内运行一个日志收集服务(Logstash)
这样每个容器都需要运行Logstash,占用的服务资源较多

单独运行日志容器

单独用一个Docker容器运行日志服务,对每个容器打标签,抓取宿主机上所有容器的日志文件

网络收集

容器内应用将日志发送到日志中心并进行收集,例如Log4j利用TCP将日志发送到远端服务器。
网络带宽成本较高

Docker与监控

Docker容器本身对宿主机来说就是一个进程,传统运维手段对这种进程级别的监控很难做到自发现、自管理。

Zabbix

Zabbix的官网如下
https://www.zabbix.com/cn
image.png

  • 在每个容器总安装Zabbix Agent
    但这违反了Docker的单一职责的原则,同时,也会增加宿主机负担
  • 在宿主机安装Zabbix Agent
    在宿主机上安装Zabbix Agent通过Python脚本监控Docker容器,将数据反馈给Zabbix Server

Docker原生监控方案

  • Prometheus
    其也为开源的系统监控解决方案
    https://prometheus.io/
    image.png
    其与其他最主要的区别就是多维的数据模型,提供多种视图和仪表盘,支持垂直和水平组合
    通过docker-compse配置文件就可以建立全面监控的环境
  • docker stats命令
    Docker自带的检查容器资源消耗情况的基本命令行工具。
    如果没有限制容器内存,那么会显示宿主机总内存
docker stats [OPTIONS] [CONTAINER...]
  -a, --all             Show all containers (default shows just running)
      --format string   Pretty-print images using a Go template
      --help            Print usage
      --no-stream       Disable streaming stats and only pull the first resul

如下图所示
image.png

  • cAdvisor
    google发布的开源原生支持Docker,并可以开箱即用地支持其他非Docker容器,提供了运行时容器资源使用情况和性能特征的方法
    https://github.com/google/cadvisor
    执行下图中的命令并稍微修改下端口和版本
    image.png

Docker与CI/CD

落实在具体实现层面一般是指,用Git进行代码的持续提交,提交之后用Sonar进行代码持续检查,通过Jenkins实现代码的日编译,日编译之后打包成war包或jar包推送到构建仓库,由SaltStack自动化部署工具发布。
对于Docker而言,Docker下的CI/CD基本类似,不同点为:

  • Docker不打包而是打成镜像image
  • Docker轻量级可以在同一个环境下针对不同war包进行版本升级,编排得当可以一键启动一套环境,发布一整串关联镜像

Docker下的CI/CD=多租户+多环境+快速构建+快速部署

image.png

  • 编译
    根据相应的配置文件,编译代码打成jar或war包等
  • 构建
    使用Jenkins编译构建源码,打包生产Docker镜像
  • 编排
    根据编排策略,动态扩容和扩展各个服务节点
  • 部署
    根据服务启动顺序和拓扑图,在机器上部署服务
  • 配置
    将配置和代码分离,容器和配置无关,容器一次编译,到处运行

实现方案

Docker运维问题

  • VM级别调优在容器中实现难度大
  • 容器化部署复杂,排查问题成本高
  • 不完整隔离,共享内核不安全,调优难

这个家伙很懒,啥也没有留下😋