ডকার পাত্রে কোনও প্রক্রিয়া চলছে কিনা তা কীভাবে পরীক্ষা করবেন


89

[আপডেট1] আমার একটি শেল রয়েছে যা কিছু ফাংশনে টিসিপি কার্নেল প্যারামিটারগুলি পরিবর্তন করবে, তবে এখন আমার এই শেলটি ডকার পাত্রে চালানো দরকার, এর অর্থ শেলটি এটি একটি ধারকের ভিতরে চলছে এবং কার্নেলটি কনফিগার করা বন্ধ করতে হবে stop

এখন আমি কীভাবে এটি অর্জন করব তা নিশ্চিত নই, ধারকটির অভ্যন্তরের বিষয়বস্তু এখানে /proc/self/cgroup:

9:hugetlb:/
8:perf_event:/
7:blkio:/
6:freezer:/
5:devices:/
4:memory:/
3:cpuacct:/
2:cpu:/docker/25ef774c390558ad8c4e9a8590b6a1956231aae404d6a7aba4dde320ff569b8b
1:cpuset:/

এই প্রক্রিয়াটি কোনও ধারকটির ভিতরে চলছে কিনা তা বোঝার জন্য উপরের কোনও পতাকাগুলি ব্যবহার করতে পারি?

[আপডেট ২]: আমি lxc / ডকারের ভিতরে কোনও প্রক্রিয়া চালিত হয় কিনা তা নির্ধারণের বিষয়টিও লক্ষ্য করেছি , তবে মনে হয় এটি এই ক্ষেত্রে কাজ করছে না, /proc/1/cgroupআমার ধারকটির বিষয়বস্তুটি হ'ল:

8:perf_event:/
7:blkio:/
6:freezer:/
5:devices:/
4:memory:/
3:cpuacct:/
2:cpu:/docker/25ef774c390558ad8c4e9a8590b6a1956231aae404d6a7aba4dde320ff569b8b
1:cpuset:/

না / lxc / ধারক


খুব পরিষ্কার প্রশ্ন নয়। আপনার এটার দরকার কেন?
হেন্ক ল্যাঙ্গভেল্ড


আমার ক্ষেত্রে @ ফিশ নং / এলএক্সসি / <কনটেনারিড>, আপডেট দেখুন
হেরিজেজ

4
@ হেনকলেঙ্গেলভেল্ড কার্নেল প্যারামিটারগুলি কেবল ডকার পাত্রেই পঠনযোগ্য, তাই আমার শেলগুলি পাত্রে রাখার চেষ্টা করছে এবং আমার শেলের মধ্যে কার্নেল ফাংশন অক্ষম করছে কিনা তা আমার জানতে হবে। আপডেট দেখুন।
হ্যারিজেজ

স্ক্রিপ্টের কয়েকটি পদক্ষেপ কার্নেল প্যারামিটারগুলি সংশোধন করার চেষ্টা করে এবং ডকারে চলার সময় এড়িয়ে যাওয়া দরকার। পরিষ্কার.
হেন্ক ল্যাঙ্গভেল্ড

উত্তর:


70

আপনি যদি কোনও ডকারের ধারকের ভিতরে আছেন বা এর মাধ্যমে করা যায় না তবে কোনও ডকারের ধারক ভিতরে পরীক্ষা করতে /proc/1/cgroup। যেহেতু এই পোস্টটি প্রস্তাব দেওয়া আপনি নিম্নলিখিত করতে পারেন:

আপনি এখানে দেখতে পারেন এমন কোনও ডকারের ধারকের বাইরে সমস্ত প্রবেশদ্বার /proc/1/cgroupশেষ হয় /:

vagrant@ubuntu-13:~$ cat /proc/1/cgroup
11:name=systemd:/
10:hugetlb:/
9:perf_event:/
8:blkio:/
7:freezer:/
6:devices:/
5:memory:/
4:cpuacct:/
3:cpu:/
2:cpuset:/

একটি ডকারের ধারকের ভিতরে কয়েকটি নিয়ন্ত্রণ গোষ্ঠী ডকার (বা এলএক্সসি) এর অন্তর্ভুক্ত থাকবে:

