【初心者向け】AWS+Hubot+Slackで自動返信するBOTの作り方(後半)

AWS+Hubot+Slackを使ってBOTを作る方法(後半)を投稿します:)

前半はこちら
http://qiita.com/ShirakawaYoshimaru/items/dc79b9548a43f9c6fe9f

構成はこんな感じ
(前半)1.EC2サーバー作成のための下準備
(前半)2.EC2サーバーを立てる
(後半)3.SlackのBOT設定
(後半)4.EC2サーバーに入ってHubotを作る
(後半)5.Tips


間違いやアドバイス等があったら気軽にコメントください><
では始めて行きます 🙂

3.SlackのBOT設定

Slackに追加するBOTは、最初にSlackに登録し、チャンネルに招待する必要があります。

3-1.BOTをSlackチームに登録する

このurlを開いてくか、
https://slack.com/apps

もしくは、
Slackのチーム名をクリックして、メニューを開いて「Apps & integrations」をクリックしてください。
Slack 2016-04-15 10-59-33.jpg

ブラウザでこんな画面が開きます。
検索バーに「Hubot」を入力して検索しましょう。Hubot導入画面に遷移できます 🙂
App Directory | Slack 2016-04-15 11-05-07.jpg

Hubot導入画面でHubotをインストール(追加)したいチームを選択します。
Hubot | Slack 2016-04-15 11-12-41.jpg

チームの選択ができたら、まずはBotの名前を入力します。
Botの名前は小文字/数字/ドット/アンダーバー/スラッシュしか使えないので注意です。
(大文字は使えません)
Hubot | tech_salon Slack 2016-04-15 11-18-45.jpg

次の画面に行くと、Hubotの詳細設定ができるようになります。
BOTのICONはこの画面で変更できます。
ここに後で使う API TOKEN があるので必ずメモっておきましょう。
TOKENをメモったら、画面下部にある Save Integrationボタン を押してBot情報を保存します。 (Save Integrationボタンを選択しても画面は特に変わりません)
Hubot | tech_salon Slack 2016-04-15 11-24-08.jpg

3-2.BOTをチームのチャンネルに招待する

BOTをチャンネルに招待しましょう。
Slackに戻り、画面右上のメニューボタンを選択して Team Directory を選択します。
Slack 2016-04-15 11-37-25.jpg

Teamに入っているメンバー全員の一覧が見れます。先ほど追加したBOTを選択しましょう。
Slack 2016-04-15 11-38-43.jpg

BOTの詳細が見れます。下矢印?マークを選択し、 Invite to a channel を選択します。
Slack 2016-04-15 11-39-20.jpg

どこのチャンネルに招待するか選択しましょう。#randomや#generalでもいいのですが、BOTの動作テストをすることを考えると、#bot みたいなテスト用チャンネルを作成してそこに招待する方が良いでしょう。
ちなみに招待先を間違えると管理者権限がない限りremoveできないので注意してください。
僕は今回#botチャンネルを作ってそこに招待しました。
Inviteボタンを選択すれば招待完了です。
Slack 2016-04-15 11-41-18.jpg

