আমি কীভাবে ব্যর্থ `ডকার বিল্ড` এর ফাইল সিস্টেম পরিদর্শন করতে পারি?


272

আমি cpanmবিভিন্ন প্রকল্পের বেস ইমেজ হিসাবে একগুচ্ছ পার্ল মডিউল ইনস্টল করে আমাদের উন্নয়ন প্রক্রিয়াটির জন্য একটি নতুন ডকার চিত্র তৈরি করার চেষ্টা করছি ।

ডকফাইফিল বিকাশের সময়, cpanmব্যর্থতার কোডটি ফিরে আসে কারণ কিছু মডিউল পরিষ্কারভাবে ইনস্টল করেনি।

আমি আরও নিশ্চিত যে আমার aptআরও কিছু জিনিস ইনস্টল করা দরকার ।

আমার প্রশ্ন হ'ল /.cpanm/workলগগুলি পরিদর্শন করার জন্য আউটপুটে উদ্ধৃত ডিরেক্টরিটি আমি কোথায় খুঁজে পাব? সাধারণ ক্ষেত্রে, আমি কীভাবে একটি ব্যর্থ docker buildকমান্ডের ফাইল সিস্টেম পরিদর্শন করতে পারি ?

সকালের সম্পাদনা বুলেট কামড়ানোর পরে এবং একটি findআবিষ্কার করার পরে আমি আবিষ্কার করি

/var/lib/docker/aufs/diff/3afa404e[...]/.cpanm

এটি কি নির্ভরযোগ্য, বা আমার প্রয়োজনীয় সমস্ত জিনিস না পাওয়া পর্যন্ত আমি কি "বেয়ার" ধারক তৈরি করা এবং ম্যানুয়ালি স্টাফ চালানো ভাল?


/var/lib/docker/aufs/diff/3afa404e[...]/.cpanmসেগুলি সম্পর্কে ডকারের অভ্যন্তরীণ এবং আমি তাদের সাথে
গণ্ডগোল

উত্তর:


355

RUNএভারটাইম ডকার সাফল্যের সাথে একটি ডকফাইফাইল থেকে একটি কমান্ড কার্যকর করে, চিত্র ফাইল সিস্টেমের একটি নতুন স্তর প্রতিশ্রুতিবদ্ধ। সুবিধার্থে আপনি এই স্তরগুলি আইডিকে একটি নতুন ধারক শুরু করতে চিত্র হিসাবে ব্যবহার করতে পারেন।

নিম্নলিখিত ডকফেরাইল নিন:

FROM busybox
RUN echo 'foo' > /tmp/foo.txt
RUN echo 'bar' >> /tmp/foo.txt

এবং এটি নির্মাণ:

$ docker build -t so-2622957 .
Sending build context to Docker daemon 47.62 kB
Step 1/3 : FROM busybox
 ---> 00f017a8c2a6
Step 2/3 : RUN echo 'foo' > /tmp/foo.txt
 ---> Running in 4dbd01ebf27f
 ---> 044e1532c690
Removing intermediate container 4dbd01ebf27f
Step 3/3 : RUN echo 'bar' >> /tmp/foo.txt
 ---> Running in 74d81cb9d2b1
 ---> 5bd8172529c1
Removing intermediate container 74d81cb9d2b1
Successfully built 5bd8172529c1

আপনি এখন থেকে একটি নতুন ধারক শুরু করতে পারেন 00f017a8c2a6, 044e1532c690এবং 5bd8172529c1:

$ docker run --rm 00f017a8c2a6 cat /tmp/foo.txt
cat: /tmp/foo.txt: No such file or directory

$ docker run --rm 044e1532c690 cat /tmp/foo.txt
foo

$ docker run --rm 5bd8172529c1 cat /tmp/foo.txt
foo
bar

অবশ্যই আপনি ফাইল সিস্টেমটি অন্বেষণ করতে এবং কমান্ড ব্যবহার করে দেখতে শেল শুরু করতে চাইতে পারেন:

$ docker run --rm -it 044e1532c690 sh      
/ # ls -l /tmp
total 4
-rw-r--r--    1 root     root             4 Mar  9 19:09 foo.txt
/ # cat /tmp/foo.txt 
foo

যখন কোনও ডকফাইফিল কমান্ড ব্যর্থ হয়, আপনার প্রথমে লেয়ারের আইডিটি সন্ধান করা এবং সেই আইডি থেকে তৈরি একটি পাত্রে একটি শেল চালানো দরকার:

docker run --rm -it <id_last_working_layer> bash -il

একবার পাত্রে:

  • ব্যর্থ কমান্ড চেষ্টা করুন, এবং সমস্যা পুনরুত্পাদন
  • তারপরে কমান্ডটি ঠিক করুন এবং এটি পরীক্ষা করুন
  • অবশেষে স্থির কমান্ড দিয়ে আপনার ডকফেরাইল আপডেট করুন

আপনার যদি সত্যিকারের লেয়ারটি শেষ কার্যকারী স্তরটি থেকে কাজ করার পরিবর্তে ব্যর্থ হয় তবে পরীক্ষা করতে হবে তবে ড্রয়ের উত্তর দেখুন


2
হ্যাঁ এটা করে. আপনি যখন ইচ্ছামত পুনরায় তৈরি করতে পারবেন তখন আপনার ডকফায়িলকে ডিবাগ করার উদ্দেশ্যে এমন কোনও পয়েন্ট রক্ষার পাত্রে নেই।
থমাসলেভিল

1
ঠিক আছে এটি আসলে বেশ কার্যকর হয়েছে তবে আমার কাছে সমস্যা আছে যেখানে কোনও ধারক নির্মাণ ব্যর্থ হলে আমি যে কন্টেইনারটির কাজ করছে এটির হ্যাশ দিয়ে আমি এই কৌশলটি ব্যবহার করতে পারি না R RUN ব্যর্থ হলে কোনও চিত্র তৈরি করা হয় না। আমি কখনও কখনও মধ্যস্থ কন্টেইনারটি সংযুক্ত করতে পারি যা পরিষ্কার হয়নি?
আল্ট্রেয়াস

6
যখন ডকফাইফিল কমান্ডগুলির মধ্যে একটি ব্যর্থ হয়, আপনার যা করতে হবে তা হল পূর্ববর্তী স্তরটির আইডি সন্ধান করা এবং সেই আইডির শেল সহ একটি ধারক চালানো: এবং ধারকটিতে docker run --rm -it <id_last_working_layer> bash -ilএকবার কমান্ডটি চেষ্টা করুন যা সমস্যাটি পুনরুত্পাদন করতে ব্যর্থ হয়েছে, তারপরে কমান্ডটি ঠিক করুন এবং এটি পরীক্ষা করুন, অবশেষে আপনার ডকস্পাইলকে স্থির কমান্ড দিয়ে আপডেট করুন।
থমাসলেভিল

2
এছাড়াও, আপনি docker diff <container>সেই নির্দিষ্ট স্তরটিতে তৈরি ফাইল সিস্টেমের পরিবর্তনের পুরো তালিকা পেতে পারেন (সেই চিত্রের জন্য ফাইলগুলি যুক্ত, মুছে ফেলা বা পুরো ফাইল সিস্টেম জুড়ে পরিবর্তন করা হয়েছে)।
L0j1k

14
আমি ভেবেছিলাম এটি কাজ করছে না কারণ এটি বলেছে Unable to find image 'd5219f1ffda9:latest' locally। তবে আমি একাধিক ধরণের আইডি দ্বারা বিভ্রান্ত হয়ে পড়েছিলাম। দেখা যাচ্ছে যে আপনাকে আইডিগুলি সরাসরি তীরগুলির পরে ব্যবহার করতে হবে, "রানিং ইন ..." বলার মতো নয়।
আরএসপিয়ার

200

শীর্ষস্থানীয় উত্তরটি সেই ক্ষেত্রে কার্যকর হয় যে আপনি ব্যর্থ কমান্ডের আগেই রাষ্ট্রটি পরীক্ষা করতে চান।

