Связаться по:
vkarabedyants Telegram Viber

Блог о системном администрировании серверов и сайтов

Установка, настройка программного обеспечения Linux, Windows операционных систем

ChatOps. Начало работы

chatops

Что такое ChatOps?

ChatOps предоставляет контекст работы, который вы уже делаете, в разговорах, которые вы ведете

ChatOps по-прежнему остается свежим и необычным в мире DevOps, когда работа переходит в общий чат. Вы можете запускать команды непосредственно из чата, и все в чате могут видеть историю выполняемой команды, делать то же самое, взаимодействовать друг с другом и даже учиться. Информация и процесс принадлежат всей команде, это приносит много преимуществ.

Вы можете приступить к выполнению таких операций, как развертывание кода или серверов предоставления ресурсов из чата, просмотр графиков из инструментов мониторинга, отправка SMS, контроль ваших кластеров или просто запуск простых команд оболочки. ChatOps может представлять собой высокоуровневое представление вашего действительно сложного процесса CI / CD ,упрощая общение в чатом, например !deploy . Этот подход делает чудеса для повышения наглядности и уменьшения сложности в процессе развертываний.

Расширенные возможности ChatOps

StackStorm — это проект OpenSource, специально ориентированный на автоматизацию событий ChatOps.Платформа поддерживает множество инструментов DevOps, таких как управление конфигурацией, мониторинг, оповещение, графическое отображение и т. д., что позволяет вам управлять всем из одного центра управления.Это идеальный инструмент для ChatOps, предоставляющий возможность создавать и автоматизировать любые мыслимые рабочие процессы и управлять любыми наборами инструментов непосредственно из чата.

StackStorm имеет возможность интеграции с Ansible и множество расширенных функций ChatOps в версиях платформы 1.0 , 1.2 и 1.4, чтобы помочь вам в реальной работе, а не просто отображать забавные фотографии котенка из чата. Ниже я расскажу, как сделать ChatOps и Ansible возможным с помощью платформы StackStorm.

Кстати, StackStorm as Ansible является декларативным, написанным на Python и использующим YAML + Jinja.

План

В этом уроке мы собираемся сначала установить управляющую машину Ubuntu 14, которая будет обрабатывать нашу систему ChatOps. Затем настроим платформу StackStorm, включая пакет интеграции Ansible. Наконец, мы подключим систему с Slack и покажем некоторые простые, но реальные примеры использования Ansible непосредственно из чата интерактивным способом.

Итак, давайте начнем и убедитесь, что мы близки к технологической сингулярности , предоставив root доступ к ботам чата и позволяя им управлять нашими 100 + серверами и кластерами.

Шаг 0. Подготовьте Slack

Как уже говорилось, давайте использовать Slack.com для чата. Зарегистрируйтесь в Slack, если у вас ее еще нет. Включите интеграцию Hubot в настройках.

Hubot — бот-движок GitHub, созданный для ChatOps.


Как только вы закончите, у вас будет API-токен:

HUBOT_SLACK_TOKEN=xoxb-5187818172-I7wLh4oqzhAScwXZtPcHyxCu

Затем мы сконфигурируем всю платформу StackStorm, покажем некоторые полезные примеры, а также разрешим создавать собственные команды ChatOps.

Но подождите, есть простой способ!

Легенький режим!

Для тех, кто ленив (большинство DevOps), вот брандмауэр-репо, которое устанавливает все необходимые инструменты в простых сценариях, подготовив платформу для написания команд ChatOps в Slack chat: https://github.com/StackStorm/showcase-ansible-chatops

# replace with your token
export HUBOT_SLACK_TOKEN=xoxb-5187818172-I7wLh4oqzhAScwXZtPcHyxCu
git clone https://github.com/StackStorm/showcase-ansible-chatops.git
cd showcase-ansible-chatops

vagrant up

Для тех, кто интересуется деталями — перейдем к ручному режиму и идем дальше.

Шаг 1. Установите StackStorm

Это действительно так просто, одна команда:

curl -sSL https://stackstorm.com/packages/install.sh | sudo bash -- --user=demo --password=demo

