ความแตกต่างระหว่าง docker และ docker exec

ทั้งสองจะสามารถรันคำสั่งในคอนเทนเนอร์ได้ ทั้งสองสามารถถอดภาชนะออกได้

ดังนั้นความแตกต่างที่แท้จริงระหว่าง docker exec และ dockerแนบคืออะไร?


person MJL    schedule 21.06.2015    source แหล่งที่มา


คำตอบ (4)


มี commit PR ซึ่งเพิ่มลงในเอกสาร:

หมายเหตุ: คำสั่งนี้ (attach) ไม่ได้มีไว้สำหรับเรียกใช้กระบวนการใหม่ในคอนเทนเนอร์ ดู: docker exec

คำตอบของ "Docker วิธีรับ bash\ssh ภายในคอนเทนเนอร์ที่รัน (run -d)?" แสดงให้เห็นถึงความแตกต่าง:

(นักเทียบท่า >= 1.3) หากเราใช้ docker attach เราสามารถ ใช้เชลล์เพียงอินสแตนซ์เดียว.
ดังนั้นหากเราต้องการเปิดเทอร์มินัลใหม่ด้วยอินสแตนซ์ใหม่ของเชลล์คอนเทนเนอร์ เราเพียงแค่ต้องเรียกใช้ docker exec

หากคอนเทนเนอร์นักเทียบท่าเริ่มทำงานโดยใช้คำสั่ง /bin/bash คุณสามารถเข้าถึงได้โดยใช้ไฟล์แนบ หากไม่เป็นเช่นนั้น คุณจะต้อง ดำเนินการ คำสั่งเพื่อสร้างอินสแตนซ์ bash ภายในคอนเทนเนอร์โดยใช้ exec

ตามที่กล่าวไว้ในปัญหานี้:

  • การแนบไม่ได้มีไว้สำหรับการเรียกใช้สิ่งพิเศษในคอนเทนเนอร์ แต่สำหรับการแนบกับกระบวนการที่กำลังรันอยู่
  • "docker exec" มีไว้สำหรับเรียกใช้สิ่งใหม่ๆ ในคอนเทนเนอร์ที่เริ่มต้นแล้วโดยเฉพาะ ไม่ว่าจะเป็นเชลล์หรือกระบวนการอื่นๆ

ปัญหาเดียวกันนี้เพิ่ม:

แม้ว่า attach จะตั้งชื่อได้ไม่ดีนัก โดยเฉพาะอย่างยิ่งเนื่องจากคำสั่ง LXC lxc-attach (ซึ่งคล้ายกับ docker exec <container> /bin/sh มากกว่า แต่เฉพาะเจาะจงกับ LXC) แต่ก็มีวัตถุประสงค์เฉพาะในการแนบคุณเข้ากับกระบวนการที่ Docker เริ่มต้นอย่างแท้จริง
ขึ้นอยู่กับ กระบวนการที่เป็นพฤติกรรมอาจแตกต่างกัน เช่น การแนบกับ /bin/bash จะทำให้คุณได้รับเชลล์ แต่การแนบกับเซิร์ฟเวอร์ Redis จะเหมือนกับว่าคุณเพิ่งเริ่ม Redis โดยตรงโดยไม่ต้อง daemonizing

person VonC    schedule 21.06.2015

เมื่อคอนเทนเนอร์เริ่มใช้ /bin/bash คอนเทนเนอร์นั้นจะกลายเป็นคอนเทนเนอร์ PID 1 และนักเทียบท่าจะใช้ในการเข้าไปภายใน PID 1 ของคอนเทนเนอร์ ดังนั้น นักเทียบท่าแนบ ‹ คอนเทนเนอร์-id > จะนำคุณเข้าไปในเทอร์มินัล bash เนื่องจากเป็น PID 1 ตามที่เรากล่าวไว้ในขณะที่เริ่มต้นคอนเทนเนอร์ การออกจากคอนเทนเนอร์จะหยุดคอนเทนเนอร์

ในขณะที่คำสั่ง docker exec คุณสามารถระบุเชลล์ที่คุณต้องการป้อนได้ มันจะไม่นำคุณไปที่ PID 1 ของคอนเทนเนอร์ มันจะสร้างกระบวนการใหม่สำหรับการทุบตี นักเทียบท่า exec -it ‹ คอนเทนเนอร์-id > ทุบตี การออกจากคอนเทนเนอร์จะไม่ทำให้คอนเทนเนอร์หยุดทำงาน

คุณยังสามารถใช้ nsenter เพื่อเข้าไปในคอนเทนเนอร์ได้ nsenter -m -u -n -p -i -t ‹ pid ของคอนเทนเนอร์ > คุณสามารถค้นหา PID ของคอนเทนเนอร์ได้โดยใช้: docker inspect ‹ container-id > | grep PID

