Lxc / ডকারের ভিতরে কোনও প্রক্রিয়া চলে কিনা তা কীভাবে নির্ধারণ করবেন?


172

কোনও প্রসেস (স্ক্রিপ্ট) কোনও এলএক্সসি পাত্রে (ock ডকার রানটাইম) এর ভিতরে চলে কিনা তা নির্ধারণ করার কোনও উপায় আছে কি? আমি জানি যে কিছু প্রোগ্রামগুলি ভার্চুয়াল মেশিনের অভ্যন্তরে চলে কিনা তা সনাক্ত করতে সক্ষম, lxc / ডকারের জন্য কি অনুরূপ কিছু উপলব্ধ?


এটি পেডেন্টিক বলে মনে হতে পারে তবে আপনার যে সমস্যার মুখোমুখি হচ্ছে তার বর্ণনা দিতে এবং এটি কীভাবে সমাধান করবেন তা জিজ্ঞাসা করার জন্য আপনার প্রশ্নটির পুনঃব্যবহার করা ভাল - এটি ছাড়া প্রশ্নটি বন্ধ হওয়ার আরও বেশি সম্ভাবনা। বেশিরভাগ ক্ষেত্রেই এই পরিবর্তনটি করা কঠিন তবে আপনার ইচ্ছা থাকলে কেবল পুনরায় বিবরণ করা আপনার পক্ষে কঠিন হবে না।
mah

উত্তর:


169

সবচেয়ে নির্ভরযোগ্য উপায় চেক করা হয় /proc/1/cgroup। এটি আপনাকে init প্রক্রিয়াটির নিয়ন্ত্রণ গোষ্ঠীগুলি বলবে এবং আপনি যখন কোনও ধারক নন , তখন এটি /সমস্ত শ্রেণিবিন্যাসের জন্য হবে। আপনি যখন কোনও ধারকের ভিতরে থাকবেন, আপনি অ্যাঙ্কর পয়েন্টের নামটি দেখতে পাবেন। এলএক্সসি / ডকার পাত্র সহ এটি যথাক্রমে /lxc/<containerid>বা /docker/<containerid>যথাক্রমে কিছু হবে ।


13
ডকার এখন সেই পাথগুলির dockerপরিবর্তে ব্যবহার lxcকরে
অ্যান্ডি

4
Lxd / lxc পাত্রে জন্য নয় কাজ করে, কিন্তু stackoverflow.com/a/20010626/170230 আছে।
ড্রাকো আটার

সিস্টেমডের পরবর্তী সংস্করণগুলির সাথে দেখে মনে হচ্ছে আপনি /সমস্ত সিগ্রুপের জন্য 1 প্রক্রিয়াটিতে নির্ভর করতে পারবেন না ; আমার ডেবিয়ান 9 সিস্টেমে (232 systemd) শুধুমাত্র দশ Cgroups তিন ( 3:cpuset, 4:perf_eventএবং 7:freezer) মূলে আছে; বাকি অধীনে আছে /init.scope। এটি বলেছিল, আমি মনে করি যে সেই ফাইলটির জন্য অনুসন্ধান :/docker/করা সম্ভবত এই মুহুর্তে সবচেয়ে নির্ভরযোগ্য হিউরিস্টিক।
সিজেএস

2
grep 'docker\|lxc' /proc/1/cgroupআমার জন্য ডকার 18.09 এ কাজ করে।
রাইপেল

1
আমার জন্য কাজ করছে না। হোস্ট উবুন্টু 19.04, অতিথি উবুন্টু 18.04 এলএক্সসি সুবিধাযুক্ত ধারক ব্যবহার করে। / proc / 1 / cgroup এ lxc স্ট্রিং থাকে না।
গ্যাব

157

ডকার .dockerenvকনটেইনারটির ভিতরে ডিরেক্টরি গাছের গোড়ায় একটি ফাইল তৈরি করে । আপনি যাচাই করতে এই স্ক্রিপ্টটি চালাতে পারেন