Этот однострочный интерфейс предназначен только для демонстрационных целей, для развертывания prod вы должны использовать доступные ansible playbooks для установки st2.

Шаг 2. Установите Ansible Integration pack

Идея интеграции пакетов в StackStorm заключается в том, что они соединяют систему с внешними инструментами или службами. Нам нужен пакет Ansible:

st2 pack install ansible

Помимо пакета Ansible Integration , он устанавливает существующие двоичные файлы в Python virualenv, расположенный в /opt/stackstorm/virtualenvs/ansible/bin .

Шаг 3. Настройка ChatOps

Теперь вам нужно настроить файл /opt/stackstorm/chatops/st2chatops.env в соответствии с вашими потребностями. Для этого стоит взглянуть на все переменные, но сначала убедитесь, что вы редактируете следующие envs:

# Bot name
export HUBOT_NAME=stanley
export HUBOT_ALIAS='!'

# StackStorm API key
# Use: `st2 apikey create -k` to generate
# Replace with your key (!)
export ST2_API_KEY="123randomstring789"

# ST2 AUTH credentials
# Replace with your username/password (!)
export ST2_AUTH_USERNAME="demo"
export ST2_AUTH_PASSWORD="demo"

# Configure Hubot to use Slack
export HUBOT_ADAPTER="slack"

# Replace with your token (!)
export HUBOT_SLACK_TOKEN="xoxb-5187818172-I7wLh4oqzhAScwXZtPcHyxCu"
 Перезапустите st2chatops чтобы применить изменения, и все готово к работе:
sudo service st2chatops restart

Шаг 4. Первый ChatOps

На этом этапе вы должны увидеть Stanley bot  в чате. Пригласите его в свой канал Slack:

/invite @stanley

Получить список доступных команд:

!help

Бьюсь об заклад, вы полюбите shipit :

!ship it

После игры с существующими командами, давайте продолжим с чем-то серьезным.

Шаг 5. Создание собственных команд ChatOps

Одной из функций StackStorm является возможность создания псевдонимов команд, что упрощает работу с ChatOps. Вместо того, чтобы писать длинную команду, вы можете просто привязать ее к чему-то более дружественному и понятному, простому.

Давайте создадим собственный пакет StackStorm, который будет содержать все необходимые команды. Шаблон пакета StackStorm  псевдонимов aliases/ansible.yaml со следующим содержимым:

---
name: "chatops.ansible_local"
action_ref: "ansible.command_local"
description: "Run Ansible command on local machine"
formats:
  - display: "ansible <command>"
    representation:
      - "ansible {{ args }}"
result:
  format: |
    Ansible command `{{ execution.parameters.args }}` result: {~}
    {% if execution.result.stderr %}*Stdout:* {% endif %}
    ```{{ execution.result.stdout }}```
    {% if execution.result.stderr %}*Stderr:* ```{{ execution.result.stderr }}```{% endif %}
  extra:
    slack:
      color: "{% if execution.result.succeeded %}good{% else %}danger{% endif %}"
Теперь переместите ваши изменения в разветвленное репо GitHub, и вы сможете установить только что созданный пакет. Для этого уже существует псевдоним ChatOps:
!pack install https://github.com/armab/st2_chatops_aliases

Теперь мы можем запускать простую команду непосредственно из Slack chat:

!ansible "uname -a"

ansible chatops

Которая на низком уровне эквивалентена:

/opt/stackstorm/virtualenvs/ansible/bin/ansible all --connection=local --args='uname -a' --inventory-file='127.0.0.1,'

Но давайте рассмотрим более полезные примеры, демонстрирующие преимущества интерактивности ChatOps.

Пример №1: получить статус сервера

У Ansible есть простой модуль ping, который просто соединяется с указанными узлами и возвращает успех pong .Простой, но мощный пример, чтобы понять, состояние серверов прямо из чата в считанные секунды, без входа в терминал.

Чтобы сделать это, нам нужно создать еще одно action для нашего пакета, в котором выполняется реальные action alias команды и action alias которые является просто синтаксическим синонимами, Реализуем возможным в ChatOps:

