कैसे निर्धारित करें कि क्या कोई प्रक्रिया lxc / Docker के अंदर चलती है?


172

क्या यह निर्धारित करने का कोई तरीका है कि क्या एक प्रक्रिया (स्क्रिप्ट) एक lxc कंटेनर (~ डॉकर रनटाइम) के अंदर चलती है? मुझे पता है कि कुछ प्रोग्राम यह पता लगाने में सक्षम हैं कि क्या वे एक वर्चुअल मशीन के अंदर चलते हैं, क्या कुछ ऐसा ही उपलब्ध है lxc / docker के लिए?


यह पांडित्यपूर्ण लग सकता है, लेकिन आपके सवाल को हल करने के लिए सबसे अच्छा होगा कि आप एक समस्या का वर्णन करें और पूछें कि इसे कैसे हल किया जाए - इसके बिना, सवाल बंद होने की अधिक संभावना है। कई मामलों में यह परिवर्तन करना मुश्किल है, लेकिन अगर आप चाहें तो आपके लिए इसे फिर से लिखना मुश्किल नहीं होगा।
माह

कंटेनर के अंदर रहते हुए इस कमांड को जारी करते समय एक दिलचस्प प्रतिक्रिया होती है: अपटाइम
स्कॉट स्टेंसलैंड

जवाबों:


169

सबसे विश्वसनीय तरीका जांच करना है /proc/1/cgroup। यह आपको init प्रक्रिया के नियंत्रण समूहों को बताएगा, और जब आप कंटेनर में नहीं होंगे, तो यह /सभी पदानुक्रमों के लिए होगा । जब आप एक कंटेनर के अंदर होते हैं , तो आप लंगर बिंदु का नाम देखेंगे। एलएक्ससी / डॉकटर कंटेनरों के साथ, यह कुछ ऐसा होगा /lxc/<containerid>या /docker/<containerid>क्रमशः।


13
डॉकटर अब उन रास्तों के dockerबजाय उपयोग करता lxcहै
एंडी

4
Lxd / lxc कंटेनरों के लिए काम नहीं करता है, लेकिन stackoverflow.com/a/20010626/170230 करता है।
ड्रेको ऐटर

सिस्टमड के बाद के संस्करणों के साथ ऐसा लगता है कि आप /सभी cgroups के लिए 1 प्रक्रिया पर भरोसा नहीं कर सकते हैं ; मेरी डेबियन 9 सिस्टम पर (232 systemd) केवल दस cgroups के तीन ( 3:cpuset, 4:perf_eventऔर 7:freezer) बुनियाद होती हैं; बाकी के अधीन हैं /init.scope। उस ने कहा, मुझे लगता है कि उस फ़ाइल को खोजना :/docker/शायद फिलहाल सबसे विश्वसनीय अनुमान है।
cjs

2
grep 'docker\|lxc' /proc/1/cgroupमेरे लिए डॉकर 18.09 पर काम करता है।
11

1
मेरे लिए काम नहीं कर रहा है। मेजबान Ubuntu 19.04, अतिथि Ubuntu 18.04 LXC विशेषाधिकार प्राप्त कंटेनर का उपयोग कर। / proc / 1 / cgroup में lxc string नहीं है।
गाब

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और यह वास्तव में उस प्रकार के कंटेनर को वापस कर सकता है जिसे इसमें लगाया गया है। सहायक हो सकता है। हालांकि अन्य प्रमुख विकृतियों के बारे में नहीं जानते।


13
महत्वपूर्ण नोट: .dockerinitफ़ाइल को डॉकर के हाल के संस्करणों में हटा दिया गया है , इसलिए यह विधि किसी भी अधिक काम नहीं करेगी। इस लेखन के रूप में, .dockerenvफ़ाइल को अभी भी आसपास रखा गया है, इसलिए शायद इसका उपयोग किया जा सकता है।
जेसन आर

डेबियन /bin/running-in-containerद्वारा प्रदान किया गया है upstart। प्रणालीगत परिवर्तन के साथ यह दूर जा सकता है। मुझे आशा है कि नहीं - यह उपयोगी लगता है!
अधिकतम मर्फी