#!/bin/bash
if [ -f /.dockerenv ]; then
    echo "I'm inside matrix ;(";
else
    echo "I'm living in real world!";
fi


আরও: উবুন্টুতে আসলে একটি বাশ স্ক্রিপ্ট রয়েছে: /bin/running-in-containerএবং এটি আসলে যে ধরণের কন্টেইনারটি চালানো হয়েছিল তা এটি ফিরিয়ে দিতে পারে M সহায়ক হতে পারে। যদিও অন্য বড় ডিস্ট্রোস সম্পর্কে জানেন না।


13
গুরুত্বপূর্ণ দ্রষ্টব্য: ডকারের সাম্প্রতিক সংস্করণগুলিতে.dockerinit ফাইলটি সরানো হয়েছে , সুতরাং এই পদ্ধতিটি আর কাজ করবে না। এই লেখার হিসাবে, .dockerenvফাইলটি এখনও চারপাশে রাখা হয়েছে, যাতে সম্ভবত এটি পরিবর্তে ব্যবহার করা যেতে পারে।
জেসন আর

দেবিয়ান /bin/running-in-containerদ্বারা সরবরাহ করা হয় upstart। সিস্টেমেডে রূপান্তর হওয়ার সাথে সাথে এটি সরে যেতে পারে। আমি আশা করি না - এটি দরকারী মনে হচ্ছে!
ম্যাক্স মার্ফি 9

"ডিরেক্টরি গাছের উপরে", এর অর্থ কী? ওটা কোথায়?
আলেকজান্ডার মিলস

3
অন্যরা উল্লেখ করেছেন যে চেক করার পরামর্শ দেওয়া.dockerenv হচ্ছে না
ডেভ

1
দ্রষ্টব্য: .ডোকরেনভের জন্য পরীক্ষা কেবলমাত্র রানটাইম ডকার ডেমন হলে কাজ করে e যদি আপনি পডম্যান বা অন্য কিছু ব্যবহার করেন তবে এটি ব্যর্থ হয়।
বেনিয়ামিন কিরচের

22

একটি নতুন উবুন্টু 16.04 সিস্টেমে, নতুন সিস্টেমড ও এলএক্সসি 2.0

sudo grep -qa container=lxc /proc/1/environ

এটি আমার জন্য উবুন্টু ফোকাস 20.04 এ কাজ করে। এই বিন্দুটির উপরের উত্তরগুলির কোনওটিই করেনি।
জোনাথন হার্টলি

16

ব্যাশ স্ক্রিপ্টে ডকারের জন্য যাচাই করার একটি সংক্ষিপ্ত উপায় হ'ল:

#!/bin/bash
if grep docker /proc/1/cgroup -qa; then
   echo I'm running on docker.
fi

14

ডকারে চলছে কিনা তা পরীক্ষা করার জন্য হ্যান্ডি পাইথন ফাংশন:

def in_docker():
    """ Returns: True if running in a Docker container, else False """
    with open('/proc/1/cgroup', 'rt') as ifh:
        return 'docker' in ifh.read()

2
গুরুত্বপূর্ণ তথ্য! কনটেইনারটি কুবারনেটে চলার সময় এটি কাজ করে না। পরিবর্তে, 'ডকার' এর জায়গায় 'কুবিপোড' দিয়ে শেষ লাইনটি প্রতিস্থাপন করুন। (অথবা, একটি "বা" বিবৃতি দিন যা উভয়ের জন্য পরীক্ষা করে;))
জেজেসি

1
এটা kubepodsআমার অনুমান।
rookie099

9

প্রক্রিয়াটির পিআইডি এক্সট্রাক্ট করার জন্য আমরা প্র্যাকের শিডিয়ুল (/ proc / $ পিআইডি / সময়সূচি) ব্যবহার করি। ধারকটির ভিতরে প্রক্রিয়াটির পিআইডি পৃথক হবে তারপরে এটি হোস্টের পিআইডি (একটি নন-ধারক সিস্টেম)।

