มีวิธีการตรวจสอบว่ากระบวนการ (สคริปต์) ทำงานในภาชนะ 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
และเข้าถึงซ็อกเก็ตพอร์ตของโฮสต์