先ほどのBOT設定画面にもどり、所属チャンネル一覧に招待したチャンネルが表示されていればokです。
(間違えて#randomに招待してしまったので、スクショでは#randomと#botの二つに所属していることになっています)
Hubot | tech_salon Slack 2016-04-15 12-00-05.jpg

4.EC2サーバーに入ってHubotを作る

ここまでくれば後は簡単です!
やることは
4-1.EC2にssh接続(ログイン)する
4-2.必要なものをinstallする
4-3.Hubot作成
4-4.Hubot実行
4-5.動作確認テスト
になります 🙂
ある程度のUnixコマンドの知識は必要ですが、基本コピペでも大丈夫です 🙂

4-1.EC2にssh接続(ログイン)する

EC2へのssh接続は割と簡単です。
前半でEC2サーバーを建てる時にダウンロードしたpemファイルを使用するので用意しておきましょう。

ssh接続はこのコマンドでできます。
pemファイルのパスは自分の環境に合わせて変えてください。
userNameはEC2サーバーの場合「ec2-user」が用意されているのでそれを使います。
ipアドレスも自分のEC2サーバーに合わせて用意してください。

ssh接続コマンド
$ ssh -i pemファイルのパス userName@ipアドレス

EC2サーバーのipアドレスを確認しましょう。
AWSにログインして、EC2管理画面から自分のEC2を選択し、 パブリックIP をメモりましょう。パブリックIPを使ってssh接続します。
EC2 Management Console 2016-04-15 12-17-30.jpg

pemファイルのアクセス権限の設定が弱いとssh接続ができないのでアクセス権限を変えます。
ちなみにファイルパスを手入力するのは大変です。Finderからターミナルにファイルをドラック&ドロップすると勝手にファイルパスが記入されるので是非使ってみてください。
pemファイルのアクセス権限を強くする
$ chmod 400 pemのファイルパス

僕の場合こんな感じになりました。
shirakawayoshimaru1 — bash — 120×24 2016-04-15 12-21-31.jpg

それではターミナルを使って実践していきます。

ssh接続コマンド
$ ssh -i pemファイルのパス userName@ipアドレス

僕の環境ではこうなりました。
shirakawayoshimaru1 — bash — 120×24 2016-04-15 12-24-17.jpg

初めて接続するipアドレスには「本当にここに接続していいの?」的な確認がでるのでyesと入力しましょう。
shirakawayoshimaru1 — ssh — 120×24 2016-04-15 12-24-57.jpg

無事ssh接続ができた場合は、こんな感じになります。
shirakawayoshimaru1 — ec2-user@ip-172-16-0-10:~ — ssh — 120×24 2016-04-15 12-28-55.jpg

4-2.必要なものをinstallする

nodesとreisとnpm をインストールしてください。
コマンドを入力したらいろいろ聞かれますが全てyを入力してください。

$ sudo yum install nodejs redis npm --enablerepo=epel

次にcoffee-scriptとhubをインストールしてください。
コマンドを入力したらいろいろ聞かれますが全てyを入力してください。

$ sudo npm install -g coffee-script hubot yo generator-hubot

これで必要なものは全てinstallすることができました。

4-3.Hubot作成

まずはHubotの作業フォルダを作成しましょう。
これで「QiitaMaruBotフォルダ」を作成してその中に入れます。

$ mkdir QiitaMaruBot
$ cd QiitaMaruBot/

次にHubotを作成します。
Hubotの作成は簡単でこれだけです。

$ yo hubo

Owner:適当に入力
Bot Name: 小文字のみ
Description: 適当に入力
Bot Adapter: slackと入力

次にHubotにToken(SlackのHubot管理画面にあったやつ)を設定します。
xoxb-34928263845-fhogehogehogehogheohgehogeの部分は自分のTokenに変えてください。

$ export HUBOT_SLACK_TOKEN=xoxb-34928263845-fhogehogehogehogheohgehoge

以上でHubotの作成になります。

4-4.Hubot実行

ここではEC2サーバーの中でHubotが正常に動作しているか確認します。
Hubotに対して「ping」というメッセージを送った時に「pong」と帰って来れば成功です。

まずはHubotを実行します。
(QiitaMaruBot/bin/hubotコマンドを実行しています。)

$ ./bin/hubot

まだHerokuの設定をしていないのでエラーがでますが、気にせずEnterを押せば大丈夫です。
こんな感じになればok
shirakawayoshimaru1 — ec2-user@ip-172-16-0-10:~:QiitaMaruBot — ssh — 120×24 2016-04-15 12-46-18.jpg

後は、こんな感じでqiitamarubotにメッセージを送ってpongが帰って来ればokです。
qiitamarubotの部分は自分がつけたBOTの名前に適宜変えてください

qiitamarubot> qiitamarubot ping

こんな風に
shirakawayoshimaru1 — ec2-user@ip-172-16-0-10:~:QiitaMaruBot — ssh — 120×24 2016-04-15 12-47-37.jpg

これでHubot実行は終わりです。

正常に動作していればexitコマンドを実行してHubotを停止させます。

qiitamarubot> exit

4-5.動作確認テスト

実際にSlackのチャンネルに反応して、SlackのチャンネルにBOTが投稿できるか確認します。
まずはHubotをSlackと接続するコマンドを実行します。

$ ./bin/hubot --adapter slack

実行後にSlackの画面に行って、BOTがオンラインになっていればおkです。
Slack 2016-04-15 12-54-16.jpg

後はBotを招待したチャンネルに行って、「qiitamarubot ping」と打って「pong」が帰って来れば成功です。
Slack 2016-04-15 12-56-13.jpg

楽しいw

動作確認テストは以上になります。

5.Tips

Tipsでは、
5-1.ssh接続を終了した後でもBOTをオンラインにする方法
5-2.BOTを停止させる方法
を書きます。

5-1.ssh接続を終了した後でもBOTをオンラインにする方法

普通に./bin/hubot --adapter slackコマンドを打っただけだとssh接続を終了するときにBOTも終了してしまいます。
これではBOTとして不十分なのでssh接続を終了してもBOTタスクが実行され続けるようバックグラウンドでhubotを実行しましょう。
やり方は簡単で

$ nohup ./bin/hubot --adapter slack &

このコマンドを実行するだけです。
nohupと&をつけることでバックグラウンドでhubotが実行されます。

5-2.BOTを停止させる方法

nohupコマンドで実行したプロセスは明示的に終了させる必要があります。
やり方は簡単で、
1:プロセスのIDを調べる
2:プロセスをkillする
です。

まずはプロセスのIDを調べましょう。

$ ps aux | grep hubot

これで調べることができます。grepでhubotに関するプロセスのみを出力させます。

shirakawayoshimaru1 — ec2-user@ip-172-16-0-10:~:QiitaMaruBot — ssh — 112×24 2016-04-15 13-06-15.jpg
2つくらいプロセスがあると思うのですが、--adapter slackが付いている方のプロセスIDをメモります。

次にプロセスをkillさせます。

$ kill プロセスID

でkillできます。

これを実行することでhubotを停止させることができます。

以上!お疲れさまでした!!

参考url

yoでhubot作成時のエラーの対処

hubot構築に伴い、環境は AWS EC2 Amazon linux を選択しました。

構築は、下部の参考サイトにある通り、Amazon linuxの場合は、順々にインストールを進められました。

#mkdir ichigo
#cd ichigo
#yo hubot

が、yo hubot で下記エラーになりました。

Native thread-sleep not available.
This will result in much slower performance, but it will still work.
You should re-install spawn-sync or upgrade to the lastest version of node if possible.
Check /usr/lib/node_modules/yo/node_modules/yeoman-environment/node_modules/inquirer/node_modules/external-editor/node_modules/spawn-sync/error.log for more details
Native thread-sleep not available.
This will result in much slower performance, but it will still work.
You should re-install spawn-sync or upgrade to the lastest version of node if possible.
Check /usr/lib/node_modules/yo/node_modules/tabtab/node_modules/inquirer/node_modules/external-editor/node_modules/spawn-sync/error.log for more details

Error: EACCES, permission denied '/root/.config'
    at Object.fs.mkdirSync (fs.js:654:18)
    at sync (/usr/lib/node_modules/yo/node_modules/configstore/node_modules/mkdirp/index.js:71:13)
    at Function.sync (/usr/lib/node_modules/yo/node_modules/configstore/node_modules/mkdirp/index.js:77:24)
    at Object.create.all.get (/usr/lib/node_modules/yo/node_modules/configstore/index.js:38:13)
    at Object.Configstore (/usr/lib/node_modules/yo/node_modules/configstore/index.js:27:44)
    at new Insight (/usr/lib/node_modules/yo/node_modules/insight/lib/index.js:37:34)
    at Object.<anonymous> (/usr/lib/node_modules/yo/lib/cli.js:172:11)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)

