Slide 1

Slide 1 text

̍೥΄Ͳ%$04Λӡ༻ ͯ͠Έͨ࿩

Slide 2

Slide 2 text

ࣗݾ঺հ ࿨ా ږ @wappy100 גࣜձࣾαΠόʔΤʔδΣϯτ ɹΞυςΫຊ෦ ΞυςΫελδΦͷϩά෼ੳج൫ͷΠ ϯϑϥݟͯ·͢ DC/OS, k8s, Hadoop, Kafka

Slide 3

Slide 3 text

DC/OSͬͯԿʁ

Slide 4

Slide 4 text

• ίϯςφΦʔέετϨʔγϣϯΤϯδϯ • Mesosphereࣾ੡OSS • Data Center Operating System • Mesos / Marathon / Metronome / Spartan / Minuteman / …

Slide 5

Slide 5 text

ΞʔΩςΫνϟ

Slide 6

Slide 6 text

ΞʔΩςΫνϟ

Slide 7

Slide 7 text

ΞʔΩςΫνϟ

Slide 8

Slide 8 text

ΞʔΩςΫνϟ .FTPTNBTUFSͱͳΔ/PEF Ϧιʔε੍ޚ΋Ζ΋Ζ΍ͬͯ͘ΕΔ

Slide 9

Slide 9 text

ΞʔΩςΫνϟ

Slide 10

Slide 10 text

ΞʔΩςΫνϟ ֎෦ެ։༻/PEF αʔϏεΛ֎෦ެ։͢Δࡍ͸͜ͷ /PEFΛܦ༝ͯ͠ΞΫηεͤ͞Δ

Slide 11

Slide 11 text

ΞʔΩςΫνϟ

Slide 12

Slide 12 text

ΞʔΩςΫνϟ 8PSLFSͱͳΔ/PEF ΞϓϦέʔγϣϯͳͲ഑ஔ͞ΕΔͷ͸ίί

Slide 13

Slide 13 text

Πϯετʔϧ

Slide 14

Slide 14 text

DC/OSΠϯετʔϧ

Slide 15

Slide 15 text

#PPUTUSBQ /PEF DC/OSΠϯετʔϧ Πϯετʔϧॲཧ༻/PEFΛ༻ҙ

Slide 16

Slide 16 text

#PPUTUSBQ /PEF DC/OSΠϯετʔϧ CPPUTUSBQ@VSMpMFPQUEDPT@JOTUBMM@UNQ DMVTUFS@OBNFDMVTUFSOBNF FYIJCJUPS@TUPSBHF@CBDLFOETUBUJD JQ@EFUFDU@QVCMJD@pMFOBNFQBUIUPJQTDSJQU NBTUFS@EJTDPWFSZTUBUJD NBTUFS@MJTU NBTUFSQSJWBUFJQ NBTUFSQSJWBUFJQ NBTUFSQSJWBUFJQ BHFOU@MJTU BHFOUQSJWBUFJQ BHFOUQSJWBUFJQ BHFOUQSJWBUFJQ BHFOUQSJWBUFJQ BHFOUQSJWBUFJQ QVCMJD@BHFOU@MJTU QVCMJDBHFOUQSJWBUFJQ SFTPMWFST TTI@QPSU TTI@VTFSVTFSOBNF ΫϥελఆٛϑΝΠϧΛ༻ҙ

Slide 17

Slide 17 text

#PPUTUSBQ /PEF DC/OSΠϯετʔϧ DVSM0IUUQTEPXOMPBETEDPTJPEDPTTUBCMFEDPT@HFOFSBUF@DPOpHTI ಾγΣϧΛμ΢ϯϩʔυ

Slide 18

Slide 18 text

#PPUTUSBQ /PEF DC/OSΠϯετʔϧ DVSM0IUUQTEPXOMPBETEDPTJPEDPTTUBCMFEDPT@HFOFSBUF@DPOpHTI TVEPCBTIEDPT@HFOFSBUF@DPOpHTIŠHFODPOG ಾίϚϯυΛ࣮ߦ

Slide 19

Slide 19 text

#PPUTUSBQ /PEF DC/OSΠϯετʔϧ DVSM0IUUQTEPXOMPBETEDPTJPEDPTTUBCMFEDPT@HFOFSBUF@DPOpHTI TVEPCBTIEDPT@HFOFSBUF@DPOpHTIŠHFODPOG TVEPCBTIEDPT@HFOFSBUF@DPOpHTIŠJOTUBMMQSFSFRT ಾίϚϯυΛ࣮ߦ

