92
Service discovery and configuration provisioning mariuszgil srcministry Mariusz Gil

Service discovery and configuration provisioning

Embed Size (px)

Citation preview

Page 1: Service discovery and configuration provisioning

Service discovery and configuration provisioning

mariuszgil srcministry

Mariusz Gil

Page 2: Service discovery and configuration provisioning
Page 3: Service discovery and configuration provisioning
Page 4: Service discovery and configuration provisioning
Page 5: Service discovery and configuration provisioning

What is an application? Source code?

Page 6: Service discovery and configuration provisioning

Is it a complete solution for client?

Page 7: Service discovery and configuration provisioning
Page 8: Service discovery and configuration provisioning
Page 9: Service discovery and configuration provisioning

How to manage the configuration?

Page 10: Service discovery and configuration provisioning

Old school approach…

Page 11: Service discovery and configuration provisioning

<?php  define('DB_HOST', 'localhost'); define('DB_NAME', 'northwind'); define('DB_USER', 'root'); define('DB_PASS', 'your_password');  // This connection allows your application to be used for multi-lingual websites. function _connect_to_mysql($is_utf8 = null) { $mysql_link = mysql_connect(DB_HOST, DB_USER, DB_PASS) or die("Could not connect to database server"); mysql_select_db(DB_NAME, $mysql_link) or die("Could not select database");   if (is_null($is_utf8)) { /* This sets collation for the connection to utf8_general_ci because it is the default collation for utf8. This enables multi-lingual capability in database. */ mysql_query("SET NAMES 'utf8'"); } return $mysql_link; }

Page 12: Service discovery and configuration provisioning

<?php  // ...  // ** MySQL settings - You can get this info from your web host ** // define('DB_NAME', 'database');  /** MySQL database username */ define('DB_USER', 'username');  /** MySQL database password */ define('DB_PASSWORD', 'password');  /** MySQL hostname */ define('DB_HOST', 'localhost');  /** Database Charset to use in creating database tables. */ define('DB_CHARSET', 'utf8');  /** The Database Collate type. Don't change this if in doubt. */ define('DB_COLLATE', '');

Page 13: Service discovery and configuration provisioning

<?php /** * The base configuration for WordPress * * The wp-config.php creation script uses this file during the * installation. You don't have to use the web site, you can * copy this file to "wp-config.php" and fill in the values. * * @link https://codex.wordpress.org/Editing_wp-config.php * @package WordPress */  // ** MySQL settings - You can get this info from your web host ** // define('DB_NAME', 'database');  /** MySQL database username */ define('DB_USER', 'username');  /** MySQL database password */ define('DB_PASSWORD', 'password');  /** MySQL hostname */ define('DB_HOST', 'localhost');  /** Database Charset to use in creating database tables. */ define('DB_CHARSET', 'utf8');  /** The Database Collate type. Don't change this if in doubt. */ define('DB_COLLATE', '');

Page 14: Service discovery and configuration provisioning

bash-3.2$ ack DB_NAME wp-includes/load.php350: $wpdb = new wpdb( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST ); wp-content/plugins/xcloner-backup-and-restore/restore/XCloner.php580: $config_data = str_replace("define('DB_NAME', '", "define('DB_NAME', ‚".$_REQUEST[mysql_db]."'); #", $config_data) wp-content/plugins/w3-total-cache/lib/W3/Db.php165: parent::__construct(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);

Page 15: Service discovery and configuration provisioning

How we can improve it?

Page 16: Service discovery and configuration provisioning

<?php use Pimple\Container; $container = new Container(); $container['db'] = function() { $host = 'localhost'; $dbName = 'wordpress'; $user = 'root'; $pass = ''; return new \PDO("mysql:host={$host};dbname={$dbName}", $user, $pass); };

Page 17: Service discovery and configuration provisioning