"डायरेक्टरी ट्री के ऊपर", इसका क्या मतलब है? वह कहा है?
अलेक्जेंडर मिल्स

3
अन्य लोगों ने बताया कि जाँच .dockerenvकी अनुशंसा नहीं की जाती है
डेव

1
नोट: .dockerenv के लिए परीक्षण केवल तभी काम करता है जब रनटाइम doemon डेमन हो। यदि आप पॉडमैन या कुछ और उपयोग कर रहे हैं तो यह विफल हो जाता है।
बेंजामिन किरचर

22

एक नए ubuntu 16.04 प्रणाली पर, नया systemd और lxc 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
महत्वपूर्ण लेख! यह काम नहीं करता है जब कंटेनर कुबेरनेट्स में चल रहा है। इसके बजाय, अंतिम पंक्ति को 'docker' के स्थान पर 'kubepod' से बदलें। (या, एक "या" स्टेटमेंट में डालें जो दोनों की जांच करता है;))
JJC

1
यह kubepodsमुझे लगता है कि।
रॉकी 099

9

हम प्रक्रिया के PID को निकालने के लिए proc के शेड्यूल (/ proc / $ PID / शेड्यूल) का उपयोग करते हैं। कंटेनर के अंदर प्रक्रिया की पीआईडी ​​अलग होगी फिर यह मेजबान (एक गैर-कंटेनर प्रणाली) पर पीआईडी ​​है।

उदाहरण के लिए, कंटेनर पर / 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)

यदि आप कंटेनर में हैं या नहीं, यह अंतर करने में मदद करता है।


OS के आधार पर, "init" को "systemd" द्वारा प्रतिस्थापित करने की आवश्यकता हो सकती है। सिस्टमडे पर अधिक जानकारी यहाँ
ब्रायन वी

हां, लेकिन बिंदु init प्रक्रिया का नाम नहीं था, बिंदु प्रक्रिया संख्या थी।
मिलरजीक

यह केवल डॉकर पर काम करने के लिए लगता है। एक एलएक्ससी कंटेनर में यह सिस्टमड पीआईडी ​​1
मिलरगीक

यह अब docker में भी 1 की वापसी कर रहा है। यह आमतौर पर है shऔर initवहां नहीं है, लेकिन यह या तो लगभग कुछ भी हो सकता है।
जान हुडेक

bash-5.0# cat /proc/1/sched bash (1, #threads: 1)
डॉकटर के

5

सबसे आसान तरीका होगा पर्यावरण की जांच करना। यदि आपके पास container=lxcचर है, तो आप एक कंटेनर के भीतर हैं।

अन्यथा, यदि आप जड़ हैं, तो आप प्रदर्शन mknodया mountसंचालन करने की कोशिश कर सकते हैं , यदि यह विफल हो जाता है, तो आप ड्रॉप किए गए क्षमताओं वाले कंटेनर में सबसे अधिक संभावना रखते हैं।


यह केवल docker के लिए काम करता है (मैंने वह जाँच नहीं की), लेकिन अधिक महत्वपूर्ण रूप से lxd / lxc कंटेनरों (जाँच) के लिए, जहाँ आप /proc/1/cgroupइसका पता नहीं लगा सकते।
ड्रेको ऐटर

2
क्या आप छद्म कोड के बजाय कोड के साथ उत्तर को संपादित कर सकते हैं? "कंटेनर = lxc"? कुछ भी उचित नहीं है। क्या आपका मतलब कुछ ऐसा है अगर [["lxc" = "$ कंटेनर"]]?
अलेक्जेंडर मिल्स

3
मेरा मतलब है ... यह अजीब है, आमतौर पर env वैरिएबल सभी कैप में होते हैं, इसलिए यहां कुछ सटीक खोज रहे हैं
अलेक्जेंडर मिल्स

7
docker run alpine envकुछ भी ऐसा नहीं है जो उस चर की तरह दिखता है
आर्किमिडीज ट्रेजानो

3

मेरा उत्तर केवल Node.js प्रक्रियाओं के लिए लागू होता है, लेकिन कुछ आगंतुकों के लिए प्रासंगिक हो सकता है जो इस प्रश्न पर ठोकर खाते हैं जो Node.js विशिष्ट उत्तर की तलाश में हैं।