หมายเหตุ: หากคุณเริ่มต้นคอนเทนเนอร์ด้วยแฟล็ก -d การออกจากคอนเทนเนอร์จะไม่หยุดคอนเทนเนอร์ ไม่ว่าคุณจะใช้การแนบหรือ exec เพื่อเข้าไปข้างใน

person Samrat Priyadarshi    schedule 09.05.2017
comment
แนวคิดที่น่าสนใจเกี่ยวกับการใช้ nsenter คุณช่วยอธิบายรายละเอียดได้ไหม? การอธิบายตัวเลือกจะเป็นไปตามลำดับ ทำไมไม่ใส่เนมสเปซทั้งหมด? ทำไมคนเหล่านี้โดยเฉพาะ? - person x-yuri; 29.06.2019

ดังที่ Michael Sun ระบุไว้ในคำตอบของเขา

docker exec ดำเนินการคำสั่งใหม่ / สร้างกระบวนการใหม่ในสภาพแวดล้อมของคอนเทนเนอร์ ในขณะที่ docker attach เพียงเชื่อมต่ออินพุต/เอาต์พุต/ข้อผิดพลาดมาตรฐานของกระบวนการหลัก (ด้วย PID 1) ภายในคอนเทนเนอร์กับอินพุต/เอาต์พุต/ข้อผิดพลาดมาตรฐานที่สอดคล้องกันของเทอร์มินัลปัจจุบัน ( เทอร์มินัลที่คุณใช้เพื่อรันคำสั่ง)

คำตอบของฉันจะเน้นไปที่การให้คุณตรวจสอบข้อความข้างต้นและเข้าใจได้ชัดเจนยิ่งขึ้น

เปิดหน้าต่างเทอร์มินัลแล้วรันคำสั่ง docker run -itd --name busybox busybox /bin/sh คำสั่งจะดึงรูปภาพ busybox หากยังไม่มี จากนั้นจะสร้างคอนเทนเนอร์ชื่อ busybox โดยใช้อิมเมจนี้

คุณสามารถตรวจสอบสถานะของคอนเทนเนอร์ของคุณได้โดยการรันคำสั่ง docker ps -a | grep busybox

หากคุณรัน docker top busybox คุณจะเห็นผลลัพธ์ดังนี้

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                7469                7451                0                   11:40               pts/0               00:00:00            /bin/sh

แน่นอนว่า PID, PPID และค่าอื่นๆ จะแตกต่างออกไปในกรณีของคุณ คุณสามารถใช้เครื่องมือและยูทิลิตีอื่นๆ เช่น pstree, top, htop เพื่อดูรายการ PID และ PPID

PID และ PPID หมายถึงรหัสกระบวนการและรหัสกระบวนการหลัก กระบวนการเริ่มต้นเมื่อเราสร้างและเริ่มคอนเทนเนอร์ด้วยคำสั่ง /bin/sh ตอนนี้ให้รันคำสั่ง docker attach busybox ซึ่งจะแนบสตรีมอินพุต/เอาต์พุต/ข้อผิดพลาดมาตรฐานของคอนเทนเนอร์เข้ากับเทอร์มินัลของคุณ

หลังจากแนบคอนเทนเนอร์แล้ว ให้สร้างเซสชันเชลล์โดยรันคำสั่ง sh กด CTRL-p CTRL-q ลำดับ การดำเนินการนี้จะแยกเทอร์มินัลออกจากคอนเทนเนอร์และจะทำให้คอนเทนเนอร์ทำงานต่อไป หากตอนนี้คุณรัน docker top busybox คุณจะเห็นสองกระบวนการในรายการ

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                7469                7451                0                   11:40               pts/0               00:00:00            /bin/sh
root                7737                7469                0                   11:43               pts/0               00:00:00            sh

แต่ PPID ของทั้งสองกระบวนการจะแตกต่างกัน อันที่จริงแล้ว PPID ของกระบวนการที่สองจะเหมือนกับ PID ของกระบวนการแรก กระบวนการแรกทำหน้าที่เป็นกระบวนการหลักสำหรับเซสชันเชลล์ที่เราเพิ่งสร้างขึ้น

ตอนนี้รัน docker exec -it busybox sh เมื่อเข้าไปในคอนเทนเนอร์แล้ว ให้ตรวจสอบรายการกระบวนการที่ทำงานอยู่สำหรับคอนเทนเนอร์ busybox ในหน้าต่างเทอร์มินัลอื่นโดยรันคำสั่ง docker top busybox คุณควรเห็นสิ่งนี้

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                7469                7451                0                   11:40               pts/0               00:00:00            /bin/sh
root                7737                7469                0                   11:43               pts/0               00:00:00            sh
root                7880                7451                0                   11:45               pts/1               00:00:00            sh

