สร้าง Pod แต่เจอว่า exec format error

เรื่องของเรื่องก็มีอยู่ว่า … ผมมี Container Image เก็บอยู่บน Docker Hub ส่วนใหญ่ก็จะเป็นเครื่องมือในการทำโน่นนี่นั่น เช่น curl, dig, ansible หรือจำพวก application ที่เอาไว้ทดสอบในกรณีต่าง ๆ … ตัวที่มีอายุมากที่สุด ก็น่าจะประมาณ 3 ปีที่เริ่มสร้าง image เองมาทดสอบ มันก็เป็นอย่างนั้นมาตลอด ไม่เคยมีปัญหาอะไร แต่ว่า 2-3 วันนี้ก็นึกว่า จะเอาเครื่องมือหลาย ๆ ตัวมาร่วมกันไว้ใน image เดียว เวลาเรียกใช้งาน ทดสอบบางอย่างเล็ก ๆ น้อย ๆ ก็ใช้ตัวนี้ตัวเดียวพอ ก็เลยเริ่มจากเอา curl, ip, bash และ dig รวมกันไว้เป็นตัวเดียวโดยใช้ Base Image เป็น Alpine

author image
drs

Technology evangelistic advocacy

Posted on 2023-03-25 08:14:30 +0700

เรื่องของเรื่องก็มีอยู่ว่า … ผมมี Container Image เก็บอยู่บน Docker Hub ส่วนใหญ่ก็จะเป็นเครื่องมือในการทำโน่นนี่นั่น เช่น curl, dig, ansible หรือจำพวก application ที่เอาไว้ทดสอบในกรณีต่าง ๆ … ตัวที่มีอายุมากที่สุด ก็น่าจะประมาณ 3 ปีที่เริ่มสร้าง image เองมาทดสอบ มันก็เป็นอย่างนั้นมาตลอด ไม่เคยมีปัญหาอะไร แต่ว่า 2-3 วันนี้ก็นึกว่า จะเอาเครื่องมือหลาย ๆ ตัวมาร่วมกันไว้ใน image เดียว เวลาเรียกใช้งาน ทดสอบบางอย่างเล็ก ๆ น้อย ๆ ก็ใช้ตัวนี้ตัวเดียวพอ ก็เลยเริ่มจากเอา curl, ip, bash และ dig รวมกันไว้เป็นตัวเดียวโดยใช้ Base Image เป็น Alpine

FROM alpine

RUN apk add --update --no-cache curl iputils bash bind-tools

เริ่ม Build Container Image

ก็ปกติเลยครับ ใช้ Docker Desktop ที่ติดตั้งบน laptop ตัวเอง เรียกคำสั่ง docker build เหมือนเดิมอย่างที่เคยทำ ตัวนี้ก็เลยตั้งชื่อ image ว่า utils และ tag เป็น r23.03 แล้วก็ push มันไปเก็บไว้บน Repository ของผมบน Docker Hub

d8k-a2m2 util  > docker build -t damrongsak/utils:r23.03 --no-cache .
[+] Building 4.1s (6/6) FINISHED
 => [internal] load build definition from Dockerfile                       0.0s
 => => transferring dockerfile: 122B                                       0.0s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 2B                                            0.0s
 => [internal] load metadata for docker.io/library/alpine:latest           1.1s
 => CACHED [1/2] FROM docker.io/library/alpine@sha256:ff6bdca1701f3a8a67e  0.0s
 => [2/2] RUN apk add --update --no-cache curl iputils bash bind-tools     2.9s
 => exporting to image                                                     0.1s
 => => exporting layers                                                    0.1s
 => => writing image sha256:fe062658040d7049a108524ff891d3ee7ad4971d7d00a  0.0s
 => => naming to docker.io/damrongsak/utils:r23.0

 d8k-a2m2 util  > docker push damrongsak/utils:r23.03
