Month: 九月 2018

kubernetes 初探——部署集群

随着 docker cloud 的关闭,容器的编排工具之争似乎已经结束了,Docker Swarm 上算是完了,Kubernetes 笑到了最后。然而 k8s 的组件众多,因此部署起来也很麻烦。为此,网上有不少的网上有不少的部署教程和脚本,包括但不限于:

– kubesaz
– minikube
– kubespray
– rke
– kubernetes: the hard way

有的出于教学目的的单机版本,有的是可以在生产环境部署的版本。研究了一番,发现 rke 这个工具应该是最简单的了。不过 rke 还不太稳定,目前看来,kubespray 声明了可以在生产环境使用

本文基于 ubuntu 16.04. CentOS 上好多默认设置都需要修改,因此建议大家基于 Ubuntu 部署 k8s。

# 使用 kubespray 安装 k8s

(零) 假设我们要在三台机器上安装, 另外一台机器作为控制节点. 其中每台都作为工作节点, 两台作为 master 节点.

IP | 角色
————|———————–
10.4.17.165 | 控制节点, 不参与 k8s 集群
10.4.17.167 | master, node
10.4.17.168 | master, node
10.4.17.169 | node

(一) 下载 kubespray 安装包, 这里我们使用最新版(2018.10), 可能需要安装 python3, 如果没有安装的话

“`
VERSION=2.7.0

# download kubespray
wget https://github.com/kubernetes-incubator/kubespray/archive/v${VERSION}.tar.gz
tar xzf v${VERSION}.tar.gz

# install dependencies
pip3 install -r kubespray-${VERSION}/requirements.txt
“`

(二) 生成部署的 hosts.ini

kubespray 中有一个脚本叫做 inventory_builder 用来生成部署的 hosts.ini

“`
cd kubespray-v${VERSION}
cp -r inventory/sample inventory/mycluster
declare -a IPS=(10.4.17.167 10.4.17.168 10.4.17.169)
CONFIG_FILE=inventory/mycluster/hosts.ini python3 contrib/inventory_builder/inventory.py ${IPS[@]}
“`
生成之后, 可以查看生成的文件

“`
cat inventory/mycluster/host.ini

[k8s-cluster:children]
kube-master·▸ ·
kube-node·▸ ·

[all]
node1 ▸ ansible_host=10.4.17.167 ip=10.4.17.167
node2 ▸ ansible_host=10.4.17.168 ip=10.4.17.168
node3 ▸ ansible_host=10.4.17.169 ip=10.4.17.169

[kube-master]
node1·▸ ·
node2·▸ ·

[kube-node]
node1·▸ ·
node2·▸ ·
node3·▸ ·

[etcd]
node1·▸ ·
node2·▸ ·
node3·▸ ·

[calico-rr]

[vault]
node1·▸ ·
node2·▸ ·
node3·▸ ·
“`

(三) 修改一些配置

代理:

由于众所周知的原因, k8s 依赖的 gcr.io 在中国大陆范围内无法访问, 我们可以使用代理访问, 关于如何搭建代理超出了本文的范围.
假设我们的代理是 http://proxy.com:10086, 修改 `inventory/mycluster/group_vars/all/all.yml` 文件, 设置 http_proxy 和 https_proxy 两个变量.

下载 kubectl 到本机:

设置 kubectl_localhost 和 kubeconfig_localhost 两个变量为 true. 安装完成后会在本机安装 kubectl, 并且可以使用 inventory/mycluster/artifacts/admin.conf 使用 kubectl.

(四) 部署

这里我们需要使用 tiger 用户, 这个用户需要满足如下条件:

1. 可以无密码远程登录
2. 在远程主机上具有无密码 sudo 权限

“`
ansible-playbook -i inventory/mycluster/hosts.ini cluster.yml –become –user tiger -v
“`

大概过十几分钟就部署好了

(五) 验证

“`
cd inventory/mycluster/artifacts
./kubectl.sh get nodes

NAME STATUS ROLES AGE VERSION
node1 Ready master,node 1d v1.11.3
node2 Ready master,node 1d v1.11.3
node3 Ready node 1d v1.11.3
“`

参考:

1. [HN 上关于 Docker Cloud 关闭的讨论](https://news.ycombinator.com/item?id=16665130)
2. [使用Kubespray部署生产可用的Kubernetes集群](http://www.itmuch.com/docker/kubernetes-deploy-by-kubespray/)

requests cookies 为空的一个坑

有时候,requests 返回的 cookies 会为空,原因是链接发生了 301/302 跳转,而 cookies 是跟着第一个响应返回的,第二个响应没有返回 Set-Cookie header。所以直接读取 r.cookies 是空的,而在 session.cookies 中是有数据的。

解决方法是直接读 s.cookies。

“`
s = requests.Session()
r = s.get(‘http://httpbin.org/cookies/set?foo=bar’)
cookies = requests.utils.dict_from_cookiejar(s.cookies)
s.cookies.clear()
“`

不过需要注意的是如果在多线程环境中使用 session 需要注意锁的问题,建议把 session 设置成 thread local 的类型。

influxdb+grafana+telegraf 监控系统搭建

本文基于 ubuntu 18.04

# 要不要用 docker?

这是一个哲学问题,用不用其实都有各自的好处。不过在这里我倾向于不用。因为 influxdb
和 grafana 都有好多的状态,而且不是都可以写到 mysql 中的,所以既然还得 mount 出来,
何苦用 docker 呢?telegraf 需要采集系统的相关信息,更不适合放在 docker 里面。

– InfluxDB,开源的时间序列数据库
– Grafana,开源的数据可视化工具

# 搭建过程

## influxdb && telegraf

因为这两个都是一家的产品,所以安装步骤都是一样的。按照[官网](https://docs.influxdata.com/influxdb/v1.6/introduction/installation/)给的安装步骤,其实很简单的。

“`
curl -sL https://repos.influxdata.com/influxdb.key | sudo apt-key add –
source /etc/lsb-release
echo “deb https://repos.influxdata.com/${DISTRIB_ID,,} ${DISTRIB_CODENAME} stable” | sudo tee /etc/apt/sources.list.d/influxdb.list

sudo apt-get update && sudo apt-get install influxdb telegraf
sudo systemctl start influxdb telegraf
“`

我们暂时就不配置了,直接使用默认配置。可以通过 `systemctl status influxdb` 来查看状态

## grafana

同样参考[官网](http://docs.grafana.org/installation/debian/)的教程。

## 基本概念

Grafana 从数据源中读取数据, 数据源一般是时间序列数据库. their data can be mixed in a single panel.

Grafana 使用 `orginazations` and `users` to manage permissions.

A dashboard consists of rows, rows consist of panels. for each panel, there is a query editor to edit which data the panel should show.

# 参考

1. http://docs.grafana.org/guides/gettingstarted/
2. http://docs.grafana.org/guides/basic_concepts/

“`
VERSION=5.1.4
wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_${VERSION}_amd64.deb
apt-get install -y adduser libfontconfig
dpkg -i grafana_${VERSION}_amd64.deb

sudo /bin/systemctl daemon-reload
sudo /bin/systemctl enable grafana-server
sudo /bin/systemctl start grafana-server
“`

然后就 ok 啦,打开 http://ip:3000 就能访问 grafana 的界面了,默认用户名和密码是 admin。如果是在阿里云等云上面,注意要在安全组里面开一下 3000 端口。

# 配置

## 配置 telegraf 的插件

## 配置 grafana 的 datasource

未完待续

# 参考资料

1. https://blog.csdn.net/w958660278/article/details/80484486
2. https://juejin.im/post/5b4568c851882519790c72f3
3. https://grafana.com/dashboards/928

监控系统基本概念与选型

# 时序数据库

监控系统的基础是时序数据库

现代的监控系统一般都有如下几部分组成:

时序数据库 + 前端显示 + 报警系统 + 指标收集

一般需要实现的功能:

– 度量数据收集和可视化
– 收集尽可能多的性能和状态数据
– 图形化做有意义的展示
– 如果发现可疑问题,可以关联其他图表找到原因
– 错误检测
– 按需告警, 触发条件越宽松则告警应该越少
– 避免误报

从监控的层次划分的话,一般包含三层监控:

– 基础层: 主机的CPU,内存,网络及IO等
– 中间层: 应用运行的中间件层, Nginx, Tomcat, MySQL, Redis
– 应用层: 服务端及客户端性能数据,如API访问次数和响应时间等

现代的监控越来越关注应用层和其他层数据的整合能力, 具有快速找到系统瓶颈, 方便扩容或代码优化.

# 时序数据库的选择

监控数据往往都带有时间戳,其实就是一种典型时间序列数据,而这方面已经有很多专门的存储系统,如 opentsdb,influxdb,prometheus 等。相比 mysql 这样的传统数据库,这类系统在存储、查询上针对时间序列数据都做了特别的优化。

其中 opentsdb 基于 hadoop 生态系统,考虑到搭建的复杂度,暂时不考虑了。influxdb 和 prometheus 都是 Golang 编写的,直接一个二进制文件就可以运行。两者的区别有:

– prometheus 对于保存长时间的数据有一些问题,influxdb 似乎没有问题
– 另外 influxdb 可以直接写入,而 prometheus 是基于拉(pull)模式的,也就是说程序不能直接写入 prometheus,而是需要由 prometheus 去定期拉监控数据,太反人类了。
– influxdb 的查询类似 SQL,而 prometheus 的查询语法更加简洁,但是有学习成本,各有千秋吧

所以选用 influxdb了。

# 前端显示

唯一的标准自然是越漂亮越好,所以我们选择 grafana。

当然另一需要考虑的是编写查询界面不要过于复杂,这方面 grafana 只需要拖拽空间和勾勾选选就可以了,显然不成问题。

# 报警系统

grafan 自带了一些报警,但是只能根据阈值报警,显然不能满足我们的需求。我们这里选择了 bosun,是 Stack Overflow 开源的一款监控系统。通过简单的几个语句就可以编写复杂的报警条件。

# 指标收集

按照前面的分析,对于应用层,也就是我们自己的代码,可以随意地添加代码打点,这里不再赘述。对于系统的 metrics 的收集,可以使用 influxdb 公司钦定的 telegraf。telegraf 也有一些不同的插件,可以很好地支持 mysql、redis 等的监控数据收集。

# 参考

1. [Logs and Metrics and Graphs, Oh my!](https://grafana.com/blog/2016/01/05/logs-and-metrics-and-graphs-oh-my/)
2. [Prometheus 和 influxdb 对比](https://www.gaott.info/prometheus-vs-influxdb/)
3. [360基于Prometheus的在线服务监控实践](https://dbaplus.cn/news-72-1462-1.html)
4. [虎牙直播运维负责人张观石:基于时序数据库的直播业务监控实践](http://www.yunweipai.com/archives/20983.html)
5. [监控系统选型](http://xoyo.space/2017/04/new-monitor-architecture/)
6. [openTSDB/Bosun报警语法 介绍/学习笔记](https://blog.csdn.net/lslxdx/article/details/79454916)

为什么不使用 scrapy?

最近面了几家公司,每当我提到头条的爬虫都是自己写的时候,对方一个下意识的问题就是
“为什么不使用开源的 scrapy?”。实际上我在头条的 lead 就是 scrapy 的 contributor,
而他自己也不用自己的框架,显然说明 scrapy 不适合大型项目,那么具体问题在哪儿呢?
今天终于有时间了,详细写写这个问题。

# 爬虫并不需要一个框架

Web 服务器是一个爬虫可以抽象出来的是各种组件。而 scrapy 太简陋了,比如说去重,
直接用的是内存中的一个集合。如果要依赖 scrapy 写一个大型的爬虫,几乎每个组件都要
自己实现,那有何必用 scrapy 呢?

# scrapy 不是完整的爬虫框架

一个完整的爬虫至少需要两部分,fetcher 和 frontier。其中 fetcher 用于下载网页,而
frontier 用于调度。scrapy 重点实现的是 fetcher 部分,也就是下载部分。

# scrapy 依赖 twisted

这一点导致 scrapy 深入后曲线非常地陡峭,要想了解一些内部的机理,必须对 twisted
比较明了。而 twisted 正如它的名字一样,是非常扭曲的一些概念,虽然性能非常好,
但是要理解起来是要花上不少时间的。

# scrapy 适合的领域

scrapy 主要是和一次性地从指定的站点爬取一些数据

最重要的并不是你使用不使用 Scrapy,而是你不能为每一站点去单独写一个爬虫的脚本。代码的灵
活度实在太大了,对于没有足够经验的工程师来说,写出来的脚本可能很难维护。重点是要把主循环
掌握在爬虫平台的手中,而不是让每一个脚本都各行其是。

# 参考

1. [scrapy 源码解读](http://kaito-kidd.com/2016/11/01/scrapy-code-analyze-architecture/)