যাইহোক, প্রশ্নটি জিজ্ঞাসা করে যে কীভাবে ব্যর্থ কন্টেইনারটির অবস্থাটি পরীক্ষা করতে হবে। আমার পরিস্থিতিতে, ব্যর্থ কমান্ডটি এমন একটি বিল্ড যা বেশ কয়েক ঘন্টা সময় নেয়, সুতরাং ব্যর্থ কমান্ডের পূর্বে রিওয়াইন্ড করা এবং এটি আবার চালানো দীর্ঘ সময় নেয় এবং এটি খুব সহায়ক নয়।

এখানে সমাধানটি হ'ল ব্যর্থ হওয়া ধারকটি সন্ধান করা:

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                          PORTS               NAMES
6934ada98de6        42e0228751b3        "/bin/sh -c './utils/"   24 minutes ago      Exited (1) About a minute ago                       sleepy_bell

এটি একটি চিত্র প্রতিশ্রুতিবদ্ধ:

$ docker commit 6934ada98de6
sha256:7015687976a478e0e94b60fa496d319cdf4ec847bcd612aecf869a72336e6b83

এবং তারপরে চিত্রটি চালান [যদি প্রয়োজন হয় তবে ব্যাশ চালিয়ে যান]:

$ docker run -it 7015687976a4 [bash -il]

এখন আপনি প্রকৃতপক্ষে বিল্ডের অবস্থার দিকে তাকান যে এটি ব্যর্থ হয়েছিল, কমান্ডটি চালানোর আগে ব্যর্থ হওয়ার কারণে এটি ব্যর্থ হয়েছিল।


আগ্রহের বাইরে, আপনি কেন ধারক থেকে একটি নতুন চিত্র তৈরি করার প্রয়োজন হবে? কেন শুধু পাত্রে শুরু হয় না? ব্যর্থ ধারক থেকে তৈরি কোনও চিত্র যদি চালাতে সক্ষম হয়, তবে অবশ্যই বন্ধ / ব্যর্থ পাত্রে চালানোও সক্ষম? নাকি আমি কিছু মিস করছি?
এনএমএইচ

@nmh কারণ এটি আপনাকে আবার ব্যর্থ কমান্ড না চালিয়ে ব্যর্থ অবস্থায় একটি ধারক ক্যাপচার ও পরীক্ষা করতে দেয়। কখনও কখনও ব্যর্থ কমান্ডটি কার্যকর করতে কয়েক মিনিট বা বেশি সময় নেয় তাই এটি ব্যর্থ অবস্থাকে ট্যাগ করার সুবিধাজনক উপায়। উদাহরণস্বরূপ, আমি বর্তমানে একটি ব্যর্থ সি ++ লাইব্রেরি বিল্ডের লগগুলি পরিদর্শন করতে এই পন্থাটি ব্যবহার করছি যা কয়েক মিনিট সময় নেয়। সম্পাদনা করুন - সবেমাত্র লক্ষ্য করেছেন যে ড্রু বলেছিলেন যে [তাঁর] পরিস্থিতিতে ব্যর্থ কমান্ডটি এমন একটি বিল্ড যা বেশ কয়েক ঘন্টা সময় নেয়, সুতরাং ব্যর্থ কমান্ডের পূর্বে পুনর্নির্মাণ করা এবং এটি পুনরায় চালানো দীর্ঘ সময় নেয় এবং এটি খুব সহায়ক নয়।
জাইম সোটো

@ এনএমএইচ আমি মনে করি ব্যর্থ কন্টেইনারটি শুরু করার চেষ্টা করার সাথে সমস্যাটি হ'ল সাধারণত ধারকটির স্টার্ট কমান্ডটি কার্যকর হওয়ার জন্য পরিবর্তন করা দরকার। আপনি যদি ব্যর্থ ধারকটি আবার শুরু করার চেষ্টা করেন তবে এটি কমান্ডটি পুনরায় ব্যর্থ হবে এবং আপনি যেখানে শুরু করেছিলেন সেখানে ফিরে আসবেন। একটি চিত্র তৈরি করে আপনি একটি ভিন্ন স্টার্ট কমান্ড দিয়ে একটি ধারক শুরু করতে পারেন।
সেন্টিমানে

