The introduction of mRuby on Container /mruby-on-container

2cf373725ded741824c50fd571eda6e1?s=47 KONDO Uchio
September 08, 2016

The introduction of mRuby on Container /mruby-on-container

@ RubyKaigi 2016, Kyoto
2016/09/08
#container #linux

2cf373725ded741824c50fd571eda6e1?s=128

KONDO Uchio

September 08, 2016
Tweet

Transcript

  1. 5IF N 3VCZPO$POUBJOFS 6DIJP,POEP(.01&1"#0JOD 4FQUI 3VCZ,BJHJ 8FMDPNFUPNZIBDPOJXB

  2. 4PGUXBSF%FWFMPQFS1SJODJQBM 6DIJP,POEP (.01FQBCP *OD%FW1SPEVDUJWJUZ3%5FBN

  3. 6DIJP,POEP !VE[VSB *TBOZP3VCZJTU POFPG 'VLVPLBSCDPPSEJOBUPST  3BJMT(JSMT'VLVPLB0SHBOJ[FST BOEBTZTUFNQSPHSBNNJOHOPWJDF 0OFPGUIFBVUIPSTPG
 l5IF1FSGFDU3VCZz

    l5IF1FSGFDU3VCZPO3BJMTz #PUIJO+BQBOFTF
  4. 'VLVPLB !VE[VSBJTGSPN'VLVPLB #VUCFJOHB.JLBXB4BNVSBJJOIJTIFBSU  'VLVPLBJTMPDBUFEJOUIFl8FTUz +BQBO XIJDIJTBl$PBTUzDJUZ -FU`TWJTJU'VLVPLBSC GSPNIUUQTIPXDBTFDJUZGVLVPLBMHKQBMMSJHIUTSFTFSWFE

  5. .ZDPOUBJOFSCBTFECBDLHSPVOE 

  6. #FGPSFUIF9EBZ*EFDJEFEUPDSFBUFIBDPOJXB w *IBWFCFFOFYQFSJFODFELJOETPGDPOUBJOFST w %PDLFSGPSBOJOIPVTF$*CBTJT w -9$GPSB1BB4QSPWJEFECZNZDPNQBOZ TRBMFKQ

  7. %PDLFSGPSJOIPVTF$* w ESPOFJP 044WFSTJPO

  8. %SPOFJP w %SPOFVTFT%PDLFSBTBOFQIFNFSBM$*DPOUBJOFSCBDLFOE w %SPOFBOE%PDLFSJTTPDPPM CVU*NFU w 4PNFTUSBOHFCVHT w *ODSFBTJOHBNPVOUPGPQFSBUJPOT

  9. FH*TTVF 8IFOUSZJOH%PDLFSJO%PDLFS VTFGVM GPS*OGSB$*  TPNFQBDLBHFTNBEFUSPVCMFJO JOTUBMMJOH FTQFDJBMMZIUUQE BOE TZTUFNE

     5IJTJTCFDBVTFPMEFSWFSTJPOTPGBVGT CVJMEEPFTO`UTVQQPSUpMFDBQBCJMJUJFT
 #VU*DPVMEOPUEFTDSJCFUIFCVHJO EFUBJMBUUIBUUJNF
  10. 0QFSBUJPOT PQFSBUJPOT w &WFSZEBZIBSEEJTLDMFBOVQPQFSBUJPOʜʜ • docker ps -a | \


    grep Exited | \
 awk '{ print $1 }' | \
 xargs docker rm -f w *ODSFBTJOH-" $16VTBHF NFNPSZʜʜ w *XBTMFTTGBNJMJBSBOEIBEMFTTLOPXIPXTBCPVU%PDLFSPSDPOUBJOFST JOUFSOBM TP*IBETPNFUSPVCMFT
  11. 4RBMF w *TB1MBUGPSNBTB4FSWJDF w 1SPWJEFECZ(.01FQBCP

  12. -9$JO4RBMF w -9$MPPLFENPSFMJHIUXFJHIUBOEVOEFSTUBOEBCMFUPNFUIBOEPDLFS w FH w $BOVTFCJOENPVOUSBUIFSUIBOBVGT PSBMJLF  w

    $BODIPPTFOPOFUXPSLJTPMBUJPO QMBZJOHJTPMBUJPOJOTJEFUIFDPOUBJOFS
 TPVOEFSTUBOEBCMFBOEDPOUSPMMBCMFGPSNFBUUIBUUJNF
  13. #VUʜʜ w *NFUTPNFEJTDPOUFOUBHBJOJOPQFSBUJPO w FHSFTPVSDFSFBMMPDBUJPO w DQVTFUSFBMMPDBUJPOJTEPOFCZSFHFOFSBUJOHDPOpHXJUIDIFGJO4RBMF w 0UIFSSFTPVSDFSFBMMPDBUJPOTBSFEPOFCZIBOE FHNFNPSZMJNJU

     w "OE*IBEBDPOqJDUJOVQHSBEJOH-9$JUTFMG w #FDBVTFXFXFSFVTJOHWFSZFBSMZ-9$
  14. $PODMVTJPO w *IBEUPTUVEZIBSEFSBCPVUDPOUBJOFSTʜʜ w *XJTIFEUPIBWFBCSBOEOFXDPOUBJOFSFOHJOFXIJDIFOBCMFVT w UPDPNCJOFDPOUBJOFSTZTUFNBUUSJCVUFTJOBDDPSEBODFXJUIPVSDIPJDF w UPDIBOHFUIFTFTZTUFNBUUSJCVUFTCZEZOBNJDQSPHSBNNJOH w

    4P*IBWFDSFBUFEIBDPOJXB )BDPOJXBTJHOJpFTBNJOJBUVSFHBSEFOJO+BQBOFTF BOE$JOWPMWFT$0/UBJOFS
  15. "TNBMMUPVSPG)BDPOJXB 

  16. *OTUBMMBUJPO w 1BDLBHFTBSFBWBJMBCMFJOQBDLBHFDMPVE
 IUUQTQBDLBHFDMPVEJPVE[VSBIBDPOJXBJOTUBMM # example for deb-ish distro curl

    -s https://packagecloud.io/install/repositories/udzura/ haconiwa/script.deb.sh | sudo bash apt-get update apt-get install haconiwa apt-get install lxc lxc-templates # Required to bootstrap fs
  17. 'JSTU DSFBUFUIFDPOpHpMFGSPNCPJMFSQMBUF $ haconiwa new test.haco assign new haconiwa name

    = haconiwa-0491a405 assign rootfs location = /var/lib/haconiwa/0491a405 create test.haco
  18. 5IFpMFMPPLTMJLFKVTUBTNBMMSVCZTDSJQU

  19. 3VOUIFCPPUTUSBQWJBlIBDPOJXBDSFBUFz w 5IFOUIFBMQJOFMJOVYJTCFJOHCPPUTUSBQQFECZEFGBVMU

  20. *OTUBMMTTIE DIBOHFTTIEDPOpH Haconiwa.define do |config|
 #...
 config.provision do |p| p.run_shell

    <<-SHELL apk add --update openssh sed -i 's/#Port.*/Port 2222/' /etc/ssh/sshd_config # NOTE: insecure but an example below sed -i 's/#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config sed -i 's/#PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config echo root:r00t | chpasswd ssh-keygen -t rsa -P "" -f /etc/ssh/ssh_host_rsa_key SHELL end #... end
  21. lIBDPOJXBQSPWJTJPOzUPQSPWJTJPOBHBJO

  22. $IBOHFlJOJUzDPNNBOEUPTTIE UIFOJOWPLFlSVOz Haconiwa.define do |config| # The container name and

    container's hostname: config.name = "haconiwa-0491a405" # The first process when invoking haconiwa run: # config.init_command = "/bin/bash" # To: config.init_command = %w(/usr/sbin/sshd -D) # And uncomment: config.daemonize!
 #...
 end $ haconiwa run test.haco
  23. None
  24. EFNPIUUQTDMPVEHJUIVCVTFSDPOUFOUDPNBTTFUTBEGGFBFFDBFCCFBHJG

  25. 'JOBMMZ SVOlIBDPOJXBLJMMzUPLJMMTTIEDPOUBJOFS $ haconiwa kill test.haco Kill success

  26. .PSFBCPVU%4- w :PVDBODPOpHVSFOBNFTQBDF DHSPVQ DBQBCJMJUZ NPVOUQPJOU MJNJU TFUVJE TFUHJEʜʜWJBIBDPpMF JGOFDFTTBSZ

    TFFDPNNFOUT  w #PJMFSQMBUF`TEFGBVMU w *UVOTIBSFTOBNFTQBDFTVUTJQDQJENOUCVUOFUVTFS w *USFNPVOUTTPNFNPVOUQPJOUTJOBOFXOBNFTQBDF FHQSPD TZT
  27. $PODMVTJPOPGUIJTTFDUJPO w )BDPOJXBDBOCFJOTUBMMFEBTQBDLBHFT
 $FOU04%FCJBOKFTTJF6CVOUVUSVTUZBOEYFOJBM  w )BDPOJXBTVQQPSUTUIFTFDPOUBJOFSPQFSBUJPOT w OFXDSFBUFSVOBUUBDILJMM w

    :PVDBODPNCJOFDPOUBJOFSGVODUJPOBMJUJFTVTJOHIBDPpMF`T%4-
 4FFDPNNFOUTPOHFOFSBUFEPOF
  28. $POUBJOFSUFDIOPMPHZPWFSWJFX 

  29. "GUFSJOTUBMM)BDPOJXB w 5IFSFBSFUXPFYUSBCJOBSJFT w IBDPSC w IBDPJSC w 5IFZBSFKVTUNSVCZBOENJSCCJOBSJFT XIJDIBSFFNCFEEFEXJUIDPOUBJOFS

    NHFNT
  30. -FU`TTUVEZDPOUBJOFSXJUINSVCZ

  31. 8IBUXFDBMM -JOVY DPOUBJOFS w *TDPNQPTFEXJUITPNF-JOVYGFBUVSFT w -JOVY/BNFTQBDF w DISPPUCJOENPVOU w

    DHSPVQT w -JOVYDBQBCJMJUJFT w SFTPVSDFMJNJUT TFUVJETFUHJEʜʜ
  32. -JOVYOBNFTQBDF w -JOVYOBNFTQBDFQSPWJEFTUIFQBSUJUJPOTJO04SFTPVSDFT w FH w 654/BNFTQBDF4FQBSBUFTIPTUOBNFGSPNIPTUNBDIJOF w 1*%/BNFTQBDF$PVOUTVQ1SPDFTT*%TBHBJO w

    .PVOU/BNFTQBDF4FQBSBUFTNPVOUQPJOUJOGPSNBUJPOGSPNIPTU w 0UIFST*1$ /FUXPSL 6TFS $(SPVQ
  33. /BNFTQBDFVOTIBSFUPTFF654OBNFTQBDF puts "Before unshare:" RunCmd.new("sample1").run "uname -a" # This puts

    “localhost” # Then unsure the UTS namespace Namespace.unshare Namespace::CLONE_NEWUTS Procutil.sethostname "rubykaigi.example.org" puts "After new namespace:" RunCmd.new("sample1").run "uname -a" # This puts “rubykaigi.example.org” and parent remains unchanged
  34. DISPPUBOECJOENPVOU w DISPPU  DISPPU   w $IBOHFTUIFSPPUEJSFDUPSZPGUIFDBMMJOHQSPDFTT w

    CJOENPVOU w *TVTFGVMUPVTFTPNFEJSFDUPSJFTPSpMFTGSPNBOPUIFSMPDBUJPO w 0SUPBEETPNFTVCEJSFDUPSJFTFYUSBBUUSJCVUFT FHSFBEPOMZ
  35. FH04EJSFDUPSZUSFFVOEFSIPTU04TVCEJSFDUPSZ w lDISPPUzJOUPIFSFUPFOUFSBOJTPMBUFEpMFTZTUFN

  36. /BNFTQBDF DISPPUTNBMMFTUDPOUBJOFS # The smallest container with mruby: Namespace.unshare(Namespace::CLONE_NEWNS|Namespace::CLONE_NEWPID) m

    = Mount.new m.make_private "/" root = "/var/lib/haconiwa/125f23ef" m.bind_mount root, root, readonly: true # To make readonly Dir.chroot root Dir.chdir "/" c = Process.fork { m.mount "proc", "/proc", :type => "proc" Exec.exec "/bin/sh" } puts "Container exited: #{Process.waitpid2(c).inspect}"
  37. 5IFTNBMMFTUDPOUBJOFSJOMJOFT

  38. DHSPVQT $POUSPM(SPVQT w 5IFGFBUVSFPG-JOVYLFSOFM w 5IJTlQSPWJEFTGPSHSPVQJOHPGUBTLTBOESFTPVSDFUSBDLJOHBOEMJNJUBUJPOTGPS UIPTFHSPVQTz GSPNNBODHSPVQT  

    w 5IJTGFBUVSFGPSIBOEMJOHSFTPVSDFTCZHSPVQTPGUBTLTJTVTFGVMUPNBLF
 lBDPOUBJOFS JOEFFEBHSPVQPGQSPDFTTFT zMPPLTMJLFBOJOEJWJEVBM04
  39. FHDQVTFUMJNJUBUJPOCZDHSPVQ cpuset = Cgroup::CPUSET.new "rubykaigi001" cpuset.cpus = "0-1"; cpuset.mems =

    "0" cpuset.create # Comment out to use full-core cpuset.attach def fib(n); n < 2 ? 1 : fib(n-2) + fib(n-1); end procs = (1..4).to_a.map do Process.fork do loop { fib(rand(1000)) } end end procs.each {|pid| Process.waitpid pid }
  40. -JNJUUIFDPSFTUPVTF /PDHSPVQ DQVTFUDQVT

  41. -JOVYDBQBCJMJUJFT w 5SBEJUJPOBMlSPPUzIBTTVQFSQPXFSBOEUIJTJTUPPEBOHFSPVTJOTPNFDBTFT w -JOVYDBQBCJMJUJFTJTBOJEFBUPEJWJEFUIFQSJWJMFHFTJOUPEJTUJODUVOJUT w 8FDBODIPPTFKVTUUIFOFDFTTBSZVOJUTGPSPQFSBUJPOT

  42. FHESPQQJOHUJNFDPOUSPMQSJWJMFHFGSPNlSPPUz # Will be dropped after the process invoke execve(2)

    Capability.drop_bound Capability.from_name("cap_sys_time") exec "/bin/bash" # Then to be new program... root@localhost:~# hacorb mruby/caps.rb # new process below root@localhost:~# date -s 'Thu, 21 Dec 95 14:44:05 JST' date: cannot set date: Operation not permitted # even a root Wed Dec 20 21:44:05 PST 1995 root@localhost:~# date Thu Aug 25 20:40:59 PDT 2016 # unchanged
  43. 0UIFST w 3FTPVSDFDPOUSPM SMJNJU 0OFTXFVTFWJBVMJNJU w TFUVJETFUHJE$POUSPMMJOHFGGFDUJWFSFBMVTFS*%JTJNQPSUBOUGPSBDPOUBJOFS w 0UIFSTPDBMMFEDPOUBJOFSGFBUVSFTTVDIBTB4&-JOVYQPMJDZBSFOPU TVQQPSUFECZDVSSFOUIBDPOJXB

    TPSSZCVUMFUNFTLJQʜ
  44. $PODMVTJPOUIFDPOUBJOFSXFDBMMJT *TPMBUJPOT -JOVYOBNFTQBDF DISPPU CJOENPVOU ʜ -JNJUBUJPOT DHSPVQT DBQBCJMJUJFT SFTPVSDFMJNJU

    ʜ 8JUIUIFTF UIFlQSPDFTTzDBOCFUSFBUFEBTBOl04zCZEFWFMPQFST "OEUIFTFDBOCFDPOUSPMMFECZIBDPOJXB`T3VCZ%4-
  45. ':*0$*TQFDJpDBUJPOT w *UEFpOFTXIBUGFBUVSFTUPCFTVQQPSUFECZ0$*DPOUBJOFS
 FH/BNFTQBDFT $POUSPMHSPVQT 1SPDFTTDPOpHVSBUJPO TVDIBTDBQBCJMJUJFT 6TFS OBNFTQBDFNBQQJOHT TFDDPNQʜʜ

    w IUUQTHJUIVCDPNPQFODPOUBJOFSTSVOUJNFTQFDCMPCNBTUFSDPOpHNE w IUUQTHJUIVCDPNPQFODPOUBJOFSTSVOUJNFTQFDCMPCNBTUFSDPOpHMJOVYNE w #58 0$*TQFDSFGFSTUPMJOVYBOETPMBSJTTQFDJpDDPOpH w *UJTMJLFMZUIBU)BDPOJXBDBOQSPWJEFUIFBCTUSBDUMBZFSGPSSFTPVSDF MJNJUBUJPO OBNFTQBDF pMFTZTUFN CFUXFFOLFSOFMT w *UXJMMCFSFMFBTFEGBSJOUIFGVUVSF NBZCF
  46. )BDPOJXBBOENSVCZ BOENSVCZJTHPPEGPSTZTUFNQSPHSBNNJOH 

  47. "WFSZTIPSUIJTUPSZPG)BDPOJXB

  48. 'JSTUJNQMFNFOUBUJPOPG)BDPOJXB w *O$3VCZ w /BNFTQBDFIBOEMJOHCZ,FSOFMTZTDBMM w %JSDISPPUNPVOU  DBMMCZ,FSOFMTZTUFN w

    %PJOHBpMFPQFSBUJPO PQFOSFBEXSJUF GPSDHSPVQ w 6TJOH''*GPSDBQBCJMJUJFT EFQFOEFOUPOMJCDBQ  w "OE1SPDFTTGPSL,FSOFMFYFDUIFHPMEFOUXJO
  49. *UXPSLT CVUʜʜ w 5IFSFXFSFTPNFXPSSJFT

  50. &TQFDJBMMZ TPNFSFTUSJDUJPOTJOTZTUFNDBMMT w $3VCZJTJOWPLFEJONVMUJUISFBEFENPEF 5IJTJTCFDBVTFPGBUJNFSUISFBEXIJDIJTVTFGVMUPBMNPTUBMMPGMBOHVBHFVTF DBTFT#VUʜʜ [vagrant@udzura ~]$ ruby -e

    'loop { sleep 1 }' & [1] 7560 [vagrant@udzura ~]$ ls -l /proc/7560/task/ total 0 dr-xr-xr-x 6 vagrant vagrant 0 8݄ 25 11:38 7560 dr-xr-xr-x 6 vagrant vagrant 0 8݄ 25 11:38 7561
  51. *OTQFDUJOHNBOBCPVUOBNFTQBDFTZTDBMMT w NBOQBHFPGVOTIBSF   w $-0/&@/&81*% TJODF-JOVY ʜʜ
 $-0/&@/&81*%BVUPNBUJDBMMZJNQMJFT$-0/&@5)3&"%BTXFMMʜʜ


    
 &33034
 &*/7"-$-0/&@5)3&"% $-0/&@4*()"/% PS$-0/&@7.XBTTQFDJpFE JOqBHT BOEUIFDBMMFSJTNVMUJUISFBEFE w IUUQNBOPSHMJOVYNBOQBHFTNBOVOTIBSFIUNM
  52. *OTQFDUJOHNBOBCPVUOBNFTQBDFTZTDBMMT   w NBOQBHFPGTFUOT   w "QSPDFTTNBZOPUCFSFBTTPDJBUFEXJUIBOFXNPVOUOBNFTQBDFJGJUJT NVMUJUISFBEFE

    w "NVMUJUISFBEFEQSPDFTTNBZOPUDIBOHFVTFSOBNFTQBDFXJUITFUOT  w ʜʜ w IUUQNBOPSHMJOVYNBOQBHFTNBOTFUOTIUNM
  53. 4P3VCZJNQMFNFOUBUJPODIPTF w 5PDSFBUFVOTIBSFEQSPDFTT w DSFBUFTBUFNQPSBSZTIFMMpMFBOEUIFOQBTTJUUPVOTIBSF   w 5PBUUBDIFYJTUJOHOBNFTQBDF w

    JUMBSHFMZEFQFOETPOOTFOUFS   w 5IFTFBSFʜʜ5IFTFBSFVOEFTJSBCMFTUSBUFHZ VHMZQSPDFTTMBZPVU
  54. 4P*EFDJEFEUPSFXSJUF JONSVCZ

  55. 3FXSJUFJONSVCZʜʜ w 5IJTFOETVQUPCFBHPPEDIPJDFUPNFJOTPNFSFBTPO w *`NHPJOHUPEFTDSJCF

  56. (SFBUFYJTUJOHNSCHFNT w MJCDHSPVQNSVCZXSBQQFSCZNBUTVNPUPSZ w MJCDBQNSVCZXSBQQFSCZNBUTVNPUPSZ w TNBMMVOTIBSF  XSBQQFSCZIJSPLBXB OPU*%IBDPOJXB

     w **+`THSFBUNSCHFNT FTQFDJBMMZNSVCZEJSBOENSVCZQSPDFTT
  57. NSVCZ`T$"1*GPSXSBQQJOH$MJCSBSZDBMM w *IBEUPJNQMFNFOUTPNFNSCHFNT BMNPTUPGXIJDIBSFXSBQQJOHTPNF$ MFWFMTZTUFNDBMMTPS$MJCSBSZGVODUJPOT w #VUUIJTXBTBFBTJFSKPCUIBO*FYQFDUFE

  58. &YBNQMFNSVCZMJOVYOBNFTQBDF w 8SJUFBTNBMMGVODUJPOXJUIBOBJWFVTFPGTFUOT   w 5IFOBUUBDIUPBNPEVMF static mrb_value mrb_namespace_setns_by_fd(mrb_state

    *mrb, mrb_value self) { mrb_int fileno, nstype; int ret; mrb_get_args(mrb, "ii", &fileno, &nstype); ret = setns((int)fileno, (int)nstype); if (ret < 0) { mrb_sys_fail(mrb, "setns failed"); } return mrb_fixnum_value(ret); } /* ... */ void mrb_mruby_namespace_gem_init(mrb_state *mrb) { struct RClass *namespace; namespace = mrb_define_class(mrb, "Namespace", mrb->object_class); mrb_define_class_method(mrb, namespace, "setns_by_fd", mrb_namespace_setns_by_fd, MRB_ARGS_REQ(2)); }
  59. 'PS3VCZJTI"1*MPPLT KVTUEPXSJUF w *IBWFJNQMFNFOUFEVTFSGSJFOEMZQBSBNFUFSBSHVNFOUTJOUIFSVCZMBZFS class Namespace def self.setns(flag, options) fd

    = options[:fd] pid = options[:pid] if fd setns_by_fd(fd, flag) elsif pid setns_by_pid(pid, flag) else raise ArgumentError, "Options :fd or :pid must be specified" end end end
  60. NSVCZBTBl$zGSBNFXPSL w NSVCZQSPWJEFTNBOZGVODUJPOBMJUJFTUIBUBSFVTFGVMJOXSJUJOH$ w ($ SFTPVSDFMJGFDZDMFNBOBHFNFOU w TUSJOHBSSBZIBTIUBCMFPCKFDUBOEGVODUJPOTGSJFOEMZUPIBOEMF w 6TFSJOQVU

    BTBSVCZDPEF $XPSMENBQQFS NSC@HFU@BSHTNSC@ @WBMVF
  61. FHSFTPVSDFMJGFDZDMFNBOBHFNFOU w NSVCZIBT($ w :PVKVTUDBO w CJOEZPVS$PCKFDUUP
 3VCZPCKFDUXIFODSFBUFE w SFHJTUFSUIFGSFFJOHGVODUJPO


    GPS$PCKFDU
 XIFO3VCZPCKFDUJT($`FE static void mrb_cap_context_free(mrb_state *mrb, void *p) { mrb_cap_context *ctx = (mrb_cap_context *)p; cap_free(ctx->cap); mrb_free(mrb, ctx); } static const struct mrb_data_type mrb_cap_context_type = { "mrb_cap_context", mrb_cap_context_free, }; mrb_value mrb_cap_init(mrb_state *mrb, mrb_value self) { mrb_cap_context *cap_ctx; //... DATA_TYPE(self) = &mrb_cap_context_type; DATA_PTR(self) = cap_ctx; //... } &YBNQMFBUNSVCZDBQBCJMJUZ
  62. FHl4USJOHzIBOEMJOHBOETPPO w )VNBOTXBOUFEUPBWPJEEJSFDUMZIBOEMJOHPGDIBS<>`T w NSVCZ`T4USJOHDMBTTQSPWJEFT w 3FTPVSDFIBOEMJOHJO3VCZMBZFS w 4USJOHNPEJpDBUJPOUPPMDIBJOT w

    :PVDBODBMM3VCZ`TQPXFSGVMBOE
 qFYJCMF4USJOHNFUIPETFWFOJO
 $XPSME w 'PSBSSBZIBTIBOEPUIFSPCKFDUT 
 TBNFBTBCPWF mrb_value member; mrb_get_config_value(mrb, "member", "o", &member); mrb_value mnum = mrb_funcall(mrb, member, "size", 0); int i; int seki_num = mrb_fixnum(mnum); for (i = 0; i < seki_num; i++) { mnum = mrb_funcall(mrb, member, "size", 0); mrb_value seki = mrb_funcall(mrb, mrb_top_self(mrb), "rand", 1, mnum); mrb_p(mrb, mrb_funcall(mrb, member, "[]", 1, seki)); mrb_funcall(mrb, member, "delete_at", 1, seki); } 5IFlTFLJHBFNSVCZzDPEF IUUQTHJUIVCDPNNBUTVNPUPSNSVCZDPOpHCMPCNBTUFSFYBNQMFTFLJHBFTFLJHBFD
  63. NSVCZDMJGPSDPNNBOEMJOFUPPM w 7FSZIFMQGVMGPSJNQMFNFOUJOHBDPNNBOE BOEJU`TCJOBSZ  w haconiwaCJOBSZJTDSFBUFEVOEFSUIFNSVCZDMJEJSFDUPSZMBZPVU UIBOLT w *IBWFBEEFETPNFDVTUPNJ[BUJPOTUP3BLFpMF

    w FH w NSVCZWFSTJPOMPDLFSDIFDLTPVUTQFDJpDWFSTJPOPGNSVCZGSPNHJUIVCXIFOCVJMEJOH w NSVCZNSCHFNWFSTJPOEFUFDUPS w POCVJMEJOH HFOFSBUFTBpMFXIJDIIBTBMMPGNSCHFNBOENSVCZWFSTJPOIBTIFT JTQPTTJCMF BOEUIFO FNCFETUIJTUPBDPNNBOE w "OE*IBWFDSFBUFENSVCZBSHUBCMFGPSQBSTJOHBSHVNFOUT  w IUUQTHJUIVCDPNVE[VSBNSVCZBSHUBCMF
  64. ':*UIFDPOUBJOFSNSCHFNT*VTFPSDSFBUF GFBUVSFT DPVOUFSQBSUNSVCZHFN -JOVYOBNFTQBDF mruby-linux-namespace DISPPUBOECJOENPVOU mruby-dir mruby-mount(*) DHSPVQT mruby-cgroup

    -JOVYDBQBCJMJUJFT mruby-capability 3FTPVSDFMJNJUT mruby-resources 0UIFST GPSLFYFDXBJU mruby-process mruby-exec(*) w "DUVBMMZ UIFTFBSFBMSFBEZVTFECZUIFIBDPSCFYBNQMF OPUQVCMJTIFEUPNHFNMJTU
  65. $PODMVTJPOPGUIJTQBSU w 'PSPOFTXIPBSFPCMJHFEUPVUJMJ[FTZTUFNDBMMTPS$MJCSBSJFT 
 NSVCZ`TFDPTZTUFNBOE"1*TIPVMECFBIFMQ w NSVCZWFSTJPOPG)BDPOJXBJTXSJUUFOJOKVTUNPOUIT QPXFSFECZNSVCZ

  66. $POUBJOFSBT$PEF  0SDIFTUSBUJPOBT$PEF 

  67. /PXUIBUXFIBWF)BDPOJXB w 8JUI)BDPOJXB XFDBODPNCJOFBOEDPOUSPMMJOVYDPOUBJOFSGFBUVSFTCZ XSJUJOHNSVCZDPEF w *OPUIFSXPSET XFIBWFSFBMJ[FEUIF$POUBJOFSBT$PEF w /PUFUIJTJTVOEFSIFBWZEFWFMPQNFOU

  68. #VUXIBUXFXBOUJOSFBMPQTXPSMEJT w 5IFXBZUPDPOUSPM w )PXUPEFQMPZNVMUJQMFDPOUBJOFST w )PXUPJODSFBTFPSEFDSFBTFDPOUBJOFST w )PXUPMJOLNVMUJQMFDPOUBJOFSTJONVMUJQMFSPMFT w

    ʜʜJOFBTZBOEqVFOUNBOOFS w BLB5IFMBZFSPG0SDIFTUSBUJPO
  69. 0SDIFTUSBUJPOBT$PEF FTQFDJBMMZGPSDPOUBJOFST

  70. *IBWFOPTJMWFSCVMMFUBCPVUUIJTRVFTUJPO w #VU CVUIBWFBGFXJEFBT w 3FTUPGUIFQSFTFOUBUJPOXJMMCFVTFEGPSUIFTFESFBNZUIPVHIUT

  71. #58DVSSFOUMZIBDPOJXBTVQQPSUT w 4JNQMFDMVTUFSJOHXJUIFUDECBDLFOE w 0WFSMBZOFUXPSLJOHVTJOHqBOOFM FUDEBOEOFUOT config.namespace.enter "net", via: "/var/run/netns/haco001"

  72. EFNPIUUQTDMPVEHJUIVCVTFSDPOUFOUDPNBTTFUTGDFFBFEFDBFBHJG

  73. &YQFSJNFOUBMlIBDPOJXBXBUDIzDPNNBOE w $BVUJPO5IJTJTFYQFSJNFOUBMPGFYQFSJNFOUBMOFTT w 5IFTQFDXJMMEFpOJUFMZDIBOHF

  74. 1SFQBSFDPOUBJOFSCBTFBT Haconiwa.define do |config| suffix = UUID.secure_uuid("%4x%4x") config.name = "haconiwa-#{suffix}"

    config.init_command = ["/bin/sleep", UUID.secure_random(30..60).to_s] config.daemonize! root = Pathname.new("/var/lib/haconiwa/common") config.chroot_to root #... end
  75. 1SFQBSFXBUDIFS%4-BT Haconiwa.watch do |config| config.watch :cluster do |event| if event.cluster.count

    < 5 # Should be spawned 1 by 1 Haconiwa.spawn "/etc/haconiwa/haco.d/sleeper.haco" end end end
  76. 5IFOSVOUIFXBUDIJOH%4- $ haconiwa watch process-keeper.rb Registered: cluster ……

  77. $PVOUPGDPOUBJOFSTXJMMCFLFQUUP

  78. *OUIFGVUVSF CFESFBNJFSBOENPSFBNCJUJPVT w &WFOU%4-DBOCFSFHJTUFSFEUPFUDE PSTPNFXIFSFHPPETUPSBHF  w &BDIDPOUBJOFSTVQFSWJTPSNJHIUCFMJOLFEJOBXFBLSFMBUJPOTIJQ 
 BOEUIFOFMFDUUIFMFBEFS

    
 UIFOUIFMFBEFSDBOXBUDIUIFDMVTUFSBOEpSFUIFSFHJTUFSFEFWFOUT w 5IJTMPPLTMJLFBLFSOFMMFTT 410'MFTTBSDIJUFDUVSFUIBUNBZCFXPSLT w #VUOPJNQMFNFOUBUJPOZFUʜ  w *IBWFGPVOENSVCZ$JNQMFNFOUBUJPOPGSBGU TP*`MMUSZOFBSGVUVSF
  79. 4VQFSWJTPS 5IF$POUBJOFS 1SPDFTT FUDE FUDE FUDE 0WFSMBZ/FUXPSLT 4VQFSWJTPS 5IF$POUBJOFS 1SPDFTT

    4VQFSWJTPS 5IF$POUBJOFS 1SPDFTT 47TBSF$MVTUFSECZ3BGU 5IF)PTU "1*BDDFTT
  80. $PODMVTJPOPGUIJTUBML 

  81. l$POUBJOFSzJTBDPNCJOBUJPO w $PNQBSFl5IF6/*9QIJMPTPQIZz w &BDIGFBUVSFJTTNBMMFOPVHIBOEFBTJFSUPMFBSOUIBOZPVFYQFDU w *OEFFE ZPVDBOUSZUIFTFMJOVYGFBUVSFTTFQBSBUFMZ CZNSVCZ

  82. NSVCZJTWFSZHPPEGPSTZTUFNQSPHSBNNJOH w NSVCZIBTDPPMBOEXFMMEFTJHOFE$"1*T w 5IJOFOPVHIUPFBTJMZXSBQTZTUFNDBMMT$MJCSBSJFT

  83. 8FXJMMCFBCMFUPDPOUSPMDPOUBJOFSTCZDPEFT w 8FDBOEPJUEFpOJUFMZXJUINSVCZ w $POUBJOFSUFDIOPMPHZJTUIFneighPGPSDIFTUSBUJPO w 8JUIIBDPOJXBBOENSVCZ JUTIPVMECFBSFBMGVUVSFUIBUCPUIDPOUBJOFSTBOE PSDIFTUSBUJPOXJMMCFVOEFSDPOUSPM DBUDIJOHVQXJUIEZOBNJDFOWJSPONFOU

    DIBOHFT
  84. 5IFDPOUBJOFSTBTUIFDFMMTPGUIFPSHBOJTN w 5IJTEPFTOUMPPLMJLFBGBJSZUBMFGPSNF w BOEGPSNBUTVNPUPSZNBZCF

  85. 5IFqVFOUTZTUFN

  86. ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ

  87. 4QFDJBM5IBOLT w "MMPGQIPUPTGSPNIUUQTIPXDBTFDJUZGVLVPLBMHKQ w 1SPWJEFECZ'VLVPLB$JUZ 8FXFMDPNFFOHJOFFSTNPWJOHUP'VLVPLB  w FYDFQUDFMMTQIPUPIUUQXXXQVCMJDEPNBJOQJDUVSFTOFUWJFXJNBHFQIQ JNBHF

    1%  w &OHMJTISFWJFXFSCZ!@[[BL UIBOLT
  88. 3FGFSFODFT w 3FGFSFODFT BMMJO+BQBOFTF  w 4RBMFTUBMLPGNJOF w IUUQTTQFBLFSEFDLDPNVE[VSBQIQQBBTTRBMFXP[IJFSVKJTIV w

    $POUBJOFSUVUPSJBMT w IUUQTTQFBLFSEFDLDPNIBZBKPUVLVUVUFYVFCVMJOVYLPOUFOBGBMTFMJDF CZ!IBZBKP  w IUUQTTQFBLFSEFDLDPNUFOGPSXBSEPTDLZPUP CZ!UFOGPSXBSE  w IUUQTTQFBLFSEFDLDPNVE[VSBUIFTLFMUPOPGXIBMFT
  89. ܅΋ϖύϘͰಇ͔ͳ͍͔ʁ 8FBSFIJSJOH !QC@SFDSVJU w 1MFBTFUBMLUPNF
 JGZPV`SFJOUFSFTUFEJO3VCZ NSVCZ DPOUBJOFS 1PLÉNPO(0PSUIFSPDLCBOE1BWFNFOU