แแแแแ แฏแแแ! แฉแแแ แแแแแแแแแ แแแแแแแแแแก แแแ แแแแแชแแแแแแแ แแฃแจแแแแแกแแแแก. แจแแฃแซแแแแแแแ แฌแแ แแแแแแแแแแ แกแแแแแแแแแแแแแแ แแ แแแ แแแ แแแ แแแแแชแแแแแแ แกแแแฃแแแ แ แแแแกแขแแ แแก แแแ แแจแ, แ แแแแแแแช แงแแแแ แแแแแฌแแแ แแ แแแ แแฃแจแแแแก. แแ แแแแแแแ, แฉแแแแก แแ แแแ แแแแก แงแแแแแแแแก แแฅแแก แแก ๐ แฉแแแ แฉแแ แแฃแแ แแแ แ แแแก แแแแคแแแฃแ แแชแแแจแ, แขแฃแแแแแกแ แแ แแแแแแแกแขแ แแ แแแแจแ แแ แแแญแแแ แแแ แแแแแ แแแฃแจแแแแแแ MapReduce แกแแแฃแจแแแแแก แแฅ แแ แแงแแแแแแ Spark-แก.
แแ แแแกแขแจแ แฉแแแ แแแขแงแแแ, แแฃ แ แแแแ แแแแแแญแ แแ แแแแกแขแแ แแก แแ แแแแแแแแ แ แแแขแแแ แแแแก แแ แแแแแแ แฆแ แฃแแแแก แแแแแงแแแแแแ แกแแแฃแแแ แ แแแขแแกแแแแแ แแก แแแฌแแ แแ
แแ แแแแแแ
แฉแแแแ แแแแกแขแแ แ แแ แแแแแแงแแแแแ แขแแแแฃแ แ แแแแแจแ. แแแแแแแฃแ แแแ แซแแแแ แแ แแแแแแแแ แแ. แแแแแแแแแ, แแ แแก แแ แแฅแขแแแฃแแ แแแแแแแแแแแ, แ แแแแกแแช 30-แแ แแแแแแแแ แแ แแแกแฌแแแแแแแแ แแแแแแ แแแแกแขแแ แจแ แแ แแฌแงแแแแ แแแก แแแแแงแแแแแแก. แแ แแแแแ, แแ แแก แแแแแแแ แแฆแแแแ, แ แแแแกแแช แแแขแแแ แแแ แแแแจแแแแแแแแแ แแแ แแแแ. แแแแแ แฉแแ แแ แแก แแแแกแขแแ แ แแฃแจแแแแก แแแขแแแ แแฃแ แ แแแแแจแ.
ะ ะตัะตะฝะธะต โ1 โ ััะพ ะดะตัะถะฐัั ะบะปะฐััะตั, ะบะพัะพััะน ะฑัะดะตั ะฒัะดะตัะถะธะฒะฐัั ะฟะธะบะพะฒัะต ะทะฐะณััะทะบะธ, ะฝะพ ะฑัะดะตั ะฟัะพััะฐะธะฒะฐัั ะฒะพ ะฒัะต ะพััะฐะปัะฝะพะต ะฒัะตะผั.
แแแแแกแแแแแ #2 แแ แแก แแแขแแ แ แแแแกแขแแ แแก แจแแแแ แฉแฃแแแแ, แ แแแแแกแแช แฎแแแแ แแแแขแแแ แแแแแซแแแก แแแแกแแแแก แฌแแ แแ แแแแฃแ แ แแแขแแแ แแแแก แแ แแก.
แแแแแกแแแแแ #3 แแ แแก แแแขแแ แ แแแแกแขแแ แแก แจแแแแฎแแ แแ แแแขแแกแแแแแ แแก แแแฌแแ แ, แ แแแแแแช แแแแแขแแ แแแแก แแแฃแฌแแแก แแแแกแขแแ แแก แแแแแแแแ แ แแแขแแแ แแแแก แแ แกแฎแแแแแกแฎแแ API-แแแแก แแแแแงแแแแแแ แแแแแแขแแแก แแ แแแแแฆแแแก แแแแแซแแแก แแแแกแขแแ แแแแ.
แแ แแแกแขแจแ แแแกแแฃแแ แแแ แแแแแกแแแแแแ #3. แแก แแแขแแกแแแแแ แ แแแแแ แแ แแก แแแแแแแแแแฃแแ แแแ แ แคแแฅแขแแ แแแแ แแ แแ แ แจแแแ แคแแฅแขแแ แแแแ แแ แแ แแแแแแแ แแแ แฎแจแแ แแ แแ แแฌแแแแแ แแแก. แฉแแแ แแแงแแแแแ Mail.ru Cloud Solutions แฆแ แฃแแแแแแ แแแคแ แแกแขแ แฃแฅแขแฃแ แแก แแ แแแแฌแแ แแ แแแขแแกแแแแแ แ MCS API-แแก แแแแแงแแแแแแ. แแ แ แแแแแ แฉแแแ แแแกแฌแแแแแ แแแแแชแแแแแแแ แแฃแจแแแแแก, แแแแแแฌแงแแแขแแ แแแแฉแแแแแแแแ, แแฃ แ แแแแ แจแแแแซแแแแ แแแฌแแ แแ แแกแแแแกแ แแแขแแกแแแแแ แ แแฅแแแแ แแแแแแแแกแแแแก แแ แแแแแแงแแแแ แแแ แแฅแแแแก แฆแ แฃแแแแแแ
แฌแแแแแแ แแแแแ
แแแ แแแ แ แแแจแ, แแฅแแแ แฃแแแ แแฅแแแแแ Hadoop แแแแกแขแแ แ. แแแแแแแแแ, แฉแแแ แแแงแแแแแ HDP แแแแแฌแแแแแแก.
แแแแกแแแแแก, แ แแ แแฅแแแแ แแแแแซแแแ แกแฌแ แแคแแ แแแแแแขแแก แแ แฌแแแจแแแแก, แแฅแแแ แฃแแแ แแฅแแแแแ แ แแแแแแก แแแ แแแแฃแแ แแแแแฌแแแแแ แแแแแซแแแก แจแแ แแก.
- แกแแแแแแกแขแ แ แแแแแซแ. แแกแ, แแ แแคแ แแก แแแแกแแแฃแแ แแแฃแแ แแฎแกแแ แแ แแ แแก แกแแญแแ แ: แแแแกแขแแ แแก แแแแแแ แ แแแแแซแ, แ แแแแแแแแแช แแแจแแแแฃแแแ, แแแแแแแแแ, Spark แแ แแแแแ แ, แแฃ แแงแแแแแ แแแขแแ แแฅแขแแฃแ แ แแแแแก.
- แแแ แแฆแแก แแแแแซแ. แแก แแ แแก แแแแแซแ, แ แแแแแแแช แแแแฎแแแ แแแแแชแแแแแก HDFS-แแ แแ แกแแแแช แฎแแแแ แแแแแแแแแแ.
- แแแแแแแแแแ แแแแแซแ. แแก แแ แแก แแแแแซแ, แกแแแแช แแฅแแแ แแ แแแแฎแแแ แแ แแคแแ แก HDFS-แแ, แแแแ แแ แกแแแแช แฎแแแแ แแแแแแแแแแ.
แแแแจแแแแแแแแแ แฌแแ แขแแแ. แแแขแแกแแแแแ แแแ แแแฎแแแแ แแแกแแแ แขแแแแก แแแแแซแแแแก แแแแ. แแฃ แแแแฌแงแแแ แแแแ แ แขแแแแก แแแแแซแแแแก แแฆแแแแก แแ แแแแแขแแแแก, แ แแแแแ แแแแก แกแแฉแฅแแ แ แซแแแแแ แแแแแแ แแฅแแแแ - แแแแแแแกแแชแแแก แแ แฎแแแแฎแแ แฉแแ แแแแกแแก แกแแแแแแ แแแกแญแแ แแแแ แแฅแแแแก แแแแกแขแแ แแ. แแก, แ แ แแฅแแ แฃแแแ, แแ แแ แแก แแก, แ แแกแแช แแแแแแแแ แแแขแแแแขแฃแ แ แกแแแแแ แแแแกแแแ. แแแฃ แแแ แแแแ แแ แแแแ แ แขแแแแก แแแแแซแแแก แแ แแแฎแแแแ. แแกแแแ แฌแแ แแแแแแแแแ แแแแแแแแฃแ แกแแชแแชแฎแแแกแฃแแแ แแแ แแแแกแขแแ แก, แ แแแแแแช แแแ แกแแแแแก แแ แแแ แแแแก แแแแแแแแแแแจแ.
แแกแ แ แแ, แฉแแแแ แแแขแแกแแแแแ แ แแแฌแแ แแแแ Python 3-แจแ, แแงแแแแแก Ambari API-แก แแแแกแขแแ แฃแแ แกแแ แแแกแแแแก แกแแแแ แแแแแ, แแงแแแแแก
แแแแแฌแงแแแขแแก แแ แฅแแขแแฅแขแฃแ แ
- แแแแฃแแ
autoscaler.py
. แแแ แจแแแชแแแก แกแแ แแแแกแก: 1) แแแแแ แแแ แแฃแจแแแแแก แคแฃแแฅแชแแแแ, 2) MCS-แแแ แแฃแจแแแแแก แคแฃแแฅแชแแแแ, 3) แคแฃแแฅแชแแแแ, แ แแแแแแแช แฃแจแฃแแแแ แฃแแแแจแแ แแแแ แแแขแแกแแแแแ แแก แแแแแแแก. - แกแแ แแแขแ
observer.py
. แแ แกแแแแแแ แแก แจแแแแแแ แกแฎแแแแแกแฎแแ แฌแแกแแแแกแแแ: แ แแแแก แแ แ แ แแแแแแขแแแจแ แแแแแซแแฎแแแ แแแขแแกแแแแแ แแก แคแฃแแฅแชแแแแ. - แแแแคแแแฃแ แแชแแแก แคแแแแ
config.py
. แแก แจแแแชแแแก, แแแแแแแแแ, แแแแแซแแแแก แฉแแแแแแแแแแก, แ แแแแแแแช แแแแแแแ แแฃแแแ แแแขแแกแแแแแ แแแแแ แแ แกแฎแแ แแแ แแแแขแ แแแแ, แ แแแแแแแช แแแแแแแแก แแฎแแแแแ, แแแแแแแแแ, แ แแแแแแ แฎแแแ แฃแแแ แแแแแแแแแ แแฎแแแ แแแแแซแแก แแแแแขแแแแก แแแแแแขแแแแ. แแกแแแ แแ แแก แแแแกแแแแก แแแฌแงแแแแก แแ แแแแ แแแแแแญแแแแ, แ แแแ แแแแกแแแแ แแแแฅแแแแแแก แแแแกแขแแ แแแแก แแแฅแกแแแแแฃแ แ แแแกแแจแแแแ แแแแคแแแฃแ แแชแแ.
แแแแแ แแฎแแ แแแแแแฎแแแแ แแแแแก แแแฌแแแแแก แแแ แแแแ แแ แ แคแแแแแก แจแแแแแ.
1. Autoscaler.py แแแแฃแแ
แแแแแ แแก แแแแกแ
แแกแ แแแแแแงแฃแ แแแ แแแแแก แแแฌแแแ, แ แแแแแแช แจแแแชแแแก แแแแกแก Ambari
:
class Ambari:
def __init__(self, ambari_url, cluster_name, headers, auth):
self.ambari_url = ambari_url
self.cluster_name = cluster_name
self.headers = headers
self.auth = auth
def stop_all_services(self, hostname):
url = self.ambari_url + self.cluster_name + '/hosts/' + hostname + '/host_components/'
url2 = self.ambari_url + self.cluster_name + '/hosts/' + hostname
req0 = requests.get(url2, headers=self.headers, auth=self.auth)
services = req0.json()['host_components']
services_list = list(map(lambda x: x['HostRoles']['component_name'], services))
data = {
"RequestInfo": {
"context":"Stop All Host Components",
"operation_level": {
"level":"HOST",
"cluster_name": self.cluster_name,
"host_names": hostname
},
"query":"HostRoles/component_name.in({0})".format(",".join(services_list))
},
"Body": {
"HostRoles": {
"state":"INSTALLED"
}
}
}
req = requests.put(url, data=json.dumps(data), headers=self.headers, auth=self.auth)
if req.status_code in [200, 201, 202]:
message = 'Request accepted'
else:
message = req.status_code
return message
แแแแแ, แแแแแแแแแ, แจแแแแซแแแแ แแแฎแแ แคแฃแแฅแชแแแก แแแแฎแแ แชแแแแแแ stop_all_services
, แ แแแแแแช แแฉแแ แแแก แงแแแแ แกแแ แแแกแก แกแแกแฃแ แแแ แแแแกแขแแ แฃแ แแแแแซแแ.
แแแแกแแก แจแแกแแกแแแแแแแ Ambari
แจแแ แแแแแแ:
ambari_url
แแแแแแแแแ, แแแกแฌแแแก'http://localhost:8080/api/v1/clusters/'
,cluster_name
โ แแฅแแแแ แแแแกแขแแ แแก แกแแฎแแแ แแแแแ แจแ,headers = {'X-Requested-By': 'ambari'}
- แแ แจแแแแแ
auth
แแฅ แแ แแก แแฅแแแแ แจแแกแแแ แแ แแแ แแแ แแแแแ แแกแแแแก:auth = ('login', 'password')
.
แคแฃแแฅแชแแ แแแแแกแแแแแ แกแฎแแ แแ แแคแแ แแ, แแฃ แแ แ แ แแแแแแแแ แแแ แ REST API-แแ แแแแแ แแกแแแ. แแแแแแฃแ แ แแแแแกแแแ แแกแแ, แฉแแแ แฏแแ แแแฆแแแ แแแแแซแแ แแแจแแแแฃแแ แกแแ แแแกแแแแก แฉแแแแแแแแแแก แแ แจแแแแแ แแแฎแแแ แแแชแแแฃแ แแแแกแขแแ แแ, แแแชแแแฃแ แแแแแซแแ, แกแแ แแแกแแแแก แแแแแขแแแแก แกแแแแแ แกแแฎแแแแฌแแคแแจแ. INSTALLED
. แคแฃแแฅแชแแแแ แงแแแแ แกแแ แแแกแแก แแแจแแแแแกแแแแก, แแแแแซแแแแก แกแแฎแแแแฌแแคแแจแ แแแแแกแแขแแแแ Maintenance
แแ แ.แจ. แแแแแแงแฃแ แแแ แแกแแแแกแ - แแกแแแ แแฎแแแแ แ แแแแแแแแ แแแแฎแแแแแ API-แแก แแแจแแแแแแ.
แแแแกแ แแแแก
แแกแ แแแแแแงแฃแ แแแ แแแแแก แแแฌแแแ, แ แแแแแแช แจแแแชแแแก แแแแกแก Mcs
:
class Mcs:
def __init__(self, id1, id2, password):
self.id1 = id1
self.id2 = id2
self.password = password
self.mcs_host = 'https://infra.mail.ru:8774/v2.1'
def vm_turn_on(self, hostname):
self.token = self.get_mcs_token()
host = self.hostname_to_vmname(hostname)
vm_id = self.get_vm_id(host)
mcs_url1 = self.mcs_host + '/servers/' + self.vm_id + '/action'
headers = {
'X-Auth-Token': '{0}'.format(self.token),
'Content-Type': 'application/json'
}
data = {'os-start' : 'null'}
mcs = requests.post(mcs_url1, data=json.dumps(data), headers=headers)
return mcs.status_code
แแแแกแแก แจแแกแแกแแแแแแแ Mcs
แฉแแแ แแแแแแชแแแ แแ แแแฅแขแแก ID-แก แฆแ แฃแแแแจแ แแ แแแแฎแแแ แแแแแก ID-แก, แแกแแแ แแแก แแแ แแแก. แคแฃแแฅแชแแแจแ vm_turn_on
แฉแแแ แแแแแแ แฉแแแ แแแ แแ แ-แแ แแ แแแแฅแแแ. แแแแแแ แแฅ แชแแขแ แฃแคแ แ แ แแฃแแแ. แแแแแก แแแกแแฌแงแแกแจแ แกแแ แกแฎแแ แคแฃแแฅแชแแแก แแซแแฎแแแ: 1) แฃแแแ แแแแแฆแแ แแแขแแแ, 2) แฐแแกแขแแก แกแแฎแแแ แแแแแแแงแแแแแ แแแแ แแขแแก แกแแฎแแแแ MCS-แจแ, 3) แแแแแฆแแ แแ แแแแ แแขแแก ID. แจแแแแแแ, แฉแแแ แฃแแ แแแแ แแแแแแแแ แแแกแขแแก แแแแฎแแแแแก แแ แแแแฃแจแแแ แแก แแแแฅแแแ.
แแกแ แแแแแแงแฃแ แแแ แแแขแแแแก แแแฆแแแแก แคแฃแแฅแชแแ:
def get_mcs_token(self):
url = 'https://infra.mail.ru:35357/v3/auth/tokens?nocatalog'
headers = {'Content-Type': 'application/json'}
data = {
'auth': {
'identity': {
'methods': ['password'],
'password': {
'user': {
'id': self.id1,
'password': self.password
}
}
},
'scope': {
'project': {
'id': self.id2
}
}
}
}
params = (('nocatalog', ''),)
req = requests.post(url, data=json.dumps(data), headers=headers, params=params)
self.token = req.headers['X-Subject-Token']
return self.token
แแแขแแกแแแแแ แแก แแแแกแ
แแก แแแแกแ แจแแแชแแแก แคแฃแแฅแชแแแแก, แ แแแแแแแช แแแแแแจแแ แแแฃแแแ แแแแแ แแแแ แแชแแฃแ แแแแแแแกแแแ.
แแกแ แแแแแแงแฃแ แแแ แแ แแแแกแแก แแแแแก แแแฌแแแ:
class Autoscaler:
def __init__(self, ambari, mcs, scaling_hosts, yarn_ram_per_node, yarn_cpu_per_node):
self.scaling_hosts = scaling_hosts
self.ambari = ambari
self.mcs = mcs
self.q_ram = deque()
self.q_cpu = deque()
self.num = 0
self.yarn_ram_per_node = yarn_ram_per_node
self.yarn_cpu_per_node = yarn_cpu_per_node
def scale_down(self, hostname):
flag1 = flag2 = flag3 = flag4 = flag5 = False
if hostname in self.scaling_hosts:
while True:
time.sleep(5)
status1 = self.ambari.decommission_nodemanager(hostname)
if status1 == 'Request accepted' or status1 == 500:
flag1 = True
logging.info('Decomission request accepted: {0}'.format(flag1))
break
while True:
time.sleep(5)
status3 = self.ambari.check_service(hostname, 'NODEMANAGER')
if status3 == 'INSTALLED':
flag3 = True
logging.info('Nodemaneger decommissioned: {0}'.format(flag3))
break
while True:
time.sleep(5)
status2 = self.ambari.maintenance_on(hostname)
if status2 == 'Request accepted' or status2 == 500:
flag2 = True
logging.info('Maintenance request accepted: {0}'.format(flag2))
break
while True:
time.sleep(5)
status4 = self.ambari.check_maintenance(hostname, 'NODEMANAGER')
if status4 == 'ON' or status4 == 'IMPLIED_FROM_HOST':
flag4 = True
self.ambari.stop_all_services(hostname)
logging.info('Maintenance is on: {0}'.format(flag4))
logging.info('Stopping services')
break
time.sleep(90)
status5 = self.mcs.vm_turn_off(hostname)
while True:
time.sleep(5)
status5 = self.mcs.get_vm_info(hostname)['server']['status']
if status5 == 'SHUTOFF':
flag5 = True
logging.info('VM is turned off: {0}'.format(flag5))
break
if flag1 and flag2 and flag3 and flag4 and flag5:
message = 'Success'
logging.info('Scale-down finished')
logging.info('Cooldown period has started. Wait for several minutes')
return message
แแแฆแแแ แแแแแแแแแแแก แจแแกแแกแแแแแแ. Ambari
ะธ Mcs
, แแแแแซแแแแก แกแแ, แ แแแแแแแช แแแจแแแแฃแแแ แกแแแแแ แแแแแ, แแกแแแ แแแแแซแแก แแแแคแแแฃแ แแชแแแก แแแ แแแแขแ แแแ: แแแฎแกแแแ แแแ แแ CPU แแแแแงแแคแแแ แแแแแซแแกแแแแก YARN-แจแ. แแกแแแ แแ แแก 2 แจแแแ แแแ แแแแขแ แ q_ram, q_cpu, แ แแแแแแแช แ แแแแแแ. แแแแ แแแแแงแแแแแแ, แฉแแแ แแแแแฎแแแ แแแแแแแแ แ แแแกแแขแฃแ แ แแแขแแแ แแแแก แแแแจแแแแแแแแแก. แแฃ แแแแแแแฎแแแ, แ แแ แแแแ 5 แฌแฃแแแก แแแแแแแแแแแจแ แแฃแแแแแแ แแแแแแ แแ แแแขแแแ แแแ, แแแจแแ แแแแแแฌแงแแแขแแ, แ แแ แฃแแแ แแแแแแแขแแ +1 แแแแแซแ แแแแกแขแแ แจแ. แแแแแ แแแฅแแแก แแแแกแขแแ แแแแก แแ แแกแแแแแ แแกแ แแแแแงแแแแแแก แแแแแแแ แแแแแแ.
แแแแแ แแแงแแแแแแ แแแแ แแ แแก แคแฃแแฅแชแแแก แแแแแแแแ, แ แแแแแแช แจแแแก แแแแฅแแแแก แแแแกแขแแ แแแแ แแ แแฉแแ แแแก แแแก แฆแ แฃแแแแจแ. แฏแแ แแ แแก แแแแแแแกแแ YARN Nodemanager
, แจแแแแแ แฉแแแ แแแแแ แ แแแแแ Maintenance
, แจแแแแแ แฉแแแ แแฌแงแแแขแ แงแแแแ แกแแ แแแกแก แแแฌแงแแแแแแแแแ แแ แแแแแ แแแ แแแ แขแฃแแแฃแ แ แแแแฅแแแ แฆแ แฃแแแแจแ.
2. แกแแ แแแขแแก แแแแแแแ แแแแแแ.py
แแแแแก แแแแฃแจแ แแฅแแแแ:
if scaler.assert_up(config.scale_up_thresholds) == True:
hostname = cloud.get_vm_to_up(config.scaling_hosts)
if hostname != None:
status1 = scaler.scale_up(hostname)
if status1 == 'Success':
text = {"text": "{0} has been successfully scaled-up".format(hostname)}
post = {"text": "{0}".format(text)}
json_data = json.dumps(post)
req = requests.post(webhook, data=json_data.encode('ascii'), headers={'Content-Type': 'application/json'})
time.sleep(config.cooldown_period*60)
ะ ะฝะตะผ ะผั ะฟัะพะฒะตััะตะผ, ัะปะพะถะธะปะธัั ะปะธ ััะปะพะฒะธั ะดะปั ัะฒะตะปะธัะตะฝะธั ะผะพัะฝะพััะตะน ะบะปะฐััะตัะฐ ะธ ะตััั ะปะธ ะฒะพะพะฑัะต ะฒ ัะตะทะตัะฒะต ะผะฐัะธะฝั, ะฟะพะปััะฐะตะผ ั
ะพััะฝะตะนะผ ะพะดะฝะพะน ะธะท ะฝะธั
, ะดะพะฑะฐะฒะปัะตะผ ะตะต ะฒ ะบะปะฐััะตั ะธ ะฟัะฑะปะธะบัะตะผ ะพะฑ ััะพะผ ัะพะพะฑัะตะฝะธะต ะฒ Slack ะฝะฐัะตะน ะบะพะผะฐะฝะดั. ะะพัะปะต ัะตะณะพ ะทะฐะฟััะบะฐะตััั cooldown_period
, แ แแแแกแแช แฉแแแ แแ แแแแแขแแแ แแ แแ แแฎแกแแแ แแ แแคแแ แก แแแแกแขแแ แแแแ, แแ แแแแ แฃแแ แแแแ แแแแแแ แแแแแ แแแขแแแ แแแแก. แแฃ แแก แแแกแขแแแแแฃแ แแ แแ แแแขแแแแแฃแ แ แแแขแแแ แแแแก แแแแจแแแแแแแแแแก แแแ แแคแแแจแแ, แแแจแแ แฉแแแ แฃแแ แแแแ แแแแ แซแแแแแ แแแแแขแแ แแแแก. แแฃ แแ แแ แแแแแซแ แแ แแงแ แกแแแแแ แแกแ, แแแจแแ แแแแแขแแแ แแแแ แแก.
แแ แจแแแแฎแแแแแกแแแแก, แ แแชแ แฌแแ แแแแฅแแก แแแแแแแแแ, แฃแแแ แแฃแกแขแแ แแแชแแ, แ แแ แแ แแ แแแแแซแ แแ แแฅแแแแ แกแแแแแ แแกแ, แแแแขแแ แกแแกแฌแ แแคแแ แแแฌแงแแแ แงแแแแ แแแแแกแฃแคแแ แแแแแซแก แแ แแแแ แซแแแแแ แแแ แแฅแขแแฃแ แแแแก แแแแแแแแแแก แแแแแแแ. แแก แฎแแแแ แแฅแขแแแแแแก แแ แแแก แแแแแแญแแแแแก แกแแแก แแแแแงแแแแแแ.
แแแกแแแแ
Autoscaler แแ แแก แแแ แแ แแ แแแกแแฎแแ แฎแแแแแ แแแแแฌแงแแแขแ แแ แจแแแแฎแแแแแแแกแแแแก, แ แแแแกแแช แแฅแแแ แแแแแชแแแ แแ แแแแแแแแ แ แแแกแแขแฃแ แ แแแขแแแ แแแแก. แแฅแแแ แแ แแแ แแฃแแแ แแแแฆแฌแแแ แกแแกแฃแ แแแ แแแกแแขแฃแ แแแแคแแแฃแ แแชแแแก แแแแฃแ แ แแแขแแแ แแแแกแแแแก แแ แแแแแแ แแฃแแแ แแ แแแแฎแแแ แแ แแแแกแขแแ แก แแแขแแแ แแแแก แแ แแก, แแแแแแแแ แคแฃแแก. แแแ แแ แแแแกแ, แแก แงแแแแแคแแ แ แแแขแแแแขแฃแ แแ แฎแแแแ แแฅแแแแ แแแแแฌแแแแแแแก แแแ แแจแ. แแแแแ แแแขแแกแแแแแ แ แกแฎแแ แแ แแคแแ แแ, แแฃ แแ แ แแแแกแขแแ แแแแแฏแแ แแก API-แกแ แแ แฆแ แฃแแแแแแแ แแ แแแแแแแ แแก API-แก แแแแแ แ แแแแฎแแแแแแแก แแแแ แแแ, แ แแแแแแช แแแฌแแ แแแแ แแแ แแแแฃแแ แแแแแแแก แแแฎแแแแแ. แ แแช แแฃแชแแแแแแแ แฃแแแ แแแฎแกแแแแแ, แแ แแก แแแแแซแแแแก แแแงแแคแ 3 แขแแแแ, แ แแแแ แช แแแ แ แแแแฌแแ แแ. แแ แแแแแแแ แ แแฅแแแแ.
แฌแงแแ แ: www.habr.com