From dc9019f48e919a828538de40f5b4ae4aa8ef10b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D9=85=D9=90=D9=8A=D8=B2=D9=8E=D8=A7=D9=86=D9=8F=20=D8=A7?= =?UTF-8?q?=D9=84=D9=92=D8=AF=D9=91=D9=90=D9=8A=D9=86=D9=92=20=D8=B9=D9=8E?= =?UTF-8?q?=D8=A8=D9=92=D8=AF=D9=8F=20=D8=B0=D9=90=D9=8A=D9=92=20=D8=A7?= =?UTF-8?q?=D9=84=D9=92=D8=AC=D9=8E=D9=84=D9=8E=D8=A7=D9=84=D9=90=20=D9=88?= =?UTF-8?q?=D9=8E=20=D8=A7=D9=84=D9=92=D8=A5=D9=90=D9=83=D9=92=D8=B1=D9=8E?= =?UTF-8?q?=D8=A7=D9=85=D9=90?= Date: Wed, 24 Mar 2021 14:45:05 +0400 Subject: [PATCH 1/3] Add request calculation --- Dockerfile | 3 ++- README.md | 9 ++++--- bin/autoscale | 15 ++++++++--- src/Helper/Resource.php | 42 +++++++++++++++++++++++++++++ src/Kubernetes/Nodes.php | 57 ++++++++++++++++++++++++++++++++++++++++ src/Scale.php | 12 ++++++--- 6 files changed, 127 insertions(+), 11 deletions(-) create mode 100644 src/Helper/Resource.php diff --git a/Dockerfile b/Dockerfile index 77e33b5..967c25d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM islamicnetwork/php74:cli +FROM islamicnetwork/php:8.0-cli COPY . /autoscaler/ @@ -12,6 +12,7 @@ ENV LINODE_LKE_CLUSTER_POOL_MINIMUM_NODES "3" ENV AUTOSCALE_TRIGGER "memory" ENV AUTOSCALE_UP_PERCENTAGE "60" ENV AUTOSCALE_DOWN_PERCENTAGE "40" +ENV AUTOSCALE_RESOURCE_REQUEST_PERCENTAGE "80" ENV AUTOSCALE_QUERY_INTERVAL "10" ENV AUTOSCALE_THRESHOLD_COUNT "3" ENV AUTOSCALE_NUMBER_OF_NODES "1" diff --git a/README.md b/README.md index 7221783..a1ba492 100644 --- a/README.md +++ b/README.md @@ -46,9 +46,10 @@ The docker container takes all its configuration via environment variables. Here | AUTOSCALE_TRIGGER | 'cpu' or 'memory' | AUTOSCALE_UP_PERCENTAGE | At what percentage of 'cpu' or 'memory' to scale up the node pool. Example: 65 | AUTOSCALE_DOWN_PERCENTAGE | At what percentage of 'cpu' or 'memory' to scale down the node pool. Example: 40 +| AUTOSCALE_RESOURCE_REQUEST_PERCENTAGE | At what percentage of 'cpu' or 'memory' of the requested / available to scale up or down the cluster. Default: 80 | AUTOSCALE_QUERY_INTERVAL | How many seconds to wait before each call to the Kubernetes API to check CPU and Memory usage. Example: 10 | AUTOSCALE_THRESHOLD_COUNT | After how many consecutive matches of AUTOSCALE_UP_PERCENTAGE or AUTOSCALE_DOWN_PERCENTAGE to scale the cluster up or down. -| AUTOSCALE_NUMBER_OF_NODES | How many nodes to add or remove at one time when scaling the cluster. Example: 1 or 2 or 3 or N +| AUTOSCALE_NUMBER_OF_NODES | How many nodes to add at one time when scaling the cluster. Example: 1 or 2 or 3 or N | AUTOSCALE_WAIT_TIME_AFTER_SCALING | How many seconds to wait after scaling up or down to start checking CPU and Memory. This should be set the to give the cluster enough time to adjust itself with the updated number of nodes. Example: 150 To understand the above assuming we have set the following values. @@ -57,15 +58,15 @@ To understand the above assuming we have set the following values. * AUTOSCALE_UP_PERCENTAGE=30 * AUTOSCALE_QUERY_INTERVAL=10 * AUTOSCALE_THRESHOLD_COUNT=3 -* AUTOSCALE_NUMBER_OF_NODES=1 +* AUTOSCALE_NUMBER_OF_NODES=2 * AUTOSCALE_WAIT_TIME_AFTER_SCALING=180 With this setup, the autoscaler utility will query the Kuberenetes API every 10 seconds. If with 3 consecutive calls -to the API (effectively meaning over 30 seconds), the memory usage is higher than 65%, 1 more node will be added to the +to the API (effectively meaning over 30 seconds), the memory usage is higher than 65%, 2 more nodes will be added to the specified node pool. The utility will wait for 180 seconds and then start querying the API every 10 seconds again. If with 3 consecutive calls to the API (effectively meaning over 30 seconds), the memory usage is lower than 30%, -1 node will be removed from the specified node pool. The utility will wait for 180 seconds and then start +1 node will be removed (**nodes are always removed one at a time to ensure you don't run out of capacity all of a sudden**) from the specified node pool. The utility will wait for 180 seconds and then start querying the API every 10 seconds again. ## Usage diff --git a/bin/autoscale b/bin/autoscale index a29df0f..16f07e1 100644 --- a/bin/autoscale +++ b/bin/autoscale @@ -20,6 +20,7 @@ pcntl_signal(SIGINT, function () { $autoscaleTrigger = getenv('AUTOSCALE_TRIGGER'); // memory or cpu for memory percentage or CPU percentage $autoscaleUpAtUtilisationPercent = getenv('AUTOSCALE_UP_PERCENTAGE'); $autoscaleDownAtUtilisationPercent = getenv('AUTOSCALE_DOWN_PERCENTAGE'); +$autoscaleUpOrDownRequestPercentage = getenv('AUTOSCALE_RESOURCE_REQUEST_PERCENTAGE'); $autoscaleQueryInterval = getenv('AUTOSCALE_QUERY_INTERVAL'); // Seconds. We'll call K8S after every interval to fetch node utilisation metrics $autoscaleThresholdCount = getenv('AUTOSCALE_THRESHOLD_COUNT'); // Number of consecutive times the utilisation percentage should be greater than $autoscaleAtCpuUtilisationPercent or $autoscaleAtMemoryUtilisationPercent to autoscale. $autoscaleNodesToAddOrRemovePerBreach = getenv('AUTOSCALE_NUMBER_OF_NODES'); @@ -63,8 +64,15 @@ while (true) { } $usedPercentage = $autoscaleTrigger == 'cpu' ? $nodes->getUsedCpuPercent() : $nodes->getUsedMemoryPercent(); - $scale = new Scale($autoscaleUpAtUtilisationPercent, $autoscaleDownAtUtilisationPercent, $usedPercentage); - $logger->info(strtoupper($autoscaleTrigger) . ' Scale calculated', ['usedPercentage' => $usedPercentage, 'scaleUpPercentage' => $autoscaleUpAtUtilisationPercent, 'scaleDownPercentage' => $autoscaleDownAtUtilisationPercent]); + $requestedPercentage = $autoscaleTrigger == 'cpu' ? $nodes->getRequestedCpuPercent() : $nodes->getRequestedMemoryPercent(); + $scale = new Scale($autoscaleUpAtUtilisationPercent, $autoscaleDownAtUtilisationPercent, $usedPercentage, $requestedPercentage, $autoscaleUpOrDownRequestPercentage); + $logger->info(strtoupper($autoscaleTrigger) . ' Scale calculated', [ + 'usedPercentage' => $usedPercentage, + 'scaleUpPercentage' => $autoscaleUpAtUtilisationPercent, + 'scaleDownPercentage' => $autoscaleDownAtUtilisationPercent, + 'requestedPercentage' => $requestedPercentage, + 'scaleUporDownRequestPercentage' => $autoscaleUpOrDownRequestPercentage + ]); if ($scale->scaleUp()) { $logger->info('Scale Count: Up'); $counter->up(); @@ -91,7 +99,8 @@ while (true) { if ($currentNodesInPool > $linodeClusterPoolMinimumNodeCount && ($currentNodesInPool - $autoscaleNodesToAddOrRemovePerBreach) >= $linodeClusterPoolMinimumNodeCount) { $logger->alert('Current Nodes in LKE Pool: ' . $currentNodesInPool); $logger->alert("Removing $autoscaleNodesToAddOrRemovePerBreach node(s)..."); - $linode->updateNodeCount($currentNodesInPool - $autoscaleNodesToAddOrRemovePerBreach); + // Scale down only 1 node at a time, this is much safer than scaling down multiple nodes + $linode->updateNodeCount($currentNodesInPool - 1); sleep($autoscaleWaitTimeBetweenScaling); } $logger->alert("Skip downsizing cluster because we are already at the minimum number ($linodeClusterPoolMinimumNodeCount) of nodes or scaling down by $autoscaleNodesToAddOrRemovePerBreach will put us at less than the minimum number."); diff --git a/src/Helper/Resource.php b/src/Helper/Resource.php new file mode 100644 index 0000000..99c7bd1 --- /dev/null +++ b/src/Helper/Resource.php @@ -0,0 +1,42 @@ +client = $client; $this->nodes = $this->client->createList("/api/v1/nodes"); + $this->pods = $this->client->createList("/api/v1/pods"); $this->nodeMetrics = $this->client->createList("/apis/metrics.k8s.io/v1beta1/nodes"); $this->calculateAvailableResources(); $this->calculateUsedResources(); @@ -35,6 +46,22 @@ public function getNodes(): ResourceList return $this->nodes; } + private function calculateRequestedResources(): void + { + $this->requestedCpu = 0; + $this->requestedMemory = 0; + $this->limitCpu = 0; + $this->limitMemory = 0; + foreach ($this->pods->stream() as $pod) { + foreach ($pod['containers'] as $container) { + $this->limitCpu += (float) Resource::getCpuMilliValue($container['resources']['limits']['cpu']); + $this->limitMemory += (float) Resource::getMemoryBytes($container['resources']['limits']['memory']); + $this->requestedCpu += (float) Resource::getCpuMilliValue($container['resources']['requests']['cpu']); + $this->requestedMemory += (float) Resource::getMemoryBytes($container['resources']['requests']['memory']); + } + } + } + private function calculateAvailableResources(): void { $this->availableCpu = 0; @@ -85,4 +112,34 @@ public function getUsedMemoryPercent(): float { return ($this->usedMemory / $this->availableMemory) * 100; } + + public function getRequestedCpu(): float + { + return $this->requestedCpu; + } + + public function getRequestedMemory(): float + { + return $this->requestedMemory; + } + + public function getLimitCpu(): float + { + return $this->limitCpu; + } + + public function getLimitMemory(): float + { + return $this->limitMemory; + } + + public function getRequestedCpuPercent(): float + { + return ($this->requestedCpu / $this->availableCpu) * 100; + } + + public function getRequestedMemoryPercent(): float + { + return ($this->requestedMemory / $this->availableMemory) * 100; + } } \ No newline at end of file diff --git a/src/Scale.php b/src/Scale.php index 7d09a54..90c1588 100644 --- a/src/Scale.php +++ b/src/Scale.php @@ -9,22 +9,28 @@ class Scale public float $thresholdUpPercentage; public float $thresholdDownPercentage; public float $usedPercentage; + public float $requestedPercentage; + public float $thresholdRequestPercentage; - public function __construct(float $thresholdUpPercentage, float $thresholdDownPercentage, float $usedPercentage) + public function __construct(float $thresholdUpPercentage, float $thresholdDownPercentage, float $usedPercentage, float $requestedPercentage, float $thresholdRequestPercentage) { $this->thresholdUpPercentage = $thresholdUpPercentage; $this->thresholdDownPercentage = $thresholdDownPercentage; $this->usedPercentage = $usedPercentage; + $this->requestedPercentage = $requestedPercentage; + $this->thresholdRequestPercentage = $thresholdRequestPercentage; } public function scaleUp() { - return $this->usedPercentage > $this->thresholdUpPercentage; + return $this->usedPercentage > $this->thresholdUpPercentage + || $this->requestedPercentage > $this->thresholdRequestPercentage; } public function scaleDown() { - return $this->usedPercentage < $this->thresholdDownPercentage; + return $this->usedPercentage < $this->thresholdDownPercentage + || $this->requestedPercentage < $this->thresholdRequestPercentage; } } \ No newline at end of file From 195d8ca638d3927910c46512e0ef5bb02de6d9c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D9=85=D9=90=D9=8A=D8=B2=D9=8E=D8=A7=D9=86=D9=8F=20=D8=A7?= =?UTF-8?q?=D9=84=D9=92=D8=AF=D9=91=D9=90=D9=8A=D9=86=D9=92=20=D8=B9=D9=8E?= =?UTF-8?q?=D8=A8=D9=92=D8=AF=D9=8F=20=D8=B0=D9=90=D9=8A=D9=92=20=D8=A7?= =?UTF-8?q?=D9=84=D9=92=D8=AC=D9=8E=D9=84=D9=8E=D8=A7=D9=84=D9=90=20=D9=88?= =?UTF-8?q?=D9=8E=20=D8=A7=D9=84=D9=92=D8=A5=D9=90=D9=83=D9=92=D8=B1=D9=8E?= =?UTF-8?q?=D8=A7=D9=85=D9=90?= Date: Wed, 24 Mar 2021 14:48:47 +0400 Subject: [PATCH 2/3] Update lock file --- composer.lock | 776 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 523 insertions(+), 253 deletions(-) diff --git a/composer.lock b/composer.lock index 0505b83..31111b6 100644 --- a/composer.lock +++ b/composer.lock @@ -45,37 +45,42 @@ } ], "description": "JSONPath implementation for parsing, searching and flattening arrays", + "support": { + "issues": "https://github.com/FlowCommunications/JSONPath/issues", + "source": "https://github.com/FlowCommunications/JSONPath/tree/0.5.0" + }, + "abandoned": "softcreatr/jsonpath", "time": "2019-07-15T17:23:22+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "7.0.1", + "version": "7.3.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "2d9d3c186a6637a43193e66b097c50e4451eaab2" + "reference": "7008573787b430c1c1f650e3722d9bba59967628" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/2d9d3c186a6637a43193e66b097c50e4451eaab2", - "reference": "2d9d3c186a6637a43193e66b097c50e4451eaab2", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7008573787b430c1c1f650e3722d9bba59967628", + "reference": "7008573787b430c1c1f650e3722d9bba59967628", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.6.1", - "php": "^7.2.5", + "guzzlehttp/promises": "^1.4", + "guzzlehttp/psr7": "^1.7 || ^2.0", + "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0" }, "provide": { "psr/http-client-implementation": "1.0" }, "require-dev": { - "ergebnis/composer-normalize": "^2.0", + "bamarni/composer-bin-plugin": "^1.4.1", "ext-curl": "*", - "php-http/client-integration-tests": "dev-phpunit8", - "phpunit/phpunit": "^8.5.5", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.5 || ^9.3.5", "psr/log": "^1.1" }, "suggest": { @@ -86,7 +91,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "7.0-dev" + "dev-master": "7.3-dev" } }, "autoload": { @@ -126,27 +131,49 @@ "rest", "web service" ], - "time": "2020-06-27T10:33:25+00:00" + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.3.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://github.com/alexeyshockov", + "type": "github" + }, + { + "url": "https://github.com/gmponos", + "type": "github" + } + ], + "time": "2021-03-23T11:33:13+00:00" }, { "name": "guzzlehttp/promises", - "version": "v1.3.1", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "url": "https://api.github.com/repos/guzzle/promises/zipball/8e7d04f1f6450fef59366c399cfad4b9383aa30d", + "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d", "shasum": "" }, "require": { - "php": ">=5.5.0" + "php": ">=5.5" }, "require-dev": { - "phpunit/phpunit": "^4.0" + "symfony/phpunit-bridge": "^4.4 || ^5.1" }, "type": "library", "extra": { @@ -177,20 +204,24 @@ "keywords": [ "promise" ], - "time": "2016-12-20T10:07:11+00:00" + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.4.1" + }, + "time": "2021-03-07T09:25:29+00:00" }, { "name": "guzzlehttp/psr7", - "version": "1.6.1", + "version": "1.8.1", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "239400de7a173fe9901b9ac7c06497751f00727a" + "reference": "35ea11d335fd638b5882ff1725228b3d35496ab1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", - "reference": "239400de7a173fe9901b9ac7c06497751f00727a", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/35ea11d335fd638b5882ff1725228b3d35496ab1", + "reference": "35ea11d335fd638b5882ff1725228b3d35496ab1", "shasum": "" }, "require": { @@ -203,15 +234,15 @@ }, "require-dev": { "ext-zlib": "*", - "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" }, "suggest": { - "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6-dev" + "dev-master": "1.7-dev" } }, "autoload": { @@ -248,20 +279,24 @@ "uri", "url" ], - "time": "2019-07-01T23:21:34+00:00" + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/1.8.1" + }, + "time": "2021-03-21T16:25:00+00:00" }, { "name": "monolog/monolog", - "version": "2.1.1", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "f9eee5cec93dfb313a38b6b288741e84e53f02d5" + "reference": "1cb1cde8e8dd0f70cc0fe51354a59acad9302084" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f9eee5cec93dfb313a38b6b288741e84e53f02d5", - "reference": "f9eee5cec93dfb313a38b6b288741e84e53f02d5", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/1cb1cde8e8dd0f70cc0fe51354a59acad9302084", + "reference": "1cb1cde8e8dd0f70cc0fe51354a59acad9302084", "shasum": "" }, "require": { @@ -274,16 +309,17 @@ "require-dev": { "aws/aws-sdk-php": "^2.4.9 || ^3.0", "doctrine/couchdb": "~1.0@dev", - "elasticsearch/elasticsearch": "^6.0", + "elasticsearch/elasticsearch": "^7", "graylog2/gelf-php": "^1.4.2", + "mongodb/mongodb": "^1.8", "php-amqplib/php-amqplib": "~2.4", "php-console/php-console": "^3.1.3", - "php-parallel-lint/php-parallel-lint": "^1.0", "phpspec/prophecy": "^1.6.1", + "phpstan/phpstan": "^0.12.59", "phpunit/phpunit": "^8.5", "predis/predis": "^1.1", "rollbar/rollbar": "^1.3", - "ruflin/elastica": ">=0.90 <3.0", + "ruflin/elastica": ">=0.90 <7.0.1", "swiftmailer/swiftmailer": "^5.3|^6.0" }, "suggest": { @@ -303,7 +339,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-main": "2.x-dev" } }, "autoload": { @@ -319,16 +355,20 @@ { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" + "homepage": "https://seld.be" } ], "description": "Sends your logs to files, sockets, inboxes, databases and various web services", - "homepage": "http://github.com/Seldaek/monolog", + "homepage": "https://github.com/Seldaek/monolog", "keywords": [ "log", "logging", "psr-3" ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/2.2.0" + }, "funding": [ { "url": "https://github.com/Seldaek", @@ -339,7 +379,7 @@ "type": "tidelift" } ], - "time": "2020-07-23T08:41:23+00:00" + "time": "2020-12-14T13:15:25+00:00" }, { "name": "psr/http-client", @@ -388,6 +428,9 @@ "psr", "psr-18" ], + "support": { + "source": "https://github.com/php-fig/http-client/tree/master" + }, "time": "2020-06-29T06:28:15+00:00" }, { @@ -438,6 +481,9 @@ "request", "response" ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, "time": "2016-08-06T14:39:51+00:00" }, { @@ -485,6 +531,9 @@ "psr", "psr-3" ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.3" + }, "time": "2020-03-23T09:12:05+00:00" }, { @@ -525,20 +574,24 @@ } ], "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, "time": "2019-03-08T08:55:37+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.1.3", + "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "5e20b83385a77593259c9f8beb2c43cd03b2ac14" + "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5e20b83385a77593259c9f8beb2c43cd03b2ac14", - "reference": "5e20b83385a77593259c9f8beb2c43cd03b2ac14", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665", + "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665", "shasum": "" }, "require": { @@ -547,7 +600,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" }, "thanks": { "name": "symfony/contracts", @@ -575,6 +628,9 @@ ], "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/master" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -589,24 +645,24 @@ "type": "tidelift" } ], - "time": "2020-06-06T08:49:21+00:00" + "time": "2020-09-07T11:33:47+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.18.1", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "1c302646f6efc070cd46856e600e5e0684d6b454" + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454", - "reference": "1c302646f6efc070cd46856e600e5e0684d6b454", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-ctype": "For best performance" @@ -614,7 +670,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -651,6 +707,9 @@ "polyfill", "portable" ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -665,20 +724,20 @@ "type": "tidelift" } ], - "time": "2020-07-14T12:35:20+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/yaml", - "version": "v5.1.3", + "version": "v5.2.5", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "ea342353a3ef4f453809acc4ebc55382231d4d23" + "reference": "298a08ddda623485208506fcee08817807a251dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/ea342353a3ef4f453809acc4ebc55382231d4d23", - "reference": "ea342353a3ef4f453809acc4ebc55382231d4d23", + "url": "https://api.github.com/repos/symfony/yaml/zipball/298a08ddda623485208506fcee08817807a251dd", + "reference": "298a08ddda623485208506fcee08817807a251dd", "shasum": "" }, "require": { @@ -699,11 +758,6 @@ "Resources/bin/yaml-lint" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Yaml\\": "" @@ -726,8 +780,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Yaml Component", + "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v5.2.5" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -742,7 +799,7 @@ "type": "tidelift" } ], - "time": "2020-05-20T17:43:50+00:00" + "time": "2021-03-06T07:59:01+00:00" }, { "name": "travisghansen/kubernetes-client-php", @@ -793,42 +850,41 @@ "php", "rest" ], + "support": { + "issues": "https://github.com/travisghansen/kubernetes-client-php/issues", + "source": "https://github.com/travisghansen/kubernetes-client-php/tree/master" + }, "time": "2020-04-07T03:42:07+00:00" } ], "packages-dev": [ { "name": "doctrine/instantiator", - "version": "1.3.1", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea" + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f350df0268e904597e3bd9c4685c53e0e333feea", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^6.0", + "doctrine/coding-standard": "^8.0", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.13", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-shim": "^0.11", - "phpunit/phpunit": "^7.0" + "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" @@ -842,7 +898,7 @@ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "homepage": "https://ocramius.github.io/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", @@ -851,6 +907,10 @@ "constructor", "instantiate" ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -865,20 +925,20 @@ "type": "tidelift" } ], - "time": "2020-05-29T17:27:14+00:00" + "time": "2020-11-10T18:47:58+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.10.1", + "version": "1.10.2", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", "shasum": "" }, "require": { @@ -913,38 +973,43 @@ "object", "object graph" ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + }, "funding": [ { "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", "type": "tidelift" } ], - "time": "2020-06-29T13:22:24+00:00" + "time": "2020-11-13T09:40:50+00:00" }, { "name": "phar-io/manifest", - "version": "1.0.3", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", + "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", "shasum": "" }, "require": { "ext-dom": "*", "ext-phar": "*", - "phar-io/version": "^2.0", - "php": "^5.6 || ^7.0" + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -974,24 +1039,28 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2018-07-08T19:23:20+00:00" + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/master" + }, + "time": "2020-06-27T14:33:11+00:00" }, { "name": "phar-io/version", - "version": "2.0.1", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + "reference": "bae7c545bef187884426f042434e561ab1ddb182" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182", + "reference": "bae7c545bef187884426f042434e561ab1ddb182", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { @@ -1021,7 +1090,11 @@ } ], "description": "Library for handling version information and constraints", - "time": "2018-07-08T19:19:57+00:00" + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.1.0" + }, + "time": "2021-02-23T14:00:09+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -1070,20 +1143,24 @@ "reflection", "static analysis" ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, "time": "2020-06-27T09:03:43+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.2.0", + "version": "5.2.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "3170448f5769fe19f456173d833734e0ff1b84df" + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/3170448f5769fe19f456173d833734e0ff1b84df", - "reference": "3170448f5769fe19f456173d833734e0ff1b84df", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", "shasum": "" }, "require": { @@ -1122,20 +1199,24 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2020-07-20T20:05:34+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" + }, + "time": "2020-09-03T19:13:55+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.3.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "e878a14a65245fbe78f8080eba03b47c3b705651" + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e878a14a65245fbe78f8080eba03b47c3b705651", - "reference": "e878a14a65245fbe78f8080eba03b47c3b705651", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", "shasum": "" }, "require": { @@ -1167,32 +1248,36 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2020-06-27T10:12:23+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0" + }, + "time": "2020-09-17T18:55:26+00:00" }, { "name": "phpspec/prophecy", - "version": "1.11.1", + "version": "1.13.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160" + "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b20034be5efcdab4fb60ca3a29cba2949aead160", - "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea", + "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2", - "php": "^7.2", - "phpdocumentor/reflection-docblock": "^5.0", + "php": "^7.2 || ~8.0, <8.1", + "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0", "sebastian/recursion-context": "^3.0 || ^4.0" }, "require-dev": { "phpspec/phpspec": "^6.0", - "phpunit/phpunit": "^8.0" + "phpunit/phpunit": "^8.0 || ^9.0" }, "type": "library", "extra": { @@ -1230,29 +1315,33 @@ "spy", "stub" ], - "time": "2020-07-08T12:44:21+00:00" + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/1.13.0" + }, + "time": "2021-03-17T13:42:18+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "7.0.10", + "version": "7.0.14", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf" + "reference": "bb7c9a210c72e4709cdde67f8b7362f672f2225c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f1884187926fbb755a9aaf0b3836ad3165b478bf", - "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/bb7c9a210c72e4709cdde67f8b7362f672f2225c", + "reference": "bb7c9a210c72e4709cdde67f8b7362f672f2225c", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", - "php": "^7.2", + "php": ">=7.2", "phpunit/php-file-iterator": "^2.0.2", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^3.1.1", + "phpunit/php-token-stream": "^3.1.1 || ^4.0", "sebastian/code-unit-reverse-lookup": "^1.0.1", "sebastian/environment": "^4.2.2", "sebastian/version": "^2.0.1", @@ -1293,27 +1382,37 @@ "testing", "xunit" ], - "time": "2019-11-20T13:55:58+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/7.0.14" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-12-02T13:39:03+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "050bedf145a257b1ff02746c31894800e5122946" + "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", - "reference": "050bedf145a257b1ff02746c31894800e5122946", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/4b49fb70f067272b659ef0174ff9ca40fdaa6357", + "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^7.1" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { @@ -1343,7 +1442,17 @@ "filesystem", "iterator" ], - "time": "2018-09-13T20:33:42+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:25:21+00:00" }, { "name": "phpunit/php-text-template", @@ -1384,27 +1493,31 @@ "keywords": [ "template" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" + }, "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", - "version": "2.1.2", + "version": "2.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" + "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", - "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662", + "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { @@ -1433,33 +1546,43 @@ "keywords": [ "timer" ], - "time": "2019-06-07T04:22:29+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:20:02+00:00" }, { "name": "phpunit/php-token-stream", - "version": "3.1.1", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff" + "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff", - "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/a853a0e183b9db7eed023d7933a858fa1c8d25a3", + "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": "^7.1" + "php": "^7.3 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1482,43 +1605,54 @@ "keywords": [ "tokenizer" ], - "time": "2019-09-17T06:23:10+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", + "source": "https://github.com/sebastianbergmann/php-token-stream/tree/master" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "abandoned": true, + "time": "2020-08-04T08:28:15+00:00" }, { "name": "phpunit/phpunit", - "version": "8.5.8", + "version": "8.5.15", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "34c18baa6a44f1d1fbf0338907139e9dce95b997" + "reference": "038d4196d8e8cb405cd5e82cedfe413ad6eef9ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/34c18baa6a44f1d1fbf0338907139e9dce95b997", - "reference": "34c18baa6a44f1d1fbf0338907139e9dce95b997", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/038d4196d8e8cb405cd5e82cedfe413ad6eef9ef", + "reference": "038d4196d8e8cb405cd5e82cedfe413ad6eef9ef", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.2.0", + "doctrine/instantiator": "^1.3.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.9.1", - "phar-io/manifest": "^1.0.3", - "phar-io/version": "^2.0.1", - "php": "^7.2", - "phpspec/prophecy": "^1.8.1", - "phpunit/php-code-coverage": "^7.0.7", + "myclabs/deep-copy": "^1.10.0", + "phar-io/manifest": "^2.0.1", + "phar-io/version": "^3.0.2", + "php": ">=7.2", + "phpspec/prophecy": "^1.10.3", + "phpunit/php-code-coverage": "^7.0.12", "phpunit/php-file-iterator": "^2.0.2", "phpunit/php-text-template": "^1.2.1", "phpunit/php-timer": "^2.1.2", "sebastian/comparator": "^3.0.2", "sebastian/diff": "^3.0.2", - "sebastian/environment": "^4.2.2", - "sebastian/exporter": "^3.1.1", + "sebastian/environment": "^4.2.3", + "sebastian/exporter": "^3.1.2", "sebastian/global-state": "^3.0.0", "sebastian/object-enumerator": "^3.0.3", "sebastian/resource-operations": "^2.0.1", @@ -1565,6 +1699,10 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.15" + }, "funding": [ { "url": "https://phpunit.de/donate.html", @@ -1575,27 +1713,27 @@ "type": "github" } ], - "time": "2020-06-22T07:06:58+00:00" + "time": "2021-03-17T07:27:54+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": ">=5.6" }, "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { @@ -1620,29 +1758,39 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:15:22+00:00" }, { "name": "sebastian/comparator", - "version": "3.0.2", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" + "reference": "1071dfcef776a57013124ff35e1fc41ccd294758" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", - "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758", + "reference": "1071dfcef776a57013124ff35e1fc41ccd294758", "shasum": "" }, "require": { - "php": "^7.1", + "php": ">=7.1", "sebastian/diff": "^3.0", "sebastian/exporter": "^3.1" }, "require-dev": { - "phpunit/phpunit": "^7.1" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { @@ -1660,6 +1808,10 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -1671,10 +1823,6 @@ { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" } ], "description": "Provides the functionality to compare PHP values for equality", @@ -1684,24 +1832,34 @@ "compare", "equality" ], - "time": "2018-07-12T15:12:46+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:04:30+00:00" }, { "name": "sebastian/diff", - "version": "3.0.2", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" + "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", - "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211", + "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { "phpunit/phpunit": "^7.5 || ^8.0", @@ -1723,13 +1881,13 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" } ], "description": "Diff implementation", @@ -1740,24 +1898,34 @@ "unidiff", "unified diff" ], - "time": "2019-02-04T06:01:07+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:59:04+00:00" }, { "name": "sebastian/environment", - "version": "4.2.3", + "version": "4.2.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368" + "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368", - "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", + "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { "phpunit/phpunit": "^7.5" @@ -1793,24 +1961,34 @@ "environment", "hhvm" ], - "time": "2019-11-20T08:46:58+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:53:42+00:00" }, { "name": "sebastian/exporter", - "version": "3.1.2", + "version": "3.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" + "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/6b853149eab67d4da22291d36f5b0631c0fd856e", + "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e", "shasum": "" }, "require": { - "php": "^7.0", + "php": ">=7.0", "sebastian/recursion-context": "^3.0" }, "require-dev": { @@ -1860,24 +2038,34 @@ "export", "exporter" ], - "time": "2019-09-14T09:02:43+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:47:53+00:00" }, { "name": "sebastian/global-state", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4" + "reference": "474fb9edb7ab891665d3bfc6317f42a0a150454b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", - "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/474fb9edb7ab891665d3bfc6317f42a0a150454b", + "reference": "474fb9edb7ab891665d3bfc6317f42a0a150454b", "shasum": "" }, "require": { - "php": "^7.2", + "php": ">=7.2", "sebastian/object-reflector": "^1.1.1", "sebastian/recursion-context": "^3.0" }, @@ -1914,24 +2102,34 @@ "keywords": [ "global state" ], - "time": "2019-02-01T05:30:01+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:43:24+00:00" }, { "name": "sebastian/object-enumerator", - "version": "3.0.3", + "version": "3.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", + "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", "shasum": "" }, "require": { - "php": "^7.0", + "php": ">=7.0", "sebastian/object-reflector": "^1.1.1", "sebastian/recursion-context": "^3.0" }, @@ -1961,24 +2159,34 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:40:27+00:00" }, { "name": "sebastian/object-reflector", - "version": "1.1.1", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" + "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", + "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" @@ -2006,24 +2214,34 @@ ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:37:18+00:00" }, { "name": "sebastian/recursion-context", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", + "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" @@ -2044,14 +2262,14 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, { "name": "Adam Harvey", "email": "aharvey@php.net" @@ -2059,24 +2277,34 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:34:24+00:00" }, { "name": "sebastian/resource-operations", - "version": "2.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" + "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", - "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3", + "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "type": "library", "extra": { @@ -2101,24 +2329,34 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2018-10-04T04:07:39+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:30:19+00:00" }, { "name": "sebastian/type", - "version": "1.1.3", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3" + "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/3aaaa15fa71d27650d62a948be022fe3b48541a3", - "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/0150cfbc4495ed2df3872fb31b26781e4e077eb4", + "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4", "shasum": "" }, "require": { - "php": "^7.2" + "php": ">=7.2" }, "require-dev": { "phpunit/phpunit": "^8.2" @@ -2147,7 +2385,17 @@ ], "description": "Collection of value objects that represent the types of the PHP type system", "homepage": "https://github.com/sebastianbergmann/type", - "time": "2019-07-02T08:10:15+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/1.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:25:11+00:00" }, { "name": "sebastian/version", @@ -2190,20 +2438,24 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/master" + }, "time": "2016-10-03T07:35:21+00:00" }, { "name": "squizlabs/php_codesniffer", - "version": "3.5.5", + "version": "3.5.8", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "73e2e7f57d958e7228fce50dc0c61f58f017f9f6" + "reference": "9d583721a7157ee997f235f327de038e7ea6dac4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/73e2e7f57d958e7228fce50dc0c61f58f017f9f6", - "reference": "73e2e7f57d958e7228fce50dc0c61f58f017f9f6", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/9d583721a7157ee997f235f327de038e7ea6dac4", + "reference": "9d583721a7157ee997f235f327de038e7ea6dac4", "shasum": "" }, "require": { @@ -2241,7 +2493,12 @@ "phpcs", "standards" ], - "time": "2020-04-17T01:09:41+00:00" + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, + "time": "2020-10-23T02:01:07+00:00" }, { "name": "theseer/tokenizer", @@ -2281,6 +2538,10 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/master" + }, "funding": [ { "url": "https://github.com/theseer", @@ -2291,30 +2552,35 @@ }, { "name": "webmozart/assert", - "version": "1.9.1", + "version": "1.10.0", "source": { "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + "url": "https://github.com/webmozarts/assert.git", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0 || ^8.0", + "php": "^7.2 || ^8.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<3.9.1" + "vimeo/psalm": "<4.6.1 || 4.6.2" }, "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" + "phpunit/phpunit": "^8.5.13" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" @@ -2336,7 +2602,11 @@ "check", "validate" ], - "time": "2020-07-08T17:02:28+00:00" + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.10.0" + }, + "time": "2021-03-09T10:59:23+00:00" } ], "aliases": [], @@ -2346,5 +2616,5 @@ "prefer-lowest": false, "platform": [], "platform-dev": [], - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.0.0" } From a640b8338e2e856c9988042da0704d3c30ccf27b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D9=85=D9=90=D9=8A=D8=B2=D9=8E=D8=A7=D9=86=D9=8F=20=D8=A7?= =?UTF-8?q?=D9=84=D9=92=D8=AF=D9=91=D9=90=D9=8A=D9=86=D9=92=20=D8=B9=D9=8E?= =?UTF-8?q?=D8=A8=D9=92=D8=AF=D9=8F=20=D8=B0=D9=90=D9=8A=D9=92=20=D8=A7?= =?UTF-8?q?=D9=84=D9=92=D8=AC=D9=8E=D9=84=D9=8E=D8=A7=D9=84=D9=90=20=D9=88?= =?UTF-8?q?=D9=8E=20=D8=A7=D9=84=D9=92=D8=A5=D9=90=D9=83=D9=92=D8=B1=D9=8E?= =?UTF-8?q?=D8=A7=D9=85=D9=90?= Date: Wed, 24 Mar 2021 22:10:25 +0400 Subject: [PATCH 3/3] Add request scaling --- Dockerfile | 3 ++- README.md | 11 ++++++++--- bin/autoscale | 8 +++++--- src/Kubernetes/Nodes.php | 23 ++++++++++++++++------- src/Scale.php | 12 +++++++----- tests/Unit/ScaleTest.php | 14 +++++++++++--- 6 files changed, 49 insertions(+), 22 deletions(-) diff --git a/Dockerfile b/Dockerfile index 967c25d..686369c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,8 @@ ENV LINODE_LKE_CLUSTER_POOL_MINIMUM_NODES "3" ENV AUTOSCALE_TRIGGER "memory" ENV AUTOSCALE_UP_PERCENTAGE "60" ENV AUTOSCALE_DOWN_PERCENTAGE "40" -ENV AUTOSCALE_RESOURCE_REQUEST_PERCENTAGE "80" +ENV AUTOSCALE_RESOURCE_REQUEST_UP_PERCENTAGE "80" +ENV AUTOSCALE_RESOURCE_REQUEST_DOWN_PERCENTAGE "70" ENV AUTOSCALE_QUERY_INTERVAL "10" ENV AUTOSCALE_THRESHOLD_COUNT "3" ENV AUTOSCALE_NUMBER_OF_NODES "1" diff --git a/README.md b/README.md index a1ba492..6343f26 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,8 @@ The docker container takes all its configuration via environment variables. Here | AUTOSCALE_TRIGGER | 'cpu' or 'memory' | AUTOSCALE_UP_PERCENTAGE | At what percentage of 'cpu' or 'memory' to scale up the node pool. Example: 65 | AUTOSCALE_DOWN_PERCENTAGE | At what percentage of 'cpu' or 'memory' to scale down the node pool. Example: 40 -| AUTOSCALE_RESOURCE_REQUEST_PERCENTAGE | At what percentage of 'cpu' or 'memory' of the requested / available to scale up or down the cluster. Default: 80 +| AUTOSCALE_RESOURCE_REQUEST_UP_PERCENTAGE | At what percentage of 'cpu' or 'memory' of the requested / available to scale up the cluster. Default: 80 +| AUTOSCALE_RESOURCE_REQUEST_DOWN_PERCENTAGE | At what percentage of 'cpu' or 'memory' of the requested / available to scale down the cluster. Default: 70 | AUTOSCALE_QUERY_INTERVAL | How many seconds to wait before each call to the Kubernetes API to check CPU and Memory usage. Example: 10 | AUTOSCALE_THRESHOLD_COUNT | After how many consecutive matches of AUTOSCALE_UP_PERCENTAGE or AUTOSCALE_DOWN_PERCENTAGE to scale the cluster up or down. | AUTOSCALE_NUMBER_OF_NODES | How many nodes to add at one time when scaling the cluster. Example: 1 or 2 or 3 or N @@ -56,16 +57,18 @@ To understand the above assuming we have set the following values. * AUTOSCALE_TRIGGER=memory * AUTOSCALE_UP_PERCENTAGE=65 * AUTOSCALE_UP_PERCENTAGE=30 +* AUTOSCALE_RESOURCE_REQUEST_UP_PERCENTAGE=80 +* AUTOSCALE_RESOURCE_REQUEST_DOWN_PERCENTAGE=80 * AUTOSCALE_QUERY_INTERVAL=10 * AUTOSCALE_THRESHOLD_COUNT=3 * AUTOSCALE_NUMBER_OF_NODES=2 * AUTOSCALE_WAIT_TIME_AFTER_SCALING=180 With this setup, the autoscaler utility will query the Kuberenetes API every 10 seconds. If with 3 consecutive calls -to the API (effectively meaning over 30 seconds), the memory usage is higher than 65%, 2 more nodes will be added to the +to the API (effectively meaning over 30 seconds), the memory usage is higher than 65% or the requested memory exceeds 80% of the total memory available on the cluster, 2 more nodes will be added to the specified node pool. The utility will wait for 180 seconds and then start querying the API every 10 seconds again. -If with 3 consecutive calls to the API (effectively meaning over 30 seconds), the memory usage is lower than 30%, +If with 3 consecutive calls to the API (effectively meaning over 30 seconds), the memory usage is lower than 30% or the requested memory is below 80% of the total memory available on the cluster, 1 node will be removed (**nodes are always removed one at a time to ensure you don't run out of capacity all of a sudden**) from the specified node pool. The utility will wait for 180 seconds and then start querying the API every 10 seconds again. @@ -83,6 +86,8 @@ docker run -v ~/.kube/config:/root/.kube/config \ -e AUTOSCALE_TRIGGER='cpu' \ -e AUTOSCALE_UP_PERCENTAGE='60' \ -e AUTOSCALE_DOWN_PERCENTAGE='30' \ +-e AUTOSCALE_RESOURCE_REQUEST_UP_PERCENTAGE='70' \ +-e AUTOSCALE_RESOURCE_REQUEST_DOWN_PERCENTAGE='70' \ -e AUTOSCALE_QUERY_INTERVAL='10' \ -e AUTOSCALE_THRESHOLD_COUNT='3' \ -e AUTOSCALE_NUMBER_OF_NODES='1' \ diff --git a/bin/autoscale b/bin/autoscale index 16f07e1..464839b 100644 --- a/bin/autoscale +++ b/bin/autoscale @@ -20,7 +20,8 @@ pcntl_signal(SIGINT, function () { $autoscaleTrigger = getenv('AUTOSCALE_TRIGGER'); // memory or cpu for memory percentage or CPU percentage $autoscaleUpAtUtilisationPercent = getenv('AUTOSCALE_UP_PERCENTAGE'); $autoscaleDownAtUtilisationPercent = getenv('AUTOSCALE_DOWN_PERCENTAGE'); -$autoscaleUpOrDownRequestPercentage = getenv('AUTOSCALE_RESOURCE_REQUEST_PERCENTAGE'); +$autoscaleUpRequestPercentage = getenv('AUTOSCALE_RESOURCE_REQUEST_UP_PERCENTAGE'); +$autoscaleDownRequestPercentage = getenv('AUTOSCALE_RESOURCE_REQUEST_DOWN_PERCENTAGE'); $autoscaleQueryInterval = getenv('AUTOSCALE_QUERY_INTERVAL'); // Seconds. We'll call K8S after every interval to fetch node utilisation metrics $autoscaleThresholdCount = getenv('AUTOSCALE_THRESHOLD_COUNT'); // Number of consecutive times the utilisation percentage should be greater than $autoscaleAtCpuUtilisationPercent or $autoscaleAtMemoryUtilisationPercent to autoscale. $autoscaleNodesToAddOrRemovePerBreach = getenv('AUTOSCALE_NUMBER_OF_NODES'); @@ -65,13 +66,14 @@ while (true) { $usedPercentage = $autoscaleTrigger == 'cpu' ? $nodes->getUsedCpuPercent() : $nodes->getUsedMemoryPercent(); $requestedPercentage = $autoscaleTrigger == 'cpu' ? $nodes->getRequestedCpuPercent() : $nodes->getRequestedMemoryPercent(); - $scale = new Scale($autoscaleUpAtUtilisationPercent, $autoscaleDownAtUtilisationPercent, $usedPercentage, $requestedPercentage, $autoscaleUpOrDownRequestPercentage); + $scale = new Scale($autoscaleUpAtUtilisationPercent, $autoscaleDownAtUtilisationPercent, $usedPercentage, $requestedPercentage, $autoscaleUpRequestPercentage, $autoscaleDownRequestPercentage); $logger->info(strtoupper($autoscaleTrigger) . ' Scale calculated', [ 'usedPercentage' => $usedPercentage, 'scaleUpPercentage' => $autoscaleUpAtUtilisationPercent, 'scaleDownPercentage' => $autoscaleDownAtUtilisationPercent, 'requestedPercentage' => $requestedPercentage, - 'scaleUporDownRequestPercentage' => $autoscaleUpOrDownRequestPercentage + 'scaleUpRequestPercentage' => $autoscaleUpRequestPercentage, + 'scaleDownRequestPercentage' => $autoscaleDownRequestPercentage ]); if ($scale->scaleUp()) { $logger->info('Scale Count: Up'); diff --git a/src/Kubernetes/Nodes.php b/src/Kubernetes/Nodes.php index 0917bad..389b546 100644 --- a/src/Kubernetes/Nodes.php +++ b/src/Kubernetes/Nodes.php @@ -39,6 +39,7 @@ public function __construct(Client $client) $this->nodeMetrics = $this->client->createList("/apis/metrics.k8s.io/v1beta1/nodes"); $this->calculateAvailableResources(); $this->calculateUsedResources(); + $this->calculateRequestedResources(); } public function getNodes(): ResourceList @@ -53,11 +54,19 @@ private function calculateRequestedResources(): void $this->limitCpu = 0; $this->limitMemory = 0; foreach ($this->pods->stream() as $pod) { - foreach ($pod['containers'] as $container) { - $this->limitCpu += (float) Resource::getCpuMilliValue($container['resources']['limits']['cpu']); - $this->limitMemory += (float) Resource::getMemoryBytes($container['resources']['limits']['memory']); - $this->requestedCpu += (float) Resource::getCpuMilliValue($container['resources']['requests']['cpu']); - $this->requestedMemory += (float) Resource::getMemoryBytes($container['resources']['requests']['memory']); + foreach ($pod['spec']['containers'] as $container) { + $limitCpu = isset($container['resources']['limits']['cpu']) ? $container['resources']['limits']['cpu'] : 0; + $limitMemory = isset($container['resources']['limits']['memory']) ? $container['resources']['limits']['memory'] : 0; + $requestedCpu = isset($container['resources']['requests']['cpu']) ? $container['resources']['requests']['cpu'] : 0; + $requestedMemory = isset($container['resources']['requests']['memory']) ? $container['resources']['requests']['memory'] : 0; + $this->limitCpu += (float) Resource::getCpuMilliValue($limitCpu); + $this->limitMemory += (float) Resource::getMemoryBytes($limitMemory); + $this->requestedCpu += (float) Resource::getCpuMilliValue($requestedCpu); + $this->requestedMemory += (float) Resource::getMemoryBytes($requestedMemory); + $limitCpu = 0; + $limitMemory = 0; + $requestedCpu = 0; + $requestedMemory = 0; } } } @@ -135,11 +144,11 @@ public function getLimitMemory(): float public function getRequestedCpuPercent(): float { - return ($this->requestedCpu / $this->availableCpu) * 100; + return ($this->requestedCpu / ($this->availableCpu * 1000)) * 100; } public function getRequestedMemoryPercent(): float { - return ($this->requestedMemory / $this->availableMemory) * 100; + return ($this->requestedMemory / ($this->availableMemory / 1000)) * 100; } } \ No newline at end of file diff --git a/src/Scale.php b/src/Scale.php index 90c1588..61c1f7c 100644 --- a/src/Scale.php +++ b/src/Scale.php @@ -10,27 +10,29 @@ class Scale public float $thresholdDownPercentage; public float $usedPercentage; public float $requestedPercentage; - public float $thresholdRequestPercentage; + public float $thresholdRequestUpPercentage; + public float $thresholdRequestDownPercentage; - public function __construct(float $thresholdUpPercentage, float $thresholdDownPercentage, float $usedPercentage, float $requestedPercentage, float $thresholdRequestPercentage) + public function __construct(float $thresholdUpPercentage, float $thresholdDownPercentage, float $usedPercentage, float $requestedPercentage, float $thresholdRequestUpPercentage, float $thresholdRequestDownPercentage) { $this->thresholdUpPercentage = $thresholdUpPercentage; $this->thresholdDownPercentage = $thresholdDownPercentage; $this->usedPercentage = $usedPercentage; $this->requestedPercentage = $requestedPercentage; - $this->thresholdRequestPercentage = $thresholdRequestPercentage; + $this->thresholdRequestUpPercentage = $thresholdRequestUpPercentage; + $this->thresholdRequestDownPercentage = $thresholdRequestDownPercentage; } public function scaleUp() { return $this->usedPercentage > $this->thresholdUpPercentage - || $this->requestedPercentage > $this->thresholdRequestPercentage; + || $this->requestedPercentage > $this->thresholdRequestUpPercentage; } public function scaleDown() { return $this->usedPercentage < $this->thresholdDownPercentage - || $this->requestedPercentage < $this->thresholdRequestPercentage; + || $this->requestedPercentage < $this->thresholdRequestDownPercentage; } } \ No newline at end of file diff --git a/tests/Unit/ScaleTest.php b/tests/Unit/ScaleTest.php index 615b887..8d81e8e 100644 --- a/tests/Unit/ScaleTest.php +++ b/tests/Unit/ScaleTest.php @@ -12,15 +12,23 @@ class ScaleTest extends TestCase */ public function testScale() { - $scale = new Scale(65, 30, 50); + $scale = new Scale(65, 30, 50, 60, 70, 55); $this->assertFalse($scale->scaleDown()); $this->assertFalse($scale->scaleUp()); - $scale = new Scale(65, 30, 67); + $scale = new Scale(65, 30, 67, 60, 70, 60); $this->assertFalse($scale->scaleDown()); $this->assertTrue($scale->scaleUp()); - $scale = new Scale(65, 30, 29); + $scale = new Scale(65, 30, 63, 70, 60, 50); + $this->assertFalse($scale->scaleDown()); + $this->assertTrue($scale->scaleUp()); + + $scale = new Scale(65, 30, 29, 70, 80, 75); + $this->assertTrue($scale->scaleDown()); + $this->assertFalse($scale->scaleUp()); + + $scale = new Scale(65, 30, 40, 70, 80, 75); $this->assertTrue($scale->scaleDown()); $this->assertFalse($scale->scaleUp());