Ако харесвате китове или просто се интересувате от бърза и безболезнена непрекъсната доставка на вашия софтуер до производството, тогава ви каня да прочетете този уводен урок за Docker. Всичко изглежда показва, че софтуерните контейнери са бъдещето на ИТ, така че нека да се потопим бързо с китовете на контейнерите Моби Док и Моли .
Docker, представен от лого с приятелски изглеждащ кит, е проект с отворен код, който улеснява разполагането на приложения вътре в софтуерни контейнери. Основната му функционалност е активирана от функциите за изолиране на ресурси на ядрото на Linux, но освен това предоставя удобен за потребителя API. Първата версия беше пусната през 2013 г. и оттогава стана изключително популярна и се използва широко от много големи играчи като eBay, Spotify, Baidu и др . В последния кръг на финансиране, Docker е получил огромни 95 милиона долара и е на път да се превърне в основен елемент Услуги на DevOps .
Философията зад Docker може да бъде илюстрирана със следната проста аналогия. В международната транспортна индустрия стоките трябва да се транспортират по различни начини като мотокари, камиони, влакове, кранове и кораби. Тези стоки се предлагат в различни форми и размери и имат различни изисквания за съхранение: чували със захар, консерви за мляко, растения и т.н. Исторически това беше болезнен процес в зависимост от ръчната намеса във всеки транзитен пункт за товарене и разтоварване.
този тип баланс включва елементи, които идват от централна точка или създават централен фокус.
Всичко се промени с приемането на интермодални контейнери. Тъй като те се предлагат в стандартни размери и се произвеждат с оглед на транспорта, всички съответни машини могат да бъдат проектирани да се справят с тях с минимална човешка намеса. Допълнителната полза от запечатаните контейнери е, че те могат да запазят вътрешната среда като температура и влажност за чувствителни стоки. В резултат на това транспортната индустрия може да спре да се тревожи за самите стоки и да се съсредоточи върху получаването им от А до Б.
И ето къде Docker влиза и носи подобни ползи за софтуер промишленост.
На един бърз поглед виртуалните машини и контейнерите на Docker могат да изглеждат еднакви. Основните им разлики обаче ще станат очевидни, когато погледнете следната диаграма:
Приложенията, работещи във виртуални машини, освен хипервизора, изискват пълен екземпляр на операционната система и всички поддържащи библиотеки. Контейнерите, от друга страна, споделят операционната система с хоста. Hypervisor е сравним с механизма за контейнери (представен като Docker на изображението) в смисъл, че управлява жизнения цикъл на контейнерите. Важната разлика е, че процесите, изпълнявани вътре в контейнерите, са точно като родните процеси на хоста и не въвеждат никакви режийни разходи, свързани с изпълнението на хипервизора. Освен това приложенията могат да използват повторно библиотеките и да споделят данните между контейнери.
Тъй като и двете технологии имат различни силни страни, често се срещат системи, съчетаващи виртуални машини и контейнери. Перфектен пример е инструмент на име Boot2Docker, описан в раздела за инсталиране на Docker.
В горната част на диаграмата на архитектурата има регистри. По подразбиране основният регистър е Docker Hub, който хоства публични и официални изображения. Организациите могат също така да хостват своите частни регистри, ако желаят.
От дясната страна имаме изображения и контейнери. Изображенията могат да бъдат изтеглени от регистрите изрично (docker pull imageName
) или неявно при стартиране на контейнер. След като изображението се изтегли, то се кешира локално.
Контейнерите са копия на изображения - те са живото същество. Може да има множество контейнери, работещи въз основа на едно и също изображение.
В центъра е демонът на Docker, отговорен за създаването, изпълнението и наблюдението на контейнери. Освен това се грижи за изграждане и съхраняване на изображения. И накрая, отляво има клиент на Docker. Той разговаря с демона чрез HTTP. Unix сокетите се използват, когато са на една и съща машина, но дистанционното управление е възможно чрез HTTP базиран API.
За най-новите инструкции винаги трябва да се обърнете към официална документация .
Docker работи изцяло на Linux, така че в зависимост от целевата дистрибуция може да бъде толкова лесно, колкото sudo apt-get install docker.io
За подробности вижте документацията. Обикновено в Linux добавяте командите на Docker с sudo
, но ние ще го пропуснем в тази статия за по-голяма яснота.
Тъй като демонът на Docker използва специфични за Linux функции на ядрото, не е възможно да стартирате Docker първоначално в Mac OS или Windows. Вместо това трябва да инсталирате приложение, наречено Boot2Docker. Приложението се състои от VirtualBox Virtual Machine, самия Docker и помощните програми за управление Boot2Docker. Можете да следвате официалните инструкции за инсталиране на MacOS и Windows за да инсталирате Docker на тези платформи.
Нека започнем този раздел с бърз пример:
php конвертирате unicode в ascii
docker run phusion/baseimage echo 'Hello Moby Dock. Hello Molly.'
Трябва да видим този изход:
Hello Moby Dock. Hello Molly.
Зад кулисите обаче се случи много повече, отколкото си мислите:
При първото изпълнение може да забележите забавяне, преди текстът да бъде отпечатан на екрана. Ако изображението беше кеширано локално, всичко щеше да отнеме частица от секундата. Подробности за последния контейнер могат да бъдат извлечени чрез стартиране docker ps -l
:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES af14bec37930 phusion/baseimage:latest 'echo 'Hello Moby Do 2 minutes ago Exited (0) 3 seconds ago stoic_bardeen
Както можете да кажете, изпълняването на проста команда в Docker е толкова лесно, колкото и директно изпълнение на стандартен терминал. За да илюстрираме по-практичен случай на употреба, в останалата част на тази статия ще видим как можем да използваме Docker за разполагане на просто приложение за уеб сървър. За да улесним нещата, ще напишем програма на Java, която обработва HTTP GET заявки за ‘/ ping’ и отговаря със низа ‘pong n’.
import java.io.IOException; import java.io.OutputStream; import java.net.InetSocketAddress; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; public class PingPong { public static void main(String[] args) throws Exception { HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0); server.createContext('/ping', new MyHandler()); server.setExecutor(null); server.start(); } static class MyHandler implements HttpHandler { @Override public void handle(HttpExchange t) throws IOException { String response = 'pong
'; t.sendResponseHeaders(200, response.length()); OutputStream os = t.getResponseBody(); os.write(response.getBytes()); os.close(); } } }
Преди да влезете и да създадете свой собствен образ на Docker, е добра практика първо да проверите дали съществува такъв в Docker Hub или частни регистри, до които имате достъп. Например, вместо сами да инсталираме Java, ще използваме официално изображение: java:8
.
За да изградим изображение, първо трябва да вземем решение за основно изображение, което ще използваме. Обозначава се с ОТ инструкция. Тук това е официално изображение за Java 8 от Docker Hub. Ще го копираме в нашия Java файл чрез издаване на КОПИЕ инструкция. След това ще го компилираме с РАБОТА . ЕКСПОЗИЦИЯ инструкция означава, че изображението ще предоставя услуга на определен порт. ВХОДНА ТОЧКА е инструкция, която искаме да изпълним при стартиране на контейнер въз основа на това изображение и CMD показва параметрите по подразбиране, които ще му предадем.
FROM java:8 COPY PingPong.java / RUN javac PingPong.java EXPOSE 8080 ENTRYPOINT ['java'] CMD ['PingPong']
След като запазим тези инструкции във файл, наречен „Dockerfile“, можем да изградим съответното изображение на Docker, като изпълним:
кое от тях не е причина, поради която осигуряването на уеб приложения от страна на сървъра е трудно?
docker build -t toptal/pingpong .
Официалната документация за Docker има раздел, посветен на най-добрите практики относно писането на Dockerfile.
Когато изображението е изградено, можем да го оживим като контейнер. Има няколко начина, по които можем да стартираме контейнери, но нека започнем с един прост:
docker run -d -p 8080:8080 toptal/pingpong
където -p [порт на хоста]: [порт в контейнера] обозначава картографирането на портовете съответно на хоста и контейнера. Освен това казваме на Docker да стартира контейнера като демон процес във фонов режим, като посочи -д . Можете да тествате дали приложението на уеб сървъра се изпълнява, като се опитате да получите достъп до „http: // localhost: 8080 / ping“. Обърнете внимание, че на платформи, където се използва Boot2docker, ще трябва да замените ‘localhost’ с IP адреса на виртуалната машина, където Docker работи.
На Linux:
curl http://localhost:8080/ping
На платформи, изискващи Boot2Docker:
curl $(boot2docker ip):8080/ping
Ако всичко върви добре, трябва да видите отговора:
pong
Ура, първият ни потребителски контейнер Docker е жив и плува! Можем също да стартираме контейнера в интерактивен режим -то . В нашия случай ще заменим входна точка команда, така че ни се представя терминал bash. Сега можем да изпълняваме каквито команди искаме, но излизането от контейнера ще го спре:
docker run -i -t --entrypoint='bash' toptal/pingpong
Има много повече опции, които можете да използвате за стартиране на контейнерите. Нека разгледаме още няколко. Например, ако искаме да запазим данни извън контейнера, бихме могли да споделим хост файловата система с контейнера, като използваме -v . По подразбиране режимът на достъп е четене-запис, но може да се промени на режим само за четене, като се добави :ro
към пътя на обема вътре в контейнера. Обемите са особено важни, когато трябва да използваме каквато и да е информация за защита, като идентификационни данни и частни ключове вътре в контейнерите, които не трябва да се съхраняват в изображението. Освен това може да предотврати дублирането на данни, например чрез картографиране на локалното хранилище на Maven в контейнера, за да ви спести от изтеглянето на интернет два пъти.
Docker също има способността да свързва контейнери заедно. Свързаните контейнери могат да говорят помежду си, дори ако никой от портовете не е изложен. Може да се постигне с –Връзка друго-име-контейнер . По-долу е даден пример, съчетаващ споменатите по-горе параметри:
docker run -p 9999:8080 --link otherContainerA --link otherContainerB -v /Users/$USER/.m2/repository:/home/user/.m2/repository toptal/pingpong
Не е изненадващо, че списъкът с операции, които човек може да приложи към контейнерите и изображенията, е доста дълъг. За краткост, нека разгледаме само няколко от тях:
Последната команда може да бъде особено полезна за отстраняване на грешки, тъй като ви позволява да се свържете с терминал на работещ контейнер:
docker exec -i -t bash
Ако имате повече от няколко взаимосвързани контейнера, има смисъл да използвате инструмент като docker-compose . В конфигурационен файл описвате как да стартирате контейнерите и как те трябва да бъдат свързани помежду си. Независимо от количеството на включените контейнери и техните зависимости, можете да ги стартирате и да стартирате с една команда: docker-compose up
.
Нека да разгледаме три етапа от жизнения цикъл на проекта и да видим как нашият приятелски кит може да бъде от помощ.
Docker ви помага да поддържате местната среда за развитие чиста. Вместо да имате инсталирани множество версии на различни услуги като Java, Kafka, Spark, Cassandra и др., Можете просто да стартирате и спрете необходимия контейнер, когато е необходимо. Можете да направите нещата още една стъпка напред и да стартирате множество софтуерни стекове един до друг, като избягвате смесването на версиите на зависимостите.
С Docker можете да спестите време, усилия и пари. Ако вашият проект е много сложен за настройка, „докеризирайте“ го. Преминете веднъж през болката от създаването на изображение на Docker и от този момент всеки може просто да стартира контейнер на мига.
Можете също така да имате „интеграционна среда“, която се изпълнява локално (или на CI) и да замените заглушките с реални услуги, работещи в контейнери на Docker.
С Dockerfile е лесно да се постигнат възпроизводими компилации. Jenkins или други CI решения могат да бъдат конфигурирани да създават образ на Docker за всяка компилация. Можете да съхранявате някои или всички изображения в частен регистър на Docker за бъдещи справки.
С Docker вие тествате само това, което трябва да бъде тествано, и изваждате околната среда от уравнението. Извършването на тестове върху работещ контейнер може да помогне да се запазят нещата много по-предсказуеми.
Друга интересна особеност на наличието на софтуерни контейнери е, че е лесно да се въртят подчинените машини с еднаква настройка за разработка. Тя може да бъде особено полезна за тестване на натоварване на клъстерни разполагания.
Docker може да бъде общ интерфейс между разработчиците и експлоатационния персонал, премахвайки източника на триене. Той също така насърчава едни и същи изображения / двоични файлове да се използват на всяка стъпка от тръбопровода. Нещо повече, възможността за разполагане на напълно тестван контейнер без разлики в околната среда помага да се гарантира, че в процеса на компилиране няма да се появят грешки.
какво е s corporation vs c corporation
Можете безпроблемно да мигрирате приложения в производствена. Нещо, което някога е било досаден и нестабилен процес, сега може да бъде толкова просто, колкото:
docker stop container-id; docker run new-image
И ако нещо се обърка при внедряването на нова версия, винаги можете бързо да се върнете или да преминете към друг контейнер:
docker stop container-id; docker start other-container-id
... гарантирано няма да остави никаква бъркотия зад себе си или да остави нещата в непоследователно състояние.
Добро обобщение на това, което Docker прави, е включено в неговия собствен девиз: Изграждане, изпращане, бягане .
Забавлявайте се да плувате с китовете!
Част от тази работа е вдъхновена от отлична книга Използване на Docker от Адриан Муат.