vagrant@ubuntu-13:~$ docker run busybox cat /proc/1/cgroup
11:name=systemd:/
10:hugetlb:/
9:perf_event:/
8:blkio:/
7:freezer:/
6:devices:/docker/3601745b3bd54d9780436faa5f0e4f72bb46231663bb99a6bb892764917832c2
5:memory:/
4:cpuacct:/
3:cpu:/docker/3601745b3bd54d9780436faa5f0e4f72bb46231663bb99a6bb892764917832c2
2:cpuset:/

@ ফাউন্ডার উত্তর পরিষ্কার
স্কট স্টেনসল্যান্ড

4
এটি কঠোরভাবে সত্য নয় যে "ডকের ধারকের বাইরে / ক্রোক / 1 / সিগ্রুপের সমস্ত প্রবেশ /" এ শেষ হয়। উবুন্টুতে 16.04 এ উদাহরণস্বরূপ আমার কাছে রয়েছে:12:perf_event:/ 11:blkio:/init.scope 10:cpuset:/ 9:devices:/init.scope 8:hugetlb:/ 7:cpu,cpuacct:/init.scope 6:net_cls,net_prio:/ 5:memory:/init.scope 4:pids:/init.scope 3:rdma:/ 2:freezer:/ 1:name=systemd:/init.scope
samfr

এটি কেবলমাত্র লিনাক্সে কাজ করে, ডারউইন বা অন্যান্য বিএসডিগুলিতে নয় যা এমনকি একটি প্রকফ ব্যবহার করে না।
খ্রিস্টান

@ ক্রিশ্চিয়ান ডকার / এলএক্সসি লিনাক্স কেবল জিনিস, তাই ঠিক আছে, তাই না?
রবার্ট ল্যাক্রিক্স

@ রবার্টলাক্রিক্স তাই আপনি যদি বলছেন যে যদি আপনি কোনও প্রকফ না পান তবে আপনি ডকারে নেই? ঠিক আছে, আমার পক্ষে এটি যথেষ্ট ন্যায্য ...
খ্রিস্টান

112

ডকার তৈরি করে .dockerenvএবং .dockerinit( v1.11-এ সরানো হয়েছে) কনটেইনার ডিরেক্টরি গাছের শীর্ষে ফাইল ) যাতে আপনি সেগুলি বিদ্যমান কিনা তা পরীক্ষা করতে পারেন।

এর মতো কিছু কাজ করা উচিত।

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

4
অবশ্যই, যদি না আপনি বা অন্য কেউ /.dockerinitআপনার হোস্টে তৈরি করেছেন (সম্ভবত দুর্ঘটনাক্রমে), সেই ক্ষেত্রে এটি কোনও ধারকটির বাইরে ভুল হবে wrong
sosiouxme

18
যদি অন্য কেউ এটিকে তৈরি করে থাকেন / তবে সেগুলি মূল এবং আপনি ডকারে আছেন কিনা তা জানার চেয়ে আপনার আরও খারাপ সমস্যা হয়েছে।
ডেভি

15
/.dockerenvদীর্ঘমেয়াদে নির্ভর করা সাবধান । এটি এভাবে ব্যবহার করার উদ্দেশ্যে নয়
রিঅ্যাকটিভরভেন

নতুনভাবে, পোডম্যান তৈরি করে না /.dockerenv। এটি তৈরি করে /run/.containerenvকিন্তু অনুরূপ যুক্তি দ্বারা, বাস্তবায়নের বিশদটি নির্ভর করা যায় না বলে মনে হয়। কিছু পডম্যান-নির্দিষ্ট বিকল্পের জন্য github.com/containers/libpod/issues/3586 দেখুন ।
বেনি চেরনিয়াভস্কি-পাসকিন

24

প্রক্রিয়াটির পিআইডি এক্সট্রাক্ট করার জন্য আমরা প্র্যাকের শিডিউল (/ 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)

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

if [[ ! $(cat /proc/1/sched | head -n 1 | grep init) ]]; then {
    echo in docker
} else {
    echo not in docker
} fi

এটি আসলে বেশ মূল্যবান তথ্য। ধন্যবাদ
ফ্যাবিয়ান ল্যাঞ্জ

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

