Installation und Konfiguration von Mesos

2016/12/09

Server Ressourcen vollziehen seit Jahren einen starken Preisverfall mit gleicher Zunahme der Kapazitäten. Dies geht einher mit immer stärkerer Nutzung von IT Infrastruktur in unserem Alltag. Auch wenn dies dem Konsumenten nicht ersichtlich ist. Wem ist schon bewusst das hinter einem OnlineShop mehrere Hundert Server stehen. Um sehr Agil auf unterschiedliche Situationen reagieren zu können, wird vermehrt auf Software Defined Infrastructur gesetzt. D.h. Server und Netzwerkkomponenten werden nicht über Hardware sondern über Software abgedeckt um je nach Ansprüchen (z.B. Nutzung, Last, Ausfälle) onTheFly angepasst zu werden. Selbstverständlich gibt es nach wie vor Hardware auf der die Software läuft, allerdings ist diese so sehr vereinfacht, dass relativ schnell neue Hardware (Hersteller Unabhängig) besorgt, aufgebaut und dem gesamt System als Ressource zur Verfügung gestellt werden kann.

In diesem Dokument möchte ich aufzeigen, wie wir uns eine Software Defined Infrastructur mithilfe von Mesos aufbauen und Ressourcen automatisiert verwalten. Schauen wir uns zunächst ein Bild an um genauer zu verstehen, wie unser Aufbau aussehen wird.

Fangen wir an unsere Server zu Konfigurieren. Als Grundlage nehme ich CentOS. Mit leichten Anpassungen sollten jedoch auch andere von Mesos unterstützte Distributionen funktionieren.

Als erstes löschen wir auf unserer VM die Machine-id. Wenn Euer Mesos auf Bare Metal installiert wird, könnt Ihr das überspringen. Anschließend den Hostname anpassen.

rm /etc/machine-id
systemd-machine-id-setup

hostname <hostname>

In der hosts Datei werden wir alle Mesos Master und Slaves eintragen. Das wird später viele DNS Abfragen ersparen.

vim /etc/hosts
<ip> <fqdn> <hostname>

Installieren wir nun mesos!

rpm -i http://repos.mesosphere.io/el/7/noarch/RPMS/mesosphere-el-repo-7-1.noarch.rpm
vim /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
vim /etc/yum.repos.d/epel.repo

[epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/7/$basearch
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch
failovermethod=priority
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7

[epel-debuginfo]
name=Extra Packages for Enterprise Linux 7 - $basearch - Debug
#baseurl=http://download.fedoraproject.org/pub/epel/7/$basearch/debug
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-7&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=1

[epel-source]
name=Extra Packages for Enterprise Linux 7 - $basearch - Source
#baseurl=http://download.fedoraproject.org/pub/epel/7/SRPMS
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-7&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=1

Nachdem wir die Repositories hinzugefügt haben, installieren wir die benötigte Software mit deren Abhängigkeiten.

yum install mesos
yum install nginx
yum install mesosphere-zookeeper
yum install marathon
yum install chronos
yum install docker

vim /etc/mesos-slave/containerizers
docker,mesos

vim /etc/mesos-slave/docker_socket
/var/run/weave/weave.sock


Nun aktivieren und starten wir die Dienste. Wie zu sehen ist, starte ich mesos-slave und mesos-master auf dem gleichen Server. Grundsätzlich sollten es mehr als einen Master- und Slave Server geben um eine sinnvolle Redundanz aufzubauen.

systemctl start nginx
systemctl start zookeeper
systemctl start mesos-master
systemctl start mesos-slave
systemctl start marathon
systemctl start chronos

systemctl enable nginx
systemctl enable zookeeper
systemctl enable mesos-master
systemctl enable mesos-slave
systemctl enable marathon
systemctl enable chronos

Wir wir sehen, start ich diverse Dienste direkt auf dem Server. All dieses Dienste sollten daher im Mesos Cluster mehrfach vorkommen. Theoretisch koennte man diese auch in einzelne Container laufen lassen. Da meine Server Ressourcen stark begrenzt sind, unterlasse ich dies. Der Zugriff auf Marathon ist weder Passwort geschuetzt noch SSL Verschluesselt, aus diesem Grund, schalte ich einen nginx Proxy vor. Sicherheit muss sein! :-) Das gleiche mache ich auch allen anderen Diensten die eine Art GUI oder zumindest Status Seite anzeigt.

