рдирдорд╕реНрдХрд╛рд░! рдЖрдореНрд╣реА рд▓реЛрдХрд╛рдВрдирд╛ рдореЛрдареНрдпрд╛ рдбреЗрдЯрд╛рд╕рд╣ рдХрд╛рдо рдХрд░рдгреНрдпрд╛рдЪреЗ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рджреЗрддреЛ. рдореЛрдареНрдпрд╛ рдбреЗрдЯрд╛рд╡рд░реАрд▓ рд╢реИрдХреНрд╖рдгрд┐рдХ рдХрд╛рд░реНрдпрдХреНрд░рдорд╛рдЪреА рддреНрдпрд╛рдЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдХреНрд▓рд╕реНрдЯрд░рд╢рд┐рд╡рд╛рдп рдХрд▓реНрдкрдирд╛ рдХрд░рдгреЗ рдЕрд╢рдХреНрдп рдЖрд╣реЗ, рдЬреНрдпрд╛рд╡рд░ рд╕рд░реНрд╡ рд╕рд╣рднрд╛рдЧреА рдПрдХрддреНрд░ рдХрд╛рдо рдХрд░рддрд╛рдд. рдпрд╛ рдХрд╛рд░рдгрд╛рд╕реНрддрд╡, рдЖрдордЪреНрдпрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдордордзреНрдпреЗ рддреЗ рдиреЗрд╣рдореАрдЪ рдЕрд╕рддреЗ :) рдЖрдореНрд╣реА рддреНрдпрд╛рдЪреЗ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди, рдЯреНрдпреВрдирд┐рдВрдЧ рдЖрдгрд┐ рдкреНрд░рд╢рд╛рд╕рдирд╛рдордзреНрдпреЗ рдЧреБрдВрддрд▓реЗрд▓реЗ рдЕрд╕рддреЛ рдЖрдгрд┐ рд▓реЛрдХ рдереЗрдЯ рдореЕрдкрд░реЗрдбреНрдпреВрд╕ рдЬреЙрдмреНрд╕ рддреЗрдереЗ рд▓реЙрдиреНрдЪ рдХрд░рддрд╛рдд рдЖрдгрд┐ рд╕реНрдкрд╛рд░реНрдХ рд╡рд╛рдкрд░рддрд╛рдд.
рдпрд╛ рдкреЛрд╕реНрдЯрдордзреНрдпреЗ рдЖрдореНрд╣реА рддреБрдореНрд╣рд╛рд▓рд╛ рдХреНрд▓рд╛рдЙрдб рд╡рд╛рдкрд░реВрди рдЖрдордЪреЗ рд╕реНрд╡рддрдГрдЪреЗ рдСрдЯреЛрд╕реНрдХреЗрд▓рд░ рд▓рд┐рд╣реВрди рдЕрд╕рдорд╛рди рдХреНрд▓рд╕реНрдЯрд░ рд▓реЛрдбрд┐рдВрдЧрдЪреА рд╕рдорд╕реНрдпрд╛ рдХрд╢реА рд╕реЛрдбрд╡рд▓реА рддреЗ рд╕рд╛рдВрдЧреВ.
рд╕рдорд╕реНрдпрд╛
рдЖрдордЪрд╛ рдХреНрд▓рд╕реНрдЯрд░ рдард░рд╛рд╡рд┐рдХ рдореЛрдбрдордзреНрдпреЗ рд╡рд╛рдкрд░рд▓рд╛ рдЬрд╛рдд рдирд╛рд╣реА. рд╡рд┐рд▓реНрд╣реЗрд╡рд╛рдЯ рдЕрддреНрдпрдВрдд рдЕрд╕рдорд╛рди рдЖрд╣реЗ. рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд╡рд░реНрдЧ рдЖрд╣реЗрдд, рдЬреЗрд╡реНрд╣рд╛ рд╕рд░реНрд╡ 30 рд▓реЛрдХ рдЖрдгрд┐ рдПрдХ рд╢рд┐рдХреНрд╖рдХ рдХреНрд▓рд╕реНрдЯрд░рдордзреНрдпреЗ рдЬрд╛рддрд╛рдд рдЖрдгрд┐ рддреЗ рд╡рд╛рдкрд░рдгреНрдпрд╛рд╕ рдкреНрд░рд╛рд░рдВрдн рдХрд░рддрд╛рдд. рдХрд┐рдВрд╡рд╛ рдкреБрдиреНрд╣рд╛, рдЕрдВрддрд┐рдо рдореБрджрддреАрдкреВрд░реНрд╡реАрдЪреЗ рджрд┐рд╡рд╕ рдЖрд╣реЗрдд рдЬреЗрд╡реНрд╣рд╛ рд▓реЛрдб рдореЛрдареНрдпрд╛ рдкреНрд░рдорд╛рдгрд╛рдд рд╡рд╛рдврддреЗ. рдЙрд░реНрд╡рд░рд┐рдд рд╡реЗрд│ рдХреНрд▓рд╕реНрдЯрд░ рдЕрдВрдбрд░рд▓реЛрдб рдореЛрдбрдордзреНрдпреЗ рдХрд╛рд░реНрдп рдХрд░рддреЛ.
рдЙрдкрд╛рдп #1 рдореНрд╣рдгрдЬреЗ рдПрдХ рдХреНрд▓рд╕реНрдЯрд░ рдареЗрд╡рдгреЗ рдЬреЗ рдкреАрдХ рднрд╛рд░ рд╕рд╣рди рдХрд░реЗрд▓, рдкрд░рдВрддреБ рдЙрд░реНрд╡рд░рд┐рдд рд╡реЗрд│реЗрдд рдирд┐рд╖реНрдХреНрд░рд┐рдп рдЕрд╕реЗрд▓.
рдЙрдкрд╛рдп #2 рдореНрд╣рдгрдЬреЗ рдПрдХ рд▓рд╣рд╛рди рдХреНрд▓рд╕реНрдЯрд░ рдареЗрд╡рдгреЗ, рдЬреНрдпрд╛рдордзреНрдпреЗ рддреБрдореНрд╣реА рд╡рд░реНрдЧрд╛рдВрдкреВрд░реНрд╡реА рдЖрдгрд┐ рдкреАрдХ рд▓реЛрдб рджрд░рдореНрдпрд╛рди рдиреЛрдбреНрд╕ рдореЕрдиреНрдпреБрдЕрд▓реА рдЬреЛрдбрддрд╛.
рдЙрдкрд╛рдп #3 рдореНрд╣рдгрдЬреЗ рдПрдХ рд▓рд╣рд╛рди рдХреНрд▓рд╕реНрдЯрд░ рдареЗрд╡рдгреЗ рдЖрдгрд┐ рдПрдХ рдСрдЯреЛрд╕реНрдХреЗрд▓рд░ рд▓рд┐рд╣рд┐рдгреЗ рдЬреЗ рдХреНрд▓рд╕реНрдЯрд░рдЪреНрдпрд╛ рд╡рд░реНрддрдорд╛рди рд▓реЛрдбрдЪреЗ рдирд┐рд░реАрдХреНрд╖рдг рдХрд░реЗрд▓ рдЖрдгрд┐ рд╡рд┐рд╡рд┐рдз API рд╡рд╛рдкрд░реВрди, рдХреНрд▓рд╕реНрдЯрд░рдордзреВрди рдиреЛрдбреНрд╕ рдЬреЛрдбрдгреЗ рдЖрдгрд┐ рдХрд╛рдвреВрди рдЯрд╛рдХрдгреЗ.
рдпрд╛ рдкреЛрд╕реНрдЯрдордзреНрдпреЗ рдЖрдкрдг рдЙрдкрд╛рдп #3 рдмрджреНрджрд▓ рдмреЛрд▓реВ. рд╣реЗ рдСрдЯреЛрд╕реНрдХреЗрд▓рд░ рдЕрдВрддрд░реНрдЧрдд рдШрдЯрдХрд╛рдВрдРрд╡рдЬреА рдмрд╛рд╣реНрдп рдШрдЯрдХрд╛рдВрд╡рд░ рдЬрд╛рд╕реНрдд рдЕрд╡рд▓рдВрдмреВрди рдЕрд╕рддреЗ рдЖрдгрд┐ рдкреНрд░рджрд╛рддреЗ рд╕рд╣рд╕рд╛ рддреЗ рдкреНрд░рджрд╛рди рдХрд░рдд рдирд╛рд╣реАрдд. рдЖрдореНрд╣реА Mail.ru Cloud Solutions рдХреНрд▓рд╛рдЙрдб рдЗрдиреНрдлреНрд░рд╛рд╕реНрдЯреНрд░рдХреНрдЪрд░ рд╡рд╛рдкрд░рддреЛ рдЖрдгрд┐ MCS API рд╡рд╛рдкрд░реВрди рдСрдЯреЛрд╕реНрдХреЗрд▓рд░ рд▓рд┐рд╣рд┐рддреЛ. рдЖрдгрд┐ рдЖрдореНрд╣реА рдбреЗрдЯрд╛рд╕рд╣ рдХрд╕реЗ рдХрд╛рд░реНрдп рдХрд░рд╛рд╡реЗ рд╣реЗ рд╢рд┐рдХрд╡рд▓реНрдпрд╛рдореБрд│реЗ, рдЖрдореНрд╣реА рддреБрдордЪреНрдпрд╛ рд╕реНрд╡рдд: рдЪреНрдпрд╛ рд╣реЗрддреВрдВрд╕рд╛рдареА рд╕рдорд╛рди рдСрдЯреЛрд╕реНрдХреЗрд▓рд░ рдХрд╕реЗ рд▓рд┐рд╣реВ рд╢рдХрддрд╛ рдЖрдгрд┐ рддреЗ рддреБрдордЪреНрдпрд╛ рдХреНрд▓рд╛рдЙрдбрд╕рд╣ рдХрд╕реЗ рд╡рд╛рдкрд░реВ рд╢рдХрддрд╛ рд╣реЗ рджрд░реНрд╢рд╡рд┐рдгреНрдпрд╛рдЪреЗ рдард░рд╡рд▓реЗ рдЖрд╣реЗ.
рдкреВрд░реНрд╡рд╛рдкреЗрдХреНрд╖рд┐рдд
рдкреНрд░рдердо, рддреБрдордЪреНрдпрд╛рдХрдбреЗ рд╣рдбреВрдк рдХреНрд▓рд╕реНрдЯрд░ рдЕрд╕рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ. рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЖрдореНрд╣реА рдПрдЪрдбреАрдкреА рд╡рд┐рддрд░рдг рд╡рд╛рдкрд░рддреЛ.
рддреБрдордЪреЗ рдиреЛрдбреНрд╕ рджреНрд░реБрддрдкрдгреЗ рдЬреЛрдбрд▓реЗ рдЬрд╛рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдгрд┐ рдХрд╛рдвреВрди рдЯрд╛рдХрдгреНрдпрд╛рд╕рд╛рдареА, рддреБрдордЪреНрдпрд╛рдХрдбреЗ рдиреЛрдбреНрд╕рдордзреНрдпреЗ рднреВрдорд┐рдХрд╛рдВрдЪреЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡рд┐рддрд░рдг рдЕрд╕рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ.
- рдорд╛рд╕реНрдЯрд░ рдиреЛрдб. рдмрд░рдВ, рдпреЗрдереЗ рд╕реНрдкрд╖реНрдЯ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╡рд┐рд╢реЗрд╖рддрдГ рдЖрд╡рд╢реНрдпрдХ рдХрд╛рд╣реАрд╣реА рдирд╛рд╣реА: рдХреНрд▓рд╕реНрдЯрд░рдЪрд╛ рдореБрдЦреНрдп рдиреЛрдб, рдЬреНрдпрд╛рд╡рд░, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рд╕реНрдкрд╛рд░реНрдХ рдбреНрд░рд╛рдЗрд╡реНрд╣рд░ рд▓реЙрдиреНрдЪ рдХреЗрд▓рд╛ рдЬрд╛рддреЛ, рдЬрд░ рддреБрдореНрд╣реА рдкрд░рд╕реНрдкрд░рд╕рдВрд╡рд╛рджреА рдореЛрдб рд╡рд╛рдкрд░рдд рдЕрд╕рд╛рд▓.
- рддрд╛рд░реАрдЦ рдиреЛрдб. рд╣рд╛ рдиреЛрдб рдЖрд╣реЗ рдЬреНрдпрд╛рд╡рд░ рддреБрдореНрд╣реА HDFS рд╡рд░ рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣рд┐рдд рдХрд░рддрд╛ рдЖрдгрд┐ рдЬрд┐рдереЗ рдЧрдгрдирд╛ рдХреЗрд▓реА рдЬрд╛рддреЗ.
- рд╕рдВрдЧрдгрдХреАрдп рдиреЛрдб. рд╣рд╛ рдПрдХ рдиреЛрдб рдЖрд╣реЗ рдЬрд┐рдереЗ рддреБрдореНрд╣реА HDFS рд╡рд░ рдХрд╛рд╣реАрд╣реА рд╕рдВрдЪрдпрд┐рдд рдХрд░рдд рдирд╛рд╣реА, рдкрд░рдВрддреБ рдЬрд┐рдереЗ рдЧрдгрдирд╛ рдХреЗрд▓реА рдЬрд╛рддреЗ.
рдорд╣рддреНрддреНрд╡рд╛рдЪрд╛ рдореБрджреНрджрд╛. рддрд┐рд╕рд▒реНрдпрд╛ рдкреНрд░рдХрд╛рд░рдЪреНрдпрд╛ рдиреЛрдбреНрд╕рдореБрд│реЗ рдСрдЯреЛрд╕реНрдХреЗрд▓рд┐рдВрдЧ рд╣реЛрдИрд▓. рдЬрд░ рддреБрдореНрд╣реА рджреБрд╕рд▒реНрдпрд╛ рдкреНрд░рдХрд╛рд░рдЪреЗ рдиреЛрдбреНрд╕ рдШреЗрдгреЗ рдЖрдгрд┐ рдЬреЛрдбрдгреЗ рд╕реБрд░реВ рдХреЗрд▓реЗ, рддрд░ рдкреНрд░рддрд┐рд╕рд╛рджрд╛рдЪреА рдЧрддреА рдЦреВрдкрдЪ рдХрдореА рдЕрд╕реЗрд▓ - рдбрд┐рдХрдорд┐рд╢рдирд┐рдВрдЧ рдЖрдгрд┐ рд░рд┐рдХрдордорд┐рдЯрд┐рдВрдЧрд▓рд╛ рддреБрдордЪреНрдпрд╛ рдХреНрд▓рд╕реНрдЯрд░рд╡рд░ рдХрд╛рд╣реА рддрд╛рд╕ рд▓рд╛рдЧрддреАрд▓. рд╣реЗ, рдЕрд░реНрдерд╛рддрдЪ, рдСрдЯреЛрд╕реНрдХреЗрд▓рд┐рдВрдЧрдХрдбреВрди рддреБрдореНрд╣рд╛рд▓рд╛ рдЕрдкреЗрдХреНрд╖рд┐рдд рдирд╛рд╣реА. рдореНрд╣рдгрдЬреЗрдЪ, рдЖрдореНрд╣реА рдкрд╣рд┐рд▓реНрдпрд╛ рдЖрдгрд┐ рджреНрд╡рд┐рддреАрдп рдкреНрд░рдХрд╛рд░рдЪреНрдпрд╛ рдиреЛрдбреНрд╕рд▓рд╛ рд╕реНрдкрд░реНрд╢ рдХрд░рдд рдирд╛рд╣реА. рддреЗ рдХрд┐рдорд╛рди рд╡реНрдпрд╡рд╣рд╛рд░реНрдп рдХреНрд▓рд╕реНрдЯрд░рдЪреЗ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреАрд▓ рдЬреЗ рдХрд╛рд░реНрдпрдХреНрд░рдорд╛рдЪреНрдпрд╛ рд╕рдВрдкреВрд░реНрдг рдХрд╛рд▓рд╛рд╡рдзреАрдд рдЕрд╕реНрддрд┐рддреНрд╡рд╛рдд рдЕрд╕рддреАрд▓.
рддрд░, рдЖрдордЪреЗ рдСрдЯреЛрд╕реНрдХреЗрд▓рд░ рдкрд╛рдпрдерди 3 рдордзреНрдпреЗ рд▓рд┐рд╣рд┐рд▓реЗрд▓реЗ рдЖрд╣реЗ, рдХреНрд▓рд╕реНрдЯрд░ рд╕реЗрд╡рд╛ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЕрдВрдмрд╛рд░реА 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
рд╡рд░реНрдЧ рдЕрд╕рд▓реЗрд▓рд╛ рдХреЛрдбрдЪрд╛ рддреБрдХрдбрд╛ рдЕрд╕рд╛ рджрд┐рд╕рддреЛ 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
рдЖрдореНрд╣реА рдХреНрд▓рд╛рдЙрдбрдордзреНрдпреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдЖрдпрдбреА рдЖрдгрд┐ рдпреВрдЬрд░ рдЖрдпрдбреА рддрд╕реЗрдЪ рддреНрдпрд╛рдЪрд╛ рдкрд╛рд╕рд╡рд░реНрдб рдкрд╛рд╕ рдХрд░рддреЛ. рдХрд╛рд░реНрдпрд╛рдд vm_turn_on
рдЖрдореНрд╣рд╛рд▓рд╛ рдПрдХ рдорд╢реАрди рдЪрд╛рд▓реВ рдХрд░рд╛рдпрдЪреА рдЖрд╣реЗ. рдпреЗрдереЗ рддрд░реНрдХ рдереЛрдбреЗ рдЕрдзрд┐рдХ рдХреНрд▓рд┐рд╖реНрдЯ рдЖрд╣реЗ. рдХреЛрдбрдЪреНрдпрд╛ рд╕реБрд░реВрд╡рд╛рддреАрд╕, рдЗрддрд░ рддреАрди рдлрдВрдХреНрд╢рдиреНрд╕ рдореНрд╣рдгрддрд╛рдд: 1) рдЖрдореНрд╣рд╛рд▓рд╛ рдЯреЛрдХрди рдорд┐рд│рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ, 2) рдЖрдореНрд╣рд╛рд▓рд╛ MCS рдордзреАрд▓ рд╣реЛрд╕реНрдЯрдирд╛рд╡ рдорд╢реАрдирдЪреНрдпрд╛ рдирд╛рд╡рд╛рдд рд░реВрдкрд╛рдВрддрд░рд┐рдд рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ, 3) рдпрд╛ рдорд╢реАрдирдЪрд╛ рдЖрдпрдбреА рдорд┐рд│рд╡рд╛. рдкреБрдвреЗ, рдЖрдореНрд╣реА рдлрдХреНрдд рдкреЛрд╕реНрдЯ рд╡рд┐рдирдВрддреА рдХрд░рддреЛ рдЖрдгрд┐ рд╣реЗ рдорд╢реАрди рд▓реЙрдиреНрдЪ рдХрд░рддреЛ.
рдЯреЛрдХрди рдорд┐рд│рд╡рдгреНрдпрд╛рдЪреЗ рдХрд╛рд░реНрдп рдЕрд╕реЗ рджрд┐рд╕рддреЗ:
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
, рд╕реНрдХреЗрд▓рд┐рдВрдЧрд╕рд╛рдареА рдкрд░рд╡рд╛рдирдЧреА рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рдиреЛрдбреНрд╕рдЪреА рд╕реВрдЪреА, рддрд╕реЗрдЪ рдиреЛрдб рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдкреЕрд░рд╛рдореАрдЯрд░реНрд╕: YARN рдордзреАрд▓ рдиреЛрдбрд▓рд╛ рд╡рд╛рдЯрдк рдХреЗрд▓реЗрд▓реА рдореЗрдорд░реА рдЖрдгрд┐ cpu. 2 рдЕрдВрддрд░реНрдЧрдд рдкреЕрд░рд╛рдореАрдЯрд░реНрд╕ q_ram, q_cpu рджреЗрдЦреАрд▓ рдЖрд╣реЗрдд, рдЬреЗ рд░рд╛рдВрдЧ рдЖрд╣реЗрдд. рддреНрдпрд╛рдВрдЪрд╛ рд╡рд╛рдкрд░ рдХрд░реВрди, рдЖрдореНрд╣реА рд╕рдзреНрдпрд╛рдЪреНрдпрд╛ рдХреНрд▓рд╕реНрдЯрд░ рд▓реЛрдбрдЪреА рдореВрд▓реНрдпреЗ рд╕рдВрдЧреНрд░рд╣рд┐рдд рдХрд░рддреЛ. рдЧреЗрд▓реНрдпрд╛ 5 рдорд┐рдирд┐рдЯрд╛рдВрдд рд╕рд╛рддрддреНрдпрд╛рдиреЗ рд▓реЛрдб рд╡рд╛рдврдд рдЕрд╕рд▓реНрдпрд╛рдЪреЗ рдЖрдкрдг рдкрд╛рд╣рд┐рд▓реНрдпрд╛рд╕, рдЖрдкрдг рдХреНрд▓рд╕реНрдЯрд░рдордзреНрдпреЗ +1 рдиреЛрдб рдЬреЛрдбрдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ рдЕрд╕реЗ рдард░рд╡реВ. рдХреНрд▓рд╕реНрдЯрд░ рдЕрдВрдбрд░рдпреБрдЯрд┐рд▓рд╛рдпрдЭреЗрд╢рди рд╕реНрдерд┐рддреАрд╕рд╛рдареА рд╣реЗрдЪ рдЦрд░реЗ рдЖрд╣реЗ.
рд╡рд░реАрд▓ рдХреЛрдб рдлрдВрдХреНрд╢рдирдЪреЗ рдЙрджрд╛рд╣рд░рдг рдЖрд╣реЗ рдЬреЗ рдХреНрд▓рд╕реНрдЯрд░рдордзреВрди рдорд╢реАрди рдХрд╛рдвреВрди рдЯрд╛рдХрддреЗ рдЖрдгрд┐ рдХреНрд▓рд╛рдЙрдбрдордзреНрдпреЗ рдерд╛рдВрдмрд╡рддреЗ. рдкреНрд░рдердо рдбрд┐рдХрдорд┐рд╢рдирд┐рдВрдЧ рдЖрд╣реЗ YARN Nodemanager
, рдирдВрддрд░ рдореЛрдб рдЪрд╛рд▓реВ рд╣реЛрдИрд▓ Maintenance
, рдирдВрддрд░ рдЖрдореНрд╣реА рдорд╢реАрдирд╡рд░реАрд▓ рд╕рд░реНрд╡ рд╕реЗрд╡рд╛ рдерд╛рдВрдмрд╡рддреЛ рдЖрдгрд┐ рдХреНрд▓рд╛рдЙрдбрдордзреАрд▓ рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рдорд╢реАрди рдмрдВрдж рдХрд░рддреЛ.
2. Script observer.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)
рддреНрдпрд╛рдордзреНрдпреЗ, рдЖрдореНрд╣реА рдХреНрд▓рд╕реНрдЯрд░рдЪреА рдХреНрд╖рдорддрд╛ рд╡рд╛рдврд╡рдгреНрдпрд╛рд╕рд╛рдареА рдкрд░рд┐рд╕реНрдерд┐рддреА рдирд┐рд░реНрдорд╛рдг рдХреЗрд▓реА рдЖрд╣реЗ рдХрд╛ рдЖрдгрд┐ рд░рд╛рдЦреАрд╡ рдордзреНрдпреЗ рдХрд╛рд╣реА рдорд╢реАрди рдЖрд╣реЗрдд рдХрд╛ рддреЗ рддрдкрд╛рд╕рддреЛ, рддреНрдпрд╛рдкреИрдХреА рдПрдХрд╛рдЪреЗ рд╣реЛрд╕реНрдЯрдирд╛рд╡ рдорд┐рд│рд╡рд╛, рддреЗ рдХреНрд▓рд╕реНрдЯрд░рдордзреНрдпреЗ рдЬреЛрдбрд╛ рдЖрдгрд┐ рдЖрдордЪреНрдпрд╛ рдЯреАрдордЪреНрдпрд╛ рд╕реНрд▓реЕрдХрд╡рд░ рддреНрдпрд╛рдмрджреНрджрд▓ рд╕рдВрджреЗрд╢ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рд╛. рдЬреНрдпрд╛рдирдВрддрд░ рддреЗ рд╕реБрд░реВ рд╣реЛрддреЗ cooldown_period
, рдЬреЗрд╡реНрд╣рд╛ рдЖрдореНрд╣реА рдХреНрд▓рд╕реНрдЯрд░рдордзреВрди рдХрд╛рд╣реАрд╣реА рдЬреЛрдбрдд рдХрд┐рдВрд╡рд╛ рдХрд╛рдврдд рдирд╛рд╣реА, рдкрд░рдВрддреБ рдлрдХреНрдд рд▓реЛрдбрдЪреЗ рдирд┐рд░реАрдХреНрд╖рдг рдХрд░рддреЛ. рдЬрд░ рддреЗ рд╕реНрдерд┐рд░ рдЭрд╛рд▓реЗ рдЕрд╕реЗрд▓ рдЖрдгрд┐ рдЗрд╖реНрдЯрддрдо рд▓реЛрдб рд╡реНрд╣реЕрд▓реНрдпреВрдЬрдЪреНрдпрд╛ рдХреЙрд░рд┐рдбреЙрд░рдордзреНрдпреЗ рдЕрд╕реЗрд▓, рддрд░ рдЖрдореНрд╣реА рдлрдХреНрдд рдирд┐рд░реАрдХреНрд╖рдг рдЪрд╛рд▓реВ рдареЗрд╡рддреЛ. рдЬрд░ рдПрдХ рдиреЛрдб рдкреБрд░реЗрд╕рд╛ рдирд╕реЗрд▓ рддрд░ рдЖрдореНрд╣реА рджреБрд╕рд░рд╛ рдЬреЛрдбрддреЛ.
рдЖрдордЪреНрдпрд╛рдХрдбреЗ рдзрдбрд╛ рдкреБрдвреЗ рдЕрд╕реЗрд▓ рдЕрд╢рд╛ рдкреНрд░рдХрд░рдгрд╛рдВрд╕рд╛рдареА, рдЖрдореНрд╣рд╛рд▓рд╛ рдЖрдзреАрдЪ рдорд╛рд╣рд┐рдд рдЖрд╣реЗ рдХреА рдПрдХ рдиреЛрдб рдкреБрд░реЗрд╕реЗ рдирд╛рд╣реА, рдореНрд╣рдгреВрди рдЖрдореНрд╣реА рддреНрд╡рд░рд┐рдд рд╕рд░реНрд╡ рд╡рд┐рдирд╛рдореВрд▓реНрдп рдиреЛрдбреНрд╕ рд╕реБрд░реВ рдХрд░рддреЛ рдЖрдгрд┐ рдзрдбрд╛ рд╕рдВрдкреЗрдкрд░реНрдпрдВрдд рддреНрдпрд╛рдВрдирд╛ рд╕рдХреНрд░рд┐рдп рдареЗрд╡рддреЛ. рд╣реЗ рдХреНрд░рд┐рдпрд╛рдХрд▓рд╛рдк рдЯрд╛рдЗрдорд╕реНрдЯреЕрдореНрдкрдЪреА рд╕реВрдЪреА рд╡рд╛рдкрд░реВрди рдШрдбрддреЗ.
рдирд┐рд╖реНрдХрд░реНрд╖
рдЬреЗрд╡реНрд╣рд╛ рддреБрдореНрд╣рд╛рд▓рд╛ рдЕрд╕рдорд╛рди рдХреНрд▓рд╕реНрдЯрд░ рд▓реЛрдбрд┐рдВрдЧрдЪрд╛ рдЕрдиреБрднрд╡ рдпреЗрддреЛ рддреЗрд╡реНрд╣рд╛ рдСрдЯреЛрд╕реНрдХреЗрд▓рд░ рд╣реЗ рдЕрд╢рд╛ рдкреНрд░рдХрд░рдгрд╛рдВрд╕рд╛рдареА рдПрдХ рдЪрд╛рдВрдЧрд▓рд╛ рдЖрдгрд┐ рд╕реЛрдпреАрд╕реНрдХрд░ рдЙрдкрд╛рдп рдЖрд╣реЗ. рддреБрдореНрд╣реА рдПрдХрд╛рдЪ рд╡реЗрд│реА рдкреАрдХ рд▓реЛрдбрд╕рд╛рдареА рдЗрдЪреНрдЫрд┐рдд рдХреНрд▓рд╕реНрдЯрд░ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рд╕рд╛рдзреНрдп рдХрд░рддрд╛ рдЖрдгрд┐ рддреНрдпрд╛рдЪ рд╡реЗрд│реА рд╣реЗ рдХреНрд▓рд╕реНрдЯрд░ рдЕрдВрдбрд░рд▓реЛрдб рджрд░рдореНрдпрд╛рди рдареЗрд╡реВ рдирдХрд╛, рдкреИрд╢рд╛рдЪреА рдмрдЪрдд рдХрд░рд╛. рддрд╕реЗрдЪ, рд╣реЗ рд╕рд░реНрд╡ рддреБрдордЪреНрдпрд╛ рд╕рд╣рднрд╛рдЧрд╛рд╢рд┐рд╡рд╛рдп рдЖрдкреЛрдЖрдк рдШрдбрддреЗ. рдСрдЯреЛрд╕реНрдХреЗрд▓рд░ рд╕реНрд╡рддрдГ рдХреНрд▓рд╕реНрдЯрд░ рдореЕрдиреЗрдЬрд░ API рдЖрдгрд┐ рдХреНрд▓рд╛рдЙрдб рдкреНрд░рджрд╛рддрд╛ API рдЪреНрдпрд╛ рд╡рд┐рдирдВрддреАрдЪреНрдпрд╛ рд╕рдВрдЪрд╛рдкреЗрдХреНрд╖рд╛ рдЕрдзрд┐рдХ рдХрд╛рд╣реА рдирд╛рд╣реА, рдПрдХрд╛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рддрд░реНрдХрд╛рдиреБрд╕рд╛рд░ рд▓рд┐рд╣рд┐рд▓реЗрд▓реЗ рдЖрд╣реЗ. рдЖрдореНрд╣реА рдЖрдзреА рд▓рд┐рд╣рд┐рд▓реНрдпрд╛рдкреНрд░рдорд╛рдгреЗ рдиреЛрдбреНрд╕рдЪреЗ 3 рдкреНрд░рдХрд╛рд░рд╛рдВрдордзреНрдпреЗ рд╡рд┐рднрд╛рдЬрди рдХрд░рдгреЗ рд╣реЗ рддреБрдореНрд╣рд╛рд▓рд╛ рдирд┐рд╢реНрдЪрд┐рддрдкрдгреЗ рд▓рдХреНрд╖рд╛рдд рдареЗрд╡рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ. рдЖрдгрд┐ рддреБрдореНрд╣реА рдЖрдирдВрджреА рд╡реНрд╣рд╛рд▓.
рд╕реНрддреНрд░реЛрдд: www.habr.com