!status 'web'

Действия actions/server_status.yaml :

---
name: server_status
description: Show server status by running ansible ping ad-hoc command
runner_type: local-shell-cmd
entry_point: ""
enabled: true
parameters:
  sudo:
    description: "Run command with sudo"
    type: boolean
    immutable: true
    default: true
  kwarg_op:
    immutable: true
  cmd:
    description: "Command to run"
    type: string
    immutable: true
    default: "/opt/stackstorm/virtualenvs/ansible/bin/ansible {{hosts}} --module-name=ping"
  hosts:
    description: "Ansible hosts to ping"
    type: string
    required: true

Псевдонимов действий aliases/server_status.yaml :

---
name: chatops.ansible_server_status
action_ref: st2_chatops_aliases.server_status
description: Show status for hosts (ansible ping module)
formats:
  - display: "status <hosts>"
    representation:
      - "status {{ hosts }}"
      - "ping {{ hosts }}"
result:
  format: |
    Here is your status for `{{ execution.parameters.hosts }}` host(s): {~}
    ```{{ execution.result.stdout }}```
  extra:
    slack:
      color: "{% if execution.result.succeeded %}good{% else %}danger{% endif %}"
      fields:
        - title: Alive
          value: "{{ execution.result.stdout|regex_replace('(?!SUCCESS).', '')|wordcount }}"
          short: true
        - title: Dead
          value: "{{ execution.result.stdout|regex_replace('(?!UNREACHABLE).', '')|wordcount }}"
          short: true
      footer: "{{ execution.id }}"
      footer_icon: "https://stackstorm.com/wp/wp-content/uploads/2015/01/favicon.png"

Убедитесь, что вы настроили хосты в файле Ansible inventory /etc/ansible/hosts .

После внесенных изменений не забудьте переустановить отредактированный пакет из чата (замените его на ваш репозиторий github):

!pack install https://github.com/armab/st2_chatops_aliases

Очень удобно, что вы можете сохранить всю конфигурацию команды ChatOps в удаленном репо, как пакет StackStorm, и перезагрузить его после редактирования.

Давайте получим статус сервера:
статус сервера в chatops
Это действительно мощно, любой может запустить без доступа к серверу! При таком подходе сотрудничество, деплой и работу вокруг инфраструктуры можно выполнять из любого места в чате: находитесь ли вы в офисе или работаете удаленно (некоторые из нас могут работать непосредственно с пляжа).

Пример №2: перезапустить службы

У вас были ситуации, когда простой перезапуск службы может решить проблему? Не идеальный способ фиксации сбоя, но иногда вам просто нужно быстро решить проблему. Давайте напишем команду ChatOps, которая перезапускает определенные службы на определенных хостах.

Мы хотим сделать что-то вроде этого:

!service restart "rabbitmq-server" on "mq"

В ранее созданных пакетах StackStorm добавим actions/service_restart.yaml :

---
name: service_restart
description: Restart service on remote hosts
runner_type: local-shell-cmd
entry_point: ""
enabled: true
parameters:
  sudo:
    description: "Run command with sudo"
    type: boolean
    immutable: true
    default: true
  kwarg_op:
    immutable: true
  cmd:
    description: "Command to run"
    type: string
    immutable: true
    default: "/opt/stackstorm/virtualenvs/ansible/bin/ansible {{hosts}} --become --module-name=service --args='name={{service_name}} state=restarted'"
  hosts:
    description: "Ansible hosts"
    type: string
    required: true
  service_name:
    description: "Service to restart"
    type: string
    required: true
Псевдоним для ChatOps: aliases/service_restart.yaml :
---
name: chatops.ansible_service_restart
action_ref: st2_chatops_aliases.service_restart
description: Restart service on remote hosts
formats:
  - display: "service restart <service_name> on <hosts>"
    representation:
      - "service restart {{ service_name }} on {{ hosts }}"