vim /etc/nginx/conf.d/default.conf
server {
			listen       9000 ssl;
    	server_name  localhost;

			ssl_certificate /etc/nginx/ssl/nginx.crt;
			ssl_certificate_key /etc/nginx/ssl/nginx.key;

			location / {
                client_max_body_size 5000M;
                sendfile on;
                proxy_max_temp_file_size 0;
                proxy_buffering off;
                proxy_redirect off;
                proxy_pass http://[::1]:8080;
                proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
								auth_basic "Restricted";                                #For Basic Auth
      					auth_basic_user_file /etc/nginx/.htpasswd;  #For Basic Auth
       }


}

server {
        listen       9001 ssl;
        server_name  localhost;

				ssl_certificate /etc/nginx/ssl/nginx.crt;
        ssl_certificate_key /etc/nginx/ssl/nginx.key;

        location / {
                client_max_body_size 5000M;
                sendfile on;
                proxy_max_temp_file_size 0;
                proxy_buffering off;
                proxy_redirect off;
                proxy_pass http://localhost:5050;
                proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                auth_basic "Restricted";                                #For Basic Auth
                auth_basic_user_file /etc/nginx/.htpasswd;  #For Basic Auth
       }
}

server {
        listen       9002 ssl;
        server_name  localhost;

				ssl_certificate /etc/nginx/ssl/nginx.crt;
        ssl_certificate_key /etc/nginx/ssl/nginx.key;

        location / {
                client_max_body_size 5000M;
                sendfile on;
                proxy_max_temp_file_size 0;
                proxy_buffering off;
                proxy_redirect off;
                proxy_pass http://localhost:4400;
                proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                auth_basic "Restricted";                                #For Basic Auth
                auth_basic_user_file /etc/nginx/.htpasswd;  #For Basic Auth
       }
}
server {
	listen       9003;
    	server_name  localhost;


	location / {
                client_max_body_size 5000M;
                sendfile on;
                proxy_max_temp_file_size 0;
                proxy_buffering off;
                proxy_redirect off;
                proxy_pass http://localhost:9090;
                proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
		auth_basic "Restricted";                                #For Basic Auth
      		auth_basic_user_file /etc/nginx/.htpasswd;  #For Basic Auth
       }
}

server {
	listen       9004 ssl;
    	server_name  localhost;

        ssl_certificate /etc/nginx/ssl/nginx.crt;
        ssl_certificate_key /etc/nginx/ssl/nginx.key;

        proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
        proxy_no_cache $http_pragma $http_authorization;

	location / {
                client_max_body_size 5000M;
                sendfile on;
                proxy_max_temp_file_size 0;
                proxy_buffering off;
                proxy_redirect off;
                proxy_pass http://localhost:10006;
                proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
       }
}

server {
        listen       9005 ssl;
        server_name  localhost;

        ssl_certificate /etc/nginx/ssl/nginx.crt;
        ssl_certificate_key /etc/nginx/ssl/nginx.key;

        proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
        proxy_no_cache $http_pragma $http_authorization;

        location / {
                client_max_body_size 5000M;
                sendfile on;
                proxy_max_temp_file_size 0;
                proxy_buffering off;
                proxy_redirect off;
                proxy_pass http://37.61.206.28:8500;
                proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                auth_basic "Restricted";                                #For Basic Auth
                auth_basic_user_file /etc/nginx/.htpasswd;  #For Basic Auth
       }
}

