TL;DR: рдПрдХ рд╡рд┐рд╣рдВрдЧрд╛рд╡рд▓реЛрдХрди рд▓реЗрдЦ - рдХрдВрдЯреЗрдирд░рдордзреНрдпреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдЪрд╛рд▓рд╡рд┐рдгреНрдпрд╛рд╕рд╛рдареА рд╡рд╛рддрд╛рд╡рд░рдгрд╛рдЪреА рддреБрд▓рдирд╛ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдорд╛рд░реНрдЧрджрд░реНрд╢рдХ. рдбреЙрдХрд░ рдЖрдгрд┐ рдЗрддрд░ рддрддреНрд╕рдо рдкреНрд░рдгрд╛рд▓реАрдВрдЪреНрдпрд╛ рд╢рдХреНрдпрддрд╛рдВрдЪрд╛ рд╡рд┐рдЪрд╛рд░ рдХреЗрд▓рд╛ рдЬрд╛рдИрд▓.
рд╣реЗ рд╕рд░реНрд╡ рдХреБрдареВрди рдЖрд▓реЗ рдпрд╛рдЪрд╛ рдереЛрдбрд╛рд╕рд╛ рдЗрддрд┐рд╣рд╛рд╕
рдХрдерд╛
рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╡реЗрдЧрд│реЗ рдХрд░рдгреНрдпрд╛рдЪрд╛ рдкрд╣рд┐рд▓рд╛ рд╕реБрдкреНрд░рд╕рд┐рджреНрдз рдорд╛рд░реНрдЧ рдореНрд╣рдгрдЬреЗ chroot. рддреНрдпрд╛рдЪ рдирд╛рд╡рд╛рдЪрд╛ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рд░реВрдЯ рдбрд┐рд░реЗрдХреНрдЯреНрд░реАрдордзреНрдпреЗ рдмрджрд▓ рдкреНрд░рджрд╛рди рдХрд░рддреЛ - рдЕрд╢рд╛ рдкреНрд░рдХрд╛рд░реЗ рдпрд╛рд▓рд╛ рдХреЙрд▓ рдХреЗрд▓реЗрд▓реНрдпрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдордордзреНрдпреЗ рдкреНрд░рд╡реЗрд╢ рдкреНрд░рджрд╛рди рдХрд░рддреЛ, рдлрдХреНрдд рдпрд╛ рдирд┐рд░реНрджреЗрд╢рд┐рдХреЗрддреАрд▓ рдлрд╛рдпрд▓реАрдВрдордзреНрдпреЗ рдкреНрд░рд╡реЗрд╢ рдкреНрд░рджрд╛рди рдХрд░рддреЛ. рдкрд░рдВрддреБ рдЬрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд▓рд╛ рд╕реБрдкрд░рдпреВрдЬрд░ рдЕрдзрд┐рдХрд╛рд░ рджрд┐рд▓реЗ рдЧреЗрд▓реЗ рддрд░ рддреЗ рд╕рдВрднрд╛рд╡реНрдпрддрдГ chroot рдордзреВрди "рдкрд│реВрди" рдЬрд╛рдК рд╢рдХрддреЗ рдЖрдгрд┐ рдореБрдЦреНрдп рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдордордзреНрдпреЗ рдкреНрд░рд╡реЗрд╢ рдорд┐рд│рд╡реВ рд╢рдХрддреЛ. рддрд╕реЗрдЪ, рд░реВрдЯ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдмрджрд▓рдгреНрдпрд╛рд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, рдЗрддрд░ рд╕рдВрд╕рд╛рдзрдиреЗ (RAM, рдкреНрд░реЛрд╕реЗрд╕рд░), рддрд╕реЗрдЪ рдиреЗрдЯрд╡рд░реНрдХрдордзреНрдпреЗ рдкреНрд░рд╡реЗрд╢ рдорд░реНрдпрд╛рджрд┐рдд рдирд╛рд╣реАрдд.
рдкреБрдвреАрд▓ рдорд╛рд░реНрдЧ рдореНрд╣рдгрдЬреЗ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХрд░реНрдирд▓рдЪреА рдпрдВрддреНрд░рдгрд╛ рд╡рд╛рдкрд░реВрди рдХрдВрдЯреЗрдирд░рдЪреНрдпрд╛ рдЖрдд рдПрдХ рдкреВрд░реНрдг-рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкреНрд░рдгрд╛рд▓реА рд▓реЙрдиреНрдЪ рдХрд░рдгреЗ. рдпрд╛ рдкрджреНрдзрддреАрд▓рд╛ рд╡реЗрдЧрд╡реЗрдЧрд│реНрдпрд╛ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдордордзреНрдпреЗ рд╡реЗрдЧрд│реНрдпрд╛ рдкрджреНрдзрддреАрдиреЗ рдореНрд╣рдЯрд▓реЗ рдЬрд╛рддреЗ, рдкрд░рдВрддреБ рд╕рд╛рд░ рдПрдХрдЪ рдЖрд╣реЗ - рдЕрдиреЗрдХ рд╕реНрд╡рддрдВрддреНрд░ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдЪрд╛рд▓рд╡рдгреЗ, рдЬреНрдпрд╛рдкреИрдХреА рдкреНрд░рддреНрдпреЗрдХ рдореБрдЦреНрдп рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдЪрд╛рд▓рд╡рдгрд╛рд▒реНрдпрд╛ рддреНрдпрд╛рдЪ рдХрд░реНрдирд▓рд╡рд░ рдЪрд╛рд▓рддреЗ. рдпрд╛рдордзреНрдпреЗ Linux рд╕рд╛рдареА FreeBSD рдЬреЗрд▓, рд╕реЛрд▓рд╛рд░рд┐рд╕ рдЭреЛрди, OpenVZ рдЖрдгрд┐ LXC рдпрд╛рдВрдЪрд╛ рд╕рдорд╛рд╡реЗрд╢ рдЖрд╣реЗ. рдЕрд▓рдЧрд╛рд╡ рдХреЗрд╡рд│ рдбрд┐рд╕реНрдХ рд╕реНрдкреЗрд╕рд╕рд╛рдареАрдЪ рдирд╡реНрд╣реЗ рддрд░ рдЗрддрд░ рд╕рдВрд╕рд╛рдзрдирд╛рдВрд╕рд╛рдареА рджреЗрдЦреАрд▓ рдкреНрд░рджрд╛рди рдХреЗрд▓рд╛ рдЬрд╛рддреЛ, рд╡рд┐рд╢реЗрд╖рддрдГ, рдкреНрд░рддреНрдпреЗрдХ рдХрдВрдЯреЗрдирд░рдордзреНрдпреЗ рдкреНрд░реЛрд╕реЗрд╕рд░ рд╡реЗрд│, рд░реЕрдо, рдиреЗрдЯрд╡рд░реНрдХ рдмрдБрдбрд╡рд┐рдбреНрдерд╡рд░ рдирд┐рд░реНрдмрдВрдз рдЕрд╕реВ рд╢рдХрддрд╛рдд. рдХреНрд░реЛрдЯрдЪреНрдпрд╛ рддреБрд▓рдиреЗрдд, рдХрдВрдЯреЗрдирд░ рд╕реЛрдбрдгреЗ рдЕрдзрд┐рдХ рдХрдареАрдг рдЖрд╣реЗ, рдХрд╛рд░рдг рдХрдВрдЯреЗрдирд░рдордзреАрд▓ рд╕реБрдкрд░рдпреБрдЬрд░рд▓рд╛ рдлрдХреНрдд рдХрдВрдЯреЗрдирд░рдЪреНрдпрд╛ рдЖрдд рдкреНрд░рд╡реЗрд╢ рдЕрд╕рддреЛ, рддрдерд╛рдкрд┐, рдХрдВрдЯреЗрдирд░рдЪреНрдпрд╛ рдЖрдд рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдЕрджреНрдпрдпрд╛рд╡рдд рдареЗрд╡рдгреНрдпрд╛рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЖрдгрд┐ рдЬреБрдиреНрдпрд╛ рдХрд░реНрдирд▓рдЪреНрдпрд╛ рд╡рд╛рдкрд░рд╛рдореБрд│реЗ рдЖрд╡реГрддреНрддреНрдпрд╛ (Linux рд╕рд╛рдареА рд╕рдВрдмрдВрдзрд┐рдд, рдереЛрдбреНрдпрд╛ рдкреНрд░рдорд╛рдгрд╛рдд FreeBSD), рдХрд░реНрдирд▓ рдЖрдпрд╕реЛрд▓реЗрд╢рди рд╕рд┐рд╕реНрдЯреАрдо рддреЛрдбрдгреНрдпрд╛рдЪреА рдЖрдгрд┐ рдореБрдЦреНрдп рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдордордзреНрдпреЗ рдкреНрд░рд╡реЗрд╢ рдорд┐рд│рдгреНрдпрд╛рдЪреА рд╢рдХреНрдпрддрд╛ рд╢реВрдиреНрдп рдирд╕рд▓реЗрд▓реА рдЖрд╣реЗ.
рдХрдВрдЯреЗрдирд░рдордзреНрдпреЗ рдкреВрд░реНрдг рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рд▓рд╛рдБрдЪ рдХрд░рдгреНрдпрд╛рдРрд╡рдЬреА (рдЗрдирд┐рд╢рд┐рдПрд▓рд╛рдпрдЭреЗрд╢рди рд╕рд┐рд╕реНрдЯрдо, рдкреЕрдХреЗрдЬ рдореЕрдиреЗрдЬрд░ рдЗ.) рдЕрдиреБрдкреНрд░рдпреЛрдЧ рддреНрд╡рд░рд┐рдд рд▓реЙрдиреНрдЪ рдХреЗрд▓реЗ рдЬрд╛рдК рд╢рдХрддрд╛рдд, рдореБрдЦреНрдп рдЧреЛрд╖реНрдЯ рдореНрд╣рдгрдЬреЗ рдпрд╛ рд╕рдВрдзреАрд╕рд╣ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдкреНрд░рджрд╛рди рдХрд░рдгреЗ (рдЖрд╡рд╢реНрдпрдХ рд▓рд╛рдпрдмреНрд░рд░реАрдЪреА рдЙрдкрд╕реНрдерд┐рддреА рдЖрдгрд┐ рдЗрддрд░ рдлрд╛рдпрд▓реА). рд╣реА рдХрд▓реНрдкрдирд╛ рдХрдВрдЯреЗрдирд░реАрдХреГрдд рдНрдкреНрд▓рд┐рдХреЗрд╢рди рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓рд╛рдпрдЭреЗрд╢рдирд╕рд╛рдареА рдЖрдзрд╛рд░ рдореНрд╣рдгреВрди рдХрд╛рдо рдХрд░рддреЗ, рдЬреНрдпрд╛рдЪрд╛ рд╕рд░реНрд╡рд╛рдд рдкреНрд░рдореБрдЦ рдЖрдгрд┐ рд╕реБрдкреНрд░рд╕рд┐рджреНрдз рдкреНрд░рддрд┐рдирд┐рдзреА рдбреЙрдХрд░ рдЖрд╣реЗ. рдорд╛рдЧреАрд▓ рд╕рд┐рд╕реНрдЯреАрдордЪреНрдпрд╛ рддреБрд▓рдиреЗрдд, рдХрдВрдЯреЗрдирд░рдордзреАрд▓ рдЖрднрд╛рд╕реА рдиреЗрдЯрд╡рд░реНрдХрд╕рд╛рдареА рдЕрдВрдЧрднреВрдд рд╕рдорд░реНрдерди рдЖрдгрд┐ рдХрдВрдЯреЗрдирд░рдордзреАрд▓ рдЕреЕрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реНрдЯреЗрдЯрдлреБрд▓рдиреЗрд╕рд╕рд╣ рдЕрдзрд┐рдХ рд▓рд╡рдЪрд┐рдХ рдкреГрдердХреНрдХрд░рдг рдпрдВрддреНрд░рдгрд╛, рдкрд░рд┐рдгрд╛рдореА рдХрдВрдЯреЗрдирд░ рдЪрд╛рд▓рд╡рд┐рдгреНрдпрд╛рд╕рд╛рдареА рдореЛрдареНрдпрд╛ рд╕рдВрдЦреНрдпреЗрдиреЗ рднреМрддрд┐рдХ рд╕рд░реНрд╡реНрд╣рд░рдордзреВрди рдПрдХрдЪ рд╕рдордЧреНрд░ рд╡рд╛рддрд╛рд╡рд░рдг рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рдЪреА рдХреНрд╖рдорддрд╛ рдирд┐рд░реНрдорд╛рдг рдЭрд╛рд▓реА - рд╢рд┐рд╡рд╛рдп рдореЕрдиреНрдпреБрдЕрд▓ рд╕рдВрд╕рд╛рдзрди рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдирд╛рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛.
рдЧреЛрджреА рдХрд╛рдордЧрд╛рд░
рдбреЙрдХрд░ рд╣реЗ рд╕рд░реНрд╡рд╛рдд рдкреНрд░рд╕рд┐рджреНрдз рдЕреЕрдкреНрд▓рд┐рдХреЗрд╢рди рдХрдВрдЯреЗрдирд░рд╛рдпрдЭреЗрд╢рди рд╕реЙрдлреНрдЯрд╡реЗрдЕрд░ рдЖрд╣реЗ. рдЧреЛ рднрд╛рд╖реЗрдд рд▓рд┐рд╣рд┐рд▓реЗрд▓реЗ, рддреЗ рд▓рд┐рдирдХреНрд╕ рдХрд░реНрдирд▓рдЪреНрдпрд╛ рдирд┐рдпрдорд┐рдд рдХреНрд╖рдорддрд╛рдВрдЪрд╛ рд╡рд╛рдкрд░ рдХрд░рддреЗ - cgroups, рдиреЗрдорд╕реНрдкреЗрд╕реЗрд╕, рдХреНрд╖рдорддрд╛ рдЗ. рддрд╕реЗрдЪ Aufs рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдЖрдгрд┐ рдбрд┐рд╕реНрдХ рд╕реНрдкреЗрд╕ рд╡рд╛рдЪрд╡рдгреНрдпрд╛рд╕рд╛рдареА рддрддреНрд╕рдо рдЗрддрд░.
рд╕реНрд░реЛрдд: рд╡рд┐рдХрд┐рдореАрдбрд┐рдпрд╛
рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░
рдЖрд╡реГрддреНрддреА 1.11 рдкреВрд░реНрд╡реА, рдбреЙрдХрд░рдиреЗ рдХрдВрдЯреЗрдирд░рд╕рд╣ рд╕рд░реНрд╡ рдСрдкрд░реЗрд╢рдиреНрд╕ рдХрд░рдгрд╛рд░реА рдПрдХрд▓ рд╕реЗрд╡рд╛ рдореНрд╣рдгреВрди рдХрд╛рдо рдХреЗрд▓реЗ: рдХрдВрдЯреЗрдирд░рд╕рд╛рдареА рдкреНрд░рддрд┐рдорд╛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдгреЗ, рдХрдВрдЯреЗрдирд░ рд▓реЙрдиреНрдЪ рдХрд░рдгреЗ, API рд╡рд┐рдирдВрддреАрд╡рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░рдгреЗ. рдЖрд╡реГрддреНрддреА 1.11 рдкрд╛рд╕реВрди, рдбреЙрдХрд░ рдПрдХрдореЗрдХрд╛рдВрд╢реА рд╕рдВрд╡рд╛рдж рд╕рд╛рдзрдгрд╛рд░реЗ рдЕрдиреЗрдХ рднрд╛рдЧрд╛рдВрдордзреНрдпреЗ рд╡рд┐рднрд╛рдЧрд▓реЗ рдЧреЗрд▓реЗ рдЖрд╣реЗрдд: рдХрдВрдЯреЗрдирд░, рдХрдВрдЯреЗрдирд░рдЪреЗ рд╕рдВрдкреВрд░реНрдг рдЬреАрд╡рди рдЪрдХреНрд░ рд╣рд╛рддрд╛рд│рдгреНрдпрд╛рд╕рд╛рдареА (рдбрд┐рд╕реНрдХ рд╕реНрдкреЗрд╕рдЪреЗ рд╡рд╛рдЯрдк, рдкреНрд░рддрд┐рдорд╛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдгреЗ, рдиреЗрдЯрд╡рд░реНрдХрд┐рдВрдЧ, рд▓реЙрдиреНрдЪ рдХрд░рдгреЗ, рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдгреЗ рдЖрдгрд┐ рдХрдВрдЯреЗрдирд░рдЪреНрдпрд╛ рд╕реНрдерд┐рддреАрдЪреЗ рдирд┐рд░реАрдХреНрд╖рдг рдХрд░рдгреЗ) рдЖрдгрд┐ runC , рдХрдВрдЯреЗрдирд░ рд░рдирдЯрд╛рдЗрдореНрд╕, cgroups рдЪреНрдпрд╛ рд╡рд╛рдкрд░рд╛рд╡рд░ рдЖрдгрд┐ Linux рдХрд░реНрдирд▓рдЪреНрдпрд╛ рдЗрддрд░ рд╡реИрд╢рд┐рд╖реНрдЯреНрдпрд╛рдВрд╡рд░ рдЖрдзрд╛рд░рд┐рдд. рдбреЙрдХрд░ рд╕реЗрд╡рд╛ рд╕реНрд╡рддрдГрдЪ рд░рд╛рд╣рддреЗ, рдкрд░рдВрддреБ рдЖрддрд╛ рддреА рдлрдХреНрдд рдХрдВрдЯреЗрдирд░рд╡рд░ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХреЗрд▓реЗрд▓реНрдпрд╛ API рд╡рд┐рдирдВрддреАрд╡рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░рддреЗ.
рд╕реНрдерд╛рдкрдирд╛ рдЖрдгрд┐ рд╕рдВрд░рдЪрдирд╛
рдбреЙрдХрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдгреНрдпрд╛рдЪрд╛ рдорд╛рдЭрд╛ рдЖрд╡рдбрддрд╛ рдорд╛рд░реНрдЧ рдореНрд╣рдгрдЬреЗ рдбреЙрдХрд░-рдорд╢реАрди, рдЬреЗ рд░рд┐рдореЛрдЯ рд╕рд░реНрд╡реНрд╣рд░рд╡рд░ (рд╡рд┐рд╡рд┐рдз рдХреНрд▓рд╛рдЙрдбрд╕рд╣) рдбреЙрдХрд░ рдереЗрдЯ рд╕реНрдерд╛рдкрд┐рдд рдЖрдгрд┐ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рдгреНрдпрд╛рд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, рддреБрдореНрд╣рд╛рд▓рд╛ рд░рд┐рдореЛрдЯ рд╕рд░реНрд╡реНрд╣рд░рдЪреНрдпрд╛ рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдорд╕рд╣ рдХрд╛рд░реНрдп рдХрд░рдгреНрдпрд╛рд╕ рдЕрдиреБрдорддреА рджреЗрддреЗ рдЖрдгрд┐ рд╡рд┐рд╡рд┐рдз рдХрдорд╛рдВрдб рджреЗрдЦреАрд▓ рдЪрд╛рд▓рд╡реВ рд╢рдХрддреЗ.
рддрдерд╛рдкрд┐, 2018 рдкрд╛рд╕реВрди, рдкреНрд░рдХрд▓реНрдк рдлрд╛рд░рдЪ рдХрдореА рд╡рд┐рдХрд╕рд┐рдд рдЭрд╛рд▓рд╛ рдЖрд╣реЗ, рдореНрд╣рдгреВрди рдЖрдореНрд╣реА рдмрд╣реБрддреЗрдХ рд▓рд┐рдирдХреНрд╕ рд╡рд┐рддрд░рдгрд╛рдВрд╕рд╛рдареА рддреЗ рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдкрджреНрдзрддреАрдиреЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реВ - рдПрдХ рд░реЗрдкреЙрдЬрд┐рдЯрд░реА рдЬреЛрдбреВрди рдЖрдгрд┐ рдЖрд╡рд╢реНрдпрдХ рдкреЕрдХреЗрдЬреЗрд╕ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реВрди.
рд╣реА рдкрджреНрдзрдд рд╕реНрд╡рдпрдВрдЪрд▓рд┐рдд рд╕реНрдерд╛рдкрдиреЗрд╕рд╛рдареА рджреЗрдЦреАрд▓ рд╡рд╛рдкрд░рд▓реА рдЬрд╛рддреЗ, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЙрддреНрддрд░рджрд╛рдпреА рдХрд┐рдВрд╡рд╛ рдЗрддрд░ рддрддреНрд╕рдо рдкреНрд░рдгрд╛рд▓реА рд╡рд╛рдкрд░рдгреЗ, рдкрд░рдВрддреБ рдореА рдпрд╛ рд▓реЗрдЦрд╛рдд рдпрд╛рдЪрд╛ рд╡рд┐рдЪрд╛рд░ рдХрд░рдгрд╛рд░ рдирд╛рд╣реА.
рд╕реЗрдВрдЯреЛрд╕ 7 рд╡рд░ рд╕реНрдерд╛рдкрдирд╛ рдХреЗрд▓реА рдЬрд╛рдИрд▓, рдореА рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рдорд╢реАрди рд╕рд░реНрд╡реНрд╣рд░ рдореНрд╣рдгреВрди рд╡рд╛рдкрд░реЗрди, рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА, рдлрдХреНрдд рдЦрд╛рд▓реАрд▓ рдЖрджреЗрд╢ рдЪрд╛рд▓рд╡рд╛:
# yum install -y yum-utils
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# yum install docker-ce docker-ce-cli containerd.io
рд╕реНрдерд╛рдкрдиреЗрдирдВрддрд░, рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рд╕реЗрд╡рд╛ рд╕реБрд░реВ рдХрд░рдгреНрдпрд╛рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЖрд╣реЗ, рддреНрдпрд╛рд╕ рдСрдЯреЛрд▓реЛрдбрдордзреНрдпреЗ рдареЗрд╡рд╛:
# systemctl enable docker
# systemctl start docker
# firewall-cmd --zone=public --add-port=2377/tcp --permanent
рдпрд╛рд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, рддреБрдореНрд╣реА рдбреЙрдХрд░ рдЧрдЯ рддрдпрд╛рд░ рдХрд░реВ рд╢рдХрддрд╛, рдЬреНрдпрд╛рдЪреЗ рд╡рд╛рдкрд░рдХрд░реНрддреЗ sudo рд╢рд┐рд╡рд╛рдп рдбреЙрдХрд░рд╕реЛрдмрдд рдХрд╛рдо рдХрд░реВ рд╢рдХрддреАрд▓, рд▓реЙрдЧрд┐рдВрдЧ рд╕реЗрдЯ рдХрд░реВ рд╢рдХрддреАрд▓, рдмрд╛рд╣реЗрд░реВрди API рдордзреНрдпреЗ рдкреНрд░рд╡реЗрд╢ рд╕рдХреНрд╖рдо рдХрд░реВ рд╢рдХрддреАрд▓, рдлрд╛рдпрд░рд╡реЙрд▓ рдлрд╛рдЗрди-рдЯреНрдпреВрди рдХрд░рдгреНрдпрд╛рд╕ рд╡рд┐рд╕рд░реВ рдирдХрд╛ (рдЕрдиреБрдорддреА рдирд╕рд▓реЗрд▓реА рдкреНрд░рддреНрдпреЗрдХ рдЧреЛрд╖реНрдЯ рдЖрд╣реЗ. рд╡рд░реАрд▓ рдЖрдгрд┐ рдЦрд╛рд▓реА рдЙрджрд╛рд╣рд░рдгрд╛рдВрдордзреНрдпреЗ рдирд┐рд╖рд┐рджреНрдз - рдореА рд╣реЗ рд╕рд╛рдзреЗрдкрдгрд╛ рдЖрдгрд┐ рджреГрд╢реНрдпрд╛рд╕рд╛рдареА рд╡рдЧрд│рд▓реЗ рдЖрд╣реЗ), рдкрд░рдВрддреБ рдореА рдпреЗрдереЗ рдЕрдзрд┐рдХ рддрдкрд╢реАрд▓рд╛рдд рдЬрд╛рдгрд╛рд░ рдирд╛рд╣реА.
рдЗрддрд░ рд╡реИрд╢рд┐рд╖реНрдЯреНрдпреЗ
рд╡рд░реАрд▓ рдбреЙрдХрд░ рдорд╢реАрди рд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, рдПрдХ рдбреЙрдХрд░ рд░реЗрдЬрд┐рд╕реНрдЯреНрд░реА рджреЗрдЦреАрд▓ рдЖрд╣реЗ, рдХрдВрдЯреЗрдирд░рд╕рд╛рдареА рдкреНрд░рддрд┐рдорд╛ рд╕рдВрдЧреНрд░рд╣рд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдПрдХ рд╕рд╛рдзрди, рддрд╕реЗрдЪ рдбреЙрдХрд░ рдХрдВрдкреЛрдЭ - рдХрдВрдЯреЗрдирд░рдордзреНрдпреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧрд╛рдВрдЪреНрдпрд╛ рддреИрдирд╛рддреА рд╕реНрд╡рдпрдВрдЪрд▓рд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдПрдХ рд╕рд╛рдзрди, YAML рдлрд╛рдЗрд▓реНрд╕ рдХрдВрдЯреЗрдирд░ рддрдпрд╛рд░ рдЖрдгрд┐ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╡рд╛рдкрд░рд▓реНрдпрд╛ рдЬрд╛рддрд╛рдд рдЖрдгрд┐ рдЗрддрд░ рд╕рдВрдмрдВрдзрд┐рдд рдЧреЛрд╖реНрдЯреА (рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдиреЗрдЯрд╡рд░реНрдХ, рдбреЗрдЯрд╛ рд╕рдВрдЪрдпрд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдкрд░реНрд╕рд┐рд╕реНрдЯрдВрдЯ рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо).
рд╣реЗ CICD рд╕рд╛рдареА рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдЖрдпреЛрдЬрд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рджреЗрдЦреАрд▓ рд╡рд╛рдкрд░рд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ. рдЖрдгрдЦреА рдПрдХ рдордиреЛрд░рдВрдЬрдХ рд╡реИрд╢рд┐рд╖реНрдЯреНрдп рдХреНрд▓рд╕реНрдЯрд░ рдореЛрдбрдордзреНрдпреЗ рдХрд╛рд░реНрдп рдХрд░рдд рдЖрд╣реЗ, рддрдерд╛рдХрдерд┐рдд рд╕реНрд╡реЙрд░реНрдо рдореЛрдб (рдЖрд╡реГрддреНрддреА 1.12 рдкреВрд░реНрд╡реА рддреЗ рдбреЙрдХрд░ рд╕реНрд╡реЙрд░реНрдо рдореНрд╣рдгреВрди рдУрд│рдЦрд▓реЗ рдЬрд╛рдд рд╣реЛрддреЗ), рдЬреЗ рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдХрдВрдЯреЗрдирд░ рдЪрд╛рд▓рд╡рд┐рдгреНрдпрд╛рд╕рд╛рдареА рдЕрдиреЗрдХ рд╕рд░реНрд╡реНрд╣рд░рдордзреВрди рдПрдХрдЪ рдкрд╛рдпрд╛рднреВрдд рд╕реБрд╡рд┐рдзрд╛ рдПрдХрддреНрд░ рдХрд░рдгреНрдпрд╛рд╕ рдЕрдиреБрдорддреА рджреЗрддреЗ. рд╕рд░реНрд╡ рд╕рд░реНрд╡реНрд╣рд░рдЪреНрдпрд╛ рд╢реАрд░реНрд╖рд╕реНрдерд╛рдиреА рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рдиреЗрдЯрд╡рд░реНрдХрд╕рд╛рдареА рд╕рдорд░реНрдерди рдЖрд╣реЗ, рдЕрдВрдЧрднреВрдд рд▓реЛрдб рдмреЕрд▓рдиреНрд╕рд░ рдЖрд╣реЗ, рддрд╕реЗрдЪ рдХрдВрдЯреЗрдирд░рд╕рд╛рдареА рд░рд╣рд╕реНрдпрд╛рдВрд╕рд╛рдареА рд╕рдорд░реНрдерди рдЖрд╣реЗ.
рдбреЙрдХрд░ рдХрдВрдкреЛрдЬрдордзреАрд▓ YAML рдлрд╛рдпрд▓реА рдЕрд╢рд╛ рдХреНрд▓рд╕реНрдЯрд░рд╕рд╛рдареА рдХрд┐рд░рдХреЛрд│ рдмрджрд▓рд╛рдВрд╕рд╣ рд╡рд╛рдкрд░рд▓реНрдпрд╛ рдЬрд╛рдК рд╢рдХрддрд╛рдд, рд╡рд┐рд╡рд┐рдз рдХрд╛рд░рдгрд╛рдВрд╕рд╛рдареА рд▓рд╣рд╛рди рдЖрдгрд┐ рдордзреНрдпрдо рдХреНрд▓рд╕реНрдЯрд░реНрд╕рдЪреА рджреЗрдЦрднрд╛рд▓ рдкреВрд░реНрдгрдкрдгреЗ рд╕реНрд╡рдпрдВрдЪрд▓рд┐рдд рдХрд░рддрд╛рдд. рдореЛрдареНрдпрд╛ рдХреНрд▓рд╕реНрдЯрд░рд╕рд╛рдареА, рдХреБрдмрд░реНрдиреЗрдЯреНрд╕ рд╢реНрд░реЗрдпрд╕реНрдХрд░ рдЖрд╣реЗ рдХрд╛рд░рдг рдЭреБрдВрдб рдореЛрдб рджреЗрдЦрднрд╛рд▓ рдЦрд░реНрдЪ рдХреБрдмрд░реНрдиреЗрдЯреНрд╕рдЪреНрдпрд╛ рддреБрд▓рдиреЗрдд рдЬрд╛рд╕реНрдд рдЕрд╕реВ рд╢рдХрддреЛ. RunC рд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, рдХрдВрдЯреЗрдирд░рд╕рд╛рдареА рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреА рд╡рд╛рддрд╛рд╡рд░рдг рдореНрд╣рдгреВрди, рдЖрдкрдг рд╕реНрдерд╛рдкрд┐рдд рдХрд░реВ рд╢рдХрддрд╛, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде
рдбреЙрдХрд░рд╕реЛрдмрдд рдХрд╛рдо рдХрд░рдд рдЖрд╣реЗ
рдЗрдВрд╕реНрдЯреЙрд▓реЗрд╢рди рдЖрдгрд┐ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рдирдирдВрддрд░, рдЖрдореНрд╣реА рдПрдХ рдХреНрд▓рд╕реНрдЯрд░ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░реВ рдЬреНрдпрд╛рдордзреНрдпреЗ рдЖрдореНрд╣реА рд╡рд┐рдХрд╛рд╕ рдХрд╛рд░реНрдпрд╕рдВрдШрд╛рд╕рд╛рдареА GitLab рдЖрдгрд┐ Docker Registry рддреИрдирд╛рдд рдХрд░реВ. рд╕рд░реНрд╡реНрд╣рд░ рдореНрд╣рдгреВрди, рдореА рддреАрди рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рдорд╢реАрдиреНрд╕ рд╡рд╛рдкрд░реЗрди, рдЬреНрдпрд╛рд╡рд░ рдореА рдЕрддрд┐рд░рд┐рдХреНрддрдкрдгреЗ GlusterFS рд╡рд┐рддрд░рд┐рдд FS рддреИрдирд╛рдд рдХрд░реАрди, рдореА рддреЗ рдбреЙрдХрд░ рд╡реНрд╣реЙрд▓реНрдпреВрдо рд╕реНрдЯреЛрд░реЗрдЬ рдореНрд╣рдгреВрди рд╡рд╛рдкрд░реЗрди, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдбреЙрдХрд░ рд░реЗрдЬрд┐рд╕реНрдЯреНрд░реАрдЪреА рдЕрдпрд╢рд╕реНрд╡реА-рд╕реБрд░рдХреНрд╖рд┐рдд рдЖрд╡реГрддреНрддреА рдЪрд╛рд▓рд╡рдгреНрдпрд╛рд╕рд╛рдареА. рдЪрд╛рд▓рд╡рдгреНрдпрд╛рд╕рд╛рдареА рдкреНрд░рдореБрдЦ рдШрдЯрдХ: рдбреЙрдХрд░ рд░рдЬрд┐рд╕реНрдЯреНрд░реА, рдкреЛрд╕реНрдЯрдЧреНрд░реЗрд╕рдХреНрдпреВрдПрд▓, рд░реЗрдбрд┐рд╕, рдЧрд┐рдЯрд▓реЕрдм рд░рдирд░рдЪреНрдпрд╛ рд╕рдорд░реНрдердирд╛рд╕рд╣ рд╕реНрд╡реЙрд░реНрдордЪреНрдпрд╛ рд╡рд░. Postgresql рдХреНрд▓рд╕реНрдЯрд░рд┐рдВрдЧрд╕рд╣ рд▓рд╛рдБрдЪ рдХреЗрд▓реЗ рдЬрд╛рдИрд▓
рд╕рд░реНрд╡ рд╕рд░реНрд╡реНрд╣рд░рд╡рд░ GlusterFS рдЙрдкрдпреЛрдЬрд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА (рддреНрдпрд╛рдВрдирд╛ node1, node2, node3 рдореНрд╣рдгрддрд╛рдд), рддреБрдореНрд╣рд╛рд▓рд╛ рдкреЕрдХреЗрдЬреЗрд╕ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдгреЗ, рдлрд╛рдпрд░рд╡реЙрд▓ рд╕рдХреНрд╖рдо рдХрд░рдгреЗ, рдЖрд╡рд╢реНрдпрдХ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рддрдпрд╛рд░ рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ:
# yum -y install centos-release-gluster7
# yum -y install glusterfs-server
# systemctl enable glusterd
# systemctl start glusterd
# firewall-cmd --add-service=glusterfs --permanent
# firewall-cmd --reload
# mkdir -p /srv/gluster
# mkdir -p /srv/docker
# echo "$(hostname):/docker /srv/docker glusterfs defaults,_netdev 0 0" >> /etc/fstab
рд╕реНрдерд╛рдкрдиреЗрдирдВрддрд░, GlusterFS рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рдгреНрдпрд╛рдЪреЗ рдХрд╛рдо рдПрдХрд╛ рдиреЛрдбрд╡рд░реВрди рд╕реБрд░реВ рдареЗрд╡рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде node1:
# gluster peer probe node2
# gluster peer probe node3
# gluster volume create docker replica 3 node1:/srv/gluster node2:/srv/gluster node3:/srv/gluster force
# gluster volume start docker
рдордЧ рддреБрдореНрд╣рд╛рд▓рд╛ рдкрд░рд┐рдгрд╛рдореА рд╡реНрд╣реЙрд▓реНрдпреВрдо рдорд╛рдЙрдВрдЯ рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ (рдЖрджреЗрд╢ рд╕рд░реНрд╡ рд╕рд░реНрд╡реНрд╣рд░рд╡рд░ рдЪрд╛рд▓рд╡рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ):
# mount /srv/docker
рд╕реНрд╡реЙрд░реНрдо рдореЛрдб рдПрдХрд╛ рд╕рд░реНрд╡реНрд╣рд░рд╡рд░ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХреЗрд▓рд╛ рдЖрд╣реЗ, рдЬреЛ рд▓реАрдбрд░ рдЕрд╕реЗрд▓, рдмрд╛рдХреАрдЪреНрдпрд╛рдВрдирд╛ рдХреНрд▓рд╕реНрдЯрд░рдордзреНрдпреЗ рд╕рд╛рдореАрд▓ рд╡реНрд╣рд╛рд╡реЗ рд▓рд╛рдЧреЗрд▓, рдореНрд╣рдгреВрди рдкрд╣рд┐рд▓реНрдпрд╛ рд╕рд░реНрд╡реНрд╣рд░рд╡рд░ рдХрдорд╛рдВрдб рдЪрд╛рд▓рд╡рд▓реНрдпрд╛рдЪрд╛ рдкрд░рд┐рдгрд╛рдо рдмрд╛рдХреАрдЪреНрдпрд╛рд╡рд░ рдХреЙрдкреА рдЖрдгрд┐ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ.
рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдХреНрд▓рд╕реНрдЯрд░ рд╕реЗрдЯрдЕрдк, рдореА node1 рд╡рд░ рдХрдорд╛рдВрдб рдЪрд╛рд▓рд╡рддреЛ:
# docker swarm init
Swarm initialized: current node (a5jpfrh5uvo7svzz1ajduokyq) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-0c5mf7mvzc7o7vjk0wngno2dy70xs95tovfxbv4tqt9280toku-863hyosdlzvd76trfptd4xnzd xx.xx.xx.xx:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
# docker swarm join-token manager
рджреБрд╕рд▒реНрдпрд╛ рдХрдорд╛рдВрдбрдЪрд╛ рдирд┐рдХрд╛рд▓ рдХреЙрдкреА рдХрд░рд╛, node2 рдЖрдгрд┐ node3 рд╡рд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рд╛:
# docker swarm join --token SWMTKN-x-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxx xx.xx.xx.xx:2377
This node joined a swarm as a manager.
рд╣реЗ рд╕рд░реНрд╡реНрд╣рд░рдЪреЗ рдкреНрд░рд╛рдердорд┐рдХ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдкреВрд░реНрдг рдХрд░рддреЗ, рдЪрд▓рд╛ рд╕реЗрд╡рд╛ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рдгреЗ рд╕реБрд░реВ рдХрд░реВрдпрд╛, рдЕрдиреНрдпрдерд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреЗрд▓реНрдпрд╛рд╢рд┐рд╡рд╛рдп, рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХреЗрд▓реНрдпрд╛ рдЬрд╛рдгрд╛рд░реНтАНрдпрд╛ рдХрдорд╛рдВрдбреНрд╕ node1 рд╡рд░реВрди рд▓рд╛рдБрдЪ рдХреЗрд▓реНрдпрд╛ рдЬрд╛рддреАрд▓.
рд╕рд░реНрд╡ рдкреНрд░рдердо, рдХрдВрдЯреЗрдирд░рд╕рд╛рдареА рдиреЗрдЯрд╡рд░реНрдХ рддрдпрд╛рд░ рдХрд░реВрдпрд╛:
# docker network create --driver=overlay etcd
# docker network create --driver=overlay pgsql
# docker network create --driver=overlay redis
# docker network create --driver=overlay traefik
# docker network create --driver=overlay gitlab
рдордЧ рдЖрдореНрд╣реА рд╕рд░реНрд╡реНрд╣рд░ рдЪрд┐рдиреНрд╣рд╛рдВрдХрд┐рдд рдХрд░рддреЛ, рд╕рд░реНрд╡реНрд╣рд░рд╡рд░ рдХрд╛рд╣реА рд╕реЗрд╡рд╛ рдмрдВрдзрдирдХрд╛рд░рдХ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╣реЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ:
# docker node update --label-add nodename=node1 node1
# docker node update --label-add nodename=node2 node2
# docker node update --label-add nodename=node3 node3
рдкреБрдвреЗ, рдЖрдореНрд╣реА etcd рдбреЗрдЯрд╛ рд╕рдВрдЪрдпрд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рддрдпрд╛рд░ рдХрд░рддреЛ, рдЯреНрд░реЕрдлрд┐рдХ рдЖрдгрд┐ рд╕реНрдЯреЛрд▓реЙрдирд▓рд╛ рдЖрд╡рд╢реНрдпрдХ рдЕрд╕рд▓реЗрд▓реЗ KV рд╕реНрдЯреЛрд░реЗрдЬ. Postgresql рдкреНрд░рдорд╛рдгреЗрдЪ, рд╣реЗ рд╕рд░реНрд╡реНрд╣рд░рд▓рд╛ рдмрд╛рдВрдзрд▓реЗрд▓реЗ рдХрдВрдЯреЗрдирд░ рдЕрд╕рддреАрд▓, рдореНрд╣рдгреВрди рдЖрдореНрд╣реА рд╕рд░реНрд╡ рд╕рд░реНрд╡реНрд╣рд░рд╡рд░ рд╣реА рдЖрдЬреНрдЮрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рддреЛ:
# mkdir -p /srv/etcd
рдкреБрдвреЗ, etcd рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдлрд╛рдЗрд▓ рддрдпрд╛рд░ рдХрд░рд╛ рдЖрдгрд┐ рддреА рд▓рд╛рдЧреВ рдХрд░рд╛:
00etcd.yml
version: '3.7'
services:
etcd1:
image: quay.io/coreos/etcd:latest
hostname: etcd1
command:
- etcd
- --name=etcd1
- --data-dir=/data.etcd
- --advertise-client-urls=http://etcd1:2379
- --listen-client-urls=http://0.0.0.0:2379
- --initial-advertise-peer-urls=http://etcd1:2380
- --listen-peer-urls=http://0.0.0.0:2380
- --initial-cluster=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380
- --initial-cluster-state=new
- --initial-cluster-token=etcd-cluster
networks:
- etcd
volumes:
- etcd1vol:/data.etcd
deploy:
replicas: 1
placement:
constraints: [node.labels.nodename == node1]
etcd2:
image: quay.io/coreos/etcd:latest
hostname: etcd2
command:
- etcd
- --name=etcd2
- --data-dir=/data.etcd
- --advertise-client-urls=http://etcd2:2379
- --listen-client-urls=http://0.0.0.0:2379
- --initial-advertise-peer-urls=http://etcd2:2380
- --listen-peer-urls=http://0.0.0.0:2380
- --initial-cluster=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380
- --initial-cluster-state=new
- --initial-cluster-token=etcd-cluster
networks:
- etcd
volumes:
- etcd2vol:/data.etcd
deploy:
replicas: 1
placement:
constraints: [node.labels.nodename == node2]
etcd3:
image: quay.io/coreos/etcd:latest
hostname: etcd3
command:
- etcd
- --name=etcd3
- --data-dir=/data.etcd
- --advertise-client-urls=http://etcd3:2379
- --listen-client-urls=http://0.0.0.0:2379
- --initial-advertise-peer-urls=http://etcd3:2380
- --listen-peer-urls=http://0.0.0.0:2380
- --initial-cluster=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380
- --initial-cluster-state=new
- --initial-cluster-token=etcd-cluster
networks:
- etcd
volumes:
- etcd3vol:/data.etcd
deploy:
replicas: 1
placement:
constraints: [node.labels.nodename == node3]
volumes:
etcd1vol:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/etcd"
etcd2vol:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/etcd"
etcd3vol:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/etcd"
networks:
etcd:
external: true
# docker stack deploy --compose-file 00etcd.yml etcd
рдереЛрдбреНрдпрд╛ рд╡реЗрд│рд╛рдиреЗ, рдЖрдореНрд╣реА рддрдкрд╛рд╕рддреЛ рдХреА etcd рдХреНрд▓рд╕реНрдЯрд░ рд╡рд╛рдврд▓рд╛ рдЖрд╣реЗ:
# docker exec $(docker ps | awk '/etcd/ {print $1}') etcdctl member list
ade526d28b1f92f7: name=etcd1 peerURLs=http://etcd1:2380 clientURLs=http://etcd1:2379 isLeader=false
bd388e7810915853: name=etcd3 peerURLs=http://etcd3:2380 clientURLs=http://etcd3:2379 isLeader=false
d282ac2ce600c1ce: name=etcd2 peerURLs=http://etcd2:2380 clientURLs=http://etcd2:2379 isLeader=true
# docker exec $(docker ps | awk '/etcd/ {print $1}') etcdctl cluster-health
member ade526d28b1f92f7 is healthy: got healthy result from http://etcd1:2379
member bd388e7810915853 is healthy: got healthy result from http://etcd3:2379
member d282ac2ce600c1ce is healthy: got healthy result from http://etcd2:2379
cluster is healthy
Postgresql рд╕рд╛рдареА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рддрдпрд╛рд░ рдХрд░рд╛, рд╕рд░реНрд╡ рд╕рд░реНрд╡реНрд╣рд░рд╡рд░ рдХрдорд╛рдВрдб рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рд╛:
# mkdir -p /srv/pgsql
рдкреБрдвреЗ, Postgresql рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдлрд╛рдЗрд▓ рддрдпрд╛рд░ рдХрд░рд╛:
01pgsql.yml
version: '3.7'
services:
pgsentinel:
image: sorintlab/stolon:master-pg10
command:
- gosu
- stolon
- stolon-sentinel
- --cluster-name=stolon-cluster
- --store-backend=etcdv3
- --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379
- --log-level=debug
networks:
- etcd
- pgsql
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 30s
order: stop-first
failure_action: pause
pgkeeper1:
image: sorintlab/stolon:master-pg10
hostname: pgkeeper1
command:
- gosu
- stolon
- stolon-keeper
- --pg-listen-address=pgkeeper1
- --pg-repl-username=replica
- --uid=pgkeeper1
- --pg-su-username=postgres
- --pg-su-passwordfile=/run/secrets/pgsql
- --pg-repl-passwordfile=/run/secrets/pgsql_repl
- --data-dir=/var/lib/postgresql/data
- --cluster-name=stolon-cluster
- --store-backend=etcdv3
- --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379
networks:
- etcd
- pgsql
environment:
- PGDATA=/var/lib/postgresql/data
volumes:
- pgkeeper1:/var/lib/postgresql/data
secrets:
- pgsql
- pgsql_repl
deploy:
replicas: 1
placement:
constraints: [node.labels.nodename == node1]
pgkeeper2:
image: sorintlab/stolon:master-pg10
hostname: pgkeeper2
command:
- gosu
- stolon
- stolon-keeper
- --pg-listen-address=pgkeeper2
- --pg-repl-username=replica
- --uid=pgkeeper2
- --pg-su-username=postgres
- --pg-su-passwordfile=/run/secrets/pgsql
- --pg-repl-passwordfile=/run/secrets/pgsql_repl
- --data-dir=/var/lib/postgresql/data
- --cluster-name=stolon-cluster
- --store-backend=etcdv3
- --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379
networks:
- etcd
- pgsql
environment:
- PGDATA=/var/lib/postgresql/data
volumes:
- pgkeeper2:/var/lib/postgresql/data
secrets:
- pgsql
- pgsql_repl
deploy:
replicas: 1
placement:
constraints: [node.labels.nodename == node2]
pgkeeper3:
image: sorintlab/stolon:master-pg10
hostname: pgkeeper3
command:
- gosu
- stolon
- stolon-keeper
- --pg-listen-address=pgkeeper3
- --pg-repl-username=replica
- --uid=pgkeeper3
- --pg-su-username=postgres
- --pg-su-passwordfile=/run/secrets/pgsql
- --pg-repl-passwordfile=/run/secrets/pgsql_repl
- --data-dir=/var/lib/postgresql/data
- --cluster-name=stolon-cluster
- --store-backend=etcdv3
- --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379
networks:
- etcd
- pgsql
environment:
- PGDATA=/var/lib/postgresql/data
volumes:
- pgkeeper3:/var/lib/postgresql/data
secrets:
- pgsql
- pgsql_repl
deploy:
replicas: 1
placement:
constraints: [node.labels.nodename == node3]
postgresql:
image: sorintlab/stolon:master-pg10
command: gosu stolon stolon-proxy --listen-address 0.0.0.0 --cluster-name stolon-cluster --store-backend=etcdv3 --store-endpoints http://etcd1:2379,http://etcd2:2379,http://etcd3:2379
networks:
- etcd
- pgsql
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 30s
order: stop-first
failure_action: rollback
volumes:
pgkeeper1:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/pgsql"
pgkeeper2:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/pgsql"
pgkeeper3:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/pgsql"
secrets:
pgsql:
file: "/srv/docker/postgres"
pgsql_repl:
file: "/srv/docker/replica"
networks:
etcd:
external: true
pgsql:
external: true
рдЖрдореНрд╣реА рд░рд╣рд╕реНрдпреЗ рд╡реНрдпреБрддреНрдкрдиреНрди рдХрд░рддреЛ, рдлрд╛рдЗрд▓ рд▓рд╛рдЧреВ рдХрд░рддреЛ:
# </dev/urandom tr -dc 234567890qwertyuopasdfghjkzxcvbnmQWERTYUPASDFGHKLZXCVBNM | head -c $(((RANDOM%3)+15)) > /srv/docker/replica
# </dev/urandom tr -dc 234567890qwertyuopasdfghjkzxcvbnmQWERTYUPASDFGHKLZXCVBNM | head -c $(((RANDOM%3)+15)) > /srv/docker/postgres
# docker stack deploy --compose-file 01pgsql.yml pgsql
рдХрд╛рд╣реА рд╡реЗрд│рд╛рдиреЗ (рдЖрджреЗрд╢рд╛рдЪреЗ рдЖрдЙрдЯрдкреБрдЯ рдкрд╣рд╛ рдбреЙрдХрд░ рд╕реЗрд╡рд╛ lsрдХреА рд╕рд░реНрд╡ рд╕реЗрд╡рд╛ рд╡рд╛рдврд▓реНрдпрд╛ рдЖрд╣реЗрдд) Postgresql рдХреНрд▓рд╕реНрдЯрд░ рд╕реБрд░реВ рдХрд░рд╛:
# docker exec $(docker ps | awk '/pgkeeper/ {print $1}') stolonctl --cluster-name=stolon-cluster --store-backend=etcdv3 --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379 init
Postgresql рдХреНрд▓рд╕реНрдЯрд░рдЪреА рддрдпрд╛рд░реА рддрдкрд╛рд╕рдд рдЖрд╣реЗ:
# docker exec $(docker ps | awk '/pgkeeper/ {print $1}') stolonctl --cluster-name=stolon-cluster --store-backend=etcdv3 --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379 status
=== Active sentinels ===
ID LEADER
26baa11d false
74e98768 false
a8cb002b true
=== Active proxies ===
ID
4d233826
9f562f3b
b0c79ff1
=== Keepers ===
UID HEALTHY PG LISTENADDRESS PG HEALTHY PG WANTEDGENERATION PG CURRENTGENERATION
pgkeeper1 true pgkeeper1:5432 true 2 2
pgkeeper2 true pgkeeper2:5432 true 2 2
pgkeeper3 true pgkeeper3:5432 true 3 3
=== Cluster Info ===
Master Keeper: pgkeeper3
===== Keepers/DB tree =====
pgkeeper3 (master)
тФЬтФАpgkeeper2
тФФтФАpgkeeper1
рдЖрдореНрд╣реА рдмрд╛рд╣реЗрд░реВрди рдХрдВрдЯреЗрдирд░рдордзреНрдпреЗ рдкреНрд░рд╡реЗрд╢ рдЙрдШрдбрдгреНрдпрд╛рд╕рд╛рдареА рдЯреНрд░реЕрдлрд┐рдХ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рддреЛ:
03traefik.yml
version: '3.7'
services:
traefik:
image: traefik:latest
command: >
--log.level=INFO
--providers.docker=true
--entryPoints.web.address=:80
--providers.providersThrottleDuration=2
--providers.docker.watch=true
--providers.docker.swarmMode=true
--providers.docker.swarmModeRefreshSeconds=15s
--providers.docker.exposedbydefault=false
--accessLog.bufferingSize=0
--api=true
--api.dashboard=true
--api.insecure=true
networks:
- traefik
ports:
- 80:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
replicas: 3
placement:
constraints:
- node.role == manager
preferences:
- spread: node.id
labels:
- traefik.enable=true
- traefik.http.routers.traefik.rule=Host(`traefik.example.com`)
- traefik.http.services.traefik.loadbalancer.server.port=8080
- traefik.docker.network=traefik
networks:
traefik:
external: true
# docker stack deploy --compose-file 03traefik.yml traefik
рдЖрдореНрд╣реА рд░реЗрдбрд┐рд╕ рдХреНрд▓рд╕реНрдЯрд░ рд╕реБрд░реВ рдХрд░рддреЛ, рдпрд╛рд╕рд╛рдареА рдЖрдореНрд╣реА рд╕рд░реНрд╡ рдиреЛрдбреНрд╕рд╡рд░ рд╕реНрдЯреЛрд░реЗрдЬ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рддрдпрд╛рд░ рдХрд░рддреЛ:
# mkdir -p /srv/redis
05redis.yml
version: '3.7'
services:
redis-master:
image: 'bitnami/redis:latest'
networks:
- redis
ports:
- '6379:6379'
environment:
- REDIS_REPLICATION_MODE=master
- REDIS_PASSWORD=xxxxxxxxxxx
deploy:
mode: global
restart_policy:
condition: any
volumes:
- 'redis:/opt/bitnami/redis/etc/'
redis-replica:
image: 'bitnami/redis:latest'
networks:
- redis
ports:
- '6379'
depends_on:
- redis-master
environment:
- REDIS_REPLICATION_MODE=slave
- REDIS_MASTER_HOST=redis-master
- REDIS_MASTER_PORT_NUMBER=6379
- REDIS_MASTER_PASSWORD=xxxxxxxxxxx
- REDIS_PASSWORD=xxxxxxxxxxx
deploy:
mode: replicated
replicas: 3
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: any
redis-sentinel:
image: 'bitnami/redis:latest'
networks:
- redis
ports:
- '16379'
depends_on:
- redis-master
- redis-replica
entrypoint: |
bash -c 'bash -s <<EOF
"/bin/bash" -c "cat <<EOF > /opt/bitnami/redis/etc/sentinel.conf
port 16379
dir /tmp
sentinel monitor master-node redis-master 6379 2
sentinel down-after-milliseconds master-node 5000
sentinel parallel-syncs master-node 1
sentinel failover-timeout master-node 5000
sentinel auth-pass master-node xxxxxxxxxxx
sentinel announce-ip redis-sentinel
sentinel announce-port 16379
EOF"
"/bin/bash" -c "redis-sentinel /opt/bitnami/redis/etc/sentinel.conf"
EOF'
deploy:
mode: global
restart_policy:
condition: any
volumes:
redis:
driver: local
driver_opts:
type: 'none'
o: 'bind'
device: "/srv/redis"
networks:
redis:
external: true
# docker stack deploy --compose-file 05redis.yml redis
рдбреЙрдХрд░ рд░реЗрдЬрд┐рд╕реНрдЯреНрд░реА рдЬреЛрдбрд╛:
06registry.yml
version: '3.7'
services:
registry:
image: registry:2.6
networks:
- traefik
volumes:
- registry_data:/var/lib/registry
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
restart_policy:
condition: on-failure
labels:
- traefik.enable=true
- traefik.http.routers.registry.rule=Host(`registry.example.com`)
- traefik.http.services.registry.loadbalancer.server.port=5000
- traefik.docker.network=traefik
volumes:
registry_data:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/docker/registry"
networks:
traefik:
external: true
# mkdir /srv/docker/registry
# docker stack deploy --compose-file 06registry.yml registry
рдЖрдгрд┐ рд╢реЗрд╡рдЯреА - GitLab:
08gitlab-runner.yml
version: '3.7'
services:
gitlab:
image: gitlab/gitlab-ce:latest
networks:
- pgsql
- redis
- traefik
- gitlab
ports:
- 22222:22
environment:
GITLAB_OMNIBUS_CONFIG: |
postgresql['enable'] = false
redis['enable'] = false
gitlab_rails['registry_enabled'] = false
gitlab_rails['db_username'] = "gitlab"
gitlab_rails['db_password'] = "XXXXXXXXXXX"
gitlab_rails['db_host'] = "postgresql"
gitlab_rails['db_port'] = "5432"
gitlab_rails['db_database'] = "gitlab"
gitlab_rails['db_adapter'] = 'postgresql'
gitlab_rails['db_encoding'] = 'utf8'
gitlab_rails['redis_host'] = 'redis-master'
gitlab_rails['redis_port'] = '6379'
gitlab_rails['redis_password'] = 'xxxxxxxxxxx'
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.yandex.ru"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "[email protected]"
gitlab_rails['smtp_password'] = "xxxxxxxxx"
gitlab_rails['smtp_domain'] = "example.com"
gitlab_rails['gitlab_email_from'] = '[email protected]'
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_tls'] = true
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_openssl_verify_mode'] = 'peer'
external_url 'http://gitlab.example.com/'
gitlab_rails['gitlab_shell_ssh_port'] = 22222
volumes:
- gitlab_conf:/etc/gitlab
- gitlab_logs:/var/log/gitlab
- gitlab_data:/var/opt/gitlab
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role == manager
labels:
- traefik.enable=true
- traefik.http.routers.gitlab.rule=Host(`gitlab.example.com`)
- traefik.http.services.gitlab.loadbalancer.server.port=80
- traefik.docker.network=traefik
gitlab-runner:
image: gitlab/gitlab-runner:latest
networks:
- gitlab
volumes:
- gitlab_runner_conf:/etc/gitlab
- /var/run/docker.sock:/var/run/docker.sock
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role == manager
volumes:
gitlab_conf:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/docker/gitlab/conf"
gitlab_logs:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/docker/gitlab/logs"
gitlab_data:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/docker/gitlab/data"
gitlab_runner_conf:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/docker/gitlab/runner"
networks:
pgsql:
external: true
redis:
external: true
traefik:
external: true
gitlab:
external: true
# mkdir -p /srv/docker/gitlab/conf
# mkdir -p /srv/docker/gitlab/logs
# mkdir -p /srv/docker/gitlab/data
# mkdir -p /srv/docker/gitlab/runner
# docker stack deploy --compose-file 08gitlab-runner.yml gitlab
рдХреНрд▓рд╕реНрдЯрд░ рдЖрдгрд┐ рд╕реЗрд╡рд╛рдВрдЪреА рдЕрдВрддрд┐рдо рд╕реНрдерд┐рддреА:
# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
lef9n3m92buq etcd_etcd1 replicated 1/1 quay.io/coreos/etcd:latest
ij6uyyo792x5 etcd_etcd2 replicated 1/1 quay.io/coreos/etcd:latest
fqttqpjgp6pp etcd_etcd3 replicated 1/1 quay.io/coreos/etcd:latest
hq5iyga28w33 gitlab_gitlab replicated 1/1 gitlab/gitlab-ce:latest *:22222->22/tcp
dt7s6vs0q4qc gitlab_gitlab-runner replicated 1/1 gitlab/gitlab-runner:latest
k7uoezno0h9n pgsql_pgkeeper1 replicated 1/1 sorintlab/stolon:master-pg10
cnrwul4r4nse pgsql_pgkeeper2 replicated 1/1 sorintlab/stolon:master-pg10
frflfnpty7tr pgsql_pgkeeper3 replicated 1/1 sorintlab/stolon:master-pg10
x7pqqchi52kq pgsql_pgsentinel replicated 3/3 sorintlab/stolon:master-pg10
mwu2wl8fti4r pgsql_postgresql replicated 3/3 sorintlab/stolon:master-pg10
9hkbe2vksbzb redis_redis-master global 3/3 bitnami/redis:latest *:6379->6379/tcp
l88zn8cla7dc redis_redis-replica replicated 3/3 bitnami/redis:latest *:30003->6379/tcp
1utp309xfmsy redis_redis-sentinel global 3/3 bitnami/redis:latest *:30002->16379/tcp
oteb824ylhyp registry_registry replicated 1/1 registry:2.6
qovrah8nzzu8 traefik_traefik replicated 3/3 traefik:latest *:80->80/tcp, *:443->443/tcp
рдЖрдгрдЦреА рдХрд╛рдп рд╕реБрдзрд╛рд░рддрд╛ рдпреЗрдИрд▓? https рдХрдВрдЯреЗрдирд░рд╕рд╣ рдХрд╛рд░реНрдп рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА Traefik рдХреЙрдиреНрдлрд┐рдЧрд░ рдХреЗрд▓реНрдпрд╛рдЪреА рдЦрд╛рддреНрд░реА рдХрд░рд╛, Postgresql рдЖрдгрд┐ Redis рд╕рд╛рдареА tls рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдЬреЛрдбрд╛. рдкрд░рдВрддреБ рд╕рд░реНрд╡рд╕рд╛рдзрд╛рд░рдгрдкрдгреЗ, рддреБрдореНрд╣реА рддреЗ рдЖрдзреАрдЪ рд╡рд┐рдХрд╕рдХрд╛рдВрдирд╛ PoC рдореНрд╣рдгреВрди рджреЗрдК рд╢рдХрддрд╛. рдЖрддрд╛ рдбреЙрдХрд░рдЪреЗ рдкрд░реНрдпрд╛рдп рдкрд╛рд╣реВ.
рдкреЛрдбрдореЕрди
рдкреЙрдбреНрд╕рджреНрд╡рд╛рд░реЗ рдЧрдЯрдмрджреНрдз рдХреЗрд▓реЗрд▓реЗ рдХрдВрдЯреЗрдирд░ рдЪрд╛рд▓рд╡рд┐рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдгрдЦреА рдПрдХ рд╕реБрдкреНрд░рд╕рд┐рджреНрдз рдЗрдВрдЬрд┐рди (рд╢реЗрдВрдЧрд╛, рдХрдВрдЯреЗрдирд░рдЪреЗ рдЧрдЯ рдПрдХрддреНрд░ рддреИрдирд╛рдд). рдбреЙрдХрд░рдЪреНрдпрд╛ рд╡рд┐рдкрд░реАрдд, рдХрдВрдЯреЗрдирд░ рдЪрд╛рд▓рд╡рд┐рдгреНрдпрд╛рд╕рд╛рдареА рдХреЛрдгрддреНрдпрд╛рд╣реА рд╕реЗрд╡реЗрдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╛рд╣реА, рд╕рд░реНрд╡ рдХрд╛рдо рд▓рд┐рдмрдкреЙрдб рд▓рд╛рдпрдмреНрд░рд░реАрджреНрд╡рд╛рд░реЗ рдХреЗрд▓реЗ рдЬрд╛рддреЗ. Go рдордзреНрдпреЗ рджреЗрдЦреАрд▓ рд▓рд┐рд╣рд┐рд▓реЗрд▓реЗ рдЖрд╣реЗ, runC рд╕рд╛рд░рдЦреЗ рдХрдВрдЯреЗрдирд░ рдЪрд╛рд▓рд╡рд┐рдгреНрдпрд╛рд╕рд╛рдареА OCI рдЕрдиреБрд░реВрдк рд░рдирдЯрд╛рдЗрдо рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ.
рдкреЙрдбрдореЕрдирд╕реЛрдмрдд рдХрд╛рдо рдХрд░рдгреЗ рд╕рд░реНрд╡рд╕рд╛рдзрд╛рд░рдгрдкрдгреЗ рдбреЙрдХрд░рд╕рд╛рд░рдЦреЗрдЪ рдЖрд╣реЗ, рдЬреНрдпрд╛ рдкреНрд░рдорд╛рдгрд╛рдд рддреБрдореНрд╣реА рд╣реЗ рдЕрд╕реЗ рдХрд░реВ рд╢рдХрддрд╛ (рдпрд╛ рд▓реЗрдЦрд╛рдЪреНрдпрд╛ рд▓реЗрдЦрдХрд╛рд╕рд╣ рдЕрдиреЗрдХрд╛рдВрдиреА рдкреНрд░рдпрддреНрди рдХреЗрд▓рд╛ рдЖрд╣реЗ рдЕрд╕рд╛ рджрд╛рд╡рд╛ рдХреЗрд▓рд╛ рдЖрд╣реЗ):
$ alias docker=podman
рдЖрдгрд┐ рддреБрдореНрд╣реА рдХрд╛рдо рдХрд░рдд рд░рд╛рд╣реВ рд╢рдХрддрд╛. рд╕рд░реНрд╡рд╕рд╛рдзрд╛рд░рдгрдкрдгреЗ, рдкреЙрдбрдореЕрдирдЪреА рдкрд░рд┐рд╕реНрдерд┐рддреА рдЦреВрдк рдордиреЛрд░рдВрдЬрдХ рдЖрд╣реЗ, рдХрд╛рд░рдг рдЬрд░ рдХреБрдмрд░реНрдиреЗрдЯреНрд╕рдЪреНрдпрд╛ рд╕реБрд░реБрд╡рд╛рддреАрдЪреНрдпрд╛ рдЖрд╡реГрддреНрддреНрдпрд╛рдВрдиреА рдбреЙрдХрд░рд╕реЛрдмрдд рдХрд╛рдо рдХреЗрд▓реЗ рдЕрд╕реЗрд▓, рддрд░ рд╕реБрдорд╛рд░реЗ 2015 рдкрд╛рд╕реВрди, рдХрдВрдЯреЗрдирд░ рд╡рд░реНрд▓реНрдб (рдУрд╕реАрдЖрдп - рдУрдкрди рдХрдВрдЯреЗрдирд░ рдЗрдирд┐рд╢рд┐рдПрдЯрд┐рд╡реНрд╣) рдкреНрд░рдорд╛рдгрд┐рдд рдХреЗрд▓реНрдпрд╛рдирдВрддрд░ рдЖрдгрд┐ рдбреЙрдХрд░рд▓рд╛ рдХрдВрдЯреЗрдирд░ рдЖрдгрд┐ рд░рдирд╕реАрдордзреНрдпреЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХреЗрд▓реНрдпрд╛рдирдВрддрд░, рдкрд░реНрдпрд╛рдпреА рдбреЙрдХрд░ рдХреБрдмрд░реНрдиреЗрдЯреНрд╕рдордзреНрдпреЗ рдЪрд╛рд▓рд╡рд┐рдгреНрдпрд╛рд╕рд╛рдареА рд╡рд┐рдХрд╕рд┐рдд рдХреЗрд▓реЗ рдЬрд╛рдд рдЖрд╣реЗ: CRI-O. рдпрд╛ рд╕рдВрджрд░реНрднрд╛рдд рдкреЙрдбрдореЕрди рд╣рд╛ рдХрдВрдЯреЗрдирд░ рдЧреНрд░реБрдкрд┐рдВрдЧрд╕рд╣ рдХреБрдмрд░реНрдиреЗрдЯреНрд╕рдЪреНрдпрд╛ рддрддреНрддреНрд╡рд╛рдВрд╡рд░ рддрдпрд╛рд░ рдХреЗрд▓реЗрд▓рд╛ рдбреЙрдХрд░рдЪрд╛ рдкрд░реНрдпрд╛рдп рдЖрд╣реЗ, рдкрд░рдВрддреБ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕реЗрд╡рд╛рдВрд╢рд┐рд╡рд╛рдп рдбреЙрдХрд░-рд╢реИрд▓реАрддреАрд▓ рдХрдВрдЯреЗрдирд░ рдЪрд╛рд▓рд╡рдгреЗ рд╣реЗ рдкреНрд░рдХрд▓реНрдкрд╛рдЪреЗ рдореБрдЦреНрдп рдзреНрдпреЗрдп рдЖрд╣реЗ. рд╕реНрдкрд╖реНрдЯ рдХрд╛рд░рдгрд╛рд╕реНрддрд╡, рдХреЛрдгрддрд╛рд╣реА рдЭреБрдВрдб рдореЛрдб рдирд╛рд╣реА, рдХрд╛рд░рдг рд╡рд┐рдХрд╕рдХ рд╕реНрдкрд╖реНрдЯрдкрдгреЗ рдореНрд╣рдгрддрд╛рдд рдХреА рдЬрд░ рддреБрдореНрд╣рд╛рд▓рд╛ рдХреНрд▓рд╕реНрдЯрд░рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЕрд╕реЗрд▓ рддрд░ рдХреБрдмрд░реНрдиреЗрдЯреНрд╕ рдШреНрдпрд╛.
рд╕реЗрдЯрд┐рдВрдЧ
рд╕реЗрдВрдЯреЛрд╕ 7 рд╡рд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА, рдлрдХреНрдд рдПрдХреНрд╕реНрдЯреНрд░рд╛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕рдХреНрд░рд┐рдп рдХрд░рд╛ рдЖрдгрд┐ рдирдВрддрд░ рдХрдорд╛рдВрдбрд╕рд╣ рд╕рд░реНрд╡рдХрд╛рд╣реА рд╕реНрдерд╛рдкрд┐рдд рдХрд░рд╛:
# yum -y install podman
рдЗрддрд░ рд╡реИрд╢рд┐рд╖реНрдЯреНрдпреЗ
рдкреЙрдбрдореЕрди рд╕рд┐рд╕реНрдЯрдордбрд╕рд╛рдареА рдпреБрдирд┐рдЯреНрд╕ рд╡реНрдпреБрддреНрдкрдиреНрди рдХрд░реВ рд╢рдХрддреЛ, рдЕрд╢рд╛ рдкреНрд░рдХрд╛рд░реЗ рд╕рд░реНрд╡реНрд╣рд░ рд░реАрдмреВрдЯ рдХреЗрд▓реНрдпрд╛рдирдВрддрд░ рдХрдВрдЯреЗрдирд░ рд╕реБрд░реВ рдХрд░рдгреНрдпрд╛рдЪреА рд╕рдорд╕реНрдпрд╛ рд╕реЛрдбрд╡рддреЗ. рдпрд╛рд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, рдХрдВрдЯреЗрдирд░рдордзреНрдпреЗ pid 1 рдореНрд╣рдгреВрди рдпреЛрдЧреНрдпрд░рд┐рддреНрдпрд╛ рдХрд╛рд░реНрдп рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА systemd рдШреЛрд╖рд┐рдд рдХреЗрд▓реЗ рдЬрд╛рддреЗ. рдХрдВрдЯреЗрдирд░ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА, рдПрдХ рд╡реЗрдЧрд│реЗ рдмрд┐рд▓реНрдбрд╣ рдЯреВрд▓ рдЖрд╣реЗ, рддреЗрдереЗ рддреГрддреАрдп-рдкрдХреНрд╖ рд╕рд╛рдзрдиреЗ рджреЗрдЦреАрд▓ рдЖрд╣реЗрдд - рдбреЙрдХрд░-рдХрдВрдкреЛрдЬрдЪреЗ рдЕреЕрдирд╛рд▓реЙрдЧреНрд╕, рдЬреЗ рдХреБрдмрд░реНрдиреЗрдЯреНрд╕-рд╕реБрд╕рдВрдЧрдд рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдлрд╛рдЗрд▓реНрд╕ рджреЗрдЦреАрд▓ рд╡реНрдпреБрддреНрдкрдиреНрди рдХрд░рддрд╛рдд, рддреНрдпрд╛рдореБрд│реЗ рдкреЙрдбрдореЕрдирдкрд╛рд╕реВрди рдХреБрдмрд░реНрдиреЗрдЯреНрд╕рдордзреНрдпреЗ рд╕рдВрдХреНрд░рдордг рд╢рдХреНрдп рддрд┐рддрдХреЗ рд╕реЛрдкреЗ рдЖрд╣реЗ.
рдкреЙрдбрдореЕрдирд╕реЛрдмрдд рдХрд╛рдо рдХрд░рдд рдЖрд╣реЗ
рдХреЛрдгрддрд╛рд╣реА рдЭреБрдВрдб рдореЛрдб рдирд╕рд▓реНрдпрд╛рдореБрд│реЗ (рдХреНрд▓рд╕реНрдЯрд░рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЕрд╕рд▓реНрдпрд╛рд╕ рддреЗ рдХреБрдмрд░реНрдиреЗрдЯреНрд╕рд╡рд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдгреЗ рдЕрдкреЗрдХреНрд╖рд┐рдд рдЖрд╣реЗ), рдЖрдореНрд╣реА рддреЗ рд╡реЗрдЧрд│реНрдпрд╛ рдХрдВрдЯреЗрдирд░рдордзреНрдпреЗ рдПрдХрддреНрд░ рдХрд░реВ.
рдкреЙрдбрдореЕрди-рдХрдВрдкреЛрдЬ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рд╛:
# yum -y install python3-pip
# pip3 install podman-compose
рдкреЙрдбрдореЕрдирд╕рд╛рдареА рдкрд░рд┐рдгрд╛рдореА рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдлрд╛рдЗрд▓ рдереЛрдбреА рд╡реЗрдЧрд│реА рдЖрд╣реЗ, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде рдЖрдореНрд╣рд╛рд▓рд╛ рдПрдХ рд╡реЗрдЧрд│рд╛ рдЦрдВрдб рд╡рд┐рднрд╛рдЧ рдереЗрдЯ рд╕реЗрд╡рд╛ рд╡рд┐рднрд╛рдЧрд╛рдд рд╣рд▓рд╡рд╛рд╡рд╛ рд▓рд╛рдЧрд▓рд╛.
gitlab-podman.yml
version: '3.7'
services:
gitlab:
image: gitlab/gitlab-ce:latest
hostname: gitlab.example.com
restart: unless-stopped
environment:
GITLAB_OMNIBUS_CONFIG: |
gitlab_rails['gitlab_shell_ssh_port'] = 22222
ports:
- "80:80"
- "22222:22"
volumes:
- /srv/podman/gitlab/conf:/etc/gitlab
- /srv/podman/gitlab/data:/var/opt/gitlab
- /srv/podman/gitlab/logs:/var/log/gitlab
networks:
- gitlab
gitlab-runner:
image: gitlab/gitlab-runner:alpine
restart: unless-stopped
depends_on:
- gitlab
volumes:
- /srv/podman/gitlab/runner:/etc/gitlab-runner
- /var/run/docker.sock:/var/run/docker.sock
networks:
- gitlab
networks:
gitlab:
# podman-compose -f gitlab-runner.yml -d up
рдХрд╛рдорд╛рдЪрд╛ рдкрд░рд┐рдгрд╛рдо:
# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
da53da946c01 docker.io/gitlab/gitlab-runner:alpine run --user=gitlab... About a minute ago Up About a minute ago 0.0.0.0:22222->22/tcp, 0.0.0.0:80->80/tcp root_gitlab-runner_1
781c0103c94a docker.io/gitlab/gitlab-ce:latest /assets/wrapper About a minute ago Up About a minute ago 0.0.0.0:22222->22/tcp, 0.0.0.0:80->80/tcp root_gitlab_1
рддреЗ systemd рдЖрдгрд┐ kubernetes рд╕рд╛рдареА рдХрд╛рдп рд╡реНрдпреБрддреНрдкрдиреНрди рдХрд░реЗрд▓ рддреЗ рдкрд╛рд╣реВ рдпрд╛, рдпрд╛рд╕рд╛рдареА рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдкреЙрдбрдЪреЗ рдирд╛рд╡ рдХрд┐рдВрд╡рд╛ рдЖрдпрдбреА рд╢реЛрдзрдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ:
# podman pod ls
POD ID NAME STATUS CREATED # OF CONTAINERS INFRA ID
71fc2b2a5c63 root Running 11 minutes ago 3 db40ab8bf84b
рдХреБрдмрд░реНрдиреЗрдЯреНрд╕:
# podman generate kube 71fc2b2a5c63
# Generation of Kubernetes YAML is still under development!
#
# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-1.6.4
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2020-07-29T19:22:40Z"
labels:
app: root
name: root
spec:
containers:
- command:
- /assets/wrapper
env:
- name: PATH
value: /opt/gitlab/embedded/bin:/opt/gitlab/bin:/assets:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- name: TERM
value: xterm
- name: HOSTNAME
value: gitlab.example.com
- name: container
value: podman
- name: GITLAB_OMNIBUS_CONFIG
value: |
gitlab_rails['gitlab_shell_ssh_port'] = 22222
- name: LANG
value: C.UTF-8
image: docker.io/gitlab/gitlab-ce:latest
name: rootgitlab1
ports:
- containerPort: 22
hostPort: 22222
protocol: TCP
- containerPort: 80
hostPort: 80
protocol: TCP
resources: {}
securityContext:
allowPrivilegeEscalation: true
capabilities: {}
privileged: false
readOnlyRootFilesystem: false
volumeMounts:
- mountPath: /var/opt/gitlab
name: srv-podman-gitlab-data
- mountPath: /var/log/gitlab
name: srv-podman-gitlab-logs
- mountPath: /etc/gitlab
name: srv-podman-gitlab-conf
workingDir: /
- command:
- run
- --user=gitlab-runner
- --working-directory=/home/gitlab-runner
env:
- name: PATH
value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- name: TERM
value: xterm
- name: HOSTNAME
- name: container
value: podman
image: docker.io/gitlab/gitlab-runner:alpine
name: rootgitlab-runner1
resources: {}
securityContext:
allowPrivilegeEscalation: true
capabilities: {}
privileged: false
readOnlyRootFilesystem: false
volumeMounts:
- mountPath: /etc/gitlab-runner
name: srv-podman-gitlab-runner
- mountPath: /var/run/docker.sock
name: var-run-docker.sock
workingDir: /
volumes:
- hostPath:
path: /srv/podman/gitlab/runner
type: Directory
name: srv-podman-gitlab-runner
- hostPath:
path: /var/run/docker.sock
type: File
name: var-run-docker.sock
- hostPath:
path: /srv/podman/gitlab/data
type: Directory
name: srv-podman-gitlab-data
- hostPath:
path: /srv/podman/gitlab/logs
type: Directory
name: srv-podman-gitlab-logs
- hostPath:
path: /srv/podman/gitlab/conf
type: Directory
name: srv-podman-gitlab-conf
status: {}
systemd:
# podman generate systemd 71fc2b2a5c63
# pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service
# autogenerated by Podman 1.6.4
# Thu Jul 29 15:23:28 EDT 2020
[Unit]
Description=Podman pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service
Documentation=man:podman-generate-systemd(1)
Requires=container-781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3.service container-da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864.service
Before=container-781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3.service container-da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864.service
[Service]
Restart=on-failure
ExecStart=/usr/bin/podman start db40ab8bf84bf35141159c26cb6e256b889c7a98c0418eee3c4aa683c14fccaa
ExecStop=/usr/bin/podman stop -t 10 db40ab8bf84bf35141159c26cb6e256b889c7a98c0418eee3c4aa683c14fccaa
KillMode=none
Type=forking
PIDFile=/var/run/containers/storage/overlay-containers/db40ab8bf84bf35141159c26cb6e256b889c7a98c0418eee3c4aa683c14fccaa/userdata/conmon.pid
[Install]
WantedBy=multi-user.target
# container-da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864.service
# autogenerated by Podman 1.6.4
# Thu Jul 29 15:23:28 EDT 2020
[Unit]
Description=Podman container-da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864.service
Documentation=man:podman-generate-systemd(1)
RefuseManualStart=yes
RefuseManualStop=yes
BindsTo=pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service
After=pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service
[Service]
Restart=on-failure
ExecStart=/usr/bin/podman start da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864
ExecStop=/usr/bin/podman stop -t 10 da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864
KillMode=none
Type=forking
PIDFile=/var/run/containers/storage/overlay-containers/da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864/userdata/conmon.pid
[Install]
WantedBy=multi-user.target
# container-781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3.service
# autogenerated by Podman 1.6.4
# Thu Jul 29 15:23:28 EDT 2020
[Unit]
Description=Podman container-781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3.service
Documentation=man:podman-generate-systemd(1)
RefuseManualStart=yes
RefuseManualStop=yes
BindsTo=pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service
After=pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service
[Service]
Restart=on-failure
ExecStart=/usr/bin/podman start 781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3
ExecStop=/usr/bin/podman stop -t 10 781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3
KillMode=none
Type=forking
PIDFile=/var/run/containers/storage/overlay-containers/781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3/userdata/conmon.pid
[Install]
WantedBy=multi-user.target
рджреБрд░реНрджреИрд╡рд╛рдиреЗ, рдХрдВрдЯреЗрдирд░ рдЪрд╛рд▓рд╡рдгреНрдпрд╛рд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, systemd рд╕рд╛рдареА рд╡реНрдпреБрддреНрдкрдиреНрди рдХреЗрд▓реЗрд▓реЗ рдпреБрдирд┐рдЯ рджреБрд╕рд░реЗ рдХрд╛рд╣реАрд╣реА рдХрд░рдд рдирд╛рд╣реА (рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЕрд╢реА рд╕реЗрд╡рд╛ рд░реАрд╕реНрдЯрд╛рд░реНрдЯ рдЭрд╛рд▓реНрдпрд╛рд╡рд░ рдЬреБрдиреЗ рдХрдВрдЯреЗрдирд░ рд╕рд╛рдл рдХрд░рдгреЗ), рддреНрдпрд╛рдореБрд│реЗ рддреБрдореНрд╣рд╛рд▓рд╛ рдЕрд╢рд╛ рдЧреЛрд╖реНрдЯреА рд╕реНрд╡рдд: рдЬреЛрдбрд▓реНрдпрд╛ рдЬрд╛рддреАрд▓.
рддрддреНрд╡рддрдГ, рдкреЙрдбрдореЕрди рдХрдВрдЯреЗрдирд░ рдХрд╛рдп рдЖрд╣реЗрдд рдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА, рдбреЙрдХрд░-рдХрдВрдкреЛрдЭрд╕рд╛рдареА рдЬреБрдиреА рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рд╣рд╕реНрддрд╛рдВрддрд░рд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдгрд┐ рдирдВрддрд░ рдХреБрдмрд░реНрдиреЗрдЯреНрд╕рдЪреНрдпрд╛ рджрд┐рд╢реЗрдиреЗ, рдХреНрд▓рд╕реНрдЯрд░рд╡рд░ рдЬрд╛рдгреНрдпрд╛рд╕рд╛рдареА рдХрд┐рдВрд╡рд╛ рдбреЙрдХрд░рд╕рд╛рдареА рд╡рд╛рдкрд░рдгреНрдпрд╛рд╕-рд╕реЛрдкрд╛ рдкрд░реНрдпрд╛рдп рдорд┐рд│рд╡рдгреНрдпрд╛рд╕рд╛рдареА рдкреБрд░реЗрд╕реЗ рдЖрд╣реЗ.
рдЖрд░рдХреЗрдЯреА
рдкреНрд░рдХрд▓реНрдк
рдкрд▓рд╢
рдЕрдзрд┐рдХ
рдирд┐рд╖реНрдХрд░реНрд╖
рдХреБрдмрд░реНрдиреЗрдЯреНрд╕рдЪреА рдкрд░рд┐рд╕реНрдерд┐рддреА рдЦреВрдк рдордиреЛрд░рдВрдЬрдХ рдЖрд╣реЗ: рдПрдХреАрдХрдбреЗ, рдбреЙрдХрд░рд╕рд╣, рдЖрдкрдг рдХреНрд▓рд╕реНрдЯрд░ (рд╕реНрд╡рд╛рд░реНрдо рдореЛрдбрдордзреНрдпреЗ) рдПрдХрддреНрд░ рдХрд░реВ рд╢рдХрддрд╛, рдЬреНрдпрд╛рджреНрд╡рд╛рд░реЗ рдЖрдкрдг рдХреНрд▓рд╛рдпрдВрдЯрд╕рд╛рдареА рдЙрддреНрдкрд╛рджрди рд╡рд╛рддрд╛рд╡рд░рдг рджреЗрдЦреАрд▓ рдЪрд╛рд▓рд╡реВ рд╢рдХрддрд╛, рд╣реЗ рд╡рд┐рд╢реЗрд╖рддрдГ рд▓рд╣рд╛рди рд╕рдВрдШрд╛рдВрд╕рд╛рдареА рд╕рддреНрдп рдЖрд╣реЗ (3-5 рд▓реЛрдХ ), рдХрд┐рдВрд╡рд╛ рдПрдХ рд▓рд╣рд╛рди рдПрдХреВрдг рднрд╛рд░ , рдХрд┐рдВрд╡рд╛ рдЙрдЪреНрдЪ рднрд╛рд░рд╛рдВрд╕рд╣ рдХреБрдмрд░реНрдиреЗрдЯреНрд╕ рд╕реЗрдЯ рдХрд░рдгреНрдпрд╛рдЪреНрдпрд╛ рдЧреБрдВрддрд╛рдЧреБрдВрдд рд╕рдордЬреВрди рдШреЗрдгреНрдпрд╛рдЪреА рдЗрдЪреНрдЫрд╛ рдирд╕рдгреЗ.
рдкреЙрдбрдореЕрди рдкреВрд░реНрдг рд╕реБрд╕рдВрдЧрддрддрд╛ рдкреНрд░рджрд╛рди рдХрд░рдд рдирд╛рд╣реА, рдкрд░рдВрддреБ рддреНрдпрд╛рдЪрд╛ рдПрдХ рдорд╣рддреНрддреНрд╡рд╛рдЪрд╛ рдлрд╛рдпрджрд╛ рдЖрд╣реЗ - рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рд╛рдзрдирд╛рдВрд╕рд╣ (рдмрд┐рд▓реНрдбрд╛рд╣ рдЖрдгрд┐ рдЗрддрд░) рдХреБрдмрд░рдиреЗрдЯрд╕рд╣ рд╕реБрд╕рдВрдЧрддрддрд╛. рдореНрд╣рдгреВрди, рдореА рдЦрд╛рд▓реАрд▓рдкреНрд░рдорд╛рдгреЗ рдХрд╛рдорд╛рд╕рд╛рдареА рд╕рд╛рдзрдирд╛рдЪреНрдпрд╛ рдирд┐рд╡рдбреАрдХрдбреЗ рдЬрд╛рдИрди: рд▓рд╣рд╛рди рд╕рдВрдШрд╛рдВрд╕рд╛рдареА рдХрд┐рдВрд╡рд╛ рдорд░реНрдпрд╛рджрд┐рдд рдмрдЬреЗрдЯрд╕рд╣ - рдбреЙрдХрд░ (рд╕рдВрднрд╛рд╡реНрдп рдЭреБрдВрдб рдореЛрдбрд╕рд╣), рд╡реИрдпрдХреНрддрд┐рдХ рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯрд╡рд░ рд╕реНрд╡рддрдГрд╕рд╛рдареА рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА - рдкреЙрдбрдореЕрди рдХреЙрдорд░реЗрдбреНрд╕ рдЖрдгрд┐ рдЗрддрд░ рдкреНрд░рддреНрдпреЗрдХрд╛рд╕рд╛рдареА - рдХреБрдмрд░реНрдиреЗрдЯреНрд╕.
рдорд▓рд╛ рдЦрд╛рддреНрд░реА рдирд╛рд╣реА рдХреА рдбреЙрдХрд░рдЪреА рдкрд░рд┐рд╕реНрдерд┐рддреА рднрд╡рд┐рд╖реНрдпрд╛рдд рдмрджрд▓рдгрд╛рд░ рдирд╛рд╣реА, рд╢реЗрд╡рдЯреА, рддреЗ рдкрд╛рдпрдирд┐рдпрд░ рдЖрд╣реЗрдд рдЖрдгрд┐ рд╣рд│реВрд╣рд│реВ рдорд╛рдирдХреАрдХрд░рдг рджреЗрдЦреАрд▓ рдХрд░рдд рдЖрд╣реЗрдд, рдкрд░рдВрддреБ рдкреЙрдбрдореЕрди, рддреНрдпрд╛рдЪреНрдпрд╛ рд╕рд░реНрд╡ рдХрдорддрд░рддрд╛рдВрд╕рд╣ (рдлрдХреНрдд рд▓рд┐рдирдХреНрд╕рд╡рд░ рдХрд╛рд░реНрдп рдХрд░рддреЗ, рдХреНрд▓рд╕реНрдЯрд░рд┐рдВрдЧ рдирд╛рд╣реА, рдЕрд╕реЗрдВрдмреНрд▓реА рдЖрдгрд┐ рдЗрддрд░ рдХреНрд░рд┐рдпрд╛ рддреГрддреАрдп-рдкрдХреНрд╖рд╛рдЪреЗ рдирд┐рд░реНрдгрдп рдЖрд╣реЗрдд) рднрд╡рд┐рд╖реНрдп рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ рдЖрд╣реЗ, рдореНрд╣рдгреВрди рдореА рдкреНрд░рддреНрдпреЗрдХрд╛рд▓рд╛ рдЯрд┐рдкреНрдкрдгреНрдпрд╛рдВрдордзреНрдпреЗ рдпрд╛ рдирд┐рд╖реНрдХрд░реНрд╖рд╛рдВрд╡рд░ рдЪрд░реНрдЪрд╛ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдордВрддреНрд░рд┐рдд рдХрд░рддреЛ.
PS 3 рдСрдЧрд╕реНрдЯ рд░реЛрдЬреА рдЖрдореНрд╣реА рд▓реЙрдиреНрдЪ рдХрд░рдд рдЖрд╣реЛрдд "
рд░рд┐рд▓реАрдЭ рд╣реЛрдгреНрдпрд╛рдкреВрд░реНрд╡реА рдкреНрд░реА-рдСрд░реНрдбрд░рдЪреА рдХрд┐рдВрдордд: 5000 рд░реВрдмрд▓. рдХрд╛рд░реНрдпрдХреНрд░рдо "рдбреЙрдХрд░ рд╡реНрд╣рд┐рдбрд┐рдУ рдХреЛрд░реНрд╕" рдЖрдврд│реВ рд╢рдХрддреЛ
рд╕реНрддреНрд░реЛрдд: www.habr.com