คอนเทนเนอร์ VPN ออกด้วย 'exec format error': แพลตฟอร์มผิด
'exec format error' หมายความว่าไบนารีถูกสร้างสำหรับ CPU อื่น ไม่ใช่ขาด NET_ADMIN อ่านดัชนีอิมเมจก่อนแก้ไขเส้นทางหรือข้อมูลรับรอง
คอนเทนเนอร์ที่ออกทันทีด้วย exec format error มักกระตุ้นสัญชาตญาณผิด: เพิ่มความสามารถ เมานต์อุปกรณ์ แก้ไขการกำหนดค่าทันเนล ไม่มีสิ่งใดในนั้นไปถึงปัญหา เคอร์เนลไม่สามารถเรียกใช้ไบนารีได้เลย ซึ่งในคอนเทนเนอร์เกือบทุกครั้งหมายความว่าอิมเมจกำหนดเป้าหมายสถาปัตยกรรม CPU ที่แตกต่างจากโฮสต์ ทุกสิ่งที่คุณอาจเปลี่ยนในการกำหนดเส้นทาง ข้อมูลรับรอง หรือสิทธิ์เกิดขึ้นหลังจากโปรแกรมเริ่มทำงาน และไม่มีโปรแกรมใดเริ่มทำงาน
ข้อความเริ่มต้นที่ดูเหมือนข้อผิดพลาดในการกำหนดค่า
ความล้มเหลวของรูปแบบ exec มาจากตัวโหลด ก่อนที่แอปพลิเคชันจะอ่านการตั้งค่าแม้แต่รายการเดียว นั่นคือเหตุผลที่มันไม่สร้างคำเตือนการกำหนดค่าหรือบันทึกทันเนล เพราะไม่มีโปรเซสที่ยังมีชีวิตอยู่เพื่อเขียนสิ่งเหล่านั้น ความล้มเหลวยังรวดเร็วอย่างน่าทึ่ง มักเกิดขึ้นก่อนที่บรรทัดใดจะปรากฏในบันทึกคอนเทนเนอร์ด้วยซ้ำ ข้อความสั้นเดียวกันนี้ปรากฏไม่ว่าไบนารีจะสำหรับสถาปัตยกรรมอื่น ระบบปฏิบัติการอื่น หรือเสียหาย
บันทึกสภาพแวดล้อมรันไทม์และสถาปัตยกรรมพร้อมกับการอ้างอิงอิมเมจที่แน่นอน จากนั้นตรวจสอบว่าการอ้างอิงนั้นเสนออะไรจริง บน Docker Desktop แพลตฟอร์มของคอนเทนเนอร์เป็นของเครื่องเสมือน Linux ไม่ใช่แล็ปท็อป ดังนั้นสถาปัตยกรรมโฮสต์เพียงอย่างเดียวอาจทำให้เข้าใจผิด อ่านรายการดัชนีของการอ้างอิงนี้ ไม่ใช่ข้อความการตลาดบนหน้าแท็กของมัน
อ่านดัชนีอิมเมจก่อนคำสั่งรัน
เมื่อรีจิสทรีเผยแพร่การอ้างอิงหลายแพลตฟอร์ม แท็กชี้ไปที่ดัชนี และแต่ละรายการระบุชื่อแพลตฟอร์มพร้อมไดเจสต์ของตัวเอง ตรวจสอบการอ้างอิงที่อยู่ระหว่างการพิจารณา ไม่ใช่แท็กข้างเคียง และอ่านดัชนีแทนการสันนิษฐานว่ามีอะไรอยู่ข้างใน
docker buildx imagetools inspect ghcr.io/example/vpn:1.4
docker image inspect --format '{{.Os}}/{{.Architecture}}' ghcr.io/example/vpn:1.4
คำสั่งแรกแสดงรายการแพลตฟอร์มที่การอ้างอิงเผยแพร่ คำสั่งที่สองรายงานแพลตฟอร์มของอิมเมจที่มีอยู่ในเครื่องแล้ว และนั่นคือสิ่งที่รันไทม์จะเรียกใช้ การอ้างอิงที่มีรายการเดียวหมายความว่าทุกโฮสต์ได้รับไบนารีเดียวกัน และแท็กไม่สามารถช่วยเครื่องที่มันไม่เคยถูกสร้างขึ้นมาได้
แท็กเลือกตัวแปร ไม่ได้สร้างตัวแปร
ดัชนีหลายแพลตฟอร์มช่วยให้รันไทม์เลือกแถวที่ตรงกัน ซึ่งสะดวกจริงและมักถูกเข้าใจผิดว่าเป็นความสามารถในการพอร์ต การเลือกคือการค้นหา ไม่ใช่การแปล หากไม่มีตัวแปร ก็ไม่มีอะไรให้เลือก ดังนั้นแท็กเดียวกันบนสองโฮสต์อาจแก้เป็นไบนารีที่ต่างกันสองตัว และบนโฮสต์หนึ่งก็ไม่แก้อะไรที่ใช้งานได้
การปักหมุดด้วยไดเจสต์ขจัดความกำกวมและยังทำให้การตรวจทานภายหลังเป็นไปได้ เพราะไดเจสต์ระบุไบต์ที่ถูกทดสอบอย่างแม่นยำ เก็บไดเจสต์นั้นไว้กับบันทึกการติดตั้งใช้งาน แทนที่จะพึ่งพาแท็กที่บังเอิญเป็นปัจจุบัน
การจำลองเป็นข้อตกลง ไม่ใช่ชั้นการแปล
การจำลองผ่านรันไทม์ที่รองรับสามารถรันเวิร์กโหลดผู้ใช้ที่ไม่ใช่เนทีฟบางส่วนได้ ดังนั้นข้อกล่าวหาเด็ดขาดว่าสถาปัตยกรรมหนึ่งไม่สามารถรันอิมเมจของอีกอันได้เลยนั้นผิด มันไม่ใช่ทางแก้ทั่วไปเช่นกัน การทำงานแบบจำลองมีลักษณะประสิทธิภาพที่ต่างออกไป และโปรเซสเล็ก ๆ ที่เริ่มทำงานไม่ได้บอกอะไรเกี่ยวกับว่าเวิร์กโหลดทันเนลทำงานอย่างยอมรับได้หรือไม่
คู่มือหลายแพลตฟอร์มของ Docker ถือว่าการสร้างแบบเนทีฟ การคอมไพล์ข้าม และการจำลองเป็นกลยุทธ์แยกกัน และนั่นคือวิธีที่ถูกต้องในการอ่านตัวเลือก เลือกหนึ่งอย่างโดยเจตนา และประเมินเวิร์กโหลด VPN ภายใต้นั้น แทนที่จะสันนิษฐานความเท่าเทียม
สิทธิ์แก้ปัญหาที่แตกต่างออกไป
การให้ความสามารถในการบริหารเครือข่ายหรือส่งผ่านอุปกรณ์ TUN ไม่สามารถทำให้ไฟล์ปฏิบัติการที่เข้ากันไม่ได้ทำงานได้ สิ่งเหล่านี้คือสิทธิ์รันไทม์ที่โปรเซสที่กำลังทำงานใช้อยู่ พวกมันมองไม่เห็นสำหรับตัวโหลดที่ปฏิเสธไฟล์ไปแล้ว
สิ่งที่ตรงกันข้ามก็เป็นจริงเช่นกัน ไบนารีเนทีฟไม่ได้พิสูจน์อะไรเกี่ยวกับสิทธิพิเศษ การเข้าถึงอุปกรณ์ การรวมตัวแก้ชื่อ หรือนโยบายรีสตาร์ตที่ทันเนลต้องการ ดังนั้น คอนเทนเนอร์ที่เริ่มทำงานยังไม่ใช่คอนเทนเนอร์ที่ทำงานได้ กำหนดสัญญาแพลตฟอร์มก่อน แล้วจึงไปยังสัญญารันไทม์พร้อมตัวเลือกที่มีเอกสารกำกับ
เก็บไดเจสต์อิมเมจ เป้าหมายที่รองรับ และการกำหนดค่าไว้ด้วยกันในบันทึกเดียวกัน การอัปเดตแท็กที่เปลี่ยนสถาปัตยกรรมอย่างเงียบ ๆ จับได้ง่ายกว่าเมื่อไดเจสต์ก่อนหน้าถูกบันทึกไว้ มากกว่าเมื่ออาการเดียวคือข้อผิดพลาดที่คุ้นเคยและบ่ายใหม่ที่ใช้ในการดีบัก