server {
        listen       9006 ssl;
        server_name  localhost;

        ssl_certificate /etc/nginx/ssl/nginx.crt;
        ssl_certificate_key /etc/nginx/ssl/nginx.key;

        proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
        proxy_no_cache $http_pragma $http_authorization;

        location / {
                client_max_body_size 5000M;
                sendfile on;
                proxy_max_temp_file_size 0;
                proxy_buffering off;
                proxy_redirect off;
                proxy_pass http://localhost:9000;
                proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                auth_basic "Restricted";                                #For Basic Auth
                auth_basic_user_file /etc/nginx/.htpasswd;  #For Basic Auth
       }
}


Installieren wir nun Consul.

cd /install
wget https://releases.hashicorp.com/consul/0.7.5/consul_0.7.5_linux_amd64.zip
unzip consul_0.7.5_linux_amd64.zip
mv consul /usr/local/bin/

mkdir -p /opt/consul/data
useradd consul
chown -R consul: /opt/consul

Consul als systemd anlegen.

vim /etc/systemd/system/consul.service

[Unit]
Description=Consul Agent

[Service]
Environment="GOMAXPROCS=`nproc`"
User=consul
Group=consul
ExecStart=/usr/local/bin/consul agent -ui -config-file=/etc/consul.conf >> /var/log/consul 2>&1
[Install]
WantedBy=multi-user.target

Und bootfest machen:

systemctl enable consul
systemctl start consul

Nun konfigurieren wir Consul. Achtung: Wenn mehr als ein Consul Node verwendet wird, muss der “bootstrap” Eintrag entfernt werden.

vim /etc/consul.conf
{
	"bootstrap": true,
  "start_join": ["<MESOS SERVER>"],
  "disable_remote_exec": true,
  "domain": "<MESOS DOMAIN>",
  "data_dir": "/opt/consul/data",
  "log_level": "INFO",
  "enable_syslog": true,
  "node_name": "<MESOS SERVER>",
  "server": true,
  "client_addr": "<MESOS NODE IP>",
  "addresses" : {
    "rpc": "127.0.0.1"
  },
  "client_addr": "<MESOS NODE IP>",
  "bind_addr": "0.0.0.0",
  "advertise_addr": "<MESOS NODE IP>",
  "datacenter": "dc01",
  "retry_join": [ "<MESOS SERVER>" ],
  "ports": {
    "dns": 8600,
    "http": 8500,
    "https": -1,
    "rpc": 8400,
    "serf_lan": 8301,
    "serf_wan": 8302,
    "server": 8300
  },
  "rejoin_after_leave": true,
  "leave_on_terminate": true
}

Um Consul zu testen kann man folgenden Curl aufrufen. Allerdings ist dies erst sinnvoll wenn der gesamte Mesos Cluster inklusive Services läuft.

curl http://mdc0000:8500/v1/catalog/service/consul | jq

Der oben verwendete Befehl JQ ist ein json Interpreter. Man benötigt ihn nicht unbedingt, macht das lesen der Ausgabe aber einfacher.

Konfigurieren wir nun als nächstes DNSMasq um lokale mesos bezogene Anfragen an Consul zu leiten und alle anderen an den öffentlichen oder Firmen eigenen DNS Server.

vim  /etc/dnsmasq.d/10-consul
#Listen on all interfaces
interface=*

addn-hosts=/etc/hosts

# Never forward addresses in the non-routed address spaces.
bogus-priv

server=<DNS1>
server=<DNS2>

# configure DNS resolution to consul servers

server=/<MESOS DOMAIN>/<MESOS SERVER IP>#8600

Die resolv.conf von Linux muss entsprechend angepasst.

/etc/resolv.conf
nameserver 127.0.0.1

Nun habe wir zwar Consul und DNSMasq als DNS Service installiert, es fehlt uns jedoch noch ein Service um die Marathon-IDs in Consul zu übernehmen. Dies geschieht mit dem folgenden Container:

docker run -d --restart always --name=registratorMaster --net=host  --volume=/var/run/weave/weave.sock:/tmp/docker.sock gliderlabs/registrator:master -internal -resync 300 consul://<MESOS SERVER IP>:8500