Slide 20

Slide 20 text

#PPUTUSBQ /PEF DC/OSΠϯετʔϧ DVSM0IUUQTEPXOMPBETEDPTJPEDPTTUBCMFEDPT@HFOFSBUF@DPOpHTI TVEPCBTIEDPT@HFOFSBUF@DPOpHTIŠHFODPOG TVEPCBTIEDPT@HFOFSBUF@DPOpHTIŠJOTUBMMQSFSFRT TVEPCBTIEDPT@HFOFSBUF@DPOpHTIQSFqJHIU ಾίϚϯυΛ࣮ߦ

Slide 21

Slide 21 text

#PPUTUSBQ /PEF DC/OSΠϯετʔϧ DVSM0IUUQTEPXOMPBETEDPTJPEDPTTUBCMFEDPT@HFOFSBUF@DPOpHTI TVEPCBTIEDPT@HFOFSBUF@DPOpHTIŠHFODPOG TVEPCBTIEDPT@HFOFSBUF@DPOpHTIŠJOTUBMMQSFSFRT TVEPCBTIEDPT@HFOFSBUF@DPOpHTIQSFqJHIU TVEPCBTIEDPT@HFOFSBUF@DPOpHTIEFQMPZ ಾίϚϯυΛ࣮ߦ

Slide 22

Slide 22 text

#PPUTUSBQ /PEF DC/OSΠϯετʔϧ DVSM0IUUQTEPXOMPBETEDPTJPEDPTTUBCMFEDPT@HFOFSBUF@DPOpHTI TVEPCBTIEDPT@HFOFSBUF@DPOpHTIHFODPOG TVEPCBTIEDPT@HFOFSBUF@DPOpHTIJOTUBMMQSFSFRT TVEPCBTIEDPT@HFOFSBUF@DPOpHTIQSFqJHIU TVEPCBTIEDPT@HFOFSBUF@DPOpHTIEFQMPZ TVEPCBTIEDPT@HFOFSBUF@DPOpHTIQPTUqJHIU ಾίϚϯυΛ࣮ߦ

Slide 23

Slide 23 text

#PPUTUSBQ /PEF DC/OSΠϯετʔϧ IUUQ\."45&3@/0%&@*1^ ʹΞΫηε

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

• ৗ࣌ىಈαʔϏε • Marathonఆٛ(json)Λॻ͍ͯσϓϩΠ Services

Slide 26

Slide 26 text

Marathonఆٛ { "id": "/test/app", "container": { "type": "DOCKER", "docker": { "image": “nginx", "network": "BRIDGE", "portMappings": [ { "containerPort": 80, "protocol": "tcp", "labels": { "VIP_0": “/test/apps:8889" } } ] } }, "instances": 3, "cpus": 1, "mem": 1024 }

Slide 27

Slide 27 text

• όονॲཧ༻εέδϡʔϥ • Metronomeఆٛ(json)Λॻ͍ͯσϓϩΠ • cronఆٛΛهड़ Jobs

Slide 28

Slide 28 text