<?php $dice = new \Dice\Dice(); $rule = [ //Mark the class as shared so the same instance is returned each time 'shared' => true, //The constructor arguments that will be supplied when the instance is created 'constructParams' => [ 'mysql:host=127.0.0.1;dbname=mydb', 'username', 'password', ], ]; //Apply the rule to the PDO class $dice->addRule('PDO', $rule); //Now any time PDO is requested from Dice, the same instance will be returned //And will have been constructed with the arguments supplied in 'constructParams' $pdo = $dice->create('PDO');

Page 18: Service discovery and configuration provisioning

<?php $builder = new \DI\ContainerBuilder(); $builder->addDefinitions([ 'foo' => 'hello ', 'bar' => 'world', ]); $builder->addDefinitions([ 'foo' => \DI\decorate(function ($previous, \Interop\Container\ContainerInterface $container) { return $previous . $container->get('bar'); }), ]); $builder->addDefinitions([ 'values' => [ 'value 1', 'value 2', ], ]); $builder->addDefinitions([ // with the same name 'stdClass' => \DI\object('stdClass'), // with name inferred __NAMESPACE__ . '\ObjectDefinition\Class1' => \DI\object(), // with a different name 'object' => \DI\object(__NAMESPACE__ . '\ObjectDefinition\Class1'), ]); $container = $builder->build();

Page 19: Service discovery and configuration provisioning

# Swiftmailer Configurationswiftmailer: transport: "%mailer_transport%" host: "%mailer_host%" username: "%mailer_user%" password: "%mailer_password%" spool: { type: memory }

# KNP Menu configurationknp_menu: twig: template: knp_menu.html.twig templating: false default_renderer: twig

# KNP Paginator configurationknp_paginator: page_range: 5 default_options: page_name: page

# LiipImagine configurationliip_imagine: filter_sets: square_200: quality: 100 filters: thumbnail: { size: [200, 200], mode: outbound }

# Configuration parametersparameters: database_host: 127.0.0.1 database_port: null database_name: database database_user: root database_password: null mailer_transport: smtp mailer_host: 127.0.0.1 mailer_user: null mailer_password: null secret: 092402938a039b72278b9b05da3f4d4

Page 20: Service discovery and configuration provisioning
Page 21: Service discovery and configuration provisioning
Page 22: Service discovery and configuration provisioning

Is captcha feature enabled? Is remember-be feature enabled? Is remind-me feature enabled? Is 2-factor authentication enabled? Is brute-force protection enabled? How many attempts per login allowed? What is delay between failed logins? Is hide-errors protection enabled? … Is login feature enabled at all?

Page 23: Service discovery and configuration provisioning

What is database host? What is database port? What is database user? What is database password? What is database name? What is database encoding? Is database cache enabled? What is cache host? What is cache port? Where the sessions are stored?

Page 24: Service discovery and configuration provisioning

Standard feature Single form Many configuration problems

Page 25: Service discovery and configuration provisioning

How to update configs?

Page 26: Service discovery and configuration provisioning

mysql> DESC wp_options;+--------------+---------------------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra |+--------------+---------------------+------+-----+---------+----------------+| option_id | bigint(20) unsigned | NO | PRI | NULL | auto_increment || option_name | varchar(64) | NO | UNI | | || option_value | longtext | NO | | NULL | || autoload | varchar(20) | NO | | yes | |+--------------+---------------------+------+-----+---------+----------------+4 rows in set (0.00 sec)

mysql> SELECT * FROM wp_options WHERE option_name LIKE '%enabled%' LIMIT 1;+-----------+----------------------+--------------+----------+| option_id | option_name | option_value | autoload |+-----------+----------------------+--------------+----------+| 87 | link_manager_enabled | 0 | yes |+-----------+----------------------+--------------+----------+1 row in set (0.00 sec)

Page 27: Service discovery and configuration provisioning

You need to deploy application to release changes in configuration

Page 28: Service discovery and configuration provisioning

host A

Page 29: Service discovery and configuration provisioning

host A host B

Page 30: Service discovery and configuration provisioning

Another approach to maintain configs

Page 31: Service discovery and configuration provisioning

Decouple your application from hardcoded configuration details

Page 32: Service discovery and configuration provisioning

by

Page 33: Service discovery and configuration provisioning

Service discovery and configuration provisioning tool

Page 34: Service discovery and configuration provisioning
Page 35: Service discovery and configuration provisioning

Service discovery

Failure detection

Key Value storage

Multi DC ready

Page 36: Service discovery and configuration provisioning

host A host B host C host D

192.168.100.56

192.168.100.120

Page 37: Service discovery and configuration provisioning

host A host B host C host D

192.168.100.56

192.168.100.120

Page 38: Service discovery and configuration provisioning

host A host B host C host D

mysql.service.consul.

redis.service.consul.

agentserver agent agent

Page 39: Service discovery and configuration provisioning

host A host B host C host D

mysql.service.consul.

redis.service.consul.

server agent agent agent

Page 40: Service discovery and configuration provisioning

Managing services

Page 41: Service discovery and configuration provisioning

# curl -X PUT -d '{ "service": { "name": "memcached", "tags": ["cache"], "port": 11211, "check": { "name": "memcached status", "script": "echo stats | nc 127.0.0.1 11211", "interval": "5s" } }}' http://192.168.33.10:8500/v1/catalog/service/memcached

# curl -X GET http://192.168.33.10:8500/v1/catalog/service/memcached[{„Node":"vagrant-ubuntu-trusty-64","Address":"192.168.33.10","ServiceID":"memcached","ServiceName":"memcached","ServiceTags":["cache"],"ServiceAddress":"","ServicePort":11211,"ServiceEnableTagOverride":false,"CreateIndex":19,"ModifyIndex":22}]

Page 42: Service discovery and configuration provisioning

<?php

require '../vendor/autoload.php';

$sf = new SensioLabs\Consul\ServiceFactory(array( 'base_url' => 'http://192.168.33.10:8500',));

$catalog = $sf->get('catalog');$response = $catalog->service('memcached')->json();

# Result dataarray ( 0 => array ( 'Node' => 'vagrant-ubuntu-trusty-64', 'Address' => '192.168.33.10', 'ServiceID' => 'memcached', 'ServiceName' => 'memcached', 'ServiceTags' => array ( 0 => 'cache', ), 'ServiceAddress' => '', 'ServicePort' => 11211, 'ServiceEnableTagOverride' => false, 'CreateIndex' => 19, 'ModifyIndex' => 60, ),)

Page 43: Service discovery and configuration provisioning

DNS interface for services and tags

Page 44: Service discovery and configuration provisioning

<node>.node[.dc].<domain>

Page 45: Service discovery and configuration provisioning

[tag.]<service>.service[.dc].<domain>

Page 46: Service discovery and configuration provisioning

# dig @192.168.33.10 -p 8600 memcached.service.consul

; <<>> DiG 9.9.5-3ubuntu0.5-Ubuntu <<>> @192.168.33.10 -p 8600 memcached.service.consul; (1 server found);; global options: +cmd;; Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58136;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0;; WARNING: recursion requested but not available

;; QUESTION SECTION:;memcached.service.consul. IN A

;; ANSWER SECTION:memcached.service.consul. 0 IN A 192.168.33.10

;; Query time: 4 msec;; SERVER: 192.168.33.10#8600(192.168.33.10);; WHEN: Fri Jan 29 16:40:37 UTC 2016;; MSG SIZE rcvd: 82

Page 47: Service discovery and configuration provisioning

# dig @192.168.33.10 -p 8600 memcached.service.consul SRV

; <<>> DiG 9.9.5-3ubuntu0.5-Ubuntu <<>> @192.168.33.10 -p 8600 memcached.service.consul SRV; (1 server found);; global options: +cmd;; Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10299;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1;; WARNING: recursion requested but not available

;; QUESTION SECTION:;memcached.service.consul. IN SRV

;; ANSWER SECTION:memcached.service.consul. 0 IN SRV 1 1 11211 vagrant-ubuntu-trusty-64.node.dc1.consul.

;; ADDITIONAL SECTION:vagrant-ubuntu-trusty-64.node.dc1.consul. 0 IN A 192.168.33.10

;; Query time: 4 msec;; SERVER: 192.168.33.10#8600(192.168.33.10);; WHEN: Fri Jan 29 16:41:06 UTC 2016;; MSG SIZE rcvd: 182

Page 48: Service discovery and configuration provisioning

PHP Benelux Fries Example

Page 49: Service discovery and configuration provisioning

Service 1 Service 2

Page 50: Service discovery and configuration provisioning

# curl -X PUT -d '{ "Datacenter": "dc1", "Node": "vagrant-ubuntu-trusty-64", "Address": "192.168.33.10", "Service": { "ID": "fries-1", "Service": "fries", "Tags": [ "fries" ], "Address": "192.168.33.10", "Port": 1111 }}' http://192.168.33.10:8500/v1/catalog/registertrue

# curl -X PUT -d '{ "Datacenter": "dc1", "Node": "vagrant-ubuntu-trusty-64", "Address": "192.168.33.10", "Service": { "ID": "fries-2", "Service": "fries", "Tags": [ "fries" ], "Address": "192.168.33.10", "Port": 2222 }}' http://192.168.33.10:8500/v1/catalog/registertrue

Page 51: Service discovery and configuration provisioning

# dig @192.168.33.10 -p 8600 fries.service.consul SRV

; <<>> DiG 9.9.5-3ubuntu0.5-Ubuntu <<>> @192.168.33.10 -p 8600 fries.service.consul SRV; (1 server found);; global options: +cmd;; Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30707;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 2;; WARNING: recursion requested but not available

;; QUESTION SECTION:;fries.service.consul. IN SRV

;; ANSWER SECTION:fries.service.consul. 0 IN SRV 1 1 1111 vagrant-ubuntu-trusty-64.node.dc1.consul.fries.service.consul. 0 IN SRV 1 1 2222 vagrant-ubuntu-trusty-64.node.dc1.consul.

;; ADDITIONAL SECTION:vagrant-ubuntu-trusty-64.node.dc1.consul. 0 IN A 192.168.33.10vagrant-ubuntu-trusty-64.node.dc1.consul. 0 IN A 192.168.33.10

;; Query time: 4 msec;; SERVER: 192.168.33.10#8600(192.168.33.10);; WHEN: Fri Jan 29 23:21:22 UTC 2016;; MSG SIZE rcvd: 310

Page 52: Service discovery and configuration provisioning
Page 53: Service discovery and configuration provisioning

Storing values

Page 54: Service discovery and configuration provisioning

# curl -X GET http://192.168.33.10:8500/v1/kv/foo[{"LockIndex":0,"Key":"foo","Flags":128,"Value":"YmFy","CreateIndex":123,"ModifyIndex":130}]

# curl -X PUT -d 'bar' http://192.168.33.10:8500/v1/kv/footrue

# curl -X GET http://192.168.33.10:8500/v1/kv/foo[{"LockIndex":0,"Key":"foo","Flags":0,"Value":"YmFy","CreateIndex":123,"ModifyIndex":123}]

# curl -X PUT -d 'bar' http://192.168.33.10:8500/v1/kv/foo?flags=128true

Page 55: Service discovery and configuration provisioning

<?php require '../vendor/autoload.php'; $sf = new SensioLabs\Consul\ServiceFactory(array('base_url' => 'http://192.168.33.10:8500')); $kv = $sf->get('kv'); $kv->put('foo', 'bar' . time()); $response = $kv->get('foo')->json(); $kv->delete('foo'); // Result data array ( 0 => array ( 'LockIndex' => 0, 'Key' => 'foo', 'Flags' => 0, 'Value' => 'YmFyMTQ1NDA4NTQ3MA==', 'CreateIndex' => 123, 'ModifyIndex' => 147, ), )

Page 56: Service discovery and configuration provisioning

Distributed locks

Page 57: Service discovery and configuration provisioning

<?php require '../vendor/autoload.php'; $sf = new SensioLabs\Consul\ServiceFactory(array('base_url' => 'http://192.168.33.10:8500')); $session = $sf->get('session'); $kv = $sf->get('kv'); // Start a session $sessionId = $session->create()->json()['ID']; // Lock a key / value with the current session $lockAcquired = $kv->put('session/a-lock', 'a value', ['acquire' => $sessionId])->json(); if (false === $lockAcquired) { $session->destroy($sessionId); echo "The lock is already acquire by another node.\n"; exit(1); } # YOUR CRITICAL SECTION CODE HERE... $kv->delete('session/a-lock'); $session->destroy($sessionId);

Page 58: Service discovery and configuration provisioning

Useful to avoid dogpile effect

Page 59: Service discovery and configuration provisioning

Even more useful with leader election

Page 60: Service discovery and configuration provisioning

Possibilities...

Page 61: Service discovery and configuration provisioning
Page 62: Service discovery and configuration provisioning
Page 63: Service discovery and configuration provisioning

Task #1 Replace one search engine to another Without downtime

Page 64: Service discovery and configuration provisioning

<?php $backend = $userId % 100 < $settings->get('search/elastic/access_threshold', 0) ? $container->get('search.elastic') : $container->get('search.sphinx'); $suggestions = $backend->search($query);

# curl -X PUT -d '5' http://192.168.33.10:8500/v1/kv/search/elastic/threshold# curl -X PUT -d '10' http://192.168.33.10:8500/v1/kv/search/elastic/threshold# curl -X PUT -d '15' http://192.168.33.10:8500/v1/kv/search/elastic/threshold# curl -X PUT -d '25' http://192.168.33.10:8500/v1/kv/search/elastic/threshold# curl -X PUT -d '50' http://192.168.33.10:8500/v1/kv/search/elastic/threshold# curl -X PUT -d '75' http://192.168.33.10:8500/v1/kv/search/elastic/threshold# curl -X PUT -d '50' http://192.168.33.10:8500/v1/kv/search/elastic/threshold

Page 65: Service discovery and configuration provisioning

<?php $engine = $userId % 100 < $settings->get('search/elastic/access_threshold') ? 'elastic' : 'sphinx'; $backend = $container->get('search.' . $engine); $minimalQueryLength = $settings->get('search.' . $engine . '.minimal_length', 3); $maximalNumberOfSuggestion = $settings->get('search.' . $engine . '.suggestions_limits', 10); if (length($query) >= $minimalQueryLength) { $suggestions = $backend->search($query, $maximalNumberOfSuggestion); }

Page 66: Service discovery and configuration provisioning

Task #2 Add CPU/memory to the server In the middle of the night

Page 67: Service discovery and configuration provisioning

<?php if ($settings->get('recommendations/enabled')) { # Fetch recommendations for user based on request # ... }

# curl -X PUT -d '0' http://192.168.33.10:8500/v1/kv/recommendations/enabled# halt

# ADD MORE CPU/MEMORY

# curl -X PUT -d '1' http://192.168.33.10:8500/v1/kv/recommendations/enabled

Page 68: Service discovery and configuration provisioning

# curl -X PUT -d '{> "Datacenter": "dc1",> "Node": "vagrant-ubuntu-trusty-64",> "ServiceID": "memcached"> }' http://192.168.33.10:8500/v1/catalog/deregistertrue

# curl -X PUT -d '{> "Datacenter": "dc1",> "Node": "vagrant-ubuntu-trusty-64",> "Address": "192.168.33.10",> "Service": {> "ID": "memcached",> "Service": "memcached",> "Tags": [> "cache"> ],> "Address": "192.168.33.10",> "Port": 11211> }> }' http://192.168.33.10:8500/v1/catalog/registertrue

Page 69: Service discovery and configuration provisioning

<?php require '../vendor/autoload.php'; $sf = new SensioLabs\Consul\ServiceFactory(array( 'base_url' => 'http://192.168.33.10:8500', )); $catalog = $sf->get('catalog'); $serviceDefinitions = $catalog->service('memcached')->json(); $memcached = new Memcache(); foreach ($serviceDefinitions as $serviceDefinition) { $memcached->addserver($serviceDefinition['ServiceAddress'], $serviceDefinition['ServicePort']); }

Page 70: Service discovery and configuration provisioning

Long running background workers

Page 71: Service discovery and configuration provisioning
Page 72: Service discovery and configuration provisioning
Page 73: Service discovery and configuration provisioning

Watch the Watches. React

Page 74: Service discovery and configuration provisioning

host A host B host C host D

agentserver

web app

agent

background worker

agent

background worker

watch for event

make changes & fire event

Page 75: Service discovery and configuration provisioning

API methods

Page 76: Service discovery and configuration provisioning

Agent

/v1/agent/checks /v1/agent/services /v1/agent/members /v1/agent/self /v1/agent/maintenance /v1/agent/join/<address> /v1/agent/force-leave/<node>> /v1/agent/check/register /v1/agent/check/deregister/<checkID> /v1/agent/check/pass/<checkID> /v1/agent/check/warn/<checkID> /v1/agent/check/fail/<checkID> /v1/agent/service/register /v1/agent/service/deregister/<serviceID> /v1/agent/service/maintenance/<serviceID>

Page 77: Service discovery and configuration provisioning

Catalog

/v1/catalog/register /v1/catalog/deregister /v1/catalog/datacenters /v1/catalog/nodes /v1/catalog/services /v1/catalog/service/<service> /v1/catalog/node/<node>

Page 78: Service discovery and configuration provisioning

Health Checks

/v1/health/node/<node> /v1/health/checks/<service> /v1/health/service/<service> /v1/health/state/<state>

Page 79: Service discovery and configuration provisioning

Network coordinates

/v1/coordinate/datacenters /v1/coordinate/nodes

Page 80: Service discovery and configuration provisioning

Key / Values

/v1/kv/<key>

Page 81: Service discovery and configuration provisioning

Events

/v1/event/fire/<name> /v1/event/list

Page 82: Service discovery and configuration provisioning

ACL

/v1/agent/checks /v1/agent/services /v1/agent/members /v1/agent/self /v1/agent/maintenance /v1/agent/join/<address> /v1/agent/force-leave/<node>> /v1/agent/check/register /v1/agent/check/deregister/<checkID> /v1/agent/check/pass/<checkID> /v1/agent/check/warn/<checkID> /v1/agent/check/fail/<checkID> /v1/agent/service/register /v1/agent/service/deregister/<serviceID> /v1/agent/service/maintenance/<serviceID>

Page 83: Service discovery and configuration provisioning

Prepared queries

/v1/query /v1/query/<query> /v1/query/<query or name>/execute

Page 84: Service discovery and configuration provisioning

Sessions

/v1/session/create /v1/session/destroy/<session> /v1/session/info/<session> /v1/session/node/<node> /v1/session/list /v1/session/renew

Page 85: Service discovery and configuration provisioning

Server status

/v1/status/leader /v1/status/peers

Page 86: Service discovery and configuration provisioning

Alternative solutions

Page 87: Service discovery and configuration provisioning
Page 88: Service discovery and configuration provisioning
Page 89: Service discovery and configuration provisioning
Page 90: Service discovery and configuration provisioning
Page 91: Service discovery and configuration provisioning

Choose one or implement your own If you need it. Really need it

Page 92: Service discovery and configuration provisioning

Thanks! Enjoy config management! https://joind.in/talk/198e7

mariuszgil srcministry