2
আপনি এটি তৈরি DOCKER_BUILDKIT=1করতে ব্যবহার করেন নাDockerfile
ক্লিন্টম

@ এনএমএইচ এর বক্তব্য - আপনি যদি বিল্ড আউটপুটের ঠিক পরে থাকেন তবে আপনাকে চিত্র প্রতিশ্রুতি দেওয়ার দরকার নেই। ব্যর্থ বিল্ড ধারক থেকে ফাইলের ফলাফলগুলি বের করতে আপনি ডকার ধারক সিপি ব্যবহার করতে পারেন ।
হোস্টিমাচাইন

7

ডকার প্রতিটি সফল লাইনের পরে পুরো ফাইল সিস্টেম স্থিতি করেRUN

জানে যে:

  • আপনার ব্যর্থতা আগে সাম্প্রতিক রাষ্ট্র পরীক্ষা করার RUNকমান্ড, এটা Dockerfile (সেইসাথে যেকোন এবং সমস্ত পরবর্তী আউট মন্তব্য RUNকমান্ড), তারপর চালানো docker buildএবং docker runআবার।
  • ব্যর্থ কমান্ডের পরে রাষ্ট্রটি পরীক্ষা করা RUN, || trueএটি সফল করতে বাধ্য করার জন্য কেবল এতে যুক্ত করুন ; তারপরে উপরের মতো এগিয়ে যান (যে কোনও এবং পরবর্তী সমস্ত RUNকমান্ড মন্তব্য করা, চালিয়ে যান docker buildএবং রাখুন docker run)

তদা, ডকার ইন্টারনাল বা লেয়ার আইডিগুলির সাথে ঝামেলা করার দরকার নেই এবং একটি বোনাস হিসাবে ডকার স্বয়ংক্রিয়ভাবে কাজের পরিমাণটিকে পুনরায় কাজ করার পরিমাণ হ্রাস করে।


1
এটি DOCKER_BUILDKIT ব্যবহার করার সময় একটি বিশেষ সহায়ক, কারণ বিল্ডকিট উপরের তালিকাভুক্তদের মতো একই সমাধান সমর্থন করে না বলে মনে হয়।
এম। অ্যান্টনি

3

বিল্ড স্টেপ ব্যর্থতা ডিবাগ করা সত্যিই খুব বিরক্তিকর।

আমি যে সর্বোত্তম সমাধানটি পেয়েছি তা হ'ল আসল কাজ করে এমন প্রতিটি পদক্ষেপ সফল হয় তা নিশ্চিত করা এবং ব্যর্থ হয়ে যাওয়ার পরে একটি চেক যুক্ত করা। এইভাবে আপনি একটি প্রতিশ্রুতিবদ্ধ স্তর পাবেন যাতে আপনি পরিদর্শন করতে পারেন এমন ব্যর্থ পদক্ষেপের ফলাফলগুলি রয়েছে।

একটি ডকফেরাইল, # Run DB2 silent installerলাইনের পরে উদাহরণ সহ :

#
# DB2 10.5 Client Dockerfile (Part 1)
#
# Requires
#   - DB2 10.5 Client for 64bit Linux ibm_data_server_runtime_client_linuxx64_v10.5.tar.gz
#   - Response file for DB2 10.5 Client for 64bit Linux db2rtcl_nr.rsp 
#
#
# Using Ubuntu 14.04 base image as the starting point.
FROM ubuntu:14.04

MAINTAINER David Carew <carew@us.ibm.com>

# DB2 prereqs (also installing sharutils package as we use the utility uuencode to generate password - all others are required for the DB2 Client) 
RUN dpkg --add-architecture i386 && apt-get update && apt-get install -y sharutils binutils libstdc++6:i386 libpam0g:i386 && ln -s /lib/i386-linux-gnu/libpam.so.0 /lib/libpam.so.0
RUN apt-get install -y libxml2


