Безопасная работа с секретами при сборке docker-образов

Thank you for reading this post, don't forget to subscribe!

При сбор­ке Docker-обра­зов ино­гда необ­хо­ди­мо исполь­зо­вать сек­ре­ты (напри­мер, пароль к при­ват­но­му репо­зи­то­рию паке­тов), кото­рые не долж­ны в конеч­ном ито­ге оста­вать­ся в обра­зе. В послед­них вер­си­ях Docker это­го мож­но добить­ся бла­го­да­ря BuildKit

Самые оче­вид­ные вари­ан­ты рабо­ты с сек­ре­та­ми при сбор­ке Docker-обра­за - копи­ро­ва­ние с после­ду­ю­щим уда­ле­ни­ем, напри­мер, для Dockerfile:

 

При выпол­не­нии команды

docker build -t ealebed/demo:dev .

мож­но уви­деть слой обра­за до уда­ле­ния фай­ла с сек­ре­том в логе сбор­ки, кото­рый будет выгля­деть при­мер­но так (вывод силь­но сокращен):

или же мож­но вос­поль­зо­вать­ся коман­дой docker history что­бы уви­деть спи­сок сло­ев образа:

 

Слой 77f58d40c15c явля­ет­ся пол­но­цен­ным docker-обра­зом и может быть запу­щен в каче­стве кон­тей­не­ра, в кото­ром будет нахо­дить­ся “уда­лен­ный” сек­рет (.npmrc):

Вто­рой оче­вид­ный и так­же небез­опас­ный вари­ант - пере­да­вать сек­ре­ты при сбор­ке обра­за с помо­щью аргу­мен­тов. Для демон­стра­ции изме­ня­ем наш Dockerfile:

Ста­но­вит­ся понят­но, что исполь­зо­вать оба выше­при­ве­ден­ных вари­ан­та небез­опас­но. Как быть?

Начи­ная с вер­сии 18.09, в Docker есть под­держ­ка фла­га --secret для коман­ды docker build, кото­рая поз­во­ля­ет пере­да­вать фай­лы с сек­ре­та­ми в момент сбор­ки обра­за и не остав­лять их с каких-либо про­ме­жу­точ­ных сло­ях обра­за, а с вер­сии 20.10 появи­лась допол­ни­тель­ная воз­мож­ность под­гру­жать сек­ре­ты из пере­мен­ных окру­же­ния, а не толь­ко из файлов.

Рас­смот­рим при­мер (спе­ци­аль­но выво­дим содер­жи­мое сек­ре­та с помо­щью коман­ды cat):

В исто­рии наше­го сек­ре­та не видно:

Ана­ло­гич­ную ситу­а­цию наблю­да­ем при исполь­зо­ва­нии сек­ре­тов из пере­мен­ных окру­же­ния (Dockerfile остав­ля­ем неизменным):

А еще, без­услов­но, для сокры­тия сек­ре­тов мож­но исполь­зо­вать multi-stage build, когда на пер­вом эта­пе дела­ет­ся сбор­ка с исполь­зо­ва­ни­ем сек­ре­тов пере­дан­ных любым спо­со­бом - через аргу­мен­ты сбор­ки или копи­ро­ва­ние фай­ла, но в финаль­ный образ попа­да­ют толь­ко резуль­та­ты сбор­ки (напри­мер, бинар­ный файл) без сек­ре­тов в слоях.