The push refers to repository [docker.io/damrongsak/utils]
a8f481f3c96c: Pushed
edf70074bd40: Layer already exists
r23.03: digest: sha256:d24a5d581fb91db2e4b5f1c51f16dd263fa78024a4b542e272d86f8602062dbc size: 738

ทดสอบสร้าง container จาก image

ก่อนเอาไปใช้งานก็ทดสอบกันก่อนว่าใช้งานได้ตามปกติ ก็ใช้คำสั่ง docker container run ลองเรียกคำใช้คำสั่ง curl และ dig ใน container ก็ใช้งานได้ปกติดี ได้ผลอย่างที่คาดไว้

d8k-a2m2 util  > docker container run --rm damrongsak/utils:r23.03 curl -sI https://blog.d8k.io
HTTP/1.1 200 OK
Server: nginx/1.23.3
Date: Sat, 25 Mar 2023 02:57:13 GMT
Content-Type: text/html
Content-Length: 10822
Last-Modified: Thu, 29 Dec 2022 16:20:07 GMT
Connection: keep-alive
ETag: "63adbe37-2a46"
Accept-Ranges: bytes

d8k-a2m2 util  > docker container run --rm damrongsak/utils:r23.03 dig blog.d8k.io +short
167.172.72.37

เอาไปใช้งานจริง … ใช้ไม่ได้ ???

ผมก็เริ่มเอา image damrongsak/utils:r23.03 ไปทดสอบใน Kubernetes Cluster ที่ผมสร้างไว้ที่ Digital Ocean โดยมี Kubernetes Cluster ของผม ใช้ VM เป็น Ubuntu 22.04 LTS ติดตั้ง Kubernetes v1.26.3 ด้วย kubeadm

สิ่งที่เกิดขึ้นคือ ผมสร้าง Pod จาก image damrongsak/utils:r23.03 ด้วยคำสั่ง kubectl run ไม่ได้ มีสถานะออกมาว่า CrashLoopBackOff … ไปตามหา events ที่เกิดขึ้นกับ Pods ก็ดูเหมือนไม่เห็นอะไรผิดปกติ ก็เห็นแต่ว่ามีการ Back-off restarting เพราะว่า container ใน pod มัน fail

เกิดอะไรขึ้น !!!

ไปตามดู log ใน container ใน Pod ก็เห็นว่า exec /usr/bin/dig: exec format error

d8k-a2m2 ~  > kubectl get nodes
NAME      STATUS   ROLES           AGE     VERSION
cp0       Ready    control-plane   2m47s   v1.26.3
node0-0   Ready    <none>          2m17s   v1.26.3
node0-1   Ready    <none>          2m17s   v1.26.3

d8k-a2m2 ~  > kubectl run mypod --image damrongsak/utils:r23.03 -- dig blog.d8k.io +short
pod/mypod created
d8k-a2m2 ~  > kubectl get pods
NAME    READY   STATUS             RESTARTS     AGE
mypod   0/1     CrashLoopBackOff   1 (7s ago)   16s

d8k-a2m2 ~  > kubectl events --for pod/mypod
LAST SEEN              TYPE      REASON      OBJECT      MESSAGE
3m31s                  Normal    Scheduled   Pod/mypod   Successfully assigned default/mypod to node0-0
3m30s                  Normal    Pulling     Pod/mypod   Pulling image "damrongsak/utils:r23.03"
3m23s                  Normal    Pulled      Pod/mypod   Successfully pulled image "damrongsak/utils:r23.03" in 7.047334533s (7.047346457s including waiting)
117s (x5 over 3m23s)   Normal    Created     Pod/mypod   Created container mypod
117s (x5 over 3m23s)   Normal    Started     Pod/mypod   Started container mypod
117s (x4 over 3m22s)   Normal    Pulled      Pod/mypod   Container image "damrongsak/utils:r23.03" already present on machine
116s (x9 over 3m21s)   Warning   BackOff     Pod/mypod   Back-off restarting failed container mypod in pod mypod_default(d303f666-7d7a-418a-9eb0-c1aacee8efd4)