Folgendes sollte nun als Test erscheinen:

dig @<MESOS SERVER IP> -p 8600 consul.service.<MESOS DOMAIN>

; <<>> DiG 9.9.4-RedHat-9.9.4-29.el7_2.4 <<>> @<MESOS SERVER IP> -p 8600 consul.service.<MESOS DOMAIN>
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52811
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;consul.service.<MESOS DOMAIN>.	IN	A

;; ANSWER SECTION:
consul.service.<MESOS DOMAIN> . 0 IN	A	<MESOS SERVER IP>

;; Query time: 1 msec
;; SERVER: <MESOS SERVER IP>#8600(<MESOS SERVER IP>)
;; WHEN: Thu Jan 05 13:30:37 CET 2017
;; MSG SIZE  rcvd: 63

Als nächstes installieren wir weave als Virtuelle Netzwerkschicht für Docker.

curl -L git.io/weave -o /usr/local/bin/weave
chmod a+x /usr/local/bin/weave

Konfigurieren wir nun die Peers die im Weave verbunden sind. Die Peers sind alle Mesos Slave Server auf denen eine Docker Engine laufen werden. In unserer Installation ist das natürlich nur ein Server.

vim /etc/weave.env
WEAVE_PEERS="<leerzeichenseparierte liste an weave peers>"

Da weave automatisch gestartet werden soll, richten wir wieder ein Systemd mit der Abhängigkeit zur Docker Engine ein.

vim /etc/systemd/system/weaveproxy.service
[Unit]
Description=Weave Docker API proxy
Documentation=http://docs.weave.works/
After=docker.service
Requires=docker.service

[Service]
TimeoutStartSec=0
EnvironmentFile=-/etc/weave.env
EnvironmentFile=-/etc/weave.%H.env
ExecStartPre=/usr/local/bin/weave launch-proxy --without-dns --rewrite-inspect
ExecStart=/usr/bin/docker attach weaveproxy
Restart=on-failure
ExecStop=/usr/local/bin/weave stop-proxy

[Install]
WantedBy=weave.target
vim /etc/systemd/system/weave.service
[Unit]
Description=Weave Net
Documentation=http://docs.weave.works/
After=docker.service
Before=weaveproxy.service
Requires=docker.service

[Service]
TimeoutStartSec=0
EnvironmentFile=-/etc/weave.env
EnvironmentFile=-/etc/weave.%H.env
ExecStartPre=/usr/local/bin/weave launch-router --no-dns $WEAVE_PEERS --ipalloc-range 10.199.0.0/16
ExecStart=/usr/bin/docker attach weave
Restart=on-failure
ExecStop=/usr/bin/weave stop-router

[Install]
WantedBy=weave.target

Und aktivieren wie alles!

systemctl enable weaveproxy
systemctl enable weave

systemctl start docker
systemctl start weave
systemctl start weaveproxy
weave expose

Ohne weave expose bekommt unser Node keine eigene Weave IP Adresse.

Im Grundegenommen sollte nun alles soweit funktionieren. Wichtig wäre es sich nochmals alle logs via journalctl anzuschauen.

Wenn alles funktioniert, stellen wir nun den Marathon-LB Service zur Verfügung. Diesen wollen wir ebenfalls als Docker Container Realisieren. Schauen wir uns also die entsprechende JSON Datei an.

{
  "container": {
    "type": "DOCKER",
    "docker": {
      	"image": "mesosphere/marathon-lb",
      	"forcePullImage": true,
      	"network": "HOST",
      	"portMappings": [
        		{
							"containerPort": 9090,
							"hostPort": 9090,
							"servicePort": 0,
							"protocol": "tcp"
						}
      	],
  			"args": ["sse"]
    }
  },
  "id": "marathon-lb",
  "instances": 1,
  "cpus": 0.5,
  "mem": 128
}