result:
  format: |
    Service restart `{{ execution.parameters.service_name }}` on `{{ execution.parameters.hosts }}` host(s): {~}
    {% if execution.result.stderr %}
    *Exit Status*: `{{ execution.result.return_code }}`
    *Stderr:* ```{{ execution.result.stderr }}```
    *Stdout:*
    {% endif %}
    ```{{ execution.result.stdout }}```
  extra:
    slack:
      color: "{% if execution.result.succeeded %}good{% else %}danger{% endif %}"
      fields:
        - title: Restarted
          value: "{{ execution.result.stdout|regex_replace('(?!SUCCESS).', '')|wordcount }}"
          short: true
        - title: Failed
          value: "{{ execution.result.stdout|regex_replace('(?!(FAILED|UNREACHABLE)!).', '')|wordcount }}"
          short: true
      footer: "{{ execution.id }}"
      footer_icon: "https://stackstorm.com/wp/wp-content/uploads/2015/01/favicon.png"
Давайте теперь попробуем:

chatops
И знаешь, что? Благодаря мобильному клиенту Slack вы можете запускать эти команды чата и со своего мобильного телефона!

Пример №3: Получить в настоящее время MySQL-запросы

Мы хотим, чтобы простая команда slack запрашивала список процессов mysql с сервера db:

!show mysql processlist

Действие actions/mysql_processlist.yaml :

---
name: mysql_processlist
description: Show MySQL processlist
runner_type: local-shell-cmd
entry_point: ""
enabled: true
parameters:
  sudo:
    immutable: true
    default: true
  kwarg_op:
    immutable: true
  cmd:
    description: "Command to run"
    type: string
    immutable: true
    default: "/opt/stackstorm/virtualenvs/ansible/bin/ansible {{ hosts }} --become --become-user=root -m shell -a \"mysql --execute='SHOW PROCESSLIST;' | expand -t 10\""
  hosts:
    description: "Ansible hosts"
    type: string
    default: db
Action alias для ChatOps: aliases/mysql_processlist.yaml :
---
name: chatops.mysql_processlist
action_ref: st2_chatops_aliases.mysql_processlist
description: Show MySQL processlist
formats:
  - display: "show mysql processlist <hosts=db>"
    representation:
      - "show mysql processlist {{ hosts=db }}"
      - "show mysql processlist on {{ hosts=db }}"
result:
  format: |
    {% if execution.status == 'succeeded' %}MySQL queries on `{{ execution.parameters.hosts }}`: ```{{ execution.result.stdout }}```{~}{% else %}
    *Exit Code:* `{{ execution.result.return_code }}`
    *Stderr:* ```{{ execution.result.stderr }}```
    *Stdout:* ```{{ execution.result.stdout }}```
    {% endif %}
Обратите внимание, что мы сделали параметр hosts необязательным (по умолчанию — db ), поэтому эти команды эквивалентны:
!show mysql processlist
!show mysql processlist 'db'

Ваш администратор базы данных будет счастлив!

Пример №4: получить статистику HTTP nginx

Мы хотим показать коды состояния HTTP, сортировать их по поступлению, чтобы понять, сколько 200 или 50x есть на определенных серверах:

!show nginx stats on 'web'

Фактическое действие, выполняющее actions/http_status_codes.yaml команды actions/http_status_codes.yaml :

---
name: http_status_codes
description: Show sorted http status codes from nginx logs
runner_type: local-shell-cmd
entry_point: ""
enabled: true
parameters:
  sudo:
    immutable: true
    default: true
  kwarg_op:
    immutable: true
  cmd:
    description: "Command to run"
    type: string
    immutable: true
    default: "/opt/stackstorm/virtualenvs/ansible/bin/ansible {{hosts|replace('http://','')}} --become -m shell -a \"awk '{print \\$9}' /var/log/nginx/access.log|sort |uniq -c |sort -k1,1nr 2>/dev/null|column -t\""
  hosts:
    description: "Ansible hosts"
    type: string
    required: true
Псевдоним: aliases/http_status_codes.yaml
---
name: chatops.http_status_codes
action_ref: st2_chatops_aliases.http_status_codes
description: Show sorted http status codes from nginx on hosts
formats:
  - display: "show nginx stats on <hosts>"
    representation:
      - "show nginx stats on {{ hosts }}"
