چگونه داکر را داخل داکر اجرا کردم و چه چیزی از آن بیرون آمد

سلام به همه! در او مقاله قبلی، قول دادم در مورد اجرای داکر در داکر و جنبه های کاربردی استفاده از این درس صحبت کنم. وقت آن است که به قول خود عمل کنید. یک توسعه دهنده باتجربه احتمالا اعتراض خواهد کرد که کسانی که به داکر در داخل داکر نیاز دارند، به سادگی سوکت داکر را از میزبان به داخل کانتینر ارسال می کنند و این در 99٪ موارد کافی خواهد بود. اما برای پرتاب کوکی ها به سمت من عجله نکنید، زیرا ما در مورد اجرای Docker در داخل Docker صحبت خواهیم کرد. این راه حل کاربردهای زیادی دارد و این مقاله در مورد یکی از آنهاست، پس بنشینید و بازوهای خود را در مقابل خود صاف کنید.

چگونه داکر را داخل داکر اجرا کردم و چه چیزی از آن بیرون آمد

شروع

همه چیز در یک غروب بارانی سپتامبر شروع شد، زمانی که من مشغول تمیز کردن دستگاهی بودم که به قیمت 5 دلار در Digital Ocean اجاره کرده بودم، که به دلیل این واقعیت که داکر تمام 24 گیگابایت فضای دیسک موجود را با تصاویر و ظروف خود پر کرده بود، یخ زده بود. طنز این بود که همه این تصاویر و کانتینرها گذرا بودند و فقط برای آزمایش عملکرد برنامه من هر بار که نسخه جدیدی از یک کتابخانه یا فریم ورک منتشر می شد مورد نیاز بودند. من سعی کردم اسکریپت های پوسته بنویسم و ​​یک برنامه زمانبندی برای تمیز کردن زباله ها تنظیم کنم، اما فایده ای نداشت: هر بار که ناگزیر با خالی شدن فضای دیسک سرور من و قطع شدن سرور (در بهترین حالت) به پایان می رسید. در نقطه‌ای با مقاله‌ای در مورد نحوه اجرای Jenkins در یک کانتینر و نحوه ایجاد و حذف خطوط لوله ساخت از طریق یک سوکت داکر دایمون که به داخل آن ارسال می‌شود، برخوردم. من این ایده را دوست داشتم، اما تصمیم گرفتم جلوتر رفته و سعی کنم مستقیماً داکر را در داخل داکر اجرا کنم. در آن زمان، به نظر من یک راه حل کاملا منطقی به نظر می رسید که تصاویر Docker را دانلود کنم و برای تمام برنامه هایی که برای آزمایش در یک کانتینر دیگر نیاز داشتم، کانتینرهایی ایجاد کنم (بیایید آن را یک کانتینر مرحله بندی بنامیم). ایده این بود که یک کانتینر مرحله‌بندی با پرچم -rm شروع شود، که به طور خودکار کل ظرف و تمام محتویات آن را در صورت توقف حذف می‌کند. من تصویر داکر را از خود داکر سرهم کردم (https://hub.docker.com/_/docker)، اما معلوم شد که خیلی دست و پا گیر است و من هرگز نتوانستم آن را به شکلی که نیاز داشتم به کار بیاورم و خودم می خواستم تمام راه را بروم.

تمرین. مخروط ها

من تصمیم گرفتم تا ظرف را همانطور که نیاز داشتم کار کنم و آزمایشاتم را ادامه دادم که نتیجه آن جوانه های بیشماری بود. نتیجه شکنجه خودم الگوریتم زیر بود:

  1. ظرف Docker را در حالت تعاملی راه اندازی می کنیم.

    docker run --privileged -it docker:18.09.6

    به نسخه ظرف دقت کنید، به راست یا چپ بروید و DinD شما به کدو تنبل تبدیل می شود. در واقع، وقتی یک نسخه جدید منتشر می شود، همه چیز اغلب خراب می شود.
    ما باید فورا وارد پوسته شویم.

  2. ما در تلاشیم تا بفهمیم کدام کانتینرها در حال اجرا هستند (پاسخ: هیچکدام)، اما به هر حال بیایید دستور را اجرا کنیم:

    docker ps

    کمی متعجب خواهید شد، اما معلوم شد که داکر داکر حتی در حال اجرا نیست:

    error during connect: Get http://docker:2375/v1.40/containers/json: dial tcp: lookup docker on 
    192.168.65.1:53: no such host

  3. بیایید خودمان اجرا کنیم:

    dockerd &

    سورپرایز ناخوشایند دیگر:

    failed to start daemon: Error initializing network controller: error obtaining controller instance: failed 
    to create NAT chain DOCKER: Iptables not found

  4. بسته‌های iptable و bash را نصب کنید (کار کردن در bash راحت‌تر از sh است):

    apk add --no-cache iptables bash

  5. بیایید bash را راه اندازی کنیم. بالاخره به پوسته معمولی برگشتیم

  6. بیایید سعی کنیم Docker را دوباره راه اندازی کنیم:

    dockerd &

    ما باید یک صفحه طولانی از سیاهههای مربوط را ببینیم که به این موارد ختم می شود:

    INFO[2019-11-25T19:51:19.448080400Z] Daemon has completed initialization          
    INFO[2019-11-25T19:51:19.474439300Z] API listen on /var/run/docker.sock

  7. Enter را فشار دهید. ما برگشتیم به آشغال

از این به بعد، می‌توانیم کانتینرهای دیگری را در داخل کانتینر داکر خود راه اندازی کنیم، اما اگر بخواهیم کانتینر دیگری را در داخل کانتینر داکر خود راه اندازی کنیم یا مشکلی پیش بیاید و کانتینر از کار بیفتد، چه؟ همه چیز را از نو شروع کنید.

ظرف DinD و آزمایش های جدید را داشته باشید

چگونه داکر را داخل داکر اجرا کردم و چه چیزی از آن بیرون آمد
برای جلوگیری از تکرار مکرر مراحل بالا، ظرف DinD خود را ایجاد کردم:

https://github.com/alekslitvinenk/dind

راه‌حل کار DinD به من این توانایی را داد که Docker را درون داکر به صورت بازگشتی اجرا کنم و آزمایش‌های ماجراجویانه‌تری را انجام دهم.
اکنون قصد دارم یکی از این آزمایشات (موفق) را با اجرای MySQL و Nodejs شرح دهم.
بی حوصله ترین ها می توانند ببینند اینجا چطور بود

بنابراین شروع کنید:

  1. ما DinD را در حالت تعاملی راه اندازی می کنیم. در این نسخه از DinD، ما باید به صورت دستی تمام پورت هایی را که کانتینرهای فرزندمان می توانند استفاده کنند، نقشه برداری کنیم (من در حال حاضر روی این کار کار می کنم)

    docker run --privileged -it 
    -p 80:8080 
    -p 3306:3306 
    alekslitvinenk/dind

    ما وارد بشکه می‌شویم، از آنجا می‌توانیم فوراً شروع به پرتاب کانتینرهای کودک کنیم.

  2. MySQL را راه اندازی کنید:

    docker run --name mysql -e MYSQL_ROOT_PASSWORD=strongpassword -d -p 3306:3306 mysql

  3. همانطور که به صورت محلی به پایگاه داده متصل می شویم، به پایگاه داده متصل می شویم. بیایید مطمئن شویم همه چیز کار می کند.

  4. کانتینر دوم را راه اندازی کنید:

    docker run -d --rm -p 8080:8080 alekslitvinenk/hello-world-nodejs-server

    لطفا توجه داشته باشید که نقشه پورت دقیقا خواهد بود 8080:8080، از آنجایی که قبلاً پورت 80 را از میزبان به کانتینر والد به پورت 8080 نگاشت کرده ایم.

  5. ما در مرورگر به لوکال هاست می رویم، مطمئن شوید که سرور به "Hello World!" پاسخ می دهد.

در مورد من، آزمایش با ظروف Docker تو در تو کاملاً مثبت بود و من به توسعه پروژه و استفاده از آن برای مرحله‌بندی ادامه خواهم داد. به نظر من این راه حل بسیار سبک تر از Kubernetes و Jenkins X است. اما این نظر ذهنی من است.

من فکر می کنم این همه برای مقاله امروز است. در مقاله بعدی، آزمایش‌های با جزئیات بیشتری را با اجرای Docker به صورت بازگشتی در Docker و نصب دایرکتوری‌ها در کانتینرهای تودرتو شرح خواهم داد.

PS اگر این پروژه را مفید می‌دانید، لطفاً در GitHub به آن ستاره بدهید، آن را فورک کنید و به دوستان خود بگویید.

ویرایش 1 خطاهای تصحیح شده، متمرکز بر 2 ویدیو

منبع: www.habr.com

اضافه کردن نظر