Im Grundegenommen ist an der JSON Datei nichts besonderes zu erkennen. Als Modus habe ich mich hier für “sse” entschieden. Hierbei Verbindet sich Marathon-LB an den Mesos Event Endpoint um die Information für einen neuen Hostname Eintrag zu bekommen.

Laden wir nun die JSON Datei in Mesos hoch:

curl -k -XPOST -d @marathon-lb.json -H "Content-Type: application/json" localhost:8080/v2/apps

Möchte man nun einen schon vorhandenen Docker Dienst über Marathon-LB ansprechbar machen, erstellt man über Marathon folgende Lables:

  • HAPROXY_0_REDIRECT_TO_HTTPS=false
  • HAPROXY_GROUP=external
  • MARATHON_HOSTNAME=
  • HAPROXY_0_VHOST=.marathon.

Darüber hinaus ist es sinnvoll, die Service Name Environment Variable zu setzten. Dies sorgt dafür, dass Consul einen DNS Eintrag mit dem Service Name und nicht mit dem Container Name erstellt.

"env": {
	"SERVICE_NAME": "<servicename>"
},

Oder man erstellt gleich von anbegin eine entsprechende JSON Datei:

{
  "id": "nextcloud",
  "cmd": null,
  "cpus": 0.2,
  "mem": 200,
  "disk": 0,
  "instances": 1,
  "container": {
    "type": "DOCKER",
    "volumes": [],
    "docker": {
      "image": "docker.io/avhost/nextcloud",
      "network": "BRIDGE",
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 0,
          "protocol": "tcp",
          "labels": {}
        }
      ],
     "parameters": [
        {
          "key": "volume-driver",
          "value": "local"
        },
        {
          "key": "volume",
          "value": "owncloud:/var/www/html:rw"
        },
        {
          "key": "volume",
          "value": "owncloud-data:/var/data:rw"
        }
      ],
      "privileged": false,
      "forcePullImage": true
    }
  },
  "labels": {
    "HAPROXY_0_REDIRECT_TO_HTTPS": "false",
    "HAPROXY_GROUP": "external",
    "MARATHON_HOSTNAME": "nextcloud",    
    "HAPROXY_0_VHOST": "nextcloud.marathon.<MESOS DOMAIN>"
  }
}

Ab jetzt sind wir also in der Lage mit Mesos/Marathon Services oder Container zu orchestrieren. :-) Kümmern wir uns nun um das Monitoring. Hierbei setze ich auf Prometheus und Grafana.

mkdir ~/Prometheus
cd ~/Prometheus

wget https://github.com/prometheus/prometheus/releases/download/v1.5.0/prometheus-1.5.0.linux-amd64.tar.gz
tar -xvf prometheus-1.5.0.linux-amd64.tar.gz
prometheus-1.5.0.linux-amd64/prometheus -version