result:
  format: "```{{ execution.result.stdout }}```"
Результат:


Теперь чат больше похож на центр управления. Вы можете делать что-то на своих хостах из чата, и каждый может видеть результат!

Пример №5: Патч безопасности

Представьте, что вы должны исправить еще одну критическую уязвимость, такую ​​как Shellshock . Нам нужно обновить bash на всех машинах с помощью Ansible. Вместо того, чтобы запускать его как специальную команду, давайте playbooks/update_package.yaml сделаем красиво playbooks/update_package.yaml :

---
- name: Update package on remote hosts, run on 25% of servers at a time
  hosts: "{{ hosts }}"
  serial: "25%"
  become: True
  become_user: root
  tasks:
    - name: Check if Package is installed
      command: dpkg-query -l {{ package }}
      register: is_installed
      failed_when: is_installed.rc > 1
      changed_when: no

    - name: Update Package only if installed
      apt: name={{ package }}
        state=latest
        update_cache=yes
        cache_valid_time=600
      when: is_installed.rc == 0

Вы можете видеть, что переменные {{ hosts }} и {{ package }} в playbook вводятся снаружи, см. Действия StackStorm action actions/update_package.yaml :

---
name: update_package
description: Update package on remote hosts
runner_type: local-shell-cmd
entry_point: ""
enabled: true
parameters:
  sudo:
    immutable: true
    default: true
  kwarg_op:
    immutable: true
  timeout:
    default: 6000
  cmd:
    description: "Command to run"
    immutable: true
    default: "/opt/stackstorm/virtualenvs/ansible/bin/ansible-playbook /opt/stackstorm/packs/${ST2_ACTION_PACK_NAME}/playbooks/update_package.yaml --extra-vars='hosts={{hosts|replace('http://','')}} package={{package}}'"
  hosts:
    description: "Ansible hosts"
    type: string
    required: true
  package:
    description: "Package to upgrade"
    type: string
    required: true
И вот псевдоним действия, который позволяет запускать playbook как простую команду в чате,

aliases/update_package.yaml :

---
name: chatops.ansible_package_update
action_ref: st2_chatops_aliases.update_package
description: Update package on remote hosts
formats:
  - display: "update <package> on <hosts>"
    representation:
      - "update {{ package }} on {{ hosts }}"
      - "upgrade {{ package }} on {{ hosts }}"
result:
  format: |
    Update package `{{ execution.parameters.package }}` on `{{ execution.parameters.hosts }}` host(s): {~}
    {% if execution.result.stderr %}
    *Exit Status*: `{{ execution.result.return_code }}`
    *Stderr:* ```{{ execution.result.stderr }}```
    *Stdout:*
    {% endif %}
    ```{{ execution.result.stdout }}```
  extra:
    slack:
      color: "{% if execution.result.succeeded %}good{% else %}danger{% endif %}"
      fields:
        - title: Updated nodes
          value: "{{ execution.result.stdout|regex_replace('(?!changed=1).', '')|wordcount }}"
          short: true
        - title: Executed in
          value: ":timer_clock: {{ execution.elapsed_seconds | to_human_time_from_seconds }}"
          short: true
      footer: "{{ execution.id }}"
      footer_icon: "https://stackstorm.com/wp/wp-content/uploads/2015/01/favicon.png"
В заключение:
!update 'bash' on 'all'

Большая часть нашей работы, как инженеров DevOps, — это оптимизировать процессы, упрощая жизнь разработчиков, улучшая сотрудничество в команде, диагностировать проблемы быстрее, автоматизируя среду и привнося нужные инструменты, чтобы сделать компанию успешной.
ChatOps решает это на совершенно новом эффективном уровне!

Это простые примеры. Более сложные ситуации, когда несколько инструментов DevOps привязаны к динамическим рабочим процессам, будут рассмотрены в будущих статьях. Именно здесь StackStorm демонстрирует свою супермощность, принимая решения о том, что делать в зависимости от ситуации: управляемая событиями архитектура, такая как системы самовосстановления.

Хотите упростить работу?  Обращайтесь [email protected]

Оставить комментарий

Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.