PPID ของกระบวนการที่หนึ่งและสามจะเหมือนกัน ซึ่งยืนยันว่า docker exec สร้างกระบวนการใหม่ในสภาพแวดล้อมของคอนเทนเนอร์ ในขณะที่ docker attach เพียงเชื่อมต่ออินพุต/เอาต์พุต/ข้อผิดพลาดมาตรฐานของกระบวนการหลักภายในคอนเทนเนอร์กับอินพุต/เอาต์พุตมาตรฐานที่สอดคล้องกัน ข้อผิดพลาดของเทอร์มินัลปัจจุบัน

person Kartik Chauhan    schedule 20.07.2019

Docker exec ดำเนินการคำสั่งใหม่ / สร้างกระบวนการใหม่ในสภาพแวดล้อมของคอนเทนเนอร์ในขณะที่นักเทียบท่าแนบเพียงเชื่อมต่ออินพุต / เอาท์พุต / ข้อผิดพลาดมาตรฐานของกระบวนการหลัก (ด้วย PID 1) ภายในคอนเทนเนอร์กับอินพุต / เอาท์พุต / ข้อผิดพลาดมาตรฐานที่สอดคล้องกันของกระแส เทอร์มินัล (เทอร์มินัลที่คุณใช้เพื่อรันคำสั่ง)

คอนเทนเนอร์เป็นสภาพแวดล้อมแบบแยกส่วน โดยมีกระบวนการบางอย่างทำงานอยู่ในสภาพแวดล้อม โดยเฉพาะอย่างยิ่ง คอนเทนเนอร์มีพื้นที่ระบบไฟล์และพื้นที่ PID ของตัวเองที่แยกออกจากโฮสต์และคอนเทนเนอร์อื่นๆ เมื่อคอนเทนเนอร์เริ่มต้นโดยใช้ “docker run –it …” กระบวนการหลักจะมี pseudo-tty และ STDIN เก็บไว้เปิดอยู่ เมื่อเชื่อมต่อในโหมด tty คุณสามารถแยกออกจากคอนเทนเนอร์ได้ (และปล่อยให้คอนเทนเนอร์ทำงานต่อไป) โดยใช้ลำดับคีย์ที่กำหนดค่าได้ ลำดับเริ่มต้นคือ CTRL-p CTRL-q คุณกำหนดค่าลำดับคีย์โดยใช้ตัวเลือก --detach-keys หรือไฟล์การกำหนดค่า คุณสามารถแนบกลับเข้ากับคอนเทนเนอร์ที่แยกออกมาโดยแนบนักเทียบท่าได้

Docker exec เพิ่งเริ่มกระบวนการใหม่ภายในสภาพแวดล้อมของคอนเทนเนอร์ ซึ่งก็คือเป็นของพื้นที่ PID ของคอนเทนเนอร์

ตัวอย่างเช่น หากคุณเริ่มคอนเทนเนอร์โดยใช้ "docker run –dit XXX /bin/bash" คุณสามารถแนบไปกับคอนเทนเนอร์ (กระบวนการหลักของ) โดยใช้เทอร์มินัลสองเครื่องที่แตกต่างกัน ขณะที่คุณกำลังป้อนข้อมูลในเทอร์มินัลหนึ่ง คุณจะเห็นได้ว่าปรากฏในอีกเทอร์มินัลหนึ่ง เนื่องจากทั้งสองเทอร์มินัลเชื่อมต่อกับ tty เดียวกัน โปรดใช้ความระมัดระวังว่าขณะนี้คุณอยู่ในกระบวนการหลักของคอนเทนเนอร์ หากคุณพิมพ์ "exit" คุณจะออกจากคอนเทนเนอร์ (โปรดใช้ความระมัดระวังโดยใช้กุญแจในการแยกออก) และคุณจะเห็น ออกจากเทอร์มินัลทั้งสองแล้ว แต่ถ้าคุณเรียกใช้ “docker exec –it XXX /bin/bash” ในสองเทอร์มินัล คุณได้เริ่มต้นกระบวนการใหม่สองกระบวนการภายในคอนเทนเนอร์ และกระบวนการเหล่านั้นไม่เกี่ยวข้องกันและกับกระบวนการหลัก และคุณสามารถออกจากกระบวนการเหล่านั้นได้อย่างปลอดภัย .

person Michael.Sun    schedule 06.09.2018