Metronomeఆٛ { "id": "my-scheduled-job", "description": "A job that sleeps on a schedule", "run": { "cmd": "sleep 20000", "cpus": 0.01, "mem": 32, "disk": 0 }, "schedules": [ { "id": “sleep-nightly", "enabled": true, "cron": "20 0 * * *", "concurrencyPolicy": "ALLOW" } ] }

Slide 29

Slide 29 text

• ύοέʔδςϯϓϨʔτ؅ཧ • Πϯετʔϧ͢ΔͱMarathonఆٛʹै͍֤ΞϓϦέʔ γϣϯ͕σϓϩΠ͞ΕΔ • ࡉ͔͍ઃఆɺϋϯυϦϯάͳͲ೉͍͠ͷͰར༻͍ͯ͠ͳ͍ Universe

Slide 30

Slide 30 text

ӡ༻ࣄྫ ʢDC/OS 1.8.0ʙ1.9.0ʣ

Slide 31

Slide 31 text

1. εέʔϧΞ΢τ / Πϯͷ࿩ 2. ϩά·ΘΓͷ࿩ 3. MarathonϔϧενΣοΫͷ࿩ 4. Deployment͕ऴΘΒͳ͍࿩ 5. αʔϏεσΟεΧόϦো֐ͷ࿩

Slide 32

Slide 32 text

1. εέʔϧΞ΢τ / Πϯͷ࿩

Slide 33

Slide 33 text

ಉ྅ ʻʮෛՙࢼݧ͍ͨ͠ΜͰ ɹɹɹɹDC/OSΫϥελͰ͔͍ͨͬ͘͢͠ʯ ʮ͸͍ʯʼ ࿨ా

Slide 34

Slide 34 text

εέʔϧΞ΢τ؆୯ • bootstrap αʔόʹ͋Δ shell Λ͖࣋ͬͯͯ ৽نϗετͰ࣮ߦ͢Δ͚ͩ $ curl -O http://dcos-boot.example.com/dcos_install.sh $ sudo bash dcos_install.sh slave

Slide 35

Slide 35 text

ಉ྅ ʻʮෛՙࢼݧऴΘͬͨΜͰ ɹɹɹɹDC/OSΫϥελখ͍ͨͬ͘͢͞͠ʯ ʮ͸͍ʯʼ ࿨ా

Slide 36

Slide 36 text

ʮͲ͏΍ΔΜͩΖ͏ʯʼ ࿨ా

Slide 37

Slide 37 text

ͦΜͳ΋ͷ͸ͳ͍

Slide 38

Slide 38 text

৽نʹ࡞Γ௚ͯ͠ blue / green ʹͨ͠

Slide 39

Slide 39 text

2. ϩά·ΘΓͷ࿩

Slide 40

Slide 40 text

GUI͔ΒݟͯΔ

Slide 41

Slide 41 text

Metronome Job ࡞੒࣌

Slide 42

Slide 42 text

࿨ాʻʮJobsͷ΄͏ͷϩάݟΔ͔ʯ

Slide 43

Slide 43 text

࿨ాʻʮͲ͔͜ΒݟΔΜͩʯ

Slide 44

Slide 44 text

Marathonͷ΄͏͸ίί ίί

Slide 45

Slide 45 text

ݟΕͳ͍

Slide 46

Slide 46 text

ݟΕͳ͍

Slide 47

Slide 47 text

ݟΕͳ͍

Slide 48

Slide 48 text

ݟΕͳ͍

Slide 49

Slide 49 text

http://${MASTER_NODE}/mesos

Slide 50

Slide 50 text

Mesos Framework ͕ݟΕΔ

Slide 51

Slide 51 text

Task ͕ݟΕΔ

Slide 52

Slide 52 text

͋ͬͨ

Slide 53

Slide 53 text

3. MarathonϔϧενΣοΫͷ࿩

Slide 54

Slide 54 text

MarathonϔϧενΣοΫͬͯʁ { "id": “/tools/app1", "container": { "type": "DOCKER", "docker": { "image": “nginx” } }, "healthChecks": [ { "protocol": "HTTP", "path": "/health", "gracePeriodSeconds": 60, "intervalSeconds": 15, "timeoutSeconds": 10 } ], "backoffSeconds": 2, "backoffFactor": 1.2, "maxLaunchDelaySeconds": 1200, "taskKillGracePeriodSeconds": 60, • MarathonλεΫ͕ਖ਼ৗʹՔಇ͍ͯ͠Δ͔ͷϔϧε νΣοΫػߏ • httpΤϯυϙΠϯτɺίϚϯυ࣮ߦͳͲͷఆ͕ٛՄೳ

Slide 55

Slide 55 text

ಛఆͷ Marathon task ͕ Unhealty ʹͳͬͯ͠·͏ • kafka offset lag औಘ༻ʹ linkedin/burrow Λ ɹɹɹ DC/OS ্Ͱϗετ͍ͯͨ͠ • ͍͔ͭΒ͔ Unhealty ͱͳ͍ͬͯͨ ίί

Slide 56

Slide 56 text

ಛఆͷ Marathon task ͕ Unhealty ʹͳͬͯ͠·͏ • Marathon ϔϧενΣοΫ༻ΤϯυϙΠϯτΛɺϝτϦΫε औಘ༻ͷΤϯυϙΠϯτͱͯ͠͠·͍ͬͯͨ http://{burrow}/metrics • kafka topic ͕૿͑ΔͨͼʹϨεϙϯεαΠζ͕૿͑ɺ Marathon ϔϧενΣοΫ͕ΤϥʔͱͳΔ https://github.com/mesosphere/marathon/issues/3289 • ϔϧενΣοΫ༻ͷΤϯυϙΠϯτΛ༻ҙͯ͠ରԠ

Slide 57

Slide 57 text

4. Deployment͕ऴΘΒͳ͍࿩

Slide 58

Slide 58 text

Deploymentͬͯʁ • DC/OS΁౤͛ͨMarathonఆٛΛαϒϛοτ͢Δॲཧ • MarathonλεΫ͕૸ͬͨΒ׬ྃ • CPU / Memory Ϧιʔε͕଍Γͳ͍৔߹ʹ Pending ʹ ͳͬͨΓ͢Δ

Slide 59

Slide 59 text

ऴΘΒͳ͍ • image pull ࣦഊΈ͍ͨͳ task Failed ͕ى͖͍ͯΔΘ͚Ͱ ΋ͳ͍ • Ϧιʔε΋଍Γ͍ͯΔ • dcos marathon deployment stop (CLIπʔϧ) ΋ޮ͔ͳ͍

Slide 60

Slide 60 text

௚઀MarathonΛݟΔ • http://${MASTER_NODE_IP}/marathon/ui/ • task / deployment ͷ restart / destroy ΋ޮՌͳ͠ • destroy ͯ͠΋ suspended task Ͱ࢒ͬͯ͠·͏ɾɾ

Slide 61

Slide 61 text

ίϯςφ͕৐͍ͬͯΔϗετΛݟΔ • docker ίϯςφ͕ϋϯάͯ͠ docker stop / kill / rm ͕ޮ͔ͳ͍ঢ়ଶ • deployment ͸ίϯςφͷ࡟আ଴ͪͰਐΜͰ͍ͳ͍༷ࢠ • docker rm -f Ͱڧ੍࡟আ͢Δ΋ mesos ͷ task ͱͯ͠͸࢒͍ͬͯΔ • ࠶౓Deployͯ͠΋ docker stop ॲཧ͔Β࢝·ͬͯ͠·͏ • Marathon task ID Λผͷ΋ͷʹͯ͠Deploy͢Δ͜ͱͰରॲͨ͠

Slide 62

Slide 62 text

5. αʔϏεσΟεΧόϦো֐ͷ࿩

Slide 63

Slide 63 text

MarathonλεΫఆٛͰϩʔυόϥϯ εΛ࣮૷͢ΔͱɺDC/OSͰαʔϏε σΟεΧόϦͯ͘͠ΕΔ

Slide 64

Slide 64 text

Marathonఆٛ { "id": "/test/apps", "container": { "type": "DOCKER", "docker": { "image": “nginx", "network": "BRIDGE", "portMappings": [ { "containerPort": 80, "protocol": "tcp", "labels": { "VIP_0": “/test/apps:8889" } } ] } }, "instances": 3, "cpus": 1, "mem": 1024 }

Slide 65

Slide 65 text

Marathonఆٛ { "id": "/test/apps", "container": { "type": "DOCKER", "docker": { "image": “nginx", "network": "BRIDGE", "portMappings": [ { "containerPort": 80, "protocol": "tcp", "labels": { "VIP_0": “/test/apps:8889" } } ] } }, "instances": 3, "cpus": 1, "mem": 1024 }

