สารบัญ
CMD
s6-overlay เป็นชุดสคริปต์และยูทิลิตี้ที่ติดตั้งง่าย (เพียงแยก tarball หนึ่งหรือสองอัน!) ซึ่งช่วยให้คุณสามารถใช้อิมเมจ Docker ที่มีอยู่ในขณะที่ใช้ s6 เป็น pid 1 สำหรับคอนเทนเนอร์ของคุณและหัวหน้ากระบวนการสำหรับบริการของคุณ
สร้าง Dockerfile ต่อไปนี้แล้วลองใช้งาน:
# Use your favorite image
FROM ubuntu
ARG S6_OVERLAY_VERSION=3.2.0.2
RUN apt-get update && apt-get install -y nginx xz-utils
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
CMD ["/usr/sbin/nginx"]
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz /tmp
RUN tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-x86_64.tar.xz /tmp
RUN tar -C / -Jxpf /tmp/s6-overlay-x86_64.tar.xz
ENTRYPOINT ["/init"]
docker-host $ docker build -t demo .
docker-host $ docker run --name s6demo -d -p 80:80 demo
docker-host $ docker top s6demo acxf
PID TTY STAT TIME COMMAND
11735 ? Ss 0:00 _ s6-svscan
11772 ? S 0:00 _ s6-supervise
11773 ? Ss 0:00 | _ s6-linux-init-s
11771 ? Ss 0:00 _ rc.init
11812 ? S 0:00 | _ nginx
11814 ? S 0:00 | _ nginx
11816 ? S 0:00 | _ nginx
11813 ? S 0:00 | _ nginx
11815 ? S 0:00 | _ nginx
11779 ? S 0:00 _ s6-supervise
11785 ? Ss 0:00 | _ s6-ipcserverd
11778 ? S 0:00 _ s6-supervise
docker-host $ curl --head http://127.0.0.1/
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Mon, 17 Jan 2022 13:33:58 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Mon, 17 Jan 2022 13:32:11 GMT
Connection: keep-alive
ETag: "61e56fdb-264"
Accept-Ranges: bytes
หากคุณกำลังย้ายจาก s6-overlay ( v2 ) เวอร์ชันก่อนหน้าไปเป็นเวอร์ชันใหม่ ( v3 ) คุณอาจจำเป็นต้องทำการเปลี่ยนแปลงบริการของคุณหรือวิธีที่คุณใช้ s6-overlay เพื่อให้ทุกอย่างทำงานได้อย่างราบรื่น เอกสารนี้พยายามให้ความแม่นยำเกี่ยวกับวิธีการทำงานของ v3 แต่เรามีหน้าแยกต่างหากที่แสดงรายการความแตกต่างหลักๆ และสิ่งที่คุณน่าจะสังเกตเห็น โปรดอ่าน หากคุณตกอยู่ในสถานการณ์เช่นนี้!
โครงการมีเป้าหมายดังต่อไปนี้:
cont-init.d
), การสรุป ( cont-finish.d
) และบริการของตนเองโดยมีการพึ่งพาระหว่างกันPID 1
ที่เหมาะสมs6
และ s6-portable-utils
รวมถึงยูทิลิตี้ที่มีประโยชน์และประกอบได้ซึ่งทำให้ชีวิตของเราง่ายขึ้นมากlogutil-service
ซึ่งใช้ s6-log
ภายใต้ประทุนUSER
ของ Docker เพื่อเรียกใช้แผนผังกระบวนการทั้งหมดของคุณในฐานะผู้ใช้เฉพาะ ไม่สามารถใช้ได้กับคุณสมบัติทั้งหมด รายละเอียดในส่วนหมายเหตุ หนึ่งในมนต์ของ Docker ที่พบบ่อยคือ "หนึ่งกระบวนการต่อคอนเทนเนอร์" แต่เราไม่เห็นด้วย ไม่มีอะไร เลวร้าย โดยเนื้อแท้เกี่ยวกับการรันหลายกระบวนการในคอนเทนเนอร์ " สิ่ง หนึ่งต่อคอนเทนเนอร์" ที่เป็นนามธรรมมากกว่าคือนโยบายของเรา - คอนเทนเนอร์ควรทำสิ่งหนึ่ง เช่น "เรียกใช้บริการแชท" หรือ "เรียกใช้ gitlab" ซึ่งอาจเกี่ยวข้องกับหลายกระบวนการ ซึ่งเป็นเรื่องปกติ
อีกเหตุผลหนึ่งที่ผู้สร้างอิมเมจหลีกเลี่ยงหัวหน้างานกระบวนการก็คือ พวกเขาเชื่อว่าหัวหน้างานกระบวนการ ต้อง รีสตาร์ทบริการที่ล้มเหลว ซึ่งหมายความว่าคอนเทนเนอร์ Docker จะไม่มีวันตาย
สิ่งนี้ทำลายระบบนิเวศของ Docker ได้อย่างมีประสิทธิภาพ - อิมเมจส่วนใหญ่เรียกใช้กระบวนการเดียวที่จะออกเมื่อมีข้อผิดพลาด เมื่อออกจากข้อผิดพลาด ถือว่าคุณอนุญาตให้ผู้ดูแลระบบจัดการกับความล้มเหลวได้ตามต้องการ หากรูปภาพของคุณไม่มีทางออก ตอนนี้คุณต้องมีวิธีอื่นในการกู้คืนข้อผิดพลาดและการแจ้งเตือนความล้มเหลว
นโยบายของเราคือถ้า "สิ่งนั้น" ล้มเหลว คอนเทนเนอร์ก็ควรจะล้มเหลวเช่นกัน เราทำสิ่งนี้โดยพิจารณาว่ากระบวนการใดสามารถรีสตาร์ทได้ และกระบวนการใดควรทำให้คอนเทนเนอร์หยุดทำงาน ตัวอย่างเช่น หาก cron
หรือ syslog
ล้มเหลว คอนเทนเนอร์ของคุณสามารถรีสตาร์ทได้โดยไม่มีผลกระทบใดๆ แต่หาก ejabberd
ล้มเหลว คอนเทนเนอร์ควรออกเพื่อให้ผู้ดูแลระบบสามารถดำเนินการได้
การตีความ "The Docker Way" ของเราคือ:
และระบบเริ่มต้นของเราได้รับการออกแบบมาให้ทำอย่างนั้น รูปภาพของคุณจะทำงานเหมือนกับรูปภาพ Docker อื่นๆ และสอดคล้องกับระบบนิเวศของรูปภาพที่มีอยู่
ดู "การเขียนสคริปต์ปิดท้ายทางเลือก" ใต้ส่วนการใช้งาน เพื่อดูรายละเอียดเกี่ยวกับการหยุด "สิ่งนั้น"
Init แบบซ้อนทับของเราได้รับการปรับแต่งอย่างเหมาะสมเพื่อให้ทำงานอย่างเหมาะสมในสภาพแวดล้อมแบบคอนเทนเนอร์ ในส่วนนี้อธิบายสั้น ๆ ว่าขั้นตอนทำงานอย่างไร แต่ถ้าคุณต้องการทราบว่าระบบ init ที่สมบูรณ์ควรทำงานอย่างไร คุณสามารถอ่านบทความนี้: วิธีเรียกใช้ s6-svscan เป็นกระบวนการที่ 1
/etc/cont-init.d
/etc/s6-overlay/s6-rc.d
ตามการอ้างอิง/etc/services.d
) ไปยังไดเร็กทอรีชั่วคราวและให้ s6 เริ่มต้น (และดูแล) บริการเหล่านั้น/etc/cont-finish.d
TERM
ให้กับกระบวนการที่เหลือทั้งหมด ไม่ควรมีกระบวนการเหลืออยู่เลยKILL
ให้กับกระบวนการทั้งหมด จากนั้นคอนเทนเนอร์ก็ออก s6-overlay มาเป็นชุดของ tarball ที่คุณสามารถแยกออกมาบนภาพของคุณได้ tarball ที่คุณต้องการคือฟังก์ชันของรูปภาพที่คุณใช้ คนส่วนใหญ่จะต้องมีสองรายการแรก และอีกสองรายการเป็นส่วนเสริมที่คุณสามารถใช้ได้ตามสะดวก
s6-overlay-noarch.tar.xz
: tarball นี้มีสคริปต์ที่ใช้งานการซ้อนทับ เราเรียกมันว่า "noarch" เนื่องจากไม่ขึ้นอยู่กับสถาปัตยกรรม โดยมีเพียงสคริปต์และไฟล์ข้อความอื่นๆ เท่านั้น ทุกคนที่ต้องการรัน s6-overlay จำเป็นต้องแยก tarball นี้s6-overlay-x86_64.tar.xz
: แทนที่ x86_64
ด้วยสถาปัตยกรรมระบบของคุณ tarball นี้มีไบนารีที่จำเป็นทั้งหมดจากระบบนิเวศ s6 ซึ่งทั้งหมดเชื่อมโยงแบบคงที่และไม่ขวางทางไบนารีของรูปภาพของคุณ เว้นแต่คุณจะรู้แน่ชัดว่ารูปภาพของคุณมาพร้อมกับแพ็คเกจทั้งหมดที่มีไบนารี่ที่ใช้ในการโอเวอร์เลย์อยู่แล้ว คุณจะต้องแยกทาร์บอลนี้ออกs6-overlay-symlinks-noarch.tar.xz
: tarball นี้มี symlink ไปยังสคริปต์ s6-overlay ดังนั้นจึงสามารถเข้าถึงได้ผ่าน /usr/bin
โดยปกติแล้วไม่จำเป็น สคริปต์ทั้งหมดสามารถเข้าถึงได้ผ่านตัวแปรสภาพแวดล้อม PATH แต่หากคุณมีสคริปต์ผู้ใช้เก่าที่มี shebang เช่น #!/usr/bin/with-contenv
การติดตั้ง symlink เหล่านี้จะทำให้สคริปต์ทำงานได้s6-overlay-symlinks-arch.tar.xz
: tarball นี้มี symlink ไปยังไบนารีจากระบบนิเวศ s6 ที่ได้รับจาก tarball ที่สอง เพื่อให้สามารถเข้าถึงได้ผ่าน /usr/bin
โดยปกติแล้วไม่จำเป็น แต่หากคุณมีสคริปต์ผู้ใช้เก่าที่มี shebang เช่น #!/usr/bin/execlineb
การติดตั้ง symlink เหล่านี้จะทำให้สคริปต์ทำงานได้syslogd-overlay-noarch.tar.xz
: tarball นี้มีคำจำกัดความสำหรับบริการ syslogd
หากคุณกำลังเรียกใช้ daemons ที่ไม่สามารถเข้าสู่ระบบ stderr เพื่อใช้ประโยชน์จากโครงสร้างพื้นฐานการบันทึก s6 แต่ฮาร์ดโค้ดโดยใช้กลไก syslog()
เก่า คุณสามารถแยก tarball นี้ออกได้ และคอนเทนเนอร์ของคุณจะเรียกใช้การจำลองแบบ light ของ syslogd
daemon ดังนั้นบันทึก syslog ของคุณจะถูกจับและจัดเก็บไว้ในดิสก์หากต้องการติดตั้ง tarball เหล่านั้น ให้เพิ่มบรรทัดใน Dockerfile ของคุณที่สอดคล้องกับฟังก์ชันที่คุณต้องการติดตั้ง ตัวอย่างเช่น คนส่วนใหญ่จะใช้สิ่งต่อไปนี้:
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz /tmp
RUN tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-x86_64.tar.xz /tmp
RUN tar -C / -Jxpf /tmp/s6-overlay-x86_64.tar.xz
ตรวจสอบให้แน่ใจว่าได้รักษาสิทธิ์ของไฟล์ไว้เมื่อแตกไฟล์ (เช่น ใช้ตัวเลือก -p
เพื่อ tar
)
โปรเจ็กต์นี้แจกจ่ายเป็นชุดของไฟล์ .tar.xz มาตรฐาน ซึ่งคุณแยกออกมาที่รากของรูปภาพ (คุณต้องมีแพ็คเกจ xz-utils เพื่อให้ tar
เข้าใจไฟล์ .tar.xz
ซึ่งมีอยู่ในทุกการแจกจ่าย แต่ไม่เสมอไปในอิมเมจคอนเทนเนอร์เริ่มต้น ดังนั้นคุณอาจต้อง apt install xz-utils
หรือ apk add xz
หรือ เทียบเท่ากันก่อนที่คุณจะสามารถขยายไฟล์เก็บถาวรได้)
หลังจากนั้นให้ตั้ง ENTRYPOINT
ของคุณเป็น /init
ตอนนี้ เราขอแนะนำให้ใช้คำ ADD
ของ Docker แทนการรัน wget
หรือ curl
ในคำสั่ง RUN
- Docker สามารถจัดการ https URL ได้เมื่อคุณใช้ ADD
ในขณะที่อิมเมจฐานของคุณอาจใช้ https ไม่ได้ หรืออาจไม่มีด้วยซ้ำ ติดตั้ง wget
หรือ curl
เลย
จากนั้น คุณมีทางเลือก 2-3 ทาง:
CMD
ของรูปภาพCMD
การใช้ CMD
เป็นวิธีที่สะดวกในการใช้ประโยชน์จากการซ้อนทับ คุณสามารถกำหนด CMD
ของคุณ ณ เวลาบิลด์ใน Dockerfile หรือ ณ รันไทม์บนบรรทัดคำสั่ง ก็ได้ไม่ว่าจะด้วยวิธีใด มันจะถูกรันเป็นกระบวนการปกติในสภาพแวดล้อมที่ตั้งค่าโดย s6; เมื่อล้มเหลวหรือออก คอนเทนเนอร์จะปิดลงอย่างเรียบร้อยและออก คุณสามารถรันโปรแกรมแบบโต้ตอบได้ในลักษณะนี้: มีเพียง CMD เท่านั้นที่จะได้รับคำสั่งแบบโต้ตอบของคุณ กระบวนการสนับสนุนจะไม่ได้รับผลกระทบ
ตัวอย่างเช่น:
FROM busybox
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz /tmp
RUN tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-x86_64.tar.xz /tmp
RUN tar -C / -Jxpf /tmp/s6-overlay-x86_64.tar.xz
ENTRYPOINT ["/init"]
docker-host $ docker build -t s6demo .
docker-host $ docker run -ti s6demo /bin/sh
/package/admin/s6-overlay/libexec/preinit: notice: /var/run is not a symlink to /run, fixing it
s6-rc: info: service s6rc-oneshot-runner: starting
s6-rc: info: service s6rc-oneshot-runner successfully started
s6-rc: info: service fix-attrs: starting
s6-rc: info: service fix-attrs successfully started
s6-rc: info: service legacy-cont-init: starting
s6-rc: info: service legacy-cont-init successfully started
s6-rc: info: service legacy-services: starting
s6-rc: info: service legacy-services successfully started
/ # ps
PID USER TIME COMMAND
1 root 0:00 /package/admin/s6/command/s6-svscan -d4 -- /run/service
17 root 0:00 {rc.init} /bin/sh -e /run/s6/basedir/scripts/rc.init top /bin/sh
18 root 0:00 s6-supervise s6-linux-init-shutdownd
20 root 0:00 /package/admin/s6-linux-init/command/s6-linux-init-shutdownd -c /run/s6/basedir -g 3000 -C -B
24 root 0:00 s6-supervise s6rc-fdholder
25 root 0:00 s6-supervise s6rc-oneshot-runner
31 root 0:00 /package/admin/s6/command/s6-ipcserverd -1 -- /package/admin/s6/command/s6-ipcserver-access -v0 -E -l0 -i data/rules -- /packa
58 root 0:00 /bin/sh
66 root 0:00 ps
/ # exit
s6-rc: info: service legacy-services: stopping
s6-rc: info: service legacy-services successfully stopped
s6-rc: info: service legacy-cont-init: stopping
s6-rc: info: service legacy-cont-init successfully stopped
s6-rc: info: service fix-attrs: stopping
s6-rc: info: service fix-attrs successfully stopped
s6-rc: info: service s6rc-oneshot-runner: stopping
s6-rc: info: service s6rc-oneshot-runner successfully stopped
docker-host $
อีกวิธีหนึ่งในการใช้คอนเทนเนอร์ที่มีการซ้อนทับ s6 คือการให้บริการของคุณภายใต้การดูแล คุณสามารถดูแลบริการจำนวนเท่าใดก็ได้ โดยปกติแล้วจะเป็นเพียงบริการสนับสนุนสำหรับ daemon หลักที่คุณเรียกใช้ในฐานะ CMD แต่ถ้านั่นคือสิ่งที่คุณต้องการ ไม่มีอะไรขัดขวางไม่ให้คุณมี CMD ว่างเปล่าและเรียกใช้ daemon หลักของคุณในฐานะบริการภายใต้การดูแลเช่นกัน ในกรณีนั้น daemon จะถูกรีสตาร์ทโดย s6 ทุกครั้งที่ออก คอนเทนเนอร์จะหยุดเฉพาะเมื่อคุณบอกให้ทำเช่นนั้น ไม่ว่าจะผ่านคำสั่ง docker stop
หรือจากภายในคอนเทนเนอร์ด้วยคำสั่ง /run/s6/basedir/bin/halt
มีสองวิธีในการให้บริการภายใต้การดูแล วิธีเก่าซึ่งยังคงได้รับการสนับสนุนคือการสร้างไดเรกทอรีบริการ "pure s6" สร้างไดเร็กทอรีด้วยชื่อบริการของคุณใน /etc/services.d
และใส่ไฟล์ run
ลงไป นี่คือไฟล์ที่คุณจะใช้การดำเนินการตามกระบวนการที่ยาวนาน สำหรับรายละเอียดการควบคุมดูแลไดเร็กทอรีบริการ และวิธีกำหนดค่าวิธีที่ s6 จัดการกับ daemon ของคุณ โปรดดูที่เอกสารประกอบของ servicedir ตัวอย่างง่ายๆ จะมีลักษณะดังนี้:
/etc/services.d/myapp/run
:
#!/command/execlineb -P
nginx -g "daemon off;"
วิธีใหม่คือการสร้าง ไดเร็กทอรีคำจำกัดความแหล่งที่มา s6-rc ในไดเร็กทอรี /etc/s6-overlay/s6-rc.d
และเพิ่มชื่อของไดเร็กทอรีนั้นไปยังบันเดิล user
กล่าวคือ สร้างไฟล์ว่างที่มีชื่อเดียวกัน ในไดเร็กทอรี /etc/s6-overlay/s6-rc.d/user/contents.d
รูปแบบของ ไดเร็กทอรีคำจำกัดความของแหล่งที่ มามีอธิบายไว้ในหน้านี้ โปรดทราบว่าคุณสามารถกำหนด longruns ได้ เช่น daemons ที่จะดูแลโดย s6 เช่นเดียวกับเมธอด /etc/services.d
แต่ยังรวมถึง oneshots ด้วย เช่น โปรแกรมที่จะรันครั้งเดียวและออก บริการหลักของคุณน่าจะเป็นบริการ ระยะยาว ไม่ใช่แบบ oneshot : คุณอาจต้องมี daemon เพื่อคงอยู่
ข้อดีของรูปแบบใหม่นี้คือช่วยให้คุณสามารถกำหนดการขึ้นต่อกันระหว่างบริการต่างๆ ได้ หาก B ขึ้นอยู่กับ A แล้ว A จะเริ่มทำงานก่อน จากนั้น B จะเริ่มเมื่อ A พร้อม และเมื่อคอนเทนเนอร์ถูกบอกให้ออก B จะหยุด ก่อนแล้วจึง A หากคุณมีสถาปัตยกรรมที่ซับซ้อนซึ่งกระบวนการต่างๆ ต้องพึ่งพาอาศัยกัน หรือเพียงแค่ที่คุณต้องผสม oneshots และ longruns ตามลำดับที่แม่นยำ สิ่งนี้อาจเหมาะกับคุณ
ตัวอย่างข้างต้นสามารถเขียนใหม่ได้ด้วยวิธีนี้:
/etc/s6-overlay/s6-rc.d/myapp/type
:
longrun
/etc/s6-overlay/s6-rc.d/myapp/run
:
#!/command/execlineb -P
nginx -g "daemon off;"
/etc/s6-overlay/s6-rc.d/user/contents.d/myapp
: ไฟล์ว่างเปล่า (ซึ่งจะเพิ่ม myapp
ให้กับชุดบริการที่ s6-rc จะเริ่มต้นเมื่อบูตคอนเทนเนอร์)
/etc/s6-overlay/s6-rc.d/myapp/dependencies.d/base
: ไฟล์ว่างเปล่า (คำสั่งนี้จะบอก s6-rc ให้เริ่ม myapp
เมื่อบริการพื้นฐานทั้งหมดพร้อมเท่านั้น: ซึ่งจะป้องกันสภาพการแข่งขัน)
เราขอแนะนำให้คุณเปลี่ยนไปใช้รูปแบบใหม่ แต่หากคุณไม่ต้องการประโยชน์จากรูปแบบนี้ คุณสามารถใช้ไดเร็กทอรีบริการทั่วไปใน /etc/services.d
ต่อไปได้ มันก็จะใช้งานได้เช่นกัน
หากคุณเรียกใช้บริการหลักในฐานะ CMD คุณไม่ต้องทำอะไรเลย: เมื่อ CMD ของคุณออก หรือเมื่อคุณเรียกใช้ docker stop
คอนเทนเนอร์จะออกโดยธรรมชาติด้วยรหัสออกเดียวกันกับบริการของคุณ (อย่างไรก็ตาม โปรดทราบว่าในกรณี docker stop
บริการของคุณจะได้รับ SIGTERM ซึ่งในกรณีนี้รหัสทางออกจะขึ้นอยู่กับวิธีที่บริการของคุณจัดการมัน - มันสามารถดักจับมันและออก 0, ดักมันและออกจากอย่างอื่น หรือไม่ดักจับมันแล้วปล่อยให้เชลล์ออกจากโค้ดของมันเอง - ปกติคือ 130)
หากคุณเรียกใช้บริการหลักของคุณในฐานะบริการภายใต้การดูแล สิ่งต่างๆ จะแตกต่างออกไป และคุณต้องบอกคอนเทนเนอร์ว่าโค้ดใดที่จะออกเมื่อคุณส่งคำสั่ง docker stop
หากต้องการทำเช่นนั้น คุณต้องเขียนสคริปต์ finish
:
/etc/services.d
คุณต้องมีสคริปต์ /etc/services.d/myapp/finish
ที่ปฏิบัติการได้/etc/s6-overlay/s6-rc.d/myapp/finish
ที่มีสคริปต์ของคุณ (ไฟล์นั้นอาจหรือไม่สามารถเรียกใช้งานได้) สคริปต์ finish
สิ้นนี้จะถูกเรียกใช้เมื่อบริการของคุณออก และจะรับอาร์กิวเมนต์สองตัว:
ในสคริปต์ finish
คุณต้องเขียนโค้ดทางออกของคอนเทนเนอร์ที่คุณต้องการลงในไฟล์ /run/s6-linux-init-container-results/exitcode
- เท่านี้ก็เรียบร้อย
ตัวอย่างเช่น สคริปต์ finish
สำหรับบริการ myapp
ด้านบนอาจเป็นดังนี้:
#! /bin/sh
if test " $1 " -eq 256 ; then
e= $(( 128 + $2 ))
else
e= " $1 "
fi
echo " $e " > /run/s6-linux-init-container-results/exitcode
เมื่อคุณส่งคำสั่ง docker stop
ไปยังคอนเทนเนอร์ของคุณ บริการ myapp
จะถูกหยุดทำงานและสคริปต์นี้จะถูกเรียกใช้ มันจะเขียนรหัสทางออกของ myapp
(หาก myapp
จับสัญญาณ TERM) หรือ 130 (หาก myapp
ตรวจไม่พบสัญญาณ TERM) ไปยังไฟล์พิเศษ /run/s6-linux-init-container-results/exitcode
ซึ่งจะ ถูกอ่านโดย s6-overlay เมื่อสิ้นสุดขั้นตอนการปิดระบบคอนเทนเนอร์ และคอนเทนเนอร์ของคุณจะออกพร้อมกับค่านั้น
ส่วนนี้จะอธิบายฟังก์ชันการทำงานจากเวอร์ชันของ s6-overlay ที่ อยู่ก่อนหน้า เวอร์ชัน 3 fix-attrs ยังคงได้รับการสนับสนุนใน v3 แต่ เลิกใช้แล้ว ด้วยเหตุผลหลายประการ หนึ่งในนั้นคือ โดยทั่วไปแล้ว ไม่ใช่นโยบายที่ดีที่จะเปลี่ยนความเป็นเจ้าของแบบไดนามิกเมื่อสามารถทำได้แบบคงที่ อีกเหตุผลหนึ่งคือใช้ไม่ได้กับคอนเทนเนอร์ USER แทนที่จะแก้ไข attr ตอนนี้เราขอแนะนำให้คุณดูแลความเป็นเจ้าของและการอนุญาตบนโฮสต์ที่เมาท์ แบบออฟไลน์ ก่อนที่จะรันคอนเทนเนอร์ สิ่งนี้ควรทำใน Dockerfile ของคุณเมื่อคุณมีข้อมูลที่จำเป็นทั้งหมดแล้ว
ตามที่กล่าวไว้ นี่คือสิ่งที่เราเขียนไว้สำหรับเวอร์ชันก่อนหน้าและยังคงใช้ได้อยู่ในปัจจุบัน (แต่โปรดหยุดขึ้นอยู่กับเวอร์ชันนั้น):
บางครั้งการแก้ไขความเป็นเจ้าของและการอนุญาตก่อนดำเนินการต่อก็เป็นเรื่องน่าสนใจ เนื่องจากตัวอย่างเช่น คุณได้ติดตั้ง/แมปโฟลเดอร์โฮสต์ภายในคอนเทนเนอร์ของคุณ โอเวอร์เลย์ของเรามีวิธีแก้ไขปัญหานี้โดยใช้ไฟล์ใน /etc/fix-attrs.d
นี่คือรูปแบบรูปแบบตามด้วยไฟล์ fix-attrs:
path recurse account fmode dmode
path
: ไฟล์หรือเส้นทาง dirrecurse
: (ตั้งค่าเป็น true
หรือ false
) หากพบโฟลเดอร์ ให้ทำการเรียกซ้ำผ่านไฟล์และโฟลเดอร์ทั้งหมดที่อยู่ในนั้นaccount
: บัญชีเป้าหมาย เป็นไปได้ที่จะใช้ค่าเริ่มต้นเป็นทางเลือก uid:gid
หากไม่พบบัญชี ตัวอย่างเช่น nobody,32768:32768
จะพยายามใช้บัญชี nobody
ก่อน จากนั้นจึงใช้ทางเลือก uid 32768
แทน ตัวอย่างเช่น หากบัญชี daemon
คือ UID=2
และ GID=2
สิ่งเหล่านี้คือค่าที่เป็นไปได้สำหรับฟิลด์ account
:daemon: UID=2 GID=2
daemon,3:4: UID=2 GID=2
2:2,3:4: UID=2 GID=2
daemon:11111,3:4: UID=2 GID=11111
11111:daemon,3:4: UID=11111 GID=2
daemon:daemon,3:4: UID=2 GID=2
daemon:unexisting,3:4: UID=2 GID=4
unexisting:daemon,3:4: UID=3 GID=2
11111:11111,3:4: UID=11111 GID=11111
fmode
: โหมดไฟล์เป้าหมาย เช่น 0644
dmode
: เป้าหมาย dir/โหมดโฟลเดอร์ เช่น 0755
คุณมีตัวอย่างการทำงานดังนี้:
/etc/fix-attrs.d/01-mysql-data-dir
:
/var/lib/mysql true mysql 0600 0700
/etc/fix-attrs.d/02-mysql-log-dirs
:
/var/log/mysql-error-logs true nobody,32768:32768 0644 2700
/var/log/mysql-general-logs true nobody,32768:32768 0644 2700
/var/log/mysql-slow-query-logs true nobody,32768:32768 0644 2700
นี่เป็นวิธีเก่าในการทำ:
หลังจากแก้ไขแอตทริบิวต์ (ผ่าน /etc/fix-attrs.d/
) และก่อนเริ่มบริการที่ผู้ใช้ให้มา (ผ่าน s6-rc หรือ /etc/services.d
) การซ้อนทับของเราจะรันสคริปต์ทั้งหมดที่พบใน /etc/cont-init.d
ตัวอย่างเช่น:
/etc/cont-init.d/02-confd-onetime
:
#!/command/execlineb -P
with-contenv
s6-envuidgid nginx
multisubstitute
{
import -u -D0 UID
import -u -D0 GID
import -u CONFD_PREFIX
define CONFD_CHECK_CMD "/usr/sbin/nginx -t -c {{ .src }}"
}
confd --onetime --prefix="${CONFD_PREFIX}" --tmpl-uid="${UID}" --tmpl-gid="${GID}" --tmpl-src="/etc/nginx/nginx.conf.tmpl" --tmpl-dest="/etc/nginx/nginx.conf" --tmpl-check-cmd="${CONFD_CHECK_CMD}" etcd
วิธีนี้ยังคงได้รับการสนับสนุน อย่างไรก็ตาม ขณะนี้มีวิธีทั่วไปและมีประสิทธิภาพมากขึ้นในการดำเนินการนี้: เขียนงานการเริ่มต้นและการสรุป oneshot ของคุณเป็นบริการ s6-rc โดยการเพิ่มไดเร็กทอรีคำจำกัดความบริการใน /etc/s6-overlay/s6-rc.d
ทำให้เป็นส่วนหนึ่ง ของบันเดิล user
(ดังนั้นพวกมันจะเริ่มทำงานจริงเมื่อคอนเทนเนอร์บูท) และทำให้พวกเขาขึ้นอยู่กับบันเดิล base
(ดังนั้นพวกมันจะเริ่มทำงานหลังจาก base
เท่านั้น)
ข้อมูลทั้งหมดเกี่ยวกับ s6-rc สามารถพบได้ที่นี่
เมื่อคอนเทนเนอร์เริ่มทำงาน การดำเนินการจะดำเนินการตามลำดับนี้:
/etc/fix-attrs.d
/etc/cont-init.d
จะถูกรันตามลำดับuser
เริ่มต้นโดย s6-rc ตามลำดับที่กำหนดโดยการขึ้นต่อกัน บริการอาจเป็นแบบ oneshots (งานการเริ่มต้น) หรือแบบ longrun (เดมอนที่จะทำงานตลอดอายุการใช้งานของคอนเทนเนอร์) หากบริการขึ้นอยู่กับ base
จะรับประกันว่าจะเริ่มที่จุดนี้และไม่เร็วกว่านั้น หากไม่เป็นเช่นนั้น อาจมีการเริ่มต้นก่อนหน้านี้ ซึ่งอาจทำให้เกิดสภาพการแข่งขัน ดังนั้นจึงแนะนำให้ขึ้นอยู่กับ base
เสมอ/etc/services.d
เริ่มต้นขึ้นแล้วuser2
ที่มีการขึ้นต่อกันที่ถูกต้องจะเริ่มต้นขึ้น (คนส่วนใหญ่ไม่จำเป็นต้องใช้สิ่งนี้ หากคุณไม่แน่ใจ ให้ยึดติดกับชุด user
)เมื่อคอนเทนเนอร์หยุดทำงาน เนื่องจากผู้ดูแลระบบส่งคำสั่งหยุดหรือเนื่องจาก CMD ออกจากระบบ การดำเนินการจะดำเนินการในลำดับย้อนกลับ:
user2
ที่มีการขึ้นต่อกันที่ถูกต้องจะหยุดทำงาน/etc/services.d
หยุดทำงานแล้วdown
ในไดเร็กทอรีคำจำกัดความของแหล่งที่มาจะถูกดำเนินการ นั่นคือวิธีที่ s6-rc สามารถทำงานสรุปข้อมูลได้/etc/cont-finish.d
จะถูกรันตามลำดับ จุดประสงค์ของบันเดิล user2
คือการอนุญาตให้บริการผู้ใช้ที่ประกาศไว้ในบันเดิลเริ่มต้น หลังจาก /etc/services.d
แต่เพื่อที่จะทำเช่นนั้น ทุกบริการใน user2
จำเป็นต้องประกาศการพึ่งพา legacy-services
กล่าวอีกนัยหนึ่ง เพื่อให้ foobar
บริการเริ่มต้นล่าช้า คุณต้อง:
/etc/s6-overlay/s6-rc.d/foobar
เช่นเดียวกับบริการ s6-rc อื่นๆ/etc/s6-overlay/s6-rc.d/foobar/dependencies.d/legacy-services
/etc/s6-overlay/s6-rc.d/user2/contents.d/foobar
เพื่อให้แน่ใจว่า foobar
จะเริ่ม หลังจาก ทุกอย่างใน /etc/services.d
ตามค่าเริ่มต้น บริการที่สร้างใน /etc/services.d
จะรีสตาร์ทโดยอัตโนมัติ หากบริการควรทำให้คอนเทนเนอร์ล่ม คุณควรรันคอนเทนเนอร์นั้นเป็น CMD แทน แต่ถ้าคุณต้องการใช้งานเป็นบริการภายใต้การดูแล คุณจะต้องเขียนสคริปต์ finish
ซึ่งจะทำงานเมื่อบริการหยุดทำงาน หากต้องการให้คอนเทนเนอร์หยุดทำงาน จะต้องเรียกใช้คำสั่ง /run/s6/basedir/bin/halt
นี่คือตัวอย่างสคริปต์ปิดท้าย:
/etc/services.d/myapp/finish
:
#!/command/execlineb -S0
foreground { redirfd -w 1 /run/s6-linux-init-container-results/exitcode echo 0 }
/run/s6/basedir/bin/halt
บรรทัดแรกของสคริปต์เขียน 0
ไปยังไฟล์ /run/s6-linux-init-container-results/exitcode
บรรทัดที่สองหยุดคอนเทนเนอร์ เมื่อคุณหยุดคอนเทนเนอร์ผ่านคำสั่ง /run/s6/basedir/bin/halt
รันจากภายในคอนเทนเนอร์ /run/s6-linux-init-container-results/exitcode
จะถูกอ่านและเนื้อหาจะถูกใช้เป็นโค้ดออกสำหรับ คำสั่ง docker run
ที่เรียกใช้คอนเทนเนอร์ หากไม่มีไฟล์อยู่ หรือหากคอนเทนเนอร์หยุดทำงานด้วย docker stop
หรือเหตุผลอื่น รหัสทางออกจะมีค่าเริ่มต้นเป็น 0
เป็นไปได้ที่จะดำเนินการขั้นสูงเพิ่มเติมในสคริปต์เสร็จสิ้น ตัวอย่างเช่น ต่อไปนี้เป็นสคริปต์ที่จะดึงบริการลงเมื่อออกจากสถานะที่ไม่ใช่ศูนย์เท่านั้น:
/etc/services.d/myapp/finish
:
#!/command/execlineb -S1
if { eltest ${1} -ne 0 -a ${1} -ne 256 }
/run/s6/basedir/bin/halt
โปรดทราบว่าโดยทั่วไป สคริปต์เสร็จสิ้นควรใช้สำหรับการล้างข้อมูลในเครื่องหลังจากที่ daemon เสียชีวิตเท่านั้น หากบริการมีความสำคัญมากจนคอนเทนเนอร์จำเป็นต้องหยุดทำงานเมื่อคอนเทนเนอร์ไม่ทำงาน เราขอแนะนำให้เรียกใช้บริการดังกล่าวเป็น CMD
ทุกบริการสามารถมีเครื่องบันทึกเฉพาะได้ ตัวบันทึกเป็นบริการ s6 ที่อ่านจาก stdout ของบริการของคุณโดยอัตโนมัติ และบันทึกข้อมูลลงในไฟล์ที่หมุนโดยอัตโนมัติในตำแหน่งที่คุณต้องการ โปรดทราบว่าโดยปกติ daemons จะล็อกไปที่ stderr ไม่ใช่ stdout ดังนั้นคุณควรเริ่มรันสคริปต์ของบริการด้วย exec 2>&1
ในเชลล์ หรือด้วย fdmove -c 2 1
ใน execline เพื่อที่จะจับ stderr
s6-overlay จัดเตรียมยูทิลิตีที่เรียกว่า logutil-service
ซึ่งเป็น wrapper เหนือโปรแกรม s6-log
ผู้ช่วยนี้ทำสิ่งต่อไปนี้:
S6_LOGGING_SCRIPT
ต่อไปอย่างไรnobody
(ค่าเริ่มต้นเป็น 65534:65534
หากไม่มีอยู่) s6-log จะทำงานตลอดไป โดยอ่านข้อมูลจากบริการของคุณและเขียนลงในไดเร็กทอรีที่คุณระบุใน logutil-service
โปรดทราบ:
s6-setuidgid
nobody
nobody
คุณสามารถสร้างโฟลเดอร์บันทึกในสคริปต์ cont-init.d
หรือในรูปแบบ s6-rc oneshots นี่คือตัวอย่างของ myapp
ของบริการที่บันทึกไว้ซึ่งมีการใช้งานแบบเก่า:
/etc/cont-init.d/myapp-log-prepare
:
#! /bin/sh -e
mkdir -p /var/log/myapp
chown nobody:nogroup /var/log/myapp
chmod 02755 /var/log/myapp
/etc/services.d/myapp/run
:
#! /bin/sh
exec 2>&1
exec mydaemon-in-the-foreground-and-logging-to-stderr
/etc/services.d/myapp/log/run
:
#! /bin/sh
exec logutil-service /var/log/myapp
และนี่คือบริการเดียวกัน myapp ที่ใช้งานใน s6-rc
/etc/s6-overlay/s6-rc.d/myapp-log-prepare/dependencies.d/base
: ไฟล์ว่างเปล่า
/etc/s6-overlay/s6-rc.d/myapp-log-prepare/type
:
oneshot
/etc/s6-overlay/s6-rc.d/myapp-log-prepare/up
:
if { mkdir -p /var/log/myapp }
if { chown nobody:nogroup /var/log/myapp }
chmod 02755 /var/log/myapp
(จุดเริ่มต้นของส่วนรายละเอียด)
ดังนั้นไฟล์ up
และ down
จึงมีความพิเศษ: ไม่ใช่เชลล์สคริปต์ แต่เป็นบรรทัดคำสั่งเดียวที่ตีความโดย execlineb คุณไม่ควรกังวลเกี่ยวกับ execline; คุณควรจำไว้ว่าไฟล์ up
มีบรรทัดคำสั่งเดียว ดังนั้น หากคุณต้องการสคริปต์ที่มีคำแนะนำหลายประการ ต่อไปนี้คือวิธีดำเนินการ:
up
นี่คือวิธีปกติที่คุณจะเขียนไฟล์ up
สำหรับ myapp-log-prepare
:
/etc/s6-overlay/s6-rc.d/myapp-log-prepare/up
:
/etc/s6-overlay/scripts/myapp-log-prepare
/etc/s6-overlay/scripts/myapp-log-prepare
: (ต้องสามารถเรียกใช้งานได้)
#! /bin/sh -e
mkdir -p /var/log/myapp
chown nobody:nogroup /var/log/myapp
chmod 02755 /var/log/myapp
ตำแหน่งของสคริปต์จริงนั้นขึ้นอยู่กับอำเภอใจ เพียงแค่ต้องตรงกับสิ่งที่คุณเขียนในไฟล์ up
แต่ที่นี่ มันบังเอิญว่าสคริปต์นั้นเรียบง่ายพอที่จะสามารถใส่ลงในไฟล์ up
ได้ทั้งหมดโดยไม่ทำให้มันซับซ้อนเกินไปหรือยากเกินไปที่จะเข้าใจ ดังนั้นเราจึงเลือกที่จะรวมไว้เป็นตัวอย่างเพื่อแสดงให้เห็นว่ายังมีอีกมากมายที่คุณสามารถทำได้กับไฟล์ up
มาก หากคุณตั้งใจเช่นนั้น คุณสามารถอ่านเอกสารฉบับเต็มสำหรับภาษา execline ได้ที่นี่
(สิ้นสุดส่วนรายละเอียด คลิกสามเหลี่ยมด้านบนอีกครั้งเพื่อยุบ)
/etc/s6-overlay/s6-rc.d/myapp/dependencies.d/base
: ไฟล์ว่าง
/etc/s6-overlay/s6-rc.d/myapp-log/dependencies.d/myapp-log-prepare
: ไฟล์ว่างเปล่า
/etc/s6-overlay/s6-rc.d/myapp/type
:
longrun
/etc/s6-overlay/s6-rc.d/myapp/run
:
#! /bin/sh
exec 2>&1
exec mydaemon-in-the-foreground-and-logging-to-stderr
/etc/s6-overlay/s6-rc.d/myapp/producer-for
:
myapp-log
/etc/s6-overlay/s6-rc.d/myapp-log/type
:
longrun
/etc/s6-overlay/s6-rc.d/myapp-log/run
:
#! /bin/sh
exec logutil-service /var/log/myapp
/etc/s6-overlay/s6-rc.d/myapp-log/consumer-for
:
myapp
/etc/s6-overlay/s6-rc.d/myapp-log/pipeline-name
:
myapp-pipeline
/etc/s6-overlay/s6-rc.d/user/contents.d/myapp-pipeline
: ไฟล์ว่างเปล่า
ไฟล์เยอะมาก! บทสรุปของความหมายทั้งหมดคือ:
myapp | myapp-log
ไปป์ไลน์ myapp | myapp-log
ได้รับการตั้งชื่อว่า myapp-pipeline
และชื่อนี้ได้รับการประกาศให้เป็นส่วนหนึ่งของชุด user
ดังนั้นชื่อนี้จะเริ่มทำงานเมื่อคอนเทนเนอร์เริ่มทำงานmyapp-log-prepare
, myapp-log
และ myapp
ทั้งหมดขึ้นอยู่กับบันเดิล base
ซึ่งหมายความว่าพวกมันจะเริ่มทำงานเมื่อระบบพร้อมที่จะสตาร์ทเท่านั้น มันบรรลุผลสำเร็จในสิ่งเดียวกันกับเมธอด /etc/cont-init.d
plus /etc/services.d
แต่มันสะอาดกว่ามาก และสามารถรองรับกราฟการขึ้นต่อกันที่ซับซ้อนกว่ามาก ดังนั้นเมื่อใดก็ตามที่คุณมีโอกาส เราขอแนะนำ คุณทำความคุ้นเคยกับวิธี s6-rc ในการประกาศบริการและผู้บันทึกของคุณ ไวยากรณ์ทั้งหมดของไดเร็กทอรีคำจำกัดความของบริการ รวมถึงการประกาศว่าบริการของคุณเป็นแบบระยะยาวหรือแบบ oneshot การประกาศไปป์ไลน์ การเพิ่มการหมดเวลาเฉพาะบริการ หากคุณต้องการ ฯลฯ สามารถพบได้ที่นี่
เมื่อเป็นเรื่องของการดำเนินการบริการ ไม่ว่าจะเป็นบริการหรือตัวบันทึก แนวทางปฏิบัติที่ดีคือการละทิ้งสิทธิ์ก่อนที่จะดำเนินการ s6
มียูทิลิตี้สำหรับทำสิ่งเหล่านี้อยู่แล้ว:
ใน execline
:
#!/command/execlineb -P
s6-setuidgid daemon
myservice
ใน sh
:
#! /bin/sh
exec s6-setuidgid daemon myservice
หากคุณต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับยูทิลิตี้เหล่านี้ โปรดดูที่: s6-setuidgid
, s6-envuidgid
และ s6-applyuidgid
หากคุณต้องการให้สคริปต์แบบกำหนดเองของคุณมีสภาพแวดล้อมคอนเทนเนอร์ที่พร้อมใช้งาน คุณสามารถใช้ตัวช่วย with-contenv
ซึ่งจะผลักดันสิ่งเหล่านั้นทั้งหมดเข้าสู่สภาพแวดล้อมการดำเนินการของคุณ ตัวอย่างเช่น:
/etc/cont-init.d/01-contenv-example
:
#! /command/with-contenv sh
env
สคริปต์นี้จะส่งออกเนื้อหาของสภาพแวดล้อมคอนเทนเนอร์ของคุณ
Docker เวอร์ชันล่าสุดอนุญาตให้เรียกใช้คอนเทนเนอร์ด้วยระบบไฟล์รูทแบบอ่านอย่างเดียว หากคอนเทนเนอร์ของคุณเป็นเช่นนั้น คุณควรตั้งค่า S6_READ_ONLY_ROOT=1
เพื่อแจ้ง s6-overlay ว่าไม่ควรพยายามเขียนไปยังบางพื้นที่ - แต่จะดำเนินการคัดลอกลงใน tmpfs ที่ติดตั้งบน /run
แทน
โปรดทราบว่า s6-overlay จะถือว่า:
/run
มีอยู่แล้วและสามารถเขียนได้ หากไม่เป็นเช่นนั้น ระบบจะพยายามเมานต์ tmpfs ที่นั่น/var/run
เป็นลิงก์สัญลักษณ์ไปยัง /run
เพื่อความเข้ากันได้กับเวอร์ชันก่อนหน้า ถ้าไม่ใช่ก็จะทำให้มันเป็นเช่นนั้น โดยทั่วไปการตั้งค่านักเทียบท่าเริ่มต้นของคุณควรจัดเตรียม tmpfs ที่เหมาะสมไว้ใน /run
แล้ว
เป็นไปได้ที่จะปรับแต่งพฤติกรรมของ s6-overlay โดยการจัดเตรียมชุดตัวแปรสภาพแวดล้อมที่กำหนดไว้ล่วงหน้าให้กับบริบทการดำเนินการ:
PATH
(ค่าเริ่มต้น = /command:/usr/bin:/bin
): นี่คือ PATH เริ่มต้นที่บริการทั้งหมดในคอนเทนเนอร์ รวมถึง CMD จะมี ตั้งค่าตัวแปรนี้หากคุณมีบริการจำนวนมากที่ขึ้นอยู่กับไบนารีที่จัดเก็บไว้ในไดเร็กทอรีอื่น เช่น /usr/sbin
โปรดทราบว่า /command
, /usr/bin
และ /bin
จะถูกเพิ่มในเส้นทางนั้นเสมอหากไม่ได้อยู่ในเส้นทางที่คุณระบุS6_KEEP_ENV
(ค่าเริ่มต้น = 0): หากตั้งค่าไว้ สภาพแวดล้อมจะไม่ถูกรีเซ็ต และแผนผังการควบคุมทั้งหมดจะเห็นชุด env vars ดั้งเดิม มันสลับ with-contenv
เป็น nopS6_LOGGING
(ค่าเริ่มต้น = 0):0
: ส่งออกทุกอย่างไปที่ stdout/stderr1
: ใช้ตัวบันทึก catch-all
ภายในและคงทุกอย่างไว้ โดยอยู่ใน /var/log/s6-uncaught-logs
สิ่งใดก็ตามที่ทำงานเป็น CMD
จะยังคงส่งออกไปที่ stdout/stderr2
: ใช้ตัวบันทึก catch-all
ภายในและคงทุกอย่างไว้ รวมถึงเอาต์พุตของ CMD
ไม่มีการเขียนถึง stdout/stderr อย่างแน่นอนS6_CATCHALL_USER
(ค่าเริ่มต้น = root): หากตั้งค่าไว้ และหาก S6_LOGGING
เป็น 1 หรือ 2 ระบบจะเรียกใช้ตัวบันทึกที่รับทั้งหมดในฐานะผู้ใช้รายนี้ ซึ่งจะต้องกำหนดไว้ใน /etc/passwd
ของรูปภาพของคุณ การแยกสิทธิ์ทุกประการจะช่วยรักษาความปลอดภัยได้เล็กน้อยS6_BEHAVIOUR_IF_STAGE2_FAILS
(ค่าเริ่มต้น = 0): กำหนดว่าคอนเทนเนอร์ควรทำอย่างไรหากสคริปต์บริการตัวใดตัวหนึ่งล้มเหลว ซึ่งรวมถึง:fix-attrs
/etc/cont-init.d
แบบเก่าหรือรูปแบบใหม่ s6-rc oneshot ล้มเหลว/etc/services.d
แบบเก่าหรือ longrun s6-rc สไตล์ใหม่ถูกทำเครื่องหมายว่าเป็นการแจ้งเตือนความพร้อม และไม่ พร้อม ในเวลาที่กำหนด (ดู S6_CMD_WAIT_FOR_SERVICES_MAXTIME
ด้านล่าง) ค่าที่ถูกต้องสำหรับ S6_BEHAVIOUR_IF_STAGE2_FAILS
มีดังต่อไปนี้:0
: ดำเนินการต่อแบบเงียบๆ แม้ว่าสคริปต์จะล้มเหลวก็ตาม1
: ดำเนินการต่อแต่เตือนด้วยข้อความแสดงข้อผิดพลาดที่น่ารำคาญ2
: หยุดคอนเทนเนอร์S6_KILL_FINISH_MAXTIME
(ค่าเริ่มต้น = 5000): ระยะเวลาที่ระบบควรรอ (เป็นมิลลิวินาที) ณ เวลาปิดระบบ เพื่อให้สคริปต์ใน /etc/cont-finish.d
เสร็จสิ้นตามธรรมชาติ หลังจากระยะเวลานี้ สคริปต์จะถูกส่ง SIGKILL โปรดทราบว่าสคริปต์ใน /etc/cont.finish.d
จะทำงานตามลำดับ และลำดับการปิดระบบอาจรอเป็นเวลา S6_KILL_FINISH_MAXTIME
มิลลิวินาทีสำหรับ แต่ละ สคริปต์S6_SERVICES_READYTIME
(ค่าเริ่มต้น = 50): ด้วยบริการที่ประกาศใน /etc/services.d
มีสภาวะการแข่งขันที่หลีกเลี่ยงไม่ได้ระหว่างช่วงเวลาที่บริการเริ่มต้นและช่วงเวลาที่สามารถทดสอบความพร้อมได้ เพื่อหลีกเลี่ยงการแข่งขันนั้น เราจะนอนหลับสักเล็กน้อยตามค่าเริ่มต้น 50 มิลลิวินาที ก่อนที่จะทดสอบความพร้อม หากเครื่องของคุณช้าหรือยุ่งมาก คุณอาจได้รับข้อผิดพลาดที่มีลักษณะดังนี้ s6-svwait: fatal: unable to s6_svstatus_read: No such file or directory
ในกรณีนั้น คุณควรเพิ่มเวลาพักเครื่องโดยประกาศ (เป็นมิลลิวินาที) ในตัวแปร S6_SERVICES_READYTIME
โปรดทราบว่ามันเกี่ยวข้องเท่านั้น /etc/services.d
; s6-rc มีภูมิคุ้มกันต่อสภาพการแข่งขันS6_SERVICES_GRACETIME
(ค่าเริ่มต้น = 3000): ระยะเวลาที่ s6
ควรรอ (เป็นมิลลิวินาที) ณ เวลาปิดระบบ เพื่อให้บริการที่ประกาศใน /etc/services.d
หยุดทำงานก่อนที่จะดำเนินการปิดระบบส่วนที่เหลือS6_KILL_GRACETIME
(ค่าเริ่มต้น = 3000): ระยะเวลาที่ s6
ควรรอ (เป็นมิลลิวินาที) เมื่อสิ้นสุดกระบวนการปิดระบบ เมื่อกระบวนการทั้งหมดได้รับสัญญาณ TERM เพื่อให้กระบวนการหยุดทำงานก่อนที่จะส่งสัญญาณ KILL
เพื่อให้ แน่ใจว่า กระบวนการเหล่านั้นตายแล้ว .S6_LOGGING_SCRIPT
(ค่าเริ่มต้น = "n20 s1000000 T"): สภาพแวดล้อมนี้จะตัดสินใจว่าจะบันทึกอะไรและอย่างไร โดยค่าเริ่มต้น ทุกบรรทัดจะขึ้นต้นด้วย ISO8601 ซึ่งจะหมุนเวียนเมื่อไฟล์บันทึกปัจจุบันมีขนาดถึง 1mb และถูกเก็บถาวรสูงสุดที่ 20 ไฟล์S6_CMD_ARG0
(ค่าเริ่มต้น = ไม่ได้ตั้งค่า): ค่าของ env var นี้จะถูกเพิ่มเข้ากับ args CMD
ใด ๆ ที่ส่งผ่านโดยนักเทียบท่า ใช้ตัวเลือกนี้หากคุณกำลังย้ายรูปภาพที่มีอยู่ไปยัง s6-overlay และต้องการทำให้เป็นการแทนที่แบบดรอปอิน: การตั้งค่าตัวแปรนี้เป็นค่าของ ENTRYPOINT ที่ใช้ก่อนหน้านี้จะช่วยให้คุณเปลี่ยนได้S6_CMD_USE_TERMINAL
(ค่าเริ่มต้น = 0): ตั้งค่านี้เป็น 1 หากคุณมี CMD ที่ต้องการเทอร์มินัลสำหรับเอาต์พุต (โดยทั่วไปเมื่อคุณเรียกใช้คอนเทนเนอร์ด้วย docker run -it
) และคุณได้ตั้ง S6_LOGGING
เป็นค่าที่ไม่ใช่ศูนย์ การตั้งค่านี้จะทำให้ CMD ของคุณส่งออกไปยังเทอร์มินัลของคุณจริงๆ ข้อเสียเปรียบคือเอาต์พุตจะไม่ถูกบันทึก ตามค่าเริ่มต้น (เมื่อตัวแปรนี้เป็น 0 หรือไม่ได้ตั้งค่า) stdout และ stderr ของ CMD ของคุณจะถูกบันทึกเมื่อ S6_LOGGING
ไม่ใช่ศูนย์ ซึ่งหมายความว่าทั้งสองไปที่ไปป์แม้ว่าคุณจะใช้งานในเทอร์มินัลแบบโต้ตอบก็ตามS6_FIX_ATTRS_HIDDEN
(ค่าเริ่มต้น = 0): ควบคุมวิธีที่สคริปต์ fix-attrs.d
ประมวลผลไฟล์และไดเร็กทอรี0
: ไม่รวมไฟล์และไดเร็กทอรีที่ซ่อนไว้1
: ไฟล์และไดเร็กทอรีทั้งหมดได้รับการประมวลผลS6_CMD_WAIT_FOR_SERVICES
(ค่าเริ่มต้น = 0): ตามค่าเริ่มต้น เมื่อคอนเทนเนอร์เริ่มต้น บริการใน /etc/services.d
จะเริ่มต้นขึ้น และการดำเนินการจะดำเนินการเพื่อเริ่มบันเดิล user2
และ CMD หากมีการกำหนดสิ่งเหล่านี้ไว้ หาก S6_CMD_WAIT_FOR_SERVICES
ไม่ใช่ศูนย์อย่างไรก็ตามลำดับการเริ่มต้นคอนเทนเนอร์จะรอจนกว่าบริการใน /etc/services.d
จะ พร้อม ก่อนที่จะดำเนินการตามลำดับที่เหลือ โปรดทราบว่าสิ่งนี้มีความสำคัญเฉพาะในกรณีที่บริการใน /etc/services.d
แจ้งความพร้อมของพวกเขาถึง S6S6_CMD_WAIT_FOR_SERVICES_MAXTIME
(ค่าเริ่มต้น = 0, IE ไม่มีที่สิ้นสุด): เวลาสูงสุด (เป็นมิลลิวินาที) บริการอาจใช้เพื่อนำไปใช้ก่อนที่จะดำเนินการเพื่อดำเนินการ CMD ตั้งค่าตัวแปรนี้เป็นค่าบวกหากคุณมีบริการที่สามารถบล็อกได้อย่างไม่มีกำหนดและคุณต้องการให้คอนเทนเนอร์ล้มเหลวหากไม่ใช่ทุกอย่างหลังจากเวลาที่กำหนด โปรดทราบว่าค่านี้ยังรวมถึงการตั้งค่าการเริ่มต้นการเริ่มต้นคอนเทนเนอร์แบบดั้งเดิม ( /etc/cont-init.d
) และบริการ ( /etc/services.d
) ดังนั้นโปรดคำนึงถึงสิ่งนั้นเมื่อคำนวณค่าที่เหมาะสม ในเวอร์ชันของ S6-Overlay ถึง 3.1.6.2 ค่าเริ่มต้นคือ 5,000 (ห้าวินาที) แต่ทำให้เกิดความล้มเหลวของภาชนะที่ไม่พึงประสงค์มากกว่าปัญหาที่แก้ไขแล้วดังนั้นตอนนี้ไม่มีการหมดเวลาตามค่าเริ่มต้น: S6-Overlay จะรอตราบเท่าที่เป็นอยู่ จำเป็นสำหรับบริการทั้งหมดที่จะถูกนำขึ้นมาS6_READ_ONLY_ROOT
(ค่าเริ่มต้น = 0): เมื่อทำงานในคอนเทนเนอร์ที่มีระบบไฟล์รูทเป็นแบบอ่านอย่างเดียวให้ตั้งค่า env นี้เป็น 1 เพื่อแจ้งขั้นตอนเริ่มต้น 2 ว่าควรคัดลอกสคริปต์การเริ่มต้นที่ผู้ใช้จัดเตรียมไว้จาก /etc
ถึง /run/s6/etc
ก่อน มันพยายามที่จะเปลี่ยนการอนุญาต ฯลฯ ดูระบบไฟล์รูทแบบอ่านอย่างเดียวสำหรับข้อมูลเพิ่มเติมS6_SYNC_DISKS
(default = 0): ตั้งค่า env นี้เป็น 1 เพื่อแจ้งขั้นตอนเริ่มต้น 3 ว่าควรพยายามซิงค์ระบบไฟล์ก่อนหยุดคอนเทนเนอร์ หมายเหตุ: สิ่งนี้น่าจะซิงค์ระบบไฟล์ทั้งหมดบนโฮสต์S6_STAGE2_HOOK
(ค่าเริ่มต้น = ไม่มี): หากตัวแปรนี้มีอยู่เนื้อหาของมันจะถูกตีความว่าเป็นข้อความที่ตัดตอนมาจากเชลล์ที่จะทำงานในระยะแรกก่อนที่จะเริ่มให้บริการ สิ่งนี้สามารถใช้งานได้เช่นเพื่อแก้ไขฐานข้อมูลบริการแบบไดนามิกในเวลาทำงานก่อนที่มันจะถูกรวบรวมและเรียกใช้ ค่าที่ไม่ถูกต้องสามารถป้องกันไม่ให้คอนเทนเนอร์ของคุณทำงานหรือเป็นอันตรายต่อความปลอดภัยของคุณดังนั้นให้ใช้สิ่งนี้หากคุณรู้ว่าคุณกำลังทำอะไรอยู่ หากมีข้อสงสัยให้ปล่อยให้ตัวแปรนี้ไม่ได้กำหนดS6_VERBOSITY
(ค่าเริ่มต้น = 2): ควบคุมคำฟางของ S6-RC และเครื่องมืออื่น ๆ ที่อาจเกิดขึ้นที่คอนเทนเนอร์เริ่มต้นและหยุดเวลา ค่าเริ่มต้น 2 โดยปกติแล้วจะมีการแสดงรายการการเริ่มต้นและหยุดการดำเนินงาน คุณสามารถทำให้คอนเทนเนอร์เงียบลงได้โดยลดจำนวนนี้: 1 จะพิมพ์คำเตือนและข้อผิดพลาดเท่านั้นและ 0 จะพิมพ์ข้อผิดพลาดเท่านั้น นอกจากนี้คุณยังสามารถทำให้คอนเทนเนอร์ verbose มากขึ้น เช่นการติดตามการพิมพ์และข้อมูลการดีบักโดยการเพิ่มจำนวนนี้มากถึง 5 แต่ผลลัพธ์จะกลายเป็นเสียง ดังมาก และคนส่วนใหญ่ไม่ต้องการสิ่งนี้S6_CMD_RECEIVE_SIGNALS
(ค่าเริ่มต้น = 0): ตัดสินใจว่าสัญญาณที่ส่งไปยังคอนเทนเนอร์ควรถูกส่งไปยัง PID 1 หรือ CMD ของคอนเทนเนอร์หรือไม่ โดยค่าเริ่มต้นเมื่อคุณดำเนินการเป็นตัวอย่างของ docker stop
สัญญาณคำจะถูกส่งไปยัง PID 1 ของคอนเทนเนอร์ซึ่งจะทำให้เกิดลำดับการปิดตัวของคอนเทนเนอร์เต็มรูปแบบ - แต่ถ้ามี CMD อยู่มันจะเป็นหนึ่งในกระบวนการสุดท้ายที่จะถูกฆ่าตาย เฉพาะเมื่อทุกอย่างอื่นลงและคอนเทนเนอร์กำลังจะออก หากตัวแปรนี้คือ 1 หรือมากกว่าสัญญาณจะถูกเบี่ยงเบนจาก PID 1 ไปยัง CMD ซึ่งหมายความว่า docker stop
จะส่ง sigterm ไปยัง CMD แทนและคอนเทนเนอร์จะกระตุ้นขั้นตอนการปิดระบบเมื่อ CMD ตาย โปรดทราบว่ามีเพียง sigterm, sigquit, sigint, sigusr1, sigusr2, sigpwr และ sigwinch ถูกเบี่ยงเบน; สัญญาณอื่น ๆ จะถูกละเว้นหรือไม่สามารถเบี่ยงเบนความสนใจได้และจำเป็นต้องได้รับการจัดการโดย PID 1 โปรดทราบว่าการใช้ตัวเลือกนี้อาจป้องกันไม่ให้ CMD แบบโต้ตอบทำงานได้เลย - กล่าวอีกนัยหนึ่งหากคุณใช้ CMD แบบโต้ตอบในเทอร์มินัลดอนดอน 'ไม่ตั้งค่าตัวแปรนี้ แต่นั่นควรจะดีเนื่องจากในกรณีนี้คุณมีวิธีการโต้ตอบในการหยุด CMD ของคุณแล้ว หากซอฟต์แวร์ที่ทำงานในคอนเทนเนอร์ของคุณต้องการ syslog ให้แยก syslogd-overlay-noarch.tar.xz
tarball: นั่นจะทำให้คุณมีการจำลอง syslogd เล็ก ๆ บันทึกจะพบได้ภายใต้ไดเรกทอรีย่อยต่างๆของ /var/log/syslogd
ตัวอย่างเช่นข้อความจะพบได้ใน /var/log/syslogd/messages/
directory, บันทึกล่าสุดที่มีอยู่ใน /var/log/syslogd/messages/current