d8k-a2m2 ~  > kubectl logs mypod
exec /usr/bin/dig: exec format error

งง !!! อยู่หลายชั่วโมง

จาก error ที่ออกพบ แต่ว่าตอนที่ทดสอบในเครื่อง laptop ตัวเองสามารถใช้งานได้ปกติ ผมก็พุ่งเป้าไปที่ความผิดพลาดของผมเองที่น่าจะทำอะไรอย่างผิดแน่นอน

  • ใน Dockerfile มีอะไรผิดไหม
  • Base Image ที่เลือกใช้มีอะไรหรือป่าว
  • Instruction ที่ผมติดตั้ง package เพิ่ม ผมทำอะไรผิดไปไหน
  • package ที่ผมติดตั้ง ผิดตัวหรือไม่
  • ตอนที่ build ทำอะไรผิดไปป่าว
  • ตอนที่ push ไปเกิดการเปลี่ยนแปลงอะไรหรือไม่
  • Kubernetes ที่ใช้ทดสอบ มันผิดปกติอะไรหรือไม่

ผมใช้เวลาหลายชั่วโมง ทดสอบสมมุติฐานตามที่ตำแหน่งต่าง ๆ ที่คาดว่าน่าจะเกิดข้อผิดพลาดเกิดอะไรเกิดขึ้น exec /usr/bin/dig: exec format error … รูปนี้น่าจะแทนอารมณ์ผมได้ดี งงเป็นไก่ตาแตก มันเกิดอะไรขึ้นกับกรณีนี้

image

ผมมักจะมีความเชื่อว่า ผมไม่น่าจะเจอปัญหาคนเดียวในโลกนี้ และไม่น่าจะเป็นคนแรกที่เจอปัญหานี้ … มันต้องมีคนเคยเจอสิ ??? … อาจาย์ Google ช่วยได้ ค่อย ๆ นั่งนิ่ง ๆ พุ่งเป้ามาที่ keyword “exec format error” แทนที่จะคิดไปที่อื่น

อ๋อ … CPU Architecture นี้เอง

สิ่งที่ผมเปลี่ยนไปในรอบ 3 ปี ก็คือเปลี่ยน laptop ใหม่ที่เปลี่ยนมาใช้ Apple Silicon ทำให้เวลา build Container Image มันไปเลือก Base Image ตาม CPU ของเครื่องที่ผมใช้งานอยู่

image

ผมก็แค่ระบุ CPU Architecture ไปตอน build ว่าเป็น --platform linux/amd64 ก็เรียบร้อย

d8k-a2m2 util  > docker build -t damrongsak/utils --platform linux/amd64 --no-cache .
[+] Building 4.3s (6/6) FINISHED
 => [internal] load build definition from Dockerfile                                                0.0s
 => => transferring dockerfile: 122B                                                                0.0s
 => [internal] load .dockerignore                                                                   0.0s
 => => transferring context: 2B                                                                     0.0s
 => [internal] load metadata for docker.io/library/alpine:latest                                    1.0s
 => CACHED [1/2] FROM docker.io/library/alpine@sha256:ff6bdca1701f3a8a67e328815ff2346b0e4067d32ec3  0.0s
 => [2/2] RUN apk add --update --no-cache curl iputils bash bind-tools                              3.1s
 => exporting to image                                                                              0.1s
 => => exporting layers                                                                             0.0s
 => => writing image sha256:4d32ef67158b037b0a1f8925cc30d74eed5f1d4f1b064ad357e11fde9fca433d        0.0s
 => => naming to docker.io/damrongsak/utils     

d8k-a2m2 util  > docker image inspect damrongsak/utils:r23.03 | grep Architecture
        "Architecture": "arm64",

d8k-a2m2 util  > docker image inspect damrongsak/utils | grep Architecture
        "Architecture": "amd64",

Made by มูลค่าความสุข

Share on

Tags

Human knowledge belongs to the world

a line from the movie "Antitrust"