SRE运维笔记
SRE概念
SRE(sitereliabilityengineering).中文翻译为站点可靠性工程师.SRE概念中比较重要的特性在于:
1.engineer表示SRE是工程师,使用软件工程手段设计,研发和维护业务软件系统.
2.SRE的关注焦点在于可靠性,专注于软件系统架构设计,运维流程优化,让业务软件系统运行更可靠.
3.SRE主要工作是运维业务服务,
SRE团队职责:
- 可用性改进
- 延迟优化
- 性能优化
- 效率优化
- 变更管理
- 监控
- 紧急事务处理
- 容量规划与管理
本篇笔记重点学习Prometheus的relabel_config
.也就是标签的管理,包括标签过滤,自定义标签,动态替换标签等.
在Prometheus的官方文档有详细介绍:
https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
Prometheus中存储的数据为时间序列,是由Metric的名字和一系列的标签(键值对)唯一标识的, 不同的标签代表不同的时间序列,即 通过指定标签查询指定数据 。
Alertmanager还可以根据标签进行分组,将同一个标签的多个告警通知,打包成一条告警短信发送.
在Prometheus所有的Target实例中,都包含一些默认的Metadata标签信息。可以通过Prometheus UI的Targets页面中查看这些实例的Metadata标签的内容:
• address:当前Target实例的访问地址
• scheme:采集目标服务访问地址的HTTP Scheme,HTTP或者HTTPS
• metrics_path:采集目标服务访问地址的访问路径
一般来说元标签只是Prometheus内部使用,**我们一般不会让其做什么事情,并且这些标签是不会写到数据库当中的,使用promql是查询不到这些标签的.
容器其实是一种沙盒技术,顾名思义,沙盒就像是一个集装箱一样,把你的应用”装”起来.这样应用和应用之间就因为有了边界而不至于互相干扰.而被装进集装箱的应用,也可以被方便的搬来搬去.
容器的核心功能就是通过约束和修改进程的动态表现,从而为其创造出一个”边界”.对于Docker以及大多数的Linux容器来说.cgroup
是用来约束的手段,而Namespace
则是用来修改进程视图的主要方法
linux内核提拱了6种namespace隔离的系统调用,如下图所示,但是真正的容器还需要处理许多其他工作。
namespace | 系统调用参数 | 隔离内容 |
---|---|---|
UTS | CLONE_NEWUTS | 主机名或域名 |
IPC | CLONE_NEWIPC | 信号量、消息队列和共享内存 |
PID | CLONE_NEWPID | 进程编号 |
Network | CLONE_NEWNET | 网络设备、网络战、端口等 |
Mount | CLONE_NEWNS | 挂载点(文件系统) |
User | CLONE_NEWUSER | 用户组和用户组 |
实际上,linux内核实现namespace的主要目的,就是为了实现轻量级虚拟化技术服务。在同一个namespace下的进程合一感知彼此的变化,而对外界的进程一无所知。这样就可以让容器中的进程产生错觉,仿佛自己置身一个独立的系统环境中,以达到隔离的目的。
下面拿个简单例子来讲解部分Namespace技术
在上篇介绍完容器的”隔离”技术之后,我们再来研究一下容器的”限制”问题
也许你会好奇,我们不是已经通过 Linux Namespace 创建了一个“容器”吗,为什么还需要对容器做“限制”呢?
我还是以 PID Namespace 为例,来给你解释这个问题。
虽然容器的第一号进程只能看到容器里的情况,但是由于是直接运行在宿主机上,所以它和宿主机上其他所有进程之间依然是平等的竞争关系.这就意味着虽然该进程在视图上被隔离起来了,但是他能够使用宿主机上的所有资源(比如CPU,内存).
这显然不是一个”沙盒”应该表现出来的合理行为
而Linux Cgroups就是Linux内核中用来为进程设置资源限制的一个重要功能
而正如我前面所说的,Namespace 的作用是“隔离”,它让应用进程只能看到该 Namespace 内的“世界”;而 Cgroups 的作用是“限制”,它给这个“世界”围上了一圈看不见的墙。这么一折腾,进程就真的被“装”在了一个与世隔绝的房间里,而这些房间就是 PaaS 项目赖以生存的应用“沙盒”。
可是,还有一个问题不知道你有没有仔细思考过:这个房间四周虽然有了墙,但是如果容器进程低头一看地面,又是怎样一副景象呢?
换句话说,容器里的进程看到的文件系统又是什么样子的呢?
本文使用的是官方的mysqld_exporter.github地址:mysqld_exporter
mysql版本需要在5.6版本或以上
mysqld_exporter提供很多监控项(具体参考github项目介绍).如果需要开启一个监控项,在启动mysqld_exporter时,携带以下命令:
1 | --collect.key |
如果需要关闭某个监控项.携带以下命令:
1 | --no-collect.key |
如果mysqld_exporter的版本小于0.10.0,命令有些变化,双横杠变成单横杠,使用-collect.key 或者-collect.key=True|false
安装方式很简单,.下面是一个Ansible脚本以供参考
Pod是kubernetes项目中最小的API对象,是原子调度单位.我们之前学习过很多Linux容器,Docker方面的知识.那Kubernetes为什么不使用容器作为调度单位,而是要将容器封装成一个Pod?
要探讨这个问题,我们需要深入研究一下Kubernetes的设计思想和工作原理.
通过之前Docker的原理学习,我们知道容器的本质到底是什么? 容器的本质是进程.容器的镜像就像是这个进程的安装包.一键启动这个镜像,就相当于用这个安装包启动了一个进程(PID为1).那么Kubernetes呢?
Kubernetes就是操作系统! 负责所有容器的编排和管理
但是,在一个操作系统里,进程并不是孤苦伶仃的单独运行的,而是以进程组的方式,多个进程同时在一起运行.这些进程存在着”进程和进程组”的关系,他们之间有非常密切的写作关系,使得他们必须部署在同一台机器上.
由于受限于容器的”单进程模型”.一个进程组下的不同进程可能需要制作成多个不同的容器,而这多个容器在传统的调度工作中(比如像Docker Swarm,Mesos)都没有被妥善处理好,在进程组的调度上要么无法保障一个进程组的多个容器无法调度到同一个节点,要么调度的效率和性能的问题.
可在Kubernetes里,这个问题通过Pod完美解决了.Pod是kubernetes的原子调度单位,这就意味着Kubernetes是统一按照Pod而非单个容器的资源需求计算的.所以可以将多个容器部署在同一个Pod里,这些容器共享同一个Pod的网络名称,进程间通信,IP地址,共享卷等.而Kubernetes在调度时,会将他们作为一个整体,而非单个容器进程.
像这样容器间的紧密协作,我们可以称为“超亲密关系”。这些具有“超亲密关系”容器的典型特征包括但不限于:互相之间会发生直接的文件交换、使用 localhost 或者 Socket 文件进行本地通信、会发生非常频繁的远程调用、需要共享某些 Linux Namespace(比如,一个容器要加入另一个容器的 Network Namespace)等等。
Calico是一个非常流行的Kubernetes网络插件和解决方案.Calico是一个开源虚拟化网络方案,用于为云原生应用实现互联及策略控制。与Flannel相比,Calico的一个显著优势是对网络策略(network policy)的支持,它允许用户动态定义ACL规则控制进出容器的数据报文,实现为Pod间的通信按需施加安全策略。事实上,Calico可以整合进大多数主流的编排系统,如Kubernetes、Apache Mesos、Docker和OpenStack等。
Calico本身是一个三层的虚拟网络方案,它将每个节点都当作路由器(router),将每个节点的容器都当作是“节点路由器”的一个终端并为其分配一个IP地址,各节点路由器通过BGP(Border Gateway Protocol)学习生成路由规则,从而将不同节点上的容器连接起来。因此,Calico方案其实是一个纯三层的解决方案,通过每个节点协议栈的三层(网络层)确保容器之间的连通性,这摆脱了flannel host-gw类型的所有节点必须位于同一二层网络的限制,从而极大地扩展了网络规模和网络边界。
顾名思义,DaemonSet的主要作用是让你在kubernetes集群里运行一个Daemon Pod.所以,这个Pod有如下三个特征:
1.这个Pod运行在kubernetes集群的每一个节点(Node)上
2.每个节点只有一个这样的Pod实例
3.当有新的节点加入 Kubernetes 集群后,该 Pod 会自动地在新节点上被创建出来;而当旧节点被删除后,它上面的 Pod 也相应地会被回收掉.
这个机制听起来很简单,但 Daemon Pod 的意义确实是非常重要的。我随便给你列举几个例子:
Docker容器诞生以来,,如何确定合适的网络方案是亟待解决的难题之一.在日趋复杂的业务场景下,网络的复杂性也呈几何级数上升.本篇首先回顾了Docker容器的网络通信,然后介绍Kubernertes的网络模型.在Kubernetes集群中,IP地址的分配对象是以Pod为单位,而非容器.同一个Pod内的所有容器共享同一个网络名称空间