มีวิธีการตรวจสอบว่ากระบวนการ (สคริปต์) ทำงานในภาชนะ lxc (~ นักเทียบท่ารันไทม์)? ฉันรู้ว่าบางโปรแกรมสามารถตรวจพบว่าพวกเขาทำงานภายในเครื่องเสมือนจริงมีอะไรที่คล้ายกันสำหรับ lxc / docker หรือไม่?
มีวิธีการตรวจสอบว่ากระบวนการ (สคริปต์) ทำงานในภาชนะ lxc (~ นักเทียบท่ารันไทม์)? ฉันรู้ว่าบางโปรแกรมสามารถตรวจพบว่าพวกเขาทำงานภายในเครื่องเสมือนจริงมีอะไรที่คล้ายกันสำหรับ lxc / docker หรือไม่?
คำตอบ:
/proc/1/cgroupวิธีที่เชื่อถือได้มากที่สุดคือการตรวจสอบ มันจะบอกคุณกลุ่มควบคุมของกระบวนการเริ่มต้นและเมื่อคุณไม่ได้อยู่ในคอนเทนเนอร์นั่นจะเป็น/ลำดับชั้นทั้งหมด เมื่อคุณอยู่ในภาชนะคุณจะเห็นชื่อของจุดยึด ด้วยตู้คอนเทนเนอร์ LXC / Docker มันจะเป็นอะไรที่ชอบ/lxc/<containerid>หรือ/docker/<containerid>ตามลำดับ
dockerแทนlxcในเส้นทางเหล่านั้น
/กับกลุ่ม cg ทั้งหมดได้ ในระบบ Debian 9 ของฉัน (systemd 232) เพียงสามของ cgroups สิบ ( 3:cpuset, 4:perf_eventและ7:freezer) อยู่ที่ราก /init.scopeส่วนที่เหลืออยู่ภายใต้ ที่กล่าวว่าฉันคิดว่าการค้นหาไฟล์:/docker/นั้นน่าจะเป็นฮิวริสติกที่เชื่อถือได้มากที่สุดในขณะนี้
grep 'docker\|lxc' /proc/1/cgroupทำงานได้สำหรับฉันที่ Docker 18.09
นักเทียบท่าสร้าง.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จริง ๆ และจริง ๆ แล้วมันสามารถคืนชนิดของคอนเทนเนอร์ที่ถูกเรียกใช้งานได้อาจเป็นประโยชน์ ไม่ทราบเกี่ยวกับสิ่งรบกวนสำคัญอื่น ๆ
.dockerinitไฟล์ถูกลบใน Docker เวอร์ชันล่าสุดดังนั้นวิธีนี้จะไม่ทำงานอีกต่อไป จากการเขียนนี้.dockerenvไฟล์ยังคงอยู่รอบ ๆ ดังนั้นอาจใช้แทนได้
/bin/running-in-container upstartด้วยการเปลี่ยนเป็น systemd มันอาจหายไป ฉันหวังว่าจะไม่ - ฟังดูมีประโยชน์!
บนระบบใหม่ของ Ubuntu 16.04 ระบบใหม่ systemd & lxc 2.0
sudo grep -qa container=lxc /proc/1/environ
วิธีรัดกุมในการตรวจสอบนักเทียบท่าในสคริปต์ทุบตีคือ:
#!/bin/bash
if grep docker /proc/1/cgroup -qa; then
echo I'm running on docker.
fi
ฟังก์ชัน Python ที่มีประโยชน์เพื่อตรวจสอบว่าทำงานใน Docker หรือไม่:
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()
kubepodsฉันเดา
เราใช้กำหนดการของ proc (/ proc / $ PID / sched) เพื่อแยก PID ของกระบวนการ PID ของกระบวนการภายในคอนเทนเนอร์จะแตกต่างกันจากนั้นเป็น PID บนโฮสต์ (ระบบที่ไม่ใช่คอนเทนเนอร์)
ตัวอย่างเช่นผลลัพธ์ของ / proc / 1 / sched บนคอนเทนเนอร์จะส่งคืน:
root@33044d65037c:~# cat /proc/1/sched | head -n 1
bash (5276, #threads: 1)
ขณะที่อยู่บนโฮสต์ที่ไม่ใช่คอนเทนเนอร์:
$ cat /proc/1/sched | head -n 1
init (1, #threads: 1)
สิ่งนี้จะช่วยแยกความแตกต่างถ้าคุณอยู่ในภาชนะบรรจุ
shและไม่ได้initอยู่ที่นั่น แต่อาจเป็นอะไรก็ได้
bash-5.0# cat /proc/1/sched bash (1, #threads: 1)
วิธีที่ง่ายที่สุดคือการตรวจสอบสภาพแวดล้อม หากคุณมีcontainer=lxcตัวแปรแสดงว่าคุณอยู่ในคอนเทนเนอร์
มิฉะนั้นถ้าคุณเป็นรูทคุณสามารถลองดำเนินการmknodหรือmountล้มเหลวได้หากเป็นไปได้ว่าคุณมักจะอยู่ในภาชนะที่มีความสามารถในการตก
/proc/1/cgroupไม่อนุญาตให้คุณตรวจจับได้
docker run alpine envไม่ได้ให้อะไรที่ดูเหมือนตัวแปรนั้น
คำตอบของฉันใช้กับกระบวนการ Node.jsเท่านั้น แต่อาจเกี่ยวข้องกับผู้เข้าชมบางคนที่สะดุดกับคำถามนี้เพื่อค้นหาคำตอบเฉพาะของ Node.js
ฉันมีปัญหาเดียวกันและพึ่งพา/proc/self/cgroupฉันสร้างแพคเกจ npmสำหรับวัตถุประสงค์นี้เพียงอย่างเดียว - เพื่อตรวจสอบว่ากระบวนการ Node.js ทำงานในคอนเทนเนอร์ Docker หรือไม่
โมดูล NPM containerizedจะช่วยให้คุณออกมาใน Node.js. ปัจจุบันยังไม่ได้ทดสอบใน Io.js แต่อาจใช้งานได้เช่นกัน
ตรวจสอบการแก้ปัญหาทั้งหมดข้างต้นใน Python:
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
def is_non_docker(): return os.path.exists('/proc/1/cgroup')ตามคำตอบที่ยอมรับได้ที่นี่stackoverflow.com/questions/20010199/…
cat! Nice one :-D
นักเทียบท่าพัฒนาขึ้นทุกวันดังนั้นเราจึงไม่สามารถพูดได้อย่างแน่นอนว่าพวกเขาจะเก็บไว้ .dockerenv .dockerinitในอนาคต
ในที่สุดรสชาติ Linux initเป็นกระบวนการแรกที่เริ่มต้น แต่ในกรณีของตู้คอนเทนเนอร์สิ่งนี้ไม่เป็นความจริง
#!/bin/bash
if ps -p1|grep -q init;then
echo "non-docker"
else
echo "docker"
fi
initซึ่งไม่เป็นความจริงในระบบที่ใช้systemdหรือlaunchd...
init), OpenRC, initng, runit ดูที่นี่ ระบบที่ใช้ลีนุกซ์ที่ทันสมัยส่วนใหญ่จะใช้systemd, บางอันที่เก่ากว่า, พุ่งพรวด .... ระบบ OS X ที่ทันสมัยทั้งหมดจะใช้launchd
คำถาม & คำตอบนี้: "ค้นหาว่าระบบปฏิบัติการทำงานในสภาพแวดล้อมเสมือนจริง"หรือไม่ แม้ว่าจะไม่เหมือนกับคำถามของ OP แต่แน่นอนว่ามันจะตอบกรณีทั่วไปในการค้นหาว่าคุณอยู่ในคอนเทนเนอร์ใด (ถ้าเลย)
โดยเฉพาะอย่างยิ่งติดตั้งและอ่านโค้ดของสคริปต์ทุบตีนี้ซึ่งทำงานได้ดี:
คุณธรรม - อะไร :
sudo apt install virt-what
virt-whatรุ่น 1.14-1 บน Ubuntu 16.04 ต้องการแพทช์
ฉันแปล JJC เป็นทับทิมแล้ว
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
ในคอนเทนเนอร์นักเทียบท่ารายการ/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
บางทีนี่อาจเป็นการหลอกลวง:
if [ -z $(docker ps -q) ]; then
echo "There is not process currently running"
else
echo "There are processes running"
fi
นั่นคือสิ่งที่คุณต้องการ? หวังว่ามันจะช่วย =)
dockerไบนารี่จากภายในภาชนะแน่นอน
dockerและเข้าถึงซ็อกเก็ตพอร์ตของโฮสต์