# Create user db2clnt
# Generate strong random password and allow sudo to root w/o password
#
RUN  \
   adduser --quiet --disabled-password -shell /bin/bash -home /home/db2clnt --gecos "DB2 Client" db2clnt && \
   echo db2clnt:`dd if=/dev/urandom bs=16 count=1 2>/dev/null | uuencode -| head -n 2 | grep -v begin | cut -b 2-10` | chgpasswd && \
   adduser db2clnt sudo && \
   echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

# Install DB2
RUN mkdir /install
# Copy DB2 tarball - ADD command will expand it automatically
ADD v10.5fp9_linuxx64_rtcl.tar.gz /install/
# Copy response file
COPY  db2rtcl_nr.rsp /install/
# Run  DB2 silent installer
RUN mkdir /logs
RUN (/install/rtcl/db2setup -t /logs/trace -l /logs/log -u /install/db2rtcl_nr.rsp && touch /install/done) || /bin/true
RUN test -f /install/done || (echo ERROR-------; echo install failed, see files in container /logs directory of the last container layer; echo run docker run '<last image id>' /bin/cat /logs/trace; echo ----------)
RUN test -f /install/done

# Clean up unwanted files
RUN rm -fr /install/rtcl

# Login as db2clnt user
CMD su - db2clnt

0

আমি যা করব তা হ'ল নীচে ডকফর্মিল মন্তব্য করা এবং আপত্তিজনক লাইনটি অন্তর্ভুক্ত করা উচিত। তারপরে আপনি ধারকটি চালাতে এবং ডকার কমান্ডগুলি হাতে চালনা করতে পারেন এবং লগগুলিকে স্বাভাবিক উপায়ে দেখতে পারেন। যেমন ডকফেরফিল হলে

RUN foo
RUN bar
RUN baz

এবং এটা আমি করতাম বারে মারা যাচ্ছে

RUN foo
# RUN bar
# RUN baz

তারপর

$ docker build -t foo .
$ docker run -it foo bash
container# bar
...grep logs...

এই থ্রেডটি সন্ধান করার আগে আমি এটিও করতাম। আরও ভাল উপায় আছে যদিও এর জন্য বিল্ডটি পুনরায় চালানোর দরকার নেই।
অ্যারন ম্যাকমিলিন

@Aaron। এই উত্তরটি মনে করিয়ে দেওয়ার জন্য ধন্যবাদ। আমি দীর্ঘক্ষণ এটির দিকে নজর দিইনি। আপনি দয়া করে ব্যাখ্যা করতে পারেন কেন গ্রহণযোগ্য উত্তরটি ব্যবহারিক দৃষ্টিকোণ থেকে এই উত্তরটির চেয়ে ভাল। আমি স্পষ্টভাবে পেয়েছি কেন ড্র এর উত্তর আরও ভাল। মনে হচ্ছে গ্রহণযোগ্য উত্তরের জন্য এখনও পুনরায় চলমান দরকার।
seanmcl

আমি আসলে ড্রইউর উত্তরের পক্ষে ভোট দিয়েছি এবং স্বীকৃত নয়। তারা দুজনেই বিল্ডটি আবার চালনা না করেই কাজ করে। গৃহীত উত্তরে আপনি ব্যর্থ কমান্ডের ঠিক আগে শেলটিতে ঝাঁপিয়ে পড়তে পারেন (ত্রুটিটি দ্রুত হলে এটি দেখতে আপনি এটি আবার চালাতে পারেন)। অথবা ড্রয়ের জবাব দিয়ে আপনি ব্যর্থ কমান্ডটি চালুর পরে শেল পেতে পারেন (তার ক্ষেত্রে ব্যর্থ কমান্ডটি দীর্ঘকাল চলছিল এবং এর পিছনে বাম অবস্থা পরিদর্শন করা যেতে পারে)।
অ্যারন ম্যাকমিলিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.