mkdir /opt/prometheus
mv ~/Prometheus/prometheus-1.5.0.linux-amd64/* /opt/prometheus/

Als collector für Statistik Daten verwenden wir cAdvisor von google. Es gibt keinen speziellen Grund den zu nehmen. Ich weiss aber das dieser in meiner benötigten Konstellation funktioniert. :-) cAdvisor muss übrigens auf allen Mesos Slaves wo eine Docker Engine läuft gestartet werden.

docker run \
  --restart always \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:rw \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --publish=8700:8080 \
  --detach=true \
  --name=cadvisor \
  google/cadvisor:latest

cAdvisor sammelt ja nur Daten. Die müssen aber auch gespeichert werden. Hier verwenden wir Prometheus.


In der folgenden Konfigurationsdatei geben wir an, von wo Prometheus seine Daten bekommen soll. Für Docker Container Statistik verwenden wir alle die IP’s aller Server auf denen cAdvisors läuft. Für die Host Statistik verwenden wir den Systemd Dienst node_exporter. Dessen Installation und Konfiguration beschreibe ich anschliessend.

vim /opt/prometheus/prometheus.yml

global:
  scrape_interval:     15s
  evaluation_interval: 30s

	scrape_configs:

	- job_name: docker-metrics

	  static_configs:
	  - targets: ['<MESOS SERVER IP>:8700']
	    labels:
	      node: docker-nodes

	- job_name: host-metrics

	  static_configs:
	  - targets: ['<MESOS SERVER IP>:9100']
	    labels:
	      node: infrastructure-nodes

Prometheus lassen wir wieder als Systemd Dienst laufen.

vim /etc/systemd/system/prometheus.service
[Unit]
Description=Node Exporter

[Service]
User=root
ExecStart=/opt/prometheus/prometheus -storage.local.path=/opt/prometheus/data -config.file=/opt/prometheus/prometheus.yml -web.listen-address ":9999"

[Install]
WantedBy=default.target


systemctl daemon-reload
systemctl enable prometheus.service
systemctl start prometheus.service
systemctl status prometheus.service

Prometheus ist installiert, und hoffentlich auch funktionsfähig. Wie versprochen, installieren wir nun den node_exporter.

mkdir ~/Prometheus/node_exporter
cd ~/Prometheus/node_exporter

wget https://github.com/prometheus/node_exporter/releases/download/v0.14.0-rc.1/node_exporter-0.14.0-rc.1.linux-amd64.tar.gz
tar -xvf node_exporter-0.14.0-rc.1.linux-amd64.tar.gz
node_exporter-0.14.0-rc.1.linux-amd64/node_exporter

mkdir /opt/node_exporter/
cp ~/Prometheus/node_exporter/node_exporter-0.14.0-rc.1.linux-amd64/node_exporter /opt/node_exporter/

Und schon wieder ein systemd.

vim /etc/systemd/system/node-exporter.service
[Unit]
Description=Node Exporter

[Service]
User=root
ExecStart=/opt/node_exporter/node_exporter -web.listen-address=0.0.0.0:9100

[Install]
WantedBy=default.target

systemctl daemon-reload
systemctl enable node-exporter.service
systemctl start node-exporter.service
systemctl status node-exporter.service

Jetzt werden zwar sämtliche Daten gesammelt und gespeichert, aber nicht hübsch visuell dargestellt. Dies wird in unserem Fall von Grafana übernommen.

vim /etc/yum.repos.d/grafana.repo

[grafana]
name=grafana
baseurl=https://packagecloud.io/grafana/stable/el/6/$basearch
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://packagecloud.io/gpg.key https://grafanarel.s3.amazonaws.com/RPM-GPG-KEY-grafana
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
yum install grafana

systemctl start grafana-server
systemctl status grafana-server
systemctl enable grafana-server.service

TODO

Schauen wir uns nun im nachfolgenden an, wie wir die anfallenden Logs Zentral auswerten und Protokollieren.


yum install pwgen

vim /etc/yum.repos.d/mongodb-org-3.2.repo
[mongodb-org-3.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.2/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.2.asc

yum install mongodb-org

chkconfig --add mongod
systemctl daemon-reload
systemctl enable mongod.service
systemctl start mongod.service

rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch

vim /etc/yum.repos.d/elasticsearch.repo

[elasticsearch-2.x]
name=Elasticsearch repository for 2.x packages
baseurl=https://packages.elastic.co/elasticsearch/2.x/centos
gpgcheck=1
gpgkey=https://packages.elastic.co/GPG-KEY-elasticsearch
enabled=1

yum install elasticsearch

vim /etc/elasticsearch/elasticsearch.yml
cluster.name: DC01
http.port: 9400

chkconfig --add elasticsearch
systemctl daemon-reload
systemctl enable elasticsearch.service
systemctl restart elasticsearch.service

rpm -Uvh https://packages.graylog2.org/repo/packages/graylog-2.1-repository_latest.rpm
yum install graylog-server

vim /etc/graylog/server/server.conf
## Lesen und Konfigurieren
password_secret

echo -n <yourpassword> | sha256sum


chkconfig --add graylog-server
systemctl daemon-reload
systemctl enable graylog-server.service
systemctl start graylog-server.service