উদাহরণস্বরূপ, একটি ধারকটিতে / proc / 1 / সময়সূচির আউটপুট ফিরে আসবে:

root@33044d65037c:~# cat /proc/1/sched | head -n 1
bash (5276, #threads: 1)

একটি ধারকহীন হোস্টে থাকার সময়:

$ cat /proc/1/sched  | head -n 1
init (1, #threads: 1)

এটি আপনি ধারক হয়ে আছেন বা না থাকায় পার্থক্য করতে সহায়তা করে।


ওএসের উপর নির্ভর করে "init" কে "systemd" দ্বারা প্রতিস্থাপনের প্রয়োজন হতে পারে। সিস্টেমেড সম্পর্কিত আরও তথ্য এখানে
ব্রায়ানভি

হ্যাঁ, তবে বিন্দুটি আরম্ভ প্রক্রিয়ার নাম ছিল না, বিন্দুটি ছিল প্রক্রিয়া সংখ্যা।
মিলার জিইক

এটি কেবল ডকারে কাজ করে বলে মনে হচ্ছে। একটি LXC কন্টেইনারে এটা systemd PID, 1 ফিরে পাবে
MillerGeek

এটি এখন ডকারেও 1 এ ফিরে আসছে। এটি সাধারণত হয় shএবং initসেখানে থাকে না তবে এটি উভয় ক্ষেত্রেই প্রায় কিছু হতে পারে।
জানু হুডেক

ডকের অধীনে, এটি আর হয় না -bash-5.0# cat /proc/1/sched bash (1, #threads: 1)
শালম্ব

5

সবচেয়ে সহজ উপায় হল পরিবেশ পরীক্ষা করা। আপনার যদি container=lxcভেরিয়েবল থাকে তবে আপনি একটি পাত্রে রয়েছেন।

অন্যথায়, আপনি যদি রুট হন তবে আপনি সঞ্চালন করতে mknodবা mountপরিচালনা করতে চেষ্টা করতে পারেন , যদি এটি ব্যর্থ হয় তবে আপনি সম্ভবত ঝুঁকির ক্ষমতা সম্পন্ন পাত্রে থাকবেন।


এটি কেবলমাত্র ডকারের জন্যই কাজ করে না (আমি এটি চেক করিনি), তবে আরও গুরুত্বপূর্ণভাবে lxd / lxc পাত্রে (চেক করা), যেখানে /proc/1/cgroupআপনাকে এটি সনাক্ত করতে দেয় না।
ড্রাকো আটার

2
আপনি সিউডোকোডের পরিবর্তে কোড দিয়ে উত্তরটি সম্পাদনা করতে পারবেন? "ধারক = lxc"? সঠিক কিছু নয়। আপনি কি [["lxc" = "$ ধারক"]] এর মতো কিছু বোঝাতে চাইছেন?
আলেকজান্ডার মিলস

3
মানে ... এটি অদ্ভুত, সাধারণত এনভ ভেরিয়েবলগুলি সমস্ত ক্যাপগুলিতে থাকে, তাই এখানে কিছু স্পষ্টতা খুঁজছি
আলেকজান্ডার মিলস

7
docker run alpine envভেরিয়েবলের মতো দেখতে এমন কিছু দেয় না
আর্কিমিডিস ট্রাজানো

3

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

আমার একই সমস্যা ছিল এবং /proc/self/cgroupআমি একটি এনএমপি প্যাকেজ তৈরি করে তার উপর নির্ভর করি কেবল এই উদ্দেশ্যে - পাত্রে কোনও নোড.জেএস প্রক্রিয়া চালিত হয় কিনা তা সনাক্ত করতে।

Containerized npm মডিউল Node.js. মধ্যে আপনাকে সাহায্য করবে এটি বর্তমানে আইওজেজে পরীক্ষিত নয় তবে সেখানে খুব ভালভাবে কাজ করতে পারে।


এই মডিউলটির জন্য ধন্যবাদ, বেশ কয়েকটি মুক্ত ফিক্সগুলি মুলতুবি বলে মনে হচ্ছে - আপনি কি এখনও এটি বজায় রাখছেন?
স্টিভোক

2

পাইথনের উপরের সমস্ত সমাধানের জন্য পরীক্ষা করুন:

import os

def in_container():
    proc_1 = r'/proc/1/sched'

    if os.path.exists(proc_1):
        with open(proc_1, 'r') as fp:
            out = fp.read()
    else:
        out = ''

    checks = [
        'docker' in out,
        '/lxc/' in out,
        out.split(' ')[0] not in ('systemd', 'init',),
        os.path.exists('./dockerenv'),
        os.path.exists('/.dockerinit'),
        os.getenv('container') is not None
    ]
    return any(checks)


if __name__ == '__main__':
    print(in_container())

ধারণার প্রমাণ:

$ docker run --rm -it --mount type=bind,source=${PWD}/incontainer.py,target=/tmp/script.py python:3 python /tmp/script.py
True

এটি ম্যাক ভিত্তিক ডকার পাত্রে আমার পক্ষে কাজ করে না। খালি ফিরে আসে। ডকার সংস্করণ 2.1.0.1 (37199)।
splintercell

এই এক যা করেছে: def is_non_docker(): return os.path.exists('/proc/1/cgroup')যেমন গৃহীত উত্তর প্রতি এখানে stackoverflow.com/questions/20010199/...
splintercell

2
আপনি ক্যাট পুরষ্কারের একটি অকেজো ব্যবহার করুন get এবং সাবপ্রসেস একের অকেজো ব্যবহার।
জানু হুডেক

হ্যাঁ এটি সম্পূর্ণ নতুন স্তরের অপ্রয়োজনীয় cat! দুর্দান্ত এক :
ডি

আপনি ঠিক বলেছেন, আমি এখনও উত্তরটি আপডেট করব যদিও এটি এখনও সর্ববৃহৎ নয়। @ জানহুদেক
ব্লেকভ

1

ডকার দিন দিন বিকশিত হচ্ছে, তাই তারা .dockerenv .dockerinitভবিষ্যতে রাখবে কিনা তা আমরা নিশ্চিত করে বলতে পারি না ।

লিনাক্সের বেশিরভাগ স্বাদই initপ্রথম প্রক্রিয়া শুরু হয়। তবে পাত্রে ক্ষেত্রে এটি সত্য নয়।

#!/bin/bash
if ps -p1|grep -q init;then  
  echo "non-docker" 
else 
  echo "docker" 
fi

6
@ রোমানট্রোফিমভ এলএক্সসি / ডকারও নেই। কি মজার মন্তব্য।
গর্ভপাত

1
এটি সেন্টোস 7 তেও কাজ করে না। আমি যখন আমার হোস্ট মেশিনে চলি তখন এটি ডকার বলে। দেখে মনে হচ্ছে সিস্টেমড প্রসেস আইডি 1 হিসাবে চলছে
ভেঙ্কটেশ্বর রাও

@ ভেনকেটেস্বরআরাও - এটি অবশ্যই ধারকটির ভিতরে চালানো উচিত। অভিপ্রায়টি হ'ল আপনি কোনও ডকারের ধারকের ভিতরে আছেন কিনা তা খুঁজে বের করা।
গোবিন্দ কৈলাস

1
@ গোবিন্দকাইলস: সমস্যাটি হ'ল এটি অনুমান করে যে সাধারণ পিআইডি হ'ল init, যা নির্ভর systemdবা launchdভিত্তিক সিস্টেমে সত্য নয় ...
গার্ট ভ্যান ডান বার্গ

3
@ স্যামথোমাস: চালু, আপস্টার্ট, সোলারিস এসএমএফ, সিস্টেমড, সিস ভি স্টাইল ইনি, বিএসডি স্টাইল ইন্ড (এই দুটি এবং আরও কিছু লোক initযদিও তাদের পিআইডি 1 কল করতে পারে ), ওপেনআরসি, আরিগ, রানিট। এখানে দেখুন । বেশিরভাগ আধুনিক লিনাক্স-ভিত্তিক সিস্টেমগুলি ব্যবহার করবে systemd, কিছু পুরানো, আপস্টার্ট .... সমস্ত আধুনিক ওএস এক্স সিস্টেম ব্যবহার করবেlaunchd
জার্ট ভ্যান ডান বার্গ

0

এই SO প্রশ্নোত্তর: "OS ভার্চুয়াল পরিবেশে চলমান কিনা" তা অনুসন্ধান করুন ; যদিও ওপি-র প্রশ্নের মতো নয়, আপনি কোন ধারক (যদি আদৌ) থাকেন তবে এটি সাধারণ ক্ষেত্রে সুনির্দিষ্টভাবে উত্তর দেয়।

বিশেষত, এই ব্যাশ স্ক্রিপ্টের কোডটি ইনস্টল করুন এবং পড়ুন যা মনে হয় বেশ ভালভাবে কাজ করছে:

গুণ-কি :

sudo apt install virt-what

virt-whatউবুন্টু 16.04 এ 1.14-1 সংস্করণ দিয়ে কাজ করে না । প্যাচ দরকার।
লুকাস

0

আমি জেজেসির উত্তরগুলি রুবিতে অনুবাদ করেছি

def in_docker
  File.open('/proc/1/cgroup', 'rt') do |f|
    contents = f.read
    return contents =~ /docker/i || contents =~ /kubepod/i
  end
rescue StandardError => e
  p 'Local development'
  p e
  false
end

-1

একটি ডকার পাত্রে, এন্ট্রি /proc/self/cgroup হোস্টের সিগ্রুপে মাউন্ট করা হয়।

যেমন একটি পাত্রে

# awk -F: '/cpuset/' /proc/self/cgroup
3:cpuset:/docker/22bd0c154fb4e0d1b6c748faf1f1a12116acc21ce287618a115ad2bea41256b3

যদিও, হোস্ট একই

$ awk -F: '/cpuset/' /proc/self/cgroup
3:cpuset:/

লো প্রোফাইল পরীক্ষার জন্য শেলটিতে কিছু ব্যবহার করা

is_running_in_container() {
  awk -F: '/cpuset/ && $3 ~ /^\/$/{ c=1 } END { exit c }' /proc/self/cgroup
}

if is_running_in_container; then
  echo "Aye!! I'm in a container"
else 
  echo "Nay!! I'm not in a container"
fi

উভয়কে 1 প্রদান করে।
সোমিন

-4

সম্ভবত এটি কৌশলটি করুন:

if [ -z $(docker ps -q) ]; then
    echo "There is not process currently running"
else
    echo "There are processes running"
fi

তুমি কি এটাই চাও? আশা করি এটি সাহায্য করে =)


1
dockerস্পষ্টতই ধারকটির অভ্যন্তর থেকে কোনও বাইনারি পাওয়া যায় না ।
টরিনিংগেন

3
উম্ম, এটি পরিস্থিতিতে (যেমন গিটল্যাব ডকার-ইন-ডকার) ব্যর্থ হবে যেখানে নিয়ন্ত্রণকারী ধারকটি dockerহোস্টের ডকার সকেটে অ্যাক্সেস করে।
শালম্ব

1
হ্যাঁ, আপনি ঠিক বলেছেন, অবশ্যই নেই ^^ প্রশ্নটি পড়ার সময় আমি আবার প্রশ্নটি সম্পর্কে ভুল ব্যাখ্যা পেয়েছি। ধন্যবাদ শালম্ব।
লিওনার্দো দা ভিঞ্চি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.