4
@ ব্রায়ানভি দ্বারা উল্লিখিত হিসাবে, এটি আমার পক্ষেও কার্যকর হয় না।
শুভম চৌধুরী চৌধুরী

4
একটি কে 8 এস ক্লাস্টারে চলছে এমন একটি ডকার পাত্রে, head -n1 /proc/1/schedফিরে আসে dumb-init (1, #threads: 1), সুতরাং এই উত্তরে প্রস্তাবিত চেকটি ব্যর্থ হয়। (এছাড়াও, উত্তরটি যা বলেছে তার বিপরীতে পিআইডি "লাইন" হিসাবে "1" হিসাবে দেখানো হয়েছে যদিও আমি এটি একটি
ধারকতে করছি

এটি অবশ্যই সর্বজনীন সমাধান নয়। আপনি কোনও ধরণের পাত্রের পিআইডি-র জন্য যা চান তা ব্যবহার করতে পারেন (উদাহরণস্বরূপ) আপনি যদি docker run --init ...এটি করেন তবে তা হবে docker-init। আপনি যদি উদাহরণস্বরূপ docker run ... head -n 1 /proc/1/schedএটি করা হবে head
jpkotta

21

কোড হিসাবে থমাস সমাধান:

running_in_docker() {
  (awk -F/ '$2 == "docker"' /proc/self/cgroup | read non_empty_input)
}

বিঃদ্রঃ

readএকটি ডামি পরিবর্তনশীল সঙ্গে জন্য একটি সহজ বাগ্ধারা হয় এই আছে কোন আউটপুট উত্পাদন? । এটি সম্ভবত ভার্বোজকে পরিণত করার জন্য grepবা কোনও প্যাটার্নের পরীক্ষায় রূপ awkদেওয়ার জন্য একটি কমপ্যাক্ট পদ্ধতি ।

পড়ার উপর অতিরিক্ত নোট


10
ব্যতীত ... এটি কিছু কল্পনাতে ব্যর্থ হবে, কারণ, যেমন 3:cpu,cpuacct:/system.slice/docker-1ce79a0dec4a2084d54acf187a1e177e0339dc90d0218b48b4456576ecaf291e.scopeমেলে না match সহজ grep -q docker /proc/1/cgroup; এর থেকে ফলাফলের কোডটিও পর্যাপ্ত হতে হবে।
larsks

4
readএর জন্য কাজ করতে পারে bashতবে সর্বাধিক ব্যবহৃত dashশেলটিতে আপনাকে হয় read dummy(বা অনুরূপ) ব্যবহার করতে হবে বা নির্মাণের মতো ব্যবহার করতে হবে[ -n "$(command)" ]
ড্যানিয়েল অল্ডার

@ ড্যানিয়েলএল্ডার ভাল ক্যাচ, ড্যানিয়েল আমি লেখাটি আপডেট করব।
হেন্ক ল্যাঙ্গভেল্ড

4
পূর্বে এটি দাবি করেছিল যে কোনও বোর্ন সামঞ্জস্যপূর্ণ শেল readভেরিয়েবলের নাম ছাড়াই সমতলকে সমর্থন করে । এটি কেবল ব্যাশ এবং ksh93 এর ক্ষেত্রেই সত্য। ওপেনগ্রুপটি অন্তত একটি পরিবর্তনশীল ব্যতীত কেবল আচরণের read varউল্লেখ করে এবং উল্লেখ করে না read। ইন ব্যাশ এবং ksh93 , যদি কোন Var দেওয়া হয় ব্যবহারসমূহ শেল পরিবর্তনশীল পড়া REPLY
হেন্ক ল্যাঙ্গভেল্ড

4
আমরা শুধু ব্যবহার করতে পারি না কেন awk -F: '$3 ~ /docker/' /proc/self/cgroup | read? আমার জন্য কাজ কর.
শুভম চৌধুরী চৌধুরী

7

আমার জন্য যা কাজ করে তা হ'ল '/' এর ইনোড নম্বরটি পরীক্ষা করা। ডকের ভিতরে, এটি একটি খুব উচ্চ সংখ্যা। ডকের বাইরে এটি '2' এর মতো খুব কম সংখ্যক। আমি মনে করি এই পদ্ধতিটি ব্যবহার করা ফাইলসিস্টেমের উপরও নির্ভর করবে।

উদাহরণ

ডকের ভিতরে:

# ls -ali / | sed '2!d' |awk {'print $1'}
1565265

ডকের বাইরে

$ ls -ali / | sed '2!d' |awk {'print $1'}
2

একটি স্ক্রিপ্টে:

#!/bin/bash
INODE_NUM=`ls -ali / | sed '2!d' |awk {'print $1'}`
if [ $INODE_NUM == '2' ];
then
        echo "Outside the docker"
else
        echo "Inside the docker"
fi

এমএসওয়াইএস 2 এলএস -ালী / | সেড '2! ডি' | awk {'মুদ্রণ $ 1'} 232779805740174872
Bo0k

একই হিসাবে ls -di /? বিভিন্ন প্ল্যাটফর্মের
ইনোড নাম্বার

এই একমাত্র জিনিস যা আমার জন্য জেন ডোমু হোস্ট এবং এর ডকার ধারক মধ্যে পার্থক্য করতে কাজ করেছিল
মাইকেল আল্টফিল্ড

1

আমাদের পাত্রে চলমান প্রক্রিয়াগুলি বাদ দিতে হবে, তবে কেবল ডকার সিগ্রুপগুলির জন্য পরীক্ষা করার পরিবর্তে আমরা ই-ডি-সি /proc/<pid>/ns/pidসিস্টেমের সাথে তুলনা করার সিদ্ধান্ত নিয়েছি /proc/1/ns/pid। উদাহরণ:

pid=$(ps ax | grep "[r]edis-server \*:6379" | awk '{print $1}')
if [ $(readlink "/proc/$pid/ns/pid") == $(readlink /proc/1/ns/pid) ]; then
   echo "pid $pid is the same namespace as init system"
else
   echo "pid $pid is in a different namespace as init system"
fi

অথবা আমাদের ক্ষেত্রে আমরা এমন একটি লাইনার চেয়েছিলাম যা প্রক্রিয়াটি ধারক অবস্থায় না থাকলে ত্রুটি তৈরি করে

bash -c "test -h /proc/4129/ns/pid && test $(readlink /proc/4129/ns/pid) != $(readlink /proc/1/ns/pid)"

যা আমরা অন্য প্রক্রিয়া থেকে নির্বাহ করতে পারি এবং যদি প্রস্থান কোডটি শূন্য হয় তবে নির্দিষ্ট পিআইডি একটি ভিন্ন নেমস্পেসে চলছে।


আমার জন্য কাজ করে না। কোনও কে 8 এস-নির্ধারিত ডকার ধারকের মধ্যে থেকে readlink /proc/self/ns/pidএবং readlink /proc/1/ns/pidএকই আউটপুট উত্পাদন করে produce
স্টিফান মাজেউস্কি

4
@ স্টেফানমাজেস্কি মাইন্ডার কনটেনার রানটাইমটিতে কী কী বৈশিষ্ট্যগুলি সক্ষম করা হয়েছে তা দেখতে github.com/jessfraz/amicontain ব্যবহার করার চেষ্টা করতে চান
গ্রেগ ব্রে

0

SELinux ব্যবহার সম্পর্কে ড্যান ওয়ালশের মন্তব্যের ভিত্তিতে ps -eZ | grep container_t, তবে psইনস্টল করার প্রয়োজন ছাড়াই :

$ podman run --rm fedora:31 cat /proc/1/attr/current
system_u:system_r:container_t:s0:c56,c299
$ podman run --rm alpine cat /proc/1/attr/current
system_u:system_r:container_t:s0:c558,c813
$ docker run --rm fedora:31 cat /proc/1/attr/current
system_u:system_r:container_t:s0:c8,c583
$ cat /proc/1/attr/current
system_u:system_r:init_t:s0

এটি আপনাকে কেবল একটি পাত্রে চালাচ্ছেন তবে রানটাইমটি নয়।

অন্যান্য কন্টেইনার রানটাইমগুলি যাচাই করে নি তবে https://opensource.com/article/18/2/unders বোঝ-selinux-labels- container-runtimes আরও তথ্য সরবরাহ করে এবং পরামর্শ দেয় যে এটি ব্যাপকভাবে ব্যবহৃত হয়, rkt এবং lxc এর জন্যও কাজ করতে পারে ?


0

গোলং কোড

func GetContainerID(pid int32) string {
    cgroupPath := fmt.Sprintf("/proc/%s/cgroup", strconv.Itoa(int(pid)))
    return getContainerID(cgroupPath)
}

func GetImage(containerId string) string {
    if containerId == "" {
        return ""
    }
    image, ok := containerImage[containerId]
    if ok {
        return image
    } else {
        return ""
    }
}
func getContainerID(cgroupPath string) string {
    containerID := ""
    content, err := ioutil.ReadFile(cgroupPath)
    if err != nil {
        return containerID
    }
    lines := strings.Split(string(content), "\n")
    for _, line := range lines {
        field := strings.Split(line, ":")
        if len(field) < 3 {
            continue
        }
        cgroup_path := field[2]
        if len(cgroup_path) < 64 {
            continue
        }
        // Non-systemd Docker
        //5:net_prio,net_cls:/docker/de630f22746b9c06c412858f26ca286c6cdfed086d3b302998aa403d9dcedc42
        //3:net_cls:/kubepods/burstable/pod5f399c1a-f9fc-11e8-bf65-246e9659ebfc/9170559b8aadd07d99978d9460cf8d1c71552f3c64fefc7e9906ab3fb7e18f69
        pos := strings.LastIndex(cgroup_path, "/")
        if pos > 0 {
            id_len := len(cgroup_path) - pos - 1
            if id_len == 64 {
                //p.InDocker = true
                // docker id
                containerID = cgroup_path[pos+1 : pos+1+64]
                // logs.Debug("pid:%v in docker id:%v", pid, id)
                return containerID
            }
        }
        // systemd Docker
        //5:net_cls:/system.slice/docker-afd862d2ed48ef5dc0ce8f1863e4475894e331098c9a512789233ca9ca06fc62.scope
        docker_str := "docker-"
        pos = strings.Index(cgroup_path, docker_str)
        if pos > 0 {
            pos_scope := strings.Index(cgroup_path, ".scope")
            id_len := pos_scope - pos - len(docker_str)
            if pos_scope > 0 && id_len == 64 {
                containerID = cgroup_path[pos+len(docker_str) : pos+len(docker_str)+64]
                return containerID
            }
        }
    }
    return containerID
}

-1

আমি একটি অজগর লিপি তৈরি করেছি। আশা করি কেউ এটিকে কাজে লাগিয়েছেন। :-)