Slide 66

Slide 66 text

Lookup # dig testapps.marathon.l4lb.thisdcos.directory TFSWJDFOBNFNBSBUIPOMMCUIJTEDPTEJSFDUPSZ Ͱ%$04಺෦͔ΒMPPLVQՄೳͱͳΔ

Slide 67

Slide 67 text

Lookup # dig testapps.marathon.l4lb.thisdcos.directory ; <<>> DiG 9.9.4-RedHat-9.9.4-29.el7_2.2 <<>> testapps.marathon.l4lb.thisdcos.directory ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13203 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; WARNING: recursion requested but not available ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;testapps.marathon.l4lb.thisdcos.directory. IN A ;; ANSWER SECTION: testapps.marathon.l4lb.thisdcos.directory. 5 IN A 11.219.114.140 ;; Query time: 1 msec ;; SERVER: 198.51.100.1#53(198.51.100.1) ;; WHEN: Sun Nov 05 05:54:38 UTC 2017 ;; MSG SIZE rcvd: 86

Slide 68

Slide 68 text

Lookup # curl testapps.marathon.l4lb.thisdcos.directory:8889 Welcome to nginx! body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; }

Welcome to nginx!

Slide 69

Slide 69 text

͍͚ͦ͏ʂ ͱࢥͬͯ͠͹Β͘ӡ༻ͯͨ͠Βো֐ൃੜ

Slide 70

Slide 70 text

Το # curl prd-ui.marathon.l4lb.thisdcos.directory:3000 curl: (6) Could not resolve host: prd-ui.marathon.l4lb.thisdcos.directory

Slide 71

Slide 71 text

