第55回情報科学若手の会での登壇資料です。 登壇者:井上紘太朗
ZigͰίϯςφϥϯλΠϜ࡞ͬͯΈͨ2022/09/24 @ ୈ55ճใՊֶएखͷձLINEגࣜձࣾɹҪ্ ߛଠ࿕ (@musaprg)
View Slide
Ҫ্ ߛଠ࿕ (@musaprg)• ॴଐ LINEגࣜձࣾ ITαʔϏεηϯλʔ VerdaϓϥοτϑΥʔϜ։ൃKνʔϜ• Α͘͏ݴޠ Go, Python• ࠷ۙͷΠνΦγ࡞ ʮCyberpunk: Edgerunnersʯ ʮϦίϦεɾϦίΠϧʯ
Verda• LINEגࣜձࣾͰɾӡ༻͍ͯ͠ΔϓϥΠϕʔτΫϥυ• ΤεϖϥϯτޠͰʮʯ• ͞·͟·ͳαʔϏεΛఏڙ͍ͯ͠Δ• Server (VM/PM),• Load Balancer• MySQL• VOS (Object Storage)• Managed Kubernetes (VKS: Verda Kubernetes Service)• etc.
Verdaͷن• 202209݄ݱࡏͷ౷ܭ7,4 ϊʔυ Ҏ্7,4 Ϋϥελ Ҏ্7FSEB Ծαʔό Ҏ্
Ҏ߱ͷൃද༰ ॴଐاۀͷۀͱؔ͋Γ·ͤΜ
ຊͷ͓͠ͳ͕͖ 1. ·͓͖͑2. शίϯςφϥϯλΠϜ3. runzigcͷհ4. ZigͷΑ͔ͬͨɾࠔͬͨ5. ·ͱΊ
ຊηογϣϯͷΰʔϧ• ίϯςφϥϯλΠϜͷΈΛͬ͘͟ΓΔ• ZigͷഽײΛΔʢGopherࢹʣ• ͋ΘΑ͘ίϯςφϥϯλΠϜΛࣗ࡞ͯ͠ΈΑ͏ͱ͍͏ؾʹͳΔ
͜Μͳਓʹͱͬͯ໘ന͍͔• ίϯςφϥϯλΠϜͷ࣮ʹڵຯ͕͋Δ• Zigͱ͍͏ϓϩάϥϛϯάݴޠʹڵຯ͕͋Δ
͜ΜͳਓʹΓͳ͍͔…• ʢDockerΛ༻͍ͯʣͦͦίϯςφΛར༻ͨ͜͠ͱ͕ͳ͍• ίϯςφϥϯλΠϜΛ࡞ͬͨ͜ͱ͕͋Δ or ཁૉٕज़Λཧղ͍ͯ͠Δ• ओཁͳίϯςφϥϯλΠϜ࣮ʢruncʣΛಡΜͩ͜ͱ͕͋Δ• ZigͰͦΕͳΓͷنʹϓϩάϥϜΛॻ͍ͨ͜ͱ͕͋Δ
• ιϑτΣΞͱ࣮ߦڥΛͻͱ·ͱΊʹ → ίϯςφΠϝʔδ• ΠϝʔδΛల։ɾ࣮ߦ͢ΔͨΊͷԾతͳִڥ → ίϯςφ• ίϯςφΛ࡞ɾཧ͢ΔͨΊͷπʔϧ܈ → DockerDockerίϯςφ͓͞Β͍ίϯςφΠϝʔδιϑτΣΞ࣮ߦڥ-JOVYΧʔωϧίϯςφ ίϯςφ ίϯςφ
• ΠϝʔδͷϏϧυ docker build -t musaprg/hello .Dockerίϯςφ͓͞Β͍ίϯςφΠϝʔδιϑτΣΞ࣮ߦڥ-JOVYΧʔωϧίϯςφ ίϯςφ ίϯςφ
• ΠϝʔδͷϏϧυ docker build -t musaprg/hello .• ίϯςφͷىಈ docker run musaprg/helloDockerίϯςφ͓͞Β͍ίϯςφΠϝʔδιϑτΣΞ࣮ߦڥ-JOVYΧʔωϧίϯςφ ίϯςφ ίϯςφ)FMMP
ίϯςφΛىಈ͢Δͱى͖Δ͜ͱ• ߴϨϕϧϥϯλΠϜ• Πϝʔδͷཧ• ωοτϫʔΫͷઃఆ ͳͲ• ϨϕϧϥϯλΠϜ• ࣮ߦڥͷִ• ίϯςφͷཧʢىಈఀࢭʣ ͳͲhttps://medium.com/nttlabs/container-runtime-student-internship-2022-q1-89a7113e0cde ʹܝࡌ͞Ε͍ͯΔਤΛͱʹվม
ίϯςφΛىಈ͢Δͱى͖Δ͜ͱ• ߴϨϕϧϥϯλΠϜ• Πϝʔδͷཧ• ωοτϫʔΫઃఆ• ϨϕϧϥϯλΠϜ• ࣮ߦڥͷִ• ίϯςφͷཧʢىಈఀࢭʣhttps://medium.com/nttlabs/container-runtime-student-internship-2022-q1-89a7113e0cde ʹܝࡌ͞Ε͍ͯΔਤΛͱʹվมࠓճ࡞͍ͬͯΔͷͬͪ͜
ϨϕϧϥϯλΠϜ͕ͬͯΔ͜ͱ• OCI Runtime Specͱ͍͏ن͕֨ଘࡏ https://github.com/opencontainers/runtime-spec• ΠϯλʔϑΣʔε create, start, delete, kill, state• ֤छϑΥʔϚοτ• ίϯςφͷϑΝΠϧߏʢFilesystem Bundleʣ• ίϯςφͷ༷ϑΝΠϧʢconfigʣ
ϨϕϧϥϯλΠϜ͕ͬͯΔ͜ͱ• ࣮ߦڥͷִํ๏ԿͰ͍͍ʢنఆͳ͍ʣ ྫɿLinuxͷػೳΛ࣮ͬͯߦڥΛִ͢Δ• Namespaces → ίϯςφ༻ʹϦιʔεΛִ PID, UTS(hostname), mount point, network, cgroups, IPC, etc.• Control Group (cgroups) → Ϧιʔεͷ੍ޚʢྫ: cpumemoryͷ༻ྔΛ੍ݶʣ
ίϯςφٕज़Λߏ͢Δsyscallͨͪ• fork(2), clone(2) → ࢠϓϩηεͷ࡞• exec(2) → ϓϩηεͷஔ͖͑ʢ࣮ߦʣ• unshare(2) → NamespaceΛ࡞ɺ࣮ߦڥͷִ• pivot_root(2) → rootσΟϨΫτϦʢ”/“ʣͷมߋ• etc. ※cgroupsͷઃఆಛघϑΝΠϧγεςϜܦ༝Ͱॻ͖ࠐΉɻ mount point: /sys/fs/cgroup/${subsystem_name}
ϨϕϧϥϯλΠϜࢹͷىಈϓϩηε• ӈਤruncͷ෦ॲཧ ਤോখ༷ͷهࣄΑΓҾ༻ʢͱͯΘ͔Γ͍͢ͷͰΦεεϝʣ https://kurobato.hateblo.jp/entry/2021/05/02/164218• ίϯςφ࡞ʢrunc createʣ → ෦తͳॳظԽॲཧʢrunc initʣ• 2ճforkΛ͢Δͷ͕ಛతʢdouble-forkʣ• namespaceॱংͷؔ
Zig• libcඇґଘͷγϯάϧόΠφϦɾΫϩείϯύΠϧɾWebAssemblyରԠ• ݴޠ༷Λγϯϓϧʹอͭ͜ͱΛڧ͘ҙࣝͨ͠ઃܭ• Ӆṭ͞Ε੍ͨޚϑϩʔ͕ଘࡏ͠ͳ͍ʢe.g., ྫ֎, ԋࢉࢠΦʔόʔϩʔυʣ• ҉తͳώʔϓͷ֬อߦΘΕͳ͍ɻશͯ໌ࣔతʹϝϞϦཧΛߦ͏ɻ• C / C++ͱͷ૬ޓӡ༻͕ՄೳʢZig Toolchainͦͷͷ͕C/C++ίϯύΠϥʣ• ݴޠ༷ະͩunstableʢݱࡏͷόʔδϣϯ: v0.9.1ʣZig Project - Logomark / CC BY-SA 4.0.
runzigc• ZigͰॻ͔ΕͨϨϕϧίϯςφϥϯλΠϜ https://github.com/musaprg/runzigc• runcͷίʔυΛ”େ͍ʹ”ࢀߟʹ͍ͯ͠·͢• Namespace: User, UTS, PIDͷΈ• cgroups v1ʢcpu, memͷΈʣ• OCI Runtime Specʹະ४ڌ
Demo
ຊͷ͓͠ͳ͕͖ 1. ·͓͖͑2. शίϯςφϥϯλΠϜ3. runzigcͷհ4. ZigͷΑͦ͞͏ͳɾࠔͬͨ5. ·ͱΊ
ॻ͍ͯͯײͨ͡ZigͷΑ͞ 1/2• ޡղΛڪΕͣʹݴ͏ͱʮࡶʹॻ͚ΔCݴޠʯ• ײ֮తʹɺ͍͍ͩͨGoͱRustͷؒ͘Β͍• ߏจγϯϓϧͳͷͰɺൺֱతαΫαΫॻ͚Δ• ܕදهʹ͍ͭͯগ͠Ϋη͕͋ΔͷͰ׳Εඞཁ
ॻ͍ͯͯײͨ͡ZigͷΑ͞ 2/2• ܰྔͳSingle static binaryΛు͚Δ• libcͷґଘ͕ͳ͍ͷͰऔΓճ͕͠ྑ͍• ࡶͰ؆қతͳྫˠ Zig 0.9.1 Target: x86_64-linux Optimize: -O ReleaseSmall debug symbol stripped single threaded →ɹ 4.5 KiBconst std = @import("std");pub fn main() void {std.debug.print("Hello, world!\n", .{});}
ࠔͬͨ͜ͱ 1/4• Errorͦͷͷʹ࣋ͨͤΔ͜ͱ͕Մೳͳใ͕গͳ͍• error.PermissionDeniedɺ ”PermissionDenied”Ҏ্ͷใΛͨͳ͍ → ελοΫτϨʔεɾσόοάϩάͳͲΛิॿతʹ༻͍Δ͜ͱͰ ݪҼՕॴͱঢ়گͷಛఆͰ͖ΔͷͰेͰ͋Δʁ
ࠔͬͨ͜ͱ 2/4• nճϧʔϓ࣮ʹศརͳfor(int i = 0;i• Zigͷforɺ͍ΘΏΔfor-eachɻ →ɹwhile-loopͰهड़͢Δ ɹɹɹɹor ɹɹpythonͰ͍͏range()ʹ͋ͨΔͷΛࣗલ࣮• ҰԠproposalग़͍ͯΔ
ࠔͬͨ͜ͱ 3/4• Ұ෦ͷLinuxγεςϜίʔϧZigඪ४ϥΠϒϥϦͷ࣮͕ଘࡏ͠ͳ͍• sethostname(2)ͳͲ → ฦΓͷerrnoΛ ZigͷerrorʹϚοϓ͢Δ ࣮Λఆٛͯ͠ରԠpub fn valOrErr(val: anytype, errno: usize) [email protected](val) {return switch (os.errno(errno)) {.SUCCESS => val,.PERM => error.OperationNotPermitted,// …else => |e| return os.unexpectedErrno(e),};}pub fn sethostname(hostname: []const u8) SetHostNameError!void {const result = switch (native_arch) {else => linux.syscall2(.sethostname, @ptrToInt(hostname.ptr),hostname.len),};return valOrErr({}, result);}
ࠔͬͨ͜ͱ 4/4• ώʔϓͷཧ͕ඞཁͳͷएׯ໘• defer/errdeferͱ͍ͬͨείʔϓϕʔεͷ੍ޚߏจ͋Δ• RustͷΑ͏ʹউखʹղ์ ͯ͘͠Εͳ͍ {var values = std.ArrayList([]const u8).init(allocator);defer values.deinit();}// είʔϓΛൈ͚ͨ࣌Ͱ // ArrayList༻ʹ֬อ͞ΕͨϝϞϦdealloc͞ΕΔ
·ͱΊ• Linuxʹ͓͚Δίϯςφɺ cgroups + namespace Λ༻͍ͯ ϓϩηεͷϦιʔεΛ࣮ͯ͠ݱ͍ͯ͠Δ• ίϯςφϥϯλΠϜͷ͏ͪɺϨϕϧϥϯλΠϜ͕ϦιʔεͷΛ୲͍ͬͯΔ• ZigͰϨϕϧίϯςφϥϯλΠϜ runzigc Λ࡞͍ͬͯ·͢• Zigͷݴޠ༷unstableɺ·ͩ·ͩൃల్্Ͱࠓޙʹ
runzigcͷকདྷ• OCI Runtime Specશ४ڌ• Cgroup v1࣮ɾCgroup v2ରԠ• SeccompରԠ• ߴϨϕϧϥϯλΠϜ࣮Ճ ʴ CRIରԠ• ྑ͍ײ͡ͷ໊લΛߟ͑Δʢืूதʣ
ײ• ͪΌΜͱ࣮ͨ͠ΒऔΓճ͠ͷ͍͍ܰྔίϯςφϥϯλΠϜ͕ ര͢ΔͷͰ…ʁͱ͍͏୶͍ظΛ๊͍͍ͯΔɻ• ݱஈ֊Ͱ͓ͪΌͷҬɺΏ͘Ώ͑͘Δͷʹ͍͖͍ͯͨ͠• ΈΛཧղ͢ΔʹɺࣗͰ࡞ͬͯΈΔͷ͕Ұ൪• Έͳ͞ΜίϯςφϥϯλΠϜ࡞ͬͯΈ·ͤΜ͔ʁ
Reference• ίϯςφϢʔβͳΒ୭͕͍ͬͯΔϥϯλΠϜʮruncʯΛ၆ᛌ͢Δ[Container Runtime Meetup #1ൃදϨϙʔτ] https://medium.com/nttlabs/runc-overview-263b83164c98• Low-level Container Runtime:Runc Internals https://kurobato.hateblo.jp/entry/2021/05/02/164218• opencontainers/runc https://github.com/opencontainers/runc• containers/youki https://github.com/containers/youki
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠
Q&A