#!/usr/bin/env python3
#@author Jorge III Altamirano Astorga 2018
import re
import math

total = None
meminfo = open('/proc/meminfo', 'r')
for line in meminfo:
    line = line.strip()
    if "MemTotal:" in line:
        line = re.sub("[^0-9]*", "", line)
        total = int(line)
meminfo.close()
print("Total memory: %d kB"%total)

procinfo = open('/proc/self/cgroup', 'r')
for line in procinfo: 
    line = line.strip()
    if re.match('.{1,5}:name=systemd:', line):
        dockerd = "/sys/fs/cgroup/memory" + \
            re.sub("^.{1,5}:name=systemd:", "", line) + \
            "/memory.stat"
        #print(dockerd)
        memstat = open(dockerd, 'r')
        for memline in memstat:
            memline = memline.strip()
            if re.match("hierarchical_memory_limit", memline):
                memline = re.sub("[^0-9]*", \
                    "", memline)  
                total = math.floor(int(memline) / 2**10)
        memstat.close()
procinfo.close()
print("Total available memory to the container: %d kB"%total)

এটি দুর্দান্ত, তবে এটি নির্ধারণে কীভাবে সহায়তা করে আপনি কোনও ধারকের ভিতরে আছেন কিনা?
ব্যবহারকারী528025

FileNotFoundError: [Errno 2] No such file or directory: '/sys/fs/cgroup/memory/docker/<docker_id>/memory.stat'
স্ক্রুজ ম্যাকডাক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.