Τοοο # dig prd-ui.marathon.l4lb.thisdcos.directory ;; ANSWER SECTION: prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58 prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58 prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58 prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58 prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58 prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58 prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58 prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58 prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58 prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58 prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58 prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58 prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58 prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58 prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58 prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58 prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58 prd-ui.marathon.l4lb.thisdcos.directory. 5 IN A 11.214.212.58

Slide 72

Slide 72 text

͠͹Β͘͢ΔͱANSWER͢Βฦ͞ͳ͘ͳΔ # dig prd-ui.marathon.l4lb.thisdcos.directory ; <<>> DiG 9.9.4-RedHat-9.9.4-38.el7_3.2 <<>> prd-ui.marathon.l4lb.thisdcos.directory ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 55428 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;prd-ui.marathon.l4lb.thisdcos.directory. IN A ;; AUTHORITY SECTION: thisdcos.directory. 130 IN SOA ns-1461.awsdns-54.org. awsdns- hostmaster.amazon.com. 1 7200 900 1209600 86400 ;; Query time: 1 msec ;; SERVER: 198.51.100.1#53(198.51.100.1) ;; WHEN: Sun Nov 05 15:31:03 JST 2017 ;; MSG SIZE rcvd: 153

Slide 73

Slide 73 text

͠͹Β͘͢ΔͱANSWER͢Βฦ͞ͳ͘ͳΔ # dig prd-ui.marathon.l4lb.thisdcos.directory ; <<>> DiG 9.9.4-RedHat-9.9.4-38.el7_3.2 <<>> prd-ui.marathon.l4lb.thisdcos.directory ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 55428 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;prd-ui.marathon.l4lb.thisdcos.directory. IN A ;; AUTHORITY SECTION: thisdcos.directory. 130 IN SOA ns-1461.awsdns-54.org. awsdns- hostmaster.amazon.com. 1 7200 900 1209600 86400 ;; Query time: 1 msec ;; SERVER: 198.51.100.1#53(198.51.100.1) ;; WHEN: Sun Nov 05 15:31:03 JST 2017 ;; MSG SIZE rcvd: 153

Slide 74

Slide 74 text

͠͹Β͘͢ΔͱANSWER͢Βฦ͞ͳ͘ͳΔ # dig prd-ui.marathon.l4lb.thisdcos.directory ; <<>> DiG 9.9.4-RedHat-9.9.4-38.el7_3.2 <<>> prd-ui.marathon.l4lb.thisdcos.directory ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 55428 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;prd-ui.marathon.l4lb.thisdcos.directory. IN A ;; AUTHORITY SECTION: thisdcos.directory. 130 IN SOA ns-1461.awsdns-54.org. awsdns- hostmaster.amazon.com. 1 7200 900 1209600 86400 ;; Query time: 1 msec ;; SERVER: 198.51.100.1#53(198.51.100.1) ;; WHEN: Sun Nov 05 15:31:03 JST 2017 ;; MSG SIZE rcvd: 153 ίϨ͸4QBSUBO %/41SPYZ

Slide 75

Slide 75 text

Ͳ͏͔ͨ͠ • Load Balancing / VIP ൃߦ͍ͯ͠ΔMinutemanαʔϏε Λ࠶ىಈ͢Δ͜ͱͰରԠ • DC/OS 1.9.0 ʹόʔδϣϯόοϓͨ͠Β࠶ൃ͠ͳ͘ͳͬͨ ʢݪҼ௥͑ͣʣ # systemctl restart dcos-minuteman.service # dig prd-ui.marathon.l4lb.thisdcos.directory +short 11.214.212.58

Slide 76

Slide 76 text

·ͱΊ • Mesos / Marathon / Metronome ·ΘΓͷ ஌͕ࣝඞཁ • ಺෦ίϯϙʔωϯτͷτϥϒϧγϡʔτ͕ ͭΒ͍ • k8sͱൺ΂Δͱ΍͸Γ৘ใྔ͕ɾɾɾ

Slide 77

Slide 77 text

·ͱΊ • ίϯςφΦʔέετϨʔγϣϯΤϯδϯ ͱͯ͠͸ػೳ͸े෼ɺߏங΋؆୯ • ̍೥Ҏ্ӡ༻͍ͯ͠Δ͕ΫϥελམͪΔ ͳͲͷக໋తͳো֐ʹ͸ૺ۰ͤͣʢͨͩ ͠ϗετμ΢ϯʹ΋ૺ۰͍ͯ͠ͳ͍ʣ

Slide 78

Slide 78 text

͓ΘΓ