エラーの原因は、rootユーザで行なっていた為でした。
ec2-user でやり直して、hubot構築完了となりました。
本来であれば、hubotユーザを作ってやるべきですね。

修改ios模拟器路径

As of Xcode 11 (released to beta to developers yesterday), we should locate the simulator runtimes located in /Volumes/*/Library/Developer/CoreSimulator/Profiles/Runtimes

I suggest you move them to that location on your spare drive. Doing so while CoreSimulatorService is running will probably confuse its state because we don’t currently handle runtimes vanishing from the root filesystem (we do handle them disappearing due to a disk eject through), so you will probably need to SIGKILL CoreSimulatorService after doing the move by running:

sudo killall -9 com.apple.CoreSimulator.CoreSimulatorService 2> /dev/null

If you don’t want to wait for Xcode 11, you can also just create a symlink from /Library/Developer/CoreSimulator/Profiles to /Volumes/MyHDD/Library/Developer/CoreSimulator/Profiles.

zabbix to 飞书

以下是我的操作:

在 zabbix 所在服务器,安装python依赖

yum install python-pip  # 已经有了python2.7.5
pip install --upgrade pip

pip install urllib3
pip install requests

找到 zabbix 脚本目录,我的在 /usr/lib/zabbix/alertscripts

添加文件,feishu_send.py  (得益于开发同事写好了接口url,我只要按要求传递消息体就可以了, 这里传了工号和内容)

 

 

 

python 版本:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import requests
import json
import sys
import os

headers = {'Content-Type': 'application/json;charset=utf-8'}

api_url = "http://192.168.33.21:8099/api/feishu/send"

def msg(emp_no, text):
    json_text= {
    "employee_no":emp_no,
    "msg_type": "text",
    "content": {"text": text}
    }

    print(requests.post(api_url,json.dumps(json_text),headers=headers).content)


if __name__ == '__main__':
   emp_no = sys.argv[1]
   text = sys.argv[2]
   msg(emp_no, text)

 

或者使用 curl 版本: (其实就是curl 命令,拼了2个位置参数)

#!/bin/bash

curl http://192.168.33.21:8099/api/feishu/send -X POST -d '{"employee_no":"'$1'","msg_type":"text","content":{"text":"'$2'"}}' --header "Content-Type: application/json"

 

保存文件,并给予执行权限 chmod 755 feishu_send.py

手动执行测试一下: ./feishu_send.py 11220033 testtext

执行成功,飞书收到消息。

接下来,配置zabbix, 先添加,报警媒介类型,使用上面的脚本,并填好参数(是zabbix中的参数)

 

 

给用户添加报警媒介。管理,用户,点击一个用户,报警媒介,添加。类型选上图创建的,收件上则对应上图的第一个参数(这里是工号)

 

 

由于报警可能要发给几个人,所以创建个用户群组。把用户添加进来即可。

 

 

接下来添加动作。 配置,动作,事件源里选触发器,创建动作。   填写名称,新的触发条件选触发器名称,然后点击操作:

 

 

在操作界面,其它不用改。点一下操作栏,新的,

 

操作细节,如下图,最后点添加。

 

 

之后的 恢复操作,更新操作  这2项,依照上面的同样设置即可。最后点击更新。

 

 

最后,测试一下,让 zabbix 监控的对象出个错误,看飞书能否收到消息。

 

CoreDNS 简单介绍

 

1、CoreDNS 简介

CoreDNS作为CNCF中托管的一个域名发现的项目,原生集成Kubernetes,它的目标是成为云原生的DNS服务器和服务发现的参考解决方案。所以,CoreDNS走的也是Traefik的路子,降维打击SkyDNS。

从Kubernetes 1.12开始,CoreDNS就成了Kubernetes的默认DNS服务器,但 kubeadm默认安装CoreDNS的时间要更早。在Kuberentes 1.9版本中,使用 kubeadm方式安装的集群可以通过以下命令直接安装CoreDNS。

# kubeadm init --feature-gates=CoreDNS=true

下面,我们将详细解释CoreDNS的架构设计和基本用法。

从功能角度看,CoreDNS更像是一个通用的DNS方案,通过插件模式极大地扩展自身功能,从而适用于不同的场景
正如CoreDNS官方博客描述的那样:

CoreDNS is powered by plugins.

CoreDNS有以下3个特点。

  • 插件化(Plugins)。基于Caddy服务器框架,CoreDNS实现了一个插件链的架构,将大量应用端的逻辑抽象成插件的形式(例如,Kubernetes的DNS服务发现、Prometheus监控等)暴露给使用者。CoreDNS以预配置的方式将不同的插件串成一条链,按序执行插件链上的逻辑。在编译层面,用户选择需要的插件编译到最终的可执行文件中,使得运行效率更高。CoreDNS采用Go语音编写,所以从代码层面来看,每个插件其实都只实现了CoreDNS定义的接口的组件而已。第三方开发者只要按照CoreDNS Plugin API编写自定义插件,就可以很方便地集成到CoreDNS中。
  • 配置简单化。引入表达力更强的DSL,即Corefile形式的配置文件(也是基于Caddy框架开发的)。
  • 一体化的解决方案。区别于Kube-dns“三合一”的架构,CoreDNS编译出来就是一个单独的可执行文件,内置了缓存、后端存储管理和健康检查等功能,无须第三方组件辅助实现其他功能,从而使部署更方便,内存管理更安全。

2、Corefile 知多少

Corefile是CoreDNS的配置文件(源于Caddy框架的配置文件Caddyfile),它定义了:

  • DNS server以什么协议监听在哪个端口(可以同时定义多个server监听不同端口);
  • DNS负责哪个zone的权威(authoritative)DNS解析;
  • DNS server将加载哪些插件。

通常,一个典型的Corefile格式如下:

ZONE:[PORT] {
[PLUGIN] ...
}
• ZONE:定义DNS server负责的zone,PORT是可选项,默认为53;
• PLUGIN:定义DNS server要加载的插件,每个插件可以有多个参数。

例如:

{
chaos CoreDNS-001
}

上述配置文件表达的是:DNS server负责根域 . 的解析,其中插件是chaos且没有参数。

image
image
image

 

3、插件工作模式

当CoreDNS启动后,它将根据配置文件启动不同的DNS server,每个DNS server都拥有自己的插件链。当新来一个DNS请求时,它将依次经历以下3步逻辑:

image

 

CoreDNS 请求处理工作流

下面将以一个实际的 Corefile为例,详解CoreDNS处理DNS请求的工作流。
Corefile如下所示:


coredns.io:5300 {
file /etc/coredns/zones/coredns.io.db
}
example.io:53 {
errors
log
file /etc/coredns/zones/example.io.db
}
example.net:53 {
file /etc/coredns/zones/example.net.db
}
.:53 {
errors
log
health
rewrite name foo.example.com foo.default.svc.cluster.local
}

通过配置文件不难看出,我们定义了两个DNS server(尽管有4个配置块),分别监听5300和53端口。将以上Corefile翻译成处理逻辑图:

image
image

 

4、总结

无论是Kube-dns还是CoreDNS,基本原理都是利用watch Kubernetes的Service和Pod,生成DNS记录,然后通过重新配置Kubelet的DNS选项让新启动的Pod使用Kube-dns或CoreDNS提供的Kubernetes集群内域名解析服务

5. CoreDNS 提供的插件

如,k8s插件地址:https://github.com/coredns/coredns/tree/master/plugin/kubernetes

下面的文献里,有使用指南
http://ju.outofmemory.cn/entry/363914

 

Kubernetes工作负载监控:Sidecar模式

Kubernetes彻底改变了构建基础架构的方式,加快了部署速度,并使我们能够复制和扩展微服务架构。但是,Kubernetes在应用可见性和监控功能方面,却面临一系列新的挑战。

在这篇文章中,我通过回顾Sensu首席执行官Caleb Hailey在CNCF的讨论,如:一些现有的和流行的Kubernetes监控模式(例如Prometheus),以及为什么传统方法在云原生世界中的不足。除此之外,我还将介绍用于监控Kubernetes上的工作负载的当前最佳实践–sidecar模式。

容器:现状

长期以来,我们一直依靠微服务,实现在云中更快,更可靠地交付软件。容器化是微服务发展过程中自然而然的下一步,它与Kubernetes一起进行容器编排,迫使我们重新考虑如何部署和监控应用程序。

尽管Kubernetes是一个功能强大的平台,可用于在任何地方运行应用程序,但这种功能带来了更多的复杂性。

Kubernetes监控:挑战和数据来源

采用Kubernetes意味着要争夺各种各样的数据源。这些数据源都是抽象的,因此要了解系统的运行状况和性能,你需要访问堆栈中的监控数据。

Sensu首席技术官Sean Porter 之前在一篇文章中详细概述了数据源。简而言之,你需要能够从四个主要来源收集数据:

  1. 运行Kubelet的Kubernetes主机,从这些主机中获取数据的最常见方法是使用 Prometheus node exporter ,该程序从Kubernetes主机上抓取数据并在通过HTTP方式暴露。
  2. Kubernetes process即Kubelet metrics,这些提供了有关Kubernetes节点及其运行 jobs 的详细信息。
  3. Kubelet的内置cAdvisor,跟踪正在运行的容器的资源使用情况。
  4. Kube-state-metrics, Kubernetes集群级别的全局视图

Kubernetes的动态特性,要求一种动态的监控方法–并可以应对大量的分布式应用程序和临时基础设施。

Kubernetes监控策略

监控策略概括如下:

  • 远程轮询 -轮询设备并报告其健康状况的传统服务检查方法。
  • 基于节点(每个主机的代理) -监控代理位于Kubernetes主机上,或者在Kubernetes集群内部以DaemonSet进行部署,以获得对系统资源信息的访问。
  • Sidecar(每个Pod的代理) -用于监控Kubernetes系统及其正在运行的工作负载。
  • 日志和APM-日志数据和应用程序性能的管理。

考虑到这些可观察性方法,让我们仔细研究监控Kubernetes的一种更传统的方法:使用Prometheus。

Kubernetes:Prometheus监控

有篇很不错的文章—Prometheus成为Kubernetes出色的基于遥测的监控伴侣的方法

使用Prometheus监控有个好处,就是开发人员不用修改他们的deployment的yaml文件。

但是,如果你需要服务的功能运行状况检查,Prometheus则无法反映“是否健康?”。

更全面的监控方法:Sidecar模式

Kubernetes监控的 sidecar 模式是一种更具动态性的方法。Sidecar作为一种模式并不是Kubernetes的正式约定,但是随着Kubernetes的发展,Sidecar也越来越普及。

Kubernetes的Sidecar示例包括:

  • 服务网格
  • 使用作为sidecar运行的代理,来记录平台的日志
  • 监控解决方案(例如Sensu),他们以sidecar方式运行代理,可以为每个服务一对一地配对监控代理。

当你使用sidecar模式时,你的Kubernetes pod将运行应用程序的容器与运行Sensu代理的容器保持在一起。这些容器共享相同的网络空间,因此你的应用程序可以与Sensu通信,它们就像在同一容器或主机中运行一样。

Sidecar具有和微服务在云原生环境中相同的优势,如:

  • 模块化的
  • 可组合
  • 可重用

演示:Sidecar方式监控应用程序

在本教程中,我们将使用Kubectl在Kubernetes中部署应用程序(NGINX网站)。在演示的第二部分中,我们将展示如何监控已部署的应用程序。

如果你想再本地使用演示,则需要安装Kubernetes(可以通过Minikube工具在本地运行Kubernetes)并将Sensu部署到Kubernetes中

完整示例: https://github.com/calebhailey/monitoring-k8s-workloads

在kubernetes中部署Sensu,请参考 https://github.com/sensu/sensu-kube-demo

首先,使用kubectl apply命令部署NGINX部署:

nginx-deployment.yaml

---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  ports:
    - name: http
      protocol: TCP
      port: 8000
      targetPort: 80
  type: LoadBalancer

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  minReadySeconds: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - protocol: TCP
          containerPort: 80

部署

$ kubectl create namespace webinar
$ kubectl --namespace webinar apply -f kubernetes/nginx-deployment.yaml
$ kubectl --namespace webinar get services
NAME    TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
nginx   LoadBalancer   10.27.251.183   35.230.122.31   8000:30161/TCP   33d

NGINX容器默认在80端口上运行。我通过8000端口暴露了它。

现在,在浏览器中输入http://35.230.122.31:8000访问你的NGINX应用程序。

你已经在Kubernetes中部署了应用程序或服务,但是如何找出监控它的最佳方法。

让我们看看如何将Sensu Go代理作为 sidecar 添加到你的应用程序中。(这适用于所有Kubernetes控制器: deployments ,Statefulsets,DaemonSet等)。

nginx-deployment-with-sensu-sidecar.yaml

---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  ports:
    - name: http
      protocol: TCP
      port: 8000
      targetPort: 80
  type: LoadBalancer

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  minReadySeconds: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - protocol: TCP
          containerPort: 80
      - name: sensu-agent
        image: sensu/sensu:5.11.1
        command: ["/opt/sensu/bin/sensu-agent", "start", "--log-level=debug", "--insecure-skip-tls-verify", "--keepalive-interval=5", "--keepalive-timeout=10"]
        env:
        - name: SENSU_BACKEND_URL
          value: wss://sensu-backend-0.sensu.sensu-system.svc.cluster.local:8081 wss://sensu-backend-1.sensu.sensu-system.svc.cluster.local:8081 wss://sensu-backend-2.sensu.sensu-system.svc.cluster.local:8081
        - name: SENSU_NAMESPACE
          value: webinar
        - name: SENSU_SUBSCRIPTIONS
          value: linux kubernetes nginx
        - name: SENSU_DEREGISTER
          value: "true"
        - name: SENSU_STATSD_EVENT_HANDLERS
          value: statsd

使用kubectl apply以下命令更新你的deployment:

$ kubectl --namespace webinar apply -f 
kubernetes/nginx-deployment-with-sensu-sidecar.yaml

访问Sensu面板,将看到Sensu自动注册Sidecar。(Sensu还会自动注销节点,因此你可以分辨出发生故障的节点与已取消配置的节点之间的区别。)

Kubernetes中deployment 的.spec.template.spec.containers:

- name: sensu-agent
  image: sensu/sensu:5.11.1
  command: ["/opt/sensu/bin/sensu-agent", "start", "--log-level=debug", "--insecure-skip-tls-verify", "--keepalive-interval=5", "--keepalive-timeout=10"]
  env:
  - name: SENSU_BACKEND_URL
    value: wss://sensu-backend-0.sensu.sensu-system.svc.cluster.local:8081 wss://sensu-backend-1.sensu.sensu-system.svc.cluster.local:8081 wss://sensu-backend-2.sensu.sensu-system.svc.cluster.local:8081
  - name: SENSU_NAMESPACE
    value: webinar
  - name: SENSU_SUBSCRIPTIONS
    value: linux kubernetes nginx
  - name: SENSU_DEREGISTER
    value: "true"
  - name: SENSU_STATSD_EVENT_HANDLERS
    value: statsd

现在已经有了此配置,你可以轻松扩展资源。

$ kubectl --namespace webinar scale deployment nginx --replicas 10

在配置监控检查之前,我们有必要了解下有关Sensu的体系结构以及服务如何通信的背景知识。

Sensu代理以pub-sub模型与Sensu后端进行通信,并且该代理仅要求出站网络访问,因此我们不必打开代理中或Pod上的端口即可访问它们。

代理在Sensu Go中具有TLS加密的Web套接字,它们与Sensu后端保持此连接,并内置支持高可用性。

当代理连接时,它会自我描述其角色。如果是 sidecar ,它说:“我在Kubernetes上,我是Docker容器,我的角色是nginx服务。” 代理通过订阅收集数据。Sensu支持各种插件,如:Nagios插件,本地StatsD套接字Prometheus endpoints等等。

在本教程中,我们将使用Nagios check_http插件配置一个简单的检查。

首先,你需要提供Sensu配置,其中包括四个主要属性: resource type, API version, metadata, 和spec 。这些将在控制平面中注册,并与监控检查配置关联。

例如,这是Sensu中的监控检查,其中包含注册该检查所需的插件:

输出的格式为nagios_perfdata,并将其写入InfluxDB。

让我们配置监控检查:

$ sensuctl --namespace webinar create -f sensu/checks/check-nginx.yaml

你会看到该配置出现在Sensu仪表板中,可以在需要的地方对其进行编辑,并且该配置将在所有三个Kubernetes Pod上自动执行。

这是你的服务检查结果:

通过Sensu的监控事件管道,最终我们可以再面板上看到这些数据。

你可以在Sensu中配置InfluxDB处理程序,以将数据从其Nagios格式转换为InfluxDB格式,以便可以将其写入InfluxDB,并且可以开始在Granfana仪表板上查看指标。

以下是配置遥测管道(InfluxDB处理程序)的方法:

sensu/handlers/influxdb.yaml

---
type: Asset
api_version: core/v2
metadata:
  name: monitoring-plugins-alpine
spec:
  url: https://github.com/calebhailey/sensu-assets-monitoring-plugins/releases/download/2.2.0/monitoring-plugins-alpine_2.2.0_linux_amd64.tar.gz
  sha512: 81f7d411bd4ed4234dc54cd9218e808130a0a7db93d8ea998aa6ce74dc847bbd87ffa232c70bf4b066eb96ff3e6cb3ea0ddab1f593050b5c0bdb83f4eb36a6b2
  filters:
  - entity.system.os == 'linux'
  - entity.system.arch == 'amd64'
  - entity.system.platform == 'alpine'

---
type: Asset
api_version: core/v2
metadata:
  name: monitoring-plugins-centos
spec:
  url: https://github.com/calebhailey/sensu-assets-monitoring-plugins/releases/download/2.2.0/monitoring-plugins-centos_2.2.0_linux_amd64.tar.gz
  sha512: 0131ffea75099b2140b2d11da576c5b601d99eb7661a8105cadd884e5d953f215d23386a84ed871aabfe6a5751ce11443278be6ab510c8feab478b0365b329f0
  filters:
  - entity.system.os == 'linux'
  - entity.system.arch == 'amd64'
  - entity.system.platform == 'centos'

---
type: Asset
api_version: core/v2
metadata:
  name: monitoring-plugins-debian
spec:
  url: https://github.com/calebhailey/sensu-assets-monitoring-plugins/releases/download/2.2.0/monitoring-plugins-debian_2.2.0_linux_amd64.tar.gz
  sha512: 632366d0d55bd79762a71ef4e3209bcf6a499b6449ef6cb9471712e7799d3f6834ae7b3bafa1dfb00d4f358afed27971e7ed8b34d0424cdb31ec7a18aaf74b4f
  filters:
  - entity.system.os == 'linux'
  - entity.system.arch == 'amd64'
  - entity.system.platform == 'debian'

---
type: CheckConfig
api_version: core/v2
metadata:
  name: check-nginx
spec:
  command: check_http -H 127.0.0.1 -N
  publish: true
  interval: 10
  subscriptions:
  - nginx
  runtime_assets:
  - monitoring-plugins-alpine
  - monitoring-plugins-centos
  - monitoring-plugins-debian
  timeout: 10
  output_metric_format: nagios_perfdata
  output_metric_handlers:
  - influxdb

部署

$ sensuctl --namespace webinar create -f sensu/handlers/influxdb.yaml

你可以在GitHub中重新查看这些配置。

最后

现在,你已经建立了一个简单的管道,该管道可以通过Sidecar模式从Kubernetes收集指标,并且能够将数据发送到Grafana进行可视化。

如果你想了解有关InfluxDB处理程序(或可与Sensu Go一起使用的任何其他处理程序,包括PagerDuty,ElasticSearch,Splunk等的处理程序)的更多信息,请访问Sensai社区的开源目录Bonsai

如何优雅的退出/关闭/重启gunicorn进程

在工作中,会发现gunicorn启动的web服务,无论怎么使用kill -9 进程号都是无法杀死gunicorn,经过我一番百度和谷歌,发现想要删除gunicorn进程其实很简单。

1. 寻找masterpid

通过执行如下命令,可以获取Gunicorn进程树:
pstree -ap|grep gunicorn

得到如下的结果。

|-grep,6194 –col gunicorn | `-gunicorn,30080 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,4413 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,8030 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,8135 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,8137 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,11532 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,13460 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,19728 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,23585 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,23825 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,27921 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,28899 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,28900 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,28901 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,35637 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,36963 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,43074 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,43118 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,43232 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,43307 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,43308 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,44018 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,46996 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | |-gunicorn,47000 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py | `-gunicorn,47650 /usr/local/bin/gunicorn collect:app -c collect_gunicorn.py

很显然,30080就是Gunicorn的主进程。

2. 重启Gunicorn任务

按照官方的推荐方法,很容易执行命令:

kill -HUP 30080

执行上述命令后,再次执行“pstree -ap|grep gunicorn”,我们很容易发现,除了主进程,其他的Gunicorn进程都已经销毁,并新建了进程(进程ID发生了变化)。

3. 退出Gunicorn任务

kill -9 30080