मेरे पास एक ही समस्या थी और इस पर भरोसा करते हुए /proc/self/cgroupमैंने केवल इस उद्देश्य के लिए एक एनपीएम पैकेज बनाया - यह पता लगाने के लिए कि क्या डोडर कंटेनर के अंदर Node.js प्रक्रिया चलती है या नहीं।

कंटेनरीकृत NPM मॉड्यूल Node.js. में तुम बाहर में मदद मिलेगी यह वर्तमान में Io.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
आपको कैट अवार्ड का यूज़लेस यूज़ मिलता है। और उपप्रयोग का बेकार उपयोग।
जान हुडेक

हाँ यह अनावश्यक का एक नया स्तर है cat! अच्छा एक :-D
टिमम्मा

आप सही हैं, मैं इसका जवाब अपडेट कर दूंगा, हालांकि यह अभी भी सबकुछ नहीं है। @JanHudec
blakev

1

डॉकर दिन-प्रतिदिन विकसित हो रहा है, इसलिए हम .dockerenv .dockerinitभविष्य में रखने जा रहे हैं तो हम निश्चित रूप से नहीं कह सकते ।

अधिकांश लिनक्स में फ्लेवर initशुरू करने की पहली प्रक्रिया है। लेकिन कंटेनरों के मामले में यह सच नहीं है।

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

6
@RomanTrofimov LXC / Docker या तो नहीं करता है। क्या मजेदार टिप्पणी है।
abourget

1
यह सेंटो 7 में भी काम नहीं करता है। जब मैं अपने मेजबान मशीन में चलता हूं तो यह कहता है कि डॉकटर। लगता है कि systemd प्रक्रिया id 1 के रूप में चल रहा है
वेंकटेश्वर राव

@VenkateswaraRao - यह कंटेनर के अंदर चलाया जाना चाहिए। इरादा यह पता लगाने का है कि आप डॉकटर कंटेनर के अंदर हैं या नहीं।
गोविंद कैलास

1
@ गोविंदकैलस: समस्या यह है कि यह मानता है कि सामान्य पीआईडी ​​एक है init, जो कि systemdया launchdआधारित सिस्टम पर सच नहीं है ...
गर्ट वैन डेन बर्ग

3
@SamThomas: launchd, upstart, Solaris SMF, systemd, Sys V style init, BSD स्टाइल इनिट (ये दो और कुछ अन्य लोग अपने PID को 1 कह सकते हैं init), OpenRC, initng, runit। यहाँ देखें । अधिकांश आधुनिक लिनक्स-आधारित सिस्टम का उपयोग करेंगे systemd, कुछ पुराने, अपस्टार्ट .... सभी आधुनिक ओएस एक्स सिस्टम का उपयोग करेंगेlaunchd
गर्ट वैन डेन बर्ग

0

यह SO Q & A: "यह पता करें कि क्या OS एक आभासी वातावरण में चल रहा है" ; हालांकि ओपी के प्रश्न के समान नहीं है, लेकिन यह वास्तव में आम कंटेनर के जवाब देने का है कि आप किस कंटेनर में हैं (यदि बिल्कुल)।

विशेष रूप से, इस बैश स्क्रिप्ट के कोड को स्थापित करें और पढ़ें, जो बहुत अच्छी तरह से काम करता है:

पुण्य-क्या :

sudo apt install virt-what

virt-whatUbuntu 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मेजबान पर cgroups को प्रविष्टियां मुहैया कराई जाती हैं।

एक कंटेनर में जैसे

# 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
उम्म, यह उन स्थितियों में विफल होगा (जैसे gitlab docker-in-docker) जहां कंट्रोलिंग कंटेनर में dockerमेजबानों के डॉक सॉकेट तक पहुंच है।
शालम्ब

1
हाँ, आप सही हैं, निश्चित रूप से ^ ^ नहीं है। मुझे उस समय के प्रश्न के बारे में गलत व्याख्या मिली जब मैंने इसे पढ़ा। धन्यवाद, शालम्ब।
लियोनार्डो दा विंची
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.