[{"data":1,"prerenderedAt":92950},["ShallowReactive",2],{"navigation":3,"blog":508,"\u002Fblog\u002F2025":91073},[4],{"title":5,"icon":6,"path":7,"stem":8,"children":9},"Docs","i-ph-book-open","\u002Fdocs","1.docs",[10,12,23,63,73,99,123,214,279,287,326,394,420,482],{"title":5,"path":7,"stem":11},"1.docs\u002Findex",{"title":13,"icon":14,"path":15,"stem":16,"children":17,"page":22},"Coffee","i-ph-coffee-bean","\u002Fdocs\u002Fcoffee","1.docs\u002Fcoffee",[18],{"title":19,"path":20,"stem":21},"Shops","\u002Fdocs\u002Fcoffee\u002Fshops","1.docs\u002Fcoffee\u002Fshops",false,{"title":24,"icon":25,"path":26,"stem":27,"children":28,"page":22},"Databases","i-ph-database","\u002Fdocs\u002Fdatabases","1.docs\u002Fdatabases",[29,33],{"title":30,"path":31,"stem":32},"MongoDB","\u002Fdocs\u002Fdatabases\u002Fmongodb","1.docs\u002Fdatabases\u002Fmongodb",{"title":34,"icon":35,"path":36,"stem":37,"children":38,"page":22},"MySQL","i-simple-icons-mysql","\u002Fdocs\u002Fdatabases\u002Fmysql","1.docs\u002Fdatabases\u002Fmysql",[39,43,47,51,55,59],{"title":40,"path":41,"stem":42},"Cheat Sheet","\u002Fdocs\u002Fdatabases\u002Fmysql\u002Fcheat-sheet","1.docs\u002Fdatabases\u002Fmysql\u002Fcheat-sheet",{"title":44,"path":45,"stem":46},"event_scheduler","\u002Fdocs\u002Fdatabases\u002Fmysql\u002Fevent_scheduler","1.docs\u002Fdatabases\u002Fmysql\u002Fevent_scheduler",{"title":48,"path":49,"stem":50},"init_file: Run SQL file on startup","\u002Fdocs\u002Fdatabases\u002Fmysql\u002Finit_file","1.docs\u002Fdatabases\u002Fmysql\u002Finit_file",{"title":52,"path":53,"stem":54},"MariaDB","\u002Fdocs\u002Fdatabases\u002Fmysql\u002Fmariadb","1.docs\u002Fdatabases\u002Fmysql\u002Fmariadb",{"title":56,"path":57,"stem":58},"Pitfalls","\u002Fdocs\u002Fdatabases\u002Fmysql\u002Fpitfalls","1.docs\u002Fdatabases\u002Fmysql\u002Fpitfalls",{"title":60,"path":61,"stem":62},"Slow Log","\u002Fdocs\u002Fdatabases\u002Fmysql\u002Fslow-log","1.docs\u002Fdatabases\u002Fmysql\u002Fslow-log",{"title":64,"icon":65,"path":66,"stem":67,"children":68,"page":22},"Development","i-ph-code","\u002Fdocs\u002Fdevelopment","1.docs\u002Fdevelopment",[69],{"title":70,"path":71,"stem":72},"Protobuf \u002F gRPC","\u002Fdocs\u002Fdevelopment\u002Fprotobuf","1.docs\u002Fdevelopment\u002Fprotobuf",{"title":74,"icon":75,"path":76,"stem":77,"children":78,"page":22},"General","i-ph-wrench","\u002Fdocs\u002Fgeneral","1.docs\u002Fgeneral",[79,83,87,91,95],{"title":80,"path":81,"stem":82},"ADB","\u002Fdocs\u002Fgeneral\u002Fadb","1.docs\u002Fgeneral\u002Fadb",{"title":84,"path":85,"stem":86},"VS Codium","\u002Fdocs\u002Fgeneral\u002Fcodium","1.docs\u002Fgeneral\u002Fcodium",{"title":88,"path":89,"stem":90},"OpenSSL","\u002Fdocs\u002Fgeneral\u002Fopenssl","1.docs\u002Fgeneral\u002Fopenssl",{"title":92,"path":93,"stem":94},"Projects, Tools and Utilites","\u002Fdocs\u002Fgeneral\u002Ftools-utilities","1.docs\u002Fgeneral\u002Ftools-utilities",{"title":96,"path":97,"stem":98},"Online Tools","\u002Fdocs\u002Fgeneral\u002Fuseful-online-tools","1.docs\u002Fgeneral\u002Fuseful-online-tools",{"title":100,"icon":101,"path":102,"stem":103,"children":104,"page":22},"Hassio","i-simple-icons-homeassistant","\u002Fdocs\u002Fhassio","1.docs\u002Fhassio",[105,115,119],{"title":106,"icon":107,"path":108,"stem":109,"children":110,"page":22},"ESPHome","i-simple-icons-esphome","\u002Fdocs\u002Fhassio\u002Fesphome","1.docs\u002Fhassio\u002Fesphome",[111],{"title":112,"path":113,"stem":114},"Voltage - ADC","\u002Fdocs\u002Fhassio\u002Fesphome\u002Fvoltage-adc","1.docs\u002Fhassio\u002Fesphome\u002Fvoltage-adc",{"title":116,"path":117,"stem":118},"Raspberry Pi","\u002Fdocs\u002Fhassio\u002Fraspberrypi","1.docs\u002Fhassio\u002Fraspberrypi",{"title":120,"path":121,"stem":122},"Zigbee2MQTT","\u002Fdocs\u002Fhassio\u002Fzigbee2mqtt","1.docs\u002Fhassio\u002Fzigbee2mqtt",{"title":124,"icon":125,"path":126,"stem":127,"children":128,"page":22},"Kubernetes","i-simple-icons-kubernetes","\u002Fdocs\u002Fkubernetes","1.docs\u002Fkubernetes",[129,133,136,140,157,161,165,175,188,192,210],{"title":130,"path":131,"stem":132},"Certificates","\u002Fdocs\u002Fkubernetes\u002Fcertificates","1.docs\u002Fkubernetes\u002Fcertificates",{"title":40,"path":134,"stem":135},"\u002Fdocs\u002Fkubernetes\u002Fcheat-sheet","1.docs\u002Fkubernetes\u002Fcheat-sheet",{"title":137,"path":138,"stem":139},"Cluster Components Upgrade Order","\u002Fdocs\u002Fkubernetes\u002Fcluster-components-upgrade-order","1.docs\u002Fkubernetes\u002Fcluster-components-upgrade-order",{"title":141,"icon":142,"path":143,"stem":144,"children":145,"page":22},"Etcd","i-simple-icons-etcd","\u002Fdocs\u002Fkubernetes\u002Fetcd","1.docs\u002Fkubernetes\u002Fetcd",[146,149,153],{"title":40,"path":147,"stem":148},"\u002Fdocs\u002Fkubernetes\u002Fetcd\u002Fcheat-sheet","1.docs\u002Fkubernetes\u002Fetcd\u002Fcheat-sheet",{"title":150,"path":151,"stem":152},"Editing Kubernetes Objects","\u002Fdocs\u002Fkubernetes\u002Fetcd\u002Fediting-kubernetes-objects","1.docs\u002Fkubernetes\u002Fetcd\u002Fediting-kubernetes-objects",{"title":154,"path":155,"stem":156},"Snapshots: Save & Restore","\u002Fdocs\u002Fkubernetes\u002Fetcd\u002Fsnapshots-save-restore","1.docs\u002Fkubernetes\u002Fetcd\u002Fsnapshots-save-restore",{"title":158,"path":159,"stem":160},"Ingress","\u002Fdocs\u002Fkubernetes\u002Fingress","1.docs\u002Fkubernetes\u002Fingress",{"title":162,"path":163,"stem":164},"kubeadm","\u002Fdocs\u002Fkubernetes\u002Fkubeadm","1.docs\u002Fkubernetes\u002Fkubeadm",{"title":166,"icon":167,"path":168,"stem":169,"children":170,"page":22},"Logging","i-ph-log","\u002Fdocs\u002Fkubernetes\u002Flogging","1.docs\u002Fkubernetes\u002Flogging",[171],{"title":172,"path":173,"stem":174},"Regex","\u002Fdocs\u002Fkubernetes\u002Flogging\u002Fregex","1.docs\u002Fkubernetes\u002Flogging\u002Fregex",{"title":176,"icon":177,"path":178,"stem":179,"children":180,"page":22},"Monitoring","i-ph-binoculars","\u002Fdocs\u002Fkubernetes\u002Fmonitoring","1.docs\u002Fkubernetes\u002Fmonitoring",[181,184],{"title":176,"path":182,"stem":183},"\u002Fdocs\u002Fkubernetes\u002Fmonitoring\u002Fbasics","1.docs\u002Fkubernetes\u002Fmonitoring\u002Fbasics",{"title":185,"path":186,"stem":187},"Components","\u002Fdocs\u002Fkubernetes\u002Fmonitoring\u002Fcomponents","1.docs\u002Fkubernetes\u002Fmonitoring\u002Fcomponents",{"title":189,"path":190,"stem":191},"Kubernetes Name Schemas","\u002Fdocs\u002Fkubernetes\u002Fname-schema","1.docs\u002Fkubernetes\u002Fname-schema",{"title":193,"icon":194,"path":195,"stem":196,"children":197,"page":22},"Networking","i-ph-network","\u002Fdocs\u002Fkubernetes\u002Fnetworking","1.docs\u002Fkubernetes\u002Fnetworking",[198,202,206],{"title":199,"path":200,"stem":201},"Benchmarking","\u002Fdocs\u002Fkubernetes\u002Fnetworking\u002Fbenchmarking","1.docs\u002Fkubernetes\u002Fnetworking\u002Fbenchmarking",{"title":203,"path":204,"stem":205},"Explained","\u002Fdocs\u002Fkubernetes\u002Fnetworking\u002Fexplained","1.docs\u002Fkubernetes\u002Fnetworking\u002Fexplained",{"title":207,"path":208,"stem":209},"Troubleshooting","\u002Fdocs\u002Fkubernetes\u002Fnetworking\u002Ftroubleshooting","1.docs\u002Fkubernetes\u002Fnetworking\u002Ftroubleshooting",{"title":211,"path":212,"stem":213},"System Requirements","\u002Fdocs\u002Fkubernetes\u002Fsystem-requirements","1.docs\u002Fkubernetes\u002Fsystem-requirements",{"title":215,"icon":216,"path":217,"stem":218,"children":219,"page":22},"Linux","i-simple-icons-linux","\u002Fdocs\u002Flinux","1.docs\u002Flinux",[220,224,246,250,268,272,275],{"title":221,"path":222,"stem":223},"git","\u002Fdocs\u002Flinux\u002Fgit","1.docs\u002Flinux\u002Fgit",{"title":225,"path":226,"stem":227,"children":228,"page":22},"GRUB","\u002Fdocs\u002Flinux\u002Fgrub","1.docs\u002Flinux\u002Fgrub",[229,242],{"title":230,"path":231,"stem":232,"children":233,"page":22},"Boot .XYZ File","\u002Fdocs\u002Flinux\u002Fgrub\u002Fbooting-xyz-files","1.docs\u002Flinux\u002Fgrub\u002Fbooting-xyz-files",[234,238],{"title":235,"path":236,"stem":237},".img File","\u002Fdocs\u002Flinux\u002Fgrub\u002Fbooting-xyz-files\u002Fimg-file","1.docs\u002Flinux\u002Fgrub\u002Fbooting-xyz-files\u002Fimg-file",{"title":239,"path":240,"stem":241},".iso File","\u002Fdocs\u002Flinux\u002Fgrub\u002Fbooting-xyz-files\u002Fiso-file","1.docs\u002Flinux\u002Fgrub\u002Fbooting-xyz-files\u002Fiso-file",{"title":243,"path":244,"stem":245},"Preparations for 'Booting XYZ FIle'","\u002Fdocs\u002Flinux\u002Fgrub\u002Fpreparations-for-boot-xyz-file","1.docs\u002Flinux\u002Fgrub\u002Fpreparations-for-boot-xyz-file",{"title":247,"path":248,"stem":249},"mdadm","\u002Fdocs\u002Flinux\u002Fmdam","1.docs\u002Flinux\u002Fmdam",{"title":251,"icon":252,"path":253,"stem":254,"children":255,"page":22},"Nixos","i-simple-icons-nixos","\u002Fdocs\u002Flinux\u002Fnixos","1.docs\u002Flinux\u002Fnixos",[256,260,264],{"title":257,"path":258,"stem":259},"Cleanup Storage","\u002Fdocs\u002Flinux\u002Fnixos\u002Fcleanup","1.docs\u002Flinux\u002Fnixos\u002Fcleanup",{"title":261,"path":262,"stem":263},"Quick NixOS VM","\u002Fdocs\u002Flinux\u002Fnixos\u002Fquick-vm","1.docs\u002Flinux\u002Fnixos\u002Fquick-vm",{"title":265,"path":266,"stem":267},"Update","\u002Fdocs\u002Flinux\u002Fnixos\u002Fupdate","1.docs\u002Flinux\u002Fnixos\u002Fupdate",{"title":269,"path":270,"stem":271},"Quick Commands","\u002Fdocs\u002Flinux\u002Fquick-commands","1.docs\u002Flinux\u002Fquick-commands",{"title":116,"path":273,"stem":274},"\u002Fdocs\u002Flinux\u002Fraspberrypi","1.docs\u002Flinux\u002Fraspberrypi",{"title":276,"path":277,"stem":278},"sysctl","\u002Fdocs\u002Flinux\u002Fsysctl","1.docs\u002Flinux\u002Fsysctl",{"title":166,"icon":167,"path":280,"stem":281,"children":282,"page":22},"\u002Fdocs\u002Flogging","1.docs\u002Flogging",[283],{"title":284,"path":285,"stem":286},"Loki","\u002Fdocs\u002Flogging\u002Floki","1.docs\u002Flogging\u002Floki",{"title":176,"icon":177,"path":288,"stem":289,"children":290,"page":22},"\u002Fdocs\u002Fmonitoring","1.docs\u002Fmonitoring",[291,322],{"title":292,"icon":293,"path":294,"stem":295,"children":296,"page":22},"Prometheus","i-simple-icons-prometheus","\u002Fdocs\u002Fmonitoring\u002Fprometheus","1.docs\u002Fmonitoring\u002Fprometheus",[297,318],{"title":298,"path":299,"stem":300,"children":301,"page":22},"Exporters","\u002Fdocs\u002Fmonitoring\u002Fprometheus\u002Fexporters","1.docs\u002Fmonitoring\u002Fprometheus\u002Fexporters",[302,306,310,314],{"title":303,"path":304,"stem":305},"dellhw_exporter by galexrt","\u002Fdocs\u002Fmonitoring\u002Fprometheus\u002Fexporters\u002Fdellhw_exporter","1.docs\u002Fmonitoring\u002Fprometheus\u002Fexporters\u002Fdellhw_exporter",{"title":307,"path":308,"stem":309},"ethtool_exporter by Showmax","\u002Fdocs\u002Fmonitoring\u002Fprometheus\u002Fexporters\u002Fethtool_exporter","1.docs\u002Fmonitoring\u002Fprometheus\u002Fexporters\u002Fethtool_exporter",{"title":311,"path":312,"stem":313},"node_exporter by Prometheus Project","\u002Fdocs\u002Fmonitoring\u002Fprometheus\u002Fexporters\u002Fnode_exporter","1.docs\u002Fmonitoring\u002Fprometheus\u002Fexporters\u002Fnode_exporter",{"title":315,"path":316,"stem":317},"Other exporters","\u002Fdocs\u002Fmonitoring\u002Fprometheus\u002Fexporters\u002Fothers","1.docs\u002Fmonitoring\u002Fprometheus\u002Fexporters\u002Fothers",{"title":319,"path":320,"stem":321},"Tips","\u002Fdocs\u002Fmonitoring\u002Fprometheus\u002Ftips","1.docs\u002Fmonitoring\u002Fprometheus\u002Ftips",{"title":323,"path":324,"stem":325},"Thanos","\u002Fdocs\u002Fmonitoring\u002Fthanos","1.docs\u002Fmonitoring\u002Fthanos",{"title":193,"icon":194,"path":327,"stem":328,"children":329,"page":22},"\u002Fdocs\u002Fnetworking","1.docs\u002Fnetworking",[330,347,351,363,367],{"title":331,"icon":332,"path":333,"stem":334,"children":335,"page":22},"Cisco","i-simple-icons-cisco","\u002Fdocs\u002Fnetworking\u002Fcisco","1.docs\u002Fnetworking\u002Fcisco",[336,340,343],{"title":337,"path":338,"stem":339},"ACLs","\u002Fdocs\u002Fnetworking\u002Fcisco\u002Facls","1.docs\u002Fnetworking\u002Fcisco\u002Facls",{"title":40,"path":341,"stem":342},"\u002Fdocs\u002Fnetworking\u002Fcisco\u002Fcheat-sheet","1.docs\u002Fnetworking\u002Fcisco\u002Fcheat-sheet",{"title":344,"path":345,"stem":346},"Switch Configuration","\u002Fdocs\u002Fnetworking\u002Fcisco\u002Fswitch-configuration","1.docs\u002Fnetworking\u002Fcisco\u002Fswitch-configuration",{"title":348,"path":349,"stem":350},"Cloudflare","\u002Fdocs\u002Fnetworking\u002Fcloudflare","1.docs\u002Fnetworking\u002Fcloudflare",{"title":352,"path":353,"stem":354,"children":355,"page":22},"Fiber","\u002Fdocs\u002Fnetworking\u002Ffiber","1.docs\u002Fnetworking\u002Ffiber",[356,359],{"title":40,"path":357,"stem":358},"\u002Fdocs\u002Fnetworking\u002Ffiber\u002Fcheat-sheet","1.docs\u002Fnetworking\u002Ffiber\u002Fcheat-sheet",{"title":360,"path":361,"stem":362},"Glossar","\u002Fdocs\u002Fnetworking\u002Ffiber\u002Fglossar","1.docs\u002Fnetworking\u002Ffiber\u002Fglossar",{"title":364,"path":365,"stem":366},"IP-Blocklists","\u002Fdocs\u002Fnetworking\u002Fip-blocklists","1.docs\u002Fnetworking\u002Fip-blocklists",{"title":368,"icon":369,"path":370,"stem":371,"children":372,"page":22},"Mikrotik","i-simple-icons-mikrotik","\u002Fdocs\u002Fnetworking\u002Fmikrotik","1.docs\u002Fnetworking\u002Fmikrotik",[373,376,390],{"title":40,"path":374,"stem":375},"\u002Fdocs\u002Fnetworking\u002Fmikrotik\u002Fcheat-sheet","1.docs\u002Fnetworking\u002Fmikrotik\u002Fcheat-sheet",{"title":377,"icon":378,"path":379,"stem":380,"children":381,"page":22},"DNS","i-mdi-dns","\u002Fdocs\u002Fnetworking\u002Fmikrotik\u002Fdns","1.docs\u002Fnetworking\u002Fmikrotik\u002Fdns",[382,386],{"title":383,"path":384,"stem":385},"Adlists \u002F Blocklists","\u002Fdocs\u002Fnetworking\u002Fmikrotik\u002Fdns\u002Fadlists-blocklists","1.docs\u002Fnetworking\u002Fmikrotik\u002Fdns\u002Fadlists-blocklists",{"title":387,"path":388,"stem":389},"DNS over HTTPS (DOH)","\u002Fdocs\u002Fnetworking\u002Fmikrotik\u002Fdns\u002Fdns-over-https-doh","1.docs\u002Fnetworking\u002Fmikrotik\u002Fdns\u002Fdns-over-https-doh",{"title":391,"path":392,"stem":393},"Example Configs","\u002Fdocs\u002Fnetworking\u002Fmikrotik\u002Fexample-configs","1.docs\u002Fnetworking\u002Fmikrotik\u002Fexample-configs",{"title":395,"icon":396,"path":397,"stem":398,"children":399,"page":22},"Software","i-ph-file-code","\u002Fdocs\u002Fsoftware","1.docs\u002Fsoftware",[400,404,408,412,416],{"title":401,"path":402,"stem":403},"CRI-O","\u002Fdocs\u002Fsoftware\u002Fcrio","1.docs\u002Fsoftware\u002Fcrio",{"title":405,"path":406,"stem":407},"Docker Registry","\u002Fdocs\u002Fsoftware\u002Fdocker-registry","1.docs\u002Fsoftware\u002Fdocker-registry",{"title":409,"path":410,"stem":411},"GitLab CI","\u002Fdocs\u002Fsoftware\u002Fgitlab-ci","1.docs\u002Fsoftware\u002Fgitlab-ci",{"title":413,"path":414,"stem":415},"Harbor Registry","\u002Fdocs\u002Fsoftware\u002Fharbor-registry","1.docs\u002Fsoftware\u002Fharbor-registry",{"title":417,"path":418,"stem":419},"SSH","\u002Fdocs\u002Fsoftware\u002Fssh","1.docs\u002Fsoftware\u002Fssh",{"title":421,"icon":422,"path":423,"stem":424,"children":425,"page":22},"Storage","i-ph-hard-drives","\u002Fdocs\u002Fstorage","1.docs\u002Fstorage",[426,448,456,464],{"title":427,"icon":428,"path":429,"stem":430,"children":431,"page":22},"Ceph","i-simple-icons-ceph","\u002Fdocs\u002Fstorage\u002Fceph","1.docs\u002Fstorage\u002Fceph",[432,436,440,444],{"title":433,"path":434,"stem":435},"Architecture","\u002Fdocs\u002Fstorage\u002Fceph\u002Farchitecture","1.docs\u002Fstorage\u002Fceph\u002Farchitecture",{"title":437,"path":438,"stem":439},"Common Issues","\u002Fdocs\u002Fstorage\u002Fceph\u002Fcommon-issues","1.docs\u002Fstorage\u002Fceph\u002Fcommon-issues",{"title":441,"path":442,"stem":443},"OSDs","\u002Fdocs\u002Fstorage\u002Fceph\u002Fosds","1.docs\u002Fstorage\u002Fceph\u002Fosds",{"title":445,"path":446,"stem":447},"RBD (Block Storage)","\u002Fdocs\u002Fstorage\u002Fceph\u002Frbd","1.docs\u002Fstorage\u002Fceph\u002Frbd",{"title":449,"path":450,"stem":451,"children":452,"page":22},"Gluster","\u002Fdocs\u002Fstorage\u002Fgluster","1.docs\u002Fstorage\u002Fgluster",[453],{"title":437,"path":454,"stem":455},"\u002Fdocs\u002Fstorage\u002Fgluster\u002Fcommon-issues","1.docs\u002Fstorage\u002Fgluster\u002Fcommon-issues",{"title":457,"path":458,"stem":459,"children":460,"page":22},"NFS","\u002Fdocs\u002Fstorage\u002Fnfs","1.docs\u002Fstorage\u002Fnfs",[461],{"title":437,"path":462,"stem":463},"\u002Fdocs\u002Fstorage\u002Fnfs\u002Fcommon-issues","1.docs\u002Fstorage\u002Fnfs\u002Fcommon-issues",{"title":465,"icon":466,"path":467,"stem":468,"children":469,"page":22},"Rook","i-simple-icons-rook","\u002Fdocs\u002Fstorage\u002Frook","1.docs\u002Fstorage\u002Frook",[470,473,476,479],{"title":433,"path":471,"stem":472},"\u002Fdocs\u002Fstorage\u002Frook\u002Farchitecture","1.docs\u002Fstorage\u002Frook\u002Farchitecture",{"title":40,"path":474,"stem":475},"\u002Fdocs\u002Fstorage\u002Frook\u002Fcheat-sheet","1.docs\u002Fstorage\u002Frook\u002Fcheat-sheet",{"title":465,"path":477,"stem":478},"\u002Fdocs\u002Fstorage\u002Frook\u002Fcluster","1.docs\u002Fstorage\u002Frook\u002Fcluster",{"title":437,"path":480,"stem":481},"\u002Fdocs\u002Fstorage\u002Frook\u002Fcommon-issues","1.docs\u002Fstorage\u002Frook\u002Fcommon-issues",{"title":483,"icon":484,"path":485,"stem":486,"children":487,"page":22},"Web","i-ph-browser","\u002Fdocs\u002Fweb","1.docs\u002Fweb",[488,498],{"title":489,"icon":490,"path":491,"stem":492,"children":493,"page":22},"Nuxt","i-simple-icons-nuxt","\u002Fdocs\u002Fweb\u002Fnuxt","1.docs\u002Fweb\u002Fnuxt",[494],{"title":495,"path":496,"stem":497},"Loading Indicator","\u002Fdocs\u002Fweb\u002Fnuxt\u002Floading-indicator","1.docs\u002Fweb\u002Fnuxt\u002Floading-indicator",{"title":499,"icon":500,"path":501,"stem":502,"children":503,"page":22},"Tiptap","i-mdi-file-edit-outline","\u002Fdocs\u002Fweb\u002Ftiptap","1.docs\u002Fweb\u002Ftiptap",[504],{"title":505,"path":506,"stem":507},"Snippets","\u002Fdocs\u002Fweb\u002Ftiptap\u002Fsnippets","1.docs\u002Fweb\u002Ftiptap\u002Fsnippets",[509,2918,12181,12385,12706,13379,13500,13588,13635,13803,13984,14560,15160,18157,18485,18888,18925,19064,22232,26420,26522,27591,39264,49828,49989,50854,51238,52186,52278,52365,53055,55866,56096,56402,57015,57570,58339,58370,60462,61371,62647,64807,64839,66683,68051,70495,70770,70800,73260,73314,73650,74519,74694,75697,75735,75772,75819,76053,76534,76574,76609,76687,77052,77867,79035,79539,79579,79656,79746,79881,79945,79980,86846,86935,90964,91013,91049],{"id":510,"title":511,"authors":512,"badge":518,"body":519,"date":2909,"description":2910,"extension":2911,"image":2912,"meta":2913,"navigation":1254,"path":2914,"seo":2915,"stem":2916,"__hash__":2917},"posts\u002F3.blog\u002F2025\u002Fkubernetes-ipv6-only-for-real-in-good-this-time.md","Kubernetes: IPv6-only For Real In Good This Time",[513],{"name":514,"to":515,"avatar":516},"Alexander Trost","https:\u002F\u002Fgithub.com\u002Fgalexrt",{"src":517},"\u002Fimages\u002Fprofile-picture.jpg",null,{"type":520,"value":521,"toc":2893},"minimark",[522,534,539,542,557,570,574,596,609,612,617,626,649,664,667,693,697,722,725,730,734,737,885,889,892,1187,1191,1194,1198,1204,1207,1612,1619,1678,1682,1691,1700,1836,1843,1897,1901,1910,1959,2204,2409,2567,2573,2812,2818,2822,2833,2836,2841,2866,2869,2873,2880,2889],[523,524,525,526,533],"p",{},"(Photo by ",[527,528,532],"a",{"href":529,"rel":530},"https:\u002F\u002Fwww.pexels.com\u002Fphoto\u002Fperson-holding-logo-of-there-is-no-place-like-home-11035359\u002F",[531],"nofollow","RealToughCandy.com from Pexels.com",", modified to fit the blog post theme)",[535,536,538],"h2",{"id":537},"intro","Intro",[523,540,541],{},"In this blog post I want to share my experience on setting up a Talos Kubernetes cluster that runs using IPv6-only networking. No IPv4 addresses on the servers, no IPv4 addresses on the pods, no IPv4 addresses on the services. Just pure IPv6!",[523,543,544,545,550,551,556],{},"Before I'll dive into config, flags and more, this blog post is heavily based upon ",[527,546,549],{"href":547,"rel":548},"https:\u002F\u002Fdev.to\u002Fsergelogvinov\u002Fkubernetes-pods-with-global-ipv6-1aaj",[531],"\"Kubernetes PODs with global IPv6\" blog post"," by ",[527,552,555],{"href":553,"rel":554},"https:\u002F\u002Fdev.to\u002Fsergelogvinov",[531],"Serge Logvinov on dev.to",".\nIt is about Talos Kubernetes cluster config but still with IPv4 networking enabled. In the grand scheme of things, the config is very similar to what I wanted to achieve, but for IPv6-only networking.",[523,558,559,560,565,566,569],{},"Additionally if you aren't into ",[527,561,564],{"href":562,"rel":563},"https:\u002F\u002Fwww.talos.dev\u002F",[531],"Talos Linux"," (yet), I highly recommend checking it out, the shown configs should be easily adjustable for use with ",[567,568,162],"code",{}," and other cluster deployment tools.",[535,571,573],{"id":572},"the-environment-pinch-a-penny","The Environment - \"Pinch A Penny\"",[523,575,576,577,582,583,587,588,591,592,595],{},"In my case I am using ",[527,578,581],{"href":579,"rel":580},"https:\u002F\u002Fwww.hetzner.com\u002Fcloud",[531],"Hetzner Cloud"," as my cloud provider, which provides native IPv6 support and gives each VM\u002Fserver a ",[584,585,586],"strong",{},"routed"," and ",[584,589,590],{},"publicly reachable"," IPv6 ",[567,593,594],{},"\u002F64"," network.",[597,598,599],"callout",{},[523,600,601,602,587,604,591,606,608],{},"If you want to follow this blog post, make sure that your cloud provider supports IPv6 and gives you a a ",[584,603,586],{},[584,605,590],{},[567,607,594],{}," network for each of your VMs\u002Fservers.",[523,610,611],{},"So why am I \"pinching a penny\"? If I could get a working IPv6-only Kubernetes cluster going, I could save the costs of a public IPv4 address per server. So 0.60€\u002Fmonth per server, which is 7.20€\u002Fyear per server.\nIt's not \"much\" I hear you potentially think? Yes, but the more nodes you run the more you could save, so... ;-)",[613,614,616],"h3",{"id":615},"i-heard-that-github-doesnt-support-ipv6","I heard that GitHub doesn't support IPv6?",[523,618,619,620,625],{},"Yes.., but ",[527,621,624],{"href":622,"rel":623},"https:\u002F\u002Fgithub.com\u002Forgs\u002Fcommunity\u002Fdiscussions\u002F10539",[531],"there is a discussion about it in the GitHub Community"," that is open since 2022 and I know of older discussions\u002Fissues about this topic.",[597,627,628,631,634],{},[523,629,630],{},"Quick side note: If every company would at least slowly start to support IPv6 and take it seriously, I strongly believe that we would be in a much better place regarding IPv6 adoption.\nIt is annoying that a vital service that not just provides container images, but build and release artifacts of many open source projects, doesn't support IPv6.",[523,632,633],{},"I guess there are two mentions I want to make:",[635,636,637,641],"ol",{},[638,639,640],"li",{},"At least GitHub Pages supports IPv6, so that is at least one of (many) parts available over IPv6.",[638,642,643,648],{},[527,644,647],{"href":645,"rel":646},"https:\u002F\u002Fwww.worldipv6launch.org\u002F",[531],"\"World IPv6 Day\" event was held on 08. June 2011",", I hope I don't made you all feel too old.",[523,650,651,652,657,658,663],{},"It's an issue for this setup, because the Talos CCM (Cloud Controller Manager) is only published to ",[527,653,656],{"href":654,"rel":655},"https:\u002F\u002Fghcr.io\u002F",[531],"GHCR.io"," (GitHub Container Registry) and that also doesn't support IPv6.\nTechnically speaking there's several methods to workaround this. In my case I am using the ",[527,659,662],{"href":660,"rel":661},"https:\u002F\u002Fnat64.net\u002F",[531],"NAT64 service"," from Kasper Dupont that provides free-to-use NAT64\u002FDNS64 resolvers.\nIn a nutshell it translates IPv6 requests to IPv4 requests and vice versa.",[523,665,666],{},"I'll list the workarounds that come to my mind here:",[668,669,670,678,681,690],"ul",{},[638,671,672,673,677],{},"Using a NAT64\u002FDNS64 service that translates IPv6 requests to IPv4 requests and vice versa. (e.g., ",[527,674,676],{"href":660,"rel":675},[531],"nat64.net",", etc.)",[638,679,680],{},"Mirroring the images to another registry that supports IPv6 (e.g., Docker Hub, Quay.io, etc.) and use image overrides to pull from there.",[638,682,683,684,689],{},"Using a pull-through\u002Fproxy registry that supports IPv6 (e.g., ",[527,685,688],{"href":686,"rel":687},"https:\u002F\u002Fgoharbor.io\u002F",[531],"Harbor",", etc.) that caches the images on pull.",[638,691,692],{},"You could keep the IPv4 address attached on your nodes and use it as normal. Though even just writing this, it feels weird and against the idea of an IPv6-only Kubernetes cluster..",[535,694,696],{"id":695},"talos-kubernetes-config-no-ipv4-no-problem","Talos Kubernetes Config - No IPv4, No Problem",[597,698,699,704],{},[523,700,701,702,569],{},"Not using Talos Linux? No worries! The shown configs should be easily adjustable for use with ",[567,703,162],{},[523,705,706,707,710,711,714,715,718,719,721],{},"E.g., ",[567,708,709],{},"machine.network.nameservers"," would be ",[567,712,713],{},"\u002Fetc\u002Fresolv.conf",", ",[567,716,717],{},"cluster.network"," would be in the ",[567,720,162],{}," config file, etc.",[523,723,724],{},"The first thing we are going to do is to add the NAT64\u002FDNS64 resolvers to our nodes' using MachineConfig patches and get the Talos Linux ready.",[597,726,727],{},[523,728,729],{},"You might be able to update an existing cluster with these patches but I wouldn't recommend it. Creating a new cluster with these patches applied from the start is the way to go.",[613,731,733],{"id":732},"patch-for-all-machineconfigs","Patch for all MachineConfigs",[523,735,736],{},"Patch for all machines\u002Fnodes (including control planes; explanation in code comments).",[738,739,744],"pre",{"className":740,"code":741,"language":742,"meta":743,"style":743},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","machine:\n  network:\n    # Use NAT64\u002FDNS64 resolvers to resolve IPv4-only hosts like, e.g., ghcr.io\n    nameservers:\n      # NAT64\u002FDNS64 resolvers - https:\u002F\u002Fnat64.net\u002F\n      # Make sure to read through the Terms of Service before using the service\n      - 2a01:4f9:c010:3f02::1\n      - 2a00:1098:2c::1\n      - 2a01:4f8:c2c:123f::1\ncluster:\n  # Make sure Kubernetes thinks we are running in a \"cloud\" environment with a cloud controller manager\n  # In this case we'll use the Talos Cloud Controller Manager (CCM) for Hetzner Cloud\n  externalCloudProvider:\n    enabled: true\n  # Disable `kube-proxy` as we use Cilium with full kube-proxy replacement\n  proxy:\n    disabled: true\n","yaml","",[567,745,746,759,767,774,782,788,794,804,812,820,828,834,840,848,861,867,875],{"__ignoreMap":743},[747,748,751,755],"span",{"class":749,"line":750},"line",1,[747,752,754],{"class":753},"swJcz","machine",[747,756,758],{"class":757},"sMK4o",":\n",[747,760,762,765],{"class":749,"line":761},2,[747,763,764],{"class":753},"  network",[747,766,758],{"class":757},[747,768,770],{"class":749,"line":769},3,[747,771,773],{"class":772},"sHwdD","    # Use NAT64\u002FDNS64 resolvers to resolve IPv4-only hosts like, e.g., ghcr.io\n",[747,775,777,780],{"class":749,"line":776},4,[747,778,779],{"class":753},"    nameservers",[747,781,758],{"class":757},[747,783,785],{"class":749,"line":784},5,[747,786,787],{"class":772},"      # NAT64\u002FDNS64 resolvers - https:\u002F\u002Fnat64.net\u002F\n",[747,789,791],{"class":749,"line":790},6,[747,792,793],{"class":772},"      # Make sure to read through the Terms of Service before using the service\n",[747,795,797,800],{"class":749,"line":796},7,[747,798,799],{"class":757},"      -",[747,801,803],{"class":802},"sfazB"," 2a01:4f9:c010:3f02::1\n",[747,805,807,809],{"class":749,"line":806},8,[747,808,799],{"class":757},[747,810,811],{"class":802}," 2a00:1098:2c::1\n",[747,813,815,817],{"class":749,"line":814},9,[747,816,799],{"class":757},[747,818,819],{"class":802}," 2a01:4f8:c2c:123f::1\n",[747,821,823,826],{"class":749,"line":822},10,[747,824,825],{"class":753},"cluster",[747,827,758],{"class":757},[747,829,831],{"class":749,"line":830},11,[747,832,833],{"class":772},"  # Make sure Kubernetes thinks we are running in a \"cloud\" environment with a cloud controller manager\n",[747,835,837],{"class":749,"line":836},12,[747,838,839],{"class":772},"  # In this case we'll use the Talos Cloud Controller Manager (CCM) for Hetzner Cloud\n",[747,841,843,846],{"class":749,"line":842},13,[747,844,845],{"class":753},"  externalCloudProvider",[747,847,758],{"class":757},[747,849,851,854,857],{"class":749,"line":850},14,[747,852,853],{"class":753},"    enabled",[747,855,856],{"class":757},":",[747,858,860],{"class":859},"sfNiH"," true\n",[747,862,864],{"class":749,"line":863},15,[747,865,866],{"class":772},"  # Disable `kube-proxy` as we use Cilium with full kube-proxy replacement\n",[747,868,870,873],{"class":749,"line":869},16,[747,871,872],{"class":753},"  proxy",[747,874,758],{"class":757},[747,876,878,881,883],{"class":749,"line":877},17,[747,879,880],{"class":753},"    disabled",[747,882,856],{"class":757},[747,884,860],{"class":859},[613,886,888],{"id":887},"patch-for-control-plane","Patch for Control Plane",[523,890,891],{},"Patch for the control plane nodes.",[738,893,895],{"className":740,"code":894,"language":742,"meta":743,"style":743},"cluster:\n  network:\n    # Talos shouldn't deploy any CNI, we'll deploy Cilium ourselves.\n    cni:\n      name: none\n    # Only provide an IPv6 podSubnet here, so no IPv4 is allocated\u002Fused.\n    # This range is more of a dummy, as through the CCM we'll allocate slices of each node's \u002F64 network\n    # to the pods running on that node.\n    # Make sure that the podSubnet is unique and doesn't overlap with any other network in your\n    # infrastructure.\n    podSubnets:\n      - \"fd40:10::\u002F96\"\n    # Only provide an IPv6 serviceSubnet here, so no IPv4 is allocated\u002Fused.\n    serviceSubnets:\n      - \"fd40:10:100::\u002F112\"\n  controllerManager:\n    extraArgs:\n      # Make sure the kube-controller-manager listens on all interfaces (\"including\" IPv6), this can be\n      # a security implication as in a public network setting like Hetzner Cloud this would expose the\n      # kube-controller-manager's endpoints to the public internet. Therefore it is recommended to setup\n      # a firewall to only allow access from trusted IPs\u002Fnetworks.\n      bind-address: \"::\"\n      # Without disabling the node IPAM controller, this would make the controller hand out \u002F112 networks\n      # to each node.\n      node-cidr-mask-size-ipv6: \"112\"\n      # Disable Node IPAM controller as we use Talos CCM for the pod network for each node.\n      controllers: \"*,-node-ipam-controller\"\n  scheduler:\n    extraArgs:\n      # Make sure the kube-scheduler listens on all interfaces (\"including\" IPv6), this can be\n      # a security implication, see controllerManager bind-address comment above.\n      bind-address: \"::\"\n  etcd:\n    extraArgs:\n      # Make sure the etcd metrics listens on all interfaces (\"including\" IPv6), this can be\n      # a security implication, see controllerManager bind-address comment above.\n      # Note: This is optional, only needed if you want to easily scrape etcd metrics.\n      listen-metrics-urls: \"http:\u002F\u002F[::]:2381\"\n",[567,896,897,903,909,914,921,931,936,941,946,951,956,963,976,981,988,999,1006,1013,1019,1025,1031,1037,1052,1058,1064,1079,1085,1100,1108,1115,1121,1127,1140,1148,1155,1161,1166,1172],{"__ignoreMap":743},[747,898,899,901],{"class":749,"line":750},[747,900,825],{"class":753},[747,902,758],{"class":757},[747,904,905,907],{"class":749,"line":761},[747,906,764],{"class":753},[747,908,758],{"class":757},[747,910,911],{"class":749,"line":769},[747,912,913],{"class":772},"    # Talos shouldn't deploy any CNI, we'll deploy Cilium ourselves.\n",[747,915,916,919],{"class":749,"line":776},[747,917,918],{"class":753},"    cni",[747,920,758],{"class":757},[747,922,923,926,928],{"class":749,"line":784},[747,924,925],{"class":753},"      name",[747,927,856],{"class":757},[747,929,930],{"class":802}," none\n",[747,932,933],{"class":749,"line":790},[747,934,935],{"class":772},"    # Only provide an IPv6 podSubnet here, so no IPv4 is allocated\u002Fused.\n",[747,937,938],{"class":749,"line":796},[747,939,940],{"class":772},"    # This range is more of a dummy, as through the CCM we'll allocate slices of each node's \u002F64 network\n",[747,942,943],{"class":749,"line":806},[747,944,945],{"class":772},"    # to the pods running on that node.\n",[747,947,948],{"class":749,"line":814},[747,949,950],{"class":772},"    # Make sure that the podSubnet is unique and doesn't overlap with any other network in your\n",[747,952,953],{"class":749,"line":822},[747,954,955],{"class":772},"    # infrastructure.\n",[747,957,958,961],{"class":749,"line":830},[747,959,960],{"class":753},"    podSubnets",[747,962,758],{"class":757},[747,964,965,967,970,973],{"class":749,"line":836},[747,966,799],{"class":757},[747,968,969],{"class":757}," \"",[747,971,972],{"class":802},"fd40:10::\u002F96",[747,974,975],{"class":757},"\"\n",[747,977,978],{"class":749,"line":842},[747,979,980],{"class":772},"    # Only provide an IPv6 serviceSubnet here, so no IPv4 is allocated\u002Fused.\n",[747,982,983,986],{"class":749,"line":850},[747,984,985],{"class":753},"    serviceSubnets",[747,987,758],{"class":757},[747,989,990,992,994,997],{"class":749,"line":863},[747,991,799],{"class":757},[747,993,969],{"class":757},[747,995,996],{"class":802},"fd40:10:100::\u002F112",[747,998,975],{"class":757},[747,1000,1001,1004],{"class":749,"line":869},[747,1002,1003],{"class":753},"  controllerManager",[747,1005,758],{"class":757},[747,1007,1008,1011],{"class":749,"line":877},[747,1009,1010],{"class":753},"    extraArgs",[747,1012,758],{"class":757},[747,1014,1016],{"class":749,"line":1015},18,[747,1017,1018],{"class":772},"      # Make sure the kube-controller-manager listens on all interfaces (\"including\" IPv6), this can be\n",[747,1020,1022],{"class":749,"line":1021},19,[747,1023,1024],{"class":772},"      # a security implication as in a public network setting like Hetzner Cloud this would expose the\n",[747,1026,1028],{"class":749,"line":1027},20,[747,1029,1030],{"class":772},"      # kube-controller-manager's endpoints to the public internet. Therefore it is recommended to setup\n",[747,1032,1034],{"class":749,"line":1033},21,[747,1035,1036],{"class":772},"      # a firewall to only allow access from trusted IPs\u002Fnetworks.\n",[747,1038,1040,1043,1045,1047,1050],{"class":749,"line":1039},22,[747,1041,1042],{"class":753},"      bind-address",[747,1044,856],{"class":757},[747,1046,969],{"class":757},[747,1048,1049],{"class":802},"::",[747,1051,975],{"class":757},[747,1053,1055],{"class":749,"line":1054},23,[747,1056,1057],{"class":772},"      # Without disabling the node IPAM controller, this would make the controller hand out \u002F112 networks\n",[747,1059,1061],{"class":749,"line":1060},24,[747,1062,1063],{"class":772},"      # to each node.\n",[747,1065,1067,1070,1072,1074,1077],{"class":749,"line":1066},25,[747,1068,1069],{"class":753},"      node-cidr-mask-size-ipv6",[747,1071,856],{"class":757},[747,1073,969],{"class":757},[747,1075,1076],{"class":802},"112",[747,1078,975],{"class":757},[747,1080,1082],{"class":749,"line":1081},26,[747,1083,1084],{"class":772},"      # Disable Node IPAM controller as we use Talos CCM for the pod network for each node.\n",[747,1086,1088,1091,1093,1095,1098],{"class":749,"line":1087},27,[747,1089,1090],{"class":753},"      controllers",[747,1092,856],{"class":757},[747,1094,969],{"class":757},[747,1096,1097],{"class":802},"*,-node-ipam-controller",[747,1099,975],{"class":757},[747,1101,1103,1106],{"class":749,"line":1102},28,[747,1104,1105],{"class":753},"  scheduler",[747,1107,758],{"class":757},[747,1109,1111,1113],{"class":749,"line":1110},29,[747,1112,1010],{"class":753},[747,1114,758],{"class":757},[747,1116,1118],{"class":749,"line":1117},30,[747,1119,1120],{"class":772},"      # Make sure the kube-scheduler listens on all interfaces (\"including\" IPv6), this can be\n",[747,1122,1124],{"class":749,"line":1123},31,[747,1125,1126],{"class":772},"      # a security implication, see controllerManager bind-address comment above.\n",[747,1128,1130,1132,1134,1136,1138],{"class":749,"line":1129},32,[747,1131,1042],{"class":753},[747,1133,856],{"class":757},[747,1135,969],{"class":757},[747,1137,1049],{"class":802},[747,1139,975],{"class":757},[747,1141,1143,1146],{"class":749,"line":1142},33,[747,1144,1145],{"class":753},"  etcd",[747,1147,758],{"class":757},[747,1149,1151,1153],{"class":749,"line":1150},34,[747,1152,1010],{"class":753},[747,1154,758],{"class":757},[747,1156,1158],{"class":749,"line":1157},35,[747,1159,1160],{"class":772},"      # Make sure the etcd metrics listens on all interfaces (\"including\" IPv6), this can be\n",[747,1162,1164],{"class":749,"line":1163},36,[747,1165,1126],{"class":772},[747,1167,1169],{"class":749,"line":1168},37,[747,1170,1171],{"class":772},"      # Note: This is optional, only needed if you want to easily scrape etcd metrics.\n",[747,1173,1175,1178,1180,1182,1185],{"class":749,"line":1174},38,[747,1176,1177],{"class":753},"      listen-metrics-urls",[747,1179,856],{"class":757},[747,1181,969],{"class":757},[747,1183,1184],{"class":802},"http:\u002F\u002F[::]:2381",[747,1186,975],{"class":757},[613,1188,1190],{"id":1189},"patch-for-worker-nodes","Patch for Worker Nodes",[523,1192,1193],{},"No additional patch needed for only the worker nodes.",[535,1195,1197],{"id":1196},"i-route-therefore-i-am-cilium-cni","\"I route, therefore I am\" - Cilium CNI",[523,1199,1200,1201,1203],{},"Ironically, Cilium CNI technically does less routing because Hetzner Cloud already routes the ",[567,1202,594],{}," networks to the respective servers.",[523,1205,1206],{},"If we don't tell Cilium to use Kubernetes for IP Address Management (IPAM), it would allocate a range itself which we don't want to happen.",[738,1208,1210],{"className":740,"code":1209,"language":742,"meta":743,"style":743},"# This uses Talos kubespan service to connect to the Kubernetes API server.\n# In non-Talos clusters this would be, e.g., the IP of your API server or a load balancer in front of it.\nk8sServiceHost: \"localhost\"\nk8sServicePort: \"7445\"\n\n# Use Cilium with full kube-proxy replacement\nkubeProxyReplacement: true\n\ncni:\n  # Yes, we want Cilium to  be our CNI.\n  install: true\n\nipam:\n  mode: \"kubernetes\"\n\nbpf:\n  masquerade: false\n\n# This can depend on your cloud provider and setup.\nloadBalancer:\n  acceleration: \"native\"\n\nk8s:\n  # We don't want\u002Fneed IPv4 Pod CIDR, so disable it.\n  requireIPv4PodCIDR: false\n  # But require a IPv6 Pod CIDR to be present on the node.\n  requireIPv6PodCIDR: true\n\n# Disable masquerading as the IPv6 networks are (publicly) routed\u002F\"accessible.\"\nenableIPv4Masquerade: false\nenableIPv6Masquerade: false\n\ncgroup:\n  autoMount:\n    # Already done by Talos, no need to do it again in\u002Fby Cilium.\n    enabled: false\n  # This is the path on Talos Linux.\n  # In non-Talos clusters you might need to adjust it and\u002For enable autoMount again.\n  hostRoot: \u002Fsys\u002Ffs\u002Fcgroup\n\n# Make sure the Cilium DaemonSet runs in privileged mode to be able to create everything it needs.\nsecurityContext:\n  privileged: true\n\nipv4:\n  # Who needs that anyway? :-)\n  enabled: false\n\nipv6:\n  # IPv6-only, let's go!\n  enabled: true\n\n# Use native routing mode as Hetzner Cloud already routes the \u002F64 networks to the respective servers,\n# If you intend to enable both IPv4 and IPv6 you might need to adjust this mode accordingly, but\n# otherwise the IPv4 networks need to be routable to each server as well.\nroutingMode: \"native\"\n",[567,1211,1212,1217,1222,1236,1250,1256,1261,1270,1274,1281,1286,1295,1299,1306,1320,1324,1331,1341,1345,1350,1357,1371,1375,1382,1387,1396,1401,1410,1414,1419,1428,1437,1441,1448,1455,1460,1468,1473,1478,1489,1494,1500,1508,1518,1523,1531,1537,1547,1552,1560,1566,1575,1580,1586,1592,1598],{"__ignoreMap":743},[747,1213,1214],{"class":749,"line":750},[747,1215,1216],{"class":772},"# This uses Talos kubespan service to connect to the Kubernetes API server.\n",[747,1218,1219],{"class":749,"line":761},[747,1220,1221],{"class":772},"# In non-Talos clusters this would be, e.g., the IP of your API server or a load balancer in front of it.\n",[747,1223,1224,1227,1229,1231,1234],{"class":749,"line":769},[747,1225,1226],{"class":753},"k8sServiceHost",[747,1228,856],{"class":757},[747,1230,969],{"class":757},[747,1232,1233],{"class":802},"localhost",[747,1235,975],{"class":757},[747,1237,1238,1241,1243,1245,1248],{"class":749,"line":776},[747,1239,1240],{"class":753},"k8sServicePort",[747,1242,856],{"class":757},[747,1244,969],{"class":757},[747,1246,1247],{"class":802},"7445",[747,1249,975],{"class":757},[747,1251,1252],{"class":749,"line":784},[747,1253,1255],{"emptyLinePlaceholder":1254},true,"\n",[747,1257,1258],{"class":749,"line":790},[747,1259,1260],{"class":772},"# Use Cilium with full kube-proxy replacement\n",[747,1262,1263,1266,1268],{"class":749,"line":796},[747,1264,1265],{"class":753},"kubeProxyReplacement",[747,1267,856],{"class":757},[747,1269,860],{"class":859},[747,1271,1272],{"class":749,"line":806},[747,1273,1255],{"emptyLinePlaceholder":1254},[747,1275,1276,1279],{"class":749,"line":814},[747,1277,1278],{"class":753},"cni",[747,1280,758],{"class":757},[747,1282,1283],{"class":749,"line":822},[747,1284,1285],{"class":772},"  # Yes, we want Cilium to  be our CNI.\n",[747,1287,1288,1291,1293],{"class":749,"line":830},[747,1289,1290],{"class":753},"  install",[747,1292,856],{"class":757},[747,1294,860],{"class":859},[747,1296,1297],{"class":749,"line":836},[747,1298,1255],{"emptyLinePlaceholder":1254},[747,1300,1301,1304],{"class":749,"line":842},[747,1302,1303],{"class":753},"ipam",[747,1305,758],{"class":757},[747,1307,1308,1311,1313,1315,1318],{"class":749,"line":850},[747,1309,1310],{"class":753},"  mode",[747,1312,856],{"class":757},[747,1314,969],{"class":757},[747,1316,1317],{"class":802},"kubernetes",[747,1319,975],{"class":757},[747,1321,1322],{"class":749,"line":863},[747,1323,1255],{"emptyLinePlaceholder":1254},[747,1325,1326,1329],{"class":749,"line":869},[747,1327,1328],{"class":753},"bpf",[747,1330,758],{"class":757},[747,1332,1333,1336,1338],{"class":749,"line":877},[747,1334,1335],{"class":753},"  masquerade",[747,1337,856],{"class":757},[747,1339,1340],{"class":859}," false\n",[747,1342,1343],{"class":749,"line":1015},[747,1344,1255],{"emptyLinePlaceholder":1254},[747,1346,1347],{"class":749,"line":1021},[747,1348,1349],{"class":772},"# This can depend on your cloud provider and setup.\n",[747,1351,1352,1355],{"class":749,"line":1027},[747,1353,1354],{"class":753},"loadBalancer",[747,1356,758],{"class":757},[747,1358,1359,1362,1364,1366,1369],{"class":749,"line":1033},[747,1360,1361],{"class":753},"  acceleration",[747,1363,856],{"class":757},[747,1365,969],{"class":757},[747,1367,1368],{"class":802},"native",[747,1370,975],{"class":757},[747,1372,1373],{"class":749,"line":1039},[747,1374,1255],{"emptyLinePlaceholder":1254},[747,1376,1377,1380],{"class":749,"line":1054},[747,1378,1379],{"class":753},"k8s",[747,1381,758],{"class":757},[747,1383,1384],{"class":749,"line":1060},[747,1385,1386],{"class":772},"  # We don't want\u002Fneed IPv4 Pod CIDR, so disable it.\n",[747,1388,1389,1392,1394],{"class":749,"line":1066},[747,1390,1391],{"class":753},"  requireIPv4PodCIDR",[747,1393,856],{"class":757},[747,1395,1340],{"class":859},[747,1397,1398],{"class":749,"line":1081},[747,1399,1400],{"class":772},"  # But require a IPv6 Pod CIDR to be present on the node.\n",[747,1402,1403,1406,1408],{"class":749,"line":1087},[747,1404,1405],{"class":753},"  requireIPv6PodCIDR",[747,1407,856],{"class":757},[747,1409,860],{"class":859},[747,1411,1412],{"class":749,"line":1102},[747,1413,1255],{"emptyLinePlaceholder":1254},[747,1415,1416],{"class":749,"line":1110},[747,1417,1418],{"class":772},"# Disable masquerading as the IPv6 networks are (publicly) routed\u002F\"accessible.\"\n",[747,1420,1421,1424,1426],{"class":749,"line":1117},[747,1422,1423],{"class":753},"enableIPv4Masquerade",[747,1425,856],{"class":757},[747,1427,1340],{"class":859},[747,1429,1430,1433,1435],{"class":749,"line":1123},[747,1431,1432],{"class":753},"enableIPv6Masquerade",[747,1434,856],{"class":757},[747,1436,1340],{"class":859},[747,1438,1439],{"class":749,"line":1129},[747,1440,1255],{"emptyLinePlaceholder":1254},[747,1442,1443,1446],{"class":749,"line":1142},[747,1444,1445],{"class":753},"cgroup",[747,1447,758],{"class":757},[747,1449,1450,1453],{"class":749,"line":1150},[747,1451,1452],{"class":753},"  autoMount",[747,1454,758],{"class":757},[747,1456,1457],{"class":749,"line":1157},[747,1458,1459],{"class":772},"    # Already done by Talos, no need to do it again in\u002Fby Cilium.\n",[747,1461,1462,1464,1466],{"class":749,"line":1163},[747,1463,853],{"class":753},[747,1465,856],{"class":757},[747,1467,1340],{"class":859},[747,1469,1470],{"class":749,"line":1168},[747,1471,1472],{"class":772},"  # This is the path on Talos Linux.\n",[747,1474,1475],{"class":749,"line":1174},[747,1476,1477],{"class":772},"  # In non-Talos clusters you might need to adjust it and\u002For enable autoMount again.\n",[747,1479,1481,1484,1486],{"class":749,"line":1480},39,[747,1482,1483],{"class":753},"  hostRoot",[747,1485,856],{"class":757},[747,1487,1488],{"class":802}," \u002Fsys\u002Ffs\u002Fcgroup\n",[747,1490,1492],{"class":749,"line":1491},40,[747,1493,1255],{"emptyLinePlaceholder":1254},[747,1495,1497],{"class":749,"line":1496},41,[747,1498,1499],{"class":772},"# Make sure the Cilium DaemonSet runs in privileged mode to be able to create everything it needs.\n",[747,1501,1503,1506],{"class":749,"line":1502},42,[747,1504,1505],{"class":753},"securityContext",[747,1507,758],{"class":757},[747,1509,1511,1514,1516],{"class":749,"line":1510},43,[747,1512,1513],{"class":753},"  privileged",[747,1515,856],{"class":757},[747,1517,860],{"class":859},[747,1519,1521],{"class":749,"line":1520},44,[747,1522,1255],{"emptyLinePlaceholder":1254},[747,1524,1526,1529],{"class":749,"line":1525},45,[747,1527,1528],{"class":753},"ipv4",[747,1530,758],{"class":757},[747,1532,1534],{"class":749,"line":1533},46,[747,1535,1536],{"class":772},"  # Who needs that anyway? :-)\n",[747,1538,1540,1543,1545],{"class":749,"line":1539},47,[747,1541,1542],{"class":753},"  enabled",[747,1544,856],{"class":757},[747,1546,1340],{"class":859},[747,1548,1550],{"class":749,"line":1549},48,[747,1551,1255],{"emptyLinePlaceholder":1254},[747,1553,1555,1558],{"class":749,"line":1554},49,[747,1556,1557],{"class":753},"ipv6",[747,1559,758],{"class":757},[747,1561,1563],{"class":749,"line":1562},50,[747,1564,1565],{"class":772},"  # IPv6-only, let's go!\n",[747,1567,1569,1571,1573],{"class":749,"line":1568},51,[747,1570,1542],{"class":753},[747,1572,856],{"class":757},[747,1574,860],{"class":859},[747,1576,1578],{"class":749,"line":1577},52,[747,1579,1255],{"emptyLinePlaceholder":1254},[747,1581,1583],{"class":749,"line":1582},53,[747,1584,1585],{"class":772},"# Use native routing mode as Hetzner Cloud already routes the \u002F64 networks to the respective servers,\n",[747,1587,1589],{"class":749,"line":1588},54,[747,1590,1591],{"class":772},"# If you intend to enable both IPv4 and IPv6 you might need to adjust this mode accordingly, but\n",[747,1593,1595],{"class":749,"line":1594},55,[747,1596,1597],{"class":772},"# otherwise the IPv4 networks need to be routable to each server as well.\n",[747,1599,1601,1604,1606,1608,1610],{"class":749,"line":1600},56,[747,1602,1603],{"class":753},"routingMode",[747,1605,856],{"class":757},[747,1607,969],{"class":757},[747,1609,1368],{"class":802},[747,1611,975],{"class":757},[523,1613,1614,1615,1618],{},"The helm install\u002Fupgrade command I used to install Cilium CNI version 1.17.2 with the above config in the ",[567,1616,1617],{},"cilium-values.yaml"," file.:",[738,1620,1624],{"className":1621,"code":1622,"language":1623,"meta":743,"style":743},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","helm upgrade -i \\\n    --namespace=kube-system \\\n    --version=1.18.2 \\\n    -f cilium-values.yaml \\\n    cilium \\\n    cilium\u002Fcilium\n","bash",[567,1625,1626,1642,1649,1656,1666,1673],{"__ignoreMap":743},[747,1627,1628,1632,1635,1638],{"class":749,"line":750},[747,1629,1631],{"class":1630},"sBMFI","helm",[747,1633,1634],{"class":802}," upgrade",[747,1636,1637],{"class":802}," -i",[747,1639,1641],{"class":1640},"sTEyZ"," \\\n",[747,1643,1644,1647],{"class":749,"line":761},[747,1645,1646],{"class":802},"    --namespace=kube-system",[747,1648,1641],{"class":1640},[747,1650,1651,1654],{"class":749,"line":769},[747,1652,1653],{"class":802},"    --version=1.18.2",[747,1655,1641],{"class":1640},[747,1657,1658,1661,1664],{"class":749,"line":776},[747,1659,1660],{"class":802},"    -f",[747,1662,1663],{"class":802}," cilium-values.yaml",[747,1665,1641],{"class":1640},[747,1667,1668,1671],{"class":749,"line":784},[747,1669,1670],{"class":802},"    cilium",[747,1672,1641],{"class":1640},[747,1674,1675],{"class":749,"line":790},[747,1676,1677],{"class":802},"    cilium\u002Fcilium\n",[535,1679,1681],{"id":1680},"cloud-controller-to-the-rescue-allocating-ipv6-cidrs","Cloud Controller To The Rescue - Allocating IPv6 CIDRs",[523,1683,1684,1685,1687,1688,1690],{},"As mentioned before, Hetzner Cloud gives each server a routed ",[567,1686,594],{}," network. But how do we make sure that the pods on each node get use IPs from the ",[567,1689,594],{}," network assigned to them?\nThat's where the Talos Cloud Controller Manager (CCM) comes into play.",[523,1692,1693,1694,1697,1698,595],{},"With the following config it will allocate ",[567,1695,1696],{},"\u002F80"," networks to each node from their respective ",[567,1699,594],{},[738,1701,1703],{"className":740,"code":1702,"language":742,"meta":743,"style":743},"# Enable the node IPAM controller to allocate a network based on each node's \u002F64 network.\nenabledControllers:\n  - cloud-node\n  - node-ipam-controller\n\nextraArgs:\n  # Enable allocating node CIDRs based on each node's \u002F64 network.\n  - --allocate-node-cidrs\n  - --cidr-allocator-type=CloudAllocator\n  # Make sure to allocate \u002F80 networks to each node from their \u002F64 network.\n  - --node-cidr-mask-size-ipv6=80\n\ndaemonSet:\n  # Run as a DaemonSet on each node.\n  enabled: true\n\n# Needs to run when the node(s) is not ready yet to be able to allocate the CIDR before Cilium can start up.\ntolerations:\n  - effect: NoSchedule\n    operator: Exists\n",[567,1704,1705,1710,1717,1725,1732,1736,1743,1748,1755,1762,1767,1774,1778,1785,1790,1798,1802,1807,1814,1826],{"__ignoreMap":743},[747,1706,1707],{"class":749,"line":750},[747,1708,1709],{"class":772},"# Enable the node IPAM controller to allocate a network based on each node's \u002F64 network.\n",[747,1711,1712,1715],{"class":749,"line":761},[747,1713,1714],{"class":753},"enabledControllers",[747,1716,758],{"class":757},[747,1718,1719,1722],{"class":749,"line":769},[747,1720,1721],{"class":757},"  -",[747,1723,1724],{"class":802}," cloud-node\n",[747,1726,1727,1729],{"class":749,"line":776},[747,1728,1721],{"class":757},[747,1730,1731],{"class":802}," node-ipam-controller\n",[747,1733,1734],{"class":749,"line":784},[747,1735,1255],{"emptyLinePlaceholder":1254},[747,1737,1738,1741],{"class":749,"line":790},[747,1739,1740],{"class":753},"extraArgs",[747,1742,758],{"class":757},[747,1744,1745],{"class":749,"line":796},[747,1746,1747],{"class":772},"  # Enable allocating node CIDRs based on each node's \u002F64 network.\n",[747,1749,1750,1752],{"class":749,"line":806},[747,1751,1721],{"class":757},[747,1753,1754],{"class":802}," --allocate-node-cidrs\n",[747,1756,1757,1759],{"class":749,"line":814},[747,1758,1721],{"class":757},[747,1760,1761],{"class":802}," --cidr-allocator-type=CloudAllocator\n",[747,1763,1764],{"class":749,"line":822},[747,1765,1766],{"class":772},"  # Make sure to allocate \u002F80 networks to each node from their \u002F64 network.\n",[747,1768,1769,1771],{"class":749,"line":830},[747,1770,1721],{"class":757},[747,1772,1773],{"class":802}," --node-cidr-mask-size-ipv6=80\n",[747,1775,1776],{"class":749,"line":836},[747,1777,1255],{"emptyLinePlaceholder":1254},[747,1779,1780,1783],{"class":749,"line":842},[747,1781,1782],{"class":753},"daemonSet",[747,1784,758],{"class":757},[747,1786,1787],{"class":749,"line":850},[747,1788,1789],{"class":772},"  # Run as a DaemonSet on each node.\n",[747,1791,1792,1794,1796],{"class":749,"line":863},[747,1793,1542],{"class":753},[747,1795,856],{"class":757},[747,1797,860],{"class":859},[747,1799,1800],{"class":749,"line":869},[747,1801,1255],{"emptyLinePlaceholder":1254},[747,1803,1804],{"class":749,"line":877},[747,1805,1806],{"class":772},"# Needs to run when the node(s) is not ready yet to be able to allocate the CIDR before Cilium can start up.\n",[747,1808,1809,1812],{"class":749,"line":1015},[747,1810,1811],{"class":753},"tolerations",[747,1813,758],{"class":757},[747,1815,1816,1818,1821,1823],{"class":749,"line":1021},[747,1817,1721],{"class":757},[747,1819,1820],{"class":753}," effect",[747,1822,856],{"class":757},[747,1824,1825],{"class":802}," NoSchedule\n",[747,1827,1828,1831,1833],{"class":749,"line":1027},[747,1829,1830],{"class":753},"    operator",[747,1832,856],{"class":757},[747,1834,1835],{"class":802}," Exists\n",[523,1837,1838,1839,1842],{},"The helm install\u002Fupgrade command I used to install Talos CCM version 0.5.2 with the above config in the ",[567,1840,1841],{},"talos-ccm-values.yaml"," file:",[738,1844,1846],{"className":1621,"code":1845,"language":1623,"meta":743,"style":743},"helm upgrade -i \\\n    --namespace=kube-system \\\n     -f talos-ccm-values.yaml \\\n    talos-cloud-controller-manager \\\n    oci:\u002F\u002Fghcr.io\u002Fsiderolabs\u002Fcharts\u002Ftalos-cloud-controller-manager \\\n    --version 0.5.2\n",[567,1847,1848,1858,1864,1874,1881,1888],{"__ignoreMap":743},[747,1849,1850,1852,1854,1856],{"class":749,"line":750},[747,1851,1631],{"class":1630},[747,1853,1634],{"class":802},[747,1855,1637],{"class":802},[747,1857,1641],{"class":1640},[747,1859,1860,1862],{"class":749,"line":761},[747,1861,1646],{"class":802},[747,1863,1641],{"class":1640},[747,1865,1866,1869,1872],{"class":749,"line":769},[747,1867,1868],{"class":802},"     -f",[747,1870,1871],{"class":802}," talos-ccm-values.yaml",[747,1873,1641],{"class":1640},[747,1875,1876,1879],{"class":749,"line":776},[747,1877,1878],{"class":802},"    talos-cloud-controller-manager",[747,1880,1641],{"class":1640},[747,1882,1883,1886],{"class":749,"line":784},[747,1884,1885],{"class":802},"    oci:\u002F\u002Fghcr.io\u002Fsiderolabs\u002Fcharts\u002Ftalos-cloud-controller-manager",[747,1887,1641],{"class":1640},[747,1889,1890,1893],{"class":749,"line":790},[747,1891,1892],{"class":802},"    --version",[747,1894,1896],{"class":1895},"sbssI"," 0.5.2\n",[535,1898,1900],{"id":1899},"heres-how-it-looks-in-action","Here's How It Looks In Action",[523,1902,1903,1904,1909],{},"I have deployed Cilium's Star Wars™ demo application to test out the basic behavior, see ",[527,1905,1908],{"href":1906,"rel":1907},"https:\u002F\u002Fdocs.cilium.io\u002Fen\u002Fstable\u002Fgettingstarted\u002Fdemo\u002F#deploy-the-demo-application",[531],"Getting Started with the Star Wars Demo - Cilium documentation",".",[738,1911,1913],{"className":1621,"code":1912,"language":1623,"meta":743,"style":743},"$ kubectl create -n default -f https:\u002F\u002Fraw.githubusercontent.com\u002Fcilium\u002Fcilium\u002FHEAD\u002Fexamples\u002Fminikube\u002Fhttp-sw-app.yaml\n# Wait till the pods are ready\n$ kubectl get -n default pods\n",[567,1914,1915,1938,1943],{"__ignoreMap":743},[747,1916,1917,1920,1923,1926,1929,1932,1935],{"class":749,"line":750},[747,1918,1919],{"class":1630},"$",[747,1921,1922],{"class":802}," kubectl",[747,1924,1925],{"class":802}," create",[747,1927,1928],{"class":802}," -n",[747,1930,1931],{"class":802}," default",[747,1933,1934],{"class":802}," -f",[747,1936,1937],{"class":802}," https:\u002F\u002Fraw.githubusercontent.com\u002Fcilium\u002Fcilium\u002FHEAD\u002Fexamples\u002Fminikube\u002Fhttp-sw-app.yaml\n",[747,1939,1940],{"class":749,"line":761},[747,1941,1942],{"class":772},"# Wait till the pods are ready\n",[747,1944,1945,1947,1949,1952,1954,1956],{"class":749,"line":769},[747,1946,1919],{"class":1630},[747,1948,1922],{"class":802},[747,1950,1951],{"class":802}," get",[747,1953,1928],{"class":802},[747,1955,1931],{"class":802},[747,1957,1958],{"class":802}," pods\n",[738,1960,1962],{"className":1621,"code":1961,"language":1623,"meta":743,"style":743},"$ kubectl get -A svc\nNAMESPACE     NAME                             TYPE        CLUSTER-IP          EXTERNAL-IP   PORT(S)                  AGE\ndefault       deathstar                        ClusterIP   fd40:10:100::b0da   \u003Cnone>        80\u002FTCP                   7m49s\ndefault       kubernetes                       ClusterIP   fd40:10:100::1      \u003Cnone>        443\u002FTCP                  13m\ndefault       talos                            ClusterIP   fd40:10:100::bbf3   \u003Cnone>        50000\u002FTCP                12m\nkube-system   cilium-envoy                     ClusterIP   None                \u003Cnone>        9964\u002FTCP                 11m\nkube-system   hubble-peer                      ClusterIP   fd40:10:100::e43b   \u003Cnone>        443\u002FTCP                  11m\nkube-system   kube-dns                         ClusterIP   fd40:10:100::a      \u003Cnone>        53\u002FUDP,53\u002FTCP,9153\u002FTCP   12m\nkube-system   talos-cloud-controller-manager   ClusterIP   None                \u003Cnone>        50258\u002FTCP                12m\n",[567,1963,1964,1978,2010,2042,2070,2097,2126,2152,2179],{"__ignoreMap":743},[747,1965,1966,1968,1970,1972,1975],{"class":749,"line":750},[747,1967,1919],{"class":1630},[747,1969,1922],{"class":802},[747,1971,1951],{"class":802},[747,1973,1974],{"class":802}," -A",[747,1976,1977],{"class":802}," svc\n",[747,1979,1980,1983,1986,1989,1992,1995,1998,2001,2004,2007],{"class":749,"line":761},[747,1981,1982],{"class":1630},"NAMESPACE",[747,1984,1985],{"class":802},"     NAME",[747,1987,1988],{"class":802},"                             TYPE",[747,1990,1991],{"class":802},"        CLUSTER-IP",[747,1993,1994],{"class":802},"          EXTERNAL-IP",[747,1996,1997],{"class":802},"   PORT",[747,1999,2000],{"class":757},"(",[747,2002,2003],{"class":1630},"S",[747,2005,2006],{"class":757},")",[747,2008,2009],{"class":802},"                  AGE\n",[747,2011,2012,2015,2018,2021,2024,2027,2030,2033,2036,2039],{"class":749,"line":769},[747,2013,2014],{"class":1630},"default",[747,2016,2017],{"class":802},"       deathstar",[747,2019,2020],{"class":802},"                        ClusterIP",[747,2022,2023],{"class":802},"   fd40:10:100::b0da",[747,2025,2026],{"class":757},"   \u003C",[747,2028,2029],{"class":802},"non",[747,2031,2032],{"class":1640},"e",[747,2034,2035],{"class":757},">",[747,2037,2038],{"class":802},"        80\u002FTCP",[747,2040,2041],{"class":802},"                   7m49s\n",[747,2043,2044,2046,2049,2052,2055,2058,2060,2062,2064,2067],{"class":749,"line":776},[747,2045,2014],{"class":1630},[747,2047,2048],{"class":802},"       kubernetes",[747,2050,2051],{"class":802},"                       ClusterIP",[747,2053,2054],{"class":802},"   fd40:10:100::1",[747,2056,2057],{"class":757},"      \u003C",[747,2059,2029],{"class":802},[747,2061,2032],{"class":1640},[747,2063,2035],{"class":757},[747,2065,2066],{"class":802},"        443\u002FTCP",[747,2068,2069],{"class":802},"                  13m\n",[747,2071,2072,2074,2077,2080,2083,2085,2087,2089,2091,2094],{"class":749,"line":784},[747,2073,2014],{"class":1630},[747,2075,2076],{"class":802},"       talos",[747,2078,2079],{"class":802},"                            ClusterIP",[747,2081,2082],{"class":802},"   fd40:10:100::bbf3",[747,2084,2026],{"class":757},[747,2086,2029],{"class":802},[747,2088,2032],{"class":1640},[747,2090,2035],{"class":757},[747,2092,2093],{"class":802},"        50000\u002FTCP",[747,2095,2096],{"class":802},"                12m\n",[747,2098,2099,2102,2105,2108,2111,2114,2116,2118,2120,2123],{"class":749,"line":790},[747,2100,2101],{"class":1630},"kube-system",[747,2103,2104],{"class":802},"   cilium-envoy",[747,2106,2107],{"class":802},"                     ClusterIP",[747,2109,2110],{"class":802},"   None",[747,2112,2113],{"class":757},"                \u003C",[747,2115,2029],{"class":802},[747,2117,2032],{"class":1640},[747,2119,2035],{"class":757},[747,2121,2122],{"class":802},"        9964\u002FTCP",[747,2124,2125],{"class":802},"                 11m\n",[747,2127,2128,2130,2133,2136,2139,2141,2143,2145,2147,2149],{"class":749,"line":796},[747,2129,2101],{"class":1630},[747,2131,2132],{"class":802},"   hubble-peer",[747,2134,2135],{"class":802},"                      ClusterIP",[747,2137,2138],{"class":802},"   fd40:10:100::e43b",[747,2140,2026],{"class":757},[747,2142,2029],{"class":802},[747,2144,2032],{"class":1640},[747,2146,2035],{"class":757},[747,2148,2066],{"class":802},[747,2150,2151],{"class":802},"                  11m\n",[747,2153,2154,2156,2159,2162,2165,2167,2169,2171,2173,2176],{"class":749,"line":806},[747,2155,2101],{"class":1630},[747,2157,2158],{"class":802},"   kube-dns",[747,2160,2161],{"class":802},"                         ClusterIP",[747,2163,2164],{"class":802},"   fd40:10:100::a",[747,2166,2057],{"class":757},[747,2168,2029],{"class":802},[747,2170,2032],{"class":1640},[747,2172,2035],{"class":757},[747,2174,2175],{"class":802},"        53\u002FUDP,53\u002FTCP,9153\u002FTCP",[747,2177,2178],{"class":802},"   12m\n",[747,2180,2181,2183,2186,2189,2191,2193,2195,2197,2199,2202],{"class":749,"line":814},[747,2182,2101],{"class":1630},[747,2184,2185],{"class":802},"   talos-cloud-controller-manager",[747,2187,2188],{"class":802},"   ClusterIP",[747,2190,2110],{"class":802},[747,2192,2113],{"class":757},[747,2194,2029],{"class":802},[747,2196,2032],{"class":1640},[747,2198,2035],{"class":757},[747,2200,2201],{"class":802},"        50258\u002FTCP",[747,2203,2096],{"class":802},[738,2205,2207],{"className":1621,"code":2206,"language":1623,"meta":743,"style":743},"$ kubectl get pod -o wide\nNAME                         READY   STATUS    RESTARTS   AGE     IP                         NODE             NOMINATED NODE   READINESS GATES\ndeathstar-86f85ffb4d-4mt6r   1\u002F1     Running   0          36s     2a01:4f8:c014:f084::3cd2   talos-worker-2   \u003Cnone>           \u003Cnone>\ndeathstar-86f85ffb4d-7jpb4   1\u002F1     Running   0          2m12s   2a01:4f8:c014:34b1::2f8f   talos-worker-1   \u003Cnone>           \u003Cnone>\ntiefighter                   1\u002F1     Running   0          2m12s   2a01:4f8:c014:f084::f280   talos-worker-2   \u003Cnone>           \u003Cnone>\nxwing                        1\u002F1     Running   0          8s      2a01:4f8:c014:34b1::c396   talos-worker-1   \u003Cnone>           \u003Cnone>\n",[567,2208,2209,2226,2261,2302,2338,2373],{"__ignoreMap":743},[747,2210,2211,2213,2215,2217,2220,2223],{"class":749,"line":750},[747,2212,1919],{"class":1630},[747,2214,1922],{"class":802},[747,2216,1951],{"class":802},[747,2218,2219],{"class":802}," pod",[747,2221,2222],{"class":802}," -o",[747,2224,2225],{"class":802}," wide\n",[747,2227,2228,2231,2234,2237,2240,2243,2246,2249,2252,2255,2258],{"class":749,"line":761},[747,2229,2230],{"class":1630},"NAME",[747,2232,2233],{"class":802},"                         READY",[747,2235,2236],{"class":802},"   STATUS",[747,2238,2239],{"class":802},"    RESTARTS",[747,2241,2242],{"class":802},"   AGE",[747,2244,2245],{"class":802},"     IP",[747,2247,2248],{"class":802},"                         NODE",[747,2250,2251],{"class":802},"             NOMINATED",[747,2253,2254],{"class":802}," NODE",[747,2256,2257],{"class":802},"   READINESS",[747,2259,2260],{"class":802}," GATES\n",[747,2262,2263,2266,2269,2272,2275,2278,2281,2284,2286,2288,2290,2292,2295,2297,2299],{"class":749,"line":769},[747,2264,2265],{"class":1630},"deathstar-86f85ffb4d-4mt6r",[747,2267,2268],{"class":802},"   1\u002F1",[747,2270,2271],{"class":802},"     Running",[747,2273,2274],{"class":1895},"   0",[747,2276,2277],{"class":802},"          36s",[747,2279,2280],{"class":802},"     2a01:4f8:c014:f084::3cd2",[747,2282,2283],{"class":802},"   talos-worker-2",[747,2285,2026],{"class":757},[747,2287,2029],{"class":802},[747,2289,2032],{"class":1640},[747,2291,2035],{"class":757},[747,2293,2294],{"class":757},"           \u003C",[747,2296,2029],{"class":802},[747,2298,2032],{"class":1640},[747,2300,2301],{"class":757},">\n",[747,2303,2304,2307,2309,2311,2313,2316,2319,2322,2324,2326,2328,2330,2332,2334,2336],{"class":749,"line":776},[747,2305,2306],{"class":1630},"deathstar-86f85ffb4d-7jpb4",[747,2308,2268],{"class":802},[747,2310,2271],{"class":802},[747,2312,2274],{"class":1895},[747,2314,2315],{"class":802},"          2m12s",[747,2317,2318],{"class":802},"   2a01:4f8:c014:34b1::2f8f",[747,2320,2321],{"class":802},"   talos-worker-1",[747,2323,2026],{"class":757},[747,2325,2029],{"class":802},[747,2327,2032],{"class":1640},[747,2329,2035],{"class":757},[747,2331,2294],{"class":757},[747,2333,2029],{"class":802},[747,2335,2032],{"class":1640},[747,2337,2301],{"class":757},[747,2339,2340,2343,2346,2348,2350,2352,2355,2357,2359,2361,2363,2365,2367,2369,2371],{"class":749,"line":784},[747,2341,2342],{"class":1630},"tiefighter",[747,2344,2345],{"class":802},"                   1\u002F1",[747,2347,2271],{"class":802},[747,2349,2274],{"class":1895},[747,2351,2315],{"class":802},[747,2353,2354],{"class":802},"   2a01:4f8:c014:f084::f280",[747,2356,2283],{"class":802},[747,2358,2026],{"class":757},[747,2360,2029],{"class":802},[747,2362,2032],{"class":1640},[747,2364,2035],{"class":757},[747,2366,2294],{"class":757},[747,2368,2029],{"class":802},[747,2370,2032],{"class":1640},[747,2372,2301],{"class":757},[747,2374,2375,2378,2381,2383,2385,2388,2391,2393,2395,2397,2399,2401,2403,2405,2407],{"class":749,"line":790},[747,2376,2377],{"class":1630},"xwing",[747,2379,2380],{"class":802},"                        1\u002F1",[747,2382,2271],{"class":802},[747,2384,2274],{"class":1895},[747,2386,2387],{"class":802},"          8s",[747,2389,2390],{"class":802},"      2a01:4f8:c014:34b1::c396",[747,2392,2321],{"class":802},[747,2394,2026],{"class":757},[747,2396,2029],{"class":802},[747,2398,2032],{"class":1640},[747,2400,2035],{"class":757},[747,2402,2294],{"class":757},[747,2404,2029],{"class":802},[747,2406,2032],{"class":1640},[747,2408,2301],{"class":757},[738,2410,2412],{"className":1621,"code":2411,"language":1623,"meta":743,"style":743},"$ kubectl get nodes -o wide\nNAME                    STATUS                     ROLES           AGE     VERSION   INTERNAL-IP             EXTERNAL-IP   OS-IMAGE          KERNEL-VERSION   CONTAINER-RUNTIME\ntalos-control-plane-1   Ready                      control-plane   8m24s   v1.32.3   2a01:4f8:c014:b0a7::1   \u003Cnone>        Talos (v1.11.2)   6.12.48-talos    containerd:\u002F\u002F2.1.4\ntalos-worker-1          Ready                      \u003Cnone>          8m14s   v1.32.3   2a01:4f8:c014:34b1::1   \u003Cnone>        Talos (v1.11.2)   6.12.48-talos    containerd:\u002F\u002F2.1.4\ntalos-worker-2          Ready,SchedulingDisabled   \u003Cnone>          4m18s   v1.32.3   2a01:4f8:c014:f084::1   \u003Cnone>        Talos (v1.11.2)   6.12.48-talos    containerd:\u002F\u002F2.1.4\n",[567,2413,2414,2429,2460,2494,2531],{"__ignoreMap":743},[747,2415,2416,2418,2420,2422,2425,2427],{"class":749,"line":750},[747,2417,1919],{"class":1630},[747,2419,1922],{"class":802},[747,2421,1951],{"class":802},[747,2423,2424],{"class":802}," nodes",[747,2426,2222],{"class":802},[747,2428,2225],{"class":802},[747,2430,2431,2433,2436,2439,2442,2445,2448,2451,2454,2457],{"class":749,"line":761},[747,2432,2230],{"class":1630},[747,2434,2435],{"class":802},"                    STATUS",[747,2437,2438],{"class":802},"                     ROLES",[747,2440,2441],{"class":802},"           AGE",[747,2443,2444],{"class":802},"     VERSION",[747,2446,2447],{"class":802},"   INTERNAL-IP",[747,2449,2450],{"class":802},"             EXTERNAL-IP",[747,2452,2453],{"class":802},"   OS-IMAGE",[747,2455,2456],{"class":802},"          KERNEL-VERSION",[747,2458,2459],{"class":802},"   CONTAINER-RUNTIME\n",[747,2461,2462,2465,2468,2471,2474,2477,2480,2482,2484,2486,2488,2491],{"class":749,"line":769},[747,2463,2464],{"class":1630},"talos-control-plane-1",[747,2466,2467],{"class":802},"   Ready",[747,2469,2470],{"class":802},"                      control-plane",[747,2472,2473],{"class":802},"   8m24s",[747,2475,2476],{"class":802},"   v1.32.3",[747,2478,2479],{"class":802},"   2a01:4f8:c014:b0a7::1",[747,2481,2026],{"class":757},[747,2483,2029],{"class":802},[747,2485,2032],{"class":1640},[747,2487,2035],{"class":757},[747,2489,2490],{"class":802},"        Talos",[747,2492,2493],{"class":1640}," (v1.11.2)   6.12.48-talos    containerd:\u002F\u002F2.1.4\n",[747,2495,2496,2499,2502,2505,2507,2509,2511,2514,2516,2519,2521,2523,2525,2527,2529],{"class":749,"line":776},[747,2497,2498],{"class":1630},"talos-worker-1",[747,2500,2501],{"class":802},"          Ready",[747,2503,2504],{"class":757},"                      \u003C",[747,2506,2029],{"class":802},[747,2508,2032],{"class":1640},[747,2510,2035],{"class":757},[747,2512,2513],{"class":802},"          8m14s",[747,2515,2476],{"class":802},[747,2517,2518],{"class":802},"   2a01:4f8:c014:34b1::1",[747,2520,2026],{"class":757},[747,2522,2029],{"class":802},[747,2524,2032],{"class":1640},[747,2526,2035],{"class":757},[747,2528,2490],{"class":802},[747,2530,2493],{"class":1640},[747,2532,2533,2536,2539,2541,2543,2545,2547,2550,2552,2555,2557,2559,2561,2563,2565],{"class":749,"line":784},[747,2534,2535],{"class":1630},"talos-worker-2",[747,2537,2538],{"class":802},"          Ready,SchedulingDisabled",[747,2540,2026],{"class":757},[747,2542,2029],{"class":802},[747,2544,2032],{"class":1640},[747,2546,2035],{"class":757},[747,2548,2549],{"class":802},"          4m18s",[747,2551,2476],{"class":802},[747,2553,2554],{"class":802},"   2a01:4f8:c014:f084::1",[747,2556,2026],{"class":757},[747,2558,2029],{"class":802},[747,2560,2032],{"class":1640},[747,2562,2035],{"class":757},[747,2564,2490],{"class":802},[747,2566,2493],{"class":1640},[523,2568,2569,2570,2572],{},"Scheduling has been disabled for ",[567,2571,2535],{}," so that the demo app is running \"50\u002F50\" on the two nodes in the cluster.",[738,2574,2576],{"className":1621,"code":2575,"language":1623,"meta":743,"style":743},"$ kubectl exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local\u002Fv1\u002Frequest-landing\nShip landed\n$ kubectl exec xwing -- curl -s -XPOST deathstar.default.svc.cluster.local\u002Fv1\u002Frequest-landing\nShip landed\n$ kubectl get pod -o wide\nNAME                         READY   STATUS    RESTARTS   AGE     IP                         NODE             NOMINATED NODE   READINESS GATES\ndeathstar-86f85ffb4d-7jpb4   1\u002F1     Running   0          6m19s   2a01:4f8:c014:34b1::2f8f   talos-worker-1   \u003Cnone>           \u003Cnone>\ndeathstar-86f85ffb4d-q6l6f   1\u002F1     Running   0          66s     2a01:4f8:c014:34b1::9811   talos-worker-1   \u003Cnone>           \u003Cnone>\ntiefighter                   1\u002F1     Running   0          6m19s   2a01:4f8:c014:f084::f280   talos-worker-2   \u003Cnone>           \u003Cnone>\nxwing                        1\u002F1     Running   0          4m15s   2a01:4f8:c014:34b1::c396   talos-worker-1   \u003Cnone>           \u003Cnone>\n",[567,2577,2578,2605,2613,2634,2640,2654,2678,2711,2746,2778],{"__ignoreMap":743},[747,2579,2580,2582,2584,2587,2590,2593,2596,2599,2602],{"class":749,"line":750},[747,2581,1919],{"class":1630},[747,2583,1922],{"class":802},[747,2585,2586],{"class":802}," exec",[747,2588,2589],{"class":802}," tiefighter",[747,2591,2592],{"class":802}," --",[747,2594,2595],{"class":802}," curl",[747,2597,2598],{"class":802}," -s",[747,2600,2601],{"class":802}," -XPOST",[747,2603,2604],{"class":802}," deathstar.default.svc.cluster.local\u002Fv1\u002Frequest-landing\n",[747,2606,2607,2610],{"class":749,"line":761},[747,2608,2609],{"class":1630},"Ship",[747,2611,2612],{"class":802}," landed\n",[747,2614,2615,2617,2619,2621,2624,2626,2628,2630,2632],{"class":749,"line":769},[747,2616,1919],{"class":1630},[747,2618,1922],{"class":802},[747,2620,2586],{"class":802},[747,2622,2623],{"class":802}," xwing",[747,2625,2592],{"class":802},[747,2627,2595],{"class":802},[747,2629,2598],{"class":802},[747,2631,2601],{"class":802},[747,2633,2604],{"class":802},[747,2635,2636,2638],{"class":749,"line":776},[747,2637,2609],{"class":1630},[747,2639,2612],{"class":802},[747,2641,2642,2644,2646,2648,2650,2652],{"class":749,"line":784},[747,2643,1919],{"class":1630},[747,2645,1922],{"class":802},[747,2647,1951],{"class":802},[747,2649,2219],{"class":802},[747,2651,2222],{"class":802},[747,2653,2225],{"class":802},[747,2655,2656,2658,2660,2662,2664,2666,2668,2670,2672,2674,2676],{"class":749,"line":790},[747,2657,2230],{"class":1630},[747,2659,2233],{"class":802},[747,2661,2236],{"class":802},[747,2663,2239],{"class":802},[747,2665,2242],{"class":802},[747,2667,2245],{"class":802},[747,2669,2248],{"class":802},[747,2671,2251],{"class":802},[747,2673,2254],{"class":802},[747,2675,2257],{"class":802},[747,2677,2260],{"class":802},[747,2679,2680,2682,2684,2686,2688,2691,2693,2695,2697,2699,2701,2703,2705,2707,2709],{"class":749,"line":796},[747,2681,2306],{"class":1630},[747,2683,2268],{"class":802},[747,2685,2271],{"class":802},[747,2687,2274],{"class":1895},[747,2689,2690],{"class":802},"          6m19s",[747,2692,2318],{"class":802},[747,2694,2321],{"class":802},[747,2696,2026],{"class":757},[747,2698,2029],{"class":802},[747,2700,2032],{"class":1640},[747,2702,2035],{"class":757},[747,2704,2294],{"class":757},[747,2706,2029],{"class":802},[747,2708,2032],{"class":1640},[747,2710,2301],{"class":757},[747,2712,2713,2716,2718,2720,2722,2725,2728,2730,2732,2734,2736,2738,2740,2742,2744],{"class":749,"line":806},[747,2714,2715],{"class":1630},"deathstar-86f85ffb4d-q6l6f",[747,2717,2268],{"class":802},[747,2719,2271],{"class":802},[747,2721,2274],{"class":1895},[747,2723,2724],{"class":802},"          66s",[747,2726,2727],{"class":802},"     2a01:4f8:c014:34b1::9811",[747,2729,2321],{"class":802},[747,2731,2026],{"class":757},[747,2733,2029],{"class":802},[747,2735,2032],{"class":1640},[747,2737,2035],{"class":757},[747,2739,2294],{"class":757},[747,2741,2029],{"class":802},[747,2743,2032],{"class":1640},[747,2745,2301],{"class":757},[747,2747,2748,2750,2752,2754,2756,2758,2760,2762,2764,2766,2768,2770,2772,2774,2776],{"class":749,"line":814},[747,2749,2342],{"class":1630},[747,2751,2345],{"class":802},[747,2753,2271],{"class":802},[747,2755,2274],{"class":1895},[747,2757,2690],{"class":802},[747,2759,2354],{"class":802},[747,2761,2283],{"class":802},[747,2763,2026],{"class":757},[747,2765,2029],{"class":802},[747,2767,2032],{"class":1640},[747,2769,2035],{"class":757},[747,2771,2294],{"class":757},[747,2773,2029],{"class":802},[747,2775,2032],{"class":1640},[747,2777,2301],{"class":757},[747,2779,2780,2782,2784,2786,2788,2791,2794,2796,2798,2800,2802,2804,2806,2808,2810],{"class":749,"line":822},[747,2781,2377],{"class":1630},[747,2783,2380],{"class":802},[747,2785,2271],{"class":802},[747,2787,2274],{"class":1895},[747,2789,2790],{"class":802},"          4m15s",[747,2792,2793],{"class":802},"   2a01:4f8:c014:34b1::c396",[747,2795,2321],{"class":802},[747,2797,2026],{"class":757},[747,2799,2029],{"class":802},[747,2801,2032],{"class":1640},[747,2803,2035],{"class":757},[747,2805,2294],{"class":757},[747,2807,2029],{"class":802},[747,2809,2032],{"class":1640},[747,2811,2301],{"class":757},[523,2813,2814,2815,2817],{},"This seems to show that everything is working as expected! Pods are getting IPs from the ",[567,2816,594],{}," networks of the respective nodes and communication between pods is working as expected.",[535,2819,2821],{"id":2820},"summarizing-everything-and-some-notes","Summarizing Everything And Some Notes",[523,2823,2824,2825,2827,2828,2830,2831,595],{},"With the configs shown above, we have a working Talos Kubernetes cluster that runs using IPv6-only networking, using the ",[567,2826,594],{}," of each node for the pods running on that node.\nAdditionally we are using Cilium CNI in full kube-proxy replacement mode with Kubernetes-based IPAM to allocate the pod IPs and Talos CCM to allocate the respective ",[567,2829,1696],{}," networks from each node's ",[567,2832,594],{},[523,2834,2835],{},"In addition to that, to workaround the lack of IPv6 connectivity of some services we are using NAT64\u002FDNS64 resolvers to be able to pull container images from IPv4-only registries like GitHub Container Registry.",[523,2837,2838,856],{},[584,2839,2840],{},"Notes",[668,2842,2843,2852],{},[638,2844,2845,2846,2851],{},"You want to make sure that your nodes have proper firewall rules in place to only allow access from your nodes to each other. You might be able to use ",[527,2847,2850],{"href":2848,"rel":2849},"https:\u002F\u002Fdocs.cilium.io\u002Fen\u002Flatest\u002Fsecurity\u002Fhost-firewall\u002F",[531],"Cilium's Host Firewall feature"," for that though I haven't tested it yet.",[638,2853,2854,2855],{},"Make sure to double-check any application you deploy for proper IPv6 support. Some applications might still have issues with IPv6-only networking.\n",[668,2856,2857],{},[638,2858,2859,2860,2865],{},"In the past I had issues with Zalando's postgres-operator not being able to create proper IPv6 connections to the PostgreSQL instances it created. Might be fixed in the meantime, I haven't tested it recently. Haven't deployed it yet but stumbled upon ",[527,2861,2864],{"href":2862,"rel":2863},"https:\u002F\u002Fperconadev.atlassian.net\u002Fbrowse\u002FPXC-3638",[531],"this Percona Jira issue (PXC-3638)"," about \"manual\" configuration being needed to make nodes sync\u002Fjoin correctly.",[523,2867,2868],{},"P.S. In my tests I even deployed the cluster using ARM64 VMs\u002Fservers on Hetzner Cloud and everything worked as expected!",[535,2870,2872],{"id":2871},"the-cherry-on-top-github-repository-with-terraform-code-and-configs","The Cherry On Top - GitHub Repository with Terraform Code and Configs",[523,2874,2875,2876,1909],{},"The repository contains all the code and configs to deploy a Talos Kubernetes cluster with IPv6-only networking on Hetzner Cloud using Terraform (and Packer) is available at\n",[527,2877,2878],{"href":2878,"rel":2879},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fk8s-talos-ipv6-only",[531],[523,2881,2882,2883,2888],{},"Make sure to checkout the ",[527,2884,2887],{"href":2885,"rel":2886},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fk8s-talos-ipv6-only\u002Fblob\u002Fmain\u002FREADME.md",[531],"README.md"," for instructions on how to use it.",[2890,2891,2892],"style",{},"html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":743,"searchDepth":761,"depth":761,"links":2894},[2895,2896,2899,2904,2905,2906,2907,2908],{"id":537,"depth":761,"text":538},{"id":572,"depth":761,"text":573,"children":2897},[2898],{"id":615,"depth":769,"text":616},{"id":695,"depth":761,"text":696,"children":2900},[2901,2902,2903],{"id":732,"depth":769,"text":733},{"id":887,"depth":769,"text":888},{"id":1189,"depth":769,"text":1190},{"id":1196,"depth":761,"text":1197},{"id":1680,"depth":761,"text":1681},{"id":1899,"depth":761,"text":1900},{"id":2820,"depth":761,"text":2821},{"id":2871,"depth":761,"text":2872},"2025-10-13T14:09:13+02:00","Let's set up a Kubernetes cluster that runs using IPv6-only networking, using the \u002F64 networks of your machines, with Talos Linux and Cilium CNI.","md","\u002Fblog\u002F2025\u002Fkubernetes-ipv6-only-for-real-in-good-this-time.jpg",{},"\u002Fblog\u002F2025\u002Fkubernetes-ipv6-only-for-real-in-good-this-time",{"title":511,"description":2910},"3.blog\u002F2025\u002Fkubernetes-ipv6-only-for-real-in-good-this-time","67YCZTnZEdaS3UP9mLplxFbjtnzWeuEYvWCbhaCKmaw",{"id":2919,"title":2920,"authors":2921,"badge":518,"body":2925,"date":12168,"description":12169,"extension":2911,"image":12170,"meta":12172,"navigation":1254,"path":12177,"seo":12178,"stem":12179,"__hash__":12180},"posts\u002F3.blog\u002F2024\u002Fdocker-for-devs-workshop-v3.md","Docker for Devs - Workshop",[2922],{"name":2923,"to":515,"avatar":2924},"Alexander Trost (Senior Trainer Containertechnologien, PCS Pleger Consulting & Services GmbH)",{"src":517},{"type":520,"value":2926,"toc":12090},[2927,2931,2938,2945,2965,2969,2978,2981,2985,2990,2993,3004,3006,3010,3014,3028,3041,3045,3053,3057,3060,3063,3066,3073,3090,3093,3096,3099,3105,3107,3111,3115,3120,3125,3130,3138,3141,3146,3153,3174,3187,3190,3193,3218,3221,3249,3252,3269,3288,3291,3295,3301,3308,3328,3386,3397,3406,3410,3423,3427,3436,3439,3484,3488,3495,3510,3517,3522,3638,3640,3644,3647,3651,3654,3669,3674,4147,4150,4154,4198,4205,4219,4223,5628,5634,5688,5692,5717,5723,5727,5739,5757,5761,5766,5773,5800,5803,5807,5849,5881,5884,5891,5906,5910,5919,5922,5929,5954,5964,5969,6031,6036,6045,6054,6071,6079,6088,6104,6108,6118,6151,6155,6185,6190,6201,6205,6208,6211,6300,6304,6342,6357,6361,6364,6368,6390,6397,6400,6436,6440,6454,6464,6473,6541,6545,6553,6557,6560,6567,6571,6579,6583,6593,6633,6671,6675,6713,6716,6720,6731,6734,6801,6817,6997,7001,7031,7038,7042,7045,7059,7061,7066,7068,7072,7075,7078,7105,7122,7126,7132,7135,7174,7178,7203,7214,7218,7223,7225,7229,7234,7238,7252,7259,7296,7300,7320,7325,7329,7353,7360,7364,7376,7390,7399,7412,7415,7419,7429,7435,7438,7440,7443,7446,7450,7453,7456,7460,7498,7520,7524,7890,7897,7905,7909,7912,7924,7934,7937,7941,8236,8242,8246,8262,8266,8272,8283,8295,8308,8312,8322,8331,8334,8344,8385,8393,8397,8403,8406,8414,8416,8420,8423,8428,8436,8440,8443,8549,8555,8559,8756,8759,8762,8769,8773,8776,8778,8782,8785,8789,8798,8801,8810,8814,8836,8850,8865,8869,8912,8919,8923,8929,8935,8947,8950,8961,8967,8974,8978,8994,8998,9009,9218,9222,9232,9490,9496,9500,9511,9525,9532,9538,9543,9629,9633,9708,9715,9722,9748,9752,9801,9804,9813,9816,9856,9864,9869,9875,9879,9890,9896,10013,10017,10031,10037,10059,10065,10079,10082,10085,10124,10131,10136,10141,10152,10159,10164,10167,10170,10181,10185,10189,10200,10218,10222,10236,10240,10243,10267,10271,10325,10329,10340,10350,10387,10390,10408,10416,10422,10428,10468,10474,10488,10493,10497,10513,10520,10535,10552,10590,10598,10610,10627,10691,10695,10709,10728,10732,10735,10743,10748,10751,10754,10758,10765,10785,10794,10796,10802,10806,10831,10837,10857,11190,11194,11244,11248,11259,11265,11282,11286,11318,11330,11337,11345,11352,11364,11380,11384,11397,11403,11416,11434,11438,11453,11459,11465,11481,11485,11494,11501,11512,11524,11535,11539,11545,11547,11551,11555,11583,11587,11600,11603,11624,11627,11642,11646,11666,11668,11672,11677,11681,11684,11698,11701,11704,11708,11746,11748,11752,11755,11757,11761,11765,11802,11808,12087],[535,2928,2930],{"id":2929},"goal-of-the-workshop","Goal of the Workshop",[523,2932,2933,2934,2937],{},"The workshop is going to show how simple it is to use Docker and why it is worth a thought to implement it into your development workflow.\nThe second topic is how to compose containers with ",[567,2935,2936],{},"docker-compose"," to gain an understanding how everything can play together for, e.g., quick development environments.",[535,2939,2941,2944],{"id":2940},"heads-up-glossary",[584,2942,2943],{},"Heads up"," - \"Glossary\"",[668,2946,2947,2953,2959],{},[638,2948,2949,2952],{},[584,2950,2951],{},"TASK",": Is a refer to a task in the workshop repository.",[638,2954,2955,2958],{},[584,2956,2957],{},"WDWD",": Stands for \"What does what do\" aka \"Me explaining what the things listed below do\" (short forms FTW!). I only explain new things in these sections.",[638,2960,2961,2964],{},[584,2962,2963],{},"Code blocks",": Mostly contain an useful tip or expected command output.",[535,2966,2968],{"id":2967},"group-partition-schema","Group \"Partition Schema\"",[523,2970,2971,2972,2977],{},"Two groups ore more should be good. Per group at least two or more people.\nEvery group works on their own Docker containers adventure.\nIf there are people that aren't as \"advanced\", they can play around with ",[527,2973,2976],{"href":2974,"rel":2975},"https:\u002F\u002Fdocs.docker.com\u002Fswarm\u002Foverview\u002F",[531],"Docker Swarm"," (No tutorial provided in this post!).",[2979,2980],"hr",{},[535,2982,2984],{"id":2983},"readme","README",[523,2986,2987],{},[584,2988,2989],{},"RATM before asking, thanks!",[523,2991,2992],{},"(\"Read & Apply the Manual\")",[523,2994,2995,2996,2999,3000,3003],{},"If you don't know any further, add ",[567,2997,2998],{},"--help"," to the command, to get a help text\u002Fpage that should guide you to your goal or use ",[567,3001,3002],{},"man"," command to show the man(ual) page for the given command.\nIf you can't solve a problem feel free to ask.",[2979,3005],{},[535,3007,3009],{"id":3008},"intro-container-and-microservices","Intro: Container and Microservices",[613,3011,3013],{"id":3012},"why-do-people-like-the-docker-principle","Why do people like the Docker-\"Principle\"?",[523,3015,3016,3017,3019,3020,3023,3024,3027],{},"The Docker-\"Principle\" is simpleness. Making it as simple as possible to for example starting a WordPress instance with database server with only two commands (or one command using ",[567,3018,2936],{},").\nSimpleness that almost everybody, with a little knowledge about using a shell or cmd, could do it. That's what makes Docker great and bad again, because there are a lot of people that have little to no knowledge about \"basic\" troubleshooting. I had open issues, because of people ",[584,3021,3022],{},"A)"," not RTFM, ",[584,3025,3026],{},"B)"," No knowledge about how to troubleshoot problems on their own first.",[523,3029,3030,3031,714,3035,3040],{},"Overall Docker is an awesome tool, that is more and more growing with each release and with all the awesome open source applications for Docker like ",[527,3032,124],{"href":3033,"rel":3034},"http:\u002F\u002Fkubernetes.io\u002F",[531],[527,3036,3039],{"href":3037,"rel":3038},"https:\u002F\u002Fwww.nomadproject.io\u002F",[531],"Nomad",", and many more.",[613,3042,3044],{"id":3043},"micro-what-microservices","Micro-what? Microservices!",[523,3046,3047,3048,3052],{},"Microservices are small gears, like a MySQL database, NoSQL database, Redis, etc., for a big application like Redmine, GitLab, etc.\nThey allow you to test local in a small scale and then scale with your load (",[3049,3050,3051],"em",{},"if done right",").",[613,3054,3056],{"id":3055},"container","Container?!",[523,3058,3059],{},"The container world on the Linux side is huge, the Windows side has started to grow but is still quite uncommon, unless for specific use cases.\nEvery container runs in it's own (kernel) namespace. For this we need to understand how namespaces work.\nA namespace is a separated \"branch\", where processes, mounts, etc. can exist without disturbing other processes, mounts, etc. in other namespaces.",[523,3061,3062],{},"An advantage of namespaces is, that you can limit the cpu, memory, network, etc. for them. For example, a process that goes rogue, can be limited to specific resource limits.",[523,3064,3065],{},"This diagram should make it clear, how namespaces can create \"unlimited\" separated and isolated container environments.",[523,3067,3068],{},[3069,3070],"img",{"alt":3071,"src":3072},"Linux cgroups namespaces hierachy - by Shmuel Csaba Otto Traian","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Flinux-cgroups-namespaces-systemd-hierachy.png",[523,3074,3075],{},[3049,3076,3077,3078,3083,3084,3089],{},"This photo (",[527,3079,3082],{"href":3080,"rel":3081},"https:\u002F\u002Fcommons.wikimedia.org\u002Fwiki\u002FFile:Linux_kernel_unified_hierarchy_cgroups_and_systemd.svg",[531],"original",") is made by Shmuel Csaba Otto Traian, licensed under the ",[527,3085,3088],{"href":3086,"rel":3087},"https:\u002F\u002Fcreativecommons.org\u002Flicenses\u002Fby-sa\u002F3.0\u002Fdeed.en",[531],"CC Attribution-Share Alike 3.0 Unported"," license.",[523,3091,3092],{},"Docker and most other containers utilities not only use namespaces to separate containers from each other. There are several other techniques, that further improve security.",[523,3094,3095],{},"A container uses the existing Linux kernel, there are less resources used, because a container just uses the existing kernel processes and doesn't need to spawn them like when using a virtual machine.",[523,3097,3098],{},"Why is it a good idea to use separate namespaces for networked applications? Because if someone breaches for example your webserver, he is just in the container and not on the host server. If you'll then detect the breach, you just stop the container and would restart it with an updated image version that contains the latest webserver software.",[523,3100,3101,3104],{},[584,3102,3103],{},"TL;DR"," A container is NOT a VM. A container is a \"separate\" Linux system, that runs in an isolated namespaced environment of the running kernel on the running kernel.",[2979,3106],{},[535,3108,3110],{"id":3109},"prepare-for-the-docker-madness","Prepare for the Docker Madness",[613,3112,3114],{"id":3113},"system-requirements-and-installation","System \"Requirements\" and Installation",[523,3116,3117],{},[3049,3118,3119],{},"Insert \"The System Requirements are too damn high\" Meme here",[523,3121,3122],{},[584,3123,3124],{},"Nope, they're not!",[3126,3127,3129],"h4",{"id":3128},"linux-user","Linux User?",[668,3131,3132,3135],{},[638,3133,3134],{},"A working Linux distro",[638,3136,3137],{},"Linux Kernel 4.x or higher (\"included\" in the Virtualbox)",[523,3139,3140],{},"You can run Docker under any kernel 3.16+, but I recommend you to use the latest kernel for the implemented improvements in some of the file system and network systems Docker uses.",[3142,3143,3145],"h5",{"id":3144},"docker-engine-installation","Docker Engine Installation",[523,3147,3148,3149,3152],{},"To install the Docker Engine run the command (for production machines it is recommended to not just ",[567,3150,3151],{},"curl"," and pipe a script into shell like here ;-)):",[738,3154,3156],{"className":1621,"code":3155,"language":1623,"meta":743,"style":743},"curl -sSL https:\u002F\u002Fget.docker.com\u002F | sh\n",[567,3157,3158],{"__ignoreMap":743},[747,3159,3160,3162,3165,3168,3171],{"class":749,"line":750},[747,3161,3151],{"class":1630},[747,3163,3164],{"class":802}," -sSL",[747,3166,3167],{"class":802}," https:\u002F\u002Fget.docker.com\u002F",[747,3169,3170],{"class":757}," |",[747,3172,3173],{"class":1630}," sh\n",[523,3175,3176,3177,3182,3183,1909],{},"For a more details about the installation of the Docker Engine, see the Linux installation ",[527,3178,3181],{"href":3179,"rel":3180},"https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Finstallation\u002Flinux\u002F",[531],"docs"," or the Windows installation ",[527,3184,3181],{"href":3185,"rel":3186},"https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Finstallation\u002Fwindows\u002F",[531],[523,3188,3189],{},"When talking about Docker, we almost always talk about the Docker Engine. Because the Docker Engine is, as the name implies, the engine for the containers.",[523,3191,3192],{},"After you have installed it without any errors popping up, you have to start the Docker Engine.\nWhen your distribution is using systemd:",[738,3194,3196],{"className":1621,"code":3195,"language":1623,"meta":743,"style":743},"systemctl enable docker.service\nsystemctl start docker.service\n",[567,3197,3198,3209],{"__ignoreMap":743},[747,3199,3200,3203,3206],{"class":749,"line":750},[747,3201,3202],{"class":1630},"systemctl",[747,3204,3205],{"class":802}," enable",[747,3207,3208],{"class":802}," docker.service\n",[747,3210,3211,3213,3216],{"class":749,"line":761},[747,3212,3202],{"class":1630},[747,3214,3215],{"class":802}," start",[747,3217,3208],{"class":802},[523,3219,3220],{},"On distribution without systemd:",[738,3222,3224],{"className":1621,"code":3223,"language":1623,"meta":743,"style":743},"\u002Fetc\u002Finit.d\u002Fdocker start\n# or\nservice docker start\n",[567,3225,3226,3234,3239],{"__ignoreMap":743},[747,3227,3228,3231],{"class":749,"line":750},[747,3229,3230],{"class":1630},"\u002Fetc\u002Finit.d\u002Fdocker",[747,3232,3233],{"class":802}," start\n",[747,3235,3236],{"class":749,"line":761},[747,3237,3238],{"class":772},"# or\n",[747,3240,3241,3244,3247],{"class":749,"line":769},[747,3242,3243],{"class":1630},"service",[747,3245,3246],{"class":802}," docker",[747,3248,3233],{"class":802},[523,3250,3251],{},"This starts Docker and when using systemd enables the autostart for Docker Engine.",[523,3253,3254,3255,3258,3259,3261,3262,3264,3265,3268],{},"Now that Docker is installed and the Docker dameon should be running, you now have to add your non-root user to the ",[567,3256,3257],{},"docker"," group (on most distributions the group is called ",[567,3260,3257],{},").\nTo add your user to the ",[567,3263,3257],{}," group, you can run the following command (replace ",[567,3266,3267],{},"USERNAME"," with your user's username):",[738,3270,3272],{"className":1621,"code":3271,"language":1623,"meta":743,"style":743},"gpasswd -a USERNAME docker\n",[567,3273,3274],{"__ignoreMap":743},[747,3275,3276,3279,3282,3285],{"class":749,"line":750},[747,3277,3278],{"class":1630},"gpasswd",[747,3280,3281],{"class":802}," -a",[747,3283,3284],{"class":802}," USERNAME",[747,3286,3287],{"class":802}," docker\n",[523,3289,3290],{},"Please relog or restart your machine after you have added yourself to the group.",[3142,3292,3294],{"id":3293},"docker-compose-installation","docker-compose Installation",[523,3296,3297],{},[3069,3298],{"alt":3299,"src":3300},"docker-compose Logo","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Fdocker-compose-logo.png",[523,3302,3303],{},[3049,3304,3305,3307],{},[567,3306,2936],{}," Logo by Docker",[523,3309,3310,3311,3313,3314,3316,3317,3319,3320,3323,3324,3327],{},"With ",[567,3312,3151],{}," we download the ",[567,3315,2936],{}," binary, then we move ",[567,3318,2936],{}," to your ",[567,3321,3322],{},"\u002Fusr\u002Flocal\u002Fbin"," that is in your ",[567,3325,3326],{},"PATH"," and set the execute permission.",[738,3329,3331],{"className":1621,"code":3330,"language":1623,"meta":743,"style":743},"wget -O \u002Fusr\u002Flocal\u002Fbin\u002Fdocker-compose \"https:\u002F\u002Fgithub.com\u002Fdocker\u002Fcompose\u002Freleases\u002Fdownload\u002F1.8.0\u002Fdocker-compose-`uname -s`-`uname -m`\"\nsudo chmod +x \u002Fusr\u002Flocal\u002Fbin\u002Fdocker-compose\n",[567,3332,3333,3372],{"__ignoreMap":743},[747,3334,3335,3338,3341,3344,3346,3349,3352,3355,3357,3359,3362,3364,3366,3369],{"class":749,"line":750},[747,3336,3337],{"class":1630},"wget",[747,3339,3340],{"class":802}," -O",[747,3342,3343],{"class":802}," \u002Fusr\u002Flocal\u002Fbin\u002Fdocker-compose",[747,3345,969],{"class":757},[747,3347,3348],{"class":802},"https:\u002F\u002Fgithub.com\u002Fdocker\u002Fcompose\u002Freleases\u002Fdownload\u002F1.8.0\u002Fdocker-compose-",[747,3350,3351],{"class":757},"`",[747,3353,3354],{"class":1630},"uname",[747,3356,2598],{"class":802},[747,3358,3351],{"class":757},[747,3360,3361],{"class":802},"-",[747,3363,3351],{"class":757},[747,3365,3354],{"class":1630},[747,3367,3368],{"class":802}," -m",[747,3370,3371],{"class":757},"`\"\n",[747,3373,3374,3377,3380,3383],{"class":749,"line":761},[747,3375,3376],{"class":1630},"sudo",[747,3378,3379],{"class":802}," chmod",[747,3381,3382],{"class":802}," +x",[747,3384,3385],{"class":802}," \u002Fusr\u002Flocal\u002Fbin\u002Fdocker-compose\n",[523,3387,3388,3389,3391,3392,1909],{},"For more detailed ",[567,3390,2936],{}," installation docs, see ",[527,3393,3396],{"href":3394,"rel":3395},"https:\u002F\u002Fdocs.docker.com\u002Fcompose\u002Finstall\u002F",[531],"here",[523,3398,3399,3400,3402,3403,1909],{},"After you have followed the commands above, you can test if you have installed ",[567,3401,2936],{}," successfully by running ",[567,3404,3405],{},"docker-compose --version",[3126,3407,3409],{"id":3408},"windows-user","Windows User?",[668,3411,3412,3415],{},[638,3413,3414],{},"Windows 10 or higher",[638,3416,3417,3418,2006],{},"Ability to install Docker Desktop on your system (",[527,3419,3422],{"href":3420,"rel":3421},"https:\u002F\u002Fdocs.docker.com\u002Fdesktop\u002Finstall\u002Fwindows-install\u002F#system-requirements",[531],"Official Docker Desktop system requirements",[3142,3424,3426],{"id":3425},"docker-desktop-installation","Docker Desktop Installation",[523,3428,3429,3430,3435],{},"Please follow the ",[527,3431,3434],{"href":3432,"rel":3433},"https:\u002F\u002Fdocs.docker.com\u002Fdesktop\u002Finstall\u002Fwindows-install\u002F#install-docker-desktop-on-windows",[531],"up-to-date instructions from the Docker Desktop for Windows documentation"," installations steps.",[523,3437,3438],{},"If you are asked to use\u002Fenable WSL option, make sure to check that opotion.",[597,3440,3441,3444,3476],{},[523,3442,3443],{},"Should you have used WSL in the past and now have issues with WSL in general, you can try to run the following commands in a command line prompt running as administrator:",[738,3445,3447],{"className":1621,"code":3446,"language":1623,"meta":743,"style":743},"wsl --install -d Ubuntu\n\nwsl --set-default Ubuntu\n",[567,3448,3449,3463,3467],{"__ignoreMap":743},[747,3450,3451,3454,3457,3460],{"class":749,"line":750},[747,3452,3453],{"class":1630},"wsl",[747,3455,3456],{"class":802}," --install",[747,3458,3459],{"class":802}," -d",[747,3461,3462],{"class":802}," Ubuntu\n",[747,3464,3465],{"class":749,"line":761},[747,3466,1255],{"emptyLinePlaceholder":1254},[747,3468,3469,3471,3474],{"class":749,"line":769},[747,3470,3453],{"class":1630},[747,3472,3473],{"class":802}," --set-default",[747,3475,3462],{"class":802},[523,3477,3478,3479],{},"Taken from ",[527,3480,3483],{"href":3481,"rel":3482},"https:\u002F\u002Fsuperuser.com\u002Fa\u002F1755115",[531],"Stackoverflow \"The WSL CLI window disappears directly after it has opened -- how to fix that?\" response from User \"anayarojo\"",[613,3485,3487],{"id":3486},"clone-the-workshop-repo","Clone the workshop repo",[523,3489,3490,3491,3494],{},"Clone or Download the Workshop repository from GitHub ",[567,3492,3493],{},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-docker.git",". It'll provide all files and tasks used in the Workshop.",[738,3496,3498],{"className":1621,"code":3497,"language":1623,"meta":743,"style":743},"git clone https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-docker.git\n",[567,3499,3500],{"__ignoreMap":743},[747,3501,3502,3504,3507],{"class":749,"line":750},[747,3503,221],{"class":1630},[747,3505,3506],{"class":802}," clone",[747,3508,3509],{"class":802}," https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-docker.git\n",[523,3511,3512,3513],{},"Or download via this link from GitHub: ",[527,3514,3515],{"href":3515,"rel":3516},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-docker\u002Farchive\u002Frefs\u002Fheads\u002Fmaster.zip",[531],[523,3518,3519],{},[584,3520,3521],{},"Expected Output",[738,3523,3525],{"className":1621,"code":3524,"language":1623,"meta":743,"style":743},"Cloning into 'workshop-docker'...\nremote: Enumerating objects: 526, done.\nremote: Total 526 (delta 0), reused 0 (delta 0), pack-reused 526 (from 1)\nReceiving objects: 100% (526\u002F526), 98.33 KiB | 613.00 KiB\u002Fs, done.\nResolving deltas: 100% (152\u002F152), done.\n",[567,3526,3527,3547,3564,3601,3625],{"__ignoreMap":743},[747,3528,3529,3532,3535,3538,3541,3544],{"class":749,"line":750},[747,3530,3531],{"class":1630},"Cloning",[747,3533,3534],{"class":802}," into",[747,3536,3537],{"class":757}," '",[747,3539,3540],{"class":802},"workshop-docker",[747,3542,3543],{"class":757},"'",[747,3545,3546],{"class":802},"...\n",[747,3548,3549,3552,3555,3558,3561],{"class":749,"line":761},[747,3550,3551],{"class":1630},"remote:",[747,3553,3554],{"class":802}," Enumerating",[747,3556,3557],{"class":802}," objects:",[747,3559,3560],{"class":802}," 526,",[747,3562,3563],{"class":802}," done.\n",[747,3565,3566,3568,3571,3574,3577,3580,3583,3586,3589,3592,3595,3598],{"class":749,"line":769},[747,3567,3551],{"class":1630},[747,3569,3570],{"class":802}," Total",[747,3572,3573],{"class":1895}," 526",[747,3575,3576],{"class":1640}," (delta ",[747,3578,3579],{"class":1895},"0",[747,3581,3582],{"class":1640},"), reused 0 (",[747,3584,3585],{"class":1630},"delta",[747,3587,3588],{"class":1895}," 0",[747,3590,3591],{"class":1640},"), pack-reused 526 (",[747,3593,3594],{"class":1630},"from",[747,3596,3597],{"class":1895}," 1",[747,3599,3600],{"class":1640},")\n",[747,3602,3603,3606,3608,3611,3614,3617,3620,3623],{"class":749,"line":776},[747,3604,3605],{"class":1630},"Receiving",[747,3607,3557],{"class":802},[747,3609,3610],{"class":802}," 100%",[747,3612,3613],{"class":1640}," (526\u002F526), 98.33 KiB ",[747,3615,3616],{"class":757},"|",[747,3618,3619],{"class":1630}," 613.00",[747,3621,3622],{"class":802}," KiB\u002Fs,",[747,3624,3563],{"class":802},[747,3626,3627,3630,3633,3635],{"class":749,"line":784},[747,3628,3629],{"class":1630},"Resolving",[747,3631,3632],{"class":802}," deltas:",[747,3634,3610],{"class":802},[747,3636,3637],{"class":1640}," (152\u002F152), done.\n",[2979,3639],{},[535,3641,3643],{"id":3642},"running-your-first-docker-containers","Running your first Docker containers",[523,3645,3646],{},"This will guide you through the commands needed to start your WordPress instance with MySQL database server.",[613,3648,3650],{"id":3649},"hello-world","Hello World!",[523,3652,3653],{},"Now to test your Docker installation, we start like when learning a new programming language, with the simplest example. A \"Hello World\" container.\nTo run the \"Hello World\" container, you simply run the following command:",[738,3655,3657],{"className":1621,"code":3656,"language":1623,"meta":743,"style":743},"docker run hello-world\n",[567,3658,3659],{"__ignoreMap":743},[747,3660,3661,3663,3666],{"class":749,"line":750},[747,3662,3257],{"class":1630},[747,3664,3665],{"class":802}," run",[747,3667,3668],{"class":802}," hello-world\n",[523,3670,3671],{},[584,3672,3673],{},"Example Output",[738,3675,3677],{"className":1621,"code":3676,"language":1623,"meta":743,"style":743},"$ docker run hello-world\nUnable to find image 'hello-world:latest' locally\nlatest: Pulling from library\u002Fhello-world\nc1ec31eb5944: Pull complete\nDigest: sha256:91fb4b041da273d5a3273b6d587d62d518300a6ad268b28628f74997b93171b2\nStatus: Downloaded newer image for hello-world:latest\n\nHello from Docker!\nThis message shows that your installation appears to be working correctly.\n\nTo generate this message, Docker took the following steps:\n1. The Docker client contacted the Docker daemon.\n2. The Docker daemon pulled the \"hello-world\" image from the Docker Hub.\n    (amd64)\n3. The Docker daemon created a new container from that image which runs the\n    executable that produces the output you are currently reading.\n4. The Docker daemon streamed that output to the Docker client, which sent it\n    to your terminal.\n\nTo try something more ambitious, you can run an Ubuntu container with:\n$ docker run -it ubuntu bash\n\nShare images, automate workflows, and more with a free Docker ID:\nhttps:\u002F\u002Fhub.docker.com\u002F\n\nFor more examples and ideas, visit:\nhttps:\u002F\u002Fdocs.docker.com\u002Fget-started\u002F\n",[567,3678,3679,3689,3713,3727,3738,3746,3765,3769,3779,3813,3817,3846,3869,3904,3914,3952,3979,4014,4024,4028,4062,4079,4083,4115,4120,4124,4142],{"__ignoreMap":743},[747,3680,3681,3683,3685,3687],{"class":749,"line":750},[747,3682,1919],{"class":1630},[747,3684,3246],{"class":802},[747,3686,3665],{"class":802},[747,3688,3668],{"class":802},[747,3690,3691,3694,3697,3700,3703,3705,3708,3710],{"class":749,"line":761},[747,3692,3693],{"class":1630},"Unable",[747,3695,3696],{"class":802}," to",[747,3698,3699],{"class":802}," find",[747,3701,3702],{"class":802}," image",[747,3704,3537],{"class":757},[747,3706,3707],{"class":802},"hello-world:latest",[747,3709,3543],{"class":757},[747,3711,3712],{"class":802}," locally\n",[747,3714,3715,3718,3721,3724],{"class":749,"line":769},[747,3716,3717],{"class":1630},"latest:",[747,3719,3720],{"class":802}," Pulling",[747,3722,3723],{"class":802}," from",[747,3725,3726],{"class":802}," library\u002Fhello-world\n",[747,3728,3729,3732,3735],{"class":749,"line":776},[747,3730,3731],{"class":1630},"c1ec31eb5944:",[747,3733,3734],{"class":802}," Pull",[747,3736,3737],{"class":802}," complete\n",[747,3739,3740,3743],{"class":749,"line":784},[747,3741,3742],{"class":1630},"Digest:",[747,3744,3745],{"class":802}," sha256:91fb4b041da273d5a3273b6d587d62d518300a6ad268b28628f74997b93171b2\n",[747,3747,3748,3751,3754,3757,3759,3762],{"class":749,"line":790},[747,3749,3750],{"class":1630},"Status:",[747,3752,3753],{"class":802}," Downloaded",[747,3755,3756],{"class":802}," newer",[747,3758,3702],{"class":802},[747,3760,3761],{"class":802}," for",[747,3763,3764],{"class":802}," hello-world:latest\n",[747,3766,3767],{"class":749,"line":796},[747,3768,1255],{"emptyLinePlaceholder":1254},[747,3770,3771,3774,3776],{"class":749,"line":806},[747,3772,3773],{"class":1630},"Hello",[747,3775,3723],{"class":802},[747,3777,3778],{"class":802}," Docker!\n",[747,3780,3781,3784,3787,3790,3793,3796,3799,3802,3804,3807,3810],{"class":749,"line":814},[747,3782,3783],{"class":1630},"This",[747,3785,3786],{"class":802}," message",[747,3788,3789],{"class":802}," shows",[747,3791,3792],{"class":802}," that",[747,3794,3795],{"class":802}," your",[747,3797,3798],{"class":802}," installation",[747,3800,3801],{"class":802}," appears",[747,3803,3696],{"class":802},[747,3805,3806],{"class":802}," be",[747,3808,3809],{"class":802}," working",[747,3811,3812],{"class":802}," correctly.\n",[747,3814,3815],{"class":749,"line":822},[747,3816,1255],{"emptyLinePlaceholder":1254},[747,3818,3819,3822,3825,3828,3831,3834,3837,3840,3843],{"class":749,"line":830},[747,3820,3821],{"class":1630},"To",[747,3823,3824],{"class":802}," generate",[747,3826,3827],{"class":802}," this",[747,3829,3830],{"class":802}," message,",[747,3832,3833],{"class":802}," Docker",[747,3835,3836],{"class":802}," took",[747,3838,3839],{"class":802}," the",[747,3841,3842],{"class":802}," following",[747,3844,3845],{"class":802}," steps:\n",[747,3847,3848,3851,3854,3856,3859,3862,3864,3866],{"class":749,"line":836},[747,3849,3850],{"class":1630},"1.",[747,3852,3853],{"class":802}," The",[747,3855,3833],{"class":802},[747,3857,3858],{"class":802}," client",[747,3860,3861],{"class":802}," contacted",[747,3863,3839],{"class":802},[747,3865,3833],{"class":802},[747,3867,3868],{"class":802}," daemon.\n",[747,3870,3871,3874,3876,3878,3881,3884,3886,3888,3890,3893,3895,3897,3899,3901],{"class":749,"line":842},[747,3872,3873],{"class":1630},"2.",[747,3875,3853],{"class":802},[747,3877,3833],{"class":802},[747,3879,3880],{"class":802}," daemon",[747,3882,3883],{"class":802}," pulled",[747,3885,3839],{"class":802},[747,3887,969],{"class":757},[747,3889,3649],{"class":802},[747,3891,3892],{"class":757},"\"",[747,3894,3702],{"class":802},[747,3896,3723],{"class":802},[747,3898,3839],{"class":802},[747,3900,3833],{"class":802},[747,3902,3903],{"class":802}," Hub.\n",[747,3905,3906,3909,3912],{"class":749,"line":850},[747,3907,3908],{"class":757},"    (",[747,3910,3911],{"class":1630},"amd64",[747,3913,3600],{"class":757},[747,3915,3916,3919,3921,3923,3925,3928,3931,3934,3937,3939,3941,3943,3946,3949],{"class":749,"line":863},[747,3917,3918],{"class":1630},"3.",[747,3920,3853],{"class":802},[747,3922,3833],{"class":802},[747,3924,3880],{"class":802},[747,3926,3927],{"class":802}," created",[747,3929,3930],{"class":802}," a",[747,3932,3933],{"class":802}," new",[747,3935,3936],{"class":802}," container",[747,3938,3723],{"class":802},[747,3940,3792],{"class":802},[747,3942,3702],{"class":802},[747,3944,3945],{"class":802}," which",[747,3947,3948],{"class":802}," runs",[747,3950,3951],{"class":802}," the\n",[747,3953,3954,3957,3959,3962,3964,3967,3970,3973,3976],{"class":749,"line":869},[747,3955,3956],{"class":1630},"    executable",[747,3958,3792],{"class":802},[747,3960,3961],{"class":802}," produces",[747,3963,3839],{"class":802},[747,3965,3966],{"class":802}," output",[747,3968,3969],{"class":802}," you",[747,3971,3972],{"class":802}," are",[747,3974,3975],{"class":802}," currently",[747,3977,3978],{"class":802}," reading.\n",[747,3980,3981,3984,3986,3988,3990,3993,3995,3997,3999,4001,4003,4006,4008,4011],{"class":749,"line":877},[747,3982,3983],{"class":1630},"4.",[747,3985,3853],{"class":802},[747,3987,3833],{"class":802},[747,3989,3880],{"class":802},[747,3991,3992],{"class":802}," streamed",[747,3994,3792],{"class":802},[747,3996,3966],{"class":802},[747,3998,3696],{"class":802},[747,4000,3839],{"class":802},[747,4002,3833],{"class":802},[747,4004,4005],{"class":802}," client,",[747,4007,3945],{"class":802},[747,4009,4010],{"class":802}," sent",[747,4012,4013],{"class":802}," it\n",[747,4015,4016,4019,4021],{"class":749,"line":1015},[747,4017,4018],{"class":1630},"    to",[747,4020,3795],{"class":802},[747,4022,4023],{"class":802}," terminal.\n",[747,4025,4026],{"class":749,"line":1021},[747,4027,1255],{"emptyLinePlaceholder":1254},[747,4029,4030,4032,4035,4038,4041,4044,4046,4049,4051,4054,4057,4059],{"class":749,"line":1027},[747,4031,3821],{"class":1630},[747,4033,4034],{"class":802}," try",[747,4036,4037],{"class":802}," something",[747,4039,4040],{"class":802}," more",[747,4042,4043],{"class":802}," ambitious,",[747,4045,3969],{"class":802},[747,4047,4048],{"class":802}," can",[747,4050,3665],{"class":802},[747,4052,4053],{"class":802}," an",[747,4055,4056],{"class":802}," Ubuntu",[747,4058,3936],{"class":802},[747,4060,4061],{"class":802}," with:\n",[747,4063,4064,4066,4068,4070,4073,4076],{"class":749,"line":1033},[747,4065,1919],{"class":1630},[747,4067,3246],{"class":802},[747,4069,3665],{"class":802},[747,4071,4072],{"class":802}," -it",[747,4074,4075],{"class":802}," ubuntu",[747,4077,4078],{"class":802}," bash\n",[747,4080,4081],{"class":749,"line":1039},[747,4082,1255],{"emptyLinePlaceholder":1254},[747,4084,4085,4088,4091,4094,4097,4100,4102,4105,4107,4110,4112],{"class":749,"line":1054},[747,4086,4087],{"class":1630},"Share",[747,4089,4090],{"class":802}," images,",[747,4092,4093],{"class":802}," automate",[747,4095,4096],{"class":802}," workflows,",[747,4098,4099],{"class":802}," and",[747,4101,4040],{"class":802},[747,4103,4104],{"class":802}," with",[747,4106,3930],{"class":802},[747,4108,4109],{"class":802}," free",[747,4111,3833],{"class":802},[747,4113,4114],{"class":802}," ID:\n",[747,4116,4117],{"class":749,"line":1060},[747,4118,4119],{"class":1630},"https:\u002F\u002Fhub.docker.com\u002F\n",[747,4121,4122],{"class":749,"line":1066},[747,4123,1255],{"emptyLinePlaceholder":1254},[747,4125,4126,4129,4131,4134,4136,4139],{"class":749,"line":1081},[747,4127,4128],{"class":1630},"For",[747,4130,4040],{"class":802},[747,4132,4133],{"class":802}," examples",[747,4135,4099],{"class":802},[747,4137,4138],{"class":802}," ideas,",[747,4140,4141],{"class":802}," visit:\n",[747,4143,4144],{"class":749,"line":1087},[747,4145,4146],{"class":1630},"https:\u002F\u002Fdocs.docker.com\u002Fget-started\u002F\n",[523,4148,4149],{},"When everything went correct, I can now welcome you to the big World of the containers!",[613,4151,4153],{"id":4152},"basic-commands-you-need-to-know","Basic commands you need to know",[668,4155,4156,4170,4176,4190],{},[638,4157,4158,4161,4162,4165,4166,4169],{},[567,4159,4160],{},"docker ps","  - Displays all currently running containers. To display all containers, add the ",[567,4163,4164],{},"-a"," option or use the filter option ",[567,4167,4168],{},"-f []"," (can be specified multiple times).",[638,4171,4172,4175],{},[567,4173,4174],{},"docker logs"," - .",[638,4177,4178,4181,4182,4185,4186,4189],{},[567,4179,4180],{},"docker stop CONTAINER"," - Sends a ",[567,4183,4184],{},"SIGTERM"," signal to the containers main process. Where ",[567,4187,4188],{},"CONTAINER"," is a container ID or name.",[638,4191,4192,4195,4196,4189],{},[567,4193,4194],{},"docker rm CONTAINER"," - Deletes a stopped\u002Fexited container. Where ",[567,4197,4188],{},[523,4199,4200,4201,4204],{},"One of the most important commands we need is ",[567,4202,4203],{},"docker run",". So we now take a look at it and run:",[738,4206,4208],{"className":1621,"code":4207,"language":1623,"meta":743,"style":743},"docker run --help\n",[567,4209,4210],{"__ignoreMap":743},[747,4211,4212,4214,4216],{"class":749,"line":750},[747,4213,3257],{"class":1630},[747,4215,3665],{"class":802},[747,4217,4218],{"class":802}," --help\n",[523,4220,4221],{},[584,4222,3521],{},[738,4224,4226],{"className":1621,"code":4225,"language":1623,"meta":743,"style":743},"$ docker run --help\nUsage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]\n\nCreate and run a new container from an image\n\nAliases:\n  docker container run, docker run\n\nOptions:\n      --add-host list                    Add a custom host-to-IP mapping (host:ip)\n      --annotation map                   Add an annotation to the container (passed through to the OCI runtime) (default map[])\n  -a, --attach list                      Attach to STDIN, STDOUT or STDERR\n      --blkio-weight uint16              Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)\n      --blkio-weight-device list         Block IO weight (relative device weight) (default [])\n      --cap-add list                     Add Linux capabilities\n      --cap-drop list                    Drop Linux capabilities\n      --cgroup-parent string             Optional parent cgroup for the container\n      --cgroupns string                  Cgroup namespace to use (host|private)\n                                         'host':    Run the container in the Docker host's cgroup namespace\n                                         'private': Run the container in its own private cgroup namespace\n                                         '':        Use the cgroup namespace as configured by the\n                                                    default-cgroupns-mode option on the daemon (default)\n      --cidfile string                   Write the container ID to the file\n      --cpu-period int                   Limit CPU CFS (Completely Fair Scheduler) period\n      --cpu-quota int                    Limit CPU CFS (Completely Fair Scheduler) quota\n      --cpu-rt-period int                Limit CPU real-time period in microseconds\n      --cpu-rt-runtime int               Limit CPU real-time runtime in microseconds\n  -c, --cpu-shares int                   CPU shares (relative weight)\n      --cpus decimal                     Number of CPUs\n      --cpuset-cpus string               CPUs in which to allow execution (0-3, 0,1)\n      --cpuset-mems string               MEMs in which to allow execution (0-3, 0,1)\n  -d, --detach                           Run container in background and print container ID\n      --detach-keys string               Override the key sequence for detaching a container\n      --device list                      Add a host device to the container\n      --device-cgroup-rule list          Add a rule to the cgroup allowed devices list\n      --device-read-bps list             Limit read rate (bytes per second) from a device (default [])\n      --device-read-iops list            Limit read rate (IO per second) from a device (default [])\n      --device-write-bps list            Limit write rate (bytes per second) to a device (default [])\n      --device-write-iops list           Limit write rate (IO per second) to a device (default [])\n      --disable-content-trust            Skip image verification (default true)\n      --dns list                         Set custom DNS servers\n      --dns-option list                  Set DNS options\n      --dns-search list                  Set custom DNS search domains\n      --domainname string                Container NIS domain name\n      --entrypoint string                Overwrite the default ENTRYPOINT of the image\n  -e, --env list                         Set environment variables\n      --env-file list                    Read in a file of environment variables\n      --expose list                      Expose a port or a range of ports\n      --gpus gpu-request                 GPU devices to add to the container ('all' to pass all GPUs)\n      --group-add list                   Add additional groups to join\n      --health-cmd string                Command to run to check health\n      --health-interval duration         Time between running the check (ms|s|m|h) (default 0s)\n      --health-retries int               Consecutive failures needed to report unhealthy\n      --health-start-interval duration   Time between running the check during the start period (ms|s|m|h) (default 0s)\n      --health-start-period duration     Start period for the container to initialize before starting health-retries countdown (ms|s|m|h) (default 0s)\n      --health-timeout duration          Maximum time to allow one check to run (ms|s|m|h) (default 0s)\n      --help                             Print usage\n  -h, --hostname string                  Container host name\n      --init                             Run an init inside the container that forwards signals and reaps processes\n  -i, --interactive                      Keep STDIN open even if not attached\n      --ip string                        IPv4 address (e.g., 172.30.100.104)\n      --ip6 string                       IPv6 address (e.g., 2001:db8::33)\n      --ipc string                       IPC mode to use\n      --isolation string                 Container isolation technology\n      --kernel-memory bytes              Kernel memory limit\n  -l, --label list                       Set meta data on a container\n      --label-file list                  Read in a line delimited file of labels\n      --link list                        Add link to another container\n      --link-local-ip list               Container IPv4\u002FIPv6 link-local addresses\n      --log-driver string                Logging driver for the container\n      --log-opt list                     Log driver options\n      --mac-address string               Container MAC address (e.g., 92:d0:c6:0a:29:33)\n  -m, --memory bytes                     Memory limit\n      --memory-reservation bytes         Memory soft limit\n      --memory-swap bytes                Swap limit equal to memory plus swap: '-1' to enable unlimited swap\n      --memory-swappiness int            Tune container memory swappiness (0 to 100) (default -1)\n      --mount mount                      Attach a filesystem mount to the container\n      --name string                      Assign a name to the container\n      --network network                  Connect a container to a network\n      --network-alias list               Add network-scoped alias for the container\n      --no-healthcheck                   Disable any container-specified HEALTHCHECK\n      --oom-kill-disable                 Disable OOM Killer\n      --oom-score-adj int                Tune host's OOM preferences (-1000 to 1000)\n      --pid string                       PID namespace to use\n      --pids-limit int                   Tune container pids limit (set -1 for unlimited)\n      --platform string                  Set platform if server is multi-platform capable\n      --privileged                       Give extended privileges to this container\n  -p, --publish list                     Publish a container's port(s) to the host\n  -P, --publish-all                      Publish all exposed ports to random ports\n      --pull string                      Pull image before running (\"always\", \"missing\", \"never\") (default \"missing\")\n  -q, --quiet                            Suppress the pull output\n      --read-only                        Mount the container's root filesystem as read only\n      --restart string                   Restart policy to apply when a container exits (default \"no\")\n      --rm                               Automatically remove the container when it exits\n      --runtime string                   Runtime to use for this container\n      --security-opt list                Security Options\n      --shm-size bytes                   Size of \u002Fdev\u002Fshm\n      --sig-proxy                        Proxy received signals to the process (default true)\n      --stop-signal string               Signal to stop the container\n      --stop-timeout int                 Timeout (in seconds) to stop a container\n      --storage-opt list                 Storage driver options for the container\n      --sysctl map                       Sysctl options (default map[])\n      --tmpfs list                       Mount a tmpfs directory\n  -t, --tty                              Allocate a pseudo-TTY\n      --ulimit ulimit                    Ulimit options (default [])\n  -u, --user string                      Username or UID (format: \u003Cname|uid>[:\u003Cgroup|gid>])\n      --userns string                    User namespace to use\n      --uts string                       UTS namespace to use\n  -v, --volume list                      Bind mount a volume\n      --volume-driver string             Optional volume driver for the container\n      --volumes-from list                Mount volumes from the specified container(s)\n  -w, --workdir string                   Working directory inside the container\n",[567,4227,4228,4238,4269,4273,4295,4299,4304,4318,4322,4327,4352,4400,4427,4456,4485,4501,4515,4539,4567,4597,4609,4617,4622,4627,4632,4637,4642,4647,4652,4657,4662,4667,4672,4677,4682,4687,4692,4697,4702,4707,4712,4717,4722,4727,4732,4737,4742,4747,4752,4767,4772,4777,4782,4787,4792,4797,4802,4808,4814,4820,4826,4832,4838,4844,4850,4856,4862,4868,4874,4880,4886,4892,4898,4904,4910,4926,4932,4938,4944,4950,4956,4962,4968,4996,5014,5046,5075,5096,5119,5125,5131,5137,5162,5203,5227,5248,5262,5280,5309,5329,5349,5372,5392,5411,5428,5445,5498,5515,5532,5554,5575,5604],{"__ignoreMap":743},[747,4229,4230,4232,4234,4236],{"class":749,"line":750},[747,4231,1919],{"class":1630},[747,4233,3246],{"class":802},[747,4235,3665],{"class":802},[747,4237,4218],{"class":802},[747,4239,4240,4243,4246,4248,4251,4254,4257,4260,4263,4266],{"class":749,"line":761},[747,4241,4242],{"class":1630},"Usage:",[747,4244,4245],{"class":802},"  docker",[747,4247,3665],{"class":802},[747,4249,4250],{"class":1640}," [OPTIONS] IMAGE ",[747,4252,4253],{"class":757},"[",[747,4255,4256],{"class":1640},"COMMAND",[747,4258,4259],{"class":757},"]",[747,4261,4262],{"class":757}," [",[747,4264,4265],{"class":1640},"ARG...",[747,4267,4268],{"class":757},"]\n",[747,4270,4271],{"class":749,"line":769},[747,4272,1255],{"emptyLinePlaceholder":1254},[747,4274,4275,4278,4280,4282,4284,4286,4288,4290,4292],{"class":749,"line":776},[747,4276,4277],{"class":1630},"Create",[747,4279,4099],{"class":802},[747,4281,3665],{"class":802},[747,4283,3930],{"class":802},[747,4285,3933],{"class":802},[747,4287,3936],{"class":802},[747,4289,3723],{"class":802},[747,4291,4053],{"class":802},[747,4293,4294],{"class":802}," image\n",[747,4296,4297],{"class":749,"line":784},[747,4298,1255],{"emptyLinePlaceholder":1254},[747,4300,4301],{"class":749,"line":790},[747,4302,4303],{"class":1630},"Aliases:\n",[747,4305,4306,4308,4310,4313,4315],{"class":749,"line":796},[747,4307,4245],{"class":1630},[747,4309,3936],{"class":802},[747,4311,4312],{"class":802}," run,",[747,4314,3246],{"class":802},[747,4316,4317],{"class":802}," run\n",[747,4319,4320],{"class":749,"line":806},[747,4321,1255],{"emptyLinePlaceholder":1254},[747,4323,4324],{"class":749,"line":814},[747,4325,4326],{"class":1630},"Options:\n",[747,4328,4329,4332,4335,4338,4340,4343,4346,4349],{"class":749,"line":822},[747,4330,4331],{"class":1630},"      --add-host",[747,4333,4334],{"class":802}," list",[747,4336,4337],{"class":802},"                    Add",[747,4339,3930],{"class":802},[747,4341,4342],{"class":802}," custom",[747,4344,4345],{"class":802}," host-to-IP",[747,4347,4348],{"class":802}," mapping",[747,4350,4351],{"class":1640}," (host:ip)\n",[747,4353,4354,4357,4360,4363,4365,4368,4370,4372,4374,4377,4380,4382,4384,4387,4390,4393,4395,4398],{"class":749,"line":830},[747,4355,4356],{"class":1630},"      --annotation",[747,4358,4359],{"class":802}," map",[747,4361,4362],{"class":802},"                   Add",[747,4364,4053],{"class":802},[747,4366,4367],{"class":802}," annotation",[747,4369,3696],{"class":802},[747,4371,3839],{"class":802},[747,4373,3936],{"class":802},[747,4375,4376],{"class":1640}," (passed ",[747,4378,4379],{"class":802},"through",[747,4381,3696],{"class":802},[747,4383,3839],{"class":802},[747,4385,4386],{"class":802}," OCI",[747,4388,4389],{"class":802}," runtime",[747,4391,4392],{"class":1640},") (",[747,4394,2014],{"class":1630},[747,4396,4397],{"class":802}," map[]",[747,4399,3600],{"class":1640},[747,4401,4402,4405,4408,4410,4413,4415,4418,4421,4424],{"class":749,"line":836},[747,4403,4404],{"class":1630},"  -a,",[747,4406,4407],{"class":802}," --attach",[747,4409,4334],{"class":802},[747,4411,4412],{"class":802},"                      Attach",[747,4414,3696],{"class":802},[747,4416,4417],{"class":802}," STDIN,",[747,4419,4420],{"class":802}," STDOUT",[747,4422,4423],{"class":802}," or",[747,4425,4426],{"class":802}," STDERR\n",[747,4428,4429,4432,4435,4438,4441,4444,4447,4450,4452,4454],{"class":749,"line":842},[747,4430,4431],{"class":1630},"      --blkio-weight",[747,4433,4434],{"class":802}," uint16",[747,4436,4437],{"class":802},"              Block",[747,4439,4440],{"class":802}," IO",[747,4442,4443],{"class":1640}," (relative ",[747,4445,4446],{"class":802},"weight",[747,4448,4449],{"class":1640},"), between 10 and 1000, or 0 to disable (",[747,4451,2014],{"class":1630},[747,4453,3588],{"class":1895},[747,4455,3600],{"class":1640},[747,4457,4458,4461,4463,4466,4468,4471,4473,4476,4478,4480,4482],{"class":749,"line":850},[747,4459,4460],{"class":1630},"      --blkio-weight-device",[747,4462,4334],{"class":802},[747,4464,4465],{"class":802},"         Block",[747,4467,4440],{"class":802},[747,4469,4470],{"class":802}," weight",[747,4472,4443],{"class":1640},[747,4474,4475],{"class":802},"device",[747,4477,4470],{"class":802},[747,4479,4392],{"class":1640},[747,4481,2014],{"class":1630},[747,4483,4484],{"class":1640}," [])\n",[747,4486,4487,4490,4492,4495,4498],{"class":749,"line":863},[747,4488,4489],{"class":1630},"      --cap-add",[747,4491,4334],{"class":802},[747,4493,4494],{"class":802},"                     Add",[747,4496,4497],{"class":802}," Linux",[747,4499,4500],{"class":802}," capabilities\n",[747,4502,4503,4506,4508,4511,4513],{"class":749,"line":869},[747,4504,4505],{"class":1630},"      --cap-drop",[747,4507,4334],{"class":802},[747,4509,4510],{"class":802},"                    Drop",[747,4512,4497],{"class":802},[747,4514,4500],{"class":802},[747,4516,4517,4520,4523,4526,4529,4532,4534,4536],{"class":749,"line":877},[747,4518,4519],{"class":1630},"      --cgroup-parent",[747,4521,4522],{"class":802}," string",[747,4524,4525],{"class":802},"             Optional",[747,4527,4528],{"class":802}," parent",[747,4530,4531],{"class":802}," cgroup",[747,4533,3761],{"class":802},[747,4535,3839],{"class":802},[747,4537,4538],{"class":802}," container\n",[747,4540,4541,4544,4546,4549,4552,4554,4557,4560,4562,4565],{"class":749,"line":1015},[747,4542,4543],{"class":1630},"      --cgroupns",[747,4545,4522],{"class":802},[747,4547,4548],{"class":802},"                  Cgroup",[747,4550,4551],{"class":802}," namespace",[747,4553,3696],{"class":802},[747,4555,4556],{"class":802}," use",[747,4558,4559],{"class":1640}," (host",[747,4561,3616],{"class":757},[747,4563,4564],{"class":1630},"private",[747,4566,3600],{"class":1640},[747,4568,4569,4572,4575,4578,4580,4582,4585,4587,4589,4592,4594],{"class":749,"line":1021},[747,4570,4571],{"class":1630},"                                         'host'",[747,4573,856],{"class":4574},"s2Zo4",[747,4576,4577],{"class":802},"    Run",[747,4579,3839],{"class":802},[747,4581,3936],{"class":802},[747,4583,4584],{"class":802}," in",[747,4586,3839],{"class":802},[747,4588,3833],{"class":802},[747,4590,4591],{"class":802}," host",[747,4593,3543],{"class":757},[747,4595,4596],{"class":802},"s cgroup namespace\n",[747,4598,4599,4602,4604,4606],{"class":749,"line":1027},[747,4600,4601],{"class":757},"                                         '",[747,4603,4564],{"class":802},[747,4605,3543],{"class":757},[747,4607,4608],{"class":802},": Run the container in its own private cgroup namespace\n",[747,4610,4611,4614],{"class":749,"line":1033},[747,4612,4613],{"class":757},"                                         ''",[747,4615,4616],{"class":802},":        Use the cgroup namespace as configured by the\n",[747,4618,4619],{"class":749,"line":1039},[747,4620,4621],{"class":802},"                                                    default-cgroupns-mode option on the daemon (default)\n",[747,4623,4624],{"class":749,"line":1054},[747,4625,4626],{"class":802},"      --cidfile string                   Write the container ID to the file\n",[747,4628,4629],{"class":749,"line":1060},[747,4630,4631],{"class":802},"      --cpu-period int                   Limit CPU CFS (Completely Fair Scheduler) period\n",[747,4633,4634],{"class":749,"line":1066},[747,4635,4636],{"class":802},"      --cpu-quota int                    Limit CPU CFS (Completely Fair Scheduler) quota\n",[747,4638,4639],{"class":749,"line":1081},[747,4640,4641],{"class":802},"      --cpu-rt-period int                Limit CPU real-time period in microseconds\n",[747,4643,4644],{"class":749,"line":1087},[747,4645,4646],{"class":802},"      --cpu-rt-runtime int               Limit CPU real-time runtime in microseconds\n",[747,4648,4649],{"class":749,"line":1102},[747,4650,4651],{"class":802},"  -c, --cpu-shares int                   CPU shares (relative weight)\n",[747,4653,4654],{"class":749,"line":1110},[747,4655,4656],{"class":802},"      --cpus decimal                     Number of CPUs\n",[747,4658,4659],{"class":749,"line":1117},[747,4660,4661],{"class":802},"      --cpuset-cpus string               CPUs in which to allow execution (0-3, 0,1)\n",[747,4663,4664],{"class":749,"line":1123},[747,4665,4666],{"class":802},"      --cpuset-mems string               MEMs in which to allow execution (0-3, 0,1)\n",[747,4668,4669],{"class":749,"line":1129},[747,4670,4671],{"class":802},"  -d, --detach                           Run container in background and print container ID\n",[747,4673,4674],{"class":749,"line":1142},[747,4675,4676],{"class":802},"      --detach-keys string               Override the key sequence for detaching a container\n",[747,4678,4679],{"class":749,"line":1150},[747,4680,4681],{"class":802},"      --device list                      Add a host device to the container\n",[747,4683,4684],{"class":749,"line":1157},[747,4685,4686],{"class":802},"      --device-cgroup-rule list          Add a rule to the cgroup allowed devices list\n",[747,4688,4689],{"class":749,"line":1163},[747,4690,4691],{"class":802},"      --device-read-bps list             Limit read rate (bytes per second) from a device (default [])\n",[747,4693,4694],{"class":749,"line":1168},[747,4695,4696],{"class":802},"      --device-read-iops list            Limit read rate (IO per second) from a device (default [])\n",[747,4698,4699],{"class":749,"line":1174},[747,4700,4701],{"class":802},"      --device-write-bps list            Limit write rate (bytes per second) to a device (default [])\n",[747,4703,4704],{"class":749,"line":1480},[747,4705,4706],{"class":802},"      --device-write-iops list           Limit write rate (IO per second) to a device (default [])\n",[747,4708,4709],{"class":749,"line":1491},[747,4710,4711],{"class":802},"      --disable-content-trust            Skip image verification (default true)\n",[747,4713,4714],{"class":749,"line":1496},[747,4715,4716],{"class":802},"      --dns list                         Set custom DNS servers\n",[747,4718,4719],{"class":749,"line":1502},[747,4720,4721],{"class":802},"      --dns-option list                  Set DNS options\n",[747,4723,4724],{"class":749,"line":1510},[747,4725,4726],{"class":802},"      --dns-search list                  Set custom DNS search domains\n",[747,4728,4729],{"class":749,"line":1520},[747,4730,4731],{"class":802},"      --domainname string                Container NIS domain name\n",[747,4733,4734],{"class":749,"line":1525},[747,4735,4736],{"class":802},"      --entrypoint string                Overwrite the default ENTRYPOINT of the image\n",[747,4738,4739],{"class":749,"line":1533},[747,4740,4741],{"class":802},"  -e, --env list                         Set environment variables\n",[747,4743,4744],{"class":749,"line":1539},[747,4745,4746],{"class":802},"      --env-file list                    Read in a file of environment variables\n",[747,4748,4749],{"class":749,"line":1549},[747,4750,4751],{"class":802},"      --expose list                      Expose a port or a range of ports\n",[747,4753,4754,4757,4759,4762,4764],{"class":749,"line":1554},[747,4755,4756],{"class":802},"      --gpus gpu-request                 GPU devices to add to the container (",[747,4758,3543],{"class":757},[747,4760,4761],{"class":802},"all",[747,4763,3543],{"class":757},[747,4765,4766],{"class":802}," to pass all GPUs)\n",[747,4768,4769],{"class":749,"line":1562},[747,4770,4771],{"class":802},"      --group-add list                   Add additional groups to join\n",[747,4773,4774],{"class":749,"line":1568},[747,4775,4776],{"class":802},"      --health-cmd string                Command to run to check health\n",[747,4778,4779],{"class":749,"line":1577},[747,4780,4781],{"class":802},"      --health-interval duration         Time between running the check (ms|s|m|h) (default 0s)\n",[747,4783,4784],{"class":749,"line":1582},[747,4785,4786],{"class":802},"      --health-retries int               Consecutive failures needed to report unhealthy\n",[747,4788,4789],{"class":749,"line":1588},[747,4790,4791],{"class":802},"      --health-start-interval duration   Time between running the check during the start period (ms|s|m|h) (default 0s)\n",[747,4793,4794],{"class":749,"line":1594},[747,4795,4796],{"class":802},"      --health-start-period duration     Start period for the container to initialize before starting health-retries countdown (ms|s|m|h) (default 0s)\n",[747,4798,4799],{"class":749,"line":1600},[747,4800,4801],{"class":802},"      --health-timeout duration          Maximum time to allow one check to run (ms|s|m|h) (default 0s)\n",[747,4803,4805],{"class":749,"line":4804},57,[747,4806,4807],{"class":802},"      --help                             Print usage\n",[747,4809,4811],{"class":749,"line":4810},58,[747,4812,4813],{"class":802},"  -h, --hostname string                  Container host name\n",[747,4815,4817],{"class":749,"line":4816},59,[747,4818,4819],{"class":802},"      --init                             Run an init inside the container that forwards signals and reaps processes\n",[747,4821,4823],{"class":749,"line":4822},60,[747,4824,4825],{"class":802},"  -i, --interactive                      Keep STDIN open even if not attached\n",[747,4827,4829],{"class":749,"line":4828},61,[747,4830,4831],{"class":802},"      --ip string                        IPv4 address (e.g., 172.30.100.104)\n",[747,4833,4835],{"class":749,"line":4834},62,[747,4836,4837],{"class":802},"      --ip6 string                       IPv6 address (e.g., 2001:db8::33)\n",[747,4839,4841],{"class":749,"line":4840},63,[747,4842,4843],{"class":802},"      --ipc string                       IPC mode to use\n",[747,4845,4847],{"class":749,"line":4846},64,[747,4848,4849],{"class":802},"      --isolation string                 Container isolation technology\n",[747,4851,4853],{"class":749,"line":4852},65,[747,4854,4855],{"class":802},"      --kernel-memory bytes              Kernel memory limit\n",[747,4857,4859],{"class":749,"line":4858},66,[747,4860,4861],{"class":802},"  -l, --label list                       Set meta data on a container\n",[747,4863,4865],{"class":749,"line":4864},67,[747,4866,4867],{"class":802},"      --label-file list                  Read in a line delimited file of labels\n",[747,4869,4871],{"class":749,"line":4870},68,[747,4872,4873],{"class":802},"      --link list                        Add link to another container\n",[747,4875,4877],{"class":749,"line":4876},69,[747,4878,4879],{"class":802},"      --link-local-ip list               Container IPv4\u002FIPv6 link-local addresses\n",[747,4881,4883],{"class":749,"line":4882},70,[747,4884,4885],{"class":802},"      --log-driver string                Logging driver for the container\n",[747,4887,4889],{"class":749,"line":4888},71,[747,4890,4891],{"class":802},"      --log-opt list                     Log driver options\n",[747,4893,4895],{"class":749,"line":4894},72,[747,4896,4897],{"class":802},"      --mac-address string               Container MAC address (e.g., 92:d0:c6:0a:29:33)\n",[747,4899,4901],{"class":749,"line":4900},73,[747,4902,4903],{"class":802},"  -m, --memory bytes                     Memory limit\n",[747,4905,4907],{"class":749,"line":4906},74,[747,4908,4909],{"class":802},"      --memory-reservation bytes         Memory soft limit\n",[747,4911,4913,4916,4918,4921,4923],{"class":749,"line":4912},75,[747,4914,4915],{"class":802},"      --memory-swap bytes                Swap limit equal to memory plus swap: ",[747,4917,3543],{"class":757},[747,4919,4920],{"class":802},"-1",[747,4922,3543],{"class":757},[747,4924,4925],{"class":802}," to enable unlimited swap\n",[747,4927,4929],{"class":749,"line":4928},76,[747,4930,4931],{"class":802},"      --memory-swappiness int            Tune container memory swappiness (0 to 100) (default -1)\n",[747,4933,4935],{"class":749,"line":4934},77,[747,4936,4937],{"class":802},"      --mount mount                      Attach a filesystem mount to the container\n",[747,4939,4941],{"class":749,"line":4940},78,[747,4942,4943],{"class":802},"      --name string                      Assign a name to the container\n",[747,4945,4947],{"class":749,"line":4946},79,[747,4948,4949],{"class":802},"      --network network                  Connect a container to a network\n",[747,4951,4953],{"class":749,"line":4952},80,[747,4954,4955],{"class":802},"      --network-alias list               Add network-scoped alias for the container\n",[747,4957,4959],{"class":749,"line":4958},81,[747,4960,4961],{"class":802},"      --no-healthcheck                   Disable any container-specified HEALTHCHECK\n",[747,4963,4965],{"class":749,"line":4964},82,[747,4966,4967],{"class":802},"      --oom-kill-disable                 Disable OOM Killer\n",[747,4969,4971,4974,4976,4979,4982,4985,4988,4991,4994],{"class":749,"line":4970},83,[747,4972,4973],{"class":802},"      --oom-score-adj int                Tune host",[747,4975,3543],{"class":757},[747,4977,4978],{"class":802},"s",[747,4980,4981],{"class":802}," OOM",[747,4983,4984],{"class":802}," preferences",[747,4986,4987],{"class":1640}," (-1000 ",[747,4989,4990],{"class":802},"to",[747,4992,4993],{"class":1895}," 1000",[747,4995,3600],{"class":1640},[747,4997,4999,5002,5004,5007,5009,5011],{"class":749,"line":4998},84,[747,5000,5001],{"class":1630},"      --pid",[747,5003,4522],{"class":802},[747,5005,5006],{"class":802},"                       PID",[747,5008,4551],{"class":802},[747,5010,3696],{"class":802},[747,5012,5013],{"class":802}," use\n",[747,5015,5017,5020,5023,5026,5028,5031,5034,5037,5039,5041,5044],{"class":749,"line":5016},85,[747,5018,5019],{"class":1630},"      --pids-limit",[747,5021,5022],{"class":802}," int",[747,5024,5025],{"class":802},"                   Tune",[747,5027,3936],{"class":802},[747,5029,5030],{"class":802}," pids",[747,5032,5033],{"class":802}," limit",[747,5035,5036],{"class":1640}," (set ",[747,5038,4920],{"class":802},[747,5040,3761],{"class":802},[747,5042,5043],{"class":802}," unlimited",[747,5045,3600],{"class":1640},[747,5047,5049,5052,5054,5057,5060,5063,5066,5069,5072],{"class":749,"line":5048},86,[747,5050,5051],{"class":1630},"      --platform",[747,5053,4522],{"class":802},[747,5055,5056],{"class":802},"                  Set",[747,5058,5059],{"class":802}," platform",[747,5061,5062],{"class":802}," if",[747,5064,5065],{"class":802}," server",[747,5067,5068],{"class":802}," is",[747,5070,5071],{"class":802}," multi-platform",[747,5073,5074],{"class":802}," capable\n",[747,5076,5078,5081,5084,5087,5090,5092,5094],{"class":749,"line":5077},87,[747,5079,5080],{"class":1630},"      --privileged",[747,5082,5083],{"class":802},"                       Give",[747,5085,5086],{"class":802}," extended",[747,5088,5089],{"class":802}," privileges",[747,5091,3696],{"class":802},[747,5093,3827],{"class":802},[747,5095,4538],{"class":802},[747,5097,5099,5102,5105,5107,5110,5112,5114,5116],{"class":749,"line":5098},88,[747,5100,5101],{"class":1630},"  -p,",[747,5103,5104],{"class":802}," --publish",[747,5106,4334],{"class":802},[747,5108,5109],{"class":802},"                     Publish",[747,5111,3930],{"class":802},[747,5113,3936],{"class":802},[747,5115,3543],{"class":757},[747,5117,5118],{"class":802},"s port(s) to the host\n",[747,5120,5122],{"class":749,"line":5121},89,[747,5123,5124],{"class":802},"  -P, --publish-all                      Publish all exposed ports to random ports\n",[747,5126,5128],{"class":749,"line":5127},90,[747,5129,5130],{"class":802},"      --pull string                      Pull image before running (\"always\", \"missing\", \"never\") (default \"missing\")\n",[747,5132,5134],{"class":749,"line":5133},91,[747,5135,5136],{"class":802},"  -q, --quiet                            Suppress the pull output\n",[747,5138,5140,5143,5145,5147,5150,5153,5156,5159],{"class":749,"line":5139},92,[747,5141,5142],{"class":802},"      --read-only                        Mount the container",[747,5144,3543],{"class":757},[747,5146,4978],{"class":802},[747,5148,5149],{"class":802}," root",[747,5151,5152],{"class":802}," filesystem",[747,5154,5155],{"class":802}," as",[747,5157,5158],{"class":802}," read",[747,5160,5161],{"class":802}," only\n",[747,5163,5165,5168,5170,5173,5176,5178,5181,5184,5186,5188,5191,5194,5196,5199,5201],{"class":749,"line":5164},93,[747,5166,5167],{"class":1630},"      --restart",[747,5169,4522],{"class":802},[747,5171,5172],{"class":802},"                   Restart",[747,5174,5175],{"class":802}," policy",[747,5177,3696],{"class":802},[747,5179,5180],{"class":802}," apply",[747,5182,5183],{"class":802}," when",[747,5185,3930],{"class":802},[747,5187,3936],{"class":802},[747,5189,5190],{"class":802}," exits",[747,5192,5193],{"class":1640}," (default ",[747,5195,3892],{"class":757},[747,5197,5198],{"class":802},"no",[747,5200,3892],{"class":757},[747,5202,3600],{"class":1640},[747,5204,5206,5209,5212,5215,5217,5219,5221,5224],{"class":749,"line":5205},94,[747,5207,5208],{"class":1630},"      --rm",[747,5210,5211],{"class":802},"                               Automatically",[747,5213,5214],{"class":802}," remove",[747,5216,3839],{"class":802},[747,5218,3936],{"class":802},[747,5220,5183],{"class":802},[747,5222,5223],{"class":802}," it",[747,5225,5226],{"class":802}," exits\n",[747,5228,5230,5233,5235,5238,5240,5242,5244,5246],{"class":749,"line":5229},95,[747,5231,5232],{"class":1630},"      --runtime",[747,5234,4522],{"class":802},[747,5236,5237],{"class":802},"                   Runtime",[747,5239,3696],{"class":802},[747,5241,4556],{"class":802},[747,5243,3761],{"class":802},[747,5245,3827],{"class":802},[747,5247,4538],{"class":802},[747,5249,5251,5254,5256,5259],{"class":749,"line":5250},96,[747,5252,5253],{"class":1630},"      --security-opt",[747,5255,4334],{"class":802},[747,5257,5258],{"class":802},"                Security",[747,5260,5261],{"class":802}," Options\n",[747,5263,5265,5268,5271,5274,5277],{"class":749,"line":5264},97,[747,5266,5267],{"class":1630},"      --shm-size",[747,5269,5270],{"class":802}," bytes",[747,5272,5273],{"class":802},"                   Size",[747,5275,5276],{"class":802}," of",[747,5278,5279],{"class":802}," \u002Fdev\u002Fshm\n",[747,5281,5283,5286,5289,5292,5295,5297,5299,5302,5304,5307],{"class":749,"line":5282},98,[747,5284,5285],{"class":1630},"      --sig-proxy",[747,5287,5288],{"class":802},"                        Proxy",[747,5290,5291],{"class":802}," received",[747,5293,5294],{"class":802}," signals",[747,5296,3696],{"class":802},[747,5298,3839],{"class":802},[747,5300,5301],{"class":802}," process",[747,5303,5193],{"class":1640},[747,5305,5306],{"class":757},"true",[747,5308,3600],{"class":1640},[747,5310,5312,5315,5317,5320,5322,5325,5327],{"class":749,"line":5311},99,[747,5313,5314],{"class":1630},"      --stop-signal",[747,5316,4522],{"class":802},[747,5318,5319],{"class":802},"               Signal",[747,5321,3696],{"class":802},[747,5323,5324],{"class":802}," stop",[747,5326,3839],{"class":802},[747,5328,4538],{"class":802},[747,5330,5332,5335,5337,5340,5343,5346],{"class":749,"line":5331},100,[747,5333,5334],{"class":1630},"      --stop-timeout",[747,5336,5022],{"class":802},[747,5338,5339],{"class":802},"                 Timeout",[747,5341,5342],{"class":1640}," (in ",[747,5344,5345],{"class":802},"seconds",[747,5347,5348],{"class":1640},") to stop a container\n",[747,5350,5352,5355,5357,5360,5363,5366,5368,5370],{"class":749,"line":5351},101,[747,5353,5354],{"class":1630},"      --storage-opt",[747,5356,4334],{"class":802},[747,5358,5359],{"class":802},"                 Storage",[747,5361,5362],{"class":802}," driver",[747,5364,5365],{"class":802}," options",[747,5367,3761],{"class":802},[747,5369,3839],{"class":802},[747,5371,4538],{"class":802},[747,5373,5375,5378,5380,5383,5385,5387,5390],{"class":749,"line":5374},102,[747,5376,5377],{"class":1630},"      --sysctl",[747,5379,4359],{"class":802},[747,5381,5382],{"class":802},"                       Sysctl",[747,5384,5365],{"class":802},[747,5386,5193],{"class":1640},[747,5388,5389],{"class":802},"map[]",[747,5391,3600],{"class":1640},[747,5393,5395,5398,5400,5403,5405,5408],{"class":749,"line":5394},103,[747,5396,5397],{"class":1630},"      --tmpfs",[747,5399,4334],{"class":802},[747,5401,5402],{"class":802},"                       Mount",[747,5404,3930],{"class":802},[747,5406,5407],{"class":802}," tmpfs",[747,5409,5410],{"class":802}," directory\n",[747,5412,5414,5417,5420,5423,5425],{"class":749,"line":5413},104,[747,5415,5416],{"class":1630},"  -t,",[747,5418,5419],{"class":802}," --tty",[747,5421,5422],{"class":802},"                              Allocate",[747,5424,3930],{"class":802},[747,5426,5427],{"class":802}," pseudo-TTY\n",[747,5429,5431,5434,5437,5440,5442],{"class":749,"line":5430},105,[747,5432,5433],{"class":1630},"      --ulimit",[747,5435,5436],{"class":802}," ulimit",[747,5438,5439],{"class":802},"                    Ulimit",[747,5441,5365],{"class":802},[747,5443,5444],{"class":1640}," (default [])\n",[747,5446,5448,5451,5454,5456,5459,5461,5464,5467,5470,5473,5475,5478,5480,5482,5484,5487,5489,5492,5494,5496],{"class":749,"line":5447},106,[747,5449,5450],{"class":1630},"  -u,",[747,5452,5453],{"class":802}," --user",[747,5455,4522],{"class":802},[747,5457,5458],{"class":802},"                      Username",[747,5460,4423],{"class":802},[747,5462,5463],{"class":802}," UID",[747,5465,5466],{"class":1640}," (format: ",[747,5468,5469],{"class":757},"\u003C",[747,5471,5472],{"class":802},"name",[747,5474,3616],{"class":757},[747,5476,5477],{"class":1630},"uid",[747,5479,2035],{"class":1640},[747,5481,4253],{"class":802},[747,5483,856],{"class":4574},[747,5485,5486],{"class":1640},"\u003Cgroup",[747,5488,3616],{"class":757},[747,5490,5491],{"class":1630},"gid",[747,5493,2035],{"class":1640},[747,5495,4259],{"class":802},[747,5497,3600],{"class":1640},[747,5499,5501,5504,5506,5509,5511,5513],{"class":749,"line":5500},107,[747,5502,5503],{"class":1630},"      --userns",[747,5505,4522],{"class":802},[747,5507,5508],{"class":802},"                    User",[747,5510,4551],{"class":802},[747,5512,3696],{"class":802},[747,5514,5013],{"class":802},[747,5516,5518,5521,5523,5526,5528,5530],{"class":749,"line":5517},108,[747,5519,5520],{"class":1630},"      --uts",[747,5522,4522],{"class":802},[747,5524,5525],{"class":802},"                       UTS",[747,5527,4551],{"class":802},[747,5529,3696],{"class":802},[747,5531,5013],{"class":802},[747,5533,5535,5538,5541,5543,5546,5549,5551],{"class":749,"line":5534},109,[747,5536,5537],{"class":1630},"  -v,",[747,5539,5540],{"class":802}," --volume",[747,5542,4334],{"class":802},[747,5544,5545],{"class":802},"                      Bind",[747,5547,5548],{"class":802}," mount",[747,5550,3930],{"class":802},[747,5552,5553],{"class":802}," volume\n",[747,5555,5557,5560,5562,5564,5567,5569,5571,5573],{"class":749,"line":5556},110,[747,5558,5559],{"class":1630},"      --volume-driver",[747,5561,4522],{"class":802},[747,5563,4525],{"class":802},[747,5565,5566],{"class":802}," volume",[747,5568,5362],{"class":802},[747,5570,3761],{"class":802},[747,5572,3839],{"class":802},[747,5574,4538],{"class":802},[747,5576,5578,5581,5583,5586,5589,5591,5593,5596,5598,5600,5602],{"class":749,"line":5577},111,[747,5579,5580],{"class":1630},"      --volumes-from",[747,5582,4334],{"class":802},[747,5584,5585],{"class":802},"                Mount",[747,5587,5588],{"class":802}," volumes",[747,5590,3723],{"class":802},[747,5592,3839],{"class":802},[747,5594,5595],{"class":802}," specified",[747,5597,3936],{"class":802},[747,5599,2000],{"class":757},[747,5601,4978],{"class":1630},[747,5603,3600],{"class":757},[747,5605,5607,5610,5613,5615,5618,5621,5624,5626],{"class":749,"line":5606},112,[747,5608,5609],{"class":1630},"  -w,",[747,5611,5612],{"class":802}," --workdir",[747,5614,4522],{"class":802},[747,5616,5617],{"class":802},"                   Working",[747,5619,5620],{"class":802}," directory",[747,5622,5623],{"class":802}," inside",[747,5625,3839],{"class":802},[747,5627,4538],{"class":802},[523,5629,5630,5631,5633],{},"As we can see ",[567,5632,4203],{}," has a lot of options, to choose from.\nIn this workshop we are only covering some of basic options, you should know to begin with.",[738,5635,5637],{"className":1621,"code":5636,"language":1623,"meta":743,"style":743},"$ docker run --help\n\nUsage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]\n\n[...]\n",[567,5638,5639,5649,5653,5675,5679],{"__ignoreMap":743},[747,5640,5641,5643,5645,5647],{"class":749,"line":750},[747,5642,1919],{"class":1630},[747,5644,3246],{"class":802},[747,5646,3665],{"class":802},[747,5648,4218],{"class":802},[747,5650,5651],{"class":749,"line":761},[747,5652,1255],{"emptyLinePlaceholder":1254},[747,5654,5655,5657,5659,5661,5663,5665,5667,5669,5671,5673],{"class":749,"line":769},[747,5656,4242],{"class":1630},[747,5658,4245],{"class":802},[747,5660,3665],{"class":802},[747,5662,4250],{"class":1640},[747,5664,4253],{"class":757},[747,5666,4256],{"class":1640},[747,5668,4259],{"class":757},[747,5670,4262],{"class":757},[747,5672,4265],{"class":1640},[747,5674,4268],{"class":757},[747,5676,5677],{"class":749,"line":776},[747,5678,1255],{"emptyLinePlaceholder":1254},[747,5680,5681,5683,5686],{"class":749,"line":784},[747,5682,4253],{"class":757},[747,5684,5685],{"class":1640},"...",[747,5687,4268],{"class":757},[523,5689,5690,856],{},[584,5691,2957],{},[668,5693,5694,5700,5706],{},[638,5695,5696,5699],{},[567,5697,5698],{},"[OPTIONS]"," - Run flags\u002Foptions.",[638,5701,5702,5705],{},[567,5703,5704],{},"IMAGE"," - The name of a Docker image.",[638,5707,5708,5711,5712,1909],{},[567,5709,5710],{},"[COMMAND] [ARG ...]"," - Depending on the images, can be used to provide an alternative command and arguments to pass to the ",[527,5713,5716],{"href":5714,"rel":5715},"https:\u002F\u002Fdocs.docker.com\u002Freference\u002Fdockerfile\u002F#entrypoint",[531],"image's entrypoint",[523,5718,5719,5720,3052],{},"I'm going in depth about image names, command args and entrypoint later on (",[527,5721,3396],{"href":5722},"#understanding-dockerfiles",[613,5724,5726],{"id":5725},"starting-the-mysql-database-server","Starting the MySQL database server",[523,5728,5729,5730,5735,5736,5738],{},"I'm going to use the MySQL Docker image from ",[527,5731,5734],{"href":5732,"rel":5733},"https:\u002F\u002Fgithub.com\u002Fsameersbn",[531],"sameersbn"," in the workshop. Because this image is more convenient to setup, than the official available MySQL and MariaDB Docker image.\nSo we specify the ",[567,5737,5704],{}," argument in our command now.",[738,5740,5742],{"className":1621,"code":5741,"language":1623,"meta":743,"style":743},"docker run \\\n    docker.io\u002Flibrary\u002Fmysql:latest\n",[567,5743,5744,5752],{"__ignoreMap":743},[747,5745,5746,5748,5750],{"class":749,"line":750},[747,5747,3257],{"class":1630},[747,5749,3665],{"class":802},[747,5751,1641],{"class":1640},[747,5753,5754],{"class":749,"line":761},[747,5755,5756],{"class":802},"    docker.io\u002Flibrary\u002Fmysql:latest\n",[3126,5758,5760],{"id":5759},"lets-give-it-a-name-btw-can-we-keep-it","Let's give it a name (BTW Can we keep it?)",[523,5762,5763],{},[3049,5764,5765],{},"How about Dogmeat? :D",[523,5767,5768,5769,5772],{},"Our MySQL database server container should have a name, so we don't need to use the randomized name or unique ID.\nEvery container gets an unique ID and randomized name. We can override the name with the ",[567,5770,5771],{},"--name NAME"," option.\nLet's name it \"database\".\nOur command now looks like this:",[738,5774,5776],{"className":1621,"code":5775,"language":1623,"meta":743,"style":743},"docker run \\\n    --name mysql \\\n    docker.io\u002Flibrary\u002Fmysql:latest\n",[567,5777,5778,5786,5796],{"__ignoreMap":743},[747,5779,5780,5782,5784],{"class":749,"line":750},[747,5781,3257],{"class":1630},[747,5783,3665],{"class":802},[747,5785,1641],{"class":1640},[747,5787,5788,5791,5794],{"class":749,"line":761},[747,5789,5790],{"class":802},"    --name",[747,5792,5793],{"class":802}," mysql",[747,5795,1641],{"class":1640},[747,5797,5798],{"class":749,"line":769},[747,5799,5756],{"class":802},[523,5801,5802],{},"Giving a container a \"simple\" name, is important to simplify later processes, like connecting from the WordPress instance to the MySQL database server.",[3126,5804,5806],{"id":5805},"does-the-container-keep-on-running-or-do-i-need-something-like-screen-or-what","Does the container keep on running or do I need something like screen or what?!",[523,5808,5809,5810,587,5813,5816,5817,5820,5821,587,5824,5827,5828,5830,5831,587,5833,5835,5836,5838,5839,5842,5843,5845,5846,5848],{},"The  ",[567,5811,5812],{},"--detach",[567,5814,5815],{},"--interactive"," options.\nIf you now run the command to start the container, upon start you see some log output coming, but should notice that when closing the terminal, the database container immediately gets stopped\u002Fexits (To see if the container exited, use ",[567,5818,5819],{},"docker ps -a",").\nWhen you run a container, by default your current ",[567,5822,5823],{},"stdin",[567,5825,5826],{},"stdout"," will be attached to the container, making it interactive (If you want an interactive container, you should still add ",[567,5829,5815],{}," option). To disable the attachment of ",[567,5832,5823],{},[567,5834,5826],{}," add the ",[567,5837,5812],{}," (or short ",[567,5840,5841],{},"-d",") option to the command. Using the ",[567,5844,5812],{}," (or ",[567,5847,5841],{},") option, runs the container detached.",[738,5850,5852],{"className":1621,"code":5851,"language":1623,"meta":743,"style":743},"docker run \\\n    -d \\\n    --name mysql \\\n    docker.io\u002Flibrary\u002Fmysql:latest\n",[567,5853,5854,5862,5869,5877],{"__ignoreMap":743},[747,5855,5856,5858,5860],{"class":749,"line":750},[747,5857,3257],{"class":1630},[747,5859,3665],{"class":802},[747,5861,1641],{"class":1640},[747,5863,5864,5867],{"class":749,"line":761},[747,5865,5866],{"class":802},"    -d",[747,5868,1641],{"class":1640},[747,5870,5871,5873,5875],{"class":749,"line":769},[747,5872,5790],{"class":802},[747,5874,5793],{"class":802},[747,5876,1641],{"class":1640},[747,5878,5879],{"class":749,"line":776},[747,5880,5756],{"class":802},[523,5882,5883],{},"Running a container detached is most common for containers with server or headless application, like Nginx, MySQL, etc.",[523,5885,5886,5887,5890],{},"Don't forget to delete the exited\u002Fstopped MySQL database container with the remove command, ",[567,5888,5889],{},"docker rm database"," (where database is the name or ID of the container) else if starting you'll get an error saying that a container already exists with the same name.\nIn case you already forgot, here's how to delete the container",[738,5892,5894],{"className":1621,"code":5893,"language":1623,"meta":743,"style":743},"docker rm NAME\n",[567,5895,5896],{"__ignoreMap":743},[747,5897,5898,5900,5903],{"class":749,"line":750},[747,5899,3257],{"class":1630},[747,5901,5902],{"class":802}," rm",[747,5904,5905],{"class":802}," NAME\n",[3126,5907,5909],{"id":5908},"how-would-one-configure-the-mysql-database-server-instance","How would one configure the MySQL database server instance?",[523,5911,5912,5913,5915,5916,5918],{},"One big questions will be for you, \"How can I configure the MySQL database server?\" in the container.\nYou can..\n",[584,5914,3022],{}," use config files\nor\n",[584,5917,3026],{}," use environment variables (portable and the simplest way for most scenarios).",[523,5920,5921],{},"The most portable way is to use environment variables.\nMost containers that are configured through environment variables, have a script, the entrypoint, that sets config variables and a lot more, before the main application\u002Fprogram is started.",[523,5923,5924,5925,5928],{},"In the case of ",[567,5926,5927],{},"docker.io\u002Flibrary\u002Fmysql:latest"," the following environment variables are used for basic configuration:",[668,5930,5931,5941,5948],{},[638,5932,5933,5936,5937,5940],{},[567,5934,5935],{},"MYSQL_DATABASE"," - Database to create and gain access to the username given in ",[567,5938,5939],{},"MYSQL_USER"," below.",[638,5942,5943,5945,5946,1909],{},[567,5944,5939],{}," - Database User to create. User will be given access to the database(s) from ",[567,5947,5935],{},[638,5949,5950,5953],{},[567,5951,5952],{},"MYSQL_PASSWORD"," - Password for the given database user.",[523,5955,5956,5957,5845,5960,5963],{},"To specify an environment variable, the ",[567,5958,5959],{},"--env",[567,5961,5962],{},"-e",") option is used.",[597,5965,5966],{},[523,5967,5968],{},"The order of the environment variables\u002Fflags doesn't matter.",[738,5970,5972],{"className":1621,"code":5971,"language":1623,"meta":743,"style":743},"docker run \\\n[...]\n    -e 'MYSQL_DATABASE=wordpress' \\\n    -e 'MYSQL_USER=wordpress' \\\n    -e 'MYSQL_PASSWORD=wordpress' \\\n[...]\n",[567,5973,5974,5982,5987,6001,6014,6027],{"__ignoreMap":743},[747,5975,5976,5978,5980],{"class":749,"line":750},[747,5977,3257],{"class":1630},[747,5979,3665],{"class":802},[747,5981,1641],{"class":1640},[747,5983,5984],{"class":749,"line":761},[747,5985,5986],{"class":1640},"[...]\n",[747,5988,5989,5992,5994,5997,5999],{"class":749,"line":769},[747,5990,5991],{"class":1630},"    -e",[747,5993,3537],{"class":757},[747,5995,5996],{"class":802},"MYSQL_DATABASE=wordpress",[747,5998,3543],{"class":757},[747,6000,1641],{"class":1640},[747,6002,6003,6005,6007,6010,6012],{"class":749,"line":776},[747,6004,5991],{"class":802},[747,6006,3537],{"class":757},[747,6008,6009],{"class":802},"MYSQL_USER=wordpress",[747,6011,3543],{"class":757},[747,6013,1641],{"class":1640},[747,6015,6016,6018,6020,6023,6025],{"class":749,"line":784},[747,6017,5991],{"class":802},[747,6019,3537],{"class":757},[747,6021,6022],{"class":802},"MYSQL_PASSWORD=wordpress",[747,6024,3543],{"class":757},[747,6026,1641],{"class":1640},[747,6028,6029],{"class":749,"line":790},[747,6030,5986],{"class":1640},[523,6032,6033],{},[3049,6034,6035],{},"*sarcasm on* 100% secure passwords used here *sarcasm off*",[597,6037,6038],{},[523,6039,6040,6041,6044],{},"Use secure passwords when running in production!\n",[567,6042,6043],{},"openssl rand -base64 20",", can be used to generate a \"secure\" password.",[523,6046,6047,6048,6050,6051,1909],{},"If we run the database with the environment variables added, does it run? Check with ",[567,6049,5819],{},".\nIt exited? Let's check the logs! ",[567,6052,6053],{},"docker logs mysql",[523,6055,6056,6057,6062,6063,6066,6067,6070],{},"Does it complain about there being no root password specified for the setup?\nLooking at the ",[527,6058,6061],{"href":6059,"rel":6060},"https:\u002F\u002Fhub.docker.com\u002F_\u002Fmysql",[531],"Docker hub page of the official mysql image",", scroll to the \"Environment Variables\" section (pro tip use ",[567,6064,6065],{},"CTRL+F"," to search the page in your browser),\nOne of the first variables in that list is ",[567,6068,6069],{},"MYSQL_ROOT_PASSWORD",", to quote the documentation:",[6072,6073,6074],"blockquote",{},[523,6075,6076,6077],{},"This variable is mandatory and specifies the password that will be set for the MySQL root superuser account. ",[747,6078,5685],{},[523,6080,6081,6082,6084,6085,6087],{},"We need to add that environment to our ",[567,6083,4203],{}," command as well.\nHow would you go about adding it to your ",[567,6086,4203],{}," command?",[597,6089,6090,6097],{},[523,6091,6092,6093,6096],{},"For this basic Docker workshop it is out of scope to talk about secret management, as it will heavily depend on the used secrets management solution.\nFor the mysql image, you can add ",[567,6094,6095],{},"_FILE"," to the end of some environment variable and have the container image entrypoint read the file to populate the environment variable(s).",[523,6098,6099,6100,1909],{},"For the mysql's image documentation regarding that please checkout the \"Docker Secrets\" section on ",[527,6101,6103],{"href":6059,"rel":6102},[531],"the Docker Hub page",[3126,6105,6107],{"id":6106},"how-do-i-save-the-database-outside-the-container","How do I save the database outside the container?",[523,6109,6110,6111,5845,6114,6117],{},"You want to save your data outside of the container, for a simple reason: If you stop and delete the container, your data is gone. For this Docker has volumes.\nA Volume is like a mount from the host system inside the container.\nThe volume option is ",[567,6112,6113],{},"--volume",[567,6115,6116],{},"-v","). The syntax of a volume option is for example:",[738,6119,6121],{"className":1621,"code":6120,"language":1623,"meta":743,"style":743},"docker run \\\n[...]\n    -v HOST_PATH:CONTAINER_PATH:MODE\n[...]\n",[567,6122,6123,6131,6135,6143],{"__ignoreMap":743},[747,6124,6125,6127,6129],{"class":749,"line":750},[747,6126,3257],{"class":1630},[747,6128,3665],{"class":802},[747,6130,1641],{"class":1640},[747,6132,6133],{"class":749,"line":761},[747,6134,5986],{"class":1640},[747,6136,6137,6140],{"class":749,"line":769},[747,6138,6139],{"class":1630},"    -v",[747,6141,6142],{"class":802}," HOST_PATH:CONTAINER_PATH:MODE\n",[747,6144,6145,6147,6149],{"class":749,"line":776},[747,6146,4253],{"class":757},[747,6148,5685],{"class":1640},[747,6150,4268],{"class":757},[523,6152,6153,856],{},[584,6154,2957],{},[668,6156,6157,6163,6169],{},[638,6158,6159,6162],{},[567,6160,6161],{},"HOST_PATH"," - Path to mount from the host system inside the container.",[638,6164,6165,6168],{},[567,6166,6167],{},"CONTAINER_PATH"," - \"Mount\" destination path in the container.",[638,6170,6171,6174,6175,6178,6179,6182,6183,1909],{},[567,6172,6173],{},":MODE"," - Is optional. Can be ",[567,6176,6177],{},"rw"," (read-write) or ",[567,6180,6181],{},"ro"," (read-only). Defaults to ",[567,6184,6177],{},[523,6186,6187],{},[584,6188,6189],{},"NOTE",[668,6191,6192,6195,6198],{},[638,6193,6194],{},"If the host path doesn't exist it'll get created.",[638,6196,6197],{},"The host path can be a file too.",[638,6199,6200],{},"Docker doesn't distinguish between file or folder. If the path doesn't exist, a directory always get's created.",[3126,6202,6204],{"id":6203},"running-the-mysql-database-server-container","Running the MySQL database server container",[523,6206,6207],{},"Now we have all components, we need for running the MySQL container.",[523,6209,6210],{},"When we have put everything we learned now together, we should get something that looks like this:",[738,6212,6214],{"className":1621,"code":6213,"language":1623,"meta":743,"style":743},"docker run \\\n    -d \\\n    --name mysql \\\n    -e 'MYSQL_DATABASE=wordpress' \\\n    -e 'MYSQL_USER=wordpress' \\\n    -e 'MYSQL_PASSWORD=wordpress' \\\n    -e 'MYSQL_ROOT_PASSWORD=my-scret-pw' \\\n    -v \u002Fopt\u002Fdocker\u002Fwordpress\u002Fmysql:\u002Fvar\u002Flib\u002Fmysql \\\n    docker.io\u002Flibrary\u002Fmysql:latest\n",[567,6215,6216,6224,6230,6238,6250,6262,6274,6287,6296],{"__ignoreMap":743},[747,6217,6218,6220,6222],{"class":749,"line":750},[747,6219,3257],{"class":1630},[747,6221,3665],{"class":802},[747,6223,1641],{"class":1640},[747,6225,6226,6228],{"class":749,"line":761},[747,6227,5866],{"class":802},[747,6229,1641],{"class":1640},[747,6231,6232,6234,6236],{"class":749,"line":769},[747,6233,5790],{"class":802},[747,6235,5793],{"class":802},[747,6237,1641],{"class":1640},[747,6239,6240,6242,6244,6246,6248],{"class":749,"line":776},[747,6241,5991],{"class":802},[747,6243,3537],{"class":757},[747,6245,5996],{"class":802},[747,6247,3543],{"class":757},[747,6249,1641],{"class":1640},[747,6251,6252,6254,6256,6258,6260],{"class":749,"line":784},[747,6253,5991],{"class":802},[747,6255,3537],{"class":757},[747,6257,6009],{"class":802},[747,6259,3543],{"class":757},[747,6261,1641],{"class":1640},[747,6263,6264,6266,6268,6270,6272],{"class":749,"line":790},[747,6265,5991],{"class":802},[747,6267,3537],{"class":757},[747,6269,6022],{"class":802},[747,6271,3543],{"class":757},[747,6273,1641],{"class":1640},[747,6275,6276,6278,6280,6283,6285],{"class":749,"line":796},[747,6277,5991],{"class":802},[747,6279,3537],{"class":757},[747,6281,6282],{"class":802},"MYSQL_ROOT_PASSWORD=my-scret-pw",[747,6284,3543],{"class":757},[747,6286,1641],{"class":1640},[747,6288,6289,6291,6294],{"class":749,"line":806},[747,6290,6139],{"class":802},[747,6292,6293],{"class":802}," \u002Fopt\u002Fdocker\u002Fwordpress\u002Fmysql:\u002Fvar\u002Flib\u002Fmysql",[747,6295,1641],{"class":1640},[747,6297,6298],{"class":749,"line":814},[747,6299,5756],{"class":802},[523,6301,6302,856],{},[584,6303,2957],{},[668,6305,6306,6311,6317,6323,6337],{},[638,6307,6308,6310],{},[567,6309,5841],{}," - To run the container detached.",[638,6312,6313,6316],{},[567,6314,6315],{},"--name wordpress"," - Gives the container the name \"wordpress\".",[638,6318,6319,6322],{},[567,6320,6321],{},"-e ...=..."," - Specifies environment variables, that are used for configuration.",[638,6324,6325,6328,6329,6332,6333,6336],{},[567,6326,6327],{},"-v \u002Fopt\u002Fdocker\u002Fwordpress\u002Fmysql:\u002Fvar\u002Flib\u002Fmysql"," - Mount ",[567,6330,6331],{},"\u002Fopt\u002Fdocker\u002Fwordpress\u002Fmysql"," directory at ",[567,6334,6335],{},"\u002Fvar\u002Flib\u002Fmysql"," into the container.",[638,6338,6339,6341],{},[567,6340,5927],{}," - Specifies what image to use.",[523,6343,6344,6345,5845,6347,6349,6350,6353,6354,6356],{},"If you run the run command with the ",[567,6346,5812],{},[567,6348,5841],{},"), it'll just return the unique (long) ID of the container.\nWith ",[567,6351,6352],{},"docker logs CONTAINER"," (where ",[567,6355,4188],{}," is a container ID or name), you'll get the logs of the first process in the container.",[613,6358,6360],{"id":6359},"starting-the-wordpress-instance","Starting the WordPress instance",[523,6362,6363],{},"So you now already know some \"basics\", about starting containers. I'm not going in depth with every little thing anymore.",[3126,6365,6367],{"id":6366},"how-can-the-wordpress-container-and-the-mysql-container-communicate-with-each-other","How can the WordPress container and the MySQL container communicate with each other?",[523,6369,6370,6371,6374,6375,6378,6379,6382,6383,6353,6386,6389],{},"In Docker by default all containers can talk to each other, if they know the IP address, that is called short ",[567,6372,6373],{},"ICC"," or ",[567,6376,6377],{},"Inter Container Communication"," (",[567,6380,6381],{},"docker daemon [...] --icc=[true\u002Ffalse]",").\nTo allow the WordPress container to contact the MySQL container, we would need to get the IP address of the MySQL container. You can use the ",[567,6384,6385],{},"docker inspect CONTAINER_OR_IMAGE",[567,6387,6388],{},"CONTAINER_OR_IMAGE"," is the unique ID or name of a container), the command returns JSON formatted output with \"all\" informations about the given container(s) or image(s).",[523,6391,6392,6393,6396],{},"But to do this everytime the MySQL container get's restarted, is too much work. That's where Docker implements a mechanism called links.\nAs you might guess, with links, you can \"link\"\u002Fconnect containers together. Keep in mind that with the above mentioned Docker daemon option ",[567,6394,6395],{},"--icc=true"," all containers can talk to each other, when knowing the IP address of another container.",[523,6398,6399],{},"The link option syntax is like this:",[738,6401,6403],{"className":1621,"code":6402,"language":1623,"meta":743,"style":743},"docker run \\\n[OPTIONS]\n    --link=CONTAINER_NAME:LINK_NAME \\\n[IMAGE]\n",[567,6404,6405,6413,6418,6431],{"__ignoreMap":743},[747,6406,6407,6409,6411],{"class":749,"line":750},[747,6408,3257],{"class":1630},[747,6410,3665],{"class":802},[747,6412,1641],{"class":1640},[747,6414,6415],{"class":749,"line":761},[747,6416,6417],{"class":1640},"[OPTIONS]\n",[747,6419,6420,6423,6426,6429],{"class":749,"line":769},[747,6421,6422],{"class":1640},"    --link",[747,6424,6425],{"class":757},"=",[747,6427,6428],{"class":802},"CONTAINER_NAME:LINK_NAME",[747,6430,1641],{"class":1630},[747,6432,6433],{"class":749,"line":776},[747,6434,6435],{"class":1640},"[IMAGE]\n",[523,6437,6438,856],{},[584,6439,2957],{},[668,6441,6442,6448],{},[638,6443,6444,6447],{},[567,6445,6446],{},"CONTAINER_NAME"," - The container to link.",[638,6449,6450,6453],{},[567,6451,6452],{},"LINK_NAME"," - The name of the \"\u002Fetc\u002Fhosts\" entry (aka \"fake\" DNS record).",[523,6455,6456,6457,6460,6461,1909],{},"If you link the MySQL container to the WordPress container, the WordPress container will get a special entry in it's ",[567,6458,6459],{},"\u002Fetc\u002Fhosts"," about the MySQL container and \"inherit\" all of the MySQL containers environment variables prefixed with the link name.\nFor example the link option is ",[567,6462,6463],{},"--link=mysql:database",[523,6465,6466,6467,6469,6470,6472],{},"So if we take a look at the ",[567,6468,6459],{}," and environment variables inside the WordPress container, with the container link to the MySQL container, it should get much clearer how the \"linking works\".\nTo show you the created ",[567,6471,6459],{}," entry and the environment variables created inside the container.\nI'm running the following command, to just demonstrate it:",[738,6474,6476],{"className":1621,"code":6475,"language":1623,"meta":743,"style":743},"docker run \\\n    -d \\\n    --name=wordpress \\\n    --entrypoint=\u002Fbin\u002Fbash \\\n    wordpress\ncat \u002Fetc\u002Fhosts\nenv\nexit # To exit the container\ndocker rm wordpress\n",[567,6477,6478,6486,6492,6499,6506,6511,6519,6524,6532],{"__ignoreMap":743},[747,6479,6480,6482,6484],{"class":749,"line":750},[747,6481,3257],{"class":1630},[747,6483,3665],{"class":802},[747,6485,1641],{"class":1640},[747,6487,6488,6490],{"class":749,"line":761},[747,6489,5866],{"class":802},[747,6491,1641],{"class":1640},[747,6493,6494,6497],{"class":749,"line":769},[747,6495,6496],{"class":802},"    --name=wordpress",[747,6498,1641],{"class":1640},[747,6500,6501,6504],{"class":749,"line":776},[747,6502,6503],{"class":802},"    --entrypoint=\u002Fbin\u002Fbash",[747,6505,1641],{"class":1640},[747,6507,6508],{"class":749,"line":784},[747,6509,6510],{"class":802},"    wordpress\n",[747,6512,6513,6516],{"class":749,"line":790},[747,6514,6515],{"class":1630},"cat",[747,6517,6518],{"class":802}," \u002Fetc\u002Fhosts\n",[747,6520,6521],{"class":749,"line":796},[747,6522,6523],{"class":1630},"env\n",[747,6525,6526,6529],{"class":749,"line":806},[747,6527,6528],{"class":4574},"exit",[747,6530,6531],{"class":772}," # To exit the container\n",[747,6533,6534,6536,6538],{"class":749,"line":814},[747,6535,3257],{"class":1630},[747,6537,5902],{"class":802},[747,6539,6540],{"class":802}," wordpress\n",[523,6542,6543,856],{},[584,6544,2957],{},[668,6546,6547],{},[638,6548,6549,6552],{},[567,6550,6551],{},"--entrypoint=\u002Fbin\u002Fbash"," - This overwrites the command executed, when the container is started.",[523,6554,6555],{},[584,6556,3521],{},[523,6558,6559],{},"(The output here may looks a bit different, due to small changes to the commands executed in the demo)",[523,6561,6562,6563,6566],{},"The environment variables are created inside the new container only, not in the link source! The container that is used as the link destination is left untouched.\nbeginning with ",[567,6564,6565],{},"DATABASE_",", allow to get the environment variables and published ports from the linked container very simple.",[523,6568,6569],{},[584,6570,6189],{},[668,6572,6573,6576],{},[638,6574,6575],{},"There can be multiple links with the same name.",[638,6577,6578],{},"You can't attach two same named links to the destination container (the container you are creating).",[3126,6580,6582],{"id":6581},"how-can-i-reach-the-wordpress-instance-from-the-outside","How can I reach the WordPress instance from the outside?",[523,6584,6585,6586,5845,6589,6592],{},"To make a port available to the \"public\", that's why it's called publishing ports, you use the ",[567,6587,6588],{},"--publish",[567,6590,6591],{},"-p",") option in this format:",[738,6594,6596],{"className":1621,"code":6595,"language":1623,"meta":743,"style":743},"docker run \\\n[OPTIONS]\n    -p HOST_ADDRESS:HOST_PORT:CONTAINER_PORT\u002FPROTOCOL\n[IMAGE] [ARGUMENTS]\n",[567,6597,6598,6606,6610,6618],{"__ignoreMap":743},[747,6599,6600,6602,6604],{"class":749,"line":750},[747,6601,3257],{"class":1630},[747,6603,3665],{"class":802},[747,6605,1641],{"class":1640},[747,6607,6608],{"class":749,"line":761},[747,6609,6417],{"class":1640},[747,6611,6612,6615],{"class":749,"line":769},[747,6613,6614],{"class":1630},"    -p",[747,6616,6617],{"class":802}," HOST_ADDRESS:HOST_PORT:CONTAINER_PORT\u002FPROTOCOL\n",[747,6619,6620,6622,6624,6626,6628,6631],{"class":749,"line":776},[747,6621,4253],{"class":757},[747,6623,5704],{"class":1640},[747,6625,4259],{"class":757},[747,6627,4262],{"class":757},[747,6629,6630],{"class":1640},"ARGUMENTS",[747,6632,4268],{"class":757},[738,6634,6636],{"className":1621,"code":6635,"language":1623,"meta":743,"style":743},"docker run \\\n[OPTIONS] \\\n    -p 80:80\u002Ftcp \\\n[IMAGE] [ARGUMENTS]\n",[567,6637,6638,6646,6651,6660],{"__ignoreMap":743},[747,6639,6640,6642,6644],{"class":749,"line":750},[747,6641,3257],{"class":1630},[747,6643,3665],{"class":802},[747,6645,1641],{"class":1640},[747,6647,6648],{"class":749,"line":761},[747,6649,6650],{"class":1640},"[OPTIONS] \\\n",[747,6652,6653,6655,6658],{"class":749,"line":769},[747,6654,6614],{"class":1630},[747,6656,6657],{"class":802}," 80:80\u002Ftcp",[747,6659,1641],{"class":1640},[747,6661,6662,6665,6667,6669],{"class":749,"line":776},[747,6663,6664],{"class":1640},"[IMAGE] ",[747,6666,4253],{"class":757},[747,6668,6630],{"class":1640},[747,6670,4268],{"class":757},[523,6672,6673,856],{},[584,6674,2957],{},[668,6676,6677,6687,6693,6699],{},[638,6678,6679,6682,6683,6686],{},[567,6680,6681],{},"HOST_ADDRESS:"," - Optional. By default ",[567,6684,6685],{},"0.0.0.0",". Address to expose the port on the host system.",[638,6688,6689,6692],{},[567,6690,6691],{},"HOST_PORT"," - Host port to expose the container port on.",[638,6694,6695,6698],{},[567,6696,6697],{},"CONTAINER_PORT"," - Container port to expose.",[638,6700,6701,6682,6704,6707,6708,6374,6710,1909],{},[567,6702,6703],{},"\u002FPROTOCOL",[567,6705,6706],{},"tcp",". The port protocol, currently can be ",[567,6709,6706],{},[567,6711,6712],{},"udp",[523,6714,6715],{},"And that's how you forward\u002Fpublish ports from the container to the outside.",[3126,6717,6719],{"id":6718},"running-the-wordpress-instance-container","Running the WordPress instance container",[523,6721,6722,6723,6378,6726,2006],{},"To configure our WordPress container instance, the Docker image comes with extra environment variables.\nThe WordPress image name is ",[567,6724,6725],{},"wordpress",[527,6727,6730],{"href":6728,"rel":6729},"https:\u002F\u002Fhub.docker.com\u002F_\u002Fwordpress\u002F",[531],"Docker Hub Page",[523,6732,6733],{},"The possible environment variables for the configuration are the following ones:",[668,6735,6736,6745,6751,6762,6768,6777],{},[638,6737,6738,6741,6742,1909],{},[567,6739,6740],{},"-e WORDPRESS_DB_HOST=..."," Defaults to the DNS name or IP address and port of the linked MySQL container, link name ",[567,6743,6744],{},"mysql",[638,6746,6747,6750],{},[567,6748,6749],{},"-e WORDPRESS_DB_USER=..."," Defaults to \"root\".",[638,6752,6753,6756,6757,6759,6760,1909],{},[567,6754,6755],{},"-e WORDPRESS_DB_PASSWORD=..."," Defaults to the value of the ",[567,6758,6069],{}," environment variable from the linked MySQL container, link name ",[567,6761,6744],{},[638,6763,6764,6767],{},[567,6765,6766],{},"-e WORDPRESS_DB_NAME=..."," - Defaults to \"wordpress\".",[638,6769,6770,6773,6774,1909],{},[567,6771,6772],{},"-e WORDPRESS_TABLE_PREFIX=..."," - Defaults to \"\". Only set this when you need to override the default table prefix in ",[567,6775,6776],{},"wp-config.php",[638,6778,6779,714,6782,714,6785,714,6788,714,6791,714,6794,714,6797,6800],{},[567,6780,6781],{},"-e WORDPRESS_AUTH_KEY=...",[567,6783,6784],{},"-e WORDPRESS_SECURE_AUTH_KEY=...",[567,6786,6787],{},"-e WORDPRESS_LOGGED_IN_KEY=...",[567,6789,6790],{},"-e WORDPRESS_NONCE_KEY=...",[567,6792,6793],{},"-e WORDPRESS_AUTH_SALT=...",[567,6795,6796],{},"-e WORDPRESS_SECURE_AUTH_SALT=...",[567,6798,6799],{},"-e WORDPRESS_LOGGED_IN_SALT"," - Set these to a secure random value; in production use different random values per variable.",[523,6802,6803,6804,6807,6808,6810,6811,710,6813,6816],{},"In the case of the ",[567,6805,6806],{},"WORDPRESS_DB_HOST",", the value would be the name of the link name in the ",[567,6809,4203],{}," command below. In the case of the below command, the ",[567,6812,6806],{},[567,6814,6815],{},"database",".\nThe command to run the WordPress container is like this:",[738,6818,6820],{"className":1621,"code":6819,"language":1623,"meta":743,"style":743},"docker run \\\n    -d \\\n    --name wordpress \\\n    -e 'WORDPRESS_DB_HOST=database' \\\n    -e 'WORDPRESS_DB_USER=wordpress' \\\n    -e 'WORDPRESS_DB_PASSWORD=wordpress' \\\n    -e 'WORDPRESS_AUTH_KEY=wordpress' \\\n    -e 'WORDPRESS_SECURE_AUTH_KEY=wordpress' \\\n    -e 'WORDPRESS_LOGGED_IN_KEY=wordpress' \\\n    -e 'WORDPRESS_NONCE_KEY=wordpress' \\\n    -e 'WORDPRESS_AUTH_SALT=wordpress' \\\n    -e 'WORDPRESS_SECURE_AUTH_SALT=wordpress' \\\n    -e 'WORDPRESS_LOGGED_IN_SALT=wordpress' \\\n    --link mysql:database \\\n    -p 80:80 \\\n    wordpress\n",[567,6821,6822,6830,6836,6845,6858,6871,6884,6897,6910,6923,6936,6949,6962,6975,6984,6993],{"__ignoreMap":743},[747,6823,6824,6826,6828],{"class":749,"line":750},[747,6825,3257],{"class":1630},[747,6827,3665],{"class":802},[747,6829,1641],{"class":1640},[747,6831,6832,6834],{"class":749,"line":761},[747,6833,5866],{"class":802},[747,6835,1641],{"class":1640},[747,6837,6838,6840,6843],{"class":749,"line":769},[747,6839,5790],{"class":802},[747,6841,6842],{"class":802}," wordpress",[747,6844,1641],{"class":1640},[747,6846,6847,6849,6851,6854,6856],{"class":749,"line":776},[747,6848,5991],{"class":802},[747,6850,3537],{"class":757},[747,6852,6853],{"class":802},"WORDPRESS_DB_HOST=database",[747,6855,3543],{"class":757},[747,6857,1641],{"class":1640},[747,6859,6860,6862,6864,6867,6869],{"class":749,"line":784},[747,6861,5991],{"class":802},[747,6863,3537],{"class":757},[747,6865,6866],{"class":802},"WORDPRESS_DB_USER=wordpress",[747,6868,3543],{"class":757},[747,6870,1641],{"class":1640},[747,6872,6873,6875,6877,6880,6882],{"class":749,"line":790},[747,6874,5991],{"class":802},[747,6876,3537],{"class":757},[747,6878,6879],{"class":802},"WORDPRESS_DB_PASSWORD=wordpress",[747,6881,3543],{"class":757},[747,6883,1641],{"class":1640},[747,6885,6886,6888,6890,6893,6895],{"class":749,"line":796},[747,6887,5991],{"class":802},[747,6889,3537],{"class":757},[747,6891,6892],{"class":802},"WORDPRESS_AUTH_KEY=wordpress",[747,6894,3543],{"class":757},[747,6896,1641],{"class":1640},[747,6898,6899,6901,6903,6906,6908],{"class":749,"line":806},[747,6900,5991],{"class":802},[747,6902,3537],{"class":757},[747,6904,6905],{"class":802},"WORDPRESS_SECURE_AUTH_KEY=wordpress",[747,6907,3543],{"class":757},[747,6909,1641],{"class":1640},[747,6911,6912,6914,6916,6919,6921],{"class":749,"line":814},[747,6913,5991],{"class":802},[747,6915,3537],{"class":757},[747,6917,6918],{"class":802},"WORDPRESS_LOGGED_IN_KEY=wordpress",[747,6920,3543],{"class":757},[747,6922,1641],{"class":1640},[747,6924,6925,6927,6929,6932,6934],{"class":749,"line":822},[747,6926,5991],{"class":802},[747,6928,3537],{"class":757},[747,6930,6931],{"class":802},"WORDPRESS_NONCE_KEY=wordpress",[747,6933,3543],{"class":757},[747,6935,1641],{"class":1640},[747,6937,6938,6940,6942,6945,6947],{"class":749,"line":830},[747,6939,5991],{"class":802},[747,6941,3537],{"class":757},[747,6943,6944],{"class":802},"WORDPRESS_AUTH_SALT=wordpress",[747,6946,3543],{"class":757},[747,6948,1641],{"class":1640},[747,6950,6951,6953,6955,6958,6960],{"class":749,"line":836},[747,6952,5991],{"class":802},[747,6954,3537],{"class":757},[747,6956,6957],{"class":802},"WORDPRESS_SECURE_AUTH_SALT=wordpress",[747,6959,3543],{"class":757},[747,6961,1641],{"class":1640},[747,6963,6964,6966,6968,6971,6973],{"class":749,"line":842},[747,6965,5991],{"class":802},[747,6967,3537],{"class":757},[747,6969,6970],{"class":802},"WORDPRESS_LOGGED_IN_SALT=wordpress",[747,6972,3543],{"class":757},[747,6974,1641],{"class":1640},[747,6976,6977,6979,6982],{"class":749,"line":850},[747,6978,6422],{"class":802},[747,6980,6981],{"class":802}," mysql:database",[747,6983,1641],{"class":1640},[747,6985,6986,6988,6991],{"class":749,"line":863},[747,6987,6614],{"class":802},[747,6989,6990],{"class":802}," 80:80",[747,6992,1641],{"class":1640},[747,6994,6995],{"class":749,"line":869},[747,6996,6510],{"class":802},[523,6998,6999,856],{},[584,7000,2957],{},[668,7002,7003,7007,7011,7015,7027],{},[638,7004,7005,6310],{},[567,7006,5841],{},[638,7008,7009,6316],{},[567,7010,6315],{},[638,7012,7013,6322],{},[567,7014,6321],{},[638,7016,7017,7020,7021,7023,7024,7026],{},[567,7018,7019],{},"--link mysql:database"," - Creates a \"link\" named ",[567,7022,6744],{},", from the ",[567,7025,6815],{}," container.",[638,7028,7029,6341],{},[567,7030,6725],{},[523,7032,7033,7034,1909],{},"Now execute the command and you should be able to see the WordPress installation screen at ",[527,7035,7036],{"href":7036,"rel":7037},"http:\u002F\u002F127.0.0.1:80\u002F",[531],[523,7039,7040],{},[584,7041,6189],{},[523,7043,7044],{},"All data inside the container, will be lost on removal of the container! In our case, we already use volumes, so don't worry.",[523,7046,7047,7048,6353,7050,7052,7053,7055,7056,7058],{},"For cleanup you now stop and delete the container.\nTo stop the WordPress instance, run ",[567,7049,4180],{},[567,7051,4188],{}," in this case is ",[567,7054,6725],{},"). After stopping the container, you can remove it with ",[567,7057,4194],{},".\nThe container has to be stopped, before it can be removed.",[2979,7060],{},[523,7062,7063],{},[584,7064,7065],{},"Now that we looked into some of most important beginner topics of Docker, we are going to take a look deeper into these topics.",[2979,7067],{},[535,7069,7071],{"id":7070},"how-do-you-execute-a-commandshell-inside-the-container","How do you execute a command\u002Fshell inside the container?",[523,7073,7074],{},"To execute a command inside the container, after it has been started, for example in the MySQL container for maintenance access.",[523,7076,7077],{},"With our example, MySQL container let's display a list of the existing databases.\nThe command to display the databases from shell is:",[738,7079,7081],{"className":1621,"code":7080,"language":1623,"meta":743,"style":743},"mysql -u root -p -e \"SHOW DATABASES;\"\n",[567,7082,7083],{"__ignoreMap":743},[747,7084,7085,7087,7090,7092,7095,7098,7100,7103],{"class":749,"line":750},[747,7086,6744],{"class":1630},[747,7088,7089],{"class":802}," -u",[747,7091,5149],{"class":802},[747,7093,7094],{"class":802}," -p",[747,7096,7097],{"class":802}," -e",[747,7099,969],{"class":757},[747,7101,7102],{"class":802},"SHOW DATABASES;",[747,7104,975],{"class":757},[523,7106,7107,7108,7111,7112,7114,7115,7117,7118,7121],{},"For this case, the command ",[567,7109,7110],{},"docker exec"," is used.\nThe syntax of ",[567,7113,7110],{}," is a bit equal to the of ",[567,7116,4203],{},". Running ",[567,7119,7120],{},"docker exec --help"," as always to show you the help\u002Fsyntax menu.",[523,7123,7124],{},[584,7125,3521],{},[523,7127,7128],{},[3069,7129],{"alt":7130,"src":7131},"docker exec --help Output","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Fdocker-exec-help.png",[523,7133,7134],{},"To run a command interactively for example opening an interactive MySQL shell session, the command would be:",[738,7136,7138],{"className":1621,"code":7137,"language":1623,"meta":743,"style":743},"docker exec \\\n    -it \\\n    CONTAINER \\\n    mysql -u root -p\n",[567,7139,7140,7148,7155,7162],{"__ignoreMap":743},[747,7141,7142,7144,7146],{"class":749,"line":750},[747,7143,3257],{"class":1630},[747,7145,2586],{"class":802},[747,7147,1641],{"class":1640},[747,7149,7150,7153],{"class":749,"line":761},[747,7151,7152],{"class":802},"    -it",[747,7154,1641],{"class":1640},[747,7156,7157,7160],{"class":749,"line":769},[747,7158,7159],{"class":802},"    CONTAINER",[747,7161,1641],{"class":1640},[747,7163,7164,7167,7169,7171],{"class":749,"line":776},[747,7165,7166],{"class":802},"    mysql",[747,7168,7089],{"class":802},[747,7170,5149],{"class":802},[747,7172,7173],{"class":802}," -p\n",[523,7175,7176,856],{},[584,7177,2957],{},[668,7179,7180,7186,7192,7197],{},[638,7181,7182,7185],{},[567,7183,7184],{},"-i"," - Attach the stdin aka interactive.",[638,7187,7188,7191],{},[567,7189,7190],{},"-t"," - Optional. Allocates a pseudo-TTY (pseudo TeleTYpewriter) to the shell\u002Fcommand run.",[638,7193,7194,7196],{},[567,7195,4188],{}," - Container ID or name of the container the command should be executed in.",[638,7198,7199,7202],{},[567,7200,7201],{},"mysql -u root -p"," - The command and arguments to execute.",[523,7204,7205,7206,5845,7208,7210,7211,3052],{},"You would use the ",[567,7207,5812],{},[567,7209,5841],{},") option to run a non-interactive command in the background with no logs or return (Good for cron jobs ",[3049,7212,7213],{},";)",[523,7215,7216],{},[584,7217,6189],{},[668,7219,7220],{},[638,7221,7222],{},"To be able to run a command in the container, the command\u002Fbinary\u002Ffile\u002Fwhatever has to exist in the container!",[2979,7224],{},[535,7226,7228],{"id":7227},"data-data-everywhere","Data, Data everywhere",[523,7230,7231],{},[3049,7232,7233],{},"Insert \"Data Data everywhere!\" buzz lightning meme here",[613,7235,7237],{"id":7236},"volumes-aka-mounts-host-path","\"Volumes\" aka Mounts (\"Host Path\")",[523,7239,7240,7241,7244,7245,7248,7249,7251],{},"Volumes add persistence to your data. When a container is stopped and removed, the data in the container is lost.\nWith a volume you would mount the part of the data out of the container. For example with our MySQL container, we would mount the container path ",[567,7242,7243],{},"\u002Fvar\u002Flib\u002Fmysql\u002F"," (contains the MySQL databases) somewhere safe.\nSo if the MySQL server inside the container should ever crash and the container then be terminated, you can just fire up with the ",[567,7246,7247],{},"docker start"," command or delete the container and execute the ",[567,7250,4203],{}," command again. The MySQL container then starts using the data where it exited.",[523,7253,7254,7255,7258],{},"I already showed the option, but here is it again (Long form ",[567,7256,7257],{},"--volume=","):",[738,7260,7262],{"className":1621,"code":7261,"language":1623,"meta":743,"style":743},"docker run \\\n[OPTIONS]\n    -v HOST_PATH:CONTAINER_PATH:MODE\n[IMAGE] [ARGUMENTS]\n",[567,7263,7264,7272,7276,7282],{"__ignoreMap":743},[747,7265,7266,7268,7270],{"class":749,"line":750},[747,7267,3257],{"class":1630},[747,7269,3665],{"class":802},[747,7271,1641],{"class":1640},[747,7273,7274],{"class":749,"line":761},[747,7275,6417],{"class":1640},[747,7277,7278,7280],{"class":749,"line":769},[747,7279,6139],{"class":1630},[747,7281,6142],{"class":802},[747,7283,7284,7286,7288,7290,7292,7294],{"class":749,"line":776},[747,7285,4253],{"class":757},[747,7287,5704],{"class":1640},[747,7289,4259],{"class":757},[747,7291,4262],{"class":757},[747,7293,6630],{"class":1640},[747,7295,4268],{"class":757},[523,7297,7298,856],{},[584,7299,2957],{},[668,7301,7302,7306,7310],{},[638,7303,7304,6162],{},[567,7305,6161],{},[638,7307,7308,6168],{},[567,7309,6167],{},[638,7311,7312,6174,7314,6178,7316,6182,7318,1909],{},[567,7313,6173],{},[567,7315,6177],{},[567,7317,6181],{},[567,7319,6177],{},[523,7321,7322,7324],{},[584,7323,3103],{}," Data inside container to outside of container.",[523,7326,7327],{},[584,7328,6189],{},[668,7330,7331,7346],{},[638,7332,7333,7334],{},"When the host path doesn't exist, it'll get created. BUT the permissions will be a bit \"freaky\".\n",[668,7335,7336],{},[638,7337,7338,7339,7342,7343,1909],{},"When the path doesn't exist and get's created on the host, the directory will be (by default) owned by ",[567,7340,7341],{},"root:root",", mode perms ",[567,7344,7345],{},"drwxr-xr-x",[638,7347,7348,7349,1909],{},"You can now create volumes using the Docker command, but I'm not going deeper into this. You can read more about this ",[527,7350,3396],{"href":7351,"rel":7352},"https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Freference\u002Fcommandline\u002Fvolume_create\u002F",[531],[613,7354,7356,7357],{"id":7355},"data-containers-aka-volumes-from","Data containers  aka ",[567,7358,7359],{},"--volumes-from",[523,7361,7362],{},[584,7363,6189],{},[668,7365,7366,7373],{},[638,7367,7368,7369,7372],{},"I do ",[584,7370,7371],{},"NOT"," recommend this method as I often enough \"accidentally\" clear all exited\u002Fdead containers, so my disk space doesn't run out.",[638,7374,7375],{},"I also have cron jobs running on my servers, that clean exited containers. Meaning data containers would just get cleared out everytime.",[523,7377,7378,7379,7381,7382,7385,7386,7389],{},"You can store data inside another container, that's called data volume containers.\nWhen creating an image, you can specify those volumes. You create a container that has a volume \"built-into\" (Specified while the image was built), meaning that assuming it is our MySQL server image the in-built volume would be located at ",[567,7380,6335],{},"\nThe data volume container runs \"nothing\", it is just there for purpose of getting used by another container. For this you change the entrypoint with the following run option ",[567,7383,7384],{},"--entrypoint=COMMAND"," (where command could be just ",[567,7387,7388],{},"\u002Fbin\u002Ftrue",") so the container stops and doesn't run the program it should.",[523,7391,7392,7393,6353,7396,7398],{},"Now that we would have a data container, we can use the volumes from this container using the ",[567,7394,7395],{},"--volumes-from=CONTAINER",[567,7397,4188],{}," is a container name or ID) option.",[523,7400,7401,7402,7405,7406,7408,7409,7411],{},"Let's assume we have a data container, created from the example here, with the volume ",[567,7403,7404],{},"\u002Fdata"," and we have a second container, running the same image, that would save the data to ",[567,7407,7404],{},".\nIn this case using the ",[567,7410,7359],{}," option would write the data inside the first container, the data container.",[523,7413,7414],{},"As I wrote I personally don't recommend and I'm not even using this method, as I find it bad.",[613,7416,7418],{"id":7417},"actual-volumes","Actual \"Volumes\"",[523,7420,7421,7422,7425,7426,3052],{},"Docker has a way of managing volumes that are with the \"default storage\" directories on the same server.\nTo list, create, delete, and manage these volumes you can use the ",[567,7423,7424],{},"docker volume ls"," command and the other subcommands (e.g., ",[567,7427,7428],{},"docker volume --help",[523,7430,7431,7432,3052],{},"These volumes are persisted across container restarts\u002Fdeletions, unless the volume is removed (",[567,7433,7434],{},"docker volume rm VOLUME_NAME",[523,7436,7437],{},"For scalable applications storage aka \"persistence of data\" is important.",[2979,7439],{},[535,7441,193],{"id":7442},"networking",[523,7444,7445],{},"Brace Yourself for container network stuff!",[613,7447,7449],{"id":7448},"nating-using-iptables","NATing using iptables",[523,7451,7452],{},"I'm not going to explain NAT in detail here.",[523,7454,7455],{},"To badly summarize it, NAT also known as \"Network Address Translation\", allows multiple devices to share one (public) IP address. This is mainly used with IPv4 based networks, as with IPv6 there's enough IPs available.",[613,7457,7459],{"id":7458},"over-seven-bridges-you-must-go-docker0-bridge-and-veth-interfaces","Over seven bridges you must go (docker0 bridge and veth interfaces)",[523,7461,7462,7463,714,7466,7469,7470,7473,7474,7476,7477,7480,7481,6353,7484,7487,7488,7491,7492,6374,7495,1909],{},"Docker creates a bridge interface that is used as a bridge to your network interfaces (",[567,7464,7465],{},"eth0",[567,7467,7468],{},"en0",", etc.). The bridge Docker creates is called ",[567,7471,7472],{},"docker0"," by default.\nBy default the ",[567,7475,7472],{}," bridge will be assigned the ",[567,7478,7479],{},"172.17.0.1\u002F16"," IP range as a network. This IP address range will be used, to assign every container a separate IP.\nSometimes the bridge address range needs to be adjusted, in most cases when you are running Docker in a corporate network or the network range is just already in use\u002Fallocated.\nYou would need to add the ",[567,7482,7483],{},"--bip=192.168.1.0\u002F24",[567,7485,7486],{},"192.168.1.0\u002F24"," is an unused IP range) to on Debian based systems to the ",[567,7489,7490],{},"\u002Fetc\u002Fdefault\u002Fdocker"," or on RHEL based systems to the ",[567,7493,7494],{},"\u002Fetc\u002Fsysconfig\u002Fdocker",[567,7496,7497],{},"\u002Fetc\u002Fsysconfig\u002Fdocker-network",[523,7499,7500,7501,7504,7505,7507,7508,7510,7511,7513,7514,6374,7517,1909],{},"When a container is created, a ",[567,7502,7503],{},"veth"," interface will be created too (depending on the network mode). The ",[567,7506,7503],{}," interface will have an unique name. ",[567,7509,7503],{}," stands for virtual ethernet device. The ",[567,7512,7503],{}," device will \"connect\" to the bridge, to acquire network connectivity. The veth interface will not show the ip address when using tools like ",[567,7515,7516],{},"ip addr show",[567,7518,7519],{},"ifconfig",[523,7521,7522],{},[584,7523,3673],{},[738,7525,7527],{"className":1621,"code":7526,"language":1623,"meta":743,"style":743},"$ ip address show\n1: lo: \u003CLOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000\n    link\u002Floopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n    inet 127.0.0.1\u002F8 scope host lo\n       valid_lft forever preferred_lft forever\n    inet6 ::1\u002F128 scope host noprefixroute\n       valid_lft forever preferred_lft forever\n2: enp9s0f0: \u003CBROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000\n# [...]\n8: docker0: \u003CBROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default\n    link\u002Fether 02:42:c8:3e:85:6a brd ff:ff:ff:ff:ff:ff\n    inet 172.17.0.1\u002F16 brd 172.17.255.255 scope global docker0\n       valid_lft forever preferred_lft forever\n    inet6 fe80::42:c8ff:fe3e:856a\u002F64 scope link proto kernel_ll\n       valid_lft forever preferred_lft forever\n20: veth8d1ae95@if19: \u003CBROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default\n    link\u002Fether 5e:ca:e7:b8:45:9b brd ff:ff:ff:ff:ff:ff link-netnsid 0\n    inet6 fe80::5cca:e7ff:feb8:459b\u002F64 scope link proto kernel_ll\n       valid_lft forever preferred_lft foreve\n",[567,7528,7529,7542,7590,7604,7620,7634,7649,7659,7699,7704,7737,7750,7770,7780,7798,7808,7846,7864,7879],{"__ignoreMap":743},[747,7530,7531,7533,7536,7539],{"class":749,"line":750},[747,7532,1919],{"class":1630},[747,7534,7535],{"class":802}," ip",[747,7537,7538],{"class":802}," address",[747,7540,7541],{"class":802}," show\n",[747,7543,7544,7547,7550,7553,7556,7559,7561,7564,7567,7570,7573,7576,7579,7582,7584,7587],{"class":749,"line":761},[747,7545,7546],{"class":1630},"1:",[747,7548,7549],{"class":802}," lo:",[747,7551,7552],{"class":757}," \u003C",[747,7554,7555],{"class":802},"LOOPBACK,UP,LOWER_U",[747,7557,7558],{"class":1640},"P",[747,7560,2035],{"class":757},[747,7562,7563],{"class":802}," mtu",[747,7565,7566],{"class":1895}," 65536",[747,7568,7569],{"class":802}," qdisc",[747,7571,7572],{"class":802}," noqueue",[747,7574,7575],{"class":802}," state",[747,7577,7578],{"class":802}," UNKNOWN",[747,7580,7581],{"class":802}," group",[747,7583,1931],{"class":802},[747,7585,7586],{"class":802}," qlen",[747,7588,7589],{"class":1895}," 1000\n",[747,7591,7592,7595,7598,7601],{"class":749,"line":769},[747,7593,7594],{"class":1630},"    link\u002Floopback",[747,7596,7597],{"class":802}," 00:00:00:00:00:00",[747,7599,7600],{"class":802}," brd",[747,7602,7603],{"class":802}," 00:00:00:00:00:00\n",[747,7605,7606,7609,7612,7615,7617],{"class":749,"line":776},[747,7607,7608],{"class":1630},"    inet",[747,7610,7611],{"class":802}," 127.0.0.1\u002F8",[747,7613,7614],{"class":802}," scope",[747,7616,4591],{"class":802},[747,7618,7619],{"class":802}," lo\n",[747,7621,7622,7625,7628,7631],{"class":749,"line":784},[747,7623,7624],{"class":1630},"       valid_lft",[747,7626,7627],{"class":802}," forever",[747,7629,7630],{"class":802}," preferred_lft",[747,7632,7633],{"class":802}," forever\n",[747,7635,7636,7639,7642,7644,7646],{"class":749,"line":790},[747,7637,7638],{"class":1630},"    inet6",[747,7640,7641],{"class":802}," ::1\u002F128",[747,7643,7614],{"class":802},[747,7645,4591],{"class":802},[747,7647,7648],{"class":802}," noprefixroute\n",[747,7650,7651,7653,7655,7657],{"class":749,"line":796},[747,7652,7624],{"class":1630},[747,7654,7627],{"class":802},[747,7656,7630],{"class":802},[747,7658,7633],{"class":802},[747,7660,7661,7664,7667,7669,7672,7674,7676,7678,7681,7683,7686,7688,7691,7693,7695,7697],{"class":749,"line":806},[747,7662,7663],{"class":1630},"2:",[747,7665,7666],{"class":802}," enp9s0f0:",[747,7668,7552],{"class":757},[747,7670,7671],{"class":802},"BROADCAST,MULTICAST,UP,LOWER_U",[747,7673,7558],{"class":1640},[747,7675,2035],{"class":757},[747,7677,7563],{"class":802},[747,7679,7680],{"class":1895}," 1500",[747,7682,7569],{"class":802},[747,7684,7685],{"class":802}," mq",[747,7687,7575],{"class":802},[747,7689,7690],{"class":802}," UP",[747,7692,7581],{"class":802},[747,7694,1931],{"class":802},[747,7696,7586],{"class":802},[747,7698,7589],{"class":1895},[747,7700,7701],{"class":749,"line":814},[747,7702,7703],{"class":772},"# [...]\n",[747,7705,7706,7709,7712,7714,7716,7718,7720,7722,7724,7726,7728,7730,7732,7734],{"class":749,"line":822},[747,7707,7708],{"class":1630},"8:",[747,7710,7711],{"class":802}," docker0:",[747,7713,7552],{"class":757},[747,7715,7671],{"class":802},[747,7717,7558],{"class":1640},[747,7719,2035],{"class":757},[747,7721,7563],{"class":802},[747,7723,7680],{"class":1895},[747,7725,7569],{"class":802},[747,7727,7572],{"class":802},[747,7729,7575],{"class":802},[747,7731,7690],{"class":802},[747,7733,7581],{"class":802},[747,7735,7736],{"class":802}," default\n",[747,7738,7739,7742,7745,7747],{"class":749,"line":830},[747,7740,7741],{"class":1630},"    link\u002Fether",[747,7743,7744],{"class":802}," 02:42:c8:3e:85:6a",[747,7746,7600],{"class":802},[747,7748,7749],{"class":802}," ff:ff:ff:ff:ff:ff\n",[747,7751,7752,7754,7757,7759,7762,7764,7767],{"class":749,"line":836},[747,7753,7608],{"class":1630},[747,7755,7756],{"class":802}," 172.17.0.1\u002F16",[747,7758,7600],{"class":802},[747,7760,7761],{"class":1895}," 172.17.255.255",[747,7763,7614],{"class":802},[747,7765,7766],{"class":802}," global",[747,7768,7769],{"class":802}," docker0\n",[747,7771,7772,7774,7776,7778],{"class":749,"line":842},[747,7773,7624],{"class":1630},[747,7775,7627],{"class":802},[747,7777,7630],{"class":802},[747,7779,7633],{"class":802},[747,7781,7782,7784,7787,7789,7792,7795],{"class":749,"line":850},[747,7783,7638],{"class":1630},[747,7785,7786],{"class":802}," fe80::42:c8ff:fe3e:856a\u002F64",[747,7788,7614],{"class":802},[747,7790,7791],{"class":802}," link",[747,7793,7794],{"class":802}," proto",[747,7796,7797],{"class":802}," kernel_ll\n",[747,7799,7800,7802,7804,7806],{"class":749,"line":863},[747,7801,7624],{"class":1630},[747,7803,7627],{"class":802},[747,7805,7630],{"class":802},[747,7807,7633],{"class":802},[747,7809,7810,7813,7816,7818,7820,7822,7824,7826,7828,7830,7832,7835,7838,7840,7842,7844],{"class":749,"line":869},[747,7811,7812],{"class":1630},"20:",[747,7814,7815],{"class":802}," veth8d1ae95@if19:",[747,7817,7552],{"class":757},[747,7819,7671],{"class":802},[747,7821,7558],{"class":1640},[747,7823,2035],{"class":757},[747,7825,7563],{"class":802},[747,7827,7680],{"class":1895},[747,7829,7569],{"class":802},[747,7831,7572],{"class":802},[747,7833,7834],{"class":802}," master",[747,7836,7837],{"class":802}," docker0",[747,7839,7575],{"class":802},[747,7841,7690],{"class":802},[747,7843,7581],{"class":802},[747,7845,7736],{"class":802},[747,7847,7848,7850,7853,7855,7858,7861],{"class":749,"line":877},[747,7849,7741],{"class":1630},[747,7851,7852],{"class":802}," 5e:ca:e7:b8:45:9b",[747,7854,7600],{"class":802},[747,7856,7857],{"class":802}," ff:ff:ff:ff:ff:ff",[747,7859,7860],{"class":802}," link-netnsid",[747,7862,7863],{"class":1895}," 0\n",[747,7865,7866,7868,7871,7873,7875,7877],{"class":749,"line":1015},[747,7867,7638],{"class":1630},[747,7869,7870],{"class":802}," fe80::5cca:e7ff:feb8:459b\u002F64",[747,7872,7614],{"class":802},[747,7874,7791],{"class":802},[747,7876,7794],{"class":802},[747,7878,7797],{"class":802},[747,7880,7881,7883,7885,7887],{"class":749,"line":1021},[747,7882,7624],{"class":1630},[747,7884,7627],{"class":802},[747,7886,7630],{"class":802},[747,7888,7889],{"class":802}," foreve\n",[523,7891,7892,7893,7896],{},"This output shows, the docker0 interface and the veth interface of the database container. In the end we use ",[567,7894,7895],{},"docker inspect CONTAINER"," to get the IPAddress of the container.",[523,7898,7899,7900,1909],{},"Docker has the feature to even create an overlay network, between multiple machines. But I'm not going deeper into this.\nFor people interested in this feature, see the Docker docs ",[527,7901,7904],{"href":7902,"rel":7903},"https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Freference\u002Fcommandline\u002Fnetwork_create\u002F",[531],"here (Docs Docker network create)",[613,7906,7908],{"id":7907},"network-modes-default-host-or-other","Network \"modes\" (\"default\", host or other)",[523,7910,7911],{},"I've wrote, that I'm not going deeper into Docker's \"own\" (overlay) network feature, but with this topic, I'll have to go into it just a bit.",[523,7913,7914,7915,6378,7917,7920,7921,7923],{},"When running a container the default network \"mode\" is named ",[567,7916,2014],{},[567,7918,7919],{},"--net=default","). The ",[567,7922,2014],{}," network \"mode\" creates a separate network stack for every container.",[523,7925,7926,7927,7930,7931,7933],{},"There is also the network \"mode\" ",[567,7928,7929],{},"host"," available by default. The ",[567,7932,7929],{}," network \"mode\" gives the host network stack aka \"full access to the network of the host system\" inside the container.\nThis can be a huge security risk! When a container has",[523,7935,7936],{},"The network \"mode\" can be also the name of an (overlay) network created using the Docker \"client\" (engine).",[523,7938,7939],{},[584,7940,3673],{},[738,7942,7944],{"className":1621,"code":7943,"language":1623,"meta":743,"style":743},"$ docker run -it docker.io\u002Flibrary\u002Fbusybox:latest sh\nUnable to find image 'busybox:latest' locally\nlatest: Pulling from library\u002Fbusybox\n2fce1e0cdfc5: Pull complete\nDigest: sha256:c230832bd3b0be59a6c47ed64294f9ce71e91b327957920b6929a0caa8353140\nStatus: Downloaded newer image for busybox:latest\n\u002F # ip l\n1: lo: \u003CLOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000\n    link\u002Floopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n17: eth0@if18: \u003CBROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue\n    link\u002Fether 02:00:00:11:00:00 brd ff:ff:ff:ff:ff:ff\n\u002F # ip a\n1: lo: \u003CLOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000\n    link\u002Floopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n    inet 127.0.0.1\u002F8 scope host lo\n       valid_lft forever preferred_lft forever\n17: eth0@if18: \u003CBROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue\n    link\u002Fether 02:00:00:11:00:00 brd ff:ff:ff:ff:ff:ff\n    inet 172.17.0.2\u002F16 brd 172.17.255.255 scope global eth0\n       valid_lft forever preferred_lft forever\n\u002F # exit\n",[567,7945,7946,7961,7980,7991,8000,8007,8022,8030,8056,8066,8093,8104,8111,8137,8147,8159,8169,8191,8201,8219,8229],{"__ignoreMap":743},[747,7947,7948,7950,7952,7954,7956,7959],{"class":749,"line":750},[747,7949,1919],{"class":1630},[747,7951,3246],{"class":802},[747,7953,3665],{"class":802},[747,7955,4072],{"class":802},[747,7957,7958],{"class":802}," docker.io\u002Flibrary\u002Fbusybox:latest",[747,7960,3173],{"class":802},[747,7962,7963,7965,7967,7969,7971,7973,7976,7978],{"class":749,"line":761},[747,7964,3693],{"class":1630},[747,7966,3696],{"class":802},[747,7968,3699],{"class":802},[747,7970,3702],{"class":802},[747,7972,3537],{"class":757},[747,7974,7975],{"class":802},"busybox:latest",[747,7977,3543],{"class":757},[747,7979,3712],{"class":802},[747,7981,7982,7984,7986,7988],{"class":749,"line":769},[747,7983,3717],{"class":1630},[747,7985,3720],{"class":802},[747,7987,3723],{"class":802},[747,7989,7990],{"class":802}," library\u002Fbusybox\n",[747,7992,7993,7996,7998],{"class":749,"line":776},[747,7994,7995],{"class":1630},"2fce1e0cdfc5:",[747,7997,3734],{"class":802},[747,7999,3737],{"class":802},[747,8001,8002,8004],{"class":749,"line":784},[747,8003,3742],{"class":1630},[747,8005,8006],{"class":802}," sha256:c230832bd3b0be59a6c47ed64294f9ce71e91b327957920b6929a0caa8353140\n",[747,8008,8009,8011,8013,8015,8017,8019],{"class":749,"line":790},[747,8010,3750],{"class":1630},[747,8012,3753],{"class":802},[747,8014,3756],{"class":802},[747,8016,3702],{"class":802},[747,8018,3761],{"class":802},[747,8020,8021],{"class":802}," busybox:latest\n",[747,8023,8024,8027],{"class":749,"line":796},[747,8025,8026],{"class":1630},"\u002F",[747,8028,8029],{"class":772}," # ip l\n",[747,8031,8032,8034,8036,8038,8040,8042,8044,8046,8048,8050,8052,8054],{"class":749,"line":806},[747,8033,7546],{"class":1630},[747,8035,7549],{"class":802},[747,8037,7552],{"class":757},[747,8039,7555],{"class":802},[747,8041,7558],{"class":1640},[747,8043,2035],{"class":757},[747,8045,7563],{"class":802},[747,8047,7566],{"class":1895},[747,8049,7569],{"class":802},[747,8051,7572],{"class":802},[747,8053,7586],{"class":802},[747,8055,7589],{"class":1895},[747,8057,8058,8060,8062,8064],{"class":749,"line":814},[747,8059,7594],{"class":1630},[747,8061,7597],{"class":802},[747,8063,7600],{"class":802},[747,8065,7603],{"class":802},[747,8067,8068,8071,8074,8076,8079,8082,8084,8086,8088,8090],{"class":749,"line":822},[747,8069,8070],{"class":1630},"17:",[747,8072,8073],{"class":802}," eth0@if18:",[747,8075,7552],{"class":757},[747,8077,8078],{"class":802},"BROADCAST,MULTICAST,UP,LOWER_UP,M-DOW",[747,8080,8081],{"class":1640},"N",[747,8083,2035],{"class":757},[747,8085,7563],{"class":802},[747,8087,7680],{"class":1895},[747,8089,7569],{"class":802},[747,8091,8092],{"class":802}," noqueue\n",[747,8094,8095,8097,8100,8102],{"class":749,"line":830},[747,8096,7741],{"class":1630},[747,8098,8099],{"class":802}," 02:00:00:11:00:00",[747,8101,7600],{"class":802},[747,8103,7749],{"class":802},[747,8105,8106,8108],{"class":749,"line":836},[747,8107,8026],{"class":1630},[747,8109,8110],{"class":772}," # ip a\n",[747,8112,8113,8115,8117,8119,8121,8123,8125,8127,8129,8131,8133,8135],{"class":749,"line":842},[747,8114,7546],{"class":1630},[747,8116,7549],{"class":802},[747,8118,7552],{"class":757},[747,8120,7555],{"class":802},[747,8122,7558],{"class":1640},[747,8124,2035],{"class":757},[747,8126,7563],{"class":802},[747,8128,7566],{"class":1895},[747,8130,7569],{"class":802},[747,8132,7572],{"class":802},[747,8134,7586],{"class":802},[747,8136,7589],{"class":1895},[747,8138,8139,8141,8143,8145],{"class":749,"line":850},[747,8140,7594],{"class":1630},[747,8142,7597],{"class":802},[747,8144,7600],{"class":802},[747,8146,7603],{"class":802},[747,8148,8149,8151,8153,8155,8157],{"class":749,"line":863},[747,8150,7608],{"class":1630},[747,8152,7611],{"class":802},[747,8154,7614],{"class":802},[747,8156,4591],{"class":802},[747,8158,7619],{"class":802},[747,8160,8161,8163,8165,8167],{"class":749,"line":869},[747,8162,7624],{"class":1630},[747,8164,7627],{"class":802},[747,8166,7630],{"class":802},[747,8168,7633],{"class":802},[747,8170,8171,8173,8175,8177,8179,8181,8183,8185,8187,8189],{"class":749,"line":877},[747,8172,8070],{"class":1630},[747,8174,8073],{"class":802},[747,8176,7552],{"class":757},[747,8178,8078],{"class":802},[747,8180,8081],{"class":1640},[747,8182,2035],{"class":757},[747,8184,7563],{"class":802},[747,8186,7680],{"class":1895},[747,8188,7569],{"class":802},[747,8190,8092],{"class":802},[747,8192,8193,8195,8197,8199],{"class":749,"line":1015},[747,8194,7741],{"class":1630},[747,8196,8099],{"class":802},[747,8198,7600],{"class":802},[747,8200,7749],{"class":802},[747,8202,8203,8205,8208,8210,8212,8214,8216],{"class":749,"line":1021},[747,8204,7608],{"class":1630},[747,8206,8207],{"class":802}," 172.17.0.2\u002F16",[747,8209,7600],{"class":802},[747,8211,7761],{"class":1895},[747,8213,7614],{"class":802},[747,8215,7766],{"class":802},[747,8217,8218],{"class":802}," eth0\n",[747,8220,8221,8223,8225,8227],{"class":749,"line":1027},[747,8222,7624],{"class":1630},[747,8224,7627],{"class":802},[747,8226,7630],{"class":802},[747,8228,7633],{"class":802},[747,8230,8231,8233],{"class":749,"line":1033},[747,8232,8026],{"class":1630},[747,8234,8235],{"class":772}," # exit\n",[523,8237,8238,8239,8241],{},"In the output, you can see that when using the default network mode you'll get a \"newly\" created network stack and when using the ",[567,8240,7929],{}," network mode, the container gets the hosts network stack.",[613,8243,8245],{"id":8244},"publishing-ports","Publishing ports",[523,8247,8248,8249,8251,8252,8255,8256,8258,8259,1909],{},"When using the ",[567,8250,2014],{}," network mode, Docker creates ",[567,8253,8254],{},"iptables"," rules so published\u002Fforwarded ports are reachable from the outside.\nIn the example, we see the ",[567,8257,8254],{}," rules for a container with published port ",[567,8260,8261],{},"80\u002Fhttp",[523,8263,8264],{},[584,8265,3673],{},[523,8267,8268],{},[3069,8269],{"alt":8270,"src":8271},"Example iptables list output","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Fdocker-iptables-output.png",[523,8273,8274,8275,8278,8279,8282],{},"As we can see Docker uses a separate ",[567,8276,8277],{},"DOCKER"," chain in the ",[567,8280,8281],{},"FORWARD"," chain, to map incoming traffic on port 80 to the container IP.\nAfter the destination IP has been changed, Docker uses DNAT (Destination Network Address Translation), to \"map\" the traffic to the container's end address.",[523,8284,8285,8287,8288],{},[584,8286,2951],{}," ",[527,8289,8292],{"href":8290,"rel":8291},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-docker\u002Ftree\u002Fmaster\u002Fnetwork101",[531],[567,8293,8294],{},"network101",[523,8296,8297,8298,8301,8302,8304,8305,8307],{},"You can use the script ",[567,8299,8300],{},"show_me_the_network.sh"," from task ",[567,8303,8294],{},", to view your network interfaces and current ",[567,8306,8254],{}," rules.",[613,8309,8311],{"id":8310},"looking-into-your-network","Looking into your network",[523,8313,8314,8315,8318,8319,8321],{},"Before we dive into the network, the tool (",[567,8316,8317],{},"scope",") used in this section might not fully work anymore depending on your Docker version. The reason for this is that \"Weave Works\", the company behind the ",[567,8320,8317],{}," project, has shut downed a few years ago..",[523,8323,8324,8287,8326],{},[584,8325,2951],{},[527,8327,8329],{"href":8290,"rel":8328},[531],[567,8330,8294],{},[523,8332,8333],{},"Do you want to visualize your container network situation? Yes? Then one available tool is Weave Scope.",[523,8335,8336,8337,8339,8340,8343],{},"In the ",[567,8338,8294],{}," task is a file called ",[567,8341,8342],{},"start_weave_scope.sh",". The script downloads the Weave Scope wrapper script, that starts the containers needed for Weave Scope to function.\nThe commands that are used to download the Weave Scope wrapper script are:",[738,8345,8347],{"className":1621,"code":8346,"language":1623,"meta":743,"style":743},"sudo wget -O \u002Fusr\u002Flocal\u002Fbin\u002Fscope https:\u002F\u002Fgit.io\u002Fscope\nsudo chmod a+x \u002Fusr\u002Flocal\u002Fbin\u002Fscope\nsudo scope launch\n",[567,8348,8349,8364,8376],{"__ignoreMap":743},[747,8350,8351,8353,8356,8358,8361],{"class":749,"line":750},[747,8352,3376],{"class":1630},[747,8354,8355],{"class":802}," wget",[747,8357,3340],{"class":802},[747,8359,8360],{"class":802}," \u002Fusr\u002Flocal\u002Fbin\u002Fscope",[747,8362,8363],{"class":802}," https:\u002F\u002Fgit.io\u002Fscope\n",[747,8365,8366,8368,8370,8373],{"class":749,"line":761},[747,8367,3376],{"class":1630},[747,8369,3379],{"class":802},[747,8371,8372],{"class":802}," a+x",[747,8374,8375],{"class":802}," \u002Fusr\u002Flocal\u002Fbin\u002Fscope\n",[747,8377,8378,8380,8382],{"class":749,"line":769},[747,8379,3376],{"class":1630},[747,8381,7614],{"class":802},[747,8383,8384],{"class":802}," launch\n",[523,8386,8387,8388,8392],{},"After the image of the container has been pulled and started, you can then navigate to ",[527,8389,8390],{"href":8390,"rel":8391},"http:\u002F\u002Flocalhost:4040",[531]," to see the Weave Scope UI.",[523,8394,8395],{},[584,8396,3521],{},[523,8398,8399],{},[3069,8400],{"alt":8401,"src":8402},"Weave Scope UI","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Fweavescope_ui.png",[523,8404,8405],{},"Through the Weave Scope UI you gain an immersive insight into your network of the containers.",[523,8407,8408,8409,1909],{},"Due to the closure of \"Weave Works\", nowadays other tools based on \"new kernel technologies\" (eBPF) have taken the place, one of them is ",[527,8410,8413],{"href":8411,"rel":8412},"https:\u002F\u002Fcilium.io\u002F",[531],"Cilium CNI",[2979,8415],{},[535,8417,8419],{"id":8418},"limiting-container-resources","Limiting container resources",[523,8421,8422],{},"\"It's OK I know my limit\"",[523,8424,8425],{},[3049,8426,8427],{},"- said the rogue process",[523,8429,8430,8431,8435],{},"As I already mentioned in the ",[527,8432,8434],{"href":8433},"#container","Container!?"," part, namespaces can be used to limit the resources available to the processes, etc., in it.",[613,8437,8439],{"id":8438},"cpu-limit","CPU Limit",[523,8441,8442],{},"Limiting the precious computing resource of a container.",[738,8444,8446],{"className":1621,"code":8445,"language":1623,"meta":743,"style":743},"$ docker run --help\n[...]\n  --cpu-period                    Limit CPU CFS (Completely Fair Scheduler) period\n  --cpu-quota                     Limit CPU CFS (Completely Fair Scheduler) quota\n  --cpuset-cpus                   CPUs in which to allow execution (0-3, 0,1)\n[...]\n",[567,8447,8448,8458,8466,8492,8513,8541],{"__ignoreMap":743},[747,8449,8450,8452,8454,8456],{"class":749,"line":750},[747,8451,1919],{"class":1630},[747,8453,3246],{"class":802},[747,8455,3665],{"class":802},[747,8457,4218],{"class":802},[747,8459,8460,8462,8464],{"class":749,"line":761},[747,8461,4253],{"class":757},[747,8463,5685],{"class":1640},[747,8465,4268],{"class":757},[747,8467,8468,8471,8474,8477,8480,8483,8486,8489],{"class":749,"line":769},[747,8469,8470],{"class":1630},"  --cpu-period",[747,8472,8473],{"class":802},"                    Limit",[747,8475,8476],{"class":802}," CPU",[747,8478,8479],{"class":802}," CFS",[747,8481,8482],{"class":1640}," (Completely ",[747,8484,8485],{"class":802},"Fair",[747,8487,8488],{"class":802}," Scheduler",[747,8490,8491],{"class":1640},") period\n",[747,8493,8494,8497,8500,8502,8504,8506,8508,8510],{"class":749,"line":776},[747,8495,8496],{"class":1630},"  --cpu-quota",[747,8498,8499],{"class":802},"                     Limit",[747,8501,8476],{"class":802},[747,8503,8479],{"class":802},[747,8505,8482],{"class":1640},[747,8507,8485],{"class":802},[747,8509,8488],{"class":802},[747,8511,8512],{"class":1640},") quota\n",[747,8514,8515,8518,8521,8523,8525,8527,8530,8533,8536,8539],{"class":749,"line":784},[747,8516,8517],{"class":1630},"  --cpuset-cpus",[747,8519,8520],{"class":802},"                   CPUs",[747,8522,4584],{"class":802},[747,8524,3945],{"class":802},[747,8526,3696],{"class":802},[747,8528,8529],{"class":802}," allow",[747,8531,8532],{"class":802}," execution",[747,8534,8535],{"class":1640}," (0-3, ",[747,8537,8538],{"class":802},"0,1",[747,8540,3600],{"class":1640},[747,8542,8543,8545,8547],{"class":749,"line":790},[747,8544,4253],{"class":757},[747,8546,5685],{"class":1640},[747,8548,4268],{"class":757},[523,8550,8551,8552,3052],{},"You can limit the time period and the quota of the CFS (Completely Fair Scheduler).\nLimiting a container to specific cores is also possible (",[567,8553,8554],{},"--cpuset-cpus",[613,8556,8558],{"id":8557},"memory-and-swap-limit","Memory and Swap Limit",[738,8560,8562],{"className":1621,"code":8561,"language":1623,"meta":743,"style":743},"$ docker run --help\n[...]\n  --cpuset-mems                   MEMs in which to allow execution (0-3, 0,1)\n[...]\n  --kernel-memory                 Kernel memory limit\n[...]\n  --memory-reservation            Memory soft limit\n  --memory-swap                   Swap limit equal to memory plus swap: '-1' to enable unlimited swap\n  --memory-swappiness=-1          Tune container memory swappiness (0 to 100)\n[...]\n  --oom-kill-disable              Disable OOM Killer\n  --oom-score-adj                 Tune host's OOM preferences (-1000 to 1000)\n[...]\n",[567,8563,8564,8574,8582,8606,8614,8628,8636,8649,8687,8716,8724,8737,8752],{"__ignoreMap":743},[747,8565,8566,8568,8570,8572],{"class":749,"line":750},[747,8567,1919],{"class":1630},[747,8569,3246],{"class":802},[747,8571,3665],{"class":802},[747,8573,4218],{"class":802},[747,8575,8576,8578,8580],{"class":749,"line":761},[747,8577,4253],{"class":757},[747,8579,5685],{"class":1640},[747,8581,4268],{"class":757},[747,8583,8584,8587,8590,8592,8594,8596,8598,8600,8602,8604],{"class":749,"line":769},[747,8585,8586],{"class":1630},"  --cpuset-mems",[747,8588,8589],{"class":802},"                   MEMs",[747,8591,4584],{"class":802},[747,8593,3945],{"class":802},[747,8595,3696],{"class":802},[747,8597,8529],{"class":802},[747,8599,8532],{"class":802},[747,8601,8535],{"class":1640},[747,8603,8538],{"class":802},[747,8605,3600],{"class":1640},[747,8607,8608,8610,8612],{"class":749,"line":776},[747,8609,4253],{"class":757},[747,8611,5685],{"class":1640},[747,8613,4268],{"class":757},[747,8615,8616,8619,8622,8625],{"class":749,"line":784},[747,8617,8618],{"class":1630},"  --kernel-memory",[747,8620,8621],{"class":802},"                 Kernel",[747,8623,8624],{"class":802}," memory",[747,8626,8627],{"class":802}," limit\n",[747,8629,8630,8632,8634],{"class":749,"line":790},[747,8631,4253],{"class":757},[747,8633,5685],{"class":1640},[747,8635,4268],{"class":757},[747,8637,8638,8641,8644,8647],{"class":749,"line":796},[747,8639,8640],{"class":1630},"  --memory-reservation",[747,8642,8643],{"class":802},"            Memory",[747,8645,8646],{"class":802}," soft",[747,8648,8627],{"class":802},[747,8650,8651,8654,8657,8659,8662,8664,8666,8669,8672,8674,8676,8678,8680,8682,8684],{"class":749,"line":806},[747,8652,8653],{"class":1630},"  --memory-swap",[747,8655,8656],{"class":802},"                   Swap",[747,8658,5033],{"class":802},[747,8660,8661],{"class":802}," equal",[747,8663,3696],{"class":802},[747,8665,8624],{"class":802},[747,8667,8668],{"class":802}," plus",[747,8670,8671],{"class":802}," swap:",[747,8673,3537],{"class":757},[747,8675,4920],{"class":802},[747,8677,3543],{"class":757},[747,8679,3696],{"class":802},[747,8681,3205],{"class":802},[747,8683,5043],{"class":802},[747,8685,8686],{"class":802}," swap\n",[747,8688,8689,8692,8694,8696,8699,8701,8703,8706,8709,8711,8714],{"class":749,"line":814},[747,8690,8691],{"class":1640},"  --memory-swappiness",[747,8693,6425],{"class":757},[747,8695,4920],{"class":802},[747,8697,8698],{"class":1630},"          Tune",[747,8700,3936],{"class":802},[747,8702,8624],{"class":802},[747,8704,8705],{"class":802}," swappiness",[747,8707,8708],{"class":1640}," (0 ",[747,8710,4990],{"class":802},[747,8712,8713],{"class":1895}," 100",[747,8715,3600],{"class":1640},[747,8717,8718,8720,8722],{"class":749,"line":822},[747,8719,4253],{"class":757},[747,8721,5685],{"class":1640},[747,8723,4268],{"class":757},[747,8725,8726,8729,8732,8734],{"class":749,"line":830},[747,8727,8728],{"class":1630},"  --oom-kill-disable",[747,8730,8731],{"class":802},"              Disable",[747,8733,4981],{"class":802},[747,8735,8736],{"class":802}," Killer\n",[747,8738,8739,8742,8745,8747,8749],{"class":749,"line":836},[747,8740,8741],{"class":1630},"  --oom-score-adj",[747,8743,8744],{"class":802},"                 Tune",[747,8746,4591],{"class":802},[747,8748,3543],{"class":757},[747,8750,8751],{"class":802},"s OOM preferences (-1000 to 1000)\n",[747,8753,8754],{"class":749,"line":842},[747,8755,5986],{"class":802},[523,8757,8758],{},"As you can see, there is a good amount of option to play around with the memory a container can use and how it can use the memory.",[523,8760,8761],{},"A good feature if you have limited memory available is to play with the memory swappiness.",[523,8763,8764,8765,8768],{},"The ",[567,8766,8767],{},"OOM"," (Linux Out of Memory Management) options are good, if you have memory intensive applications, but only limited memory available. So important application container don't get killed, when the system should run out of memory.",[613,8770,8772],{"id":8771},"other-limits","Other Limits",[523,8774,8775],{},"There are other options for limiting resources of a container\u002Fnamespace available, though for this workshop they are out of scope.\nE.g., disk read\u002Fwrite IO, GPUs.",[2979,8777],{},[535,8779,8781],{"id":8780},"selfies-i-mean-images","\"Selfies? I mean Images\"",[523,8783,8784],{},"An image is the core of a container. Without an image, there would be no container.\nCreating images is simple to do, depending on what you try to \"containerize\".\nIn this part we set a simple goal. Our goal is to create a container that runs nginx in it.",[613,8786,8788],{"id":8787},"image-names-explained","Image Names explained",[523,8790,8791,8792,8797],{},"Images that \"come\" from the ",[527,8793,8796],{"href":8794,"rel":8795},"https:\u002F\u002Fhub.docker.com\u002F",[531],"Docker Image Hub",", don't need a repository specified.",[523,8799,8800],{},"The image we used for the MySQL container is:",[738,8802,8804],{"className":1621,"code":8803,"language":1623,"meta":743,"style":743},"docker.io\u002Flibrary\u002Fmysql:latest\n",[567,8805,8806],{"__ignoreMap":743},[747,8807,8808],{"class":749,"line":750},[747,8809,8803],{"class":1630},[523,8811,8812,856],{},[584,8813,2957],{},[668,8815,8816,8825,8830],{},[638,8817,8818,8821,8822,8824],{},[567,8819,8820],{},"library"," - The username of the creator. Please note that on Docker Hub the ",[567,8823,8820],{}," \"user\" is for official images.",[638,8826,8827,8829],{},[567,8828,6744],{}," - The name of the image.",[638,8831,8832,8835],{},[567,8833,8834],{},"latest"," - The \"version\" tag. The tag can be anything, but emojis.",[523,8837,8838,8839,8844,8845,1909],{},"An example for an image that is pulled from a different image server, than the official Docker Hub, is my image for ",[527,8840,8843],{"href":8841,"rel":8842},"https:\u002F\u002Fzulip.org\u002F",[531],"Zulip"," by Dropbox that is hosted on ",[527,8846,8849],{"href":8847,"rel":8848},"https:\u002F\u002Fquay.io",[531],"quay.io",[738,8851,8853],{"className":1621,"code":8852,"language":1623,"meta":743,"style":743},"quay.io\u002Fgalexrt\u002Fzulip:1.3.10\nSERVER\u002FUSERNAME\u002FIMAGE_NAME:TAG\n",[567,8854,8855,8860],{"__ignoreMap":743},[747,8856,8857],{"class":749,"line":750},[747,8858,8859],{"class":1630},"quay.io\u002Fgalexrt\u002Fzulip:1.3.10\n",[747,8861,8862],{"class":749,"line":761},[747,8863,8864],{"class":1630},"SERVER\u002FUSERNAME\u002FIMAGE_NAME:TAG\n",[523,8866,8867,856],{},[584,8868,2957],{},[668,8870,8871,8883,8891,8900],{},[638,8872,8873,714,8875,8878,8879,8882],{},[567,8874,8849],{},[567,8876,8877],{},"SERVER"," - Defaults to ",[567,8880,8881],{},"docker.io",". The image repository server to pull the image from.",[638,8884,8885,714,8888,8890],{},[567,8886,8887],{},"galexrt",[567,8889,3267],{}," - Username of the image creator\u002Fuploader.",[638,8892,8893,714,8896,8899],{},[567,8894,8895],{},"zulip",[567,8897,8898],{},"IMAGE_NAME"," - Name of the image.",[638,8901,8902,714,8905,8908,8909,8911],{},[567,8903,8904],{},"1.3.10",[567,8906,8907],{},"TAG"," - Like git tags. When not specified, the default is ",[567,8910,8834],{}," (which is not good).",[523,8913,8914,8915,3052],{},"In the case of official created images, like the WordPress image we used no server and username is required (by default).\nOfficial images are \"marked\" through the \"missing\" username in the image name and the Docker Image Hub url having an underscore instead of an username (",[527,8916,8917],{"href":8917,"rel":8918},"https:\u002F\u002Fhub.docker.com\u002Fr\u002F_\u002Fwordpress\u002F",[531],[613,8920,8922],{"id":8921},"what-have-layer-cakes-to-do-with-docker-images","What have Layer Cakes to do with Docker Images?",[523,8924,8925],{},[3069,8926],{"alt":8927,"src":8928},"Layer Cake from Wikimedia","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Flayer-cake-from-wikimedia.png",[523,8930,8931,8934],{},[3049,8932,8933],{},"Mhh, tasty, isn't it?"," But now back to the topic.",[523,8936,8937,8939,8940],{},[584,8938,2951],{},": ",[527,8941,8944],{"href":8942,"rel":8943},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-docker\u002Ftree\u002Fmaster\u002Fdockerfile101",[531],[567,8945,8946],{},"dockerfile101",[523,8948,8949],{},"In the Docker universe, a Docker image is built from the bottom to the top like a cake, the bottom is a baseimage (or any other image as a base).\nEvery \"new\" layer on top of it, is an action that had been run when building the image.",[523,8951,8952,8953,8956,8957,8960],{},"Meaning if we create an image from the \"baseimage\" ",[567,8954,8955],{},"fedora:23"," like the example ",[567,8958,8959],{},"Dockerfile",", a cross-section\u002Fprofile would look like this:",[523,8962,8963],{},[3069,8964],{"alt":8965,"src":8966},"Docker Dockerfile Layers","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Fdocker-data-dockerfile-layers.png",[523,8968,8969,8970,8973],{},"That is one of the reasons, why Docker images are so small. If you download 10 images that are based on ",[567,8971,8972],{},"debian:jessie",", you would only have to download the created\u002Fmodified layers, because the baseimage is the same for these 10 images.\nTo build\u002Fcreate an image, you create a Dockerfile and that's what we are going to talk about next.",[613,8975,8977],{"id":8976},"dockerfile-examples","Dockerfile Examples",[523,8979,8980,8981,8984,8985,8987,8988,8990,8991,8993],{},"As you may have already seen in the task directory ",[567,8982,8983],{},"dockerfil101",", there was a file called ",[567,8986,8959],{},".\nA ",[567,8989,8959],{}," contains build instructions for an image. ",[567,8992,8959],{},"s use a \"special\" syntax. The syntax in itself is not too hard to understand but can be hard to read in more advanced use cases.\nI'm going to show you a simple and a more advanced example of Dockerfiles.",[3126,8995,8997],{"id":8996},"simple-real-world-dockerfile-example","\"Simple\" Real World Dockerfile Example",[523,8999,9000,9001,9006,9007,1909],{},"Taken from the ",[527,9002,9005],{"href":9003,"rel":9004},"https:\u002F\u002Fgithub.com\u002Fcarazzim0\u002Fdocker-ebot",[531],"carazzim0\u002Fdocker-ebot"," GitHub project, file ",[567,9008,8959],{},[738,9010,9014],{"className":9011,"code":9012,"language":9013,"meta":743,"style":743},"language-dockerfile shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","FROM docker.io\u002Flibrary\u002Fdebian:jessie\n\nENV EBOT_HOME=\"\u002Febot\" TIMEZONE=\"Europe\u002FBerlin\"\n\nCOPY entrypoint.sh \u002Fsbin\u002Fentrypoint.sh\n\nRUN apt-get update && \\\n    apt-get -y upgrade && \\\n    apt-get clean && \\\n    apt-get -y install nodejs npm curl git php5-cli php5-mysql screen git && \\\n    apt-get clean && \\\n    sed -i \"s~;date.timezone =~date.timezone = $TIMEZONE~g\" \u002Fetc\u002Fphp5\u002Fcli\u002Fphp.ini && \\\n    \u002Fbin\u002Fln -s \u002Fusr\u002Fbin\u002Fnodejs \u002Fusr\u002Fbin\u002Fnode && \\\n    curl -sS https:\u002F\u002Fgetcomposer.org\u002Finstaller | php -- --install-dir=\u002Fusr\u002Fbin && \\\n    mkdir \"$EBOT_HOME\" && \\\n    git clone https:\u002F\u002Fgithub.com\u002FdeStrO\u002FeBot-CSGO.git \"$EBOT_HOME\" && \\\n    cd \"$EBOT_HOME\" && \\\n    git checkout \"master\" && \\\n    \u002Fusr\u002Fbin\u002Fphp \u002Fusr\u002Fbin\u002Fcomposer.phar install && \\\n    npm install socket.io formidable archiver\n\nCOPY Match.php $EBOT_HOME\u002Fsrc\u002FeBot\u002FMatch\u002FMatch.php\n\nVOLUME [\"$EBOT_HOME\u002Fdemos\", \"$EBOT_HOME\u002Flogs\"]\n\nEXPOSE 12360 12361\n\nENTRYPOINT [\"\u002Fsbin\u002Fentrypoint.sh\"]\n","dockerfile",[567,9015,9016,9024,9028,9045,9049,9057,9061,9069,9074,9079,9084,9088,9099,9104,9109,9120,9129,9138,9148,9153,9158,9162,9169,9173,9190,9194,9202,9206],{"__ignoreMap":743},[747,9017,9018,9021],{"class":749,"line":750},[747,9019,9020],{"class":1895},"FROM",[747,9022,9023],{"class":1640}," docker.io\u002Flibrary\u002Fdebian:jessie\n",[747,9025,9026],{"class":749,"line":761},[747,9027,1255],{"emptyLinePlaceholder":1254},[747,9029,9030,9033,9036,9039,9042],{"class":749,"line":769},[747,9031,9032],{"class":1895},"ENV",[747,9034,9035],{"class":1640}," EBOT_HOME=",[747,9037,9038],{"class":802},"\"\u002Febot\"",[747,9040,9041],{"class":1640}," TIMEZONE=",[747,9043,9044],{"class":802},"\"Europe\u002FBerlin\"\n",[747,9046,9047],{"class":749,"line":776},[747,9048,1255],{"emptyLinePlaceholder":1254},[747,9050,9051,9054],{"class":749,"line":784},[747,9052,9053],{"class":1895},"COPY",[747,9055,9056],{"class":1640}," entrypoint.sh \u002Fsbin\u002Fentrypoint.sh\n",[747,9058,9059],{"class":749,"line":790},[747,9060,1255],{"emptyLinePlaceholder":1254},[747,9062,9063,9066],{"class":749,"line":796},[747,9064,9065],{"class":1895},"RUN",[747,9067,9068],{"class":1640}," apt-get update && \\\n",[747,9070,9071],{"class":749,"line":806},[747,9072,9073],{"class":1640},"    apt-get -y upgrade && \\\n",[747,9075,9076],{"class":749,"line":814},[747,9077,9078],{"class":1640},"    apt-get clean && \\\n",[747,9080,9081],{"class":749,"line":822},[747,9082,9083],{"class":1640},"    apt-get -y install nodejs npm curl git php5-cli php5-mysql screen git && \\\n",[747,9085,9086],{"class":749,"line":830},[747,9087,9078],{"class":1640},[747,9089,9090,9093,9096],{"class":749,"line":836},[747,9091,9092],{"class":1640},"    sed -i ",[747,9094,9095],{"class":802},"\"s~;date.timezone =~date.timezone = $TIMEZONE~g\"",[747,9097,9098],{"class":1640}," \u002Fetc\u002Fphp5\u002Fcli\u002Fphp.ini && \\\n",[747,9100,9101],{"class":749,"line":842},[747,9102,9103],{"class":1640},"    \u002Fbin\u002Fln -s \u002Fusr\u002Fbin\u002Fnodejs \u002Fusr\u002Fbin\u002Fnode && \\\n",[747,9105,9106],{"class":749,"line":850},[747,9107,9108],{"class":1640},"    curl -sS https:\u002F\u002Fgetcomposer.org\u002Finstaller | php -- --install-dir=\u002Fusr\u002Fbin && \\\n",[747,9110,9111,9114,9117],{"class":749,"line":863},[747,9112,9113],{"class":1640},"    mkdir ",[747,9115,9116],{"class":802},"\"$EBOT_HOME\"",[747,9118,9119],{"class":1640}," && \\\n",[747,9121,9122,9125,9127],{"class":749,"line":869},[747,9123,9124],{"class":1640},"    git clone https:\u002F\u002Fgithub.com\u002FdeStrO\u002FeBot-CSGO.git ",[747,9126,9116],{"class":802},[747,9128,9119],{"class":1640},[747,9130,9131,9134,9136],{"class":749,"line":877},[747,9132,9133],{"class":1640},"    cd ",[747,9135,9116],{"class":802},[747,9137,9119],{"class":1640},[747,9139,9140,9143,9146],{"class":749,"line":1015},[747,9141,9142],{"class":1640},"    git checkout ",[747,9144,9145],{"class":802},"\"master\"",[747,9147,9119],{"class":1640},[747,9149,9150],{"class":749,"line":1021},[747,9151,9152],{"class":1640},"    \u002Fusr\u002Fbin\u002Fphp \u002Fusr\u002Fbin\u002Fcomposer.phar install && \\\n",[747,9154,9155],{"class":749,"line":1027},[747,9156,9157],{"class":1640},"    npm install socket.io formidable archiver\n",[747,9159,9160],{"class":749,"line":1033},[747,9161,1255],{"emptyLinePlaceholder":1254},[747,9163,9164,9166],{"class":749,"line":1039},[747,9165,9053],{"class":1895},[747,9167,9168],{"class":1640}," Match.php $EBOT_HOME\u002Fsrc\u002FeBot\u002FMatch\u002FMatch.php\n",[747,9170,9171],{"class":749,"line":1054},[747,9172,1255],{"emptyLinePlaceholder":1254},[747,9174,9175,9178,9180,9183,9185,9188],{"class":749,"line":1060},[747,9176,9177],{"class":1895},"VOLUME",[747,9179,4262],{"class":1640},[747,9181,9182],{"class":802},"\"$EBOT_HOME\u002Fdemos\"",[747,9184,714],{"class":1640},[747,9186,9187],{"class":802},"\"$EBOT_HOME\u002Flogs\"",[747,9189,4268],{"class":1640},[747,9191,9192],{"class":749,"line":1066},[747,9193,1255],{"emptyLinePlaceholder":1254},[747,9195,9196,9199],{"class":749,"line":1081},[747,9197,9198],{"class":1895},"EXPOSE",[747,9200,9201],{"class":1640}," 12360 12361\n",[747,9203,9204],{"class":749,"line":1087},[747,9205,1255],{"emptyLinePlaceholder":1254},[747,9207,9208,9211,9213,9216],{"class":749,"line":1102},[747,9209,9210],{"class":1895},"ENTRYPOINT",[747,9212,4262],{"class":1640},[747,9214,9215],{"class":802},"\"\u002Fsbin\u002Fentrypoint.sh\"",[747,9217,4268],{"class":1640},[3126,9219,9221],{"id":9220},"advanced-dockerfile-example","Advanced Dockerfile Example",[523,9223,9224,9225,9006,9230,1909],{},"Old copy from my previous ",[527,9226,9229],{"href":9227,"rel":9228},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fdocker-zulip",[531],"galexrt\u002Fdocker-zulip",[567,9231,8959],{},[738,9233,9235],{"className":9011,"code":9234,"language":9013,"meta":743,"style":743},"FROM quay.io\u002Fsameersbn\u002Fubuntu:latest\n\nENV ZULIP_VERSION=\"master\" DATA_DIR=\"\u002Fdata\"\n\nCOPY entrypoint.sh \u002Fsbin\u002Fentrypoint.sh\n\nRUN apt-get -q update && \\\n    apt-get -q dist-upgrade -y && \\\n    apt-get install -y git && \\\n    mkdir -p \"$DATA_DIR\" \u002Froot\u002Fzulip && \\\n    git clone https:\u002F\u002Fgithub.com\u002Fzulip\u002Fzulip.git \u002Froot\u002Fzulip && \\\n    cd \u002Froot\u002Fzulip && \\\n    git checkout \"$ZULIP_VERSION\" && \\\n    rm -rf \u002Froot\u002Fzulip\u002F.git\n\nCOPY custom_zulip_files\u002F \u002Froot\u002Fcustom_zulip\n\nRUN cp -rf \u002Froot\u002Fcustom_zulip\u002F* \u002Froot\u002Fzulip && \\\n    VOYAGER_CLASS=\"dockervoyager\" DEPLOYMENT_TYPE=\"dockervoyager\" ADDITIONAL_PACKAGES=\"python-dev python-six python-pbs\" \\\n    \u002Froot\u002Fzulip\u002Fscripts\u002Fsetup\u002Finstall && \\\n    wget -q https:\u002F\u002Fwww.zulip.com\u002Fdist\u002Freleases\u002Fzulip-server-latest.tar.gz -O \u002Ftmp\u002Fzulip-server.tar.gz && \\\n    tar xfz \u002Ftmp\u002Fzulip-server.tar.gz -C \"\u002Fhome\u002Fzulip\u002Fprod-static\" --strip-components=3 --wildcards *\u002Fprod-static\u002Fserve && \\\n    rm -rf \u002Ftmp\u002Fzulip-server.tar.gz && \\\n    ln -nsf \u002Fhome\u002Fzulip\u002Fdeployments\u002Fcurrent\u002Fprod-static\u002Fserve \u002Fhome\u002Fzulip\u002Fprod-static && \\\n    apt-get -qq autoremove --purge -y && \\\n    apt-get -qq clean && \\\n    rm -rf \u002Froot\u002Fzulip\u002Fpuppet\u002F \u002Fvar\u002Flib\u002Fapt\u002Flists\u002F* \u002Ftmp\u002F* \u002Fvar\u002Ftmp\u002F*\n\nCOPY setup_files\u002F \u002Fopt\u002Ffiles\nCOPY includes\u002Fsupervisor\u002Fconf.d\u002Fzulip_postsetup.conf \u002Fetc\u002Fsupervisor\u002Fconf.d\u002Fzulip_postsetup.conf\nCOPY includes\u002FcreateZulipAdmin.sh \u002FcreateZulipAdmin.sh\n\nVOLUME [\"$DATA_DIR\"]\nEXPOSE 80 443\n\nENTRYPOINT [\"\u002Fsbin\u002Fentrypoint.sh\"]\nCMD [\"app:run\"]\n",[567,9236,9237,9244,9248,9263,9267,9273,9277,9284,9289,9294,9305,9310,9315,9324,9329,9333,9340,9344,9351,9372,9377,9382,9393,9398,9403,9408,9413,9418,9422,9429,9436,9443,9447,9457,9464,9468,9478],{"__ignoreMap":743},[747,9238,9239,9241],{"class":749,"line":750},[747,9240,9020],{"class":1895},[747,9242,9243],{"class":1640}," quay.io\u002Fsameersbn\u002Fubuntu:latest\n",[747,9245,9246],{"class":749,"line":761},[747,9247,1255],{"emptyLinePlaceholder":1254},[747,9249,9250,9252,9255,9257,9260],{"class":749,"line":769},[747,9251,9032],{"class":1895},[747,9253,9254],{"class":1640}," ZULIP_VERSION=",[747,9256,9145],{"class":802},[747,9258,9259],{"class":1640}," DATA_DIR=",[747,9261,9262],{"class":802},"\"\u002Fdata\"\n",[747,9264,9265],{"class":749,"line":776},[747,9266,1255],{"emptyLinePlaceholder":1254},[747,9268,9269,9271],{"class":749,"line":784},[747,9270,9053],{"class":1895},[747,9272,9056],{"class":1640},[747,9274,9275],{"class":749,"line":790},[747,9276,1255],{"emptyLinePlaceholder":1254},[747,9278,9279,9281],{"class":749,"line":796},[747,9280,9065],{"class":1895},[747,9282,9283],{"class":1640}," apt-get -q update && \\\n",[747,9285,9286],{"class":749,"line":806},[747,9287,9288],{"class":1640},"    apt-get -q dist-upgrade -y && \\\n",[747,9290,9291],{"class":749,"line":814},[747,9292,9293],{"class":1640},"    apt-get install -y git && \\\n",[747,9295,9296,9299,9302],{"class":749,"line":822},[747,9297,9298],{"class":1640},"    mkdir -p ",[747,9300,9301],{"class":802},"\"$DATA_DIR\"",[747,9303,9304],{"class":1640}," \u002Froot\u002Fzulip && \\\n",[747,9306,9307],{"class":749,"line":830},[747,9308,9309],{"class":1640},"    git clone https:\u002F\u002Fgithub.com\u002Fzulip\u002Fzulip.git \u002Froot\u002Fzulip && \\\n",[747,9311,9312],{"class":749,"line":836},[747,9313,9314],{"class":1640},"    cd \u002Froot\u002Fzulip && \\\n",[747,9316,9317,9319,9322],{"class":749,"line":842},[747,9318,9142],{"class":1640},[747,9320,9321],{"class":802},"\"$ZULIP_VERSION\"",[747,9323,9119],{"class":1640},[747,9325,9326],{"class":749,"line":850},[747,9327,9328],{"class":1640},"    rm -rf \u002Froot\u002Fzulip\u002F.git\n",[747,9330,9331],{"class":749,"line":863},[747,9332,1255],{"emptyLinePlaceholder":1254},[747,9334,9335,9337],{"class":749,"line":869},[747,9336,9053],{"class":1895},[747,9338,9339],{"class":1640}," custom_zulip_files\u002F \u002Froot\u002Fcustom_zulip\n",[747,9341,9342],{"class":749,"line":877},[747,9343,1255],{"emptyLinePlaceholder":1254},[747,9345,9346,9348],{"class":749,"line":1015},[747,9347,9065],{"class":1895},[747,9349,9350],{"class":1640}," cp -rf \u002Froot\u002Fcustom_zulip\u002F* \u002Froot\u002Fzulip && \\\n",[747,9352,9353,9356,9359,9362,9364,9367,9370],{"class":749,"line":1021},[747,9354,9355],{"class":1640},"    VOYAGER_CLASS=",[747,9357,9358],{"class":802},"\"dockervoyager\"",[747,9360,9361],{"class":1640}," DEPLOYMENT_TYPE=",[747,9363,9358],{"class":802},[747,9365,9366],{"class":1640}," ADDITIONAL_PACKAGES=",[747,9368,9369],{"class":802},"\"python-dev python-six python-pbs\"",[747,9371,1641],{"class":1640},[747,9373,9374],{"class":749,"line":1027},[747,9375,9376],{"class":1640},"    \u002Froot\u002Fzulip\u002Fscripts\u002Fsetup\u002Finstall && \\\n",[747,9378,9379],{"class":749,"line":1033},[747,9380,9381],{"class":1640},"    wget -q https:\u002F\u002Fwww.zulip.com\u002Fdist\u002Freleases\u002Fzulip-server-latest.tar.gz -O \u002Ftmp\u002Fzulip-server.tar.gz && \\\n",[747,9383,9384,9387,9390],{"class":749,"line":1039},[747,9385,9386],{"class":1640},"    tar xfz \u002Ftmp\u002Fzulip-server.tar.gz -C ",[747,9388,9389],{"class":802},"\"\u002Fhome\u002Fzulip\u002Fprod-static\"",[747,9391,9392],{"class":1640}," --strip-components=3 --wildcards *\u002Fprod-static\u002Fserve && \\\n",[747,9394,9395],{"class":749,"line":1054},[747,9396,9397],{"class":1640},"    rm -rf \u002Ftmp\u002Fzulip-server.tar.gz && \\\n",[747,9399,9400],{"class":749,"line":1060},[747,9401,9402],{"class":1640},"    ln -nsf \u002Fhome\u002Fzulip\u002Fdeployments\u002Fcurrent\u002Fprod-static\u002Fserve \u002Fhome\u002Fzulip\u002Fprod-static && \\\n",[747,9404,9405],{"class":749,"line":1066},[747,9406,9407],{"class":1640},"    apt-get -qq autoremove --purge -y && \\\n",[747,9409,9410],{"class":749,"line":1081},[747,9411,9412],{"class":1640},"    apt-get -qq clean && \\\n",[747,9414,9415],{"class":749,"line":1087},[747,9416,9417],{"class":1640},"    rm -rf \u002Froot\u002Fzulip\u002Fpuppet\u002F \u002Fvar\u002Flib\u002Fapt\u002Flists\u002F* \u002Ftmp\u002F* \u002Fvar\u002Ftmp\u002F*\n",[747,9419,9420],{"class":749,"line":1102},[747,9421,1255],{"emptyLinePlaceholder":1254},[747,9423,9424,9426],{"class":749,"line":1110},[747,9425,9053],{"class":1895},[747,9427,9428],{"class":1640}," setup_files\u002F \u002Fopt\u002Ffiles\n",[747,9430,9431,9433],{"class":749,"line":1117},[747,9432,9053],{"class":1895},[747,9434,9435],{"class":1640}," includes\u002Fsupervisor\u002Fconf.d\u002Fzulip_postsetup.conf \u002Fetc\u002Fsupervisor\u002Fconf.d\u002Fzulip_postsetup.conf\n",[747,9437,9438,9440],{"class":749,"line":1123},[747,9439,9053],{"class":1895},[747,9441,9442],{"class":1640}," includes\u002FcreateZulipAdmin.sh \u002FcreateZulipAdmin.sh\n",[747,9444,9445],{"class":749,"line":1129},[747,9446,1255],{"emptyLinePlaceholder":1254},[747,9448,9449,9451,9453,9455],{"class":749,"line":1142},[747,9450,9177],{"class":1895},[747,9452,4262],{"class":1640},[747,9454,9301],{"class":802},[747,9456,4268],{"class":1640},[747,9458,9459,9461],{"class":749,"line":1150},[747,9460,9198],{"class":1895},[747,9462,9463],{"class":1640}," 80 443\n",[747,9465,9466],{"class":749,"line":1157},[747,9467,1255],{"emptyLinePlaceholder":1254},[747,9469,9470,9472,9474,9476],{"class":749,"line":1163},[747,9471,9210],{"class":1895},[747,9473,4262],{"class":1640},[747,9475,9215],{"class":802},[747,9477,4268],{"class":1640},[747,9479,9480,9483,9485,9488],{"class":749,"line":1168},[747,9481,9482],{"class":1895},"CMD",[747,9484,4262],{"class":1640},[747,9486,9487],{"class":802},"\"app:run\"",[747,9489,4268],{"class":1640},[523,9491,9492,9495],{},[3049,9493,9494],{},"Don't worry"," we're going to start with a simple and basic image to learn everything we need to know. ;)",[613,9497,9499],{"id":9498},"understanding-dockerfiles","Understanding Dockerfiles",[523,9501,9502,8939,9504],{},[584,9503,2951],{},[527,9505,9508],{"href":9506,"rel":9507},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-docker\u002Ftree\u002Fmaster\u002Fdockerfile202",[531],[567,9509,9510],{},"dockerfile202",[523,9512,9513,9516,9517,9519,9520,1909],{},[584,9514,9515],{},"TIP",": If you have trouble writing a ",[567,9518,8959],{},", checkout the ",[527,9521,9524],{"href":9522,"rel":9523},"https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Freference\u002Fbuilder\u002F",[531],"Dockerfile reference Docs",[523,9526,9527,9528,9531],{},"You will create an image with ",[567,9529,9530],{},"nginx"," installed (You can later expand it, with more functionality, like with PHP-FPM).",[523,9533,9534,9535,9537],{},"To guide you in creating a nginx image, I show you an example of a http webserver application written in golang, before you are going to create your own ",[567,9536,9530],{}," image.",[523,9539,9540,856],{},[584,9541,9542],{},"Golang Dockerfile Example",[738,9544,9546],{"className":9011,"code":9545,"language":9013,"meta":743,"style":743},"# Official golang image where the \"workspace\" (GOPATH) is configured to be at `\u002Fgo`\nFROM docker.io\u002Flibrary\u002Fgolang:1.22.7\n# Set the working directory\nWORKDIR \u002Fusr\u002Fsrc\u002Fapp\n# Copy the code into the container\nCOPY . .\u002F\n# Build the code inside the container\nRUN go build .\n# Specify the entrypoint of the container\nENTRYPOINT [\"\u002Fusr\u002Fsrc\u002Fapp\u002Fdockerfile202\"]\n\n# HTTP server listens on tcp port 8080.\nEXPOSE 8080\n",[567,9547,9548,9553,9560,9565,9573,9578,9585,9590,9597,9602,9613,9617,9622],{"__ignoreMap":743},[747,9549,9550],{"class":749,"line":750},[747,9551,9552],{"class":772},"# Official golang image where the \"workspace\" (GOPATH) is configured to be at `\u002Fgo`\n",[747,9554,9555,9557],{"class":749,"line":761},[747,9556,9020],{"class":1895},[747,9558,9559],{"class":1640}," docker.io\u002Flibrary\u002Fgolang:1.22.7\n",[747,9561,9562],{"class":749,"line":769},[747,9563,9564],{"class":772},"# Set the working directory\n",[747,9566,9567,9570],{"class":749,"line":776},[747,9568,9569],{"class":1895},"WORKDIR",[747,9571,9572],{"class":1640}," \u002Fusr\u002Fsrc\u002Fapp\n",[747,9574,9575],{"class":749,"line":784},[747,9576,9577],{"class":772},"# Copy the code into the container\n",[747,9579,9580,9582],{"class":749,"line":790},[747,9581,9053],{"class":1895},[747,9583,9584],{"class":1640}," . .\u002F\n",[747,9586,9587],{"class":749,"line":796},[747,9588,9589],{"class":772},"# Build the code inside the container\n",[747,9591,9592,9594],{"class":749,"line":806},[747,9593,9065],{"class":1895},[747,9595,9596],{"class":1640}," go build .\n",[747,9598,9599],{"class":749,"line":814},[747,9600,9601],{"class":772},"# Specify the entrypoint of the container\n",[747,9603,9604,9606,9608,9611],{"class":749,"line":822},[747,9605,9210],{"class":1895},[747,9607,4262],{"class":1640},[747,9609,9610],{"class":802},"\"\u002Fusr\u002Fsrc\u002Fapp\u002Fdockerfile202\"",[747,9612,4268],{"class":1640},[747,9614,9615],{"class":749,"line":830},[747,9616,1255],{"emptyLinePlaceholder":1254},[747,9618,9619],{"class":749,"line":836},[747,9620,9621],{"class":772},"# HTTP server listens on tcp port 8080.\n",[747,9623,9624,9626],{"class":749,"line":842},[747,9625,9198],{"class":1895},[747,9627,9628],{"class":1640}," 8080\n",[523,9630,9631,856],{},[584,9632,2957],{},[668,9634,9635,9641,9647,9671,9680,9686,9695],{},[638,9636,9637,9640],{},[567,9638,9639],{},"FROM ..."," - Use an image as the base.",[638,9642,9643,9646],{},[567,9644,9645],{},"COPY ... ..."," - Copy files from the build root.",[638,9648,9649,9652,9653,9655,9656,9661,9662],{},[567,9650,9651],{},"ADD ... ..."," - Same as ",[567,9654,9053],{},", but target can be \"online\" (e.g., an URL) and if it is an archive, it will be extracted. This has it's up and downsides, please make sure to check, e.g., to gain a deeper understanding of ",[527,9657,9660],{"href":9658,"rel":9659},"https:\u002F\u002Fphoenixnap.com\u002Fkb\u002Fdocker-add-vs-copy",[531],"the differences",".\n",[668,9663,9664],{},[638,9665,9666,9667,9670],{},"To quote the blog article from \"phoenixnap.com\": \"The ",[567,9668,9669],{},"ADD"," command use is discouraged for all cases except when the user wants to extract a local compressed file. For copying remote files, the run command combined with wget or curl is safer and more efficient. This method avoids creating an additional image layer and saves space.\"",[638,9672,9673,9676,9677,3052],{},[567,9674,9675],{},"RUN ..."," - Run commands (Shell used ",[567,9678,9679],{},"\u002Fbin\u002Fsh",[638,9681,9682,9685],{},[567,9683,9684],{},"ENTRYPOINT [\"...\"]"," - The command to execute when the container is started.",[638,9687,9688,9691,9692,9694],{},[567,9689,9690],{},"CMD [\"...\"]"," - Arguments for the ",[567,9693,9210],{},", most images will execute .",[638,9696,9697,9700,9701,6374,9704,9707],{},[567,9698,9699],{},"EXPOSE 8080 ..."," - Expose a port when linked. To specify the protocol just add ",[567,9702,9703],{},"\u002Ftcp",[567,9705,9706],{},"\u002Fudp"," at the end of the port number.",[523,9709,9710,9711,9714],{},"There's even the possibility, to execute specific commands when the image is used as a base image, the base instruction is called ",[567,9712,9713],{},"ONBUILD ...",", but explaining this is beyond the scope at this time.",[523,9716,9717,9718,9721],{},"To build an image we use the ",[567,9719,9720],{},"docker build"," command. Building this golang example image, we run the following command:",[738,9723,9725],{"className":1621,"code":9724,"language":1623,"meta":743,"style":743},"docker build -t dockerfile202 -f Dockerfile .\n",[567,9726,9727],{"__ignoreMap":743},[747,9728,9729,9731,9734,9737,9740,9742,9745],{"class":749,"line":750},[747,9730,3257],{"class":1630},[747,9732,9733],{"class":802}," build",[747,9735,9736],{"class":802}," -t",[747,9738,9739],{"class":802}," dockerfile202",[747,9741,1934],{"class":802},[747,9743,9744],{"class":802}," Dockerfile",[747,9746,9747],{"class":802}," .\n",[523,9749,9750,856],{},[584,9751,2957],{},[668,9753,9754,9760,9775,9784],{},[638,9755,9756,9759],{},[567,9757,9758],{},"build"," - Used to build Docker images.",[638,9761,9762,9765,9766,9768,9769,9771,9772,1909],{},[567,9763,9764],{},"-t IMAGE_NAME"," - Specify the name (with an optional tag) of the image, you are creating (Optional. ",[584,9767,6189],{}," This options is important when manually building and pushing a Docker image to a repository). ",[567,9770,8898],{}," is a string name for the image with an optional tag specified. The tag is added by adding double dots like this ",[567,9773,9774],{},":TAG_NAME",[638,9776,9777,9780,9781,9783],{},[567,9778,9779],{},"-f DOCKERFILE"," - Set the location of the ",[567,9782,8959],{}," (Optional).",[638,9785,9786,9788,9789,9792,9793,6374,9795,9797,9798,9800],{},[567,9787,1909],{}," - The image build root of the image build (",[584,9790,9791],{},"Important"," when ",[567,9794,9669],{},[567,9796,9053],{}," is used in the ",[567,9799,8959],{},"). All files will be at least added to the build environment for easy access, but not added to the image itself.",[523,9802,9803],{},"As you can see, it isn't that hard to build an application inside a container.",[597,9805,9806],{},[523,9807,9808,9809,1909],{},"If you want to see more advanced examples of Dockerfiles, you can find more examples in my GitHub repositories ",[527,9810,3396],{"href":9811,"rel":9812},"https:\u002F\u002Fgithub.com\u002Fsearch?q=user%3AGalexrt+container-",[531],[523,9814,9815],{},"Let's run the container and check that it is working:",[738,9817,9819],{"className":1621,"code":9818,"language":1623,"meta":743,"style":743},"docker run \\\n    -d \\\n    --name=dockerfile202 \\\n    -p 8080:8080 \\\n    dockerfile202\n",[567,9820,9821,9829,9835,9842,9851],{"__ignoreMap":743},[747,9822,9823,9825,9827],{"class":749,"line":750},[747,9824,3257],{"class":1630},[747,9826,3665],{"class":802},[747,9828,1641],{"class":1640},[747,9830,9831,9833],{"class":749,"line":761},[747,9832,5866],{"class":802},[747,9834,1641],{"class":1640},[747,9836,9837,9840],{"class":749,"line":769},[747,9838,9839],{"class":802},"    --name=dockerfile202",[747,9841,1641],{"class":1640},[747,9843,9844,9846,9849],{"class":749,"line":776},[747,9845,6614],{"class":802},[747,9847,9848],{"class":802}," 8080:8080",[747,9850,1641],{"class":1640},[747,9852,9853],{"class":749,"line":784},[747,9854,9855],{"class":802},"    dockerfile202\n",[523,9857,9858,9859,9863],{},"Open your browser and go to ",[527,9860,9861],{"href":9861,"rel":9862},"http:\u002F\u002Flocalhost:8080\u002Fhello",[531],".\nYou should see a basic page with the text on it:",[6072,9865,9866],{},[523,9867,9868],{},"Hello Gopher\nI am a simple application that displays this web page built inside a container.",[523,9870,9871,9872,1909],{},"To stop the container run ",[567,9873,9874],{},"docker stop dockerfile202",[3126,9876,9878],{"id":9877},"multi-layered-madness","Multi-Layered Madness",[523,9880,9881,8939,9883],{},[584,9882,2951],{},[527,9884,9887],{"href":9885,"rel":9886},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-docker\u002Ftree\u002Fmaster\u002Fdockerfile303",[531],[567,9888,9889],{},"dockerfile303",[523,9891,9892,9893,9895],{},"For security and cleanliness of the build environment one can use multi-layer builds to build the application in a container and copy the output into the \"end\u002Ffinal image\" produced by the ",[567,9894,8959],{},".\nTo improve the previous example of a Golang application, one could rewrite the Dockerfile to be like this:",[738,9897,9899],{"className":9011,"code":9898,"language":9013,"meta":743,"style":743},"# This is the first \"image\" we use and name it \"builder\"\nFROM docker.io\u002Flibrary\u002Fgolang:1.22.7-alpine3.20 AS builder\n# Set the working directory\nWORKDIR \u002Fusr\u002Fsrc\u002Fapp\n# Copy the code into the container\nCOPY . .\u002F\n# Build the code inside the container\nRUN go build .\n\n# This would be \"final\" image\nFROM docker.io\u002Flibrary\u002Falpine:3.20.3\nWORKDIR \u002Fapp\n# Copy the built binary from the builder image inside the \"final\" image\nCOPY --from=builder \u002Fusr\u002Fsrc\u002Fapp\u002Fdockerfile303 \u002Fusr\u002Flocal\u002Fbin\u002F\n# Specify the entrypoint of the container\nENTRYPOINT [\"\u002Fusr\u002Flocal\u002Fbin\u002Fdockerfile303\"]\n\n# HTTP server listens on tcp port 8080.\nEXPOSE 8080\n",[567,9900,9901,9906,9919,9923,9929,9933,9939,9943,9949,9953,9958,9965,9972,9977,9984,9988,9999,10003,10007],{"__ignoreMap":743},[747,9902,9903],{"class":749,"line":750},[747,9904,9905],{"class":772},"# This is the first \"image\" we use and name it \"builder\"\n",[747,9907,9908,9910,9913,9916],{"class":749,"line":761},[747,9909,9020],{"class":1895},[747,9911,9912],{"class":1640}," docker.io\u002Flibrary\u002Fgolang:1.22.7-alpine3.20 ",[747,9914,9915],{"class":1895},"AS",[747,9917,9918],{"class":1640}," builder\n",[747,9920,9921],{"class":749,"line":769},[747,9922,9564],{"class":772},[747,9924,9925,9927],{"class":749,"line":776},[747,9926,9569],{"class":1895},[747,9928,9572],{"class":1640},[747,9930,9931],{"class":749,"line":784},[747,9932,9577],{"class":772},[747,9934,9935,9937],{"class":749,"line":790},[747,9936,9053],{"class":1895},[747,9938,9584],{"class":1640},[747,9940,9941],{"class":749,"line":796},[747,9942,9589],{"class":772},[747,9944,9945,9947],{"class":749,"line":806},[747,9946,9065],{"class":1895},[747,9948,9596],{"class":1640},[747,9950,9951],{"class":749,"line":814},[747,9952,1255],{"emptyLinePlaceholder":1254},[747,9954,9955],{"class":749,"line":822},[747,9956,9957],{"class":772},"# This would be \"final\" image\n",[747,9959,9960,9962],{"class":749,"line":830},[747,9961,9020],{"class":1895},[747,9963,9964],{"class":1640}," docker.io\u002Flibrary\u002Falpine:3.20.3\n",[747,9966,9967,9969],{"class":749,"line":836},[747,9968,9569],{"class":1895},[747,9970,9971],{"class":1640}," \u002Fapp\n",[747,9973,9974],{"class":749,"line":842},[747,9975,9976],{"class":772},"# Copy the built binary from the builder image inside the \"final\" image\n",[747,9978,9979,9981],{"class":749,"line":850},[747,9980,9053],{"class":1895},[747,9982,9983],{"class":1640}," --from=builder \u002Fusr\u002Fsrc\u002Fapp\u002Fdockerfile303 \u002Fusr\u002Flocal\u002Fbin\u002F\n",[747,9985,9986],{"class":749,"line":863},[747,9987,9601],{"class":772},[747,9989,9990,9992,9994,9997],{"class":749,"line":869},[747,9991,9210],{"class":1895},[747,9993,4262],{"class":1640},[747,9995,9996],{"class":802},"\"\u002Fusr\u002Flocal\u002Fbin\u002Fdockerfile303\"",[747,9998,4268],{"class":1640},[747,10000,10001],{"class":749,"line":877},[747,10002,1255],{"emptyLinePlaceholder":1254},[747,10004,10005],{"class":749,"line":1015},[747,10006,9621],{"class":772},[747,10008,10009,10011],{"class":749,"line":1021},[747,10010,9198],{"class":1895},[747,10012,9628],{"class":1640},[523,10014,10015,856],{},[584,10016,2957],{},[668,10018,10019,10025],{},[638,10020,10021,10024],{},[567,10022,10023],{},"FROM ... AS __NAME__"," - Use an image as the base and give it a name. Giving it a name is optional but recommended for readability and especially for multi-layered container builds.",[638,10026,10027,10030],{},[567,10028,10029],{},"COPY --from=__NAME__ SRC DEST"," - Copy a file from",[523,10032,10033,10034,10036],{},"Again to build the image we use the ",[567,10035,9720],{}," command. Building this multi-layered golang example image:",[738,10038,10040],{"className":1621,"code":10039,"language":1623,"meta":743,"style":743},"docker build -t dockerfile303 -f Dockerfile .\n",[567,10041,10042],{"__ignoreMap":743},[747,10043,10044,10046,10048,10050,10053,10055,10057],{"class":749,"line":750},[747,10045,3257],{"class":1630},[747,10047,9733],{"class":802},[747,10049,9736],{"class":802},[747,10051,10052],{"class":802}," dockerfile303",[747,10054,1934],{"class":802},[747,10056,9744],{"class":802},[747,10058,9747],{"class":802},[523,10060,10061,10062,1909],{},"It should yield the same output as before, but let's look at the size of the container image.\nTo check the image size run ",[567,10063,10064],{},"docker images",[738,10066,10068],{"className":1621,"code":10067,"language":1623,"meta":743,"style":743},"$ docker images\n",[567,10069,10070],{"__ignoreMap":743},[747,10071,10072,10074,10076],{"class":749,"line":750},[747,10073,1919],{"class":1630},[747,10075,3246],{"class":802},[747,10077,10078],{"class":802}," images\n",[523,10080,10081],{},"This means that in case an attacker gains access to the container via an, e.g., exploit in the application code, the attacker would not have the whole Golang build and development tools available to them.",[523,10083,10084],{},"Let's run this container and check that it is working:",[738,10086,10088],{"className":1621,"code":10087,"language":1623,"meta":743,"style":743},"docker run \\\n    -d \\\n    --name=dockerfile303 \\\n    -p 8080:8080 \\\n    dockerfile303\n",[567,10089,10090,10098,10104,10111,10119],{"__ignoreMap":743},[747,10091,10092,10094,10096],{"class":749,"line":750},[747,10093,3257],{"class":1630},[747,10095,3665],{"class":802},[747,10097,1641],{"class":1640},[747,10099,10100,10102],{"class":749,"line":761},[747,10101,5866],{"class":802},[747,10103,1641],{"class":1640},[747,10105,10106,10109],{"class":749,"line":769},[747,10107,10108],{"class":802},"    --name=dockerfile303",[747,10110,1641],{"class":1640},[747,10112,10113,10115,10117],{"class":749,"line":776},[747,10114,6614],{"class":802},[747,10116,9848],{"class":802},[747,10118,1641],{"class":1640},[747,10120,10121],{"class":749,"line":784},[747,10122,10123],{"class":802},"    dockerfile303\n",[523,10125,10126,10127,10130],{},"Open your browser again and go to ",[527,10128,9861],{"href":9861,"rel":10129},[531],".\nYou should see a basic page with a different text on it now:",[6072,10132,10133],{},[523,10134,10135],{},"Hello Gopher\nI am a multi layered built image.",[523,10137,9871,10138,1909],{},[567,10139,10140],{},"docker stop dockerfile303",[523,10142,10143,10144,10147,10148,10151],{},"To improve security even further, one might want to change the ",[567,10145,10146],{},"docker.io\u002Flibrary\u002Falpine"," base image of the \"final\" image to be ",[567,10149,10150],{},"scratch",", which we'll go into after we have tested our built image. This is something we'll talk about later further.",[3126,10153,10155,10156,10158],{"id":10154},"base-image-scratch-that","Base image: ",[567,10157,10150],{}," that!",[523,10160,8764,10161,10163],{},[567,10162,10150],{}," \"image\" can be used for creating minimal container images containing only the things that the application needs. In Golangs case, it is quite easy as the build result is just one binary (that can even be statically compiled).",[523,10165,10166],{},"For a more complex application, e.g., written using Java Springboot, I would recommend checking out the official documentation to see if there are recommendations available.",[523,10168,10169],{},"Especially for Springboot based applications, there is tooling available to easily package your application as a (minimal) container image.",[523,10171,10172,10173,10175,10176,1909],{},"For more information on the ",[567,10174,10150],{}," image check out ",[527,10177,10180],{"href":10178,"rel":10179},"https:\u002F\u002Fdocs.docker.com\u002Fbuild\u002Fbuilding\u002Fbase-images\u002F#create-a-base-image",[531],"the \"Create base image\" Docker docs",[613,10182,10184],{"id":10183},"commands-you-need-to-know-when-working-with-docker-images","Commands you need to know when working with Docker images",[3126,10186,10188],{"id":10187},"deleting-a-docker-image","Deleting a Docker image",[523,10190,10191,10192,10195,10196,10199],{},"To delete a Docker image, you use the ",[567,10193,10194],{},"docker rmi"," subcommand. The syntax is the same as for the ",[567,10197,10198],{},"docker rm"," subcommand.",[738,10201,10203],{"className":1621,"code":10202,"language":1623,"meta":743,"style":743},"docker rmi IMAGE [IMAGE...]\n",[567,10204,10205],{"__ignoreMap":743},[747,10206,10207,10209,10212,10215],{"class":749,"line":750},[747,10208,3257],{"class":1630},[747,10210,10211],{"class":802}," rmi",[747,10213,10214],{"class":802}," IMAGE",[747,10216,10217],{"class":1640}," [IMAGE...]\n",[523,10219,10220,856],{},[584,10221,2957],{},[668,10223,10224,10230],{},[638,10225,10226,10229],{},[567,10227,10228],{},"rmi"," - The subcommand for deleting one or more image(s).",[638,10231,10232,10235],{},[567,10233,10234],{},"IMAGE [IMAGE...]"," - One or more image names or IDs to delete.",[3126,10237,10239],{"id":10238},"build-a-docker-image-from-dockerfile","Build a Docker image from Dockerfile",[523,10241,10242],{},"Use this command to build images.",[738,10244,10246],{"className":1621,"code":10245,"language":1623,"meta":743,"style":743},"docker build -t IMAGE_NAME -f DOCKERFILE BUILD_PATH\n",[567,10247,10248],{"__ignoreMap":743},[747,10249,10250,10252,10254,10256,10259,10261,10264],{"class":749,"line":750},[747,10251,3257],{"class":1630},[747,10253,9733],{"class":802},[747,10255,9736],{"class":802},[747,10257,10258],{"class":802}," IMAGE_NAME",[747,10260,1934],{"class":802},[747,10262,10263],{"class":802}," DOCKERFILE",[747,10265,10266],{"class":802}," BUILD_PATH\n",[523,10268,10269,856],{},[584,10270,2957],{},[668,10272,10273,10278,10293,10302],{},[638,10274,10275,10277],{},[567,10276,9758],{}," - The build subcommand.",[638,10279,10280,10282,10283,10285,10286,10289,10290,10292],{},[567,10281,9764],{}," - More details to ",[567,10284,8898],{}," are going to be explained in a later section, ",[527,10287,3396],{"href":10288},"#image-names-explained"," or see above ",[584,10291,2957],{}," part.",[638,10294,10295,10298,10299,10301],{},[567,10296,10297],{},"DOCKERFILE"," - Path to a Dockerfile. Defaults to the current work directory with ",[567,10300,8959],{}," attached as a file name.",[638,10303,10304,10307,10308,10310,10311,10313,10314,10316,10317,10320,10321,10324],{},[567,10305,10306],{},"BUILD_PATH"," - The build root path. Files in the directory will be added to the Docker build environment, but not to the image itself. The files are only added when the specified Dockerfile has instructions to do so. You can't go higher than the ",[567,10309,10306],{}," (e.g., if the ",[567,10312,10306],{}," is ",[567,10315,1909],{}," (current directory ",[567,10318,10319],{},"\u002Fmy-project\u002F","), you can't access files that are in your home directory ",[567,10322,10323],{},"\u002Fhome\u002Fyour-name",")!",[613,10326,10328],{"id":10327},"lets-build-your-first-own-dockerfile","Let's build your first own Dockerfile",[523,10330,10331,10332,10334,10335,10337,10338,1909],{},"Now that we know some ",[567,10333,8959],{}," basics, we can start building our own ",[567,10336,9530],{}," image from the baseimage ",[567,10339,8972],{},[523,10341,10342,10343,10346,10347,7258],{},"Let's make this like a test in the school, replace all ",[567,10344,10345],{},"__BLANK__"," with the correct answer (Solutions are ",[527,10348,3396],{"href":10349},"#nginx-dockerfile",[738,10351,10353],{"className":9011,"code":10352,"language":9013,"meta":743,"style":743},"FROM __BLANK__\n\nRUN __BLANK__\n\nENTRYPOINT [\"__BLANK__\"]\n",[567,10354,10355,10362,10366,10372,10376],{"__ignoreMap":743},[747,10356,10357,10359],{"class":749,"line":750},[747,10358,9020],{"class":1895},[747,10360,10361],{"class":1640}," __BLANK__\n",[747,10363,10364],{"class":749,"line":761},[747,10365,1255],{"emptyLinePlaceholder":1254},[747,10367,10368,10370],{"class":749,"line":769},[747,10369,9065],{"class":1895},[747,10371,10361],{"class":1640},[747,10373,10374],{"class":749,"line":776},[747,10375,1255],{"emptyLinePlaceholder":1254},[747,10377,10378,10380,10382,10385],{"class":749,"line":784},[747,10379,9210],{"class":1895},[747,10381,4262],{"class":1640},[747,10383,10384],{"class":802},"\"__BLANK__\"",[747,10386,4268],{"class":1640},[523,10388,10389],{},"Got all blanks filled out? Good. Let's build the image:",[738,10391,10393],{"className":1621,"code":10392,"language":1623,"meta":743,"style":743},"docker build -t workshop-nginx .\n",[567,10394,10395],{"__ignoreMap":743},[747,10396,10397,10399,10401,10403,10406],{"class":749,"line":750},[747,10398,3257],{"class":1630},[747,10400,9733],{"class":802},[747,10402,9736],{"class":802},[747,10404,10405],{"class":802}," workshop-nginx",[747,10407,9747],{"class":802},[523,10409,10410],{},[584,10411,10412,10413],{},"Expected Output of ",[567,10414,10415],{},"docker build -t workshop-nginx .",[523,10417,10418],{},[3069,10419],{"alt":10420,"src":10421},"Docker Build workshop-nginx image","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Fdocker-build-nginx-image.png",[523,10423,10424,10425,856],{},"The build should go successfully, when you filled in the blanks correctly. Let's run the image to see if it is working, the container name will be ",[567,10426,10427],{},"workshop-nginx",[738,10429,10431],{"className":1621,"code":10430,"language":1623,"meta":743,"style":743},"docker run \\\n    --name workshop-nginx \\\n    -d \\\n    -p 80:80 \\\n    workshop-nginx\n",[567,10432,10433,10441,10449,10455,10463],{"__ignoreMap":743},[747,10434,10435,10437,10439],{"class":749,"line":750},[747,10436,3257],{"class":1630},[747,10438,3665],{"class":802},[747,10440,1641],{"class":1640},[747,10442,10443,10445,10447],{"class":749,"line":761},[747,10444,5790],{"class":802},[747,10446,10405],{"class":802},[747,10448,1641],{"class":1640},[747,10450,10451,10453],{"class":749,"line":769},[747,10452,5866],{"class":802},[747,10454,1641],{"class":1640},[747,10456,10457,10459,10461],{"class":749,"line":776},[747,10458,6614],{"class":802},[747,10460,6990],{"class":802},[747,10462,1641],{"class":1640},[747,10464,10465],{"class":749,"line":784},[747,10466,10467],{"class":802},"    workshop-nginx\n",[523,10469,10470,10471,10473],{},"If you did something wrong, remove the container using (where ",[567,10472,6446],{}," is a container ID or name):",[738,10475,10477],{"className":1621,"code":10476,"language":1623,"meta":743,"style":743},"docker rm CONTAINER_NAME\n",[567,10478,10479],{"__ignoreMap":743},[747,10480,10481,10483,10485],{"class":749,"line":750},[747,10482,3257],{"class":1630},[747,10484,5902],{"class":802},[747,10486,10487],{"class":802}," CONTAINER_NAME\n",[523,10489,10490,10491,1909],{},"To check if the container is running with your image, run ",[567,10492,5819],{},[523,10494,10495,856],{},[584,10496,2957],{},[668,10498,10499,10508],{},[638,10500,10501,10504,10505,10507],{},[567,10502,10503],{},"ps"," - Like the ",[567,10506,10503],{},"  command, but for the containers.",[638,10509,10510,10512],{},[567,10511,4164],{}," - Show all containers, whether their current state, without it showing only running containers.",[523,10514,10515,10516,10519],{},"You should see that the container you started, has exited.\nThere's a simple reason, why the container exited\u002Fstopped. When running a command as the entrypoint, it has to stay running, not fork to background. When the process forks to background, Docker will think the process has stopped and the container status will be set to ",[567,10517,10518],{},"exited"," with the last return code.",[523,10521,10522,10523,10525,10526,10529,10530,10532,10533,3052],{},"That's why we need to tell ",[567,10524,9530],{},", not to run as a daemon, not fork to background, with the following additional arguments ",[567,10527,10528],{},"\"-g\", \"daemon off;\""," (these arguments must be added to the ",[567,10531,9210],{}," line of the ",[567,10534,8959],{},[523,10536,10537,10538,10541,10542,10544,10545,10548,10549,10551],{},"So we could make a change to the ",[567,10539,10540],{},"nginx.conf",", overwrite ",[567,10543,10540],{}," with a custom one or ",[584,10546,10547],{},"just change"," the ",[567,10550,9210],{}," line to make it look like this:",[738,10553,10555],{"className":1621,"code":10554,"language":1623,"meta":743,"style":743},"ENTRYPOINT [\"nginx\", \"-g\", \"daemon off;\"]\n",[567,10556,10557],{"__ignoreMap":743},[747,10558,10559,10561,10563,10565,10567,10569,10571,10573,10576,10578,10581,10583,10586,10588],{"class":749,"line":750},[747,10560,9210],{"class":1630},[747,10562,4262],{"class":1640},[747,10564,3892],{"class":757},[747,10566,9530],{"class":802},[747,10568,3892],{"class":757},[747,10570,714],{"class":1640},[747,10572,3892],{"class":757},[747,10574,10575],{"class":802},"-g",[747,10577,3892],{"class":757},[747,10579,10580],{"class":802},",",[747,10582,969],{"class":757},[747,10584,10585],{"class":802},"daemon off;",[747,10587,3892],{"class":757},[747,10589,4268],{"class":802},[523,10591,10592,10593,10597],{},"Let's rebuild the image (same command) and run it again. Open ",[527,10594,10595],{"href":10595,"rel":10596},"http:\u002F\u002F127.0.0.1:8080",[531]," in your browser and voilà it should show the nginx default page.",[523,10599,10600,10601,10604,10605,8301,10607,10609],{},"To go further with your created image, let's \"mount\" a volume inside the container with our own ",[567,10602,10603],{},"index.html",".\nUse the ",[567,10606,10603],{},[567,10608,9510],{}," or create one yourself.",[523,10611,10612,10613,10616,10617,10619,10620,10623,10624,10626],{},"Now we add a volume to the container. Add ",[567,10614,10615],{},"-v \"$(pwd)\":\"\u002Fusr\u002Fshare\u002Fnginx\u002Fhtml\""," to the ",[567,10618,4203],{}," command, but don't forget add the argument ",[584,10621,10622],{},"before"," the image name (in this case the image is ",[567,10625,10427],{},").\nYour command should look like this:",[738,10628,10630],{"className":1621,"code":10629,"language":1623,"meta":743,"style":743},"docker run \\\n    --name workshop-nginx \\\n    -d \\\n    -p 8080:80 \\\n    -v \"$(pwd)\":\"\u002Fusr\u002Fshare\u002Fnginx\u002Fhtml\" \\\n    workshop-nginx\n",[567,10631,10632,10640,10648,10654,10663,10687],{"__ignoreMap":743},[747,10633,10634,10636,10638],{"class":749,"line":750},[747,10635,3257],{"class":1630},[747,10637,3665],{"class":802},[747,10639,1641],{"class":1640},[747,10641,10642,10644,10646],{"class":749,"line":761},[747,10643,5790],{"class":802},[747,10645,10405],{"class":802},[747,10647,1641],{"class":1640},[747,10649,10650,10652],{"class":749,"line":769},[747,10651,5866],{"class":802},[747,10653,1641],{"class":1640},[747,10655,10656,10658,10661],{"class":749,"line":776},[747,10657,6614],{"class":802},[747,10659,10660],{"class":802}," 8080:80",[747,10662,1641],{"class":1640},[747,10664,10665,10667,10670,10673,10676,10678,10680,10683,10685],{"class":749,"line":784},[747,10666,6139],{"class":802},[747,10668,10669],{"class":757}," \"$(",[747,10671,10672],{"class":4574},"pwd",[747,10674,10675],{"class":757},")\"",[747,10677,856],{"class":802},[747,10679,3892],{"class":757},[747,10681,10682],{"class":802},"\u002Fusr\u002Fshare\u002Fnginx\u002Fhtml",[747,10684,3892],{"class":757},[747,10686,1641],{"class":1640},[747,10688,10689],{"class":749,"line":790},[747,10690,10467],{"class":802},[523,10692,10693,856],{},[584,10694,2957],{},[668,10696,10697],{},[638,10698,10699,10702,10703,10706,10707,2006],{},[567,10700,10701],{},"-v HOST:CONTAINER_PATH"," - Mount a path from the host into the container, or in the format of ",[567,10704,10705],{},"-v VOLUME_NAME:CONTAINER_PATH"," to use a volume (the volume must exist already, ",[567,10708,7424],{},[523,10710,10711,10712,10714,10715,10717,10718,10720,10721,10724,10725,10727],{},"This starts a container named ",[567,10713,10427],{}," running the image ",[567,10716,10427],{}," with a volume mounted at ",[567,10719,10682],{},".\nIf we now open ",[527,10722,10595],{"href":10595,"rel":10723},[531]," in the browser, we will see our ",[567,10726,10603],{},". Well done!",[613,10729,10731],{"id":10730},"how-can-this-help-in-the-development-workflow","How can this help in the development workflow?",[523,10733,10734],{},"If you are for example creating a new CMS written in PHP you could, create a Docker image for it.\nOn every push to the git repository of the project, the image could be built and automatic checks could be run, to ensure every feature is working fine.",[523,10736,10737,10738,856],{},"For example Travis CI has switched big parts of their build infrastructure to Docker containers.\nQuoting Travis CI some headings from their ",[527,10739,10742],{"href":10740,"rel":10741},"https:\u002F\u002Fblog.travis-ci.com\u002F2014-12-17-faster-builds-with-container-based-infrastructure\u002F",[531],"blog post",[6072,10744,10745],{},[523,10746,10747],{},"Builds start in seconds\nFaster builds\nMore available resources in a build container\nBetter network capacity, availability and throughput\nEasier to scale",[523,10749,10750],{},"As we can see, containers are better than VMs (depending on the application area).",[523,10752,10753],{},"The lower resource usage is good for the development workflow, making it cheaper and faster.",[613,10755,10757],{"id":10756},"readying-for-production","Readying for Production",[523,10759,10760,10761,10764],{},"Dockerfile ",[567,10762,10763],{},"HEALTHCHECK"," directive can be used to specify a, as the name implies, health check for the container. It can be useful when used in the right way.",[738,10766,10768],{"className":9011,"code":10767,"language":9013,"meta":743,"style":743},"HEALTHCHECK --interval=5m --timeout=3s \\\n  CMD curl -f http:\u002F\u002Flocalhost:8080\u002F || exit 1\n",[567,10769,10770,10777],{"__ignoreMap":743},[747,10771,10772,10774],{"class":749,"line":750},[747,10773,10763],{"class":1895},[747,10775,10776],{"class":1640}," --interval=5m --timeout=3s \\\n",[747,10778,10779,10782],{"class":749,"line":761},[747,10780,10781],{"class":1895},"  CMD",[747,10783,10784],{"class":1640}," curl -f http:\u002F\u002Flocalhost:8080\u002F || exit 1\n",[523,10786,10787,10788,10793],{},"A recommendation to strengthening your applications for production is to take the ",[527,10789,10792],{"href":10790,"rel":10791},"https:\u002F\u002F12factor.net\u002F",[531],"The Twelve-Factor App list"," into account when designing your applications.",[2979,10795],{},[535,10797,10799,10800],{"id":10798},"composing-containers-made-simple-with-docker-compose","Composing containers made simple with ",[567,10801,2936],{},[613,10803,10805],{"id":10804},"making-multi-container-applications-simpler-to-start","Making multi container applications simpler to start",[523,10807,10808,10809,10811,10812,10814,10815,10818,10819,10822,10823,10826,10827,1909],{},"To remove the process of typing all those commands to start the containers, ",[567,10810,2936],{}," has been created.\n",[567,10813,2936],{}," makes it ",[3049,10816,10817],{},"easy peasy lemon squeezy"," to run one to many containers using one command.\nThe syntax of a ",[567,10820,10821],{},"docker-compose.yml"," is YAML (",[3049,10824,10825],{},"YAML Ain't Markup Language","). A good syntax checker, I use, is available ",[527,10828,3396],{"href":10829,"rel":10830},"https:\u002F\u002Fyaml-online-parser.appspot.com\u002F",[531],[523,10832,10833,10834,10836],{},"In our example with WordPress we will create a ",[567,10835,10821],{}," for our MySQL database server, WordPress instance and as an extra we'll add phpMyAdmin to it.",[523,10838,10839,10840,10842,10843,10346,10845,10848,10849,10851,10852,10856],{},"Create the ",[567,10841,10821],{}," file. I made this part like a test again, so you can see where you have knowledge holes, replace all ",[567,10844,10345],{},[527,10846,3396],{"href":10847},"#wordpress-and-mysql-docker-composeyml","):\n(This ",[567,10850,10821],{}," has been taken from ",[527,10853,10854],{"href":10854,"rel":10855},"https:\u002F\u002Fwww.digitalocean.com\u002Fcommunity\u002Ftutorials\u002Fhow-to-install-wordpress-and-phpmyadmin-with-docker-compose-on-ubuntu-14-04",[531],") and modified for this task.",[738,10858,10860],{"className":740,"code":10859,"language":742,"meta":743,"style":743},"version: \"3.5\"\nservices:\n  # mysql image configuration see https:\u002F\u002Fhub.docker.com\u002F_\u002Fmysql\u002F\n  mysql:\n    image: docker.io\u002Flibrary\u002Fmysql:latest\n    environment:\n      MYSQL_ROOT_PASSWORD: my-scret-pw\n      MYSQL_DATABASE: wordpress\n      MYSQL_USER: wordpress\n      MYSQL_PASSWORD: wordpress\n    volumes:\n      - \"mysql:\u002Fvar\u002Flib\u002Fmysql:rw\"\n  # wordpress image configuration see https:\u002F\u002Fhub.docker.com\u002F_\u002Fwordpress\u002F\n  wordpress:\n    image: wordpress\n    ports:\n      - 8080:80\n    environment:\n      WORDPRESS_DB_HOST: __BLANK__:3306\n      WORDPRESS_DB_NAME: __BLANK__\n      WORDPRESS_DB_USER: __BLANK__\n      WORDPRESS_DB_PASSWORD: __BLANK__\n      WORDPRESS_AUTH_KEY: SECURE_AUTH_KEY\n      WORDPRESS_LOGGED_IN_KEY: SECURE_LOGGED_IN_KEY\n      WORDPRESS_AUTH_SALT: SECURE_AUTH_SALT\n      WORDPRESS_LOGGED_IN_SALT: SECURE_LOGGED_IN_SALT\n    volumes:\n      - wordpress:\u002Fvar\u002Fwww\u002Fhtml\n  # phpmyadmin image configuration see https:\u002F\u002Fhub.docker.com\u002Fr\u002Fphpmyadmin\u002Fphpmyadmin\u002F\n  phpmyadmin:\n    image: phpmyadmin\u002Fphpmyadmin\n    ports:\n      - 8181:80\n    environment:\n      PMA_HOST: mysql\n      PMA_USER: root\n      PMA_PASSWORD: workshop\n\nvolumes:\n  mysql:\n  wordpress:\n",[567,10861,10862,10876,10883,10888,10895,10905,10912,10922,10931,10940,10949,10956,10967,10972,10979,10987,10994,11001,11007,11017,11026,11035,11044,11054,11064,11074,11084,11090,11097,11102,11109,11118,11124,11131,11137,11147,11157,11167,11171,11178,11184],{"__ignoreMap":743},[747,10863,10864,10867,10869,10871,10874],{"class":749,"line":750},[747,10865,10866],{"class":753},"version",[747,10868,856],{"class":757},[747,10870,969],{"class":757},[747,10872,10873],{"class":802},"3.5",[747,10875,975],{"class":757},[747,10877,10878,10881],{"class":749,"line":761},[747,10879,10880],{"class":753},"services",[747,10882,758],{"class":757},[747,10884,10885],{"class":749,"line":769},[747,10886,10887],{"class":772},"  # mysql image configuration see https:\u002F\u002Fhub.docker.com\u002F_\u002Fmysql\u002F\n",[747,10889,10890,10893],{"class":749,"line":776},[747,10891,10892],{"class":753},"  mysql",[747,10894,758],{"class":757},[747,10896,10897,10900,10902],{"class":749,"line":784},[747,10898,10899],{"class":753},"    image",[747,10901,856],{"class":757},[747,10903,10904],{"class":802}," docker.io\u002Flibrary\u002Fmysql:latest\n",[747,10906,10907,10910],{"class":749,"line":790},[747,10908,10909],{"class":753},"    environment",[747,10911,758],{"class":757},[747,10913,10914,10917,10919],{"class":749,"line":796},[747,10915,10916],{"class":753},"      MYSQL_ROOT_PASSWORD",[747,10918,856],{"class":757},[747,10920,10921],{"class":802}," my-scret-pw\n",[747,10923,10924,10927,10929],{"class":749,"line":806},[747,10925,10926],{"class":753},"      MYSQL_DATABASE",[747,10928,856],{"class":757},[747,10930,6540],{"class":802},[747,10932,10933,10936,10938],{"class":749,"line":814},[747,10934,10935],{"class":753},"      MYSQL_USER",[747,10937,856],{"class":757},[747,10939,6540],{"class":802},[747,10941,10942,10945,10947],{"class":749,"line":822},[747,10943,10944],{"class":753},"      MYSQL_PASSWORD",[747,10946,856],{"class":757},[747,10948,6540],{"class":802},[747,10950,10951,10954],{"class":749,"line":830},[747,10952,10953],{"class":753},"    volumes",[747,10955,758],{"class":757},[747,10957,10958,10960,10962,10965],{"class":749,"line":836},[747,10959,799],{"class":757},[747,10961,969],{"class":757},[747,10963,10964],{"class":802},"mysql:\u002Fvar\u002Flib\u002Fmysql:rw",[747,10966,975],{"class":757},[747,10968,10969],{"class":749,"line":842},[747,10970,10971],{"class":772},"  # wordpress image configuration see https:\u002F\u002Fhub.docker.com\u002F_\u002Fwordpress\u002F\n",[747,10973,10974,10977],{"class":749,"line":850},[747,10975,10976],{"class":753},"  wordpress",[747,10978,758],{"class":757},[747,10980,10981,10983,10985],{"class":749,"line":863},[747,10982,10899],{"class":753},[747,10984,856],{"class":757},[747,10986,6540],{"class":802},[747,10988,10989,10992],{"class":749,"line":869},[747,10990,10991],{"class":753},"    ports",[747,10993,758],{"class":757},[747,10995,10996,10998],{"class":749,"line":877},[747,10997,799],{"class":757},[747,10999,11000],{"class":802}," 8080:80\n",[747,11002,11003,11005],{"class":749,"line":1015},[747,11004,10909],{"class":753},[747,11006,758],{"class":757},[747,11008,11009,11012,11014],{"class":749,"line":1021},[747,11010,11011],{"class":753},"      WORDPRESS_DB_HOST",[747,11013,856],{"class":757},[747,11015,11016],{"class":802}," __BLANK__:3306\n",[747,11018,11019,11022,11024],{"class":749,"line":1027},[747,11020,11021],{"class":753},"      WORDPRESS_DB_NAME",[747,11023,856],{"class":757},[747,11025,10361],{"class":802},[747,11027,11028,11031,11033],{"class":749,"line":1033},[747,11029,11030],{"class":753},"      WORDPRESS_DB_USER",[747,11032,856],{"class":757},[747,11034,10361],{"class":802},[747,11036,11037,11040,11042],{"class":749,"line":1039},[747,11038,11039],{"class":753},"      WORDPRESS_DB_PASSWORD",[747,11041,856],{"class":757},[747,11043,10361],{"class":802},[747,11045,11046,11049,11051],{"class":749,"line":1054},[747,11047,11048],{"class":753},"      WORDPRESS_AUTH_KEY",[747,11050,856],{"class":757},[747,11052,11053],{"class":802}," SECURE_AUTH_KEY\n",[747,11055,11056,11059,11061],{"class":749,"line":1060},[747,11057,11058],{"class":753},"      WORDPRESS_LOGGED_IN_KEY",[747,11060,856],{"class":757},[747,11062,11063],{"class":802}," SECURE_LOGGED_IN_KEY\n",[747,11065,11066,11069,11071],{"class":749,"line":1066},[747,11067,11068],{"class":753},"      WORDPRESS_AUTH_SALT",[747,11070,856],{"class":757},[747,11072,11073],{"class":802}," SECURE_AUTH_SALT\n",[747,11075,11076,11079,11081],{"class":749,"line":1081},[747,11077,11078],{"class":753},"      WORDPRESS_LOGGED_IN_SALT",[747,11080,856],{"class":757},[747,11082,11083],{"class":802}," SECURE_LOGGED_IN_SALT\n",[747,11085,11086,11088],{"class":749,"line":1087},[747,11087,10953],{"class":753},[747,11089,758],{"class":757},[747,11091,11092,11094],{"class":749,"line":1102},[747,11093,799],{"class":757},[747,11095,11096],{"class":802}," wordpress:\u002Fvar\u002Fwww\u002Fhtml\n",[747,11098,11099],{"class":749,"line":1110},[747,11100,11101],{"class":772},"  # phpmyadmin image configuration see https:\u002F\u002Fhub.docker.com\u002Fr\u002Fphpmyadmin\u002Fphpmyadmin\u002F\n",[747,11103,11104,11107],{"class":749,"line":1117},[747,11105,11106],{"class":753},"  phpmyadmin",[747,11108,758],{"class":757},[747,11110,11111,11113,11115],{"class":749,"line":1123},[747,11112,10899],{"class":753},[747,11114,856],{"class":757},[747,11116,11117],{"class":802}," phpmyadmin\u002Fphpmyadmin\n",[747,11119,11120,11122],{"class":749,"line":1129},[747,11121,10991],{"class":753},[747,11123,758],{"class":757},[747,11125,11126,11128],{"class":749,"line":1142},[747,11127,799],{"class":757},[747,11129,11130],{"class":802}," 8181:80\n",[747,11132,11133,11135],{"class":749,"line":1150},[747,11134,10909],{"class":753},[747,11136,758],{"class":757},[747,11138,11139,11142,11144],{"class":749,"line":1157},[747,11140,11141],{"class":753},"      PMA_HOST",[747,11143,856],{"class":757},[747,11145,11146],{"class":802}," mysql\n",[747,11148,11149,11152,11154],{"class":749,"line":1163},[747,11150,11151],{"class":753},"      PMA_USER",[747,11153,856],{"class":757},[747,11155,11156],{"class":802}," root\n",[747,11158,11159,11162,11164],{"class":749,"line":1168},[747,11160,11161],{"class":753},"      PMA_PASSWORD",[747,11163,856],{"class":757},[747,11165,11166],{"class":802}," workshop\n",[747,11168,11169],{"class":749,"line":1174},[747,11170,1255],{"emptyLinePlaceholder":1254},[747,11172,11173,11176],{"class":749,"line":1480},[747,11174,11175],{"class":753},"volumes",[747,11177,758],{"class":757},[747,11179,11180,11182],{"class":749,"line":1491},[747,11181,10892],{"class":753},[747,11183,758],{"class":757},[747,11185,11186,11188],{"class":749,"line":1496},[747,11187,10976],{"class":753},[747,11189,758],{"class":757},[523,11191,11192,856],{},[584,11193,2957],{},[668,11195,11196,11238],{},[638,11197,11198,11200,11201],{},[567,11199,10880],{}," - List of \"service\" containers.\n",[668,11202,11203,11229],{},[638,11204,11205,11208,11209],{},[567,11206,11207],{},"mysql:"," - Name of the container.\n",[668,11210,11211,11217,11223],{},[638,11212,11213,11216],{},[567,11214,11215],{},"image:"," - Defines the used image for the container.",[638,11218,11219,11222],{},[567,11220,11221],{},"links: []"," - A list of container links.",[638,11224,11225,11228],{},[567,11226,11227],{},"ports: []"," - A list of published ports.",[638,11230,11231,11234,11235,3052],{},[567,11232,11233],{},"environment: []"," - \"Hash\" list of environment variables (Format: ",[567,11236,11237],{},"NAME: VALUE",[638,11239,11240,11243],{},[567,11241,11242],{},"volumes:"," - List of volumes to create.",[613,11245,11247],{"id":11246},"starting-our-multi-container-applications-with-one-command","Starting our multi container applications with one command",[523,11249,11250,8939,11252],{},[584,11251,2951],{},[527,11253,11256],{"href":11254,"rel":11255},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-docker\u002Ftree\u002Fmaster\u002Fcompose101",[531],[567,11257,11258],{},"compose101",[523,11260,11261,11262,11264],{},"To \"run\"\u002Fstart the content of our ",[567,11263,10821],{},", we run:",[738,11266,11268],{"className":1621,"code":11267,"language":1623,"meta":743,"style":743},"docker-compose -f DOCKER_COMPOSE_YML up\n",[567,11269,11270],{"__ignoreMap":743},[747,11271,11272,11274,11276,11279],{"class":749,"line":750},[747,11273,2936],{"class":1630},[747,11275,1934],{"class":802},[747,11277,11278],{"class":802}," DOCKER_COMPOSE_YML",[747,11280,11281],{"class":802}," up\n",[523,11283,11284,856],{},[584,11285,2957],{},[668,11287,11288,11296,11312],{},[638,11289,11290,11292,11293,11295],{},[567,11291,2936],{}," - The ",[567,11294,2936],{}," command.",[638,11297,11298,11301,11302,11304,11305,11308,11309,11311],{},[567,11299,11300],{},"-f DOCKER_COMPOSE_YML"," - Optional. Defaults to ",[567,11303,10821],{},". ",[567,11306,11307],{},"DOCKER_COMPOSE_YML"," is a path to a valid ",[567,11310,2936],{}," file.",[638,11313,11314,11317],{},[567,11315,11316],{},"up"," - Starts the containers defined in the given docker-compose file.",[523,11319,11320,11321,11324,11325,5845,11327,11329],{},"After running the command, you should see log output starting to fill your terminal. To stop the started containers press ",[567,11322,11323],{},"CTRL+C",".\nFor running the containers detached in the background, you use the same option as for Docker, the ",[567,11326,5812],{},[567,11328,5841],{},") option.",[613,11331,11333,11334,11336],{"id":11332},"basic-docker-compose-commands","Basic ",[567,11335,2936],{}," commands",[523,11338,11339,11340,11342,11343,11295],{},"There are some ",[567,11341,2936],{}," commands you should know when working with the ",[567,11344,2936],{},[3126,11346,11348,11349,11351],{"id":11347},"stopping-all-containers-run-by-the-current-docker-compose-file","Stopping all containers run by the current ",[567,11350,2936],{}," file",[523,11353,11354,11355,11357,11358,11361,11362,11311],{},"Instead of the ",[567,11356,11316],{},", you just put ",[567,11359,11360],{},"stop"," there. Stops the containers from the current ",[567,11363,2936],{},[738,11365,11367],{"className":1621,"code":11366,"language":1623,"meta":743,"style":743},"docker-compose stop -t TIMEOUT\n",[567,11368,11369],{"__ignoreMap":743},[747,11370,11371,11373,11375,11377],{"class":749,"line":750},[747,11372,2936],{"class":1630},[747,11374,5324],{"class":802},[747,11376,9736],{"class":802},[747,11378,11379],{"class":802}," TIMEOUT\n",[523,11381,11382,856],{},[584,11383,2957],{},[668,11385,11386,11391],{},[638,11387,11388,11390],{},[567,11389,11360],{}," - Stop subcommand.",[638,11392,11393,11396],{},[567,11394,11395],{},"-t TIMEOUT"," - Optional. Timeout to wait for the containers, before the containers get killed.",[3126,11398,11400,11401,11351],{"id":11399},"deleting-all-containers-run-by-the-current-docker-compose-file","Deleting all containers run by the current ",[567,11402,2936],{},[523,11404,11405,11406,11408,11409,11412,11413,11415],{},"Replacing the ",[567,11407,11316],{}," with ",[567,11410,11411],{},"rm",", deletes all containers that are started by the current ",[567,11414,2936],{}," file, but now are stopped or exited.",[738,11417,11419],{"className":1621,"code":11418,"language":1623,"meta":743,"style":743},"docker-compose -f DOCKER_COMPOSE_YML rm -f\n",[567,11420,11421],{"__ignoreMap":743},[747,11422,11423,11425,11427,11429,11431],{"class":749,"line":750},[747,11424,2936],{"class":1630},[747,11426,1934],{"class":802},[747,11428,11278],{"class":802},[747,11430,5902],{"class":802},[747,11432,11433],{"class":802}," -f\n",[523,11435,11436,856],{},[584,11437,2957],{},[668,11439,11440,11447],{},[638,11441,11442,11444,11445,11311],{},[567,11443,11411],{}," - \"Subcommand\" for removing\u002Fdeleting all container started by the current selected ",[567,11446,2936],{},[638,11448,11449,11452],{},[567,11450,11451],{},"-f"," - Optional. Forces the removal of the containers.",[3126,11454,11456,11457,11351],{"id":11455},"restarting-all-container-started-by-the-current-docker-compose-file","Restarting all container started by the current ",[567,11458,2936],{},[523,11460,11461,11462,11464],{},"Restarts all containers that are started or have exited by the current ",[567,11463,2936],{}," file.\nThis just stops and starts the containers again and not stops, deletes and runs the containers again.",[738,11466,11468],{"className":1621,"code":11467,"language":1623,"meta":743,"style":743},"docker-compose -f DOCKER_COMPOSE_YML restart\n",[567,11469,11470],{"__ignoreMap":743},[747,11471,11472,11474,11476,11478],{"class":749,"line":750},[747,11473,2936],{"class":1630},[747,11475,1934],{"class":802},[747,11477,11278],{"class":802},[747,11479,11480],{"class":802}," restart\n",[523,11482,11483,856],{},[584,11484,2957],{},[668,11486,11487],{},[638,11488,11489,11444,11492,11311],{},[567,11490,11491],{},"restart",[567,11493,2936],{},[613,11495,11497,11498,11500],{"id":11496},"lets-play-more-with-docker-compose","Let's play more with ",[567,11499,2936],{},"!",[523,11502,11503,8939,11505],{},[584,11504,2951],{},[527,11506,11509],{"href":11507,"rel":11508},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-docker\u002Ftree\u002Fmaster\u002Fcompose202",[531],[567,11510,11511],{},"compose202",[523,11513,11514,11515,11517,11518,11520,11521,11523],{},"The task contains other ",[567,11516,10821],{},"s for you to play around with. Look at the ",[567,11519,10821],{},"s and start them.\nJust play around with ",[567,11522,2936],{}," a bit.",[523,11525,11526,11528,11529,11531,11532,11534],{},[584,11527,9515],{},": Keep the ",[567,11530,9779],{}," option in mind, when dealing with multiple ",[567,11533,10821],{},"'s in one folder.",[613,11536,11538],{"id":11537},"summary-of-these-sections","Summary of these sections",[523,11540,11541,11542,11544],{},"We can now write basic ",[567,11543,10821],{},"s. We can now start a multi container application with one single command.",[2979,11546],{},[535,11548,11550],{"id":11549},"what-to-watchout-for-and-what-to-keep-in-mind","What to watchout for and what to keep in mind?",[613,11552,11554],{"id":11553},"images","Images",[668,11556,11557,11568],{},[638,11558,11559,11560,11562,11563],{},"Don't use the ",[567,11561,8834],{}," tag for container images!\n",[668,11564,11565],{},[638,11566,11567],{},"A fully qualified tag is vital to have a reproducible container image build.",[638,11569,11570,11571,11574,11575,9661,11578],{},"Use fully qualified base image names, instead of, e.g., ",[567,11572,11573],{},"debian:bookworm",", use ",[567,11576,11577],{},"docker.io\u002Flibrary\u002Fdebian:bookworm",[668,11579,11580],{},[638,11581,11582],{},"Why? Because some container runtimes might have a different default registry configured or none at all.",[613,11584,11586],{"id":11585},"containers","Containers",[668,11588,11589,11597],{},[638,11590,11591,11592],{},"Make sure to set resource \"requests\"\u002Flimits according to the application running in the container.\n",[668,11593,11594],{},[638,11595,11596],{},"E.g., Java applications might need more memory on start but while running, so it can be a good idea to set a lower soft limit (request), than the hard limit.",[638,11598,11599],{},"Least privileges for containers and the application running inside it.",[613,11601,11602],{"id":2936},"Docker Compose",[668,11604,11605,11621],{},[638,11606,11607,11608,11610,11611,11613,11614,3052],{},"There are different versions of ",[567,11609,2936],{}," files in the wild, make sure to keep that in mind when adjusting\u002Fupdating existing ",[567,11612,2936],{}," files (",[527,11615,11618,11619],{"href":11616,"rel":11617},"https:\u002F\u002Fdocs.docker.com\u002Fcompose\u002Fintro\u002Fhistory\u002F",[531],"history and development of ",[567,11620,2936],{},[638,11622,11623],{},"Very useful tool for development environments, e.g., a MySQL database, Redis server are needed to run some local tests.",[613,11625,421],{"id":11626},"storage",[668,11628,11629,11639],{},[638,11630,11631,11632,11635,11636,3052],{},"If you have to persist data, use ",[567,11633,11634],{},"docker volume","s. Don't use container's as volumes (",[567,11637,11638],{},"--volume-from",[638,11640,11641],{},"Make sure that important data is taken care of, e.g., backups configured. It needs to be clear who is in charge of the data.",[613,11643,11645],{"id":11644},"security","Security",[668,11647,11648,11660,11663],{},[638,11649,11650,11651],{},"Least privileges for containers and the application running inside it (\"duplicate\").\n",[668,11652,11653],{},[638,11654,11655,11656,11659],{},"\"This container image I downloaded needs ",[567,11657,11658],{},"--privileged","to run\", don't do it unless you trust the source of the container image and you are sure that the application in it really needs basically full access to the host.",[638,11661,11662],{},"Use security scanners\u002Ftooling for your container images, to make sure your security team won't lose their hair.",[638,11664,11665],{},"Don't just run any publicly available container images!",[2979,11667],{},[535,11669,11671],{"id":11670},"orchestration-tools","Orchestration Tools",[523,11673,11674],{},[3049,11675,11676],{},"The right tool for the right workload. Keep that in mind or you'll have problems soon.",[613,11678,11680],{"id":11679},"a-wild-docker-swarm-appeared-kubernetes-used-rolling-update-it-was-very-effective","\"A wild Docker Swarm appeared. Kubernetes used rolling-update. It was very effective.\"",[523,11682,11683],{},"The choice of the orchestration tool, depends on many factors:",[668,11685,11686,11689,11692,11695],{},[638,11687,11688],{},"Workloads you'll handle (how many containers will be run?)",[638,11690,11691],{},"How much traffic?",[638,11693,11694],{},"Depending on your experience with the tools, stateless or stateful applications?",[638,11696,11697],{},"How many servers?",[523,11699,11700],{},"My personal favorite choice is Kubernetes, \"easy to use\", developed by Google (one of the largest and longest container users) and the huge growing community. With the latest updates as well, it can scale up to 1000+ nodes.\nI like Kubernetes more, because it offers me to start small and scale fast if needed.",[523,11702,11703],{},"That's not the only reason, but one of the biggest why.",[613,11705,11707],{"id":11706},"other-orchestration-tools","Other Orchestration Tools",[668,11709,11710,11716,11723,11729,11736,11743],{},[638,11711,11712],{},[527,11713,124],{"href":11714,"rel":11715},"https:\u002F\u002Fkubernetes.io\u002F",[531],[638,11717,11718],{},[527,11719,11722],{"href":11720,"rel":11721},"https:\u002F\u002Fmesos.apache.org\u002F",[531],"Mesos by Apache",[638,11724,11725],{},[527,11726,11728],{"href":3037,"rel":11727},[531],"Nomad by Hashicorp",[638,11730,11731],{},[527,11732,11735],{"href":11733,"rel":11734},"http:\u002F\u002Francher.com\u002F",[531],"Rancher by Rancher Labs",[638,11737,11738],{},[527,11739,11742],{"href":11740,"rel":11741},"https:\u002F\u002Fshipyard-project.com\u002F",[531],"Shipyard by the Shipyard team",[638,11744,11745],{},"And many more..",[2979,11747],{},[535,11749,11751],{"id":11750},"the-end","The End",[523,11753,11754],{},"If you are reading this, you have made it to the end. Well done, madame or sir! Have a cookie and a warm chocolate on my cap. ;-)",[2979,11756],{},[535,11758,11760],{"id":11759},"solutions-for-tasks","Solutions for \"Tasks\"",[613,11762,11764],{"id":11763},"nginx-dockerfile","nginx Dockerfile",[738,11766,11768],{"className":9011,"code":11767,"language":9013,"meta":743,"style":743},"FROM docker.io\u002Flibrary\u002Fdebian:jessie\n\nRUN apt-get update && apt-get install -y nginx\n\nENTRYPOINT [\"nginx\"]\n",[567,11769,11770,11776,11780,11787,11791],{"__ignoreMap":743},[747,11771,11772,11774],{"class":749,"line":750},[747,11773,9020],{"class":1895},[747,11775,9023],{"class":1640},[747,11777,11778],{"class":749,"line":761},[747,11779,1255],{"emptyLinePlaceholder":1254},[747,11781,11782,11784],{"class":749,"line":769},[747,11783,9065],{"class":1895},[747,11785,11786],{"class":1640}," apt-get update && apt-get install -y nginx\n",[747,11788,11789],{"class":749,"line":776},[747,11790,1255],{"emptyLinePlaceholder":1254},[747,11792,11793,11795,11797,11800],{"class":749,"line":784},[747,11794,9210],{"class":1895},[747,11796,4262],{"class":1640},[747,11798,11799],{"class":802},"\"nginx\"",[747,11801,4268],{"class":1640},[613,11803,11805,11806],{"id":11804},"wordpress-and-mysql-docker-composeyml","WordPress and MySQL ",[567,11807,10821],{},[738,11809,11811],{"className":740,"code":11810,"language":742,"meta":743,"style":743},"version: \"3.5\"\n\nservices:\n  mysql:\n    image: docker.io\u002Flibrary\u002Fmysql:latest\n    environment:\n      DB_NAME: wordpress\n      DB_USER: wordpress\n      DB_PASS: wordpress\n    volumes:\n      - \"mysql:\u002Fvar\u002Flib\u002Fmysql:rw\"\n  wordpress:\n    image: docker.io\u002Flibrary\u002Fwordpress\n    ports:\n      - 8080:80\n    environment:\n      WORDPRESS_DB_HOST: mysql:3306\n      WORDPRESS_DB_NAME: wordpress\n      WORDPRESS_DB_USER: wordpress\n      WORDPRESS_DB_PASSWORD: wordpress\n      WORDPRESS_AUTH_KEY: SECURE_AUTH_KEY\n      WORDPRESS_LOGGED_IN_KEY: SECURE_LOGGED_IN_KEY\n      WORDPRESS_AUTH_SALT: SECURE_AUTH_SALT\n      WORDPRESS_LOGGED_IN_SALT: SECURE_LOGGED_IN_SALT\n    volumes:\n      - wordpress:\u002Fvar\u002Fwww\u002Fhtml\n  phpmyadmin:\n    image: docker.io\u002Fphpmyadmin\u002Fphpmyadmin\n    ports:\n      - 8181:80\n    environment:\n      PMA_HOST: mysql\n      PMA_USER: root\n      PMA_PASSWORD: workshop\n\nvolumes:\n  mysql:\n  wordpress:\n",[567,11812,11813,11825,11829,11835,11841,11849,11855,11864,11873,11882,11888,11898,11904,11913,11919,11925,11931,11940,11948,11956,11964,11972,11980,11988,11996,12002,12008,12014,12023,12029,12035,12041,12049,12057,12065,12069,12075,12081],{"__ignoreMap":743},[747,11814,11815,11817,11819,11821,11823],{"class":749,"line":750},[747,11816,10866],{"class":753},[747,11818,856],{"class":757},[747,11820,969],{"class":757},[747,11822,10873],{"class":802},[747,11824,975],{"class":757},[747,11826,11827],{"class":749,"line":761},[747,11828,1255],{"emptyLinePlaceholder":1254},[747,11830,11831,11833],{"class":749,"line":769},[747,11832,10880],{"class":753},[747,11834,758],{"class":757},[747,11836,11837,11839],{"class":749,"line":776},[747,11838,10892],{"class":753},[747,11840,758],{"class":757},[747,11842,11843,11845,11847],{"class":749,"line":784},[747,11844,10899],{"class":753},[747,11846,856],{"class":757},[747,11848,10904],{"class":802},[747,11850,11851,11853],{"class":749,"line":790},[747,11852,10909],{"class":753},[747,11854,758],{"class":757},[747,11856,11857,11860,11862],{"class":749,"line":796},[747,11858,11859],{"class":753},"      DB_NAME",[747,11861,856],{"class":757},[747,11863,6540],{"class":802},[747,11865,11866,11869,11871],{"class":749,"line":806},[747,11867,11868],{"class":753},"      DB_USER",[747,11870,856],{"class":757},[747,11872,6540],{"class":802},[747,11874,11875,11878,11880],{"class":749,"line":814},[747,11876,11877],{"class":753},"      DB_PASS",[747,11879,856],{"class":757},[747,11881,6540],{"class":802},[747,11883,11884,11886],{"class":749,"line":822},[747,11885,10953],{"class":753},[747,11887,758],{"class":757},[747,11889,11890,11892,11894,11896],{"class":749,"line":830},[747,11891,799],{"class":757},[747,11893,969],{"class":757},[747,11895,10964],{"class":802},[747,11897,975],{"class":757},[747,11899,11900,11902],{"class":749,"line":836},[747,11901,10976],{"class":753},[747,11903,758],{"class":757},[747,11905,11906,11908,11910],{"class":749,"line":842},[747,11907,10899],{"class":753},[747,11909,856],{"class":757},[747,11911,11912],{"class":802}," docker.io\u002Flibrary\u002Fwordpress\n",[747,11914,11915,11917],{"class":749,"line":850},[747,11916,10991],{"class":753},[747,11918,758],{"class":757},[747,11920,11921,11923],{"class":749,"line":863},[747,11922,799],{"class":757},[747,11924,11000],{"class":802},[747,11926,11927,11929],{"class":749,"line":869},[747,11928,10909],{"class":753},[747,11930,758],{"class":757},[747,11932,11933,11935,11937],{"class":749,"line":877},[747,11934,11011],{"class":753},[747,11936,856],{"class":757},[747,11938,11939],{"class":802}," mysql:3306\n",[747,11941,11942,11944,11946],{"class":749,"line":1015},[747,11943,11021],{"class":753},[747,11945,856],{"class":757},[747,11947,6540],{"class":802},[747,11949,11950,11952,11954],{"class":749,"line":1021},[747,11951,11030],{"class":753},[747,11953,856],{"class":757},[747,11955,6540],{"class":802},[747,11957,11958,11960,11962],{"class":749,"line":1027},[747,11959,11039],{"class":753},[747,11961,856],{"class":757},[747,11963,6540],{"class":802},[747,11965,11966,11968,11970],{"class":749,"line":1033},[747,11967,11048],{"class":753},[747,11969,856],{"class":757},[747,11971,11053],{"class":802},[747,11973,11974,11976,11978],{"class":749,"line":1039},[747,11975,11058],{"class":753},[747,11977,856],{"class":757},[747,11979,11063],{"class":802},[747,11981,11982,11984,11986],{"class":749,"line":1054},[747,11983,11068],{"class":753},[747,11985,856],{"class":757},[747,11987,11073],{"class":802},[747,11989,11990,11992,11994],{"class":749,"line":1060},[747,11991,11078],{"class":753},[747,11993,856],{"class":757},[747,11995,11083],{"class":802},[747,11997,11998,12000],{"class":749,"line":1066},[747,11999,10953],{"class":753},[747,12001,758],{"class":757},[747,12003,12004,12006],{"class":749,"line":1081},[747,12005,799],{"class":757},[747,12007,11096],{"class":802},[747,12009,12010,12012],{"class":749,"line":1087},[747,12011,11106],{"class":753},[747,12013,758],{"class":757},[747,12015,12016,12018,12020],{"class":749,"line":1102},[747,12017,10899],{"class":753},[747,12019,856],{"class":757},[747,12021,12022],{"class":802}," docker.io\u002Fphpmyadmin\u002Fphpmyadmin\n",[747,12024,12025,12027],{"class":749,"line":1110},[747,12026,10991],{"class":753},[747,12028,758],{"class":757},[747,12030,12031,12033],{"class":749,"line":1117},[747,12032,799],{"class":757},[747,12034,11130],{"class":802},[747,12036,12037,12039],{"class":749,"line":1123},[747,12038,10909],{"class":753},[747,12040,758],{"class":757},[747,12042,12043,12045,12047],{"class":749,"line":1129},[747,12044,11141],{"class":753},[747,12046,856],{"class":757},[747,12048,11146],{"class":802},[747,12050,12051,12053,12055],{"class":749,"line":1142},[747,12052,11151],{"class":753},[747,12054,856],{"class":757},[747,12056,11156],{"class":802},[747,12058,12059,12061,12063],{"class":749,"line":1150},[747,12060,11161],{"class":753},[747,12062,856],{"class":757},[747,12064,11166],{"class":802},[747,12066,12067],{"class":749,"line":1157},[747,12068,1255],{"emptyLinePlaceholder":1254},[747,12070,12071,12073],{"class":749,"line":1163},[747,12072,11175],{"class":753},[747,12074,758],{"class":757},[747,12076,12077,12079],{"class":749,"line":1168},[747,12078,10892],{"class":753},[747,12080,758],{"class":757},[747,12082,12083,12085],{"class":749,"line":1174},[747,12084,10976],{"class":753},[747,12086,758],{"class":757},[2890,12088,12089],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":743,"searchDepth":761,"depth":761,"links":12091},[12092,12093,12095,12096,12097,12102,12106,12112,12113,12119,12126,12131,12141,12151,12158,12162,12163],{"id":2929,"depth":761,"text":2930},{"id":2940,"depth":761,"text":12094},"Heads up - \"Glossary\"",{"id":2967,"depth":761,"text":2968},{"id":2983,"depth":761,"text":2984},{"id":3008,"depth":761,"text":3009,"children":12098},[12099,12100,12101],{"id":3012,"depth":769,"text":3013},{"id":3043,"depth":769,"text":3044},{"id":3055,"depth":769,"text":3056},{"id":3109,"depth":761,"text":3110,"children":12103},[12104,12105],{"id":3113,"depth":769,"text":3114},{"id":3486,"depth":769,"text":3487},{"id":3642,"depth":761,"text":3643,"children":12107},[12108,12109,12110,12111],{"id":3649,"depth":769,"text":3650},{"id":4152,"depth":769,"text":4153},{"id":5725,"depth":769,"text":5726},{"id":6359,"depth":769,"text":6360},{"id":7070,"depth":761,"text":7071},{"id":7227,"depth":761,"text":7228,"children":12114},[12115,12116,12118],{"id":7236,"depth":769,"text":7237},{"id":7355,"depth":769,"text":12117},"Data containers  aka --volumes-from",{"id":7417,"depth":769,"text":7418},{"id":7442,"depth":761,"text":193,"children":12120},[12121,12122,12123,12124,12125],{"id":7448,"depth":769,"text":7449},{"id":7458,"depth":769,"text":7459},{"id":7907,"depth":769,"text":7908},{"id":8244,"depth":769,"text":8245},{"id":8310,"depth":769,"text":8311},{"id":8418,"depth":761,"text":8419,"children":12127},[12128,12129,12130],{"id":8438,"depth":769,"text":8439},{"id":8557,"depth":769,"text":8558},{"id":8771,"depth":769,"text":8772},{"id":8780,"depth":761,"text":8781,"children":12132},[12133,12134,12135,12136,12137,12138,12139,12140],{"id":8787,"depth":769,"text":8788},{"id":8921,"depth":769,"text":8922},{"id":8976,"depth":769,"text":8977},{"id":9498,"depth":769,"text":9499},{"id":10183,"depth":769,"text":10184},{"id":10327,"depth":769,"text":10328},{"id":10730,"depth":769,"text":10731},{"id":10756,"depth":769,"text":10757},{"id":10798,"depth":761,"text":12142,"children":12143},"Composing containers made simple with docker-compose",[12144,12145,12146,12148,12150],{"id":10804,"depth":769,"text":10805},{"id":11246,"depth":769,"text":11247},{"id":11332,"depth":769,"text":12147},"Basic docker-compose commands",{"id":11496,"depth":769,"text":12149},"Let's play more with docker-compose!",{"id":11537,"depth":769,"text":11538},{"id":11549,"depth":761,"text":11550,"children":12152},[12153,12154,12155,12156,12157],{"id":11553,"depth":769,"text":11554},{"id":11585,"depth":769,"text":11586},{"id":2936,"depth":769,"text":11602},{"id":11626,"depth":769,"text":421},{"id":11644,"depth":769,"text":11645},{"id":11670,"depth":761,"text":11671,"children":12159},[12160,12161],{"id":11679,"depth":769,"text":11680},{"id":11706,"depth":769,"text":11707},{"id":11750,"depth":761,"text":11751},{"id":11759,"depth":761,"text":11760,"children":12164},[12165,12166],{"id":11763,"depth":769,"text":11764},{"id":11804,"depth":769,"text":12167},"WordPress and MySQL docker-compose.yml","2024-10-01T10:48:12+02:00","\"Docker for Devs\"-Workshop for getting started with Docker and containers.",{"src":12171},"\u002Fblog\u002Fcovers\u002Fdocker-logo-vertical.png",{"tags":12173},[12174,12175,124,12176],"Workshop","Docker","Docker for Admins","\u002Fblog\u002F2024\u002Fdocker-for-devs-workshop-v3",{"title":2920,"description":12169},"3.blog\u002F2024\u002Fdocker-for-devs-workshop-v3","lKs8GFUWcB9MM07BncPjLPbRCpR3eS4AnEhmQn1ItaE",{"id":12182,"title":12183,"authors":12184,"badge":518,"body":12187,"date":12377,"description":12378,"extension":2911,"image":12379,"meta":12380,"navigation":1254,"path":12381,"seo":12382,"stem":12383,"__hash__":12384},"posts\u002F3.blog\u002F2023\u002Fcompany-politics-are-hobbling-data-performance.md","Company politics are hobbling your distributed data performance",[12185],{"name":514,"to":515,"avatar":12186},{"src":517},{"type":520,"value":12188,"toc":12363},[12189,12195,12210,12218,12233,12236,12240,12243,12246,12249,12253,12256,12263,12266,12270,12273,12277,12280,12284,12293,12296,12300,12303,12307,12310,12320,12324,12327,12330,12334,12337,12341,12350,12352],[12190,12191,12192],"note",{},[523,12193,12194],{},"This blog post is originally from the Koor Technologies, Inc. website which due Koor Technologies, Inc. closure in early 2024 doesn't exist anymore.",[597,12196,12197],{},[523,12198,12199,12200,550,12205],{},"Cover photo credits go to ",[527,12201,12204],{"href":12202,"rel":12203},"https:\u002F\u002Fwww.pexels.com\u002Fphoto\u002Fcar-stuck-on-muddy-road-13648107\u002F",[531],"Car Stuck on Muddy Road",[527,12206,12209],{"href":12207,"rel":12208},"https:\u002F\u002Fwww.pexels.com\u002F@alexalexal\u002F",[531],"Alexandra Bakhareva",[523,12211,12212,12213,12217],{},"I’ve discussed ",[527,12214,12216],{"href":12215},"\u002Fblog\u002F2023\u002Fits-slow-and-i-dont-know-why","debugging storage performance issues"," on this blog before, and I encourage you to check that post out if you haven’t already. Today, I want to focus on data storage problems that are a little more nebulous and hard to isolate. Some of these issues are actually preventable, and often arise from cultural and organizational factors.",[523,12219,12220,12221,12226,12227,12232],{},"Sometimes the root cause of a performance issue is unclear because the symptom appears unrelated. These issues always make me think of the YouTube channel ",[527,12222,12225],{"href":12223,"rel":12224},"https:\u002F\u002Fwww.youtube.com\u002F@HVACRVIDEOS",[531],"HVACR videos",". In ",[527,12228,12231],{"href":12229,"rel":12230},"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=qpfLysLcJ8M",[531],"this video"," in particular, Chris is called in about a water leak which turns out to have nothing to do with the faulty freezer in question. The root of your problem could be lurking in something that appears totally unrelated to where the problem is surfacing. Be ready to explore all possibilities, not just the obvious ones, or as Chris likes to call it, “Big picture diagnosis.”",[523,12234,12235],{},"But what do you do when the root of your storage problem is in another part of the organization? What if it’s a network problem and you can’t access the network logs or even get time with a network admin? These are some of the greatest data storage challenges, and they’re cultural, not technical.",[535,12237,12239],{"id":12238},"data-storage-is-everyones-problem","Data storage is everyone’s problem",[523,12241,12242],{},"If you’re having storage performance issues, it’s not just your storage team who’s going to feel it. Even though storage is usually managed by one team under operations or infrastructure, storage performance touches multiple parts of an organization.",[523,12244,12245],{},"The location of your storage team will impact what information it has access to, which can create problems when debugging (more on this later). Who they report into will also impact the storage budget, and whether you have a robust solution that’s actually fit for purpose.",[523,12247,12248],{},"Data storage is not immune to the fiefdom effect. Anytime you have teams or departments with differing political goals, you have misaligned incentives, which creates an environment where other groups and their needs are seen as adversarial. Now, when you have storage performance problems, your data gets stuck in the mud.",[535,12250,12252],{"id":12251},"the-last-silo-in-devops","The last silo in DevOps",[523,12254,12255],{},"I’m going to use the network as a primary example, because it can often be responsible for storage access issues, and network issues are often the hardest to debug. Despite advances in cross-functional collaboration in the past 15 years, DevOps didn’t solve for this—the networking team is still an island.",[523,12257,12258,12259,12262],{},"Now, we’re ",[3049,12260,12261],{},"not"," suggesting DevNetOps.",[523,12264,12265],{},"Networking is its own domain; network admins have a different skill set and operate with different technology. But the current dynamic does create problems for storage management and performance:",[613,12267,12269],{"id":12268},"misaligned-incentives","Misaligned incentives",[523,12271,12272],{},"Network admins have to balance between stability and performance. At a lot of companies, making time to collaborate on troubleshooting is not incentivized because people aren’t aligned on what success is.",[613,12274,12276],{"id":12275},"tech-debt","Tech debt",[523,12278,12279],{},"Networks are often much older than the services they support. Changes to modernize networks threaten uptime, for example: to replace a switch, all connected servers need to be switched over, which can cause a short, but potentially noticeable outage. This requires coordination with the application team\u002Fs so they are on standby should an automatic failover mechanism fail. The challenge with balancing uptime with modernization means networks tend to operate with tech debt. Among other issues, this is how you end up with storage bottlenecks when the network capacity simply can’t serve the throughput you need.",[613,12281,12283],{"id":12282},"lack-of-transparency","Lack of transparency",[523,12285,12286,12287,12292],{},"Network logs are (understandably) treated as sensitive, and the company can’t grant everyone access due to security concerns. But if you have to go to another group to read logs of the service you’re using, this creates bottlenecks. When your storage team has to get through a ",[527,12288,12291],{"href":12289,"rel":12290},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FBastard_Operator_From_Hell",[531],"BOFH"," to troubleshoot, everyone loses.",[523,12294,12295],{},"These problems aren’t unique to the network, but it tends to be where you run into these issues most. Because of the different skill set and sensitivity of network logs they are less likely to be transparent. (Sometimes it is simply more convenient to restrict access, because visibility exposes the presiding team to feedback and criticism.)",[535,12297,12299],{"id":12298},"how-do-you-get-ahead-of-storage-problems","How do you get ahead of storage problems?",[523,12301,12302],{},"A lot of the challenges I’ve pointed out above are rooted in a lack of planning and experience. Think about this: if you want to build a Kubernetes cluster, what do you need? Well, Kubernetes, obviously, but what else? There’s logging, monitoring, load balancers … You don’t want to wait until you have a problem to find out who takes care of what. If there’s a team that does logging for the whole company, establish upfront how you will work together when there’s an incident. If your team isn’t experienced in what you’re attempting, it might be worth seeking help.",[613,12304,12306],{"id":12305},"investigate-early-and-often","Investigate early and often",[523,12308,12309],{},"Chasing down the cause of odd behavior is another way to catch performance issues before they cause bottlenecks.",[6072,12311,12312],{},[523,12313,12314,12315],{},"“Paying attention to ‘fishy’ things lets you get ahead of the game with your infrastructure—instead of reacting to fires all the time, you can detect symptoms before they affect customers.” — ",[527,12316,12319],{"href":12317,"rel":12318},"http:\u002F\u002Fyellerapp.com\u002Fposts\u002F2015-03-16-incuriosity-killed-the-infrastructure.html",[531],"Incuriosity Will Kill Your Infrastructure",[613,12321,12323],{"id":12322},"kill-your-storage-admin-the-role-not-the-person","Kill your Storage Admin? (the role, not the person)",[523,12325,12326],{},"At a previous company, we had a cross-functional pod, a “network consortium” of sorts, composed of people from across the organization, all responsible for managing and maintaining the network. You could think of it as “if you build it, you run it” for storage—being on call created a sense of shared responsibility and accountability for performance. This was an additional responsibility on top of people’s full-time roles, so probably not feasible for every organization.",[523,12328,12329],{},"You don’t need to merge teams to encourage transparency. If each team is more open and collaborative when it comes to other teams using their provided services, you get a similar effect to a cross-functional team. In many cases, placing everyone under a CIO who holds them accountable for working together can do the trick.",[613,12331,12333],{"id":12332},"align-on-a-common-cause","Align on a common cause",[523,12335,12336],{},"To prevent territorialism, you need a company goal that supersedes departmental politics. Say what you want about DevOps, the principles of collaboration, shared responsibility, and coordination in service of a common goal (usually of serving customers better) are valuable. Working towards the same outcome prevents situations where a team can’t get help with debugging a problem because it doesn’t impact the other team’s goal.",[535,12338,12340],{"id":12339},"whats-your-story","What’s Your Story?",[523,12342,12343,12344,12349],{},"We’d love to hear about your challenges with storage performance. ",[527,12345,12348],{"href":12346,"rel":12347},"https:\u002F\u002Ftwitter.com\u002Fkoor_tech",[531],"Tweet, er, X us"," with your story.",[2979,12351],{},[523,12353,12354],{},[3049,12355,12356,12357,12362],{},"Our appreciation and gratitude to ",[527,12358,12361],{"href":12359,"rel":12360},"https:\u002F\u002Fthebasementoffice.co.uk\u002F",[531],"Rebecca Dodd"," who made this post possible.",{"title":743,"searchDepth":761,"depth":761,"links":12364},[12365,12366,12371,12376],{"id":12238,"depth":761,"text":12239},{"id":12251,"depth":761,"text":12252,"children":12367},[12368,12369,12370],{"id":12268,"depth":769,"text":12269},{"id":12275,"depth":769,"text":12276},{"id":12282,"depth":769,"text":12283},{"id":12298,"depth":761,"text":12299,"children":12372},[12373,12374,12375],{"id":12305,"depth":769,"text":12306},{"id":12322,"depth":769,"text":12323},{"id":12332,"depth":769,"text":12333},{"id":12339,"depth":761,"text":12340},"2023-08-30T00:00:00+02:00","Data storage isn’t everyone’s responsibility, but it is everyone’s problem. These are some reflections on where storage performance goes wrong.","\u002Fblog\u002F2023\u002Fcompany-politics-are-hobbling-data-performance.jpg",{},"\u002Fblog\u002F2023\u002Fcompany-politics-are-hobbling-data-performance",{"title":12183,"description":12378},"3.blog\u002F2023\u002Fcompany-politics-are-hobbling-data-performance","rXUqxLTD7lInPofd7PzDLQu67p9ReRFPwAU_POhpahc",{"id":12386,"title":12387,"authors":12388,"badge":518,"body":12391,"date":12699,"description":12700,"extension":2911,"image":12701,"meta":12702,"navigation":1254,"path":12215,"seo":12703,"stem":12704,"__hash__":12705},"posts\u002F3.blog\u002F2023\u002Fits-slow-and-i-dont-know-why.md","It's Slow and I Don't Know Why",[12389],{"name":514,"to":515,"avatar":12390},{"src":517},{"type":520,"value":12392,"toc":12685},[12393,12397,12411,12420,12440,12443,12447,12450,12459,12463,12471,12474,12482,12490,12494,12497,12504,12507,12510,12513,12526,12530,12543,12547,12550,12556,12573,12576,12580,12590,12594,12597,12600,12618,12633,12636,12639,12643,12646,12657,12660,12663,12676,12678],[12190,12394,12395],{},[523,12396,12194],{},[597,12398,12399],{},[523,12400,12199,12401,550,12406],{},[527,12402,12405],{"href":12403,"rel":12404},"https:\u002F\u002Fwww.pexels.com\u002Fphoto\u002Fclose-up-photo-of-turtle-2613148\u002F",[531],"Close up Photo of Turtle",[527,12407,12410],{"href":12408,"rel":12409},"https:\u002F\u002Ftwitter.com\u002Fdibert",[531],"David Dibert",[523,12412,12413,12414,12419],{},"Today I'm going to talk about how I approach debugging storage performance problems. There's a kind of ",[527,12415,12418],{"href":12416,"rel":12417},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FPincer_movement",[531],"pincer movement"," I like to do to narrow in on the cause, covering these areas:",[668,12421,12422,12425,12428,12431,12434,12437],{},[638,12423,12424],{},"Hardware",[638,12426,12427],{},"Network",[638,12429,12430],{},"Operating system",[638,12432,12433],{},"Application",[638,12435,12436],{},"Correlated jobs",[638,12438,12439],{},"The type of storage you're using",[523,12441,12442],{},"The very first question I recommend asking is:",[535,12444,12446],{"id":12445},"what-is-your-hardware-capable-of","What is your hardware capable of?",[523,12448,12449],{},"Hard drives are slow. If you're using a standardized framework that no one else seems to have an issue with, it could be your hardware. I often find that people have expectations of their hardware that just aren't realistic. Even if you implement smart caching or some other magic, there's no getting past the physical constraints of your hardware.",[523,12451,12452,12453,12458],{},"While SSDs (solid state drives) offer slightly better performance, even the newer NVMe (Non-Volatile Memory Express) SSDs have their limitations (for instance, ",[527,12454,12457],{"href":12455,"rel":12456},"https:\u002F\u002Fblog.okami.dev\u002Fceph-etcd-and-the-sync-hole\u002F",[531],"whether your NVMe SSD has power loss protection or not can impact its speed","). So, your first step is always to test your hardware.",[535,12460,12462],{"id":12461},"fio","Fio",[523,12464,12465,12466,12470],{},"You can use ",[527,12467,12462],{"href":12468,"rel":12469},"https:\u002F\u002Fgithub.com\u002Faxboe\u002Ffio",[531]," (Flexible I\u002FO Tester) for benchmarking and performance testing storage devices by simulating input\u002Foutput (I\u002FO) workloads. You can create customized workloads that closely resemble real-world usage patterns, by specifying the type of operations, the size of data being read or written, the number of threads or concurrent operations, and other parameters.",[523,12472,12473],{},"For example:",[738,12475,12480],{"className":12476,"code":12478,"language":12479},[12477],"language-text","sudo fio \\\n--filename=device\u002Ffile name \\\n--direct=1 \\\n--rw=randread \\\n--bs=4k \\\n--ioengine=libaio \\\n--iodepth=256 \\\n--runtime=120 \\\n--numjobs=4 \\\n--time_based \\\n--group_reporting \\\n--name=iops-test-job \\\n--eta-newline=1 \\\n--readonly\n","text",[567,12481,12478],{"__ignoreMap":743},[523,12483,12484,12485,1909],{},"This script runs Fio, testing random reads of your device for 120 seconds. There are lots more ",[527,12486,12489],{"href":12487,"rel":12488},"https:\u002F\u002Fgithub.com\u002Faxboe\u002Ffio\u002Ftree\u002Fmaster\u002Fexamples",[531],"examples in the GitHub repo",[535,12491,12493],{"id":12492},"what-is-your-network-capable-of","What is your network capable of?",[523,12495,12496],{},"If you've ruled out a hardware issue, the next layer to consider is your network capacity. The nature of storage management is that your client and database need to talk to each other. So even if your hardware is capable of higher throughput than what you're getting, if your network is limited to 1 gigabit, that's all you're going to get.",[523,12498,12499,12500,3052],{},"Every time you write 1 byte of data, it needs to be replicated. It's recommended that organizations using Ceph for storage management use two networks per Ceph cluster: one for \"public\" client communication with Ceph cluster components and one for data replication traffic (you can learn more in ",[527,12501,12503],{"href":12502},"\u002Fblog\u002F2023\u002Fmultus-is-the-way-to-go-for-rook-ceph-networking\u002F","our blog post about how this works in Kubernetes for Rook Ceph networking",[523,12505,12506],{},"Of course, you're not always fortunate enough to be architecting your own network setup: at large organizations, you may be working with a network that is 5-10 years old and simply wasn't designed to be up to the load you're expecting of it today.",[523,12508,12509],{},"There are some tools that can help you test for networking issues:",[613,12511,12512],{"id":12512},"iperf",[523,12514,12515,12520,12521,1909],{},[527,12516,12519],{"href":12517,"rel":12518},"https:\u002F\u002Fgithub.com\u002Fesnet\u002Fiperf",[531],"Iperf3"," lets you measure the maximum achievable bandwidth on TCP, UDP, and SCTP networks. It's commonly used to assess performance, latency, and packet loss between two devices, using a client-server model. You can adjust the duration of the test, amount of data sent, or network protocol, depending on your network setup and needs. Here's an example of ",[527,12522,12525],{"href":12523,"rel":12524},"https:\u002F\u002Fwww.tecmint.com\u002Ftest-network-throughput-in-linux\u002F",[531],"how to perform advanced network throughput testing in Linux with iperf",[613,12527,12529],{"id":12528},"ancientt","Ancientt",[523,12531,12532,12533,12537,12538,1909],{},"For more advanced and granular network performance testing, you can use ",[527,12534,12529],{"href":12535,"rel":12536},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fancientt",[531]," to automatically run tools like iperf3 in dynamic environments like Kubernetes. Ancientt's output is a sheet where you can identify outlier nodes with poor performance—helping you to isolate variations in latency (jitter), out-of-order packets, retransmissions, and other anomalies. Check out a ",[527,12539,12542],{"href":12540,"rel":12541},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fancientt\u002Fblob\u002Fmain\u002Fdocs\u002Fdemos.md",[531],"demo of Ancientt in action here",[535,12544,12546],{"id":12545},"is-there-a-misconfiguration-with-your-operating-system","Is there a misconfiguration with your operating system?",[523,12548,12549],{},"You've ruled out your hardware. Your network is up to the job. Now what? You can continue your search upwards from the bottom (your operating system, kernel, drivers) or test from the top downwards (your application), closing in on the root of your problem.",[523,12551,12552],{},[3069,12553],{"alt":12554,"src":12555},"Linux 6.2 Storage Stack Diagram by \"Werner Fischer\" - Thomas-Krenn.AG","\u002Fblog\u002F2023\u002Fits-slow-and-i-dont-know-why\u002FLinux-storage-stack-diagram_v6.2.png",[597,12557,12558],{},[523,12559,12560,12561,12566,12567,12572],{},"Diagram by ",[527,12562,12565],{"href":12563,"rel":12564},"https:\u002F\u002Fwww.thomas-krenn.com\u002Fen\u002Fwiki\u002FUser:Wfischer",[531],"\"Werner Fischer\""," from the ",[527,12568,12571],{"href":12569,"rel":12570},"https:\u002F\u002Fwww.thomas-krenn.com\u002Fen\u002Fwiki\u002FLinux_Storage_Stack_Diagram",[531],"Linux Storage Stack Diagram - Thomas-Krenn Wiki"," licensed under CC-BY-SA 3.0.",[523,12574,12575],{},"Critically, you need to approach testing layer by layer, rather than running tests in parallel, which can lead to murky results. Ideally you should isolate your tests on storage (a real pincer movement would be simultaneous, but it's still a helpful visual).",[613,12577,12579],{"id":12578},"sar","SAR",[523,12581,12582,12586,12587,12589],{},[527,12583,12579],{"href":12584,"rel":12585},"https:\u002F\u002Flinux.die.net\u002Fman\u002F1\u002Fsar",[531]," (System Activity Reporter) enables you to collect data about your operating system's performance (things like CPU and memory usage, disk activity, etc.) You can save the ",[567,12588,12578],{}," command's output automatically to files where, over time, you may be able to spot patterns of high resource usage or overloading.",[535,12591,12593],{"id":12592},"when-your-storage-performance-slows-down-what-else-is-happening-at-the-time","When your storage performance slows down, what else is happening at the time?",[523,12595,12596],{},"Story time: In a previous role, I worked with a customer who was using Ceph and experiencing massive slowdowns with their storage performance. We started with their hardware and network capacity, but the cause eluded us. Non-hardware issues are harder to diagnose.",[523,12598,12599],{},"So, going by the bottom-up then top-down approach above, we looked at their application logs.",[6072,12601,12602],{},[523,12603,12604,12607,12610,12613,12615],{},[3049,12605,12606],{},"Wait a minute, these slowdowns keep happening at 2AM.",[12608,12609],"br",{},[3049,12611,12612],{},"Are there any jobs running at that time?",[12608,12614],{},[3049,12616,12617],{},"Oh yes, they run backups at that time.",[523,12619,12620,12621,12626,12627,12632],{},"For context, the ",[527,12622,12625],{"href":12623,"rel":12624},"https:\u002F\u002Fdocs.ceph.com\u002Fen\u002Fquincy\u002Fmgr\u002F#ceph-manager-daemon",[531],"Ceph Manager"," is a vital component of the Ceph cluster. The customer had ",[527,12628,12631],{"href":12629,"rel":12630},"https:\u002F\u002Fdocs.ceph.com\u002Fen\u002Flatest\u002Frados\u002Foperations\u002Fplacement-groups\u002F",[531],"autoscaling placement groups"," (PGs) enabled, which was creating an unintended effect. Each of the customer's backups of around 50GB was being read and immediately written to the same cluster, triggering autoscaling to accommodate the sudden increase in data.",[523,12634,12635],{},"When the backup was completed and the 50GB of data written, it simply disappeared from the cluster, prompting autoscaling to scale back down again. Now, this wasn't a bug or an issue so much as the computer doing what it was told to do, but this continual scaling up and down was extremely resource intensive, hence the hard slowdowns. The thing with autoscaling—in any context—is you can't just set it and forget it. You need to pay attention to the impact of autoscaling so you aren't caught out by a misconfiguration.",[523,12637,12638],{},"By looking at the timing of those slowdowns, we were able to correlate the issue with the backups, which helped us to close in on the cause. As a first step we introduced a delay that staggered the backups, reducing the stress on the system and therefore mitigating the slowdowns. We also disabled the PG autoscaler and set a calculated PG count for the affected storage pool that worked much better for the workload.",[535,12640,12642],{"id":12641},"are-you-using-the-right-kind-of-storage-for-your-needs","Are you using the right kind of storage for your needs?",[523,12644,12645],{},"Performance issues can creep in when using a different storage system than your use case requires.",[668,12647,12648,12651,12654],{},[638,12649,12650],{},"Object storage: Ideal for storing and retrieving unstructured data, like backups. It's great for scalability and high availability, but it's not as fast as block storage.",[638,12652,12653],{},"Block storage: Typically used for applications requiring low-level access to data storage, like databases, virtual machines (VMs), and enterprise applications. It's handy for situations where you can't afford latency or outages.",[638,12655,12656],{},"File system storage: If you've got hierarchical directory structures and need a familiar interface and compatibility with other file-sharing applications, file system storage does the job. It can be slowed down, though, if you have file locking set up incorrectly—leading to unexplained timeouts.",[523,12658,12659],{},"We'll explore the different types of storage systems in more depth in an upcoming post.",[535,12661,12662],{"id":12339},"What's your story?",[523,12664,12665,12666,5845,12670,12675],{},"We'd love to hear about your challenges with storage performance. ",[527,12667,12669],{"href":12346,"rel":12668},[531],"Tweet us",[527,12671,12674],{"href":12672,"rel":12673},"https:\u002F\u002Fx.com\u002Fkoor_tech",[531],"X us","?) with your story.",[2979,12677],{},[523,12679,12680],{},[3049,12681,12356,12682,12362],{},[527,12683,12361],{"href":12359,"rel":12684},[531],{"title":743,"searchDepth":761,"depth":761,"links":12686},[12687,12688,12689,12693,12696,12697,12698],{"id":12445,"depth":761,"text":12446},{"id":12461,"depth":761,"text":12462},{"id":12492,"depth":761,"text":12493,"children":12690},[12691,12692],{"id":12512,"depth":769,"text":12512},{"id":12528,"depth":769,"text":12529},{"id":12545,"depth":761,"text":12546,"children":12694},[12695],{"id":12578,"depth":769,"text":12579},{"id":12592,"depth":761,"text":12593},{"id":12641,"depth":761,"text":12642},{"id":12339,"depth":761,"text":12662},"2023-07-25T00:00:00+02:00","We've been there. Here are some debugging tools and tips for getting to the bottom of storage performance issues.","\u002Fblog\u002F2023\u002Fits-slow-and-i-dont-know-why.jpg",{},{"title":12387,"description":12700},"3.blog\u002F2023\u002Fits-slow-and-i-dont-know-why","IeHZIfBC-8WW_OUJIVBQ8meWNA1jOjKGVGpUuem2DWo",{"id":12707,"title":12708,"authors":12709,"badge":518,"body":12712,"date":13371,"description":13372,"extension":2911,"image":13373,"meta":13374,"navigation":1254,"path":13375,"seo":13376,"stem":13377,"__hash__":13378},"posts\u002F3.blog\u002F2023\u002Fmultus-is-the-way-to-go-for-rook-ceph-networking.md","Multus is the way to go for Rook Ceph networking",[12710],{"name":514,"to":515,"avatar":12711},{"src":517},{"type":520,"value":12713,"toc":13368},[12714,12718,12725,12739,12783,12792,12795,12867,12870,12872,12876,12887,12900,12909,12929,12940,13129,13136,13169,13180,13189,13300,13308,13315,13323,13325,13336,13342,13362,13365],[12190,12715,12716],{},[523,12717,12194],{},[523,12719,12720,12721,12724],{},"Have you ever wanted to add more than one network interface to your Pods? Need a safer way to connect a ",[3049,12722,12723],{},"legacy"," application to multiple network VLANs in Kubernetes? Let's see how we can achieve this for a Rook Ceph cluster.",[523,12726,12727,12728,12731,12732,12735,12736,12738],{},"Normally in Kubernetes a Pod only has a single interface to communicate on the cluster network. This is and should be enough for most applications, but for production Rook Ceph deployments it isn't good enough.\nFrom Ceph's recommendation, you should preferably use two different networks. A ",[3049,12729,12730],{},"public network"," on which clients can and will talk to all the Ceph cluster components and the second ",[3049,12733,12734],{},"cluster network",". The ",[3049,12737,12734],{},", as the name might imply is used for certain Ceph cluster traffic, to be exact the Ceph OSD data replication traffic.",[523,12740,12741,12742,12749,12750,12752,12753,12756,12757,12760,12761,12764,12765,12768,12769,12771,12772,12775,12776,12778,12779,12782],{},"A long time ago, ",[527,12743,12746],{"href":12744,"rel":12745},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Foverview\u002Fcomponents\u002F#kube-proxy",[531],[567,12747,12748],{},"kube-proxy"," was still using ",[567,12751,8254],{}," (by default at the time) to ",[3049,12754,12755],{},"route"," traffic to service IPs, the ",[567,12758,12759],{},"hostNetwork"," option was a common way to increase network \"throughput\". ",[567,12762,12763],{},"hostNetwork: true"," does that by exposing the node's network stack to the Pod's containers. At first glance, this might sound great, but it comes with some drawbacks in the security department.\nI can still remember jokingly running ",[567,12766,12767],{},"shutdown"," in a ",[567,12770,12759],{}," Pod and, let's just say I was thankfully able to somehow power on the server again through ",[3049,12773,12774],{},"good"," old remote management interface (IPMI). So take that ",[567,12777,12759],{}," mode, you can ",[3049,12780,12781],{},"weaken"," the isolation of containers by a lot.",[523,12784,12785,12786,12788,12789,12791],{},"You will end up with more traffic on the ",[3049,12787,12734],{}," than on the ",[3049,12790,12730],{}," for a simple reason, a client needs to \"write\" data once to an OSD, but the OSD needs to talk with an X amount of other OSDs to fulfill the replication requirement of the storage pool.",[523,12793,12794],{},"A simplified diagram of this flow of data from a client:",[12796,12797,12798],"mermaid",{},[738,12799,12802],{"className":12800,"code":12801,"language":12796,"meta":743,"style":743},"language-mermaid shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","---\ntitle: Ceph Data Replication Flow\n---\nsequenceDiagram\n    Client->>OSD1: Write data to volume\n    OSD1->>OSD2: Store one replica of this data\n    OSD1->>OSD3: Store one replica of this data\n    OSD1-->>OSD1: Write data to disk\n    OSD2-->>OSD2: Write data to disk\n    OSD2->>OSD1: Data has been saved\n    OSD1-->>OSD1: Write data to disk\n    OSD3->>OSD1: Data has been saved\n    OSD1->>Client: Write Confirmation\n",[567,12803,12804,12809,12814,12818,12823,12828,12833,12838,12843,12848,12853,12857,12862],{"__ignoreMap":743},[747,12805,12806],{"class":749,"line":750},[747,12807,12808],{"class":1640},"---\n",[747,12810,12811],{"class":749,"line":761},[747,12812,12813],{"class":1640},"title: Ceph Data Replication Flow\n",[747,12815,12816],{"class":749,"line":769},[747,12817,12808],{"class":1640},[747,12819,12820],{"class":749,"line":776},[747,12821,12822],{"class":1640},"sequenceDiagram\n",[747,12824,12825],{"class":749,"line":784},[747,12826,12827],{"class":1640},"    Client->>OSD1: Write data to volume\n",[747,12829,12830],{"class":749,"line":790},[747,12831,12832],{"class":1640},"    OSD1->>OSD2: Store one replica of this data\n",[747,12834,12835],{"class":749,"line":796},[747,12836,12837],{"class":1640},"    OSD1->>OSD3: Store one replica of this data\n",[747,12839,12840],{"class":749,"line":806},[747,12841,12842],{"class":1640},"    OSD1-->>OSD1: Write data to disk\n",[747,12844,12845],{"class":749,"line":814},[747,12846,12847],{"class":1640},"    OSD2-->>OSD2: Write data to disk\n",[747,12849,12850],{"class":749,"line":822},[747,12851,12852],{"class":1640},"    OSD2->>OSD1: Data has been saved\n",[747,12854,12855],{"class":749,"line":830},[747,12856,12842],{"class":1640},[747,12858,12859],{"class":749,"line":836},[747,12860,12861],{"class":1640},"    OSD3->>OSD1: Data has been saved\n",[747,12863,12864],{"class":749,"line":842},[747,12865,12866],{"class":1640},"    OSD1->>Client: Write Confirmation\n",[523,12868,12869],{},"Sidenote: That's a reason why Ceph can appear slower in direct comparisons with other storage projects because an input\u002F \"data write\" operation is only confirmed after it has been fully replicated.",[2979,12871],{},[535,12873,12875],{"id":12874},"so-where-does-multus-come-into-play-here","So where does Multus come into play here?",[523,12877,12878,12879,1909],{},"Multus allows you to attach one or more (specific) network interfaces to your Pods. Making the whole ordeal of setting a Pod's network interfaces to a Pod streamlined.\nThere are still going to be some security implications when you, e.g., attach a node's network interface to a Pod, but at least it is made transparent through ",[527,12880,12883,12884],{"href":12881,"rel":12882},"https:\u002F\u002Fgithub.com\u002Fk8snetworkplumbingwg\u002Fmultus-cni\u002Fblob\u002F0c37bb043c704a730535a011a19c0bde36c1463b\u002Fdocs\u002Fquickstart.md#storing-a-configuration-as-a-custom-resource",[531],"Multus' ",[567,12885,12886],{},"Custom Resource Definitions",[523,12888,12889,12890,12893,12894,12899],{},"A security team could simply restrict access to these \"network definitions\" using RBAC in Kubernetes. This in combination with a ",[3049,12891,12892],{},"policy agent"," (e.g., ",[527,12895,12898],{"href":12896,"rel":12897},"https:\u002F\u002Fwww.openpolicyagent.org\u002F",[531],"Open Policy Agent (OPA)","), can help enforce certain \"network access policies\".\nFor monitoring\u002F auditing as well, you can just keep an eye on which network definitions are used by which Pods.",[523,12901,12902,12903,587,12905,12908],{},"Let's assume we have a Kubernetes node with two physically connected network interfaces. Let's stick to the \"good old\" interface naming schema to keep it simple: ",[567,12904,7465],{},[567,12906,12907],{},"eth1"," interface. :winking_face:",[523,12910,12911,12913,12914,12916,12917,12919,12920,12922,12923,12928],{},[567,12912,7465],{}," is used as the \"default\" interface of the node, we will be using ",[567,12915,7465],{}," for the Ceph ",[3049,12918,12730],{}," (client traffic) and ",[567,12921,12907],{}," for Ceph's OSD replication. For simplicity, we'll assume both networks have a ",[527,12924,12927],{"href":12925,"rel":12926},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FDynamic_Host_Configuration_Protocol",[531],"DHCP server"," running.",[523,12930,12931,12932,856],{},"To get started, we need to ",[527,12933,12936,12937],{"href":12934,"rel":12935},"https:\u002F\u002Fgithub.com\u002Fk8snetworkplumbingwg\u002Fmultus-cni\u002Fblob\u002Fmaster\u002Fdocs\u002Fquickstart.md#storing-a-configuration-as-a-custom-resource",[531],"create two ",[567,12938,12939],{},"NetworkAttachDefinitions",[738,12941,12943],{"className":740,"code":12942,"language":742,"meta":743,"style":743},"apiVersion: \"k8s.cni.cncf.io\u002Fv1\"\nkind: NetworkAttachmentDefinition\nmetadata:\n  name: ceph-public-net\nspec:\n  config: '{\n      \"cniVersion\": \"0.3.1\",\n      \"type\": \"host-device\",\n      \"device\": \"eth0\",\n      \"ipam\": {\n        \"type\": \"dhcp\"\n      }\n    }'\n---\napiVersion: \"k8s.cni.cncf.io\u002Fv1\"\nkind: NetworkAttachmentDefinition\nmetadata:\n  name: ceph-cluster-net\nspec:\n  config: '{\n      \"cniVersion\": \"0.3.1\",\n      \"type\": \"host-device\",\n      \"device\": \"eth1\",\n      \"ipam\": {\n        \"type\": \"dhcp\"\n      }\n    }'\n",[567,12944,12945,12959,12969,12976,12986,12993,13005,13010,13015,13020,13025,13030,13035,13043,13047,13059,13067,13073,13082,13088,13098,13102,13106,13111,13115,13119,13123],{"__ignoreMap":743},[747,12946,12947,12950,12952,12954,12957],{"class":749,"line":750},[747,12948,12949],{"class":753},"apiVersion",[747,12951,856],{"class":757},[747,12953,969],{"class":757},[747,12955,12956],{"class":802},"k8s.cni.cncf.io\u002Fv1",[747,12958,975],{"class":757},[747,12960,12961,12964,12966],{"class":749,"line":761},[747,12962,12963],{"class":753},"kind",[747,12965,856],{"class":757},[747,12967,12968],{"class":802}," NetworkAttachmentDefinition\n",[747,12970,12971,12974],{"class":749,"line":769},[747,12972,12973],{"class":753},"metadata",[747,12975,758],{"class":757},[747,12977,12978,12981,12983],{"class":749,"line":776},[747,12979,12980],{"class":753},"  name",[747,12982,856],{"class":757},[747,12984,12985],{"class":802}," ceph-public-net\n",[747,12987,12988,12991],{"class":749,"line":784},[747,12989,12990],{"class":753},"spec",[747,12992,758],{"class":757},[747,12994,12995,12998,13000,13002],{"class":749,"line":790},[747,12996,12997],{"class":753},"  config",[747,12999,856],{"class":757},[747,13001,3537],{"class":757},[747,13003,13004],{"class":802},"{\n",[747,13006,13007],{"class":749,"line":796},[747,13008,13009],{"class":802},"      \"cniVersion\": \"0.3.1\",\n",[747,13011,13012],{"class":749,"line":806},[747,13013,13014],{"class":802},"      \"type\": \"host-device\",\n",[747,13016,13017],{"class":749,"line":814},[747,13018,13019],{"class":802},"      \"device\": \"eth0\",\n",[747,13021,13022],{"class":749,"line":822},[747,13023,13024],{"class":802},"      \"ipam\": {\n",[747,13026,13027],{"class":749,"line":830},[747,13028,13029],{"class":802},"        \"type\": \"dhcp\"\n",[747,13031,13032],{"class":749,"line":836},[747,13033,13034],{"class":802},"      }\n",[747,13036,13037,13040],{"class":749,"line":842},[747,13038,13039],{"class":802},"    }",[747,13041,13042],{"class":757},"'\n",[747,13044,13045],{"class":749,"line":850},[747,13046,12808],{"class":1630},[747,13048,13049,13051,13053,13055,13057],{"class":749,"line":863},[747,13050,12949],{"class":753},[747,13052,856],{"class":757},[747,13054,969],{"class":757},[747,13056,12956],{"class":802},[747,13058,975],{"class":757},[747,13060,13061,13063,13065],{"class":749,"line":869},[747,13062,12963],{"class":753},[747,13064,856],{"class":757},[747,13066,12968],{"class":802},[747,13068,13069,13071],{"class":749,"line":877},[747,13070,12973],{"class":753},[747,13072,758],{"class":757},[747,13074,13075,13077,13079],{"class":749,"line":1015},[747,13076,12980],{"class":753},[747,13078,856],{"class":757},[747,13080,13081],{"class":802}," ceph-cluster-net\n",[747,13083,13084,13086],{"class":749,"line":1021},[747,13085,12990],{"class":753},[747,13087,758],{"class":757},[747,13089,13090,13092,13094,13096],{"class":749,"line":1027},[747,13091,12997],{"class":753},[747,13093,856],{"class":757},[747,13095,3537],{"class":757},[747,13097,13004],{"class":802},[747,13099,13100],{"class":749,"line":1033},[747,13101,13009],{"class":802},[747,13103,13104],{"class":749,"line":1039},[747,13105,13014],{"class":802},[747,13107,13108],{"class":749,"line":1054},[747,13109,13110],{"class":802},"      \"device\": \"eth1\",\n",[747,13112,13113],{"class":749,"line":1060},[747,13114,13024],{"class":802},[747,13116,13117],{"class":749,"line":1066},[747,13118,13029],{"class":802},[747,13120,13121],{"class":749,"line":1081},[747,13122,13034],{"class":802},[747,13124,13125,13127],{"class":749,"line":1087},[747,13126,13039],{"class":802},[747,13128,13042],{"class":757},[523,13130,13131,13132,13135],{},"Short explanation on what the ",[567,13133,13134],{},".spec.config"," here means:",[668,13137,13138,13153],{},[638,13139,13140,13143,13144,13152],{},[567,13141,13142],{},"\"type\": \"host-device\""," uses the ",[527,13145,13148,13151],{"href":13146,"rel":13147},"https:\u002F\u002Fwww.cni.dev\u002Fplugins\u002Fcurrent\u002Fmain\u002Fhost-device\u002F",[531],[567,13149,13150],{},"host-device"," CNI plugin"," to \"Move an already-existing device into a container.\"",[638,13154,13155,13157,13158,8287,13161,13168],{},[567,13156,1303],{}," section, ",[567,13159,13160],{},"\"type\": \"dhcp\"",[527,13162,13165,13151],{"href":13163,"rel":13164},"https:\u002F\u002Fwww.cni.dev\u002Fplugins\u002Fcurrent\u002Fipam\u002Fdhcp\u002F",[531],[567,13166,13167],{},"dhcp"," tells the CNI to get an IP from a DHCP server.",[523,13170,13171,13172,13175,13176,13179],{},"You can run ",[567,13173,13174],{},"kubectl get network-attachment-definitions"," to confirm that both ",[567,13177,13178],{},"NetworkAttachmentDefinitions"," have been created.",[523,13181,13182,13185,13186,13188],{},[584,13183,13184],{},"Warning",": For existing clusters, you currently can't easily switch from, e.g., \"container network\" to ",[567,13187,12759],{}," mode\u002F Multus.",[738,13190,13192],{"className":740,"code":13191,"language":742,"meta":743,"style":743},"apiVersion: ceph.rook.io\u002Fv1\nkind: CephCluster\nmetadata:\n  name: rook-ceph\n  namespace: rook-ceph\nspec:\n  [...]\n  network:\n    provider: multus\n    selectors:\n      public: ceph-public-net\n      cluster: ceph-cluster-net\n  [...]\n",[567,13193,13194,13203,13212,13218,13227,13236,13242,13251,13257,13267,13274,13283,13292],{"__ignoreMap":743},[747,13195,13196,13198,13200],{"class":749,"line":750},[747,13197,12949],{"class":753},[747,13199,856],{"class":757},[747,13201,13202],{"class":802}," ceph.rook.io\u002Fv1\n",[747,13204,13205,13207,13209],{"class":749,"line":761},[747,13206,12963],{"class":753},[747,13208,856],{"class":757},[747,13210,13211],{"class":802}," CephCluster\n",[747,13213,13214,13216],{"class":749,"line":769},[747,13215,12973],{"class":753},[747,13217,758],{"class":757},[747,13219,13220,13222,13224],{"class":749,"line":776},[747,13221,12980],{"class":753},[747,13223,856],{"class":757},[747,13225,13226],{"class":802}," rook-ceph\n",[747,13228,13229,13232,13234],{"class":749,"line":784},[747,13230,13231],{"class":753},"  namespace",[747,13233,856],{"class":757},[747,13235,13226],{"class":802},[747,13237,13238,13240],{"class":749,"line":790},[747,13239,12990],{"class":753},[747,13241,758],{"class":757},[747,13243,13244,13247,13249],{"class":749,"line":796},[747,13245,13246],{"class":757},"  [",[747,13248,5685],{"class":1895},[747,13250,4268],{"class":757},[747,13252,13253,13255],{"class":749,"line":806},[747,13254,764],{"class":753},[747,13256,758],{"class":757},[747,13258,13259,13262,13264],{"class":749,"line":814},[747,13260,13261],{"class":753},"    provider",[747,13263,856],{"class":757},[747,13265,13266],{"class":802}," multus\n",[747,13268,13269,13272],{"class":749,"line":822},[747,13270,13271],{"class":753},"    selectors",[747,13273,758],{"class":757},[747,13275,13276,13279,13281],{"class":749,"line":830},[747,13277,13278],{"class":753},"      public",[747,13280,856],{"class":757},[747,13282,12985],{"class":802},[747,13284,13285,13288,13290],{"class":749,"line":836},[747,13286,13287],{"class":753},"      cluster",[747,13289,856],{"class":757},[747,13291,13081],{"class":802},[747,13293,13294,13296,13298],{"class":749,"line":842},[747,13295,13246],{"class":757},[747,13297,5685],{"class":1895},[747,13299,4268],{"class":757},[523,13301,13302,13303,2006],{},"(Documentation: ",[527,13304,13307],{"href":13305,"rel":13306},"https:\u002F\u002Frook.io\u002Fdocs\u002Frook\u002Fv1.11\u002FCRDs\u002FCluster\u002Fceph-cluster-crd\u002F#multus",[531],"Ceph Cluster CRD - Multus Configuration - Rook Ceph v1.11",[523,13309,13310,13311,13314],{},"This will tell the Rook Ceph operator to \"attach\" the Multus network annotations to the Ceph components, no need to add anything else to the ",[567,13312,13313],{},"CephCluster"," object.",[523,13316,13317,13318,1909],{},"To summarize, we can use Multus to more specifically and easily have a Rook Ceph cluster use two different networks for ",[527,13319,13322],{"href":13320,"rel":13321},"https:\u002F\u002Fdocs.ceph.com\u002Fen\u002Fquincy\u002Frados\u002Fconfiguration\u002Fnetwork-config-ref\u002F",[531],"performance reasons",[2979,13324],{},[523,13326,13327,13328,8287,13333,13335],{},"Looking back at the ",[527,13329,13332],{"href":13330,"rel":13331},"https:\u002F\u002Fgithub.com\u002Frook\u002Frook\u002Fpull\u002F975",[531],"time I implemented",[567,13334,12759],{}," mode in Rook, it is still the simplest way\nto \"skip the container network\" to gain more performance (depending on the CNI encapsulation, etc., used by your Kubernetes cluster network) or expose a service to other clusters\u002F servers which \"can't be just 'loadbalanced'\u002F proxied\".",[523,13337,13338,13339,13341],{},"We are looking into improving the existing documentation and examples, to make it easier for people to use Multus, instead of ",[567,13340,12759],{}," mode, with their Rook Ceph clusters.",[523,13343,13344,13345,13350,13351,13356,13357,1909],{},"If you want to get a more in-depth look at what Multus can do, be sure to check out this great post by ",[527,13346,13349],{"href":13347,"rel":13348},"https:\u002F\u002Fdevopstales.github.io\u002F",[531],"devopstales"," here: ",[527,13352,13355],{"href":13353,"rel":13354},"https:\u002F\u002Fdevopstales.github.io\u002Fkubernetes\u002Fmultus\u002F",[531],"Use Multus CNI in Kubernetes - devopstales",".\nTo look at what other plugins and config options the CNI project and plugins have, check out ",[527,13358,13361],{"href":13359,"rel":13360},"https:\u002F\u002Fwww.cni.dev\u002Fplugins\u002Fcurrent\u002F",[531],"CNI Documentation - Plugins Overview",[523,13363,13364],{},"Thanks for reading!",[2890,13366,13367],{},"html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":743,"searchDepth":761,"depth":761,"links":13369},[13370],{"id":12874,"depth":761,"text":12875},"2023-05-10T11:25:13+02:00","Let's talk about Multus and why you should use it ","\u002Fblog\u002F2023\u002Fmultus-is-the-way-to-go-for-rook-ceph-networking.jpg",{},"\u002Fblog\u002F2023\u002Fmultus-is-the-way-to-go-for-rook-ceph-networking",{"title":12708,"description":13372},"3.blog\u002F2023\u002Fmultus-is-the-way-to-go-for-rook-ceph-networking","S3YtZ_VkbrRhhY3OdOgoYilNUU9Ae_HuHnVryXfbLyk",{"id":13380,"title":13381,"authors":13382,"badge":518,"body":13387,"date":13492,"description":13493,"extension":2911,"image":13494,"meta":13495,"navigation":1254,"path":13496,"seo":13497,"stem":13498,"__hash__":13499},"posts\u002F3.blog\u002F2022\u002Fbetter-insights-extended-ceph-exporter.md","Better Insights: Extended Ceph Exporter for your Ceph Clusters",[13383,13385],{"name":514,"to":515,"avatar":13384},{"src":517},{"name":13386},"Gaurav Sitlani",{"type":520,"value":13388,"toc":13486},[13389,13393,13409,13420,13427,13430,13434,13445,13451,13454,13458,13465,13477],[12190,13390,13391],{},[523,13392,12194],{},[597,13394,13397],{"color":13395,"icon":13396},"success","i-ph-check-circle",[523,13398,13399,13400,13403,13404,1909],{},"To continue the work on the ",[567,13401,13402],{},"extended-ceph-exporter"," project, I have created an independent fork on GitHub ",[527,13405,13408],{"href":13406,"rel":13407},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fextended-ceph-exporter",[531],"galexrt\u002Fextended-ceph-exporter",[523,13410,13411,13412,13414,13415,1909],{},"We are happy to announce that our ",[567,13413,13402],{}," project is hereby publicly available to anyone under the ",[527,13416,13419],{"href":13417,"rel":13418},"https:\u002F\u002Fwww.apache.org\u002Flicenses\u002FLICENSE-2.0",[531],"Apache 2.0 License",[535,13421,13423,13424,13426],{"id":13422},"what-is-the-extended-ceph-exporter","What is the ",[567,13425,13402],{},"?",[523,13428,13429],{},"It is a Prometheus metrics exporter to provide extended metrics from a Ceph cluster.",[535,13431,13433],{"id":13432},"what-extended-metrics-are-exported","What \"extended\" metrics are \"exported\"?",[523,13435,13436,13437,13440,13441,13444],{},"Currently we have two modules that focus on the RGW S3 object storage aspect of Ceph.\nWe are exporting the RGW Bucket Usage information and User Quota information which enables the users to understand the current usage about their Object Storage cluster.\nThis is to improve visibility into application’s object storage usage.\nFor these two metric modules we are getting the metrics through the ",[567,13438,13439],{},"RGW S3 Admin API"," using the ",[567,13442,13443],{},"go-ceph"," rgw\u002Fadmin API.\nThe metrics are collected at the Prometheus metrics endpoint which are eventually used for displaying the information in a nice Grafana dashboard.",[523,13446,13447],{},[3069,13448],{"alt":13449,"src":13450},"Dashboard","https:\u002F\u002Fgithub.com\u002Fkoor-tech\u002Fextended-ceph-exporter\u002Fblob\u002Fmain\u002Fgrafana\u002Fceph-rgw-bucket-usage-overview.png?raw=true",[523,13452,13453],{},"The above dashboard will help in monitoring which buckets are consuming your storage based on the object count and bucket sizes.\nIf the user wants to know if they've set and enabled Quota on their bucket and how much storage they have consumed based on that, this will make the life easier with this information being right in front on a nice dashboard. Furthermore, it would really help in managing the Day 2 operation aspect of the buckets if there's a need to delete some data or scale up your cluster by adding more storage and increasing your Quota.",[535,13455,13457],{"id":13456},"thanks","Thanks!",[523,13459,13460,13461,1909],{},"Check it out on GitHub: ",[527,13462,13463],{"href":13463,"rel":13464},"https:\u002F\u002Fgithub.com\u002Fkoor-tech\u002Fextended-ceph-exporter",[531],[523,13466,13467,13468,13473,13474,13476],{},"If you have any feedback please feel free to share and start a ",[527,13469,13472],{"href":13470,"rel":13471},"https:\u002F\u002Fgithub.com\u002Fkoor-tech\u002Fextended-ceph-exporter\u002Fdiscussions\u002F",[531],"discussion"," on the ",[567,13475,13402],{}," Github project.",[597,13478,13479],{"color":13395,"icon":13396},[523,13480,13399,13481,13403,13483,1909],{},[567,13482,13402],{},[527,13484,13408],{"href":13406,"rel":13485},[531],{"title":743,"searchDepth":761,"depth":761,"links":13487},[13488,13490,13491],{"id":13422,"depth":761,"text":13489},"What is the extended-ceph-exporter?",{"id":13432,"depth":761,"text":13433},{"id":13456,"depth":761,"text":13457},"2022-09-27T09:25:13+02:00","We are happy to announce that our `extended-ceph-exporter` project is hereby publicly available.","\u002Fblog\u002F2022\u002Fbetter-insights-extended-ceph-exporter.jpg",{},"\u002Fblog\u002F2022\u002Fbetter-insights-extended-ceph-exporter",{"title":13381,"description":13493},"3.blog\u002F2022\u002Fbetter-insights-extended-ceph-exporter","SdqiC0iE4ekySIey7Ju0KXFMoSA010TpbrClipBg_Ro",{"id":13501,"title":13502,"authors":13503,"badge":518,"body":13506,"date":13580,"description":13581,"extension":2911,"image":13582,"meta":13583,"navigation":1254,"path":13584,"seo":13585,"stem":13586,"__hash__":13587},"posts\u002F3.blog\u002F2022\u002Fchoosing-the-right-storage-part-2-common-storage-types.md","Choosing the right Storage: Part 2 Common Storage Types",[13504],{"name":514,"to":515,"avatar":13505},{"src":517},{"type":520,"value":13507,"toc":13578},[13508,13512,13515,13518,13521,13524,13538,13541,13544,13547,13566,13569,13575],[12190,13509,13510],{},[523,13511,12194],{},[523,13513,13514],{},"In the first part of this series, we have come across several different types of data that a typical web application would need to save \"somewhere\".\nWe have scratched the surface of where the data is saved to, but there is more to it.",[523,13516,13517],{},"Let's say a user has just created a new document in our web application. What will the web application do to store the document?\nThe web application connect to the database server and will instruct the database server to store it.\nThe database server adds the document to it's internal \"housekeeping\" list so it knows where document is located at in its \"data store\" system.\nThe \"data store\" system is highly sophisticated as it has logic to try to prevent data loss in case of, e.g., a power outage.\nTo keep it simple, the \"data store\" system can be seen as a librarian, a librarian knows where every book (document) is located at and keeps record about any movement of the books.\nThe document is now stored in the database server, but where exactly is it stored? It is stored on the storage of the server that the database server is running on.\nFor the \"data store\" system to work at its peak efficiency level, it uses the operating system I\u002FO (input\u002Foutput), caching and other subsystems.\nThe best storage type for database servers is block storage. Block storage is very \"low level\" in the operating system and by that can allow the operating system to leverage it well.",[523,13519,13520],{},"Now what if a user wants to upload a profile picture, where should the picture be stored?\nAs mentioned last time it heavily depends on your use case and scale which storage type makes most sense here.\nFor smaller to medium web applications, using filesystem storage is a viable option. A simple network share (e.g., NFS) is easy to setup and maintain upto a certain scale. The filesystem would be \"attached\" to every webserver that runs our web application, thanks to that all profile pictures are available on every webserver at all times.\nIn the cloud native world, object store would be the way to go for most similar scenarios. If an application already exists and needs to be augmented to use object storage, it will cost time but depending on the scale of the applications it can make a huge impact in regards to scalability and maintainability.",[523,13522,13523],{},"The advantages why object storage can be better than filesystem storage lie within the following questions:",[668,13525,13526,13532],{},[638,13527,13528,13531],{},[584,13529,13530],{},"How much space will be needed?",": An object storage can easily scale to petabytes of data, where a filesystem storage might have issues due to other factors to reach this scale.",[638,13533,13534,13537],{},[584,13535,13536],{},"How many files will need to be stored?",": Both filesystem and object storage can store many many files, but a filesystem storage is most often reaching it's scalability limits faster.",[523,13539,13540],{},"These are just two questions and there are so many parameters to take into account when deciding between filesystem and object storage.",[523,13542,13543],{},"Why wasn't block storage mentioned for storing profile pictures? Block storage is inherently a bad choice for most \"multiple readers and writers at the same time\" (e.g., dynamically scaling webservers) scenarios.",[523,13545,13546],{},"To break down the 3 most common storage types into one sentence each:",[668,13548,13549,13556,13563],{},[638,13550,13551,13552,13555],{},"Block Storage: Think of it like an external ",[584,13553,13554],{},"USB disk"," that has a \"mass\" to it.",[638,13557,13558,13559,13562],{},"File\u002FFilesystem Storage: Have you ever worked at a larger enterprise? Your colleagues and you probably had a bunch of ",[584,13560,13561],{},"shares"," that you could use to share documents with each other.",[638,13564,13565],{},"Object Storage: Do you have an app on your phone that automatically uploads your camera photos and displays them somewhere online for you? Object store is kinda like that but without the fancy web interface.",[523,13567,13568],{},"This image might make iteasier for you to differentiate between the 3 most common storage types:",[523,13570,13571],{},[3069,13572],{"alt":13573,"src":13574},"Block vs. Filesystem vs. Object Storage","\u002Fblog\u002F2022\u002Fchoosing-the-right-storage\u002Fblock-vs-filesystem-vs-object.png",[523,13576,13577],{},"In the next part of the \"Choosing the right Storage\" series, we will look into backing up and restoring data.",{"title":743,"searchDepth":761,"depth":761,"links":13579},[],"2022-04-21T15:25:13+02:00","Second part of our \"Choosing the right Storage\" series. Let's dive into the 3 most common storage types.","\u002Fblog\u002F2022\u002Fchoosing-the-right-storage\u002Fchoosing-the-right-storage.jpg",{},"\u002Fblog\u002F2022\u002Fchoosing-the-right-storage-part-2-common-storage-types",{"title":13502,"description":13581},"3.blog\u002F2022\u002Fchoosing-the-right-storage-part-2-common-storage-types","sOxRMdMq9LovK7XJkw8DCuclr4w0-32Xzet9Gz4Sue0",{"id":13589,"title":13590,"authors":13591,"badge":518,"body":13594,"date":13628,"description":13629,"extension":2911,"image":13582,"meta":13630,"navigation":1254,"path":13631,"seo":13632,"stem":13633,"__hash__":13634},"posts\u002F3.blog\u002F2022\u002Fchoosing-the-right-storage-part-1-application-storage.md","Choosing the right Storage: Part 1 Application Storage",[13592],{"name":514,"to":515,"avatar":13593},{"src":517},{"type":520,"value":13595,"toc":13626},[13596,13600,13605,13608,13611,13614,13617,13620,13623],[12190,13597,13598],{},[523,13599,12194],{},[523,13601,13602,13604],{},[584,13603,3103],{}," It is important to think about all the data that must be stored during the design phase of an application.",[523,13606,13607],{},"In this first post of a series about use cases for storage, we will look at the main types of \"storage\".\nLet's dissect what data a classic PHP based web application would need to store.",[523,13609,13610],{},"Starting at the webserver, you have access and error logs of Apache, NGINX, whatever webserver you are using.\nAccess logs of the most common webservers contain one line for every request made to the webserver. Thankfully webservers are smart enough to write these logs in such a way that requests are not blocked.\nStill they can grow in size in specific situations, such as a Distributed Denial of Service (DDOS) attack against the webserver.\nError logs can be used for debugging purposes when an error occured on the webserver side.\nBesides the webserver's log files, the operating system the webserver is running on. The operating system will most likely run other services besides the webserver, that are needed to, e.g., administrate the server remotely (SSH; Secure Shell Server).",[523,13612,13613],{},"Now onto the web application, assuming that the web application has some sort of user login, there should be some way to store these \"user sessions\".\nA small web application with one webserver could get away with storing the user sessions locally, as there is no need for them to be \"shared\".\nBut a medium to large web application with more than one webserver (e.g., for high availability) would use some database to store the sessions.\nThere's several database projects out there which can be used for storing sessions, the main take away is that depending on the scale other measures need to be taken.\nFor a very large web application, having a central \"session database\" can have advantages and disadvantages.\n\"Small\" things like user sessions storage should be kept in mind and not forgotten when designing a (new) application.",[523,13615,13616],{},"The user has logged in and wants to upload a document to the web application. That's additional data that needs to be stored.\nWhere should such data be stored? There's different opinions and ways on how to accomplish this.\nOne approach for smaller file uploads can be to store them in the database, but this approach does not scale too well.\nIn the cloud native world Object Storage would be the answer (to everything). Object Storage in form of \"S3 compatible storage\" has been made well known by Amazon Web Services.\nAmazon Web Services themselves are offering a service called \"Amazon Simple Storage Service\", short \"Amazon S3\".\nThe S3 Object Storage API allows for simple file upload and download. This can make it easy to be implemented in (new) applications to store certain data in an S3 compatible Object Storage.",[523,13618,13619],{},"Where should user posts be stored? For most use cases the answer here will be a database.\nThere's several different databases available each of them covers many different use cases. Among the most commonly used are MySQL, PostgreSQL and Microsoft SQL Server.\nMost web applications are using MySQL or PostgreSQL databases. Even with more and more NoSQL databases popping up, it really depends on your use case.\nIs your data mostly relational? Non relational data? Storing documents?\nStill in the end no matter the database used, the database must be stored some where.",[523,13621,13622],{},"An important point that hasn't been touched on yet is that for every bit of data that is stored, the question \"does it need a backup?\" arises.\nTo that question the answer should most of the time be a definite \"Yes\".\nWe'll dive more into backups in a future post on our blog.",[523,13624,13625],{},"In the next part of the \"Choosing the right Storage\" series, we will look into the 3 most common storage types (Block Storage, Filesystem Storage, Object Storage).",{"title":743,"searchDepth":761,"depth":761,"links":13627},[],"2022-04-11T15:25:13+02:00","First part of our \"Choosing the right Storage\" series. Let's dive into the data a web application needs to store.",{},"\u002Fblog\u002F2022\u002Fchoosing-the-right-storage-part-1-application-storage",{"title":13590,"description":13629},"3.blog\u002F2022\u002Fchoosing-the-right-storage-part-1-application-storage","8zc4Boo2Ma1rJeq_B12gQ_wKcpn-lh0cu6zgK3pXHYo",{"id":13636,"title":13637,"authors":13638,"badge":518,"body":13641,"date":13796,"description":13797,"extension":2911,"image":13668,"meta":13798,"navigation":1254,"path":13799,"seo":13800,"stem":13801,"__hash__":13802},"posts\u002F3.blog\u002F2022\u002Ftaking-control.md","Taking Control",[13639],{"name":514,"to":515,"avatar":13640},{"src":517},{"type":520,"value":13642,"toc":13793},[13643,13646,13652,13661,13683,13690,13693,13700,13709,13728,13731,13734,13755,13758,13763,13766],[523,13644,13645],{},"Just as a YouTuber would say now \"Well.. it has been some time since my last video\" and showing a screenshot of their last video's upload time with the typical \"it has been x weeks\" or longer.\nWould it be wrong to do the same but with my last blog post?",[523,13647,13648],{},[3069,13649],{"alt":13650,"src":13651},"Last blog article was from January 2020","\u002Fblog\u002F2022\u002Ftaking-control\u002Flast-post.png",[523,13653,13654,13655,13660],{},"Well.. it has been quite some time since my last blog post, hasn't it? Two years have been a long time. Since then many things have happened and changed, but for most parts improved. During the times we live in right now, it feels weird to say that things have improved.\nCovid is still \"raging\" in most countries and let's just say \"politics\" are at an all time high of being a \"landmine\" of a topic choice. Not to mention the ",[527,13656,13659],{"href":13657,"rel":13658},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FDoomsday_Clock",[531],"Doomsday Clock"," being moved to 100 seconds before midnight in January 2020.",[6072,13662,13663,13669,13673],{},[523,13664,13665],{},[3069,13666],{"alt":13667,"src":13668},"Doomsday clock, in 2022, at 1.67 minutes (100 seconds) to midnight - Uploaded to Wikimedia by Ryanicus Girraficus","\u002Fblog\u002F2022\u002Ftaking-control\u002Fdoomsday_clock_(1.67_minutes).png",[523,13670,13671],{},[3049,13672,13667],{},[523,13674,13675,13676,13679,13680],{},"\"Well.. would you look at the time? It has gotten ",[3049,13677,13678],{},"late",", hasn't it?\" ",[3049,13681,13682],{},"*gestures vaguely at the doomsday clock*",[523,13684,13685,13686,13689],{},"One of the best decisions I have made in the last two years regarding the current state of the world, was to uninstall any news apps and unsubscribe from any news magazines (y'all still know those things out of paper which cost money?). No more news for me. You could probably interpret this as a person isolating themselves by doing this, but for me personally it was not about isolating but about taking back control.\nTaking (back) control? Why don't I just stop looking at the news app then? I'm not the only one doing things out of reflex, right? Everytime I'm waiting on, let's say a train, my hands go to my phone and next thing I know is I'm checking the news, surfing Hacker News for some cool new articles.. I could go on and on, but you know what I mean.\nThinking about it now, \"reflex\" might be the wrong word but a \"habit\" would be better suited here. Breaking habits is hard, creating new (hopefully healthier) habits is even harder.\nIt's interesting how a habit can go to a certain extent to make you feel like an \"addict\". ",[3049,13687,13688],{},"The brain is weird.","\nBut why did I stop looking at news in general? It is the same reason as to \"why I disabled YouTube's autoplay feature\".\nI want to be in control of what I watch and when I watch it. If a video ends, I want to control what comes next. I don't want an algorithm to just \"feed me\" what it thinks I would like to see next.\nIt felt weird, but in a good way to realize what \"was taken\" away because I let YouTube's autoplay algorithm decide what comes next. Maybe the algorithm shows me a video of a cat playing the piano? Maybe a compilation of kids falling? I am not saying that the YouTube algorithm is bad, or that all algorithms are bad, but when I watch videos it is my time and I want to control what I do in my time.\nAnyone remember the saying \"time is money\"? For me it is not about \"money\", but about the time, my time to be exact.\nOnly the future will tell if more people realize and \"rebell\" against the algorithms and \"think more\" for themselves.",[523,13691,13692],{},"Maybe to try to elaborate on the \"taking control of my time\", I just recently started switching away from Google Mail to another more privacy focused email provider.\nCan you believe that I now need to sort my emails by myself? Again it feels weird at first and not having four automatically sorted categories for any emails.\nAn algorithm might come close to sorting my emails and knowing which email might be so important to be sorted into the \"Primary\" category, especially after some training.\nBut in the end only I can know if this new email is (really) important to me (\"under the current circumstances\").\nDo I care about the new game that was just released on Steam? How would \"the algorithm\" know that? Maybe it is the long awaited \"Half Life 3\"? Who knows? The \"alorithm\" might be able to get it right with enough \"context\" from the internet and data from me, but it will never be \"perfect\". The \"algorithm\" needs \"feedback\" from the users to improve itself.",[523,13694,13695,13696,13699],{},"Feedback is important. It can be frustrating to receive certain (\"negative\") feedback. Speaking for myself, I am always thankful for anyone giving me any feedback even when disgruntled at first.\nBeing able to reflect on oneself and other's feedback is an important skill. A skill which needs to be trained as is with everything we do every day.\nAs an example, some people are better at handling awkward situations as others. I personally think that I am ",[3049,13697,13698],{},"highly skilled"," at creating awkward situations.\nMost of my friends can probably confirm that.. but a skill is a skill, right?\nFeedback and reflecting is good as long is it is drank like alcohol, responsibly and in moderation.\n\"Over reflecting\", better known as \"over thinking\", is not good in the long term. For anyone constantly \"over thinking\" situations, I would recommend you to reflect on that.. oh wait a second... is this a recursion joke to divert your attention away from the \"problem\"? Maybe.\nLet me summarize, reflecting on your thoughts, situations, feedback, etc., do it! It is important, but keep it in moderation. Too much reflecting\u002Fthinking is not good in the long term.\nIf you \"reflect\" too much, reflect about it! Again, y'all want a side of \"recursion\" with that over thinking of yours?\nAs a previously professional overthinker, I can confirm that over thinking can and will hurt you in a long term.. Accepting that fact, and not over thinking every feedback takes a long time. It is a mountain to over come and if you want to make it, you can as long as you keep at it.",[523,13701,13702,13703,13708],{},"Thanks to my family, friends and acquaintances, I can with confidence say I am ready for the future! I am ready to improve myself every day and being up for the tasks at hand every day.\nSuch a \"social network\" is important to have, hard to maintance and even harder to \"find\"(\u002F build).\nMy three most important sentences that I have heard during the last years were, \"Stop thinking so much\", \"Your father was proud of you\", and \"I love you as you are.\"\nAt first I wasn't able to accept these \"sentences\". Not because of my some \"social illiteracy\" that some times occures, but because my brain was blocking them to be accepted by my \"heart\".\nIsn't it normally the other way around? Normally the heart is blocking\u002F clouding our judgment, isn't it?\nTo keep this brief, as it starts to feel weird writing about something so personal for anyone to see.\nI have been able to start overcoming this, what I would \"summarize\" as my personal ",[527,13704,13707],{"href":13705,"rel":13706},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FHedgehog%27s_dilemma",[531],"\"Hedgehog's dilemma\"",", for my \"work life\" and \"life life\".\nThere's many bad people out there to take advantage of you (or, worse, e.g., bully you), because of that many people stop trusting anyone easily and are hard on everyone for simple mistakes, misunderstandings, etc.\nEven though people do these things to protect themselves, eventually you have to take the risk of getting hurt by people.\nWithout accepting the fact that there are \"bad people\" out in the world, how will you strive to be a \"better\" person without knowning your \"enemy\"?\nIn the end, there is only one person that can help you, and that is yourself.\nNot even the biggest nut cracker in the world could crack your shell, only you can crack through your shell, the thougest of them all.\nEven with my young 24 years old, I can tell you that it will hurt, it will feel confusing, but it will be definitely worth it.",[523,13710,13711,13712,13717,13718,1909],{},"For anyone reading this article struggling with their current fights, I personally really like this ",[527,13713,13716],{"href":13714,"rel":13715},"https:\u002F\u002Fdepts.washington.edu\u002Ffammed\u002Fwp-content\u002Fuploads\u002F2019\u002F03\u002FKaters-selfcare_printable.pdf",[531],"\"Everything Is Awful and I'm Not Okay: questions to ask before giving up\" by Sinope"," poster",[13719,13720,13721],"sup",{},[527,13722,13727],{"href":13723,"ariaDescribedBy":13724,"dataFootnoteRef":743,"id":13726},"#user-content-fn-1",[13725],"footnote-label","user-content-fnref-1","1",[523,13729,13730],{},"I know, I know, I have gone all out in regards to melancholic topics in this post so far, but these things need to be talked about.\nNot everything is just sunshine and flowers every time, and that is okay. Without the \"highs\", how would we know what a \"low\" is? Without a \"low\" how would we know what a \"high\" is?\nWe need a better acceptance for mental health in the world. Not just in the IT sector, but in general in our society.\nEspecially with Covid pushing everyone to their limits, we need to stop using mental illness as a tool to gain likes and followers!\nInstead we need to start helping the \"wounded\" fight their fights if they are willing to accept the help for their own sake.",[523,13732,13733],{},"So.. what's the latest news with me?\nI'm doing pretty well. I have lost some weight during the lockdowns, I have girlfriend which supports me and helps make my apartment actually \"liveable\" in (you guessed it her middle name is \"interior and decoration design\").\nI gained new friends (\"Possums like to play dead, right?\"), new knowledge, new insights into the world and so much more.\nI have been able to improve! I haven't neceesarily reached every goal I set for myself, but I am in control of my time and therefor myself more than ever.\nFuture, I have experience from the past and the current times, so I'm ready for you, here I come!",[523,13735,13736,13737,13742,13743,13748,13749,13754],{},"Besides being ready fur the future, as of today, 1st April 2022, I am not working for Cloudical anymore.\nI have started a new endeavor at ",[527,13738,13741],{"href":13739,"rel":13740},"https:\u002F\u002Fkoor.tech\u002F",[531],"Koor Technologies, Inc."," as a Founding Engineer.\nThanks to ",[527,13744,13747],{"href":13745,"rel":13746},"https:\u002F\u002Fopencoreventures.com\u002F",[531],"Open Core Ventures"," for providing me this opportunity!\nKoor Technologies, Inc. is an open source company which has been funded by Open Core Ventures.\nIf you have experience in Ceph storage and\u002F or the ",[527,13750,13753],{"href":13751,"rel":13752},"https:\u002F\u002Frook.io\u002F",[531],"Rook project",", and are looking for something new, feel free to reach out to me via email or other channels (check the icons in the sidebar).",[523,13756,13757],{},"Thanks for reading and I hope you can take something with you from this article!",[523,13759,13760],{},[3049,13761,13762],{},"This post is in memory of my father Philipp, who has passed away in 2019. I have made you proud and I will continue doing so in the future.",[523,13764,13765],{},"- Alexander",[13767,13768,13771,13776],"section",{"className":13769,"dataFootnotes":743},[13770],"footnotes",[535,13772,13775],{"className":13773,"id":13725},[13774],"sr-only","Footnotes",[635,13777,13778],{},[638,13779,13781,13782,8287,13786],{"id":13780},"user-content-fn-1","Copyright Sinope (eponis.tumblr.com), 2015. This work is licensed under a Creative Commons Attribution 4.0 International License. Original: ",[527,13783,13784],{"href":13784,"rel":13785},"http:\u002F\u002Feponis.tumblr.com\u002Fpost\u002F113798088670\u002Feverything-is-awful-and-im-not-okay-questions-to",[531],[527,13787,13792],{"href":13788,"ariaLabel":13789,"className":13790,"dataFootnoteBackref":743},"#user-content-fnref-1","Back to reference 1",[13791],"data-footnote-backref","↩",{"title":743,"searchDepth":761,"depth":761,"links":13794},[13795],{"id":13725,"depth":761,"text":13775},"2022-03-25T13:12:30+01:00","Talking about time, control, Hedgehog's dilemma and other personal points.",{},"\u002Fblog\u002F2022\u002Ftaking-control",{"title":13637,"description":13797},"3.blog\u002F2022\u002Ftaking-control","zEoq4a18b8jaiyiJ3sYeeX2aGxGfgaIvcwkZXeSA8TU",{"id":13804,"title":13805,"authors":13806,"badge":518,"body":13809,"date":13970,"description":13971,"extension":2911,"image":13972,"meta":13974,"navigation":1254,"path":13980,"seo":13981,"stem":13982,"__hash__":13983},"posts\u002F3.blog\u002F2020\u002Ffosdem20.md","FOSDEM'20 Brussels",[13807],{"name":514,"to":515,"avatar":13808},{"src":517},{"type":520,"value":13810,"toc":13968},[13811,13825,13828,13830,13833,13836,13845,13852,13858,13873,13876,13882,13893,13896,13899,13902,13905,13918,13925,13931,13939,13942,13945,13951,13959,13962,13965],[523,13812,13813,13814,13819,13820,1909],{},"Checkout the original publication of this article on the ",[527,13815,13818],{"href":13816,"rel":13817},"http:\u002F\u002Fthe-report.cloud\u002F",[531],"The Cloud Report"," site, where it was posted originally, here: ",[527,13821,13824],{"href":13822,"rel":13823},"http:\u002F\u002Fthe-report.cloud\u002Ffosdem2020-brussels",[531],"The Cloud Report - FOSDEM’2020 Brussels",[523,13826,13827],{},"Thanks to The Cloud Report for allowing me to write and publish the post on their blog!",[2979,13829],{},[523,13831,13832],{},"I'm sitting in the ICE train back home from FOSDEM'2020 Brussels, and I’ve got only one thing to say: \"What a wonderful weekend!\"",[523,13834,13835],{},"FOSDEM, a weekend in Brussles, Belgium, where great minds in the form of developers, administrators and engineers meet and connect.\nThey talk about their topics, projects, experiences and ideas.\nIt's great to get in touch with the people behind the projects, and to stay in contact with people from previous companies\u002F projects. Being able to discuss problems and features with project developers in person normally results in awesomeness for the project in the end.\nOr, put differently, did you ever want to buy the guy that made a project you are using a beer for helping with a bug\u002F feature? I hope your answer to that question is \"yes\", and FOSDEM is the place to do exactly that.",[523,13837,13838,13839,13844],{},"For FOSDEM newcomers, don't worry, your not the only one being a bit overwhelmed with FOSDEM.\nEvery year it is a new adventure, with rooms changed, different ways to get to rooms due to some construction work at the university and other points.\nA recommendation I can give is to read and apply the \"Open Sourcing Mental Illness Conference Handbook\" which can be found on the ",[527,13840,13843],{"href":13841,"rel":13842},"https:\u002F\u002Fwww.cncf.io\u002Fblog\u002F2020\u002F01\u002F10\u002Fkeeping-cloud-native-well\u002F",[531],"Keeping Cloud Native Well - Cloud Native Computing Foundation"," blog. It is great to see such a group nowadays look into this topic.",[523,13846,13847,13848,13851],{},"I sadly, but also thankfully, have to say that there is only one \"down\", which is the same as last year.\nA big problem are the rooms; the Devrooms with topics such as containers, Golang and other popular topics, are always \"full house\" (full rooms). In some cases this even means that there are (long) queues to get in the rooms.\nTo be fair here, in my opinion it has gotten better in comparison to last year, still it is a bit of a bummer if you want to hear a talk and you can't get in\u002F need to be there 3 talks before (camping) the talk even starts to have a seat in the room. (Please don't room camp, thanks! ",[567,13849,13850],{},";-)",") If you don't necessarily want to be in the room, there are livestreams available for all rooms, which is cool in its own as not many conferences have that.\nI'm hope that this problem will be further improved next year for FOSDEM'21.",[523,13853,13854],{},[3069,13855],{"alt":13856,"src":13857},"FOSDEM'20 - Outside area shot #1","\u002Fblog\u002F2020\u002Ffosdem20\u002Fmvimg_20200201_135436.jpg",[523,13859,13860,13861,13866,13867,13872],{},"One of the awesome things to mention is that the recordings of the talks are available pretty quick as it is a self service system for the speakers. In my case the ",[527,13862,13865],{"href":13863,"rel":13864},"https:\u002F\u002Fvideo.fosdem.org\u002F2020\u002FH.1308\u002Frook_cloud_native_storage_for_kubernetes.mp4",[531],"\"Rook Cloud Native Storage for Kubernetes\" by Alexander Trost"," I gave, is already available to watch.\nThe more time passes, the more talk recordings will be available to watch. If you go to the ",[527,13868,13871],{"href":13869,"rel":13870},"https:\u002F\u002Ffosdem.org\u002F2020\u002Fschedule\u002F",[531],"FOSDEM'20 schedule"," and click on a talk, it should have the recording linked in the \"Links\" section for you to watch.",[523,13874,13875],{},"Let's dive into one of the talks that stood out to me. It is the \"The Linux Kernel: We have to finish this thing one day;)\" by \"Thorsten Leenhuis\".",[523,13877,13878],{},[3069,13879],{"alt":13880,"src":13881},"FOSDEM'20 - Saturday, Janson Room: \"The Linux Kernel: We have to finish this thing one day ;)\" by \"Thorsten Leemhuis\"","\u002Fblog\u002F2020\u002Ffosdem20\u002Fimg_20200201_101052.jpg",[523,13883,13884,13885,13888,13889,13892],{},"He talked about Linux getting \"actual\" Async IO through ",[567,13886,13887],{},"io_uring",", which should give a boost to the \"kernel scalability\" of Linux.\nThe scalability of Linux is an interesting point as in a lot of cases a to be implemented feature\u002F change, has to work on existing code to improve it. One example he brought up was the use of the ",[567,13890,13891],{},"lock_kernel()"," call, which usage is almost completely removed from the kernel code to improve performance and scalability.",[523,13894,13895],{},"Another big example for change and also improvement, is eBPF. For the people that don't know about eBPF yet, it is a way to run \"BPF programs\" in the Linux kernel. These \"BPF programs\" can be very powerful, as can be seen in the Cilium project, which uses it filter traffic on L4 and L7 (e.g., HTTP, Kafka, GRPC and others) as well. Other kernel subsystems have shown interest in eBPF.",[523,13897,13898],{},"BPF itself helps to bring \"Dtrace 2.0\". It does so in form of BCC and bpftrace to Linux, for more and better tracing capabilities in and around the Linux kernel.",[523,13900,13901],{},"Realtime is a feature in which various people and companies are investing time into. This is a great thing as things need to be fast, very fast for realtime processing, meaning that the whole kernel benefits from these realtime capabilities.",[523,13903,13904],{},"Besides all these technical topics, he brought up a point which I think everyone should remember:",[6072,13906,13907,13910],{},[523,13908,13909],{},"\"Reaching big goals in small steps\"",[523,13911,13912,13913],{},"By ",[527,13914,13917],{"href":13915,"rel":13916},"https:\u002F\u002Fwww.leemhuis.info\u002F",[531],"Thorsten Leemhuis",[523,13919,13920,13921,13924],{},"Most features in the Linux kernel came in small steps to in the end form a big whole feature and\u002F or improvement. Looking at ",[567,13922,13923],{},"BPF"," that has been built over years, that definitely seems right.",[523,13926,13927],{},[3069,13928],{"alt":13929,"src":13930},"FOSDEM'20 - Outside area shot #2","\u002Fblog\u002F2020\u002Ffosdem20\u002Fmvimg_20200201_142211.jpg",[523,13932,13933,13934,13938],{},"There were many interesting talks, too many interesting topics for just two days, but that is what the recordings are for. As mentioned earlier, it’s best to checkout the ",[527,13935,13937],{"href":13869,"rel":13936},[531],"FOSDEM'2020 schedule"," to get a feeling of how many different topics\u002F areas there are.",[523,13940,13941],{},"I spent most of the time talking with to people I know, but also with unknown people, to hear about their old and new experiences, projects and ideas.\nIn addition to that I, for me as a speaker, it is flattering to get interesting questions to answer during the talk and afterwards outside the room.\nI had extensive talks with people new to, and already using, Rook, after my talk.\nThese conversations, questions and feedback are always a great way to gather insights on how people are using the project and how Rook can be further improved, but also how I myself can improve as a speaker.",[523,13943,13944],{},"Thanks to the community around Free Software, Open Source and Hackerspaces, there have been a lot of possibilities to grab a beer or two with colleagues and friends.\nAs a tradition I can say the waffles are still very good and I can fully recommend them.",[523,13946,13947],{},[3069,13948],{"alt":13949,"src":13950},"FOSDEM'20 - Belgium Waffles at Le Funambule","\u002Fblog\u002F2020\u002Ffosdem20\u002Fimg_20200201_211417.jpg",[523,13952,13953,13954,1909],{},"Be sure to try their waffles next time you are in Brussels, see ",[527,13955,13958],{"href":13956,"rel":13957},"https:\u002F\u002Fgoo.gl\u002Fmaps\u002FfiJC2Qm2hr22",[531],"Le Funambule on Google Maps",[523,13960,13961],{},"In summary, FOSDEM is always a great event to meet and connect with people, not necessarily to go to (many) talks due to the room situation, but still you will have definitely learned something afterwards that may help you in your future IT adventures.",[523,13963,13964],{},"If you haven't been to FOSDEM yet, maybe this article has shown that you should join next year#s FOSDEM.\nFeel free to drop by and say hi, should you visit FOSDEM next time.",[523,13966,13967],{},"Have Fun!",{"title":743,"searchDepth":761,"depth":761,"links":13969},[],"2020-01-31T19:06:12+01:00","Some thoughts, notes, comments and pictures from the FOSDEM'20 in Brussels, Belgium.",{"src":13973},"\u002Fblog\u002F2020\u002Ffosdem20\u002Ffosdem2020-brussels-cover-w1250px.png",{"tags":13975},[13976,13977,13978,427,465,13979],"Conferences","FOSDEM","Brussels","Talk","\u002Fblog\u002F2020\u002Ffosdem20",{"title":13805,"description":13971},"3.blog\u002F2020\u002Ffosdem20","P-HV6psl4GYuvZgOzO24ymde82RjKRP6kIKIL-AWNmI",{"id":13985,"title":13986,"authors":13987,"badge":518,"body":13990,"date":14548,"description":14549,"extension":2911,"image":14550,"meta":14551,"navigation":1254,"path":14556,"seo":14557,"stem":14558,"__hash__":14559},"posts\u002F3.blog\u002F2020\u002Fmy-home-office-setup-v2.md","My Home Office Setup v2",[13988],{"name":514,"to":515,"avatar":13989},{"src":517},{"type":520,"value":13991,"toc":14532},[13992,13996,13999,14003,14006,14009,14015,14019,14023,14026,14057,14061,14064,14091,14103,14107,14125,14134,14137,14161,14165,14168,14222,14225,14229,14238,14241,14245,14254,14260,14263,14267,14270,14276,14281,14306,14313,14317,14320,14329,14338,14344,14347,14356,14360,14459,14468,14474,14478,14510,14514,14520,14523,14527,14530],[535,13993,13995],{"id":13994},"it-was-time","It was time",[523,13997,13998],{},"Time to create an updated post of my improved home office setup.\nLet's dive right into it.",[535,14000,14002],{"id":14001},"table","Table",[523,14004,14005],{},"The table is 1.60m (~5.24934 feet) long.",[523,14007,14008],{},"The cable management has been improved in comparsion to my previous setup post.\nIt can still be further improved but it is much better than before and I'm finally happy with it now.",[523,14010,14011],{},[3069,14012],{"alt":14013,"src":14014},"Table\u002F Desk Shot","\u002Fblog\u002F2020\u002Fmy-home-office-setup-v2\u002Fwork-desk.jpg",[613,14016,14018],{"id":14017},"computers","Computers",[3126,14020,14022],{"id":14021},"gaming","Gaming",[523,14024,14025],{},"This compliments my \"small\" Steam library pretty well and the Valve Index headset which is pretty dope to use and play games on.",[668,14027,14028,14031,14034,14037,14040,14054],{},[638,14029,14030],{},"CPU: Intel© i7-7700k (4c\u002F8t)",[638,14032,14033],{},"Memory: 16GB DDR4-3000",[638,14035,14036],{},"GPU: ASUS ROG STRIX RTX2080 Super A8G GAMING",[638,14038,14039],{},"Network: Dual port 10G network card",[638,14041,14042,14043],{},"Disk(s):\n",[668,14044,14045,14048,14051],{},[638,14046,14047],{},"1x 500GB SATA SSD",[638,14049,14050],{},"1x 3TB SATA HDD",[638,14052,14053],{},"1x 4TB SATA HDD",[638,14055,14056],{},"Case: be quiet! Silent Base 601 Midi-Tower",[3126,14058,14060],{"id":14059},"workstation","Workstation",[523,14062,14063],{},"The \"heart\" of working at home.",[668,14065,14066,14069,14072,14075,14077,14089],{},[638,14067,14068],{},"CPU: AMD Ryzen 7 1800X (8c\u002F16t)",[638,14070,14071],{},"Memory: 32GB DDR4-2133",[638,14073,14074],{},"GPU: 2x Radeon RX 560 OC 4G",[638,14076,14039],{},[638,14078,14042,14079],{},[668,14080,14081,14084,14086],{},[638,14082,14083],{},"1x 500GB NVMe SSD",[638,14085,14047],{},[638,14087,14088],{},"4x 8TB HDDs",[638,14090,14056],{},[6072,14092,14093,14097,14100],{},[523,14094,14095],{},[584,14096,6189],{},[523,14098,14099],{},"For version 3, I'm planning to upgrade the workstation to have at least 64GB, and a newer, bigger AMD processor. A AMD Threadripper would be nice.\nIf it is affordable maybe even an AMD EPYC processor.",[523,14101,14102],{},"New GPUs and 40G network card are on the list of potential improvements for version 3. Though new GPUs and network cards will probably \"include\" a AMD Threadripper + a fitting Motherboard.",[613,14104,14106],{"id":14105},"monitors","Monitors",[668,14108,14109,14117],{},[638,14110,14111,14112],{},"4x ",[527,14113,14116],{"href":14114,"rel":14115},"http:\u002F\u002Fwww.lg.com\u002Fus\u002Fmonitors\u002Flg-29UM68-P-ultrawide-monitor",[531],"LG 29UM68-P 29\" 21:9 UltraWide LED monitors",[638,14118,14119,14120],{},"1x ",[527,14121,14124],{"href":14122,"rel":14123},"https:\u002F\u002Famazon.de\u002FGrundig-VLE-6220-Fernseher-Tuner\u002Fdp\u002FB0092K3C6I",[531],"Grundig 32 VLE 6220 BH 80 cm (32 Zoll)",[523,14126,14127,14128,14133],{},"A big shoutout to ",[527,14129,14132],{"href":14130,"rel":14131},"https:\u002F\u002Fwww.ricoo.eu\u002F",[531],"Ricoo Medientechnik"," as their monitor stands are awesome and not too expensive!",[523,14135,14136],{},"I'm using the following monitor stands from Ricoo:",[668,14138,14139,14146,14149],{},[638,14140,14119,14141],{},[527,14142,14145],{"href":14143,"rel":14144},"https:\u002F\u002Fwww.ricoo.eu\u002Fen\u002Fricoo-pc-screen-led-monitor-stand-ts3511-table-mount-for-2-monitors-monitor-brackets-tft-swivel-arm-monitor-mount-pivoting-monitor-fastener-monitor-rack-monitor-arm-compatible-with-vesa-100x100\u002Fa-11189\u002F",[531],"Ricoo Monitor Stand TS3511 Table Mount for 2 Monitors (TS3011)",[638,14147,14148],{},"2x Ricoo Desk Monitor Mount Arm (TS3011) (not available anymore, a newer model has been released)",[638,14150,14119,14151,14156],{},[527,14152,14155],{"href":14153,"rel":14154},"https:\u002F\u002Fwww.ricoo.eu\u002Fmonitor-tv-tischhalterung-haeoehenverstellbar-schwenkbar-neigbar-ts9711\u002Fa-11377\u002F",[531],"Ricoo Desk Monitor Mount Arm (TS9711)",[668,14157,14158],{},[638,14159,14160],{},"Note: It almost as good as the old TS3011 model. The thing that I would have wished for is to have an additional cable channel in the lower part of the arm.",[613,14162,14164],{"id":14163},"audio","Audio",[523,14166,14167],{},"Moving on to the audio equipment, I use the following pieces for audio input and output control:",[668,14169,14170,14204],{},[638,14171,14172,14173],{},"Input\n",[668,14174,14175,14182,14189,14197],{},[638,14176,14177],{},[527,14178,14181],{"href":14179,"rel":14180},"https:\u002F\u002Fwww.thomann.de\u002Fde\u002Frode_nt1a_complete_vocal_recording.htm",[531],"Rode NT1-A Complete Vocal Recording",[638,14183,14184],{},[527,14185,14188],{"href":14186,"rel":14187},"https:\u002F\u002Fmackie.com\u002Fproducts\u002Fprofxv3-professional-effects-mixers-usb",[531],"Mackie ProFX10v3",[638,14190,14191,14196],{},[527,14192,14195],{"href":14193,"rel":14194},"https:\u002F\u002Fwww.thomann.de\u002Fde\u002Fdbx_286_s.htm",[531],"DBX 286 S"," (Temporarily removed due to some audio issues)",[638,14198,14199],{},[527,14200,14203],{"href":14201,"rel":14202},"http:\u002F\u002Fwww.doukaudio.com\u002Fmini-21-in-12-out-35mm-stereo-audio-switcher-passive-selector-splitter-box-p0088.html",[531],"Mini 2(1)-IN-1(2)-OUT 3.5mm Stereo Audio Switcher Passive Selector Splitter Box MC102 - Nobsound",[638,14205,14206,14207],{},"Output\n",[668,14208,14209],{},[638,14210,14211,14216,14217,2006],{},[527,14212,14215],{"href":14213,"rel":14214},"https:\u002F\u002Fwww.thomann.de\u002Fgb\u002Fnumark_m_4_black.htm",[531],"Numark M 4"," (The link is to the black edition, I have the grey one. I got it cheap from ",[527,14218,14221],{"href":14219,"rel":14220},"https:\u002F\u002Fwww.rockshop.de\u002F",[531],"Rockshop.de",[523,14223,14224],{},"To \"blast\" music at the neighbors I have a very old 5.1 sound system, which sadly has a high level of noise when no sound is played.\nI'll probably replace the sound system with something better and check if it is worth to go for some USB sound cards.",[613,14226,14228],{"id":14227},"chair","Chair",[523,14230,14231,14232,14237],{},"A ",[527,14233,14236],{"href":14234,"rel":14235},"https:\u002F\u002Fwww.caseking.de\u002Fnoblechairs-epic-gaming-stuhl-schwarz-gold-gagc-038.html",[531],"noblechairs EPIC Gaming Stuhl - schwarz\u002Fgold"," because your arse and back will thank you for it.",[523,14239,14240],{},"Pretty good chair, though if you want to spend more go for a more expensive one with, e.g., \"limitless\" backrest and more features.",[535,14242,14244],{"id":14243},"home-automation-lighting","Home Automation (+ Lighting)",[523,14246,14247,14248,14253],{},"I'm using the awesome ",[527,14249,14252],{"href":14250,"rel":14251},"https:\u002F\u002Fwww.home-assistant.io\u002F",[531],"Home Assistant"," to control the lights in all rooms of my apartment.\nI also have temperature sensors and power measuring power plugs, etc to \"keep an eye\" on the apartment.",[523,14255,14256],{},[3069,14257],{"alt":14258,"src":14259},"Homeassistant Lighting Show Demo 1","\u002Fblog\u002F2020\u002Fmy-home-office-setup-v2\u002Fhomeassistant-lightning-show.jpg",[535,14261,12427],{"id":14262},"network",[613,14264,14266],{"id":14265},"network-map","Network Map",[523,14268,14269],{},"A network map showing the cable connections between the routers, switches, clients, etc.",[523,14271,14272],{},[3069,14273],{"alt":14274,"src":14275},"Network Map Diagram (click image to enlarge)","\u002Fblog\u002F2020\u002Fmy-home-office-setup-v2\u002Fhomenetwork-diagram.png",[523,14277,14278,856],{},[584,14279,14280],{},"Icon\u002F Image Credits",[668,14282,14283,14290,14298],{},[638,14284,14285],{},[527,14286,14289],{"href":14287,"rel":14288},"https:\u002F\u002Fcommons.wikimedia.org\u002Fwiki\u002FFile:RaspberryPi_4_Model_B.svg",[531],"\"Raspberry Pi 4 Model B\" diagram is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License by Jstrom99",[638,14291,14292,14297],{},[527,14293,14296],{"href":14294,"rel":14295},"https:\u002F\u002Fmikrotik.com\u002F",[531],"Mikrotik Product Images\u002F Icons"," are subject to Mikrotik's copyright.",[638,14299,14300,14301,1909],{},"Other icons\u002F diagrams are from ",[527,14302,14305],{"href":14303,"rel":14304},"https:\u002F\u002Fwww.yworks.com\u002Fproducts\u002Fyed",[531],"yEd Graph Editor by yworks",[523,14307,14308,14309,1909],{},"The Network Rack is shown in detail in the ",[527,14310,14312],{"href":14311},"#network-rack","next section below",[613,14314,14316],{"id":14315},"network-rack","Network Rack",[523,14318,14319],{},"The rack is 12 units (12U\u002F 12HE) high and 600mm in depth.",[523,14321,14322,14323,14328],{},"I have added some Noctua fans to the top\u002F \"roof\" of the track to have some air pushed into the rack. The fans are controlled by a NZXT Grid+ V3 (AC-GRDP3-M1; the ",[527,14324,14327],{"href":14325,"rel":14326},"https:\u002F\u002Fwww.nzxt.com\u002F",[531],"NZXT website"," does not list it anymore..).",[523,14330,14331,14332,14337],{},"I'm a huge ",[527,14333,14336],{"href":14334,"rel":14335},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FNeon_Genesis_Evangelion",[531],"Neon Genesis Evangelion and Evangelion Rebuilds"," fan so I put some cool stickers on the front.",[523,14339,14340],{},[3069,14341],{"alt":14342,"src":14343},"Network Rack Front Shot (a slightly older picture than from the front overview below)\" width=\"500px","\u002Fblog\u002F2020\u002Fmy-home-office-setup-v2\u002Fnetwork-rack-front-closed.jpg",[523,14345,14346],{},"The network rack provides up to 10G network and power to my PoE powered devices.",[6072,14348,14349,14353],{},[523,14350,14351],{},[584,14352,6189],{},[523,14354,14355],{},"Version 3 will probably have 40G network. The prices for used 40G network cards (and other equipment) are getting lower and lower every day.\nIn addition to that I want to be able to monitor the power used by the equipment, which is definitely high on the list to have for version 3.",[3126,14357,14359],{"id":14358},"rack-contents","Rack Contents",[668,14361,14362,14369,14391,14398,14405,14412,14444,14452],{},[638,14363,14364],{},[527,14365,14368],{"href":14366,"rel":14367},"https:\u002F\u002Fwww.thomann.de\u002Fintl\u002Fthe_t_racks_power_8_s.htm",[531],"the t.racks Power 8 S - thomann",[638,14370,14371,14376],{},[527,14372,14375],{"href":14373,"rel":14374},"https:\u002F\u002Fwww.thomann.de\u002Fintl\u002Fadam_hall_87551_ablage_19_1he.htm",[531],"Adam Hall 87551 Rack Tray 19\" 1HE - thomann",[668,14377,14378],{},[638,14379,14380,14381,14386],{},"A few ",[527,14382,14385],{"href":14383,"rel":14384},"https:\u002F\u002Fwww.raspberrypi.org\u002F",[531],"Raspberry PIs",[668,14387,14388],{},[638,14389,14390],{},"Used for several tasks like Home automation, Security, Monitoring, etc.",[638,14392,14393],{},[527,14394,14397],{"href":14395,"rel":14396},"https:\u002F\u002Fmikrotik.com\u002Fproduct\u002Frb4011igs_rm",[531],"Mikrotik RB4011iGS+RM",[638,14399,14400],{},[527,14401,14404],{"href":14402,"rel":14403},"https:\u002F\u002Fmikrotik.com\u002Fproduct\u002Fcrs309_1g_8s_in",[531],"Mikrotik CRS309-1G-8S+IN",[638,14406,14407],{},[527,14408,14411],{"href":14409,"rel":14410},"https:\u002F\u002Fmikrotik.com\u002Fproduct\u002Fcrs112_8p_4s_in",[531],"Mikrotik CRS112-8P-4S-IN",[638,14413,14414,14419],{},[527,14415,14418],{"href":14416,"rel":14417},"https:\u002F\u002Fwww.fs.com\u002Fproducts\u002F72910.html",[531],"1U 19\" Cable Management Panel with 5 Detachable Plastic D-rings and Lacing Bar on the Blank Rackmount Fiber Patch Panel",[668,14420,14421,14437],{},[638,14422,14423,14428],{},[527,14424,14427],{"href":14425,"rel":14426},"https:\u002F\u002Fwww.fs.com\u002Fproducts\u002F66602.html",[531],"6-Port FHD Multimedia Modular Panel with 6x Plastic Clips",[668,14429,14430],{},[638,14431,14432],{},[527,14433,14436],{"href":14434,"rel":14435},"https:\u002F\u002Fwww.fs.com\u002Fde\u002Fproducts\u002F41438.html",[531],"Cat6 RJ45 (8P8C) Unshielded Coupler Keystone Insert Module",[638,14438,14439],{},[527,14440,14443],{"href":14441,"rel":14442},"https:\u002F\u002Fwww.fs.com\u002Fde\u002Fproducts\u002F41998.html",[531],"12 port LC Duplex, 24 Fibers OM4 Multimode FHD Fiber Adapter Panel",[638,14445,14446,14451],{},[527,14447,14450],{"href":14448,"rel":14449},"https:\u002F\u002Fopnsense.org\u002F",[531],"OPNSense"," Router\u002F Firewall",[638,14453,14454],{},[527,14455,14458],{"href":14456,"rel":14457},"https:\u002F\u002Fwww.synology.com\u002Fen-global\u002Fcompany\u002Fnews\u002Farticle\u002FSynology_Presents_DiskStation_DS413",[531],"Synology DiskStation DS413",[523,14460,14461,14462,14467],{},"The cables are mostly from ",[527,14463,14466],{"href":14464,"rel":14465},"https:\u002F\u002Fwww.fs.com\u002F",[531],"FS.COM GmbH",". The \"icing on the cake\" is that some cables are custom lengths (e.g., 0.15-0.25m) so they fit just right and not have too much cable leftover.",[523,14469,14470],{},[3069,14471],{"alt":14472,"src":14473},"Network Rack Front Shot\" width=\"500px","\u002Fblog\u002F2020\u002Fmy-home-office-setup-v2\u002Fnetwork-rack-front.jpg",[3126,14475,14477],{"id":14476},"opnsense-firewall-router-specs","OPNSense Firewall\u002F Router Specs",[668,14479,14480,14488,14491,14494,14496,14499,14507],{},[638,14481,14482,14483],{},"CPU: Intel Celeron G4900\n",[668,14484,14485],{},[638,14486,14487],{},"Fan: Noctua NH-L9x65 CPU-Kühler",[638,14489,14490],{},"RAM: 2x Crucial Ballistix DDR4-2666 4GB",[638,14492,14493],{},"Mainboard: Gigabyte B360N WIFI",[638,14495,14039],{},[638,14497,14498],{},"PSU: Kolink SFX-350",[638,14500,14501,14502],{},"Sorage:\n",[668,14503,14504],{},[638,14505,14506],{},"1x 260GB SSD",[638,14508,14509],{},"Case: Kolink - Satellite Mini-ITX-\u002F Micro-ATX-Gehäuse - schwarz",[535,14511,14513],{"id":14512},"additional-equipment","Additional Equipment",[523,14515,14516,14517,14519],{},"From the ",[527,14518,14316],{"href":14311}," there is an empty \"pipe\" (German: Leerrohr) for cabling going through the wall and outside down to the basement.\nThe \"pipe\" holds fiber and coper cables inside, and \"zip tied\" to the outside of the \"pipe\" is a compressed air line to a compressor.",[523,14521,14522],{},"Having compressed air available for cleaning computers and other equipment is cool to have.",[535,14524,14526],{"id":14525},"summary","Summary",[523,14528,14529],{},"Well, what is there to say? I beefed up my setup even further to be able to achieve more and have fun getting to know the new hardware.",[523,14531,13967],{},{"title":743,"searchDepth":761,"depth":761,"links":14533},[14534,14535,14541,14542,14546,14547],{"id":13994,"depth":761,"text":13995},{"id":14001,"depth":761,"text":14002,"children":14536},[14537,14538,14539,14540],{"id":14017,"depth":769,"text":14018},{"id":14105,"depth":769,"text":14106},{"id":14163,"depth":769,"text":14164},{"id":14227,"depth":769,"text":14228},{"id":14243,"depth":761,"text":14244},{"id":14262,"depth":761,"text":12427,"children":14543},[14544,14545],{"id":14265,"depth":769,"text":14266},{"id":14315,"depth":769,"text":14316},{"id":14512,"depth":761,"text":14513},{"id":14525,"depth":761,"text":14526},"2020-01-10T11:58:26+01:00","In this post I'm showing you my current gaming and home office setup.",{"src":14014},{"tags":14552},[14553,14554,14555,14060,12427],"Home Office","Office","Computer","\u002Fblog\u002F2020\u002Fmy-home-office-setup-v2",{"title":13986,"description":14549},"3.blog\u002F2020\u002Fmy-home-office-setup-v2","8uLFhFDPEFxBP67MdhjMNL4PNBXqwalmEM5AYqnM5v0",{"id":14561,"title":14562,"authors":14563,"badge":518,"body":14566,"date":15149,"description":15150,"extension":2911,"image":15151,"meta":15153,"navigation":1254,"path":15156,"seo":15157,"stem":15158,"__hash__":15159},"posts\u002F3.blog\u002F2020\u002Frook-new-winds-in-the-v1-1-release.md","Rook: New Winds in the v1.1 release",[14564],{"name":514,"to":515,"avatar":14565},{"src":517},{"type":520,"value":14567,"toc":15137},[14568,14579,14582,14584,14588,14595,14603,14607,14615,14632,14635,14638,14642,14645,14649,14655,14658,14679,14682,14914,14917,14920,14928,14931,14937,14941,14944,14947,14955,14959,14962,14968,14975,14978,14981,14984,14991,14999,15003,15011,15019,15029,15032,15035,15037,15040,15043,15047,15050,15093,15096,15098,15102,15105,15134],[523,14569,14570,14571,14574,14575,14578],{},"This is a cross post of an older post from ",[527,14572,13818],{"href":13816,"rel":14573},[531],", be sure to checkout the ",[527,14576,13818],{"href":13816,"rel":14577},[531]," website.",[523,14580,14581],{},"Thanks to them for allowing me to write and publish the post on their blog!",[2979,14583],{},[535,14585,14587],{"id":14586},"preface","Preface",[523,14589,14590,14591,14594],{},"Rook is a storage orchestrator for Kubernetes using the operator pattern.\nThat means that Rook can run, e.g., Ceph, EdgeFS, Yugabyte and other persistence providers in a Kubernetes cluster.\nThis allows applications to create, e.g., a ",[567,14592,14593],{},"YBCluster"," object to get a YugabyteDB cluster to provide persistence for your applications in Kubernetes.",[523,14596,14597,14598,14602],{},"Be sure to check out Rook's website ",[527,14599,14601],{"href":13751,"rel":14600},[531],"Rook.io"," for more information.",[535,14604,14606],{"id":14605},"numbers","Numbers",[523,14608,14609,14610,856],{},"The Rook project is continuously growing, more contributors, more Twitter followers and the growing Slack member count.\nThe following are the numbers from the ",[527,14611,14614],{"href":14612,"rel":14613},"https:\u002F\u002Fblog.rook.io\u002Frook-v1-1-accelerating-storage-providers-5b9e8d5901d8",[531],"official Rook v1.1 release blog post",[668,14616,14617,14620,14623,14626,14629],{},[638,14618,14619],{},"5K to 6K+ Github stars",[638,14621,14622],{},"150 to 196 Contributors",[638,14624,14625],{},"40M to 74M+ Container downloads",[638,14627,14628],{},"3050 to 3700+ Twitter followers",[638,14630,14631],{},"1610 to 2200+ Slack members",[523,14633,14634],{},"Those numbers are awesome for the storage backends and Rook itself!",[523,14636,14637],{},"It is good to see the project grow in numbers, but also mature further in regards to governance, project charter and CNCF project graduation in the future.\nWith each release Rook is getting more boring. This is good, as especially newly introduced features get faster stable because of that.",[535,14639,14641],{"id":14640},"new-features-and-improvements","New Features and Improvements",[523,14643,14644],{},"Let's dive into some of the most outstanding features and improvements of the latest Rook 1.1 release.",[613,14646,14648],{"id":14647},"new-storage-provider-yugabyte-db","New Storage Provider: Yugabyte DB",[523,14650,14651,14652,1909],{},"In the latest Rook release version 1.1, Yugabyte DB joined the list of storage providers in the Rook project.\nBringing the total of storage providers to ",[584,14653,14654],{},"7",[523,14656,14657],{},"Below list contains all current storage providers which are integrated in Rook:",[668,14659,14660,14663,14665,14668,14671,14674,14676],{},[638,14661,14662],{},"Cassandra",[638,14664,427],{},[638,14666,14667],{},"CockroachDB",[638,14669,14670],{},"EdgeFS",[638,14672,14673],{},"Minio",[638,14675,457],{},[638,14677,14678],{},"Yugabyte DB",[523,14680,14681],{},"To show how easy it know is to create a Yugabyte DB cluster in Kubernetes, just look at the code snippet:",[738,14683,14685],{"className":740,"code":14684,"language":742,"meta":743,"style":743},"apiVersion: yugabytedb.rook.io\u002Fv1alpha1\nkind: YBCluster\nmetadata:\n  name: hello-ybdb-cluster\n  namespace: rook-yugabytedb\nspec:\n  master:\n    replicas: 3\n    volumeClaimTemplate:\n      [...]\n  tserver:\n    replicas: 3\n    network:\n      ports:\n        - name: yb-tserver-ui\n          port: 9000\n        - name: yb-tserver-rpc\n          port: 9100\n        - name: ycql\n          port: 9042\n        - name: yedis\n          port: 6379\n        - name: ysql\n          port: 5433\n    volumeClaimTemplate:\n      [...]\n",[567,14686,14687,14696,14705,14711,14720,14729,14735,14742,14752,14759,14768,14775,14783,14790,14797,14810,14820,14831,14840,14851,14860,14871,14880,14891,14900,14906],{"__ignoreMap":743},[747,14688,14689,14691,14693],{"class":749,"line":750},[747,14690,12949],{"class":753},[747,14692,856],{"class":757},[747,14694,14695],{"class":802}," yugabytedb.rook.io\u002Fv1alpha1\n",[747,14697,14698,14700,14702],{"class":749,"line":761},[747,14699,12963],{"class":753},[747,14701,856],{"class":757},[747,14703,14704],{"class":802}," YBCluster\n",[747,14706,14707,14709],{"class":749,"line":769},[747,14708,12973],{"class":753},[747,14710,758],{"class":757},[747,14712,14713,14715,14717],{"class":749,"line":776},[747,14714,12980],{"class":753},[747,14716,856],{"class":757},[747,14718,14719],{"class":802}," hello-ybdb-cluster\n",[747,14721,14722,14724,14726],{"class":749,"line":784},[747,14723,13231],{"class":753},[747,14725,856],{"class":757},[747,14727,14728],{"class":802}," rook-yugabytedb\n",[747,14730,14731,14733],{"class":749,"line":790},[747,14732,12990],{"class":753},[747,14734,758],{"class":757},[747,14736,14737,14740],{"class":749,"line":796},[747,14738,14739],{"class":753},"  master",[747,14741,758],{"class":757},[747,14743,14744,14747,14749],{"class":749,"line":806},[747,14745,14746],{"class":753},"    replicas",[747,14748,856],{"class":757},[747,14750,14751],{"class":1895}," 3\n",[747,14753,14754,14757],{"class":749,"line":814},[747,14755,14756],{"class":753},"    volumeClaimTemplate",[747,14758,758],{"class":757},[747,14760,14761,14764,14766],{"class":749,"line":822},[747,14762,14763],{"class":757},"      [",[747,14765,5685],{"class":1895},[747,14767,4268],{"class":757},[747,14769,14770,14773],{"class":749,"line":830},[747,14771,14772],{"class":753},"  tserver",[747,14774,758],{"class":757},[747,14776,14777,14779,14781],{"class":749,"line":836},[747,14778,14746],{"class":753},[747,14780,856],{"class":757},[747,14782,14751],{"class":1895},[747,14784,14785,14788],{"class":749,"line":842},[747,14786,14787],{"class":753},"    network",[747,14789,758],{"class":757},[747,14791,14792,14795],{"class":749,"line":850},[747,14793,14794],{"class":753},"      ports",[747,14796,758],{"class":757},[747,14798,14799,14802,14805,14807],{"class":749,"line":863},[747,14800,14801],{"class":757},"        -",[747,14803,14804],{"class":753}," name",[747,14806,856],{"class":757},[747,14808,14809],{"class":802}," yb-tserver-ui\n",[747,14811,14812,14815,14817],{"class":749,"line":869},[747,14813,14814],{"class":753},"          port",[747,14816,856],{"class":757},[747,14818,14819],{"class":1895}," 9000\n",[747,14821,14822,14824,14826,14828],{"class":749,"line":877},[747,14823,14801],{"class":757},[747,14825,14804],{"class":753},[747,14827,856],{"class":757},[747,14829,14830],{"class":802}," yb-tserver-rpc\n",[747,14832,14833,14835,14837],{"class":749,"line":1015},[747,14834,14814],{"class":753},[747,14836,856],{"class":757},[747,14838,14839],{"class":1895}," 9100\n",[747,14841,14842,14844,14846,14848],{"class":749,"line":1021},[747,14843,14801],{"class":757},[747,14845,14804],{"class":753},[747,14847,856],{"class":757},[747,14849,14850],{"class":802}," ycql\n",[747,14852,14853,14855,14857],{"class":749,"line":1027},[747,14854,14814],{"class":753},[747,14856,856],{"class":757},[747,14858,14859],{"class":1895}," 9042\n",[747,14861,14862,14864,14866,14868],{"class":749,"line":1033},[747,14863,14801],{"class":757},[747,14865,14804],{"class":753},[747,14867,856],{"class":757},[747,14869,14870],{"class":802}," yedis\n",[747,14872,14873,14875,14877],{"class":749,"line":1039},[747,14874,14814],{"class":753},[747,14876,856],{"class":757},[747,14878,14879],{"class":1895}," 6379\n",[747,14881,14882,14884,14886,14888],{"class":749,"line":1054},[747,14883,14801],{"class":757},[747,14885,14804],{"class":753},[747,14887,856],{"class":757},[747,14889,14890],{"class":802}," ysql\n",[747,14892,14893,14895,14897],{"class":749,"line":1060},[747,14894,14814],{"class":753},[747,14896,856],{"class":757},[747,14898,14899],{"class":1895}," 5433\n",[747,14901,14902,14904],{"class":749,"line":1066},[747,14903,14756],{"class":753},[747,14905,758],{"class":757},[747,14907,14908,14910,14912],{"class":749,"line":1081},[747,14909,14763],{"class":757},[747,14911,5685],{"class":1895},[747,14913,4268],{"class":757},[523,14915,14916],{},"Yep, just a few lines of code and the Rook Yugabyte DB operator will take care of creating everything needed for a Yugabyte DB cluster.\nThat is the magic that the Operator Pattern in Kubernetes brings. Applications like that are destined to have an operator with CustomResourceDefinitions to make life easier for the Development and Operations teams in Kubernetes.",[523,14918,14919],{},"One more thing to note is that you can technically run a Rook Ceph or EdgeFS Cluster in your Kubernetes and run, e.g., Yugabyte DB, Minio, and so on, on top of that storage provider.",[523,14921,14922,14923,1909],{},"If you want to know more about Yugabyte DB Rook integration, checkout their blog post ",[527,14924,14927],{"href":14925,"rel":14926},"https:\u002F\u002Fblog.yugabyte.com\u002Frook-operator-announcement\u002F",[531],"Yugabyte DB Blog - Announcing the New Rook Operator for Yugabyte DB",[613,14929,427],{"id":14930},"ceph",[523,14932,14933],{},[3069,14934],{"alt":14935,"src":14936},"Ceph Logo","\u002Fblog\u002F2020\u002Frook-new-winds-in-the-v1-1-release\u002Fceph_logo_standard_rgb_120411_fa.png",[3126,14938,14940],{"id":14939},"csi-the-new-default-for-provisioning-and-mounting-storage","CSI the new default for Provisioning and Mounting Storage",[523,14942,14943],{},"In previous releases the default was to use the Rook Flexvolume driver for provisioning and mounting of Ceph storage.\nIn comparision with the now default Ceph CSI driver, the Flexvolume is lacking features, like dynamic provisioning of PersistentVolumeClaim for CephFS (filesystem storage).",[523,14945,14946],{},"The Ceph CSI driver brings many improvements and the mentioned dynamic provisioning feature for CephFS PersistentVolumeClaims. There is a lesser used features that is not implemented in the Ceph CSI driver yet, mounting erasure-coded block storage, but the Ceph CSI team is working on implement this feature to bring it on the same level as the Flexvolume.",[523,14948,14949,14950,1909],{},"For the impatient people that want to get the CephFS dynamic provisioning for their cluster and\u002F or get started with Rook in general, checkout the ",[527,14951,14954],{"href":14952,"rel":14953},"https:\u002F\u002Frook.io\u002Fdocs\u002Frook\u002Fv1.1\u002F",[531],"Rook v1.1 Documentation",[3126,14956,14958],{"id":14957},"osds-can-now-run-on-persistentvolumeclaims","OSDs can now run on PersistentVolumeClaims",[523,14960,14961],{},"Yep, you read that right, Ceph OSDs (data stores) can now run on PersistentVolumeClaims.\nThis finally gives many people an option to reliably run in cloud environments (e.g., Azure, AWS, Google Cloud) with their Rook Ceph cluster setups.",[523,14963,14964,14967],{},[584,14965,14966],{},"Fun fact",": This technically enables one to run a Rook Ceph Cluster on PersistentVolumes from another Rook Ceph cluster.",[523,14969,14970,14971,1909],{},"Let's continue on that fun fact in ",[527,14972,14974],{"href":14973},"#rook-ceph-in-rook-ceph-in-rook-ceph","Rook Ceph in Rook Ceph in Rook Ceph …",[3126,14976,14974],{"id":14977},"rook-ceph-in-rook-ceph-in-rook-ceph",[523,14979,14980],{},"I will soon be doing an experiment, in which I'll be running a Rook Ceph Cluster on top of another Rook Ceph Cluster. \"Wrapping\" a Rook Ceph Cluster once in another Rook Ceph Cluster is boring though, so the experiment will be to wrap a Rook Ceph Cluster on top of as many other warpped Rook Ceph Cluster as possible.",[613,14982,14670],{"id":14983},"edgefs",[523,14985,14986,14987,14990],{},"Has accomplished a milestone in the Rook project by being the second storage provider to release their CRDs as stable ",[567,14988,14989],{},"v1",".\nThat is awesome to see, but not the only big accomplishment for the v1.1 release.",[523,14992,14993,14994,1909],{},"For a general roundup of all that is new in EdgeFS, checkout ",[527,14995,14998],{"href":14996,"rel":14997},"https:\u002F\u002Fmedium.com\u002Fedgefs\u002Fkubernetes-rook-edgefs-1-1-released-452799283fce",[531],"Kubernetes Rook EdgeFS 1.1 Released - EdgeFS",[3126,15000,15002],{"id":15001},"multi-homed-network","Multi homed network",[523,15004,15005,15006,1909],{},"EdgeFS is the first to implement multi (homed) network. Their initial integration efforts are done with ",[527,15007,15010],{"href":15008,"rel":15009},"https:\u002F\u002Fgithub.com\u002Fintel\u002Fmultus-cni",[531],"Intel's project Multus CNI",[523,15012,15013,15014,11500],{},"This is thanks to the Google Summer of Code (GSoC) participant ",[527,15015,15018],{"href":15016,"rel":15017},"https:\u002F\u002Fapp.slack.com\u002Fteam\u002FUHQJJL2MA",[531],"@giovanism",[523,15020,15021,15025,15028],{},[3069,15022],{"alt":15023,"src":15024},"Example of Frontend vs. Backend isolation in Rook EdgeFS with multi-homed networks","\u002Fblog\u002F2020\u002Frook-new-winds-in-the-v1-1-release\u002Fedgefs-network-isolation.png",[584,15026,15027],{},"Source",": EdgeFS v1.1 Release Blog Post",[523,15030,15031],{},"In their v1.1 blog post, from which the diagram was taken, contains a performance benchmarks that shows that multi homed network can improve the performance of the storage.\nBesides the performance improvements, depending on the network setup this can even allow the storage to be more resilient as it would be, e.g., unaffected by application network outages.",[523,15033,15034],{},"This is a huge thing to happen in the Rook project and hopefully soon to be seen to be implemented in the Rook Ceph Cluster CRD as well.",[535,15036,14526],{"id":14525},[523,15038,15039],{},"The Rook project is getting boring.\nThere are still many important things to further work and improve on. One burning topic is disaster recovery, which is pretty much a complex manual process right now. That process just \"screams\" to be \"automated\" to a certain aspect, to remove the human factor as much as possible.",[523,15041,15042],{},"Join the in-cluster storage revolution, Rook on!",[535,15044,15046],{"id":15045},"how-to-get-involved","How to get involved",[523,15048,15049],{},"If you are interested in Rook, don’t hesitate to connect with the Rook community and project using the below ways.",[668,15051,15052,15059,15066,15073,15079,15086],{},[638,15053,15054],{},[527,15055,15058],{"href":15056,"rel":15057},"https:\u002F\u002Ftwitter.com\u002Frook_io",[531],"Twitter",[638,15060,15061],{},[527,15062,15065],{"href":15063,"rel":15064},"https:\u002F\u002Frook-io.slack.com\u002F",[531],"Slack",[638,15067,15068],{},[527,15069,15072],{"href":15070,"rel":15071},"https:\u002F\u002Fgithub.com\u002Frook\u002Frook",[531],"Contribute to Rook",[638,15074,15075],{},[527,15076,15078],{"href":13751,"rel":15077},[531],"Website",[638,15080,15081],{},[527,15082,15085],{"href":15083,"rel":15084},"https:\u002F\u002Fgroups.google.com\u002Fforum\u002F#!forum\u002Frook-dev",[531],"Mailing List",[638,15087,15088],{},[527,15089,15092],{"href":15090,"rel":15091},"https:\u002F\u002Fgithub.com\u002Frook\u002Frook\u002F#community-meeting",[531],"Community Meetings",[523,15094,15095],{},"Besides the typical social media channels, Slack and so on, should you attend the KubeCon + CloudNativeCon North America 2019 be sure to visit the CNCF Project Pavilion.",[2979,15097],{},[535,15099,15101],{"id":15100},"other-articles-about-rook","Other articles about Rook",[523,15103,15104],{},"If you are interested in reading other articles about the Rook project, be sure to checkout the following links:",[668,15106,15107,15113,15119,15124,15129],{},[638,15108,15109],{},[527,15110,15111],{"href":15111,"rel":15112},"http:\u002F\u002Fthe-report.cloud\u002Frook-more-than-ceph",[531],[638,15114,15115],{},[527,15116,15117],{"href":15117,"rel":15118},"http:\u002F\u002Fthe-report.cloud\u002Frook-v1-0-adds-support-for-ceph-nautilus-edgefs-and-nfs-operator",[531],[638,15120,15121],{},[527,15122,14612],{"href":14612,"rel":15123},[531],[638,15125,15126],{},[527,15127,14996],{"href":14996,"rel":15128},[531],[638,15130,15131],{},[527,15132,14925],{"href":14925,"rel":15133},[531],[2890,15135,15136],{},"html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":743,"searchDepth":761,"depth":761,"links":15138},[15139,15140,15141,15146,15147,15148],{"id":14586,"depth":761,"text":14587},{"id":14605,"depth":761,"text":14606},{"id":14640,"depth":761,"text":14641,"children":15142},[15143,15144,15145],{"id":14647,"depth":769,"text":14648},{"id":14930,"depth":769,"text":427},{"id":14983,"depth":769,"text":14670},{"id":14525,"depth":761,"text":14526},{"id":15045,"depth":761,"text":15046},{"id":15100,"depth":761,"text":15101},"2020-01-06T15:20:10+01:00","Cross post of an older post I published on The Cloud Report blog about the Rook v1.1 release.",{"src":15152},"\u002Fblog\u002F2020\u002Frook-new-winds-in-the-v1-1-release\u002Frook-v1-1-blog-cover.png",{"tags":15154},[15155,465,427],"Articles","\u002Fblog\u002F2020\u002Frook-new-winds-in-the-v1-1-release",{"title":14562,"description":15150},"3.blog\u002F2020\u002Frook-new-winds-in-the-v1-1-release","YEJR94_NLeaFAaU1ECHziFLfk16Y_13DK275JaaEN04",{"id":15161,"title":15162,"authors":15163,"badge":518,"body":15166,"date":18149,"description":18150,"extension":2911,"image":518,"meta":18151,"navigation":1254,"path":18153,"seo":18154,"stem":18155,"__hash__":18156},"posts\u002F3.blog\u002F2020\u002Frunning-owncloud-in-kubernetes-with-rook-ceph-storage-part-2.md","Running ownCloud in Kubernetes with Rook Ceph Storage - Part 2",[15164],{"name":514,"to":515,"avatar":15165},{"src":517},{"type":520,"value":15167,"toc":18128},[15168,15182,15184,15186,15190,15193,15197,15200,15218,15228,15238,15242,15246,15252,15255,15277,15289,15310,15317,15320,15393,15396,15407,15411,15414,15441,15457,15461,15468,15482,15486,15489,15516,15519,15648,15657,15661,15664,15672,15689,15707,15710,15713,15977,15981,15984,15992,16008,16015,16018,16045,16048,16052,16055,16062,16078,16081,16158,16162,16165,16253,16260,16314,16317,16567,16572,16631,16641,16643,16649,16936,16960,16983,16987,16990,16993,16996,17065,17068,17110,17113,17133,17140,17213,17224,17227,17231,17234,17237,17291,17297,17305,17308,17328,17335,17488,17491,17494,17497,17504,17518,17529,17554,17565,17579,17582,17976,17982,17993,17996,18000,18004,18023,18026,18034,18038,18062,18066,18069,18073,18078,18081,18095,18099,18104,18117,18120,18123,18125],[523,15169,15170,15171,15176,15177,1909],{},"This a cross post of a post I wrote for the ",[527,15172,15175],{"href":15173,"rel":15174},"https:\u002F\u002Fowncloud.org\u002Fnews\u002F",[531],"ownCloud Blog",", the original post can be found here: ",[527,15178,15181],{"href":15179,"rel":15180},"https:\u002F\u002Fowncloud.org\u002Fnews\u002Frunning-owncloud-in-kubernetes-with-rook-ceph-storage-step-by-step\u002F",[531],"Running ownCloud in Kubernetes With Rook Ceph Storage – Step by Step",[523,15183,14581],{},[2979,15185],{},[535,15187,15189],{"id":15188},"preparations","Preparations",[523,15191,15192],{},"Let's prepare for the Kubernetes madness!",[613,15194,15196],{"id":15195},"kubernetes-cluster-access","Kubernetes Cluster Access",[523,15198,15199],{},"As written in the first part, it is expected that you have (admin) access to a Kubernetes cluster already.",[523,15201,15202,15203,714,15208,587,15213,1909],{},"If you don't have a Kubernetes cluster, you can try using the following projects ",[527,15204,15207],{"href":15205,"rel":15206},"https:\u002F\u002Fgithub.com\u002Fxetys\u002Fhetzner-kube",[531],"xetys\u002Fhetzner-kube on GitHub",[527,15209,15212],{"href":15210,"rel":15211},"https:\u002F\u002Fkubespray.io\u002F",[531],"Kubespray",[527,15214,15217],{"href":15215,"rel":15216},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fsetup\u002F",[531],"others (Kubernetes documentation)",[523,15219,15220,15221,15224,15225,1909],{},"minikube is not enough when started with the default resources, be sure to give minikube extra resources otherwise you will run into problems! Be sure to add the following flags to the ",[567,15222,15223],{},"minikube start"," command: ",[567,15226,15227],{},"--memory=4096 --cpus=3 --disk-size=40g",[523,15229,15230,15231,15234,15235,15237],{},"You should have ",[567,15232,15233],{},"cluster-admin"," access to the Kubernetes cluster! Other access can also work, but due to the nature of objects that are created along the way it is easier to have the ",[567,15236,15233],{}," access.",[613,15239,15241],{"id":15240},"kubernetes-cluster","Kubernetes Cluster",[3126,15243,15245],{"id":15244},"ingress-controller","Ingress Controller",[523,15247,15248,15251],{},[584,15249,15250],{},"WARNING"," Only follow this section, if your Kubernetes cluster does not have an Ingress controller yet.",[523,15253,15254],{},"We are going to install the Kubernetes NGINX Ingress Controller.",[738,15256,15258],{"className":1621,"code":15257,"language":1623,"meta":743,"style":743},"# Taken from https:\u002F\u002Fgithub.com\u002Fkubernetes\u002Fingress-nginx\u002Fblob\u002Fmaster\u002Fdeploy\u002Fstatic\u002Fmandatory.yaml\nkubectl apply -f ingress-nginx\u002F\n",[567,15259,15260,15265],{"__ignoreMap":743},[747,15261,15262],{"class":749,"line":750},[747,15263,15264],{"class":772},"# Taken from https:\u002F\u002Fgithub.com\u002Fkubernetes\u002Fingress-nginx\u002Fblob\u002Fmaster\u002Fdeploy\u002Fstatic\u002Fmandatory.yaml\n",[747,15266,15267,15270,15272,15274],{"class":749,"line":761},[747,15268,15269],{"class":1630},"kubectl",[747,15271,5180],{"class":802},[747,15273,1934],{"class":802},[747,15275,15276],{"class":802}," ingress-nginx\u002F\n",[523,15278,15279,15280,15283,15284,1909],{},"The instructions shown here are for an environment without ",[567,15281,15282],{},"LoadBalancer"," Service type support (e.g., bare metal, \"normal\" VM provider, not cloud), for installation instructions for other environments checkout ",[527,15285,15288],{"href":15286,"rel":15287},"https:\u002F\u002Fkubernetes.github.io\u002Fingress-nginx\u002Fdeploy\u002F",[531],"Installation Guide - NGINX Ingress Controller",[738,15290,15292],{"className":1621,"code":15291,"language":1623,"meta":743,"style":743},"# Taken from # Taken from https:\u002F\u002Fgithub.com\u002Fkubernetes\u002Fingress-nginx\u002Fblob\u002Fmaster\u002Fdeploy\u002Fstatic\u002Fprovider\u002Fbaremetal\u002Fservice-nodeport.yaml\nkubectl apply -f ingress-nginx\u002Fservice-nodeport.yaml\n",[567,15293,15294,15299],{"__ignoreMap":743},[747,15295,15296],{"class":749,"line":750},[747,15297,15298],{"class":772},"# Taken from # Taken from https:\u002F\u002Fgithub.com\u002Fkubernetes\u002Fingress-nginx\u002Fblob\u002Fmaster\u002Fdeploy\u002Fstatic\u002Fprovider\u002Fbaremetal\u002Fservice-nodeport.yaml\n",[747,15300,15301,15303,15305,15307],{"class":749,"line":761},[747,15302,15269],{"class":1630},[747,15304,5180],{"class":802},[747,15306,1934],{"class":802},[747,15308,15309],{"class":802}," ingress-nginx\u002Fservice-nodeport.yaml\n",[523,15311,15312,15313,15316],{},"As these are bare metal installation instructions, the NGINX Ingress controller will be available through a Service of type ",[567,15314,15315],{},"NodePort",". This Service type exposes one or more ports on all Nodes in the Kubernetes cluster.",[523,15318,15319],{},"To get that port run:",[738,15321,15323],{"className":1621,"code":15322,"language":1623,"meta":743,"style":743},"$ kubectl get -n ingress-nginx service ingress-nginx\nNAME            TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE\ningress-nginx   NodePort   10.108.254.160   \u003Cnone>        80:30512\u002FTCP,443:30243\u002FTCP   23m\n",[567,15324,15325,15344,15368],{"__ignoreMap":743},[747,15326,15327,15329,15331,15333,15335,15338,15341],{"class":749,"line":750},[747,15328,1919],{"class":1630},[747,15330,1922],{"class":802},[747,15332,1951],{"class":802},[747,15334,1928],{"class":802},[747,15336,15337],{"class":802}," ingress-nginx",[747,15339,15340],{"class":802}," service",[747,15342,15343],{"class":802}," ingress-nginx\n",[747,15345,15346,15348,15351,15354,15357,15359,15361,15363,15365],{"class":749,"line":761},[747,15347,2230],{"class":1630},[747,15349,15350],{"class":802},"            TYPE",[747,15352,15353],{"class":802},"       CLUSTER-IP",[747,15355,15356],{"class":802},"       EXTERNAL-IP",[747,15358,1997],{"class":802},[747,15360,2000],{"class":757},[747,15362,2003],{"class":1630},[747,15364,2006],{"class":757},[747,15366,15367],{"class":802},"                      AGE\n",[747,15369,15370,15373,15376,15379,15381,15383,15385,15387,15390],{"class":749,"line":769},[747,15371,15372],{"class":1630},"ingress-nginx",[747,15374,15375],{"class":802},"   NodePort",[747,15377,15378],{"class":1895},"   10.108.254.160",[747,15380,2026],{"class":757},[747,15382,2029],{"class":802},[747,15384,2032],{"class":1640},[747,15386,2035],{"class":757},[747,15388,15389],{"class":802},"        80:30512\u002FTCP,443:30243\u002FTCP",[747,15391,15392],{"class":802},"   23m\n",[523,15394,15395],{},"In that output you can see the NodePorts for HTTP and HTTPS on which you can connect to the NGINX Ingress controller and ownCloud later.",[523,15397,15398,15399,15401,15402,1909],{},"Though as written you probably want to look into a more \"solid\" way to expose the NGINX Ingress controller(s), for bare metal where there is no Kubernetes LoadBalancer integration one can consider using ",[567,15400,12759],{}," option for that: ",[527,15403,15406],{"href":15404,"rel":15405},"https:\u002F\u002Fkubernetes.github.io\u002Fingress-nginx\u002Fdeploy\u002Fbaremetal\u002F#via-the-host-network",[531],"Bare-metal considerations - NGINX Ingress Controller",[3126,15408,15410],{"id":15409},"namespaces","Namespaces",[523,15412,15413],{},"Through the whole installation we will create 4 Namespaces:",[668,15415,15416,15426,15432],{},[638,15417,15418,15421,15422,3052],{},[567,15419,15420],{},"rook-ceph"," - For the Rook run Ceph cluster + the Rook Ceph operator (will be created in ",[527,15423,15425],{"href":15424},"#rook-ceph-storage","Rook Ceph storage",[638,15427,15428,15431],{},[567,15429,15430],{},"owncloud"," - For ownCloud and the other operators, such as Zalando's Postgres Operator and KubeDB for Redis.",[638,15433,15434,15436,15437,3052],{},[567,15435,15372],{}," - If you don't have an Ingress controller running yet, the namespace is used for the Ingress NGINX controller (it is already created in the ",[527,15438,15440],{"href":15439},"#ingress-controller","Ingress Controller steps",[738,15442,15444],{"className":1621,"code":15443,"language":1623,"meta":743,"style":743},"kubectl create -f namespaces.yaml\n",[567,15445,15446],{"__ignoreMap":743},[747,15447,15448,15450,15452,15454],{"class":749,"line":750},[747,15449,15269],{"class":1630},[747,15451,1925],{"class":802},[747,15453,1934],{"class":802},[747,15455,15456],{"class":802}," namespaces.yaml\n",[535,15458,15460],{"id":15459},"rook-ceph-storage","Rook Ceph Storage",[523,15462,15463,15464,1909],{},"Now on to running Ceph in Kubernetes, using the ",[527,15465,15467],{"href":13751,"rel":15466},[531],"Rook.io project",[523,15469,15470,15471,15474,15475,15477,15478,15481],{},"In the following sections make sure to use the available ",[567,15472,15473],{},"-test"," suffixed files if you have less than 3 Nodes which are available to any application\u002F Pod (e.g., depending on your cluster the masters are not available for Pods).\n(You can change that, for that be sure to dig into the ",[567,15476,13313],{}," object's ",[567,15479,15480],{},"spec.placement.tolerations"," and the Operator environment variables for the discover and agent daemons. Running application Pods on the masters is not recommended though)",[613,15483,15485],{"id":15484},"operator","Operator",[523,15487,15488],{},"The operator will take care of starting up the Ceph components one by one and also preparing of disks and health checking.",[738,15490,15492],{"className":1621,"code":15491,"language":1623,"meta":743,"style":743},"kubectl create -f rook-ceph\u002Fcommon.yaml\nkubectl create -f rook-ceph\u002Foperator.yaml\n",[567,15493,15494,15505],{"__ignoreMap":743},[747,15495,15496,15498,15500,15502],{"class":749,"line":750},[747,15497,15269],{"class":1630},[747,15499,1925],{"class":802},[747,15501,1934],{"class":802},[747,15503,15504],{"class":802}," rook-ceph\u002Fcommon.yaml\n",[747,15506,15507,15509,15511,15513],{"class":749,"line":761},[747,15508,15269],{"class":1630},[747,15510,1925],{"class":802},[747,15512,1934],{"class":802},[747,15514,15515],{"class":802}," rook-ceph\u002Foperator.yaml\n",[523,15517,15518],{},"You can check on the Pods to see how it looks:",[738,15520,15522],{"className":1621,"code":15521,"language":1623,"meta":743,"style":743},"$ kubectl get -n rook-ceph pod\nNAME                                  READY   STATUS    RESTARTS   AGE\nrook-ceph-agent-cbrgv                 1\u002F1     Running   0          90s\nrook-ceph-agent-wfznr                 1\u002F1     Running   0          90s\nrook-ceph-agent-zhgg7                 1\u002F1     Running   0          90s\nrook-ceph-operator-6897f5c696-j724m   1\u002F1     Running   0          2m18s\nrook-discover-jg798                   1\u002F1     Running   0          90s\nrook-discover-kfxc8                   1\u002F1     Running   0          90s\nrook-discover-qbhfs                   1\u002F1     Running   0          90s\n",[567,15523,15524,15540,15554,15569,15582,15595,15609,15622,15635],{"__ignoreMap":743},[747,15525,15526,15528,15530,15532,15534,15537],{"class":749,"line":750},[747,15527,1919],{"class":1630},[747,15529,1922],{"class":802},[747,15531,1951],{"class":802},[747,15533,1928],{"class":802},[747,15535,15536],{"class":802}," rook-ceph",[747,15538,15539],{"class":802}," pod\n",[747,15541,15542,15544,15547,15549,15551],{"class":749,"line":761},[747,15543,2230],{"class":1630},[747,15545,15546],{"class":802},"                                  READY",[747,15548,2236],{"class":802},[747,15550,2239],{"class":802},[747,15552,15553],{"class":802},"   AGE\n",[747,15555,15556,15559,15562,15564,15566],{"class":749,"line":769},[747,15557,15558],{"class":1630},"rook-ceph-agent-cbrgv",[747,15560,15561],{"class":802},"                 1\u002F1",[747,15563,2271],{"class":802},[747,15565,2274],{"class":1895},[747,15567,15568],{"class":802},"          90s\n",[747,15570,15571,15574,15576,15578,15580],{"class":749,"line":776},[747,15572,15573],{"class":1630},"rook-ceph-agent-wfznr",[747,15575,15561],{"class":802},[747,15577,2271],{"class":802},[747,15579,2274],{"class":1895},[747,15581,15568],{"class":802},[747,15583,15584,15587,15589,15591,15593],{"class":749,"line":784},[747,15585,15586],{"class":1630},"rook-ceph-agent-zhgg7",[747,15588,15561],{"class":802},[747,15590,2271],{"class":802},[747,15592,2274],{"class":1895},[747,15594,15568],{"class":802},[747,15596,15597,15600,15602,15604,15606],{"class":749,"line":790},[747,15598,15599],{"class":1630},"rook-ceph-operator-6897f5c696-j724m",[747,15601,2268],{"class":802},[747,15603,2271],{"class":802},[747,15605,2274],{"class":1895},[747,15607,15608],{"class":802},"          2m18s\n",[747,15610,15611,15614,15616,15618,15620],{"class":749,"line":796},[747,15612,15613],{"class":1630},"rook-discover-jg798",[747,15615,2345],{"class":802},[747,15617,2271],{"class":802},[747,15619,2274],{"class":1895},[747,15621,15568],{"class":802},[747,15623,15624,15627,15629,15631,15633],{"class":749,"line":806},[747,15625,15626],{"class":1630},"rook-discover-kfxc8",[747,15628,2345],{"class":802},[747,15630,2271],{"class":802},[747,15632,2274],{"class":1895},[747,15634,15568],{"class":802},[747,15636,15637,15640,15642,15644,15646],{"class":749,"line":814},[747,15638,15639],{"class":1630},"rook-discover-qbhfs",[747,15641,2345],{"class":802},[747,15643,2271],{"class":802},[747,15645,2274],{"class":1895},[747,15647,15568],{"class":802},[523,15649,8764,15650,15653,15654,15656],{},[567,15651,15652],{},"rook-discover-*"," Pods are each one on each Node of your Kubernetes cluster, as they are discovering the disks of the Nodes so the operator can plan the actions for a given ",[567,15655,13313],{}," object which comes up next.",[613,15658,15660],{"id":15659},"ceph-cluster","Ceph Cluster",[523,15662,15663],{},"This is the definition of Ceph cluster that will be created in Kubernetes. It contains the lists and options on which disks to use and on which Nodes.",[523,15665,15666,15667,1909],{},"If you wanna see some example CephCluster objects to see what is possible, be sure to checkout ",[527,15668,15671],{"href":15669,"rel":15670},"https:\u002F\u002Frook.io\u002Fdocs\u002Frook\u002Fv1.0\u002Fceph-cluster-crd.html",[531],"Rook v1.0 Documentation - CephCluster CRD",[523,15673,15674,15677,15678,15681,15682,15684,15685,15688],{},[584,15675,15676],{},"INFO"," Use the ",[567,15679,15680],{},"cluster-test.yaml"," when your Kubernetes cluster has less than 3 schedulable Nodes (e.g., minikube)!\nWhen using the ",[567,15683,15680],{}," only one ",[567,15686,15687],{},"mon"," is started. If that mon is down for whatever reason, the Ceph Cluster will come to a halt to prevent any data \"corruption\".",[738,15690,15692],{"className":1621,"code":15691,"language":1623,"meta":743,"style":743},"$ kubectl create -f rook-ceph\u002Fcluster.yaml\n",[567,15693,15694],{"__ignoreMap":743},[747,15695,15696,15698,15700,15702,15704],{"class":749,"line":750},[747,15697,1919],{"class":1630},[747,15699,1922],{"class":802},[747,15701,1925],{"class":802},[747,15703,1934],{"class":802},[747,15705,15706],{"class":802}," rook-ceph\u002Fcluster.yaml\n",[523,15708,15709],{},"This will now cause the operator to start the Ceph cluster after the specifications in the CephCluster object.",[523,15711,15712],{},"To see which Pods have already been created by the operator, you can run (output example from a three node cluster):",[738,15714,15716],{"className":1621,"code":15715,"language":1623,"meta":743,"style":743},"$ kubectl get -n rook-ceph pod\nNAME                                                     READY   STATUS      RESTARTS   AGE\nrook-ceph-agent-cbrgv                                    1\u002F1     Running     0          11m\nrook-ceph-agent-wfznr                                    1\u002F1     Running     0          11m\nrook-ceph-agent-zhgg7                                    1\u002F1     Running     0          11m\nrook-ceph-mgr-a-77fc54c489-66mpd                         1\u002F1     Running     0          6m45s\nrook-ceph-mon-a-68b94cd66-m48lm                          1\u002F1     Running     0          8m6s\nrook-ceph-mon-b-7b679476f-mc7wj                          1\u002F1     Running     0          8m\nrook-ceph-mon-c-b5c468c94-f8knt                          1\u002F1     Running     0          7m54s\nrook-ceph-operator-6897f5c696-j724m                      1\u002F1     Running     0          11m\nrook-ceph-osd-0-5c8d8fcdd-m4gl7                          1\u002F1     Running     0          5m55s\nrook-ceph-osd-1-67bfb7d647-vzmpv                         1\u002F1     Running     0          5m56s\nrook-ceph-osd-2-c8c55548f-ws8sl                          1\u002F1     Running     0          5m11s\nrook-ceph-osd-prepare-owncloudrookceph-worker-01-svvz9   0\u002F2     Completed   0          6m7s\nrook-ceph-osd-prepare-owncloudrookceph-worker-02-mhvf2   0\u002F2     Completed   0          6m7s\nrook-ceph-osd-prepare-owncloudrookceph-worker-03-nt2gs   0\u002F2     Completed   0          6m7s\nrook-discover-jg798                                      1\u002F1     Running     0          11m\nrook-discover-kfxc8                                      1\u002F1     Running     0          11m\nrook-discover-qbhfs                                      1\u002F1     Running     0          11m\n",[567,15717,15718,15732,15746,15761,15773,15785,15800,15815,15829,15843,15856,15870,15884,15898,15914,15927,15940,15953,15965],{"__ignoreMap":743},[747,15719,15720,15722,15724,15726,15728,15730],{"class":749,"line":750},[747,15721,1919],{"class":1630},[747,15723,1922],{"class":802},[747,15725,1951],{"class":802},[747,15727,1928],{"class":802},[747,15729,15536],{"class":802},[747,15731,15539],{"class":802},[747,15733,15734,15736,15739,15741,15744],{"class":749,"line":761},[747,15735,2230],{"class":1630},[747,15737,15738],{"class":802},"                                                     READY",[747,15740,2236],{"class":802},[747,15742,15743],{"class":802},"      RESTARTS",[747,15745,15553],{"class":802},[747,15747,15748,15750,15753,15755,15758],{"class":749,"line":769},[747,15749,15558],{"class":1630},[747,15751,15752],{"class":802},"                                    1\u002F1",[747,15754,2271],{"class":802},[747,15756,15757],{"class":1895},"     0",[747,15759,15760],{"class":802},"          11m\n",[747,15762,15763,15765,15767,15769,15771],{"class":749,"line":776},[747,15764,15573],{"class":1630},[747,15766,15752],{"class":802},[747,15768,2271],{"class":802},[747,15770,15757],{"class":1895},[747,15772,15760],{"class":802},[747,15774,15775,15777,15779,15781,15783],{"class":749,"line":784},[747,15776,15586],{"class":1630},[747,15778,15752],{"class":802},[747,15780,2271],{"class":802},[747,15782,15757],{"class":1895},[747,15784,15760],{"class":802},[747,15786,15787,15790,15793,15795,15797],{"class":749,"line":790},[747,15788,15789],{"class":1630},"rook-ceph-mgr-a-77fc54c489-66mpd",[747,15791,15792],{"class":802},"                         1\u002F1",[747,15794,2271],{"class":802},[747,15796,15757],{"class":1895},[747,15798,15799],{"class":802},"          6m45s\n",[747,15801,15802,15805,15808,15810,15812],{"class":749,"line":796},[747,15803,15804],{"class":1630},"rook-ceph-mon-a-68b94cd66-m48lm",[747,15806,15807],{"class":802},"                          1\u002F1",[747,15809,2271],{"class":802},[747,15811,15757],{"class":1895},[747,15813,15814],{"class":802},"          8m6s\n",[747,15816,15817,15820,15822,15824,15826],{"class":749,"line":806},[747,15818,15819],{"class":1630},"rook-ceph-mon-b-7b679476f-mc7wj",[747,15821,15807],{"class":802},[747,15823,2271],{"class":802},[747,15825,15757],{"class":1895},[747,15827,15828],{"class":802},"          8m\n",[747,15830,15831,15834,15836,15838,15840],{"class":749,"line":814},[747,15832,15833],{"class":1630},"rook-ceph-mon-c-b5c468c94-f8knt",[747,15835,15807],{"class":802},[747,15837,2271],{"class":802},[747,15839,15757],{"class":1895},[747,15841,15842],{"class":802},"          7m54s\n",[747,15844,15845,15847,15850,15852,15854],{"class":749,"line":822},[747,15846,15599],{"class":1630},[747,15848,15849],{"class":802},"                      1\u002F1",[747,15851,2271],{"class":802},[747,15853,15757],{"class":1895},[747,15855,15760],{"class":802},[747,15857,15858,15861,15863,15865,15867],{"class":749,"line":830},[747,15859,15860],{"class":1630},"rook-ceph-osd-0-5c8d8fcdd-m4gl7",[747,15862,15807],{"class":802},[747,15864,2271],{"class":802},[747,15866,15757],{"class":1895},[747,15868,15869],{"class":802},"          5m55s\n",[747,15871,15872,15875,15877,15879,15881],{"class":749,"line":836},[747,15873,15874],{"class":1630},"rook-ceph-osd-1-67bfb7d647-vzmpv",[747,15876,15792],{"class":802},[747,15878,2271],{"class":802},[747,15880,15757],{"class":1895},[747,15882,15883],{"class":802},"          5m56s\n",[747,15885,15886,15889,15891,15893,15895],{"class":749,"line":842},[747,15887,15888],{"class":1630},"rook-ceph-osd-2-c8c55548f-ws8sl",[747,15890,15807],{"class":802},[747,15892,2271],{"class":802},[747,15894,15757],{"class":1895},[747,15896,15897],{"class":802},"          5m11s\n",[747,15899,15900,15903,15906,15909,15911],{"class":749,"line":850},[747,15901,15902],{"class":1630},"rook-ceph-osd-prepare-owncloudrookceph-worker-01-svvz9",[747,15904,15905],{"class":802},"   0\u002F2",[747,15907,15908],{"class":802},"     Completed",[747,15910,2274],{"class":1895},[747,15912,15913],{"class":802},"          6m7s\n",[747,15915,15916,15919,15921,15923,15925],{"class":749,"line":863},[747,15917,15918],{"class":1630},"rook-ceph-osd-prepare-owncloudrookceph-worker-02-mhvf2",[747,15920,15905],{"class":802},[747,15922,15908],{"class":802},[747,15924,2274],{"class":1895},[747,15926,15913],{"class":802},[747,15928,15929,15932,15934,15936,15938],{"class":749,"line":869},[747,15930,15931],{"class":1630},"rook-ceph-osd-prepare-owncloudrookceph-worker-03-nt2gs",[747,15933,15905],{"class":802},[747,15935,15908],{"class":802},[747,15937,2274],{"class":1895},[747,15939,15913],{"class":802},[747,15941,15942,15944,15947,15949,15951],{"class":749,"line":877},[747,15943,15613],{"class":1630},[747,15945,15946],{"class":802},"                                      1\u002F1",[747,15948,2271],{"class":802},[747,15950,15757],{"class":1895},[747,15952,15760],{"class":802},[747,15954,15955,15957,15959,15961,15963],{"class":749,"line":1015},[747,15956,15626],{"class":1630},[747,15958,15946],{"class":802},[747,15960,2271],{"class":802},[747,15962,15757],{"class":1895},[747,15964,15760],{"class":802},[747,15966,15967,15969,15971,15973,15975],{"class":749,"line":1021},[747,15968,15639],{"class":1630},[747,15970,15946],{"class":802},[747,15972,2271],{"class":802},[747,15974,15757],{"class":1895},[747,15976,15760],{"class":802},[613,15978,15980],{"id":15979},"block-storage-rbd","Block storage (RBD)",[523,15982,15983],{},"Before creating the CephFS filesystem, let's create a block storage pool with a StorageClass.\nThe StorageClass is for the PostgreSQL and if you want even the Redis cluster.",[523,15985,15986,15677,15988,15991],{},[584,15987,15676],{},[567,15989,15990],{},"storageclass-test.yaml"," when your Kubernetes cluster has less than 3 schedulable Nodes!",[738,15993,15995],{"className":1621,"code":15994,"language":1623,"meta":743,"style":743},"kubectl create -f rook-ceph\u002Fstorageclass.yaml\n",[567,15996,15997],{"__ignoreMap":743},[747,15998,15999,16001,16003,16005],{"class":749,"line":750},[747,16000,15269],{"class":1630},[747,16002,1925],{"class":802},[747,16004,1934],{"class":802},[747,16006,16007],{"class":802}," rook-ceph\u002Fstorageclass.yaml\n",[523,16009,16010,16011,1909],{},"In case of a block storage Pool there are no additional Pods that will be started, we'll verify that the block storage Pool has been created in the ",[527,16012,16014],{"href":16013},"#toolbox","Toolbox section",[523,16016,16017],{},"One more thing to do is, to set the created StorageClass as default in the Kubernetes cluster by running the following command:",[738,16019,16021],{"className":1621,"code":16020,"language":1623,"meta":743,"style":743},"kubectl patch storageclass rook-ceph-block -p '{\"metadata\": {\"annotations\":{\"storageclass.kubernetes.io\u002Fis-default-class\":\"true\"}}}'\n",[567,16022,16023],{"__ignoreMap":743},[747,16024,16025,16027,16030,16033,16036,16038,16040,16043],{"class":749,"line":750},[747,16026,15269],{"class":1630},[747,16028,16029],{"class":802}," patch",[747,16031,16032],{"class":802}," storageclass",[747,16034,16035],{"class":802}," rook-ceph-block",[747,16037,7094],{"class":802},[747,16039,3537],{"class":757},[747,16041,16042],{"class":802},"{\"metadata\": {\"annotations\":{\"storageclass.kubernetes.io\u002Fis-default-class\":\"true\"}}}",[747,16044,13042],{"class":757},[523,16046,16047],{},"Now you are ready to move onto the storage for the actual data to be stored in ownCloud!",[613,16049,16051],{"id":16050},"cephfs","CephFS",[523,16053,16054],{},"CephFS is the filesystem that Ceph offers, with its POSIX compliance it is a perfect fit to be used with ownCloud.",[523,16056,16057,15677,16059,15991],{},[584,16058,15676],{},[567,16060,16061],{},"filesystem-test.yaml",[738,16063,16065],{"className":1621,"code":16064,"language":1623,"meta":743,"style":743},"kubectl create -f rook-ceph\u002Ffilesystem.yaml\n",[567,16066,16067],{"__ignoreMap":743},[747,16068,16069,16071,16073,16075],{"class":749,"line":750},[747,16070,15269],{"class":1630},[747,16072,1925],{"class":802},[747,16074,1934],{"class":802},[747,16076,16077],{"class":802}," rook-ceph\u002Ffilesystem.yaml\n",[523,16079,16080],{},"Creation of the CephFS will cause, so called MDS daemons, MDS Pods to be started.",[738,16082,16084],{"className":1621,"code":16083,"language":1623,"meta":743,"style":743},"$ kubectl get -n rook-ceph pod\nNAME                                    READY   STATUS      RESTARTS   AGE\n[...]\nrook-ceph-mds-myfs-a-747b75bdc7-9nzwx                    1\u002F1     Running     0          11s\nrook-ceph-mds-myfs-b-76b9fcc8cc-md8bz                    1\u002F1     Running     0          10s\n[...]\n",[567,16085,16086,16100,16113,16121,16136,16150],{"__ignoreMap":743},[747,16087,16088,16090,16092,16094,16096,16098],{"class":749,"line":750},[747,16089,1919],{"class":1630},[747,16091,1922],{"class":802},[747,16093,1951],{"class":802},[747,16095,1928],{"class":802},[747,16097,15536],{"class":802},[747,16099,15539],{"class":802},[747,16101,16102,16104,16107,16109,16111],{"class":749,"line":761},[747,16103,2230],{"class":1630},[747,16105,16106],{"class":802},"                                    READY",[747,16108,2236],{"class":802},[747,16110,15743],{"class":802},[747,16112,15553],{"class":802},[747,16114,16115,16117,16119],{"class":749,"line":769},[747,16116,4253],{"class":757},[747,16118,5685],{"class":1640},[747,16120,4268],{"class":757},[747,16122,16123,16126,16129,16131,16133],{"class":749,"line":776},[747,16124,16125],{"class":1630},"rook-ceph-mds-myfs-a-747b75bdc7-9nzwx",[747,16127,16128],{"class":802},"                    1\u002F1",[747,16130,2271],{"class":802},[747,16132,15757],{"class":1895},[747,16134,16135],{"class":802},"          11s\n",[747,16137,16138,16141,16143,16145,16147],{"class":749,"line":784},[747,16139,16140],{"class":1630},"rook-ceph-mds-myfs-b-76b9fcc8cc-md8bz",[747,16142,16128],{"class":802},[747,16144,2271],{"class":802},[747,16146,15757],{"class":1895},[747,16148,16149],{"class":802},"          10s\n",[747,16151,16152,16154,16156],{"class":749,"line":790},[747,16153,4253],{"class":757},[747,16155,5685],{"class":1640},[747,16157,4268],{"class":757},[613,16159,16161],{"id":16160},"toolbox","Toolbox",[523,16163,16164],{},"This will create a Pod which will allow us to run Ceph commands. It will be use to quickly check the Ceph clusters status.",[738,16166,16168],{"className":1621,"code":16167,"language":1623,"meta":743,"style":743},"$ kubectl create -f rook-ceph\u002Ftoolbox.yaml\n# Wait for the Pod to be `Running`\n$ kubectl get -n rook-ceph pod -l \"app=rook-ceph-tools\"\nNAME                                    READY   STATUS      RESTARTS   AGE\n[...]\nrook-ceph-tools-5966446d7b-nrw5n                         1\u002F1     Running     0          10s\n[...]\n",[567,16169,16170,16183,16188,16212,16224,16232,16245],{"__ignoreMap":743},[747,16171,16172,16174,16176,16178,16180],{"class":749,"line":750},[747,16173,1919],{"class":1630},[747,16175,1922],{"class":802},[747,16177,1925],{"class":802},[747,16179,1934],{"class":802},[747,16181,16182],{"class":802}," rook-ceph\u002Ftoolbox.yaml\n",[747,16184,16185],{"class":749,"line":761},[747,16186,16187],{"class":772},"# Wait for the Pod to be `Running`\n",[747,16189,16190,16192,16194,16196,16198,16200,16202,16205,16207,16210],{"class":749,"line":769},[747,16191,1919],{"class":1630},[747,16193,1922],{"class":802},[747,16195,1951],{"class":802},[747,16197,1928],{"class":802},[747,16199,15536],{"class":802},[747,16201,2219],{"class":802},[747,16203,16204],{"class":802}," -l",[747,16206,969],{"class":757},[747,16208,16209],{"class":802},"app=rook-ceph-tools",[747,16211,975],{"class":757},[747,16213,16214,16216,16218,16220,16222],{"class":749,"line":776},[747,16215,2230],{"class":1630},[747,16217,16106],{"class":802},[747,16219,2236],{"class":802},[747,16221,15743],{"class":802},[747,16223,15553],{"class":802},[747,16225,16226,16228,16230],{"class":749,"line":784},[747,16227,4253],{"class":757},[747,16229,5685],{"class":1640},[747,16231,4268],{"class":757},[747,16233,16234,16237,16239,16241,16243],{"class":749,"line":790},[747,16235,16236],{"class":1630},"rook-ceph-tools-5966446d7b-nrw5n",[747,16238,15792],{"class":802},[747,16240,2271],{"class":802},[747,16242,15757],{"class":1895},[747,16244,16149],{"class":802},[747,16246,16247,16249,16251],{"class":749,"line":796},[747,16248,4253],{"class":757},[747,16250,5685],{"class":1640},[747,16252,4268],{"class":757},[523,16254,16255,16256,16259],{},"Now use ",[567,16257,16258],{},"kubectl exec"," to enter the Rook Ceph Toolbox Pod:",[738,16261,16263],{"className":1621,"code":16262,"language":1623,"meta":743,"style":743},"kubectl exec -n rook-ceph -it $(kubectl get -n rook-ceph pod -l \"app=rook-ceph-tools\" -o jsonpath='{.items[0].metadata.name}') bash\n",[567,16264,16265],{"__ignoreMap":743},[747,16266,16267,16269,16271,16273,16275,16277,16280,16282,16284,16286,16288,16290,16292,16294,16296,16298,16300,16303,16305,16308,16310,16312],{"class":749,"line":750},[747,16268,15269],{"class":1630},[747,16270,2586],{"class":802},[747,16272,1928],{"class":802},[747,16274,15536],{"class":802},[747,16276,4072],{"class":802},[747,16278,16279],{"class":757}," $(",[747,16281,15269],{"class":1630},[747,16283,1951],{"class":802},[747,16285,1928],{"class":802},[747,16287,15536],{"class":802},[747,16289,2219],{"class":802},[747,16291,16204],{"class":802},[747,16293,969],{"class":757},[747,16295,16209],{"class":802},[747,16297,3892],{"class":757},[747,16299,2222],{"class":802},[747,16301,16302],{"class":802}," jsonpath=",[747,16304,3543],{"class":757},[747,16306,16307],{"class":802},"{.items[0].metadata.name}",[747,16309,3543],{"class":757},[747,16311,2006],{"class":757},[747,16313,4078],{"class":802},[523,16315,16316],{},"In the Rook Ceph Toolbox Pod, run the following command to get the Ceph cluster health status (example output from a 7 Node Kubernetes Rook Ceph cluster):",[738,16318,16320],{"className":1621,"code":16319,"language":1623,"meta":743,"style":743},"$ ceph -s\n cluster:\n   id:     f8492cd9-3d14-432c-b681-6f73425d6851\n   health: HEALTH_OK\n\n services:\n   mon: 3 daemons, quorum c,b,a\n   mgr: a(active)\n   mds: repl-2-1-2\u002F2\u002F2 up  {0=repl-2-1-c=up:active,1=repl-2-1-b=up:active}, 2 up:standby-replay\n   osd: 7 osds: 7 up, 7 in\n\n data:\n   pools:   3 pools, 300 pgs\n   objects: 1.41 M objects, 4.0 TiB\n   usage:   8.2 TiB used, 17 TiB\u002F 25 TiB avail\n   pgs:     300 active+clean\n\n io:\n   client:   6.2 KiB\u002Fs rd, 1.5 MiB\u002Fs wr, 4 op\u002Fs rd, 140 op\u002Fs wr\n\n",[567,16321,16322,16332,16337,16345,16353,16357,16362,16379,16393,16413,16434,16438,16443,16460,16480,16508,16519,16523,16528],{"__ignoreMap":743},[747,16323,16324,16326,16329],{"class":749,"line":750},[747,16325,1919],{"class":1630},[747,16327,16328],{"class":802}," ceph",[747,16330,16331],{"class":802}," -s\n",[747,16333,16334],{"class":749,"line":761},[747,16335,16336],{"class":1630}," cluster:\n",[747,16338,16339,16342],{"class":749,"line":769},[747,16340,16341],{"class":1630},"   id:",[747,16343,16344],{"class":802},"     f8492cd9-3d14-432c-b681-6f73425d6851\n",[747,16346,16347,16350],{"class":749,"line":776},[747,16348,16349],{"class":1630},"   health:",[747,16351,16352],{"class":802}," HEALTH_OK\n",[747,16354,16355],{"class":749,"line":784},[747,16356,1255],{"emptyLinePlaceholder":1254},[747,16358,16359],{"class":749,"line":790},[747,16360,16361],{"class":1630}," services:\n",[747,16363,16364,16367,16370,16373,16376],{"class":749,"line":796},[747,16365,16366],{"class":1630},"   mon:",[747,16368,16369],{"class":1895}," 3",[747,16371,16372],{"class":802}," daemons,",[747,16374,16375],{"class":802}," quorum",[747,16377,16378],{"class":802}," c,b,a\n",[747,16380,16381,16384,16386,16388,16391],{"class":749,"line":806},[747,16382,16383],{"class":1630},"   mgr:",[747,16385,3930],{"class":802},[747,16387,2000],{"class":757},[747,16389,16390],{"class":1630},"active",[747,16392,3600],{"class":757},[747,16394,16395,16398,16401,16404,16407,16410],{"class":749,"line":814},[747,16396,16397],{"class":1630},"   mds:",[747,16399,16400],{"class":802}," repl-2-1-2\u002F2\u002F2",[747,16402,16403],{"class":802}," up",[747,16405,16406],{"class":802},"  {0=repl-2-1-c=up:active,1=repl-2-1-b=up:active},",[747,16408,16409],{"class":1895}," 2",[747,16411,16412],{"class":802}," up:standby-replay\n",[747,16414,16415,16418,16421,16424,16426,16429,16431],{"class":749,"line":822},[747,16416,16417],{"class":1630},"   osd:",[747,16419,16420],{"class":1895}," 7",[747,16422,16423],{"class":802}," osds:",[747,16425,16420],{"class":1895},[747,16427,16428],{"class":802}," up,",[747,16430,16420],{"class":1895},[747,16432,16433],{"class":802}," in\n",[747,16435,16436],{"class":749,"line":830},[747,16437,1255],{"emptyLinePlaceholder":1254},[747,16439,16440],{"class":749,"line":836},[747,16441,16442],{"class":1630}," data:\n",[747,16444,16445,16448,16451,16454,16457],{"class":749,"line":842},[747,16446,16447],{"class":1630},"   pools:",[747,16449,16450],{"class":1895},"   3",[747,16452,16453],{"class":802}," pools,",[747,16455,16456],{"class":1895}," 300",[747,16458,16459],{"class":802}," pgs\n",[747,16461,16462,16465,16468,16471,16474,16477],{"class":749,"line":850},[747,16463,16464],{"class":1630},"   objects:",[747,16466,16467],{"class":1895}," 1.41",[747,16469,16470],{"class":802}," M",[747,16472,16473],{"class":802}," objects,",[747,16475,16476],{"class":1895}," 4.0",[747,16478,16479],{"class":802}," TiB\n",[747,16481,16482,16485,16488,16491,16494,16497,16500,16503,16505],{"class":749,"line":863},[747,16483,16484],{"class":1630},"   usage:",[747,16486,16487],{"class":1895},"   8.2",[747,16489,16490],{"class":802}," TiB",[747,16492,16493],{"class":802}," used,",[747,16495,16496],{"class":1895}," 17",[747,16498,16499],{"class":802}," TiB\u002F",[747,16501,16502],{"class":1895}," 25",[747,16504,16490],{"class":802},[747,16506,16507],{"class":802}," avail\n",[747,16509,16510,16513,16516],{"class":749,"line":869},[747,16511,16512],{"class":1630},"   pgs:",[747,16514,16515],{"class":1895},"     300",[747,16517,16518],{"class":802}," active+clean\n",[747,16520,16521],{"class":749,"line":877},[747,16522,1255],{"emptyLinePlaceholder":1254},[747,16524,16525],{"class":749,"line":1015},[747,16526,16527],{"class":1630}," io:\n",[747,16529,16530,16533,16536,16539,16542,16545,16548,16551,16554,16557,16559,16562,16564],{"class":749,"line":1021},[747,16531,16532],{"class":1630},"   client:",[747,16534,16535],{"class":1895},"   6.2",[747,16537,16538],{"class":802}," KiB\u002Fs",[747,16540,16541],{"class":802}," rd,",[747,16543,16544],{"class":1895}," 1.5",[747,16546,16547],{"class":802}," MiB\u002Fs",[747,16549,16550],{"class":802}," wr,",[747,16552,16553],{"class":1895}," 4",[747,16555,16556],{"class":802}," op\u002Fs",[747,16558,16541],{"class":802},[747,16560,16561],{"class":1895}," 140",[747,16563,16556],{"class":802},[747,16565,16566],{"class":802}," wr\n",[523,16568,16569,16570,856],{},"You can also get it by using ",[567,16571,15269],{},[738,16573,16575],{"className":1621,"code":16574,"language":1623,"meta":743,"style":743},"$ kubectl get -n rook-ceph cephcluster rook-ceph\nNAME        DATADIRHOSTPATH   MONCOUNT   AGE   STATE     HEALTH\nrook-ceph   \u002Fmnt\u002Fsda1\u002Frook    3          14m   Created   HEALTH_OK\n",[567,16576,16577,16594,16612],{"__ignoreMap":743},[747,16578,16579,16581,16583,16585,16587,16589,16592],{"class":749,"line":750},[747,16580,1919],{"class":1630},[747,16582,1922],{"class":802},[747,16584,1951],{"class":802},[747,16586,1928],{"class":802},[747,16588,15536],{"class":802},[747,16590,16591],{"class":802}," cephcluster",[747,16593,13226],{"class":802},[747,16595,16596,16598,16601,16604,16606,16609],{"class":749,"line":761},[747,16597,2230],{"class":1630},[747,16599,16600],{"class":802},"        DATADIRHOSTPATH",[747,16602,16603],{"class":802},"   MONCOUNT",[747,16605,2242],{"class":802},[747,16607,16608],{"class":802},"   STATE",[747,16610,16611],{"class":802},"     HEALTH\n",[747,16613,16614,16616,16619,16622,16625,16628],{"class":749,"line":769},[747,16615,15420],{"class":1630},[747,16617,16618],{"class":802},"   \u002Fmnt\u002Fsda1\u002Frook",[747,16620,16621],{"class":1895},"    3",[747,16623,16624],{"class":802},"          14m",[747,16626,16627],{"class":802},"   Created",[747,16629,16630],{"class":802},"   HEALTH_OK\n",[523,16632,16633,16634,16636,16637,16640],{},"That even shows you some additional information directly through ",[567,16635,15269],{}," instead of having to read the ",[567,16638,16639],{},"ceph -s"," output.",[613,16642,14526],{"id":14525},[523,16644,16645,16646,16648],{},"This is how it should look Pod wise now in your ",[567,16647,15420],{}," Namespace (example output from a 3 Node Kubernetes cluster):",[738,16650,16652],{"className":1621,"code":16651,"language":1623,"meta":743,"style":743},"$ kubectl get -n rook-ceph pod\nNAME                                                     READY   STATUS      RESTARTS   AGE\nrook-ceph-agent-cbrgv                                    1\u002F1     Running     0          15m\nrook-ceph-agent-wfznr                                    1\u002F1     Running     0          15m\nrook-ceph-agent-zhgg7                                    1\u002F1     Running     0          15m\nrook-ceph-mds-myfs-a-747b75bdc7-9nzwx                    1\u002F1     Running     0          42s\nrook-ceph-mds-myfs-b-76b9fcc8cc-md8bz                    1\u002F1     Running     0          41s\nrook-ceph-mgr-a-77fc54c489-66mpd                         1\u002F1     Running     0          11m\nrook-ceph-mon-a-68b94cd66-m48lm                          1\u002F1     Running     0          12m\nrook-ceph-mon-b-7b679476f-mc7wj                          1\u002F1     Running     0          2m22s\nrook-ceph-mon-c-b5c468c94-f8knt                          1\u002F1     Running     0          2m6s\nrook-ceph-operator-6897f5c696-j724m                      1\u002F1     Running     0          16m\nrook-ceph-osd-0-5c8d8fcdd-m4gl7                          1\u002F1     Running     0          10m\nrook-ceph-osd-1-67bfb7d647-vzmpv                         1\u002F1     Running     0          10m\nrook-ceph-osd-2-c8c55548f-ws8sl                          1\u002F1     Running     0          9m48s\nrook-ceph-osd-prepare-owncloudrookceph-worker-01-5xpqk   0\u002F2     Completed   0          73s\nrook-ceph-osd-prepare-owncloudrookceph-worker-02-xnl8p   0\u002F2     Completed   0          70s\nrook-ceph-osd-prepare-owncloudrookceph-worker-03-2qggs   0\u002F2     Completed   0          68s\nrook-ceph-tools-5966446d7b-nrw5n                         1\u002F1     Running     0          8s\nrook-discover-jg798                                      1\u002F1     Running     0          15m\nrook-discover-kfxc8                                      1\u002F1     Running     0          15m\nrook-discover-qbhfs                                      1\u002F1     Running     0          15m\n",[567,16653,16654,16668,16680,16693,16705,16717,16730,16743,16755,16768,16781,16794,16807,16820,16832,16845,16859,16873,16887,16900,16912,16924],{"__ignoreMap":743},[747,16655,16656,16658,16660,16662,16664,16666],{"class":749,"line":750},[747,16657,1919],{"class":1630},[747,16659,1922],{"class":802},[747,16661,1951],{"class":802},[747,16663,1928],{"class":802},[747,16665,15536],{"class":802},[747,16667,15539],{"class":802},[747,16669,16670,16672,16674,16676,16678],{"class":749,"line":761},[747,16671,2230],{"class":1630},[747,16673,15738],{"class":802},[747,16675,2236],{"class":802},[747,16677,15743],{"class":802},[747,16679,15553],{"class":802},[747,16681,16682,16684,16686,16688,16690],{"class":749,"line":769},[747,16683,15558],{"class":1630},[747,16685,15752],{"class":802},[747,16687,2271],{"class":802},[747,16689,15757],{"class":1895},[747,16691,16692],{"class":802},"          15m\n",[747,16694,16695,16697,16699,16701,16703],{"class":749,"line":776},[747,16696,15573],{"class":1630},[747,16698,15752],{"class":802},[747,16700,2271],{"class":802},[747,16702,15757],{"class":1895},[747,16704,16692],{"class":802},[747,16706,16707,16709,16711,16713,16715],{"class":749,"line":784},[747,16708,15586],{"class":1630},[747,16710,15752],{"class":802},[747,16712,2271],{"class":802},[747,16714,15757],{"class":1895},[747,16716,16692],{"class":802},[747,16718,16719,16721,16723,16725,16727],{"class":749,"line":790},[747,16720,16125],{"class":1630},[747,16722,16128],{"class":802},[747,16724,2271],{"class":802},[747,16726,15757],{"class":1895},[747,16728,16729],{"class":802},"          42s\n",[747,16731,16732,16734,16736,16738,16740],{"class":749,"line":796},[747,16733,16140],{"class":1630},[747,16735,16128],{"class":802},[747,16737,2271],{"class":802},[747,16739,15757],{"class":1895},[747,16741,16742],{"class":802},"          41s\n",[747,16744,16745,16747,16749,16751,16753],{"class":749,"line":806},[747,16746,15789],{"class":1630},[747,16748,15792],{"class":802},[747,16750,2271],{"class":802},[747,16752,15757],{"class":1895},[747,16754,15760],{"class":802},[747,16756,16757,16759,16761,16763,16765],{"class":749,"line":814},[747,16758,15804],{"class":1630},[747,16760,15807],{"class":802},[747,16762,2271],{"class":802},[747,16764,15757],{"class":1895},[747,16766,16767],{"class":802},"          12m\n",[747,16769,16770,16772,16774,16776,16778],{"class":749,"line":822},[747,16771,15819],{"class":1630},[747,16773,15807],{"class":802},[747,16775,2271],{"class":802},[747,16777,15757],{"class":1895},[747,16779,16780],{"class":802},"          2m22s\n",[747,16782,16783,16785,16787,16789,16791],{"class":749,"line":830},[747,16784,15833],{"class":1630},[747,16786,15807],{"class":802},[747,16788,2271],{"class":802},[747,16790,15757],{"class":1895},[747,16792,16793],{"class":802},"          2m6s\n",[747,16795,16796,16798,16800,16802,16804],{"class":749,"line":836},[747,16797,15599],{"class":1630},[747,16799,15849],{"class":802},[747,16801,2271],{"class":802},[747,16803,15757],{"class":1895},[747,16805,16806],{"class":802},"          16m\n",[747,16808,16809,16811,16813,16815,16817],{"class":749,"line":842},[747,16810,15860],{"class":1630},[747,16812,15807],{"class":802},[747,16814,2271],{"class":802},[747,16816,15757],{"class":1895},[747,16818,16819],{"class":802},"          10m\n",[747,16821,16822,16824,16826,16828,16830],{"class":749,"line":850},[747,16823,15874],{"class":1630},[747,16825,15792],{"class":802},[747,16827,2271],{"class":802},[747,16829,15757],{"class":1895},[747,16831,16819],{"class":802},[747,16833,16834,16836,16838,16840,16842],{"class":749,"line":863},[747,16835,15888],{"class":1630},[747,16837,15807],{"class":802},[747,16839,2271],{"class":802},[747,16841,15757],{"class":1895},[747,16843,16844],{"class":802},"          9m48s\n",[747,16846,16847,16850,16852,16854,16856],{"class":749,"line":869},[747,16848,16849],{"class":1630},"rook-ceph-osd-prepare-owncloudrookceph-worker-01-5xpqk",[747,16851,15905],{"class":802},[747,16853,15908],{"class":802},[747,16855,2274],{"class":1895},[747,16857,16858],{"class":802},"          73s\n",[747,16860,16861,16864,16866,16868,16870],{"class":749,"line":877},[747,16862,16863],{"class":1630},"rook-ceph-osd-prepare-owncloudrookceph-worker-02-xnl8p",[747,16865,15905],{"class":802},[747,16867,15908],{"class":802},[747,16869,2274],{"class":1895},[747,16871,16872],{"class":802},"          70s\n",[747,16874,16875,16878,16880,16882,16884],{"class":749,"line":1015},[747,16876,16877],{"class":1630},"rook-ceph-osd-prepare-owncloudrookceph-worker-03-2qggs",[747,16879,15905],{"class":802},[747,16881,15908],{"class":802},[747,16883,2274],{"class":1895},[747,16885,16886],{"class":802},"          68s\n",[747,16888,16889,16891,16893,16895,16897],{"class":749,"line":1021},[747,16890,16236],{"class":1630},[747,16892,15792],{"class":802},[747,16894,2271],{"class":802},[747,16896,15757],{"class":1895},[747,16898,16899],{"class":802},"          8s\n",[747,16901,16902,16904,16906,16908,16910],{"class":749,"line":1027},[747,16903,15613],{"class":1630},[747,16905,15946],{"class":802},[747,16907,2271],{"class":802},[747,16909,15757],{"class":1895},[747,16911,16692],{"class":802},[747,16913,16914,16916,16918,16920,16922],{"class":749,"line":1033},[747,16915,15626],{"class":1630},[747,16917,15946],{"class":802},[747,16919,2271],{"class":802},[747,16921,15757],{"class":1895},[747,16923,16692],{"class":802},[747,16925,16926,16928,16930,16932,16934],{"class":749,"line":1039},[747,16927,15639],{"class":1630},[747,16929,15946],{"class":802},[747,16931,2271],{"class":802},[747,16933,15757],{"class":1895},[747,16935,16692],{"class":802},[523,16937,16938,16939,16941,16942,16945,16946,10313,16949,16952,16953,16955,16956,16959],{},"The important thing is that the ",[567,16940,16639],{}," output or the ",[567,16943,16944],{},"kubectl get cephcluster"," output shows that the ",[567,16947,16948],{},"health",[567,16950,16951],{},"HEALTH_OK"," and that you have OSD Pods running (",[567,16954,16639],{}," output line: ",[567,16957,16958],{},"osd: 3 osds: 3 up, 3 in"," (where 3 is basically the amount of OSD Pods).",[523,16961,16962,16963,16966,16967,16970,16971,16974,16975,16978,16979,16982],{},"Should you not have any OSD Pod, make sure all your Nodes are ",[567,16964,16965],{},"Ready"," and schedulable (e.g., no taints preventing \"normal\" Pods to run) and make sure to checkout the logs of the ",[567,16968,16969],{},"rook-ceph-osd-prepare-*"," and if existing ",[567,16972,16973],{},"rook-ceph-osd-[0-9]*"," Pods. If you don't have any Pods related to ",[567,16976,16977],{},"rook-ceph-osd-*"," look into the ",[567,16980,16981],{},"rook-ceph-operator-*"," logs for error messages, be sure to go over each line to make sure you don't miss an error message.",[535,16984,16986],{"id":16985},"postgresql","PostgreSQL",[523,16988,16989],{},"Moving on to the PostgreSQL for ownCloud.",[523,16991,16992],{},"Zalando's PostgreSQL operator does a great job for running PostgreSQL in Kubernetes.",[523,16994,16995],{},"First thing to create is the PostgreSQL Operator which brings the CustomResourceDefinitions, remember the custom Kubernetes objects, with itself.\nUsing the Ceph block storage (RBD) we are going to create a redundant PostgreSQL instance for ownCloud to use.",[738,16997,16999],{"className":1621,"code":16998,"language":1623,"meta":743,"style":743},"$ kubectl create -n owncloud -f postgres\u002Fpostgres-operator.yaml\n# Check for the PostgreSQL operator Pod to be created and running\n$ kubectl get -n owncloud pod\nNAME                                 READY   STATUS    RESTARTS   AGE\npostgres-operator-6464fc9c48-6twrd   1\u002F1     Running   0          5m23s\n",[567,17000,17001,17019,17024,17038,17051],{"__ignoreMap":743},[747,17002,17003,17005,17007,17009,17011,17014,17016],{"class":749,"line":750},[747,17004,1919],{"class":1630},[747,17006,1922],{"class":802},[747,17008,1925],{"class":802},[747,17010,1928],{"class":802},[747,17012,17013],{"class":802}," owncloud",[747,17015,1934],{"class":802},[747,17017,17018],{"class":802}," postgres\u002Fpostgres-operator.yaml\n",[747,17020,17021],{"class":749,"line":761},[747,17022,17023],{"class":772},"# Check for the PostgreSQL operator Pod to be created and running\n",[747,17025,17026,17028,17030,17032,17034,17036],{"class":749,"line":769},[747,17027,1919],{"class":1630},[747,17029,1922],{"class":802},[747,17031,1951],{"class":802},[747,17033,1928],{"class":802},[747,17035,17013],{"class":802},[747,17037,15539],{"class":802},[747,17039,17040,17042,17045,17047,17049],{"class":749,"line":776},[747,17041,2230],{"class":1630},[747,17043,17044],{"class":802},"                                 READY",[747,17046,2236],{"class":802},[747,17048,2239],{"class":802},[747,17050,15553],{"class":802},[747,17052,17053,17056,17058,17060,17062],{"class":749,"line":784},[747,17054,17055],{"class":1630},"postgres-operator-6464fc9c48-6twrd",[747,17057,2268],{"class":802},[747,17059,2271],{"class":802},[747,17061,2274],{"class":1895},[747,17063,17064],{"class":802},"          5m23s\n",[523,17066,17067],{},"That is the operator created, moving on to the PostgreSQL custom resource object that will cause the operator to create a PostgreSQL instance for use in Kubernetes:",[738,17069,17071],{"className":1621,"code":17070,"language":1623,"meta":743,"style":743},"# Make sure the CustomResourceDefinition of the PostgreSQL has been created\n$ kubectl get customresourcedefinitions.apiextensions.k8s.io postgresqls.acid.zalan.do\nNAME                        CREATED AT\npostgresqls.acid.zalan.do   2019-08-04T10:27:59Z\n",[567,17072,17073,17078,17092,17102],{"__ignoreMap":743},[747,17074,17075],{"class":749,"line":750},[747,17076,17077],{"class":772},"# Make sure the CustomResourceDefinition of the PostgreSQL has been created\n",[747,17079,17080,17082,17084,17086,17089],{"class":749,"line":761},[747,17081,1919],{"class":1630},[747,17083,1922],{"class":802},[747,17085,1951],{"class":802},[747,17087,17088],{"class":802}," customresourcedefinitions.apiextensions.k8s.io",[747,17090,17091],{"class":802}," postgresqls.acid.zalan.do\n",[747,17093,17094,17096,17099],{"class":749,"line":769},[747,17095,2230],{"class":1630},[747,17097,17098],{"class":802},"                        CREATED",[747,17100,17101],{"class":802}," AT\n",[747,17103,17104,17107],{"class":749,"line":776},[747,17105,17106],{"class":1630},"postgresqls.acid.zalan.do",[747,17108,17109],{"class":802},"   2019-08-04T10:27:59Z\n",[523,17111,17112],{},"The CustomResourceDefinition exists? Perfect, continue with the creation:",[738,17114,17116],{"className":1621,"code":17115,"language":1623,"meta":743,"style":743},"kubectl create -n owncloud -f postgres\u002Fpostgres.yaml\n",[567,17117,17118],{"__ignoreMap":743},[747,17119,17120,17122,17124,17126,17128,17130],{"class":749,"line":750},[747,17121,15269],{"class":1630},[747,17123,1925],{"class":802},[747,17125,1928],{"class":802},[747,17127,17013],{"class":802},[747,17129,1934],{"class":802},[747,17131,17132],{"class":802}," postgres\u002Fpostgres.yaml\n",[523,17134,17135,17136,17139],{},"It will take a bit for the two PostgreSQL Pods to appear, but in the end you should have two ",[567,17137,17138],{},"owncloud-postgres"," Pods:",[738,17141,17143],{"className":1621,"code":17142,"language":1623,"meta":743,"style":743},"$ kubectl get -n owncloud pod\nNAME                                 READY   STATUS    RESTARTS   AGE\nowncloud-postgres-0                  1\u002F1     Running   0          92s\nowncloud-postgres-1                  1\u002F1     Running   0          64s\npostgres-operator-6464fc9c48-6twrd   1\u002F1     Running   0          7m\n",[567,17144,17145,17159,17171,17186,17200],{"__ignoreMap":743},[747,17146,17147,17149,17151,17153,17155,17157],{"class":749,"line":750},[747,17148,1919],{"class":1630},[747,17150,1922],{"class":802},[747,17152,1951],{"class":802},[747,17154,1928],{"class":802},[747,17156,17013],{"class":802},[747,17158,15539],{"class":802},[747,17160,17161,17163,17165,17167,17169],{"class":749,"line":761},[747,17162,2230],{"class":1630},[747,17164,17044],{"class":802},[747,17166,2236],{"class":802},[747,17168,2239],{"class":802},[747,17170,15553],{"class":802},[747,17172,17173,17176,17179,17181,17183],{"class":749,"line":769},[747,17174,17175],{"class":1630},"owncloud-postgres-0",[747,17177,17178],{"class":802},"                  1\u002F1",[747,17180,2271],{"class":802},[747,17182,2274],{"class":1895},[747,17184,17185],{"class":802},"          92s\n",[747,17187,17188,17191,17193,17195,17197],{"class":749,"line":776},[747,17189,17190],{"class":1630},"owncloud-postgres-1",[747,17192,17178],{"class":802},[747,17194,2271],{"class":802},[747,17196,2274],{"class":1895},[747,17198,17199],{"class":802},"          64s\n",[747,17201,17202,17204,17206,17208,17210],{"class":749,"line":784},[747,17203,17055],{"class":1630},[747,17205,2268],{"class":802},[747,17207,2271],{"class":802},[747,17209,2274],{"class":1895},[747,17211,17212],{"class":802},"          7m\n",[523,17214,17215,587,17217,17219,17220,17223],{},[567,17216,17175],{},[567,17218,17190],{}," in ",[567,17221,17222],{},"Running"," status? That looks good.",[523,17225,17226],{},"Now that the database is running, let's continue to the Redis.",[535,17228,17230],{"id":17229},"redis","Redis",[523,17232,17233],{},"To run a Redis cluster we need the KubeDB Operator, installing it can done using a bash script or Helm.",[523,17235,17236],{},"To keep it quick'n'easy we'll use their bash script for that:",[738,17238,17240],{"className":1621,"code":17239,"language":1623,"meta":743,"style":743},"curl -fsSL https:\u002F\u002Fraw.githubusercontent.com\u002Fkubedb\u002Fcli\u002F0.12.0\u002Fhack\u002Fdeploy\u002Fkubedb.sh -o kubedb.sh\n# Take a look at the script using, e.g., `cat kubedb.sh`\n#\n# If you are fine with it, run it:\nchmod +x kubedb.sh\n.\u002Fkubedb.sh\n# It will install the KubeDB operator to the cluster in the `kube-system` Namespace\n",[567,17241,17242,17257,17262,17267,17272,17281,17286],{"__ignoreMap":743},[747,17243,17244,17246,17249,17252,17254],{"class":749,"line":750},[747,17245,3151],{"class":1630},[747,17247,17248],{"class":802}," -fsSL",[747,17250,17251],{"class":802}," https:\u002F\u002Fraw.githubusercontent.com\u002Fkubedb\u002Fcli\u002F0.12.0\u002Fhack\u002Fdeploy\u002Fkubedb.sh",[747,17253,2222],{"class":802},[747,17255,17256],{"class":802}," kubedb.sh\n",[747,17258,17259],{"class":749,"line":761},[747,17260,17261],{"class":772},"# Take a look at the script using, e.g., `cat kubedb.sh`\n",[747,17263,17264],{"class":749,"line":769},[747,17265,17266],{"class":772},"#\n",[747,17268,17269],{"class":749,"line":776},[747,17270,17271],{"class":772},"# If you are fine with it, run it:\n",[747,17273,17274,17277,17279],{"class":749,"line":784},[747,17275,17276],{"class":1630},"chmod",[747,17278,3382],{"class":802},[747,17280,17256],{"class":802},[747,17282,17283],{"class":749,"line":790},[747,17284,17285],{"class":1630},".\u002Fkubedb.sh\n",[747,17287,17288],{"class":749,"line":796},[747,17289,17290],{"class":772},"# It will install the KubeDB operator to the cluster in the `kube-system` Namespace\n",[523,17292,17293,17294,2006],{},"(You can remove the script afterwards: ",[567,17295,17296],{},"rm kubedb.sh",[523,17298,17299,17300,1909],{},"For more information on the bash script and\u002F or the Helm installation, checkout ",[527,17301,17304],{"href":17302,"rel":17303},"https:\u002F\u002Fkubedb.com\u002Fdocs\u002F0.12.0\u002Fsetup\u002Finstall\u002F#install-kubedb-operator",[531],"KubeDB",[523,17306,17307],{},"Moving on to creating the Redis cluster, run:",[738,17309,17311],{"className":1621,"code":17310,"language":1623,"meta":743,"style":743},"kubectl create -n owncloud -f redis.yaml\n",[567,17312,17313],{"__ignoreMap":743},[747,17314,17315,17317,17319,17321,17323,17325],{"class":749,"line":750},[747,17316,15269],{"class":1630},[747,17318,1925],{"class":802},[747,17320,1928],{"class":802},[747,17322,17013],{"class":802},[747,17324,1934],{"class":802},[747,17326,17327],{"class":802}," redis.yaml\n",[523,17329,17330,17331,17334],{},"It will take a few seconds for the first Redis Pod(s) to be started, to check that it worked look for Pods with ",[567,17332,17333],{},"redis-owncloud-"," in their name:",[738,17336,17338],{"className":1621,"code":17337,"language":1623,"meta":743,"style":743},"$ kubectl get -n owncloud pods\nNAME                                 READY   STATUS    RESTARTS   AGE\nowncloud-postgres-0                  1\u002F1     Running   0          6m41s\nowncloud-postgres-1                  1\u002F1     Running   0          6m13s\npostgres-operator-6464fc9c48-6twrd   1\u002F1     Running   0          12m\nredis-owncloud-shard0-0              1\u002F1     Running   0          49s\nredis-owncloud-shard0-1              1\u002F1     Running   0          40s\nredis-owncloud-shard1-0              1\u002F1     Running   0          29s\nredis-owncloud-shard1-1              1\u002F1     Running   0          19s\nredis-owncloud-shard2-0              1\u002F1     Running   0          14s\nredis-owncloud-shard2-1              1\u002F1     Running   0          10s\n",[567,17339,17340,17354,17366,17379,17392,17404,17419,17433,17447,17461,17475],{"__ignoreMap":743},[747,17341,17342,17344,17346,17348,17350,17352],{"class":749,"line":750},[747,17343,1919],{"class":1630},[747,17345,1922],{"class":802},[747,17347,1951],{"class":802},[747,17349,1928],{"class":802},[747,17351,17013],{"class":802},[747,17353,1958],{"class":802},[747,17355,17356,17358,17360,17362,17364],{"class":749,"line":761},[747,17357,2230],{"class":1630},[747,17359,17044],{"class":802},[747,17361,2236],{"class":802},[747,17363,2239],{"class":802},[747,17365,15553],{"class":802},[747,17367,17368,17370,17372,17374,17376],{"class":749,"line":769},[747,17369,17175],{"class":1630},[747,17371,17178],{"class":802},[747,17373,2271],{"class":802},[747,17375,2274],{"class":1895},[747,17377,17378],{"class":802},"          6m41s\n",[747,17380,17381,17383,17385,17387,17389],{"class":749,"line":776},[747,17382,17190],{"class":1630},[747,17384,17178],{"class":802},[747,17386,2271],{"class":802},[747,17388,2274],{"class":1895},[747,17390,17391],{"class":802},"          6m13s\n",[747,17393,17394,17396,17398,17400,17402],{"class":749,"line":784},[747,17395,17055],{"class":1630},[747,17397,2268],{"class":802},[747,17399,2271],{"class":802},[747,17401,2274],{"class":1895},[747,17403,16767],{"class":802},[747,17405,17406,17409,17412,17414,17416],{"class":749,"line":790},[747,17407,17408],{"class":1630},"redis-owncloud-shard0-0",[747,17410,17411],{"class":802},"              1\u002F1",[747,17413,2271],{"class":802},[747,17415,2274],{"class":1895},[747,17417,17418],{"class":802},"          49s\n",[747,17420,17421,17424,17426,17428,17430],{"class":749,"line":796},[747,17422,17423],{"class":1630},"redis-owncloud-shard0-1",[747,17425,17411],{"class":802},[747,17427,2271],{"class":802},[747,17429,2274],{"class":1895},[747,17431,17432],{"class":802},"          40s\n",[747,17434,17435,17438,17440,17442,17444],{"class":749,"line":806},[747,17436,17437],{"class":1630},"redis-owncloud-shard1-0",[747,17439,17411],{"class":802},[747,17441,2271],{"class":802},[747,17443,2274],{"class":1895},[747,17445,17446],{"class":802},"          29s\n",[747,17448,17449,17452,17454,17456,17458],{"class":749,"line":814},[747,17450,17451],{"class":1630},"redis-owncloud-shard1-1",[747,17453,17411],{"class":802},[747,17455,2271],{"class":802},[747,17457,2274],{"class":1895},[747,17459,17460],{"class":802},"          19s\n",[747,17462,17463,17466,17468,17470,17472],{"class":749,"line":822},[747,17464,17465],{"class":1630},"redis-owncloud-shard2-0",[747,17467,17411],{"class":802},[747,17469,2271],{"class":802},[747,17471,2274],{"class":1895},[747,17473,17474],{"class":802},"          14s\n",[747,17476,17477,17480,17482,17484,17486],{"class":749,"line":830},[747,17478,17479],{"class":1630},"redis-owncloud-shard2-1",[747,17481,17411],{"class":802},[747,17483,2271],{"class":802},[747,17485,2274],{"class":1895},[747,17487,16149],{"class":802},[523,17489,17490],{},"That is how it should like now.",[535,17492,17493],{"id":15430},"ownCloud",[523,17495,17496],{},"Now the final \"piece\", ownCloud.",[523,17498,17499,17500,17503],{},"The folder ",[567,17501,17502],{},"owncloud\u002F"," contains all the manifests we need.",[668,17505,17506,17509,17512,17515],{},[638,17507,17508],{},"ConfigMap and Secret for basic configuration of the ownCloud.",[638,17510,17511],{},"Deployment to get ownCloud Pods running in Kubernetes.",[638,17513,17514],{},"Service and Ingress to expose ownCloud to the internet.",[638,17516,17517],{},"CronJob to run the ownCloud cron task execution (e.g., cleanup and others), instead of having the cron run per instance.",[523,17519,17520,17521,17524,17525,3052],{},"The ownCloud Deployment currently uses a custom built image (",[567,17522,17523],{},"galexrt\u002Fowncloud-server:latest",") which has a fix for a clustered Redis configuration issue (pull request has been opened ",[527,17526,17527],{"href":17527,"rel":17528},"https:\u002F\u002Fgithub.com\u002Fowncloud-docker\u002Fbase\u002Fpull\u002F95",[531],[738,17530,17532],{"className":1621,"code":17531,"language":1623,"meta":743,"style":743},"kubectl create -n owncloud -f owncloud\u002F\n# Now we'll wait for ownCloud to have installed the database to then scale the ownCloud up to `2` (or more if you want)\n",[567,17533,17534,17549],{"__ignoreMap":743},[747,17535,17536,17538,17540,17542,17544,17546],{"class":749,"line":750},[747,17537,15269],{"class":1630},[747,17539,1925],{"class":802},[747,17541,1928],{"class":802},[747,17543,17013],{"class":802},[747,17545,1934],{"class":802},[747,17547,17548],{"class":802}," owncloud\u002F\n",[747,17550,17551],{"class":749,"line":761},[747,17552,17553],{"class":772},"# Now we'll wait for ownCloud to have installed the database to then scale the ownCloud up to `2` (or more if you want)\n",[523,17555,17556,17557,17560,17561,17564],{},"The admin username is ",[567,17558,17559],{},"myowncloudadmin"," and can be changed in the ",[567,17562,17563],{},"owncloud\u002Fowncloud-configmap.yaml"," file. Be sure to restart both ownCloud Pods after changing values in the ConfigMaps and Secrets.",[523,17566,17567,17568,17571,17572,17575,17576,10324],{},"If you want to change the admin password, edit the ",[567,17569,17570],{},"owncloud\u002Fowncloud-secret.yaml"," file line ",[567,17573,17574],{},"OWNCLOUD_ADMIN_PASSWORD",". The values in a Kubernetes Secret object are base64 encoded (e.g., ",[567,17577,17578],{},"echo -n YOUR_PASSWORD | base64 -w0",[523,17580,17581],{},"To know when your ownCloud is up'n'running check the logs, e.g.:",[738,17583,17585],{"className":1621,"code":17584,"language":1623,"meta":743,"style":743},"$ kubectl logs -n owncloud -f owncloud-856fcc4947-crscn\nCreating volume folders...\nCreating hook folders...\nWaiting for PostgreSQL...\nwait-for-it: waiting 180 seconds for owncloud-postgres:5432\nwait-for-it: owncloud-postgres:5432 is available after 1 seconds\nRemoving custom folder...\nLinking custom folder...\nRemoving config folder...\nLinking config folder...\nWriting config file...\nFixing base perms...\nFixing data perms...\nFixing hook perms...\nInstalling server database...\nownCloud was successfully installed\nownCloud is already latest version\nWriting objectstore config...\nWriting php config...\nUpdating htaccess config...\n.htaccess has been updated\nWriting apache config...\nEnabling webcron background...\nSet mode for background jobs to 'webcron'\nTouching cron configs...\nStarting cron daemon...\nStarting apache daemon...\n[Sun Aug 04 13:26:18.986407 2019] [mpm_prefork:notice] [pid 190] AH00163: Apache\u002F2.4.29 (Ubuntu) configured -- resuming normal operations\n[Sun Aug 04 13:26:18.986558 2019] [core:notice] [pid 190] AH00094: Command line: '\u002Fusr\u002Fsbin\u002Fapache2 -f \u002Fetc\u002Fapache2\u002Fapache2.conf -D FOREGROUND'\n",[567,17586,17587,17605,17615,17624,17634,17653,17673,17683,17692,17701,17709,17719,17730,17739,17747,17757,17770,17785,17795,17804,17814,17828,17837,17848,17873,17884,17894,17902,17940],{"__ignoreMap":743},[747,17588,17589,17591,17593,17596,17598,17600,17602],{"class":749,"line":750},[747,17590,1919],{"class":1630},[747,17592,1922],{"class":802},[747,17594,17595],{"class":802}," logs",[747,17597,1928],{"class":802},[747,17599,17013],{"class":802},[747,17601,1934],{"class":802},[747,17603,17604],{"class":802}," owncloud-856fcc4947-crscn\n",[747,17606,17607,17610,17612],{"class":749,"line":761},[747,17608,17609],{"class":1630},"Creating",[747,17611,5566],{"class":802},[747,17613,17614],{"class":802}," folders...\n",[747,17616,17617,17619,17622],{"class":749,"line":769},[747,17618,17609],{"class":1630},[747,17620,17621],{"class":802}," hook",[747,17623,17614],{"class":802},[747,17625,17626,17629,17631],{"class":749,"line":776},[747,17627,17628],{"class":1630},"Waiting",[747,17630,3761],{"class":802},[747,17632,17633],{"class":802}," PostgreSQL...\n",[747,17635,17636,17639,17642,17645,17648,17650],{"class":749,"line":784},[747,17637,17638],{"class":1630},"wait-for-it:",[747,17640,17641],{"class":802}," waiting",[747,17643,17644],{"class":1895}," 180",[747,17646,17647],{"class":802}," seconds",[747,17649,3761],{"class":802},[747,17651,17652],{"class":802}," owncloud-postgres:5432\n",[747,17654,17655,17657,17660,17662,17665,17668,17670],{"class":749,"line":790},[747,17656,17638],{"class":1630},[747,17658,17659],{"class":802}," owncloud-postgres:5432",[747,17661,5068],{"class":802},[747,17663,17664],{"class":802}," available",[747,17666,17667],{"class":802}," after",[747,17669,3597],{"class":1895},[747,17671,17672],{"class":802}," seconds\n",[747,17674,17675,17678,17680],{"class":749,"line":796},[747,17676,17677],{"class":1630},"Removing",[747,17679,4342],{"class":802},[747,17681,17682],{"class":802}," folder...\n",[747,17684,17685,17688,17690],{"class":749,"line":806},[747,17686,17687],{"class":1630},"Linking",[747,17689,4342],{"class":802},[747,17691,17682],{"class":802},[747,17693,17694,17696,17699],{"class":749,"line":814},[747,17695,17677],{"class":1630},[747,17697,17698],{"class":802}," config",[747,17700,17682],{"class":802},[747,17702,17703,17705,17707],{"class":749,"line":822},[747,17704,17687],{"class":1630},[747,17706,17698],{"class":802},[747,17708,17682],{"class":802},[747,17710,17711,17714,17716],{"class":749,"line":830},[747,17712,17713],{"class":1630},"Writing",[747,17715,17698],{"class":802},[747,17717,17718],{"class":802}," file...\n",[747,17720,17721,17724,17727],{"class":749,"line":836},[747,17722,17723],{"class":1630},"Fixing",[747,17725,17726],{"class":802}," base",[747,17728,17729],{"class":802}," perms...\n",[747,17731,17732,17734,17737],{"class":749,"line":842},[747,17733,17723],{"class":1630},[747,17735,17736],{"class":802}," data",[747,17738,17729],{"class":802},[747,17740,17741,17743,17745],{"class":749,"line":850},[747,17742,17723],{"class":1630},[747,17744,17621],{"class":802},[747,17746,17729],{"class":802},[747,17748,17749,17752,17754],{"class":749,"line":863},[747,17750,17751],{"class":1630},"Installing",[747,17753,5065],{"class":802},[747,17755,17756],{"class":802}," database...\n",[747,17758,17759,17761,17764,17767],{"class":749,"line":869},[747,17760,17493],{"class":1630},[747,17762,17763],{"class":802}," was",[747,17765,17766],{"class":802}," successfully",[747,17768,17769],{"class":802}," installed\n",[747,17771,17772,17774,17776,17779,17782],{"class":749,"line":877},[747,17773,17493],{"class":1630},[747,17775,5068],{"class":802},[747,17777,17778],{"class":802}," already",[747,17780,17781],{"class":802}," latest",[747,17783,17784],{"class":802}," version\n",[747,17786,17787,17789,17792],{"class":749,"line":1015},[747,17788,17713],{"class":1630},[747,17790,17791],{"class":802}," objectstore",[747,17793,17794],{"class":802}," config...\n",[747,17796,17797,17799,17802],{"class":749,"line":1021},[747,17798,17713],{"class":1630},[747,17800,17801],{"class":802}," php",[747,17803,17794],{"class":802},[747,17805,17806,17809,17812],{"class":749,"line":1027},[747,17807,17808],{"class":1630},"Updating",[747,17810,17811],{"class":802}," htaccess",[747,17813,17794],{"class":802},[747,17815,17816,17819,17822,17825],{"class":749,"line":1033},[747,17817,17818],{"class":1630},".htaccess",[747,17820,17821],{"class":802}," has",[747,17823,17824],{"class":802}," been",[747,17826,17827],{"class":802}," updated\n",[747,17829,17830,17832,17835],{"class":749,"line":1039},[747,17831,17713],{"class":1630},[747,17833,17834],{"class":802}," apache",[747,17836,17794],{"class":802},[747,17838,17839,17842,17845],{"class":749,"line":1054},[747,17840,17841],{"class":1630},"Enabling",[747,17843,17844],{"class":802}," webcron",[747,17846,17847],{"class":802}," background...\n",[747,17849,17850,17853,17856,17858,17861,17864,17866,17868,17871],{"class":749,"line":1060},[747,17851,17852],{"class":1630},"Set",[747,17854,17855],{"class":802}," mode",[747,17857,3761],{"class":802},[747,17859,17860],{"class":802}," background",[747,17862,17863],{"class":802}," jobs",[747,17865,3696],{"class":802},[747,17867,3537],{"class":757},[747,17869,17870],{"class":802},"webcron",[747,17872,13042],{"class":757},[747,17874,17875,17878,17881],{"class":749,"line":1066},[747,17876,17877],{"class":1630},"Touching",[747,17879,17880],{"class":802}," cron",[747,17882,17883],{"class":802}," configs...\n",[747,17885,17886,17889,17891],{"class":749,"line":1081},[747,17887,17888],{"class":1630},"Starting",[747,17890,17880],{"class":802},[747,17892,17893],{"class":802}," daemon...\n",[747,17895,17896,17898,17900],{"class":749,"line":1087},[747,17897,17888],{"class":1630},[747,17899,17834],{"class":802},[747,17901,17893],{"class":802},[747,17903,17904,17906,17909,17912,17915,17917,17919,17922,17924,17926,17929,17931,17934,17937],{"class":749,"line":1102},[747,17905,4253],{"class":757},[747,17907,17908],{"class":1640},"Sun Aug ",[747,17910,17911],{"class":1895},"04",[747,17913,17914],{"class":1640}," 13:26:18.986407 2019",[747,17916,4259],{"class":757},[747,17918,4262],{"class":757},[747,17920,17921],{"class":1640},"mpm_prefork:notice",[747,17923,4259],{"class":757},[747,17925,4262],{"class":757},[747,17927,17928],{"class":1640},"pid 190",[747,17930,4259],{"class":757},[747,17932,17933],{"class":1640}," AH00163: Apache\u002F2.4.29 (",[747,17935,17936],{"class":1630},"Ubuntu",[747,17938,17939],{"class":1640},") configured -- resuming normal operations\n",[747,17941,17942,17944,17946,17948,17951,17953,17955,17958,17960,17962,17964,17966,17969,17971,17974],{"class":749,"line":1110},[747,17943,4253],{"class":757},[747,17945,17908],{"class":1640},[747,17947,17911],{"class":1895},[747,17949,17950],{"class":1640}," 13:26:18.986558 2019",[747,17952,4259],{"class":757},[747,17954,4262],{"class":757},[747,17956,17957],{"class":1640},"core:notice",[747,17959,4259],{"class":757},[747,17961,4262],{"class":757},[747,17963,17928],{"class":1640},[747,17965,4259],{"class":757},[747,17967,17968],{"class":1640}," AH00094: Command line: ",[747,17970,3543],{"class":757},[747,17972,17973],{"class":802},"\u002Fusr\u002Fsbin\u002Fapache2 -f \u002Fetc\u002Fapache2\u002Fapache2.conf -D FOREGROUND",[747,17975,13042],{"class":757},[523,17977,8764,17978,17981],{},[567,17979,17980],{},"Installing server database..."," will take some time depending on your network, storage and other factors.",[523,17983,17984,17985,17988,17989,17992],{},"After the ",[567,17986,17987],{},"[Sun Aug 04 13:26:18.986558 2019] [core:notice] [pid 190] AH00094: Command line: '\u002Fusr\u002Fsbin\u002Fapache2 -f \u002Fetc\u002Fapache2\u002Fapache2.conf -D FOREGROUND'"," you should be able to reach your ownCloud instance through the NodePort Service Port (on HTTP) or through the Ingress (default address ",[567,17990,17991],{},"owncloud.example.com","). If you are using the Ingress from the example files, be sure to edit it to use a (sub-) domain pointing to the Ingress controllers in your Kubernetes cluster.",[523,17994,17995],{},"You now have a ownCloud instance running.",[613,17997,17999],{"id":17998},"further-points","Further points",[3126,18001,18003],{"id":18002},"https","HTTPS",[523,18005,18006,18007,18012,18013,18016,18017,18022],{},"To further improve the experience of running ownCloud in Kubernetes, you will probably want to checkout ",[527,18008,18011],{"href":18009,"rel":18010},"https:\u002F\u002Fgithub.com\u002Fjetstack\u002Fcert-manager",[531],"Jetstack's cert-manager project on GitHub"," to get yourself Letsencrypt certificates for your Ingress controller.\nThe ",[567,18014,18015],{},"cert-manager"," allows you to request ",[527,18018,18021],{"href":18019,"rel":18020},"https:\u002F\u002Fletsencrypt.org\u002F",[531],"Let's Encrypt"," certificates easily through Kubernetes custom objects and keep them uptodate.",[523,18024,18025],{},"Meaning the ownCloud will then be reachable via HTTPS which combined with the ownCloud encryption makes it pretty secure.",[523,18027,18028,18029,1909],{},"For more information on using TLS with Kubernetes Ingress, checkout ",[527,18030,18033],{"href":18031,"rel":18032},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fservices-networking\u002Fingress\u002F#tls",[531],"Ingress - Kubernetes",[3126,18035,18037],{"id":18036},"pod-health-checks","Pod Health Checks",[523,18039,8336,18040,18043,18044,587,18047,18050,18051,18054,18055,18058,18059,3052],{},[567,18041,18042],{},"owncloud\u002Fowncloud-deployment.yaml"," there is a ",[567,18045,18046],{},"readinessProbe",[567,18048,18049],{},"livenessProbe"," in the Deployment sepc but commented out.\nAfter the ownCloud has been installed and you have verified it is running, you can go ahead and uncomment those lines and use ",[567,18052,18053],{},"kubectl apply","\u002F ",[567,18056,18057],{},"kubectl replace"," (don't forget to specify the Namespace ",[567,18060,18061],{},"-n owncloud",[3126,18063,18065],{"id":18064},"upload-filesize","Upload Filesize",[523,18067,18068],{},"When changing the upload filesize on the ownCloud instance itself through the environment variables, be sure to also update the Ingress controller with the \"max upload file size\".",[3126,18070,18072],{"id":18071},"other-configuration-options","Other configuration options",[523,18074,18075,18076,1909],{},"When wanting to change config options, you need to provide them through environment variables. The environment variables are given to the ownCloud Deployment in the ",[567,18077,17563],{},[523,18079,18080],{},"A list of all available environment variables can be found here:",[668,18082,18083,18089],{},[638,18084,18085],{},[527,18086,18087],{"href":18087,"rel":18088},"https:\u002F\u002Fgithub.com\u002Fowncloud-docker\u002Fserver#available-environment-variables",[531],[638,18090,18091],{},[527,18092,18093],{"href":18093,"rel":18094},"https:\u002F\u002Fgithub.com\u002Fowncloud-docker\u002Fbase#available-environment-variables",[531],[613,18096,18098],{"id":18097},"updating-owncloud-in-kubernetes","Updating ownCloud in Kubernetes",[523,18100,18101,18102,1909],{},"It is the same procedure as with running ownCloud with, e.g., ",[567,18103,2936],{},[523,18105,18106,18107,6378,18109,18112,18113,18116],{},"To update ownCloud you need to scale down the Deployment to ",[567,18108,13727],{},[567,18110,18111],{},"replicas","), then update the image, wait for the one single Pod come up again and then scale up the ownCloud Deployment again to, e.g., ",[567,18114,18115],{},"2"," or more.",[535,18118,14526],{"id":18119},"summary-1",[523,18121,18122],{},"This is the end of the two part series on running ownCloud in Kubernetes.",[523,18124,13967],{},[2890,18126,18127],{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}",{"title":743,"searchDepth":761,"depth":761,"links":18129},[18130,18134,18142,18143,18144,18148],{"id":15188,"depth":761,"text":15189,"children":18131},[18132,18133],{"id":15195,"depth":769,"text":15196},{"id":15240,"depth":769,"text":15241},{"id":15459,"depth":761,"text":15460,"children":18135},[18136,18137,18138,18139,18140,18141],{"id":15484,"depth":769,"text":15485},{"id":15659,"depth":769,"text":15660},{"id":15979,"depth":769,"text":15980},{"id":16050,"depth":769,"text":16051},{"id":16160,"depth":769,"text":16161},{"id":14525,"depth":769,"text":14526},{"id":16985,"depth":761,"text":16986},{"id":17229,"depth":761,"text":17230},{"id":15430,"depth":761,"text":17493,"children":18145},[18146,18147],{"id":17998,"depth":769,"text":17999},{"id":18097,"depth":769,"text":18098},{"id":18119,"depth":761,"text":14526},"2020-01-06T14:56:41+01:00","How to run ownCloud in Kubernetes with using Rook for a Ceph Cluster.",{"tags":18152},[15155,17493],"\u002Fblog\u002F2020\u002Frunning-owncloud-in-kubernetes-with-rook-ceph-storage-part-2",{"title":15162,"description":18150},"3.blog\u002F2020\u002Frunning-owncloud-in-kubernetes-with-rook-ceph-storage-part-2","tl4XyCW4H12mdLR7fSqH3504mj47kUbFpnqkCK4KFsk",{"id":18158,"title":18159,"authors":18160,"badge":518,"body":18163,"date":18478,"description":18150,"extension":2911,"image":518,"meta":18479,"navigation":1254,"path":18481,"seo":18482,"stem":18483,"__hash__":18484},"posts\u002F3.blog\u002F2020\u002Frunning-owncloud-in-kubernetes-with-rook-ceph-storage-part-1.md","Running ownCloud in Kubernetes with Rook Ceph Storage - Part 1",[18161],{"name":514,"to":515,"avatar":18162},{"src":517},{"type":520,"value":18164,"toc":18469},[18165,18175,18177,18179,18187,18190,18193,18217,18221,18230,18238,18244,18248,18251,18255,18258,18266,18275,18278,18290,18299,18301,18304,18312,18315,18318,18320,18328,18337,18352,18359,18362,18376,18391,18394,18396,18404,18413,18421,18425,18428,18434,18437,18466],[523,18166,15170,18167,15176,18170,1909],{},[527,18168,15175],{"href":15173,"rel":18169},[531],[527,18171,18174],{"href":18172,"rel":18173},"https:\u002F\u002Fowncloud.org\u002Fnews\u002Frunning-owncloud-in-kubernetes-with-rook-ceph-storage\u002F",[531],"Running ownCloud in Kubernetes With Rook Ceph Storage",[523,18176,14581],{},[2979,18178],{},[523,18180,18181,18182,18186],{},"In dieser zweiteiligen Artikelreihe wird es darum gehen ownCloud hochverfügbar in ",[527,18183,124],{"href":18184,"rel":18185},"https:\u002F\u002Fkubernetes.io",[531]," zu betreiben.",[523,18188,18189],{},"Der erste Teil wird dabei auf die Grundaspekte und Requirements eingehen, so das am Ende ein Plan bereit ist der im zweiten Teil dann Schritt für Schritt umgesetzt wird.",[523,18191,18192],{},"Zusammengefasst soll folgendes erreicht werden:",[668,18194,18195,18206],{},[638,18196,18197,18198],{},"Hardware-\u002F Serverausfälle sollen nicht zu:\n",[668,18199,18200,18203],{},[638,18201,18202],{},"Datenverlust führen.",[638,18204,18205],{},"ownCloud an sich nicht mehr verfügbar ist.",[638,18207,18208,18209],{},"Steigende Userzahlen sollen weniger\u002F keine Probleme verursachen:\n",[668,18210,18211,18214],{},[638,18212,18213],{},"Ceph ist an sich je nach gegebenen Storage in den genutzten Servern schnell unterwegs und sollte ohne Probleme mit vielen Usern klar kommen.",[638,18215,18216],{},"Die Datenbank ist neben dem Storage noch ein denkbares \"Bottleneck\", jedoch komnmt das darauf an wie und welche Features in ownCloud genutzt werden.",[535,18218,18220],{"id":18219},"kubernetes-was-ist-das","Kubernetes - Was ist das?",[523,18222,18223,18224,18229],{},"Kubernetes ist ein Orchestrator für Container. Bedeutet das Kubernetes Container verteilt über mehrere Server laufen lassen kann und noch weitere Features die uns dann nützlich sein werden.\nNeben Container laufen lassen, kann Kubernetes noch vieles mehr, unteranderem mit Leichtigkeit HTTP Anwendungen im Internet erreichbar zu machen.\nDafür wird das ",[527,18225,18228],{"href":18226,"rel":18227},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fservices-networking\u002Fingress\u002F",[531],"Kubernetes Ingress Feature"," genutzt.",[523,18231,18232,18233,1909],{},"Im weiteren Kontext der Artikelreihe wird Kubernetes (Grund-) Wissen vorrausgesetz. Sollte Kubernetes noch eine \"Pandorasbüchse\" für sie sein, kann dies unteranderem durch die hervorragenden Tutorials auf der Kubernetes Homepage Stück für Stück aufgebaut werden, siehe ",[527,18234,18237],{"href":18235,"rel":18236},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Ftutorials\u002F",[531],"Tutorials - Kubernetes",[523,18239,18240,18243],{},[584,18241,18242],{},"ACHTUNG"," Der zweite Artikel in der Artikelreihe geht davon aus das ein funktionierendes Kubernetes Cluster mit einem Node\u002F Worker mindestens vorhanden ist.",[535,18245,18247],{"id":18246},"was-brauchen-wir-dafür","Was brauchen wir dafür?",[523,18249,18250],{},"Fangen wir erstmal bei den Komponenten an die immger gebraucht werden an und arbeiten uns dann direkt auch zu entsprechenden Tools\u002F Projekten vor die uns im Kubernetes Umfeld dabei helfen können.",[613,18252,18254],{"id":18253},"datenbank-postgresql","Datenbank - PostgreSQL",[523,18256,18257],{},"Fangen wir bei einer der wichtigsten Komponenten an, die Datenbank.",[523,18259,18260,18261,1909],{},"Im Falle von kleinen ownCloud Instanz, kann es sein das SQLite als Datenbank eingesetzt wird. SQLite ist nicht für Hochverfügbarkeit gemacht. Es sollte in jedem Fall ein Wechsel auf gegebenfalls PostgreSQL, MySQL oder Oracle in betracht gezogen werden. Oracle Datenbank Server Unterstützung ist in der ownCloud Enterprise Edition verfügbar.\nFür mehr Informationen was SQLite angeht, siehe ",[527,18262,18265],{"href":18263,"rel":18264},"https:\u002F\u002Fcentral.owncloud.org\u002Ft\u002Fwhen-to-and-not-to-use-sqlite\u002F853",[531],"When to and not to use SQLITE - FAQ - ownCloud Central",[523,18267,18268,18269,18274],{},"Unter den unterstützten Datenbanken, ",[527,18270,18273],{"href":18271,"rel":18272},"https:\u002F\u002Fdoc.owncloud.com\u002Fserver\u002F10.1\u002Fadmin_manual\u002Fconfiguration\u002Fdatabase\u002Flinux_database_configuration.html",[531],"ownCloud Documentation 10.1 - Database configuration on Linux",", ist unteranderem PostgreSQL. Da es recht einfache Operator in Kubernetes gibt die ein PostgreSQL Cluster laufen lassen können, werden wir diese nun nutzen.",[523,18276,18277],{},"Bevor jedoch der \"PostgreSQL Operator\" gezeigt wird, was ist so ein Operator überhaupt?",[523,18279,18280,18281,18286,18287,18289],{},"Ein Operator in Kubernetes vereinfacht gesehen ein Automatisierungsmechanismus. Anhand von Custom Objekten in Kubernetes, sogenannten ",[527,18282,18285],{"href":18283,"rel":18284},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Ftasks\u002Faccess-kubernetes-api\u002Fcustom-resources\u002Fcustom-resource-definitions\u002F",[531],"CustomResourceDefinitions",", reagiert der Operator darauf und erstellt in den meisten Fällen entsprechende Objekte in Kubernetes.\nBedeutet als Beispiel für einen PostgreSQL Operator: Wenn ein ",[567,18288,16986],{}," Objekt erstellt wird, reagiert der Operator darauf und erstellt automatisch Stück für Stück Kubernetes Objekte (e.g., Service, Deployment, StatefulSet) um ein PostgreSQL Cluster zu erstellen.",[523,18291,18292,18293,18298],{},"In diesem Artikel wird ",[527,18294,18297],{"href":18295,"rel":18296},"https:\u002F\u002Fgithub.com\u002Fzalando\u002Fpostgres-operator",[531],"Zalando's Postgres Operator"," zum Einsatz kommen, um ein PostgreSQL cluster in Kubernetes zu betreiben.",[613,18300,421],{"id":11626},[523,18302,18303],{},"ownCloud braucht Storage um die hochgeladenen Dateien zu speichern. Die Datenbank braucht auch einen Speicher (Storage) für, e.g., User Logins.",[523,18305,18306,18307,18311],{},"Für Owncloud macht ein Filesystem Storage, als bekanntestes Beispiel ",[527,18308,457],{"href":18309,"rel":18310},"https:\u002F\u002Fnfs.org\u002F",[531],", am meisten Sinn. Grund für Nutzung eines Filesystem Storage anstatt Block Storage ist, dass Block Storage nicht wirklich für mehr als einen Writer gemacht ist.\nMan kann auch Object Storage, bekannte Beispiele AWS S3, in ownCloud einbinden, jedoch \"beschränken\" wir uns in dieser Artikelreihe auf die Nutzung des Filesystem Storage für ownCloud.",[523,18313,18314],{},"Für PostgreSQL sollte zwingend Block Storage verwendet werden, da es dort sonst zu Performanceeinbusen kommt. Hintergrund der Performanceeinbusen ist, dass bei Block Storage kann die Datenbank \"direkter\" schreiben. Dabei kann der Linux Kernel entsprechend Caching betreiben.",[523,18316,18317],{},"Nun da die Frage geklärt ist welcher Storage Typ für die verschiedenen Komponenten zu nutzen ist, gehen wir über zum Einsatz kommenden Storage Software.",[3126,18319,427],{"id":14930},[523,18321,18322,18323,18327],{},"Das ",[527,18324,427],{"href":18325,"rel":18326},"https:\u002F\u002Fceph.com",[531]," Projekt existiert seit ungefähr 2006.\nCeph hat als oberste Priorität Datensicherheit. Das passt perfekt, da wir keine unserer wertvollen Daten, e.g., Urlaubsfotos, Musik oder ähnliches, verlieren möchten.",[523,18329,18330,18331,18336],{},"Man muss sich auch keine Sorgen machen das Ceph so schnell nicht mehr weiterentwickelt wird. Die ",[527,18332,18335],{"href":18333,"rel":18334},"https:\u002F\u002Fceph.com\u002Ffoundation\u002F",[531],"Ceph Foundation"," unterstützt Ceph zentral, um die starke Entwicklung noch stärker als sie schon ist voran zu treiben.\nDas zeigt Mal wieder wie gut es ist wenn Firmen die Open Source nutzen \"zusammen kommen\" und gemeinsam an einem Strang ziehen.",[523,18338,18339,18340,18345,18346,18351],{},"Ceph an sich ist sehr komplex, bringt dafür aber auch einiges an Features mit sich. Neben Filesystem storage, gibt es auch Block storage und sogar Object Storage in verschiedenen Protokollen (e.g., S3 kompatibles Protokoll, OpenStack SWIFT).\nWas ich grundlegend empfehlen würde ist, sich durch das ",[527,18341,18344],{"href":18342,"rel":18343},"http:\u002F\u002Fdocs.ceph.com\u002Fdocs\u002Fmaster\u002Fstart\u002Fintro\u002F",[531],"Intro to Ceph - Ceph Documentation"," durch zulesen um die Grundkonzepte zu verstehen.\n",[527,18347,18350],{"href":18348,"rel":18349},"https:\u002F\u002Fceph.com\u002Fusers\u002F",[531],"CERN, Deutsche Telekom, und viele andere Organistationen und Firmen"," nutzen Ceph als Storage System für ihre Applikationen.",[523,18353,18354,18355,18358],{},"Wahrscheinlich kommt jetzt die Frage auf \"Wo soll Ceph laufen?\". Das ist eine gute Frage die jedoch schnell beantwortet ist, in Kubernetes. ",[527,18356,14601],{"href":13751,"rel":18357},[531]," ist der Weg das zu schaffen.",[523,18360,18361],{},"Rook ermöglicht es Ceph und andere Software für persistente Datenhaltung, wie z.B. EdgeFS, Minio, CockroachDB und weitere, in Kubernetes laufen zu lassen.",[523,18363,18364,18365,18368,18369,18371,18372,18375],{},"Beim Punkt ",[527,18366,18254],{"href":18367},"#datenbank-postgresql"," wurden Kubernetes Operatoren angesprochen. Rook ist genau auch ein Operator, der auf die Custom Kubernetes Objekte reagiert und dann zum Beispiel bei ",[567,18370,13313],{}," Objekten ein Ceph Cluster in Kubernetes Stück für Stück startet.\nNeben des Erstellen des Ceph Clusters, kümmert sich Rook momentan auch um das erstellen und löschen von Volumen in Ceph, damit auch das \"Management\" der passenden ",[567,18373,18374],{},"PersistentVolume"," Objekt in Kubernetes.",[523,18377,18378,18379,18384,18385,18390],{},"Für Container und Kubernetes Interessierte kann ich empfehlen sich in die Themen ",[527,18380,18383],{"href":18381,"rel":18382},"https:\u002F\u002Fkubernetes.io\u002Fblog\u002F2020\u002F01\u002F15\u002Fcontainer-storage-interface-ga\u002F",[531],"Kubernetes Blog - Container Storage Interface (CSI)"," und ",[527,18386,18389],{"href":18387,"rel":18388},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fstorage\u002Fpersistent-volumes\u002F",[531],"Kubernetes - Persistent Volumes"," einzulesen.",[523,18392,18393],{},"Damit haben wir also den Punkt Storage für ownCloud in Kubernetes geklärt.\nFehlt nur noch eine Komponente, Redis.",[613,18395,17230],{"id":17229},[523,18397,18398,18399],{},"Standardmäßig wird die Datenbank für \"File Locking\" eingesetzt. Jedoch ist das eine entsprechende Last die am Ende eher störend für die Datenbank ist, deswegen werden wir Redis dafür einsetzen.\nZu diesem Thema gibt es ",[527,18400,18403],{"href":18401,"rel":18402},"https:\u002F\u002Fdoc.owncloud.com\u002Fserver\u002Fadmin_manual\u002Fconfiguration\u002Ffiles\u002Ffiles_locking_transactional.html",[531],"ownCloud - Transactional File Locking",[523,18405,18406,18407,18412],{},"Dafür wird auch wieder ein Operator eingesetzt, der uns das Leben dabei entsprechend einfacher machen soll. ",[527,18408,18411],{"href":18409,"rel":18410},"https:\u002F\u002Fkubedb.com\u002Fdocs\u002F0.12.0\u002Fwelcome\u002F",[531],"kubed Operator"," kann unteranderem Redis als Cluster in Kubernetes laufen lassen.",[523,18414,18415,18416,1909],{},"Für mehr Informationen zum Redis Part im kubed Operator, siehe ",[527,18417,18420],{"href":18418,"rel":18419},"https:\u002F\u002Fkubedb.com\u002Fdocs\u002F0.12.0\u002Fconcepts\u002Fdatabases\u002Fredis\u002F",[531],"Redis Documentation - kubedb Operator",[535,18422,18424],{"id":18423},"der-plan","Der Plan",[523,18426,18427],{},"Um eine Übersicht zu geben wie das in Kubernetes aussehen wird, hier ein Diagram mit dem \"Geflecht\" aus Komponenten:",[523,18429,18430],{},[3069,18431],{"alt":18432,"src":18433},"ownCloud in Kubernetes mit Rook Ceph Storage - Architektur Diagramm","\u002Fblog\u002F2020\u002Frunning-owncloud-in-kubernetes-with-rook-ceph-storage-part-1\u002Fowncloud-in-kubernetes-rook-ceph.png",[523,18435,18436],{},"Um das ganze nochmal in Stichpunkten zusammenzufassen:",[668,18438,18439,18447,18453,18459],{},[638,18440,18441,18442],{},"Kubernetes um ownCloud und die anderen Komponenten als Container laufen zu lassen.\n",[668,18443,18444],{},[638,18445,18446],{},"Ingress Controller (hängt von der Kubernetes Installation ab) um ownCloud im Internet verfügbar zu machen.",[638,18448,18449,18452],{},[527,18450,18297],{"href":18295,"rel":18451},[531]," für PostgreSQL Cluster in Kubernetes.",[638,18454,18455,18458],{},[527,18456,18411],{"href":18409,"rel":18457},[531]," für Redis Cluster in Kubernetes.",[638,18460,18461,18462,18465],{},"Ceph als Storage und per ",[527,18463,14601],{"href":13751,"rel":18464},[531]," als Container in Kubernetes.",[523,18467,18468],{},"Das ist der Plan und der Plan wird im zweiten Teil der Artikelreihe, Schritt für Schritt umgesetzt um ownCloud in Kubernetes redundant und ausfallsicher laufen zu lassen.",{"title":743,"searchDepth":761,"depth":761,"links":18470},[18471,18472,18477],{"id":18219,"depth":761,"text":18220},{"id":18246,"depth":761,"text":18247,"children":18473},[18474,18475,18476],{"id":18253,"depth":769,"text":18254},{"id":11626,"depth":769,"text":421},{"id":17229,"depth":769,"text":17230},{"id":18423,"depth":761,"text":18424},"2020-01-06T14:55:41+01:00",{"tags":18480},[15155,17493],"\u002Fblog\u002F2020\u002Frunning-owncloud-in-kubernetes-with-rook-ceph-storage-part-1",{"title":18159,"description":18150},"3.blog\u002F2020\u002Frunning-owncloud-in-kubernetes-with-rook-ceph-storage-part-1","JlWOaqmf2TeTYpAndZbYikm5WlQ0tZsIZJEzQ_55OCU",{"id":18486,"title":18487,"authors":18488,"badge":518,"body":18491,"date":18876,"description":18877,"extension":2911,"image":18878,"meta":18880,"navigation":1254,"path":18884,"seo":18885,"stem":18886,"__hash__":18887},"posts\u002F3.blog\u002F2019\u002Fancientt-automation-for-network-testing-tools.md","Ancientt - Automation for Network Testing Tools",[18489],{"name":514,"to":515,"avatar":18490},{"src":517},{"type":520,"value":18492,"toc":18868},[18493,18509,18511,18515,18522,18528,18736,18743,18750,18761,18765,18768,18774,18784,18788,18796,18808,18812,18820,18834,18843,18845,18851,18857,18860,18863,18865],[523,18494,18495,18496,18501,18502,18505,18506,14578],{},"This is a ",[527,18497,18500],{"href":18498,"rel":18499},"http:\u002F\u002Fthe-report.cloud\u002Fancientt-automation-for-network-testing-tools",[531],"cross post"," from ",[527,18503,13818],{"href":13816,"rel":18504},[531],".\nBe sure to checkout the ",[527,18507,13818],{"href":13816,"rel":18508},[531],[2979,18510],{},[535,18512,18514],{"id":18513},"what-is-ancientt","What is Ancientt",[523,18516,18517,18518,18521],{},"Ancientt is a tool to automate network testing tools, like ",[567,18519,18520],{},"iperf3",", in dynamic environments such as Kubernetes, Ansible and more to come dynamic environments.",[523,18523,18524,18525,18527],{},"Meaning that, if you want to test the network throughput with ",[567,18526,18520],{}," of your Kubernetes cluster, you can easily do that with Ancientt.\nA simple \"test definitions\" file is used to tell Ancientt what exactly to do:",[738,18529,18531],{"className":740,"code":18530,"language":742,"meta":743,"style":743},"version: '0'\nrunner:\n  name: kubernetes\n  kubernetes: {}\ntests:\n- name: iperf3-one-random-to-all-nodes\n  type: iperf3\n  outputs:\n  - name: csv\n    csv:\n      filePath: .\n      namePattern: 'ancientt-results-{{ .Data.Tester }}.csv'\n  hosts:\n    servers:\n    - name: one-random\n      random: true\n      count: 1\n    clients:\n    - name: all-hosts\n      all: true\n  iperf3:\n    duration: 30\n",[567,18532,18533,18545,18552,18561,18571,18578,18589,18599,18606,18617,18624,18633,18647,18654,18661,18673,18682,18692,18699,18710,18719,18726],{"__ignoreMap":743},[747,18534,18535,18537,18539,18541,18543],{"class":749,"line":750},[747,18536,10866],{"class":753},[747,18538,856],{"class":757},[747,18540,3537],{"class":757},[747,18542,3579],{"class":802},[747,18544,13042],{"class":757},[747,18546,18547,18550],{"class":749,"line":761},[747,18548,18549],{"class":753},"runner",[747,18551,758],{"class":757},[747,18553,18554,18556,18558],{"class":749,"line":769},[747,18555,12980],{"class":753},[747,18557,856],{"class":757},[747,18559,18560],{"class":802}," kubernetes\n",[747,18562,18563,18566,18568],{"class":749,"line":776},[747,18564,18565],{"class":753},"  kubernetes",[747,18567,856],{"class":757},[747,18569,18570],{"class":757}," {}\n",[747,18572,18573,18576],{"class":749,"line":784},[747,18574,18575],{"class":753},"tests",[747,18577,758],{"class":757},[747,18579,18580,18582,18584,18586],{"class":749,"line":790},[747,18581,3361],{"class":757},[747,18583,14804],{"class":753},[747,18585,856],{"class":757},[747,18587,18588],{"class":802}," iperf3-one-random-to-all-nodes\n",[747,18590,18591,18594,18596],{"class":749,"line":796},[747,18592,18593],{"class":753},"  type",[747,18595,856],{"class":757},[747,18597,18598],{"class":802}," iperf3\n",[747,18600,18601,18604],{"class":749,"line":806},[747,18602,18603],{"class":753},"  outputs",[747,18605,758],{"class":757},[747,18607,18608,18610,18612,18614],{"class":749,"line":814},[747,18609,1721],{"class":757},[747,18611,14804],{"class":753},[747,18613,856],{"class":757},[747,18615,18616],{"class":802}," csv\n",[747,18618,18619,18622],{"class":749,"line":822},[747,18620,18621],{"class":753},"    csv",[747,18623,758],{"class":757},[747,18625,18626,18629,18631],{"class":749,"line":830},[747,18627,18628],{"class":753},"      filePath",[747,18630,856],{"class":757},[747,18632,9747],{"class":1895},[747,18634,18635,18638,18640,18642,18645],{"class":749,"line":836},[747,18636,18637],{"class":753},"      namePattern",[747,18639,856],{"class":757},[747,18641,3537],{"class":757},[747,18643,18644],{"class":802},"ancientt-results-{{ .Data.Tester }}.csv",[747,18646,13042],{"class":757},[747,18648,18649,18652],{"class":749,"line":842},[747,18650,18651],{"class":753},"  hosts",[747,18653,758],{"class":757},[747,18655,18656,18659],{"class":749,"line":850},[747,18657,18658],{"class":753},"    servers",[747,18660,758],{"class":757},[747,18662,18663,18666,18668,18670],{"class":749,"line":863},[747,18664,18665],{"class":757},"    -",[747,18667,14804],{"class":753},[747,18669,856],{"class":757},[747,18671,18672],{"class":802}," one-random\n",[747,18674,18675,18678,18680],{"class":749,"line":869},[747,18676,18677],{"class":753},"      random",[747,18679,856],{"class":757},[747,18681,860],{"class":859},[747,18683,18684,18687,18689],{"class":749,"line":877},[747,18685,18686],{"class":753},"      count",[747,18688,856],{"class":757},[747,18690,18691],{"class":1895}," 1\n",[747,18693,18694,18697],{"class":749,"line":1015},[747,18695,18696],{"class":753},"    clients",[747,18698,758],{"class":757},[747,18700,18701,18703,18705,18707],{"class":749,"line":1021},[747,18702,18665],{"class":757},[747,18704,14804],{"class":753},[747,18706,856],{"class":757},[747,18708,18709],{"class":802}," all-hosts\n",[747,18711,18712,18715,18717],{"class":749,"line":1027},[747,18713,18714],{"class":753},"      all",[747,18716,856],{"class":757},[747,18718,860],{"class":859},[747,18720,18721,18724],{"class":749,"line":1033},[747,18722,18723],{"class":753},"  iperf3",[747,18725,758],{"class":757},[747,18727,18728,18731,18733],{"class":749,"line":1039},[747,18729,18730],{"class":753},"    duration",[747,18732,856],{"class":757},[747,18734,18735],{"class":1895}," 30\n",[523,18737,18738,18739,18742],{},"The above \"test definitions\" file tells Ancinett, to use the Kubernetes \"runner\", to run a test from one randomly chosen Node to all the other Nodes (+ itself) in the Kubernetes cluster.\nTest results are stored as CSV in files named after the given ",[567,18740,18741],{},"namePattern"," to make it easy to split results by \"server\", \"client\" and other available variables.",[6072,18744,18745],{},[523,18746,18747,18749],{},[584,18748,6189],{}," It doesn't have to be a Kubernetes cluster, an OpenShift cluster works as well.",[523,18751,18752,18753,1909],{},"Besides being able to run on Kubernetes and OpenShift, you can also provide an Ansible inventory file which also can be used to run tests on it.\nThe targeted hosts need to have the network testing tools installed as of right now. An example Ansible playbook can be found here: ",[527,18754,18757,18758,5620],{"href":18755,"rel":18756},"https:\u002F\u002Fgithub.com\u002Fcloudical-io\u002Fancientt\u002Ftree\u002Fmaster\u002Fexamples\u002Frunners\u002Fansible",[531],"GitHub cloudical-io\u002Fancientt - ",[567,18759,18760],{},"examples\u002Frunners\u002Fansible",[613,18762,18764],{"id":18763},"why-did-we-create-ancientt","Why did we create Ancientt",[523,18766,18767],{},"More and more people are moving to platforms like Kubernetes, OpenStack, OpenShift and others. The biggest problem we see in such installments is most of the time the network. Either because of performance, latency or general connectivity issues.",[523,18769,18770,18771,18773],{},"Ancientt right now allows us to easily run ",[567,18772,18520],{}," tests across whole Kubernetes and OpenShift clusters, and normal machines (through Ansible). Doing such tests manually takes a lot of time away from  other potentially critical points that should be investigated.\nWith Ancientt you can easily run such tests faster. This should save you time and the results hopefully get you faster to a resolution of the problem and\u002F or improving your network performance.",[523,18775,18776,18777,714,18780,18783],{},"We'll hopefully soon be able to add more network testing tools to the list, to make it even easier to run tests. E.g., ",[567,18778,18779],{},"smokeping",[567,18781,18782],{},"siege"," and others, should be able to help with latency and performance tests.",[613,18785,18787],{"id":18786},"future-of-ancientt","Future of Ancientt",[523,18789,18790,18791,1909],{},"For the near future, we'll focus on making it possible to get the results into Prometheus. This would allow for constant network testing, monitoring and alerting on issues.\nIf you have a good idea on how this can be achieved, feel free to comment on ",[527,18792,18795],{"href":18793,"rel":18794},"https:\u002F\u002Fgithub.com\u002Fcloudical-io\u002Fancientt\u002Fissues\u002F38",[531],"GitHub cloudical-io\u002Fancientt - Issue 'outputs: Prometheus' #38",[523,18797,18798,18799,18802,18803,1909],{},"As written in the ",[527,18800,18764],{"href":18801},"#why-did-we-create-ancientt"," section, we'll look into adding more network testing tools.\nFor a list of potential new network testing tools to be worked on for Ancinett, checkout ",[527,18804,18807],{"href":18805,"rel":18806},"https:\u002F\u002Fgithub.com\u002Fcloudical-io\u002Fancientt\u002Fissues?q=is%3Aissue+is%3Aopen+label%3Atesters",[531],"GitHub cloudical-io\u002Fancientt Issues with Label `testers",[613,18809,18811],{"id":18810},"wanna-try-out-ancientt","Wanna try out Ancientt?",[523,18813,18814,18815,1909],{},"Checkout the Ancientt project on GitHub: ",[527,18816,18819],{"href":18817,"rel":18818},"https:\u002F\u002Fgithub.com\u002Fcloudical-io\u002Fancientt\u002F",[531],"GitHub cloudical-io\u002Fancientt",[523,18821,18822,18823,18828,18829,1909],{},"To get you started on the test definition options available, there is a ",[527,18824,18827],{"href":18825,"rel":18826},"https:\u002F\u002Fgithub.com\u002Fcloudical-io\u002Fancientt\u002Fblob\u002Fmaster\u002Fdocs\u002Fconfig-examples.md",[531],"config examples doc page",".\nIf you want to dive into all available test defintion options, see ",[527,18830,18833],{"href":18831,"rel":18832},"https:\u002F\u002Fgithub.com\u002Fcloudical-io\u002Fancientt\u002Fblob\u002Fmaster\u002Fdocs\u002Fconfig-structure.md",[531],"onfig structure doc page",[523,18835,18836,18837,1909],{},"All available documentation can be found in the ",[527,18838,18757,18841,5620],{"href":18839,"rel":18840},"https:\u002F\u002Fgithub.com\u002Fcloudical-io\u002Fancientt\u002Ftree\u002Fmaster\u002Fdocs",[531],[567,18842,7],{},[535,18844,14526],{"id":14525},[523,18846,18847,18848,18850],{},"Ancientt can help you run ",[567,18849,18520],{}," tests, soon other network test tools as well, in a Kubernetes and OpenShift clusters, and using Ansible in an organized and quick way. Most importantly also collect the test results in an orderly fashion in output formats, like CSV, Excel, MySQL and SQLite.",[523,18852,18853,18854,1909],{},"Be sure to check out the project on GitHub: ",[527,18855,18819],{"href":18817,"rel":18856},[531],[523,18858,18859],{},"We are happy about any contributions, be it documentation or code changes.",[523,18861,18862],{},"If you like the project, be sure to leave a Star to help the project reach more people.",[523,18864,13967],{},[2890,18866,18867],{},"html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":743,"searchDepth":761,"depth":761,"links":18869},[18870,18875],{"id":18513,"depth":761,"text":18514,"children":18871},[18872,18873,18874],{"id":18763,"depth":769,"text":18764},{"id":18786,"depth":769,"text":18787},{"id":18810,"depth":769,"text":18811},{"id":14525,"depth":761,"text":14526},"2019-10-12T13:10:52+02:00","Let's see what Ancientt is and how Ancientt can help by automating certain network testing tools.",{"src":18879},"\u002Fblog\u002F2019\u002Fancientt-automation-for-network-testing-tools\u002Fancientt.jpg",{"tags":18881},[15155,12427,176,18882,18883,12529],"Open Source","Project","\u002Fblog\u002F2019\u002Fancientt-automation-for-network-testing-tools",{"title":18487,"description":18877},"3.blog\u002F2019\u002Fancientt-automation-for-network-testing-tools","rve0kHeI3YnjvoUDQO2ohnvLELd5CsUOkx_GCQF9Rio",{"id":18889,"title":18890,"authors":18891,"badge":518,"body":18894,"date":18912,"description":18913,"extension":2911,"image":18914,"meta":18916,"navigation":1254,"path":18921,"seo":18922,"stem":18923,"__hash__":18924},"posts\u002F3.blog\u002F2019\u002Fsitrep-container-and-ipv6-presentation.md","Sitrep Container and IPv6 Presentation",[18892],{"name":514,"to":515,"avatar":18893},{"src":517},{"type":520,"value":18895,"toc":18910},[18896,18899,18902,18907],[523,18897,18898],{},"I created this presentation for a local IPv6 \"Stammtisch\" to talk about the current situation of IPv6 in Docker and Kubernetes.",[523,18900,18901],{},"If you want to present these slides somewhere, please get in contact with me first. Thanks!",[18903,18904],"iframe",{"src":18905,"frameBorder":3579,"height":18906,"allowFullScreen":5306,"mozallowfullscreen":5306,"webkitallowfullscreen":5306},"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002Fe\u002F2PACX-1vRbG0WGDIOhWw93j6vZfF7WP_4eowY7CraJZdqDe1xazk8hsY-m4bGe-BddszWLUlo7VwGJmYWFj-T4\u002Fembed?start=false&loop=true&delayms=5000",575,[523,18908,18909],{},"If you have any suggestions for the presentation, feel free to leave them in the comments.",{"title":743,"searchDepth":761,"depth":761,"links":18911},[],"2019-09-25T20:23:04+02:00","My 'Sitrep Container and IPv6' slides which I held at an IPv6 meetup.",{"src":18915},"\u002Fblog\u002F2019\u002Fsitrep-container-and-ipv6-presentation\u002Fcover.png",{"tags":18917},[18918,18919,12427,18920],"Presentations","IPv6","ContainerDays","\u002Fblog\u002F2019\u002Fsitrep-container-and-ipv6-presentation",{"title":18890,"description":18913},"3.blog\u002F2019\u002Fsitrep-container-and-ipv6-presentation","n7Ni4jDjvoVnClXCaJ4lIZ29q0qvR2SBBYJuH5qIW2Q",{"id":18926,"title":18927,"authors":18928,"badge":518,"body":18931,"date":19054,"description":19055,"extension":2911,"image":19056,"meta":19058,"navigation":1254,"path":19060,"seo":19061,"stem":19062,"__hash__":19063},"posts\u002F3.blog\u002F2019\u002Fimportance-of-ipv6-in-a-cloudy-world-presentation.md","Importance of IPv6 in a Cloudy World Presentation",[18929],{"name":514,"to":515,"avatar":18930},{"src":517},{"type":520,"value":18932,"toc":19050},[18933,18941,18943,18946,18948,18952,18960,18965,18969,19015,19020,19048],[523,18934,18935,18936,1909],{},"I created this presentation to show off why IPv6 is important in the current day and age of Cloud at ",[527,18937,18940],{"href":18938,"rel":18939},"https:\u002F\u002Fcontainerdays.io\u002F",[531],"Container Days Hamburg",[523,18942,18901],{},[18903,18944],{"src":18945,"frameBorder":3579,"height":18906,"allowFullScreen":5306,"mozallowfullscreen":5306,"webkitallowfullscreen":5306},"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002Fe\u002F2PACX-1vSTUOUprgklcX5m9_Xdl6gaGL1PxRvumW0IFrinej0e4cXyIqlGYs8tqusLBA1_ASJXRX5MGJ-v_KnP\u002Fembed?start=false&loop=true&delayms=5000",[523,18947,18909],{},[535,18949,18951],{"id":18950},"recording","Recording",[523,18953,18954,18955,856],{},"The recording of the talk can be found on ",[527,18956,18959],{"href":18957,"rel":18958},"https:\u002F\u002Fwww.youtube.com\u002Fchannel\u002FUCi1CejrHbE6QPz37dG9gMFA",[531],"Container Days YouTube channel",[18903,18961],{"height":18962,"src":18963,"frameBorder":3579,"allow":18964,"allowFullScreen":1254},"575px","https:\u002F\u002Fwww.youtube.com\u002Fembed\u002FoZKC1i1KYPQ?list=PLHhKcdBlprMdg-fwPD1b3IjBRR_Ga09H0","accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",[535,18966,18968],{"id":18967},"impressions","Impressions",[6072,18970,18974,19010,19011],{"className":18971,"dataLang":18973},[18972],"twitter-tweet","en",[523,18975,18977,18978,18982,18984,18985,18989,18990,8287,18994,8287,18998,8287,19002,8287,19006],{"lang":18973,"dir":18976},"ltr","Good morning ",[527,18979,18981],{"href":18980},"https:\u002F\u002Ftwitter.com\u002Fhashtag\u002Fcontainerdays?src=hash&ref_src=twsrc%5Etfw","#containerdays",[12608,18983],{},"We're starting the day with Alexander Trost ",[527,18986,18988],{"href":18987},"https:\u002F\u002Ftwitter.com\u002Fgalexrt?ref_src=twsrc%5Etfw","@galexrt"," showing us the importance of IPv6...",[527,18991,18993],{"href":18992},"https:\u002F\u002Ftwitter.com\u002Fhashtag\u002FCDS19?src=hash&ref_src=twsrc%5Etfw","#CDS19",[527,18995,18997],{"href":18996},"https:\u002F\u002Ftwitter.com\u002Fhashtag\u002Fcloudnative?src=hash&ref_src=twsrc%5Etfw","#cloudnative",[527,18999,19001],{"href":19000},"https:\u002F\u002Ftwitter.com\u002Fhashtag\u002Fcloudical?src=hash&ref_src=twsrc%5Etfw","#cloudical",[527,19003,19005],{"href":19004},"https:\u002F\u002Ftwitter.com\u002Fhashtag\u002FCloudexcellence?src=hash&ref_src=twsrc%5Etfw","#Cloudexcellence",[527,19007,19009],{"href":19008},"https:\u002F\u002Ft.co\u002FbWDC1gqArD","pic.twitter.com\u002FbWDC1gqArD","— Cloudical (@cloudical_gmbh) ",[527,19012,19014],{"href":19013},"https:\u002F\u002Ftwitter.com\u002Fcloudical_gmbh\u002Fstatus\u002F1143783269021945856?ref_src=twsrc%5Etfw","June 26, 2019",[19016,19017],"script",{"async":1254,"src":19018,"charSet":19019},"https:\u002F\u002Fplatform.twitter.com\u002Fwidgets.js","utf-8",[6072,19021,19023,19044,19045],{"className":19022,"dataLang":18973},[18972],[523,19024,19025,19029,19030,19032,19033,11304,19035,19037,19039,19040],{"lang":18973,"dir":18976},[527,19026,19028],{"href":19027},"https:\u002F\u002Ftwitter.com\u002Fcloudical_gmbh?ref_src=twsrc%5Etfw","@cloudical_gmbh","'s ",[527,19031,18988],{"href":18987}," on stage at ",[527,19034,18993],{"href":18992},[12608,19036],{},[12608,19038],{},"Like his talk. ",[527,19041,19043],{"href":19042},"https:\u002F\u002Ft.co\u002FvhzvTzhmFT","pic.twitter.com\u002FvhzvTzhmFT","— Karsten Samaschke (@samaschke) ",[527,19046,19014],{"href":19047},"https:\u002F\u002Ftwitter.com\u002Fsamaschke\u002Fstatus\u002F1143783409954828293?ref_src=twsrc%5Etfw",[19016,19049],{"async":1254,"src":19018,"charSet":19019},{"title":743,"searchDepth":761,"depth":761,"links":19051},[19052,19053],{"id":18950,"depth":761,"text":18951},{"id":18967,"depth":761,"text":18968},"2019-06-28T12:50:19+02:00","My 'Importance of IPv6 in a Cloudy World Presentation' slides which I held at the ContainerDays Hamburg 2019.",{"src":19057},"\u002Fblog\u002F2019\u002Fimportance-of-ipv6-in-a-cloudy-world-presentation\u002Fimportance-of-ipv6-in-a-cloudy-world-presentation.png",{"tags":19059},[18918,18919,12427,18920],"\u002Fblog\u002F2019\u002Fimportance-of-ipv6-in-a-cloudy-world-presentation",{"title":18927,"description":19055},"3.blog\u002F2019\u002Fimportance-of-ipv6-in-a-cloudy-world-presentation","NlsTRoMEhwFBJeVbdI58QGvqKNlYsnewz2d9SuPcDm4",{"id":19065,"title":19066,"authors":19067,"badge":518,"body":19070,"date":22219,"description":22220,"extension":2911,"image":22221,"meta":22223,"navigation":1254,"path":22228,"seo":22229,"stem":22230,"__hash__":22231},"posts\u002F3.blog\u002F2019\u002Fmatrix-synapse-saml2-login.md","Matrix Synapse SAML2 Login",[19068],{"name":514,"to":515,"avatar":19069},{"src":517},{"type":520,"value":19071,"toc":22201},[19072,19081,19083,19097,19118,19122,19133,19144,19149,19170,19183,19187,19191,19194,19200,19203,19490,19493,19499,19514,19518,19528,19534,19557,19561,19565,19568,19582,19591,19598,19609,19635,19645,19654,19776,19789,19795,19812,19819,19823,19839,19844,19849,20490,20495,20504,20511,21148,21154,21157,21302,21325,21329,21332,22163,22179,22181,22184,22190,22196,22198],[6072,19073,19074,19078],{},[523,19075,19076],{},[584,19077,6189],{},[523,19079,19080],{},"This is a very rough write-up on how to use Keycloak SAML2 with a Matrix Synapse Homeserver for user authentication. Keep in mind that not all points outlined here may 100% work for you and \"turning and changing\" some parameters may be needed to get it working for your setup.",[535,19082,538],{"id":537},[523,19084,19085,19086,19091,19092,1909],{},"This blog post is especially made for Keycloak SAML 2.0 SSO with Matrix with the ",[527,19087,19090],{"href":19088,"rel":19089},"https:\u002F\u002Fgithub.com\u002Fmatrix-org\u002Fsynapse\u002Fpull\u002F5422",[531],"GitHub matrix-org\u002Fsynapse - Complete the SAML2 implementation #5422",", which is based on my draft PR ",[527,19093,19096],{"href":19094,"rel":19095},"https:\u002F\u002Fgithub.com\u002Fmatrix-org\u002Fsynapse\u002Fpull\u002F5316",[531],"GitHub matrix-org\u002Fsynapse - SAML2 Improvements and redirect stuff #5316",[6072,19098,19099,19104],{},[523,19100,19101],{},[584,19102,19103],{},"THANKS",[523,19105,19106,19107,714,19112,19117],{},"Thanks to Helder Ferreira (",[527,19108,19111],{"href":19109,"rel":19110},"https:\u002F\u002Ftwitter.com\u002Fwounn",[531],"@wounn Twitter",[527,19113,19116],{"href":19114,"rel":19115},"https:\u002F\u002Fgithub.com\u002FHelderFSFerreira",[531],"HelderFSFerreira GitHub",") for reaching out to me and updating the configs in this post!",[535,19119,19121],{"id":19120},"matrix-syanspe","Matrix Syanspe",[523,19123,19124,19125,1909],{},"To get SAML 2.0 working you need to have a Matrix Synapse Homeserver running version at least ",[527,19126,19129,19130],{"href":19127,"rel":19128},"https:\u002F\u002Fmatrix.org\u002Fblog\u002F2019\u002F07\u002F04\u002Fsynapse-1-1-0-released",[531],"version ",[567,19131,19132],{},"1.1,0",[523,19134,19135,19136,19139,19140,19143],{},"In addition to that you need to have the ",[567,19137,19138],{},"pysaml2"," Python module installed and ",[567,19141,19142],{},"xmlsec1"," must be installed on the Matrix Synapse homeserver too.",[523,19145,19146,19147,1909],{},"On Debian and CentOS (possibly all RHEL based OSes) the package is called ",[567,19148,19142],{},[523,19150,19151,19152,19154,19155,19158,19159,19161,19162,19165,19166,19169],{},"Be sure to verify that the path to ",[567,19153,19142],{}," is correctly configured in the upcoming ",[567,19156,19157],{},"\u002Fsynapse\u002Fconfig\u002Fsp_conf.py"," section. To make sure you have the right path for the ",[567,19160,19138],{}," config, run ",[567,19163,19164],{},"which xmlsec1"," and use the printed out path for the ",[567,19167,19168],{},"xmlsec_binary"," option.",[6072,19171,19172,19176],{},[523,19173,19174],{},[584,19175,6189],{},[523,19177,19178,19179,19182],{},"The blog post assumes that the config for the Matrix Synapse Homeserver is located in ",[567,19180,19181],{},"\u002Fsynapse\u002Fconfig\u002F"," directory, you can simply change this as long as you change it in all files and\u002F or steps to do.",[535,19184,19186],{"id":19185},"keycloak","Keycloak",[613,19188,19190],{"id":19189},"saml2-client","SAML2 Client",[523,19192,19193],{},"In Keycloak create a new SAML client and set the settings of that client as follows:",[523,19195,19196],{},[3069,19197],{"alt":19198,"src":19199},"Keycloak Client Settings","\u002Fblog\u002F2019\u002Fmatrix-synapse-saml2-login\u002Fkeycloak-client-settings-tab.png",[523,19201,19202],{},"Two mappers should be created:",[668,19204,19205,19255],{},[638,19206,19207,19209,19210,19214],{},[567,19208,5477],{}," for the username.\n",[3069,19211],{"alt":19212,"src":19213},"Keycloak Client Mapper uid Options","\u002Fblog\u002F2019\u002Fmatrix-synapse-saml2-login\u002Fkeycloak-client-mapper-uid.png",[668,19215,19216,19225,19233,19240,19247],{},[638,19217,19218,19221,19222],{},[567,19219,19220],{},"Mapper Type"," - ",[567,19223,19224],{},"User Property",[638,19226,19227,19221,19230],{},[567,19228,19229],{},"Property",[567,19231,19232],{},"Username",[638,19234,19235,19221,19238],{},[567,19236,19237],{},"Friendly Name",[567,19239,5477],{},[638,19241,19242,19221,19245],{},[567,19243,19244],{},"SAML Attribute Name",[567,19246,5477],{},[638,19248,19249,19221,19252],{},[567,19250,19251],{},"SAML Attribute NameFormat",[567,19253,19254],{},"URI Reference",[638,19256,19257,19260,19261,19265],{},[567,19258,19259],{},"displayName"," for the displayed name in Keycloak.\n",[3069,19262],{"alt":19263,"src":19264},"Keycloak Client Mapper displayName Options","\u002Fblog\u002F2019\u002Fmatrix-synapse-saml2-login\u002Fkeycloak-client-mapper-displayname.png",[668,19266,19267,19274,19463,19471,19477,19483],{},[638,19268,19269,19221,19271],{},[567,19270,19220],{},[567,19272,19273],{},"Javascript Mapper",[638,19275,19276,19279],{},[567,19277,19278],{},"Script",[738,19280,19284],{"className":19281,"code":19282,"language":19283,"meta":743,"style":743},"language-javascript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F Concat First and Last name of user when non-empty\nnames = [];\n\nfirstName = user.getFirstName();\nif (firstName.length > 0) {\n    names.push(firstName);\n}\nlastName = user.getLastName();\nif (lastName.length > 0) {\n    names.push(lastName);\n}\n\nexports = names.join(\" \");\n","javascript",[567,19285,19286,19291,19304,19308,19328,19351,19370,19375,19393,19412,19429,19433,19437],{"__ignoreMap":743},[747,19287,19288],{"class":749,"line":750},[747,19289,19290],{"class":772},"\u002F\u002F Concat First and Last name of user when non-empty\n",[747,19292,19293,19296,19298,19301],{"class":749,"line":761},[747,19294,19295],{"class":1640},"names ",[747,19297,6425],{"class":757},[747,19299,19300],{"class":1640}," []",[747,19302,19303],{"class":757},";\n",[747,19305,19306],{"class":749,"line":769},[747,19307,1255],{"emptyLinePlaceholder":1254},[747,19309,19310,19313,19315,19318,19320,19323,19326],{"class":749,"line":776},[747,19311,19312],{"class":1640},"firstName ",[747,19314,6425],{"class":757},[747,19316,19317],{"class":1640}," user",[747,19319,1909],{"class":757},[747,19321,19322],{"class":4574},"getFirstName",[747,19324,19325],{"class":1640},"()",[747,19327,19303],{"class":757},[747,19329,19330,19334,19337,19339,19342,19344,19346,19349],{"class":749,"line":784},[747,19331,19333],{"class":19332},"s7zQu","if",[747,19335,19336],{"class":1640}," (firstName",[747,19338,1909],{"class":757},[747,19340,19341],{"class":1640},"length ",[747,19343,2035],{"class":757},[747,19345,3588],{"class":1895},[747,19347,19348],{"class":1640},") ",[747,19350,13004],{"class":757},[747,19352,19353,19356,19358,19361,19363,19366,19368],{"class":749,"line":790},[747,19354,19355],{"class":1640},"    names",[747,19357,1909],{"class":757},[747,19359,19360],{"class":4574},"push",[747,19362,2000],{"class":753},[747,19364,19365],{"class":1640},"firstName",[747,19367,2006],{"class":753},[747,19369,19303],{"class":757},[747,19371,19372],{"class":749,"line":796},[747,19373,19374],{"class":757},"}\n",[747,19376,19377,19380,19382,19384,19386,19389,19391],{"class":749,"line":806},[747,19378,19379],{"class":1640},"lastName ",[747,19381,6425],{"class":757},[747,19383,19317],{"class":1640},[747,19385,1909],{"class":757},[747,19387,19388],{"class":4574},"getLastName",[747,19390,19325],{"class":1640},[747,19392,19303],{"class":757},[747,19394,19395,19397,19400,19402,19404,19406,19408,19410],{"class":749,"line":814},[747,19396,19333],{"class":19332},[747,19398,19399],{"class":1640}," (lastName",[747,19401,1909],{"class":757},[747,19403,19341],{"class":1640},[747,19405,2035],{"class":757},[747,19407,3588],{"class":1895},[747,19409,19348],{"class":1640},[747,19411,13004],{"class":757},[747,19413,19414,19416,19418,19420,19422,19425,19427],{"class":749,"line":822},[747,19415,19355],{"class":1640},[747,19417,1909],{"class":757},[747,19419,19360],{"class":4574},[747,19421,2000],{"class":753},[747,19423,19424],{"class":1640},"lastName",[747,19426,2006],{"class":753},[747,19428,19303],{"class":757},[747,19430,19431],{"class":749,"line":830},[747,19432,19374],{"class":757},[747,19434,19435],{"class":749,"line":836},[747,19436,1255],{"emptyLinePlaceholder":1254},[747,19438,19439,19442,19445,19448,19450,19453,19455,19457,19459,19461],{"class":749,"line":842},[747,19440,19441],{"class":757},"exports",[747,19443,19444],{"class":757}," =",[747,19446,19447],{"class":1640}," names",[747,19449,1909],{"class":757},[747,19451,19452],{"class":4574},"join",[747,19454,2000],{"class":1640},[747,19456,3892],{"class":757},[747,19458,969],{"class":757},[747,19460,2006],{"class":1640},[747,19462,19303],{"class":757},[638,19464,19465,19221,19468],{},[567,19466,19467],{},"Single Value Attribute",[567,19469,19470],{},"On",[638,19472,19473,19221,19475],{},[567,19474,19237],{},[567,19476,19259],{},[638,19478,19479,19221,19481],{},[567,19480,19244],{},[567,19482,19259],{},[638,19484,19485,19221,19487],{},[567,19486,19251],{},[567,19488,19489],{},"Basic",[523,19491,19492],{},"In the end it should look like this:",[523,19494,19495],{},[3069,19496],{"alt":19497,"src":19498},"Keycloak Client Mappers List","\u002Fblog\u002F2019\u002Fmatrix-synapse-saml2-login\u002Fkeycloak-client-mappers-list.png",[6072,19500,19501,19505],{},[523,19502,19503],{},[584,19504,15676],{},[523,19506,19507,19508,19513],{},"Thanks to ",[527,19509,19512],{"href":19510,"rel":19511},"http:\u002F\u002Fdisq.us\u002Fp\u002F239xrfr",[531],"this comment"," for pointing to the correct attributes to use for Matrix Synapse code to pick'em up!",[613,19515,19517],{"id":19516},"saml-20-identity-provider-metadata-file","SAML 2.0 Identity Provider Metadata file",[523,19519,19520,19521,19523,19524,19527],{},"Now download the Keycloak \"SAML 2.0 Identity Provider Metadata\" file.\nYou can get it when you login to the \"Keycloak Admin Console\" and then click the \"SAML 2.0 Identity Provider Metadata\" link in the ",[567,19522,74],{}," tab (selected by default) at the ",[567,19525,19526],{},"Endpoints"," list.",[523,19529,19530],{},[3069,19531],{"alt":19532,"src":19533},"Keycloak Realm Settings","\u002Fblog\u002F2019\u002Fmatrix-synapse-saml2-login\u002Fkeycloak-realm-settings.png",[6072,19535,19536,19540,19550],{},[523,19537,19538],{},[584,19539,6189],{},[523,19541,19542,19543,19545,19546,19549],{},"Should you not have this button\u002F link in the ",[567,19544,19526],{}," list, update your Keycloak instance to version ",[567,19547,19548],{},"6.0.1"," or higher!",[523,19551,19552,19553,19556],{},"If you have a very good reason to not keep your Keycloak uptodate, you can try to get the file from ",[567,19554,19555],{},"https:\u002F\u002FYOUR_KEYCLOAK_URL\u002Fauth\u002Frealms\u002FYOUR_REALM\u002Fprotocol\u002Fsaml\u002Fdescriptor",".\n(Replace the placeholders according to your setup)",[535,19558,19560],{"id":19559},"files","Files",[613,19562,19564],{"id":19563},"replacements","Replacements",[523,19566,19567],{},"Be sure to replace the following strings with your value:",[668,19569,19570,19576],{},[638,19571,19572,19575],{},[567,19573,19574],{},"matrix.example.com"," - Your Matrix homeserver address.",[638,19577,19578,19581],{},[567,19579,19580],{},"matrix-example-com"," - The name of the SAML2 Keycloak client you chose during the client creation.",[613,19583,19585,587,19588],{"id":19584},"synapseconfigkeypem-and-synapseconfigcertpem",[567,19586,19587],{},"\u002Fsynapse\u002Fconfig\u002Fkey.pem",[567,19589,19590],{},"\u002Fsynapse\u002Fconfig\u002Fcert.pem",[523,19592,19593,19594,19597],{},"Certificate and key from Keycloak Client \"SAML Keys\" tab page.\nIf there is no certificate and key shown, press the ",[567,19595,19596],{},"Generate new keys"," button to generate them.",[523,19599,19600,19601,19604,19605,19608],{},"Click the ",[567,19602,19603],{},"Export"," button, set the following options before clicking the ",[567,19606,19607],{},"Download"," button:",[668,19610,19611,19617,19620,19623,19629],{},[638,19612,19613,19614],{},"Archive Format: ",[567,19615,19616],{},"PKCS12",[638,19618,19619],{},"Key Alias: The name of your Keycloak Client.",[638,19621,19622],{},"Key Password: A password which is used later to \"decrypt\" the PKCS12 cert + key store.",[638,19624,19625,19626],{},"Realm Certificate Alias: ",[567,19627,19628],{},"master",[638,19630,19631,19632,1909],{},"Store password: Either another password or the same as for ",[567,19633,19634],{},"Key Password",[523,19636,19637,19638,19641,19642,19644],{},"You should get a file named ",[567,19639,19640],{},"keystore.p12"," after pressing the ",[567,19643,19607],{}," button.",[523,19646,19647,19648,19650,19651,7258],{},"Now run the following sequence of commands to extract the key and cert in PEM format (this assumes the file is named ",[567,19649,19640],{}," and the password chosen is ",[567,19652,19653],{},"example123",[738,19655,19657],{"className":1621,"code":19656,"language":1623,"meta":743,"style":743},"$ export KEYSTORE_PW=\"example123\"\n$ openssl pkcs12 -in keystore.p12 -password \"pass:${KEYSTORE_PW}\" -nocerts -nodes | openssl rsa -out key.pem\nwriting RSA key\n$ openssl pkcs12 -in keystore.p12 -password \"pass:${KEYSTORE_PW}\" -nodes | openssl x509 -out cert.pem\n",[567,19658,19659,19675,19727,19738],{"__ignoreMap":743},[747,19660,19661,19663,19666,19669,19671,19673],{"class":749,"line":750},[747,19662,1919],{"class":1630},[747,19664,19665],{"class":802}," export",[747,19667,19668],{"class":802}," KEYSTORE_PW=",[747,19670,3892],{"class":757},[747,19672,19653],{"class":802},[747,19674,975],{"class":757},[747,19676,19677,19679,19682,19685,19688,19691,19694,19696,19699,19702,19705,19708,19711,19714,19716,19718,19721,19724],{"class":749,"line":761},[747,19678,1919],{"class":1630},[747,19680,19681],{"class":802}," openssl",[747,19683,19684],{"class":802}," pkcs12",[747,19686,19687],{"class":802}," -in",[747,19689,19690],{"class":802}," keystore.p12",[747,19692,19693],{"class":802}," -password",[747,19695,969],{"class":757},[747,19697,19698],{"class":802},"pass:",[747,19700,19701],{"class":757},"${",[747,19703,19704],{"class":1640},"KEYSTORE_PW",[747,19706,19707],{"class":757},"}\"",[747,19709,19710],{"class":802}," -nocerts",[747,19712,19713],{"class":802}," -nodes",[747,19715,3170],{"class":757},[747,19717,19681],{"class":1630},[747,19719,19720],{"class":802}," rsa",[747,19722,19723],{"class":802}," -out",[747,19725,19726],{"class":802}," key.pem\n",[747,19728,19729,19732,19735],{"class":749,"line":769},[747,19730,19731],{"class":1630},"writing",[747,19733,19734],{"class":802}," RSA",[747,19736,19737],{"class":802}," key\n",[747,19739,19740,19742,19744,19746,19748,19750,19752,19754,19756,19758,19760,19762,19764,19766,19768,19771,19773],{"class":749,"line":776},[747,19741,1919],{"class":1630},[747,19743,19681],{"class":802},[747,19745,19684],{"class":802},[747,19747,19687],{"class":802},[747,19749,19690],{"class":802},[747,19751,19693],{"class":802},[747,19753,969],{"class":757},[747,19755,19698],{"class":802},[747,19757,19701],{"class":757},[747,19759,19704],{"class":1640},[747,19761,19707],{"class":757},[747,19763,19713],{"class":802},[747,19765,3170],{"class":757},[747,19767,19681],{"class":1630},[747,19769,19770],{"class":802}," x509",[747,19772,19723],{"class":802},[747,19774,19775],{"class":802}," cert.pem\n",[523,19777,19778,19779,587,19782,19785,19786,19788],{},"Two files, ",[567,19780,19781],{},"key.pem",[567,19783,19784],{},"cert.pem",", are now generated in your current directory and now just need to be placed in the ",[567,19787,19181],{}," directory (full paths see section title) on the Matrix Synapse host(s).",[613,19790,19792],{"id":19791},"synapseconfigidpxml",[567,19793,19794],{},"\u002Fsynapse\u002Fconfig\u002Fidp.xml",[6072,19796,19797,19801],{},[523,19798,19799],{},[584,19800,6189],{},[523,19802,19803,19804,19808,19809,19811],{},"If you have already downloaded the \"SAML 2.0 Identity Provider Metadata\" file as mentioned in the ",[527,19805,19807],{"href":19806},"#saml-2-0-identity-provider-metadata-file","Keycloak - SAML 2.0 Identity Provider Metadata file section",", you can just use and copy it to ",[567,19810,19794],{}," on the Matrix Synapse Homeserver.",[523,19813,19814,19815,19523,19817,19527],{},"You can get it when you login to the \"Keycloak Admin Console\" and then click the \"SAML 2.0 Identity Provider Metadata\" link in the ",[567,19816,74],{},[567,19818,19526],{},[523,19820,19821],{},[3069,19822],{"alt":19532,"src":19533},[6072,19824,19825,19829,19835],{},[523,19826,19827],{},[584,19828,6189],{},[523,19830,19542,19831,19545,19833,19549],{},[567,19832,19526],{},[567,19834,19548],{},[523,19836,19552,19837,19556],{},[567,19838,19555],{},[523,19840,19841,19842,19811],{},"Be sure to copy the downloaded file to ",[567,19843,19794],{},[523,19845,19846,856],{},[584,19847,19848],{},"Example Keycloak SAML 2.0 Identity Provider Metadata file",[738,19850,19854],{"className":19851,"code":19852,"language":19853,"meta":743,"style":743},"language-xml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\u003C!--\n  ~ Copyright 2016 Red Hat, Inc. and\u002For its affiliates\n  ~ and other contributors as indicated by the @author tags.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~ http:\u002F\u002Fwww.apache.org\u002Flicenses\u002FLICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n\u003CEntitiesDescriptor Name=\"urn:keycloak\" xmlns=\"urn:oasis:names:tc:SAML:2.0:metadata\"\n                    xmlns:dsig=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002F09\u002Fxmldsig#\">\n    \u003CEntityDescriptor entityID=\"https:\u002F\u002F__YOUR_KEYCLOAK_URL__\u002Fauth\u002Frealms\u002Fmaster\">\n        \u003CIDPSSODescriptor WantAuthnRequestsSigned=\"true\"\n            protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol\">\n                        \u003CKeyDescriptor use=\"signing\">\n                          \u003Cdsig:KeyInfo>\n                            \u003Cdsig:KeyName>[REDACTED]\u003C\u002Fdsig:KeyName>\n                            \u003Cdsig:X509Data>\n                              \u003Cdsig:X509Certificate>[REDACTED]\u003C\u002Fdsig:X509Certificate>\n                            \u003C\u002Fdsig:X509Data>\n                          \u003C\u002Fdsig:KeyInfo>\n                        \u003C\u002FKeyDescriptor>\n\n            \u003CSingleLogoutService\n                    Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\"\n                    Location=\"https:\u002F\u002F__YOUR_KEYCLOAK_URL__\u002Fauth\u002Frealms\u002Fmaster\u002Fprotocol\u002Fsaml\" \u002F>\n            \u003CSingleLogoutService\n                    Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\"\n                    Location=\"https:\u002F\u002F__YOUR_KEYCLOAK_URL__\u002Fauth\u002Frealms\u002Fmaster\u002Fprotocol\u002Fsaml\" \u002F>\n            \u003CNameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent\u003C\u002FNameIDFormat>\n            \u003CNameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient\u003C\u002FNameIDFormat>\n            \u003CNameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified\u003C\u002FNameIDFormat>\n            \u003CNameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\u003C\u002FNameIDFormat>\n            \u003CSingleSignOnService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\"\n                Location=\"https:\u002F\u002F__YOUR_KEYCLOAK_URL__\u002Fauth\u002Frealms\u002Fmaster\u002Fprotocol\u002Fsaml\" \u002F>\n            \u003CSingleSignOnService\n                Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\"\n                Location=\"https:\u002F\u002F__YOUR_KEYCLOAK_URL__\u002Fauth\u002Frealms\u002Fmaster\u002Fprotocol\u002Fsaml\" \u002F>\n            \u003CSingleSignOnService\n                Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:SOAP\"\n                Location=\"https:\u002F\u002F__YOUR_KEYCLOAK_URL__\u002Fauth\u002Frealms\u002Fmaster\u002Fprotocol\u002Fsaml\" \u002F>\n        \u003C\u002FIDPSSODescriptor>\n    \u003C\u002FEntityDescriptor>\n\u003C\u002FEntitiesDescriptor>\n","xml",[567,19855,19856,19891,19896,19901,19906,19911,19916,19921,19926,19930,19935,19939,19944,19949,19954,19959,19964,19969,19973,20004,20025,20047,20066,20082,20103,20117,20145,20158,20184,20197,20210,20219,20223,20231,20245,20262,20268,20281,20295,20313,20330,20347,20364,20382,20397,20404,20417,20431,20437,20450,20464,20473,20482],{"__ignoreMap":743},[747,19857,19858,19861,19863,19867,19869,19871,19874,19876,19879,19881,19883,19886,19888],{"class":749,"line":750},[747,19859,19860],{"class":757},"\u003C?",[747,19862,19853],{"class":753},[747,19864,19866],{"class":19865},"spNyl"," version",[747,19868,6425],{"class":757},[747,19870,3892],{"class":757},[747,19872,19873],{"class":802},"1.0",[747,19875,3892],{"class":757},[747,19877,19878],{"class":19865}," encoding",[747,19880,6425],{"class":757},[747,19882,3892],{"class":757},[747,19884,19885],{"class":802},"UTF-8",[747,19887,3892],{"class":757},[747,19889,19890],{"class":757},"?>\n",[747,19892,19893],{"class":749,"line":761},[747,19894,19895],{"class":772},"\u003C!--\n",[747,19897,19898],{"class":749,"line":769},[747,19899,19900],{"class":772},"  ~ Copyright 2016 Red Hat, Inc. and\u002For its affiliates\n",[747,19902,19903],{"class":749,"line":776},[747,19904,19905],{"class":772},"  ~ and other contributors as indicated by the @author tags.\n",[747,19907,19908],{"class":749,"line":784},[747,19909,19910],{"class":772},"  ~\n",[747,19912,19913],{"class":749,"line":790},[747,19914,19915],{"class":772},"  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n",[747,19917,19918],{"class":749,"line":796},[747,19919,19920],{"class":772},"  ~ you may not use this file except in compliance with the License.\n",[747,19922,19923],{"class":749,"line":806},[747,19924,19925],{"class":772},"  ~ You may obtain a copy of the License at\n",[747,19927,19928],{"class":749,"line":814},[747,19929,19910],{"class":772},[747,19931,19932],{"class":749,"line":822},[747,19933,19934],{"class":772},"  ~ http:\u002F\u002Fwww.apache.org\u002Flicenses\u002FLICENSE-2.0\n",[747,19936,19937],{"class":749,"line":830},[747,19938,19910],{"class":772},[747,19940,19941],{"class":749,"line":836},[747,19942,19943],{"class":772},"  ~ Unless required by applicable law or agreed to in writing, software\n",[747,19945,19946],{"class":749,"line":842},[747,19947,19948],{"class":772},"  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n",[747,19950,19951],{"class":749,"line":850},[747,19952,19953],{"class":772},"  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",[747,19955,19956],{"class":749,"line":863},[747,19957,19958],{"class":772},"  ~ See the License for the specific language governing permissions and\n",[747,19960,19961],{"class":749,"line":869},[747,19962,19963],{"class":772},"  ~ limitations under the License.\n",[747,19965,19966],{"class":749,"line":877},[747,19967,19968],{"class":772},"  -->\n",[747,19970,19971],{"class":749,"line":1015},[747,19972,1255],{"emptyLinePlaceholder":1254},[747,19974,19975,19977,19980,19983,19985,19987,19990,19992,19995,19997,19999,20002],{"class":749,"line":1021},[747,19976,5469],{"class":757},[747,19978,19979],{"class":753},"EntitiesDescriptor",[747,19981,19982],{"class":19865}," Name",[747,19984,6425],{"class":757},[747,19986,3892],{"class":757},[747,19988,19989],{"class":802},"urn:keycloak",[747,19991,3892],{"class":757},[747,19993,19994],{"class":19865}," xmlns",[747,19996,6425],{"class":757},[747,19998,3892],{"class":757},[747,20000,20001],{"class":802},"urn:oasis:names:tc:SAML:2.0:metadata",[747,20003,975],{"class":757},[747,20005,20006,20009,20011,20014,20016,20018,20021,20023],{"class":749,"line":1027},[747,20007,20008],{"class":19865},"                    xmlns",[747,20010,856],{"class":757},[747,20012,20013],{"class":19865},"dsig",[747,20015,6425],{"class":757},[747,20017,3892],{"class":757},[747,20019,20020],{"class":802},"http:\u002F\u002Fwww.w3.org\u002F2000\u002F09\u002Fxmldsig#",[747,20022,3892],{"class":757},[747,20024,2301],{"class":757},[747,20026,20027,20030,20033,20036,20038,20040,20043,20045],{"class":749,"line":1033},[747,20028,20029],{"class":757},"    \u003C",[747,20031,20032],{"class":753},"EntityDescriptor",[747,20034,20035],{"class":19865}," entityID",[747,20037,6425],{"class":757},[747,20039,3892],{"class":757},[747,20041,20042],{"class":802},"https:\u002F\u002F__YOUR_KEYCLOAK_URL__\u002Fauth\u002Frealms\u002Fmaster",[747,20044,3892],{"class":757},[747,20046,2301],{"class":757},[747,20048,20049,20052,20055,20058,20060,20062,20064],{"class":749,"line":1039},[747,20050,20051],{"class":757},"        \u003C",[747,20053,20054],{"class":753},"IDPSSODescriptor",[747,20056,20057],{"class":19865}," WantAuthnRequestsSigned",[747,20059,6425],{"class":757},[747,20061,3892],{"class":757},[747,20063,5306],{"class":802},[747,20065,975],{"class":757},[747,20067,20068,20071,20073,20075,20078,20080],{"class":749,"line":1054},[747,20069,20070],{"class":19865},"            protocolSupportEnumeration",[747,20072,6425],{"class":757},[747,20074,3892],{"class":757},[747,20076,20077],{"class":802},"urn:oasis:names:tc:SAML:2.0:protocol",[747,20079,3892],{"class":757},[747,20081,2301],{"class":757},[747,20083,20084,20087,20090,20092,20094,20096,20099,20101],{"class":749,"line":1060},[747,20085,20086],{"class":757},"                        \u003C",[747,20088,20089],{"class":753},"KeyDescriptor",[747,20091,4556],{"class":19865},[747,20093,6425],{"class":757},[747,20095,3892],{"class":757},[747,20097,20098],{"class":802},"signing",[747,20100,3892],{"class":757},[747,20102,2301],{"class":757},[747,20104,20105,20108,20110,20112,20115],{"class":749,"line":1066},[747,20106,20107],{"class":757},"                          \u003C",[747,20109,20013],{"class":753},[747,20111,856],{"class":757},[747,20113,20114],{"class":753},"KeyInfo",[747,20116,2301],{"class":757},[747,20118,20119,20122,20124,20126,20129,20131,20134,20137,20139,20141,20143],{"class":749,"line":1081},[747,20120,20121],{"class":757},"                            \u003C",[747,20123,20013],{"class":753},[747,20125,856],{"class":757},[747,20127,20128],{"class":753},"KeyName",[747,20130,2035],{"class":757},[747,20132,20133],{"class":1640},"[REDACTED]",[747,20135,20136],{"class":757},"\u003C\u002F",[747,20138,20013],{"class":753},[747,20140,856],{"class":757},[747,20142,20128],{"class":753},[747,20144,2301],{"class":757},[747,20146,20147,20149,20151,20153,20156],{"class":749,"line":1087},[747,20148,20121],{"class":757},[747,20150,20013],{"class":753},[747,20152,856],{"class":757},[747,20154,20155],{"class":753},"X509Data",[747,20157,2301],{"class":757},[747,20159,20160,20163,20165,20167,20170,20172,20174,20176,20178,20180,20182],{"class":749,"line":1102},[747,20161,20162],{"class":757},"                              \u003C",[747,20164,20013],{"class":753},[747,20166,856],{"class":757},[747,20168,20169],{"class":753},"X509Certificate",[747,20171,2035],{"class":757},[747,20173,20133],{"class":1640},[747,20175,20136],{"class":757},[747,20177,20013],{"class":753},[747,20179,856],{"class":757},[747,20181,20169],{"class":753},[747,20183,2301],{"class":757},[747,20185,20186,20189,20191,20193,20195],{"class":749,"line":1110},[747,20187,20188],{"class":757},"                            \u003C\u002F",[747,20190,20013],{"class":753},[747,20192,856],{"class":757},[747,20194,20155],{"class":753},[747,20196,2301],{"class":757},[747,20198,20199,20202,20204,20206,20208],{"class":749,"line":1117},[747,20200,20201],{"class":757},"                          \u003C\u002F",[747,20203,20013],{"class":753},[747,20205,856],{"class":757},[747,20207,20114],{"class":753},[747,20209,2301],{"class":757},[747,20211,20212,20215,20217],{"class":749,"line":1123},[747,20213,20214],{"class":757},"                        \u003C\u002F",[747,20216,20089],{"class":753},[747,20218,2301],{"class":757},[747,20220,20221],{"class":749,"line":1129},[747,20222,1255],{"emptyLinePlaceholder":1254},[747,20224,20225,20228],{"class":749,"line":1142},[747,20226,20227],{"class":757},"            \u003C",[747,20229,20230],{"class":753},"SingleLogoutService\n",[747,20232,20233,20236,20238,20240,20243],{"class":749,"line":1150},[747,20234,20235],{"class":19865},"                    Binding",[747,20237,6425],{"class":757},[747,20239,3892],{"class":757},[747,20241,20242],{"class":802},"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",[747,20244,975],{"class":757},[747,20246,20247,20250,20252,20254,20257,20259],{"class":749,"line":1157},[747,20248,20249],{"class":19865},"                    Location",[747,20251,6425],{"class":757},[747,20253,3892],{"class":757},[747,20255,20256],{"class":802},"https:\u002F\u002F__YOUR_KEYCLOAK_URL__\u002Fauth\u002Frealms\u002Fmaster\u002Fprotocol\u002Fsaml",[747,20258,3892],{"class":757},[747,20260,20261],{"class":757}," \u002F>\n",[747,20263,20264,20266],{"class":749,"line":1163},[747,20265,20227],{"class":757},[747,20267,20230],{"class":753},[747,20269,20270,20272,20274,20276,20279],{"class":749,"line":1168},[747,20271,20235],{"class":19865},[747,20273,6425],{"class":757},[747,20275,3892],{"class":757},[747,20277,20278],{"class":802},"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect",[747,20280,975],{"class":757},[747,20282,20283,20285,20287,20289,20291,20293],{"class":749,"line":1174},[747,20284,20249],{"class":19865},[747,20286,6425],{"class":757},[747,20288,3892],{"class":757},[747,20290,20256],{"class":802},[747,20292,3892],{"class":757},[747,20294,20261],{"class":757},[747,20296,20297,20299,20302,20304,20307,20309,20311],{"class":749,"line":1480},[747,20298,20227],{"class":757},[747,20300,20301],{"class":753},"NameIDFormat",[747,20303,2035],{"class":757},[747,20305,20306],{"class":1640},"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",[747,20308,20136],{"class":757},[747,20310,20301],{"class":753},[747,20312,2301],{"class":757},[747,20314,20315,20317,20319,20321,20324,20326,20328],{"class":749,"line":1491},[747,20316,20227],{"class":757},[747,20318,20301],{"class":753},[747,20320,2035],{"class":757},[747,20322,20323],{"class":1640},"urn:oasis:names:tc:SAML:2.0:nameid-format:transient",[747,20325,20136],{"class":757},[747,20327,20301],{"class":753},[747,20329,2301],{"class":757},[747,20331,20332,20334,20336,20338,20341,20343,20345],{"class":749,"line":1496},[747,20333,20227],{"class":757},[747,20335,20301],{"class":753},[747,20337,2035],{"class":757},[747,20339,20340],{"class":1640},"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",[747,20342,20136],{"class":757},[747,20344,20301],{"class":753},[747,20346,2301],{"class":757},[747,20348,20349,20351,20353,20355,20358,20360,20362],{"class":749,"line":1502},[747,20350,20227],{"class":757},[747,20352,20301],{"class":753},[747,20354,2035],{"class":757},[747,20356,20357],{"class":1640},"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",[747,20359,20136],{"class":757},[747,20361,20301],{"class":753},[747,20363,2301],{"class":757},[747,20365,20366,20368,20371,20374,20376,20378,20380],{"class":749,"line":1510},[747,20367,20227],{"class":757},[747,20369,20370],{"class":753},"SingleSignOnService",[747,20372,20373],{"class":19865}," Binding",[747,20375,6425],{"class":757},[747,20377,3892],{"class":757},[747,20379,20242],{"class":802},[747,20381,975],{"class":757},[747,20383,20384,20387,20389,20391,20393,20395],{"class":749,"line":1520},[747,20385,20386],{"class":19865},"                Location",[747,20388,6425],{"class":757},[747,20390,3892],{"class":757},[747,20392,20256],{"class":802},[747,20394,3892],{"class":757},[747,20396,20261],{"class":757},[747,20398,20399,20401],{"class":749,"line":1525},[747,20400,20227],{"class":757},[747,20402,20403],{"class":753},"SingleSignOnService\n",[747,20405,20406,20409,20411,20413,20415],{"class":749,"line":1533},[747,20407,20408],{"class":19865},"                Binding",[747,20410,6425],{"class":757},[747,20412,3892],{"class":757},[747,20414,20278],{"class":802},[747,20416,975],{"class":757},[747,20418,20419,20421,20423,20425,20427,20429],{"class":749,"line":1539},[747,20420,20386],{"class":19865},[747,20422,6425],{"class":757},[747,20424,3892],{"class":757},[747,20426,20256],{"class":802},[747,20428,3892],{"class":757},[747,20430,20261],{"class":757},[747,20432,20433,20435],{"class":749,"line":1549},[747,20434,20227],{"class":757},[747,20436,20403],{"class":753},[747,20438,20439,20441,20443,20445,20448],{"class":749,"line":1554},[747,20440,20408],{"class":19865},[747,20442,6425],{"class":757},[747,20444,3892],{"class":757},[747,20446,20447],{"class":802},"urn:oasis:names:tc:SAML:2.0:bindings:SOAP",[747,20449,975],{"class":757},[747,20451,20452,20454,20456,20458,20460,20462],{"class":749,"line":1562},[747,20453,20386],{"class":19865},[747,20455,6425],{"class":757},[747,20457,3892],{"class":757},[747,20459,20256],{"class":802},[747,20461,3892],{"class":757},[747,20463,20261],{"class":757},[747,20465,20466,20469,20471],{"class":749,"line":1568},[747,20467,20468],{"class":757},"        \u003C\u002F",[747,20470,20054],{"class":753},[747,20472,2301],{"class":757},[747,20474,20475,20478,20480],{"class":749,"line":1577},[747,20476,20477],{"class":757},"    \u003C\u002F",[747,20479,20032],{"class":753},[747,20481,2301],{"class":757},[747,20483,20484,20486,20488],{"class":749,"line":1582},[747,20485,20136],{"class":757},[747,20487,19979],{"class":753},[747,20489,2301],{"class":757},[613,20491,20493],{"id":20492},"synapseconfigsp_confpy",[567,20494,19157],{},[523,20496,20497,20498,20500,20501,20503],{},"This is the ",[567,20499,19138],{}," config file. It configures ",[567,20502,19138],{}," to talk with the Keycloak server and do SAML2 authentication.",[523,20505,20506,20507,2006],{},"Create this file with the following content:\n(Don't forget to replace the placeholders, see ",[527,20508,20510],{"href":20509},"#replacements","Replacements section",[738,20512,20516],{"className":20513,"code":20514,"language":20515,"meta":743,"style":743},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import saml2\nfrom saml2.saml import NAME_FORMAT_URI\n\nBASE = \"https:\u002F\u002Fmatrix.example.com\u002F\"\n\nCONFIG = {\n    \"entityid\": \"matrix-example-com\",\n    \"description\": \"Matrix Server\",\n    \"service\": {\n        \"sp\": {\n            \"name\": \"matrix-login\",\n            \"endpoints\": {\n                \"single_sign_on_service\": [\n                    (BASE + \"_matrix\u002Fsaml2\u002Fauthn_response\", saml2.BINDING_HTTP_POST),\n                ],\n                \"assertion_consumer_service\": [\n                    (BASE + \"_matrix\u002Fsaml2\u002Fauthn_response\", saml2.BINDING_HTTP_POST),\n                ],\n                #\"single_logout_service\": [\n                #    (BASE + \"_matrix\u002Fsaml2\u002Flogout\", saml2.BINDING_HTTP_POST),\n                #],\n            },\n            \"required_attributes\": [\"uid\",],\n            \"optional_attributes\": [\"displayName\"],\n            \"sign_assertion\": True,\n            \"sign_response\": True,\n        }\n    },\n    \"debug\": 0,\n    \"key_file\": \"\u002Fsynapse\u002Fconfig\u002Fkey.pem\",\n    \"cert_file\": \"\u002Fsynapse\u002Fconfig\u002Fcert.pem\",\n    \"encryption_keypairs\": [\n        {\n            \"key_file\": \"\u002Fsynapse\u002Fconfig\u002Fkey.pem\",\n            \"cert_file\": \"\u002Fsynapse\u002Fconfig\u002Fcert.pem\",\n        }\n    ],\n    \"attribute_map_dir\": \"\u002Fsynapse\u002Fsaml2_attribute_maps\u002F\",\n    \"metadata\": {\n        \"local\": [\"\u002Fsynapse\u002Fconfig\u002Fidp.xml\"]\n    },\n    # If you want to have organization and contact_person for the pysaml2 config\n    #\"organization\": {\n    #    \"name\": \"Example AB\",\n    #    \"display_name\": [(\"Example AB\", \"se\"), (\"Example Co.\", \"en\")],\n    #    \"url\": \"http:\u002F\u002Fexample.com\u002Froland\",\n    #},\n    #\"contact_person\": [{\n    #    \"given_name\": \"Example\",\n    #    \"sur_name\": \"Example\",\n    #    \"email_address\": [\"example@example.com\"],\n    #    \"contact_type\": \"technical\",\n    #    },\n    #],\n    # Make sure to have xmlsec1 installed on your host(s)!\n    \"xmlsec_binary\": \"\u002Fusr\u002Fbin\u002Fxmlsec1\",\n    \"name_form\": NAME_FORMAT_URI,\n}\n","python",[567,20517,20518,20526,20543,20547,20561,20565,20575,20596,20616,20628,20642,20662,20675,20690,20719,20724,20737,20761,20765,20770,20775,20780,20785,20807,20829,20843,20856,20861,20866,20881,20900,20919,20932,20937,20955,20973,20977,20982,21002,21014,21035,21039,21044,21049,21054,21059,21064,21069,21074,21079,21084,21089,21094,21099,21104,21109,21128,21144],{"__ignoreMap":743},[747,20519,20520,20523],{"class":749,"line":750},[747,20521,20522],{"class":19332},"import",[747,20524,20525],{"class":1640}," saml2\n",[747,20527,20528,20530,20533,20535,20538,20540],{"class":749,"line":761},[747,20529,3594],{"class":19332},[747,20531,20532],{"class":1640}," saml2",[747,20534,1909],{"class":757},[747,20536,20537],{"class":1640},"saml ",[747,20539,20522],{"class":19332},[747,20541,20542],{"class":1640}," NAME_FORMAT_URI\n",[747,20544,20545],{"class":749,"line":769},[747,20546,1255],{"emptyLinePlaceholder":1254},[747,20548,20549,20552,20554,20556,20559],{"class":749,"line":776},[747,20550,20551],{"class":1640},"BASE ",[747,20553,6425],{"class":757},[747,20555,969],{"class":757},[747,20557,20558],{"class":802},"https:\u002F\u002Fmatrix.example.com\u002F",[747,20560,975],{"class":757},[747,20562,20563],{"class":749,"line":784},[747,20564,1255],{"emptyLinePlaceholder":1254},[747,20566,20567,20570,20572],{"class":749,"line":790},[747,20568,20569],{"class":1640},"CONFIG ",[747,20571,6425],{"class":757},[747,20573,20574],{"class":757}," {\n",[747,20576,20577,20580,20583,20585,20587,20589,20591,20593],{"class":749,"line":796},[747,20578,20579],{"class":757},"    \"",[747,20581,20582],{"class":802},"entityid",[747,20584,3892],{"class":757},[747,20586,856],{"class":757},[747,20588,969],{"class":757},[747,20590,19580],{"class":802},[747,20592,3892],{"class":757},[747,20594,20595],{"class":757},",\n",[747,20597,20598,20600,20603,20605,20607,20609,20612,20614],{"class":749,"line":806},[747,20599,20579],{"class":757},[747,20601,20602],{"class":802},"description",[747,20604,3892],{"class":757},[747,20606,856],{"class":757},[747,20608,969],{"class":757},[747,20610,20611],{"class":802},"Matrix Server",[747,20613,3892],{"class":757},[747,20615,20595],{"class":757},[747,20617,20618,20620,20622,20624,20626],{"class":749,"line":814},[747,20619,20579],{"class":757},[747,20621,3243],{"class":802},[747,20623,3892],{"class":757},[747,20625,856],{"class":757},[747,20627,20574],{"class":757},[747,20629,20630,20633,20636,20638,20640],{"class":749,"line":822},[747,20631,20632],{"class":757},"        \"",[747,20634,20635],{"class":802},"sp",[747,20637,3892],{"class":757},[747,20639,856],{"class":757},[747,20641,20574],{"class":757},[747,20643,20644,20647,20649,20651,20653,20655,20658,20660],{"class":749,"line":830},[747,20645,20646],{"class":757},"            \"",[747,20648,5472],{"class":802},[747,20650,3892],{"class":757},[747,20652,856],{"class":757},[747,20654,969],{"class":757},[747,20656,20657],{"class":802},"matrix-login",[747,20659,3892],{"class":757},[747,20661,20595],{"class":757},[747,20663,20664,20666,20669,20671,20673],{"class":749,"line":836},[747,20665,20646],{"class":757},[747,20667,20668],{"class":802},"endpoints",[747,20670,3892],{"class":757},[747,20672,856],{"class":757},[747,20674,20574],{"class":757},[747,20676,20677,20680,20683,20685,20687],{"class":749,"line":842},[747,20678,20679],{"class":757},"                \"",[747,20681,20682],{"class":802},"single_sign_on_service",[747,20684,3892],{"class":757},[747,20686,856],{"class":757},[747,20688,20689],{"class":757}," [\n",[747,20691,20692,20695,20697,20700,20702,20705,20707,20709,20711,20713,20716],{"class":749,"line":850},[747,20693,20694],{"class":757},"                    (",[747,20696,20551],{"class":1640},[747,20698,20699],{"class":757},"+",[747,20701,969],{"class":757},[747,20703,20704],{"class":802},"_matrix\u002Fsaml2\u002Fauthn_response",[747,20706,3892],{"class":757},[747,20708,10580],{"class":757},[747,20710,20532],{"class":1640},[747,20712,1909],{"class":757},[747,20714,20715],{"class":753},"BINDING_HTTP_POST",[747,20717,20718],{"class":757},"),\n",[747,20720,20721],{"class":749,"line":863},[747,20722,20723],{"class":757},"                ],\n",[747,20725,20726,20728,20731,20733,20735],{"class":749,"line":869},[747,20727,20679],{"class":757},[747,20729,20730],{"class":802},"assertion_consumer_service",[747,20732,3892],{"class":757},[747,20734,856],{"class":757},[747,20736,20689],{"class":757},[747,20738,20739,20741,20743,20745,20747,20749,20751,20753,20755,20757,20759],{"class":749,"line":877},[747,20740,20694],{"class":757},[747,20742,20551],{"class":1640},[747,20744,20699],{"class":757},[747,20746,969],{"class":757},[747,20748,20704],{"class":802},[747,20750,3892],{"class":757},[747,20752,10580],{"class":757},[747,20754,20532],{"class":1640},[747,20756,1909],{"class":757},[747,20758,20715],{"class":753},[747,20760,20718],{"class":757},[747,20762,20763],{"class":749,"line":1015},[747,20764,20723],{"class":757},[747,20766,20767],{"class":749,"line":1021},[747,20768,20769],{"class":772},"                #\"single_logout_service\": [\n",[747,20771,20772],{"class":749,"line":1027},[747,20773,20774],{"class":772},"                #    (BASE + \"_matrix\u002Fsaml2\u002Flogout\", saml2.BINDING_HTTP_POST),\n",[747,20776,20777],{"class":749,"line":1033},[747,20778,20779],{"class":772},"                #],\n",[747,20781,20782],{"class":749,"line":1039},[747,20783,20784],{"class":757},"            },\n",[747,20786,20787,20789,20792,20794,20796,20798,20800,20802,20804],{"class":749,"line":1054},[747,20788,20646],{"class":757},[747,20790,20791],{"class":802},"required_attributes",[747,20793,3892],{"class":757},[747,20795,856],{"class":757},[747,20797,4262],{"class":757},[747,20799,3892],{"class":757},[747,20801,5477],{"class":802},[747,20803,3892],{"class":757},[747,20805,20806],{"class":757},",],\n",[747,20808,20809,20811,20814,20816,20818,20820,20822,20824,20826],{"class":749,"line":1060},[747,20810,20646],{"class":757},[747,20812,20813],{"class":802},"optional_attributes",[747,20815,3892],{"class":757},[747,20817,856],{"class":757},[747,20819,4262],{"class":757},[747,20821,3892],{"class":757},[747,20823,19259],{"class":802},[747,20825,3892],{"class":757},[747,20827,20828],{"class":757},"],\n",[747,20830,20831,20833,20836,20838,20840],{"class":749,"line":1066},[747,20832,20646],{"class":757},[747,20834,20835],{"class":802},"sign_assertion",[747,20837,3892],{"class":757},[747,20839,856],{"class":757},[747,20841,20842],{"class":757}," True,\n",[747,20844,20845,20847,20850,20852,20854],{"class":749,"line":1081},[747,20846,20646],{"class":757},[747,20848,20849],{"class":802},"sign_response",[747,20851,3892],{"class":757},[747,20853,856],{"class":757},[747,20855,20842],{"class":757},[747,20857,20858],{"class":749,"line":1087},[747,20859,20860],{"class":757},"        }\n",[747,20862,20863],{"class":749,"line":1102},[747,20864,20865],{"class":757},"    },\n",[747,20867,20868,20870,20873,20875,20877,20879],{"class":749,"line":1110},[747,20869,20579],{"class":757},[747,20871,20872],{"class":802},"debug",[747,20874,3892],{"class":757},[747,20876,856],{"class":757},[747,20878,3588],{"class":1895},[747,20880,20595],{"class":757},[747,20882,20883,20885,20888,20890,20892,20894,20896,20898],{"class":749,"line":1117},[747,20884,20579],{"class":757},[747,20886,20887],{"class":802},"key_file",[747,20889,3892],{"class":757},[747,20891,856],{"class":757},[747,20893,969],{"class":757},[747,20895,19587],{"class":802},[747,20897,3892],{"class":757},[747,20899,20595],{"class":757},[747,20901,20902,20904,20907,20909,20911,20913,20915,20917],{"class":749,"line":1123},[747,20903,20579],{"class":757},[747,20905,20906],{"class":802},"cert_file",[747,20908,3892],{"class":757},[747,20910,856],{"class":757},[747,20912,969],{"class":757},[747,20914,19590],{"class":802},[747,20916,3892],{"class":757},[747,20918,20595],{"class":757},[747,20920,20921,20923,20926,20928,20930],{"class":749,"line":1129},[747,20922,20579],{"class":757},[747,20924,20925],{"class":802},"encryption_keypairs",[747,20927,3892],{"class":757},[747,20929,856],{"class":757},[747,20931,20689],{"class":757},[747,20933,20934],{"class":749,"line":1142},[747,20935,20936],{"class":757},"        {\n",[747,20938,20939,20941,20943,20945,20947,20949,20951,20953],{"class":749,"line":1150},[747,20940,20646],{"class":757},[747,20942,20887],{"class":802},[747,20944,3892],{"class":757},[747,20946,856],{"class":757},[747,20948,969],{"class":757},[747,20950,19587],{"class":802},[747,20952,3892],{"class":757},[747,20954,20595],{"class":757},[747,20956,20957,20959,20961,20963,20965,20967,20969,20971],{"class":749,"line":1157},[747,20958,20646],{"class":757},[747,20960,20906],{"class":802},[747,20962,3892],{"class":757},[747,20964,856],{"class":757},[747,20966,969],{"class":757},[747,20968,19590],{"class":802},[747,20970,3892],{"class":757},[747,20972,20595],{"class":757},[747,20974,20975],{"class":749,"line":1163},[747,20976,20860],{"class":757},[747,20978,20979],{"class":749,"line":1168},[747,20980,20981],{"class":757},"    ],\n",[747,20983,20984,20986,20989,20991,20993,20995,20998,21000],{"class":749,"line":1174},[747,20985,20579],{"class":757},[747,20987,20988],{"class":802},"attribute_map_dir",[747,20990,3892],{"class":757},[747,20992,856],{"class":757},[747,20994,969],{"class":757},[747,20996,20997],{"class":802},"\u002Fsynapse\u002Fsaml2_attribute_maps\u002F",[747,20999,3892],{"class":757},[747,21001,20595],{"class":757},[747,21003,21004,21006,21008,21010,21012],{"class":749,"line":1480},[747,21005,20579],{"class":757},[747,21007,12973],{"class":802},[747,21009,3892],{"class":757},[747,21011,856],{"class":757},[747,21013,20574],{"class":757},[747,21015,21016,21018,21021,21023,21025,21027,21029,21031,21033],{"class":749,"line":1491},[747,21017,20632],{"class":757},[747,21019,21020],{"class":802},"local",[747,21022,3892],{"class":757},[747,21024,856],{"class":757},[747,21026,4262],{"class":757},[747,21028,3892],{"class":757},[747,21030,19794],{"class":802},[747,21032,3892],{"class":757},[747,21034,4268],{"class":757},[747,21036,21037],{"class":749,"line":1496},[747,21038,20865],{"class":757},[747,21040,21041],{"class":749,"line":1502},[747,21042,21043],{"class":772},"    # If you want to have organization and contact_person for the pysaml2 config\n",[747,21045,21046],{"class":749,"line":1510},[747,21047,21048],{"class":772},"    #\"organization\": {\n",[747,21050,21051],{"class":749,"line":1520},[747,21052,21053],{"class":772},"    #    \"name\": \"Example AB\",\n",[747,21055,21056],{"class":749,"line":1525},[747,21057,21058],{"class":772},"    #    \"display_name\": [(\"Example AB\", \"se\"), (\"Example Co.\", \"en\")],\n",[747,21060,21061],{"class":749,"line":1533},[747,21062,21063],{"class":772},"    #    \"url\": \"http:\u002F\u002Fexample.com\u002Froland\",\n",[747,21065,21066],{"class":749,"line":1539},[747,21067,21068],{"class":772},"    #},\n",[747,21070,21071],{"class":749,"line":1549},[747,21072,21073],{"class":772},"    #\"contact_person\": [{\n",[747,21075,21076],{"class":749,"line":1554},[747,21077,21078],{"class":772},"    #    \"given_name\": \"Example\",\n",[747,21080,21081],{"class":749,"line":1562},[747,21082,21083],{"class":772},"    #    \"sur_name\": \"Example\",\n",[747,21085,21086],{"class":749,"line":1568},[747,21087,21088],{"class":772},"    #    \"email_address\": [\"example@example.com\"],\n",[747,21090,21091],{"class":749,"line":1577},[747,21092,21093],{"class":772},"    #    \"contact_type\": \"technical\",\n",[747,21095,21096],{"class":749,"line":1582},[747,21097,21098],{"class":772},"    #    },\n",[747,21100,21101],{"class":749,"line":1588},[747,21102,21103],{"class":772},"    #],\n",[747,21105,21106],{"class":749,"line":1594},[747,21107,21108],{"class":772},"    # Make sure to have xmlsec1 installed on your host(s)!\n",[747,21110,21111,21113,21115,21117,21119,21121,21124,21126],{"class":749,"line":1600},[747,21112,20579],{"class":757},[747,21114,19168],{"class":802},[747,21116,3892],{"class":757},[747,21118,856],{"class":757},[747,21120,969],{"class":757},[747,21122,21123],{"class":802},"\u002Fusr\u002Fbin\u002Fxmlsec1",[747,21125,3892],{"class":757},[747,21127,20595],{"class":757},[747,21129,21130,21132,21135,21137,21139,21142],{"class":749,"line":4804},[747,21131,20579],{"class":757},[747,21133,21134],{"class":802},"name_form",[747,21136,3892],{"class":757},[747,21138,856],{"class":757},[747,21140,21141],{"class":1640}," NAME_FORMAT_URI",[747,21143,20595],{"class":757},[747,21145,21146],{"class":749,"line":4810},[747,21147,19374],{"class":757},[613,21149,21151],{"id":21150},"synapsesaml2_attribute_mapsmappy",[567,21152,21153],{},"\u002Fsynapse\u002Fsaml2_attribute_maps\u002Fmap.py",[523,21155,21156],{},"This file is your way to map attributes coming from the SSO (\u002F IDP) service.",[738,21158,21160],{"className":20513,"code":21159,"language":20515,"meta":743,"style":743},"MAP = {\n    \"identifier\": \"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\",\n    \"fro\": {\n        'uid': 'uid',\n        'displayName': 'displayName',\n    },\n    \"to\": {\n        'uid': 'uid',\n        'displayName': 'displayName',\n    }\n}\n",[567,21161,21162,21171,21191,21204,21223,21241,21245,21257,21275,21293,21298],{"__ignoreMap":743},[747,21163,21164,21167,21169],{"class":749,"line":750},[747,21165,21166],{"class":1640},"MAP ",[747,21168,6425],{"class":757},[747,21170,20574],{"class":757},[747,21172,21173,21175,21178,21180,21182,21184,21187,21189],{"class":749,"line":761},[747,21174,20579],{"class":757},[747,21176,21177],{"class":802},"identifier",[747,21179,3892],{"class":757},[747,21181,856],{"class":757},[747,21183,969],{"class":757},[747,21185,21186],{"class":802},"urn:oasis:names:tc:SAML:2.0:attrname-format:uri",[747,21188,3892],{"class":757},[747,21190,20595],{"class":757},[747,21192,21193,21195,21198,21200,21202],{"class":749,"line":769},[747,21194,20579],{"class":757},[747,21196,21197],{"class":802},"fro",[747,21199,3892],{"class":757},[747,21201,856],{"class":757},[747,21203,20574],{"class":757},[747,21205,21206,21209,21211,21213,21215,21217,21219,21221],{"class":749,"line":776},[747,21207,21208],{"class":757},"        '",[747,21210,5477],{"class":802},[747,21212,3543],{"class":757},[747,21214,856],{"class":757},[747,21216,3537],{"class":757},[747,21218,5477],{"class":802},[747,21220,3543],{"class":757},[747,21222,20595],{"class":757},[747,21224,21225,21227,21229,21231,21233,21235,21237,21239],{"class":749,"line":784},[747,21226,21208],{"class":757},[747,21228,19259],{"class":802},[747,21230,3543],{"class":757},[747,21232,856],{"class":757},[747,21234,3537],{"class":757},[747,21236,19259],{"class":802},[747,21238,3543],{"class":757},[747,21240,20595],{"class":757},[747,21242,21243],{"class":749,"line":790},[747,21244,20865],{"class":757},[747,21246,21247,21249,21251,21253,21255],{"class":749,"line":796},[747,21248,20579],{"class":757},[747,21250,4990],{"class":802},[747,21252,3892],{"class":757},[747,21254,856],{"class":757},[747,21256,20574],{"class":757},[747,21258,21259,21261,21263,21265,21267,21269,21271,21273],{"class":749,"line":806},[747,21260,21208],{"class":757},[747,21262,5477],{"class":802},[747,21264,3543],{"class":757},[747,21266,856],{"class":757},[747,21268,3537],{"class":757},[747,21270,5477],{"class":802},[747,21272,3543],{"class":757},[747,21274,20595],{"class":757},[747,21276,21277,21279,21281,21283,21285,21287,21289,21291],{"class":749,"line":814},[747,21278,21208],{"class":757},[747,21280,19259],{"class":802},[747,21282,3543],{"class":757},[747,21284,856],{"class":757},[747,21286,3537],{"class":757},[747,21288,19259],{"class":802},[747,21290,3543],{"class":757},[747,21292,20595],{"class":757},[747,21294,21295],{"class":749,"line":822},[747,21296,21297],{"class":757},"    }\n",[747,21299,21300],{"class":749,"line":830},[747,21301,19374],{"class":757},[6072,21303,21304,21308],{},[523,21305,21306],{},[584,21307,6189],{},[523,21309,21310,21315,21316,1909],{},[584,21311,21312,21314],{},[567,21313,21197],{}," in the above file is not a typo",", see ",[527,21317,21320,21322,21323],{"href":21318,"rel":21319},"https:\u002F\u002Fpysaml2.readthedocs.io\u002Fen\u002Flatest\u002Fhowto\u002Fconfig.html#attribute-map-dir",[531],[567,21321,19138],{}," Documentation - \"Configuration of pySAML2 entities\" - ",[567,21324,20988],{},[613,21326,21328],{"id":21327},"your-matrix-synapse-homeserver-config-yaml-file","Your Matrix Synapse Homeserver Config YAML file",[523,21330,21331],{},"Add or change the following lines to your Matrix Synapse Homeserver config (make sure you don't duplicate the lines as that may lead to weird server behavior and\u002F or issues):",[738,21333,21335],{"className":740,"code":21334,"language":742,"meta":743,"style":743},"[...]\n## Registration ##\n#\n# Registration can be rate-limited using the parameters in the \"Ratelimiting\"\n# section of this file.\n\n# Enable registration for new users.\n#\nenable_registration: false\n\n\nsaml2_config:\n  # `sp_config` is the configuration for the pysaml2 Service Provider.\n  # See pysaml2 docs for format of config.\n  #\n  # Default values will be used for the 'entityid' and 'service' settings,\n  # so it is not normally necessary to specify them unless you need to\n  # override them.\n  #\n  sp_config:\n  #  # point this to the IdP's metadata. You can use either a local file or\n  #  # (preferably) a URL.\n    metadata:\n  #    #local: [\"saml2\u002Fidp.xml\"]\n      remote:\n        - url: https:\u002F\u002FYOUR_KEYCLOAK_URL\u002Fauth\u002Frealms\u002FYOUR_REALM\u002Fprotocol\u002Fsaml\u002Fdescriptor\n  #\n  #    # By default, the user has to go to our login page first. If you'd like\n  #    # to allow IdP-initiated login, set 'allow_unsolicited: true' in a\n  #    # 'service.sp' section:\n  #    #\n  #    #service:\n  #    #  sp:\n  #    #    allow_unsolicited: true\n  #\n  #    # The examples below are just used to generate our metadata xml, and you\n  #    # may well not need them, depending on your setup. Alternatively you\n  #    # may need a whole lot more detail - see the pysaml2 docs!\n  #\n  #    description: [\"My awesome SP\", \"en\"]\n  #    name: [\"Test SP\", \"en\"]\n  #\n  #    organization:\n  #      name: Example com\n  #      display_name:\n  #        - [\"Example co\", \"en\"]\n  #      display_name:\n  #        - [\"Example co\", \"en\"]\n  #      url: \"http:\u002F\u002Fexample.com\"\n  #\n  #    contact_person:\n  #      - given_name: Bob\n  #        sur_name: \"the Sysadmin\"\n  #        email_address\": [\"admin@example.com\"]\n  #        contact_type\": technical\n\n  # Instead of putting the config inline as above, you can specify a\n  # separate pysaml2 configuration file:\n  #\n  config_path: \"\u002Fdata\u002Fsp_conf.py\"\n  # Or for container envs:\n  config_path: \"\u002Fsynapse\u002Fconfig\u002Fsp_conf.py\"\n\n  # The lifetime of a SAML session. This defines how long a user has to\n  # complete the authentication process, if allow_unsolicited is unset.\n  # The default is 5 minutes.\n  #\n  #saml_session_lifetime: 5m\n\n  # An external module can be provided here as a custom solution to\n  # mapping attributes returned from a saml provider onto a matrix user.\n  #\n  user_mapping_provider:\n    # The custom module's class. Uncomment to use a custom module.\n    #\n    #module: mapping_provider.SamlMappingProvider\n\n    # Custom configuration values for the module. Below options are\n    # intended for the built-in provider, they should be changed if\n    # using a custom module. This section will be passed as a Python\n    # dictionary to the module's `parse_config` method.\n    #\n    config:\n      # The SAML attribute (after mapping via the attribute maps) to use\n      # to derive the Matrix ID from. 'uid' by default.\n      #\n      # Note: This used to be configured by the\n      # saml2_config.mxid_source_attribute option. If that is still\n      # defined, its value will be used instead.\n      #\n      #mxid_source_attribute: displayName\n\n      # The mapping system to use for mapping the saml attribute onto a\n      # matrix ID.\n      #\n      # Options include:\n      #  * 'hexencode' (which maps unpermitted characters to '=xx')\n      #  * 'dotreplace' (which replaces unpermitted characters with\n      #     '.').\n      # The default is 'hexencode'.\n      #\n      # Note: This used to be configured by the\n      # saml2_config.mxid_mapping option. If that is still defined, its\n      # value will be used instead.\n      #\n      #mxid_mapping: dotreplace\n\n  # In previous versions of synapse, the mapping from SAML attribute to\n  # MXID was always calculated dynamically rather than stored in a\n  # table. For backwards- compatibility, we will look for user_ids\n  # matching such a pattern before creating a new account.\n  #\n  # This setting controls the SAML attribute which will be used for this\n  # backwards-compatibility lookup. Typically it should be 'uid', but if\n  # the attribute maps are changed, it may be necessary to change it.\n  #\n  # The default is 'uid'.\n  #\n  #grandfathered_mxid_source_attribute: upn\n\n  # Directory in which Synapse will try to find the template files below.\n  # If not set, default templates from within the Synapse package will be used.\n  #\n  # DO NOT UNCOMMENT THIS SETTING unless you want to customise the templates.\n  # If you *do* uncomment it, you will need to make sure that all the templates\n  # below are in the directory.\n  #\n  # Synapse will look for the following templates in this directory:\n  #\n  # * HTML page to display to users if something goes wrong during the\n  #   authentication process: 'saml_error.html'.\n  #\n  #   This template doesn't currently need any variable to render.\n  #\n  # You can see the default templates at:\n  # https:\u002F\u002Fgithub.com\u002Fmatrix-org\u002Fsynapse\u002Ftree\u002Fmaster\u002Fsynapse\u002Fres\u002Ftemplates\n  #\n  #template_dir: \"res\u002Ftemplates\"\n\npassword_config:\n   # Uncomment to disable password login\n   #\n   enabled: false\n\n   # Uncomment to disable authentication against the local password\n   # database. This is ignored if `enabled` is false, and is only useful\n   # if you have other password_providers.\n   #\n   #localdb_enabled: false\n\n   # Uncomment and change to a secret random string for extra security.\n   # DO NOT CHANGE THIS AFTER INITIAL SETUP!\n   #\n   #pepper: \"EVEN_MORE_SECRET\"\n[...]\n",[567,21336,21337,21345,21350,21354,21359,21364,21368,21373,21377,21386,21390,21394,21401,21406,21411,21416,21421,21426,21431,21435,21442,21447,21452,21459,21464,21471,21483,21487,21492,21497,21502,21507,21512,21517,21522,21526,21531,21536,21541,21545,21550,21555,21559,21564,21569,21574,21579,21583,21587,21592,21596,21601,21606,21611,21616,21621,21625,21630,21635,21639,21653,21658,21670,21674,21679,21684,21689,21693,21698,21702,21707,21712,21716,21723,21728,21733,21738,21742,21747,21752,21757,21762,21766,21773,21778,21783,21788,21793,21798,21803,21807,21812,21816,21821,21826,21830,21835,21840,21845,21850,21855,21859,21863,21868,21873,21877,21882,21886,21891,21896,21901,21906,21910,21916,21922,21928,21933,21939,21944,21950,21955,21961,21967,21972,21978,21984,21990,21995,22001,22006,22012,22018,22023,22029,22034,22040,22046,22051,22057,22062,22070,22076,22082,22092,22097,22103,22109,22115,22120,22126,22131,22137,22143,22148,22154],{"__ignoreMap":743},[747,21338,21339,21341,21343],{"class":749,"line":750},[747,21340,4253],{"class":757},[747,21342,5685],{"class":1895},[747,21344,4268],{"class":757},[747,21346,21347],{"class":749,"line":761},[747,21348,21349],{"class":772},"## Registration ##\n",[747,21351,21352],{"class":749,"line":769},[747,21353,17266],{"class":772},[747,21355,21356],{"class":749,"line":776},[747,21357,21358],{"class":772},"# Registration can be rate-limited using the parameters in the \"Ratelimiting\"\n",[747,21360,21361],{"class":749,"line":784},[747,21362,21363],{"class":772},"# section of this file.\n",[747,21365,21366],{"class":749,"line":790},[747,21367,1255],{"emptyLinePlaceholder":1254},[747,21369,21370],{"class":749,"line":796},[747,21371,21372],{"class":772},"# Enable registration for new users.\n",[747,21374,21375],{"class":749,"line":806},[747,21376,17266],{"class":772},[747,21378,21379,21382,21384],{"class":749,"line":814},[747,21380,21381],{"class":753},"enable_registration",[747,21383,856],{"class":757},[747,21385,1340],{"class":859},[747,21387,21388],{"class":749,"line":822},[747,21389,1255],{"emptyLinePlaceholder":1254},[747,21391,21392],{"class":749,"line":830},[747,21393,1255],{"emptyLinePlaceholder":1254},[747,21395,21396,21399],{"class":749,"line":836},[747,21397,21398],{"class":753},"saml2_config",[747,21400,758],{"class":757},[747,21402,21403],{"class":749,"line":842},[747,21404,21405],{"class":772},"  # `sp_config` is the configuration for the pysaml2 Service Provider.\n",[747,21407,21408],{"class":749,"line":850},[747,21409,21410],{"class":772},"  # See pysaml2 docs for format of config.\n",[747,21412,21413],{"class":749,"line":863},[747,21414,21415],{"class":772},"  #\n",[747,21417,21418],{"class":749,"line":869},[747,21419,21420],{"class":772},"  # Default values will be used for the 'entityid' and 'service' settings,\n",[747,21422,21423],{"class":749,"line":877},[747,21424,21425],{"class":772},"  # so it is not normally necessary to specify them unless you need to\n",[747,21427,21428],{"class":749,"line":1015},[747,21429,21430],{"class":772},"  # override them.\n",[747,21432,21433],{"class":749,"line":1021},[747,21434,21415],{"class":772},[747,21436,21437,21440],{"class":749,"line":1027},[747,21438,21439],{"class":753},"  sp_config",[747,21441,758],{"class":757},[747,21443,21444],{"class":749,"line":1033},[747,21445,21446],{"class":772},"  #  # point this to the IdP's metadata. You can use either a local file or\n",[747,21448,21449],{"class":749,"line":1039},[747,21450,21451],{"class":772},"  #  # (preferably) a URL.\n",[747,21453,21454,21457],{"class":749,"line":1054},[747,21455,21456],{"class":753},"    metadata",[747,21458,758],{"class":757},[747,21460,21461],{"class":749,"line":1060},[747,21462,21463],{"class":772},"  #    #local: [\"saml2\u002Fidp.xml\"]\n",[747,21465,21466,21469],{"class":749,"line":1066},[747,21467,21468],{"class":753},"      remote",[747,21470,758],{"class":757},[747,21472,21473,21475,21478,21480],{"class":749,"line":1081},[747,21474,14801],{"class":757},[747,21476,21477],{"class":753}," url",[747,21479,856],{"class":757},[747,21481,21482],{"class":802}," https:\u002F\u002FYOUR_KEYCLOAK_URL\u002Fauth\u002Frealms\u002FYOUR_REALM\u002Fprotocol\u002Fsaml\u002Fdescriptor\n",[747,21484,21485],{"class":749,"line":1087},[747,21486,21415],{"class":772},[747,21488,21489],{"class":749,"line":1102},[747,21490,21491],{"class":772},"  #    # By default, the user has to go to our login page first. If you'd like\n",[747,21493,21494],{"class":749,"line":1110},[747,21495,21496],{"class":772},"  #    # to allow IdP-initiated login, set 'allow_unsolicited: true' in a\n",[747,21498,21499],{"class":749,"line":1117},[747,21500,21501],{"class":772},"  #    # 'service.sp' section:\n",[747,21503,21504],{"class":749,"line":1123},[747,21505,21506],{"class":772},"  #    #\n",[747,21508,21509],{"class":749,"line":1129},[747,21510,21511],{"class":772},"  #    #service:\n",[747,21513,21514],{"class":749,"line":1142},[747,21515,21516],{"class":772},"  #    #  sp:\n",[747,21518,21519],{"class":749,"line":1150},[747,21520,21521],{"class":772},"  #    #    allow_unsolicited: true\n",[747,21523,21524],{"class":749,"line":1157},[747,21525,21415],{"class":772},[747,21527,21528],{"class":749,"line":1163},[747,21529,21530],{"class":772},"  #    # The examples below are just used to generate our metadata xml, and you\n",[747,21532,21533],{"class":749,"line":1168},[747,21534,21535],{"class":772},"  #    # may well not need them, depending on your setup. Alternatively you\n",[747,21537,21538],{"class":749,"line":1174},[747,21539,21540],{"class":772},"  #    # may need a whole lot more detail - see the pysaml2 docs!\n",[747,21542,21543],{"class":749,"line":1480},[747,21544,21415],{"class":772},[747,21546,21547],{"class":749,"line":1491},[747,21548,21549],{"class":772},"  #    description: [\"My awesome SP\", \"en\"]\n",[747,21551,21552],{"class":749,"line":1496},[747,21553,21554],{"class":772},"  #    name: [\"Test SP\", \"en\"]\n",[747,21556,21557],{"class":749,"line":1502},[747,21558,21415],{"class":772},[747,21560,21561],{"class":749,"line":1510},[747,21562,21563],{"class":772},"  #    organization:\n",[747,21565,21566],{"class":749,"line":1520},[747,21567,21568],{"class":772},"  #      name: Example com\n",[747,21570,21571],{"class":749,"line":1525},[747,21572,21573],{"class":772},"  #      display_name:\n",[747,21575,21576],{"class":749,"line":1533},[747,21577,21578],{"class":772},"  #        - [\"Example co\", \"en\"]\n",[747,21580,21581],{"class":749,"line":1539},[747,21582,21573],{"class":772},[747,21584,21585],{"class":749,"line":1549},[747,21586,21578],{"class":772},[747,21588,21589],{"class":749,"line":1554},[747,21590,21591],{"class":772},"  #      url: \"http:\u002F\u002Fexample.com\"\n",[747,21593,21594],{"class":749,"line":1562},[747,21595,21415],{"class":772},[747,21597,21598],{"class":749,"line":1568},[747,21599,21600],{"class":772},"  #    contact_person:\n",[747,21602,21603],{"class":749,"line":1577},[747,21604,21605],{"class":772},"  #      - given_name: Bob\n",[747,21607,21608],{"class":749,"line":1582},[747,21609,21610],{"class":772},"  #        sur_name: \"the Sysadmin\"\n",[747,21612,21613],{"class":749,"line":1588},[747,21614,21615],{"class":772},"  #        email_address\": [\"admin@example.com\"]\n",[747,21617,21618],{"class":749,"line":1594},[747,21619,21620],{"class":772},"  #        contact_type\": technical\n",[747,21622,21623],{"class":749,"line":1600},[747,21624,1255],{"emptyLinePlaceholder":1254},[747,21626,21627],{"class":749,"line":4804},[747,21628,21629],{"class":772},"  # Instead of putting the config inline as above, you can specify a\n",[747,21631,21632],{"class":749,"line":4810},[747,21633,21634],{"class":772},"  # separate pysaml2 configuration file:\n",[747,21636,21637],{"class":749,"line":4816},[747,21638,21415],{"class":772},[747,21640,21641,21644,21646,21648,21651],{"class":749,"line":4822},[747,21642,21643],{"class":753},"  config_path",[747,21645,856],{"class":757},[747,21647,969],{"class":757},[747,21649,21650],{"class":802},"\u002Fdata\u002Fsp_conf.py",[747,21652,975],{"class":757},[747,21654,21655],{"class":749,"line":4828},[747,21656,21657],{"class":772},"  # Or for container envs:\n",[747,21659,21660,21662,21664,21666,21668],{"class":749,"line":4834},[747,21661,21643],{"class":753},[747,21663,856],{"class":757},[747,21665,969],{"class":757},[747,21667,19157],{"class":802},[747,21669,975],{"class":757},[747,21671,21672],{"class":749,"line":4840},[747,21673,1255],{"emptyLinePlaceholder":1254},[747,21675,21676],{"class":749,"line":4846},[747,21677,21678],{"class":772},"  # The lifetime of a SAML session. This defines how long a user has to\n",[747,21680,21681],{"class":749,"line":4852},[747,21682,21683],{"class":772},"  # complete the authentication process, if allow_unsolicited is unset.\n",[747,21685,21686],{"class":749,"line":4858},[747,21687,21688],{"class":772},"  # The default is 5 minutes.\n",[747,21690,21691],{"class":749,"line":4864},[747,21692,21415],{"class":772},[747,21694,21695],{"class":749,"line":4870},[747,21696,21697],{"class":772},"  #saml_session_lifetime: 5m\n",[747,21699,21700],{"class":749,"line":4876},[747,21701,1255],{"emptyLinePlaceholder":1254},[747,21703,21704],{"class":749,"line":4882},[747,21705,21706],{"class":772},"  # An external module can be provided here as a custom solution to\n",[747,21708,21709],{"class":749,"line":4888},[747,21710,21711],{"class":772},"  # mapping attributes returned from a saml provider onto a matrix user.\n",[747,21713,21714],{"class":749,"line":4894},[747,21715,21415],{"class":772},[747,21717,21718,21721],{"class":749,"line":4900},[747,21719,21720],{"class":753},"  user_mapping_provider",[747,21722,758],{"class":757},[747,21724,21725],{"class":749,"line":4906},[747,21726,21727],{"class":772},"    # The custom module's class. Uncomment to use a custom module.\n",[747,21729,21730],{"class":749,"line":4912},[747,21731,21732],{"class":772},"    #\n",[747,21734,21735],{"class":749,"line":4928},[747,21736,21737],{"class":772},"    #module: mapping_provider.SamlMappingProvider\n",[747,21739,21740],{"class":749,"line":4934},[747,21741,1255],{"emptyLinePlaceholder":1254},[747,21743,21744],{"class":749,"line":4940},[747,21745,21746],{"class":772},"    # Custom configuration values for the module. Below options are\n",[747,21748,21749],{"class":749,"line":4946},[747,21750,21751],{"class":772},"    # intended for the built-in provider, they should be changed if\n",[747,21753,21754],{"class":749,"line":4952},[747,21755,21756],{"class":772},"    # using a custom module. This section will be passed as a Python\n",[747,21758,21759],{"class":749,"line":4958},[747,21760,21761],{"class":772},"    # dictionary to the module's `parse_config` method.\n",[747,21763,21764],{"class":749,"line":4964},[747,21765,21732],{"class":772},[747,21767,21768,21771],{"class":749,"line":4970},[747,21769,21770],{"class":753},"    config",[747,21772,758],{"class":757},[747,21774,21775],{"class":749,"line":4998},[747,21776,21777],{"class":772},"      # The SAML attribute (after mapping via the attribute maps) to use\n",[747,21779,21780],{"class":749,"line":5016},[747,21781,21782],{"class":772},"      # to derive the Matrix ID from. 'uid' by default.\n",[747,21784,21785],{"class":749,"line":5048},[747,21786,21787],{"class":772},"      #\n",[747,21789,21790],{"class":749,"line":5077},[747,21791,21792],{"class":772},"      # Note: This used to be configured by the\n",[747,21794,21795],{"class":749,"line":5098},[747,21796,21797],{"class":772},"      # saml2_config.mxid_source_attribute option. If that is still\n",[747,21799,21800],{"class":749,"line":5121},[747,21801,21802],{"class":772},"      # defined, its value will be used instead.\n",[747,21804,21805],{"class":749,"line":5127},[747,21806,21787],{"class":772},[747,21808,21809],{"class":749,"line":5133},[747,21810,21811],{"class":772},"      #mxid_source_attribute: displayName\n",[747,21813,21814],{"class":749,"line":5139},[747,21815,1255],{"emptyLinePlaceholder":1254},[747,21817,21818],{"class":749,"line":5164},[747,21819,21820],{"class":772},"      # The mapping system to use for mapping the saml attribute onto a\n",[747,21822,21823],{"class":749,"line":5205},[747,21824,21825],{"class":772},"      # matrix ID.\n",[747,21827,21828],{"class":749,"line":5229},[747,21829,21787],{"class":772},[747,21831,21832],{"class":749,"line":5250},[747,21833,21834],{"class":772},"      # Options include:\n",[747,21836,21837],{"class":749,"line":5264},[747,21838,21839],{"class":772},"      #  * 'hexencode' (which maps unpermitted characters to '=xx')\n",[747,21841,21842],{"class":749,"line":5282},[747,21843,21844],{"class":772},"      #  * 'dotreplace' (which replaces unpermitted characters with\n",[747,21846,21847],{"class":749,"line":5311},[747,21848,21849],{"class":772},"      #     '.').\n",[747,21851,21852],{"class":749,"line":5331},[747,21853,21854],{"class":772},"      # The default is 'hexencode'.\n",[747,21856,21857],{"class":749,"line":5351},[747,21858,21787],{"class":772},[747,21860,21861],{"class":749,"line":5374},[747,21862,21792],{"class":772},[747,21864,21865],{"class":749,"line":5394},[747,21866,21867],{"class":772},"      # saml2_config.mxid_mapping option. If that is still defined, its\n",[747,21869,21870],{"class":749,"line":5413},[747,21871,21872],{"class":772},"      # value will be used instead.\n",[747,21874,21875],{"class":749,"line":5430},[747,21876,21787],{"class":772},[747,21878,21879],{"class":749,"line":5447},[747,21880,21881],{"class":772},"      #mxid_mapping: dotreplace\n",[747,21883,21884],{"class":749,"line":5500},[747,21885,1255],{"emptyLinePlaceholder":1254},[747,21887,21888],{"class":749,"line":5517},[747,21889,21890],{"class":772},"  # In previous versions of synapse, the mapping from SAML attribute to\n",[747,21892,21893],{"class":749,"line":5534},[747,21894,21895],{"class":772},"  # MXID was always calculated dynamically rather than stored in a\n",[747,21897,21898],{"class":749,"line":5556},[747,21899,21900],{"class":772},"  # table. For backwards- compatibility, we will look for user_ids\n",[747,21902,21903],{"class":749,"line":5577},[747,21904,21905],{"class":772},"  # matching such a pattern before creating a new account.\n",[747,21907,21908],{"class":749,"line":5606},[747,21909,21415],{"class":772},[747,21911,21913],{"class":749,"line":21912},113,[747,21914,21915],{"class":772},"  # This setting controls the SAML attribute which will be used for this\n",[747,21917,21919],{"class":749,"line":21918},114,[747,21920,21921],{"class":772},"  # backwards-compatibility lookup. Typically it should be 'uid', but if\n",[747,21923,21925],{"class":749,"line":21924},115,[747,21926,21927],{"class":772},"  # the attribute maps are changed, it may be necessary to change it.\n",[747,21929,21931],{"class":749,"line":21930},116,[747,21932,21415],{"class":772},[747,21934,21936],{"class":749,"line":21935},117,[747,21937,21938],{"class":772},"  # The default is 'uid'.\n",[747,21940,21942],{"class":749,"line":21941},118,[747,21943,21415],{"class":772},[747,21945,21947],{"class":749,"line":21946},119,[747,21948,21949],{"class":772},"  #grandfathered_mxid_source_attribute: upn\n",[747,21951,21953],{"class":749,"line":21952},120,[747,21954,1255],{"emptyLinePlaceholder":1254},[747,21956,21958],{"class":749,"line":21957},121,[747,21959,21960],{"class":772},"  # Directory in which Synapse will try to find the template files below.\n",[747,21962,21964],{"class":749,"line":21963},122,[747,21965,21966],{"class":772},"  # If not set, default templates from within the Synapse package will be used.\n",[747,21968,21970],{"class":749,"line":21969},123,[747,21971,21415],{"class":772},[747,21973,21975],{"class":749,"line":21974},124,[747,21976,21977],{"class":772},"  # DO NOT UNCOMMENT THIS SETTING unless you want to customise the templates.\n",[747,21979,21981],{"class":749,"line":21980},125,[747,21982,21983],{"class":772},"  # If you *do* uncomment it, you will need to make sure that all the templates\n",[747,21985,21987],{"class":749,"line":21986},126,[747,21988,21989],{"class":772},"  # below are in the directory.\n",[747,21991,21993],{"class":749,"line":21992},127,[747,21994,21415],{"class":772},[747,21996,21998],{"class":749,"line":21997},128,[747,21999,22000],{"class":772},"  # Synapse will look for the following templates in this directory:\n",[747,22002,22004],{"class":749,"line":22003},129,[747,22005,21415],{"class":772},[747,22007,22009],{"class":749,"line":22008},130,[747,22010,22011],{"class":772},"  # * HTML page to display to users if something goes wrong during the\n",[747,22013,22015],{"class":749,"line":22014},131,[747,22016,22017],{"class":772},"  #   authentication process: 'saml_error.html'.\n",[747,22019,22021],{"class":749,"line":22020},132,[747,22022,21415],{"class":772},[747,22024,22026],{"class":749,"line":22025},133,[747,22027,22028],{"class":772},"  #   This template doesn't currently need any variable to render.\n",[747,22030,22032],{"class":749,"line":22031},134,[747,22033,21415],{"class":772},[747,22035,22037],{"class":749,"line":22036},135,[747,22038,22039],{"class":772},"  # You can see the default templates at:\n",[747,22041,22043],{"class":749,"line":22042},136,[747,22044,22045],{"class":772},"  # https:\u002F\u002Fgithub.com\u002Fmatrix-org\u002Fsynapse\u002Ftree\u002Fmaster\u002Fsynapse\u002Fres\u002Ftemplates\n",[747,22047,22049],{"class":749,"line":22048},137,[747,22050,21415],{"class":772},[747,22052,22054],{"class":749,"line":22053},138,[747,22055,22056],{"class":772},"  #template_dir: \"res\u002Ftemplates\"\n",[747,22058,22060],{"class":749,"line":22059},139,[747,22061,1255],{"emptyLinePlaceholder":1254},[747,22063,22065,22068],{"class":749,"line":22064},140,[747,22066,22067],{"class":753},"password_config",[747,22069,758],{"class":757},[747,22071,22073],{"class":749,"line":22072},141,[747,22074,22075],{"class":772},"   # Uncomment to disable password login\n",[747,22077,22079],{"class":749,"line":22078},142,[747,22080,22081],{"class":772},"   #\n",[747,22083,22085,22088,22090],{"class":749,"line":22084},143,[747,22086,22087],{"class":753},"   enabled",[747,22089,856],{"class":757},[747,22091,1340],{"class":859},[747,22093,22095],{"class":749,"line":22094},144,[747,22096,1255],{"emptyLinePlaceholder":1254},[747,22098,22100],{"class":749,"line":22099},145,[747,22101,22102],{"class":772},"   # Uncomment to disable authentication against the local password\n",[747,22104,22106],{"class":749,"line":22105},146,[747,22107,22108],{"class":772},"   # database. This is ignored if `enabled` is false, and is only useful\n",[747,22110,22112],{"class":749,"line":22111},147,[747,22113,22114],{"class":772},"   # if you have other password_providers.\n",[747,22116,22118],{"class":749,"line":22117},148,[747,22119,22081],{"class":772},[747,22121,22123],{"class":749,"line":22122},149,[747,22124,22125],{"class":772},"   #localdb_enabled: false\n",[747,22127,22129],{"class":749,"line":22128},150,[747,22130,1255],{"emptyLinePlaceholder":1254},[747,22132,22134],{"class":749,"line":22133},151,[747,22135,22136],{"class":772},"   # Uncomment and change to a secret random string for extra security.\n",[747,22138,22140],{"class":749,"line":22139},152,[747,22141,22142],{"class":772},"   # DO NOT CHANGE THIS AFTER INITIAL SETUP!\n",[747,22144,22146],{"class":749,"line":22145},153,[747,22147,22081],{"class":772},[747,22149,22151],{"class":749,"line":22150},154,[747,22152,22153],{"class":772},"   #pepper: \"EVEN_MORE_SECRET\"\n",[747,22155,22157,22159,22161],{"class":749,"line":22156},155,[747,22158,4253],{"class":757},[747,22160,5685],{"class":1895},[747,22162,4268],{"class":757},[6072,22164,22165,22169],{},[523,22166,22167],{},[584,22168,19103],{},[523,22170,22171,22172,714,22175,22178],{},"And again a huge thanks to Helder Ferreira (",[527,22173,19111],{"href":19109,"rel":22174},[531],[527,22176,19116],{"href":19114,"rel":22177},[531],") for updating the configs in this post!",[535,22180,14526],{"id":14525},[523,22182,22183],{},"That should be it, now when you go to your Riot Webapp (and chose your Matrix Homeserver) it should give you a button to login through your (SAML2) SSO.",[523,22185,22186],{},[3069,22187],{"alt":22188,"src":22189},"Riot Webapp SSO Login","\u002Fblog\u002F2019\u002Fmatrix-synapse-saml2-login\u002Friot-webapp-sso-login.png",[523,22191,22192,22193,22195],{},"If it does not work, make sure your Matrix Synapse Homeserver has the required ",[567,22194,19138],{}," module installed and check your Synapse Homeserver logs for errors and\u002F or warnings.",[523,22197,13967],{},[2890,22199,22200],{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}",{"title":743,"searchDepth":761,"depth":761,"links":22202},[22203,22204,22205,22209,22218],{"id":537,"depth":761,"text":538},{"id":19120,"depth":761,"text":19121},{"id":19185,"depth":761,"text":19186,"children":22206},[22207,22208],{"id":19189,"depth":769,"text":19190},{"id":19516,"depth":769,"text":19517},{"id":19559,"depth":761,"text":19560,"children":22210},[22211,22212,22214,22215,22216,22217],{"id":19563,"depth":769,"text":19564},{"id":19584,"depth":769,"text":22213},"\u002Fsynapse\u002Fconfig\u002Fkey.pem and \u002Fsynapse\u002Fconfig\u002Fcert.pem",{"id":19791,"depth":769,"text":19794},{"id":20492,"depth":769,"text":19157},{"id":21150,"depth":769,"text":21153},{"id":21327,"depth":769,"text":21328},{"id":14525,"depth":761,"text":14526},"2019-06-28T11:51:19+02:00","Tutorial on how to use Keycloak with Matrix Synapse Homeserver for authentication of users.",{"src":22222},"\u002Fblog\u002F2019\u002Fmatrix-synapse-saml2-login\u002Fmatrix-synapse-saml2-login.png",{"tags":22224},[22225,22226,22227],"Matrix","Matrix Synapse","SAML2","\u002Fblog\u002F2019\u002Fmatrix-synapse-saml2-login",{"title":19066,"description":22220},"3.blog\u002F2019\u002Fmatrix-synapse-saml2-login","97LzhDF2mVtFuTEYEFxCLHjQXp-wOrCnqFQCCOlQ8kU",{"id":22233,"title":22234,"authors":22235,"badge":518,"body":22238,"date":26407,"description":26408,"extension":2911,"image":26409,"meta":26411,"navigation":1254,"path":26416,"seo":26417,"stem":26418,"__hash__":26419},"posts\u002F3.blog\u002F2019\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature.md","GitLab + Kubernetes: Using GitLab CI's Kubernetes Cluster feature - UPDATED",[22236],{"name":514,"to":515,"avatar":22237},{"src":517},{"type":520,"value":22239,"toc":26385},[22240,22242,22245,22256,22265,22269,22309,22330,22334,22341,22344,22348,22365,22376,22382,22453,22460,22463,22470,22476,22492,22505,22521,22577,22591,23058,23089,23099,23307,23314,23318,23334,23539,23548,23560,23564,23570,23580,23586,23593,23599,23605,23608,23704,23710,23718,23748,23761,23767,23808,23814,23817,23861,23864,23925,23941,23956,24009,24021,24026,25115,25135,25152,25158,25162,25172,25175,25187,25193,25247,25257,25268,25309,25317,25320,25324,25327,25336,25683,25696,25717,25737,25923,25952,25964,26172,26198,26213,26216,26220,26226,26279,26282,26288,26294,26300,26303,26309,26316,26322,26328,26331,26335,26338,26342,26356,26360,26375,26377,26380,26382],[535,22241,538],{"id":537},[523,22243,22244],{},"This post walks through using GitLab CI's Kubernetes Cluster feature to deploy built container images to Kubernetes.",[523,22246,22247,22248,22251,22252,1909],{},"This is an update to my old guide which uses the in GitLab ",[567,22249,22250],{},"10.3"," deprecated Kubernetes integration feature, see: ",[527,22253,22255],{"href":22254},"\u002Fblog\u002F2017\u002FGitLab-Kubernetes-Perfect-Match-for-Continuous-Delivery-with-Container.md","GitLab + Kubernetes: Perfect Match for Continuous Delivery with Container",[6072,22257,22258,22262],{},[523,22259,22260],{},[584,22261,6189],{},[523,22263,22264],{},"Please check the requirements before beginning.",[613,22266,22268],{"id":22267},"requirements","Requirements",[668,22270,22271,22273,22289,22294],{},[638,22272,15241],{},[638,22274,22275,22276],{},"GitLab instance\n",[668,22277,22278,22281],{},[638,22279,22280],{},"GitLab Container Registry enabled.",[638,22282,22283,22284],{},"GitLab CI runner configured and enabled.\n",[668,22285,22286],{},[638,22287,22288],{},"The CI runners must be able to access the Kubernetes apiserver.",[638,22290,22291,22293],{},[567,22292,15269],{}," configured with Kubernetes cluster access.",[638,22295,22296,22297,22300],{},"Kubernetes ",[567,22298,22299],{},"ServiceAccount",[668,22301,22302],{},[638,22303,22304,22305,1909],{},"That has specific permissions, for more information see ",[527,22306,22308],{"href":22307},"#Step-2-Get-ServiceAccount-Token-from-Kubernetes","Step 2 - Get ServiceAccount Token from Kubernetes",[6072,22310,22311,22315],{},[523,22312,22313],{},[584,22314,6189],{},[523,22316,22317,22318,8287,22321,22324,22325,8287,22327,22329],{},"In this post the Kubernetes ",[567,22319,22320],{},"Namespace",[567,22322,22323],{},"presentation-gitlab-k8s"," will be used for \"everything\". If you want to use your own, be sure to replace ",[567,22326,22323],{},[567,22328,22320],{}," in the example fiels and\u002F or snippets in the post.",[535,22331,22333],{"id":22332},"gitlab-ci-kubernetes-cluster-feature","GitLab CI Kubernetes Cluster Feature",[523,22335,22336,22337,22340],{},"The GitLab CI Kubernetes Cluster feature is the successor of the deprecated and beginning with ",[567,22338,22339],{},"10.3d"," disabled Kubernetes project integration.\nThankfully it is \"100%\" backwards compatible.",[523,22342,22343],{},"Though I have to note that I find it a bit \"mehh\" that you can only create\u002Fadd one Kubernetes cluster in the GitLab community edition (CE).",[535,22345,22347],{"id":22346},"step-1-download-and-import-example-repository","Step 1 - Download and \"import\" example Repository",[523,22349,22350,22351,22356,22357,22360,22361,22364],{},"The repository with the files used in this blog post are available on GitHub: ",[527,22352,22355],{"href":22353,"rel":22354},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fpresentation-gitlab-k8s",[531],"galexrt\u002Fpresentation-gitlab-k8s",".\nYou can use the GitLab repository import functionality to import the repository. If you imported the repository into your GitLab, you should already see GitLab CI begin to do it's work, but fail on the ",[567,22358,22359],{},"release_upload"," and at latest on the ",[567,22362,22363],{},"deploy_dev"," task, as you shouldn't have the Kubernetes integration configured and activated before you even read the post yet ;)",[6072,22366,22367,22371],{},[523,22368,22369],{},[584,22370,6189],{},[523,22372,22373,22374,3361],{},"If you have now\u002Falready imported the repository, jump to ",[527,22375,22308],{"href":22307},[523,22377,22378,22379,22381],{},"When creating the repository, keep it empty! Don't add a ",[567,22380,2984],{}," or anything at all to it.\nGo ahead and clone my repository with the files locally. To import the repository the remote needs to be changed. For this we run the following commands:",[738,22383,22385],{"className":1621,"code":22384,"language":1623,"meta":743,"style":743},"$ git clone https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fpresentation-gitlab-k8s.git\n$ cd presentation-gitlab-k8s\n# Change the remote of the repository\n$ git remote set-url origin YOUR_GITLAB_PROJECT_URL\n# Now to push\u002F\"import\" the repository run:\n$ git push -u origin master\n",[567,22386,22387,22399,22409,22414,22432,22437],{"__ignoreMap":743},[747,22388,22389,22391,22394,22396],{"class":749,"line":750},[747,22390,1919],{"class":1630},[747,22392,22393],{"class":802}," git",[747,22395,3506],{"class":802},[747,22397,22398],{"class":802}," https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fpresentation-gitlab-k8s.git\n",[747,22400,22401,22403,22406],{"class":749,"line":761},[747,22402,1919],{"class":1630},[747,22404,22405],{"class":802}," cd",[747,22407,22408],{"class":802}," presentation-gitlab-k8s\n",[747,22410,22411],{"class":749,"line":769},[747,22412,22413],{"class":772},"# Change the remote of the repository\n",[747,22415,22416,22418,22420,22423,22426,22429],{"class":749,"line":776},[747,22417,1919],{"class":1630},[747,22419,22393],{"class":802},[747,22421,22422],{"class":802}," remote",[747,22424,22425],{"class":802}," set-url",[747,22427,22428],{"class":802}," origin",[747,22430,22431],{"class":802}," YOUR_GITLAB_PROJECT_URL\n",[747,22433,22434],{"class":749,"line":784},[747,22435,22436],{"class":772},"# Now to push\u002F\"import\" the repository run:\n",[747,22438,22439,22441,22443,22446,22448,22450],{"class":749,"line":790},[747,22440,1919],{"class":1630},[747,22442,22393],{"class":802},[747,22444,22445],{"class":802}," push",[747,22447,7089],{"class":802},[747,22449,22428],{"class":802},[747,22451,22452],{"class":802}," master\n",[523,22454,22455,22456,1909],{},"In the end it should have been successful and when navigating to the repository in the GitLab, you should see the files in the repository.\nIf you have problems with importing the repository, please see this Stackoverflow post: ",[527,22457,22458],{"href":22458,"rel":22459},"https:\u002F\u002Fstackoverflow.com\u002Fa\u002F20360068\u002F2172930",[531],[523,22461,22462],{},"Now we can begin with the GitLab Kubernetes integration.",[535,22464,22466,22467,22469],{"id":22465},"step-2-get-a-serviceaccount-token-from-kubernetes","Step 2 - Get a ",[567,22468,22299],{}," Token from Kubernetes",[523,22471,22472,22473,22475],{},"Before continuing, make sure that the ",[567,22474,22320],{}," for the example files of the repository exist by running:",[738,22477,22479],{"className":1621,"code":22478,"language":1623,"meta":743,"style":743},"kubectl create ns presentation-gitlab-k8s\n",[567,22480,22481],{"__ignoreMap":743},[747,22482,22483,22485,22487,22490],{"class":749,"line":750},[747,22484,15269],{"class":1630},[747,22486,1925],{"class":802},[747,22488,22489],{"class":802}," ns",[747,22491,22408],{"class":802},[523,22493,22494,22495,22497,22498,22500,22501,22504],{},"For the GitLab Kubernetes integration a ",[567,22496,22299],{}," token is needed.\nThe ",[567,22499,22299],{}," token is used during ",[567,22502,22503],{},"environment"," builds, builds by which an environment should be deployed, by the GitLab CI Runner to connect and authenticate with your Kubernetes cluster and apply the manifests.",[523,22506,22507,22508,22510,22511,22513,22514,22516,22517,22520],{},"The GitLab documentation has an example for creating a ",[567,22509,22299],{}," with the necessary permissions though I would not recommed to use it.\nBecause it is very open permissions-wise, as it uses the ",[567,22512,15233],{}," ClusterRole on a cluster-wide scope. This basically grants the person that has the ",[567,22515,22299],{}," token full access to the Kubernetes cluster, which I personally ",[584,22518,22519],{},"do not"," recommend!",[523,22522,22523,22524,22526,22527,587,22530,22533,22534,22536,22537,8287,22539,22542,22543,8287,22545,10548,22547,22549,22550,22552,22553,22555,22556,587,22558,22560,22561,22563,22564,22567,22568,22571,22572,22542,22574,22576],{},"The following snippet is a ",[567,22525,22299],{}," with a ",[567,22528,22529],{},"Role",[567,22531,22532],{},"RoleBinding",", which means that the ",[567,22535,22299],{}," only gets the permissions of the ",[567,22538,22529],{},[567,22540,22541],{},"gitlab-ci"," in the ",[567,22544,22323],{},[567,22546,15410],{},[567,22548,22532],{}," exists in.\nThis allows for fine grained control to which the ",[567,22551,22299],{}," has access to, so that if you need to deploy to more than one ",[567,22554,22320],{}," you can simply create the ",[567,22557,22529],{},[567,22559,22532],{}," to be in another ",[567,22562,22320],{}," while leaving the ",[567,22565,22566],{},"namespace:"," field in the ",[567,22569,22570],{},"subjets:"," list as is targeting the ",[567,22573,22299],{},[567,22575,22320],{}," the token is used from.",[6072,22578,22579],{},[523,22580,22581,8287,22584],{},[584,22582,22583],{},"FILE",[527,22585,22588],{"href":22586,"rel":22587},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fpresentation-gitlab-k8s\u002Fblob\u002Fmaster\u002Fgitlab-ci\u002Frbac.yaml",[531],[567,22589,22590],{},"gitlab-ci\u002Frbac.yaml",[738,22592,22594],{"className":740,"code":22593,"language":742,"meta":743,"style":743},"---\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: gitlab-ci\n  namespace: presentation-gitlab-k8s\n---\nkind: Role\napiVersion: rbac.authorization.k8s.io\u002Fv1\nmetadata:\n  namespace: presentation-gitlab-k8s\n  name: gitlab-ci\nrules:\n- apiGroups: [\"\"]\n  resources: [\"*\"]\n  verbs: [\"*\"]\n- apiGroups: [\"apps\"]\n  resources: [\"*\"]\n  verbs: [\"*\"]\n- apiGroups: [\"batch\"]\n  resources: [\"*\"]\n  verbs: [\"*\"]\n- apiGroups: [\"extensions\"]\n  resources: [\"*\"]\n  verbs: [\"*\"]\n- apiGroups: [\"autoscaling\"]\n  resources: [\"*\"]\n  verbs: [\"*\"]\n---\nkind: RoleBinding\napiVersion: rbac.authorization.k8s.io\u002Fv1\nmetadata:\n  name: gitlab-ci\n  namespace: presentation-gitlab-k8s\nsubjects:\n- kind: ServiceAccount\n  name: gitlab-ci\n  namespace: presentation-gitlab-k8s\nroleRef:\n  kind: Role\n  name: gitlab-ci\n  apiGroup: rbac.authorization.k8s.io\n",[567,22595,22596,22600,22609,22618,22624,22633,22641,22645,22654,22663,22669,22677,22685,22692,22708,22726,22743,22762,22778,22794,22813,22829,22845,22864,22880,22896,22915,22931,22947,22951,22960,22968,22974,22982,22990,22997,23008,23016,23024,23031,23040,23048],{"__ignoreMap":743},[747,22597,22598],{"class":749,"line":750},[747,22599,12808],{"class":1630},[747,22601,22602,22604,22606],{"class":749,"line":761},[747,22603,12949],{"class":753},[747,22605,856],{"class":757},[747,22607,22608],{"class":802}," v1\n",[747,22610,22611,22613,22615],{"class":749,"line":769},[747,22612,12963],{"class":753},[747,22614,856],{"class":757},[747,22616,22617],{"class":802}," ServiceAccount\n",[747,22619,22620,22622],{"class":749,"line":776},[747,22621,12973],{"class":753},[747,22623,758],{"class":757},[747,22625,22626,22628,22630],{"class":749,"line":784},[747,22627,12980],{"class":753},[747,22629,856],{"class":757},[747,22631,22632],{"class":802}," gitlab-ci\n",[747,22634,22635,22637,22639],{"class":749,"line":790},[747,22636,13231],{"class":753},[747,22638,856],{"class":757},[747,22640,22408],{"class":802},[747,22642,22643],{"class":749,"line":796},[747,22644,12808],{"class":1630},[747,22646,22647,22649,22651],{"class":749,"line":806},[747,22648,12963],{"class":753},[747,22650,856],{"class":757},[747,22652,22653],{"class":802}," Role\n",[747,22655,22656,22658,22660],{"class":749,"line":814},[747,22657,12949],{"class":753},[747,22659,856],{"class":757},[747,22661,22662],{"class":802}," rbac.authorization.k8s.io\u002Fv1\n",[747,22664,22665,22667],{"class":749,"line":822},[747,22666,12973],{"class":753},[747,22668,758],{"class":757},[747,22670,22671,22673,22675],{"class":749,"line":830},[747,22672,13231],{"class":753},[747,22674,856],{"class":757},[747,22676,22408],{"class":802},[747,22678,22679,22681,22683],{"class":749,"line":836},[747,22680,12980],{"class":753},[747,22682,856],{"class":757},[747,22684,22632],{"class":802},[747,22686,22687,22690],{"class":749,"line":842},[747,22688,22689],{"class":753},"rules",[747,22691,758],{"class":757},[747,22693,22694,22696,22699,22701,22703,22706],{"class":749,"line":850},[747,22695,3361],{"class":757},[747,22697,22698],{"class":753}," apiGroups",[747,22700,856],{"class":757},[747,22702,4262],{"class":757},[747,22704,22705],{"class":757},"\"\"",[747,22707,4268],{"class":757},[747,22709,22710,22713,22715,22717,22719,22722,22724],{"class":749,"line":863},[747,22711,22712],{"class":753},"  resources",[747,22714,856],{"class":757},[747,22716,4262],{"class":757},[747,22718,3892],{"class":757},[747,22720,22721],{"class":802},"*",[747,22723,3892],{"class":757},[747,22725,4268],{"class":757},[747,22727,22728,22731,22733,22735,22737,22739,22741],{"class":749,"line":869},[747,22729,22730],{"class":753},"  verbs",[747,22732,856],{"class":757},[747,22734,4262],{"class":757},[747,22736,3892],{"class":757},[747,22738,22721],{"class":802},[747,22740,3892],{"class":757},[747,22742,4268],{"class":757},[747,22744,22745,22747,22749,22751,22753,22755,22758,22760],{"class":749,"line":877},[747,22746,3361],{"class":757},[747,22748,22698],{"class":753},[747,22750,856],{"class":757},[747,22752,4262],{"class":757},[747,22754,3892],{"class":757},[747,22756,22757],{"class":802},"apps",[747,22759,3892],{"class":757},[747,22761,4268],{"class":757},[747,22763,22764,22766,22768,22770,22772,22774,22776],{"class":749,"line":1015},[747,22765,22712],{"class":753},[747,22767,856],{"class":757},[747,22769,4262],{"class":757},[747,22771,3892],{"class":757},[747,22773,22721],{"class":802},[747,22775,3892],{"class":757},[747,22777,4268],{"class":757},[747,22779,22780,22782,22784,22786,22788,22790,22792],{"class":749,"line":1021},[747,22781,22730],{"class":753},[747,22783,856],{"class":757},[747,22785,4262],{"class":757},[747,22787,3892],{"class":757},[747,22789,22721],{"class":802},[747,22791,3892],{"class":757},[747,22793,4268],{"class":757},[747,22795,22796,22798,22800,22802,22804,22806,22809,22811],{"class":749,"line":1027},[747,22797,3361],{"class":757},[747,22799,22698],{"class":753},[747,22801,856],{"class":757},[747,22803,4262],{"class":757},[747,22805,3892],{"class":757},[747,22807,22808],{"class":802},"batch",[747,22810,3892],{"class":757},[747,22812,4268],{"class":757},[747,22814,22815,22817,22819,22821,22823,22825,22827],{"class":749,"line":1033},[747,22816,22712],{"class":753},[747,22818,856],{"class":757},[747,22820,4262],{"class":757},[747,22822,3892],{"class":757},[747,22824,22721],{"class":802},[747,22826,3892],{"class":757},[747,22828,4268],{"class":757},[747,22830,22831,22833,22835,22837,22839,22841,22843],{"class":749,"line":1039},[747,22832,22730],{"class":753},[747,22834,856],{"class":757},[747,22836,4262],{"class":757},[747,22838,3892],{"class":757},[747,22840,22721],{"class":802},[747,22842,3892],{"class":757},[747,22844,4268],{"class":757},[747,22846,22847,22849,22851,22853,22855,22857,22860,22862],{"class":749,"line":1054},[747,22848,3361],{"class":757},[747,22850,22698],{"class":753},[747,22852,856],{"class":757},[747,22854,4262],{"class":757},[747,22856,3892],{"class":757},[747,22858,22859],{"class":802},"extensions",[747,22861,3892],{"class":757},[747,22863,4268],{"class":757},[747,22865,22866,22868,22870,22872,22874,22876,22878],{"class":749,"line":1060},[747,22867,22712],{"class":753},[747,22869,856],{"class":757},[747,22871,4262],{"class":757},[747,22873,3892],{"class":757},[747,22875,22721],{"class":802},[747,22877,3892],{"class":757},[747,22879,4268],{"class":757},[747,22881,22882,22884,22886,22888,22890,22892,22894],{"class":749,"line":1066},[747,22883,22730],{"class":753},[747,22885,856],{"class":757},[747,22887,4262],{"class":757},[747,22889,3892],{"class":757},[747,22891,22721],{"class":802},[747,22893,3892],{"class":757},[747,22895,4268],{"class":757},[747,22897,22898,22900,22902,22904,22906,22908,22911,22913],{"class":749,"line":1081},[747,22899,3361],{"class":757},[747,22901,22698],{"class":753},[747,22903,856],{"class":757},[747,22905,4262],{"class":757},[747,22907,3892],{"class":757},[747,22909,22910],{"class":802},"autoscaling",[747,22912,3892],{"class":757},[747,22914,4268],{"class":757},[747,22916,22917,22919,22921,22923,22925,22927,22929],{"class":749,"line":1087},[747,22918,22712],{"class":753},[747,22920,856],{"class":757},[747,22922,4262],{"class":757},[747,22924,3892],{"class":757},[747,22926,22721],{"class":802},[747,22928,3892],{"class":757},[747,22930,4268],{"class":757},[747,22932,22933,22935,22937,22939,22941,22943,22945],{"class":749,"line":1102},[747,22934,22730],{"class":753},[747,22936,856],{"class":757},[747,22938,4262],{"class":757},[747,22940,3892],{"class":757},[747,22942,22721],{"class":802},[747,22944,3892],{"class":757},[747,22946,4268],{"class":757},[747,22948,22949],{"class":749,"line":1110},[747,22950,12808],{"class":1630},[747,22952,22953,22955,22957],{"class":749,"line":1117},[747,22954,12963],{"class":753},[747,22956,856],{"class":757},[747,22958,22959],{"class":802}," RoleBinding\n",[747,22961,22962,22964,22966],{"class":749,"line":1123},[747,22963,12949],{"class":753},[747,22965,856],{"class":757},[747,22967,22662],{"class":802},[747,22969,22970,22972],{"class":749,"line":1129},[747,22971,12973],{"class":753},[747,22973,758],{"class":757},[747,22975,22976,22978,22980],{"class":749,"line":1142},[747,22977,12980],{"class":753},[747,22979,856],{"class":757},[747,22981,22632],{"class":802},[747,22983,22984,22986,22988],{"class":749,"line":1150},[747,22985,13231],{"class":753},[747,22987,856],{"class":757},[747,22989,22408],{"class":802},[747,22991,22992,22995],{"class":749,"line":1157},[747,22993,22994],{"class":753},"subjects",[747,22996,758],{"class":757},[747,22998,22999,23001,23004,23006],{"class":749,"line":1163},[747,23000,3361],{"class":757},[747,23002,23003],{"class":753}," kind",[747,23005,856],{"class":757},[747,23007,22617],{"class":802},[747,23009,23010,23012,23014],{"class":749,"line":1168},[747,23011,12980],{"class":753},[747,23013,856],{"class":757},[747,23015,22632],{"class":802},[747,23017,23018,23020,23022],{"class":749,"line":1174},[747,23019,13231],{"class":753},[747,23021,856],{"class":757},[747,23023,22408],{"class":802},[747,23025,23026,23029],{"class":749,"line":1480},[747,23027,23028],{"class":753},"roleRef",[747,23030,758],{"class":757},[747,23032,23033,23036,23038],{"class":749,"line":1491},[747,23034,23035],{"class":753},"  kind",[747,23037,856],{"class":757},[747,23039,22653],{"class":802},[747,23041,23042,23044,23046],{"class":749,"line":1496},[747,23043,12980],{"class":753},[747,23045,856],{"class":757},[747,23047,22632],{"class":802},[747,23049,23050,23053,23055],{"class":749,"line":1502},[747,23051,23052],{"class":753},"  apiGroup",[747,23054,856],{"class":757},[747,23056,23057],{"class":802}," rbac.authorization.k8s.io\n",[6072,23059,23060,23064,23074],{},[523,23061,23062],{},[584,23063,6189],{},[523,23065,23066,23067,23073],{},"It is highly recommended to ",[584,23068,23069,23070,23072],{},"have a separate ",[567,23071,22299],{}," for each application"," accessing the Kubernetes API!\nAnother project should always get its own token, so in the access logs it can be better seen which token has been (mis-)used.",[523,23075,23076,23077,18054,23080,23083,23084,1909],{},"Should you experience issues creating the ",[567,23078,23079],{},"ClusterRole(Binding)",[567,23081,23082],{},"Role(Binding)"," object, and you are on GKE or other Kubernetes as a Service platforms, please take a look at this GitHub issue: ",[527,23085,23088],{"href":23086,"rel":23087},"https:\u002F\u002Fgithub.com\u002Fcoreos\u002Fprometheus-operator\u002Fissues\u002F357#issue-227263978",[531],"GitHub coreos\u002Fprometheus-operator RBAC on GKE - extra step needed #357",[523,23090,23091,23092,23094,23095,23098],{},"In my case even if it not the best way, I'll go with the default ",[567,23093,22299],{}," created in the namespace where I will run the application.\nFor that I check what ",[567,23096,23097],{},"Secrets"," exist, then get the secret and base64 decode it.",[738,23100,23102],{"className":1621,"code":23101,"language":1623,"meta":743,"style":743},"$ kubectl get -n presentation-gitlab-k8s secret\nNAME                    TYPE                                  DATA   AGE\ndefault-token-2kmsr     kubernetes.io\u002Fservice-account-token   3      3m11s\ngitlab-ci-token-jlc58   kubernetes.io\u002Fservice-account-token   3      118s\n# In this case the ServiceAccount token Secret is named `gitlab-ci-token-jlc58`,\n# the name of the Secret will differ between clusters (it will always start with `gitlab-ci-token-`)\n$ kubectl get -n presentation-gitlab-k8s secret gitlab-ci-token-jlc58 -o yaml\napiVersion: v1\ndata:\n  ca.crt: [REDACATED]\n  namespace: [REDACATED]\n  token: [BASE64_ENCODED_TOKEN_HERE]\nkind: Secret\nmetadata:\n[...]\n  name: gitlab-ci-token-jlc58\n  namespace: presentation-gitlab-k8s\n[...]\ntype: kubernetes.io\u002Fservice-account-token\n$ echo BASE64_ENCODED_TOKEN_HERE | base64 -d\nYOUR_DECODED_TOKEN\n# Long cryptic looking output, copy it.\n",[567,23103,23104,23120,23132,23145,23158,23163,23168,23191,23198,23203,23211,23218,23226,23234,23239,23247,23255,23261,23269,23279,23297,23302],{"__ignoreMap":743},[747,23105,23106,23108,23110,23112,23114,23117],{"class":749,"line":750},[747,23107,1919],{"class":1630},[747,23109,1922],{"class":802},[747,23111,1951],{"class":802},[747,23113,1928],{"class":802},[747,23115,23116],{"class":802}," presentation-gitlab-k8s",[747,23118,23119],{"class":802}," secret\n",[747,23121,23122,23124,23127,23130],{"class":749,"line":761},[747,23123,2230],{"class":1630},[747,23125,23126],{"class":802},"                    TYPE",[747,23128,23129],{"class":802},"                                  DATA",[747,23131,15553],{"class":802},[747,23133,23134,23137,23140,23142],{"class":749,"line":769},[747,23135,23136],{"class":1630},"default-token-2kmsr",[747,23138,23139],{"class":802},"     kubernetes.io\u002Fservice-account-token",[747,23141,16450],{"class":1895},[747,23143,23144],{"class":802},"      3m11s\n",[747,23146,23147,23150,23153,23155],{"class":749,"line":776},[747,23148,23149],{"class":1630},"gitlab-ci-token-jlc58",[747,23151,23152],{"class":802},"   kubernetes.io\u002Fservice-account-token",[747,23154,16450],{"class":1895},[747,23156,23157],{"class":802},"      118s\n",[747,23159,23160],{"class":749,"line":784},[747,23161,23162],{"class":772},"# In this case the ServiceAccount token Secret is named `gitlab-ci-token-jlc58`,\n",[747,23164,23165],{"class":749,"line":790},[747,23166,23167],{"class":772},"# the name of the Secret will differ between clusters (it will always start with `gitlab-ci-token-`)\n",[747,23169,23170,23172,23174,23176,23178,23180,23183,23186,23188],{"class":749,"line":796},[747,23171,1919],{"class":1630},[747,23173,1922],{"class":802},[747,23175,1951],{"class":802},[747,23177,1928],{"class":802},[747,23179,23116],{"class":802},[747,23181,23182],{"class":802}," secret",[747,23184,23185],{"class":802}," gitlab-ci-token-jlc58",[747,23187,2222],{"class":802},[747,23189,23190],{"class":802}," yaml\n",[747,23192,23193,23196],{"class":749,"line":806},[747,23194,23195],{"class":1630},"apiVersion:",[747,23197,22608],{"class":802},[747,23199,23200],{"class":749,"line":814},[747,23201,23202],{"class":1630},"data:\n",[747,23204,23205,23208],{"class":749,"line":822},[747,23206,23207],{"class":1630},"  ca.crt:",[747,23209,23210],{"class":1640}," [REDACATED]\n",[747,23212,23213,23216],{"class":749,"line":830},[747,23214,23215],{"class":1630},"  namespace:",[747,23217,23210],{"class":1640},[747,23219,23220,23223],{"class":749,"line":836},[747,23221,23222],{"class":1630},"  token:",[747,23224,23225],{"class":1640}," [BASE64_ENCODED_TOKEN_HERE]\n",[747,23227,23228,23231],{"class":749,"line":842},[747,23229,23230],{"class":1630},"kind:",[747,23232,23233],{"class":802}," Secret\n",[747,23235,23236],{"class":749,"line":850},[747,23237,23238],{"class":1630},"metadata:\n",[747,23240,23241,23243,23245],{"class":749,"line":863},[747,23242,4253],{"class":757},[747,23244,5685],{"class":1640},[747,23246,4268],{"class":757},[747,23248,23249,23252],{"class":749,"line":869},[747,23250,23251],{"class":1630},"  name:",[747,23253,23254],{"class":802}," gitlab-ci-token-jlc58\n",[747,23256,23257,23259],{"class":749,"line":877},[747,23258,23215],{"class":1630},[747,23260,22408],{"class":802},[747,23262,23263,23265,23267],{"class":749,"line":1015},[747,23264,4253],{"class":757},[747,23266,5685],{"class":1640},[747,23268,4268],{"class":757},[747,23270,23271,23274,23276],{"class":749,"line":1021},[747,23272,23273],{"class":4574},"type",[747,23275,856],{"class":802},[747,23277,23278],{"class":802}," kubernetes.io\u002Fservice-account-token\n",[747,23280,23281,23283,23286,23289,23291,23294],{"class":749,"line":1027},[747,23282,1919],{"class":1630},[747,23284,23285],{"class":802}," echo",[747,23287,23288],{"class":802}," BASE64_ENCODED_TOKEN_HERE",[747,23290,3170],{"class":757},[747,23292,23293],{"class":1630}," base64",[747,23295,23296],{"class":802}," -d\n",[747,23298,23299],{"class":749,"line":1033},[747,23300,23301],{"class":1630},"YOUR_DECODED_TOKEN\n",[747,23303,23304],{"class":749,"line":1039},[747,23305,23306],{"class":772},"# Long cryptic looking output, copy it.\n",[523,23308,23309,23310,23313],{},"Copy ",[567,23311,23312],{},"YOUR_DECODED_TOKEN"," somewhere safe for an upcoming step.",[535,23315,23317],{"id":23316},"step-3-get-the-kubernetes-ca-certificate","Step 3 - Get the Kubernetes CA Certificate",[523,23319,23320,23321,12566,23326,23329,23330,23333],{},"As you may have seen in ",[527,23322,22466,23324,22469],{"href":23323},"#step-2-get-a-serviceaccount-token-from-kubernetes",[567,23325,22299],{},[567,23327,23328],{},"kubectl get secrets"," command output, there was a key named ",[567,23331,23332],{},"ca.crt"," in it.",[738,23335,23337],{"className":1621,"code":23336,"language":1623,"meta":743,"style":743},"$ kubectl get -n presentation-gitlab-k8s secret\nNAME                    TYPE                                  DATA   AGE\ndefault-token-2kmsr     kubernetes.io\u002Fservice-account-token   3      3m11s\ngitlab-ci-token-jlc58   kubernetes.io\u002Fservice-account-token   3      118s\n# In this case the ServiceAccount token Secret is named `gitlab-ci-token-jlc58`,\n# the name of the Secret will differ between clusters (it will always start with `gitlab-ci-token-`)\n$ kubectl get -n presentation-gitlab-k8s secret gitlab-ci-token-jlc58 -o yaml\napiVersion: v1\ndata:\n  ca.crt: [BASE64_ENCODED_CA_CERT_HERE]\n  namespace: [REDACATED]\n  token: [REDACATED]\nkind: Secret\nmetadata:\n[...]\n  name: gitlab-ci-token-jlc58\n  namespace: presentation-gitlab-k8s\n[...]\ntype: kubernetes.io\u002Fservice-account-token\n$ echo BASE64_ENCODED_CA_CERT_HERE | base64 -d\nYOUR_BASE64_DECODED_CA_CERT_HERE\n\n# Looks something like this:\n-----BEGIN CERTIFICATE-----\n[REDACATED]\n-----END CERTIFICATE-----\n",[567,23338,23339,23353,23363,23373,23383,23387,23391,23411,23417,23421,23428,23434,23440,23446,23450,23458,23464,23470,23478,23486,23501,23506,23510,23515,23523,23532],{"__ignoreMap":743},[747,23340,23341,23343,23345,23347,23349,23351],{"class":749,"line":750},[747,23342,1919],{"class":1630},[747,23344,1922],{"class":802},[747,23346,1951],{"class":802},[747,23348,1928],{"class":802},[747,23350,23116],{"class":802},[747,23352,23119],{"class":802},[747,23354,23355,23357,23359,23361],{"class":749,"line":761},[747,23356,2230],{"class":1630},[747,23358,23126],{"class":802},[747,23360,23129],{"class":802},[747,23362,15553],{"class":802},[747,23364,23365,23367,23369,23371],{"class":749,"line":769},[747,23366,23136],{"class":1630},[747,23368,23139],{"class":802},[747,23370,16450],{"class":1895},[747,23372,23144],{"class":802},[747,23374,23375,23377,23379,23381],{"class":749,"line":776},[747,23376,23149],{"class":1630},[747,23378,23152],{"class":802},[747,23380,16450],{"class":1895},[747,23382,23157],{"class":802},[747,23384,23385],{"class":749,"line":784},[747,23386,23162],{"class":772},[747,23388,23389],{"class":749,"line":790},[747,23390,23167],{"class":772},[747,23392,23393,23395,23397,23399,23401,23403,23405,23407,23409],{"class":749,"line":796},[747,23394,1919],{"class":1630},[747,23396,1922],{"class":802},[747,23398,1951],{"class":802},[747,23400,1928],{"class":802},[747,23402,23116],{"class":802},[747,23404,23182],{"class":802},[747,23406,23185],{"class":802},[747,23408,2222],{"class":802},[747,23410,23190],{"class":802},[747,23412,23413,23415],{"class":749,"line":806},[747,23414,23195],{"class":1630},[747,23416,22608],{"class":802},[747,23418,23419],{"class":749,"line":814},[747,23420,23202],{"class":1630},[747,23422,23423,23425],{"class":749,"line":822},[747,23424,23207],{"class":1630},[747,23426,23427],{"class":1640}," [BASE64_ENCODED_CA_CERT_HERE]\n",[747,23429,23430,23432],{"class":749,"line":830},[747,23431,23215],{"class":1630},[747,23433,23210],{"class":1640},[747,23435,23436,23438],{"class":749,"line":836},[747,23437,23222],{"class":1630},[747,23439,23210],{"class":1640},[747,23441,23442,23444],{"class":749,"line":842},[747,23443,23230],{"class":1630},[747,23445,23233],{"class":802},[747,23447,23448],{"class":749,"line":850},[747,23449,23238],{"class":1630},[747,23451,23452,23454,23456],{"class":749,"line":863},[747,23453,4253],{"class":757},[747,23455,5685],{"class":1640},[747,23457,4268],{"class":757},[747,23459,23460,23462],{"class":749,"line":869},[747,23461,23251],{"class":1630},[747,23463,23254],{"class":802},[747,23465,23466,23468],{"class":749,"line":877},[747,23467,23215],{"class":1630},[747,23469,22408],{"class":802},[747,23471,23472,23474,23476],{"class":749,"line":1015},[747,23473,4253],{"class":757},[747,23475,5685],{"class":1640},[747,23477,4268],{"class":757},[747,23479,23480,23482,23484],{"class":749,"line":1021},[747,23481,23273],{"class":4574},[747,23483,856],{"class":802},[747,23485,23278],{"class":802},[747,23487,23488,23490,23492,23495,23497,23499],{"class":749,"line":1027},[747,23489,1919],{"class":1630},[747,23491,23285],{"class":802},[747,23493,23494],{"class":802}," BASE64_ENCODED_CA_CERT_HERE",[747,23496,3170],{"class":757},[747,23498,23293],{"class":1630},[747,23500,23296],{"class":802},[747,23502,23503],{"class":749,"line":1033},[747,23504,23505],{"class":1630},"YOUR_BASE64_DECODED_CA_CERT_HERE\n",[747,23507,23508],{"class":749,"line":1039},[747,23509,1255],{"emptyLinePlaceholder":1254},[747,23511,23512],{"class":749,"line":1054},[747,23513,23514],{"class":772},"# Looks something like this:\n",[747,23516,23517,23520],{"class":749,"line":1060},[747,23518,23519],{"class":1630},"-----BEGIN",[747,23521,23522],{"class":802}," CERTIFICATE-----\n",[747,23524,23525,23527,23530],{"class":749,"line":1066},[747,23526,4253],{"class":757},[747,23528,23529],{"class":1640},"REDACATED",[747,23531,4268],{"class":757},[747,23533,23534,23537],{"class":749,"line":1081},[747,23535,23536],{"class":1630},"-----END",[747,23538,23522],{"class":802},[6072,23540,23541,23545],{},[523,23542,23543],{},[584,23544,6189],{},[523,23546,23547],{},"If you have not been able to get the Kubernetes CA certificate through this method, there might be something wrong with your Kuberleltes cluster. Be sure to contact your Kubernetes cluster administrator\u002F support team.",[523,23549,23550,23551,23554,23555,1909],{},"Save the CA certificate (",[567,23552,23553],{},"YOUR_BASE64_DECODED_CA_CERT_HERE",") somewhere safe with the token from ",[527,23556,23557,23558,22469],{"href":23323},"Step 2 - Get ",[567,23559,22299],{},[535,23561,23563],{"id":23562},"step-4-create-a-kubernetes-cluster-in-gitlab-ci","Step 4 - Create a Kubernetes cluster in GitLab CI",[523,23565,23566,23567,23569],{},"You will now need the ",[567,23568,22299],{}," token, the CA certificate, Kubernetes API server address and the namespace you want to run the application in.",[523,23571,23572,23573,23576,23577,23579],{},"In your GitLab's sidebar, go to ",[567,23574,23575],{},"Operations"," -> ",[567,23578,124],{}," and you should get to this page:",[523,23581,23582],{},[3069,23583],{"alt":23584,"src":23585},"GitLab CI Kubernetes cluster - Cluster list page","\u002Fblog\u002F2019\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature\u002Fgitlab-ci-kubernetes-cluster-empty-cluster-list.png",[523,23587,23588,23589,23592],{},"Now click the ",[567,23590,23591],{},"Add Kubernetes cluster"," button and you come to this page with two tabs.\nOn this page you can decide, if you want to create a new Google GKE cluster or add an existing cluster.",[523,23594,19600,23595,23598],{},[567,23596,23597],{},"Add existing cluster"," tab, in which we can input the Kubernetes cluster information we just gathered the information in the last few steps:_",[523,23600,23601],{},[3069,23602],{"alt":23603,"src":23604},"GitLab CI Kubernetes cluster - Add existing cluster form","\u002Fblog\u002F2019\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature\u002Fgitlab-ci-kubernetes-cluster-add-form.png",[523,23606,23607],{},"Fill in the fields as follows:",[668,23609,23610,23616,23640,23649,23661,23688,23694],{},[638,23611,23612,23615],{},[567,23613,23614],{},"Kubernetes cluster name"," - can be \"anything\", pick something you are able to identify the cluster later on again in case of issues. The other fields should be filled with the information we gathered it in the previous steps.",[638,23617,23618,23621,23622,23626,23627,23630,23631],{},[567,23619,23620],{},"API URL"," - the address of the Kubernetes API server, this depends on where your GitLab CI runners are running. If they are running inside the Kubernetes cluster (e.g., followed the ",[527,23623,23625],{"href":23624},"\u002Fblog\u002F2017\u002FGitLab-Kubernetes-Running-CI-Runners-in-Kubernetes.md","tutorial on my blog","), you should put ",[567,23628,23629],{},"https:\u002F\u002Fkubernetes.default.svc.cluster.local:443"," there. When the runners are external to the clusters put the load balanced Kubernetes API Server address here.\n",[668,23632,23633],{},[638,23634,23635,23636,23639],{},"Keep in mind that the ",[567,23637,23638],{},"cluster.local"," is Kubernetes default cluster domain name, be sure to set it according to your Kubernetes.",[638,23641,23642,23645,23646,1909],{},[567,23643,23644],{},"CA Certificate"," - CA certificate of your Kubernetes cluster from ",[527,23647,23317],{"href":23648},"#step-3-get-the-kubernetes-ca-certificate",[638,23650,23651,11292,23654,23656,23657,1909],{},[567,23652,23653],{},"Service Token",[567,23655,22299],{}," token we extracted in ",[527,23658,23557,23659,22469],{"href":23323},[567,23660,22299],{},[638,23662,23663,23666,23667,23669,23670],{},[567,23664,23665],{},"Project namespace (optional, unique)"," - Optional. I highly recommend setting the ",[567,23668,22320],{}," to be used in Kubernetes here.\n",[668,23671,23672],{},[638,23673,23674,23675,8287,23677,23679,23680,23682,23683,23685,23686,1909],{},"In case of the example files\u002F repository, the ",[567,23676,22320],{},[567,23678,22323],{}," is used. If you wanna use your own ",[567,23681,22320],{}," here, please be sure that you have created everything till now in your ",[567,23684,22320],{}," and are going to edit\u002F set\u002F modify all the manifests with your ",[567,23687,22320],{},[638,23689,23690,23693],{},[567,23691,23692],{},"RBAC-enabled cluster"," - Should be ticked as hopefully only Kubernetes clusters with RBAC enabled exists anymore.",[638,23695,23696,23699,23700,1909],{},[567,23697,23698],{},"GitLab-managed cluster"," - Untick as you the project owner should take care of creating Namespaces for your projects. Due to the lowered permissions scoped to Namespaces and not the whole cluster, see ",[527,23701,22466,23702,22469],{"href":23323},[567,23703,22299],{},[523,23705,23706,23707,23709],{},"Click ",[567,23708,23591],{}," to add the cluster to GitLab and you now have the Kubernetes cluster feature\u002F integration activated and ready.",[535,23711,23713,23714,23717],{"id":23712},"step-5-add-a-gitlab-ciyml-to-your-project","Step 5 - Add a ",[567,23715,23716],{},".gitlab-ci.yml"," to your project",[6072,23719,23720,23724],{},[523,23721,23722],{},[584,23723,6189],{},[523,23725,23726,23727,23730,23731,23734,23735,23740,23741,23743,23744,23747],{},"Replace ",[567,23728,23729],{},"registry.example.com"," is the address to your GitLab container registry.\n",[567,23732,23733],{},"s3.example.com"," is just a ",[527,23736,23739],{"href":23737,"rel":23738},"https:\u002F\u002Fminio.io\u002F",[531],"minio"," instance where I upload the artifact to an \"external\" destination for demonstration. To remove this step just delete the ",[567,23742,22359],{}," structure.\nReplace ",[567,23745,23746],{},"{gitlab,s3,registry}.example.com"," with your corresponding domain name!",[6072,23749,23750,23754],{},[523,23751,23752],{},[584,23753,15250],{},[523,23755,23756,23757,23760],{},"You should first commit when you are done with adding all the manifests from all the other ",[584,23758,23759],{},"sixth step"," to come too!",[523,23762,23763,23764,23766],{},"A job in the ",[567,23765,23716],{}," file looks like this:",[738,23768,23770],{"className":740,"code":23769,"language":742,"meta":743,"style":743},"# run the golang application tests\ntest:\n    stage: test\n    script:\n        - go test .\u002F...\n",[567,23771,23772,23777,23784,23794,23801],{"__ignoreMap":743},[747,23773,23774],{"class":749,"line":750},[747,23775,23776],{"class":772},"# run the golang application tests\n",[747,23778,23779,23782],{"class":749,"line":761},[747,23780,23781],{"class":753},"test",[747,23783,758],{"class":757},[747,23785,23786,23789,23791],{"class":749,"line":769},[747,23787,23788],{"class":753},"    stage",[747,23790,856],{"class":757},[747,23792,23793],{"class":802}," test\n",[747,23795,23796,23799],{"class":749,"line":776},[747,23797,23798],{"class":753},"    script",[747,23800,758],{"class":757},[747,23802,23803,23805],{"class":749,"line":784},[747,23804,14801],{"class":757},[747,23806,23807],{"class":802}," go test .\u002F...\n",[523,23809,23810,23811,23813],{},"The job above would run for the ",[567,23812,23781],{}," stage.",[523,23815,23816],{},"To specify the stages to be run, you put a simple list of the names anywhere in the file:",[738,23818,23820],{"className":740,"code":23819,"language":742,"meta":743,"style":743},"# list of all stages\nstages:\n    - test\n    - build\n    - release\n    - deploy\n",[567,23821,23822,23827,23834,23840,23847,23854],{"__ignoreMap":743},[747,23823,23824],{"class":749,"line":750},[747,23825,23826],{"class":772},"# list of all stages\n",[747,23828,23829,23832],{"class":749,"line":761},[747,23830,23831],{"class":753},"stages",[747,23833,758],{"class":757},[747,23835,23836,23838],{"class":749,"line":769},[747,23837,18665],{"class":757},[747,23839,23793],{"class":802},[747,23841,23842,23844],{"class":749,"line":776},[747,23843,18665],{"class":757},[747,23845,23846],{"class":802}," build\n",[747,23848,23849,23851],{"class":749,"line":784},[747,23850,18665],{"class":757},[747,23852,23853],{"class":802}," release\n",[747,23855,23856,23858],{"class":749,"line":790},[747,23857,18665],{"class":757},[747,23859,23860],{"class":802}," deploy\n",[523,23862,23863],{},"You can specify the image to be used to run the commands on a global level or on a per job basis. To extend the given job example, see below how you can specify the image:",[738,23865,23867],{"className":740,"code":23866,"language":742,"meta":743,"style":743},"# For jobs without a image specified use the below Docker image\nimage: golang:1.12.5-stretch\n# Or for the test job the image `golang:1.9` will be used:\ntest:\n    stage: test\n    image: python:3\n    script:\n        - echo Something in the test step in a python:3 image\n",[567,23868,23869,23874,23884,23889,23895,23903,23912,23918],{"__ignoreMap":743},[747,23870,23871],{"class":749,"line":750},[747,23872,23873],{"class":772},"# For jobs without a image specified use the below Docker image\n",[747,23875,23876,23879,23881],{"class":749,"line":761},[747,23877,23878],{"class":753},"image",[747,23880,856],{"class":757},[747,23882,23883],{"class":802}," golang:1.12.5-stretch\n",[747,23885,23886],{"class":749,"line":769},[747,23887,23888],{"class":772},"# Or for the test job the image `golang:1.9` will be used:\n",[747,23890,23891,23893],{"class":749,"line":776},[747,23892,23781],{"class":753},[747,23894,758],{"class":757},[747,23896,23897,23899,23901],{"class":749,"line":784},[747,23898,23788],{"class":753},[747,23900,856],{"class":757},[747,23902,23793],{"class":802},[747,23904,23905,23907,23909],{"class":749,"line":790},[747,23906,10899],{"class":753},[747,23908,856],{"class":757},[747,23910,23911],{"class":802}," python:3\n",[747,23913,23914,23916],{"class":749,"line":796},[747,23915,23798],{"class":753},[747,23917,758],{"class":757},[747,23919,23920,23922],{"class":749,"line":806},[747,23921,14801],{"class":757},[747,23923,23924],{"class":802}," echo Something in the test step in a python:3 image\n",[6072,23926,23927,23931],{},[523,23928,23929],{},[584,23930,6189],{},[523,23932,23933,23934,23936,23937,1909],{},"For other parts of the ",[567,23935,23716],{},", please check the comments in the file below or just checkout the GitLab CI documentation for all possible settings\u002Fparameters here: ",[527,23938,23939],{"href":23939,"rel":23940},"https:\u002F\u002Fdocs.gitlab.com\u002Fce\u002Fci\u002Fyaml\u002FREADME.html",[531],[523,23942,8336,23943,23945,23946,714,23948,714,23950,587,23953,856],{},[567,23944,23716],{}," 4 stages are defined ",[567,23947,23781],{},[567,23949,9758],{},[567,23951,23952],{},"release",[567,23954,23955],{},"deploy",[668,23957,23958,23969,23978,23993],{},[638,23959,23960,23962,23963,23968],{},[567,23961,23781],{}," stage simply runs ",[527,23964,23967],{"href":23965,"rel":23966},"https:\u002F\u002Fgolang.org\u002Fcmd\u002Fgo\u002F#hdr-Test_packages",[531],"go test"," to test the example Golang application in this case.",[638,23970,23971,23973,23974,23977],{},[567,23972,9758],{}," stage compiles the application and tells GitLab CI that the end binary ",[567,23975,23976],{},"app"," is an artifact to be preserved in GitLab and the build containers.",[638,23979,23980,23982,23983,23986,23987,23989,23990,23992],{},[567,23981,23952],{}," stage in which the ",[567,23984,23985],{},"image_build"," job, builds the Docker image and pushes it into the GitLab Container Registry. In the ",[567,23988,23952],{}," stage, I also upload the artifact ",[567,23991,23976],{}," into a S3.",[638,23994,23995,23997,23998,24001,24002,24004,24005,24008],{},[567,23996,23955],{}," stage for branches always deploys to the ",[567,23999,24000],{},"dev"," environment, for tags it will be deployed to ",[567,24003,24000],{}," and the manually triggered into ",[567,24006,24007],{},"live"," environment.",[6072,24010,24011],{},[523,24012,24013,8287,24015],{},[584,24014,22583],{},[527,24016,24019],{"href":24017,"rel":24018},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fpresentation-gitlab-k8s\u002Fblob\u002Fmaster\u002F.gitlab-ci.yml",[531],[567,24020,23716],{},[523,24022,24023,24024,23766],{},"The whole ",[567,24025,23716],{},[738,24027,24029],{"className":740,"code":24028,"language":742,"meta":743,"style":743},"image:\n  name: golang:1.12.5-stretch\n  entrypoint: [\"\u002Fbin\u002Fsh\", \"-c\"]\n\n# The problem is that to be able to use go get, one needs to put\n# the repository in the $GOPATH. So for example if your gitlab domain\n# is mydomainperso.com, and that your repository is repos\u002Fprojectname, and\n# the default GOPATH being \u002Fgo, then you'd need to have your\n# repository in \u002Fgo\u002Fsrc\u002Fmydomainperso.com\u002Frepos\u002Fprojectname\n# Thus, making a symbolic link corrects this.\nbefore_script:\n  - mkdir -p \"\u002Fgo\u002Fsrc\u002Fgitlab.example.com\u002F${CI_PROJECT_PATH}\"\n  - ln -sf \"${CI_PROJECT_DIR}\" \"\u002Fgo\u002Fsrc\u002Fgitlab.example.com\u002F${CI_PROJECT_PATH}\"\n  - cd \"\u002Fgo\u002Fsrc\u002Fgitlab.example.com\u002F${CI_PROJECT_PATH}\u002F\"\n\nstages:\n  - test\n  - build\n  - release\n  - review\n  - deploy\n\ntest:\n  stage: test\n  script:\n    - make test\n\ntest2:\n  stage: test\n  script:\n    - sleep 3\n    - echo \"We did it! Something else runs in parallel!\"\n\ncompile:\n  stage: build\n  script:\n    # Add here all the dependencies, or use glide\u002Fgovendor\u002F...\n    # to get them automatically.\n    - make build\n  artifacts:\n    paths:\n      - app\n\n# Example job to upload the built release to a S3 server with mc\n# For this you need to set `S3_ACCESS_KEY` and `S3_SECRET_KEY` in your GitLab project CI's secret variables\n#release_upload:\n#  stage: release\n#  image:\n#    name: minio\u002Fmc\n#    entrypoint: [\"\u002Fbin\u002Fsh\", \"-c\"]\n#  script:\n#    - echo \"=> We already have artifact sotrage in GitLab! This is for demonstational purposes only.\"\n#    - mc config host add edenmalmoe https:\u002F\u002Fs3.edenmal.net ${ACCESS_KEY} ${SECRET_KEY} S3v4\n#    - mc mb -p edenmalmoe\u002Fbuild-release-${CI_PROJECT_NAME}\u002F\n#    - mc cp app edenmalmoe\u002Fbuild-release-${CI_PROJECT_NAME}\u002F\n\nimage_build:\n  stage: release\n  image:\n    name: docker:latest\n    entrypoint: [\"\u002Fbin\u002Fsh\", \"-c\"]\n  variables:\n    DOCKER_HOST: tcp:\u002F\u002Flocalhost:2375\n  services:\n    - docker:dind\n  script:\n    - docker info\n    - docker login -u \"${CI_REGISTRY_USER}\" -p \"${CI_REGISTRY_PASSWORD}\" \"${CI_REGISTRY}\"\n    - docker build -t \"${CI_REGISTRY_IMAGE}:latest\" .\n    - docker tag \"${CI_REGISTRY_IMAGE}:latest\" \"${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_NAME}\"\n    - test ! -z \"${CI_COMMIT_TAG}\" && docker push \"${CI_REGISTRY_IMAGE}:latest\"\n    - docker push \"${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_NAME}\"\n\ndeploy_review:\n  image:\n    name: lachlanevenson\u002Fk8s-kubectl:latest\n    entrypoint: [\"\u002Fbin\u002Fsh\", \"-c\"]\n  stage: review\n  only:\n    - branches\n  except:\n    - tags\n  environment:\n    name: review\u002F$CI_BUILD_REF_NAME\n    url: https:\u002F\u002F$CI_ENVIRONMENT_SLUG-presentation-gitlab-k8s.edenmal.net\n    on_stop: stop_review\n    kubernetes:\n      namespace: presentation-gitlab-k8s\n  script:\n    - kubectl version\n    - cd manifests\u002F\n    - sed -i \"s~__CI_REGISTRY_IMAGE__~${CI_REGISTRY_IMAGE}~\" deployment.yaml\n    - sed -i \"s\u002F__CI_ENVIRONMENT_SLUG__\u002F${CI_ENVIRONMENT_SLUG}\u002F\" deployment.yaml ingress.yaml service.yaml\n    - sed -i \"s\u002F__VERSION__\u002F${CI_COMMIT_REF_NAME}\u002F\" deployment.yaml ingress.yaml service.yaml\n    - |\n      if kubectl apply -f deployment.yaml | grep -q unchanged; then\n          echo \"=> Patching deployment to force image update.\"\n          kubectl patch -f deployment.yaml -p \"{\\\"spec\\\":{\\\"template\\\":{\\\"metadata\\\":{\\\"annotations\\\":{\\\"ci-last-updated\\\":\\\"$(date +'%s')\\\"}}}}}\"\n      else\n          echo \"=> Deployment apply has changed the object, no need to force image update.\"\n      fi\n    - kubectl apply -f service.yaml || true\n    - kubectl apply -f ingress.yaml\n    - kubectl rollout status -f deployment.yaml\n    - kubectl get all,ing -l ref=${CI_ENVIRONMENT_SLUG}\n\nstop_review:\n  image:\n    name: lachlanevenson\u002Fk8s-kubectl:latest\n    entrypoint: [\"\u002Fbin\u002Fsh\", \"-c\"]\n  stage: review\n  variables:\n    GIT_STRATEGY: none\n  when: manual\n  only:\n    - branches\n  except:\n    - master\n    - tags\n  environment:\n    name: review\u002F$CI_BUILD_REF_NAME\n    action: stop\n    kubernetes:\n      namespace: presentation-gitlab-k8s\n  script:\n    - kubectl version\n    - kubectl delete ing -l ref=${CI_ENVIRONMENT_SLUG}\n    - kubectl delete all -l ref=${CI_ENVIRONMENT_SLUG}\n\ndeploy_live:\n  image:\n    name: lachlanevenson\u002Fk8s-kubectl:latest\n    entrypoint: [\"\u002Fbin\u002Fsh\", \"-c\"]\n  stage: deploy\n  environment:\n    name: live\n    url: https:\u002F\u002Flive-presentation-gitlab-k8s.edenmal.net\n    kubernetes:\n      namespace: presentation-gitlab-k8s\n  only:\n    - tags\n  when: manual\n  script:\n    - kubectl version\n    - cd manifests\u002F\n    - sed -i \"s~__CI_REGISTRY_IMAGE__~${CI_REGISTRY_IMAGE}~\" deployment.yaml\n    - sed -i \"s\u002F__CI_ENVIRONMENT_SLUG__\u002F${CI_ENVIRONMENT_SLUG}\u002F\" deployment.yaml ingress.yaml service.yaml\n    - sed -i \"s\u002F__VERSION__\u002F${CI_COMMIT_REF_NAME}\u002F\" deployment.yaml ingress.yaml service.yaml\n    - kubectl apply -f deployment.yaml\n    - kubectl apply -f service.yaml\n    - kubectl apply -f ingress.yaml\n    - kubectl rollout status -f deployment.yaml\n    - kubectl get all,ing -l ref=${CI_ENVIRONMENT_SLUG}\n",[567,24030,24031,24037,24045,24071,24075,24080,24085,24090,24095,24100,24105,24112,24119,24126,24133,24137,24143,24149,24155,24161,24168,24174,24178,24184,24193,24200,24207,24211,24218,24226,24232,24239,24246,24250,24257,24265,24271,24276,24281,24288,24295,24302,24309,24313,24318,24323,24328,24333,24338,24343,24348,24353,24358,24363,24368,24373,24377,24383,24391,24398,24408,24433,24440,24450,24457,24464,24470,24477,24484,24491,24498,24505,24512,24516,24523,24529,24538,24562,24570,24577,24584,24591,24598,24605,24614,24624,24634,24641,24650,24656,24663,24670,24677,24684,24691,24698,24703,24708,24713,24718,24723,24728,24735,24742,24749,24756,24760,24767,24773,24781,24805,24813,24819,24828,24838,24844,24850,24856,24862,24868,24874,24882,24892,24898,24906,24912,24918,24925,24932,24936,24943,24949,24957,24981,24989,24995,25004,25013,25019,25027,25033,25039,25047,25053,25059,25065,25071,25077,25083,25090,25097,25103,25109],{"__ignoreMap":743},[747,24032,24033,24035],{"class":749,"line":750},[747,24034,23878],{"class":753},[747,24036,758],{"class":757},[747,24038,24039,24041,24043],{"class":749,"line":761},[747,24040,12980],{"class":753},[747,24042,856],{"class":757},[747,24044,23883],{"class":802},[747,24046,24047,24050,24052,24054,24056,24058,24060,24062,24064,24067,24069],{"class":749,"line":769},[747,24048,24049],{"class":753},"  entrypoint",[747,24051,856],{"class":757},[747,24053,4262],{"class":757},[747,24055,3892],{"class":757},[747,24057,9679],{"class":802},[747,24059,3892],{"class":757},[747,24061,10580],{"class":757},[747,24063,969],{"class":757},[747,24065,24066],{"class":802},"-c",[747,24068,3892],{"class":757},[747,24070,4268],{"class":757},[747,24072,24073],{"class":749,"line":776},[747,24074,1255],{"emptyLinePlaceholder":1254},[747,24076,24077],{"class":749,"line":784},[747,24078,24079],{"class":772},"# The problem is that to be able to use go get, one needs to put\n",[747,24081,24082],{"class":749,"line":790},[747,24083,24084],{"class":772},"# the repository in the $GOPATH. So for example if your gitlab domain\n",[747,24086,24087],{"class":749,"line":796},[747,24088,24089],{"class":772},"# is mydomainperso.com, and that your repository is repos\u002Fprojectname, and\n",[747,24091,24092],{"class":749,"line":806},[747,24093,24094],{"class":772},"# the default GOPATH being \u002Fgo, then you'd need to have your\n",[747,24096,24097],{"class":749,"line":814},[747,24098,24099],{"class":772},"# repository in \u002Fgo\u002Fsrc\u002Fmydomainperso.com\u002Frepos\u002Fprojectname\n",[747,24101,24102],{"class":749,"line":822},[747,24103,24104],{"class":772},"# Thus, making a symbolic link corrects this.\n",[747,24106,24107,24110],{"class":749,"line":830},[747,24108,24109],{"class":753},"before_script",[747,24111,758],{"class":757},[747,24113,24114,24116],{"class":749,"line":836},[747,24115,1721],{"class":757},[747,24117,24118],{"class":802}," mkdir -p \"\u002Fgo\u002Fsrc\u002Fgitlab.example.com\u002F${CI_PROJECT_PATH}\"\n",[747,24120,24121,24123],{"class":749,"line":842},[747,24122,1721],{"class":757},[747,24124,24125],{"class":802}," ln -sf \"${CI_PROJECT_DIR}\" \"\u002Fgo\u002Fsrc\u002Fgitlab.example.com\u002F${CI_PROJECT_PATH}\"\n",[747,24127,24128,24130],{"class":749,"line":850},[747,24129,1721],{"class":757},[747,24131,24132],{"class":802}," cd \"\u002Fgo\u002Fsrc\u002Fgitlab.example.com\u002F${CI_PROJECT_PATH}\u002F\"\n",[747,24134,24135],{"class":749,"line":863},[747,24136,1255],{"emptyLinePlaceholder":1254},[747,24138,24139,24141],{"class":749,"line":869},[747,24140,23831],{"class":753},[747,24142,758],{"class":757},[747,24144,24145,24147],{"class":749,"line":877},[747,24146,1721],{"class":757},[747,24148,23793],{"class":802},[747,24150,24151,24153],{"class":749,"line":1015},[747,24152,1721],{"class":757},[747,24154,23846],{"class":802},[747,24156,24157,24159],{"class":749,"line":1021},[747,24158,1721],{"class":757},[747,24160,23853],{"class":802},[747,24162,24163,24165],{"class":749,"line":1027},[747,24164,1721],{"class":757},[747,24166,24167],{"class":802}," review\n",[747,24169,24170,24172],{"class":749,"line":1033},[747,24171,1721],{"class":757},[747,24173,23860],{"class":802},[747,24175,24176],{"class":749,"line":1039},[747,24177,1255],{"emptyLinePlaceholder":1254},[747,24179,24180,24182],{"class":749,"line":1054},[747,24181,23781],{"class":753},[747,24183,758],{"class":757},[747,24185,24186,24189,24191],{"class":749,"line":1060},[747,24187,24188],{"class":753},"  stage",[747,24190,856],{"class":757},[747,24192,23793],{"class":802},[747,24194,24195,24198],{"class":749,"line":1066},[747,24196,24197],{"class":753},"  script",[747,24199,758],{"class":757},[747,24201,24202,24204],{"class":749,"line":1081},[747,24203,18665],{"class":757},[747,24205,24206],{"class":802}," make test\n",[747,24208,24209],{"class":749,"line":1087},[747,24210,1255],{"emptyLinePlaceholder":1254},[747,24212,24213,24216],{"class":749,"line":1102},[747,24214,24215],{"class":753},"test2",[747,24217,758],{"class":757},[747,24219,24220,24222,24224],{"class":749,"line":1110},[747,24221,24188],{"class":753},[747,24223,856],{"class":757},[747,24225,23793],{"class":802},[747,24227,24228,24230],{"class":749,"line":1117},[747,24229,24197],{"class":753},[747,24231,758],{"class":757},[747,24233,24234,24236],{"class":749,"line":1123},[747,24235,18665],{"class":757},[747,24237,24238],{"class":802}," sleep 3\n",[747,24240,24241,24243],{"class":749,"line":1129},[747,24242,18665],{"class":757},[747,24244,24245],{"class":802}," echo \"We did it! Something else runs in parallel!\"\n",[747,24247,24248],{"class":749,"line":1142},[747,24249,1255],{"emptyLinePlaceholder":1254},[747,24251,24252,24255],{"class":749,"line":1150},[747,24253,24254],{"class":753},"compile",[747,24256,758],{"class":757},[747,24258,24259,24261,24263],{"class":749,"line":1157},[747,24260,24188],{"class":753},[747,24262,856],{"class":757},[747,24264,23846],{"class":802},[747,24266,24267,24269],{"class":749,"line":1163},[747,24268,24197],{"class":753},[747,24270,758],{"class":757},[747,24272,24273],{"class":749,"line":1168},[747,24274,24275],{"class":772},"    # Add here all the dependencies, or use glide\u002Fgovendor\u002F...\n",[747,24277,24278],{"class":749,"line":1174},[747,24279,24280],{"class":772},"    # to get them automatically.\n",[747,24282,24283,24285],{"class":749,"line":1480},[747,24284,18665],{"class":757},[747,24286,24287],{"class":802}," make build\n",[747,24289,24290,24293],{"class":749,"line":1491},[747,24291,24292],{"class":753},"  artifacts",[747,24294,758],{"class":757},[747,24296,24297,24300],{"class":749,"line":1496},[747,24298,24299],{"class":753},"    paths",[747,24301,758],{"class":757},[747,24303,24304,24306],{"class":749,"line":1502},[747,24305,799],{"class":757},[747,24307,24308],{"class":802}," app\n",[747,24310,24311],{"class":749,"line":1510},[747,24312,1255],{"emptyLinePlaceholder":1254},[747,24314,24315],{"class":749,"line":1520},[747,24316,24317],{"class":772},"# Example job to upload the built release to a S3 server with mc\n",[747,24319,24320],{"class":749,"line":1525},[747,24321,24322],{"class":772},"# For this you need to set `S3_ACCESS_KEY` and `S3_SECRET_KEY` in your GitLab project CI's secret variables\n",[747,24324,24325],{"class":749,"line":1533},[747,24326,24327],{"class":772},"#release_upload:\n",[747,24329,24330],{"class":749,"line":1539},[747,24331,24332],{"class":772},"#  stage: release\n",[747,24334,24335],{"class":749,"line":1549},[747,24336,24337],{"class":772},"#  image:\n",[747,24339,24340],{"class":749,"line":1554},[747,24341,24342],{"class":772},"#    name: minio\u002Fmc\n",[747,24344,24345],{"class":749,"line":1562},[747,24346,24347],{"class":772},"#    entrypoint: [\"\u002Fbin\u002Fsh\", \"-c\"]\n",[747,24349,24350],{"class":749,"line":1568},[747,24351,24352],{"class":772},"#  script:\n",[747,24354,24355],{"class":749,"line":1577},[747,24356,24357],{"class":772},"#    - echo \"=> We already have artifact sotrage in GitLab! This is for demonstational purposes only.\"\n",[747,24359,24360],{"class":749,"line":1582},[747,24361,24362],{"class":772},"#    - mc config host add edenmalmoe https:\u002F\u002Fs3.edenmal.net ${ACCESS_KEY} ${SECRET_KEY} S3v4\n",[747,24364,24365],{"class":749,"line":1588},[747,24366,24367],{"class":772},"#    - mc mb -p edenmalmoe\u002Fbuild-release-${CI_PROJECT_NAME}\u002F\n",[747,24369,24370],{"class":749,"line":1594},[747,24371,24372],{"class":772},"#    - mc cp app edenmalmoe\u002Fbuild-release-${CI_PROJECT_NAME}\u002F\n",[747,24374,24375],{"class":749,"line":1600},[747,24376,1255],{"emptyLinePlaceholder":1254},[747,24378,24379,24381],{"class":749,"line":4804},[747,24380,23985],{"class":753},[747,24382,758],{"class":757},[747,24384,24385,24387,24389],{"class":749,"line":4810},[747,24386,24188],{"class":753},[747,24388,856],{"class":757},[747,24390,23853],{"class":802},[747,24392,24393,24396],{"class":749,"line":4816},[747,24394,24395],{"class":753},"  image",[747,24397,758],{"class":757},[747,24399,24400,24403,24405],{"class":749,"line":4822},[747,24401,24402],{"class":753},"    name",[747,24404,856],{"class":757},[747,24406,24407],{"class":802}," docker:latest\n",[747,24409,24410,24413,24415,24417,24419,24421,24423,24425,24427,24429,24431],{"class":749,"line":4828},[747,24411,24412],{"class":753},"    entrypoint",[747,24414,856],{"class":757},[747,24416,4262],{"class":757},[747,24418,3892],{"class":757},[747,24420,9679],{"class":802},[747,24422,3892],{"class":757},[747,24424,10580],{"class":757},[747,24426,969],{"class":757},[747,24428,24066],{"class":802},[747,24430,3892],{"class":757},[747,24432,4268],{"class":757},[747,24434,24435,24438],{"class":749,"line":4834},[747,24436,24437],{"class":753},"  variables",[747,24439,758],{"class":757},[747,24441,24442,24445,24447],{"class":749,"line":4840},[747,24443,24444],{"class":753},"    DOCKER_HOST",[747,24446,856],{"class":757},[747,24448,24449],{"class":802}," tcp:\u002F\u002Flocalhost:2375\n",[747,24451,24452,24455],{"class":749,"line":4846},[747,24453,24454],{"class":753},"  services",[747,24456,758],{"class":757},[747,24458,24459,24461],{"class":749,"line":4852},[747,24460,18665],{"class":757},[747,24462,24463],{"class":802}," docker:dind\n",[747,24465,24466,24468],{"class":749,"line":4858},[747,24467,24197],{"class":753},[747,24469,758],{"class":757},[747,24471,24472,24474],{"class":749,"line":4864},[747,24473,18665],{"class":757},[747,24475,24476],{"class":802}," docker info\n",[747,24478,24479,24481],{"class":749,"line":4870},[747,24480,18665],{"class":757},[747,24482,24483],{"class":802}," docker login -u \"${CI_REGISTRY_USER}\" -p \"${CI_REGISTRY_PASSWORD}\" \"${CI_REGISTRY}\"\n",[747,24485,24486,24488],{"class":749,"line":4876},[747,24487,18665],{"class":757},[747,24489,24490],{"class":802}," docker build -t \"${CI_REGISTRY_IMAGE}:latest\" .\n",[747,24492,24493,24495],{"class":749,"line":4882},[747,24494,18665],{"class":757},[747,24496,24497],{"class":802}," docker tag \"${CI_REGISTRY_IMAGE}:latest\" \"${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_NAME}\"\n",[747,24499,24500,24502],{"class":749,"line":4888},[747,24501,18665],{"class":757},[747,24503,24504],{"class":802}," test ! -z \"${CI_COMMIT_TAG}\" && docker push \"${CI_REGISTRY_IMAGE}:latest\"\n",[747,24506,24507,24509],{"class":749,"line":4894},[747,24508,18665],{"class":757},[747,24510,24511],{"class":802}," docker push \"${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_NAME}\"\n",[747,24513,24514],{"class":749,"line":4900},[747,24515,1255],{"emptyLinePlaceholder":1254},[747,24517,24518,24521],{"class":749,"line":4906},[747,24519,24520],{"class":753},"deploy_review",[747,24522,758],{"class":757},[747,24524,24525,24527],{"class":749,"line":4912},[747,24526,24395],{"class":753},[747,24528,758],{"class":757},[747,24530,24531,24533,24535],{"class":749,"line":4928},[747,24532,24402],{"class":753},[747,24534,856],{"class":757},[747,24536,24537],{"class":802}," lachlanevenson\u002Fk8s-kubectl:latest\n",[747,24539,24540,24542,24544,24546,24548,24550,24552,24554,24556,24558,24560],{"class":749,"line":4934},[747,24541,24412],{"class":753},[747,24543,856],{"class":757},[747,24545,4262],{"class":757},[747,24547,3892],{"class":757},[747,24549,9679],{"class":802},[747,24551,3892],{"class":757},[747,24553,10580],{"class":757},[747,24555,969],{"class":757},[747,24557,24066],{"class":802},[747,24559,3892],{"class":757},[747,24561,4268],{"class":757},[747,24563,24564,24566,24568],{"class":749,"line":4940},[747,24565,24188],{"class":753},[747,24567,856],{"class":757},[747,24569,24167],{"class":802},[747,24571,24572,24575],{"class":749,"line":4946},[747,24573,24574],{"class":753},"  only",[747,24576,758],{"class":757},[747,24578,24579,24581],{"class":749,"line":4952},[747,24580,18665],{"class":757},[747,24582,24583],{"class":802}," branches\n",[747,24585,24586,24589],{"class":749,"line":4958},[747,24587,24588],{"class":753},"  except",[747,24590,758],{"class":757},[747,24592,24593,24595],{"class":749,"line":4964},[747,24594,18665],{"class":757},[747,24596,24597],{"class":802}," tags\n",[747,24599,24600,24603],{"class":749,"line":4970},[747,24601,24602],{"class":753},"  environment",[747,24604,758],{"class":757},[747,24606,24607,24609,24611],{"class":749,"line":4998},[747,24608,24402],{"class":753},[747,24610,856],{"class":757},[747,24612,24613],{"class":802}," review\u002F$CI_BUILD_REF_NAME\n",[747,24615,24616,24619,24621],{"class":749,"line":5016},[747,24617,24618],{"class":753},"    url",[747,24620,856],{"class":757},[747,24622,24623],{"class":802}," https:\u002F\u002F$CI_ENVIRONMENT_SLUG-presentation-gitlab-k8s.edenmal.net\n",[747,24625,24626,24629,24631],{"class":749,"line":5048},[747,24627,24628],{"class":753},"    on_stop",[747,24630,856],{"class":757},[747,24632,24633],{"class":802}," stop_review\n",[747,24635,24636,24639],{"class":749,"line":5077},[747,24637,24638],{"class":753},"    kubernetes",[747,24640,758],{"class":757},[747,24642,24643,24646,24648],{"class":749,"line":5098},[747,24644,24645],{"class":753},"      namespace",[747,24647,856],{"class":757},[747,24649,22408],{"class":802},[747,24651,24652,24654],{"class":749,"line":5121},[747,24653,24197],{"class":753},[747,24655,758],{"class":757},[747,24657,24658,24660],{"class":749,"line":5127},[747,24659,18665],{"class":757},[747,24661,24662],{"class":802}," kubectl version\n",[747,24664,24665,24667],{"class":749,"line":5133},[747,24666,18665],{"class":757},[747,24668,24669],{"class":802}," cd manifests\u002F\n",[747,24671,24672,24674],{"class":749,"line":5139},[747,24673,18665],{"class":757},[747,24675,24676],{"class":802}," sed -i \"s~__CI_REGISTRY_IMAGE__~${CI_REGISTRY_IMAGE}~\" deployment.yaml\n",[747,24678,24679,24681],{"class":749,"line":5164},[747,24680,18665],{"class":757},[747,24682,24683],{"class":802}," sed -i \"s\u002F__CI_ENVIRONMENT_SLUG__\u002F${CI_ENVIRONMENT_SLUG}\u002F\" deployment.yaml ingress.yaml service.yaml\n",[747,24685,24686,24688],{"class":749,"line":5205},[747,24687,18665],{"class":757},[747,24689,24690],{"class":802}," sed -i \"s\u002F__VERSION__\u002F${CI_COMMIT_REF_NAME}\u002F\" deployment.yaml ingress.yaml service.yaml\n",[747,24692,24693,24695],{"class":749,"line":5229},[747,24694,18665],{"class":757},[747,24696,24697],{"class":19332}," |\n",[747,24699,24700],{"class":749,"line":5250},[747,24701,24702],{"class":802},"      if kubectl apply -f deployment.yaml | grep -q unchanged; then\n",[747,24704,24705],{"class":749,"line":5264},[747,24706,24707],{"class":802},"          echo \"=> Patching deployment to force image update.\"\n",[747,24709,24710],{"class":749,"line":5282},[747,24711,24712],{"class":802},"          kubectl patch -f deployment.yaml -p \"{\\\"spec\\\":{\\\"template\\\":{\\\"metadata\\\":{\\\"annotations\\\":{\\\"ci-last-updated\\\":\\\"$(date +'%s')\\\"}}}}}\"\n",[747,24714,24715],{"class":749,"line":5311},[747,24716,24717],{"class":802},"      else\n",[747,24719,24720],{"class":749,"line":5331},[747,24721,24722],{"class":802},"          echo \"=> Deployment apply has changed the object, no need to force image update.\"\n",[747,24724,24725],{"class":749,"line":5351},[747,24726,24727],{"class":802},"      fi\n",[747,24729,24730,24732],{"class":749,"line":5374},[747,24731,18665],{"class":757},[747,24733,24734],{"class":802}," kubectl apply -f service.yaml || true\n",[747,24736,24737,24739],{"class":749,"line":5394},[747,24738,18665],{"class":757},[747,24740,24741],{"class":802}," kubectl apply -f ingress.yaml\n",[747,24743,24744,24746],{"class":749,"line":5413},[747,24745,18665],{"class":757},[747,24747,24748],{"class":802}," kubectl rollout status -f deployment.yaml\n",[747,24750,24751,24753],{"class":749,"line":5430},[747,24752,18665],{"class":757},[747,24754,24755],{"class":802}," kubectl get all,ing -l ref=${CI_ENVIRONMENT_SLUG}\n",[747,24757,24758],{"class":749,"line":5447},[747,24759,1255],{"emptyLinePlaceholder":1254},[747,24761,24762,24765],{"class":749,"line":5500},[747,24763,24764],{"class":753},"stop_review",[747,24766,758],{"class":757},[747,24768,24769,24771],{"class":749,"line":5517},[747,24770,24395],{"class":753},[747,24772,758],{"class":757},[747,24774,24775,24777,24779],{"class":749,"line":5534},[747,24776,24402],{"class":753},[747,24778,856],{"class":757},[747,24780,24537],{"class":802},[747,24782,24783,24785,24787,24789,24791,24793,24795,24797,24799,24801,24803],{"class":749,"line":5556},[747,24784,24412],{"class":753},[747,24786,856],{"class":757},[747,24788,4262],{"class":757},[747,24790,3892],{"class":757},[747,24792,9679],{"class":802},[747,24794,3892],{"class":757},[747,24796,10580],{"class":757},[747,24798,969],{"class":757},[747,24800,24066],{"class":802},[747,24802,3892],{"class":757},[747,24804,4268],{"class":757},[747,24806,24807,24809,24811],{"class":749,"line":5577},[747,24808,24188],{"class":753},[747,24810,856],{"class":757},[747,24812,24167],{"class":802},[747,24814,24815,24817],{"class":749,"line":5606},[747,24816,24437],{"class":753},[747,24818,758],{"class":757},[747,24820,24821,24824,24826],{"class":749,"line":21912},[747,24822,24823],{"class":753},"    GIT_STRATEGY",[747,24825,856],{"class":757},[747,24827,930],{"class":802},[747,24829,24830,24833,24835],{"class":749,"line":21918},[747,24831,24832],{"class":753},"  when",[747,24834,856],{"class":757},[747,24836,24837],{"class":802}," manual\n",[747,24839,24840,24842],{"class":749,"line":21924},[747,24841,24574],{"class":753},[747,24843,758],{"class":757},[747,24845,24846,24848],{"class":749,"line":21930},[747,24847,18665],{"class":757},[747,24849,24583],{"class":802},[747,24851,24852,24854],{"class":749,"line":21935},[747,24853,24588],{"class":753},[747,24855,758],{"class":757},[747,24857,24858,24860],{"class":749,"line":21941},[747,24859,18665],{"class":757},[747,24861,22452],{"class":802},[747,24863,24864,24866],{"class":749,"line":21946},[747,24865,18665],{"class":757},[747,24867,24597],{"class":802},[747,24869,24870,24872],{"class":749,"line":21952},[747,24871,24602],{"class":753},[747,24873,758],{"class":757},[747,24875,24876,24878,24880],{"class":749,"line":21957},[747,24877,24402],{"class":753},[747,24879,856],{"class":757},[747,24881,24613],{"class":802},[747,24883,24884,24887,24889],{"class":749,"line":21963},[747,24885,24886],{"class":753},"    action",[747,24888,856],{"class":757},[747,24890,24891],{"class":802}," stop\n",[747,24893,24894,24896],{"class":749,"line":21969},[747,24895,24638],{"class":753},[747,24897,758],{"class":757},[747,24899,24900,24902,24904],{"class":749,"line":21974},[747,24901,24645],{"class":753},[747,24903,856],{"class":757},[747,24905,22408],{"class":802},[747,24907,24908,24910],{"class":749,"line":21980},[747,24909,24197],{"class":753},[747,24911,758],{"class":757},[747,24913,24914,24916],{"class":749,"line":21986},[747,24915,18665],{"class":757},[747,24917,24662],{"class":802},[747,24919,24920,24922],{"class":749,"line":21992},[747,24921,18665],{"class":757},[747,24923,24924],{"class":802}," kubectl delete ing -l ref=${CI_ENVIRONMENT_SLUG}\n",[747,24926,24927,24929],{"class":749,"line":21997},[747,24928,18665],{"class":757},[747,24930,24931],{"class":802}," kubectl delete all -l ref=${CI_ENVIRONMENT_SLUG}\n",[747,24933,24934],{"class":749,"line":22003},[747,24935,1255],{"emptyLinePlaceholder":1254},[747,24937,24938,24941],{"class":749,"line":22008},[747,24939,24940],{"class":753},"deploy_live",[747,24942,758],{"class":757},[747,24944,24945,24947],{"class":749,"line":22014},[747,24946,24395],{"class":753},[747,24948,758],{"class":757},[747,24950,24951,24953,24955],{"class":749,"line":22020},[747,24952,24402],{"class":753},[747,24954,856],{"class":757},[747,24956,24537],{"class":802},[747,24958,24959,24961,24963,24965,24967,24969,24971,24973,24975,24977,24979],{"class":749,"line":22025},[747,24960,24412],{"class":753},[747,24962,856],{"class":757},[747,24964,4262],{"class":757},[747,24966,3892],{"class":757},[747,24968,9679],{"class":802},[747,24970,3892],{"class":757},[747,24972,10580],{"class":757},[747,24974,969],{"class":757},[747,24976,24066],{"class":802},[747,24978,3892],{"class":757},[747,24980,4268],{"class":757},[747,24982,24983,24985,24987],{"class":749,"line":22031},[747,24984,24188],{"class":753},[747,24986,856],{"class":757},[747,24988,23860],{"class":802},[747,24990,24991,24993],{"class":749,"line":22036},[747,24992,24602],{"class":753},[747,24994,758],{"class":757},[747,24996,24997,24999,25001],{"class":749,"line":22042},[747,24998,24402],{"class":753},[747,25000,856],{"class":757},[747,25002,25003],{"class":802}," live\n",[747,25005,25006,25008,25010],{"class":749,"line":22048},[747,25007,24618],{"class":753},[747,25009,856],{"class":757},[747,25011,25012],{"class":802}," https:\u002F\u002Flive-presentation-gitlab-k8s.edenmal.net\n",[747,25014,25015,25017],{"class":749,"line":22053},[747,25016,24638],{"class":753},[747,25018,758],{"class":757},[747,25020,25021,25023,25025],{"class":749,"line":22059},[747,25022,24645],{"class":753},[747,25024,856],{"class":757},[747,25026,22408],{"class":802},[747,25028,25029,25031],{"class":749,"line":22064},[747,25030,24574],{"class":753},[747,25032,758],{"class":757},[747,25034,25035,25037],{"class":749,"line":22072},[747,25036,18665],{"class":757},[747,25038,24597],{"class":802},[747,25040,25041,25043,25045],{"class":749,"line":22078},[747,25042,24832],{"class":753},[747,25044,856],{"class":757},[747,25046,24837],{"class":802},[747,25048,25049,25051],{"class":749,"line":22084},[747,25050,24197],{"class":753},[747,25052,758],{"class":757},[747,25054,25055,25057],{"class":749,"line":22094},[747,25056,18665],{"class":757},[747,25058,24662],{"class":802},[747,25060,25061,25063],{"class":749,"line":22099},[747,25062,18665],{"class":757},[747,25064,24669],{"class":802},[747,25066,25067,25069],{"class":749,"line":22105},[747,25068,18665],{"class":757},[747,25070,24676],{"class":802},[747,25072,25073,25075],{"class":749,"line":22111},[747,25074,18665],{"class":757},[747,25076,24683],{"class":802},[747,25078,25079,25081],{"class":749,"line":22117},[747,25080,18665],{"class":757},[747,25082,24690],{"class":802},[747,25084,25085,25087],{"class":749,"line":22122},[747,25086,18665],{"class":757},[747,25088,25089],{"class":802}," kubectl apply -f deployment.yaml\n",[747,25091,25092,25094],{"class":749,"line":22128},[747,25093,18665],{"class":757},[747,25095,25096],{"class":802}," kubectl apply -f service.yaml\n",[747,25098,25099,25101],{"class":749,"line":22133},[747,25100,18665],{"class":757},[747,25102,24741],{"class":802},[747,25104,25105,25107],{"class":749,"line":22139},[747,25106,18665],{"class":757},[747,25108,24748],{"class":802},[747,25110,25111,25113],{"class":749,"line":22145},[747,25112,18665],{"class":757},[747,25114,24755],{"class":802},[6072,25116,25117,25121],{},[523,25118,25119],{},[584,25120,6189],{},[523,25122,25123,25124,25127,25128,25131,25132,1909],{},"Be sure to replace ",[567,25125,25126],{},"gitlab.example.com"," with your GitLab address and\u002F or remove the top ",[567,25129,25130],{},"before_script:"," part when using ",[567,25133,25134],{},"go mod",[523,25136,25137,25138,587,25141,25144,25145,25148,25149],{},"There are special control keys like ",[567,25139,25140],{},"when",[567,25142,25143],{},"only"," that allow for limiting the runs of the CI, to for example with ",[567,25146,25147],{},"only: [\"tags\"]"," to run for created tags only and so on.\nMore on this topic can be found at the GitLab CI YAML file documentation here: ",[527,25150,23939],{"href":23939,"rel":25151},[531],[523,25153,25154,25155,25157],{},"I hope you can what it does by looking at the ",[567,25156,19016],{}," parts of the jobs and the stages that will be run.",[535,25159,25161],{"id":25160},"step-6-add-docker-login-information-to-kubernetes","Step 6 - Add Docker login information to Kubernetes",[523,25163,25164,25165,25168,25169,25171],{},"To be able to deploy the built image from the GitLab registry later on, you need to add the Docker login information for the GitLab Registry as a ",[567,25166,25167],{},"Secret"," to Kubernetes. You need to have ",[567,25170,15269],{}," downloaded and usable on your system for that.",[523,25173,25174],{},"Be sure to replace the following placeholders in the upcoming command:",[668,25176,25177,25182],{},[638,25178,25179,4175],{},[567,25180,25181],{},"YOUR_GITLAB_USERNAME",[638,25183,25184,4175],{},[567,25185,25186],{},"YOUR_PERSONAL_GITLAB_ACCESS_TOKEN_HERE",[523,25188,25189,25190,25192],{},"After replacing the placeholders in the command, run it to create the Docker login ",[567,25191,25167],{}," in Kubernetes:",[738,25194,25196],{"className":1621,"code":25195,"language":1623,"meta":743,"style":743},"kubectl create \\\n    -n presentation-gitlab-k8s \\\n    secret docker-registry registry-gitlab-key \\\n    --docker-server=registry.example.com \\\n    --docker-username=YOUR_GITLAB_USERNAME \\\n    --docker-password=YOUR_PERSONAL_GITLAB_ACCESS_TOKEN_HERE\n",[567,25197,25198,25206,25215,25228,25235,25242],{"__ignoreMap":743},[747,25199,25200,25202,25204],{"class":749,"line":750},[747,25201,15269],{"class":1630},[747,25203,1925],{"class":802},[747,25205,1641],{"class":1640},[747,25207,25208,25211,25213],{"class":749,"line":761},[747,25209,25210],{"class":802},"    -n",[747,25212,23116],{"class":802},[747,25214,1641],{"class":1640},[747,25216,25217,25220,25223,25226],{"class":749,"line":769},[747,25218,25219],{"class":802},"    secret",[747,25221,25222],{"class":802}," docker-registry",[747,25224,25225],{"class":802}," registry-gitlab-key",[747,25227,1641],{"class":1640},[747,25229,25230,25233],{"class":749,"line":776},[747,25231,25232],{"class":802},"    --docker-server=registry.example.com",[747,25234,1641],{"class":1640},[747,25236,25237,25240],{"class":749,"line":784},[747,25238,25239],{"class":802},"    --docker-username=YOUR_GITLAB_USERNAME",[747,25241,1641],{"class":1640},[747,25243,25244],{"class":749,"line":790},[747,25245,25246],{"class":802},"    --docker-password=YOUR_PERSONAL_GITLAB_ACCESS_TOKEN_HERE\n",[523,25248,25249,25250,25252,25253,25256],{},"Keep the name of the ",[567,25251,25167],{}," in mind that has been created by the ",[567,25254,25255],{},"kubectl create"," command above, it is needed in the next command.",[523,25258,25259,25260,8287,25262,25264,25265,25267],{},"This \"patches\" the ",[567,25261,2014],{},[567,25263,22299],{}," to automatically use the Docker login ",[567,25266,25167],{}," for pulling images from the registry.",[738,25269,25271],{"className":1621,"code":25270,"language":1623,"meta":743,"style":743},"kubectl patch \\\n    -n presentation-gitlab-k8s \\\n    serviceaccount default \\\n    -p '{\"imagePullSecrets\": [{\"name\": \"registry-gitlab-key\"}]}'\n",[567,25272,25273,25281,25289,25298],{"__ignoreMap":743},[747,25274,25275,25277,25279],{"class":749,"line":750},[747,25276,15269],{"class":1630},[747,25278,16029],{"class":802},[747,25280,1641],{"class":1640},[747,25282,25283,25285,25287],{"class":749,"line":761},[747,25284,25210],{"class":802},[747,25286,23116],{"class":802},[747,25288,1641],{"class":1640},[747,25290,25291,25294,25296],{"class":749,"line":769},[747,25292,25293],{"class":802},"    serviceaccount",[747,25295,1931],{"class":802},[747,25297,1641],{"class":1640},[747,25299,25300,25302,25304,25307],{"class":749,"line":776},[747,25301,6614],{"class":802},[747,25303,3537],{"class":757},[747,25305,25306],{"class":802},"{\"imagePullSecrets\": [{\"name\": \"registry-gitlab-key\"}]}",[747,25308,13042],{"class":757},[523,25310,25311,25312,2006],{},"(For more information, see ",[527,25313,25316],{"href":25314,"rel":25315},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Ftasks\u002Fconfigure-pod-container\u002Fconfigure-service-account\u002F#add-imagepullsecrets-to-a-service-account",[531],"Kubernetes - Configure Service Accounts for Pods - Add ImagePullSecrets to a service account",[523,25318,25319],{},"Next thing is to create the Kubernetes manifests to deploy the built Docker image(s) to the cluster.",[535,25321,25323],{"id":25322},"step-7-create-kubernetes-manifests","Step 7 - Create Kubernetes manifests",[523,25325,25326],{},"Now you are creating the Kubernetes manifests for your application and add them to your repository.",[523,25328,10839,25329,25332,25333,7258],{},[567,25330,25331],{},"Deployment"," manifest (",[567,25334,25335],{},"deployment.yaml",[738,25337,25339],{"className":740,"code":25338,"language":742,"meta":743,"style":743},"apiVersion: apps\u002Fv1\nkind: Deployment\nmetadata:\n  name: presentation-gitlab-k8s-__CI_ENVIRONMENT_SLUG__\n  labels:\n    app: presentation-gitlab-k8s\n    ref: __CI_ENVIRONMENT_SLUG__\n    track: stable\nspec:\n  replicas: 2\n  selector:\n    matchLabels:\n      app: presentation-gitlab-k8s\n      ref: __CI_ENVIRONMENT_SLUG__\n  template:\n    metadata:\n      labels:\n        app: presentation-gitlab-k8s\n        ref: __CI_ENVIRONMENT_SLUG__\n        track: stable\n    spec:\n      containers:\n      - name: app\n        image: __CI_REGISTRY_IMAGE__:__VERSION__\n        imagePullPolicy: Always\n        ports:\n        - name: http-metrics\n          protocol: TCP\n          containerPort: 8000\n        livenessProbe:\n          httpGet:\n            path: \u002Fhealth\n            port: 8000\n          initialDelaySeconds: 3\n          timeoutSeconds: 2\n        readinessProbe:\n          httpGet:\n            path: \u002Fhealth\n            port: 8000\n          initialDelaySeconds: 3\n          timeoutSeconds: 2\n",[567,25340,25341,25350,25359,25365,25374,25381,25390,25400,25410,25416,25426,25433,25440,25449,25458,25465,25471,25478,25487,25496,25505,25512,25519,25529,25539,25549,25556,25567,25577,25587,25594,25601,25611,25620,25629,25638,25645,25651,25659,25667,25675],{"__ignoreMap":743},[747,25342,25343,25345,25347],{"class":749,"line":750},[747,25344,12949],{"class":753},[747,25346,856],{"class":757},[747,25348,25349],{"class":802}," apps\u002Fv1\n",[747,25351,25352,25354,25356],{"class":749,"line":761},[747,25353,12963],{"class":753},[747,25355,856],{"class":757},[747,25357,25358],{"class":802}," Deployment\n",[747,25360,25361,25363],{"class":749,"line":769},[747,25362,12973],{"class":753},[747,25364,758],{"class":757},[747,25366,25367,25369,25371],{"class":749,"line":776},[747,25368,12980],{"class":753},[747,25370,856],{"class":757},[747,25372,25373],{"class":802}," presentation-gitlab-k8s-__CI_ENVIRONMENT_SLUG__\n",[747,25375,25376,25379],{"class":749,"line":784},[747,25377,25378],{"class":753},"  labels",[747,25380,758],{"class":757},[747,25382,25383,25386,25388],{"class":749,"line":790},[747,25384,25385],{"class":753},"    app",[747,25387,856],{"class":757},[747,25389,22408],{"class":802},[747,25391,25392,25395,25397],{"class":749,"line":796},[747,25393,25394],{"class":753},"    ref",[747,25396,856],{"class":757},[747,25398,25399],{"class":802}," __CI_ENVIRONMENT_SLUG__\n",[747,25401,25402,25405,25407],{"class":749,"line":806},[747,25403,25404],{"class":753},"    track",[747,25406,856],{"class":757},[747,25408,25409],{"class":802}," stable\n",[747,25411,25412,25414],{"class":749,"line":814},[747,25413,12990],{"class":753},[747,25415,758],{"class":757},[747,25417,25418,25421,25423],{"class":749,"line":822},[747,25419,25420],{"class":753},"  replicas",[747,25422,856],{"class":757},[747,25424,25425],{"class":1895}," 2\n",[747,25427,25428,25431],{"class":749,"line":830},[747,25429,25430],{"class":753},"  selector",[747,25432,758],{"class":757},[747,25434,25435,25438],{"class":749,"line":836},[747,25436,25437],{"class":753},"    matchLabels",[747,25439,758],{"class":757},[747,25441,25442,25445,25447],{"class":749,"line":842},[747,25443,25444],{"class":753},"      app",[747,25446,856],{"class":757},[747,25448,22408],{"class":802},[747,25450,25451,25454,25456],{"class":749,"line":850},[747,25452,25453],{"class":753},"      ref",[747,25455,856],{"class":757},[747,25457,25399],{"class":802},[747,25459,25460,25463],{"class":749,"line":863},[747,25461,25462],{"class":753},"  template",[747,25464,758],{"class":757},[747,25466,25467,25469],{"class":749,"line":869},[747,25468,21456],{"class":753},[747,25470,758],{"class":757},[747,25472,25473,25476],{"class":749,"line":877},[747,25474,25475],{"class":753},"      labels",[747,25477,758],{"class":757},[747,25479,25480,25483,25485],{"class":749,"line":1015},[747,25481,25482],{"class":753},"        app",[747,25484,856],{"class":757},[747,25486,22408],{"class":802},[747,25488,25489,25492,25494],{"class":749,"line":1021},[747,25490,25491],{"class":753},"        ref",[747,25493,856],{"class":757},[747,25495,25399],{"class":802},[747,25497,25498,25501,25503],{"class":749,"line":1027},[747,25499,25500],{"class":753},"        track",[747,25502,856],{"class":757},[747,25504,25409],{"class":802},[747,25506,25507,25510],{"class":749,"line":1033},[747,25508,25509],{"class":753},"    spec",[747,25511,758],{"class":757},[747,25513,25514,25517],{"class":749,"line":1039},[747,25515,25516],{"class":753},"      containers",[747,25518,758],{"class":757},[747,25520,25521,25523,25525,25527],{"class":749,"line":1054},[747,25522,799],{"class":757},[747,25524,14804],{"class":753},[747,25526,856],{"class":757},[747,25528,24308],{"class":802},[747,25530,25531,25534,25536],{"class":749,"line":1060},[747,25532,25533],{"class":753},"        image",[747,25535,856],{"class":757},[747,25537,25538],{"class":802}," __CI_REGISTRY_IMAGE__:__VERSION__\n",[747,25540,25541,25544,25546],{"class":749,"line":1066},[747,25542,25543],{"class":753},"        imagePullPolicy",[747,25545,856],{"class":757},[747,25547,25548],{"class":802}," Always\n",[747,25550,25551,25554],{"class":749,"line":1081},[747,25552,25553],{"class":753},"        ports",[747,25555,758],{"class":757},[747,25557,25558,25560,25562,25564],{"class":749,"line":1087},[747,25559,14801],{"class":757},[747,25561,14804],{"class":753},[747,25563,856],{"class":757},[747,25565,25566],{"class":802}," http-metrics\n",[747,25568,25569,25572,25574],{"class":749,"line":1102},[747,25570,25571],{"class":753},"          protocol",[747,25573,856],{"class":757},[747,25575,25576],{"class":802}," TCP\n",[747,25578,25579,25582,25584],{"class":749,"line":1110},[747,25580,25581],{"class":753},"          containerPort",[747,25583,856],{"class":757},[747,25585,25586],{"class":1895}," 8000\n",[747,25588,25589,25592],{"class":749,"line":1117},[747,25590,25591],{"class":753},"        livenessProbe",[747,25593,758],{"class":757},[747,25595,25596,25599],{"class":749,"line":1123},[747,25597,25598],{"class":753},"          httpGet",[747,25600,758],{"class":757},[747,25602,25603,25606,25608],{"class":749,"line":1129},[747,25604,25605],{"class":753},"            path",[747,25607,856],{"class":757},[747,25609,25610],{"class":802}," \u002Fhealth\n",[747,25612,25613,25616,25618],{"class":749,"line":1142},[747,25614,25615],{"class":753},"            port",[747,25617,856],{"class":757},[747,25619,25586],{"class":1895},[747,25621,25622,25625,25627],{"class":749,"line":1150},[747,25623,25624],{"class":753},"          initialDelaySeconds",[747,25626,856],{"class":757},[747,25628,14751],{"class":1895},[747,25630,25631,25634,25636],{"class":749,"line":1157},[747,25632,25633],{"class":753},"          timeoutSeconds",[747,25635,856],{"class":757},[747,25637,25425],{"class":1895},[747,25639,25640,25643],{"class":749,"line":1163},[747,25641,25642],{"class":753},"        readinessProbe",[747,25644,758],{"class":757},[747,25646,25647,25649],{"class":749,"line":1168},[747,25648,25598],{"class":753},[747,25650,758],{"class":757},[747,25652,25653,25655,25657],{"class":749,"line":1174},[747,25654,25605],{"class":753},[747,25656,856],{"class":757},[747,25658,25610],{"class":802},[747,25660,25661,25663,25665],{"class":749,"line":1480},[747,25662,25615],{"class":753},[747,25664,856],{"class":757},[747,25666,25586],{"class":1895},[747,25668,25669,25671,25673],{"class":749,"line":1491},[747,25670,25624],{"class":753},[747,25672,856],{"class":757},[747,25674,14751],{"class":1895},[747,25676,25677,25679,25681],{"class":749,"line":1496},[747,25678,25633],{"class":753},[747,25680,856],{"class":757},[747,25682,25425],{"class":1895},[523,25684,25685,25686,25688,25689,25691,25692],{},"This is a basic Kubernetes ",[567,25687,25331],{}," manifest. For more information on ",[567,25690,25331],{}," manifests please check the Kubernetes Docs page here: ",[527,25693,25694],{"href":25694,"rel":25695},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fworkloads\u002Fcontrollers\u002Fdeployment\u002F",[531],[523,25697,25698,25699,587,25702,25705,25706,25708,25709,6374,25711,25713,25714,25716],{},"Placeholders like ",[567,25700,25701],{},"__CI_ENVIRONMENT_SLUG__",[567,25703,25704],{},"__VERSION__"," are used for templating this single manifest for the multiple environments we want to achieve.\nFor example later the ",[567,25707,25701],{}," get's replaced by ",[567,25710,24000],{},[567,25712,24007],{}," (environment name) and ",[567,25715,25704],{}," with the built image tag.",[523,25718,25719,25720,25723,25724,25726,25727,25730,25731,25733,25734,7258],{},"To be able to connect to the generated ",[567,25721,25722],{},"Pod","s of the ",[567,25725,25331],{},", a ",[567,25728,25729],{},"Service"," is also required.\nA ",[567,25732,25729],{}," manifest looks like this, includes the placeholders already (",[567,25735,25736],{},"service.yaml",[738,25738,25740],{"className":740,"code":25739,"language":742,"meta":743,"style":743},"apiVersion: v1\nkind: Service\nmetadata:\n  name: presentation-gitlab-k8s-__CI_BUILD_REF_SLUG__\n  namespace: presentation-gitlab-k8s\n  labels:\n    app: __CI_BUILD_REF_SLUG__\n  annotations:\n    prometheus.io\u002Fscrape: \"true\"\n    prometheus.io\u002Fport: \"8000\"\n    prometheus.io\u002Fscheme: \"http\"\n    prometheus.io\u002Fpath: \"\u002Fmetrics\"\nspec:\n  type: ClusterIP\n  ports:\n    - name: http-metrics\n      port: 8000\n      protocol: TCP\n  selector:\n    app: __CI_BUILD_REF_SLUG__\n",[567,25741,25742,25750,25759,25765,25774,25782,25788,25797,25804,25817,25831,25845,25859,25865,25874,25881,25891,25900,25909,25915],{"__ignoreMap":743},[747,25743,25744,25746,25748],{"class":749,"line":750},[747,25745,12949],{"class":753},[747,25747,856],{"class":757},[747,25749,22608],{"class":802},[747,25751,25752,25754,25756],{"class":749,"line":761},[747,25753,12963],{"class":753},[747,25755,856],{"class":757},[747,25757,25758],{"class":802}," Service\n",[747,25760,25761,25763],{"class":749,"line":769},[747,25762,12973],{"class":753},[747,25764,758],{"class":757},[747,25766,25767,25769,25771],{"class":749,"line":776},[747,25768,12980],{"class":753},[747,25770,856],{"class":757},[747,25772,25773],{"class":802}," presentation-gitlab-k8s-__CI_BUILD_REF_SLUG__\n",[747,25775,25776,25778,25780],{"class":749,"line":784},[747,25777,13231],{"class":753},[747,25779,856],{"class":757},[747,25781,22408],{"class":802},[747,25783,25784,25786],{"class":749,"line":790},[747,25785,25378],{"class":753},[747,25787,758],{"class":757},[747,25789,25790,25792,25794],{"class":749,"line":796},[747,25791,25385],{"class":753},[747,25793,856],{"class":757},[747,25795,25796],{"class":802}," __CI_BUILD_REF_SLUG__\n",[747,25798,25799,25802],{"class":749,"line":806},[747,25800,25801],{"class":753},"  annotations",[747,25803,758],{"class":757},[747,25805,25806,25809,25811,25813,25815],{"class":749,"line":814},[747,25807,25808],{"class":753},"    prometheus.io\u002Fscrape",[747,25810,856],{"class":757},[747,25812,969],{"class":757},[747,25814,5306],{"class":802},[747,25816,975],{"class":757},[747,25818,25819,25822,25824,25826,25829],{"class":749,"line":822},[747,25820,25821],{"class":753},"    prometheus.io\u002Fport",[747,25823,856],{"class":757},[747,25825,969],{"class":757},[747,25827,25828],{"class":802},"8000",[747,25830,975],{"class":757},[747,25832,25833,25836,25838,25840,25843],{"class":749,"line":830},[747,25834,25835],{"class":753},"    prometheus.io\u002Fscheme",[747,25837,856],{"class":757},[747,25839,969],{"class":757},[747,25841,25842],{"class":802},"http",[747,25844,975],{"class":757},[747,25846,25847,25850,25852,25854,25857],{"class":749,"line":836},[747,25848,25849],{"class":753},"    prometheus.io\u002Fpath",[747,25851,856],{"class":757},[747,25853,969],{"class":757},[747,25855,25856],{"class":802},"\u002Fmetrics",[747,25858,975],{"class":757},[747,25860,25861,25863],{"class":749,"line":842},[747,25862,12990],{"class":753},[747,25864,758],{"class":757},[747,25866,25867,25869,25871],{"class":749,"line":850},[747,25868,18593],{"class":753},[747,25870,856],{"class":757},[747,25872,25873],{"class":802}," ClusterIP\n",[747,25875,25876,25879],{"class":749,"line":863},[747,25877,25878],{"class":753},"  ports",[747,25880,758],{"class":757},[747,25882,25883,25885,25887,25889],{"class":749,"line":869},[747,25884,18665],{"class":757},[747,25886,14804],{"class":753},[747,25888,856],{"class":757},[747,25890,25566],{"class":802},[747,25892,25893,25896,25898],{"class":749,"line":877},[747,25894,25895],{"class":753},"      port",[747,25897,856],{"class":757},[747,25899,25586],{"class":1895},[747,25901,25902,25905,25907],{"class":749,"line":1015},[747,25903,25904],{"class":753},"      protocol",[747,25906,856],{"class":757},[747,25908,25576],{"class":802},[747,25910,25911,25913],{"class":749,"line":1021},[747,25912,25430],{"class":753},[747,25914,758],{"class":757},[747,25916,25917,25919,25921],{"class":749,"line":1027},[747,25918,25385],{"class":753},[747,25920,856],{"class":757},[747,25922,25796],{"class":802},[523,25924,25925,25926,25928,25929,25932,25933,25938,25939,25941,25942,25944,25945,25947,25948],{},"The application runs on port ",[567,25927,25828],{},". The port is named ",[567,25930,25931],{},"http-metrics"," as in my case of Kubernetes cluster I use the ",[527,25934,25937],{"href":25935,"rel":25936},"https:\u002F\u002Fgithub.com\u002Fcoreos\u002Fprometheus-operator",[531],"prometheus-operator"," which creates the \"auto-discovery\" config for Prometheus for example to monitor all ",[567,25940,25729],{},"s with a port named ",[567,25943,25931],{},".\nThe Kubernetes ",[567,25946,25729],{}," documentation can be found here: ",[527,25949,25950],{"href":25950,"rel":25951},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fservices-networking\u002Fservice\u002F",[531],[523,25953,25954,25955,25957,25958,25960,25961,3052],{},"But now we would be only able to connect to the cluster from the inside and not the outside. That's what ",[567,25956,158],{},"es are for. As the name implies they provide a way of allowing traffic to kind of flow into the cluster to a certain ",[567,25959,25729],{},".\nThe following manifest contains so called \"annotations\" that would automatically get a Let'sencrypt certificate for it and deploy it into the \"loadbalancer\". The file is named (",[567,25962,25963],{},"ingress.yaml",[738,25965,25967],{"className":740,"code":25966,"language":742,"meta":743,"style":743},"apiVersion: extensions\u002Fv1beta1\nkind: Ingress\nmetadata:\n  name: presentation-gitlab-k8s-__CI_BUILD_REF_SLUG__\n  namespace: presentation-gitlab-k8s\n  labels:\n    app: __CI_BUILD_REF_SLUG__\n  annotations:\n    kubernetes.io\u002Ftls-acme: \"true\"\n    kubernetes.io\u002Fingress.class: \"nginx\"\nspec:\n  tls:\n  - hosts:\n    - __CI_BUILD_REF_SLUG__-presentation-gitlab-k8s.edenmal.net\n    # the secret used here is an unsigned wildcard cert for demo purposes\n    # use your own or comment this out\n    secretName: tls-wildcard-demo\n  rules:\n  - host: __CI_BUILD_REF_SLUG__-presentation-gitlab-k8s.edenmal.net\n    http:\n      paths:\n      - path: \u002F\n        backend:\n          serviceName: presentation-gitlab-k8s-__CI_BUILD_REF_SLUG__\n          servicePort: 8000\n",[567,25968,25969,25978,25987,25993,26001,26009,26015,26023,26029,26042,26055,26061,26068,26077,26084,26089,26094,26104,26111,26121,26128,26135,26147,26154,26163],{"__ignoreMap":743},[747,25970,25971,25973,25975],{"class":749,"line":750},[747,25972,12949],{"class":753},[747,25974,856],{"class":757},[747,25976,25977],{"class":802}," extensions\u002Fv1beta1\n",[747,25979,25980,25982,25984],{"class":749,"line":761},[747,25981,12963],{"class":753},[747,25983,856],{"class":757},[747,25985,25986],{"class":802}," Ingress\n",[747,25988,25989,25991],{"class":749,"line":769},[747,25990,12973],{"class":753},[747,25992,758],{"class":757},[747,25994,25995,25997,25999],{"class":749,"line":776},[747,25996,12980],{"class":753},[747,25998,856],{"class":757},[747,26000,25773],{"class":802},[747,26002,26003,26005,26007],{"class":749,"line":784},[747,26004,13231],{"class":753},[747,26006,856],{"class":757},[747,26008,22408],{"class":802},[747,26010,26011,26013],{"class":749,"line":790},[747,26012,25378],{"class":753},[747,26014,758],{"class":757},[747,26016,26017,26019,26021],{"class":749,"line":796},[747,26018,25385],{"class":753},[747,26020,856],{"class":757},[747,26022,25796],{"class":802},[747,26024,26025,26027],{"class":749,"line":806},[747,26026,25801],{"class":753},[747,26028,758],{"class":757},[747,26030,26031,26034,26036,26038,26040],{"class":749,"line":814},[747,26032,26033],{"class":753},"    kubernetes.io\u002Ftls-acme",[747,26035,856],{"class":757},[747,26037,969],{"class":757},[747,26039,5306],{"class":802},[747,26041,975],{"class":757},[747,26043,26044,26047,26049,26051,26053],{"class":749,"line":822},[747,26045,26046],{"class":753},"    kubernetes.io\u002Fingress.class",[747,26048,856],{"class":757},[747,26050,969],{"class":757},[747,26052,9530],{"class":802},[747,26054,975],{"class":757},[747,26056,26057,26059],{"class":749,"line":830},[747,26058,12990],{"class":753},[747,26060,758],{"class":757},[747,26062,26063,26066],{"class":749,"line":836},[747,26064,26065],{"class":753},"  tls",[747,26067,758],{"class":757},[747,26069,26070,26072,26075],{"class":749,"line":842},[747,26071,1721],{"class":757},[747,26073,26074],{"class":753}," hosts",[747,26076,758],{"class":757},[747,26078,26079,26081],{"class":749,"line":850},[747,26080,18665],{"class":757},[747,26082,26083],{"class":802}," __CI_BUILD_REF_SLUG__-presentation-gitlab-k8s.edenmal.net\n",[747,26085,26086],{"class":749,"line":863},[747,26087,26088],{"class":772},"    # the secret used here is an unsigned wildcard cert for demo purposes\n",[747,26090,26091],{"class":749,"line":869},[747,26092,26093],{"class":772},"    # use your own or comment this out\n",[747,26095,26096,26099,26101],{"class":749,"line":877},[747,26097,26098],{"class":753},"    secretName",[747,26100,856],{"class":757},[747,26102,26103],{"class":802}," tls-wildcard-demo\n",[747,26105,26106,26109],{"class":749,"line":1015},[747,26107,26108],{"class":753},"  rules",[747,26110,758],{"class":757},[747,26112,26113,26115,26117,26119],{"class":749,"line":1021},[747,26114,1721],{"class":757},[747,26116,4591],{"class":753},[747,26118,856],{"class":757},[747,26120,26083],{"class":802},[747,26122,26123,26126],{"class":749,"line":1027},[747,26124,26125],{"class":753},"    http",[747,26127,758],{"class":757},[747,26129,26130,26133],{"class":749,"line":1033},[747,26131,26132],{"class":753},"      paths",[747,26134,758],{"class":757},[747,26136,26137,26139,26142,26144],{"class":749,"line":1039},[747,26138,799],{"class":757},[747,26140,26141],{"class":753}," path",[747,26143,856],{"class":757},[747,26145,26146],{"class":802}," \u002F\n",[747,26148,26149,26152],{"class":749,"line":1054},[747,26150,26151],{"class":753},"        backend",[747,26153,758],{"class":757},[747,26155,26156,26159,26161],{"class":749,"line":1060},[747,26157,26158],{"class":753},"          serviceName",[747,26160,856],{"class":757},[747,26162,25773],{"class":802},[747,26164,26165,26168,26170],{"class":749,"line":1066},[747,26166,26167],{"class":753},"          servicePort",[747,26169,856],{"class":757},[747,26171,25586],{"class":1895},[523,26173,26174,25947,26176,26179,26180,26183,26184,8287,26186,587,26188,26190,26191,587,26194,26197],{},[567,26175,158],{},[527,26177,18226],{"href":18226,"rel":26178},[531],".\nTo be able to reach the domain names, you need to already have the DNS names created. With the current manifest you would need to create ",[567,26181,26182],{},"__CI_ENVIRONMENT_SLUG__-presentation-gitlab-k8s.example.com",", where ",[567,26185,25701],{},[567,26187,24007],{},[567,26189,24000],{},". Resulting in ",[567,26192,26193],{},"dev-presentation-gitlab-k8s.example.com",[567,26195,26196],{},"live-presentation-gitlab-k8s.example.com"," to be created by yourself.",[6072,26199,26200,26204],{},[523,26201,26202],{},[584,26203,6189],{},[523,26205,26206,26207,26212],{},"The deployment stage could be expanded to use a DNS providers API or even the ",[527,26208,26211],{"href":26209,"rel":26210},"https:\u002F\u002Fgithub.com\u002Fkubernetes-incubator\u002Fexternal-dns",[531],"kubernetes-incubator\u002Fexternal-dns Operator",", to create a new subdomain for each merge request. This would mean that each merge request would be reviewable under its own",[523,26214,26215],{},"Now that we have gone through all the manifests in the repository, we can move on to the next step.",[535,26217,26219],{"id":26218},"step-8-make-a-change-push-and-watch-the-magic-happen","Step 8 - Make a change, push and watch the magic happen!",[523,26221,26222,26223,26225],{},"Now that you have the manifests and the ",[567,26224,23716],{}," file in the repository or from the imported one, you can make a change to the code or just create a file by running the following commands:",[738,26227,26229],{"className":1621,"code":26228,"language":1623,"meta":743,"style":743},"$ touch test1\n$ git add test1\n$ git commit -m\"Testing the GitLab CI functionality #1\"\n$ git push\n",[567,26230,26231,26241,26252,26270],{"__ignoreMap":743},[747,26232,26233,26235,26238],{"class":749,"line":750},[747,26234,1919],{"class":1630},[747,26236,26237],{"class":802}," touch",[747,26239,26240],{"class":802}," test1\n",[747,26242,26243,26245,26247,26250],{"class":749,"line":761},[747,26244,1919],{"class":1630},[747,26246,22393],{"class":802},[747,26248,26249],{"class":802}," add",[747,26251,26240],{"class":802},[747,26253,26254,26256,26258,26261,26263,26265,26268],{"class":749,"line":769},[747,26255,1919],{"class":1630},[747,26257,22393],{"class":802},[747,26259,26260],{"class":802}," commit",[747,26262,3368],{"class":802},[747,26264,3892],{"class":757},[747,26266,26267],{"class":802},"Testing the GitLab CI functionality #1",[747,26269,975],{"class":757},[747,26271,26272,26274,26276],{"class":749,"line":776},[747,26273,1919],{"class":1630},[747,26275,22393],{"class":802},[747,26277,26278],{"class":802}," push\n",[523,26280,26281],{},"The commands create a new file, commit it and push the change to the repository on GitLab.",[523,26283,26284,26285,26287],{},"Now you should see GitLab creating a new pipeline for your change and start running through the stages, which you specified in the ",[567,26286,23716],{},", with their jobs.",[523,26289,26290],{},[3069,26291],{"alt":26292,"src":26293},"GitLab CI - Pipelines list","\u002Fblog\u002F2019\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature\u002Fgitlab-ci-pipelines-list.png",[523,26295,26296],{},[3069,26297],{"alt":26298,"src":26299},"GitLab CI - Commit Pipeline list view","\u002Fblog\u002F2019\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature\u002Fgitlab-ci-commit-pipeline-running.png",[523,26301,26302],{},"When you now go to the pipeline, you should see a view like this:",[523,26304,26305],{},[3069,26306],{"alt":26307,"src":26308},"GitLab CI - Running Pipeline Overview","\u002Fblog\u002F2019\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature\u002Fgitlab-ci-pipeline-view.png",[523,26310,26311,26312,26315],{},"The last stage shows if you did everything correct. If it passes you now have successfully deployed your application to your Kubernetes cluster.\nA successful stage ",[567,26313,26314],{},"review"," deploy looks like this:",[523,26317,26318],{},[3069,26319],{"alt":26320,"src":26321},"GitLab CI - Pipeline deploy_review job successful","\u002Fblog\u002F2019\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature\u002Fgitlab-ci-pipeline-deploy-review-successful.png",[523,26323,26324,26325,26327],{},"If any of the build\u002Fsteps fail for you, you may have misconfigured your ",[567,26326,23716],{}," or the GitLab CI Kubernetes integration can't reach the configured Kubernetes cluster. Make sure connectivity from the GitLab CI Runners to the Kubernetes cluster is given!\nFor Troubleshooting see the below section for more details on some possible issues.",[535,26329,207],{"id":26330},"troubleshooting",[613,26332,26334],{"id":26333},"pipeline-stuck-on-pending","Pipeline stuck on pending",[523,26336,26337],{},"If the build pipeline is stuck in pending, it could be that your GitLab CI runner aren't properly configured with your GitLab CI instance.",[613,26339,26341],{"id":26340},"build-failure","Build failure",[668,26343,26344,26350],{},[638,26345,26346,26347,26349],{},"If you made any changes to the ",[567,26348,23716],{},", use the \"CI Lint\" functionality available on the GitLab Repo pipeline page in the top right corner to check for any syntax issues.",[638,26351,26352,26353,26355],{},"Did you replace all domain names ",[567,26354,23746],{}," with your own domains?",[613,26357,26359],{"id":26358},"unable-to-reach-the-app-review-urldeployed-project","Unable to reach the app review URL\u002Fdeployed project",[668,26361,26362,26367],{},[638,26363,26352,26364,26366],{},[567,26365,23746],{}," with your own domains?\n*",[638,26368,26369,26370],{},"Is your Ingress controller configured to pickup your Ingress objects?\n",[668,26371,26372],{},[638,26373,26374],{},"Your DNS names correctly setup to point to the Ingress controller?",[535,26376,14526],{"id":14525},[523,26378,26379],{},"I hope this helps you, using the GitLab CI Kubernetes cluster feature for your Continuous Delivery of your application(s) to Kubernetes.\nFor questions about the post, please leave a comment below, thanks!",[523,26381,13967],{},[2890,26383,26384],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}",{"title":743,"searchDepth":761,"depth":761,"links":26386},[26387,26390,26391,26392,26394,26395,26396,26398,26399,26400,26401,26406],{"id":537,"depth":761,"text":538,"children":26388},[26389],{"id":22267,"depth":769,"text":22268},{"id":22332,"depth":761,"text":22333},{"id":22346,"depth":761,"text":22347},{"id":22465,"depth":761,"text":26393},"Step 2 - Get a ServiceAccount Token from Kubernetes",{"id":23316,"depth":761,"text":23317},{"id":23562,"depth":761,"text":23563},{"id":23712,"depth":761,"text":26397},"Step 5 - Add a .gitlab-ci.yml to your project",{"id":25160,"depth":761,"text":25161},{"id":25322,"depth":761,"text":25323},{"id":26218,"depth":761,"text":26219},{"id":26330,"depth":761,"text":207,"children":26402},[26403,26404,26405],{"id":26333,"depth":769,"text":26334},{"id":26340,"depth":769,"text":26341},{"id":26358,"depth":769,"text":26359},{"id":14525,"depth":761,"text":14526},"2019-06-10T14:53:20+02:00","This post shows possibilites on how to use GitLab in combination with Kubernetes to contionously deliver your applications with Container, using the new GitLab CI Kubernetes Cluster feature.",{"src":26410},"\u002Fblog\u002F2018\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature.png",{"tags":26412},[26413,26414,124,26415],"GitLab","Continuous Delivery","Container","\u002Fblog\u002F2019\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature",{"title":22234,"description":26408},"3.blog\u002F2019\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature","6CBjMYLDYVvQ6OZoWxo4f8BkyeMkVAHGdcgQZlThHj8",{"id":26421,"title":26422,"authors":26423,"badge":518,"body":26426,"date":26513,"description":26514,"extension":2911,"image":26515,"meta":26516,"navigation":1254,"path":26518,"seo":26519,"stem":26520,"__hash__":26521},"posts\u002F3.blog\u002F2019\u002Fcontainer-and-kubernetes-training.md","Container and Kubernetes Training",[26424],{"name":514,"to":515,"avatar":26425},{"src":517},{"type":520,"value":26427,"toc":26508},[26428,26432,26435,26439,26451,26453,26457,26460,26463,26470,26478,26480,26506],[535,26429,26431],{"id":26430},"welcome","Welcome!",[523,26433,26434],{},"Quick short introduction to myself, my name is Alexander Trost. I’m a sysadmin who loves automation, containers, coding in Go, playing games but also with new technologies.\nI'm currently working at Cloudical as a DevOps Engineer, helping companies move to the cloud and\u002F or to container technologies (e.g., Docker, Kubernetes, etc).",[535,26436,26438],{"id":26437},"goal-of-the-training","Goal of the Training",[523,26440,26441,26442,26446,26447,26450],{},"The training is going to show how simple it is to get started with containers. In this case ",[527,26443,12175],{"href":26444,"rel":26445},"https:\u002F\u002Fwww.docker.com\u002F",[531]," is used, as it is the most popular container toolchain and runtime right now.\nAfter getting to know containers and Docker, we will hopefully realize that there is a need for some kind of ",[3049,26448,26449],{},"magical"," orchestration layer to run applications and more in containers (in an orchestrated way). The important if you haven't noticed here is the orchestration of containers in an automated and orchestrated manner.",[2979,26452],{},[535,26454,26456],{"id":26455},"material-for-the-training","Material for the training",[523,26458,26459],{},"The material for the training has been taken \"offline\" to revise it but also due to the amount of time that is put into the whole of the material. I hope you understand!",[523,26461,26462],{},"Should you have attended the training and have not received the material in form of PDFs yet, please contact me by email, thanks!",[523,26464,26465,26466,2006],{},"(You can get my email address by using the email icon in the sidebar or the ",[527,26467,26469],{"href":26468},"\u002Fabout","About page",[523,26471,26472,26473,1909],{},"The repository with some example files remains public, see ",[527,26474,26477],{"href":26475,"rel":26476},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-container-docker-kubernetes",[531],"GitHub galexrt\u002Fworkshop-container-docker-kubernetes repository",[2979,26479],{},[523,26481,26482,26483,26488,26489,26494,26495,26500,26501,26505],{},"A thanks to ",[527,26484,26487],{"href":26485,"rel":26486},"https:\u002F\u002Ftwitter.com\u002Ffpfka",[531],"Felix Pfefferkorn (@fpfka)"," for asking me to hold this training at ",[527,26490,26493],{"href":26491,"rel":26492},"https:\u002F\u002Fffg.guug.de\u002F",[531],"GUUG-Frühjahrsfachgespräch 2019"," and being an awesome training officer (Ausbildungsleiter) at ",[527,26496,26499],{"href":26497,"rel":26498},"https:\u002F\u002Fjobs.1und1.de\u002F",[531],"1&1",".\nAnother thanks to ",[527,26502,26504],{"href":26491,"rel":26503},[531],"GUUG-Frühjahrsfachgespräch 2019 team"," for having me there for this trainings at their conference!",[523,26507,13967],{},{"title":743,"searchDepth":761,"depth":761,"links":26509},[26510,26511,26512],{"id":26430,"depth":761,"text":26431},{"id":26437,"depth":761,"text":26438},{"id":26455,"depth":761,"text":26456},"2019-03-26T22:20:06+01:00","Container und Kubernetes Training Material",{"src":12171},{"tags":26517},[12174,12175,124,26415],"\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training",{"title":26422,"description":26514},"3.blog\u002F2019\u002Fcontainer-and-kubernetes-training","z8ucEuBcNhudNo59b5IL7Ghm8uSWwxCnSNN-ea9PG18",{"id":26523,"title":26524,"authors":26525,"badge":518,"body":26528,"date":27582,"description":26514,"extension":2911,"image":27583,"meta":27585,"navigation":1254,"path":27587,"seo":27588,"stem":27589,"__hash__":27590},"posts\u002F3.blog\u002F2019\u002Fcontainer-and-kubernetes-training-day3.md","Container and Kubernetes - Day #3",[26526],{"name":514,"to":515,"avatar":26527},{"src":517},{"type":520,"value":26529,"toc":27564},[26530,26532,26534,26536,26541,26543,26547,26561,26563,26567,26575,26578,26584,26587,26591,26594,26598,26610,26618,26621,26630,26633,26640,26649,26660,26663,26668,26682,26685,26695,26698,26709,26712,26724,26730,26733,26744,26747,26790,26794,26805,26808,26811,26818,26829,26839,26842,26845,26856,26861,26864,26867,26880,26884,26887,26891,26909,26912,26915,26918,26921,26931,26942,26945,26969,26972,26974,26984,26999,27005,27012,27016,27019,27022,27025,27058,27061,27065,27068,27073,27082,27091,27132,27136,27144,27146,27150,27154,27160,27163,27166,27169,27200,27203,27212,27214,27220,27224,27227,27230,27238,27241,27245,27253,27256,27262,27268,27271,27289,27295,27297,27301,27304,27307,27310,27317,27323,27327,27334,27340,27344,27352,27358,27360,27364,27367,27376,27379,27382,27386,27389,27392,27396,27401,27404,27408,27412,27415,27455,27458,27462,27465,27480,27484,27487,27500,27543,27545,27549,27552,27559,27561],[535,26531,26431],{"id":26430},[523,26533,26434],{},[535,26535,26438],{"id":26437},[523,26537,26538,26539,26450],{},"The training is going to show how simple it is to get started with containers. In this case Docker is used, as it is the most popular container toolchain and runtime right now.\nAfter getting to know containers and Docker, we will hopefully realize that there is a need for some kind of ",[3049,26540,26449],{},[2979,26542],{},[535,26544,26546],{"id":26545},"goal-of-the-day","Goal of the day",[523,26548,26549,26550,714,26554,587,26558,1909],{},"Goal of the day is to look into Kubernetes itself by going over the architecture and components of a Kubernetes cluster. Besides that we will take a closer look at the configuration of kubelet and Kubernetes master components.\nThen we will go over operational topics, like ",[527,26551,26553],{"href":26552},"#monitoring","monitoring",[527,26555,26557],{"href":26556},"#logging","logging",[527,26559,11626],{"href":26560},"#storage",[2979,26562],{},[535,26564,26566],{"id":26565},"architecture-components","Architecture + Components",[523,26568,26569,26570,1909],{},"Information can also be found in a more compact format here: ",[527,26571,26574],{"href":26572,"rel":26573},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Foverview\u002Fcomponents\u002F",[531],"Kubernetes Components Overview - Kubernetes",[523,26576,26577],{},"Remember this Kubernetes cluster architecture diagram?",[523,26579,26580],{},[3069,26581],{"alt":26582,"src":26583},"Kubernetes Cluster architecture","\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day3\u002Fkubernetes-cluster-architecture.png",[523,26585,26586],{},"Now we go over each component in more detail.",[613,26588,26590],{"id":26589},"master-components","Master Components",[523,26592,26593],{},"Even though they are called \"Master Components\" this doesn't mean they all need to run on the masters. For some components, e.g., etcd, it is recommended to run them on separate servers for better performance.",[3126,26595,26597],{"id":26596},"etcd-the-brain","etcd - The brain",[6072,26599,26600],{},[523,26601,26602,8287,26605,1909],{},[584,26603,26604],{},"REFERENCE",[527,26606,26609],{"href":26607,"rel":26608},"https:\u002F\u002Fgithub.com\u002Fetcd-io\u002Fetcd",[531],"GitHub etcd-io\u002Fetcd",[523,26611,26612,26613,1909],{},"The etcd is the brain of a Kubernetes cluster. It is responsible for storing all the Kubernetes objects.\netcd in itself is a \"distributed reliable key-value store for most critical data of a distributed system\". It uses the Raft for the clustering and failover logic. In the etcd documentation there is a whole documentation about the mechanism they have and what you can do with it, see ",[527,26614,26617],{"href":26615,"rel":26616},"https:\u002F\u002Fetcd.readthedocs.io\u002Fen\u002Flatest\u002Fserver-learner.html",[531],"etcd documentation - \"Cluster Membership\" Learner",[523,26619,26620],{},"Kubernetes uses etcd v3 API since some time now, so you should hopefully not come across any Kubernetes clusters that still use etcd v2 API.",[6072,26622,26623,26627],{},[523,26624,26625],{},[584,26626,6189],{},[523,26628,26629],{},"Looking at the format in which Kubernetes stored objects with the etcd v2 API it is \"easier\" for humans to understand, but isn't as performant as the v3 API. Kubernetes stores data in protobuf format with etcd v3 API, enabling Kubernetes to be pretty fast with its objects.",[523,26631,26632],{},"Running etcd can be a b*tch, but unless you throw away the etcd data every 5 minutes because you want refresh servers all the time you should not have too many problems.",[6072,26634,26635],{},[523,26636,26637,26639],{},[584,26638,3103],{}," etcd is the data store of the Kubernetes objects. Can be a bottleneck of the Kubernetes cluster.",[523,26641,26642,26645,26646,26648],{},[567,26643,26644],{},"etcdctl"," is etcd's client tool which allows you to do certain tasks against an etcd cluster. With ",[567,26647,26644],{}," you can create, edit and delete keys (objects) and many more things, but you don't want to do that unless you what you do. If you would edit objects you'll can end up with Kubernetes being unable to decode objects and thus possibly causing the Kubernetes cluster to fail sooner or later.",[523,26650,26651,26652,1909],{},"Ironically I have wrote a documentation page about doing exactly that, \"safely\" editing Kubernetes objects in etcd, see ",[527,26653,26655,26656,26659],{"href":26654},"\u002Fdocs\u002Fkubernetes\u002Fetcd\u002Fediting-kubernetes-objects\u002F","Editing Kubernetes objects in ",[567,26657,26658],{},"etcd"," - Docs",[523,26661,26662],{},"From what people have told for bigger Kubernetes cluster installations (many nodes and\u002F or many many users), the etcd can be a bottleneck depending on the (virtual) hardware.\nTo quote such a post from memory:",[6072,26664,26665],{},[523,26666,26667],{},"\"etcd was getting slower and slower with more people using the cluster:",[668,26669,26670,26673,26676,26679],{},[638,26671,26672],{},"Checked the IO load on the Kubernetes master servers running etcd.",[638,26674,26675],{},"Moved etcd to dedicated servers.",[638,26677,26678],{},"Additionally put SSD or better under etcd data directory.",[638,26680,26681],{},"And bottleneck is gone!\"",[523,26683,26684],{},"If you want to read about more such bigger Kubernetes cluster scaling cases, just search for \"Scaling Kubernetes to a million users\"\u002F \"Issues scaling Kubernetes\".",[6072,26686,26687,26692],{},[523,26688,26689,26691],{},[584,26690,6189],{}," Most people will \"never\" run more than at max 100+ nodes per cluster.",[523,26693,26694],{},"Unless you are Google or have very ambitious plans like me :-D",[3126,26696,26697],{"id":26697},"kube-apiserver",[6072,26699,26700],{},[523,26701,26702,8287,26704,1909],{},[584,26703,26604],{},[527,26705,26708],{"href":26706,"rel":26707},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Freference\u002Fcommand-line-tools-reference\u002Fkube-apiserver\u002F",[531],"Kubernetes - kube-apiserver Reference",[523,26710,26711],{},"When etcd is the brain of the Kubernetes cluster, the kube-apiserver is the ingestion system for information\u002F obejcts so to speak of.\nThe kube-apiserver is the only component talking to the etcd directly, all other upcoming are always only talking to the kube-apiserver!",[6072,26713,26714,26718,26721],{},[523,26715,26716],{},[584,26717,6189],{},[523,26719,26720],{},"YES! All other components are talking through the kube-apiserver. The reason for that is simple, the kube-apiserver is the one instance that does authentication for users\u002F ServiceAccounts*, validation (+ admission controlling) of objects.",[523,26722,26723],{},"*ServiceAccounts = are as the name implies \"accounts\" for services\u002F robots, e.g., a token for your CI pipeline used for deployments to Kubernetes, controlled access for applications\u002F operators to the Kubernetes API.",[523,26725,26726,26727,26729],{},"Ever heard of fancy custom Kubernetes objects (CustomResourceDefinitions) like ",[567,26728,292],{},"? kube-apiserver takes care of registering their paths in its API.",[3126,26731,26732],{"id":26732},"kube-controller-manager",[6072,26734,26735],{},[523,26736,26737,8287,26739,1909],{},[584,26738,26604],{},[527,26740,26743],{"href":26741,"rel":26742},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Freference\u002Fcommand-line-tools-reference\u002Fkube-controller-manager\u002F",[531],"Kubernetes - kube-controller-manager Reference",[523,26745,26746],{},"kube-controller-manager is kind of the backbone as it uses the kube-apiserver to watch certain objects and the runs control loops to react on changes to them.\nExamples of those control loops:",[668,26748,26749,26771,26781,26787],{},[638,26750,26751,26753,26754,26756,26757,26759,26760,26763,26764,26767,26768,26770],{},[567,26752,25331],{}," object has its ",[567,26755,18111],{}," changed from ",[567,26758,18115],{}," to ",[567,26761,26762],{},"5",", the kube-controller-manager will then go ahead and update the current ",[567,26765,26766],{},"ReplicaSet"," for the ",[567,26769,25331],{}," and with that create the new Pods.",[638,26772,14231,26773,26776,26777,26780],{},[567,26774,26775],{},"Node"," has not been updated (keeped alive) by the server's kubelet since time n, kube-controller-manager will mark the node as ",[567,26778,26779],{},"NotReady"," and then after some additional time evict (delete) the Pods from the node so they are rescheduled.",[638,26782,26783,26784,26786],{},"Allocating IP CIDRs to each ",[567,26785,26775],{}," in the cluster (if enabled).",[638,26788,26789],{},"Many more jobs of keeping in control of what is going on in the Kubernetes cluster.",[3142,26791,26793],{"id":26792},"cloud-controller-manager-are-you-in-the-cloud","cloud-controller-manager - Are you in the cloud?",[6072,26795,26796],{},[523,26797,26798,8287,26800,1909],{},[584,26799,26604],{},[527,26801,26804],{"href":26802,"rel":26803},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Freference\u002Fcommand-line-tools-reference\u002Fcloud-controller-manager\u002F",[531],"Kubernetes - cloud-controller-manager Reference",[523,26806,26807],{},"Is like the kube-controller-manager, but for the cloud. It is talking with the underlying cloud provider to provide certain services of the cloud provider to Kubernetes.",[523,26809,26810],{},"To quote the documentation, as there isn't really a better way to say it:",[6072,26812,26813],{},[668,26814,26815],{},[638,26816,26817],{},"Node Controller: For checking the cloud provider to determine if a node has been deleted in the cloud after it stops responding",[668,26819,26820,26823,26826],{},[638,26821,26822],{},"Route Controller: For setting up routes in the underlying cloud infrastructure",[638,26824,26825],{},"Service Controller: For creating, updating and deleting cloud provider load balancers",[638,26827,26828],{},"Volume Controller: For creating, attaching, and mounting volumes, and interacting with the cloud provider to orchestrate volumes",[6072,26830,26831],{},[523,26832,26833,26834],{},"- ",[527,26835,26838],{"href":26836,"rel":26837},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Foverview\u002Fcomponents\u002F#cloud-controller-manager",[531],"Kubernetes Components Overview - cloud-controller-manager - Kubernetes",[523,26840,26841],{},"It is basically a cloud support for the kube-controller-manager.",[3126,26843,26844],{"id":26844},"kube-scheduler",[6072,26846,26847],{},[523,26848,26849,8287,26851,1909],{},[584,26850,26604],{},[527,26852,26855],{"href":26853,"rel":26854},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Freference\u002Fcommand-line-tools-reference\u002Fkube-scheduler\u002F",[531],"Kubernetes - kube-scheduler Reference",[523,26857,26858],{},[3049,26859,26860],{},"*hoping that the name makes it obvious to what the kube-scheduler does*",[523,26862,26863],{},"Well.. the kube-scheduler schedules Pods in the Kubernetes cluster.\nThe kube-scheduler doesn't just throw dice but will also take available resources on the Nodes, \"placement\" options (Pod- and Node Affinity\u002F AntiAffinity, Taints and Tolerations) and even if supported by the used storage the \"location\" of PersistentVolumes into account to find the best place for each Pod.",[523,26865,26866],{},"It doesn't do more but it also doesn't do less than that.",[6072,26868,26869,26873],{},[523,26870,26871],{},[584,26872,6189],{},[523,26874,26875,26876,26879],{},"One thing that I want to note, but wouldn't recommend unless you know what you are doing. You can tell objects, like Deployments, StatefulSets and so on, which scheduler to use (",[567,26877,26878],{},"schedulerName"," field). This means that you can run your own schedulers to assign Pods to Nodes on your own custom logic.",[613,26881,26883],{"id":26882},"node-components","Node Components",[523,26885,26886],{},"This section is about all the components needed for a server to be a function Node in a Kubernetes cluster.",[3126,26888,26890],{"id":26889},"container-runtime-interface","Container Runtime Interface",[523,26892,26893,26894,714,26899,26903,26904,1909],{},"The Container Runtime Interface is an unified interface to talk to a Container Runtime (e.g., ",[527,26895,26898],{"href":26896,"rel":26897},"https:\u002F\u002Fgithub.com\u002Fcontainerd\u002Fcontainerd",[531],"containerd",[527,26900,401],{"href":26901,"rel":26902},"https:\u002F\u002Fcri-o.io",[531],"), for more insight on Kubernetes side, see ",[527,26905,26908],{"href":26906,"rel":26907},"https:\u002F\u002Fkubernetes.io\u002Fblog\u002F2016\u002F12\u002Fcontainer-runtime-interface-cri-in-kubernetes\u002F",[531],"Kubernetes Blog - Introducing Container Runtime Interface (CRI) in Kubernetes",[523,26910,26911],{},"Docker is also a Container Runtime that Kubernetes supports it, but right now this integration is directly through Docker (\u002F Moby) libraries instead of one unified interface which works for all container runtimes.",[523,26913,26914],{},"The point of different Container runtimes is, e.g., that Kata Containers is able to run containers in lightweight VMs to give (untrusted) workload more isolation.",[523,26916,26917],{},"It is needed on every Node that will run Pods in the end. Depending on how the Kubernetes cluster is installed, e.g., with kubeadm, all servers including the master servers can run containers (master servers are \"restricted\" (tainted) by default).",[3126,26919,26920],{"id":26920},"kubelet",[6072,26922,26923],{},[523,26924,26925,8287,26927,1909],{},[584,26926,26604],{},[527,26928,26708],{"href":26929,"rel":26930},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Freference\u002Fcommand-line-tools-reference\u002Fkubelet\u002F",[531],[523,26932,26933,26934,26938,26939,3052],{},"Besides the ",[527,26935,26937],{"href":26936},"#container-runtime-interface","Container Runtime of your choice",", the kubelet is the most important component on the Nodes (followed by the ",[527,26940,12748],{"href":26941},"#kube-proxy",[523,26943,26944],{},"The kubelet is the one and only component which is talking with the container runtime to create and run containers for a Pod.\nFor example the kubelet takes care of following tasks:",[668,26946,26947,26950,26953],{},[638,26948,26949],{},"Creating the containers with their shared (network) contexts.",[638,26951,26952],{},"Depending on the storage used, mounts and if needed formats the volumes for each Pod.",[638,26954,26955,26956],{},"Besides PersistentVolumes mounting, it will also create the necessary volumes for ConfigMaps and Secrets.\n",[668,26957,26958],{},[638,26959,26960,26961,26964,26965,26968],{},"E.g., when using ",[567,26962,26963],{},"emptyDir"," is used with ",[567,26966,26967],{},"medium: memory"," it takes care of creating the in-memory directory.",[523,26970,26971],{},"Besides that for the storage aspect it will talk with the \"installed\" CSI (\u002F FlexVolume) drivers to get the storage mounted.",[3126,26973,12748],{"id":12748},[6072,26975,26976],{},[523,26977,26978,8287,26980,1909],{},[584,26979,26604],{},[527,26981,26708],{"href":26982,"rel":26983},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Freference\u002Fcommand-line-tools-reference\u002Fkube-proxy\u002F",[531],[523,26985,26986,26987,26990,26991,26994,26995,26998],{},"You have heard about ",[567,26988,26989],{},"Services"," in Kubernetes? They have those cool ",[567,26992,26993],{},"ClusterIP","s. The kube-proxy is the one that is setting up ipvs and iptables rules (depending on the \"mode\" chosen) so the Service ",[567,26996,26997],{},"ClusterIPs"," are reachable.",[523,27000,27001],{},[3069,27002],{"alt":27003,"src":27004},"Kubernetes - Service IP iptables Diagram","\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day3\u002Fkubernetes-networking-explained-service-ip-iptables-flow.svg",[523,27006,27007,27008,2006],{},"(Originally taken from ",[527,27009,27011],{"href":27010},"\u002Fdocs\u002Fkubernetes\u002Fnetworking\u002Fexplained\u002F#service-ip-iptables","Kubernetes Network Explained - Service IP iptables - Docs",[3126,27013,27015],{"id":27014},"cni-sdn","CNI\u002F SDN",[523,27017,27018],{},"This was mostly covered in the previous Network section, but to summarize:",[523,27020,27021],{},"It takes care of the network for the Pods started by the kubelet.\nIn most times the CNI will create a overlay network in \"mesh network between all Nodes\" style.",[523,27023,27024],{},"To name some CNIs:",[668,27026,27027,27035,27049],{},[638,27028,27029,27034],{},[527,27030,27033],{"href":27031,"rel":27032},"https:\u002F\u002Fgithub.com\u002Fcoreos\u002Fflannel",[531],"CoreOS Flannel",": VXLAN Mesh network between the servers. The simplest network plugin that can span over more than one node.",[638,27036,27037,27042,27043,27048],{},[527,27038,27041],{"href":27039,"rel":27040},"https:\u002F\u002Fwww.projectcalico.org\u002F",[531],"Project Calico",": Either BGP + IP-IP or in form of ",[527,27044,27047],{"href":27045,"rel":27046},"https:\u002F\u002Fdocs.projectcalico.org\u002Flatest\u002Fgetting-started\u002Fkubernetes\u002Finstallation\u002Fflannel",[531],"Canal"," using Flannel for the traffic between the nodes.",[638,27050,27051,27052,27057],{},"And many more ",[527,27053,27056],{"href":27054,"rel":27055},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fcluster-administration\u002Fnetworking\u002F",[531],"Kubernetes - Cluster Networking"," ...",[523,27059,27060],{},"Most CNIs are deployed through a DaemonSet that then runs the CNI in a container, which makes it easier to update and maintain.",[613,27062,27064],{"id":27063},"addons","Addons",[3126,27066,377],{"id":27067},"dns",[6072,27069,27070],{},[523,27071,27072],{},"\"Isn't the problem always either network, DNS or both?\"",[523,27074,27075,27076,27078,27079,27081],{},"A Kubernetes cluster relies heavily on DNS. This is because Kubernetes itself provides service discovery through the ",[567,27077,26989],{}," which get a DNS name. Reason for that is that if running in another cluster the ",[567,27080,25729],{}," ClusterIP could be different for whatever reason (e.g., different network ranges used).",[523,27083,27084,27085,27090],{},"This addon is most of the time running inside of Kubernetes. The DNS server used is ",[527,27086,27089],{"href":27087,"rel":27088},"https:\u002F\u002Fcoredns.io\u002F",[531],"CoreDNS",", which is \"CoreDNS is a DNS server that chains plugins\".\nShould you run into performance issues with the DNS inside a Kubernetes cluster consider the following:",[668,27092,27093,27108],{},[638,27094,27095,27096],{},"Slow external name resolution?\n",[668,27097,27098],{},[638,27099,27100,27101,27104,27105,27107],{},"=> Check what upstream DNS servers are used in the CoreDNS configuration (",[567,27102,27103],{},"coredns"," ConfigMap in ",[567,27106,2101],{}," namespace).",[638,27109,27110,27111],{},"Getting weird DNS timeouts of >= 5 seconds?\n",[668,27112,27113],{},[638,27114,27115,27116],{},"=> See the following sources for information:\n",[668,27117,27118,27125],{},[638,27119,27120],{},[527,27121,27124],{"href":27122,"rel":27123},"https:\u002F\u002Ftech.xing.com\u002Fa-reason-for-unexplained-connection-timeouts-on-kubernetes-docker-abd041cf7e02",[531],"A reason for unexplained connection timeouts on Kubernetes\u002FDocker by Maxime Lagresle - Xing Engineering blog",[638,27126,27127],{},[527,27128,27131],{"href":27129,"rel":27130},"https:\u002F\u002Fgithub.com\u002Fkubernetes\u002Fkubernetes\u002Fissues\u002F56903",[531],"GitHub kubernetes\u002Fkubernetes - Issue: DNS intermittent delays of 5s #56903",[3126,27133,27135],{"id":27134},"monitoring-logging-and-more","Monitoring, Logging and more",[523,27137,27138,27139,27143],{},"These components\u002F parts will be covered in the ",[527,27140,27142],{"href":27141},"#operating-a-kubernetes-cluster","Operating a Kubernetes cluster"," section.",[2979,27145],{},[535,27147,27149],{"id":27148},"operating-a-kubernetes-cluster","Operating a Kubernetes Cluster",[613,27151,27153],{"id":27152},"what-is-an-operator-making-your-life-easier","What is an Operator? Making your life easier.",[523,27155,27156],{},[3069,27157],{"alt":27158,"src":27159},"Jeopardy - Kubernetes 'What is an Operator' question","\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day3\u002Fjeopardy-kubernetes-operator-automation-question.png",[523,27161,27162],{},"An Operator is a pattern in Kubernetes. What are you doing when running and taking care of an application? You are operating the application.\nCan you guess what an Operator (pattern) is doing in Kubernetes then?",[523,27164,27165],{},"An Operator takes care of running the application. You, the user, are just creating a custom object in Kubernetes, which has been defined by the operator creator. Based on that the operator reacts and, e.g., for Rook.io is creating each component of a Ceph cluster in Kubernetes through normal Deployment, StatefulSets and other objects.",[523,27167,27168],{},"Examples for operators:",[668,27170,27171,27178,27185,27192],{},[638,27172,27173,27177],{},[527,27174,27176],{"href":13751,"rel":27175},[531],"Rook.io operators"," - Run a whole Ceph cluster in Kubernetes, EdgeFS, NFS and more in Kubernetes with ease.",[638,27179,27180,27184],{},[527,27181,27183],{"href":25935,"rel":27182},[531],"CoreOS prometheus-operator"," - Run and configure Prometheus easily through custom objects in Kubernetes.",[638,27186,27187,27191],{},[527,27188,27190],{"href":18295,"rel":27189},[531],"Zalando postgres-operator"," - Run Postgres Clusters in Kubernetes.",[638,27193,27194,27195,1909],{},"For more cool operators, checkout the ",[527,27196,27199],{"href":27197,"rel":27198},"https:\u002F\u002Foperatorhub.io\u002F",[531],"OperatorHub",[523,27201,27202],{},"These operators allow admins and developers to reduce the time spent on getting things to run\u002F running applications in Kubernetes.",[6072,27204,27205,27209],{},[523,27206,27207],{},[584,27208,6189],{},[523,27210,27211],{},"This doesn't mean that you, the user doesn't need to know how to run, tune, maintain these applications. Operators are just automation and in the \"worst\" case manual intervention is the only help to fix bad issues unresolveable by automation.",[613,27213,176],{"id":26553},[523,27215,27216,27217,1909],{},"Before going into the actual components, like Prometheus and Grafana that are used for monitoring, let's talk about how you can get \"agents\"\u002F exporters on the servers to get, e.g., metrics, logs and other useful stuff. The way to do that achieve that are ",[567,27218,27219],{},"DaemonSets",[3126,27221,27223],{"id":27222},"daemonset","DaemonSet",[523,27225,27226],{},"A DaemonSet is a way to run a Pod on any Node in the Kubernetes cluster.",[523,27228,27229],{},"Pods created through a DaemonSet are scheduled partially by the so called DaemonSet controller but also through the default scheduler since Kubernetes v1.12.\nMeaning that you can specify certain placement options, like NodeAffinity, every Node in the Kubernetes cluster will get a Pod of a DaemonSet scheduled on it.",[523,27231,27232,27233,1909],{},"For more information on how DaemonSet Pods are scheduled, see ",[527,27234,27237],{"href":27235,"rel":27236},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fworkloads\u002Fcontrollers\u002Fdaemonset\u002F#how-daemon-pods-are-scheduled",[531],"Kubernetes - DaemonSet - How Daemon Pods are Scheduled",[523,27239,27240],{},"This is perfect for, e.g., deployment of CNI plugin (Flannel, etc) and for monitoring, but also logging such an \"agent\"\u002F exporter  can be deployed easily.",[3126,27242,27244],{"id":27243},"grafana","Grafana",[523,27246,27247,27248,27252],{},"Haven't heard about ",[527,27249,27244],{"href":27250,"rel":27251},"https:\u002F\u002Fgrafana.com",[531]," yet? You're in for a treat.",[523,27254,27255],{},"Grafana is the \"best\" tool for visualizing metrics.",[523,27257,27258],{},[3069,27259],{"alt":27260,"src":27261},"Grafana Dashboard - Kubernetes Cluster Resources","\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day3\u002Fgrafana-dashboard-k8s-resources.png",[523,27263,27264],{},[3069,27265],{"alt":27266,"src":27267},"Grafana Dashboard - Ceph Cluster Overview","\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day3\u002Fgrafana-dashboard-ceph-cluster.png",[3126,27269,292],{"id":27270},"prometheus",[523,27272,27273,27277,27278,714,27283,27288],{},[527,27274,292],{"href":27275,"rel":27276},"https:\u002F\u002Fprometheus.io\u002F",[531]," is the best cloud native for monitoring. Thanks to it, ",[527,27279,27282],{"href":27280,"rel":27281},"https:\u002F\u002Fopenmetrics.io\u002F",[531],"OpenMetrics",[527,27284,27287],{"href":27285,"rel":27286},"https:\u002F\u002Fopencensus.io",[531],"OpenCensus"," and many other projects have been sparked which allow to collect metrics and also do other things such as collecting traces.\nPrometheus itself is only for metrics though.",[523,27290,27291,27292,27294],{},"Big differences to most other monitoring systems is that the Prometheus server is pulling metrics from ",[567,27293,25856],{}," (or other paths) endpoints. Another difference is that there is no high availability concept in point of sharing the data bwtween one or more instances.\nIf you want HA, for Prometheus you just run more than one instance and use, e.g., remote storage which writes to InfluxDB or other time serires databases for the data high availability aspect.",[613,27296,166],{"id":26557},[3126,27298,27300],{"id":27299},"who-needs-logs-anyway-am-i-right","Who needs logs anyway, am I right?",[523,27302,27303],{},"Logs are always a problem in the new cool container world.",[523,27305,27306],{},"The one application logs too much",[3126,27308,284],{"id":27309},"loki",[523,27311,27312,27316],{},[527,27313,284],{"href":27314,"rel":27315},"https:\u002F\u002Fgrafana.com\u002Floki",[531]," \"Prometheus-inspired logging for cloud natives.\"",[523,27318,27319,27320,1909],{},"An alternative to Elasticsearch, from the makers of ",[527,27321,27244],{"href":27322},"#grafana",[3126,27324,27326],{"id":27325},"kibana","Kibana",[523,27328,27329,27333],{},[527,27330,27326],{"href":27331,"rel":27332},"https:\u002F\u002Fwww.elastic.co\u002Fproducts\u002Fkibana",[531]," is made by the guys a tool which is especially good for looking at logs is Kibana. Grafana can also display logs, but Kibana is better in that regard through their simple search interface.\nSadly in Kibana I personally think the visualizations are not as good as in Grafana.",[523,27335,27336],{},[3069,27337],{"alt":27338,"src":27339},"Kibana Home Site","\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day3\u002Fkibana-home-site.png",[3126,27341,27343],{"id":27342},"storing-logs","Storing Logs",[668,27345,27346,27349],{},[638,27347,27348],{},"EFK (Elasticsearch + Fluentd + Kibana)",[638,27350,27351],{},"ELK (Elasticsearch + Logstash + Kibana)",[523,27353,27354,27355,1909],{},"There aren't really alternatives besides ",[527,27356,284],{"href":27357},"#loki",[613,27359,421],{"id":11626},[3126,27361,27363],{"id":27362},"local-storage","Local Storage",[523,27365,27366],{},"Is a feature to allow you to provide applications with storage from the nodes themselves for better performance.",[6072,27368,27369,27373],{},[523,27370,27371],{},[584,27372,15250],{},[523,27374,27375],{},"The storage is not replicated in any way as it is local on the Node!",[523,27377,27378],{},"Example: A Pod using Local Storage from Node A, will always be \"forced\" to run on Node A. Only when the user manually intervens the Pod would be \"moved\" to another Local Storage PersistentVolume.",[523,27380,27381],{},"This must be kept in mind when using Local Storage and already during planning.",[3126,27383,27385],{"id":27384},"container-storage-interface-csi-in-memory-of-flexvolume","Container Storage Interface (CSI) - In memory of FlexVolume",[523,27387,27388],{},"CSI allows storage providers to easily provide their storage to any software\u002F platform through the CSI standard.",[523,27390,27391],{},"This is especially good for Kubernetes as this allows bugs in volume providers\u002F drivers to be fixed faster, than if they would be in-tree in Kubernetes (in the Kubernetes code).",[3126,27393,27395],{"id":27394},"rookio-ftw","Rook.io FTW!?",[523,27397,27398],{},[527,27399,14601],{"href":13751,"rel":27400},[531],[523,27402,27403],{},"Rook can run storage providers for you through operators, e.g., Cassandra, Ceph, CockroachDB, EdgeFS, Minio, NFS and YugabyteDB.",[613,27405,27407],{"id":27406},"maintenance-tasks","Maintenance Tasks",[3126,27409,27411],{"id":27410},"upgrading-a-cluster-order","Upgrading a Cluster (Order)",[523,27413,27414],{},"Any pre-upgrade processes documented\u002F communicated must be applied before upgrading components.",[668,27416,27417,27442],{},[638,27418,27419,27420],{},"Master Components\n",[668,27421,27422,27426,27438],{},[638,27423,27424],{},[567,27425,26697],{},[638,27427,27428,27430],{},[567,27429,26732],{},[668,27431,27432],{},[638,27433,27434,27435,1909],{},"If used, ",[567,27436,27437],{},"cloud-controller-manager",[638,27439,27440],{},[567,27441,26844],{},[638,27443,27444,27445],{},"Node Components\n",[668,27446,27447,27451],{},[638,27448,27449],{},[567,27450,26920],{},[638,27452,27453],{},[567,27454,12748],{},[523,27456,27457],{},"After that other components, like, e.g., CNI plugin, Monitoring, Operators.",[3142,27459,27461],{"id":27460},"cordon-bleu-my-nodes","Cordon (Bleu) my Nodes",[523,27463,27464],{},"Cordoning a Node makes it unschedulable (bleed out as no new Pods are scheduled on it then).",[738,27466,27468],{"className":1621,"code":27467,"language":1623,"meta":743,"style":743},"kubectl cordon NODE_NAME\n",[567,27469,27470],{"__ignoreMap":743},[747,27471,27472,27474,27477],{"class":749,"line":750},[747,27473,15269],{"class":1630},[747,27475,27476],{"class":802}," cordon",[747,27478,27479],{"class":802}," NODE_NAME\n",[3142,27481,27483],{"id":27482},"drain-a-node","Drain a Node",[523,27485,27486],{},"Draining a Node removes each Pod from a Node and marks it as cordoned (unschedulable). This is useful when, e.g., wanting to maintenance to a Node.",[6072,27488,27489,27493],{},[523,27490,27491],{},[584,27492,6189],{},[523,27494,27495,27496,27499],{},"Be aware though that if users run applications in Kubernetes with ",[567,27497,27498],{},"replicas: 1"," they will have a service intrruption, due to Pods bein terminated and created on another Node.",[738,27501,27503],{"className":1621,"code":27502,"language":1623,"meta":743,"style":743},"kubectl drain NODE_NAME\nkubectl drain --ignore-daemonsets=true NODE_NAME\nkubectl drain --ignore-daemonsets=true --delete-local-data=true NODE_NAME\n# I would recommend adding the `--timeout=0s` flag with a decent timeout time\n",[567,27504,27505,27514,27525,27538],{"__ignoreMap":743},[747,27506,27507,27509,27512],{"class":749,"line":750},[747,27508,15269],{"class":1630},[747,27510,27511],{"class":802}," drain",[747,27513,27479],{"class":802},[747,27515,27516,27518,27520,27523],{"class":749,"line":761},[747,27517,15269],{"class":1630},[747,27519,27511],{"class":802},[747,27521,27522],{"class":802}," --ignore-daemonsets=true",[747,27524,27479],{"class":802},[747,27526,27527,27529,27531,27533,27536],{"class":749,"line":769},[747,27528,15269],{"class":1630},[747,27530,27511],{"class":802},[747,27532,27522],{"class":802},[747,27534,27535],{"class":802}," --delete-local-data=true",[747,27537,27479],{"class":802},[747,27539,27540],{"class":749,"line":776},[747,27541,27542],{"class":772},"# I would recommend adding the `--timeout=0s` flag with a decent timeout time\n",[2979,27544],{},[535,27546,27548],{"id":27547},"summary-of-the-day","Summary of the Day",[523,27550,27551],{},"If you are reading this, you have made it to the end of day #2. Well done, sir or madam, have a second cookie!",[523,27553,27554,27555,1909],{},"I hope everyone had a good time during the training's first day and has taken new knowledge with them already.\nIf you have any feedback about the training itself or the materials, please let me know in person or email me at ",[527,27556,27558],{"href":27557},"mailto:me@galexrt.moe","me AT galexrt DOT moe",[523,27560,13967],{},[2890,27562,27563],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":743,"searchDepth":761,"depth":761,"links":27565},[27566,27567,27568,27569,27574,27581],{"id":26430,"depth":761,"text":26431},{"id":26437,"depth":761,"text":26438},{"id":26545,"depth":761,"text":26546},{"id":26565,"depth":761,"text":26566,"children":27570},[27571,27572,27573],{"id":26589,"depth":769,"text":26590},{"id":26882,"depth":769,"text":26883},{"id":27063,"depth":769,"text":27064},{"id":27148,"depth":761,"text":27149,"children":27575},[27576,27577,27578,27579,27580],{"id":27152,"depth":769,"text":27153},{"id":26553,"depth":769,"text":176},{"id":26557,"depth":769,"text":166},{"id":11626,"depth":769,"text":421},{"id":27406,"depth":769,"text":27407},{"id":27547,"depth":761,"text":27548},"2019-03-26T21:27:06+01:00",{"src":27584},"\u002Fblog\u002Fcovers\u002Fkubernetes-logo-with-bg.png",{"tags":27586},[12174,12175,124,26415],"\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day3",{"title":26524,"description":26514},"3.blog\u002F2019\u002Fcontainer-and-kubernetes-training-day3","RIJNdJIf8buFDjsw1A8kkKrit69LVfg0uCpuNK3qO_Q",{"id":27592,"title":27593,"authors":27594,"badge":518,"body":27597,"date":39256,"description":26514,"extension":2911,"image":39257,"meta":39258,"navigation":1254,"path":39260,"seo":39261,"stem":39262,"__hash__":39263},"posts\u002F3.blog\u002F2019\u002Fcontainer-and-kubernetes-training-day2.md","Container and Kubernetes - Day #2",[27595],{"name":514,"to":515,"avatar":27596},{"src":517},{"type":520,"value":27598,"toc":39192},[27599,27601,27603,27605,27609,27611,27613,27622,27624,27628,27634,27637,27670,27673,27676,27679,27682,27685,27687,27701,27719,27722,27725,27727,27732,27736,27740,27743,27746,27749,27753,27763,27766,27789,27793,27840,27848,27854,27858,27862,27865,27868,27976,27988,28003,28006,28010,28013,28042,28046,28049,28057,28059,28066,28078,28097,28100,28103,28105,28109,28112,28116,28121,28137,28145,28147,28153,28260,28263,28265,28269,28271,28286,28618,28621,28627,28630,28639,28661,28672,28676,28686,28696,28740,28755,28769,29667,29681,29684,29713,29717,29730,29739,29887,29890,29893,29928,29934,29938,29988,29994,29999,30004,30016,30022,30101,30111,30113,30126,30142,30151,30155,30161,30164,30167,30173,30240,30243,30253,30257,30264,30287,30296,30305,30351,30367,30594,30604,30609,30615,30653,30656,30671,30675,30688,30759,30769,30791,30796,30829,30843,30961,30975,30980,30985,30999,31009,31088,31094,31103,31111,31133,31613,31631,31644,31647,31651,31661,31682,31695,31700,31827,31839,31912,31921,31924,31942,31947,31957,31965,31970,31996,32012,32017,32032,32040,32046,32071,32076,32082,32093,32104,32110,32119,32126,32160,32164,32169,32183,32195,32208,32213,32324,32327,32346,32419,32443,32463,32472,32505,32511,32792,32798,32887,32902,32910,33054,33060,33063,33066,33077,33090,33096,33102,33107,33118,33130,33134,33147,33155,33179,33185,33229,33232,33259,33265,33271,33644,33647,33650,33654,33664,33667,33720,33729,33732,33785,33788,33792,33801,33814,33817,33821,33835,33840,34293,34300,34309,34482,34499,34507,34519,34525,34945,34954,34961,34963,34967,34970,34978,34984,34987,34991,35004,35006,35009,35012,35014,35018,35023,35026,35046,35049,35055,35061,35072,35078,35116,35124,35131,35134,35184,35188,35192,35197,35200,35204,35207,35223,35229,35242,35262,35265,35331,35334,35337,35371,35377,35396,35456,35472,35477,35481,35502,35508,36786,36792,36843,36849,36858,36861,36901,36908,36914,36970,36981,37102,37108,37114,37123,37134,37204,37210,37223,37227,37230,37238,37259,37312,37321,37339,37343,37346,37385,37390,37472,37476,37489,37499,37593,37603,37619,37628,37650,37653,37751,37758,37762,37775,37781,37790,37796,37799,37818,37824,37848,37850,37854,37857,37870,37872,37908,37912,37915,37918,37931,37935,37941,37944,37964,37970,37975,37995,38005,38015,38017,38020,38023,38026,38028,38032,38037,38041,38052,38066,38069,38158,38164,38202,38251,38257,38286,38292,38294,38298,38305,38307,38317,38324,38326,38332,38334,38347,38354,38357,38364,38379,38386,38389,38396,38406,38416,38429,38432,38435,38438,38441,38444,38450,38453,38456,38460,38477,38481,38487,38489,38496,38500,38506,38511,38515,38518,38536,38572,38576,38586,38592,38595,38599,38602,38627,38666,38670,38677,38681,38706,38728,38735,38781,38816,38820,38827,38843,38862,38867,38886,38912,38916,38925,38949,38986,38995,38999,39008,39029,39058,39066,39070,39074,39080,39098,39121,39125,39131,39150,39177,39179,39181,39183,39187,39189],[535,27600,26431],{"id":26430},[523,27602,26434],{},[535,27604,26438],{"id":26437},[523,27606,26538,27607,26450],{},[3049,27608,26449],{},[2979,27610],{},[535,27612,26546],{"id":26545},[523,27614,27615,27616,27618,27619,27621],{},"Goal of the day is to setup a Kubernetes cluster using the official Kubernetes tool ",[567,27617,162],{}," and deploy an example application consisting of multiple applications (application, database, cache, etc).\nIn the process of setting up the Kubernetes cluster with ",[567,27620,162],{},", we will look at the architecture of a Kubernetes cluster. This will show how Kubernetes does the container orchestration and what additional features it brings. After that everyone should have a basic understanding what is needed to run a Kubernetes cluster and how to deploy an application to it.",[2979,27623],{},[535,27625,27627],{"id":27626},"container-orchestration-tools","Container Orchestration Tools",[6072,27629,27630],{},[523,27631,27632],{},[3049,27633,11676],{},[523,27635,27636],{},"There are many container orchestration tools available, to name a few here is a list:",[668,27638,27639,27645,27650,27656,27663,27668],{},[638,27640,27641],{},[527,27642,2976],{"href":27643,"rel":27644},"https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Fswarm\u002F",[531],[638,27646,27647],{},[527,27648,11722],{"href":11720,"rel":27649},[531],[638,27651,27652],{},[527,27653,11735],{"href":27654,"rel":27655},"https:\u002F\u002Francher.com\u002F",[531],[638,27657,27658],{},[527,27659,27662],{"href":27660,"rel":27661},"https:\u002F\u002Fportainer.io\u002F",[531],"Portainer by Portainer Team",[638,27664,27665],{},[527,27666,11728],{"href":3037,"rel":27667},[531],[638,27669,11745],{},[523,27671,27672],{},"There are a lot of tools available to orchestrate containers with. Problem is with so many tools available, to find the one that fits your use case.",[523,27674,27675],{},"As you kind of have potentially already decided, in this training we will go over Kubernetes.",[523,27677,27678],{},"For me personally the reason is that",[613,27680,27681],{"id":11679},"A wild Docker Swarm appeared. Kubernetes used rolling update. It was very effective.",[523,27683,27684],{},"*Insert Pokemon battle between Docker Swarm and Kubernetes here*",[523,27686,11683],{},[668,27688,27689,27692,27695,27698],{},[638,27690,27691],{},"What workloads are you going to handle? How many containers would you run? What features do you need from the platform for your application to run smoothly?",[638,27693,27694],{},"Where do you want to run your workload? In the cloud? On premise?",[638,27696,27697],{},"What are your security requirements?",[638,27699,27700],{},"What integration possibilites does the orchestration tool offer? E.g., Istio - Service Mesh Proxy\u002F Routing.",[523,27702,27703,27704,587,27707,27710,27711,27714,27715,27718],{},"My choice when I initially got into the container orchestration topic were ",[527,27705,2976],{"href":27643,"rel":27706},[531],[527,27708,11722],{"href":11720,"rel":27709},[531],". After \"playing around\" with both, I concluded for me that ",[527,27712,2976],{"href":27643,"rel":27713},[531]," was not mature enough from itself and the ecosystem around it, ",[527,27716,11722],{"href":11720,"rel":27717},[531]," on the other hand was interesting to play around with, but after I have tried out Kubernetes it just felt \"better.\nSome of the other reasons for me to use Kubernetes are and were that if you know what you are doing it is pretty easy to use with the right tools, developed by Google who have long experience with containers (from what they tell they are also one of the longest and largest users of containers) and, I know weird point for someone running Kubernetes privately, but Kubernetes can scale up to 5000 nodes (version v1.14). Most users will never reach this amount of nodes but still it is good to know it could and it would if you should ever have the need for so many nodes.",[523,27720,27721],{},"If the ecosystem\u002F community around a software project is very important for you, I can safely say that Kubernetes is there. \"Most important\" is also that not only individuals are working on Kubernetes, but also many many companies come together to work on Kubernetes the project itself and the ecosystem around it.",[523,27723,27724],{},"There are probably more reasons to like and\u002F or dislike Kubernetes, but that is up to you now!\nI hope you can form yourself a good opinion on Kubernetes, even though a very much opinioated person is holding the workshop. ;-)",[535,27726,124],{"id":1317},[523,27728,27729],{},[3069,27730],{"alt":27731,"src":27584},"Kubernetes Logo",[613,27733,27735],{"id":27734},"so-what-has-kubernetes-to-offer-features-of-kubernetes","So what has Kubernetes to offer? - Features of Kubernetes",[3126,27737,27739],{"id":27738},"kubernetes-is-a-framework-paint-your-picture-in","Kubernetes is a framework - Paint your picture in!",[523,27741,27742],{},"Kubernetes is \"just\" a framework. It gives you basic abilities to run containres, make them available to the outside, make storage available for your application and more.",[523,27744,27745],{},"But even Kubernetes features have an \"end\". For this Kubernetes has many abilities to allow extending the Kubernetes API to for example add custom objects.\nExample: A \"Project\" object which causes a Namespace (logical name isolation in Kubernetes) and, e.g., create Network Security Policies, for network side protection, automatically through an operator (pattern)*.",[523,27747,27748],{},"*Operator pattern = A pattern of watching for objects and\u002F or object changes in the Kubernetes API and then reacting to those creations\u002F changes (e.g., creating other objects).",[3126,27750,27752],{"id":27751},"you-want-to-use-storage-in-kubernetes","You want to use Storage in Kubernetes?",[523,27754,27755,27756,27759,27760,27762],{},"No problem, Kubernetes allows you to specify claims for storage volumes and depending on if your storage system\u002F software supports it dynamically provision these \"claims for storage\" for you.\nMeaning that an application create a ",[567,27757,27758],{},"PersistentVolumeClaim"," requesting 50 Gigabytes of storage. Kubernetes and\u002F or the storage system\u002F software will then take care of creating the actual volume\u002F disk and to not lose track of it, create a ",[567,27761,18374],{}," in Kubernetes again (\"Mapping\" between Kubernetes and the Storage).",[523,27764,27765],{},"This allows for simple use of storage depending on if your storage system\u002F software supports it.",[6072,27767,27768,27772,27775],{},[523,27769,27770],{},[584,27771,6189],{},[523,27773,27774],{},"Container Storage Interface (CSI) plays an important role now and in the future. CSI is a set of interfaces which a storage system\u002F software can implement so that Kubernetes and other systems can easily request storage.",[523,27776,27777,27778,27781,27782,27784,27785,27788],{},"\"To mention it already there is a new interface for requesting\u002F 'managing' storage, which is named ",[584,27779,27780],{},"C","ontainer ",[584,27783,2003],{},"torage ",[584,27786,27787],{},"I","nterface (CSI). The goal of CSI is to have an unified interface through which anyone can request storage. Mounting of the requested storage is done by the storage dependent CSI driver then.\"",[3126,27790,27792],{"id":27791},"and-there-are-even-more-features","And there are even more features!",[668,27794,27795,27798,27806,27809,27837],{},[638,27796,27797],{},"Horizontal Autoscaling for applications",[638,27799,27800,27801],{},"Loadbalancing for Level 4 and 7 Services.\n",[668,27802,27803],{},[638,27804,27805],{},"Level 7 Services are balanced using a Ingress Controller, which is not part of Kubernetes by default.",[638,27807,27808],{},"Utilizing existing Storage for your applications (e.g., Ceph, NFS).",[638,27810,27811,27812],{},"Framework - Kubernetes API is easily extensible, examples for applications helping you with Kubernetes are:\n",[668,27813,27814,27822,27830],{},[638,27815,27816,27821],{},[527,27817,27820],{"href":27818,"rel":27819},"https:\u002F\u002Fistio.io\u002F",[531],"Istio"," - \"Connect, secure, control, and observe services\".",[638,27823,27824,27829],{},[527,27825,27828],{"href":27826,"rel":27827},"https:\u002F\u002Fvitess.io\u002F",[531],"Vitess"," - \"Vitess is a database clustering system for horizontal scaling of MySQL\".",[638,27831,27832,27836],{},[527,27833,27835],{"href":25935,"rel":27834},[531],"Prometheus Operator"," - \"Prometheus Operator creates\u002F configures\u002Fmanages Prometheus clusters atop Kubernetes\".",[638,27838,27839],{},"And more features already there and to come..",[523,27841,8764,27842,27847],{},[527,27843,27846],{"href":27844,"rel":27845},"https:\u002F\u002Fgithub.com\u002Fkubernetes\u002Fenhancements",[531],"GitHub kubernetes\u002F enhancements repository"," is the place for enchancement tracking and backlog for Kubernetes. I suggest to check it out to see what else is on the \"roadmap\".",[523,27849,27850],{},[3069,27851],{"alt":27852,"src":27853},"Kubernetes - 'It's dangerous to go alone' Zelda Meme intensifies","\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day2\u002Fkubernetes-its-dangerous-to-go-alone.png",[613,27855,27857],{"id":27856},"use-case-examples","Use Case Examples",[3126,27859,27861],{"id":27860},"web-applications","Web applications",[523,27863,27864],{},"The ease of Ingress objects in Kubernetes, allows for simple exposition of HTTP based applications.",[523,27866,27867],{},"Example Ingres Object:",[738,27869,27871],{"className":740,"code":27870,"language":742,"meta":743,"style":743},"apiVersion: extensions\u002Fv1beta1\nkind: Ingress\nmetadata:\n  name: my-web-app\nspec:\n  # tls: Also possible with ease\n  rules:\n  - host: example.com\n    http:\n      paths:\n      - path: \u002F\n        backend:\n          serviceName: my-web-app\n          servicePort: 8080\n",[567,27872,27873,27881,27889,27895,27904,27910,27915,27921,27932,27938,27944,27954,27960,27968],{"__ignoreMap":743},[747,27874,27875,27877,27879],{"class":749,"line":750},[747,27876,12949],{"class":753},[747,27878,856],{"class":757},[747,27880,25977],{"class":802},[747,27882,27883,27885,27887],{"class":749,"line":761},[747,27884,12963],{"class":753},[747,27886,856],{"class":757},[747,27888,25986],{"class":802},[747,27890,27891,27893],{"class":749,"line":769},[747,27892,12973],{"class":753},[747,27894,758],{"class":757},[747,27896,27897,27899,27901],{"class":749,"line":776},[747,27898,12980],{"class":753},[747,27900,856],{"class":757},[747,27902,27903],{"class":802}," my-web-app\n",[747,27905,27906,27908],{"class":749,"line":784},[747,27907,12990],{"class":753},[747,27909,758],{"class":757},[747,27911,27912],{"class":749,"line":790},[747,27913,27914],{"class":772},"  # tls: Also possible with ease\n",[747,27916,27917,27919],{"class":749,"line":796},[747,27918,26108],{"class":753},[747,27920,758],{"class":757},[747,27922,27923,27925,27927,27929],{"class":749,"line":806},[747,27924,1721],{"class":757},[747,27926,4591],{"class":753},[747,27928,856],{"class":757},[747,27930,27931],{"class":802}," example.com\n",[747,27933,27934,27936],{"class":749,"line":814},[747,27935,26125],{"class":753},[747,27937,758],{"class":757},[747,27939,27940,27942],{"class":749,"line":822},[747,27941,26132],{"class":753},[747,27943,758],{"class":757},[747,27945,27946,27948,27950,27952],{"class":749,"line":830},[747,27947,799],{"class":757},[747,27949,26141],{"class":753},[747,27951,856],{"class":757},[747,27953,26146],{"class":802},[747,27955,27956,27958],{"class":749,"line":836},[747,27957,26151],{"class":753},[747,27959,758],{"class":757},[747,27961,27962,27964,27966],{"class":749,"line":842},[747,27963,26158],{"class":753},[747,27965,856],{"class":757},[747,27967,27903],{"class":802},[747,27969,27970,27972,27974],{"class":749,"line":850},[747,27971,26167],{"class":753},[747,27973,856],{"class":757},[747,27975,9628],{"class":1895},[6072,27977,27978,27982],{},[523,27979,27980],{},[584,27981,6189],{},[523,27983,27984,27985,27987],{},"We will get back to ",[567,27986,158],{}," objects later on in the training, but for now we have to begin at the very basics.",[523,27989,27990,27991,27994,27995,27998,27999,28002],{},"The example Ingress object causes the \"application\" ",[567,27992,27993],{},"my-web-app"," to be available reachable when accessing ",[567,27996,27997],{},"example.com",".\nYou could even have different ",[567,28000,28001],{},"path","s for different application in the same or other objects, making it easy to \"combine\" multiple (micro-)services.",[523,28004,28005],{},"Having more insight and control of incoming traffic can be done as shown in the next use case example.",[3126,28007,28009],{"id":28008},"service-mesh-istio-linkerd-and-others","Service Mesh (Istio, Linkerd, and others)",[523,28011,28012],{},"Service Meshes allow you to gain more insight into the flow of traffic to your application.\nNot only can you gain more insight, but you can also control the traffic that with, e.g., Circuit Breaker Pattern and more possibilites.",[668,28014,28015,28021,28028,28035],{},[638,28016,28017],{},[527,28018,27820],{"href":28019,"rel":28020},"https:\u002F\u002Fistio.io",[531],[638,28022,28023],{},[527,28024,28027],{"href":28025,"rel":28026},"https:\u002F\u002Flinkerd.io",[531],"Linkerd",[638,28029,28030],{},[527,28031,28034],{"href":28032,"rel":28033},"https:\u002F\u002Fwww.consul.io\u002Fdocs\u002Fconnect\u002F",[531],"Consul Connect",[638,28036,28037],{},[527,28038,28041],{"href":28039,"rel":28040},"https:\u002F\u002Fwww.envoyproxy.io\u002Flearn\u002Fservice-mesh",[531],"Enovy Service Mesh",[3126,28043,28045],{"id":28044},"and-more","And more ...",[523,28047,28048],{},"There are many more use cases you can cover using Kubernetes or even containers in general.",[523,28050,28051,28052,1909],{},"To get some examples\u002F case studies of companies moving\u002F having moved to Kubernetes, checkout the ",[527,28053,28056],{"href":28054,"rel":28055},"https:\u002F\u002Fkubernetes.io\u002Fcase-studies\u002F",[531],"Kubernetes - Case Studies page",[2979,28058],{},[535,28060,28062,28063,28065],{"id":28061},"from-docker-compose-to-kubernetes","From ",[567,28064,2936],{}," to Kubernetes?",[523,28067,28068,28069,28071,28072,28077],{},"There are tools to translate ",[567,28070,2936],{}," files to Kubernetes \"format\" (",[527,28073,28076],{"href":28074,"rel":28075},"https:\u002F\u002Fgithub.com\u002Fkubernetes\u002Fkompose",[531],"kompose","), but I would not recommend them for two simple reasons:",[668,28079,28080,28094],{},[638,28081,28082,28083,28086],{},"To learn what objects are necessary and needed behind an application in Kubernetes, it is better to, e.g., have a Hackathon where everyone is playing around with the application to get it running on Kubernetes. ",[584,28084,28085],{},"=> Learn effect!",[668,28087,28088,28091],{},[638,28089,28090],{},"Additionally as there are some features which Docker doesn't have, getting to know them through such a Hackathon makes for a good team building either way :-)",[638,28092,28093],{},"Besides in the end you simply need to know the (basic) objects of Kubernetes to run, scale and keep your application running.",[638,28095,28096],{},"The results are \"basic\" and still require manual improvements (e.g., health probes\u002F checks, persistent storage, and more) to be made that the applications can\u002F will run smoothly in Kubernetes with everything Kubernetes has to offer.",[523,28098,28099],{},"So please take yourself the time to play around with the available Kubernetes objects and features. This should give you an overview of what is available and optimal for your application(s) when you think\u002F want to move them to Kubernetes.",[523,28101,28102],{},"Taking yourself time for looking into Kubernetes and other solutions will allow you to make a good decision, instead of using a butcher knife in an operation where a scalpel would have gotten the job done perfectly fine.",[2979,28104],{},[535,28106,28108],{"id":28107},"prepare-for-the-kubernetes-madness","Prepare for the Kubernetes madness",[523,28110,28111],{},"Connect to the first training VM using SSH and follow the sections ahead.",[613,28113,28115],{"id":28114},"kubernetes-system-requirements","Kubernetes System Requirements",[523,28117,28118,28119,856],{},"The following are the system requirements for a Kubernetes node which will or has been setup with ",[567,28120,162],{},[668,28122,28123,28126,28129],{},[638,28124,28125],{},"2 or more CPU cores",[638,28127,28128],{},"2 or more Gigabytes of memory",[638,28130,28131,28132],{},"No MAC nor IP address duplication for the servers used.\n",[668,28133,28134],{},[638,28135,28136],{},"For later on, make sure you don't use IP ranges already used in your company\u002F organisation.",[523,28138,28139,28140,1909],{},"For the full list of requirements, see ",[527,28141,28144],{"href":28142,"rel":28143},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fsetup\u002Findependent\u002Finstall-kubeadm\u002F#before-you-begin",[531],"Kubernetes - Install kubeadm documentation \"Before you begin\" section",[613,28146,3487],{"id":3486},[523,28148,28149,28150,3494],{},"Clone the repository, which contains the example and task files, from GitHub ",[567,28151,28152],{},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-container-docker-kubernetes.git",[738,28154,28156],{"className":1621,"code":28155,"language":1623,"meta":743,"style":743},"$ git clone https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-container-docker-kubernetes.git\nCloning into 'workshop-container-docker-kubernetes'...\nremote: Enumerating objects: 30, done.\nremote: Counting objects: 100% (30\u002F30), done.\nremote: Compressing objects: 100% (23\u002F23), done.\nremote: Total 30 (delta 3), reused 30 (delta 3), pack-reused 0\nUnpacking objects: 100% (30\u002F30), done.\n",[567,28157,28158,28169,28184,28197,28211,28225,28249],{"__ignoreMap":743},[747,28159,28160,28162,28164,28166],{"class":749,"line":750},[747,28161,1919],{"class":1630},[747,28163,22393],{"class":802},[747,28165,3506],{"class":802},[747,28167,28168],{"class":802}," https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-container-docker-kubernetes.git\n",[747,28170,28171,28173,28175,28177,28180,28182],{"class":749,"line":761},[747,28172,3531],{"class":1630},[747,28174,3534],{"class":802},[747,28176,3537],{"class":757},[747,28178,28179],{"class":802},"workshop-container-docker-kubernetes",[747,28181,3543],{"class":757},[747,28183,3546],{"class":802},[747,28185,28186,28188,28190,28192,28195],{"class":749,"line":769},[747,28187,3551],{"class":1630},[747,28189,3554],{"class":802},[747,28191,3557],{"class":802},[747,28193,28194],{"class":802}," 30,",[747,28196,3563],{"class":802},[747,28198,28199,28201,28204,28206,28208],{"class":749,"line":776},[747,28200,3551],{"class":1630},[747,28202,28203],{"class":802}," Counting",[747,28205,3557],{"class":802},[747,28207,3610],{"class":802},[747,28209,28210],{"class":1640}," (30\u002F30), done.\n",[747,28212,28213,28215,28218,28220,28222],{"class":749,"line":784},[747,28214,3551],{"class":1630},[747,28216,28217],{"class":802}," Compressing",[747,28219,3557],{"class":802},[747,28221,3610],{"class":802},[747,28223,28224],{"class":1640}," (23\u002F23), done.\n",[747,28226,28227,28229,28231,28234,28236,28239,28242,28244,28246],{"class":749,"line":790},[747,28228,3551],{"class":1630},[747,28230,3570],{"class":802},[747,28232,28233],{"class":1895}," 30",[747,28235,3576],{"class":1640},[747,28237,28238],{"class":1895},"3",[747,28240,28241],{"class":1640},"), reused 30 (",[747,28243,3585],{"class":1630},[747,28245,16369],{"class":1895},[747,28247,28248],{"class":1640},"), pack-reused 0\n",[747,28250,28251,28254,28256,28258],{"class":749,"line":796},[747,28252,28253],{"class":1630},"Unpacking",[747,28255,3557],{"class":802},[747,28257,3610],{"class":802},[747,28259,28210],{"class":1640},[523,28261,28262],{},"Now you are ready to run your first Pods in Kubernetes!",[2979,28264],{},[535,28266,28268],{"id":28267},"kubernetes-first-steps","Kubernetes: First Steps",[613,28270,3650],{"id":3649},[523,28272,28273,28274,714,28276,28279,28280,28282,28283,28285],{},"Kubernetes has something similar to ",[567,28275,4203],{},[567,28277,28278],{},"kubectl run",". We will use ",[567,28281,28278],{}," for the first example to get started but to already say it, ",[567,28284,28278],{}," isn't really used in the end to, e.g., deploy applications.",[738,28287,28289],{"className":1621,"code":28288,"language":1623,"meta":743,"style":743},"$ kubectl run -it --image=hello-world --restart=Never hello-world\n\nHello from Docker!\nThis message shows that your installation appears to be working correctly.\n\nTo generate this message, Docker took the following steps:\n 1. The Docker client contacted the Docker daemon.\n 2. The Docker daemon pulled the \"hello-world\" image from the Docker Hub.\n    (amd64)\n 3. The Docker daemon created a new container from that image which runs the\n    executable that produces the output you are currently reading.\n 4. The Docker daemon streamed that output to the Docker client, which sent it\n    to your terminal.\n\nTo try something more ambitious, you can run an Ubuntu container with:\n $ docker run -it ubuntu bash\n\nShare images, automate workflows, and more with a free Docker ID:\n https:\u002F\u002Fhub.docker.com\u002F\n\nFor more examples and ideas, visit:\n https:\u002F\u002Fdocs.docker.com\u002Fget-started\u002F\n\n",[567,28290,28291,28309,28313,28321,28345,28349,28369,28388,28419,28427,28458,28478,28509,28517,28521,28547,28562,28566,28590,28595,28599,28613],{"__ignoreMap":743},[747,28292,28293,28295,28297,28299,28301,28304,28307],{"class":749,"line":750},[747,28294,1919],{"class":1630},[747,28296,1922],{"class":802},[747,28298,3665],{"class":802},[747,28300,4072],{"class":802},[747,28302,28303],{"class":802}," --image=hello-world",[747,28305,28306],{"class":802}," --restart=Never",[747,28308,3668],{"class":802},[747,28310,28311],{"class":749,"line":761},[747,28312,1255],{"emptyLinePlaceholder":1254},[747,28314,28315,28317,28319],{"class":749,"line":769},[747,28316,3773],{"class":1630},[747,28318,3723],{"class":802},[747,28320,3778],{"class":802},[747,28322,28323,28325,28327,28329,28331,28333,28335,28337,28339,28341,28343],{"class":749,"line":776},[747,28324,3783],{"class":1630},[747,28326,3786],{"class":802},[747,28328,3789],{"class":802},[747,28330,3792],{"class":802},[747,28332,3795],{"class":802},[747,28334,3798],{"class":802},[747,28336,3801],{"class":802},[747,28338,3696],{"class":802},[747,28340,3806],{"class":802},[747,28342,3809],{"class":802},[747,28344,3812],{"class":802},[747,28346,28347],{"class":749,"line":784},[747,28348,1255],{"emptyLinePlaceholder":1254},[747,28350,28351,28353,28355,28357,28359,28361,28363,28365,28367],{"class":749,"line":790},[747,28352,3821],{"class":1630},[747,28354,3824],{"class":802},[747,28356,3827],{"class":802},[747,28358,3830],{"class":802},[747,28360,3833],{"class":802},[747,28362,3836],{"class":802},[747,28364,3839],{"class":802},[747,28366,3842],{"class":802},[747,28368,3845],{"class":802},[747,28370,28371,28374,28376,28378,28380,28382,28384,28386],{"class":749,"line":796},[747,28372,28373],{"class":1630}," 1.",[747,28375,3853],{"class":802},[747,28377,3833],{"class":802},[747,28379,3858],{"class":802},[747,28381,3861],{"class":802},[747,28383,3839],{"class":802},[747,28385,3833],{"class":802},[747,28387,3868],{"class":802},[747,28389,28390,28393,28395,28397,28399,28401,28403,28405,28407,28409,28411,28413,28415,28417],{"class":749,"line":806},[747,28391,28392],{"class":1630}," 2.",[747,28394,3853],{"class":802},[747,28396,3833],{"class":802},[747,28398,3880],{"class":802},[747,28400,3883],{"class":802},[747,28402,3839],{"class":802},[747,28404,969],{"class":757},[747,28406,3649],{"class":802},[747,28408,3892],{"class":757},[747,28410,3702],{"class":802},[747,28412,3723],{"class":802},[747,28414,3839],{"class":802},[747,28416,3833],{"class":802},[747,28418,3903],{"class":802},[747,28420,28421,28423,28425],{"class":749,"line":814},[747,28422,3908],{"class":757},[747,28424,3911],{"class":1630},[747,28426,3600],{"class":757},[747,28428,28429,28432,28434,28436,28438,28440,28442,28444,28446,28448,28450,28452,28454,28456],{"class":749,"line":822},[747,28430,28431],{"class":1630}," 3.",[747,28433,3853],{"class":802},[747,28435,3833],{"class":802},[747,28437,3880],{"class":802},[747,28439,3927],{"class":802},[747,28441,3930],{"class":802},[747,28443,3933],{"class":802},[747,28445,3936],{"class":802},[747,28447,3723],{"class":802},[747,28449,3792],{"class":802},[747,28451,3702],{"class":802},[747,28453,3945],{"class":802},[747,28455,3948],{"class":802},[747,28457,3951],{"class":802},[747,28459,28460,28462,28464,28466,28468,28470,28472,28474,28476],{"class":749,"line":830},[747,28461,3956],{"class":1630},[747,28463,3792],{"class":802},[747,28465,3961],{"class":802},[747,28467,3839],{"class":802},[747,28469,3966],{"class":802},[747,28471,3969],{"class":802},[747,28473,3972],{"class":802},[747,28475,3975],{"class":802},[747,28477,3978],{"class":802},[747,28479,28480,28483,28485,28487,28489,28491,28493,28495,28497,28499,28501,28503,28505,28507],{"class":749,"line":836},[747,28481,28482],{"class":1630}," 4.",[747,28484,3853],{"class":802},[747,28486,3833],{"class":802},[747,28488,3880],{"class":802},[747,28490,3992],{"class":802},[747,28492,3792],{"class":802},[747,28494,3966],{"class":802},[747,28496,3696],{"class":802},[747,28498,3839],{"class":802},[747,28500,3833],{"class":802},[747,28502,4005],{"class":802},[747,28504,3945],{"class":802},[747,28506,4010],{"class":802},[747,28508,4013],{"class":802},[747,28510,28511,28513,28515],{"class":749,"line":842},[747,28512,4018],{"class":1630},[747,28514,3795],{"class":802},[747,28516,4023],{"class":802},[747,28518,28519],{"class":749,"line":850},[747,28520,1255],{"emptyLinePlaceholder":1254},[747,28522,28523,28525,28527,28529,28531,28533,28535,28537,28539,28541,28543,28545],{"class":749,"line":863},[747,28524,3821],{"class":1630},[747,28526,4034],{"class":802},[747,28528,4037],{"class":802},[747,28530,4040],{"class":802},[747,28532,4043],{"class":802},[747,28534,3969],{"class":802},[747,28536,4048],{"class":802},[747,28538,3665],{"class":802},[747,28540,4053],{"class":802},[747,28542,4056],{"class":802},[747,28544,3936],{"class":802},[747,28546,4061],{"class":802},[747,28548,28549,28552,28554,28556,28558,28560],{"class":749,"line":869},[747,28550,28551],{"class":1630}," $",[747,28553,3246],{"class":802},[747,28555,3665],{"class":802},[747,28557,4072],{"class":802},[747,28559,4075],{"class":802},[747,28561,4078],{"class":802},[747,28563,28564],{"class":749,"line":877},[747,28565,1255],{"emptyLinePlaceholder":1254},[747,28567,28568,28570,28572,28574,28576,28578,28580,28582,28584,28586,28588],{"class":749,"line":1015},[747,28569,4087],{"class":1630},[747,28571,4090],{"class":802},[747,28573,4093],{"class":802},[747,28575,4096],{"class":802},[747,28577,4099],{"class":802},[747,28579,4040],{"class":802},[747,28581,4104],{"class":802},[747,28583,3930],{"class":802},[747,28585,4109],{"class":802},[747,28587,3833],{"class":802},[747,28589,4114],{"class":802},[747,28591,28592],{"class":749,"line":1021},[747,28593,28594],{"class":1630}," https:\u002F\u002Fhub.docker.com\u002F\n",[747,28596,28597],{"class":749,"line":1027},[747,28598,1255],{"emptyLinePlaceholder":1254},[747,28600,28601,28603,28605,28607,28609,28611],{"class":749,"line":1033},[747,28602,4128],{"class":1630},[747,28604,4040],{"class":802},[747,28606,4133],{"class":802},[747,28608,4099],{"class":802},[747,28610,4138],{"class":802},[747,28612,4141],{"class":802},[747,28614,28615],{"class":749,"line":1039},[747,28616,28617],{"class":1630}," https:\u002F\u002Fdocs.docker.com\u002Fget-started\u002F\n",[523,28619,28620],{},"Cool, isn't it? It's a bit like Docker, but so different in the end.",[523,28622,28623,28624,28626],{},"What the ",[567,28625,28278],{}," command has just done is create a \"Pod\" object in Kubernetes which is similar to a \"container\" in the Docker world, more on that later.",[523,28628,28629],{},"Kubernetes uses YAML (\u002F JSON for the hardcore people) to define objects in its API. The mentioned \"Pod\" object is one of them.",[6072,28631,28632,28636],{},[523,28633,28634],{},[584,28635,6189],{},[523,28637,28638],{},"Speaking of YAML:",[668,28640,28641,28648],{},[638,28642,28643,28644,28647],{},"To separate documents\u002F objects, you put ",[567,28645,28646],{},"---"," in between them.",[638,28649,28650,28651],{},"Don't use tabs, only use spaces in YAML files, or your gonna have a bad time.\n",[668,28652,28653],{},[638,28654,28655,28656,28660],{},"You can use, e.g., ",[527,28657,28659],{"href":10829,"rel":28658},[531],"Online YAML Parser"," to validate your YAML files online or also locally through addons\u002F extensions in your editor.",[523,28662,28663,28664,28666,28667,28669,28670,1909],{},"There are different types of objects in Kubernetes, as an example with the above ",[567,28665,28278],{}," command we created a ",[567,28668,25722],{}," object with the name of ",[567,28671,3649],{},[3126,28673,28675],{"id":28674},"lets-look-at-the-pod-object","Let's look at the \"Pod\" object",[523,28677,2000,28678,2006],{},[3049,28679,28680,28681],{},"No we are not talking about the band ",[527,28682,28685],{"href":28683,"rel":28684},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FP.O.D.",[531],"P.O.D.",[523,28687,28688,28689,28691,28692,28695],{},"To look at the Pod we just created using ",[567,28690,28278],{},", we are going to use ",[567,28693,28694],{},"kubectl get"," now:",[738,28697,28699],{"className":1621,"code":28698,"language":1623,"meta":743,"style":743},"$ kubectl get pod hello-world\nNAME          READY   STATUS      RESTARTS   AGE\nhello-world   0\u002F1     Completed   0          12s\n",[567,28700,28701,28713,28726],{"__ignoreMap":743},[747,28702,28703,28705,28707,28709,28711],{"class":749,"line":750},[747,28704,1919],{"class":1630},[747,28706,1922],{"class":802},[747,28708,1951],{"class":802},[747,28710,2219],{"class":802},[747,28712,3668],{"class":802},[747,28714,28715,28717,28720,28722,28724],{"class":749,"line":761},[747,28716,2230],{"class":1630},[747,28718,28719],{"class":802},"          READY",[747,28721,2236],{"class":802},[747,28723,15743],{"class":802},[747,28725,15553],{"class":802},[747,28727,28728,28730,28733,28735,28737],{"class":749,"line":769},[747,28729,3649],{"class":1630},[747,28731,28732],{"class":802},"   0\u002F1",[747,28734,15908],{"class":802},[747,28736,2274],{"class":1895},[747,28738,28739],{"class":802},"          12s\n",[523,28741,28742,28743,28745,28746,28748,28749,28751,28752,28754],{},"This only got us the Pod in a \"list\" format. Omitting the ",[567,28744,3649],{}," (object name) would cause all Pod objects in the current ",[567,28747,22320],{}," to be listed.\nA ",[567,28750,22320],{}," is a logical naming space separation for objects, meaning that it is possible to have multiple ",[567,28753,3649],{}," Pod objects in different namespaces at the same time.\nThis is one of the \"special\" points of Kubernetes, being able to separate object (\u002F applications) by name already.",[523,28756,28757,28758,28761,28762,28765,28766,28768],{},"To get the YAML\u002F JSON contents of this Pod object, we add the ",[567,28759,28760],{},"--output=FORMAT"," (short: ",[567,28763,28764],{},"-o FORMAT",") flag to the ",[567,28767,28694],{}," command:",[738,28770,28772],{"className":740,"code":28771,"language":742,"meta":743,"style":743},"$ kubectl get pod hello-world --output yaml\napiVersion: v1\nkind: Pod\nmetadata:\n  annotations:\n    cni.projectcalico.org\u002FpodIP: 100.67.92.19\u002F32\n  creationTimestamp: \"2019-05-04T18:02:30Z\"\n  labels:\n    run: hello-world\n  name: hello-world\n  namespace: default\n  resourceVersion: \"11195745\"\n  selfLink: \u002Fapi\u002Fv1\u002Fnamespaces\u002Fdefault\u002Fpods\u002Fhello-world\n  uid: c919ad65-6e96-11e9-a6f0-9600001d3faa\nspec:\n  containers:\n  - image: hello-world\n    imagePullPolicy: Always\n    name: hello-world\n    resources: {}\n    stdin: true\n    stdinOnce: true\n    terminationMessagePath: \u002Fdev\u002Ftermination-log\n    terminationMessagePolicy: File\n    tty: true\n    volumeMounts:\n    - mountPath: \u002Fvar\u002Frun\u002Fsecrets\u002Fkubernetes.io\u002Fserviceaccount\n      name: default-token-lb5tz\n      readOnly: true\n  dnsPolicy: ClusterFirst\n  enableServiceLinks: true\n  nodeName: k8s02-node-mvljd2v2nje-htz-deu-fsn1dc1.clster.systems\n  priority: 0\n  restartPolicy: Never\n  schedulerName: default-scheduler\n  securityContext: {}\n  serviceAccount: default\n  serviceAccountName: default\n  terminationGracePeriodSeconds: 30\n  tolerations:\n  - effect: NoExecute\n    key: node.kubernetes.io\u002Fnot-ready\n    operator: Exists\n    tolerationSeconds: 300\n  - effect: NoExecute\n    key: node.kubernetes.io\u002Funreachable\n    operator: Exists\n    tolerationSeconds: 300\n  volumes:\n  - name: default-token-lb5tz\n    secret:\n      defaultMode: 420\n      secretName: default-token-lb5tz\nstatus:\n  conditions:\n  - lastProbeTime: null\n    lastTransitionTime: \"2019-05-04T18:02:31Z\"\n    reason: PodCompleted\n    status: \"True\"\n    type: Initialized\n  - lastProbeTime: null\n    lastTransitionTime: \"2019-05-04T18:02:35Z\"\n    reason: PodCompleted\n    status: \"False\"\n    type: Ready\n  - lastProbeTime: null\n    lastTransitionTime: \"2019-05-04T18:02:35Z\"\n    reason: PodCompleted\n    status: \"False\"\n    type: ContainersReady\n  - lastProbeTime: null\n    lastTransitionTime: \"2019-05-04T18:02:30Z\"\n    status: \"True\"\n    type: PodScheduled\n  containerStatuses:\n  - containerID: containerd:\u002F\u002Ff5cea87d6ed60944a564c28ca9f1ee96eda262f3d0b99587fa798c0ea1a650ed\n    image: docker.io\u002Flibrary\u002Fhello-world:latest\n    imageID: docker.io\u002Flibrary\u002Fhello-world@sha256:92695bc579f31df7a63da6922075d0666e565ceccad16b59c3374d2cf4e8e50e\n    lastState: {}\n    name: hello-world\n    ready: false\n    restartCount: 0\n    state:\n      terminated:\n        containerID: containerd:\u002F\u002Ff5cea87d6ed60944a564c28ca9f1ee96eda262f3d0b99587fa798c0ea1a650ed\n        exitCode: 0\n        finishedAt: \"2019-05-04T18:02:34Z\"\n        reason: Completed\n        startedAt: \"2019-05-04T18:02:34Z\"\n  hostIP: [IP OF NODE REMOVED]\n  phase: Succeeded\n  podIP: 100.67.92.19\n  qosClass: BestEffort\n  startTime: \"2019-05-04T18:02:31Z\"\n",[567,28773,28774,28779,28787,28796,28802,28808,28818,28832,28838,28847,28855,28863,28877,28887,28897,28903,28910,28920,28929,28937,28946,28955,28964,28974,28984,28993,29000,29012,29021,29030,29040,29049,29059,29068,29078,29088,29097,29106,29115,29124,29131,29142,29152,29160,29170,29180,29189,29197,29205,29212,29222,29228,29238,29247,29254,29261,29273,29287,29297,29311,29321,29331,29344,29352,29365,29374,29384,29396,29404,29416,29425,29435,29447,29459,29468,29475,29487,29496,29506,29515,29523,29532,29541,29548,29555,29564,29573,29587,29597,29610,29624,29634,29644,29654],{"__ignoreMap":743},[747,28775,28776],{"class":749,"line":750},[747,28777,28778],{"class":802},"$ kubectl get pod hello-world --output yaml\n",[747,28780,28781,28783,28785],{"class":749,"line":761},[747,28782,12949],{"class":753},[747,28784,856],{"class":757},[747,28786,22608],{"class":802},[747,28788,28789,28791,28793],{"class":749,"line":769},[747,28790,12963],{"class":753},[747,28792,856],{"class":757},[747,28794,28795],{"class":802}," Pod\n",[747,28797,28798,28800],{"class":749,"line":776},[747,28799,12973],{"class":753},[747,28801,758],{"class":757},[747,28803,28804,28806],{"class":749,"line":784},[747,28805,25801],{"class":753},[747,28807,758],{"class":757},[747,28809,28810,28813,28815],{"class":749,"line":790},[747,28811,28812],{"class":753},"    cni.projectcalico.org\u002FpodIP",[747,28814,856],{"class":757},[747,28816,28817],{"class":802}," 100.67.92.19\u002F32\n",[747,28819,28820,28823,28825,28827,28830],{"class":749,"line":796},[747,28821,28822],{"class":753},"  creationTimestamp",[747,28824,856],{"class":757},[747,28826,969],{"class":757},[747,28828,28829],{"class":802},"2019-05-04T18:02:30Z",[747,28831,975],{"class":757},[747,28833,28834,28836],{"class":749,"line":806},[747,28835,25378],{"class":753},[747,28837,758],{"class":757},[747,28839,28840,28843,28845],{"class":749,"line":814},[747,28841,28842],{"class":753},"    run",[747,28844,856],{"class":757},[747,28846,3668],{"class":802},[747,28848,28849,28851,28853],{"class":749,"line":822},[747,28850,12980],{"class":753},[747,28852,856],{"class":757},[747,28854,3668],{"class":802},[747,28856,28857,28859,28861],{"class":749,"line":830},[747,28858,13231],{"class":753},[747,28860,856],{"class":757},[747,28862,7736],{"class":802},[747,28864,28865,28868,28870,28872,28875],{"class":749,"line":836},[747,28866,28867],{"class":753},"  resourceVersion",[747,28869,856],{"class":757},[747,28871,969],{"class":757},[747,28873,28874],{"class":802},"11195745",[747,28876,975],{"class":757},[747,28878,28879,28882,28884],{"class":749,"line":842},[747,28880,28881],{"class":753},"  selfLink",[747,28883,856],{"class":757},[747,28885,28886],{"class":802}," \u002Fapi\u002Fv1\u002Fnamespaces\u002Fdefault\u002Fpods\u002Fhello-world\n",[747,28888,28889,28892,28894],{"class":749,"line":850},[747,28890,28891],{"class":753},"  uid",[747,28893,856],{"class":757},[747,28895,28896],{"class":802}," c919ad65-6e96-11e9-a6f0-9600001d3faa\n",[747,28898,28899,28901],{"class":749,"line":863},[747,28900,12990],{"class":753},[747,28902,758],{"class":757},[747,28904,28905,28908],{"class":749,"line":869},[747,28906,28907],{"class":753},"  containers",[747,28909,758],{"class":757},[747,28911,28912,28914,28916,28918],{"class":749,"line":877},[747,28913,1721],{"class":757},[747,28915,3702],{"class":753},[747,28917,856],{"class":757},[747,28919,3668],{"class":802},[747,28921,28922,28925,28927],{"class":749,"line":1015},[747,28923,28924],{"class":753},"    imagePullPolicy",[747,28926,856],{"class":757},[747,28928,25548],{"class":802},[747,28930,28931,28933,28935],{"class":749,"line":1021},[747,28932,24402],{"class":753},[747,28934,856],{"class":757},[747,28936,3668],{"class":802},[747,28938,28939,28942,28944],{"class":749,"line":1027},[747,28940,28941],{"class":753},"    resources",[747,28943,856],{"class":757},[747,28945,18570],{"class":757},[747,28947,28948,28951,28953],{"class":749,"line":1033},[747,28949,28950],{"class":753},"    stdin",[747,28952,856],{"class":757},[747,28954,860],{"class":859},[747,28956,28957,28960,28962],{"class":749,"line":1039},[747,28958,28959],{"class":753},"    stdinOnce",[747,28961,856],{"class":757},[747,28963,860],{"class":859},[747,28965,28966,28969,28971],{"class":749,"line":1054},[747,28967,28968],{"class":753},"    terminationMessagePath",[747,28970,856],{"class":757},[747,28972,28973],{"class":802}," \u002Fdev\u002Ftermination-log\n",[747,28975,28976,28979,28981],{"class":749,"line":1060},[747,28977,28978],{"class":753},"    terminationMessagePolicy",[747,28980,856],{"class":757},[747,28982,28983],{"class":802}," File\n",[747,28985,28986,28989,28991],{"class":749,"line":1066},[747,28987,28988],{"class":753},"    tty",[747,28990,856],{"class":757},[747,28992,860],{"class":859},[747,28994,28995,28998],{"class":749,"line":1081},[747,28996,28997],{"class":753},"    volumeMounts",[747,28999,758],{"class":757},[747,29001,29002,29004,29007,29009],{"class":749,"line":1087},[747,29003,18665],{"class":757},[747,29005,29006],{"class":753}," mountPath",[747,29008,856],{"class":757},[747,29010,29011],{"class":802}," \u002Fvar\u002Frun\u002Fsecrets\u002Fkubernetes.io\u002Fserviceaccount\n",[747,29013,29014,29016,29018],{"class":749,"line":1102},[747,29015,925],{"class":753},[747,29017,856],{"class":757},[747,29019,29020],{"class":802}," default-token-lb5tz\n",[747,29022,29023,29026,29028],{"class":749,"line":1110},[747,29024,29025],{"class":753},"      readOnly",[747,29027,856],{"class":757},[747,29029,860],{"class":859},[747,29031,29032,29035,29037],{"class":749,"line":1117},[747,29033,29034],{"class":753},"  dnsPolicy",[747,29036,856],{"class":757},[747,29038,29039],{"class":802}," ClusterFirst\n",[747,29041,29042,29045,29047],{"class":749,"line":1123},[747,29043,29044],{"class":753},"  enableServiceLinks",[747,29046,856],{"class":757},[747,29048,860],{"class":859},[747,29050,29051,29054,29056],{"class":749,"line":1129},[747,29052,29053],{"class":753},"  nodeName",[747,29055,856],{"class":757},[747,29057,29058],{"class":802}," k8s02-node-mvljd2v2nje-htz-deu-fsn1dc1.clster.systems\n",[747,29060,29061,29064,29066],{"class":749,"line":1142},[747,29062,29063],{"class":753},"  priority",[747,29065,856],{"class":757},[747,29067,7863],{"class":1895},[747,29069,29070,29073,29075],{"class":749,"line":1150},[747,29071,29072],{"class":753},"  restartPolicy",[747,29074,856],{"class":757},[747,29076,29077],{"class":802}," Never\n",[747,29079,29080,29083,29085],{"class":749,"line":1157},[747,29081,29082],{"class":753},"  schedulerName",[747,29084,856],{"class":757},[747,29086,29087],{"class":802}," default-scheduler\n",[747,29089,29090,29093,29095],{"class":749,"line":1163},[747,29091,29092],{"class":753},"  securityContext",[747,29094,856],{"class":757},[747,29096,18570],{"class":757},[747,29098,29099,29102,29104],{"class":749,"line":1168},[747,29100,29101],{"class":753},"  serviceAccount",[747,29103,856],{"class":757},[747,29105,7736],{"class":802},[747,29107,29108,29111,29113],{"class":749,"line":1174},[747,29109,29110],{"class":753},"  serviceAccountName",[747,29112,856],{"class":757},[747,29114,7736],{"class":802},[747,29116,29117,29120,29122],{"class":749,"line":1480},[747,29118,29119],{"class":753},"  terminationGracePeriodSeconds",[747,29121,856],{"class":757},[747,29123,18735],{"class":1895},[747,29125,29126,29129],{"class":749,"line":1491},[747,29127,29128],{"class":753},"  tolerations",[747,29130,758],{"class":757},[747,29132,29133,29135,29137,29139],{"class":749,"line":1496},[747,29134,1721],{"class":757},[747,29136,1820],{"class":753},[747,29138,856],{"class":757},[747,29140,29141],{"class":802}," NoExecute\n",[747,29143,29144,29147,29149],{"class":749,"line":1502},[747,29145,29146],{"class":753},"    key",[747,29148,856],{"class":757},[747,29150,29151],{"class":802}," node.kubernetes.io\u002Fnot-ready\n",[747,29153,29154,29156,29158],{"class":749,"line":1510},[747,29155,1830],{"class":753},[747,29157,856],{"class":757},[747,29159,1835],{"class":802},[747,29161,29162,29165,29167],{"class":749,"line":1520},[747,29163,29164],{"class":753},"    tolerationSeconds",[747,29166,856],{"class":757},[747,29168,29169],{"class":1895}," 300\n",[747,29171,29172,29174,29176,29178],{"class":749,"line":1525},[747,29173,1721],{"class":757},[747,29175,1820],{"class":753},[747,29177,856],{"class":757},[747,29179,29141],{"class":802},[747,29181,29182,29184,29186],{"class":749,"line":1533},[747,29183,29146],{"class":753},[747,29185,856],{"class":757},[747,29187,29188],{"class":802}," node.kubernetes.io\u002Funreachable\n",[747,29190,29191,29193,29195],{"class":749,"line":1539},[747,29192,1830],{"class":753},[747,29194,856],{"class":757},[747,29196,1835],{"class":802},[747,29198,29199,29201,29203],{"class":749,"line":1549},[747,29200,29164],{"class":753},[747,29202,856],{"class":757},[747,29204,29169],{"class":1895},[747,29206,29207,29210],{"class":749,"line":1554},[747,29208,29209],{"class":753},"  volumes",[747,29211,758],{"class":757},[747,29213,29214,29216,29218,29220],{"class":749,"line":1562},[747,29215,1721],{"class":757},[747,29217,14804],{"class":753},[747,29219,856],{"class":757},[747,29221,29020],{"class":802},[747,29223,29224,29226],{"class":749,"line":1568},[747,29225,25219],{"class":753},[747,29227,758],{"class":757},[747,29229,29230,29233,29235],{"class":749,"line":1577},[747,29231,29232],{"class":753},"      defaultMode",[747,29234,856],{"class":757},[747,29236,29237],{"class":1895}," 420\n",[747,29239,29240,29243,29245],{"class":749,"line":1582},[747,29241,29242],{"class":753},"      secretName",[747,29244,856],{"class":757},[747,29246,29020],{"class":802},[747,29248,29249,29252],{"class":749,"line":1588},[747,29250,29251],{"class":753},"status",[747,29253,758],{"class":757},[747,29255,29256,29259],{"class":749,"line":1594},[747,29257,29258],{"class":753},"  conditions",[747,29260,758],{"class":757},[747,29262,29263,29265,29268,29270],{"class":749,"line":1600},[747,29264,1721],{"class":757},[747,29266,29267],{"class":753}," lastProbeTime",[747,29269,856],{"class":757},[747,29271,29272],{"class":757}," null\n",[747,29274,29275,29278,29280,29282,29285],{"class":749,"line":4804},[747,29276,29277],{"class":753},"    lastTransitionTime",[747,29279,856],{"class":757},[747,29281,969],{"class":757},[747,29283,29284],{"class":802},"2019-05-04T18:02:31Z",[747,29286,975],{"class":757},[747,29288,29289,29292,29294],{"class":749,"line":4810},[747,29290,29291],{"class":753},"    reason",[747,29293,856],{"class":757},[747,29295,29296],{"class":802}," PodCompleted\n",[747,29298,29299,29302,29304,29306,29309],{"class":749,"line":4816},[747,29300,29301],{"class":753},"    status",[747,29303,856],{"class":757},[747,29305,969],{"class":757},[747,29307,29308],{"class":802},"True",[747,29310,975],{"class":757},[747,29312,29313,29316,29318],{"class":749,"line":4822},[747,29314,29315],{"class":753},"    type",[747,29317,856],{"class":757},[747,29319,29320],{"class":802}," Initialized\n",[747,29322,29323,29325,29327,29329],{"class":749,"line":4828},[747,29324,1721],{"class":757},[747,29326,29267],{"class":753},[747,29328,856],{"class":757},[747,29330,29272],{"class":757},[747,29332,29333,29335,29337,29339,29342],{"class":749,"line":4834},[747,29334,29277],{"class":753},[747,29336,856],{"class":757},[747,29338,969],{"class":757},[747,29340,29341],{"class":802},"2019-05-04T18:02:35Z",[747,29343,975],{"class":757},[747,29345,29346,29348,29350],{"class":749,"line":4840},[747,29347,29291],{"class":753},[747,29349,856],{"class":757},[747,29351,29296],{"class":802},[747,29353,29354,29356,29358,29360,29363],{"class":749,"line":4846},[747,29355,29301],{"class":753},[747,29357,856],{"class":757},[747,29359,969],{"class":757},[747,29361,29362],{"class":802},"False",[747,29364,975],{"class":757},[747,29366,29367,29369,29371],{"class":749,"line":4852},[747,29368,29315],{"class":753},[747,29370,856],{"class":757},[747,29372,29373],{"class":802}," Ready\n",[747,29375,29376,29378,29380,29382],{"class":749,"line":4858},[747,29377,1721],{"class":757},[747,29379,29267],{"class":753},[747,29381,856],{"class":757},[747,29383,29272],{"class":757},[747,29385,29386,29388,29390,29392,29394],{"class":749,"line":4864},[747,29387,29277],{"class":753},[747,29389,856],{"class":757},[747,29391,969],{"class":757},[747,29393,29341],{"class":802},[747,29395,975],{"class":757},[747,29397,29398,29400,29402],{"class":749,"line":4870},[747,29399,29291],{"class":753},[747,29401,856],{"class":757},[747,29403,29296],{"class":802},[747,29405,29406,29408,29410,29412,29414],{"class":749,"line":4876},[747,29407,29301],{"class":753},[747,29409,856],{"class":757},[747,29411,969],{"class":757},[747,29413,29362],{"class":802},[747,29415,975],{"class":757},[747,29417,29418,29420,29422],{"class":749,"line":4882},[747,29419,29315],{"class":753},[747,29421,856],{"class":757},[747,29423,29424],{"class":802}," ContainersReady\n",[747,29426,29427,29429,29431,29433],{"class":749,"line":4888},[747,29428,1721],{"class":757},[747,29430,29267],{"class":753},[747,29432,856],{"class":757},[747,29434,29272],{"class":757},[747,29436,29437,29439,29441,29443,29445],{"class":749,"line":4894},[747,29438,29277],{"class":753},[747,29440,856],{"class":757},[747,29442,969],{"class":757},[747,29444,28829],{"class":802},[747,29446,975],{"class":757},[747,29448,29449,29451,29453,29455,29457],{"class":749,"line":4900},[747,29450,29301],{"class":753},[747,29452,856],{"class":757},[747,29454,969],{"class":757},[747,29456,29308],{"class":802},[747,29458,975],{"class":757},[747,29460,29461,29463,29465],{"class":749,"line":4906},[747,29462,29315],{"class":753},[747,29464,856],{"class":757},[747,29466,29467],{"class":802}," PodScheduled\n",[747,29469,29470,29473],{"class":749,"line":4912},[747,29471,29472],{"class":753},"  containerStatuses",[747,29474,758],{"class":757},[747,29476,29477,29479,29482,29484],{"class":749,"line":4928},[747,29478,1721],{"class":757},[747,29480,29481],{"class":753}," containerID",[747,29483,856],{"class":757},[747,29485,29486],{"class":802}," containerd:\u002F\u002Ff5cea87d6ed60944a564c28ca9f1ee96eda262f3d0b99587fa798c0ea1a650ed\n",[747,29488,29489,29491,29493],{"class":749,"line":4934},[747,29490,10899],{"class":753},[747,29492,856],{"class":757},[747,29494,29495],{"class":802}," docker.io\u002Flibrary\u002Fhello-world:latest\n",[747,29497,29498,29501,29503],{"class":749,"line":4940},[747,29499,29500],{"class":753},"    imageID",[747,29502,856],{"class":757},[747,29504,29505],{"class":802}," docker.io\u002Flibrary\u002Fhello-world@sha256:92695bc579f31df7a63da6922075d0666e565ceccad16b59c3374d2cf4e8e50e\n",[747,29507,29508,29511,29513],{"class":749,"line":4946},[747,29509,29510],{"class":753},"    lastState",[747,29512,856],{"class":757},[747,29514,18570],{"class":757},[747,29516,29517,29519,29521],{"class":749,"line":4952},[747,29518,24402],{"class":753},[747,29520,856],{"class":757},[747,29522,3668],{"class":802},[747,29524,29525,29528,29530],{"class":749,"line":4958},[747,29526,29527],{"class":753},"    ready",[747,29529,856],{"class":757},[747,29531,1340],{"class":859},[747,29533,29534,29537,29539],{"class":749,"line":4964},[747,29535,29536],{"class":753},"    restartCount",[747,29538,856],{"class":757},[747,29540,7863],{"class":1895},[747,29542,29543,29546],{"class":749,"line":4970},[747,29544,29545],{"class":753},"    state",[747,29547,758],{"class":757},[747,29549,29550,29553],{"class":749,"line":4998},[747,29551,29552],{"class":753},"      terminated",[747,29554,758],{"class":757},[747,29556,29557,29560,29562],{"class":749,"line":5016},[747,29558,29559],{"class":753},"        containerID",[747,29561,856],{"class":757},[747,29563,29486],{"class":802},[747,29565,29566,29569,29571],{"class":749,"line":5048},[747,29567,29568],{"class":753},"        exitCode",[747,29570,856],{"class":757},[747,29572,7863],{"class":1895},[747,29574,29575,29578,29580,29582,29585],{"class":749,"line":5077},[747,29576,29577],{"class":753},"        finishedAt",[747,29579,856],{"class":757},[747,29581,969],{"class":757},[747,29583,29584],{"class":802},"2019-05-04T18:02:34Z",[747,29586,975],{"class":757},[747,29588,29589,29592,29594],{"class":749,"line":5098},[747,29590,29591],{"class":753},"        reason",[747,29593,856],{"class":757},[747,29595,29596],{"class":802}," Completed\n",[747,29598,29599,29602,29604,29606,29608],{"class":749,"line":5121},[747,29600,29601],{"class":753},"        startedAt",[747,29603,856],{"class":757},[747,29605,969],{"class":757},[747,29607,29584],{"class":802},[747,29609,975],{"class":757},[747,29611,29612,29615,29617,29619,29622],{"class":749,"line":5127},[747,29613,29614],{"class":753},"  hostIP",[747,29616,856],{"class":757},[747,29618,4262],{"class":757},[747,29620,29621],{"class":802},"IP OF NODE REMOVED",[747,29623,4268],{"class":757},[747,29625,29626,29629,29631],{"class":749,"line":5133},[747,29627,29628],{"class":753},"  phase",[747,29630,856],{"class":757},[747,29632,29633],{"class":802}," Succeeded\n",[747,29635,29636,29639,29641],{"class":749,"line":5139},[747,29637,29638],{"class":753},"  podIP",[747,29640,856],{"class":757},[747,29642,29643],{"class":1895}," 100.67.92.19\n",[747,29645,29646,29649,29651],{"class":749,"line":5164},[747,29647,29648],{"class":753},"  qosClass",[747,29650,856],{"class":757},[747,29652,29653],{"class":802}," BestEffort\n",[747,29655,29656,29659,29661,29663,29665],{"class":749,"line":5205},[747,29657,29658],{"class":753},"  startTime",[747,29660,856],{"class":757},[747,29662,969],{"class":757},[747,29664,29284],{"class":802},[747,29666,975],{"class":757},[523,29668,29669,10548,29672,29674,29675,29677,29678,29680],{},[3049,29670,29671],{},"Don't worry be happy",[567,29673,28694],{}," output shows \"every field\" of this Pod object named ",[567,29676,3649],{}," (e.g., the ",[567,29679,29251],{}," part\u002F structure is generated by Kubernetes). You don't need to provide all of them, only a (small) handful of the specifications.",[523,29682,29683],{},"A Pod is Kubernetes' logical unit of workload, which consists of one or more containers which will all run in the same Node. All containers of a Pod share the same process and network context, and volumes (for data) between each other.\nBesides that a Pod has one IP address (+ localhost).",[6072,29685,29686,29690],{},[523,29687,29688],{},[584,29689,6189],{},[523,29691,29692,29693,29695,29696,29700,29701,29712],{},"If at any point you need help with Kubernetes object and\u002F or ",[567,29694,15269],{}," cli, please look into the ",[527,29697,29699],{"href":29698},"#kubessar","Kubessar"," and\u002F or ",[527,29702,29704,29706,29707,29711],{"href":29703},"#kubectl-our-tool-to-catch-deploy-them-all",[567,29705,15269],{}," - Our tool to ",[29708,29709,29710],"del",{},"catch"," deploy them all"," sections for information.",[3126,29714,29716],{"id":29715},"pod-no-not-the-band","Pod - \"No, not the band\"",[6072,29718,29719],{},[523,29720,29721,8939,29723],{},[584,29722,2951],{},[527,29724,29727],{"href":29725,"rel":29726},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-container-docker-kubernetes\u002Ftree\u002Fmaster\u002Fkubernetes101",[531],[567,29728,29729],{},"kubernetes101",[523,29731,29732,29733,29735,29736,7258],{},"A simple nginx Pod object which will run a ",[567,29734,9530],{}," container with the port 80 exposed inside the cluster looks like this (file ",[567,29737,29738],{},"nginx.yaml",[738,29740,29742],{"className":740,"code":29741,"language":742,"meta":743,"style":743},"apiVersion: v1\nkind: Pod\nmetadata:\n  labels:\n    app.kubernetes.io\u002Fname: nginx\n  name: nginx\nspec:\n  containers:\n  - image: nginx:1.15.12\n    name: nginx\n    env:\n    - name: MY_ENV_VAR\n      value: \"Hello World!\"\n    ports:\n    - containerPort: 80\n      name: http\n      protocol: TCP\n",[567,29743,29744,29752,29760,29766,29772,29782,29790,29796,29802,29813,29821,29828,29839,29852,29858,29870,29879],{"__ignoreMap":743},[747,29745,29746,29748,29750],{"class":749,"line":750},[747,29747,12949],{"class":753},[747,29749,856],{"class":757},[747,29751,22608],{"class":802},[747,29753,29754,29756,29758],{"class":749,"line":761},[747,29755,12963],{"class":753},[747,29757,856],{"class":757},[747,29759,28795],{"class":802},[747,29761,29762,29764],{"class":749,"line":769},[747,29763,12973],{"class":753},[747,29765,758],{"class":757},[747,29767,29768,29770],{"class":749,"line":776},[747,29769,25378],{"class":753},[747,29771,758],{"class":757},[747,29773,29774,29777,29779],{"class":749,"line":784},[747,29775,29776],{"class":753},"    app.kubernetes.io\u002Fname",[747,29778,856],{"class":757},[747,29780,29781],{"class":802}," nginx\n",[747,29783,29784,29786,29788],{"class":749,"line":790},[747,29785,12980],{"class":753},[747,29787,856],{"class":757},[747,29789,29781],{"class":802},[747,29791,29792,29794],{"class":749,"line":796},[747,29793,12990],{"class":753},[747,29795,758],{"class":757},[747,29797,29798,29800],{"class":749,"line":806},[747,29799,28907],{"class":753},[747,29801,758],{"class":757},[747,29803,29804,29806,29808,29810],{"class":749,"line":814},[747,29805,1721],{"class":757},[747,29807,3702],{"class":753},[747,29809,856],{"class":757},[747,29811,29812],{"class":802}," nginx:1.15.12\n",[747,29814,29815,29817,29819],{"class":749,"line":822},[747,29816,24402],{"class":753},[747,29818,856],{"class":757},[747,29820,29781],{"class":802},[747,29822,29823,29826],{"class":749,"line":830},[747,29824,29825],{"class":753},"    env",[747,29827,758],{"class":757},[747,29829,29830,29832,29834,29836],{"class":749,"line":836},[747,29831,18665],{"class":757},[747,29833,14804],{"class":753},[747,29835,856],{"class":757},[747,29837,29838],{"class":802}," MY_ENV_VAR\n",[747,29840,29841,29844,29846,29848,29850],{"class":749,"line":842},[747,29842,29843],{"class":753},"      value",[747,29845,856],{"class":757},[747,29847,969],{"class":757},[747,29849,3650],{"class":802},[747,29851,975],{"class":757},[747,29853,29854,29856],{"class":749,"line":850},[747,29855,10991],{"class":753},[747,29857,758],{"class":757},[747,29859,29860,29862,29865,29867],{"class":749,"line":863},[747,29861,18665],{"class":757},[747,29863,29864],{"class":753}," containerPort",[747,29866,856],{"class":757},[747,29868,29869],{"class":1895}," 80\n",[747,29871,29872,29874,29876],{"class":749,"line":869},[747,29873,925],{"class":753},[747,29875,856],{"class":757},[747,29877,29878],{"class":802}," http\n",[747,29880,29881,29883,29885],{"class":749,"line":877},[747,29882,25904],{"class":753},[747,29884,856],{"class":757},[747,29886,25576],{"class":802},[523,29888,29889],{},"Splitting the YAML into multiple parts to get a better grasp of what what means and which parts are \"more\" important.",[523,29891,29892],{},"An object no matter if it is a Kubernetes \"in-built\" or custom defined ones, will always consist of:",[668,29894,29895,29900,29911,29921],{},[638,29896,29897,29899],{},[567,29898,12949],{},": The (API) version of the object API to use.",[638,29901,29902,29904,29905,714,29907,714,29909,3052],{},[567,29903,12963],{},": \"Type\" of the object (e.g., ",[567,29906,25722],{},[567,29908,22320],{},[567,29910,25331],{},[638,29912,29913,29915,29916,1909],{},[567,29914,12973],{},": Basic information about an object, see next section, ",[527,29917,29919],{"href":29918},"#metadata",[567,29920,12973],{},[638,29922,29923,29925,29926,13314],{},[567,29924,12990],{},": Specifications for the ",[567,29927,25722],{},[523,29929,29930,29931,29933],{},"There are more parts to a ",[567,29932,25722],{}," object, but there are .",[3142,29935,29936],{"id":12973},[567,29937,12973],{},[668,29939,29940,29951,29967,29977],{},[638,29941,29942,29945,29946,1909],{},[567,29943,29944],{},"annotations",": Key\u002F Value pairs with information you do not need to select the objects by; ",[527,29947,29950],{"href":29948,"rel":29949},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Foverview\u002Fworking-with-objects\u002Fannotations\u002F",[531],"Kubernetes - Annotations",[638,29952,29953,29956,29957,29961,29962,1909],{},[567,29954,29955],{},"labels",": Labels of the object (key-value pairs). You can select objects based on labels (",[527,29958,29960],{"href":29959},"#getting-listing-objects-using-label-selectors","label selector","); ",[527,29963,29966],{"href":29964,"rel":29965},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Foverview\u002Fworking-with-objects\u002Flabels\u002F",[531],"Kubernetes - Labels",[638,29968,29969,29971,29972,1909],{},[567,29970,5472],{},": Name of the object; ",[527,29973,29976],{"href":29974,"rel":29975},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Foverview\u002Fworking-with-objects\u002Fnames\u002F",[531],"Kubernetes - Names",[638,29978,29979,29982,29983,1909],{},[567,29980,29981],{},"namespace",": This is only available when the object (API) is namespaced, allows to separate objects name-wise from each other; ",[527,29984,29987],{"href":29985,"rel":29986},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Foverview\u002Fworking-with-objects\u002Fnamespaces\u002F",[531],"Kubernetes - Namespaces",[3142,29989,29991,29993],{"id":29990},"spec-and-others",[567,29992,12990],{}," and others",[523,29995,29996,29997,2006],{},"(\"others\" = e.g., ",[567,29998,29251],{},[523,30000,30001,30002,3052],{},"This is the part which is always different per object and also potentially different per API version (",[567,30003,12949],{},[523,30005,30006,30007,30010,30011,1909],{},"To know how each object in itself looks, please refer to the Kubernetes API reference for your Kubernetes cluster version (",[567,30008,30009],{},"kubectl version","): ",[527,30012,30015],{"href":30013,"rel":30014},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Freference\u002F",[531],"Kubernetes - Reference",[6072,30017,30018],{},[523,30019,30020],{},[584,30021,2957],{},[668,30023,30024],{},[638,30025,30026,30029,30030],{},[567,30027,30028],{},"spec.containers",": List of containers to run in this Pod (more is not good, just create more Pods).\n",[668,30031,30032,30037,30042,30068],{},[638,30033,30034,30036],{},[567,30035,23878],{},": Container image name\u002F URL to run.",[638,30038,30039,30041],{},[567,30040,5472],{},": Name of the container.",[638,30043,30044,30047,30048],{},[567,30045,30046],{},"env",": Environment variables to add to the container.\n",[668,30049,30050,30055],{},[638,30051,30052,30054],{},[567,30053,5472],{},": Name of the environment variable.",[638,30056,30057,30060,30061,30064,30065,30067],{},[567,30058,30059],{},"value",": Value of the environment variable. In an upcoming section we will look into dynamically using so called ",[567,30062,30063],{},"ConfigMap","s and ",[567,30066,23097],{}," for the configuration of your application.",[638,30069,30070,30073,30074],{},[567,30071,30072],{},"ports",": List of ports to \"open\" on the container.\n",[668,30075,30076,30082,30087],{},[638,30077,30078,30081],{},[567,30079,30080],{},"containerPort",": Port on the container.",[638,30083,30084,30086],{},[567,30085,5472],{},": \"Human\" name for the port.",[638,30088,30089,30092,30093,6374,30096,5193,30099,3052],{},[567,30090,30091],{},"protocol",": Protocol of the port, either ",[567,30094,30095],{},"TCP",[567,30097,30098],{},"UDP",[567,30100,30095],{},[523,30102,30103,30104,30106,30107,27143],{},"That is a very basic ",[567,30105,25722],{}," YAML structure, you can do much more as shown in the ",[527,30108,30110],{"href":30109},"#so-what-has-kubernetes-to-offer-features-of-kubernetes","Kubernetes features",[3126,30112,15410],{"id":15409},[523,30114,30115,30116,30118,30119,587,30122,30125],{},"Namespaces in Kubernetes are exactly what the name implies, a space for names. Meaning that most objects in Kubernetes are namespaced.\nMeaning that you can have a ",[567,30117,25722],{}," object in Namespace ",[567,30120,30121],{},"abc",[567,30123,30124],{},"xyz"," with the same name.",[523,30127,30128,30129,714,30131,714,30133,714,30135,714,30137,714,30139,30141],{},"Same goes for other objects, besides Pods, in Kubernetes, e.g., ",[567,30130,25331],{},[567,30132,25729],{},[567,30134,26766],{},[567,30136,27758],{},[567,30138,25167],{},[567,30140,30063],{}," and many more.",[6072,30143,30144,30148],{},[523,30145,30146],{},[584,30147,6189],{},[523,30149,30150],{},"In Kubernetes there are no sub-Namespaces and also no sub-sub-Namespaces, sub-sub-sub-sub-Namespaces. Keep that in mind when naming them.\nI would recommend you to create a Namespace naming schema in some way for your Kubernetes cluster(s) in your company\u002F organisation.",[613,30152,30154],{"id":30153},"lets-run-wordpress-on-kubernetes","Let's run WordPress on Kubernetes",[523,30156,30157],{},[3069,30158],{"alt":30159,"src":30160},"WordPress Logo","\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day2\u002Flogo-wordpress-bg-medblue.png",[523,30162,30163],{},"What do we need for WordPress? Some storage for our attachments and a MySQL database. Nothing easier than that.",[523,30165,30166],{},"Before jumping further into the magical world of Kubernetes objects in form of YAML structures, let's look at the \"requirements\" for WordPress (no redundancy yet) from a Kubernetes feature perspective.",[6072,30168,30169],{},[523,30170,30171],{},[584,30172,2957],{},[668,30174,30175,30207,30217],{},[638,30176,30177,30178,30180,30181,9661,30183],{},"We want to run a MySQL database ",[567,30179,25722],{}," and WordPress ",[567,30182,25722],{},[668,30184,30185,30188],{},[638,30186,30187],{},"We want to keep it running no matter what is going in the Kubernetes cluster (e.g., a node failure).",[638,30189,30190,30191,30193,30194,30196,30197,30199,30200,30202,30203,27143],{},"=> ",[567,30192,25331],{}," - Keeps X instances\u002F ",[567,30195,18111],{}," of a defined ",[567,30198,25722],{}," template running. The ",[567,30201,25722],{}," template contains the same information as seen in the above ",[527,30204,30206],{"href":30205},"#let-s-look-at-the-pod","Let's look at the \"Pod\"",[638,30208,30209,30210],{},"MySQL should be reachable under the same name and\u002F or IP address at all times.\n",[668,30211,30212],{},[638,30213,30190,30214,30216],{},[567,30215,25729],{}," - Causes an IP to be \"allocated\" and made reachable from within the Kubernetes cluster (Pods), and DNS records.",[638,30218,30219,30220],{},"WordPress should be exposed to the \"public\".\n",[668,30221,30222],{},[638,30223,30190,30224,30226,30227,30229,30230,714,30235,1909],{},[567,30225,158],{}," - Exposes a HTTP application to the Internet, which is \"selected\" through a ",[567,30228,25729],{}," object. This is done through a so called Kubernetes Ingress Controller, which is running, e.g., ",[527,30231,30234],{"href":30232,"rel":30233},"https:\u002F\u002Fnginx.org\u002F",[531],"NGINX",[527,30236,30239],{"href":30237,"rel":30238},"https:\u002F\u002Ftraefik.io\u002F",[531],"Traefik",[523,30241,30242],{},"We now know the Kubernetes objects we need to get a MySQL database and the WordPress running.",[523,30244,30245,30248,30249,1909],{},[584,30246,30247],{},"Let's begin ticking off each part of the list!"," Starting with the ",[527,30250,30252],{"href":30251},"#mysql-database","MySQL Database",[3126,30254,30256],{"id":30255},"running-the-mysql-database","Running the MySQL Database",[523,30258,30259],{},[584,30260,14231,30261,30263],{},[567,30262,25722],{}," in itself does not have any means of being \"recreated\" when it has been deleted.",[523,30265,30266,30267,30270,30271,30273,30274,30277,30278,30280,30281,30283,30284,30286],{},"That is where objects like ",[567,30268,30269],{},"Deployments"," (+ ",[567,30272,26766],{},") and ",[567,30275,30276],{},"StatefulSet"," come into play.\nWe start with a ",[567,30279,25331],{}," object which we can tell to always keep X instances (",[567,30282,18111],{},") of our defined \"",[567,30285,25722],{}," template\".",[6072,30288,30289,30293],{},[523,30290,30291],{},[584,30292,6189],{},[523,30294,30295],{},"For now we leave high availability of the MySQL database Pod out of the picture.",[523,30297,30298,30299,30301,30302,30304],{},"The \"",[567,30300,25722],{}," template\" is basically the \"same\" as a ",[567,30303,25722],{},", but with a few fields\u002F structures left out. These left out fields\u002F structures are \"templated\" by the Deployment object automatically.",[523,30306,30307,30308,30310,30311,30313,30314,30316,30317,30319,30320,30322,30323,30325,30326,30328,30329,30331,30332,30335,30336,30338,30339,30341,30342,30344,30345,30347,30348,30350],{},"When you create a ",[567,30309,25331],{},", a so called ",[567,30312,26766],{}," object is created automatically. The ",[567,30315,26766],{}," created is the current state of the ",[567,30318,25331],{},". Means that if the ",[567,30321,25331],{}," is updated (e.g., a new ",[567,30324,23878],{}," is used for a container in the ",[567,30327,25722],{}," template), a new ",[567,30330,26766],{}," is created (there is a limit of ",[567,30333,30334],{},"10"," by default, they are deleted automatically).\nIf you delete a ",[567,30337,25722],{}," that is part of the ",[567,30340,25331],{},", the ",[567,30343,26766],{}," \"magic\" in the background create a new ",[567,30346,25722],{}," to fullfill the wanted ",[567,30349,18111],{}," count.",[6072,30352,30353],{},[523,30354,30355,8939,30357,19221,30364],{},[584,30356,2951],{},[527,30358,30361],{"href":30359,"rel":30360},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-container-docker-kubernetes\u002Ftree\u002Fmaster\u002Fkubernetes202",[531],[567,30362,30363],{},"kubernetes202",[567,30365,30366],{},"mysql.yaml",[738,30368,30373],{"className":740,"code":30369,"filename":30370,"highlights":30371,"language":742,"meta":743,"style":743},"apiVersion: apps\u002Fv1\nkind: Deployment\nmetadata:\n  name: mysql\n  labels:\n    app.kubernetes.io\u002Fname: mysql\n    app.kubernetes.io\u002Fpart-of: wordpress\nspec:\n  selector:\n    matchLabels:\n      app.kubernetes.io\u002Fname: mysql\n      app.kubernetes.io\u002Fpart-of: wordpress\n  template:\n    metadata:\n      labels:\n        app.kubernetes.io\u002Fname: mysql\n        app.kubernetes.io\u002Fpart-of: wordpress\n    spec:\n      containers:\n      - image: mysql:5.6\n        name: mysql\n        env:\n        - name: MYSQL_ROOT_PASSWORD\n          value: changeme\n        ports:\n        - containerPort: 3306\n          name: mysql\n          protocol: TCP\n","\"13-28\"",[30372],0,[567,30374,30375,30383,30391,30397,30405,30411,30419,30428,30434,30440,30446,30455,30464,30470,30476,30482,30491,30500,30506,30512,30523,30532,30539,30550,30560,30566,30577,30586],{"__ignoreMap":743},[747,30376,30377,30379,30381],{"class":749,"line":750},[747,30378,12949],{"class":753},[747,30380,856],{"class":757},[747,30382,25349],{"class":802},[747,30384,30385,30387,30389],{"class":749,"line":761},[747,30386,12963],{"class":753},[747,30388,856],{"class":757},[747,30390,25358],{"class":802},[747,30392,30393,30395],{"class":749,"line":769},[747,30394,12973],{"class":753},[747,30396,758],{"class":757},[747,30398,30399,30401,30403],{"class":749,"line":776},[747,30400,12980],{"class":753},[747,30402,856],{"class":757},[747,30404,11146],{"class":802},[747,30406,30407,30409],{"class":749,"line":784},[747,30408,25378],{"class":753},[747,30410,758],{"class":757},[747,30412,30413,30415,30417],{"class":749,"line":790},[747,30414,29776],{"class":753},[747,30416,856],{"class":757},[747,30418,11146],{"class":802},[747,30420,30421,30424,30426],{"class":749,"line":796},[747,30422,30423],{"class":753},"    app.kubernetes.io\u002Fpart-of",[747,30425,856],{"class":757},[747,30427,6540],{"class":802},[747,30429,30430,30432],{"class":749,"line":806},[747,30431,12990],{"class":753},[747,30433,758],{"class":757},[747,30435,30436,30438],{"class":749,"line":814},[747,30437,25430],{"class":753},[747,30439,758],{"class":757},[747,30441,30442,30444],{"class":749,"line":822},[747,30443,25437],{"class":753},[747,30445,758],{"class":757},[747,30447,30448,30451,30453],{"class":749,"line":830},[747,30449,30450],{"class":753},"      app.kubernetes.io\u002Fname",[747,30452,856],{"class":757},[747,30454,11146],{"class":802},[747,30456,30457,30460,30462],{"class":749,"line":836},[747,30458,30459],{"class":753},"      app.kubernetes.io\u002Fpart-of",[747,30461,856],{"class":757},[747,30463,6540],{"class":802},[747,30465,30466,30468],{"class":749,"line":842},[747,30467,25462],{"class":753},[747,30469,758],{"class":757},[747,30471,30472,30474],{"class":749,"line":850},[747,30473,21456],{"class":753},[747,30475,758],{"class":757},[747,30477,30478,30480],{"class":749,"line":863},[747,30479,25475],{"class":753},[747,30481,758],{"class":757},[747,30483,30484,30487,30489],{"class":749,"line":869},[747,30485,30486],{"class":753},"        app.kubernetes.io\u002Fname",[747,30488,856],{"class":757},[747,30490,11146],{"class":802},[747,30492,30493,30496,30498],{"class":749,"line":877},[747,30494,30495],{"class":753},"        app.kubernetes.io\u002Fpart-of",[747,30497,856],{"class":757},[747,30499,6540],{"class":802},[747,30501,30502,30504],{"class":749,"line":1015},[747,30503,25509],{"class":753},[747,30505,758],{"class":757},[747,30507,30508,30510],{"class":749,"line":1021},[747,30509,25516],{"class":753},[747,30511,758],{"class":757},[747,30513,30514,30516,30518,30520],{"class":749,"line":1027},[747,30515,799],{"class":757},[747,30517,3702],{"class":753},[747,30519,856],{"class":757},[747,30521,30522],{"class":802}," mysql:5.6\n",[747,30524,30525,30528,30530],{"class":749,"line":1033},[747,30526,30527],{"class":753},"        name",[747,30529,856],{"class":757},[747,30531,11146],{"class":802},[747,30533,30534,30537],{"class":749,"line":1039},[747,30535,30536],{"class":753},"        env",[747,30538,758],{"class":757},[747,30540,30541,30543,30545,30547],{"class":749,"line":1054},[747,30542,14801],{"class":757},[747,30544,14804],{"class":753},[747,30546,856],{"class":757},[747,30548,30549],{"class":802}," MYSQL_ROOT_PASSWORD\n",[747,30551,30552,30555,30557],{"class":749,"line":1060},[747,30553,30554],{"class":753},"          value",[747,30556,856],{"class":757},[747,30558,30559],{"class":802}," changeme\n",[747,30561,30562,30564],{"class":749,"line":1066},[747,30563,25553],{"class":753},[747,30565,758],{"class":757},[747,30567,30568,30570,30572,30574],{"class":749,"line":1081},[747,30569,14801],{"class":757},[747,30571,29864],{"class":753},[747,30573,856],{"class":757},[747,30575,30576],{"class":1895}," 3306\n",[747,30578,30579,30582,30584],{"class":749,"line":1087},[747,30580,30581],{"class":753},"          name",[747,30583,856],{"class":757},[747,30585,11146],{"class":802},[747,30587,30588,30590,30592],{"class":749,"line":1102},[747,30589,25571],{"class":753},[747,30591,856],{"class":757},[747,30593,25576],{"class":802},[523,30595,30596,30597,714,30599,587,30601,30603],{},"As previosuly talked about ",[567,30598,12949],{},[567,30600,12963],{},[567,30602,12973],{}," are for identifying the object.",[523,30605,8764,30606,30608],{},[567,30607,12990],{}," structure contains the following info:",[6072,30610,30611],{},[523,30612,30613],{},[584,30614,2957],{},[668,30616,30617,30634],{},[638,30618,30619,30622,30623,30625,30626,30628,30629,3052],{},[567,30620,30621],{},"selector",": The selector to \"find\" the Pods spawned from the ",[567,30624,25331],{}," (through the ",[567,30627,26766],{},"; ",[527,30630,30633],{"href":30631,"rel":30632},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fworkloads\u002Fcontrollers\u002Fdeployment\u002F#rollover-aka-multiple-updates-in-flight",[531],"Kubernetes - Deployments - Selector Information",[638,30635,30636,30639,30640,30642,30643,30649,30650,30652],{},[567,30637,30638],{},"template",": This is the \"Pod\" ",[567,30641,30638],{}," structure previosuly written about, see ",[527,30644,30646,30647],{"href":30645},"#pod-no-not-the-band","example ",[567,30648,25722],{}," for how a ",[567,30651,25722],{}," object looks.",[523,30654,30655],{},"All these fields\u002F structures are important for the Deployment, but there are tools to have this and the other objects tempalted to reduce Time-to-Deploy (TtD).",[6072,30657,30658,30662],{},[523,30659,30660],{},[584,30661,6189],{},[523,30663,30664,30665,30667,30668,30670],{},"Don't run a ",[567,30666,15269],{}," command on the ",[567,30669,30366],{}," file yet.",[3126,30672,30674],{"id":30673},"configuring-the-mysql-server","Configuring the MySQL server",[523,30676,30677,30678,30681,30682,30684,30685,856],{},"In the above ",[527,30679,30680],{"href":30645},"Pod - “No, not the band”"," section, a ",[567,30683,25722],{}," object was shown with a section called ",[567,30686,30687],{},"env:",[738,30689,30693],{"className":740,"code":30690,"filename":30691,"highlights":30692,"language":742,"meta":743,"style":743},"[...]\nspec:\n  containers:\n[...]\n    env:\n    - name: MY_ENV_VAR\n      value: \"Hello World!\"\n[...]\n","\"5-7\"",[30372],[567,30694,30695,30703,30709,30715,30723,30729,30739,30751],{"__ignoreMap":743},[747,30696,30697,30699,30701],{"class":749,"line":750},[747,30698,4253],{"class":757},[747,30700,5685],{"class":1895},[747,30702,4268],{"class":757},[747,30704,30705,30707],{"class":749,"line":761},[747,30706,12990],{"class":753},[747,30708,758],{"class":757},[747,30710,30711,30713],{"class":749,"line":769},[747,30712,28907],{"class":753},[747,30714,758],{"class":757},[747,30716,30717,30719,30721],{"class":749,"line":776},[747,30718,4253],{"class":757},[747,30720,5685],{"class":1895},[747,30722,4268],{"class":757},[747,30724,30725,30727],{"class":749,"line":784},[747,30726,29825],{"class":753},[747,30728,758],{"class":757},[747,30730,30731,30733,30735,30737],{"class":749,"line":790},[747,30732,18665],{"class":757},[747,30734,14804],{"class":753},[747,30736,856],{"class":757},[747,30738,29838],{"class":802},[747,30740,30741,30743,30745,30747,30749],{"class":749,"line":796},[747,30742,29843],{"class":753},[747,30744,856],{"class":757},[747,30746,969],{"class":757},[747,30748,3650],{"class":802},[747,30750,975],{"class":757},[747,30752,30753,30755,30757],{"class":749,"line":806},[747,30754,4253],{"class":757},[747,30756,5685],{"class":1895},[747,30758,4268],{"class":757},[523,30760,8336,30761,30763,30764,30064,30766,30768],{},[584,30762,2957],{}," section, it was explained that those variables are added to the container as environment variables, so your application can consume them.\nTo have a better separation between the actual definition of your Pod's containers, we are looking into ",[567,30765,30063],{},[567,30767,25167],{},"s now.",[523,30770,30771,587,30774,30776,30777,29700,30779,30781,30782,29700,30784,30786,30787,30790],{},[567,30772,30773],{},"ConfigMaps",[567,30775,23097],{}," are basically objects to have key-value pairs of \"data\" in them. They can be used to provide applications with configuration\u002F secrets.\nAn important part to mention is that if you edit a ",[567,30778,30063],{},[567,30780,25167],{}," object and have a key set as an environment variable for a Pod, the environment variable is never updated due to limitations in environment variable handling for processes.\nOn the other hand if you have mounted a ",[567,30783,30063],{},[567,30785,25167],{}," object, the mount will be updated (at latest after 1 minute, configurable) in the Pods, this means that you can \"",[567,30788,30789],{},"inotify","\" on your config file(s) and then reload dynamically.",[3142,30792,30794],{"id":30793},"configmap",[567,30795,30063],{},[523,30797,30798,30799,30801,30802,30805,30806,30809,30810,30813,30814,30817,30818,30820,30821,587,30823,30825,30826,30828],{},"This is an example of a ",[567,30800,30063],{},". It has two keys defined in it, one named ",[567,30803,30804],{},"MY_API_SERVICE_ADDRESS"," with a single line string value and a second one ",[567,30807,30808],{},"config.yaml"," which is a multi-line string.\nEspecially for the second key, it would make sense to mount this key as a file. This is possible by specifying the list of keys (",[567,30811,30812],{},"items",") in the ",[567,30815,30816],{},"volumeMounts"," list. Meaning that if you added such an entry the ",[567,30819,30808],{}," would be available inside the Pod's container for your application to read from, like anyother file (",[567,30822,30063],{},[567,30824,25167],{}," keys mounted are read-only!).\nThe ",[567,30827,30816],{}," list, is the list of given volumes to mount to a container in a Pod, more on that in an upcoming section.",[6072,30830,30831],{},[523,30832,30833,8939,30835,19221,30840],{},[584,30834,2951],{},[527,30836,30838],{"href":29725,"rel":30837},[531],[567,30839,29729],{},[567,30841,30842],{},"configmap.yaml",[738,30844,30846],{"className":740,"code":30845,"language":742,"meta":743,"style":743},"apiVersion: v1\ndata:\n  # You can have multiple key-value pairs in one `ConfigMap`\n  MY_API_SERVICE_ADDRESS: https:\u002F\u002Fmy-api-service.example.com\n  # You can specify which keys of a `ConfigMap` to mount in a Pod\n  config.yaml: |\n    database:\n      host: broker\n      port: 5234\n      username: root\n      # Will be read from the environment by the application reading the `config.yaml`\n      password: ${DB_USER}\nkind: ConfigMap\nmetadata:\n  labels:\n    app.kubernetes.io\u002Fname: my-app\n  name: my-config\n",[567,30847,30848,30856,30863,30868,30878,30883,30892,30897,30902,30907,30912,30917,30922,30931,30937,30943,30952],{"__ignoreMap":743},[747,30849,30850,30852,30854],{"class":749,"line":750},[747,30851,12949],{"class":753},[747,30853,856],{"class":757},[747,30855,22608],{"class":802},[747,30857,30858,30861],{"class":749,"line":761},[747,30859,30860],{"class":753},"data",[747,30862,758],{"class":757},[747,30864,30865],{"class":749,"line":769},[747,30866,30867],{"class":772},"  # You can have multiple key-value pairs in one `ConfigMap`\n",[747,30869,30870,30873,30875],{"class":749,"line":776},[747,30871,30872],{"class":753},"  MY_API_SERVICE_ADDRESS",[747,30874,856],{"class":757},[747,30876,30877],{"class":802}," https:\u002F\u002Fmy-api-service.example.com\n",[747,30879,30880],{"class":749,"line":784},[747,30881,30882],{"class":772},"  # You can specify which keys of a `ConfigMap` to mount in a Pod\n",[747,30884,30885,30888,30890],{"class":749,"line":790},[747,30886,30887],{"class":753},"  config.yaml",[747,30889,856],{"class":757},[747,30891,24697],{"class":19332},[747,30893,30894],{"class":749,"line":796},[747,30895,30896],{"class":802},"    database:\n",[747,30898,30899],{"class":749,"line":806},[747,30900,30901],{"class":802},"      host: broker\n",[747,30903,30904],{"class":749,"line":814},[747,30905,30906],{"class":802},"      port: 5234\n",[747,30908,30909],{"class":749,"line":822},[747,30910,30911],{"class":802},"      username: root\n",[747,30913,30914],{"class":749,"line":830},[747,30915,30916],{"class":802},"      # Will be read from the environment by the application reading the `config.yaml`\n",[747,30918,30919],{"class":749,"line":836},[747,30920,30921],{"class":802},"      password: ${DB_USER}\n",[747,30923,30924,30926,30928],{"class":749,"line":842},[747,30925,12963],{"class":753},[747,30927,856],{"class":757},[747,30929,30930],{"class":802}," ConfigMap\n",[747,30932,30933,30935],{"class":749,"line":850},[747,30934,12973],{"class":753},[747,30936,758],{"class":757},[747,30938,30939,30941],{"class":749,"line":863},[747,30940,25378],{"class":753},[747,30942,758],{"class":757},[747,30944,30945,30947,30949],{"class":749,"line":869},[747,30946,29776],{"class":753},[747,30948,856],{"class":757},[747,30950,30951],{"class":802}," my-app\n",[747,30953,30954,30956,30958],{"class":749,"line":877},[747,30955,12980],{"class":753},[747,30957,856],{"class":757},[747,30959,30960],{"class":802}," my-config\n",[523,30962,30963,30964,30966,30967,30970,30971,30974],{},"If you want to, you can copy the contents of the ",[567,30965,30063],{}," example and run ",[567,30968,30969],{},"kubectl create -f FILE_NAME"," on it. After that you can use ",[567,30972,30973],{},"kubectl get configmap NAME -o yaml"," to look at it in the Kubernetes API.",[3142,30976,30978],{"id":30977},"secret",[567,30979,25167],{},[523,30981,14231,30982,30984],{},[567,30983,25167],{}," is only base64 encoded, so it is not so secret as the name implies. You can however encrypt the data inside the \"brain of the Kubernetes cluster\".",[6072,30986,30987],{},[523,30988,30989,8939,30991,19221,30996],{},[584,30990,2951],{},[527,30992,30994],{"href":29725,"rel":30993},[531],[567,30995,29729],{},[567,30997,30998],{},"secret.yaml",[523,31000,31001,31002,31005,31006,856],{},"The example below has a single key-value pair, named ",[567,31003,31004],{},"DB_PASSWORD"," with the base64 encoded value ",[567,31007,31008],{},"kubernetesiscool",[738,31010,31012],{"className":740,"code":31011,"language":742,"meta":743,"style":743},"apiVersion: v1\ndata:\n  # `Secret` values are base64 encoded right now.\n  DB_PASSWORD: a3ViZXJuZXRlc2lzY29vbA==\nkind: Secret\nmetadata:\n  labels:\n    app.kubernetes.io\u002Fname: my-app\n  name: my-app\ntype: Opaque\n",[567,31013,31014,31022,31028,31033,31043,31051,31057,31063,31071,31079],{"__ignoreMap":743},[747,31015,31016,31018,31020],{"class":749,"line":750},[747,31017,12949],{"class":753},[747,31019,856],{"class":757},[747,31021,22608],{"class":802},[747,31023,31024,31026],{"class":749,"line":761},[747,31025,30860],{"class":753},[747,31027,758],{"class":757},[747,31029,31030],{"class":749,"line":769},[747,31031,31032],{"class":772},"  # `Secret` values are base64 encoded right now.\n",[747,31034,31035,31038,31040],{"class":749,"line":776},[747,31036,31037],{"class":753},"  DB_PASSWORD",[747,31039,856],{"class":757},[747,31041,31042],{"class":802}," a3ViZXJuZXRlc2lzY29vbA==\n",[747,31044,31045,31047,31049],{"class":749,"line":784},[747,31046,12963],{"class":753},[747,31048,856],{"class":757},[747,31050,23233],{"class":802},[747,31052,31053,31055],{"class":749,"line":790},[747,31054,12973],{"class":753},[747,31056,758],{"class":757},[747,31058,31059,31061],{"class":749,"line":796},[747,31060,25378],{"class":753},[747,31062,758],{"class":757},[747,31064,31065,31067,31069],{"class":749,"line":806},[747,31066,29776],{"class":753},[747,31068,856],{"class":757},[747,31070,30951],{"class":802},[747,31072,31073,31075,31077],{"class":749,"line":814},[747,31074,12980],{"class":753},[747,31076,856],{"class":757},[747,31078,30951],{"class":802},[747,31080,31081,31083,31085],{"class":749,"line":822},[747,31082,23273],{"class":753},[747,31084,856],{"class":757},[747,31086,31087],{"class":802}," Opaque\n",[523,31089,31090,31091,31093],{},"You can as for a ",[567,31092,30063],{}," mount specify which keys to mount in a Pod's containers, which will be covered now.",[523,31095,30963,31096,30966,31098,30970,31100,30974],{},[567,31097,25167],{},[567,31099,30969],{},[567,31101,31102],{},"kubectl get secret NAME -o yaml",[3142,31104,31106,31107,587,31109],{"id":31105},"moving-the-mysql-configuration-to-a-configmap-and-secret","Moving the MySQL configuration to a ",[567,31108,30063],{},[567,31110,25167],{},[6072,31112,31113,31117],{},[523,31114,31115],{},[584,31116,6189],{},[523,31118,31119,31120,587,31122,31124,31125,587,31127,31129,31130,31132],{},"Mounting a ",[567,31121,30063],{},[567,31123,25167],{}," will be a topic for later on. For this section we'll just use values from a ",[567,31126,30063],{},[567,31128,25167],{}," as environment variables of the example MySQL ",[567,31131,25331],{}," object here.",[738,31134,31136],{"className":740,"code":31135,"language":742,"meta":743,"style":743},"apiVersion: v1\ndata:\n  MYSQL_ALLOW_EMPTY_PASSWORD: \"off\"\nkind: ConfigMap\nmetadata:\n  labels:\n    app.kubernetes.io\u002Fname: mysql\n    app.kubernetes.io\u002Fpart-of: wordpress\n  name: mysql-config\n---\napiVersion: v1\ndata:\n  MYSQL_ROOT_PASSWORD: Y2hhbmdlbWU=\nkind: Secret\nmetadata:\n  labels:\n    app.kubernetes.io\u002Fname: mysql\n    app.kubernetes.io\u002Fpart-of: wordpress\n  name: mysql-secret\ntype: Opaque\n---\napiVersion: apps\u002Fv1\nkind: Deployment\nmetadata:\n  name: mysql\n  labels:\n    app.kubernetes.io\u002Fname: mysql\n    app.kubernetes.io\u002Fpart-of: wordpress\n[...]\nspec:\n[...]\n  selector:\n    matchLabels:\n      app.kubernetes.io\u002Fname: mysql\n      app.kubernetes.io\u002Fpart-of: wordpress\n  template:\n[...]\n    spec:\n      containers:\n      - image: mysql:5.6\n        name: mysql\n        # Two ways possible:\n        ## 1. If we want to mount specific keys from the `Secret` or `ConfigMap`:\n        env:\n        ### For `Secret`\n        - name: MYSQL_ROOT_PASSWORD\n          valueFrom:\n            secretKeyRef:\n              name: mysql-secret\n              key: MYSQL_ROOT_PASSWORD\n        ### For `ConfigMap`\n        - name: MYSQL_ALLOW_EMPTY_PASSWORD\n          valueFrom:\n            configMapKeyRef:\n              name: mysql-config\n              key: MYSQL_ALLOW_EMPTY_PASSWORD\n        ## 2. If we want to add all keys (which are all uppercase) of a `Secret` or `ConfigMap` as environment variables we can use:\n        envFrom:\n        ### For `Secret`\n        - secretRef:\n            name: mysql-secret\n        ### For `ConfigMap`\n        - configMapRef:\n            name: mysql-config\n[...]\n",[567,31137,31138,31146,31152,31166,31174,31180,31186,31194,31202,31211,31215,31223,31229,31239,31247,31253,31259,31267,31275,31284,31292,31296,31304,31312,31318,31326,31332,31340,31348,31356,31362,31370,31376,31382,31390,31398,31404,31412,31418,31424,31434,31442,31447,31452,31458,31463,31473,31480,31487,31496,31505,31510,31521,31527,31534,31542,31550,31555,31562,31566,31575,31584,31588,31597,31605],{"__ignoreMap":743},[747,31139,31140,31142,31144],{"class":749,"line":750},[747,31141,12949],{"class":753},[747,31143,856],{"class":757},[747,31145,22608],{"class":802},[747,31147,31148,31150],{"class":749,"line":761},[747,31149,30860],{"class":753},[747,31151,758],{"class":757},[747,31153,31154,31157,31159,31161,31164],{"class":749,"line":769},[747,31155,31156],{"class":753},"  MYSQL_ALLOW_EMPTY_PASSWORD",[747,31158,856],{"class":757},[747,31160,969],{"class":757},[747,31162,31163],{"class":802},"off",[747,31165,975],{"class":757},[747,31167,31168,31170,31172],{"class":749,"line":776},[747,31169,12963],{"class":753},[747,31171,856],{"class":757},[747,31173,30930],{"class":802},[747,31175,31176,31178],{"class":749,"line":784},[747,31177,12973],{"class":753},[747,31179,758],{"class":757},[747,31181,31182,31184],{"class":749,"line":790},[747,31183,25378],{"class":753},[747,31185,758],{"class":757},[747,31187,31188,31190,31192],{"class":749,"line":796},[747,31189,29776],{"class":753},[747,31191,856],{"class":757},[747,31193,11146],{"class":802},[747,31195,31196,31198,31200],{"class":749,"line":806},[747,31197,30423],{"class":753},[747,31199,856],{"class":757},[747,31201,6540],{"class":802},[747,31203,31204,31206,31208],{"class":749,"line":814},[747,31205,12980],{"class":753},[747,31207,856],{"class":757},[747,31209,31210],{"class":802}," mysql-config\n",[747,31212,31213],{"class":749,"line":822},[747,31214,12808],{"class":1630},[747,31216,31217,31219,31221],{"class":749,"line":830},[747,31218,12949],{"class":753},[747,31220,856],{"class":757},[747,31222,22608],{"class":802},[747,31224,31225,31227],{"class":749,"line":836},[747,31226,30860],{"class":753},[747,31228,758],{"class":757},[747,31230,31231,31234,31236],{"class":749,"line":842},[747,31232,31233],{"class":753},"  MYSQL_ROOT_PASSWORD",[747,31235,856],{"class":757},[747,31237,31238],{"class":802}," Y2hhbmdlbWU=\n",[747,31240,31241,31243,31245],{"class":749,"line":850},[747,31242,12963],{"class":753},[747,31244,856],{"class":757},[747,31246,23233],{"class":802},[747,31248,31249,31251],{"class":749,"line":863},[747,31250,12973],{"class":753},[747,31252,758],{"class":757},[747,31254,31255,31257],{"class":749,"line":869},[747,31256,25378],{"class":753},[747,31258,758],{"class":757},[747,31260,31261,31263,31265],{"class":749,"line":877},[747,31262,29776],{"class":753},[747,31264,856],{"class":757},[747,31266,11146],{"class":802},[747,31268,31269,31271,31273],{"class":749,"line":1015},[747,31270,30423],{"class":753},[747,31272,856],{"class":757},[747,31274,6540],{"class":802},[747,31276,31277,31279,31281],{"class":749,"line":1021},[747,31278,12980],{"class":753},[747,31280,856],{"class":757},[747,31282,31283],{"class":802}," mysql-secret\n",[747,31285,31286,31288,31290],{"class":749,"line":1027},[747,31287,23273],{"class":753},[747,31289,856],{"class":757},[747,31291,31087],{"class":802},[747,31293,31294],{"class":749,"line":1033},[747,31295,12808],{"class":1630},[747,31297,31298,31300,31302],{"class":749,"line":1039},[747,31299,12949],{"class":753},[747,31301,856],{"class":757},[747,31303,25349],{"class":802},[747,31305,31306,31308,31310],{"class":749,"line":1054},[747,31307,12963],{"class":753},[747,31309,856],{"class":757},[747,31311,25358],{"class":802},[747,31313,31314,31316],{"class":749,"line":1060},[747,31315,12973],{"class":753},[747,31317,758],{"class":757},[747,31319,31320,31322,31324],{"class":749,"line":1066},[747,31321,12980],{"class":753},[747,31323,856],{"class":757},[747,31325,11146],{"class":802},[747,31327,31328,31330],{"class":749,"line":1081},[747,31329,25378],{"class":753},[747,31331,758],{"class":757},[747,31333,31334,31336,31338],{"class":749,"line":1087},[747,31335,29776],{"class":753},[747,31337,856],{"class":757},[747,31339,11146],{"class":802},[747,31341,31342,31344,31346],{"class":749,"line":1102},[747,31343,30423],{"class":753},[747,31345,856],{"class":757},[747,31347,6540],{"class":802},[747,31349,31350,31352,31354],{"class":749,"line":1110},[747,31351,4253],{"class":757},[747,31353,5685],{"class":1895},[747,31355,4268],{"class":757},[747,31357,31358,31360],{"class":749,"line":1117},[747,31359,12990],{"class":753},[747,31361,758],{"class":757},[747,31363,31364,31366,31368],{"class":749,"line":1123},[747,31365,4253],{"class":757},[747,31367,5685],{"class":1895},[747,31369,4268],{"class":757},[747,31371,31372,31374],{"class":749,"line":1129},[747,31373,25430],{"class":753},[747,31375,758],{"class":757},[747,31377,31378,31380],{"class":749,"line":1142},[747,31379,25437],{"class":753},[747,31381,758],{"class":757},[747,31383,31384,31386,31388],{"class":749,"line":1150},[747,31385,30450],{"class":753},[747,31387,856],{"class":757},[747,31389,11146],{"class":802},[747,31391,31392,31394,31396],{"class":749,"line":1157},[747,31393,30459],{"class":753},[747,31395,856],{"class":757},[747,31397,6540],{"class":802},[747,31399,31400,31402],{"class":749,"line":1163},[747,31401,25462],{"class":753},[747,31403,758],{"class":757},[747,31405,31406,31408,31410],{"class":749,"line":1168},[747,31407,4253],{"class":757},[747,31409,5685],{"class":1895},[747,31411,4268],{"class":757},[747,31413,31414,31416],{"class":749,"line":1174},[747,31415,25509],{"class":753},[747,31417,758],{"class":757},[747,31419,31420,31422],{"class":749,"line":1480},[747,31421,25516],{"class":753},[747,31423,758],{"class":757},[747,31425,31426,31428,31430,31432],{"class":749,"line":1491},[747,31427,799],{"class":757},[747,31429,3702],{"class":753},[747,31431,856],{"class":757},[747,31433,30522],{"class":802},[747,31435,31436,31438,31440],{"class":749,"line":1496},[747,31437,30527],{"class":753},[747,31439,856],{"class":757},[747,31441,11146],{"class":802},[747,31443,31444],{"class":749,"line":1502},[747,31445,31446],{"class":772},"        # Two ways possible:\n",[747,31448,31449],{"class":749,"line":1510},[747,31450,31451],{"class":772},"        ## 1. If we want to mount specific keys from the `Secret` or `ConfigMap`:\n",[747,31453,31454,31456],{"class":749,"line":1520},[747,31455,30536],{"class":753},[747,31457,758],{"class":757},[747,31459,31460],{"class":749,"line":1525},[747,31461,31462],{"class":772},"        ### For `Secret`\n",[747,31464,31465,31467,31469,31471],{"class":749,"line":1533},[747,31466,14801],{"class":757},[747,31468,14804],{"class":753},[747,31470,856],{"class":757},[747,31472,30549],{"class":802},[747,31474,31475,31478],{"class":749,"line":1539},[747,31476,31477],{"class":753},"          valueFrom",[747,31479,758],{"class":757},[747,31481,31482,31485],{"class":749,"line":1549},[747,31483,31484],{"class":753},"            secretKeyRef",[747,31486,758],{"class":757},[747,31488,31489,31492,31494],{"class":749,"line":1554},[747,31490,31491],{"class":753},"              name",[747,31493,856],{"class":757},[747,31495,31283],{"class":802},[747,31497,31498,31501,31503],{"class":749,"line":1562},[747,31499,31500],{"class":753},"              key",[747,31502,856],{"class":757},[747,31504,30549],{"class":802},[747,31506,31507],{"class":749,"line":1568},[747,31508,31509],{"class":772},"        ### For `ConfigMap`\n",[747,31511,31512,31514,31516,31518],{"class":749,"line":1577},[747,31513,14801],{"class":757},[747,31515,14804],{"class":753},[747,31517,856],{"class":757},[747,31519,31520],{"class":802}," MYSQL_ALLOW_EMPTY_PASSWORD\n",[747,31522,31523,31525],{"class":749,"line":1582},[747,31524,31477],{"class":753},[747,31526,758],{"class":757},[747,31528,31529,31532],{"class":749,"line":1588},[747,31530,31531],{"class":753},"            configMapKeyRef",[747,31533,758],{"class":757},[747,31535,31536,31538,31540],{"class":749,"line":1594},[747,31537,31491],{"class":753},[747,31539,856],{"class":757},[747,31541,31210],{"class":802},[747,31543,31544,31546,31548],{"class":749,"line":1600},[747,31545,31500],{"class":753},[747,31547,856],{"class":757},[747,31549,31520],{"class":802},[747,31551,31552],{"class":749,"line":4804},[747,31553,31554],{"class":772},"        ## 2. If we want to add all keys (which are all uppercase) of a `Secret` or `ConfigMap` as environment variables we can use:\n",[747,31556,31557,31560],{"class":749,"line":4810},[747,31558,31559],{"class":753},"        envFrom",[747,31561,758],{"class":757},[747,31563,31564],{"class":749,"line":4816},[747,31565,31462],{"class":772},[747,31567,31568,31570,31573],{"class":749,"line":4822},[747,31569,14801],{"class":757},[747,31571,31572],{"class":753}," secretRef",[747,31574,758],{"class":757},[747,31576,31577,31580,31582],{"class":749,"line":4828},[747,31578,31579],{"class":753},"            name",[747,31581,856],{"class":757},[747,31583,31283],{"class":802},[747,31585,31586],{"class":749,"line":4834},[747,31587,31509],{"class":772},[747,31589,31590,31592,31595],{"class":749,"line":4840},[747,31591,14801],{"class":757},[747,31593,31594],{"class":753}," configMapRef",[747,31596,758],{"class":757},[747,31598,31599,31601,31603],{"class":749,"line":4846},[747,31600,31579],{"class":753},[747,31602,856],{"class":757},[747,31604,31210],{"class":802},[747,31606,31607,31609,31611],{"class":749,"line":4852},[747,31608,4253],{"class":757},[747,31610,5685],{"class":1895},[747,31612,4268],{"class":757},[523,31614,31615,31616,31619,31620,18054,31622,550,31624,31626,31627,31630],{},"For the first method, this would take the given ",[567,31617,31618],{},"key","(s) from the ",[567,31621,30063],{},[567,31623,25167],{},[567,31625,5472],{}," and add that value under the environment variable name to the container of the Pod.\nThe ",[567,31628,31629],{},"envFrom"," method, will do the same but simply add all keys (which are all uppercase) to the container of the Pod as environment variables.",[523,31632,31633,31634,587,31636,31638,31639,29700,31641,31643],{},"As fine-grained that you can specify which keys of a ",[567,31635,30063],{},[567,31637,25167],{}," to be available as environment variables, is also possible for mounting keys into a Pod. They will be mounted as files directly.\nWhen mounted and the ",[567,31640,30063],{},[567,31642,25167],{}," is updated, the content of the mounted keys is also updated (will take at maximum one minute after the change to have propagated to each node).",[523,31645,31646],{},"Now that we know about configuration of Pods, let's move on to making the MySQL server available as a \"Service\" in the Kubernetes cluster.",[3126,31648,31650],{"id":31649},"making-the-mysql-server-available-as-a-service","Making the MySQL server available as a \"Service\"",[523,31652,31653,31654,31656,31657,31660],{},"In Kubernetes there are ",[567,31655,25729],{}," objects, which allow to select one or more ",[567,31658,31659],{},"Pods"," based on labels and \"group\" them behind \"one\" cluster wide reachable IP and a DNS record for it.",[523,31662,31663,31664,31666,31667,31669,31670,31672,31673,31675,31676,31678,31679,31681],{},"Meaning that if we were to run a web application through a ",[567,31665,25331],{},", we would create a ",[567,31668,25729],{}," selecting the application ",[567,31671,31659],{}," based on the labels. That would allow any application in the cluster (also an Ingress controller), to access the web application through one IP address\u002F DNS name.\nWithout ",[567,31674,26989],{}," in Kubernetes you would need to talk to a ",[567,31677,25722],{}," IP address directly, meaning that if the Pod is deleted and a new one is started that the IP address can be different. Having such one IP address and DNS name, allows for DNS based service discovery and dynamically extending an application behind that ",[567,31680,25729],{}," without \"anyone\" noticing.",[6072,31683,31684],{},[523,31685,31686,8939,31688,19221,31693],{},[584,31687,2951],{},[527,31689,31691],{"href":30359,"rel":31690},[531],[567,31692,30363],{},[567,31694,30366],{},[523,31696,14231,31697,31699],{},[567,31698,25729],{}," object looks like that:",[738,31701,31705],{"className":740,"code":31702,"filename":31703,"highlights":31704,"language":742,"meta":743,"style":743},"apiVersion: v1\nkind: Service\nmetadata:\n  name: mysql\n  labels:\n    app.kubernetes.io\u002Fname: mysql\n    app.kubernetes.io\u002Fpart-of: wordpress\nspec:\n  ports:\n    - name: mysql\n      port: 3306\n      protocol: TCP\n  selector:\n    app.kubernetes.io\u002Fname: mysql\n    app.kubernetes.io\u002Fpart-of: wordpress\n  type: ClusterIP\n","\"9-16\"",[30372],[567,31706,31707,31715,31723,31729,31737,31743,31751,31759,31765,31771,31781,31789,31797,31803,31811,31819],{"__ignoreMap":743},[747,31708,31709,31711,31713],{"class":749,"line":750},[747,31710,12949],{"class":753},[747,31712,856],{"class":757},[747,31714,22608],{"class":802},[747,31716,31717,31719,31721],{"class":749,"line":761},[747,31718,12963],{"class":753},[747,31720,856],{"class":757},[747,31722,25758],{"class":802},[747,31724,31725,31727],{"class":749,"line":769},[747,31726,12973],{"class":753},[747,31728,758],{"class":757},[747,31730,31731,31733,31735],{"class":749,"line":776},[747,31732,12980],{"class":753},[747,31734,856],{"class":757},[747,31736,11146],{"class":802},[747,31738,31739,31741],{"class":749,"line":784},[747,31740,25378],{"class":753},[747,31742,758],{"class":757},[747,31744,31745,31747,31749],{"class":749,"line":790},[747,31746,29776],{"class":753},[747,31748,856],{"class":757},[747,31750,11146],{"class":802},[747,31752,31753,31755,31757],{"class":749,"line":796},[747,31754,30423],{"class":753},[747,31756,856],{"class":757},[747,31758,6540],{"class":802},[747,31760,31761,31763],{"class":749,"line":806},[747,31762,12990],{"class":753},[747,31764,758],{"class":757},[747,31766,31767,31769],{"class":749,"line":814},[747,31768,25878],{"class":753},[747,31770,758],{"class":757},[747,31772,31773,31775,31777,31779],{"class":749,"line":822},[747,31774,18665],{"class":757},[747,31776,14804],{"class":753},[747,31778,856],{"class":757},[747,31780,11146],{"class":802},[747,31782,31783,31785,31787],{"class":749,"line":830},[747,31784,25895],{"class":753},[747,31786,856],{"class":757},[747,31788,30576],{"class":1895},[747,31790,31791,31793,31795],{"class":749,"line":836},[747,31792,25904],{"class":753},[747,31794,856],{"class":757},[747,31796,25576],{"class":802},[747,31798,31799,31801],{"class":749,"line":842},[747,31800,25430],{"class":753},[747,31802,758],{"class":757},[747,31804,31805,31807,31809],{"class":749,"line":850},[747,31806,29776],{"class":753},[747,31808,856],{"class":757},[747,31810,11146],{"class":802},[747,31812,31813,31815,31817],{"class":749,"line":863},[747,31814,30423],{"class":753},[747,31816,856],{"class":757},[747,31818,6540],{"class":802},[747,31820,31821,31823,31825],{"class":749,"line":869},[747,31822,18593],{"class":753},[747,31824,856],{"class":757},[747,31826,25873],{"class":802},[6072,31828,31829,31833],{},[523,31830,31831],{},[584,31832,2957],{},[523,31834,31835,31836,31838],{},"Focusing on the ",[567,31837,12990],{}," part here.",[668,31840,31841,31897,31904],{},[638,31842,31843,31845,31846],{},[567,31844,30072],{},": List of ports.\n",[668,31847,31848,31853,31862,31876],{},[638,31849,31850,31852],{},[567,31851,5472],{},": Name of the port.",[638,31854,31855,31858,31859,31861],{},[567,31856,31857],{},"port",": Port on the ",[567,31860,25729],{}," that should be \"exposed\" inside the Kubernetes cluster.",[638,31863,31864,8939,31866,6374,31868,31870,31871,31873,31874,3052],{},[567,31865,30091],{},[567,31867,30095],{},[567,31869,30098],{}," (there are other protocols but \"only\" for other ",[567,31872,23273],{},"s of ",[567,31875,25729],{},[638,31877,31878,31881,31882,587,31885,31888,31889,31892,31893,31896],{},[567,31879,31880],{},"targetPort",": Optional. Allows to use a different port on the Pod side (e.g., ",[567,31883,31884],{},"port: 80",[567,31886,31887],{},"targetPort: 8080",", will cause traffic on the Service on port ",[567,31890,31891],{},"80"," to be \"redirected\" to port ",[567,31894,31895],{},"8080"," on the Pods).",[638,31898,31899,31901,31902,1909],{},[567,31900,30621],{},": A label selector . With that you can select Pods based on their labels for the ",[567,31903,25729],{},[638,31905,31906,31908,31909,31911],{},[567,31907,23273],{},": Optional. ",[567,31910,26993],{}," (default), what that means will be looked into detail in a second.",[523,31913,31914,31915,23273,31918,31920],{},"Now we look into the last mentioned field ",[567,31916,31917],{},"type. There are multiple ",[567,31919,25723],{},"Service`, which allow for different \"publishing\"\u002F exposition of one or more Pods inside and\u002F or outside of the Kubernetes cluster.",[523,31922,31923],{},"We'll scratch a network topic already with that but the actual in-deep look will be done later on.",[6072,31925,31926,31930],{},[523,31927,31928],{},[584,31929,6189],{},[523,31931,31932,31933,31935,31936,31938,31939,31941],{},"For most software defined networks that can be used with Kubernetes a Service IP is not pingable! Only the ports in the ",[567,31934,25729],{}," objects are \"connected\" to the ",[567,31937,31659],{}," that the ",[567,31940,25729],{}," is selecting.",[3142,31943,31945],{"id":31944},"clusterip",[567,31946,26993],{},[6072,31948,31949],{},[523,31950,31951,31952],{},"\"Exposes the service on a cluster-internal IP. Choosing this value makes the service only reachable from within the cluster. This is the default ServiceType.\"\n– Taken from ",[527,31953,31956],{"href":31954,"rel":31955},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fservices-networking\u002Fservice\u002F#publishing-services-service-types",[531],"Kubernetes - Services: ClusterIP",[523,31958,31959,31960,8287,31962,31964],{},"This is the most commonly used ",[567,31961,25729],{},[567,31963,23273],{},". A cluster-interally reachable IP address and a DNS name, for services inside the Kubernetes cluster to use.",[3142,31966,31968],{"id":31967},"nodeport",[567,31969,15315],{},[6072,31971,31972],{},[523,31973,31974,31975,31977,31978,31980,31981,31983,31984,31986,31987,31990,31991],{},"\"Exposes the service on each Node’s IP at a static port (the ",[567,31976,15315],{},"). A ",[567,31979,26993],{}," service, to which the ",[567,31982,15315],{}," service will route, is automatically created. You’ll be able to contact the ",[567,31985,15315],{}," service, from outside the cluster, by requesting ",[567,31988,31989],{},"\u003CNodeIP>:\u003CNodePort>",".\"\n– Taken from ",[527,31992,31995],{"href":31993,"rel":31994},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fservices-networking\u002Fservice\u002F#nodeport",[531],"Kubernetes - Services: NodePort",[523,31997,31998,31999,32001,32002,32004,32005,32008,32009,32011],{},"Is a ",[567,32000,26993],{}," service, so an IP address and DNS name is allocated, but for this ",[567,32003,26993],{}," a port is opened on all Nodes of the cluster (changeable, ",[567,32006,32007],{},"trafficPolicy","). The port is from the so called ",[567,32010,15315],{}," Port range.",[3142,32013,32015],{"id":32014},"loadbalancer",[567,32016,15282],{},[6072,32018,32019],{},[523,32020,32021,32022,587,32024,32026,32027],{},"\"Exposes the service externally using a cloud provider’s load balancer. ",[567,32023,15315],{},[567,32025,26993],{}," services, to which the external load balancer will route, are automatically created.\"\n– Taken from ",[527,32028,32031],{"href":32029,"rel":32030},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fservices-networking\u002Fservice\u002F#loadbalancer",[531],"Kubernetes - Services: LoadBalancer",[523,32033,31998,32034,32036,32037,32039],{},[567,32035,15315],{}," service which has the ",[567,32038,15315],{},"(s) exposed through a Cloud load balancer. This is possible for certain cloud providers\u002F environments (e.g., AWS, Google Cloud, OpenStack, and more).",[3142,32041,32043],{"id":32042},"externalname",[567,32044,32045],{},"ExternalName",[6072,32047,32048],{},[523,32049,32050,32051,32054,32055,32058,32059,32062,32063,31990,32066],{},"\"Maps the service to the contents of the ",[567,32052,32053],{},"externalName"," field (e.g. ",[567,32056,32057],{},"foo.bar.example.com","), by returning a ",[567,32060,32061],{},"CNAME"," record with its value. No proxying of any kind is set up. This requires version 1.7 or higher of ",[567,32064,32065],{},"kube-dns",[527,32067,32070],{"href":32068,"rel":32069},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fservices-networking\u002Fservice\u002F#externalname",[531],"Kubernetes - Services: ExternalName",[523,32072,14231,32073,32075],{},[567,32074,32061],{},"for an external name (no proxying).",[3126,32077,32079,32081],{"id":32078},"service-dns-name-naming",[567,32080,25729],{}," DNS Name Naming",[523,32083,32084,32085,32087,32088,22542,32090,32092],{},"Let's say we have a ",[567,32086,25729],{}," named ",[567,32089,6744],{},[567,32091,2014],{}," namespace. This is the cluster-internal DNS name schema:",[738,32094,32098],{"className":32095,"code":32096,"language":32097,"meta":743,"style":743},"language-ini shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","NAME.NAMESPACE.svc.cluster.local\n","ini",[567,32099,32100],{"__ignoreMap":743},[747,32101,32102],{"class":749,"line":750},[747,32103,32096],{"class":1640},[523,32105,32106,32107,32109],{},"Which means for our ",[567,32108,25729],{}," this is its full name:",[738,32111,32113],{"className":32095,"code":32112,"language":32097,"meta":743,"style":743},"wordpress.default.svc.cluster.local\n",[567,32114,32115],{"__ignoreMap":743},[747,32116,32117],{"class":749,"line":750},[747,32118,32112],{"class":1640},[523,32120,8764,32121,32123,32124,1909],{},[567,32122,23638],{}," is a customizable cluster-wide DNS prefix. I would recommend you to leave it as ",[567,32125,23638],{},[523,32127,32128,32129,32132,32133,32136,32137,32139,32140,32142,32143,32145,32146,32149,32150,32153,32154,32156,32157,32159],{},"Please note that for the DNS resolution ",[567,32130,32131],{},"search"," parameters are set in the ",[567,32134,32135],{},"resolv.conf"," mounted inside the Pod's containers.\nMeaning that if a Pod in the namespace ",[567,32138,2014],{}," wants to access the ",[567,32141,6744],{}," Service, it can just use ",[567,32144,6744],{}," for the DNS name.\nBut a Pod from the namespace ",[567,32147,32148],{},"workshop",", must use at least the following DNS name ",[567,32151,32152],{},"mysql.default.svc"," to access the ",[567,32155,6744],{}," Service in the ",[567,32158,2014],{}," namespace.",[3126,32161,32163],{"id":32162},"storage-for-our-precious-mysql-database","Storage for our precious MySQL database",[523,32165,32166],{},[3049,32167,32168],{},"Insert Lord of the Rings Gollumn \"My precious data\" Meme",[523,32170,32171,32172,32177,32178,2006],{},"(Taken from ",[527,32173,32176],{"href":32174,"rel":32175},"https:\u002F\u002Ftechcrunch.com\u002F2018\u002F09\u002F23\u002Four-precious\u002F",[531],"TechCrunch | Our Precious",", owned by ",[527,32179,32182],{"href":32180,"rel":32181},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FJ._R._R._Tolkien",[531],"J.R.R. Tolkien",[523,32184,32185,32186,32188,32189,32191,32192,32194],{},"Right now if the MySQL database Pod is deleted all data in it would be lost.\nWe don't want that to happen, so we are going to put storage in the Pod. This is done using ",[567,32187,27758],{},"s. A ",[567,32190,27758],{}," is a way to \"request\"\u002F \"claim\" X amount of storage for an application.\nThis is mostly used with dynamically provisioned storage, where the Kubernetes storage in some way is talking to a storage software\u002F system to create ",[567,32193,18374],{},"s on-demand when the user needs them.",[6072,32196,32197],{},[523,32198,32199,8939,32201,19221,32206],{},[584,32200,2951],{},[527,32202,32204],{"href":30359,"rel":32203},[531],[567,32205,30363],{},[567,32207,30366],{},[523,32209,14231,32210,32212],{},[567,32211,27758],{}," looks like this:",[738,32214,32216],{"className":740,"code":32215,"language":742,"meta":743,"style":743},"apiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: mysql\n  labels:\n    app.kubernetes.io\u002Fname: mysql\n    app.kubernetes.io\u002Fpart-of: wordpress\nspec:\n  storageClassName: rook-ceph-block\n  accessModes:\n  - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n",[567,32217,32218,32226,32235,32241,32249,32255,32263,32271,32277,32287,32294,32301,32307,32314],{"__ignoreMap":743},[747,32219,32220,32222,32224],{"class":749,"line":750},[747,32221,12949],{"class":753},[747,32223,856],{"class":757},[747,32225,22608],{"class":802},[747,32227,32228,32230,32232],{"class":749,"line":761},[747,32229,12963],{"class":753},[747,32231,856],{"class":757},[747,32233,32234],{"class":802}," PersistentVolumeClaim\n",[747,32236,32237,32239],{"class":749,"line":769},[747,32238,12973],{"class":753},[747,32240,758],{"class":757},[747,32242,32243,32245,32247],{"class":749,"line":776},[747,32244,12980],{"class":753},[747,32246,856],{"class":757},[747,32248,11146],{"class":802},[747,32250,32251,32253],{"class":749,"line":784},[747,32252,25378],{"class":753},[747,32254,758],{"class":757},[747,32256,32257,32259,32261],{"class":749,"line":790},[747,32258,29776],{"class":753},[747,32260,856],{"class":757},[747,32262,11146],{"class":802},[747,32264,32265,32267,32269],{"class":749,"line":796},[747,32266,30423],{"class":753},[747,32268,856],{"class":757},[747,32270,6540],{"class":802},[747,32272,32273,32275],{"class":749,"line":806},[747,32274,12990],{"class":753},[747,32276,758],{"class":757},[747,32278,32279,32282,32284],{"class":749,"line":814},[747,32280,32281],{"class":753},"  storageClassName",[747,32283,856],{"class":757},[747,32285,32286],{"class":802}," rook-ceph-block\n",[747,32288,32289,32292],{"class":749,"line":822},[747,32290,32291],{"class":753},"  accessModes",[747,32293,758],{"class":757},[747,32295,32296,32298],{"class":749,"line":830},[747,32297,1721],{"class":757},[747,32299,32300],{"class":802}," ReadWriteOnce\n",[747,32302,32303,32305],{"class":749,"line":836},[747,32304,22712],{"class":753},[747,32306,758],{"class":757},[747,32308,32309,32312],{"class":749,"line":842},[747,32310,32311],{"class":753},"    requests",[747,32313,758],{"class":757},[747,32315,32316,32319,32321],{"class":749,"line":850},[747,32317,32318],{"class":753},"      storage",[747,32320,856],{"class":757},[747,32322,32323],{"class":802}," 5Gi\n",[523,32325,32326],{},"I hope it is looking pretty straight forward to you.",[6072,32328,32329,32333,32342],{},[523,32330,32331],{},[584,32332,6189],{},[523,32334,32335,32336,32341],{},"In the provided cluster there is a ",[527,32337,32340],{"href":32338,"rel":32339},"https:\u002F\u002Frook.io",[531],"Rook Ceph cluster"," running which is running Ceph in the Kubernetes cluster and dynamically provides storage for the Kubernetes cluster.\nKeep that in mind when trying in other Kubernetes cluster, besides the provided ones.",[523,32343,32344],{},[584,32345,2957],{},[668,32347,32348,32362,32383],{},[638,32349,32350,32353,32354,32357,32358,32361],{},[567,32351,32352],{},"storageClassName",": There are ",[567,32355,32356],{},"StorageClass","es in Kubernetes which can hold different ",[567,32359,32360],{},"parameters"," which are given to the dynamic storage volume provisioner.",[638,32363,32364,32367,32368,714,32371,587,32374,32377,32378,1909],{},[567,32365,32366],{},"accessModes",": There are three different access modes for volumes. ",[567,32369,32370],{},"ReadWriteOnce",[567,32372,32373],{},"ReadOnlyMany",[567,32375,32376],{},"ReadWriteMany",", these boil down to \"mount once\", \"many mounts for read\" and \"many mounts for write \" see ",[527,32379,32382],{"href":32380,"rel":32381},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fstorage\u002Fpersistent-volumes\u002F#access-modes",[531],"Kubernetes - Persistent Volumes - Access Modes",[638,32384,32385,32388,32389],{},[567,32386,32387],{},"resources",": Resource spec.\n",[668,32390,32391],{},[638,32392,32393,32396],{},[567,32394,32395],{},"requests",[668,32397,32398],{},[638,32399,32400,32402,32403,32405,32406,32409,32410,714,32412,714,32415,32418],{},[567,32401,11626],{},": The (minimum) size of the storage for the ",[567,32404,18374],{}," to create. Can be just a number (",[567,32407,32408],{},"Mi","), ",[567,32411,32408],{},[567,32413,32414],{},"Gi",[567,32416,32417],{},"Ti"," and so on.",[523,32420,32421,32422,32424,32425,32427,32428,32430,32431,32433,32434,32436,32437,32439,32440,32442],{},"For the Pod from the ",[567,32423,25331],{}," to use this ",[567,32426,27758],{}," is to add an entry to the ",[567,32429,11175],{}," list of the Pod, and for the container(s) to consume it then an entry to the ",[567,32432,30816],{}," list.\nThe names probably make it clear that the ",[567,32435,11175],{}," list the actual list of volumes that will be added to the Pod and the ",[567,32438,30816],{}," are then the points where the ",[567,32441,11175],{}," are mounted inside the container(s) of the Pod.",[523,32444,32445,32446,32448,32449,32452,32453,32456,32457,32459,32460,32462],{},"Save the ",[567,32447,27758],{}," as ",[567,32450,32451],{},"mysql-pvc.yaml"," and run ",[567,32454,32455],{},"kubectl create -f mysql-pvc.yaml"," on the file (from the master server).\nThe ",[567,32458,25255],{}," should respond back with a message that a ",[567,32461,27758],{}," has been created (no errors).",[523,32464,32465,32466,32468,32469,32471],{},"Now that we have a ",[567,32467,27758],{}," \"claiming\" storage for the MySQL Pod, we just need to add that to the ",[567,32470,25331],{}," object that it will mount and use the storage.",[6072,32473,32474,32486,32490],{},[523,32475,32476,8939,32478,19221,32483],{},[584,32477,2951],{},[527,32479,32481],{"href":30359,"rel":32480},[531],[567,32482,30363],{},[567,32484,32485],{},"mysql-with-storage.yaml",[523,32487,32488],{},[584,32489,6189],{},[523,32491,32492,32493,18054,32495,32497,32498,32500,32501,32504],{},"Have you previoulsy ran ",[567,32494,25255],{},[567,32496,18053],{}," on ",[567,32499,30366],{},"? Please run ",[567,32502,32503],{},"kubectl delete -f mysql.yaml"," to remove the objects first before continuing.",[523,32506,32507,32508,32510],{},"MySQL Deployment example with ",[567,32509,27758],{}," for the storage:",[738,32512,32516],{"className":740,"code":32513,"filename":32514,"highlights":32515,"language":742,"meta":743,"style":743},"apiVersion: apps\u002Fv1\nkind: Deployment\nmetadata:\n  name: mysql\n  labels:\n    app.kubernetes.io\u002Fname: mysql\n    app.kubernetes.io\u002Fpart-of: wordpress\nspec:\n  selector:\n    matchLabels:\n      app.kubernetes.io\u002Fname: mysql\n      app.kubernetes.io\u002Fpart-of: wordpress\n  strategy:\n    type: Recreate\n  template:\n    metadata:\n      labels:\n        app.kubernetes.io\u002Fname: mysql\n        app.kubernetes.io\u002Fpart-of: wordpress\n    spec:\n      containers:\n      - image: mysql:5.6\n        name: mysql\n        env:\n        - name: MYSQL_ROOT_PASSWORD\n          value: changeme\n        ports:\n        - containerPort: 3306\n          name: mysql\n        volumeMounts:\n        - name: mysql\n          mountPath: \u002Fvar\u002Flib\u002Fmysql\n      volumes:\n      - name: mysql\n        persistentVolumeClaim:\n          claimName: mysql\n","\"28-34\"",[30372],[567,32517,32518,32526,32534,32540,32548,32554,32562,32570,32576,32582,32588,32596,32604,32611,32620,32626,32632,32638,32646,32654,32660,32666,32676,32684,32690,32700,32708,32714,32724,32732,32739,32749,32759,32766,32776,32783],{"__ignoreMap":743},[747,32519,32520,32522,32524],{"class":749,"line":750},[747,32521,12949],{"class":753},[747,32523,856],{"class":757},[747,32525,25349],{"class":802},[747,32527,32528,32530,32532],{"class":749,"line":761},[747,32529,12963],{"class":753},[747,32531,856],{"class":757},[747,32533,25358],{"class":802},[747,32535,32536,32538],{"class":749,"line":769},[747,32537,12973],{"class":753},[747,32539,758],{"class":757},[747,32541,32542,32544,32546],{"class":749,"line":776},[747,32543,12980],{"class":753},[747,32545,856],{"class":757},[747,32547,11146],{"class":802},[747,32549,32550,32552],{"class":749,"line":784},[747,32551,25378],{"class":753},[747,32553,758],{"class":757},[747,32555,32556,32558,32560],{"class":749,"line":790},[747,32557,29776],{"class":753},[747,32559,856],{"class":757},[747,32561,11146],{"class":802},[747,32563,32564,32566,32568],{"class":749,"line":796},[747,32565,30423],{"class":753},[747,32567,856],{"class":757},[747,32569,6540],{"class":802},[747,32571,32572,32574],{"class":749,"line":806},[747,32573,12990],{"class":753},[747,32575,758],{"class":757},[747,32577,32578,32580],{"class":749,"line":814},[747,32579,25430],{"class":753},[747,32581,758],{"class":757},[747,32583,32584,32586],{"class":749,"line":822},[747,32585,25437],{"class":753},[747,32587,758],{"class":757},[747,32589,32590,32592,32594],{"class":749,"line":830},[747,32591,30450],{"class":753},[747,32593,856],{"class":757},[747,32595,11146],{"class":802},[747,32597,32598,32600,32602],{"class":749,"line":836},[747,32599,30459],{"class":753},[747,32601,856],{"class":757},[747,32603,6540],{"class":802},[747,32605,32606,32609],{"class":749,"line":842},[747,32607,32608],{"class":753},"  strategy",[747,32610,758],{"class":757},[747,32612,32613,32615,32617],{"class":749,"line":850},[747,32614,29315],{"class":753},[747,32616,856],{"class":757},[747,32618,32619],{"class":802}," Recreate\n",[747,32621,32622,32624],{"class":749,"line":863},[747,32623,25462],{"class":753},[747,32625,758],{"class":757},[747,32627,32628,32630],{"class":749,"line":869},[747,32629,21456],{"class":753},[747,32631,758],{"class":757},[747,32633,32634,32636],{"class":749,"line":877},[747,32635,25475],{"class":753},[747,32637,758],{"class":757},[747,32639,32640,32642,32644],{"class":749,"line":1015},[747,32641,30486],{"class":753},[747,32643,856],{"class":757},[747,32645,11146],{"class":802},[747,32647,32648,32650,32652],{"class":749,"line":1021},[747,32649,30495],{"class":753},[747,32651,856],{"class":757},[747,32653,6540],{"class":802},[747,32655,32656,32658],{"class":749,"line":1027},[747,32657,25509],{"class":753},[747,32659,758],{"class":757},[747,32661,32662,32664],{"class":749,"line":1033},[747,32663,25516],{"class":753},[747,32665,758],{"class":757},[747,32667,32668,32670,32672,32674],{"class":749,"line":1039},[747,32669,799],{"class":757},[747,32671,3702],{"class":753},[747,32673,856],{"class":757},[747,32675,30522],{"class":802},[747,32677,32678,32680,32682],{"class":749,"line":1054},[747,32679,30527],{"class":753},[747,32681,856],{"class":757},[747,32683,11146],{"class":802},[747,32685,32686,32688],{"class":749,"line":1060},[747,32687,30536],{"class":753},[747,32689,758],{"class":757},[747,32691,32692,32694,32696,32698],{"class":749,"line":1066},[747,32693,14801],{"class":757},[747,32695,14804],{"class":753},[747,32697,856],{"class":757},[747,32699,30549],{"class":802},[747,32701,32702,32704,32706],{"class":749,"line":1081},[747,32703,30554],{"class":753},[747,32705,856],{"class":757},[747,32707,30559],{"class":802},[747,32709,32710,32712],{"class":749,"line":1087},[747,32711,25553],{"class":753},[747,32713,758],{"class":757},[747,32715,32716,32718,32720,32722],{"class":749,"line":1102},[747,32717,14801],{"class":757},[747,32719,29864],{"class":753},[747,32721,856],{"class":757},[747,32723,30576],{"class":1895},[747,32725,32726,32728,32730],{"class":749,"line":1110},[747,32727,30581],{"class":753},[747,32729,856],{"class":757},[747,32731,11146],{"class":802},[747,32733,32734,32737],{"class":749,"line":1117},[747,32735,32736],{"class":753},"        volumeMounts",[747,32738,758],{"class":757},[747,32740,32741,32743,32745,32747],{"class":749,"line":1123},[747,32742,14801],{"class":757},[747,32744,14804],{"class":753},[747,32746,856],{"class":757},[747,32748,11146],{"class":802},[747,32750,32751,32754,32756],{"class":749,"line":1129},[747,32752,32753],{"class":753},"          mountPath",[747,32755,856],{"class":757},[747,32757,32758],{"class":802}," \u002Fvar\u002Flib\u002Fmysql\n",[747,32760,32761,32764],{"class":749,"line":1142},[747,32762,32763],{"class":753},"      volumes",[747,32765,758],{"class":757},[747,32767,32768,32770,32772,32774],{"class":749,"line":1150},[747,32769,799],{"class":757},[747,32771,14804],{"class":753},[747,32773,856],{"class":757},[747,32775,11146],{"class":802},[747,32777,32778,32781],{"class":749,"line":1157},[747,32779,32780],{"class":753},"        persistentVolumeClaim",[747,32782,758],{"class":757},[747,32784,32785,32788,32790],{"class":749,"line":1163},[747,32786,32787],{"class":753},"          claimName",[747,32789,856],{"class":757},[747,32791,11146],{"class":802},[6072,32793,32794],{},[523,32795,32796],{},[584,32797,2957],{},[668,32799,32800,32819,32840],{},[638,32801,32802,32805,32806,9661,32808],{},[567,32803,32804],{},"strategy",": Strategy to update Pods that are spawned through the ",[567,32807,25331],{},[668,32809,32810],{},[638,32811,32812,32814,32815,32818],{},[567,32813,23273],{},": Strategy name. ",[567,32816,32817],{},"Recreate"," will delete an old Pod first and create a new one afterwards.",[638,32820,32821,32823,32824,32826,32827],{},[567,32822,30816],{},": List of mounts for the ",[567,32825,11175],{}," list.\n",[668,32828,32829,32834],{},[638,32830,32831,32833],{},[567,32832,5472],{},": Name of the volume.",[638,32835,32836,32839],{},[567,32837,32838],{},"mountPath",": The path inside the container to attach the volume to.",[638,32841,32842,32844,32845],{},[567,32843,11175],{},": List of volumes for the Pod's container.\n",[668,32846,32847,32855,32874],{},[638,32848,32849,32851,32852,32854],{},[567,32850,5472],{},": Name of the volume, will be used in the ",[567,32853,30816],{}," list for matching to a volume.",[638,32856,32857,32860,32861,9661,32863],{},[567,32858,32859],{},"persistentVolumeClaim",": Volume information for a ",[567,32862,27758],{},[668,32864,32865],{},[638,32866,32867,32870,32871,32873],{},[567,32868,32869],{},"claimName",": Name of an existing ",[567,32872,27758],{}," to mount.",[638,32875,32876,32877,32879,32880,714,32882,714,32884,32886],{},"Besides mounting storage through ",[567,32878,27758],{},"s, there are other storage options available for your applications (",[567,32881,26963],{},[567,32883,30063],{},[567,32885,23097],{},", etc).",[523,32888,32889,32890,32893,32894,32896,32897,32899,32900,1909],{},"Now that our database will not lose its data, we can run ",[567,32891,32892],{},"kubectl create -f mysql-with-storage.yaml"," in the task directory, this will create a MySQL Deployment which mounts the ",[567,32895,27758],{}," previosuly created to the ",[567,32898,6744],{}," container at ",[567,32901,6335],{},[523,32903,17984,32904,32906,32907,32909],{},[567,32905,25255],{}," run, we can use ",[567,32908,28694],{}," to check if our Deployment and PersistentVolumeClaim have been created:",[738,32911,32913],{"className":1621,"code":32912,"language":1623,"meta":743,"style":743},"$ kubectl get deployment,pod,persistentvolumeclaim\nNAME                          READY   UP-TO-DATE   AVAILABLE   AGE\ndeployment.extensions\u002Fmysql   1\u002F1     1            1           86s\n\nNAME                         READY   STATUS      RESTARTS   AGE\npod\u002Fhello-world              0\u002F1     Completed   0          26h\npod\u002Fmysql-5fc68fb84c-bssg4   1\u002F1     Running     0          86s\n\nNAME                          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE\npersistentvolumeclaim\u002Fmysql   Bound    pvc-3ede7af3-6f74-11e9-a6f0-9600001d3faa   5Gi        RWO            rook-ceph-block   86s\n",[567,32914,32915,32926,32941,32957,32961,32973,32988,33002,33006,33031],{"__ignoreMap":743},[747,32916,32917,32919,32921,32923],{"class":749,"line":750},[747,32918,1919],{"class":1630},[747,32920,1922],{"class":802},[747,32922,1951],{"class":802},[747,32924,32925],{"class":802}," deployment,pod,persistentvolumeclaim\n",[747,32927,32928,32930,32933,32936,32939],{"class":749,"line":761},[747,32929,2230],{"class":1630},[747,32931,32932],{"class":802},"                          READY",[747,32934,32935],{"class":802},"   UP-TO-DATE",[747,32937,32938],{"class":802},"   AVAILABLE",[747,32940,15553],{"class":802},[747,32942,32943,32946,32948,32951,32954],{"class":749,"line":769},[747,32944,32945],{"class":1630},"deployment.extensions\u002Fmysql",[747,32947,2268],{"class":802},[747,32949,32950],{"class":1895},"     1",[747,32952,32953],{"class":1895},"            1",[747,32955,32956],{"class":802},"           86s\n",[747,32958,32959],{"class":749,"line":776},[747,32960,1255],{"emptyLinePlaceholder":1254},[747,32962,32963,32965,32967,32969,32971],{"class":749,"line":784},[747,32964,2230],{"class":1630},[747,32966,2233],{"class":802},[747,32968,2236],{"class":802},[747,32970,15743],{"class":802},[747,32972,15553],{"class":802},[747,32974,32975,32978,32981,32983,32985],{"class":749,"line":790},[747,32976,32977],{"class":1630},"pod\u002Fhello-world",[747,32979,32980],{"class":802},"              0\u002F1",[747,32982,15908],{"class":802},[747,32984,2274],{"class":1895},[747,32986,32987],{"class":802},"          26h\n",[747,32989,32990,32993,32995,32997,32999],{"class":749,"line":796},[747,32991,32992],{"class":1630},"pod\u002Fmysql-5fc68fb84c-bssg4",[747,32994,2268],{"class":802},[747,32996,2271],{"class":802},[747,32998,15757],{"class":1895},[747,33000,33001],{"class":802},"          86s\n",[747,33003,33004],{"class":749,"line":806},[747,33005,1255],{"emptyLinePlaceholder":1254},[747,33007,33008,33010,33013,33016,33019,33022,33025,33028],{"class":749,"line":814},[747,33009,2230],{"class":1630},[747,33011,33012],{"class":802},"                          STATUS",[747,33014,33015],{"class":802},"   VOLUME",[747,33017,33018],{"class":802},"                                     CAPACITY",[747,33020,33021],{"class":802},"   ACCESS",[747,33023,33024],{"class":802}," MODES",[747,33026,33027],{"class":802},"   STORAGECLASS",[747,33029,33030],{"class":802},"      AGE\n",[747,33032,33033,33036,33039,33042,33045,33048,33051],{"class":749,"line":822},[747,33034,33035],{"class":1630},"persistentvolumeclaim\u002Fmysql",[747,33037,33038],{"class":802},"   Bound",[747,33040,33041],{"class":802},"    pvc-3ede7af3-6f74-11e9-a6f0-9600001d3faa",[747,33043,33044],{"class":802},"   5Gi",[747,33046,33047],{"class":802},"        RWO",[747,33049,33050],{"class":802},"            rook-ceph-block",[747,33052,33053],{"class":802},"   86s\n",[523,33055,33056,33057,33059],{},"(The name in the ",[567,33058,9177],{}," column at the end will be different per cluster!)",[523,33061,33062],{},"Isn't that cool? We now have a MySQL Pod running.",[523,33064,33065],{},"Before we make sure the database server is working, let's quickly close the basic storage topic, by looking at the other important volume types for applications in Kubernetes.",[3142,33067,33069,33070,714,33072,714,33074,33076],{"id":33068},"volume-types-emptydir-configmap-secrets-etc","Volume Types (",[567,33071,26963],{},[567,33073,30063],{},[567,33075,23097],{},", etc)",[523,33078,33079,33080,30064,33082,33084,33085,587,33087,1909],{},"Besides previosuly talked about ",[567,33081,30063],{},[567,33083,23097],{}," which can used for environment variable and also to mount as volumes, there are some important other volume types like ",[567,33086,26963],{},[567,33088,33089],{},"hostPath",[33091,33092,33094],"h6",{"id":33093},"emptydir",[567,33095,26963],{},[523,33097,33098,33099,33101],{},"When a Pod is created and scheduled to a node, a empty directory is created and mounted inside the Pod.\nThis directory is only persistent till the Pod has been deleted, if a Pod of, e.g., the same ",[567,33100,25331],{}," is put on the same node, the new Pod gets its own new empty directory and not a used one.",[33091,33103,33105],{"id":33104},"hostpath",[567,33106,33089],{},[523,33108,33109,33110,33112,33113,1909],{},"A Pod can also mount storage from the host into the container(s). Unless you have a very good reason, restrict usage of ",[567,33111,33089],{}," and use ",[527,33114,33117],{"href":33115,"rel":33116},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fstorage\u002Fvolumes\u002F#local",[531],"Kubernetes - Local Persistent Storage",[6072,33119,33120,33124],{},[523,33121,33122],{},[584,33123,6189],{},[523,33125,33126,33127,33129],{},"There can be good reason to mount a host path into a Pod's container(s), but for normal users that can lead to nodes running full because there is no data management behind ",[567,33128,33089],{}," \"volumes\".",[3126,33131,33133],{"id":33132},"make-sure-the-database-server-is-working","Make sure the database server is working",[523,33135,33136,33137,33139,33140,33142,33143,33146],{},"Maybe you know about ",[567,33138,7110],{},", which can be used to run a command and\u002F or shell inside a running container.\n",[567,33141,16258],{}," does the same but for Pods. If a Pod has more than one container, it will \"cmplain\" to you and tell you the list of containers, which you can specify using the ",[567,33144,33145],{},"-c CONTAINER_NAME"," flag.",[523,33148,33149,33150,33152,33153,856],{},"Adapt the following command to your ",[567,33151,6744],{}," Pod name with the command ",[567,33154,1623],{},[738,33156,33158],{"className":1621,"code":33157,"language":1623,"meta":743,"style":743},"kubectl exec -it POD_NAME -- COMMAND ARGS\n",[567,33159,33160],{"__ignoreMap":743},[747,33161,33162,33164,33166,33168,33171,33173,33176],{"class":749,"line":750},[747,33163,15269],{"class":1630},[747,33165,2586],{"class":802},[747,33167,4072],{"class":802},[747,33169,33170],{"class":802}," POD_NAME",[747,33172,2592],{"class":802},[747,33174,33175],{"class":802}," COMMAND",[747,33177,33178],{"class":802}," ARGS\n",[6072,33180,33181],{},[523,33182,33183],{},[584,33184,2957],{},[668,33186,33187,33209,33215,33220],{},[638,33188,33189,19221,33192,33195,33196,33198,33199,33202,33203,714,33206,32418],{},[567,33190,33191],{},"-it",[567,33193,33194],{},"i"," stands for interactive (attach stdin and stdout, stderr from the ",[567,33197,15269],{},"). ",[567,33200,33201],{},"t"," will cause a TTY to be attached, a TTY is needed for applications like ",[567,33204,33205],{},"vim",[567,33207,33208],{},"emacs",[638,33210,33211,33214],{},[567,33212,33213],{},"POD_NAME"," - Name of the Pod to exec into.",[638,33216,33217,33219],{},[567,33218,4256],{}," - Command to execute inside the Pod's container.",[638,33221,33222,33225,33226,33228],{},[567,33223,33224],{},"ARGS"," - Optional. Arguments passed to the ",[567,33227,4256],{}," given.",[523,33230,33231],{},"The result can look like this:",[738,33233,33235],{"className":1621,"code":33234,"language":1623,"meta":743,"style":743},"$ kubectl exec -it mysql-5fc68fb84c-bssg4 -- bash\nroot@mysql-5fc68fb84c-bssg4:\u002F#\n",[567,33236,33237,33254],{"__ignoreMap":743},[747,33238,33239,33241,33243,33245,33247,33250,33252],{"class":749,"line":750},[747,33240,1919],{"class":1630},[747,33242,1922],{"class":802},[747,33244,2586],{"class":802},[747,33246,4072],{"class":802},[747,33248,33249],{"class":802}," mysql-5fc68fb84c-bssg4",[747,33251,2592],{"class":802},[747,33253,4078],{"class":802},[747,33255,33256],{"class":749,"line":761},[747,33257,33258],{"class":1630},"root@mysql-5fc68fb84c-bssg4:\u002F#\n",[523,33260,33261,33262,33264],{},"This has now opened an interactive ",[567,33263,1623],{}," shell inside the MySQL Pod.",[523,33266,33267,33268,33270],{},"Let's use ",[567,33269,6744],{}," command to connect to the database server:",[738,33272,33274],{"className":1621,"code":33273,"language":1623,"meta":743,"style":743},"root@mysql-5fc68fb84c-bssg4:\u002F# mysql -u root -p$MYSQL_ROOT_PASSWORD\nWarning: Using a password on the command line interface can be insecure.\nWelcome to the MySQL monitor.  Commands end with ; or \\g.\nYour MySQL connection id is 1\nServer version: 5.6.44 MySQL Community Server (GPL)\n\nCopyright (c) 2000, 2019, Oracle and\u002For its affiliates. All rights reserved.\n\nOracle is a registered trademark of Oracle Corporation and\u002For its\naffiliates. Other names may be trademarks of their respective\nowners.\n\nType 'help;' or '\\h' for help. Type '\\c' to clear the current input statement.\n\nmysql> SHOW DATABASES;\n+--------------------+\n| Database           |\n+--------------------+\n| information_schema |\n| mysql              |\n| performance_schema |\n+--------------------+\n3 rows in set (0.00 sec)\n\nmysql> quit\nBye\nroot@mysql-5fc68fb84c-bssg4:\u002F# exit\n",[567,33275,33276,33292,33326,33359,33376,33398,33402,33410,33414,33443,33469,33474,33478,33530,33534,33549,33554,33564,33568,33577,33586,33595,33599,33619,33623,33632,33637],{"__ignoreMap":743},[747,33277,33278,33281,33283,33285,33287,33289],{"class":749,"line":750},[747,33279,33280],{"class":1630},"root@mysql-5fc68fb84c-bssg4:\u002F#",[747,33282,5793],{"class":802},[747,33284,7089],{"class":802},[747,33286,5149],{"class":802},[747,33288,7094],{"class":802},[747,33290,33291],{"class":1640},"$MYSQL_ROOT_PASSWORD\n",[747,33293,33294,33297,33300,33302,33305,33308,33310,33313,33316,33319,33321,33323],{"class":749,"line":761},[747,33295,33296],{"class":1630},"Warning:",[747,33298,33299],{"class":802}," Using",[747,33301,3930],{"class":802},[747,33303,33304],{"class":802}," password",[747,33306,33307],{"class":802}," on",[747,33309,3839],{"class":802},[747,33311,33312],{"class":802}," command",[747,33314,33315],{"class":802}," line",[747,33317,33318],{"class":802}," interface",[747,33320,4048],{"class":802},[747,33322,3806],{"class":802},[747,33324,33325],{"class":802}," insecure.\n",[747,33327,33328,33331,33333,33335,33338,33341,33344,33347,33349,33352,33354,33357],{"class":749,"line":769},[747,33329,33330],{"class":1630},"Welcome",[747,33332,3696],{"class":802},[747,33334,3839],{"class":802},[747,33336,33337],{"class":802}," MySQL",[747,33339,33340],{"class":802}," monitor.",[747,33342,33343],{"class":802},"  Commands",[747,33345,33346],{"class":802}," end",[747,33348,4104],{"class":802},[747,33350,33351],{"class":757}," ;",[747,33353,4423],{"class":1630},[747,33355,33356],{"class":1640}," \\g",[747,33358,9661],{"class":802},[747,33360,33361,33364,33366,33369,33372,33374],{"class":749,"line":776},[747,33362,33363],{"class":1630},"Your",[747,33365,33337],{"class":802},[747,33367,33368],{"class":802}," connection",[747,33370,33371],{"class":802}," id",[747,33373,5068],{"class":802},[747,33375,18691],{"class":1895},[747,33377,33378,33381,33384,33387,33389,33392,33395],{"class":749,"line":784},[747,33379,33380],{"class":1630},"Server",[747,33382,33383],{"class":802}," version:",[747,33385,33386],{"class":1895}," 5.6.44",[747,33388,33337],{"class":802},[747,33390,33391],{"class":802}," Community",[747,33393,33394],{"class":802}," Server",[747,33396,33397],{"class":1640}," (GPL)\n",[747,33399,33400],{"class":749,"line":790},[747,33401,1255],{"emptyLinePlaceholder":1254},[747,33403,33404,33407],{"class":749,"line":796},[747,33405,33406],{"class":1630},"Copyright",[747,33408,33409],{"class":1640}," (c) 2000, 2019, Oracle and\u002For its affiliates. All rights reserved.\n",[747,33411,33412],{"class":749,"line":806},[747,33413,1255],{"emptyLinePlaceholder":1254},[747,33415,33416,33419,33421,33423,33426,33429,33431,33434,33437,33440],{"class":749,"line":814},[747,33417,33418],{"class":1630},"Oracle",[747,33420,5068],{"class":802},[747,33422,3930],{"class":802},[747,33424,33425],{"class":802}," registered",[747,33427,33428],{"class":802}," trademark",[747,33430,5276],{"class":802},[747,33432,33433],{"class":802}," Oracle",[747,33435,33436],{"class":802}," Corporation",[747,33438,33439],{"class":802}," and\u002For",[747,33441,33442],{"class":802}," its\n",[747,33444,33445,33448,33451,33453,33456,33458,33461,33463,33466],{"class":749,"line":822},[747,33446,33447],{"class":1630},"affiliates.",[747,33449,33450],{"class":802}," Other",[747,33452,19447],{"class":802},[747,33454,33455],{"class":802}," may",[747,33457,3806],{"class":802},[747,33459,33460],{"class":802}," trademarks",[747,33462,5276],{"class":802},[747,33464,33465],{"class":802}," their",[747,33467,33468],{"class":802}," respective\n",[747,33470,33471],{"class":749,"line":830},[747,33472,33473],{"class":1630},"owners.\n",[747,33475,33476],{"class":749,"line":836},[747,33477,1255],{"emptyLinePlaceholder":1254},[747,33479,33480,33483,33485,33488,33490,33492,33494,33497,33499,33501,33504,33507,33509,33512,33514,33516,33519,33521,33524,33527],{"class":749,"line":842},[747,33481,33482],{"class":1630},"Type",[747,33484,3537],{"class":757},[747,33486,33487],{"class":802},"help;",[747,33489,3543],{"class":757},[747,33491,4423],{"class":802},[747,33493,3537],{"class":757},[747,33495,33496],{"class":802},"\\h",[747,33498,3543],{"class":757},[747,33500,3761],{"class":802},[747,33502,33503],{"class":802}," help.",[747,33505,33506],{"class":802}," Type",[747,33508,3537],{"class":757},[747,33510,33511],{"class":802},"\\c",[747,33513,3543],{"class":757},[747,33515,3696],{"class":802},[747,33517,33518],{"class":802}," clear",[747,33520,3839],{"class":802},[747,33522,33523],{"class":802}," current",[747,33525,33526],{"class":802}," input",[747,33528,33529],{"class":802}," statement.\n",[747,33531,33532],{"class":749,"line":850},[747,33533,1255],{"emptyLinePlaceholder":1254},[747,33535,33536,33538,33541,33544,33547],{"class":749,"line":863},[747,33537,6744],{"class":1630},[747,33539,33540],{"class":1640},"> ",[747,33542,33543],{"class":802},"SHOW",[747,33545,33546],{"class":802}," DATABASES",[747,33548,19303],{"class":757},[747,33550,33551],{"class":749,"line":869},[747,33552,33553],{"class":1630},"+--------------------+\n",[747,33555,33556,33558,33561],{"class":749,"line":877},[747,33557,3616],{"class":757},[747,33559,33560],{"class":1630}," Database",[747,33562,33563],{"class":757},"           |\n",[747,33565,33566],{"class":749,"line":1015},[747,33567,33553],{"class":1630},[747,33569,33570,33572,33575],{"class":749,"line":1021},[747,33571,3616],{"class":757},[747,33573,33574],{"class":1630}," information_schema",[747,33576,24697],{"class":757},[747,33578,33579,33581,33583],{"class":749,"line":1027},[747,33580,3616],{"class":757},[747,33582,5793],{"class":1630},[747,33584,33585],{"class":757},"              |\n",[747,33587,33588,33590,33593],{"class":749,"line":1033},[747,33589,3616],{"class":757},[747,33591,33592],{"class":1630}," performance_schema",[747,33594,24697],{"class":757},[747,33596,33597],{"class":749,"line":1039},[747,33598,33553],{"class":1630},[747,33600,33601,33603,33606,33608,33611,33614,33617],{"class":749,"line":1054},[747,33602,28238],{"class":1630},[747,33604,33605],{"class":802}," rows",[747,33607,4584],{"class":802},[747,33609,33610],{"class":802}," set",[747,33612,33613],{"class":1640}," (0.00 ",[747,33615,33616],{"class":802},"sec",[747,33618,3600],{"class":1640},[747,33620,33621],{"class":749,"line":1060},[747,33622,1255],{"emptyLinePlaceholder":1254},[747,33624,33625,33627,33629],{"class":749,"line":1066},[747,33626,6744],{"class":1630},[747,33628,33540],{"class":1640},[747,33630,33631],{"class":802},"quit\n",[747,33633,33634],{"class":749,"line":1081},[747,33635,33636],{"class":1630},"Bye\n",[747,33638,33639,33641],{"class":749,"line":1087},[747,33640,33280],{"class":1630},[747,33642,33643],{"class":802}," exit\n",[523,33645,33646],{},"Awesome! Our MySQL server Pod is running as should.",[523,33648,33649],{},"We took the \"extra\" steps to attach storage to the MySQL Deployment so let's test what happens if the MySQL Pod is deleted.",[3142,33651,33653],{"id":33652},"test-resilience-of-mysql-server-deployment","Test resilience of MySQL server Deployment",[523,33655,33656,33657,33659,33660,33663],{},"Go ahead and delete the MySQL Pod in the ",[567,33658,2014],{}," Namespace (no need to use ",[567,33661,33662],{},"--namespace"," flag though as it is the default).",[523,33665,33666],{},"To get the current Pods, run:",[738,33668,33670],{"className":1621,"code":33669,"language":1623,"meta":743,"style":743},"$ kubectl get pod\nNAME                     READY   STATUS      RESTARTS   AGE\nhello-world              0\u002F1     Completed   0          26h\nmysql-5fc68fb84c-bssg4   1\u002F1     Running     0          11m\n",[567,33671,33672,33682,33695,33707],{"__ignoreMap":743},[747,33673,33674,33676,33678,33680],{"class":749,"line":750},[747,33675,1919],{"class":1630},[747,33677,1922],{"class":802},[747,33679,1951],{"class":802},[747,33681,15539],{"class":802},[747,33683,33684,33686,33689,33691,33693],{"class":749,"line":761},[747,33685,2230],{"class":1630},[747,33687,33688],{"class":802},"                     READY",[747,33690,2236],{"class":802},[747,33692,15743],{"class":802},[747,33694,15553],{"class":802},[747,33696,33697,33699,33701,33703,33705],{"class":749,"line":769},[747,33698,3649],{"class":1630},[747,33700,32980],{"class":802},[747,33702,15908],{"class":802},[747,33704,2274],{"class":1895},[747,33706,32987],{"class":802},[747,33708,33709,33712,33714,33716,33718],{"class":749,"line":776},[747,33710,33711],{"class":1630},"mysql-5fc68fb84c-bssg4",[747,33713,2268],{"class":802},[747,33715,2271],{"class":802},[747,33717,15757],{"class":1895},[747,33719,15760],{"class":802},[523,33721,33722,33723,33725,33726,1909],{},"Pod with name ",[567,33724,33711],{}," is our target, so run ",[567,33727,33728],{},"kubectl delete pod mysql-5fc68fb84c-bssg4",[523,33730,33731],{},"Checking the current Pods now, we should see a new Pod running:",[738,33733,33735],{"className":1621,"code":33734,"language":1623,"meta":743,"style":743},"$ kubectl get pod\nNAME                     READY   STATUS      RESTARTS   AGE\nhello-world              0\u002F1     Completed   0          26h\nmysql-5fc68fb84c-crm86   0\u002F1     Running     0          16s\n",[567,33736,33737,33747,33759,33771],{"__ignoreMap":743},[747,33738,33739,33741,33743,33745],{"class":749,"line":750},[747,33740,1919],{"class":1630},[747,33742,1922],{"class":802},[747,33744,1951],{"class":802},[747,33746,15539],{"class":802},[747,33748,33749,33751,33753,33755,33757],{"class":749,"line":761},[747,33750,2230],{"class":1630},[747,33752,33688],{"class":802},[747,33754,2236],{"class":802},[747,33756,15743],{"class":802},[747,33758,15553],{"class":802},[747,33760,33761,33763,33765,33767,33769],{"class":749,"line":769},[747,33762,3649],{"class":1630},[747,33764,32980],{"class":802},[747,33766,15908],{"class":802},[747,33768,2274],{"class":1895},[747,33770,32987],{"class":802},[747,33772,33773,33776,33778,33780,33782],{"class":749,"line":776},[747,33774,33775],{"class":1630},"mysql-5fc68fb84c-crm86",[747,33777,28732],{"class":802},[747,33779,2271],{"class":802},[747,33781,15757],{"class":1895},[747,33783,33784],{"class":802},"          16s\n",[523,33786,33787],{},"This will mean for our WordPress which we are going to create in the next section, that if the MySQL Pod is down\u002F deleted, a new one will spawn up with the same data so that WordPress can continue working.",[3126,33789,33791],{"id":33790},"what-do-we-have-now","What do we have now?",[523,33793,33794,33795,33797,33798,33800],{},"We now have a ",[567,33796,25331],{}," which keep one Pod of MySQL running running. The ",[567,33799,25331],{}," has the configuration in it for the MySQL Pod it is spawning.\nBut we have not specified a store for the MySQL data yet, we will do that as the next step.",[523,33802,26933,33803,33805,33806,33808,33809,33811,33812,1909],{},[567,33804,25331],{}," we have a ",[567,33807,25729],{},", which makes the MySQL reachable under a \"static\" cluster-internal IP address and DNS name for the ",[567,33810,25729],{},".\nMeaning the WordPress can easily access the MySQL database server through the DNS name of the ",[567,33813,25729],{},[523,33815,33816],{},"So let's get right onto it and run WordPress.",[3126,33818,33820],{"id":33819},"running-wordpress","Running WordPress",[6072,33822,33823],{},[523,33824,33825,8939,33827,19221,33832],{},[584,33826,2951],{},[527,33828,33830],{"href":30359,"rel":33829},[531],[567,33831,30363],{},[567,33833,33834],{},"wordpress.yaml",[523,33836,33837,33839],{},[567,33838,6725],{}," Deployment, Service and PersistentVolumeClaim YAML:",[738,33841,33845],{"className":740,"code":33842,"filename":33843,"highlights":33844,"language":742,"meta":743,"style":743},"apiVersion: apps\u002Fv1\nkind: Deployment\nmetadata:\n  name: wordpress\n  labels:\n    app.kubernetes.io\u002Fname: wordpress\n    app.kubernetes.io\u002Fpart-of: wordpress\nspec:\n  selector:\n    matchLabels:\n      app.kubernetes.io\u002Fname: wordpress\n      app.kubernetes.io\u002Fpart-of: wordpress\n  template:\n    metadata:\n      labels:\n        app.kubernetes.io\u002Fname: wordpress\n        app.kubernetes.io\u002Fpart-of: wordpress\n    spec:\n      containers:\n      - image: wordpress:5.1.1-php7.1-apache\n        name: wordpress\n        env:\n        - name: WORDPRESS_DB_HOST\n          value: mysql\n        - name: WORDPRESS_DB_PASSWORD\n          value: changeme\n        ports:\n        - containerPort: 80\n          name: wordpress\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: wordpress\n  labels:\n    app.kubernetes.io\u002Fname: wordpress\n    app.kubernetes.io\u002Fpart-of: wordpress\nspec:\n  ports:\n    - name: http\n      port: 80\n      protocol: TCP\n  selector:\n    app.kubernetes.io\u002Fname: wordpress\n    app.kubernetes.io\u002Fpart-of: wordpress\n  type: NodePort\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  labels:\n    app.kubernetes.io\u002Fname: wordpress\n    app.kubernetes.io\u002Fpart-of: wordpress\n  name: wordpress\nspec:\n  storageClassName: rook-ceph-block\n  accessModes:\n  - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n","\"19-29\"",[30372],[567,33846,33847,33855,33863,33869,33877,33883,33891,33899,33905,33911,33917,33925,33933,33939,33945,33951,33959,33967,33973,33979,33990,33998,34004,34015,34023,34034,34042,34048,34058,34066,34070,34078,34086,34092,34100,34106,34114,34122,34128,34134,34144,34152,34160,34166,34174,34182,34191,34195,34203,34211,34217,34223,34231,34239,34247,34253,34261,34267,34273,34279,34285],{"__ignoreMap":743},[747,33848,33849,33851,33853],{"class":749,"line":750},[747,33850,12949],{"class":753},[747,33852,856],{"class":757},[747,33854,25349],{"class":802},[747,33856,33857,33859,33861],{"class":749,"line":761},[747,33858,12963],{"class":753},[747,33860,856],{"class":757},[747,33862,25358],{"class":802},[747,33864,33865,33867],{"class":749,"line":769},[747,33866,12973],{"class":753},[747,33868,758],{"class":757},[747,33870,33871,33873,33875],{"class":749,"line":776},[747,33872,12980],{"class":753},[747,33874,856],{"class":757},[747,33876,6540],{"class":802},[747,33878,33879,33881],{"class":749,"line":784},[747,33880,25378],{"class":753},[747,33882,758],{"class":757},[747,33884,33885,33887,33889],{"class":749,"line":790},[747,33886,29776],{"class":753},[747,33888,856],{"class":757},[747,33890,6540],{"class":802},[747,33892,33893,33895,33897],{"class":749,"line":796},[747,33894,30423],{"class":753},[747,33896,856],{"class":757},[747,33898,6540],{"class":802},[747,33900,33901,33903],{"class":749,"line":806},[747,33902,12990],{"class":753},[747,33904,758],{"class":757},[747,33906,33907,33909],{"class":749,"line":814},[747,33908,25430],{"class":753},[747,33910,758],{"class":757},[747,33912,33913,33915],{"class":749,"line":822},[747,33914,25437],{"class":753},[747,33916,758],{"class":757},[747,33918,33919,33921,33923],{"class":749,"line":830},[747,33920,30450],{"class":753},[747,33922,856],{"class":757},[747,33924,6540],{"class":802},[747,33926,33927,33929,33931],{"class":749,"line":836},[747,33928,30459],{"class":753},[747,33930,856],{"class":757},[747,33932,6540],{"class":802},[747,33934,33935,33937],{"class":749,"line":842},[747,33936,25462],{"class":753},[747,33938,758],{"class":757},[747,33940,33941,33943],{"class":749,"line":850},[747,33942,21456],{"class":753},[747,33944,758],{"class":757},[747,33946,33947,33949],{"class":749,"line":863},[747,33948,25475],{"class":753},[747,33950,758],{"class":757},[747,33952,33953,33955,33957],{"class":749,"line":869},[747,33954,30486],{"class":753},[747,33956,856],{"class":757},[747,33958,6540],{"class":802},[747,33960,33961,33963,33965],{"class":749,"line":877},[747,33962,30495],{"class":753},[747,33964,856],{"class":757},[747,33966,6540],{"class":802},[747,33968,33969,33971],{"class":749,"line":1015},[747,33970,25509],{"class":753},[747,33972,758],{"class":757},[747,33974,33975,33977],{"class":749,"line":1021},[747,33976,25516],{"class":753},[747,33978,758],{"class":757},[747,33980,33981,33983,33985,33987],{"class":749,"line":1027},[747,33982,799],{"class":757},[747,33984,3702],{"class":753},[747,33986,856],{"class":757},[747,33988,33989],{"class":802}," wordpress:5.1.1-php7.1-apache\n",[747,33991,33992,33994,33996],{"class":749,"line":1033},[747,33993,30527],{"class":753},[747,33995,856],{"class":757},[747,33997,6540],{"class":802},[747,33999,34000,34002],{"class":749,"line":1039},[747,34001,30536],{"class":753},[747,34003,758],{"class":757},[747,34005,34006,34008,34010,34012],{"class":749,"line":1054},[747,34007,14801],{"class":757},[747,34009,14804],{"class":753},[747,34011,856],{"class":757},[747,34013,34014],{"class":802}," WORDPRESS_DB_HOST\n",[747,34016,34017,34019,34021],{"class":749,"line":1060},[747,34018,30554],{"class":753},[747,34020,856],{"class":757},[747,34022,11146],{"class":802},[747,34024,34025,34027,34029,34031],{"class":749,"line":1066},[747,34026,14801],{"class":757},[747,34028,14804],{"class":753},[747,34030,856],{"class":757},[747,34032,34033],{"class":802}," WORDPRESS_DB_PASSWORD\n",[747,34035,34036,34038,34040],{"class":749,"line":1081},[747,34037,30554],{"class":753},[747,34039,856],{"class":757},[747,34041,30559],{"class":802},[747,34043,34044,34046],{"class":749,"line":1087},[747,34045,25553],{"class":753},[747,34047,758],{"class":757},[747,34049,34050,34052,34054,34056],{"class":749,"line":1102},[747,34051,14801],{"class":757},[747,34053,29864],{"class":753},[747,34055,856],{"class":757},[747,34057,29869],{"class":1895},[747,34059,34060,34062,34064],{"class":749,"line":1110},[747,34061,30581],{"class":753},[747,34063,856],{"class":757},[747,34065,6540],{"class":802},[747,34067,34068],{"class":749,"line":1117},[747,34069,12808],{"class":1630},[747,34071,34072,34074,34076],{"class":749,"line":1123},[747,34073,12949],{"class":753},[747,34075,856],{"class":757},[747,34077,22608],{"class":802},[747,34079,34080,34082,34084],{"class":749,"line":1129},[747,34081,12963],{"class":753},[747,34083,856],{"class":757},[747,34085,25758],{"class":802},[747,34087,34088,34090],{"class":749,"line":1142},[747,34089,12973],{"class":753},[747,34091,758],{"class":757},[747,34093,34094,34096,34098],{"class":749,"line":1150},[747,34095,12980],{"class":753},[747,34097,856],{"class":757},[747,34099,6540],{"class":802},[747,34101,34102,34104],{"class":749,"line":1157},[747,34103,25378],{"class":753},[747,34105,758],{"class":757},[747,34107,34108,34110,34112],{"class":749,"line":1163},[747,34109,29776],{"class":753},[747,34111,856],{"class":757},[747,34113,6540],{"class":802},[747,34115,34116,34118,34120],{"class":749,"line":1168},[747,34117,30423],{"class":753},[747,34119,856],{"class":757},[747,34121,6540],{"class":802},[747,34123,34124,34126],{"class":749,"line":1174},[747,34125,12990],{"class":753},[747,34127,758],{"class":757},[747,34129,34130,34132],{"class":749,"line":1480},[747,34131,25878],{"class":753},[747,34133,758],{"class":757},[747,34135,34136,34138,34140,34142],{"class":749,"line":1491},[747,34137,18665],{"class":757},[747,34139,14804],{"class":753},[747,34141,856],{"class":757},[747,34143,29878],{"class":802},[747,34145,34146,34148,34150],{"class":749,"line":1496},[747,34147,25895],{"class":753},[747,34149,856],{"class":757},[747,34151,29869],{"class":1895},[747,34153,34154,34156,34158],{"class":749,"line":1502},[747,34155,25904],{"class":753},[747,34157,856],{"class":757},[747,34159,25576],{"class":802},[747,34161,34162,34164],{"class":749,"line":1510},[747,34163,25430],{"class":753},[747,34165,758],{"class":757},[747,34167,34168,34170,34172],{"class":749,"line":1520},[747,34169,29776],{"class":753},[747,34171,856],{"class":757},[747,34173,6540],{"class":802},[747,34175,34176,34178,34180],{"class":749,"line":1525},[747,34177,30423],{"class":753},[747,34179,856],{"class":757},[747,34181,6540],{"class":802},[747,34183,34184,34186,34188],{"class":749,"line":1533},[747,34185,18593],{"class":753},[747,34187,856],{"class":757},[747,34189,34190],{"class":802}," NodePort\n",[747,34192,34193],{"class":749,"line":1539},[747,34194,12808],{"class":1630},[747,34196,34197,34199,34201],{"class":749,"line":1549},[747,34198,12949],{"class":753},[747,34200,856],{"class":757},[747,34202,22608],{"class":802},[747,34204,34205,34207,34209],{"class":749,"line":1554},[747,34206,12963],{"class":753},[747,34208,856],{"class":757},[747,34210,32234],{"class":802},[747,34212,34213,34215],{"class":749,"line":1562},[747,34214,12973],{"class":753},[747,34216,758],{"class":757},[747,34218,34219,34221],{"class":749,"line":1568},[747,34220,25378],{"class":753},[747,34222,758],{"class":757},[747,34224,34225,34227,34229],{"class":749,"line":1577},[747,34226,29776],{"class":753},[747,34228,856],{"class":757},[747,34230,6540],{"class":802},[747,34232,34233,34235,34237],{"class":749,"line":1582},[747,34234,30423],{"class":753},[747,34236,856],{"class":757},[747,34238,6540],{"class":802},[747,34240,34241,34243,34245],{"class":749,"line":1588},[747,34242,12980],{"class":753},[747,34244,856],{"class":757},[747,34246,6540],{"class":802},[747,34248,34249,34251],{"class":749,"line":1594},[747,34250,12990],{"class":753},[747,34252,758],{"class":757},[747,34254,34255,34257,34259],{"class":749,"line":1600},[747,34256,32281],{"class":753},[747,34258,856],{"class":757},[747,34260,32286],{"class":802},[747,34262,34263,34265],{"class":749,"line":4804},[747,34264,32291],{"class":753},[747,34266,758],{"class":757},[747,34268,34269,34271],{"class":749,"line":4810},[747,34270,1721],{"class":757},[747,34272,32300],{"class":802},[747,34274,34275,34277],{"class":749,"line":4816},[747,34276,22712],{"class":753},[747,34278,758],{"class":757},[747,34280,34281,34283],{"class":749,"line":4822},[747,34282,32311],{"class":753},[747,34284,758],{"class":757},[747,34286,34287,34289,34291],{"class":749,"line":4828},[747,34288,32318],{"class":753},[747,34290,856],{"class":757},[747,34292,32323],{"class":802},[523,34294,34295,34296,34299],{},"Go to the task directory and run ",[567,34297,34298],{},"kubectl create -f wordpress.yaml",".\nThis will create the objects defined in the YAML.",[523,34301,34302,34303,34305,34306,34308],{},"Check on the newly created ",[567,34304,6725],{}," objects using ",[567,34307,28694],{}," with a label selector:",[738,34310,34312],{"className":1621,"code":34311,"language":1623,"meta":743,"style":743},"$ kubectl get deployment,svc,persistentvolumeclaim,pod -l app.kubernetes.io\u002Fname=wordpress\nNAME                              READY   UP-TO-DATE   AVAILABLE   AGE\ndeployment.extensions\u002Fwordpress   1\u002F1     1            1           44s\n\nNAME                TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE\nservice\u002Fwordpress   NodePort   100.76.188.95   \u003Cnone>        80:30142\u002FTCP   44s\n\nNAME                              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS               AGE\npersistentvolumeclaim\u002Fwordpress   Bound    pvc-8059dc54-6f77-11e9-a067-9600001d3fa9   5Gi        RWO            rook-ceph-block-repl-3-1   44s\n\nNAME                             READY   STATUS    RESTARTS   AGE\npod\u002Fwordpress-56bdcbcb5b-jhpjw   1\u002F1     Running   0          44s\n",[567,34313,34314,34330,34343,34357,34361,34384,34408,34412,34432,34451,34455,34468],{"__ignoreMap":743},[747,34315,34316,34318,34320,34322,34325,34327],{"class":749,"line":750},[747,34317,1919],{"class":1630},[747,34319,1922],{"class":802},[747,34321,1951],{"class":802},[747,34323,34324],{"class":802}," deployment,svc,persistentvolumeclaim,pod",[747,34326,16204],{"class":802},[747,34328,34329],{"class":802}," app.kubernetes.io\u002Fname=wordpress\n",[747,34331,34332,34334,34337,34339,34341],{"class":749,"line":761},[747,34333,2230],{"class":1630},[747,34335,34336],{"class":802},"                              READY",[747,34338,32935],{"class":802},[747,34340,32938],{"class":802},[747,34342,15553],{"class":802},[747,34344,34345,34348,34350,34352,34354],{"class":749,"line":769},[747,34346,34347],{"class":1630},"deployment.extensions\u002Fwordpress",[747,34349,2268],{"class":802},[747,34351,32950],{"class":1895},[747,34353,32953],{"class":1895},[747,34355,34356],{"class":802},"           44s\n",[747,34358,34359],{"class":749,"line":776},[747,34360,1255],{"emptyLinePlaceholder":1254},[747,34362,34363,34365,34368,34370,34373,34375,34377,34379,34381],{"class":749,"line":784},[747,34364,2230],{"class":1630},[747,34366,34367],{"class":802},"                TYPE",[747,34369,15353],{"class":802},[747,34371,34372],{"class":802},"      EXTERNAL-IP",[747,34374,1997],{"class":802},[747,34376,2000],{"class":757},[747,34378,2003],{"class":1630},[747,34380,2006],{"class":757},[747,34382,34383],{"class":802},"        AGE\n",[747,34385,34386,34389,34391,34394,34396,34398,34400,34402,34405],{"class":749,"line":790},[747,34387,34388],{"class":1630},"service\u002Fwordpress",[747,34390,15375],{"class":802},[747,34392,34393],{"class":1895},"   100.76.188.95",[747,34395,2026],{"class":757},[747,34397,2029],{"class":802},[747,34399,2032],{"class":1640},[747,34401,2035],{"class":757},[747,34403,34404],{"class":802},"        80:30142\u002FTCP",[747,34406,34407],{"class":802},"   44s\n",[747,34409,34410],{"class":749,"line":796},[747,34411,1255],{"emptyLinePlaceholder":1254},[747,34413,34414,34416,34419,34421,34423,34425,34427,34429],{"class":749,"line":806},[747,34415,2230],{"class":1630},[747,34417,34418],{"class":802},"                              STATUS",[747,34420,33015],{"class":802},[747,34422,33018],{"class":802},[747,34424,33021],{"class":802},[747,34426,33024],{"class":802},[747,34428,33027],{"class":802},[747,34430,34431],{"class":802},"               AGE\n",[747,34433,34434,34437,34439,34442,34444,34446,34449],{"class":749,"line":814},[747,34435,34436],{"class":1630},"persistentvolumeclaim\u002Fwordpress",[747,34438,33038],{"class":802},[747,34440,34441],{"class":802},"    pvc-8059dc54-6f77-11e9-a067-9600001d3fa9",[747,34443,33044],{"class":802},[747,34445,33047],{"class":802},[747,34447,34448],{"class":802},"            rook-ceph-block-repl-3-1",[747,34450,34407],{"class":802},[747,34452,34453],{"class":749,"line":822},[747,34454,1255],{"emptyLinePlaceholder":1254},[747,34456,34457,34459,34462,34464,34466],{"class":749,"line":830},[747,34458,2230],{"class":1630},[747,34460,34461],{"class":802},"                             READY",[747,34463,2236],{"class":802},[747,34465,2239],{"class":802},[747,34467,15553],{"class":802},[747,34469,34470,34473,34475,34477,34479],{"class":749,"line":836},[747,34471,34472],{"class":1630},"pod\u002Fwordpress-56bdcbcb5b-jhpjw",[747,34474,2268],{"class":802},[747,34476,2271],{"class":802},[747,34478,2274],{"class":1895},[747,34480,34481],{"class":802},"          44s\n",[523,34483,8764,34484,34487,34488,34491,34492,34494,34495,34498],{},[567,34485,34486],{},"STATUS"," column for the ",[567,34489,34490],{},"pod\u002Fwordpress-..."," should be ",[567,34493,17222],{},", if not please let me know and you can try to look into yourself using the ",[567,34496,34497],{},"kubectl describe KIND OBJECT_NAME"," which will be explained in the next section.",[3142,34500,34502,34503,34506],{"id":34501},"having-issues-kubectl-describe-is-here-for-you","Having issues? ",[567,34504,34505],{},"kubectl describe"," is here for you",[523,34508,34509,34511,34512,34515,34516,34518],{},[567,34510,34505],{}," is a way to \"describe\" Pods in a human readable form. In this \"description\" the ",[567,34513,34514],{},"Events"," for Pods are shown. These ",[567,34517,34514],{}," can help you track down what the issue is with, e.g., a Pod not starting up.",[523,34520,34521,34522,34524],{},"Run ",[567,34523,34505],{}," on the Pod above and checkout the output:",[738,34526,34530],{"className":740,"code":34527,"filename":34528,"highlights":34529,"language":742,"meta":743,"style":743},"$ kubectl describe pod wordpress-56bdcbcb5b-jhpjw\nName:               wordpress-56bdcbcb5b-jhpjw\nNamespace:          default\nPriority:           0\nPriorityClassName:  \u003Cnone>\nNode:               k8s02-node-9one1voqljz-htz-deu-fsn1dc1.clster.systems\u002F94.130.51.245\nStart Time:         Sun, 05 May 2019 22:51:05 +0200\nLabels:             app.kubernetes.io\u002Fname=wordpress\n                    app.kubernetes.io\u002Fpart-of=wordpress\n                    pod-template-hash=56bdcbcb5b\nAnnotations:        cni.projectcalico.org\u002FpodIP: 100.67.207.68\u002F32\nStatus:             Running\nIP:                 100.67.207.68\nControlled By:      ReplicaSet\u002Fwordpress-56bdcbcb5b\nContainers:\n  wordpress:\n    Container ID:   containerd:\u002F\u002F301ffa076b4151276e97e2c9df9f9e3788aa1cb6bfead00b70f84d04d78b4595\n    Image:          wordpress:5.1.1-php7.1-apache\n    Image ID:       docker.io\u002Flibrary\u002Fwordpress@sha256:ec14baae52d61e409ea4c2ccaf63401a660266977b0b6ec2dc81396f55f27f57\n    Port:           80\u002FTCP\n    Host Port:      0\u002FTCP\n    State:          Running\n      Started:      Sun, 05 May 2019 22:51:07 +0200\n    Ready:          True\n    Restart Count:  0\n    Environment:\n      WORDPRESS_DB_HOST:      mysql\n      WORDPRESS_DB_PASSWORD:  changeme\n    Mounts:\n      \u002Fvar\u002Frun\u002Fsecrets\u002Fkubernetes.io\u002Fserviceaccount from default-token-lb5tz (ro)\nConditions:\n  Type              Status\n  Initialized       True\n  Ready             True\n  ContainersReady   True\n  PodScheduled      True\nVolumes:\n  default-token-lb5tz:\n    Type:        Secret (a volume populated by a Secret)\n    SecretName:  default-token-lb5tz\n    Optional:    false\nQoS Class:       BestEffort\nNode-Selectors:  \u003Cnone>\nTolerations:     node.kubernetes.io\u002Fnot-ready:NoExecute for 300s\n                 node.kubernetes.io\u002Funreachable:NoExecute for 300s\nEvents:\n  Type    Reason     Age    From                                                            Message\n  ----    ------     ----   ----                                                            -------\n  Normal  Scheduled  4m16s  default-scheduler                                               Successfully assigned default\u002Fwordpress-56bdcbcb5b-jhpjw to k8s02-node-9one1voqljz-htz-deu-fsn1dc1.clster.systems\n  Normal  Pulled     4m15s  kubelet, k8s02-node-9one1voqljz-htz-deu-fsn1dc1.clster.systems  Container image \"wordpress:5.1.1-php7.1-apache\" already present on machine\n  Normal  Created    4m15s  kubelet, k8s02-node-9one1voqljz-htz-deu-fsn1dc1.clster.systems  Created container wordpress\n  Normal  Started    4m14s  kubelet, k8s02-node-9one1voqljz-htz-deu-fsn1dc1.clster.systems  Started container wordpress\n","\"46-52\"",[30372],[567,34531,34532,34537,34547,34556,34566,34576,34585,34595,34605,34610,34615,34630,34640,34650,34660,34666,34672,34682,34692,34702,34712,34722,34732,34742,34752,34762,34769,34778,34787,34794,34799,34806,34811,34816,34821,34826,34831,34838,34845,34855,34865,34875,34885,34894,34904,34909,34915,34920,34925,34930,34935,34940],{"__ignoreMap":743},[747,34533,34534],{"class":749,"line":750},[747,34535,34536],{"class":802},"$ kubectl describe pod wordpress-56bdcbcb5b-jhpjw\n",[747,34538,34539,34542,34544],{"class":749,"line":761},[747,34540,34541],{"class":753},"Name",[747,34543,856],{"class":757},[747,34545,34546],{"class":802},"               wordpress-56bdcbcb5b-jhpjw\n",[747,34548,34549,34551,34553],{"class":749,"line":769},[747,34550,22320],{"class":753},[747,34552,856],{"class":757},[747,34554,34555],{"class":802},"          default\n",[747,34557,34558,34561,34563],{"class":749,"line":776},[747,34559,34560],{"class":753},"Priority",[747,34562,856],{"class":757},[747,34564,34565],{"class":1895},"           0\n",[747,34567,34568,34571,34573],{"class":749,"line":784},[747,34569,34570],{"class":753},"PriorityClassName",[747,34572,856],{"class":757},[747,34574,34575],{"class":802},"  \u003Cnone>\n",[747,34577,34578,34580,34582],{"class":749,"line":790},[747,34579,26775],{"class":753},[747,34581,856],{"class":757},[747,34583,34584],{"class":802},"               k8s02-node-9one1voqljz-htz-deu-fsn1dc1.clster.systems\u002F94.130.51.245\n",[747,34586,34587,34590,34592],{"class":749,"line":796},[747,34588,34589],{"class":753},"Start Time",[747,34591,856],{"class":757},[747,34593,34594],{"class":802},"         Sun, 05 May 2019 22:51:05 +0200\n",[747,34596,34597,34600,34602],{"class":749,"line":806},[747,34598,34599],{"class":753},"Labels",[747,34601,856],{"class":757},[747,34603,34604],{"class":802},"             app.kubernetes.io\u002Fname=wordpress\n",[747,34606,34607],{"class":749,"line":814},[747,34608,34609],{"class":802},"                    app.kubernetes.io\u002Fpart-of=wordpress\n",[747,34611,34612],{"class":749,"line":822},[747,34613,34614],{"class":802},"                    pod-template-hash=56bdcbcb5b\n",[747,34616,34617,34620,34622,34625,34627],{"class":749,"line":830},[747,34618,34619],{"class":753},"Annotations",[747,34621,856],{"class":757},[747,34623,34624],{"class":753},"        cni.projectcalico.org\u002FpodIP",[747,34626,856],{"class":757},[747,34628,34629],{"class":802}," 100.67.207.68\u002F32\n",[747,34631,34632,34635,34637],{"class":749,"line":836},[747,34633,34634],{"class":753},"Status",[747,34636,856],{"class":757},[747,34638,34639],{"class":802},"             Running\n",[747,34641,34642,34645,34647],{"class":749,"line":842},[747,34643,34644],{"class":753},"IP",[747,34646,856],{"class":757},[747,34648,34649],{"class":1895},"                 100.67.207.68\n",[747,34651,34652,34655,34657],{"class":749,"line":850},[747,34653,34654],{"class":753},"Controlled By",[747,34656,856],{"class":757},[747,34658,34659],{"class":802},"      ReplicaSet\u002Fwordpress-56bdcbcb5b\n",[747,34661,34662,34664],{"class":749,"line":863},[747,34663,11586],{"class":753},[747,34665,758],{"class":757},[747,34667,34668,34670],{"class":749,"line":869},[747,34669,10976],{"class":753},[747,34671,758],{"class":757},[747,34673,34674,34677,34679],{"class":749,"line":877},[747,34675,34676],{"class":753},"    Container ID",[747,34678,856],{"class":757},[747,34680,34681],{"class":802},"   containerd:\u002F\u002F301ffa076b4151276e97e2c9df9f9e3788aa1cb6bfead00b70f84d04d78b4595\n",[747,34683,34684,34687,34689],{"class":749,"line":1015},[747,34685,34686],{"class":753},"    Image",[747,34688,856],{"class":757},[747,34690,34691],{"class":802},"          wordpress:5.1.1-php7.1-apache\n",[747,34693,34694,34697,34699],{"class":749,"line":1021},[747,34695,34696],{"class":753},"    Image ID",[747,34698,856],{"class":757},[747,34700,34701],{"class":802},"       docker.io\u002Flibrary\u002Fwordpress@sha256:ec14baae52d61e409ea4c2ccaf63401a660266977b0b6ec2dc81396f55f27f57\n",[747,34703,34704,34707,34709],{"class":749,"line":1027},[747,34705,34706],{"class":753},"    Port",[747,34708,856],{"class":757},[747,34710,34711],{"class":802},"           80\u002FTCP\n",[747,34713,34714,34717,34719],{"class":749,"line":1033},[747,34715,34716],{"class":753},"    Host Port",[747,34718,856],{"class":757},[747,34720,34721],{"class":802},"      0\u002FTCP\n",[747,34723,34724,34727,34729],{"class":749,"line":1039},[747,34725,34726],{"class":753},"    State",[747,34728,856],{"class":757},[747,34730,34731],{"class":802},"          Running\n",[747,34733,34734,34737,34739],{"class":749,"line":1054},[747,34735,34736],{"class":753},"      Started",[747,34738,856],{"class":757},[747,34740,34741],{"class":802},"      Sun, 05 May 2019 22:51:07 +0200\n",[747,34743,34744,34747,34749],{"class":749,"line":1060},[747,34745,34746],{"class":753},"    Ready",[747,34748,856],{"class":757},[747,34750,34751],{"class":859},"          True\n",[747,34753,34754,34757,34759],{"class":749,"line":1066},[747,34755,34756],{"class":753},"    Restart Count",[747,34758,856],{"class":757},[747,34760,34761],{"class":1895},"  0\n",[747,34763,34764,34767],{"class":749,"line":1081},[747,34765,34766],{"class":753},"    Environment",[747,34768,758],{"class":757},[747,34770,34771,34773,34775],{"class":749,"line":1087},[747,34772,11011],{"class":753},[747,34774,856],{"class":757},[747,34776,34777],{"class":802},"      mysql\n",[747,34779,34780,34782,34784],{"class":749,"line":1102},[747,34781,11039],{"class":753},[747,34783,856],{"class":757},[747,34785,34786],{"class":802},"  changeme\n",[747,34788,34789,34792],{"class":749,"line":1110},[747,34790,34791],{"class":753},"    Mounts",[747,34793,758],{"class":757},[747,34795,34796],{"class":749,"line":1117},[747,34797,34798],{"class":802},"      \u002Fvar\u002Frun\u002Fsecrets\u002Fkubernetes.io\u002Fserviceaccount from default-token-lb5tz (ro)\n",[747,34800,34801,34804],{"class":749,"line":1123},[747,34802,34803],{"class":753},"Conditions",[747,34805,758],{"class":757},[747,34807,34808],{"class":749,"line":1129},[747,34809,34810],{"class":802},"  Type              Status\n",[747,34812,34813],{"class":749,"line":1142},[747,34814,34815],{"class":802},"  Initialized       True\n",[747,34817,34818],{"class":749,"line":1150},[747,34819,34820],{"class":802},"  Ready             True\n",[747,34822,34823],{"class":749,"line":1157},[747,34824,34825],{"class":802},"  ContainersReady   True\n",[747,34827,34828],{"class":749,"line":1163},[747,34829,34830],{"class":802},"  PodScheduled      True\n",[747,34832,34833,34836],{"class":749,"line":1168},[747,34834,34835],{"class":753},"Volumes",[747,34837,758],{"class":757},[747,34839,34840,34843],{"class":749,"line":1174},[747,34841,34842],{"class":753},"  default-token-lb5tz",[747,34844,758],{"class":757},[747,34846,34847,34850,34852],{"class":749,"line":1480},[747,34848,34849],{"class":753},"    Type",[747,34851,856],{"class":757},[747,34853,34854],{"class":802},"        Secret (a volume populated by a Secret)\n",[747,34856,34857,34860,34862],{"class":749,"line":1491},[747,34858,34859],{"class":753},"    SecretName",[747,34861,856],{"class":757},[747,34863,34864],{"class":802},"  default-token-lb5tz\n",[747,34866,34867,34870,34872],{"class":749,"line":1496},[747,34868,34869],{"class":753},"    Optional",[747,34871,856],{"class":757},[747,34873,34874],{"class":859},"    false\n",[747,34876,34877,34880,34882],{"class":749,"line":1502},[747,34878,34879],{"class":753},"QoS Class",[747,34881,856],{"class":757},[747,34883,34884],{"class":802},"       BestEffort\n",[747,34886,34887,34890,34892],{"class":749,"line":1510},[747,34888,34889],{"class":753},"Node-Selectors",[747,34891,856],{"class":757},[747,34893,34575],{"class":802},[747,34895,34896,34899,34901],{"class":749,"line":1520},[747,34897,34898],{"class":753},"Tolerations",[747,34900,856],{"class":757},[747,34902,34903],{"class":802},"     node.kubernetes.io\u002Fnot-ready:NoExecute for 300s\n",[747,34905,34906],{"class":749,"line":1525},[747,34907,34908],{"class":802},"                 node.kubernetes.io\u002Funreachable:NoExecute for 300s\n",[747,34910,34911,34913],{"class":749,"line":1533},[747,34912,34514],{"class":753},[747,34914,758],{"class":757},[747,34916,34917],{"class":749,"line":1539},[747,34918,34919],{"class":802},"  Type    Reason     Age    From                                                            Message\n",[747,34921,34922],{"class":749,"line":1549},[747,34923,34924],{"class":802},"  ----    ------     ----   ----                                                            -------\n",[747,34926,34927],{"class":749,"line":1554},[747,34928,34929],{"class":802},"  Normal  Scheduled  4m16s  default-scheduler                                               Successfully assigned default\u002Fwordpress-56bdcbcb5b-jhpjw to k8s02-node-9one1voqljz-htz-deu-fsn1dc1.clster.systems\n",[747,34931,34932],{"class":749,"line":1562},[747,34933,34934],{"class":802},"  Normal  Pulled     4m15s  kubelet, k8s02-node-9one1voqljz-htz-deu-fsn1dc1.clster.systems  Container image \"wordpress:5.1.1-php7.1-apache\" already present on machine\n",[747,34936,34937],{"class":749,"line":1568},[747,34938,34939],{"class":802},"  Normal  Created    4m15s  kubelet, k8s02-node-9one1voqljz-htz-deu-fsn1dc1.clster.systems  Created container wordpress\n",[747,34941,34942],{"class":749,"line":1577},[747,34943,34944],{"class":802},"  Normal  Started    4m14s  kubelet, k8s02-node-9one1voqljz-htz-deu-fsn1dc1.clster.systems  Started container wordpress\n",[523,34946,34947,34948,714,34951,34953],{},"Instead of having to look through the massive YAML output of running ",[567,34949,34950],{},"kubectl get TYPE OBJECT_NAME -o yaml",[567,34952,34505],{}," outputs most information that is needed to look into an issue.",[523,34955,34956,34957,34960],{},"Be sure to use it if you should have issues and\u002F or encounter weird behavior (e.g., no Pods starting for a Deployment (",[567,34958,34959],{},"kubectl describe deployment OBJECT_NAME","), etc).",[2979,34962],{},[535,34964,34966],{"id":34965},"get-creative-with-your-kubernetes-cluster","Get creative with your Kubernetes cluster!",[523,34968,34969],{},"To further deepen the new knowledge we have made, let's deploy an PHP Guestbook application that uses Redis.",[523,34971,34972,34973,1909],{},"For that please follow the instructions here: ",[527,34974,34977],{"href":34975,"rel":34976},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Ftutorials\u002Fstateless-application\u002Fguestbook\u002F",[531],"Example: Deploying PHP Guestbook application with Redis - Kubernetes documentation",[523,34979,34980],{},[3069,34981],{"alt":34982,"src":34983},"Kubernetes Guestbook Tutorial Content","\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day2\u002Fkubernetes-guestbook-agenda.png",[523,34985,34986],{},"If you have questions and\u002F or issues with the instructions or questions about Kubernetes, please let me know\u002F ask them now.",[613,34988,34990],{"id":34989},"already-done-with-the-php-guestbook-application-on-kubernetes","Already done with the PHP Guestbook application on Kubernetes?",[523,34992,34993,34994,34999,35000,35003],{},"You can look into the ",[527,34995,34998],{"href":34996,"rel":34997},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Ftutorials\u002Fkubernetes-basics\u002F",[531],"Kubernetes - Learn Kubernetes Basics"," page and go through the ",[567,35001,35002],{},"^.+ Your App"," tutorials linked in the sidebar, for more tasks to deepen your knowledge, or take a break for a few minutes to relax your brain.",[613,35005,14526],{"id":14525},[523,35007,35008],{},"You have successfully learned about the basic objects and commands to deploy an application onto of Kubernetes as a container.",[523,35010,35011],{},"We will now move on the deploying your own Kubernetes cluster in the next section (and after the break).",[2979,35013],{},[535,35015,35017],{"id":35016},"deploy-your-own-kubernetes-cluster","Deploy your own Kubernetes cluster",[523,35019,35020],{},[3049,35021,35022],{},"Follow these simple steps to get a Kubernetes cluster up and running fast.",[523,35024,35025],{},"The recipe for a Kubernetes cluster is as follows:",[668,35027,35028,35031,35034,35037,35040,35043],{},[638,35029,35030],{},"500g flour",[638,35032,35033],{},"75g sugar",[638,35035,35036],{},"1 pinch of salt",[638,35038,35039],{},"200ml of lukewarm milk",[638,35041,35042],{},"100g soft butter",[638,35044,35045],{},"2 eggs",[523,35047,35048],{},"Just kidding, we are not beginning to bake a cake now or are we?",[523,35050,35051,35052,35054],{},"You will need to have at least one server which will be used for the ",[567,35053,19628],{}," components.",[613,35056,35058,35059,13426],{"id":35057},"what-is-kubeadm","What is ",[567,35060,162],{},[523,35062,35063,35065,35066,35068,35069,35071],{},[567,35064,162],{}," is the official Tool to configure a ",[567,35067,26920],{},", which is the node component of Kubernetes, to run in master or node \"mode\" in the end.\nThere are other tools\u002F ways to deploy Kubernetes, which awill be listed in the upcoming sub section.\nReason why ",[567,35070,162],{}," is used here is simply because it is an official tool which is \"guaranteed\" to work with the Kubernetes version released (they follow the same release cycle).",[3126,35073,35075,35076],{"id":35074},"alternatives-additions-to-kubeadm","\"Alternatives\"\u002F Additions to ",[567,35077,162],{},[668,35079,35080,35086,35094,35102],{},[638,35081,35082,35085],{},[527,35083,15212],{"href":15210,"rel":35084},[531]," - Ansible deployment for Kubernetes.",[638,35087,35088,35093],{},[527,35089,35092],{"href":35090,"rel":35091},"https:\u002F\u002Fkublr.com\u002F",[531],"kublr"," - \"Reliable, Secure Container Management - Designed for modern enterprise\".",[638,35095,35096,35101],{},[527,35097,35100],{"href":35098,"rel":35099},"https:\u002F\u002Fgithub.com\u002Fkelseyhightower\u002Fkubernetes-the-hard-way",[531],"Kelsey Hightower's Kubernetes The Hard Way"," - If you want to learn \"everything\" about Kubernetes, follow the guide and it will lead you down the rabbit hole of Kubernetes.",[638,35103,35104,35105],{},"One of the many Cloud Kubernetes solutions:\n",[668,35106,35107,35110,35113],{},[638,35108,35109],{},"Google Kubernetes Engine (GKE)",[638,35111,35112],{},"Azure Kubernetes Service (AKS)",[638,35114,35115],{},"Amazon Managed Kubernetes Service (EKS)",[523,35117,35118,35119,1909],{},"Many factors play into what is the right way for you to run\u002F install\u002F buy Kubernetes, this Kubernetes documentation page can help you with a list of \"all\" available solutions: ",[527,35120,35123],{"href":35121,"rel":35122},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fsetup\u002Fpick-right-solution\u002F",[531],"Picking the right solution - Kubernetes documentation",[613,35125,35127,35128,35130],{"id":35126},"what-are-kubeadms-prerequisites","What are ",[567,35129,162],{},"'s prerequisites?",[523,35132,35133],{},"Hard-\u002F Software-Requirements are as follows:",[668,35135,35136,35139,35150],{},[638,35137,35138],{},"Servers must have at least 2 CPU (cores\u002F threads) and at least 2GB of RAM.",[638,35140,35141,35142],{},"OS: Linux or Windows\n",[668,35143,35144,35147],{},[638,35145,35146],{},"Linux: Recommended to have Kernel 4.x or better.",[638,35148,35149],{},"Windows: Support was just added with Kubernetes v1.14.",[638,35151,35152,35153],{},"Container runtime:\n",[668,35154,35155,35160],{},[638,35156,35157],{},[527,35158,12175],{"href":26444,"rel":35159},[531],[638,35161,14231,35162,35164,35165,35168,35169,35171,35172],{},[584,35163,27780],{},"ontainer",[584,35166,35167],{},"R","untime",[584,35170,27787],{},"nterface (CRI) compatible container runtime\n",[668,35173,35174],{},[638,35175,706,35176,714,35180,10580],{},[527,35177,26898],{"href":35178,"rel":35179},"https:\u002F\u002Fcontainerd.io",[531],[527,35181,401],{"href":35182,"rel":35183},"https:\u002F\u002Fgithub.com\u002Fkubernetes-sigs\u002Fcri-o",[531],[613,35185,35187],{"id":35186},"steps-to-your-own-kubernetes-cluster","Steps to your own Kubernetes cluster",[3126,35189,35191],{"id":35190},"stop-architecture-time","Stop, Architecture time!",[523,35193,35194],{},[3069,35195],{"alt":26582,"src":35196},"\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day2\u002Fkubernetes-cluster-architecture.png",[523,35198,35199],{},"More detailed information on each component with some insights, will be given later.",[3142,35201,35203],{"id":35202},"network-architecture","Network Architecture",[523,35205,35206],{},"A Kubernetes cluster always requires at least two IP ranges:",[668,35208,35209,35212],{},[638,35210,35211],{},"Service\u002F Cluster IP address range - IP address range to select IPs for Services from.",[638,35213,35214,35215,35217,35218],{},"Pod IP range - IP address range to select an IP for each non-",[567,35216,12759],{}," Pod in the Kubernetes cluster.\n",[668,35219,35220],{},[638,35221,35222],{},"This can be \"optional\" depending on, e.g., the CNI plugin you are using and other factors.",[3126,35224,35226,35228],{"id":35225},"kubeadm-installation",[567,35227,162],{}," Installation",[523,35230,35231,35232,587,35234,35236,35237,1909],{},"The instructions for the ",[567,35233,162],{},[567,35235,26920],{}," installation have been taken from the Kubernetes documentation, see ",[527,35238,35241],{"href":35239,"rel":35240},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fsetup\u002Findependent\u002Finstall-kubeadm\u002F#installing-kubeadm-kubelet-and-kubectl",[531],"Installing kubeadm - Kubernetes documentation",[6072,35243,35244,35248],{},[523,35245,35246],{},[584,35247,6189],{},[523,35249,35250,35251,35253,35254,35256,35257,587,35259,35261],{},"An important point to mention is that ",[567,35252,162],{}," is only doing the configuration of the ",[567,35255,26920],{},", which will then take care of spawning the components needed.\nThis means that we need to care to install the correct version of both ",[567,35258,162],{},[567,35260,26920],{}," packages.",[523,35263,35264],{},"To be able to install the packages we need to add the Kubernetes repository for RHEL-based systems:",[738,35266,35268],{"className":1621,"code":35267,"language":1623,"meta":743,"style":743},"cat \u003C\u003CEOF > \u002Fetc\u002Fyum.repos.d\u002Fkubernetes.repo\n[kubernetes]\nname=Kubernetes\nbaseurl=https:\u002F\u002Fpackages.cloud.google.com\u002Fyum\u002Frepos\u002Fkubernetes-el7-x86_64\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=https:\u002F\u002Fpackages.cloud.google.com\u002Fyum\u002Fdoc\u002Fyum-key.gpg https:\u002F\u002Fpackages.cloud.google.com\u002Fyum\u002Fdoc\u002Frpm-package-key.gpg\nexclude=kube*\nEOF\n",[567,35269,35270,35286,35291,35296,35301,35306,35311,35316,35321,35326],{"__ignoreMap":743},[747,35271,35272,35274,35277,35280,35283],{"class":749,"line":750},[747,35273,6515],{"class":1630},[747,35275,35276],{"class":757}," \u003C\u003C",[747,35278,35279],{"class":757},"EOF",[747,35281,35282],{"class":757}," >",[747,35284,35285],{"class":802}," \u002Fetc\u002Fyum.repos.d\u002Fkubernetes.repo\n",[747,35287,35288],{"class":749,"line":761},[747,35289,35290],{"class":802},"[kubernetes]\n",[747,35292,35293],{"class":749,"line":769},[747,35294,35295],{"class":802},"name=Kubernetes\n",[747,35297,35298],{"class":749,"line":776},[747,35299,35300],{"class":802},"baseurl=https:\u002F\u002Fpackages.cloud.google.com\u002Fyum\u002Frepos\u002Fkubernetes-el7-x86_64\n",[747,35302,35303],{"class":749,"line":784},[747,35304,35305],{"class":802},"enabled=1\n",[747,35307,35308],{"class":749,"line":790},[747,35309,35310],{"class":802},"gpgcheck=1\n",[747,35312,35313],{"class":749,"line":796},[747,35314,35315],{"class":802},"repo_gpgcheck=1\n",[747,35317,35318],{"class":749,"line":806},[747,35319,35320],{"class":802},"gpgkey=https:\u002F\u002Fpackages.cloud.google.com\u002Fyum\u002Fdoc\u002Fyum-key.gpg https:\u002F\u002Fpackages.cloud.google.com\u002Fyum\u002Fdoc\u002Frpm-package-key.gpg\n",[747,35322,35323],{"class":749,"line":814},[747,35324,35325],{"class":802},"exclude=kube*\n",[747,35327,35328],{"class":749,"line":822},[747,35329,35330],{"class":757},"EOF\n",[523,35332,35333],{},"Well.. SELinux everyone has it enabled, right guys? Right now it is recommended to disable SELinux.\nAt one point we can hope for good SELinux support for Kubernetes.",[523,35335,35336],{},"Let's go ahead and disable it:",[738,35338,35340],{"className":1621,"code":35339,"language":1623,"meta":743,"style":743},"# Set SELinux in permissive mode (effectively disabling it)\nsetenforce 0\nsed -i 's\u002F^SELINUX=enforcing$\u002FSELINUX=permissive\u002F' \u002Fetc\u002Fselinux\u002Fconfig\n",[567,35341,35342,35347,35354],{"__ignoreMap":743},[747,35343,35344],{"class":749,"line":750},[747,35345,35346],{"class":772},"# Set SELinux in permissive mode (effectively disabling it)\n",[747,35348,35349,35352],{"class":749,"line":761},[747,35350,35351],{"class":1630},"setenforce",[747,35353,7863],{"class":1895},[747,35355,35356,35359,35361,35363,35366,35368],{"class":749,"line":769},[747,35357,35358],{"class":1630},"sed",[747,35360,1637],{"class":802},[747,35362,3537],{"class":757},[747,35364,35365],{"class":802},"s\u002F^SELINUX=enforcing$\u002FSELINUX=permissive\u002F",[747,35367,3543],{"class":757},[747,35369,35370],{"class":802}," \u002Fetc\u002Fselinux\u002Fconfig\n",[523,35372,35373,35374,35376],{},"After that we can just go ahead and install the following packages and enable the ",[567,35375,26920],{}," service:",[668,35378,35379,35384,35391],{},[638,35380,35381,35383],{},[567,35382,26920],{}," - The node component of Kubernetes, which takes care of talking with the container runtime to run containers.",[638,35385,35386,35388,35389,1909],{},[567,35387,162],{}," - The \"configuration utility\" for the ",[567,35390,26920],{},[638,35392,35393,35395],{},[567,35394,15269],{}," - Kubernetes client utility, doesn't hurt if it is on every server, no matter if just a node. It is only \"needed\" on the master(s) because we will use the master VM to access the Kubernetes API through it.",[738,35397,35399],{"className":1621,"code":35398,"language":1623,"meta":743,"style":743},"dnf install -y kubelet kubeadm kubectl --disableexcludes=kubernetes\nsystemctl enable --now kubelet\n# Set the \"new\" K8S CNI plugins path for the kubelet (because Docker is used we can do it on the kubelet)\nsed -i 's|KUBELET_EXTRA_ARGS=|KUBELET_EXTRA_ARGS=--cni-bin-dir=\u002Fopt\u002Fcni\u002Fbin,\u002Fusr\u002Flibexec\u002Fcni |' \u002Fetc\u002Fsysconfig\u002Fkubelet\n",[567,35400,35401,35423,35435,35440],{"__ignoreMap":743},[747,35402,35403,35406,35409,35412,35415,35418,35420],{"class":749,"line":750},[747,35404,35405],{"class":1630},"dnf",[747,35407,35408],{"class":802}," install",[747,35410,35411],{"class":802}," -y",[747,35413,35414],{"class":802}," kubelet",[747,35416,35417],{"class":802}," kubeadm",[747,35419,1922],{"class":802},[747,35421,35422],{"class":802}," --disableexcludes=kubernetes\n",[747,35424,35425,35427,35429,35432],{"class":749,"line":761},[747,35426,3202],{"class":1630},[747,35428,3205],{"class":802},[747,35430,35431],{"class":802}," --now",[747,35433,35434],{"class":802}," kubelet\n",[747,35436,35437],{"class":749,"line":769},[747,35438,35439],{"class":772},"# Set the \"new\" K8S CNI plugins path for the kubelet (because Docker is used we can do it on the kubelet)\n",[747,35441,35442,35444,35446,35448,35451,35453],{"class":749,"line":776},[747,35443,35358],{"class":1630},[747,35445,1637],{"class":802},[747,35447,3537],{"class":757},[747,35449,35450],{"class":802},"s|KUBELET_EXTRA_ARGS=|KUBELET_EXTRA_ARGS=--cni-bin-dir=\u002Fopt\u002Fcni\u002Fbin,\u002Fusr\u002Flibexec\u002Fcni |",[747,35452,3543],{"class":757},[747,35454,35455],{"class":802}," \u002Fetc\u002Fsysconfig\u002Fkubelet\n",[6072,35457,35458,35462],{},[523,35459,35460],{},[584,35461,6189],{},[523,35463,35464,35465,714,35468,35471],{},"CNI plugin path fix: In case of other CRI compatile container runtimes, e.g., ",[527,35466,26898],{"href":35178,"rel":35467},[531],[527,35469,401],{"href":35182,"rel":35470},[531],", this would need to be done in the container runtimes config file(s).",[523,35473,35474,35475,1909],{},"After that we can go ahead and setup the initial master for the Kuberntes cluster using ",[567,35476,162],{},[3126,35478,35480],{"id":35479},"setting-up-the-initial-master-of-the-kubernetes-cluster","Setting up the initial master of the Kubernetes cluster",[6072,35482,35483,35487,35494],{},[523,35484,35485],{},[584,35486,6189],{},[523,35488,35489,35490,35493],{},"Only run this on the first master server! The other master servers don't need to be ",[567,35491,35492],{},"init","ialized, they need to be joined to the first Kubernetes master server.",[523,35495,35496,35497,1909],{},"For more information on high availability Kubernetes clusters, see ",[527,35498,35501],{"href":35499,"rel":35500},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fsetup\u002Findependent\u002Fhigh-availability\u002F",[531],"Creating Highly Available Clusters with kubeadm - Kubernetes",[523,35503,35504,35505,28768],{},"To setup the initial master of the Kubernetes cluster, we will use the ",[567,35506,35507],{},"kubeadm init",[738,35509,35511],{"className":1621,"code":35510,"language":1623,"meta":743,"style":743},"$ kubeadm init \\\n    --pod-network-cidr=100.64.0.0\u002F13 \\\n    --service-cidr=100.72.0.0\u002F13\n[init] Using Kubernetes version: v1.14.1\n[preflight] Running pre-flight checks\n    [WARNING IsDockerSystemdCheck]: detected \"cgroupfs\" as the Docker cgroup driver. The recommended driver is \"systemd\". Please follow the guide at https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fsetup\u002Fcri\u002F\n[preflight] Pulling images required for setting up a Kubernetes cluster\n[preflight] This might take a minute or two, depending on the speed of your internet connection\n[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'\n[kubelet-start] Writing kubelet environment file with flags to file \"\u002Fvar\u002Flib\u002Fkubelet\u002Fkubeadm-flags.env\"\n[kubelet-start] Writing kubelet configuration to file \"\u002Fvar\u002Flib\u002Fkubelet\u002Fconfig.yaml\"\n[kubelet-start] Activating the kubelet service\n[certs] Using certificateDir folder \"\u002Fetc\u002Fkubernetes\u002Fpki\"\n[certs] Generating \"ca\" certificate and key\n[certs] Generating \"apiserver\" certificate and key\n[certs] apiserver serving cert is signed for DNS names [k8s-c1-master-1.eden.run kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [100.72.0.1 159.69.244.41]\n[certs] Generating \"apiserver-kubelet-client\" certificate and key\n[certs] Generating \"front-proxy-ca\" certificate and key\n[certs] Generating \"front-proxy-client\" certificate and key\n[certs] Generating \"etcd\u002Fca\" certificate and key\n[certs] Generating \"etcd\u002Fserver\" certificate and key\n[certs] etcd\u002Fserver serving cert is signed for DNS names [k8s-c1-master-1.eden.run localhost] and IPs [159.69.244.41 127.0.0.1 ::1]\n[certs] Generating \"etcd\u002Fpeer\" certificate and key\n[certs] etcd\u002Fpeer serving cert is signed for DNS names [k8s-c1-master-1.eden.run localhost] and IPs [159.69.244.41 127.0.0.1 ::1]\n[certs] Generating \"etcd\u002Fhealthcheck-client\" certificate and key\n[certs] Generating \"apiserver-etcd-client\" certificate and key\n[certs] Generating \"sa\" key and public key\n[kubeconfig] Using kubeconfig folder \"\u002Fetc\u002Fkubernetes\"\n[kubeconfig] Writing \"admin.conf\" kubeconfig file\n[kubeconfig] Writing \"kubelet.conf\" kubeconfig file\n[kubeconfig] Writing \"controller-manager.conf\" kubeconfig file\n[kubeconfig] Writing \"scheduler.conf\" kubeconfig file\n[control-plane] Using manifest folder \"\u002Fetc\u002Fkubernetes\u002Fmanifests\"\n[control-plane] Creating static Pod manifest for \"kube-apiserver\"\n[control-plane] Creating static Pod manifest for \"kube-controller-manager\"\n[control-plane] Creating static Pod manifest for \"kube-scheduler\"\n[etcd] Creating static Pod manifest for local etcd in \"\u002Fetc\u002Fkubernetes\u002Fmanifests\"\n[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory \"\u002Fetc\u002Fkubernetes\u002Fmanifests\". This can take up to 4m0s\n[apiclient] All control plane components are healthy after 15.502780 seconds\n[upload-config] storing the configuration used in ConfigMap \"kubeadm-config\" in the \"kube-system\" Namespace\n[kubelet] Creating a ConfigMap \"kubelet-config-1.14\" in namespace kube-system with the configuration for the kubelets in the cluster\n[upload-certs] Skipping phase. Please see --experimental-upload-certs\n[mark-control-plane] Marking the node k8s-c1-master-1.eden.run as control-plane by adding the label \"node-role.kubernetes.io\u002Fmaster=''\"\n[mark-control-plane] Marking the node k8s-c1-master-1.eden.run as control-plane by adding the taints [node-role.kubernetes.io\u002Fmaster:NoSchedule]\n[bootstrap-token] Using token: mqn3hg.p8r8p7yyi7ozoqbx\n[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles\n[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials\n[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token\n[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster\n[bootstrap-token] creating the \"cluster-info\" ConfigMap in the \"kube-public\" namespace\n[addons] Applied essential addon: CoreDNS\n[addons] Applied essential addon: kube-proxy\n\nYour Kubernetes control-plane has initialized successfully!\n\nTo start using your cluster, you need to run the following as a regular user:\n\n  mkdir -p $HOME\u002F.kube\n  sudo cp -i \u002Fetc\u002Fkubernetes\u002Fadmin.conf $HOME\u002F.kube\u002Fconfig\n  sudo chown $(id -u):$(id -g) $HOME\u002F.kube\u002Fconfig\n\nYou should now deploy a pod network to the cluster.\nRun \"kubectl apply -f [podnetwork].yaml\" with one of the options listed at:\n  https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fcluster-administration\u002Faddons\u002F\n\nThen you can join any number of worker nodes by running the following on each as root:\n\nkubeadm join 159.69.244.41:6443 --token mqn3hg.p8r8p7yyi7ozoqbx \\\n    --discovery-token-ca-cert-hash sha256:4000680d6a69786e1d69c3f7aef7fd03c533665e00f35886e0d2b33754d3c03c\n",[567,35512,35513,35524,35531,35536,35547,35559,35627,35644,35655,35673,35692,35710,35721,35740,35761,35780,35816,35835,35854,35873,35892,35911,35948,35967,36000,36019,36038,36058,36077,36098,36117,36136,36155,36174,36193,36211,36229,36250,36276,36288,36318,36344,36356,36375,36393,36405,36416,36432,36443,36459,36490,36501,36512,36516,36534,36538,36575,36579,36592,36610,36642,36646,36674,36703,36708,36712,36757,36761,36778],{"__ignoreMap":743},[747,35514,35515,35517,35519,35522],{"class":749,"line":750},[747,35516,1919],{"class":1630},[747,35518,35417],{"class":802},[747,35520,35521],{"class":802}," init",[747,35523,1641],{"class":1640},[747,35525,35526,35529],{"class":749,"line":761},[747,35527,35528],{"class":802},"    --pod-network-cidr=100.64.0.0\u002F13",[747,35530,1641],{"class":1640},[747,35532,35533],{"class":749,"line":769},[747,35534,35535],{"class":802},"    --service-cidr=100.72.0.0\u002F13\n",[747,35537,35538,35540,35542,35544],{"class":749,"line":776},[747,35539,4253],{"class":757},[747,35541,35492],{"class":1640},[747,35543,4259],{"class":757},[747,35545,35546],{"class":1640}," Using Kubernetes version: v1.14.1\n",[747,35548,35549,35551,35554,35556],{"class":749,"line":784},[747,35550,4253],{"class":757},[747,35552,35553],{"class":1640},"preflight",[747,35555,4259],{"class":757},[747,35557,35558],{"class":1640}," Running pre-flight checks\n",[747,35560,35561,35564,35567,35569,35571,35574,35576,35579,35581,35583,35585,35587,35589,35592,35594,35597,35599,35601,35603,35606,35608,35610,35613,35616,35618,35621,35624],{"class":749,"line":790},[747,35562,35563],{"class":757},"    [",[747,35565,35566],{"class":1640},"WARNING IsDockerSystemdCheck",[747,35568,4259],{"class":757},[747,35570,856],{"class":4574},[747,35572,35573],{"class":802}," detected",[747,35575,969],{"class":757},[747,35577,35578],{"class":802},"cgroupfs",[747,35580,3892],{"class":757},[747,35582,5155],{"class":802},[747,35584,3839],{"class":802},[747,35586,3833],{"class":802},[747,35588,4531],{"class":802},[747,35590,35591],{"class":802}," driver.",[747,35593,3853],{"class":802},[747,35595,35596],{"class":802}," recommended",[747,35598,5362],{"class":802},[747,35600,5068],{"class":802},[747,35602,969],{"class":757},[747,35604,35605],{"class":802},"systemd",[747,35607,3892],{"class":757},[747,35609,1909],{"class":802},[747,35611,35612],{"class":802}," Please",[747,35614,35615],{"class":802}," follow",[747,35617,3839],{"class":802},[747,35619,35620],{"class":802}," guide",[747,35622,35623],{"class":802}," at",[747,35625,35626],{"class":802}," https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fsetup\u002Fcri\u002F\n",[747,35628,35629,35631,35633,35635,35638,35641],{"class":749,"line":796},[747,35630,4253],{"class":757},[747,35632,35553],{"class":1640},[747,35634,4259],{"class":757},[747,35636,35637],{"class":1640}," Pulling images required ",[747,35639,35640],{"class":19332},"for",[747,35642,35643],{"class":1640}," setting up a Kubernetes cluster\n",[747,35645,35646,35648,35650,35652],{"class":749,"line":806},[747,35647,4253],{"class":757},[747,35649,35553],{"class":1640},[747,35651,4259],{"class":757},[747,35653,35654],{"class":1640}," This might take a minute or two, depending on the speed of your internet connection\n",[747,35656,35657,35659,35661,35663,35666,35668,35671],{"class":749,"line":814},[747,35658,4253],{"class":757},[747,35660,35553],{"class":1640},[747,35662,4259],{"class":757},[747,35664,35665],{"class":1640}," You can also perform this action in beforehand using ",[747,35667,3543],{"class":757},[747,35669,35670],{"class":802},"kubeadm config images pull",[747,35672,13042],{"class":757},[747,35674,35675,35677,35680,35682,35685,35687,35690],{"class":749,"line":822},[747,35676,4253],{"class":757},[747,35678,35679],{"class":1640},"kubelet-start",[747,35681,4259],{"class":757},[747,35683,35684],{"class":1640}," Writing kubelet environment file with flags to file ",[747,35686,3892],{"class":757},[747,35688,35689],{"class":802},"\u002Fvar\u002Flib\u002Fkubelet\u002Fkubeadm-flags.env",[747,35691,975],{"class":757},[747,35693,35694,35696,35698,35700,35703,35705,35708],{"class":749,"line":830},[747,35695,4253],{"class":757},[747,35697,35679],{"class":1640},[747,35699,4259],{"class":757},[747,35701,35702],{"class":1640}," Writing kubelet configuration to file ",[747,35704,3892],{"class":757},[747,35706,35707],{"class":802},"\u002Fvar\u002Flib\u002Fkubelet\u002Fconfig.yaml",[747,35709,975],{"class":757},[747,35711,35712,35714,35716,35718],{"class":749,"line":836},[747,35713,4253],{"class":757},[747,35715,35679],{"class":1640},[747,35717,4259],{"class":757},[747,35719,35720],{"class":1640}," Activating the kubelet service\n",[747,35722,35723,35725,35728,35730,35733,35735,35738],{"class":749,"line":842},[747,35724,4253],{"class":757},[747,35726,35727],{"class":1640},"certs",[747,35729,4259],{"class":757},[747,35731,35732],{"class":1640}," Using certificateDir folder ",[747,35734,3892],{"class":757},[747,35736,35737],{"class":802},"\u002Fetc\u002Fkubernetes\u002Fpki",[747,35739,975],{"class":757},[747,35741,35742,35744,35746,35748,35751,35753,35756,35758],{"class":749,"line":850},[747,35743,4253],{"class":757},[747,35745,35727],{"class":1640},[747,35747,4259],{"class":757},[747,35749,35750],{"class":1640}," Generating ",[747,35752,3892],{"class":757},[747,35754,35755],{"class":802},"ca",[747,35757,3892],{"class":757},[747,35759,35760],{"class":1640}," certificate and key\n",[747,35762,35763,35765,35767,35769,35771,35773,35776,35778],{"class":749,"line":863},[747,35764,4253],{"class":757},[747,35766,35727],{"class":1640},[747,35768,4259],{"class":757},[747,35770,35750],{"class":1640},[747,35772,3892],{"class":757},[747,35774,35775],{"class":802},"apiserver",[747,35777,3892],{"class":757},[747,35779,35760],{"class":1640},[747,35781,35782,35784,35786,35788,35791,35793,35796,35798,35801,35803,35806,35808,35811,35814],{"class":749,"line":869},[747,35783,4253],{"class":757},[747,35785,35727],{"class":1640},[747,35787,4259],{"class":757},[747,35789,35790],{"class":1640}," apiserver serving cert is signed ",[747,35792,35640],{"class":19332},[747,35794,35795],{"class":1640}," DNS names ",[747,35797,4253],{"class":757},[747,35799,35800],{"class":1640},"k8s-c1-master-1.eden.run kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local",[747,35802,4259],{"class":757},[747,35804,35805],{"class":1640}," and IPs ",[747,35807,4253],{"class":757},[747,35809,35810],{"class":1895},"100.72.0.1",[747,35812,35813],{"class":1640}," 159.69.244.41",[747,35815,4268],{"class":757},[747,35817,35818,35820,35822,35824,35826,35828,35831,35833],{"class":749,"line":877},[747,35819,4253],{"class":757},[747,35821,35727],{"class":1640},[747,35823,4259],{"class":757},[747,35825,35750],{"class":1640},[747,35827,3892],{"class":757},[747,35829,35830],{"class":802},"apiserver-kubelet-client",[747,35832,3892],{"class":757},[747,35834,35760],{"class":1640},[747,35836,35837,35839,35841,35843,35845,35847,35850,35852],{"class":749,"line":1015},[747,35838,4253],{"class":757},[747,35840,35727],{"class":1640},[747,35842,4259],{"class":757},[747,35844,35750],{"class":1640},[747,35846,3892],{"class":757},[747,35848,35849],{"class":802},"front-proxy-ca",[747,35851,3892],{"class":757},[747,35853,35760],{"class":1640},[747,35855,35856,35858,35860,35862,35864,35866,35869,35871],{"class":749,"line":1021},[747,35857,4253],{"class":757},[747,35859,35727],{"class":1640},[747,35861,4259],{"class":757},[747,35863,35750],{"class":1640},[747,35865,3892],{"class":757},[747,35867,35868],{"class":802},"front-proxy-client",[747,35870,3892],{"class":757},[747,35872,35760],{"class":1640},[747,35874,35875,35877,35879,35881,35883,35885,35888,35890],{"class":749,"line":1027},[747,35876,4253],{"class":757},[747,35878,35727],{"class":1640},[747,35880,4259],{"class":757},[747,35882,35750],{"class":1640},[747,35884,3892],{"class":757},[747,35886,35887],{"class":802},"etcd\u002Fca",[747,35889,3892],{"class":757},[747,35891,35760],{"class":1640},[747,35893,35894,35896,35898,35900,35902,35904,35907,35909],{"class":749,"line":1033},[747,35895,4253],{"class":757},[747,35897,35727],{"class":1640},[747,35899,4259],{"class":757},[747,35901,35750],{"class":1640},[747,35903,3892],{"class":757},[747,35905,35906],{"class":802},"etcd\u002Fserver",[747,35908,3892],{"class":757},[747,35910,35760],{"class":1640},[747,35912,35913,35915,35917,35919,35922,35924,35926,35928,35931,35933,35935,35937,35940,35943,35946],{"class":749,"line":1039},[747,35914,4253],{"class":757},[747,35916,35727],{"class":1640},[747,35918,4259],{"class":757},[747,35920,35921],{"class":1640}," etcd\u002Fserver serving cert is signed ",[747,35923,35640],{"class":19332},[747,35925,35795],{"class":1640},[747,35927,4253],{"class":757},[747,35929,35930],{"class":1640},"k8s-c1-master-1.eden.run localhost",[747,35932,4259],{"class":757},[747,35934,35805],{"class":1640},[747,35936,4253],{"class":757},[747,35938,35939],{"class":1895},"159.69.244.41",[747,35941,35942],{"class":1895}," 127.0.0.1",[747,35944,35945],{"class":1640}," ::1",[747,35947,4268],{"class":757},[747,35949,35950,35952,35954,35956,35958,35960,35963,35965],{"class":749,"line":1054},[747,35951,4253],{"class":757},[747,35953,35727],{"class":1640},[747,35955,4259],{"class":757},[747,35957,35750],{"class":1640},[747,35959,3892],{"class":757},[747,35961,35962],{"class":802},"etcd\u002Fpeer",[747,35964,3892],{"class":757},[747,35966,35760],{"class":1640},[747,35968,35969,35971,35973,35975,35978,35980,35982,35984,35986,35988,35990,35992,35994,35996,35998],{"class":749,"line":1060},[747,35970,4253],{"class":757},[747,35972,35727],{"class":1640},[747,35974,4259],{"class":757},[747,35976,35977],{"class":1640}," etcd\u002Fpeer serving cert is signed ",[747,35979,35640],{"class":19332},[747,35981,35795],{"class":1640},[747,35983,4253],{"class":757},[747,35985,35930],{"class":1640},[747,35987,4259],{"class":757},[747,35989,35805],{"class":1640},[747,35991,4253],{"class":757},[747,35993,35939],{"class":1895},[747,35995,35942],{"class":1895},[747,35997,35945],{"class":1640},[747,35999,4268],{"class":757},[747,36001,36002,36004,36006,36008,36010,36012,36015,36017],{"class":749,"line":1066},[747,36003,4253],{"class":757},[747,36005,35727],{"class":1640},[747,36007,4259],{"class":757},[747,36009,35750],{"class":1640},[747,36011,3892],{"class":757},[747,36013,36014],{"class":802},"etcd\u002Fhealthcheck-client",[747,36016,3892],{"class":757},[747,36018,35760],{"class":1640},[747,36020,36021,36023,36025,36027,36029,36031,36034,36036],{"class":749,"line":1081},[747,36022,4253],{"class":757},[747,36024,35727],{"class":1640},[747,36026,4259],{"class":757},[747,36028,35750],{"class":1640},[747,36030,3892],{"class":757},[747,36032,36033],{"class":802},"apiserver-etcd-client",[747,36035,3892],{"class":757},[747,36037,35760],{"class":1640},[747,36039,36040,36042,36044,36046,36048,36050,36053,36055],{"class":749,"line":1087},[747,36041,4253],{"class":757},[747,36043,35727],{"class":1640},[747,36045,4259],{"class":757},[747,36047,35750],{"class":1640},[747,36049,3892],{"class":757},[747,36051,36052],{"class":802},"sa",[747,36054,3892],{"class":757},[747,36056,36057],{"class":1640}," key and public key\n",[747,36059,36060,36062,36065,36067,36070,36072,36075],{"class":749,"line":1102},[747,36061,4253],{"class":757},[747,36063,36064],{"class":1640},"kubeconfig",[747,36066,4259],{"class":757},[747,36068,36069],{"class":1640}," Using kubeconfig folder ",[747,36071,3892],{"class":757},[747,36073,36074],{"class":802},"\u002Fetc\u002Fkubernetes",[747,36076,975],{"class":757},[747,36078,36079,36081,36083,36085,36088,36090,36093,36095],{"class":749,"line":1110},[747,36080,4253],{"class":757},[747,36082,36064],{"class":1640},[747,36084,4259],{"class":757},[747,36086,36087],{"class":1640}," Writing ",[747,36089,3892],{"class":757},[747,36091,36092],{"class":802},"admin.conf",[747,36094,3892],{"class":757},[747,36096,36097],{"class":1640}," kubeconfig file\n",[747,36099,36100,36102,36104,36106,36108,36110,36113,36115],{"class":749,"line":1117},[747,36101,4253],{"class":757},[747,36103,36064],{"class":1640},[747,36105,4259],{"class":757},[747,36107,36087],{"class":1640},[747,36109,3892],{"class":757},[747,36111,36112],{"class":802},"kubelet.conf",[747,36114,3892],{"class":757},[747,36116,36097],{"class":1640},[747,36118,36119,36121,36123,36125,36127,36129,36132,36134],{"class":749,"line":1123},[747,36120,4253],{"class":757},[747,36122,36064],{"class":1640},[747,36124,4259],{"class":757},[747,36126,36087],{"class":1640},[747,36128,3892],{"class":757},[747,36130,36131],{"class":802},"controller-manager.conf",[747,36133,3892],{"class":757},[747,36135,36097],{"class":1640},[747,36137,36138,36140,36142,36144,36146,36148,36151,36153],{"class":749,"line":1129},[747,36139,4253],{"class":757},[747,36141,36064],{"class":1640},[747,36143,4259],{"class":757},[747,36145,36087],{"class":1640},[747,36147,3892],{"class":757},[747,36149,36150],{"class":802},"scheduler.conf",[747,36152,3892],{"class":757},[747,36154,36097],{"class":1640},[747,36156,36157,36159,36162,36164,36167,36169,36172],{"class":749,"line":1142},[747,36158,4253],{"class":757},[747,36160,36161],{"class":1640},"control-plane",[747,36163,4259],{"class":757},[747,36165,36166],{"class":1640}," Using manifest folder ",[747,36168,3892],{"class":757},[747,36170,36171],{"class":802},"\u002Fetc\u002Fkubernetes\u002Fmanifests",[747,36173,975],{"class":757},[747,36175,36176,36178,36180,36182,36185,36187,36189,36191],{"class":749,"line":1150},[747,36177,4253],{"class":757},[747,36179,36161],{"class":1640},[747,36181,4259],{"class":757},[747,36183,36184],{"class":1640}," Creating static Pod manifest ",[747,36186,35640],{"class":19332},[747,36188,969],{"class":757},[747,36190,26697],{"class":802},[747,36192,975],{"class":757},[747,36194,36195,36197,36199,36201,36203,36205,36207,36209],{"class":749,"line":1157},[747,36196,4253],{"class":757},[747,36198,36161],{"class":1640},[747,36200,4259],{"class":757},[747,36202,36184],{"class":1640},[747,36204,35640],{"class":19332},[747,36206,969],{"class":757},[747,36208,26732],{"class":802},[747,36210,975],{"class":757},[747,36212,36213,36215,36217,36219,36221,36223,36225,36227],{"class":749,"line":1163},[747,36214,4253],{"class":757},[747,36216,36161],{"class":1640},[747,36218,4259],{"class":757},[747,36220,36184],{"class":1640},[747,36222,35640],{"class":19332},[747,36224,969],{"class":757},[747,36226,26844],{"class":802},[747,36228,975],{"class":757},[747,36230,36231,36233,36235,36237,36239,36241,36244,36246,36248],{"class":749,"line":1168},[747,36232,4253],{"class":757},[747,36234,26658],{"class":1640},[747,36236,4259],{"class":757},[747,36238,36184],{"class":1640},[747,36240,35640],{"class":19332},[747,36242,36243],{"class":1640}," local etcd in ",[747,36245,3892],{"class":757},[747,36247,36171],{"class":802},[747,36249,975],{"class":757},[747,36251,36252,36254,36257,36259,36262,36264,36267,36269,36271,36273],{"class":749,"line":1174},[747,36253,4253],{"class":757},[747,36255,36256],{"class":1640},"wait-control-plane",[747,36258,4259],{"class":757},[747,36260,36261],{"class":1640}," Waiting ",[747,36263,35640],{"class":19332},[747,36265,36266],{"class":1640}," the kubelet to boot up the control plane as static Pods from directory ",[747,36268,3892],{"class":757},[747,36270,36171],{"class":802},[747,36272,3892],{"class":757},[747,36274,36275],{"class":1640},". This can take up to 4m0s\n",[747,36277,36278,36280,36283,36285],{"class":749,"line":1480},[747,36279,4253],{"class":757},[747,36281,36282],{"class":1640},"apiclient",[747,36284,4259],{"class":757},[747,36286,36287],{"class":1640}," All control plane components are healthy after 15.502780 seconds\n",[747,36289,36290,36292,36295,36297,36300,36302,36305,36307,36309,36311,36313,36315],{"class":749,"line":1491},[747,36291,4253],{"class":757},[747,36293,36294],{"class":1640},"upload-config",[747,36296,4259],{"class":757},[747,36298,36299],{"class":1640}," storing the configuration used in ConfigMap ",[747,36301,3892],{"class":757},[747,36303,36304],{"class":802},"kubeadm-config",[747,36306,3892],{"class":757},[747,36308,22542],{"class":1640},[747,36310,3892],{"class":757},[747,36312,2101],{"class":802},[747,36314,3892],{"class":757},[747,36316,36317],{"class":1640}," Namespace\n",[747,36319,36320,36322,36324,36326,36329,36331,36334,36336,36339,36341],{"class":749,"line":1496},[747,36321,4253],{"class":757},[747,36323,26920],{"class":1640},[747,36325,4259],{"class":757},[747,36327,36328],{"class":1640}," Creating a ConfigMap ",[747,36330,3892],{"class":757},[747,36332,36333],{"class":802},"kubelet-config-1.14",[747,36335,3892],{"class":757},[747,36337,36338],{"class":1640}," in namespace kube-system with the configuration ",[747,36340,35640],{"class":19332},[747,36342,36343],{"class":1640}," the kubelets in the cluster\n",[747,36345,36346,36348,36351,36353],{"class":749,"line":1502},[747,36347,4253],{"class":757},[747,36349,36350],{"class":1640},"upload-certs",[747,36352,4259],{"class":757},[747,36354,36355],{"class":1640}," Skipping phase. Please see --experimental-upload-certs\n",[747,36357,36358,36360,36363,36365,36368,36370,36373],{"class":749,"line":1510},[747,36359,4253],{"class":757},[747,36361,36362],{"class":1640},"mark-control-plane",[747,36364,4259],{"class":757},[747,36366,36367],{"class":1640}," Marking the node k8s-c1-master-1.eden.run as control-plane by adding the label ",[747,36369,3892],{"class":757},[747,36371,36372],{"class":802},"node-role.kubernetes.io\u002Fmaster=''",[747,36374,975],{"class":757},[747,36376,36377,36379,36381,36383,36386,36388,36391],{"class":749,"line":1520},[747,36378,4253],{"class":757},[747,36380,36362],{"class":1640},[747,36382,4259],{"class":757},[747,36384,36385],{"class":1640}," Marking the node k8s-c1-master-1.eden.run as control-plane by adding the taints ",[747,36387,4253],{"class":757},[747,36389,36390],{"class":1640},"node-role.kubernetes.io\u002Fmaster:NoSchedule",[747,36392,4268],{"class":757},[747,36394,36395,36397,36400,36402],{"class":749,"line":1525},[747,36396,4253],{"class":757},[747,36398,36399],{"class":1640},"bootstrap-token",[747,36401,4259],{"class":757},[747,36403,36404],{"class":1640}," Using token: mqn3hg.p8r8p7yyi7ozoqbx\n",[747,36406,36407,36409,36411,36413],{"class":749,"line":1533},[747,36408,4253],{"class":757},[747,36410,36399],{"class":1640},[747,36412,4259],{"class":757},[747,36414,36415],{"class":1640}," Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles\n",[747,36417,36418,36420,36422,36424,36427,36429],{"class":749,"line":1539},[747,36419,4253],{"class":757},[747,36421,36399],{"class":1640},[747,36423,4259],{"class":757},[747,36425,36426],{"class":1640}," configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order ",[747,36428,35640],{"class":19332},[747,36430,36431],{"class":1640}," nodes to get long term certificate credentials\n",[747,36433,36434,36436,36438,36440],{"class":749,"line":1549},[747,36435,4253],{"class":757},[747,36437,36399],{"class":1640},[747,36439,4259],{"class":757},[747,36441,36442],{"class":1640}," configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token\n",[747,36444,36445,36447,36449,36451,36454,36456],{"class":749,"line":1554},[747,36446,4253],{"class":757},[747,36448,36399],{"class":1640},[747,36450,4259],{"class":757},[747,36452,36453],{"class":1640}," configured RBAC rules to allow certificate rotation ",[747,36455,35640],{"class":19332},[747,36457,36458],{"class":1640}," all node client certificates in the cluster\n",[747,36460,36461,36463,36465,36467,36470,36472,36475,36477,36480,36482,36485,36487],{"class":749,"line":1562},[747,36462,4253],{"class":757},[747,36464,36399],{"class":1640},[747,36466,4259],{"class":757},[747,36468,36469],{"class":1640}," creating the ",[747,36471,3892],{"class":757},[747,36473,36474],{"class":802},"cluster-info",[747,36476,3892],{"class":757},[747,36478,36479],{"class":1640}," ConfigMap in the ",[747,36481,3892],{"class":757},[747,36483,36484],{"class":802},"kube-public",[747,36486,3892],{"class":757},[747,36488,36489],{"class":1640}," namespace\n",[747,36491,36492,36494,36496,36498],{"class":749,"line":1568},[747,36493,4253],{"class":757},[747,36495,27063],{"class":1640},[747,36497,4259],{"class":757},[747,36499,36500],{"class":1640}," Applied essential addon: CoreDNS\n",[747,36502,36503,36505,36507,36509],{"class":749,"line":1577},[747,36504,4253],{"class":757},[747,36506,27063],{"class":1640},[747,36508,4259],{"class":757},[747,36510,36511],{"class":1640}," Applied essential addon: kube-proxy\n",[747,36513,36514],{"class":749,"line":1582},[747,36515,1255],{"emptyLinePlaceholder":1254},[747,36517,36518,36520,36523,36526,36528,36531],{"class":749,"line":1588},[747,36519,33363],{"class":1630},[747,36521,36522],{"class":802}," Kubernetes",[747,36524,36525],{"class":802}," control-plane",[747,36527,17821],{"class":802},[747,36529,36530],{"class":802}," initialized",[747,36532,36533],{"class":802}," successfully!\n",[747,36535,36536],{"class":749,"line":1594},[747,36537,1255],{"emptyLinePlaceholder":1254},[747,36539,36540,36542,36544,36547,36549,36552,36554,36557,36559,36561,36563,36565,36567,36569,36572],{"class":749,"line":1600},[747,36541,3821],{"class":1630},[747,36543,3215],{"class":802},[747,36545,36546],{"class":802}," using",[747,36548,3795],{"class":802},[747,36550,36551],{"class":802}," cluster,",[747,36553,3969],{"class":802},[747,36555,36556],{"class":802}," need",[747,36558,3696],{"class":802},[747,36560,3665],{"class":802},[747,36562,3839],{"class":802},[747,36564,3842],{"class":802},[747,36566,5155],{"class":802},[747,36568,3930],{"class":802},[747,36570,36571],{"class":802}," regular",[747,36573,36574],{"class":802}," user:\n",[747,36576,36577],{"class":749,"line":4804},[747,36578,1255],{"emptyLinePlaceholder":1254},[747,36580,36581,36584,36586,36589],{"class":749,"line":4810},[747,36582,36583],{"class":1630},"  mkdir",[747,36585,7094],{"class":802},[747,36587,36588],{"class":1640}," $HOME",[747,36590,36591],{"class":802},"\u002F.kube\n",[747,36593,36594,36597,36600,36602,36605,36607],{"class":749,"line":4816},[747,36595,36596],{"class":1630},"  sudo",[747,36598,36599],{"class":802}," cp",[747,36601,1637],{"class":802},[747,36603,36604],{"class":802}," \u002Fetc\u002Fkubernetes\u002Fadmin.conf",[747,36606,36588],{"class":1640},[747,36608,36609],{"class":802},"\u002F.kube\u002Fconfig\n",[747,36611,36612,36614,36617,36619,36622,36624,36626,36628,36631,36633,36636,36638,36640],{"class":749,"line":4822},[747,36613,36596],{"class":1630},[747,36615,36616],{"class":802}," chown",[747,36618,16279],{"class":757},[747,36620,36621],{"class":1630},"id",[747,36623,7089],{"class":802},[747,36625,2006],{"class":757},[747,36627,856],{"class":802},[747,36629,36630],{"class":757},"$(",[747,36632,36621],{"class":1630},[747,36634,36635],{"class":802}," -g",[747,36637,2006],{"class":757},[747,36639,36588],{"class":1640},[747,36641,36609],{"class":802},[747,36643,36644],{"class":749,"line":4828},[747,36645,1255],{"emptyLinePlaceholder":1254},[747,36647,36648,36651,36654,36657,36660,36662,36664,36667,36669,36671],{"class":749,"line":4834},[747,36649,36650],{"class":1630},"You",[747,36652,36653],{"class":802}," should",[747,36655,36656],{"class":802}," now",[747,36658,36659],{"class":802}," deploy",[747,36661,3930],{"class":802},[747,36663,2219],{"class":802},[747,36665,36666],{"class":802}," network",[747,36668,3696],{"class":802},[747,36670,3839],{"class":802},[747,36672,36673],{"class":802}," cluster.\n",[747,36675,36676,36679,36681,36684,36686,36688,36691,36693,36695,36697,36700],{"class":749,"line":4840},[747,36677,36678],{"class":1630},"Run",[747,36680,969],{"class":757},[747,36682,36683],{"class":802},"kubectl apply -f [podnetwork].yaml",[747,36685,3892],{"class":757},[747,36687,4104],{"class":802},[747,36689,36690],{"class":802}," one",[747,36692,5276],{"class":802},[747,36694,3839],{"class":802},[747,36696,5365],{"class":802},[747,36698,36699],{"class":802}," listed",[747,36701,36702],{"class":802}," at:\n",[747,36704,36705],{"class":749,"line":4846},[747,36706,36707],{"class":1630},"  https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fcluster-administration\u002Faddons\u002F\n",[747,36709,36710],{"class":749,"line":4852},[747,36711,1255],{"emptyLinePlaceholder":1254},[747,36713,36714,36717,36719,36721,36724,36727,36730,36732,36735,36737,36740,36743,36745,36747,36749,36752,36754],{"class":749,"line":4858},[747,36715,36716],{"class":1630},"Then",[747,36718,3969],{"class":802},[747,36720,4048],{"class":802},[747,36722,36723],{"class":802}," join",[747,36725,36726],{"class":802}," any",[747,36728,36729],{"class":802}," number",[747,36731,5276],{"class":802},[747,36733,36734],{"class":802}," worker",[747,36736,2424],{"class":802},[747,36738,36739],{"class":802}," by",[747,36741,36742],{"class":802}," running",[747,36744,3839],{"class":802},[747,36746,3842],{"class":802},[747,36748,33307],{"class":802},[747,36750,36751],{"class":802}," each",[747,36753,5155],{"class":802},[747,36755,36756],{"class":802}," root:\n",[747,36758,36759],{"class":749,"line":4864},[747,36760,1255],{"emptyLinePlaceholder":1254},[747,36762,36763,36765,36767,36770,36773,36776],{"class":749,"line":4870},[747,36764,162],{"class":1630},[747,36766,36723],{"class":802},[747,36768,36769],{"class":802}," 159.69.244.41:6443",[747,36771,36772],{"class":802}," --token",[747,36774,36775],{"class":802}," mqn3hg.p8r8p7yyi7ozoqbx",[747,36777,1641],{"class":1640},[747,36779,36780,36783],{"class":749,"line":4876},[747,36781,36782],{"class":802},"    --discovery-token-ca-cert-hash",[747,36784,36785],{"class":802}," sha256:4000680d6a69786e1d69c3f7aef7fd03c533665e00f35886e0d2b33754d3c03c\n",[6072,36787,36788],{},[523,36789,36790],{},[584,36791,2957],{},[668,36793,36794,36813],{},[638,36795,36796,36798,36799],{},[567,36797,35507],{}," - Initialize a Kubernetes cluster first master.\n",[668,36800,36801,36807],{},[638,36802,36803,36806],{},[567,36804,36805],{},"--pod-network-cidr=100.64.0.0\u002F13"," - Pod IP address range.",[638,36808,36809,36812],{},[567,36810,36811],{},"--service-cidr=100.72.0.0\u002F13"," - Service\u002F Cluster IP address range.",[638,36814,36815,36816],{},"In the output:\n",[668,36817,36818,36837],{},[638,36819,36820,36823,36824,36823,36827,36830,36831,36833,36834,36836],{},[567,36821,36822],{},"mkdir [...]"," + ",[567,36825,36826],{},"sudo cp",[567,36828,36829],{},"sudo chown"," - These commands copy the ",[567,36832,36064],{}," which contains the access credentials to the cluster to the default location, so the ",[567,36835,15269],{}," can pick it up without any changes to it's configuration.",[638,36838,36839,36842],{},[567,36840,36841],{},"kubeadm join [...]"," - The command which allows us to join other servers into the cluster.",[523,36844,36845,36846,36848],{},"This will pull the images needed by the ",[567,36847,26920],{}," as the so called \"pause image\", besides in case of the master the images for the Kubernetes master components are also pulled, and generate configurations for those components.",[523,36850,17984,36851,36853,36854,36857],{},[567,36852,35507],{}," command ran successfully make sure to copy the command beginning with ",[567,36855,36856],{},"kubeadm join"," to a safe location, it is needed later on.",[523,36859,36860],{},"The Kubernetes master components consist of:",[668,36862,36863,36871,36882,36893],{},[638,36864,36865,36867,36868,36870],{},[567,36866,26658],{}," - It is either run as Pod inside the cluster as is done with the \"default\" cluster installation from ",[567,36869,162],{},", but an \"cluster external\" etcd could also be used.",[638,36872,36873,36875,36876,714,36878,587,36880,1909],{},[567,36874,26697],{}," - The API server is the \"gateway\" to the etcd with the other components, like ",[567,36877,26920],{},[567,36879,26732],{},[567,36881,26844],{},[638,36883,36884,36886,36887,36889,36890,36892],{},[567,36885,26732],{}," - Taking care of management aspects such as, for Services of type NodePort to select a free port in the configured range, make sure nodes are marked as ",[567,36888,26779],{}," when they have not updated themselves at the APi for sometime, and more control loops, making sure Deployments and other \"",[567,36891,18111],{}," object type\" are at their desired and if not try to bring them to the desired state, and many .",[638,36894,36895,36897,36898,36900],{},[567,36896,26844],{}," - Takes care of the scheduling of Pods in the Kubernetes cluster depending on various factors like total node resources requests. Also if supported by the storage driver the ",[567,36899,26844],{}," will take location of the storage (PersistentVolumes) into account.",[523,36902,36903,36904,1909],{},"For a more detailed view on what each Kubernetes component, see ",[527,36905,36907],{"href":26572,"rel":36906},[531],"Kubernetes Components - Kubernetes",[523,36909,36910,36911,36913],{},"Then we just need to configure the ",[567,36912,15269],{}," (only) on the master server to be able to talk with Kubernetes cluster we just created:",[738,36915,36917],{"className":1621,"code":36916,"language":1623,"meta":743,"style":743},"mkdir -p $HOME\u002F.kube\ncp -i \u002Fetc\u002Fkubernetes\u002Fadmin.conf $HOME\u002F.kube\u002Fconfig\nchown $(id -u):$(id -g) $HOME\u002F.kube\u002Fconfig\n",[567,36918,36919,36930,36943],{"__ignoreMap":743},[747,36920,36921,36924,36926,36928],{"class":749,"line":750},[747,36922,36923],{"class":1630},"mkdir",[747,36925,7094],{"class":802},[747,36927,36588],{"class":1640},[747,36929,36591],{"class":802},[747,36931,36932,36935,36937,36939,36941],{"class":749,"line":761},[747,36933,36934],{"class":1630},"cp",[747,36936,1637],{"class":802},[747,36938,36604],{"class":802},[747,36940,36588],{"class":1640},[747,36942,36609],{"class":802},[747,36944,36945,36948,36950,36952,36954,36956,36958,36960,36962,36964,36966,36968],{"class":749,"line":769},[747,36946,36947],{"class":1630},"chown",[747,36949,16279],{"class":757},[747,36951,36621],{"class":1630},[747,36953,7089],{"class":802},[747,36955,2006],{"class":757},[747,36957,856],{"class":802},[747,36959,36630],{"class":757},[747,36961,36621],{"class":1630},[747,36963,36635],{"class":802},[747,36965,2006],{"class":757},[747,36967,36588],{"class":1640},[747,36969,36609],{"class":802},[523,36971,36972,36973,36976,36977,36980],{},"Finally on the master server, run ",[567,36974,36975],{},"kubectl get componentstatus"," to get the current component status and ",[567,36978,36979],{},"kubectl get nodes"," to get the list of nodes of cluster which should only return the master server we are on right now.",[738,36982,36984],{"className":1621,"code":36983,"language":1623,"meta":743,"style":743},"$ kubectl get componentstatus\nNAME                 STATUS    MESSAGE             ERROR\ncontroller-manager   Healthy   ok\nscheduler            Healthy   ok\netcd-0               Healthy   {\"health\":\"true\"}\n$ kubectl get nodes\nNAME                       STATUS     ROLES    AGE     VERSION\nk8s-c1-master-1.eden.run   NotReady   master   2m33s   v1.14.1\n",[567,36985,36986,36997,37010,37021,37031,37058,37069,37085],{"__ignoreMap":743},[747,36987,36988,36990,36992,36994],{"class":749,"line":750},[747,36989,1919],{"class":1630},[747,36991,1922],{"class":802},[747,36993,1951],{"class":802},[747,36995,36996],{"class":802}," componentstatus\n",[747,36998,36999,37001,37004,37007],{"class":749,"line":761},[747,37000,2230],{"class":1630},[747,37002,37003],{"class":802},"                 STATUS",[747,37005,37006],{"class":802},"    MESSAGE",[747,37008,37009],{"class":802},"             ERROR\n",[747,37011,37012,37015,37018],{"class":749,"line":769},[747,37013,37014],{"class":1630},"controller-manager",[747,37016,37017],{"class":802},"   Healthy",[747,37019,37020],{"class":802},"   ok\n",[747,37022,37023,37026,37029],{"class":749,"line":776},[747,37024,37025],{"class":1630},"scheduler",[747,37027,37028],{"class":802},"            Healthy",[747,37030,37020],{"class":802},[747,37032,37033,37036,37039,37042,37044,37046,37048,37050,37052,37054,37056],{"class":749,"line":784},[747,37034,37035],{"class":1630},"etcd-0",[747,37037,37038],{"class":802},"               Healthy",[747,37040,37041],{"class":802},"   {",[747,37043,3892],{"class":757},[747,37045,16948],{"class":802},[747,37047,3892],{"class":757},[747,37049,856],{"class":802},[747,37051,3892],{"class":757},[747,37053,5306],{"class":802},[747,37055,3892],{"class":757},[747,37057,19374],{"class":802},[747,37059,37060,37062,37064,37066],{"class":749,"line":790},[747,37061,1919],{"class":1630},[747,37063,1922],{"class":802},[747,37065,1951],{"class":802},[747,37067,37068],{"class":802}," nodes\n",[747,37070,37071,37073,37076,37079,37082],{"class":749,"line":796},[747,37072,2230],{"class":1630},[747,37074,37075],{"class":802},"                       STATUS",[747,37077,37078],{"class":802},"     ROLES",[747,37080,37081],{"class":802},"    AGE",[747,37083,37084],{"class":802},"     VERSION\n",[747,37086,37087,37090,37093,37096,37099],{"class":749,"line":806},[747,37088,37089],{"class":1630},"k8s-c1-master-1.eden.run",[747,37091,37092],{"class":802},"   NotReady",[747,37094,37095],{"class":802},"   master",[747,37097,37098],{"class":802},"   2m33s",[747,37100,37101],{"class":802},"   v1.14.1\n",[523,37103,37104,37105,37107],{},"It is okay for the node to be in ",[567,37106,26779],{}," status, because we currently have not deployed a network. This will be done in the next section.",[3142,37109,37111,37112,8532],{"id":37110},"errors-during-kubeadm-execution","Errors during ",[567,37113,162],{},[6072,37115,37116,37120],{},[523,37117,37118],{},[584,37119,15250],{},[523,37121,37122],{},"This will remove all Kubernetes related data on the master and node that you are running the \"reset\" command on.",[523,37124,37125,37126,37128,37129,6374,37131,37133],{},"If you should encounter issues with ",[567,37127,162],{}," failing during, e.g., ",[567,37130,36856],{},[567,37132,35507],{},", you can do a reset of that node:",[738,37135,37137],{"className":1621,"code":37136,"language":1623,"meta":743,"style":743},"kubeadm reset -f\n# Clear iptables rules\niptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X\n# Clear ipvs rules\nipvsadm --clear\n",[567,37138,37139,37148,37153,37191,37196],{"__ignoreMap":743},[747,37140,37141,37143,37146],{"class":749,"line":750},[747,37142,162],{"class":1630},[747,37144,37145],{"class":802}," reset",[747,37147,11433],{"class":802},[747,37149,37150],{"class":749,"line":761},[747,37151,37152],{"class":772},"# Clear iptables rules\n",[747,37154,37155,37157,37160,37163,37166,37168,37171,37173,37175,37177,37179,37182,37184,37186,37188],{"class":749,"line":769},[747,37156,8254],{"class":1630},[747,37158,37159],{"class":802}," -F",[747,37161,37162],{"class":757}," &&",[747,37164,37165],{"class":1630}," iptables",[747,37167,9736],{"class":802},[747,37169,37170],{"class":802}," nat",[747,37172,37159],{"class":802},[747,37174,37162],{"class":757},[747,37176,37165],{"class":1630},[747,37178,9736],{"class":802},[747,37180,37181],{"class":802}," mangle",[747,37183,37159],{"class":802},[747,37185,37162],{"class":757},[747,37187,37165],{"class":1630},[747,37189,37190],{"class":802}," -X\n",[747,37192,37193],{"class":749,"line":776},[747,37194,37195],{"class":772},"# Clear ipvs rules\n",[747,37197,37198,37201],{"class":749,"line":784},[747,37199,37200],{"class":1630},"ipvsadm",[747,37202,37203],{"class":802}," --clear\n",[6072,37205,37206],{},[523,37207,37208],{},[584,37209,2957],{},[668,37211,37212],{},[638,37213,37214,37216,37217,37219,37220,37222],{},[567,37215,11451],{}," - In this case stands for \"force\", this will just \"reset\" the node and make it ready to be ",[567,37218,35507],{},"ed or ",[567,37221,36856],{},"ed again.",[3126,37224,37226],{"id":37225},"lets-add-some-network-to-the-cluster-first","Let's add some network to the cluster first",[523,37228,37229],{},"Before we go ahead and join the two node servers we have \"join\" the Kubernetes cluster, let's install a network. The network install must be done on the master and only once.",[523,37231,37232,37233,37237],{},"In this case ",[527,37234,37236],{"href":27031,"rel":37235},[531],"Flannel"," will be used as the network provider, as it is the most basic one which should work no matter what.",[6072,37239,37240,37244],{},[523,37241,37242],{},[584,37243,6189],{},[523,37245,37246,37247,37250,37251,1909],{},"The IP address range used for the Pods will be ",[567,37248,37249],{},"100.64.0.0\u002F13"," which is part of ",[527,37252,37255,37258],{"href":37253,"rel":37254},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FIPv4#Special-use_addresses",[531],[567,37256,37257],{},"100.64.0.0\u002F10"," space normally used for carrier-grade NAT",[738,37260,37262],{"className":1621,"code":37261,"language":1623,"meta":743,"style":743},"$ curl -O \\\n    https:\u002F\u002Fraw.githubusercontent.com\u002Fcoreos\u002Fflannel\u002Fa70459be0084506e4ec919aa1c114638878db11b\u002FDocumentation\u002Fkube-flannel.yml\n$ sed -i -e \"s?10.244.0.0\u002F16?100.64.0.0\u002F13?g\" kube-flannel.yml\n$ kubectl apply -f kube-flannel.yml\n",[567,37263,37264,37274,37279,37300],{"__ignoreMap":743},[747,37265,37266,37268,37270,37272],{"class":749,"line":750},[747,37267,1919],{"class":1630},[747,37269,2595],{"class":802},[747,37271,3340],{"class":802},[747,37273,1641],{"class":1640},[747,37275,37276],{"class":749,"line":761},[747,37277,37278],{"class":802},"    https:\u002F\u002Fraw.githubusercontent.com\u002Fcoreos\u002Fflannel\u002Fa70459be0084506e4ec919aa1c114638878db11b\u002FDocumentation\u002Fkube-flannel.yml\n",[747,37280,37281,37283,37286,37288,37290,37292,37295,37297],{"class":749,"line":769},[747,37282,1919],{"class":1630},[747,37284,37285],{"class":802}," sed",[747,37287,1637],{"class":802},[747,37289,7097],{"class":802},[747,37291,969],{"class":757},[747,37293,37294],{"class":802},"s?10.244.0.0\u002F16?100.64.0.0\u002F13?g",[747,37296,3892],{"class":757},[747,37298,37299],{"class":802}," kube-flannel.yml\n",[747,37301,37302,37304,37306,37308,37310],{"class":749,"line":776},[747,37303,1919],{"class":1630},[747,37305,1922],{"class":802},[747,37307,5180],{"class":802},[747,37309,1934],{"class":802},[747,37311,37299],{"class":802},[523,37313,37314,37315,37317,37318,17139],{},"Running the following command will show you the Pods in the ",[567,37316,2101],{}," namespace and there you should hopefully already see at least one ",[567,37319,37320],{},"kube-flannel-*",[738,37322,37324],{"className":1621,"code":37323,"language":1623,"meta":743,"style":743},"kubectl get -n kube-system pod\n",[567,37325,37326],{"__ignoreMap":743},[747,37327,37328,37330,37332,37334,37337],{"class":749,"line":750},[747,37329,15269],{"class":1630},[747,37331,1951],{"class":802},[747,37333,1928],{"class":802},[747,37335,37336],{"class":802}," kube-system",[747,37338,15539],{"class":802},[3126,37340,37342],{"id":37341},"join-each-node-server-into-your-kubernetes-cluster","Join each node server into your Kubernetes cluster",[523,37344,37345],{},"On the master server run the following command to print out the \"join\" command for the nodes:",[738,37347,37349],{"className":1621,"code":37348,"language":1623,"meta":743,"style":743},"$ kubeadm token create --print-join-command\nkubeadm join --token 447067.20b55955bd6abe6c 192.168.99.100:8443 --discovery-token-ca-cert-hash sha256:17023a5c90b996e50c514e63e161e46f78be216fd48c0c3df3be67e008b28889\n",[567,37350,37351,37365],{"__ignoreMap":743},[747,37352,37353,37355,37357,37360,37362],{"class":749,"line":750},[747,37354,1919],{"class":1630},[747,37356,35417],{"class":802},[747,37358,37359],{"class":802}," token",[747,37361,1925],{"class":802},[747,37363,37364],{"class":802}," --print-join-command\n",[747,37366,37367,37369,37371,37373,37376,37379,37382],{"class":749,"line":761},[747,37368,162],{"class":1630},[747,37370,36723],{"class":802},[747,37372,36772],{"class":802},[747,37374,37375],{"class":802}," 447067.20b55955bd6abe6c",[747,37377,37378],{"class":802}," 192.168.99.100:8443",[747,37380,37381],{"class":802}," --discovery-token-ca-cert-hash",[747,37383,37384],{"class":802}," sha256:17023a5c90b996e50c514e63e161e46f78be216fd48c0c3df3be67e008b28889\n",[523,37386,37387,37388,7258],{},"Copy the command to the two nodes and run it on them.\nAfter a few seconds\u002F minutes the command should exit successfully and you should be able to see the two nodes in the nodes list on the master (",[567,37389,36979],{},[738,37391,37393],{"className":1621,"code":37392,"language":1623,"meta":743,"style":743},"$ kubectl get nodes\nNAME                       STATUS     ROLES    AGE     VERSION\nk8s-c1-master-1.eden.run   Ready      master   5m33s   v1.14.1\nk8s-c1-worker-1.eden.run   Ready      \u003Cnone>   46s     v1.14.1\nk8s-c1-worker-2.eden.run   Ready      \u003Cnone>   10s     v1.14.1\n",[567,37394,37395,37405,37417,37431,37452],{"__ignoreMap":743},[747,37396,37397,37399,37401,37403],{"class":749,"line":750},[747,37398,1919],{"class":1630},[747,37400,1922],{"class":802},[747,37402,1951],{"class":802},[747,37404,37068],{"class":802},[747,37406,37407,37409,37411,37413,37415],{"class":749,"line":761},[747,37408,2230],{"class":1630},[747,37410,37075],{"class":802},[747,37412,37078],{"class":802},[747,37414,37081],{"class":802},[747,37416,37084],{"class":802},[747,37418,37419,37421,37423,37426,37429],{"class":749,"line":769},[747,37420,37089],{"class":1630},[747,37422,2467],{"class":802},[747,37424,37425],{"class":802},"      master",[747,37427,37428],{"class":802},"   5m33s",[747,37430,37101],{"class":802},[747,37432,37433,37436,37438,37440,37442,37444,37446,37449],{"class":749,"line":776},[747,37434,37435],{"class":1630},"k8s-c1-worker-1.eden.run",[747,37437,2467],{"class":802},[747,37439,2057],{"class":757},[747,37441,2029],{"class":802},[747,37443,2032],{"class":1640},[747,37445,2035],{"class":757},[747,37447,37448],{"class":802},"   46s",[747,37450,37451],{"class":802},"     v1.14.1\n",[747,37453,37454,37457,37459,37461,37463,37465,37467,37470],{"class":749,"line":784},[747,37455,37456],{"class":1630},"k8s-c1-worker-2.eden.run",[747,37458,2467],{"class":802},[747,37460,2057],{"class":757},[747,37462,2029],{"class":802},[747,37464,2032],{"class":1640},[747,37466,2035],{"class":757},[747,37468,37469],{"class":802},"   10s",[747,37471,37451],{"class":802},[3126,37473,37475],{"id":37474},"test-the-kubernetes-cluster-health","Test the Kubernetes cluster health",[6072,37477,37478],{},[523,37479,37480,8939,37482],{},[584,37481,2951],{},[527,37483,37486],{"href":37484,"rel":37485},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-container-docker-kubernetes\u002Ftree\u002Fmaster\u002Fkubernetes404",[531],[567,37487,37488],{},"kubernetes404",[523,37490,37491,37492,37494,37495,37498],{},"In the task ",[567,37493,37488],{}," directory is a file called ",[567,37496,37497],{},"busybox.yaml",". We will now deploy this file onto our cluster.\nThe file looks like this:",[738,37500,37502],{"className":1621,"code":37501,"language":1623,"meta":743,"style":743},"apiVersion: v1\nkind: Pod\nmetadata:\n  name: busybox\nspec:\n  containers:\n  - image: busybox\n    command:\n      - sleep\n      - \"3600\"\n    imagePullPolicy: IfNotPresent\n    name: busybox\n  restartPolicy: Always\n",[567,37503,37504,37510,37516,37520,37527,37532,37537,37546,37553,37560,37571,37579,37586],{"__ignoreMap":743},[747,37505,37506,37508],{"class":749,"line":750},[747,37507,23195],{"class":1630},[747,37509,22608],{"class":802},[747,37511,37512,37514],{"class":749,"line":761},[747,37513,23230],{"class":1630},[747,37515,28795],{"class":802},[747,37517,37518],{"class":749,"line":769},[747,37519,23238],{"class":1630},[747,37521,37522,37524],{"class":749,"line":776},[747,37523,23251],{"class":1630},[747,37525,37526],{"class":802}," busybox\n",[747,37528,37529],{"class":749,"line":784},[747,37530,37531],{"class":1630},"spec:\n",[747,37533,37534],{"class":749,"line":790},[747,37535,37536],{"class":1630},"  containers:\n",[747,37538,37539,37541,37544],{"class":749,"line":796},[747,37540,1721],{"class":1630},[747,37542,37543],{"class":802}," image:",[747,37545,37526],{"class":802},[747,37547,37548,37551],{"class":749,"line":806},[747,37549,37550],{"class":4574},"    command",[747,37552,758],{"class":802},[747,37554,37555,37557],{"class":749,"line":814},[747,37556,799],{"class":1630},[747,37558,37559],{"class":802}," sleep\n",[747,37561,37562,37564,37566,37569],{"class":749,"line":822},[747,37563,799],{"class":1630},[747,37565,969],{"class":757},[747,37567,37568],{"class":802},"3600",[747,37570,975],{"class":757},[747,37572,37573,37576],{"class":749,"line":830},[747,37574,37575],{"class":1630},"    imagePullPolicy:",[747,37577,37578],{"class":802}," IfNotPresent\n",[747,37580,37581,37584],{"class":749,"line":836},[747,37582,37583],{"class":1630},"    name:",[747,37585,37526],{"class":802},[747,37587,37588,37591],{"class":749,"line":842},[747,37589,37590],{"class":1630},"  restartPolicy:",[747,37592,25548],{"class":802},[523,37594,37595,37596,37598,37599,37602],{},"Connect to the Kubernetes master server and in the task directory ",[567,37597,29729],{}," run the following command to create the ",[567,37600,37601],{},"busybox"," Pod:",[738,37604,37606],{"className":1621,"code":37605,"language":1623,"meta":743,"style":743},"kubectl create -f busybox.yaml\n",[567,37607,37608],{"__ignoreMap":743},[747,37609,37610,37612,37614,37616],{"class":749,"line":750},[747,37611,15269],{"class":1630},[747,37613,1925],{"class":802},[747,37615,1934],{"class":802},[747,37617,37618],{"class":802}," busybox.yaml\n",[523,37620,37621,37622,37624,37625,37627],{},"The syntax of the ",[567,37623,37601],{}," Pod object manifest, is a bit similar to the syntax of ",[567,37626,2936],{}," files. It should get clear when you look at some other examples.",[523,37629,34521,37630,37633,37634,37636,37637,37639,37640,37642,37643,37645,37646,37649],{},[567,37631,37632],{},"kubectl get pod busybox"," to see the status of the ",[567,37635,37601],{}," Pod we created through the ",[567,37638,25255],{}," command. The ",[567,37641,37601],{}," Pod should be in ",[567,37644,17222],{}," state if it is not use ",[567,37647,37648],{},"kubectl describe pod busybox"," to show some general information and the events of the Pod. The events can help you find out what the issue is.",[523,37651,37652],{},"After that run the following command to make sure Pods can reach the Kubernetes API which should mean that the container network works fine.",[738,37654,37656],{"className":1621,"code":37655,"language":1623,"meta":743,"style":743},"$ kubectl exec busybox -- wget https:\u002F\u002Fkubernetes.default.svc.cluster.local:443\nConnecting to kubernetes.default.svc.cluster.local:443 (100.72.0.1:443)\nwget: note: TLS certificate validation not implemented\nwget: server returned error: HTTP\u002F1.1 403 Forbidden\ncommand terminated with exit code 1\n",[567,37657,37658,37676,37689,37712,37733],{"__ignoreMap":743},[747,37659,37660,37662,37664,37666,37669,37671,37673],{"class":749,"line":750},[747,37661,1919],{"class":1630},[747,37663,1922],{"class":802},[747,37665,2586],{"class":802},[747,37667,37668],{"class":802}," busybox",[747,37670,2592],{"class":802},[747,37672,8355],{"class":802},[747,37674,37675],{"class":802}," https:\u002F\u002Fkubernetes.default.svc.cluster.local:443\n",[747,37677,37678,37681,37683,37686],{"class":749,"line":761},[747,37679,37680],{"class":1630},"Connecting",[747,37682,3696],{"class":802},[747,37684,37685],{"class":802}," kubernetes.default.svc.cluster.local:443",[747,37687,37688],{"class":1640}," (100.72.0.1:443)\n",[747,37690,37691,37694,37697,37700,37703,37706,37709],{"class":749,"line":769},[747,37692,37693],{"class":1630},"wget:",[747,37695,37696],{"class":802}," note:",[747,37698,37699],{"class":802}," TLS",[747,37701,37702],{"class":802}," certificate",[747,37704,37705],{"class":802}," validation",[747,37707,37708],{"class":802}," not",[747,37710,37711],{"class":802}," implemented\n",[747,37713,37714,37716,37718,37721,37724,37727,37730],{"class":749,"line":776},[747,37715,37693],{"class":1630},[747,37717,5065],{"class":802},[747,37719,37720],{"class":802}," returned",[747,37722,37723],{"class":802}," error:",[747,37725,37726],{"class":802}," HTTP\u002F1.1",[747,37728,37729],{"class":1895}," 403",[747,37731,37732],{"class":802}," Forbidden\n",[747,37734,37735,37738,37741,37743,37746,37749],{"class":749,"line":784},[747,37736,37737],{"class":4574},"command",[747,37739,37740],{"class":802}," terminated",[747,37742,4104],{"class":802},[747,37744,37745],{"class":802}," exit",[747,37747,37748],{"class":802}," code",[747,37750,18691],{"class":1895},[523,37752,37753,37754,37757],{},"If you get the error that is shown above (",[567,37755,37756],{},"403"," return status), the cluster should be okay now and I can welcome you to the Kubernetes Danger Zone!\nIf you should get a different output, something probably went wrong please contact me.\nThe motto being \"Welcome to the Danger Zone!\"",[613,37759,37761],{"id":37760},"lets-extend-the-kubernetes-cluster-with-cool-features","Let's extend the Kubernetes cluster with cool features!",[6072,37763,37764],{},[523,37765,37766,8939,37768],{},[584,37767,2951],{},[527,37769,37772],{"href":37770,"rel":37771},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-container-docker-kubernetes\u002Ftree\u002Fmaster\u002Fkubernetes303",[531],[567,37773,37774],{},"kubernetes303",[523,37776,37777,37778,37780],{},"The task ",[567,37779,37774],{}," directory contains some additional manifests to add some features like, an Ingress cntroller, a PersistentVolume provider using Rook Ceph operator for storage and Prometheus Monitoring for the cluster.",[6072,37782,37783,37787],{},[523,37784,37785],{},[584,37786,6189],{},[523,37788,37789],{},"In this as there are many different objects most depending in some on the other, for simplicity are just going to \"brute force the system\".\nIgnore any \"already exists\" errors as they are okay.",[523,37791,37792,37793,37795],{},"Please enter the task directory and follow the \"Create\u002F Apply Order\" in the ",[567,37794,2887],{}," there.",[523,37797,37798],{},"The command to create the objects is",[738,37800,37802],{"className":1621,"code":37801,"language":1623,"meta":743,"style":743},"kubectl create -R -f DIRECTORY\n",[567,37803,37804],{"__ignoreMap":743},[747,37805,37806,37808,37810,37813,37815],{"class":749,"line":750},[747,37807,15269],{"class":1630},[747,37809,1925],{"class":802},[747,37811,37812],{"class":802}," -R",[747,37814,1934],{"class":802},[747,37816,37817],{"class":802}," DIRECTORY\n",[6072,37819,37820],{},[523,37821,37822],{},[584,37823,2957],{},[668,37825,37826,37839],{},[638,37827,37828,37831,37832,37834,37835,37838],{},[567,37829,37830],{},"-R"," - Means recursive. Making the ",[567,37833,25255],{}," recurse through every sub directory in the ",[567,37836,37837],{},"kubernetes303\u002F"," in this case.",[638,37840,37841,37844,37845,3052],{},[567,37842,37843],{},"DIRECTORY"," - Is the current directory you want to create all objects from (",[584,37846,37847],{},"Respect the \"Create\u002F Apply Order\"!",[2979,37849],{},[535,37851,37853],{"id":37852},"network-stuff-because-network-in-kubernetes-is-special","Network stuff. Because network in Kubernetes is \"special\".",[523,37855,37856],{},"Let's talk network!",[6072,37858,37859,37863],{},[523,37860,37861],{},[584,37862,6189],{},[523,37864,37865,37866,1909],{},"Do you want to look at complex network diagrams about Kubernetes? Checkout ",[527,37867,37869],{"href":37868},"\u002Fdocs\u002Fkubernetes\u002Fnetworking\u002Fexplained\u002F","Kubernetes Network Explained - Docs",[613,37871,22268],{"id":22267},[668,37873,37874,37892,37905],{},[638,37875,37876,37877],{},"At least two un-routed IP ranges.\n",[635,37878,37879,37886],{},[638,37880,37881,37882,37885],{},"IP range should have at least of CIDR size: ",[567,37883,37884],{},"NUMBER_OF_NODES * IPV4 \u002F24",". It will be used for the Pods IPs by the SDN\u002F Kubernetes.",[638,37887,37888,37889,1909],{},"IP range is used for Kubernetes ",[567,37890,37891],{},"Service ClusterIPs",[638,37893,37894,37895],{},"You should have at least 1G connection between the servers.\n",[668,37896,37897],{},[638,37898,37899,37900],{},"If you have internet facing service, make sure that it is enough in general network capacity.\n",[668,37901,37902],{},[638,37903,37904],{},"=> Talk with your network team!",[638,37906,37907],{},"Load Balancer is recommended for production for the Kubernetes API (more details on the architecture follow soon).",[613,37909,37911],{"id":37910},"sdn-and-cni","SDN and CNI?",[523,37913,37914],{},"Equals ❤️ for dynamic network for containers!",[3126,37916,360],{"id":37917},"glossar",[668,37919,37920,37923],{},[638,37921,37922],{},"SDN stands for Software Defined Network",[638,37924,37925,37926],{},"CNI = ",[527,37927,37930],{"href":37928,"rel":37929},"https:\u002F\u002Fgithub.com\u002Fcontainernetworking\u002Fcni",[531],"Container Network Interface",[3126,37932,37934],{"id":37933},"what-do-they-do","What do they do?",[523,37936,8764,37937,37940],{},[527,37938,37930],{"href":37928,"rel":37939},[531]," in itself is a unified interface for any system to request \"network\", e.g, an IP address.",[523,37942,37943],{},"There are many different CNI plugins available, here is a list of some:",[668,37945,37946,37951,37959],{},[638,37947,37948,27034],{},[527,37949,27033],{"href":27031,"rel":37950},[531],[638,37952,37953,27042,37956,27048],{},[527,37954,27041],{"href":27039,"rel":37955},[531],[527,37957,27047],{"href":27045,"rel":37958},[531],[638,37960,27051,37961,27057],{},[527,37962,27056],{"href":27054,"rel":37963},[531],[613,37965,37967,37969],{"id":37966},"kube-proxy-takes-care-of-service-clusterips",[567,37968,12748],{}," - Takes care of Service ClusterIPs",[523,37971,8764,37972,37974],{},[567,37973,12748],{}," component must be run on every node as it takes care of making the ClusterIPs of the Services \"available\".",[523,37976,8764,37977,37979,37980,6374,37982,37985,37986,37988,37989,37991,37992,37994],{},[567,37978,12748],{}," does this through either ",[567,37981,8254],{},[567,37983,37984],{},"ipvs"," (which uses only a small amount of ",[567,37987,8254],{}," rules), the default for new cluster is ",[567,37990,37984],{},".\nReason for ",[567,37993,37984],{}," being the default is because it is performance-wise better than having \"a billion\" iptables rules on each node doing \"routing\"\u002F filtering.",[523,37996,37997,37998,587,38001,38004],{},"Why not connect to a Node and run ",[567,37999,38000],{},"iptables-save",[567,38002,38003],{},"ipvsadm -ln"," to check on what is going on.",[6072,38006,38007],{},[523,38008,38009,38011,38012,38014],{},[584,38010,3103],{}," The ",[567,38013,8254],{}," and\u002F or IPVS \"rules\" take care of forwarding the traffic where it needs to be for ClusterIPs.",[613,38016,18919],{"id":1557},[523,38018,38019],{},"Oh boi, right now if you want dual stack network for your Pods you are in for a challenge. Dual stack is not really supported right now. It is either IPv4 or IPv6 in your cluster.",[523,38021,38022],{},"This is sadly due to bigger clouds not having IPv6 (by default) enabled and most companies not batting an eye.",[523,38024,38025],{},"A huge problem for users having DSL-Light, where you share one IPv4 address with many and often don't have enough bandwidth over IPv4, though IPv6 is working fine you have most of the bandwidth all the time without any issues (+ port fowarding is active at most ISPs).",[2979,38027],{},[535,38029,38031],{"id":38030},"deploying-an-application-to-kubernetes","Deploying an application to Kubernetes",[523,38033,8764,38034,38036],{},[567,38035,15269],{}," utility allows us to create objects, in this section I'm going to cover how you can create Manifest files for Kubernetes objects.",[613,38038,38040],{"id":38039},"busybox-pod-example","BusyBox Pod Example",[6072,38042,38043],{},[523,38044,38045,8939,38047],{},[584,38046,2951],{},[527,38048,38050],{"href":37770,"rel":38049},[531],[567,38051,37774],{},[6072,38053,38054,38058],{},[523,38055,38056],{},[584,38057,6189],{},[523,38059,38060,38061,22542,38063,38065],{},"The snippet below is from the file ",[567,38062,37497],{},[567,38064,37774],{}," task.",[523,38067,38068],{},"You have already seen this example, but here again with more explanations:",[738,38070,38072],{"className":1621,"code":38071,"language":1623,"meta":743,"style":743},"apiVersion: v1\nkind: Pod\nmetadata:\n  name: busybox\n  namespace: default\nspec:\n  containers:\n  - image: busybox\n    command:\n      - sleep\n      - \"3600\"\n    imagePullPolicy: IfNotPresent\n    name: busybox\n  restartPolicy: Always\n",[567,38073,38074,38080,38086,38090,38096,38102,38106,38110,38118,38124,38130,38140,38146,38152],{"__ignoreMap":743},[747,38075,38076,38078],{"class":749,"line":750},[747,38077,23195],{"class":1630},[747,38079,22608],{"class":802},[747,38081,38082,38084],{"class":749,"line":761},[747,38083,23230],{"class":1630},[747,38085,28795],{"class":802},[747,38087,38088],{"class":749,"line":769},[747,38089,23238],{"class":1630},[747,38091,38092,38094],{"class":749,"line":776},[747,38093,23251],{"class":1630},[747,38095,37526],{"class":802},[747,38097,38098,38100],{"class":749,"line":784},[747,38099,23215],{"class":1630},[747,38101,7736],{"class":802},[747,38103,38104],{"class":749,"line":790},[747,38105,37531],{"class":1630},[747,38107,38108],{"class":749,"line":796},[747,38109,37536],{"class":1630},[747,38111,38112,38114,38116],{"class":749,"line":806},[747,38113,1721],{"class":1630},[747,38115,37543],{"class":802},[747,38117,37526],{"class":802},[747,38119,38120,38122],{"class":749,"line":814},[747,38121,37550],{"class":4574},[747,38123,758],{"class":802},[747,38125,38126,38128],{"class":749,"line":822},[747,38127,799],{"class":1630},[747,38129,37559],{"class":802},[747,38131,38132,38134,38136,38138],{"class":749,"line":830},[747,38133,799],{"class":1630},[747,38135,969],{"class":757},[747,38137,37568],{"class":802},[747,38139,975],{"class":757},[747,38141,38142,38144],{"class":749,"line":836},[747,38143,37575],{"class":1630},[747,38145,37578],{"class":802},[747,38147,38148,38150],{"class":749,"line":842},[747,38149,37583],{"class":1630},[747,38151,37526],{"class":802},[747,38153,38154,38156],{"class":749,"line":850},[747,38155,37590],{"class":1630},[747,38157,25548],{"class":802},[6072,38159,38160],{},[523,38161,38162],{},[584,38163,2957],{},[668,38165,38166,38172,38178,38184,38190,38196],{},[638,38167,38168,38171],{},[567,38169,38170],{},"apiVersion: v1"," - Sets the API version to use.",[638,38173,38174,38177],{},[567,38175,38176],{},"kind: Pod"," - Sets the type\u002F kind of the \"obejct\".",[638,38179,38180,38183],{},[567,38181,38182],{},"metadata: []"," - A list of metadata information, like what name or namespace to use.",[638,38185,38186,38189],{},[567,38187,38188],{},"spec: []"," - A list of \"specifications\". In this case containing a list of containers.",[638,38191,38192,38195],{},[567,38193,38194],{},"containers:"," - List of containers, see next snippet for more information.",[638,38197,38198,38201],{},[567,38199,38200],{},"restartPolicy: Always"," - Restart policy. In this case the Pod always restarts, until deleted.",[738,38203,38205],{"className":1621,"code":38204,"language":1623,"meta":743,"style":743},"- image: busybox\n  command:\n    - sleep\n    - \"3600\"\n  imagePullPolicy: IfNotPresent\n  name: busybox\n",[567,38206,38207,38215,38222,38228,38238,38245],{"__ignoreMap":743},[747,38208,38209,38211,38213],{"class":749,"line":750},[747,38210,3361],{"class":1630},[747,38212,37543],{"class":802},[747,38214,37526],{"class":802},[747,38216,38217,38220],{"class":749,"line":761},[747,38218,38219],{"class":4574},"  command",[747,38221,758],{"class":802},[747,38223,38224,38226],{"class":749,"line":769},[747,38225,18665],{"class":1630},[747,38227,37559],{"class":802},[747,38229,38230,38232,38234,38236],{"class":749,"line":776},[747,38231,18665],{"class":1630},[747,38233,969],{"class":757},[747,38235,37568],{"class":802},[747,38237,975],{"class":757},[747,38239,38240,38243],{"class":749,"line":784},[747,38241,38242],{"class":1630},"  imagePullPolicy:",[747,38244,37578],{"class":802},[747,38246,38247,38249],{"class":749,"line":790},[747,38248,23251],{"class":1630},[747,38250,37526],{"class":802},[6072,38252,38253],{},[523,38254,38255],{},[584,38256,2957],{},[668,38258,38259,38268,38274,38280],{},[638,38260,38261,38264,38265,38267],{},[567,38262,38263],{},"- image: busybox"," - Use the busybox image. The ",[567,38266,3361],{}," (minus) begins the list entry.",[638,38269,38270,38273],{},[567,38271,38272],{},"command: []"," - The command to run in the container (not the entrypoint).",[638,38275,38276,38279],{},[567,38277,38278],{},"imagePullPolicy: IfNotPresent"," - The image pull policy.",[638,38281,38282,38285],{},[567,38283,38284],{},"name: busybox"," - The name of the container of the Pod.",[523,38287,38288,38289,38291],{},"Most things are seem similar but different to ",[567,38290,10821],{},"s, but if you know the basic syntax differences you should be good to go.",[2979,38293],{},[535,38295,38297],{"id":38296},"kubessar-a-glossar-but-for-kubernetes","Kubessar - A Glossar but for Kubernetes",[6072,38299,38300],{},[523,38301,38302],{},[3049,38303,38304],{},"Like a glossar, but for Kubernetes stuff. So a Kubessar?",[613,38306,34599],{"id":29955},[523,38308,38309,38310,38313,38314,1909],{},"Labels are a way to.. well.. label objects, you can use these labels to \"group\" objects together and select them all together then.\nFor example a label selector looks like this: ",[567,38311,38312],{},"app.kubernetes.io\u002Fname=my-application"," or for multiple labels: ",[567,38315,38316],{},"app.kubernetes.io\u002Fname=my-application,app.kubernetes.io\u002Fversion=1.2.3",[523,38318,38319,38320,1909],{},"Kubernetes has a list of recommended label (names): ",[527,38321,38322],{"href":38322,"rel":38323},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Foverview\u002Fworking-with-objects\u002Fcommon-labels\u002F",[531],[613,38325,34619],{"id":29944},[523,38327,38328,38329,38331],{},"Annotations are kind of like labels just from the concept of key-value pairs, but you can't filter on annotations.\nAnnotations are meant to hold information of, e.g., an application ",[567,38330,25331],{},", which is there is no need to select the objects on.",[613,38333,22320],{"id":29981},[523,38335,38336,38337,38339,38340,38343,38344,38346],{},"Separation of resources. Allowing for quotas per namespace.\nWhen not specifying a namespace in the ",[567,38338,15269],{}," command, if set the namespace configured in the kubeconfig (",[567,38341,38342],{},"$HOME\u002F.kube\u002Fconfig",") else ",[567,38345,2014],{}," namespace will be used.",[613,38348,38350,38351,2006],{"id":38349},"pod-po","Pod (",[567,38352,38353],{},"po",[523,38355,38356],{},"A Pod is a logical construct of one or more containers that will run together and share the same context.\nThe one or more containers of a Pod share the same network context, meaning they have the same interface (= IP address).",[613,38358,38360,38361,2006],{"id":38359},"deployment-deployment","Deployment (",[567,38362,38363],{},"deployment",[523,38365,14231,38366,38368,38369,38371,38372,38374,38375,38378],{},[567,38367,25331],{}," is a way to deploy your application and always keep a specific number of ",[567,38370,18111],{}," of the application running.\nIn addition to that when the ",[567,38373,25331],{}," object is edited there will be a history retained, the sub section ",[527,38376,26766],{"href":38377},"#replicaset-rs"," will give more insight into this.",[3126,38380,38382,38383,2006],{"id":38381},"replicaset-rs","ReplicaSet (",[567,38384,38385],{},"rs",[523,38387,38388],{},"When a Deployment is created or updated a ReplicaSet is created per creation\u002F change to the Deployment.\nThe ReplicaSet is an imprint of the current state of the Deployment. This is the history part of the Deployment.",[613,38390,38392,38393,2006],{"id":38391},"service-svc","Service (",[567,38394,38395],{},"svc",[523,38397,38398,38399,6374,38401,38403,38404,1909],{},"Exposed one or more Ports of Pods which are selected by a label selector. The access to the port(s) is \"load balanced\" using ",[567,38400,8254],{},[567,38402,37984],{}," depending on how the cluster has been setup. In the upcoming cluster installation, the component which \"configures\" these Service IPs on each node will use ",[567,38405,37984],{},[523,38407,38408,38409,587,38412,38415],{},"When you create a Service, a ",[567,38410,38411],{},"A",[567,38413,38414],{},"SRV"," DNS record is created so that you can access the server through a \"static\" DNS name.",[738,38417,38419],{"className":1621,"code":38418,"language":1623,"meta":743,"style":743},"wordpress.default.svc.cluster.local\nNAME.NAMESPACE.svc.cluster.local\n",[567,38420,38421,38425],{"__ignoreMap":743},[747,38422,38423],{"class":749,"line":750},[747,38424,32112],{"class":1630},[747,38426,38427],{"class":749,"line":761},[747,38428,32096],{"class":1630},[523,38430,38431],{},"(where cluster.local is the default cluster DNS suffix)",[523,38433,38434],{},"In addition to that there are three types of Service available:",[3126,38436,26993],{"id":38437},"clusterip-1",[523,38439,38440],{},"An IP address, which is the so called Service IP range, which is only reachable on the port(s) exposed by the service. This means that an ICMP ping won't work.",[3126,38442,15315],{"id":38443},"nodeport-1",[523,38445,38446,38447,3052],{},"A NodePort Service is based on the ClusterIP Service type.\nThe addition is that as the name may imply a port is opened on every node of the cluster (by default) which is in the so called node port range (",[567,38448,38449],{},"30000-32767",[3126,38451,15282],{"id":38452},"loadbalancer-1",[523,38454,38455],{},"A LoadBalancer in a nutshell is a NodePort service which triggers the creation and automatic configuration of a LoadBalancer in the environment (e.g., in a Kubernetes as a Service cloud, Kubernetes in OpenStack).",[613,38457,38459],{"id":38458},"other-objects","Other Objects",[668,38461,38462,38465,38471,38474],{},[638,38463,38464],{},"StatefulSet - Deployment like object but with a \"twist\" in regard to persistence (PersistentVolumeClaims).",[638,38466,38467,38468,3052],{},"PersistentVolumeClaims and PersistentVolumes - Claims are for requesting storage and the PersistentVolumes are the \"mapping\" part for Kubernetes and storage system\u002F software (",[567,38469,38470],{},"storage system\u002F software \u003C-> Kubernetes",[638,38472,38473],{},"ResourceQuota - Resource quotas for a namespace in regards to compute resources but also actual objects.",[638,38475,38476],{},"Nodes - Information about nodes in the cluster.",[613,38478,38480],{"id":38479},"object-manifest-files","Object Manifest files",[523,38482,38483,38484,38486],{},"Manifest files can be either in a YAML and\u002F or JSON format which Kubernetes is able to understand and interpret accordingly. These files are descriptors\u002F specifications for Kubernetes objects and can be created, edited, updated and deleted on a Kubernetes cluster using the ",[567,38485,15269],{}," Kubernetes client tool.",[2979,38488],{},[535,38490,38492,29706,38494,29711],{"id":38491},"kubectl-our-tool-to-catch-deploy-them-all",[567,38493,15269],{},[29708,38495,29710],{},[523,38497,38498],{},[3069,38499],{"alt":27852,"src":27853},[613,38501,38503,38504],{"id":38502},"the-basics-of-kubectl","The Basics of ",[567,38505,15269],{},[523,38507,8764,38508,38510],{},[567,38509,15269],{}," command is used to create new \"objects\", view Pods, ReplicationController and all other available objects in Kubernetes.",[3126,38512,38514],{"id":38513},"get-list-objects","Get\u002F List objects",[523,38516,38517],{},"To view all Pods in all namespaces of the Kubernetes cluster:",[738,38519,38521],{"className":1621,"code":38520,"language":1623,"meta":743,"style":743},"kubectl get -n NAMESPACE pods\n",[567,38522,38523],{"__ignoreMap":743},[747,38524,38525,38527,38529,38531,38534],{"class":749,"line":750},[747,38526,15269],{"class":1630},[747,38528,1951],{"class":802},[747,38530,1928],{"class":802},[747,38532,38533],{"class":802}," NAMESPACE",[747,38535,1958],{"class":802},[6072,38537,38538,38542],{},[523,38539,38540],{},[584,38541,2957],{},[668,38543,38544,38549,38555,38560,38566],{},[638,38545,38546,38548],{},[567,38547,15269],{}," - The kubectl command.",[638,38550,38551,38554],{},[567,38552,38553],{},"get"," - Get \"objects\" from kubernetes API.",[638,38556,38557,38559],{},[567,38558,1982],{}," - Name of the namespace you want to get objects from.",[638,38561,38562,38565],{},[567,38563,38564],{},"--all-namespaces"," - Show objects from all namespaces.",[638,38567,38568,38571],{},[567,38569,38570],{},"pods"," - Show only Pods (Can be a comma seperated list of types, short forms are available).",[3142,38573,38575],{"id":38574},"getting-listing-objects-using-label-selectors","Getting\u002F Listing objects using label selectors",[523,38577,38578,38579,38582,38583,1909],{},"Labels are an important of Kubernetes as they allow you to \"group\" your objects when selecting them.\nMeaning for example if you have certain components that are for the backend, you could add a label to them ",[567,38580,38581],{},"role = backend"," and the frontend components with ",[567,38584,38585],{},"role = frontend",[523,38587,38588,38589,1909],{},"Kubernetes has a list of rcommended labels to use for applications: ",[527,38590,38322],{"href":38322,"rel":38591},[531],[523,38593,38594],{},"You can basically specify \"anything\" as a label, so you are able to select your objects fine grained on your own accord.",[3126,38596,38598],{"id":38597},"gather-information-about-one-or-more-objects","Gather information about one or more object(s)",[523,38600,38601],{},"Get pretty formatted informations about one or more object(s):",[738,38603,38605],{"className":1621,"code":38604,"language":1623,"meta":743,"style":743},"kubectl describe --namespace=NAMESPACE TYPE\u002FNAME (TYPE\u002FNAME ...)\n",[567,38606,38607],{"__ignoreMap":743},[747,38608,38609,38611,38614,38617,38620,38623,38625],{"class":749,"line":750},[747,38610,15269],{"class":1630},[747,38612,38613],{"class":802}," describe",[747,38615,38616],{"class":802}," --namespace=NAMESPACE",[747,38618,38619],{"class":802}," TYPE\u002FNAME",[747,38621,38622],{"class":1640}," (TYPE\u002FNAME ",[747,38624,5685],{"class":802},[747,38626,3600],{"class":1640},[6072,38628,38629,38633],{},[523,38630,38631],{},[584,38632,2957],{},[668,38634,38635,38641,38647,38659],{},[638,38636,38637,38640],{},[567,38638,38639],{},"describe"," - Call the describe routines.",[638,38642,38643,38646],{},[567,38644,38645],{},"--namespace=NAMESPACE"," - Set namespace to search in (optional when set through kubeconfig file).",[638,38648,38649,38652,38653,714,38656,38658],{},[567,38650,38651],{},"TYPE"," - The type of objects to show. For example ",[567,38654,38655],{},"pod",[567,38657,38363],{}," (for Deployment).",[638,38660,38661,38663,38664,1909],{},[567,38662,2230],{}," - Name of the object to show. For our WordPress Pod, would be ",[567,38665,6725],{},[3126,38667,38669],{"id":38668},"create-one-or-more-objects-in-kubernetes","Create one or more object(s) in Kubernetes",[523,38671,38672,38673,38676],{},"To create Kubernetes objects through a manifest file or through commands, the ",[567,38674,38675],{},"create"," subcommand is used:",[3142,38678,38680],{"id":38679},"creating-objects-through-a-manifest-file","Creating objects through a manifest file",[738,38682,38684],{"className":1621,"code":38683,"language":1623,"meta":743,"style":743},"kubectl \\\n    create \\\n    -f FILE_NAME\n",[567,38685,38686,38692,38699],{"__ignoreMap":743},[747,38687,38688,38690],{"class":749,"line":750},[747,38689,15269],{"class":1630},[747,38691,1641],{"class":1640},[747,38693,38694,38697],{"class":749,"line":761},[747,38695,38696],{"class":802},"    create",[747,38698,1641],{"class":1640},[747,38700,38701,38703],{"class":749,"line":769},[747,38702,1660],{"class":802},[747,38704,38705],{"class":802}," FILE_NAME\n",[6072,38707,38708,38712],{},[523,38709,38710],{},[584,38711,2957],{},[668,38713,38714,38719],{},[638,38715,38716,38718],{},[567,38717,38675],{}," - Subcommand.",[638,38720,38721,38724,38725,38727],{},[567,38722,38723],{},"-f FILE_NAME"," - Can be one file, a directory or ",[567,38726,3361],{}," for stdin. When a directory is specified, files are read in alphabetical order.",[3142,38729,38731,38732,38734],{"id":38730},"create-eg-a-configmap-through-the-kubectl-create-subcommands","Create, e.g., a ConfigMap through the ",[567,38733,25255],{}," subcommands",[738,38736,38738],{"className":1621,"code":38737,"language":1623,"meta":743,"style":743},"kubectl \\\n    create \\\n    configmap OBJECT_NAME \\\n    --from-file=path\u002Fto\u002Ffile \\\n    --from-literal=\"key=value\"\n",[567,38739,38740,38746,38752,38762,38769],{"__ignoreMap":743},[747,38741,38742,38744],{"class":749,"line":750},[747,38743,15269],{"class":1630},[747,38745,1641],{"class":1640},[747,38747,38748,38750],{"class":749,"line":761},[747,38749,38696],{"class":802},[747,38751,1641],{"class":1640},[747,38753,38754,38757,38760],{"class":749,"line":769},[747,38755,38756],{"class":802},"    configmap",[747,38758,38759],{"class":802}," OBJECT_NAME",[747,38761,1641],{"class":1640},[747,38763,38764,38767],{"class":749,"line":776},[747,38765,38766],{"class":802},"    --from-file=path\u002Fto\u002Ffile",[747,38768,1641],{"class":1640},[747,38770,38771,38774,38776,38779],{"class":749,"line":784},[747,38772,38773],{"class":802},"    --from-literal=",[747,38775,3892],{"class":757},[747,38777,38778],{"class":802},"key=value",[747,38780,975],{"class":757},[6072,38782,38783,38787],{},[523,38784,38785],{},[584,38786,2957],{},[668,38788,38789,38793,38798,38804,38810],{},[638,38790,38791,38718],{},[567,38792,38675],{},[638,38794,38795,38797],{},[567,38796,30793],{}," - Type of object to create.",[638,38799,38800,38803],{},[567,38801,38802],{},"OBJECT_NAME"," - The name of the object.",[638,38805,38806,38809],{},[567,38807,38808],{},"--from-file=path\u002Fto\u002Ffile"," - Takes the file path and puts it in a key named after the file path.",[638,38811,38812,38815],{},[567,38813,38814],{},"--from-literal=\"key=value\""," - Takes a key-value pair and puts it in the ConfigMap.",[3126,38817,38819],{"id":38818},"delete-one-or-more-objects","Delete one or more object(s)",[523,38821,38822,38823,38826],{},"To delete one or more object(s), there's the ",[567,38824,38825],{},"delete"," subcommand:",[738,38828,38830],{"className":1621,"code":38829,"language":1623,"meta":743,"style":743},"kubectl delete -f FILE_NAME\n",[567,38831,38832],{"__ignoreMap":743},[747,38833,38834,38836,38839,38841],{"class":749,"line":750},[747,38835,15269],{"class":1630},[747,38837,38838],{"class":802}," delete",[747,38840,1934],{"class":802},[747,38842,38705],{"class":802},[6072,38844,38845,38849],{},[523,38846,38847],{},[584,38848,2957],{},[668,38850,38851,38856],{},[638,38852,38853,38855],{},[567,38854,38825],{}," - Deletes specified object(s).",[638,38857,38858,38724,38860,38727],{},[567,38859,38723],{},[567,38861,3361],{},[523,38863,38864],{},[584,38865,38866],{},"Or",[738,38868,38870],{"className":1621,"code":38869,"language":1623,"meta":743,"style":743},"kubectl delete TYPE\u002FNAME (TYPE\u002FNAME ...)\n",[567,38871,38872],{"__ignoreMap":743},[747,38873,38874,38876,38878,38880,38882,38884],{"class":749,"line":750},[747,38875,15269],{"class":1630},[747,38877,38838],{"class":802},[747,38879,38619],{"class":802},[747,38881,38622],{"class":1640},[747,38883,5685],{"class":802},[747,38885,3600],{"class":1640},[6072,38887,38888,38892],{},[523,38889,38890],{},[584,38891,2957],{},[668,38893,38894,38898,38906],{},[638,38895,38896,38855],{},[567,38897,38825],{},[638,38899,38900,38652,38902,714,38904,38658],{},[567,38901,38651],{},[567,38903,38655],{},[567,38905,38363],{},[638,38907,38908,38663,38910,1909],{},[567,38909,2230],{},[567,38911,6725],{},[3126,38913,38915],{"id":38914},"execute-command-inside-a-pods-container","Execute command inside a Pod's container",[523,38917,38918,38919,38922,38923,856],{},"Using the ",[567,38920,38921],{},"exec"," subcommand, with almost the same syntax as ",[567,38924,7110],{},[738,38926,38928],{"className":1621,"code":38927,"language":1623,"meta":743,"style":743},"kubectl exec OPTIONS POD_NAME (-c CONTAINER_NAME) COMMAND\n",[567,38929,38930],{"__ignoreMap":743},[747,38931,38932,38934,38936,38939,38941,38944,38946],{"class":749,"line":750},[747,38933,15269],{"class":1630},[747,38935,2586],{"class":802},[747,38937,38938],{"class":802}," OPTIONS",[747,38940,33170],{"class":802},[747,38942,38943],{"class":1640}," (-c ",[747,38945,6446],{"class":802},[747,38947,38948],{"class":1640},") COMMAND\n",[6072,38950,38951,38955],{},[523,38952,38953],{},[584,38954,2957],{},[668,38956,38957,38961,38970,38976,38981],{},[638,38958,38959,38855],{},[567,38960,38921],{},[638,38962,38963,38966,38967,38969],{},[567,38964,38965],{},"OPTIONS"," - For example ",[567,38968,7184],{}," for interactive, see the help menu for more information.",[638,38971,38972,38663,38974,1909],{},[567,38973,33213],{},[567,38975,6725],{},[638,38977,38978,38980],{},[567,38979,33145],{}," - Optional. If the specified Pod has more than one container, then it is required.",[638,38982,38983,38985],{},[567,38984,4256],{}," - The command to run inside the container.",[523,38987,38988,38989,38991,38992,38994],{},"If you are trying to exec into a Pod with multiple containers and have not selected a container using the ",[567,38990,24066],{}," flag, ",[567,38993,16258],{}," will \"complain\" about it and print a list of containers.",[3126,38996,38998],{"id":38997},"view-the-logs-of-a-pods-container","View the logs of a Pod's container",[523,39000,8764,39001,39004,39005,39007],{},[567,39002,39003],{},"logs"," subcommand, has almost the same syntax as ",[567,39006,4174],{}," with some Kubernetes Pod object related flags sprinkled in.",[738,39009,39011],{"className":1621,"code":39010,"language":1623,"meta":743,"style":743},"kubectl logs OPTIONS POD_NAME (-c CONTAINER_NAME) COMMAND\n",[567,39012,39013],{"__ignoreMap":743},[747,39014,39015,39017,39019,39021,39023,39025,39027],{"class":749,"line":750},[747,39016,15269],{"class":1630},[747,39018,17595],{"class":802},[747,39020,38938],{"class":802},[747,39022,33170],{"class":802},[747,39024,38943],{"class":1640},[747,39026,6446],{"class":802},[747,39028,38948],{"class":1640},[6072,39030,39031,39035],{},[523,39032,39033],{},[584,39034,2957],{},[668,39036,39037,39041,39048,39054],{},[638,39038,39039,38855],{},[567,39040,38921],{},[638,39042,39043,38966,39045,39047],{},[567,39044,38965],{},[567,39046,11451],{}," for follow the output, see the help menu for more information.",[638,39049,39050,38663,39052,1909],{},[567,39051,2230],{},[567,39053,6725],{},[638,39055,39056,38980],{},[567,39057,33145],{},[523,39059,39060,39061,38991,39063,38994],{},"If you are trying to get the logs of a Pod with multiple containers and have not selected a container using the ",[567,39062,24066],{},[567,39064,39065],{},"kubectl logs",[613,39067,39069],{"id":39068},"advanced-kubectl-usage","Advanced kubectl usage",[3126,39071,39073],{"id":39072},"editing-an-existing-deployment-object","Editing an existing Deployment object",[523,39075,8764,39076,39079],{},[567,39077,39078],{},"edit"," subcommand allows you to edit an object which for, e.g., Deployment, StatefulSet:",[738,39081,39083],{"className":1621,"code":39082,"language":1623,"meta":743,"style":743},"kubectl edit TYPE OBJECT_NAME\n",[567,39084,39085],{"__ignoreMap":743},[747,39086,39087,39089,39092,39095],{"class":749,"line":750},[747,39088,15269],{"class":1630},[747,39090,39091],{"class":802}," edit",[747,39093,39094],{"class":802}," TYPE",[747,39096,39097],{"class":802}," OBJECT_NAME\n",[6072,39099,39100,39104],{},[523,39101,39102],{},[584,39103,2957],{},[668,39105,39106,39111,39116],{},[638,39107,39108,39110],{},[567,39109,39078],{}," - Rolling update subcommand.",[638,39112,39113,39115],{},[567,39114,38651],{}," - The type of object to edit.",[638,39117,39118,39120],{},[567,39119,38802],{}," - Name of object to be edited.",[3126,39122,39124],{"id":39123},"scaling-a-deployment","Scaling a Deployment",[523,39126,8764,39127,39130],{},[567,39128,39129],{},"scale"," subcommand allows you scale the replicas size of a given object:",[738,39132,39134],{"className":1621,"code":39133,"language":1623,"meta":743,"style":743},"kubectl scale TYPE OBJECT_NAME --replicas=SIZE\n",[567,39135,39136],{"__ignoreMap":743},[747,39137,39138,39140,39143,39145,39147],{"class":749,"line":750},[747,39139,15269],{"class":1630},[747,39141,39142],{"class":802}," scale",[747,39144,39094],{"class":802},[747,39146,38759],{"class":802},[747,39148,39149],{"class":802}," --replicas=SIZE\n",[6072,39151,39152,39156],{},[523,39153,39154],{},[584,39155,2957],{},[668,39157,39158,39163,39167,39171],{},[638,39159,39160,39162],{},[567,39161,39129],{}," - Scale subcommand.",[638,39164,39165,39115],{},[567,39166,38651],{},[638,39168,39169,39120],{},[567,39170,38802],{},[638,39172,39173,39176],{},[567,39174,39175],{},"--replicas=SIZE"," - Set the replicas for the object.",[2979,39178],{},[535,39180,27548],{"id":27547},[523,39182,27551],{},[523,39184,27554,39185,1909],{},[527,39186,27558],{"href":27557},[523,39188,13967],{},[2890,39190,39191],{},"html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}",{"title":743,"searchDepth":761,"depth":761,"links":39193},[39194,39195,39196,39197,39200,39204,39206,39210,39214,39218,39226,39233,39236,39249,39255],{"id":26430,"depth":761,"text":26431},{"id":26437,"depth":761,"text":26438},{"id":26545,"depth":761,"text":26546},{"id":27626,"depth":761,"text":27627,"children":39198},[39199],{"id":11679,"depth":769,"text":27681},{"id":1317,"depth":761,"text":124,"children":39201},[39202,39203],{"id":27734,"depth":769,"text":27735},{"id":27856,"depth":769,"text":27857},{"id":28061,"depth":761,"text":39205},"From docker-compose to Kubernetes?",{"id":28107,"depth":761,"text":28108,"children":39207},[39208,39209],{"id":28114,"depth":769,"text":28115},{"id":3486,"depth":769,"text":3487},{"id":28267,"depth":761,"text":28268,"children":39211},[39212,39213],{"id":3649,"depth":769,"text":3650},{"id":30153,"depth":769,"text":30154},{"id":34965,"depth":761,"text":34966,"children":39215},[39216,39217],{"id":34989,"depth":769,"text":34990},{"id":14525,"depth":769,"text":14526},{"id":35016,"depth":761,"text":35017,"children":39219},[39220,39222,39224,39225],{"id":35057,"depth":769,"text":39221},"What is kubeadm?",{"id":35126,"depth":769,"text":39223},"What are kubeadm's prerequisites?",{"id":35186,"depth":769,"text":35187},{"id":37760,"depth":769,"text":37761},{"id":37852,"depth":761,"text":37853,"children":39227},[39228,39229,39230,39232],{"id":22267,"depth":769,"text":22268},{"id":37910,"depth":769,"text":37911},{"id":37966,"depth":769,"text":39231},"kube-proxy - Takes care of Service ClusterIPs",{"id":1557,"depth":769,"text":18919},{"id":38030,"depth":761,"text":38031,"children":39234},[39235],{"id":38039,"depth":769,"text":38040},{"id":38296,"depth":761,"text":38297,"children":39237},[39238,39239,39240,39241,39243,39245,39247,39248],{"id":29955,"depth":769,"text":34599},{"id":29944,"depth":769,"text":34619},{"id":29981,"depth":769,"text":22320},{"id":38349,"depth":769,"text":39242},"Pod (po)",{"id":38359,"depth":769,"text":39244},"Deployment (deployment)",{"id":38391,"depth":769,"text":39246},"Service (svc)",{"id":38458,"depth":769,"text":38459},{"id":38479,"depth":769,"text":38480},{"id":38491,"depth":761,"text":39250,"children":39251},"kubectl - Our tool to catch deploy them all",[39252,39254],{"id":38502,"depth":769,"text":39253},"The Basics of kubectl",{"id":39068,"depth":769,"text":39069},{"id":27547,"depth":761,"text":27548},"2019-03-26T21:25:06+01:00",{"src":27584},{"tags":39259},[12174,12175,124,26415],"\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day2",{"title":27593,"description":26514},"3.blog\u002F2019\u002Fcontainer-and-kubernetes-training-day2","qLxi1shG9g1y6P_5wkuWN1cSVVMZDAbdbFQ7jvQPg94",{"id":39265,"title":39266,"authors":39267,"badge":518,"body":39270,"date":49820,"description":26514,"extension":2911,"image":49821,"meta":49822,"navigation":1254,"path":49824,"seo":49825,"stem":49826,"__hash__":49827},"posts\u002F3.blog\u002F2019\u002Fcontainer-and-kubernetes-training-day1.md","Container and Kubernetes - Day #1",[39268],{"name":514,"to":515,"avatar":39269},{"src":517},{"type":520,"value":39271,"toc":49753},[39272,39274,39276,39278,39285,39287,39289,39292,39297,39300,39303,39307,39341,39349,39362,39366,39369,39372,39375,39381,39383,39387,39391,39412,39424,39426,39429,39443,39446,39449,39452,39455,39459,39462,39464,39466,39479,39482,39485,39487,39496,39498,39500,39512,39516,39533,39537,39540,39545,39565,39572,39576,39579,39609,39621,39631,39634,39654,39657,39663,40099,40112,40116,40125,40142,40145,40154,40158,40163,40174,40351,40359,40365,40434,40436,40440,40534,40537,40539,40541,40544,40546,40549,40552,40927,40930,40932,40935,40940,40945,40976,40985,41001,41036,41042,41048,41068,41074,41079,41098,41104,41109,41133,41138,41141,41322,41327,41330,43053,43058,43071,43074,43077,43085,43088,43098,43101,43107,43112,43115,43368,43374,43385,43422,43431,43500,43510,43514,43520,43527,43534,43537,43543,43568,43574,43578,43581,43589,43592,43597,43629,43636,43720,43724,43732,43734,43763,43775,43781,43802,43811,43815,43823,43853,43859,43889,43895,43903,43907,43910,43912,44009,44015,44047,44057,44061,44069,44075,44085,44107,44113,44119,44126,44365,44368,44411,44417,44438,44446,44456,44468,44472,44483,44486,44488,44492,44494,44498,44515,44518,44536,44550,44553,44559,44592,44598,44612,44615,44638,44641,44647,44974,44981,44993,45059,45078,45127,45139,45173,45186,45269,45277,45283,45289,45300,45392,45400,45423,45426,45443,45452,45461,45465,45478,45480,45563,45566,45729,45765,45770,45778,45781,45795,45799,45810,45845,45877,45880,45883,45886,45889,45891,45893,45896,45900,45904,45915,45919,45955,46003,46008,46011,46019,46022,46032,46038,46051,46060,46066,46074,46079,46081,46083,46085,46089,46094,46097,46103,46105,46122,46143,46157,46160,46166,46176,46185,46291,46297,46312,46339,46345,46351,46357,46369,46372,46378,46380,46385,46394,46405,46794,46801,47065,47071,47083,47092,47094,47105,47108,47114,47148,47153,47158,47160,47162,47164,47172,47178,47180,47182,47270,47274,47276,47446,47448,47450,47454,47456,47459,47461,47463,47468,47471,47480,47502,47514,47528,47567,47572,47576,47582,47594,47597,47606,47612,47618,47621,47635,47638,47642,47651,47841,47845,47852,48207,48213,48215,48241,48245,48249,48253,48355,48414,48419,48441,48445,48467,48515,48522,48526,48530,48535,48546,48549,48553,48561,48575,48591,48595,48598,48618,48654,48658,48666,48673,48707,48709,48725,48739,48745,48749,48761,48765,48785,48790,48800,48810,48844,48853,48861,48868,48926,48940,48942,48945,48951,48955,48958,48961,48963,48969,48973,48985,49003,49008,49021,49313,49350,49360,49364,49379,49381,49392,49402,49418,49456,49578,49584,49601,49607,49616,49634,49654,49658,49663,49677,49692,49698,49731,49736,49738,49740,49743,49748,49750],[535,39273,26431],{"id":26430},[523,39275,26434],{},[535,39277,26438],{"id":26437},[523,39279,26441,39280,26446,39283,26450],{},[527,39281,12175],{"href":26444,"rel":39282},[531],[3049,39284,26449],{},[2979,39286],{},[535,39288,2984],{"id":2983},[523,39290,39291],{},"If you have any questions or something is unclear during the workshop, please do not hesistate to ask.",[523,39293,39294],{},[584,39295,39296],{},"RTFM before asking, thanks!",[523,39298,39299],{},"Please before asking though make sure you have read the whole question, task and\u002F or comment, thanks!",[523,39301,39302],{},"Now get ready for day #1 of the training!",[613,39304,39306],{"id":39305},"heads-up-blogger-words","Heads up - \"Blogger\" Words",[668,39308,39309,39315,39319,39323],{},[638,39310,39311,39314],{},[584,39312,39313],{},"Grey Boxes",": Mostly contain an useful tip, expected command output or something funny.",[638,39316,39317,2952],{},[584,39318,2951],{},[638,39320,39321,2958],{},[584,39322,2957],{},[638,39324,39325,8939,39327,8287,39330,39333,39334,39337,39338,39340],{},[584,39326,3103],{},[584,39328,39329],{},"Too",[584,39331,39332],{},"L","ong ",[584,39335,39336],{},"D","idn't ",[584,39339,35167],{},"ead.",[613,39342,39344],{"id":39343},"whats-in-the-fcking-box",[527,39345,39348],{"href":39346,"rel":39347},"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=HOkLPjaVK_w",[531],"\"What's in the f*cking box?!\"",[523,39350,39351,39352,39355,39356,587,39358,39361],{},"The VMs you are given for the training are running Fedora 29 (with Cockpit enabled).\nCockpit is a simple web management, which allows me to \"monitor\" the VMs and help, if a problem occurs.\nAlso to note ",[567,39353,39354],{},"firewalld"," has been stopped, disabled and removed, ",[567,39357,8254],{},[567,39359,39360],{},"ip6tables"," have been cleared and rule persistence disabled.",[3126,39363,39365],{"id":39364},"why-are-the-vms-running-fedora","Why are the VMs running Fedora?",[523,39367,39368],{},"That's simple. Fedora is more up to date, not e.g., like Debian ",[523,39370,39371],{},"More \"up to date\" may not mean more stable (for \"classical\"\u002F legacy applications) but having the latest kernel and other important applications, programs and libraries in their latest versions just makes it easier to run containers.\n(Most applications, programs and libraries are available in their latest version from Fedora repositories, meaning that we do not need to begin building and\u002F or downloading binares for applications, programs and libraries which is nice)",[535,39373,39374],{"id":26545},"Goal of the Day",[523,39376,39377,39378,39380],{},"We are going to learn what containers are, why they have gained so much popularity and what use cases for container there are. After everyone is on the same page of what a container is, we are going to look at Docker, as it is the most common container runtime.\nWe will look at running and managing containers, and building container images with Docker. ",[567,39379,2936],{}," will also be shown, to demonstrate the simplicity of containers for multi container applications.\nThis will allow everyone to manage Docker containers and build their own application container images. With that we are ready to dive into enterprise container orchestration with Kubernetes on the next day.",[2979,39382],{},[535,39384,39386],{"id":39385},"container-and-microservices","Container and Microservices",[613,39388,39390],{"id":39389},"why-do-people-like-the-docker-way","Why do people like the \"Docker way\"?",[523,39392,39393,39394,39396,39397,39399,39400,39403,39404,39407,39408,39411],{},"The \"Docker way\" is basically just a way to package applications but also simplicity to run the containerized applications. Making it as simple as possible to for example starting a WordPress with database server with only two commands (or one command using ",[567,39395,2936],{},").\nSimpleness that almost everybody, with even very little knowledge about using a shell or cmd, could do it. That's what makes Docker great but also opens a \"dark\" side.\nThe \"dark\" side being that those people and for example open issues, because they are unable to do basic debugging of an issue on their own and\u002F or ",[584,39398,35167],{},"ead",[584,39401,39402],{},"T","he",[584,39405,39406],{},"F","ucking",[584,39409,39410],{},"M","anual.",[523,39413,39414,39415,714,39420,39423],{},"Still overall Docker is a good tool, which started the whole \"container\" hype.\nThanks to that, all the awesome open source applications using containers, like ",[527,39416,39419],{"href":39417,"rel":39418},"https:\u002F\u002Fgithub.com\u002Fopencontainers",[531],"Open Container Initiative",[527,39421,124],{"href":3033,"rel":39422},[531]," and many many more.",[613,39425,3044],{"id":3043},[523,39427,39428],{},"Microservices are small gears of a big application.\nAs an example if you have an application which can show the weather, time and stores the per user timezone, one can imagine the following microservices:",[668,39430,39431,39434,39437,39440],{},[638,39432,39433],{},"Weather Service",[638,39435,39436],{},"Time Service",[638,39438,39439],{},"User Timezone Profile Service",[638,39441,39442],{},"Database",[523,39444,39445],{},"If for example you have many people access the weather service, you could go ahead and scale up\u002F down that single service as needed to accomplish the load.",[523,39447,39448],{},"A MariaDB database, NoSQL database, Redis, etc, can also be seenfor a big application like, e.g., GitLab, WordPress, Magento, PrestaShop, etc.",[523,39450,39451],{},"Due to containers being smaller than VMs developers can test locally with ease and containers are and should be ephemeral. You should never have a problem with a container being deleted and\u002F or recreated because for example you would lose data.\nBut obviously there is also a plus point for production, if Microservices are done right. When done right, it will allow to scale an application with ease at the pain points.",[523,39453,39454],{},"Meaning, e.g., that if the database is overloaded you would be able to scale it .",[613,39456,39458],{"id":39457},"container-container","Container? Container!",[523,39460,39461],{},"Currently Docker containers can (and will) only allow you to run any distribution that runs on Linux. NO WINDOWS or other bullshit!\nEvery container runs in it's own namespace. For this we need to understand how namespaces work.\nA namespace is a separated \"branch\", where processes, mounts, etc. can exist without disturbing other processes, mounts, etc. in other namespaces.",[523,39463,3062],{},[523,39465,3065],{},[523,39467,39468,39471],{},[3069,39469],{"alt":3071,"src":39470},"\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day1\u002Flinux-cgroups-namespaces-systemd-hierachy.png",[33194,39472,3077,39473,3083,39476,3089],{},[527,39474,3082],{"href":3080,"rel":39475},[531],[527,39477,3088],{"href":3086,"rel":39478},[531],[523,39480,39481],{},"Docker and most other containers utilities use namespaces to separate containers from each other. There are several other techniques for kernel namespace separation to further improve security.",[523,39483,39484],{},"A container uses the running Linux kernel of the host, that is why there are less resources used, because a container is just using the existing kernel processes and doesn't need to spawn processes like that like when using a virtual machine.",[523,39486,3098],{},[6072,39488,39489,39493],{},[523,39490,39491],{},[584,39492,3103],{},[523,39494,39495],{},"A container is NOT a VM. A container is a \"separate\" namespace in the container of the host and not like a VM where everything is virtualized for the system, which can then be controlled.",[2979,39497],{},[535,39499,3110],{"id":3109},[6072,39501,39502,39506],{},[523,39503,39504],{},[584,39505,6189],{},[523,39507,39508,39509,39511],{},"These steps only need to be exeucted the VM which has ",[567,39510,19628],{}," in its name, not the other machines.",[613,39513,39515],{"id":39514},"side-notes","Side Notes",[668,39517,39518,39521,39530],{},[638,39519,39520],{},"You can also install Docker on your system or in a VirtualBox. If you use a VirtualBox, please consider using Fedora 29 or anyother linux distro with at least kernel 4.x.",[638,39522,39523,39524,39529],{},"If you are a Windows or Mac OSX user, switch to linux m8, thanks! Just kidding, there are ways like ",[527,39525,39528],{"href":39526,"rel":39527},"http:\u002F\u002Fboot2docker.io\u002F",[531],"Boot2Docker"," to run Docker \"there\" (I don't help or give any support if you use it though!).",[638,39531,39532],{},"The download and login details to the VMs will be given to you.",[613,39534,39536],{"id":39535},"docker-system-requirements","Docker System Requirements",[523,39538,39539],{},"\"The System Requirements are too damn high.\"",[523,39541,39542],{},[584,39543,39544],{},"Nope, they're not! :-D",[668,39546,39547,39550],{},[638,39548,39549],{},"A Linux-based distribution",[638,39551,39552,39553,39556],{},"Linux Kernel ",[567,39554,39555],{},"4.x+",[668,39557,39558],{},[638,39559,39560,39561,39564],{},"If you are on a RHEL based distribution, the ",[567,39562,39563],{},"3.x"," should also work though a more up to date kernel is preferred.",[523,39566,39567,39568,39571],{},"You can run Docker under any kernel ",[567,39569,39570],{},"3.16+",", but I recommend you to use a more up to date kernel for the implemented improvements in some of the file system and network systems Docker uses.",[613,39573,39575],{"id":39574},"docker-installation","Docker Installation",[523,39577,39578],{},"To install Docker run the command:",[738,39580,39582],{"className":1621,"code":39581,"language":1623,"meta":743,"style":743},"curl -sSL https:\u002F\u002Fget.docker.com\u002F -o install-docker.sh\n# Look at the install-docker.sh script to make sure there is nothing evil going on\nsh install-docker.sh\n",[567,39583,39584,39597,39602],{"__ignoreMap":743},[747,39585,39586,39588,39590,39592,39594],{"class":749,"line":750},[747,39587,3151],{"class":1630},[747,39589,3164],{"class":802},[747,39591,3167],{"class":802},[747,39593,2222],{"class":802},[747,39595,39596],{"class":802}," install-docker.sh\n",[747,39598,39599],{"class":749,"line":761},[747,39600,39601],{"class":772},"# Look at the install-docker.sh script to make sure there is nothing evil going on\n",[747,39603,39604,39607],{"class":749,"line":769},[747,39605,39606],{"class":1630},"sh",[747,39608,39596],{"class":802},[523,39610,39611,39612,39616,39617,1909],{},"For more details on the installation of Docker, please refer to the Docker documentation Linux installation ",[527,39613,3181],{"href":39614,"rel":39615},"https:\u002F\u002Fdocs.docker.com\u002Finstall\u002F",[531]," and select the distribution in the navigation sidebar, or the Windows installation ",[527,39618,3181],{"href":39619,"rel":39620},"https:\u002F\u002Fdocs.docker.com\u002Fdocker-for-windows\u002F",[531],[523,39622,39623,39624,39626,39627,39630],{},"Docker consistst of the client program ",[567,39625,3257],{}," and the Docker Daemon (",[567,39628,39629],{},"dockerd","). To keep it simple \"that is it\", but there is more behind Docker.",[523,39632,39633],{},"After you have installed it hopefully without any errors popping up, you have to enable and start the Docker Engine:",[738,39635,39636],{"className":1621,"code":3195,"language":1623,"meta":743,"style":743},[567,39637,39638,39646],{"__ignoreMap":743},[747,39639,39640,39642,39644],{"class":749,"line":750},[747,39641,3202],{"class":1630},[747,39643,3205],{"class":802},[747,39645,3208],{"class":802},[747,39647,39648,39650,39652],{"class":749,"line":761},[747,39649,3202],{"class":1630},[747,39651,3215],{"class":802},[747,39653,3208],{"class":802},[523,39655,39656],{},"This enables and starts the Docker daemon service.",[523,39658,39659,39660,856],{},"To make sure the Docker daemon is working as expected, run ",[567,39661,39662],{},"docker info",[738,39664,39666],{"className":1621,"code":39665,"language":1623,"meta":743,"style":743},"$ docker info\nContainers: 0\n Running: 0\n Paused: 0\n Stopped: 0\nImages: 31\nServer Version: 18.09.3-ce\nStorage Driver: overlay2\n Backing Filesystem: extfs\n Supports d_type: true\n Native Overlay Diff: false\nLogging Driver: json-file\nCgroup Driver: cgroupfs\nPlugins:\n Volume: local\n Network: bridge host macvlan null overlay\n Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog\nSwarm: inactive\nRuntimes: runc\nDefault Runtime: runc\nInit Binary: docker-init\ncontainerd version: bb71b10fd8f58240ca47fbb579b9d1028eea7c84.m\nrunc version: ccb5efd37fb7c86364786e9137e22948751de7ed-dirty\ninit version: fec3683\nSecurity Options:\n seccomp\n  Profile: default\nKernel Version: 5.0.5\nOperating System: Manjaro Linux\nOSType: linux\nArchitecture: x86_64\nCPUs: 16\nTotal Memory: 31.35GiB\nName: debwrk01\nID: SZK7:4SPS:NJUU:6FTH:YUFZ:6U5B:CNGQ:HICZ:DEZZ:EADO:JDUB:6SGH\nDocker Root Dir: \u002Fvar\u002Flib\u002Fdocker\nDebug Mode (client): false\nDebug Mode (server): false\nUsername: galexrt\nRegistry: https:\u002F\u002Findex.docker.io\u002Fv1\u002F\nLabels:\nExperimental: false\nInsecure Registries:\n 127.0.0.0\u002F8\nLive Restore Enabled: false\n",[567,39667,39668,39677,39684,39691,39698,39705,39713,39723,39733,39744,39754,39767,39776,39786,39791,39799,39818,39853,39861,39869,39879,39890,39899,39909,39918,39925,39930,39937,39947,39961,39969,39977,39985,39996,40004,40012,40025,40036,40045,40053,40061,40066,40073,40081,40086],{"__ignoreMap":743},[747,39669,39670,39672,39674],{"class":749,"line":750},[747,39671,1919],{"class":1630},[747,39673,3246],{"class":802},[747,39675,39676],{"class":802}," info\n",[747,39678,39679,39682],{"class":749,"line":761},[747,39680,39681],{"class":1630},"Containers:",[747,39683,7863],{"class":1895},[747,39685,39686,39689],{"class":749,"line":769},[747,39687,39688],{"class":1630}," Running:",[747,39690,7863],{"class":1895},[747,39692,39693,39696],{"class":749,"line":776},[747,39694,39695],{"class":1630}," Paused:",[747,39697,7863],{"class":1895},[747,39699,39700,39703],{"class":749,"line":784},[747,39701,39702],{"class":1630}," Stopped:",[747,39704,7863],{"class":1895},[747,39706,39707,39710],{"class":749,"line":790},[747,39708,39709],{"class":1630},"Images:",[747,39711,39712],{"class":1895}," 31\n",[747,39714,39715,39717,39720],{"class":749,"line":796},[747,39716,33380],{"class":1630},[747,39718,39719],{"class":802}," Version:",[747,39721,39722],{"class":802}," 18.09.3-ce\n",[747,39724,39725,39727,39730],{"class":749,"line":806},[747,39726,421],{"class":1630},[747,39728,39729],{"class":802}," Driver:",[747,39731,39732],{"class":802}," overlay2\n",[747,39734,39735,39738,39741],{"class":749,"line":814},[747,39736,39737],{"class":1630}," Backing",[747,39739,39740],{"class":802}," Filesystem:",[747,39742,39743],{"class":802}," extfs\n",[747,39745,39746,39749,39752],{"class":749,"line":822},[747,39747,39748],{"class":1630}," Supports",[747,39750,39751],{"class":802}," d_type:",[747,39753,860],{"class":757},[747,39755,39756,39759,39762,39765],{"class":749,"line":830},[747,39757,39758],{"class":1630}," Native",[747,39760,39761],{"class":802}," Overlay",[747,39763,39764],{"class":802}," Diff:",[747,39766,1340],{"class":757},[747,39768,39769,39771,39773],{"class":749,"line":836},[747,39770,166],{"class":1630},[747,39772,39729],{"class":802},[747,39774,39775],{"class":802}," json-file\n",[747,39777,39778,39781,39783],{"class":749,"line":842},[747,39779,39780],{"class":1630},"Cgroup",[747,39782,39729],{"class":802},[747,39784,39785],{"class":802}," cgroupfs\n",[747,39787,39788],{"class":749,"line":850},[747,39789,39790],{"class":1630},"Plugins:\n",[747,39792,39793,39796],{"class":749,"line":863},[747,39794,39795],{"class":1630}," Volume:",[747,39797,39798],{"class":802}," local\n",[747,39800,39801,39804,39807,39809,39812,39815],{"class":749,"line":869},[747,39802,39803],{"class":1630}," Network:",[747,39805,39806],{"class":802}," bridge",[747,39808,4591],{"class":802},[747,39810,39811],{"class":802}," macvlan",[747,39813,39814],{"class":802}," null",[747,39816,39817],{"class":802}," overlay\n",[747,39819,39820,39823,39826,39829,39832,39835,39838,39841,39844,39847,39850],{"class":749,"line":877},[747,39821,39822],{"class":1630}," Log:",[747,39824,39825],{"class":802}," awslogs",[747,39827,39828],{"class":802}," fluentd",[747,39830,39831],{"class":802}," gcplogs",[747,39833,39834],{"class":802}," gelf",[747,39836,39837],{"class":802}," journald",[747,39839,39840],{"class":802}," json-file",[747,39842,39843],{"class":802}," local",[747,39845,39846],{"class":802}," logentries",[747,39848,39849],{"class":802}," splunk",[747,39851,39852],{"class":802}," syslog\n",[747,39854,39855,39858],{"class":749,"line":1015},[747,39856,39857],{"class":1630},"Swarm:",[747,39859,39860],{"class":802}," inactive\n",[747,39862,39863,39866],{"class":749,"line":1021},[747,39864,39865],{"class":1630},"Runtimes:",[747,39867,39868],{"class":802}," runc\n",[747,39870,39871,39874,39877],{"class":749,"line":1027},[747,39872,39873],{"class":1630},"Default",[747,39875,39876],{"class":802}," Runtime:",[747,39878,39868],{"class":802},[747,39880,39881,39884,39887],{"class":749,"line":1033},[747,39882,39883],{"class":1630},"Init",[747,39885,39886],{"class":802}," Binary:",[747,39888,39889],{"class":802}," docker-init\n",[747,39891,39892,39894,39896],{"class":749,"line":1039},[747,39893,26898],{"class":1630},[747,39895,33383],{"class":802},[747,39897,39898],{"class":802}," bb71b10fd8f58240ca47fbb579b9d1028eea7c84.m\n",[747,39900,39901,39904,39906],{"class":749,"line":1054},[747,39902,39903],{"class":1630},"runc",[747,39905,33383],{"class":802},[747,39907,39908],{"class":802}," ccb5efd37fb7c86364786e9137e22948751de7ed-dirty\n",[747,39910,39911,39913,39915],{"class":749,"line":1060},[747,39912,35492],{"class":1630},[747,39914,33383],{"class":802},[747,39916,39917],{"class":802}," fec3683\n",[747,39919,39920,39922],{"class":749,"line":1066},[747,39921,11645],{"class":1630},[747,39923,39924],{"class":802}," Options:\n",[747,39926,39927],{"class":749,"line":1081},[747,39928,39929],{"class":1630}," seccomp\n",[747,39931,39932,39935],{"class":749,"line":1087},[747,39933,39934],{"class":1630},"  Profile:",[747,39936,7736],{"class":802},[747,39938,39939,39942,39944],{"class":749,"line":1102},[747,39940,39941],{"class":1630},"Kernel",[747,39943,39719],{"class":802},[747,39945,39946],{"class":1895}," 5.0.5\n",[747,39948,39949,39952,39955,39958],{"class":749,"line":1110},[747,39950,39951],{"class":1630},"Operating",[747,39953,39954],{"class":802}," System:",[747,39956,39957],{"class":802}," Manjaro",[747,39959,39960],{"class":802}," Linux\n",[747,39962,39963,39966],{"class":749,"line":1117},[747,39964,39965],{"class":1630},"OSType:",[747,39967,39968],{"class":802}," linux\n",[747,39970,39971,39974],{"class":749,"line":1123},[747,39972,39973],{"class":1630},"Architecture:",[747,39975,39976],{"class":802}," x86_64\n",[747,39978,39979,39982],{"class":749,"line":1129},[747,39980,39981],{"class":1630},"CPUs:",[747,39983,39984],{"class":1895}," 16\n",[747,39986,39987,39990,39993],{"class":749,"line":1142},[747,39988,39989],{"class":1630},"Total",[747,39991,39992],{"class":802}," Memory:",[747,39994,39995],{"class":802}," 31.35GiB\n",[747,39997,39998,40001],{"class":749,"line":1150},[747,39999,40000],{"class":1630},"Name:",[747,40002,40003],{"class":802}," debwrk01\n",[747,40005,40006,40009],{"class":749,"line":1157},[747,40007,40008],{"class":1630},"ID:",[747,40010,40011],{"class":802}," SZK7:4SPS:NJUU:6FTH:YUFZ:6U5B:CNGQ:HICZ:DEZZ:EADO:JDUB:6SGH\n",[747,40013,40014,40016,40019,40022],{"class":749,"line":1163},[747,40015,12175],{"class":1630},[747,40017,40018],{"class":802}," Root",[747,40020,40021],{"class":802}," Dir:",[747,40023,40024],{"class":802}," \u002Fvar\u002Flib\u002Fdocker\n",[747,40026,40027,40030,40033],{"class":749,"line":1168},[747,40028,40029],{"class":1630},"Debug",[747,40031,40032],{"class":802}," Mode",[747,40034,40035],{"class":1640}," (client): false\n",[747,40037,40038,40040,40042],{"class":749,"line":1174},[747,40039,40029],{"class":1630},[747,40041,40032],{"class":802},[747,40043,40044],{"class":1640}," (server): false\n",[747,40046,40047,40050],{"class":749,"line":1480},[747,40048,40049],{"class":1630},"Username:",[747,40051,40052],{"class":802}," galexrt\n",[747,40054,40055,40058],{"class":749,"line":1491},[747,40056,40057],{"class":1630},"Registry:",[747,40059,40060],{"class":802}," https:\u002F\u002Findex.docker.io\u002Fv1\u002F\n",[747,40062,40063],{"class":749,"line":1496},[747,40064,40065],{"class":1630},"Labels:\n",[747,40067,40068,40071],{"class":749,"line":1502},[747,40069,40070],{"class":1630},"Experimental:",[747,40072,1340],{"class":757},[747,40074,40075,40078],{"class":749,"line":1510},[747,40076,40077],{"class":1630},"Insecure",[747,40079,40080],{"class":802}," Registries:\n",[747,40082,40083],{"class":749,"line":1520},[747,40084,40085],{"class":1630}," 127.0.0.0\u002F8\n",[747,40087,40088,40091,40094,40097],{"class":749,"line":1525},[747,40089,40090],{"class":1630},"Live",[747,40092,40093],{"class":802}," Restore",[747,40095,40096],{"class":802}," Enabled:",[747,40098,1340],{"class":757},[523,40100,40101,40102,40106,40107,1909],{},"After making sure Docker is working correctly, continue with either ",[527,40103,40105],{"href":40104},"#non-root-user","Non-Root User section"," when you accessing the server as a non-root user or directly to the next section, ",[527,40108,40110,35228],{"href":40109},"#docker-compose-installation",[567,40111,2936],{},[3126,40113,40115],{"id":40114},"non-root-user","Non-Root User",[523,40117,40118,40119,40121,40122,40124],{},"If you are connected as a non-root user, you need to add your user to the ",[567,40120,3257],{}," group. The group name may vary depending on the distribution used.\nTo add your user to the ",[567,40123,3257],{}," group, you can run the following command:",[738,40126,40128],{"className":1621,"code":40127,"language":1623,"meta":743,"style":743},"gpasswd -a $USER docker\n",[567,40129,40130],{"__ignoreMap":743},[747,40131,40132,40134,40136,40139],{"class":749,"line":750},[747,40133,3278],{"class":1630},[747,40135,3281],{"class":802},[747,40137,40138],{"class":1640}," $USER ",[747,40140,40141],{"class":802},"docker\n",[523,40143,40144],{},"Please logout from the server, after you have added yourself to the group.",[6072,40146,40147,40151],{},[523,40148,40149],{},[584,40150,6189],{},[523,40152,40153],{},"If you are persistent control connections for SSH, you need to terminate those connections as well when you are logged in as the user you just added to the Docker group.",[613,40155,40156,35228],{"id":3293},[567,40157,2936],{},[523,40159,40160],{},[3069,40161],{"alt":3299,"src":40162},"\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day1\u002Fdocker-compose-logo.png",[523,40164,40165,40166,3316,40168,3319,40170,3323,40172,3327],{},"With curl we download the ",[567,40167,2936],{},[567,40169,2936],{},[567,40171,3322],{},[567,40173,3326],{},[738,40175,40177],{"className":1621,"code":40176,"language":1623,"meta":743,"style":743},"$ sudo curl -L \"https:\u002F\u002Fgithub.com\u002Fdocker\u002Fcompose\u002Freleases\u002Fdownload\u002F1.24.0\u002Fdocker-compose-$(uname -s)-$(uname -m)\" -o \u002Fusr\u002Flocal\u002Fbin\u002Fdocker-compose\n% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n                               Dload  Upload   Total   Spent    Left  Speed\n100   617    0   617    0     0   1226      0 --:--:-- --:--:-- --:--:--  1226\n100 15.4M  100 15.4M    0     0  5751k      0  0:00:02  0:00:02 --:--:-- 7099k\n$ sudo chmod +x \u002Fusr\u002Flocal\u002Fbin\u002Fdocker-compose\n",[567,40178,40179,40218,40255,40275,40308,40339],{"__ignoreMap":743},[747,40180,40181,40183,40186,40188,40191,40193,40196,40198,40200,40202,40204,40206,40208,40210,40212,40214,40216],{"class":749,"line":750},[747,40182,1919],{"class":1630},[747,40184,40185],{"class":802}," sudo",[747,40187,2595],{"class":802},[747,40189,40190],{"class":802}," -L",[747,40192,969],{"class":757},[747,40194,40195],{"class":802},"https:\u002F\u002Fgithub.com\u002Fdocker\u002Fcompose\u002Freleases\u002Fdownload\u002F1.24.0\u002Fdocker-compose-",[747,40197,36630],{"class":757},[747,40199,3354],{"class":1630},[747,40201,2598],{"class":802},[747,40203,2006],{"class":757},[747,40205,3361],{"class":802},[747,40207,36630],{"class":757},[747,40209,3354],{"class":1630},[747,40211,3368],{"class":802},[747,40213,10675],{"class":757},[747,40215,2222],{"class":802},[747,40217,3385],{"class":802},[747,40219,40220,40223,40225,40228,40231,40234,40237,40240,40243,40246,40249,40252],{"class":749,"line":761},[747,40221,40222],{"class":1630},"%",[747,40224,3570],{"class":802},[747,40226,40227],{"class":802},"    %",[747,40229,40230],{"class":802}," Received",[747,40232,40233],{"class":802}," %",[747,40235,40236],{"class":802}," Xferd",[747,40238,40239],{"class":802},"  Average",[747,40241,40242],{"class":802}," Speed",[747,40244,40245],{"class":802},"   Time",[747,40247,40248],{"class":802},"    Time",[747,40250,40251],{"class":802},"     Time",[747,40253,40254],{"class":802},"  Current\n",[747,40256,40257,40260,40263,40266,40269,40272],{"class":749,"line":769},[747,40258,40259],{"class":1630},"                               Dload",[747,40261,40262],{"class":802},"  Upload",[747,40264,40265],{"class":802},"   Total",[747,40267,40268],{"class":802},"   Spent",[747,40270,40271],{"class":802},"    Left",[747,40273,40274],{"class":802},"  Speed\n",[747,40276,40277,40280,40283,40286,40288,40290,40292,40295,40298,40301,40303,40305],{"class":749,"line":776},[747,40278,40279],{"class":1630},"100",[747,40281,40282],{"class":1895},"   617",[747,40284,40285],{"class":1895},"    0",[747,40287,40282],{"class":1895},[747,40289,40285],{"class":1895},[747,40291,15757],{"class":1895},[747,40293,40294],{"class":1895},"   1226",[747,40296,40297],{"class":1895},"      0",[747,40299,40300],{"class":802}," --:--:--",[747,40302,40300],{"class":802},[747,40304,40300],{"class":802},[747,40306,40307],{"class":1895},"  1226\n",[747,40309,40310,40312,40315,40318,40320,40322,40324,40327,40329,40332,40334,40336],{"class":749,"line":784},[747,40311,40279],{"class":1630},[747,40313,40314],{"class":802}," 15.4M",[747,40316,40317],{"class":1895},"  100",[747,40319,40314],{"class":802},[747,40321,40285],{"class":1895},[747,40323,15757],{"class":1895},[747,40325,40326],{"class":802},"  5751k",[747,40328,40297],{"class":1895},[747,40330,40331],{"class":802},"  0:00:02",[747,40333,40331],{"class":802},[747,40335,40300],{"class":802},[747,40337,40338],{"class":802}," 7099k\n",[747,40340,40341,40343,40345,40347,40349],{"class":749,"line":790},[747,40342,1919],{"class":1630},[747,40344,40185],{"class":802},[747,40346,3379],{"class":802},[747,40348,3382],{"class":802},[747,40350,3385],{"class":802},[523,40352,3388,40353,40355,40356,1909],{},[567,40354,2936],{}," installation instructions, see ",[527,40357,3394],{"href":3394,"rel":40358},[531],[523,40360,40361,40362,856],{},"After you have followed the commands above, you can check if the \"install\" was successfully by running ",[567,40363,40364],{},"docker-compose version",[738,40366,40368],{"className":1621,"code":40367,"language":1623,"meta":743,"style":743},"$ docker-compose version\ndocker-compose version 1.23.2, build unknown\ndocker-py version: 3.7.0\nCPython version: 3.7.2\nOpenSSL version: OpenSSL 1.1.1b  26 Feb 2019\n",[567,40369,40370,40379,40393,40403,40413],{"__ignoreMap":743},[747,40371,40372,40374,40377],{"class":749,"line":750},[747,40373,1919],{"class":1630},[747,40375,40376],{"class":802}," docker-compose",[747,40378,17784],{"class":802},[747,40380,40381,40383,40385,40388,40390],{"class":749,"line":761},[747,40382,2936],{"class":1630},[747,40384,19866],{"class":802},[747,40386,40387],{"class":802}," 1.23.2,",[747,40389,9733],{"class":802},[747,40391,40392],{"class":802}," unknown\n",[747,40394,40395,40398,40400],{"class":749,"line":769},[747,40396,40397],{"class":1630},"docker-py",[747,40399,33383],{"class":802},[747,40401,40402],{"class":1895}," 3.7.0\n",[747,40404,40405,40408,40410],{"class":749,"line":776},[747,40406,40407],{"class":1630},"CPython",[747,40409,33383],{"class":802},[747,40411,40412],{"class":1895}," 3.7.2\n",[747,40414,40415,40417,40419,40422,40425,40428,40431],{"class":749,"line":784},[747,40416,88],{"class":1630},[747,40418,33383],{"class":802},[747,40420,40421],{"class":802}," OpenSSL",[747,40423,40424],{"class":802}," 1.1.1b",[747,40426,40427],{"class":1895},"  26",[747,40429,40430],{"class":802}," Feb",[747,40432,40433],{"class":1895}," 2019\n",[613,40435,3487],{"id":3486},[523,40437,28149,40438,3494],{},[567,40439,28152],{},[738,40441,40442],{"className":1621,"code":28155,"language":1623,"meta":743,"style":743},[567,40443,40444,40454,40468,40480,40492,40504,40524],{"__ignoreMap":743},[747,40445,40446,40448,40450,40452],{"class":749,"line":750},[747,40447,1919],{"class":1630},[747,40449,22393],{"class":802},[747,40451,3506],{"class":802},[747,40453,28168],{"class":802},[747,40455,40456,40458,40460,40462,40464,40466],{"class":749,"line":761},[747,40457,3531],{"class":1630},[747,40459,3534],{"class":802},[747,40461,3537],{"class":757},[747,40463,28179],{"class":802},[747,40465,3543],{"class":757},[747,40467,3546],{"class":802},[747,40469,40470,40472,40474,40476,40478],{"class":749,"line":769},[747,40471,3551],{"class":1630},[747,40473,3554],{"class":802},[747,40475,3557],{"class":802},[747,40477,28194],{"class":802},[747,40479,3563],{"class":802},[747,40481,40482,40484,40486,40488,40490],{"class":749,"line":776},[747,40483,3551],{"class":1630},[747,40485,28203],{"class":802},[747,40487,3557],{"class":802},[747,40489,3610],{"class":802},[747,40491,28210],{"class":1640},[747,40493,40494,40496,40498,40500,40502],{"class":749,"line":784},[747,40495,3551],{"class":1630},[747,40497,28217],{"class":802},[747,40499,3557],{"class":802},[747,40501,3610],{"class":802},[747,40503,28224],{"class":1640},[747,40505,40506,40508,40510,40512,40514,40516,40518,40520,40522],{"class":749,"line":790},[747,40507,3551],{"class":1630},[747,40509,3570],{"class":802},[747,40511,28233],{"class":1895},[747,40513,3576],{"class":1640},[747,40515,28238],{"class":1895},[747,40517,28241],{"class":1640},[747,40519,3585],{"class":1630},[747,40521,16369],{"class":1895},[747,40523,28248],{"class":1640},[747,40525,40526,40528,40530,40532],{"class":749,"line":796},[747,40527,28253],{"class":1630},[747,40529,3557],{"class":802},[747,40531,3610],{"class":802},[747,40533,28210],{"class":1640},[523,40535,40536],{},"Now you are ready to run your first container!",[2979,40538],{},[535,40540,3643],{"id":3642},[523,40542,40543],{},"This section will guide you through starting your first container and the process of starting a WordPress container with a MariaDB database container.",[613,40545,3650],{"id":3649},[523,40547,40548],{},"Now to start your first container and test your Docker installation, we will start like when learning a new programming language, with a simple example: a \"Hello World\" container.",[523,40550,40551],{},"To run the \"Hello World\" container, you just run the following command:",[738,40553,40555],{"className":1621,"code":40554,"language":1623,"meta":743,"style":743},"$ docker run hello-world\nUnable to find image 'hello-world:latest' locally\nlatest: Pulling from library\u002Fhello-world\n1b930d010525: Pull complete\nDigest: sha256:2557e3c07ed1e38f26e389462d03ed943586f744621577a99efb77324b0fe535\nStatus: Downloaded newer image for hello-world:latest\n\nHello from Docker!\nThis message shows that your installation appears to be working correctly.\n\nTo generate this message, Docker took the following steps:\n 1. The Docker client contacted the Docker daemon.\n 2. The Docker daemon pulled the \"hello-world\" image from the Docker Hub.\n    (amd64)\n 3. The Docker daemon created a new container from that image which runs the\n    executable that produces the output you are currently reading.\n 4. The Docker daemon streamed that output to the Docker client, which sent it\n    to your terminal.\n\nTo try something more ambitious, you can run an Ubuntu container with:\n $ docker run -it ubuntu bash\n\nShare images, automate workflows, and more with a free Docker ID:\n https:\u002F\u002Fhub.docker.com\u002F\n\nFor more examples and ideas, visit:\n https:\u002F\u002Fdocs.docker.com\u002Fget-started\u002F\n\n",[567,40556,40557,40567,40585,40595,40604,40611,40625,40629,40637,40661,40665,40685,40703,40733,40741,40771,40791,40821,40829,40833,40859,40873,40877,40901,40905,40909,40923],{"__ignoreMap":743},[747,40558,40559,40561,40563,40565],{"class":749,"line":750},[747,40560,1919],{"class":1630},[747,40562,3246],{"class":802},[747,40564,3665],{"class":802},[747,40566,3668],{"class":802},[747,40568,40569,40571,40573,40575,40577,40579,40581,40583],{"class":749,"line":761},[747,40570,3693],{"class":1630},[747,40572,3696],{"class":802},[747,40574,3699],{"class":802},[747,40576,3702],{"class":802},[747,40578,3537],{"class":757},[747,40580,3707],{"class":802},[747,40582,3543],{"class":757},[747,40584,3712],{"class":802},[747,40586,40587,40589,40591,40593],{"class":749,"line":769},[747,40588,3717],{"class":1630},[747,40590,3720],{"class":802},[747,40592,3723],{"class":802},[747,40594,3726],{"class":802},[747,40596,40597,40600,40602],{"class":749,"line":776},[747,40598,40599],{"class":1630},"1b930d010525:",[747,40601,3734],{"class":802},[747,40603,3737],{"class":802},[747,40605,40606,40608],{"class":749,"line":784},[747,40607,3742],{"class":1630},[747,40609,40610],{"class":802}," sha256:2557e3c07ed1e38f26e389462d03ed943586f744621577a99efb77324b0fe535\n",[747,40612,40613,40615,40617,40619,40621,40623],{"class":749,"line":790},[747,40614,3750],{"class":1630},[747,40616,3753],{"class":802},[747,40618,3756],{"class":802},[747,40620,3702],{"class":802},[747,40622,3761],{"class":802},[747,40624,3764],{"class":802},[747,40626,40627],{"class":749,"line":796},[747,40628,1255],{"emptyLinePlaceholder":1254},[747,40630,40631,40633,40635],{"class":749,"line":806},[747,40632,3773],{"class":1630},[747,40634,3723],{"class":802},[747,40636,3778],{"class":802},[747,40638,40639,40641,40643,40645,40647,40649,40651,40653,40655,40657,40659],{"class":749,"line":814},[747,40640,3783],{"class":1630},[747,40642,3786],{"class":802},[747,40644,3789],{"class":802},[747,40646,3792],{"class":802},[747,40648,3795],{"class":802},[747,40650,3798],{"class":802},[747,40652,3801],{"class":802},[747,40654,3696],{"class":802},[747,40656,3806],{"class":802},[747,40658,3809],{"class":802},[747,40660,3812],{"class":802},[747,40662,40663],{"class":749,"line":822},[747,40664,1255],{"emptyLinePlaceholder":1254},[747,40666,40667,40669,40671,40673,40675,40677,40679,40681,40683],{"class":749,"line":830},[747,40668,3821],{"class":1630},[747,40670,3824],{"class":802},[747,40672,3827],{"class":802},[747,40674,3830],{"class":802},[747,40676,3833],{"class":802},[747,40678,3836],{"class":802},[747,40680,3839],{"class":802},[747,40682,3842],{"class":802},[747,40684,3845],{"class":802},[747,40686,40687,40689,40691,40693,40695,40697,40699,40701],{"class":749,"line":836},[747,40688,28373],{"class":1630},[747,40690,3853],{"class":802},[747,40692,3833],{"class":802},[747,40694,3858],{"class":802},[747,40696,3861],{"class":802},[747,40698,3839],{"class":802},[747,40700,3833],{"class":802},[747,40702,3868],{"class":802},[747,40704,40705,40707,40709,40711,40713,40715,40717,40719,40721,40723,40725,40727,40729,40731],{"class":749,"line":842},[747,40706,28392],{"class":1630},[747,40708,3853],{"class":802},[747,40710,3833],{"class":802},[747,40712,3880],{"class":802},[747,40714,3883],{"class":802},[747,40716,3839],{"class":802},[747,40718,969],{"class":757},[747,40720,3649],{"class":802},[747,40722,3892],{"class":757},[747,40724,3702],{"class":802},[747,40726,3723],{"class":802},[747,40728,3839],{"class":802},[747,40730,3833],{"class":802},[747,40732,3903],{"class":802},[747,40734,40735,40737,40739],{"class":749,"line":850},[747,40736,3908],{"class":757},[747,40738,3911],{"class":1630},[747,40740,3600],{"class":757},[747,40742,40743,40745,40747,40749,40751,40753,40755,40757,40759,40761,40763,40765,40767,40769],{"class":749,"line":863},[747,40744,28431],{"class":1630},[747,40746,3853],{"class":802},[747,40748,3833],{"class":802},[747,40750,3880],{"class":802},[747,40752,3927],{"class":802},[747,40754,3930],{"class":802},[747,40756,3933],{"class":802},[747,40758,3936],{"class":802},[747,40760,3723],{"class":802},[747,40762,3792],{"class":802},[747,40764,3702],{"class":802},[747,40766,3945],{"class":802},[747,40768,3948],{"class":802},[747,40770,3951],{"class":802},[747,40772,40773,40775,40777,40779,40781,40783,40785,40787,40789],{"class":749,"line":869},[747,40774,3956],{"class":1630},[747,40776,3792],{"class":802},[747,40778,3961],{"class":802},[747,40780,3839],{"class":802},[747,40782,3966],{"class":802},[747,40784,3969],{"class":802},[747,40786,3972],{"class":802},[747,40788,3975],{"class":802},[747,40790,3978],{"class":802},[747,40792,40793,40795,40797,40799,40801,40803,40805,40807,40809,40811,40813,40815,40817,40819],{"class":749,"line":877},[747,40794,28482],{"class":1630},[747,40796,3853],{"class":802},[747,40798,3833],{"class":802},[747,40800,3880],{"class":802},[747,40802,3992],{"class":802},[747,40804,3792],{"class":802},[747,40806,3966],{"class":802},[747,40808,3696],{"class":802},[747,40810,3839],{"class":802},[747,40812,3833],{"class":802},[747,40814,4005],{"class":802},[747,40816,3945],{"class":802},[747,40818,4010],{"class":802},[747,40820,4013],{"class":802},[747,40822,40823,40825,40827],{"class":749,"line":1015},[747,40824,4018],{"class":1630},[747,40826,3795],{"class":802},[747,40828,4023],{"class":802},[747,40830,40831],{"class":749,"line":1021},[747,40832,1255],{"emptyLinePlaceholder":1254},[747,40834,40835,40837,40839,40841,40843,40845,40847,40849,40851,40853,40855,40857],{"class":749,"line":1027},[747,40836,3821],{"class":1630},[747,40838,4034],{"class":802},[747,40840,4037],{"class":802},[747,40842,4040],{"class":802},[747,40844,4043],{"class":802},[747,40846,3969],{"class":802},[747,40848,4048],{"class":802},[747,40850,3665],{"class":802},[747,40852,4053],{"class":802},[747,40854,4056],{"class":802},[747,40856,3936],{"class":802},[747,40858,4061],{"class":802},[747,40860,40861,40863,40865,40867,40869,40871],{"class":749,"line":1033},[747,40862,28551],{"class":1630},[747,40864,3246],{"class":802},[747,40866,3665],{"class":802},[747,40868,4072],{"class":802},[747,40870,4075],{"class":802},[747,40872,4078],{"class":802},[747,40874,40875],{"class":749,"line":1039},[747,40876,1255],{"emptyLinePlaceholder":1254},[747,40878,40879,40881,40883,40885,40887,40889,40891,40893,40895,40897,40899],{"class":749,"line":1054},[747,40880,4087],{"class":1630},[747,40882,4090],{"class":802},[747,40884,4093],{"class":802},[747,40886,4096],{"class":802},[747,40888,4099],{"class":802},[747,40890,4040],{"class":802},[747,40892,4104],{"class":802},[747,40894,3930],{"class":802},[747,40896,4109],{"class":802},[747,40898,3833],{"class":802},[747,40900,4114],{"class":802},[747,40902,40903],{"class":749,"line":1060},[747,40904,28594],{"class":1630},[747,40906,40907],{"class":749,"line":1066},[747,40908,1255],{"emptyLinePlaceholder":1254},[747,40910,40911,40913,40915,40917,40919,40921],{"class":749,"line":1081},[747,40912,4128],{"class":1630},[747,40914,4040],{"class":802},[747,40916,4133],{"class":802},[747,40918,4099],{"class":802},[747,40920,4138],{"class":802},[747,40922,4141],{"class":802},[747,40924,40925],{"class":749,"line":1087},[747,40926,28617],{"class":1630},[523,40928,40929],{},"When everything went correct, you should have a similar output and I can now welcome you to the big world of the containers!\nThe motto being \"Welcome to the Danger Zone!\"",[613,40931,4153],{"id":4152},[523,40933,40934],{},"These are a few basic Docker commands which are useful and important for working with Docker:",[3126,40936,40938],{"id":40937},"docker-ps",[567,40939,4160],{},[523,40941,40942,40943,33146],{},"Displays all currently running containers. To display all containers even containers which are not running anymore, add the ",[567,40944,4164],{},[738,40946,40948],{"className":1621,"code":40947,"language":1623,"meta":743,"style":743},"$ docker ps\n# Or\n$ docker ps -a\n",[567,40949,40950,40959,40964],{"__ignoreMap":743},[747,40951,40952,40954,40956],{"class":749,"line":750},[747,40953,1919],{"class":1630},[747,40955,3246],{"class":802},[747,40957,40958],{"class":802}," ps\n",[747,40960,40961],{"class":749,"line":761},[747,40962,40963],{"class":772},"# Or\n",[747,40965,40966,40968,40970,40973],{"class":749,"line":769},[747,40967,1919],{"class":1630},[747,40969,3246],{"class":802},[747,40971,40972],{"class":802}," ps",[747,40974,40975],{"class":802}," -a\n",[3126,40977,40979,18054,40982],{"id":40978},"docker-start-container_name_or_id-docker-stop-container_name_or_id",[567,40980,40981],{},"docker start CONTAINER_NAME_OR_ID",[567,40983,40984],{},"docker stop CONTAINER_NAME_OR_ID",[523,40986,40987,40988,6378,40990,40993,40994,6378,40997,41000],{},"Start or stop a container by sending a ",[567,40989,4184],{},[567,40991,40992],{},"15",") first and after a timeout of default 10 seconds, a ",[567,40995,40996],{},"SIGKILL",[567,40998,40999],{},"9",") is sent.\nBoth commands just print out the targeted container(s) name.",[738,41002,41004],{"className":1621,"code":41003,"language":1623,"meta":743,"style":743},"$ docker stop my-cool-container\nmy-cool-container\n$ docker start my-cool-container\nmy-cool-container\n",[567,41005,41006,41017,41022,41032],{"__ignoreMap":743},[747,41007,41008,41010,41012,41014],{"class":749,"line":750},[747,41009,1919],{"class":1630},[747,41011,3246],{"class":802},[747,41013,5324],{"class":802},[747,41015,41016],{"class":802}," my-cool-container\n",[747,41018,41019],{"class":749,"line":761},[747,41020,41021],{"class":1630},"my-cool-container\n",[747,41023,41024,41026,41028,41030],{"class":749,"line":769},[747,41025,1919],{"class":1630},[747,41027,3246],{"class":802},[747,41029,3215],{"class":802},[747,41031,41016],{"class":802},[747,41033,41034],{"class":749,"line":776},[747,41035,41021],{"class":1630},[3126,41037,41039],{"id":41038},"docker-restart-container_name_or_id",[567,41040,41041],{},"docker restart CONTAINER_NAME_OR_ID",[523,41043,41044,41045,4189],{},"Stop and start the given container(s). Where ",[567,41046,41047],{},"CONTAINER_NAME_OR_ID",[738,41049,41051],{"className":1621,"code":41050,"language":1623,"meta":743,"style":743},"$ docker restart my-cool-container\nmy-cool-container\n",[567,41052,41053,41064],{"__ignoreMap":743},[747,41054,41055,41057,41059,41062],{"class":749,"line":750},[747,41056,1919],{"class":1630},[747,41058,3246],{"class":802},[747,41060,41061],{"class":802}," restart",[747,41063,41016],{"class":802},[747,41065,41066],{"class":749,"line":761},[747,41067,41021],{"class":1630},[3126,41069,41071],{"id":41070},"docker-rm-container_name_or_id",[567,41072,41073],{},"docker rm CONTAINER_NAME_OR_ID",[523,41075,41076,41077,4189],{},"Remove a stopped or exited container. Where ",[567,41078,41047],{},[738,41080,41082],{"className":1621,"code":41081,"language":1623,"meta":743,"style":743},"$ docker rm my-cool-container\nmy-cool-container\n",[567,41083,41084,41094],{"__ignoreMap":743},[747,41085,41086,41088,41090,41092],{"class":749,"line":750},[747,41087,1919],{"class":1630},[747,41089,3246],{"class":802},[747,41091,5902],{"class":802},[747,41093,41016],{"class":802},[747,41095,41096],{"class":749,"line":761},[747,41097,41021],{"class":1630},[3126,41099,41101],{"id":41100},"docker-logs-container_name_or_id",[567,41102,41103],{},"docker logs CONTAINER_NAME_OR_ID",[523,41105,41106,41107,4189],{},"Show the logs of a container. Where ",[567,41108,41047],{},[738,41110,41112],{"className":1621,"code":41111,"language":1623,"meta":743,"style":743},"$ docker logs my-cool-container\n[... Many log lines from the my-cool-container application ...]\n",[567,41113,41114,41124],{"__ignoreMap":743},[747,41115,41116,41118,41120,41122],{"class":749,"line":750},[747,41117,1919],{"class":1630},[747,41119,3246],{"class":802},[747,41121,17595],{"class":802},[747,41123,41016],{"class":802},[747,41125,41126,41128,41131],{"class":749,"line":761},[747,41127,4253],{"class":757},[747,41129,41130],{"class":1640},"... Many log lines from the my-cool-container application ...",[747,41132,4268],{"class":757},[3126,41134,41136],{"id":41135},"docker-images",[567,41137,10064],{},[523,41139,41140],{},"List the images with the tags and size which are currently on the Docker host.",[738,41142,41144],{"className":1621,"code":41143,"language":1623,"meta":743,"style":743},"$ docker images\nREPOSITORY                         TAG                                          IMAGE ID            CREATED             SIZE\nfedora-emacs                       latest                                       f8f91b022f8c        About an hour ago   965MB\nwordpress                          5.1-php7.1-apache                            bfb3e0bc8467        3 days ago          412MB\ngolang                             1.12.2-stretch                               c7942203692b        3 days ago          774MB\nbusybox                            1.30.1-glibc                                 d5d8c9fc06a4        7 days ago          4.46MB\ncentos                             7                                            9f38484d220f        3 weeks ago         202MB\nmariadb                            10.4.3-bionic                                9057231b8afe        4 weeks ago         379MB\nfedora                             29                                           d7372e6c93c6        7 weeks ago         275MB\n",[567,41145,41146,41154,41174,41199,41220,41240,41260,41281,41302],{"__ignoreMap":743},[747,41147,41148,41150,41152],{"class":749,"line":750},[747,41149,1919],{"class":1630},[747,41151,3246],{"class":802},[747,41153,10078],{"class":802},[747,41155,41156,41159,41162,41165,41168,41171],{"class":749,"line":761},[747,41157,41158],{"class":1630},"REPOSITORY",[747,41160,41161],{"class":802},"                         TAG",[747,41163,41164],{"class":802},"                                          IMAGE",[747,41166,41167],{"class":802}," ID",[747,41169,41170],{"class":802},"            CREATED",[747,41172,41173],{"class":802},"             SIZE\n",[747,41175,41176,41179,41182,41185,41188,41190,41193,41196],{"class":749,"line":769},[747,41177,41178],{"class":1630},"fedora-emacs",[747,41180,41181],{"class":802},"                       latest",[747,41183,41184],{"class":802},"                                       f8f91b022f8c",[747,41186,41187],{"class":802},"        About",[747,41189,4053],{"class":802},[747,41191,41192],{"class":802}," hour",[747,41194,41195],{"class":802}," ago",[747,41197,41198],{"class":802},"   965MB\n",[747,41200,41201,41203,41206,41209,41212,41215,41217],{"class":749,"line":776},[747,41202,6725],{"class":1630},[747,41204,41205],{"class":802},"                          5.1-php7.1-apache",[747,41207,41208],{"class":802},"                            bfb3e0bc8467",[747,41210,41211],{"class":1895},"        3",[747,41213,41214],{"class":802}," days",[747,41216,41195],{"class":802},[747,41218,41219],{"class":802},"          412MB\n",[747,41221,41222,41225,41228,41231,41233,41235,41237],{"class":749,"line":784},[747,41223,41224],{"class":1630},"golang",[747,41226,41227],{"class":802},"                             1.12.2-stretch",[747,41229,41230],{"class":802},"                               c7942203692b",[747,41232,41211],{"class":1895},[747,41234,41214],{"class":802},[747,41236,41195],{"class":802},[747,41238,41239],{"class":802},"          774MB\n",[747,41241,41242,41244,41247,41250,41253,41255,41257],{"class":749,"line":790},[747,41243,37601],{"class":1630},[747,41245,41246],{"class":802},"                            1.30.1-glibc",[747,41248,41249],{"class":802},"                                 d5d8c9fc06a4",[747,41251,41252],{"class":1895},"        7",[747,41254,41214],{"class":802},[747,41256,41195],{"class":802},[747,41258,41259],{"class":802},"          4.46MB\n",[747,41261,41262,41265,41268,41271,41273,41276,41278],{"class":749,"line":796},[747,41263,41264],{"class":1630},"centos",[747,41266,41267],{"class":1895},"                             7",[747,41269,41270],{"class":802},"                                            9f38484d220f",[747,41272,41211],{"class":1895},[747,41274,41275],{"class":802}," weeks",[747,41277,41195],{"class":802},[747,41279,41280],{"class":802},"         202MB\n",[747,41282,41283,41286,41289,41292,41295,41297,41299],{"class":749,"line":806},[747,41284,41285],{"class":1630},"mariadb",[747,41287,41288],{"class":802},"                            10.4.3-bionic",[747,41290,41291],{"class":802},"                                9057231b8afe",[747,41293,41294],{"class":1895},"        4",[747,41296,41275],{"class":802},[747,41298,41195],{"class":802},[747,41300,41301],{"class":802},"         379MB\n",[747,41303,41304,41307,41310,41313,41315,41317,41319],{"class":749,"line":814},[747,41305,41306],{"class":1630},"fedora",[747,41308,41309],{"class":1895},"                             29",[747,41311,41312],{"class":802},"                                           d7372e6c93c6",[747,41314,41252],{"class":1895},[747,41316,41275],{"class":802},[747,41318,41195],{"class":802},[747,41320,41321],{"class":802},"         275MB\n",[3126,41323,41325],{"id":41324},"docker-run",[567,41326,4203],{},[523,41328,41329],{},"Create and start a container. This comnmand will be shown extensively in the next section.",[738,41331,41333],{"className":1621,"code":41332,"language":1623,"meta":743,"style":743},"docker run --help\n\nUsage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]\n\nRun a command in a new container\n\nOptions:\n      --add-host list                  Add a custom host-to-IP mapping (host:ip)\n  -a, --attach list                    Attach to STDIN, STDOUT or STDERR\n      --blkio-weight uint16            Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)\n      --blkio-weight-device list       Block IO weight (relative device weight) (default [])\n      --cap-add list                   Add Linux capabilities\n      --cap-drop list                  Drop Linux capabilities\n      --cgroup-parent string           Optional parent cgroup for the container\n      --cidfile string                 Write the container ID to the file\n      --cpu-period int                 Limit CPU CFS (Completely Fair Scheduler) period\n      --cpu-quota int                  Limit CPU CFS (Completely Fair Scheduler) quota\n      --cpu-rt-period int              Limit CPU real-time period in microseconds\n      --cpu-rt-runtime int             Limit CPU real-time runtime in microseconds\n  -c, --cpu-shares int                 CPU shares (relative weight)\n      --cpus decimal                   Number of CPUs\n      --cpuset-cpus string             CPUs in which to allow execution (0-3, 0,1)\n      --cpuset-mems string             MEMs in which to allow execution (0-3, 0,1)\n  -d, --detach                         Run container in background and print container ID\n      --detach-keys string             Override the key sequence for detaching a container\n      --device list                    Add a host device to the container\n      --device-cgroup-rule list        Add a rule to the cgroup allowed devices list\n      --device-read-bps list           Limit read rate (bytes per second) from a device (default [])\n      --device-read-iops list          Limit read rate (IO per second) from a device (default [])\n      --device-write-bps list          Limit write rate (bytes per second) to a device (default [])\n      --device-write-iops list         Limit write rate (IO per second) to a device (default [])\n      --disable-content-trust          Skip image verification (default true)\n      --dns list                       Set custom DNS servers\n      --dns-option list                Set DNS options\n      --dns-search list                Set custom DNS search domains\n      --entrypoint string              Overwrite the default ENTRYPOINT of the image\n  -e, --env list                       Set environment variables\n      --env-file list                  Read in a file of environment variables\n      --expose list                    Expose a port or a range of ports\n      --group-add list                 Add additional groups to join\n      --health-cmd string              Command to run to check health\n      --health-interval duration       Time between running the check (ms|s|m|h) (default 0s)\n      --health-retries int             Consecutive failures needed to report unhealthy\n      --health-start-period duration   Start period for the container to initialize before starting health-retries countdown (ms|s|m|h) (default 0s)\n      --health-timeout duration        Maximum time to allow one check to run (ms|s|m|h) (default 0s)\n      --help                           Print usage\n  -h, --hostname string                Container host name\n      --init                           Run an init inside the container that forwards signals and reaps processes\n  -i, --interactive                    Keep STDIN open even if not attached\n      --ip string                      IPv4 address (e.g., 172.30.100.104)\n      --ip6 string                     IPv6 address (e.g., 2001:db8::33)\n      --ipc string                     IPC mode to use\n      --isolation string               Container isolation technology\n      --kernel-memory bytes            Kernel memory limit\n  -l, --label list                     Set meta data on a container\n      --label-file list                Read in a line delimited file of labels\n      --link list                      Add link to another container\n      --link-local-ip list             Container IPv4\u002FIPv6 link-local addresses\n      --log-driver string              Logging driver for the container\n      --log-opt list                   Log driver options\n      --mac-address string             Container MAC address (e.g., 92:d0:c6:0a:29:33)\n  -m, --memory bytes                   Memory limit\n      --memory-reservation bytes       Memory soft limit\n      --memory-swap bytes              Swap limit equal to memory plus swap: '-1' to enable unlimited swap\n      --memory-swappiness int          Tune container memory swappiness (0 to 100) (default -1)\n      --mount mount                    Attach a filesystem mount to the container\n      --name string                    Assign a name to the container\n      --network string                 Connect a container to a network (default \"default\")\n      --network-alias list             Add network-scoped alias for the container\n      --no-healthcheck                 Disable any container-specified HEALTHCHECK\n      --oom-kill-disable               Disable OOM Killer\n      --oom-score-adj int              Tune host's OOM preferences (-1000 to 1000)\n      --pid string                     PID namespace to use\n      --pids-limit int                 Tune container pids limit (set -1 for unlimited)\n      --privileged                     Give extended privileges to this container\n  -p, --publish list                   Publish a container's port(s) to the host\n  -P, --publish-all                    Publish all exposed ports to random ports\n      --read-only                      Mount the container's root filesystem as read only\n      --restart string                 Restart policy to apply when a container exits (default \"no\")\n      --rm                             Automatically remove the container when it exits\n      --runtime string                 Runtime to use for this container\n      --security-opt list              Security Options\n      --shm-size bytes                 Size of \u002Fdev\u002Fshm\n      --sig-proxy                      Proxy received signals to the process (default true)\n      --stop-signal string             Signal to stop a container (default \"SIGTERM\")\n      --stop-timeout int               Timeout (in seconds) to stop a container\n      --storage-opt list               Storage driver options for the container\n      --sysctl map                     Sysctl options (default map[])\n      --tmpfs list                     Mount a tmpfs directory\n  -t, --tty                            Allocate a pseudo-TTY\n      --ulimit ulimit                  Ulimit options (default [])\n  -u, --user string                    Username or UID (format: \u003Cname|uid>[:\u003Cgroup|gid>])\n      --userns string                  User namespace to use\n      --uts string                     UTS namespace to use\n  -v, --volume list                    Bind mount a volume\n      --volume-driver string           Optional volume driver for the container\n      --volumes-from list              Mount volumes from the specified container(s)\n  -w, --workdir string                 Working directory inside the container\n",[567,41334,41335,41343,41347,41369,41373,41389,41393,41397,41416,41437,41460,41485,41497,41510,41529,41552,41574,41596,41619,41639,41661,41677,41703,41729,41756,41783,41805,41835,41866,41893,41920,41946,41965,41983,41998,42017,42040,42058,42080,42107,42128,42150,42196,42220,42277,42324,42335,42353,42386,42413,42432,42451,42467,42483,42497,42521,42547,42566,42585,42603,42617,42638,42653,42667,42703,42733,42754,42774,42804,42826,42842,42854,42870,42875,42880,42885,42909,42936,42953,42958,42963,42968,42973,42978,42983,42988,42993,42998,43003,43008,43013,43018,43023,43028,43033,43038,43043,43048],{"__ignoreMap":743},[747,41336,41337,41339,41341],{"class":749,"line":750},[747,41338,3257],{"class":1630},[747,41340,3665],{"class":802},[747,41342,4218],{"class":802},[747,41344,41345],{"class":749,"line":761},[747,41346,1255],{"emptyLinePlaceholder":1254},[747,41348,41349,41351,41353,41355,41357,41359,41361,41363,41365,41367],{"class":749,"line":769},[747,41350,4242],{"class":1630},[747,41352,4245],{"class":802},[747,41354,3665],{"class":802},[747,41356,4250],{"class":1640},[747,41358,4253],{"class":757},[747,41360,4256],{"class":1640},[747,41362,4259],{"class":757},[747,41364,4262],{"class":757},[747,41366,4265],{"class":1640},[747,41368,4268],{"class":757},[747,41370,41371],{"class":749,"line":776},[747,41372,1255],{"emptyLinePlaceholder":1254},[747,41374,41375,41377,41379,41381,41383,41385,41387],{"class":749,"line":784},[747,41376,36678],{"class":1630},[747,41378,3930],{"class":802},[747,41380,33312],{"class":802},[747,41382,4584],{"class":802},[747,41384,3930],{"class":802},[747,41386,3933],{"class":802},[747,41388,4538],{"class":802},[747,41390,41391],{"class":749,"line":790},[747,41392,1255],{"emptyLinePlaceholder":1254},[747,41394,41395],{"class":749,"line":796},[747,41396,4326],{"class":1630},[747,41398,41399,41401,41403,41406,41408,41410,41412,41414],{"class":749,"line":806},[747,41400,4331],{"class":1630},[747,41402,4334],{"class":802},[747,41404,41405],{"class":802},"                  Add",[747,41407,3930],{"class":802},[747,41409,4342],{"class":802},[747,41411,4345],{"class":802},[747,41413,4348],{"class":802},[747,41415,4351],{"class":1640},[747,41417,41418,41420,41422,41424,41427,41429,41431,41433,41435],{"class":749,"line":814},[747,41419,4404],{"class":1630},[747,41421,4407],{"class":802},[747,41423,4334],{"class":802},[747,41425,41426],{"class":802},"                    Attach",[747,41428,3696],{"class":802},[747,41430,4417],{"class":802},[747,41432,4420],{"class":802},[747,41434,4423],{"class":802},[747,41436,4426],{"class":802},[747,41438,41439,41441,41443,41446,41448,41450,41452,41454,41456,41458],{"class":749,"line":822},[747,41440,4431],{"class":1630},[747,41442,4434],{"class":802},[747,41444,41445],{"class":802},"            Block",[747,41447,4440],{"class":802},[747,41449,4443],{"class":1640},[747,41451,4446],{"class":802},[747,41453,4449],{"class":1640},[747,41455,2014],{"class":1630},[747,41457,3588],{"class":1895},[747,41459,3600],{"class":1640},[747,41461,41462,41464,41466,41469,41471,41473,41475,41477,41479,41481,41483],{"class":749,"line":830},[747,41463,4460],{"class":1630},[747,41465,4334],{"class":802},[747,41467,41468],{"class":802},"       Block",[747,41470,4440],{"class":802},[747,41472,4470],{"class":802},[747,41474,4443],{"class":1640},[747,41476,4475],{"class":802},[747,41478,4470],{"class":802},[747,41480,4392],{"class":1640},[747,41482,2014],{"class":1630},[747,41484,4484],{"class":1640},[747,41486,41487,41489,41491,41493,41495],{"class":749,"line":836},[747,41488,4489],{"class":1630},[747,41490,4334],{"class":802},[747,41492,4362],{"class":802},[747,41494,4497],{"class":802},[747,41496,4500],{"class":802},[747,41498,41499,41501,41503,41506,41508],{"class":749,"line":842},[747,41500,4505],{"class":1630},[747,41502,4334],{"class":802},[747,41504,41505],{"class":802},"                  Drop",[747,41507,4497],{"class":802},[747,41509,4500],{"class":802},[747,41511,41512,41514,41516,41519,41521,41523,41525,41527],{"class":749,"line":850},[747,41513,4519],{"class":1630},[747,41515,4522],{"class":802},[747,41517,41518],{"class":802},"           Optional",[747,41520,4528],{"class":802},[747,41522,4531],{"class":802},[747,41524,3761],{"class":802},[747,41526,3839],{"class":802},[747,41528,4538],{"class":802},[747,41530,41531,41534,41536,41539,41541,41543,41545,41547,41549],{"class":749,"line":863},[747,41532,41533],{"class":1630},"      --cidfile",[747,41535,4522],{"class":802},[747,41537,41538],{"class":802},"                 Write",[747,41540,3839],{"class":802},[747,41542,3936],{"class":802},[747,41544,41167],{"class":802},[747,41546,3696],{"class":802},[747,41548,3839],{"class":802},[747,41550,41551],{"class":802}," file\n",[747,41553,41554,41557,41559,41562,41564,41566,41568,41570,41572],{"class":749,"line":869},[747,41555,41556],{"class":1630},"      --cpu-period",[747,41558,5022],{"class":802},[747,41560,41561],{"class":802},"                 Limit",[747,41563,8476],{"class":802},[747,41565,8479],{"class":802},[747,41567,8482],{"class":1640},[747,41569,8485],{"class":802},[747,41571,8488],{"class":802},[747,41573,8491],{"class":1640},[747,41575,41576,41579,41581,41584,41586,41588,41590,41592,41594],{"class":749,"line":877},[747,41577,41578],{"class":1630},"      --cpu-quota",[747,41580,5022],{"class":802},[747,41582,41583],{"class":802},"                  Limit",[747,41585,8476],{"class":802},[747,41587,8479],{"class":802},[747,41589,8482],{"class":1640},[747,41591,8485],{"class":802},[747,41593,8488],{"class":802},[747,41595,8512],{"class":1640},[747,41597,41598,41601,41603,41606,41608,41611,41614,41616],{"class":749,"line":1015},[747,41599,41600],{"class":1630},"      --cpu-rt-period",[747,41602,5022],{"class":802},[747,41604,41605],{"class":802},"              Limit",[747,41607,8476],{"class":802},[747,41609,41610],{"class":802}," real-time",[747,41612,41613],{"class":802}," period",[747,41615,4584],{"class":802},[747,41617,41618],{"class":802}," microseconds\n",[747,41620,41621,41624,41626,41629,41631,41633,41635,41637],{"class":749,"line":1021},[747,41622,41623],{"class":1630},"      --cpu-rt-runtime",[747,41625,5022],{"class":802},[747,41627,41628],{"class":802},"             Limit",[747,41630,8476],{"class":802},[747,41632,41610],{"class":802},[747,41634,4389],{"class":802},[747,41636,4584],{"class":802},[747,41638,41618],{"class":802},[747,41640,41641,41644,41647,41649,41652,41655,41657,41659],{"class":749,"line":1027},[747,41642,41643],{"class":1630},"  -c,",[747,41645,41646],{"class":802}," --cpu-shares",[747,41648,5022],{"class":802},[747,41650,41651],{"class":802},"                 CPU",[747,41653,41654],{"class":802}," shares",[747,41656,4443],{"class":1640},[747,41658,4446],{"class":802},[747,41660,3600],{"class":1640},[747,41662,41663,41666,41669,41672,41674],{"class":749,"line":1033},[747,41664,41665],{"class":1630},"      --cpus",[747,41667,41668],{"class":802}," decimal",[747,41670,41671],{"class":802},"                   Number",[747,41673,5276],{"class":802},[747,41675,41676],{"class":802}," CPUs\n",[747,41678,41679,41682,41684,41687,41689,41691,41693,41695,41697,41699,41701],{"class":749,"line":1039},[747,41680,41681],{"class":1630},"      --cpuset-cpus",[747,41683,4522],{"class":802},[747,41685,41686],{"class":802},"             CPUs",[747,41688,4584],{"class":802},[747,41690,3945],{"class":802},[747,41692,3696],{"class":802},[747,41694,8529],{"class":802},[747,41696,8532],{"class":802},[747,41698,8535],{"class":1640},[747,41700,8538],{"class":802},[747,41702,3600],{"class":1640},[747,41704,41705,41708,41710,41713,41715,41717,41719,41721,41723,41725,41727],{"class":749,"line":1054},[747,41706,41707],{"class":1630},"      --cpuset-mems",[747,41709,4522],{"class":802},[747,41711,41712],{"class":802},"             MEMs",[747,41714,4584],{"class":802},[747,41716,3945],{"class":802},[747,41718,3696],{"class":802},[747,41720,8529],{"class":802},[747,41722,8532],{"class":802},[747,41724,8535],{"class":1640},[747,41726,8538],{"class":802},[747,41728,3600],{"class":1640},[747,41730,41731,41734,41737,41740,41742,41744,41746,41748,41751,41753],{"class":749,"line":1060},[747,41732,41733],{"class":1630},"  -d,",[747,41735,41736],{"class":802}," --detach",[747,41738,41739],{"class":802},"                         Run",[747,41741,3936],{"class":802},[747,41743,4584],{"class":802},[747,41745,17860],{"class":802},[747,41747,4099],{"class":802},[747,41749,41750],{"class":802}," print",[747,41752,3936],{"class":802},[747,41754,41755],{"class":802}," ID\n",[747,41757,41758,41761,41763,41766,41768,41771,41774,41776,41779,41781],{"class":749,"line":1066},[747,41759,41760],{"class":1630},"      --detach-keys",[747,41762,4522],{"class":802},[747,41764,41765],{"class":802},"             Override",[747,41767,3839],{"class":802},[747,41769,41770],{"class":802}," key",[747,41772,41773],{"class":802}," sequence",[747,41775,3761],{"class":802},[747,41777,41778],{"class":802}," detaching",[747,41780,3930],{"class":802},[747,41782,4538],{"class":802},[747,41784,41785,41788,41790,41792,41794,41796,41799,41801,41803],{"class":749,"line":1081},[747,41786,41787],{"class":1630},"      --device",[747,41789,4334],{"class":802},[747,41791,4337],{"class":802},[747,41793,3930],{"class":802},[747,41795,4591],{"class":802},[747,41797,41798],{"class":802}," device",[747,41800,3696],{"class":802},[747,41802,3839],{"class":802},[747,41804,4538],{"class":802},[747,41806,41807,41810,41812,41815,41817,41820,41822,41824,41826,41829,41832],{"class":749,"line":1087},[747,41808,41809],{"class":1630},"      --device-cgroup-rule",[747,41811,4334],{"class":802},[747,41813,41814],{"class":802},"        Add",[747,41816,3930],{"class":802},[747,41818,41819],{"class":802}," rule",[747,41821,3696],{"class":802},[747,41823,3839],{"class":802},[747,41825,4531],{"class":802},[747,41827,41828],{"class":802}," allowed",[747,41830,41831],{"class":802}," devices",[747,41833,41834],{"class":802}," list\n",[747,41836,41837,41840,41842,41845,41847,41850,41853,41856,41859,41862,41864],{"class":749,"line":1102},[747,41838,41839],{"class":1630},"      --device-read-bps",[747,41841,4334],{"class":802},[747,41843,41844],{"class":802},"           Limit",[747,41846,5158],{"class":802},[747,41848,41849],{"class":802}," rate",[747,41851,41852],{"class":1640}," (bytes ",[747,41854,41855],{"class":802},"per",[747,41857,41858],{"class":802}," second",[747,41860,41861],{"class":1640},") from a device (",[747,41863,2014],{"class":1630},[747,41865,4484],{"class":1640},[747,41867,41868,41871,41873,41876,41878,41880,41883,41885,41887,41889,41891],{"class":749,"line":1110},[747,41869,41870],{"class":1630},"      --device-read-iops",[747,41872,4334],{"class":802},[747,41874,41875],{"class":802},"          Limit",[747,41877,5158],{"class":802},[747,41879,41849],{"class":802},[747,41881,41882],{"class":1640}," (IO ",[747,41884,41855],{"class":802},[747,41886,41858],{"class":802},[747,41888,41861],{"class":1640},[747,41890,2014],{"class":1630},[747,41892,4484],{"class":1640},[747,41894,41895,41898,41900,41902,41905,41907,41909,41911,41913,41916,41918],{"class":749,"line":1117},[747,41896,41897],{"class":1630},"      --device-write-bps",[747,41899,4334],{"class":802},[747,41901,41875],{"class":802},[747,41903,41904],{"class":802}," write",[747,41906,41849],{"class":802},[747,41908,41852],{"class":1640},[747,41910,41855],{"class":802},[747,41912,41858],{"class":802},[747,41914,41915],{"class":1640},") to a device (",[747,41917,2014],{"class":1630},[747,41919,4484],{"class":1640},[747,41921,41922,41925,41927,41930,41932,41934,41936,41938,41940,41942,41944],{"class":749,"line":1123},[747,41923,41924],{"class":1630},"      --device-write-iops",[747,41926,4334],{"class":802},[747,41928,41929],{"class":802},"         Limit",[747,41931,41904],{"class":802},[747,41933,41849],{"class":802},[747,41935,41882],{"class":1640},[747,41937,41855],{"class":802},[747,41939,41858],{"class":802},[747,41941,41915],{"class":1640},[747,41943,2014],{"class":1630},[747,41945,4484],{"class":1640},[747,41947,41948,41951,41954,41956,41959,41961,41963],{"class":749,"line":1129},[747,41949,41950],{"class":1630},"      --disable-content-trust",[747,41952,41953],{"class":802},"          Skip",[747,41955,3702],{"class":802},[747,41957,41958],{"class":802}," verification",[747,41960,5193],{"class":1640},[747,41962,5306],{"class":757},[747,41964,3600],{"class":1640},[747,41966,41967,41970,41972,41975,41977,41980],{"class":749,"line":1142},[747,41968,41969],{"class":1630},"      --dns",[747,41971,4334],{"class":802},[747,41973,41974],{"class":802},"                       Set",[747,41976,4342],{"class":802},[747,41978,41979],{"class":802}," DNS",[747,41981,41982],{"class":802}," servers\n",[747,41984,41985,41988,41990,41993,41995],{"class":749,"line":1150},[747,41986,41987],{"class":1630},"      --dns-option",[747,41989,4334],{"class":802},[747,41991,41992],{"class":802},"                Set",[747,41994,41979],{"class":802},[747,41996,41997],{"class":802}," options\n",[747,41999,42000,42003,42005,42007,42009,42011,42014],{"class":749,"line":1157},[747,42001,42002],{"class":1630},"      --dns-search",[747,42004,4334],{"class":802},[747,42006,41992],{"class":802},[747,42008,4342],{"class":802},[747,42010,41979],{"class":802},[747,42012,42013],{"class":802}," search",[747,42015,42016],{"class":802}," domains\n",[747,42018,42019,42022,42024,42027,42029,42031,42034,42036,42038],{"class":749,"line":1163},[747,42020,42021],{"class":1630},"      --entrypoint",[747,42023,4522],{"class":802},[747,42025,42026],{"class":802},"              Overwrite",[747,42028,3839],{"class":802},[747,42030,1931],{"class":802},[747,42032,42033],{"class":802}," ENTRYPOINT",[747,42035,5276],{"class":802},[747,42037,3839],{"class":802},[747,42039,4294],{"class":802},[747,42041,42042,42045,42048,42050,42052,42055],{"class":749,"line":1168},[747,42043,42044],{"class":1630},"  -e,",[747,42046,42047],{"class":802}," --env",[747,42049,4334],{"class":802},[747,42051,41974],{"class":802},[747,42053,42054],{"class":802}," environment",[747,42056,42057],{"class":802}," variables\n",[747,42059,42060,42063,42065,42068,42070,42072,42074,42076,42078],{"class":749,"line":1174},[747,42061,42062],{"class":1630},"      --env-file",[747,42064,4334],{"class":802},[747,42066,42067],{"class":802},"                  Read",[747,42069,4584],{"class":802},[747,42071,3930],{"class":802},[747,42073,11351],{"class":802},[747,42075,5276],{"class":802},[747,42077,42054],{"class":802},[747,42079,42057],{"class":802},[747,42081,42082,42085,42087,42090,42092,42095,42097,42099,42102,42104],{"class":749,"line":1480},[747,42083,42084],{"class":1630},"      --expose",[747,42086,4334],{"class":802},[747,42088,42089],{"class":802},"                    Expose",[747,42091,3930],{"class":802},[747,42093,42094],{"class":802}," port",[747,42096,4423],{"class":802},[747,42098,3930],{"class":802},[747,42100,42101],{"class":802}," range",[747,42103,5276],{"class":802},[747,42105,42106],{"class":802}," ports\n",[747,42108,42109,42112,42114,42117,42120,42123,42125],{"class":749,"line":1491},[747,42110,42111],{"class":1630},"      --group-add",[747,42113,4334],{"class":802},[747,42115,42116],{"class":802},"                 Add",[747,42118,42119],{"class":802}," additional",[747,42121,42122],{"class":802}," groups",[747,42124,3696],{"class":802},[747,42126,42127],{"class":802}," join\n",[747,42129,42130,42133,42135,42138,42140,42142,42144,42147],{"class":749,"line":1496},[747,42131,42132],{"class":1630},"      --health-cmd",[747,42134,4522],{"class":802},[747,42136,42137],{"class":802},"              Command",[747,42139,3696],{"class":802},[747,42141,3665],{"class":802},[747,42143,3696],{"class":802},[747,42145,42146],{"class":802}," check",[747,42148,42149],{"class":802}," health\n",[747,42151,42152,42155,42158,42161,42164,42166,42168,42170,42173,42175,42177,42179,42182,42184,42187,42189,42191,42194],{"class":749,"line":1502},[747,42153,42154],{"class":1630},"      --health-interval",[747,42156,42157],{"class":802}," duration",[747,42159,42160],{"class":802},"       Time",[747,42162,42163],{"class":802}," between",[747,42165,36742],{"class":802},[747,42167,3839],{"class":802},[747,42169,42146],{"class":802},[747,42171,42172],{"class":1640}," (ms",[747,42174,3616],{"class":757},[747,42176,4978],{"class":1630},[747,42178,3616],{"class":757},[747,42180,42181],{"class":1630},"m",[747,42183,3616],{"class":757},[747,42185,42186],{"class":1630},"h",[747,42188,4392],{"class":1640},[747,42190,2014],{"class":1630},[747,42192,42193],{"class":802}," 0s",[747,42195,3600],{"class":1640},[747,42197,42198,42201,42203,42206,42209,42212,42214,42217],{"class":749,"line":1510},[747,42199,42200],{"class":1630},"      --health-retries",[747,42202,5022],{"class":802},[747,42204,42205],{"class":802},"             Consecutive",[747,42207,42208],{"class":802}," failures",[747,42210,42211],{"class":802}," needed",[747,42213,3696],{"class":802},[747,42215,42216],{"class":802}," report",[747,42218,42219],{"class":802}," unhealthy\n",[747,42221,42222,42225,42227,42230,42232,42234,42236,42238,42240,42243,42246,42249,42252,42255,42257,42259,42261,42263,42265,42267,42269,42271,42273,42275],{"class":749,"line":1520},[747,42223,42224],{"class":1630},"      --health-start-period",[747,42226,42157],{"class":802},[747,42228,42229],{"class":802},"   Start",[747,42231,41613],{"class":802},[747,42233,3761],{"class":802},[747,42235,3839],{"class":802},[747,42237,3936],{"class":802},[747,42239,3696],{"class":802},[747,42241,42242],{"class":802}," initialize",[747,42244,42245],{"class":802}," before",[747,42247,42248],{"class":802}," starting",[747,42250,42251],{"class":802}," health-retries",[747,42253,42254],{"class":802}," countdown",[747,42256,42172],{"class":1640},[747,42258,3616],{"class":757},[747,42260,4978],{"class":1630},[747,42262,3616],{"class":757},[747,42264,42181],{"class":1630},[747,42266,3616],{"class":757},[747,42268,42186],{"class":1630},[747,42270,4392],{"class":1640},[747,42272,2014],{"class":1630},[747,42274,42193],{"class":802},[747,42276,3600],{"class":1640},[747,42278,42279,42282,42284,42287,42290,42292,42294,42296,42298,42300,42302,42304,42306,42308,42310,42312,42314,42316,42318,42320,42322],{"class":749,"line":1525},[747,42280,42281],{"class":1630},"      --health-timeout",[747,42283,42157],{"class":802},[747,42285,42286],{"class":802},"        Maximum",[747,42288,42289],{"class":802}," time",[747,42291,3696],{"class":802},[747,42293,8529],{"class":802},[747,42295,36690],{"class":802},[747,42297,42146],{"class":802},[747,42299,3696],{"class":802},[747,42301,3665],{"class":802},[747,42303,42172],{"class":1640},[747,42305,3616],{"class":757},[747,42307,4978],{"class":1630},[747,42309,3616],{"class":757},[747,42311,42181],{"class":1630},[747,42313,3616],{"class":757},[747,42315,42186],{"class":1630},[747,42317,4392],{"class":1640},[747,42319,2014],{"class":1630},[747,42321,42193],{"class":802},[747,42323,3600],{"class":1640},[747,42325,42326,42329,42332],{"class":749,"line":1533},[747,42327,42328],{"class":1630},"      --help",[747,42330,42331],{"class":802},"                           Print",[747,42333,42334],{"class":802}," usage\n",[747,42336,42337,42340,42343,42345,42348,42350],{"class":749,"line":1539},[747,42338,42339],{"class":1630},"  -h,",[747,42341,42342],{"class":802}," --hostname",[747,42344,4522],{"class":802},[747,42346,42347],{"class":802},"                Container",[747,42349,4591],{"class":802},[747,42351,42352],{"class":802}," name\n",[747,42354,42355,42358,42361,42363,42365,42367,42369,42371,42373,42376,42378,42380,42383],{"class":749,"line":1549},[747,42356,42357],{"class":1630},"      --init",[747,42359,42360],{"class":802},"                           Run",[747,42362,4053],{"class":802},[747,42364,35521],{"class":802},[747,42366,5623],{"class":802},[747,42368,3839],{"class":802},[747,42370,3936],{"class":802},[747,42372,3792],{"class":802},[747,42374,42375],{"class":802}," forwards",[747,42377,5294],{"class":802},[747,42379,4099],{"class":802},[747,42381,42382],{"class":802}," reaps",[747,42384,42385],{"class":802}," processes\n",[747,42387,42388,42391,42394,42397,42400,42403,42406,42408,42410],{"class":749,"line":1554},[747,42389,42390],{"class":1630},"  -i,",[747,42392,42393],{"class":802}," --interactive",[747,42395,42396],{"class":802},"                    Keep",[747,42398,42399],{"class":802}," STDIN",[747,42401,42402],{"class":802}," open",[747,42404,42405],{"class":802}," even",[747,42407,5062],{"class":802},[747,42409,37708],{"class":802},[747,42411,42412],{"class":802}," attached\n",[747,42414,42415,42418,42420,42423,42425,42427,42430],{"class":749,"line":1562},[747,42416,42417],{"class":1630},"      --ip",[747,42419,4522],{"class":802},[747,42421,42422],{"class":802},"                      IPv4",[747,42424,7538],{"class":802},[747,42426,12893],{"class":1640},[747,42428,42429],{"class":1895},"172.30.100.104",[747,42431,3600],{"class":1640},[747,42433,42434,42437,42439,42442,42444,42446,42449],{"class":749,"line":1568},[747,42435,42436],{"class":1630},"      --ip6",[747,42438,4522],{"class":802},[747,42440,42441],{"class":802},"                     IPv6",[747,42443,7538],{"class":802},[747,42445,12893],{"class":1640},[747,42447,42448],{"class":802},"2001:db8::33",[747,42450,3600],{"class":1640},[747,42452,42453,42456,42458,42461,42463,42465],{"class":749,"line":1577},[747,42454,42455],{"class":1630},"      --ipc",[747,42457,4522],{"class":802},[747,42459,42460],{"class":802},"                     IPC",[747,42462,17855],{"class":802},[747,42464,3696],{"class":802},[747,42466,5013],{"class":802},[747,42468,42469,42472,42474,42477,42480],{"class":749,"line":1582},[747,42470,42471],{"class":1630},"      --isolation",[747,42473,4522],{"class":802},[747,42475,42476],{"class":802},"               Container",[747,42478,42479],{"class":802}," isolation",[747,42481,42482],{"class":802}," technology\n",[747,42484,42485,42488,42490,42493,42495],{"class":749,"line":1588},[747,42486,42487],{"class":1630},"      --kernel-memory",[747,42489,5270],{"class":802},[747,42491,42492],{"class":802},"            Kernel",[747,42494,8624],{"class":802},[747,42496,8627],{"class":802},[747,42498,42499,42502,42505,42507,42510,42513,42515,42517,42519],{"class":749,"line":1594},[747,42500,42501],{"class":1630},"  -l,",[747,42503,42504],{"class":802}," --label",[747,42506,4334],{"class":802},[747,42508,42509],{"class":802},"                     Set",[747,42511,42512],{"class":802}," meta",[747,42514,17736],{"class":802},[747,42516,33307],{"class":802},[747,42518,3930],{"class":802},[747,42520,4538],{"class":802},[747,42522,42523,42526,42528,42531,42533,42535,42537,42540,42542,42544],{"class":749,"line":1600},[747,42524,42525],{"class":1630},"      --label-file",[747,42527,4334],{"class":802},[747,42529,42530],{"class":802},"                Read",[747,42532,4584],{"class":802},[747,42534,3930],{"class":802},[747,42536,33315],{"class":802},[747,42538,42539],{"class":802}," delimited",[747,42541,11351],{"class":802},[747,42543,5276],{"class":802},[747,42545,42546],{"class":802}," labels\n",[747,42548,42549,42552,42554,42557,42559,42561,42564],{"class":749,"line":4804},[747,42550,42551],{"class":1630},"      --link",[747,42553,4334],{"class":802},[747,42555,42556],{"class":802},"                      Add",[747,42558,7791],{"class":802},[747,42560,3696],{"class":802},[747,42562,42563],{"class":802}," another",[747,42565,4538],{"class":802},[747,42567,42568,42571,42573,42576,42579,42582],{"class":749,"line":4810},[747,42569,42570],{"class":1630},"      --link-local-ip",[747,42572,4334],{"class":802},[747,42574,42575],{"class":802},"             Container",[747,42577,42578],{"class":802}," IPv4\u002FIPv6",[747,42580,42581],{"class":802}," link-local",[747,42583,42584],{"class":802}," addresses\n",[747,42586,42587,42590,42592,42595,42597,42599,42601],{"class":749,"line":4816},[747,42588,42589],{"class":1630},"      --log-driver",[747,42591,4522],{"class":802},[747,42593,42594],{"class":802},"              Logging",[747,42596,5362],{"class":802},[747,42598,3761],{"class":802},[747,42600,3839],{"class":802},[747,42602,4538],{"class":802},[747,42604,42605,42608,42610,42613,42615],{"class":749,"line":4822},[747,42606,42607],{"class":1630},"      --log-opt",[747,42609,4334],{"class":802},[747,42611,42612],{"class":802},"                   Log",[747,42614,5362],{"class":802},[747,42616,41997],{"class":802},[747,42618,42619,42622,42624,42626,42629,42631,42633,42636],{"class":749,"line":4828},[747,42620,42621],{"class":1630},"      --mac-address",[747,42623,4522],{"class":802},[747,42625,42575],{"class":802},[747,42627,42628],{"class":802}," MAC",[747,42630,7538],{"class":802},[747,42632,12893],{"class":1640},[747,42634,42635],{"class":802},"92:d0:c6:0a:29:33",[747,42637,3600],{"class":1640},[747,42639,42640,42643,42646,42648,42651],{"class":749,"line":4834},[747,42641,42642],{"class":1630},"  -m,",[747,42644,42645],{"class":802}," --memory",[747,42647,5270],{"class":802},[747,42649,42650],{"class":802},"                   Memory",[747,42652,8627],{"class":802},[747,42654,42655,42658,42660,42663,42665],{"class":749,"line":4840},[747,42656,42657],{"class":1630},"      --memory-reservation",[747,42659,5270],{"class":802},[747,42661,42662],{"class":802},"       Memory",[747,42664,8646],{"class":802},[747,42666,8627],{"class":802},[747,42668,42669,42672,42674,42677,42679,42681,42683,42685,42687,42689,42691,42693,42695,42697,42699,42701],{"class":749,"line":4846},[747,42670,42671],{"class":1630},"      --memory-swap",[747,42673,5270],{"class":802},[747,42675,42676],{"class":802},"              Swap",[747,42678,5033],{"class":802},[747,42680,8661],{"class":802},[747,42682,3696],{"class":802},[747,42684,8624],{"class":802},[747,42686,8668],{"class":802},[747,42688,8671],{"class":802},[747,42690,3537],{"class":757},[747,42692,4920],{"class":802},[747,42694,3543],{"class":757},[747,42696,3696],{"class":802},[747,42698,3205],{"class":802},[747,42700,5043],{"class":802},[747,42702,8686],{"class":802},[747,42704,42705,42708,42710,42712,42714,42716,42718,42720,42722,42724,42726,42728,42731],{"class":749,"line":4852},[747,42706,42707],{"class":1630},"      --memory-swappiness",[747,42709,5022],{"class":802},[747,42711,8698],{"class":802},[747,42713,3936],{"class":802},[747,42715,8624],{"class":802},[747,42717,8705],{"class":802},[747,42719,8708],{"class":1640},[747,42721,4990],{"class":802},[747,42723,8713],{"class":1895},[747,42725,4392],{"class":1640},[747,42727,2014],{"class":1630},[747,42729,42730],{"class":802}," -1",[747,42732,3600],{"class":1640},[747,42734,42735,42738,42740,42742,42744,42746,42748,42750,42752],{"class":749,"line":4858},[747,42736,42737],{"class":1630},"      --mount",[747,42739,5548],{"class":802},[747,42741,41426],{"class":802},[747,42743,3930],{"class":802},[747,42745,5152],{"class":802},[747,42747,5548],{"class":802},[747,42749,3696],{"class":802},[747,42751,3839],{"class":802},[747,42753,4538],{"class":802},[747,42755,42756,42759,42761,42764,42766,42768,42770,42772],{"class":749,"line":4864},[747,42757,42758],{"class":1630},"      --name",[747,42760,4522],{"class":802},[747,42762,42763],{"class":802},"                    Assign",[747,42765,3930],{"class":802},[747,42767,14804],{"class":802},[747,42769,3696],{"class":802},[747,42771,3839],{"class":802},[747,42773,4538],{"class":802},[747,42775,42776,42779,42781,42784,42786,42788,42790,42792,42794,42796,42798,42800,42802],{"class":749,"line":4870},[747,42777,42778],{"class":1630},"      --network",[747,42780,4522],{"class":802},[747,42782,42783],{"class":802},"                 Connect",[747,42785,3930],{"class":802},[747,42787,3936],{"class":802},[747,42789,3696],{"class":802},[747,42791,3930],{"class":802},[747,42793,36666],{"class":802},[747,42795,5193],{"class":1640},[747,42797,3892],{"class":757},[747,42799,2014],{"class":802},[747,42801,3892],{"class":757},[747,42803,3600],{"class":1640},[747,42805,42806,42809,42811,42814,42817,42820,42822,42824],{"class":749,"line":4876},[747,42807,42808],{"class":1630},"      --network-alias",[747,42810,4334],{"class":802},[747,42812,42813],{"class":802},"             Add",[747,42815,42816],{"class":802}," network-scoped",[747,42818,42819],{"class":802}," alias",[747,42821,3761],{"class":802},[747,42823,3839],{"class":802},[747,42825,4538],{"class":802},[747,42827,42828,42831,42834,42836,42839],{"class":749,"line":4882},[747,42829,42830],{"class":1630},"      --no-healthcheck",[747,42832,42833],{"class":802},"                 Disable",[747,42835,36726],{"class":802},[747,42837,42838],{"class":802}," container-specified",[747,42840,42841],{"class":802}," HEALTHCHECK\n",[747,42843,42844,42847,42850,42852],{"class":749,"line":4888},[747,42845,42846],{"class":1630},"      --oom-kill-disable",[747,42848,42849],{"class":802},"               Disable",[747,42851,4981],{"class":802},[747,42853,8736],{"class":802},[747,42855,42856,42859,42861,42864,42866,42868],{"class":749,"line":4894},[747,42857,42858],{"class":1630},"      --oom-score-adj",[747,42860,5022],{"class":802},[747,42862,42863],{"class":802},"              Tune",[747,42865,4591],{"class":802},[747,42867,3543],{"class":757},[747,42869,8751],{"class":802},[747,42871,42872],{"class":749,"line":4900},[747,42873,42874],{"class":802},"      --pid string                     PID namespace to use\n",[747,42876,42877],{"class":749,"line":4906},[747,42878,42879],{"class":802},"      --pids-limit int                 Tune container pids limit (set -1 for unlimited)\n",[747,42881,42882],{"class":749,"line":4912},[747,42883,42884],{"class":802},"      --privileged                     Give extended privileges to this container\n",[747,42886,42887,42890,42892,42894,42896,42898,42900,42902,42904,42906],{"class":749,"line":4928},[747,42888,42889],{"class":802},"  -p, --publish list                   Publish a container",[747,42891,3543],{"class":757},[747,42893,4978],{"class":802},[747,42895,42094],{"class":802},[747,42897,2000],{"class":757},[747,42899,4978],{"class":1630},[747,42901,2006],{"class":757},[747,42903,3696],{"class":802},[747,42905,3839],{"class":802},[747,42907,42908],{"class":802}," host\n",[747,42910,42911,42914,42917,42920,42923,42926,42929,42931,42934],{"class":749,"line":4934},[747,42912,42913],{"class":1630},"  -P,",[747,42915,42916],{"class":802}," --publish-all",[747,42918,42919],{"class":802},"                    Publish",[747,42921,42922],{"class":802}," all",[747,42924,42925],{"class":802}," exposed",[747,42927,42928],{"class":802}," ports",[747,42930,3696],{"class":802},[747,42932,42933],{"class":802}," random",[747,42935,42106],{"class":802},[747,42937,42938,42941,42944,42946,42948,42950],{"class":749,"line":4940},[747,42939,42940],{"class":1630},"      --read-only",[747,42942,42943],{"class":802},"                      Mount",[747,42945,3839],{"class":802},[747,42947,3936],{"class":802},[747,42949,3543],{"class":757},[747,42951,42952],{"class":802},"s root filesystem as read only\n",[747,42954,42955],{"class":749,"line":4946},[747,42956,42957],{"class":802},"      --restart string                 Restart policy to apply when a container exits (default \"no\")\n",[747,42959,42960],{"class":749,"line":4952},[747,42961,42962],{"class":802},"      --rm                             Automatically remove the container when it exits\n",[747,42964,42965],{"class":749,"line":4958},[747,42966,42967],{"class":802},"      --runtime string                 Runtime to use for this container\n",[747,42969,42970],{"class":749,"line":4964},[747,42971,42972],{"class":802},"      --security-opt list              Security Options\n",[747,42974,42975],{"class":749,"line":4970},[747,42976,42977],{"class":802},"      --shm-size bytes                 Size of \u002Fdev\u002Fshm\n",[747,42979,42980],{"class":749,"line":4998},[747,42981,42982],{"class":802},"      --sig-proxy                      Proxy received signals to the process (default true)\n",[747,42984,42985],{"class":749,"line":5016},[747,42986,42987],{"class":802},"      --stop-signal string             Signal to stop a container (default \"SIGTERM\")\n",[747,42989,42990],{"class":749,"line":5048},[747,42991,42992],{"class":802},"      --stop-timeout int               Timeout (in seconds) to stop a container\n",[747,42994,42995],{"class":749,"line":5077},[747,42996,42997],{"class":802},"      --storage-opt list               Storage driver options for the container\n",[747,42999,43000],{"class":749,"line":5098},[747,43001,43002],{"class":802},"      --sysctl map                     Sysctl options (default map[])\n",[747,43004,43005],{"class":749,"line":5121},[747,43006,43007],{"class":802},"      --tmpfs list                     Mount a tmpfs directory\n",[747,43009,43010],{"class":749,"line":5127},[747,43011,43012],{"class":802},"  -t, --tty                            Allocate a pseudo-TTY\n",[747,43014,43015],{"class":749,"line":5133},[747,43016,43017],{"class":802},"      --ulimit ulimit                  Ulimit options (default [])\n",[747,43019,43020],{"class":749,"line":5139},[747,43021,43022],{"class":802},"  -u, --user string                    Username or UID (format: \u003Cname|uid>[:\u003Cgroup|gid>])\n",[747,43024,43025],{"class":749,"line":5164},[747,43026,43027],{"class":802},"      --userns string                  User namespace to use\n",[747,43029,43030],{"class":749,"line":5205},[747,43031,43032],{"class":802},"      --uts string                     UTS namespace to use\n",[747,43034,43035],{"class":749,"line":5229},[747,43036,43037],{"class":802},"  -v, --volume list                    Bind mount a volume\n",[747,43039,43040],{"class":749,"line":5250},[747,43041,43042],{"class":802},"      --volume-driver string           Optional volume driver for the container\n",[747,43044,43045],{"class":749,"line":5264},[747,43046,43047],{"class":802},"      --volumes-from list              Mount volumes from the specified container(s)\n",[747,43049,43050],{"class":749,"line":5282},[747,43051,43052],{"class":802},"  -w, --workdir string                 Working directory inside the container\n",[523,43054,5630,43055,43057],{},[567,43056,4203],{}," has a lot of flags, to choose from. These flags allow to \"configure\" how the container should created.",[6072,43059,43060,43064],{},[523,43061,43062],{},[584,43063,6189],{},[523,43065,43066,43067,43070],{},"Most of these flags are also available for ",[567,43068,43069],{},"docker create",", which can be used to create containers but not start them.",[523,43072,43073],{},"In this workshop we are only covering the basic flags, you should know to begin with.",[523,43075,43076],{},"So we are going to focus on the usage part first:",[6072,43078,43079],{},[738,43080,43081],{"className":1621,"code":743,"language":1623,"meta":743,"style":743},[567,43082,43083],{"__ignoreMap":743},[747,43084],{"class":749,"line":750},[523,43086,43087],{},"$ docker run --help",[523,43089,43090,43091,43093,43094,8287,43096],{},"Usage:\tdocker run ",[747,43092,38965],{}," IMAGE ",[747,43095,4256],{},[747,43097,4265],{},[523,43099,43100],{},"Run a command in a new container",[738,43102,43105],{"className":43103,"code":43104,"language":12479},[12477],"\n> **WDWD**\n>\n* `[OPTIONS]` - Run flags for the container to be run.\n* `IMAGE` - The name of the Container image to use for the container.\n* `[COMMAND] [ARG ...]` - Depending on the images, `COMMAND` and `ARG`s will be used either as arguments or as the command + arguments by the so called \"entrypoint\" of the container.\n\nI'm going in depth about image names, command args and entrypoint later on in [\"Understanding Dockerfiles\"](#Understanding-Dockerfiles).\n\n### Starting the MariaDB database server\n\nWe are going to use the \"official\" MariaDB Container image from the Docker Hub.\nSo we will now specify that image as the `IMAGE` argument in our `docker run` command now:\n\n```bash\ndocker run \\\n    mariadb:10.4.3-bionic\n",[567,43106,43104],{"__ignoreMap":743},[523,43108,43109,43110,1909],{},"When running this command the first time, Docker will pull the image from the Docker Hub and then create the container from it.\nBut as we have not given any configuration details for it, the \"entrypoint\" script exits with an error telling us that we need to specify certain environment variables.\nThe \"entrypoint\" script is the \"first\" thing to be executed when the container is started, which happens automatically when using ",[567,43111,4203],{},[523,43113,43114],{},"The output should look something like this:",[738,43116,43118],{"className":1621,"code":43117,"language":1623,"meta":743,"style":743},"$ docker run \\\n   mariadb:10.4.3-bionic\nUnable to find image 'mariadb:10.4.3-bionic' locally\n10.4.3-bionic: Pulling from library\u002Fmariadb\n898c46f3b1a1: Pull complete\n63366dfa0a50: Pull complete\n041d4cd74a92: Pull complete\n6e1bee0f8701: Pull complete\n0fa9bfc0c84b: Pull complete\n8e9b088fe106: Pull complete\naf96bccda5c4: Pull complete\n0655ee57b408: Pull complete\n58e50a9049b1: Pull complete\n57cd7839e491: Pull complete\n23d8b0c94134: Pull complete\n4aaa8cd60ac7: Pull complete\n052f0d0b139f: Pull complete\n78d717e43484: Pull complete\nDigest: sha256:fb69aaa343a69826d4fb00809b8eb340a660cec3651a946dfd87f2113e0af627\nStatus: Downloaded newer image for mariadb:10.4.3-bionic\nerror: database is uninitialized and password option is not specified\n  You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD\n",[567,43119,43120,43130,43135,43154,43166,43175,43184,43193,43202,43211,43220,43229,43238,43247,43256,43265,43274,43283,43292,43299,43314,43341],{"__ignoreMap":743},[747,43121,43122,43124,43126,43128],{"class":749,"line":750},[747,43123,1919],{"class":1630},[747,43125,3246],{"class":802},[747,43127,3665],{"class":802},[747,43129,1641],{"class":1640},[747,43131,43132],{"class":749,"line":761},[747,43133,43134],{"class":802},"   mariadb:10.4.3-bionic\n",[747,43136,43137,43139,43141,43143,43145,43147,43150,43152],{"class":749,"line":769},[747,43138,3693],{"class":1630},[747,43140,3696],{"class":802},[747,43142,3699],{"class":802},[747,43144,3702],{"class":802},[747,43146,3537],{"class":757},[747,43148,43149],{"class":802},"mariadb:10.4.3-bionic",[747,43151,3543],{"class":757},[747,43153,3712],{"class":802},[747,43155,43156,43159,43161,43163],{"class":749,"line":776},[747,43157,43158],{"class":1630},"10.4.3-bionic:",[747,43160,3720],{"class":802},[747,43162,3723],{"class":802},[747,43164,43165],{"class":802}," library\u002Fmariadb\n",[747,43167,43168,43171,43173],{"class":749,"line":784},[747,43169,43170],{"class":1630},"898c46f3b1a1:",[747,43172,3734],{"class":802},[747,43174,3737],{"class":802},[747,43176,43177,43180,43182],{"class":749,"line":790},[747,43178,43179],{"class":1630},"63366dfa0a50:",[747,43181,3734],{"class":802},[747,43183,3737],{"class":802},[747,43185,43186,43189,43191],{"class":749,"line":796},[747,43187,43188],{"class":1630},"041d4cd74a92:",[747,43190,3734],{"class":802},[747,43192,3737],{"class":802},[747,43194,43195,43198,43200],{"class":749,"line":806},[747,43196,43197],{"class":1630},"6e1bee0f8701:",[747,43199,3734],{"class":802},[747,43201,3737],{"class":802},[747,43203,43204,43207,43209],{"class":749,"line":814},[747,43205,43206],{"class":1630},"0fa9bfc0c84b:",[747,43208,3734],{"class":802},[747,43210,3737],{"class":802},[747,43212,43213,43216,43218],{"class":749,"line":822},[747,43214,43215],{"class":1630},"8e9b088fe106:",[747,43217,3734],{"class":802},[747,43219,3737],{"class":802},[747,43221,43222,43225,43227],{"class":749,"line":830},[747,43223,43224],{"class":1630},"af96bccda5c4:",[747,43226,3734],{"class":802},[747,43228,3737],{"class":802},[747,43230,43231,43234,43236],{"class":749,"line":836},[747,43232,43233],{"class":1630},"0655ee57b408:",[747,43235,3734],{"class":802},[747,43237,3737],{"class":802},[747,43239,43240,43243,43245],{"class":749,"line":842},[747,43241,43242],{"class":1630},"58e50a9049b1:",[747,43244,3734],{"class":802},[747,43246,3737],{"class":802},[747,43248,43249,43252,43254],{"class":749,"line":850},[747,43250,43251],{"class":1630},"57cd7839e491:",[747,43253,3734],{"class":802},[747,43255,3737],{"class":802},[747,43257,43258,43261,43263],{"class":749,"line":863},[747,43259,43260],{"class":1630},"23d8b0c94134:",[747,43262,3734],{"class":802},[747,43264,3737],{"class":802},[747,43266,43267,43270,43272],{"class":749,"line":869},[747,43268,43269],{"class":1630},"4aaa8cd60ac7:",[747,43271,3734],{"class":802},[747,43273,3737],{"class":802},[747,43275,43276,43279,43281],{"class":749,"line":877},[747,43277,43278],{"class":1630},"052f0d0b139f:",[747,43280,3734],{"class":802},[747,43282,3737],{"class":802},[747,43284,43285,43288,43290],{"class":749,"line":1015},[747,43286,43287],{"class":1630},"78d717e43484:",[747,43289,3734],{"class":802},[747,43291,3737],{"class":802},[747,43293,43294,43296],{"class":749,"line":1021},[747,43295,3742],{"class":1630},[747,43297,43298],{"class":802}," sha256:fb69aaa343a69826d4fb00809b8eb340a660cec3651a946dfd87f2113e0af627\n",[747,43300,43301,43303,43305,43307,43309,43311],{"class":749,"line":1027},[747,43302,3750],{"class":1630},[747,43304,3753],{"class":802},[747,43306,3756],{"class":802},[747,43308,3702],{"class":802},[747,43310,3761],{"class":802},[747,43312,43313],{"class":802}," mariadb:10.4.3-bionic\n",[747,43315,43316,43319,43322,43324,43327,43329,43331,43334,43336,43338],{"class":749,"line":1033},[747,43317,43318],{"class":1630},"error:",[747,43320,43321],{"class":802}," database",[747,43323,5068],{"class":802},[747,43325,43326],{"class":802}," uninitialized",[747,43328,4099],{"class":802},[747,43330,33304],{"class":802},[747,43332,43333],{"class":802}," option",[747,43335,5068],{"class":802},[747,43337,37708],{"class":802},[747,43339,43340],{"class":802}," specified\n",[747,43342,43343,43346,43348,43350,43353,43355,43357,43360,43363,43365],{"class":749,"line":1039},[747,43344,43345],{"class":1630},"  You",[747,43347,36556],{"class":802},[747,43349,3696],{"class":802},[747,43351,43352],{"class":802}," specify",[747,43354,36690],{"class":802},[747,43356,5276],{"class":802},[747,43358,43359],{"class":802}," MYSQL_ROOT_PASSWORD,",[747,43361,43362],{"class":802}," MYSQL_ALLOW_EMPTY_PASSWORD",[747,43364,4099],{"class":802},[747,43366,43367],{"class":802}," MYSQL_RANDOM_ROOT_PASSWORD\n",[523,43369,43370,43371,43373],{},"What is the container named? Can the Docker daemon read our mind and has already named ",[567,43372,6815],{},"? A random name is given to the container, and thankfully no.\nWhen a container is started and no name is given, it will receive a randomly generated name. It is an actual name and not just some bits and bytes mashed in a mixer, that would be the container id.",[523,43375,8336,43376,43379,43380,43382,43383,7026],{},[527,43377,4153],{"href":43378},"#basic-commands-you-need-to-know"," section we have learned about the ",[567,43381,4160],{}," command. Now we are going to use it to learn more about it and get the name and id of the first try at a ",[567,43384,41285],{},[738,43386,43388],{"className":1621,"code":43387,"language":1623,"meta":743,"style":743},"$ docker ps\nCONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES\n",[567,43389,43390,43398],{"__ignoreMap":743},[747,43391,43392,43394,43396],{"class":749,"line":750},[747,43393,1919],{"class":1630},[747,43395,3246],{"class":802},[747,43397,40958],{"class":802},[747,43399,43400,43402,43404,43407,43410,43413,43416,43419],{"class":749,"line":761},[747,43401,4188],{"class":1630},[747,43403,41167],{"class":802},[747,43405,43406],{"class":802},"        IMAGE",[747,43408,43409],{"class":802},"               COMMAND",[747,43411,43412],{"class":802},"             CREATED",[747,43414,43415],{"class":802},"             STATUS",[747,43417,43418],{"class":802},"              PORTS",[747,43420,43421],{"class":802},"               NAMES\n",[523,43423,43424,43425,43427,43428,43430],{},"What's that? No container in the list of running containers. Due to the missing configuration as seen in the above logs the container is not running anymore and has terminated itself.\nThe ",[567,43426,4160],{}," command has a flag called ",[567,43429,4164],{}," which will show us all container, even those not running anymore:",[738,43432,43434],{"className":1621,"code":43433,"language":1623,"meta":743,"style":743},"$ docker ps -a\nCONTAINER ID        IMAGE                   COMMAND                  CREATED              STATUS                          PORTS               NAMES\n7864ef7db36a        mariadb:10.4.3-bionic   \"docker-entrypoint.s…\"   About a minute ago   Exited (1) About a minute ago                       recursing_bell\n",[567,43435,43436,43446,43468],{"__ignoreMap":743},[747,43437,43438,43440,43442,43444],{"class":749,"line":750},[747,43439,1919],{"class":1630},[747,43441,3246],{"class":802},[747,43443,40972],{"class":802},[747,43445,40975],{"class":802},[747,43447,43448,43450,43452,43454,43457,43460,43463,43466],{"class":749,"line":761},[747,43449,4188],{"class":1630},[747,43451,41167],{"class":802},[747,43453,43406],{"class":802},[747,43455,43456],{"class":802},"                   COMMAND",[747,43458,43459],{"class":802},"                  CREATED",[747,43461,43462],{"class":802},"              STATUS",[747,43464,43465],{"class":802},"                          PORTS",[747,43467,43421],{"class":802},[747,43469,43470,43473,43476,43479,43482,43484,43487,43489,43492,43494,43497],{"class":749,"line":769},[747,43471,43472],{"class":1630},"7864ef7db36a",[747,43474,43475],{"class":802},"        mariadb:10.4.3-bionic",[747,43477,43478],{"class":757},"   \"",[747,43480,43481],{"class":802},"docker-entrypoint.s…",[747,43483,3892],{"class":757},[747,43485,43486],{"class":802},"   About",[747,43488,3930],{"class":802},[747,43490,43491],{"class":802}," minute",[747,43493,41195],{"class":802},[747,43495,43496],{"class":802},"   Exited",[747,43498,43499],{"class":1640}," (1) About a minute ago                       recursing_bell\n",[523,43501,43502,43503,43505,43506,43509],{},"In this case the container (short) ID is ",[567,43504,43472],{}," and the generated name is ",[567,43507,43508],{},"recursing_bell",", to change that so that we can target the container more easily we are going to give the container a name in the next section.",[3126,43511,43513],{"id":43512},"lets-give-the-container-a-name-before-continuing","Let's give the container a name before continuing",[523,43515,43516],{},[3069,43517],{"alt":43518,"src":43519},"Hello my name is: Mr. Docker, Container","\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day1\u002Fhello_my_name_is_docker_container_sticker.png",[523,43521,43522,43523,2006],{},"(Original image taken from ",[527,43524,43525],{"href":43525,"rel":43526},"https:\u002F\u002Fcommons.wikimedia.org\u002Fwiki\u002FFile:Hello_my_name_is_sticker.svg",[531],[523,43528,43529,43530,43533],{},"Our MariaDB database server container should have a name, right? When not specifying a name for the container it will get a randomized name.\nEvery container gets an unique ID and randomized name. We can set\u002F override the name with the ",[567,43531,43532],{},"--name=NAME"," flag.\nLet's name it \"database\".",[523,43535,43536],{},"Before running the command again, let's first add a name to the container and add some configuration to it. The configuration part will be done in the next section though.",[523,43538,43539,43540,43542],{},"Adding a name to a container is as simple as adding another flag to the ",[567,43541,4203],{}," command, example:",[738,43544,43546],{"className":1621,"code":43545,"language":1623,"meta":743,"style":743},"docker run \\\n    --name=database \\\n    mariadb:10.4.3-bionic\n",[567,43547,43548,43556,43563],{"__ignoreMap":743},[747,43549,43550,43552,43554],{"class":749,"line":750},[747,43551,3257],{"class":1630},[747,43553,3665],{"class":802},[747,43555,1641],{"class":1640},[747,43557,43558,43561],{"class":749,"line":761},[747,43559,43560],{"class":802},"    --name=database",[747,43562,1641],{"class":1640},[747,43564,43565],{"class":749,"line":769},[747,43566,43567],{"class":802},"    mariadb:10.4.3-bionic\n",[523,43569,43570,43571,43573],{},"This gives the container the name ",[567,43572,6815],{},", which makes it easier to target the container and simplifies later processes, like connecting from the upcoming WordPress container to the MariaDB database server container.",[3126,43575,43577],{"id":43576},"how-would-one-configure-the-mariadb-database-server-container","How would one configure the MariaDB database server container?",[523,43579,43580],{},"One big questions will be for you, \"How can I configure the MariaDB database server?\" in the container.",[523,43582,43583,43584,5915,43586,43588],{},"You can..\n",[584,43585,3022],{},[584,43587,3026],{}," use environment variables (portable and the best way).",[523,43590,43591],{},"The most portable way is to use environment variables.\nMost containers that are configured through environment variables, have a script, the entrypoint, that sets config variables and a lot more, before the main application\u002F program is started.",[523,43593,6803,43594,43596],{},[567,43595,41285],{}," container image the following environment variables are available for configuration:",[668,43598,43599,43605,43609,43615,43620,43626],{},[638,43600,43601,5945,43603,1909],{},[567,43602,5939],{},[567,43604,5935],{},[638,43606,43607,5953],{},[567,43608,5952],{},[638,43610,43611,5936,43613,1909],{},[567,43612,5935],{},[567,43614,5939],{},[638,43616,43617,43619],{},[567,43618,6069],{}," - Root user password for database server.",[638,43621,43622,43625],{},[567,43623,43624],{},"MYSQL_ROOT_HOST"," - Root user allowed host (range) for database server.",[638,43627,43628],{},"And more to configure the database more granular..",[523,43630,5956,43631,5845,43633,43635],{},[567,43632,5959],{},[567,43634,5962],{}," short form) flag can be used:",[738,43637,43639],{"className":1621,"code":43638,"language":1623,"meta":743,"style":743},"docker run \\\n[...]\n    --env 'MYSQL_USER=wordpress' \\\n    -e 'MYSQL_PASSWORD=wordpress' \\\n    -e 'MYSQL_DATABASE=wordpress' \\\n    -e 'MYSQL_ROOT_PASSWORD=secure_password' \\\n    -e 'MYSQL_ROOT_HOST=%' \\\n[...]\n",[567,43640,43641,43649,43653,43666,43678,43690,43703,43716],{"__ignoreMap":743},[747,43642,43643,43645,43647],{"class":749,"line":750},[747,43644,3257],{"class":1630},[747,43646,3665],{"class":802},[747,43648,1641],{"class":1640},[747,43650,43651],{"class":749,"line":761},[747,43652,5986],{"class":1640},[747,43654,43655,43658,43660,43662,43664],{"class":749,"line":769},[747,43656,43657],{"class":1630},"    --env",[747,43659,3537],{"class":757},[747,43661,6009],{"class":802},[747,43663,3543],{"class":757},[747,43665,1641],{"class":1640},[747,43667,43668,43670,43672,43674,43676],{"class":749,"line":776},[747,43669,5991],{"class":802},[747,43671,3537],{"class":757},[747,43673,6022],{"class":802},[747,43675,3543],{"class":757},[747,43677,1641],{"class":1640},[747,43679,43680,43682,43684,43686,43688],{"class":749,"line":784},[747,43681,5991],{"class":802},[747,43683,3537],{"class":757},[747,43685,5996],{"class":802},[747,43687,3543],{"class":757},[747,43689,1641],{"class":1640},[747,43691,43692,43694,43696,43699,43701],{"class":749,"line":790},[747,43693,5991],{"class":802},[747,43695,3537],{"class":757},[747,43697,43698],{"class":802},"MYSQL_ROOT_PASSWORD=secure_password",[747,43700,3543],{"class":757},[747,43702,1641],{"class":1640},[747,43704,43705,43707,43709,43712,43714],{"class":749,"line":796},[747,43706,5991],{"class":802},[747,43708,3537],{"class":757},[747,43710,43711],{"class":802},"MYSQL_ROOT_HOST=%",[747,43713,3543],{"class":757},[747,43715,1641],{"class":1640},[747,43717,43718],{"class":749,"line":806},[747,43719,5986],{"class":1640},[523,43721,43722],{},[3049,43723,6035],{},[6072,43725,43726],{},[523,43727,6040,43728,43731],{},[567,43729,43730],{},"openssl rand -base64 64",", can be used to generate a \"secure\" passwords.",[3126,43733,5806],{"id":5805},[523,43735,43736,43737,43739,43740,43742,43743,587,43745,43747,43748,43750,43751,587,43753,43755,43756,5838,43758,43760,43761,1909],{},"If you run the command to start the container, upon start you see some log output coming, but should notice that when closing the terminal, the database container will be immediately stopped (run ",[567,43738,5819],{}," to see all containers).\nWhen you ",[567,43741,4203],{}," a container, by default your current ",[567,43744,5823],{},[567,43746,5826],{}," will be attached to the container, making it \"interactive\" (If you want an interactive container, you should still add ",[567,43749,5815],{}," flag, so it is clear from that).\nIf you want as for most applications, like database, web, cache and so on server application, you can disable the attachment of ",[567,43752,5823],{},[567,43754,5826],{}," by adding the ",[567,43757,5812],{},[567,43759,5841],{},") flag to the command. To view logs of the detached container you can normally use ",[567,43762,41103],{},[523,43764,43765,43766,43768,43769,43771,43772,43774],{},"Have you already run into errors where Docker is telling you that a container with the same exists? You need to delete exited\u002F stopped containers with the ",[567,43767,41073],{}," command (where ",[567,43770,41047],{}," would be, is the name or ID of the container, e.g., ",[567,43773,6815],{},"), this \"clears\" their name and removes the container.",[523,43776,43777,43778,43780],{},"The command to delete the container named ",[567,43779,6815],{}," is like this:",[738,43782,43784],{"className":1621,"code":43783,"language":1623,"meta":743,"style":743},"$ docker rm database\ndatabase\n",[567,43785,43786,43797],{"__ignoreMap":743},[747,43787,43788,43790,43792,43794],{"class":749,"line":750},[747,43789,1919],{"class":1630},[747,43791,3246],{"class":802},[747,43793,5902],{"class":802},[747,43795,43796],{"class":802}," database\n",[747,43798,43799],{"class":749,"line":761},[747,43800,43801],{"class":1630},"database\n",[6072,43803,43804,43808],{},[523,43805,43806],{},[584,43807,6189],{},[523,43809,43810],{},"On success it will print out the name of the container(s) stopped.",[3126,43812,43814],{"id":43813},"how-do-i-save-the-database-data-outside-the-container","How do I save the database data outside the container?",[523,43816,43817,43818,5845,43820,43822],{},"You want to save your data outside of the container, for a simple reason: If you stop and delete the container, your data is gone. For this Docker has volumes.\nA Volume is like a mount from the host system inside the container.\nThe volume flag is ",[567,43819,6113],{},[567,43821,6116],{},"). The syntax of the volume flag is for example:",[738,43824,43826],{"className":1621,"code":43825,"language":1623,"meta":743,"style":743},"docker run \\\n[...]\n    -v HOST_PATH:CONTAINER_PATH:MODE \\\n[...]\n",[567,43827,43828,43836,43840,43849],{"__ignoreMap":743},[747,43829,43830,43832,43834],{"class":749,"line":750},[747,43831,3257],{"class":1630},[747,43833,3665],{"class":802},[747,43835,1641],{"class":1640},[747,43837,43838],{"class":749,"line":761},[747,43839,5986],{"class":1640},[747,43841,43842,43844,43847],{"class":749,"line":769},[747,43843,6139],{"class":1630},[747,43845,43846],{"class":802}," HOST_PATH:CONTAINER_PATH:MODE",[747,43848,1641],{"class":1640},[747,43850,43851],{"class":749,"line":776},[747,43852,5986],{"class":1640},[6072,43854,43855],{},[523,43856,43857],{},[584,43858,2957],{},[668,43860,43861,43865,43869],{},[638,43862,43863,6162],{},[567,43864,6161],{},[638,43866,43867,6168],{},[567,43868,6167],{},[638,43870,43871,43873,43874,43876,43877,43879,43880,18054,43883,43886,43887,1909],{},[567,43872,6173],{}," - Optional. Can be ",[567,43875,6177],{}," (read-write), ",[567,43878,6181],{}," (read-only), ",[567,43881,43882],{},"z",[567,43884,43885],{},"Z"," cause files to be SELinux relabeled on the path. Default is ",[567,43888,6177],{},[6072,43890,43891],{},[523,43892,43893],{},[584,43894,6189],{},[668,43896,43897,43899,43901],{},[638,43898,6194],{},[638,43900,6197],{},[638,43902,6200],{},[3126,43904,43906],{"id":43905},"running-the-mariadb-database-server-container","Running the MariaDB database server container",[523,43908,43909],{},"Now we have all components, we need for running the MariaDB container.",[523,43911,6210],{},[738,43913,43915],{"className":1621,"code":43914,"language":1623,"meta":743,"style":743},"docker run \\\n    -d \\\n    --name=database \\\n    -e 'MYSQL_USER=wordpress' \\\n    -e 'MYSQL_PASSWORD=wordpress' \\\n    -e 'MYSQL_DATABASE=wordpress' \\\n    -e 'MYSQL_ROOT_PASSWORD=secure_password' \\\n    -e 'MYSQL_ROOT_HOST=%' \\\n    -v \u002Fopt\u002Fdocker\u002Fwordpress\u002Fmysql:\u002Fvar\u002Flib\u002Fmysql \\\n    mariadb:10.4.3-bionic\n",[567,43916,43917,43925,43931,43937,43949,43961,43973,43985,43997,44005],{"__ignoreMap":743},[747,43918,43919,43921,43923],{"class":749,"line":750},[747,43920,3257],{"class":1630},[747,43922,3665],{"class":802},[747,43924,1641],{"class":1640},[747,43926,43927,43929],{"class":749,"line":761},[747,43928,5866],{"class":802},[747,43930,1641],{"class":1640},[747,43932,43933,43935],{"class":749,"line":769},[747,43934,43560],{"class":802},[747,43936,1641],{"class":1640},[747,43938,43939,43941,43943,43945,43947],{"class":749,"line":776},[747,43940,5991],{"class":802},[747,43942,3537],{"class":757},[747,43944,6009],{"class":802},[747,43946,3543],{"class":757},[747,43948,1641],{"class":1640},[747,43950,43951,43953,43955,43957,43959],{"class":749,"line":784},[747,43952,5991],{"class":802},[747,43954,3537],{"class":757},[747,43956,6022],{"class":802},[747,43958,3543],{"class":757},[747,43960,1641],{"class":1640},[747,43962,43963,43965,43967,43969,43971],{"class":749,"line":790},[747,43964,5991],{"class":802},[747,43966,3537],{"class":757},[747,43968,5996],{"class":802},[747,43970,3543],{"class":757},[747,43972,1641],{"class":1640},[747,43974,43975,43977,43979,43981,43983],{"class":749,"line":796},[747,43976,5991],{"class":802},[747,43978,3537],{"class":757},[747,43980,43698],{"class":802},[747,43982,3543],{"class":757},[747,43984,1641],{"class":1640},[747,43986,43987,43989,43991,43993,43995],{"class":749,"line":806},[747,43988,5991],{"class":802},[747,43990,3537],{"class":757},[747,43992,43711],{"class":802},[747,43994,3543],{"class":757},[747,43996,1641],{"class":1640},[747,43998,43999,44001,44003],{"class":749,"line":814},[747,44000,6139],{"class":802},[747,44002,6293],{"class":802},[747,44004,1641],{"class":1640},[747,44006,44007],{"class":749,"line":822},[747,44008,43567],{"class":802},[6072,44010,44011],{},[523,44012,44013],{},[584,44014,2957],{},[668,44016,44017,44021,44026,44034,44043],{},[638,44018,44019,6310],{},[567,44020,5841],{},[638,44022,44023,6316],{},[567,44024,44025],{},"--name=wordpress",[638,44027,44028,44030,44031,1909],{},[567,44029,6321],{}," - Specify each an environment variables to be added to the container, as seen in ",[527,44032,43577],{"href":44033},"#how-would-one-configure-the-mariadb-database-server-container",[638,44035,44036,6328,44038,44040,44041,1909],{},[567,44037,6327],{},[567,44039,6331],{}," directory of the host to inside the container at ",[567,44042,6335],{},[638,44044,44045,6341],{},[567,44046,43149],{},[523,44048,6344,44049,5845,44051,6349,44053,6353,44055,6356],{},[567,44050,5812],{},[567,44052,5841],{},[567,44054,6352],{},[567,44056,4188],{},[613,44058,44060],{"id":44059},"how-do-you-execute-a-command-get-a-shell-inside-a-container","How do you execute a command\u002F get a shell inside a container?",[523,44062,44063,44064,44066,44067,7026],{},"Let's check the MariaDB server if the wanted ",[567,44065,6725],{}," database has been created. For that we need to execute a command inside the ",[567,44068,6815],{},[523,44070,44071,44072,44074],{},"To execute a command inside a container, for example in the MariaDB ",[567,44073,6815],{}," container for, e.g., maintenance access.",[523,44076,44077,44078,44080,44081,44084],{},"The following ",[567,44079,6744],{}," command will execute the ",[567,44082,44083],{},"SHOW DATAbASE"," query which lists the existing databases:",[738,44086,44087],{"className":1621,"code":7080,"language":1623,"meta":743,"style":743},[567,44088,44089],{"__ignoreMap":743},[747,44090,44091,44093,44095,44097,44099,44101,44103,44105],{"class":749,"line":750},[747,44092,6744],{"class":1630},[747,44094,7089],{"class":802},[747,44096,5149],{"class":802},[747,44098,7094],{"class":802},[747,44100,7097],{"class":802},[747,44102,969],{"class":757},[747,44104,7102],{"class":802},[747,44106,975],{"class":757},[523,44108,44109,44110,44112],{},"The command ",[567,44111,7110],{}," can be used to execute a separate command inside a container.",[523,44114,44115,44116,44118],{},"Running ",[567,44117,7120],{}," will shows the help menu:",[6072,44120,44121],{},[523,44122,44123],{},[584,44124,44125],{},"EXAMPLE",[738,44127,44129],{"className":1621,"code":44128,"language":1623,"meta":743,"style":743},"$ docker exec --help\n\nUsage:  docker exec [OPTIONS] CONTAINER COMMAND [ARG...]\n\nRun a command in a running container\n\nOptions:\n  -d, --detach               Detached mode: run command in the background\n      --detach-keys string   Override the key sequence for detaching a container\n  -e, --env list             Set environment variables\n  -i, --interactive          Keep STDIN open even if not attached\n      --privileged           Give extended privileges to the command\n  -t, --tty                  Allocate a pseudo-TTY\n  -u, --user string          Username or UID (format: \u003Cname|uid>[:\u003Cgroup|gid>])\n  -w, --workdir string       Working directory inside the container\n",[567,44130,44131,44141,44145,44162,44166,44182,44186,44190,44213,44236,44251,44272,44290,44303,44346],{"__ignoreMap":743},[747,44132,44133,44135,44137,44139],{"class":749,"line":750},[747,44134,1919],{"class":1630},[747,44136,3246],{"class":802},[747,44138,2586],{"class":802},[747,44140,4218],{"class":802},[747,44142,44143],{"class":749,"line":761},[747,44144,1255],{"emptyLinePlaceholder":1254},[747,44146,44147,44149,44151,44153,44156,44158,44160],{"class":749,"line":769},[747,44148,4242],{"class":1630},[747,44150,4245],{"class":802},[747,44152,2586],{"class":802},[747,44154,44155],{"class":1640}," [OPTIONS] CONTAINER COMMAND ",[747,44157,4253],{"class":757},[747,44159,4265],{"class":1640},[747,44161,4268],{"class":757},[747,44163,44164],{"class":749,"line":776},[747,44165,1255],{"emptyLinePlaceholder":1254},[747,44167,44168,44170,44172,44174,44176,44178,44180],{"class":749,"line":784},[747,44169,36678],{"class":1630},[747,44171,3930],{"class":802},[747,44173,33312],{"class":802},[747,44175,4584],{"class":802},[747,44177,3930],{"class":802},[747,44179,36742],{"class":802},[747,44181,4538],{"class":802},[747,44183,44184],{"class":749,"line":790},[747,44185,1255],{"emptyLinePlaceholder":1254},[747,44187,44188],{"class":749,"line":796},[747,44189,4326],{"class":1630},[747,44191,44192,44194,44196,44199,44202,44204,44206,44208,44210],{"class":749,"line":806},[747,44193,41733],{"class":1630},[747,44195,41736],{"class":802},[747,44197,44198],{"class":802},"               Detached",[747,44200,44201],{"class":802}," mode:",[747,44203,3665],{"class":802},[747,44205,33312],{"class":802},[747,44207,4584],{"class":802},[747,44209,3839],{"class":802},[747,44211,44212],{"class":802}," background\n",[747,44214,44215,44217,44219,44222,44224,44226,44228,44230,44232,44234],{"class":749,"line":814},[747,44216,41760],{"class":1630},[747,44218,4522],{"class":802},[747,44220,44221],{"class":802},"   Override",[747,44223,3839],{"class":802},[747,44225,41770],{"class":802},[747,44227,41773],{"class":802},[747,44229,3761],{"class":802},[747,44231,41778],{"class":802},[747,44233,3930],{"class":802},[747,44235,4538],{"class":802},[747,44237,44238,44240,44242,44244,44247,44249],{"class":749,"line":822},[747,44239,42044],{"class":1630},[747,44241,42047],{"class":802},[747,44243,4334],{"class":802},[747,44245,44246],{"class":802},"             Set",[747,44248,42054],{"class":802},[747,44250,42057],{"class":802},[747,44252,44253,44255,44257,44260,44262,44264,44266,44268,44270],{"class":749,"line":830},[747,44254,42390],{"class":1630},[747,44256,42393],{"class":802},[747,44258,44259],{"class":802},"          Keep",[747,44261,42399],{"class":802},[747,44263,42402],{"class":802},[747,44265,42405],{"class":802},[747,44267,5062],{"class":802},[747,44269,37708],{"class":802},[747,44271,42412],{"class":802},[747,44273,44274,44276,44279,44281,44283,44285,44287],{"class":749,"line":836},[747,44275,5080],{"class":1630},[747,44277,44278],{"class":802},"           Give",[747,44280,5086],{"class":802},[747,44282,5089],{"class":802},[747,44284,3696],{"class":802},[747,44286,3839],{"class":802},[747,44288,44289],{"class":802}," command\n",[747,44291,44292,44294,44296,44299,44301],{"class":749,"line":842},[747,44293,5416],{"class":1630},[747,44295,5419],{"class":802},[747,44297,44298],{"class":802},"                  Allocate",[747,44300,3930],{"class":802},[747,44302,5427],{"class":802},[747,44304,44305,44307,44309,44311,44314,44316,44318,44320,44322,44324,44326,44328,44330,44332,44334,44336,44338,44340,44342,44344],{"class":749,"line":850},[747,44306,5450],{"class":1630},[747,44308,5453],{"class":802},[747,44310,4522],{"class":802},[747,44312,44313],{"class":802},"          Username",[747,44315,4423],{"class":802},[747,44317,5463],{"class":802},[747,44319,5466],{"class":1640},[747,44321,5469],{"class":757},[747,44323,5472],{"class":802},[747,44325,3616],{"class":757},[747,44327,5477],{"class":1630},[747,44329,2035],{"class":1640},[747,44331,4253],{"class":802},[747,44333,856],{"class":4574},[747,44335,5486],{"class":1640},[747,44337,3616],{"class":757},[747,44339,5491],{"class":1630},[747,44341,2035],{"class":1640},[747,44343,4259],{"class":802},[747,44345,3600],{"class":1640},[747,44347,44348,44350,44352,44354,44357,44359,44361,44363],{"class":749,"line":863},[747,44349,5609],{"class":1630},[747,44351,5612],{"class":802},[747,44353,4522],{"class":802},[747,44355,44356],{"class":802},"       Working",[747,44358,5620],{"class":802},[747,44360,5623],{"class":802},[747,44362,3839],{"class":802},[747,44364,4538],{"class":802},[523,44366,44367],{},"To run a command interactively for example opening an interactive MariaDB shell session, the command would be:",[738,44369,44371],{"className":1621,"code":44370,"language":1623,"meta":743,"style":743},"docker exec \\\n    -it \\\n    CONTAINER \\\n    mysql -u root -p -e \"SHOW DATABASES;\"\n",[567,44372,44373,44381,44387,44393],{"__ignoreMap":743},[747,44374,44375,44377,44379],{"class":749,"line":750},[747,44376,3257],{"class":1630},[747,44378,2586],{"class":802},[747,44380,1641],{"class":1640},[747,44382,44383,44385],{"class":749,"line":761},[747,44384,7152],{"class":802},[747,44386,1641],{"class":1640},[747,44388,44389,44391],{"class":749,"line":769},[747,44390,7159],{"class":802},[747,44392,1641],{"class":1640},[747,44394,44395,44397,44399,44401,44403,44405,44407,44409],{"class":749,"line":776},[747,44396,7166],{"class":802},[747,44398,7089],{"class":802},[747,44400,5149],{"class":802},[747,44402,7094],{"class":802},[747,44404,7097],{"class":802},[747,44406,969],{"class":757},[747,44408,7102],{"class":802},[747,44410,975],{"class":757},[6072,44412,44413],{},[523,44414,44415],{},[584,44416,2957],{},[668,44418,44419,44424,44429,44433],{},[638,44420,44421,44423],{},[567,44422,7184],{}," - Attach the stdin aka \"interactive mode\".",[638,44425,44426,44428],{},[567,44427,7190],{}," - Optional. Allocate a pseudo-TTY (pseudo TeleTYpewriter) to the shell\u002F command run.",[638,44430,44431,7196],{},[567,44432,4188],{},[638,44434,44435,44437],{},[567,44436,7201],{}," - The command and arguments for the command to execute inside the container.",[523,44439,44440,44441,5845,44443,44445],{},"You can also use the ",[567,44442,5812],{},[567,44444,5841],{},") option to exec the command non-interactively inside the container with no logs or exit code).",[523,44447,44448,44449,44451,44452,44455],{},"When running the above ",[567,44450,7110],{}," command, be sure to enter the MySQL ",[567,44453,44454],{},"root"," user password when prompted for it.",[6072,44457,44458,44462],{},[523,44459,44460],{},[584,44461,6189],{},[523,44463,44464,44465,44467],{},"To be able to run a command in the container, the command\u002F binary\u002F file has to exist in the container! Also to note that when the command\u002F binary is not in the containers ",[567,44466,3326],{},", you must give the full absolute path to it.",[613,44469,44471],{"id":44470},"summary-of-what-we-did-so-far","Summary of what we did so far",[523,44473,44474,44475,44477,44478,44480,44481,1909],{},"We now have a MariaDB 10.4.3 container running which is configured to create a database named ",[567,44476,6725],{}," with a user named ",[567,44479,6725],{}," and password ",[567,44482,6725],{},[523,44484,44485],{},"Now we are going to move on to create the WordPress container which will use the database container.",[2979,44487],{},[613,44489,44491],{"id":44490},"starting-the-wordpress-container","Starting the WordPress container",[523,44493,6363],{},[3126,44495,44497],{"id":44496},"how-can-the-wordpress-container-and-the-mariadb-container-communicate-with-each-other","How can the WordPress container and the MariaDB container communicate with each other?",[523,44499,44500,44504,44505,550,44510,2006],{},[3069,44501],{"alt":44502,"src":44503},"Got network communication for your containers?","\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day1\u002Fnetwork-cat5-cat6-internet.png","\n(Original photo taken from ",[527,44506,44509],{"href":44507,"rel":44508},"https:\u002F\u002Fwww.pexels.com\u002Fphoto\u002Fcat5-cat6-internet-network-807540\u002F",[531],"pexels.com - Free stock photo site",[527,44511,44514],{"href":44512,"rel":44513},"https:\u002F\u002Fwww.pexels.com\u002F@promote365-xyz-266925\u002F",[531],"Promote365 .xyz",[523,44516,44517],{},"In Docker in general by default all containers can talk to each other, if they know the IP address.",[6072,44519,44520],{},[523,44521,44522,44524,44525,6378,44527,19348,44529,44532,44533,44535],{},[584,44523,6189],{}," There is an option for the Docker daemon that is called ",[567,44526,6377],{},[567,44528,6373],{},[567,44530,44531],{},"--icc=[true\u002Ffalse]",", default ",[567,44534,5306],{},", but disabling this may have other implications than just stopping ICC communication too.",[523,44537,44538,44539,6353,44541,44543,44544,44547,44548,3052],{},"So now to make sure the WordPress container can talk to the MariaDB container, we could use the IP address of the MariaDB container. To get the IP address of the container we can use ",[567,44540,6385],{},[567,44542,6388],{}," is the unique ID or name of the container). ",[567,44545,44546],{},"docker inspect"," command will return a JSON output with \"all\" informations about the given container(s), but is also working for Docker containers image(s) (",[567,44549,10064],{},[523,44551,44552],{},"But it would be too much work to keep the IP address up to date, when the container gets a new IP address! That is where the \"Docker Networking\" feature comes into play.",[523,44554,44555,44556,28768],{},"So to be able to use this Docker Networking feature, we need to create a network for the application containers.\nThis can be done using ",[567,44557,44558],{},"docker network create",[738,44560,44562],{"className":1621,"code":44561,"language":1623,"meta":743,"style":743},"docker network \\\n    create \\\n    [OPTIONS] \\\n    [NETWORK_NAME]\n",[567,44563,44564,44572,44578,44583],{"__ignoreMap":743},[747,44565,44566,44568,44570],{"class":749,"line":750},[747,44567,3257],{"class":1630},[747,44569,36666],{"class":802},[747,44571,1641],{"class":1640},[747,44573,44574,44576],{"class":749,"line":761},[747,44575,38696],{"class":802},[747,44577,1641],{"class":1640},[747,44579,44580],{"class":749,"line":769},[747,44581,44582],{"class":1640},"    [OPTIONS] \\\n",[747,44584,44585,44587,44590],{"class":749,"line":776},[747,44586,35563],{"class":757},[747,44588,44589],{"class":1640},"NETWORK_NAME",[747,44591,4268],{"class":757},[6072,44593,44594],{},[523,44595,44596],{},[584,44597,2957],{},[668,44599,44600,44607],{},[638,44601,44602,44604,44605,11295],{},[567,44603,38965],{}," - Options for the ",[567,44606,44558],{},[638,44608,44609,44611],{},[567,44610,44589],{}," - The name of the network to be created.",[523,44613,44614],{},"Running the following command, will create a new network in Docker which means there is a new network device on the server created too:",[738,44616,44618],{"className":1621,"code":44617,"language":1623,"meta":743,"style":743},"docker network \\\n    create \\\n    wordpress\n",[567,44619,44620,44628,44634],{"__ignoreMap":743},[747,44621,44622,44624,44626],{"class":749,"line":750},[747,44623,3257],{"class":1630},[747,44625,36666],{"class":802},[747,44627,1641],{"class":1640},[747,44629,44630,44632],{"class":749,"line":761},[747,44631,38696],{"class":802},[747,44633,1641],{"class":1640},[747,44635,44636],{"class":749,"line":769},[747,44637,6510],{"class":802},[523,44639,44640],{},"This new network device can be seen in the output below:",[6072,44642,44643],{},[523,44644,44645],{},[584,44646,44125],{},[738,44648,44650],{"className":1621,"code":44649,"language":1623,"meta":743,"style":743},"$ docker network create wordpress\n4cc4efd905ff369efdf691dfe9d20c7c55775e628ccb57cc3fdac499785ea05b\n$ ip addr show\n1: lo: \u003CLOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000\n    link\u002Floopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n    inet 127.0.0.1\u002F8 scope host lo\n       valid_lft forever preferred_lft forever\n    inet6 ::1\u002F128 scope host\n       valid_lft forever preferred_lft forever\n2: enp4s0: \u003CBROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000\n[...]\n3: docker0: \u003CNO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default\n    link\u002Fether 02:42:d1:cc:07:47 brd ff:ff:ff:ff:ff:ff\n    inet 172.17.0.1\u002F16 brd 172.17.255.255 scope global docker0\n       valid_lft forever preferred_lft forever\n    inet6 fe80::42:d1ff:fecc:747\u002F64 scope link\n       valid_lft forever preferred_lft forever\n4: br-4cc4efd905ff: \u003CNO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default\n    link\u002Fether 02:42:90:e4:8d:a1 brd ff:ff:ff:ff:ff:ff\n    inet 172.18.0.1\u002F16 brd 172.18.255.255 scope global br-4cc4efd905ff\n       valid_lft forever preferred_lft forever\n",[567,44651,44652,44664,44669,44680,44714,44724,44736,44746,44756,44766,44802,44810,44843,44854,44870,44880,44892,44902,44934,44945,44964],{"__ignoreMap":743},[747,44653,44654,44656,44658,44660,44662],{"class":749,"line":750},[747,44655,1919],{"class":1630},[747,44657,3246],{"class":802},[747,44659,36666],{"class":802},[747,44661,1925],{"class":802},[747,44663,6540],{"class":802},[747,44665,44666],{"class":749,"line":761},[747,44667,44668],{"class":1630},"4cc4efd905ff369efdf691dfe9d20c7c55775e628ccb57cc3fdac499785ea05b\n",[747,44670,44671,44673,44675,44678],{"class":749,"line":769},[747,44672,1919],{"class":1630},[747,44674,7535],{"class":802},[747,44676,44677],{"class":802}," addr",[747,44679,7541],{"class":802},[747,44681,44682,44684,44686,44688,44690,44692,44694,44696,44698,44700,44702,44704,44706,44708,44710,44712],{"class":749,"line":776},[747,44683,7546],{"class":1630},[747,44685,7549],{"class":802},[747,44687,7552],{"class":757},[747,44689,7555],{"class":802},[747,44691,7558],{"class":1640},[747,44693,2035],{"class":757},[747,44695,7563],{"class":802},[747,44697,7566],{"class":1895},[747,44699,7569],{"class":802},[747,44701,7572],{"class":802},[747,44703,7575],{"class":802},[747,44705,7578],{"class":802},[747,44707,7581],{"class":802},[747,44709,1931],{"class":802},[747,44711,7586],{"class":802},[747,44713,7589],{"class":1895},[747,44715,44716,44718,44720,44722],{"class":749,"line":784},[747,44717,7594],{"class":1630},[747,44719,7597],{"class":802},[747,44721,7600],{"class":802},[747,44723,7603],{"class":802},[747,44725,44726,44728,44730,44732,44734],{"class":749,"line":790},[747,44727,7608],{"class":1630},[747,44729,7611],{"class":802},[747,44731,7614],{"class":802},[747,44733,4591],{"class":802},[747,44735,7619],{"class":802},[747,44737,44738,44740,44742,44744],{"class":749,"line":796},[747,44739,7624],{"class":1630},[747,44741,7627],{"class":802},[747,44743,7630],{"class":802},[747,44745,7633],{"class":802},[747,44747,44748,44750,44752,44754],{"class":749,"line":806},[747,44749,7638],{"class":1630},[747,44751,7641],{"class":802},[747,44753,7614],{"class":802},[747,44755,42908],{"class":802},[747,44757,44758,44760,44762,44764],{"class":749,"line":814},[747,44759,7624],{"class":1630},[747,44761,7627],{"class":802},[747,44763,7630],{"class":802},[747,44765,7633],{"class":802},[747,44767,44768,44770,44773,44775,44777,44779,44781,44783,44785,44787,44790,44792,44794,44796,44798,44800],{"class":749,"line":822},[747,44769,7663],{"class":1630},[747,44771,44772],{"class":802}," enp4s0:",[747,44774,7552],{"class":757},[747,44776,7671],{"class":802},[747,44778,7558],{"class":1640},[747,44780,2035],{"class":757},[747,44782,7563],{"class":802},[747,44784,7680],{"class":1895},[747,44786,7569],{"class":802},[747,44788,44789],{"class":802}," fq_codel",[747,44791,7575],{"class":802},[747,44793,7690],{"class":802},[747,44795,7581],{"class":802},[747,44797,1931],{"class":802},[747,44799,7586],{"class":802},[747,44801,7589],{"class":1895},[747,44803,44804,44806,44808],{"class":749,"line":830},[747,44805,4253],{"class":757},[747,44807,5685],{"class":1640},[747,44809,4268],{"class":757},[747,44811,44812,44815,44817,44819,44822,44824,44826,44828,44830,44832,44834,44836,44839,44841],{"class":749,"line":836},[747,44813,44814],{"class":1630},"3:",[747,44816,7711],{"class":802},[747,44818,7552],{"class":757},[747,44820,44821],{"class":802},"NO-CARRIER,BROADCAST,MULTICAST,U",[747,44823,7558],{"class":1640},[747,44825,2035],{"class":757},[747,44827,7563],{"class":802},[747,44829,7680],{"class":1895},[747,44831,7569],{"class":802},[747,44833,7572],{"class":802},[747,44835,7575],{"class":802},[747,44837,44838],{"class":802}," DOWN",[747,44840,7581],{"class":802},[747,44842,7736],{"class":802},[747,44844,44845,44847,44850,44852],{"class":749,"line":842},[747,44846,7741],{"class":1630},[747,44848,44849],{"class":802}," 02:42:d1:cc:07:47",[747,44851,7600],{"class":802},[747,44853,7749],{"class":802},[747,44855,44856,44858,44860,44862,44864,44866,44868],{"class":749,"line":850},[747,44857,7608],{"class":1630},[747,44859,7756],{"class":802},[747,44861,7600],{"class":802},[747,44863,7761],{"class":1895},[747,44865,7614],{"class":802},[747,44867,7766],{"class":802},[747,44869,7769],{"class":802},[747,44871,44872,44874,44876,44878],{"class":749,"line":863},[747,44873,7624],{"class":1630},[747,44875,7627],{"class":802},[747,44877,7630],{"class":802},[747,44879,7633],{"class":802},[747,44881,44882,44884,44887,44889],{"class":749,"line":869},[747,44883,7638],{"class":1630},[747,44885,44886],{"class":802}," fe80::42:d1ff:fecc:747\u002F64",[747,44888,7614],{"class":802},[747,44890,44891],{"class":802}," link\n",[747,44893,44894,44896,44898,44900],{"class":749,"line":877},[747,44895,7624],{"class":1630},[747,44897,7627],{"class":802},[747,44899,7630],{"class":802},[747,44901,7633],{"class":802},[747,44903,44904,44907,44910,44912,44914,44916,44918,44920,44922,44924,44926,44928,44930,44932],{"class":749,"line":1015},[747,44905,44906],{"class":1630},"4:",[747,44908,44909],{"class":802}," br-4cc4efd905ff:",[747,44911,7552],{"class":757},[747,44913,44821],{"class":802},[747,44915,7558],{"class":1640},[747,44917,2035],{"class":757},[747,44919,7563],{"class":802},[747,44921,7680],{"class":1895},[747,44923,7569],{"class":802},[747,44925,7572],{"class":802},[747,44927,7575],{"class":802},[747,44929,44838],{"class":802},[747,44931,7581],{"class":802},[747,44933,7736],{"class":802},[747,44935,44936,44938,44941,44943],{"class":749,"line":1021},[747,44937,7741],{"class":1630},[747,44939,44940],{"class":802}," 02:42:90:e4:8d:a1",[747,44942,7600],{"class":802},[747,44944,7749],{"class":802},[747,44946,44947,44949,44952,44954,44957,44959,44961],{"class":749,"line":1027},[747,44948,7608],{"class":1630},[747,44950,44951],{"class":802}," 172.18.0.1\u002F16",[747,44953,7600],{"class":802},[747,44955,44956],{"class":1895}," 172.18.255.255",[747,44958,7614],{"class":802},[747,44960,7766],{"class":802},[747,44962,44963],{"class":802}," br-4cc4efd905ff\n",[747,44965,44966,44968,44970,44972],{"class":749,"line":1033},[747,44967,7624],{"class":1630},[747,44969,7627],{"class":802},[747,44971,7630],{"class":802},[747,44973,7633],{"class":802},[3126,44975,44977,44978,44980],{"id":44976},"network-resolvconf-and-hostnames","Network - ",[567,44979,32135],{}," and hostnames",[523,44982,44983,44984,44986,44987,44989,44990,44992],{},"As we are talking about network, let's take a quick look at the ",[567,44985,32135],{}," and hostnames.\nRunning the following commands will show you the ",[567,44988,32135],{}," and hostname of the container (output below the ",[584,44991,2957],{}," explanation):",[738,44994,44996],{"className":1621,"code":44995,"language":1623,"meta":743,"style":743},"$ docker run \\\n    -it \\\n    --rm \\\n    --entrypoint=\u002Fbin\u002Fbash \\\n    wordpress:5.1-php7.1-apache\n$ hostname\n$ cat \u002Fetc\u002Fhosts\n$ exit\n# The `--rm` flag takes care of removing the container then, so no need to manually delete the container\n",[567,44997,44998,45008,45014,45021,45027,45032,45039,45048,45054],{"__ignoreMap":743},[747,44999,45000,45002,45004,45006],{"class":749,"line":750},[747,45001,1919],{"class":1630},[747,45003,3246],{"class":802},[747,45005,3665],{"class":802},[747,45007,1641],{"class":1640},[747,45009,45010,45012],{"class":749,"line":761},[747,45011,7152],{"class":802},[747,45013,1641],{"class":1640},[747,45015,45016,45019],{"class":749,"line":769},[747,45017,45018],{"class":802},"    --rm",[747,45020,1641],{"class":1640},[747,45022,45023,45025],{"class":749,"line":776},[747,45024,6503],{"class":802},[747,45026,1641],{"class":1640},[747,45028,45029],{"class":749,"line":784},[747,45030,45031],{"class":802},"    wordpress:5.1-php7.1-apache\n",[747,45033,45034,45036],{"class":749,"line":790},[747,45035,1919],{"class":1630},[747,45037,45038],{"class":802}," hostname\n",[747,45040,45041,45043,45046],{"class":749,"line":796},[747,45042,1919],{"class":1630},[747,45044,45045],{"class":802}," cat",[747,45047,6518],{"class":802},[747,45049,45050,45052],{"class":749,"line":806},[747,45051,1919],{"class":1630},[747,45053,33643],{"class":802},[747,45055,45056],{"class":749,"line":814},[747,45057,45058],{"class":772},"# The `--rm` flag takes care of removing the container then, so no need to manually delete the container\n",[6072,45060,45061,45065],{},[523,45062,45063],{},[584,45064,2957],{},[668,45066,45067,45073],{},[638,45068,45069,45072],{},[567,45070,45071],{},"--rm"," - Causes the container to be deleted when stopped\u002F exited.",[638,45074,45075,45077],{},[567,45076,6551],{}," - This overwrites the command executed (as proccess number #1 in the container), when the container is started.",[738,45079,45081],{"className":1621,"code":45080,"language":1623,"meta":743,"style":743},"$ docker run \\\n    -it \\\n    --rm \\\n    --entrypoint=\u002Fbin\u002Fbash \\\n    wordpress:5.1-php7.1-apache\nroot@7c329dddc849:\u002Fvar\u002Fwww\u002Fhtml# hostname\n7c329dddc849\n",[567,45082,45083,45093,45099,45105,45111,45115,45122],{"__ignoreMap":743},[747,45084,45085,45087,45089,45091],{"class":749,"line":750},[747,45086,1919],{"class":1630},[747,45088,3246],{"class":802},[747,45090,3665],{"class":802},[747,45092,1641],{"class":1640},[747,45094,45095,45097],{"class":749,"line":761},[747,45096,7152],{"class":802},[747,45098,1641],{"class":1640},[747,45100,45101,45103],{"class":749,"line":769},[747,45102,45018],{"class":802},[747,45104,1641],{"class":1640},[747,45106,45107,45109],{"class":749,"line":776},[747,45108,6503],{"class":802},[747,45110,1641],{"class":1640},[747,45112,45113],{"class":749,"line":784},[747,45114,45031],{"class":802},[747,45116,45117,45120],{"class":749,"line":790},[747,45118,45119],{"class":1630},"root@7c329dddc849:\u002Fvar\u002Fwww\u002Fhtml#",[747,45121,45038],{"class":802},[747,45123,45124],{"class":749,"line":796},[747,45125,45126],{"class":1630},"7c329dddc849\n",[523,45128,45129,45130,45133,45134,18054,45136,45138],{},"Every container is getting a random hostname, you can override the hostname of a container using the ",[567,45131,45132],{},"--hostname=HOSTNAME"," flag for ",[567,45135,4203],{},[567,45137,43069],{},". As a general note your application should try to not rely on the hostname too much, that can also be important for later on with Kubernetes.",[738,45140,45142],{"className":1621,"code":45141,"language":1623,"meta":743,"style":743},"root@7c329dddc849:\u002Fvar\u002Fwww\u002Fhtml# cat \u002Fetc\u002Fresolv.conf\n# Generated by NetworkManager\nsearch lan\nnameserver 172.16.1.1\n",[567,45143,45144,45153,45158,45165],{"__ignoreMap":743},[747,45145,45146,45148,45150],{"class":749,"line":750},[747,45147,45119],{"class":1630},[747,45149,45045],{"class":802},[747,45151,45152],{"class":802}," \u002Fetc\u002Fresolv.conf\n",[747,45154,45155],{"class":749,"line":761},[747,45156,45157],{"class":772},"# Generated by NetworkManager\n",[747,45159,45160,45162],{"class":749,"line":769},[747,45161,32131],{"class":1630},[747,45163,45164],{"class":802}," lan\n",[747,45166,45167,45170],{"class":749,"line":776},[747,45168,45169],{"class":1630},"nameserver",[747,45171,45172],{"class":1895}," 172.16.1.1\n",[523,45174,8764,45175,45177,45178,45181,45182,45185],{},[567,45176,32135],{}," is partially passed through from the host system. Meaning that in this example ",[567,45179,45180],{},"172.16.1.1"," is the address of the local nameserver I'm using (",[567,45183,45184],{},"172.16.1.1\u002F24"," is the network range the host is in).",[738,45187,45189],{"className":1621,"code":45188,"language":1623,"meta":743,"style":743},"root@7c329dddc849:\u002Fvar\u002Fwww\u002Fhtml# cat \u002Fetc\u002Fhosts\n127.0.0.1   localhost\n::1 localhost ip6-localhost ip6-loopback\nfe00::0 ip6-localnet\nff00::0 ip6-mcastprefix\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n172.17.0.3  7c329dddc849\nroot@7c329dddc849:\u002Fvar\u002Fwww\u002Fhtml# exit\n",[567,45190,45191,45199,45207,45223,45231,45239,45247,45255,45263],{"__ignoreMap":743},[747,45192,45193,45195,45197],{"class":749,"line":750},[747,45194,45119],{"class":1630},[747,45196,45045],{"class":802},[747,45198,6518],{"class":802},[747,45200,45201,45204],{"class":749,"line":761},[747,45202,45203],{"class":1630},"127.0.0.1",[747,45205,45206],{"class":802},"   localhost\n",[747,45208,45209,45211,45214,45217,45220],{"class":749,"line":769},[747,45210,856],{"class":4574},[747,45212,45213],{"class":802},":1",[747,45215,45216],{"class":802}," localhost",[747,45218,45219],{"class":802}," ip6-localhost",[747,45221,45222],{"class":802}," ip6-loopback\n",[747,45224,45225,45228],{"class":749,"line":776},[747,45226,45227],{"class":1630},"fe00::0",[747,45229,45230],{"class":802}," ip6-localnet\n",[747,45232,45233,45236],{"class":749,"line":784},[747,45234,45235],{"class":1630},"ff00::0",[747,45237,45238],{"class":802}," ip6-mcastprefix\n",[747,45240,45241,45244],{"class":749,"line":790},[747,45242,45243],{"class":1630},"ff02::1",[747,45245,45246],{"class":802}," ip6-allnodes\n",[747,45248,45249,45252],{"class":749,"line":796},[747,45250,45251],{"class":1630},"ff02::2",[747,45253,45254],{"class":802}," ip6-allrouters\n",[747,45256,45257,45260],{"class":749,"line":806},[747,45258,45259],{"class":1630},"172.17.0.3",[747,45261,45262],{"class":802},"  7c329dddc849\n",[747,45264,45265,45267],{"class":749,"line":814},[747,45266,45119],{"class":1630},[747,45268,33643],{"class":802},[523,45270,8764,45271,45273,45274,45276],{},[567,45272,6459],{}," file is generated per container and has the hostname of the container as an entry in it. As we can see the hostname does not resolve to ",[567,45275,45203],{},", where everyone feels at home, but to the IP of the container (depending on who you ask this is good or bad, to be left uncommented).",[3126,45278,45280,45281,36666],{"id":45279},"lets-connect-the-database-container-to-the-wordpress-network","Let's connect the database container to the ",[567,45282,6725],{},[523,45284,45285,45286,45288],{},"There are two choices to connect the database container to the ",[567,45287,6725],{}," network:",[668,45290,45291],{},[638,45292,45293,45294,45297,45298,28768],{},"Stop, delete and create the database container again but now with the ",[567,45295,45296],{},"--net=wordpress"," flag added to the ",[567,45299,4203],{},[738,45301,45303],{"className":1621,"code":45302,"language":1623,"meta":743,"style":743},"docker run \\\n    -d \\\n    --net=wordpress \\\n    --name=database \\\n    -e 'MYSQL_ROOT_PASSWORD=secure_password' \\\n    -e 'MYSQL_USER=wordpress' \\\n    -e 'MYSQL_PASSWORD=wordpress' \\\n    -e 'MYSQL_DATABASE=wordpress' \\\n    -v \u002Fopt\u002Fdocker\u002Fwordpress\u002Fmysql:\u002Fvar\u002Flib\u002Fmysql \\\n    mariadb:10.4.3-bionic\n",[567,45304,45305,45313,45319,45326,45332,45344,45356,45368,45380,45388],{"__ignoreMap":743},[747,45306,45307,45309,45311],{"class":749,"line":750},[747,45308,3257],{"class":1630},[747,45310,3665],{"class":802},[747,45312,1641],{"class":1640},[747,45314,45315,45317],{"class":749,"line":761},[747,45316,5866],{"class":802},[747,45318,1641],{"class":1640},[747,45320,45321,45324],{"class":749,"line":769},[747,45322,45323],{"class":802},"    --net=wordpress",[747,45325,1641],{"class":1640},[747,45327,45328,45330],{"class":749,"line":776},[747,45329,43560],{"class":802},[747,45331,1641],{"class":1640},[747,45333,45334,45336,45338,45340,45342],{"class":749,"line":784},[747,45335,5991],{"class":802},[747,45337,3537],{"class":757},[747,45339,43698],{"class":802},[747,45341,3543],{"class":757},[747,45343,1641],{"class":1640},[747,45345,45346,45348,45350,45352,45354],{"class":749,"line":790},[747,45347,5991],{"class":802},[747,45349,3537],{"class":757},[747,45351,6009],{"class":802},[747,45353,3543],{"class":757},[747,45355,1641],{"class":1640},[747,45357,45358,45360,45362,45364,45366],{"class":749,"line":796},[747,45359,5991],{"class":802},[747,45361,3537],{"class":757},[747,45363,6022],{"class":802},[747,45365,3543],{"class":757},[747,45367,1641],{"class":1640},[747,45369,45370,45372,45374,45376,45378],{"class":749,"line":806},[747,45371,5991],{"class":802},[747,45373,3537],{"class":757},[747,45375,5996],{"class":802},[747,45377,3543],{"class":757},[747,45379,1641],{"class":1640},[747,45381,45382,45384,45386],{"class":749,"line":814},[747,45383,6139],{"class":802},[747,45385,6293],{"class":802},[747,45387,1641],{"class":1640},[747,45389,45390],{"class":749,"line":822},[747,45391,43567],{"class":802},[668,45393,45394],{},[638,45395,45396,45397,28768],{},"Use the ",[567,45398,45399],{},"docker network connect",[738,45401,45403],{"className":1621,"code":45402,"language":1623,"meta":743,"style":743},"docker network connect [NETWORK_NAME] [CONTAINER_NAME]\n",[567,45404,45405],{"__ignoreMap":743},[747,45406,45407,45409,45411,45414,45417,45419,45421],{"class":749,"line":750},[747,45408,3257],{"class":1630},[747,45410,36666],{"class":802},[747,45412,45413],{"class":802}," connect",[747,45415,45416],{"class":1640}," [NETWORK_NAME] ",[747,45418,4253],{"class":757},[747,45420,6446],{"class":1640},[747,45422,4268],{"class":757},[523,45424,45425],{},"In this case that would be:",[738,45427,45429],{"className":1621,"code":45428,"language":1623,"meta":743,"style":743},"docker network connect wordpress database\n",[567,45430,45431],{"__ignoreMap":743},[747,45432,45433,45435,45437,45439,45441],{"class":749,"line":750},[747,45434,3257],{"class":1630},[747,45436,36666],{"class":802},[747,45438,45413],{"class":802},[747,45440,6842],{"class":802},[747,45442,43796],{"class":802},[523,45444,45445,45446,45448,45449,45451],{},"The command connects the ",[567,45447,6815],{}," container to the ",[567,45450,6725],{}," network, that we previously created.",[523,45453,45454,45455,45457,45458,45460],{},"Now that the ",[567,45456,6815],{}," container is in the ",[567,45459,6725],{}," network, we can go ahead and begin to start the WordPress instance.",[3126,45462,45464],{"id":45463},"running-the-wordpress-container","Running the WordPress container",[523,45466,45467,45468,6378,45470,45474,45475,1909],{},"To configure our WordPress container, the Container image comes with extra environment variables.\nThe WordPress container image name is ",[567,45469,6725],{},[527,45471,45473],{"href":6728,"rel":45472},[531],"Docker Hub - WordPress Image",") and the tag for now is ",[567,45476,45477],{},"5.1-php7.1-apache",[523,45479,6733],{},[668,45481,45482,45493,45506,45521,45536,45560],{},[638,45483,45484,45487,45488,45490,45491,7026],{},[567,45485,45486],{},"WORDPRESS_DB_HOST=..."," - Set to ",[567,45489,6815],{}," so it will connect to the ",[567,45492,6815],{},[638,45494,45495,45487,45498,45500,45501,45503,45504,1909],{},[567,45496,45497],{},"WORDPRESS_DB_USER=...",[567,45499,6725],{}," as we have configured the ",[567,45502,6815],{}," container to create a user with name ",[567,45505,6725],{},[638,45507,45508,45487,45511,45500,45513,45515,45516,45518,45519,1909],{},[567,45509,45510],{},"WORDPRESS_DB_PASSWORD=...",[567,45512,6725],{},[567,45514,6815],{}," container to create the ",[567,45517,6725],{}," user with password ",[567,45520,6725],{},[638,45522,45523,45487,45526,45500,45528,45530,45531,26767,45533,45535],{},[567,45524,45525],{},"WORDPRESS_MYSQL_DATABASE=...",[567,45527,6725],{},[567,45529,6815],{}," container to create a database ",[567,45532,6725],{},[567,45534,6725],{}," user.",[638,45537,45538,714,45541,714,45544,714,45547,714,45550,714,45553,714,45556,45559],{},[567,45539,45540],{},"WORDPRESS_AUTH_KEY=...",[567,45542,45543],{},"WORDPRESS_SECURE_AUTH_KEY=...",[567,45545,45546],{},"WORDPRESS_LOGGED_IN_KEY=...",[567,45548,45549],{},"WORDPRESS_NONCE_KEY=...",[567,45551,45552],{},"WORDPRESS_AUTH_SALT=...",[567,45554,45555],{},"WORDPRESS_SECURE_AUTH_SALT=...",[567,45557,45558],{},"WORDPRESS_LOGGED_IN_SALT"," - These need to be set to a secure random value; in production use different random values per variable.",[638,45561,45562],{},"And other ones which are \"optional\" in regards to getting the WordPress container up'n'running.",[523,45564,45565],{},"The command to run the WordPress container should look like this now:",[738,45567,45569],{"className":1621,"code":45568,"language":1623,"meta":743,"style":743},"docker run \\\n    -d \\\n    --net=wordpress \\\n    --name=wordpress \\\n    -e 'WORDPRESS_DB_HOST=database' \\\n    -e 'WORDPRESS_DB_USER=wordpress' \\\n    -e 'WORDPRESS_DB_PASSWORD=wordpress' \\\n    -e 'WORDPRESS_AUTH_KEY=wordpress' \\\n    -e 'WORDPRESS_SECURE_AUTH_KEY=wordpress' \\\n    -e 'WORDPRESS_LOGGED_IN_KEY=wordpress' \\\n    -e 'WORDPRESS_NONCE_KEY=wordpress' \\\n    -e 'WORDPRESS_AUTH_SALT=wordpress' \\\n    -e 'WORDPRESS_SECURE_AUTH_SALT=wordpress' \\\n    -e 'WORDPRESS_LOGGED_IN_SALT=wordpress' \\\n    -p 80:80 \\\n    wordpress:5.1-php7.1-apache\n",[567,45570,45571,45579,45585,45591,45597,45609,45621,45633,45645,45657,45669,45681,45693,45705,45717,45725],{"__ignoreMap":743},[747,45572,45573,45575,45577],{"class":749,"line":750},[747,45574,3257],{"class":1630},[747,45576,3665],{"class":802},[747,45578,1641],{"class":1640},[747,45580,45581,45583],{"class":749,"line":761},[747,45582,5866],{"class":802},[747,45584,1641],{"class":1640},[747,45586,45587,45589],{"class":749,"line":769},[747,45588,45323],{"class":802},[747,45590,1641],{"class":1640},[747,45592,45593,45595],{"class":749,"line":776},[747,45594,6496],{"class":802},[747,45596,1641],{"class":1640},[747,45598,45599,45601,45603,45605,45607],{"class":749,"line":784},[747,45600,5991],{"class":802},[747,45602,3537],{"class":757},[747,45604,6853],{"class":802},[747,45606,3543],{"class":757},[747,45608,1641],{"class":1640},[747,45610,45611,45613,45615,45617,45619],{"class":749,"line":790},[747,45612,5991],{"class":802},[747,45614,3537],{"class":757},[747,45616,6866],{"class":802},[747,45618,3543],{"class":757},[747,45620,1641],{"class":1640},[747,45622,45623,45625,45627,45629,45631],{"class":749,"line":796},[747,45624,5991],{"class":802},[747,45626,3537],{"class":757},[747,45628,6879],{"class":802},[747,45630,3543],{"class":757},[747,45632,1641],{"class":1640},[747,45634,45635,45637,45639,45641,45643],{"class":749,"line":806},[747,45636,5991],{"class":802},[747,45638,3537],{"class":757},[747,45640,6892],{"class":802},[747,45642,3543],{"class":757},[747,45644,1641],{"class":1640},[747,45646,45647,45649,45651,45653,45655],{"class":749,"line":814},[747,45648,5991],{"class":802},[747,45650,3537],{"class":757},[747,45652,6905],{"class":802},[747,45654,3543],{"class":757},[747,45656,1641],{"class":1640},[747,45658,45659,45661,45663,45665,45667],{"class":749,"line":822},[747,45660,5991],{"class":802},[747,45662,3537],{"class":757},[747,45664,6918],{"class":802},[747,45666,3543],{"class":757},[747,45668,1641],{"class":1640},[747,45670,45671,45673,45675,45677,45679],{"class":749,"line":830},[747,45672,5991],{"class":802},[747,45674,3537],{"class":757},[747,45676,6931],{"class":802},[747,45678,3543],{"class":757},[747,45680,1641],{"class":1640},[747,45682,45683,45685,45687,45689,45691],{"class":749,"line":836},[747,45684,5991],{"class":802},[747,45686,3537],{"class":757},[747,45688,6944],{"class":802},[747,45690,3543],{"class":757},[747,45692,1641],{"class":1640},[747,45694,45695,45697,45699,45701,45703],{"class":749,"line":842},[747,45696,5991],{"class":802},[747,45698,3537],{"class":757},[747,45700,6957],{"class":802},[747,45702,3543],{"class":757},[747,45704,1641],{"class":1640},[747,45706,45707,45709,45711,45713,45715],{"class":749,"line":850},[747,45708,5991],{"class":802},[747,45710,3537],{"class":757},[747,45712,6970],{"class":802},[747,45714,3543],{"class":757},[747,45716,1641],{"class":1640},[747,45718,45719,45721,45723],{"class":749,"line":863},[747,45720,6614],{"class":802},[747,45722,6990],{"class":802},[747,45724,1641],{"class":1640},[747,45726,45727],{"class":749,"line":869},[747,45728,45031],{"class":802},[6072,45730,45731,45735],{},[523,45732,45733],{},[584,45734,2957],{},[668,45736,45737,45741,45749,45756,45760],{},[638,45738,45739,6310],{},[567,45740,5841],{},[638,45742,45743,45745,45746,45748],{},[567,45744,45296],{}," - Put the container inside the ",[567,45747,6725],{}," network, we created earlier.",[638,45750,45751,45753,45754,1909],{},[567,45752,44025],{}," - Gives the container the name ",[567,45755,6725],{},[638,45757,45758,6322],{},[567,45759,6321],{},[638,45761,45762,6341],{},[567,45763,45764],{},"wordpress:5.1-php7.1-apache",[523,45766,7033,45767,1909],{},[567,45768,45769],{},"http:\u002F\u002FIP_ADDRESS_OF_THE_SERVER:80",[6072,45771,45772,45776],{},[523,45773,45774],{},[584,45775,6189],{},[523,45777,7044],{},[523,45779,45780],{},"For cleanup you now stop and delete the containers.",[523,45782,45783,45784,45786,45787,6353,45789,7052,45791,7055,45793,7058],{},"To stop the ",[567,45785,6725],{}," , run ",[567,45788,4180],{},[567,45790,4188],{},[567,45792,6725],{},[567,45794,4194],{},[3126,45796,45798],{"id":45797},"how-can-the-wordpress-container-be-reached-from-the-outside-world-now","How can the WordPress container be reached from the outside world now?",[523,45800,45801,45802,45804,45805,5845,45807,45809],{},"Right now it can't but we can change this by making the webserver port (",[567,45803,31891],{},") available to the \"public\", by publishing\u002F exposing the port(s).\nThat is what the ",[567,45806,6588],{},[567,45808,6591],{},") flag is used for, in this format:",[738,45811,45813],{"className":1621,"code":45812,"language":1623,"meta":743,"style":743},"docker run \\\n[OTHER_OPTIONS] \\\n#   -p HOST_ADDRESS:HOST_PORT:CONTAINER_PORT\u002FPROTOCOL\n    -p 80:80\u002Ftcp \\\n[...]\n",[567,45814,45815,45823,45828,45833,45841],{"__ignoreMap":743},[747,45816,45817,45819,45821],{"class":749,"line":750},[747,45818,3257],{"class":1630},[747,45820,3665],{"class":802},[747,45822,1641],{"class":1640},[747,45824,45825],{"class":749,"line":761},[747,45826,45827],{"class":1640},"[OTHER_OPTIONS] \\\n",[747,45829,45830],{"class":749,"line":769},[747,45831,45832],{"class":772},"#   -p HOST_ADDRESS:HOST_PORT:CONTAINER_PORT\u002FPROTOCOL\n",[747,45834,45835,45837,45839],{"class":749,"line":776},[747,45836,6614],{"class":1630},[747,45838,6657],{"class":802},[747,45840,1641],{"class":1640},[747,45842,45843],{"class":749,"line":784},[747,45844,5986],{"class":1640},[6072,45846,45847,45851],{},[523,45848,45849],{},[584,45850,2957],{},[668,45852,45853,45859,45863,45867],{},[638,45854,45855,6682,45857,6686],{},[567,45856,6681],{},[567,45858,6685],{},[638,45860,45861,6692],{},[567,45862,6691],{},[638,45864,45865,6698],{},[567,45866,6697],{},[638,45868,45869,6682,45871,6707,45873,6374,45875,1909],{},[567,45870,6703],{},[567,45872,6706],{},[567,45874,6706],{},[567,45876,6712],{},[523,45878,45879],{},"And that's how you forward\u002F publish ports from the container to the outside.",[535,45881,44471],{"id":45882},"summary-of-what-we-did-so-far-1",[523,45884,45885],{},"You should now be able to list containers, start up container, create a network for your containers and be able to access them from the \"outside\".",[523,45887,45888],{},"Please make sure to stop and\u002F or remove stopped\u002F terminated containers.",[523,45890,7065],{},[2979,45892],{},[535,45894,45895],{"id":7227},"Data, Data everywhere!",[523,45897,45898],{},[3049,45899,7233],{},[613,45901,45903],{"id":45902},"volumes-aka-mounts","Volumes aka Mounts",[523,45905,45906,45907,45909,45910,7248,45912,45914],{},"Volumes add persistence to your data. When a container is stopped and removed, the data in the container is lost.\nWith a volume you would mount the part of the data out of the container. For example with our MariaDB container, we would mount the container path ",[567,45908,7243],{}," (contains the MariaDB databases) somewhere safe.\nSo if the MariaDB server inside the container should ever crash and the container then be terminated, you can just fire up with the ",[567,45911,7247],{},[567,45913,4203],{}," command again. The MariaDB container then starts using the data where it exited.",[523,45916,7254,45917,7258],{},[567,45918,7257],{},[738,45920,45921],{"className":1621,"code":7261,"language":1623,"meta":743,"style":743},[567,45922,45923,45931,45935,45941],{"__ignoreMap":743},[747,45924,45925,45927,45929],{"class":749,"line":750},[747,45926,3257],{"class":1630},[747,45928,3665],{"class":802},[747,45930,1641],{"class":1640},[747,45932,45933],{"class":749,"line":761},[747,45934,6417],{"class":1640},[747,45936,45937,45939],{"class":749,"line":769},[747,45938,6139],{"class":1630},[747,45940,6142],{"class":802},[747,45942,45943,45945,45947,45949,45951,45953],{"class":749,"line":776},[747,45944,4253],{"class":757},[747,45946,5704],{"class":1640},[747,45948,4259],{"class":757},[747,45950,4262],{"class":757},[747,45952,6630],{"class":1640},[747,45954,4268],{"class":757},[6072,45956,45957,45961,45981,45985,45991,45995],{},[523,45958,45959],{},[584,45960,2957],{},[668,45962,45963,45967,45971],{},[638,45964,45965,6162],{},[567,45966,6161],{},[638,45968,45969,6168],{},[567,45970,6167],{},[638,45972,45973,6174,45975,6178,45977,6182,45979,1909],{},[567,45974,6173],{},[567,45976,6177],{},[567,45978,6181],{},[567,45980,6177],{},[523,45982,45983],{},[584,45984,3103],{},[523,45986,45987,45990],{},[567,45988,45989],{},"-v HOST_PATH:CONTAINER_PATH"," allows you to store data from containers on the host.",[523,45992,45993],{},[584,45994,6189],{},[523,45996,45997,45998,46000,46001,1909],{},"When the host path doesn't exist, it will be created. BUT the permissions will be a bit \"freaky\", when the path get's created on the host, the directory will be (by default) owned by ",[567,45999,7341],{},", directory permissions ",[567,46002,7345],{},[613,46004,46006,33312],{"id":46005},"docker-volume-command",[567,46007,11634],{},[523,46009,46010],{},"Docker nowadays also allows to create volumes for containers locally but also through available storage drivers.",[523,46012,46013,46014,1909],{},"Through plugins for the Docker Engine you can access multiple different storage systems\u002F softwares.\nA list of volume plugins can be found here: ",[527,46015,46018],{"href":46016,"rel":46017},"https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Fextend\u002Flegacy_plugins\u002F#volume-plugins",[531],"Docker Engine Documentation - Volume Plugins",[523,46020,46021],{},"This in general is pretty useful as the Docker engine takes care to provide a volume for your container(s), but in regards to the second day when we start to run Kubernetes we will see that Docker doesn't matter too much anymore with such features.",[523,46023,46024,46025,27781,46027,27784,46029,46031],{},"To mention it already there is a new interface for requesting\u002F \"managing\" storage, which is named ",[584,46026,27780],{},[584,46028,2003],{},[584,46030,27787],{},"nterface (CSI). The goal of CSI is to have an unified interface through which anyone can request storage. Mounting of the requested storage is done by the storage dependent CSI driver then.",[613,46033,7356,46035,46037],{"id":46034},"data-containers-aka-volumes-from-deprecated",[567,46036,7359],{}," (DEPRECATED)",[6072,46039,46040,46044],{},[523,46041,46042],{},[584,46043,6189],{},[668,46045,46046,46049],{},[638,46047,46048],{},"I do NOT recommend this method as I often enough \"accidentally\" clear all exited\u002F dead containers, so my disk space doesn't run out.",[638,46050,7375],{},[523,46052,46053,46054,7381,46056,7385,46058,7389],{},"You can store data inside another container, that's called data volume containers.\nWhen creating an image, you can specify those volumes. You create a container that has a volume \"built-into\" (Specified while the image was built), meaning that assuming it is our MariaDB server image the in-built volume would be located at ",[567,46055,6335],{},[567,46057,7384],{},[567,46059,7388],{},[523,46061,7392,46062,6353,46064,7398],{},[567,46063,7395],{},[567,46065,4188],{},[523,46067,7401,46068,7405,46070,7408,46072,7411],{},[567,46069,7404],{},[567,46071,7404],{},[567,46073,7359],{},[523,46075,46076],{},[584,46077,46078],{},"I personally don't recommend data container for data sharing, as I find it a bad practice to store data inside a ephemeral container.",[2979,46080],{},[535,46082,193],{"id":7442},[523,46084,7445],{},[613,46086,46088],{"id":46087},"nating-your-way-into-my-container","NATing your way into my container",[6072,46090,46091],{},[523,46092,46093],{},"I'm not going to explain NAT in-depth here.",[523,46095,46096],{},"Network Address Translation (NAT) allows multiple devices to sit behind the same IP address.",[523,46098,46099,46100,46102],{},"Docker creates ",[567,46101,8254],{}," rules to allow traffic to the container.",[613,46104,7459],{"id":7458},[523,46106,46107,46108,46110,46111,714,46113,46115,46116,46118,46119,46121],{},"By default Docker creates a bridge called ",[567,46109,7472],{},", that is used as a bridge to your \"normal\" network interface(s) (e.g., ",[567,46112,7465],{},[567,46114,7468],{},", etc).\nThe ",[567,46117,7472],{}," bridge tries to find an unoccupied network range, mostly from the ",[567,46120,7479],{}," IP range as a network. This IP address range will be used, to assign every container a separate IP.\nSometimes the bridge address range needs to be adjusted, even though Docker tries it's \"best\" to find a free IP range. In most cases when you are running Docker in a corporate network, get in touch with your network team to ask for a \"free range\".",[6072,46123,46124,46128],{},[523,46125,46126],{},[584,46127,6189],{},[523,46129,46130,46131,6353,46133,46135,46136,46138,46139,6374,46141,1909],{},"To manually override the Docker bridge address, you can add the ",[567,46132,7483],{},[567,46134,7486],{}," is an unused IP range) to your Docker Daemon flags in the Systemd Unit file or through the \"config\" files, e.g., on Debian based systems ",[567,46137,7490],{}," or on RHEL based systems ",[567,46140,7494],{},[567,46142,7497],{},[6072,46144,46145,46151],{},[523,46146,46147,8287,46149,33318],{},[584,46148,44125],{},[567,46150,7472],{},[738,46152,46153],{"className":1621,"code":743,"language":1623,"meta":743,"style":743},[567,46154,46155],{"__ignoreMap":743},[747,46156],{"class":749,"line":750},[523,46158,46159],{},"$ ip addr show docker0\n4: docker0: \u003CNO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default\nlink\u002Fether 02:42:d1:cc:07:47 brd ff:ff:ff:ff:ff:ff\ninet 172.17.0.1\u002F16 brd 172.17.255.255 scope global docker0\nvalid_lft forever preferred_lft forever\ninet6 fe80::42:d1ff:fecc:747\u002F64 scope link\nvalid_lft forever preferred_lft forever",[738,46161,46164],{"className":46162,"code":46163,"language":12479},[12477],"\nWhen a container is created, a `veth` interface will be created (depending on the network mode, [next section](#network-modes-default-host-or-other)). The `veth` interface will have an unique name.\n`veth` stands for virtual ethernet device and it will be connected to the `docker0` bridge, to acquire network connectivity.\nThe veth interface will not show the IP address when using tools like `ip addr show` or `ifconfig` on the host, but you are able to see the IP inside the container.\n\n> **EXAMPLE** `veth` interface of container from host\n> ```bash\n$ ip addr show veth9af2aa6\n138: veth9af2aa6@if137: \u003CBROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-4cc4efd905ff state UP group default\n    link\u002Fether be:e2:72:ce:72:1b brd ff:ff:ff:ff:ff:ff link-netnsid 0\n    inet6 fe80::bce2:72ff:fece:721b\u002F64 scope link\n       valid_lft forever preferred_lft forever\n",[567,46165,46163],{"__ignoreMap":743},[523,46167,46168,46169,46172,46173,46175],{},"Previously we also had it about other networks\u002F bridges in regards to ",[567,46170,46171],{},"docker network"," commands. When running ",[567,46174,44558],{}," a new bridge will be created which has its \"own\" IP range as can been seen in the example output.",[6072,46177,46178],{},[523,46179,46180,8287,46182,46184],{},[584,46181,44125],{},[567,46183,44558],{}," \"normal\" bridge on host",[738,46186,46188],{"className":1621,"code":46187,"language":1623,"meta":743,"style":743},"$ ip addr show br-4cc4efd905ff\n104: br-4cc4efd905ff: \u003CBROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default\n    link\u002Fether 02:42:90:e4:8d:a1 brd ff:ff:ff:ff:ff:ff\n    inet 172.18.0.1\u002F16 brd 172.18.255.255 scope global br-4cc4efd905ff\n       valid_lft forever preferred_lft forever\n    inet6 fe80::42:90ff:fee4:8da1\u002F64 scope link\n       valid_lft forever preferred_lft forever\n",[567,46189,46190,46203,46234,46244,46260,46270,46281],{"__ignoreMap":743},[747,46191,46192,46194,46196,46198,46201],{"class":749,"line":750},[747,46193,1919],{"class":1630},[747,46195,7535],{"class":802},[747,46197,44677],{"class":802},[747,46199,46200],{"class":802}," show",[747,46202,44963],{"class":802},[747,46204,46205,46208,46210,46212,46214,46216,46218,46220,46222,46224,46226,46228,46230,46232],{"class":749,"line":761},[747,46206,46207],{"class":1630},"104:",[747,46209,44909],{"class":802},[747,46211,7552],{"class":757},[747,46213,7671],{"class":802},[747,46215,7558],{"class":1640},[747,46217,2035],{"class":757},[747,46219,7563],{"class":802},[747,46221,7680],{"class":1895},[747,46223,7569],{"class":802},[747,46225,7572],{"class":802},[747,46227,7575],{"class":802},[747,46229,7690],{"class":802},[747,46231,7581],{"class":802},[747,46233,7736],{"class":802},[747,46235,46236,46238,46240,46242],{"class":749,"line":769},[747,46237,7741],{"class":1630},[747,46239,44940],{"class":802},[747,46241,7600],{"class":802},[747,46243,7749],{"class":802},[747,46245,46246,46248,46250,46252,46254,46256,46258],{"class":749,"line":776},[747,46247,7608],{"class":1630},[747,46249,44951],{"class":802},[747,46251,7600],{"class":802},[747,46253,44956],{"class":1895},[747,46255,7614],{"class":802},[747,46257,7766],{"class":802},[747,46259,44963],{"class":802},[747,46261,46262,46264,46266,46268],{"class":749,"line":784},[747,46263,7624],{"class":1630},[747,46265,7627],{"class":802},[747,46267,7630],{"class":802},[747,46269,7633],{"class":802},[747,46271,46272,46274,46277,46279],{"class":749,"line":790},[747,46273,7638],{"class":1630},[747,46275,46276],{"class":802}," fe80::42:90ff:fee4:8da1\u002F64",[747,46278,7614],{"class":802},[747,46280,44891],{"class":802},[747,46282,46283,46285,46287,46289],{"class":749,"line":796},[747,46284,7624],{"class":1630},[747,46286,7627],{"class":802},[747,46288,7630],{"class":802},[747,46290,7633],{"class":802},[523,46292,46293,46294,856],{},"You can view the IP address and much more information of containers, using ",[567,46295,46296],{},"docker inspect CONTAINER_NAME",[6072,46298,46299,46306],{},[523,46300,46301,8287,46303],{},[584,46302,44125],{},[567,46304,46305],{},"docker inspect database",[738,46307,46308],{"className":1621,"code":743,"language":1623,"meta":743,"style":743},[567,46309,46310],{"__ignoreMap":743},[747,46311],{"class":749,"line":750},[523,46313,46314,46315],{},"$ docker inspect database\n",[747,46316,46317,46318,46320,46321,46323,46324,46326,46327,46329,46330,46332,46333,46335,46336,46338],{},"\n{\n",[747,46319,5685],{},"\n\"Name\": \"\u002Fdatabase\",\n",[747,46322,5685],{},"\n\"NetworkSettings\": {\n",[747,46325,5685],{},"\n\"Ports\": {\n\"3306\u002Ftcp\": null\n},\n",[747,46328,5685],{},"\n\"Networks\": {\n\"wordpress\": {\n",[747,46331,5685],{},"\n\"Gateway\": \"172.18.0.1\",\n\"IPAddress\": \"172.18.0.2\",\n\"IPPrefixLen\": 16,\n",[747,46334,5685],{},"\n\"MacAddress\": \"02:42:ac:12:00:02\",\n",[747,46337,5685],{},"\n}\n}\n}\n}\n",[738,46340,46343],{"className":46341,"code":46342,"language":12479},[12477],"\n#### Multi Machine Network\n\nDocker Swarm, which is the \"clustered\" mode\u002F \"version\" of Docker, can allow you to create an overlay network, between multiple machines. But I'm not going deeper into this here.\nFor people interested in this feature, see the [Docker Docs `network create`](https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Freference\u002Fcommandline\u002Fnetwork_create\u002F).\n\n#### IPv6\n\n> _Let's not talk about that, okay ..?_\n\nWith Docker itself it is not too much of a problem to use IPv6, but sadly not too optimal.\n\nYou can have IPv4 and IPv6, but let's concern ourselves with that when we are looking at Kubernetes. Reason for looking at this topic first in Kubernetes is that, in Kubernetes you won't really use the networking of Docker anymore.\n\n### Network modes (\"default\", host or other)\n\nI've wrote, that I'm not going deeper into Docker's own (overlay) network feature, but with this topic, I'll have to go into it just a bit.\n\nWhen running a container in the default network mode (named `default`, `--net=default`). The `default` network mode causes every container to get a separate network interface\u002F stack.\n\nThere is also the network mode `host` available by default. The `host` network mode gives the host network stack aka \"full access to the network of the host system\" inside the container.\n\nThe `--net` flag can also take a name of a network which has been created using the `docker network` command, e.g, as used in the example `wordpress` as the network name `--net=wordpress`.\n\n> **NOTE**\n>\n> For the upcoming example outputs, the `docker0` bridge uses the `172.17.0.1\u002F16`!\n\nThe below snippet shows how the contaienr inside network looks for \"default\" (\u002F unspecified) network mode:\n\n> **EXAMPLE**\n> ```bash\nHOST $ docker run -it debian:jessie ip addr show\n1: lo: \u003CLOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000\n    link\u002Floopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n    inet 127.0.0.1\u002F8 scope host lo\n       valid_lft forever preferred_lft forever\n141: eth0@if142: \u003CBROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default\n    link\u002Fether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff\n    inet 172.17.0.2\u002F16 brd 172.17.255.255 scope global eth0\n       valid_lft forever preferred_lft forever\n",[567,46344,46342],{"__ignoreMap":743},[523,46346,46347,46348,46350],{},"As you can see the container is getting an IP from the ",[567,46349,7472],{}," bridge.",[523,46352,46353,46354,13426],{},"What about using the host's network with ",[567,46355,46356],{},"--net=host",[6072,46358,46359,46363],{},[523,46360,46361],{},[584,46362,44125],{},[738,46364,46365],{"className":1621,"code":743,"language":1623,"meta":743,"style":743},[567,46366,46367],{"__ignoreMap":743},[747,46368],{"class":749,"line":750},[523,46370,46371],{},"$ docker run -it --net=host debian:jessie ip addr show\n1: lo: \u003CLOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000\nlink\u002Floopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\ninet 127.0.0.1\u002F8 scope host lo\nvalid_lft forever preferred_lft forever\ninet6 ::1\u002F128 scope host\nvalid_lft forever preferred_lft forever\n2: enp4s0: \u003CBROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000\nlink\u002Fether REDACTED brd ff:ff:ff:ff:ff:ff\ninet 172.16.1.99\u002F24 brd 172.16.1.255 scope global noprefixroute dynamic enp4s0\nvalid_lft 5204sec preferred_lft 5204sec\ninet6 REDACTED\u002F64 scope global noprefixroute dynamic\nvalid_lft 86396sec preferred_lft 14396sec\ninet6 fe80::800b:52b6:865b:5444\u002F64 scope link noprefixroute\nvalid_lft forever preferred_lft forever\n4: docker0: \u003CNO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default\nlink\u002Fether 02:42:d1:cc:07:47 brd ff:ff:ff:ff:ff:ff\ninet 172.17.0.1\u002F16 brd 172.17.255.255 scope global docker0\nvalid_lft forever preferred_lft forever\ninet6 fe80::42:d1ff:fecc:747\u002F64 scope link\nvalid_lft forever preferred_lft forever\n104: br-4cc4efd905ff: \u003CBROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default\nlink\u002Fether 02:42:90:e4:8d:a1 brd ff:ff:ff:ff:ff:ff\ninet 172.18.0.1\u002F16 brd 172.18.255.255 scope global br-4cc4efd905ff\nvalid_lft forever preferred_lft forever\ninet6 fe80::42:90ff:fee4:8da1\u002F64 scope link\nvalid_lft forever preferred_lft forever\n138: veth9af2aa6@if137: \u003CBROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-4cc4efd905ff state UP group default\nlink\u002Fether be:e2:72:ce:72:1b brd ff:ff:ff:ff:ff:ff\ninet6 fe80::bce2:72ff:fece:721b\u002F64 scope link\nvalid_lft forever preferred_lft forever",[738,46373,46376],{"className":46374,"code":46375,"language":12479},[12477],"\nThe container is getting full access to the host's network stack when using `--net=host`.\n\nThe `br-4cc4efd905ff` interface is the `wordpress` network previously created.\n\n> **WARNING**\n>\n> This means that there are no namespaces between the host's network stack and the container!\n>\n> A container running with `--net=host` can potentially shutdown your server.\n> Only use `--net=host` when you know what you are doing and what the implications are.\n\nJust for comparsion here the `ip addr show` output directly from the host to compare it with the above output from the container.\n\n> **EXAMPLE**\n> ```bash\nHOST $ ip addr show\n1: lo: \u003CLOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000\n    link\u002Floopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n    inet 127.0.0.1\u002F8 scope host lo\n       valid_lft forever preferred_lft forever\n    inet6 ::1\u002F128 scope host\n       valid_lft forever preferred_lft forever\n2: enp4s0: \u003CBROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000\n    link\u002Fether REDACTED brd ff:ff:ff:ff:ff:ff\n    inet 172.16.1.99\u002F24 brd 172.16.1.255 scope global dynamic noprefixroute enp4s0\n       valid_lft 5188sec preferred_lft 5188sec\n    inet6 REDACTED\u002F64 scope global dynamic noprefixroute\n       valid_lft 86395sec preferred_lft 14395sec\n    inet6 fe80::800b:52b6:865b:5444\u002F64 scope link noprefixroute\n       valid_lft forever preferred_lft forever\n4: docker0: \u003CNO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default\n    link\u002Fether 02:42:d1:cc:07:47 brd ff:ff:ff:ff:ff:ff\n    inet 172.17.0.1\u002F16 brd 172.17.255.255 scope global docker0\n       valid_lft forever preferred_lft forever\n    inet6 fe80::42:d1ff:fecc:747\u002F64 scope link\n       valid_lft forever preferred_lft forever\n104: br-4cc4efd905ff: \u003CBROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default\n    link\u002Fether 02:42:90:e4:8d:a1 brd ff:ff:ff:ff:ff:ff\n    inet 172.18.0.1\u002F16 brd 172.18.255.255 scope global br-4cc4efd905ff\n       valid_lft forever preferred_lft forever\n    inet6 fe80::42:90ff:fee4:8da1\u002F64 scope link\n       valid_lft forever preferred_lft forever\n138: veth9af2aa6@if137: \u003CBROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-4cc4efd905ff state UP group default\n    link\u002Fether be:e2:72:ce:72:1b brd ff:ff:ff:ff:ff:ff link-netnsid 0\n    inet6 fe80::bce2:72ff:fece:721b\u002F64 scope link\n       valid_lft forever preferred_lft forever\n",[567,46377,46375],{"__ignoreMap":743},[613,46379,8245],{"id":8244},[523,46381,46099,46382,46384],{},[567,46383,8254],{}," rules so published (\u002F exposing) ports are reachable from the host itself but also from the outside.",[523,46386,46387,46388,46390,46391,856],{},"In the below example output below, all ",[567,46389,8254],{}," rules are shown that are created when one container is publishing\u002F exposing port ",[567,46392,46393],{},"3000\u002FTCP",[6072,46395,46396,46400],{},[523,46397,46398],{},[584,46399,44125],{},[523,46401,46402,46404],{},[567,46403,8254],{}," filter rules",[738,46406,46408],{"className":1621,"code":46407,"language":1623,"meta":743,"style":743},"# iptables -L -n\nChain INPUT (policy ACCEPT)\ntarget     prot opt source               destination\n\nChain FORWARD (policy DROP)\ntarget     prot opt source               destination\nDOCKER-USER  all  --  0.0.0.0\u002F0            0.0.0.0\u002F0\nDOCKER-ISOLATION-STAGE-1  all  --  0.0.0.0\u002F0            0.0.0.0\u002F0\nACCEPT     all  --  0.0.0.0\u002F0            0.0.0.0\u002F0            ctstate RELATED,ESTABLISHED\nDOCKER     all  --  0.0.0.0\u002F0            0.0.0.0\u002F0\nACCEPT     all  --  0.0.0.0\u002F0            0.0.0.0\u002F0\nACCEPT     all  --  0.0.0.0\u002F0            0.0.0.0\u002F0\n\nChain OUTPUT (policy ACCEPT)\ntarget     prot opt source               destination\n\nChain DOCKER (1 references)\ntarget     prot opt source               destination\nACCEPT     tcp  --  0.0.0.0\u002F0            172.17.0.2           tcp dpt:3000\n\nChain DOCKER-ISOLATION-STAGE-1 (1 references)\ntarget     prot opt source               destination\nDOCKER-ISOLATION-STAGE-2  all  --  0.0.0.0\u002F0            0.0.0.0\u002F0\nRETURN     all  --  0.0.0.0\u002F0            0.0.0.0\u002F0\n\nChain DOCKER-ISOLATION-STAGE-2 (1 references)\ntarget     prot opt source               destination\nDROP       all  --  0.0.0.0\u002F0            0.0.0.0\u002F0\nRETURN     all  --  0.0.0.0\u002F0            0.0.0.0\u002F0\n\nChain DOCKER-USER (1 references)\ntarget     prot opt source               destination\nRETURN     all  --  0.0.0.0\u002F0            0.0.0.0\u002F0\n",[567,46409,46410,46415,46431,46448,46452,46466,46478,46495,46508,46528,46540,46552,46564,46568,46581,46593,46597,46612,46624,46644,46648,46661,46673,46686,46699,46703,46716,46728,46741,46753,46757,46770,46782],{"__ignoreMap":743},[747,46411,46412],{"class":749,"line":750},[747,46413,46414],{"class":772},"# iptables -L -n\n",[747,46416,46417,46420,46423,46426,46429],{"class":749,"line":761},[747,46418,46419],{"class":1630},"Chain",[747,46421,46422],{"class":802}," INPUT",[747,46424,46425],{"class":1640}," (policy ",[747,46427,46428],{"class":802},"ACCEPT",[747,46430,3600],{"class":1640},[747,46432,46433,46436,46439,46442,46445],{"class":749,"line":769},[747,46434,46435],{"class":1630},"target",[747,46437,46438],{"class":802},"     prot",[747,46440,46441],{"class":802}," opt",[747,46443,46444],{"class":802}," source",[747,46446,46447],{"class":802},"               destination\n",[747,46449,46450],{"class":749,"line":776},[747,46451,1255],{"emptyLinePlaceholder":1254},[747,46453,46454,46456,46459,46461,46464],{"class":749,"line":784},[747,46455,46419],{"class":1630},[747,46457,46458],{"class":802}," FORWARD",[747,46460,46425],{"class":1640},[747,46462,46463],{"class":802},"DROP",[747,46465,3600],{"class":1640},[747,46467,46468,46470,46472,46474,46476],{"class":749,"line":790},[747,46469,46435],{"class":1630},[747,46471,46438],{"class":802},[747,46473,46441],{"class":802},[747,46475,46444],{"class":802},[747,46477,46447],{"class":802},[747,46479,46480,46483,46486,46489,46492],{"class":749,"line":796},[747,46481,46482],{"class":1630},"DOCKER-USER",[747,46484,46485],{"class":802},"  all",[747,46487,46488],{"class":802},"  --",[747,46490,46491],{"class":802},"  0.0.0.0\u002F0",[747,46493,46494],{"class":802},"            0.0.0.0\u002F0\n",[747,46496,46497,46500,46502,46504,46506],{"class":749,"line":806},[747,46498,46499],{"class":1630},"DOCKER-ISOLATION-STAGE-1",[747,46501,46485],{"class":802},[747,46503,46488],{"class":802},[747,46505,46491],{"class":802},[747,46507,46494],{"class":802},[747,46509,46510,46512,46515,46517,46519,46522,46525],{"class":749,"line":814},[747,46511,46428],{"class":1630},[747,46513,46514],{"class":802},"     all",[747,46516,46488],{"class":802},[747,46518,46491],{"class":802},[747,46520,46521],{"class":802},"            0.0.0.0\u002F0",[747,46523,46524],{"class":802},"            ctstate",[747,46526,46527],{"class":802}," RELATED,ESTABLISHED\n",[747,46529,46530,46532,46534,46536,46538],{"class":749,"line":822},[747,46531,8277],{"class":1630},[747,46533,46514],{"class":802},[747,46535,46488],{"class":802},[747,46537,46491],{"class":802},[747,46539,46494],{"class":802},[747,46541,46542,46544,46546,46548,46550],{"class":749,"line":830},[747,46543,46428],{"class":1630},[747,46545,46514],{"class":802},[747,46547,46488],{"class":802},[747,46549,46491],{"class":802},[747,46551,46494],{"class":802},[747,46553,46554,46556,46558,46560,46562],{"class":749,"line":836},[747,46555,46428],{"class":1630},[747,46557,46514],{"class":802},[747,46559,46488],{"class":802},[747,46561,46491],{"class":802},[747,46563,46494],{"class":802},[747,46565,46566],{"class":749,"line":842},[747,46567,1255],{"emptyLinePlaceholder":1254},[747,46569,46570,46572,46575,46577,46579],{"class":749,"line":850},[747,46571,46419],{"class":1630},[747,46573,46574],{"class":802}," OUTPUT",[747,46576,46425],{"class":1640},[747,46578,46428],{"class":802},[747,46580,3600],{"class":1640},[747,46582,46583,46585,46587,46589,46591],{"class":749,"line":863},[747,46584,46435],{"class":1630},[747,46586,46438],{"class":802},[747,46588,46441],{"class":802},[747,46590,46444],{"class":802},[747,46592,46447],{"class":802},[747,46594,46595],{"class":749,"line":869},[747,46596,1255],{"emptyLinePlaceholder":1254},[747,46598,46599,46601,46604,46607,46610],{"class":749,"line":877},[747,46600,46419],{"class":1630},[747,46602,46603],{"class":802}," DOCKER",[747,46605,46606],{"class":1640}," (1 ",[747,46608,46609],{"class":802},"references",[747,46611,3600],{"class":1640},[747,46613,46614,46616,46618,46620,46622],{"class":749,"line":1015},[747,46615,46435],{"class":1630},[747,46617,46438],{"class":802},[747,46619,46441],{"class":802},[747,46621,46444],{"class":802},[747,46623,46447],{"class":802},[747,46625,46626,46628,46631,46633,46635,46638,46641],{"class":749,"line":1021},[747,46627,46428],{"class":1630},[747,46629,46630],{"class":802},"     tcp",[747,46632,46488],{"class":802},[747,46634,46491],{"class":802},[747,46636,46637],{"class":1895},"            172.17.0.2",[747,46639,46640],{"class":802},"           tcp",[747,46642,46643],{"class":802}," dpt:3000\n",[747,46645,46646],{"class":749,"line":1027},[747,46647,1255],{"emptyLinePlaceholder":1254},[747,46649,46650,46652,46655,46657,46659],{"class":749,"line":1033},[747,46651,46419],{"class":1630},[747,46653,46654],{"class":802}," DOCKER-ISOLATION-STAGE-1",[747,46656,46606],{"class":1640},[747,46658,46609],{"class":802},[747,46660,3600],{"class":1640},[747,46662,46663,46665,46667,46669,46671],{"class":749,"line":1039},[747,46664,46435],{"class":1630},[747,46666,46438],{"class":802},[747,46668,46441],{"class":802},[747,46670,46444],{"class":802},[747,46672,46447],{"class":802},[747,46674,46675,46678,46680,46682,46684],{"class":749,"line":1054},[747,46676,46677],{"class":1630},"DOCKER-ISOLATION-STAGE-2",[747,46679,46485],{"class":802},[747,46681,46488],{"class":802},[747,46683,46491],{"class":802},[747,46685,46494],{"class":802},[747,46687,46688,46691,46693,46695,46697],{"class":749,"line":1060},[747,46689,46690],{"class":1630},"RETURN",[747,46692,46514],{"class":802},[747,46694,46488],{"class":802},[747,46696,46491],{"class":802},[747,46698,46494],{"class":802},[747,46700,46701],{"class":749,"line":1066},[747,46702,1255],{"emptyLinePlaceholder":1254},[747,46704,46705,46707,46710,46712,46714],{"class":749,"line":1081},[747,46706,46419],{"class":1630},[747,46708,46709],{"class":802}," DOCKER-ISOLATION-STAGE-2",[747,46711,46606],{"class":1640},[747,46713,46609],{"class":802},[747,46715,3600],{"class":1640},[747,46717,46718,46720,46722,46724,46726],{"class":749,"line":1087},[747,46719,46435],{"class":1630},[747,46721,46438],{"class":802},[747,46723,46441],{"class":802},[747,46725,46444],{"class":802},[747,46727,46447],{"class":802},[747,46729,46730,46732,46735,46737,46739],{"class":749,"line":1102},[747,46731,46463],{"class":1630},[747,46733,46734],{"class":802},"       all",[747,46736,46488],{"class":802},[747,46738,46491],{"class":802},[747,46740,46494],{"class":802},[747,46742,46743,46745,46747,46749,46751],{"class":749,"line":1110},[747,46744,46690],{"class":1630},[747,46746,46514],{"class":802},[747,46748,46488],{"class":802},[747,46750,46491],{"class":802},[747,46752,46494],{"class":802},[747,46754,46755],{"class":749,"line":1117},[747,46756,1255],{"emptyLinePlaceholder":1254},[747,46758,46759,46761,46764,46766,46768],{"class":749,"line":1123},[747,46760,46419],{"class":1630},[747,46762,46763],{"class":802}," DOCKER-USER",[747,46765,46606],{"class":1640},[747,46767,46609],{"class":802},[747,46769,3600],{"class":1640},[747,46771,46772,46774,46776,46778,46780],{"class":749,"line":1129},[747,46773,46435],{"class":1630},[747,46775,46438],{"class":802},[747,46777,46441],{"class":802},[747,46779,46444],{"class":802},[747,46781,46447],{"class":802},[747,46783,46784,46786,46788,46790,46792],{"class":749,"line":1142},[747,46785,46690],{"class":1630},[747,46787,46514],{"class":802},[747,46789,46488],{"class":802},[747,46791,46491],{"class":802},[747,46793,46494],{"class":802},[6072,46795,46796],{},[523,46797,46798,46800],{},[567,46799,8254],{}," nat rules",[738,46802,46804],{"className":1621,"code":46803,"language":1623,"meta":743,"style":743},"# iptables -t nat -L -n\nChain PREROUTING (policy ACCEPT)\ntarget     prot opt source               destination\nDOCKER     all  --  0.0.0.0\u002F0            0.0.0.0\u002F0            ADDRTYPE match dst-type LOCAL\n\nChain INPUT (policy ACCEPT)\ntarget     prot opt source               destination\n\nChain OUTPUT (policy ACCEPT)\ntarget     prot opt source               destination\nDOCKER     all  --  0.0.0.0\u002F0           !127.0.0.0\u002F8          ADDRTYPE match dst-type LOCAL\n\nChain POSTROUTING (policy ACCEPT)\ntarget     prot opt source               destination\nMASQUERADE  all  --  172.17.0.0\u002F16        0.0.0.0\u002F0\nMASQUERADE  tcp  --  172.17.0.2           172.17.0.2           tcp dpt:3000\n\nChain DOCKER (2 references)\ntarget     prot opt source               destination\nRETURN     all  --  0.0.0.0\u002F0            0.0.0.0\u002F0\nDNAT       tcp  --  0.0.0.0\u002F0            0.0.0.0\u002F0            tcp dpt:3000 to:172.17.0.2:3000\n",[567,46805,46806,46811,46824,46836,46860,46864,46876,46888,46892,46904,46916,46938,46942,46955,46967,46982,47001,47005,47018,47030,47042],{"__ignoreMap":743},[747,46807,46808],{"class":749,"line":750},[747,46809,46810],{"class":772},"# iptables -t nat -L -n\n",[747,46812,46813,46815,46818,46820,46822],{"class":749,"line":761},[747,46814,46419],{"class":1630},[747,46816,46817],{"class":802}," PREROUTING",[747,46819,46425],{"class":1640},[747,46821,46428],{"class":802},[747,46823,3600],{"class":1640},[747,46825,46826,46828,46830,46832,46834],{"class":749,"line":769},[747,46827,46435],{"class":1630},[747,46829,46438],{"class":802},[747,46831,46441],{"class":802},[747,46833,46444],{"class":802},[747,46835,46447],{"class":802},[747,46837,46838,46840,46842,46844,46846,46848,46851,46854,46857],{"class":749,"line":776},[747,46839,8277],{"class":1630},[747,46841,46514],{"class":802},[747,46843,46488],{"class":802},[747,46845,46491],{"class":802},[747,46847,46521],{"class":802},[747,46849,46850],{"class":802},"            ADDRTYPE",[747,46852,46853],{"class":802}," match",[747,46855,46856],{"class":802}," dst-type",[747,46858,46859],{"class":802}," LOCAL\n",[747,46861,46862],{"class":749,"line":784},[747,46863,1255],{"emptyLinePlaceholder":1254},[747,46865,46866,46868,46870,46872,46874],{"class":749,"line":790},[747,46867,46419],{"class":1630},[747,46869,46422],{"class":802},[747,46871,46425],{"class":1640},[747,46873,46428],{"class":802},[747,46875,3600],{"class":1640},[747,46877,46878,46880,46882,46884,46886],{"class":749,"line":796},[747,46879,46435],{"class":1630},[747,46881,46438],{"class":802},[747,46883,46441],{"class":802},[747,46885,46444],{"class":802},[747,46887,46447],{"class":802},[747,46889,46890],{"class":749,"line":806},[747,46891,1255],{"emptyLinePlaceholder":1254},[747,46893,46894,46896,46898,46900,46902],{"class":749,"line":814},[747,46895,46419],{"class":1630},[747,46897,46574],{"class":802},[747,46899,46425],{"class":1640},[747,46901,46428],{"class":802},[747,46903,3600],{"class":1640},[747,46905,46906,46908,46910,46912,46914],{"class":749,"line":822},[747,46907,46435],{"class":1630},[747,46909,46438],{"class":802},[747,46911,46441],{"class":802},[747,46913,46444],{"class":802},[747,46915,46447],{"class":802},[747,46917,46918,46920,46922,46924,46926,46929,46932,46934,46936],{"class":749,"line":830},[747,46919,8277],{"class":1630},[747,46921,46514],{"class":802},[747,46923,46488],{"class":802},[747,46925,46491],{"class":802},[747,46927,46928],{"class":802},"           !127.0.0.0\u002F8",[747,46930,46931],{"class":802},"          ADDRTYPE",[747,46933,46853],{"class":802},[747,46935,46856],{"class":802},[747,46937,46859],{"class":802},[747,46939,46940],{"class":749,"line":836},[747,46941,1255],{"emptyLinePlaceholder":1254},[747,46943,46944,46946,46949,46951,46953],{"class":749,"line":842},[747,46945,46419],{"class":1630},[747,46947,46948],{"class":802}," POSTROUTING",[747,46950,46425],{"class":1640},[747,46952,46428],{"class":802},[747,46954,3600],{"class":1640},[747,46956,46957,46959,46961,46963,46965],{"class":749,"line":850},[747,46958,46435],{"class":1630},[747,46960,46438],{"class":802},[747,46962,46441],{"class":802},[747,46964,46444],{"class":802},[747,46966,46447],{"class":802},[747,46968,46969,46972,46974,46976,46979],{"class":749,"line":863},[747,46970,46971],{"class":1630},"MASQUERADE",[747,46973,46485],{"class":802},[747,46975,46488],{"class":802},[747,46977,46978],{"class":802},"  172.17.0.0\u002F16",[747,46980,46981],{"class":802},"        0.0.0.0\u002F0\n",[747,46983,46984,46986,46989,46991,46994,46997,46999],{"class":749,"line":869},[747,46985,46971],{"class":1630},[747,46987,46988],{"class":802},"  tcp",[747,46990,46488],{"class":802},[747,46992,46993],{"class":1895},"  172.17.0.2",[747,46995,46996],{"class":1895},"           172.17.0.2",[747,46998,46640],{"class":802},[747,47000,46643],{"class":802},[747,47002,47003],{"class":749,"line":877},[747,47004,1255],{"emptyLinePlaceholder":1254},[747,47006,47007,47009,47011,47014,47016],{"class":749,"line":1015},[747,47008,46419],{"class":1630},[747,47010,46603],{"class":802},[747,47012,47013],{"class":1640}," (2 ",[747,47015,46609],{"class":802},[747,47017,3600],{"class":1640},[747,47019,47020,47022,47024,47026,47028],{"class":749,"line":1021},[747,47021,46435],{"class":1630},[747,47023,46438],{"class":802},[747,47025,46441],{"class":802},[747,47027,46444],{"class":802},[747,47029,46447],{"class":802},[747,47031,47032,47034,47036,47038,47040],{"class":749,"line":1027},[747,47033,46690],{"class":1630},[747,47035,46514],{"class":802},[747,47037,46488],{"class":802},[747,47039,46491],{"class":802},[747,47041,46494],{"class":802},[747,47043,47044,47047,47050,47052,47054,47056,47059,47062],{"class":749,"line":1033},[747,47045,47046],{"class":1630},"DNAT",[747,47048,47049],{"class":802},"       tcp",[747,47051,46488],{"class":802},[747,47053,46491],{"class":802},[747,47055,46521],{"class":802},[747,47057,47058],{"class":802},"            tcp",[747,47060,47061],{"class":802}," dpt:3000",[747,47063,47064],{"class":802}," to:172.17.0.2:3000\n",[523,47066,8274,47067,8278,47069,8282],{},[567,47068,8277],{},[567,47070,8281],{},[6072,47072,47073],{},[523,47074,47075,8287,47077],{},[584,47076,2951],{},[527,47078,47081],{"href":47079,"rel":47080},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-container-docker-kubernetes\u002Ftree\u002Fmaster\u002Fnetwork101",[531],[567,47082,8294],{},[523,47084,8297,47085,8301,47088,8304,47090,8307],{},[567,47086,47087],{},"show_me_dat_network.sh",[567,47089,8294],{},[567,47091,8254],{},[613,47093,8311],{"id":8310},[6072,47095,47096],{},[523,47097,47098,8287,47100],{},[584,47099,2951],{},[527,47101,47103],{"href":47079,"rel":47102},[531],[567,47104,8294],{},[523,47106,47107],{},"Do you want to visualize your container network situation? Yes? Then the perfect tool for this is Weave Scope.",[523,47109,8336,47110,8339,47112,8343],{},[567,47111,8294],{},[567,47113,8342],{},[738,47115,47116],{"className":1621,"code":8346,"language":1623,"meta":743,"style":743},[567,47117,47118,47130,47140],{"__ignoreMap":743},[747,47119,47120,47122,47124,47126,47128],{"class":749,"line":750},[747,47121,3376],{"class":1630},[747,47123,8355],{"class":802},[747,47125,3340],{"class":802},[747,47127,8360],{"class":802},[747,47129,8363],{"class":802},[747,47131,47132,47134,47136,47138],{"class":749,"line":761},[747,47133,3376],{"class":1630},[747,47135,3379],{"class":802},[747,47137,8372],{"class":802},[747,47139,8375],{"class":802},[747,47141,47142,47144,47146],{"class":749,"line":769},[747,47143,3376],{"class":1630},[747,47145,7614],{"class":802},[747,47147,8384],{"class":802},[523,47149,8387,47150,8392],{},[567,47151,47152],{},"http:\u002F\u002FIP_ADDRESS_OF_THE_SERVER:4040",[523,47154,47155],{},[3069,47156],{"alt":8401,"src":47157},"\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day1\u002Fweavescope_ui.png",[523,47159,8405],{},[2979,47161],{},[535,47163,8419],{"id":8418},[6072,47165,47166,47168],{},[523,47167,8422],{},[523,47169,47170],{},[3049,47171,8427],{},[523,47173,8430,47174,47177],{},[527,47175,8434],{"href":47176},"#Container"," part, namespaces are able to limit the resources available to processes, etc.",[613,47179,8439],{"id":8438},[523,47181,8442],{},[738,47183,47184],{"className":1621,"code":8445,"language":1623,"meta":743,"style":743},[567,47185,47186,47196,47204,47222,47240,47262],{"__ignoreMap":743},[747,47187,47188,47190,47192,47194],{"class":749,"line":750},[747,47189,1919],{"class":1630},[747,47191,3246],{"class":802},[747,47193,3665],{"class":802},[747,47195,4218],{"class":802},[747,47197,47198,47200,47202],{"class":749,"line":761},[747,47199,4253],{"class":757},[747,47201,5685],{"class":1640},[747,47203,4268],{"class":757},[747,47205,47206,47208,47210,47212,47214,47216,47218,47220],{"class":749,"line":769},[747,47207,8470],{"class":1630},[747,47209,8473],{"class":802},[747,47211,8476],{"class":802},[747,47213,8479],{"class":802},[747,47215,8482],{"class":1640},[747,47217,8485],{"class":802},[747,47219,8488],{"class":802},[747,47221,8491],{"class":1640},[747,47223,47224,47226,47228,47230,47232,47234,47236,47238],{"class":749,"line":776},[747,47225,8496],{"class":1630},[747,47227,8499],{"class":802},[747,47229,8476],{"class":802},[747,47231,8479],{"class":802},[747,47233,8482],{"class":1640},[747,47235,8485],{"class":802},[747,47237,8488],{"class":802},[747,47239,8512],{"class":1640},[747,47241,47242,47244,47246,47248,47250,47252,47254,47256,47258,47260],{"class":749,"line":784},[747,47243,8517],{"class":1630},[747,47245,8520],{"class":802},[747,47247,4584],{"class":802},[747,47249,3945],{"class":802},[747,47251,3696],{"class":802},[747,47253,8529],{"class":802},[747,47255,8532],{"class":802},[747,47257,8535],{"class":1640},[747,47259,8538],{"class":802},[747,47261,3600],{"class":1640},[747,47263,47264,47266,47268],{"class":749,"line":790},[747,47265,4253],{"class":757},[747,47267,5685],{"class":1640},[747,47269,4268],{"class":757},[523,47271,8551,47272,3052],{},[567,47273,8554],{},[613,47275,8558],{"id":8557},[738,47277,47278],{"className":1621,"code":8561,"language":1623,"meta":743,"style":743},[567,47279,47280,47290,47298,47320,47328,47338,47346,47356,47388,47412,47420,47430,47442],{"__ignoreMap":743},[747,47281,47282,47284,47286,47288],{"class":749,"line":750},[747,47283,1919],{"class":1630},[747,47285,3246],{"class":802},[747,47287,3665],{"class":802},[747,47289,4218],{"class":802},[747,47291,47292,47294,47296],{"class":749,"line":761},[747,47293,4253],{"class":757},[747,47295,5685],{"class":1640},[747,47297,4268],{"class":757},[747,47299,47300,47302,47304,47306,47308,47310,47312,47314,47316,47318],{"class":749,"line":769},[747,47301,8586],{"class":1630},[747,47303,8589],{"class":802},[747,47305,4584],{"class":802},[747,47307,3945],{"class":802},[747,47309,3696],{"class":802},[747,47311,8529],{"class":802},[747,47313,8532],{"class":802},[747,47315,8535],{"class":1640},[747,47317,8538],{"class":802},[747,47319,3600],{"class":1640},[747,47321,47322,47324,47326],{"class":749,"line":776},[747,47323,4253],{"class":757},[747,47325,5685],{"class":1640},[747,47327,4268],{"class":757},[747,47329,47330,47332,47334,47336],{"class":749,"line":784},[747,47331,8618],{"class":1630},[747,47333,8621],{"class":802},[747,47335,8624],{"class":802},[747,47337,8627],{"class":802},[747,47339,47340,47342,47344],{"class":749,"line":790},[747,47341,4253],{"class":757},[747,47343,5685],{"class":1640},[747,47345,4268],{"class":757},[747,47347,47348,47350,47352,47354],{"class":749,"line":796},[747,47349,8640],{"class":1630},[747,47351,8643],{"class":802},[747,47353,8646],{"class":802},[747,47355,8627],{"class":802},[747,47357,47358,47360,47362,47364,47366,47368,47370,47372,47374,47376,47378,47380,47382,47384,47386],{"class":749,"line":806},[747,47359,8653],{"class":1630},[747,47361,8656],{"class":802},[747,47363,5033],{"class":802},[747,47365,8661],{"class":802},[747,47367,3696],{"class":802},[747,47369,8624],{"class":802},[747,47371,8668],{"class":802},[747,47373,8671],{"class":802},[747,47375,3537],{"class":757},[747,47377,4920],{"class":802},[747,47379,3543],{"class":757},[747,47381,3696],{"class":802},[747,47383,3205],{"class":802},[747,47385,5043],{"class":802},[747,47387,8686],{"class":802},[747,47389,47390,47392,47394,47396,47398,47400,47402,47404,47406,47408,47410],{"class":749,"line":814},[747,47391,8691],{"class":1640},[747,47393,6425],{"class":757},[747,47395,4920],{"class":802},[747,47397,8698],{"class":1630},[747,47399,3936],{"class":802},[747,47401,8624],{"class":802},[747,47403,8705],{"class":802},[747,47405,8708],{"class":1640},[747,47407,4990],{"class":802},[747,47409,8713],{"class":1895},[747,47411,3600],{"class":1640},[747,47413,47414,47416,47418],{"class":749,"line":822},[747,47415,4253],{"class":757},[747,47417,5685],{"class":1640},[747,47419,4268],{"class":757},[747,47421,47422,47424,47426,47428],{"class":749,"line":830},[747,47423,8728],{"class":1630},[747,47425,8731],{"class":802},[747,47427,4981],{"class":802},[747,47429,8736],{"class":802},[747,47431,47432,47434,47436,47438,47440],{"class":749,"line":836},[747,47433,8741],{"class":1630},[747,47435,8744],{"class":802},[747,47437,4591],{"class":802},[747,47439,3543],{"class":757},[747,47441,8751],{"class":802},[747,47443,47444],{"class":749,"line":842},[747,47445,5986],{"class":802},[523,47447,8758],{},[523,47449,8761],{},[523,47451,8764,47452,8768],{},[567,47453,8767],{},[2979,47455],{},[535,47457,47458],{"id":8780},"Selfies? I mean Images",[523,47460,8784],{},[613,47462,8788],{"id":8787},[523,47464,8791,47465,8797],{},[527,47466,8796],{"href":8794,"rel":47467},[531],[523,47469,47470],{},"The image we used for the MariaDB container is:",[738,47472,47474],{"className":1621,"code":47473,"language":1623,"meta":743,"style":743},"mariadb:10.4.3-bionic\n",[567,47475,47476],{"__ignoreMap":743},[747,47477,47478],{"class":749,"line":750},[747,47479,47473],{"class":1630},[6072,47481,47482,47486],{},[523,47483,47484],{},[584,47485,2957],{},[668,47487,47488,47493,47498],{},[638,47489,47490,47492],{},[567,47491,5734],{}," - The username of the creator.",[638,47494,47495,47497],{},[567,47496,6744],{}," - The image name.",[638,47499,47500,8835],{},[567,47501,8834],{},[523,47503,47504,47505,47510,47511,856],{},"An example for an image that is pulled from a different image server, than the official Docker Hub, is my ",[527,47506,47509],{"href":47507,"rel":47508},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fdellhw_exporter",[531],"Prometheus DellHW Exporter"," image that is hosted on ",[527,47512,8849],{"href":8847,"rel":47513},[531],[738,47515,47517],{"className":1621,"code":47516,"language":1623,"meta":743,"style":743},"quay.io\u002Fgalexrt\u002Fdellhw_exporter:v1.3.5\nSERVER\u002FUSERNAME\u002FIMAGE_NAME:TAG\n",[567,47518,47519,47524],{"__ignoreMap":743},[747,47520,47521],{"class":749,"line":750},[747,47522,47523],{"class":1630},"quay.io\u002Fgalexrt\u002Fdellhw_exporter:v1.3.5\n",[747,47525,47526],{"class":749,"line":761},[747,47527,8864],{"class":1630},[6072,47529,47530,47534],{},[523,47531,47532],{},[584,47533,2957],{},[668,47535,47536,47544,47551,47558],{},[638,47537,47538,714,47540,8878,47542,8882],{},[567,47539,8849],{},[567,47541,8877],{},[567,47543,8881],{},[638,47545,47546,714,47548,47550],{},[567,47547,8887],{},[567,47549,3267],{}," - Username of the image author\u002F uploader.",[638,47552,47553,714,47556,8899],{},[567,47554,47555],{},"dellhw_exporter",[567,47557,8898],{},[638,47559,47560,714,47563,8908,47565,1909],{},[567,47561,47562],{},"v1.3.5",[567,47564,8907],{},[567,47566,8834],{},[523,47568,47569,47570,1909],{},"In the case of official created images, like the WordPress image we used no server and username is required (by default).\nOfficial images are \"marked\" by not having a username in the image \"address\". When browsing such iamges on Docker Hub, the URL does have an underscore instead of a username, e.g., ",[567,47571,6728],{},[613,47573,47575],{"id":47574},"what-have-layer-cakes-to-do-with-container-images","What have Layer Cakes to do with Container Images?",[523,47577,47578],{},[3069,47579],{"alt":47580,"src":47581},"Mhh, tasty, isn't it? But now back to the topic.","\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day1\u002Flayer-cake-from-wikimedia.png",[6072,47583,47584],{},[523,47585,47586,8939,47588],{},[584,47587,2951],{},[527,47589,47592],{"href":47590,"rel":47591},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-container-docker-kubernetes\u002Ftree\u002Fmaster\u002Fdockerfile101",[531],[567,47593,8946],{},[523,47595,47596],{},"In the Docker universe, a Container image is built from the bottom to the top like a cake, the bottom is a baseimage (or any other image as a base).\nEvery \"new\" layer on top of it, is an action that had been run when building the image.",[523,47598,47599,47600,8956,47603,47605],{},"Meaning if we create an image from the baseimage ",[567,47601,47602],{},"fedora:29",[567,47604,8959],{},", a cross-section\u002F profile would look like this:",[523,47607,47608],{},[3069,47609],{"alt":47610,"src":47611},"Dockerfile Steps\u002F Container Image Layers","\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day1\u002Fcontainer-image-layers-diagram.png",[523,47613,47614,47615,47617],{},"That is one of the reasons, why Container images are so small. If you download 10 images that are based on ",[567,47616,8972],{},", you would only have to download the created\u002F modified layers, because the baseimage is the same for these 10 images.\nTo build\u002F create an image, you create a Dockerfile and that's what we are going to talk about next.",[613,47619,47620],{"id":8976},"Dockerfile examples",[523,47622,47623,47624,47626,47627,8987,47629,47631,47632,47634],{},"As you may have already seen in the current task directory ",[567,47625,8946],{},", there is a file called ",[567,47628,8959],{},[567,47630,8959],{}," contains container image build instructions. ",[567,47633,8959],{},"s have their own syntax, but the syntax is pretty simple.",[523,47636,47637],{},"I'm going to show you two more or less advanced Dockerfile examples in the next section, one for a Golang and one for a Python application.",[3126,47639,47641],{"id":47640},"golang-application-with-dependency-dockerfile-example","Golang application with Dependency Dockerfile Example",[523,47643,9000,47644,47648,47649,1909],{},[527,47645,47647],{"href":47507,"rel":47646},[531],"GitHub project galexrt\u002Fdellhw_exporter",", file ",[567,47650,8959],{},[738,47652,47654],{"className":9011,"code":47653,"language":9013,"meta":743,"style":743},"FROM centos:7\nLABEL maintainer=\"Alexander Trost \u003Cgalexrt@googlemail.com>\"\n\n# Environment variables\nENV DSU_VERSION=\"DSU_18.08.00\" \\\n    PATH=\"$PATH:\u002Fopt\u002Fdell\u002Fsrvadmin\u002Fbin:\u002Fopt\u002Fdell\u002Fsrvadmin\u002Fsbin\" \\\n    USER=\"root\" \\\n    PASS=\"password\" \\\n    SYSTEMCTL_SKIP_REDIRECT=\"1\"\n\n# Do overall update and install missing packages needed for OpenManage\nRUN yum -y update && \\\n    yum -y install sysvinit-tools wget perl passwd gcc which tar libstdc++.so.6 compat-libstdc++-33.i686 glibc.i686 && \\\n    echo \"$USER:$PASS\" | chpasswd && \\\n    wget -q -O - \"https:\u002F\u002Flinux.dell.com\u002Frepo\u002Fhardware\u002F${DSU_VERSION}\u002Fbootstrap.cgi\" | bash && \\\n    rpm --import \"https:\u002F\u002Flinux.dell.com\u002Frepo\u002Fpgp_pubkeys\u002F0x1285491434D8786F.asc\" && \\\n    yum -y install srvadmin-base srvadmin-storageservices && \\\n    yum clean all\n\n\nADD .build\u002Flinux-amd64\u002Fdellhw_exporter \u002Fbin\u002Fdellhw_exporter\n\nENTRYPOINT [\"\u002Fbin\u002Fdellhw_exporter\"]\n\nCMD [\"-container\"]\n",[567,47655,47656,47663,47674,47678,47683,47695,47705,47715,47725,47733,47737,47742,47749,47754,47765,47776,47786,47791,47796,47800,47804,47811,47815,47826,47830],{"__ignoreMap":743},[747,47657,47658,47660],{"class":749,"line":750},[747,47659,9020],{"class":1895},[747,47661,47662],{"class":1640}," centos:7\n",[747,47664,47665,47668,47671],{"class":749,"line":761},[747,47666,47667],{"class":1895},"LABEL",[747,47669,47670],{"class":1640}," maintainer=",[747,47672,47673],{"class":802},"\"Alexander Trost \u003Cgalexrt@googlemail.com>\"\n",[747,47675,47676],{"class":749,"line":769},[747,47677,1255],{"emptyLinePlaceholder":1254},[747,47679,47680],{"class":749,"line":776},[747,47681,47682],{"class":772},"# Environment variables\n",[747,47684,47685,47687,47690,47693],{"class":749,"line":784},[747,47686,9032],{"class":1895},[747,47688,47689],{"class":1640}," DSU_VERSION=",[747,47691,47692],{"class":802},"\"DSU_18.08.00\"",[747,47694,1641],{"class":1640},[747,47696,47697,47700,47703],{"class":749,"line":790},[747,47698,47699],{"class":1640},"    PATH=",[747,47701,47702],{"class":802},"\"$PATH:\u002Fopt\u002Fdell\u002Fsrvadmin\u002Fbin:\u002Fopt\u002Fdell\u002Fsrvadmin\u002Fsbin\"",[747,47704,1641],{"class":1640},[747,47706,47707,47710,47713],{"class":749,"line":796},[747,47708,47709],{"class":1640},"    USER=",[747,47711,47712],{"class":802},"\"root\"",[747,47714,1641],{"class":1640},[747,47716,47717,47720,47723],{"class":749,"line":806},[747,47718,47719],{"class":1640},"    PASS=",[747,47721,47722],{"class":802},"\"password\"",[747,47724,1641],{"class":1640},[747,47726,47727,47730],{"class":749,"line":814},[747,47728,47729],{"class":1640},"    SYSTEMCTL_SKIP_REDIRECT=",[747,47731,47732],{"class":802},"\"1\"\n",[747,47734,47735],{"class":749,"line":822},[747,47736,1255],{"emptyLinePlaceholder":1254},[747,47738,47739],{"class":749,"line":830},[747,47740,47741],{"class":772},"# Do overall update and install missing packages needed for OpenManage\n",[747,47743,47744,47746],{"class":749,"line":836},[747,47745,9065],{"class":1895},[747,47747,47748],{"class":1640}," yum -y update && \\\n",[747,47750,47751],{"class":749,"line":842},[747,47752,47753],{"class":1640},"    yum -y install sysvinit-tools wget perl passwd gcc which tar libstdc++.so.6 compat-libstdc++-33.i686 glibc.i686 && \\\n",[747,47755,47756,47759,47762],{"class":749,"line":850},[747,47757,47758],{"class":1640},"    echo ",[747,47760,47761],{"class":802},"\"$USER:$PASS\"",[747,47763,47764],{"class":1640}," | chpasswd && \\\n",[747,47766,47767,47770,47773],{"class":749,"line":863},[747,47768,47769],{"class":1640},"    wget -q -O - ",[747,47771,47772],{"class":802},"\"https:\u002F\u002Flinux.dell.com\u002Frepo\u002Fhardware\u002F${DSU_VERSION}\u002Fbootstrap.cgi\"",[747,47774,47775],{"class":1640}," | bash && \\\n",[747,47777,47778,47781,47784],{"class":749,"line":869},[747,47779,47780],{"class":1640},"    rpm --import ",[747,47782,47783],{"class":802},"\"https:\u002F\u002Flinux.dell.com\u002Frepo\u002Fpgp_pubkeys\u002F0x1285491434D8786F.asc\"",[747,47785,9119],{"class":1640},[747,47787,47788],{"class":749,"line":877},[747,47789,47790],{"class":1640},"    yum -y install srvadmin-base srvadmin-storageservices && \\\n",[747,47792,47793],{"class":749,"line":1015},[747,47794,47795],{"class":1640},"    yum clean all\n",[747,47797,47798],{"class":749,"line":1021},[747,47799,1255],{"emptyLinePlaceholder":1254},[747,47801,47802],{"class":749,"line":1027},[747,47803,1255],{"emptyLinePlaceholder":1254},[747,47805,47806,47808],{"class":749,"line":1033},[747,47807,9669],{"class":1895},[747,47809,47810],{"class":1640}," .build\u002Flinux-amd64\u002Fdellhw_exporter \u002Fbin\u002Fdellhw_exporter\n",[747,47812,47813],{"class":749,"line":1039},[747,47814,1255],{"emptyLinePlaceholder":1254},[747,47816,47817,47819,47821,47824],{"class":749,"line":1054},[747,47818,9210],{"class":1895},[747,47820,4262],{"class":1640},[747,47822,47823],{"class":802},"\"\u002Fbin\u002Fdellhw_exporter\"",[747,47825,4268],{"class":1640},[747,47827,47828],{"class":749,"line":1060},[747,47829,1255],{"emptyLinePlaceholder":1254},[747,47831,47832,47834,47836,47839],{"class":749,"line":1066},[747,47833,9482],{"class":1895},[747,47835,4262],{"class":1640},[747,47837,47838],{"class":802},"\"-container\"",[747,47840,4268],{"class":1640},[3126,47842,47844],{"id":47843},"advanced-python-application-dockerfile-example","Advanced Python Application Dockerfile Example",[523,47846,9000,47847,1909],{},[527,47848,47851],{"href":47849,"rel":47850},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fdocker-healthchecks",[531],"GitHub project galexrt\u002Fdocker-healthchecks",[738,47853,47855],{"className":9011,"code":47854,"language":9013,"meta":743,"style":743},"FROM debian:stretch\nLABEL maintainer=\"Alexander Trost \u003Cgalexrt@googlemail.com>\"\n\nENV DATA_DIR=\"\u002Fdata\" \\\n    HEALTHCHECKS_VERSION=\"master\" \\\n    HEALTHCHECKS_USER=\"1000\" \\\n    HEALTHCHECKS_GROUP=\"1000\"\n\nRUN groupadd -g \"$HEALTHCHECKS_GROUP\" healthchecks && \\\n    useradd -u \"$HEALTHCHECKS_USER\" -g \"$HEALTHCHECKS_GROUP\" -m -d \u002Fhome\u002Fhealthchecks -s \u002Fbin\u002Fbash healthchecks && \\\n    apt-get update && \\\n    apt-get install -y wget sudo gnupg2 && \\\n    echo \"deb http:\u002F\u002Fapt.postgresql.org\u002Fpub\u002Frepos\u002Fapt\u002F stretch-pgdg main\" > \u002Fetc\u002Fapt\u002Fsources.list.d\u002Fpsql.list && \\\n    wget -q -O- https:\u002F\u002Fwww.postgresql.org\u002Fmedia\u002Fkeys\u002FACCC4CF8.asc | \\\n    apt-key add - && \\\n    apt-get update && \\\n    apt-get dist-upgrade -y && \\\n    apt-get install -y git python3 python3-dev python3-setuptools python3-dateutil \\\n        python-mysqldb postgresql-server-dev-9.6 build-essential libxml2-dev \\\n        libxslt-dev libz-dev default-libmysqlclient-dev supervisor nginx && \\\n    easy_install3 -U pip && \\\n    mkdir -p \u002Fhealthchecks \"$DATA_DIR\" && \\\n    chown healthchecks:healthchecks -R \u002Fhealthchecks \"$DATA_DIR\" && \\\n    easy_install3 six && \\\n    pip install gunicorn && \\\n    sudo -u healthchecks -g healthchecks sh -c \"git clone https:\u002F\u002Fgithub.com\u002Fhealthchecks\u002Fhealthchecks.git \u002Fhealthchecks && \\\n    cd \u002Fhealthchecks && \\\n    git checkout $HEALTHCHECKS_VERSION && \\\n    pip install -r requirements.txt --user && \\\n    pip install mysqlclient --user\" && \\\n    apt-get --purge remove -y build-essential python3-dev gnupg2 && \\\n    apt-get -q autoremove -y && \\\n    rm -rf \u002Ftmp\u002F*\n\nCOPY entrypoint.sh \u002Fentrypoint.sh\nCOPY includes\u002Fscripts\u002F \u002Fusr\u002Flocal\u002Fbin\u002F\nCOPY includes\u002Fsupervisor\u002F \u002Fetc\u002Fsupervisor\u002F\nCOPY includes\u002Fnginx\u002F \u002Fetc\u002Fnginx\u002F\n\nRUN chown -R healthchecks:healthchecks \\\n  \u002Fetc\u002Fnginx \\\n  \u002Fvar\u002Flib\u002Fnginx \\\n  \u002Fvar\u002Flog \\\n  \u002Frun\n\nUSER 1000\n\nVOLUME [\"$DATA_DIR\"]\n\nEXPOSE 8000\u002Ftcp\n\nENTRYPOINT [\"\u002Fentrypoint.sh\"]\n\nCMD [\"app:run\"]\n",[567,47856,47857,47864,47872,47876,47887,47896,47906,47914,47918,47931,47947,47952,47957,47967,47972,47977,47981,47986,47991,47996,48001,48006,48015,48024,48029,48034,48042,48047,48052,48057,48064,48069,48074,48079,48083,48090,48097,48104,48111,48115,48122,48127,48132,48137,48142,48146,48153,48157,48167,48171,48178,48182,48193,48197],{"__ignoreMap":743},[747,47858,47859,47861],{"class":749,"line":750},[747,47860,9020],{"class":1895},[747,47862,47863],{"class":1640}," debian:stretch\n",[747,47865,47866,47868,47870],{"class":749,"line":761},[747,47867,47667],{"class":1895},[747,47869,47670],{"class":1640},[747,47871,47673],{"class":802},[747,47873,47874],{"class":749,"line":769},[747,47875,1255],{"emptyLinePlaceholder":1254},[747,47877,47878,47880,47882,47885],{"class":749,"line":776},[747,47879,9032],{"class":1895},[747,47881,9259],{"class":1640},[747,47883,47884],{"class":802},"\"\u002Fdata\"",[747,47886,1641],{"class":1640},[747,47888,47889,47892,47894],{"class":749,"line":784},[747,47890,47891],{"class":1640},"    HEALTHCHECKS_VERSION=",[747,47893,9145],{"class":802},[747,47895,1641],{"class":1640},[747,47897,47898,47901,47904],{"class":749,"line":790},[747,47899,47900],{"class":1640},"    HEALTHCHECKS_USER=",[747,47902,47903],{"class":802},"\"1000\"",[747,47905,1641],{"class":1640},[747,47907,47908,47911],{"class":749,"line":796},[747,47909,47910],{"class":1640},"    HEALTHCHECKS_GROUP=",[747,47912,47913],{"class":802},"\"1000\"\n",[747,47915,47916],{"class":749,"line":806},[747,47917,1255],{"emptyLinePlaceholder":1254},[747,47919,47920,47922,47925,47928],{"class":749,"line":814},[747,47921,9065],{"class":1895},[747,47923,47924],{"class":1640}," groupadd -g ",[747,47926,47927],{"class":802},"\"$HEALTHCHECKS_GROUP\"",[747,47929,47930],{"class":1640}," healthchecks && \\\n",[747,47932,47933,47936,47939,47942,47944],{"class":749,"line":822},[747,47934,47935],{"class":1640},"    useradd -u ",[747,47937,47938],{"class":802},"\"$HEALTHCHECKS_USER\"",[747,47940,47941],{"class":1640}," -g ",[747,47943,47927],{"class":802},[747,47945,47946],{"class":1640}," -m -d \u002Fhome\u002Fhealthchecks -s \u002Fbin\u002Fbash healthchecks && \\\n",[747,47948,47949],{"class":749,"line":830},[747,47950,47951],{"class":1640},"    apt-get update && \\\n",[747,47953,47954],{"class":749,"line":836},[747,47955,47956],{"class":1640},"    apt-get install -y wget sudo gnupg2 && \\\n",[747,47958,47959,47961,47964],{"class":749,"line":842},[747,47960,47758],{"class":1640},[747,47962,47963],{"class":802},"\"deb http:\u002F\u002Fapt.postgresql.org\u002Fpub\u002Frepos\u002Fapt\u002F stretch-pgdg main\"",[747,47965,47966],{"class":1640}," > \u002Fetc\u002Fapt\u002Fsources.list.d\u002Fpsql.list && \\\n",[747,47968,47969],{"class":749,"line":850},[747,47970,47971],{"class":1640},"    wget -q -O- https:\u002F\u002Fwww.postgresql.org\u002Fmedia\u002Fkeys\u002FACCC4CF8.asc | \\\n",[747,47973,47974],{"class":749,"line":863},[747,47975,47976],{"class":1640},"    apt-key add - && \\\n",[747,47978,47979],{"class":749,"line":869},[747,47980,47951],{"class":1640},[747,47982,47983],{"class":749,"line":877},[747,47984,47985],{"class":1640},"    apt-get dist-upgrade -y && \\\n",[747,47987,47988],{"class":749,"line":1015},[747,47989,47990],{"class":1640},"    apt-get install -y git python3 python3-dev python3-setuptools python3-dateutil \\\n",[747,47992,47993],{"class":749,"line":1021},[747,47994,47995],{"class":1640},"        python-mysqldb postgresql-server-dev-9.6 build-essential libxml2-dev \\\n",[747,47997,47998],{"class":749,"line":1027},[747,47999,48000],{"class":1640},"        libxslt-dev libz-dev default-libmysqlclient-dev supervisor nginx && \\\n",[747,48002,48003],{"class":749,"line":1033},[747,48004,48005],{"class":1640},"    easy_install3 -U pip && \\\n",[747,48007,48008,48011,48013],{"class":749,"line":1039},[747,48009,48010],{"class":1640},"    mkdir -p \u002Fhealthchecks ",[747,48012,9301],{"class":802},[747,48014,9119],{"class":1640},[747,48016,48017,48020,48022],{"class":749,"line":1054},[747,48018,48019],{"class":1640},"    chown healthchecks:healthchecks -R \u002Fhealthchecks ",[747,48021,9301],{"class":802},[747,48023,9119],{"class":1640},[747,48025,48026],{"class":749,"line":1060},[747,48027,48028],{"class":1640},"    easy_install3 six && \\\n",[747,48030,48031],{"class":749,"line":1066},[747,48032,48033],{"class":1640},"    pip install gunicorn && \\\n",[747,48035,48036,48039],{"class":749,"line":1081},[747,48037,48038],{"class":1640},"    sudo -u healthchecks -g healthchecks sh -c ",[747,48040,48041],{"class":802},"\"git clone https:\u002F\u002Fgithub.com\u002Fhealthchecks\u002Fhealthchecks.git \u002Fhealthchecks && \\\n",[747,48043,48044],{"class":749,"line":1087},[747,48045,48046],{"class":802},"    cd \u002Fhealthchecks && \\\n",[747,48048,48049],{"class":749,"line":1102},[747,48050,48051],{"class":802},"    git checkout $HEALTHCHECKS_VERSION && \\\n",[747,48053,48054],{"class":749,"line":1110},[747,48055,48056],{"class":802},"    pip install -r requirements.txt --user && \\\n",[747,48058,48059,48062],{"class":749,"line":1117},[747,48060,48061],{"class":802},"    pip install mysqlclient --user\"",[747,48063,9119],{"class":1640},[747,48065,48066],{"class":749,"line":1123},[747,48067,48068],{"class":1640},"    apt-get --purge remove -y build-essential python3-dev gnupg2 && \\\n",[747,48070,48071],{"class":749,"line":1129},[747,48072,48073],{"class":1640},"    apt-get -q autoremove -y && \\\n",[747,48075,48076],{"class":749,"line":1142},[747,48077,48078],{"class":1640},"    rm -rf \u002Ftmp\u002F*\n",[747,48080,48081],{"class":749,"line":1150},[747,48082,1255],{"emptyLinePlaceholder":1254},[747,48084,48085,48087],{"class":749,"line":1157},[747,48086,9053],{"class":1895},[747,48088,48089],{"class":1640}," entrypoint.sh \u002Fentrypoint.sh\n",[747,48091,48092,48094],{"class":749,"line":1163},[747,48093,9053],{"class":1895},[747,48095,48096],{"class":1640}," includes\u002Fscripts\u002F \u002Fusr\u002Flocal\u002Fbin\u002F\n",[747,48098,48099,48101],{"class":749,"line":1168},[747,48100,9053],{"class":1895},[747,48102,48103],{"class":1640}," includes\u002Fsupervisor\u002F \u002Fetc\u002Fsupervisor\u002F\n",[747,48105,48106,48108],{"class":749,"line":1174},[747,48107,9053],{"class":1895},[747,48109,48110],{"class":1640}," includes\u002Fnginx\u002F \u002Fetc\u002Fnginx\u002F\n",[747,48112,48113],{"class":749,"line":1480},[747,48114,1255],{"emptyLinePlaceholder":1254},[747,48116,48117,48119],{"class":749,"line":1491},[747,48118,9065],{"class":1895},[747,48120,48121],{"class":1640}," chown -R healthchecks:healthchecks \\\n",[747,48123,48124],{"class":749,"line":1496},[747,48125,48126],{"class":1640},"  \u002Fetc\u002Fnginx \\\n",[747,48128,48129],{"class":749,"line":1502},[747,48130,48131],{"class":1640},"  \u002Fvar\u002Flib\u002Fnginx \\\n",[747,48133,48134],{"class":749,"line":1510},[747,48135,48136],{"class":1640},"  \u002Fvar\u002Flog \\\n",[747,48138,48139],{"class":749,"line":1520},[747,48140,48141],{"class":1640},"  \u002Frun\n",[747,48143,48144],{"class":749,"line":1525},[747,48145,1255],{"emptyLinePlaceholder":1254},[747,48147,48148,48151],{"class":749,"line":1533},[747,48149,48150],{"class":1895},"USER",[747,48152,7589],{"class":1640},[747,48154,48155],{"class":749,"line":1539},[747,48156,1255],{"emptyLinePlaceholder":1254},[747,48158,48159,48161,48163,48165],{"class":749,"line":1549},[747,48160,9177],{"class":1895},[747,48162,4262],{"class":1640},[747,48164,9301],{"class":802},[747,48166,4268],{"class":1640},[747,48168,48169],{"class":749,"line":1554},[747,48170,1255],{"emptyLinePlaceholder":1254},[747,48172,48173,48175],{"class":749,"line":1562},[747,48174,9198],{"class":1895},[747,48176,48177],{"class":1640}," 8000\u002Ftcp\n",[747,48179,48180],{"class":749,"line":1568},[747,48181,1255],{"emptyLinePlaceholder":1254},[747,48183,48184,48186,48188,48191],{"class":749,"line":1577},[747,48185,9210],{"class":1895},[747,48187,4262],{"class":1640},[747,48189,48190],{"class":802},"\"\u002Fentrypoint.sh\"",[747,48192,4268],{"class":1640},[747,48194,48195],{"class":749,"line":1582},[747,48196,1255],{"emptyLinePlaceholder":1254},[747,48198,48199,48201,48203,48205],{"class":749,"line":1588},[747,48200,9482],{"class":1895},[747,48202,4262],{"class":1640},[747,48204,9487],{"class":802},[747,48206,4268],{"class":1640},[523,48208,48209,48212],{},[584,48210,48211],{},"Don't worry we're going to start with a simple and basic image!"," :-)",[613,48214,9499],{"id":9498},[6072,48216,48217,48227,48231],{},[523,48218,48219,8939,48221],{},[584,48220,2951],{},[527,48222,48225],{"href":48223,"rel":48224},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-container-docker-kubernetes\u002Ftree\u002Fmaster\u002Fdockerfile202",[531],[567,48226,9510],{},[523,48228,48229],{},[584,48230,9515],{},[523,48232,48233,48234,9519,48236,48240],{},"If you have trouble writing a ",[567,48235,8959],{},[527,48237,48239],{"href":9522,"rel":48238},[531],"Dockerfile Docs"," for the full \"syntax\".",[523,48242,9527,48243,9531],{},[567,48244,9530],{},[523,48246,9534,48247,9537],{},[567,48248,9530],{},[523,48250,48251,856],{},[584,48252,9542],{},[738,48254,48256],{"className":9011,"code":48255,"language":9013,"meta":743,"style":743},"# golang image where workspace (GOPATH) configured at \u002Fgo.\nFROM golang:1.12.2-stretch\n\n# Add a label to the image so everyone knows who is maintaing it.\nLABEL maintainer=\"John Doe \u003Cjohn.doe@example.com>\"\n\n# Copy the local package files to the container’s workspace.\nADD . \u002Fgo\u002Fsrc\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-container-docker-kubernetes\n\n# Build the project inside the container.\nRUN go install github.com\u002Fgalexrt\u002Fworkshop-container-docker-kubernetes\n\n# Run the  command when the container starts.\nENTRYPOINT [\"\u002Fgo\u002Fbin\u002Fworkshop-container-docker-kubernetes\"]\n\n# http server listens on port 8080.\nEXPOSE 8080\n",[567,48257,48258,48263,48270,48274,48279,48288,48292,48297,48304,48308,48313,48320,48324,48329,48340,48344,48349],{"__ignoreMap":743},[747,48259,48260],{"class":749,"line":750},[747,48261,48262],{"class":772},"# golang image where workspace (GOPATH) configured at \u002Fgo.\n",[747,48264,48265,48267],{"class":749,"line":761},[747,48266,9020],{"class":1895},[747,48268,48269],{"class":1640}," golang:1.12.2-stretch\n",[747,48271,48272],{"class":749,"line":769},[747,48273,1255],{"emptyLinePlaceholder":1254},[747,48275,48276],{"class":749,"line":776},[747,48277,48278],{"class":772},"# Add a label to the image so everyone knows who is maintaing it.\n",[747,48280,48281,48283,48285],{"class":749,"line":784},[747,48282,47667],{"class":1895},[747,48284,47670],{"class":1640},[747,48286,48287],{"class":802},"\"John Doe \u003Cjohn.doe@example.com>\"\n",[747,48289,48290],{"class":749,"line":790},[747,48291,1255],{"emptyLinePlaceholder":1254},[747,48293,48294],{"class":749,"line":796},[747,48295,48296],{"class":772},"# Copy the local package files to the container’s workspace.\n",[747,48298,48299,48301],{"class":749,"line":806},[747,48300,9669],{"class":1895},[747,48302,48303],{"class":1640}," . \u002Fgo\u002Fsrc\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-container-docker-kubernetes\n",[747,48305,48306],{"class":749,"line":814},[747,48307,1255],{"emptyLinePlaceholder":1254},[747,48309,48310],{"class":749,"line":822},[747,48311,48312],{"class":772},"# Build the project inside the container.\n",[747,48314,48315,48317],{"class":749,"line":830},[747,48316,9065],{"class":1895},[747,48318,48319],{"class":1640}," go install github.com\u002Fgalexrt\u002Fworkshop-container-docker-kubernetes\n",[747,48321,48322],{"class":749,"line":836},[747,48323,1255],{"emptyLinePlaceholder":1254},[747,48325,48326],{"class":749,"line":842},[747,48327,48328],{"class":772},"# Run the  command when the container starts.\n",[747,48330,48331,48333,48335,48338],{"class":749,"line":850},[747,48332,9210],{"class":1895},[747,48334,4262],{"class":1640},[747,48336,48337],{"class":802},"\"\u002Fgo\u002Fbin\u002Fworkshop-container-docker-kubernetes\"",[747,48339,4268],{"class":1640},[747,48341,48342],{"class":749,"line":863},[747,48343,1255],{"emptyLinePlaceholder":1254},[747,48345,48346],{"class":749,"line":869},[747,48347,48348],{"class":772},"# http server listens on port 8080.\n",[747,48350,48351,48353],{"class":749,"line":877},[747,48352,9198],{"class":1895},[747,48354,9628],{"class":1640},[6072,48356,48357,48361],{},[523,48358,48359],{},[584,48360,2957],{},[668,48362,48363,48368,48377,48381,48388,48394,48398,48404],{},[638,48364,48365,48367],{},[567,48366,9639],{}," - Sets the baseimage.",[638,48369,48370,48373,48374,3052],{},[567,48371,48372],{},"LABEL ...=..."," - Labels to add to the image, in key value pairs (",[567,48375,48376],{},"KEY=VALUE",[638,48378,48379,9646],{},[567,48380,9645],{},[638,48382,48383,9652,48385,48387],{},[567,48384,9651],{},[567,48386,9053],{},", but target can be \"online\" and if it is an archive, it will be extracted.",[638,48389,48390,9676,48392,3052],{},[567,48391,9675],{},[567,48393,9679],{},[638,48395,48396,9685],{},[567,48397,9684],{},[638,48399,48400,9691,48402,1909],{},[567,48401,9690],{},[567,48403,9210],{},[638,48405,48406,48409,48410,6374,48412,1909],{},[567,48407,48408],{},"EXPOSE 8080\u002FTCP NUMBER\u002FPROTOCOL..."," - Expose a port (This is important when linking containers together, as otherwise the port would not reachable from the other containers). Protocol can be ",[567,48411,30095],{},[567,48413,30098],{},[523,48415,9710,48416,48418],{},[567,48417,9713],{},", but explaining this is beyond the scope of this training. Thanks for understanding!",[6072,48420,48421,48433],{},[523,48422,8764,48423,48426,48427,48430,48431,1909],{},[567,48424,48425],{},"ONBUILD"," instruction adds to the image a ",[3049,48428,48429],{},"trigger"," instruction to be executed at a later time, when the image is used as the base for another build. The trigger will be executed in the context of the downstream build, as if it had been inserted immediately after the FROM instruction in the downstream ",[567,48432,8959],{},[523,48434,48435,48436],{},"– Quote from ",[527,48437,48440],{"href":48438,"rel":48439},"https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Freference\u002Fbuilder\u002F#onbuild",[531],"Docker Dockerfile Documentation - ONBUILD section",[523,48442,9717,48443,9721],{},[567,48444,9720],{},[738,48446,48448],{"className":1621,"code":48447,"language":1623,"meta":743,"style":743},"docker build -f Dockerfile -t workshop-gowebapp .\n",[567,48449,48450],{"__ignoreMap":743},[747,48451,48452,48454,48456,48458,48460,48462,48465],{"class":749,"line":750},[747,48453,3257],{"class":1630},[747,48455,9733],{"class":802},[747,48457,1934],{"class":802},[747,48459,9744],{"class":802},[747,48461,9736],{"class":802},[747,48463,48464],{"class":802}," workshop-gowebapp",[747,48466,9747],{"class":802},[6072,48468,48469,48473],{},[523,48470,48471],{},[584,48472,2957],{},[668,48474,48475,48480,48497,48503],{},[638,48476,48477,48479],{},[567,48478,9758],{}," - Used to build Container images.",[638,48481,48482,48484,48485,9771,48487,48489,48490],{},[567,48483,9764],{}," - Specify the name (with an optional tag) of the image, you are creating. ",[567,48486,8898],{},[567,48488,9774],{},". This flag in itself is optional.\n",[668,48491,48492],{},[638,48493,48494,48496],{},[584,48495,6189],{}," This options is useful when manually building and pushing a Container image to a repository, so you can specify the name of the image as you want.",[638,48498,48499,9780,48501,9783],{},[567,48500,9779],{},[567,48502,8959],{},[638,48504,48505,9788,48507,9792,48509,6374,48511,9797,48513,9800],{},[567,48506,1909],{},[584,48508,9791],{},[567,48510,9669],{},[567,48512,9053],{},[567,48514,8959],{},[523,48516,48517,48518,1909],{},"As you can see, it isn't hard to build your first Container images.\nIf you want to see more advanced examples, you can find more examples in my GitHub repositories ",[527,48519,3396],{"href":48520,"rel":48521},"https:\u002F\u002Fgithub.com\u002Fsearch?q=user%3Agalexrt+docker-",[531],[613,48523,48525],{"id":48524},"commands-you-need-to-know-when-working-with-container-images","Commands you need to know when working with Container images",[3126,48527,48529],{"id":48528},"listing-the-container-images","Listing the Container images",[523,48531,48532,48533,28768],{},"To list the Container images, use the ",[567,48534,10064],{},[738,48536,48538],{"className":1621,"code":48537,"language":1623,"meta":743,"style":743},"docker images\n",[567,48539,48540],{"__ignoreMap":743},[747,48541,48542,48544],{"class":749,"line":750},[747,48543,3257],{"class":1630},[747,48545,10078],{"class":802},[523,48547,48548],{},"The command can also take a name of an image, but then it will only show quick overview of the given image.",[3126,48550,48552],{"id":48551},"deleting-a-container-image","Deleting a Container image",[523,48554,48555,48556,48558,48559,28768],{},"To delete a Container image, you use the ",[567,48557,10194],{}," command. The syntax is basically the same as for the ",[567,48560,10198],{},[738,48562,48563],{"className":1621,"code":10202,"language":1623,"meta":743,"style":743},[567,48564,48565],{"__ignoreMap":743},[747,48566,48567,48569,48571,48573],{"class":749,"line":750},[747,48568,3257],{"class":1630},[747,48570,10211],{"class":802},[747,48572,10214],{"class":802},[747,48574,10217],{"class":1640},[6072,48576,48577,48581],{},[523,48578,48579],{},[584,48580,2957],{},[668,48582,48583,48587],{},[638,48584,48585,10229],{},[567,48586,10228],{},[638,48588,48589,10235],{},[567,48590,10234],{},[3126,48592,48594],{"id":48593},"build-a-container-image-from-dockerfile","Build a Container image from Dockerfile",[523,48596,48597],{},"Use this command to build images:",[738,48599,48600],{"className":1621,"code":10245,"language":1623,"meta":743,"style":743},[567,48601,48602],{"__ignoreMap":743},[747,48603,48604,48606,48608,48610,48612,48614,48616],{"class":749,"line":750},[747,48605,3257],{"class":1630},[747,48607,9733],{"class":802},[747,48609,9736],{"class":802},[747,48611,10258],{"class":802},[747,48613,1934],{"class":802},[747,48615,10263],{"class":802},[747,48617,10266],{"class":802},[6072,48619,48620,48624],{},[523,48621,48622],{},[584,48623,2957],{},[668,48625,48626,48630,48641,48647],{},[638,48627,48628,10277],{},[567,48629,9758],{},[638,48631,48632,10282,48634,10285,48636,10289,48639,10292],{},[567,48633,9764],{},[567,48635,8898],{},[527,48637,3396],{"href":48638},"#Image-Names-explained",[584,48640,2957],{},[638,48642,48643,10298,48645,10301],{},[567,48644,10297],{},[567,48646,8959],{},[638,48648,48649,48651,48652,11500],{},[567,48650,10306],{}," - The build root path. Files in the directory will be added to the Docker build environment, but not to the image itself. The files are only added when the specified Dockerfile has instructions to do so. You can't go deeper than the ",[567,48653,10306],{},[613,48655,48657],{"id":48656},"lets-build-your-first-container-image","Let's build your first Container image",[523,48659,10331,48660,10334,48662,10337,48664,1909],{},[567,48661,8959],{},[567,48663,9530],{},[567,48665,8972],{},[523,48667,10342,48668,10346,48670,7258],{},[567,48669,10345],{},[527,48671,3396],{"href":48672},"#nginx-Dockerfile",[738,48674,48675],{"className":9011,"code":10352,"language":9013,"meta":743,"style":743},[567,48676,48677,48683,48687,48693,48697],{"__ignoreMap":743},[747,48678,48679,48681],{"class":749,"line":750},[747,48680,9020],{"class":1895},[747,48682,10361],{"class":1640},[747,48684,48685],{"class":749,"line":761},[747,48686,1255],{"emptyLinePlaceholder":1254},[747,48688,48689,48691],{"class":749,"line":769},[747,48690,9065],{"class":1895},[747,48692,10361],{"class":1640},[747,48694,48695],{"class":749,"line":776},[747,48696,1255],{"emptyLinePlaceholder":1254},[747,48698,48699,48701,48703,48705],{"class":749,"line":784},[747,48700,9210],{"class":1895},[747,48702,4262],{"class":1640},[747,48704,10384],{"class":802},[747,48706,4268],{"class":1640},[523,48708,10389],{},[738,48710,48711],{"className":1621,"code":10392,"language":1623,"meta":743,"style":743},[567,48712,48713],{"__ignoreMap":743},[747,48714,48715,48717,48719,48721,48723],{"class":749,"line":750},[747,48716,3257],{"class":1630},[747,48718,9733],{"class":802},[747,48720,9736],{"class":802},[747,48722,10405],{"class":802},[747,48724,9747],{"class":802},[6072,48726,48727,48733],{},[523,48728,48729],{},[584,48730,10412,48731],{},[567,48732,10415],{},[738,48734,48735],{"className":1621,"code":743,"language":1623,"meta":743,"style":743},[567,48736,48737],{"__ignoreMap":743},[747,48738],{"class":749,"line":750},[738,48740,48743],{"className":48741,"code":48742,"language":12479},[12477],"\nThe build should go successfully, when you filled in the blanks correctly. Let's run the image to see if it is working, the container name will be `workshop-nginx`:\n\n```bash\ndocker run \\\n    --name=workshop-nginx \\\n    -d \\\n    -p 80:80 \\\n    workshop-nginx\n",[567,48744,48742],{"__ignoreMap":743},[523,48746,10470,48747,10473],{},[567,48748,6446],{},[738,48750,48751],{"className":1621,"code":10476,"language":1623,"meta":743,"style":743},[567,48752,48753],{"__ignoreMap":743},[747,48754,48755,48757,48759],{"class":749,"line":750},[747,48756,3257],{"class":1630},[747,48758,5902],{"class":802},[747,48760,10487],{"class":802},[523,48762,10490,48763,1909],{},[567,48764,5819],{},[6072,48766,48767,48771],{},[523,48768,48769],{},[584,48770,2957],{},[668,48772,48773,48781],{},[638,48774,48775,10504,48777,48780],{},[567,48776,10503],{},[567,48778,48779],{},"ps "," command, but for the containers.",[638,48782,48783,10512],{},[567,48784,4164],{},[523,48786,48787,48788,10519],{},"You should see that the container you started, has exited.\nThere's a simple reason, why the container exited\u002F stopped. When running a command as the entrypoint, it has to stay running, not fork to background. When the process forks to background, Docker will think the process has stopped and the container status will be set to ",[567,48789,10518],{},[523,48791,10522,48792,10525,48794,10529,48796,10532,48798,3052],{},[567,48793,9530],{},[567,48795,10528],{},[567,48797,9210],{},[567,48799,8959],{},[523,48801,10537,48802,10541,48804,10544,48806,10548,48808,10551],{},[567,48803,10540],{},[567,48805,10540],{},[584,48807,10547],{},[567,48809,9210],{},[738,48811,48812],{"className":1621,"code":10554,"language":1623,"meta":743,"style":743},[567,48813,48814],{"__ignoreMap":743},[747,48815,48816,48818,48820,48822,48824,48826,48828,48830,48832,48834,48836,48838,48840,48842],{"class":749,"line":750},[747,48817,9210],{"class":1630},[747,48819,4262],{"class":1640},[747,48821,3892],{"class":757},[747,48823,9530],{"class":802},[747,48825,3892],{"class":757},[747,48827,714],{"class":1640},[747,48829,3892],{"class":757},[747,48831,10575],{"class":802},[747,48833,3892],{"class":757},[747,48835,10580],{"class":802},[747,48837,969],{"class":757},[747,48839,10585],{"class":802},[747,48841,3892],{"class":757},[747,48843,4268],{"class":802},[523,48845,48846,48847,48849,48850,10597],{},"Let's rebuild the image (same ",[567,48848,9720],{}," command) and run it again. Open ",[567,48851,48852],{},"http:\u002F\u002FIP_ADDRESS_OF_THE_SERVER:8080",[523,48854,10600,48855,10604,48857,8301,48859,10609],{},[567,48856,10603],{},[567,48858,10603],{},[567,48860,9510],{},[523,48862,10612,48863,10616,48865,48867],{},[567,48864,10615],{},[567,48866,4203],{}," command, but don't forget add the argument before the image name.\nYour command should look like this:",[738,48869,48871],{"className":1621,"code":48870,"language":1623,"meta":743,"style":743},"docker run \\\n    --name=workshop-nginx \\\n    -d \\\n    -p 8080:80 \\\n    -v \"$(pwd)\":\"\u002Fusr\u002Fshare\u002Fnginx\u002Fhtml\" \\\n    workshop-nginx\n",[567,48872,48873,48881,48888,48894,48902,48922],{"__ignoreMap":743},[747,48874,48875,48877,48879],{"class":749,"line":750},[747,48876,3257],{"class":1630},[747,48878,3665],{"class":802},[747,48880,1641],{"class":1640},[747,48882,48883,48886],{"class":749,"line":761},[747,48884,48885],{"class":802},"    --name=workshop-nginx",[747,48887,1641],{"class":1640},[747,48889,48890,48892],{"class":749,"line":769},[747,48891,5866],{"class":802},[747,48893,1641],{"class":1640},[747,48895,48896,48898,48900],{"class":749,"line":776},[747,48897,6614],{"class":802},[747,48899,10660],{"class":802},[747,48901,1641],{"class":1640},[747,48903,48904,48906,48908,48910,48912,48914,48916,48918,48920],{"class":749,"line":784},[747,48905,6139],{"class":802},[747,48907,10669],{"class":757},[747,48909,10672],{"class":4574},[747,48911,10675],{"class":757},[747,48913,856],{"class":802},[747,48915,3892],{"class":757},[747,48917,10682],{"class":802},[747,48919,3892],{"class":757},[747,48921,1641],{"class":1640},[747,48923,48924],{"class":749,"line":790},[747,48925,10467],{"class":802},[523,48927,10711,48928,10714,48930,10717,48932,48934,48935,48937,48938,10727],{},[567,48929,10427],{},[567,48931,10427],{},[567,48933,10682],{},".\nRun the command and if everything went well after a few seconds, you can now open ",[567,48936,48852],{}," in the browser. You should see the contents of the previously created ",[567,48939,10603],{},[613,48941,10731],{"id":10730},[523,48943,48944],{},"If you are for example creating a new CMS written in PHP, you could create a Dockerfile for it so that a Container image can be created for it.\nOn every push to the git repository of the project, the image could be built and automatic checks could be run, to ensure every feature is working fine.",[523,48946,48947,48948,856],{},"For example Travis CI has switched big parts of their build infrastructure to Docker containers.\nQuoting Travis CIsome headings from their ",[527,48949,10742],{"href":10740,"rel":48950},[531],[6072,48952,48953],{},[523,48954,10747],{},[523,48956,48957],{},"As we can see, containers can be better than VMs depending on the use case.",[523,48959,48960],{},"Due to the lower resource usage, containers are good for the development workflow, making it faster and cheaper in the end.",[2979,48962],{},[535,48964,48966,48967],{"id":48965},"composing-containers-together-with-docker-compose","\"Composing\" containers together with ",[567,48968,2936],{},[613,48970,48972],{"id":48971},"making-multi-container-applications-easier-to-start","Making multi container applications easier to start",[6072,48974,48975],{},[523,48976,48977,8939,48979],{},[584,48978,2951],{},[527,48980,48983],{"href":48981,"rel":48982},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-container-docker-kubernetes\u002Ftree\u002Fmaster\u002Fcompose101",[531],[567,48984,11258],{},[523,48986,48987,48988,48990,48991,10811,48993,10814,48995,10818,48997,48999,49000,1909],{},"To remove the process of typing all ",[567,48989,4203],{}," and so on, commands to start the containers, ",[567,48992,2936],{},[567,48994,2936],{},[3049,48996,10817],{},[567,48998,10821],{}," is YAML. As it is just YAML, you can basically just use a YAML syntax checker, e.g., ",[527,49001,28659],{"href":10829,"rel":49002},[531],[523,49004,10833,49005,49007],{},[567,49006,10821],{}," for our MariaDB database server, WordPress and as an extra we'll add phpMyAdmin to it too.",[523,49009,10839,49010,10842,49012,49014,49015,49018,49019,7258],{},[567,49011,10821],{},[567,49013,10345],{}," with the correct answer (the solution is available in the ",[567,49016,49017],{},"docker-compose-solution.yml"," file of task ",[567,49020,11258],{},[738,49022,49024],{"className":740,"code":49023,"language":742,"meta":743,"style":743},"version: '3.1'\nservices:\n  # mariadb database image configuration, see https:\u002F\u002Fhub.docker.com\u002F_\u002Fmariadb\n  database:\n    image: \"mariadb:10.4.3-bionic\"\n    environment:\n      MYSQL_DATABASE: wordpress\n      MYSQL_USER: wordpress\n      MYSQL_PASSWORD: wordpress\n      MYSQL_ROOT_PASSWORD: secure_password\n      MYSQL_ROOT_HOST: '%'\n    volumes:\n      - \"\u002Fopt\u002Fdocker\u002Fdatabase:\u002Fvar\u002Flib\u002Fmysql:rw\"\n  # wordpress image configuration, see https:\u002F\u002Fhub.docker.com\u002Fr\u002F_\u002Fwordpress\u002F\n  wordpress:\n    image: \"wordpress:5.1-php7.1-apache\"\n    ports:\n      - 8080:80\n    environment:\n      WORDPRESS_DB_HOST: \"__BLANK__\"\n      WORDPRESS_DB_NAME: __BLANK__\n      WORDPRESS_DB_USER: __BLANK__\n      WORDPRESS_DB_PASSWORD: __BLANK__\n      WORDPRESS_AUTH_KEY: SECURE_AUTH_KEY\n      WORDPRESS_LOGGED_IN_KEY: SECURE_LOGGED_IN_KEY\n      WORDPRESS_AUTH_SALT: SECURE_AUTH_SALT\n      WORDPRESS_LOGGED_IN_SALT: SECURE_LOGGED_IN_SALT\n  # phpmyadmin image configuration, see https:\u002F\u002Fhub.docker.com\u002Fr\u002Fphpmyadmin\u002Fphpmyadmin\u002F\n  phpmyadmin:\n    image: \"phpmyadmin\u002Fphpmyadmin:4.8\"\n    ports:\n      - 8181:80\n    environment:\n      PMA_HOST: database\n      PMA_USER: root\n      PMA_PASSWORD: secure_password\n",[567,49025,49026,49039,49045,49050,49057,49069,49075,49083,49091,49099,49108,49121,49127,49138,49143,49149,49161,49167,49173,49179,49191,49199,49207,49215,49223,49231,49239,49247,49252,49258,49271,49277,49283,49289,49297,49305],{"__ignoreMap":743},[747,49027,49028,49030,49032,49034,49037],{"class":749,"line":750},[747,49029,10866],{"class":753},[747,49031,856],{"class":757},[747,49033,3537],{"class":757},[747,49035,49036],{"class":802},"3.1",[747,49038,13042],{"class":757},[747,49040,49041,49043],{"class":749,"line":761},[747,49042,10880],{"class":753},[747,49044,758],{"class":757},[747,49046,49047],{"class":749,"line":769},[747,49048,49049],{"class":772},"  # mariadb database image configuration, see https:\u002F\u002Fhub.docker.com\u002F_\u002Fmariadb\n",[747,49051,49052,49055],{"class":749,"line":776},[747,49053,49054],{"class":753},"  database",[747,49056,758],{"class":757},[747,49058,49059,49061,49063,49065,49067],{"class":749,"line":784},[747,49060,10899],{"class":753},[747,49062,856],{"class":757},[747,49064,969],{"class":757},[747,49066,43149],{"class":802},[747,49068,975],{"class":757},[747,49070,49071,49073],{"class":749,"line":790},[747,49072,10909],{"class":753},[747,49074,758],{"class":757},[747,49076,49077,49079,49081],{"class":749,"line":796},[747,49078,10926],{"class":753},[747,49080,856],{"class":757},[747,49082,6540],{"class":802},[747,49084,49085,49087,49089],{"class":749,"line":806},[747,49086,10935],{"class":753},[747,49088,856],{"class":757},[747,49090,6540],{"class":802},[747,49092,49093,49095,49097],{"class":749,"line":814},[747,49094,10944],{"class":753},[747,49096,856],{"class":757},[747,49098,6540],{"class":802},[747,49100,49101,49103,49105],{"class":749,"line":822},[747,49102,10916],{"class":753},[747,49104,856],{"class":757},[747,49106,49107],{"class":802}," secure_password\n",[747,49109,49110,49113,49115,49117,49119],{"class":749,"line":830},[747,49111,49112],{"class":753},"      MYSQL_ROOT_HOST",[747,49114,856],{"class":757},[747,49116,3537],{"class":757},[747,49118,40222],{"class":802},[747,49120,13042],{"class":757},[747,49122,49123,49125],{"class":749,"line":836},[747,49124,10953],{"class":753},[747,49126,758],{"class":757},[747,49128,49129,49131,49133,49136],{"class":749,"line":842},[747,49130,799],{"class":757},[747,49132,969],{"class":757},[747,49134,49135],{"class":802},"\u002Fopt\u002Fdocker\u002Fdatabase:\u002Fvar\u002Flib\u002Fmysql:rw",[747,49137,975],{"class":757},[747,49139,49140],{"class":749,"line":850},[747,49141,49142],{"class":772},"  # wordpress image configuration, see https:\u002F\u002Fhub.docker.com\u002Fr\u002F_\u002Fwordpress\u002F\n",[747,49144,49145,49147],{"class":749,"line":863},[747,49146,10976],{"class":753},[747,49148,758],{"class":757},[747,49150,49151,49153,49155,49157,49159],{"class":749,"line":869},[747,49152,10899],{"class":753},[747,49154,856],{"class":757},[747,49156,969],{"class":757},[747,49158,45764],{"class":802},[747,49160,975],{"class":757},[747,49162,49163,49165],{"class":749,"line":877},[747,49164,10991],{"class":753},[747,49166,758],{"class":757},[747,49168,49169,49171],{"class":749,"line":1015},[747,49170,799],{"class":757},[747,49172,11000],{"class":802},[747,49174,49175,49177],{"class":749,"line":1021},[747,49176,10909],{"class":753},[747,49178,758],{"class":757},[747,49180,49181,49183,49185,49187,49189],{"class":749,"line":1027},[747,49182,11011],{"class":753},[747,49184,856],{"class":757},[747,49186,969],{"class":757},[747,49188,10345],{"class":802},[747,49190,975],{"class":757},[747,49192,49193,49195,49197],{"class":749,"line":1033},[747,49194,11021],{"class":753},[747,49196,856],{"class":757},[747,49198,10361],{"class":802},[747,49200,49201,49203,49205],{"class":749,"line":1039},[747,49202,11030],{"class":753},[747,49204,856],{"class":757},[747,49206,10361],{"class":802},[747,49208,49209,49211,49213],{"class":749,"line":1054},[747,49210,11039],{"class":753},[747,49212,856],{"class":757},[747,49214,10361],{"class":802},[747,49216,49217,49219,49221],{"class":749,"line":1060},[747,49218,11048],{"class":753},[747,49220,856],{"class":757},[747,49222,11053],{"class":802},[747,49224,49225,49227,49229],{"class":749,"line":1066},[747,49226,11058],{"class":753},[747,49228,856],{"class":757},[747,49230,11063],{"class":802},[747,49232,49233,49235,49237],{"class":749,"line":1081},[747,49234,11068],{"class":753},[747,49236,856],{"class":757},[747,49238,11073],{"class":802},[747,49240,49241,49243,49245],{"class":749,"line":1087},[747,49242,11078],{"class":753},[747,49244,856],{"class":757},[747,49246,11083],{"class":802},[747,49248,49249],{"class":749,"line":1102},[747,49250,49251],{"class":772},"  # phpmyadmin image configuration, see https:\u002F\u002Fhub.docker.com\u002Fr\u002Fphpmyadmin\u002Fphpmyadmin\u002F\n",[747,49253,49254,49256],{"class":749,"line":1110},[747,49255,11106],{"class":753},[747,49257,758],{"class":757},[747,49259,49260,49262,49264,49266,49269],{"class":749,"line":1117},[747,49261,10899],{"class":753},[747,49263,856],{"class":757},[747,49265,969],{"class":757},[747,49267,49268],{"class":802},"phpmyadmin\u002Fphpmyadmin:4.8",[747,49270,975],{"class":757},[747,49272,49273,49275],{"class":749,"line":1123},[747,49274,10991],{"class":753},[747,49276,758],{"class":757},[747,49278,49279,49281],{"class":749,"line":1129},[747,49280,799],{"class":757},[747,49282,11130],{"class":802},[747,49284,49285,49287],{"class":749,"line":1142},[747,49286,10909],{"class":753},[747,49288,758],{"class":757},[747,49290,49291,49293,49295],{"class":749,"line":1150},[747,49292,11141],{"class":753},[747,49294,856],{"class":757},[747,49296,43796],{"class":802},[747,49298,49299,49301,49303],{"class":749,"line":1157},[747,49300,11151],{"class":753},[747,49302,856],{"class":757},[747,49304,11156],{"class":802},[747,49306,49307,49309,49311],{"class":749,"line":1163},[747,49308,11161],{"class":753},[747,49310,856],{"class":757},[747,49312,49107],{"class":802},[6072,49314,49315,49319],{},[523,49316,49317],{},[584,49318,2957],{},[668,49320,49321,49327,49332,49337,49342],{},[638,49322,49323,49326],{},[567,49324,49325],{},"database:"," - Name of the container.",[638,49328,49329,11216],{},[567,49330,49331],{},"  image:",[638,49333,49334,11222],{},[567,49335,49336],{},"  links: []",[638,49338,49339,11228],{},[567,49340,49341],{},"  ports: []",[638,49343,49344,49347,49348,3052],{},[567,49345,49346],{},"  environment: []"," - Key\u002F Value list of environment variables (Format: ",[567,49349,11237],{},[523,49351,49352,49353,587,49356,49359],{},"I have also added the environment variables ",[567,49354,49355],{},"DB_REMOTE_ROOT_NAME",[567,49357,49358],{},"DB_REMOTE_ROOT_PASS",", so that Admin can access the MariaDB server.",[3126,49361,49363],{"id":49362},"networking-changes","Networking Changes",[523,49365,49366,49367,49369,49370,49372,49373,49375,49376,49378],{},"As you might have spotted the above ",[567,49368,2936],{}," file does not have anything related to which ",[567,49371,14262],{}," to use in it.\nThat is because ",[567,49374,2936],{}," creates a ",[567,49377,14262],{}," based on the \"project name\" by default, meaning that there is no need in our case to create another network.",[613,49380,11247],{"id":11246},[6072,49382,49383],{},[523,49384,49385,8939,49387],{},[584,49386,2951],{},[527,49388,49390],{"href":48981,"rel":49389},[531],[567,49391,11258],{},[523,49393,49394,49395,49397,49398,49401],{},"To run\u002F start the content of the filled out ",[567,49396,10821],{}," (if you are too lazy to fill out the file, use the ",[567,49399,49400],{},"docker-compose-solutions.yml",") run:",[738,49403,49405],{"className":1621,"code":49404,"language":1623,"meta":743,"style":743},"docker-compose -f docker-compose.yml up\n",[567,49406,49407],{"__ignoreMap":743},[747,49408,49409,49411,49413,49416],{"class":749,"line":750},[747,49410,2936],{"class":1630},[747,49412,1934],{"class":802},[747,49414,49415],{"class":802}," docker-compose.yml",[747,49417,11281],{"class":802},[6072,49419,49420,49424,49446,49450],{},[523,49421,49422],{},[584,49423,2957],{},[668,49425,49426,49432,49442],{},[638,49427,49428,11292,49430,11295],{},[567,49429,2936],{},[567,49431,2936],{},[638,49433,49434,11301,49436,11304,49438,11308,49440,11311],{},[567,49435,11300],{},[567,49437,10821],{},[567,49439,11307],{},[567,49441,2936],{},[638,49443,49444,11317],{},[567,49445,11316],{},[523,49447,49448],{},[584,49449,44125],{},[738,49451,49452],{"className":1621,"code":743,"language":1623,"meta":743,"style":743},[567,49453,49454],{"__ignoreMap":743},[747,49455],{"class":749,"line":750},[523,49457,49458,49459,49461,49462,49464,49465,49468,49469,49472,49473,49545,49546,49549,49550,49552,49553,8287,49556,8287,49558,49561,49562,8287,49565,8287,49567,49569,49570,49572,49575,49577],{},"$ docker-compose up # no need for ",[567,49460,11300],{}," flag as the default file is used ",[567,49463,10821],{},"\nCreating compose101_database_1   ... done\nCreating compose101_phpmyadmin_1 ... done\nCreating compose101_wordpress_1  ... done\nAttaching to compose101_database_1, compose101_phpmyadmin_1, compose101_wordpress_1\nphpmyadmin_1  | phpMyAdmin not found in \u002Fvar\u002Fwww\u002Fhtml - copying now...\nwordpress_1   | WordPress not found in \u002Fvar\u002Fwww\u002Fhtml - copying now...\nphpmyadmin_1  | Complete! phpMyAdmin has been successfully copied to \u002Fvar\u002Fwww\u002Fhtml\nwordpress_1   | Complete! WordPress has been successfully copied to \u002Fvar\u002Fwww\u002Fhtml\nphpmyadmin_1  | \u002Fusr\u002Flib\u002Fpython2.7\u002Fsite-packages\u002Fsupervisor\u002Foptions.py:461: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a \"-c\" argument specifying an absolute path to a configuration file for improved security.\nphpmyadmin_1  |   'Supervisord is running as root and it is searching '\nphpmyadmin_1  | 2019-04-07 22:17:35,638 CRIT Supervisor is running as root.  Privileges were not dropped because no user is specified in the config file.  If you intend to run as root, you can set user=root in the config file to avoid this message.\nphpmyadmin_1  | 2019-04-07 22:17:35,638 INFO Included extra file \"\u002Fetc\u002Fsupervisor.d\u002Fnginx.ini\" during parsing\nphpmyadmin_1  | 2019-04-07 22:17:35,638 INFO Included extra file \"\u002Fetc\u002Fsupervisor.d\u002Fphp.ini\" during parsing\nphpmyadmin_1  | 2019-04-07 22:17:35,646 INFO RPC interface 'supervisor' initialized\nphpmyadmin_1  | 2019-04-07 22:17:35,646 CRIT Server 'unix_http_server' running without any HTTP authentication checking\nphpmyadmin_1  | 2019-04-07 22:17:35,646 INFO supervisord started with pid 1\nwordpress_1   | ",[747,49466,49467],{},"07-Apr-2019 22:17:35 UTC"," PHP Warning:  mysqli::__construct(): (HY000\u002F2002): Connection refused in - on line 22\nwordpress_1   |\nwordpress_1   | MySQL Connection Error: (2002) Connection refused\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49470,49471],{},"Note"," mysqld (mysqld 10.4.3-MariaDB-1:10.4.3+maria",[29708,49474,49475,49476,49478,49479,49481,49482,49484,49485,49487,49488,49490,49491,49493,49494,49496,49497,49499,49500,49502,49503,49505,49506,49508,49509,49511,49512,49514,49515,49517,49518,49520,49521,49523,49524,49526,49527,49529,49530,49532,49533,49535,49536,49538,49539,49541,49542,49544],{},"bionic) starting as process 1 ...\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49477,49471],{}," InnoDB: Using Linux native AIO\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49480,49471],{}," InnoDB: Mutexes and rw_locks use GCC atomic builtins\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49483,49471],{}," InnoDB: Uses event mutexes\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49486,49471],{}," InnoDB: Compressed tables use zlib 1.2.11\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49489,49471],{}," InnoDB: Number of pools: 1\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49492,49471],{}," InnoDB: Using SSE2 crc32 instructions\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49495,49471],{}," mysqld: O_TMPFILE is not supported on \u002Ftmp (disabling future attempts)\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49498,49471],{}," InnoDB: Initializing buffer pool, total size = 256M, instances = 1, chunk size = 128M\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49501,49471],{}," InnoDB: Completed initialization of buffer pool\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49504,49471],{}," InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49507,49471],{}," InnoDB: 128 out of 128 rollback segments are active.\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49510,49471],{}," InnoDB: Creating shared tablespace for temporary tables\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49513,49471],{}," InnoDB: Setting file '.\u002Fibtmp1' size to 12 MB. Physically writing the file full; Please wait ...\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49516,49471],{}," InnoDB: File '.\u002Fibtmp1' size is now 12 MB.\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49519,49471],{}," InnoDB: 10.4.3 started; log sequence number 139845; transaction id 21\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49522,49471],{}," InnoDB: Loading buffer pool(s) from \u002Fvar\u002Flib\u002Fmysql\u002Fib_buffer_pool\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49525,49471],{}," Plugin 'FEEDBACK' is disabled.\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49528,49471],{}," Server socket created on IP: '::'.\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49531,13184],{}," 'proxies_priv' entry '@% root@81494c3919ba' ignored in --skip-name-resolve mode.\ndatabase_1    | 2019-04-07 22:17:35 0 ",[747,49534,49471],{}," InnoDB: Buffer pool(s) load completed at 190407 22:17:35\ndatabase_1    | 2019-04-07 22:17:36 0 ",[747,49537,49471],{}," Reading of all Master_info entries succeded\ndatabase_1    | 2019-04-07 22:17:36 0 ",[747,49540,49471],{}," Added new Master_info '' to hash table\ndatabase_1    | 2019-04-07 22:17:36 0 ",[747,49543,49471],{}," mysqld: ready for connections.\ndatabase_1    | Version: '10.4.3-MariaDB-1:10.4.3+maria","bionic'  socket: '\u002Fvar\u002Frun\u002Fmysqld\u002Fmysqld.sock'  port: 3306  mariadb.org binary distribution\nphpmyadmin_1  | 2019-04-07 22:17:36,648 INFO spawned: 'php-fpm' with pid 21\nphpmyadmin_1  | 2019-04-07 22:17:36,649 INFO spawned: 'nginx' with pid 22\nphpmyadmin_1  | ",[747,49547,49548],{},"07-Apr-2019 22:17:36"," NOTICE: fpm is running, pid 21\nphpmyadmin_1  | ",[747,49551,49548],{}," NOTICE: ready to handle connections\nphpmyadmin_1  | 2019-04-07 22:17:37,671 INFO success: php-fpm entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)\nphpmyadmin_1  | 2019-04-07 22:17:37,671 INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)\nwordpress_1   | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.19.0.4. Set the 'ServerName' directive globally to suppress this message\nwordpress_1   | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.19.0.4. Set the 'ServerName' directive globally to suppress this message\nwordpress_1   | ",[747,49554,49555],{},"Sun Apr 07 22:17:38.927887 2019",[747,49557,17921],{},[747,49559,49560],{},"pid 1"," AH00163: Apache\u002F2.4.25 (Debian) PHP\u002F7.1.28 configured -- resuming normal operations\nwordpress_1   | ",[747,49563,49564],{},"Sun Apr 07 22:17:38.927939 2019",[747,49566,17957],{},[747,49568,49560],{}," AH00094: Command line: 'apache2 -D FOREGROUND'\n",[747,49571,5685],{},[3049,49573,49574],{},"Insert Apache access logs of the WordPress and\u002F or phpMyAdmin stance being access",[747,49576,5685],{},"\n^CGracefully stopping... (press Ctrl+C again to force)\nStopping compose101_wordpress_1  ... done\nStopping compose101_phpmyadmin_1 ... done\nStopping compose101_database_1   ... done",[738,49579,49582],{"className":49580,"code":49581,"language":12479},[12477],"\nAfter running the command, you should see log output starting to fill your terminal. To stop the started containers press `CTRL+C`.\nAgain as with a single container, to detach the container into background when running `docker-compuse up`, add the the `--detach` (or `-d`) flag.\n\n## Basic `docker-compose` commands\n\nThere are some `docker-compose` commands you should know when working with the `docker-compose` command.\n\n### Stopping all containers run by the current `docker-compose` file\n\nInstead of the `up`, you just put `stop` there. Stops the containers from the current `docker-compose` file:\n\n```bash\ndocker-compose stop -t TIMEOUT\n",[567,49583,49581],{"__ignoreMap":743},[6072,49585,49586,49590],{},[523,49587,49588],{},[584,49589,2957],{},[668,49591,49592,49596],{},[638,49593,49594,11390],{},[567,49595,11360],{},[638,49597,49598,49600],{},[567,49599,11395],{}," - Optional. Timeout to wait for the containers to exit, before the containers get killed.",[613,49602,49604,49605,11351],{"id":49603},"deleting-all-containers-from-the-current-docker-compose-file","Deleting all containers from the current ",[567,49606,2936],{},[523,49608,11405,49609,11408,49611,11412,49613,49615],{},[567,49610,11316],{},[567,49612,11411],{},[567,49614,2936],{}," file, but now are stopped or exited:",[738,49617,49619],{"className":1621,"code":49618,"language":1623,"meta":743,"style":743},"docker-compose -f DOCKER_COMPOSE_YML rm --force\n",[567,49620,49621],{"__ignoreMap":743},[747,49622,49623,49625,49627,49629,49631],{"class":749,"line":750},[747,49624,2936],{"class":1630},[747,49626,1934],{"class":802},[747,49628,11278],{"class":802},[747,49630,5902],{"class":802},[747,49632,49633],{"class":802}," --force\n",[6072,49635,49636,49640],{},[523,49637,49638],{},[584,49639,2957],{},[668,49641,49642,49649],{},[638,49643,49644,49646,49647,11311],{},[567,49645,11411],{}," - Subcommand to remove\u002F delete all container started by the selected ",[567,49648,2936],{},[638,49650,49651,11452],{},[567,49652,49653],{},"--force",[613,49655,11456,49656,11351],{"id":11455},[567,49657,2936],{},[523,49659,11461,49660,49662],{},[567,49661,2936],{}," file.\nThis just stops and starts the containers again. It does not delete and create the containers again.",[738,49664,49665],{"className":1621,"code":11467,"language":1623,"meta":743,"style":743},[567,49666,49667],{"__ignoreMap":743},[747,49668,49669,49671,49673,49675],{"class":749,"line":750},[747,49670,2936],{"class":1630},[747,49672,1934],{"class":802},[747,49674,11278],{"class":802},[747,49676,11480],{"class":802},[6072,49678,49679,49683],{},[523,49680,49681],{},[584,49682,2957],{},[668,49684,49685],{},[638,49686,49687,49689,49690,11311],{},[567,49688,11491],{}," - Subcommand to stop and then start all containers of the selected ",[567,49691,2936],{},[613,49693,49695,49696,11500],{"id":49694},"lets-play-some-more-with-docker-compose","Let's play some more with ",[567,49697,2936],{},[6072,49699,49700,49710,49719,49723],{},[523,49701,49702,8939,49704],{},[584,49703,2951],{},[527,49705,49708],{"href":49706,"rel":49707},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-container-docker-kubernetes\u002Ftree\u002Fmaster\u002Fcompose202",[531],[567,49709,11511],{},[523,49711,49712,49713,49715,49716,49718],{},"The task directory contains some other ",[567,49714,10821],{}," files for you to play around with. Look at the ",[567,49717,10821],{},"s, realize what they do and run 'em.",[523,49720,49721],{},[584,49722,9515],{},[523,49724,49725,49726,11531,49728,49730],{},"Keep the ",[567,49727,9779],{},[567,49729,10821],{}," as in this case in specific.",[523,49732,49733,49734,1909],{},"Let me know if you run into any issues, during \"play time\" with ",[567,49735,2936],{},[2979,49737],{},[535,49739,27548],{"id":27547},[523,49741,49742],{},"If you are reading this, you have made it to the end of day #1. Well done, sir or madam, have a cookie!",[523,49744,27554,49745,1909],{},[527,49746,27558],{"href":49747},"mailto:galexrt@googlemail.com",[523,49749,13967],{},[2890,49751,49752],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":743,"searchDepth":761,"depth":761,"links":49754},[49755,49756,49757,49761,49762,49767,49774,49781,49782,49789,49795,49799,49808,49819],{"id":26430,"depth":761,"text":26431},{"id":26437,"depth":761,"text":26438},{"id":2983,"depth":761,"text":2984,"children":49758},[49759,49760],{"id":39305,"depth":769,"text":39306},{"id":39343,"depth":769,"text":39348},{"id":26545,"depth":761,"text":39374},{"id":39385,"depth":761,"text":39386,"children":49763},[49764,49765,49766],{"id":39389,"depth":769,"text":39390},{"id":3043,"depth":769,"text":3044},{"id":39457,"depth":769,"text":39458},{"id":3109,"depth":761,"text":3110,"children":49768},[49769,49770,49771,49772,49773],{"id":39514,"depth":769,"text":39515},{"id":39535,"depth":769,"text":39536},{"id":39574,"depth":769,"text":39575},{"id":3293,"depth":769,"text":3294},{"id":3486,"depth":769,"text":3487},{"id":3642,"depth":761,"text":3643,"children":49775},[49776,49777,49778,49779,49780],{"id":3649,"depth":769,"text":3650},{"id":4152,"depth":769,"text":4153},{"id":44059,"depth":769,"text":44060},{"id":44470,"depth":769,"text":44471},{"id":44490,"depth":769,"text":44491},{"id":45882,"depth":761,"text":44471},{"id":7227,"depth":761,"text":45895,"children":49783},[49784,49785,49787],{"id":45902,"depth":769,"text":45903},{"id":46005,"depth":769,"text":49786},"docker volume command",{"id":46034,"depth":769,"text":49788},"Data containers  aka --volumes-from (DEPRECATED)",{"id":7442,"depth":761,"text":193,"children":49790},[49791,49792,49793,49794],{"id":46087,"depth":769,"text":46088},{"id":7458,"depth":769,"text":7459},{"id":8244,"depth":769,"text":8245},{"id":8310,"depth":769,"text":8311},{"id":8418,"depth":761,"text":8419,"children":49796},[49797,49798],{"id":8438,"depth":769,"text":8439},{"id":8557,"depth":769,"text":8558},{"id":8780,"depth":761,"text":47458,"children":49800},[49801,49802,49803,49804,49805,49806,49807],{"id":8787,"depth":769,"text":8788},{"id":47574,"depth":769,"text":47575},{"id":8976,"depth":769,"text":47620},{"id":9498,"depth":769,"text":9499},{"id":48524,"depth":769,"text":48525},{"id":48656,"depth":769,"text":48657},{"id":10730,"depth":769,"text":10731},{"id":48965,"depth":761,"text":49809,"children":49810},"\"Composing\" containers together with docker-compose",[49811,49812,49813,49815,49817],{"id":48971,"depth":769,"text":48972},{"id":11246,"depth":769,"text":11247},{"id":49603,"depth":769,"text":49814},"Deleting all containers from the current docker-compose file",{"id":11455,"depth":769,"text":49816},"Restarting all container started by the current docker-compose file",{"id":49694,"depth":769,"text":49818},"Let's play some more with docker-compose!",{"id":27547,"depth":761,"text":27548},"2019-03-26T21:20:06+01:00",{"src":12171},{"tags":49823},[12174,12175,124,26415],"\u002Fblog\u002F2019\u002Fcontainer-and-kubernetes-training-day1",{"title":39266,"description":26514},"3.blog\u002F2019\u002Fcontainer-and-kubernetes-training-day1","HFiyrSY1SdfIG6FCqvTRqgZNXO-mGTww1zxwEI8eMDQ",{"id":49829,"title":49830,"authors":49831,"badge":518,"body":49834,"date":49980,"description":49981,"extension":2911,"image":49982,"meta":49983,"navigation":1254,"path":49985,"seo":49986,"stem":49987,"__hash__":49988},"posts\u002F3.blog\u002F2019\u002Ffosdem19-brussels.md","FOSDEM'19 Brussels",[49832],{"name":514,"to":515,"avatar":49833},{"src":517},{"type":520,"value":49835,"toc":49971},[49836,49839,49843,49849,49855,49861,49867,49873,49877,49880,49886,49894,49899,49905,49909,49915,49921,49926,49931,49936,49939,49944,49947,49950,49953,49959,49963,49966,49969],[523,49837,49838],{},"FOSDEM was from Saturday, 02.02. to Sunday, 03.02.2019 in Brussels, Belgium.",[535,49840,49842],{"id":49841},"saturday","Saturday",[523,49844,49845],{},[3069,49846],{"alt":49847,"src":49848},"FOSDEM'19 Brussels - Snow on Saturday","\u002Fblog\u002F2019\u002Ffosdem19-brussels\u002Fimg_20190202_080557.jpg",[523,49850,49851],{},[3069,49852],{"alt":49853,"src":49854},"FOSDEM'19 Brussels - ULB FOSDEM middle 'street' with food trucks","\u002Fblog\u002F2019\u002Ffosdem19-brussels\u002Fpano_20190202_091303.vr.jpg",[523,49856,49857],{},[3069,49858],{"alt":49859,"src":49860},"FOSDEM'19 Brussels - Booth area","\u002Fblog\u002F2019\u002Ffosdem19-brussels\u002Fimg_20190202_110641.jpg",[523,49862,49863],{},[3069,49864],{"alt":49865,"src":49866},"FOSDEM'19 Brussels - Gluster, Ceph and Rook booth","\u002Fblog\u002F2019\u002Ffosdem19-brussels\u002Fdyy8hdmwoaaffza.jpg",[523,49868,49869],{},[3069,49870],{"alt":49871,"src":49872},"FOSDEM'19 Brussels - openSUSE Original 'Tumbleweed' Beer\" width=\"350px","\u002Fblog\u002F2019\u002Ffosdem19-brussels\u002Fimg_20190202_125902_970.jpg",[613,49874,49876],{"id":49875},"extra","Extra",[523,49878,49879],{},"The Belgian know how to make freaking awesome waffles!\nLOOK AT THOSE WAFFLES!!!",[523,49881,49882],{},[3069,49883],{"alt":49884,"src":49885},"FOSDEM'19 Brussels - Le Funambule Waffle Selection","\u002Fblog\u002F2019\u002Ffosdem19-brussels\u002Fimg_20190202_222902.jpg",[523,49887,49888,49889,49893],{},"If you are in Brussels, go to ",[527,49890,49892],{"href":13956,"rel":49891},[531],"Le Funambule"," in the inner city of Brussels:",[18903,49895],{"src":49896,"height":49897,"frameBorder":3579,"style":49898,"allowFullScreen":1254},"https:\u002F\u002Fwww.google.com\u002Fmaps\u002Fembed?pb=!1m18!1m12!1m3!1d322441.9224249947!2d4.351430301210488!3d50.84824876440262!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47c3c387599d5ac7%3A0xcad88e22902d5fa0!2sLe+Funambule!5e0!3m2!1sen!2sde!4v1550959777179","100%","min-height:400px;border:0",[523,49900,49901],{},[3069,49902],{"alt":49903,"src":49904},"FOSDEM'19 Brussels - Le Funambule Waffle with cream whip and chocolate sauce","\u002Fblog\u002F2019\u002Ffosdem19-brussels\u002Fimg_20190202_223003.jpg",[535,49906,49908],{"id":49907},"sunday","Sunday",[523,49910,49911],{},[3069,49912],{"alt":49913,"src":49914},"FOSDEM'19 Brussels - ","\u002Fblog\u002F2019\u002Ffosdem19-brussels\u002Fimg_20190203_122548.jpg",[523,49916,49917,49918,11500],{},"My time to shine for the ",[527,49919,13753],{"href":13751,"rel":49920},[531],[523,49922,49923],{},[3069,49924],{"alt":49913,"src":49925},"\u002Fblog\u002F2019\u002Ffosdem19-brussels\u002Fdyeruxhwwauzhvc.jpg",[523,49927,49928],{},[3069,49929],{"alt":49913,"src":49930},"\u002Fblog\u002F2019\u002Ffosdem19-brussels\u002Fdyerzdtwkaa4mzo.jpg",[523,49932,49933],{},[3069,49934],{"alt":49913,"src":49935},"\u002Fblog\u002F2019\u002Ffosdem19-brussels\u002Fdyeue9qx4aaaetg.jpg",[523,49937,49938],{},"From the feedback I got on Twitter I did a good job.",[523,49940,49941],{},[3069,49942],{"alt":49913,"src":49943},"\u002Fblog\u002F2019\u002Ffosdem19-brussels\u002Fimg_20190203_141125.jpg",[523,49945,49946],{},"I finally got to meet Hans Cornelis which I owed me a beer for some help with Rook :-P",[613,49948,49876],{"id":49949},"extra-1",[523,49951,49952],{},"Bringing home some of that delicious Belgian berr is a must :-)",[523,49954,49955],{},[3069,49956],{"alt":49957,"src":49958},"FOSDEM'19 Brussels - Belgian Beers are a must as a gift","\u002Fblog\u002F2019\u002Ffosdem19-brussels\u002Fimg_20190203_175635.jpg",[535,49960,49962],{"id":49961},"monday","Monday",[523,49964,49965],{},"Shout out to my Uber driver \"Aziz\" for knowing all the shortcuts through the city so I was on time.",[523,49967,49968],{},"It was cool to see former colleagues and many friends there. Always nice to have a chat about life and current projects.",[523,49970,13967],{},{"title":743,"searchDepth":761,"depth":761,"links":49972},[49973,49976,49979],{"id":49841,"depth":761,"text":49842,"children":49974},[49975],{"id":49875,"depth":769,"text":49876},{"id":49907,"depth":761,"text":49908,"children":49977},[49978],{"id":49949,"depth":769,"text":49876},{"id":49961,"depth":761,"text":49962},"2019-02-23T17:50:09+01:00","Some thoughts, notes, comments and pictures from the FOSDEM'19 in Brussels, Belgium.",{"src":49866},{"tags":49984},[13976,13977,13978,427,465,13979],"\u002Fblog\u002F2019\u002Ffosdem19-brussels",{"title":49830,"description":49981},"3.blog\u002F2019\u002Ffosdem19-brussels","fFR8WcJNTff3VBRaRkZ4xwOnBJA5MAjbW_19hjkZPjg",{"id":49990,"title":49991,"authors":518,"badge":518,"body":49992,"date":50842,"description":50843,"extension":2911,"image":50844,"meta":50846,"navigation":1254,"path":50850,"seo":50851,"stem":50852,"__hash__":50853},"posts\u002F3.blog\u002F2019\u002Fmy-sysctl-parameters.md","My Sysctl Parameters",{"type":520,"value":49993,"toc":50829},[49994,49997,50008,50028,50031,50034,50046,50051,50115,50120,50240,50245,50250,50288,50292,50632,50636,50716,50725,50742,50747,50794,50797,50799,50807,50809,50812,50815],[523,49995,49996],{},"These are the sysctl settings I deploy on most of my machines.\nThe \"machines\" I am speaking of here, are \"always\" assumed to have at least the following \"hardware\" (it shouldn't really matter if it is actual metal or virtual machine):",[668,49998,49999,50002,50005],{},[638,50000,50001],{},"CPU: Quad or more Core",[638,50003,50004],{},"RAM: 32GB or more memory",[638,50006,50007],{},"Network: 1Gbit\u002Fs",[6072,50009,50010,50014,50021,50025],{},[523,50011,50012],{},[584,50013,6189],{},[523,50015,50016,50017,50020],{},"For \"thiccer wires\", one does simply increase the ",[567,50018,50019],{},"net.*mem"," parameters.",[523,50022,50023],{},[584,50024,6189],{},[523,50026,50027],{},"I'm using parts of these paramters for machines smaller than the given \"specs\" too, but then modified a bit accordingly.",[523,50029,50030],{},"If you have comments and\u002For tips about the parameters, feel free to comment them below.",[523,50032,50033],{},"I will add description and\u002For reasoning for some of the sysctl parameter \"groups\" over time below the whole list.",[50035,50036,50037,50038,50045],"details",{},"\n    ",[14525,50039,50040,50041],{},"Full list of my sysctl parameters, ready for copy'n'paste - ",[50042,50043,50044],"b",{},"Click to expand","\n```ini\nfs.aio_max_nr = 1048576\nfs.file_max = 2097152\nfs.inotify.max_user_instances = 5120\nfs.inotify.max_user_watches = 1572864\nfs.nr_open = 3145728\nfs.protected_hardlinks = 1\nfs.protected_symlinks = 1\nfs.suid_dumpable = 0\nkernel.core_uses_pid = 1\nkernel.dmesg_restrict = 1\nkernel.exec-shield = 1\nkernel.kptr_restrict = 1\nkernel.yama.ptrace_scope = 2\nkernel.panic = 10\nkernel.panic_on_oops = 1\nkernel.pid_max = 4194303\nkernel.randomize_va_space = 2\nkernel.sched_autogroup_enabled = 0\nkernel.sched_migration_cost = 5000000\nkernel.sysrq = 0\nnet.core.default_qdisc = fq\nnet.core.netdev_budget = 600\nnet.core.netdev_max_backlog = 65536\nnet.core.optmem_max = 2048000\nnet.core.rmem_max = 2048000\nnet.core.somaxconn = 65536\nnet.core.wmem_max = 2048000\nnet.ipv4.conf.all.accept_redirects = 0\nnet.ipv4.conf.all.accept_source_route = 0\nnet.ipv4.conf.all.bootp_relay = 0\nnet.ipv4.conf.all.forwarding = 1\nnet.ipv4.conf.all.igmpv2_unsolicited_report_interval = 10000\nnet.ipv4.conf.all.igmpv3_unsolicited_report_interval = 1000\nnet.ipv4.conf.all.ignore_routes_with_linkdown = 0\nnet.ipv4.conf.all.log_martians = 1\nnet.ipv4.conf.all.proxy_arp = 0\nnet.ipv4.conf.all.rp_filter = 1\nnet.ipv4.conf.all.secure_redirects = 1\nnet.ipv4.conf.all.send_redirects = 0\nnet.ipv4.conf.default.accept_redirects = 0\nnet.ipv4.conf.default.accept_source_route = 0\nnet.ipv4.conf.default.forwarding = 1\nnet.ipv4.conf.default.log_martians = 1\nnet.ipv4.conf.default.rp_filter = 1\nnet.ipv4.conf.default.secure_redirects = 1\nnet.ipv4.conf.default.send_redirects = 0\nnet.ipv4.conf.lo.accept_source_route = 1\nnet.ipv4.fwmark_reflect = 0\nnet.ipv4.icmp_echo_ignore_all = 0\nnet.ipv4.icmp_echo_ignore_broadcasts = 1\nnet.ipv4.icmp_ignore_bogus_error_responses = 1\nnet.ipv4.icmp_msgs_burst = 50\nnet.ipv4.icmp_msgs_per_sec = 1000\nnet.ipv4.ip_forward = 1\nnet.ipv4.ipfrag_secret_interval = 600\nnet.ipv4.ip_local_port_range = 1024 65535\nnet.ipv4.neigh.default.gc_thresh1 = 4048\nnet.ipv4.neigh.default.gc_thresh2 = 6144\nnet.ipv4.neigh.default.gc_thresh3 = 8192\nnet.ipv4.netfilter.nf_conntrack_generic_timeout = 300\nnet.ipv4.netfilter.nf_conntrack_tcp_timeout_time_wait = 60\nnet.ipv4.tcp_congestion_control = bbr\nnet.ipv4.tcp_fin_timeout = 10\nnet.ipv4.tcp_keepalive_intvl = 25\nnet.ipv4.tcp_keepalive_probes = 5\nnet.ipv4.tcp_keepalive_time = 420\nnet.ipv4.tcp_max_syn_backlog = 4096\nnet.ipv4.tcp_max_tw_buckets = 160000\nnet.ipv4.tcp_moderate_rcvbuf = 1\nnet.ipv4.tcp_no_metrics_save = 1\nnet.ipv4.tcp_notsent_lowat = 16384\nnet.ipv4.tcp_rfc1337 = 1\nnet.ipv4.tcp_rmem = 4096 87380 8388608\nnet.ipv4.tcp_sack = 1\nnet.ipv4.tcp_slow_start_after_idle = 0\nnet.ipv4.tcp_synack_retries = 3\nnet.ipv4.tcp_syncookies = 1\nnet.ipv4.tcp_syn_retries = 2\nnet.ipv4.tcp_timestamps = 1\nnet.ipv4.tcp_tw_recycle = 0\nnet.ipv4.tcp_tw_reuse = 1\nnet.ipv4.tcp_window_scaling = 1\nnet.ipv4.tcp_wmem = 4096 87380 8388608\nnet.ipv4.udp_rmem_min = 8192\nnet.ipv4.udp_wmem_min = 8192\nnet.ipv4.vs.conntrack = 1\nnet.ipv4.vs.conn_reuse_mode = 1\nnet.ipv4.vs.expire_nodest_conn = 1\nnet.ipv4.vs.sloppy_tcp = 1\nnet.ipv6.conf.all.accept_ra = 0\nnet.ipv6.conf.all.accept_ra_defrtr = 0\nnet.ipv6.conf.all.accept_ra_pinfo = 0\nnet.ipv6.conf.all.accept_redirects = 0\nnet.ipv6.conf.all.accept_source_route = 0\nnet.ipv6.conf.all.forwarding = 1\nnet.ipv6.conf.default.accept_redirects = 0\nnet.ipv6.conf.default.accept_source_route = 0\nnet.ipv6.conf.default.autoconf = 1\nnet.ipv6.conf.default.forwarding = 1\nnet.ipv6.conf.default.max_addresses = 16\nnet.ipv6.ip6frag_secret_interval = 600\nnet.ipv6.route.max_size = 16384\nnet.ipv6.xfrm6_gc_thresh = 32768\nnet.netfilter.nf_conntrack_expect_max = 2048\nnet.netfilter.nf_conntrack_max = 1024000\nnet.netfilter.nf_conntrack_tcp_timeout_established = 600\nnet.nf_conntrack_max = 1024000\nvm.overcommit_memory = 1\nvm.overcommit_ratio = 20\nvm.panic_on_oom = 0\n```\n",[535,50047,50049],{"id":50048},"fs",[567,50050,50048],{},[668,50052,50053,50058,50076,50081,50094,50099,50104,50109],{},[638,50054,50055],{},[567,50056,50057],{},"fs.aio_max_nr = 1048576",[638,50059,50060,50063,50064,11304,50068,50071,50072,50075],{},[567,50061,50062],{},"fs.file_max = 2097152"," Increase maximum file descriptors on kernel level, see ",[527,50065,50066],{"href":50066,"rel":50067},"https:\u002F\u002Fserverfault.com\u002Fa\u002F122682\u002F367169",[531],[584,50069,50070],{},"SPOILER"," You still need to set ",[567,50073,50074],{},"ulimits"," for \"normal\" users.",[638,50077,50078],{},[567,50079,50080],{},"fs.inotify.max_user_instances = 5120",[638,50082,50083,50086],{},[567,50084,50085],{},"fs.inotify.max_user_watches = 1572864",[668,50087,50088],{},[638,50089,8764,50090,50093],{},[567,50091,50092],{},"fs.inotify.max_user_*"," values have been increased as it seems in some Kubernetes clusters there have been issues in regards to flexvolume plugin (possibly also CSI as they also place drivers on the hosts and CSI and\u002For kubelet are (inotify) watching for them).",[638,50095,50096],{},[567,50097,50098],{},"fs.nr_open = 3145728",[638,50100,50101],{},[567,50102,50103],{},"fs.protected_hardlinks = 1",[638,50105,50106],{},[567,50107,50108],{},"fs.protected_symlinks = 1",[638,50110,50111,50114],{},[567,50112,50113],{},"fs.suid_dumpable = 0"," Restrict core dumps.",[535,50116,50118],{"id":50117},"kernel",[567,50119,50117],{},[668,50121,50122,50127,50141,50147,50156,50173,50179,50185,50191,50196,50216,50234],{},[638,50123,50124],{},[567,50125,50126],{},"kernel.core_uses_pid = 1",[638,50128,50129,50132,50133,50136,50137,50140],{},[567,50130,50131],{},"kernel.dmesg_restrict = 1"," Disables ",[567,50134,50135],{},"dmesg"," for containers without the needed ",[567,50138,50139],{},"CAP_SYSLOG"," capability and obviously with that non-root users on the host.",[638,50142,50143,50146],{},[567,50144,50145],{},"kernel.exec-shield = 1"," Only available on RedHat Enterprise Linux OS.",[638,50148,50149,50152,50153,50155],{},[567,50150,50151],{},"kernel.kptr_restrict = 1"," Only allow access to kernel symbol adresses for users with ",[567,50154,50139],{}," capability.",[638,50157,50158,50161,50162,50165,50166,50169,50170,50172],{},[567,50159,50160],{},"kernel.yama.ptrace_scope = 1"," Restrict ",[567,50163,50164],{},"ptrace"," to parent processes (0 any process with same uid, 1 only parent process, 2 users with ",[567,50167,50168],{},"CAP_SYS_PTRACE",", 3 noone can ptrace reboot required to allow ",[567,50171,50164],{}," again).",[638,50174,50175,50178],{},[567,50176,50177],{},"kernel.panic = 10"," Reset the machine on kernel panic after 10 seconds.",[638,50180,50181,50184],{},[567,50182,50183],{},"kernel.panic_on_oops = 1"," Cause a kernel panic when a kernel BUG\u002F \"Oops\" is encountered.",[638,50186,50187,50190],{},[567,50188,50189],{},"kernel.pid_max = 4194303"," Increase maximum PID because we are running many containers with many processes (could be set lower, but here just in case so many processes are being run and\u002For PIDs are \"never\" going to \"overlap\").",[638,50192,50193],{},[567,50194,50195],{},"kernel.randomize_va_space = 2",[638,50197,50198,50201,50213,50215],{},[567,50199,50200],{},"kernel.sched_autogroup_enabled = 0",[6072,50202,50203,50206],{},[523,50204,50205],{},"The migration cost should be increased, almost universally on server\nsystems with many processes. This means systems like PostgreSQL or\nApache would benefit from having higher migration costs.",[523,50207,26833,50208,1909],{},[527,50209,50212],{"href":50210,"rel":50211},"https:\u002F\u002Fwww.postgresql.org\u002Fmessage-id\u002F50E4AAB1.9040902@optionshouse.com",[531],"PostgreSQL: Two Necessary Kernel Tweaks for Linux Systems",[12608,50214],{},"We have many processes because of containers which are potentially spawned in a manner that would \"cause\" processes to be \"choked out of CPU cycles in favor of less important tasks\", so disable it.",[638,50217,50218,50221,50231,50233],{},[567,50219,50220],{},"kernel.sched_migration_cost = 5000000",[6072,50222,50223,50226],{},[523,50224,50225],{},"It basically groups tasks by TTY so perceived responsiveness is improved.\nBut on server systems, large daemons like PostgreSQL are going to be\nlaunched from the same pseudo-TTY, and be effectively choked out of CPU\ncycles in favor of less important tasks.",[523,50227,26833,50228,1909],{},[527,50229,50212],{"href":50210,"rel":50230},[531],[12608,50232],{},"Many containers most of the time, depending on the workload, also mean many processes, though it is set not too high as suggested in the PostgreSQL mailing thread.",[638,50235,50236,50239],{},[567,50237,50238],{},"kernel.sysrq = 0"," Limit",[535,50241,50243],{"id":50242},"net",[567,50244,50242],{},[613,50246,50248],{"id":50247},"core",[567,50249,50247],{},[668,50251,50252,50263,50268,50273,50278,50283],{},[638,50253,50254,50257,50258,1909],{},[567,50255,50256],{},"net.core.default_qdisc = fq"," Good for HTTP\u002F2, see ",[527,50259,50262],{"href":50260,"rel":50261},"https:\u002F\u002Fblog.cloudflare.com\u002Fhttp-2-prioritization-with-nginx\u002F",[531],"Cloudflare - Optimizing HTTP\u002F2 prioritization with BBR and tcp_notsent_lowat",[638,50264,50265],{},[567,50266,50267],{},"net.core.netdev_max_backlog = 65536",[638,50269,50270],{},[567,50271,50272],{},"net.core.optmem_max = 2048000",[638,50274,50275],{},[567,50276,50277],{},"net.core.rmem_max = 2048000",[638,50279,50280],{},[567,50281,50282],{},"net.core.somaxconn = 65536",[638,50284,50285],{},[567,50286,50287],{},"net.core.wmem_max = 2048000",[613,50289,50290],{"id":1528},[567,50291,1528],{},[668,50293,50294,50299,50304,50310,50316,50321,50326,50331,50342,50347,50352,50357,50362,50367,50372,50378,50387,50392,50397,50402,50407,50418,50423,50428,50434,50439,50444,50449,50454,50460,50465,50470,50475,50480,50485,50493,50498,50503,50508,50513,50518,50523,50528,50533,50541,50546,50551,50556,50561,50566,50571,50576,50581,50586,50591,50596,50601,50606,50611,50617,50622,50627],{},[638,50295,50296],{},[567,50297,50298],{},"net.ipv4.conf.all.accept_redirects = 0",[638,50300,50301],{},[567,50302,50303],{},"net.ipv4.conf.all.accept_source_route = 0",[638,50305,50306,50309],{},[567,50307,50308],{},"net.ipv4.conf.all.bootp_relay = 0"," Disable Bootstrap protocol, as it is superseded by DHCP.",[638,50311,50312,50315],{},[567,50313,50314],{},"net.ipv4.conf.all.forwarding = 1"," Allow forwarding of traffic on \"all\" interfaces (needed for containers).",[638,50317,50318],{},[567,50319,50320],{},"net.ipv4.conf.all.igmpv2_unsolicited_report_interval = 10000",[638,50322,50323],{},[567,50324,50325],{},"net.ipv4.conf.all.igmpv3_unsolicited_report_interval = 1000",[638,50327,50328],{},[567,50329,50330],{},"net.ipv4.conf.all.ignore_routes_with_linkdown = 0",[638,50332,50333,50336,50337,1909],{},[567,50334,50335],{},"net.ipv4.conf.all.log_martians = 1"," Log all packets for \"all\" interfaces that are going to so called ",[527,50338,50341],{"href":50339,"rel":50340},"https:\u002F\u002Fserverfault.com\u002Fquestions\u002F570980\u002Fwhat-is-the-usefulness-of-logging-of-martians-packet-e-g-net-ipv4-conf-all-lo",[531],"martians addresses",[638,50343,50344],{},[567,50345,50346],{},"net.ipv4.conf.all.proxy_arp = 0",[638,50348,50349],{},[567,50350,50351],{},"net.ipv4.conf.all.rp_filter = 1",[638,50353,50354],{},[567,50355,50356],{},"net.ipv4.conf.all.secure_redirects = 1",[638,50358,50359],{},[567,50360,50361],{},"net.ipv4.conf.all.send_redirects = 0",[638,50363,50364],{},[567,50365,50366],{},"net.ipv4.conf.default.accept_redirects = 0",[638,50368,50369],{},[567,50370,50371],{},"net.ipv4.conf.default.accept_source_route = 0",[638,50373,50374,50377],{},[567,50375,50376],{},"net.ipv4.conf.default.forwarding = 1"," Allow forwarding of traffic by default for (new) interfaces (needed for containers).",[638,50379,50380,50383,50384,1909],{},[567,50381,50382],{},"net.ipv4.conf.default.log_martians = 1"," Log all packets by default for (new) interfaces that are going to so called ",[527,50385,50341],{"href":50339,"rel":50386},[531],[638,50388,50389],{},[567,50390,50391],{},"net.ipv4.conf.default.rp_filter = 1",[638,50393,50394],{},[567,50395,50396],{},"net.ipv4.conf.default.secure_redirects = 1",[638,50398,50399],{},[567,50400,50401],{},"net.ipv4.conf.default.send_redirects = 0",[638,50403,50404],{},[567,50405,50406],{},"net.ipv4.conf.lo.accept_source_route = 1",[638,50408,50409,50412,50413,1909],{},[567,50410,50411],{},"net.ipv4.fwmark_reflect = 0"," Don't set fwmark on kernel generated reply packets, see ",[527,50414,50417],{"href":50415,"rel":50416},"https:\u002F\u002Fsysctl-explorer.net\u002Fnet\u002Fipv4\u002Ffwmark_reflect\u002F",[531],"sysctl-explorer.net - net.ipv4.fwmark_reflect",[638,50419,50420],{},[567,50421,50422],{},"net.ipv4.icmp_echo_ignore_all = 0",[638,50424,50425],{},[567,50426,50427],{},"net.ipv4.icmp_echo_ignore_broadcasts = 1",[638,50429,50430,50433],{},[567,50431,50432],{},"net.ipv4.icmp_ignore_bogus_error_responses = 1"," Ignore bogus responses (don't log it in the kernel logs).",[638,50435,50436],{},[567,50437,50438],{},"net.ipv4.icmp_msgs_burst = 50",[638,50440,50441],{},[567,50442,50443],{},"net.ipv4.icmp_msgs_per_sec = 1000",[638,50445,50446],{},[567,50447,50448],{},"net.ipv4.ip_forward = 1",[638,50450,50451],{},[567,50452,50453],{},"net.ipv4.ipfrag_secret_interval = 600",[638,50455,50456,50459],{},[567,50457,50458],{},"net.ipv4.ip_local_port_range = 1024 65535"," Increase the per IP \"dynamic\" port limit (e.g., used for (S|D)NAT).",[638,50461,50462],{},[567,50463,50464],{},"net.ipv4.neigh.default.gc_thresh1 = 4048",[638,50466,50467],{},[567,50468,50469],{},"net.ipv4.neigh.default.gc_thresh2 = 6144",[638,50471,50472],{},[567,50473,50474],{},"net.ipv4.neigh.default.gc_thresh3 = 8192",[638,50476,50477],{},[567,50478,50479],{},"net.ipv4.netfilter.nf_conntrack_generic_timeout = 300",[638,50481,50482],{},[567,50483,50484],{},"net.ipv4.netfilter.nf_conntrack_tcp_timeout_time_wait = 60",[638,50486,50487,50257,50490,1909],{},[567,50488,50489],{},"net.ipv4.tcp_congestion_control = bbr",[527,50491,50262],{"href":50260,"rel":50492},[531],[638,50494,50495],{},[567,50496,50497],{},"net.ipv4.tcp_fin_timeout = 10",[638,50499,50500],{},[567,50501,50502],{},"net.ipv4.tcp_keepalive_intvl = 25",[638,50504,50505],{},[567,50506,50507],{},"net.ipv4.tcp_keepalive_probes = 5",[638,50509,50510],{},[567,50511,50512],{},"net.ipv4.tcp_keepalive_time = 420",[638,50514,50515],{},[567,50516,50517],{},"net.ipv4.tcp_max_syn_backlog = 4096",[638,50519,50520],{},[567,50521,50522],{},"net.ipv4.tcp_max_tw_buckets = 160000",[638,50524,50525],{},[567,50526,50527],{},"net.ipv4.tcp_moderate_rcvbuf = 1",[638,50529,50530],{},[567,50531,50532],{},"net.ipv4.tcp_no_metrics_save = 1",[638,50534,50535,50257,50538,1909],{},[567,50536,50537],{},"net.ipv4.tcp_notsent_lowat = 16384",[527,50539,50262],{"href":50260,"rel":50540},[531],[638,50542,50543],{},[567,50544,50545],{},"net.ipv4.tcp_rfc1337 = 1",[638,50547,50548],{},[567,50549,50550],{},"net.ipv4.tcp_rmem = 4096 16384 8388608",[638,50552,50553],{},[567,50554,50555],{},"net.ipv4.tcp_sack = 1",[638,50557,50558],{},[567,50559,50560],{},"net.ipv4.tcp_slow_start_after_idle = 0",[638,50562,50563],{},[567,50564,50565],{},"net.ipv4.tcp_synack_retries = 3",[638,50567,50568],{},[567,50569,50570],{},"net.ipv4.tcp_syncookies = 1",[638,50572,50573],{},[567,50574,50575],{},"net.ipv4.tcp_syn_retries = 2",[638,50577,50578],{},[567,50579,50580],{},"net.ipv4.tcp_timestamps = 1",[638,50582,50583],{},[567,50584,50585],{},"net.ipv4.tcp_tw_recycle = 0",[638,50587,50588],{},[567,50589,50590],{},"net.ipv4.tcp_tw_reuse = 1",[638,50592,50593],{},[567,50594,50595],{},"net.ipv4.tcp_window_scaling = 1",[638,50597,50598],{},[567,50599,50600],{},"net.ipv4.tcp_wmem = 4096 16384 8388608",[638,50602,50603],{},[567,50604,50605],{},"net.ipv4.udp_rmem_min = 8192",[638,50607,50608],{},[567,50609,50610],{},"net.ipv4.udp_wmem_min = 8192",[638,50612,50613,50616],{},[567,50614,50615],{},"net.ipv4.vs.conntrack = 1"," Enable IPVS connection tracking.",[638,50618,50619],{},[567,50620,50621],{},"net.ipv4.vs.conn_reuse_mode = 1",[638,50623,50624],{},[567,50625,50626],{},"net.ipv4.vs.expire_nodest_conn = 1",[638,50628,50629],{},[567,50630,50631],{},"net.ipv4.vs.sloppy_tcp = 1",[613,50633,50634],{"id":1557},[567,50635,1557],{},[668,50637,50638,50643,50648,50653,50658,50663,50668,50673,50678,50683,50688,50693,50701,50706,50711],{},[638,50639,50640],{},[567,50641,50642],{},"net.ipv6.conf.all.accept_ra = 0",[638,50644,50645],{},[567,50646,50647],{},"net.ipv6.conf.all.accept_ra_defrtr = 0",[638,50649,50650],{},[567,50651,50652],{},"net.ipv6.conf.all.accept_ra_pinfo = 0",[638,50654,50655],{},[567,50656,50657],{},"net.ipv6.conf.all.accept_redirects = 0",[638,50659,50660],{},[567,50661,50662],{},"net.ipv6.conf.all.accept_source_route = 0",[638,50664,50665,50315],{},[567,50666,50667],{},"net.ipv6.conf.all.forwarding = 1",[638,50669,50670],{},[567,50671,50672],{},"net.ipv6.conf.default.max_addresses = 16",[638,50674,50675],{},[567,50676,50677],{},"net.ipv6.conf.default.accept_redirects = 0",[638,50679,50680],{},[567,50681,50682],{},"net.ipv6.conf.default.accept_source_route = 0",[638,50684,50685],{},[567,50686,50687],{},"net.ipv6.conf.default.autoconf = 1",[638,50689,50690,50377],{},[567,50691,50692],{},"net.ipv6.conf.default.forwarding = 1",[638,50694,50695,50412,50698,1909],{},[567,50696,50697],{},"net.ipv6.fwmark_reflect = 0",[527,50699,50417],{"href":50415,"rel":50700},[531],[638,50702,50703],{},[567,50704,50705],{},"net.ipv6.ip6frag_secret_interval = 600",[638,50707,50708],{},[567,50709,50710],{},"net.ipv6.route.max_size = 16384",[638,50712,50713],{},[567,50714,50715],{},"net.ipv6.xfrm6_gc_thresh = 32768",[613,50717,50719,587,50722],{"id":50718},"netfilter-and-nf_conntrack_max",[567,50720,50721],{},"netfilter",[567,50723,50724],{},"nf_conntrack_max",[668,50726,50727,50732,50737],{},[638,50728,50729],{},[567,50730,50731],{},"net.netfilter.nf_conntrack_expect_max = 4096",[638,50733,50734],{},[567,50735,50736],{},"net.netfilter.nf_conntrack_max = 1024000",[638,50738,50739],{},[567,50740,50741],{},"net.netfilter.nf_conntrack_tcp_timeout_established = 600",[535,50743,50745],{"id":50744},"vm",[567,50746,50744],{},[668,50748,50749,50760,50766,50772,50788],{},[638,50750,50751,50754,50755,1909],{},[567,50752,50753],{},"vm.max_map_count = 262144"," If you run Elasticsearch one requirement for the preflight checks to pass, see ",[527,50756,50759],{"href":50757,"rel":50758},"https:\u002F\u002Fwww.elastic.co\u002Fguide\u002Fen\u002Felasticsearch\u002Freference\u002Fcurrent\u002Fvm-max-map-count.html",[531],"Elasticsearch Documentation Reference - Virtual memory",[638,50761,50762,50765],{},[567,50763,50764],{},"vm.overcommit_memory = 1"," Enable memory overcommitment.",[638,50767,50768,50771],{},[567,50769,50770],{},"vm.overcommit_ratio = 20"," How much percent of the total (physical) memory will be allowed to be overcommitet.",[638,50773,50774,50777,50778,50781,50782,50784,50785,50787],{},[567,50775,50776],{},"vm.panic_on_oom = 0"," Don't panic on ",[584,50779,50780],{},"O","ut ",[584,50783,50780],{},"f ",[584,50786,39410],{},"emory situation. It is fine to be out of memory because the OOM Killer will then already be going and killing processes according to their OOM score.",[638,50789,50790,50793],{},[567,50791,50792],{},"vm.swappiness = 0"," No swap please. Kubelet does not like it and if you run out of memory and don't have a special use case for swap, your memory is simply sized to low.",[523,50795,50796],{},"As written if you have comments and\u002For tips about the parameters, feel free to comment them below.",[523,50798,13967],{},[523,50800,50801,50802,2006],{},"(The cover photo is an edited screenshot from ",[527,50803,50806],{"href":50804,"rel":50805},"https:\u002F\u002Flinux.die.net\u002F",[531],"die.net Linux Documentation",[2979,50808],{},[535,50810,50811],{"id":46609},"References",[523,50813,50814],{},"Over the years \"collecting\" these sysctl settings I came across several different sources, sites and posts. This section is a (late) try to collect these so others can see from where certain sysctl values come:",[668,50816,50817,50823],{},[638,50818,50819],{},[527,50820,50821],{"href":50821,"rel":50822},"https:\u002F\u002Fwww.kmotoko.com\u002Farticles\u002Flinux-hardening-kernel-parameters-with-sysctl\u002F",[531],[638,50824,50825],{},[527,50826,50827],{"href":50827,"rel":50828},"https:\u002F\u002Fwww.tecmint.com\u002Fprotect-hard-and-symbolic-links-in-centos-rhel\u002F",[531],{"title":743,"searchDepth":761,"depth":761,"links":50830},[50831,50832,50833,50840,50841],{"id":50048,"depth":761,"text":50048},{"id":50117,"depth":761,"text":50117},{"id":50242,"depth":761,"text":50242,"children":50834},[50835,50836,50837,50838],{"id":50247,"depth":769,"text":50247},{"id":1528,"depth":769,"text":1528},{"id":1557,"depth":769,"text":1557},{"id":50718,"depth":769,"text":50839},"netfilter and nf_conntrack_max",{"id":50744,"depth":761,"text":50744},{"id":46609,"depth":761,"text":50811},"2019-02-18T08:15:20+01:00","These are the sysctl settings I deploy on most of my machines.",{"src":50845},"\u002Fblog\u002F2019\u002Fmy-sysctl-parameters\u002Fcover.png",{"author":50847,"tags":50848},"Author Name",[215,276,50849],"Tuning","\u002Fblog\u002F2019\u002Fmy-sysctl-parameters",{"title":49991,"description":50843},"3.blog\u002F2019\u002Fmy-sysctl-parameters","mZyv03HxxnnGg3jOb3veagwtVXJ01XBGeoihgXHPHtA",{"id":50855,"title":50856,"authors":50857,"badge":518,"body":50860,"date":51228,"description":51229,"extension":2911,"image":51230,"meta":51232,"navigation":1254,"path":51234,"seo":51235,"stem":51236,"__hash__":51237},"posts\u002F3.blog\u002F2019\u002Frook-more-than-ceph.md","Rook more than Ceph",[50858],{"name":514,"to":515,"avatar":50859},{"src":517},{"type":520,"value":50861,"toc":51210},[50862,50873,50875,50877,50880,50884,50887,50890,50893,50896,50900,50904,50907,50911,50914,50919,50923,50926,50929,50933,50936,50941,50944,50947,50952,50957,50960,50963,50967,50970,50975,50978,50981,50985,51018,51021,51029,51032,51035,51039,51042,51047,51053,51067,51078,51081,51093,51096,51100,51106,51109,51122,51125,51129,51132,51170,51173,51175],[523,50863,50864,50865,50868,50869,1909],{},"Checkout the orignal publication of this article on the ",[527,50866,13818],{"href":13816,"rel":50867},[531]," site here: ",[527,50870,50872],{"href":15111,"rel":50871},[531],"The Cloud Report - Rook more than Ceph",[2979,50874],{},[535,50876,14587],{"id":14586},[523,50878,50879],{},"Rook allows you to run Ceph and other storage backends in Kubernetes with ease. Consumption of storage, especially block and filesystem storage, can be consumed through Kubernetes native ways. this allows users of a Kubernetes cluster to consume storage easily as in \"any\" other standard Kubernetes cluster out there. allowing users to \"switch\" between any Kubernetes offering to run their containerized applications. Looking at the storage backends such as minio and CockroachDB, this can also potentially reduce costs for you if you use rook to simply run the CockroachDB yourself instead of through your cloud provider.",[535,50881,50883],{"id":50882},"data-and-persistence","Data and Persistence",[523,50885,50886],{},"Aren’t we all loving the comfort of the cloud? Simple back-up and also sharing of pictures as an example. Ignoring privacy concerns for now when using a company for that, instead of e.g., self hosting, which would be a whole other topic. I love being able to take pictures of my cats, the landscape, and my food and sharing the pictures. Sharing a picture with the world or just your family is only a few clicks away. The best of that, even my mother can do it.",[523,50888,50889],{},"Imagine the following situation. Your phone has been stolen and all your pictures in the cloud have been deleted due to a software bug. I, personally, would probably get a heart attack just thinking about that I am a person which likes to look at old pictures from time to time to remember happenings and friends during the time.",[523,50891,50892],{},"You may ask yourself what does this have to do with \"Data and Persistence\". There is a simple answer for that. Pictures are data and the persistence is, well in this case, gone because your data has been deleted.",[523,50894,50895],{},"Persistence of Data has a different importance to each of us. A student in America may hope for the persistence to be lost on his student debts and the other may have a job agency which basically relies on keeping the data of their clients not only available and intact but also secure.",[535,50897,50899],{"id":50898},"storage-what-is-the-right-one","Storage: What is the right one?",[613,50901,50903],{"id":50902},"block-storage","Block storage",[523,50905,50906],{},"Will give you block devices on which you can format as you need, just like a \"normal\" disk attached to your system. Block storage is used for applications, such as MySQL, PostgreSQL, and more, which need the \"raw\" performance of block devices and the caching coming with that.",[613,50908,50910],{"id":50909},"filesystem-storage","Filesystem storage",[523,50912,50913],{},"Is basically a \"normal\" filesystem which can be consumed directly. This is a good way to share data between multiple applications in a read and write a lot manner. This is commonly used to share AI models or scientific data between multiple running jobs or applications.",[523,50915,50916],{},[3049,50917,50918],{},"Technical note: if you have very very old\u002Flegacy applications which are not really 64bit compatible, you might run into (stat syscall used) problems when the filesystem is using 64bit inodes.",[613,50920,50922],{"id":50921},"object-storage","Object storage",[523,50924,50925],{},"Object storage is a very cloud native approach to storing data. You don’t store data on a block device and\u002For filesystem, you use a HTTP API. Most commonly known in the object storage field is Amazon Web Services S3 storage. There are also open source projects implementing (parts) of the S3 API to act as a drop-in replacement for AWS S3. Next to S3, there are also other object store APIs\u002Fprotocols, such as OpenStack Swift, Ceph Rados and more.",[523,50927,50928],{},"In the end it boils down to what are the needs of your applications, but I would definitely keep in mind what the different storage types can offer. If you narrowed down what storage type can be used, look into the storage software market to see which \"additional\" possibilities each software can give you for your storage needs.",[535,50930,50932],{"id":50931},"storage-in-a-cloud-native-world","Storage in a Cloud-Native world",[523,50934,50935],{},"In a Cloud-Native world, where everything is dynamic, distributed, and must be resilient, it is more important than ever to keep the feature set of your storage which is used for your customer data. It must be highly available all the time, resilient to failure of a server and\u002For application, and scale to the needs of your application(s).",[523,50937,50938],{},[3069,50939],{"alt":743,"src":50940},"\u002Fblog\u002F2019\u002Frook-more-than-ceph\u002Fscreenshot-2019-01-14-at-23.44.07-300x175.png",[523,50942,50943],{},"This might seem like an easy task if your are in the cloud, but even cloud have limits at a certain point. Though if you have special needs for anything in the cloud you are using, it will definitely help to talk with your cloud provider to resolve problems. The point of talking to your cloud provider(s) is important before and while you are using their proposal. As an example, if you should experience problems with the platform itself or scaling issues of, let’s say, block storage, you can directly give feedback to them about it and possibly work together with them to workout a fix for the issue. Or provide another product which will be able to scale to your current and future needs.",[523,50945,50946],{},"Storage is especially problematic when it comes to scale depending on the solution you are running\u002Fusing. Assuming your application in itself can scale without issues, but the storage runs into performance issues. In most cases you can’t just add ten more storage servers and the problem goes away. \"Zooming out\" of storage as a topic to persistence, one must accept that there are always certain limits to persisting data. Let it be the amount, speed, or consistency of data, there will always be a limit or at least a trade off.",[523,50948,50949],{},[3069,50950],{"alt":743,"src":50951},"\u002Fblog\u002F2019\u002Frook-more-than-ceph\u002Fscreenshot-2019-01-14-at-23.45.01-768x398.png",[6072,50953,50954],{},[523,50955,50956],{},"Rook is a framework to make it easy to bring storage backends to run inside Kubernetes.",[523,50958,50959],{},"A good example for such scaling limits is Facebook. To keep it short, Facebook at one point just \"admitted\" that there will always be a delay during replication of data\u002Finfo. They accept that when a user from Germany updates his profile that it can\u002Fwill take up to 3-5 minutes before users from e.g., Seattle, USA, will be able to see those changes.",[523,50961,50962],{},"To summarize this section: Your storage should be as Cloud-Native as your application. Talk with your cloud provider during testing and usage, keep them in the loop when you run into issues. Also don’t try to push limits which can’t be pushed right now at the current state of technology.",[535,50964,50966],{"id":50965},"what-can-rook-offer-for-your-kubernetes-cluster","What can Rook offer for your Kubernetes cluster?",[523,50968,50969],{},"Rook can turn all or selected nodes into \"Ceph storage servers\". This allows you to use \"wasted\" space from the nodes your Kubernetes cluster runs on. Next to \"just utilizing ‘wasted’ storage\", you don’t need to buy extra storage servers. You would just keep that in mind during planning the hardware for the Kubernetes cluster (figure 1).",[523,50971,50972],{},[3069,50973],{"alt":743,"src":50974},"\u002Fblog\u002F2019\u002Frook-more-than-ceph\u002Fscreenshot-2019-01-14-at-23.55.13-233x300.png",[523,50976,50977],{},"With running storage on the nodes your applications can also run on, the hyperconverged aspect is also kind of covered. You might not get more performance because of your application running on the same node as your storage with Ceph, but Ceph and Rook are aware of this and will possibly look into ways of improving this. Please note that Ceph’s priority will always be consistency even if speed needs to be sacrificed for that.",[523,50979,50980],{},"Ceph is not the only storage backend which can be run using Rook but more on that later.",[613,50982,50984],{"id":50983},"rook-kubernetes-integration","Rook Kubernetes integration",[523,50986,50987,50988,714,50990,587,50992,50994,50995,50998,50999,51001,51002,51004,51005,51007,51008,51011,51012,51014,51015,51017],{},"In Kubernetes you can consume storage for your applications, through these Kubernetes objects: ",[567,50989,27758],{},[567,50991,18374],{},[567,50993,32356],{},". Each of these objects has their own role. ",[567,50996,50997],{},"PersistentVolumeClaims"," are what users create to claim\u002Frequest storage for their applications. A ",[567,51000,27758],{}," is basically the user facing side of storage in Kubernetes as it is standing for a ",[567,51003,18374],{}," behind that. To enable users to consume storage easily through ",[567,51006,50997],{},", a Kubernetes administrator should create ",[567,51009,51010],{},"StorageClasses",". An administrator can create multiple ",[567,51013,51010],{}," and also define one as a default. A ",[567,51016,32356],{}," holds parameters which can be \"used\" during the provisioning process by the specific storage provider\u002Fdriver.",[523,51019,51020],{},"You see, Rook enables you to consume storage the Kubernetes native way. The way most operators work in point of their native Kubernetes integration is to watch \"simply\" for events happening to a certain selection of objects. \"Events\" are, e.g., that an object has been created, deleted, updated. This allows the operator to react to certain \"situations\" and act accordingly, e.g., when a watched object is deleted, the operator could run it’s own cleanup routines or with Rook as an example, the user creates a Ceph Cluster object and the operator begins to create all the components for the Ceph Cluster in Kubernetes.",[523,51022,51023,51024,11304,51026,51028],{},"To be able to have custom objects in Kubernetes, Rook uses ",[567,51025,18285],{},[567,51027,18285],{}," are a Kubernetes feature which allows users to specify their own objects in their Kubernetes clusters. These custom objects allow the user to abstract certain applications\u002Ftasks, e.g., with Rook the user is allowed to create one Ceph Cluster object and have the Rook Ceph operator create all the other objects (ConfigMaps, Secrets, Deployments and so on) in Kubernetes.",[523,51030,51031],{},"Onto the topic of how Kubernetes mounts the storage for your applications to be consumed: If you have already heard a bit about storage for containers, you may have come across CSI (Container Storage Interface). CSI is a standardized API to request storage. Instead of having to maintain drivers per storage backend in the Kubernetes project, the driver maintenance is moved to each storage backend itself, which allows faster fixes of issues with the driver. The normal process when there is an issue in an intree Kubernetes volume plugin is to go through the whole Kubernetes release process to get the fix out. The storage backend projects create a driver which implements the CSI driver interface\u002Fspecifications, through which Kubernetes and other platforms can the request storage.",[523,51033,51034],{},"For mounting Ceph volumes in Kubernetes, currently Rook uses the flexvolume driver which may require a small configuration change in existing Kubernetes clusters. Using CSI with Rook Ceph clusters will hopefully soon be possible when CSI support has been implemented in the Rook 0.9 release. Depending on how you see it flexvolume is just the mount (and unmount) part of what CSI is.",[535,51036,51038],{"id":51037},"running-ceph-with-rook-in-kubernetes","Running Ceph with Rook in Kubernetes",[523,51040,51041],{},"Objects in Kubernetes describe a state, e.g., a Pod object contains the state (info) on how a Pod must be created (container image, command to be run, ports to be open, and so on). The same applies to a Rook Ceph cluster object. A Rook Ceph cluster object describes the user desired state of a Ceph Cluster in their Kubernetes cluster. Below is an example of a basic Rook Ceph Cluster object:",[523,51043,51044],{},[3069,51045],{"alt":743,"src":51046},"\u002Fblog\u002F2019\u002Frook-more-than-ceph\u002Frook-ceph-cluster-yaml.png",[523,51048,51049,51050],{},"Not going into too much details about the example Rook Ceph Cluster object here, it will instruct the Rook Ceph operator to use all nodes in your cluster as long as they are applicable (don’t have taints and\u002For other \"restrictions\" on them). For each applicable node it will try to use all empty devices and store configs and some state data in the ",[567,51051,51052],{},"dataDirHostPath: \u002Fvar\u002Flib\u002Frook.",[523,51054,51055,51056,51059,51060,51063,51064,51066],{},"If you would search through the Kubernetes API reference you wouldn’t find this API (",[567,51057,51058],{},"ceph.rok.io\u002Fv1beta1",") nor the object kind Cluster. As written in the previous section, user defined APIs and objects (kinds) are introduced by a ",[567,51061,51062],{},"CustomResourceDefinition"," to the Kubernetes API. All ",[567,51065,51062],{}," of Rook are created during the installation of Rook in your Kubernetes cluster.",[523,51068,51069,51070,51073,51074,51077],{},"Creating the above object on your Kubernetes cluster, with the Rook Ceph operator running, would cause the Rook Ceph operator to react to the event that an object of type\u002F kind ",[567,51071,51072],{},"Clusterin"," the API ",[567,51075,51076],{},"ceph.rook.io\u002Fv1beta1"," has been created.",[523,51079,51080],{},"Before shortly going into what the Rook Ceph operator does now, I give a quick overview about how a \"standard\" Ceph cluster looks like. A Ceph cluster always has one or more Ceph Monitors which are the brain of the cluster, and a Ceph Manager which takes care of gathering metrics and doing other maintenance tasks. There are more components in a Ceph cluster, to focus on the third which is next to the Monitors and Manager the most important thing which will store your data. Ceph Object Storage Daemon (OSD) is the component which \"talks\" to a disk or directory to store and serve your data.",[523,51082,51083,51084,587,51086,51088,51089,51092],{},"The Rook Ceph operator will start and manage the Ceph monitors, Ceph Manager and Ceph OSDs for you. To store data in so called Pools in your Ceph cluster, the user can simply create a Pool object. Again the Rook Ceph operator will take of it and in this create a Ceph pool. The pool can then directly be consumed using a ",[567,51085,32356],{},[567,51087,50997],{}," to dynamically get ",[567,51090,51091],{},"PersistentVolumes"," provisioned for your applications.",[523,51094,51095],{},"This is how simple it is to run a Ceph cluster inside Kubernetes and consume the storage of the Ceph cluster.",[535,51097,51099],{"id":51098},"rook-is-more-than-just-ceph","Rook is more than just Ceph",[523,51101,51102,51103,51105],{},"Rook is a framework to make it easy to bring storage backendstoruninsideof Kubernetes. Thefocusfor Rookistonot only bringing Ceph which is for block, filesystem and object storage, but also for persistence on a more application specific level by running CockroachDB and Minio through a Rook operator. Due to have the abstraction of complex tasks\u002Fapplications through ",[567,51104,18285],{}," in Kubernetes, it is as simple as deploying a Ceph Cluster as shown with the above code snippet.",[523,51107,51108],{},"To give a quick overview of the currently implemented storage backends besides Ceph, here is a list of the other storage backends:",[668,51110,51111,51114,51117],{},[638,51112,51113],{},"Minio – Minio is an open source object storage which implements the S3 API.",[638,51115,51116],{},"CockroachDB – CockroachDB provides ultraresilient SQL for global business. Rook allows you to run it through one object to ease the deployment of CockroachDB.",[638,51118,51119,51120,1909],{},"NFS – NFS exports are provided through the NFS Ganesha server on top of arbitrary ",[567,51121,50997],{},[523,51123,51124],{},"For more information on the state and availability of each storage backend, please look at \"Project Status\" section in the README file in the Rook GitHub project. Please note that not all storage backends here are available in Rook version 0.8, which is at the point of writing this article the latest version, some are currently only in the latest development version but a 0.9 release is targeted to happen soon.",[535,51126,51128],{"id":51127},"rook-project-roadmap","Rook project roadmap",[523,51130,51131],{},"To give you an outlook of what can be to come up, a summary of the current Rook project roadmap:",[668,51133,51134,51140,51142,51144,51146,51148,51151,51154,51157,51160,51167],{},[638,51135,51136,51137,51139],{},"Further stabilization for the ",[567,51138,18285],{}," specifications and managing\u002Forchestration logic:",[638,51141,427],{},[638,51143,14667],{},[638,51145,14673],{},[638,51147,457],{},[638,51149,51150],{},"Dynamic provisioning of filesystem storage for Ceph.",[638,51152,51153],{},"Decoupling the Ceph version from Rook to allow the users to run \"any\" Ceph version.",[638,51155,51156],{},"Simpler and better disk management to allow adding, removing and replacing disks in Rook Ceph cluster.",[638,51158,51159],{},"Adding Cassandra as a new storage provider",[638,51161,51162,51163,51166],{},"Object Storage user ",[567,51164,51165],{},"CustomResourceDefinition,"," to allow managing users by creating, deleting and modifying objects in Kubernetes.",[638,51168,51169],{},"There is more to come for a more detailed roadmap, please look at the roadmap file in the Rook GitHub project.",[613,51171,51172],{"id":15045},"How to get involved?",[523,51174,15049],{},[668,51176,51177,51180,51186,51189,51195,51200,51208],{},[638,51178,51179],{},"Twitter – @rook_io",[638,51181,51182,51183],{},"Slack – ",[527,51184,15063],{"href":15063,"rel":51185},[531],[638,51187,51188],{},"For conferences and meetups: Checkout the #conferences Slack Channel",[638,51190,51191,51192],{},"Contribute to Rook: ",[527,51193,15070],{"href":15070,"rel":51194},[531],[638,51196,51197],{},[527,51198,13751],{"href":13751,"rel":51199},[531],[638,51201,51202,51203,51207],{},"Forums – ",[527,51204,51205],{"href":51205,"rel":51206},"https:\u002F\u002Fgroups.google.com\u002Fforum\u002F#!forum\u002F",[531]," rook-dev",[638,51209,15092],{},{"title":743,"searchDepth":761,"depth":761,"links":51211},[51212,51213,51214,51219,51220,51223,51224,51225],{"id":14586,"depth":761,"text":14587},{"id":50882,"depth":761,"text":50883},{"id":50898,"depth":761,"text":50899,"children":51215},[51216,51217,51218],{"id":50902,"depth":769,"text":50903},{"id":50909,"depth":769,"text":50910},{"id":50921,"depth":769,"text":50922},{"id":50931,"depth":761,"text":50932},{"id":50965,"depth":761,"text":50966,"children":51221},[51222],{"id":50983,"depth":769,"text":50984},{"id":51037,"depth":761,"text":51038},{"id":51098,"depth":761,"text":51099},{"id":51127,"depth":761,"text":51128,"children":51226},[51227],{"id":15045,"depth":769,"text":51172},"2019-01-07T08:13:53+01:00","Cross-Post of my \"Rook more than Ceph\" article from \"The Cloud Report\"",{"src":51231},"\u002Fblog\u002Fcovers\u002Fceph-rook-logos.png",{"tags":51233},[15155,465,427],"\u002Fblog\u002F2019\u002Frook-more-than-ceph",{"title":50856,"description":51229},"3.blog\u002F2019\u002Frook-more-than-ceph","3B2M9EHWRpZXFTtbQh8Z2vNhb3nIs1bBRgj_MbQEJ44",{"id":51239,"title":51240,"authors":51241,"badge":518,"body":51244,"date":52177,"description":52178,"extension":2911,"image":52179,"meta":52180,"navigation":1254,"path":52182,"seo":52183,"stem":52184,"__hash__":52185},"posts\u002F3.blog\u002F2018\u002Fceph-day-berlin-2018.md","Ceph Day Berlin 2018",[51242],{"name":514,"to":515,"avatar":51243},{"src":517},{"type":520,"value":51245,"toc":52155},[51246,51262,51266,51274,51278,51284,51298,51304,51312,51318,51321,51327,51331,51335,51341,51344,51347,51356,51362,51368,51374,51380,51383,51393,51399,51402,51405,51411,51414,51418,51424,51431,51446,51449,51455,51458,51464,51467,51473,51479,51486,51489,51492,51495,51499,51505,51508,51511,51517,51522,51525,51531,51537,51540,51546,51549,51553,51567,51573,51579,51583,51589,51597,51602,51605,51608,51614,51617,51623,51626,51632,51635,51638,51644,51650,51656,51659,51663,51669,51675,51678,51686,51706,51712,51718,51721,51725,51731,51737,51753,51770,51773,51779,51782,51788,51794,51805,51811,51817,51820,51824,51830,51833,51839,51842,51848,51852,51855,51862,51868,51882,51886,51892,51897,51903,51906,51909,51915,51921,51927,51930,51934,51944,51950,51956,51962,51968,51971,51994,51998,52004,52010,52015,52021,52027,52030,52033,52039,52045,52052,52058,52064,52068,52074,52079,52082,52085,52088,52094,52100,52103,52106,52112,52116,52122,52125,52129,52135,52138,52141,52143,52146,52153],[6072,51247,51248,51252,51255,51259],{},[523,51249,51250],{},[584,51251,6189],{},[523,51253,51254],{},"All credit for the slides in the pictures goes to their creators!",[523,51256,51257],{},[584,51258,6189],{},[523,51260,51261],{},"If you are in one of these pictures and want it removed, please contact me by email (see about\u002Fimprint page).",[535,51263,51265],{"id":51264},"slides","Slides",[523,51267,51268,51269,1909],{},"The slides of the talks can be found here: ",[527,51270,51273],{"href":51271,"rel":51272},"https:\u002F\u002Fwww.slideshare.net\u002FInktank_Ceph",[531],"Ceph Community  presentations channel - SlideShare",[535,51275,51277],{"id":51276},"welcome-kickoff","Welcome & Kickoff",[523,51279,51280],{},[3069,51281],{"alt":51282,"src":51283},"Ceph Day Berlin 2018 - Cloudical team arrived at the conference center","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_083629.jpg",[523,51285,51286,51287,51292,51293,1909],{},"I arrived with my colleagues from ",[527,51288,51291],{"href":51289,"rel":51290},"https:\u002F\u002Fcloudical.io\u002F",[531],"Cloudical"," at the Ceph Day Berlin location, which at the same time was the location for ",[527,51294,51297],{"href":51295,"rel":51296},"https:\u002F\u002Fwww.openstack.org\u002Fsummit\u002Fberlin-2018\u002F",[531],"OpenStack Summit",[523,51299,51300],{},[3069,51301],{"alt":51302,"src":51303},"Ceph Day Berlin 2018 - Ceph Day Sponsors","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_091336.jpg",[523,51305,51306,51311],{},[527,51307,51310],{"href":51308,"rel":51309},"https:\u002F\u002Ftwitter.com\u002Fliewegas",[531],"Sage Weil"," announced that the Ceph Foundation has been founded with help from the Linux Foundation.",[523,51313,51314],{},[3069,51315],{"alt":51316,"src":51317},"Ceph Day Berlin 2018 - Ceph Foundation","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_091637.jpg",[523,51319,51320],{},"Cephalocon Barcelona has been announced. It will take place just \"before\" KubeCon and just shows that the Ceph team wants to be storage for cloud and containers.",[523,51322,51323],{},[3069,51324],{"alt":51325,"src":51326},"Ceph Day Berlin 2018 - Cephalocon Barcelona announcement","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_092128.jpg",[535,51328,51330],{"id":51329},"talks","Talks",[613,51332,51334],{"id":51333},"state-of-ceph-sage-weil-red-hat","State Of Ceph, Sage Weil, Red Hat",[523,51336,51337],{},[3069,51338],{"alt":51339,"src":51340},"Ceph Day Berlin 2018 - Ceph Release Schedule Overview","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_092242.jpg",[523,51342,51343],{},"There will be a telemetry module for the Ceph MGR but it will be opt-in. The telemetry data will be anonymized and only \"basic\" stats such as OSD count, cluster size and so on are transmitted.",[523,51345,51346],{},"To help Ceph clusters with their reliability, features have been added to take the health of devices\u002Fdisks into account. Disk failure prediction can be used to preemptively move data to other disks\u002Fservers before a failure to reduce recovery time and cluster load.",[523,51348,51349,51350,51355],{},"The Ceph MGR in general and the Ceph MGR dashboard module have been further improved by ",[527,51351,51354],{"href":51352,"rel":51353},"https:\u002F\u002Fgithub.com\u002Fjcsp",[531],"John Spray",".\nAdditionally to the Ceph MGR becoming more and more stable, the REST API module for the MGR has been improved. The REST API isn't completely \"there\" yet, but it is actively being worked on.",[523,51357,51358],{},[3069,51359],{"alt":51360,"src":51361},"Ceph Day Berlin 2018 - State Of Ceph, Sage Weil, Red Hat - Automation and Management","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_092350.jpg",[523,51363,51364],{},[3069,51365],{"alt":51366,"src":51367},"Ceph Day Berlin 2018 - State Of Ceph, Sage Weil, Red Hat - Orchestrator Sandwhich","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_092726.jpg",[523,51369,51370],{},[3069,51371],{"alt":51372,"src":51373},"Ceph Day Berlin 2018 - State Of Ceph, Sage Weil, Red Hat - Kubernetes Above and Below","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_092913.jpg",[523,51375,51376],{},[3069,51377],{"alt":51378,"src":51379},"Ceph Day Berlin 2018 - State Of Ceph, Sage Weil, Red Hat - Rook","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_093016.jpg",[523,51381,51382],{},"The goal for Ceph in Kubernetes is to further go the cloud-native way by making it more and more easy to have storage for containers.",[523,51384,51385,51388,51389,51392],{},[567,51386,51387],{},"ceph top"," is like ",[567,51390,51391],{},"top"," but for Ceph cluster. It will show you the current \"load\"\u002Fusage of the whole Ceph cluster.",[523,51394,51395,51398],{},[567,51396,51397],{},"cephfs-shell"," is a command cli which allows to work with the CephFS without \"mounting\" it. That is perfect for quickly putting files, directories and setting quotas on a CephFS through scripts\u002Fautomation.",[523,51400,51401],{},"Project Crimson is looking into re-implementing the OSD data path for better performance, with a focus on \"new\" devices, e.g., flash and NVME storage.",[523,51403,51404],{},"For new modern IT infrastructures, it is planned to \"Reframe Ceph RGW\". This is done to make it more suitable for modern IT infrastructures which most of the time rely on multiple cloud providers\u002Fdatacenter.",[523,51406,51407],{},[3069,51408],{"alt":51409,"src":51410},"Ceph Day Berlin 2018 - State Of Ceph, Sage Weil, Red Hat - Hardware is changing","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_093803.jpg",[523,51412,51413],{},"RGW federation\u002Fsync can allow you to have global user and bucket namespaces in sync over multiple Ceph RGW clusters\u002Fzones.\nRGW sync (now) available to e.g., sync an on-premise Ceph RGW cluster with an AWS S3 for \"backup\" or just keep two (or more) Ceph RGW clusters in sync.",[613,51415,51417],{"id":51416},"managing-and-monitoring-ceph-with-the-ceph-manager-dashboard-lenz-grimmer-suse","Managing and Monitoring Ceph with the Ceph Manager Dashboard, Lenz Grimmer, SUSE",[523,51419,51420],{},[3069,51421],{"alt":51422,"src":51423},"Ceph Day Berlin 2018 - Managing and Monitoring Ceph with the Ceph Manager Dashboard, Lenz Grimmer, SUSE - Title Slide","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_094522.jpg",[6072,51425,51426],{},[523,51427,51428,51430],{},[584,51429,6189],{}," He has a big Rook sticker on his laptop, which is totally cool as they are currently nowhere available anymore. :-)",[523,51432,51433,51434,51439,51440,51445],{},"They mentioned at last ",[527,51435,51438],{"href":51436,"rel":51437},"https:\u002F\u002Fceph.com\u002Fcephdays\u002Fgermany\u002F",[531],"Ceph Day Germany in Darmstadt"," that the dashboard was available now and is hugely inspired by the ",[527,51441,51444],{"href":51442,"rel":51443},"https:\u002F\u002Fwww.openattic.org\u002F",[531],"OpenATTIC"," project.\nSo thanks for them to put the work into the official Ceph MGR dashboard module!",[523,51447,51448],{},"They have more features coming up for the Ceph Nautilus release. A big part will be to allow even further configuration over the web with ease.",[523,51450,51451],{},[3069,51452],{"alt":51453,"src":51454},"Ceph Day Berlin 2018 - Managing and Monitoring Ceph with the Ceph Manager Dashboard, Lenz Grimmer, SUSE - Dashboard v2 Overview (Mimic)","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_095006.jpg",[523,51456,51457],{},"I'm especially happy to see the in-built SAML2 support and the auditing support which will be useful for companies.",[523,51459,51460],{},[3069,51461],{"alt":51462,"src":51463},"Ceph Day Berlin 2018 - Managing and Monitoring Ceph with the Ceph Manager Dashboard, Lenz Grimmer, SUSE - New Dashboard features for Nautilus","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_095333.jpg",[523,51465,51466],{},"You can also have a per server overview page with metrics displayed through Grafana.",[523,51468,51469],{},[3069,51470],{"alt":51471,"src":51472},"Ceph Day Berlin 2018 - Managing and Monitoring Ceph with the Ceph Manager Dashboard, Lenz Grimmer, SUSE - Dashboard Screenshot #1","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_095702.jpg",[523,51474,51475],{},[3069,51476],{"alt":51477,"src":51478},"Ceph Day Berlin 2018 - Managing and Monitoring Ceph with the Ceph Manager Dashboard, Lenz Grimmer, SUSE - Dashboard Screenshot #2","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_095900.jpg",[523,51480,51481,51482,51485],{},"Next to \"just being a dashboard\", as mentioned earlier there is a focus on allowing a user to make changes to the Ceph config through the Ceph MGR dashboard.\nCreating snapshots, clones of ",[567,51483,51484],{},"rbd"," images is now also possible through the dashboard.",[523,51487,51488],{},"Even if it is a small thing, thanks to a user contribution You can now see as which user you are logged into the dashboard now.",[523,51490,51491],{},"To summarize, the dashboard can not only show but can also create, modify and also delete \"things\" in Ceph and edit configurations.",[523,51493,51494],{},"An outlook for the dashboard is to integrate the upcoming orchestration layer of the Ceph MGR.",[613,51496,51498],{"id":51497},"building-a-ceph-storage-appliance-thats-cooler-than-a-dog-phil-straw-softiron","Building a Ceph Storage Appliance That's Cooler Than a Dog, Phil Straw, SoftIron",[523,51500,51501],{},[3069,51502],{"alt":51503,"src":51504},"Ceph Day Berlin 2018 - Building a Ceph Storage Appliance That's Cooler Than a Dog, Phil Straw, SoftIron - Title Slide","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_104610.jpg",[523,51506,51507],{},"SoftIron does a lot of thermal analysis of servers.",[523,51509,51510],{},"When they got their new thermal camera, next to taking pictures of dogs with it, they took pictures of their competitors and their own servers.\nThey do that to see their server cooling optimization against the competition:",[523,51512,51513],{},[3069,51514],{"alt":51515,"src":51516},"Ceph Day Berlin 2018 - Building a Ceph Storage Appliance That's Cooler Than a Dog, Phil Straw, SoftIron - 'And the second thing?' - Using thermal camera on servers","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_104844.jpg",[6072,51518,51519],{},[523,51520,51521],{},"\"Power is heat\", Power costs money, cooling also costs money = A lot of money",[523,51523,51524],{},"If the design of the servers is optimized for \"being cool\", one can potentially get back parts\u002Fall of their costs of the equipment back through saving on cooling costs.\nThough in most cases this would require separate datacenter rooms for the optimized servers with less cooling.",[523,51526,51527],{},[3069,51528],{"alt":51529,"src":51530},"Ceph Day Berlin 2018 - Building a Ceph Storage Appliance That's Cooler Than a Dog, Phil Straw, SoftIron - 'Thermal Analysis' server comparison","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_105034.jpg",[523,51532,51533],{},[3069,51534],{"alt":51535,"src":51536},"Ceph Day Berlin 2018 - Building a Ceph Storage Appliance That's Cooler Than a Dog, Phil Straw, SoftIron - 'Derivation of \"Dog Power\"- Rest'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_105155.jpg",[523,51538,51539],{},"A round of applause for their dog.",[523,51541,51542],{},[3069,51543],{"alt":51544,"src":51545},"Ceph Day Berlin 2018 - Building a Ceph Storage Appliance That's Cooler Than a Dog, Phil Straw, SoftIron - 'How do we do it?'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_105952.jpg",[523,51547,51548],{},"In the end their goal is to have \"cool\" servers which can \"quickly\" get back the costs through the servers reduced cooling needs.",[613,51550,51552],{"id":51551},"unlimited-fileserver-with-samba-ctdb-and-cephfs-robert-sander-heinlein-support","Unlimited Fileserver with Samba CTDB and CephFS, Robert Sander, Heinlein Support",[6072,51554,51555,51559],{},[523,51556,51557],{},[584,51558,6189],{},[523,51560,51561,51562,51566],{},"As this isn't really a topic which falls into my interest area. I'd recommend to checkout the full slides of the talk on the ",[527,51563,51565],{"href":51564},"#slides","SlideShare",". Now have a few pictures without too much comments from my side:",[523,51568,51569],{},[3069,51570],{"alt":51571,"src":51572},"Ceph Day Berlin 2018 - Unlimited Fileserver with Samba CTDB and CephFS, Robert Sander, Heinlein Support - 'Concept'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_110331.jpg",[523,51574,51575],{},[3069,51576],{"alt":51577,"src":51578},"Ceph Day Berlin 2018 - Unlimited Fileserver with Samba CTDB and CephFS, Robert Sander, Heinlein Support - 'CTDB - clustered trivial database'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_110847.jpg",[613,51580,51582],{"id":51581},"ceph-implementations-for-the-meerkat-radio-telescope-bennett-sarao-ska-africa","Ceph implementations for the MeerKAT radio telescope, Bennett SARAO, SKA Africa",[523,51584,51585],{},[3069,51586],{"alt":51587,"src":51588},"Ceph Day Berlin 2018 - Ceph implementations for the MeerKAT radio telescope, Bennett SARAO, SKA Africa - Title Slide","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_112547.jpg",[523,51590,51591,51592,1909],{},"After some technical difficulties, he started talking about their work with Ceph at ",[527,51593,51596],{"href":51594,"rel":51595},"https:\u002F\u002Fwww.skatelescope.org\u002F",[531],"SKA Africa",[6072,51598,51599],{},[523,51600,51601],{},"\"All radio telescopes have received less energy than a snowflake hitting the ground.\"",[523,51603,51604],{},"This comment just makes it more and more interesting of how sensitive the radio dishes must be and with that how much data is coming from the sensors.",[523,51606,51607],{},"With more radio dishes the quality of pictures generated from the observations increases, resulting in a picture of the \"sky\"\u002Funiverse which is more and more clear.",[523,51609,51610],{},[3069,51611],{"alt":51612,"src":51613},"Ceph Day Berlin 2018 - Ceph implementations for the MeerKAT radio telescope, Bennett SARAO, SKA Africa - 'A fuller picture'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_113048.jpg",[523,51615,51616],{},"All these radio dishes create an enormous amount of data which needs to be saved, this is where Ceph comes into play.",[523,51618,51619],{},[3069,51620],{"alt":51621,"src":51622},"Ceph Day Berlin 2018 - Ceph implementations for the MeerKAT radio telescope, Bennett SARAO, SKA Africa - 'Radio Telescopes - In a nutshell'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_113927.jpg",[523,51624,51625],{},"They have tons of data flowing in from the radios dishes which doesn't only need to be written but also read again and worked on in a timely manner.\nA problem they had to solve is the data transfer between the radio dishes and the datacenter, which is over 900 kilometers away.\nThey shielded their data lines so that it \"survives\" the 900 kilometer transfer.",[523,51627,51628],{},[3069,51629],{"alt":51630,"src":51631},"Ceph Day Berlin 2018 - Ceph implementations for the MeerKAT radio telescope, Bennett SARAO, SKA Africa - 'SDP Data Rates'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_114031.jpg",[523,51633,51634],{},"What I didn't think is that they use Ceph RGW S3 storage. It just shows how good object storage can be for such amounts of data in their use case.",[523,51636,51637],{},"As they had project budget problems, because of the \"decline\" of the African dollar in comparison to the US dollar, they used available government programs for such technological projects which brought them together with local IT companies to save costs for the hardware used at the project.",[523,51639,51640],{},[3069,51641],{"alt":51642,"src":51643},"Ceph Day Berlin 2018 - Ceph implementations for the MeerKAT radio telescope, Bennett SARAO, SKA Africa - 'Ceph - MeerKAT cluster to SeeKAT cluster'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_114447.jpg",[523,51645,51646],{},[3069,51647],{"alt":51648,"src":51649},"Ceph Day Berlin 2018 - Ceph implementations for the MeerKAT radio telescope, Bennett SARAO, SKA Africa - 'Ceph Hardware Platform'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_114839.jpg",[523,51651,51652],{},[3069,51653],{"alt":51654,"src":51655},"Ceph Day Berlin 2018 - Ceph implementations for the MeerKAT radio telescope, Bennett SARAO, SKA Africa - '16 Node Ceph Cluster - Production until end November 2018'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_115345_1.jpg",[523,51657,51658],{},"Interesting insights were given in the talk in how Ceph is used for such amounts from data for scientific research.",[613,51660,51662],{"id":51661},"disk-health-prediction-and-resource-allocation-for-ceph-by-using-machine-learning-jeremy-wei-prophetstor","Disk health prediction and resource allocation for Ceph by using machine learning, Jeremy Wei, Prophetstor",[523,51664,51665],{},[3069,51666],{"alt":51667,"src":51668},"Ceph Day Berlin 2018 - Disk health prediction and resource allocation for Ceph by using machine learning, Jeremy Wei, Prophetstor - 'Major Stability problem: Ceph Cluster'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_115752.jpg",[523,51670,51671],{},[3069,51672],{"alt":51673,"src":51674},"Ceph Day Berlin 2018 - Disk health prediction and resource allocation for Ceph by using machine learning, Jeremy Wei, Prophetstor - 'Ceph DiskPrediction Plugin'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_120004.jpg",[523,51676,51677],{},"The disk health prediction is\u002Fwill be merged into Ceph Mimic to allow for smarter data placement and\u002For preemptive movement of data before a disk fails.\nThere will also be a mode for cloud providers to read the health of used cloud provider storage volume(s) and to act accordingly before there would be a failure on the cloud provider site in point of performance and\u002For latency hits.",[523,51679,51680,51685],{},[527,51681,51684],{"href":51682,"rel":51683},"https:\u002F\u002Fwww.prophetstor.com",[531],"Prophetstor"," will offer a commercial edition which has further support for even better detection and especially interesting anomaly detection for disks.",[6072,51687,51688,51692],{},[523,51689,51690],{},[584,51691,6189],{},[523,51693,51694,51699,51700,51705],{},[527,51695,51698],{"href":51696,"rel":51697},"https:\u002F\u002Fgithub.com\u002Fcontainers-ai\u002FAlameda",[531],"Alameda"," is the open source project for such resource predictions and failure detection. A ",[527,51701,51704],{"href":51702,"rel":51703},"https:\u002F\u002Fgithub.com\u002Frook\u002Frook\u002Fpull\u002F2182",[531],"pull request"," is open at the Rook.io project for a design document.",[523,51707,51708],{},[3069,51709],{"alt":51710,"src":51711},"Ceph Day Berlin 2018 - Disk health prediction and resource allocation for Ceph by using machine learning, Jeremy Wei, Prophetstor - 'The Brain of Resources Orchestrator for Kubernetes'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_120622.jpg",[523,51713,51714],{},[3069,51715],{"alt":51716,"src":51717},"Ceph Day Berlin 2018 - Disk health prediction and resource allocation for Ceph by using machine learning, Jeremy Wei, Prophetstor - 'Pod Allocation Before\u002FAfter Alameda Enabled'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_120740.jpg",[523,51719,51720],{},"Utilizing Kubernetes seems like the perfect way here as the workload in the Kubernetes cluster can be automatically adjusted\u002Fmoved depending on the predicted information.",[613,51722,51724],{"id":51723},"mastering-ceph-operations-upmap-and-the-mgr-balancer-dan-van-der-ster-cern","Mastering Ceph Operations: Upmap and the Mgr Balancer, Dan van der Ster, CERN",[523,51726,51727],{},[3069,51728],{"alt":51729,"src":51730},"Ceph Day Berlin 2018 - Mastering Ceph Operations: Upmap and the Mgr Balancer, Dan van der Ster, CERN - 'CephFS Scale Testing'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_130923.jpg",[523,51732,51733],{},[3069,51734],{"alt":51735,"src":51736},"Ceph Day Berlin 2018 - Mastering Ceph Operations: Upmap and the Mgr Balancer, Dan van der Ster, CERN - 'Do we really need CRUSH?'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_131310.jpg",[523,51738,51739,51740,51747,51748,1909],{},"In Luminous there is a new feature named ",[527,51741,51744],{"href":51742,"rel":51743},"http:\u002F\u002Fdocs.ceph.com\u002Fdocs\u002Fmimic\u002Frados\u002Foperations\u002Fupmap\u002F",[531],[567,51745,51746],{},"upmap"," and a ",[527,51749,51752],{"href":51750,"rel":51751},"http:\u002F\u002Fdocs.ceph.com\u002Fdocs\u002Fmimic\u002Fmgr\u002Fbalancer\u002F",[531],"PG balancer",[668,51754,51755,51763],{},[638,51756,51757,51762],{},[527,51758,51760],{"href":51742,"rel":51759},[531],[567,51761,51746],{}," - Allows you to move PGs exactly where you want them.",[638,51764,51765,51769],{},[527,51766,51768],{"href":51750,"rel":51767},[531],"PG Balancer"," - Can automatically balance PGs between servers.",[523,51771,51772],{},"The PG balancer allowed CERN to recover terrabytes of data because of how PGs were automaticallly rebalanced between OSDs.",[523,51774,51775],{},[3069,51776],{"alt":51777,"src":51778},"Ceph Day Berlin 2018 - Mastering Ceph Operations: Upmap and the Mgr Balancer, Dan van der Ster, CERN - 'Turning on the balancer (luminous)'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_131659.jpg",[523,51780,51781],{},"(You need to restart the MGR (in Luminous) when this configuration has been set)",[523,51783,51784],{},[3069,51785],{"alt":51786,"src":51787},"Ceph Day Berlin 2018 - Mastering Ceph Operations: Upmap and the Mgr Balancer, Dan van der Ster, CERN - 'A brief interlude...'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_131855.jpg",[523,51789,51790],{},[3069,51791],{"alt":51792,"src":51793},"Ceph Day Berlin 2018 - Mastering Ceph Operations: Upmap and the Mgr Balancer, Dan van der Ster, CERN - 'Adding capacity with upmap'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_132154.jpg",[523,51795,51796,51798,51799,51801,51802,51804],{},[567,51797,51746],{}," allows you to not worry about changes that would affect your PGs in point of being moved and\u002For rebalanced. Using ",[567,51800,51746],{}," would basically allow you \"pin\"\u002Fmap PGs to \"stay\" where they are or \"force\" them to somewhere else.\nThis is extremely useful if you change placement options which would normally require (for big amounts of data) weeks long of PG rebalancing. In such a case you would just ",[567,51803,51746],{}," the PGs and they stay where they are when you made your placement changes.",[523,51806,51807],{},[3069,51808],{"alt":51809,"src":51810},"Ceph Day Berlin 2018 - Mastering Ceph Operations: Upmap and the Mgr Balancer, Dan van der Ster, CERN - 'No leap of faith required'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_132720.jpg",[523,51812,51813],{},[3069,51814],{"alt":51815,"src":51816},"Ceph Day Berlin 2018 - Mastering Ceph Operations: Upmap and the Mgr Balancer, Dan van der Ster, CERN - 'What's next for \"upmap remapped\"'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_132725.jpg",[523,51818,51819],{},"I think this would make a great core feature for Ceph. Though I think it would need to see improvements in user experience as it seems a bit complicated without as he said \"their scripts\" which generated most of their commands.",[613,51821,51823],{"id":51822},"deploying-ceph-in-kubernetes-with-rook-sebastian-wagner-suse","Deploying Ceph in Kubernetes with Rook, Sebastian Wagner, SUSE",[523,51825,51826],{},[3069,51827],{"alt":51828,"src":51829},"Ceph Day Berlin 2018 - Deploying Ceph in Kubernetes with Rook, Sebastian Wagner, SUSE - Title Slide","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_133144.jpg",[523,51831,51832],{},"It is good to see SUSE and RedHat talk about Rook.",[523,51834,51835],{},[3069,51836],{"alt":51837,"src":51838},"Ceph Day Berlin 2018 - Deploying Ceph in Kubernetes with Rook, Sebastian Wagner, SUSE - 'Integration into Ceph'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_134118.jpg",[523,51840,51841],{},"A big point which is partly going to be \"solved\" by the MGR orchestration layer\u002Fmodule, that the orchestration \"systems\", e.g., Rook, Ansible, DeepSEA and others, can simply integrate\u002Fimplement the \"bridge\" to be able to be used as a orchestration \"helper\".\nIn the end, it shouldn't matter if you want to run Ceph using Kubernetes, on bare metal using Ansible or DeepSEA and other possible environments. The Ceph MGR is currently, with the orchestration layer\u002Fmodule targeted to be the interface to do that.",[523,51843,51844,51845,1909],{},"If you want information about Rook, I would recommend to checkout the Rook project homepage: ",[527,51846,13751],{"href":13751,"rel":51847},[531],[613,51849,51851],{"id":51850},"ceph-management-the-easy-and-reliable-way-martin-verges-croit","Ceph management the easy and reliable way, Martin Verges, croit",[523,51853,51854],{},"Their approach boots the OS in an in-ram overlay filesystem for simple and easy updating. In addition to that, new servers register themselves by a \"config\" given to them by the PXE server.",[523,51856,51857,51858,51861],{},"When the PXE server is setup each node just needs to PXE boot, then one can select the nodes and disks on the nodes, and click the \"Create\" button in their webinterface to manage the node(s). ",[567,51859,51860],{},"ceph-volume"," will then be used to provision the disks for use as OSDs in Ceph.",[523,51863,51864],{},[3069,51865],{"alt":51866,"src":51867},"Ceph Day Berlin 2018 - Ceph management the easy and reliable way, Martin Verges, croit - 'Is it Possible to Beat the Prices of Amazon Glacier with Ceph?'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_135442.jpg",[523,51869,51870,51871,51876,51877,1909],{},"There is a Vagrant demo available for ",[527,51872,51875],{"href":51873,"rel":51874},"https:\u002F\u002Fcroit.io\u002F",[531],"croit"," in action, see ",[527,51878,51881],{"href":51879,"rel":51880},"https:\u002F\u002Fgithub.com\u002Fcroit\u002Fvagrant-demo",[531],"GitHub croit\u002Fvagrant-demo",[613,51883,51885],{"id":51884},"_5-reasons-to-use-arm-based-micro-server-architecture-for-ceph-storage-aaron-joue-ambedded-technology","5 reasons to use Arm-based micro-server architecture for Ceph Storage, Aaron Joue, Ambedded Technology",[523,51887,51888],{},[3069,51889],{"alt":51890,"src":51891},"Ceph Day Berlin 2018 - 5 reasons to use Arm-based micro-server architecture for Ceph Storage, Aaron Joue, Ambedded Technology - 'Ceph is Scalable & No Single Point of Failure'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_143157.jpg",[6072,51893,51894],{},[523,51895,51896],{},"\"Even with Ceph, hardware failure is painful.\"",[523,51898,51899],{},[3069,51900],{"alt":51901,"src":51902},"Ceph Day Berlin 2018 - 5 reasons to use Arm-based micro-server architecture for Ceph Storage, Aaron Joue, Ambedded Technology - '(1) Minimize the Failure Domain'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_143730.jpg",[523,51904,51905],{},"Using ARM based servers in a \"certain way\" allows to have the same performance at lower server and power costs.",[523,51907,51908],{},"Due to the servers using less power, you end up with a higher density than with most \"normal\" servers.",[523,51910,51911],{},[3069,51912],{"alt":51913,"src":51914},"Ceph Day Berlin 2018 - 5 reasons to use Arm-based micro-server architecture for Ceph Storage, Aaron Joue, Ambedded Technology - 'Arm-based Micro-Server Architecture'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_143845.jpg",[523,51916,51917],{},[3069,51918],{"alt":51919,"src":51920},"Ceph Day Berlin 2018 - 5 reasons to use Arm-based micro-server architecture for Ceph Storage, Aaron Joue, Ambedded Technology - '(3) Bonus: Reduce Power Consumprtion'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_144155.jpg",[523,51922,51923],{},[3069,51924],{"alt":51925,"src":51926},"Ceph Day Berlin 2018 - 5 reasons to use Arm-based micro-server architecture for Ceph Storage, Aaron Joue, Ambedded Technology - 'Object Store Performance'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_144653.jpg",[523,51928,51929],{},"It is good to see performance benchmarks for Arm64 servers.",[613,51931,51933],{"id":51932},"practical-cephfs-with-nfs-today-using-openstack-manila-tom-barron-red-hat","Practical CephFS with NFS today using OpenStack Manila, Tom Barron, Red Hat",[6072,51935,51936,51940],{},[523,51937,51938],{},[584,51939,6189],{},[523,51941,51561,51942,51566],{},[527,51943,51565],{"href":51564},[523,51945,51946],{},[3069,51947],{"alt":51948,"src":51949},"Ceph Day Berlin 2018 - Practical CephFS with NFS today using OpenStack Manila, Tom Barron, Red Hat - 'There's a perfectly good native CephFS solution for Manila'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_150046.jpg",[523,51951,51952],{},[3069,51953],{"alt":51954,"src":51955},"Ceph Day Berlin 2018 - Practical CephFS with NFS today using OpenStack Manila, Tom Barron, Red Hat - 'Why NFS Ganesha?'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_150209.jpg",[523,51957,51958],{},[3069,51959],{"alt":51960,"src":51961},"Ceph Day Berlin 2018 - Practical CephFS with NFS today using OpenStack Manila, Tom Barron, Red Hat - 'CephFS NFS driver deployment with TripleO'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_150429.jpg",[523,51963,51964],{},[3069,51965],{"alt":51966,"src":51967},"Ceph Day Berlin 2018 - Practical CephFS with NFS today using OpenStack Manila, Tom Barron, Red Hat - 'Current CephFS NFS Driver'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_151716.jpg",[523,51969,51970],{},"Software mentioned in the presentation slides linked here for your convenience:",[668,51972,51973,51980,51987],{},[638,51974,51975],{},[527,51976,51979],{"href":51977,"rel":51978},"https:\u002F\u002Fwww.rdoproject.org\u002Ftripleo\u002F",[531],"TripleO",[638,51981,51982],{},[527,51983,51986],{"href":51984,"rel":51985},"https:\u002F\u002Fwiki.openstack.org\u002Fwiki\u002FManila",[531],"Manila",[638,51988,51989],{},[527,51990,51993],{"href":51991,"rel":51992},"https:\u002F\u002Fgithub.com\u002Fnfs-ganesha\u002Fnfs-ganesha\u002Fwiki",[531],"NFS Ganesha",[613,51995,51997],{"id":51996},"ceph-on-the-brain-a-year-with-the-human-brain-project-stig-telfer-stackhpc","Ceph on the Brain: A Year with the Human Brain Project, Stig Telfer, StackHPC",[523,51999,52000],{},[3069,52001],{"alt":52002,"src":52003},"Ceph Day Berlin 2018 - Ceph on the Brain: A Year with the Human Brain Project, Stig Telfer, StackHPC - 'Ceph on the Brain!'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_152140.jpg",[523,52005,52006],{},[3069,52007],{"alt":52008,"src":52009},"Ceph Day Berlin 2018 - Ceph on the Brain: A Year with the Human Brain Project, Stig Telfer, StackHPC - 'JULIA pilot system'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_152446.jpg",[6072,52011,52012],{},[523,52013,52014],{},"\"Hot hardware when it was 2016\"",[523,52016,52017],{},[3069,52018],{"alt":52019,"src":52020},"Ceph Day Berlin 2018 - Ceph on the Brain: A Year with the Human Brain Project, Stig Telfer, StackHPC - 'Ceph's Performance Record'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_152700.jpg",[523,52022,52023],{},[3069,52024],{"alt":52025,"src":52026},"Ceph Day Berlin 2018 - Ceph on the Brain: A Year with the Human Brain Project, Stig Telfer, StackHPC - 'JULIA Cluster Fabric'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_152852.jpg",[523,52028,52029],{},"It is amazing to see that they reach around 5GBits on bluestore instead of mere 400-500 Mbit\u002Fs on filestore.",[523,52031,52032],{},"Interestingly they had immense losses in performance (from around 16 GBit\u002Fs to 4-5 Gbit\u002Fs) when they tried using LVM for the disks instead of direct partitions.",[523,52034,52035],{},[3069,52036],{"alt":52037,"src":52038},"Ceph Day Berlin 2018 - Ceph on the Brain: A Year with the Human Brain Project, Stig Telfer, StackHPC - 'Write Amplification - Bluestore'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_153501.jpg",[523,52040,52041],{},[3069,52042],{"alt":52043,"src":52044},"Ceph Day Berlin 2018 - Ceph on the Brain: A Year with the Human Brain Project, Stig Telfer, StackHPC - 'Spectre\u002FMeltdown Mitigations'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_153934.jpg",[523,52046,52047,52048,52051],{},"Those loses of performance because of Spectre\u002FMeltdown Mittigations... ",[584,52049,52050],{},"15.5%"," I\u002FO performance loss is huge in \"any\" Ceph environment. Not only looking at Ceph, for any application such a loss of performance is problem.",[523,52053,52054],{},[3069,52055],{"alt":52056,"src":52057},"Ceph Day Berlin 2018 - Ceph on the Brain: A Year with the Human Brain Project, Stig Telfer, StackHPC - 'Burst Buffer Workflows'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_154358.jpg",[523,52059,52060],{},[3069,52061],{"alt":52062,"src":52063},"Ceph Day Berlin 2018 - Ceph on the Brain: A Year with the Human Brain Project, Stig Telfer, StackHPC - 'New Developments in Ceph-RDMA'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_154625.jpg",[613,52065,52067],{"id":52066},"into-the-cold-object-storage-in-switchengines-simon-leinen-switch","Into the cold: Object Storage in SWITCHengines, Simon Leinen, SWITCH",[523,52069,52070],{},[3069,52071],{"alt":52072,"src":52073},"Ceph Day Berlin 2018 - Into the cold: Object Storage in SWITCHengines, Simon Leinen, SWITCH - 'Users Discover Object Storage: SWITCHtube'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_161153.jpg",[6072,52075,52076],{},[523,52077,52078],{},"\"Like YouTube but without ads\" most likely only for educational videos.",[523,52080,52081],{},"They use object storage not only for \"cat pictures\u002Fvideos and etc\" but also for research data and everything else.",[523,52083,52084],{},"Keystone is \"Denial of Service\"d when it is not tweaked to \"perfection\" to handle many requests, causing increase in latency for every request to the object storage.",[523,52086,52087],{},"It is a challenge to (cost efficiently) save data for long-term.",[523,52089,52090],{},[3069,52091],{"alt":52092,"src":52093},"Ceph Day Berlin 2018 - Into the cold: Object Storage in SWITCHengines, Simon Leinen, SWITCH - 'Customer Requirements\u002FExpectations'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_162629.jpg",[523,52095,52096],{},[3069,52097],{"alt":52098,"src":52099},"Ceph Day Berlin 2018 - Into the cold: Object Storage in SWITCHengines, Simon Leinen, SWITCH - 'Cost\u002FPerformance'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_162701.jpg",[523,52101,52102],{},"Using (aggressive) erasure coded for long-term storage sounds reasonable as long as the SLAs are correctly communicated and able to be kept with the chosen erasure coded configuration.",[523,52104,52105],{},"(As long as the aggressive erasure coded profiles don't attack you while administrating the Ceph cluster)",[523,52107,52108],{},[3069,52109],{"alt":52110,"src":52111},"Ceph Day Berlin 2018 - Into the cold: Object Storage in SWITCHengines, Simon Leinen, SWITCH - '\"Moonshot\" challenge for Ceph (or other SDS)'","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_163811.jpg",[613,52113,52115],{"id":52114},"qa","Q&A",[523,52117,52118],{},[3069,52119],{"alt":52120,"src":52121},"Ceph Day Berlin 2018 - Q&A Session - Speakers on stage","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_164210.jpg",[523,52123,52124],{},"Cool to see all speakers that were still there, answering questions of the attendees.",[535,52126,52128],{"id":52127},"networking-reception","Networking Reception",[523,52130,52131],{},[3069,52132],{"alt":52133,"src":52134},"Ceph Day Berlin 2018 - Networking Reception","\u002Fblog\u002F2018\u002Fceph-day-berlin-2018\u002Fimg_20181112_160852.jpg",[523,52136,52137],{},"Free beer! After a whole day of talks about Ceph and talking to people about Rook, we were happy and exhausted.",[523,52139,52140],{},"I hope to see most Ceph Day attendees at one of the next Ceph Day.",[535,52142,14526],{"id":14525},[523,52144,52145],{},"The Ceph foundation is an awesome step forward for Ceph and projects using Ceph like Rook!",[523,52147,52148,52149,52152],{},"It was cool meeting ",[527,52150,51310],{"href":51308,"rel":52151},[531]," and Sebastian Wagner in person instead of just through Rook meeting calls.\nThe talks were interesting, though in general for me some were more interesting than others, but it was the perfect mix of topics.",[523,52154,13967],{},{"title":743,"searchDepth":761,"depth":761,"links":52156},[52157,52158,52159,52175,52176],{"id":51264,"depth":761,"text":51265},{"id":51276,"depth":761,"text":51277},{"id":51329,"depth":761,"text":51330,"children":52160},[52161,52162,52163,52164,52165,52166,52167,52168,52169,52170,52171,52172,52173,52174],{"id":51333,"depth":769,"text":51334},{"id":51416,"depth":769,"text":51417},{"id":51497,"depth":769,"text":51498},{"id":51551,"depth":769,"text":51552},{"id":51581,"depth":769,"text":51582},{"id":51661,"depth":769,"text":51662},{"id":51723,"depth":769,"text":51724},{"id":51822,"depth":769,"text":51823},{"id":51850,"depth":769,"text":51851},{"id":51884,"depth":769,"text":51885},{"id":51932,"depth":769,"text":51933},{"id":51996,"depth":769,"text":51997},{"id":52066,"depth":769,"text":52067},{"id":52114,"depth":769,"text":52115},{"id":52127,"depth":761,"text":52128},{"id":14525,"depth":761,"text":14526},"2018-11-12T08:00:53+01:00","Talks, thoughts and pictures from the Ceph Day Berlin 2018.",{"src":51317},{"tags":52181},[13976,427,421],"\u002Fblog\u002F2018\u002Fceph-day-berlin-2018",{"title":51240,"description":52178},"3.blog\u002F2018\u002Fceph-day-berlin-2018","iWLlufATKjRNZ3fzxEpr0tRbh_qsGc31X2clQrNKWzY",{"id":52187,"title":52188,"authors":52189,"badge":518,"body":52192,"date":52266,"description":52267,"extension":2911,"image":52268,"meta":52270,"navigation":1254,"path":52274,"seo":52275,"stem":52276,"__hash__":52277},"posts\u002F3.blog\u002F2018\u002Fwhat-exactly-is-cloud-native-even.md","What exactly is „Cloud Native\" even?",[52190],{"name":514,"to":515,"avatar":52191},{"src":517},{"type":520,"value":52193,"toc":52264},[52194,52204,52206,52209,52214,52217,52220,52223,52226,52229,52232,52235,52238,52240,52245],[523,52195,50864,52196,13819,52199,1909],{},[527,52197,13818],{"href":13816,"rel":52198},[531],[527,52200,52203],{"href":52201,"rel":52202},"http:\u002F\u002Fthe-report.cloud\u002Fwhat-exactly-is-cloud-native-even",[531],"The Cloud Report - What exactly is „Cloud Native\" even?",[2979,52205],{},[523,52207,52208],{},"Let’s look at the Cloud Native Computing Foundation mission statement for an explanation what \"Cloud Native\" is in their eyes:",[6072,52210,52211],{},[523,52212,52213],{},"The Foundation’s mission is to create and drive the adoption of a new computing paradigm that is optimized for modern distributed systems environments capable of scaling to tens of thousands of self healing multi-tenant nodes.¹",[523,52215,52216],{},"What exactly can we take away from the CNCF mission statement in aspect of \"Cloud Native\"?",[523,52218,52219],{},"\"Cloud Native\" in its broadest aspects is about building \"distributed systems\" and having these \"environments\" capableto \"scaling to tens of thousands of self healing multi-tenant nodes\".",[523,52221,52222],{},"Applying these aspects on to our own applications means that we make them resilient against (e.g., server, network)",[523,52224,52225],{},"failures, scalable so that when from day to the other you have one million new users you don’t get sweaty by the heat fromthe servers and new users, and self healing that if somethingbreaks it is able to recover on its own (in most cases) allowingyou to sleep during the night.",[523,52227,52228],{},"But is \"Cloud Native\" really just a \"paradigm\" that applies to applications? Isn’t it also a \"state of mind\" which comes with the move to having more automation in place to be able to handle \"Cloud Native\" and wanting to automate \"everything\"?",[523,52230,52231],{},"Generally speaking if one moves to use the cloud and does not use any automation he will \"fall out of the cloud\" pretty fast for sure. Already before \"Cloud Native\" was a thing automation was key to get servers, applications and others managed fast and without a hassle. When automation is used and applied \"correctly\", there is no one correct way, the load on the teams is reduced and they can focus on their primary objective to develop new or improve existing products.",[523,52233,52234],{},"As we can already summarize \"Cloud Native\" is more thanjust a \"computing paradigm\", it is a mindset to live by. A mindset which is about being open (source) and sharing too. For this let’s take a quick look at Google as they are a good example of how open source can help your business grow. Google open sourced the Kubernetes² project. The Kubernetes project has a huge global community with people from many different companies, which are working on Kubernetes to improve it for everyone. Depending on your current stance to open source, especially when you are working in a \"closed off\" corporate, you may find this weird. But this is how people want to work, most administrators and developers want to share their success and failures openly at conferences and meetups. This exchange of information between people helps others to not make the same mistakes, to put it simply: to learn from the success and failures of others. This is where transparency comes into play. Sad enough not all corporates allow their employees to be open about such things, but in most cases to consider there are almost no downsides to allow your employees to openly exchange such information. As a corporate may deem it hard to allow such an open exchange of information and possibly also code (contributions), it is possible as one can see from companies such as NetFlix, Google and others which are openly sharing their stories and helping projects.",[523,52236,52237],{},"The question for the end is \"Are you ready to think Cloud Native or are you just ‘jumping’ on to the hype train?\".",[2979,52239],{},[523,52241,52242,856],{},[584,52243,52244],{},"Sources",[668,52246,52247,52254,52259],{},[638,52248,52249,52253],{},[527,52250,52251],{"href":52251,"rel":52252},"https:\u002F\u002Fwww.cncf.io\u002Fabout\u002Fcharter\u002F",[531]," Section \"1. Mission of the Cloud Native Computing Foundation.\"",[638,52255,52256],{},[527,52257,10790],{"href":10790,"rel":52258},[531],[638,52260,52261],{},[527,52262,11714],{"href":11714,"rel":52263},[531],{"title":743,"searchDepth":761,"depth":761,"links":52265},[],"2018-10-15T08:15:20+01:00","Cross-Post of my \"What exactly is „Cloud Native\" even?\" article from \"The Cloud Report\"",{"src":52269},"\u002Fblog\u002Fcovers\u002Fcloudy-road-from-gratisography-com.jpg",{"tags":52271},[52272,52273,15155],"Cloud Native","Cloud","\u002Fblog\u002F2018\u002Fwhat-exactly-is-cloud-native-even",{"title":52188,"description":52267},"3.blog\u002F2018\u002Fwhat-exactly-is-cloud-native-even","2TfsKjECO0SF77ZAGPAnh0wamGzLaLKo1HfPo_CSXt8",{"id":52279,"title":52280,"authors":52281,"badge":518,"body":52284,"date":52353,"description":52354,"extension":2911,"image":52355,"meta":52357,"navigation":1254,"path":52361,"seo":52362,"stem":52363,"__hash__":52364},"posts\u002F3.blog\u002F2018\u002Fdistributed-storage-with-rook-presentation.md","Distributed Storage with Rook Presentation",[52282],{"name":514,"to":515,"avatar":52283},{"src":517},{"type":520,"value":52285,"toc":52348},[52286,52289,52291,52305,52309,52321,52328,52331,52334,52337,52339,52344],[2890,52287,52288],{},"iframe{display: block; margin: auto;}",[535,52290,13457],{"id":13456},[523,52292,52293,52294,52298,52299,52304],{},"A thanks to Kim-Norman Sahm from ",[527,52295,51291],{"href":52296,"rel":52297},"https:\u002F\u002Ftwitter.com\u002Fcloudical",[531]," for reaching out to me if I wanted to talk about Rook with him.\nAlso thanks to ",[527,52300,52303],{"href":52301,"rel":52302},"https:\u002F\u002Ftwitter.com\u002Fjbw976",[531],"Jared Watts",", Tony Allen and the other awesome Rook people for creating the slides for KubeCon Copenhagen 2018, on which we based our slides partially on.",[535,52306,52308],{"id":52307},"presentation","Presentation",[523,52310,52311,52312,52315,52316,1909],{},"Kim-Norman Sahm and I created this presentation to show off Rook.io at ",[527,52313,18940],{"href":18938,"rel":52314},[531],".\nThe files used in the demo during the presentation can be found here: ",[527,52317,52320],{"href":52318,"rel":52319},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fpresentation-distributed-storage-with-rook",[531],"GitHub galexrt\u002Fpresentation-distributed-storage-with-rook",[523,52322,52323,52324,52327],{},"Checkout my blog post about the Container Days Hamburg 2018, see ",[527,52325,18940],{"href":52326},"\u002Fblog\u002F2018\u002FContainer-Days-2018-Hamburg.md",", where I also have a few pictures of the talk from the crowd.",[523,52329,52330],{},"If you want to present these slides somewhere, please get in contact with Kim-Norman Sahm or me first. Thanks!",[18903,52332],{"src":52333,"frameBorder":3579,"height":18906,"allowFullScreen":5306,"mozallowfullscreen":5306,"webkitallowfullscreen":5306},"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002Fe\u002F2PACX-1vR-pNSaQi-h6OTNKyUogshuChpDtnIVdPcO3TV8Y3i-4mRG19uJurJ04lmJUv6ys9p6dXeWNBpuNlp7\u002Fembed?start=false&loop=true&delayms=5000",[523,52335,52336],{},"If you have any suggestions for the presentation, feel free to leave them in the comments. :)",[535,52338,18951],{"id":18950},[523,52340,18954,52341,856],{},[527,52342,18959],{"href":18957,"rel":52343},[531],[18903,52345],{"height":18962,"src":52346,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002Fg53z3_SnKIw","autoplay; encrypted-media",{"title":743,"searchDepth":761,"depth":761,"links":52349},[52350,52351,52352],{"id":13456,"depth":761,"text":13457},{"id":52307,"depth":761,"text":52308},{"id":18950,"depth":761,"text":18951},"2018-07-10T15:50:42+02:00","A presentation about \"Distributed Storage with Rook\" which was held at Container Days Hamburg.",{"src":52356},"\u002Fblog\u002Fcovers\u002Frook-io-logo-only.png",{"tags":52358},[18918,124,52359,52360],"KubeCon","Austin","\u002Fblog\u002F2018\u002Fdistributed-storage-with-rook-presentation",{"title":52280,"description":52354},"3.blog\u002F2018\u002Fdistributed-storage-with-rook-presentation","o_MDm3V0wVuhu-5hrmrQALBGAvmjQe6KMxtAqBvud_s",{"id":52366,"title":52367,"authors":52368,"badge":518,"body":52371,"date":53046,"description":53047,"extension":2911,"image":53048,"meta":53049,"navigation":1254,"path":53051,"seo":53052,"stem":53053,"__hash__":53054},"posts\u002F3.blog\u002F2018\u002Fcontainer-days-2018-hamburg.md","Container Days 2018 Hamburg",[52369],{"name":514,"to":515,"avatar":52370},{"src":517},{"type":520,"value":52372,"toc":53031},[52373,52375,52385,52387,52391,52399,52405,52411,52414,52416,52420,52423,52429,52435,52439,52445,52450,52453,52457,52460,52489,52492,52519,52525,52528,52534,52537,52540,52544,52547,52550,52556,52559,52564,52567,52570,52573,52576,52580,52583,52586,52592,52595,52602,52610,52613,52616,52620,52626,52631,52639,52642,52648,52651,52654,52660,52663,52669,52675,52679,52685,52688,52694,52716,52719,52732,52740,52743,52751,52754,52760,52764,52770,52773,52777,52783,52785,52789,52792,52796,52802,52808,52814,52831,52845,52851,52888,52892,52898,52901,52908,52914,52917,52925,52933,52937,52943,52977,52979,52982,52985,52991,52997,53000,53003,53010,53012,53014,53020,53023,53025],[535,52374,13457],{"id":13456},[523,52376,52377,52378,52381,52382,1909],{},"A thanks and shoutout to ",[527,52379,51291],{"href":51289,"rel":52380},[531]," for allowing me to talk about Rook together with Kim-Norman Sahm.\nCheckout their Twitter: ",[527,52383,51291],{"href":52296,"rel":52384},[531],[2979,52386],{},[535,52388,52390],{"id":52389},"day-0","Day #0",[523,52392,52393,52394,1909],{},"The speaker party was filled with cool people and a nice atmosphere at ",[527,52395,52398],{"href":52396,"rel":52397},"https:\u002F\u002Fwww.strandpauli.de",[531],"StrandPauli",[523,52400,52401],{},[3069,52402],{"alt":52403,"src":52404},"Container Days 2018 - Night view from StrandPauli","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180618_233433-pano.jpg",[523,52406,52407],{},[3069,52408],{"alt":52409,"src":52410},"Container Days 2018 - Reeperbahn Trainstation sign","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180618_235548.jpg",[523,52412,52413],{},"Obvious visit to the Hamburg Reeperbahn. Just kidding, we just used the train station to get back to our hotel (as far as I remember) ;)",[2979,52415],{},[535,52417,52419],{"id":52418},"day-1","Day #1",[523,52421,52422],{},"Let's see what awesomeness the day will bring. I hope I'll learn new stuff about containers and Kubernetes, and hopefully meet all the cool people again. :)",[523,52424,52425],{},[3069,52426],{"alt":52427,"src":52428},"Container Days 2018 - Shuttle busses to the conference venue","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180620_094453.jpg",[523,52430,52431],{},[3069,52432],{"alt":52433,"src":52434},"Container Days 2018 - The crowd is getting ready for the keynotes","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180619_090832.jpg",[613,52436,52438],{"id":52437},"keynotes","Keynotes",[523,52440,52441],{},[3069,52442],{"alt":52443,"src":52444},"Container Days 2018 - Julian and Sebastian from Loodse on stage","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180619_091209.jpg",[6072,52446,52447],{},[523,52448,52449],{},"\"Back to the harbor.\"",[523,52451,52452],{},"..where containers originate.",[3126,52454,52456],{"id":52455},"globalization-in-the-port-how-containers-changed-the-world-of-harbour-work-ursula-richenberger-german-port-museum","Globalization in the port. How containers changed the world of harbour work. - Ursula Richenberger, German Port Museum",[523,52458,52459],{},"A container combines two important points. Storage and Transport.\nCharacteristics of shipping containers are:",[668,52461,52462,52465,52468],{},[638,52463,52464],{},"Stackability",[638,52466,52467],{},"Handling",[638,52469,52470,52471],{},"Flexibility\n",[668,52472,52473,52476],{},[638,52474,52475],{},"\"Toilets, Store\" - Container are not for goods transportation only.",[638,52477,52478,52479],{},"Transport by:\n",[668,52480,52481,52484,52487],{},[638,52482,52483],{},"Train",[638,52485,52486],{},"Truck",[638,52488,2609],{},[523,52490,52491],{},"These can be seen as the following in the IT world:",[668,52493,52494,52497,52500],{},[638,52495,52496],{},"Scalability",[638,52498,52499],{},"Ease of use (e.g. YAML manifests)",[638,52501,52470,52502],{},[668,52503,52504,52511],{},[638,52505,52506,52510],{},[527,52507,39419],{"href":52508,"rel":52509},"https:\u002F\u002Fwww.opencontainers.org\u002F",[531]," creating standards to be able to run, e.g. Docker images run on any Container runtime implementing the Container Runtime Interface standard and Container image standard.",[638,52512,52513,52518],{},[527,52514,52517],{"href":52515,"rel":52516},"https:\u002F\u002Fwww.cncf.io\u002Fcertification\u002Fkcsp\u002F",[531],"Certified Kubernetes Service provider"," allow us to run our (Kubernetes) workload \"anywhere\".",[523,52520,52521],{},[3069,52522],{"alt":52523,"src":52524},"Container Days 2018 - Globalization in the port","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180619_091950_1.jpg",[523,52526,52527],{},"Such hubs in a harbor are the core which made the Hamburg harbor especially powerful in global trading.",[523,52529,52530],{},[3069,52531],{"alt":52532,"src":52533},"Container Days 2018 - The difference between before the 'revolution' and after","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180619_092244.jpg",[523,52535,52536],{},"A huge revolution happened in the transport logistics because of containers.\nBecause of the transport container revolution, many things have been automated though still not everything.",[523,52538,52539],{},"\"In the reality a container transports goods, but aren't our applications in containers also just goods? Goods that we want to deliver fast to our customers.\"",[3126,52541,52543],{"id":52542},"emergence-of-linux-application-containers-and-the-rise-of-kubernetes-craig-mcluckie-heptio","Emergence of Linux Application Containers and the Rise of Kubernetes - Craig McLuckie, Heptio",[523,52545,52546],{},"\"dotCloud\" has renamed themselves to \"Docker\".\nThey had the problem of wanting to run \"user\" code in production and be fast with it, instead of \"having to review every bit of code\".",[523,52548,52549],{},"Google uses cgroups to use resources more efficient. Though at first the code was private, but they donated the cgroups code.\nThis has advantages for everyone and especially for Goole, because it reduces the workload of \"rebasing\" on upstream changes happening.",[523,52551,52552],{},[3069,52553],{"alt":52554,"src":52555},"Container Days 2018 - 'Why open source?'","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180619_093856.jpg",[523,52557,52558],{},"They open sourced their code for it and with that the Linux kernel built namespaces. cgroups, namespace and other parts came together, not only for good of the community but also for Google, as already mentioned.",[6072,52560,52561],{},[523,52562,52563],{},"\"upstream is powerful\" - Craig McLuckie",[523,52565,52566],{},"The more you push your changes to upstream, the less work you have to do to maintain your implemented \"feature set\" (e.g. no rebasing all the time).",[523,52568,52569],{},"Google with their experience, looking at you Kubernetes, gave us a \"blueprint\" in regard of that it is possible to run at scale with containers as they do.",[523,52571,52572],{},"The thesis behind Kubernetes is\u002Fwas that we can give it the community, but simply offer it \"as a Service\" running it better than \"anyone else\".\nThis thinking allows Google to score big time, because \"every\" company runs it, also lowering (new) developer time to production (how long a new developer needs to get changes to production).",[523,52574,52575],{},"Kubernetes project brought a lot of companies together, in discussions for features and issues helping out by contributing and\u002For sponsoring such projects.",[3126,52577,52579],{"id":52578},"the-cloud-native-evolution-ihor-dvoretskyi-cncf","The Cloud Native Evolution - Ihor Dvoretskyi, CNCF",[523,52581,52582],{},"A monolith application can be seen as a static glacier, which is hard to fix bugs in and further develop.",[523,52584,52585],{},"Destroying an application is a benefit as long as you can redeploy it, looking at containers you normally just \"throw away\" used containers.",[523,52587,52588],{},[3069,52589],{"alt":52590,"src":52591},"Container Days 2018 - 'Congrats Kubernetes' for the graduation as a CNCF project","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180619_100207.jpg",[523,52593,52594],{},"Kubernetes is the first project to graduate from all of the Cloud Native Computing Foundation projects.",[523,52596,52597,52601],{},[3069,52598],{"alt":52599,"src":52600},"Container Days 2018 - Cloud Native Computing Foundation project landscape","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180619_100420.jpg","\n*Rook is seen on a slide during a conference photo*",[523,52603,52604,52605,1909],{},"The CNCF projects can live next to eacht other and are not in direct competition.\nCNCF landscape can be viewed in it's full extent here: ",[527,52606,52609],{"href":52607,"rel":52608},"https:\u002F\u002Fl.cncf.io",[531],"CNCF Cloud Native Interactive Landscape",[523,52611,52612],{},"The most important is the community.\nNot only are there more than 23 thousand contributors contributing to CNCF projects, but also a huge meetup community all around the globe.\nTo further help with the community, there are also many initiatives (e.g. meet the maintainers).",[613,52614,18918],{"id":52615},"presentations",[3126,52617,52619],{"id":52618},"distributed-database-devops-dilemmas-kubernetes-to-the-rescue-akmal-chaudhri-gridgain-systems","Distributed Database DevOps Dilemmas? Kubernetes to the rescue! - Akmal Chaudhri, GridGain Systems",[523,52621,52622],{},[3069,52623],{"alt":52624,"src":52625},"Container Days 2018 - Day #1 Don't buy these books.","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180619_121925.jpg",[6072,52627,52628],{},[523,52629,52630],{},"\"Don't buy these books.\" - Akmal Chaudhri",[523,52632,52633,52634,1909],{},"He also writes articles from time to time. A list of his articles can be found here: ",[527,52635,52638],{"href":52636,"rel":52637},"https:\u002F\u002Fdzone.com\u002Fusers\u002F1313357\u002FVeryFatBoy.html",[531],"DZone Akmal Chaudhri Articles list",[523,52640,52641],{},"Apache Ignite is a In-Memory Computing Platform.",[523,52643,52644],{},[3069,52645],{"alt":52646,"src":52647},"Container Days 2018 - Day #1 Apache Ignite is..","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180619_122359.jpg",[523,52649,52650],{},"Peer to Peer system. It allows for pessimistic and optimistic transactions.",[523,52652,52653],{},"Because of the in-memory caching, you can run SQL queries, machine learning and other tasks on the incoming data across the cluster quickly (e.g. IoT data).",[523,52655,52656],{},[3069,52657],{"alt":52658,"src":52659},"Container Days 2018 - Day #1 Apache Ignite Clustering","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180619_123205.jpg",[523,52661,52662],{},"Running Ignite inside of Kubernetes, allows to you use the Kubernetes scaling features combined with service discovery.",[523,52664,52665],{},[3069,52666],{"alt":52667,"src":52668},"Container Days 2018 - Day #1 Can scale 'as needed' by simply utilizing kubectl scale","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180619_123712.jpg",[523,52670,52671,52672,11295],{},"It allows you to scale 'as needed' by utilizing ",[567,52673,52674],{},"kubectl scale",[3126,52676,52678],{"id":52677},"the-what-and-why-of-flatcar-linux-a-friendly-fork-of-container-linux-chris-kühl-kinvolk","The \"what\" and \"why\" of Flatcar Linux, a friendly fork of Container Linux - Chris Kühl, Kinvolk",[523,52680,52681],{},[3069,52682],{"alt":52683,"src":52684},"Container Days 2018 - Day #1 'All Systems Go!' Linux conference, September 28-30, 2018 in Berlin, Germany","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180619_172255.jpg",[523,52686,52687],{},"They have an upcoming event about the \"stack\" below the applications and\u002For container runtime on September 28-30, 2018 in Berlin, Germany.",[523,52689,52690],{},[3069,52691],{"alt":52692,"src":52693},"Container Days 2018 - Day #1 'What is Flatcar Linux?'","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180619_172649.jpg",[523,52695,52696,52697,52702,52703,714,52706,587,52709,52712,52713,52715],{},"They deliver ",[527,52698,52701],{"href":52699,"rel":52700},"https:\u002F\u002Fwww.flatcar-linux.org\u002F",[531],"Flatcar Linux"," in three channels as Container Linux: ",[567,52704,52705],{},"stable",[567,52707,52708],{},"beta",[567,52710,52711],{},"alpha",".\nYou should always run some nodes with the beta version to test that changes are compatible with upcoming ",[567,52714,52705],{}," versions.",[523,52717,52718],{},"Two the points why they forked CoreOS\u002FContainer Linux are:",[668,52720,52721,52729],{},[638,52722,52723,52724],{},"CoreOS was bought by RedHat.\n",[668,52725,52726],{},[638,52727,52728],{},"Though they already talked about it before that. They generally try not to make it in a competitive manner.",[638,52730,52731],{},"No support for CoreOS\u002FContainer Linux available (only when using the full Tectonic stack).",[523,52733,52734,52739],{},[527,52735,52738],{"href":52736,"rel":52737},"https:\u002F\u002Fkinvolk.io\u002F",[531],"Kinvolk"," already exists for three years, so they seem to be successful with their \"goal\".",[523,52741,52742],{},"Their goal is to be an independent infrastructure company for cloud native technology.",[523,52744,52745,52746,1909],{},"Flatcar Linux has support for ",[527,52747,52750],{"href":52748,"rel":52749},"https:\u002F\u002Ftyphoon.psdn.io\u002F",[531],"Typhoon",[523,52752,52753],{},"For now they are only offering support for larger installations of Flatcar Linux and contribute more to maintenance of Container Linux from which Flatcar Linux benefits from.\nAnother goal for the future is to offer commercial support for Typhoon.",[523,52755,52756],{},[3069,52757],{"alt":52758,"src":52759},"Container Days 2018 - Day #1 'Thank you!' for showing an interesting 'new' Linux for containers","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180619_174753.jpg",[613,52761,52763],{"id":52762},"lunch-time","Lunch Time",[523,52765,52766],{},[3069,52767],{"alt":52768,"src":52769},"Container Days 2018 - Day #1 Lunch time","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180619_125610.jpg",[523,52771,52772],{},"As last year, I only ate the burger, because it was and is good. Only thing all of us noticed, it is a bit hard to scale burger cooking unless you add more Big Ben Burger trucks.",[613,52774,52776],{"id":52775},"booths","Booths",[523,52778,52779],{},[3069,52780],{"alt":52781,"src":52782},"Container Days 2018 - Day #1 Booth shot","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180619_194503.jpg",[2979,52784],{},[535,52786,52788],{"id":52787},"day-2","Day #2",[613,52790,18918],{"id":52791},"presentations-1",[3126,52793,52795],{"id":52794},"handson-podsecuritypolicies-erkan-yanar","HandsOn PodSecurityPolicies - Erkan Yanar",[523,52797,52798],{},[3069,52799],{"alt":52800,"src":52801},"Container Days 2018 - Day #2 PodSecurityPolicies let's get started","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180620_105246.jpg",[523,52803,52804,52807],{},[567,52805,52806],{},"PodSecurityPolicies"," are to further cage in applications running inside containers.\nOn OpenShift it is by default required to run containers as non root.",[523,52809,52810,52811,52813],{},"To enable ",[567,52812,52806],{}," you just need to change the admission controller flag on the API server(s).",[523,52815,52816,52818,52819,52821,52822,714,52824,714,52827,52830],{},[567,52817,31659],{}," are restricted by ",[567,52820,52806],{},", not ",[567,52823,30269],{},[567,52825,52826],{},"StatefulSets",[567,52828,52829],{},"ReplicaSets",", because they only \"spawn\" Pod objects.",[6072,52832,52833,52837],{},[523,52834,52835],{},[584,52836,6189],{},[668,52838,52839,52842],{},[638,52840,52841],{},"Authentication: know who you are",[638,52843,52844],{},"Authorization what you are allowed to do.",[523,52846,52847],{},[3069,52848],{"alt":52849,"src":52850},"Container Days 2018 - Day #2 Docker equivalent flags for the Kubernetes PodSecurityPolicies options","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180620_111517.jpg",[668,52852,52853,52859,52873,52882],{},[638,52854,52855,52858],{},[567,52856,52857],{},"allowPrivilegeEscalation"," disallows more privileges and\u002For capabilities to be \"given\" to containers.",[638,52860,52861,52863,52864],{},[567,52862,26963],{}," can possibly be used to DoS the filesystem of the host system.\n",[668,52865,52866],{},[638,52867,52868,52869,52872],{},"At least looking at storage space limitation one could use ",[567,52870,52871],{},"Quotas"," for storage requests.",[638,52874,52875,52877,52878,52881],{},[567,52876,33089],{}," is also evil if used to for example modified ",[567,52879,52880],{},"\u002Fetc\u002Fshadow"," and\u002For other important files.",[638,52883,52884,52887],{},[567,52885,52886],{},"readOnlyRootFilesystem"," allows the container filesystem to be read-only to prevent applications from filling your host disk through that and\u002For \"attackers\" to write files.",[3126,52889,52891],{"id":52890},"migrating-the-next-generation-mobile-core-towards-5g-with-kubernetes-karla-saur-intel","Migrating the Next Generation Mobile Core Towards 5G with Kubernetes - Karla Saur, Intel",[523,52893,52894],{},[3069,52895],{"alt":52896,"src":52897},"Container Days 2018 - Day #2 Core Pinning feature","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180620_134723.jpg",[523,52899,52900],{},"They implemented features such as \"core pinning\" to further keep workload from swichting between CPU cores.",[523,52902,52903,52907],{},[3069,52904],{"alt":52905,"src":52906},"Container Days 2018 - Day #2 Performance comparison non-container and Kubernetes environment","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180620_134838.jpg","\nDuring their performance tests they found that Kubernetes does perform a little less well than when the application is not run in containers. Though those were just about 5% and was okay for them, because they have simplicity for scaling through that.",[523,52909,52910],{},[3069,52911],{"alt":52912,"src":52913},"Container Days 2018 - Day #2 Their load balancer setup","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180620_135624.jpg",[523,52915,52916],{},"They wrote their own load balancer as existing load balancer are more or less \"just\" focused on level 4 and 7.",[523,52918,52919,52920,1909],{},"The NGIC gateway is available under ",[527,52921,52924],{"href":52922,"rel":52923},"https:\u002F\u002Fgerrit.opencord.org\u002F#\u002Fq\u002Fproject:ngic",[531],"project:ngic | gerrit.opencord Code Review",[523,52926,52927,52928,52932],{},"Another project they have open source is ",[527,52929,52931],{"href":15008,"rel":52930},[531],"MULTUS CNI plugin",". This CNI (plugin) allows you to attach multiple network interfaces (CNI plugins) to one Pod.",[3126,52934,52936],{"id":52935},"distributed-storage-with-rook-kim-norman-sahm-cloudical-alexander-trost-rook-contributor","Distributed storage with Rook - Kim-Norman Sahm, Cloudical & Alexander Trost, Rook Contributor",[523,52938,52939],{},[3069,52940],{"alt":52941,"src":52942},"Container Days 2018 - Day #2 Kim-Norman Sahm and Alexander Trost getting ready for the Rook talk","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180620_122748.jpg",[6072,52944,52947,52972,52973],{"className":52945,"dataLang":18973},[18972,52946],"tw-align-center",[523,52948,52949,52950,52954,52955,52959,52960,8287,52964,8287,52968],{"lang":18973,"dir":18976},"A great presentation about ",[527,52951,52953],{"href":52952},"https:\u002F\u002Ftwitter.com\u002Frook_io?ref_src=twsrc%5Etfw","@rook_io",", the sandboxed project of ",[527,52956,52958],{"href":52957},"https:\u002F\u002Ftwitter.com\u002FCloudNativeFdn?ref_src=twsrc%5Etfw","@CloudNativeFdn"," at ",[527,52961,52963],{"href":52962},"https:\u002F\u002Ftwitter.com\u002FConDaysEU?ref_src=twsrc%5Etfw","@ConDaysEU",[527,52965,52967],{"href":52966},"https:\u002F\u002Ftwitter.com\u002Fhashtag\u002FCDS18?src=hash&ref_src=twsrc%5Etfw","#CDS18",[527,52969,52971],{"href":52970},"https:\u002F\u002Ft.co\u002FtYQy3vY47A","pic.twitter.com\u002FtYQy3vY47A","— Ihor Dvoretskyi (@idvoretskyi) ",[527,52974,52976],{"href":52975},"https:\u002F\u002Ftwitter.com\u002Fidvoretskyi\u002Fstatus\u002F1009438369192046595?ref_src=twsrc%5Etfw","June 20, 2018",[19016,52978],{"async":1254,"src":19018,"charSet":19019},[523,52980,52981],{},"It was an amazing experience talking about Rook. Sadly not all parts of the demo worked, \"Damn Demo gods have left us\".",[523,52983,52984],{},"I can reassure that it works, after the talk and questions I checked again and the Elasticsearch cluster demo part had started up fine. Additionally I deployed the \"same\" manifests again in the evening (only change was to add HTTP basic auth to the Ingress) and the Elasticsearch cluster started fine again.",[523,52986,52987],{},[3069,52988],{"alt":52989,"src":52990},"Container Days 2018 - Day #2 'We did it!' Celebrating after the 'storm'.","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180620_170132.jpg",[523,52992,52993,52994,1909],{},"The demo files can be found here: ",[527,52995,52320],{"href":52318,"rel":52996},[531],[523,52998,52999],{},"The slides can be downloaded as a PDF here: [Distributed storage with Rook.pdf](\u002Fblog\u002F2018\u002FContainer-Days-2018-Hamburg\u002FDistributed storage with Rook.pdf).",[613,53001,52763],{"id":53002},"lunch-time-1",[523,53004,53005,53009],{},[3069,53006],{"alt":53007,"src":53008},"Container Days 2018 - Day #2 Lunch time","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fimg_20180620_123011.jpg","\nToday it was Pulled Turkey Burger time, it was also great.\nThough as mentioned yesterday there was a good amount of wait until you have gotten your burger.",[2979,53011],{},[535,53013,14526],{"id":14525},[523,53015,53016],{},[3069,53017],{"alt":53018,"src":53019},"Container Days 2018 - Hafenmuseum, Hamburg was the perfect choice for Container Days!","\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg\u002Fpano_20180620_123015.jpg",[523,53021,53022],{},"As last year it was awesome meeting all those people and learning new stuff about containers through the variety of talks.\nThis year was especially cool for me, because it was my first time speaking at a public conference.",[523,53024,13967],{},[523,53026,53027,53030],{},[584,53028,53029],{},"P.S.",": Please let me know (by comment or email), if there is anything I can improve to make this post about the conference even better. Thanks for reading!",{"title":743,"searchDepth":761,"depth":761,"links":53032},[53033,53034,53035,53041,53045],{"id":13456,"depth":761,"text":13457},{"id":52389,"depth":761,"text":52390},{"id":52418,"depth":761,"text":52419,"children":53036},[53037,53038,53039,53040],{"id":52437,"depth":769,"text":52438},{"id":52615,"depth":769,"text":18918},{"id":52762,"depth":769,"text":52763},{"id":52775,"depth":769,"text":52776},{"id":52787,"depth":761,"text":52788,"children":53042},[53043,53044],{"id":52791,"depth":769,"text":18918},{"id":53002,"depth":769,"text":52763},{"id":14525,"depth":761,"text":14526},"2018-06-19T08:45:06+02:00","Some thoughts, notes, comments and pictures from the Container Days 2018 in Hamburg.",{"src":52444},{"tags":53050},[13976,18920,26415,12175,124],"\u002Fblog\u002F2018\u002Fcontainer-days-2018-hamburg",{"title":52367,"description":53047},"3.blog\u002F2018\u002Fcontainer-days-2018-hamburg","rlO8B42XJ19t3DzvD2N8IJ-7ebrxilfg3YkC7qGt3x4",{"id":53056,"title":53057,"authors":53058,"badge":518,"body":53061,"date":55858,"description":26408,"extension":2911,"image":55859,"meta":55860,"navigation":1254,"path":55862,"seo":55863,"stem":55864,"__hash__":55865},"posts\u002F3.blog\u002F2018\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature.md","GitLab + Kubernetes: Using GitLab CI's Kubernetes Cluster feature",[53059],{"name":514,"to":515,"avatar":53060},{"src":517},{"type":520,"value":53062,"toc":55837},[53063,53067,53073,53076,53078,53080,53082,53088,53096,53098,53128,53140,53142,53146,53148,53150,53159,53169,53173,53231,53236,53238,53241,53265,53275,53284,53324,53329,53515,53521,53523,53537,53571,53587,53666,53684,53694,53697,53703,53705,53709,53716,53721,53726,53732,53739,53744,53749,53761,53766,53770,53797,53802,53806,53840,53844,53846,53884,53886,53943,53956,53968,54003,54007,54849,54860,54864,54866,54873,54936,54946,54948,54950,54956,55242,55255,55264,55278,55290,55460,55478,55486,55674,55693,55710,55712,55714,55718,55764,55766,55777,55783,55791,55795,55797,55799,55801,55803,55814,55816,55828,55830,55832,55834],[535,53064,53066],{"id":53065},"updated","UPDATED",[523,53068,53069,53070,1909],{},"An updated version of this post can be found here: ",[527,53071,22234],{"href":53072},"\u002Fblog\u002F2019\u002FGitLab-Kubernetes-Using-GitLab-CIs-Kubernetes-Cluster-feature.md",[523,53074,53075],{},"Please use it instead of this post which is already a bit dated again and not all uptodate with the latest changes to the example repository. Thanks!",[2979,53077],{},[535,53079,538],{"id":537},[523,53081,22244],{},[523,53083,22247,53084,22251,53086,1909],{},[567,53085,22250],{},[527,53087,22255],{"href":22254},[6072,53089,53090,53094],{},[523,53091,53092],{},[584,53093,6189],{},[523,53095,22264],{},[613,53097,22268],{"id":22267},[668,53099,53100,53102,53114,53118],{},[638,53101,15241],{},[638,53103,22275,53104],{},[668,53105,53106,53108],{},[638,53107,22280],{},[638,53109,22283,53110],{},[668,53111,53112],{},[638,53113,22288],{},[638,53115,53116,22293],{},[567,53117,15269],{},[638,53119,22296,53120,53122],{},[567,53121,22299],{},[668,53123,53124],{},[638,53125,22304,53126,1909],{},[527,53127,22308],{"href":22307},[6072,53129,53130,53134],{},[523,53131,53132],{},[584,53133,6189],{},[523,53135,53136,53137,53139],{},"In this post the Kubernetes namespace ",[567,53138,22323],{}," will be used for \"everything\".",[535,53141,22333],{"id":22332},[523,53143,22336,53144,22340],{},[567,53145,22339],{},[523,53147,22343],{},[535,53149,22347],{"id":22346},[523,53151,22350,53152,22356,53155,22360,53157,22364],{},[527,53153,22355],{"href":22353,"rel":53154},[531],[567,53156,22359],{},[567,53158,22363],{},[6072,53160,53161,53165],{},[523,53162,53163],{},[584,53164,6189],{},[523,53166,22373,53167,3361],{},[527,53168,22308],{"href":22307},[523,53170,22378,53171,22381],{},[567,53172,2984],{},[738,53174,53175],{"className":1621,"code":22384,"language":1623,"meta":743,"style":743},[567,53176,53177,53187,53195,53199,53213,53217],{"__ignoreMap":743},[747,53178,53179,53181,53183,53185],{"class":749,"line":750},[747,53180,1919],{"class":1630},[747,53182,22393],{"class":802},[747,53184,3506],{"class":802},[747,53186,22398],{"class":802},[747,53188,53189,53191,53193],{"class":749,"line":761},[747,53190,1919],{"class":1630},[747,53192,22405],{"class":802},[747,53194,22408],{"class":802},[747,53196,53197],{"class":749,"line":769},[747,53198,22413],{"class":772},[747,53200,53201,53203,53205,53207,53209,53211],{"class":749,"line":776},[747,53202,1919],{"class":1630},[747,53204,22393],{"class":802},[747,53206,22422],{"class":802},[747,53208,22425],{"class":802},[747,53210,22428],{"class":802},[747,53212,22431],{"class":802},[747,53214,53215],{"class":749,"line":784},[747,53216,22436],{"class":772},[747,53218,53219,53221,53223,53225,53227,53229],{"class":749,"line":790},[747,53220,1919],{"class":1630},[747,53222,22393],{"class":802},[747,53224,22445],{"class":802},[747,53226,7089],{"class":802},[747,53228,22428],{"class":802},[747,53230,22452],{"class":802},[523,53232,22455,53233,1909],{},[527,53234,22458],{"href":22458,"rel":53235},[531],[523,53237,22462],{},[535,53239,22308],{"id":53240},"step-2-get-serviceaccount-token-from-kubernetes",[6072,53242,53243,53247,53259],{},[523,53244,53245],{},[584,53246,6189],{},[523,53248,53249,53250,53252,53253,714,53255,714,53257,1909],{},"This step is definetely a bit different for newer clusters as you need to get a ",[567,53251,22299],{}," token from an account with enough permissions to create, modify and delete the following objects in Kubernetes: Create, modify and delete ",[567,53254,25331],{},[567,53256,25729],{},[567,53258,158],{},[523,53260,53261,53262,53264],{},"For more information and a prescription, talk to your cluster administrator about a ",[567,53263,22299],{}," that matches these requirements.",[523,53266,53267,53268,53271,53272,53274],{},"For Kubernetes ",[567,53269,53270],{},"1.6"," and higher with role-based access control (RBAC) enabled you need to have a ",[567,53273,22299],{}," with the correct permissions, to deploy in the namespace of your choice.",[523,53276,53267,53277,53280,53281,53283],{},[567,53278,53279],{},"1.5"," and below, you just need to a) create a ",[567,53282,22299],{}," (see note below) or b) use the default existing one in the namespace of your choice.",[6072,53285,53286,53290,53298,53304],{},[523,53287,53288],{},[584,53289,6189],{},[523,53291,53292,53293,11500],{},"It is recommended to ",[584,53294,53295,53296,23072],{},"create a new ",[567,53297,22299],{},[523,53299,53300,53301,53303],{},"For information on how create a ",[567,53302,22299],{},", please refer to the Kubernetes documentation here:",[668,53305,53306,53315],{},[638,53307,22296,53308,53310,53311],{},[567,53309,53279],{}," and below: ",[527,53312,53313],{"href":53313,"rel":53314},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fadmin\u002Fservice-accounts-admin\u002F",[531],[638,53316,22296,53317,53319,53320],{},[567,53318,53270],{}," and higher (with RBAC enabled): ",[527,53321,53322],{"href":53322,"rel":53323},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fadmin\u002Fauthorization\u002Frbac\u002F",[531],[523,53325,23091,53326,53328],{},[567,53327,22299],{}," created in the namespace where I will run the application.\nFor that I check what secrets exist, then get the secret and base64 decode it.",[738,53330,53332],{"className":1621,"code":53331,"language":1623,"meta":743,"style":743},"$ kubectl get -n presentation-gitlab-k8s secret\nNAME                                           TYPE                                  DATA      AGE\ndefault-token-nmx1q                            kubernetes.io\u002Fservice-account-token   3         20m\n$ kubectl get -n presentation-gitlab-k8s secret default-token-nmx1q -o yaml\napiVersion: v1\ndata:\n  ca.crt: [REDACATED]\n  namespace: [REDACATED]\n  token: [THIS IS YOUR TOKEN BASE64 ENCODED]\nkind: Secret\nmetadata:\n  annotations:\n    kubernetes.io\u002Fservice-account.name: default\n  [...]\n  name: default-token-nmx1q\n  namespace: presentation-gitlab-k8s\n  [...]\ntype: kubernetes.io\u002Fservice-account-token\n$ echo YOUR_TOKEN_HERE | base64 -d\nYOUR_DECODED_TOKEN\n",[567,53333,53334,53348,53359,53372,53393,53399,53403,53409,53415,53437,53443,53447,53452,53459,53467,53474,53480,53488,53496,53511],{"__ignoreMap":743},[747,53335,53336,53338,53340,53342,53344,53346],{"class":749,"line":750},[747,53337,1919],{"class":1630},[747,53339,1922],{"class":802},[747,53341,1951],{"class":802},[747,53343,1928],{"class":802},[747,53345,23116],{"class":802},[747,53347,23119],{"class":802},[747,53349,53350,53352,53355,53357],{"class":749,"line":761},[747,53351,2230],{"class":1630},[747,53353,53354],{"class":802},"                                           TYPE",[747,53356,23129],{"class":802},[747,53358,33030],{"class":802},[747,53360,53361,53364,53367,53369],{"class":749,"line":769},[747,53362,53363],{"class":1630},"default-token-nmx1q",[747,53365,53366],{"class":802},"                            kubernetes.io\u002Fservice-account-token",[747,53368,16450],{"class":1895},[747,53370,53371],{"class":802},"         20m\n",[747,53373,53374,53376,53378,53380,53382,53384,53386,53389,53391],{"class":749,"line":776},[747,53375,1919],{"class":1630},[747,53377,1922],{"class":802},[747,53379,1951],{"class":802},[747,53381,1928],{"class":802},[747,53383,23116],{"class":802},[747,53385,23182],{"class":802},[747,53387,53388],{"class":802}," default-token-nmx1q",[747,53390,2222],{"class":802},[747,53392,23190],{"class":802},[747,53394,53395,53397],{"class":749,"line":784},[747,53396,23195],{"class":1630},[747,53398,22608],{"class":802},[747,53400,53401],{"class":749,"line":790},[747,53402,23202],{"class":1630},[747,53404,53405,53407],{"class":749,"line":796},[747,53406,23207],{"class":1630},[747,53408,23210],{"class":1640},[747,53410,53411,53413],{"class":749,"line":806},[747,53412,23215],{"class":1630},[747,53414,23210],{"class":1640},[747,53416,53417,53419,53422,53425,53428,53431,53434],{"class":749,"line":814},[747,53418,23222],{"class":1630},[747,53420,53421],{"class":1640}," [THIS ",[747,53423,53424],{"class":802},"IS",[747,53426,53427],{"class":802}," YOUR",[747,53429,53430],{"class":802}," TOKEN",[747,53432,53433],{"class":802}," BASE64",[747,53435,53436],{"class":802}," ENCODED]\n",[747,53438,53439,53441],{"class":749,"line":822},[747,53440,23230],{"class":1630},[747,53442,23233],{"class":802},[747,53444,53445],{"class":749,"line":830},[747,53446,23238],{"class":1630},[747,53448,53449],{"class":749,"line":836},[747,53450,53451],{"class":1630},"  annotations:\n",[747,53453,53454,53457],{"class":749,"line":842},[747,53455,53456],{"class":1630},"    kubernetes.io\u002Fservice-account.name:",[747,53458,7736],{"class":802},[747,53460,53461,53463,53465],{"class":749,"line":850},[747,53462,13246],{"class":757},[747,53464,5685],{"class":1640},[747,53466,4268],{"class":757},[747,53468,53469,53471],{"class":749,"line":863},[747,53470,23251],{"class":1630},[747,53472,53473],{"class":802}," default-token-nmx1q\n",[747,53475,53476,53478],{"class":749,"line":869},[747,53477,23215],{"class":1630},[747,53479,22408],{"class":802},[747,53481,53482,53484,53486],{"class":749,"line":877},[747,53483,13246],{"class":757},[747,53485,5685],{"class":1640},[747,53487,4268],{"class":757},[747,53489,53490,53492,53494],{"class":749,"line":1015},[747,53491,23273],{"class":4574},[747,53493,856],{"class":802},[747,53495,23278],{"class":802},[747,53497,53498,53500,53502,53505,53507,53509],{"class":749,"line":1021},[747,53499,1919],{"class":1630},[747,53501,23285],{"class":802},[747,53503,53504],{"class":802}," YOUR_TOKEN_HERE",[747,53506,3170],{"class":757},[747,53508,23293],{"class":1630},[747,53510,23296],{"class":802},[747,53512,53513],{"class":749,"line":1027},[747,53514,23301],{"class":1630},[523,53516,53517,53518,53520],{},"In the end copy ",[567,53519,23312],{}," somewhere safe.",[535,53522,23317],{"id":23316},[523,53524,53525,53526,53529,53530,53533,53534,53536],{},"At least for my cluster that I setup with the ",[567,53527,53528],{},"kubernetes\u002Fcontrib"," Ansible deployment the Kubernetes CA certificate is located in ",[567,53531,53532],{},"\u002Fetc\u002Fkubernetes\u002Fcerts\u002Fca.crt",".\nSo a simple ",[567,53535,6515],{}," does the thing ;)",[738,53538,53540],{"className":1621,"code":53539,"language":1623,"meta":743,"style":743},"$ cat \u002Fetc\u002Fkubernetes\u002Fca.crt\n-----BEGIN CERTIFICATE-----\n[REDACATED]\n-----END CERTIFICATE-----\n",[567,53541,53542,53551,53557,53565],{"__ignoreMap":743},[747,53543,53544,53546,53548],{"class":749,"line":750},[747,53545,1919],{"class":1630},[747,53547,45045],{"class":802},[747,53549,53550],{"class":802}," \u002Fetc\u002Fkubernetes\u002Fca.crt\n",[747,53552,53553,53555],{"class":749,"line":761},[747,53554,23519],{"class":1630},[747,53556,23522],{"class":802},[747,53558,53559,53561,53563],{"class":749,"line":769},[747,53560,4253],{"class":757},[747,53562,23529],{"class":1640},[747,53564,4268],{"class":757},[747,53566,53567,53569],{"class":749,"line":776},[747,53568,23536],{"class":1630},[747,53570,23522],{"class":802},[523,53572,53573,53574,53576,53577,53580,53581,53583,53584,1909],{},"If you have gotten a ",[567,53575,15269],{}," config from your provider or administrator, you can find the CA certificate location in there at the ",[567,53578,53579],{},"certificate-authority"," key.\nIn most cases the so called ",[567,53582,36064],{}," will be located at ",[567,53585,53586],{},"~\u002F.kube\u002Fconfig",[738,53588,53590],{"className":740,"code":53589,"language":742,"meta":743,"style":743},"[...]\napiVersion: v1\nclusters:\n- cluster:\n    # This is where CA certificate will be located at\n    certificate-authority: path\u002Fto\u002Fmy\u002Fcafile\n    server: https:\u002F\u002Fhorse.org:4443\n  name: horse-cluster\n[...]\n",[567,53591,53592,53600,53608,53615,53624,53629,53639,53649,53658],{"__ignoreMap":743},[747,53593,53594,53596,53598],{"class":749,"line":750},[747,53595,4253],{"class":757},[747,53597,5685],{"class":1895},[747,53599,4268],{"class":757},[747,53601,53602,53604,53606],{"class":749,"line":761},[747,53603,12949],{"class":753},[747,53605,856],{"class":757},[747,53607,22608],{"class":802},[747,53609,53610,53613],{"class":749,"line":769},[747,53611,53612],{"class":753},"clusters",[747,53614,758],{"class":757},[747,53616,53617,53619,53622],{"class":749,"line":776},[747,53618,3361],{"class":757},[747,53620,53621],{"class":753}," cluster",[747,53623,758],{"class":757},[747,53625,53626],{"class":749,"line":784},[747,53627,53628],{"class":772},"    # This is where CA certificate will be located at\n",[747,53630,53631,53634,53636],{"class":749,"line":790},[747,53632,53633],{"class":753},"    certificate-authority",[747,53635,856],{"class":757},[747,53637,53638],{"class":802}," path\u002Fto\u002Fmy\u002Fcafile\n",[747,53640,53641,53644,53646],{"class":749,"line":796},[747,53642,53643],{"class":753},"    server",[747,53645,856],{"class":757},[747,53647,53648],{"class":802}," https:\u002F\u002Fhorse.org:4443\n",[747,53650,53651,53653,53655],{"class":749,"line":806},[747,53652,12980],{"class":753},[747,53654,856],{"class":757},[747,53656,53657],{"class":802}," horse-cluster\n",[747,53659,53660,53662,53664],{"class":749,"line":814},[747,53661,4253],{"class":757},[747,53663,5685],{"class":1895},[747,53665,4268],{"class":757},[523,53667,53668,53669,53671,53672,53675,53676,53679,53680,53683],{},"If your ",[567,53670,36064],{}," does not contain a ",[567,53673,53674],{},"certificate-authority:",", but a ",[567,53677,53678],{},"certificate-authority-data:"," take the contents of it and run ",[567,53681,53682],{},"base64 -d"," on it. That will base64 decode the CA certificate for you.",[523,53685,53686,53687,53689,53690,1909],{},"For more information on ",[567,53688,36064],{},", see the Kubernetes documentation for \"access\" to Kubernetes cluster here: ",[527,53691,53692],{"href":53692,"rel":53693},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Ftasks\u002Faccess-application-cluster\u002Fauthenticate-across-clusters-kubeconfig\u002F",[531],[523,53695,53696],{},"For other cluster \"types\"\u002Fdeployments, please refer to your cluster administrator or guide.",[523,53698,53699,53700,1909],{},"Save the CA certificate somewhere safe with the token from ",[527,53701,22308],{"href":53702},"#Step2-Get-ServiceAccount-Token-from-Kubernetes",[535,53704,23563],{"id":23562},[523,53706,23566,53707,23569],{},[567,53708,22299],{},[523,53710,23572,53711,23576,53714,23579],{},[567,53712,53713],{},"CI\u002F CD",[567,53715,124],{},[523,53717,53718],{},[3069,53719],{"alt":23584,"src":53720},"\u002Fblog\u002F2018\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature\u002Fgitlab-ci-kubernetes-cluster-empty-cluster-list.png",[523,53722,23588,53723,53725],{},[567,53724,23591],{}," button and you get this page:",[523,53727,53728],{},[3069,53729],{"alt":53730,"src":53731},"GitLab CI Kubernetes cluster - Create GKE cluster or add existing cluster page","\u002Fblog\u002F2018\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature\u002Fgitlab-ci-kubernetes-cluster-add-cluster.png",[523,53733,53734,53735,53738],{},"On this page you can decide, if you want to create a new Google GKE cluster or add an existing cluster.\nClick ",[567,53736,53737],{},"Add an existing Kubernetes cluster"," button, so we can the Kubernetes cluster we just gathered the information for.",[523,53740,53741],{},[3069,53742],{"alt":23603,"src":53743},"\u002Fblog\u002F2018\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature\u002Fgitlab-ci-kubernetes-cluster-add-existing-cluster.png",[523,53745,8764,53746,53748],{},[567,53747,23614],{}," can be \"anything\", pick something you are able to identify the cluster later on again in case of issues. The other fields should be filled with the information we gathered it in the previous steps.",[523,53750,8764,53751,53754,53755,53757,53758,53760],{},[567,53752,53753],{},"Project namespace"," is optional though the ",[567,53756,23716],{}," shown above\u002Fused here \"must\" have a Kubernetes namespace provided, so set it to ",[567,53759,22323],{}," (or your own value, but you need to change all manifests in the repository to match this one then).",[523,53762,23706,53763,53765],{},[567,53764,23591],{}," to add the cluster to GitLab and you now have the Kubernetes integration activated and ready.",[535,53767,23713,53768,23717],{"id":23712},[567,53769,23716],{},[6072,53771,53772,53776,53789],{},[523,53773,53774],{},[584,53775,6189],{},[523,53777,23726,53778,23730,53780,23734,53782,23740,53785,23743,53787,23747],{},[567,53779,23729],{},[567,53781,23733],{},[527,53783,23739],{"href":23737,"rel":53784},[531],[567,53786,22359],{},[567,53788,23746],{},[523,53790,53791,53793,53794,53796],{},[584,53792,15250],{}," You should first commit when you are done with adding the manifests from the ",[584,53795,23759],{}," too!",[523,53798,8764,53799,53801],{},[567,53800,23716],{}," is based on the official GitLab CI Go template.",[523,53803,23763,53804,23766],{},[567,53805,23716],{},[738,53807,53808],{"className":740,"code":23769,"language":742,"meta":743,"style":743},[567,53809,53810,53814,53820,53828,53834],{"__ignoreMap":743},[747,53811,53812],{"class":749,"line":750},[747,53813,23776],{"class":772},[747,53815,53816,53818],{"class":749,"line":761},[747,53817,23781],{"class":753},[747,53819,758],{"class":757},[747,53821,53822,53824,53826],{"class":749,"line":769},[747,53823,23788],{"class":753},[747,53825,856],{"class":757},[747,53827,23793],{"class":802},[747,53829,53830,53832],{"class":749,"line":776},[747,53831,23798],{"class":753},[747,53833,758],{"class":757},[747,53835,53836,53838],{"class":749,"line":784},[747,53837,14801],{"class":757},[747,53839,23807],{"class":802},[523,53841,23810,53842,23813],{},[567,53843,23781],{},[523,53845,23816],{},[738,53847,53848],{"className":740,"code":23819,"language":742,"meta":743,"style":743},[567,53849,53850,53854,53860,53866,53872,53878],{"__ignoreMap":743},[747,53851,53852],{"class":749,"line":750},[747,53853,23826],{"class":772},[747,53855,53856,53858],{"class":749,"line":761},[747,53857,23831],{"class":753},[747,53859,758],{"class":757},[747,53861,53862,53864],{"class":749,"line":769},[747,53863,18665],{"class":757},[747,53865,23793],{"class":802},[747,53867,53868,53870],{"class":749,"line":776},[747,53869,18665],{"class":757},[747,53871,23846],{"class":802},[747,53873,53874,53876],{"class":749,"line":784},[747,53875,18665],{"class":757},[747,53877,23853],{"class":802},[747,53879,53880,53882],{"class":749,"line":790},[747,53881,18665],{"class":757},[747,53883,23860],{"class":802},[523,53885,23863],{},[738,53887,53889],{"className":740,"code":53888,"language":742,"meta":743,"style":743},"# For jobs without a image specified use the below\nimage: golang:1.10.3-stretch\n# Or for the test job the image `golang:1.9` will be used:\ntest:\n    stage: test\n    image: python:3\n    script:\n        - echo Something in the test step in a python:3 image\n",[567,53890,53891,53896,53905,53909,53915,53923,53931,53937],{"__ignoreMap":743},[747,53892,53893],{"class":749,"line":750},[747,53894,53895],{"class":772},"# For jobs without a image specified use the below\n",[747,53897,53898,53900,53902],{"class":749,"line":761},[747,53899,23878],{"class":753},[747,53901,856],{"class":757},[747,53903,53904],{"class":802}," golang:1.10.3-stretch\n",[747,53906,53907],{"class":749,"line":769},[747,53908,23888],{"class":772},[747,53910,53911,53913],{"class":749,"line":776},[747,53912,23781],{"class":753},[747,53914,758],{"class":757},[747,53916,53917,53919,53921],{"class":749,"line":784},[747,53918,23788],{"class":753},[747,53920,856],{"class":757},[747,53922,23793],{"class":802},[747,53924,53925,53927,53929],{"class":749,"line":790},[747,53926,10899],{"class":753},[747,53928,856],{"class":757},[747,53930,23911],{"class":802},[747,53932,53933,53935],{"class":749,"line":796},[747,53934,23798],{"class":753},[747,53936,758],{"class":757},[747,53938,53939,53941],{"class":749,"line":806},[747,53940,14801],{"class":757},[747,53942,23924],{"class":802},[6072,53944,53945,53949],{},[523,53946,53947],{},[584,53948,6189],{},[523,53950,23933,53951,23936,53953,1909],{},[567,53952,23716],{},[527,53954,23939],{"href":23939,"rel":53955},[531],[523,53957,8336,53958,23945,53960,714,53962,714,53964,587,53966,856],{},[567,53959,23716],{},[567,53961,23781],{},[567,53963,9758],{},[567,53965,23952],{},[567,53967,23955],{},[668,53969,53970,53977,53983,53993],{},[638,53971,53972,23962,53974,23968],{},[567,53973,23781],{},[527,53975,23967],{"href":23965,"rel":53976},[531],[638,53978,53979,23973,53981,23977],{},[567,53980,9758],{},[567,53982,23976],{},[638,53984,53985,23982,53987,23986,53989,23989,53991,23992],{},[567,53986,23952],{},[567,53988,23985],{},[567,53990,23952],{},[567,53992,23976],{},[638,53994,53995,23997,53997,24001,53999,24004,54001,24008],{},[567,53996,23955],{},[567,53998,24000],{},[567,54000,24000],{},[567,54002,24007],{},[523,54004,24023,54005,23766],{},[567,54006,23716],{},[738,54008,54010],{"className":740,"code":54009,"language":742,"meta":743,"style":743},"image: golang:1.10.3-stretch\n\n# The problem is that to be able to use go get, one needs to put\n# the repository in the $GOPATH. So for example if your gitlab domain\n# is mydomainperso.com, and that your repository is repos\u002Fprojectname, and\n# the default GOPATH being \u002Fgo, then you'd need to have your\n# repository in \u002Fgo\u002Fsrc\u002Fmydomainperso.com\u002Frepos\u002Fprojectname\n# Thus, making a symbolic link corrects this.\nbefore_script:\n  - mkdir -p \"\u002Fgo\u002Fsrc\u002Fgitlab.zerbytes.net\u002F${CI_PROJECT_NAMESPACE}\"\n  - ln -sf \"${CI_PROJECT_DIR}\" \"\u002Fgo\u002Fsrc\u002Fgitlab.zerbytes.net\u002F${CI_PROJECT_PATH}\"\n  - cd \"\u002Fgo\u002Fsrc\u002Fgitlab.zerbytes.net\u002F${CI_PROJECT_PATH}\u002F\"\n\nstages:\n  - test\n  - build\n  - release\n  - review\n  - deploy\n\ntest:\n  stage: test\n  script:\n    - make test\n\ntest2:\n  stage: test\n  script:\n    - sleep 3\n    - echo \"We did it! Something else runs in parallel!\"\n\ncompile:\n  stage: build\n  script:\n    # Add here all the dependencies, or use glide\u002Fgovendor\u002F...\n    # to get them automatically.\n    - make build\n  artifacts:\n    paths:\n      - app\n\n# Example job to upload the built release to a S3 server with mc\n# For this you need to set `S3_ACCESS_KEY` and `S3_SECRET_KEY` in your GitLab project CI's secret variables\n#release_upload:\n#  stage: release\n#  image: minio\u002Fmc\n#  script:\n#    - echo \"=> We already have artifact sotrage in GitLab! This is for demonstational purposes only.\"\n#    - mc config host add edenmalnet https:\u002F\u002Fs3.edenmal.net ${S3_ACCESS_KEY} ${S3_SECRET_KEY} S3v4\n#    - mc mb -p edenmalnet\u002Fbuild-release-${CI_PROJECT_NAME}\u002F\n#    - mc cp app edenmalnet\u002Fbuild-release-${CI_PROJECT_NAME}\u002F\n\nimage_build:\n  stage: release\n  image: docker:latest\n  variables:\n    DOCKER_HOST: tcp:\u002F\u002Flocalhost:2375\n  services:\n    - docker:dind\n  script:\n    - docker info\n    - docker login -u gitlab-ci-token -p ${CI_JOB_TOKEN} registry.zerbytes.net\n    - docker build -t registry.zerbytes.net\u002F${CI_PROJECT_PATH}:latest .\n    - docker tag registry.zerbytes.net\u002F${CI_PROJECT_PATH}:latest registry.zerbytes.net\u002F${CI_PROJECT_PATH}:${CI_COMMIT_REF_NAME}\n    - test ! -z \"${CI_COMMIT_TAG}\" && docker push registry.zerbytes.net\u002F${CI_PROJECT_PATH}:latest\n    - docker push registry.zerbytes.net\u002F${CI_PROJECT_PATH}:${CI_COMMIT_REF_NAME}\n\ndeploy_review:\n  image: lachlanevenson\u002Fk8s-kubectl:latest\n  stage: review\n  only:\n    - branches\n  except:\n    - tags\n  environment:\n    name: review\u002F$CI_BUILD_REF_NAME\n    url: https:\u002F\u002F$CI_BUILD_REF_SLUG-presentation-gitlab-k8s.edenmal.net\n    on_stop: stop_review\n    kubernetes:\n      namespace: presentation-gitlab-k8s\n  script:\n    - kubectl version\n    - cd manifests\u002F\n    - sed -i \"s\u002F__CI_BUILD_REF_SLUG__\u002F${CI_BUILD_REF_SLUG}\u002F\" deployment.yaml ingress.yaml service.yaml\n    - sed -i \"s\u002F__VERSION__\u002F${CI_COMMIT_REF_NAME}\u002F\" deployment.yaml ingress.yaml service.yaml\n    - |\n      if kubectl apply -f deployment.yaml | grep -q unchanged; then\n          echo \"=> Patching deployment to force image update.\"\n          kubectl patch -f deployment.yaml -p \"{\\\"spec\\\":{\\\"template\\\":{\\\"metadata\\\":{\\\"annotations\\\":{\\\"ci-last-updated\\\":\\\"$(date +'%s')\\\"}}}}}\"\n      else\n          echo \"=> Deployment apply has changed the object, no need to force image update.\"\n      fi\n    - kubectl apply -f service.yaml || true\n    - kubectl apply -f ingress.yaml\n    - kubectl rollout status -f deployment.yaml\n    - kubectl get all,ing -l app=${CI_BUILD_REF_SLUG}\n\nstop_review:\n  image: lachlanevenson\u002Fk8s-kubectl:latest\n  stage: review\n  variables:\n    GIT_STRATEGY: none\n  when: manual\n  only:\n    - branches\n  except:\n    - master\n    - tags\n  environment:\n    name: review\u002F$CI_BUILD_REF_NAME\n    action: stop\n    kubernetes:\n      namespace: presentation-gitlab-k8s\n  script:\n    - kubectl version\n    - kubectl delete ing -l app=${CI_BUILD_REF_SLUG}\n    - kubectl delete all -l app=${CI_BUILD_REF_SLUG}\n\ndeploy_live:\n  image: lachlanevenson\u002Fk8s-kubectl:latest\n  stage: deploy\n  environment:\n    name: live\n    url: https:\u002F\u002Flive-presentation-gitlab-k8s.edenmal.net\n    kubernetes:\n      namespace: presentation-gitlab-k8s\n  only:\n    - tags\n  when: manual\n  script:\n    - kubectl version\n    - cd manifests\u002F\n    - sed -i \"s\u002F__CI_BUILD_REF_SLUG__\u002F${CI_ENVIRONMENT_SLUG}\u002F\" deployment.yaml ingress.yaml service.yaml\n    - sed -i \"s\u002F__VERSION__\u002F${CI_COMMIT_REF_NAME}\u002F\" deployment.yaml ingress.yaml service.yaml\n    - kubectl apply -f deployment.yaml\n    - kubectl apply -f service.yaml\n    - kubectl apply -f ingress.yaml\n    - kubectl rollout status -f deployment.yaml\n    - kubectl get all,ing -l app=${CI_ENVIRONMENT_SLUG}\n",[567,54011,54012,54020,54024,54028,54032,54036,54040,54044,54048,54054,54061,54068,54075,54079,54085,54091,54097,54103,54109,54115,54119,54125,54133,54139,54145,54149,54155,54163,54169,54175,54181,54185,54191,54199,54205,54209,54213,54219,54225,54231,54237,54241,54245,54249,54253,54257,54262,54266,54270,54275,54280,54285,54289,54295,54303,54311,54317,54325,54331,54337,54343,54349,54356,54363,54370,54377,54384,54388,54394,54402,54410,54416,54422,54428,54434,54440,54448,54457,54465,54471,54479,54485,54491,54497,54504,54510,54516,54520,54524,54528,54532,54536,54540,54546,54552,54558,54565,54569,54575,54583,54591,54597,54605,54613,54619,54625,54631,54637,54643,54649,54657,54665,54671,54679,54685,54691,54698,54705,54709,54715,54723,54731,54737,54745,54753,54759,54767,54773,54779,54787,54793,54799,54805,54812,54818,54824,54830,54836,54842],{"__ignoreMap":743},[747,54013,54014,54016,54018],{"class":749,"line":750},[747,54015,23878],{"class":753},[747,54017,856],{"class":757},[747,54019,53904],{"class":802},[747,54021,54022],{"class":749,"line":761},[747,54023,1255],{"emptyLinePlaceholder":1254},[747,54025,54026],{"class":749,"line":769},[747,54027,24079],{"class":772},[747,54029,54030],{"class":749,"line":776},[747,54031,24084],{"class":772},[747,54033,54034],{"class":749,"line":784},[747,54035,24089],{"class":772},[747,54037,54038],{"class":749,"line":790},[747,54039,24094],{"class":772},[747,54041,54042],{"class":749,"line":796},[747,54043,24099],{"class":772},[747,54045,54046],{"class":749,"line":806},[747,54047,24104],{"class":772},[747,54049,54050,54052],{"class":749,"line":814},[747,54051,24109],{"class":753},[747,54053,758],{"class":757},[747,54055,54056,54058],{"class":749,"line":822},[747,54057,1721],{"class":757},[747,54059,54060],{"class":802}," mkdir -p \"\u002Fgo\u002Fsrc\u002Fgitlab.zerbytes.net\u002F${CI_PROJECT_NAMESPACE}\"\n",[747,54062,54063,54065],{"class":749,"line":830},[747,54064,1721],{"class":757},[747,54066,54067],{"class":802}," ln -sf \"${CI_PROJECT_DIR}\" \"\u002Fgo\u002Fsrc\u002Fgitlab.zerbytes.net\u002F${CI_PROJECT_PATH}\"\n",[747,54069,54070,54072],{"class":749,"line":836},[747,54071,1721],{"class":757},[747,54073,54074],{"class":802}," cd \"\u002Fgo\u002Fsrc\u002Fgitlab.zerbytes.net\u002F${CI_PROJECT_PATH}\u002F\"\n",[747,54076,54077],{"class":749,"line":842},[747,54078,1255],{"emptyLinePlaceholder":1254},[747,54080,54081,54083],{"class":749,"line":850},[747,54082,23831],{"class":753},[747,54084,758],{"class":757},[747,54086,54087,54089],{"class":749,"line":863},[747,54088,1721],{"class":757},[747,54090,23793],{"class":802},[747,54092,54093,54095],{"class":749,"line":869},[747,54094,1721],{"class":757},[747,54096,23846],{"class":802},[747,54098,54099,54101],{"class":749,"line":877},[747,54100,1721],{"class":757},[747,54102,23853],{"class":802},[747,54104,54105,54107],{"class":749,"line":1015},[747,54106,1721],{"class":757},[747,54108,24167],{"class":802},[747,54110,54111,54113],{"class":749,"line":1021},[747,54112,1721],{"class":757},[747,54114,23860],{"class":802},[747,54116,54117],{"class":749,"line":1027},[747,54118,1255],{"emptyLinePlaceholder":1254},[747,54120,54121,54123],{"class":749,"line":1033},[747,54122,23781],{"class":753},[747,54124,758],{"class":757},[747,54126,54127,54129,54131],{"class":749,"line":1039},[747,54128,24188],{"class":753},[747,54130,856],{"class":757},[747,54132,23793],{"class":802},[747,54134,54135,54137],{"class":749,"line":1054},[747,54136,24197],{"class":753},[747,54138,758],{"class":757},[747,54140,54141,54143],{"class":749,"line":1060},[747,54142,18665],{"class":757},[747,54144,24206],{"class":802},[747,54146,54147],{"class":749,"line":1066},[747,54148,1255],{"emptyLinePlaceholder":1254},[747,54150,54151,54153],{"class":749,"line":1081},[747,54152,24215],{"class":753},[747,54154,758],{"class":757},[747,54156,54157,54159,54161],{"class":749,"line":1087},[747,54158,24188],{"class":753},[747,54160,856],{"class":757},[747,54162,23793],{"class":802},[747,54164,54165,54167],{"class":749,"line":1102},[747,54166,24197],{"class":753},[747,54168,758],{"class":757},[747,54170,54171,54173],{"class":749,"line":1110},[747,54172,18665],{"class":757},[747,54174,24238],{"class":802},[747,54176,54177,54179],{"class":749,"line":1117},[747,54178,18665],{"class":757},[747,54180,24245],{"class":802},[747,54182,54183],{"class":749,"line":1123},[747,54184,1255],{"emptyLinePlaceholder":1254},[747,54186,54187,54189],{"class":749,"line":1129},[747,54188,24254],{"class":753},[747,54190,758],{"class":757},[747,54192,54193,54195,54197],{"class":749,"line":1142},[747,54194,24188],{"class":753},[747,54196,856],{"class":757},[747,54198,23846],{"class":802},[747,54200,54201,54203],{"class":749,"line":1150},[747,54202,24197],{"class":753},[747,54204,758],{"class":757},[747,54206,54207],{"class":749,"line":1157},[747,54208,24275],{"class":772},[747,54210,54211],{"class":749,"line":1163},[747,54212,24280],{"class":772},[747,54214,54215,54217],{"class":749,"line":1168},[747,54216,18665],{"class":757},[747,54218,24287],{"class":802},[747,54220,54221,54223],{"class":749,"line":1174},[747,54222,24292],{"class":753},[747,54224,758],{"class":757},[747,54226,54227,54229],{"class":749,"line":1480},[747,54228,24299],{"class":753},[747,54230,758],{"class":757},[747,54232,54233,54235],{"class":749,"line":1491},[747,54234,799],{"class":757},[747,54236,24308],{"class":802},[747,54238,54239],{"class":749,"line":1496},[747,54240,1255],{"emptyLinePlaceholder":1254},[747,54242,54243],{"class":749,"line":1502},[747,54244,24317],{"class":772},[747,54246,54247],{"class":749,"line":1510},[747,54248,24322],{"class":772},[747,54250,54251],{"class":749,"line":1520},[747,54252,24327],{"class":772},[747,54254,54255],{"class":749,"line":1525},[747,54256,24332],{"class":772},[747,54258,54259],{"class":749,"line":1533},[747,54260,54261],{"class":772},"#  image: minio\u002Fmc\n",[747,54263,54264],{"class":749,"line":1539},[747,54265,24352],{"class":772},[747,54267,54268],{"class":749,"line":1549},[747,54269,24357],{"class":772},[747,54271,54272],{"class":749,"line":1554},[747,54273,54274],{"class":772},"#    - mc config host add edenmalnet https:\u002F\u002Fs3.edenmal.net ${S3_ACCESS_KEY} ${S3_SECRET_KEY} S3v4\n",[747,54276,54277],{"class":749,"line":1562},[747,54278,54279],{"class":772},"#    - mc mb -p edenmalnet\u002Fbuild-release-${CI_PROJECT_NAME}\u002F\n",[747,54281,54282],{"class":749,"line":1568},[747,54283,54284],{"class":772},"#    - mc cp app edenmalnet\u002Fbuild-release-${CI_PROJECT_NAME}\u002F\n",[747,54286,54287],{"class":749,"line":1577},[747,54288,1255],{"emptyLinePlaceholder":1254},[747,54290,54291,54293],{"class":749,"line":1582},[747,54292,23985],{"class":753},[747,54294,758],{"class":757},[747,54296,54297,54299,54301],{"class":749,"line":1588},[747,54298,24188],{"class":753},[747,54300,856],{"class":757},[747,54302,23853],{"class":802},[747,54304,54305,54307,54309],{"class":749,"line":1594},[747,54306,24395],{"class":753},[747,54308,856],{"class":757},[747,54310,24407],{"class":802},[747,54312,54313,54315],{"class":749,"line":1600},[747,54314,24437],{"class":753},[747,54316,758],{"class":757},[747,54318,54319,54321,54323],{"class":749,"line":4804},[747,54320,24444],{"class":753},[747,54322,856],{"class":757},[747,54324,24449],{"class":802},[747,54326,54327,54329],{"class":749,"line":4810},[747,54328,24454],{"class":753},[747,54330,758],{"class":757},[747,54332,54333,54335],{"class":749,"line":4816},[747,54334,18665],{"class":757},[747,54336,24463],{"class":802},[747,54338,54339,54341],{"class":749,"line":4822},[747,54340,24197],{"class":753},[747,54342,758],{"class":757},[747,54344,54345,54347],{"class":749,"line":4828},[747,54346,18665],{"class":757},[747,54348,24476],{"class":802},[747,54350,54351,54353],{"class":749,"line":4834},[747,54352,18665],{"class":757},[747,54354,54355],{"class":802}," docker login -u gitlab-ci-token -p ${CI_JOB_TOKEN} registry.zerbytes.net\n",[747,54357,54358,54360],{"class":749,"line":4840},[747,54359,18665],{"class":757},[747,54361,54362],{"class":802}," docker build -t registry.zerbytes.net\u002F${CI_PROJECT_PATH}:latest .\n",[747,54364,54365,54367],{"class":749,"line":4846},[747,54366,18665],{"class":757},[747,54368,54369],{"class":802}," docker tag registry.zerbytes.net\u002F${CI_PROJECT_PATH}:latest registry.zerbytes.net\u002F${CI_PROJECT_PATH}:${CI_COMMIT_REF_NAME}\n",[747,54371,54372,54374],{"class":749,"line":4852},[747,54373,18665],{"class":757},[747,54375,54376],{"class":802}," test ! -z \"${CI_COMMIT_TAG}\" && docker push registry.zerbytes.net\u002F${CI_PROJECT_PATH}:latest\n",[747,54378,54379,54381],{"class":749,"line":4858},[747,54380,18665],{"class":757},[747,54382,54383],{"class":802}," docker push registry.zerbytes.net\u002F${CI_PROJECT_PATH}:${CI_COMMIT_REF_NAME}\n",[747,54385,54386],{"class":749,"line":4864},[747,54387,1255],{"emptyLinePlaceholder":1254},[747,54389,54390,54392],{"class":749,"line":4870},[747,54391,24520],{"class":753},[747,54393,758],{"class":757},[747,54395,54396,54398,54400],{"class":749,"line":4876},[747,54397,24395],{"class":753},[747,54399,856],{"class":757},[747,54401,24537],{"class":802},[747,54403,54404,54406,54408],{"class":749,"line":4882},[747,54405,24188],{"class":753},[747,54407,856],{"class":757},[747,54409,24167],{"class":802},[747,54411,54412,54414],{"class":749,"line":4888},[747,54413,24574],{"class":753},[747,54415,758],{"class":757},[747,54417,54418,54420],{"class":749,"line":4894},[747,54419,18665],{"class":757},[747,54421,24583],{"class":802},[747,54423,54424,54426],{"class":749,"line":4900},[747,54425,24588],{"class":753},[747,54427,758],{"class":757},[747,54429,54430,54432],{"class":749,"line":4906},[747,54431,18665],{"class":757},[747,54433,24597],{"class":802},[747,54435,54436,54438],{"class":749,"line":4912},[747,54437,24602],{"class":753},[747,54439,758],{"class":757},[747,54441,54442,54444,54446],{"class":749,"line":4928},[747,54443,24402],{"class":753},[747,54445,856],{"class":757},[747,54447,24613],{"class":802},[747,54449,54450,54452,54454],{"class":749,"line":4934},[747,54451,24618],{"class":753},[747,54453,856],{"class":757},[747,54455,54456],{"class":802}," https:\u002F\u002F$CI_BUILD_REF_SLUG-presentation-gitlab-k8s.edenmal.net\n",[747,54458,54459,54461,54463],{"class":749,"line":4940},[747,54460,24628],{"class":753},[747,54462,856],{"class":757},[747,54464,24633],{"class":802},[747,54466,54467,54469],{"class":749,"line":4946},[747,54468,24638],{"class":753},[747,54470,758],{"class":757},[747,54472,54473,54475,54477],{"class":749,"line":4952},[747,54474,24645],{"class":753},[747,54476,856],{"class":757},[747,54478,22408],{"class":802},[747,54480,54481,54483],{"class":749,"line":4958},[747,54482,24197],{"class":753},[747,54484,758],{"class":757},[747,54486,54487,54489],{"class":749,"line":4964},[747,54488,18665],{"class":757},[747,54490,24662],{"class":802},[747,54492,54493,54495],{"class":749,"line":4970},[747,54494,18665],{"class":757},[747,54496,24669],{"class":802},[747,54498,54499,54501],{"class":749,"line":4998},[747,54500,18665],{"class":757},[747,54502,54503],{"class":802}," sed -i \"s\u002F__CI_BUILD_REF_SLUG__\u002F${CI_BUILD_REF_SLUG}\u002F\" deployment.yaml ingress.yaml service.yaml\n",[747,54505,54506,54508],{"class":749,"line":5016},[747,54507,18665],{"class":757},[747,54509,24690],{"class":802},[747,54511,54512,54514],{"class":749,"line":5048},[747,54513,18665],{"class":757},[747,54515,24697],{"class":19332},[747,54517,54518],{"class":749,"line":5077},[747,54519,24702],{"class":802},[747,54521,54522],{"class":749,"line":5098},[747,54523,24707],{"class":802},[747,54525,54526],{"class":749,"line":5121},[747,54527,24712],{"class":802},[747,54529,54530],{"class":749,"line":5127},[747,54531,24717],{"class":802},[747,54533,54534],{"class":749,"line":5133},[747,54535,24722],{"class":802},[747,54537,54538],{"class":749,"line":5139},[747,54539,24727],{"class":802},[747,54541,54542,54544],{"class":749,"line":5164},[747,54543,18665],{"class":757},[747,54545,24734],{"class":802},[747,54547,54548,54550],{"class":749,"line":5205},[747,54549,18665],{"class":757},[747,54551,24741],{"class":802},[747,54553,54554,54556],{"class":749,"line":5229},[747,54555,18665],{"class":757},[747,54557,24748],{"class":802},[747,54559,54560,54562],{"class":749,"line":5250},[747,54561,18665],{"class":757},[747,54563,54564],{"class":802}," kubectl get all,ing -l app=${CI_BUILD_REF_SLUG}\n",[747,54566,54567],{"class":749,"line":5264},[747,54568,1255],{"emptyLinePlaceholder":1254},[747,54570,54571,54573],{"class":749,"line":5282},[747,54572,24764],{"class":753},[747,54574,758],{"class":757},[747,54576,54577,54579,54581],{"class":749,"line":5311},[747,54578,24395],{"class":753},[747,54580,856],{"class":757},[747,54582,24537],{"class":802},[747,54584,54585,54587,54589],{"class":749,"line":5331},[747,54586,24188],{"class":753},[747,54588,856],{"class":757},[747,54590,24167],{"class":802},[747,54592,54593,54595],{"class":749,"line":5351},[747,54594,24437],{"class":753},[747,54596,758],{"class":757},[747,54598,54599,54601,54603],{"class":749,"line":5374},[747,54600,24823],{"class":753},[747,54602,856],{"class":757},[747,54604,930],{"class":802},[747,54606,54607,54609,54611],{"class":749,"line":5394},[747,54608,24832],{"class":753},[747,54610,856],{"class":757},[747,54612,24837],{"class":802},[747,54614,54615,54617],{"class":749,"line":5413},[747,54616,24574],{"class":753},[747,54618,758],{"class":757},[747,54620,54621,54623],{"class":749,"line":5430},[747,54622,18665],{"class":757},[747,54624,24583],{"class":802},[747,54626,54627,54629],{"class":749,"line":5447},[747,54628,24588],{"class":753},[747,54630,758],{"class":757},[747,54632,54633,54635],{"class":749,"line":5500},[747,54634,18665],{"class":757},[747,54636,22452],{"class":802},[747,54638,54639,54641],{"class":749,"line":5517},[747,54640,18665],{"class":757},[747,54642,24597],{"class":802},[747,54644,54645,54647],{"class":749,"line":5534},[747,54646,24602],{"class":753},[747,54648,758],{"class":757},[747,54650,54651,54653,54655],{"class":749,"line":5556},[747,54652,24402],{"class":753},[747,54654,856],{"class":757},[747,54656,24613],{"class":802},[747,54658,54659,54661,54663],{"class":749,"line":5577},[747,54660,24886],{"class":753},[747,54662,856],{"class":757},[747,54664,24891],{"class":802},[747,54666,54667,54669],{"class":749,"line":5606},[747,54668,24638],{"class":753},[747,54670,758],{"class":757},[747,54672,54673,54675,54677],{"class":749,"line":21912},[747,54674,24645],{"class":753},[747,54676,856],{"class":757},[747,54678,22408],{"class":802},[747,54680,54681,54683],{"class":749,"line":21918},[747,54682,24197],{"class":753},[747,54684,758],{"class":757},[747,54686,54687,54689],{"class":749,"line":21924},[747,54688,18665],{"class":757},[747,54690,24662],{"class":802},[747,54692,54693,54695],{"class":749,"line":21930},[747,54694,18665],{"class":757},[747,54696,54697],{"class":802}," kubectl delete ing -l app=${CI_BUILD_REF_SLUG}\n",[747,54699,54700,54702],{"class":749,"line":21935},[747,54701,18665],{"class":757},[747,54703,54704],{"class":802}," kubectl delete all -l app=${CI_BUILD_REF_SLUG}\n",[747,54706,54707],{"class":749,"line":21941},[747,54708,1255],{"emptyLinePlaceholder":1254},[747,54710,54711,54713],{"class":749,"line":21946},[747,54712,24940],{"class":753},[747,54714,758],{"class":757},[747,54716,54717,54719,54721],{"class":749,"line":21952},[747,54718,24395],{"class":753},[747,54720,856],{"class":757},[747,54722,24537],{"class":802},[747,54724,54725,54727,54729],{"class":749,"line":21957},[747,54726,24188],{"class":753},[747,54728,856],{"class":757},[747,54730,23860],{"class":802},[747,54732,54733,54735],{"class":749,"line":21963},[747,54734,24602],{"class":753},[747,54736,758],{"class":757},[747,54738,54739,54741,54743],{"class":749,"line":21969},[747,54740,24402],{"class":753},[747,54742,856],{"class":757},[747,54744,25003],{"class":802},[747,54746,54747,54749,54751],{"class":749,"line":21974},[747,54748,24618],{"class":753},[747,54750,856],{"class":757},[747,54752,25012],{"class":802},[747,54754,54755,54757],{"class":749,"line":21980},[747,54756,24638],{"class":753},[747,54758,758],{"class":757},[747,54760,54761,54763,54765],{"class":749,"line":21986},[747,54762,24645],{"class":753},[747,54764,856],{"class":757},[747,54766,22408],{"class":802},[747,54768,54769,54771],{"class":749,"line":21992},[747,54770,24574],{"class":753},[747,54772,758],{"class":757},[747,54774,54775,54777],{"class":749,"line":21997},[747,54776,18665],{"class":757},[747,54778,24597],{"class":802},[747,54780,54781,54783,54785],{"class":749,"line":22003},[747,54782,24832],{"class":753},[747,54784,856],{"class":757},[747,54786,24837],{"class":802},[747,54788,54789,54791],{"class":749,"line":22008},[747,54790,24197],{"class":753},[747,54792,758],{"class":757},[747,54794,54795,54797],{"class":749,"line":22014},[747,54796,18665],{"class":757},[747,54798,24662],{"class":802},[747,54800,54801,54803],{"class":749,"line":22020},[747,54802,18665],{"class":757},[747,54804,24669],{"class":802},[747,54806,54807,54809],{"class":749,"line":22025},[747,54808,18665],{"class":757},[747,54810,54811],{"class":802}," sed -i \"s\u002F__CI_BUILD_REF_SLUG__\u002F${CI_ENVIRONMENT_SLUG}\u002F\" deployment.yaml ingress.yaml service.yaml\n",[747,54813,54814,54816],{"class":749,"line":22031},[747,54815,18665],{"class":757},[747,54817,24690],{"class":802},[747,54819,54820,54822],{"class":749,"line":22036},[747,54821,18665],{"class":757},[747,54823,25089],{"class":802},[747,54825,54826,54828],{"class":749,"line":22042},[747,54827,18665],{"class":757},[747,54829,25096],{"class":802},[747,54831,54832,54834],{"class":749,"line":22048},[747,54833,18665],{"class":757},[747,54835,24741],{"class":802},[747,54837,54838,54840],{"class":749,"line":22053},[747,54839,18665],{"class":757},[747,54841,24748],{"class":802},[747,54843,54844,54846],{"class":749,"line":22059},[747,54845,18665],{"class":757},[747,54847,54848],{"class":802}," kubectl get all,ing -l app=${CI_ENVIRONMENT_SLUG}\n",[523,54850,25137,54851,587,54853,25144,54855,25148,54857],{},[567,54852,25140],{},[567,54854,25143],{},[567,54856,25147],{},[527,54858,23939],{"href":23939,"rel":54859},[531],[523,54861,25154,54862,25157],{},[567,54863,19016],{},[535,54865,25161],{"id":25160},[523,54867,25164,54868,25168,54870,54872],{},[567,54869,25167],{},[567,54871,15269],{}," downloaded and usable on your system for that.\nThe command for creating the Docker login secret is:",[738,54874,54876],{"className":1621,"code":54875,"language":1623,"meta":743,"style":743},"# YOUR_SECRET_NAME for example \"registry-example-gitlab-key\"\n$ kubectl create \\\n    -n presentation-gitlab-k8s \\\n    secret docker-registry YOUR_PULLSECRET_NAME_HERE \\\n    --docker-server=registry.example.com \\\n    --docker-username=YOUR_GITLAB_USERNAME \\\n    --docker-password=YOUR_PERSONAL_GITLAB_ACCESS_TOKEN_HERE \\\n    --docker-email=YOUR_GITLAB_EMAIL_ADDRESS\n",[567,54877,54878,54883,54893,54901,54912,54918,54924,54931],{"__ignoreMap":743},[747,54879,54880],{"class":749,"line":750},[747,54881,54882],{"class":772},"# YOUR_SECRET_NAME for example \"registry-example-gitlab-key\"\n",[747,54884,54885,54887,54889,54891],{"class":749,"line":761},[747,54886,1919],{"class":1630},[747,54888,1922],{"class":802},[747,54890,1925],{"class":802},[747,54892,1641],{"class":1640},[747,54894,54895,54897,54899],{"class":749,"line":769},[747,54896,25210],{"class":802},[747,54898,23116],{"class":802},[747,54900,1641],{"class":1640},[747,54902,54903,54905,54907,54910],{"class":749,"line":776},[747,54904,25219],{"class":802},[747,54906,25222],{"class":802},[747,54908,54909],{"class":802}," YOUR_PULLSECRET_NAME_HERE",[747,54911,1641],{"class":1640},[747,54913,54914,54916],{"class":749,"line":784},[747,54915,25232],{"class":802},[747,54917,1641],{"class":1640},[747,54919,54920,54922],{"class":749,"line":790},[747,54921,25239],{"class":802},[747,54923,1641],{"class":1640},[747,54925,54926,54929],{"class":749,"line":796},[747,54927,54928],{"class":802},"    --docker-password=YOUR_PERSONAL_GITLAB_ACCESS_TOKEN_HERE",[747,54930,1641],{"class":1640},[747,54932,54933],{"class":749,"line":806},[747,54934,54935],{"class":802},"    --docker-email=YOUR_GITLAB_EMAIL_ADDRESS\n",[523,54937,54938,54939,54942,54943,54945],{},"Write down the name you gave the secret (",[567,54940,54941],{},"YOUR_PULLSECRET_NAME_HERE","). You will need to put it into the ",[567,54944,25331],{}," manifest that is coming up next.",[535,54947,25323],{"id":25322},[523,54949,25326],{},[523,54951,10839,54952,25332,54954,7258],{},[567,54953,25331],{},[567,54955,25335],{},[738,54957,54959],{"className":740,"code":54958,"language":742,"meta":743,"style":743},"apiVersion: apps\u002Fv1\nkind: Deployment\nmetadata:\n  name: __CI_BUILD_REF_SLUG__\n  labels:\n    app: __CI_BUILD_REF_SLUG__\n    track: stable\nspec:\n  replicas: 2\n  selector:\n    matchLabels:\n      app: __CI_BUILD_REF_SLUG__\n  template:\n    metadata:\n      labels:\n        app: __CI_BUILD_REF_SLUG__\n        track: stable\n    spec:\n      imagePullSecrets:\n        - name: regsecret\n      containers:\n      - name: app\n        image: registry.zerbytes.net\u002Fatrost\u002Fpresentation-gitlab-k8s:__VERSION__\n        imagePullPolicy: Always\n        ports:\n        - containerPort: 8000\n        livenessProbe:\n          httpGet:\n            path: \u002Fhealth\n            port: 8000\n          initialDelaySeconds: 3\n          timeoutSeconds: 2\n        readinessProbe:\n          httpGet:\n            path: \u002Fhealth\n            port: 8000\n          initialDelaySeconds: 3\n          timeoutSeconds: 2\n",[567,54960,54961,54969,54977,54983,54991,54997,55005,55013,55019,55027,55033,55039,55047,55053,55059,55065,55073,55081,55087,55094,55105,55111,55121,55130,55138,55144,55154,55160,55166,55174,55182,55190,55198,55204,55210,55218,55226,55234],{"__ignoreMap":743},[747,54962,54963,54965,54967],{"class":749,"line":750},[747,54964,12949],{"class":753},[747,54966,856],{"class":757},[747,54968,25349],{"class":802},[747,54970,54971,54973,54975],{"class":749,"line":761},[747,54972,12963],{"class":753},[747,54974,856],{"class":757},[747,54976,25358],{"class":802},[747,54978,54979,54981],{"class":749,"line":769},[747,54980,12973],{"class":753},[747,54982,758],{"class":757},[747,54984,54985,54987,54989],{"class":749,"line":776},[747,54986,12980],{"class":753},[747,54988,856],{"class":757},[747,54990,25796],{"class":802},[747,54992,54993,54995],{"class":749,"line":784},[747,54994,25378],{"class":753},[747,54996,758],{"class":757},[747,54998,54999,55001,55003],{"class":749,"line":790},[747,55000,25385],{"class":753},[747,55002,856],{"class":757},[747,55004,25796],{"class":802},[747,55006,55007,55009,55011],{"class":749,"line":796},[747,55008,25404],{"class":753},[747,55010,856],{"class":757},[747,55012,25409],{"class":802},[747,55014,55015,55017],{"class":749,"line":806},[747,55016,12990],{"class":753},[747,55018,758],{"class":757},[747,55020,55021,55023,55025],{"class":749,"line":814},[747,55022,25420],{"class":753},[747,55024,856],{"class":757},[747,55026,25425],{"class":1895},[747,55028,55029,55031],{"class":749,"line":822},[747,55030,25430],{"class":753},[747,55032,758],{"class":757},[747,55034,55035,55037],{"class":749,"line":830},[747,55036,25437],{"class":753},[747,55038,758],{"class":757},[747,55040,55041,55043,55045],{"class":749,"line":836},[747,55042,25444],{"class":753},[747,55044,856],{"class":757},[747,55046,25796],{"class":802},[747,55048,55049,55051],{"class":749,"line":842},[747,55050,25462],{"class":753},[747,55052,758],{"class":757},[747,55054,55055,55057],{"class":749,"line":850},[747,55056,21456],{"class":753},[747,55058,758],{"class":757},[747,55060,55061,55063],{"class":749,"line":863},[747,55062,25475],{"class":753},[747,55064,758],{"class":757},[747,55066,55067,55069,55071],{"class":749,"line":869},[747,55068,25482],{"class":753},[747,55070,856],{"class":757},[747,55072,25796],{"class":802},[747,55074,55075,55077,55079],{"class":749,"line":877},[747,55076,25500],{"class":753},[747,55078,856],{"class":757},[747,55080,25409],{"class":802},[747,55082,55083,55085],{"class":749,"line":1015},[747,55084,25509],{"class":753},[747,55086,758],{"class":757},[747,55088,55089,55092],{"class":749,"line":1021},[747,55090,55091],{"class":753},"      imagePullSecrets",[747,55093,758],{"class":757},[747,55095,55096,55098,55100,55102],{"class":749,"line":1027},[747,55097,14801],{"class":757},[747,55099,14804],{"class":753},[747,55101,856],{"class":757},[747,55103,55104],{"class":802}," regsecret\n",[747,55106,55107,55109],{"class":749,"line":1033},[747,55108,25516],{"class":753},[747,55110,758],{"class":757},[747,55112,55113,55115,55117,55119],{"class":749,"line":1039},[747,55114,799],{"class":757},[747,55116,14804],{"class":753},[747,55118,856],{"class":757},[747,55120,24308],{"class":802},[747,55122,55123,55125,55127],{"class":749,"line":1054},[747,55124,25533],{"class":753},[747,55126,856],{"class":757},[747,55128,55129],{"class":802}," registry.zerbytes.net\u002Fatrost\u002Fpresentation-gitlab-k8s:__VERSION__\n",[747,55131,55132,55134,55136],{"class":749,"line":1060},[747,55133,25543],{"class":753},[747,55135,856],{"class":757},[747,55137,25548],{"class":802},[747,55139,55140,55142],{"class":749,"line":1066},[747,55141,25553],{"class":753},[747,55143,758],{"class":757},[747,55145,55146,55148,55150,55152],{"class":749,"line":1081},[747,55147,14801],{"class":757},[747,55149,29864],{"class":753},[747,55151,856],{"class":757},[747,55153,25586],{"class":1895},[747,55155,55156,55158],{"class":749,"line":1087},[747,55157,25591],{"class":753},[747,55159,758],{"class":757},[747,55161,55162,55164],{"class":749,"line":1102},[747,55163,25598],{"class":753},[747,55165,758],{"class":757},[747,55167,55168,55170,55172],{"class":749,"line":1110},[747,55169,25605],{"class":753},[747,55171,856],{"class":757},[747,55173,25610],{"class":802},[747,55175,55176,55178,55180],{"class":749,"line":1117},[747,55177,25615],{"class":753},[747,55179,856],{"class":757},[747,55181,25586],{"class":1895},[747,55183,55184,55186,55188],{"class":749,"line":1123},[747,55185,25624],{"class":753},[747,55187,856],{"class":757},[747,55189,14751],{"class":1895},[747,55191,55192,55194,55196],{"class":749,"line":1129},[747,55193,25633],{"class":753},[747,55195,856],{"class":757},[747,55197,25425],{"class":1895},[747,55199,55200,55202],{"class":749,"line":1142},[747,55201,25642],{"class":753},[747,55203,758],{"class":757},[747,55205,55206,55208],{"class":749,"line":1150},[747,55207,25598],{"class":753},[747,55209,758],{"class":757},[747,55211,55212,55214,55216],{"class":749,"line":1157},[747,55213,25605],{"class":753},[747,55215,856],{"class":757},[747,55217,25610],{"class":802},[747,55219,55220,55222,55224],{"class":749,"line":1163},[747,55221,25615],{"class":753},[747,55223,856],{"class":757},[747,55225,25586],{"class":1895},[747,55227,55228,55230,55232],{"class":749,"line":1168},[747,55229,25624],{"class":753},[747,55231,856],{"class":757},[747,55233,14751],{"class":1895},[747,55235,55236,55238,55240],{"class":749,"line":1174},[747,55237,25633],{"class":753},[747,55239,856],{"class":757},[747,55241,25425],{"class":1895},[6072,55243,55244,55248],{},[523,55245,55246],{},[584,55247,6189],{},[523,55249,55250,55251,55254],{},"Don't forget to replace ",[567,55252,55253],{},"YOUR_SECRET_NAME_HERE"," with the actual name of your Docker login secret created in the previous step.",[523,55256,25685,55257,25688,55259,25691,55261],{},[567,55258,25331],{},[567,55260,25331],{},[527,55262,25694],{"href":25694,"rel":55263},[531],[523,55265,25698,55266,587,55268,25705,55270,25708,55272,6374,55274,25713,55276,25716],{},[567,55267,25701],{},[567,55269,25704],{},[567,55271,25701],{},[567,55273,24000],{},[567,55275,24007],{},[567,55277,25704],{},[523,55279,25719,55280,25723,55282,25726,55284,25730,55286,25733,55288,7258],{},[567,55281,25722],{},[567,55283,25331],{},[567,55285,25729],{},[567,55287,25729],{},[567,55289,25736],{},[738,55291,55292],{"className":740,"code":25739,"language":742,"meta":743,"style":743},[567,55293,55294,55302,55310,55316,55324,55332,55338,55346,55352,55364,55376,55388,55400,55406,55414,55420,55430,55438,55446,55452],{"__ignoreMap":743},[747,55295,55296,55298,55300],{"class":749,"line":750},[747,55297,12949],{"class":753},[747,55299,856],{"class":757},[747,55301,22608],{"class":802},[747,55303,55304,55306,55308],{"class":749,"line":761},[747,55305,12963],{"class":753},[747,55307,856],{"class":757},[747,55309,25758],{"class":802},[747,55311,55312,55314],{"class":749,"line":769},[747,55313,12973],{"class":753},[747,55315,758],{"class":757},[747,55317,55318,55320,55322],{"class":749,"line":776},[747,55319,12980],{"class":753},[747,55321,856],{"class":757},[747,55323,25773],{"class":802},[747,55325,55326,55328,55330],{"class":749,"line":784},[747,55327,13231],{"class":753},[747,55329,856],{"class":757},[747,55331,22408],{"class":802},[747,55333,55334,55336],{"class":749,"line":790},[747,55335,25378],{"class":753},[747,55337,758],{"class":757},[747,55339,55340,55342,55344],{"class":749,"line":796},[747,55341,25385],{"class":753},[747,55343,856],{"class":757},[747,55345,25796],{"class":802},[747,55347,55348,55350],{"class":749,"line":806},[747,55349,25801],{"class":753},[747,55351,758],{"class":757},[747,55353,55354,55356,55358,55360,55362],{"class":749,"line":814},[747,55355,25808],{"class":753},[747,55357,856],{"class":757},[747,55359,969],{"class":757},[747,55361,5306],{"class":802},[747,55363,975],{"class":757},[747,55365,55366,55368,55370,55372,55374],{"class":749,"line":822},[747,55367,25821],{"class":753},[747,55369,856],{"class":757},[747,55371,969],{"class":757},[747,55373,25828],{"class":802},[747,55375,975],{"class":757},[747,55377,55378,55380,55382,55384,55386],{"class":749,"line":830},[747,55379,25835],{"class":753},[747,55381,856],{"class":757},[747,55383,969],{"class":757},[747,55385,25842],{"class":802},[747,55387,975],{"class":757},[747,55389,55390,55392,55394,55396,55398],{"class":749,"line":836},[747,55391,25849],{"class":753},[747,55393,856],{"class":757},[747,55395,969],{"class":757},[747,55397,25856],{"class":802},[747,55399,975],{"class":757},[747,55401,55402,55404],{"class":749,"line":842},[747,55403,12990],{"class":753},[747,55405,758],{"class":757},[747,55407,55408,55410,55412],{"class":749,"line":850},[747,55409,18593],{"class":753},[747,55411,856],{"class":757},[747,55413,25873],{"class":802},[747,55415,55416,55418],{"class":749,"line":863},[747,55417,25878],{"class":753},[747,55419,758],{"class":757},[747,55421,55422,55424,55426,55428],{"class":749,"line":869},[747,55423,18665],{"class":757},[747,55425,14804],{"class":753},[747,55427,856],{"class":757},[747,55429,25566],{"class":802},[747,55431,55432,55434,55436],{"class":749,"line":877},[747,55433,25895],{"class":753},[747,55435,856],{"class":757},[747,55437,25586],{"class":1895},[747,55439,55440,55442,55444],{"class":749,"line":1015},[747,55441,25904],{"class":753},[747,55443,856],{"class":757},[747,55445,25576],{"class":802},[747,55447,55448,55450],{"class":749,"line":1021},[747,55449,25430],{"class":753},[747,55451,758],{"class":757},[747,55453,55454,55456,55458],{"class":749,"line":1027},[747,55455,25385],{"class":753},[747,55457,856],{"class":757},[747,55459,25796],{"class":802},[523,55461,25925,55462,25928,55464,25932,55466,25938,55469,25941,55471,25944,55473,25947,55475],{},[567,55463,25828],{},[567,55465,25931],{},[527,55467,25937],{"href":25935,"rel":55468},[531],[567,55470,25729],{},[567,55472,25931],{},[567,55474,25729],{},[527,55476,25950],{"href":25950,"rel":55477},[531],[523,55479,25954,55480,25957,55482,25960,55484,3052],{},[567,55481,158],{},[567,55483,25729],{},[567,55485,25963],{},[738,55487,55488],{"className":740,"code":25966,"language":742,"meta":743,"style":743},[567,55489,55490,55498,55506,55512,55520,55528,55534,55542,55548,55560,55572,55578,55584,55592,55598,55602,55606,55614,55620,55630,55636,55642,55652,55658,55666],{"__ignoreMap":743},[747,55491,55492,55494,55496],{"class":749,"line":750},[747,55493,12949],{"class":753},[747,55495,856],{"class":757},[747,55497,25977],{"class":802},[747,55499,55500,55502,55504],{"class":749,"line":761},[747,55501,12963],{"class":753},[747,55503,856],{"class":757},[747,55505,25986],{"class":802},[747,55507,55508,55510],{"class":749,"line":769},[747,55509,12973],{"class":753},[747,55511,758],{"class":757},[747,55513,55514,55516,55518],{"class":749,"line":776},[747,55515,12980],{"class":753},[747,55517,856],{"class":757},[747,55519,25773],{"class":802},[747,55521,55522,55524,55526],{"class":749,"line":784},[747,55523,13231],{"class":753},[747,55525,856],{"class":757},[747,55527,22408],{"class":802},[747,55529,55530,55532],{"class":749,"line":790},[747,55531,25378],{"class":753},[747,55533,758],{"class":757},[747,55535,55536,55538,55540],{"class":749,"line":796},[747,55537,25385],{"class":753},[747,55539,856],{"class":757},[747,55541,25796],{"class":802},[747,55543,55544,55546],{"class":749,"line":806},[747,55545,25801],{"class":753},[747,55547,758],{"class":757},[747,55549,55550,55552,55554,55556,55558],{"class":749,"line":814},[747,55551,26033],{"class":753},[747,55553,856],{"class":757},[747,55555,969],{"class":757},[747,55557,5306],{"class":802},[747,55559,975],{"class":757},[747,55561,55562,55564,55566,55568,55570],{"class":749,"line":822},[747,55563,26046],{"class":753},[747,55565,856],{"class":757},[747,55567,969],{"class":757},[747,55569,9530],{"class":802},[747,55571,975],{"class":757},[747,55573,55574,55576],{"class":749,"line":830},[747,55575,12990],{"class":753},[747,55577,758],{"class":757},[747,55579,55580,55582],{"class":749,"line":836},[747,55581,26065],{"class":753},[747,55583,758],{"class":757},[747,55585,55586,55588,55590],{"class":749,"line":842},[747,55587,1721],{"class":757},[747,55589,26074],{"class":753},[747,55591,758],{"class":757},[747,55593,55594,55596],{"class":749,"line":850},[747,55595,18665],{"class":757},[747,55597,26083],{"class":802},[747,55599,55600],{"class":749,"line":863},[747,55601,26088],{"class":772},[747,55603,55604],{"class":749,"line":869},[747,55605,26093],{"class":772},[747,55607,55608,55610,55612],{"class":749,"line":877},[747,55609,26098],{"class":753},[747,55611,856],{"class":757},[747,55613,26103],{"class":802},[747,55615,55616,55618],{"class":749,"line":1015},[747,55617,26108],{"class":753},[747,55619,758],{"class":757},[747,55621,55622,55624,55626,55628],{"class":749,"line":1021},[747,55623,1721],{"class":757},[747,55625,4591],{"class":753},[747,55627,856],{"class":757},[747,55629,26083],{"class":802},[747,55631,55632,55634],{"class":749,"line":1027},[747,55633,26125],{"class":753},[747,55635,758],{"class":757},[747,55637,55638,55640],{"class":749,"line":1033},[747,55639,26132],{"class":753},[747,55641,758],{"class":757},[747,55643,55644,55646,55648,55650],{"class":749,"line":1039},[747,55645,799],{"class":757},[747,55647,26141],{"class":753},[747,55649,856],{"class":757},[747,55651,26146],{"class":802},[747,55653,55654,55656],{"class":749,"line":1054},[747,55655,26151],{"class":753},[747,55657,758],{"class":757},[747,55659,55660,55662,55664],{"class":749,"line":1060},[747,55661,26158],{"class":753},[747,55663,856],{"class":757},[747,55665,25773],{"class":802},[747,55667,55668,55670,55672],{"class":749,"line":1066},[747,55669,26167],{"class":753},[747,55671,856],{"class":757},[747,55673,25586],{"class":1895},[523,55675,55676,25947,55678,26179,55681,26183,55683,8287,55685,587,55687,26190,55689,587,55691,26197],{},[567,55677,158],{},[527,55679,18226],{"href":18226,"rel":55680},[531],[567,55682,26182],{},[567,55684,25701],{},[567,55686,24007],{},[567,55688,24000],{},[567,55690,26193],{},[567,55692,26196],{},[6072,55694,55695],{},[523,55696,55697,55699,55700,12566,55704,55709],{},[584,55698,6189],{}," The deployment stage could be expanded to use the DNS providers API to create the domain name for you or the ",[527,55701,55703],{"href":26209,"rel":55702},[531],"external-dns operator",[527,55705,55708],{"href":55706,"rel":55707},"https:\u002F\u002Fgithub.com\u002Fkubernetes-incubator",[531],"Kubernetes incubator"," project could be used.",[523,55711,26215],{},[535,55713,26219],{"id":26218},[523,55715,26222,55716,26225],{},[567,55717,23716],{},[738,55719,55720],{"className":1621,"code":26228,"language":1623,"meta":743,"style":743},[567,55721,55722,55730,55740,55756],{"__ignoreMap":743},[747,55723,55724,55726,55728],{"class":749,"line":750},[747,55725,1919],{"class":1630},[747,55727,26237],{"class":802},[747,55729,26240],{"class":802},[747,55731,55732,55734,55736,55738],{"class":749,"line":761},[747,55733,1919],{"class":1630},[747,55735,22393],{"class":802},[747,55737,26249],{"class":802},[747,55739,26240],{"class":802},[747,55741,55742,55744,55746,55748,55750,55752,55754],{"class":749,"line":769},[747,55743,1919],{"class":1630},[747,55745,22393],{"class":802},[747,55747,26260],{"class":802},[747,55749,3368],{"class":802},[747,55751,3892],{"class":757},[747,55753,26267],{"class":802},[747,55755,975],{"class":757},[747,55757,55758,55760,55762],{"class":749,"line":776},[747,55759,1919],{"class":1630},[747,55761,22393],{"class":802},[747,55763,26278],{"class":802},[523,55765,26281],{},[523,55767,26284,55768,55770,55771,55774],{},[567,55769,23716],{},", with their jobs.\n",[3069,55772],{"alt":26292,"src":55773},"\u002Fblog\u002F2018\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature\u002Fgitlab-ci-pipelines-list.png",[3069,55775],{"alt":26298,"src":55776},"\u002Fblog\u002F2018\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature\u002Fgitlab-ci-commit-pipeline-running.png",[523,55778,55779,55780],{},"When you now go to the pipeline, you should see a view like this:\n",[3069,55781],{"alt":26307,"src":55782},"\u002Fblog\u002F2018\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature\u002Fgitlab-ci-pipeline-view.png",[523,55784,26311,55785,55787,55788],{},[567,55786,26314],{}," deploy looks like this:\n",[3069,55789],{"alt":26320,"src":55790},"\u002Fblog\u002F2018\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature\u002Fgitlab-ci-pipeline-deploy-review-successful.png",[523,55792,26324,55793,26327],{},[567,55794,23716],{},[535,55796,207],{"id":26330},[613,55798,26334],{"id":26333},[523,55800,26337],{},[613,55802,26341],{"id":26340},[668,55804,55805,55809],{},[638,55806,26346,55807,26349],{},[567,55808,23716],{},[638,55810,26352,55811,26355],{},[567,55812,55813],{},"{gitlab,s3,registry}.zerbytes.net",[613,55815,26359],{"id":26358},[668,55817,55818,55822],{},[638,55819,26352,55820,26355],{},[567,55821,55813],{},[638,55823,55824,55825,55827],{},"Is your Ingress (class) correctly setup in the ",[567,55826,158],{}," object\u002FKubernetes cluster?",[535,55829,14526],{"id":14525},[523,55831,26379],{},[523,55833,13967],{},[2890,55835,55836],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}",{"title":743,"searchDepth":761,"depth":761,"links":55838},[55839,55840,55843,55844,55845,55846,55847,55848,55849,55850,55851,55852,55857],{"id":53065,"depth":761,"text":53066},{"id":537,"depth":761,"text":538,"children":55841},[55842],{"id":22267,"depth":769,"text":22268},{"id":22332,"depth":761,"text":22333},{"id":22346,"depth":761,"text":22347},{"id":53240,"depth":761,"text":22308},{"id":23316,"depth":761,"text":23317},{"id":23562,"depth":761,"text":23563},{"id":23712,"depth":761,"text":26397},{"id":25160,"depth":761,"text":25161},{"id":25322,"depth":761,"text":25323},{"id":26218,"depth":761,"text":26219},{"id":26330,"depth":761,"text":207,"children":55853},[55854,55855,55856],{"id":26333,"depth":769,"text":26334},{"id":26340,"depth":769,"text":26341},{"id":26358,"depth":769,"text":26359},{"id":14525,"depth":761,"text":14526},"2018-06-17T12:35:42+02:00",{"src":26410},{"tags":55861},[26413,26414,124,26415],"\u002Fblog\u002F2018\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature",{"title":53057,"description":26408},"3.blog\u002F2018\u002Fgitlab-kubernetes-using-gitlab-cis-kubernetes-cluster-feature","iZGzl6Weeha1tFjMnG_x3sW0JM0na6sGD95bxhkduYY",{"id":55867,"title":55868,"authors":55869,"badge":518,"body":55872,"date":56086,"description":56087,"extension":2911,"image":56088,"meta":56089,"navigation":1254,"path":56092,"seo":56093,"stem":56094,"__hash__":56095},"posts\u002F3.blog\u002F2018\u002Fk8s-vagrant-multi-node-the-magic-behind-this-project.md","k8s-vagrant-multi-node: The magic behind this project",[55870],{"name":514,"to":515,"avatar":55871},{"src":517},{"type":520,"value":55873,"toc":56082},[55874,55880,55888,55890,55906,55910,55926,56035,56044,56047,56060,56077,56079],[523,55875,55876],{},[3069,55877],{"alt":55878,"src":55879},"Kubernetes and Hashicorp Vagrant Logo","\u002Fblog\u002Fcovers\u002Fkubernetes-vagrant-logo.png",[523,55881,55882,55883,1909],{},"The GitHub repository can be found here: ",[527,55884,55887],{"href":55885,"rel":55886},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fk8s-vagrant-multi-node",[531],"galexrt\u002Fk8s-vagrant-multi-node",[535,55889,538],{"id":537},[523,55891,55892,55893,45133,55896,55899,55900,587,55903,1909],{},"The Vagrant VirtualBox provider can't start VMs in parallel (",[567,55894,55895],{},"--parallel",[567,55897,55898],{},"vagrant up",").\nIt is possible to do so, but you need to \"invest\" in ",[567,55901,55902],{},"Vagrantfile",[567,55904,55905],{},"Makefile",[535,55907,55909],{"id":55908},"solution","Solution",[523,55911,55912,55913,55915,55916,26183,55919,55922,55923,55925],{},"Use ",[567,55914,55905],{}," to run ",[567,55917,55918],{},"NODE=X vagrant up",[567,55920,55921],{},"NODE=X"," is the \"number\" of the node you want to be started.\nTo tell ",[567,55924,55905],{}," to start these \"many\" targets you use a \"hack\" like this:",[738,55927,55929],{"className":1621,"code":55928,"language":1623,"meta":743,"style":743},"[...]\nnodes: $(shell for i in $(shell seq 1 $(NODE_COUNT)); do echo \"node-$$i\"; done)\n\nnode-%:\n    VAGRANT_VAGRANTFILE=Vagrantfile_nodes NODE=$* vagrant up\n[...]\n",[567,55930,55931,55939,55996,56000,56005,56027],{"__ignoreMap":743},[747,55932,55933,55935,55937],{"class":749,"line":750},[747,55934,4253],{"class":757},[747,55936,5685],{"class":1640},[747,55938,4268],{"class":757},[747,55940,55941,55944,55946,55949,55951,55954,55956,55958,55960,55963,55965,55967,55970,55973,55976,55978,55980,55983,55986,55988,55991,55994],{"class":749,"line":761},[747,55942,55943],{"class":1630},"nodes:",[747,55945,16279],{"class":757},[747,55947,55948],{"class":1630},"shell",[747,55950,3761],{"class":802},[747,55952,55953],{"class":802}," i",[747,55955,4584],{"class":802},[747,55957,16279],{"class":757},[747,55959,55948],{"class":1630},[747,55961,55962],{"class":802}," seq",[747,55964,3597],{"class":1895},[747,55966,16279],{"class":757},[747,55968,55969],{"class":1630},"NODE_COUNT",[747,55971,55972],{"class":757},"));",[747,55974,55975],{"class":19332}," do",[747,55977,23285],{"class":4574},[747,55979,969],{"class":757},[747,55981,55982],{"class":802},"node-$",[747,55984,55985],{"class":1640},"$i",[747,55987,3892],{"class":757},[747,55989,55990],{"class":757},";",[747,55992,55993],{"class":1640}," done",[747,55995,3600],{"class":757},[747,55997,55998],{"class":749,"line":769},[747,55999,1255],{"emptyLinePlaceholder":1254},[747,56001,56002],{"class":749,"line":776},[747,56003,56004],{"class":1630},"node-%:\n",[747,56006,56007,56010,56012,56015,56017,56019,56022,56025],{"class":749,"line":784},[747,56008,56009],{"class":1640},"    VAGRANT_VAGRANTFILE",[747,56011,6425],{"class":757},[747,56013,56014],{"class":802},"Vagrantfile_nodes",[747,56016,2254],{"class":1640},[747,56018,6425],{"class":757},[747,56020,56021],{"class":1640},"$* ",[747,56023,56024],{"class":1630},"vagrant",[747,56026,11281],{"class":802},[747,56028,56029,56031,56033],{"class":749,"line":790},[747,56030,4253],{"class":757},[747,56032,5685],{"class":1640},[747,56034,4268],{"class":757},[523,56036,56037,56038,56040,56041,1909],{},"Wanting to start ",[567,56039,30334],{}," VMs in parallel using this method would be done like this: ",[567,56042,56043],{},"make -j 10 nodes NODE_COUNT=10",[523,56045,56046],{},"Simple but powerful.",[6072,56048,56049],{},[523,56050,56051,56053,56054,56056,56057,56059],{},[584,56052,6189],{}," When you use this method with ",[567,56055,55905],{}," you can make a \"dependency\" tree using ",[567,56058,55905],{}," targets.\nInstead of relying on Vagrant.",[523,56061,56062,56063,587,56065,56067,56068,587,56070,56072,56073,56076],{},"For a full example ",[567,56064,55905],{},[567,56066,55902],{},", see the ",[567,56069,55905],{},[567,56071,56014],{}," files in the ",[527,56074,55887],{"href":55885,"rel":56075},[531]," project repository.",[523,56078,13967],{},[2890,56080,56081],{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":743,"searchDepth":761,"depth":761,"links":56083},[56084,56085],{"id":537,"depth":761,"text":538},{"id":55908,"depth":761,"text":55909},"2018-06-07T13:12:27+02:00","In this post I'm going to write about a project I started to speed up multi-node Kubernetes dev environments. I'm going to especially explain how to simple it can be to start VirtualBox VMs in parallel.",{"src":55879},{"tags":56090},[56091,124],"Vagrant","\u002Fblog\u002F2018\u002Fk8s-vagrant-multi-node-the-magic-behind-this-project",{"title":55868,"description":56087},"3.blog\u002F2018\u002Fk8s-vagrant-multi-node-the-magic-behind-this-project","XhOIXDmWFJ84mqWcciMM_khgWit1yt2ue5IqYkv0Ido",{"id":56097,"title":56098,"authors":56099,"badge":518,"body":56102,"date":56391,"description":56392,"extension":2911,"image":56393,"meta":56394,"navigation":1254,"path":56398,"seo":56399,"stem":56400,"__hash__":56401},"posts\u002F3.blog\u002F2018\u002Fmy-new-home-office-setup.md","My New Home Office Setup",[56100],{"name":514,"to":515,"avatar":56101},{"src":517},{"type":520,"value":56103,"toc":56376},[56104,56107,56111,56114,56117,56121,56125,56128,56145,56148,56157,56159,56162,56165,56184,56187,56191,56194,56197,56199,56210,56213,56246,56249,56251,56258,56264,56267,56269,56283,56285,56287,56322,56325,56327,56332,56334,56338,56347,56351,56354,56360,56366,56369,56371,56374],[523,56105,56106],{},"In this post I'm going over my new game and home office setup.",[535,56108,56110],{"id":56109},"new-table","New table",[523,56112,56113],{},"First part of the new home setup, was a new table.\nThe previous was a cheap table from IKEA. The new table is 2.60m long instead of previously only 2.00m.\nThe 0.60m more space is awesome. The desk feels emptier but in a good way, and I have more space for equipment.",[523,56115,56116],{},"If you have the space, go for a big table and keep it clean!",[535,56118,56120],{"id":56119},"tech-stuff","Tech stuff",[613,56122,56124],{"id":56123},"power-distribution","Power Distribution",[523,56126,56127],{},"The following power strips are used for power distribution:",[668,56129,56130,56138],{},[638,56131,56132,56133],{},"2x ",[527,56134,56137],{"href":56135,"rel":56136},"https:\u002F\u002Fwww.thomann.de\u002Fintl\u002Fadam_hall_874716_power_strip_1_u_19.htm",[531],"Adam Hall 874716 Power Strip 1 U 19\" - 16-port",[638,56139,56140,56141],{},"And some ",[527,56142,56144],{"href":14366,"rel":56143},[531],"the t.racks Power 8 S - 8-port",[523,56146,56147],{},"The 16-port power strips are pretyy neat and I can recommend them.\n(I'll soon \"mount\" them to the table so that the cables are off the ground)",[523,56149,56150,56151,56156],{},"End goal here would be to finally buy myself a fancy ",[527,56152,56155],{"href":56153,"rel":56154},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FUninterruptible_power_supply",[531],"Uninterruptible power supply",", just in case the apocalypse is happening :-D",[613,56158,12427],{"id":14262},[523,56160,56161],{},"I'm driving a dual WAN setup using a FritzBoxes and a OpenSense firewall router.",[523,56163,56164],{},"OpenSense firewall router box hardware specifications:",[668,56166,56167,56170,56172,56175,56177,56179,56182],{},[638,56168,56169],{},"CPU: Intel Celeron G4900",[638,56171,14487],{},[638,56173,56174],{},"RAM: Crucial Ballistix DDR4-2666 4GB",[638,56176,14493],{},[638,56178,14498],{},[638,56180,56181],{},"Sorage: Samsung 860 EVO 260GB SSD",[638,56183,14509],{},[523,56185,56186],{},"For network switches, I'm using two cheap 8-port Netgear Managed Switches which get the job done (they can VLAN so perfect with my OpenSense firewall router).",[613,56188,56190],{"id":56189},"automation","Automation",[523,56192,56193],{},"I have a few Raspberry Pis which power the video surveillance and security system, and take care of home automations, like turning on the lights in the morning and so on.",[523,56195,56196],{},"I can probably extend this, but I'm fine with what it does right now.",[613,56198,14018],{"id":14017},[6072,56200,56201,56207],{},[523,56202,56203,56204,56206],{},"The most important part of the calculation are the ",[29708,56205,14017],{}," calculators.",[523,56208,56209],{},"- Alexander Trost",[523,56211,56212],{},"I have two machines, one for gaming and one for working:",[668,56214,56215,56231],{},[638,56216,56217,56218],{},"Gaming\n",[668,56219,56220,56223,56225,56228],{},[638,56221,56222],{},"CPU: Intel(c) I7-7700k",[638,56224,14033],{},[638,56226,56227],{},"GPU: Nvidia GeForce GTX 970",[638,56229,56230],{},"Disk(s): 1x 500GB SATA SSD, 1x 3TB SATA HDD, 1x 4TB SATA HDD",[638,56232,56233,56234],{},"Workstation\n",[668,56235,56236,56239,56241,56243],{},[638,56237,56238],{},"CPU: AMD Ryzen 7 1800X",[638,56240,14071],{},[638,56242,14074],{},[638,56244,56245],{},"Disk(s): 1x 500GB NVMe SSD, 1x 500GB SATA SSD",[523,56247,56248],{},"Obviously the gaming computer can always need an upgrade but I am happy with it and the workstation.\nYou really notice the 8 cores and 16 threads of the AMD Ryzen when compiling code.",[613,56250,14106],{"id":14105},[523,56252,56253,56254,1909],{},"I'm currently using 4x LG 29UM68-P 29\" 21:9 UltraWide LED monitors, see ",[527,56255,56257],{"href":14114,"rel":56256},[531],"LG 29UM68-P 29\" product page",[523,56259,14127,56260,56263],{},[527,56261,14132],{"href":14130,"rel":56262},[531]," for their awesome and not too expensive* monitor stands!",[523,56265,56266],{},"(*In comparsion with around 4 other companies that sell and\u002F or buy monitor stands)",[523,56268,14136],{},[668,56270,56271,56276],{},[638,56272,14119,56273],{},[527,56274,14145],{"href":14143,"rel":56275},[531],[638,56277,56132,56278],{},[527,56279,56282],{"href":56280,"rel":56281},"https:\u002F\u002Fwww.ricoo.eu\u002Fen\u002Fricoo-desk-mount-monitor-ts3011-with-gas-spring-articulation-monitor-bracket-swivelling-tiltable-desk-monitor-stand-pedestal-flat-screen-pc-monitor-tft-display-swivel-arm-desk-led-lcd-desk-holder-brackets-universal-tv-vesa-75x75-100x100\u002Fa-10789\u002F",[531],"Ricoo Desk Monitor Mount Arm (TS3011)",[613,56284,14164],{"id":14163},[523,56286,14167],{},[668,56288,56289,56300,56305,56314],{},[638,56290,56291,56294,56295,2006],{},[527,56292,14195],{"href":14193,"rel":56293},[531]," (Temporarily switched out for ",[527,56296,56299],{"href":56297,"rel":56298},"https:\u002F\u002Fwww.thomann.de\u002Fgb\u002Fbehringer_xenyx_802.htm",[531],"Behringer 802 Xenyx",[638,56301,56302],{},[527,56303,14181],{"href":14179,"rel":56304},[531],[638,56306,56307,56310,56311,2006],{},[527,56308,14215],{"href":14213,"rel":56309},[531]," (The link is to the black edition, but I have the grey one. I got it cheap from ",[527,56312,14221],{"href":14219,"rel":56313},[531],[638,56315,56316,56321],{},[527,56317,56320],{"href":56318,"rel":56319},"https:\u002F\u002Fwww.rockshop.de\u002Fakai-mpx8",[531],"Akai MPX8"," (Just for the lolz as a soundboard style \"player\")",[523,56323,56324],{},"To \"blast\" music at the neighbors I have a very old 5.1 sound system, which sadly has a high level of noise by default. I'll probably replace it soon with a better sound system.",[613,56326,14228],{"id":14227},[523,56328,14231,56329,14237],{},[527,56330,14236],{"href":14234,"rel":56331},[531],[523,56333,14240],{},[535,56335,56337],{"id":56336},"finishing-touches","Finishing touches",[523,56339,56340,56341,56346],{},"To give the whole setup a nice touch, I have added ",[527,56342,56345],{"href":56343,"rel":56344},"https:\u002F\u002Fwww.amazon.de\u002FPhilips-LightStrip-erweiterbar-Millionen-kompatibel\u002Fdp\u002FB0148NMVQA",[531],"Philipps Hue LED Lightstrips"," to the back of the monitors. Though I still have to finally use the \"in-built\" glue of the light strips to put them on the back of the monitors.",[535,56348,56350],{"id":56349},"result","Result",[523,56352,56353],{},"The result is pretty rad!",[523,56355,56356],{},[3069,56357],{"alt":56358,"src":56359},"My New Home Setup - Rad Results!","\u002Fblog\u002F2018\u002Fmy-new-home-office-setup\u002Fhomeoffice-desktop-setup-shot-1.jpg",[523,56361,56362],{},[3069,56363],{"alt":56364,"src":56365},"My New Home Setup - With colored background lighting even better!","\u002Fblog\u002F2018\u002Fmy-new-home-office-setup\u002Fhomeoffice-desktop-setup-shot-2.jpg",[523,56367,56368],{},"(The LightStrip is hanging down as this was a picture during me gluing it to the monitors with the integrated glue strips)",[535,56370,14526],{"id":14525},[523,56372,56373],{},"That is my home office setup. It gets the job done and is a dream come true for me.\nI have more ideas to exapnd this setup, e.g., making cut outs for the mixer, but I have to see if I'm going that far.",[523,56375,13967],{},{"title":743,"searchDepth":761,"depth":761,"links":56377},[56378,56379,56388,56389,56390],{"id":56109,"depth":761,"text":56110},{"id":56119,"depth":761,"text":56120,"children":56380},[56381,56382,56383,56384,56385,56386,56387],{"id":56123,"depth":769,"text":56124},{"id":14262,"depth":769,"text":12427},{"id":56189,"depth":769,"text":56190},{"id":14017,"depth":769,"text":14018},{"id":14105,"depth":769,"text":14106},{"id":14163,"depth":769,"text":14164},{"id":14227,"depth":769,"text":14228},{"id":56336,"depth":761,"text":56337},{"id":56349,"depth":761,"text":56350},{"id":14525,"depth":761,"text":14526},"2018-06-05T13:47:13+02:00","In this post I'm showing you my new gaming and home office setup.",{"src":56359},{"tags":56395},[56396,14554,56397,14018],"Home","Setup","\u002Fblog\u002F2018\u002Fmy-new-home-office-setup",{"title":56098,"description":56392},"3.blog\u002F2018\u002Fmy-new-home-office-setup","hwNBepAz0MnvdLeih_i8rzrhYZRvileshTW6GpZbcO4",{"id":56403,"title":56404,"authors":56405,"badge":518,"body":56408,"date":57006,"description":57007,"extension":2911,"image":57008,"meta":57009,"navigation":1254,"path":57011,"seo":57012,"stem":57013,"__hash__":57014},"posts\u002F3.blog\u002F2018\u002Fkubecon-copenhagen-2018-day-3.md","KubeCon Copenhagen 2018 - Day 3",[56406],{"name":514,"to":515,"avatar":56407},{"src":517},{"type":520,"value":56409,"toc":56991},[56410,56412,56424,56440,56442,56454,56458,56462,56468,56474,56477,56480,56486,56489,56492,56495,56498,56504,56507,56513,56516,56519,56525,56528,56532,56538,56543,56549,56552,56556,56586,56597,56603,56613,56619,56624,56639,56643,56649,56652,56658,56661,56675,56681,56684,56687,56690,56701,56704,56707,56713,56716,56722,56726,56732,56739,56745,56751,56757,56768,56774,56781,56787,56790,56796,56800,56805,56811,56814,56825,56827,56831,56857,56859,56862,56865,56872,56876,56882,56905,56907,56910,56916,56919,56925,56930,56933,56936,56942,56945,56951,56957,56963,56966,56972,56978,56984,56986,56989],[2890,56411,52288],{},[6072,56413,56414,56419],{},[523,56415,56416,56418],{},[584,56417,6189],{}," All credit for the slides in the pictures goes to their creators!",[523,56420,56421,56423],{},[584,56422,6189],{}," If you are in one of these pictures and want it removed, please contact me by email (see about\u002Fimprint page).",[6072,56425,56426,56435],{},[523,56427,56428,56431,56432],{},[584,56429,56430],{},"WIP"," This post is still work in progress! The content of this post can rapidly change.\nThis note will be removed when the post has been completed.\n",[584,56433,56434],{},"TODO",[635,56436,56437],{},[638,56438,56439],{},"Proof read.",[535,56441,26431],{"id":26430},[523,56443,56444,56445,56449,56450,1909],{},"A warm \"Welcome\" if you are new to the three day post series from KubeCon Copenhagen, I recommend you to checkout the first day blog post too, here ",[527,56446,56448],{"href":56447},"\u002Fblog\u002F2018\u002FKubeCon-Copenhagen-2018-Day-1.md","KubeCon Copenhagen 2018 Day 1"," and the second day blog post, here ",[527,56451,56453],{"href":56452},"\u002Fblog\u002F2018\u002FKubeCon-Copenhagen-2018-Day-2.md","KubeCon Copenhagen 2018 Day 2",[535,56455,56457],{"id":56456},"morning-keynotes","Morning Keynotes",[613,56459,56461],{"id":56460},"keynote-kubeflow-ml-on-kubernetes-david-aronchick-product-manager-cloud-ai-and-co-founder-of-kubeflow-google-vishnu-kannan-sr-software-engineer-google","Keynote: Kubeflow ML on Kubernetes - David Aronchick, Product Manager, Cloud AI and Co-Founder of Kubeflow, Google & Vishnu Kannan, Sr. Software Engineer, Google",[523,56463,56464],{},[3069,56465],{"alt":56466,"src":56467},"KubeCon - Keynote - KubeCon Bingo","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_090657.jpg",[523,56469,56470],{},[3069,56471],{"alt":56472,"src":56473},"KubeCon - Keynote - Power effectiveness with AI","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_090844.jpg",[523,56475,56476],{},"Doing machine learning allowed Google to save up to 40% on their power bill.",[523,56478,56479],{},"Machine learning for cloud native, needs to be a) composable, b) Portability and c) Scalability.",[523,56481,56482],{},[3069,56483],{"alt":56484,"src":56485},"KubeCon - Keynote - Oh, you want to use ML on K8s?","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_091333.jpg",[523,56487,56488],{},"If you want to run ML on Kubernetes, you are gonna have a bad time, but not anymore thanks to KubeFlow.",[523,56490,56491],{},"It takes an expert for just ML, running it in Kubernetes is hard too, but KubeFlow can help.\nThey have released Kubeflow 0.1.\nIt is built so that you can customize it as you want.",[523,56493,56494],{},"Their demo showed an example of ML usage for finding the likeliness of reviews.",[523,56496,56497],{},"The \"normal\" way without ML just used predefined words to see how likely the review is to be either a recommendation, neutral or bad.",[523,56499,56500],{},[3069,56501],{"alt":56502,"src":56503},"KubeCon - Keynote - KubeFlow TensorBoard","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_092147.jpg",[523,56505,56506],{},"TensorBoard can be used to see some metrics about the metrics.",[523,56508,56509],{},[3069,56510],{"alt":56511,"src":56512},"KubeCon - Keynote - KubeFlow ML end result","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_092308.jpg",[523,56514,56515],{},"It is able to run on \"any\" K8S cloud.",[523,56517,56518],{},"A Swedish city had used data science to reduce injuries through new snowfall by optimizing the snowplow paths.",[523,56520,56521],{},[3069,56522],{"alt":56523,"src":56524},"KubeCon - Keynote - KubeFlow  - We're just getting started!","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_092657.jpg",[523,56526,56527],{},"Awesome, I will definitely try this out to get me started in ML.\nThe end goal is to make Kubernetes to number one platform for ML.",[613,56529,56531],{"id":56530},"keynote-running-with-scissors-liz-rice-technology-evangelist-aqua-security","Keynote: Running with Scissors - Liz Rice, Technology Evangelist, Aqua Security",[523,56533,56534],{},[3069,56535],{"alt":56536,"src":56537},"KubeCon - Keynote - Running with Scissors Title","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_092956.jpg",[6072,56539,56540],{},[523,56541,56542],{},"\"You might carry the scissors for miles before you cut yourself\"\n- Liz Rice",[523,56544,56545],{},[3069,56546],{"alt":56547,"src":56548},"KubeCon - Keynote - Container Isolation - View from Host","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_093323.jpg",[523,56550,56551],{},"Linux container isolation is mostly done through capabilities.\nA container run through Kubernetes (mostly likely also Docker) drops most \"bad\" capabilities\u002Fisn't even granted the capabilities on start.",[523,56553,56554,856],{},[567,56555,1505],{},[668,56557,56558,56564,56580],{},[638,56559,56560,56563],{},[567,56561,56562],{},"privileged: true"," gives all privileges.",[638,56565,56566,56569,56570,6353,56573,56576,56577,56579],{},[567,56567,56568],{},"runAsNonRoot"," option sets the container to run the image as non root. Though the image needs to have ",[567,56571,56572],{},"USER 1000",[567,56574,56575],{},"1000"," isn't ",[567,56578,3579],{}," aka root) to be able to run otherwise Kubernetes will not be able to run.",[638,56581,56582,56585],{},[567,56583,56584],{},"runAsUser"," force container process to be started as user ID (same exists for supplemental groups).",[523,56587,56588,56589,56591,56592,1909],{},"For more information see the ",[567,56590,1505],{}," documentation: ",[527,56593,56596],{"href":56594,"rel":56595},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Ftasks\u002Fconfigure-pod-container\u002Fsecurity-context\u002F",[531],"Kubernetes.io Documentation - Pod SecurityContext",[523,56598,56599],{},[3069,56600],{"alt":56601,"src":56602},"KubeCon - Keynote - Security with USER in Dockerfile","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_094113.jpg",[523,56604,56605,56609,56610,56612],{},[3069,56606],{"alt":56607,"src":56608},"KubeCon - Keynote - Host can't remove root file created by root container as non root","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_094344.jpg","\nOne can potentially use a volume mount of the pod to access files from hosts and because the UID is ",[567,56611,3579],{}," aka root, everything can be done.",[523,56614,56615],{},[3069,56616],{"alt":56617,"src":56618},"KubeCon - Keynote - Stop running with scissors","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_094636.jpg",[6072,56620,56621],{},[523,56622,56623],{},"\"We need to prevent us from running with scissors\"\n- Liz Rice",[635,56625,56626,56633,56636],{},[638,56627,56628,56629,56632],{},"Change applications Dockerfiles and add ",[567,56630,56631],{},"USER __YOUR_ID__"," line.",[638,56634,56635],{},"Use tools like from Aqua Security.",[638,56637,56638],{},"Use PodSecurityPolicies.",[613,56640,56642],{"id":56641},"keynote-scaling-deep-learning-models-in-production-using-kubernetes-sahil-dua-software-developer-bookingcom","Keynote: Scaling Deep Learning Models in Production Using Kubernetes - Sahil Dua, Software Developer, Booking.com",[523,56644,56645],{},[3069,56646],{"alt":56647,"src":56648},"KubeCon - Keynote - Booking.com Scaling Highlights","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_095039.jpg",[523,56650,56651],{},"They run Deep Learning at huge scale.",[523,56653,56654],{},[3069,56655],{"alt":56656,"src":56657},"KubeCon - Keynote - Scaling Deep Learning Models in Production Using Kubernetes Title","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_095032.jpg",[523,56659,56660],{},"They use it for:",[668,56662,56663,56666,56669,56672],{},[638,56664,56665],{},"Image Tagging",[638,56667,56668],{},"Translations",[638,56670,56671],{},"Advertisement bidding",[638,56673,56674],{},"And more..",[523,56676,56677],{},[3069,56678],{"alt":56679,"src":56680},"KubeCon - Keynote - Booking.com Image Tagging","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_095350.jpg",[523,56682,56683],{},"Once they have the tags on the images the user is able to better search for certain factors of a hotel\u002Froom.",[523,56685,56686],{},"The workload for deep learning is immmensive. From 10 to 100s of GBs to sometimes even terrabytes of data to go through.",[523,56688,56689],{},"They choose Kubernetes because of the:",[668,56691,56692,56695,56698],{},[638,56693,56694],{},"Isolation",[638,56696,56697],{},"Elasticity",[638,56699,56700],{},"Flexibility",[523,56702,56703],{},"They don't put training data into the images. This removes the need to always repull the image.\nThey simply use Hadoop or PVs to access\u002Fmount the training data.",[523,56705,56706],{},"I recommend to checkout the recording as he made a nice graphical visualization on their setup.",[523,56708,56709],{},[3069,56710],{"alt":56711,"src":56712},"KubeCon - Keynote - Booking.com Serving ML Predictions 1","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_100114.jpg",[523,56714,56715],{},"They use common code (possibly a library) which contains access instructions to the model(s). To that they containerize the application, but without the model in it.\nThe model is loaded in memory \"on demand\" from Hadoop storage and then it begins to serve the predictions.",[523,56717,56718],{},[3069,56719],{"alt":56720,"src":56721},"KubeCon - Keynote - Booking.com Serving ML Predictions 2","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_100355.jpg",[613,56723,56725],{"id":56724},"keynote-crossing-the-river-by-feeling-the-stones-simon-wardley-researcher-leading-edge-forum","Keynote: Crossing the River by Feeling the Stones - Simon Wardley, Researcher, Leading Edge Forum",[523,56727,56728],{},[3069,56729],{"alt":56730,"src":56731},"KubeCon - Keynote - Crossing the River by Feeling the Stones - Title","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_100931.jpg",[523,56733,56734,56738],{},[3069,56735],{"alt":56736,"src":56737},"KubeCon - Keynote - Crossing the River by Feeling the Stones - Common Blahs","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_101057.jpg","\n(blah, blah, blah)",[523,56740,56741],{},[3069,56742],{"alt":56743,"src":56744},"KubeCon - Keynote - Crossing the River by Feeling the Stones - Blah Template","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_101133.jpg",[523,56746,56747],{},[3069,56748],{"alt":56749,"src":56750},"KubeCon - Keynote - Crossing the River by Feeling the Stones - Auto generate strategies","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_101136.jpg",[523,56752,56753],{},[3069,56754],{"alt":56755,"src":56756},"KubeCon - Keynote - Crossing the River by Feeling the Stones - Three main feedback points for his autogenerated strategies","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_101242.jpg",[523,56758,56759,56763],{},[3069,56760],{"alt":56761,"src":56762},"KubeCon - Keynote - Crossing the River by Feeling the Stones - Automatic Strategy Generator Online","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_101252.jpg",[527,56764,56767],{"href":56765,"rel":56766},"http:\u002F\u002Fstrategy-madlibs.herokuapp.com",[531],"Automatic Strategy Generator Online",[523,56769,56770],{},[3069,56771],{"alt":56772,"src":56773},"KubeCon - Keynote - Crossing the River by Feeling the Stones - Four fields","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_101657.jpg",[523,56775,56776,56780],{},[3069,56777],{"alt":56778,"src":56779},"KubeCon - Keynote - Crossing the River by Feeling the Stones - 'The End of cloud is neigh ...'","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_102829_1.jpg","\n'The End of cloud is neigh ...'",[523,56782,56783],{},[3069,56784],{"alt":56785,"src":56786},"KubeCon - Keynote - Crossing the River by Feeling the Stones - Circle of purpose and movement","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_103047.jpg",[523,56788,56789],{},"This was the funniest keynote, you have to checkout the recording of it if you weren't there.",[523,56791,56792],{},[3069,56793],{"alt":56794,"src":56795},"KubeCon - Keynote - Crossing the River by Feeling the Stones - Deng Xiaoping Quote","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_103051.jpg",[613,56797,56799],{"id":56798},"keynote-closing-remarks-kelsey-hightower-kubernetes-community-member-google-liz-rice-technology-evangelist-aqua-security","Keynote: Closing Remarks – Kelsey Hightower, Kubernetes Community Member, Google & Liz Rice, Technology Evangelist, Aqua Security",[6072,56801,56802],{},[523,56803,56804],{},"\"You feel the AC?\"\n- Kelsey Hightower",[523,56806,56807],{},[3069,56808],{"alt":56809,"src":56810},"KubeCon - Keynote - Closing Remarks - Upcoming conferences","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_103242.jpg",[523,56812,56813],{},"The upcoming CloudNativeCon and KubeCon will be at:",[668,56815,56816,56819,56822],{},[638,56817,56818],{},"Shanghai, China: November 14-15. 2018",[638,56820,56821],{},"Seattle, North America: December 11-13. 2018",[638,56823,56824],{},"Barcelona, Europe: May 21-23. 2019",[535,56826,51330],{"id":51329},[613,56828,56830],{"id":56829},"rook-deep-dive-bassam-tabbara-tony-allen-jared-watts-upbound-intermediate-skill-level","Rook Deep Dive – Bassam Tabbara, Tony Allen & Jared Watts, Upbound (Intermediate Skill Level)",[6072,56832,56834,56852,56853],{"className":56833,"dataLang":18973},[18972,52946],[523,56835,56836,56837,56839,56840,56844,56845,56847,56848],{"lang":18973,"dir":18976},"full room for the ",[527,56838,52953],{"href":52952},"  deep dive.  actually 2 deep dives, one for developers and one for administrators. great job ",[527,56841,56843],{"href":56842},"https:\u002F\u002Ftwitter.com\u002Ftonya11en?ref_src=twsrc%5Etfw","@tonya11en","  and ",[527,56846,18988],{"href":18987},"! ",[527,56849,56851],{"href":56850},"https:\u002F\u002Ft.co\u002FLqszC4Qzdl","pic.twitter.com\u002FLqszC4Qzdl","— Jared Watts (@jbw976) ",[527,56854,56856],{"href":56855},"https:\u002F\u002Ftwitter.com\u002Fjbw976\u002Fstatus\u002F992412121538465792?ref_src=twsrc%5Etfw","May 4, 2018",[19016,56858],{"async":1254,"src":19018,"charSet":19019},[523,56860,56861],{},"First of all thanks for coming to the talk!\nA big thanks also goes out to Jared and Tony that I could talk about the administrative side of Rook. I really enjoyed helping with the slides.",[523,56863,56864],{},"I hope everyone liked the talk. If you have feedback about the talk, get in touch with Jared, Tony or me.",[523,56866,56867,56868,1909],{},"Be sure to follow Jared's Twitter ",[527,56869,56871],{"href":52301,"rel":56870},[531],"@jbw976",[613,56873,56875],{"id":56874},"kubernetes-runs-anywhere-but-does-your-data-jared-watts-upbound-beginner-skill-level","Kubernetes Runs Anywhere, but Does your Data? - Jared Watts, Upbound (Beginner Skill Level)",[523,56877,56878],{},[3069,56879],{"alt":56880,"src":56881},"KubeCon - Talk - Kubernetes Runs Anywhere, but Does your Data? Title","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_144545.jpg",[6072,56883,56885,56901,56902],{"className":56884,"dataLang":18973},[18972,52946],[523,56886,56887,56890,56891,8287,56895,8287,56897],{"lang":18973,"dir":18976},[527,56888,56871],{"href":56889},"https:\u002F\u002Ftwitter.com\u002Fjbw976?ref_src=twsrc%5Etfw"," fills the auditorium talking about portability of stateful workloads across clouds? ",[527,56892,56894],{"href":56893},"https:\u002F\u002Ftwitter.com\u002Fhashtag\u002Fkubecon?src=hash&ref_src=twsrc%5Etfw","#kubecon",[527,56896,52953],{"href":52952},[527,56898,56900],{"href":56899},"https:\u002F\u002Ft.co\u002FbmqkmVaBbS","pic.twitter.com\u002FbmqkmVaBbS","— bassam (@bassamtabbara) ",[527,56903,56856],{"href":56904},"https:\u002F\u002Ftwitter.com\u002Fbassamtabbara\u002Fstatus\u002F992385488500772864?ref_src=twsrc%5Etfw",[19016,56906],{"async":1254,"src":19018,"charSet":19019},[523,56908,56909],{},"Kubernetes runs anywhere (even on a robot vacuum cleaner).\nThe power of Kubernetes is also Portability.",[523,56911,56912],{},[3069,56913],{"alt":56914,"src":56915},"KubeCon - Talk - Kubernetes Runs Anywhere, but Does your Data? - How does Kubernetes do it?","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_144900.jpg",[523,56917,56918],{},"There are abstractions for running applications in Kubernetse but also already for Storage in general.\nStorage abstraction is available through PersistentVolumes, PersistentVolumeClaims and more.",[523,56920,56921],{},[3069,56922],{"alt":56923,"src":56924},"KubeCon - Talk - Kubernetes Runs Anywhere, but Does your Data? - Where Storage Falls Short","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_145357.jpg",[523,56926,56927],{},[3069,56928],{"alt":56923,"src":56929},"\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_145458.jpg",[523,56931,56932],{},"The provisioning is still more in the background than consuming storage.\nThis will change with ContainerStorageInterface (CSI).",[523,56934,56935],{},"To be able to run stateful applications anywhere you need a portable storage solutions.\nCRDs can be used to create abstractions.",[523,56937,56938],{},[3069,56939],{"alt":56940,"src":56941},"KubeCon - Talk - Kubernetes Runs Anywhere, but Does your Data? - Operator's Control Loop","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_150229.jpg",[523,56943,56944],{},"On the first day you deploy, on the second you support it (Day 2 operations).",[523,56946,56947],{},[3069,56948],{"alt":56949,"src":56950},"KubeCon - Talk - Kubernetes Runs Anywhere, but Does your Data? - Kubernetes API and Clientsets","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_150457.jpg",[523,56952,56953],{},[3069,56954],{"alt":56955,"src":56956},"KubeCon - Talk - Kubernetes Runs Anywhere, but Does your Data? - Event Triggers","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_150734.jpg",[523,56958,56959],{},[3069,56960],{"alt":56961,"src":56962},"KubeCon - Talk - Kubernetes Runs Anywhere, but Does your Data? - Demo Deployments spawned by a controller through a CRD 1","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_151151.jpg",[523,56964,56965],{},"The new WIP CockroachDB and Minio operator were show cased next to the Ceph one.",[523,56967,56968],{},[3069,56969],{"alt":56970,"src":56971},"KubeCon - Talk - Kubernetes Runs Anywhere, but Does your Data? - Demo Deployments spawned by a controller through a CRD 2","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_151152.jpg",[523,56973,56974],{},[3069,56975],{"alt":56976,"src":56977},"KubeCon - Talk - Kubernetes Runs Anywhere, but Does your Data? - Demo Deployments spawned by a controller through a CRD 3","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_151153.jpg",[523,56979,56980],{},[3069,56981],{"alt":56982,"src":56983},"KubeCon - Talk - Kubernetes Runs Anywhere, but Does your Data? - Questions?","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3\u002Fimg_20180504_151613.jpg",[535,56985,14526],{"id":14525},[523,56987,56988],{},"As always KubeCon was awesome. I met amazing people, had very interesting talks and found new contacts.",[523,56990,13967],{},{"title":743,"searchDepth":761,"depth":761,"links":56992},[56993,56994,57001,57005],{"id":26430,"depth":761,"text":26431},{"id":56456,"depth":761,"text":56457,"children":56995},[56996,56997,56998,56999,57000],{"id":56460,"depth":769,"text":56461},{"id":56530,"depth":769,"text":56531},{"id":56641,"depth":769,"text":56642},{"id":56724,"depth":769,"text":56725},{"id":56798,"depth":769,"text":56799},{"id":51329,"depth":761,"text":51330,"children":57002},[57003,57004],{"id":56829,"depth":769,"text":56830},{"id":56874,"depth":769,"text":56875},{"id":14525,"depth":761,"text":14526},"2018-05-04T08:16:15+02:00","Talks, keynotes, thoughts and pictures from the KubeCon Copenhagen 2018 Day 3.",{"src":56537},{"tags":57010},[13976,52359,26415,12175,124],"\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-3",{"title":56404,"description":57007},"3.blog\u002F2018\u002Fkubecon-copenhagen-2018-day-3","BuOkuspqxS3PvNUQMxhr0k-sCBnVoBKMV5A4o7ro7fQ",{"id":57016,"title":57017,"authors":57018,"badge":518,"body":57021,"date":57561,"description":57562,"extension":2911,"image":57563,"meta":57564,"navigation":1254,"path":57566,"seo":57567,"stem":57568,"__hash__":57569},"posts\u002F3.blog\u002F2018\u002Fkubecon-copenhagen-2018-day-2.md","KubeCon Copenhagen 2018 - Day 2",[57019],{"name":514,"to":515,"avatar":57020},{"src":517},{"type":520,"value":57022,"toc":57543},[57023,57025,57044,57046,57050,57052,57056,57063,57066,57076,57078,57084,57093,57099,57102,57108,57111,57117,57126,57128,57134,57137,57141,57154,57158,57161,57167,57170,57176,57179,57183,57189,57192,57198,57201,57207,57210,57215,57218,57223,57226,57232,57235,57240,57245,57248,57254,57257,57263,57273,57277,57283,57286,57293,57296,57299,57310,57314,57317,57321,57323,57327,57347,57349,57352,57354,57358,57361,57365,57368,57374,57380,57383,57387,57393,57403,57407,57413,57420,57425,57427,57430,57436,57439,57442,57445,57451,57455,57461,57466,57469,57472,57477,57483,57488,57491,57497,57500,57503,57506,57510,57517,57534,57536,57538,57541],[2890,57024,52288],{},[6072,57026,57027,57031,57033,57037,57039],{},[523,57028,57029],{},[584,57030,6189],{},[523,57032,51254],{},[523,57034,57035],{},[584,57036,6189],{},[523,57038,51261],{},[523,57040,57041,57043],{},[584,57042,56430],{}," This post is still work in progress! The content of this post can rapidly change.\nThis note will be removed when the post has been completed.",[535,57045,26431],{"id":26430},[523,57047,56444,57048,1909],{},[527,57049,56448],{"href":56447},[535,57051,56457],{"id":56456},[613,57053,57055],{"id":57054},"keynote-kubernetes-project-update-aparna-sinha-group-product-manager-kubernetes-and-google-kubernetes-engine-google","Keynote: Kubernetes Project Update - Aparna Sinha, Group Product Manager, Kubernetes and Google Kubernetes Engine, Google",[523,57057,57058,57062],{},[3069,57059],{"alt":57060,"src":57061},"KubeCon - Keynote - Kubernetes Major Milestones","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_090849.jpg","\nKubernetes Major Milestones",[523,57064,57065],{},"The following points are currently especially important for enterprises:",[635,57067,57068,57070,57073],{},[638,57069,11645],{},[638,57071,57072],{},"Applications",[638,57074,57075],{},"Experience",[3126,57077,11645],{"id":11644},[523,57079,57080],{},[3069,57081],{"alt":57082,"src":57083},"KubeCon - Keynote - Kubernetes Security Progress","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_091152.jpg",[523,57085,57086,57087,57092],{},"On GKE they made updates seamless.\n\"Old\" points are awaking for Kubernetes like Threat detection.\nGKE integrates with a good amount of security\u002Ftreat detections to make the platform safer.\nUpcoming from SIG container is sandboxed containers. To get a \"full\" sandboxed container, you should use a hypervisor. Still the users want the low resource point of (normal) containers.\nGoogle has open sourced ",[527,57088,57091],{"href":57089,"rel":57090},"https:\u002F\u002Fgithub.com\u002Fgoogle\u002Fgvisor",[531],"gVisor"," which is a sandboxed container runtime.",[523,57094,57095],{},[3069,57096],{"alt":57097,"src":57098},"KubeCon - Keynote - Sandboxed containers","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_091557.jpg",[3126,57100,57072],{"id":57101},"applications",[523,57103,57104],{},[3069,57105],{"alt":57106,"src":57107},"KubeCon - Keynote - Kubernetes Applications Progress","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_091823.jpg",[523,57109,57110],{},"Kubernetes has now an integration to be the scheduler for Apache Spark.\nTo automate stateful applications, it is recommended to use an operator.",[523,57112,57113],{},[3069,57114],{"alt":57115,"src":57116},"KubeCon - Keynote - Automating stateful applications","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_091934.jpg",[523,57118,57119,57120,57125],{},"In the demo Google's ",[527,57121,57124],{"href":57122,"rel":57123},"https:\u002F\u002Fgithub.com\u002FGoogleCloudPlatform\u002Fspark-on-k8s-operator",[531],"spark-operator"," was showcased.\nI recommend to checkout the recording, to see exactly what she showed.",[3142,57127,176],{"id":26553},[523,57129,57130],{},[3069,57131],{"alt":57132,"src":57133},"KubeCon - Keynote - Kubernetes Monitoring","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_092435.jpg",[523,57135,57136],{},"Prometheus is the default monitoring\u002Fmetrics pipeline in Kubernetes.",[3142,57138,57140],{"id":57139},"developer-experience","Developer Experience",[523,57142,57143,57144,57149,57150,57153],{},"A Google Customer engineer developed ",[527,57145,57148],{"href":57146,"rel":57147},"https:\u002F\u002Fgithub.com\u002FGoogleContainerTools\u002Fskaffold",[531],"Skaffold"," which improves the developer experience for continuous integration + deployment.\nIn the end the developer just wants to \"run his code\".\nThe important part is that the developer can focus on the development.\n",[527,57151,57148],{"href":57146,"rel":57152},[531]," will pick up changes and automatically deploy it to Kubernetes (from what I think, especially for testing).",[613,57155,57157],{"id":57156},"keynote-accelerating-kubernetes-native-applications-brandon-philips-cto-of-coreos-red-hat","Keynote: Accelerating Kubernetes Native Applications - Brandon Philips, CTO of CoreOS, Red Hat",[523,57159,57160],{},"The point of operators making it easy to deploy and manage applications is more and more important.",[523,57162,57163],{},[3069,57164],{"alt":57165,"src":57166},"KubeCon - Keynote - Operators: Kube Native Apps","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_093229.jpg",[523,57168,57169],{},"It is amazing to hear a success story such as that for an operator, as you normally just hear \"it works\" ;)",[523,57171,57172],{},[3069,57173],{"alt":57174,"src":57175},"KubeCon - Keynote - The Operator Framework","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_093315.jpg",[523,57177,57178],{},"They will release more components of the operator framework over the coming weeks.\nBut a point coming with with having more and more operators running is that you need a lifecycle management for operators in general.\nA lifecycle management in that point could be like a catalog of operators.",[613,57180,57182],{"id":57181},"keynote-switching-horses-midstream-the-challenges-of-migrating-150-microservices-to-kubernetes-sarah-wells-technical-director-for-operations-and-reliability-financial-times","Keynote: Switching Horses Midstream: The Challenges of Migrating 150+ Microservices to Kubernetes - Sarah Wells, Technical Director for Operations and Reliability, Financial Times",[523,57184,57185],{},[3069,57186],{"alt":57187,"src":57188},"KubeCon - Keynote - This is what it really looks like","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_093852.jpg",[523,57190,57191],{},"If you are doing a thing such as \"live\" migration, it is as with every project a journey.",[523,57193,57194],{},[3069,57195],{"alt":57196,"src":57197},"KubeCon - Keynote - Metrics for success","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_094325.jpg",[523,57199,57200],{},"Their setup is very complex as they went completely for microservice architecture already.\nThey see innovation like a spending (innovation token).\nIn the end they reached a cost reduction in AWS of about ~80%.",[523,57202,57203],{},[3069,57204],{"alt":57205,"src":57206},"KubeCon - Keynote - Opted for Kubernetes","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_094326.jpg",[523,57208,57209],{},"They opted for Kubernetes, so they can ask other people about it as opposed to creating their own orchestration tool. With an own tool, you on your own need to know the documentation.",[6072,57211,57212],{},[523,57213,57214],{},"\"You pay a cost when running services in parallel\"\n- Sarah Wells",[523,57216,57217],{},"It is always a risk, but risks are to be conquered if the advantages overweight the disadvantages.\nThey used traffic replay to test further and simply use their existing API to push to both stacks to test.",[6072,57219,57220],{},[523,57221,57222],{},"\"Switching from systemd files to Helm\"\n- Sarah Wells",[523,57224,57225],{},"If you don't use Golang vendoring, you're gonna have a bad time when rebuilding a two year old project.",[523,57227,57228],{},[3069,57229],{"alt":57230,"src":57231},"KubeCon - Keynote - Shouldn't be too scared quote","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_094455.jpg",[523,57233,57234],{},"In their case they had a good amount of services already having a readiness and\u002For liveness \"interface\".",[6072,57236,57237],{},[523,57238,57239],{},"\"Easy to get sucked into making things better\"\n- Sarah Wells",[6072,57241,57242],{},[523,57243,57244],{},"\"It is worth mentioning the increase in bills to the people that pay the bills\"\n- Sarah Wells",[523,57246,57247],{},"The final migration went smooth for them mostly only issues arose because people used the platform in a way they didn't understand.",[523,57249,57250],{},[3069,57251],{"alt":57252,"src":57253},"KubeCon - Keynote - Healthcheck timeouts","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_095106.jpg",[523,57255,57256],{},"They broke even in about three years after their migration.",[523,57258,57259],{},[3069,57260],{"alt":57261,"src":57262},"KubeCon - Keynote - Reduction in hosting and support costs","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_095600.jpg",[6072,57264,57265],{},[523,57266,3892,57267,57269,57270,57272],{},[747,57268,5685],{},"a happier team",[747,57271,5685],{},"\"\n- Sarah Wells",[613,57274,57276],{"id":57275},"keynote-shaping-the-cloud-native-future-abby-kearns-executive-director-cloud-foundry-foundation","Keynote: Shaping the Cloud Native Future - Abby Kearns, Executive Director, Cloud Foundry Foundation",[523,57278,57279],{},[3069,57280],{"alt":57281,"src":57282},"KubeCon - Keynote - Cloud Cobbling","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_100114.jpg",[523,57284,57285],{},"Everything is \"cobbling\" together a way for themselves to the cloud.",[523,57287,57288,57292],{},[3069,57289],{"alt":57290,"src":57291},"KubeCon - Keynote - Trinity of Interoperability, Innovation and Velocity","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_100118.jpg","\nTrinity of Interoperability, Innovation and Velocity",[523,57294,57295],{},"A companies world increases with each software\u002Ftechnology they use.",[523,57297,57298],{},"TBH this is kind of the same as everyone is saying:",[668,57300,57301,57304,57307],{},[638,57302,57303],{},"OpenSource is cool",[638,57305,57306],{},"We have to get together (conferences, meetups, etc)",[638,57308,57309],{},"And so on..",[613,57311,57313],{"id":57312},"keynote-skip-the-anxiety-attack-build-secure-apps-with-kubernetes-jason-mcgee-fellow-ibm","Keynote: Skip the Anxiety Attack - Build Secure Apps with Kubernetes, Jason McGee, Fellow, IBM",[523,57315,57316],{},"I wasn't at the keynote because I had checked out the CNCF booth for the \"Meet the Maintainer - Rook\" meetup.",[613,57318,57320],{"id":57319},"keynote-softwares-community-dave-zolotusky-software-engineer-spotify","Keynote: Software's Community - Dave Zolotusky, Software Engineer, Spotify",[523,57322,57316],{},[535,57324,57326],{"id":57325},"meet-the-maintainer-rook","Meet the Maintainer - Rook",[6072,57328,57330,57342,57343],{"className":57329,"dataLang":18973},[18972,52946],[523,57331,57332,57333,57335,57336,8287,57338],{"lang":18973,"dir":18976},"Hostile takeover of the ",[527,57334,52958],{"href":52957}," booth in progress ",[527,57337,56894],{"href":56893},[527,57339,57341],{"href":57340},"https:\u002F\u002Ft.co\u002FB034FWvOgk","pic.twitter.com\u002FB034FWvOgk","— rook (@rook_io) ",[527,57344,57346],{"href":57345},"https:\u002F\u002Ftwitter.com\u002Frook_io\u002Fstatus\u002F991969884056768513?ref_src=twsrc%5Etfw","May 3, 2018",[19016,57348],{"async":1254,"src":19018,"charSet":19019},[523,57350,57351],{},"It was nice meeting people interested in Rook.",[535,57353,51330],{"id":51329},[613,57355,57357],{"id":57356},"blackholes-and-wormholes-understand-and-troubleshoot-the-magic-of-kubernetes-networking-minhan-xia-rohit-ramkumar-google-intermediate-skill-level","Blackholes and Wormholes: Understand and Troubleshoot the “Magic” of Kubernetes Networking - Minhan Xia & Rohit Ramkumar, Google (Intermediate Skill Level)",[523,57359,57360],{},"Both talkers are \"the last line of defense\" for support cases.",[3126,57362,57364],{"id":57363},"blackhole-case","Blackhole Case",[523,57366,57367],{},"No backend receives a packet sent by another Pod after a endpoint change.",[523,57369,57370],{},[3069,57371],{"alt":57372,"src":57373},"KubeCon - Talk - Blackholes and Wormholes: Understand and Troubleshoot the “Magic” of Kubernetes Networking - Conntrack in a nutshell","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_140349.jpg",[523,57375,57376],{},[3069,57377],{"alt":57378,"src":57379},"KubeCon - Talk - Blackholes and Wormholes: Understand and Troubleshoot the “Magic” of Kubernetes Networking - Netfilter in a nutshell","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_140452.jpg",[523,57381,57382],{},"In this case, when the Service IP is called a conntrack entry is created when routed to Pod A. When a Pod is killed and the conntrack entries still exist, the traffic fails to get to the other Pods because of this.\nA fix for this has been implemented in kube-proxy. Kube-proxy flushes the conntrack table of stale entries now, though there might be a small delay\u002Floss for then incoming packets until \"everything\" has been refreshed.",[3126,57384,57386],{"id":57385},"yet-another-blackhole-case","Yet Another Blackhole Case",[523,57388,57389],{},[3069,57390],{"alt":57391,"src":57392},"KubeCon - Talk - Blackholes and Wormholes: Understand and Troubleshoot the “Magic” of Kubernetes Networking - Blackhole #2 - Explained","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_141040.jpg",[523,57394,57395,57396,57399,57400,57402],{},"This was caused due to OOM causing networkd to be restarted which then triggered a bug that reset the ",[567,57397,57398],{},"forwarding"," sysctl setting for the main ethernet interface to ",[567,57401,3579],{}," causing no more traffic to be forwarded to the container network bridge.",[3126,57404,57406],{"id":57405},"wormhole","Wormhole",[523,57408,57409],{},[3069,57410],{"alt":57411,"src":57412},"KubeCon - Talk - Blackholes and Wormholes: Understand and Troubleshoot the “Magic” of Kubernetes Networking - Wormhole Set up","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_141239.jpg",[523,57414,57415,57416,57419],{},"Because of Pod B on a node which exposes a ",[567,57417,57418],{},"hostPort"," that is the same as the Pod A, that is why the traffic is wormholed to Pod B.",[6072,57421,57422],{},[523,57423,57424],{},"\"Iptables should be as explicit as possible.\"\n- Minhan Xia & Rohit Ramkumar",[3126,57426,207],{"id":26330},[523,57428,57429],{},"Iptables is the first source of truth.",[523,57431,57432],{},[3069,57433],{"alt":57434,"src":57435},"KubeCon - Talk - Blackholes and Wormholes: Understand and Troubleshoot the “Magic” of Kubernetes Networking - What's in my iptables?","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_141832.jpg",[523,57437,57438],{},"Each endpoint has it's own chain.",[523,57440,57441],{},"conntrack is also an important to see where the connection got \"tracked\" to.",[523,57443,57444],{},"tcpdump should be used to verify that a request\u002Fdata was actually sent from a Pod and\u002For received on another node.",[523,57446,57447],{},[3069,57448],{"alt":57449,"src":57450},"KubeCon - Talk - Blackholes and Wormholes: Understand and Troubleshoot the “Magic” of Kubernetes Networking - Conclusion","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_142456.jpg",[613,57452,57454],{"id":57453},"clusters-as-cattle-how-to-seamlessly-migrate-apps-across-kubernetes-clusters-andy-goldstein-heptio-intermediate-skill-level","Clusters as Cattle: How to Seamlessly Migrate Apps across Kubernetes Clusters - Andy Goldstein, Heptio (Intermediate Skill Level)",[523,57456,57457],{},[3069,57458],{"alt":57459,"src":57460},"KubeCon - Talk - Clusters as Cattle: How to Seamlessly Migrate Apps across Kubernetes Clusters - Title","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_163243.jpg",[6072,57462,57463],{},[523,57464,57465],{},"\"Tickets\nApprovals\nDelays\"\n- Andy Goldstein",[523,57467,57468],{},"Your server is your pet, when it is broken you want to fix it as fast as possible.",[523,57470,57471],{},"Kubernetes does the scheduling.",[6072,57473,57474],{},[523,57475,57476],{},"\"Is a cluster a cattle or a pet?\"\n- Andy Goldstein",[523,57478,57479],{},[3069,57480],{"alt":57481,"src":57482},"KubeCon - Talk - Clusters as Cattle: How to Seamlessly Migrate Apps across Kubernetes Clusters - K8s App Migrations","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_164429.jpg",[6072,57484,57485],{},[523,57486,57487],{},"\"At one point every node will be decomissioned\"\n- Andy Goldstein",[523,57489,57490],{},"Overall in Kubernetes yout should not use IPs for Services. DNS names should be used instead.",[523,57492,57493],{},[3069,57494],{"alt":57495,"src":57496},"KubeCon - Talk - Clusters as Cattle: How to Seamlessly Migrate Apps across Kubernetes Clusters - Routing Overview","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_165004.jpg",[523,57498,57499],{},"When migrating one could potentially use a setup such as this and use a separate Kubernetes cluster to do the routing of the internet traffic.",[523,57501,57502],{},"His demo showed the whole setup he explained.\nHe showcased the migration point from one to another cluster. This can potentially be also used for failover.\nAdditionally to that heptio\u002Fark's backup and restore was demonstrated with that.",[523,57504,57505],{},"Interesting to see the switch functionality between the clusters with a simple config change.",[535,57507,57509],{"id":57508},"all-attendee-party","All Attendee Party",[523,57511,57512,57516],{},[3069,57513],{"alt":57514,"src":57515},"KubeCon - All Attendee Party - So many people!","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2\u002Fimg_20180503_184245.jpg","\nSo many people!",[6072,57518,57520,56901,57531],{"className":57519,"dataLang":18973},[18972,52946],[523,57521,8764,57522,57524,57525,8287,57527],{"lang":18973,"dir":18976},[527,57523,52958],{"href":52957}," has stepped up their game. This event rocks! A new normal for ",[527,57526,56894],{"href":56893},[527,57528,57530],{"href":57529},"https:\u002F\u002Ft.co\u002FhprNrJnK5V","pic.twitter.com\u002FhprNrJnK5V",[527,57532,57346],{"href":57533},"https:\u002F\u002Ftwitter.com\u002Fbassamtabbara\u002Fstatus\u002F992092821631877120?ref_src=twsrc%5Etfw",[19016,57535],{"async":1254,"src":19018,"charSet":19019},[535,57537,14526],{"id":14525},[523,57539,57540],{},"The all attendee party was awesome! Looking forward to the next KubeCon all attendee party already.",[523,57542,13967],{},{"title":743,"searchDepth":761,"depth":761,"links":57544},[57545,57546,57554,57555,57559,57560],{"id":26430,"depth":761,"text":26431},{"id":56456,"depth":761,"text":56457,"children":57547},[57548,57549,57550,57551,57552,57553],{"id":57054,"depth":769,"text":57055},{"id":57156,"depth":769,"text":57157},{"id":57181,"depth":769,"text":57182},{"id":57275,"depth":769,"text":57276},{"id":57312,"depth":769,"text":57313},{"id":57319,"depth":769,"text":57320},{"id":57325,"depth":761,"text":57326},{"id":51329,"depth":761,"text":51330,"children":57556},[57557,57558],{"id":57356,"depth":769,"text":57357},{"id":57453,"depth":769,"text":57454},{"id":57508,"depth":761,"text":57509},{"id":14525,"depth":761,"text":14526},"2018-05-03T08:30:27+02:00","Talks, keynotes, thoughts and pictures from the KubeCon Copenhagen 2018 Day 2.",{"src":57061},{"tags":57565},[13976,52359,26415,12175,124],"\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-2",{"title":57017,"description":57562},"3.blog\u002F2018\u002Fkubecon-copenhagen-2018-day-2","jNamrhcZEuVFOlA-2qIa8JTYcGYoCHRHaPSnjGcBme4",{"id":57571,"title":57572,"authors":57573,"badge":518,"body":57576,"date":58330,"description":58331,"extension":2911,"image":58332,"meta":58333,"navigation":1254,"path":58335,"seo":58336,"stem":58337,"__hash__":58338},"posts\u002F3.blog\u002F2018\u002Fkubecon-copenhagen-2018-day-1.md","KubeCon Copenhagen 2018 - Day 1",[57574],{"name":514,"to":515,"avatar":57575},{"src":517},{"type":520,"value":57577,"toc":58305},[57578,57580,57598,57600,57603,57605,57609,57615,57621,57624,57630,57637,57642,57645,57653,57659,57668,57672,57675,57679,57686,57707,57714,57721,57725,57767,57774,57777,57784,57791,57794,57798,57801,57805,57812,57816,57819,57824,57828,57831,57838,57845,57852,57855,57859,57865,57871,57874,57880,57883,57886,57892,57895,57901,57907,57915,57919,57922,57928,57933,57936,57940,57946,57949,57954,57960,57965,57968,57971,57977,57980,57986,57991,57994,58000,58003,58009,58014,58022,58024,58028,58031,58041,58044,58047,58050,58053,58061,58064,58067,58070,58076,58080,58083,58086,58092,58095,58098,58104,58110,58113,58116,58119,58125,58128,58133,58136,58142,58148,58152,58156,58163,58167,58173,58177,58183,58187,58193,58197,58200,58206,58209,58212,58217,58220,58225,58228,58231,58234,58239,58242,58246,58251,58256,58261,58268,58275,58279,58284,58289,58291,58294,58300,58303],[2890,57579,52288],{},[6072,57581,57582,57586,57588,57592,57594],{},[523,57583,57584],{},[584,57585,6189],{},[523,57587,51254],{},[523,57589,57590],{},[584,57591,6189],{},[523,57593,51261],{},[523,57595,57596,57043],{},[584,57597,56430],{},[535,57599,26431],{"id":26430},[523,57601,57602],{},"A big welcome to everyone at KubeCon!\nI'm happy to have already met a good amount of Rooklers just during badge pickup.",[535,57604,56457],{"id":56456},[613,57606,57608],{"id":57607},"keynote-how-good-is-our-code-dan-kohn-executive-director-cloud-native-computing-foundation","Keynote: How Good Is Our Code? - Dan Kohn, Executive Director, Cloud Native Computing Foundation",[523,57610,57611],{},[3069,57612],{"alt":57613,"src":57614},"KubeCon - Keynote - How Good Is Our Code? - KubeCon Attendees","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_090721.jpg",[523,57616,57617],{},[3069,57618],{"alt":57619,"src":57620},"KubeCon - Keynote - How Good Is Our Code? - CNCF is a critical part","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_090724.jpg",[523,57622,57623],{},"SQLite is a good example for test coverage, because they have 100% coverage. But even though they have a test coverage of 100%, bugs have been found with a \"magic\" genetic bug finder program.\nBugs in such a case are hopefully just caused by usages that the developers hasn't thought about and because of that has not tested for.",[523,57625,57626],{},[3069,57627],{"alt":57628,"src":57629},"KubeCon: Tweet about code quality","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_091220.jpg",[523,57631,57632,57636],{},[3069,57633],{"alt":57634,"src":57635},"KubeCon: SLOCs for the cloud trail map application and stack","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_091534.jpg","\n(SLOCs are lines of code)",[6072,57638,57639],{},[523,57640,57641],{},"\"A patch doesn't help until it is deployed to production\" (Continous Integration)\n- Dan Kohn",[523,57643,57644],{},"CI should run multiple types of tests, smoke, integration, unit.\nAs Kelsey Hightwoer wrote in a tweet, if you don't have CI for your application, Kubernetes is your smallest problem.",[523,57646,57647,57648,57652],{},"A cloud native trail map is available at the CNCF sponsor showcase booth or online at ",[527,57649,57651],{"href":52607,"rel":57650},[531],"l.cncf.io",".\nYour adventure though should first lead to containers of your applications, because containerized CI is easier to do.",[523,57654,57655],{},[3069,57656],{"alt":57657,"src":57658},"KubeCon - Keynote - Kelsey Hightower is showin of nocode repository","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_092644.jpg",[523,57660,57661,57662,57667],{},"Kelsey Hightwoer showed his ",[527,57663,57666],{"href":57664,"rel":57665},"https:\u002F\u002Fgithub.com\u002Fkelseyhightwoer\u002Fnocode",[531],"GitHub kelseyhightwoer\u002Fnocode"," \"tutorial\". It was hilarious, definitely checkout the keynote recording for that.",[613,57669,57671],{"id":57670},"keynote-cncf-project-update-liz-rice-technology-evangelist-aqua-security-sugu-sougoumarane-cto-planetscale-data-colin-sullivan-product-manager-synadia-communications-inc-andrew-jessup-co-founder-scytale-inc","Keynote: CNCF Project Update - Liz Rice, Technology Evangelist, Aqua Security; Sugu Sougoumarane, CTO, PlanetScale Data; Colin Sullivan, Product Manager, Synadia Communications, Inc. & Andrew Jessup, Co-founder Scytale Inc.",[523,57673,57674],{},"Currently there is a total of 20 projects in the CNCF.",[3126,57676,57678],{"id":57677},"sandbox-projects","Sandbox projects",[523,57680,57681,57685],{},[3069,57682],{"alt":57683,"src":57684},"KubeCon - Keynote - Rook was showed as one of the sandbox projects","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_092918.jpg","\n(FTW! I'm totatlly not biased;))",[668,57687,57688,57693,57699],{},[638,57689,57690],{},[527,57691,465],{"href":13751,"rel":57692},[531],[638,57694,57695],{},[527,57696,57698],{"href":12896,"rel":57697},[531],"Open Policy Agent",[638,57700,57701,57706],{},[527,57702,57705],{"href":57703,"rel":57704},"https:\u002F\u002Fspiffe.io\u002F",[531],"SPIFFE & SPIRE"," - Tries to solve the problem of trust between workloads. Looks interesting to clear up the authentication\u002Ftrust issues currently broadly existing.",[523,57708,57709,57713],{},[3069,57710],{"alt":57711,"src":57712},"KubeCon - Keynote - In a multi cloud world, who is establishing the trust?","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_093118.jpg","\nIn a multi cloud world, who is establishing the trust?",[523,57715,57716,57720],{},[3069,57717],{"alt":57718,"src":57719},"KubeCon - Keynote - SPIFFE & SPIRE can be a solution to improve the situation","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_093446.jpg","\nSPIFFE & SPIRE can be a solution to improve the situation",[3126,57722,57724],{"id":57723},"incubation-projects","Incubation projects",[668,57726,57727,57730,57732,57735,57737,57740,57743,57746,57749,57752,57755,57758,57761,57764],{},[638,57728,57729],{},"coreDNS",[638,57731,28027],{},[638,57733,57734],{},"Envoy",[638,57736,292],{},[638,57738,57739],{},"OpenTracing (Updated APIs and libraries for a total of 9 languages)",[638,57741,57742],{},"Jaeger",[638,57744,57745],{},"Fluentd",[638,57747,57748],{},"NATS - Already has some CNCF Projects integration, like Prometheus",[638,57750,57751],{},"Container Network Interface (CNI)",[638,57753,57754],{},"GRPC",[638,57756,57757],{},"containerd (v1.1 Support for Kubernetes CRI)",[638,57759,57760],{},"TUF (Secure framework for software updates)",[638,57762,57763],{},"Notary (based on TUF, for secure software distribution)",[638,57765,57766],{},"Vitess (database orchestration for MySQL horizontal scaling, takes away the pain of sharding in the application)",[523,57768,57769,57773],{},[3069,57770],{"alt":57771,"src":57772},"KubeCon - Keynote - NATS feature list","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_094316.jpg","\nNATS feature list",[523,57775,57776],{},"Vitess showed an interesting demo:",[523,57778,57779,57783],{},[3069,57780],{"alt":57781,"src":57782},"KubeCon - Keynote - Grafana dashboard showing the Vitess Gateway QPS and other metrics","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_095500.jpg","\nGrafana dashboard showing the Vitess Gateway QPS and other metrics",[523,57785,57786,57790],{},[3069,57787],{"alt":57788,"src":57789},"KubeCon - Keynote - Vitess webinterface before telling Vitess to use the shards","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_095507.jpg","\nVitess webinterface before telling Vitess to use the shards",[523,57792,57793],{},"It is easy and awesome looking! They have a simple to use cli tool to execute tasks, but it seems that everything is managed through Kubernetes.",[3126,57795,57797],{"id":57796},"graduated-projects","Graduated Projects",[523,57799,57800],{},"Kubernetes is the first project that has graduated.",[3126,57802,57804],{"id":57803},"what-is-graduation","What is graduation?",[523,57806,57807,57811],{},[3069,57808],{"alt":57809,"src":57810},"KubeCon - Keynote - Graduation 'graph'","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_095905.jpg","\nGraduation 'graph'",[3126,57813,57815],{"id":57814},"getting-involved-into-cncf-projects","Getting involved into CNCF projects",[523,57817,57818],{},"Track sessions about \"nuts and bolts\" of projects\u002Fimplementations-\nIntros & Deep Dives of the Projects, Kubernetes SIG and CNCF working groups.\nHallway Track to meet people in the hallway to find out about others problems and solutions.",[523,57820,57821],{},[584,57822,57823],{},"You are the community!",[613,57825,57827],{"id":57826},"keynote-re-thinking-networking-for-microservices-lew-tucker-vpcto-cloud-computing-cisco-systems-inc","Keynote: Re-thinking Networking for Microservices - Lew Tucker, VP\u002FCTO Cloud Computing, Cisco Systems, Inc.",[523,57829,57830],{},"Cisco has created \"Cisco Container Platform\".",[523,57832,57833,57837],{},[3069,57834],{"alt":57835,"src":57836},"KubeCon - Keynote - Shift in how apps are built","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_100711.jpg","\nThere is a shift in how apps are built.",[523,57839,57840,57844],{},[3069,57841],{"alt":57842,"src":57843},"KubeCon - Keynote - 'Services should be simple but get complicated fast'","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_100823.jpg","\n'Services should be simple but get complicated fast'",[523,57846,57847,57851],{},[3069,57848],{"alt":57849,"src":57850},"KubeCon - Keynote - Handing-off certain tasks to a service mesh","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_100857.jpg","\nHanding-off certain tasks to a service mesh.",[523,57853,57854],{},"Using a service mesh allows to not modify the service's code to get it more \"secure\".",[613,57856,57858],{"id":57857},"keynote-cern-experiences-with-multi-cloud-federated-kubernetes-ricardo-rocha-staff-member-cern-clenimar-filemon-software-engineer-federal-university-of-campina-grande","Keynote: CERN Experiences with Multi-Cloud Federated Kubernetes - Ricardo Rocha, Staff Member, CERN & Clenimar Filemon, Software Engineer, Federal University of Campina Grande",[523,57860,57861],{},[3069,57862],{"alt":57863,"src":57864},"KubeCon - Keynote - CERN map of LHCb","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_101328.jpg",[523,57866,57867],{},[3069,57868],{"alt":57869,"src":57870},"KubeCon - Keynote - How much data is collected at CERN LHCb","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_101706.jpg",[523,57872,57873],{},"They have a lot of data up to 1PB\u002Fsec, but it is filtered and in the end it can be about 1-10GB\u002Fs.\nOver 200 Kubernetes are already running, from small to large clusters.",[523,57875,57876],{},[3069,57877],{"alt":57878,"src":57879},"KubeCon - Keynote - Numbers about Compute power at CERN","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_101910.jpg",[523,57881,57882],{},"Their numbers are extremely high in comparison to some big companies.",[523,57884,57885],{},"Their motivation for Federation is the uniform API for deployments, load balancing and much more.\nIt is especially good for their use cases with batch jobs, done with HTCondur. HTCondur allows for good scheduling by taking fair share and preemption into account. But HTCondur needs external storage and networking.\nThey have containerized the whole thing and use the Kubernetes Federation on \"all\" of their clusters dedicated to HTCondur.",[523,57887,57888],{},[3069,57889],{"alt":57890,"src":57891},"KubeCon - Keynote - Distributed computing","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_102000.jpg",[523,57893,57894],{},"Through the federation new nodes can be added to any cluster at any time, and through a DaemonSet automatically pick up the work especially for a tool such as HTCondur which uses a node agent for it's own node registration.",[523,57896,57897],{},[3069,57898],{"alt":57899,"src":57900},"KubeCon - Keynote - Setup with Startd and Kubernetes Federation use","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_102611.jpg",[523,57902,57903],{},[3069,57904],{"alt":57905,"src":57906},"KubeCon - Keynote - Workflow visualization for their distributed computing tasks","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_103048.jpg",[523,57908,57909,57910,1909],{},"Their demo showed how to run complex jobs on multiple Kubernetes clusters with federation.\nFor the visualization program, it can probably found here: ",[527,57911,57914],{"href":57912,"rel":57913},"https:\u002F\u002Fgithub.com\u002Frecast-hep",[531],"GitHub recast-hep",[613,57916,57918],{"id":57917},"keynote-from-innovation-to-production-dirk-hohndel-vp-chief-open-source-officer-vmware","Keynote: From Innovation to Production - Dirk Hohndel, VP & Chief Open Source Officer, VMware",[523,57920,57921],{},"They created a product using open source.",[523,57923,57924],{},[3069,57925],{"alt":57926,"src":57927},"KubeCon - Keynote - VMWare Open Source Office Hours during KubeCon","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_103600.jpg",[6072,57929,57930],{},[523,57931,57932],{},"\"Innovation is done by individuals\"\n- Dirk Hohndel",[523,57934,57935],{},"It is time to invest in minorities in the IT field. Opportunities need to be created for them.",[613,57937,57939],{"id":57938},"keynote-cncf-20-20-vision-alexis-richardson-founder-ceo-weaveworks","Keynote: CNCF 20-20 Vision - Alexis Richardson, Founder & CEO, Weaveworks",[523,57941,57942],{},[3069,57943],{"alt":57944,"src":57945},"KubeCon - Keynote - Alexis Richardson on stage","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_104011.jpg",[523,57947,57948],{},"CNCF until now was kind of in a \"start up\" phase as a company. Which now more and more moves to getting \"Acceptance\".",[6072,57950,57951],{},[523,57952,57953],{},"\"We are not a start up any more\"\n- Alexis Richardson",[523,57955,57956],{},[3069,57957],{"alt":57958,"src":57959},"KubeCon - Keynote - Why a platform?","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_104339_1.jpg",[6072,57961,57962],{},[523,57963,57964],{},"\"For a lot of people 'cloud native' is just 'cloud'\"\n- Alexis Richardson",[523,57966,57967],{},"Today it is pretty easy to install a project such as Hadoop for data analysis or TensorFlow for machine learning with KubeFlow in Kubernetes.",[523,57969,57970],{},"Deploying faster allows for a higher velocity of applications\u002Fproducts (lower Time To Market).",[523,57972,57973],{},[3069,57974],{"alt":57975,"src":57976},"KubeCon - Keynote - '2018: We have KubeFloW'","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_104717.jpg",[523,57978,57979],{},"Everybody can do this faster and faster with CNCF projects.",[523,57981,57982],{},[3069,57983],{"alt":57984,"src":57985},"KubeCon - Keynote - High Velocity","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_104454.jpg",[6072,57987,57988],{},[523,57989,57990],{},"\"Just run my code\"\n- Alexis Richardson",[523,57992,57993],{},"It shouldn't be run my applicatiom\u002Fcontainer anymore, it should just be as simple as git pushing the code and automatically pushed out to your platform, e.g. Kubernetes.",[523,57995,57996],{},[3069,57997],{"alt":57998,"src":57999},"KubeCon - Keynote - The key pieces we need","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_104830.jpg",[523,58001,58002],{},"Code centric by using git as the central point for the code and as the trigger for CI + CD.",[523,58004,58005],{},[3069,58006],{"alt":58007,"src":58008},"KubeCon - Keynote - New ways of working","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_105338.jpg",[6072,58010,58011],{},[523,58012,58013],{},"\"What is missing? The developers.\"",[523,58015,58016,58017,58021],{},"Ethics are more and more important with the greater tools which given even greater power.\n",[3069,58018],{"alt":58019,"src":58020},"KubeCon - Keynote - Ethics are more important than ever","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_105559.jpg","\nEthics are more important than ever (looking at you Zuckerberg).",[535,58023,51330],{"id":51329},[613,58025,58027],{"id":58026},"replacing-nginx-with-envoy-in-a-traffic-control-system-mark-mcbride-turbine-labs-inc-advanced-skill-level","Replacing NGINX with Envoy in a Traffic Control System - Mark McBride, Turbine Labs, Inc (Advanced Skill Level)",[523,58029,58030],{},"A point for Envoy is that it is more made for a cloud native environment that changes fast.",[523,58032,58033,58034,587,58037,58040],{},"NGINX does not have a great amount of routing options besides ",[567,58035,58036],{},"location",[567,58038,58039],{},"redirect",". The routing in Envoy can be more dynamic, it is more made to route on facts besides the URI and\u002For server name which NGINX is mostly used for. It can possibly route on \"fact\" is this QA or Live? Which application version?\nEnvoy has taken notice of the already pretty good reload functionality and does it more dynamically.",[523,58042,58043],{},"Together with the overall dynamic in the routing, it is much more sophisticated than NGINX.\nStill to keep in mind, most software has good reason to co-exist beside each other depending on the task it should suffice in.",[523,58045,58046],{},"A good amount of big companies are maintainers on the project. To that over 50% of commits were made by people outside those companies.",[523,58048,58049],{},"Envoy is not reaching the current benchmarks looking at NGINX (and other webservers), but Envoy gives you more dynamic for a little bit less performance.\nA company has to look into the features, like filtering, of Envoy and the trade off, less performance, in comparison to the other existing solutions.",[523,58051,58052],{},"Migrations need to have enough people knowing what is going on and how to roll it back in case of failure.\nTo that a list of points that need to watched out for during the rollout (e.g. latencies) should be made and a list of tasks to be done for the actual \"piece by piece\" rollout.",[6072,58054,58055],{},[523,58056,58057,58058,58060],{},"\"Know when to roll back",[747,58059,5685],{},"\"\n- Mark McBride",[523,58062,58063],{},"Health checks from their perspective are only good for \"Yes, I'm listening on that port\u002Faccepting requests\" and not is the application \"working\" (e.g. successfully processing requests\u002Fdata).",[523,58065,58066],{},"They are looking into open sourcing applications that can speed up own migrations.",[523,58068,58069],{},"I'd recommend to checkout the recording of the talk as there is a good amount of Envoy stuff and overall how one would roll this out explained.",[523,58071,58072],{},[3069,58073],{"alt":58074,"src":58075},"KubeCon: Replacing NGINX with Envoy in a Traffic Control System - Thank You","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_143426.jpg",[613,58077,58079],{"id":58078},"rook-project-intro-bassam-tabbara-tony-allen-jared-watts-upbound-any-skill-level","Rook Project Intro – Bassam Tabbara, Tony Allen & Jared Watts, Upbound (Any Skill Level)",[523,58081,58082],{},"Rook takes the load of managing storage backends in Kubernetes of your shoulders.",[523,58084,58085],{},"It solves the limitations of each cloud providers having it's own storage aka vendor locking with the cloud.\nRook runs the storage ON the Kubernetes cluster which allows stateful workload to be moved more consistently between different clouds because the storage configuration stays the same.\nWith the storage configuration staying the same on each cloud, Rook has created a working abstraction between different clouds.",[523,58087,58088],{},[3069,58089],{"alt":58090,"src":58091},"KubeCon: Rook Project Intro","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_162516.jpg",[523,58093,58094],{},"With the upcoming support for CockroachDB and Minio, this will even further move to decouple certain applications from each cloud providers.",[523,58096,58097],{},"Rook uses the same patterns as for example CoreOS's etcd-operator or their prometheus-operator.\nRook goes beyond that with managing\u002Foperating each storage \"backend\" to a certain aspect to as written take the load of the shoulders of the user.",[523,58099,58100],{},[3069,58101],{"alt":58102,"src":58103},"KubeCon: Storage ON Kubernetes","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_162919.jpg",[523,58105,58106],{},[3069,58107],{"alt":58108,"src":58109},"KubeCon: Rook Architecture","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_163713.jpg",[523,58111,58112],{},"In point of managing\u002Foperating, the Rook operator makes sure the cluster is healthy and also provisions the storage for the storage.",[523,58114,58115],{},"Rook tries to be more of a framework for storage solutions, next to Ceph there will be as mentioned soon be support for CockroachDB, Minio, Nexenta Storage and more.\nIt allows current storage providers to simply integrate with Rook and let it do the \"dirty\" work. This is good as some storage providers can with that \"move\" the workload to the community to implement and possibly add best practices to health checks.",[523,58117,58118],{},"In the demo he went through the quickstart guide and showed an example with WordPress which used block storage.",[523,58120,58121],{},[3069,58122],{"alt":58123,"src":58124},"KubeCon: Rook Demo WordPress and MySQL example","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_164538.jpg",[523,58126,58127],{},"The cluster is now ready to be used after maybe 20-45 seconds.",[523,58129,58130],{},[3069,58131],{"alt":58123,"src":58132},"\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_165002.jpg",[523,58134,58135],{},"Killing the MySQL pod didn't cause issues, because Kubernetes brought a new one and Rook agent made sure that it is only used after the other one is terminated (fencing).",[523,58137,58138,58139,1909],{},"That is it for the intro, if you want to know more checkout ",[527,58140,14601],{"href":32338,"rel":58141},[531],[523,58143,58144],{},[3069,58145],{"alt":58146,"src":58147},"KubeCon: Rook Project Intro - 'Questions?'","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_165943.jpg",[535,58149,58151],{"id":58150},"evening-keynotes","Evening Keynotes",[613,58153,58155],{"id":58154},"keynote-anatomy-of-a-production-kubernetes-outage-oliver-beattie-head-of-engineering-monzo-bank","Keynote: Anatomy of a Production Kubernetes Outage - Oliver Beattie, Head of Engineering, Monzo Bank",[6072,58157,58158],{},[523,58159,58160,58162],{},[584,58161,6189],{}," I have not been to this keynotes. Just listing it here for completeness.",[613,58164,58166],{"id":58165},"keynote-container-native-dev-and-ops-experience-its-getting-easier-fast-ralph-squillace-principal-pm-azure-container-platform-microsoft","Keynote: Container-Native Dev-and-ops Experience: It's Getting Easier, Fast. - Ralph Squillace, Principal PM – Azure Container Platform, Microsoft",[6072,58168,58169],{},[523,58170,58171,58162],{},[584,58172,6189],{},[613,58174,58176],{"id":58175},"keynote-cloud-native-observability-security-from-google-cloud-craig-box-staff-developer-advocate-google","Keynote: Cloud Native Observability & Security from Google Cloud - Craig Box, Staff Developer Advocate, Google",[6072,58178,58179],{},[523,58180,58181,58162],{},[584,58182,6189],{},[613,58184,58186],{"id":58185},"keynote-cncf-end-user-awards-presented-by-chris-aniszczyk-coo-cloud-native-computing-foundation","Keynote: CNCF End User Awards - Presented by Chris Aniszczyk, COO, Cloud Native Computing Foundation",[6072,58188,58189],{},[523,58190,58191,58162],{},[584,58192,6189],{},[613,58194,58196],{"id":58195},"keynote-prometheus-20-the-next-scale-of-cloud-native-monitoring-fabian-reinartz-software-engineer-google","Keynote: Prometheus 2.0 – The Next Scale of Cloud Native Monitoring - Fabian Reinartz, Software Engineer, Google",[523,58198,58199],{},"They have more than 15000 stars on GitHub.\nThe first version was cut in March 2014, later on in January 2015 Prometheus was publicly announced.",[523,58201,58202],{},[3069,58203],{"alt":58204,"src":58205},"KubeCon - Keynote - ","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_180204.jpg",[523,58207,58208],{},"For the Prometheus 2.0, they created a new TSDB engine for it as others wouldn't perform fast enough.\n\"Can persist 1.000.000+ samples\u002Fcore\u002Fsec to disk\"",[523,58210,58211],{},"After they optimized the TSDB, they noticed that all load was going outside the DB, especially the scrapping part of Prometheus.",[523,58213,58214],{},[3069,58215],{"alt":58204,"src":58216},"\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_180548.jpg",[523,58218,58219],{},"With Prometheus 1.0 you would need to wait for weeks to see if the resources you gave it is enough.",[523,58221,58222],{},[3069,58223],{"alt":58204,"src":58224},"\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_180740.jpg",[523,58226,58227],{},"With Prometheus 2 they also massively increased the query latency which was getting more and more with Prometheus 1.",[523,58229,58230],{},"Staleness has also been improved in Prometheus 2. These improvements made the alerting more agile due to the faster triggering of \"missing\" data.",[523,58232,58233],{},"They want to stay engaged with OpenMetrics.",[523,58235,58236],{},[3069,58237],{"alt":58204,"src":58238},"\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_181256.jpg",[523,58240,58241],{},"There is a book available \"Prometheus Up & Running\" and free for the next 30 days for KubeCon goers.",[613,58243,58245],{"id":58244},"keynote-serverless-not-so-faas-kelsey-hightower-kubernetes-community-member-google","Keynote: Serverless, Not So FaaS - Kelsey Hightower, Kubernetes Community Member, Google",[6072,58247,58248],{},[523,58249,58250],{},"\"That's where I come in and steal your servers\"\n- Kelsey Hightwoer",[523,58252,58253],{},[3069,58254],{"alt":58204,"src":58255},"\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_181734.jpg",[6072,58257,58258],{},[523,58259,58260],{},"\"Don't standardize all events. The envelope is enough\"\n- Kelsey Hightower",[523,58262,58263,58264,1909],{},"A standardized event envelope can be found ",[527,58265,3396],{"href":58266,"rel":58267},"https:\u002F\u002Fcloudevents.io",[531],[523,58269,58270],{},[527,58271,58274],{"href":58272,"rel":58273},"https:\u002F\u002Fserverless.com",[531],"Serverless Event Gateway",[613,58276,58278],{"id":58277},"keynote-closing-remarks-liz-rice-technology-evangelist-aqua-security","Keynote: Closing Remarks - Liz Rice, Technology Evangelist, Aqua Security",[523,58280,58281],{},[3069,58282],{"alt":58204,"src":58283},"\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_183114.jpg",[6072,58285,58286],{},[523,58287,58288],{},"\"Just follow the smell of sponsors\"\n- Liz Rice",[535,58290,14526],{"id":14525},[523,58292,58293],{},"Thanks for the beer CNCF and KubeCon!",[523,58295,58296],{},[3069,58297],{"alt":58298,"src":58299},"KubeCon: Summary - Beer","\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1\u002Fimg_20180502_185215.jpg",[523,58301,58302],{},"It was nice meeting a lot of new people and people from Rook Slack in person.",[523,58304,13967],{},{"title":743,"searchDepth":761,"depth":761,"links":58306},[58307,58308,58316,58320,58329],{"id":26430,"depth":761,"text":26431},{"id":56456,"depth":761,"text":56457,"children":58309},[58310,58311,58312,58313,58314,58315],{"id":57607,"depth":769,"text":57608},{"id":57670,"depth":769,"text":57671},{"id":57826,"depth":769,"text":57827},{"id":57857,"depth":769,"text":57858},{"id":57917,"depth":769,"text":57918},{"id":57938,"depth":769,"text":57939},{"id":51329,"depth":761,"text":51330,"children":58317},[58318,58319],{"id":58026,"depth":769,"text":58027},{"id":58078,"depth":769,"text":58079},{"id":58150,"depth":761,"text":58151,"children":58321},[58322,58323,58324,58325,58326,58327,58328],{"id":58154,"depth":769,"text":58155},{"id":58165,"depth":769,"text":58166},{"id":58175,"depth":769,"text":58176},{"id":58185,"depth":769,"text":58186},{"id":58195,"depth":769,"text":58196},{"id":58244,"depth":769,"text":58245},{"id":58277,"depth":769,"text":58278},{"id":14525,"depth":761,"text":14526},"2018-05-01T07:45:25+02:00","Talks, keynotes, thoughts and pictures from the KubeCon Copenhagen 2018 Day 1.",{"src":57629},{"tags":58334},[13976,52359,26415,12175,124],"\u002Fblog\u002F2018\u002Fkubecon-copenhagen-2018-day-1",{"title":57572,"description":58331},"3.blog\u002F2018\u002Fkubecon-copenhagen-2018-day-1","r8MJ1U4aUgZ61EEF1nfoR2a0h2ePsylgQFeXdla0hMg",{"id":58340,"title":58341,"authors":58342,"badge":518,"body":58345,"date":58360,"description":58361,"extension":2911,"image":58362,"meta":58364,"navigation":1254,"path":58366,"seo":58367,"stem":58368,"__hash__":58369},"posts\u002F3.blog\u002F2018\u002Fkubecon-austin-2017-recap-presentation.md","KubeCon Austin 2017 (Recap) Presentation",[58343],{"name":514,"to":515,"avatar":58344},{"src":517},{"type":520,"value":58346,"toc":58358},[58347,58350,58353,58356],[523,58348,58349],{},"I created this presentation to recap my visit to KubeCon 2017 in Austin for my colleagues.",[523,58351,58352],{},"If you want to present my slides somewhere, please get in contact with me first. Thanks!",[18903,58354],{"src":58355,"frameBorder":3579,"height":18906,"allowFullScreen":5306,"mozallowfullscreen":5306,"webkitallowfullscreen":5306},"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002Fe\u002F2PACX-1vQXDyp91vvRU36GmMBQmQlh0PTqQf-Utqck3tNggzU4BKoR5tN20dxQOs6hJzyDx7qjzpPoMzOlQuBX\u002Fembed?start=false&loop=true&delayms=5000",[523,58357,52336],{},{"title":743,"searchDepth":761,"depth":761,"links":58359},[],"2018-04-04T08:30:12+02:00","A recap presentation about the KubeCon Austin 2017.",{"src":58363},"https:\u002F\u002Favatars1.githubusercontent.com\u002Fu\u002F13629408?s=400&v=4",{"tags":58365},[18918,124,52359,52360],"\u002Fblog\u002F2018\u002Fkubecon-austin-2017-recap-presentation",{"title":58341,"description":58361},"3.blog\u002F2018\u002Fkubecon-austin-2017-recap-presentation","MnOs90RLJeCpX6bPy-Q8JJ4w9J0Uvwn3E3NoOs2sLZQ",{"id":58371,"title":58372,"authors":58373,"badge":518,"body":58376,"date":60452,"description":60453,"extension":2911,"image":60454,"meta":60456,"navigation":1254,"path":60458,"seo":60459,"stem":60460,"__hash__":60461},"posts\u002F3.blog\u002F2018\u002Fcri-o-container-linux-how-to-install.md","CRI-O + Container Linux: How to Install",[58374],{"name":514,"to":515,"avatar":58375},{"src":517},{"type":520,"value":58377,"toc":60430},[58378,58380,58401,58424,58426,58474,58478,58481,58484,58500,58503,58506,58510,58524,58552,58555,58593,58596,58716,58719,58723,58747,58750,58773,58800,58808,58977,58987,58999,59012,59022,59026,59031,59043,59064,59073,59088,59100,59109,59113,59122,59128,59369,59380,59386,59499,59508,59512,59523,59575,59580,59596,59603,59618,59633,59718,59729,59744,59754,59815,59822,59825,59853,59863,59883,59886,59890,59896,59925,59935,59944,60013,60023,60040,60093,60108,60138,60141,60166,60169,60181,60185,60212,60234,60237,60251,60257,60264,60268,60271,60314,60320,60326,60366,60378,60380,60387,60398,60400,60407,60422,60425,60427],[535,58379,538],{"id":537},[6072,58381,58382,58386,58391,58395],{},[523,58383,58384],{},[584,58385,15250],{},[523,58387,58388],{},[584,58389,58390],{},"Currently it is very very far from optimal to run CRI-O on a \"no package manager\" system like Container Linux. For curious people, this should work \"perfectly\" though.",[523,58392,58393],{},[584,58394,6189],{},[523,58396,58397,58398,58400],{},"If it is not clear from the above ",[567,58399,15250],{},", I wouldn't recommend this for production (yet). Personally I will soon replace Docker with CRI-O in my private Kubernetes cluster though, because Docker causes issues in my cluster.",[523,58402,58403,58404,58408,58409,32497,58412,58417,58418,58423],{},"This post is showing how you can install and run ",[527,58405,401],{"href":58406,"rel":58407},"https:\u002F\u002Fcri-o.io\u002F",[531]," for ",[527,58410,124],{"href":11714,"rel":58411},[531],[527,58413,58416],{"href":58414,"rel":58415},"https:\u002F\u002Fcoreos.com\u002Fos\u002Fdocs\u002Flatest\u002F",[531],"Container Linux"," (previously CoreOS).\nCRI-O is an implementation of the ",[527,58419,58422],{"href":58420,"rel":58421},"https:\u002F\u002Fgithub.com\u002Fkubernetes\u002Fcommunity\u002Fblob\u002Fmaster\u002Fcontributors\u002Fdevel\u002Fcontainer-runtime-interface.md",[531],"Kubernetes Container Runtime Interface (CRI)",".\nThere are still some things not (fully) implemented in CRI-O yet, like Container metrics (see Kubernetes CRI link).",[613,58425,22268],{"id":22267},[668,58427,58428,58440,58461,58468],{},[638,58429,58430,58431,58436,58437,2006],{},"Golang (e.g. ",[527,58432,58435],{"href":58433,"rel":58434},"https:\u002F\u002Fgolang.org\u002Fdoc\u002Finstall",[531],"Getting Started - The Go Programming Language"," with a set ",[567,58438,58439],{},"$GOPATH",[638,58441,58442,6378,58447,6374,58450,58453,58454,58456,58457,2006],{},[527,58443,58446],{"href":58444,"rel":58445},"https:\u002F\u002Fgithub.com\u002Fcri-o\u002Fcri-o",[531],"CRI-O source code",[567,58448,58449],{},"go get",[567,58451,58452],{},"git clone",") in your ",[567,58455,58439],{}," (will be explained in ",[527,58458,58460],{"href":58459},"#Step-1-Preparations","Step 1 - Preparations",[638,58462,58463,58467],{},[527,58464,58466],{"href":58414,"rel":58465},[531],"Container Linux (\u002F CoreOS)"," machines",[638,58469,58470,58473],{},[567,58471,58472],{},"ldd"," Linux tool to show the shared object dependencies of binaries.",[535,58475,58477],{"id":58476},"why-switch-to-cri-o","Why switch to CRI-O?",[523,58479,58480],{},"For me the reason is simple: \"Docker seems to break down every few weeks in my private cluster and causes nodes to need a reboot..\".\nFrom running CRI-O for a bit now, Kubelet has gone \"quiet\". No more logs about issues with the container runtime (in my case Docker caused a good amount of logs in Kubelet).",[523,58482,58483],{},"I suggest you take a look at a few posts about CRI-O to get a general understanding of what CRI-O is:",[668,58485,58486,58493],{},[638,58487,58488],{},[527,58489,58492],{"href":58490,"rel":58491},"https:\u002F\u002Fwww.projectatomic.io\u002Fblog\u002F2017\u002F06\u002F6-reasons-why-cri-o-is-the-best-runtime-for-kubernetes\u002F",[531],"6 Reasons why CRI-O is the best runtime for Kubernetes - Project Atomic",[638,58494,58495],{},[527,58496,58499],{"href":58497,"rel":58498},"https:\u002F\u002Fthenewstack.io\u002Fcri-o-project-run-containers-without-docker-reaches-1-0\u002F",[531],"CRI-O, the Project to Run Containers without Docker, Reaches 1.0 - The New Stack",[523,58501,58502],{},"But you are most likely here because you already know that, right? ;)",[523,58504,58505],{},"Another point for me is that in the best case it will be \"shipped\" with Kubernetes at some point in time, so that you \"just\" upgrade Kubelet and et voilà you get the new CRI-O version. I would totally wnat it to be like that.",[535,58507,58509],{"id":58508},"step-1-build-cri-o","Step 1 - Build CRI-O",[6072,58511,58512,58516],{},[523,58513,58514],{},[584,58515,6189],{},[523,58517,58518,58519,1909],{},"You need to make sure you have the dependencies installed CRI-O expects you to have, they can be found here: ",[527,58520,58523],{"href":58521,"rel":58522},"https:\u002F\u002Fgithub.com\u002Fcri-o\u002Fcri-o\u002Fblob\u002Fmaster\u002Ftutorials\u002Fsetup.md#build-and-run-dependencies",[531],"Build and install CRI-O from source - Build and Run Dependencies section on cri-o\u002Fcri-o GitHub",[523,58525,58526,58527,6378,58532,58537,58538,58543,58544,58547,58548,58551],{},"You can either use release binaries (which are not linked to the releases (yet?)) or build CRI-O your own, for that checkout the ",[527,58528,58531],{"href":58529,"rel":58530},"https:\u002F\u002Fgithub.com\u002Fcri-o\u002Fcri-o\u002Fblob\u002Fmaster\u002Ftutorials\u002Fsetup.md",[531],"Build and install CRI-O from source on cri-o\u002Fcri-o GitHub",[527,58533,58536],{"href":58534,"rel":58535},"https:\u002F\u002Fgithub.com\u002Fcri-o\u002Fcri-o#getting-started",[531],"cri-o\u002Fcri-o README.md - Getting started section",").\nBefore you just go ahead and build from \"master\" branch, I'd recommend you to checkout ",[527,58539,58542],{"href":58540,"rel":58541},"https:\u002F\u002Fgithub.com\u002Fcri-o\u002Fcri-o#compatibility-matrix-cri-o---kubernetes-clusters",[531],"CRI-O's Kubernetes compatibility matrix"," and choose a release branch, e.g., ",[567,58545,58546],{},"release-1.14"," for Kubernetes ",[567,58549,58550],{},"v1.14.x"," compatibility.",[523,58553,58554],{},"Summarized to build the binary from source run:",[738,58556,58558],{"className":1621,"code":58557,"language":1623,"meta":743,"style":743},"$ go get -u github.com\u002Fcri-o\u002Fcri-o\n$ cd $GOPATH\u002Fsrc\u002Fgithub.com\u002Fcri-o\u002Fcri-o\n$ make\n",[567,58559,58560,58574,58586],{"__ignoreMap":743},[747,58561,58562,58564,58567,58569,58571],{"class":749,"line":750},[747,58563,1919],{"class":1630},[747,58565,58566],{"class":802}," go",[747,58568,1951],{"class":802},[747,58570,7089],{"class":802},[747,58572,58573],{"class":802}," github.com\u002Fcri-o\u002Fcri-o\n",[747,58575,58576,58578,58580,58583],{"class":749,"line":761},[747,58577,1919],{"class":1630},[747,58579,22405],{"class":802},[747,58581,58582],{"class":1640}," $GOPATH",[747,58584,58585],{"class":802},"\u002Fsrc\u002Fgithub.com\u002Fcri-o\u002Fcri-o\n",[747,58587,58588,58590],{"class":749,"line":769},[747,58589,1919],{"class":1630},[747,58591,58592],{"class":802}," make\n",[523,58594,58595],{},"That will produce all CRI-O binaries, see:",[738,58597,58599],{"className":1621,"code":58598,"language":1623,"meta":743,"style":743},"$ ls -hl $GOPATH\u002Fsrc\u002Fgithub.com\u002Fcri-o\u002Fcri-o\u002Fbin\ntotal 86M\n-rwxr-xr-x 1 user user  56K 19. Apr 12:14 conmon\n-rwxr-xr-x 1 user user  46M 19. Apr 12:14 crio\n-rwxr-xr-x 1 user user  40M 19. Apr 12:14 crio-config\n-rwxr-xr-x 1 user user 743K 19. Apr 12:14 pause\n",[567,58600,58601,58616,58624,58650,58672,58694],{"__ignoreMap":743},[747,58602,58603,58605,58608,58611,58613],{"class":749,"line":750},[747,58604,1919],{"class":1630},[747,58606,58607],{"class":802}," ls",[747,58609,58610],{"class":802}," -hl",[747,58612,58582],{"class":1640},[747,58614,58615],{"class":802},"\u002Fsrc\u002Fgithub.com\u002Fcri-o\u002Fcri-o\u002Fbin\n",[747,58617,58618,58621],{"class":749,"line":761},[747,58619,58620],{"class":1630},"total",[747,58622,58623],{"class":802}," 86M\n",[747,58625,58626,58629,58631,58633,58635,58638,58641,58644,58647],{"class":749,"line":769},[747,58627,58628],{"class":1630},"-rwxr-xr-x",[747,58630,3597],{"class":1895},[747,58632,19317],{"class":802},[747,58634,19317],{"class":802},[747,58636,58637],{"class":802},"  56K",[747,58639,58640],{"class":802}," 19.",[747,58642,58643],{"class":802}," Apr",[747,58645,58646],{"class":802}," 12:14",[747,58648,58649],{"class":802}," conmon\n",[747,58651,58652,58654,58656,58658,58660,58663,58665,58667,58669],{"class":749,"line":776},[747,58653,58628],{"class":1630},[747,58655,3597],{"class":1895},[747,58657,19317],{"class":802},[747,58659,19317],{"class":802},[747,58661,58662],{"class":802},"  46M",[747,58664,58640],{"class":802},[747,58666,58643],{"class":802},[747,58668,58646],{"class":802},[747,58670,58671],{"class":802}," crio\n",[747,58673,58674,58676,58678,58680,58682,58685,58687,58689,58691],{"class":749,"line":784},[747,58675,58628],{"class":1630},[747,58677,3597],{"class":1895},[747,58679,19317],{"class":802},[747,58681,19317],{"class":802},[747,58683,58684],{"class":802},"  40M",[747,58686,58640],{"class":802},[747,58688,58643],{"class":802},[747,58690,58646],{"class":802},[747,58692,58693],{"class":802}," crio-config\n",[747,58695,58696,58698,58700,58702,58704,58707,58709,58711,58713],{"class":749,"line":790},[747,58697,58628],{"class":1630},[747,58699,3597],{"class":1895},[747,58701,19317],{"class":802},[747,58703,19317],{"class":802},[747,58705,58706],{"class":802}," 743K",[747,58708,58640],{"class":802},[747,58710,58643],{"class":802},[747,58712,58646],{"class":802},[747,58714,58715],{"class":802}," pause\n",[523,58717,58718],{},"These binaries are needed and will be referenced to in the  upcoming steps.",[535,58720,58722],{"id":58721},"step-2-upload-cri-o-and-dependencies","Step 2 - Upload CRI-O and \"Dependencies\"",[6072,58724,58725,58729],{},[523,58726,58727],{},[584,58728,6189],{},[523,58730,58731,58732,6378,58735,58738,58739,58742,58743,58746],{},"It is possible that the dependent libraries are named differently on your (build) machine.\nUse ",[567,58733,58734],{},"ldd FILENAME",[567,58736,58737],{},"ldd crio",") to show which libraries need to be copied. All libraries with ",[567,58740,58741],{},"not found"," need to be copied to the ",[567,58744,58745],{},"\u002Fopt\u002Flib64"," directory.",[523,58748,58749],{},"On \"all\" servers which should be switched to use CRI-O as the Container Runtime we need to create some directory:",[738,58751,58753],{"className":1621,"code":58752,"language":1623,"meta":743,"style":743},"mkdir -p \u002Fopt\u002Fbin \u002Fopt\u002Flib64 \u002Fetc\u002Fcrio \u002Fvar\u002Flib\u002Fcrio\n",[567,58754,58755],{"__ignoreMap":743},[747,58756,58757,58759,58761,58764,58767,58770],{"class":749,"line":750},[747,58758,36923],{"class":1630},[747,58760,7094],{"class":802},[747,58762,58763],{"class":802}," \u002Fopt\u002Fbin",[747,58765,58766],{"class":802}," \u002Fopt\u002Flib64",[747,58768,58769],{"class":802}," \u002Fetc\u002Fcrio",[747,58771,58772],{"class":802}," \u002Fvar\u002Flib\u002Fcrio\n",[523,58774,58775,58776,587,58779,58782,58783,58786,58787,10616,58789,58792,58793,58796,58797,58799],{},"Now upload the compiled ",[567,58777,58778],{},"crio",[567,58780,58781],{},"conmon"," (not ",[567,58784,58785],{},"common",") binaries from ",[527,58788,58460],{"href":58459},[567,58790,58791],{},"\u002Fopt\u002Fbin"," directory on the hosts.\nAfter that run ",[567,58794,58795],{},"ldd \u002Fopt\u002Fbin\u002Fcrio"," (and for ",[567,58798,58781],{}," too), to see which libraries need to uploaded too.",[523,58801,58802,58804,58805,856],{},[584,58803,3673],{}," of ",[567,58806,58807],{},"ldd \u002Fusr\u002Fbin\u002Fffmpeg",[738,58809,58811],{"className":1621,"code":58810,"language":1623,"meta":743,"style":743},"ldd \u002Fusr\u002Fbin\u002Fffmpeg\n    linux-vdso.so.1 =>  (0x00007ffffc1fe000)\n    libavfilter.so.0 => not found\n    libpostproc.so.51 => not found\n    libswscale.so.0 => not found\n    libavdevice.so.52 => not found\n    libavformat.so.52 => not found\n    libavcodec.so.52 => not found\n    libavutil.so.49 => not found\n    libm.so.6 => \u002Flib\u002Fx86_64-linux-gnu\u002Flibm.so.6 (0x00007fdd18259000)\n    libpthread.so.0 => \u002Flib\u002Fx86_64-linux-gnu\u002Flibpthread.so.0 (0x00007fdd1803a000)\n    libc.so.6 => \u002Flib\u002Fx86_64-linux-gnu\u002Flibc.so.6 (0x00007fdd17c75000)\n    \u002Flib64\u002Fld-linux-x86-64.so.2 (0x00007fdd18583000)\n",[567,58812,58813,58820,58832,58846,58859,58872,58885,58898,58911,58924,58939,58954,58969],{"__ignoreMap":743},[747,58814,58815,58817],{"class":749,"line":750},[747,58816,58472],{"class":1630},[747,58818,58819],{"class":802}," \u002Fusr\u002Fbin\u002Fffmpeg\n",[747,58821,58822,58825,58827,58829],{"class":749,"line":761},[747,58823,58824],{"class":1630},"    linux-vdso.so.1",[747,58826,19444],{"class":1640},[747,58828,2035],{"class":757},[747,58830,58831],{"class":1640},"  (0x00007ffffc1fe000)\n",[747,58833,58834,58837,58839,58841,58843],{"class":749,"line":769},[747,58835,58836],{"class":1630},"    libavfilter.so.0",[747,58838,19444],{"class":1640},[747,58840,2035],{"class":757},[747,58842,37708],{"class":802},[747,58844,58845],{"class":802}," found\n",[747,58847,58848,58851,58853,58855,58857],{"class":749,"line":776},[747,58849,58850],{"class":1630},"    libpostproc.so.51",[747,58852,19444],{"class":1640},[747,58854,2035],{"class":757},[747,58856,37708],{"class":802},[747,58858,58845],{"class":802},[747,58860,58861,58864,58866,58868,58870],{"class":749,"line":784},[747,58862,58863],{"class":1630},"    libswscale.so.0",[747,58865,19444],{"class":1640},[747,58867,2035],{"class":757},[747,58869,37708],{"class":802},[747,58871,58845],{"class":802},[747,58873,58874,58877,58879,58881,58883],{"class":749,"line":790},[747,58875,58876],{"class":1630},"    libavdevice.so.52",[747,58878,19444],{"class":1640},[747,58880,2035],{"class":757},[747,58882,37708],{"class":802},[747,58884,58845],{"class":802},[747,58886,58887,58890,58892,58894,58896],{"class":749,"line":796},[747,58888,58889],{"class":1630},"    libavformat.so.52",[747,58891,19444],{"class":1640},[747,58893,2035],{"class":757},[747,58895,37708],{"class":802},[747,58897,58845],{"class":802},[747,58899,58900,58903,58905,58907,58909],{"class":749,"line":806},[747,58901,58902],{"class":1630},"    libavcodec.so.52",[747,58904,19444],{"class":1640},[747,58906,2035],{"class":757},[747,58908,37708],{"class":802},[747,58910,58845],{"class":802},[747,58912,58913,58916,58918,58920,58922],{"class":749,"line":814},[747,58914,58915],{"class":1630},"    libavutil.so.49",[747,58917,19444],{"class":1640},[747,58919,2035],{"class":757},[747,58921,37708],{"class":802},[747,58923,58845],{"class":802},[747,58925,58926,58929,58931,58933,58936],{"class":749,"line":822},[747,58927,58928],{"class":1630},"    libm.so.6",[747,58930,19444],{"class":1640},[747,58932,2035],{"class":757},[747,58934,58935],{"class":802}," \u002Flib\u002Fx86_64-linux-gnu\u002Flibm.so.6",[747,58937,58938],{"class":1640}," (0x00007fdd18259000)\n",[747,58940,58941,58944,58946,58948,58951],{"class":749,"line":830},[747,58942,58943],{"class":1630},"    libpthread.so.0",[747,58945,19444],{"class":1640},[747,58947,2035],{"class":757},[747,58949,58950],{"class":802}," \u002Flib\u002Fx86_64-linux-gnu\u002Flibpthread.so.0",[747,58952,58953],{"class":1640}," (0x00007fdd1803a000)\n",[747,58955,58956,58959,58961,58963,58966],{"class":749,"line":836},[747,58957,58958],{"class":1630},"    libc.so.6",[747,58960,19444],{"class":1640},[747,58962,2035],{"class":757},[747,58964,58965],{"class":802}," \u002Flib\u002Fx86_64-linux-gnu\u002Flibc.so.6",[747,58967,58968],{"class":1640}," (0x00007fdd17c75000)\n",[747,58970,58971,58974],{"class":749,"line":842},[747,58972,58973],{"class":1630},"    \u002Flib64\u002Fld-linux-x86-64.so.2",[747,58975,58976],{"class":1640}," (0x00007fdd18583000)\n",[523,58978,58979,58980,58983,58984,58986],{},"If you look at the example output for, unrelated, ",[567,58981,58982],{},"ffmpeg"," binary, you see some entries having ",[567,58985,58741],{}," behind the arrow. These libraries need to be copied to the hosts.",[523,58988,58989,58990,58993,58994,58996,58997,58746],{},"For CRI-O this can possibly be the ",[567,58991,58992],{},"libgpgme.so.11"," library. Meaning that you copy the ",[567,58995,58992],{}," of your build machine\u002F laptop to the hosts ",[567,58998,58745],{},[523,59000,59001,59002,22542,59004,59006,59007,587,59009,59011],{},"Upload all libraries that are ",[567,59003,58741],{},[567,59005,58472],{}," output for ",[567,59008,58778],{},[567,59010,58781],{}," binary. The path to each library should be shown as in the above example output.",[523,59013,59014,59015,59018,59019,59021],{},"To verify that the libraries copied are correct, you can run ",[567,59016,59017],{},"LD_LIBRARY_PATH=:\u002Fopt\u002Flib64 ldd \u002Fopt\u002Fbin\u002Fcrio"," and it should now show no ",[567,59020,58741],{}," entries anymore.",[613,59023,59025],{"id":59024},"software-dependencies","Software dependencies",[523,59027,59028,59029,58746],{},"Depending on which version of Container Linux (CoreOS), you may need to copy the following software dependencies of the following dependencies to your hosts ",[567,59030,58791],{},[523,59032,59033,59034,6374,59037,6353,59040,59042],{},"Make sure to verify that the software are not on the servers already, e.g., use ",[567,59035,59036],{},"command -v runc",[567,59038,59039],{},"which runc",[567,59041,39903],{}," is the software you are checking for).",[668,59044,59045,59050,59055,59060],{},[638,59046,59047,59049],{},[567,59048,39903],{}," - If that is missing something is probably \"wrong\" with your host's Container Linux.",[638,59051,59052],{},[567,59053,59054],{},"socat",[638,59056,59057],{},[567,59058,59059],{},"iproute",[638,59061,59062],{},[567,59063,8254],{},[523,59065,59066,856],{},[584,59067,59068,59069,59072],{},"Example for ",[567,59070,59071],{},"conntrack"," binary",[523,59074,59075,59076,59078,59079,59081,59082,59084,59085,59087],{},"Upload ",[567,59077,59071],{}," binary to ",[567,59080,58791],{}," and the ",[567,59083,58741],{}," library dependencies to ",[567,59086,58745],{}," which would be:",[668,59089,59090,59095],{},[638,59091,59092],{},[567,59093,59094],{},"libnetfilter_conntrack.so.3",[638,59096,59097],{},[567,59098,59099],{},"libnfnetlink.so.0",[523,59101,44115,59102,59105,59106,59108],{},[567,59103,59104],{},"LD_LIBRARY_PATH=:\u002Fopt\u002Flib64 ldd \u002Fopt\u002Fbin\u002Fconntrack"," should show no ",[567,59107,58741],{}," library entries.",[535,59110,59112],{"id":59111},"step-3-cri-o-systemd-service","Step 3 - CRI-O Systemd Service",[6072,59114,59115,59119],{},[523,59116,59117],{},[584,59118,6189],{},[523,59120,59121],{},"The Systemd service units shown here are modified versions of the originals!\nKeep that in mind if you have made your own modifications to the service unit files.",[523,59123,59124,59125,856],{},"Create Systemd service unit at ",[567,59126,59127],{},"\u002Fetc\u002Fsystemd\u002Fsystem\u002Fcrio.service",[738,59129,59131],{"className":32095,"code":59130,"language":32097,"meta":743,"style":743},"[Unit]\nDescription=Open Container Initiative Daemon\nDocumentation=https:\u002F\u002Fgithub.com\u002Fcri-o\u002Fcri-o\nWants=network-online.target\nAfter=network-online.target\n\n[Service]\nType=notify\nEnvironmentFile=-\u002Fetc\u002Fsysconfig\u002Fcrio\nEnvironment=GOTRACEBACK=crash\nEnvironment=LD_LIBRARY_PATH=:\u002Fopt\u002Flib64\nEnvironment=PATH=\u002Fusr\u002Flocal\u002Fsbin:\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fsbin:\u002Fusr\u002Fbin:\u002Fopt\u002Fbin\nExecStart=\u002Fusr\u002Flocal\u002Fbin\u002Fcrio \\\n          $CRIO_STORAGE_OPTIONS \\\n          $CRIO_NETWORK_OPTIONS \\\n          $CRIO_METRICS_OPTIONS\nExecReload=\u002Fbin\u002Fkill -s HUP $MAINPID\nTasksMax=infinity\nLimitNOFILE=1048576\nLimitNPROC=1048576\nLimitCORE=infinity\nOOMScoreAdjust=-999\nTimeoutStartSec=0\nRestart=on-abnormal\n\n[Install]\nWantedBy=multi-user.target\n",[567,59132,59133,59138,59148,59158,59168,59177,59181,59186,59195,59205,59220,59234,59247,59257,59262,59267,59272,59282,59292,59302,59311,59320,59330,59340,59350,59354,59359],{"__ignoreMap":743},[747,59134,59135],{"class":749,"line":750},[747,59136,59137],{"class":757},"[Unit]\n",[747,59139,59140,59143,59145],{"class":749,"line":761},[747,59141,59142],{"class":753},"Description",[747,59144,6425],{"class":757},[747,59146,59147],{"class":1640},"Open Container Initiative Daemon\n",[747,59149,59150,59153,59155],{"class":749,"line":769},[747,59151,59152],{"class":753},"Documentation",[747,59154,6425],{"class":757},[747,59156,59157],{"class":1640},"https:\u002F\u002Fgithub.com\u002Fcri-o\u002Fcri-o\n",[747,59159,59160,59163,59165],{"class":749,"line":776},[747,59161,59162],{"class":753},"Wants",[747,59164,6425],{"class":757},[747,59166,59167],{"class":1640},"network-online.target\n",[747,59169,59170,59173,59175],{"class":749,"line":784},[747,59171,59172],{"class":753},"After",[747,59174,6425],{"class":757},[747,59176,59167],{"class":1640},[747,59178,59179],{"class":749,"line":790},[747,59180,1255],{"emptyLinePlaceholder":1254},[747,59182,59183],{"class":749,"line":796},[747,59184,59185],{"class":757},"[Service]\n",[747,59187,59188,59190,59192],{"class":749,"line":806},[747,59189,33482],{"class":753},[747,59191,6425],{"class":757},[747,59193,59194],{"class":1640},"notify\n",[747,59196,59197,59200,59202],{"class":749,"line":814},[747,59198,59199],{"class":753},"EnvironmentFile",[747,59201,6425],{"class":757},[747,59203,59204],{"class":1640},"-\u002Fetc\u002Fsysconfig\u002Fcrio\n",[747,59206,59207,59210,59212,59215,59217],{"class":749,"line":822},[747,59208,59209],{"class":753},"Environment",[747,59211,6425],{"class":757},[747,59213,59214],{"class":753},"GOTRACEBACK",[747,59216,6425],{"class":757},[747,59218,59219],{"class":1640},"crash\n",[747,59221,59222,59224,59226,59229,59231],{"class":749,"line":830},[747,59223,59209],{"class":753},[747,59225,6425],{"class":757},[747,59227,59228],{"class":753},"LD_LIBRARY_PATH",[747,59230,6425],{"class":757},[747,59232,59233],{"class":1640},":\u002Fopt\u002Flib64\n",[747,59235,59236,59238,59240,59242,59244],{"class":749,"line":836},[747,59237,59209],{"class":753},[747,59239,6425],{"class":757},[747,59241,3326],{"class":753},[747,59243,6425],{"class":757},[747,59245,59246],{"class":1640},"\u002Fusr\u002Flocal\u002Fsbin:\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fsbin:\u002Fusr\u002Fbin:\u002Fopt\u002Fbin\n",[747,59248,59249,59252,59254],{"class":749,"line":842},[747,59250,59251],{"class":753},"ExecStart",[747,59253,6425],{"class":757},[747,59255,59256],{"class":1640},"\u002Fusr\u002Flocal\u002Fbin\u002Fcrio \\\n",[747,59258,59259],{"class":749,"line":850},[747,59260,59261],{"class":1640},"          $CRIO_STORAGE_OPTIONS \\\n",[747,59263,59264],{"class":749,"line":863},[747,59265,59266],{"class":1640},"          $CRIO_NETWORK_OPTIONS \\\n",[747,59268,59269],{"class":749,"line":869},[747,59270,59271],{"class":1640},"          $CRIO_METRICS_OPTIONS\n",[747,59273,59274,59277,59279],{"class":749,"line":877},[747,59275,59276],{"class":753},"ExecReload",[747,59278,6425],{"class":757},[747,59280,59281],{"class":1640},"\u002Fbin\u002Fkill -s HUP $MAINPID\n",[747,59283,59284,59287,59289],{"class":749,"line":1015},[747,59285,59286],{"class":753},"TasksMax",[747,59288,6425],{"class":757},[747,59290,59291],{"class":1640},"infinity\n",[747,59293,59294,59297,59299],{"class":749,"line":1021},[747,59295,59296],{"class":753},"LimitNOFILE",[747,59298,6425],{"class":757},[747,59300,59301],{"class":1640},"1048576\n",[747,59303,59304,59307,59309],{"class":749,"line":1027},[747,59305,59306],{"class":753},"LimitNPROC",[747,59308,6425],{"class":757},[747,59310,59301],{"class":1640},[747,59312,59313,59316,59318],{"class":749,"line":1033},[747,59314,59315],{"class":753},"LimitCORE",[747,59317,6425],{"class":757},[747,59319,59291],{"class":1640},[747,59321,59322,59325,59327],{"class":749,"line":1039},[747,59323,59324],{"class":753},"OOMScoreAdjust",[747,59326,6425],{"class":757},[747,59328,59329],{"class":1640},"-999\n",[747,59331,59332,59335,59337],{"class":749,"line":1054},[747,59333,59334],{"class":753},"TimeoutStartSec",[747,59336,6425],{"class":757},[747,59338,59339],{"class":1640},"0\n",[747,59341,59342,59345,59347],{"class":749,"line":1060},[747,59343,59344],{"class":753},"Restart",[747,59346,6425],{"class":757},[747,59348,59349],{"class":1640},"on-abnormal\n",[747,59351,59352],{"class":749,"line":1066},[747,59353,1255],{"emptyLinePlaceholder":1254},[747,59355,59356],{"class":749,"line":1081},[747,59357,59358],{"class":757},"[Install]\n",[747,59360,59361,59364,59366],{"class":749,"line":1087},[747,59362,59363],{"class":753},"WantedBy",[747,59365,6425],{"class":757},[747,59367,59368],{"class":1640},"multi-user.target\n",[523,59370,59371,59372,1909],{},"The original Systemd service unit was taken from ",[527,59373,59376,59377],{"href":59374,"rel":59375},"https:\u002F\u002Fgithub.com\u002Fcri-o\u002Fcri-o\u002Fblob\u002Fmaster\u002Fcontrib\u002Fsystemd\u002Fcrio.service",[531],"GitHub cri-o\u002Fcri-o - master ",[567,59378,59379],{},"contrib\u002Fsystemd\u002Fcrio.service",[523,59381,59382,59383,856],{},"To signal CRI-O that a shutdown has started, a second Systemd service unit is used at ",[567,59384,59385],{},"\u002Fetc\u002Fsystemd\u002Fsystem\u002Fcrio-shutdown.service",[738,59387,59389],{"className":32095,"code":59388,"language":32097,"meta":743,"style":743},"[Unit]\nDescription=Shutdown CRIO containers before shutting down the system\nWants=crio.service\nAfter=crio.service\nDocumentation=man:crio(8)\n\n[Service]\nType=oneshot\nExecStart=\u002Fusr\u002Fbin\u002Frm -f \u002Fvar\u002Flib\u002Fcrio\u002Fcrio.shutdown\nExecStop=\u002Fusr\u002Fbin\u002Fbash -c \"\u002Fusr\u002Fbin\u002Fmkdir \u002Fvar\u002Flib\u002Fcrio; \u002Fusr\u002Fbin\u002Ftouch \u002Fvar\u002Flib\u002Fcrio\u002Fcrio.shutdown\"\nRemainAfterExit=yes\n\n[Install]\nWantedBy=multi-user.target\n",[567,59390,59391,59395,59404,59413,59421,59430,59434,59438,59447,59456,59473,59483,59487,59491],{"__ignoreMap":743},[747,59392,59393],{"class":749,"line":750},[747,59394,59137],{"class":757},[747,59396,59397,59399,59401],{"class":749,"line":761},[747,59398,59142],{"class":753},[747,59400,6425],{"class":757},[747,59402,59403],{"class":1640},"Shutdown CRIO containers before shutting down the system\n",[747,59405,59406,59408,59410],{"class":749,"line":769},[747,59407,59162],{"class":753},[747,59409,6425],{"class":757},[747,59411,59412],{"class":1640},"crio.service\n",[747,59414,59415,59417,59419],{"class":749,"line":776},[747,59416,59172],{"class":753},[747,59418,6425],{"class":757},[747,59420,59412],{"class":1640},[747,59422,59423,59425,59427],{"class":749,"line":784},[747,59424,59152],{"class":753},[747,59426,6425],{"class":757},[747,59428,59429],{"class":1640},"man:crio(8)\n",[747,59431,59432],{"class":749,"line":790},[747,59433,1255],{"emptyLinePlaceholder":1254},[747,59435,59436],{"class":749,"line":796},[747,59437,59185],{"class":757},[747,59439,59440,59442,59444],{"class":749,"line":806},[747,59441,33482],{"class":753},[747,59443,6425],{"class":757},[747,59445,59446],{"class":1640},"oneshot\n",[747,59448,59449,59451,59453],{"class":749,"line":814},[747,59450,59251],{"class":753},[747,59452,6425],{"class":757},[747,59454,59455],{"class":1640},"\u002Fusr\u002Fbin\u002Frm -f \u002Fvar\u002Flib\u002Fcrio\u002Fcrio.shutdown\n",[747,59457,59458,59461,59463,59466,59468,59471],{"class":749,"line":822},[747,59459,59460],{"class":753},"ExecStop",[747,59462,6425],{"class":757},[747,59464,59465],{"class":1640},"\u002Fusr\u002Fbin\u002Fbash -c ",[747,59467,3892],{"class":757},[747,59469,59470],{"class":802},"\u002Fusr\u002Fbin\u002Fmkdir \u002Fvar\u002Flib\u002Fcrio; \u002Fusr\u002Fbin\u002Ftouch \u002Fvar\u002Flib\u002Fcrio\u002Fcrio.shutdown",[747,59472,975],{"class":757},[747,59474,59475,59478,59480],{"class":749,"line":830},[747,59476,59477],{"class":753},"RemainAfterExit",[747,59479,6425],{"class":757},[747,59481,59482],{"class":1640},"yes\n",[747,59484,59485],{"class":749,"line":836},[747,59486,1255],{"emptyLinePlaceholder":1254},[747,59488,59489],{"class":749,"line":842},[747,59490,59358],{"class":757},[747,59492,59493,59495,59497],{"class":749,"line":850},[747,59494,59363],{"class":753},[747,59496,6425],{"class":757},[747,59498,59368],{"class":1640},[523,59500,59371,59501,1909],{},[527,59502,59376,59505],{"href":59503,"rel":59504},"https:\u002F\u002Fgithub.com\u002Fcri-o\u002Fcri-o\u002Fblob\u002Fmaster\u002Fcontrib\u002Fsystemd\u002Fcrio-shutdown.service",[531],[567,59506,59507],{},"contrib\u002Fsystemd\u002Fcrio-shutdown.service",[535,59509,59511],{"id":59510},"step-4-configure-cri-o","Step 4 - Configure CRI-O",[523,59513,59514,59515,59518,59519,59522],{},"Create the directory ",[567,59516,59517],{},"\u002Fetc\u002Fsysconfig"," if it doesn't exist yet, and create\u002F update the file ",[567,59520,59521],{},"\u002Fetc\u002Fsysconfig\u002Fcrio"," in it with the following content:",[738,59524,59526],{"className":1621,"code":59525,"language":1623,"meta":743,"style":743},"# \u002Fetc\u002Fsysconfig\u002Fcrio\n\n# use \"--enable-metrics\" and \"--metrics-port value\"\n#CRIO_METRICS_OPTIONS=\"--enable-metrics\"\n\n#CRIO_NETWORK_OPTIONS=\nCRIO_NETWORK_OPTIONS=\"--conmon=\u002Fopt\u002Fbin\u002Fconmon\"\n#CRIO_STORAGE_OPTIONS=\n",[567,59527,59528,59533,59537,59542,59547,59551,59556,59570],{"__ignoreMap":743},[747,59529,59530],{"class":749,"line":750},[747,59531,59532],{"class":772},"# \u002Fetc\u002Fsysconfig\u002Fcrio\n",[747,59534,59535],{"class":749,"line":761},[747,59536,1255],{"emptyLinePlaceholder":1254},[747,59538,59539],{"class":749,"line":769},[747,59540,59541],{"class":772},"# use \"--enable-metrics\" and \"--metrics-port value\"\n",[747,59543,59544],{"class":749,"line":776},[747,59545,59546],{"class":772},"#CRIO_METRICS_OPTIONS=\"--enable-metrics\"\n",[747,59548,59549],{"class":749,"line":784},[747,59550,1255],{"emptyLinePlaceholder":1254},[747,59552,59553],{"class":749,"line":790},[747,59554,59555],{"class":772},"#CRIO_NETWORK_OPTIONS=\n",[747,59557,59558,59561,59563,59565,59568],{"class":749,"line":796},[747,59559,59560],{"class":1640},"CRIO_NETWORK_OPTIONS",[747,59562,6425],{"class":757},[747,59564,3892],{"class":757},[747,59566,59567],{"class":802},"--conmon=\u002Fopt\u002Fbin\u002Fconmon",[747,59569,975],{"class":757},[747,59571,59572],{"class":749,"line":806},[747,59573,59574],{"class":772},"#CRIO_STORAGE_OPTIONS=\n",[523,59576,8764,59577,59579],{},[567,59578,59521],{}," file holds a few flags which do the following:",[668,59581,59582],{},[638,59583,59584,59586,59587,26767,59590,59592,59593,1909],{},[567,59585,59567],{}," - Use ",[567,59588,59589],{},"\u002Fopt\u002Fbin\u002Fconmon",[567,59591,58781],{}," binary, instead of searching through ",[567,59594,59595],{},"$PATH",[523,59597,59598,59599,856],{},"There are two other files needed from the ",[527,59600,59602],{"href":58444,"rel":59601},[531],"GitHub cri-o\u002Fcri-o repository",[523,59604,59605,59606,59609,59610,1909],{},"First file is to be placed at ",[567,59607,59608],{},"\u002Fetc\u002Fcrio\u002Fseccomp.json",", it can be found here: ",[527,59611,59614,59615],{"href":59612,"rel":59613},"https:\u002F\u002Fgithub.com\u002Fcri-o\u002Fcri-o\u002Fblob\u002Fmaster\u002Fseccomp.json",[531],"GitHub kubernetes-incubator - master ",[567,59616,59617],{},"seccomp.json",[523,59619,59620,59621,59624,59625,59632],{},"Second to be placed at ",[567,59622,59623],{},"\u002Fetc\u002Fcontainers\u002Fpolicy.json",", the original can be found here: ",[527,59626,59614,59629],{"href":59627,"rel":59628},"https:\u002F\u002Fgithub.com\u002Fcri-o\u002Fcri-o\u002Fblob\u002Fmaster\u002Ftest\u002Fpolicy.json",[531],[567,59630,59631],{},"test\u002Fpolicy.json",", as you may see from the path where the file is located, it is probably just used for testing, so I'd recommend you to use this \"slimmed down\" version:",[738,59634,59638],{"className":59635,"code":59636,"language":59637,"meta":743,"style":743},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n    \"default\": [\n        {\n            \"type\": \"insecureAcceptAnything\"\n        }\n    ],\n    \"transports\": {\n        \"docker\": {}\n    }\n}\n","json",[567,59639,59640,59644,59656,59660,59677,59681,59685,59698,59710,59714],{"__ignoreMap":743},[747,59641,59642],{"class":749,"line":750},[747,59643,13004],{"class":757},[747,59645,59646,59648,59650,59652,59654],{"class":749,"line":761},[747,59647,20579],{"class":757},[747,59649,2014],{"class":19865},[747,59651,3892],{"class":757},[747,59653,856],{"class":757},[747,59655,20689],{"class":757},[747,59657,59658],{"class":749,"line":769},[747,59659,20936],{"class":757},[747,59661,59662,59664,59666,59668,59670,59672,59675],{"class":749,"line":776},[747,59663,20646],{"class":757},[747,59665,23273],{"class":1630},[747,59667,3892],{"class":757},[747,59669,856],{"class":757},[747,59671,969],{"class":757},[747,59673,59674],{"class":802},"insecureAcceptAnything",[747,59676,975],{"class":757},[747,59678,59679],{"class":749,"line":784},[747,59680,20860],{"class":757},[747,59682,59683],{"class":749,"line":790},[747,59684,20981],{"class":757},[747,59686,59687,59689,59692,59694,59696],{"class":749,"line":796},[747,59688,20579],{"class":757},[747,59690,59691],{"class":19865},"transports",[747,59693,3892],{"class":757},[747,59695,856],{"class":757},[747,59697,20574],{"class":757},[747,59699,59700,59702,59704,59706,59708],{"class":749,"line":806},[747,59701,20632],{"class":757},[747,59703,3257],{"class":1630},[747,59705,3892],{"class":757},[747,59707,856],{"class":757},[747,59709,18570],{"class":757},[747,59711,59712],{"class":749,"line":814},[747,59713,21297],{"class":757},[747,59715,59716],{"class":749,"line":822},[747,59717,19374],{"class":757},[523,59719,59720,59721,2006],{},"(This file is also available as a Gist: ",[527,59722,59725,59726],{"href":59723,"rel":59724},"https:\u002F\u002Fgist.github.com\u002Fgalexrt\u002F5ff3b48994328368330949a8ed0634ea#file-policy-json",[531],"GitHub Gist - galexrt - My current CRI-O config file - ",[567,59727,59728],{},"policy.json",[523,59730,59731,59732,59735,59736,59739,59740,59743],{},"Now that the parts around CRI-O are configured, let's configure CRI-O \"in-depth\" using the ",[567,59733,59734],{},"crio.conf"," file.\nYou can use the ",[567,59737,59738],{},"crio config --default > \u002Fetc\u002Fcrio\u002Fcrio.conf"," command to generate a config with sane defaults (",[567,59741,59742],{},"--default"," flag adds the sane defaults).",[523,59745,59746,59747,59749,59750,59753],{},"An important point to change in the ",[567,59748,59734],{}," to make CRI-O \"Docker backwards compatible\" is to make CRI-O not fail for images without an image registry server. Normally such images are served from Docker Hub, but CRI-O by default would fail. To fix that modify the ",[567,59751,59752],{},"\u002Fetc\u002Fcrio\u002Fcrio.conf"," as follows:",[738,59755,59757],{"className":32095,"code":59756,"language":32097,"meta":743,"style":743},"[...]\n# List of registries to be used when pulling an unqualified image (e.g.,\n# \"alpine:latest\"). By default, registries is set to \"docker.io\" for\n# compatibility reasons. Depending on your workload and usecase you may add more\n# registries (e.g., \"quay.io\", \"registry.fedoraproject.org\",\n# \"registry.opensuse.org\", etc.).\nregistries = [\n    \"docker.io\",\n]\n[...]\n",[567,59758,59759,59763,59768,59773,59778,59783,59788,59797,59807,59811],{"__ignoreMap":743},[747,59760,59761],{"class":749,"line":750},[747,59762,5986],{"class":757},[747,59764,59765],{"class":749,"line":761},[747,59766,59767],{"class":772},"# List of registries to be used when pulling an unqualified image (e.g.,\n",[747,59769,59770],{"class":749,"line":769},[747,59771,59772],{"class":772},"# \"alpine:latest\"). By default, registries is set to \"docker.io\" for\n",[747,59774,59775],{"class":749,"line":776},[747,59776,59777],{"class":772},"# compatibility reasons. Depending on your workload and usecase you may add more\n",[747,59779,59780],{"class":749,"line":784},[747,59781,59782],{"class":772},"# registries (e.g., \"quay.io\", \"registry.fedoraproject.org\",\n",[747,59784,59785],{"class":749,"line":790},[747,59786,59787],{"class":772},"# \"registry.opensuse.org\", etc.).\n",[747,59789,59790,59793,59795],{"class":749,"line":796},[747,59791,59792],{"class":753},"registries",[747,59794,19444],{"class":757},[747,59796,20689],{"class":1640},[747,59798,59799,59801,59803,59805],{"class":749,"line":806},[747,59800,20579],{"class":757},[747,59802,8881],{"class":802},[747,59804,3892],{"class":757},[747,59806,20595],{"class":1640},[747,59808,59809],{"class":749,"line":814},[747,59810,4268],{"class":1640},[747,59812,59813],{"class":749,"line":822},[747,59814,5986],{"class":757},[523,59816,59817,59818,59821],{},"The change is to uncomment\u002F add ",[567,59819,59820],{},"\"docker.io\","," to the list of \"default\"\u002F unqualified registries to pull from.",[523,59823,59824],{},"Also I recommend you to change the following other values too:",[668,59826,59827,59841,59847],{},[638,59828,59829,59832,59833,59836,59837,59840],{},[567,59830,59831],{},"storage_driver = \"\""," - To ",[567,59834,59835],{},"storage_driver = \"overlay\""," to use overlay storage for the containers and images. ",[567,59838,59839],{},"overlay"," is the default, but it is good to \"enforce\" a default in case that may change at one point.",[638,59842,59843,59846],{},[567,59844,59845],{},"pids_limit = 10240"," (or higher) - Set the maximum process ID limit for a container.",[638,59848,59849,59852],{},[567,59850,59851],{},"enable_shared_pid_namespace = false"," - Enable shared Process ID namespace between containers of a Pod (depends on if you want\u002F need it).",[523,59854,59855,59856,59859,59860,3052],{},"You may also need to change the ",[567,59857,59858],{},"network_dir"," config option to reflect the CNI (config) path used by your setup (default is ",[567,59861,59862],{},"\u002Fetc\u002Fcni\u002Fnet.d\u002F",[6072,59864,59865,59869,59875],{},[523,59866,59867],{},[584,59868,6189],{},[523,59870,59871,59872,59874],{},"The full ",[567,59873,59752],{}," I am using is available on GitHub as a Gist:",[50035,59876,59877,59880],{},[14525,59878,59879],{},"GitHub Gist - galexrt - My current CRI-O config file - **Click to expand**",[19016,59881],{"src":59882},"https:\u002F\u002Fgist.github.com\u002Fgalexrt\u002F5ff3b48994328368330949a8ed0634ea.js",[523,59884,59885],{},"Now that CRI-O is ready to be used, we can continue to configure Kubelet to use CRI-O.",[535,59887,59889],{"id":59888},"step-5-configure-kubelet-to-use-cri-o","Step 5 - Configure Kubelet to use CRI-O",[523,59891,59892,59893,856],{},"The following flags need to be added to the ",[567,59894,59895],{},"kubelet.service",[668,59897,59898,59907,59913,59919],{},[638,59899,59900,59903,59904,1909],{},[567,59901,59902],{},"--container-runtime=remote"," - Use the Container Runtime ",[567,59905,59906],{},"remote",[638,59908,59909,59912],{},[567,59910,59911],{},"--container-runtime-endpoint=unix:\u002F\u002F\u002Frun\u002Fcrio\u002Fcrio.sock"," - Where the Container Runtime can be reached.",[638,59914,59915,59918],{},[567,59916,59917],{},"--image-service-endpoint=unix:\u002F\u002F\u002Frun\u002Fcrio\u002Fcrio.sock"," - Where the (Container Runtime) Image Service endpoint can be reached.",[638,59920,59921,59924],{},[567,59922,59923],{},"--runtime-request-timeout=10m"," - Timeout for Container Runtime requests.",[523,59926,59927,59928,59931,59932,2006],{},"(If you are using dynamic kubelet configuration files, the option to change is ",[567,59929,59930],{},"criSocket:",". Set it to ",[567,59933,59934],{},"criSocket: \u002Frun\u002Fcrio\u002Fcrio.sock",[523,59936,59937,59938,59940,59941,856],{},"The below snippet is from a ",[567,59939,59895],{}," that uses the ",[567,59942,59943],{},"\u002Fusr\u002Flib\u002Fcoreos\u002Fkubelet-wrapper",[738,59945,59947],{"className":32095,"code":59946,"language":32097,"meta":743,"style":743},"ExecStart=\u002Fusr\u002Flib\u002Fcoreos\u002Fkubelet-wrapper \\\n[...]\n  --container-runtime=remote \\\n  --container-runtime-endpoint=unix:\u002F\u002F\u002Frun\u002Fcrio\u002Fcrio.sock \\\n  --image-service-endpoint=unix:\u002F\u002F\u002Frun\u002Fcrio\u002Fcrio.sock \\\n  --runtime-request-timeout=10m \\\n[...]\n",[567,59948,59949,59958,59962,59974,59986,59997,60009],{"__ignoreMap":743},[747,59950,59951,59953,59955],{"class":749,"line":750},[747,59952,59251],{"class":753},[747,59954,6425],{"class":757},[747,59956,59957],{"class":1640},"\u002Fusr\u002Flib\u002Fcoreos\u002Fkubelet-wrapper \\\n",[747,59959,59960],{"class":749,"line":761},[747,59961,5986],{"class":757},[747,59963,59964,59966,59969,59971],{"class":749,"line":769},[747,59965,46488],{"class":1640},[747,59967,59968],{"class":753},"container-runtime",[747,59970,6425],{"class":757},[747,59972,59973],{"class":1640},"remote \\\n",[747,59975,59976,59978,59981,59983],{"class":749,"line":776},[747,59977,46488],{"class":1640},[747,59979,59980],{"class":753},"container-runtime-endpoint",[747,59982,6425],{"class":757},[747,59984,59985],{"class":1640},"unix:\u002F\u002F\u002Frun\u002Fcrio\u002Fcrio.sock \\\n",[747,59987,59988,59990,59993,59995],{"class":749,"line":784},[747,59989,46488],{"class":1640},[747,59991,59992],{"class":753},"image-service-endpoint",[747,59994,6425],{"class":757},[747,59996,59985],{"class":1640},[747,59998,59999,60001,60004,60006],{"class":749,"line":790},[747,60000,46488],{"class":1640},[747,60002,60003],{"class":753},"runtime-request-timeout",[747,60005,6425],{"class":757},[747,60007,60008],{"class":1640},"10m \\\n",[747,60010,60011],{"class":749,"line":796},[747,60012,5986],{"class":757},[523,60014,60015,60016,1909],{},"More details on the flags and\u002F or commands can be found at ",[527,60017,59376,60020],{"href":60018,"rel":60019},"https:\u002F\u002Fgithub.com\u002Fcri-o\u002Fcri-o\u002Fblob\u002Fmaster\u002Ftutorials\u002Fkubernetes.md#preparing-kubelet",[531],[567,60021,60022],{},"kubernetes.md",[523,60024,60025,60026,60028,60029,60032,60033,60035,60036,60039],{},"Additionally you need to add a mount for the host path ",[567,60027,58791],{}," to the same path in the ",[567,60030,60031],{},"kubelet-wrapper",", that is so that the ",[567,60034,26920],{}," is able to reach the CRI-O binaries as they were\u002F are not shipped within the ",[567,60037,60038],{},"gcr.io\u002Fgoogle-containers\u002Fhyperkube-amd64"," images.\nThe lines for that will look like that:",[738,60041,60043],{"className":32095,"code":60042,"language":32097,"meta":743,"style":743},"    --volume opt-bin,kind=host,source=\u002Fopt\u002Fbin,readOnly=true \\\n    --mount volume=opt-bin,target=\u002Fopt\u002Fbin \\\n",[567,60044,60045,60073],{"__ignoreMap":743},[747,60046,60047,60050,60052,60054,60057,60060,60062,60065,60068,60070],{"class":749,"line":750},[747,60048,60049],{"class":1640},"    --volume opt-bin,",[747,60051,12963],{"class":753},[747,60053,6425],{"class":757},[747,60055,60056],{"class":1640},"host,",[747,60058,60059],{"class":753},"source",[747,60061,6425],{"class":757},[747,60063,60064],{"class":1640},"\u002Fopt\u002Fbin,",[747,60066,60067],{"class":753},"readOnly",[747,60069,6425],{"class":757},[747,60071,60072],{"class":1640},"true \\\n",[747,60074,60075,60078,60081,60083,60086,60088,60090],{"class":749,"line":761},[747,60076,60077],{"class":1640},"    --mount ",[747,60079,60080],{"class":753},"volume",[747,60082,6425],{"class":757},[747,60084,60085],{"class":1640},"opt-bin,",[747,60087,46435],{"class":753},[747,60089,6425],{"class":757},[747,60091,60092],{"class":1640},"\u002Fopt\u002Fbin \\\n",[523,60094,60095,60096,60099,60100,60102,60103,2006],{},"(These lines need to be added to the ",[567,60097,60098],{},"RKT_RUN_ARGS"," environment variable in your ",[567,60101,59895],{}," unit file, example on how this can look like can be found here: ",[527,60104,60107],{"href":60105,"rel":60106},"https:\u002F\u002Fgithub.com\u002Fcoreos\u002Fcoreos-kubernetes\u002Fblob\u002Fmaster\u002FDocumentation\u002Fkubelet-wrapper.md#allow-pods-to-use-rbd-volumes",[531],"kubelet-wrapper \"Allow pods to use rbd volumes\" documentation- coreos\u002Fcoreos-kubernetes GitHub repository",[523,60109,60110,60111,60114,60115,60117,60118,60120,60121,60123,60124,60127,60128,60130,60131,60134,60135,60137],{},"After that we should add the ",[567,60112,60113],{},"crio.service"," as a dependency to the ",[567,60116,59895],{},", this causes systemd to start up ",[567,60119,26920],{}," only after ",[567,60122,60113],{}," is running. This can be achieved by adding\u002F editing the ",[567,60125,60126],{},"After="," section in your ",[567,60129,59895],{}," unit file.\nIf ",[567,60132,60133],{},"docker.service"," is in the ",[567,60136,60126],{}," section, go ahead and remove it.",[523,60139,60140],{},"It should look like this:",[738,60142,60144],{"className":32095,"code":60143,"language":32097,"meta":743,"style":743},"[Unit]\n...\nAfter=crio.service\n...\n",[567,60145,60146,60150,60154,60162],{"__ignoreMap":743},[747,60147,60148],{"class":749,"line":750},[747,60149,59137],{"class":757},[747,60151,60152],{"class":749,"line":761},[747,60153,3546],{"class":1640},[747,60155,60156,60158,60160],{"class":749,"line":769},[747,60157,59172],{"class":753},[747,60159,6425],{"class":757},[747,60161,59412],{"class":1640},[747,60163,60164],{"class":749,"line":776},[747,60165,3546],{"class":1640},[523,60167,60168],{},"Now that the CRI-O and Kubelet Systemd service units have been created and\u002For modified we need to reload Systemd:",[738,60170,60172],{"className":1621,"code":60171,"language":1623,"meta":743,"style":743},"systemctl daemon-reload\n",[567,60173,60174],{"__ignoreMap":743},[747,60175,60176,60178],{"class":749,"line":750},[747,60177,3202],{"class":1630},[747,60179,60180],{"class":802}," daemon-reload\n",[535,60182,60184],{"id":60183},"step-6-start-cri-o-and-restart-kubelet","Step 6 - Start CRI-O and restart Kubelet",[738,60186,60188],{"className":1621,"code":60187,"language":1623,"meta":743,"style":743},"systemctl enable crio.service crio-shutdown.service\nsystemctl start crio.service crio-shutdown.service\n",[567,60189,60190,60202],{"__ignoreMap":743},[747,60191,60192,60194,60196,60199],{"class":749,"line":750},[747,60193,3202],{"class":1630},[747,60195,3205],{"class":802},[747,60197,60198],{"class":802}," crio.service",[747,60200,60201],{"class":802}," crio-shutdown.service\n",[747,60203,60204,60206,60208,60210],{"class":749,"line":761},[747,60205,3202],{"class":1630},[747,60207,3215],{"class":802},[747,60209,60198],{"class":802},[747,60211,60201],{"class":802},[6072,60213,60214],{},[523,60215,60216,38011,60218,60221,60222,6374,60225,60228,60229,1909],{},[584,60217,6189],{},[567,60219,60220],{},".service"," can be omitted in this case as there is no other unit (example ",[567,60223,60224],{},".mount",[567,60226,60227],{},".device",") with that name. For more info on that please refer to the ",[527,60230,60233],{"href":60231,"rel":60232},"https:\u002F\u002Fwww.freedesktop.org\u002Fsoftware\u002Fsystemd\u002Fman\u002Fsystemctl.html",[531],"Systemd man pages",[523,60235,60236],{},"If there was no error during the start CRI-O, you are ready to restart Kubelet and let it start the containers through CRI-O:",[738,60238,60240],{"className":1621,"code":60239,"language":1623,"meta":743,"style":743},"systemctl restart kubelet.service\n",[567,60241,60242],{"__ignoreMap":743},[747,60243,60244,60246,60248],{"class":749,"line":750},[747,60245,3202],{"class":1630},[747,60247,41061],{"class":802},[747,60249,60250],{"class":802}," kubelet.service\n",[523,60252,60253,60254,1909],{},"If you want to make sure that Kubelet uses CRI-O successfully, you can check the logs of Kubelet by running ",[567,60255,60256],{},"journalctl -u kubelet -xe",[523,60258,60259,60260,1909],{},"Now that Kubelet should use CRI-O as the Container Runtime (CRI), you can move on the ",[527,60261,60263],{"href":60262},"#Step-7-Test-your-new-Container-Runtime","Step 7 - Test your new Container Runtime",[535,60265,60267],{"id":60266},"step-8-test-your-new-container-runtime","Step 8 - Test your new Container Runtime",[523,60269,60270],{},"There are multiple ways to test if CRI-O starts containers:",[668,60272,60273,60300,60308],{},[638,60274,60275,60285,60286,60289,60290,60292,60293,1909],{},[527,60276,60279,19221,60282],{"href":60277,"rel":60278},"https:\u002F\u002Fgithub.com\u002Fkubernetes-incubator\u002Fcri-tools",[531],[567,60280,60281],{},"cri-tools",[567,60283,60284],{},"crictl"," can list the containers and images on the node. Example to list the containers: ",[567,60287,60288],{},"crictl --image-endpoint=\u002Frun\u002Fcrio\u002Fcrio.sock --runtime-endpoint=\u002Frun\u002Fcrio\u002Fcrio.sock ps",", for more information on how to use ",[567,60291,60284],{}," see ",[527,60294,59614,60297],{"href":60295,"rel":60296},"https:\u002F\u002Fgithub.com\u002Fkubernetes-incubator\u002Fcri-tools\u002Fblob\u002Fmaster\u002Fdocs\u002Fcrictl.md",[531],[567,60298,60299],{},"docs\u002Fcrictl.md",[638,60301,60302,60304,60305,1909],{},[567,60303,39903],{}," can be used like this: ",[567,60306,60307],{},"runc list",[638,60309,60310,60311,1909],{},"Kubernetes shows you the Pod status per node: ",[567,60312,60313],{},"kubectl get --all-namespaces pods -o wide | grep $NODE_NAME",[535,60315,60317,60318],{"id":60316},"step-9-disable-and-stop-dockerservice","Step 9 - Disable and stop ",[567,60319,60133],{},[523,60321,60322,60323,60325],{},"Now that we are sure containers are running fine with CRI-O, go ahead stop and disable the ",[567,60324,60133],{}," on the host(s) using the following commands:",[738,60327,60329],{"className":1621,"code":60328,"language":1623,"meta":743,"style":743},"systemctl stop docker.service\nsystemctl disable docker.service\n\n## If you want to make extra sure Docker will never start up again on the hosts, run:\nsystemctl mask docker.service\n",[567,60330,60331,60339,60348,60352,60357],{"__ignoreMap":743},[747,60332,60333,60335,60337],{"class":749,"line":750},[747,60334,3202],{"class":1630},[747,60336,5324],{"class":802},[747,60338,3208],{"class":802},[747,60340,60341,60343,60346],{"class":749,"line":761},[747,60342,3202],{"class":1630},[747,60344,60345],{"class":802}," disable",[747,60347,3208],{"class":802},[747,60349,60350],{"class":749,"line":769},[747,60351,1255],{"emptyLinePlaceholder":1254},[747,60353,60354],{"class":749,"line":776},[747,60355,60356],{"class":772},"## If you want to make extra sure Docker will never start up again on the hosts, run:\n",[747,60358,60359,60361,60364],{"class":749,"line":784},[747,60360,3202],{"class":1630},[747,60362,60363],{"class":802}," mask",[747,60365,3208],{"class":802},[523,60367,60368,60369,60371,60372,60375,60376,1909],{},"This masks the ",[567,60370,60133],{},", systemd will then symlink ",[567,60373,60374],{},"\u002Fdev\u002Fnull"," \"in place\" of the ",[567,60377,60133],{},[535,60379,207],{"id":26330},[613,60381,60383,60384,60386],{"id":60382},"timeout-or-connection-refuesd-when-trying-to-kubectl-exec-into-a-pod","\"Timeout\" or \"Connection refuesd\" when trying to ",[567,60385,16258],{}," into a Pod",[523,60388,60389,60390,60393,60394,60397],{},"If you have a firewall on the nodes, you may need to allow CRI-O's so called ",[567,60391,60392],{},"stream_port"," which is by default listening on ",[567,60395,60396],{},"10010\u002FTCP",". It needs to be accessible by the Kubernetes masters.",[535,60399,14526],{"id":14525},[523,60401,60402,60403,60406],{},"This should get you started with installing and running ",[527,60404,401],{"href":58406,"rel":60405},[531]," for Kubernetes on Container Linux (previously CoreOS).",[523,60408,60409,60410,60415,60416,60421],{},"You can basically put most of these \"copy files commands\" into your ",[527,60411,60414],{"href":60412,"rel":60413},"https:\u002F\u002Fcoreos.com\u002Fos\u002Fdocs\u002Flatest\u002Fcluster-architectures.html",[531],"Container Linux\u002F Ignition Config",", even ",[527,60417,60420],{"href":60418,"rel":60419},"https:\u002F\u002Fcloudinit.readthedocs.io\u002Fen\u002Flatest\u002Findex.html",[531],"cloud-config"," would be one way to automate it during OS install\u002F boot.",[523,60423,60424],{},"For questions about the post, please leave a comment below, thanks!",[523,60426,13967],{},[2890,60428,60429],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}",{"title":743,"searchDepth":761,"depth":761,"links":60431},[60432,60435,60436,60437,60440,60441,60442,60443,60444,60445,60447,60451],{"id":537,"depth":761,"text":538,"children":60433},[60434],{"id":22267,"depth":769,"text":22268},{"id":58476,"depth":761,"text":58477},{"id":58508,"depth":761,"text":58509},{"id":58721,"depth":761,"text":58722,"children":60438},[60439],{"id":59024,"depth":769,"text":59025},{"id":59111,"depth":761,"text":59112},{"id":59510,"depth":761,"text":59511},{"id":59888,"depth":761,"text":59889},{"id":60183,"depth":761,"text":60184},{"id":60266,"depth":761,"text":60267},{"id":60316,"depth":761,"text":60446},"Step 9 - Disable and stop docker.service",{"id":26330,"depth":761,"text":207,"children":60448},[60449],{"id":60382,"depth":769,"text":60450},"\"Timeout\" or \"Connection refuesd\" when trying to kubectl exec into a Pod",{"id":14525,"depth":761,"text":14526},"2018-03-06T21:14:11+02:00","This post is containing steps on how you can install CRI-O on Container Linux.",{"src":60455},"\u002Fblog\u002Fcovers\u002Fcrio-container-linux-logos.png",{"tags":60457},[26415,401,124,58416],"\u002Fblog\u002F2018\u002Fcri-o-container-linux-how-to-install",{"title":58372,"description":60453},"3.blog\u002F2018\u002Fcri-o-container-linux-how-to-install","c5_U4jcLAQ5_jCcgusb0OiPgSlWqojXTecCInNZNZho",{"id":60463,"title":60464,"authors":60465,"badge":518,"body":60468,"date":61362,"description":61363,"extension":2911,"image":61364,"meta":61365,"navigation":1254,"path":61367,"seo":61368,"stem":61369,"__hash__":61370},"posts\u002F3.blog\u002F2018\u002Fceph-day-germany-2018.md","Ceph Day Darmstadt 2018",[60466],{"name":514,"to":515,"avatar":60467},{"src":517},{"type":520,"value":60469,"toc":61342},[60470,60484,60486,60492,60495,60501,60503,60507,60510,60514,60517,60520,60528,60546,60552,60555,60564,60572,60575,60590,60599,60602,60609,60612,60615,60621,60624,60627,60631,60642,60645,60651,60662,60665,60671,60674,60681,60684,60687,60694,60698,60706,60709,60717,60720,60723,60729,60732,60735,60752,60755,60760,60763,60766,60769,60772,60781,60790,60797,60804,60807,60813,60816,60819,60826,60829,60840,60843,60846,60849,60852,60860,60863,60867,60873,60876,60882,60885,60889,60892,60898,60901,60907,60910,60913,60922,60925,60931,60934,60938,60941,60947,60950,60957,60963,60966,60975,60978,60981,60984,60990,61002,61005,61008,61014,61017,61020,61024,61027,61033,61036,61039,61045,61048,61054,61057,61064,61068,61071,61074,61077,61085,61088,61105,61108,61114,61117,61121,61124,61130,61133,61141,61148,61152,61158,61209,61212,61215,61219,61225,61228,61235,61238,61244,61250,61253,61256,61262,61265,61271,61274,61281,61285,61288,61294,61301,61305,61311,61314,61317,61321,61327,61330,61332,61335,61337,61339],[6072,60471,60472,60476,60478,60482],{},[523,60473,60474],{},[584,60475,6189],{},[523,60477,51254],{},[523,60479,60480],{},[584,60481,6189],{},[523,60483,51261],{},[535,60485,51277],{"id":51276},[523,60487,60488],{},[3069,60489],{"alt":60490,"src":60491},"On my way to Ceph Day Darmstadt 2018","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_084118.jpg",[523,60493,60494],{},"We got some small sweet breakfast snacks and coffee to start the day off!",[523,60496,60497],{},[3069,60498],{"alt":60499,"src":60500},"Ceph Day Darmstadt 2018 Kickoff","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_091357.jpg",[535,60502,51330],{"id":51329},[613,60504,60506],{"id":60505},"ceph-luminous-is-out-whats-in-it-for-you-john-spray-red-hat","Ceph Luminous is out what's in it for you? - John Spray (Red Hat)",[523,60508,60509],{},"Ceph is going to use a new\u002Fchanged release cadence. The new release cadence is as follows, that a new stable release is made every 9 month.\nAdditionally to that, the upgrade is only supported from version N-2.",[3126,60511,60513],{"id":60512},"luminous-release","Luminous Release",[523,60515,60516],{},"There is a new OSD backend: BlueStore.\nIt is faster (than FileStore?) on HDDs (~2x), SSDs (~1.5x). BlueStore calculates data checksums which can be used for erasure code. This also allows for smaller journals.\nTo further decrease the amount of data saved, in-line compression is possible now.",[523,60518,60519],{},"It is now possible to run RBD & CephFS on erasure coded pools (at least the data pools).\nThere have been significant improvements in efficiency for erasure coded pools. Keep the following points in mind:",[668,60521,60522,60525],{},[638,60523,60524],{},"Small writes are slower than replication (more bytes to disk)",[638,60526,60527],{},"Large writes are faster than replication (fewer bytes to disk)",[523,60529,60530,60531,714,60536,714,60541,60545],{},"The Ceph MGR component is now a mandatory part of the cluster.\nModules for the MGR are available for ",[527,60532,60535],{"href":60533,"rel":60534},"http:\u002F\u002Fdocs.ceph.com\u002Fdocs\u002Fmaster\u002Fmgr\u002Fzabbix\u002F",[531],"zabbix",[527,60537,60540],{"href":60538,"rel":60539},"http:\u002F\u002Fdocs.ceph.com\u002Fdocs\u002Fmaster\u002Fmgr\u002Finflux\u002F",[531],"influxdb",[527,60542,27270],{"href":60543,"rel":60544},"http:\u002F\u002Fdocs.ceph.com\u002Fdocs\u002Fmaster\u002Fmgr\u002Fprometheus\u002F",[531],", etc.\nThrough the move out of certain performance stats collections the MON performance should be improved.",[523,60547,60548],{},[3069,60549],{"alt":60550,"src":60551},"Ceph Day Darmstadt 2018 - Ceph Luminous - Ceph MGR","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_092358.jpg",[523,60553,60554],{},"There has also been a (modernized) dashboard for Ceph, but it is read-only (it is not a configuration tool).",[523,60556,8764,60557,60559,60560,60563],{},[567,60558,14930],{}," commands have been cleaned up a lot. ",[567,60561,60562],{},"ceph status"," is not so verbose anymore.\nAn example of \"removed\" verboseness is the PG status. Previously the PG status was shown for \"every\" state PGs where in.\nBut what counts for you, when checking the cluster status:",[668,60565,60566,60569],{},[638,60567,60568],{},"How many PGs are healthy?",[638,60570,60571],{},"How many PGs are in an unhealthy?",[523,60573,60574],{},"This, let's call \"domination\", has also been reduced in the logs (unless otherwise specified by a logging options\u002Fflag).",[523,60576,60577,60578,60581,60582,60585,60586,60589],{},"The new ",[567,60579,60580],{},"AsyncMessenger"," should remove the need to have to increase the ",[567,60583,60584],{},"ulimit"," on nodes because there is now a fixed size thread pool for the messenger.\n",[567,60587,60588],{},"DPDK"," from Intel is going to be a way to support new faster storage devices in point of the network, so it won't be the bottleneck.",[6072,60591,60592],{},[523,60593,60594,60595],{},"DPDK is a set of libraries and drivers for fast packet processing.\nSee ",[527,60596,60597],{"href":60597,"rel":60598},"https:\u002F\u002Fgithub.com\u002Fceph\u002Fdpdk",[531],[523,60600,60601],{},"OSD balance is a way to move single PGs to other OSDs, which can be a good feature to further balance OSDs either by automated orchestration or manual labor.\nSome new features though, require Ceph\u002FRBD clients with Luminous or higher.",[523,60603,60604,60605,60608],{},"A lot of overall improvements to RADOS, like ",[567,60606,60607],{},"require_min_compat_client"," to \"force\" a certain minimum client versions (aka no communication with clients lower than VERSION).",[523,60610,60611],{},"CephFS now supports multiple active MDS daemons with that you can scale out your metadata performance by simply adding more MDS instances.\n(Directory) Subtree pinning allows to isolate certain workloads (directories), by \"pinning\" directories to specific MDS servers ~= work distribution.\nI think this is awesome to be used with an orchestration mechanism to distribute certain directories (which are heavily used) automatically to \"bigger\" MDS nodes\u002Fservers.\nThe large directory fragmentation support is now enabled by default.",[523,60613,60614],{},"RGW S3 has now the (AWS) S3 encryption API implemented and dynamic bucket index sharding has been added.",[523,60616,60617],{},[3069,60618],{"alt":60619,"src":60620},"Ceph Day Darmstadt 2018 - Ceph Luminous - RGW Metadata search","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_093423.jpg",[523,60622,60623],{},"It is now also possible to use a tool, like Elasticsearch, to do metadata searches.",[523,60625,60626],{},"ISCSI support has been added for RBD.\nThe kernel RBD module has been updated with the \"latest\" features, which is awesome.",[3126,60628,60630],{"id":60629},"mimic","Mimic",[523,60632,60633,60634,12735,60636,60638,60639,60641],{},"The Ceph MONs will now do\u002Fallow for a central configuration of the components. To bring Kubernetes in this, this seems like what is currently going on with the ",[567,60635,26920],{},[567,60637,26920],{}," will soon be able to be configured by the \"apiserver\", which will ease the deployment of (many) ",[567,60640,26920],{},"s.",[523,60643,60644],{},"Optimizations to the PG peering, which will be helpful for users that have network flaps from time to time that cause network \"outages\".\nImprovements for Erasure Coding (EC) for single OSD failures.",[523,60646,60647],{},[3069,60648],{"alt":60649,"src":60650},"Ceph Day Darmstadt 2018 - Ceph Luminous - Other RADOS improvements","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_092959.jpg",[523,60652,60653,60654,60661],{},"Quality of service (QoS) is another constant point of constant work.\nContinued development on ",[527,60655,60658],{"href":60656,"rel":60657},"https:\u002F\u002Fgithub.com\u002Fceph\u002Fdmclock",[531],[567,60659,60660],{},"dmclock",", a distributed QoS algorithm (for \"speed\" reservations).\nThere is already a promising prototype available.\n\"Speed\" reservations would allow an admin to \"reserve\" storage speed (Mbit\u002Fs) by clients.",[523,60663,60664],{},"Another thing is tiering which has already been in many Ceph releases.",[523,60666,60667,60668,60670],{},"A new ",[567,60669,58039],{}," primitive has been added. It is like a symlink to data (\u002Fan object).",[523,60672,60673],{},"Deduplication is also a topic which will most likely done through hashing.",[6072,60675,60676],{},[523,60677,60678,60680],{},[584,60679,15250],{}," Keep in mind the law of your country! At least for Darmstadt it seems that you must store the data the same way the user has by law.",[523,60682,60683],{},"Still a point of research of deduplication is if it should be done inline, async or as an agent.",[523,60685,60686],{},"The Ceph MGR will receive improvements to modules and overall \"infrastructure\" of it.\nAdditionally to that the rebuild reporting has been improved to show a progress bar instead of only a list of PGs.",[523,60688,60689,60690,1909],{},"ARM builds will be further improved in point of (more) official builds.\nThey are very useful for example for embedded systems that sit directly on a disk or overall cheap ARM servers.\nTo contribute to the \"ARM cause\" hardware can be contributed to Ceph.\nIf you want to hear more about ARM, this talk from this Ceph Day maybe interesting for your: ",[527,60691,60693],{"href":60692},"#A-flexible-ARM-based-Ceph-solution-Mohammad-Ammar-Starline","A flexible ARM-based Ceph solution - Mohammad Ammar (Starline)",[613,60695,60697],{"id":60696},"email-storage-with-ceph-danny-al-gaaf-deutsche-telekom-ag","Email Storage with Ceph - Danny Al-Gaaf (Deutsche Telekom AG)",[523,60699,60700,60701,1909],{},"Slides can be found at ",[527,60702,60705],{"href":60703,"rel":60704},"https:\u002F\u002Fdalgaaf.github.io\u002Fcephday-Darmstadt-emailstorage\u002F",[531],"dalgaaf\u002Fcephday-Darmstadt-emailstorage GitHub page",[523,60707,60708],{},"They are using Dovecot with \"simple\" Network Attached Storage (NAS).\nHaving the following stats:",[668,60710,60711,60714],{},[638,60712,60713],{},"~39 million accounts",[638,60715,60716],{},"~1.3 Petabyte of emails",[523,60718,60719],{},"With NFS most operations are to check access to files and checking for existence of files.\nBut trafficwise the most are write and followed by read.",[523,60721,60722],{},"Email size distribution:",[523,60724,60725],{},[3069,60726],{"alt":60727,"src":60728},"Ceph Day Darmstadt 2018 - Email Storage - Email Distribution","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_095818.jpg",[523,60730,60731],{},"WORM = Written Once Read Many (especially for emails).\nDepending on which entrypoint (protocol, webmailer) the users go the traffic is different, due to differences in the implementations of IMAP, POP3 protocol and mailer vs webmailer.",[523,60733,60734],{},"Their motivation behind using Ceph is:",[668,60736,60737,60740,60743,60746,60749],{},[638,60738,60739],{},"Faster (than NFS)",[638,60741,60742],{},"Automatic self healing",[638,60744,60745],{},"Less IO overhead",[638,60747,60748],{},"Prevent vendor lockin",[638,60750,60751],{},"Reduce costs with Open Source",[523,60753,60754],{},"CephFS was not an option because of the same issues as with NFS. With NFS and CephFS, mails have to go through \"every\" POSIX layer of the filesystem before being \"written\".\nAlso CephFS requires full access to the storage network to be able to work.",[668,60756,60757],{},[638,60758,60759],{},"RBD would be impractical, because of \"only one mount\" (ReadWriteMany), additionally also the point of again requiring full access to the storage network.",[523,60761,60762],{},"Ceph RGW does not need a direct\u002F\"full\" storage network access, also it can be secured by a Level 7 Web Application Firewall (WAF).",[523,60764,60765],{},"librados allows for direct access to RADOS. But it is not originally made for mail handling, issues with how to handle cache\u002Findexes came up. Again the security point arose, that librarods requires access to the \"full\" storage network.",[523,60767,60768],{},"Dovecot has a high market share 72%.\nThere was already an object store plugin available for Dovecot but it is paid by the number of email accounts.\nDeutsche Telekom's approach was that closed source was not an option. They have \"another\" company, named Tallence AG, doing the coding for them.",[523,60770,60771],{},"They will do\u002Fdid a \"migration\" in multiple steps:\nFirs step was to put mails in RADOS directly with a generic email abstraction on top of librados.\nMetadata and indexes where placed on CephFS.",[523,60773,60774,60775,60780],{},"librmb is a mail object format.\nMails are immutable regarding ",[527,60776,60779],{"href":60777,"rel":60778},"https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc5322",[531],"RFC-5322",".\nA simple rmbd tool has been build to get metadata information to be able test it quickly.",[523,60782,60783,60784,60789],{},"It's open source!: ",[527,60785,60788],{"href":60786,"rel":60787},"https:\u002F\u002Fgithub.com\u002Fceph-dovecot",[531],"GitHub ceph-dovecot",", it is written in C++.",[6072,60791,60792],{},[523,60793,60794,60796],{},[584,60795,6189],{}," They most likely chose C++ because of the optimized data path.",[523,60798,60799,60800],{},"The Ceph release they are currently utilizing is Luminous.\n",[3069,60801],{"alt":60802,"src":60803},"Ceph Day Darmstadt 2018 - Email Storage - Ceph Release used","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_101100_1.jpg",[523,60805,60806],{},"They use commodity x86_64 server hardware for Ceph, which further reduces costs.",[523,60808,60809],{},[3069,60810],{"alt":60811,"src":60812},"Ceph Day Darmstadt 2018 - Email Storage - Hardware Setup","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_101221.jpg",[523,60814,60815],{},"Why do they use such an overkill for CPU and memory in their servers? Because hardware vendors didn't offer single CPU and \"low\" memory for the number of drives they would use.\nTo note here for Ceph MDS, it seems work better the more RAM it has available.",[523,60817,60818],{},"They most of the time have two different fire compartments per datacenter.",[523,60820,60821,60822],{},"They have 4 x 10G between the switches:\n",[3069,60823],{"alt":60824,"src":60825},"Ceph Day Darmstadt 2018 - Email Storage - Network Setup","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_101601.jpg",[523,60827,60828],{},"They are testing their setup through:",[668,60830,60831,60834,60837],{},[638,60832,60833],{},"Load tests",[638,60835,60836],{},"Failure scenario tests",[638,60838,60839],{},"Exiting Ceph tests",[523,60841,60842],{},"One topic to solve for Ceph Erasure Coding (EC) is, to improve especially in point of small writes performance.",[523,60844,60845],{},"When everything works they will move to production, without any impact for the users.",[523,60847,60848],{},"They want to get rid of using CephFS for caches and indexes in the future too.",[523,60850,60851],{},"Summary of the move to Ceph:",[668,60853,60854,60857],{},[638,60855,60856],{},"Ceph can replace NFS (in a good way).",[638,60858,60859],{},"librmb and Dovecot rbox are Open Source projects.",[523,60861,60862],{},"They mentioned that data deduplication is potentially legally forbidden for user data.",[613,60864,60866],{"id":60865},"email-objects-in-rados-peter-mauritius-tallence-ag","Email Objects in RADOS - Peter Mauritius (Tallence AG)",[523,60868,60869],{},[3069,60870],{"alt":60871,"src":60872},"Ceph Day Darmstadt 2018 - Email Objects - Dovecot Mail Storage","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_103805.jpg",[523,60874,60875],{},"Dovecot has a good plugin architecture which allows to easily write and integrate a plugin.\nThey use CephFS for the users mail and mailbox directory hierarchy, but not for the actual mails.\nMails are saved through librados directly as an object in kind of a hybrid storage, as the caches and indexes are still maintained by Dovecot on CephFS.",[523,60877,60878],{},[3069,60879],{"alt":60880,"src":60881},"Ceph Day Darmstadt 2018 - Email Objects - What will be stored?","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_104538.jpg",[523,60883,60884],{},"A lot of xattr\u002Fomap on an OSD (more than millions), may lead to an unstable OSD.",[613,60886,60888],{"id":60887},"ceph-at-sap-how-to-build-a-cattle-cloud-marc-koderer-sap-jan-fajerski-suse","Ceph at SAP – How to build a cattle cloud - Marc Koderer (SAP)\u002F Jan Fajerski (SUSE)",[523,60890,60891],{},"Building a cloud native application\u002Fservice is not easy.",[523,60893,60894],{},[3069,60895],{"alt":60896,"src":60897},"Ceph Day Darmstadt 2018 - Ceph at SAP - Traditional vs cloud native Applications","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_112514.jpg",[523,60899,60900],{},"To protect a Ceph object store, you should start at the application layer, to limit the connections and have a \"loop back off\" for GET\u002FPOST\u002FPUT, etc.\nIf not implemented in the application, can also be done in the Loadbalancers by utilizing rate limiting and even blacklisting.",[523,60902,60903],{},[3069,60904],{"alt":60905,"src":60906},"Ceph Day Darmstadt 2018 - Ceph at SAP - Ceph Overview","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_113136.jpg",[523,60908,60909],{},"Every availability zone has the same store capacity and hardware.\nFor replication they use 2x 25Gbit for each backend and frontend.\nTheir setup is designed to compensate the outage of one availability zone.",[523,60911,60912],{},"Again mentioned here is that through the removal of the filesystem POSIX layer (when FileStore is used) is, that BlueStore is faster.",[523,60914,60915,60916,60921],{},"They use ",[527,60917,60920],{"href":60918,"rel":60919},"https:\u002F\u002Fgithub.com\u002FSUSE\u002FDeepSea",[531],"GitHub SUSE\u002FDeepSea"," for deployment which is based on\u002Fuses Salt Stack.\nA goal of the deployment process is to minimize the manual work.\nThey have different stages for their deployments, example stage 0 is that all hardware is there and at the same state as every node (updates, etc).",[523,60923,60924],{},"For configuration of storage with Ceph, they have created something called \"Storage profiles\" these files are generated through their DeppSea hardware discovery and contain the disk configuration for each server\u002Fhost.",[523,60926,60927],{},[3069,60928],{"alt":60929,"src":60930},"Ceph Day Darmstadt 2018 - Ceph at SAP - Storage Profiles","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_114122.jpg",[523,60932,60933],{},"Ceph RGW with S3 support is especially good for applications because it is compatible with multiple cloud environments where S3 is offered as a service.\nFor example, you can use Ceph as S3 on premise and use AWS S3 in the AWS cloud.",[613,60935,60937],{"id":60936},"ceph-for-big-science-dan-van-der-ster-cern","Ceph for Big Science - Dan van der Ster (CERN)",[523,60939,60940],{},"They generate about 10 GB per second, and about 50 Petabyte per year.",[523,60942,60943],{},[3069,60944],{"alt":60945,"src":60946},"Ceph Day Darmstadt 2018 - Ceph for Big Science - Scale Testing","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_120110.jpg",[523,60948,60949],{},"They use virtual NFS filers currently with about ~60TB and ~30 servers. But this doesn't really scale performance wise.",[523,60951,60952,60956],{},[3069,60953],{"alt":60954,"src":60955},"Ceph Day Darmstadt 2018 - Ceph for Big Science - CephFS: Filer Evolution","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_120422.jpg","\nIt is good to hear that there will be a new CSI CephFS plugin.",[523,60958,60959],{},[3069,60960],{"alt":60961,"src":60962},"Ceph Day Darmstadt 2018 - Ceph for Big Science - Multi-MDS in Production","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_120636.jpg",[523,60964,60965],{},"They scaled up to two MDS with Luminous upgrade, as the multi MDS feature has been added.",[523,60967,60968,60969,60974],{},"CERN is building their HPC clusters from commodity parts to reduce costs.\n",[527,60970,60973],{"href":60971,"rel":60972},"https:\u002F\u002Fwww.vi4io.org\u002Fio500\u002Fstart",[531],"IO-500"," is a top list for fastest storage but not only the heroes should be on there, but also the anti-heroes with not so fast storage. The benchmarks for it will be published with the tuning parameters and configuration used.",[523,60976,60977],{},"Ceph RGW - S3 @ CERN\nThey use HAProxy to balance the load in front of the Ceph RGWs, to mitigate Ceph RGW restarts and direct traffic of \"special\" buckets to dedicated Ceph RGW instances.",[523,60979,60980],{},"Meletdown\u002FSpectre had something good for them (at least the storage team), as now they Hypervisors are not accessing the Ceph clusters with an old client version anymore.",[523,60982,60983],{},"There is a module in Luminous which allows to re-balance PGs from node to node, there are some things though that need to be kept in mind depending on which mode is used.",[523,60985,60986],{},[3069,60987],{"alt":60988,"src":60989},"Ceph Day Darmstadt 2018 - Ceph for Big Science - ceph balancer on","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_122717.jpg",[523,60991,60992,60993,60996,60997,1909],{},"If you have ",[567,60994,60995],{},"activating+rempped"," PGs, you should checkout the Ceph issue ",[527,60998,61001],{"href":60999,"rel":61000},"http:\u002F\u002Ftracker.ceph.com\u002Fissues\u002F22440",[531],"#22440New pgs per osd hard limit can cause peering issues on existing clusters",[613,61003,60693],{"id":61004},"a-flexible-arm-based-ceph-solution-mohammad-ammar-starline",[523,61006,61007],{},"ARM has a high cost effiency, because the prices are very low due to high competition in this hardware field.\nAttempts to run SoC (System on a Chip) systems with Ceph, can be seen in HDDs that come with an ARM processor.\nThere is also a broad range of ARM full server configurations available.\nAnother point is that has already been \"demonstrated\" with Raspberry Pi is, that ARM doesn't require much space to run.",[523,61009,61010],{},[3069,61011],{"alt":61012,"src":61013},"Ceph Day Darmstadt 2018 - A flexible ARM-based Ceph solution - Hardware Advantages","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_124643.jpg",[523,61015,61016],{},"It is feasible to run one such server as an entry level storage.\nTo scale up services such as Ceph MONs, OSDs would be pinned\u002Fmoved to other servers in the rack (example was with 3 servers each 1U, having each 1 Ceph MON).",[523,61018,61019],{},"Using ARM with Ceph combines the scalability and flexibility of Ceph with the cost efficiency and \"speed\" (of many servers) of ARM.\nWith the cost effiency also comes power efficiency, that further reduces costs.",[613,61021,61023],{"id":61022},"five-years-of-ceph-and-outlook-lars-marowsky-bree-suse","Five years of Ceph and Outlook - Lars Marowsky-Bree (SUSE)",[523,61025,61026],{},"The direction is set by the people who code or the people who pay people to code.\nThe SUSE Enterprise Storage is keeping up in a good manner with the upstream project and release cycle.",[523,61028,61029],{},[3069,61030],{"alt":61031,"src":61032},"Ceph Day Darmstadt 2018 - Five years of Ceph  and Outlook - SUSE Enterprise Storage 5","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_140825.jpg",[523,61034,61035],{},"The \"Enterprise\" part here mostly seems to come from a) support and b) orchestration (framework) around Ceph.\nA good orchestration layer helps with tasks such as upgrading FileStore OSDs to BlueStore.",[523,61037,61038],{},"For each filesystem, block storage and block use case, Ceph is a potential candidate.",[523,61040,61041],{},[3069,61042],{"alt":61043,"src":61044},"Ceph Day Darmstadt 2018 - Five years of Ceph  - Focus areas of SUSE Enterprise Storage 6","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_141516.jpg",[523,61046,61047],{},"CIFS\u002FSamba is not going away too soon in corporate environments.",[523,61049,61050],{},[3069,61051],{"alt":61052,"src":61053},"Ceph Day Darmstadt 2018 - Five years of Ceph  - Advice nobody asked for (and I wish they did)","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_141849.jpg",[523,61055,61056],{},"You can't just put in Ceph and never touch it again. It is, as always, with software, it grows and changes aka updates.\nDon't skimp on the network layer (you should at least have 40G network for Ceph).\nHeterogeneous environments are a good idea to not suffer a whole cluster failure on a bug for example in the network card.",[523,61058,61059,61060],{},"There are more possibilities to meet with the Ceph community this year.\n",[3069,61061],{"alt":61062,"src":61063},"Ceph Day Darmstadt 2018 - Five years of Ceph  - Interested? Join us for more!","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_142624.jpg",[613,61065,61067],{"id":61066},"ceph-management-and-monitoring-with-openattic-kai-wagner-suse","Ceph Management and Monitoring with openATTIC - Kai Wagner (SUSE)",[523,61069,61070],{},"There have been a lot of changes from the project start till now to the user interface.\nSince 2017 they have only focused on \"Ceph only\" (and first).",[523,61072,61073],{},"For deployments they are using Salt. They chose it as it is fast, allows for parallel execution and has a good scalability.\nSalt here is used with DeepSea for orchestration.\nopenATTIC allows management of iSCSI tagets via lrbd.\nFor MONitoring part it deploys Prometheus and Grafana.",[523,61075,61076],{},"After the decision to be a \"Ceph only user interface\", they set new goals such as:",[668,61078,61079,61082],{},[638,61080,61081],{},"To be a Open Source Ceph management and monitoring interface.",[638,61083,61084],{},"Scaling without becoming overwhelming.",[523,61086,61087],{},"Some features of openATTIC:",[668,61089,61090,61093,61096,61099,61102],{},[638,61091,61092],{},"Stateless",[638,61094,61095],{},"Ceph RGW management",[638,61097,61098],{},"Web-based configuration",[638,61100,61101],{},"Support for Ceph Luminous release features",[638,61103,61104],{},"And much more..",[523,61106,61107],{},"Outlook to the future of openATTIC and Ceph MGR:",[523,61109,61110],{},[3069,61111],{"alt":61112,"src":61113},"Ceph Day Darmstadt 2018 - Ceph Management and Monitoring - openATTIC goes upstream","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_144034.jpg",[523,61115,61116],{},"They want to go upstream with the user interface\u002Fdashboard: \"Change the logo\", become the new default dashboard for Ceph.",[613,61118,61120],{"id":61119},"ceph-performance-on-new-intel-platforms-and-ssds-mohamed-elsaid-intel","Ceph Performance on New Intel Platforms and SSDs - Mohamed Elsaid (Intel)",[523,61122,61123],{},"Intel® tries to be the \"power\" behind the hardware of today's storage software\u002Fvendors.",[523,61125,61126],{},[3069,61127],{"alt":61128,"src":61129},"Ceph Day Darmstadt 2018 - Ceph Performance on New Intel Platforms and SSDs - Ceph Benchmarking with Intel Purley, Skylake & Optane","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_151105.jpg",[523,61131,61132],{},"It was a very hardware heavy talk. A lot of performance diagrams.\nNot that this was not interesting, but if someone is searching appropriate hardware for the task he should get this information without a problem from Intel or other hardware vendors.",[523,61134,61135,61136,1909],{},"They have put up a site with part of these informations, see ",[527,61137,61140],{"href":61138,"rel":61139},"https:\u002F\u002Fstoragebuilders.intel.com\u002F",[531],"Intel® Storage Builders",[6072,61142,61143],{},[523,61144,61145,61147],{},[584,61146,6189],{}," Intel still doesn't get why everyone is \"pissed\" at them..\nOne of the X bugs, that is only working on Intel, is a good reason to be \"pissed\" at them. :)",[613,61149,61151],{"id":61150},"_10-ways-to-break-your-ceph-cluster-wido-den-hollander-42oncom","10 ways to break your Ceph cluster - Wido den Hollander (42on.com)",[523,61153,61154],{},[3069,61155],{"alt":61156,"src":61157},"Ceph Day Darmstadt 2018 - 10 ways to break your Ceph Cluster - Thank you!","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_160247_1.jpg",[635,61159,61160,61163,61166,61173,61176,61187,61194,61197,61200,61203,61206],{},[638,61161,61162],{},"Wrong CRUSH failure domain - Don't assume it is working, test the failover (before going live with it)!",[638,61164,61165],{},"Decommissioning a host - A disk failed in another system causing the data to get corrupt, during the removal of the other host. Only remove a node when the cluster is healthy (and has enough failover capacity).",[638,61167,61168,61169,61172],{},"Removing ",[567,61170,61171],{},"log"," files in MON's data directory - This deletes actual data required for the MONs to run. When backfills happen, the MONs data directory will grow (8 days backfill, grew to 45GB).",[638,61174,61175],{},"Removing the wrong pool - Double check before removal of \"anything\", as when a pool is gone, it is gone for real.",[638,61177,61178,61179,61182,61183,61186],{},"Setting the OSD ",[567,61180,61181],{},"noout"," flag for a \"long time\" - Don't run a system in ",[567,61184,61185],{},"HEALTH_WARN"," status (other ways would be to set minimal replicated data available to at least two or more).",[638,61188,61189,61190,61193],{},"Mounting XFS with ",[567,61191,61192],{},"nobarrier"," option - It can cause the FS to be corrupted and Ceph data lost.",[638,61195,61196],{},"Enabling Writeback on HBA without BBU - This should not be done unless you have a BBU!",[638,61198,61199],{},"Creating too many Placement Groups - Can cause an overdoes of the Ceph cluster in cases like power\u002Fnode failure.",[638,61201,61202],{},"Using 2x replication - If a node fails while you are doing for example maintenance, the data on the maintained node is outdated due to new writes to the other node PGs.",[638,61204,61205],{},"Underestimating Monitors - Use good hardware with enough resources (even though they don't use that much CPU or memory) the hardware should not fail easily (using SD-cards for MONs). Go for 5 MONs instead of backing the MONs up.",[638,61207,61208],{},"Updating Cephx keys with the wrong permissions - This can cause a huge failure for a cluster, the example shown was OSDs key without write permission to a pool, which caused corrupted filesystems for VMs.",[523,61210,61211],{},"A reasonable OSD count should be chosen depending on the information given on the Ceph PG calc page.",[523,61213,61214],{},"It was funny to hear the stories, as almost everyone had already experienced such a story for himself at one point in time.",[613,61216,61218],{"id":61217},"development-update-ceph-mgr-and-kubernetes-john-spray-red-hat","Development update: ceph-mgr and kubernetes - John Spray (Red Hat)",[523,61220,61221],{},[3069,61222],{"alt":61223,"src":61224},"Ceph Day Darmstadt 2018 - Development update: ceph-mgr and kubernetes - Managing Ceph in containers: ceph-mgr and Rook","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_161126.jpg",[523,61226,61227],{},"Currently managing Ceph is kinda fractured depending on how you deploy Ceph .",[523,61229,61230,61231],{},"\"Why hasn't everyone switched to Containers?\"\n",[3069,61232],{"alt":61233,"src":61234},"Ceph Day Darmstadt 2018 - Development update: ceph-mgr and kubernetes - Glorious Container Future","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_161353.jpg",[523,61236,61237],{},"Kubernetes is a tool to run containers. A tool for container orchestration which keeps a lot of points, like (cpu and memory) resources, in view while scheduling containers.",[523,61239,61240],{},[3069,61241],{"alt":61242,"src":61243},"Ceph Day Darmstadt 2018 - Development update: ceph-mgr and kubernetes - Rook","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_161714.jpg",[523,61245,61246],{},[3069,61247],{"alt":61248,"src":61249},"Ceph Day Darmstadt 2018 - Development update: ceph-mgr and kubernetes - How can we re-use the Rook operator","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_162521.jpg",[523,61251,61252],{},"Depending on how you see it, the \"user interface\" through YAML is problematic especially for destructive options where an user normally would be asked to confirm by adding multiple flags to the command.",[523,61254,61255],{},"John Spray kind of proposes to use Rook \"only\" to run the infrastructure around and not directly talk with Ceph except with the Ceph MGR.",[523,61257,61258],{},[3069,61259],{"alt":61260,"src":61261},"Ceph Day Darmstadt 2018 - Development update: ceph-mgr and kubernetes - Two ways to consume containerized Ceph","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_162648.jpg",[523,61263,61264],{},"Rook is partly for the \"Just give me the storage\" people within and for the Kubernetes cluster.",[523,61266,61267],{},[3069,61268],{"alt":61269,"src":61270},"Ceph Day Darmstadt 2018 - Development update: ceph-mgr and kubernetes - What doesn't Kubernetes do for us?","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_162954.jpg",[523,61272,61273],{},"The plan is unwind Rook to also allow external clusters to be used with Rook and do some pieces using the Ceph MGR instead of Rook or both.\nMore discussions on that are currently taking place and will continue from what I know.",[523,61275,61276,61277,61280],{},"Overall there has been work on improving MGR modules like ",[567,61278,61279],{},"pg_num"," management and openATTIC dashboard v2 upstream to Ceph ongoing.",[613,61282,61284],{"id":61283},"everyone-can-build-and-maintain-a-ceph-cluster-with-croit-paul-emmerich-croit","Everyone can Build and Maintain a Ceph Cluster with croit - Paul Emmerich (croit)",[523,61286,61287],{},"They are building a plattform to \"deploy, use, mamnage and monitor\" Ceph cluster(s).",[523,61289,61290],{},[3069,61291],{"alt":61292,"src":61293},"Ceph Day Darmstadt 2018 - Everyone can Build and Maintain a Ceph Cluster with croit - croit Webinterface","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_170931.jpg",[523,61295,61296,61297,61300],{},"The shown demo was of their latest ",[527,61298,51875],{"href":51873,"rel":61299},[531]," release.\nThe web interface looks nice (and is responsive) from what I have seen in the demo.\nIt allows to manage and monitor every Ceph service (from MON to RGW) through the user interface, but also through a REST API.",[613,61302,61304],{"id":61303},"ssd-only-performance-with-ceph-sven-michels-sectoor-gmbh","SSD-only Performance with Ceph - Sven Michels (sectoor GmbH)",[523,61306,61307],{},[3069,61308],{"alt":61309,"src":61310},"Ceph Day Darmstadt 2018 - SSD-only Performance with Ceph - The Limit","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_172603.jpg",[523,61312,61313],{},"The limit for SSDs (or overall non-spinning disks) is mostly because of the Ceph OSD code.\nA solution for that is to rewrite the Ceph OSD code with non-spinning disks in mind.\nCeph will be the limit most of the time before the hardware, when using non-spinning disks.",[523,61315,61316],{},"If you want a full performance Ceph cluster, this current limit should be kept in mind.\nAlso to note here, that work in the OSD code is currently ongoing for the next Ceph release (Mimic).",[613,61318,61320],{"id":61319},"qa-session","Q&A Session",[523,61322,61323],{},[3069,61324],{"alt":61325,"src":61326},"Ceph Day Darmstadt 2018 - Q&A Session - Speaker Lineup","\u002Fblog\u002F2018\u002Fceph-day-germany-2018\u002Fimg_20180207_173832.jpg",[523,61328,61329],{},"So many talks in one day at one event. Awesome!\nI'm happy to go there next year again and maybe even as a speaker.",[535,61331,14526],{"id":14525},[523,61333,61334],{},"It was very informative listening to all the talks. It was especially interesting to hear about the different use cases of Ceph (librados, RBD, CephFS and RGW).\nAs always it was interesting talking and hearing from Ceph users and devs, what they are doing with Ceph.",[523,61336,13967],{},[2979,61338],{},[523,61340,61341],{},"Intel and the Intel logo are trademarks of Intel Corporation or its subsidiaries in the U.S. and\u002For other countries.",{"title":743,"searchDepth":761,"depth":761,"links":61343},[61344,61345,61361],{"id":51276,"depth":761,"text":51277},{"id":51329,"depth":761,"text":51330,"children":61346},[61347,61348,61349,61350,61351,61352,61353,61354,61355,61356,61357,61358,61359,61360],{"id":60505,"depth":769,"text":60506},{"id":60696,"depth":769,"text":60697},{"id":60865,"depth":769,"text":60866},{"id":60887,"depth":769,"text":60888},{"id":60936,"depth":769,"text":60937},{"id":61004,"depth":769,"text":60693},{"id":61022,"depth":769,"text":61023},{"id":61066,"depth":769,"text":61067},{"id":61119,"depth":769,"text":61120},{"id":61150,"depth":769,"text":61151},{"id":61217,"depth":769,"text":61218},{"id":61283,"depth":769,"text":61284},{"id":61303,"depth":769,"text":61304},{"id":61319,"depth":769,"text":61320},{"id":14525,"depth":761,"text":14526},"2018-02-07T06:20:53+02:00","Talks, thoughts and pictures from the Ceph Day Darmstadt 2018.",{"src":60500},{"tags":61366},[13976,427,421],"\u002Fblog\u002F2018\u002Fceph-day-germany-2018",{"title":60464,"description":61363},"3.blog\u002F2018\u002Fceph-day-germany-2018","gLUM-XXehMe1hGUa7myOoEisy6U-2ReHIWDfGoornN8",{"id":61372,"title":61373,"authors":61374,"badge":518,"body":61377,"date":62637,"description":62638,"extension":2911,"image":62639,"meta":62641,"navigation":1254,"path":62643,"seo":62644,"stem":62645,"__hash__":62646},"posts\u002F3.blog\u002F2018\u002Fgitlab-keycloak-saml-2-0-omniauth-provider.md","GitLab: Use Keycloak as SAML 2.0 OmniAuth Provider",[61375],{"name":514,"to":515,"avatar":61376},{"src":517},{"type":520,"value":61378,"toc":62615},[61379,61381,61388,61397,61399,61420,61424,61439,61445,61451,61458,61461,61464,61468,61480,61483,61489,61493,61510,61516,61523,61527,61530,61536,61539,61690,61696,61700,61709,61715,61719,61722,61732,61738,61748,61751,61780,61790,61904,61907,61914,61917,61924,61928,61931,61944,61964,62493,62499,62517,62520,62530,62547,62551,62564,62580,62583,62586,62590,62593,62597,62605,62607,62610,62612],[535,61380,538],{"id":537},[523,61382,61383,61384,61387],{},"This post shows how you can use Keycloak with SAML 2.0 as an OmniAuth Provider for GitLab (CE and EE).\nPlease note that these settings are tested only with GitLab CE ",[567,61385,61386],{},"10.x.x"," and above.\nGitLab EE edition should probably work too, additionally offers more control features like Admin groups, \"User must be in group\u002Frole to be able to login\", etc.",[523,61389,61390,61391,61396],{},"If you haven't heard of Keycloak yet, checkout their website at: ",[527,61392,61395],{"href":61393,"rel":61394},"http:\u002F\u002Fwww.keycloak.org\u002F",[531],"Keycloak.org",".\nIn short Keycloak is an Open Source Identity and Access Management that allows SSO, uses standard protocols like OpenID Connect, OAuth 2.0 and SAML 2.0, it also has other very interesting features available.",[613,61398,22268],{"id":22267},[668,61400,61401,61412],{},[638,61402,61403,61404],{},"Running and working Keycloak instance(s)\n",[668,61405,61406,61409],{},[638,61407,61408],{},"Keycloak knowledge on an intermediate level",[638,61410,61411],{},"Keycloak admin access (you need permissions to create a client in a realm of choice)",[638,61413,61414,61415],{},"Running GitLab instance\n",[668,61416,61417],{},[638,61418,61419],{},"Access to the GitLab's instance configuration files",[535,61421,61423],{"id":61422},"step-1-create-saml-client-in-keycloak","Step 1 - Create SAML Client in Keycloak",[6072,61425,61426,61430],{},[523,61427,61428],{},[584,61429,6189],{},[523,61431,23726,61432,61435,61436,1909],{},[567,61433,61434],{},"gitlab.edenmal.moe"," with your actual GitLab hostname, example ",[567,61437,61438],{},"my-gitlab.edenmal.moe",[523,61440,61441,61442,61444],{},"Go to the Clients page and click the ",[567,61443,4277],{}," button in the right upper corner.",[523,61446,61447],{},[3069,61448],{"alt":61449,"src":61450},"Keycloak - Add Client form","\u002Fblog\u002F2018\u002Fgitlab-keycloak-saml-2-0-omniauth-provider\u002Fkeycloak-add-client.png",[523,61452,61453,61454,1909],{},"The configuration of the SAML client will be done in ",[527,61455,61457],{"href":61456},"#step-2-configure-sAML-client-in-keycloak","Step 2 - Configure SAML Client in Keycloak",[535,61459,61457],{"id":61460},"step-2-configure-saml-client-in-keycloak",[523,61462,61463],{},"In this step the configuration of the created Keycloak SAML client will be done.\nIf you aren't on the client configuration page of your created SAML client yet, navigate to it now.",[613,61465,61467],{"id":61466},"settings-tab","Settings Tab",[6072,61469,61470,61474],{},[523,61471,61472],{},[584,61473,6189],{},[523,61475,23726,61476,61435,61478,1909],{},[567,61477,61434],{},[567,61479,61438],{},[523,61481,61482],{},"The next screenshots contains the settings you need to set on your client.",[523,61484,61485],{},[3069,61486],{"alt":61487,"src":61488},"Keycloak - Created Client Settings overview","\u002Fblog\u002F2018\u002Fgitlab-keycloak-saml-2-0-omniauth-provider\u002Fkeycloak-client-settings-overview.png",[613,61490,61492],{"id":61491},"roles-tab","Roles Tab",[523,61494,61495,61496,61499,61500,61505,61506,61509],{},"GitLab CE users are \"only\" able to specifically mark users as \"external\" in GitLab, that is what, below in the screenshot, the ",[567,61497,61498],{},"gitlab.edenmal.moe:external"," group is for.\nGitLab EE users have more possibilites to restrict access, which can be found here: ",[527,61501,61504],{"href":61502,"rel":61503},"https:\u002F\u002Fdocs.gitlab.com\u002Fee\u002Fintegration\u002Fsaml.html",[531],"GitLab EE Documentation - SAML OmniAuth Provider",".\nPlease note that the roles other than the ",[567,61507,61508],{},"*:external"," in the screenshot, only \"work\" for GitLab EE edition.",[523,61511,61512],{},[3069,61513],{"alt":61514,"src":61515},"Keycloak - Created Client Settings Roles Tab","\u002Fblog\u002F2018\u002Fgitlab-keycloak-saml-2-0-omniauth-provider\u002Fkeycloak-client-roles-tab.png",[523,61517,61518,61519,61522],{},"Now that you have setup roles to control the acccess to your GitLab, continue on to the ",[567,61520,61521],{},"Mappers"," tab.",[613,61524,61526],{"id":61525},"mappers-tab","Mappers Tab",[523,61528,61529],{},"Mappers, as the name may suggest, allow you to map user information to parameters in the SAML 2.0 request for GitLab.\nAn example would be to map the Username into the request for GitLab.",[523,61531,61532],{},[3069,61533],{"alt":61534,"src":61535},"Keycloak - Created Client Settings Mappers Tab","\u002Fblog\u002F2018\u002Fgitlab-keycloak-saml-2-0-omniauth-provider\u002Fkeycloak-client-mappers-tab.png",[523,61537,61538],{},"The created mappers configuration is:",[668,61540,61541,61573,61601,61630,61659],{},[638,61542,61543,61544,61546],{},"Name: ",[567,61545,5472],{},[668,61547,61548,61553,61558,61563,61568],{},[638,61549,61550,61551],{},"Mapper Type: ",[567,61552,19224],{},[638,61554,61555,61556],{},"Property: ",[567,61557,19232],{},[638,61559,61560,61561],{},"Friendly Name: ",[567,61562,19232],{},[638,61564,61565,61566],{},"SAML Attribute Name: ",[567,61567,5472],{},[638,61569,61570,61571],{},"SAML Attribute NameFormat: ",[567,61572,19489],{},[638,61574,61543,61575,61578],{},[567,61576,61577],{},"email",[668,61579,61580,61584,61589,61593,61597],{},[638,61581,61550,61582],{},[567,61583,19224],{},[638,61585,61555,61586],{},[567,61587,61588],{},"Email",[638,61590,61560,61591],{},[567,61592,61588],{},[638,61594,61565,61595],{},[567,61596,61577],{},[638,61598,61570,61599],{},[567,61600,19489],{},[638,61602,61543,61603,61606],{},[567,61604,61605],{},"first_name",[668,61607,61608,61612,61617,61622,61626],{},[638,61609,61550,61610],{},[567,61611,19224],{},[638,61613,61555,61614],{},[567,61615,61616],{},"FirstName",[638,61618,61560,61619],{},[567,61620,61621],{},"First Name",[638,61623,61565,61624],{},[567,61625,61605],{},[638,61627,61570,61628],{},[567,61629,19489],{},[638,61631,61543,61632,61635],{},[567,61633,61634],{},"last_name",[668,61636,61637,61641,61646,61651,61655],{},[638,61638,61550,61639],{},[567,61640,19224],{},[638,61642,61555,61643],{},[567,61644,61645],{},"LastName",[638,61647,61560,61648],{},[567,61649,61650],{},"Last Name",[638,61652,61565,61653],{},[567,61654,61634],{},[638,61656,61570,61657],{},[567,61658,19489],{},[638,61660,61543,61661,61664],{},[567,61662,61663],{},"roles",[668,61665,61666,61671,61676,61681,61685],{},[638,61667,61550,61668],{},[567,61669,61670],{},"Role list",[638,61672,61673,61674],{},"Role attribute name: ",[567,61675,61663],{},[638,61677,61560,61678],{},[567,61679,61680],{},"Roles",[638,61682,61570,61683],{},[567,61684,19489],{},[638,61686,61687,61688],{},"Single Role Attribute: ",[567,61689,19470],{},[523,61691,61692,61693,1909],{},"All of the mappers have \"Consent Required\" set to ",[567,61694,61695],{},"Off",[613,61697,61699],{"id":61698},"scope-tab","Scope Tab",[523,61701,61702,61703,61705,61706,61708],{},"Sadly this option needs to be set to ",[567,61704,19470],{}," for GitLab, as there seem to issues with it getting the ",[567,61707,61663],{}," because of \"missing\" scopes requested.",[523,61710,61711],{},[3069,61712],{"alt":61713,"src":61714},"Keycloak - Created Client Settings Scope Tab","\u002Fblog\u002F2018\u002Fgitlab-keycloak-saml-2-0-omniauth-provider\u002Fkeycloak-client-scope-tab.png",[535,61716,61718],{"id":61717},"step-3-get-certificate-fingerprint","Step 3 - Get Certificate Fingerprint",[523,61720,61721],{},"The Keycloak IDP realm's public certificate fingerprint is needed for the configuration of SAML2.0.",[523,61723,61724,61725,61728,61729,1909],{},"For that go to the ",[567,61726,61727],{},"Realm Settings"," sidebar menu point and client the ",[567,61730,61731],{},"SAML 2.0 Identity Provder Metadata",[523,61733,61734],{},[3069,61735],{"alt":61736,"src":61737},"Keycloak Realm Settings Page","\u002Fblog\u002F2018\u002Fgitlab-keycloak-saml-2-0-omniauth-provider\u002Fkeycloak-realm-settings.png",[523,61739,61740,61741,36823,61745,61747],{},"Now download\u002F save page by, e.g., using ",[61742,61743,61744],"kbd",{},"CTRL",[61742,61746,2003],{},", right click on the page and \"Save as...\".",[523,61749,61750],{},"The file contains the Keycloak IDP public certificate of which the public fingerprint is needed for the configuration on GitLab's side.\nTo get that certificate in the \"correct\" format and get the fingerprint, I have a small script snippet below to extract the cert and print the fingerprint.",[6072,61752,61753,61758],{},[523,61754,61755],{},[584,61756,61757],{},"REQUIREMENTS",[668,61759,61760,61766,61771,61775],{},[638,61761,61762,61763,2006],{},"bash (located at ",[567,61764,61765],{},"\u002Fbin\u002Fbash",[638,61767,61768],{},[567,61769,61770],{},"grep",[638,61772,61773],{},[567,61774,35358],{},[638,61776,61777],{},[567,61778,61779],{},"openssl",[523,61781,61782,61783,61786,61787,61789],{},"Set the ",[567,61784,61785],{},"IDP_DESCRIPTOR_FILE"," variable to the path where you saved the ",[567,61788,61731],{}," \"page\" to.",[738,61791,61793],{"className":1621,"code":61792,"language":1623,"meta":743,"style":743},"IDP_DESCRIPTOR_FILE=\"~\u002FDownloads\u002Fdescriptor\"\n(\n    echo \"-----BEGIN CERTIFICATE-----\"\n    grep -oP '\u003Cds:X509Certificate>(.*)\u003C\u002Fds:X509Certificate>' \"$IDP_DESCRIPTOR_FILE\" | sed -r -e 's~\u003C[\u002F]?ds:X509Certificate>~~g' | fold -w 64\n    echo \"-----END CERTIFICATE-----\"\n) | openssl x509 -noout -fingerprint -sha1\n",[567,61794,61795,61808,61813,61825,61874,61885],{"__ignoreMap":743},[747,61796,61797,61799,61801,61803,61806],{"class":749,"line":750},[747,61798,61785],{"class":1640},[747,61800,6425],{"class":757},[747,61802,3892],{"class":757},[747,61804,61805],{"class":802},"~\u002FDownloads\u002Fdescriptor",[747,61807,975],{"class":757},[747,61809,61810],{"class":749,"line":761},[747,61811,61812],{"class":757},"(\n",[747,61814,61815,61818,61820,61823],{"class":749,"line":769},[747,61816,61817],{"class":4574},"    echo",[747,61819,969],{"class":757},[747,61821,61822],{"class":802},"-----BEGIN CERTIFICATE-----",[747,61824,975],{"class":757},[747,61826,61827,61830,61833,61835,61838,61840,61842,61845,61847,61849,61851,61854,61856,61858,61861,61863,61865,61868,61871],{"class":749,"line":776},[747,61828,61829],{"class":1630},"    grep",[747,61831,61832],{"class":802}," -oP",[747,61834,3537],{"class":757},[747,61836,61837],{"class":802},"\u003Cds:X509Certificate>(.*)\u003C\u002Fds:X509Certificate>",[747,61839,3543],{"class":757},[747,61841,969],{"class":757},[747,61843,61844],{"class":1640},"$IDP_DESCRIPTOR_FILE",[747,61846,3892],{"class":757},[747,61848,3170],{"class":757},[747,61850,37285],{"class":1630},[747,61852,61853],{"class":802}," -r",[747,61855,7097],{"class":802},[747,61857,3537],{"class":757},[747,61859,61860],{"class":802},"s~\u003C[\u002F]?ds:X509Certificate>~~g",[747,61862,3543],{"class":757},[747,61864,3170],{"class":757},[747,61866,61867],{"class":1630}," fold",[747,61869,61870],{"class":802}," -w",[747,61872,61873],{"class":1895}," 64\n",[747,61875,61876,61878,61880,61883],{"class":749,"line":784},[747,61877,61817],{"class":4574},[747,61879,969],{"class":757},[747,61881,61882],{"class":802},"-----END CERTIFICATE-----",[747,61884,975],{"class":757},[747,61886,61887,61889,61891,61893,61895,61898,61901],{"class":749,"line":790},[747,61888,2006],{"class":757},[747,61890,3170],{"class":757},[747,61892,19681],{"class":1630},[747,61894,19770],{"class":802},[747,61896,61897],{"class":802}," -noout",[747,61899,61900],{"class":802}," -fingerprint",[747,61902,61903],{"class":802}," -sha1\n",[523,61905,61906],{},"Write down the fingerprint that is printed out by the script we need it for GitLab configuration later on.",[523,61908,61909,61910,1909],{},"Now that you have the Keycloak IDP certificate fingerprint and the SAML 2.0 client created + configured, we can move on to configuring GitLab to use the client for authentication in the next step ",[527,61911,61913],{"href":61912},"#step-4-configure-gitlab","Step 4 - Configure GitLab",[535,61915,61913],{"id":61916},"step-4-configure-gitlab",[523,61918,61919,61920,61923],{},"This needs to be done in the ",[567,61921,61922],{},"gitlab.yml"," config file of your GitLab instance.",[613,61925,61927],{"id":61926},"adding-the-saml-omniauth-provider-configuration","Adding the SAML OmniAuth Provider configuration",[523,61929,61930],{},"The GitLab config YAML snippet below contains the settings that control the SAML OmniAuth Provider.",[6072,61932,61933,61938],{},[523,61934,61935,61937],{},[584,61936,6189],{}," The snippet below is from GitLab CE.",[523,61939,61940,61941,1909],{},"GitLab EE has more options for SAML authentication, see ",[527,61942,61504],{"href":61502,"rel":61943},[531],[523,61945,61946,61947,61435,61949,61951,61952,61955,61956,587,61960,61963],{},"As before, don't forget to replace ",[567,61948,61434],{},[567,61950,61438],{},".\nAdditionally replace ",[567,61953,61954],{},"YOUR_KEYCLOAK_CERT_FINGERPRINT"," with the Keycloak certificate fingerprint from the ",[527,61957,61959],{"href":61958},"#Get-Certificate-Fingerprint","previous step's section (Get Certificate Fingerprint)",[567,61961,61962],{},"keycloak.edenmal.moe"," with the actual address to your Keycloak instance.",[738,61965,61967],{"className":740,"code":61966,"language":742,"meta":743,"style":743},"production:\n[...]\n    omniauth:\n        # Allow login via Twitter, Google, etc. using OmniAuth providers\n        enabled: true\n\n        # Uncomment this to automatically sign in with a specific omniauth provider's without\n        # showing GitLab's sign-in page (default: show the GitLab sign-in page)\n        auto_sign_in_with_provider:\n\n        # Sync user's email address from the specified Omniauth provider every time the user logs\n        # in (default: nil). And consequently make this field read-only.\n        # sync_email_from_provider: cas3\n\n        # CAUTION!\n        # This allows users to login without having a user account first. Define the allowed providers\n        # using an array, e.g. [\"saml\", \"twitter\"], or as true\u002Ffalse to allow all providers or none.\n        # User accounts will be created automatically when authentication was successful.\n        allow_single_sign_on: [saml]\n\n        # Locks down those users until they have been cleared by the admin (default: true).\n        block_auto_created_users: true\n        # Look up new users in LDAP servers. If a match is found (same uid), automatically\n        # link the omniauth identity with the LDAP account. (default: false)\n        auto_link_ldap_user: false\n\n        # Allow users with existing accounts to login and auto link their account via SAML\n        # login, without having to do a manual login first and manually add SAML\n        # (default: false)\n        auto_link_saml_user: true\n\n        # Set different Omniauth providers as external so that all users creating accounts\n        # via these providers will not be able to have access to internal projects. You\n        # will need to use the full name of the provider, like `google_oauth2` for Google.\n        # Refer to the examples below for the full names of the supported providers.\n        # (default: [])\n        external_providers: []\n\n        ## Auth providers\n        # Uncomment the following lines and fill in the data of the auth provider you want to use\n        # If your favorite auth provider is not listed you can use others:\n        # see https:\u002F\u002Fgithub.com\u002Fgitlabhq\u002Fgitlab-public-wiki\u002Fwiki\u002FCustom-omniauth-provider-configurations\n        # The 'app_id' and 'app_secret' parameters are always passed as the first two\n        # arguments, followed by optional 'args' which can be either a hash or an array.\n        # Documentation for this is available at http:\u002F\u002Fdoc.gitlab.com\u002Fce\u002Fintegration\u002Fomniauth.html\n        providers:\n          # See omniauth-cas3 for more configuration details\n          - { name: 'saml',\n              label: 'gitlab.edenmal.moe Keycloak',\n              groups_attribute: 'roles',\n              external_groups: ['gitlab.edenmal.moe:external'],\n              args: {\n                      assertion_consumer_service_url: 'https:\u002F\u002Fgitlab.edenmal.moe\u002Fusers\u002Fauth\u002Fsaml\u002Fcallback',\n                      idp_cert_fingerprint: 'YOUR_KEYCLOAK_CERT_FINGERPRINT',\n                      idp_sso_target_url: 'https:\u002F\u002Fkeycloak.edenmal.moe\u002Fauth\u002Frealms\u002Fmaster\u002Fprotocol\u002Fsaml\u002Fclients\u002Fgitlab.edenmal.moe',\n                      issuer: 'gitlab.edenmal.moe',\n                      attribute_statements: {\n                        first_name: ['first_name'],\n                        last_name: ['last_name'],\n                        name: ['name'],\n                        username: ['name'],\n                        email: ['email'] },\n                      name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent' } }\n",[567,61968,61969,61976,61984,61991,61996,62005,62009,62014,62019,62026,62030,62035,62040,62045,62049,62054,62059,62064,62069,62083,62087,62092,62101,62106,62111,62120,62124,62129,62134,62139,62148,62152,62157,62162,62167,62172,62177,62187,62191,62196,62201,62206,62211,62216,62221,62226,62233,62238,62258,62274,62289,62306,62315,62331,62346,62362,62377,62386,62403,62420,62437,62454,62474],{"__ignoreMap":743},[747,61970,61971,61974],{"class":749,"line":750},[747,61972,61973],{"class":753},"production",[747,61975,758],{"class":757},[747,61977,61978,61980,61982],{"class":749,"line":761},[747,61979,4253],{"class":757},[747,61981,5685],{"class":1895},[747,61983,4268],{"class":757},[747,61985,61986,61989],{"class":749,"line":769},[747,61987,61988],{"class":753},"    omniauth",[747,61990,758],{"class":757},[747,61992,61993],{"class":749,"line":776},[747,61994,61995],{"class":772},"        # Allow login via Twitter, Google, etc. using OmniAuth providers\n",[747,61997,61998,62001,62003],{"class":749,"line":784},[747,61999,62000],{"class":753},"        enabled",[747,62002,856],{"class":757},[747,62004,860],{"class":859},[747,62006,62007],{"class":749,"line":790},[747,62008,1255],{"emptyLinePlaceholder":1254},[747,62010,62011],{"class":749,"line":796},[747,62012,62013],{"class":772},"        # Uncomment this to automatically sign in with a specific omniauth provider's without\n",[747,62015,62016],{"class":749,"line":806},[747,62017,62018],{"class":772},"        # showing GitLab's sign-in page (default: show the GitLab sign-in page)\n",[747,62020,62021,62024],{"class":749,"line":814},[747,62022,62023],{"class":753},"        auto_sign_in_with_provider",[747,62025,758],{"class":757},[747,62027,62028],{"class":749,"line":822},[747,62029,1255],{"emptyLinePlaceholder":1254},[747,62031,62032],{"class":749,"line":830},[747,62033,62034],{"class":772},"        # Sync user's email address from the specified Omniauth provider every time the user logs\n",[747,62036,62037],{"class":749,"line":836},[747,62038,62039],{"class":772},"        # in (default: nil). And consequently make this field read-only.\n",[747,62041,62042],{"class":749,"line":842},[747,62043,62044],{"class":772},"        # sync_email_from_provider: cas3\n",[747,62046,62047],{"class":749,"line":850},[747,62048,1255],{"emptyLinePlaceholder":1254},[747,62050,62051],{"class":749,"line":863},[747,62052,62053],{"class":772},"        # CAUTION!\n",[747,62055,62056],{"class":749,"line":869},[747,62057,62058],{"class":772},"        # This allows users to login without having a user account first. Define the allowed providers\n",[747,62060,62061],{"class":749,"line":877},[747,62062,62063],{"class":772},"        # using an array, e.g. [\"saml\", \"twitter\"], or as true\u002Ffalse to allow all providers or none.\n",[747,62065,62066],{"class":749,"line":1015},[747,62067,62068],{"class":772},"        # User accounts will be created automatically when authentication was successful.\n",[747,62070,62071,62074,62076,62078,62081],{"class":749,"line":1021},[747,62072,62073],{"class":753},"        allow_single_sign_on",[747,62075,856],{"class":757},[747,62077,4262],{"class":757},[747,62079,62080],{"class":802},"saml",[747,62082,4268],{"class":757},[747,62084,62085],{"class":749,"line":1027},[747,62086,1255],{"emptyLinePlaceholder":1254},[747,62088,62089],{"class":749,"line":1033},[747,62090,62091],{"class":772},"        # Locks down those users until they have been cleared by the admin (default: true).\n",[747,62093,62094,62097,62099],{"class":749,"line":1039},[747,62095,62096],{"class":753},"        block_auto_created_users",[747,62098,856],{"class":757},[747,62100,860],{"class":859},[747,62102,62103],{"class":749,"line":1054},[747,62104,62105],{"class":772},"        # Look up new users in LDAP servers. If a match is found (same uid), automatically\n",[747,62107,62108],{"class":749,"line":1060},[747,62109,62110],{"class":772},"        # link the omniauth identity with the LDAP account. (default: false)\n",[747,62112,62113,62116,62118],{"class":749,"line":1066},[747,62114,62115],{"class":753},"        auto_link_ldap_user",[747,62117,856],{"class":757},[747,62119,1340],{"class":859},[747,62121,62122],{"class":749,"line":1081},[747,62123,1255],{"emptyLinePlaceholder":1254},[747,62125,62126],{"class":749,"line":1087},[747,62127,62128],{"class":772},"        # Allow users with existing accounts to login and auto link their account via SAML\n",[747,62130,62131],{"class":749,"line":1102},[747,62132,62133],{"class":772},"        # login, without having to do a manual login first and manually add SAML\n",[747,62135,62136],{"class":749,"line":1110},[747,62137,62138],{"class":772},"        # (default: false)\n",[747,62140,62141,62144,62146],{"class":749,"line":1117},[747,62142,62143],{"class":753},"        auto_link_saml_user",[747,62145,856],{"class":757},[747,62147,860],{"class":859},[747,62149,62150],{"class":749,"line":1123},[747,62151,1255],{"emptyLinePlaceholder":1254},[747,62153,62154],{"class":749,"line":1129},[747,62155,62156],{"class":772},"        # Set different Omniauth providers as external so that all users creating accounts\n",[747,62158,62159],{"class":749,"line":1142},[747,62160,62161],{"class":772},"        # via these providers will not be able to have access to internal projects. You\n",[747,62163,62164],{"class":749,"line":1150},[747,62165,62166],{"class":772},"        # will need to use the full name of the provider, like `google_oauth2` for Google.\n",[747,62168,62169],{"class":749,"line":1157},[747,62170,62171],{"class":772},"        # Refer to the examples below for the full names of the supported providers.\n",[747,62173,62174],{"class":749,"line":1163},[747,62175,62176],{"class":772},"        # (default: [])\n",[747,62178,62179,62182,62184],{"class":749,"line":1168},[747,62180,62181],{"class":753},"        external_providers",[747,62183,856],{"class":757},[747,62185,62186],{"class":757}," []\n",[747,62188,62189],{"class":749,"line":1174},[747,62190,1255],{"emptyLinePlaceholder":1254},[747,62192,62193],{"class":749,"line":1480},[747,62194,62195],{"class":772},"        ## Auth providers\n",[747,62197,62198],{"class":749,"line":1491},[747,62199,62200],{"class":772},"        # Uncomment the following lines and fill in the data of the auth provider you want to use\n",[747,62202,62203],{"class":749,"line":1496},[747,62204,62205],{"class":772},"        # If your favorite auth provider is not listed you can use others:\n",[747,62207,62208],{"class":749,"line":1502},[747,62209,62210],{"class":772},"        # see https:\u002F\u002Fgithub.com\u002Fgitlabhq\u002Fgitlab-public-wiki\u002Fwiki\u002FCustom-omniauth-provider-configurations\n",[747,62212,62213],{"class":749,"line":1510},[747,62214,62215],{"class":772},"        # The 'app_id' and 'app_secret' parameters are always passed as the first two\n",[747,62217,62218],{"class":749,"line":1520},[747,62219,62220],{"class":772},"        # arguments, followed by optional 'args' which can be either a hash or an array.\n",[747,62222,62223],{"class":749,"line":1525},[747,62224,62225],{"class":772},"        # Documentation for this is available at http:\u002F\u002Fdoc.gitlab.com\u002Fce\u002Fintegration\u002Fomniauth.html\n",[747,62227,62228,62231],{"class":749,"line":1533},[747,62229,62230],{"class":753},"        providers",[747,62232,758],{"class":757},[747,62234,62235],{"class":749,"line":1539},[747,62236,62237],{"class":772},"          # See omniauth-cas3 for more configuration details\n",[747,62239,62240,62243,62246,62248,62250,62252,62254,62256],{"class":749,"line":1549},[747,62241,62242],{"class":757},"          -",[747,62244,62245],{"class":757}," {",[747,62247,14804],{"class":753},[747,62249,856],{"class":757},[747,62251,3537],{"class":757},[747,62253,62080],{"class":802},[747,62255,3543],{"class":757},[747,62257,20595],{"class":757},[747,62259,62260,62263,62265,62267,62270,62272],{"class":749,"line":1554},[747,62261,62262],{"class":753},"              label",[747,62264,856],{"class":757},[747,62266,3537],{"class":757},[747,62268,62269],{"class":802},"gitlab.edenmal.moe Keycloak",[747,62271,3543],{"class":757},[747,62273,20595],{"class":757},[747,62275,62276,62279,62281,62283,62285,62287],{"class":749,"line":1562},[747,62277,62278],{"class":753},"              groups_attribute",[747,62280,856],{"class":757},[747,62282,3537],{"class":757},[747,62284,61663],{"class":802},[747,62286,3543],{"class":757},[747,62288,20595],{"class":757},[747,62290,62291,62294,62296,62298,62300,62302,62304],{"class":749,"line":1568},[747,62292,62293],{"class":753},"              external_groups",[747,62295,856],{"class":757},[747,62297,4262],{"class":757},[747,62299,3543],{"class":757},[747,62301,61498],{"class":802},[747,62303,3543],{"class":757},[747,62305,20828],{"class":757},[747,62307,62308,62311,62313],{"class":749,"line":1577},[747,62309,62310],{"class":753},"              args",[747,62312,856],{"class":757},[747,62314,20574],{"class":757},[747,62316,62317,62320,62322,62324,62327,62329],{"class":749,"line":1582},[747,62318,62319],{"class":753},"                      assertion_consumer_service_url",[747,62321,856],{"class":757},[747,62323,3537],{"class":757},[747,62325,62326],{"class":802},"https:\u002F\u002Fgitlab.edenmal.moe\u002Fusers\u002Fauth\u002Fsaml\u002Fcallback",[747,62328,3543],{"class":757},[747,62330,20595],{"class":757},[747,62332,62333,62336,62338,62340,62342,62344],{"class":749,"line":1588},[747,62334,62335],{"class":753},"                      idp_cert_fingerprint",[747,62337,856],{"class":757},[747,62339,3537],{"class":757},[747,62341,61954],{"class":802},[747,62343,3543],{"class":757},[747,62345,20595],{"class":757},[747,62347,62348,62351,62353,62355,62358,62360],{"class":749,"line":1594},[747,62349,62350],{"class":753},"                      idp_sso_target_url",[747,62352,856],{"class":757},[747,62354,3537],{"class":757},[747,62356,62357],{"class":802},"https:\u002F\u002Fkeycloak.edenmal.moe\u002Fauth\u002Frealms\u002Fmaster\u002Fprotocol\u002Fsaml\u002Fclients\u002Fgitlab.edenmal.moe",[747,62359,3543],{"class":757},[747,62361,20595],{"class":757},[747,62363,62364,62367,62369,62371,62373,62375],{"class":749,"line":1600},[747,62365,62366],{"class":753},"                      issuer",[747,62368,856],{"class":757},[747,62370,3537],{"class":757},[747,62372,61434],{"class":802},[747,62374,3543],{"class":757},[747,62376,20595],{"class":757},[747,62378,62379,62382,62384],{"class":749,"line":4804},[747,62380,62381],{"class":753},"                      attribute_statements",[747,62383,856],{"class":757},[747,62385,20574],{"class":757},[747,62387,62388,62391,62393,62395,62397,62399,62401],{"class":749,"line":4810},[747,62389,62390],{"class":753},"                        first_name",[747,62392,856],{"class":757},[747,62394,4262],{"class":757},[747,62396,3543],{"class":757},[747,62398,61605],{"class":802},[747,62400,3543],{"class":757},[747,62402,20828],{"class":757},[747,62404,62405,62408,62410,62412,62414,62416,62418],{"class":749,"line":4816},[747,62406,62407],{"class":753},"                        last_name",[747,62409,856],{"class":757},[747,62411,4262],{"class":757},[747,62413,3543],{"class":757},[747,62415,61634],{"class":802},[747,62417,3543],{"class":757},[747,62419,20828],{"class":757},[747,62421,62422,62425,62427,62429,62431,62433,62435],{"class":749,"line":4822},[747,62423,62424],{"class":753},"                        name",[747,62426,856],{"class":757},[747,62428,4262],{"class":757},[747,62430,3543],{"class":757},[747,62432,5472],{"class":802},[747,62434,3543],{"class":757},[747,62436,20828],{"class":757},[747,62438,62439,62442,62444,62446,62448,62450,62452],{"class":749,"line":4828},[747,62440,62441],{"class":753},"                        username",[747,62443,856],{"class":757},[747,62445,4262],{"class":757},[747,62447,3543],{"class":757},[747,62449,5472],{"class":802},[747,62451,3543],{"class":757},[747,62453,20828],{"class":757},[747,62455,62456,62459,62461,62463,62465,62467,62469,62471],{"class":749,"line":4834},[747,62457,62458],{"class":753},"                        email",[747,62460,856],{"class":757},[747,62462,4262],{"class":757},[747,62464,3543],{"class":757},[747,62466,61577],{"class":802},[747,62468,3543],{"class":757},[747,62470,4259],{"class":757},[747,62472,62473],{"class":757}," },\n",[747,62475,62476,62479,62481,62483,62485,62487,62490],{"class":749,"line":4840},[747,62477,62478],{"class":753},"                      name_identifier_format",[747,62480,856],{"class":757},[747,62482,3537],{"class":757},[747,62484,20306],{"class":802},[747,62486,3543],{"class":757},[747,62488,62489],{"class":757}," }",[747,62491,62492],{"class":757}," }\n",[523,62494,62495,62496,62498],{},"Full examples of the ",[567,62497,61922],{}," with all available options can be found here for GitLab:",[668,62500,62501,62509],{},[638,62502,62503,62504],{},"CE edition: ",[527,62505,62508],{"href":62506,"rel":62507},"https:\u002F\u002Fgitlab.com\u002Fgitlab-org\u002Fgitlab-ce\u002Fblob\u002Fmaster\u002Fconfig\u002Fgitlab.yml.example",[531],"config\u002Fgitlab.yml.example · master · gitlab-org\u002Fgitlab-ce",[638,62510,62511,62512],{},"EE Edition: ",[527,62513,62516],{"href":62514,"rel":62515},"https:\u002F\u002Fgitlab.com\u002Fgitlab-org\u002Fgitlab-ee\u002Fblob\u002Fmaster\u002Fconfig\u002Fgitlab.yml.example",[531],"config\u002Fgitlab.yml.example · master · gitlab-org\u002Fgitlab-ee",[523,62518,62519],{},"Make sure the address to your Keycloak instance is correct.",[523,62521,62522,62523,62526,62527,19169],{},"You can adjust most options that are outside the ",[567,62524,62525],{},"providers"," section to your likings, for example the ",[567,62528,62529],{},"block_auto_created_users",[6072,62531,62532,62536],{},[523,62533,62534],{},[584,62535,6189],{},[523,62537,8764,62538,62540,62541,62543,62544,1909],{},[567,62539,62529],{}," option defaults to ",[567,62542,5306],{},", meaning that when you first time login in to GitLab through a authentication provider your account will be blocked.\nSo be ready to unblock the new account with an admin account or set the option to ",[567,62545,62546],{},"false",[535,62548,62550],{"id":62549},"step-5-try-to-login-to-your-gitlab","Step 5 - Try to login to your GitLab",[523,62552,62553,62554,62557,62558,62560,62561,62563],{},"Logout of GitLab and you should land on the normal GitLab login page.\nJust try to login to GitLab using the button named after the ",[567,62555,62556],{},"label"," value in the ",[567,62559,62525],{}," section of the ",[567,62562,61922],{},".\nIf it is not working, I suggest you investigate the Keycloak logs and GitLabs application logs for any errors thrown there.",[523,62565,62566,62567,62570,62571,62573,62574,6378,62576,62579],{},"When that works, you can switch the toggle that automatically redirects you to your login provider.\nThe option in GitLab to automatically redirect to the SSO provider (Keycloak in this case) is ",[567,62568,62569],{},"auto_sign_in_with_provider",".\nTo allow the automatic redirection set ",[567,62572,62569],{}," to the (string) value ",[567,62575,62080],{},[567,62577,62578],{},"auto_sign_in_with_provider: saml",") and restart your GitLab instance.",[523,62581,62582],{},"Now when going to your GitLab instance, you should automatically get redirected to your Keycloak instance and be prompted for login.",[535,62584,62585],{"id":39514},"Side notes",[613,62587,62589],{"id":62588},"high-availability-for-sessions","High availability for Sessions",[523,62591,62592],{},"It is recommended that if you have more than one GitLab instance, that you use a shared Redis so users session are not invalidated when getting sent to the other GitLab instance.",[613,62594,62596],{"id":62595},"sso-logout","SSO Logout",[523,62598,62599,62600,1909],{},"SSO Logout is currently not supported by GitLab. There is an issue open to implement this behavior, see ",[527,62601,62604],{"href":62602,"rel":62603},"https:\u002F\u002Fgitlab.com\u002Fgitlab-org\u002Fgitlab-ce\u002Fissues\u002F17344",[531],"Explore SAML Single Sign Out (#17344) · Issues · gitlab-org\u002Fgitlab-ce",[535,62606,14526],{"id":14525},[523,62608,62609],{},"I hope this helps you to get started with using Keycloak as a GitLab SAML 2.0 OmniAuth Provider for simple SSO login.\nFor questions about the post or issues while trying the configuration from this post, please leave a comment below, thanks!",[523,62611,13967],{},[2890,62613,62614],{},"html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":743,"searchDepth":761,"depth":761,"links":62616},[62617,62620,62621,62627,62628,62631,62632,62636],{"id":537,"depth":761,"text":538,"children":62618},[62619],{"id":22267,"depth":769,"text":22268},{"id":61422,"depth":761,"text":61423},{"id":61460,"depth":761,"text":61457,"children":62622},[62623,62624,62625,62626],{"id":61466,"depth":769,"text":61467},{"id":61491,"depth":769,"text":61492},{"id":61525,"depth":769,"text":61526},{"id":61698,"depth":769,"text":61699},{"id":61717,"depth":761,"text":61718},{"id":61916,"depth":761,"text":61913,"children":62629},[62630],{"id":61926,"depth":769,"text":61927},{"id":62549,"depth":761,"text":62550},{"id":39514,"depth":761,"text":62585,"children":62633},[62634,62635],{"id":62588,"depth":769,"text":62589},{"id":62595,"depth":769,"text":62596},{"id":14525,"depth":761,"text":14526},"2018-01-16T16:15:53+02:00","How to use Keycloak SAML 2.0 for GitLab as an OmniAuth provider.",{"src":62640},"\u002Fblog\u002Fcovers\u002Fgitlab-keycloak-logo.png",{"tags":62642},[26413,19186,22227],"\u002Fblog\u002F2018\u002Fgitlab-keycloak-saml-2-0-omniauth-provider",{"title":61373,"description":62638},"3.blog\u002F2018\u002Fgitlab-keycloak-saml-2-0-omniauth-provider","d5nuA3Vozu9wMvekCHREz9DsMo5Gc6y5Qa2pFz2vEzY",{"id":62648,"title":62649,"authors":62650,"badge":518,"body":62653,"date":64798,"description":64799,"extension":2911,"image":64800,"meta":64801,"navigation":1254,"path":64803,"seo":64804,"stem":64805,"__hash__":64806},"posts\u002F3.blog\u002F2017\u002Fkubecon-2017-austin.md","KubeCon 2017 Austin",[62651],{"name":514,"to":515,"avatar":62652},{"src":517},{"type":520,"value":62654,"toc":64774},[62655,62657,62667,62669,62680,62682,62684,62699,62705,62710,62716,62719,62721,62725,62733,62735,62737,62746,62749,62753,62773,62786,62790,62809,62812,62819,62821,62827,62831,62836,62845,62849,62852,62855,62869,62872,62887,62892,62910,62916,62924,62929,62951,62955,62969,62973,62976,62979,62982,62986,62992,62995,62998,63005,63011,63014,63017,63020,63024,63030,63033,63036,63038,63046,63055,63058,63061,63064,63070,63073,63079,63082,63088,63094,63102,63105,63108,63112,63115,63126,63129,63142,63145,63152,63155,63167,63173,63176,63182,63188,63191,63193,63196,63200,63203,63206,63213,63218,63221,63224,63228,63231,63237,63243,63246,63260,63263,63274,63277,63281,63284,63287,63290,63294,63297,63300,63304,63307,63313,63327,63329,63331,63334,63340,63344,63347,63353,63356,63364,63370,63378,63381,63385,63388,63391,63397,63400,63403,63409,63415,63421,63424,63438,63444,63450,63456,63460,63463,63466,63472,63475,63478,63482,63485,63488,63491,63494,63510,63517,63523,63526,63532,63543,63549,63579,63585,63588,63594,63597,63613,63619,63623,63626,63629,63635,63646,63661,63665,63671,63674,63677,63680,63686,63705,63708,63711,63718,63721,63730,63739,63748,63751,63776,63782,63788,63799,63805,63819,63837,63848,63851,63857,63864,63867,63870,63873,63880,63883,63946,63949,63955,63962,63965,63973,63980,63986,63990,63998,64004,64008,64012,64018,64022,64025,64028,64031,64034,64039,64045,64050,64056,64061,64067,64072,64078,64085,64090,64093,64099,64102,64108,64112,64118,64121,64124,64129,64132,64138,64152,64158,64161,64167,64170,64176,64179,64185,64191,64194,64200,64203,64209,64215,64221,64227,64230,64236,64242,64245,64249,64252,64255,64261,64266,64269,64275,64278,64282,64285,64288,64294,64297,64421,64424,64432,64436,64439,64448,64454,64457,64463,64469,64475,64481,64487,64490,64496,64499,64505,64508,64515,64518,64524,64527,64546,64552,64557,64560,64583,64589,64593,64596,64599,64605,64618,64624,64630,64636,64641,64648,64654,64657,64660,64666,64669,64675,64684,64690,64701,64707,64713,64719,64722,64738,64744,64747,64751,64757,64760,64762,64765,64767,64771],[2890,62656,52288],{},[6072,62658,62659,62663],{},[523,62660,62661,56418],{},[584,62662,6189],{},[523,62664,62665,56423],{},[584,62666,6189],{},[535,62668,13457],{"id":13456},[523,62670,62671,62672,587,62675,1909],{},"A huge thanks goes out to Rook and Quantum Corporation for helping me with my trip and the conference! Checkout their Twitter ",[527,62673,52953],{"href":15056,"rel":62674},[531],[527,62676,62679],{"href":62677,"rel":62678},"https:\u002F\u002Ftwitter.com\u002FQuantumCorp",[531],"@QuantumCorp",[2979,62681],{},[535,62683,52390],{"id":52389},[6072,62685,62686,62694],{},[523,62687,62688,62690,62691,1909],{},[584,62689,6189],{}," If you don't want to read about my flight and stay, skip to ",[527,62692,52419],{"href":62693},"#Day-1",[523,62695,62696,62698],{},[584,62697,3103],{}," First flight in a \"long\" time and alone, nervous as hell.",[523,62700,62701],{},[3069,62702],{"alt":62703,"src":62704},"KubeCon: Flight - Boarding the plane to KubeCon","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171205_102158.jpg",[6072,62706,62707],{},[523,62708,62709],{},"\"Started from STR (Stuttgart) now we're in the sky.\"\nTotally not a \"rip off\" of a songtext by Drake",[523,62711,62712],{},[3069,62713],{"alt":62714,"src":62715},"KubeCon: Flight - Look out of airplane window","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171205_105841.jpg",[523,62717,62718],{},"I had a pit stop in Atlanta, and then flew to Austin. The flight to Austin was a bit rough because it just started raining when the airplane departed.\nAfter a total of about 12 hours, I finally arrived in Austin in the hotel. Pretty exhausted, but ready for KubeCon!\nSaying it here already, I was not really jet lagged, but I heard that flying back will definitely jet lag me. But well, I will enjoy my days off after KubeCon to \"cure\" my jet lag and get ready for work again.",[2979,62720],{},[535,62722,62724],{"id":62723},"keynotes-and-talks-recordings-youtube-playlist","Keynotes and Talks Recordings YouTube Playlist",[523,62726,62727,62728,1909],{},"KubeCon has published all keynotes and talks as a nice YouTube playlist, you can check it out here: ",[527,62729,62732],{"href":62730,"rel":62731},"https:\u002F\u002Fwww.youtube.com\u002Fplaylist?list=PLj6h78yzYM2P-3-xqvmWaZbbI1sW-ulZb",[531],"KubeCon + CloudNativeCon 2017 - Austin - YouTube",[2979,62734],{},[535,62736,52419],{"id":52418},[6072,62738,62739,62743],{},[523,62740,62741],{},[584,62742,15676],{},[523,62744,62745],{},"The quality of the photos in this post varies pretty hard. This is caused by me using a smartphone camera to take the photos.",[523,62747,62748],{},"I was pretty lucky to be there early, as I got my badge instantly. Others hadn't that much luck later on and had to wait a good time.",[613,62750,62752],{"id":62751},"rook-team-booth","Rook Team + Booth",[6072,62754,62755,62759,62766,62770],{},[523,62756,62757],{},[584,62758,6189],{},[523,62760,62761,62762,1909],{},"If you don't want to know about the Rook team + community photos and the booth, skip to ",[527,62763,62765],{"href":62764},"#Keynote-Morning","Day #1 - Morning Keynotes",[523,62767,62768],{},[584,62769,15676],{},[523,62771,62772],{},"These images were mostly taken on friday, the third day of KubeCon.",[523,62774,62775,62776,62781,62782],{},"I was welcomed at the Rook both with swag from the Rook team for Rook. I also got the awesome green Rook birthday shirt, check it out on ",[527,62777,62780],{"href":62778,"rel":62779},"https:\u002F\u002Fwww.amazon.com\u002Fdp\u002FB07781SN5J",[531],"Amazon",", part of the Rook team and I wear it in the photos below.\n",[3069,62783],{"alt":62784,"src":62785},"Me with Rook swag","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171206_080008.jpg",[62787,62788,62789],"center",{},"We also took photos of the team and community users who were there.",[14001,62791,50037,62793],{"style":62792},"width:100%",[62794,62795,62796,62797,50037],"tbody",{},"\n        ",[62798,62799,62800,62801,62800,62806,62796],"tr",{},"\n            ",[62802,62803,62805],"td",{"style":62804},"width:50%","\n                ![KubeCon: Rook Team + Community photo #1](\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_104945.jpg)\n            ",[62802,62807,62808],{"style":62804},"\n                ![KubeCon: Rook Team + Community photo #2](\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Frook-team-photo-2.jpg)\n            ",[523,62810,62811],{},"Please note the image was actually a photo sphere, that is why it looks a bit \"bugged\".",[523,62813,62814,62818],{},[3069,62815],{"alt":62816,"src":62817},"KubeCon: Rook booth Shot #2","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_104619.jpg","\nThe Rook booth, logo and stickers are looking awesome, shoutout to their art designer.",[613,62820,56457],{"id":56456},[523,62822,62823],{},[3069,62824],{"alt":62825,"src":62826},"KubeCon: Keynote Day #1 Shot #1","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171206_092513.jpg",[3126,62828,62830],{"id":62829},"a-community-of-builders-cloudnativecon-opening-keynote-dan-kohn-executive-director-cloud-native-computing-foundation","A Community of Builders: CloudNativeCon Opening Keynote - Dan Kohn, Executive Director, Cloud Native Computing Foundation",[18903,62832],{"width":62833,"height":62834,"src":62835,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},560,315,"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FZ3aBWkNXnhw",[523,62837,62838,62839,62844],{},"There are over 4k+ people at the KubeCon. That is more than the last three events together. Even in point of terror attacks, we, the community\u002Fpeople \"continue developing, building\" our awesome projects.\nAdditionally to all the awesome tracks there has been the first Serverless track at KubeCon.\n\"Kubernetes is the Linux of the cloud\", it is Open Source Infrastructure that works anywhere.\nIt is amazing to see the statistics of the Kubernetes and other related projects at ",[527,62840,62843],{"href":62841,"rel":62842},"https:\u002F\u002Fdevstats.k8s.io",[531],"devstats.k8s.io",".\nContainers have pushed the boundaries allowing us for quick\u002Ffast delivery of applications.\nToday there are hundreds of Meetups around the world about Kubernetes and overall cloud native. There are free EdX courses by CNCF\u002FKubernetes available. Also the Certified Kubernetes Administrator \"programm has over 600 people already registered.",[3126,62846,62848],{"id":62847},"cncf-project-updates-michelle-noorali-senior-software-engineer-microsoft-azure","CNCF Project Updates - Michelle Noorali, Senior Software Engineer, Microsoft Azure",[18903,62850],{"width":62833,"height":62834,"src":62851,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FzPOlDe-J9ZA",[523,62853,62854],{},"A goal of the CNCF now is to reach commercial sustainability with the projects.\nThe CNCF member count is \"sky rocketing\" and currently at over 150+ members. This helps the community through funds to support projects.\nStats about the CNCF:",[668,62856,62857,62860,62863,62866],{},[638,62858,62859],{},"25 certified Kubernetes service providers (example cloud providers for an easy Kubernetes)",[638,62861,62862],{},"42 certified Kubernetes Partners",[638,62864,62865],{},"14 projects currently hosted",[638,62867,62868],{},"A lot of CNCF scholar ships in Texas, Austin and around the world",[523,62870,62871],{},"The next KubeCon will be held in Copenhagen on May 2018, additionally there will be a KubeCon in China, Shanghai in Novemeber 2018 to \"compensate\" the increasing usage in the Asian market of CNCF projects.",[523,62873,62874,62875,62878,62879,62882,62883,62886],{},"Kubernetes was the first project donated to the CNCF. This is especially awesome to look at how cloud native Kubernetes is. It allows scaling, allow for cross cloud deployments and much more.\nContainer Storage Interface (short CSI) allows simple and no vendor lockin storage integration for containers in general but will also soon be coming to Kubernetes.\nCoreDNS ",[567,62876,62877],{},"v1.0"," released, in Kubernetes ",[567,62880,62881],{},"v1.9.x"," it will be available as a replacement for kube-dns.\nContainerd (orignally built by Docker) has released version ",[567,62884,62885],{},"1.0.0",", there is also a (Kubernetes) Container Runtime Interface (short CRI) implementation available.\nCoreOS' rkt is security-minded and also CRI compatible. CoreOS \"created\" (and is currently maintaining) Container Network Interface (short CNI). CNI makes the network layer pluggable for not only containers.\nIf you haven't know yet, \"everyone\" uses CNI, Kubernetes, Docker, rkt, CRI-O, etc).",[523,62888,62889,856],{},[584,62890,62891],{},"Observability",[668,62893,62894,62901],{},[638,62895,62896,62897,62900],{},"Prometheus (with PromQL) was the second project accepted into CNCF. With the Prometheus ",[567,62898,62899],{},"v2.0"," release, they reduced the IO by 100x with the new storage engine used. Additionally there will PromCon's next year again.",[638,62902,62903,62904,62906,62907,62909],{},"Fluentd (solves the logging pipeline problem; aggregation, filter, etc) version ",[567,62905,62877],{}," has been released. This release contains a new Fluentd forward protocol ",[567,62908,14989],{},", improved Prometheus support\u002Fmetrics. Fluentd is more and more a full ecosystem, to further build on that they have released fluent-bit which allows forwarding of data\u002Flogs to Fluentd (it feels a bit like Elastic Beats).",[523,62911,62912],{},[3069,62913],{"alt":62914,"src":62915},"Fluentd logging flow","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171206_093611.jpg",[668,62917,62918,62921],{},[638,62919,62920],{},"OpenTracing is a vendor neutral standard for distributed tracing. They have released OpenTracoing implementations for 4 new API languages.",[638,62922,62923],{},"Jaeger implements the OpenTracing standard and is working on better integration into other CNCF projects.",[523,62925,62926,856],{},[584,62927,62928],{},"Relibaility",[668,62930,62931,62940,62948],{},[638,62932,62933,62934,62939],{},"Linkerd allows the creation of a service mesh. Linkerd has attracted many new big company users. They also announced a \"new\" project ",[527,62935,62938],{"href":62936,"rel":62937},"https:\u002F\u002Fconduit.io",[531],"Conduit.io"," it is also a service mesh but very lightweight and currently only for gRPC traffic.",[638,62941,62942,62943,1909],{},"Envoy is a service proxy. The integration into Kubernetes is done through an Ingress controller which can be found here ",[527,62944,62947],{"href":62945,"rel":62946},"https:\u002F\u002Fgithub.com\u002Fheptio\u002Fcontour",[531],"GitHub heptio\u002Fcontour",[638,62949,62950],{},"gRPC allowed Google to improve secutiry and relibaility for their services. They are currently working on creating implementations for more languages.",[523,62952,62953,856],{},[584,62954,11645],{},[668,62956,62957],{},[638,62958,62959,62960,62965,62966,1909],{},"TUF: Software Update Specifications. A goal is to retain as much security as possible (for example used for Internet of Things devices). They announced that ",[527,62961,62964],{"href":62962,"rel":62963},"https:\u002F\u002Fgithub.com\u002Ftheupdateframework\u002Fnotary",[531],"Notary",", which implements the TUF specification, has released version ",[567,62967,62968],{},"v0.6.0",[3126,62970,62972],{"id":62971},"accelerating-the-digital-transformation-imad-sousou-vp-software-services-group-gm-opensource-technology-center-intel-corporation","Accelerating the Digital Transformation - Imad Sousou, VP, Software Services Group & GM, OpenSource Technology Center, Intel Corporation",[18903,62974],{"width":62833,"height":62834,"src":62975,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FpqoDF4QCRy8",[523,62977,62978],{},"There is a new container runtime by Intel called Kata containers (\"Kata\" means \"Trust\" in Greek). It is especially taking a look at \"isolation\" of containers. Containers \"normally\" have less isolation due to a) more applications running on one host\u002Fnode and b) the containers are most of the time just separated by Kernel CGroups. It is kinda always a \"Speed OR Security\" (Container VS VMs).\nUsing Intel(c) Clear Containers and Hyper's runV allow hardware accelerated containers. Kata containers are compliant to the CRI specification.\nAdditionally good for the Kata container project is that a lot of contributors are not only from Intel(c) but also from other companies (\"independent\"). If you are interested get involved in the project!",[523,62980,62981],{},"Also there was a mention of the AlibabaCloud about their new X-Dragon bare metal cloud servers that can serve up to 4.5 Million pps. AlibabaCloud works on (better) integration for their cloud platform to Kubernetes",[3126,62983,62985],{"id":62984},"cloud-native-cd-spinnaker-and-the-culture-behind-the-tech-dianne-marsh-director-of-engineering-netflix","Cloud Native CD: Spinnaker and the Culture Behind the Tech - Dianne Marsh, Director of Engineering, Netflix",[523,62987,62988],{},[3069,62989],{"alt":62990,"src":62991},"KubeCon: Keynote Netflix Shot #1","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171206_101514.jpg",[18903,62993],{"width":62833,"height":62834,"src":62994,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FmfFtfaulCtg",[523,62996,62997],{},"Before I begin, this keynote\u002Fpresentation\u002Ftalk was one of the best presentations of KubeCon for me. It had so much to learn\u002F\"takeaway\" from.",[523,62999,63000,63001,63004],{},"The culture (of a company) impacts Tools and Technologies. At Netflix employees are encouraged to work with \"Freedom & Responsibility\" and \"Share information openly, broadly, and deliberately\".\nThe second point about sharing, code can be taken as an example for that. Employees\u002FTeams should be able to openly share their code. This again can be seen differently, from being broadly open by open sourcing code for the public (GitHub, GitLab.com, etc) or at least being able to share code in the company's code management system.\nBack to Netflix, there was a lot of pressure on the Spinnaker and Edge Center team. Every team solved their \"own\" problems fast, but didn't \"catch up\" with each other.\nTo have the \"Courage and Selflessness\" especially as an engineer, saying that he isn't able to keep up with the other project takes some \"balls\" to do.\nSpinnaker is a continous integration and deployment tool, to directly note it supports only ",[567,63002,63003],{},"Active\u003C->Active"," application deployments.\nIn 2015 Netflix released Spinnaker as an open source project. Open Source \"always\" does good to a project, as today it supports multiple cloud providers to due the pluggable and multi cloud provider architecture from the begining on.\nTo go into \"open sourucing an internal project\" a bit further, Spinnaker is a good example of how open sourcing a project can allow a company to gain from it. Through the community the project gained features like support for more cloud providers and also overall find issues \"better\" due to more users of the project.\nA point that can't be truer is \"You better understand your service than anybody else\". Who doesn't know \"every\" specific detail of their code they have written and I'm not talking about undocumented features, more of just the structure that someone could \"ask you in your sleep\" and get an instant response from you.\n\"Guardrails, not Gates\" \u003C- THIS, this is kinda mind blowing when you think about it. \"Engineers should decide when to deploy\", \"Am I ready to deploy without a manual step?\" these are questions you should ask yourself before going live. To get back to the first \"THIS\" again, you shouldn't make a gate someone can \"simply\" climb over. You should make a working guardrail to guide people to the correct thing.",[523,63006,63007],{},[3069,63008],{"alt":63009,"src":63010},"KubeCon: Keynote Netflix Shot #2","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171206_102123.jpg",[523,63012,63013],{},"A criticality for business' deployments is to more and more have \"Increasing interest in delegation(bility)\". Instead of what I can tell about myself to, do everything myself, know I can delegate something and not because I was told but because I want to.",[523,63015,63016],{},"An overall summary for some of these points is \"Think carefully about the tools you chose, are you fighting the culture with it?\". You should always take the culture of your company\u002Fenvironment in to account when choosing a tool\u002Ftechnology.\nFor example, \"does it make sense to use Kubernetes?\" \"We already have a working agile platform to deploy from. Why switch to Kubernetes?\".",[523,63018,63019],{},"As I wrote in the beginning for this keynote, it was one of the best keynote talks for me. I hope this can be read from writing.",[3126,63021,63023],{"id":63022},"cloud-native-at-aws-adrian-cockcroft-vice-president-cloud-architecture-strategy-amazon-web-services","Cloud Native at AWS - Adrian Cockcroft, Vice President Cloud Architecture Strategy, Amazon Web Services",[523,63025,63026],{},[3069,63027],{"alt":63028,"src":63029},"AWS works to integrate cloud native components into ECS","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171206_103216.jpg",[18903,63031],{"width":62833,"height":62834,"src":63032,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002F5U-6sxR5DaQ",[523,63034,63035],{},"Amazon Web Services is looking forward to \"Grow Communities, Improve Code, Increase Contributions\". A Kubernetes related point is that the scalability testing will be moved to AWS soon.\nAbout AWS Network, they have it fully integrated into CNI and the changes are already in the upstream. Just use CNI and you \"get\" AWS networking\nThere is\u002Fwill be some kind of bare metal servers available on AWS.\nAWS Fargate takes away \"everything\" around Kubernetes. It is kind of like SaaS for Kubernetes where you just provide the applications. This is especially good for when you don't want to run the instances below your Kubernetes.\nFargate is a bit like AWS's own GKE.\nThey are building \"An Open Source Kubernetes Experience\", where you simply bring your \"manifests\" and are good to go. The \"Open Source Kubernetes Experience\" from AWS will also try to integrate most AWS services \"natively\" into the clusters.\nIf you want to dig deeper with security on AWS, there will be IAM authentication with Heptio and additionally Kube2IAM, which adds IAM to Pods (ServiceAccount), but this is currently work in progress.",[613,63037,51330],{"id":51329},[3126,63039,63041,63042,63045],{"id":63040},"the-true-costs-of-running-cloud-native-infrastructure-b-dmytro-dyachuk-pax-automa","The True Costs of Running Cloud Native Infrastructure ",[747,63043,63044],{},"B"," - Dmytro Dyachuk, Pax Automa",[6072,63047,63048,63052],{},[523,63049,63050],{},[584,63051,6189],{},[523,63053,63054],{},"I haven't gotten to the first part of the talk.",[18903,63056],{"width":62833,"height":62834,"src":63057,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FNElaNl1Kwkw",[523,63059,63060],{},"Still the part I saw was pretty interesting.\nOverall most costs are for compute power (not \"only\" energy power, especially CPU), storage second and third especially in case of colocation people\u002Fstaff maintaining the servers.\nStorage is second because it depends on how many IOPS you want\u002Fneed. If you want good good enough hardware to deliver the IOPS you need and want it may even come in first. This shouldn't be overlooked during your planning.",[523,63062,63063],{},"Aggregated values of how often the workload(s) got scaled up'n'down is a \"must\" to take the future into account and not run out of resources mid-way of a new deployment.\nThrough the dynamic of clouds (providers) there is no issue for resources, as they can be added on the fly, but still it is not that easily with 1:1 deployments (looking at different cloud regions, resources may not available the same between regions).\nOver time the amount of reserved resources should be increased, this potentially also applies to limits for deployed workloads. Increasing the reserved resources and limits on applications over time allows to make sure that for reserved at least always what is needed is available and for limits on workloads they allow for better control of what is needed for scaling up further.\nThis allows to make sure that for existing and new demand there are enough resources available for use.\nOver provisioned resources can be used for workloads as an example batch jobs or any workload that can be scaled down without impact to customers.",[523,63065,63066],{},[3069,63067],{"alt":63068,"src":63069},"KubeCon Talk: Colocation, AWS side by side","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171206_151637.jpg",[523,63071,63072],{},"Taking a closer look at colocation, there are \"always\" more resources available as needed and the costs with that only increase when more is needed (not taking upgrades and hardware End Of Life into account here).\nThrough this money can be saved, but to be able to do this in a good way the right analytical values need to be taken into calculation.",[523,63074,63075],{},[3069,63076],{"alt":63077,"src":63078},"KubeCon Talk: Colocation Provisioning workload diagram","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171206_151414.jpg",[523,63080,63081],{},"Additionally to note here is that at one point a cloud provider (in the talk it was AWS as an example), colocation wins as the costs \"stay\" on a continual level and only increase when new\u002Fmore resources are needed.",[523,63083,63084],{},[3069,63085],{"alt":63086,"src":63087},"KubeCon Talk: Colocation vs AWS cost Cross over point","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171206_151753.jpg",[523,63089,63090,63091,856],{},"It really depends on the changes of the workload and what the application(s) needs for dynamic scaling.\n",[584,63092,63093],{},"Examples",[668,63095,63096,63099],{},[638,63097,63098],{},"CPU heavy workload may be better run on AWS as CPU is cheaper to up'n'down scale quickly on demandm, where colocation\u002Fbare metal could be more expensive.",[638,63100,63101],{},"Storage heavy workload may better of with colocation may be cheaper due to the \"one time\" cost for the storage servers.",[523,63103,63104],{},"Additionally it may also only stays cheap(er) at a certain scale of the total workloads with colocation. If you only have a huge spike of load sometimes a cloud will be cheaper than colocation.",[523,63106,63107],{},"My takeaway is that you should always plan for at least one cloud provider and colocation (bare metal).",[3126,63109,63111],{"id":63110},"cri-o-all-the-runtime-kubernetes-needs-and-nothing-more-mrunal-patel-red-hat","CRI-O: All the Runtime Kubernetes Needs, and Nothing More - Mrunal Patel, Red Hat",[18903,63113],{"width":62833,"height":62834,"src":63114,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FNVa8xR4Eyj8",[523,63116,63117,63121,63122,63125],{},[527,63118,401],{"href":63119,"rel":63120},"http:\u002F\u002Fcri-o.io\u002F",[531]," or Container Runtime Interface Open utilizes ",[567,63123,63124],{},"runC"," to create and run containers. CRI-O seems to allow an \"init\" system for the container process to be started that does the reaping of \"detached\" processes.\nThe integration into Kubernetes also seem to be simple and stable. The change to use CRI-O for Kubernetes passes over 300 tests for PRs in Kubernetes, without any changes to Kubernetes in \"favor\" of CRI-O.\nAs most container runtimes do, it utilizes CNI to configure the network of a container.",[523,63127,63128],{},"CRI-O looks like a pretty good alternative to Docker (and other runtimes) when running a Kubernetes environment.",[523,63130,63131,63132,63135,63136,63141],{},"Next steps for CRI-O will be to release version ",[567,63133,63134],{},"1.9",". The releases will be in hand with each Kubernetes versions and support the Kubernetes specific version too.\nTheir blog is available at: ",[527,63137,63140],{"href":63138,"rel":63139},"https:\u002F\u002Fmedium.com\u002Fcri-o",[531],"CRI-O Medium",".\nFor OpenShift users it is also already planned to use CRI-O instead of Docker (which is currently the default).\nIt is full feature compatible to running Kubernetes with Docker. Log format is different to Docker's format. Everything that directly consumes the logs needs to use the CRI-O format (like Kubernetes cluster addon Fluentd).\nCRI-O is tied to Kubernetes (and will be tested with Kubernetes together too). When running something else than containers on Kubernetes, one should consider evaluating the available container runtimes to see which fits the workload.",[523,63143,63144],{},"A switch to CRI-O for 100% Kubernetes environments seems like a good step to do. Depending on how you update your Kubernetes, you may not have any additional steps (maybe even less) after a switch to CRI-O.",[3126,63146,63148,63149,63151],{"id":63147},"building-a-secure-multi-protocol-and-multi-tenant-cluster-for-internet-facing-services-a-bich-le-platform9","Building a Secure, Multi-Protocol and Multi-Tenant Cluster for Internet-Facing Services ",[747,63150,38411],{}," - Bich Le, Platform9",[18903,63153],{"width":62833,"height":62834,"src":63154,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FtFdcrncaxD4",[523,63156,63157,63158,63163,63164,63166],{},"Platform9 has a project named ",[527,63159,63162],{"href":63160,"rel":63161},"https:\u002F\u002Fgithub.com\u002Fplatform9\u002Fdecco",[531],"Decco"," that manages Namespaces and Network Policies in Kubernetes for them. They use ",[567,63165,51062],{},"s for that.",[523,63168,63169],{},[3069,63170],{"alt":63171,"src":63172},"KubeCon Talk: Decco Traffic Management Slide","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171206_163841.jpg",[523,63174,63175],{},"Additionally to network policies Decco has upcoming support to do authentication of traffic with Istio. The current authentication flows were shown for TCP and HTTP traffic.",[523,63177,63178],{},[3069,63179],{"alt":63180,"src":63181},"KubeCon Talk: Traffic Flow TCP Slide","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171206_164203.jpg",[523,63183,63184],{},[3069,63185],{"alt":63186,"src":63187},"KubeCon Talk: Traffic Flow HTTP Slide","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171206_164321.jpg",[523,63189,63190],{},"Looks like a pretty interesting project to manage multiple projects (and maybe even environments\u002Fstages) on top of a single Kubernetes cluster. THis seems like a good possibility for companies looking to regulate namespace creation and security around them.",[613,63192,58151],{"id":58150},[523,63194,63195],{},"I haven't been to many talks\u002Fpresentations today due to many interesting discussions\u002Fchats with the Rook team and other awesome people at KubeCon.",[3126,63197,63199],{"id":63198},"service-meshes-and-observability-ben-sigelman-lightstep","Service Meshes and Observability - Ben Sigelman, LightStep",[18903,63201],{"width":62833,"height":62834,"src":63202,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FRGT5XHH_Gis",[523,63204,63205],{},"\"A Service Mesh can help\"! Nobody likes to write the same things over and over again. Through reduction of one big service into many (micro)services this can be achieved (depending on the type of service you are running). This thought goes into the direction that when you use smaller parts (microservices) for services, you can reuse them and scale them individual.\nBut there remains one big problem for microservices. What can be done to help reduce the \"Ahh which microservice is broken?\" during on-call. A distributed tracing tool is a good \"weapon\" against that and to gain insight.\nOpenTracing can help to keep the difference between tracing formats between multiple languages small as it is a standard.",[523,63207,63208,63209,63212],{},"The big part of ",[584,63210,63211],{},"distributed"," tracing is having all information for a trace from the first service the traffic enters to every service with all the information required to debug \"any\" issues (be it performance, errors or exceptions).\nWhen the (micro)services are more complex this can be a big hassle to achieve, as services then sometimes have queues for requests, etc which makes tracing even harder to achieve and read during analysis.",[6072,63214,63215],{},[523,63216,63217],{},"Donuts as a Service (DaaS): \"Scaling fast and running into performance issues\"",[523,63219,63220],{},"Jaeger, a CNCF hosted project, allows you to view the traces in a detailed way, but you still need to have the whole data of every trace.\nAnalyzing traces on a huge business level is harder the more concurrency of overall requests you are having.\nCurrently there are tracing sidecars available for some protocols\u002Fapplications already (for example nginx, Conduit).",[523,63222,63223],{},"BTW Examples involving Donuts are pretty nice.",[3126,63225,63227],{"id":63226},"kubernetes-this-job-is-too-hard-building-new-tools-patterns-and-paradigms-to-democratize-distributed-system-development-brendan-burns-distinguished-engineer-microsoft","Kubernetes: This Job is Too Hard: Building New Tools, Patterns and Paradigms to Democratize Distributed System Development - Brendan Burns, Distinguished Engineer, Microsoft",[18903,63229],{"width":62833,"height":62834,"src":63230,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FgCQfFXSHSxw",[523,63232,63233,63234,63236],{},"Enable people to build distributed applications.\nA lot of tools\u002Fsteps before deployment. Before you can think of your application you have to go throuh the \"whole\" process of what to use.\nA problem with development would be that some values for example port ",[567,63235,31891],{}," specified in the application, the Dockerfile and Kubernetes manifest makes it prone to errors when one change in these files has been forgotten.",[523,63238,63239,63240,63242],{},"First principle is to have a \"Everything in one place\" that contains information such as what is the port of the application. So that it only has to be changed in one location and not cause issues because it was only changed in one in later times.\nSecond principle is \"Build libraries, not platforms\". Meaning that instead of always building 100% specific to an application, write code that can be reused in form of libraries that is most of the time.\nThird is \"Encourage sharing and re-use\". That built applications\u002Flibraries are shared with teams or even the open source community (GitHub, GitLab.com).\nI personally think that the second and third are especially connected with each other. Sharing a library allows to ",[584,63241,12261],{}," write code over and over again, and lower the \"risk\" of building a \"platform\" instead of an application.",[523,63244,63245],{},"Takeaways:",[668,63247,63248,63251,63254,63257],{},[638,63249,63250],{},"Why not unit test your configs too?",[638,63252,63253],{},"Design your application in (pseudo) code.",[638,63255,63256],{},"Make the application\u002Fcode more approachable (example for new employees).",[638,63258,63259],{},"As hopefully always, unit, style and other tests should be written and run.",[523,63261,63262],{},"When looking into which \"item\" you can map to the following:",[668,63264,63265,63268,63271],{},[638,63266,63267],{},"Standard Library -> ???",[638,63269,63270],{},"Runtime -> Kubernetes",[638,63272,63273],{},"Objects -> Containers",[523,63275,63276],{},"There is nothing \"universal\" for a \"Standard Library\".\nThis is where the Metaparticle project comes in. It allows for an application to contain instructions on how to build, push and deploy itself. Also functions for distritbuted sharding, locking and other important functionality which is normally written over and over again is included in Metaparticle.\nAdditionally it tried to reduce gaps for the \"problems\" with knowledge of building distributed applications and as mentioned earlier code for \"simple\" distributed applications tasks (locking, sharding, etc) isn't written over and over again.",[3126,63278,63280],{"id":63279},"can-100-million-developers-use-kubernetes-alexis-richardson-ceo-weaveworks","Can 100 Million Developers Use Kubernetes? - Alexis Richardson, CEO, Weaveworks",[18903,63282],{"width":62833,"height":62834,"src":63283,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002F21l8v6eObcc",[523,63285,63286],{},"The bot that colorizes black and white images, OpenFaaS (Functions as a Service) project played a huge role.\nWhen something (an application) could be \"merged\"\u002Fsplitted (libraries), it will reduce the time needed to re-do a lot of work\u002Fcode already done (multiple times).",[523,63288,63289],{},"A big point during the keynote was:\n\"What are we building for?\" -> For the future of today's kids.",[613,63291,63293],{"id":63292},"community-awards","Community Awards",[18903,63295],{"width":62833,"height":62834,"src":63296,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FDllNMIY4HzU",[523,63298,63299],{},"Congratulations to all the winners of the awards!\nThank you for your contributions to the community!",[613,63301,63303],{"id":63302},"party","Party",[523,63305,63306],{},"There was a marching band playing after the Keynotes in the sponsor showcase:",[523,63308,63309],{},[3069,63310],{"alt":63311,"src":63312},"KubeCon: Party marching band","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171206_182054.jpg",[523,63314,63315,63316,63320,63321,63326],{},"I only attended the party with Rook and ",[527,63317,63319],{"href":57703,"rel":63318},[531],"SPIFFE",", not the \"official\" KubeCon one. It was interesting to see ",[527,63322,63325],{"href":63323,"rel":63324},"http:\u002F\u002Fwww.ignitetalks.io\u002F",[531],"Ignite Talks"," for the first time.",[2979,63328],{},[535,63330,52788],{"id":52787},[613,63332,56457],{"id":63333},"morning-keynotes-1",[523,63335,63336],{},[3069,63337],{"alt":63338,"src":63339},"KubeCon: Keynote Day #2 Shot #1","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_090311.jpg",[3126,63341,63343],{"id":63342},"kubecon-opening-keynote-project-update-kelsey-hightower-staff-developer-advocate-google","KubeCon Opening Keynote - Project Update - Kelsey Hightower, Staff Developer Advocate, Google",[18903,63345],{"width":62833,"height":62834,"src":63346,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002F07jq-5VbBVQ",[523,63348,63349],{},[3069,63350],{"alt":63351,"src":63352},"KubeCon: Keynote Kelsey Hightower at it again","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_091604.jpg",[523,63354,63355],{},"\"Kubernetes changelog is boring\" because Kubernetes is now on a level\u002Fmaturity as a project on which you can build stuff on top of it!",[523,63357,63358,63363],{},[527,63359,63362],{"href":63360,"rel":63361},"https:\u002F\u002Ftwitter.com\u002Fkelseyhightower",[531],"Kelsey Hightower"," showed off voice controlled Kubernetes cluster creation on Google Cloud Platform.",[523,63365,63366,63367,63369],{},"If you need to create a ticket to deploy, you should stay with having separate clusters (and don't work against the \"culture\").\n\"No one cares\", to be exact developers, don't want ",[567,63368,15269],{}," on their systems. They just want to develop their application(s)\u002Fproject(s).\n\"Wanted is that when a code change is done, the dev gets a URL to where it is running (even better get metrics for it too)\" like GitLab Auto DevOps style which allows to do exactly that automatically for you.\nConfig is \"Implementation details\".\n\"Be in shame when you build your releases on a laptop\" I can't agree more on such a point.\nA full workflow should be simply available for (every) application. This really goes into the direction of using something like GitLab Auto DevOps, which kind of takes care of the workflow and instantly sets you up with something working.",[668,63371,63372,63375],{},[638,63373,63374],{},"Push -> Build -> Deploy to dev (with URL + Metrics available)",[638,63376,63377],{},"Tag -> build -> Deploy to QA",[523,63379,63380],{},"\"Visibility for users\", when users have the visibility they don't have the need to get access\u002Ftools (kubectl), because they already know what is going on.\nAnother point \"Don't rebuild the image between QA and Live\" that I also just can agree to 100% in. There is a reason why you test something in QA and with containers you just move it to production\u002Flive because you know that image will work and do what we tested.\nThis is a very interesting point for Emergencies, \"Emergencies should allow to run without pupelines\". Depending on how you see it, this is kind of controversial. I'll leave it at that.",[3126,63382,63384],{"id":63383},"kubernetes-secret-superpower-chen-goldberg-anthony-yeh-google","Kubernetes Secret Superpower - Chen Goldberg & Anthony Yeh, Google",[18903,63386],{"width":62833,"height":62834,"src":63387,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002F1kjgwXP_N7A",[523,63389,63390],{},"A large eco system has formed around Kubernetes.",[523,63392,63393],{},[3069,63394],{"alt":63395,"src":63396},"KubeCon: Keynote Kubernetes' system layers","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_093656.jpg",[523,63398,63399],{},"Kubernetes is ready for us, the community and companies to extend\u002Fbuild on, as in the previous Keynote written.",[523,63401,63402],{},"Kubernetes is build for chaos as a cloud native application should be able to handle.\nBecause of Kubernetes \"being built for chaos\", you can see Kubernetes as many reconcilation loops \"all the time\" to make sure chaos gets resolved.",[523,63404,63405,63406,63408],{},"Through techniques like ",[567,63407,51062],{},"s it is simple to build an \"extension\" for the Kubernetes API server.\nBut there are also other ways to build upon the Kubernetes Apiserver, which can be seen in the images below.",[523,63410,63411],{},[3069,63412],{"alt":63413,"src":63414},"KubeCon: Keynote Kubernetes extension from flexible to easier","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_093957.jpg",[523,63416,63417],{},[3069,63418],{"alt":63419,"src":63420},"KubeCon: Keynote Rook mentioned on a slide","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_094055.jpg",[523,63422,63423],{},"YES!! Rook again on a slide during the Keynotes. This is awesome, to get recognizition for Rook as an operator at such a big event.",[523,63425,63426,63431,63432,63434,63435,63437],{},[527,63427,63430],{"href":63428,"rel":63429},"https:\u002F\u002Fgithub.com\u002FGoogleCloudPlatform\u002Fkube-metacontroller",[531],"github GoogleCloudPlatform\u002Fkube-metacontroller"," is a project to extend Kubernetes on a meta level through ",[567,63433,51062],{},"s.\nThe kube-metacontroller is a ",[567,63436,51062],{}," controller. It is not in the Kubernetes lifecycle, it is an \"external\" project.",[523,63439,63440],{},[3069,63441],{"alt":63442,"src":63443},"KubeCon: Keynote kube-metacontroller demo","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_094446.jpg",[523,63445,63446,63447,63449],{},"The demo shown was about re-implementing StatefulSets as CatSets with a \"custom\" specificiation structure.\nNew features are more likely to come in form of ",[567,63448,51062],{},"s from projects of users and companies, and not from Kubernetes directly anymore. Users can now just implement a new feature as they want\u002Fneed it.",[523,63451,63452,63453,63455],{},"Extensibility is about empowering users. Google and IBM are building Istio using ",[567,63454,51062],{},"s to make it easy to use and \"integrate\" with existing clusters.",[3126,63457,63459],{"id":63458},"red-hat-making-containers-boring-again-clayton-coleman-architect-kubernetes-and-openshift-red-hat","Red Hat: Making Containers Boring (again) - Clayton Coleman, Architect, Kubernetes and OpenShift, Red Hat",[18903,63461],{"width":62833,"height":62834,"src":63462,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FAE0gZlA2sZ8",[523,63464,63465],{},"\"Infrastructure allows us to turn the impossible into the ordinary.\"\nLots of applications in Kubernetes send lots of events in Kubernetes. Red Hat has submitted many issues and pull requests to fix issues with events, metrics and overall running Kubernetes in a \"huge\" environment.",[523,63467,63468],{},[3069,63469],{"alt":63470,"src":63471},"KubeCon: Keynote Making Kubernetes boring","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_095910.jpg",[523,63473,63474],{},"The release of etcd3 helped fix issues with scaling, as the memory use of etcd went down about -66%. Which is pretty awesome.",[523,63476,63477],{},"\"Boring\" effectly means a certain maturity of a project and not (always) the death of it.",[3126,63479,63481],{"id":63480},"pushing-the-limits-of-kubernetes-with-game-of-thrones-zihao-yu-illya-chekrygin-hbo","Pushing the Limits of Kubernetes with Game of Thrones - Zihao Yu & Illya Chekrygin, HBO",[18903,63483],{"width":62833,"height":62834,"src":63484,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002F7skInj_vqN0",[523,63486,63487],{},"Their talk was about the experience with Kubernetes at HBO.",[523,63489,63490],{},"Even a cloud, like AWS or GCE, has limits in the end.",[523,63492,63493],{},"One of the reasons why they use Kubernetes is that the \"Batteries are included\", \"everything\" can be switched out.\nThey are using Terraform to create their Kubernetes clusters on top of their cloud provider.\nThey have a fixed number of masters, a failed one will be replaced. Nodes are up'n'down scaling all the time.\nStill in the begining some issues, like Prometheus pod is rescheduled on scale down.\nThey register their minons with taints depending if their were either more of scaled instance or there by \"default\"\u002Freserved.\nAdditionally they have backup minions (not sure if so, but maybe they are cluster independent at least per region) if there is no more instance type available (to be honest this kind of sounds like hoarding of resources).\nService Types in Kubernetes may have some problems in \"high\" load clusters:",[668,63495,63496,63504],{},[638,63497,63498,36823,63501,63503],{},[567,63499,63500],{},"type: ClusterIP",[567,63502,158],{}," have problems keeping up with burst traffic spikes.",[638,63505,63506,63509],{},[567,63507,63508],{},"type: LoadBalancer"," is limited by the AWS\u002Fcloud providers API rate limits.",[523,63511,63512,63513,63516],{},"They had the best experience with ",[567,63514,63515],{},"type: NodePort"," and using ELBs that have been \"manually\" (not through Kubernetes) setup.",[523,63518,63519],{},[3069,63520],{"alt":63521,"src":63522},"KubeCon: Keynote Networking Services","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_101452.jpg",[523,63524,63525],{},"Flannel has problems scaling beyond a certain point. There are multiple issues open at the Flannel project to look further into these issues, most of the issues have already been resolved.",[523,63527,63528],{},[3069,63529],{"alt":63530,"src":63531},"KubeCon: Keynote Flannel scaling problems","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_101218.jpg",[523,63533,63534,63535,63538,63539,63542],{},"DNS ",[567,63536,63537],{},"ndots:5"," has some issues because it creates a lot of \"bad\" requests. The image shows all possibilities the name ",[567,63540,63541],{},"pgsql.backend.hbo.com"," would take:",[523,63544,63545],{},[3069,63546],{"alt":63547,"src":63548},"KubeCon: Keynote kube-dns ndots issue","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_101544.jpg",[523,63550,63551,63552,63554,63555,714,63558,587,63561,63564,63565,63567,63568,63573,63574,1909],{},"To improve this you can tune ",[567,63553,32065],{}," by adding flags like ",[567,63556,63557],{},"--cache",[567,63559,63560],{},"--address",[567,63562,63563],{},"--server=\u002Fhomeboxoffice.com\u002F10.1.2.3#53",". More details about tweaking ",[567,63566,32065],{}," in general can be found at ",[527,63569,63572],{"href":63570,"rel":63571},"https:\u002F\u002Fgithub.com\u002Frsmitty",[531],"Spencer Smith","'s blog post ",[527,63575,63578],{"href":63576,"rel":63577},"https:\u002F\u002Frsmitty.github.io\u002FKubeDNS-Tweaks\u002F",[531],"KubeDNS Tweaks for Performance",[523,63580,63581],{},[3069,63582],{"alt":63583,"src":63584},"KubeCon: Keynote kube-dns tunning","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_101717.jpg",[523,63586,63587],{},"Using Prometheus and cAdvisor is not that performant\u002F\"good\" of an idea with 300 and more nodes with every node having 40 cores each and over 20k containers running in the cluster.",[523,63589,63590],{},[3069,63591],{"alt":63592,"src":63593},"KubeCon: Keynote Kubernetes Telemetry","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_101836.jpg",[523,63595,63596],{},"HBO's advice:",[6072,63598,63599,63602],{},[523,63600,63601],{},"\"Were We Ready?\":",[668,63603,63604,63607,63610],{},[638,63605,63606],{},"Load test",[638,63608,63609],{},"Load test more!",[638,63611,63612],{},"Load test the SHIT Out of it!!!\n- HBO",[523,63614,63615],{},[3069,63616],{"alt":63617,"src":63618},"KubeCon: Keynote HBO's advice","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_102010.jpg",[3126,63620,63622],{"id":63621},"progress-toward-zero-trust-kubernetes-networks-spike-curtis-senior-software-engineer-tigera","Progress Toward Zero Trust Kubernetes Networks - Spike Curtis, Senior Software Engineer, Tigera",[18903,63624],{"width":62833,"height":62834,"src":63625,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FAgxt9Vg-YP4",[523,63627,63628],{},"Most clouds use Calico Project for their network security policy application.\nModern attacks have become more sophisticated.",[523,63630,63631],{},[3069,63632],{"alt":63633,"src":63634},"KubeCon: Keynote evolution of secure application connectivity","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_102333.jpg",[523,63636,63637,63638,63642,63643,63645],{},"One way to better protect against attacks, is to do network segmentation.\n",[527,63639,63641],{"href":27818,"rel":63640},[531],"Isitio"," handles it transparently for applications.\nThey announced that Calico support for Kubernetes network security policy and Istio service mesh.\nKubernetes already allows authentication through ",[567,63644,22299],{},"s token which would allow each Pod to authenticate itself.",[523,63647,63648,63649,63654,63655,63660],{},"By reducing the trust (network segmentation) in the network the security is increased. Also named Zero Trust network model.\n",[527,63650,63653],{"href":63651,"rel":63652},"https:\u002F\u002Fgithub.com\u002Fprojectcalico\u002Fapp-policy",[531],"github.com projectcalico\u002Fapp-policy","\nTigera announced ",[527,63656,63659],{"href":63657,"rel":63658},"https:\u002F\u002Ftigera.io\u002Fcnx",[531],"Tigera CNX"," which is for especially targeted to businesses that want a secure application connectivity platform.",[3126,63662,63664],{"id":63663},"the-road-ahead-on-the-kubernetes-journey-craig-mcluckie-ceo-heptio","The Road Ahead on the Kubernetes Journey - Craig McLuckie, CEO, Heptio",[523,63666,63667],{},[3069,63668],{"alt":63669,"src":63670},"KubeCon: Keynote Road Ahead on the Kubernetes Journey Shot #1","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_102922.jpg",[18903,63672],{"width":62833,"height":62834,"src":63673,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002F3FR82H7NwAw",[523,63675,63676],{},"\"The community gotta figure it (\u002Fthe future) out\"",[523,63678,63679],{},"If a developer needs to wait days to get a virtual machine to develop, the productivity is in the cellar. Development productivity is important for both the company and the developer.\nA cloud world kinda consists of everything \"Everything as a Service\".\nIn a world of microservices disaster recovery is very important, when a lot of services depend on each other it is important to correctly do a disaster recovery.",[523,63681,63682],{},[3069,63683],{"alt":63684,"src":63685},"KubeCon: Keynote Seperation of concerns","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_103535.jpg",[523,63687,63688,63689,63694,63695,63700,63701,63704],{},"Most cloud providers want\u002Fhave a upstream conformance Kubernetes as a Service. The Kubernetes always works everywhere the same, which is good for us the people.\nThat is what a tool like ",[527,63690,63693],{"href":63691,"rel":63692},"https:\u002F\u002Fgithub.com\u002Fheptio\u002Fsonobuoy",[531],"Heptio Sonobuoy"," is for, running\u002Fpackaging (conformance) tests to run on multiple cloud providers with ease.\nHaving the possibility for multi-cloud is the dynamic to move between clouds and get what you need, where you want.\nHeptio is working with Microsoft to bring their project ",[527,63696,63699],{"href":63697,"rel":63698},"https:\u002F\u002Fgithub.com\u002Fheptio\u002Fark",[531],"Ark"," disaster recovery and portability to Microsoft Azure.\n",[527,63702,63699],{"href":63697,"rel":63703},[531]," seems to be a shot worth to look into for disaster recovery of Kubernetes (and storage in Kubernetes).\nThe storage part is still more or less work in progress depending on where you are running your Kubernetes cluster. There is already support for some clouds like AWS and GCE, with Azure coming up through the cooperation with Microsoft.",[523,63706,63707],{},"\"Enterprise is.. complicated\" because there is no \"one\" tool for example Ingress, Logging, Monitoring, CI\u002FCD, Security and Stateful services that everyone uses right now.\nAdditionally the politics and \"rules\" in each company are always different, and at least for a platform like Kubernetes a formalization of extensibility is good to do.\nCompanies using Kubernetes are making it easier for new employees to faster begin working and be productive. This still depends on how they allow access to Kubernetes and how the rollout\u002Fdeployment of applications is done but still through tools like Helm or good old manifests it is easier.",[613,63709,51330],{"id":63710},"talks-1",[3126,63712,63714,63715,63717],{"id":63713},"extending-kubernetes-101-a-travis-nielsen-quantum-corp","Extending Kubernetes 101 ",[747,63716,38411],{}," - Travis Nielsen, Quantum Corp",[18903,63719],{"width":62833,"height":62834,"src":63720,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002Fyn04ERW0SbI",[523,63722,63723,63724,63726,63727,63729],{},"Kubernetes resources are declarative. You want a namespace, you get a namespace.\nWhen wanting to declare your own resources, ",[567,63725,51062],{},"s (CRDs) are what you want to do. To note for ",[567,63728,51062],{},"s they use the same pattern as the built-in resources.",[523,63731,63732,63733,63735,63736,63738],{},"You declare it and the \"owner\" in the Kubernetes cluster of the ",[567,63734,51062],{}," controller makes it happen.\nThe traditional approach is to create a REST API \"outside\" of Kubernetes. This isn't a good way to run something \"Kubernetes-native\".\nThe ",[567,63737,51062],{}," objects are as simply edited as every other object in Kubernetes.\nUsing Kubernetes objects directly is way better for Devs and Ops to use, as it streamlines the way to use something in the \"Kubernetes way\" (manifests).",[523,63740,63741,63742,63744,63745,63747],{},"When developing ",[567,63743,51062],{},"s you should design the ",[567,63746,51062],{}," properties. Additionally in Kubernetes 1.8+ there is code generation available to make resources available to clients to use\u002Fconsume better.",[523,63749,63750],{},"The flow of an operator is like:",[635,63752,63753,63759,63765,63770],{},[638,63754,63755,63756,63758],{},"Design the ",[567,63757,51062],{}," properties.",[638,63760,63761,63762,63764],{},"Register the ",[567,63763,51062],{}," at the API server.",[638,63766,63767,63768,1909],{},"Run a watch loop on your ",[567,63769,51062],{},[638,63771,63772,63773,63775],{},"On events to the ",[567,63774,51062],{},", trigger defined functions\u002Fmethods.",[523,63777,63778,63779,63781],{},"An example ",[567,63780,51062],{}," could look like this:",[523,63783,63784],{},[3069,63785],{"alt":63786,"src":63787},"KubeCon: Talk Extend Kubernetes example CustomResourceDefinition","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_112529.jpg",[523,63789,63790,63791,1909],{},"It can has any kind of structure as long as it can be done with a YAML file.\nThe code of the sample operator shown is available at ",[527,63792,63795,63796,5620],{"href":63793,"rel":63794},"https:\u002F\u002Fgithub.com\u002Frook\u002Foperator-kit\u002Ftree\u002Fmaster\u002Fsample-operator",[531],"GitHub rook\u002Foperator-kit - ",[567,63797,63798],{},"\u002Fsample-operator",[523,63800,63801],{},[3069,63802],{"alt":63803,"src":63804},"KubeCon: Talk Extend Kubernetes example CustomResourceDefinition Go code structure","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_112731.jpg",[523,63806,63807,63808,63810,63811,25726,63813,63815,63816,63818],{},"In Go to pickup a ",[567,63809,51062],{}," for (automatic) code generation, you just add annotations in the code.\nAdditionally to be able to list each ",[567,63812,51062],{},[567,63814,51062],{}," structure with an \"array\"\u002Flist type of the ",[567,63817,51062],{}," should be also created.",[523,63820,63821,63822,714,63825,587,63827,63830,63831,63833,63834,63836],{},"As written in the fourth point in the operator flow, an operator reacts on events such as ",[567,63823,63824],{},"Add",[567,63826,265],{},[567,63828,63829],{},"Delete"," during the watch of the ",[567,63832,51062],{},"s.\nThe operator should should \"include\" the code generated by the Kubernetes ",[567,63835,51062],{}," generation tool.",[523,63838,63839,63840,63842,63843,1909],{},"An operator kit is useful to not write the same code for handling ",[567,63841,51062],{},"s over and over again, for example ",[527,63844,63847],{"href":63845,"rel":63846},"https:\u002F\u002Fgithub.com\u002Frook\u002Foperator-kit",[531],"GitHub rook\u002Foperator-kit",[523,63849,63850],{},"Rook was named as example (with it's operator-kit, see link above):",[523,63852,63853],{},[3069,63854],{"alt":63855,"src":63856},"KubeCon: Talk Extend Kubernetes Rook project","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_114247.jpg",[3126,63858,63860,63861,63863],{"id":63859},"building-helm-charts-from-the-ground-up-an-introduction-to-kubernetes-i-amy-chen-heptio","Building Helm Charts From the Ground Up: An Introduction to Kubernetes ",[747,63862,27787],{}," - Amy Chen, Heptio",[18903,63865],{"width":62833,"height":62834,"src":63866,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FvQX5nokoqrQ",[523,63868,63869],{},"Helm is like a \"version control system\" for Kubernetes manifests.\nInstead of \"normal\" Kubernetes only allows to rollback certain types of objects, like Deployments.\nHelm allows to rollback more than that through versioning of manifest as \"bundles\".",[523,63871,63872],{},"It even simplifies installing, upgrading of objects in Kubernetes that have been created through Helm.",[3126,63874,63876,63877,63879],{"id":63875},"vault-and-secret-management-in-kubernetes-i-armon-dadgar-hashicorp","Vault and Secret Management in Kubernetes ",[747,63878,27787],{}," - Armon Dadgar, HashiCorp",[18903,63881],{"width":62833,"height":62834,"src":63882,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FFhUJYwM_xy0",[738,63884,63886],{"className":1621,"code":63885,"language":1623,"meta":743,"style":743},"Application requests Credentials -> Vault -> Create Credentials in Database\nApplication \u003C- Vault \u003C- Return created Credentials to Application\n",[567,63887,63888,63920],{"__ignoreMap":743},[747,63889,63890,63892,63895,63898,63901,63903,63906,63908,63910,63913,63915,63917],{"class":749,"line":750},[747,63891,12433],{"class":1630},[747,63893,63894],{"class":802}," requests",[747,63896,63897],{"class":802}," Credentials",[747,63899,63900],{"class":1640}," -",[747,63902,2035],{"class":757},[747,63904,63905],{"class":802}," Vault",[747,63907,63900],{"class":1640},[747,63909,2035],{"class":757},[747,63911,63912],{"class":802}," Create",[747,63914,63897],{"class":802},[747,63916,4584],{"class":802},[747,63918,63919],{"class":802}," Database\n",[747,63921,63922,63924,63926,63928,63930,63932,63934,63937,63939,63941,63943],{"class":749,"line":761},[747,63923,12433],{"class":1630},[747,63925,7552],{"class":757},[747,63927,3361],{"class":802},[747,63929,63905],{"class":802},[747,63931,7552],{"class":757},[747,63933,3361],{"class":802},[747,63935,63936],{"class":802}," Return",[747,63938,3927],{"class":802},[747,63940,63897],{"class":802},[747,63942,3696],{"class":802},[747,63944,63945],{"class":802}," Application\n",[523,63947,63948],{},"How Dynamic secrets should be handled in Vault:",[523,63950,63951],{},[3069,63952],{"alt":63953,"src":63954},"KubeCon: Talk Vault Management Kubernetes Dynamic secrets","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_145649.jpg",[523,63956,63957,63958,63961],{},"To be able to dynamically create credentials on demand, there are plugins available that are separate from the core.\nThese plugins are available for multiple applications like MySQL, SSH and more. This is kinda more of a community \"thing\" to create more and more plugins\u002Fintegrations for applications.\nHigh availability is achieved by a ",[567,63959,63960],{},"active\u003C->standby"," model. The standby instances proxy the requests to the active instance.",[523,63963,63964],{},"A bit about some of the features in Vault:\nEntities are a reprensentation of a signle person which is consistent across logins.\nAlias allow a mapping between an entity and an auth backend.\nIdentity Groups allow a \"team sharing\" like structure, example:",[668,63966,63967,63970],{},[638,63968,63969],{},"Development -> consists of Team ABC and Team XYZ",[638,63971,63972],{},"Ops -> consists of Team DEF and TEAM XYZ",[523,63974,63975,63976,1909],{},"Vault has a Kubernetes authentication backend for authentication with Service Accounts from Pods, see ",[527,63977,63978],{"href":63978,"rel":63979},"https:\u002F\u002Fwww.vaultproject.io\u002Fdocs\u002Fauth\u002FKubernetes.html",[531],[523,63981,63982],{},[3069,63983],{"alt":63984,"src":63985},"KubeCon: Talk Vault Management Kubernetes Auth Backend","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_151323.jpg",[613,63987,63989],{"id":63988},"lunch-time-tacos-by-redhat","Lunch time: Tacos by RedHat",[523,63991,63992,63993,11500],{},"This is my mandatory food shot.\nThanks for the Tacos to ",[527,63994,63997],{"href":63995,"rel":63996},"https:\u002F\u002Ftwitter.com\u002FRedHatNews",[531],"RedHat, Inc. - @RedHatNews",[523,63999,64000],{},[3069,64001],{"alt":64002,"src":64003},"KubeCon: Food Tacos from RedHat","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171207_131949.jpg",[535,64005,64007],{"id":64006},"day-3","Day #3",[613,64009,64011],{"id":64010},"keynotes-morning","Keynotes Morning",[523,64013,64014],{},[3069,64015],{"alt":64016,"src":64017},"KubeCon: Keynote Day #3 Shot #1","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_091014.jpg",[3126,64019,64021],{"id":64020},"opening-remarks-keynote-kubernetes-community-sarah-novotny-head-of-open-source-strategy-google-cloud-platform-google","Opening Remarks + Keynote: Kubernetes Community - Sarah Novotny, Head of Open Source Strategy, Google Cloud Platform, Google",[18903,64023],{"width":62833,"height":62834,"src":64024,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002F-5R_GbGg1nI",[523,64026,64027],{},"There was snow yesterday, which is pretty rare in Texas and especially in Austin.",[523,64029,64030],{},"KubeCon is a huge event, is it still the community I love?\nWho has the power? Who to ask? Steering Committee!",[523,64032,64033],{},"\"Culture eats strategy for breakfast.\" - Ptere Drucker\nFrom 400 two years ago to this year huge increase.",[6072,64035,64036],{},[523,64037,64038],{},"Distribution > Centralization",[523,64040,64041],{},[3069,64042],{"alt":64043,"src":64044},"KubeCon: Keynote Opening Remarks #1","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_091306.jpg",[6072,64046,64047],{},[523,64048,64049],{},"Inclusive > Exclusive\nIt's a core piece.",[523,64051,64052],{},[3069,64053],{"alt":64054,"src":64055},"KubeCon: Keynote Opening Remarks #2","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_091722.jpg",[6072,64057,64058],{},[523,64059,64060],{},"Community > Company\nA culture of contious learning.",[523,64062,64063],{},[3069,64064],{"alt":64065,"src":64066},"KubeCon: Keynote Opening Remarks #3","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_091906.jpg",[6072,64068,64069],{},[523,64070,64071],{},"Improvement > Stagnation",[523,64073,64074],{},[3069,64075],{"alt":64076,"src":64077},"KubeCon: Keynote Opening Remarks #4","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_092143.jpg",[523,64079,64080],{},[527,64081,64084],{"href":64082,"rel":64083},"https:\u002F\u002Fbit.ly\u002Fk8smentoring",[531],"bit.ly\u002Fk8smentoring",[6072,64086,64087],{},[523,64088,64089],{},"Automation > Process",[523,64091,64092],{},"There is a \"Manual labor tasks, chop wood, carry water\" award which has been given out at the first day before the party.",[523,64094,64095],{},[3069,64096],{"alt":64097,"src":64098},"KubeCon: Keynote Opening Remarks #5","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_092405.jpg",[523,64100,64101],{},"Love Kubernetes, shape the industry.",[523,64103,64104],{},[3069,64105],{"alt":64106,"src":64107},"KubeCon: Keynote Love Kubernetes, shape the industry","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_092442.jpg",[3126,64109,64111],{"id":64110},"kubernetes-at-github-jesse-newland-principal-site-reliability-engineer-github","Kubernetes at GitHub - Jesse Newland, Principal Site Reliability Engineer, GitHub",[523,64113,64114],{},[3069,64115],{"alt":64116,"src":64117},"KubeCon: Keynote Day #3 Shot #2","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_092701.jpg",[18903,64119],{"width":62833,"height":62834,"src":64120,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FOgRHIZt8Yy8",[523,64122,64123],{},"GitHub and GitHub API production are running on Kubernetes.\nAt the time (4 years ago) it seemed \"impossible\" to run applications in containers. Keep in mind that projects like Kubernetes didn't exist back then.\nSeniors at GitHub said wait for it:",[6072,64125,64126],{},[523,64127,64128],{},"\"We're not the right spot to do the execution\"",[523,64130,64131],{},"They were really not in the right place and time to do that.",[523,64133,64134],{},[3069,64135],{"alt":64136,"src":64137},"KubeCon: Keynote GitHub Love Kubernetes","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_092944.jpg",[523,64139,64140,64141,59081,64146,64151],{},"They already have about 20% of their services running in Kubernetes.\n",[527,64142,64145],{"href":64143,"rel":64144},"https:\u002F\u002Fgithub.com",[531],"GitHub.com",[527,64147,64150],{"href":64148,"rel":64149},"https:\u002F\u002Fapi.github.com\u002F",[531],"GitHub API"," are already powered by Kubernetes (at least the stateless part of it).",[523,64153,64154],{},[3069,64155],{"alt":64156,"src":64157},"KubeCon: Keynote GitHub over 20% services on Kubernetes","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_093054.jpg",[523,64159,64160],{},"There was no real experience operating Kubernetes clusters.\nMultiple clusters in different sites are used. Their existing deployment tools are used to deploy to their multiple sites.\nAn interesting aspect from the hardware side is that they use small \"blade\" like servers, see next image.",[523,64162,64163],{},[3069,64164],{"alt":64165,"src":64166},"KubeCon: Keynote GitHub blade servers","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_093237.jpg",[523,64168,64169],{},"And their current clusters look like this:",[523,64171,64172],{},[3069,64173],{"alt":64174,"src":64175},"KubeCon: Keynote GitHub Cluster configuration","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_093208.jpg",[523,64177,64178],{},"ChatOps is used to deploy by chat. Hubot is used for the chat commands. They are also using Puppet for deploying to Kubernetes.\nThat they use Puppet is pretty interesting as most people seem to try to get away from Puppet when switching to a platform like Kubernetes.\nThey use a construct of Consul + templating to \"route\" the traffic to the correct destination.",[523,64180,64181],{},[3069,64182],{"alt":64183,"src":64184},"KubeCon: Keynote GitHub consul service router","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_093447.jpg",[523,64186,64187,64188,64190],{},"They hope to replace their self built construct with the Enovy proxy project soon.\nGLB (GitHub LoadBalancer) is used for load balancing and to expose the services to the load balancer ",[567,64189,15315],{}," is used.",[523,64192,64193],{},"Awesome tools have been created:",[523,64195,64196],{},[3069,64197],{"alt":64198,"src":64199},"KubeCon: Keynote GitHub Awesome tool","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_093550.jpg",[523,64201,64202],{},"Workflow Conventions have been set. This allows everyone to be on the same page for development and deployment which in return allows for increased development effiency and faster deployments.",[523,64204,64205],{},[3069,64206],{"alt":64207,"src":64208},"KubeCon: Keynote GitHub Lab Branch Workflow","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_093906.jpg",[523,64210,64211],{},[3069,64212],{"alt":64213,"src":64214},"KubeCon: Keynote GitHub Lab workflow","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_094004.jpg",[523,64216,64217,64218,64220],{},"When a commit is pushed to a pull request a so called  \"lab\" URL is returned. This \"lab\" URL has a build running with given changes. Every \"lab\" application has it's own ",[567,64219,22320],{}," which is deleted after 24 hours.\nCanary deployments with their routing construct allow them to give small a percentage of traffic a new feature so it can be tested before it is released.\nAll GitHub services are now using canary deployments.",[523,64222,64223],{},[3069,64224],{"alt":64225,"src":64226},"KubeCon: Keynote GitHub Canary deploy","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_094203.jpg",[523,64228,64229],{},"The plan for GitHub with Kubernetes is to move more and more workload to Kubernetes. They have also plans to get persistent volumes in Kubernetes for their engineers.",[523,64231,64232],{},[3069,64233],{"alt":64234,"src":64235},"KubeCon: Keynote GitHub Kubernetes made it easier for SREs","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_094323.jpg",[523,64237,64238],{},[3069,64239],{"alt":64240,"src":64241},"KubeCon: Keynote GitHub Decomposition of monolith services","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_094338.jpg",[523,64243,64244],{},"Currently most of their used projects aren't Open Source yet, but they will begin to change that soon.\n\"It is the least we could do for the community\"\nThis is a good view on returning to the community and overall open source as a company.",[3126,64246,64248],{"id":64247},"manage-the-app-on-kubernetes-brandon-philips-cto-coreos","Manage the App on Kubernetes - Brandon Philips, CTO, CoreOS",[18903,64250],{"width":62833,"height":62834,"src":64251,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002Ful624nYC8pw",[523,64253,64254],{},"The goal is to make applications easier to build, deploy, update and \"everything\".\nThere is a demand for running more and more applications on Kubernetes, but with moving more applications into Kubernetes you are also more and more accountable for them.",[523,64256,64257],{},[3069,64258],{"alt":64259,"src":64260},"KubeCon: Keynote CoreOS Pre-Kubernetes State for Applications","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_094851.jpg",[6072,64262,64263],{},[523,64264,64265],{},"Who is the owner? Where are the dashboards? Metrics and SLAs? Docs?",[523,64267,64268],{},"An eco system should have a catalog of the applications running, with all information (owner, SLAs, etc) in it.",[523,64270,64271],{},[3069,64272],{"alt":64273,"src":64274},"KubeCon: Keynote CoreOS Future Kubernetes State for Applications","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_095007.jpg",[523,64276,64277],{},"These informations should be moved into metadata of the application (in Kubernetes too).\nThis is partly a vision right now. It is all managed through objects in Kubernetes, which have the advantage that everyone with correct access to Kubernetes can read them.\nThey showed off the Tectonic console which already can manage applications through operators like ETCD, Vault and Prometheus.",[3126,64279,64281],{"id":64280},"whats-next-getting-excited-about-kubernetes-in-2018-clayton-coleman-architect-kubernetes-and-openshift-red-hat","What's Next? Getting Excited about Kubernetes in 2018 - Clayton Coleman, Architect, Kubernetes and OpenShift, Red Hat",[18903,64283],{"width":62833,"height":62834,"src":64284,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FlUnD9SJDgo8",[523,64286,64287],{},"How can we make Kubernetes exciting (again)?\nWe, the people, should help make \"everything\" better (contributing, discussing proposals and issues and engaging in a Special Interest Group).",[523,64289,64290],{},[3069,64291],{"alt":64292,"src":64293},"KubeCon: Keynote Suprise we already are!","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_095556.jpg",[523,64295,64296],{},"But.. if you haven't been engaged, you should go out of your comfort zone and work with people for projects you haven't worked with yet.",[635,64298,64299,64357],{},[638,64300,64301,64302],{},"Build faster, smarter, better: Set it Open Source, like Ruby on Rails, they have set the tone for creating and sharing (Gems) code. Sharing now enables everyone to build a service mesh.\n",[668,64303,64304,64320,64339],{},[638,64305,64306,64307,714,64310,714,64314,64319],{},"2018 Year of the Service Mesh: ",[527,64308,63641],{"href":27818,"rel":64309},[531],[527,64311,57734],{"href":64312,"rel":64313},"https:\u002F\u002Fwww.envoyproxy.io\u002F",[531],[527,64315,64318],{"href":64316,"rel":64317},"https:\u002F\u002Fconduit.io\u002F",[531],"Conduit"," will help solve this problem\u002Fuse case. Machine learning is\u002Fwill be more and more important.",[638,64321,64322,64323,714,64328,714,64333,64338],{},"Serverless? ",[527,64324,64327],{"href":64325,"rel":64326},"http:\u002F\u002Ffission.io\u002F",[531],"fission",[527,64329,64332],{"href":64330,"rel":64331},"http:\u002F\u002Fkubeless.io\u002F",[531],"Kubeless",[527,64334,64337],{"href":64335,"rel":64336},"https:\u002F\u002Fopenwhisk.apache.org\u002F",[531],"Apache OpenWhisk"," are some examples for projects that implement serverless.",[638,64340,64341,64342,714,64347,714,64351,64356],{},"Defining Apps: Applications are getting more complex over the years. ",[527,64343,64346],{"href":64344,"rel":64345},"https:\u002F\u002Fhelm.sh\u002F",[531],"Helm",[527,64348,28076],{"href":64349,"rel":64350},"http:\u002F\u002Fkompose.io\u002F",[531],[527,64352,64355],{"href":64353,"rel":64354},"http:\u002F\u002Fkedgeproject.org\u002F",[531],"kedge"," and other applications try helping with making it simpler for complex applications to \"exist\".",[638,64358,64359,64360],{},"Security and Authentication\n",[668,64361,64362,64376,64388,64413],{},[638,64363,64364,714,64368,64371,64372,64375],{},[527,64365,64367],{"href":57703,"rel":64366},[531],"Spiffe",[527,64369,27820],{"href":27818,"rel":64370},[531]," and Kerberos for securing workload identity. The working group ",[567,64373,64374],{},"container-identity-wg"," is working on improving that.",[638,64377,64378,64379,64384,64385,1909],{},"Multi-tenancy, Policy through ",[527,64380,64383],{"href":64381,"rel":64382},"https:\u002F\u002Fgithub.com\u002Fopen-policy-agent",[531],"open policy agent (OPA)",", LDAP, ",[567,64386,64387],{},"\u003CINSERT POLICY HERE>",[638,64389,64390,64391,714,64394,714,64398,714,64402,714,64407,64412],{},"Better containers (and virtual machines!): ",[527,64392,401],{"href":63119,"rel":64393},[531],[527,64395,26898],{"href":64396,"rel":64397},"https:\u002F\u002Fcontainerd.io\u002F",[531],[527,64399,64401],{"href":52508,"rel":64400},[531],"OCI",[527,64403,64406],{"href":64404,"rel":64405},"https:\u002F\u002Fgithub.com\u002Fkubevirt",[531],"kubevirt",[527,64408,64411],{"href":64409,"rel":64410},"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Fvirtualization\u002Fhyper-v-on-windows\u002Fabout\u002F",[531],"Hyper-V",", debug containers (for debugging in production as an example).",[638,64414,64415,64420],{},[527,64416,64419],{"href":64417,"rel":64418},"https:\u002F\u002Fgithub.com\u002Fappscode\u002Fkubed",[531],"GitHub appscode\u002Fkubed",", github.com\u002Fheptio\u002Fark github.com\u002Fcloudnativelabs\u002Fkube-router, github.com\u002FGoogleCloudPlatform\u002Fkube-metacontroller",[523,64422,64423],{},"How do you participate? Build something. Use anything. Help anyone. Talk to people. Create something new!",[6072,64425,64426],{},[523,64427,64428,64431],{},[584,64429,64430],{},"Hint",": But don't reinvent everything.",[3126,64433,64435],{"id":64434},"what-is-kubernetes-brian-grant-principal-engineer-google","What is Kubernetes? - Brian Grant, Principal Engineer, Google",[18903,64437],{"width":62833,"height":62834,"src":64438,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FcHkXOeP8rQ0",[523,64440,64441,64442,64447],{},"Kubernetes was launched at ",[527,64443,64446],{"href":64444,"rel":64445},"https:\u002F\u002Fconferences.oreilly.com\u002Foscon\u002Foscon-or",[531],"OSCON",". Kubernetes was the most fun for him. I can confirm this!",[523,64449,64450],{},[3069,64451],{"alt":64452,"src":64453},"KubeCon: Keynote Is Kubernetes a...","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_101821.jpg",[523,64455,64456],{},"Pretty good look at more of the Kubernetes technical side.",[523,64458,64459],{},[3069,64460],{"alt":64461,"src":64462},"KubeCon: Keynote Google CaaS","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_102515.jpg",[523,64464,64465],{},[3069,64466],{"alt":64467,"src":64468},"KubeCon: Keynote Google Controllers","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_102516.jpg",[523,64470,64471],{},[3069,64472],{"alt":64473,"src":64474},"KubeCon: Keynote Google SaaS","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_102728.jpg",[523,64476,64477,64478,64480],{},"Nice! Again Rook was named as an example for extending the Kubernetes API (through ",[567,64479,51062],{},"s).",[523,64482,64483],{},[3069,64484],{"alt":64485,"src":64486},"KubeCon: Keynote Google Kubernetes Extension Examples","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_103147.jpg",[523,64488,64489],{},"\"As long as it implements the API, it is\u002Fshould compatible\"",[523,64491,64492,64493,64495],{},"Kubernetes can be used for automating management, Service Catalog APIs.\nKubernetes is kind of a portable cloud abstraction.\nKubernetes shouldn't do everything you want! You can build your own tools to do that on Kubernetes, like with ",[567,64494,51062],{},"s. SDKs are under development to make creating APIs even simpler and easier.",[523,64497,64498],{},"Conclusion is that Kubernetes is awesome!",[523,64500,64501],{},[3069,64502],{"alt":64503,"src":64504},"KubeCon: Keynote Google Conclusion of Talk","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_103151.jpg",[613,64506,51330],{"id":64507},"talks-2",[3126,64509,64511,64512,64514],{"id":64510},"disaster-recovery-for-your-kubernetes-clusters-i-andy-goldstein-steve-kriss-heptio","Disaster Recovery for your Kubernetes Clusters ",[747,64513,27787],{}," - Andy Goldstein & Steve Kriss, Heptio",[18903,64516],{"width":62833,"height":62834,"src":64517,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FqRPNuT080Hk",[523,64519,64520,64521,64523],{},"A big problem in Kubernetes about disaster recovery is stateful data. Stateful data already begins with the etcd data for Kubernetes and goes down to the ",[567,64522,51091],{}," used inside Kubernetes.\nFor etcd you can do backups on block, file, etcdctl or Kubernetes API discovery level.",[523,64525,64526],{},"For Persistent Volumes there is currently nothing really for backing them up, except for cloud providers as they most of the time have a volume snapshot API. But there is on going work for a snapshot\u002Fbackup API in Kubernetes in some way.\nFrom my perspective it is likely that this will be added to the Container Storage Interface in some way.",[523,64528,64529,64533,64534,64536,64537,64539,64540,64545],{},[527,64530,64532],{"href":63697,"rel":64531},[531],"Heptio Ark"," allows to do restore of API objects and ",[567,64535,51091],{}," in Kubernetes. Additionally it is able to backup and restore ",[567,64538,51091],{},", currently \"only\" cloud providers such as AWS and GCE. There is on going discussion how to implement backups for example with ",[527,64541,64544],{"href":64542,"rel":64543},"https:\u002F\u002Fgithub.com\u002Fappscode\u002Fstash",[531],"appscode Stash"," through Ark.\nWhen using the Kubernetes API Discovery it discovers all APIs available in the Kubernetes API server asked.\nAn overview of Heptio Ark features are:",[523,64547,64548],{},[3069,64549],{"alt":64550,"src":64551},"KubeCon: Talk Heptio Ark DR Features","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_141307.jpg",[523,64553,64554],{},[3069,64555],{"alt":64550,"src":64556},"\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_141544.jpg",[523,64558,64559],{},"The features can be extended through hooks (example a script should be run before a backup is taken) and plugins.\nThere are different types of plugins, which allow different ways to extend Ark with more functionality.",[523,64561,64562,64563,64565,64566,64568,64569,64571,64572,64574,64575,64577,64578,1909],{},"In the demo they used Rook block storage and showed how to backup and restore a ",[567,64564,18374],{},".\nIt is as simple as running a command to create a scheduled backup. When for example deleting a namespace with a ",[567,64567,27758],{},", it allows to fully recover the Kubernetes objects (new UIDs though) of the ",[567,64570,18374],{}," and the content ",[567,64573,18374],{}," itself too.\nAs noted earlier the support for the content of a ",[567,64576,18374],{}," is mostly for cloud providers, but there is work done already for that in ",[527,64579,64582],{"href":64580,"rel":64581},"https:\u002F\u002Fgithub.com\u002Fheptio\u002Fark\u002Fissues\u002F19",[531],"heptio\u002Fark Issue 19 - Back up non-cloud persistent volumes",[523,64584,64585,64586,1909],{},"A great point about Ark, is that it is open source. To communicate with the Ark (\u002FHeptio) team fast, they have a channel in the Kubernetes Slack ",[567,64587,64588],{},"#ark-dr",[3126,64590,64592],{"id":64591},"one-chart-to-rule-them-all-continuous-deployment-with-helm-at-ticketmaster-michael-goodness-raphael-deem-ticketmaster","One Chart to Rule Them All: Continuous Deployment with Helm at Ticketmaster - Michael Goodness & Raphael Deem, Ticketmaster",[18903,64594],{"width":62833,"height":62834,"src":64595,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FHzJ9ycX1h0c",[523,64597,64598],{},"No \"Lord of the Rings\" memes, even when the title suggests it.\nThere is no native way to bundle every \"dependent\" resource together, to make creating\u002Fupdating\u002Fdeleting simpler for application deployments.\nHelm is like a package manager for applications on Kubernetes.\nWhen you have a lot of clusters and multiple stages a tool like Helm makes it easier for teams to package their applications (for each stage).\nThey also use a tool to create namespaces, which adds some metadata to it, RBAC, resource quotas and network policies automatically.",[523,64600,64601],{},[3069,64602],{"alt":64603,"src":64604},"KubeCon: Talk One Chart - Versions","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_145519.jpg",[523,64606,64607,64608,64611,64612,64614,64615,1909],{},"I personally prefer a mix of both ways, as some teams just want to have stuff like they want it to and that is just how it is right now that some teams like it their own way. Taking that \"freedom\" away wouldn't be that good for existing teams that work like that (where no standard is set in the company).\nLooking at Springboot applications ",[567,64609,64610],{},"v2"," looks like the better approach for it, but it also depends on what kind of (Springboot) application you want to deploy.\nIn ",[567,64613,64610],{}," having a lot of knobs and dials, can be considered good depending on how experienced the team(s) are with those features controlled by the dials and knobs.\nKnobs for stuff like tracing, logging and other sidecar\u002Ffeatures is nice to have in the templates.\nBut covering everything is never possible so only the most important functions should be \"exposed\" as values in the ",[567,64616,64617],{},"values.yaml",[523,64619,64620],{},[3069,64621],{"alt":64622,"src":64623},"KubeCon: Talk One Chart - Chart Shot #1","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_150657.jpg",[523,64625,64626],{},[3069,64627],{"alt":64628,"src":64629},"KubeCon: Talk One Chart - Chart Shot #2","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_150924.jpg",[523,64631,64632],{},[3069,64633],{"alt":64634,"src":64635},"KubeCon: Talk One Chart - Chart Shot #3","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_151204.jpg",[523,64637,64638,64639,1909],{},"They have a pretty awesome (and complex) looking Helm Chart \"Template\" for their so called \"Webservice\" (chart).\nIt has many features to simply be toggled through the ",[567,64640,64617],{},[3126,64642,64644,64645,64647],{"id":64643},"economics-of-using-local-storage-attached-to-vms-on-cloud-providers-i-pavel-snagovsky-quantum","Economics of using Local Storage Attached to VMs on Cloud Providers ",[747,64646,27787],{}," - Pavel Snagovsky, Quantum",[523,64649,64650],{},[3069,64651],{"alt":64652,"src":64653},"KubeCon: Talk Local Storage Shot #1","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_154415.jpg",[18903,64655],{"width":62833,"height":62834,"src":64656,"frameBorder":3579,"allow":52347,"allowFullScreen":1254},"https:\u002F\u002Fwww.youtube-nocookie.com\u002Fembed\u002FePLUqOnbdp4",[523,64658,64659],{},"Locally attached storage is most of the time faster and mostly inexpensive (depending on your (cloud) provider).",[523,64661,64662],{},[3069,64663],{"alt":64664,"src":64665},"KubeCon: Talk Local Storage Pros & Cons","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_154418.jpg",[523,64667,64668],{},"Using an application like Rook to utilize that storage would be a good possibility to use that fast storage overall for the Kubernetes, in the cluster.",[523,64670,64671],{},[3069,64672],{"alt":64673,"src":64674},"KubeCon: Talk Local Storage Harnessing the benefits with Rook","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_154655.jpg",[523,64676,64677,64678,64683],{},"Rook solves the problem of local storage going to waste (by not being used) and instead utilizes it as written earlier to be used in Kubernetes for Kubernetes.\nThe performance is in some cases better with Rook instead of using a cloud provider of choice block storage.\nFor AWS a performance comparison can be found in this ",[527,64679,64682],{"href":64680,"rel":64681},"https:\u002F\u002Fblog.rook.io\u002Frun-your-own-high-performance-ebs-wherever-kubernetes-runs-798a136bd808",[531],"Rook blog post"," and the charts can be seen in the next photo:",[523,64685,64686],{},[3069,64687],{"alt":64688,"src":64689},"KubeCon: Talk Local Storage AWS performance comparison","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_155453.jpg",[523,64691,64692,64693,6374,64697,3052],{},"Another advantage when taking a look at using Kubernetes in multiple cloud environments, is that Rook is compatible with Kubernetes and has only a small amount of requiremenets for it to run, making it easier to migrate\u002Fmove data between clouds (an example for migrating data would be ",[527,64694,64696],{"href":63697,"rel":64695},[531],"heptio\u002Fark",[527,64698,64700],{"href":64542,"rel":64699},[531],"appscode\u002Fstash",[523,64702,64703],{},[3069,64704],{"alt":64705,"src":64706},"KubeCon: Talk Local Storage Rook Compatibility","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_155917.jpg",[523,64708,64709],{},[3069,64710],{"alt":64711,"src":64712},"KubeCon: Talk Local Storage AWS Local Storage costs","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_160138.jpg",[523,64714,64715],{},[3069,64716],{"alt":64717,"src":64718},"KubeCon: Talk Local Storage Costs Summary","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_160256.jpg",[523,64720,64721],{},"Use cases for Rook are:",[668,64723,64724,64727,64730,64736],{},[638,64725,64726],{},"Use the Rook object store instead of the cloud provider ones (overall running services yourself, may lower the cost for you if the administration knowledge is existing).",[638,64728,64729],{},"Multiple clusters for different performance and isolation requirements are possible.",[638,64731,64732,64733,64735],{},"Kubernetes integration allows a simple switch to Rook as it \"exposes\" storage through Kubernetes native ",[567,64734,32356],{},"es.",[638,64737,11745],{},[523,64739,64740],{},[3069,64741],{"alt":64742,"src":64743},"KubeCon: Talk Local Storage Conclusion","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fimg_20171208_160632.jpg",[523,64745,64746],{},"Rook is awesome! But keep in mind that, as always, it is dependent on if it really fits your specific use case.\nDepending on what your use case is in the cloud or on bare metal, you could save money for certain use cases.",[613,64748,64750],{"id":64749},"find-a-job-post-a-job-get-involved-wall","\"Find A Job | Post A Job | Get Involved\" Wall",[523,64752,64753],{},[3069,64754],{"alt":64755,"src":64756},"KubeCon: Sponsor Showcase Find A Job | Post A Job | Get Involved Wall","\u002Fblog\u002F2017\u002Fkubecon-2017-austin\u002Fpano_20171208_165212.jpg",[523,64758,64759],{},"If you need more pixels, I can help you as I still have the photo in original resolution available, please send me an email about it. Thanks!",[535,64761,14526],{"id":14525},[523,64763,64764],{},"My first travel to the USA, my first KubeCon, it was awesome!\nI have met a lot of awesome people and it was especially nice to see the Rook team and community.\nI hope to see a lot of those awesome people at the next KubeCon in Copenhagen.",[523,64766,13967],{},[523,64768,64769,53030],{},[584,64770,53029],{},[2890,64772,64773],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":743,"searchDepth":761,"depth":761,"links":64775},[64776,64777,64778,64779,64787,64792,64797],{"id":13456,"depth":761,"text":13457},{"id":52389,"depth":761,"text":52390},{"id":62723,"depth":761,"text":62724},{"id":52418,"depth":761,"text":52419,"children":64780},[64781,64782,64783,64784,64785,64786],{"id":62751,"depth":769,"text":62752},{"id":56456,"depth":769,"text":56457},{"id":51329,"depth":769,"text":51330},{"id":58150,"depth":769,"text":58151},{"id":63292,"depth":769,"text":63293},{"id":63302,"depth":769,"text":63303},{"id":52787,"depth":761,"text":52788,"children":64788},[64789,64790,64791],{"id":63333,"depth":769,"text":56457},{"id":63710,"depth":769,"text":51330},{"id":63988,"depth":769,"text":63989},{"id":64006,"depth":761,"text":64007,"children":64793},[64794,64795,64796],{"id":64010,"depth":769,"text":64011},{"id":64507,"depth":769,"text":51330},{"id":64749,"depth":769,"text":64750},{"id":14525,"depth":761,"text":14526},"2017-12-05T12:09:28-05:00","Talks, keynotes, thoughts and pictures from the KubeCon Texas, Austin 2017. Be aware that this post contains many photos! Check you wifi before opening.",{"src":62826},{"tags":64802},[13976,52359,26415,12175,124],"\u002Fblog\u002F2017\u002Fkubecon-2017-austin",{"title":62649,"description":64799},"3.blog\u002F2017\u002Fkubecon-2017-austin","6C0cOWAJnT0Db1u82fcnF7LGPpp1ZtSFeQOe1ETItpw",{"id":64808,"title":64809,"authors":64810,"badge":518,"body":64813,"date":64827,"description":64828,"extension":2911,"image":64829,"meta":64831,"navigation":1254,"path":64835,"seo":64836,"stem":64837,"__hash__":64838},"posts\u002F3.blog\u002F2017\u002Fwriting-your-first-golang-microthingy-presentation.md","Writing your first Golang Microthingy Presentation",[64811],{"name":514,"to":515,"avatar":64812},{"src":517},{"type":520,"value":64814,"toc":64825},[64815,64818,64820,64823],[523,64816,64817],{},"I created this presentation to talk a bit about Microservices and Goland. In addition for the presentation, there is a repository containing Golang example code for a very basic Microservice example application.",[523,64819,58352],{},[18903,64821],{"src":64822,"frameBorder":3579,"height":18906,"allowFullScreen":5306,"mozallowfullscreen":5306,"webkitallowfullscreen":5306},"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002Fe\u002F2PACX-1vSiW9gsn83Cw1MMbyvtyd8YLrZF31jZx5J8qIHq-9vsz-o_bwcjB8OUjAAwT6R-Zcdjbuch5Lx4_fc3\u002Fembed?start=false&loop=true&delayms=5000",[523,64824,52336],{},{"title":743,"searchDepth":761,"depth":761,"links":64826},[],"2017-11-05T12:15:46+02:00","A presentation about writing a Microservice in Golang. Talks about the basics, why Microservices? Why Golang?",{"src":64830},"\u002Fblog\u002Fcovers\u002Fgo-logo_lightblue.png",{"tags":64832},[18918,64833,64834],"Golang","Microservices","\u002Fblog\u002F2017\u002Fwriting-your-first-golang-microthingy-presentation",{"title":64809,"description":64828},"3.blog\u002F2017\u002Fwriting-your-first-golang-microthingy-presentation","b_Rm0UJdgZtEU7Ym6eahmSwIdqJH_RretjiHBrs2KsU",{"id":64840,"title":64841,"authors":64842,"badge":518,"body":64845,"date":66673,"description":66674,"extension":2911,"image":66675,"meta":66677,"navigation":1254,"path":66679,"seo":66680,"stem":66681,"__hash__":66682},"posts\u002F3.blog\u002F2017\u002Fgitlab-kubernetes-gitlab-on-top-of-kubernetes.md","GitLab + Kubernetes: GitLab on top of Kubernetes",[64843],{"name":514,"to":515,"avatar":64844},{"src":517},{"type":520,"value":64846,"toc":66654},[64847,64849,64855,64858,64874,64881,64890,64893,64907,64924,64926,64964,64973,64977,64986,64990,64993,65086,65094,65098,65104,65106,65119,65640,65642,65655,65681,65691,65698,65737,65740,65864,65867,65881,65888,66303,66305,66308,66437,66440,66451,66569,66573,66579,66594,66604,66608,66611,66622,66625,66641,66643,66649,66651],[535,64848,538],{"id":537},[523,64850,64851,64852,1909],{},"This is the third post in the three post series about Kubernetes and GitLab. The first post can be found here: ",[527,64853,64854],{"href":22254},"Edenmal - GitLab + Kubernetes: Perfect Match for Continuous Delivery with Container",[523,64856,64857],{},"This post will not cover how to setup a Postgres and Redis server\u002Fcluster for the GitLab.\nIn the near future I may even publish all my current manifests, that also contain Postgres and Redis server\u002Fcluster manifests.",[523,64859,64860,64861,64868,64869,64873],{},"If you don't have a Postgres and Redis, I would recommend you to check out the Kubernetes manifests at ",[527,64862,64865],{"href":64863,"rel":64864},"https:\u002F\u002Fgithub.com\u002Fsameersbn\u002Fdocker-gitlab",[531],[567,64866,64867],{},"sameersbn\u002Fdocker-gitlab"," repo, here: ",[527,64870,64871],{"href":64871,"rel":64872},"https:\u002F\u002Fgithub.com\u002Fsameersbn\u002Fdocker-gitlab\u002Ftree\u002Fmaster\u002Fkubernetes",[531]," They contain a manifest for Postgres and Redis server.",[613,64875,64877,64878,64880],{"id":64876},"decision-to-use-sameersbn-gitlab-image-instead-of-the-official","Decision to use ",[567,64879,5734],{}," GitLab image instead of the official",[523,64882,64883,64884,64889],{},"The manifests below are using ",[527,64885,64887],{"href":64863,"rel":64886},[531],[567,64888,64867],{}," image. You may ask \"Why not use the official GitLab image?\".\nA good question, the answer to that lies in the concept of configuration of GitLab inside the container.\nI personally prefer an image that doesn't need a persistent volume for the configuration.\nOnly time I want to use a persistent volume, is when I have data from an application that needs to persistence.\nLast time I looked a the official GitLab Docker image I was required to have a persistent volume for the configuration.",[523,64891,64892],{},"That is not how I imagine an application in a container to be configured. I prefer:",[668,64894,64895,64898,64904],{},[638,64896,64897],{},"Configuration through environment variables",[638,64899,64900,64903],{},[584,64901,64902],{},"ONE"," \"small\" configuration (fitting into a Kubernetes ConfigMap)",[638,64905,64906],{},"Configuration by flag",[523,64908,64909,64910,64915,64916,64923],{},"Having to \"move\" around a persistent volume which contains the config is a bad thing from my point of view.\nThat is the reason behind why I am using ",[527,64911,64913],{"href":64863,"rel":64912},[531],[567,64914,64867],{}," image instead of the official ",[527,64917,64920],{"href":64918,"rel":64919},"https:\u002F\u002Fhub.docker.com\u002Fr\u002Fgitlab\u002Fgitlab-ce\u002F",[531],[567,64921,64922],{},"gitlab\u002Fgitlab-ce"," image.\nAdditionally there are some other smaller points, for example what runs in the container is more than should. At best one process per container.",[613,64925,22268],{"id":22267},[668,64927,64928,64931,64937,64950,64953,64958,64961],{},[638,64929,64930],{},"Kubernetes cluster with Ingress support",[638,64932,64933,64934,2006],{},"Kubernetes Ingress Controller (example: ",[527,64935,64936],{"href":743},"nginx-ingress controller",[638,64938,64939,64940],{},"StorageClass configured in Kubernetes\n",[668,64941,64942],{},[638,64943,64944,64946,64947,2006],{},[567,64945,32376],{}," Persistent Storage (example CephFS using ",[527,64948,465],{"href":32338,"rel":64949},[531],[638,64951,64952],{},"Domain\u002FSubdomain ready to be used for the GitLab",[638,64954,64955,64957],{},[567,64956,15269],{}," binary (with Kubernetes cluster access)",[638,64959,64960],{},"Postgres server for GitLab",[638,64962,64963],{},"Redis server\u002Fcluster for GitLab",[6072,64965,64966,64970],{},[523,64967,64968],{},[584,64969,6189],{},[523,64971,64972],{},"Postgres and Redis need to be reachable from inside the Kubernetes cluster.",[613,64974,64976],{"id":64975},"manifests","Manifests",[523,64978,64979,64980,64985],{},"The manifests shown in this blog post will also be available on GitHub here: ",[527,64981,64984],{"href":64982,"rel":64983},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fkubernetes-manifests",[531],"GitHub - galexrt\u002Fkubernetes-manifests",".\nIf you want the latest manifests version, I recommend you checkout the repository (though I try to keep the blog post and repository in the same state\u002Fversion).",[535,64987,64989],{"id":64988},"step-1-verify-kubernetes-cluster-connectivity","Step 1 - Verify Kubernetes cluster \"connectivity\"",[523,64991,64992],{},"To check if you have proper Kubernetes cluster connection, run the following command:",[738,64994,64996],{"className":1621,"code":64995,"language":1623,"meta":743,"style":743},"$ kubectl cluster-info\nkubectl cluster-info\nKubernetes master is running at https:\u002F\u002Fk8s.example.com:443\nKubeDNS is running at https:\u002F\u002Fk8s.example.com:443\u002Fapi\u002Fv1\u002Fnamespaces\u002Fkube-system\u002Fservices\u002Fkube-dns\u002Fproxy\n[...]\nTo further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.\n$\n",[567,64997,64998,65007,65013,65028,65042,65050,65081],{"__ignoreMap":743},[747,64999,65000,65002,65004],{"class":749,"line":750},[747,65001,1919],{"class":1630},[747,65003,1922],{"class":802},[747,65005,65006],{"class":802}," cluster-info\n",[747,65008,65009,65011],{"class":749,"line":761},[747,65010,15269],{"class":1630},[747,65012,65006],{"class":802},[747,65014,65015,65017,65019,65021,65023,65025],{"class":749,"line":769},[747,65016,124],{"class":1630},[747,65018,7834],{"class":802},[747,65020,5068],{"class":802},[747,65022,36742],{"class":802},[747,65024,35623],{"class":802},[747,65026,65027],{"class":802}," https:\u002F\u002Fk8s.example.com:443\n",[747,65029,65030,65033,65035,65037,65039],{"class":749,"line":776},[747,65031,65032],{"class":1630},"KubeDNS",[747,65034,5068],{"class":802},[747,65036,36742],{"class":802},[747,65038,35623],{"class":802},[747,65040,65041],{"class":802}," https:\u002F\u002Fk8s.example.com:443\u002Fapi\u002Fv1\u002Fnamespaces\u002Fkube-system\u002Fservices\u002Fkube-dns\u002Fproxy\n",[747,65043,65044,65046,65048],{"class":749,"line":784},[747,65045,4253],{"class":757},[747,65047,5685],{"class":1640},[747,65049,4268],{"class":757},[747,65051,65052,65054,65057,65060,65062,65065,65067,65070,65072,65074,65077,65079],{"class":749,"line":790},[747,65053,3821],{"class":1630},[747,65055,65056],{"class":802}," further",[747,65058,65059],{"class":802}," debug",[747,65061,4099],{"class":802},[747,65063,65064],{"class":802}," diagnose",[747,65066,53621],{"class":802},[747,65068,65069],{"class":802}," problems,",[747,65071,4556],{"class":802},[747,65073,3537],{"class":757},[747,65075,65076],{"class":802},"kubectl cluster-info dump",[747,65078,3543],{"class":757},[747,65080,9661],{"class":802},[747,65082,65083],{"class":749,"line":796},[747,65084,65085],{"class":1630},"$\n",[523,65087,8764,65088,65090,65091,65093],{},[567,65089,15269],{}," command ",[567,65092,36474],{}," shows you if you can connect to the cluster\nand list the available cluster services (in the ouput: Kubernetes apiserver and KubeDNS service).",[535,65095,65097],{"id":65096},"step-2-write-kubernetes-manifests-for-gitlab","Step 2 - Write Kubernetes manifests for GitLab",[523,65099,18798,65100,65103],{},[527,65101,538],{"href":65102},"#Intro",", the manifests will cover only the GitLab.",[613,65105,30063],{"id":30793},[523,65107,65108,65109,65114,65115,5940],{},"The list of all available environment variables for the configuration, can be found here: ",[527,65110,65113],{"href":65111,"rel":65112},"https:\u002F\u002Fgithub.com\u002Fsameersbn\u002Fdocker-gitlab#available-configuration-parameters",[531],"sameersbn\u002Fdocker-gitlab - Available Configuration Parameters",".\nIf you have a variable that would contain a password or token, put it in the ",[527,65116,65118],{"href":65117},"#Secret","Secret manifest",[738,65120,65122],{"className":740,"code":65121,"language":742,"meta":743,"style":743},"apiVersion: v1\ndata:\n  # Timezone\n  TZ: \"Europe\u002FBerlin\"\n  GITLAB_TIMEZONE: \"Berlin\"\n  # GitLab\n  GITLAB_ROOT_EMAIL: \"admin@example.com\"\n  GITLAB_HOST: \"gitlab.example.com\"\n  GITLAB_PORT: \"443\"\n  GITLAB_SSH_HOST: \"ssh.gitlab.example.com\"\n  GITLAB_SSH_PORT: \"22\"\n  GITLAB_HTTPS: \"true\"\n  GITLAB_NOTIFY_ON_BROKEN_BUILDS: \"true\"\n  GITLAB_NOTIFY_PUSHER: \"false\"\n  GITLAB_PIPELINE_SCHEDULE_WORKER_CRON: \"*\u002F5 * * * *\"\n  # GitLab Backup\n  GITLAB_BACKUP_SCHEDULE: \"daily\"\n  GITLAB_BACKUP_TIME: \"04:30\"\n  # GitLab DB\n  DB_ADAPTER: \"postgresql\"\n  DB_HOST: \"__YOUR_POSTGRES_ADDRESS__\"\n  DB_PORT: \"5432\"\n  DB_USER: \"gitlab\"\n  DB_NAME: \"gitlab\"\n  # GitLab Redis\n  REDIS_HOST: \"__YOUR_REDIS_ADDRESS__\"\n  REDIS_PORT: \"6379\"\n  # Nginx settings\n  NGINX_MAX_UPLOAD_SIZE: \"100m\"\n  # GitLab SMTP settings\n  GITLAB_EMAIL: \"noreply@example.com\"\n  GITLAB_EMAIL_DISPLAY_NAME: \"GitLab Example\"\n  GITLAB_EMAIL_REPLY_TO: \"gitlab@example.com\"\n  SMTP_ENABLED: \"true\"\n  SMTP_DOMAIN: \"example.com\"\n  SMTP_HOST: \"smtp.example.com\"\n  SMTP_PORT: \"587\"\n  SMTP_USER: \"gitlab\"\n  SMTP_STARTTLS: \"true\"\n  SMTP_AUTHENTICATION: \"login\"\n  # Your other config vars below\nkind: ConfigMap\nmetadata:\n  labels:\n    app: gitlab\n  name: gitlab-cm\n",[567,65123,65124,65132,65138,65143,65157,65171,65176,65190,65203,65217,65231,65245,65258,65271,65284,65298,65303,65317,65331,65336,65349,65363,65377,65391,65404,65409,65423,65437,65442,65456,65461,65475,65489,65503,65516,65529,65543,65557,65570,65583,65597,65602,65610,65616,65622,65631],{"__ignoreMap":743},[747,65125,65126,65128,65130],{"class":749,"line":750},[747,65127,12949],{"class":753},[747,65129,856],{"class":757},[747,65131,22608],{"class":802},[747,65133,65134,65136],{"class":749,"line":761},[747,65135,30860],{"class":753},[747,65137,758],{"class":757},[747,65139,65140],{"class":749,"line":769},[747,65141,65142],{"class":772},"  # Timezone\n",[747,65144,65145,65148,65150,65152,65155],{"class":749,"line":776},[747,65146,65147],{"class":753},"  TZ",[747,65149,856],{"class":757},[747,65151,969],{"class":757},[747,65153,65154],{"class":802},"Europe\u002FBerlin",[747,65156,975],{"class":757},[747,65158,65159,65162,65164,65166,65169],{"class":749,"line":784},[747,65160,65161],{"class":753},"  GITLAB_TIMEZONE",[747,65163,856],{"class":757},[747,65165,969],{"class":757},[747,65167,65168],{"class":802},"Berlin",[747,65170,975],{"class":757},[747,65172,65173],{"class":749,"line":790},[747,65174,65175],{"class":772},"  # GitLab\n",[747,65177,65178,65181,65183,65185,65188],{"class":749,"line":796},[747,65179,65180],{"class":753},"  GITLAB_ROOT_EMAIL",[747,65182,856],{"class":757},[747,65184,969],{"class":757},[747,65186,65187],{"class":802},"admin@example.com",[747,65189,975],{"class":757},[747,65191,65192,65195,65197,65199,65201],{"class":749,"line":806},[747,65193,65194],{"class":753},"  GITLAB_HOST",[747,65196,856],{"class":757},[747,65198,969],{"class":757},[747,65200,25126],{"class":802},[747,65202,975],{"class":757},[747,65204,65205,65208,65210,65212,65215],{"class":749,"line":814},[747,65206,65207],{"class":753},"  GITLAB_PORT",[747,65209,856],{"class":757},[747,65211,969],{"class":757},[747,65213,65214],{"class":802},"443",[747,65216,975],{"class":757},[747,65218,65219,65222,65224,65226,65229],{"class":749,"line":822},[747,65220,65221],{"class":753},"  GITLAB_SSH_HOST",[747,65223,856],{"class":757},[747,65225,969],{"class":757},[747,65227,65228],{"class":802},"ssh.gitlab.example.com",[747,65230,975],{"class":757},[747,65232,65233,65236,65238,65240,65243],{"class":749,"line":830},[747,65234,65235],{"class":753},"  GITLAB_SSH_PORT",[747,65237,856],{"class":757},[747,65239,969],{"class":757},[747,65241,65242],{"class":802},"22",[747,65244,975],{"class":757},[747,65246,65247,65250,65252,65254,65256],{"class":749,"line":836},[747,65248,65249],{"class":753},"  GITLAB_HTTPS",[747,65251,856],{"class":757},[747,65253,969],{"class":757},[747,65255,5306],{"class":802},[747,65257,975],{"class":757},[747,65259,65260,65263,65265,65267,65269],{"class":749,"line":842},[747,65261,65262],{"class":753},"  GITLAB_NOTIFY_ON_BROKEN_BUILDS",[747,65264,856],{"class":757},[747,65266,969],{"class":757},[747,65268,5306],{"class":802},[747,65270,975],{"class":757},[747,65272,65273,65276,65278,65280,65282],{"class":749,"line":850},[747,65274,65275],{"class":753},"  GITLAB_NOTIFY_PUSHER",[747,65277,856],{"class":757},[747,65279,969],{"class":757},[747,65281,62546],{"class":802},[747,65283,975],{"class":757},[747,65285,65286,65289,65291,65293,65296],{"class":749,"line":863},[747,65287,65288],{"class":753},"  GITLAB_PIPELINE_SCHEDULE_WORKER_CRON",[747,65290,856],{"class":757},[747,65292,969],{"class":757},[747,65294,65295],{"class":802},"*\u002F5 * * * *",[747,65297,975],{"class":757},[747,65299,65300],{"class":749,"line":869},[747,65301,65302],{"class":772},"  # GitLab Backup\n",[747,65304,65305,65308,65310,65312,65315],{"class":749,"line":877},[747,65306,65307],{"class":753},"  GITLAB_BACKUP_SCHEDULE",[747,65309,856],{"class":757},[747,65311,969],{"class":757},[747,65313,65314],{"class":802},"daily",[747,65316,975],{"class":757},[747,65318,65319,65322,65324,65326,65329],{"class":749,"line":1015},[747,65320,65321],{"class":753},"  GITLAB_BACKUP_TIME",[747,65323,856],{"class":757},[747,65325,969],{"class":757},[747,65327,65328],{"class":802},"04:30",[747,65330,975],{"class":757},[747,65332,65333],{"class":749,"line":1021},[747,65334,65335],{"class":772},"  # GitLab DB\n",[747,65337,65338,65341,65343,65345,65347],{"class":749,"line":1027},[747,65339,65340],{"class":753},"  DB_ADAPTER",[747,65342,856],{"class":757},[747,65344,969],{"class":757},[747,65346,16985],{"class":802},[747,65348,975],{"class":757},[747,65350,65351,65354,65356,65358,65361],{"class":749,"line":1033},[747,65352,65353],{"class":753},"  DB_HOST",[747,65355,856],{"class":757},[747,65357,969],{"class":757},[747,65359,65360],{"class":802},"__YOUR_POSTGRES_ADDRESS__",[747,65362,975],{"class":757},[747,65364,65365,65368,65370,65372,65375],{"class":749,"line":1039},[747,65366,65367],{"class":753},"  DB_PORT",[747,65369,856],{"class":757},[747,65371,969],{"class":757},[747,65373,65374],{"class":802},"5432",[747,65376,975],{"class":757},[747,65378,65379,65382,65384,65386,65389],{"class":749,"line":1054},[747,65380,65381],{"class":753},"  DB_USER",[747,65383,856],{"class":757},[747,65385,969],{"class":757},[747,65387,65388],{"class":802},"gitlab",[747,65390,975],{"class":757},[747,65392,65393,65396,65398,65400,65402],{"class":749,"line":1060},[747,65394,65395],{"class":753},"  DB_NAME",[747,65397,856],{"class":757},[747,65399,969],{"class":757},[747,65401,65388],{"class":802},[747,65403,975],{"class":757},[747,65405,65406],{"class":749,"line":1066},[747,65407,65408],{"class":772},"  # GitLab Redis\n",[747,65410,65411,65414,65416,65418,65421],{"class":749,"line":1081},[747,65412,65413],{"class":753},"  REDIS_HOST",[747,65415,856],{"class":757},[747,65417,969],{"class":757},[747,65419,65420],{"class":802},"__YOUR_REDIS_ADDRESS__",[747,65422,975],{"class":757},[747,65424,65425,65428,65430,65432,65435],{"class":749,"line":1087},[747,65426,65427],{"class":753},"  REDIS_PORT",[747,65429,856],{"class":757},[747,65431,969],{"class":757},[747,65433,65434],{"class":802},"6379",[747,65436,975],{"class":757},[747,65438,65439],{"class":749,"line":1102},[747,65440,65441],{"class":772},"  # Nginx settings\n",[747,65443,65444,65447,65449,65451,65454],{"class":749,"line":1110},[747,65445,65446],{"class":753},"  NGINX_MAX_UPLOAD_SIZE",[747,65448,856],{"class":757},[747,65450,969],{"class":757},[747,65452,65453],{"class":802},"100m",[747,65455,975],{"class":757},[747,65457,65458],{"class":749,"line":1117},[747,65459,65460],{"class":772},"  # GitLab SMTP settings\n",[747,65462,65463,65466,65468,65470,65473],{"class":749,"line":1123},[747,65464,65465],{"class":753},"  GITLAB_EMAIL",[747,65467,856],{"class":757},[747,65469,969],{"class":757},[747,65471,65472],{"class":802},"noreply@example.com",[747,65474,975],{"class":757},[747,65476,65477,65480,65482,65484,65487],{"class":749,"line":1129},[747,65478,65479],{"class":753},"  GITLAB_EMAIL_DISPLAY_NAME",[747,65481,856],{"class":757},[747,65483,969],{"class":757},[747,65485,65486],{"class":802},"GitLab Example",[747,65488,975],{"class":757},[747,65490,65491,65494,65496,65498,65501],{"class":749,"line":1142},[747,65492,65493],{"class":753},"  GITLAB_EMAIL_REPLY_TO",[747,65495,856],{"class":757},[747,65497,969],{"class":757},[747,65499,65500],{"class":802},"gitlab@example.com",[747,65502,975],{"class":757},[747,65504,65505,65508,65510,65512,65514],{"class":749,"line":1150},[747,65506,65507],{"class":753},"  SMTP_ENABLED",[747,65509,856],{"class":757},[747,65511,969],{"class":757},[747,65513,5306],{"class":802},[747,65515,975],{"class":757},[747,65517,65518,65521,65523,65525,65527],{"class":749,"line":1157},[747,65519,65520],{"class":753},"  SMTP_DOMAIN",[747,65522,856],{"class":757},[747,65524,969],{"class":757},[747,65526,27997],{"class":802},[747,65528,975],{"class":757},[747,65530,65531,65534,65536,65538,65541],{"class":749,"line":1163},[747,65532,65533],{"class":753},"  SMTP_HOST",[747,65535,856],{"class":757},[747,65537,969],{"class":757},[747,65539,65540],{"class":802},"smtp.example.com",[747,65542,975],{"class":757},[747,65544,65545,65548,65550,65552,65555],{"class":749,"line":1168},[747,65546,65547],{"class":753},"  SMTP_PORT",[747,65549,856],{"class":757},[747,65551,969],{"class":757},[747,65553,65554],{"class":802},"587",[747,65556,975],{"class":757},[747,65558,65559,65562,65564,65566,65568],{"class":749,"line":1174},[747,65560,65561],{"class":753},"  SMTP_USER",[747,65563,856],{"class":757},[747,65565,969],{"class":757},[747,65567,65388],{"class":802},[747,65569,975],{"class":757},[747,65571,65572,65575,65577,65579,65581],{"class":749,"line":1480},[747,65573,65574],{"class":753},"  SMTP_STARTTLS",[747,65576,856],{"class":757},[747,65578,969],{"class":757},[747,65580,5306],{"class":802},[747,65582,975],{"class":757},[747,65584,65585,65588,65590,65592,65595],{"class":749,"line":1491},[747,65586,65587],{"class":753},"  SMTP_AUTHENTICATION",[747,65589,856],{"class":757},[747,65591,969],{"class":757},[747,65593,65594],{"class":802},"login",[747,65596,975],{"class":757},[747,65598,65599],{"class":749,"line":1496},[747,65600,65601],{"class":772},"  # Your other config vars below\n",[747,65603,65604,65606,65608],{"class":749,"line":1502},[747,65605,12963],{"class":753},[747,65607,856],{"class":757},[747,65609,30930],{"class":802},[747,65611,65612,65614],{"class":749,"line":1510},[747,65613,12973],{"class":753},[747,65615,758],{"class":757},[747,65617,65618,65620],{"class":749,"line":1520},[747,65619,25378],{"class":753},[747,65621,758],{"class":757},[747,65623,65624,65626,65628],{"class":749,"line":1525},[747,65625,25385],{"class":753},[747,65627,856],{"class":757},[747,65629,65630],{"class":802}," gitlab\n",[747,65632,65633,65635,65637],{"class":749,"line":1533},[747,65634,12980],{"class":753},[747,65636,856],{"class":757},[747,65638,65639],{"class":802}," gitlab-cm\n",[613,65641,25167],{"id":30977},[523,65643,65644,65645,65647,65648,65651,65652,65654],{},"The values for the ",[567,65646,30860],{}," keys, need to be ",[567,65649,65650],{},"base64"," encoded.\nThis can be done from the command line on most Linuxes using the ",[567,65653,65650],{}," command. Like this:",[738,65656,65658],{"className":1621,"code":65657,"language":1623,"meta":743,"style":743},"echo -n \"YOUR_VALUE\" | base64 -w0\n",[567,65659,65660],{"__ignoreMap":743},[747,65661,65662,65665,65667,65669,65672,65674,65676,65678],{"class":749,"line":750},[747,65663,65664],{"class":4574},"echo",[747,65666,1928],{"class":802},[747,65668,969],{"class":757},[747,65670,65671],{"class":802},"YOUR_VALUE",[747,65673,3892],{"class":757},[747,65675,3170],{"class":757},[747,65677,23293],{"class":1630},[747,65679,65680],{"class":802}," -w0\n",[523,65682,65683,65684,65687,65688,65690],{},"(The ",[567,65685,65686],{},"-w0"," stops ",[567,65689,65650],{}," wrapping after specific length per line)",[523,65692,65693,65694,65697],{},"In the manifest below there are variables beginning with ",[567,65695,65696],{},"__YOUR_...__",", you need to replace those.",[668,65699,65700,65709,65718,65726],{},[638,65701,65702,65705,65706,65708],{},[567,65703,65704],{},"__YOUR_GITLAB_SECRETS_"," variables should be replaced by ",[567,65707,65650],{}," encoded randomly generated strings.",[638,65710,65711,65714,65715,65717],{},[567,65712,65713],{},"__YOUR_DB_PASS__"," should be replaced by ",[567,65716,65650],{}," encoded Postgres database server password.",[638,65719,65720,65714,65723,65725],{},[567,65721,65722],{},"__YOUR_SMTP_PASS__",[567,65724,65650],{}," encoded SMTP server password.",[638,65727,65728,65714,65731,65733,65734,65736],{},[567,65729,65730],{},"__YOUR_GITLAB_ROOT_PASSWORD__",[567,65732,65650],{}," encoded chosen first GitLab user ",[567,65735,44454],{}," password of your choice.",[523,65738,65739],{},"The manifest looks like this:",[738,65741,65743],{"className":740,"code":65742,"language":742,"meta":743,"style":743},"apiVersion: v1\ndata:\n  GITLAB_SECRETS_DB_KEY_BASE: __YOUR_GITLAB_SECRETS_DB_KEY_BASE__\n  GITLAB_SECRETS_SECRET_KEY_BASE: __YOUR_GITLAB_SECRETS_SECRET_KEY_BASE__\n  GITLAB_SECRETS_OTP_KEY_BASE: __YOUR_GITLAB_SECRETS_OTP_KEY_BASE__\n  DB_PASS: __YOUR_DB_PASS__\n  SMTP_PASS: __YOUR_SMTP_PASS__\n  GITLAB_ROOT_PASSWORD: __YOUR_GITLAB_ROOT_PASSWORD__\nkind: Secret\nmetadata:\n  labels:\n    app: gitlab\n  name: gitlab-secret\ntype: Opaque\n",[567,65744,65745,65753,65759,65769,65779,65789,65799,65809,65819,65827,65833,65839,65847,65856],{"__ignoreMap":743},[747,65746,65747,65749,65751],{"class":749,"line":750},[747,65748,12949],{"class":753},[747,65750,856],{"class":757},[747,65752,22608],{"class":802},[747,65754,65755,65757],{"class":749,"line":761},[747,65756,30860],{"class":753},[747,65758,758],{"class":757},[747,65760,65761,65764,65766],{"class":749,"line":769},[747,65762,65763],{"class":753},"  GITLAB_SECRETS_DB_KEY_BASE",[747,65765,856],{"class":757},[747,65767,65768],{"class":802}," __YOUR_GITLAB_SECRETS_DB_KEY_BASE__\n",[747,65770,65771,65774,65776],{"class":749,"line":776},[747,65772,65773],{"class":753},"  GITLAB_SECRETS_SECRET_KEY_BASE",[747,65775,856],{"class":757},[747,65777,65778],{"class":802}," __YOUR_GITLAB_SECRETS_SECRET_KEY_BASE__\n",[747,65780,65781,65784,65786],{"class":749,"line":784},[747,65782,65783],{"class":753},"  GITLAB_SECRETS_OTP_KEY_BASE",[747,65785,856],{"class":757},[747,65787,65788],{"class":802}," __YOUR_GITLAB_SECRETS_OTP_KEY_BASE__\n",[747,65790,65791,65794,65796],{"class":749,"line":790},[747,65792,65793],{"class":753},"  DB_PASS",[747,65795,856],{"class":757},[747,65797,65798],{"class":802}," __YOUR_DB_PASS__\n",[747,65800,65801,65804,65806],{"class":749,"line":796},[747,65802,65803],{"class":753},"  SMTP_PASS",[747,65805,856],{"class":757},[747,65807,65808],{"class":802}," __YOUR_SMTP_PASS__\n",[747,65810,65811,65814,65816],{"class":749,"line":806},[747,65812,65813],{"class":753},"  GITLAB_ROOT_PASSWORD",[747,65815,856],{"class":757},[747,65817,65818],{"class":802}," __YOUR_GITLAB_ROOT_PASSWORD__\n",[747,65820,65821,65823,65825],{"class":749,"line":814},[747,65822,12963],{"class":753},[747,65824,856],{"class":757},[747,65826,23233],{"class":802},[747,65828,65829,65831],{"class":749,"line":822},[747,65830,12973],{"class":753},[747,65832,758],{"class":757},[747,65834,65835,65837],{"class":749,"line":830},[747,65836,25378],{"class":753},[747,65838,758],{"class":757},[747,65840,65841,65843,65845],{"class":749,"line":836},[747,65842,25385],{"class":753},[747,65844,856],{"class":757},[747,65846,65630],{"class":802},[747,65848,65849,65851,65853],{"class":749,"line":842},[747,65850,12980],{"class":753},[747,65852,856],{"class":757},[747,65854,65855],{"class":802}," gitlab-secret\n",[747,65857,65858,65860,65862],{"class":749,"line":850},[747,65859,23273],{"class":753},[747,65861,856],{"class":757},[747,65863,31087],{"class":802},[613,65865,30276],{"id":65866},"statefulset",[523,65868,65869,65870,65872,65873,11304,65875,65877,65878,65880],{},"This ",[567,65871,30276],{}," contains the image used and what is not often used ",[567,65874,31629],{},[567,65876,31629],{}," uses a list of \"references\" to ConfigMaps and Secrets and puts them as environment variables into the Pod.\nUsing ",[567,65879,31629],{}," has one disadvantage, when updating a ConfigMap or Secret referenced, the Pod doesn't get \"updated\"\u002Frecreated.\nDepending on how you look at rolling out software every change to a ConfigMap and Secret can be considered a version change aka updating the object to trigger update of the Pods.",[523,65882,65883,65884,65887],{},"You need to replace ",[567,65885,65886],{},"__STORAGE_CLASS__"," with the available StorageClass in your Kubernetes cluster.",[738,65889,65891],{"className":740,"code":65890,"language":742,"meta":743,"style":743},"apiVersion: apps\u002Fv1beta1\nkind: StatefulSet\nmetadata:\n  labels:\n    app: gitlab\n  name: gitlab\nspec:\n  serviceName: gitlab\n  replicas: 1\n  volumeClaimTemplates:\n  - metadata:\n      name: gitlab-persistent-storage\n    spec:\n      accessModes: [ \"ReadWriteOnce\" ]\n      storageClassName: __STORAGE_CLASS__\n      resources:\n        requests:\n          storage: 50Gi\n  template:\n    metadata:\n      labels:\n        app: gitlab\n    spec:\n      containers:\n      - name: gitlab\n        image: sameersbn\u002Fgitlab:10.1.1\n        imagePullPolicy: Always\n        envFrom:\n          - configMapRef:\n              name: gitlab-cm\n          - secretRef:\n              name: gitlab-secret\n        ports:\n        - containerPort: 22\n          name: ssh\n          protocol: TCP\n        - containerPort: 80\n          name: http\n          protocol: TCP\n        resources:\n          limits:\n            cpu: \"2\"\n            memory: 4Gi\n          requests:\n            cpu: \"500m\"\n            memory: \"1Gi\"\n        volumeMounts:\n        - name: gitlab-persistent-storage\n          mountPath: \u002Fhome\u002Fgit\u002Fdata\n",[567,65892,65893,65902,65911,65917,65923,65931,65939,65945,65954,65962,65969,65978,65987,65993,66011,66021,66028,66035,66045,66051,66057,66063,66071,66077,66083,66093,66102,66110,66116,66124,66132,66140,66148,66154,66165,66174,66182,66192,66200,66208,66215,66222,66235,66245,66252,66265,66278,66284,66294],{"__ignoreMap":743},[747,65894,65895,65897,65899],{"class":749,"line":750},[747,65896,12949],{"class":753},[747,65898,856],{"class":757},[747,65900,65901],{"class":802}," apps\u002Fv1beta1\n",[747,65903,65904,65906,65908],{"class":749,"line":761},[747,65905,12963],{"class":753},[747,65907,856],{"class":757},[747,65909,65910],{"class":802}," StatefulSet\n",[747,65912,65913,65915],{"class":749,"line":769},[747,65914,12973],{"class":753},[747,65916,758],{"class":757},[747,65918,65919,65921],{"class":749,"line":776},[747,65920,25378],{"class":753},[747,65922,758],{"class":757},[747,65924,65925,65927,65929],{"class":749,"line":784},[747,65926,25385],{"class":753},[747,65928,856],{"class":757},[747,65930,65630],{"class":802},[747,65932,65933,65935,65937],{"class":749,"line":790},[747,65934,12980],{"class":753},[747,65936,856],{"class":757},[747,65938,65630],{"class":802},[747,65940,65941,65943],{"class":749,"line":796},[747,65942,12990],{"class":753},[747,65944,758],{"class":757},[747,65946,65947,65950,65952],{"class":749,"line":806},[747,65948,65949],{"class":753},"  serviceName",[747,65951,856],{"class":757},[747,65953,65630],{"class":802},[747,65955,65956,65958,65960],{"class":749,"line":814},[747,65957,25420],{"class":753},[747,65959,856],{"class":757},[747,65961,18691],{"class":1895},[747,65963,65964,65967],{"class":749,"line":822},[747,65965,65966],{"class":753},"  volumeClaimTemplates",[747,65968,758],{"class":757},[747,65970,65971,65973,65976],{"class":749,"line":830},[747,65972,1721],{"class":757},[747,65974,65975],{"class":753}," metadata",[747,65977,758],{"class":757},[747,65979,65980,65982,65984],{"class":749,"line":836},[747,65981,925],{"class":753},[747,65983,856],{"class":757},[747,65985,65986],{"class":802}," gitlab-persistent-storage\n",[747,65988,65989,65991],{"class":749,"line":842},[747,65990,25509],{"class":753},[747,65992,758],{"class":757},[747,65994,65995,65998,66000,66002,66004,66006,66008],{"class":749,"line":850},[747,65996,65997],{"class":753},"      accessModes",[747,65999,856],{"class":757},[747,66001,4262],{"class":757},[747,66003,969],{"class":757},[747,66005,32370],{"class":802},[747,66007,3892],{"class":757},[747,66009,66010],{"class":757}," ]\n",[747,66012,66013,66016,66018],{"class":749,"line":863},[747,66014,66015],{"class":753},"      storageClassName",[747,66017,856],{"class":757},[747,66019,66020],{"class":802}," __STORAGE_CLASS__\n",[747,66022,66023,66026],{"class":749,"line":869},[747,66024,66025],{"class":753},"      resources",[747,66027,758],{"class":757},[747,66029,66030,66033],{"class":749,"line":877},[747,66031,66032],{"class":753},"        requests",[747,66034,758],{"class":757},[747,66036,66037,66040,66042],{"class":749,"line":1015},[747,66038,66039],{"class":753},"          storage",[747,66041,856],{"class":757},[747,66043,66044],{"class":802}," 50Gi\n",[747,66046,66047,66049],{"class":749,"line":1021},[747,66048,25462],{"class":753},[747,66050,758],{"class":757},[747,66052,66053,66055],{"class":749,"line":1027},[747,66054,21456],{"class":753},[747,66056,758],{"class":757},[747,66058,66059,66061],{"class":749,"line":1033},[747,66060,25475],{"class":753},[747,66062,758],{"class":757},[747,66064,66065,66067,66069],{"class":749,"line":1039},[747,66066,25482],{"class":753},[747,66068,856],{"class":757},[747,66070,65630],{"class":802},[747,66072,66073,66075],{"class":749,"line":1054},[747,66074,25509],{"class":753},[747,66076,758],{"class":757},[747,66078,66079,66081],{"class":749,"line":1060},[747,66080,25516],{"class":753},[747,66082,758],{"class":757},[747,66084,66085,66087,66089,66091],{"class":749,"line":1066},[747,66086,799],{"class":757},[747,66088,14804],{"class":753},[747,66090,856],{"class":757},[747,66092,65630],{"class":802},[747,66094,66095,66097,66099],{"class":749,"line":1081},[747,66096,25533],{"class":753},[747,66098,856],{"class":757},[747,66100,66101],{"class":802}," sameersbn\u002Fgitlab:10.1.1\n",[747,66103,66104,66106,66108],{"class":749,"line":1087},[747,66105,25543],{"class":753},[747,66107,856],{"class":757},[747,66109,25548],{"class":802},[747,66111,66112,66114],{"class":749,"line":1102},[747,66113,31559],{"class":753},[747,66115,758],{"class":757},[747,66117,66118,66120,66122],{"class":749,"line":1110},[747,66119,62242],{"class":757},[747,66121,31594],{"class":753},[747,66123,758],{"class":757},[747,66125,66126,66128,66130],{"class":749,"line":1117},[747,66127,31491],{"class":753},[747,66129,856],{"class":757},[747,66131,65639],{"class":802},[747,66133,66134,66136,66138],{"class":749,"line":1123},[747,66135,62242],{"class":757},[747,66137,31572],{"class":753},[747,66139,758],{"class":757},[747,66141,66142,66144,66146],{"class":749,"line":1129},[747,66143,31491],{"class":753},[747,66145,856],{"class":757},[747,66147,65855],{"class":802},[747,66149,66150,66152],{"class":749,"line":1142},[747,66151,25553],{"class":753},[747,66153,758],{"class":757},[747,66155,66156,66158,66160,66162],{"class":749,"line":1150},[747,66157,14801],{"class":757},[747,66159,29864],{"class":753},[747,66161,856],{"class":757},[747,66163,66164],{"class":1895}," 22\n",[747,66166,66167,66169,66171],{"class":749,"line":1157},[747,66168,30581],{"class":753},[747,66170,856],{"class":757},[747,66172,66173],{"class":802}," ssh\n",[747,66175,66176,66178,66180],{"class":749,"line":1163},[747,66177,25571],{"class":753},[747,66179,856],{"class":757},[747,66181,25576],{"class":802},[747,66183,66184,66186,66188,66190],{"class":749,"line":1168},[747,66185,14801],{"class":757},[747,66187,29864],{"class":753},[747,66189,856],{"class":757},[747,66191,29869],{"class":1895},[747,66193,66194,66196,66198],{"class":749,"line":1174},[747,66195,30581],{"class":753},[747,66197,856],{"class":757},[747,66199,29878],{"class":802},[747,66201,66202,66204,66206],{"class":749,"line":1480},[747,66203,25571],{"class":753},[747,66205,856],{"class":757},[747,66207,25576],{"class":802},[747,66209,66210,66213],{"class":749,"line":1491},[747,66211,66212],{"class":753},"        resources",[747,66214,758],{"class":757},[747,66216,66217,66220],{"class":749,"line":1496},[747,66218,66219],{"class":753},"          limits",[747,66221,758],{"class":757},[747,66223,66224,66227,66229,66231,66233],{"class":749,"line":1502},[747,66225,66226],{"class":753},"            cpu",[747,66228,856],{"class":757},[747,66230,969],{"class":757},[747,66232,18115],{"class":802},[747,66234,975],{"class":757},[747,66236,66237,66240,66242],{"class":749,"line":1510},[747,66238,66239],{"class":753},"            memory",[747,66241,856],{"class":757},[747,66243,66244],{"class":802}," 4Gi\n",[747,66246,66247,66250],{"class":749,"line":1520},[747,66248,66249],{"class":753},"          requests",[747,66251,758],{"class":757},[747,66253,66254,66256,66258,66260,66263],{"class":749,"line":1525},[747,66255,66226],{"class":753},[747,66257,856],{"class":757},[747,66259,969],{"class":757},[747,66261,66262],{"class":802},"500m",[747,66264,975],{"class":757},[747,66266,66267,66269,66271,66273,66276],{"class":749,"line":1533},[747,66268,66239],{"class":753},[747,66270,856],{"class":757},[747,66272,969],{"class":757},[747,66274,66275],{"class":802},"1Gi",[747,66277,975],{"class":757},[747,66279,66280,66282],{"class":749,"line":1539},[747,66281,32736],{"class":753},[747,66283,758],{"class":757},[747,66285,66286,66288,66290,66292],{"class":749,"line":1549},[747,66287,14801],{"class":757},[747,66289,14804],{"class":753},[747,66291,856],{"class":757},[747,66293,65986],{"class":802},[747,66295,66296,66298,66300],{"class":749,"line":1554},[747,66297,32753],{"class":753},[747,66299,856],{"class":757},[747,66301,66302],{"class":802}," \u002Fhome\u002Fgit\u002Fdata\n",[613,66304,25729],{"id":3243},[523,66306,66307],{},"This Service is for the Ingress to be able to reach the GitLab.",[738,66309,66311],{"className":740,"code":66310,"language":742,"meta":743,"style":743},"apiVersion: v1\nkind: Service\nmetadata:\n  labels:\n    app: gitlab\n  name: gitlab\nspec:\n  ports:\n  - name: ssh\n    port: 22\n    protocol: TCP\n  - name: http\n    port: 80\n    protocol: TCP\n  selector:\n    app: gitlab\n",[567,66312,66313,66321,66329,66335,66341,66349,66357,66363,66369,66379,66388,66397,66407,66415,66423,66429],{"__ignoreMap":743},[747,66314,66315,66317,66319],{"class":749,"line":750},[747,66316,12949],{"class":753},[747,66318,856],{"class":757},[747,66320,22608],{"class":802},[747,66322,66323,66325,66327],{"class":749,"line":761},[747,66324,12963],{"class":753},[747,66326,856],{"class":757},[747,66328,25758],{"class":802},[747,66330,66331,66333],{"class":749,"line":769},[747,66332,12973],{"class":753},[747,66334,758],{"class":757},[747,66336,66337,66339],{"class":749,"line":776},[747,66338,25378],{"class":753},[747,66340,758],{"class":757},[747,66342,66343,66345,66347],{"class":749,"line":784},[747,66344,25385],{"class":753},[747,66346,856],{"class":757},[747,66348,65630],{"class":802},[747,66350,66351,66353,66355],{"class":749,"line":790},[747,66352,12980],{"class":753},[747,66354,856],{"class":757},[747,66356,65630],{"class":802},[747,66358,66359,66361],{"class":749,"line":796},[747,66360,12990],{"class":753},[747,66362,758],{"class":757},[747,66364,66365,66367],{"class":749,"line":806},[747,66366,25878],{"class":753},[747,66368,758],{"class":757},[747,66370,66371,66373,66375,66377],{"class":749,"line":814},[747,66372,1721],{"class":757},[747,66374,14804],{"class":753},[747,66376,856],{"class":757},[747,66378,66173],{"class":802},[747,66380,66381,66384,66386],{"class":749,"line":822},[747,66382,66383],{"class":753},"    port",[747,66385,856],{"class":757},[747,66387,66164],{"class":1895},[747,66389,66390,66393,66395],{"class":749,"line":830},[747,66391,66392],{"class":753},"    protocol",[747,66394,856],{"class":757},[747,66396,25576],{"class":802},[747,66398,66399,66401,66403,66405],{"class":749,"line":836},[747,66400,1721],{"class":757},[747,66402,14804],{"class":753},[747,66404,856],{"class":757},[747,66406,29878],{"class":802},[747,66408,66409,66411,66413],{"class":749,"line":842},[747,66410,66383],{"class":753},[747,66412,856],{"class":757},[747,66414,29869],{"class":1895},[747,66416,66417,66419,66421],{"class":749,"line":850},[747,66418,66392],{"class":753},[747,66420,856],{"class":757},[747,66422,25576],{"class":802},[747,66424,66425,66427],{"class":749,"line":863},[747,66426,25430],{"class":753},[747,66428,758],{"class":757},[747,66430,66431,66433,66435],{"class":749,"line":869},[747,66432,25385],{"class":753},[747,66434,856],{"class":757},[747,66436,65630],{"class":802},[613,66438,158],{"id":66439},"ingress",[523,66441,66442,66443,66446,66447,66450],{},"To be able to reach the GitLab from outside the cluster over your Ingress controller of choice.\nThe Ingress requires the Service created in ",[527,66444,25729],{"href":66445},"#Service",".\nYou need to replace ",[567,66448,66449],{},"__INGRESS_CLASS__"," with your in cluster configured Ingress controller.",[738,66452,66454],{"className":740,"code":66453,"language":742,"meta":743,"style":743},"apiVersion: extensions\u002Fv1beta1\nkind: Ingress\nmetadata:\n  name: gitlab-examplecom\n  annotations:\n    kubernetes.io\u002Fingress.class: __INGRESS_CLASS__\nspec:\n  rules:\n  - host: gitlab.example.com\n    http:\n      paths:\n      - path: \u002F\n        backend:\n          serviceName: gitlab\n          servicePort: 80\n",[567,66455,66456,66464,66472,66478,66487,66493,66502,66508,66514,66525,66531,66537,66547,66553,66561],{"__ignoreMap":743},[747,66457,66458,66460,66462],{"class":749,"line":750},[747,66459,12949],{"class":753},[747,66461,856],{"class":757},[747,66463,25977],{"class":802},[747,66465,66466,66468,66470],{"class":749,"line":761},[747,66467,12963],{"class":753},[747,66469,856],{"class":757},[747,66471,25986],{"class":802},[747,66473,66474,66476],{"class":749,"line":769},[747,66475,12973],{"class":753},[747,66477,758],{"class":757},[747,66479,66480,66482,66484],{"class":749,"line":776},[747,66481,12980],{"class":753},[747,66483,856],{"class":757},[747,66485,66486],{"class":802}," gitlab-examplecom\n",[747,66488,66489,66491],{"class":749,"line":784},[747,66490,25801],{"class":753},[747,66492,758],{"class":757},[747,66494,66495,66497,66499],{"class":749,"line":790},[747,66496,26046],{"class":753},[747,66498,856],{"class":757},[747,66500,66501],{"class":802}," __INGRESS_CLASS__\n",[747,66503,66504,66506],{"class":749,"line":796},[747,66505,12990],{"class":753},[747,66507,758],{"class":757},[747,66509,66510,66512],{"class":749,"line":806},[747,66511,26108],{"class":753},[747,66513,758],{"class":757},[747,66515,66516,66518,66520,66522],{"class":749,"line":814},[747,66517,1721],{"class":757},[747,66519,4591],{"class":753},[747,66521,856],{"class":757},[747,66523,66524],{"class":802}," gitlab.example.com\n",[747,66526,66527,66529],{"class":749,"line":822},[747,66528,26125],{"class":753},[747,66530,758],{"class":757},[747,66532,66533,66535],{"class":749,"line":830},[747,66534,26132],{"class":753},[747,66536,758],{"class":757},[747,66538,66539,66541,66543,66545],{"class":749,"line":836},[747,66540,799],{"class":757},[747,66542,26141],{"class":753},[747,66544,856],{"class":757},[747,66546,26146],{"class":802},[747,66548,66549,66551],{"class":749,"line":842},[747,66550,26151],{"class":753},[747,66552,758],{"class":757},[747,66554,66555,66557,66559],{"class":749,"line":850},[747,66556,26158],{"class":753},[747,66558,856],{"class":757},[747,66560,65630],{"class":802},[747,66562,66563,66565,66567],{"class":749,"line":863},[747,66564,26167],{"class":753},[747,66566,856],{"class":757},[747,66568,29869],{"class":1895},[535,66570,66572],{"id":66571},"step-3-create-the-manifests","Step 3 - Create the manifests",[523,66574,66575,66576,66578],{},"You can either a) save all manifests in one file, but then separated by ",[567,66577,28646],{}," or b) per manifest on file.\nTo create\u002Frun the mnaifests on Kubernetes, you can now go ahead an run:",[738,66580,66582],{"className":1621,"code":66581,"language":1623,"meta":743,"style":743},"kubectl create -f FILE_NAME\n",[567,66583,66584],{"__ignoreMap":743},[747,66585,66586,66588,66590,66592],{"class":749,"line":750},[747,66587,15269],{"class":1630},[747,66589,1925],{"class":802},[747,66591,1934],{"class":802},[747,66593,38705],{"class":802},[523,66595,66596,66597,66600,66601,66603],{},"Where ",[567,66598,66599],{},"FILE_NAME"," is the name of the file containing the mnaifest(s).\nIf the command I suggest you take a look at the line which ",[567,66602,15269],{}," told you the error is.",[535,66605,66607],{"id":66606},"step-4-login-to-your-new-gitlab","Step 4 - Login to your new GitLab",[523,66609,66610],{},"If everything was successfull, you should be able to see your GitLab instance in,\ndepending on the server network bandwith and GitLab database setup speed, about 10-15 minutes.",[523,66612,66613,66614,66618,66619,1909],{},"You should then be able to login to your GitLab over the domain name you used in the ",[527,66615,66617],{"href":66616},"#Ingress","Ingress manifest",".\nWith the example values above the address would be ",[567,66620,66621],{},"https:\u002F\u002Fgitlab.example.com",[523,66623,66624],{},"The login information for the first \"root\" user is:",[668,66626,66627,66632],{},[638,66628,66629,66630],{},"Username: ",[567,66631,44454],{},[638,66633,66634,66635,66637,66638],{},"Password: ",[567,66636,65650],{}," decoded value chosen in ",[527,66639,66640],{"href":65117},"Secret - GITLAB_ROOT_PASSWORD",[535,66642,14526],{"id":14525},[523,66644,66645,66646,1909],{},"I hope this gives a good idea on how to run GitLab on Kubernetes or even simply a starting point for extending\u002Fcustomizing the manifests for your needs.\nAnother starting point that also contains manifests for a single Postgres and Redis server, can be found here: ",[527,66647,64871],{"href":64871,"rel":66648},[531],[523,66650,13967],{},[2890,66652,66653],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":743,"searchDepth":761,"depth":761,"links":66655},[66656,66662,66663,66670,66671,66672],{"id":537,"depth":761,"text":538,"children":66657},[66658,66660,66661],{"id":64876,"depth":769,"text":66659},"Decision to use sameersbn GitLab image instead of the official",{"id":22267,"depth":769,"text":22268},{"id":64975,"depth":769,"text":64976},{"id":64988,"depth":761,"text":64989},{"id":65096,"depth":761,"text":65097,"children":66664},[66665,66666,66667,66668,66669],{"id":30793,"depth":769,"text":30063},{"id":30977,"depth":769,"text":25167},{"id":65866,"depth":769,"text":30276},{"id":3243,"depth":769,"text":25729},{"id":66439,"depth":769,"text":158},{"id":66571,"depth":761,"text":66572},{"id":66606,"depth":761,"text":66607},{"id":14525,"depth":761,"text":14526},"2017-11-04T18:00:46+02:00","How to run GitLab on top of a Kubernetes cluster with persitent storage.",{"src":66676},"\u002Fblog\u002F2017\u002Fgitlab-kubernetes-gitlab-on-top-of-kubernetes\u002Fgitlab-kubernetes-gitlab-on-top-of-kubernetes.png",{"tags":66678},[26414,26413,124,26415],"\u002Fblog\u002F2017\u002Fgitlab-kubernetes-gitlab-on-top-of-kubernetes",{"title":64841,"description":66674},"3.blog\u002F2017\u002Fgitlab-kubernetes-gitlab-on-top-of-kubernetes","zCf0g28_ForbKSDqYiCipzyzvgXFrSAXtoRHRV5G60c",{"id":66684,"title":66685,"authors":66686,"badge":518,"body":66689,"date":68040,"description":68041,"extension":2911,"image":68042,"meta":68044,"navigation":1254,"path":68047,"seo":68048,"stem":68049,"__hash__":68050},"posts\u002F3.blog\u002F2017\u002Fcontainer-linux-deploy-on-bare-metal-without-dhcp-server.md","Container Linux: Deploy on Bare-Metal without DHCP server",[66687],{"name":514,"to":515,"avatar":66688},{"src":517},{"type":520,"value":66690,"toc":68027},[66691,66693,66696,66700,66719,66723,66732,66798,66803,66875,66879,66882,66886,66898,66920,67020,67026,67050,67053,67056,67064,67087,67092,67131,67136,67168,67180,67220,67239,67294,67302,67317,67329,67348,67357,67360,67363,67450,67461,67464,67518,67524,67537,67540,67554,67562,67565,67765,67773,67780,67783,67868,67875,67885,67889,67895,68001,68008,68011,68017,68019,68022,68024],[535,66692,538],{"id":537},[523,66694,66695],{},"This post shows you how you can run Container Linux without a DHCP server configured for custom iPXE boot.",[613,66697,66699],{"id":66698},"clarification","Clarification",[523,66701,19507,66702,66707,66708,66713,66714,66718],{},[527,66703,66706],{"href":66704,"rel":66705},"https:\u002F\u002Fdisqus.com\u002Fby\u002Fjudiantara\u002F",[531],"Baju Judiantara"," for his ",[527,66709,66712],{"href":66710,"rel":66711},"https:\u002F\u002Fdisq.us\u002Fp\u002F1p8dqa7",[531],"comment","!\nHe correctly found that the title is contradict to the IPXE boot script in ",[527,66715,66717],{"href":66716},"#Step-4-Add-grub-config-for-iPXE-boot","Step 4 - Add grub config for iPXE boot",".\nTo resolve the conratdict of the title with the post I have added a snippet which does the interface configuration manual and not over DHCP.",[535,66720,66722],{"id":66721},"step-1-setup-matchbox","Step 1 - Setup Matchbox",[523,66724,66725,66726,66731],{},"I will not go over this here, as the CoreOS documentation about this is pretty good, see here: ",[527,66727,66730],{"href":66728,"rel":66729},"https:\u002F\u002Fgithub.com\u002Fcoreos\u002Fmatchbox\u002Fblob\u002Fmaster\u002FDocumentation\u002Fgetting-started.md#matchbox",[531],"coreos\u002Fmatchbox Documentation - Getting Started",".\nAt least for my I did something like this:",[668,66733,66734,66737,66750,66759,66762,66773,66793],{},[638,66735,66736],{},"Download and install matchbox (the way to run Matchbox as a Docker container be seen below).",[638,66738,66739,66740,587,66743,66746,66747,3052],{},"Create ",[567,66741,66742],{},"\u002Fvar\u002Flib\u002Fmatchbox\u002Fassets",[567,66744,66745],{},"\u002Fetc\u002Fmatchbox"," directory (",[567,66748,66749],{},"mkdir -p \u002Fvar\u002Flib\u002Fmatchbox\u002Fassets \u002Fetc\u002Fmatchbox",[638,66751,66752,66753,6378,66756,3052],{},"Git clone the Matchbox repository ",[567,66754,66755],{},"https:\u002F\u002Fgithub.com\u002Fcoreos\u002Fmatchbox.git",[567,66757,66758],{},"git clone https:\u002F\u002Fgithub.com\u002Fcoreos\u002Fmatchbox.git",[638,66760,66761],{},"Enter the cloned Matchbox repository.",[638,66763,66764,66765,66768,66769,66772],{},"Generate certificates with the ",[567,66766,66767],{},".\u002Fscripts\u002Ftls\u002Fcert-gen"," script from the Matchbox repository (enter the ",[567,66770,66771],{},"scripts\u002F"," directory before execution).",[638,66774,66775,66776,66768,66779,66781,66782],{},"Download Container Linux with the ",[567,66777,66778],{},".\u002Fscripts\u002Fget-coreos",[567,66780,66771],{}," directory before execution).\n",[668,66783,66784],{},[638,66785,66786,66787,8939,66790],{},"An example to download Container Linux stable version ",[567,66788,66789],{},"1465.7.0",[567,66791,66792],{},".\u002Fscripts\u002Fget-coreos stable 1465.7.0 \u002Fvar\u002Flib\u002Fmatchbox\u002Fassets",[638,66794,66795,66796,11295],{},"(When Docker is used to run Matchbox) Run matchbox, with the following ",[567,66797,4203],{},[523,66799,8764,66800,66802],{},[567,66801,4203],{}," command I used looked like this:",[738,66804,66806],{"className":1621,"code":66805,"language":1623,"meta":743,"style":743},"$ docker run \\\n    --net=host \\\n    -d \\\n    -v \u002Fvar\u002Flib\u002Fmatchbox:\u002Fvar\u002Flib\u002Fmatchbox:Z \\\n    -v \u002Fetc\u002Fmatchbox:\u002Fetc\u002Fmatchbox:Z,ro \\\n    quay.io\u002Fcoreos\u002Fmatchbox:latest \\\n    -address=0.0.0.0:8080 \\\n    -rpc-address=0.0.0.0:8081 \\\n    -log-level=debug\n",[567,66807,66808,66818,66825,66831,66840,66849,66856,66863,66870],{"__ignoreMap":743},[747,66809,66810,66812,66814,66816],{"class":749,"line":750},[747,66811,1919],{"class":1630},[747,66813,3246],{"class":802},[747,66815,3665],{"class":802},[747,66817,1641],{"class":1640},[747,66819,66820,66823],{"class":749,"line":761},[747,66821,66822],{"class":802},"    --net=host",[747,66824,1641],{"class":1640},[747,66826,66827,66829],{"class":749,"line":769},[747,66828,5866],{"class":802},[747,66830,1641],{"class":1640},[747,66832,66833,66835,66838],{"class":749,"line":776},[747,66834,6139],{"class":802},[747,66836,66837],{"class":802}," \u002Fvar\u002Flib\u002Fmatchbox:\u002Fvar\u002Flib\u002Fmatchbox:Z",[747,66839,1641],{"class":1640},[747,66841,66842,66844,66847],{"class":749,"line":784},[747,66843,6139],{"class":802},[747,66845,66846],{"class":802}," \u002Fetc\u002Fmatchbox:\u002Fetc\u002Fmatchbox:Z,ro",[747,66848,1641],{"class":1640},[747,66850,66851,66854],{"class":749,"line":790},[747,66852,66853],{"class":802},"    quay.io\u002Fcoreos\u002Fmatchbox:latest",[747,66855,1641],{"class":1640},[747,66857,66858,66861],{"class":749,"line":796},[747,66859,66860],{"class":802},"    -address=0.0.0.0:8080",[747,66862,1641],{"class":1640},[747,66864,66865,66868],{"class":749,"line":806},[747,66866,66867],{"class":802},"    -rpc-address=0.0.0.0:8081",[747,66869,1641],{"class":1640},[747,66871,66872],{"class":749,"line":814},[747,66873,66874],{"class":802},"    -log-level=debug\n",[535,66876,66878],{"id":66877},"step-2-reboot-the-servers-into-a-resuce-system","Step 2 - Reboot the servers into a Resuce system",[523,66880,66881],{},"The title says it all, reboot all the servers you want to run Container Linux on into a rescue\u002Frecovery system based on Linux.",[535,66883,66885],{"id":66884},"step-3-optional-clear-the-disks-yourself-to-prevent-bootloader-issues","Step 3 - (Optional) clear the disks yourself to prevent bootloader \"issues\"",[6072,66887,66888,66892],{},[523,66889,66890],{},[584,66891,6189],{},[523,66893,23726,66894,66897],{},[567,66895,66896],{},"\u002Fdev\u002Fsda"," with the disk in your server(s). This needs to be done in this and the next steps that work with the disk(s).",[523,66899,66900,66901,66904,66905,66907,66908,66911,66912,66915,66916,66919],{},"This is more of a \"brute force\" to clear the disks completely.\nFirst two commands disable and \"remove\" LVM devices. ",[567,66902,66903],{},"umount"," to unmount the disk's partitions and ",[567,66906,247],{}," to zero the disks (",[567,66909,66910],{},"\u002Fdev\u002Fsd{a,b}",") superblocks so no mdadm RAID is detected. The ",[567,66913,66914],{},"dd"," additionally clears the first 10M of the disk, this is more than just the partition table and MBR, but I personally like to simply erase a bit more just in case.. The end runs ",[567,66917,66918],{},"cgpt"," to \"repair\" the disks GPT tables, this fixed issues with Container Linux having trouble creating the partitions during the installation process for me.",[738,66921,66923],{"className":1621,"code":66922,"language":1623,"meta":743,"style":743},"lvscan 2>\u002Fdev\u002Fnull | awk '{print \"lvremove -f \"$2}' | sh\nvgremove 2>\u002Fdev\u002Fnull\nmdadm --stop --scan\numount \u002Fdev\u002Fsda[1-9] 2>\u002Fdev\u002Fnull\nmdadm --zero-superblock \u002Fdev\u002Fsda\ndd if=\u002Fdev\u002Fzero of=\u002Fdev\u002Fsda bs=10M count=10\ncgpt repair \u002Fdev\u002Fsda\n",[567,66924,66925,66951,66961,66971,66982,66992,67011],{"__ignoreMap":743},[747,66926,66927,66930,66933,66935,66937,66940,66942,66945,66947,66949],{"class":749,"line":750},[747,66928,66929],{"class":1630},"lvscan",[747,66931,66932],{"class":757}," 2>",[747,66934,60374],{"class":802},[747,66936,3170],{"class":757},[747,66938,66939],{"class":1630}," awk",[747,66941,3537],{"class":757},[747,66943,66944],{"class":802},"{print \"lvremove -f \"$2}",[747,66946,3543],{"class":757},[747,66948,3170],{"class":757},[747,66950,3173],{"class":1630},[747,66952,66953,66956,66958],{"class":749,"line":761},[747,66954,66955],{"class":1630},"vgremove",[747,66957,66932],{"class":757},[747,66959,66960],{"class":802},"\u002Fdev\u002Fnull\n",[747,66962,66963,66965,66968],{"class":749,"line":769},[747,66964,247],{"class":1630},[747,66966,66967],{"class":802}," --stop",[747,66969,66970],{"class":802}," --scan\n",[747,66972,66973,66975,66978,66980],{"class":749,"line":776},[747,66974,66903],{"class":1630},[747,66976,66977],{"class":802}," \u002Fdev\u002Fsda[1-9]",[747,66979,66932],{"class":757},[747,66981,66960],{"class":802},[747,66983,66984,66986,66989],{"class":749,"line":784},[747,66985,247],{"class":1630},[747,66987,66988],{"class":802}," --zero-superblock",[747,66990,66991],{"class":802}," \u002Fdev\u002Fsda\n",[747,66993,66994,66996,66999,67002,67005,67008],{"class":749,"line":790},[747,66995,66914],{"class":1630},[747,66997,66998],{"class":802}," if=\u002Fdev\u002Fzero",[747,67000,67001],{"class":802}," of=\u002Fdev\u002Fsda",[747,67003,67004],{"class":802}," bs=10M",[747,67006,67007],{"class":802}," count=",[747,67009,67010],{"class":1895},"10\n",[747,67012,67013,67015,67018],{"class":749,"line":796},[747,67014,66918],{"class":1630},[747,67016,67017],{"class":802}," repair",[747,67019,66991],{"class":802},[523,67021,67022,67023,67025],{},"If you are on a Debian based resuce\u002Frecovery system, you need to install ",[567,67024,66918],{}," you can do this by running:",[738,67027,67029],{"className":1621,"code":67028,"language":1623,"meta":743,"style":743},"apt-get update\napt-get install -y cgpt\n",[567,67030,67031,67039],{"__ignoreMap":743},[747,67032,67033,67036],{"class":749,"line":750},[747,67034,67035],{"class":1630},"apt-get",[747,67037,67038],{"class":802}," update\n",[747,67040,67041,67043,67045,67047],{"class":749,"line":761},[747,67042,67035],{"class":1630},[747,67044,35408],{"class":802},[747,67046,35411],{"class":802},[747,67048,67049],{"class":802}," cgpt\n",[535,67051,66717],{"id":67052},"step-4-add-grub-config-for-ipxe-boot",[523,67054,67055],{},"The following commands do the following:",[635,67057,67058],{},[638,67059,67060,67061,67063],{},"\"Zap\"\u002FClear the disk ",[567,67062,66896],{}," just in case again.",[738,67065,67067],{"className":1621,"code":67066,"language":1623,"meta":743,"style":743},"sgdisk --zap-all --clear \u002Fdev\u002Fsda >\u002Fdev\u002Fnull\n",[567,67068,67069],{"__ignoreMap":743},[747,67070,67071,67074,67077,67080,67083,67085],{"class":749,"line":750},[747,67072,67073],{"class":1630},"sgdisk",[747,67075,67076],{"class":802}," --zap-all",[747,67078,67079],{"class":802}," --clear",[747,67081,67082],{"class":802}," \u002Fdev\u002Fsda",[747,67084,35282],{"class":757},[747,67086,66960],{"class":802},[635,67088,67089],{"start":761},[638,67090,67091],{},"Create a BIOS boot partition (size ~4096M) on the disk.",[738,67093,67095],{"className":1621,"code":67094,"language":1623,"meta":743,"style":743},"sgdisk --new 1:2048:4095 -c 1:\"BIOS Boot Partition\" -t 1:ef02 \u002Fdev\u002Fsda >\u002Fdev\u002Fnull\n",[567,67096,67097],{"__ignoreMap":743},[747,67098,67099,67101,67104,67107,67110,67113,67115,67118,67120,67122,67125,67127,67129],{"class":749,"line":750},[747,67100,67073],{"class":1630},[747,67102,67103],{"class":802}," --new",[747,67105,67106],{"class":802}," 1:2048:4095",[747,67108,67109],{"class":802}," -c",[747,67111,67112],{"class":802}," 1:",[747,67114,3892],{"class":757},[747,67116,67117],{"class":802},"BIOS Boot Partition",[747,67119,3892],{"class":757},[747,67121,9736],{"class":802},[747,67123,67124],{"class":802}," 1:ef02",[747,67126,67082],{"class":802},[747,67128,35282],{"class":757},[747,67130,66960],{"class":802},[635,67132,67133],{"start":769},[638,67134,67135],{},"Create a partition for \"data\" which will be used for the grub configs.",[738,67137,67139],{"className":1621,"code":67138,"language":1623,"meta":743,"style":743},"sgdisk --new 2:4096:500M -c 2:\"Linux Boot Partition\" \u002Fdev\u002Fsda >\u002Fdev\u002Fnull\n",[567,67140,67141],{"__ignoreMap":743},[747,67142,67143,67145,67147,67150,67152,67155,67157,67160,67162,67164,67166],{"class":749,"line":750},[747,67144,67073],{"class":1630},[747,67146,67103],{"class":802},[747,67148,67149],{"class":802}," 2:4096:500M",[747,67151,67109],{"class":802},[747,67153,67154],{"class":802}," 2:",[747,67156,3892],{"class":757},[747,67158,67159],{"class":802},"Linux Boot Partition",[747,67161,3892],{"class":757},[747,67163,67082],{"class":802},[747,67165,35282],{"class":757},[747,67167,66960],{"class":802},[635,67169,67170],{"start":776},[638,67171,67172,67173,67176,67177,1909],{},"The next three commands, format the data partition with ",[567,67174,67175],{},"ext2",", create the mount target directory and mount the data partition to ",[567,67178,67179],{},"\u002Fboot",[738,67181,67183],{"className":1621,"code":67182,"language":1623,"meta":743,"style":743},"mkfs.ext2 -F -q \u002Fdev\u002Fsda2\nmkdir \u002Fboot\nmount -t ext2 \u002Fdev\u002Fsda2 \u002Fboot\n",[567,67184,67185,67198,67205],{"__ignoreMap":743},[747,67186,67187,67190,67192,67195],{"class":749,"line":750},[747,67188,67189],{"class":1630},"mkfs.ext2",[747,67191,37159],{"class":802},[747,67193,67194],{"class":802}," -q",[747,67196,67197],{"class":802}," \u002Fdev\u002Fsda2\n",[747,67199,67200,67202],{"class":749,"line":761},[747,67201,36923],{"class":1630},[747,67203,67204],{"class":802}," \u002Fboot\n",[747,67206,67207,67210,67212,67215,67218],{"class":749,"line":769},[747,67208,67209],{"class":1630},"mount",[747,67211,9736],{"class":802},[747,67213,67214],{"class":802}," ext2",[747,67216,67217],{"class":802}," \u002Fdev\u002Fsda2",[747,67219,67204],{"class":802},[523,67221,67222,67223,67226,67227,67230,67231,67234,67235,67238],{},"Next up is to add a ",[567,67224,67225],{},"menuentry"," for iPXE boot to a file named ",[567,67228,67229],{},"\u002Fboot\u002Fgrub2\u002Fgrub.cfg",". But first the folder structure needs to be created with a simple ",[567,67232,67233],{},"mkdir \u002Fboot\u002Fgrub2",".\nThe content in the code block needs to be put in the ",[567,67236,67237],{},"grub.cfg"," in the given path:",[738,67240,67244],{"className":67241,"code":67242,"language":67243,"meta":743,"style":743},"language-c shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","menuentry \"Network boot (iPXE)\" {\n    linux16 \u002Fipxe.lkrn\n    initrd16 \u002Fmatchbox.ipxe\n}\n","c",[567,67245,67246,67260,67275,67290],{"__ignoreMap":743},[747,67247,67248,67251,67253,67256,67258],{"class":749,"line":750},[747,67249,67250],{"class":1640},"menuentry ",[747,67252,3892],{"class":757},[747,67254,67255],{"class":802},"Network boot (iPXE)",[747,67257,3892],{"class":757},[747,67259,20574],{"class":757},[747,67261,67262,67265,67267,67270,67272],{"class":749,"line":761},[747,67263,67264],{"class":753},"    linux16 ",[747,67266,8026],{"class":757},[747,67268,67269],{"class":1640},"ipxe",[747,67271,1909],{"class":757},[747,67273,67274],{"class":1640},"lkrn\n",[747,67276,67277,67280,67282,67285,67287],{"class":749,"line":769},[747,67278,67279],{"class":753},"    initrd16 ",[747,67281,8026],{"class":757},[747,67283,67284],{"class":1640},"matchbox",[747,67286,1909],{"class":757},[747,67288,67289],{"class":1640},"ipxe\n",[747,67291,67292],{"class":749,"line":776},[747,67293,19374],{"class":757},[523,67295,67296,67297,67299,67300,7258],{},"After creating the ",[567,67298,67237],{}," we need to install grub to the disk.\nThis can be done via (for ",[567,67301,66896],{},[738,67303,67305],{"className":1621,"code":67304,"language":1623,"meta":743,"style":743},"grub-install --no-floppy \u002Fdev\u002Fsda\n",[567,67306,67307],{"__ignoreMap":743},[747,67308,67309,67312,67315],{"class":749,"line":750},[747,67310,67311],{"class":1630},"grub-install",[747,67313,67314],{"class":802}," --no-floppy",[747,67316,66991],{"class":802},[523,67318,67319,67320,8939,67322,67326,67327,32212],{},"Download ipxe.lkrn from boot.ipxe.org to ",[567,67321,67179],{},[527,67323,67324],{"href":67324,"rel":67325},"https:\u002F\u002Fboot.ipxe.org\u002Fipxe.lkrn",[531],". This can be done by curl or wget whatever you prefer.\nAn example with ",[567,67328,3151],{},[738,67330,67332],{"className":1621,"code":67331,"language":1623,"meta":743,"style":743},"curl -L https:\u002F\u002Fboot.ipxe.org\u002Fipxe.lkrn -o \u002Fboot\u002Fipxe.lkrn\n",[567,67333,67334],{"__ignoreMap":743},[747,67335,67336,67338,67340,67343,67345],{"class":749,"line":750},[747,67337,3151],{"class":1630},[747,67339,40190],{"class":802},[747,67341,67342],{"class":802}," https:\u002F\u002Fboot.ipxe.org\u002Fipxe.lkrn",[747,67344,2222],{"class":802},[747,67346,67347],{"class":802}," \u002Fboot\u002Fipxe.lkrn\n",[523,67349,67350,67351,10616,67354,67356],{},"Now that grub and the iPXE \"loader\" is installed, we just need to tell grub what to \"handover\" to the iPXE \"loader\".\nFor that we add a file named ",[567,67352,67353],{},"matchbox.ipxe",[567,67355,67179],{}," directory. The file content looks like this:",[523,67358,67359],{},"Even though the title says \"without DHCP server\", if you should \"only\" have the issue that you are not allowed to boot (custom) IPXE over your DHCP server, but are using DHCP for address configuration checkout the second snippet below.",[523,67361,67362],{},"For manual interface configuration in IPXE can be done like this:",[738,67364,67366],{"className":1621,"code":67365,"language":1623,"meta":743,"style":743},"#!ipxe\n\n# set IP of first interface\nset net0\u002Fip 192.168.0.100\n# set netmask of first interface\nset net0\u002Fnetmask 255.255.255.0\n# set gateway of first interface\nset net0\u002Fgateway 192.168.0.1\n# set dns to google ns a\nset dns 8.8.8.8\n\nchain http:\u002F\u002Fmatchbox.example.net:8080\u002Fboot.ipxe\n",[567,67367,67368,67373,67377,67382,67393,67398,67408,67413,67423,67428,67438,67442],{"__ignoreMap":743},[747,67369,67370],{"class":749,"line":750},[747,67371,67372],{"class":772},"#!ipxe\n",[747,67374,67375],{"class":749,"line":761},[747,67376,1255],{"emptyLinePlaceholder":1254},[747,67378,67379],{"class":749,"line":769},[747,67380,67381],{"class":772},"# set IP of first interface\n",[747,67383,67384,67387,67390],{"class":749,"line":776},[747,67385,67386],{"class":4574},"set",[747,67388,67389],{"class":802}," net0\u002Fip",[747,67391,67392],{"class":1895}," 192.168.0.100\n",[747,67394,67395],{"class":749,"line":784},[747,67396,67397],{"class":772},"# set netmask of first interface\n",[747,67399,67400,67402,67405],{"class":749,"line":790},[747,67401,67386],{"class":4574},[747,67403,67404],{"class":802}," net0\u002Fnetmask",[747,67406,67407],{"class":1895}," 255.255.255.0\n",[747,67409,67410],{"class":749,"line":796},[747,67411,67412],{"class":772},"# set gateway of first interface\n",[747,67414,67415,67417,67420],{"class":749,"line":806},[747,67416,67386],{"class":4574},[747,67418,67419],{"class":802}," net0\u002Fgateway",[747,67421,67422],{"class":1895}," 192.168.0.1\n",[747,67424,67425],{"class":749,"line":814},[747,67426,67427],{"class":772},"# set dns to google ns a\n",[747,67429,67430,67432,67435],{"class":749,"line":822},[747,67431,67386],{"class":4574},[747,67433,67434],{"class":802}," dns",[747,67436,67437],{"class":1895}," 8.8.8.8\n",[747,67439,67440],{"class":749,"line":830},[747,67441,1255],{"emptyLinePlaceholder":1254},[747,67443,67444,67447],{"class":749,"line":836},[747,67445,67446],{"class":1630},"chain",[747,67448,67449],{"class":802}," http:\u002F\u002Fmatchbox.example.net:8080\u002Fboot.ipxe\n",[523,67451,67452,67453,67455,67456,1909],{},"More info on IPXE ",[567,67454,67386],{}," command, can be found here: ",[527,67457,67460],{"href":67458,"rel":67459},"http:\u002F\u002Fipxe.org\u002Fcmd\u002Fset",[531],"iPXE - open source boot firmware [cmd:set]",[523,67462,67463],{},"If you use a DHCP server for address configuration, you can try using this snippet:\n(This is useful for public cloud providers which don't allow custom IPXE chains)",[738,67465,67467],{"className":1621,"code":67466,"language":1623,"meta":743,"style":743},"#!ipxe\n\ndhcp\n# set dns to google ns a\nset dns 8.8.8.8\n# enable the first network interface\nifopen net0\n# call the Matchbox server for the next iPXE steps\nchain http:\u002F\u002Fmatchbox.example.net:8080\u002Fboot.ipxe\n",[567,67468,67469,67473,67477,67482,67486,67494,67499,67507,67512],{"__ignoreMap":743},[747,67470,67471],{"class":749,"line":750},[747,67472,67372],{"class":772},[747,67474,67475],{"class":749,"line":761},[747,67476,1255],{"emptyLinePlaceholder":1254},[747,67478,67479],{"class":749,"line":769},[747,67480,67481],{"class":1630},"dhcp\n",[747,67483,67484],{"class":749,"line":776},[747,67485,67427],{"class":772},[747,67487,67488,67490,67492],{"class":749,"line":784},[747,67489,67386],{"class":4574},[747,67491,67434],{"class":802},[747,67493,67437],{"class":1895},[747,67495,67496],{"class":749,"line":790},[747,67497,67498],{"class":772},"# enable the first network interface\n",[747,67500,67501,67504],{"class":749,"line":796},[747,67502,67503],{"class":1630},"ifopen",[747,67505,67506],{"class":802}," net0\n",[747,67508,67509],{"class":749,"line":806},[747,67510,67511],{"class":772},"# call the Matchbox server for the next iPXE steps\n",[747,67513,67514,67516],{"class":749,"line":814},[747,67515,67446],{"class":1630},[747,67517,67449],{"class":802},[523,67519,23726,67520,67523],{},[567,67521,67522],{},"matchbox.example.net:8080"," with your Matchbox server address\u002FIP.",[6072,67525,67526,67530],{},[523,67527,67528],{},[584,67529,6189],{},[523,67531,67532,67533,1909],{},"Don't reboot the servres yet! Wait with the rebooting until we have configured a Matchbox profile in ",[527,67534,67536],{"href":67535},"#Step-5-Create-a-profile-and-group-for-Container-Linux-for-the-Deployment","Step 5 - Create a profile and group for Container Linux for the Deployment",[535,67538,67536],{"id":67539},"step-5-create-a-profile-and-group-for-container-linux-for-the-deployment",[523,67541,67542,67543,67548,67549,1909],{},"For this please take a look at the examples provided in the Matchobx repository, which can be seen here: ",[527,67544,67547],{"href":67545,"rel":67546},"https:\u002F\u002Fgithub.com\u002Fcoreos\u002Fmatchbox\u002Ftree\u002Fmaster\u002Fexamples",[531],"GitHub CoreOS Matchbox - Examples Folder",".\nIf you need help by that the full documentation, can be found here: ",[527,67550,67553],{"href":67551,"rel":67552},"https:\u002F\u002Fcoreos.com\u002Fmatchbox\u002Fdocs\u002Flatest",[531],"Matchbox latest documentation",[523,67555,67556,67557,67561],{},"Don't forget to add your own SSH key to the profile or else ",[527,67558,67560],{"href":67559},"#Step-7-Connect-to-a-server-by-SSH","Step 7 - Connect to a server by SSH"," won't work for you.",[523,67563,67564],{},"An basic example profile for running Container Linux on all servers:",[738,67566,67568],{"className":59635,"code":67567,"language":59637,"meta":743,"style":743},"{\n    \"id\": \"coreos\",\n    \"name\": \"Simple CoreOS Container Linux catch-all profile\",\n    \"ignition_id\": \"coreos-install.yaml.tmpl\",\n    \"boot\": {\n        \"kernel\": \"\u002Fassets\u002Fcoreos\u002F1465.7.0\u002Fcoreos_production_pxe.vmlinuz\",\n        \"initrd\": [\n            \"\u002Fassets\u002Fcoreos\u002F1465.7.0\u002Fcoreos_production_pxe_image.cpio.gz\"\n        ],\n        \"args\": [\n            \"coreos.config.url=http:\u002F\u002Fmatchbox.example.net:8080\u002Fignition?uuid=${uuid}\\u0026mac=${mac:hexhyp}\",\n            \"coreos.first_boot=yes\",\n            \"console=tty0\",\n            \"console=ttyS0\"\n        ]\n    }\n}\n",[567,67569,67570,67574,67593,67612,67632,67645,67664,67677,67686,67691,67704,67721,67732,67743,67752,67757,67761],{"__ignoreMap":743},[747,67571,67572],{"class":749,"line":750},[747,67573,13004],{"class":757},[747,67575,67576,67578,67580,67582,67584,67586,67589,67591],{"class":749,"line":761},[747,67577,20579],{"class":757},[747,67579,36621],{"class":19865},[747,67581,3892],{"class":757},[747,67583,856],{"class":757},[747,67585,969],{"class":757},[747,67587,67588],{"class":802},"coreos",[747,67590,3892],{"class":757},[747,67592,20595],{"class":757},[747,67594,67595,67597,67599,67601,67603,67605,67608,67610],{"class":749,"line":769},[747,67596,20579],{"class":757},[747,67598,5472],{"class":19865},[747,67600,3892],{"class":757},[747,67602,856],{"class":757},[747,67604,969],{"class":757},[747,67606,67607],{"class":802},"Simple CoreOS Container Linux catch-all profile",[747,67609,3892],{"class":757},[747,67611,20595],{"class":757},[747,67613,67614,67616,67619,67621,67623,67625,67628,67630],{"class":749,"line":776},[747,67615,20579],{"class":757},[747,67617,67618],{"class":19865},"ignition_id",[747,67620,3892],{"class":757},[747,67622,856],{"class":757},[747,67624,969],{"class":757},[747,67626,67627],{"class":802},"coreos-install.yaml.tmpl",[747,67629,3892],{"class":757},[747,67631,20595],{"class":757},[747,67633,67634,67636,67639,67641,67643],{"class":749,"line":784},[747,67635,20579],{"class":757},[747,67637,67638],{"class":19865},"boot",[747,67640,3892],{"class":757},[747,67642,856],{"class":757},[747,67644,20574],{"class":757},[747,67646,67647,67649,67651,67653,67655,67657,67660,67662],{"class":749,"line":790},[747,67648,20632],{"class":757},[747,67650,50117],{"class":1630},[747,67652,3892],{"class":757},[747,67654,856],{"class":757},[747,67656,969],{"class":757},[747,67658,67659],{"class":802},"\u002Fassets\u002Fcoreos\u002F1465.7.0\u002Fcoreos_production_pxe.vmlinuz",[747,67661,3892],{"class":757},[747,67663,20595],{"class":757},[747,67665,67666,67668,67671,67673,67675],{"class":749,"line":796},[747,67667,20632],{"class":757},[747,67669,67670],{"class":1630},"initrd",[747,67672,3892],{"class":757},[747,67674,856],{"class":757},[747,67676,20689],{"class":757},[747,67678,67679,67681,67684],{"class":749,"line":806},[747,67680,20646],{"class":757},[747,67682,67683],{"class":802},"\u002Fassets\u002Fcoreos\u002F1465.7.0\u002Fcoreos_production_pxe_image.cpio.gz",[747,67685,975],{"class":757},[747,67687,67688],{"class":749,"line":814},[747,67689,67690],{"class":757},"        ],\n",[747,67692,67693,67695,67698,67700,67702],{"class":749,"line":822},[747,67694,20632],{"class":757},[747,67696,67697],{"class":1630},"args",[747,67699,3892],{"class":757},[747,67701,856],{"class":757},[747,67703,20689],{"class":757},[747,67705,67706,67708,67711,67714,67717,67719],{"class":749,"line":830},[747,67707,20646],{"class":757},[747,67709,67710],{"class":802},"coreos.config.url=http:\u002F\u002Fmatchbox.example.net:8080\u002Fignition?uuid=${uuid}",[747,67712,67713],{"class":1640},"\\u0026",[747,67715,67716],{"class":802},"mac=${mac:hexhyp}",[747,67718,3892],{"class":757},[747,67720,20595],{"class":757},[747,67722,67723,67725,67728,67730],{"class":749,"line":836},[747,67724,20646],{"class":757},[747,67726,67727],{"class":802},"coreos.first_boot=yes",[747,67729,3892],{"class":757},[747,67731,20595],{"class":757},[747,67733,67734,67736,67739,67741],{"class":749,"line":842},[747,67735,20646],{"class":757},[747,67737,67738],{"class":802},"console=tty0",[747,67740,3892],{"class":757},[747,67742,20595],{"class":757},[747,67744,67745,67747,67750],{"class":749,"line":850},[747,67746,20646],{"class":757},[747,67748,67749],{"class":802},"console=ttyS0",[747,67751,975],{"class":757},[747,67753,67754],{"class":749,"line":863},[747,67755,67756],{"class":757},"        ]\n",[747,67758,67759],{"class":749,"line":869},[747,67760,21297],{"class":757},[747,67762,67763],{"class":749,"line":877},[747,67764,19374],{"class":757},[523,67766,67767,67768,3052],{},"(This is an slightly altered example taken from here: ",[527,67769,67772],{"href":67770,"rel":67771},"https:\u002F\u002Fgithub.com\u002Fcoreos\u002Fmatchbox\u002Fblob\u002Fmaster\u002Fexamples\u002Fprofiles\u002Fsimple\u002Fdefault.json",[531],"GitHub coreos\u002Fmatchbox: examples\u002Fprofiles\u002Fsimple\u002Fdefault.json",[523,67774,23726,67775,67777,67778,67523],{},[567,67776,66789],{}," with the chosen Container Linux version and also as earlier replace ",[567,67779,67522],{},[523,67781,67782],{},"A catch-all\u002Fwildcard group looks like this:",[738,67784,67786],{"className":59635,"code":67785,"language":59637,"meta":743,"style":743},"{\n    \"id\": \"coreos-catch-all\",\n    \"profile\": \"coreos\",\n    \"metadata\": {\n        \"ssh_authorized_key\": \"ssh-rsa [...]\"\n    }\n}\n",[567,67787,67788,67792,67811,67830,67842,67860,67864],{"__ignoreMap":743},[747,67789,67790],{"class":749,"line":750},[747,67791,13004],{"class":757},[747,67793,67794,67796,67798,67800,67802,67804,67807,67809],{"class":749,"line":761},[747,67795,20579],{"class":757},[747,67797,36621],{"class":19865},[747,67799,3892],{"class":757},[747,67801,856],{"class":757},[747,67803,969],{"class":757},[747,67805,67806],{"class":802},"coreos-catch-all",[747,67808,3892],{"class":757},[747,67810,20595],{"class":757},[747,67812,67813,67815,67818,67820,67822,67824,67826,67828],{"class":749,"line":769},[747,67814,20579],{"class":757},[747,67816,67817],{"class":19865},"profile",[747,67819,3892],{"class":757},[747,67821,856],{"class":757},[747,67823,969],{"class":757},[747,67825,67588],{"class":802},[747,67827,3892],{"class":757},[747,67829,20595],{"class":757},[747,67831,67832,67834,67836,67838,67840],{"class":749,"line":776},[747,67833,20579],{"class":757},[747,67835,12973],{"class":19865},[747,67837,3892],{"class":757},[747,67839,856],{"class":757},[747,67841,20574],{"class":757},[747,67843,67844,67846,67849,67851,67853,67855,67858],{"class":749,"line":784},[747,67845,20632],{"class":757},[747,67847,67848],{"class":1630},"ssh_authorized_key",[747,67850,3892],{"class":757},[747,67852,856],{"class":757},[747,67854,969],{"class":757},[747,67856,67857],{"class":802},"ssh-rsa [...]",[747,67859,975],{"class":757},[747,67861,67862],{"class":749,"line":790},[747,67863,21297],{"class":757},[747,67865,67866],{"class":749,"line":796},[747,67867,19374],{"class":757},[523,67869,67767,67870,3052],{},[527,67871,67874],{"href":67872,"rel":67873},"https:\u002F\u002Fgithub.com\u002Fcoreos\u002Fmatchbox\u002Fblob\u002Fmaster\u002Fexamples\u002Fgroups\u002Fsimple\u002Fdefault.json",[531],"GitHub coreos\u002Fmatchbox: examples\u002Fgroups\u002Fsimple\u002Fdefault.json",[523,67876,67877,67878,67881,67882,58746],{},"The profiles go into the ",[567,67879,67880],{},"\u002Fvar\u002Flib\u002Fmatchbox\u002Fprofiles"," and the groups into ",[567,67883,67884],{},"\u002Fvar\u002Flib\u002Fmatchbox\u002Fgroups",[535,67886,67888],{"id":67887},"step-6-reboot-the-servers","Step 6 - Reboot the servers",[523,67890,67891,67892],{},"As the title suggests reboot your servers.\nWhen you now have rebooted your servers, you should see some activity in the Matchbox server (\"access\") log.\nTo view the logs of Matchbox when running in Docker with the command in ",[527,67893,66722],{"href":67894},"#Step-1-Setup-matchbox",[738,67896,67898],{"className":1621,"code":67897,"language":1623,"meta":743,"style":743},"[...]\ntime=\"2017-09-09T14:43:26Z\" level=debug msg=\"Matched an Ignition or Container Linux Config template\" group=coreos-install-container-linux-node01 labels=map[mac:XX-XX-XX-XX-XX-XX uuid:[...]] profile=coreos-install\ntime=\"2017-09-09T14:43:30Z\" level=info msg=\"HTTP GET \u002Fignition?uuid=[...]&mac=XX-XX-XX-XX-XX-XX\"\n[...]\n",[567,67899,67900,67908,67962,67993],{"__ignoreMap":743},[747,67901,67902,67904,67906],{"class":749,"line":750},[747,67903,4253],{"class":757},[747,67905,5685],{"class":1640},[747,67907,4268],{"class":757},[747,67909,67910,67913,67915,67917,67920,67922,67925,67927,67929,67932,67934,67936,67939,67941,67943,67945,67948,67951,67953,67956,67959],{"class":749,"line":761},[747,67911,67912],{"class":1640},"time",[747,67914,6425],{"class":757},[747,67916,3892],{"class":757},[747,67918,67919],{"class":802},"2017-09-09T14:43:26Z",[747,67921,3892],{"class":757},[747,67923,67924],{"class":1640}," level",[747,67926,6425],{"class":757},[747,67928,20872],{"class":802},[747,67930,67931],{"class":1640}," msg",[747,67933,6425],{"class":757},[747,67935,3892],{"class":757},[747,67937,67938],{"class":802},"Matched an Ignition or Container Linux Config template",[747,67940,3892],{"class":757},[747,67942,7581],{"class":1640},[747,67944,6425],{"class":757},[747,67946,67947],{"class":802},"coreos-install-container-linux-node01",[747,67949,67950],{"class":1640}," labels",[747,67952,6425],{"class":757},[747,67954,67955],{"class":802},"map[mac:XX-XX-XX-XX-XX-XX",[747,67957,67958],{"class":1630}," uuid:[...]]",[747,67960,67961],{"class":802}," profile=coreos-install\n",[747,67963,67964,67966,67968,67970,67973,67975,67977,67979,67982,67984,67986,67988,67991],{"class":749,"line":769},[747,67965,67912],{"class":1640},[747,67967,6425],{"class":757},[747,67969,3892],{"class":757},[747,67971,67972],{"class":802},"2017-09-09T14:43:30Z",[747,67974,3892],{"class":757},[747,67976,67924],{"class":1640},[747,67978,6425],{"class":757},[747,67980,67981],{"class":802},"info",[747,67983,67931],{"class":1640},[747,67985,6425],{"class":757},[747,67987,3892],{"class":757},[747,67989,67990],{"class":802},"HTTP GET \u002Fignition?uuid=[...]&mac=XX-XX-XX-XX-XX-XX",[747,67992,975],{"class":757},[747,67994,67995,67997,67999],{"class":749,"line":776},[747,67996,4253],{"class":757},[747,67998,5685],{"class":1640},[747,68000,4268],{"class":757},[523,68002,68003,68004,68007],{},"(Where ",[567,68005,68006],{},"coreos-install"," is the name of the profile you created)",[535,68009,67560],{"id":68010},"step-7-connect-to-a-server-by-ssh",[523,68012,68013,68014,68016],{},"Again just what the title says. Just connect to one of your servers with username ",[567,68015,50247],{}," over SSH (port 22).",[535,68018,14526],{"id":14525},[523,68020,68021],{},"For questions about the post, please leave a comment below or send me an email, thanks!",[523,68023,13967],{},[2890,68025,68026],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":743,"searchDepth":761,"depth":761,"links":68028},[68029,68032,68033,68034,68035,68036,68037,68038,68039],{"id":537,"depth":761,"text":538,"children":68030},[68031],{"id":66698,"depth":769,"text":66699},{"id":66721,"depth":761,"text":66722},{"id":66877,"depth":761,"text":66878},{"id":66884,"depth":761,"text":66885},{"id":67052,"depth":761,"text":66717},{"id":67539,"depth":761,"text":67536},{"id":67887,"depth":761,"text":67888},{"id":68010,"depth":761,"text":67560},{"id":14525,"depth":761,"text":14526},"2017-08-31T19:41:04+02:00","This is more of a quick writeup in form of a note on how to deploy Container Linux on bare-metal without DHCP server.",{"src":68043},"\u002Fblog\u002Fcovers\u002Fcontainer_linux_logo.png",{"tags":68045},[26415,58416,68046],"Bare Metal","\u002Fblog\u002F2017\u002Fcontainer-linux-deploy-on-bare-metal-without-dhcp-server",{"title":66685,"description":68041},"3.blog\u002F2017\u002Fcontainer-linux-deploy-on-bare-metal-without-dhcp-server","xT53J6OB8Qn7jItx0HJnmAvKjHbcXmrNk6SXgve9oDc",{"id":68052,"title":68053,"authors":68054,"badge":518,"body":68057,"date":70485,"description":70486,"extension":2911,"image":70487,"meta":70489,"navigation":1254,"path":70491,"seo":70492,"stem":70493,"__hash__":70494},"posts\u002F3.blog\u002F2017\u002Fgitlab-kubernetes-running-ci-runners-in-kubernetes.md","GitLab + Kubernetes: Running CI Runners in Kubernetes",[68055],{"name":514,"to":515,"avatar":68056},{"src":517},{"type":520,"value":68058,"toc":70463},[68059,68061,68066,68073,68075,68098,68100,68105,68107,68109,68191,68198,68202,68205,68212,68219,68226,68233,68240,68244,68247,68251,68266,68270,68276,68312,68316,68341,68727,68733,68782,69097,69113,69131,69273,69277,69283,69286,69306,69311,69317,69391,69395,69415,69426,69970,70000,70004,70033,70036,70044,70050,70293,70312,70316,70325,70339,70353,70358,70362,70374,70377,70383,70390,70392,70396,70399,70438,70447,70449,70458,70460],[535,68060,538],{"id":537},[523,68062,68063,68064,1909],{},"In this post, I'll be going over using GitLab CI to create your application's container Continuous Delivery to Kubernetes.\nThis is the second post in the three post series about Kubernetes and GitLab. The first post can be found here: ",[527,68065,64854],{"href":22254},[6072,68067,68068],{},[523,68069,68070,68072],{},[584,68071,6189],{}," Please check the requirements before beginning.",[613,68074,22268],{"id":22267},[668,68076,68077,68080,68083,68087],{},[638,68078,68079],{},"Kubernetes cluster",[638,68081,68082],{},"Running GitLab instance",[638,68084,68085,64957],{},[567,68086,15269],{},[638,68088,64939,68089],{},[668,68090,68091],{},[638,68092,68093,64946,68095,2006],{},[567,68094,32376],{},[527,68096,465],{"href":32338,"rel":68097},[531],[613,68099,64976],{"id":64975},[523,68101,64979,68102,64985],{},[527,68103,64984],{"href":64982,"rel":68104},[531],[535,68106,64989],{"id":64988},[523,68108,64992],{},[738,68110,68111],{"className":1621,"code":64995,"language":1623,"meta":743,"style":743},[567,68112,68113,68121,68127,68141,68153,68161,68187],{"__ignoreMap":743},[747,68114,68115,68117,68119],{"class":749,"line":750},[747,68116,1919],{"class":1630},[747,68118,1922],{"class":802},[747,68120,65006],{"class":802},[747,68122,68123,68125],{"class":749,"line":761},[747,68124,15269],{"class":1630},[747,68126,65006],{"class":802},[747,68128,68129,68131,68133,68135,68137,68139],{"class":749,"line":769},[747,68130,124],{"class":1630},[747,68132,7834],{"class":802},[747,68134,5068],{"class":802},[747,68136,36742],{"class":802},[747,68138,35623],{"class":802},[747,68140,65027],{"class":802},[747,68142,68143,68145,68147,68149,68151],{"class":749,"line":776},[747,68144,65032],{"class":1630},[747,68146,5068],{"class":802},[747,68148,36742],{"class":802},[747,68150,35623],{"class":802},[747,68152,65041],{"class":802},[747,68154,68155,68157,68159],{"class":749,"line":784},[747,68156,4253],{"class":757},[747,68158,5685],{"class":1640},[747,68160,4268],{"class":757},[747,68162,68163,68165,68167,68169,68171,68173,68175,68177,68179,68181,68183,68185],{"class":749,"line":790},[747,68164,3821],{"class":1630},[747,68166,65056],{"class":802},[747,68168,65059],{"class":802},[747,68170,4099],{"class":802},[747,68172,65064],{"class":802},[747,68174,53621],{"class":802},[747,68176,65069],{"class":802},[747,68178,4556],{"class":802},[747,68180,3537],{"class":757},[747,68182,65076],{"class":802},[747,68184,3543],{"class":757},[747,68186,9661],{"class":802},[747,68188,68189],{"class":749,"line":796},[747,68190,65085],{"class":1630},[523,68192,8764,68193,65090,68195,68197],{},[567,68194,15269],{},[567,68196,36474],{}," shows you if you can connect to the cluster and list the available cluster services (in the ouput: Kubernetes apiserver and KubeDNS service).",[535,68199,68201],{"id":68200},"step-2-get-gitlab-ci-register-token-from-gitlab","Step 2 - Get GitLab CI Register Token from GitLab",[523,68203,68204],{},"Go to your GitLab instance and go to the Admin area.",[523,68206,68207,68208],{},"To go to your Admin area, click the wrench icon next to the search bar in the top right of any GitLab page:\n",[3069,68209],{"alt":68210,"src":68211},"GitLab Admin area icon position","\u002Fblog\u002F2017\u002Fgitlab-kubernetes-running-ci-runners-in-kubernetes\u002Fgitlab-admin-area-icon-position.png",[523,68213,68214,68215],{},"Next click on the Runners tab in the navbar.\n",[3069,68216],{"alt":68217,"src":68218},"GitLab Admin area Runners tab","\u002Fblog\u002F2017\u002Fgitlab-kubernetes-running-ci-runners-in-kubernetes\u002Fgitlab-admin-area-navbar.png",[523,68220,68221,68222],{},"Et-voilà! There is your token (in the picture the token would be where the blanked out area is).\n",[3069,68223],{"alt":68224,"src":68225},"GitLab Admin area Runners Token","\u002Fblog\u002F2017\u002Fgitlab-kubernetes-running-ci-runners-in-kubernetes\u002Fgitlab-admin-area-token.png",[523,68227,68228,68229,1909],{},"Now copy the token somewhere safe for usage in ",[527,68230,68232],{"href":68231},"#Step-3-Write-manifest-for-GitLab-CI-Runners","Step 3 - Write manifest for GitLab CI Runners",[6072,68234,68235],{},[523,68236,68237,68239],{},[584,68238,6189],{}," Keep the token securely stored!",[535,68241,68243],{"id":68242},"step-3-write-kubernetes-manifests-for-gitlab-ci-runners","Step 3 - Write Kubernetes manifests for GitLab CI Runners",[523,68245,68246],{},"This step will show you the manifests for the GitLab CI runner manifests for Kubernetes.",[613,68248,68250],{"id":68249},"kubernetes-api-references","Kubernetes API References",[523,68252,68253,68254,68258,68259,68262,68263,1909],{},"The Kubernetes API references can be found on the official ",[527,68255,68257],{"href":18184,"rel":68256},[531],"Kubernetes.io"," page here: ",[527,68260,30013],{"href":30013,"rel":68261},[531],"\nAll manifests should be compatible with Kubernetes ",[567,68264,68265],{},"1.7",[613,68267,68269],{"id":68268},"namespace-for-the-build-tasks","Namespace for the build tasks",[523,68271,23726,68272,68275],{},[567,68273,68274],{},"YOUR_GITLAB_BUILD_NAMESPACE"," with a name for the namespace in which the GitLab CI builds are run. The separate namespace for the GitLab CI builds is useful for detecting stuck containers (for example when there was an issue with the runner not cleaning up).",[738,68277,68279],{"className":740,"code":68278,"language":742,"meta":743,"style":743},"apiVersion: v1\nkind: Namespace\nmetadata:\n  name: YOUR_GITLAB_BUILD_NAMESPACE\n",[567,68280,68281,68289,68297,68303],{"__ignoreMap":743},[747,68282,68283,68285,68287],{"class":749,"line":750},[747,68284,12949],{"class":753},[747,68286,856],{"class":757},[747,68288,22608],{"class":802},[747,68290,68291,68293,68295],{"class":749,"line":761},[747,68292,12963],{"class":753},[747,68294,856],{"class":757},[747,68296,36317],{"class":802},[747,68298,68299,68301],{"class":749,"line":769},[747,68300,12973],{"class":753},[747,68302,758],{"class":757},[747,68304,68305,68307,68309],{"class":749,"line":776},[747,68306,12980],{"class":753},[747,68308,856],{"class":757},[747,68310,68311],{"class":802}," YOUR_GITLAB_BUILD_NAMESPACE\n",[613,68313,68315],{"id":68314},"configmap-for-the-environment-variables-and-script","ConfigMap for the Environment Variables and Script",[523,68317,68318,68319,68321,68322,68325,68326,68329,68330,68333,68334,68336,68337,68340],{},"First we gonna start with the ",[567,68320,30063],{}," for the basic configuration using environment variables of the GitLab CI Runner image:\nYou have to point ",[567,68323,68324],{},"YOUR_GITLAB_CI_SERVER_URL"," to your GitLab instance's URL with ",[567,68327,68328],{},"\u002Fci"," appended to it (like this ",[567,68331,68332],{},"https:\u002F\u002Fgitlab.example.com\u002Fci",").\nAlso you need to replace ",[567,68335,68274],{}," with the name of the namespace from the step ",[527,68338,68269],{"href":68339},"#Namespace-for-the-build-tasks"," in every manifest coming up.",[738,68342,68344],{"className":740,"code":68343,"language":742,"meta":743,"style":743},"apiVersion: v1\ndata:\n  REGISTER_NON_INTERACTIVE: \"true\"\n  REGISTER_LOCKED: \"false\"\n  CI_SERVER_URL: \"YOUR_GITLAB_CI_SERVER_URL\"\n  METRICS_SERVER: \"0.0.0.0:9100\"\n  RUNNER_REQUEST_CONCURRENCY: \"4\"\n  RUNNER_EXECUTOR: \"kubernetes\"\n  KUBERNETES_NAMESPACE: \"YOUR_GITLAB_BUILD_NAMESPACE\"\n  KUBERNETES_PRIVILEGED: \"true\"\n  KUBERNETES_CPU_REQUEST: \"250m\"\n  KUBERNETES_MEMORY_REQUEST: \"256Mi\"\n  KUBERNETES_CPU_LIMIT: \"1\"\n  KUBERNETES_MEMORY_LIMIT: \"1Gi\"\n  KUBERNETES_SERVICE_CPU_REQUEST: \"150m\"\n  KUBERNETES_SERVICE_MEMORY_REQUEST: \"256Mi\"\n  KUBERNETES_SERVICE_CPU_LIMIT: \"1\"\n  KUBERNETES_SERVICE_MEMORY_LIMIT: \"1Gi\"\n  KUBERNETES_HELPER_CPU_REQUEST: \"150m\"\n  KUBERNETES_HELPER_MEMORY_REQUEST: \"100Mi\"\n  KUBERNETES_HELPER_CPU_LIMIT: \"500m\"\n  KUBERNETES_HELPER_MEMORY_LIMIT: \"200Mi\"\n  KUBERNETES_PULL_POLICY: \"if-not-present\"\n  KUBERNETES_TERMINATIONGRACEPERIODSECONDS: \"10\"\n  KUBERNETES_POLL_INTERVAL: \"5\"\n  KUBERNETES_POLL_TIMEOUT: \"360\"\nkind: ConfigMap\nmetadata:\n  labels:\n    app: gitlab-ci-runner\n  name: gitlab-ci-runner-cm\n  namespace: YOUR_GITLAB_BUILD_NAMESPACE\n",[567,68345,68346,68354,68360,68373,68386,68399,68413,68427,68440,68453,68466,68480,68494,68507,68520,68534,68547,68560,68573,68586,68600,68613,68627,68641,68654,68667,68681,68689,68695,68701,68710,68719],{"__ignoreMap":743},[747,68347,68348,68350,68352],{"class":749,"line":750},[747,68349,12949],{"class":753},[747,68351,856],{"class":757},[747,68353,22608],{"class":802},[747,68355,68356,68358],{"class":749,"line":761},[747,68357,30860],{"class":753},[747,68359,758],{"class":757},[747,68361,68362,68365,68367,68369,68371],{"class":749,"line":769},[747,68363,68364],{"class":753},"  REGISTER_NON_INTERACTIVE",[747,68366,856],{"class":757},[747,68368,969],{"class":757},[747,68370,5306],{"class":802},[747,68372,975],{"class":757},[747,68374,68375,68378,68380,68382,68384],{"class":749,"line":776},[747,68376,68377],{"class":753},"  REGISTER_LOCKED",[747,68379,856],{"class":757},[747,68381,969],{"class":757},[747,68383,62546],{"class":802},[747,68385,975],{"class":757},[747,68387,68388,68391,68393,68395,68397],{"class":749,"line":784},[747,68389,68390],{"class":753},"  CI_SERVER_URL",[747,68392,856],{"class":757},[747,68394,969],{"class":757},[747,68396,68324],{"class":802},[747,68398,975],{"class":757},[747,68400,68401,68404,68406,68408,68411],{"class":749,"line":790},[747,68402,68403],{"class":753},"  METRICS_SERVER",[747,68405,856],{"class":757},[747,68407,969],{"class":757},[747,68409,68410],{"class":802},"0.0.0.0:9100",[747,68412,975],{"class":757},[747,68414,68415,68418,68420,68422,68425],{"class":749,"line":796},[747,68416,68417],{"class":753},"  RUNNER_REQUEST_CONCURRENCY",[747,68419,856],{"class":757},[747,68421,969],{"class":757},[747,68423,68424],{"class":802},"4",[747,68426,975],{"class":757},[747,68428,68429,68432,68434,68436,68438],{"class":749,"line":806},[747,68430,68431],{"class":753},"  RUNNER_EXECUTOR",[747,68433,856],{"class":757},[747,68435,969],{"class":757},[747,68437,1317],{"class":802},[747,68439,975],{"class":757},[747,68441,68442,68445,68447,68449,68451],{"class":749,"line":814},[747,68443,68444],{"class":753},"  KUBERNETES_NAMESPACE",[747,68446,856],{"class":757},[747,68448,969],{"class":757},[747,68450,68274],{"class":802},[747,68452,975],{"class":757},[747,68454,68455,68458,68460,68462,68464],{"class":749,"line":822},[747,68456,68457],{"class":753},"  KUBERNETES_PRIVILEGED",[747,68459,856],{"class":757},[747,68461,969],{"class":757},[747,68463,5306],{"class":802},[747,68465,975],{"class":757},[747,68467,68468,68471,68473,68475,68478],{"class":749,"line":830},[747,68469,68470],{"class":753},"  KUBERNETES_CPU_REQUEST",[747,68472,856],{"class":757},[747,68474,969],{"class":757},[747,68476,68477],{"class":802},"250m",[747,68479,975],{"class":757},[747,68481,68482,68485,68487,68489,68492],{"class":749,"line":836},[747,68483,68484],{"class":753},"  KUBERNETES_MEMORY_REQUEST",[747,68486,856],{"class":757},[747,68488,969],{"class":757},[747,68490,68491],{"class":802},"256Mi",[747,68493,975],{"class":757},[747,68495,68496,68499,68501,68503,68505],{"class":749,"line":842},[747,68497,68498],{"class":753},"  KUBERNETES_CPU_LIMIT",[747,68500,856],{"class":757},[747,68502,969],{"class":757},[747,68504,13727],{"class":802},[747,68506,975],{"class":757},[747,68508,68509,68512,68514,68516,68518],{"class":749,"line":850},[747,68510,68511],{"class":753},"  KUBERNETES_MEMORY_LIMIT",[747,68513,856],{"class":757},[747,68515,969],{"class":757},[747,68517,66275],{"class":802},[747,68519,975],{"class":757},[747,68521,68522,68525,68527,68529,68532],{"class":749,"line":863},[747,68523,68524],{"class":753},"  KUBERNETES_SERVICE_CPU_REQUEST",[747,68526,856],{"class":757},[747,68528,969],{"class":757},[747,68530,68531],{"class":802},"150m",[747,68533,975],{"class":757},[747,68535,68536,68539,68541,68543,68545],{"class":749,"line":869},[747,68537,68538],{"class":753},"  KUBERNETES_SERVICE_MEMORY_REQUEST",[747,68540,856],{"class":757},[747,68542,969],{"class":757},[747,68544,68491],{"class":802},[747,68546,975],{"class":757},[747,68548,68549,68552,68554,68556,68558],{"class":749,"line":877},[747,68550,68551],{"class":753},"  KUBERNETES_SERVICE_CPU_LIMIT",[747,68553,856],{"class":757},[747,68555,969],{"class":757},[747,68557,13727],{"class":802},[747,68559,975],{"class":757},[747,68561,68562,68565,68567,68569,68571],{"class":749,"line":1015},[747,68563,68564],{"class":753},"  KUBERNETES_SERVICE_MEMORY_LIMIT",[747,68566,856],{"class":757},[747,68568,969],{"class":757},[747,68570,66275],{"class":802},[747,68572,975],{"class":757},[747,68574,68575,68578,68580,68582,68584],{"class":749,"line":1021},[747,68576,68577],{"class":753},"  KUBERNETES_HELPER_CPU_REQUEST",[747,68579,856],{"class":757},[747,68581,969],{"class":757},[747,68583,68531],{"class":802},[747,68585,975],{"class":757},[747,68587,68588,68591,68593,68595,68598],{"class":749,"line":1027},[747,68589,68590],{"class":753},"  KUBERNETES_HELPER_MEMORY_REQUEST",[747,68592,856],{"class":757},[747,68594,969],{"class":757},[747,68596,68597],{"class":802},"100Mi",[747,68599,975],{"class":757},[747,68601,68602,68605,68607,68609,68611],{"class":749,"line":1033},[747,68603,68604],{"class":753},"  KUBERNETES_HELPER_CPU_LIMIT",[747,68606,856],{"class":757},[747,68608,969],{"class":757},[747,68610,66262],{"class":802},[747,68612,975],{"class":757},[747,68614,68615,68618,68620,68622,68625],{"class":749,"line":1039},[747,68616,68617],{"class":753},"  KUBERNETES_HELPER_MEMORY_LIMIT",[747,68619,856],{"class":757},[747,68621,969],{"class":757},[747,68623,68624],{"class":802},"200Mi",[747,68626,975],{"class":757},[747,68628,68629,68632,68634,68636,68639],{"class":749,"line":1054},[747,68630,68631],{"class":753},"  KUBERNETES_PULL_POLICY",[747,68633,856],{"class":757},[747,68635,969],{"class":757},[747,68637,68638],{"class":802},"if-not-present",[747,68640,975],{"class":757},[747,68642,68643,68646,68648,68650,68652],{"class":749,"line":1060},[747,68644,68645],{"class":753},"  KUBERNETES_TERMINATIONGRACEPERIODSECONDS",[747,68647,856],{"class":757},[747,68649,969],{"class":757},[747,68651,30334],{"class":802},[747,68653,975],{"class":757},[747,68655,68656,68659,68661,68663,68665],{"class":749,"line":1066},[747,68657,68658],{"class":753},"  KUBERNETES_POLL_INTERVAL",[747,68660,856],{"class":757},[747,68662,969],{"class":757},[747,68664,26762],{"class":802},[747,68666,975],{"class":757},[747,68668,68669,68672,68674,68676,68679],{"class":749,"line":1081},[747,68670,68671],{"class":753},"  KUBERNETES_POLL_TIMEOUT",[747,68673,856],{"class":757},[747,68675,969],{"class":757},[747,68677,68678],{"class":802},"360",[747,68680,975],{"class":757},[747,68682,68683,68685,68687],{"class":749,"line":1087},[747,68684,12963],{"class":753},[747,68686,856],{"class":757},[747,68688,30930],{"class":802},[747,68690,68691,68693],{"class":749,"line":1102},[747,68692,12973],{"class":753},[747,68694,758],{"class":757},[747,68696,68697,68699],{"class":749,"line":1110},[747,68698,25378],{"class":753},[747,68700,758],{"class":757},[747,68702,68703,68705,68707],{"class":749,"line":1117},[747,68704,25385],{"class":753},[747,68706,856],{"class":757},[747,68708,68709],{"class":802}," gitlab-ci-runner\n",[747,68711,68712,68714,68716],{"class":749,"line":1123},[747,68713,12980],{"class":753},[747,68715,856],{"class":757},[747,68717,68718],{"class":802}," gitlab-ci-runner-cm\n",[747,68720,68721,68723,68725],{"class":749,"line":1129},[747,68722,13231],{"class":753},[747,68724,856],{"class":757},[747,68726,68311],{"class":802},[523,68728,68729,68730,68732],{},"The above ",[567,68731,30063],{}," also adds resource requests and limits to the build containers run. You can change them as long as they follow the Kubernetes resource limits units.",[6072,68734,68735,68739,68759,68763,68777],{},[523,68736,68737],{},[584,68738,6189],{},[523,68740,68741,68742,68744,68745,68747,68748,68750,68751,68753,68754,68756,68757,64480],{},"When you have added new options to the ",[567,68743,30063],{},", you need to delete each GitLab CI Runner Pod. This is currently a limitation of using Kubernetes ",[567,68746,31629],{}," instead of ",[567,68749,30046],{}," directly (",[567,68752,31629],{}," helps keep manifests shorter by moving the environment variables out to ",[567,68755,30063],{},"s or ",[567,68758,25167],{},[523,68760,68761],{},[584,68762,6189],{},[523,68764,68765,68766,22542,68769,68771,68772,68774,68775,1909],{},"To add additional options (\u002Fflags), you need to run ",[567,68767,68768],{},"gitlab-ci-multi-runner register --help",[567,68770,25722],{}," to see all available flags with their matching environment variable counter part (in square brackets, without the ",[567,68773,1919],{}," sign) next to the flag name.\nYou just add the env vars for the flags you want to configure, as shown in the above ",[567,68776,30063],{},[523,68778,68779,68780,856],{},"Example output of ",[567,68781,68768],{},[738,68783,68785],{"className":1621,"code":68784,"language":1623,"meta":743,"style":743},"gitlab-runner@gitlab-ci-runner-0:\u002F$ gitlab-ci-multi-runner --help\n[...]\n--kubernetes-cpu-limit value                          The CPU allocation given to build containers (default: \"1\") [$KUBERNETES_CPU_LIMIT]\n--kubernetes-memory-limit value                       The amount of memory allocated to build containers (default: \"4Gi\") [$KUBERNETES_MEMORY_LIMIT]\n--kubernetes-service-cpu-limit value                  The CPU allocation given to build service containers (default: \"1\") [$KUBERNETES_SERVICE_CPU_LIMIT]\n--kubernetes-service-memory-limit value               The amount of memory allocated to build service containers (default: \"1Gi\") [$KUBERNETES_SERVICE_MEMORY_LIMIT]\n--kubernetes-helper-cpu-limit value                   The CPU allocation given to build helper containers (default: \"500m\") [$KUBERNETES_HELPER_CPU_LIMIT]\n--kubernetes-helper-memory-limit value                The amount of memory allocated to build helper containers (default: \"3Gi\") [$KUBERNETES_HELPER_MEMORY_LIMIT]\n--kubernetes-cpu-request value                        The CPU allocation requested for build containers [$KUBERNETES_CPU_REQUEST]\n[...]\n",[567,68786,68787,68797,68805,68849,68893,68934,68977,69019,69063,69089],{"__ignoreMap":743},[747,68788,68789,68792,68795],{"class":749,"line":750},[747,68790,68791],{"class":1630},"gitlab-runner@gitlab-ci-runner-0:\u002F$",[747,68793,68794],{"class":802}," gitlab-ci-multi-runner",[747,68796,4218],{"class":802},[747,68798,68799,68801,68803],{"class":749,"line":761},[747,68800,4253],{"class":757},[747,68802,5685],{"class":1640},[747,68804,4268],{"class":757},[747,68806,68807,68810,68813,68816,68818,68821,68824,68826,68828,68831,68834,68836,68838,68840,68842,68844,68847],{"class":749,"line":769},[747,68808,68809],{"class":1630},"--kubernetes-cpu-limit",[747,68811,68812],{"class":802}," value",[747,68814,68815],{"class":802},"                          The",[747,68817,8476],{"class":802},[747,68819,68820],{"class":802}," allocation",[747,68822,68823],{"class":802}," given",[747,68825,3696],{"class":802},[747,68827,9733],{"class":802},[747,68829,68830],{"class":802}," containers",[747,68832,68833],{"class":1640}," (default: ",[747,68835,3892],{"class":757},[747,68837,13727],{"class":802},[747,68839,3892],{"class":757},[747,68841,19348],{"class":1640},[747,68843,4253],{"class":757},[747,68845,68846],{"class":1640},"$KUBERNETES_CPU_LIMIT",[747,68848,4268],{"class":757},[747,68850,68851,68854,68856,68859,68862,68864,68866,68869,68871,68873,68875,68877,68879,68882,68884,68886,68888,68891],{"class":749,"line":776},[747,68852,68853],{"class":1630},"--kubernetes-memory-limit",[747,68855,68812],{"class":802},[747,68857,68858],{"class":802},"                       The",[747,68860,68861],{"class":802}," amount",[747,68863,5276],{"class":802},[747,68865,8624],{"class":802},[747,68867,68868],{"class":802}," allocated",[747,68870,3696],{"class":802},[747,68872,9733],{"class":802},[747,68874,68830],{"class":802},[747,68876,68833],{"class":1640},[747,68878,3892],{"class":757},[747,68880,68881],{"class":802},"4Gi",[747,68883,3892],{"class":757},[747,68885,19348],{"class":1640},[747,68887,4253],{"class":757},[747,68889,68890],{"class":1640},"$KUBERNETES_MEMORY_LIMIT",[747,68892,4268],{"class":757},[747,68894,68895,68898,68900,68903,68905,68907,68909,68911,68913,68915,68917,68919,68921,68923,68925,68927,68929,68932],{"class":749,"line":784},[747,68896,68897],{"class":1630},"--kubernetes-service-cpu-limit",[747,68899,68812],{"class":802},[747,68901,68902],{"class":802},"                  The",[747,68904,8476],{"class":802},[747,68906,68820],{"class":802},[747,68908,68823],{"class":802},[747,68910,3696],{"class":802},[747,68912,9733],{"class":802},[747,68914,15340],{"class":802},[747,68916,68830],{"class":802},[747,68918,68833],{"class":1640},[747,68920,3892],{"class":757},[747,68922,13727],{"class":802},[747,68924,3892],{"class":757},[747,68926,19348],{"class":1640},[747,68928,4253],{"class":757},[747,68930,68931],{"class":1640},"$KUBERNETES_SERVICE_CPU_LIMIT",[747,68933,4268],{"class":757},[747,68935,68936,68939,68941,68944,68946,68948,68950,68952,68954,68956,68958,68960,68962,68964,68966,68968,68970,68972,68975],{"class":749,"line":790},[747,68937,68938],{"class":1630},"--kubernetes-service-memory-limit",[747,68940,68812],{"class":802},[747,68942,68943],{"class":802},"               The",[747,68945,68861],{"class":802},[747,68947,5276],{"class":802},[747,68949,8624],{"class":802},[747,68951,68868],{"class":802},[747,68953,3696],{"class":802},[747,68955,9733],{"class":802},[747,68957,15340],{"class":802},[747,68959,68830],{"class":802},[747,68961,68833],{"class":1640},[747,68963,3892],{"class":757},[747,68965,66275],{"class":802},[747,68967,3892],{"class":757},[747,68969,19348],{"class":1640},[747,68971,4253],{"class":757},[747,68973,68974],{"class":1640},"$KUBERNETES_SERVICE_MEMORY_LIMIT",[747,68976,4268],{"class":757},[747,68978,68979,68982,68984,68987,68989,68991,68993,68995,68997,69000,69002,69004,69006,69008,69010,69012,69014,69017],{"class":749,"line":796},[747,68980,68981],{"class":1630},"--kubernetes-helper-cpu-limit",[747,68983,68812],{"class":802},[747,68985,68986],{"class":802},"                   The",[747,68988,8476],{"class":802},[747,68990,68820],{"class":802},[747,68992,68823],{"class":802},[747,68994,3696],{"class":802},[747,68996,9733],{"class":802},[747,68998,68999],{"class":802}," helper",[747,69001,68830],{"class":802},[747,69003,68833],{"class":1640},[747,69005,3892],{"class":757},[747,69007,66262],{"class":802},[747,69009,3892],{"class":757},[747,69011,19348],{"class":1640},[747,69013,4253],{"class":757},[747,69015,69016],{"class":1640},"$KUBERNETES_HELPER_CPU_LIMIT",[747,69018,4268],{"class":757},[747,69020,69021,69024,69026,69029,69031,69033,69035,69037,69039,69041,69043,69045,69047,69049,69052,69054,69056,69058,69061],{"class":749,"line":806},[747,69022,69023],{"class":1630},"--kubernetes-helper-memory-limit",[747,69025,68812],{"class":802},[747,69027,69028],{"class":802},"                The",[747,69030,68861],{"class":802},[747,69032,5276],{"class":802},[747,69034,8624],{"class":802},[747,69036,68868],{"class":802},[747,69038,3696],{"class":802},[747,69040,9733],{"class":802},[747,69042,68999],{"class":802},[747,69044,68830],{"class":802},[747,69046,68833],{"class":1640},[747,69048,3892],{"class":757},[747,69050,69051],{"class":802},"3Gi",[747,69053,3892],{"class":757},[747,69055,19348],{"class":1640},[747,69057,4253],{"class":757},[747,69059,69060],{"class":1640},"$KUBERNETES_HELPER_MEMORY_LIMIT",[747,69062,4268],{"class":757},[747,69064,69065,69068,69070,69073,69075,69077,69080,69082,69084,69086],{"class":749,"line":814},[747,69066,69067],{"class":1630},"--kubernetes-cpu-request",[747,69069,68812],{"class":802},[747,69071,69072],{"class":802},"                        The",[747,69074,8476],{"class":802},[747,69076,68820],{"class":802},[747,69078,69079],{"class":802}," requested",[747,69081,3761],{"class":802},[747,69083,9733],{"class":802},[747,69085,68830],{"class":802},[747,69087,69088],{"class":1640}," [$KUBERNETES_CPU_REQUEST]\n",[747,69090,69091,69093,69095],{"class":749,"line":822},[747,69092,4253],{"class":757},[747,69094,5685],{"class":1640},[747,69096,4268],{"class":757},[6072,69098,69099,69103],{},[523,69100,69101],{},[584,69102,6189],{},[523,69104,69105,69106,69109,69110,69112],{},"To run a command in the GitLab CI Runner Pods, use ",[567,69107,69108],{},"kubectl exec -n YOUR_GITLAB_BUILD_NAMESPACE -it gitlab-ci-runner-0 \u002Fbin\u002Fbash",". This will drop you into the Pod and give you ",[567,69111,1623],{}," shell.",[523,69114,69115,69116,69118,69119,69122,69123,69125,69126,1909],{},"Next up is the ",[567,69117,30063],{}," which contains a small script which registers, runs and unregisters the GitLab CI Runner.\nThe runner unregister will only be triggered when the Pod is normally terminated through Kubernetes (",[567,69120,69121],{},"TERM"," signal).\nIn case of a forced termination of the Pod (",[567,69124,40996],{}," signal), the CI runner won't unregister itself. Cleanup of such \"killed\" CI Runners has to be done manually.\nMore information on Pod termination can be found here: ",[527,69127,69130],{"href":69128,"rel":69129},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fworkloads\u002Fpods\u002Fpod\u002F#termination-of-pods",[531],"Kubernetes - Pods - Termination of Pods",[738,69132,69134],{"className":740,"code":69133,"language":742,"meta":743,"style":743},"apiVersion: v1\ndata:\n  run.sh: |\n    #!\u002Fbin\u002Fbash\n    unregister() {\n        kill %1\n        echo \"Unregistering runner ${RUNNER_NAME} ...\"\n        \u002Fusr\u002Fbin\u002Fgitlab-ci-multi-runner unregister -t \"$(\u002Fusr\u002Fbin\u002Fgitlab-ci-multi-runner list 2>&1 | tail -n1 | awk '{print $4}' | cut -d'=' -f2)\" -n ${RUNNER_NAME}\n        exit $?\n    }\n    trap 'unregister' EXIT HUP INT QUIT PIPE TERM\n    echo \"Registering runner ${RUNNER_NAME} ...\"\n    \u002Fusr\u002Fbin\u002Fgitlab-ci-multi-runner register -r ${GITLAB_CI_TOKEN}\n    sed -i 's\u002F^concurrent.*\u002Fconcurrent = '\"${RUNNER_REQUEST_CONCURRENCY}\"'\u002F' \u002Fhome\u002Fgitlab-runner\u002F.gitlab-runner\u002Fconfig.toml\n    echo \"Starting runner ${RUNNER_NAME} ...\"\n    \u002Fusr\u002Fbin\u002Fgitlab-ci-multi-runner run -n ${RUNNER_NAME} &\n    wait\nkind: ConfigMap\nmetadata:\n  labels:\n    app: gitlab-ci-runner\n  name: gitlab-ci-runner-scripts\n  namespace: YOUR_GITLAB_BUILD_NAMESPACE\n",[567,69135,69136,69144,69150,69159,69164,69169,69174,69179,69184,69189,69193,69198,69203,69208,69213,69218,69223,69228,69236,69242,69248,69256,69265],{"__ignoreMap":743},[747,69137,69138,69140,69142],{"class":749,"line":750},[747,69139,12949],{"class":753},[747,69141,856],{"class":757},[747,69143,22608],{"class":802},[747,69145,69146,69148],{"class":749,"line":761},[747,69147,30860],{"class":753},[747,69149,758],{"class":757},[747,69151,69152,69155,69157],{"class":749,"line":769},[747,69153,69154],{"class":753},"  run.sh",[747,69156,856],{"class":757},[747,69158,24697],{"class":19332},[747,69160,69161],{"class":749,"line":776},[747,69162,69163],{"class":802},"    #!\u002Fbin\u002Fbash\n",[747,69165,69166],{"class":749,"line":784},[747,69167,69168],{"class":802},"    unregister() {\n",[747,69170,69171],{"class":749,"line":790},[747,69172,69173],{"class":802},"        kill %1\n",[747,69175,69176],{"class":749,"line":796},[747,69177,69178],{"class":802},"        echo \"Unregistering runner ${RUNNER_NAME} ...\"\n",[747,69180,69181],{"class":749,"line":806},[747,69182,69183],{"class":802},"        \u002Fusr\u002Fbin\u002Fgitlab-ci-multi-runner unregister -t \"$(\u002Fusr\u002Fbin\u002Fgitlab-ci-multi-runner list 2>&1 | tail -n1 | awk '{print $4}' | cut -d'=' -f2)\" -n ${RUNNER_NAME}\n",[747,69185,69186],{"class":749,"line":814},[747,69187,69188],{"class":802},"        exit $?\n",[747,69190,69191],{"class":749,"line":822},[747,69192,21297],{"class":802},[747,69194,69195],{"class":749,"line":830},[747,69196,69197],{"class":802},"    trap 'unregister' EXIT HUP INT QUIT PIPE TERM\n",[747,69199,69200],{"class":749,"line":836},[747,69201,69202],{"class":802},"    echo \"Registering runner ${RUNNER_NAME} ...\"\n",[747,69204,69205],{"class":749,"line":842},[747,69206,69207],{"class":802},"    \u002Fusr\u002Fbin\u002Fgitlab-ci-multi-runner register -r ${GITLAB_CI_TOKEN}\n",[747,69209,69210],{"class":749,"line":850},[747,69211,69212],{"class":802},"    sed -i 's\u002F^concurrent.*\u002Fconcurrent = '\"${RUNNER_REQUEST_CONCURRENCY}\"'\u002F' \u002Fhome\u002Fgitlab-runner\u002F.gitlab-runner\u002Fconfig.toml\n",[747,69214,69215],{"class":749,"line":863},[747,69216,69217],{"class":802},"    echo \"Starting runner ${RUNNER_NAME} ...\"\n",[747,69219,69220],{"class":749,"line":869},[747,69221,69222],{"class":802},"    \u002Fusr\u002Fbin\u002Fgitlab-ci-multi-runner run -n ${RUNNER_NAME} &\n",[747,69224,69225],{"class":749,"line":877},[747,69226,69227],{"class":802},"    wait\n",[747,69229,69230,69232,69234],{"class":749,"line":1015},[747,69231,12963],{"class":753},[747,69233,856],{"class":757},[747,69235,30930],{"class":802},[747,69237,69238,69240],{"class":749,"line":1021},[747,69239,12973],{"class":753},[747,69241,758],{"class":757},[747,69243,69244,69246],{"class":749,"line":1027},[747,69245,25378],{"class":753},[747,69247,758],{"class":757},[747,69249,69250,69252,69254],{"class":749,"line":1033},[747,69251,25385],{"class":753},[747,69253,856],{"class":757},[747,69255,68709],{"class":802},[747,69257,69258,69260,69262],{"class":749,"line":1039},[747,69259,12980],{"class":753},[747,69261,856],{"class":757},[747,69263,69264],{"class":802}," gitlab-ci-runner-scripts\n",[747,69266,69267,69269,69271],{"class":749,"line":1054},[747,69268,13231],{"class":753},[747,69270,856],{"class":757},[747,69272,68311],{"class":802},[613,69274,69276],{"id":69275},"secret-for-the-token-environment-variable","Secret for the Token Environment Variable",[523,69278,69279,69280,1909],{},"Then we'll use the GitLab CI runner token to create a secret in Kubernetes for it to use it in the ",[567,69281,69282],{},"Statefulset",[523,69284,69285],{},"To encode the token as base64, you can run something like this:",[738,69287,69289],{"className":1621,"code":69288,"language":1623,"meta":743,"style":743},"$ echo YOUR_GITLAB_CI_TOKEN | base64 -w0\n",[567,69290,69291],{"__ignoreMap":743},[747,69292,69293,69295,69297,69300,69302,69304],{"class":749,"line":750},[747,69294,1919],{"class":1630},[747,69296,23285],{"class":802},[747,69298,69299],{"class":802}," YOUR_GITLAB_CI_TOKEN",[747,69301,3170],{"class":757},[747,69303,23293],{"class":1630},[747,69305,65680],{"class":802},[523,69307,2000,69308,69310],{},[567,69309,65650],{}," should be available and already installed on most Linux distributions)",[523,69312,23726,69313,69316],{},[567,69314,69315],{},"YOUR_BASE64_ENCODED_TOKEN"," with the output from the above command.",[738,69318,69320],{"className":740,"code":69319,"language":742,"meta":743,"style":743},"apiVersion: v1\nkind: Secret\nmetadata:\n  name: gitlab-ci-token\n  namespace: YOUR_GITLAB_BUILD_NAMESPACE\n  labels:\n    app: gitlab-ci-runner\ndata:\n  GITLAB_CI_TOKEN: YOUR_BASE64_ENCODED_TOKEN\n",[567,69321,69322,69330,69338,69344,69353,69361,69367,69375,69381],{"__ignoreMap":743},[747,69323,69324,69326,69328],{"class":749,"line":750},[747,69325,12949],{"class":753},[747,69327,856],{"class":757},[747,69329,22608],{"class":802},[747,69331,69332,69334,69336],{"class":749,"line":761},[747,69333,12963],{"class":753},[747,69335,856],{"class":757},[747,69337,23233],{"class":802},[747,69339,69340,69342],{"class":749,"line":769},[747,69341,12973],{"class":753},[747,69343,758],{"class":757},[747,69345,69346,69348,69350],{"class":749,"line":776},[747,69347,12980],{"class":753},[747,69349,856],{"class":757},[747,69351,69352],{"class":802}," gitlab-ci-token\n",[747,69354,69355,69357,69359],{"class":749,"line":784},[747,69356,13231],{"class":753},[747,69358,856],{"class":757},[747,69360,68311],{"class":802},[747,69362,69363,69365],{"class":749,"line":790},[747,69364,25378],{"class":753},[747,69366,758],{"class":757},[747,69368,69369,69371,69373],{"class":749,"line":796},[747,69370,25385],{"class":753},[747,69372,856],{"class":757},[747,69374,68709],{"class":802},[747,69376,69377,69379],{"class":749,"line":806},[747,69378,30860],{"class":753},[747,69380,758],{"class":757},[747,69382,69383,69386,69388],{"class":749,"line":814},[747,69384,69385],{"class":753},"  GITLAB_CI_TOKEN",[747,69387,856],{"class":757},[747,69389,69390],{"class":802}," YOUR_BASE64_ENCODED_TOKEN\n",[613,69392,69394],{"id":69393},"statefulset-for-the-actually-running-the-runners-in-kubernetes","Statefulset for the actually running the Runners in Kubernetes",[523,69396,69397,69398,69401,69402,69405,69406,69409,69410,1909],{},"This container specification for the GitLab CI runner has a twist added to it. On start the runer tries to unregister any runner with the same name. This is especially useful when a node is lost (aka ",[567,69399,69400],{},"NodeLost"," event). It then tries to re-register itself and then begin to run. On a normal stop of the Pod, the GitLab CI runner will run the ",[567,69403,69404],{},"unregister"," command to try to unregister itself, so it won't be used by GitLab anymore. This is done by using Kubernetes ",[567,69407,69408],{},"lifecycle"," \"hooks\", documentation about them can be found here: ",[527,69411,69414],{"href":69412,"rel":69413},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fcontainers\u002Fcontainer-lifecycle-hooks\u002F",[531],"Kubernetes.io - Container Lifecycle Hooks",[523,69416,69417,69418,69420,69421,30064,69423,69425],{},"Another awesome thing is that using ",[567,69419,31629],{}," allows to specify ",[567,69422,25167],{},[567,69424,30063],{},"s to be used as environment variables (variables are only set when they match the specific regex for environment variables).",[738,69427,69429],{"className":740,"code":69428,"language":742,"meta":743,"style":743},"apiVersion: apps\u002Fv1beta1\nkind: StatefulSet\nmetadata:\n  name: gitlab-ci-runner\n  namespace: YOUR_GITLAB_BUILD_NAMESPACE\n  labels:\n    app: gitlab-ci-runner\nspec:\n  updateStrategy:\n    type: RollingUpdate\n  replicas: 2\n  serviceName: gitlab-ci-runner\n  template:\n    metadata:\n      labels:\n        app: gitlab-ci-runner\n    spec:\n      affinity:\n        podAntiAffinity:\n          requiredDuringSchedulingIgnoredDuringExecution:\n            - topologyKey: \"kubernetes.io\u002Fhostname\"\n              labelSelector:\n                matchExpressions:\n                - key: app\n                  operator: In\n                  values:\n                  - gitlab-ci-runner\n      volumes:\n      - name: gitlab-ci-runner-scripts\n        projected:\n          sources:\n          - configMap:\n              name: gitlab-ci-runner-scripts\n              items:\n              - key: run.sh\n                path: run.sh\n                mode: 0755\n      serviceAccountName: gitlab-ci\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 999\n        supplementalGroups: [999]\n      containers:\n      - image: gitlab\u002Fgitlab-runner:v12.6.0\n        name: gitlab-ci-runner\n        command:\n        - \u002Fscripts\u002Frun.sh\n        envFrom:\n        - configMapRef:\n            name: gitlab-ci-runner-cm\n        - secretRef:\n            name: gitlab-ci-token\n        env:\n        - name: RUNNER_NAME\n          valueFrom:\n            fieldRef:\n              fieldPath: metadata.name\n        ports:\n        - containerPort: 9100\n          name: http-metrics\n          protocol: TCP\n        volumeMounts:\n        - name: gitlab-ci-runner-scripts\n          mountPath: \"\u002Fscripts\"\n          readOnly: true\n      restartPolicy: Always\n",[567,69430,69431,69439,69447,69453,69461,69469,69475,69483,69489,69496,69505,69513,69521,69527,69533,69539,69547,69553,69560,69567,69574,69591,69598,69605,69616,69626,69633,69640,69646,69656,69663,69670,69679,69687,69694,69706,69715,69725,69734,69741,69750,69760,69774,69780,69791,69799,69806,69813,69819,69827,69835,69843,69851,69857,69868,69874,69881,69891,69897,69907,69915,69923,69929,69939,69952,69961],{"__ignoreMap":743},[747,69432,69433,69435,69437],{"class":749,"line":750},[747,69434,12949],{"class":753},[747,69436,856],{"class":757},[747,69438,65901],{"class":802},[747,69440,69441,69443,69445],{"class":749,"line":761},[747,69442,12963],{"class":753},[747,69444,856],{"class":757},[747,69446,65910],{"class":802},[747,69448,69449,69451],{"class":749,"line":769},[747,69450,12973],{"class":753},[747,69452,758],{"class":757},[747,69454,69455,69457,69459],{"class":749,"line":776},[747,69456,12980],{"class":753},[747,69458,856],{"class":757},[747,69460,68709],{"class":802},[747,69462,69463,69465,69467],{"class":749,"line":784},[747,69464,13231],{"class":753},[747,69466,856],{"class":757},[747,69468,68311],{"class":802},[747,69470,69471,69473],{"class":749,"line":790},[747,69472,25378],{"class":753},[747,69474,758],{"class":757},[747,69476,69477,69479,69481],{"class":749,"line":796},[747,69478,25385],{"class":753},[747,69480,856],{"class":757},[747,69482,68709],{"class":802},[747,69484,69485,69487],{"class":749,"line":806},[747,69486,12990],{"class":753},[747,69488,758],{"class":757},[747,69490,69491,69494],{"class":749,"line":814},[747,69492,69493],{"class":753},"  updateStrategy",[747,69495,758],{"class":757},[747,69497,69498,69500,69502],{"class":749,"line":822},[747,69499,29315],{"class":753},[747,69501,856],{"class":757},[747,69503,69504],{"class":802}," RollingUpdate\n",[747,69506,69507,69509,69511],{"class":749,"line":830},[747,69508,25420],{"class":753},[747,69510,856],{"class":757},[747,69512,25425],{"class":1895},[747,69514,69515,69517,69519],{"class":749,"line":836},[747,69516,65949],{"class":753},[747,69518,856],{"class":757},[747,69520,68709],{"class":802},[747,69522,69523,69525],{"class":749,"line":842},[747,69524,25462],{"class":753},[747,69526,758],{"class":757},[747,69528,69529,69531],{"class":749,"line":850},[747,69530,21456],{"class":753},[747,69532,758],{"class":757},[747,69534,69535,69537],{"class":749,"line":863},[747,69536,25475],{"class":753},[747,69538,758],{"class":757},[747,69540,69541,69543,69545],{"class":749,"line":869},[747,69542,25482],{"class":753},[747,69544,856],{"class":757},[747,69546,68709],{"class":802},[747,69548,69549,69551],{"class":749,"line":877},[747,69550,25509],{"class":753},[747,69552,758],{"class":757},[747,69554,69555,69558],{"class":749,"line":1015},[747,69556,69557],{"class":753},"      affinity",[747,69559,758],{"class":757},[747,69561,69562,69565],{"class":749,"line":1021},[747,69563,69564],{"class":753},"        podAntiAffinity",[747,69566,758],{"class":757},[747,69568,69569,69572],{"class":749,"line":1027},[747,69570,69571],{"class":753},"          requiredDuringSchedulingIgnoredDuringExecution",[747,69573,758],{"class":757},[747,69575,69576,69579,69582,69584,69586,69589],{"class":749,"line":1033},[747,69577,69578],{"class":757},"            -",[747,69580,69581],{"class":753}," topologyKey",[747,69583,856],{"class":757},[747,69585,969],{"class":757},[747,69587,69588],{"class":802},"kubernetes.io\u002Fhostname",[747,69590,975],{"class":757},[747,69592,69593,69596],{"class":749,"line":1039},[747,69594,69595],{"class":753},"              labelSelector",[747,69597,758],{"class":757},[747,69599,69600,69603],{"class":749,"line":1054},[747,69601,69602],{"class":753},"                matchExpressions",[747,69604,758],{"class":757},[747,69606,69607,69610,69612,69614],{"class":749,"line":1060},[747,69608,69609],{"class":757},"                -",[747,69611,41770],{"class":753},[747,69613,856],{"class":757},[747,69615,24308],{"class":802},[747,69617,69618,69621,69623],{"class":749,"line":1066},[747,69619,69620],{"class":753},"                  operator",[747,69622,856],{"class":757},[747,69624,69625],{"class":802}," In\n",[747,69627,69628,69631],{"class":749,"line":1081},[747,69629,69630],{"class":753},"                  values",[747,69632,758],{"class":757},[747,69634,69635,69638],{"class":749,"line":1087},[747,69636,69637],{"class":757},"                  -",[747,69639,68709],{"class":802},[747,69641,69642,69644],{"class":749,"line":1102},[747,69643,32763],{"class":753},[747,69645,758],{"class":757},[747,69647,69648,69650,69652,69654],{"class":749,"line":1110},[747,69649,799],{"class":757},[747,69651,14804],{"class":753},[747,69653,856],{"class":757},[747,69655,69264],{"class":802},[747,69657,69658,69661],{"class":749,"line":1117},[747,69659,69660],{"class":753},"        projected",[747,69662,758],{"class":757},[747,69664,69665,69668],{"class":749,"line":1123},[747,69666,69667],{"class":753},"          sources",[747,69669,758],{"class":757},[747,69671,69672,69674,69677],{"class":749,"line":1129},[747,69673,62242],{"class":757},[747,69675,69676],{"class":753}," configMap",[747,69678,758],{"class":757},[747,69680,69681,69683,69685],{"class":749,"line":1142},[747,69682,31491],{"class":753},[747,69684,856],{"class":757},[747,69686,69264],{"class":802},[747,69688,69689,69692],{"class":749,"line":1150},[747,69690,69691],{"class":753},"              items",[747,69693,758],{"class":757},[747,69695,69696,69699,69701,69703],{"class":749,"line":1157},[747,69697,69698],{"class":757},"              -",[747,69700,41770],{"class":753},[747,69702,856],{"class":757},[747,69704,69705],{"class":802}," run.sh\n",[747,69707,69708,69711,69713],{"class":749,"line":1163},[747,69709,69710],{"class":753},"                path",[747,69712,856],{"class":757},[747,69714,69705],{"class":802},[747,69716,69717,69720,69722],{"class":749,"line":1168},[747,69718,69719],{"class":753},"                mode",[747,69721,856],{"class":757},[747,69723,69724],{"class":1895}," 0755\n",[747,69726,69727,69730,69732],{"class":749,"line":1174},[747,69728,69729],{"class":753},"      serviceAccountName",[747,69731,856],{"class":757},[747,69733,22632],{"class":802},[747,69735,69736,69739],{"class":749,"line":1480},[747,69737,69738],{"class":753},"      securityContext",[747,69740,758],{"class":757},[747,69742,69743,69746,69748],{"class":749,"line":1491},[747,69744,69745],{"class":753},"        runAsNonRoot",[747,69747,856],{"class":757},[747,69749,860],{"class":859},[747,69751,69752,69755,69757],{"class":749,"line":1496},[747,69753,69754],{"class":753},"        runAsUser",[747,69756,856],{"class":757},[747,69758,69759],{"class":1895}," 999\n",[747,69761,69762,69765,69767,69769,69772],{"class":749,"line":1502},[747,69763,69764],{"class":753},"        supplementalGroups",[747,69766,856],{"class":757},[747,69768,4262],{"class":757},[747,69770,69771],{"class":1895},"999",[747,69773,4268],{"class":757},[747,69775,69776,69778],{"class":749,"line":1510},[747,69777,25516],{"class":753},[747,69779,758],{"class":757},[747,69781,69782,69784,69786,69788],{"class":749,"line":1520},[747,69783,799],{"class":757},[747,69785,3702],{"class":753},[747,69787,856],{"class":757},[747,69789,69790],{"class":802}," gitlab\u002Fgitlab-runner:v12.6.0\n",[747,69792,69793,69795,69797],{"class":749,"line":1525},[747,69794,30527],{"class":753},[747,69796,856],{"class":757},[747,69798,68709],{"class":802},[747,69800,69801,69804],{"class":749,"line":1533},[747,69802,69803],{"class":753},"        command",[747,69805,758],{"class":757},[747,69807,69808,69810],{"class":749,"line":1539},[747,69809,14801],{"class":757},[747,69811,69812],{"class":802}," \u002Fscripts\u002Frun.sh\n",[747,69814,69815,69817],{"class":749,"line":1549},[747,69816,31559],{"class":753},[747,69818,758],{"class":757},[747,69820,69821,69823,69825],{"class":749,"line":1554},[747,69822,14801],{"class":757},[747,69824,31594],{"class":753},[747,69826,758],{"class":757},[747,69828,69829,69831,69833],{"class":749,"line":1562},[747,69830,31579],{"class":753},[747,69832,856],{"class":757},[747,69834,68718],{"class":802},[747,69836,69837,69839,69841],{"class":749,"line":1568},[747,69838,14801],{"class":757},[747,69840,31572],{"class":753},[747,69842,758],{"class":757},[747,69844,69845,69847,69849],{"class":749,"line":1577},[747,69846,31579],{"class":753},[747,69848,856],{"class":757},[747,69850,69352],{"class":802},[747,69852,69853,69855],{"class":749,"line":1582},[747,69854,30536],{"class":753},[747,69856,758],{"class":757},[747,69858,69859,69861,69863,69865],{"class":749,"line":1588},[747,69860,14801],{"class":757},[747,69862,14804],{"class":753},[747,69864,856],{"class":757},[747,69866,69867],{"class":802}," RUNNER_NAME\n",[747,69869,69870,69872],{"class":749,"line":1594},[747,69871,31477],{"class":753},[747,69873,758],{"class":757},[747,69875,69876,69879],{"class":749,"line":1600},[747,69877,69878],{"class":753},"            fieldRef",[747,69880,758],{"class":757},[747,69882,69883,69886,69888],{"class":749,"line":4804},[747,69884,69885],{"class":753},"              fieldPath",[747,69887,856],{"class":757},[747,69889,69890],{"class":802}," metadata.name\n",[747,69892,69893,69895],{"class":749,"line":4810},[747,69894,25553],{"class":753},[747,69896,758],{"class":757},[747,69898,69899,69901,69903,69905],{"class":749,"line":4816},[747,69900,14801],{"class":757},[747,69902,29864],{"class":753},[747,69904,856],{"class":757},[747,69906,14839],{"class":1895},[747,69908,69909,69911,69913],{"class":749,"line":4822},[747,69910,30581],{"class":753},[747,69912,856],{"class":757},[747,69914,25566],{"class":802},[747,69916,69917,69919,69921],{"class":749,"line":4828},[747,69918,25571],{"class":753},[747,69920,856],{"class":757},[747,69922,25576],{"class":802},[747,69924,69925,69927],{"class":749,"line":4834},[747,69926,32736],{"class":753},[747,69928,758],{"class":757},[747,69930,69931,69933,69935,69937],{"class":749,"line":4840},[747,69932,14801],{"class":757},[747,69934,14804],{"class":753},[747,69936,856],{"class":757},[747,69938,69264],{"class":802},[747,69940,69941,69943,69945,69947,69950],{"class":749,"line":4846},[747,69942,32753],{"class":753},[747,69944,856],{"class":757},[747,69946,969],{"class":757},[747,69948,69949],{"class":802},"\u002Fscripts",[747,69951,975],{"class":757},[747,69953,69954,69957,69959],{"class":749,"line":4852},[747,69955,69956],{"class":753},"          readOnly",[747,69958,856],{"class":757},[747,69960,860],{"class":859},[747,69962,69963,69966,69968],{"class":749,"line":4858},[747,69964,69965],{"class":753},"      restartPolicy",[747,69967,856],{"class":757},[747,69969,25548],{"class":802},[6072,69971,69972,69976,69991],{},[523,69973,69974],{},[584,69975,6189],{},[523,69977,69978,69979,69981,69982,69985,69986,1909],{},"Be sure to use the \"latest\" available image tag for the GitLab CI runner (",[567,69980,11215],{},").\nThe available image tags for the ",[567,69983,69984],{},"gitlab\u002Fgitlab-runner"," image can be found here: ",[527,69987,69990],{"href":69988,"rel":69989},"https:\u002F\u002Fhub.docker.com\u002Fr\u002Fgitlab\u002Fgitlab-runner\u002Ftags",[531],"gitlab\u002Fgitlab-runner Tags - Docker Hub",[523,69992,69993,69994,714,69996,69999],{},"It is not recommended to use \"dynamic static\" tags (e.g., ",[567,69995,8834],{},[567,69997,69998],{},"bleeding",", etc). Best is to use a specific tag, which makes debugging easier.",[613,70001,70003],{"id":70002},"rbac-serviceaccount-role-and-rolebinding","RBAC: ServiceAccount, Role and Rolebinding",[6072,70005,70006,70010,70013,70017],{},[523,70007,70008],{},[584,70009,6189],{},[523,70011,70012],{},"If you are not using RBAC, skip this section.",[523,70014,70015],{},[584,70016,6189],{},[523,70018,70019,70020,70022,70023,70025,70026,70029,70030,70032],{},"I know for myself that the ",[567,70021,22529],{}," used here can and should be improved. Though as it is ",[584,70024,12261],{}," a wildcard ",[567,70027,70028],{},"ClusterRole"," it is not that worse at least for my setup as the ",[567,70031,68274],{}," namespace is dedicated for GitLab CI.",[523,70034,70035],{},"As noted above:",[668,70037,70038,70041],{},[638,70039,70040],{},"These are very very very (did I say very?) open permissions granted to the GitLab CI runners.",[638,70042,70043],{},"These can\u002Fshould\u002Fmust be refined and reduced for \"real\" production environments.",[523,70045,70046,70047,70049],{},"If you had the time to refine\u002Freduce them, please let me know in the comments. I'm happy to give you a shoutout in the post and add your improved ",[567,70048,22529],{},", thanks!",[738,70051,70053],{"className":740,"code":70052,"language":742,"meta":743,"style":743},"apiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: gitlab-ci\n  namespace: YOUR_GITLAB_BUILD_NAMESPACE\n---\nkind: Role\napiVersion: rbac.authorization.k8s.io\u002Fv1\nmetadata:\n  namespace: YOUR_GITLAB_BUILD_NAMESPACE\n  name: gitlab-ci\nrules:\n  - apiGroups: [\"\"]\n    resources: [\"*\"]\n    verbs: [\"*\"]\n---\nkind: RoleBinding\napiVersion: rbac.authorization.k8s.io\u002Fv1\nmetadata:\n  name: gitlab-ci\n  namespace: YOUR_GITLAB_BUILD_NAMESPACE\nsubjects:\n  - kind: ServiceAccount\n    name: gitlab-ci\n    namespace: YOUR_GITLAB_BUILD_NAMESPACE\nroleRef:\n  kind: Role\n  name: gitlab-ci\n  apiGroup: rbac.authorization.k8s.io\n",[567,70054,70055,70063,70071,70077,70085,70093,70097,70105,70113,70119,70127,70135,70141,70155,70171,70188,70192,70200,70208,70214,70222,70230,70236,70246,70254,70263,70269,70277,70285],{"__ignoreMap":743},[747,70056,70057,70059,70061],{"class":749,"line":750},[747,70058,12949],{"class":753},[747,70060,856],{"class":757},[747,70062,22608],{"class":802},[747,70064,70065,70067,70069],{"class":749,"line":761},[747,70066,12963],{"class":753},[747,70068,856],{"class":757},[747,70070,22617],{"class":802},[747,70072,70073,70075],{"class":749,"line":769},[747,70074,12973],{"class":753},[747,70076,758],{"class":757},[747,70078,70079,70081,70083],{"class":749,"line":776},[747,70080,12980],{"class":753},[747,70082,856],{"class":757},[747,70084,22632],{"class":802},[747,70086,70087,70089,70091],{"class":749,"line":784},[747,70088,13231],{"class":753},[747,70090,856],{"class":757},[747,70092,68311],{"class":802},[747,70094,70095],{"class":749,"line":790},[747,70096,12808],{"class":1630},[747,70098,70099,70101,70103],{"class":749,"line":796},[747,70100,12963],{"class":753},[747,70102,856],{"class":757},[747,70104,22653],{"class":802},[747,70106,70107,70109,70111],{"class":749,"line":806},[747,70108,12949],{"class":753},[747,70110,856],{"class":757},[747,70112,22662],{"class":802},[747,70114,70115,70117],{"class":749,"line":814},[747,70116,12973],{"class":753},[747,70118,758],{"class":757},[747,70120,70121,70123,70125],{"class":749,"line":822},[747,70122,13231],{"class":753},[747,70124,856],{"class":757},[747,70126,68311],{"class":802},[747,70128,70129,70131,70133],{"class":749,"line":830},[747,70130,12980],{"class":753},[747,70132,856],{"class":757},[747,70134,22632],{"class":802},[747,70136,70137,70139],{"class":749,"line":836},[747,70138,22689],{"class":753},[747,70140,758],{"class":757},[747,70142,70143,70145,70147,70149,70151,70153],{"class":749,"line":842},[747,70144,1721],{"class":757},[747,70146,22698],{"class":753},[747,70148,856],{"class":757},[747,70150,4262],{"class":757},[747,70152,22705],{"class":757},[747,70154,4268],{"class":757},[747,70156,70157,70159,70161,70163,70165,70167,70169],{"class":749,"line":850},[747,70158,28941],{"class":753},[747,70160,856],{"class":757},[747,70162,4262],{"class":757},[747,70164,3892],{"class":757},[747,70166,22721],{"class":802},[747,70168,3892],{"class":757},[747,70170,4268],{"class":757},[747,70172,70173,70176,70178,70180,70182,70184,70186],{"class":749,"line":863},[747,70174,70175],{"class":753},"    verbs",[747,70177,856],{"class":757},[747,70179,4262],{"class":757},[747,70181,3892],{"class":757},[747,70183,22721],{"class":802},[747,70185,3892],{"class":757},[747,70187,4268],{"class":757},[747,70189,70190],{"class":749,"line":869},[747,70191,12808],{"class":1630},[747,70193,70194,70196,70198],{"class":749,"line":877},[747,70195,12963],{"class":753},[747,70197,856],{"class":757},[747,70199,22959],{"class":802},[747,70201,70202,70204,70206],{"class":749,"line":1015},[747,70203,12949],{"class":753},[747,70205,856],{"class":757},[747,70207,22662],{"class":802},[747,70209,70210,70212],{"class":749,"line":1021},[747,70211,12973],{"class":753},[747,70213,758],{"class":757},[747,70215,70216,70218,70220],{"class":749,"line":1027},[747,70217,12980],{"class":753},[747,70219,856],{"class":757},[747,70221,22632],{"class":802},[747,70223,70224,70226,70228],{"class":749,"line":1033},[747,70225,13231],{"class":753},[747,70227,856],{"class":757},[747,70229,68311],{"class":802},[747,70231,70232,70234],{"class":749,"line":1039},[747,70233,22994],{"class":753},[747,70235,758],{"class":757},[747,70237,70238,70240,70242,70244],{"class":749,"line":1054},[747,70239,1721],{"class":757},[747,70241,23003],{"class":753},[747,70243,856],{"class":757},[747,70245,22617],{"class":802},[747,70247,70248,70250,70252],{"class":749,"line":1060},[747,70249,24402],{"class":753},[747,70251,856],{"class":757},[747,70253,22632],{"class":802},[747,70255,70256,70259,70261],{"class":749,"line":1066},[747,70257,70258],{"class":753},"    namespace",[747,70260,856],{"class":757},[747,70262,68311],{"class":802},[747,70264,70265,70267],{"class":749,"line":1081},[747,70266,23028],{"class":753},[747,70268,758],{"class":757},[747,70270,70271,70273,70275],{"class":749,"line":1087},[747,70272,23035],{"class":753},[747,70274,856],{"class":757},[747,70276,22653],{"class":802},[747,70278,70279,70281,70283],{"class":749,"line":1102},[747,70280,12980],{"class":753},[747,70282,856],{"class":757},[747,70284,22632],{"class":802},[747,70286,70287,70289,70291],{"class":749,"line":1110},[747,70288,23052],{"class":753},[747,70290,856],{"class":757},[747,70292,23057],{"class":802},[523,70294,23076,70295,70297,70298,70301,70302,70307,70308,10324],{},[567,70296,22529],{}," object and you are on GKE (other Kubernetes as a Service platforms maybe affected too), please take a look at this GitHub issue: ",[527,70299,23088],{"href":23086,"rel":70300},[531],".\nThanks to ",[527,70303,70306],{"href":70304,"rel":70305},"https:\u002F\u002Fdisqus.com\u002Fby\u002Fparamaw\u002F",[531],"Parama Danoesubroto"," for commenting about this for GKE (see his comment ",[527,70309,70310],{"href":70310,"rel":70311},"http:\u002F\u002Fdisq.us\u002Fp\u002F1r9y13d",[531],[535,70313,70315],{"id":70314},"step-4-create-the-manifests","Step 4 - Create the manifests",[523,70317,70318,70319,70321,70322,70324],{},"To interact with the Kubernetes cluster the ",[567,70320,15269],{}," programm is used. To create\u002F\"run\" a manifest on the Kubernetes cluster the subcommand ",[567,70323,38675],{}," is used.\nAn example, like this:",[738,70326,70327],{"className":1621,"code":66581,"language":1623,"meta":743,"style":743},[567,70328,70329],{"__ignoreMap":743},[747,70330,70331,70333,70335,70337],{"class":749,"line":750},[747,70332,15269],{"class":1630},[747,70334,1925],{"class":802},[747,70336,1934],{"class":802},[747,70338,38705],{"class":802},[523,70340,8764,70341,70343,70344,70346,70347,70349,70350,1909],{},[567,70342,66599],{}," would be the corresponding name of file you saved the manifest(s) in.\nTo specify multiple manifests in one go, just add ",[567,70345,38723],{}," per file behind the ",[567,70348,38675],{},". Like this ",[567,70351,70352],{},"kubectl create -f FILE_NAME_1 -f FILE_NAME_2 -f FILE_NAME_3 ...",[523,70354,70355,70356,1909],{},"Now specify the manifests you created in the ",[527,70357,68232],{"href":68231},[535,70359,70361],{"id":70360},"step-5-check-the-gitlab-ci-runners","Step 5 - Check the GitLab CI Runners",[6072,70363,70364,70368],{},[523,70365,70366],{},[584,70367,6189],{},[523,70369,70370,70371,1909],{},"For an example GitLab CI pipeline construct, please take a look at the repository on GitHub ",[527,70372,22355],{"href":22353,"rel":70373},[531],[523,70375,70376],{},"Go to the GitLab Admin area and there to the \"Runners\" tab as shown above.",[523,70378,70379],{},[3069,70380],{"alt":70381,"src":70382},"GitLab Runners List","\u002Fblog\u002F2017\u002Fgitlab-kubernetes-running-ci-runners-in-kubernetes\u002Fgitlab-runners-list.png",[523,70384,70385,70386,70389],{},"In the table\u002Flist below where you got the GitLab runner token from, the runners should habe appeared.\nIf not check the ",[527,70387,207],{"href":70388},"#Troubleshooting"," section below.",[535,70391,207],{"id":26330},[613,70393,70395],{"id":70394},"check-the-logs-of-the-gitlab-ci-runner-pods","Check the logs of the GitLab CI runner Pods",[523,70397,70398],{},"To get logs from one of the GitLab CI runner pods, you can use the following command:",[738,70400,70402],{"className":1621,"code":70401,"language":1623,"meta":743,"style":743},"$ kubectl logs -f gitlab-ci-runner-0\n[...]\nGITLAB_CI_RUNNER_0_POD_LOGS_HERE\n[...]\n",[567,70403,70404,70417,70425,70430],{"__ignoreMap":743},[747,70405,70406,70408,70410,70412,70414],{"class":749,"line":750},[747,70407,1919],{"class":1630},[747,70409,1922],{"class":802},[747,70411,17595],{"class":802},[747,70413,1934],{"class":802},[747,70415,70416],{"class":802}," gitlab-ci-runner-0\n",[747,70418,70419,70421,70423],{"class":749,"line":761},[747,70420,4253],{"class":757},[747,70422,5685],{"class":1640},[747,70424,4268],{"class":757},[747,70426,70427],{"class":749,"line":769},[747,70428,70429],{"class":1630},"GITLAB_CI_RUNNER_0_POD_LOGS_HERE\n",[747,70431,70432,70434,70436],{"class":749,"line":776},[747,70433,4253],{"class":757},[747,70435,5685],{"class":1640},[747,70437,4268],{"class":757},[523,70439,8764,70440,70442,70443,70446],{},[567,70441,11451],{}," option is causing the logs to be streamed, like with the ",[567,70444,70445],{},"tail"," command.\nCheck the logs for any errors.",[535,70448,14526],{"id":14525},[523,70450,70451,70452,70454,70455,70457],{},"Now you should have two (or more depending if you have changed the ",[567,70453,18111],{}," count in the ",[567,70456,30276],{}," manifest) GitLab CI runner that use Kubernetes as an so called executor for CI tasks.",[523,70459,13967],{},[2890,70461,70462],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":743,"searchDepth":761,"depth":761,"links":70464},[70465,70469,70470,70471,70479,70480,70481,70484],{"id":537,"depth":761,"text":538,"children":70466},[70467,70468],{"id":22267,"depth":769,"text":22268},{"id":64975,"depth":769,"text":64976},{"id":64988,"depth":761,"text":64989},{"id":68200,"depth":761,"text":68201},{"id":68242,"depth":761,"text":68243,"children":70472},[70473,70474,70475,70476,70477,70478],{"id":68249,"depth":769,"text":68250},{"id":68268,"depth":769,"text":68269},{"id":68314,"depth":769,"text":68315},{"id":69275,"depth":769,"text":69276},{"id":69393,"depth":769,"text":69394},{"id":70002,"depth":769,"text":70003},{"id":70314,"depth":761,"text":70315},{"id":70360,"depth":761,"text":70361},{"id":26330,"depth":761,"text":207,"children":70482},[70483],{"id":70394,"depth":769,"text":70395},{"id":14525,"depth":761,"text":14526},"2017-08-31T09:30:00+02:00","How to run GitLab CI Runners in Kubernetes using the GitLab CI Runner's Kubernetes executor.",{"src":70488},"\u002Fblog\u002F2017\u002Fgitlab-kubernetes-running-ci-runners-in-kubernetes\u002Fgitlab-kubernetes-running-ci-runners-in-kubernetes.png",{"tags":70490},[26414,26413,124,26415],"\u002Fblog\u002F2017\u002Fgitlab-kubernetes-running-ci-runners-in-kubernetes",{"title":68053,"description":70486},"3.blog\u002F2017\u002Fgitlab-kubernetes-running-ci-runners-in-kubernetes","CphRvWNYgzevWuQgqyhnIlr1hG7ZvZZ22-FThWDGOZk",{"id":70496,"title":70497,"authors":70498,"badge":518,"body":70501,"date":70759,"description":70760,"extension":2911,"image":70761,"meta":70763,"navigation":1254,"path":70766,"seo":70767,"stem":70768,"__hash__":70769},"posts\u002F3.blog\u002F2017\u002Fceph-rbd-bench-commands.md","Ceph: rbd bench Commands",[70499],{"name":514,"to":515,"avatar":70500},{"src":517},{"type":520,"value":70502,"toc":70750},[70503,70505,70524,70528,70531,70565,70569,70573,70579,70589,70592,70624,70628,70632,70635,70685,70689,70692,70731,70734,70745,70747],[535,70504,538],{"id":537},[523,70506,70507,70508,59081,70513,70518,70519,1909],{},"The reference to these commands is from ",[527,70509,70512],{"href":70510,"rel":70511},"https:\u002F\u002Fwww.sebastien-han.fr\u002Fblog\u002F2015\u002F09\u002F02\u002Fceph-validate-that-the-rbd-cache-is-active\u002F",[531],"Sébastien Han Blog Post \"Ceph: validate that the RBD cache is active\"",[527,70514,70517],{"href":70515,"rel":70516},"http:\u002F\u002Fdocs.ceph.com\u002Fdocs\u002Fjewel\u002Fman\u002F8\u002Frbd\u002F",[531],"rbd man Page",".\nFor more posts about Ceph, take a look at ",[527,70520,70523],{"href":70521,"rel":70522},"https:\u002F\u002Fwww.sebastien-han.fr\u002F",[531],"Sébastien Han Blog",[535,70525,70527],{"id":70526},"requisite-rbd-image-for-running-the-benchmarks","Requisite - RBD image for running the Benchmarks",[523,70529,70530],{},"To be able to run a rbd benchmark, you need to create an image.\nThe command to create an image for this would be:",[738,70532,70534],{"className":1621,"code":70533,"language":1623,"meta":743,"style":743},"$ RBD_IMAGE_NAME=\"bench1\"\n$ rbd create --size=10G $RBD_IMAGE_NAME\n",[567,70535,70536,70550],{"__ignoreMap":743},[747,70537,70538,70540,70543,70545,70548],{"class":749,"line":750},[747,70539,1919],{"class":1630},[747,70541,70542],{"class":802}," RBD_IMAGE_NAME=",[747,70544,3892],{"class":757},[747,70546,70547],{"class":802},"bench1",[747,70549,975],{"class":757},[747,70551,70552,70554,70557,70559,70562],{"class":749,"line":761},[747,70553,1919],{"class":1630},[747,70555,70556],{"class":802}," rbd",[747,70558,1925],{"class":802},[747,70560,70561],{"class":802}," --size=10G",[747,70563,70564],{"class":1640}," $RBD_IMAGE_NAME\n",[535,70566,70568],{"id":70567},"rbd-bench","rbd bench",[613,70570,70572],{"id":70571},"flags","Flags",[523,70574,70575,70576,70578],{},"Takes normal ",[567,70577,51484],{}," command flags like:",[668,70580,70581],{},[638,70582,70583,6374,70585,70588],{},[567,70584,6591],{},[567,70586,70587],{},"--pool"," for the rbd pool to use.",[523,70590,70591],{},"The following flags are for the benchmark configuration:",[668,70593,70594,70600,70606,70612,70618],{},[638,70595,70596,70599],{},[567,70597,70598],{},"--io-type"," if read or write IO should be run.",[638,70601,70602,70605],{},[567,70603,70604],{},"--io-size"," how big every IO should be (in B\u002FK\u002FM\u002FG\u002FT).",[638,70607,70608,70611],{},[567,70609,70610],{},"--io-threads"," how many IOs are done in parallel.",[638,70613,70614,70617],{},[567,70615,70616],{},"--io-total"," how much total IO should be done.",[638,70619,70620,70623],{},[567,70621,70622],{},"--io-pattern"," sequential or random IO pattern.",[613,70625,70627],{"id":70626},"benchmarks","Benchmarks",[3126,70629,70631],{"id":70630},"write-benchmark","Write Benchmark",[523,70633,70634],{},"For sequential write benchmark:",[738,70636,70638],{"className":1621,"code":70637,"language":1623,"meta":743,"style":743},"$ rbd -p replicapool bench $RBD_IMAGE_NAME --io-type write --io-size 8192 --io-threads 256 --io-total 10G --io-pattern seq\n",[567,70639,70640],{"__ignoreMap":743},[747,70641,70642,70644,70646,70648,70651,70654,70657,70659,70661,70664,70667,70670,70673,70676,70679,70682],{"class":749,"line":750},[747,70643,1919],{"class":1630},[747,70645,70556],{"class":802},[747,70647,7094],{"class":802},[747,70649,70650],{"class":802}," replicapool",[747,70652,70653],{"class":802}," bench",[747,70655,70656],{"class":1640}," $RBD_IMAGE_NAME ",[747,70658,70598],{"class":802},[747,70660,41904],{"class":802},[747,70662,70663],{"class":802}," --io-size",[747,70665,70666],{"class":1895}," 8192",[747,70668,70669],{"class":802}," --io-threads",[747,70671,70672],{"class":1895}," 256",[747,70674,70675],{"class":802}," --io-total",[747,70677,70678],{"class":802}," 10G",[747,70680,70681],{"class":802}," --io-pattern",[747,70683,70684],{"class":802}," seq\n",[3126,70686,70688],{"id":70687},"read-benchmark","Read Benchmark",[523,70690,70691],{},"For sequential read benchmark:",[738,70693,70695],{"className":1621,"code":70694,"language":1623,"meta":743,"style":743},"$ rbd -p replicapool bench $RBD_IMAGE_NAME --io-type read --io-size 8192 --io-threads 256 --io-total 10G --io-pattern seq\n",[567,70696,70697],{"__ignoreMap":743},[747,70698,70699,70701,70703,70705,70707,70709,70711,70713,70715,70717,70719,70721,70723,70725,70727,70729],{"class":749,"line":750},[747,70700,1919],{"class":1630},[747,70702,70556],{"class":802},[747,70704,7094],{"class":802},[747,70706,70650],{"class":802},[747,70708,70653],{"class":802},[747,70710,70656],{"class":1640},[747,70712,70598],{"class":802},[747,70714,5158],{"class":802},[747,70716,70663],{"class":802},[747,70718,70666],{"class":1895},[747,70720,70669],{"class":802},[747,70722,70672],{"class":1895},[747,70724,70675],{"class":802},[747,70726,70678],{"class":802},[747,70728,70681],{"class":802},[747,70730,70684],{"class":802},[613,70732,2840],{"id":70733},"notes",[668,70735,70736],{},[638,70737,70738,70739,70741,70742,1909],{},"To use random IO instead of sequential IO pattern, change the ",[567,70740,70622],{}," flag value to ",[567,70743,70744],{},"rand",[523,70746,13967],{},[2890,70748,70749],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":743,"searchDepth":761,"depth":761,"links":70751},[70752,70753,70754],{"id":537,"depth":761,"text":538},{"id":70526,"depth":761,"text":70527},{"id":70567,"depth":761,"text":70568,"children":70755},[70756,70757,70758],{"id":70571,"depth":769,"text":70572},{"id":70626,"depth":769,"text":70627},{"id":70733,"depth":769,"text":2840},"2017-08-05T23:53:35+02:00","Commands for running rbd bench(marks).",{"src":70762},"\u002Fblog\u002Fcovers\u002Fceph_logo_stacked_rgb_120411_fa.png",{"tags":70764},[427,70765],"Benchmark","\u002Fblog\u002F2017\u002Fceph-rbd-bench-commands",{"title":70497,"description":70760},"3.blog\u002F2017\u002Fceph-rbd-bench-commands","b3G1tCMYEeGjQ5FgwxfT6uM_-Pl-aZNuIYbXJUZ3rK4",{"id":70771,"title":70772,"authors":70773,"badge":518,"body":70776,"date":70790,"description":70791,"extension":2911,"image":70792,"meta":70794,"navigation":1254,"path":70796,"seo":70797,"stem":70798,"__hash__":70799},"posts\u002F3.blog\u002F2017\u002Fkubernetes-wyntk-gitlab-ci-kubernetes-presentation.md","Kubernetes - WYNTK - GitLab CI + Kubernetes Presentation",[70774],{"name":514,"to":515,"avatar":70775},{"src":517},{"type":520,"value":70777,"toc":70788},[70778,70781,70783,70786],[523,70779,70780],{},"This is a presentation about WYNTK or \"What You Need To Know\" about using GitLab CI with Kubernetes for Continous Delivery as a quick overview.",[523,70782,58352],{},[18903,70784],{"src":70785,"frameBorder":3579,"height":18906,"allowFullScreen":5306,"mozallowfullscreen":5306,"webkitallowfullscreen":5306},"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002F1yu-9QLO4yOp2HeQR044eAOp8SdxnqaTDz-JYLXy7C2s\u002Fembed?start=false&loop=true&delayms=5000",[523,70787,52336],{},{"title":743,"searchDepth":761,"depth":761,"links":70789},[],"2017-07-31T19:32:15+02:00","A presentation about \"What You Need To Know\" about using GitLab CI with Kubernetes for Continous Delivery as a quick overview.",{"src":70793},"\u002Fblog\u002F2017\u002Fkubernetes-wyntk-gitlab-ci-kubernetes-presentation\u002Fkubernetes-wyntk-gitlab-ci-kubernetes-presentation.png",{"tags":70795},[18918,124,26415,26413,26414],"\u002Fblog\u002F2017\u002Fkubernetes-wyntk-gitlab-ci-kubernetes-presentation",{"title":70772,"description":70791},"3.blog\u002F2017\u002Fkubernetes-wyntk-gitlab-ci-kubernetes-presentation","5_MJ2PL-H0bnls6mTvNvcVLSyVGHoyuSajjEhYsQ6v4",{"id":70801,"title":22255,"authors":70802,"badge":518,"body":70805,"date":73250,"description":73251,"extension":2911,"image":73252,"meta":73254,"navigation":1254,"path":73256,"seo":73257,"stem":73258,"__hash__":73259},"posts\u002F3.blog\u002F2017\u002Fgitlab-kubernetes-perfect-match-for-continuous-delivery-with-container.md",[70803],{"name":514,"to":515,"avatar":70804},{"src":517},{"type":520,"value":70806,"toc":73229},[70807,70811,70816,70825,70832,70835,70846,70850,70855,70857,70859,70862,70870,70872,70902,70912,70916,70922,70924,70933,70943,70947,71005,71010,71012,71014,71033,71045,71076,71080,71250,71254,71256,71264,71296,71306,71376,71383,71385,71389,71393,71397,71411,71417,71423,71429,71432,71438,71444,71448,71474,71478,71482,71516,71520,71522,71560,71562,71619,71632,71644,71679,71683,72339,72351,72355,72357,72363,72423,72429,72431,72433,72439,72705,72715,72724,72738,72750,72872,72890,72898,73077,73096,73108,73111,73113,73117,73163,73165,73170,73176,73178,73184,73189,73195,73199,73201,73203,73205,73207,73219,73221,73224,73226],[535,70808,70810],{"id":70809},"deprecation-warning","Deprecation Warning",[523,70812,70813,70814,1909],{},"GitLab has deprecated the Kubernetes integration with release ",[567,70815,22250],{},[6072,70817,70818],{},[523,70819,70820,70821,1909],{},"Kubernetes service integration has been deprecated in GitLab 10.3. If the service is active the cluster information still be editable, however we advised to disable and reconfigure the clusters using the new Clusters page. If the service is inactive the fields will be uneditable. Read GitLab 10.3 release post for more information.\nSee ",[527,70822,70823],{"href":70823,"rel":70824},"https:\u002F\u002Fdocs.gitlab.com\u002Fce\u002Fuser\u002Fproject\u002Fintegrations\u002Fkubernetes.html",[531],[523,70826,70827,70828,1909],{},"Instead of the integration, the new GitLab CI Kubernetes Cluster feature should be used, the documentation for that can be found here: ",[527,70829,70830],{"href":70830,"rel":70831},"https:\u002F\u002Fdocs.gitlab.com\u002Fce\u002Fuser\u002Fproject\u002Fclusters\u002Findex.html",[531],[523,70833,70834],{},"The new GitLab CI Cluster feature in GitLab exposes the same environment variables as the \"old\" Kubernetes integration.",[6072,70836,70837],{},[523,70838,70839,70841,70842,1909],{},[584,70840,6189],{}," An updated post on using the new GitLab CI Cluster feature, can be found here: ",[527,70843,70845],{"href":70844},"\u002Fblog\u002F2018\u002FGitLab-Kubernetes-Using-GitLab-CIs-Kubernetes-Cluster-feature.md","Edenmal - GitLab + Kubernetes: Using GitLab CI's Kubernetes Cluster feature",[535,70847,70849],{"id":70848},"updated-version-of-this-post-is-available","Updated version of this Post is available",[523,70851,70852,70853,1909],{},"An updated post using the new GitLab CI Cluster feature, can be found here: ",[527,70854,70845],{"href":70844},[2979,70856],{},[535,70858,538],{"id":537},[523,70860,70861],{},"In this post, I'll be going over using GitLab CI to create your application's container Continuous Delivery to Kubernetes.\nThis is the first of a three post series about Kubernetes and GitLab.",[6072,70863,70864,70868],{},[523,70865,70866],{},[584,70867,6189],{},[523,70869,22264],{},[613,70871,22268],{"id":22267},[668,70873,70874,70876,70888,70892],{},[638,70875,15241],{},[638,70877,22275,70878],{},[668,70879,70880,70882],{},[638,70881,22280],{},[638,70883,22283,70884],{},[668,70885,70886],{},[638,70887,22288],{},[638,70889,70890,22293],{},[567,70891,15269],{},[638,70893,22296,70894,70896],{},[567,70895,22299],{},[668,70897,70898],{},[638,70899,22304,70900,1909],{},[527,70901,22308],{"href":22307},[6072,70903,70904,70908],{},[523,70905,70906],{},[584,70907,6189],{},[523,70909,53136,70910,53139],{},[567,70911,22323],{},[535,70913,70915],{"id":70914},"gitlab-integration-kubernetes","GitLab Integration: Kubernetes",[523,70917,70918,70919,70921],{},"GitLab has multiple integrations for different applications, from Jira to Kubernetes and much more.\nThe GitLab Kubernetes integration mainly simplifies the usage of Kubernetes config in your GitLab CI pipelines. It adds environment variables to the GitLab CI build environment that are \"always\" the same.\nInstead of having to manually add secret variables this is done in the integration settings and as written the names of the variables are \"always\" the same.\nThe second point about the integration which was greatly expanded in the version ",[567,70920,61386],{}," release is the AutoDevOps functionality. I haven't worked yet with the AutoDevOps feature, but at least from the docs it seems to allow you to deploy to testing automatically, generate an URL (Ingress) for your changes and other pretty stuff to make it faster and easier to develop application on top of Kubernetes.",[535,70923,22347],{"id":22346},[523,70925,22350,70926,22356,70929,22360,70931,22364],{},[527,70927,22355],{"href":22353,"rel":70928},[531],[567,70930,22359],{},[567,70932,22363],{},[6072,70934,70935,70939],{},[523,70936,70937],{},[584,70938,6189],{},[523,70940,22373,70941,3361],{},[527,70942,22308],{"href":22307},[523,70944,22378,70945,22381],{},[567,70946,2984],{},[738,70948,70949],{"className":1621,"code":22384,"language":1623,"meta":743,"style":743},[567,70950,70951,70961,70969,70973,70987,70991],{"__ignoreMap":743},[747,70952,70953,70955,70957,70959],{"class":749,"line":750},[747,70954,1919],{"class":1630},[747,70956,22393],{"class":802},[747,70958,3506],{"class":802},[747,70960,22398],{"class":802},[747,70962,70963,70965,70967],{"class":749,"line":761},[747,70964,1919],{"class":1630},[747,70966,22405],{"class":802},[747,70968,22408],{"class":802},[747,70970,70971],{"class":749,"line":769},[747,70972,22413],{"class":772},[747,70974,70975,70977,70979,70981,70983,70985],{"class":749,"line":776},[747,70976,1919],{"class":1630},[747,70978,22393],{"class":802},[747,70980,22422],{"class":802},[747,70982,22425],{"class":802},[747,70984,22428],{"class":802},[747,70986,22431],{"class":802},[747,70988,70989],{"class":749,"line":784},[747,70990,22436],{"class":772},[747,70992,70993,70995,70997,70999,71001,71003],{"class":749,"line":790},[747,70994,1919],{"class":1630},[747,70996,22393],{"class":802},[747,70998,22445],{"class":802},[747,71000,7089],{"class":802},[747,71002,22428],{"class":802},[747,71004,22452],{"class":802},[523,71006,22455,71007,1909],{},[527,71008,22458],{"href":22458,"rel":71009},[531],[523,71011,22462],{},[535,71013,22308],{"id":53240},[6072,71015,71016,71020],{},[523,71017,71018],{},[584,71019,6189],{},[523,71021,53249,71022,53252,71024,714,71026,714,71028,71030,71031,53264],{},[567,71023,22299],{},[567,71025,25331],{},[567,71027,25729],{},[567,71029,158],{},".\nTalk to your cluster administrator about a ",[567,71032,22299],{},[523,71034,53267,71035,53271,71037,71039,71040,71042,71043,53283],{},[567,71036,53270],{},[567,71038,22299],{}," with the correct permissions, to deploy in the namespace of your choice.\nFor Kubernetes ",[567,71041,53279],{}," and below you just need to a) create a ",[567,71044,22299],{},[6072,71046,71047,71051,71060],{},[523,71048,71049],{},[584,71050,6189],{},[523,71052,53292,71053,71057,71058,53303],{},[584,71054,53295,71055,23072],{},[567,71056,22299],{},"!\nFor information on how create a ",[567,71059,22299],{},[668,71061,71062,71069],{},[638,71063,22296,71064,53310,71066],{},[567,71065,53279],{},[527,71067,53313],{"href":53313,"rel":71068},[531],[638,71070,22296,71071,53319,71073],{},[567,71072,53270],{},[527,71074,53322],{"href":53322,"rel":71075},[531],[523,71077,23091,71078,53328],{},[567,71079,22299],{},[738,71081,71082],{"className":1621,"code":53331,"language":1623,"meta":743,"style":743},[567,71083,71084,71098,71108,71118,71138,71144,71148,71154,71160,71176,71182,71186,71190,71196,71204,71210,71216,71224,71232,71246],{"__ignoreMap":743},[747,71085,71086,71088,71090,71092,71094,71096],{"class":749,"line":750},[747,71087,1919],{"class":1630},[747,71089,1922],{"class":802},[747,71091,1951],{"class":802},[747,71093,1928],{"class":802},[747,71095,23116],{"class":802},[747,71097,23119],{"class":802},[747,71099,71100,71102,71104,71106],{"class":749,"line":761},[747,71101,2230],{"class":1630},[747,71103,53354],{"class":802},[747,71105,23129],{"class":802},[747,71107,33030],{"class":802},[747,71109,71110,71112,71114,71116],{"class":749,"line":769},[747,71111,53363],{"class":1630},[747,71113,53366],{"class":802},[747,71115,16450],{"class":1895},[747,71117,53371],{"class":802},[747,71119,71120,71122,71124,71126,71128,71130,71132,71134,71136],{"class":749,"line":776},[747,71121,1919],{"class":1630},[747,71123,1922],{"class":802},[747,71125,1951],{"class":802},[747,71127,1928],{"class":802},[747,71129,23116],{"class":802},[747,71131,23182],{"class":802},[747,71133,53388],{"class":802},[747,71135,2222],{"class":802},[747,71137,23190],{"class":802},[747,71139,71140,71142],{"class":749,"line":784},[747,71141,23195],{"class":1630},[747,71143,22608],{"class":802},[747,71145,71146],{"class":749,"line":790},[747,71147,23202],{"class":1630},[747,71149,71150,71152],{"class":749,"line":796},[747,71151,23207],{"class":1630},[747,71153,23210],{"class":1640},[747,71155,71156,71158],{"class":749,"line":806},[747,71157,23215],{"class":1630},[747,71159,23210],{"class":1640},[747,71161,71162,71164,71166,71168,71170,71172,71174],{"class":749,"line":814},[747,71163,23222],{"class":1630},[747,71165,53421],{"class":1640},[747,71167,53424],{"class":802},[747,71169,53427],{"class":802},[747,71171,53430],{"class":802},[747,71173,53433],{"class":802},[747,71175,53436],{"class":802},[747,71177,71178,71180],{"class":749,"line":822},[747,71179,23230],{"class":1630},[747,71181,23233],{"class":802},[747,71183,71184],{"class":749,"line":830},[747,71185,23238],{"class":1630},[747,71187,71188],{"class":749,"line":836},[747,71189,53451],{"class":1630},[747,71191,71192,71194],{"class":749,"line":842},[747,71193,53456],{"class":1630},[747,71195,7736],{"class":802},[747,71197,71198,71200,71202],{"class":749,"line":850},[747,71199,13246],{"class":757},[747,71201,5685],{"class":1640},[747,71203,4268],{"class":757},[747,71205,71206,71208],{"class":749,"line":863},[747,71207,23251],{"class":1630},[747,71209,53473],{"class":802},[747,71211,71212,71214],{"class":749,"line":869},[747,71213,23215],{"class":1630},[747,71215,22408],{"class":802},[747,71217,71218,71220,71222],{"class":749,"line":877},[747,71219,13246],{"class":757},[747,71221,5685],{"class":1640},[747,71223,4268],{"class":757},[747,71225,71226,71228,71230],{"class":749,"line":1015},[747,71227,23273],{"class":4574},[747,71229,856],{"class":802},[747,71231,23278],{"class":802},[747,71233,71234,71236,71238,71240,71242,71244],{"class":749,"line":1021},[747,71235,1919],{"class":1630},[747,71237,23285],{"class":802},[747,71239,53504],{"class":802},[747,71241,3170],{"class":757},[747,71243,23293],{"class":1630},[747,71245,23296],{"class":802},[747,71247,71248],{"class":749,"line":1027},[747,71249,23301],{"class":1630},[523,71251,53517,71252,53520],{},[567,71253,23312],{},[535,71255,23317],{"id":23316},[523,71257,53525,71258,53529,71260,53533,71262,53536],{},[567,71259,53528],{},[567,71261,53532],{},[567,71263,6515],{},[738,71265,71266],{"className":1621,"code":53539,"language":1623,"meta":743,"style":743},[567,71267,71268,71276,71282,71290],{"__ignoreMap":743},[747,71269,71270,71272,71274],{"class":749,"line":750},[747,71271,1919],{"class":1630},[747,71273,45045],{"class":802},[747,71275,53550],{"class":802},[747,71277,71278,71280],{"class":749,"line":761},[747,71279,23519],{"class":1630},[747,71281,23522],{"class":802},[747,71283,71284,71286,71288],{"class":749,"line":769},[747,71285,4253],{"class":757},[747,71287,23529],{"class":1640},[747,71289,4268],{"class":757},[747,71291,71292,71294],{"class":749,"line":776},[747,71293,23536],{"class":1630},[747,71295,23522],{"class":802},[523,71297,53573,71298,53576,71300,53580,71302,53583,71304,1909],{},[567,71299,15269],{},[567,71301,53579],{},[567,71303,36064],{},[567,71305,53586],{},[738,71307,71308],{"className":740,"code":53589,"language":742,"meta":743,"style":743},[567,71309,71310,71318,71326,71332,71340,71344,71352,71360,71368],{"__ignoreMap":743},[747,71311,71312,71314,71316],{"class":749,"line":750},[747,71313,4253],{"class":757},[747,71315,5685],{"class":1895},[747,71317,4268],{"class":757},[747,71319,71320,71322,71324],{"class":749,"line":761},[747,71321,12949],{"class":753},[747,71323,856],{"class":757},[747,71325,22608],{"class":802},[747,71327,71328,71330],{"class":749,"line":769},[747,71329,53612],{"class":753},[747,71331,758],{"class":757},[747,71333,71334,71336,71338],{"class":749,"line":776},[747,71335,3361],{"class":757},[747,71337,53621],{"class":753},[747,71339,758],{"class":757},[747,71341,71342],{"class":749,"line":784},[747,71343,53628],{"class":772},[747,71345,71346,71348,71350],{"class":749,"line":790},[747,71347,53633],{"class":753},[747,71349,856],{"class":757},[747,71351,53638],{"class":802},[747,71353,71354,71356,71358],{"class":749,"line":796},[747,71355,53643],{"class":753},[747,71357,856],{"class":757},[747,71359,53648],{"class":802},[747,71361,71362,71364,71366],{"class":749,"line":806},[747,71363,12980],{"class":753},[747,71365,856],{"class":757},[747,71367,53657],{"class":802},[747,71369,71370,71372,71374],{"class":749,"line":814},[747,71371,4253],{"class":757},[747,71373,5685],{"class":1895},[747,71375,4268],{"class":757},[523,71377,53686,71378,53689,71380,1909],{},[567,71379,36064],{},[527,71381,53692],{"href":53692,"rel":71382},[531],[523,71384,53696],{},[523,71386,53699,71387,1909],{},[527,71388,22308],{"href":53702},[535,71390,71392],{"id":71391},"step-4-activate-the-kubernetes-integration-in-gitlab","Step 4 - Activate the Kubernetes Integration in GitLab",[523,71394,23566,71395,23569],{},[567,71396,22299],{},[523,71398,71399,71400,71403,71404,71407,71408,1909],{},"To setup the integration in GitLab, go to your project of choice and go to ",[567,71401,71402],{},"Settings","->",[567,71405,71406],{},"Integrations",". Scroll down to ",[567,71409,71410],{},"Project services",[523,71412,71413],{},[3069,71414],{"alt":71415,"src":71416},"GitLab - Settings -> Integrations","\u002Fblog\u002F2017\u002Fgitlab-kubernetes-perfect-match-for-continuous-delivery-with-container\u002Fphoto01.png",[523,71418,71419,71420,71422],{},"Now find the ",[567,71421,124],{}," point in the list and click on it.",[523,71424,71425],{},[3069,71426],{"alt":71427,"src":71428},"GitLab - Integration list","\u002Fblog\u002F2017\u002Fgitlab-kubernetes-perfect-match-for-continuous-delivery-with-container\u002Fphoto02.png",[523,71430,71431],{},"Next you need to fill out the formular with the token, the CA certificate, the Kubernetes API server address and namespace.",[523,71433,71434],{},[3069,71435],{"alt":71436,"src":71437},"GitLab - Kubernetes Integration Form","\u002Fblog\u002F2017\u002Fgitlab-kubernetes-perfect-match-for-continuous-delivery-with-container\u002Fphoto03.png",[523,71439,23706,71440,71443],{},[567,71441,71442],{},"Save changes"," and you now have the Kubernetes integration activated.",[535,71445,23713,71446,23717],{"id":23712},[567,71447,23716],{},[6072,71449,71450,71454,71468],{},[523,71451,71452],{},[584,71453,6189],{},[523,71455,71456,23730,71458,23734,71460,71463,71464,23743,71466,23747],{},[567,71457,23729],{},[567,71459,23733],{},[527,71461,23739],{"href":23737,"rel":71462},[531]," where I upload the artifact to an \"external\" destination for demonstration. To remove this step just delete the ",[567,71465,22359],{},[567,71467,23746],{},[523,71469,71470,53793,71472,53796],{},[584,71471,15250],{},[584,71473,23759],{},[523,71475,8764,71476,53801],{},[567,71477,23716],{},[523,71479,23763,71480,23766],{},[567,71481,23716],{},[738,71483,71484],{"className":740,"code":23769,"language":742,"meta":743,"style":743},[567,71485,71486,71490,71496,71504,71510],{"__ignoreMap":743},[747,71487,71488],{"class":749,"line":750},[747,71489,23776],{"class":772},[747,71491,71492,71494],{"class":749,"line":761},[747,71493,23781],{"class":753},[747,71495,758],{"class":757},[747,71497,71498,71500,71502],{"class":749,"line":769},[747,71499,23788],{"class":753},[747,71501,856],{"class":757},[747,71503,23793],{"class":802},[747,71505,71506,71508],{"class":749,"line":776},[747,71507,23798],{"class":753},[747,71509,758],{"class":757},[747,71511,71512,71514],{"class":749,"line":784},[747,71513,14801],{"class":757},[747,71515,23807],{"class":802},[523,71517,23810,71518,23813],{},[567,71519,23781],{},[523,71521,23816],{},[738,71523,71524],{"className":740,"code":23819,"language":742,"meta":743,"style":743},[567,71525,71526,71530,71536,71542,71548,71554],{"__ignoreMap":743},[747,71527,71528],{"class":749,"line":750},[747,71529,23826],{"class":772},[747,71531,71532,71534],{"class":749,"line":761},[747,71533,23831],{"class":753},[747,71535,758],{"class":757},[747,71537,71538,71540],{"class":749,"line":769},[747,71539,18665],{"class":757},[747,71541,23793],{"class":802},[747,71543,71544,71546],{"class":749,"line":776},[747,71545,18665],{"class":757},[747,71547,23846],{"class":802},[747,71549,71550,71552],{"class":749,"line":784},[747,71551,18665],{"class":757},[747,71553,23853],{"class":802},[747,71555,71556,71558],{"class":749,"line":790},[747,71557,18665],{"class":757},[747,71559,23860],{"class":802},[523,71561,23863],{},[738,71563,71565],{"className":740,"code":71564,"language":742,"meta":743,"style":743},"# For jobs without a image specified use the below\nimage: golang:1.8.3\n# Or for the test job the image `python:3` will be used:\ntest:\n    stage: test\n    image: python:3\n    script:\n        - go test .\u002F...\n",[567,71566,71567,71571,71580,71585,71591,71599,71607,71613],{"__ignoreMap":743},[747,71568,71569],{"class":749,"line":750},[747,71570,53895],{"class":772},[747,71572,71573,71575,71577],{"class":749,"line":761},[747,71574,23878],{"class":753},[747,71576,856],{"class":757},[747,71578,71579],{"class":802}," golang:1.8.3\n",[747,71581,71582],{"class":749,"line":769},[747,71583,71584],{"class":772},"# Or for the test job the image `python:3` will be used:\n",[747,71586,71587,71589],{"class":749,"line":776},[747,71588,23781],{"class":753},[747,71590,758],{"class":757},[747,71592,71593,71595,71597],{"class":749,"line":784},[747,71594,23788],{"class":753},[747,71596,856],{"class":757},[747,71598,23793],{"class":802},[747,71600,71601,71603,71605],{"class":749,"line":790},[747,71602,10899],{"class":753},[747,71604,856],{"class":757},[747,71606,23911],{"class":802},[747,71608,71609,71611],{"class":749,"line":796},[747,71610,23798],{"class":753},[747,71612,758],{"class":757},[747,71614,71615,71617],{"class":749,"line":806},[747,71616,14801],{"class":757},[747,71618,23807],{"class":802},[6072,71620,71621,71625],{},[523,71622,71623],{},[584,71624,6189],{},[523,71626,23933,71627,23936,71629,1909],{},[567,71628,23716],{},[527,71630,23939],{"href":23939,"rel":71631},[531],[523,71633,8336,71634,23945,71636,714,71638,714,71640,587,71642,856],{},[567,71635,23716],{},[567,71637,23781],{},[567,71639,9758],{},[567,71641,23952],{},[567,71643,23955],{},[668,71645,71646,71653,71659,71669],{},[638,71647,71648,23962,71650,23968],{},[567,71649,23781],{},[527,71651,23967],{"href":23965,"rel":71652},[531],[638,71654,71655,23973,71657,23977],{},[567,71656,9758],{},[567,71658,23976],{},[638,71660,71661,23982,71663,23986,71665,23989,71667,23992],{},[567,71662,23952],{},[567,71664,23985],{},[567,71666,23952],{},[567,71668,23976],{},[638,71670,71671,23997,71673,24001,71675,24004,71677,24008],{},[567,71672,23955],{},[567,71674,24000],{},[567,71676,24000],{},[567,71678,24007],{},[523,71680,24023,71681,23766],{},[567,71682,23716],{},[738,71684,71686],{"className":740,"code":71685,"language":742,"meta":743,"style":743},"image: golang:1.8.3\n# Fix the location of the go source code, different changes may be required for other languages\nbefore_script:\n    - mkdir -p \u002Fgo\u002Fsrc\u002Fgitlab.example.com\u002F${CI_PROJECT_NAMESPACE}\n    - ln -sf ${CI_PROJECT_DIR} \u002Fgo\u002Fsrc\u002Fgitlab.example.com\u002F${CI_PROJECT_PATH}\n    - cd \u002Fgo\u002Fsrc\u002Fgitlab.example.com\u002F${CI_PROJECT_PATH}\u002F\n# list of all stages\nstages:\n    - test\n    - build\n    - release\n    - deploy\n# run the golang application tests\ntest:\n    stage: test\n    script:\n        - go test .\u002F...\n        - \u002Fgo\u002Fbin\u002Fgovendor test +local\n# build\u002Fcompile the application\ncompile:\n    stage: build\n    variables:\n      VERSION: \"1.0.14\"\n    script:\n        - go build -race -ldflags \"-extldflags '-static'\" -o app\n    artifacts:\n        paths:\n            - app\n# use minio client to upload the built binary to a S3 storage\nrelease_upload:\n    stage: release\n    image: minio\u002Fmc\n    script:\n      - echo \"=> We already have artifact sotrage in GitLab! Are we sure we want this too?\"\n      - mc config host add examplenet https:\u002F\u002Fs3.example.com ${ACCESS_KEY} ${SECRET_KEY} S3v4\n      - mc mb -p examplenet\u002Fbuild-release-${CI_PROJECT_NAME}\u002F\n      - mc cp app examplenet\u002Fbuild-release-${CI_PROJECT_NAME}\u002F\n# build the Docker image with the artifact\nimage_build:\n    stage: release\n    image: docker:latest\n    variables:\n        DOCKER_HOST: \"tcp:\u002F\u002Flocalhost:2375\"\n    services:\n        - docker:dind\n    script:\n        - docker info\n        - docker login -u gitlab-ci-token -p ${CI_JOB_TOKEN} registry.example.com\n        - docker build -t registry.example.com\u002F${CI_PROJECT_PATH}:latest .\n        - docker tag registry.example.com\u002F${CI_PROJECT_PATH}:latest registry.example.com\u002F${CI_PROJECT_PATH}:${CI_COMMIT_REF_NAME}\n        - test ! -z \"${CI_COMMIT_TAG}\" && docker push registry.example.com\u002F${CI_PROJECT_PATH}:latest\n        - docker push registry.example.com\u002F${CI_PROJECT_PATH}:${CI_COMMIT_REF_NAME}\n# deploy to dev \"environment\", the Kubernetes manifests to the cluster\ndeploy_dev:\n    image: registry.gitlab.com\u002Fgitlab-examples\u002Fkubernetes-deploy\n    stage: deploy\n    environment:\n        name: dev\n        url: \"https:\u002F\u002Fdev-presentation-gitlab-k8s.example.com\"\n    script:\n        - echo \"${KUBE_CA_PEM}\" > kube_ca.pem\n        - kubectl config set-cluster default-cluster --server=${KUBE_URL} --certificate-authority=\"$(pwd)\u002Fkube_ca.pem\"\n        - kubectl config set-credentials default-admin --token=${KUBE_TOKEN}\n        - kubectl config set-context default-system --cluster=default-cluster --user=default-admin --namespace ${KUBE_NAMESPACE}\n        - kubectl config use-context default-system\n        - sed -i \"s\u002F__CI_ENVIRONMENT_SLUG__\u002F${CI_ENVIRONMENT_SLUG}\u002F\" deployment.yaml ingress.yaml service.yaml\n        - sed -i \"s\u002F__VERSION__\u002F${CI_COMMIT_REF_NAME}\u002F\" deployment.yaml ingress.yaml service.yaml\n        - kubectl cluster-info\n        - kubectl get deployments -l app=${CI_ENVIRONMENT_SLUG}\n        - kubectl create -f deployment.yaml || (kubectl delete -f deployment.yaml && kubectl apply -f deployment.yaml)\n        - kubectl create -f service.yaml || true\n        - kubectl apply -f ingress.yaml\n# deploy to live \"environment\", the Kubernetes manifests to the cluster\ndeploy_live:\n    image: registry.gitlab.com\u002Fgitlab-examples\u002Fkubernetes-deploy\n    stage: deploy\n    environment:\n        name: live\n        url: \"https:\u002F\u002Flive-presentation-gitlab-k8s.example.com\"\n    only:\n        - tags\n    when: manual\n    script:\n        - echo \"${KUBE_CA_PEM}\" > kube_ca.pem\n        - kubectl config set-cluster default-cluster --server=${KUBE_URL} --certificate-authority=\"$(pwd)\u002Fkube_ca.pem\"\n        - kubectl config set-credentials default-admin --token=${KUBE_TOKEN}\n        - kubectl config set-context default-system --cluster=default-cluster --user=default-admin --namespace ${KUBE_NAMESPACE}\n        - kubectl config use-context default-system\n        - sed -i \"s\u002F__CI_ENVIRONMENT_SLUG__\u002F${CI_ENVIRONMENT_SLUG}\u002F\" deployment.yaml ingress.yaml service.yaml\n        - sed -i \"s\u002F__VERSION__\u002F${CI_COMMIT_REF_NAME}\u002F\" deployment.yaml ingress.yaml service.yaml\n        - kubectl cluster-info\n        - kubectl get deployments -l app=${CI_ENVIRONMENT_SLUG}\n        - kubectl apply -f deployment.yaml\n        - kubectl create -f service.yaml || true\n        - kubectl apply -f ingress.yaml\n",[567,71687,71688,71696,71701,71707,71714,71721,71728,71732,71738,71744,71750,71756,71762,71766,71772,71780,71786,71792,71799,71804,71810,71818,71825,71839,71845,71852,71859,71866,71872,71877,71883,71891,71900,71906,71913,71920,71927,71934,71939,71945,71953,71961,71967,71981,71988,71994,72000,72006,72013,72020,72027,72034,72041,72046,72052,72061,72069,72075,72084,72098,72104,72111,72118,72125,72132,72139,72145,72151,72158,72165,72172,72179,72185,72190,72196,72204,72212,72218,72226,72239,72246,72252,72261,72267,72273,72279,72285,72291,72297,72303,72309,72315,72321,72327,72333],{"__ignoreMap":743},[747,71689,71690,71692,71694],{"class":749,"line":750},[747,71691,23878],{"class":753},[747,71693,856],{"class":757},[747,71695,71579],{"class":802},[747,71697,71698],{"class":749,"line":761},[747,71699,71700],{"class":772},"# Fix the location of the go source code, different changes may be required for other languages\n",[747,71702,71703,71705],{"class":749,"line":769},[747,71704,24109],{"class":753},[747,71706,758],{"class":757},[747,71708,71709,71711],{"class":749,"line":776},[747,71710,18665],{"class":757},[747,71712,71713],{"class":802}," mkdir -p \u002Fgo\u002Fsrc\u002Fgitlab.example.com\u002F${CI_PROJECT_NAMESPACE}\n",[747,71715,71716,71718],{"class":749,"line":784},[747,71717,18665],{"class":757},[747,71719,71720],{"class":802}," ln -sf ${CI_PROJECT_DIR} \u002Fgo\u002Fsrc\u002Fgitlab.example.com\u002F${CI_PROJECT_PATH}\n",[747,71722,71723,71725],{"class":749,"line":790},[747,71724,18665],{"class":757},[747,71726,71727],{"class":802}," cd \u002Fgo\u002Fsrc\u002Fgitlab.example.com\u002F${CI_PROJECT_PATH}\u002F\n",[747,71729,71730],{"class":749,"line":796},[747,71731,23826],{"class":772},[747,71733,71734,71736],{"class":749,"line":806},[747,71735,23831],{"class":753},[747,71737,758],{"class":757},[747,71739,71740,71742],{"class":749,"line":814},[747,71741,18665],{"class":757},[747,71743,23793],{"class":802},[747,71745,71746,71748],{"class":749,"line":822},[747,71747,18665],{"class":757},[747,71749,23846],{"class":802},[747,71751,71752,71754],{"class":749,"line":830},[747,71753,18665],{"class":757},[747,71755,23853],{"class":802},[747,71757,71758,71760],{"class":749,"line":836},[747,71759,18665],{"class":757},[747,71761,23860],{"class":802},[747,71763,71764],{"class":749,"line":842},[747,71765,23776],{"class":772},[747,71767,71768,71770],{"class":749,"line":850},[747,71769,23781],{"class":753},[747,71771,758],{"class":757},[747,71773,71774,71776,71778],{"class":749,"line":863},[747,71775,23788],{"class":753},[747,71777,856],{"class":757},[747,71779,23793],{"class":802},[747,71781,71782,71784],{"class":749,"line":869},[747,71783,23798],{"class":753},[747,71785,758],{"class":757},[747,71787,71788,71790],{"class":749,"line":877},[747,71789,14801],{"class":757},[747,71791,23807],{"class":802},[747,71793,71794,71796],{"class":749,"line":1015},[747,71795,14801],{"class":757},[747,71797,71798],{"class":802}," \u002Fgo\u002Fbin\u002Fgovendor test +local\n",[747,71800,71801],{"class":749,"line":1021},[747,71802,71803],{"class":772},"# build\u002Fcompile the application\n",[747,71805,71806,71808],{"class":749,"line":1027},[747,71807,24254],{"class":753},[747,71809,758],{"class":757},[747,71811,71812,71814,71816],{"class":749,"line":1033},[747,71813,23788],{"class":753},[747,71815,856],{"class":757},[747,71817,23846],{"class":802},[747,71819,71820,71823],{"class":749,"line":1039},[747,71821,71822],{"class":753},"    variables",[747,71824,758],{"class":757},[747,71826,71827,71830,71832,71834,71837],{"class":749,"line":1054},[747,71828,71829],{"class":753},"      VERSION",[747,71831,856],{"class":757},[747,71833,969],{"class":757},[747,71835,71836],{"class":802},"1.0.14",[747,71838,975],{"class":757},[747,71840,71841,71843],{"class":749,"line":1060},[747,71842,23798],{"class":753},[747,71844,758],{"class":757},[747,71846,71847,71849],{"class":749,"line":1066},[747,71848,14801],{"class":757},[747,71850,71851],{"class":802}," go build -race -ldflags \"-extldflags '-static'\" -o app\n",[747,71853,71854,71857],{"class":749,"line":1081},[747,71855,71856],{"class":753},"    artifacts",[747,71858,758],{"class":757},[747,71860,71861,71864],{"class":749,"line":1087},[747,71862,71863],{"class":753},"        paths",[747,71865,758],{"class":757},[747,71867,71868,71870],{"class":749,"line":1102},[747,71869,69578],{"class":757},[747,71871,24308],{"class":802},[747,71873,71874],{"class":749,"line":1110},[747,71875,71876],{"class":772},"# use minio client to upload the built binary to a S3 storage\n",[747,71878,71879,71881],{"class":749,"line":1117},[747,71880,22359],{"class":753},[747,71882,758],{"class":757},[747,71884,71885,71887,71889],{"class":749,"line":1123},[747,71886,23788],{"class":753},[747,71888,856],{"class":757},[747,71890,23853],{"class":802},[747,71892,71893,71895,71897],{"class":749,"line":1129},[747,71894,10899],{"class":753},[747,71896,856],{"class":757},[747,71898,71899],{"class":802}," minio\u002Fmc\n",[747,71901,71902,71904],{"class":749,"line":1142},[747,71903,23798],{"class":753},[747,71905,758],{"class":757},[747,71907,71908,71910],{"class":749,"line":1150},[747,71909,799],{"class":757},[747,71911,71912],{"class":802}," echo \"=> We already have artifact sotrage in GitLab! Are we sure we want this too?\"\n",[747,71914,71915,71917],{"class":749,"line":1157},[747,71916,799],{"class":757},[747,71918,71919],{"class":802}," mc config host add examplenet https:\u002F\u002Fs3.example.com ${ACCESS_KEY} ${SECRET_KEY} S3v4\n",[747,71921,71922,71924],{"class":749,"line":1163},[747,71923,799],{"class":757},[747,71925,71926],{"class":802}," mc mb -p examplenet\u002Fbuild-release-${CI_PROJECT_NAME}\u002F\n",[747,71928,71929,71931],{"class":749,"line":1168},[747,71930,799],{"class":757},[747,71932,71933],{"class":802}," mc cp app examplenet\u002Fbuild-release-${CI_PROJECT_NAME}\u002F\n",[747,71935,71936],{"class":749,"line":1174},[747,71937,71938],{"class":772},"# build the Docker image with the artifact\n",[747,71940,71941,71943],{"class":749,"line":1480},[747,71942,23985],{"class":753},[747,71944,758],{"class":757},[747,71946,71947,71949,71951],{"class":749,"line":1491},[747,71948,23788],{"class":753},[747,71950,856],{"class":757},[747,71952,23853],{"class":802},[747,71954,71955,71957,71959],{"class":749,"line":1496},[747,71956,10899],{"class":753},[747,71958,856],{"class":757},[747,71960,24407],{"class":802},[747,71962,71963,71965],{"class":749,"line":1502},[747,71964,71822],{"class":753},[747,71966,758],{"class":757},[747,71968,71969,71972,71974,71976,71979],{"class":749,"line":1510},[747,71970,71971],{"class":753},"        DOCKER_HOST",[747,71973,856],{"class":757},[747,71975,969],{"class":757},[747,71977,71978],{"class":802},"tcp:\u002F\u002Flocalhost:2375",[747,71980,975],{"class":757},[747,71982,71983,71986],{"class":749,"line":1520},[747,71984,71985],{"class":753},"    services",[747,71987,758],{"class":757},[747,71989,71990,71992],{"class":749,"line":1525},[747,71991,14801],{"class":757},[747,71993,24463],{"class":802},[747,71995,71996,71998],{"class":749,"line":1533},[747,71997,23798],{"class":753},[747,71999,758],{"class":757},[747,72001,72002,72004],{"class":749,"line":1539},[747,72003,14801],{"class":757},[747,72005,24476],{"class":802},[747,72007,72008,72010],{"class":749,"line":1549},[747,72009,14801],{"class":757},[747,72011,72012],{"class":802}," docker login -u gitlab-ci-token -p ${CI_JOB_TOKEN} registry.example.com\n",[747,72014,72015,72017],{"class":749,"line":1554},[747,72016,14801],{"class":757},[747,72018,72019],{"class":802}," docker build -t registry.example.com\u002F${CI_PROJECT_PATH}:latest .\n",[747,72021,72022,72024],{"class":749,"line":1562},[747,72023,14801],{"class":757},[747,72025,72026],{"class":802}," docker tag registry.example.com\u002F${CI_PROJECT_PATH}:latest registry.example.com\u002F${CI_PROJECT_PATH}:${CI_COMMIT_REF_NAME}\n",[747,72028,72029,72031],{"class":749,"line":1568},[747,72030,14801],{"class":757},[747,72032,72033],{"class":802}," test ! -z \"${CI_COMMIT_TAG}\" && docker push registry.example.com\u002F${CI_PROJECT_PATH}:latest\n",[747,72035,72036,72038],{"class":749,"line":1577},[747,72037,14801],{"class":757},[747,72039,72040],{"class":802}," docker push registry.example.com\u002F${CI_PROJECT_PATH}:${CI_COMMIT_REF_NAME}\n",[747,72042,72043],{"class":749,"line":1582},[747,72044,72045],{"class":772},"# deploy to dev \"environment\", the Kubernetes manifests to the cluster\n",[747,72047,72048,72050],{"class":749,"line":1588},[747,72049,22363],{"class":753},[747,72051,758],{"class":757},[747,72053,72054,72056,72058],{"class":749,"line":1594},[747,72055,10899],{"class":753},[747,72057,856],{"class":757},[747,72059,72060],{"class":802}," registry.gitlab.com\u002Fgitlab-examples\u002Fkubernetes-deploy\n",[747,72062,72063,72065,72067],{"class":749,"line":1600},[747,72064,23788],{"class":753},[747,72066,856],{"class":757},[747,72068,23860],{"class":802},[747,72070,72071,72073],{"class":749,"line":4804},[747,72072,10909],{"class":753},[747,72074,758],{"class":757},[747,72076,72077,72079,72081],{"class":749,"line":4810},[747,72078,30527],{"class":753},[747,72080,856],{"class":757},[747,72082,72083],{"class":802}," dev\n",[747,72085,72086,72089,72091,72093,72096],{"class":749,"line":4816},[747,72087,72088],{"class":753},"        url",[747,72090,856],{"class":757},[747,72092,969],{"class":757},[747,72094,72095],{"class":802},"https:\u002F\u002Fdev-presentation-gitlab-k8s.example.com",[747,72097,975],{"class":757},[747,72099,72100,72102],{"class":749,"line":4822},[747,72101,23798],{"class":753},[747,72103,758],{"class":757},[747,72105,72106,72108],{"class":749,"line":4828},[747,72107,14801],{"class":757},[747,72109,72110],{"class":802}," echo \"${KUBE_CA_PEM}\" > kube_ca.pem\n",[747,72112,72113,72115],{"class":749,"line":4834},[747,72114,14801],{"class":757},[747,72116,72117],{"class":802}," kubectl config set-cluster default-cluster --server=${KUBE_URL} --certificate-authority=\"$(pwd)\u002Fkube_ca.pem\"\n",[747,72119,72120,72122],{"class":749,"line":4840},[747,72121,14801],{"class":757},[747,72123,72124],{"class":802}," kubectl config set-credentials default-admin --token=${KUBE_TOKEN}\n",[747,72126,72127,72129],{"class":749,"line":4846},[747,72128,14801],{"class":757},[747,72130,72131],{"class":802}," kubectl config set-context default-system --cluster=default-cluster --user=default-admin --namespace ${KUBE_NAMESPACE}\n",[747,72133,72134,72136],{"class":749,"line":4852},[747,72135,14801],{"class":757},[747,72137,72138],{"class":802}," kubectl config use-context default-system\n",[747,72140,72141,72143],{"class":749,"line":4858},[747,72142,14801],{"class":757},[747,72144,24683],{"class":802},[747,72146,72147,72149],{"class":749,"line":4864},[747,72148,14801],{"class":757},[747,72150,24690],{"class":802},[747,72152,72153,72155],{"class":749,"line":4870},[747,72154,14801],{"class":757},[747,72156,72157],{"class":802}," kubectl cluster-info\n",[747,72159,72160,72162],{"class":749,"line":4876},[747,72161,14801],{"class":757},[747,72163,72164],{"class":802}," kubectl get deployments -l app=${CI_ENVIRONMENT_SLUG}\n",[747,72166,72167,72169],{"class":749,"line":4882},[747,72168,14801],{"class":757},[747,72170,72171],{"class":802}," kubectl create -f deployment.yaml || (kubectl delete -f deployment.yaml && kubectl apply -f deployment.yaml)\n",[747,72173,72174,72176],{"class":749,"line":4888},[747,72175,14801],{"class":757},[747,72177,72178],{"class":802}," kubectl create -f service.yaml || true\n",[747,72180,72181,72183],{"class":749,"line":4894},[747,72182,14801],{"class":757},[747,72184,24741],{"class":802},[747,72186,72187],{"class":749,"line":4900},[747,72188,72189],{"class":772},"# deploy to live \"environment\", the Kubernetes manifests to the cluster\n",[747,72191,72192,72194],{"class":749,"line":4906},[747,72193,24940],{"class":753},[747,72195,758],{"class":757},[747,72197,72198,72200,72202],{"class":749,"line":4912},[747,72199,10899],{"class":753},[747,72201,856],{"class":757},[747,72203,72060],{"class":802},[747,72205,72206,72208,72210],{"class":749,"line":4928},[747,72207,23788],{"class":753},[747,72209,856],{"class":757},[747,72211,23860],{"class":802},[747,72213,72214,72216],{"class":749,"line":4934},[747,72215,10909],{"class":753},[747,72217,758],{"class":757},[747,72219,72220,72222,72224],{"class":749,"line":4940},[747,72221,30527],{"class":753},[747,72223,856],{"class":757},[747,72225,25003],{"class":802},[747,72227,72228,72230,72232,72234,72237],{"class":749,"line":4946},[747,72229,72088],{"class":753},[747,72231,856],{"class":757},[747,72233,969],{"class":757},[747,72235,72236],{"class":802},"https:\u002F\u002Flive-presentation-gitlab-k8s.example.com",[747,72238,975],{"class":757},[747,72240,72241,72244],{"class":749,"line":4952},[747,72242,72243],{"class":753},"    only",[747,72245,758],{"class":757},[747,72247,72248,72250],{"class":749,"line":4958},[747,72249,14801],{"class":757},[747,72251,24597],{"class":802},[747,72253,72254,72257,72259],{"class":749,"line":4964},[747,72255,72256],{"class":753},"    when",[747,72258,856],{"class":757},[747,72260,24837],{"class":802},[747,72262,72263,72265],{"class":749,"line":4970},[747,72264,23798],{"class":753},[747,72266,758],{"class":757},[747,72268,72269,72271],{"class":749,"line":4998},[747,72270,14801],{"class":757},[747,72272,72110],{"class":802},[747,72274,72275,72277],{"class":749,"line":5016},[747,72276,14801],{"class":757},[747,72278,72117],{"class":802},[747,72280,72281,72283],{"class":749,"line":5048},[747,72282,14801],{"class":757},[747,72284,72124],{"class":802},[747,72286,72287,72289],{"class":749,"line":5077},[747,72288,14801],{"class":757},[747,72290,72131],{"class":802},[747,72292,72293,72295],{"class":749,"line":5098},[747,72294,14801],{"class":757},[747,72296,72138],{"class":802},[747,72298,72299,72301],{"class":749,"line":5121},[747,72300,14801],{"class":757},[747,72302,24683],{"class":802},[747,72304,72305,72307],{"class":749,"line":5127},[747,72306,14801],{"class":757},[747,72308,24690],{"class":802},[747,72310,72311,72313],{"class":749,"line":5133},[747,72312,14801],{"class":757},[747,72314,72157],{"class":802},[747,72316,72317,72319],{"class":749,"line":5139},[747,72318,14801],{"class":757},[747,72320,72164],{"class":802},[747,72322,72323,72325],{"class":749,"line":5164},[747,72324,14801],{"class":757},[747,72326,25089],{"class":802},[747,72328,72329,72331],{"class":749,"line":5205},[747,72330,14801],{"class":757},[747,72332,72178],{"class":802},[747,72334,72335,72337],{"class":749,"line":5229},[747,72336,14801],{"class":757},[747,72338,24741],{"class":802},[523,72340,25137,72341,587,72343,25144,72345,72347,72348],{},[567,72342,25140],{},[567,72344,25143],{},[567,72346,25147],{}," to run for created tags only and so on.\nMore on this topic can be found at the GitLab CI file documentation here: ",[527,72349,23939],{"href":23939,"rel":72350},[531],[523,72352,25154,72353,25157],{},[567,72354,19016],{},[535,72356,25161],{"id":25160},[523,72358,25164,72359,25168,72361,54872],{},[567,72360,25167],{},[567,72362,15269],{},[738,72364,72366],{"className":1621,"code":72365,"language":1623,"meta":743,"style":743},"# YOUR_SECRET_NAME for example \"registry-example-gitlab-key\"\n$ kubectl create \\\n    -n presentation-gitlab-k8s \\\n    secret docker-registry YOUR_SECRET_NAME_HERE \\\n    --docker-server=registry.example.com \\\n    --docker-username=YOUR_GITLAB_USERNAME \\\n    --docker-password=YOUR_PERSONAL_GITLAB_ACCESS_TOKEN_HERE \\\n    --docker-email=YOUR_GITLAB_EMAIL_ADDRESS\n",[567,72367,72368,72372,72382,72390,72401,72407,72413,72419],{"__ignoreMap":743},[747,72369,72370],{"class":749,"line":750},[747,72371,54882],{"class":772},[747,72373,72374,72376,72378,72380],{"class":749,"line":761},[747,72375,1919],{"class":1630},[747,72377,1922],{"class":802},[747,72379,1925],{"class":802},[747,72381,1641],{"class":1640},[747,72383,72384,72386,72388],{"class":749,"line":769},[747,72385,25210],{"class":802},[747,72387,23116],{"class":802},[747,72389,1641],{"class":1640},[747,72391,72392,72394,72396,72399],{"class":749,"line":776},[747,72393,25219],{"class":802},[747,72395,25222],{"class":802},[747,72397,72398],{"class":802}," YOUR_SECRET_NAME_HERE",[747,72400,1641],{"class":1640},[747,72402,72403,72405],{"class":749,"line":784},[747,72404,25232],{"class":802},[747,72406,1641],{"class":1640},[747,72408,72409,72411],{"class":749,"line":790},[747,72410,25239],{"class":802},[747,72412,1641],{"class":1640},[747,72414,72415,72417],{"class":749,"line":796},[747,72416,54928],{"class":802},[747,72418,1641],{"class":1640},[747,72420,72421],{"class":749,"line":806},[747,72422,54935],{"class":802},[523,72424,54938,72425,54942,72427,54945],{},[567,72426,55253],{},[567,72428,25331],{},[535,72430,25323],{"id":25322},[523,72432,25326],{},[523,72434,10839,72435,25332,72437,7258],{},[567,72436,25331],{},[567,72438,25335],{},[738,72440,72442],{"className":740,"code":72441,"language":742,"meta":743,"style":743},"apiVersion: extensions\u002Fv1beta1\nkind: Deployment\nmetadata:\n  name: __CI_ENVIRONMENT_SLUG__\n  labels:\n    app: __CI_ENVIRONMENT_SLUG__\n    track: stable\nspec:\n  replicas: 4\n  template:\n    metadata:\n      labels:\n        app: __CI_ENVIRONMENT_SLUG__\n        track: stable\n    spec:\n      imagePullSecrets:\n        - name: YOUR_SECRET_NAME_HERE\n      containers:\n      - name: app\n        image: registry.example.com\u002Fatrost\u002Fpresentation-gitlab-k8s:__VERSION__\n        imagePullPolicy: Always\n        ports:\n        - containerPort: 8000\n        livenessProbe:\n          httpGet:\n            path: \u002Fhealth\n            port: 8000\n          initialDelaySeconds: 3\n          timeoutSeconds: 2\n        readinessProbe:\n          httpGet:\n            path: \u002Fhealth\n            port: 8000\n          initialDelaySeconds: 3\n          timeoutSeconds: 2\n",[567,72443,72444,72452,72460,72466,72474,72480,72488,72496,72502,72511,72517,72523,72529,72537,72545,72551,72557,72568,72574,72584,72593,72601,72607,72617,72623,72629,72637,72645,72653,72661,72667,72673,72681,72689,72697],{"__ignoreMap":743},[747,72445,72446,72448,72450],{"class":749,"line":750},[747,72447,12949],{"class":753},[747,72449,856],{"class":757},[747,72451,25977],{"class":802},[747,72453,72454,72456,72458],{"class":749,"line":761},[747,72455,12963],{"class":753},[747,72457,856],{"class":757},[747,72459,25358],{"class":802},[747,72461,72462,72464],{"class":749,"line":769},[747,72463,12973],{"class":753},[747,72465,758],{"class":757},[747,72467,72468,72470,72472],{"class":749,"line":776},[747,72469,12980],{"class":753},[747,72471,856],{"class":757},[747,72473,25399],{"class":802},[747,72475,72476,72478],{"class":749,"line":784},[747,72477,25378],{"class":753},[747,72479,758],{"class":757},[747,72481,72482,72484,72486],{"class":749,"line":790},[747,72483,25385],{"class":753},[747,72485,856],{"class":757},[747,72487,25399],{"class":802},[747,72489,72490,72492,72494],{"class":749,"line":796},[747,72491,25404],{"class":753},[747,72493,856],{"class":757},[747,72495,25409],{"class":802},[747,72497,72498,72500],{"class":749,"line":806},[747,72499,12990],{"class":753},[747,72501,758],{"class":757},[747,72503,72504,72506,72508],{"class":749,"line":814},[747,72505,25420],{"class":753},[747,72507,856],{"class":757},[747,72509,72510],{"class":1895}," 4\n",[747,72512,72513,72515],{"class":749,"line":822},[747,72514,25462],{"class":753},[747,72516,758],{"class":757},[747,72518,72519,72521],{"class":749,"line":830},[747,72520,21456],{"class":753},[747,72522,758],{"class":757},[747,72524,72525,72527],{"class":749,"line":836},[747,72526,25475],{"class":753},[747,72528,758],{"class":757},[747,72530,72531,72533,72535],{"class":749,"line":842},[747,72532,25482],{"class":753},[747,72534,856],{"class":757},[747,72536,25399],{"class":802},[747,72538,72539,72541,72543],{"class":749,"line":850},[747,72540,25500],{"class":753},[747,72542,856],{"class":757},[747,72544,25409],{"class":802},[747,72546,72547,72549],{"class":749,"line":863},[747,72548,25509],{"class":753},[747,72550,758],{"class":757},[747,72552,72553,72555],{"class":749,"line":869},[747,72554,55091],{"class":753},[747,72556,758],{"class":757},[747,72558,72559,72561,72563,72565],{"class":749,"line":877},[747,72560,14801],{"class":757},[747,72562,14804],{"class":753},[747,72564,856],{"class":757},[747,72566,72567],{"class":802}," YOUR_SECRET_NAME_HERE\n",[747,72569,72570,72572],{"class":749,"line":1015},[747,72571,25516],{"class":753},[747,72573,758],{"class":757},[747,72575,72576,72578,72580,72582],{"class":749,"line":1021},[747,72577,799],{"class":757},[747,72579,14804],{"class":753},[747,72581,856],{"class":757},[747,72583,24308],{"class":802},[747,72585,72586,72588,72590],{"class":749,"line":1027},[747,72587,25533],{"class":753},[747,72589,856],{"class":757},[747,72591,72592],{"class":802}," registry.example.com\u002Fatrost\u002Fpresentation-gitlab-k8s:__VERSION__\n",[747,72594,72595,72597,72599],{"class":749,"line":1033},[747,72596,25543],{"class":753},[747,72598,856],{"class":757},[747,72600,25548],{"class":802},[747,72602,72603,72605],{"class":749,"line":1039},[747,72604,25553],{"class":753},[747,72606,758],{"class":757},[747,72608,72609,72611,72613,72615],{"class":749,"line":1054},[747,72610,14801],{"class":757},[747,72612,29864],{"class":753},[747,72614,856],{"class":757},[747,72616,25586],{"class":1895},[747,72618,72619,72621],{"class":749,"line":1060},[747,72620,25591],{"class":753},[747,72622,758],{"class":757},[747,72624,72625,72627],{"class":749,"line":1066},[747,72626,25598],{"class":753},[747,72628,758],{"class":757},[747,72630,72631,72633,72635],{"class":749,"line":1081},[747,72632,25605],{"class":753},[747,72634,856],{"class":757},[747,72636,25610],{"class":802},[747,72638,72639,72641,72643],{"class":749,"line":1087},[747,72640,25615],{"class":753},[747,72642,856],{"class":757},[747,72644,25586],{"class":1895},[747,72646,72647,72649,72651],{"class":749,"line":1102},[747,72648,25624],{"class":753},[747,72650,856],{"class":757},[747,72652,14751],{"class":1895},[747,72654,72655,72657,72659],{"class":749,"line":1110},[747,72656,25633],{"class":753},[747,72658,856],{"class":757},[747,72660,25425],{"class":1895},[747,72662,72663,72665],{"class":749,"line":1117},[747,72664,25642],{"class":753},[747,72666,758],{"class":757},[747,72668,72669,72671],{"class":749,"line":1123},[747,72670,25598],{"class":753},[747,72672,758],{"class":757},[747,72674,72675,72677,72679],{"class":749,"line":1129},[747,72676,25605],{"class":753},[747,72678,856],{"class":757},[747,72680,25610],{"class":802},[747,72682,72683,72685,72687],{"class":749,"line":1142},[747,72684,25615],{"class":753},[747,72686,856],{"class":757},[747,72688,25586],{"class":1895},[747,72690,72691,72693,72695],{"class":749,"line":1150},[747,72692,25624],{"class":753},[747,72694,856],{"class":757},[747,72696,14751],{"class":1895},[747,72698,72699,72701,72703],{"class":749,"line":1157},[747,72700,25633],{"class":753},[747,72702,856],{"class":757},[747,72704,25425],{"class":1895},[6072,72706,72707,72711],{},[523,72708,72709],{},[584,72710,6189],{},[523,72712,55250,72713,55254],{},[567,72714,55253],{},[523,72716,25685,72717,25688,72719,25691,72721],{},[567,72718,25331],{},[567,72720,25331],{},[527,72722,25694],{"href":25694,"rel":72723},[531],[523,72725,25698,72726,587,72728,25705,72730,25708,72732,6374,72734,25713,72736,25716],{},[567,72727,25701],{},[567,72729,25704],{},[567,72731,25701],{},[567,72733,24000],{},[567,72735,24007],{},[567,72737,25704],{},[523,72739,25719,72740,25723,72742,25726,72744,25730,72746,25733,72748,7258],{},[567,72741,25722],{},[567,72743,25331],{},[567,72745,25729],{},[567,72747,25729],{},[567,72749,25736],{},[738,72751,72753],{"className":740,"code":72752,"language":742,"meta":743,"style":743},"apiVersion: v1\nkind: Service\nmetadata:\n  name: presentation-gitlab-k8s-__CI_ENVIRONMENT_SLUG__\n  namespace: presentation-gitlab-k8s\n  labels:\n      prometheus-scrape: \"true\"\nspec:\n  type: ClusterIP\n  ports:\n    - name: http-metrics\n      port: 8000\n      protocol: TCP\n  selector:\n    app: __CI_ENVIRONMENT_SLUG__\n",[567,72754,72755,72763,72771,72777,72785,72793,72799,72812,72818,72826,72832,72842,72850,72858,72864],{"__ignoreMap":743},[747,72756,72757,72759,72761],{"class":749,"line":750},[747,72758,12949],{"class":753},[747,72760,856],{"class":757},[747,72762,22608],{"class":802},[747,72764,72765,72767,72769],{"class":749,"line":761},[747,72766,12963],{"class":753},[747,72768,856],{"class":757},[747,72770,25758],{"class":802},[747,72772,72773,72775],{"class":749,"line":769},[747,72774,12973],{"class":753},[747,72776,758],{"class":757},[747,72778,72779,72781,72783],{"class":749,"line":776},[747,72780,12980],{"class":753},[747,72782,856],{"class":757},[747,72784,25373],{"class":802},[747,72786,72787,72789,72791],{"class":749,"line":784},[747,72788,13231],{"class":753},[747,72790,856],{"class":757},[747,72792,22408],{"class":802},[747,72794,72795,72797],{"class":749,"line":790},[747,72796,25378],{"class":753},[747,72798,758],{"class":757},[747,72800,72801,72804,72806,72808,72810],{"class":749,"line":796},[747,72802,72803],{"class":753},"      prometheus-scrape",[747,72805,856],{"class":757},[747,72807,969],{"class":757},[747,72809,5306],{"class":802},[747,72811,975],{"class":757},[747,72813,72814,72816],{"class":749,"line":806},[747,72815,12990],{"class":753},[747,72817,758],{"class":757},[747,72819,72820,72822,72824],{"class":749,"line":814},[747,72821,18593],{"class":753},[747,72823,856],{"class":757},[747,72825,25873],{"class":802},[747,72827,72828,72830],{"class":749,"line":822},[747,72829,25878],{"class":753},[747,72831,758],{"class":757},[747,72833,72834,72836,72838,72840],{"class":749,"line":830},[747,72835,18665],{"class":757},[747,72837,14804],{"class":753},[747,72839,856],{"class":757},[747,72841,25566],{"class":802},[747,72843,72844,72846,72848],{"class":749,"line":836},[747,72845,25895],{"class":753},[747,72847,856],{"class":757},[747,72849,25586],{"class":1895},[747,72851,72852,72854,72856],{"class":749,"line":842},[747,72853,25904],{"class":753},[747,72855,856],{"class":757},[747,72857,25576],{"class":802},[747,72859,72860,72862],{"class":749,"line":850},[747,72861,25430],{"class":753},[747,72863,758],{"class":757},[747,72865,72866,72868,72870],{"class":749,"line":863},[747,72867,25385],{"class":753},[747,72869,856],{"class":757},[747,72871,25399],{"class":802},[523,72873,25925,72874,25928,72876,25932,72878,25938,72881,25941,72883,25944,72885,25947,72887],{},[567,72875,25828],{},[567,72877,25931],{},[527,72879,25937],{"href":25935,"rel":72880},[531],[567,72882,25729],{},[567,72884,25931],{},[567,72886,25729],{},[527,72888,25950],{"href":25950,"rel":72889},[531],[523,72891,25954,72892,25957,72894,25960,72896,3052],{},[567,72893,158],{},[567,72895,25729],{},[567,72897,25963],{},[738,72899,72901],{"className":740,"code":72900,"language":742,"meta":743,"style":743},"apiVersion: extensions\u002Fv1beta1\nkind: Ingress\nmetadata:\n  name: presentation-gitlab-k8s-__CI_ENVIRONMENT_SLUG__\n  namespace: presentation-gitlab-k8s\n  annotations:\n    # letsencrypt support enabled (https:\u002F\u002Fgithub.com\u002Fjetstack\u002Fkube-lego)\n    kubernetes.io\u002Ftls-acme: \"true\"\n    # use the Kubernetes ingress \"nginx\"\n    kubernetes.io\u002Fingress.class: \"nginx\"\nspec:\n  tls:\n  - hosts:\n    - __CI_ENVIRONMENT_SLUG__-presentation-gitlab-k8s.example.com\n    secretName: tls-com-example-__CI_ENVIRONMENT_SLUG__-presentation-gitlab-k8s\n  rules:\n  - host: __CI_ENVIRONMENT_SLUG__-presentation-gitlab-k8s.example.com\n    http:\n      paths:\n      - path: \u002F\n        backend:\n          serviceName: presentation-gitlab-k8s-__CI_ENVIRONMENT_SLUG__\n          servicePort: 8000\n",[567,72902,72903,72911,72919,72925,72933,72941,72947,72952,72964,72969,72981,72987,72993,73001,73008,73017,73023,73033,73039,73045,73055,73061,73069],{"__ignoreMap":743},[747,72904,72905,72907,72909],{"class":749,"line":750},[747,72906,12949],{"class":753},[747,72908,856],{"class":757},[747,72910,25977],{"class":802},[747,72912,72913,72915,72917],{"class":749,"line":761},[747,72914,12963],{"class":753},[747,72916,856],{"class":757},[747,72918,25986],{"class":802},[747,72920,72921,72923],{"class":749,"line":769},[747,72922,12973],{"class":753},[747,72924,758],{"class":757},[747,72926,72927,72929,72931],{"class":749,"line":776},[747,72928,12980],{"class":753},[747,72930,856],{"class":757},[747,72932,25373],{"class":802},[747,72934,72935,72937,72939],{"class":749,"line":784},[747,72936,13231],{"class":753},[747,72938,856],{"class":757},[747,72940,22408],{"class":802},[747,72942,72943,72945],{"class":749,"line":790},[747,72944,25801],{"class":753},[747,72946,758],{"class":757},[747,72948,72949],{"class":749,"line":796},[747,72950,72951],{"class":772},"    # letsencrypt support enabled (https:\u002F\u002Fgithub.com\u002Fjetstack\u002Fkube-lego)\n",[747,72953,72954,72956,72958,72960,72962],{"class":749,"line":806},[747,72955,26033],{"class":753},[747,72957,856],{"class":757},[747,72959,969],{"class":757},[747,72961,5306],{"class":802},[747,72963,975],{"class":757},[747,72965,72966],{"class":749,"line":814},[747,72967,72968],{"class":772},"    # use the Kubernetes ingress \"nginx\"\n",[747,72970,72971,72973,72975,72977,72979],{"class":749,"line":822},[747,72972,26046],{"class":753},[747,72974,856],{"class":757},[747,72976,969],{"class":757},[747,72978,9530],{"class":802},[747,72980,975],{"class":757},[747,72982,72983,72985],{"class":749,"line":830},[747,72984,12990],{"class":753},[747,72986,758],{"class":757},[747,72988,72989,72991],{"class":749,"line":836},[747,72990,26065],{"class":753},[747,72992,758],{"class":757},[747,72994,72995,72997,72999],{"class":749,"line":842},[747,72996,1721],{"class":757},[747,72998,26074],{"class":753},[747,73000,758],{"class":757},[747,73002,73003,73005],{"class":749,"line":850},[747,73004,18665],{"class":757},[747,73006,73007],{"class":802}," __CI_ENVIRONMENT_SLUG__-presentation-gitlab-k8s.example.com\n",[747,73009,73010,73012,73014],{"class":749,"line":863},[747,73011,26098],{"class":753},[747,73013,856],{"class":757},[747,73015,73016],{"class":802}," tls-com-example-__CI_ENVIRONMENT_SLUG__-presentation-gitlab-k8s\n",[747,73018,73019,73021],{"class":749,"line":869},[747,73020,26108],{"class":753},[747,73022,758],{"class":757},[747,73024,73025,73027,73029,73031],{"class":749,"line":877},[747,73026,1721],{"class":757},[747,73028,4591],{"class":753},[747,73030,856],{"class":757},[747,73032,73007],{"class":802},[747,73034,73035,73037],{"class":749,"line":1015},[747,73036,26125],{"class":753},[747,73038,758],{"class":757},[747,73040,73041,73043],{"class":749,"line":1021},[747,73042,26132],{"class":753},[747,73044,758],{"class":757},[747,73046,73047,73049,73051,73053],{"class":749,"line":1027},[747,73048,799],{"class":757},[747,73050,26141],{"class":753},[747,73052,856],{"class":757},[747,73054,26146],{"class":802},[747,73056,73057,73059],{"class":749,"line":1033},[747,73058,26151],{"class":753},[747,73060,758],{"class":757},[747,73062,73063,73065,73067],{"class":749,"line":1039},[747,73064,26158],{"class":753},[747,73066,856],{"class":757},[747,73068,25373],{"class":802},[747,73070,73071,73073,73075],{"class":749,"line":1054},[747,73072,26167],{"class":753},[747,73074,856],{"class":757},[747,73076,25586],{"class":1895},[523,73078,73079,25947,73081,26179,73084,26183,73086,8287,73088,587,73090,26190,73092,587,73094,26197],{},[567,73080,158],{},[527,73082,18226],{"href":18226,"rel":73083},[531],[567,73085,26182],{},[567,73087,25701],{},[567,73089,24007],{},[567,73091,24000],{},[567,73093,26193],{},[567,73095,26196],{},[6072,73097,73098],{},[523,73099,73100,55699,73102,12566,73105,55709],{},[584,73101,6189],{},[527,73103,55703],{"href":26209,"rel":73104},[531],[527,73106,55708],{"href":55706,"rel":73107},[531],[523,73109,73110],{},"Now that we have all the manifests in the repository, we can move on to the next step.",[535,73112,26219],{"id":26218},[523,73114,26222,73115,26225],{},[567,73116,23716],{},[738,73118,73119],{"className":1621,"code":26228,"language":1623,"meta":743,"style":743},[567,73120,73121,73129,73139,73155],{"__ignoreMap":743},[747,73122,73123,73125,73127],{"class":749,"line":750},[747,73124,1919],{"class":1630},[747,73126,26237],{"class":802},[747,73128,26240],{"class":802},[747,73130,73131,73133,73135,73137],{"class":749,"line":761},[747,73132,1919],{"class":1630},[747,73134,22393],{"class":802},[747,73136,26249],{"class":802},[747,73138,26240],{"class":802},[747,73140,73141,73143,73145,73147,73149,73151,73153],{"class":749,"line":769},[747,73142,1919],{"class":1630},[747,73144,22393],{"class":802},[747,73146,26260],{"class":802},[747,73148,3368],{"class":802},[747,73150,3892],{"class":757},[747,73152,26267],{"class":802},[747,73154,975],{"class":757},[747,73156,73157,73159,73161],{"class":749,"line":776},[747,73158,1919],{"class":1630},[747,73160,22393],{"class":802},[747,73162,26278],{"class":802},[523,73164,26281],{},[523,73166,73167,73168,26287],{},"Now you should see GitLab creating a \"new\" pipeline and running the stages, which you specified in the ",[567,73169,23716],{},[523,73171,73172],{},[3069,73173],{"alt":73174,"src":73175},"GitLab - Pipeline List","\u002Fblog\u002F2017\u002Fgitlab-kubernetes-perfect-match-for-continuous-delivery-with-container\u002Fphoto04.png",[523,73177,26302],{},[523,73179,73180],{},[3069,73181],{"alt":73182,"src":73183},"GitLab - New Pipeline Overview","\u002Fblog\u002F2017\u002Fgitlab-kubernetes-perfect-match-for-continuous-delivery-with-container\u002Fphoto05.png",[523,73185,73186,73187,32212],{},"The last stage shows if you did everything correct. If it passes you now have successfully deployed your application to your Kubernetes cluster.\nA successful stage \"build\" ",[567,73188,22363],{},[523,73190,73191],{},[3069,73192],{"alt":73193,"src":73194},"GitLab - deploy_dev job passed","\u002Fblog\u002F2017\u002Fgitlab-kubernetes-perfect-match-for-continuous-delivery-with-container\u002Fphoto06.png",[523,73196,26324,73197,26327],{},[567,73198,23716],{},[535,73200,207],{"id":26330},[613,73202,26334],{"id":26333},[523,73204,26337],{},[613,73206,26341],{"id":26340},[668,73208,73209,73213],{},[638,73210,26346,73211,26349],{},[567,73212,23716],{},[638,73214,73215,73216,73218],{},"Did you replace all the example domains ",[567,73217,23746],{}," with your own correct addresses?",[535,73220,14526],{"id":14525},[523,73222,73223],{},"I hope this helps you, getting started with using GitLab CI in combination with Kubernetes for Continuous Delivery of your application(s).\nFor questions about the post, please leave a comment below, thanks!\nI'm maybe going to create a post about how I run GitLab and GitLab CI runner on top of Kubernetes in the near future too.",[523,73225,13967],{},[2890,73227,73228],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":743,"searchDepth":761,"depth":761,"links":73230},[73231,73232,73233,73236,73237,73238,73239,73240,73241,73242,73243,73244,73245,73249],{"id":70809,"depth":761,"text":70810},{"id":70848,"depth":761,"text":70849},{"id":537,"depth":761,"text":538,"children":73234},[73235],{"id":22267,"depth":769,"text":22268},{"id":70914,"depth":761,"text":70915},{"id":22346,"depth":761,"text":22347},{"id":53240,"depth":761,"text":22308},{"id":23316,"depth":761,"text":23317},{"id":71391,"depth":761,"text":71392},{"id":23712,"depth":761,"text":26397},{"id":25160,"depth":761,"text":25161},{"id":25322,"depth":761,"text":25323},{"id":26218,"depth":761,"text":26219},{"id":26330,"depth":761,"text":207,"children":73246},[73247,73248],{"id":26333,"depth":769,"text":26334},{"id":26340,"depth":769,"text":26341},{"id":14525,"depth":761,"text":14526},"2017-07-04T17:08:36+02:00","This post shows possibilites on how to use GitLab in combination with Kubernetes to contionously deliver your applications with Container.",{"src":73253},"\u002Fblog\u002F2017\u002Fgitlab-kubernetes-perfect-match-for-continuous-delivery-with-container\u002Fgitlab-kubernetes-perfect-match-for-continuous-delivery-with-container.png",{"tags":73255},[26413,26414,124,26415],"\u002Fblog\u002F2017\u002Fgitlab-kubernetes-perfect-match-for-continuous-delivery-with-container",{"title":22255,"description":73251},"3.blog\u002F2017\u002Fgitlab-kubernetes-perfect-match-for-continuous-delivery-with-container","LgTujnZlcnQFDP9rfSRD-l8qg_If053GOGm4M9EcrBo",{"id":73261,"title":73262,"authors":73263,"badge":518,"body":73266,"date":73305,"description":73306,"extension":2911,"image":73307,"meta":73308,"navigation":1254,"path":73310,"seo":73311,"stem":73312,"__hash__":73313},"posts\u002F3.blog\u002F2017\u002Fcontainer-linux-specification-yaml.md","Container Linux: Specification YAML",[73264],{"name":514,"to":515,"avatar":73265},{"src":517},{"type":520,"value":73267,"toc":73303},[73268,73276,73286,73295,73298,73300],[523,73269,73270,73271,73275],{},"I checked the Container Linux configuration page and found the config specification here: ",[527,73272,73273],{"href":73273,"rel":73274},"https:\u002F\u002Fcoreos.com\u002Fos\u002Fdocs\u002Flatest\u002Fconfiguration.html",[531]," (link refers to the latest version, the current version can be seen in the below field).\nBut it was presented as a HTML list, which I thought is bad and took it upon me to create a YAML version from it for easy use.",[6072,73277,73278],{},[523,73279,73280,8287,73283],{},[584,73281,73282],{},"CURRENT VERSION",[567,73284,73285],{},"1451.2.0",[523,73287,73288,73289,73294],{},"The result can be found on ",[527,73290,73293],{"href":73291,"rel":73292},"https:\u002F\u002Fgist.github.com\u002Fgalexrt\u002F198b2738585b3000092ac3d1382fcfc3",[531],"GitHub Gist"," or simply below in the embeded Gist:",[19016,73296],{"src":73297},"https:\u002F\u002Fgist.github.com\u002Fgalexrt\u002F198b2738585b3000092ac3d1382fcfc3.js",[523,73299,13967],{},[523,73301,73302],{},"P.S. I try my best to keep it up to date. If you should notice it being outdated, please let me know by comment or email. Thanks!",{"title":743,"searchDepth":761,"depth":761,"links":73304},[],"2017-07-01T16:14:21+02:00","The Container Linux config specification as a YAML template.",{"src":68043},{"tags":73309},[26415,58416],"\u002Fblog\u002F2017\u002Fcontainer-linux-specification-yaml",{"title":73262,"description":73306},"3.blog\u002F2017\u002Fcontainer-linux-specification-yaml","F5e7w8Y7nh1JF_l-BTdtRDTGKzaSlvcL47mLSnjd2D0",{"id":73315,"title":73316,"authors":73317,"badge":518,"body":73320,"date":73639,"description":73640,"extension":2911,"image":73641,"meta":73642,"navigation":1254,"path":73646,"seo":73647,"stem":73648,"__hash__":73649},"posts\u002F3.blog\u002F2017\u002Fgoogle-cloud-enterprise-grade-hybrid-cloud-with-kubernetes-cluster-federation.md","Google Cloud: Enterprise Grade Hybrid Cloud with Kubernetes Cluster Federation",[73318],{"name":514,"to":515,"avatar":73319},{"src":517},{"type":520,"value":73321,"toc":73631},[73322,73324,73327,73334,73337,73340,73342,73346,73352,73355,73357,73361,73370,73373,73376,73379,73382,73385,73388,73390,73394,73414,73425,73440,73443,73456,73469,73472,73475,73493,73496,73504,73518,73529,73531,73535,73548,73551,73554,73562,73565,73568,73571,73574,73588,73599,73605,73608,73614,73617,73619,73621,73624,73626],[535,73323,538],{"id":537},[523,73325,73326],{},"I went to the Google Cloud Event about \"Enterprise Grade Hybrid Cloud with Kubernetes Cluster Federation\" at Google Munich.",[6072,73328,73329],{},[523,73330,73331,73333],{},[584,73332,6189],{}," I wrote the next few sentences while not having internet connection because of \"DeutscheBahn\" ;)",[523,73335,73336],{},"A thing I just have to note is that I had taken an IC instead of an ICE to Munich. Now guess what, ICs don't have wifi.. I personally think that in a county as advanced as Germany, it should be \"required\" to have wifi on \"every\" train. Maybe not trams but at least ICs and ECs too instead of only ICEs.\nI could solve my problem by using my phone as a hotspot which was just as unreliable as the internet in the ICE, but at least I had a bit of internet, so I got that going for me which is nice. Another awesome thing was that my seat's outlet wasn't working..",[523,73338,73339],{},"At least I arrived without any delays and hope that this \"lucky\" strike keeps on going when I travel back home.",[2979,73341],{},[535,73343,73345],{"id":73344},"first-impression","First impression",[523,73347,73348],{},[3069,73349],{"alt":73350,"src":73351},"Google Isar Valley Room - Google Cloud CoreOS Event Photo 1","\u002Fblog\u002F2017\u002Fgoogle-cloud-enterprise-grade-hybrid-cloud-with-kubernetes-cluster-federation\u002Fphoto0.png",[523,73353,73354],{},"So it's my first time at Google and I have to say it is awesome. If you ever have the chance to go to an event at Google, go for it! :)",[2979,73356],{},[535,73358,73360],{"id":73359},"google-cloud-in-a-multi-cloud-world","\"Google Cloud in a multi-cloud world\"",[523,73362,73363,73364,73369],{},"This sort of intro to the event was held by ",[527,73365,73368],{"href":73366,"rel":73367},"https:\u002F\u002Ftwitter.com\u002Fjensbussmann",[531],"Jens Bussmann",". He works at Google and realised the event.\nGoogle starts about two billion containers per week (the number is already some years old), but from an outside perspective you can easily account for the growth Google had in the last few years and know that the number is definetely higher already but not announced (yet).\nContainers are used for over ten years at Google and one of the simplest reasons is that they are easier to move and scale. Moving three containers is simpler than moving three VMs. The same goes for scaling. It's just as it is. Some people may argue that with Google's VM live migration for their Google Cloud Plattform they would use VMs more, but that technology just wasn't available when they \"started\" doing containers.",[523,73371,73372],{},"How did it come to Kubernetes?\nI can't really say too much about that, as Google as keeps itself very quiet about Borg and so on, but from what I know.\nBorg started as their go-to-scheduler. Then for running more and more containers, a fork of some sort from Borg was created and called Omega.\nAt one point Google decided to take the years of experience and put them into the community. This was done by creating the Kubernetes project.\nThe Kubernetes project now is one of the biggest open source projects out there and combines simplicity with flexibility for container orchestration.\nIf you now take a look at the project, you say that from Google and the community perspective it was a huge success, putting Kubernetes out there.",[523,73374,73375],{},"We all know it, but yes Google also runs applications, just like everyone else. Google is continuing to improve Kubernetes, not only to match the community but also try make it fit for their own application workloads. As currently most applications at Google don't run in Kubernetes, they will slowly transition to run them in Kubernetes too.\nNowadays Google engineers, looking at the percentage, commit less to Kubernetes. But there is a very good reason for that. The reason is that there are now just more \"outside\" collaborators that have caused the \"commit percentage\" (by company) to drop for Google engineers. A very positive message that the community is sending with that \"response\" to the project.",[523,73377,73378],{},"Kubernetes currently supports up to about 5k nodes or 150k pods. Even Google \"admitted\" that they and no other company is running more than that and asking the audience also showed the same results for other Kubernetes (\u002F Container) users. Most \"users\" are like \"We need at least over 5k nodes for running enterprise applications on Kubernetes\" but \"in real life\" some of these companies don't even run more than 100 nodes at the same time in the same cluster..",[523,73380,73381],{},"If size should ever matter (I hope you see what I did there ;) ), Federation can help by mitigating this \"issue\" by splitting the \"load\" (pods, etc) over multiple cluster.\nOther advantages to see when looking at running a hybrid cloud setup with federation is that (when doing it correctly) you get a nice way to do failover with increased control over your data. As big companies more and more have the need to run on-premise, this also allows for running sensitive data applications on-premise and run other tasks on the cloud (aka on demand). Let's take germany as an example for data protection laws, to get more trust from customers too, you have to run on-premise to comply with law and make customers feel safe about their data.",[523,73383,73384],{},"For Google to step up with the Kubernetes project was a good thing to do. Google simply knows how to scale applications, as they have seven products that have more than one billion active users! Google Cloud Plattform is no exception to that many \"users\".\nFrom the outside it definetely looks like they know what to do to scale effectively and with efficiency in mind.\nGoogle utilizes their technology so efficiently that they can handle high load situations without so called pre-warming of their applications.",[523,73386,73387],{},"Summarized I can say that Google has with their years of experience and technology what it takes for them, as we saw with the Kubernetes project, to stand up and create a good cloud (Google Cloud Plattform) and an even better container orchestration tool. Their Google Cloud Plattform with their VM live migration and other very interesting features, has definetely what it takes to step up to the plate of AWS and other providers, to put the tide for a \"good\" cloud provider even higher and keep it their for a long time.",[2979,73389],{},[535,73391,73393],{"id":73392},"tectonic-self-driving-kubernetes-for-on-premise-and-cloud","\"Tectonic: Self-driving Kubernetes for on-premise and cloud\"",[523,73395,73396,73401,73402,73407,73408,73413],{},[527,73397,73400],{"href":73398,"rel":73399},"https:\u002F\u002Ftwitter.com\u002Fpst418",[531],"Philipp Strube"," is General Manager at ",[527,73403,73406],{"href":73404,"rel":73405},"https:\u002F\u002Fcoreos.com\u002F",[531],"CoreOS"," and he held the presentation about ",[527,73409,73412],{"href":73410,"rel":73411},"https:\u002F\u002Fcoreos.com\u002Ftectonic\u002F",[531],"Tectonic"," which self-drives Kubernetes to a certain aspect.",[6072,73415,73416],{},[523,73417,73418,73420,73421,73424],{},[584,73419,6189],{}," I like the company \"motto\"\u002Fslogan:\n\"Secutring the Internet\" - ",[527,73422,73406],{"href":73404,"rel":73423},[531],"\nAlso there aren't many companies that can say, that (almost) all of their projects are open source.",[523,73426,73427,73428,73433,73434,73439],{},"Earlier called CoreOS, now called Container Linux is an extermely lightweight linux with an update scheme like Chrome OS (two partition updating) is used in combination with their \"newest\" creation called \"Tectonic\".\nTectonic is for simple management of updates for the Container Linux hosts. For example the update process, ensures that not all servers go down for a reboot. The application used for that is ",[527,73429,73432],{"href":73430,"rel":73431},"https:\u002F\u002Fgithub.com\u002Fcoreos\u002Flocksmith",[531],"locksmith",", available on GitHub.\nTectonic overall makes Kubernetes much more \"supportable\"\u002F\"maintainable\" by \"automatically\" adding features like authentication using their ",[527,73435,73438],{"href":73436,"rel":73437},"https:\u002F\u002Fgithub.com\u002Fcoreos\u002Fdex",[531],"Dex"," project, which allows for LDAP authentication and is also available on GitHub.",[523,73441,73442],{},"The Terraform \"language\" is utilized for the \"description\" of the servers and components. You can easily use the installer to create one cluster after another by changing just some variables in the variable file for Terraform.\nCoreOS makes sure with every update, that you have what you need to run Kubernetes with Tectonic, the best example for that is the what I call the version fiasco of Docker, when they changed to using \"dates\" in their version \"numbers\" which resulted in Kubernetes having problems with using it and also having issues with the \"quick\" API changes.",[523,73444,73445,73446,73449,73450,73455],{},"A project called ",[567,73447,73448],{},"bootkube"," that is currently in the ",[527,73451,73454],{"href":73452,"rel":73453},"https:\u002F\u002Fgithub.com\u002Fkubernetes-incubator\u002Fbootkube",[531],"Kubernetes project incubator",", is used for bootstraping Kubernetes using Kubernetes. It allows to sort of run Kubernetes in Kubernetes for the bootstrap process.",[523,73457,73458,73459,73462,73463,73468],{},"Operators strike again! Operators are used extensively when running Tectonic. One of them is used for checking the undelying hosts for Container Linux updates and would then also trigger the reboot for the update, and the ",[527,73460,25937],{"href":25935,"rel":73461},[531]," is used for the monitoring part inside the cluster.\nAnother mentioned operator from CoreOS is the ",[527,73464,73467],{"href":73465,"rel":73466},"https:\u002F\u002Fgithub.com\u002Fcoreos\u002Fetcd-operator",[531],"etcd-operator",". As the name implies it \"operates\" etcd in Kubernetes, when enabling an experimental flag the etcd-operator also sets up etcd in the cluster.",[523,73470,73471],{},"The operators should later on reliably manage the \"applications\" to keep the \"manual\" maintenance as low as possible.",[523,73473,73474],{},"Through the abstraction that Tectonic brings with using Terraform you can easily re-run\u002Fapply the given configuration and change it as wanted. In the end it doesn't and shouldn't really matter which cloud provider you are using (AWS, GCP, Azure, \"Bare Metal\", etc). It feels a bit like a managed Kubernetes cluster with lower manual maintenance required.",[523,73476,73477,73478,73480,73481,73483,73484,73487,73488,73492],{},"The demo showed a Tectonic Kubernetes cluster running on the Google Cloud Plattform, which is still in a pretty beta state, as seen on the Tectonic documentation page. He said that the next release will contain the feature to imitate Kubernetes ",[567,73479,61680],{}," to see what they can do. This will make creating ",[567,73482,61680],{}," definetely simpler to see which things they are able to do or not to.\nThe Tectonic installer automatically creates ",[567,73485,73486],{},"Ingres","es for ",[527,73489,292],{"href":73490,"rel":73491},"https:\u002F\u002Fgithub.com\u002Fprometheus\u002Fprometheus",[531]," and the Tectonic admin web interface.",[523,73494,73495],{},"As always I can confirm, that operators are are cool and the prometheus-operator in specific is very cool, but to have equality here, all operators are cool! ;)",[523,73497,73498,73499,1909],{},"For curious people that know the Terraform \"language\", the Tectonic installer is available on GitHub here: ",[527,73500,73503],{"href":73501,"rel":73502},"https:\u002F\u002Fgithub.com\u002Fcoreos\u002Ftectonic-installer",[531],"coreos\u002Ftectonic-installer",[523,73505,73506,73507,587,73512,73517],{},"I already had the chance to experience the simplicity of the Tectonic installer (at least for the AWS plattform) at the Container Days workshop by ",[527,73508,73511],{"href":73509,"rel":73510},"https:\u002F\u002Fgithub.com\u002Fmxinden",[531],"Max Inden",[527,73513,73516],{"href":73514,"rel":73515},"https:\u002F\u002Fgithub.com\u002Falexsomesan",[531],"Alex Somesan"," this year, but the presentation just strengthened some points I made:",[668,73519,73520,73523,73526],{},[638,73521,73522],{},"Operators are awesome!",[638,73524,73525],{},"Tectonic is a nice way to self-drive Kubernetes cluster.",[638,73527,73528],{},"Using Tectonic to install\u002Frun multiple Kubernetes cluster and use Federation with them seems to be a good way for creating a hybrid cloud environment.",[2979,73530],{},[535,73532,73534],{"id":73533},"federation-benefits-real-world-use-cases-and-best-practices","\"Federation: Benefits, real world use-cases and best practices\"",[523,73536,73537,73538,18501,73543,1909],{},"The presentation was held by ",[527,73539,73542],{"href":73540,"rel":73541},"https:\u002F\u002Ftwitter.com\u002Fmichmueller_",[531],"Michael Mueller",[527,73544,73547],{"href":73545,"rel":73546},"https:\u002F\u002Fcontainer-soultions.com",[531],"Container Solutions",[523,73549,73550],{},"He brought up some examples of \"extreme\" IT outages.\nThe first example was the British Airways in May 2017 when they had an UPS failure that caused one of their datacenters to go mostly down. It took about 2.5 days for them to recover from this failure. They had a second datacenter in place but hadn't tested the failover to the other datacenter.\nThe next one, was a storage failure at Microsoft Azure in November 2014. At Azure through a single button click the software was deployed by one developer which caused the system to overload due to an application issue and fail. The outage was about 11 hours and 11 Azure datacenters were affected by this.\nWho doesn't remember the day the internet couldn't load it's \"static\" content. A software (and automation?) misconfiguration caused the AWS S3 service to be done for one of Amazon's region. For the applications that had used just this one region, the conclusion is to not only use one S3 zone for their data, but also have failsafes for service outages like the data \"backed up\" by at least a second zone.",[523,73552,73553],{},"He showed a quote from the Amazon CTO:",[6072,73555,73556],{},[523,73557,73558,73561],{},[584,73559,73560],{},"QUOTE"," Werner Vogels, Amazon CTO\n\"Everything fails, all the time\"",[523,73563,73564],{},"From my point of view, applications need to be additionally tested on how to \"react\" when dependent services have failures\u002Foutages. This then could be used to improve the response from the applications and lower the impact for users.",[523,73566,73567],{},"But now to the all awaited point \"How can Federation 'fix' this problem?\" (or at least try to make it better).\nSo first at all, there is no \"real\" fix for this problem. There will always be outages, you can just protect yourself by adding more, so to say, points of \"failure\".\nAn important fact is that overall Kubernetes federation is vendor indepedent. You can run it anywhere it would normally run too. It can be seen as a bridge between the on-premise and cloud Kubernetes cluster.",[523,73569,73570],{},"How can Federation \"fix\" this problem? It can \"fixed\" by deploying applications into multiple Kubernetes cluster (in the best scenario are hosted at various cloud providers).\nHybrid cloud is not good when still keeping old structures, that may even still contain \"bad\" failover strategies (especially with manual failover triggering required).\nOn failure the traffic can\u002Fis \"re-routed\" (by DNS changes or globally routed\u002Fswitched failover IPs) to the other remaining datacenters.",[523,73572,73573],{},"For running federation you need\u002Fshould have:",[668,73575,73576,73579,73582,73585],{},[638,73577,73578],{},"Multiple Kubernetes cluster",[638,73580,73581],{},"Federation control plane (at least one)",[638,73583,73584],{},"A supported DNS provider (with some sort of health checks)",[638,73586,73587],{},"Bonus points for a global distributed load balancing solution (examples are Google GIP or for HTTP \"only\" applications CDNs like: Akamai, Fastly and Cloudflare)",[523,73589,73590,73594,73595,73598],{},[3069,73591],{"alt":73592,"src":73593},"Federation structure - From CoreOS","https:\u002F\u002Fcoreos.com\u002Fsites\u002Fdefault\u002Ffiles\u002Finline-images\u002Ffederation-api-4x.png","\nThis diagram from ",[527,73596,73406],{"href":73404,"rel":73597},[531]," shows the Kubernetes federation structure pretty good.",[523,73600,8764,73601,73604],{},[567,73602,73603],{},"Federation Controller Manager"," by default \"divides\" the workload by cluster. For example you want 100 pods on a federation with 3 cluster, by default this will result in ~33 pods on each cluster.",[523,73606,73607],{},"In the demo he showed a simple world map UI that is able to enable and disable zones with buttons click. It showed the request of \"users\" where they got routed. They were always routed to the nearest Kubernetes cluster using the Google Cloud Plattform Global IP feature.",[523,73609,73610,73611,73613],{},"When you want to use federation in production, please keep in mind that it is still under heavy development, but with the Kubernetes 1.7 release there will be some mayor improvements to federation. Also to note is that some features like ",[567,73612,52826],{}," are not working\u002Fimplemented (yet) in federation.\nFor the federation control plane there is also no \"automatic\" HA without a lot of manual work around it possible.",[523,73615,73616],{},"Federation ovrall eases the orchestration of multiple cluster\u002Fzones, but you still need applications that support \"cross zone\u002Fdatacenter replication\".\nFederation overall is just for controlling\u002F\"scheduling\" of workload, for example it doesn't \"mess\" with DNS, network and other stuff. The control plane will only do some labeling at the object level to make identifying objects easier on a per cluster basis simpler.\nTo take operators into the view again, there is definetely again a worthy point for creating operators for simpler usage for applications across multiple zones and failover of them, example usage would be automatic switching replication to zones on or off depending on their state.",[2979,73618],{},[535,73620,14526],{"id":14525},[523,73622,73623],{},"The event was very informative. The presentations and discussions held were very interesting.",[523,73625,13967],{},[523,73627,73628,73630],{},[584,73629,53029],{},": Please let me know (by comment or email), if there is anything I can improve to make this post about the event even better. Thanks for reading!",{"title":743,"searchDepth":761,"depth":761,"links":73632},[73633,73634,73635,73636,73637,73638],{"id":537,"depth":761,"text":538},{"id":73344,"depth":761,"text":73345},{"id":73359,"depth":761,"text":73360},{"id":73392,"depth":761,"text":73393},{"id":73533,"depth":761,"text":73534},{"id":14525,"depth":761,"text":14526},"2017-06-29T09:14:45+02:00","These are my thoughts and notes about the presentation and overall the Google Cloud Kubernetes Federation event itself.",{"src":73351},{"tags":73643},[26415,73644,73645,124],"Google Cloud","Event","\u002Fblog\u002F2017\u002Fgoogle-cloud-enterprise-grade-hybrid-cloud-with-kubernetes-cluster-federation",{"title":73316,"description":73640},"3.blog\u002F2017\u002Fgoogle-cloud-enterprise-grade-hybrid-cloud-with-kubernetes-cluster-federation","thhP5rStdIEyG9R0UPWQt0QKK03ViNheEFiGtwOzD3M",{"id":73651,"title":73652,"authors":73653,"badge":518,"body":73656,"date":74510,"description":74511,"extension":2911,"image":74512,"meta":74513,"navigation":1254,"path":74515,"seo":74516,"stem":74517,"__hash__":74518},"posts\u002F3.blog\u002F2017\u002Fcontainer-days-2017-hamburg.md","Container Days 2017 Hamburg",[73654],{"name":514,"to":515,"avatar":73655},{"src":517},{"type":520,"value":73657,"toc":74489},[73658,73660,73668,73682,73684,73686,73689,73693,73707,73713,73719,73722,73724,73728,73742,73748,73751,73753,73755,73758,73784,73787,73796,73798,73802,73812,73832,73847,73857,73900,73910,73926,73930,73938,73945,73953,73960,73975,73981,73989,74017,74029,74036,74040,74058,74060,74062,74065,74069,74077,74083,74086,74111,74114,74118,74121,74124,74130,74138,74144,74154,74162,74164,74170,74185,74187,74190,74194,74206,74213,74216,74219,74225,74238,74249,74256,74260,74272,74275,74281,74284,74287,74290,74301,74304,74313,74316,74322,74335,74338,74342,74354,74364,74386,74392,74402,74408,74419,74428,74432,74441,74456,74458,74460,74477,74480,74483,74487],[535,73659,13457],{"id":13456},[523,73661,73662,73663,73667],{},"A huge thanks and shoutout to ",[527,73664,73666],{"href":73509,"rel":73665},[531],"Max Inden @mxinden"," for having some time for a very interesting talk.",[523,73669,73670,73673,73674,73677,73678,73681],{},[584,73671,73672],{},"BTW"," Checkout ",[527,73675,73406],{"href":73404,"rel":73676},[531],"'s awesome Kubernetes ",[527,73679,25937],{"href":25935,"rel":73680},[531]," project. It is awesome for easily running Prometheus + Alertmanager in Kubernetes.",[2979,73683],{},[535,73685,52419],{"id":52418},[523,73687,73688],{},"Let's see what nice things the day will bring. I hope I'll learn something new about containers and Kubernetes, and hopefully meet some new people. :-)",[613,73690,73692],{"id":73691},"presentation-a-devops-state-of-mind-continuous-security-for-containers-with-kubernetes","Presentation: \"A DevOps State of Mind: Continuous Security for Containers with Kubernetes\"",[523,73694,73695,73696,18501,73701,73706],{},"The presentation of ",[527,73697,73700],{"href":73698,"rel":73699},"https:\u002F\u002Ftwitter.com\u002Fchrisvantuin",[531],"Chris van Tuin",[527,73702,73705],{"href":73703,"rel":73704},"https:\u002F\u002Fwww.redhat.com\u002Fen",[531],"Red Hat"," was very interesting for me. I'm going to attach a small diagram of what I have taken from it.",[523,73708,73709],{},[3069,73710],{"alt":73711,"src":73712},"My own diagram of what I think was the message of Chris van Tuin from Red Hat with his presentation.","\u002Fblog\u002F2017\u002Fcontainer-days-2017-hamburg\u002Fcds2017-photo0.png",[523,73714,73715],{},[3069,73716],{"alt":73717,"src":73718},"Quick photo of the crowd and one of the slides of the presentation.","\u002Fblog\u002F2017\u002Fcontainer-days-2017-hamburg\u002Fcds2017-photo1.png",[523,73720,73721],{},"For me what counted here, was the message (see the diagram above) I got from the presentation. Interesting isn't only to write, but also to discuss about it at the conference.",[2979,73723],{},[613,73725,73727],{"id":73726},"presentation-deploy-a-resilient-e-commerce-platform-using-latest-docker-tools","Presentation: \"Deploy a resilient E-commerce platform using latest docker tools\"",[523,73729,73730,73731,18501,73736,73741],{},"Next presentation I went to was \"Deploy a resilient E-commerce platform using latest docker tools\" of ",[527,73732,73735],{"href":73733,"rel":73734},"https:\u002F\u002Fgithub.com\u002Fxinity",[531],"Rachid Zarouali",[527,73737,73740],{"href":73738,"rel":73739},"https:\u002F\u002Fwww.synolia.com\u002F",[531],"SYNOLIA",".\nHe gave some interesting insights in their E-commerce platform, in which they weren't \"simply\" using Kubernetes. As the title from the presentation suggets, the tools used by them are mostly official Docker tools\u002Fprojects, but also some other open source projects too.",[523,73743,73744,73747],{},[584,73745,73746],{},"For Kubernetes users",": Just keep on using Kubernetes ;)",[523,73749,73750],{},"Overall a well made presentation, as written with good insights into the tooling used. Should be interesting for everyone that has to decide between Kubernetes and Docker Swarm.",[2979,73752],{},[613,73754,52763],{"id":52762},[523,73756,73757],{},"I'll just point you to my Tweet for a \"proper\" response to that:",[6072,73759,73761,73779,73780],{"className":73760,"dataLang":18973},[18972,52946],[523,73762,73763,8287,73767,73770,73771,8287,73775],{"lang":18973,"dir":18976},[527,73764,73766],{"href":73765},"https:\u002F\u002Ftwitter.com\u002Fmesosphere","@mesosphere",[527,73768,52963],{"href":73769},"https:\u002F\u002Ftwitter.com\u002FConDaysEU"," Your \"cloud\" burgers are delicious! ",[527,73772,73774],{"href":73773},"https:\u002F\u002Ftwitter.com\u002Fhashtag\u002FCDS17?src=hash","#CDS17",[527,73776,73778],{"href":73777},"https:\u002F\u002Ft.co\u002Fg1cpkd81rN","pic.twitter.com\u002Fg1cpkd81rN","— galexrt (@galexrt) ",[527,73781,73783],{"href":73782},"https:\u002F\u002Ftwitter.com\u002Fgalexrt\u002Fstatus\u002F877127039479926784","June 20, 2017",[19016,73785],{"async":1254,"src":73786,"charSet":19019},"\u002F\u002Fplatform.twitter.com\u002Fwidgets.js",[523,73788,73789,73790,73795],{},"To summarize it, the pulled pork burger I had was delicious! Good on the ",[527,73791,73794],{"href":73792,"rel":73793},"http:\u002F\u002Fbigbenburgertruck.de\u002F",[531],"Big Ben Burger Truck Hamburg"," guys for that.",[2979,73797],{},[613,73799,73801],{"id":73800},"workshop-kubernetes-anywhere-production-ready-with-prometheus","Workshop: \"Kubernetes Anywhere, Production Ready with Prometheus\"",[523,73803,73804,73805,587,73808,73811],{},"The workshop was held by ",[527,73806,73666],{"href":73509,"rel":73807},[531],[527,73809,73516],{"href":73514,"rel":73810},[531],".\nI couldn't really create my own cluster on AWS for testing, as my AWS account gave me some trouble to first sort out.",[523,73813,73814,73815,73818,73819,73822,73823,73825,73826,73828,73829,73831],{},"It is very interesting to see ",[527,73816,73412],{"href":73410,"rel":73817},[531]," create the cluster with such simplicity. As I already worked with the prometheus-operator there wasn't that much new I could learn about, but at least I could collect some more experience on how to better create\u002Fuse the prometheus-operator ",[567,73820,73821],{},"ServiceMonitor","s.\nThe approach for using ",[567,73824,73821],{},"s the \"best\" way, is to create the least ",[567,73827,73821],{},"s for the most ",[567,73830,25729],{},"s you want to monitor.",[523,73833,73834,73837,73838,36823,73841,73846],{},[584,73835,73836],{},"About Tectonic",": It looks, as already written earlier, like an awesome tool for deploying Kubernetes on AWS and Bare Metal. But keep in mind, I could only try it out on AWS, but will definetly try it when I have the time to deploy Kubernets with ",[527,73839,73412],{"href":73410,"rel":73840},[531],[527,73842,73845],{"href":73843,"rel":73844},"https:\u002F\u002Fcoreos.com\u002Fmatchbox\u002F",[531],"Matchbox"," on bare-metal.",[523,73848,73849,73850,73852,73853,73856],{},"From the workshop I \"rediscovered\" the usage of ",[567,73851,15269],{},"s subcommand ",[567,73854,73855],{},"port-forward",". You should definetly use it, instead of for example using the Kubernetes api directly as a (HTTP) proxy.\nAs I normally used the API proxy to access services, here the usage of the command:",[738,73858,73860],{"className":1621,"code":73859,"language":1623,"meta":743,"style":743},"$ kubectl port-forward POD [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N] [options]\n",[567,73861,73862],{"__ignoreMap":743},[747,73863,73864,73866,73868,73871,73874,73877,73879,73881,73883,73886,73888,73891,73893,73895,73898],{"class":749,"line":750},[747,73865,1919],{"class":1630},[747,73867,1922],{"class":802},[747,73869,73870],{"class":802}," port-forward",[747,73872,73873],{"class":802}," POD",[747,73875,73876],{"class":1640}," [LOCAL_PORT:]REMOTE_PORT ",[747,73878,4253],{"class":757},[747,73880,5685],{"class":1640},[747,73882,4253],{"class":757},[747,73884,73885],{"class":1640},"LOCAL_PORT_N:",[747,73887,4259],{"class":757},[747,73889,73890],{"class":1640},"REMOTE_PORT_N",[747,73892,4259],{"class":757},[747,73894,4262],{"class":757},[747,73896,73897],{"class":1640},"options",[747,73899,4268],{"class":757},[523,73901,73902,73903,8287,73906,73909],{},"So all in all, the workshop was well done and brought some insights into using ",[527,73904,73406],{"href":73404,"rel":73905},[531],[527,73907,73412],{"href":73410,"rel":73908},[531]," software\u002Ftool.",[6072,73911,73912],{},[523,73913,73914,73916,73917,73920,73921,1909],{},[584,73915,6189],{}," For people wanting to try out the workshop of ",[527,73918,73511],{"href":73509,"rel":73919},[531],", the workshop github repo with all the information is located here: ",[527,73922,73925],{"href":73923,"rel":73924},"https:\u002F\u002Fgithub.com\u002Fmxinden\u002Fk8s-anywhere-workshop",[531],"mxinden\u002Fk8s-anywhere-workshop",[613,73927,73929],{"id":73928},"presentation-automating-kubernetes-cluster-operations-with-operators","Presentation: \"Automating Kubernetes Cluster Operations with Operators\"",[523,73931,73932,73933,1909],{},"Or \"Running Kubernetes in Kubernetes\".\nThis presentation was held by Timo Derstappen from ",[527,73934,73937],{"href":73935,"rel":73936},"https:\u002F\u002Fgiantswarm.io\u002F",[531],"Giant Swarm",[6072,73939,73940],{},[523,73941,73942],{},[584,73943,73944],{},"GLOSSAR",[668,73946,73947],{},[638,73948,73949,73952],{},[3049,73950,73951],{},"Giantnetes"," - The \"master\" Kubernetes instance, in which the other Kubernetes clusters are started\u002Frun.",[523,73954,73955,73956,73959],{},"Use operators to run ",[584,73957,73958],{},"operational"," tasks from within the cluster.",[6072,73961,73962,73966],{},[523,73963,73964],{},[584,73965,6189],{},[523,73967,73968,73969,26759,73972,73974],{},"Kubernetes renames ",[567,73970,73971],{},"Third Party Resources",[567,73973,12886],{}," soon.",[523,73976,73977,73980],{},[584,73978,73979],{},"OUTLOOK",": Using operators you can automate \"everything\" for and around the cluster.",[6072,73982,73983],{},[523,73984,73985,73988],{},[584,73986,73987],{},"EXAMPLES"," Operator examples from presenter:",[668,73990,73991,73997,74003,74009,74015],{},[638,73992,73993,73996],{},[567,73994,73995],{},"cert-operator"," - Creates certificates for the ingresses, etc.",[638,73998,73999,74002],{},[567,74000,74001],{},"kvm-operator"," - To spin up new KVM instances for the cluster(s).",[638,74004,74005,74008],{},[567,74006,74007],{},"flannel-operator"," - Configures networks for Kubernetes clusters that run inside the Giantnetes.",[638,74010,74011,74014],{},[567,74012,74013],{},"dns-operator"," - For external DNS provisioning.",[638,74016,57309],{},[523,74018,74019,74020,74023,74024,1909],{},"They also created a library\u002Fboilerplate for simple creation of Kubernetes operators.\nThe library is named ",[567,74021,74022],{},"operatorkit"," and written in Golang. The GitHub repo can be found here: ",[527,74025,74028],{"href":74026,"rel":74027},"https:\u002F\u002Fgithub.com\u002Fgiantswarm\u002Foperatorkit",[531],"giantswarm\u002Foperatorkit",[6072,74030,74031],{},[523,74032,74033,74035],{},[584,74034,6189],{}," They built a nice game, where you shoot Kubernetes pods.\nSeperate note originally taken from the presenter: \"We are hiring!\"",[613,74037,74039],{"id":74038},"end-of-the-first-day","End of the first day",[523,74041,74042,74043,74045,74046,74049,74050,74053,74054,74057],{},"I try to summarize the day for today in a simple manner: \"Kubernetes, Security, Deploying, Automation and Beer!\".\nExtensive talks about using Kubernetes operators (aka ",[567,74044,73971],{},"s) to automate tasks, using ",[527,74047,73412],{"href":73410,"rel":74048},[531]," to create Kubernetes clusters and especially the ",[527,74051,25937],{"href":25935,"rel":74052},[531]," for automating the monitoring in a cluster from the workshop from ",[527,74055,73666],{"href":73509,"rel":74056},[531],".\nThe day was fun, the workshop was good, the lunch was deliciois and overall everybody had fun.",[2979,74059],{},[535,74061,52788],{"id":52787},[523,74063,74064],{},"Yesterday was a good day. Some new interesting concepts about running containers, not only in Kubernetes but also using \"native\" Docker tools, have been shown.",[613,74066,74068],{"id":74067},"presentation-meet-kubo-bosh-powered-kubernetes-cluster","Presentation: \"Meet Kubo: BOSH-Powered Kubernetes Cluster\"",[523,74070,74071,74072,1909],{},"The presentation was held by Ulrich Hoelscher from ",[527,74073,74076],{"href":74074,"rel":74075},"https:\u002F\u002Ftwitter.com\u002FDellEMC",[531],"Dell EMC",[523,74078,74079],{},[3069,74080],{"alt":74081,"src":74082},"The slide showed the 'inheritance' from BORG.","\u002Fblog\u002F2017\u002Fcontainer-days-2017-hamburg\u002Fcds2017-photo2.png",[523,74084,74085],{},"No offense against the presentator, maybe it was just the lack of me drinking a coffee before going to the tlak, but in the end it sounded like \"Kubernetes, Containers, VMs, Pivotal Cloud Foundry does the thing\".",[6072,74087,74088,74092,74095,74099],{},[523,74089,74090],{},[584,74091,6189],{},[523,74093,74094],{},"Aren't we all companies that want to sell our products? ;)",[523,74096,74097],{},[584,74098,6189],{},[523,74100,74101,74102,714,74105,587,74108,74110],{},"The speaker said that Google recommends seperate Kubernetes clusters per stage aka ",[3049,74103,74104],{},"Dev",[3049,74106,74107],{},"QA",[3049,74109,40090],{}," cluster.",[523,74112,74113],{},"Overall it was interesting what BOSH with Kubo has to offer for running Kubernetes in the cloud.\nFor me it wasn't that interesting, as I'm looking for a tool that works on bare-metal and not only in the cloud from a specific provider. BOSH may even work with bare-metal too, but it doesn't seem like it as he mentioned the usage of cloud loadbalancers for HTTP and TCP services, and cloud provider API(s) for creating VMs for the cluster.",[613,74115,74117],{"id":74116},"presentation-containerops-using-kubernetes-to-orchestrate-devops-workflow","Presentation: \"ContainerOps - Using Kubernetes to Orchestrate DevOps Workflow\"",[523,74119,74120],{},"The presentation was held by Zhen Ju from Huawei.",[523,74122,74123],{},"He talked about the DevOps story, DevOps Workflow Orechestration and the lifecycle of DevOps.\nIt would be best, to just take a look at his slides to get a good impression on what he talked about.",[523,74125,74126],{},[3069,74127],{"alt":74128,"src":74129},"Another diagram that showed a DevOps flow for building applications.","\u002Fblog\u002F2017\u002Fcontainer-days-2017-hamburg\u002Fcds2017-photo3.png",[523,74131,74132,74133,1909],{},"He mentioned their baseimage that solves the issues with some existing baseimages, like lightweighness of the image, process reaping, etc.\nIt is availabe on GitHub: ",[527,74134,74137],{"href":74135,"rel":74136},"https:\u002F\u002Fgithub.com\u002Fphusion\u002Fbaseimage-docker",[531],"phusion\u002Fbaseimage-docker",[523,74139,74140],{},[3069,74141],{"alt":74142,"src":74143},"Even though the quality of the pictures seem to get worse from picture to picture. The slide contained an interesting diagram of an 'example' DevOps Orchestration Workflow.","\u002Fblog\u002F2017\u002Fcontainer-days-2017-hamburg\u002Fcds2017-photo4.png",[6072,74145,74146,74151],{},[523,74147,74148,74150],{},[584,74149,73560],{}," from Zhen Ju:",[523,74152,74153],{},"\"With Container, For Container\"",[523,74155,74156,74157,1909],{},"Their project for simplifying\u002Fsimpler DevOps is located on GitHub, here: ",[527,74158,74161],{"href":74159,"rel":74160},"https:\u002F\u002Fgithub.com\u002FHuawei\u002FcontainerOps",[531],"Huawei\u002FcontainerOps",[613,74163,52763],{"id":53002},[523,74165,74166,74167,856],{},"This time, I'll have to point you to a tweet from ",[527,74168,52963],{"href":73769,"rel":74169},[531],[6072,74171,74173,74180,74181],{"className":74172,"dataLang":18973},[18972,52946],[523,74174,74175,74176],{"lang":18973,"dir":18976},"No words necessary! ",[527,74177,74179],{"href":74178},"https:\u002F\u002Ft.co\u002Fas8SC7aWIS","pic.twitter.com\u002Fas8SC7aWIS","— ContainerDays (@ConDaysEU) ",[527,74182,74184],{"href":74183},"https:\u002F\u002Ftwitter.com\u002FConDaysEU\u002Fstatus\u002F877463813548896256","June 21, 2017",[19016,74186],{"async":1254,"src":73786,"charSet":19019},[523,74188,74189],{},"I ate the burger instead of the falafel, but at least for the burger I can confirm that they were still as delicious as yesterday!",[613,74191,74193],{"id":74192},"presentation-ship-your-containers-fast-with-gitlabci","Presentation: \"Ship your containers fast with GitLab\u002FCI\"",[523,74195,73537,74196,18501,74201,1909],{},[527,74197,74200],{"href":74198,"rel":74199},"https:\u002F\u002Fgithub.com\u002Fsolidnerd",[531],"Niclas Mietz",[527,74202,74205],{"href":74203,"rel":74204},"https:\u002F\u002Fbee42.com\u002F",[531],"Bee42",[523,74207,74208,74209,74212],{},"It depends heavily on your decision on \"where\" you want to run the GitLab CI runner. The GitLab CI runner will run the given Docker images and the commands to in the end build your project.\nAlthough creating the process\u002Fpipeline(s) for a project isn't that hard as it might seem. If you are already using Docker to build your project it will be very simple to switch to using GitLab CI pipelines. It's almost as easy as simply putting the commands used to create\u002Fcompile\u002Fbuild and later on test your project into a ",[567,74210,74211],{},".gitlab-ci.yaml"," file.\nGitLab automatically detects if the CI file exists and will then show you the status of the run\u002Frunning build next to the commit(s).",[523,74214,74215],{},"Running \"Docker in Docker\" is also an option for going for fully reproducible Docker image builds.",[523,74217,74218],{},"The pipelines of GitLab CI allow for simple triggering of deployments to specific stages by a button push.\nThe deployment process has some integration possibilities, for example automatically adding Kubernetes Token, Certificate, etc. to the runner container to make the deployment to Kubernetes simpler.",[523,74220,74221],{},[3069,74222],{"alt":74223,"src":74224},"The slide originally showed the example build flow using GitLab CI.","\u002Fblog\u002F2017\u002Fcontainer-days-2017-hamburg\u002Fcds2017-photo5.png",[523,74226,74227,74228,74233,74234,74237],{},"An interesting point he brought up was the use of the ",[527,74229,74232],{"href":74230,"rel":74231},"https:\u002F\u002Fgithub.com\u002Fbitnami\u002Fminideb",[531],"bitnami\u002Fminideb"," image. The ",[527,74235,74232],{"href":74230,"rel":74236},[531]," image uses glibc instead of like for example Alpine the musl library. That makes it better compatible\u002F usable for \"older\"\u002F existing applications.",[523,74239,74240,74241,13350,74244,1909],{},"The first part of the GitLab CI tutorial can be found at the blog of ",[527,74242,74205],{"href":74203,"rel":74243},[531],[527,74245,74248],{"href":74246,"rel":74247},"https:\u002F\u002Fbee42.com\u002Fblog\u002Fgetting-started-with-gitlab-part1\u002F",[531],"Bee42 - Getting Started with GitLab CI with Containers (Part 1)",[523,74250,74251,74252,74255],{},"To summarize this presentation, it showed how simple it is how to use the GitLab CI to create pipelines for your projects. For more see the link to ",[527,74253,74205],{"href":74203,"rel":74254},[531]," blog above.",[613,74257,74259],{"id":74258},"presentation-monitoring-and-logging-in-wonderland","Presentation: \"Monitoring and Logging in Wonderland\"",[523,74261,73537,74262,18501,74267,1909],{},[527,74263,74266],{"href":74264,"rel":74265},"https:\u002F\u002Ftwitter.com\u002FSeiffertP",[531],"Paul Seiffert",[527,74268,74271],{"href":74269,"rel":74270},"https:\u002F\u002Fwww.jimdo.com\u002F",[531],"Jimdo",[523,74273,74274],{},"First of all, I have to admit \"Wunderland\" is an interesting name for such a PaaS platform.",[523,74276,74277],{},[3069,74278],{"alt":74279,"src":74280},"The photo contains a slide with the layers in which Wonderland works\u002Fbegins.","\u002Fblog\u002F2017\u002Fcontainer-days-2017-hamburg\u002Fcds2017-photo6.png",[523,74282,74283],{},"Wonderland manages the infrastructure, from loadbalancers to the containers the applications run in.",[523,74285,74286],{},"For the monitoring, they utilize their Grafana to automatically create dashboard for every service, they are running.",[523,74288,74289],{},"They have the following differenciation between metrics. It is like this:",[668,74291,74292,74295,74298],{},[638,74293,74294],{},"Application - Actual metrics from the application running.",[638,74296,74297],{},"System - Metrics from the Servers\u002FHosts\u002FVMs running.",[638,74299,74300],{},"Infrastructure - Metrics about AWS loadbalancers, etc.",[523,74302,74303],{},"..metrics.",[6072,74305,74306,74310],{},[523,74307,74308],{},[584,74309,6189],{},[523,74311,74312],{},"I would even go so far as to add a \"Cloud\" in front of the \"Infrastructure metrics\" in the case of using a Cloud provider.",[523,74314,74315],{},"To gather all application metrics running in volatile containers on different hosts. The Wonderland Service Discovery is used to discover services for the Prometheus monitoring.\nAn important aspect for metrics is the retention. They use so called \"recording rules\" for Prometheus. These \"recording rules\" are automatically created by a self written application to pre-aggregate certain metrics automatically and directly.",[523,74317,74318],{},[3069,74319],{"alt":74320,"src":74321},"The photo contains a slide with the differenciation between short- and long term storage of metrics with Prometheus federation. In their case short term ~30 min and long term 32 days.","\u002Fblog\u002F2017\u002Fcontainer-days-2017-hamburg\u002Fcds2017-photo7.png",[523,74323,74324,74325,74330,74331,74334],{},"For analyzing logs in case of issues, they simply use ",[527,74326,74329],{"href":74327,"rel":74328},"https:\u002F\u002Fwww.elastic.co\u002Fproducts\u002Fbeats\u002Ffilebeat",[531],"Logbeat\u002FFilebeat"," for the shipping of logs and ",[527,74332,27326],{"href":27331,"rel":74333},[531]," for visualizing the logs.",[523,74336,74337],{},"An interesting presentation about their own infrastructure. It shows exactly some points that are a problem for not only them, but for everyone. Good to see how they have solved the issues. That gives everyone a good idea\u002Fconcepts that may be altered\u002Fused to fit for their own case\u002Fproblem.",[613,74339,74341],{"id":74340},"presentation-operating-microservices-with-nomad-and-consul","Presentation: \"Operating Microservices with Nomad and Consul\"",[523,74343,73537,74344,18501,74349,1909],{},[527,74345,74348],{"href":74346,"rel":74347},"https:\u002F\u002Ftwitter.com\u002Fspanneberg",[531],"Bastian Spanneberg",[527,74350,74353],{"href":74351,"rel":74352},"https:\u002F\u002Fwww.instana.com\u002F",[531],"Instana",[6072,74355,74356,74361],{},[523,74357,74358],{},[584,74359,74360],{},"DISCLAIMER",[523,74362,74363],{},"I got to the presentation a bit late. I got there at the begining of the well made demo.",[523,74365,74366,74367,74370,74371,18501,74376,74381,74382,74385],{},"From what I still saw, ",[527,74368,3039],{"href":3037,"rel":74369},[531]," looks very interesting as it seems to seamlessly integrate with ",[527,74372,74375],{"href":74373,"rel":74374},"https:\u002F\u002Fwww.consul.io\u002F",[531],"Consul",[527,74377,74380],{"href":74378,"rel":74379},"https:\u002F\u002Fwww.hashicorp.com",[531],"Hashicorp",", and run jobs in combination with Consul health checks quite well.\n",[527,74383,74348],{"href":74346,"rel":74384},[531]," showed the ease of the Consul API with some usage examples for his demo:",[523,74387,74388],{},[3069,74389],{"alt":74390,"src":74391},"The slide with the Consul usage for his demo.","\u002Fblog\u002F2017\u002Fcontainer-days-2017-hamburg\u002Fcds2017-photo8.png",[523,74393,74394,74395,12735,74398,74401],{},"It was interesting to see how easy it is to run containers with ",[527,74396,3039],{"href":3037,"rel":74397},[531],[527,74399,74375],{"href":74373,"rel":74400},[531]," \"service\" manifests have an interesting, human-readable format too, which makes it easy like with the YAML manifests from Kubernetes, Docker Swarm and so on.",[523,74403,74404],{},[3069,74405],{"alt":74406,"src":74407},"Who would have thought it, in the end somebody asked about the nice UI he showed. It was the Instana monitoring tool. Seems like a decent tool for monitoring and going further with tracing and everything done automatically. Just checkout their page here: https:\u002F\u002Fwww.instana.com\u002F.","\u002Fblog\u002F2017\u002Fcontainer-days-2017-hamburg\u002Fcds2017-photo9.png",[523,74409,74410,74411,74414,74415,74418],{},"A solid presentation with a nice demonstration of \"everything\" that was talked about. Now I would definetly take a closer look at ",[527,74412,3039],{"href":3037,"rel":74413},[531]," as a container runner, especially when comparing container \"runner\" (not orchestrators, see NOTE below), and ",[527,74416,74375],{"href":74373,"rel":74417},[531]," as a Key\u002FValue storage with a twist.",[6072,74420,74421,74425],{},[523,74422,74423],{},[584,74424,6189],{},[523,74426,74427],{},"He stated that Nomad currently doesn't have \"real\" orchestration capabilities aka you would need to write tooling around it for orchestration.",[613,74429,74431],{"id":74430},"end-of-the-second-day","End of the second day",[6072,74433,74434,74438],{},[523,74435,74436],{},[584,74437,73560],{},[523,74439,74440],{},"\"The sun is slowly turning its back to us. We will wait for the comeback in the morning.\"",[523,74442,74443,74444,74449,74450,74455],{},"From what I've heard from ",[527,74445,74448],{"href":74446,"rel":74447},"https:\u002F\u002Ftwitter.com\u002FJu4444",[531],"Julian Hansert",", most feedback was good and that new ideas to continue to improve the conference were given and will actively be added with best knowledge to it, to make the conference even better or as Trump would say: ",[527,74451,74454],{"href":74452,"rel":74453},"http:\u002F\u002Fjungle.horse\u002F?jungle=The+best+conference.#%7B%22s%22%3A%22i%20have%20conferences%2C%20but%20container%20days%20has%20the%20best%20container%20conference!%22%7D",[531],"Text to Trump - Jungle.horse",".\nIt was quite a nice day again, but I would say the wind was a bit stronger today.",[2979,74457],{},[535,74459,14526],{"id":14525},[523,74461,74462,74465,74466,74469,74470,74473,74474,1909],{},[584,74463,74464],{},"But even the stronger winds"," didn't stop us, the attendants, to stop talking about containers and how we, for ourselves, ",[584,74467,74468],{},"can maneuver"," through the ",[584,74471,74472],{},"strong streams"," of the many different container projects, tools and orchestrators to find us the ",[584,74475,74476],{},"perfect fitting tool for the job",[523,74478,74479],{},"I for my part have one thing I would change, but for myself, that I should bring a phone with a more stable camera API or b) bring a seperate good camera for taking photos at the conference, so the photos have a better quality than the potato like ones right now.",[523,74481,74482],{},"I hope everybody had fun and learned something new. I hope to stay in touch with the cool people I met there and see them soon at another conference or meetup. :-)\nHave Fun!",[523,74484,74485,53030],{},[584,74486,53029],{},[2890,74488,64773],{},{"title":743,"searchDepth":761,"depth":761,"links":74490},[74491,74492,74500,74509],{"id":13456,"depth":761,"text":13457},{"id":52418,"depth":761,"text":52419,"children":74493},[74494,74495,74496,74497,74498,74499],{"id":73691,"depth":769,"text":73692},{"id":73726,"depth":769,"text":73727},{"id":52762,"depth":769,"text":52763},{"id":73800,"depth":769,"text":73801},{"id":73928,"depth":769,"text":73929},{"id":74038,"depth":769,"text":74039},{"id":52787,"depth":761,"text":52788,"children":74501},[74502,74503,74504,74505,74506,74507,74508],{"id":74067,"depth":769,"text":74068},{"id":74116,"depth":769,"text":74117},{"id":53002,"depth":769,"text":52763},{"id":74192,"depth":769,"text":74193},{"id":74258,"depth":769,"text":74259},{"id":74340,"depth":769,"text":74341},{"id":74430,"depth":769,"text":74431},{"id":14525,"depth":761,"text":14526},"2017-06-20T11:23:08+02:00","Some thoughts, notes, comments and pictures from the Container Days 2017 in Hamburg.",{"src":73718},{"tags":74514},[13976,18920,26415,12175,124],"\u002Fblog\u002F2017\u002Fcontainer-days-2017-hamburg",{"title":73652,"description":74511},"3.blog\u002F2017\u002Fcontainer-days-2017-hamburg","eBgYquKXAUcmqaX-Ft2TPB8EotviDzO7w9HYJZPLrZI",{"id":74520,"title":74521,"authors":74522,"badge":518,"body":74525,"date":74685,"description":74686,"extension":2911,"image":74687,"meta":74688,"navigation":1254,"path":74690,"seo":74691,"stem":74692,"__hash__":74693},"posts\u002F3.blog\u002F2017\u002Fgolang-go-get-from-gitlab.md","Golang: go get from GitLab",[74523],{"name":514,"to":515,"avatar":74524},{"src":517},{"type":520,"value":74526,"toc":74679},[74527,74534,74548,74557,74561,74572,74575,74581,74592,74595,74601,74615,74623,74627,74632,74666,74668,74674,74676],[523,74528,74529,74530,74533],{},"I just now came across the problem that I created a repository on a private GitLab instance for a Golang project and could not just use ",[567,74531,74532],{},"go get ..."," to get it.\nAfter a short Google search, I came across this StackOverflow question and thankfully it had a working answer.",[523,74535,74536,74537,74542,74543,1909],{},"The original StackOverflow question can be found here: ",[527,74538,74541],{"href":74539,"rel":74540},"https:\u002F\u002Fstackoverflow.com\u002Fquestions\u002F29707689\u002Fhow-do-you-use-golang-with-a-private-gitlab-repo\u002F37844256#37844256",[531],"StackOverflow - how do you use golang with a private gitlab repo?",", the question was asked by User ",[527,74544,74547],{"href":74545,"rel":74546},"https:\u002F\u002Fstackoverflow.com\u002Fusers\u002F2904939\u002Fjames-fremen",[531],"James Fremen",[6072,74549,74550,74554],{},[523,74551,74552],{},[584,74553,6189],{},[523,74555,74556],{},"I will quote the question and answer which worked here so it is sort of archived here.",[535,74558,74560],{"id":74559},"the-original-question","The original question",[6072,74562,74563,74566],{},[523,74564,74565],{},"GitLab is a free, open-source way to host private .git repositories but it does not seem to work with golang. When you create a project it generates a URL of the form:",[738,74567,74568],{"className":1621,"code":743,"language":1623,"meta":743,"style":743},[567,74569,74570],{"__ignoreMap":743},[747,74571],{"class":749,"line":750},[523,74573,74574],{},"git@1.2.3.4:private-developers\u002Fproject.git",[738,74576,74579],{"className":74577,"code":74578,"language":12479},[12477],"> where: 1.2.3.4 is the IP address of the gitlab server private-developers is a user group which has access to the private repo\n>\n> Golang 1.2.1 doesn't seem to understand this syntax.\n>\n>```bash\ngo get git@1.2.3.4:private-developers\u002Fproject.git\n",[567,74580,74578],{"__ignoreMap":743},[6072,74582,74583,74586],{},[523,74584,74585],{},"results in:",[738,74587,74588],{"className":1621,"code":743,"language":1623,"meta":743,"style":743},[567,74589,74590],{"__ignoreMap":743},[747,74591],{"class":749,"line":750},[523,74593,74594],{},"package git@23.251.148.129\u002Fproject.git: unrecognized import path \"git@1.2.3.4\u002Fproject.git\"",[738,74596,74599],{"className":74597,"code":74598,"language":12479},[12477],"> Is there a way to get this to work?\n>\n> thanks!\n\nAuthor of the question [James Fremen](https:\u002F\u002Fstackoverflow.com\u002Fusers\u002F2904939\u002Fjames-fremen)\n\n## The answer that worked for me\n> Run this command:\n>\n>```bash\ngit config --global url.\"git@1.2.3.4:\".insteadOf \"https:\u002F\u002F1.2.3.4\u002F\"\n",[567,74600,74598],{"__ignoreMap":743},[6072,74602,74603,74612],{},[523,74604,74605,74606,74608,74609,1909],{},"Assuming you have the correct privileges to ",[567,74607,58452],{}," the repository, this will make go get work for all repos on server ",[567,74610,74611],{},"1.2.3.4",[523,74613,74614],{},"I tested this to work with go version 1.6.2 and 1.8.",[523,74616,74617,74618],{},"Author of the answer ",[527,74619,74622],{"href":74620,"rel":74621},"https:\u002F\u002Fstackoverflow.com\u002Fusers\u002F616644\u002Frick-smith",[531],"Rick Smith",[613,74624,74626],{"id":74625},"example-for-dns-names","Example for DNS names",[523,74628,74629,74630,1909],{},"So for example with dns names, it would be for a gitlab running at ",[567,74631,25126],{},[738,74633,74635],{"className":1621,"code":74634,"language":1623,"meta":743,"style":743},"git config --global url.\"git@gitlab.example.com:\".insteadOf \"https:\u002F\u002Fexample.com\u002F\"\n",[567,74636,74637],{"__ignoreMap":743},[747,74638,74639,74641,74643,74646,74649,74651,74654,74656,74659,74661,74664],{"class":749,"line":750},[747,74640,221],{"class":1630},[747,74642,17698],{"class":802},[747,74644,74645],{"class":802}," --global",[747,74647,74648],{"class":802}," url.",[747,74650,3892],{"class":757},[747,74652,74653],{"class":802},"git@gitlab.example.com:",[747,74655,3892],{"class":757},[747,74657,74658],{"class":802},".insteadOf",[747,74660,969],{"class":757},[747,74662,74663],{"class":802},"https:\u002F\u002Fexample.com\u002F",[747,74665,975],{"class":757},[535,74667,14526],{"id":14525},[523,74669,74670,74671,1909],{},"With that change, you can now successfully run ",[567,74672,74673],{},"go get gitlab.example.com\u002Fexample-user\u002Fexample-project",[523,74675,13967],{},[2890,74677,74678],{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}",{"title":743,"searchDepth":761,"depth":761,"links":74680},[74681,74684],{"id":74559,"depth":761,"text":74560,"children":74682},[74683],{"id":74625,"depth":769,"text":74626},{"id":14525,"depth":761,"text":14526},"2017-06-02T14:39:01+02:00","I just now came across the problem that I created a repository on a private GitLab instance for a Golang project and could not just use go get ... to get it.\nAfter a short Google search, I came across this StackOverflow question and thankfully it had a working answer.",{"src":64830},{"tags":74689},[64833,26413],"\u002Fblog\u002F2017\u002Fgolang-go-get-from-gitlab",{"title":74521,"description":74686},"3.blog\u002F2017\u002Fgolang-go-get-from-gitlab","8rTZgp0SozHD0tnkmq_mUkTmeShkGwPpReJh0hy8Gv4",{"id":74695,"title":74696,"authors":74697,"badge":518,"body":74700,"date":75688,"description":75689,"extension":2911,"image":75690,"meta":75691,"navigation":1254,"path":75693,"seo":75694,"stem":75695,"__hash__":75696},"posts\u002F3.blog\u002F2017\u002Fkubernetes-elasticsearch-operator.md","Kubernetes Elasticsearch Operator",[74698],{"name":514,"to":515,"avatar":74699},{"src":517},{"type":520,"value":74701,"toc":75679},[74702,74713,74720,74724,74730,74746,74750,74757,74850,74853,74856,74860,74866,74870,74873,75351,75355,75358,75669,75671,75674,75676],[523,74703,74704,74705,74708,74709,74712],{},"I got the inspiration for writing a so called operator for Kubernetes from the ",[527,74706,73406],{"href":73404,"rel":74707},[531]," project ",[527,74710,25937],{"href":25935,"rel":74711},[531],".\nSo a big thanks to them for creating the project, as also the code is almost completely based on their operator code.",[523,74714,74715,74716,1909],{},"The project can be found on GitHub: ",[527,74717,74718],{"href":74718,"rel":74719},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Felasticsearch-operator",[531],[613,74721,74723],{"id":74722},"installation","Installation",[523,74725,45396,74726,74729],{},[567,74727,74728],{},"bundle.yaml"," that is in the repo root, to run the operator on the cluster.",[738,74731,74733],{"className":1621,"code":74732,"language":1623,"meta":743,"style":743},"kubectl create -f bundle.yaml\n",[567,74734,74735],{"__ignoreMap":743},[747,74736,74737,74739,74741,74743],{"class":749,"line":750},[747,74738,15269],{"class":1630},[747,74740,1925],{"class":802},[747,74742,1934],{"class":802},[747,74744,74745],{"class":802}," bundle.yaml\n",[613,74747,74749],{"id":74748},"verify-the-installation-of-the-thirdpartyresources","Verify the installation of the ThirdPartyResources",[523,74751,74752,74753,74756],{},"To verify that the operator has successful installed its ",[567,74754,74755],{},"ThirdPartyResources",", you simply check the Kubernetes server for them:",[738,74758,74760],{"className":1621,"code":74759,"language":1623,"meta":743,"style":743},"$ kubectl get thirdpartyresources\nNAME                                       DESCRIPTION                           VERSION(S)\n[...]\ncurator.elasticsearch.zerbytes.net         Managed Curator instance(s)           v1alpha1\nelasticsearch.elasticsearch.zerbytes.net   Managed Elasticsearch instance(s)     v1alpha1\n[...]\n",[567,74761,74762,74773,74789,74797,74820,74842],{"__ignoreMap":743},[747,74763,74764,74766,74768,74770],{"class":749,"line":750},[747,74765,1919],{"class":1630},[747,74767,1922],{"class":802},[747,74769,1951],{"class":802},[747,74771,74772],{"class":802}," thirdpartyresources\n",[747,74774,74775,74777,74780,74783,74785,74787],{"class":749,"line":761},[747,74776,2230],{"class":1630},[747,74778,74779],{"class":802},"                                       DESCRIPTION",[747,74781,74782],{"class":802},"                           VERSION",[747,74784,2000],{"class":757},[747,74786,2003],{"class":1630},[747,74788,3600],{"class":757},[747,74790,74791,74793,74795],{"class":749,"line":769},[747,74792,4253],{"class":757},[747,74794,5685],{"class":1640},[747,74796,4268],{"class":757},[747,74798,74799,74802,74805,74808,74811,74813,74815,74817],{"class":749,"line":776},[747,74800,74801],{"class":1630},"curator.elasticsearch.zerbytes.net",[747,74803,74804],{"class":802},"         Managed",[747,74806,74807],{"class":802}," Curator",[747,74809,74810],{"class":802}," instance",[747,74812,2000],{"class":757},[747,74814,4978],{"class":1630},[747,74816,2006],{"class":757},[747,74818,74819],{"class":802},"           v1alpha1\n",[747,74821,74822,74825,74828,74831,74833,74835,74837,74839],{"class":749,"line":784},[747,74823,74824],{"class":1630},"elasticsearch.elasticsearch.zerbytes.net",[747,74826,74827],{"class":802},"   Managed",[747,74829,74830],{"class":802}," Elasticsearch",[747,74832,74810],{"class":802},[747,74834,2000],{"class":757},[747,74836,4978],{"class":1630},[747,74838,2006],{"class":757},[747,74840,74841],{"class":802},"     v1alpha1\n",[747,74843,74844,74846,74848],{"class":749,"line":790},[747,74845,4253],{"class":757},[747,74847,5685],{"class":1640},[747,74849,4268],{"class":757},[523,74851,74852],{},"If those two entries are shown, the operator should now be working.",[535,74854,63093],{"id":74855},"examples",[613,74857,74859],{"id":74858},"use-the-examples","Use the examples",[523,74861,74862,74863,74865],{},"You use the ",[567,74864,25255],{}," command for that. If you need help, check the help menu.",[613,74867,74869],{"id":74868},"elasticsearch-manifest","Elasticsearch manifest",[523,74871,74872],{},"The manifest below would create a simple Elasticsearch cluster, consisting of 1x master, 1x data and 1x ingest node.",[738,74874,74876],{"className":740,"code":74875,"language":742,"meta":743,"style":743},"apiVersion: \"elasticsearch.zerbytes.net\u002Fv1alpha1\"\nkind: \"Elasticsearch\"\nmetadata:\n  name: \"example\"\nspec:\n  version: \"5.4.0\"\n  # automatically calculate java memory opts\n  # not implemented yet\n  javaMemoryControl: true\n  # this is currently not implemented due to it being missing\n  # from the used k8s go-client\n  #imagePullSecrets: \"example\"\n  # config that is added to *all* autogenrated config file\n  additionalConfig: |\n    action.auto_create_index: .security,.monitoring*,.watches,.triggered_watches,.watcher-history*,filebeat-*,metricbeat-*,packetbeat-*,winlogbeat-*,heartbeat-*\n  master:\n    replicas: 1\n    #nodeSelector:\n    #  elasticsearch-data: \"yes\"\n    resources:\n      limits:\n        memory: \"512Mi\"\n      requests:\n        memory: \"512Mi\"\n    # add to the jvm.options file\n    javaOpts: |\n      # your additional java opts here\n    additionalConfig: |\n      # your addtional elasticsearch configuration here\n    storage:\n      class: rbd\n      resources:\n        requests:\n          storage: 10Gi\n  data:\n    replicas: 1\n    #nodeSelector:\n    #  elasticsearch-data: \"yes\"\n    resources:\n      limits:\n        memory: \"512Mi\"\n      requests:\n        memory: \"512Mi\"\n    javaOpts: |\n      # your additional java opts here\n    additionalConfig: |\n      # your addtional elasticsearch configuration here\n    storage:\n      class: rbd\n      resources:\n        requests:\n          storage: 15Gi\n  ingest:\n    replicas: 1\n    #nodeSelector:\n    #  elasticsearch-data: \"yes\"\n    resources:\n      limits:\n        memory: \"512Mi\"\n      requests:\n        memory: \"512Mi\"\n    javaOpts: |\n      # your additional java opts here\n    additionalConfig: |\n      # your addtional elasticsearch ingest configuration here\n",[567,74877,74878,74891,74904,74910,74923,74929,74943,74948,74953,74962,74967,74972,74977,74982,74991,74996,75002,75010,75015,75020,75026,75033,75047,75054,75066,75071,75080,75085,75094,75099,75106,75116,75122,75128,75137,75144,75152,75156,75160,75166,75172,75184,75190,75202,75210,75214,75222,75226,75232,75240,75246,75252,75261,75268,75276,75280,75284,75290,75296,75308,75314,75326,75334,75338,75346],{"__ignoreMap":743},[747,74879,74880,74882,74884,74886,74889],{"class":749,"line":750},[747,74881,12949],{"class":753},[747,74883,856],{"class":757},[747,74885,969],{"class":757},[747,74887,74888],{"class":802},"elasticsearch.zerbytes.net\u002Fv1alpha1",[747,74890,975],{"class":757},[747,74892,74893,74895,74897,74899,74902],{"class":749,"line":761},[747,74894,12963],{"class":753},[747,74896,856],{"class":757},[747,74898,969],{"class":757},[747,74900,74901],{"class":802},"Elasticsearch",[747,74903,975],{"class":757},[747,74905,74906,74908],{"class":749,"line":769},[747,74907,12973],{"class":753},[747,74909,758],{"class":757},[747,74911,74912,74914,74916,74918,74921],{"class":749,"line":776},[747,74913,12980],{"class":753},[747,74915,856],{"class":757},[747,74917,969],{"class":757},[747,74919,74920],{"class":802},"example",[747,74922,975],{"class":757},[747,74924,74925,74927],{"class":749,"line":784},[747,74926,12990],{"class":753},[747,74928,758],{"class":757},[747,74930,74931,74934,74936,74938,74941],{"class":749,"line":790},[747,74932,74933],{"class":753},"  version",[747,74935,856],{"class":757},[747,74937,969],{"class":757},[747,74939,74940],{"class":802},"5.4.0",[747,74942,975],{"class":757},[747,74944,74945],{"class":749,"line":796},[747,74946,74947],{"class":772},"  # automatically calculate java memory opts\n",[747,74949,74950],{"class":749,"line":806},[747,74951,74952],{"class":772},"  # not implemented yet\n",[747,74954,74955,74958,74960],{"class":749,"line":814},[747,74956,74957],{"class":753},"  javaMemoryControl",[747,74959,856],{"class":757},[747,74961,860],{"class":859},[747,74963,74964],{"class":749,"line":822},[747,74965,74966],{"class":772},"  # this is currently not implemented due to it being missing\n",[747,74968,74969],{"class":749,"line":830},[747,74970,74971],{"class":772},"  # from the used k8s go-client\n",[747,74973,74974],{"class":749,"line":836},[747,74975,74976],{"class":772},"  #imagePullSecrets: \"example\"\n",[747,74978,74979],{"class":749,"line":842},[747,74980,74981],{"class":772},"  # config that is added to *all* autogenrated config file\n",[747,74983,74984,74987,74989],{"class":749,"line":850},[747,74985,74986],{"class":753},"  additionalConfig",[747,74988,856],{"class":757},[747,74990,24697],{"class":19332},[747,74992,74993],{"class":749,"line":863},[747,74994,74995],{"class":802},"    action.auto_create_index: .security,.monitoring*,.watches,.triggered_watches,.watcher-history*,filebeat-*,metricbeat-*,packetbeat-*,winlogbeat-*,heartbeat-*\n",[747,74997,74998,75000],{"class":749,"line":869},[747,74999,14739],{"class":753},[747,75001,758],{"class":757},[747,75003,75004,75006,75008],{"class":749,"line":877},[747,75005,14746],{"class":753},[747,75007,856],{"class":757},[747,75009,18691],{"class":1895},[747,75011,75012],{"class":749,"line":1015},[747,75013,75014],{"class":772},"    #nodeSelector:\n",[747,75016,75017],{"class":749,"line":1021},[747,75018,75019],{"class":772},"    #  elasticsearch-data: \"yes\"\n",[747,75021,75022,75024],{"class":749,"line":1027},[747,75023,28941],{"class":753},[747,75025,758],{"class":757},[747,75027,75028,75031],{"class":749,"line":1033},[747,75029,75030],{"class":753},"      limits",[747,75032,758],{"class":757},[747,75034,75035,75038,75040,75042,75045],{"class":749,"line":1039},[747,75036,75037],{"class":753},"        memory",[747,75039,856],{"class":757},[747,75041,969],{"class":757},[747,75043,75044],{"class":802},"512Mi",[747,75046,975],{"class":757},[747,75048,75049,75052],{"class":749,"line":1054},[747,75050,75051],{"class":753},"      requests",[747,75053,758],{"class":757},[747,75055,75056,75058,75060,75062,75064],{"class":749,"line":1060},[747,75057,75037],{"class":753},[747,75059,856],{"class":757},[747,75061,969],{"class":757},[747,75063,75044],{"class":802},[747,75065,975],{"class":757},[747,75067,75068],{"class":749,"line":1066},[747,75069,75070],{"class":772},"    # add to the jvm.options file\n",[747,75072,75073,75076,75078],{"class":749,"line":1081},[747,75074,75075],{"class":753},"    javaOpts",[747,75077,856],{"class":757},[747,75079,24697],{"class":19332},[747,75081,75082],{"class":749,"line":1087},[747,75083,75084],{"class":802},"      # your additional java opts here\n",[747,75086,75087,75090,75092],{"class":749,"line":1102},[747,75088,75089],{"class":753},"    additionalConfig",[747,75091,856],{"class":757},[747,75093,24697],{"class":19332},[747,75095,75096],{"class":749,"line":1110},[747,75097,75098],{"class":802},"      # your addtional elasticsearch configuration here\n",[747,75100,75101,75104],{"class":749,"line":1117},[747,75102,75103],{"class":753},"    storage",[747,75105,758],{"class":757},[747,75107,75108,75111,75113],{"class":749,"line":1123},[747,75109,75110],{"class":753},"      class",[747,75112,856],{"class":757},[747,75114,75115],{"class":802}," rbd\n",[747,75117,75118,75120],{"class":749,"line":1129},[747,75119,66025],{"class":753},[747,75121,758],{"class":757},[747,75123,75124,75126],{"class":749,"line":1142},[747,75125,66032],{"class":753},[747,75127,758],{"class":757},[747,75129,75130,75132,75134],{"class":749,"line":1150},[747,75131,66039],{"class":753},[747,75133,856],{"class":757},[747,75135,75136],{"class":802}," 10Gi\n",[747,75138,75139,75142],{"class":749,"line":1157},[747,75140,75141],{"class":753},"  data",[747,75143,758],{"class":757},[747,75145,75146,75148,75150],{"class":749,"line":1163},[747,75147,14746],{"class":753},[747,75149,856],{"class":757},[747,75151,18691],{"class":1895},[747,75153,75154],{"class":749,"line":1168},[747,75155,75014],{"class":772},[747,75157,75158],{"class":749,"line":1174},[747,75159,75019],{"class":772},[747,75161,75162,75164],{"class":749,"line":1480},[747,75163,28941],{"class":753},[747,75165,758],{"class":757},[747,75167,75168,75170],{"class":749,"line":1491},[747,75169,75030],{"class":753},[747,75171,758],{"class":757},[747,75173,75174,75176,75178,75180,75182],{"class":749,"line":1496},[747,75175,75037],{"class":753},[747,75177,856],{"class":757},[747,75179,969],{"class":757},[747,75181,75044],{"class":802},[747,75183,975],{"class":757},[747,75185,75186,75188],{"class":749,"line":1502},[747,75187,75051],{"class":753},[747,75189,758],{"class":757},[747,75191,75192,75194,75196,75198,75200],{"class":749,"line":1510},[747,75193,75037],{"class":753},[747,75195,856],{"class":757},[747,75197,969],{"class":757},[747,75199,75044],{"class":802},[747,75201,975],{"class":757},[747,75203,75204,75206,75208],{"class":749,"line":1520},[747,75205,75075],{"class":753},[747,75207,856],{"class":757},[747,75209,24697],{"class":19332},[747,75211,75212],{"class":749,"line":1525},[747,75213,75084],{"class":802},[747,75215,75216,75218,75220],{"class":749,"line":1533},[747,75217,75089],{"class":753},[747,75219,856],{"class":757},[747,75221,24697],{"class":19332},[747,75223,75224],{"class":749,"line":1539},[747,75225,75098],{"class":802},[747,75227,75228,75230],{"class":749,"line":1549},[747,75229,75103],{"class":753},[747,75231,758],{"class":757},[747,75233,75234,75236,75238],{"class":749,"line":1554},[747,75235,75110],{"class":753},[747,75237,856],{"class":757},[747,75239,75115],{"class":802},[747,75241,75242,75244],{"class":749,"line":1562},[747,75243,66025],{"class":753},[747,75245,758],{"class":757},[747,75247,75248,75250],{"class":749,"line":1568},[747,75249,66032],{"class":753},[747,75251,758],{"class":757},[747,75253,75254,75256,75258],{"class":749,"line":1577},[747,75255,66039],{"class":753},[747,75257,856],{"class":757},[747,75259,75260],{"class":802}," 15Gi\n",[747,75262,75263,75266],{"class":749,"line":1582},[747,75264,75265],{"class":753},"  ingest",[747,75267,758],{"class":757},[747,75269,75270,75272,75274],{"class":749,"line":1588},[747,75271,14746],{"class":753},[747,75273,856],{"class":757},[747,75275,18691],{"class":1895},[747,75277,75278],{"class":749,"line":1594},[747,75279,75014],{"class":772},[747,75281,75282],{"class":749,"line":1600},[747,75283,75019],{"class":772},[747,75285,75286,75288],{"class":749,"line":4804},[747,75287,28941],{"class":753},[747,75289,758],{"class":757},[747,75291,75292,75294],{"class":749,"line":4810},[747,75293,75030],{"class":753},[747,75295,758],{"class":757},[747,75297,75298,75300,75302,75304,75306],{"class":749,"line":4816},[747,75299,75037],{"class":753},[747,75301,856],{"class":757},[747,75303,969],{"class":757},[747,75305,75044],{"class":802},[747,75307,975],{"class":757},[747,75309,75310,75312],{"class":749,"line":4822},[747,75311,75051],{"class":753},[747,75313,758],{"class":757},[747,75315,75316,75318,75320,75322,75324],{"class":749,"line":4828},[747,75317,75037],{"class":753},[747,75319,856],{"class":757},[747,75321,969],{"class":757},[747,75323,75044],{"class":802},[747,75325,975],{"class":757},[747,75327,75328,75330,75332],{"class":749,"line":4834},[747,75329,75075],{"class":753},[747,75331,856],{"class":757},[747,75333,24697],{"class":19332},[747,75335,75336],{"class":749,"line":4840},[747,75337,75084],{"class":802},[747,75339,75340,75342,75344],{"class":749,"line":4846},[747,75341,75089],{"class":753},[747,75343,856],{"class":757},[747,75345,24697],{"class":19332},[747,75347,75348],{"class":749,"line":4852},[747,75349,75350],{"class":802},"      # your addtional elasticsearch ingest configuration here\n",[613,75352,75354],{"id":75353},"curator-manifest","Curator manifest",[523,75356,75357],{},"Curator manifests are very primitive. You have to provide a full configuration for it.\nI may improve them in the future.",[738,75359,75361],{"className":740,"code":75360,"language":742,"meta":743,"style":743},"apiVersion: \"elasticsearch.zerbytes.net\u002Fv1alpha1\"\nkind: Curator\nmetadata:\n  name: \"example\"\nspec:\n  schedule: \"1 0 * * *\"\n  config: |\n  # Remember, leave a key empty if there is no value.  None will be a string,\n  # not a Python \"NoneType\"\n  client:\n    hosts:\n      - elasticsearch-example\n    port: 9200\n    url_prefix:\n    use_ssl: False\n    certificate:\n    client_cert:\n    client_key:\n    ssl_no_validate: False\n    http_auth: \"elastic:changeme\"\n    timeout: 30\n    master_only: False\n  logging:\n    loglevel: INFO\n    logfile:\n    logformat: default\n    blacklist: ['elasticsearch', 'urllib3']\n  actions: |\n    # Remember, leave a key empty if there is no value.  None will be a string,\n    # not a Python \"NoneType\"\n    #\n    # Also remember that all examples have 'disable_action' set to True.  If you\n    # want to use this action as a template, be sure to set this to False after\n    # copying it.\n    actions:\n      1:\n        action: delete_indices\n        description: \"Clean up ES by deleting old indices\"\n        options:\n          timeout_override:\n          continue_if_exception: False\n          disable_action: False\n          ignore_empty_list: True\n          timeout_override: 300\n        filters:\n        - filtertype: age\n          source: name\n          direction: older\n          timestring: '%Y.%m.%d'\n          unit: days\n          unit_count: 4\n          field:\n          stats_result:\n          epoch:\n          exclude: False\n",[567,75362,75363,75375,75384,75390,75402,75408,75422,75430,75435,75440,75445,75450,75455,75460,75465,75470,75475,75480,75485,75490,75495,75500,75505,75510,75515,75520,75525,75530,75535,75540,75545,75549,75554,75559,75564,75569,75574,75579,75584,75589,75594,75599,75604,75609,75614,75619,75624,75629,75634,75639,75644,75649,75654,75659,75664],{"__ignoreMap":743},[747,75364,75365,75367,75369,75371,75373],{"class":749,"line":750},[747,75366,12949],{"class":753},[747,75368,856],{"class":757},[747,75370,969],{"class":757},[747,75372,74888],{"class":802},[747,75374,975],{"class":757},[747,75376,75377,75379,75381],{"class":749,"line":761},[747,75378,12963],{"class":753},[747,75380,856],{"class":757},[747,75382,75383],{"class":802}," Curator\n",[747,75385,75386,75388],{"class":749,"line":769},[747,75387,12973],{"class":753},[747,75389,758],{"class":757},[747,75391,75392,75394,75396,75398,75400],{"class":749,"line":776},[747,75393,12980],{"class":753},[747,75395,856],{"class":757},[747,75397,969],{"class":757},[747,75399,74920],{"class":802},[747,75401,975],{"class":757},[747,75403,75404,75406],{"class":749,"line":784},[747,75405,12990],{"class":753},[747,75407,758],{"class":757},[747,75409,75410,75413,75415,75417,75420],{"class":749,"line":790},[747,75411,75412],{"class":753},"  schedule",[747,75414,856],{"class":757},[747,75416,969],{"class":757},[747,75418,75419],{"class":802},"1 0 * * *",[747,75421,975],{"class":757},[747,75423,75424,75426,75428],{"class":749,"line":796},[747,75425,12997],{"class":753},[747,75427,856],{"class":757},[747,75429,24697],{"class":19332},[747,75431,75432],{"class":749,"line":806},[747,75433,75434],{"class":802},"  # Remember, leave a key empty if there is no value.  None will be a string,\n",[747,75436,75437],{"class":749,"line":814},[747,75438,75439],{"class":802},"  # not a Python \"NoneType\"\n",[747,75441,75442],{"class":749,"line":822},[747,75443,75444],{"class":802},"  client:\n",[747,75446,75447],{"class":749,"line":830},[747,75448,75449],{"class":802},"    hosts:\n",[747,75451,75452],{"class":749,"line":836},[747,75453,75454],{"class":802},"      - elasticsearch-example\n",[747,75456,75457],{"class":749,"line":842},[747,75458,75459],{"class":802},"    port: 9200\n",[747,75461,75462],{"class":749,"line":850},[747,75463,75464],{"class":802},"    url_prefix:\n",[747,75466,75467],{"class":749,"line":863},[747,75468,75469],{"class":802},"    use_ssl: False\n",[747,75471,75472],{"class":749,"line":869},[747,75473,75474],{"class":802},"    certificate:\n",[747,75476,75477],{"class":749,"line":877},[747,75478,75479],{"class":802},"    client_cert:\n",[747,75481,75482],{"class":749,"line":1015},[747,75483,75484],{"class":802},"    client_key:\n",[747,75486,75487],{"class":749,"line":1021},[747,75488,75489],{"class":802},"    ssl_no_validate: False\n",[747,75491,75492],{"class":749,"line":1027},[747,75493,75494],{"class":802},"    http_auth: \"elastic:changeme\"\n",[747,75496,75497],{"class":749,"line":1033},[747,75498,75499],{"class":802},"    timeout: 30\n",[747,75501,75502],{"class":749,"line":1039},[747,75503,75504],{"class":802},"    master_only: False\n",[747,75506,75507],{"class":749,"line":1054},[747,75508,75509],{"class":802},"  logging:\n",[747,75511,75512],{"class":749,"line":1060},[747,75513,75514],{"class":802},"    loglevel: INFO\n",[747,75516,75517],{"class":749,"line":1066},[747,75518,75519],{"class":802},"    logfile:\n",[747,75521,75522],{"class":749,"line":1081},[747,75523,75524],{"class":802},"    logformat: default\n",[747,75526,75527],{"class":749,"line":1087},[747,75528,75529],{"class":802},"    blacklist: ['elasticsearch', 'urllib3']\n",[747,75531,75532],{"class":749,"line":1102},[747,75533,75534],{"class":802},"  actions: |\n",[747,75536,75537],{"class":749,"line":1110},[747,75538,75539],{"class":802},"    # Remember, leave a key empty if there is no value.  None will be a string,\n",[747,75541,75542],{"class":749,"line":1117},[747,75543,75544],{"class":802},"    # not a Python \"NoneType\"\n",[747,75546,75547],{"class":749,"line":1123},[747,75548,21732],{"class":802},[747,75550,75551],{"class":749,"line":1129},[747,75552,75553],{"class":802},"    # Also remember that all examples have 'disable_action' set to True.  If you\n",[747,75555,75556],{"class":749,"line":1142},[747,75557,75558],{"class":802},"    # want to use this action as a template, be sure to set this to False after\n",[747,75560,75561],{"class":749,"line":1150},[747,75562,75563],{"class":802},"    # copying it.\n",[747,75565,75566],{"class":749,"line":1157},[747,75567,75568],{"class":802},"    actions:\n",[747,75570,75571],{"class":749,"line":1163},[747,75572,75573],{"class":802},"      1:\n",[747,75575,75576],{"class":749,"line":1168},[747,75577,75578],{"class":802},"        action: delete_indices\n",[747,75580,75581],{"class":749,"line":1174},[747,75582,75583],{"class":802},"        description: \"Clean up ES by deleting old indices\"\n",[747,75585,75586],{"class":749,"line":1480},[747,75587,75588],{"class":802},"        options:\n",[747,75590,75591],{"class":749,"line":1491},[747,75592,75593],{"class":802},"          timeout_override:\n",[747,75595,75596],{"class":749,"line":1496},[747,75597,75598],{"class":802},"          continue_if_exception: False\n",[747,75600,75601],{"class":749,"line":1502},[747,75602,75603],{"class":802},"          disable_action: False\n",[747,75605,75606],{"class":749,"line":1510},[747,75607,75608],{"class":802},"          ignore_empty_list: True\n",[747,75610,75611],{"class":749,"line":1520},[747,75612,75613],{"class":802},"          timeout_override: 300\n",[747,75615,75616],{"class":749,"line":1525},[747,75617,75618],{"class":802},"        filters:\n",[747,75620,75621],{"class":749,"line":1533},[747,75622,75623],{"class":802},"        - filtertype: age\n",[747,75625,75626],{"class":749,"line":1539},[747,75627,75628],{"class":802},"          source: name\n",[747,75630,75631],{"class":749,"line":1549},[747,75632,75633],{"class":802},"          direction: older\n",[747,75635,75636],{"class":749,"line":1554},[747,75637,75638],{"class":802},"          timestring: '%Y.%m.%d'\n",[747,75640,75641],{"class":749,"line":1562},[747,75642,75643],{"class":802},"          unit: days\n",[747,75645,75646],{"class":749,"line":1568},[747,75647,75648],{"class":802},"          unit_count: 4\n",[747,75650,75651],{"class":749,"line":1577},[747,75652,75653],{"class":802},"          field:\n",[747,75655,75656],{"class":749,"line":1582},[747,75657,75658],{"class":802},"          stats_result:\n",[747,75660,75661],{"class":749,"line":1588},[747,75662,75663],{"class":802},"          epoch:\n",[747,75665,75666],{"class":749,"line":1594},[747,75667,75668],{"class":802},"          exclude: False\n",[2979,75670],{},[523,75672,75673],{},"If you have any questions about the operator or the usage, feel free to open an issue on GitHub or leave a comment.",[523,75675,13967],{},[2890,75677,75678],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":743,"searchDepth":761,"depth":761,"links":75680},[75681,75682,75683],{"id":74722,"depth":769,"text":74723},{"id":74748,"depth":769,"text":74749},{"id":74855,"depth":761,"text":63093,"children":75684},[75685,75686,75687],{"id":74858,"depth":769,"text":74859},{"id":74868,"depth":769,"text":74869},{"id":75353,"depth":769,"text":75354},"2017-05-30T10:51:42+02:00","Installation and examples for using my elasticsearch operator (GitHub galexrt\u002Felasticsearch-operator).",{"src":58363},{"tags":75692},[124,15485,64833,18882],"\u002Fblog\u002F2017\u002Fkubernetes-elasticsearch-operator",{"title":74696,"description":75689},"3.blog\u002F2017\u002Fkubernetes-elasticsearch-operator","GftctqlxLNv31DpP4-oEc2K0VvKhR-2WgV0xDuhIaXk",{"id":75698,"title":75699,"authors":75700,"badge":518,"body":75703,"date":75726,"description":75727,"extension":2911,"image":75728,"meta":75729,"navigation":1254,"path":75731,"seo":75732,"stem":75733,"__hash__":75734},"posts\u002F3.blog\u002F2017\u002Fdocker-presentation.md","(Old) Docker Presentation",[75701],{"name":514,"to":515,"avatar":75702},{"src":517},{"type":520,"value":75704,"toc":75724},[75705,75708,75717,75719,75722],[523,75706,75707],{},"I created this Docker presentation about three years ago (2014).",[6072,75709,75710,75714],{},[523,75711,75712],{},[584,75713,6189],{},[523,75715,75716],{},"The presentation is in german.",[523,75718,58352],{},[18903,75720],{"src":75721,"frameBorder":3579,"height":18906,"allowFullScreen":5306,"mozallowfullscreen":5306,"webkitallowfullscreen":5306},"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002F1FA4F3UFoPUwXUf3TV_CucoOyNtvbaz8513ocqc78NWc\u002Fembed?start=false&loop=true&delayms=5000",[523,75723,52336],{},{"title":743,"searchDepth":761,"depth":761,"links":75725},[],"2017-04-27T09:15:00+02:00","An older presentation of I made for my training.",{"src":12171},{"tags":75730},[18918,12175],"\u002Fblog\u002F2017\u002Fdocker-presentation",{"title":75699,"description":75727},"3.blog\u002F2017\u002Fdocker-presentation","5sd0uNoBqNkzNIFexuMGEZxej6z3SDuvjA597RUWm0Q",{"id":75736,"title":75737,"authors":75738,"badge":518,"body":75741,"date":75763,"description":75764,"extension":2911,"image":75765,"meta":75766,"navigation":1254,"path":75768,"seo":75769,"stem":75770,"__hash__":75771},"posts\u002F3.blog\u002F2017\u002Fkubernetes-v3-presentation.md","Kubernetes v3 Presentation",[75739],{"name":514,"to":515,"avatar":75740},{"src":517},{"type":520,"value":75742,"toc":75761},[75743,75746,75754,75756,75759],[523,75744,75745],{},"This is an updated version of my Kubernetes v2 presentation.",[6072,75747,75748,75752],{},[523,75749,75750],{},[584,75751,6189],{},[523,75753,75716],{},[523,75755,58352],{},[18903,75757],{"src":75758,"frameBorder":3579,"height":18906,"allowFullScreen":5306,"mozallowfullscreen":5306,"webkitallowfullscreen":5306},"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002F1BBArN0yWdTbK1-Xy63d-NiwOT3QGHPvlQN7_pTxobtE\u002Fembed?start=false&loop=true&delayms=5000",[523,75760,52336],{},{"title":743,"searchDepth":761,"depth":761,"links":75762},[],"2017-01-27T13:33:00+02:00","The latest version of my Kubernetes presentation. Containing some of the new Kubernetes features.",{"src":27584},{"tags":75767},[18918,124],"\u002Fblog\u002F2017\u002Fkubernetes-v3-presentation",{"title":75737,"description":75764},"3.blog\u002F2017\u002Fkubernetes-v3-presentation","OgOXWxJab2SGgJt2u4T396uLMsUmqtCi2usHvsecNHc",{"id":75773,"title":75774,"authors":75775,"badge":518,"body":75778,"date":75808,"description":75809,"extension":2911,"image":75810,"meta":75812,"navigation":1254,"path":75815,"seo":75816,"stem":75817,"__hash__":75818},"posts\u002F3.blog\u002F2016\u002Fmy-blog-layout-has-been-updated.md","My Blog Layout has been updated",[75776],{"name":514,"to":515,"avatar":75777},{"src":517},{"type":520,"value":75779,"toc":75806},[75780,75783,75785,75792],[523,75781,75782],{},"I finally had some time to add Google Custom Search Engine to my Blog.",[2979,75784],{},[523,75786,75787,75788,75791],{},"I fixed some layout bugs with Bootstrap wells too. Some ",[567,75789,75790],{},"well","-classes were placed at the wrong level making some of them look bigger than others when viewing the page from mobile.",[523,75793,75794,75795,75800,75801,1909],{},"My fork of ",[527,75796,75799],{"href":75797,"rel":75798},"https:\u002F\u002Fgithub.com\u002FXadillaX\u002Fhexadillax",[531],"XadillaX\u002Fhexadillax"," Hexo theme is located at ",[527,75802,75805],{"href":75803,"rel":75804},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fhexadillax",[531],"galexrt\u002Fhexadillax",{"title":743,"searchDepth":761,"depth":761,"links":75807},[],"2016-09-16T13:20:10+02:00","The design of my blog has been updated with Google Custom Search Engine and some other fixes.",{"src":75811},"\u002Fblog\u002F2016\u002Fmy-blog-layout-has-been-updated\u002Fblog_gce_search_bar.png",{"tags":75813},[75814],"My Blog","\u002Fblog\u002F2016\u002Fmy-blog-layout-has-been-updated",{"title":75774,"description":75809},"3.blog\u002F2016\u002Fmy-blog-layout-has-been-updated","DCad4giHWTpad20PUhFdWAqOZBogV49D2-rFg1mmRPs",{"id":75820,"title":75821,"authors":518,"badge":518,"body":75822,"date":76045,"description":76046,"extension":2911,"image":518,"meta":76047,"navigation":1254,"path":76049,"seo":76050,"stem":76051,"__hash__":76052},"posts\u002F3.blog\u002F2016\u002Fiptables-using-statistic-module.md","iptables: Using statistic module",{"type":520,"value":75823,"toc":76041},[75824,75828,75831,75834,75974,75978,75981,76029,76031,76038],[535,75825,75827],{"id":75826},"load-balance-with-iptables-between-two-servers","\"Load Balance\" with iptables between two servers",[523,75829,75830],{},"Kubernetes uses this method to load balance traffic between pods in the cluster.",[523,75832,75833],{},"The commands below create separate chains for each server and for the load balancing of port 80 in this case:",[738,75835,75837],{"className":1621,"code":75836,"language":1623,"meta":743,"style":743},"iptables -t nat -N LB_PORT80\niptables -t nat -N LB_PORT80_SERVER1\niptables -t nat -A LB_PORT80 \\\n    -m statistic --mode random --probability 0.5000 \\\n    -j LB_PORT80_SERVER1\niptables -t nat -N LB_PORT80_SERVER2\niptables -t nat -A LB_PORT80 \\\n    -j LB_PORT80_SERVER2\niptables -t nat -A INPUT -p tcp -m tcp --dport 80 -j LB_PORT80\n",[567,75838,75839,75853,75866,75881,75902,75909,75922,75936,75942],{"__ignoreMap":743},[747,75840,75841,75843,75845,75847,75850],{"class":749,"line":750},[747,75842,8254],{"class":1630},[747,75844,9736],{"class":802},[747,75846,37170],{"class":802},[747,75848,75849],{"class":802}," -N",[747,75851,75852],{"class":802}," LB_PORT80\n",[747,75854,75855,75857,75859,75861,75863],{"class":749,"line":761},[747,75856,8254],{"class":1630},[747,75858,9736],{"class":802},[747,75860,37170],{"class":802},[747,75862,75849],{"class":802},[747,75864,75865],{"class":802}," LB_PORT80_SERVER1\n",[747,75867,75868,75870,75872,75874,75876,75879],{"class":749,"line":769},[747,75869,8254],{"class":1630},[747,75871,9736],{"class":802},[747,75873,37170],{"class":802},[747,75875,1974],{"class":802},[747,75877,75878],{"class":802}," LB_PORT80",[747,75880,1641],{"class":1640},[747,75882,75883,75886,75889,75892,75894,75897,75900],{"class":749,"line":776},[747,75884,75885],{"class":802},"    -m",[747,75887,75888],{"class":802}," statistic",[747,75890,75891],{"class":802}," --mode",[747,75893,42933],{"class":802},[747,75895,75896],{"class":802}," --probability",[747,75898,75899],{"class":1895}," 0.5000",[747,75901,1641],{"class":1640},[747,75903,75904,75907],{"class":749,"line":784},[747,75905,75906],{"class":802},"    -j",[747,75908,75865],{"class":802},[747,75910,75911,75913,75915,75917,75919],{"class":749,"line":790},[747,75912,8254],{"class":1630},[747,75914,9736],{"class":802},[747,75916,37170],{"class":802},[747,75918,75849],{"class":802},[747,75920,75921],{"class":802}," LB_PORT80_SERVER2\n",[747,75923,75924,75926,75928,75930,75932,75934],{"class":749,"line":796},[747,75925,8254],{"class":1630},[747,75927,9736],{"class":802},[747,75929,37170],{"class":802},[747,75931,1974],{"class":802},[747,75933,75878],{"class":802},[747,75935,1641],{"class":1640},[747,75937,75938,75940],{"class":749,"line":806},[747,75939,75906],{"class":802},[747,75941,75921],{"class":802},[747,75943,75944,75946,75948,75950,75952,75954,75956,75959,75961,75963,75966,75969,75972],{"class":749,"line":814},[747,75945,8254],{"class":1630},[747,75947,9736],{"class":802},[747,75949,37170],{"class":802},[747,75951,1974],{"class":802},[747,75953,46422],{"class":802},[747,75955,7094],{"class":802},[747,75957,75958],{"class":802}," tcp",[747,75960,3368],{"class":802},[747,75962,75958],{"class":802},[747,75964,75965],{"class":802}," --dport",[747,75967,75968],{"class":1895}," 80",[747,75970,75971],{"class":802}," -j",[747,75973,75852],{"class":802},[535,75975,75977],{"id":75976},"dropping-packages-with-a-x-probability-from-a-specific-ip-address","Dropping packages with a X% probability from a specific IP address",[523,75979,75980],{},"My favorite rule to mess with people ;)",[738,75982,75984],{"className":1621,"code":75983,"language":1623,"meta":743,"style":743},"iptables -A INPUT \\\n    -s IP_ADDRESS \\\n    -m statistic --mode random --probability 0.5000 \\\n    -j DROP\n",[567,75985,75986,75996,76006,76022],{"__ignoreMap":743},[747,75987,75988,75990,75992,75994],{"class":749,"line":750},[747,75989,8254],{"class":1630},[747,75991,1974],{"class":802},[747,75993,46422],{"class":802},[747,75995,1641],{"class":1640},[747,75997,75998,76001,76004],{"class":749,"line":761},[747,75999,76000],{"class":802},"    -s",[747,76002,76003],{"class":802}," IP_ADDRESS",[747,76005,1641],{"class":1640},[747,76007,76008,76010,76012,76014,76016,76018,76020],{"class":749,"line":769},[747,76009,75885],{"class":802},[747,76011,75888],{"class":802},[747,76013,75891],{"class":802},[747,76015,42933],{"class":802},[747,76017,75896],{"class":802},[747,76019,75899],{"class":1895},[747,76021,1641],{"class":1640},[747,76023,76024,76026],{"class":749,"line":776},[747,76025,75906],{"class":802},[747,76027,76028],{"class":802}," DROP\n",[2979,76030],{},[523,76032,76033,76034,76037],{},"These are only two examples, but there many more possibilities to utilize the ",[567,76035,76036],{},"iptables statistic"," module.",[2890,76039,76040],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":743,"searchDepth":761,"depth":761,"links":76042},[76043,76044],{"id":75826,"depth":761,"text":75827},{"id":75976,"depth":761,"text":75977},"2016-09-14T15:50:49+02:00","This post will show some examples using the iptables statistic module random mode.",{"tags":76048},[193,8254],"\u002Fblog\u002F2016\u002Fiptables-using-statistic-module",{"title":75821,"description":76046},"3.blog\u002F2016\u002Fiptables-using-statistic-module","qQGf3Qr_HAnt41GklRTMgDrHMCokbmIgzf7wINoVmbI",{"id":76054,"title":76055,"authors":518,"badge":518,"body":76056,"date":76524,"description":76525,"extension":2911,"image":76526,"meta":76528,"navigation":1254,"path":76530,"seo":76531,"stem":76532,"__hash__":76533},"posts\u002F3.blog\u002F2016\u002Fzulip-installation.md","Zulip: Installation",{"type":520,"value":76057,"toc":76510},[76058,76066,76069,76071,76081,76088,76092,76101,76104,76122,76129,76133,76136,76148,76154,76172,76177,76180,76233,76247,76250,76254,76257,76265,76274,76277,76281,76284,76297,76301,76307,76310,76355,76358,76362,76365,76383,76386,76402,76411,76414,76420,76446,76449,76453,76456,76459,76467,76469,76473,76477,76480,76496,76498,76500,76507],[6072,76059,76060],{},[523,76061,76062,76065],{},[584,76063,76064],{},"Please note",": This post is more of a \"draft\" that may not be on my level of post quality.",[523,76067,76068],{},"Zulip is a powerful open source group chat able to handle multi channel communications. It runs on python.",[535,76070,22268],{"id":22267},[523,76072,76073,76074,76077,76078,76080],{},"An Ubuntu Server with at least ",[567,76075,76076],{},"2GB"," of RAM (",[567,76079,76076],{}," RAM is currently the recommended amount for a small site).\nMy example server for this tutorial has the following address:",[668,76082,76083],{},[638,76084,76085],{},[567,76086,76087],{},"203.0.113.1 zulip-tutorial-example",[535,76089,76091],{"id":76090},"preparing-your-server-for-zulip","Preparing your server for Zulip",[6072,76093,76094,76098],{},[523,76095,76096],{},[584,76097,6189],{},[523,76099,76100],{},"The current Zulip installation deployment uses one full server! The deployment doesn't care about other services on the server.",[523,76102,76103],{},"Make sure your server is at the latest version before continuing with the\nTo update all packages on Ubuntu run:",[738,76105,76107],{"className":1621,"code":76106,"language":1623,"meta":743,"style":743},"apt-get update\napt-get upgrade\n",[567,76108,76109,76115],{"__ignoreMap":743},[747,76110,76111,76113],{"class":749,"line":750},[747,76112,67035],{"class":1630},[747,76114,67038],{"class":802},[747,76116,76117,76119],{"class":749,"line":761},[747,76118,67035],{"class":1630},[747,76120,76121],{"class":802}," upgrade\n",[523,76123,76124,76125,76128],{},"Confirm with (depending on the system locale) with ",[567,76126,76127],{},"y",".`",[535,76130,76132],{"id":76131},"step-1-downloading-zulip","Step 1 - Downloading Zulip",[523,76134,76135],{},"Please login as root user.\nOn most Ubuntu systems, you would use",[738,76137,76139],{"className":1621,"code":76138,"language":1623,"meta":743,"style":743},"sudo -i\n",[567,76140,76141],{"__ignoreMap":743},[747,76142,76143,76145],{"class":749,"line":750},[747,76144,3376],{"class":1630},[747,76146,76147],{"class":802}," -i\n",[523,76149,76150,76151,1909],{},"to switch to the root user.\nNext up we make sure that we are in the root user's home directory ",[567,76152,76153],{},"\u002Froot",[738,76155,76157],{"className":1621,"code":76156,"language":1623,"meta":743,"style":743},"cd \u002Froot\npwd\n",[567,76158,76159,76167],{"__ignoreMap":743},[747,76160,76161,76164],{"class":749,"line":750},[747,76162,76163],{"class":4574},"cd",[747,76165,76166],{"class":802}," \u002Froot\n",[747,76168,76169],{"class":749,"line":761},[747,76170,76171],{"class":4574},"pwd\n",[523,76173,76174,76176],{},[567,76175,10672],{}," prints the current working directoy.",[523,76178,76179],{},"For the latest Zulip version the download and extraction commands are:",[738,76181,76183],{"className":1621,"code":76182,"language":1623,"meta":743,"style":743},"cd \u002Froot\nwget https:\u002F\u002Fwww.zulip.com\u002Fdist\u002Freleases\u002Fzulip-server-latest.tar.gz\nrm -rf \u002Froot\u002Fzulip && mkdir \u002Froot\u002Fzulip\ntar -xf zulip-server-latest.tar.gz --directory=\u002Froot\u002Fzulip --strip-components=1\n",[567,76184,76185,76191,76198,76216],{"__ignoreMap":743},[747,76186,76187,76189],{"class":749,"line":750},[747,76188,76163],{"class":4574},[747,76190,76166],{"class":802},[747,76192,76193,76195],{"class":749,"line":761},[747,76194,3337],{"class":1630},[747,76196,76197],{"class":802}," https:\u002F\u002Fwww.zulip.com\u002Fdist\u002Freleases\u002Fzulip-server-latest.tar.gz\n",[747,76199,76200,76202,76205,76208,76210,76213],{"class":749,"line":769},[747,76201,11411],{"class":1630},[747,76203,76204],{"class":802}," -rf",[747,76206,76207],{"class":802}," \u002Froot\u002Fzulip",[747,76209,37162],{"class":757},[747,76211,76212],{"class":1630}," mkdir",[747,76214,76215],{"class":802}," \u002Froot\u002Fzulip\n",[747,76217,76218,76221,76224,76227,76230],{"class":749,"line":776},[747,76219,76220],{"class":1630},"tar",[747,76222,76223],{"class":802}," -xf",[747,76225,76226],{"class":802}," zulip-server-latest.tar.gz",[747,76228,76229],{"class":802}," --directory=\u002Froot\u002Fzulip",[747,76231,76232],{"class":802}," --strip-components=1\n",[6072,76234,76235,76239],{},[523,76236,76237],{},[584,76238,6189],{},[523,76240,76241,76242,587,76244,76246],{},"You need to have ",[567,76243,76220],{},[567,76245,3337],{}," installed on the server. On most servers these tools are already installed.",[523,76248,76249],{},"Now that we have Zulip downloaded, we can continue to the next step.",[535,76251,76253],{"id":76252},"step-2-install-zulip","Step 2 - Install Zulip",[523,76255,76256],{},"With the following command, we start the Zulip installation.",[6072,76258,76259],{},[523,76260,76261,76264],{},[584,76262,76263],{},"!! WARNING !!"," This will install Zulip to your server and if other applications are also running on this server it can completely mess them up, as mentioned earlier!",[738,76266,76268],{"className":1621,"code":76267,"language":1623,"meta":743,"style":743},"\u002Froot\u002Fzulip\u002Fscripts\u002Fsetup\u002Finstall\n",[567,76269,76270],{"__ignoreMap":743},[747,76271,76272],{"class":749,"line":750},[747,76273,76267],{"class":1630},[523,76275,76276],{},"The command may take some to complete. The command installs Zulip's dependencies and Zulip itself on the server.",[535,76278,76280],{"id":76279},"step-3-checking-the-zulip-installation","Step 3 - Checking the Zulip installation",[523,76282,76283],{},"Navigate to the bottom of the file and check that it reports the success of the installation.\nThe command for opening the installation log file in a \"paginator\" is:",[738,76285,76287],{"className":1621,"code":76286,"language":1623,"meta":743,"style":743},"less \u002Fvar\u002Flog\u002Fzulip\u002Finstall.log\n",[567,76288,76289],{"__ignoreMap":743},[747,76290,76291,76294],{"class":749,"line":750},[747,76292,76293],{"class":1630},"less",[747,76295,76296],{"class":802}," \u002Fvar\u002Flog\u002Fzulip\u002Finstall.log\n",[535,76298,76300],{"id":76299},"step-4-configuring-the-zulip-instance","Step 4 - Configuring the Zulip instance",[523,76302,76303,76304,1909],{},"For Zulip to function you need to set some mandatory settings.\nZulip's config file is located at ",[567,76305,76306],{},"\u002Fetc\u002Fzulip\u002Fsettings.py",[523,76308,76309],{},"The following list contains the mandatory settings.",[668,76311,76312,76318,76324,76329,76335,76341,76347],{},[638,76313,76314,76317],{},[567,76315,76316],{},"EXTERNAL_HOST"," should be your external address.",[638,76319,76320,76323],{},[567,76321,76322],{},"ZULIP_ADMINISTRATOR"," the email of the administrator that will be also shown as the contact email address.",[638,76325,76326],{},[567,76327,76328],{},"AUTHENTICATION_BACKENDS",[638,76330,76331,76334],{},[567,76332,76333],{},"EMAIL_*"," the email server settings, please look at the comments in the file for more information about the variables.",[638,76336,76337,76340],{},[567,76338,76339],{},"DEFAULT_FROM_EMAIL"," the default sender email address used for the outgoing email traffic.",[638,76342,76343,76346],{},[567,76344,76345],{},"NOREPLY_EMAIL_ADDRESS"," the address for noreply in the outgoing email traffic.",[638,76348,76349,76352,76353,1909],{},[567,76350,76351],{},"ALLOWED_HOSTS"," the fully qualified DNS name of the server you installed Zulip on or just set it to ",[567,76354,22721],{},[523,76356,76357],{},"The config file contains a comment above all the variables.\nGo ahead and configure the mandatory values to your needs.",[535,76359,76361],{"id":76360},"step-5-preparing-the-zulip-instance-for-usage","Step 5 - Preparing the Zulip instance for usage",[523,76363,76364],{},"Now that you have Zulip configured, we can now initialize the database.",[738,76366,76368],{"className":1621,"code":76367,"language":1623,"meta":743,"style":743},"su zulip -c \u002Fhome\u002Fzulip\u002Fdeployments\u002Fcurrent\u002Fscripts\u002Fsetup\u002Finitialize-database\n",[567,76369,76370],{"__ignoreMap":743},[747,76371,76372,76375,76378,76380],{"class":749,"line":750},[747,76373,76374],{"class":1630},"su",[747,76376,76377],{"class":802}," zulip",[747,76379,67109],{"class":802},[747,76381,76382],{"class":802}," \u002Fhome\u002Fzulip\u002Fdeployments\u002Fcurrent\u002Fscripts\u002Fsetup\u002Finitialize-database\n",[523,76384,76385],{},"After the database initialization has successfully completed, we should now you should verify that your Zulip email settings are correct:",[738,76387,76389],{"className":1621,"code":76388,"language":1623,"meta":743,"style":743},".\u002Fmanage.py send_test_email YOUR_EMAIL_ADDRESS\n",[567,76390,76391],{"__ignoreMap":743},[747,76392,76393,76396,76399],{"class":749,"line":750},[747,76394,76395],{"class":1630},".\u002Fmanage.py",[747,76397,76398],{"class":802}," send_test_email",[747,76400,76401],{"class":802}," YOUR_EMAIL_ADDRESS\n",[6072,76403,76404,76408],{},[523,76405,76406],{},[584,76407,6189],{},[523,76409,76410],{},"Replace the placeholders with your own values.",[523,76412,76413],{},"The command above will send a test email to the specified email address, please make sure the email successfully arrives.\nIf it's not in the inbox make sure to also check your SPAM folder.",[523,76415,76416,76417,76419],{},"We need a Zulip organistation for your users.\nFor that we need to switch to the ",[567,76418,8895],{}," user, switch into the current Zulip installation and create a link for realm generation with the command:",[738,76421,76423],{"className":1621,"code":76422,"language":1623,"meta":743,"style":743},"su zulip\ncd \u002Fhome\u002Fzulip\u002Fdeployments\u002Fcurrent\n.\u002Fmanage.py generate_realm_creation_link\n",[567,76424,76425,76432,76439],{"__ignoreMap":743},[747,76426,76427,76429],{"class":749,"line":750},[747,76428,76374],{"class":1630},[747,76430,76431],{"class":802}," zulip\n",[747,76433,76434,76436],{"class":749,"line":761},[747,76435,76163],{"class":4574},[747,76437,76438],{"class":802}," \u002Fhome\u002Fzulip\u002Fdeployments\u002Fcurrent\n",[747,76440,76441,76443],{"class":749,"line":769},[747,76442,76395],{"class":1630},[747,76444,76445],{"class":802}," generate_realm_creation_link\n",[523,76447,76448],{},"Go to the link the last command outputs and you will be prompted with a form for an account and realm creation.\nA realm is like an organization.",[535,76450,76452],{"id":76451},"step-6-using-your-zulip-instance","Step 6 - Using your Zulip instance",[523,76454,76455],{},"Now just navigate to your Zulip instance and if you need to login go ahead.",[523,76457,76458],{},"You now have a working Zulip instance!",[523,76460,76461,76462,1909],{},"If you want to read more about configuration and the integration possibilities you can go to the official documentation of Zulip.\nSee ",[527,76463,76466],{"href":76464,"rel":76465},"https:\u002F\u002Fzulip.readthedocs.io\u002Fen\u002Flatest\u002Findex.html",[531],"Zulip Official Documentation",[2979,76468],{},[535,76470,76472],{"id":76471},"tips-and-tricks","Tips and Tricks",[613,76474,76476],{"id":76475},"restarting-zulip","Restarting Zulip",[523,76478,76479],{},"Use the below command to restart your Zulip instance, after making changes to the config:",[738,76481,76483],{"className":1621,"code":76482,"language":1623,"meta":743,"style":743},"su zulip -c \u002Fhome\u002Fzulip\u002Fdeployments\u002Fcurrent\u002Fscripts\u002Frestart-server\n",[567,76484,76485],{"__ignoreMap":743},[747,76486,76487,76489,76491,76493],{"class":749,"line":750},[747,76488,76374],{"class":1630},[747,76490,76377],{"class":802},[747,76492,67109],{"class":802},[747,76494,76495],{"class":802}," \u002Fhome\u002Fzulip\u002Fdeployments\u002Fcurrent\u002Fscripts\u002Frestart-server\n",[2979,76497],{},[535,76499,207],{"id":26330},[523,76501,76502,76503,1909],{},"A good guide for troubleshooting can be found on the official documentation of Zulip ",[527,76504,3396],{"href":76505,"rel":76506},"https:\u002F\u002Fzulip.readthedocs.io\u002Fen\u002Flatest\u002Fprod-troubleshooting.html",[531],[2890,76508,76509],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}",{"title":743,"searchDepth":761,"depth":761,"links":76511},[76512,76513,76514,76515,76516,76517,76518,76519,76520,76523],{"id":22267,"depth":761,"text":22268},{"id":76090,"depth":761,"text":76091},{"id":76131,"depth":761,"text":76132},{"id":76252,"depth":761,"text":76253},{"id":76279,"depth":761,"text":76280},{"id":76299,"depth":761,"text":76300},{"id":76360,"depth":761,"text":76361},{"id":76451,"depth":761,"text":76452},{"id":76471,"depth":761,"text":76472,"children":76521},[76522],{"id":76475,"depth":769,"text":76476},{"id":26330,"depth":761,"text":207},"2016-09-14T09:23:42+02:00","A tutorial that guides you through installing Zulip.",{"src":76527},"\u002Fblog\u002F2016\u002Fzulip-installation\u002Fzulip-icon-512x512.png",{"tags":76529},[8843,74723],"\u002Fblog\u002F2016\u002Fzulip-installation",{"title":76055,"description":76525},"3.blog\u002F2016\u002Fzulip-installation","9VcR-miX2pQW1CB6riV85QIABaLE2Q00ZShzTwinuVI",{"id":76535,"title":76536,"authors":518,"badge":518,"body":76537,"date":76564,"description":76565,"extension":2911,"image":76566,"meta":76567,"navigation":1254,"path":76570,"seo":76571,"stem":76572,"__hash__":76573},"posts\u002F3.blog\u002F2016\u002Fkubernetes-interactive-bootcamp.md","Kubernetes Interactive Bootcamp",{"type":520,"value":76538,"toc":76562},[76539,76544,76547,76555],[523,76540,76541],{},[3069,76542],{"alt":27731,"src":76543},"\u002Fblog\u002F2016\u002Fkubernetes-interactive-bootcamp\u002Fpost_title_image.png",[523,76545,76546],{},"I just found out that Kubernetes has an interactive bootcamp available.",[523,76548,76549,76550,1909],{},"Here is the link to it: ",[527,76551,76554],{"href":76552,"rel":76553},"http:\u002F\u002Fkubernetes.io\u002Fkubernetes-bootcamp\u002Findex.html",[531],"Kubernetes Bootcamp",[523,76556,76557,76558,1909],{},"The GitHub repo of it is located ",[527,76559,3396],{"href":76560,"rel":76561},"https:\u002F\u002Fgithub.com\u002Fkubernetes\u002Fkubernetes-bootcamp",[531],{"title":743,"searchDepth":761,"depth":761,"links":76563},[],"2016-09-13T15:31:45+02:00","The link to the Kubernetes interactive Bootcamp.",{"src":58363},{"tags":76568},[76569,124],"Link Dumps","\u002Fblog\u002F2016\u002Fkubernetes-interactive-bootcamp",{"title":76536,"description":76565},"3.blog\u002F2016\u002Fkubernetes-interactive-bootcamp","iBp_zzzfCQYc224Kes_fJyQi7IN9_wCh4YCBbMgz2T0",{"id":76575,"title":76576,"authors":76577,"badge":518,"body":76580,"date":76601,"description":76584,"extension":2911,"image":76602,"meta":76603,"navigation":1254,"path":76605,"seo":76606,"stem":76607,"__hash__":76608},"posts\u002F3.blog\u002F2016\u002Fkubernetes-v2-presentation.md","Kubernetes v2 Presentation",[76578],{"name":514,"to":515,"avatar":76579},{"src":517},{"type":520,"value":76581,"toc":76599},[76582,76585,76593,76595,76597],[523,76583,76584],{},"I have update my old Kubernetes presentation to contain the latest Kubernetes features.",[6072,76586,76587,76591],{},[523,76588,76589],{},[584,76590,6189],{},[523,76592,75716],{},[523,76594,58352],{},[18903,76596],{"src":75758,"frameBorder":3579,"height":18906,"allowFullScreen":5306,"mozallowfullscreen":5306,"webkitallowfullscreen":5306},[523,76598,52336],{},{"title":743,"searchDepth":761,"depth":761,"links":76600},[],"2016-09-12T11:35:00+02:00",{"src":58363},{"tags":76604},[18918,124],"\u002Fblog\u002F2016\u002Fkubernetes-v2-presentation",{"title":76576,"description":76584},"3.blog\u002F2016\u002Fkubernetes-v2-presentation","DFKzwe4-KhmArIbw_pyqz-A5VdOGbfgzhTfeh_hRzVk",{"id":76610,"title":76611,"authors":76612,"badge":518,"body":76615,"date":76678,"description":76679,"extension":2911,"image":76680,"meta":76681,"navigation":1254,"path":76683,"seo":76684,"stem":76685,"__hash__":76686},"posts\u002F3.blog\u002F2016\u002Fdocker-live-restore-option-for-containers.md","Docker: Live restore option for containers",[76613],{"name":514,"to":515,"avatar":76614},{"src":517},{"type":520,"value":76616,"toc":76676},[76617],[76618,76619,76621,76637,76639,76651,76663,76666,76668],"div",{"style":76620},"margin:0 auto",[6072,76622,76626,76632,76633],{"className":76623,"dataConversation":76624,"dataLang":76625},[18972],"none","de",[523,76627,76628,76629],{"lang":18973,"dir":18976},"Docker 1.12 has a nice set of improvements that significantly improve the ability to administrate the Docker daemon. ",[527,76630,76631],{"href":76631},"https:\u002F\u002Ft.co\u002FbXt4PwPXRr","— Kelsey Hightower (@kelseyhightower) ",[527,76634,76636],{"href":76635},"https:\u002F\u002Ftwitter.com\u002Fkelseyhightower\u002Fstatus\u002F759558599177674752","31. Juli 2016",[19016,76638],{"async":1254,"src":73786,"charSet":19019},[523,76640,76641,76642,76650],{},"On the ",[527,76643,76646,76647],{"href":76644,"rel":76645},"https:\u002F\u002Fgithub.com\u002Fdocker\u002Fdocker\u002Freleases\u002Ftag\u002Fv1.12.0",[531],"Docker GitHub release\u002Fchangelog page of ",[567,76648,76649],{},"v1.12.0"," under the Runtime section the first point:",[6072,76652,76653],{},[523,76654,76655,76656],{},"Add --live-restore daemon flag to keep containers running when daemon shuts down, and regain control on startup ",[527,76657,76660],{"href":76658,"rel":76659},"https:\u002F\u002Fgithub.com\u002Fdocker\u002Fdocker\u002Fpull\u002F23213",[531],[567,76661,76662],{},"#23213",[523,76664,76665],{},"This new option allows containers to keep running even when stopping, restarting or upgrading the Docker daemon.",[2979,76667],{},[523,76669,76670,38011,76672,76675],{},[584,76671,3103],{},[567,76673,76674],{},"--live-restore"," flag keeps containers running during a Docker daemon update.",{"title":743,"searchDepth":761,"depth":761,"links":76677},[],"2016-08-29T16:09:00+02:00","New flag in Docker daemon runtime allows to keep containers running even when Docker daemon is stopped.",{"src":12171},{"tags":76682},[12175],"\u002Fblog\u002F2016\u002Fdocker-live-restore-option-for-containers",{"title":76611,"description":76679},"3.blog\u002F2016\u002Fdocker-live-restore-option-for-containers","uBnxFga5isHc0UyYvuIlkWx7288vTzFB3Zt3gVrWBvQ",{"id":76688,"title":76689,"authors":76690,"badge":518,"body":76693,"date":77041,"description":77042,"extension":2911,"image":77043,"meta":77045,"navigation":1254,"path":77048,"seo":77049,"stem":77050,"__hash__":77051},"posts\u002F3.blog\u002F2016\u002Fopenvswitch-persistent-ip-configuration-under-rhel-based-distros.md","OpenVSwitch: Persistent IP configuration under Rhel based distros",[76691],{"name":514,"to":515,"avatar":76692},{"src":517},{"type":520,"value":76694,"toc":77035},[76695,76713,76717,76720,76734,76741,76755,76768,76771,76775,76784,76790,76915,76921,76993,76996,76999,77020,77022,77032],[6072,76696,76697,76701],{},[523,76698,76699],{},[584,76700,6189],{},[523,76702,76703,76704,76708,76709,76712],{},"This post is a follow up on my post ",[527,76705,76707],{"href":76706},"\u002Fblog\u002F2016\u002Fopenvswitch-multi-host-overlay-network\u002F","OpenVSwitch: Multi-Host Overlay Network",".\nThe interface in this example is named ",[567,76710,76711],{},"br0",". Change according to your interface.",[535,76714,76716],{"id":76715},"preparing-for-using-the-interface-configurations","Preparing for using the interface configurations",[523,76718,76719],{},"To persist the configurations you can either use the NetworkManager or use good old network-scripts.\nHere I'm going to show how it's done using the good old network-scripts.\nFirst at all we have to disable the NetworkManager service with this command:",[738,76721,76723],{"className":1621,"code":76722,"language":1623,"meta":743,"style":743},"systemctl disable NetworkManager.service\n",[567,76724,76725],{"__ignoreMap":743},[747,76726,76727,76729,76731],{"class":749,"line":750},[747,76728,3202],{"class":1630},[747,76730,60345],{"class":802},[747,76732,76733],{"class":802}," NetworkManager.service\n",[523,76735,76736,76737,76740],{},"And enable the old fashioned ",[567,76738,76739],{},"network.service"," with:",[738,76742,76744],{"className":1621,"code":76743,"language":1623,"meta":743,"style":743},"systemctl enable network.service\n",[567,76745,76746],{"__ignoreMap":743},[747,76747,76748,76750,76752],{"class":749,"line":750},[747,76749,3202],{"class":1630},[747,76751,3205],{"class":802},[747,76753,76754],{"class":802}," network.service\n",[6072,76756,76757,76761],{},[523,76758,76759],{},[584,76760,15250],{},[523,76762,76763,76764,76767],{},"You need to have properly configured network-scripts for your other \"normal\" interfaces too (like ",[567,76765,76766],{},"enp3s0",") or else after a reboot the network connectivity to your server will not work correctly!!",[523,76769,76770],{},"We can now go on to creating the configuration for the OpenVSwitch bridges and ports.",[535,76772,76774],{"id":76773},"creating-configuration-for-an-interface-named-obr0","Creating configuration for an interface named obr0",[6072,76776,76777,76781],{},[523,76778,76779],{},[584,76780,6189],{},[523,76782,76783],{},"You should only need to persist IP configurations for bridge devices and not ports.",[523,76785,76786,76787,856],{},"Create a file called ",[567,76788,76789],{},"\u002Fetc\u002Fsysconfig\u002Fnetwork-scripts\u002Fifcfg-obr0",[738,76791,76793],{"className":32095,"code":76792,"language":32097,"meta":743,"style":743},"NAME=\"obr0\"\nDEVICE=\"obr0\"\nNM_CONTROLLED=\"yes\"\nONBOOT=\"yes\"\nIPV6INIT=no\nTYPE=\"OVSBridge\"\nDEVICETYPE=\"ovs\"\nMTU=1400\nIPADDR=10.244.1.0\nPREFIX=16\n",[567,76794,76795,76808,76821,76835,76848,76858,76871,76885,76895,76905],{"__ignoreMap":743},[747,76796,76797,76799,76801,76803,76806],{"class":749,"line":750},[747,76798,2230],{"class":753},[747,76800,6425],{"class":757},[747,76802,3892],{"class":757},[747,76804,76805],{"class":802},"obr0",[747,76807,975],{"class":757},[747,76809,76810,76813,76815,76817,76819],{"class":749,"line":761},[747,76811,76812],{"class":753},"DEVICE",[747,76814,6425],{"class":757},[747,76816,3892],{"class":757},[747,76818,76805],{"class":802},[747,76820,975],{"class":757},[747,76822,76823,76826,76828,76830,76833],{"class":749,"line":769},[747,76824,76825],{"class":753},"NM_CONTROLLED",[747,76827,6425],{"class":757},[747,76829,3892],{"class":757},[747,76831,76832],{"class":802},"yes",[747,76834,975],{"class":757},[747,76836,76837,76840,76842,76844,76846],{"class":749,"line":776},[747,76838,76839],{"class":753},"ONBOOT",[747,76841,6425],{"class":757},[747,76843,3892],{"class":757},[747,76845,76832],{"class":802},[747,76847,975],{"class":757},[747,76849,76850,76853,76855],{"class":749,"line":784},[747,76851,76852],{"class":753},"IPV6INIT",[747,76854,6425],{"class":757},[747,76856,76857],{"class":1640},"no\n",[747,76859,76860,76862,76864,76866,76869],{"class":749,"line":790},[747,76861,38651],{"class":753},[747,76863,6425],{"class":757},[747,76865,3892],{"class":757},[747,76867,76868],{"class":802},"OVSBridge",[747,76870,975],{"class":757},[747,76872,76873,76876,76878,76880,76883],{"class":749,"line":796},[747,76874,76875],{"class":753},"DEVICETYPE",[747,76877,6425],{"class":757},[747,76879,3892],{"class":757},[747,76881,76882],{"class":802},"ovs",[747,76884,975],{"class":757},[747,76886,76887,76890,76892],{"class":749,"line":806},[747,76888,76889],{"class":753},"MTU",[747,76891,6425],{"class":757},[747,76893,76894],{"class":1640},"1400\n",[747,76896,76897,76900,76902],{"class":749,"line":814},[747,76898,76899],{"class":753},"IPADDR",[747,76901,6425],{"class":757},[747,76903,76904],{"class":1640},"10.244.1.0\n",[747,76906,76907,76910,76912],{"class":749,"line":822},[747,76908,76909],{"class":753},"PREFIX",[747,76911,6425],{"class":757},[747,76913,76914],{"class":1640},"16\n",[6072,76916,76917],{},[523,76918,76919],{},[584,76920,2957],{},[668,76922,76923,76929,76934,76939,76951,76956,76967,76976,76982,76988],{},[638,76924,76925,76928],{},[567,76926,76927],{},"NAME=\"YOUR_INTERFACE_NAME\""," - The name of the interface.",[638,76930,76931,76928],{},[567,76932,76933],{},"DEVICE=\"YOUR_DEVICE_NAME\"",[638,76935,76936,76928],{},[567,76937,76938],{},"NM_CONTROLLED=\"yes\"",[638,76940,76941,76944,76945,76947,76948,76950],{},[567,76942,76943],{},"ONBOOT=\"INTERFACE_NAME\""," - If ",[567,76946,76832],{},", the interface is created when the server boots. Should be ",[567,76949,76832],{}," in most cases.",[638,76952,76953,76928],{},[567,76954,76955],{},"IPV6INIT=\"INTERFACE_NAME\"",[638,76957,76958,76961,76962,76966],{},[567,76959,76960],{},"TYPE=\"OVSBridge\""," - The type of the  interface (see ",[527,76963,76965],{"href":76964},"#OpenVSwitch-related-configuration","OpenVSwitch related configuration"," for more info)",[638,76968,76969,76972,76973,76975],{},[567,76970,76971],{},"DEVICETYPE=\"ovs\""," - The device type of the interface (see ",[527,76974,76965],{"href":76964}," for more info).",[638,76977,76978,76981],{},[567,76979,76980],{},"MTU=YOUR_MTU"," - The MTU of the interface (Only add this option if you know what you are doing).",[638,76983,76984,76987],{},[567,76985,76986],{},"IPADDR=YOUR_INTERFACE_IP_ADDRESS"," - The name of the created interface.",[638,76989,76990,76987],{},[567,76991,76992],{},"PREFIX=YOUR_NETWORK_PREFIX",[535,76994,76965],{"id":76995},"openvswitch-related-configuration",[523,76997,76998],{},"The following options\u002Farguments are important when configuring OpenVSwitch created interfaces:",[668,77000,77001,77012],{},[638,77002,77003,77005,77006,77008,77009,1909],{},[567,77004,76875],{}," - For a bridge interface use ",[567,77007,76868],{}," and for a port interface use ",[567,77010,77011],{},"OVSPort",[638,77013,77014,77016,77017,77019],{},[567,77015,38651],{}," - Always ",[567,77018,76882],{}," for a OpenVSwitch interface.",[535,77021,14526],{"id":14525},[523,77023,77024,77025,77028,77029,77031],{},"That's all you need to do, disable the ",[567,77026,77027],{},"NetworkManager.service"," and activate the good old ",[567,77030,14262],{}," service.",[2890,77033,77034],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}",{"title":743,"searchDepth":761,"depth":761,"links":77036},[77037,77038,77039,77040],{"id":76715,"depth":761,"text":76716},{"id":76773,"depth":761,"text":76774},{"id":76995,"depth":761,"text":76965},{"id":14525,"depth":761,"text":14526},"2016-08-11T18:22:22+02:00","Persisting the interface IP configuration for OpenVSwitch interfaces\u002Fdevices under Rhel based distros.",{"src":77044},"\u002Fblog\u002F2016\u002Fopenvswitch-persistent-ip-configuration-under-rhel-based-distros\u002Fpost_title_image.png",{"tags":77046},[193,77047],"OpenVSwitch","\u002Fblog\u002F2016\u002Fopenvswitch-persistent-ip-configuration-under-rhel-based-distros",{"title":76689,"description":77042},"3.blog\u002F2016\u002Fopenvswitch-persistent-ip-configuration-under-rhel-based-distros","lJHE2gDv89P5DeGnyj_eZ2vleXkO4d4tz50E08EzXrM",{"id":77053,"title":76707,"authors":77054,"badge":518,"body":77057,"date":77857,"description":77858,"extension":2911,"image":77859,"meta":77861,"navigation":1254,"path":77863,"seo":77864,"stem":77865,"__hash__":77866},"posts\u002F3.blog\u002F2016\u002Fopenvswitch-multi-host-overlay-network.md",[77055],{"name":514,"to":515,"avatar":77056},{"src":517},{"type":520,"value":77058,"toc":77845},[77059,77074,77078,77081,77083,77101,77105,77108,77110,77114,77123,77129,77143,77153,77167,77170,77179,77183,77186,77202,77217,77298,77302,77305,77341,77344,77351,77354,77374,77380,77403,77407,77410,77421,77428,77489,77496,77551,77558,77611,77615,77622,77642,77651,77657,77697,77702,77726,77729,77733,77742,77754,77767,77778,77795,77798,77820,77832,77835,77837,77840,77842],[6072,77060,77061,77065],{},[523,77062,77063],{},[584,77064,6189],{},[523,77066,77067,77068,77070,77071,1909],{},"This tutorial is written for Fedora but can be applied to all rhel based systems.\nThe only \"big\" thing you would need to change is the package manager command from ",[567,77069,35405],{}," to for example ",[567,77072,77073],{},"yum",[535,77075,77077],{"id":77076},"what-is-openvswitch","What is OpenVSwitch",[523,77079,77080],{},"OpenVSwitch is a SDN application (Software defined networking) that allows you to create networks and switches on software level.",[535,77082,22268],{"id":22267},[668,77084,77085,77088,77091],{},[638,77086,77087],{},"At least two servers running Fedora 23 or higher (it may even work with Fedora 21 and higher, but it is not tested!).",[638,77089,77090],{},"Root access to the servers.",[638,77092,77093,77094,714,77096,714,77098,2006],{},"Network connectivity between the servers (the following protocols need to be allowed: ",[567,77095,6706],{},[567,77097,6712],{},[567,77099,77100],{},"gre",[535,77102,77104],{"id":77103},"goals","Goals",[523,77106,77107],{},"The goal of the tutorial is to create an \"overlay\" network between two and more servers using OpenVSwitch.",[2979,77109],{},[535,77111,77113],{"id":77112},"step-1-installing-openvswitch","Step 1 - Installing OpenVSwitch",[6072,77115,77116,77120],{},[523,77117,77118],{},[584,77119,6189],{},[523,77121,77122],{},"Do this step on all servers.",[523,77124,77125,77126,77128],{},"To install OpenVSwitch on Fedora 24 we use the package manager ",[567,77127,35405],{},".\nThe command to install the OpenVSwitch package is:",[738,77130,77132],{"className":1621,"code":77131,"language":1623,"meta":743,"style":743},"dnf install openvswitch\n",[567,77133,77134],{"__ignoreMap":743},[747,77135,77136,77138,77140],{"class":749,"line":750},[747,77137,35405],{"class":1630},[747,77139,35408],{"class":802},[747,77141,77142],{"class":802}," openvswitch\n",[523,77144,77145,77146,77148,77149,7258],{},"After the command has been successfully run, you now have OpenVSwitch installed.\nFirst at all we have to start the OpenVSwitch service. To do that we use ",[567,77147,3202],{}," (more details on how to use systemctl can be seen ",[527,77150,3396],{"href":77151,"rel":77152},"https:\u002F\u002Fdocs.openvswitch.org\u002Fen\u002Flatest\u002Fintro\u002Finstall\u002F",[531],[738,77154,77156],{"className":1621,"code":77155,"language":1623,"meta":743,"style":743},"systemctl start openvswitch.service\n",[567,77157,77158],{"__ignoreMap":743},[747,77159,77160,77162,77164],{"class":749,"line":750},[747,77161,3202],{"class":1630},[747,77163,3215],{"class":802},[747,77165,77166],{"class":802}," openvswitch.service\n",[523,77168,77169],{},"This starts the OpenVSwitch service.",[6072,77171,77172,77176],{},[523,77173,77174],{},[584,77175,15250],{},[523,77177,77178],{},"Don't enable the service yet because if you accidentally \"kill\" your network connection through OpenVSwitch, you can just reboot the server and the configuration will not be loaded.",[535,77180,77182],{"id":77181},"step-2-creating-the-bridge-interface","Step 2 - Creating the bridge interface",[523,77184,77185],{},"Now that you have OpenVSwitch installed and the service started, you can create the bridge interface.\nThe command for creating an OpenVSwitch bridge device is:",[738,77187,77189],{"className":1621,"code":77188,"language":1623,"meta":743,"style":743},"ovs-vsctl add-br BRIDGE_NAME\n",[567,77190,77191],{"__ignoreMap":743},[747,77192,77193,77196,77199],{"class":749,"line":750},[747,77194,77195],{"class":1630},"ovs-vsctl",[747,77197,77198],{"class":802}," add-br",[747,77200,77201],{"class":802}," BRIDGE_NAME\n",[523,77203,77204,77205,714,77207,710,77210,77212,77213,77216],{},"When you want to create a bridge named ",[567,77206,76711],{},[567,77208,77209],{},"BRIDGE_NAME",[567,77211,76711],{},". You have now created your bridge interface.\nTo see your bridge interface use the ",[567,77214,77215],{},"ip"," command (the below output should be similar to yours):",[738,77218,77220],{"className":1621,"code":77219,"language":1623,"meta":743,"style":743},"$ ip link\n[...]\n4: br0: \u003CBROADCAST,MULTICAST,,LOWER_UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default qlen 1\n    link\u002Fether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff\n[...]\n",[567,77221,77222,77230,77238,77279,77290],{"__ignoreMap":743},[747,77223,77224,77226,77228],{"class":749,"line":750},[747,77225,1919],{"class":1630},[747,77227,7535],{"class":802},[747,77229,44891],{"class":802},[747,77231,77232,77234,77236],{"class":749,"line":761},[747,77233,4253],{"class":757},[747,77235,5685],{"class":1640},[747,77237,4268],{"class":757},[747,77239,77240,77242,77245,77247,77250,77252,77254,77256,77258,77260,77262,77264,77266,77268,77271,77273,77275,77277],{"class":749,"line":769},[747,77241,44906],{"class":1630},[747,77243,77244],{"class":802}," br0:",[747,77246,7552],{"class":757},[747,77248,77249],{"class":802},"BROADCAST,MULTICAST,,LOWER_U",[747,77251,7558],{"class":1640},[747,77253,2035],{"class":757},[747,77255,7563],{"class":802},[747,77257,7680],{"class":1895},[747,77259,7569],{"class":802},[747,77261,7572],{"class":802},[747,77263,7575],{"class":802},[747,77265,44838],{"class":802},[747,77267,17855],{"class":802},[747,77269,77270],{"class":802}," DEFAULT",[747,77272,7581],{"class":802},[747,77274,1931],{"class":802},[747,77276,7586],{"class":802},[747,77278,18691],{"class":1895},[747,77280,77281,77283,77286,77288],{"class":749,"line":776},[747,77282,7741],{"class":1630},[747,77284,77285],{"class":802}," xx:xx:xx:xx:xx:xx",[747,77287,7600],{"class":802},[747,77289,7749],{"class":802},[747,77291,77292,77294,77296],{"class":749,"line":784},[747,77293,4253],{"class":757},[747,77295,5685],{"class":1640},[747,77297,4268],{"class":757},[535,77299,77301],{"id":77300},"step-3-preparing-for-the-gre-tunnels","Step 3 - Preparing for the GRE tunnels",[523,77303,77304],{},"You should now create a list of your servers and beginning from 0 a number for example like this:",[738,77306,77310],{"className":77307,"code":77308,"language":77309,"meta":743,"style":743},"language-csv shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","server-1 0\nserver-2 1\nserver-3 2\n[...]\nserver-8 7\nserver-9 8\n","csv",[567,77311,77312,77317,77322,77327,77331,77336],{"__ignoreMap":743},[747,77313,77314],{"class":749,"line":750},[747,77315,77316],{"class":1640},"server-1 0\n",[747,77318,77319],{"class":749,"line":761},[747,77320,77321],{"class":1640},"server-2 1\n",[747,77323,77324],{"class":749,"line":769},[747,77325,77326],{"class":1640},"server-3 2\n",[747,77328,77329],{"class":749,"line":776},[747,77330,5986],{"class":1640},[747,77332,77333],{"class":749,"line":784},[747,77334,77335],{"class":1640},"server-8 7\n",[747,77337,77338],{"class":749,"line":790},[747,77339,77340],{"class":1640},"server-9 8\n",[523,77342,77343],{},"The number behind the server name will be the tunnel interface number and needs to be the same on all servers when creating the meshed tunnel network.",[6072,77345,77346],{},[523,77347,77348,77350],{},[584,77349,6189],{}," Save this list somewhere safe, it is very important when you later want to expand your network.",[523,77352,77353],{},"A list for three servers with the interface name and IP address written behind the lines:",[738,77355,77357],{"className":77307,"code":77356,"language":77309,"meta":743,"style":743},"server-1 0 gre0 IP: 1.1.1.1\nserver-2 1 gre1 IP: 2.2.2.2\nserver-3 2 gre2 IP: 3.3.3.3\n",[567,77358,77359,77364,77369],{"__ignoreMap":743},[747,77360,77361],{"class":749,"line":750},[747,77362,77363],{"class":1640},"server-1 0 gre0 IP: 1.1.1.1\n",[747,77365,77366],{"class":749,"line":761},[747,77367,77368],{"class":1640},"server-2 1 gre1 IP: 2.2.2.2\n",[747,77370,77371],{"class":749,"line":769},[747,77372,77373],{"class":1640},"server-3 2 gre2 IP: 3.3.3.3\n",[523,77375,77376,77377,77379],{},"Your server firewall should not block the GRE tunnel protocol traffic.\nFor iptables the protocol name is ",[567,77378,77100],{},".\nAn example rule to allow all GRE tunnel protocol traffic:",[738,77381,77383],{"className":1621,"code":77382,"language":1623,"meta":743,"style":743},"iptables -A INPUT -p gre -j ACCEPT\n",[567,77384,77385],{"__ignoreMap":743},[747,77386,77387,77389,77391,77393,77395,77398,77400],{"class":749,"line":750},[747,77388,8254],{"class":1630},[747,77390,1974],{"class":802},[747,77392,46422],{"class":802},[747,77394,7094],{"class":802},[747,77396,77397],{"class":802}," gre",[747,77399,75971],{"class":802},[747,77401,77402],{"class":802}," ACCEPT\n",[535,77404,77406],{"id":77405},"step-4-opening-the-gre-tunnels","Step 4 - Opening the GRE tunnels",[523,77408,77409],{},"Before creating the first GRE tunnels you should know that it will not make any sense if you have more than 3-4 servers to link all of them together. You should create a redundant mesh between your servers and not link all to all.",[6072,77411,77412,77416],{},[523,77413,77414],{},[584,77415,6189],{},[523,77417,66596,77418,77420],{},[567,77419,76711],{}," in the commands is your bridge device. Please change it according to your bridge name.",[523,77422,77423,77424,77427],{},"Starting on your the first server (IP: ",[567,77425,77426],{},"1.1.1.1","), we create the tunnel to the second and third server:",[738,77429,77431],{"className":1621,"code":77430,"language":1623,"meta":743,"style":743},"ovs-vsctl add-port br0 gre1 -- set interface gre1 type=gre options:remote_ip=2.2.2.2\novs-vsctl add-port br0 gre1 -- set interface gre2 type=gre options:remote_ip=3.3.3.3\n",[567,77432,77433,77463],{"__ignoreMap":743},[747,77434,77435,77437,77440,77443,77446,77448,77450,77452,77454,77457,77460],{"class":749,"line":750},[747,77436,77195],{"class":1630},[747,77438,77439],{"class":802}," add-port",[747,77441,77442],{"class":802}," br0",[747,77444,77445],{"class":802}," gre1",[747,77447,2592],{"class":802},[747,77449,33610],{"class":802},[747,77451,33318],{"class":802},[747,77453,77445],{"class":802},[747,77455,77456],{"class":802}," type=gre",[747,77458,77459],{"class":802}," options:remote_ip=",[747,77461,77462],{"class":1895},"2.2.2.2\n",[747,77464,77465,77467,77469,77471,77473,77475,77477,77479,77482,77484,77486],{"class":749,"line":761},[747,77466,77195],{"class":1630},[747,77468,77439],{"class":802},[747,77470,77442],{"class":802},[747,77472,77445],{"class":802},[747,77474,2592],{"class":802},[747,77476,33610],{"class":802},[747,77478,33318],{"class":802},[747,77480,77481],{"class":802}," gre2",[747,77483,77456],{"class":802},[747,77485,77459],{"class":802},[747,77487,77488],{"class":1895},"3.3.3.3\n",[523,77490,77491,77492,77495],{},"On the second server (",[567,77493,77494],{},"2.2.2.2",") we now create the tunnel to the first and third server with the commands:",[738,77497,77499],{"className":1621,"code":77498,"language":1623,"meta":743,"style":743},"ovs-vsctl add-port br0 gre0 -- set interface gre0 type=gre options:remote_ip=1.1.1.1\novs-vsctl add-port br0 gre0 -- set interface gre2 type=gre options:remote_ip=3.3.3.3\n",[567,77500,77501,77527],{"__ignoreMap":743},[747,77502,77503,77505,77507,77509,77512,77514,77516,77518,77520,77522,77524],{"class":749,"line":750},[747,77504,77195],{"class":1630},[747,77506,77439],{"class":802},[747,77508,77442],{"class":802},[747,77510,77511],{"class":802}," gre0",[747,77513,2592],{"class":802},[747,77515,33610],{"class":802},[747,77517,33318],{"class":802},[747,77519,77511],{"class":802},[747,77521,77456],{"class":802},[747,77523,77459],{"class":802},[747,77525,77526],{"class":1895},"1.1.1.1\n",[747,77528,77529,77531,77533,77535,77537,77539,77541,77543,77545,77547,77549],{"class":749,"line":761},[747,77530,77195],{"class":1630},[747,77532,77439],{"class":802},[747,77534,77442],{"class":802},[747,77536,77511],{"class":802},[747,77538,2592],{"class":802},[747,77540,33610],{"class":802},[747,77542,33318],{"class":802},[747,77544,77481],{"class":802},[747,77546,77456],{"class":802},[747,77548,77459],{"class":802},[747,77550,77488],{"class":1895},[523,77552,77553,77554,77557],{},"On the third server (",[567,77555,77556],{},"3.3.3.3",") we create the tunnel back to the first and second server so the three server mesh is complete:",[738,77559,77561],{"className":1621,"code":77560,"language":1623,"meta":743,"style":743},"ovs-vsctl add-port br0 gre0 -- set interface gre0 type=gre options:remote_ip=1.1.1.1\novs-vsctl add-port br0 gre0 -- set interface gre1 type=gre options:remote_ip=2.2.2.2\n",[567,77562,77563,77587],{"__ignoreMap":743},[747,77564,77565,77567,77569,77571,77573,77575,77577,77579,77581,77583,77585],{"class":749,"line":750},[747,77566,77195],{"class":1630},[747,77568,77439],{"class":802},[747,77570,77442],{"class":802},[747,77572,77511],{"class":802},[747,77574,2592],{"class":802},[747,77576,33610],{"class":802},[747,77578,33318],{"class":802},[747,77580,77511],{"class":802},[747,77582,77456],{"class":802},[747,77584,77459],{"class":802},[747,77586,77526],{"class":1895},[747,77588,77589,77591,77593,77595,77597,77599,77601,77603,77605,77607,77609],{"class":749,"line":761},[747,77590,77195],{"class":1630},[747,77592,77439],{"class":802},[747,77594,77442],{"class":802},[747,77596,77511],{"class":802},[747,77598,2592],{"class":802},[747,77600,33610],{"class":802},[747,77602,33318],{"class":802},[747,77604,77445],{"class":802},[747,77606,77456],{"class":802},[747,77608,77459],{"class":802},[747,77610,77462],{"class":1895},[535,77612,77614],{"id":77613},"step-5-adding-ip-addresses-to-the-bridges","Step 5 - Adding IP addresses to the bridges",[523,77616,77617,77618,77621],{},"You can now add an extra field to the exisiting server list which contains the network range.\nIn the tutorial case the network will be ",[567,77619,77620],{},"10.244.0.0\u002F16"," network, so the list looks like this:",[738,77623,77625],{"className":77307,"code":77624,"language":77309,"meta":743,"style":743},"server-1 0 gre0 IP: 1.1.1.1 Network: 10.244.1.0\nserver-2 1 gre1 IP: 2.2.2.2 Network: 10.244.2.0\nserver-3 2 gre2 IP: 3.3.3.3 Network: 10.244.3.0\n",[567,77626,77627,77632,77637],{"__ignoreMap":743},[747,77628,77629],{"class":749,"line":750},[747,77630,77631],{"class":1640},"server-1 0 gre0 IP: 1.1.1.1 Network: 10.244.1.0\n",[747,77633,77634],{"class":749,"line":761},[747,77635,77636],{"class":1640},"server-2 1 gre1 IP: 2.2.2.2 Network: 10.244.2.0\n",[747,77638,77639],{"class":749,"line":769},[747,77640,77641],{"class":1640},"server-3 2 gre2 IP: 3.3.3.3 Network: 10.244.3.0\n",[6072,77643,77644,77648],{},[523,77645,77646],{},[584,77647,6189],{},[523,77649,77650],{},"It is important to know what servers uses which IP address to avoid address conflicts.\nIf you changed the CIDR of the network range from the tutorial, you also have to change the broadcast address in the below commands.",[523,77652,77653,77654,77656],{},"Now that you have decided what server has what network slice, we can set the interface up and add the IP addresses to the bridge on each server.\nOn the first server (",[567,77655,77426],{},") the command would look like this:",[738,77658,77660],{"className":1621,"code":77659,"language":1623,"meta":743,"style":743},"ip link set br0 up\nip addr add 10.244.1.0\u002F16 broadcast 10.244.255.255 dev br0\n",[567,77661,77662,77674],{"__ignoreMap":743},[747,77663,77664,77666,77668,77670,77672],{"class":749,"line":750},[747,77665,77215],{"class":1630},[747,77667,7791],{"class":802},[747,77669,33610],{"class":802},[747,77671,77442],{"class":802},[747,77673,11281],{"class":802},[747,77675,77676,77678,77680,77682,77685,77688,77691,77694],{"class":749,"line":761},[747,77677,77215],{"class":1630},[747,77679,44677],{"class":802},[747,77681,26249],{"class":802},[747,77683,77684],{"class":802}," 10.244.1.0\u002F16",[747,77686,77687],{"class":802}," broadcast",[747,77689,77690],{"class":1895}," 10.244.255.255",[747,77692,77693],{"class":802}," dev",[747,77695,77696],{"class":802}," br0\n",[523,77698,77491,77699,77701],{},[567,77700,77494],{},") the command is slightly different due to the other address:",[738,77703,77705],{"className":1621,"code":77704,"language":1623,"meta":743,"style":743},"ip addr add 10.244.2.0\u002F16 broadcast 10.244.255.255 dev br0\n",[567,77706,77707],{"__ignoreMap":743},[747,77708,77709,77711,77713,77715,77718,77720,77722,77724],{"class":749,"line":750},[747,77710,77215],{"class":1630},[747,77712,44677],{"class":802},[747,77714,26249],{"class":802},[747,77716,77717],{"class":802}," 10.244.2.0\u002F16",[747,77719,77687],{"class":802},[747,77721,77690],{"class":1895},[747,77723,77693],{"class":802},[747,77725,77696],{"class":802},[523,77727,77728],{},"And so on with different IP addresses per server.",[535,77730,77732],{"id":77731},"step-6-checking-the-virtual-network-connectivity","Step 6 - Checking the virtual network connectivity",[523,77734,77735,77736,77739,77740,49401],{},"Now that every server has it's own IP address in the virtual network, we can check the connectivity.\nWe are going to use the ",[567,77737,77738],{},"ping"," command for testing the connectivity between the servers.\nFrom the first server (",[567,77741,77426],{},[738,77743,77745],{"className":1621,"code":77744,"language":1623,"meta":743,"style":743},"ping 10.244.2.0\n",[567,77746,77747],{"__ignoreMap":743},[747,77748,77749,77751],{"class":749,"line":750},[747,77750,77738],{"class":1630},[747,77752,77753],{"class":1895}," 10.244.2.0\n",[523,77755,77756,77757,22542,77760,8287,77763,77766],{},"If you should not receive a ping response in the next 10 seconds, it may be caused by a setting called ",[567,77758,77759],{},"proxy_arp",[567,77761,77762],{},"\u002Fsys",[567,77764,77765],{},"net.ipv4"," \"category\".",[6072,77768,77769,77773],{},[523,77770,77771],{},[584,77772,6189],{},[523,77774,66596,77775,77777],{},[567,77776,76711],{}," in the command(s) is your bridge device. Please change it according to your bridge name.",[738,77779,77781],{"className":1621,"code":77780,"language":1623,"meta":743,"style":743},"sysctl -w net.ipv4.conf.br0.proxy_arp=1\n",[567,77782,77783],{"__ignoreMap":743},[747,77784,77785,77787,77789,77792],{"class":749,"line":750},[747,77786,276],{"class":1630},[747,77788,61870],{"class":802},[747,77790,77791],{"class":802}," net.ipv4.conf.br0.proxy_arp=",[747,77793,77794],{"class":1895},"1\n",[523,77796,77797],{},"To persist this change you can run:",[738,77799,77801],{"className":1621,"code":77800,"language":1623,"meta":743,"style":743},"echo \"net.ipv4.conf.br0.proxy_arp=1\" >> \u002Fetc\u002Fsysctl.conf\n",[567,77802,77803],{"__ignoreMap":743},[747,77804,77805,77807,77809,77812,77814,77817],{"class":749,"line":750},[747,77806,65664],{"class":4574},[747,77808,969],{"class":757},[747,77810,77811],{"class":802},"net.ipv4.conf.br0.proxy_arp=1",[747,77813,3892],{"class":757},[747,77815,77816],{"class":757}," >>",[747,77818,77819],{"class":802}," \u002Fetc\u002Fsysctl.conf\n",[6072,77821,77822,77826],{},[523,77823,77824],{},[584,77825,6189],{},[523,77827,8764,77828,77831],{},[567,77829,77830],{},"\u002Fetc\u002Fsysctl.conf"," file is loaded on every boot.",[523,77833,77834],{},"Now after that change, retry to ping and it now should work.",[535,77836,14526],{"id":14525},[523,77838,77839],{},"As long as you build a good mesh between the servers the virtual network between the servers will be redundant.\nBut don't over do the mesh building between the servers. As mentioned earlier too many tunnels is too much.",[523,77841,13967],{},[2890,77843,77844],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}",{"title":743,"searchDepth":761,"depth":761,"links":77846},[77847,77848,77849,77850,77851,77852,77853,77854,77855,77856],{"id":77076,"depth":761,"text":77077},{"id":22267,"depth":761,"text":22268},{"id":77103,"depth":761,"text":77104},{"id":77112,"depth":761,"text":77113},{"id":77181,"depth":761,"text":77182},{"id":77300,"depth":761,"text":77301},{"id":77405,"depth":761,"text":77406},{"id":77613,"depth":761,"text":77614},{"id":77731,"depth":761,"text":77732},{"id":14525,"depth":761,"text":14526},"2016-08-09T09:25:51+02:00","Creating a mutli-host overlay network between two and more servers.",{"src":77860},"\u002Fblog\u002F2016\u002Fopenvswitch-multi-host-overlay-network\u002Fpost_title_image.png",{"tags":77862},[193,77047],"\u002Fblog\u002F2016\u002Fopenvswitch-multi-host-overlay-network",{"title":76707,"description":77858},"3.blog\u002F2016\u002Fopenvswitch-multi-host-overlay-network","U5UHXrkz5veaFCjeW2Oc18j6tqLREMJETX5Vhq3rh3s",{"id":77868,"title":77869,"authors":77870,"badge":518,"body":77873,"date":79027,"description":77877,"extension":2911,"image":79028,"meta":79029,"navigation":1254,"path":79031,"seo":79032,"stem":79033,"__hash__":79034},"posts\u002F3.blog\u002F2016\u002Fceph-build-your-own-cluster-on-centos.md","Ceph: Build your own cluster on CentOS",[77871],{"name":514,"to":515,"avatar":77872},{"src":517},{"type":520,"value":77874,"toc":79014},[77875,77878,77890,77893,77896,77898,77901,77908,77920,77932,77942,77946,77949,78022,78029,78095,78117,78120,78151,78155,78168,78203,78209,78227,78231,78234,78251,78256,78262,78540,78546,78567,78572,78575,78597,78607,78616,78644,78658,78667,78671,78674,78677,78726,78732,78750,78753,78772,78778,78794,78796,78813,78817,78820,78835,78844,78847,78862,78870,78873,78875,78879,78885,78890,78980,78984,78991,78993,79009,79011],[523,77876,77877],{},"Ceph is an object, a block and filesystem storage system.",[523,77879,77880,77881,77885,77886,1909],{},"As you can see from the Ceph.com visitors map ",[527,77882,3396],{"href":77883,"rel":77884},"http:\u002F\u002Fwww.revolvermaps.com\u002F?target=enlarge&i=1lzi710tj7s&color=80D2DC&m=0",[531],", people all around the world search for it. You can also see some metrics about the Ceph project at their metrics site ",[527,77887,3396],{"href":77888,"rel":77889},"http:\u002F\u002Fmetrics.ceph.com\u002F",[531],[523,77891,77892],{},"I'm going to go over the installation of a two node Ceph storage cluster.\nYou can then build on those storage nodes and choose multiple storage types you want to use.",[523,77894,77895],{},"I personally recommend to use at least two nodes even for a test cluster!",[535,77897,22268],{"id":22267},[523,77899,77900],{},"I assume that you have basic linux knowledge and at least two servers with CentOS7 up and running that can reach each other.",[523,77902,77903,77904,77907],{},"In my case my two example servers are having 2vCores and 4GB RAM. The OS used is CentOS7 (to be exact ",[567,77905,77906],{},"CentOS Linux release 7.2.1511 (Core)",").\nMy examples servers for this tutorial have the following addresses:",[668,77909,77910,77915],{},[638,77911,77912],{},[567,77913,77914],{},"203.0.113.1 ceph-tutorial-node1",[638,77916,77917],{},[567,77918,77919],{},"203.0.113.2 ceph-tutorial-node2",[523,77921,77922],{},[3049,77923,77924,77926,77927],{},[584,77925,76064],{}," the IPs used here are according to ",[527,77928,77931],{"href":77929,"rel":77930},"https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc5737",[531],"RFC5737",[523,77933,77934,77937,77938,77941],{},[584,77935,77936],{},"You have to decide from what server you want to deploy your cluster.","\nI use the first server ",[567,77939,77940],{},"ceph-tutorial-node1"," as the \"deployment\" server.",[535,77943,77945],{"id":77944},"preparing-your-servers-for-ceph","Preparing your servers for Ceph",[523,77947,77948],{},"Let's begin first by adding the Epel and Ceph repository to all our used servers.\nOn all the servers we have, we need to add the Epel package repositories to the repository list.\nThe following commands add the Epel package repositories and the Epel repository verification key:",[738,77950,77952],{"className":1621,"code":77951,"language":1623,"meta":743,"style":743},"sudo yum install -y yum-utils && sudo yum-config-manager --add-repo https:\u002F\u002Fdl.fedoraproject.org\u002Fpub\u002Fepel\u002F7\u002Fx86_64\u002F\nsudo yum install --nogpgcheck -y epel-release\nsudo rpm --import \u002Fetc\u002Fpki\u002Frpm-gpg\u002FRPM-GPG-KEY-EPEL-7\nsudo rm \u002Fetc\u002Fyum.repos.d\u002Fdl.fedoraproject.org*\n",[567,77953,77954,77981,77997,78010],{"__ignoreMap":743},[747,77955,77956,77958,77961,77963,77965,77968,77970,77972,77975,77978],{"class":749,"line":750},[747,77957,3376],{"class":1630},[747,77959,77960],{"class":802}," yum",[747,77962,35408],{"class":802},[747,77964,35411],{"class":802},[747,77966,77967],{"class":802}," yum-utils",[747,77969,37162],{"class":757},[747,77971,40185],{"class":1630},[747,77973,77974],{"class":802}," yum-config-manager",[747,77976,77977],{"class":802}," --add-repo",[747,77979,77980],{"class":802}," https:\u002F\u002Fdl.fedoraproject.org\u002Fpub\u002Fepel\u002F7\u002Fx86_64\u002F\n",[747,77982,77983,77985,77987,77989,77992,77994],{"class":749,"line":761},[747,77984,3376],{"class":1630},[747,77986,77960],{"class":802},[747,77988,35408],{"class":802},[747,77990,77991],{"class":802}," --nogpgcheck",[747,77993,35411],{"class":802},[747,77995,77996],{"class":802}," epel-release\n",[747,77998,77999,78001,78004,78007],{"class":749,"line":769},[747,78000,3376],{"class":1630},[747,78002,78003],{"class":802}," rpm",[747,78005,78006],{"class":802}," --import",[747,78008,78009],{"class":802}," \u002Fetc\u002Fpki\u002Frpm-gpg\u002FRPM-GPG-KEY-EPEL-7\n",[747,78011,78012,78014,78016,78019],{"class":749,"line":776},[747,78013,3376],{"class":1630},[747,78015,5902],{"class":802},[747,78017,78018],{"class":802}," \u002Fetc\u002Fyum.repos.d\u002Fdl.fedoraproject.org",[747,78020,78021],{"class":1640},"*\n",[523,78023,78024,78025,78028],{},"Now that our servers have the Epel repository added, we're finally going to add the Ceph repository.\nUse your favorited editor to create a file ",[567,78026,78027],{},"\u002Fetc\u002Fyum.repos.d\u002Fceph.repo"," and copy the following content into it:",[738,78030,78032],{"className":32095,"code":78031,"language":32097,"meta":743,"style":743},"[ceph-noarch]\nname=Ceph noarch packages\nbaseurl=http:\u002F\u002Fdownload.ceph.com\u002Frpm-jewel\u002Fel7\u002Fnoarch\nenabled=1\ngpgcheck=1\ntype=rpm-md\ngpgkey=https:\u002F\u002Fdownload.ceph.com\u002Fkeys\u002Frelease.asc\n",[567,78033,78034,78039,78048,78058,78067,78076,78085],{"__ignoreMap":743},[747,78035,78036],{"class":749,"line":750},[747,78037,78038],{"class":757},"[ceph-noarch]\n",[747,78040,78041,78043,78045],{"class":749,"line":761},[747,78042,5472],{"class":753},[747,78044,6425],{"class":757},[747,78046,78047],{"class":1640},"Ceph noarch packages\n",[747,78049,78050,78053,78055],{"class":749,"line":769},[747,78051,78052],{"class":753},"baseurl",[747,78054,6425],{"class":757},[747,78056,78057],{"class":1640},"http:\u002F\u002Fdownload.ceph.com\u002Frpm-jewel\u002Fel7\u002Fnoarch\n",[747,78059,78060,78063,78065],{"class":749,"line":776},[747,78061,78062],{"class":753},"enabled",[747,78064,6425],{"class":757},[747,78066,77794],{"class":1640},[747,78068,78069,78072,78074],{"class":749,"line":784},[747,78070,78071],{"class":753},"gpgcheck",[747,78073,6425],{"class":757},[747,78075,77794],{"class":1640},[747,78077,78078,78080,78082],{"class":749,"line":790},[747,78079,23273],{"class":753},[747,78081,6425],{"class":757},[747,78083,78084],{"class":1640},"rpm-md\n",[747,78086,78087,78090,78092],{"class":749,"line":796},[747,78088,78089],{"class":753},"gpgkey",[747,78091,6425],{"class":757},[747,78093,78094],{"class":1640},"https:\u002F\u002Fdownload.ceph.com\u002Fkeys\u002Frelease.asc\n",[523,78096,78097,78099,78100,78103,78104,30273,78106,78109,78110,78112,78113,78116],{},[584,78098,76064],{}," You can replace ",[567,78101,78102],{},"jewel"," with the Ceph release version you want to install (current latest release is ",[567,78105,78102],{},[567,78107,78108],{},"el7"," with, depending on what CentOS version number you have, for example for CentOS7 it should be ",[567,78111,78108],{}," and for CentOS6 it should be ",[567,78114,78115],{},"el6"," (other CentOS versions don't have official rpm builds available and will not work!).",[523,78118,78119],{},"Now we have the Ceph repository in our repository list on all of our servers.\nAn important step is to configure NTP service on all servers to keep the time synchronized across the storage cluster, but I'm not going to cover this.\nOther important things to make sure, before continuing with the tutorial:",[668,78121,78122,78134,78144],{},[638,78123,78124,78125,78130,78131,1909],{},"You should use an user with password less login and sudo without password rights on details how to create an user for that see ",[527,78126,78129],{"href":78127,"rel":78128},"http:\u002F\u002Fdocs.ceph.com\u002Fdocs\u002Fmaster\u002Fstart\u002Fquick-start-preflight\u002F#enable-password-less-ssh",[531],"Ceph Preflight Docs",", but it is ",[584,78132,78133],{},"not required",[638,78135,78136,78137,78140,78141,3052],{},"Selinux needs to be set to ",[567,78138,78139],{},"Permissive"," during the installation process (Command to disable SElinux temporarly",[567,78142,78143],{},"sudo setenforce 0",[638,78145,78146,78147,3052],{},"By default firewalld is in place on most CentOS servers, you either have to open the specific ports or just disable the firewall completely (for more details see ",[527,78148,78129],{"href":78149,"rel":78150},"http:\u002F\u002Fdocs.ceph.com\u002Fdocs\u002Fmaster\u002Fstart\u002Fquick-start-preflight\u002F#open-required-ports",[531],[535,78152,78154],{"id":78153},"preparing-the-ceph-deployment","Preparing the Ceph deployment",[523,78156,78157,78158,78161,78162,78164,78165,78167],{},"Switch to your deployment server and install the Ceph deployment package ",[567,78159,78160],{},"ceph-deploy"," on the deployment server, in my case server ",[567,78163,77940],{},".\nThe first commands will update your package database and system. The second command will install the ",[567,78166,78160],{}," package on your CentOS server:",[738,78169,78171],{"className":1621,"code":78170,"language":1623,"meta":743,"style":743},"sudo yum clean all && sudo yum update\nsudo yum install ceph-deploy\n",[567,78172,78173,78192],{"__ignoreMap":743},[747,78174,78175,78177,78179,78182,78184,78186,78188,78190],{"class":749,"line":750},[747,78176,3376],{"class":1630},[747,78178,77960],{"class":802},[747,78180,78181],{"class":802}," clean",[747,78183,42922],{"class":802},[747,78185,37162],{"class":757},[747,78187,40185],{"class":1630},[747,78189,77960],{"class":802},[747,78191,67038],{"class":802},[747,78193,78194,78196,78198,78200],{"class":749,"line":761},[747,78195,3376],{"class":1630},[747,78197,77960],{"class":802},[747,78199,35408],{"class":802},[747,78201,78202],{"class":802}," ceph-deploy\n",[523,78204,78205,78206,78208],{},"Still on the deployment server (in my case ",[567,78207,77940],{},") create a folder where files for the deployment will be stored. For example:",[738,78210,78212],{"className":1621,"code":78211,"language":1623,"meta":743,"style":743},"mkdir ~\u002Fmy-ceph-cluster\ncd ~\u002Fmy-ceph-cluster\n",[567,78213,78214,78221],{"__ignoreMap":743},[747,78215,78216,78218],{"class":749,"line":750},[747,78217,36923],{"class":1630},[747,78219,78220],{"class":802}," ~\u002Fmy-ceph-cluster\n",[747,78222,78223,78225],{"class":749,"line":761},[747,78224,76163],{"class":4574},[747,78226,78220],{"class":802},[535,78228,78230],{"id":78229},"deploying-ceph-storage-nodes","Deploying Ceph storage nodes",[523,78232,78233],{},"To generate the basic Ceph cluster configuration I run for my two servers:",[738,78235,78237],{"className":1621,"code":78236,"language":1623,"meta":743,"style":743},"ceph-deploy new ceph-tutorial-node1 ceph-tutorial-node2\n",[567,78238,78239],{"__ignoreMap":743},[747,78240,78241,78243,78245,78248],{"class":749,"line":750},[747,78242,78160],{"class":1630},[747,78244,3933],{"class":802},[747,78246,78247],{"class":802}," ceph-tutorial-node1",[747,78249,78250],{"class":802}," ceph-tutorial-node2\n",[523,78252,78253,78255],{},[584,78254,76064],{}," Where ceph-tutorial-node1 is you deployment server.",[523,78257,78258,78259,28768],{},"Example output of the ",[567,78260,78261],{},"ceph-deploy new ceph-tutorial-node1",[738,78263,78265],{"className":32095,"code":78264,"language":32097,"meta":743,"style":743},"# ceph-deploy new ceph-tutorial-node1\n[ceph_deploy.conf][DEBUG ] found configuration file at: \u002Froot\u002F.cephdeploy.conf\n[ceph_deploy.cli][INFO  ] Invoked (1.5.34): \u002Fusr\u002Fbin\u002Fceph-deploy new ceph-tutorial-node1\n[ceph_deploy.cli][INFO  ] ceph-deploy options:\n[ceph_deploy.cli][INFO  ]  username                      : None\n[ceph_deploy.cli][INFO  ]  func                          : \u003Cfunction new at 0x1cfb6e0>\n[ceph_deploy.cli][INFO  ]  verbose                       : False\n[ceph_deploy.cli][INFO  ]  overwrite_conf                : False\n[ceph_deploy.cli][INFO  ]  quiet                         : False\n[ceph_deploy.cli][INFO  ]  cd_conf                       : \u003Cceph_deploy.conf.cephdeploy.Conf instance at 0x1d56710>\n[ceph_deploy.cli][INFO  ]  cluster                       : ceph\n[ceph_deploy.cli][INFO  ]  ssh_copykey                   : True\n[ceph_deploy.cli][INFO  ]  mon                           : ['ceph-tutorial-node1']\n[ceph_deploy.cli][INFO  ]  public_network                : None\n[ceph_deploy.cli][INFO  ]  ceph_conf                     : None\n[ceph_deploy.cli][INFO  ]  cluster_network               : None\n[ceph_deploy.cli][INFO  ]  default_release               : False\n[ceph_deploy.cli][INFO  ]  fsid                          : None\n[ceph_deploy.new][DEBUG ] Creating new cluster named ceph\n[ceph_deploy.new][INFO  ] making sure passwordless SSH succeeds\n[ceph-tutorial-node1][DEBUG ] connected to host: ceph-tutorial-node1\n[ceph-tutorial-node1][DEBUG ] detect platform information from remote host\n[ceph-tutorial-node1][DEBUG ] detect machine type\n[ceph-tutorial-node1][DEBUG ] find the location of an executable\n[ceph-tutorial-node1][INFO  ] Running command: \u002Fusr\u002Fsbin\u002Fip link show\n[ceph-tutorial-node1][INFO  ] Running command: \u002Fusr\u002Fsbin\u002Fip addr show\n[ceph-tutorial-node1][DEBUG ] IP addresses found: ['203.0.113.1']\n[ceph_deploy.new][DEBUG ] Resolving host ceph-tutorial-node1\n[ceph_deploy.new][DEBUG ] Monitor ceph-tutorial-node1 at 203.0.113.1\n[ceph_deploy.new][DEBUG ] Monitor initial members are ['ceph-tutorial-node1']\n[ceph_deploy.new][DEBUG ] Monitor addrs are ['203.0.113.1']\n[ceph_deploy.new][DEBUG ] Creating a random mon key...\n[ceph_deploy.new][DEBUG ] Writing monitor keyring to ceph.mon.keyring...\n[ceph_deploy.new][DEBUG ] Writing initial config to ceph.conf...\n",[567,78266,78267,78272,78280,78288,78295,78302,78309,78316,78323,78330,78337,78344,78351,78366,78373,78380,78387,78394,78401,78409,78416,78424,78431,78438,78445,78452,78459,78475,78482,78489,78504,78519,78526,78533],{"__ignoreMap":743},[747,78268,78269],{"class":749,"line":750},[747,78270,78271],{"class":772},"# ceph-deploy new ceph-tutorial-node1\n",[747,78273,78274,78277],{"class":749,"line":761},[747,78275,78276],{"class":757},"[ceph_deploy.conf]",[747,78278,78279],{"class":1640},"[DEBUG ] found configuration file at: \u002Froot\u002F.cephdeploy.conf\n",[747,78281,78282,78285],{"class":749,"line":769},[747,78283,78284],{"class":757},"[ceph_deploy.cli]",[747,78286,78287],{"class":1640},"[INFO  ] Invoked (1.5.34): \u002Fusr\u002Fbin\u002Fceph-deploy new ceph-tutorial-node1\n",[747,78289,78290,78292],{"class":749,"line":776},[747,78291,78284],{"class":757},[747,78293,78294],{"class":1640},"[INFO  ] ceph-deploy options:\n",[747,78296,78297,78299],{"class":749,"line":784},[747,78298,78284],{"class":757},[747,78300,78301],{"class":1640},"[INFO  ]  username                      : None\n",[747,78303,78304,78306],{"class":749,"line":790},[747,78305,78284],{"class":757},[747,78307,78308],{"class":1640},"[INFO  ]  func                          : \u003Cfunction new at 0x1cfb6e0>\n",[747,78310,78311,78313],{"class":749,"line":796},[747,78312,78284],{"class":757},[747,78314,78315],{"class":1640},"[INFO  ]  verbose                       : False\n",[747,78317,78318,78320],{"class":749,"line":806},[747,78319,78284],{"class":757},[747,78321,78322],{"class":1640},"[INFO  ]  overwrite_conf                : False\n",[747,78324,78325,78327],{"class":749,"line":814},[747,78326,78284],{"class":757},[747,78328,78329],{"class":1640},"[INFO  ]  quiet                         : False\n",[747,78331,78332,78334],{"class":749,"line":822},[747,78333,78284],{"class":757},[747,78335,78336],{"class":1640},"[INFO  ]  cd_conf                       : \u003Cceph_deploy.conf.cephdeploy.Conf instance at 0x1d56710>\n",[747,78338,78339,78341],{"class":749,"line":830},[747,78340,78284],{"class":757},[747,78342,78343],{"class":1640},"[INFO  ]  cluster                       : ceph\n",[747,78345,78346,78348],{"class":749,"line":836},[747,78347,78284],{"class":757},[747,78349,78350],{"class":1640},"[INFO  ]  ssh_copykey                   : True\n",[747,78352,78353,78355,78358,78360,78362,78364],{"class":749,"line":842},[747,78354,78284],{"class":757},[747,78356,78357],{"class":1640},"[INFO  ]  mon                           : [",[747,78359,3543],{"class":757},[747,78361,77940],{"class":802},[747,78363,3543],{"class":757},[747,78365,4268],{"class":1640},[747,78367,78368,78370],{"class":749,"line":850},[747,78369,78284],{"class":757},[747,78371,78372],{"class":1640},"[INFO  ]  public_network                : None\n",[747,78374,78375,78377],{"class":749,"line":863},[747,78376,78284],{"class":757},[747,78378,78379],{"class":1640},"[INFO  ]  ceph_conf                     : None\n",[747,78381,78382,78384],{"class":749,"line":869},[747,78383,78284],{"class":757},[747,78385,78386],{"class":1640},"[INFO  ]  cluster_network               : None\n",[747,78388,78389,78391],{"class":749,"line":877},[747,78390,78284],{"class":757},[747,78392,78393],{"class":1640},"[INFO  ]  default_release               : False\n",[747,78395,78396,78398],{"class":749,"line":1015},[747,78397,78284],{"class":757},[747,78399,78400],{"class":1640},"[INFO  ]  fsid                          : None\n",[747,78402,78403,78406],{"class":749,"line":1021},[747,78404,78405],{"class":757},"[ceph_deploy.new]",[747,78407,78408],{"class":1640},"[DEBUG ] Creating new cluster named ceph\n",[747,78410,78411,78413],{"class":749,"line":1027},[747,78412,78405],{"class":757},[747,78414,78415],{"class":1640},"[INFO  ] making sure passwordless SSH succeeds\n",[747,78417,78418,78421],{"class":749,"line":1033},[747,78419,78420],{"class":757},"[ceph-tutorial-node1]",[747,78422,78423],{"class":1640},"[DEBUG ] connected to host: ceph-tutorial-node1\n",[747,78425,78426,78428],{"class":749,"line":1039},[747,78427,78420],{"class":757},[747,78429,78430],{"class":1640},"[DEBUG ] detect platform information from remote host\n",[747,78432,78433,78435],{"class":749,"line":1054},[747,78434,78420],{"class":757},[747,78436,78437],{"class":1640},"[DEBUG ] detect machine type\n",[747,78439,78440,78442],{"class":749,"line":1060},[747,78441,78420],{"class":757},[747,78443,78444],{"class":1640},"[DEBUG ] find the location of an executable\n",[747,78446,78447,78449],{"class":749,"line":1066},[747,78448,78420],{"class":757},[747,78450,78451],{"class":1640},"[INFO  ] Running command: \u002Fusr\u002Fsbin\u002Fip link show\n",[747,78453,78454,78456],{"class":749,"line":1081},[747,78455,78420],{"class":757},[747,78457,78458],{"class":1640},"[INFO  ] Running command: \u002Fusr\u002Fsbin\u002Fip addr show\n",[747,78460,78461,78463,78466,78468,78471,78473],{"class":749,"line":1087},[747,78462,78420],{"class":757},[747,78464,78465],{"class":1640},"[DEBUG ] IP addresses found: [",[747,78467,3543],{"class":757},[747,78469,78470],{"class":802},"203.0.113.1",[747,78472,3543],{"class":757},[747,78474,4268],{"class":1640},[747,78476,78477,78479],{"class":749,"line":1102},[747,78478,78405],{"class":757},[747,78480,78481],{"class":1640},"[DEBUG ] Resolving host ceph-tutorial-node1\n",[747,78483,78484,78486],{"class":749,"line":1110},[747,78485,78405],{"class":757},[747,78487,78488],{"class":1640},"[DEBUG ] Monitor ceph-tutorial-node1 at 203.0.113.1\n",[747,78490,78491,78493,78496,78498,78500,78502],{"class":749,"line":1117},[747,78492,78405],{"class":757},[747,78494,78495],{"class":1640},"[DEBUG ] Monitor initial members are [",[747,78497,3543],{"class":757},[747,78499,77940],{"class":802},[747,78501,3543],{"class":757},[747,78503,4268],{"class":1640},[747,78505,78506,78508,78511,78513,78515,78517],{"class":749,"line":1123},[747,78507,78405],{"class":757},[747,78509,78510],{"class":1640},"[DEBUG ] Monitor addrs are [",[747,78512,3543],{"class":757},[747,78514,78470],{"class":802},[747,78516,3543],{"class":757},[747,78518,4268],{"class":1640},[747,78520,78521,78523],{"class":749,"line":1129},[747,78522,78405],{"class":757},[747,78524,78525],{"class":1640},"[DEBUG ] Creating a random mon key...\n",[747,78527,78528,78530],{"class":749,"line":1142},[747,78529,78405],{"class":757},[747,78531,78532],{"class":1640},"[DEBUG ] Writing monitor keyring to ceph.mon.keyring...\n",[747,78534,78535,78537],{"class":749,"line":1150},[747,78536,78405],{"class":757},[747,78538,78539],{"class":1640},"[DEBUG ] Writing initial config to ceph.conf...\n",[523,78541,44115,78542,78545],{},[567,78543,78544],{},"ls",", we see the generated files in the directory:",[738,78547,78549],{"className":1621,"code":78548,"language":1623,"meta":743,"style":743},"# ls\nceph.conf  ceph-deploy-ceph.log  ceph.mon.keyring\n",[567,78550,78551,78556],{"__ignoreMap":743},[747,78552,78553],{"class":749,"line":750},[747,78554,78555],{"class":772},"# ls\n",[747,78557,78558,78561,78564],{"class":749,"line":761},[747,78559,78560],{"class":1630},"ceph.conf",[747,78562,78563],{"class":802},"  ceph-deploy-ceph.log",[747,78565,78566],{"class":802},"  ceph.mon.keyring\n",[523,78568,78569,78570,1909],{},"Now we need to add an option to the bottom of the default Ceph configuration file ",[567,78571,78560],{},[523,78573,78574],{},"The options is:",[738,78576,78578],{"className":1621,"code":78577,"language":1623,"meta":743,"style":743},"osd pool default size = 2\n",[567,78579,78580],{"__ignoreMap":743},[747,78581,78582,78585,78588,78590,78593,78595],{"class":749,"line":750},[747,78583,78584],{"class":1630},"osd",[747,78586,78587],{"class":802}," pool",[747,78589,1931],{"class":802},[747,78591,78592],{"class":802}," size",[747,78594,19444],{"class":802},[747,78596,25425],{"class":1895},[523,78598,78599,78600,78603,78604,78606],{},"The option sets the number of replications, for two nodes you ",[584,78601,78602],{},"have"," tp set it to ",[567,78605,18115],{}," else the Ceph cluster will not become healthy.\nYou can also add other options here, but as this is just a basic tutorial on how to create a Ceph cluster I'm not covering other options than the default.",[523,78608,78609,78610,78612,78613,78615],{},"Now that our Ceph configuration ",[567,78611,78560],{}," is ready we are going to install Ceph on all servers and create our initial cluster monitor.\nThe command for deploying Ceph onto my two servers and creating the monitor server on your server chosen above, in my case ",[567,78614,77940],{}," the commands look like this:",[738,78617,78619],{"className":1621,"code":78618,"language":1623,"meta":743,"style":743},"ceph-deploy install --no-adjust-repos ceph-tutorial-node1 ceph-tutorial-node2\nceph-deploy mon create-initial\n",[567,78620,78621,78634],{"__ignoreMap":743},[747,78622,78623,78625,78627,78630,78632],{"class":749,"line":750},[747,78624,78160],{"class":1630},[747,78626,35408],{"class":802},[747,78628,78629],{"class":802}," --no-adjust-repos",[747,78631,78247],{"class":802},[747,78633,78250],{"class":802},[747,78635,78636,78638,78641],{"class":749,"line":761},[747,78637,78160],{"class":1630},[747,78639,78640],{"class":802}," mon",[747,78642,78643],{"class":802}," create-initial\n",[523,78645,78646,78649,78650,78653,78654,3052],{},[584,78647,78648],{},"Errors"," If the command fails, you need to apply a bug fix with the command ",[567,78651,78652],{},"sed -i '78s\u002Fallow \\*\u002Fallow\u002Fg' \u002Fusr\u002Flib\u002Fpython2.7\u002Fsite-packages\u002Fceph_deploy\u002Fgatherkeys.py",". The bug  can be seen ",[527,78655,3396],{"href":78656,"rel":78657},"http:\u002F\u002Ftracker.ceph.com\u002Fissues\u002F16443",[531],[523,78659,78660,78662,78663,78666],{},[584,78661,76064],{}," If the last command exits with errors, check the connectivity of your servers and firewall between the servers (if a firewall is in place between the servers, make sure it allows the Ceph ports, ports: TCP Ceph mon(itor) 6789, Ceph OSDs 6800:7300 (for more information see ",[527,78664,78129],{"href":78149,"rel":78665},[531],")).",[535,78668,78670],{"id":78669},"creating-the-storage-nodes","Creating the storage nodes",[523,78672,78673],{},"Use ssh to connect to your servers that you want to be storage nodes and create a directory for the storaged data.",[523,78675,78676],{},"In my case:",[738,78678,78680],{"className":1621,"code":78679,"language":1623,"meta":743,"style":743},"ssh ceph-tutorial-node1\nsudo mkdir \u002Fvar\u002Flocal\u002Fosd\nexit\n\nssh ceph-tutorial-node2\nsudo mkdir \u002Fvar\u002Flocal\u002Fosd\nexit\n",[567,78681,78682,78690,78699,78704,78708,78714,78722],{"__ignoreMap":743},[747,78683,78684,78687],{"class":749,"line":750},[747,78685,78686],{"class":1630},"ssh",[747,78688,78689],{"class":802}," ceph-tutorial-node1\n",[747,78691,78692,78694,78696],{"class":749,"line":761},[747,78693,3376],{"class":1630},[747,78695,76212],{"class":802},[747,78697,78698],{"class":802}," \u002Fvar\u002Flocal\u002Fosd\n",[747,78700,78701],{"class":749,"line":769},[747,78702,78703],{"class":4574},"exit\n",[747,78705,78706],{"class":749,"line":776},[747,78707,1255],{"emptyLinePlaceholder":1254},[747,78709,78710,78712],{"class":749,"line":784},[747,78711,78686],{"class":1630},[747,78713,78250],{"class":802},[747,78715,78716,78718,78720],{"class":749,"line":790},[747,78717,3376],{"class":1630},[747,78719,76212],{"class":802},[747,78721,78698],{"class":802},[747,78723,78724],{"class":749,"line":796},[747,78725,78703],{"class":4574},[523,78727,78728,78729,78731],{},"Back on your deployment server (in my case ",[567,78730,77940],{},") we are going to prepare the storage nodes with the following command:",[738,78733,78735],{"className":1621,"code":78734,"language":1623,"meta":743,"style":743},"ceph-deploy osd prepare {ceph-node}:\u002Fpath\u002Fto\u002Fdirectory\n",[567,78736,78737],{"__ignoreMap":743},[747,78738,78739,78741,78744,78747],{"class":749,"line":750},[747,78740,78160],{"class":1630},[747,78742,78743],{"class":802}," osd",[747,78745,78746],{"class":802}," prepare",[747,78748,78749],{"class":802}," {ceph-node}:\u002Fpath\u002Fto\u002Fdirectory\n",[523,78751,78752],{},"For my two servers I run:",[738,78754,78756],{"className":1621,"code":78755,"language":1623,"meta":743,"style":743},"ceph-deploy osd prepare ceph-tutorial-node1:\u002Fvar\u002Flocal\u002Fosd ceph-tutorial-node2:\u002Fvar\u002Flocal\u002Fosd\n",[567,78757,78758],{"__ignoreMap":743},[747,78759,78760,78762,78764,78766,78769],{"class":749,"line":750},[747,78761,78160],{"class":1630},[747,78763,78743],{"class":802},[747,78765,78746],{"class":802},[747,78767,78768],{"class":802}," ceph-tutorial-node1:\u002Fvar\u002Flocal\u002Fosd",[747,78770,78771],{"class":802}," ceph-tutorial-node2:\u002Fvar\u002Flocal\u002Fosd\n",[523,78773,8764,78774,78777],{},[567,78775,78776],{},"ceph-deploy osd prepare"," prepares the storage location and sets up the Ceph OSD in the background.\nThe only thing we have to do now is to activate the storage locations (Ceph OSDs) using the activate command:",[738,78779,78781],{"className":1621,"code":78780,"language":1623,"meta":743,"style":743},"ceph-deploy osd activate {ceph-node}:\u002Fpath\u002Fto\u002Fdirectory\n",[567,78782,78783],{"__ignoreMap":743},[747,78784,78785,78787,78789,78792],{"class":749,"line":750},[747,78786,78160],{"class":1630},[747,78788,78743],{"class":802},[747,78790,78791],{"class":802}," activate",[747,78793,78749],{"class":802},[523,78795,78752],{},[738,78797,78799],{"className":1621,"code":78798,"language":1623,"meta":743,"style":743},"ceph-deploy osd activate ceph-tutorial-node1:\u002Fvar\u002Flocal\u002Fosd ceph-tutorial-node2:\u002Fvar\u002Flocal\u002Fosd\n",[567,78800,78801],{"__ignoreMap":743},[747,78802,78803,78805,78807,78809,78811],{"class":749,"line":750},[747,78804,78160],{"class":1630},[747,78806,78743],{"class":802},[747,78808,78791],{"class":802},[747,78810,78768],{"class":802},[747,78812,78771],{"class":802},[535,78814,78816],{"id":78815},"finalizing-your-ceph-cluster","Finalizing your Ceph cluster",[523,78818,78819],{},"Copy the Ceph admin key to the servers you want to be able to configure your Ceph cluster from with the below command:",[738,78821,78823],{"className":1621,"code":78822,"language":1623,"meta":743,"style":743},"ceph-deploy admin {deployment-node}\n",[567,78824,78825],{"__ignoreMap":743},[747,78826,78827,78829,78832],{"class":749,"line":750},[747,78828,78160],{"class":1630},[747,78830,78831],{"class":802}," admin",[747,78833,78834],{"class":802}," {deployment-node}\n",[523,78836,78837,78839,78840,78843],{},[584,78838,76064],{}," Where ",[567,78841,78842],{},"{deployment-node}"," is your server you ran all the commands on.",[523,78845,78846],{},"To check if you Ceph cluster is healthy use the health command:",[738,78848,78850],{"className":1621,"code":78849,"language":1623,"meta":743,"style":743},"# ceph health\nHEALTH_OK\n",[567,78851,78852,78857],{"__ignoreMap":743},[747,78853,78854],{"class":749,"line":750},[747,78855,78856],{"class":772},"# ceph health\n",[747,78858,78859],{"class":749,"line":761},[747,78860,78861],{"class":1630},"HEALTH_OK\n",[523,78863,78864,78866,78867,78869],{},[584,78865,76064],{}," If it shows something else than ",[567,78868,16951],{}," your cluster is unhealthy and may not even work properly.",[523,78871,78872],{},"That's all. Now you have a working Ceph storage cluster.",[535,78874,207],{"id":26330},[613,78876,78878],{"id":78877},"log-file-location","Log file location",[523,78880,78881,78882,1909],{},"In case of other problems, all Ceph log files are located under ",[567,78883,78884],{},"\u002Fvar\u002Flog\u002Fceph\u002F",[523,78886,78887,856],{},[584,78888,78889],{},"Example",[738,78891,78893],{"className":1621,"code":78892,"language":1623,"meta":743,"style":743},"# ls -hl \u002Fvar\u002Flog\u002Fceph\u002F\ntotal 340K\n-rw------- 1 root root 126K Aug  8 13:24 ceph.log\n-rw-r--r-- 1 root root 196K Aug  8 13:25 ceph-mon.ceph-tutorial-node1.log\n-rw-r--r-- 1 root root 5.2K Aug  8 09:26 ceph-osd.0.log\n\n",[567,78894,78895,78900,78907,78933,78957],{"__ignoreMap":743},[747,78896,78897],{"class":749,"line":750},[747,78898,78899],{"class":772},"# ls -hl \u002Fvar\u002Flog\u002Fceph\u002F\n",[747,78901,78902,78904],{"class":749,"line":761},[747,78903,58620],{"class":1630},[747,78905,78906],{"class":802}," 340K\n",[747,78908,78909,78912,78914,78916,78918,78921,78924,78927,78930],{"class":749,"line":769},[747,78910,78911],{"class":1630},"-rw-------",[747,78913,3597],{"class":1895},[747,78915,5149],{"class":802},[747,78917,5149],{"class":802},[747,78919,78920],{"class":802}," 126K",[747,78922,78923],{"class":802}," Aug",[747,78925,78926],{"class":1895},"  8",[747,78928,78929],{"class":802}," 13:24",[747,78931,78932],{"class":802}," ceph.log\n",[747,78934,78935,78938,78940,78942,78944,78947,78949,78951,78954],{"class":749,"line":776},[747,78936,78937],{"class":1630},"-rw-r--r--",[747,78939,3597],{"class":1895},[747,78941,5149],{"class":802},[747,78943,5149],{"class":802},[747,78945,78946],{"class":802}," 196K",[747,78948,78923],{"class":802},[747,78950,78926],{"class":1895},[747,78952,78953],{"class":802}," 13:25",[747,78955,78956],{"class":802}," ceph-mon.ceph-tutorial-node1.log\n",[747,78958,78959,78961,78963,78965,78967,78970,78972,78974,78977],{"class":749,"line":784},[747,78960,78937],{"class":1630},[747,78962,3597],{"class":1895},[747,78964,5149],{"class":802},[747,78966,5149],{"class":802},[747,78968,78969],{"class":802}," 5.2K",[747,78971,78923],{"class":802},[747,78973,78926],{"class":1895},[747,78975,78976],{"class":802}," 09:26",[747,78978,78979],{"class":802}," ceph-osd.0.log\n",[613,78981,78983],{"id":78982},"clock-skew-error","\"Clock skew\" error",[523,78985,78986,78987,78990],{},"If the health command returns a message like ",[567,78988,78989],{},"clock skew detected",", then your clock on the server(s) is not synced. Please install and configure an NTP server and client(s).",[535,78992,14526],{"id":14525},[523,78994,78995,78996,78998,78999,587,79004,1909],{},"This should help you get started with installing\u002Frunning a Ceph cluster on CentOS.\nIf you have issues, please refer to the official ",[567,78997,78160],{}," documentation her: ",[527,79000,79003],{"href":79001,"rel":79002},"http:\u002F\u002Fdocs.ceph.com\u002Fceph-deploy\u002Fdocs\u002F",[531],"ceph-deploy - Deploy Ceph with minimal infrastructure - ceph-deploy 2.0.0 documentation",[527,79005,79008],{"href":79006,"rel":79007},"http:\u002F\u002Fdocs.ceph.com\u002Fdocs\u002Fmaster\u002Frados\u002Fdeployment\u002F",[531],"Ceph Deployment - Ceph Documentation",[523,79010,13967],{},[2890,79012,79013],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":743,"searchDepth":761,"depth":761,"links":79015},[79016,79017,79018,79019,79020,79021,79022,79026],{"id":22267,"depth":761,"text":22268},{"id":77944,"depth":761,"text":77945},{"id":78153,"depth":761,"text":78154},{"id":78229,"depth":761,"text":78230},{"id":78669,"depth":761,"text":78670},{"id":78815,"depth":761,"text":78816},{"id":26330,"depth":761,"text":207,"children":79023},[79024,79025],{"id":78877,"depth":769,"text":78878},{"id":78982,"depth":769,"text":78983},{"id":14525,"depth":761,"text":14526},"2016-07-29T09:29:00+02:00",{"src":70762},{"tags":79030},[427],"\u002Fblog\u002F2016\u002Fceph-build-your-own-cluster-on-centos",{"title":77869,"description":77877},"3.blog\u002F2016\u002Fceph-build-your-own-cluster-on-centos","K1mEpFbAq9lxMOUqMTf6DyxVl3Vd2fLIrTb04xI8xDU",{"id":79036,"title":79037,"authors":79038,"badge":518,"body":79041,"date":79529,"description":79530,"extension":2911,"image":518,"meta":79531,"navigation":1254,"path":79535,"seo":79536,"stem":79537,"__hash__":79538},"posts\u002F3.blog\u002F2016\u002Fsteamcmd-not-working-on-cephfs.md","SteamCMD: Not working on CephFS",[79039],{"name":514,"to":515,"avatar":79040},{"src":517},{"type":520,"value":79042,"toc":79527},[79043,79048,79062,79070,79279,79286,79452,79482,79496,79517,79524],[523,79044,79045],{},[3049,79046,79047],{},"See title.",[523,79049,79050,79051,79054,79055,59081,79058,79061],{},"Yes, you read right. SteamCMD is not working on CephFS (and maybe GlusterFS too, I can't test it on GlusterFS ).\nThe reason for that is a \"failing\" ",[567,79052,79053],{},"getdents"," when on the CephFS.\nA colleague told me that error may be related to the ",[567,79056,79057],{},"st_size",[567,79059,79060],{},"rbytes"," of CephFS.",[523,79063,79064,856],{},[584,79065,79066,79069],{},[567,79067,79068],{},"strace"," on xfs filesystem",[738,79071,79073],{"className":1621,"code":79072,"language":1623,"meta":743,"style":743},"[...]\n[pid 123] stat64(\".\u002Fzip0.zip\", 0xf71c9c40) = -1 ENOENT (No such file or directory)\n[pid 123] open(\".\", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 2\n[pid 123] fstat64(2, {st_mode=S_IFDIR|0755, st_size=100, ...}) = 0\n[pid 123] getdents(2, \u002F* 7 entries *\u002F, 32768) = 152\n[pid 123] getdents(2, \u002F* 0 entries *\u002F, 32768) = 0\n[pid 123] close(2)\n[...]\n",[567,79074,79075,79083,79120,79162,79193,79228,79256,79271],{"__ignoreMap":743},[747,79076,79077,79079,79081],{"class":749,"line":750},[747,79078,4253],{"class":757},[747,79080,5685],{"class":1640},[747,79082,4268],{"class":757},[747,79084,79085,79087,79090,79092,79095,79098,79100,79103,79106,79109,79112,79114,79116,79118],{"class":749,"line":761},[747,79086,4253],{"class":757},[747,79088,79089],{"class":1640},"pid 123",[747,79091,4259],{"class":757},[747,79093,79094],{"class":1640}," stat64(",[747,79096,79097],{"class":1630},"\".\u002Fzip0.zip\"",[747,79099,10580],{"class":1630},[747,79101,79102],{"class":1895}," 0xf71c9c40",[747,79104,79105],{"class":1640},") = -1 ENOENT (",[747,79107,79108],{"class":1630},"No",[747,79110,79111],{"class":802}," such",[747,79113,11351],{"class":802},[747,79115,4423],{"class":802},[747,79117,5620],{"class":802},[747,79119,3600],{"class":1640},[747,79121,79122,79124,79126,79128,79131,79134,79136,79139,79141,79144,79146,79149,79151,79154,79156,79159],{"class":749,"line":769},[747,79123,4253],{"class":757},[747,79125,79089],{"class":1640},[747,79127,4259],{"class":757},[747,79129,79130],{"class":1640}," open(",[747,79132,79133],{"class":1630},"\".\"",[747,79135,10580],{"class":1630},[747,79137,79138],{"class":802}," O_RDONLY",[747,79140,3616],{"class":757},[747,79142,79143],{"class":1630},"O_NONBLOCK",[747,79145,3616],{"class":757},[747,79147,79148],{"class":1630},"O_LARGEFILE",[747,79150,3616],{"class":757},[747,79152,79153],{"class":1630},"O_DIRECTORY",[747,79155,3616],{"class":757},[747,79157,79158],{"class":1630},"O_CLOEXEC",[747,79160,79161],{"class":1640},") = 2\n",[747,79163,79164,79166,79168,79170,79173,79176,79179,79181,79184,79187,79190],{"class":749,"line":776},[747,79165,4253],{"class":757},[747,79167,79089],{"class":1640},[747,79169,4259],{"class":757},[747,79171,79172],{"class":1640}," fstat64(",[747,79174,79175],{"class":1630},"2,",[747,79177,79178],{"class":802}," {st_mode=S_IFDIR",[747,79180,3616],{"class":757},[747,79182,79183],{"class":1630},"0755,",[747,79185,79186],{"class":802}," st_size=100,",[747,79188,79189],{"class":802}," ...}",[747,79191,79192],{"class":1640},") = 0\n",[747,79194,79195,79197,79199,79201,79204,79206,79209,79211,79213,79216,79219,79222,79225],{"class":749,"line":784},[747,79196,4253],{"class":757},[747,79198,79089],{"class":1640},[747,79200,4259],{"class":757},[747,79202,79203],{"class":1640}," getdents(",[747,79205,79175],{"class":1630},[747,79207,79208],{"class":802}," \u002F",[747,79210,22721],{"class":1640},[747,79212,16420],{"class":1895},[747,79214,79215],{"class":802}," entries",[747,79217,79218],{"class":1640}," *",[747,79220,79221],{"class":802},"\u002F,",[747,79223,79224],{"class":1895}," 32768",[747,79226,79227],{"class":1640},") = 152\n",[747,79229,79230,79232,79234,79236,79238,79240,79242,79244,79246,79248,79250,79252,79254],{"class":749,"line":790},[747,79231,4253],{"class":757},[747,79233,79089],{"class":1640},[747,79235,4259],{"class":757},[747,79237,79203],{"class":1640},[747,79239,79175],{"class":1630},[747,79241,79208],{"class":802},[747,79243,22721],{"class":1640},[747,79245,3588],{"class":1895},[747,79247,79215],{"class":802},[747,79249,79218],{"class":1640},[747,79251,79221],{"class":802},[747,79253,79224],{"class":1895},[747,79255,79192],{"class":1640},[747,79257,79258,79260,79262,79264,79267,79269],{"class":749,"line":796},[747,79259,4253],{"class":757},[747,79261,79089],{"class":1640},[747,79263,4259],{"class":757},[747,79265,79266],{"class":1640}," close(",[747,79268,18115],{"class":1630},[747,79270,3600],{"class":1640},[747,79272,79273,79275,79277],{"class":749,"line":806},[747,79274,4253],{"class":757},[747,79276,5685],{"class":1640},[747,79278,4268],{"class":757},[523,79280,79281],{},[584,79282,79283,79285],{},[567,79284,79068],{}," on CephFS:",[738,79287,79289],{"className":1621,"code":79288,"language":1623,"meta":743,"style":743},"[...]\n[pid 123] stat64(\".\u002Fzip0.zip\", 0xf720ac40) = -1 ENOENT (No such file or directory)\n[pid 123] open(\".\", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 2\n[pid 123] fstat64(2, {st_mode=S_IFDIR|0755, st_size=5, ...}) = 0\n[pid 123] getdents(2, 0xf7002114, 65536) = -1 EOVERFLOW (Value too large for defined data type)\n[pid 123] close(2)\n[...]\n",[567,79290,79291,79299,79330,79364,79389,79430,79444],{"__ignoreMap":743},[747,79292,79293,79295,79297],{"class":749,"line":750},[747,79294,4253],{"class":757},[747,79296,5685],{"class":1640},[747,79298,4268],{"class":757},[747,79300,79301,79303,79305,79307,79309,79311,79313,79316,79318,79320,79322,79324,79326,79328],{"class":749,"line":761},[747,79302,4253],{"class":757},[747,79304,79089],{"class":1640},[747,79306,4259],{"class":757},[747,79308,79094],{"class":1640},[747,79310,79097],{"class":1630},[747,79312,10580],{"class":1630},[747,79314,79315],{"class":1895}," 0xf720ac40",[747,79317,79105],{"class":1640},[747,79319,79108],{"class":1630},[747,79321,79111],{"class":802},[747,79323,11351],{"class":802},[747,79325,4423],{"class":802},[747,79327,5620],{"class":802},[747,79329,3600],{"class":1640},[747,79331,79332,79334,79336,79338,79340,79342,79344,79346,79348,79350,79352,79354,79356,79358,79360,79362],{"class":749,"line":769},[747,79333,4253],{"class":757},[747,79335,79089],{"class":1640},[747,79337,4259],{"class":757},[747,79339,79130],{"class":1640},[747,79341,79133],{"class":1630},[747,79343,10580],{"class":1630},[747,79345,79138],{"class":802},[747,79347,3616],{"class":757},[747,79349,79143],{"class":1630},[747,79351,3616],{"class":757},[747,79353,79148],{"class":1630},[747,79355,3616],{"class":757},[747,79357,79153],{"class":1630},[747,79359,3616],{"class":757},[747,79361,79158],{"class":1630},[747,79363,79161],{"class":1640},[747,79365,79366,79368,79370,79372,79374,79376,79378,79380,79382,79385,79387],{"class":749,"line":776},[747,79367,4253],{"class":757},[747,79369,79089],{"class":1640},[747,79371,4259],{"class":757},[747,79373,79172],{"class":1640},[747,79375,79175],{"class":1630},[747,79377,79178],{"class":802},[747,79379,3616],{"class":757},[747,79381,79183],{"class":1630},[747,79383,79384],{"class":802}," st_size=5,",[747,79386,79189],{"class":802},[747,79388,79192],{"class":1640},[747,79390,79391,79393,79395,79397,79399,79401,79404,79406,79409,79412,79415,79418,79420,79423,79425,79428],{"class":749,"line":784},[747,79392,4253],{"class":757},[747,79394,79089],{"class":1640},[747,79396,4259],{"class":757},[747,79398,79203],{"class":1640},[747,79400,79175],{"class":1630},[747,79402,79403],{"class":802}," 0xf7002114,",[747,79405,7566],{"class":1895},[747,79407,79408],{"class":1640},") = -1 EOVERFLOW (",[747,79410,79411],{"class":1630},"Value",[747,79413,79414],{"class":802}," too",[747,79416,79417],{"class":802}," large",[747,79419,3761],{"class":802},[747,79421,79422],{"class":802}," defined",[747,79424,17736],{"class":802},[747,79426,79427],{"class":802}," type",[747,79429,3600],{"class":1640},[747,79431,79432,79434,79436,79438,79440,79442],{"class":749,"line":790},[747,79433,4253],{"class":757},[747,79435,79089],{"class":1640},[747,79437,4259],{"class":757},[747,79439,79266],{"class":1640},[747,79441,18115],{"class":1630},[747,79443,3600],{"class":1640},[747,79445,79446,79448,79450],{"class":749,"line":796},[747,79447,4253],{"class":757},[747,79449,5685],{"class":1640},[747,79451,4268],{"class":757},[523,79453,79454,79455,79457,79458,79460,79461,18501,79464,79466,79467,79469,79470,79473,79474,79477,79478,79481],{},"As you can see the ",[567,79456,79057],{}," on the xfs filesystem reported is higher (",[567,79459,40279],{},").\nThe third parameter (",[567,79462,79463],{},"unsigned int count",[567,79465,79053],{}," man page), comes as a result from the \"weird\" ",[567,79468,79057],{},", given to the ",[567,79471,79472],{},"getdents()"," function is lower ",[567,79475,79476],{},"32768"," than the int ",[567,79479,79480],{},"65536"," on the CephFS.",[523,79483,79484,79485,79488,79489,79492,79493,79495],{},"In C an ",[567,79486,79487],{},"unsigned short int"," can only be ",[567,79490,79491],{},"65535"," max, but ",[567,79494,79480],{}," got returned..",[523,79497,79498,79499,79501,79502,79504,79505,79507,79508,79511,79512,79516],{},"Next I tried to look into the ",[567,79500,79060],{}," that a colleague mentioned.\nAnd guess what I found looking for a way to disable\u002Ffix\u002Fmodify the ",[567,79503,79057],{}," from CephFS.\nI found out that the documented ",[567,79506,79060],{}," and for me interesting ",[567,79509,79510],{},"norbytes"," mount option.\nWhen looking at the docs we see that both mount options are documented: ",[527,79513,79514],{"href":79514,"rel":79515},"http:\u002F\u002Fdocs.ceph.com\u002Fdocs\u002Fhammer\u002Fman\u002F8\u002Fmount.ceph\u002F#options",[531],"\nI used GitHub's code search but the only occurrences I found are in the man page files.",[523,79518,79519,79520,1909],{},"I have directly created an issue at the Ceph's Bugtracker to see if it is an issue in my setup or really a missing feature in Ceph. For the interested here is the link to the issue: ",[527,79521,79522],{"href":79522,"rel":79523},"http:\u002F\u002Ftracker.ceph.com\u002Fissues\u002F16738",[531],[2890,79525,79526],{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":743,"searchDepth":761,"depth":761,"links":79528},[],"2016-07-26T18:30:53+02:00","A small and uncomplete analysis of why the SteamCMD is not working on CephFS.",{"tags":79532},[79533,79534,427,16051],"SteamCMD","Analysis","\u002Fblog\u002F2016\u002Fsteamcmd-not-working-on-cephfs",{"title":79037,"description":79530},"3.blog\u002F2016\u002Fsteamcmd-not-working-on-cephfs","ea_2IYey61sSj6MBhguHcsfM2Xucl3fCR1NsPzn-cto",{"id":79540,"title":79541,"authors":79542,"badge":518,"body":79545,"date":79572,"description":743,"extension":2911,"image":518,"meta":79573,"navigation":1254,"path":79575,"seo":79576,"stem":79577,"__hash__":79578},"posts\u002F3.blog\u002F2016\u002Fnuclear-fusion-presentation.md","Nuclear Fusion Presentation",[79543],{"name":514,"to":515,"avatar":79544},{"src":517},{"type":520,"value":79546,"toc":79570},[79547,79555,79558,79561,79564,79567],[6072,79548,79549,79553],{},[523,79550,79551],{},[584,79552,6189],{},[523,79554,75716],{},[523,79556,79557],{},"If you want to use or present my presentation somewhere, please get in contact with me first. Thanks!",[18903,79559],{"src":79560,"frameBorder":3579,"height":18906,"allowFullScreen":5306,"mozallowfullscreen":5306,"webkitallowfullscreen":5306},"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002F12OPXT0LAp1cvIgRec-Y2Sn4UI8wKaoBLRPerSatUAsw\u002Fembed?start=false&loop=true&delayms=5000",[523,79562,79563],{},"And for the laughs, my origianl presentation I did for school some years ago and that \"inspired\" the new presentation:",[18903,79565],{"src":79566,"frameBorder":3579,"height":18906,"allowFullScreen":5306,"mozallowfullscreen":5306,"webkitallowfullscreen":5306},"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002F1j-IfSMNyR0GwffgWcfJJTyLLJz5E1JcUishBW2-Zixc\u002Fembed?start=false&loop=true&delayms=5000",[523,79568,79569],{},"If you like or have any suggestions for the presentation, feel free to leave them in the comments. :)",{"title":743,"searchDepth":761,"depth":761,"links":79571},[],"2016-07-09T16:44:22+02:00",{"tags":79574},[18918],"\u002Fblog\u002F2016\u002Fnuclear-fusion-presentation",{"title":79541,"description":743},"3.blog\u002F2016\u002Fnuclear-fusion-presentation","VGA5XRCCwPBU4eYzGuaHjqMnk21irfEWpw_FMl4s_PU",{"id":79580,"title":79581,"authors":79582,"badge":518,"body":79585,"date":79647,"description":79648,"extension":2911,"image":518,"meta":79649,"navigation":1254,"path":79652,"seo":79653,"stem":79654,"__hash__":79655},"posts\u002F3.blog\u002F2016\u002Fpsa-keep-your-computer-clean.md","PSA: Keep your computer clean!",[79583],{"name":514,"to":515,"avatar":79584},{"src":517},{"type":520,"value":79586,"toc":79645},[79587,79602,79605,79608,79611,79618,79620,79623,79626,79628,79642],[6072,79588,79589,79595],{},[523,79590,79591],{},[3069,79592],{"alt":79593,"src":79594},"Dust in the Radiator","\u002Fblog\u002F2016\u002Fpsa-keep-your-computer-clean\u002Fdust-in-the-radi-1.png",[523,79596,79597,79601],{},[3069,79598],{"alt":79599,"src":79600},"The pile of dust","\u002Fblog\u002F2016\u002Fpsa-keep-your-computer-clean\u002Fdust-in-the-radi-2.png","\nThat much dust came off the radiator. The dust was heavily reducing the cooling of the cpu.",[523,79603,79604],{},"I can't stress this enough. Cooling systems full with dust reducing the cooling throughput your computer.",[523,79606,79607],{},"What do the Pictures \"tell\" you? The air flow isn't going through very well.\nIf your computer is under high load, it could happen that the cpu or gpu are throttled. because of high temperature.",[523,79609,79610],{},"In worst case: When it's getting really hot, one of your computer components may overheat and causes your computer to get slower or just turn off.",[6072,79612,79613],{},[523,79614,79615,79617],{},[584,79616,3103],{}," Keep your computer clean.",[2979,79619],{},[523,79621,79622],{},"I personally clean my computer every 4 to 5 months and so should you too!",[523,79624,79625],{},"Have fun keeping your computer clean! :)",[2979,79627],{},[523,79629,79630,79633,79634],{},[584,79631,79632],{},"EDIT",": I cleaned my computer again after I didn't do it longer than I want to admit.. Here is a video of the dust in the radiator:\n",[79635,79636,79638],"video",{"controls":1254,"poster":79637},"\u002Fblog\u002F2016\u002FPSA-Keep-your-computer-clean\u002Fdust-in-the-radi-1.png",[60059,79639],{"src":79640,"type":79641},"\u002Fblog\u002F2016\u002FPSA-Keep-your-computer-clean\u002Fradi-dust-blockage.mp4","video\u002Fmp4",[523,79643,79644],{},"Well.. I should clean my radiators on open case machines more often.",{"title":743,"searchDepth":761,"depth":761,"links":79646},[],"2016-06-27T10:43:00+02:00","Keep your computer(s) clean for them to work even now when a hot summer is around the corner.",{"tags":79650},[79651,14555],"PSA","\u002Fblog\u002F2016\u002Fpsa-keep-your-computer-clean",{"title":79581,"description":79648},"3.blog\u002F2016\u002Fpsa-keep-your-computer-clean","FTwfPkgVAT9C-C4IgDkDC2VxzVBvedDQ5W6nwDBhUL8",{"id":79657,"title":79658,"authors":79659,"badge":518,"body":79662,"date":79735,"description":79736,"extension":2911,"image":518,"meta":79737,"navigation":1254,"path":79742,"seo":79743,"stem":79744,"__hash__":79745},"posts\u002F3.blog\u002F2016\u002Fansible-user-management-role.md","Ansible User Management Role",[79660],{"name":514,"to":515,"avatar":79661},{"src":517},{"type":520,"value":79663,"toc":79732},[79664,79677,79679,79682,79712,79714,79722,79725,79727,79730],[523,79665,79666,79667,79672,79673],{},"GitHub repository: ",[527,79668,79671],{"href":79669,"rel":79670},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fansible-usersmgt",[531],"galexrt\u002Fansible-usersmgt",".\nAnsible Galaxy: ",[527,79674,3396],{"href":79675,"rel":79676},"https:\u002F\u002Fgalaxy.ansible.com\u002Fgalexrt\u002Fansible-usersmgt\u002F",[531],[2979,79678],{},[523,79680,79681],{},"This is an Ansible role for user management that I have created.\nCurrently has the following features:",[668,79683,79684,79691,79702],{},[638,79685,79686,79687,79690],{},"SSH key management (currently fixed ssh key directory ",[567,79688,79689],{},"\u002Fetc\u002Fssh\u002Fauthorized_keys",", is on the roadmap).",[638,79692,79693,79694],{},"Creation and removal of:\n",[668,79695,79696,79699],{},[638,79697,79698],{},"Groups",[638,79700,79701],{},"Users",[638,79703,79704,79705,587,79708,79711],{},"Additional fine tunning through ",[567,79706,79707],{},"only_on_hosts",[567,79709,79710],{},"not_on_hosts"," lists possible.",[535,79713,63093],{"id":74855},[523,79715,20497,79716,79721],{},[527,79717,79720],{"href":79718,"rel":79719},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fansible-usersmgt\u002Fblob\u002Fmaster\u002FEXAMPLES.md",[531],"EXAMPLES.md"," from the repository.",[19016,79723],{"src":79724},"https:\u002F\u002Fgist-it.appspot.com\u002Fhttps:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fansible-usersmgt\u002Fblob\u002Fmaster\u002FEXAMPLES.md",[2979,79726],{},[523,79728,79729],{},"If you have any feedback or ideas for improvements, feel free to leave it in the comments or create an issue or pull request on GitHub. :)",[523,79731,13967],{},{"title":743,"searchDepth":761,"depth":761,"links":79733},[79734],{"id":74855,"depth":761,"text":63093},"2016-05-25T14:36:25+02:00","A simple to use Ansible user management role made by me.",{"tags":79738},[79739,79740,79741],"GitHub Projects","User Management","Ansible","\u002Fblog\u002F2016\u002Fansible-user-management-role",{"title":79658,"description":79736},"3.blog\u002F2016\u002Fansible-user-management-role","jMT8qX4204jLkFlYEE4QjjHBicDQF_6Nk8MPAt4NZn0",{"id":79747,"title":79748,"authors":79749,"badge":518,"body":79752,"date":79872,"description":79873,"extension":2911,"image":518,"meta":79874,"navigation":1254,"path":79877,"seo":79878,"stem":79879,"__hash__":79880},"posts\u002F3.blog\u002F2016\u002Fin-search-of-a-webhosting.md","In search of a Webhosting",[79750],{"name":514,"to":515,"avatar":79751},{"src":517},{"type":520,"value":79753,"toc":79863},[79754,79757,79761,79765,79768,79773,79777,79780,79785,79790,79794,79805,79808,79812,79815,79835,79838,79840,79844,79847,79855,79858],[523,79755,79756],{},"Some points you should consider before buying a shared webhosting.",[535,79758,79760],{"id":79759},"points-to-consider-about-a-shared-hosting","Points to consider about a shared hosting",[613,79762,79764],{"id":79763},"ipv6-connectivity","IPv6 connectivity",[523,79766,79767],{},"If the hoster offers CloudFlare CDN with the package, you can ignore this point as CloudFlare has 6to4 support.",[6072,79769,79770],{},[523,79771,79772],{},"I personally completely ignore this point, if CloudFlare CDN is available.",[613,79774,79776],{"id":79775},"is-unlimited-really-unlimited","Is Unlimited really Unlimited?",[523,79778,79779],{},"Some hoster have offers like \"Unlimited Webspace\", but you will never have unlimited space.\nIf you check the disk space with a script, you'll see that you don't have \"unlimited\" space. The space you'll see is more of a \"normal\" hard drive size like 1TB or a bit more for HDD hosting and for SSD hosting ranging from 240 to 480GB. Keep that in mind.",[6072,79781,79782],{},[523,79783,79784],{},"The GB values are from my \"experience\" with shared webhostings until now.",[523,79786,79787,79789],{},[584,79788,76064],{}," that some hosters give you \"unlimited\" webspace, but have a limit on the inode count. For newlings, one inode is one file or directory.\nBut in most cases the limit of the inode count is enough for a blog, as long as you don't intend to upload 10 thousands of pictures for every post.\nThe inode count should even cover multiple small to middle WordPress installation.",[613,79791,79793],{"id":79792},"price-politics-a-dark-chapter-in-the-existence-of-companies","Price Politics - A dark chapter in the existence of companies",[523,79795,79796,79797,79800,79801,79804],{},"Companies get it right! If you display a \"promotional\" price of ",[584,79798,79799],{},"3.99$"," and I as a customer notice at the checkout that the price is for a ",[584,79802,79803],{},"3-year contract","..\nI don't want to bind myself for so long to a company and you should not too!\nA simple reason for not binding yourself to a company for that long, is that when big problems occur (after the money back guarantee) but you have to stick to them, because you have paid for 3-years.",[523,79806,79807],{},"One month contracts are better, for the point that you can cancel any time.",[613,79809,79811],{"id":79810},"webhosting-features-that-should-also-be-included","Webhosting features that should also be included",[523,79813,79814],{},"A webhoster should always have at least the following features:",[668,79816,79817,79820,79823,79829,79832],{},[638,79818,79819],{},"PHP version selection (+ PHP module selection) - Older PHP version for older PHP applications.",[638,79821,79822],{},"Addon Domains aka \"Multiple External Domain\" Hosting - To allow the hosting of multiple domains even from an external registrar.",[638,79824,79825,79826,79828],{},"Error Log Insight - To see configuration problems with ",[567,79827,17818],{}," files and your PHP applications.",[638,79830,79831],{},"CloudFlare CDN - Website optimization, CDN and DDOS protection.",[638,79833,79834],{},"SSH (SFTP) access - For secure file access or at least FTP with TLS encryption.",[523,79836,79837],{},"I think that these are the most important features a webhosting should have included (for \"free\", without an extra fee).",[2979,79839],{},[535,79841,79843],{"id":79842},"an-question-to-ask-yourself-should-i-host-it-myself","An question to ask yourself: Should I host it myself?",[523,79845,79846],{},"Some people with enough knowledge may ask themselves \"Why don't I setup a webhosting and mail server by myself?\".\nI asked myself the same question, but fast came to a conclusion.\nIf I setup the webhosting and mail service by myself, I have to look after it, keep the software up to date and check that all services are up and running (blacklist checking, etc.).\nKeeping everything running aka Maintenance will take up some time.",[6072,79848,79849],{},[523,79850,79851,79854],{},[584,79852,79853],{},"Keep in mind!"," Setting up your own webhosting takes a good amount of time and the maintenace of the services requires time too.",[523,79856,79857],{},"I personally have tested some hosters, but after now three \"tested\" hosters I decided that it's cheaper and even if it costs \"more\" time to maintain that self hosting is a lot better.\nWhen you host on your own server(s), you can better fortify against attacks, don't install\u002Fdisable everything you don't need to improve performance.",[523,79859,79860,79862],{},[584,79861,3103],{}," Hosting on your own server is better, because you are alone and can do whatever you want. But you NEED to have good knowledge to do so!",{"title":743,"searchDepth":761,"depth":761,"links":79864},[79865,79871],{"id":79759,"depth":761,"text":79760,"children":79866},[79867,79868,79869,79870],{"id":79763,"depth":769,"text":79764},{"id":79775,"depth":769,"text":79776},{"id":79792,"depth":769,"text":79793},{"id":79810,"depth":769,"text":79811},{"id":79842,"depth":761,"text":79843},"2016-05-08T14:48:13+02:00","Some points to look out for when looking for a cheap and good shared webhosting.",{"tags":79875},[79876],"Webhosting","\u002Fblog\u002F2016\u002Fin-search-of-a-webhosting",{"title":79748,"description":79873},"3.blog\u002F2016\u002Fin-search-of-a-webhosting","T0M3wFk_SkfHSDVvKm18gV8iKWjBQrNc3U_PVpoWIpQ",{"id":79882,"title":79883,"authors":79884,"badge":518,"body":79887,"date":79934,"description":79935,"extension":2911,"image":518,"meta":79936,"navigation":1254,"path":79941,"seo":79942,"stem":79943,"__hash__":79944},"posts\u002F3.blog\u002F2016\u002Fsrcds-server-restarter-script.md","SRCDS Server Restarter Script",[79885],{"name":514,"to":515,"avatar":79886},{"src":517},{"type":520,"value":79888,"toc":79932},[79889,79902,79912,79918],[523,79890,79891,79892,79895,79896,79901],{},"The script uses the ",[567,79893,79894],{},"Net::SRCDS::Queries"," Perl module by Author ",[527,79897,79900],{"href":79898,"rel":79899},"https:\u002F\u002Fmetacpan.org\u002Fauthor\u002FMASANORIH",[531],"MASANORIH"," to communicate with the SRCDS servers.",[523,79903,79904,79905,79908,79909,79911],{},"It checks if the servers responds to Source Server Queries, when the server does not respond to the queries, the script considers the server as unreachable\u002Foffline.\nWhen the server is considered unreachable\u002Foffline, the script uses normal bash commands to write a line with ",[567,79906,79907],{},"unreachable"," into a file.\nAfter the script wrote the line to the file it checks how many lines with ",[567,79910,79907],{}," have been written to the file.\nIf five lines or more have been written to the file, the configured restart script\u002Fcommands will be executed.",[523,79913,79914,79915],{},"That's all the script does. Simple but effective, right? ",[79916,79917],"d",{},[6072,79919,79920],{},[523,79921,79922,79923,79928,79929,1909],{},"Please check the ",[527,79924,79927],{"href":79925,"rel":79926},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fgameserver-scripts",[531],"galexrt\u002Fgameserver-scripts"," repository for the latest version of the script. In the directory of the repo in ",[567,79930,79931],{},"srcds-restarter\u002F",{"title":743,"searchDepth":761,"depth":761,"links":79933},[],"2016-04-30T15:41:02+02:00","SRCDS Server Restarter Script - Automatically restarts freezed\u002Fcrashed SRCDS servers. Using only a Perl script and a Cronjob.",{"tags":79937},[79938,79939,79940],"Perl","SRCDS Server","Gamserver","\u002Fblog\u002F2016\u002Fsrcds-server-restarter-script",{"title":79883,"description":79935},"3.blog\u002F2016\u002Fsrcds-server-restarter-script","2JAy_2VlSZz2Fryq25B-boKUfk024eDUKXvHJwSnA3E",{"id":79946,"title":79947,"authors":79948,"badge":518,"body":79951,"date":79971,"description":79972,"extension":2911,"image":79973,"meta":79974,"navigation":1254,"path":79976,"seo":79977,"stem":79978,"__hash__":79979},"posts\u002F3.blog\u002F2016\u002Fdocker-for-admins-workshop-recap-presentation.md","Docker for Admins Workshop Recap Presentation",[79949],{"name":514,"to":515,"avatar":79950},{"src":517},{"type":520,"value":79952,"toc":79969},[79953,79956,79958,79962,79964],[523,79954,79955],{},"I created the presentation after I held my Docker for Admins Workshop.\nThis presentation is just a small recap of the Workshop and as the Workshop is posted on my blog, I'm posting the presentation here too.",[523,79957,58352],{},[18903,79959],{"src":79960,"frameBorder":3579,"height":79961,"allowFullScreen":5306,"mozallowfullscreen":5306,"webkitallowfullscreen":5306},"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002F1c4922Wd4_TGGd-cS42ehgD2vI9x8peE1_t9O1pIxi4M\u002Fembed?start=false&loop=true&delayms=5000",569,[523,79963,79569],{},[523,79965,79966],{},[3049,79967,79968],{},"P.S. To everyone that already saw the presentation, I changed the design of it, because of the colors used in the first design.",{"title":743,"searchDepth":761,"depth":761,"links":79970},[],"2016-04-29T17:24:37+02:00","Docker for Admins Workshop Recap in one small presentation.",{"src":12171},{"tags":79975},[18918,12175,12174,12176],"\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-recap-presentation",{"title":79947,"description":79972},"3.blog\u002F2016\u002Fdocker-for-admins-workshop-recap-presentation","FegJCombhBfrJ6E9v39hf0x68psU5i_V-Scsi7pckJU",{"id":79981,"title":79982,"authors":79983,"badge":518,"body":79986,"date":86837,"description":86838,"extension":2911,"image":86839,"meta":86840,"navigation":1254,"path":86842,"seo":86843,"stem":86844,"__hash__":86845},"posts\u002F3.blog\u002F2016\u002Fdocker-for-admins-workshop-v2.md","Docker for Admins - Workshop v2",[79984],{"name":514,"to":515,"avatar":79985},{"src":517},{"type":520,"value":79987,"toc":86732},[79988,79991,80000,80002,80017,80020,80030,80034,80040,80045,80048,80052,80055,80057,80059,80063,80069,80076,80078,80080,80082,80090,80105,80107,80111,80113,80115,80117,80119,80123,80136,80138,80140,80142,80148,80150,80152,80165,80167,80185,80189,80193,80197,80203,80205,80207,80214,80217,80233,80241,80243,80245,80265,80267,80278,80280,80282,80288,80293,80303,80347,80354,80360,80366,80372,80374,80381,80386,80398,80404,80406,80408,80410,80412,80421,80435,80437,80439,80451,80457,80459,80461,80485,80489,80501,80511,80515,80540,80545,80547,80554,80572,80574,80578,80582,80607,80609,80611,80637,80668,80670,80674,80686,80688,80694,80696,80701,80722,80728,80788,80792,80798,80800,80806,80836,80874,80876,80878,80880,80955,80987,80997,80999,81001,81003,81015,81019,81021,81051,81067,81073,81079,81137,81155,81159,81171,81173,81179,81215,81249,81281,81283,81285,81292,81294,81340,81350,81516,81548,81553,81561,81571,81573,81579,81581,81583,81585,81587,81609,81619,81627,81629,81663,81687,81695,81705,81707,81709,81713,81715,81723,81727,81763,81815,81819,81832,81840,81846,81854,81856,81858,81860,81862,81864,81869,81872,81874,81897,81911,81922,81927,81929,81932,81940,81947,81949,81960,81962,81972,81980,81986,81997,82005,82007,82018,82020,82026,82060,82065,82073,82075,82077,82079,82087,82091,82093,82095,82183,82187,82189,82359,82361,82363,82367,82369,82371,82373,82375,82380,82382,82391,82411,82419,82431,82467,82472,82474,82479,82490,82492,82498,82502,82506,82508,82520,82524,82531,82703,82705,82712,82941,82946,82948,82971,82975,82979,82997,83001,83004,83008,83011,83015,83018,83022,83028,83032,83035,83041,83081,83088,83090,83092,83098,83112,83128,83130,83132,83152,83186,83190,83198,83204,83238,83240,83256,83267,83271,83309,83313,83325,83329,83347,83351,83361,83371,83405,83410,83418,83424,83482,83495,83497,83499,83505,83509,83511,83514,83516,83520,83522,83537,83541,83555,83788,83818,83825,83827,83838,83842,83856,83887,83895,83899,83905,83909,83917,83931,83947,83951,83959,83975,83993,83997,84001,84015,84029,84033,84061,84063,84067,84069,84071,84075,84078,84080,84086,84089,84091,84093,84119,84121,84125,84130,84133,84135,84140,84144,84147,84154,84157,84161,84164,84167,84177,84179,84181,84185,84189,84195,84204,84208,84211,84214,84216,84230,84234,84241,84245,84249,84253,84256,84272,84297,84299,84302,84322,84353,84357,84362,84376,84395,84397,84402,84416,84434,84438,84456,84482,84484,84490,84511,84544,84546,84552,84572,84600,84602,84606,84612,84631,84658,84662,84667,84679,84707,84709,84711,84716,84720,84725,84734,84743,84767,84771,84783,84789,84795,84922,84962,84969,84972,84976,85000,85010,85027,85030,85036,85039,85043,85052,85055,85057,85069,85075,85163,85168,85174,85194,85197,85203,85206,85209,85215,85218,85238,85246,85256,85260,85268,85292,85295,85299,85305,85329,85332,85339,85348,85352,85358,85361,85373,85376,85378,85382,85387,85389,85401,85404,85492,85525,85571,85598,85602,85606,85613,86245,86257,86259,86263,86267,86278,86292,86308,86314,86317,86321,86328,86342,86345,86349,86366,86369,86372,86376,86383,86387,86394,86403,86407,86410,86413,86415,86417,86420,86422,86426,86428,86463,86467,86729],[79989,79990,2930],"h1",{"id":2929},[523,79992,2933,79993,79995,79996,79999],{},[567,79994,2936],{},".\nThe last part is about the container orchestration tool Kubernetes by Google. As part of this you are going to create a ",[527,79997,124],{"href":3033,"rel":79998},[531]," cluster and you take a look at the internal services of Kubernetes and deploy applications on top of it.",[79989,80001,39306],{"id":39305},[668,80003,80004,80009,80013],{},[638,80005,80006,39314],{},[584,80007,80008],{},"Grey Boxes with green line on the left",[638,80010,80011,2952],{},[584,80012,2951],{},[638,80014,80015,2958],{},[584,80016,2957],{},[79989,80018,80019],{"id":2967},"Group Partition Schema",[523,80021,80022,80023,80026,80027,2977],{},"Two groups ore more should be good. Per group at least two or more people.\nEvery group works on their own ",[527,80024,124],{"href":3033,"rel":80025},[531]," cluster.\nIf there are people that aren't as \"advanced\", they can play around with ",[527,80028,2976],{"href":2974,"rel":80029},[531],[79989,80031,80033],{"id":80032},"special-details","Special details",[523,80035,80036,80037,80039],{},"A prepared VirtualBox Image will be given around on an USB stick, during the preparation of the workshop.\nThe VM Username is ",[567,80038,32148],{}," and so is the password.",[535,80041,80042],{"id":39343},[527,80043,39348],{"href":39346,"rel":80044},[531],[523,80046,80047],{},"Fedora 23 with Docker and Cockpit enabled.\nCockpit is enabled, so I can simply help and also monitor the VMs, if a problem occurs.\nFirewalld removed, Iptables cleared and persistence disabled.",[613,80049,80051],{"id":80050},"why-is-the-vm-running-fedora","Why is the VM running Fedora?",[523,80053,80054],{},"That's simple, instead of, e.g., Debian, Ubuntu or CentOS? Fedora is more up to date. Not like Debian",[2979,80056],{},[79989,80058,2984],{"id":2983},[523,80060,80061],{},[584,80062,39296],{},[523,80064,2995,80065,80068],{},[567,80066,80067],{},"to the command, to get a help page that should guide you to your goal or use"," to show the man(ual) page for the given command. If you can't solve your problem feel free to ask me.",[6072,80070,80071],{},[523,80072,80073,80074],{},"There are no dumb questions, but please don't ask them. Okay?\n-- ",[3049,80075,514],{},[2979,80077],{},[79989,80079,3009],{"id":3008},[535,80081,3013],{"id":3012},[523,80083,3016,80084,3019,80086,3023,80088,3027],{},[567,80085,2936],{},[584,80087,3022],{},[584,80089,3026],{},[523,80091,3030,80092,714,80095,714,80100,30141],{},[527,80093,124],{"href":3033,"rel":80094},[531],[527,80096,80099],{"href":80097,"rel":80098},"https:\u002F\u002Fclusterhq.com\u002Fflocker\u002Fintroduction\u002F",[531],"Flocker",[527,80101,80104],{"href":80102,"rel":80103},"https:\u002F\u002Fwww.weave.works\u002F",[531],"Weave",[535,80106,3044],{"id":3043},[523,80108,3047,80109,3052],{},[3049,80110,3051],{},[535,80112,3056],{"id":3055},[523,80114,39461],{},[523,80116,3062],{},[523,80118,3065],{},[523,80120,80121],{},[3069,80122],{"alt":3071,"src":3072},[523,80124,80125],{},[3049,80126,80127,80128,80131,80132,80135],{},"This photo ([original](",[527,80129,3080],{"href":3080,"rel":80130},[531],")) is made by Shmuel Csaba Otto Traian, licensed under the [CC Attribution-Share Alike 3.0 Unported](",[527,80133,3086],{"href":3086,"rel":80134},[531],") license.",[523,80137,3092],{},[523,80139,3095],{},[523,80141,3098],{},[6072,80143,80144],{},[523,80145,80146,3104],{},[584,80147,3103],{},[2979,80149],{},[79989,80151,3110],{"id":3109},[6072,80153,80154],{},[523,80155,80156,8287,80158],{},[584,80157,2951],{},[527,80159,80162],{"href":80160,"rel":80161},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-docker\u002Ftree\u002Fmaster\u002Fsetup101",[531],[567,80163,80164],{},"setup101",[535,80166,39515],{"id":39514},[668,80168,80169,80172,80179],{},[638,80170,80171],{},"You can install Docker directly on your system or in a VirtualBox. If you use a VirtualBox, please consider using Fedora 23 or anyother linux distro with at least kernel 4.x.",[638,80173,80174,80175,80178],{},"If you are a Windows or Mac OSX user, ask yourself \"What have I done wrong, to use such shitty plattform?\", switch to linux m8, thanks! You can use ",[527,80176,39528],{"href":39526,"rel":80177},[531]," (I don't help or give any support if you use it though!).",[638,80180,80181,80182,1909],{},"The download and login details to the VM are located ",[527,80183,3396],{"href":80184},"#special-details",[535,80186,80188],{"id":80187},"system-requirements","System \"Requirements\"",[523,80190,80191],{},[3049,80192,3119],{},[523,80194,80195],{},[584,80196,3124],{},[668,80198,80199,80201],{},[638,80200,3134],{},[638,80202,3137],{},[523,80204,3140],{},[535,80206,3145],{"id":3144},[6072,80208,80209],{},[523,80210,80211],{},[584,80212,80213],{},"If you use the workshop VM, you can skip this section.",[523,80215,80216],{},"To install the Docker Engine run the command:",[738,80218,80219],{"className":1621,"code":3155,"language":1623,"meta":743,"style":743},[567,80220,80221],{"__ignoreMap":743},[747,80222,80223,80225,80227,80229,80231],{"class":749,"line":750},[747,80224,3151],{"class":1630},[747,80226,3164],{"class":802},[747,80228,3167],{"class":802},[747,80230,3170],{"class":757},[747,80232,3173],{"class":1630},[523,80234,3176,80235,3182,80238,1909],{},[527,80236,3181],{"href":3179,"rel":80237},[531],[527,80239,3181],{"href":3185,"rel":80240},[531],[523,80242,3189],{},[523,80244,3192],{},[738,80246,80247],{"className":1621,"code":3195,"language":1623,"meta":743,"style":743},[567,80248,80249,80257],{"__ignoreMap":743},[747,80250,80251,80253,80255],{"class":749,"line":750},[747,80252,3202],{"class":1630},[747,80254,3205],{"class":802},[747,80256,3208],{"class":802},[747,80258,80259,80261,80263],{"class":749,"line":761},[747,80260,3202],{"class":1630},[747,80262,3215],{"class":802},[747,80264,3208],{"class":802},[523,80266,3220],{},[738,80268,80270],{"className":1621,"code":80269,"language":1623,"meta":743,"style":743},"\u002Fetc\u002Finit.d\u002Fdocker start\n",[567,80271,80272],{"__ignoreMap":743},[747,80273,80274,80276],{"class":749,"line":750},[747,80275,3230],{"class":1630},[747,80277,3233],{"class":802},[523,80279,3251],{},[535,80281,3294],{"id":3293},[6072,80283,80284],{},[523,80285,80286],{},[584,80287,80213],{},[523,80289,80290,80292],{},[3069,80291],{"alt":3299,"src":3300},"\n_`docker-compose` Logo by Docker_",[523,80294,40165,80295,3316,80297,3319,80299,3323,80301,3327],{},[567,80296,2936],{},[567,80298,2936],{},[567,80300,3322],{},[567,80302,3326],{},[738,80304,80305],{"className":1621,"code":3330,"language":1623,"meta":743,"style":743},[567,80306,80307,80337],{"__ignoreMap":743},[747,80308,80309,80311,80313,80315,80317,80319,80321,80323,80325,80327,80329,80331,80333,80335],{"class":749,"line":750},[747,80310,3337],{"class":1630},[747,80312,3340],{"class":802},[747,80314,3343],{"class":802},[747,80316,969],{"class":757},[747,80318,3348],{"class":802},[747,80320,3351],{"class":757},[747,80322,3354],{"class":1630},[747,80324,2598],{"class":802},[747,80326,3351],{"class":757},[747,80328,3361],{"class":802},[747,80330,3351],{"class":757},[747,80332,3354],{"class":1630},[747,80334,3368],{"class":802},[747,80336,3371],{"class":757},[747,80338,80339,80341,80343,80345],{"class":749,"line":761},[747,80340,3376],{"class":1630},[747,80342,3379],{"class":802},[747,80344,3382],{"class":802},[747,80346,3385],{"class":802},[523,80348,3388,80349,3391,80351,1909],{},[567,80350,2936],{},[527,80352,3396],{"href":3394,"rel":80353},[531],[523,80355,3399,80356,3402,80358,1909],{},[567,80357,2936],{},[567,80359,3405],{},[523,80361,80362,80363,80365],{},"The recording below shows the expected output for the ",[567,80364,2936],{}," installation and the installation test.",[6072,80367,80368],{},[523,80369,80370],{},[584,80371,3521],{},[535,80373,3487],{"id":3486},[6072,80375,80376],{},[523,80377,80378],{},[584,80379,80380],{},"If you use the workshop VM, you can skip these steps.",[523,80382,80383,80384,3494],{},"Clone the Workshop repo from GitHub ",[567,80385,3493],{},[738,80387,80388],{"className":1621,"code":3497,"language":1623,"meta":743,"style":743},[567,80389,80390],{"__ignoreMap":743},[747,80391,80392,80394,80396],{"class":749,"line":750},[747,80393,221],{"class":1630},[747,80395,3506],{"class":802},[747,80397,3509],{"class":802},[6072,80399,80400],{},[523,80401,80402],{},[584,80403,3521],{},[2979,80405],{},[79989,80407,3643],{"id":3642},[523,80409,3646],{},[535,80411,3650],{"id":3649},[523,80413,80414,80415,3258,80417,3261,80419,40124],{},"When you have Docker installed correctly, you now have to add your user to the ",[567,80416,3257],{},[567,80418,3257],{},[567,80420,3257],{},[738,80422,80423],{"className":1621,"code":40127,"language":1623,"meta":743,"style":743},[567,80424,80425],{"__ignoreMap":743},[747,80426,80427,80429,80431,80433],{"class":749,"line":750},[747,80428,3278],{"class":1630},[747,80430,3281],{"class":802},[747,80432,40138],{"class":1640},[747,80434,40141],{"class":802},[523,80436,3290],{},[523,80438,3653],{},[738,80440,80441],{"className":1621,"code":3656,"language":1623,"meta":743,"style":743},[567,80442,80443],{"__ignoreMap":743},[747,80444,80445,80447,80449],{"class":749,"line":750},[747,80446,3257],{"class":1630},[747,80448,3665],{"class":802},[747,80450,3668],{"class":802},[6072,80452,80453],{},[523,80454,80455],{},[584,80456,3673],{},[523,80458,4149],{},[535,80460,4153],{"id":4152},[668,80462,80463,80471,80479],{},[638,80464,80465,4161,80467,4165,80469,4169],{},[567,80466,4160],{},[567,80468,4164],{},[567,80470,4168],{},[638,80472,80473,4181,80475,4185,80477,4189],{},[567,80474,4180],{},[567,80476,4184],{},[567,80478,4188],{},[638,80480,80481,4195,80483,4189],{},[567,80482,4194],{},[567,80484,4188],{},[523,80486,4200,80487,4204],{},[567,80488,4203],{},[738,80490,80491],{"className":1621,"code":4207,"language":1623,"meta":743,"style":743},[567,80492,80493],{"__ignoreMap":743},[747,80494,80495,80497,80499],{"class":749,"line":750},[747,80496,3257],{"class":1630},[747,80498,3665],{"class":802},[747,80500,4218],{"class":802},[6072,80502,80503],{},[523,80504,80505,80507],{},[584,80506,3521],{},[3069,80508],{"alt":80509,"src":80510},"docker run --help Output","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Fdocker-run-help.png",[523,80512,5630,80513,5633],{},[567,80514,4203],{},[6072,80516,80517,80525],{},[523,80518,80519,80523],{},[3069,80520],{"alt":80521,"src":80522},"Docker run syntax","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Fdocker-run-syntax.png",[584,80524,2957],{},[668,80526,80527,80531,80535],{},[638,80528,80529,5699],{},[567,80530,5698],{},[638,80532,80533,5705],{},[567,80534,5704],{},[638,80536,80537,80539],{},[567,80538,5710],{}," - Depending on the images, used as arguments or as the command by the entrypoint.",[523,80541,5719,80542,3052],{},[527,80543,3396],{"href":80544},"#Understanding-Dockerfiles",[535,80546,5726],{"id":5725},[523,80548,5729,80549,5735,80552,5738],{},[527,80550,5734],{"href":5732,"rel":80551},[531],[567,80553,5704],{},[738,80555,80557],{"className":1621,"code":80556,"language":1623,"meta":743,"style":743},"docker run \\\n    sameersbn\u002Fmysql:latest\n",[567,80558,80559,80567],{"__ignoreMap":743},[747,80560,80561,80563,80565],{"class":749,"line":750},[747,80562,3257],{"class":1630},[747,80564,3665],{"class":802},[747,80566,1641],{"class":1640},[747,80568,80569],{"class":749,"line":761},[747,80570,80571],{"class":802},"    sameersbn\u002Fmysql:latest\n",[613,80573,5760],{"id":5759},[523,80575,80576],{},[3049,80577,5765],{},[523,80579,5768,80580,5772],{},[567,80581,5771],{},[738,80583,80585],{"className":1621,"code":80584,"language":1623,"meta":743,"style":743},"docker run \\\n    --name mysql \\\n    sameersbn\u002Fmysql:latest\n",[567,80586,80587,80595,80603],{"__ignoreMap":743},[747,80588,80589,80591,80593],{"class":749,"line":750},[747,80590,3257],{"class":1630},[747,80592,3665],{"class":802},[747,80594,1641],{"class":1640},[747,80596,80597,80599,80601],{"class":749,"line":761},[747,80598,5790],{"class":802},[747,80600,5793],{"class":802},[747,80602,1641],{"class":1640},[747,80604,80605],{"class":749,"line":769},[747,80606,80571],{"class":802},[523,80608,5802],{},[613,80610,5806],{"id":5805},[523,80612,5809,80613,587,80615,5816,80617,5820,80619,587,80621,5827,80623,5830,80625,587,80627,5835,80629,5838,80631,5842,80633,5845,80635,5848],{},[567,80614,5812],{},[567,80616,5815],{},[567,80618,5819],{},[567,80620,5823],{},[567,80622,5826],{},[567,80624,5815],{},[567,80626,5823],{},[567,80628,5826],{},[567,80630,5812],{},[567,80632,5841],{},[567,80634,5812],{},[567,80636,5841],{},[738,80638,80640],{"className":1621,"code":80639,"language":1623,"meta":743,"style":743},"docker run \\\n    -d \\\n    --name mysql \\\n    sameersbn\u002Fmysql:latest\n",[567,80641,80642,80650,80656,80664],{"__ignoreMap":743},[747,80643,80644,80646,80648],{"class":749,"line":750},[747,80645,3257],{"class":1630},[747,80647,3665],{"class":802},[747,80649,1641],{"class":1640},[747,80651,80652,80654],{"class":749,"line":761},[747,80653,5866],{"class":802},[747,80655,1641],{"class":1640},[747,80657,80658,80660,80662],{"class":749,"line":769},[747,80659,5790],{"class":802},[747,80661,5793],{"class":802},[747,80663,1641],{"class":1640},[747,80665,80666],{"class":749,"line":776},[747,80667,80571],{"class":802},[523,80669,5883],{},[523,80671,5886,80672,5890],{},[567,80673,5889],{},[738,80675,80676],{"className":1621,"code":5893,"language":1623,"meta":743,"style":743},[567,80677,80678],{"__ignoreMap":743},[747,80679,80680,80682,80684],{"class":749,"line":750},[747,80681,3257],{"class":1630},[747,80683,5902],{"class":802},[747,80685,5905],{"class":802},[613,80687,5909],{"id":5908},[523,80689,5912,80690,5915,80692,43588],{},[584,80691,3022],{},[584,80693,3026],{},[523,80695,5921],{},[523,80697,5924,80698,5928],{},[567,80699,80700],{},"sameersbn\u002Fmysql:latest",[668,80702,80703,80711,80716],{},[638,80704,80705,5945,80708,1909],{},[567,80706,80707],{},"DB_USER",[567,80709,80710],{},"DB_NAME",[638,80712,80713,5953],{},[567,80714,80715],{},"DB_PASS",[638,80717,80718,5936,80720,1909],{},[567,80719,80710],{},[567,80721,80707],{},[523,80723,5956,80724,5845,80726,5963],{},[567,80725,5959],{},[567,80727,5962],{},[738,80729,80731],{"className":1621,"code":80730,"language":1623,"meta":743,"style":743},"docker run \\\n[...]\n    -e 'DB_USER=wordpress' \\\n    -e 'DB_PASS=wordpress' \\\n    -e 'DB_NAME=wordpress' \\\n[...]\n",[567,80732,80733,80741,80745,80758,80771,80784],{"__ignoreMap":743},[747,80734,80735,80737,80739],{"class":749,"line":750},[747,80736,3257],{"class":1630},[747,80738,3665],{"class":802},[747,80740,1641],{"class":1640},[747,80742,80743],{"class":749,"line":761},[747,80744,5986],{"class":1640},[747,80746,80747,80749,80751,80754,80756],{"class":749,"line":769},[747,80748,5991],{"class":1630},[747,80750,3537],{"class":757},[747,80752,80753],{"class":802},"DB_USER=wordpress",[747,80755,3543],{"class":757},[747,80757,1641],{"class":1640},[747,80759,80760,80762,80764,80767,80769],{"class":749,"line":776},[747,80761,5991],{"class":802},[747,80763,3537],{"class":757},[747,80765,80766],{"class":802},"DB_PASS=wordpress",[747,80768,3543],{"class":757},[747,80770,1641],{"class":1640},[747,80772,80773,80775,80777,80780,80782],{"class":749,"line":784},[747,80774,5991],{"class":802},[747,80776,3537],{"class":757},[747,80778,80779],{"class":802},"DB_NAME=wordpress",[747,80781,3543],{"class":757},[747,80783,1641],{"class":1640},[747,80785,80786],{"class":749,"line":790},[747,80787,5986],{"class":1640},[523,80789,80790],{},[3049,80791,6035],{},[6072,80793,80794],{},[523,80795,6040,80796,6044],{},[567,80797,6043],{},[613,80799,6107],{"id":6106},[523,80801,6110,80802,5845,80804,6117],{},[567,80803,6113],{},[567,80805,6116],{},[738,80807,80808],{"className":1621,"code":6120,"language":1623,"meta":743,"style":743},[567,80809,80810,80818,80822,80828],{"__ignoreMap":743},[747,80811,80812,80814,80816],{"class":749,"line":750},[747,80813,3257],{"class":1630},[747,80815,3665],{"class":802},[747,80817,1641],{"class":1640},[747,80819,80820],{"class":749,"line":761},[747,80821,5986],{"class":1640},[747,80823,80824,80826],{"class":749,"line":769},[747,80825,6139],{"class":1630},[747,80827,6142],{"class":802},[747,80829,80830,80832,80834],{"class":749,"line":776},[747,80831,4253],{"class":757},[747,80833,5685],{"class":1640},[747,80835,4268],{"class":757},[6072,80837,80838,80842,80862,80866],{},[523,80839,80840],{},[584,80841,2957],{},[668,80843,80844,80848,80852],{},[638,80845,80846,6162],{},[567,80847,6161],{},[638,80849,80850,6168],{},[567,80851,6167],{},[638,80853,80854,6174,80856,6178,80858,6182,80860,1909],{},[567,80855,6173],{},[567,80857,6177],{},[567,80859,6181],{},[567,80861,6177],{},[523,80863,80864],{},[584,80865,6189],{},[668,80867,80868,80870,80872],{},[638,80869,6194],{},[638,80871,6197],{},[638,80873,6200],{},[613,80875,6204],{"id":6203},[523,80877,6207],{},[523,80879,6210],{},[738,80881,80883],{"className":1621,"code":80882,"language":1623,"meta":743,"style":743},"docker run \\\n    -d \\\n    --name mysql \\\n    -e 'DB_USER=wordpress' \\\n    -e 'DB_PASS=wordpress' \\\n    -e 'DB_NAME=wordpress' \\\n    -v \u002Fopt\u002Fdocker\u002Fwordpress\u002Fmysql:\u002Fvar\u002Flib\u002Fmysql \\\n    sameersbn\u002Fmysql:latest\n",[567,80884,80885,80893,80899,80907,80919,80931,80943,80951],{"__ignoreMap":743},[747,80886,80887,80889,80891],{"class":749,"line":750},[747,80888,3257],{"class":1630},[747,80890,3665],{"class":802},[747,80892,1641],{"class":1640},[747,80894,80895,80897],{"class":749,"line":761},[747,80896,5866],{"class":802},[747,80898,1641],{"class":1640},[747,80900,80901,80903,80905],{"class":749,"line":769},[747,80902,5790],{"class":802},[747,80904,5793],{"class":802},[747,80906,1641],{"class":1640},[747,80908,80909,80911,80913,80915,80917],{"class":749,"line":776},[747,80910,5991],{"class":802},[747,80912,3537],{"class":757},[747,80914,80753],{"class":802},[747,80916,3543],{"class":757},[747,80918,1641],{"class":1640},[747,80920,80921,80923,80925,80927,80929],{"class":749,"line":784},[747,80922,5991],{"class":802},[747,80924,3537],{"class":757},[747,80926,80766],{"class":802},[747,80928,3543],{"class":757},[747,80930,1641],{"class":1640},[747,80932,80933,80935,80937,80939,80941],{"class":749,"line":790},[747,80934,5991],{"class":802},[747,80936,3537],{"class":757},[747,80938,80779],{"class":802},[747,80940,3543],{"class":757},[747,80942,1641],{"class":1640},[747,80944,80945,80947,80949],{"class":749,"line":796},[747,80946,6139],{"class":802},[747,80948,6293],{"class":802},[747,80950,1641],{"class":1640},[747,80952,80953],{"class":749,"line":806},[747,80954,80571],{"class":802},[6072,80956,80957,80961],{},[523,80958,80959],{},[584,80960,2957],{},[668,80962,80963,80967,80971,80975,80983],{},[638,80964,80965,6310],{},[567,80966,5841],{},[638,80968,80969,6316],{},[567,80970,6315],{},[638,80972,80973,6322],{},[567,80974,6321],{},[638,80976,80977,6328,80979,6332,80981,6336],{},[567,80978,6327],{},[567,80980,6331],{},[567,80982,6335],{},[638,80984,80985,6341],{},[567,80986,80700],{},[523,80988,6344,80989,5845,80991,6349,80993,6353,80995,6356],{},[567,80990,5812],{},[567,80992,5841],{},[567,80994,6352],{},[567,80996,4188],{},[535,80998,6360],{"id":6359},[523,81000,6363],{},[613,81002,6367],{"id":6366},[523,81004,6370,81005,6374,81007,6378,81009,6382,81011,6353,81013,6389],{},[567,81006,6373],{},[567,81008,6377],{},[567,81010,6381],{},[567,81012,6385],{},[567,81014,6388],{},[523,81016,6392,81017,6396],{},[567,81018,6395],{},[523,81020,6399],{},[738,81022,81023],{"className":1621,"code":6402,"language":1623,"meta":743,"style":743},[567,81024,81025,81033,81037,81047],{"__ignoreMap":743},[747,81026,81027,81029,81031],{"class":749,"line":750},[747,81028,3257],{"class":1630},[747,81030,3665],{"class":802},[747,81032,1641],{"class":1640},[747,81034,81035],{"class":749,"line":761},[747,81036,6417],{"class":1640},[747,81038,81039,81041,81043,81045],{"class":749,"line":769},[747,81040,6422],{"class":1640},[747,81042,6425],{"class":757},[747,81044,6428],{"class":802},[747,81046,1641],{"class":1630},[747,81048,81049],{"class":749,"line":776},[747,81050,6435],{"class":1640},[6072,81052,81053,81057],{},[523,81054,81055],{},[584,81056,2957],{},[668,81058,81059,81063],{},[638,81060,81061,6447],{},[567,81062,6446],{},[638,81064,81065,6453],{},[567,81066,6452],{},[523,81068,6456,81069,6460,81071,1909],{},[567,81070,6459],{},[567,81072,6463],{},[523,81074,6466,81075,6469,81077,6472],{},[567,81076,6459],{},[567,81078,6459],{},[738,81080,81081],{"className":1621,"code":6475,"language":1623,"meta":743,"style":743},[567,81082,81083,81091,81097,81103,81109,81113,81119,81123,81129],{"__ignoreMap":743},[747,81084,81085,81087,81089],{"class":749,"line":750},[747,81086,3257],{"class":1630},[747,81088,3665],{"class":802},[747,81090,1641],{"class":1640},[747,81092,81093,81095],{"class":749,"line":761},[747,81094,5866],{"class":802},[747,81096,1641],{"class":1640},[747,81098,81099,81101],{"class":749,"line":769},[747,81100,6496],{"class":802},[747,81102,1641],{"class":1640},[747,81104,81105,81107],{"class":749,"line":776},[747,81106,6503],{"class":802},[747,81108,1641],{"class":1640},[747,81110,81111],{"class":749,"line":784},[747,81112,6510],{"class":802},[747,81114,81115,81117],{"class":749,"line":790},[747,81116,6515],{"class":1630},[747,81118,6518],{"class":802},[747,81120,81121],{"class":749,"line":796},[747,81122,6523],{"class":1630},[747,81124,81125,81127],{"class":749,"line":806},[747,81126,6528],{"class":4574},[747,81128,6531],{"class":772},[747,81130,81131,81133,81135],{"class":749,"line":814},[747,81132,3257],{"class":1630},[747,81134,5902],{"class":802},[747,81136,6540],{"class":802},[6072,81138,81139,81143,81149,81153],{},[523,81140,81141],{},[584,81142,2957],{},[668,81144,81145],{},[638,81146,81147,6552],{},[567,81148,6551],{},[523,81150,81151],{},[584,81152,3521],{},[523,81154,6559],{},[523,81156,6562,81157,6566],{},[567,81158,6565],{},[6072,81160,81161,81165],{},[523,81162,81163],{},[584,81164,6189],{},[668,81166,81167,81169],{},[638,81168,6575],{},[638,81170,6578],{},[613,81172,6582],{"id":6581},[523,81174,6585,81175,5845,81177,6592],{},[567,81176,6588],{},[567,81178,6591],{},[738,81180,81181],{"className":1621,"code":6595,"language":1623,"meta":743,"style":743},[567,81182,81183,81191,81195,81201],{"__ignoreMap":743},[747,81184,81185,81187,81189],{"class":749,"line":750},[747,81186,3257],{"class":1630},[747,81188,3665],{"class":802},[747,81190,1641],{"class":1640},[747,81192,81193],{"class":749,"line":761},[747,81194,6417],{"class":1640},[747,81196,81197,81199],{"class":749,"line":769},[747,81198,6614],{"class":1630},[747,81200,6617],{"class":802},[747,81202,81203,81205,81207,81209,81211,81213],{"class":749,"line":776},[747,81204,4253],{"class":757},[747,81206,5704],{"class":1640},[747,81208,4259],{"class":757},[747,81210,4262],{"class":757},[747,81212,6630],{"class":1640},[747,81214,4268],{"class":757},[738,81216,81217],{"className":1621,"code":6635,"language":1623,"meta":743,"style":743},[567,81218,81219,81227,81231,81239],{"__ignoreMap":743},[747,81220,81221,81223,81225],{"class":749,"line":750},[747,81222,3257],{"class":1630},[747,81224,3665],{"class":802},[747,81226,1641],{"class":1640},[747,81228,81229],{"class":749,"line":761},[747,81230,6650],{"class":1640},[747,81232,81233,81235,81237],{"class":749,"line":769},[747,81234,6614],{"class":1630},[747,81236,6657],{"class":802},[747,81238,1641],{"class":1640},[747,81240,81241,81243,81245,81247],{"class":749,"line":776},[747,81242,6664],{"class":1640},[747,81244,4253],{"class":757},[747,81246,6630],{"class":1640},[747,81248,4268],{"class":757},[6072,81250,81251,81255],{},[523,81252,81253],{},[584,81254,2957],{},[668,81256,81257,81263,81267,81271],{},[638,81258,81259,6682,81261,6686],{},[567,81260,6681],{},[567,81262,6685],{},[638,81264,81265,6692],{},[567,81266,6691],{},[638,81268,81269,6698],{},[567,81270,6697],{},[638,81272,81273,6682,81275,6707,81277,6374,81279,1909],{},[567,81274,6703],{},[567,81276,6706],{},[567,81278,6706],{},[567,81280,6712],{},[523,81282,6715],{},[613,81284,6719],{"id":6718},[523,81286,6722,81287,6378,81289,2006],{},[567,81288,6725],{},[527,81290,6730],{"href":6728,"rel":81291},[531],[523,81293,6733],{},[668,81295,81296,81302,81306,81314,81318,81324],{},[638,81297,81298,6741,81300,1909],{},[567,81299,6740],{},[567,81301,6744],{},[638,81303,81304,6750],{},[567,81305,6749],{},[638,81307,81308,6756,81310,6759,81312,1909],{},[567,81309,6755],{},[567,81311,6069],{},[567,81313,6744],{},[638,81315,81316,6767],{},[567,81317,6766],{},[638,81319,81320,6773,81322,1909],{},[567,81321,6772],{},[567,81323,6776],{},[638,81325,81326,714,81328,714,81330,714,81332,714,81334,714,81336,714,81338,6800],{},[567,81327,6781],{},[567,81329,6784],{},[567,81331,6787],{},[567,81333,6790],{},[567,81335,6793],{},[567,81337,6796],{},[567,81339,6799],{},[523,81341,6803,81342,6807,81344,6810,81346,710,81348,6816],{},[567,81343,6806],{},[567,81345,4203],{},[567,81347,6806],{},[567,81349,6815],{},[738,81351,81352],{"className":1621,"code":6819,"language":1623,"meta":743,"style":743},[567,81353,81354,81362,81368,81376,81388,81400,81412,81424,81436,81448,81460,81472,81484,81496,81504,81512],{"__ignoreMap":743},[747,81355,81356,81358,81360],{"class":749,"line":750},[747,81357,3257],{"class":1630},[747,81359,3665],{"class":802},[747,81361,1641],{"class":1640},[747,81363,81364,81366],{"class":749,"line":761},[747,81365,5866],{"class":802},[747,81367,1641],{"class":1640},[747,81369,81370,81372,81374],{"class":749,"line":769},[747,81371,5790],{"class":802},[747,81373,6842],{"class":802},[747,81375,1641],{"class":1640},[747,81377,81378,81380,81382,81384,81386],{"class":749,"line":776},[747,81379,5991],{"class":802},[747,81381,3537],{"class":757},[747,81383,6853],{"class":802},[747,81385,3543],{"class":757},[747,81387,1641],{"class":1640},[747,81389,81390,81392,81394,81396,81398],{"class":749,"line":784},[747,81391,5991],{"class":802},[747,81393,3537],{"class":757},[747,81395,6866],{"class":802},[747,81397,3543],{"class":757},[747,81399,1641],{"class":1640},[747,81401,81402,81404,81406,81408,81410],{"class":749,"line":790},[747,81403,5991],{"class":802},[747,81405,3537],{"class":757},[747,81407,6879],{"class":802},[747,81409,3543],{"class":757},[747,81411,1641],{"class":1640},[747,81413,81414,81416,81418,81420,81422],{"class":749,"line":796},[747,81415,5991],{"class":802},[747,81417,3537],{"class":757},[747,81419,6892],{"class":802},[747,81421,3543],{"class":757},[747,81423,1641],{"class":1640},[747,81425,81426,81428,81430,81432,81434],{"class":749,"line":806},[747,81427,5991],{"class":802},[747,81429,3537],{"class":757},[747,81431,6905],{"class":802},[747,81433,3543],{"class":757},[747,81435,1641],{"class":1640},[747,81437,81438,81440,81442,81444,81446],{"class":749,"line":814},[747,81439,5991],{"class":802},[747,81441,3537],{"class":757},[747,81443,6918],{"class":802},[747,81445,3543],{"class":757},[747,81447,1641],{"class":1640},[747,81449,81450,81452,81454,81456,81458],{"class":749,"line":822},[747,81451,5991],{"class":802},[747,81453,3537],{"class":757},[747,81455,6931],{"class":802},[747,81457,3543],{"class":757},[747,81459,1641],{"class":1640},[747,81461,81462,81464,81466,81468,81470],{"class":749,"line":830},[747,81463,5991],{"class":802},[747,81465,3537],{"class":757},[747,81467,6944],{"class":802},[747,81469,3543],{"class":757},[747,81471,1641],{"class":1640},[747,81473,81474,81476,81478,81480,81482],{"class":749,"line":836},[747,81475,5991],{"class":802},[747,81477,3537],{"class":757},[747,81479,6957],{"class":802},[747,81481,3543],{"class":757},[747,81483,1641],{"class":1640},[747,81485,81486,81488,81490,81492,81494],{"class":749,"line":842},[747,81487,5991],{"class":802},[747,81489,3537],{"class":757},[747,81491,6970],{"class":802},[747,81493,3543],{"class":757},[747,81495,1641],{"class":1640},[747,81497,81498,81500,81502],{"class":749,"line":850},[747,81499,6422],{"class":802},[747,81501,6981],{"class":802},[747,81503,1641],{"class":1640},[747,81505,81506,81508,81510],{"class":749,"line":863},[747,81507,6614],{"class":802},[747,81509,6990],{"class":802},[747,81511,1641],{"class":1640},[747,81513,81514],{"class":749,"line":869},[747,81515,6510],{"class":802},[6072,81517,81518,81522],{},[523,81519,81520],{},[584,81521,2957],{},[668,81523,81524,81528,81532,81536,81544],{},[638,81525,81526,6310],{},[567,81527,5841],{},[638,81529,81530,6316],{},[567,81531,6315],{},[638,81533,81534,6322],{},[567,81535,6321],{},[638,81537,81538,7020,81540,7023,81542,7026],{},[567,81539,7019],{},[567,81541,6744],{},[567,81543,6815],{},[638,81545,81546,6341],{},[567,81547,6725],{},[523,81549,7033,81550,1909],{},[527,81551,7036],{"href":7036,"rel":81552},[531],[6072,81554,81555,81559],{},[523,81556,81557],{},[584,81558,6189],{},[523,81560,7044],{},[523,81562,7047,81563,6353,81565,7052,81567,7055,81569,7058],{},[567,81564,4180],{},[567,81566,4188],{},[567,81568,6725],{},[567,81570,4194],{},[2979,81572],{},[6072,81574,81575],{},[523,81576,81577],{},[584,81578,7065],{},[2979,81580],{},[79989,81582,7071],{"id":7070},[523,81584,7074],{},[523,81586,7077],{},[738,81588,81589],{"className":1621,"code":7080,"language":1623,"meta":743,"style":743},[567,81590,81591],{"__ignoreMap":743},[747,81592,81593,81595,81597,81599,81601,81603,81605,81607],{"class":749,"line":750},[747,81594,6744],{"class":1630},[747,81596,7089],{"class":802},[747,81598,5149],{"class":802},[747,81600,7094],{"class":802},[747,81602,7097],{"class":802},[747,81604,969],{"class":757},[747,81606,7102],{"class":802},[747,81608,975],{"class":757},[523,81610,7107,81611,7111,81613,7114,81615,7117,81617,7121],{},[567,81612,7110],{},[567,81614,7110],{},[567,81616,4203],{},[567,81618,7120],{},[6072,81620,81621],{},[523,81622,81623,81625],{},[584,81624,3521],{},[3069,81626],{"alt":7130,"src":7131},[523,81628,7134],{},[738,81630,81631],{"className":1621,"code":7137,"language":1623,"meta":743,"style":743},[567,81632,81633,81641,81647,81653],{"__ignoreMap":743},[747,81634,81635,81637,81639],{"class":749,"line":750},[747,81636,3257],{"class":1630},[747,81638,2586],{"class":802},[747,81640,1641],{"class":1640},[747,81642,81643,81645],{"class":749,"line":761},[747,81644,7152],{"class":802},[747,81646,1641],{"class":1640},[747,81648,81649,81651],{"class":749,"line":769},[747,81650,7159],{"class":802},[747,81652,1641],{"class":1640},[747,81654,81655,81657,81659,81661],{"class":749,"line":776},[747,81656,7166],{"class":802},[747,81658,7089],{"class":802},[747,81660,5149],{"class":802},[747,81662,7173],{"class":802},[6072,81664,81665,81669],{},[523,81666,81667],{},[584,81668,2957],{},[668,81670,81671,81675,81679,81683],{},[638,81672,81673,7185],{},[567,81674,7184],{},[638,81676,81677,7191],{},[567,81678,7190],{},[638,81680,81681,7196],{},[567,81682,4188],{},[638,81684,81685,7202],{},[567,81686,7201],{},[523,81688,7205,81689,5845,81691,7210,81693,3052],{},[567,81690,5812],{},[567,81692,5841],{},[3049,81694,7213],{},[6072,81696,81697,81701],{},[523,81698,81699],{},[584,81700,6189],{},[668,81702,81703],{},[638,81704,7222],{},[2979,81706],{},[79989,81708,7228],{"id":7227},[523,81710,81711],{},[3049,81712,7233],{},[535,81714,45903],{"id":45902},[523,81716,7240,81717,7244,81719,7248,81721,7251],{},[567,81718,7243],{},[567,81720,7247],{},[567,81722,4203],{},[523,81724,7254,81725,7258],{},[567,81726,7257],{},[738,81728,81729],{"className":1621,"code":7261,"language":1623,"meta":743,"style":743},[567,81730,81731,81739,81743,81749],{"__ignoreMap":743},[747,81732,81733,81735,81737],{"class":749,"line":750},[747,81734,3257],{"class":1630},[747,81736,3665],{"class":802},[747,81738,1641],{"class":1640},[747,81740,81741],{"class":749,"line":761},[747,81742,6417],{"class":1640},[747,81744,81745,81747],{"class":749,"line":769},[747,81746,6139],{"class":1630},[747,81748,6142],{"class":802},[747,81750,81751,81753,81755,81757,81759,81761],{"class":749,"line":776},[747,81752,4253],{"class":757},[747,81754,5704],{"class":1640},[747,81756,4259],{"class":757},[747,81758,4262],{"class":757},[747,81760,6630],{"class":1640},[747,81762,4268],{"class":757},[6072,81764,81765,81769,81789,81793,81797],{},[523,81766,81767],{},[584,81768,2957],{},[668,81770,81771,81775,81779],{},[638,81772,81773,6162],{},[567,81774,6161],{},[638,81776,81777,6168],{},[567,81778,6167],{},[638,81780,81781,6174,81783,6178,81785,6182,81787,1909],{},[567,81782,6173],{},[567,81784,6177],{},[567,81786,6181],{},[567,81788,6177],{},[523,81790,81791,7324],{},[584,81792,3103],{},[523,81794,81795],{},[584,81796,6189],{},[668,81798,81799,81802,81810],{},[638,81800,81801],{},"When the host path doesn't exist, it'll get created. BUT the permissions will be a bit \"freaky\".",[638,81803,81804,81805,81807,81808,1909],{},"When the path get's created on the host, the directory will be (by default) owned by ",[567,81806,7341],{},", mod perms ",[567,81809,7345],{},[638,81811,7348,81812,1909],{},[527,81813,3396],{"href":7351,"rel":81814},[531],[535,81816,7356,81817],{"id":7355},[567,81818,7359],{},[6072,81820,81821,81825],{},[523,81822,81823],{},[584,81824,6189],{},[668,81826,81827,81830],{},[638,81828,81829],{},"I do NOT recommend this method as I often enough \"accidentally\" clear all exited\u002Fdead containers, so my disk space doesn't run out.",[638,81831,7375],{},[523,81833,7378,81834,7381,81836,7385,81838,7389],{},[567,81835,6335],{},[567,81837,7384],{},[567,81839,7388],{},[523,81841,7392,81842,6353,81844,7398],{},[567,81843,7395],{},[567,81845,4188],{},[523,81847,7401,81848,7405,81850,7408,81852,7411],{},[567,81849,7404],{},[567,81851,7404],{},[567,81853,7359],{},[523,81855,7414],{},[2979,81857],{},[79989,81859,193],{"id":7442},[523,81861,7445],{},[535,81863,7449],{"id":7448},[6072,81865,81866],{},[523,81867,81868],{},"I'm not going to explain NAT here.",[523,81870,81871],{},"NAT also Network Address Translation, allows multiple devices to sit behind one IP address.",[535,81873,7459],{"id":7458},[523,81875,81876,81877,714,81879,7469,81881,7473,81883,7476,81885,7480,81887,6353,81889,7487,81891,7491,81893,6374,81895,1909],{},"Docker creates a bridge that is used as a bridge to your network interfaces (",[567,81878,7465],{},[567,81880,7468],{},[567,81882,7472],{},[567,81884,7472],{},[567,81886,7479],{},[567,81888,7483],{},[567,81890,7486],{},[567,81892,7490],{},[567,81894,7494],{},[567,81896,7497],{},[523,81898,7500,81899,7504,81901,7507,81903,7510,81905,7513,81907,6374,81909,1909],{},[567,81900,7503],{},[567,81902,7503],{},[567,81904,7503],{},[567,81906,7503],{},[567,81908,7516],{},[567,81910,7519],{},[6072,81912,81913,81917],{},[523,81914,81915],{},[584,81916,3673],{},[523,81918,81919,81920,7896],{},"This recording shows, the docker0 interface and the veth interface of the database container. In the end we use ",[567,81921,7895],{},[523,81923,7899,81924,1909],{},[527,81925,7904],{"href":7902,"rel":81926},[531],[535,81928,7908],{"id":7907},[523,81930,81931],{},"I've wrote, that I'm not going deeper into Docker's own (overlay) network feature, but with this topic, I'll have to go into it just a bit.",[523,81933,7914,81934,6378,81936,7920,81938,7923],{},[567,81935,2014],{},[567,81937,7919],{},[567,81939,2014],{},[523,81941,7926,81942,7930,81944,81946],{},[567,81943,7929],{},[567,81945,7929],{}," network \"mode\" gives the host network stack aka \"full access to the network of the host system\" inside the container.",[523,81948,7936],{},[6072,81950,81951,81955],{},[523,81952,81953],{},[584,81954,3673],{},[523,81956,81957,81958,8241],{},"In the recording, you can see that when using the default network mode you'll get a \"newly\" created network stack and when using the ",[567,81959,7929],{},[535,81961,8245],{"id":8244},[523,81963,8248,81964,8251,81966,8255,81968,8258,81970,1909],{},[567,81965,2014],{},[567,81967,8254],{},[567,81969,8254],{},[567,81971,8261],{},[6072,81973,81974],{},[523,81975,81976,81978],{},[584,81977,3673],{},[3069,81979],{"alt":8270,"src":8271},[523,81981,8274,81982,8278,81984,8282],{},[567,81983,8277],{},[567,81985,8281],{},[6072,81987,81988],{},[523,81989,81990,8287,81992],{},[584,81991,2951],{},[527,81993,81995],{"href":8290,"rel":81994},[531],[567,81996,8294],{},[523,81998,8297,81999,8301,82001,8304,82003,8307],{},[567,82000,47087],{},[567,82002,8294],{},[567,82004,8254],{},[535,82006,8311],{"id":8310},[6072,82008,82009],{},[523,82010,82011,8287,82013],{},[584,82012,2951],{},[527,82014,82016],{"href":8290,"rel":82015},[531],[567,82017,8294],{},[523,82019,47107],{},[523,82021,8336,82022,8339,82024,8343],{},[567,82023,8294],{},[567,82025,8342],{},[738,82027,82028],{"className":1621,"code":8346,"language":1623,"meta":743,"style":743},[567,82029,82030,82042,82052],{"__ignoreMap":743},[747,82031,82032,82034,82036,82038,82040],{"class":749,"line":750},[747,82033,3376],{"class":1630},[747,82035,8355],{"class":802},[747,82037,3340],{"class":802},[747,82039,8360],{"class":802},[747,82041,8363],{"class":802},[747,82043,82044,82046,82048,82050],{"class":749,"line":761},[747,82045,3376],{"class":1630},[747,82047,3379],{"class":802},[747,82049,8372],{"class":802},[747,82051,8375],{"class":802},[747,82053,82054,82056,82058],{"class":749,"line":769},[747,82055,3376],{"class":1630},[747,82057,7614],{"class":802},[747,82059,8384],{"class":802},[523,82061,8387,82062,8392],{},[527,82063,8390],{"href":8390,"rel":82064},[531],[6072,82066,82067],{},[523,82068,82069,82071],{},[584,82070,3521],{},[3069,82072],{"alt":8401,"src":8402},[523,82074,8405],{},[2979,82076],{},[79989,82078,8419],{"id":8418},[6072,82080,82081,82083],{},[523,82082,8422],{},[523,82084,82085],{},[3049,82086,8427],{},[523,82088,8430,82089,47177],{},[527,82090,8434],{"href":47176},[535,82092,8439],{"id":8438},[523,82094,8442],{},[738,82096,82097],{"className":1621,"code":8445,"language":1623,"meta":743,"style":743},[567,82098,82099,82109,82117,82135,82153,82175],{"__ignoreMap":743},[747,82100,82101,82103,82105,82107],{"class":749,"line":750},[747,82102,1919],{"class":1630},[747,82104,3246],{"class":802},[747,82106,3665],{"class":802},[747,82108,4218],{"class":802},[747,82110,82111,82113,82115],{"class":749,"line":761},[747,82112,4253],{"class":757},[747,82114,5685],{"class":1640},[747,82116,4268],{"class":757},[747,82118,82119,82121,82123,82125,82127,82129,82131,82133],{"class":749,"line":769},[747,82120,8470],{"class":1630},[747,82122,8473],{"class":802},[747,82124,8476],{"class":802},[747,82126,8479],{"class":802},[747,82128,8482],{"class":1640},[747,82130,8485],{"class":802},[747,82132,8488],{"class":802},[747,82134,8491],{"class":1640},[747,82136,82137,82139,82141,82143,82145,82147,82149,82151],{"class":749,"line":776},[747,82138,8496],{"class":1630},[747,82140,8499],{"class":802},[747,82142,8476],{"class":802},[747,82144,8479],{"class":802},[747,82146,8482],{"class":1640},[747,82148,8485],{"class":802},[747,82150,8488],{"class":802},[747,82152,8512],{"class":1640},[747,82154,82155,82157,82159,82161,82163,82165,82167,82169,82171,82173],{"class":749,"line":784},[747,82156,8517],{"class":1630},[747,82158,8520],{"class":802},[747,82160,4584],{"class":802},[747,82162,3945],{"class":802},[747,82164,3696],{"class":802},[747,82166,8529],{"class":802},[747,82168,8532],{"class":802},[747,82170,8535],{"class":1640},[747,82172,8538],{"class":802},[747,82174,3600],{"class":1640},[747,82176,82177,82179,82181],{"class":749,"line":790},[747,82178,4253],{"class":757},[747,82180,5685],{"class":1640},[747,82182,4268],{"class":757},[523,82184,8551,82185,3052],{},[567,82186,8554],{},[535,82188,8558],{"id":8557},[738,82190,82191],{"className":1621,"code":8561,"language":1623,"meta":743,"style":743},[567,82192,82193,82203,82211,82233,82241,82251,82259,82269,82301,82325,82333,82343,82355],{"__ignoreMap":743},[747,82194,82195,82197,82199,82201],{"class":749,"line":750},[747,82196,1919],{"class":1630},[747,82198,3246],{"class":802},[747,82200,3665],{"class":802},[747,82202,4218],{"class":802},[747,82204,82205,82207,82209],{"class":749,"line":761},[747,82206,4253],{"class":757},[747,82208,5685],{"class":1640},[747,82210,4268],{"class":757},[747,82212,82213,82215,82217,82219,82221,82223,82225,82227,82229,82231],{"class":749,"line":769},[747,82214,8586],{"class":1630},[747,82216,8589],{"class":802},[747,82218,4584],{"class":802},[747,82220,3945],{"class":802},[747,82222,3696],{"class":802},[747,82224,8529],{"class":802},[747,82226,8532],{"class":802},[747,82228,8535],{"class":1640},[747,82230,8538],{"class":802},[747,82232,3600],{"class":1640},[747,82234,82235,82237,82239],{"class":749,"line":776},[747,82236,4253],{"class":757},[747,82238,5685],{"class":1640},[747,82240,4268],{"class":757},[747,82242,82243,82245,82247,82249],{"class":749,"line":784},[747,82244,8618],{"class":1630},[747,82246,8621],{"class":802},[747,82248,8624],{"class":802},[747,82250,8627],{"class":802},[747,82252,82253,82255,82257],{"class":749,"line":790},[747,82254,4253],{"class":757},[747,82256,5685],{"class":1640},[747,82258,4268],{"class":757},[747,82260,82261,82263,82265,82267],{"class":749,"line":796},[747,82262,8640],{"class":1630},[747,82264,8643],{"class":802},[747,82266,8646],{"class":802},[747,82268,8627],{"class":802},[747,82270,82271,82273,82275,82277,82279,82281,82283,82285,82287,82289,82291,82293,82295,82297,82299],{"class":749,"line":806},[747,82272,8653],{"class":1630},[747,82274,8656],{"class":802},[747,82276,5033],{"class":802},[747,82278,8661],{"class":802},[747,82280,3696],{"class":802},[747,82282,8624],{"class":802},[747,82284,8668],{"class":802},[747,82286,8671],{"class":802},[747,82288,3537],{"class":757},[747,82290,4920],{"class":802},[747,82292,3543],{"class":757},[747,82294,3696],{"class":802},[747,82296,3205],{"class":802},[747,82298,5043],{"class":802},[747,82300,8686],{"class":802},[747,82302,82303,82305,82307,82309,82311,82313,82315,82317,82319,82321,82323],{"class":749,"line":814},[747,82304,8691],{"class":1640},[747,82306,6425],{"class":757},[747,82308,4920],{"class":802},[747,82310,8698],{"class":1630},[747,82312,3936],{"class":802},[747,82314,8624],{"class":802},[747,82316,8705],{"class":802},[747,82318,8708],{"class":1640},[747,82320,4990],{"class":802},[747,82322,8713],{"class":1895},[747,82324,3600],{"class":1640},[747,82326,82327,82329,82331],{"class":749,"line":822},[747,82328,4253],{"class":757},[747,82330,5685],{"class":1640},[747,82332,4268],{"class":757},[747,82334,82335,82337,82339,82341],{"class":749,"line":830},[747,82336,8728],{"class":1630},[747,82338,8731],{"class":802},[747,82340,4981],{"class":802},[747,82342,8736],{"class":802},[747,82344,82345,82347,82349,82351,82353],{"class":749,"line":836},[747,82346,8741],{"class":1630},[747,82348,8744],{"class":802},[747,82350,4591],{"class":802},[747,82352,3543],{"class":757},[747,82354,8751],{"class":802},[747,82356,82357],{"class":749,"line":842},[747,82358,5986],{"class":802},[523,82360,8758],{},[523,82362,8761],{},[523,82364,8764,82365,8768],{},[567,82366,8767],{},[2979,82368],{},[79989,82370,47458],{"id":8780},[523,82372,8784],{},[535,82374,8788],{"id":8787},[523,82376,8791,82377,8797],{},[527,82378,8796],{"href":8794,"rel":82379},[531],[523,82381,8800],{},[738,82383,82385],{"className":1621,"code":82384,"language":1623,"meta":743,"style":743},"sameersbn\u002Fmysql:latest\n",[567,82386,82387],{"__ignoreMap":743},[747,82388,82389],{"class":749,"line":750},[747,82390,82384],{"class":1630},[6072,82392,82393,82397],{},[523,82394,82395],{},[584,82396,2957],{},[668,82398,82399,82403,82407],{},[638,82400,82401,47492],{},[567,82402,5734],{},[638,82404,82405,47497],{},[567,82406,6744],{},[638,82408,82409,8835],{},[567,82410,8834],{},[523,82412,8838,82413,8844,82416,1909],{},[527,82414,8843],{"href":8841,"rel":82415},[531],[527,82417,8849],{"href":8847,"rel":82418},[531],[738,82420,82421],{"className":1621,"code":8852,"language":1623,"meta":743,"style":743},[567,82422,82423,82427],{"__ignoreMap":743},[747,82424,82425],{"class":749,"line":750},[747,82426,8859],{"class":1630},[747,82428,82429],{"class":749,"line":761},[747,82430,8864],{"class":1630},[6072,82432,82433,82437],{},[523,82434,82435],{},[584,82436,2957],{},[668,82438,82439,82447,82453,82459],{},[638,82440,82441,714,82443,8878,82445,8882],{},[567,82442,8849],{},[567,82444,8877],{},[567,82446,8881],{},[638,82448,82449,714,82451,8890],{},[567,82450,8887],{},[567,82452,3267],{},[638,82454,82455,714,82457,8899],{},[567,82456,8895],{},[567,82458,8898],{},[638,82460,82461,714,82463,8908,82465,1909],{},[567,82462,8904],{},[567,82464,8907],{},[567,82466,8834],{},[523,82468,8914,82469,3052],{},[527,82470,8917],{"href":8917,"rel":82471},[531],[535,82473,8922],{"id":8921},[523,82475,82476,82478],{},[3069,82477],{"alt":8927,"src":8928},"\n_Mhh, tasty, isn't it?_ But now back to the topic.",[6072,82480,82481],{},[523,82482,82483,8939,82485],{},[584,82484,2951],{},[527,82486,82488],{"href":8942,"rel":82487},[531],[567,82489,8946],{},[523,82491,8949],{},[523,82493,8952,82494,8956,82496,8960],{},[567,82495,8955],{},[567,82497,8959],{},[523,82499,82500],{},[3069,82501],{"alt":8965,"src":8966},[523,82503,8969,82504,8973],{},[567,82505,8972],{},[535,82507,47620],{"id":8976},[523,82509,8980,82510,8984,82512,8987,82514,82516,82517,82519],{},[567,82511,8983],{},[567,82513,8959],{},[567,82515,8959],{}," contains build instructions for an image. For ",[567,82518,8959],{},"s there is a \"special\" syntax, but the syntax is very simple.\nI'm going to show you a simple and a more advanced example of Dockerfiles.",[613,82521,82523],{"id":82522},"simple-dockerfile-example","Simple Dockerfile Example",[523,82525,9000,82526,9006,82529,1909],{},[527,82527,9005],{"href":9003,"rel":82528},[531],[567,82530,8959],{},[738,82532,82534],{"className":9011,"code":82533,"language":9013,"meta":743,"style":743},"FROM debian:jessie\n\nENV EBOT_HOME=\"\u002Febot\" TIMEZONE=\"Europe\u002FBerlin\"\n\nADD entrypoint.sh \u002Fsbin\u002Fentrypoint.sh\n\nRUN apt-get update && \\\n    apt-get -y upgrade && \\\n    apt-get clean && \\\n    apt-get -y install nodejs npm curl git php5-cli php5-mysql screen git && \\\n    apt-get clean && \\\n    sed -i \"s~;date.timezone =~date.timezone = $TIMEZONE~g\" \u002Fetc\u002Fphp5\u002Fcli\u002Fphp.ini && \\\n    \u002Fbin\u002Fln -s \u002Fusr\u002Fbin\u002Fnodejs \u002Fusr\u002Fbin\u002Fnode && \\\n    curl -sS https:\u002F\u002Fgetcomposer.org\u002Finstaller | php -- --install-dir=\u002Fusr\u002Fbin && \\\n    mkdir \"$EBOT_HOME\" && \\\n    git clone https:\u002F\u002Fgithub.com\u002FdeStrO\u002FeBot-CSGO.git \"$EBOT_HOME\" && \\\n    cd \"$EBOT_HOME\" && \\\n    git checkout \"master\" && \\\n    \u002Fusr\u002Fbin\u002Fphp \u002Fusr\u002Fbin\u002Fcomposer.phar install && \\\n    npm install socket.io formidable archiver\n\nCOPY Match.php $EBOT_HOME\u002Fsrc\u002FeBot\u002FMatch\u002FMatch.php\n\nVOLUME [\"$EBOT_HOME\u002Fdemos\", \"$EBOT_HOME\u002Flogs\"]\n\nEXPOSE 12360 12361\n\nENTRYPOINT [\"\u002Fsbin\u002Fentrypoint.sh\"]\n",[567,82535,82536,82543,82547,82559,82563,82569,82573,82579,82583,82587,82591,82595,82603,82607,82611,82619,82627,82635,82643,82647,82651,82655,82661,82665,82679,82683,82689,82693],{"__ignoreMap":743},[747,82537,82538,82540],{"class":749,"line":750},[747,82539,9020],{"class":1895},[747,82541,82542],{"class":1640}," debian:jessie\n",[747,82544,82545],{"class":749,"line":761},[747,82546,1255],{"emptyLinePlaceholder":1254},[747,82548,82549,82551,82553,82555,82557],{"class":749,"line":769},[747,82550,9032],{"class":1895},[747,82552,9035],{"class":1640},[747,82554,9038],{"class":802},[747,82556,9041],{"class":1640},[747,82558,9044],{"class":802},[747,82560,82561],{"class":749,"line":776},[747,82562,1255],{"emptyLinePlaceholder":1254},[747,82564,82565,82567],{"class":749,"line":784},[747,82566,9669],{"class":1895},[747,82568,9056],{"class":1640},[747,82570,82571],{"class":749,"line":790},[747,82572,1255],{"emptyLinePlaceholder":1254},[747,82574,82575,82577],{"class":749,"line":796},[747,82576,9065],{"class":1895},[747,82578,9068],{"class":1640},[747,82580,82581],{"class":749,"line":806},[747,82582,9073],{"class":1640},[747,82584,82585],{"class":749,"line":814},[747,82586,9078],{"class":1640},[747,82588,82589],{"class":749,"line":822},[747,82590,9083],{"class":1640},[747,82592,82593],{"class":749,"line":830},[747,82594,9078],{"class":1640},[747,82596,82597,82599,82601],{"class":749,"line":836},[747,82598,9092],{"class":1640},[747,82600,9095],{"class":802},[747,82602,9098],{"class":1640},[747,82604,82605],{"class":749,"line":842},[747,82606,9103],{"class":1640},[747,82608,82609],{"class":749,"line":850},[747,82610,9108],{"class":1640},[747,82612,82613,82615,82617],{"class":749,"line":863},[747,82614,9113],{"class":1640},[747,82616,9116],{"class":802},[747,82618,9119],{"class":1640},[747,82620,82621,82623,82625],{"class":749,"line":869},[747,82622,9124],{"class":1640},[747,82624,9116],{"class":802},[747,82626,9119],{"class":1640},[747,82628,82629,82631,82633],{"class":749,"line":877},[747,82630,9133],{"class":1640},[747,82632,9116],{"class":802},[747,82634,9119],{"class":1640},[747,82636,82637,82639,82641],{"class":749,"line":1015},[747,82638,9142],{"class":1640},[747,82640,9145],{"class":802},[747,82642,9119],{"class":1640},[747,82644,82645],{"class":749,"line":1021},[747,82646,9152],{"class":1640},[747,82648,82649],{"class":749,"line":1027},[747,82650,9157],{"class":1640},[747,82652,82653],{"class":749,"line":1033},[747,82654,1255],{"emptyLinePlaceholder":1254},[747,82656,82657,82659],{"class":749,"line":1039},[747,82658,9053],{"class":1895},[747,82660,9168],{"class":1640},[747,82662,82663],{"class":749,"line":1054},[747,82664,1255],{"emptyLinePlaceholder":1254},[747,82666,82667,82669,82671,82673,82675,82677],{"class":749,"line":1060},[747,82668,9177],{"class":1895},[747,82670,4262],{"class":1640},[747,82672,9182],{"class":802},[747,82674,714],{"class":1640},[747,82676,9187],{"class":802},[747,82678,4268],{"class":1640},[747,82680,82681],{"class":749,"line":1066},[747,82682,1255],{"emptyLinePlaceholder":1254},[747,82684,82685,82687],{"class":749,"line":1081},[747,82686,9198],{"class":1895},[747,82688,9201],{"class":1640},[747,82690,82691],{"class":749,"line":1087},[747,82692,1255],{"emptyLinePlaceholder":1254},[747,82694,82695,82697,82699,82701],{"class":749,"line":1102},[747,82696,9210],{"class":1895},[747,82698,4262],{"class":1640},[747,82700,9215],{"class":802},[747,82702,4268],{"class":1640},[613,82704,9221],{"id":9220},[523,82706,9000,82707,9006,82710,1909],{},[527,82708,9229],{"href":9227,"rel":82709},[531],[567,82711,8959],{},[738,82713,82715],{"className":9011,"code":82714,"language":9013,"meta":743,"style":743},"FROM quay.io\u002Fsameersbn\u002Fubuntu:latest\nMAINTAINER Alexander Trost \u003Cgalexrt@googlemail.com>\n\nENV ZULIP_VERSION=\"master\" DATA_DIR=\"\u002Fdata\"\n\nADD entrypoint.sh \u002Fsbin\u002Fentrypoint.sh\n\nRUN apt-get -q update && \\\n    apt-get -q dist-upgrade -y && \\\n    apt-get install -y git && \\\n    mkdir -p \"$DATA_DIR\" \u002Froot\u002Fzulip && \\\n    git clone https:\u002F\u002Fgithub.com\u002Fzulip\u002Fzulip.git \u002Froot\u002Fzulip && \\\n    cd \u002Froot\u002Fzulip && \\\n    git checkout \"$ZULIP_VERSION\" && \\\n    rm -rf \u002Froot\u002Fzulip\u002F.git\n\nADD custom_zulip_files\u002F \u002Froot\u002Fcustom_zulip\n\nRUN cp -rf \u002Froot\u002Fcustom_zulip\u002F* \u002Froot\u002Fzulip && \\\n    VOYAGER_CLASS=\"dockervoyager\" DEPLOYMENT_TYPE=\"dockervoyager\" ADDITIONAL_PACKAGES=\"python-dev python-six python-pbs\" \\\n    \u002Froot\u002Fzulip\u002Fscripts\u002Fsetup\u002Finstall && \\\n    wget -q https:\u002F\u002Fwww.zulip.com\u002Fdist\u002Freleases\u002Fzulip-server-latest.tar.gz -O \u002Ftmp\u002Fzulip-server.tar.gz && \\\n    tar xfz \u002Ftmp\u002Fzulip-server.tar.gz -C \"\u002Fhome\u002Fzulip\u002Fprod-static\" --strip-components=3 --wildcards *\u002Fprod-static\u002Fserve && \\\n    rm -rf \u002Ftmp\u002Fzulip-server.tar.gz && \\\n    ln -nsf \u002Fhome\u002Fzulip\u002Fdeployments\u002Fcurrent\u002Fprod-static\u002Fserve \u002Fhome\u002Fzulip\u002Fprod-static && \\\n    apt-get -qq autoremove --purge -y && \\\n    apt-get -qq clean && \\\n    rm -rf \u002Froot\u002Fzulip\u002Fpuppet\u002F \u002Fvar\u002Flib\u002Fapt\u002Flists\u002F* \u002Ftmp\u002F* \u002Fvar\u002Ftmp\u002F*\n\nADD setup_files\u002F \u002Fopt\u002Ffiles\nADD includes\u002Fsupervisor\u002Fconf.d\u002Fzulip_postsetup.conf \u002Fetc\u002Fsupervisor\u002Fconf.d\u002Fzulip_postsetup.conf\nADD includes\u002FcreateZulipAdmin.sh \u002FcreateZulipAdmin.sh\n\nVOLUME [\"$DATA_DIR\"]\nEXPOSE 80 443\n\nENTRYPOINT [\"\u002Fsbin\u002Fentrypoint.sh\"]\nCMD [\"app:run\"]\n",[567,82716,82717,82723,82731,82735,82747,82751,82757,82761,82767,82771,82775,82783,82787,82791,82799,82803,82807,82813,82817,82823,82839,82843,82847,82855,82859,82863,82867,82871,82875,82879,82885,82891,82897,82901,82911,82917,82921,82931],{"__ignoreMap":743},[747,82718,82719,82721],{"class":749,"line":750},[747,82720,9020],{"class":1895},[747,82722,9243],{"class":1640},[747,82724,82725,82728],{"class":749,"line":761},[747,82726,82727],{"class":1895},"MAINTAINER",[747,82729,82730],{"class":1640}," Alexander Trost \u003Cgalexrt@googlemail.com>\n",[747,82732,82733],{"class":749,"line":769},[747,82734,1255],{"emptyLinePlaceholder":1254},[747,82736,82737,82739,82741,82743,82745],{"class":749,"line":776},[747,82738,9032],{"class":1895},[747,82740,9254],{"class":1640},[747,82742,9145],{"class":802},[747,82744,9259],{"class":1640},[747,82746,9262],{"class":802},[747,82748,82749],{"class":749,"line":784},[747,82750,1255],{"emptyLinePlaceholder":1254},[747,82752,82753,82755],{"class":749,"line":790},[747,82754,9669],{"class":1895},[747,82756,9056],{"class":1640},[747,82758,82759],{"class":749,"line":796},[747,82760,1255],{"emptyLinePlaceholder":1254},[747,82762,82763,82765],{"class":749,"line":806},[747,82764,9065],{"class":1895},[747,82766,9283],{"class":1640},[747,82768,82769],{"class":749,"line":814},[747,82770,9288],{"class":1640},[747,82772,82773],{"class":749,"line":822},[747,82774,9293],{"class":1640},[747,82776,82777,82779,82781],{"class":749,"line":830},[747,82778,9298],{"class":1640},[747,82780,9301],{"class":802},[747,82782,9304],{"class":1640},[747,82784,82785],{"class":749,"line":836},[747,82786,9309],{"class":1640},[747,82788,82789],{"class":749,"line":842},[747,82790,9314],{"class":1640},[747,82792,82793,82795,82797],{"class":749,"line":850},[747,82794,9142],{"class":1640},[747,82796,9321],{"class":802},[747,82798,9119],{"class":1640},[747,82800,82801],{"class":749,"line":863},[747,82802,9328],{"class":1640},[747,82804,82805],{"class":749,"line":869},[747,82806,1255],{"emptyLinePlaceholder":1254},[747,82808,82809,82811],{"class":749,"line":877},[747,82810,9669],{"class":1895},[747,82812,9339],{"class":1640},[747,82814,82815],{"class":749,"line":1015},[747,82816,1255],{"emptyLinePlaceholder":1254},[747,82818,82819,82821],{"class":749,"line":1021},[747,82820,9065],{"class":1895},[747,82822,9350],{"class":1640},[747,82824,82825,82827,82829,82831,82833,82835,82837],{"class":749,"line":1027},[747,82826,9355],{"class":1640},[747,82828,9358],{"class":802},[747,82830,9361],{"class":1640},[747,82832,9358],{"class":802},[747,82834,9366],{"class":1640},[747,82836,9369],{"class":802},[747,82838,1641],{"class":1640},[747,82840,82841],{"class":749,"line":1033},[747,82842,9376],{"class":1640},[747,82844,82845],{"class":749,"line":1039},[747,82846,9381],{"class":1640},[747,82848,82849,82851,82853],{"class":749,"line":1054},[747,82850,9386],{"class":1640},[747,82852,9389],{"class":802},[747,82854,9392],{"class":1640},[747,82856,82857],{"class":749,"line":1060},[747,82858,9397],{"class":1640},[747,82860,82861],{"class":749,"line":1066},[747,82862,9402],{"class":1640},[747,82864,82865],{"class":749,"line":1081},[747,82866,9407],{"class":1640},[747,82868,82869],{"class":749,"line":1087},[747,82870,9412],{"class":1640},[747,82872,82873],{"class":749,"line":1102},[747,82874,9417],{"class":1640},[747,82876,82877],{"class":749,"line":1110},[747,82878,1255],{"emptyLinePlaceholder":1254},[747,82880,82881,82883],{"class":749,"line":1117},[747,82882,9669],{"class":1895},[747,82884,9428],{"class":1640},[747,82886,82887,82889],{"class":749,"line":1123},[747,82888,9669],{"class":1895},[747,82890,9435],{"class":1640},[747,82892,82893,82895],{"class":749,"line":1129},[747,82894,9669],{"class":1895},[747,82896,9442],{"class":1640},[747,82898,82899],{"class":749,"line":1142},[747,82900,1255],{"emptyLinePlaceholder":1254},[747,82902,82903,82905,82907,82909],{"class":749,"line":1150},[747,82904,9177],{"class":1895},[747,82906,4262],{"class":1640},[747,82908,9301],{"class":802},[747,82910,4268],{"class":1640},[747,82912,82913,82915],{"class":749,"line":1157},[747,82914,9198],{"class":1895},[747,82916,9463],{"class":1640},[747,82918,82919],{"class":749,"line":1163},[747,82920,1255],{"emptyLinePlaceholder":1254},[747,82922,82923,82925,82927,82929],{"class":749,"line":1168},[747,82924,9210],{"class":1895},[747,82926,4262],{"class":1640},[747,82928,9215],{"class":802},[747,82930,4268],{"class":1640},[747,82932,82933,82935,82937,82939],{"class":749,"line":1174},[747,82934,9482],{"class":1895},[747,82936,4262],{"class":1640},[747,82938,9487],{"class":802},[747,82940,4268],{"class":1640},[523,82942,82943,82945],{},[3049,82944,9494],{}," we're going to make a very simple and basic image. ;)",[535,82947,9499],{"id":9498},[6072,82949,82950,82959,82963],{},[523,82951,82952,8939,82954],{},[584,82953,2951],{},[527,82955,82957],{"href":9506,"rel":82956},[531],[567,82958,9510],{},[523,82960,82961],{},[584,82962,9515],{},[523,82964,48233,82965,82967,82968,1909],{},[567,82966,8959],{},", check the ",[527,82969,48239],{"href":9522,"rel":82970},[531],[523,82972,9527,82973,9531],{},[567,82974,9530],{},[523,82976,9534,82977,9537],{},[567,82978,9530],{},[6072,82980,82981,82991],{},[523,82982,82983,82985,82986,2006],{},[584,82984,9542],{},": (Example taken from ",[527,82987,82990],{"href":82988,"rel":82989},"https:\u002F\u002Fmedium.com\u002F@shijuvar\u002Fdeploying-go-web-apps-with-docker-1b7561b36f53#.lkj19wklp",[531],"Shiju Varghese Medium Blog",[738,82992,82993],{"className":9011,"code":743,"language":9013,"meta":743,"style":743},[567,82994,82995],{"__ignoreMap":743},[747,82996],{"class":749,"line":750},[79989,82998,83000],{"id":82999},"golang-image-where-workspace-gopath-configured-at-go","golang image where workspace (GOPATH) configured at \u002Fgo.",[523,83002,83003],{},"FROM golang:latest",[79989,83005,83007],{"id":83006},"copy-the-local-package-files-to-the-containers-workspace","Copy the local package files to the container’s workspace.",[523,83009,83010],{},"ADD . \u002Fgo\u002Fsrc\u002Fgithub.com\u002Fshijuvar\u002Fgolang-docker",[79989,83012,83014],{"id":83013},"build-the-golang-docker-command-inside-the-container","Build the golang-docker command inside the container.",[523,83016,83017],{},"RUN go install github.com\u002Fshijuvar\u002Fgolang-docker",[79989,83019,83021],{"id":83020},"run-the-golang-docker-command-when-the-container-starts","Run the golang-docker command when the container starts.",[523,83023,83024,83025],{},"ENTRYPOINT ",[747,83026,83027],{},"\"\u002Fgo\u002Fbin\u002Fgolang-docker\"",[79989,83029,83031],{"id":83030},"http-server-listens-on-port-8080","http server listens on port 8080.",[523,83033,83034],{},"EXPOSE 8080",[738,83036,83039],{"className":83037,"code":83038,"language":12479,"meta":743},[12477],"\n> **WDWD**\n>\n> * `FROM ...` - Sets the baseimage.\n> * `COPY ... ...` - Copy files from the build root.\n> * `ADD ... ...` - Same as `COPY`, but target can be \"online\" and if it is an archive, it will be extracted.\n> * `RUN ...` - Run commands (Shell used `\u002Fbin\u002Fsh`).\n> * `ENTRYPOINT [\"...\"]` - The command to execute when the container is started.\n> * `CMD [\"...\"]` - Arguments for the `ENTRYPOINT`.\n> * `EXPOSE 8080 ...` - Expose a port when linked (_If not specified port not reachable when linked!_). To specify protocol just add a `\u002Ftcp` or `\u002Fudp`.\n\nThere's even the possibility, to execute specific commands when the image is used as a base image, the base instruction is called `ONBUILD ...`, but explaining this is beyond the scope of this workshop. Thanks for understanding!\n\nTo build an image we use the `docker build` command. Building this golang example image, we run the following command:\n```bash\ndocker build -t golang-docker -f Dockerfile .\n\n",[567,83040,83038],{"__ignoreMap":743},[6072,83042,83043,83047],{},[523,83044,83045],{},[584,83046,2957],{},[668,83048,83049,83053,83063,83069],{},[638,83050,83051,9759],{},[567,83052,9758],{},[638,83054,83055,9765,83057,9768,83059,9771,83061,1909],{},[567,83056,9764],{},[584,83058,6189],{},[567,83060,8898],{},[567,83062,9774],{},[638,83064,83065,9780,83067,9783],{},[567,83066,9779],{},[567,83068,8959],{},[638,83070,83071,9788,83073,9792,83075,6374,83077,9797,83079,9800],{},[567,83072,1909],{},[584,83074,9791],{},[567,83076,9669],{},[567,83078,9053],{},[567,83080,8959],{},[523,83082,83083,83084,1909],{},"As you can see, it isn't hard to build your first Docker images.\nIf you want to see more advanced examples, you can find more examples in my GitHub repositories ",[527,83085,3396],{"href":83086,"rel":83087},"https:\u002F\u002Fgithub.com\u002Fsearch?q=user%3AGalexrt+docker-",[531],[535,83089,10184],{"id":10183},[613,83091,10188],{"id":10187},[523,83093,10191,83094,10195,83096,10199],{},[567,83095,10194],{},[567,83097,10198],{},[738,83099,83100],{"className":1621,"code":10202,"language":1623,"meta":743,"style":743},[567,83101,83102],{"__ignoreMap":743},[747,83103,83104,83106,83108,83110],{"class":749,"line":750},[747,83105,3257],{"class":1630},[747,83107,10211],{"class":802},[747,83109,10214],{"class":802},[747,83111,10217],{"class":1640},[6072,83113,83114,83118],{},[523,83115,83116],{},[584,83117,2957],{},[668,83119,83120,83124],{},[638,83121,83122,10229],{},[567,83123,10228],{},[638,83125,83126,10235],{},[567,83127,10234],{},[613,83129,10239],{"id":10238},[523,83131,10242],{},[738,83133,83134],{"className":1621,"code":10245,"language":1623,"meta":743,"style":743},[567,83135,83136],{"__ignoreMap":743},[747,83137,83138,83140,83142,83144,83146,83148,83150],{"class":749,"line":750},[747,83139,3257],{"class":1630},[747,83141,9733],{"class":802},[747,83143,9736],{"class":802},[747,83145,10258],{"class":802},[747,83147,1934],{"class":802},[747,83149,10263],{"class":802},[747,83151,10266],{"class":802},[6072,83153,83154,83158],{},[523,83155,83156],{},[584,83157,2957],{},[668,83159,83160,83164,83174,83180],{},[638,83161,83162,10277],{},[567,83163,9758],{},[638,83165,83166,10282,83168,10285,83170,10289,83172,10292],{},[567,83167,9764],{},[567,83169,8898],{},[527,83171,3396],{"href":48638},[584,83173,2957],{},[638,83175,83176,10298,83178,10301],{},[567,83177,10297],{},[567,83179,8959],{},[638,83181,83182,48651,83184,11500],{},[567,83183,10306],{},[567,83185,10306],{},[535,83187,83189],{"id":83188},"lets-build-your-first-docker-image","Let's build your first Docker image",[523,83191,10331,83192,10334,83194,10337,83196,1909],{},[567,83193,8959],{},[567,83195,9530],{},[567,83197,8972],{},[523,83199,10342,83200,10346,83202,7258],{},[567,83201,10345],{},[527,83203,3396],{"href":48672},[738,83205,83206],{"className":9011,"code":10352,"language":9013,"meta":743,"style":743},[567,83207,83208,83214,83218,83224,83228],{"__ignoreMap":743},[747,83209,83210,83212],{"class":749,"line":750},[747,83211,9020],{"class":1895},[747,83213,10361],{"class":1640},[747,83215,83216],{"class":749,"line":761},[747,83217,1255],{"emptyLinePlaceholder":1254},[747,83219,83220,83222],{"class":749,"line":769},[747,83221,9065],{"class":1895},[747,83223,10361],{"class":1640},[747,83225,83226],{"class":749,"line":776},[747,83227,1255],{"emptyLinePlaceholder":1254},[747,83229,83230,83232,83234,83236],{"class":749,"line":784},[747,83231,9210],{"class":1895},[747,83233,4262],{"class":1640},[747,83235,10384],{"class":802},[747,83237,4268],{"class":1640},[523,83239,10389],{},[738,83241,83242],{"className":1621,"code":10392,"language":1623,"meta":743,"style":743},[567,83243,83244],{"__ignoreMap":743},[747,83245,83246,83248,83250,83252,83254],{"class":749,"line":750},[747,83247,3257],{"class":1630},[747,83249,9733],{"class":802},[747,83251,9736],{"class":802},[747,83253,10405],{"class":802},[747,83255,9747],{"class":802},[6072,83257,83258],{},[523,83259,83260,8287,83263,83265],{},[584,83261,83262],{},"Expected Output of",[584,83264,10415],{},[3069,83266],{"alt":10420,"src":10421},[523,83268,10424,83269,856],{},[567,83270,10427],{},[738,83272,83273],{"className":1621,"code":10430,"language":1623,"meta":743,"style":743},[567,83274,83275,83283,83291,83297,83305],{"__ignoreMap":743},[747,83276,83277,83279,83281],{"class":749,"line":750},[747,83278,3257],{"class":1630},[747,83280,3665],{"class":802},[747,83282,1641],{"class":1640},[747,83284,83285,83287,83289],{"class":749,"line":761},[747,83286,5790],{"class":802},[747,83288,10405],{"class":802},[747,83290,1641],{"class":1640},[747,83292,83293,83295],{"class":749,"line":769},[747,83294,5866],{"class":802},[747,83296,1641],{"class":1640},[747,83298,83299,83301,83303],{"class":749,"line":776},[747,83300,6614],{"class":802},[747,83302,6990],{"class":802},[747,83304,1641],{"class":1640},[747,83306,83307],{"class":749,"line":784},[747,83308,10467],{"class":802},[523,83310,10470,83311,10473],{},[567,83312,6446],{},[738,83314,83315],{"className":1621,"code":10476,"language":1623,"meta":743,"style":743},[567,83316,83317],{"__ignoreMap":743},[747,83318,83319,83321,83323],{"class":749,"line":750},[747,83320,3257],{"class":1630},[747,83322,5902],{"class":802},[747,83324,10487],{"class":802},[523,83326,10490,83327,1909],{},[567,83328,5819],{},[6072,83330,83331,83335],{},[523,83332,83333],{},[584,83334,2957],{},[668,83336,83337,83343],{},[638,83338,83339,10504,83341,10507],{},[567,83340,10503],{},[567,83342,10503],{},[638,83344,83345,10512],{},[567,83346,4164],{},[523,83348,10515,83349,10519],{},[567,83350,10518],{},[523,83352,10522,83353,10525,83355,10529,83357,10532,83359,3052],{},[567,83354,9530],{},[567,83356,10528],{},[567,83358,9210],{},[567,83360,8959],{},[523,83362,10537,83363,10541,83365,10544,83367,10548,83369,10551],{},[567,83364,10540],{},[567,83366,10540],{},[584,83368,10547],{},[567,83370,9210],{},[738,83372,83373],{"className":1621,"code":10554,"language":1623,"meta":743,"style":743},[567,83374,83375],{"__ignoreMap":743},[747,83376,83377,83379,83381,83383,83385,83387,83389,83391,83393,83395,83397,83399,83401,83403],{"class":749,"line":750},[747,83378,9210],{"class":1630},[747,83380,4262],{"class":1640},[747,83382,3892],{"class":757},[747,83384,9530],{"class":802},[747,83386,3892],{"class":757},[747,83388,714],{"class":1640},[747,83390,3892],{"class":757},[747,83392,10575],{"class":802},[747,83394,3892],{"class":757},[747,83396,10580],{"class":802},[747,83398,969],{"class":757},[747,83400,10585],{"class":802},[747,83402,3892],{"class":757},[747,83404,4268],{"class":802},[523,83406,10592,83407,10597],{},[527,83408,10595],{"href":10595,"rel":83409},[531],[523,83411,10600,83412,10604,83414,8301,83416,10609],{},[567,83413,10603],{},[567,83415,10603],{},[567,83417,9510],{},[523,83419,10612,83420,10616,83422,48867],{},[567,83421,10615],{},[567,83423,4203],{},[738,83425,83426],{"className":1621,"code":10629,"language":1623,"meta":743,"style":743},[567,83427,83428,83436,83444,83450,83458,83478],{"__ignoreMap":743},[747,83429,83430,83432,83434],{"class":749,"line":750},[747,83431,3257],{"class":1630},[747,83433,3665],{"class":802},[747,83435,1641],{"class":1640},[747,83437,83438,83440,83442],{"class":749,"line":761},[747,83439,5790],{"class":802},[747,83441,10405],{"class":802},[747,83443,1641],{"class":1640},[747,83445,83446,83448],{"class":749,"line":769},[747,83447,5866],{"class":802},[747,83449,1641],{"class":1640},[747,83451,83452,83454,83456],{"class":749,"line":776},[747,83453,6614],{"class":802},[747,83455,10660],{"class":802},[747,83457,1641],{"class":1640},[747,83459,83460,83462,83464,83466,83468,83470,83472,83474,83476],{"class":749,"line":784},[747,83461,6139],{"class":802},[747,83463,10669],{"class":757},[747,83465,10672],{"class":4574},[747,83467,10675],{"class":757},[747,83469,856],{"class":802},[747,83471,3892],{"class":757},[747,83473,10682],{"class":802},[747,83475,3892],{"class":757},[747,83477,1641],{"class":1640},[747,83479,83480],{"class":749,"line":790},[747,83481,10467],{"class":802},[523,83483,10711,83484,10714,83486,10717,83488,10720,83490,10724,83493,10727],{},[567,83485,10427],{},[567,83487,10427],{},[567,83489,10682],{},[527,83491,10595],{"href":10595,"rel":83492},[531],[567,83494,10603],{},[535,83496,10731],{"id":10730},[523,83498,10734],{},[523,83500,83501,83502,856],{},"For example Travis-CI has switched big parts of their build infrastructure to Docker containers.\nQuoting Travis-CI some headings from their ",[527,83503,10742],{"href":10740,"rel":83504},[531],[6072,83506,83507],{},[523,83508,10747],{},[523,83510,10750],{},[523,83512,83513],{},"The lower resource usage is good for the development workflow, making it faster and cheaper.",[2979,83515],{},[79989,83517,10799,83518],{"id":10798},[567,83519,2936],{},[535,83521,10805],{"id":10804},[523,83523,10808,83524,10811,83526,10814,83528,10818,83530,10822,83532,10826,83534,1909],{},[567,83525,2936],{},[567,83527,2936],{},[3049,83529,10817],{},[567,83531,10821],{},[3049,83533,10825],{},[527,83535,3396],{"href":10829,"rel":83536},[531],[523,83538,10833,83539,10836],{},[567,83540,10821],{},[523,83542,10839,83543,10842,83545,10346,83547,10848,83550,10851,83552,2006],{},[567,83544,10821],{},[567,83546,10345],{},[527,83548,3396],{"href":83549},"#WordPress-and-MySQL-docker-compose-yml",[567,83551,10821],{},[527,83553,10854],{"href":10854,"rel":83554},[531],[738,83556,83558],{"className":1621,"code":83557,"language":1623,"meta":743,"style":743},"database:\n  image: sameersbn\u002Fmysql:latest\n  environment:\n    DB_NAME: wordpress\n    DB_USER: wordpress\n    DB_PASS: wordpress\n    DB_REMOTE_ROOT_NAME: root\n    DB_REMOTE_ROOT_PASS: workshop\n  volumes:\n    - \"\u002Fopt\u002Fdocker\u002Fdatabase:\u002Fvar\u002Flib\u002Fmysql:rw\"\n# wordpress image configuration see https:\u002F\u002Fhub.docker.com\u002F_\u002Fwordpress\u002F\nwordpress:\n  image: wordpress\n  links:\n    - __BLANK__:mysql\n  ports:\n    - 8080:80\n  environment:\n    WORDPRESS_DB_HOST: __BLANK__:3306\n    WORDPRESS_DB_NAME: __BLANK__\n    WORDPRESS_DB_USER: __BLANK__\n    WORDPRESS_DB_PASSWORD: __BLANK__\n    WORDPRESS_AUTH_KEY: SECURE_AUTH_KEY\n    WORDPRESS_LOGGED_IN_KEY: SECURE_LOGGED_IN_KEY\n    WORDPRESS_AUTH_SALT: SECURE_AUTH_SALT\n    WORDPRESS_LOGGED_IN_SALT: SECURE_LOGGED_IN_SALT\n# phpmyadmin image configuration see https:\u002F\u002Fhub.docker.com\u002Fr\u002Fphpmyadmin\u002Fphpmyadmin\u002F\nphpmyadmin:\n  image: phpmyadmin\u002Fphpmyadmin\n  links:\n    - mysql:database\n  ports:\n    - 8181:80\n  environment:\n    PMA_HOST: mysql\n    PMA_USER: root\n    PMA_PASSWORD: workshop\n",[567,83559,83560,83565,83572,83577,83584,83591,83598,83605,83612,83617,83627,83632,83637,83643,83648,83655,83660,83666,83670,83677,83684,83691,83698,83705,83712,83719,83726,83731,83736,83742,83746,83753,83757,83763,83767,83774,83781],{"__ignoreMap":743},[747,83561,83562],{"class":749,"line":750},[747,83563,83564],{"class":1630},"database:\n",[747,83566,83567,83569],{"class":749,"line":761},[747,83568,49331],{"class":1630},[747,83570,83571],{"class":802}," sameersbn\u002Fmysql:latest\n",[747,83573,83574],{"class":749,"line":769},[747,83575,83576],{"class":1630},"  environment:\n",[747,83578,83579,83582],{"class":749,"line":776},[747,83580,83581],{"class":1630},"    DB_NAME:",[747,83583,6540],{"class":802},[747,83585,83586,83589],{"class":749,"line":784},[747,83587,83588],{"class":1630},"    DB_USER:",[747,83590,6540],{"class":802},[747,83592,83593,83596],{"class":749,"line":790},[747,83594,83595],{"class":1630},"    DB_PASS:",[747,83597,6540],{"class":802},[747,83599,83600,83603],{"class":749,"line":796},[747,83601,83602],{"class":1630},"    DB_REMOTE_ROOT_NAME:",[747,83604,11156],{"class":802},[747,83606,83607,83610],{"class":749,"line":806},[747,83608,83609],{"class":1630},"    DB_REMOTE_ROOT_PASS:",[747,83611,11166],{"class":802},[747,83613,83614],{"class":749,"line":814},[747,83615,83616],{"class":1630},"  volumes:\n",[747,83618,83619,83621,83623,83625],{"class":749,"line":822},[747,83620,18665],{"class":1630},[747,83622,969],{"class":757},[747,83624,49135],{"class":802},[747,83626,975],{"class":757},[747,83628,83629],{"class":749,"line":830},[747,83630,83631],{"class":772},"# wordpress image configuration see https:\u002F\u002Fhub.docker.com\u002F_\u002Fwordpress\u002F\n",[747,83633,83634],{"class":749,"line":836},[747,83635,83636],{"class":1630},"wordpress:\n",[747,83638,83639,83641],{"class":749,"line":842},[747,83640,49331],{"class":1630},[747,83642,6540],{"class":802},[747,83644,83645],{"class":749,"line":850},[747,83646,83647],{"class":1630},"  links:\n",[747,83649,83650,83652],{"class":749,"line":863},[747,83651,18665],{"class":1630},[747,83653,83654],{"class":802}," __BLANK__:mysql\n",[747,83656,83657],{"class":749,"line":869},[747,83658,83659],{"class":1630},"  ports:\n",[747,83661,83662,83664],{"class":749,"line":877},[747,83663,18665],{"class":1630},[747,83665,11000],{"class":802},[747,83667,83668],{"class":749,"line":1015},[747,83669,83576],{"class":1630},[747,83671,83672,83675],{"class":749,"line":1021},[747,83673,83674],{"class":1630},"    WORDPRESS_DB_HOST:",[747,83676,11016],{"class":802},[747,83678,83679,83682],{"class":749,"line":1027},[747,83680,83681],{"class":1630},"    WORDPRESS_DB_NAME:",[747,83683,10361],{"class":802},[747,83685,83686,83689],{"class":749,"line":1033},[747,83687,83688],{"class":1630},"    WORDPRESS_DB_USER:",[747,83690,10361],{"class":802},[747,83692,83693,83696],{"class":749,"line":1039},[747,83694,83695],{"class":1630},"    WORDPRESS_DB_PASSWORD:",[747,83697,10361],{"class":802},[747,83699,83700,83703],{"class":749,"line":1054},[747,83701,83702],{"class":1630},"    WORDPRESS_AUTH_KEY:",[747,83704,11053],{"class":802},[747,83706,83707,83710],{"class":749,"line":1060},[747,83708,83709],{"class":1630},"    WORDPRESS_LOGGED_IN_KEY:",[747,83711,11063],{"class":802},[747,83713,83714,83717],{"class":749,"line":1066},[747,83715,83716],{"class":1630},"    WORDPRESS_AUTH_SALT:",[747,83718,11073],{"class":802},[747,83720,83721,83724],{"class":749,"line":1081},[747,83722,83723],{"class":1630},"    WORDPRESS_LOGGED_IN_SALT:",[747,83725,11083],{"class":802},[747,83727,83728],{"class":749,"line":1087},[747,83729,83730],{"class":772},"# phpmyadmin image configuration see https:\u002F\u002Fhub.docker.com\u002Fr\u002Fphpmyadmin\u002Fphpmyadmin\u002F\n",[747,83732,83733],{"class":749,"line":1102},[747,83734,83735],{"class":1630},"phpmyadmin:\n",[747,83737,83738,83740],{"class":749,"line":1110},[747,83739,49331],{"class":1630},[747,83741,11117],{"class":802},[747,83743,83744],{"class":749,"line":1117},[747,83745,83647],{"class":1630},[747,83747,83748,83750],{"class":749,"line":1123},[747,83749,18665],{"class":1630},[747,83751,83752],{"class":802}," mysql:database\n",[747,83754,83755],{"class":749,"line":1129},[747,83756,83659],{"class":1630},[747,83758,83759,83761],{"class":749,"line":1142},[747,83760,18665],{"class":1630},[747,83762,11130],{"class":802},[747,83764,83765],{"class":749,"line":1150},[747,83766,83576],{"class":1630},[747,83768,83769,83772],{"class":749,"line":1157},[747,83770,83771],{"class":1630},"    PMA_HOST:",[747,83773,11146],{"class":802},[747,83775,83776,83779],{"class":749,"line":1163},[747,83777,83778],{"class":1630},"    PMA_USER:",[747,83780,11156],{"class":802},[747,83782,83783,83786],{"class":749,"line":1168},[747,83784,83785],{"class":1630},"    PMA_PASSWORD:",[747,83787,11166],{"class":802},[6072,83789,83790,83794],{},[523,83791,83792],{},[584,83793,2957],{},[668,83795,83796,83800,83804,83808,83812],{},[638,83797,83798,49326],{},[567,83799,49325],{},[638,83801,83802,11216],{},[567,83803,11215],{},[638,83805,83806,11222],{},[567,83807,11221],{},[638,83809,83810,11228],{},[567,83811,11227],{},[638,83813,83814,11234,83816,3052],{},[567,83815,11233],{},[567,83817,11237],{},[523,83819,49352,83820,587,83822,83824],{},[567,83821,49355],{},[567,83823,49358],{},", so that Admin can access the MySQL server.",[535,83826,11247],{"id":11246},[6072,83828,83829],{},[523,83830,83831,8939,83833],{},[584,83832,2951],{},[527,83834,83836],{"href":11254,"rel":83835},[531],[567,83837,11258],{},[523,83839,11261,83840,11264],{},[567,83841,10821],{},[738,83843,83844],{"className":1621,"code":11267,"language":1623,"meta":743,"style":743},[567,83845,83846],{"__ignoreMap":743},[747,83847,83848,83850,83852,83854],{"class":749,"line":750},[747,83849,2936],{"class":1630},[747,83851,1934],{"class":802},[747,83853,11278],{"class":802},[747,83855,11281],{"class":802},[6072,83857,83858,83862],{},[523,83859,83860],{},[584,83861,2957],{},[668,83863,83864,83870,83880],{},[638,83865,83866,11292,83868,11295],{},[567,83867,2936],{},[567,83869,2936],{},[638,83871,83872,11301,83874,11304,83876,11308,83878,11311],{},[567,83873,11300],{},[567,83875,10821],{},[567,83877,11307],{},[567,83879,2936],{},[638,83881,83882,83884,83885],{},[567,83883,11316],{}," - Starts the containers defined in the given docker-compose file.\n",[584,83886,3521],{},[523,83888,11320,83889,11324,83891,5845,83893,11329],{},[567,83890,11323],{},[567,83892,5812],{},[567,83894,5841],{},[535,83896,11333,83897,11336],{"id":11332},[567,83898,2936],{},[523,83900,11339,83901,11342,83903,11295],{},[567,83902,2936],{},[567,83904,2936],{},[613,83906,11348,83907,11351],{"id":11347},[567,83908,2936],{},[523,83910,11354,83911,11357,83913,11361,83915,11311],{},[567,83912,11316],{},[567,83914,11360],{},[567,83916,2936],{},[738,83918,83919],{"className":1621,"code":11366,"language":1623,"meta":743,"style":743},[567,83920,83921],{"__ignoreMap":743},[747,83922,83923,83925,83927,83929],{"class":749,"line":750},[747,83924,2936],{"class":1630},[747,83926,5324],{"class":802},[747,83928,9736],{"class":802},[747,83930,11379],{"class":802},[6072,83932,83933,83937],{},[523,83934,83935],{},[584,83936,2957],{},[668,83938,83939,83943],{},[638,83940,83941,11390],{},[567,83942,11360],{},[638,83944,83945,11396],{},[567,83946,11395],{},[613,83948,11400,83949,11351],{"id":11399},[567,83950,2936],{},[523,83952,11405,83953,11408,83955,11412,83957,11415],{},[567,83954,11316],{},[567,83956,11411],{},[567,83958,2936],{},[738,83960,83961],{"className":1621,"code":11418,"language":1623,"meta":743,"style":743},[567,83962,83963],{"__ignoreMap":743},[747,83964,83965,83967,83969,83971,83973],{"class":749,"line":750},[747,83966,2936],{"class":1630},[747,83968,1934],{"class":802},[747,83970,11278],{"class":802},[747,83972,5902],{"class":802},[747,83974,11433],{"class":802},[6072,83976,83977,83981],{},[523,83978,83979],{},[584,83980,2957],{},[668,83982,83983,83989],{},[638,83984,83985,11444,83987,11311],{},[567,83986,11411],{},[567,83988,2936],{},[638,83990,83991,11452],{},[567,83992,11451],{},[613,83994,11456,83995,11351],{"id":11455},[567,83996,2936],{},[523,83998,11461,83999,11464],{},[567,84000,2936],{},[738,84002,84003],{"className":1621,"code":11467,"language":1623,"meta":743,"style":743},[567,84004,84005],{"__ignoreMap":743},[747,84006,84007,84009,84011,84013],{"class":749,"line":750},[747,84008,2936],{"class":1630},[747,84010,1934],{"class":802},[747,84012,11278],{"class":802},[747,84014,11480],{"class":802},[6072,84016,84017,84021],{},[523,84018,84019],{},[584,84020,2957],{},[668,84022,84023],{},[638,84024,84025,11444,84027,11311],{},[567,84026,11491],{},[567,84028,2936],{},[535,84030,11497,84031,11500],{"id":11496},[567,84032,2936],{},[6072,84034,84035,84051,84055],{},[523,84036,84037,8939,84039,84044,84045,11517,84047,11520,84049,11523],{},[584,84038,2951],{},[527,84040,84042],{"href":11507,"rel":84041},[531],[567,84043,11511],{},"\nThe task contains other ",[567,84046,10821],{},[567,84048,10821],{},[567,84050,2936],{},[523,84052,84053],{},[584,84054,9515],{},[523,84056,49725,84057,11531,84059,11534],{},[567,84058,9779],{},[567,84060,10821],{},[535,84062,11538],{"id":11537},[523,84064,11541,84065,11544],{},[567,84066,10821],{},[2979,84068],{},[79989,84070,11671],{"id":11670},[523,84072,84073],{},[3049,84074,11676],{},[535,84076,84077],{"id":11679},"A wild Docker Swarm appeared. Kubernetes used rolling-update. It was very effective.",[523,84079,11683],{},[668,84081,84082,84084],{},[638,84083,11688],{},[638,84085,11697],{},[523,84087,84088],{},"My favorite choice is Kubernetes, easy to use, developed by Google (one of the largest and longest container users) and now with the latest updates, can scale up to 1000+ nodes.\nI like Kubernetes more, because it offers a rolling-update feature. Allowing you to update your application Pod by Pod.",[523,84090,11703],{},[535,84092,11707],{"id":11706},[668,84094,84095,84101,84106,84111,84116],{},[638,84096,84097],{},[527,84098,11722],{"href":84099,"rel":84100},"http:\u002F\u002Fmesos.apache.org\u002F",[531],[638,84102,84103],{},[527,84104,11735],{"href":11733,"rel":84105},[531],[638,84107,84108],{},[527,84109,11742],{"href":11740,"rel":84110},[531],[638,84112,84113],{},[527,84114,11728],{"href":3037,"rel":84115},[531],[638,84117,84118],{},"And many more",[2979,84120],{},[79989,84122,84124],{"id":84123},"kubessar-glossar-but-for-kubernetes","Kubessar - Glossar but for Kubernetes",[523,84126,84127],{},[3049,84128,84129],{},"Like a glossar, but for Kubernetes stuff.",[523,84131,84132],{},"I highly recommend you to look through my Kubernetes presentation to get to know Kubernetes a bit better, before starting to work with it.\nPlease note, that the presentation is written in german.",[535,84134,22320],{"id":29981},[523,84136,84137,84138,38346],{},"Separation of resources. Allowing for quotas per namespace.\nWhen not specifying a namespace, the ",[567,84139,2014],{},[535,84141,38350,84142,2006],{"id":38349},[567,84143,38353],{},[523,84145,84146],{},"A set of one or more containers.",[535,84148,84150,84151,2006],{"id":84149},"replication-controller-rc","Replication Controller (",[567,84152,84153],{},"rc",[523,84155,84156],{},"A ReplicationController ensures that there are always the specific number of replica of a given Pod.",[535,84158,38392,84159,2006],{"id":38391},[567,84160,38395],{},[523,84162,84163],{},"Exposed ports of one or multiple pods. The access to the port(s) is \"loadbalanced\" using iptables.\nA service also creates a A and SRV DNS record, when using the kubedns Pod.",[535,84165,84166],{"id":38458},"Other \"Objects\"",[668,84168,84169,84174],{},[638,84170,84171,84172,11295],{},"kubeclt Files - \"Deployment\" files for \"objects\" of Kubernetes. Can be \"deployed\"\u002Frun\u002Fexecuted using the ",[567,84173,15269],{},[638,84175,84176],{},"ResourceQuotas - Resource quotas for a namespace.",[2979,84178],{},[79989,84180,124],{"id":1317},[523,84182,84183],{},[3069,84184],{"alt":27731,"src":27584},[535,84186,84188],{"id":84187},"kubernetes-features","Kubernetes Features",[613,84190,8764,84192,84194],{"id":84191},"the-iptables-rules-will-blow-your-mind",[567,84193,8254],{}," rules will blow your mind",[523,84196,84197,84198,84200,84201,84203],{},"If you have already worked with the basics of ",[567,84199,8254],{},", this will blow your mind, a lot more is possible with ",[567,84202,8254],{}," than you thought.",[613,84205,84207],{"id":84206},"you-have-some-network-volumes","You have some Network Volumes?",[523,84209,84210],{},"No problem, Kubernetes allows you to specify volumes that are network volumes and mount them by a simple name.\nYou could even use the volume claim system. Where a Pod just says, I need X GB storage and Kubernetes does the rest for you.",[523,84212,84213],{},"(As long as the specific mount binaries are installed on every server, this will work with no problems)",[613,84215,27792],{"id":27791},[668,84217,84218,84221,84224,84227],{},[638,84219,84220],{},"Loadbalanceing for L4 and L7",[638,84222,84223],{},"L7 https termination",[638,84225,84226],{},"Autoscaling of Replication Controller",[638,84228,84229],{},"And more features already there and to come",[79989,84231,84233],{"id":84232},"kubectl-our-tool-to-deploy-them-all","kubectl - Our tool to deploy them all",[523,84235,84236,84240],{},[3069,84237],{"alt":84238,"src":84239},"Kubernetes Zelda - It's dangerous to go alone","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Fkubernetes-its-dangerous-to-go-alone.png","\n_Zelda Meme intensifies_",[535,84242,38503,84243],{"id":38502},[567,84244,15269],{},[523,84246,8764,84247,38510],{},[567,84248,15269],{},[613,84250,84252],{"id":84251},"list-objects","List objects",[523,84254,84255],{},"To view all Pods in all namespaces.",[738,84257,84259],{"className":1621,"code":84258,"language":1623,"meta":743,"style":743},"kubectl get --all-namespaces pods\n",[567,84260,84261],{"__ignoreMap":743},[747,84262,84263,84265,84267,84270],{"class":749,"line":750},[747,84264,15269],{"class":1630},[747,84266,1951],{"class":802},[747,84268,84269],{"class":802}," --all-namespaces",[747,84271,1958],{"class":802},[6072,84273,84274,84278],{},[523,84275,84276],{},[584,84277,2957],{},[668,84279,84280,84284,84288,84292],{},[638,84281,84282,38548],{},[567,84283,15269],{},[638,84285,84286,38554],{},[567,84287,38553],{},[638,84289,84290,38565],{},[567,84291,38564],{},[638,84293,84294,84296],{},[567,84295,38570],{}," - Show only pods (Can be a comma seperated list of types, short forms are available).",[613,84298,38598],{"id":38597},[523,84300,84301],{},"Get informations about one or more object(s).",[738,84303,84304],{"className":1621,"code":38604,"language":1623,"meta":743,"style":743},[567,84305,84306],{"__ignoreMap":743},[747,84307,84308,84310,84312,84314,84316,84318,84320],{"class":749,"line":750},[747,84309,15269],{"class":1630},[747,84311,38613],{"class":802},[747,84313,38616],{"class":802},[747,84315,38619],{"class":802},[747,84317,38622],{"class":1640},[747,84319,5685],{"class":802},[747,84321,3600],{"class":1640},[6072,84323,84324,84328],{},[523,84325,84326],{},[584,84327,2957],{},[668,84329,84330,84334,84338,84347],{},[638,84331,84332,38640],{},[567,84333,38639],{},[638,84335,84336,38646],{},[567,84337,38645],{},[638,84339,84340,38652,84342,714,84344,84346],{},[567,84341,38651],{},[567,84343,38655],{},[567,84345,84153],{}," (for replication controller).",[638,84348,84349,38663,84351,1909],{},[567,84350,2230],{},[567,84352,6725],{},[613,84354,84356],{"id":84355},"create-one-or-more-objects","Create one or more object(s)",[523,84358,84359,84360,10199],{},"To deploy\u002Fexecute a \"kubectl\" file, we use the ",[567,84361,38675],{},[738,84363,84364],{"className":1621,"code":66581,"language":1623,"meta":743,"style":743},[567,84365,84366],{"__ignoreMap":743},[747,84367,84368,84370,84372,84374],{"class":749,"line":750},[747,84369,15269],{"class":1630},[747,84371,1925],{"class":802},[747,84373,1934],{"class":802},[747,84375,38705],{"class":802},[6072,84377,84378,84382],{},[523,84379,84380],{},[584,84381,2957],{},[668,84383,84384,84389],{},[638,84385,84386,84388],{},[567,84387,38675],{}," - Creates an object.",[638,84390,84391,38724,84393,38727],{},[567,84392,38723],{},[567,84394,3361],{},[613,84396,38819],{"id":38818},[523,84398,84399,84400,10199],{},"To stop\u002Fdelete one or more object(s), there's the ",[567,84401,38825],{},[738,84403,84404],{"className":1621,"code":38829,"language":1623,"meta":743,"style":743},[567,84405,84406],{"__ignoreMap":743},[747,84407,84408,84410,84412,84414],{"class":749,"line":750},[747,84409,15269],{"class":1630},[747,84411,38838],{"class":802},[747,84413,1934],{"class":802},[747,84415,38705],{"class":802},[6072,84417,84418,84422],{},[523,84419,84420],{},[584,84421,2957],{},[668,84423,84424,84428],{},[638,84425,84426,38855],{},[567,84427,38825],{},[638,84429,84430,38724,84432,38727],{},[567,84431,38723],{},[567,84433,3361],{},[523,84435,84436],{},[584,84437,38866],{},[738,84439,84440],{"className":1621,"code":38869,"language":1623,"meta":743,"style":743},[567,84441,84442],{"__ignoreMap":743},[747,84443,84444,84446,84448,84450,84452,84454],{"class":749,"line":750},[747,84445,15269],{"class":1630},[747,84447,38838],{"class":802},[747,84449,38619],{"class":802},[747,84451,38622],{"class":1640},[747,84453,5685],{"class":802},[747,84455,3600],{"class":1640},[6072,84457,84458,84462],{},[523,84459,84460],{},[584,84461,2957],{},[668,84463,84464,84468,84476],{},[638,84465,84466,38855],{},[567,84467,38825],{},[638,84469,84470,38652,84472,714,84474,84346],{},[567,84471,38651],{},[567,84473,38655],{},[567,84475,84153],{},[638,84477,84478,38663,84480,1909],{},[567,84479,2230],{},[567,84481,6725],{},[613,84483,38915],{"id":38914},[523,84485,38918,84486,38922,84488,1909],{},[567,84487,38921],{},[567,84489,7110],{},[738,84491,84493],{"className":1621,"code":84492,"language":1623,"meta":743,"style":743},"kubectl exec POD_NAME OPTIONS (-c CONTAINER_NAME) COMMAND\n",[567,84494,84495],{"__ignoreMap":743},[747,84496,84497,84499,84501,84503,84505,84507,84509],{"class":749,"line":750},[747,84498,15269],{"class":1630},[747,84500,2586],{"class":802},[747,84502,33170],{"class":802},[747,84504,38938],{"class":802},[747,84506,38943],{"class":1640},[747,84508,6446],{"class":802},[747,84510,38948],{"class":1640},[6072,84512,84513,84517],{},[523,84514,84515],{},[584,84516,2957],{},[668,84518,84519,84523,84529,84535,84540],{},[638,84520,84521,38855],{},[567,84522,38921],{},[638,84524,84525,38663,84527,1909],{},[567,84526,2230],{},[567,84528,6725],{},[638,84530,84531,38966,84533,38969],{},[567,84532,38965],{},[567,84534,7184],{},[638,84536,84537,84539],{},[567,84538,33145],{}," - Optional. If the specified pod has more than one container, then it is required.",[638,84541,84542,38985],{},[567,84543,4256],{},[613,84545,38998],{"id":38997},[523,84547,8764,84548,39004,84550,1909],{},[567,84549,39003],{},[567,84551,4174],{},[738,84553,84554],{"className":1621,"code":39010,"language":1623,"meta":743,"style":743},[567,84555,84556],{"__ignoreMap":743},[747,84557,84558,84560,84562,84564,84566,84568,84570],{"class":749,"line":750},[747,84559,15269],{"class":1630},[747,84561,17595],{"class":802},[747,84563,38938],{"class":802},[747,84565,33170],{"class":802},[747,84567,38943],{"class":1640},[747,84569,6446],{"class":802},[747,84571,38948],{"class":1640},[6072,84573,84574,84578],{},[523,84575,84576],{},[584,84577,2957],{},[668,84579,84580,84584,84590,84596],{},[638,84581,84582,38855],{},[567,84583,38921],{},[638,84585,84586,38966,84588,39047],{},[567,84587,38965],{},[567,84589,11451],{},[638,84591,84592,38663,84594,1909],{},[567,84593,2230],{},[567,84595,6725],{},[638,84597,84598,84539],{},[567,84599,33145],{},[535,84601,39069],{"id":39068},[613,84603,84605],{"id":84604},"update-the-pods-of-a-replication-controller-during-runtime","Update the Pods of a Replication Controller during runtime",[523,84607,8764,84608,84611],{},[567,84609,84610],{},"rolling-update"," subcommand allows to stop one pod after another and replace it with a new instace of the pod.",[738,84613,84615],{"className":1621,"code":84614,"language":1623,"meta":743,"style":743},"kubectl rolling-update REPLICATION -f FILE_NAME\n",[567,84616,84617],{"__ignoreMap":743},[747,84618,84619,84621,84624,84627,84629],{"class":749,"line":750},[747,84620,15269],{"class":1630},[747,84622,84623],{"class":802}," rolling-update",[747,84625,84626],{"class":802}," REPLICATION",[747,84628,1934],{"class":802},[747,84630,38705],{"class":802},[6072,84632,84633,84637],{},[523,84634,84635],{},[584,84636,2957],{},[668,84638,84639,84643,84651],{},[638,84640,84641,39110],{},[567,84642,84610],{},[638,84644,84645,84648,84649,1909],{},[567,84646,84647],{},"REPLICATION"," - The ReplicationController to update with the given ",[567,84650,66599],{},[638,84652,84653,84655,84656,38727],{},[567,84654,38723],{}," - Name of the updated ReplicationController file. Can be one file, a directory or ",[567,84657,3361],{},[613,84659,84661],{"id":84660},"scaling-running-replication-controller","Scaling running Replication Controller",[523,84663,8764,84664,84666],{},[567,84665,39129],{}," subcommand gives you control over the size of running ReplicationController.",[738,84668,84670],{"className":1621,"code":84669,"language":1623,"meta":743,"style":743},"kubectl scale\n",[567,84671,84672],{"__ignoreMap":743},[747,84673,84674,84676],{"class":749,"line":750},[747,84675,15269],{"class":1630},[747,84677,84678],{"class":802}," scale\n",[6072,84680,84681,84685],{},[523,84682,84683],{},[584,84684,2957],{},[668,84686,84687,84691,84697],{},[638,84688,84689,39162],{},[567,84690,39129],{},[638,84692,84693,84696],{},[567,84694,84695],{},"--replicas=X"," - Set the given ReplicationController to X replicas.",[638,84698,84699,6374,84701,84704,84705,38727],{},[567,84700,38723],{},[567,84702,84703],{},"replicationcontrollers FOO"," - Name of the ReplicationController to scale. Can be just the name or one file, a directory or ",[567,84706,3361],{},[2979,84708],{},[79989,84710,35017],{"id":35016},[523,84712,84713],{},[3049,84714,84715],{},"Follow these simple steps and get a Kubernetes cluster up and running fast.",[535,84717,84719],{"id":84718},"install-ansible","Install Ansible",[523,84721,84722],{},[3049,84723,84724],{},"If you use the provided Virtual Box, this step is not needed!",[6072,84726,84727],{},[523,84728,84729,84730,84733],{},"The package ",[567,84731,84732],{},"python-netaddr"," also needs to be installed on the client. Don't forget to install it!!",[523,84735,84736,84737,84742],{},"Please refer to the official ",[527,84738,84741],{"href":84739,"rel":84740},"http:\u002F\u002Fdocs.ansible.com\u002Fansible\u002Fintro_installation.html#installing-the-control-machine",[531],"Ansible Installation Docs"," on how to install Ansible on your machine.",[668,84744,84745,84753,84760],{},[638,84746,84747,84748],{},"For ArchLinux: ",[527,84749,84752],{"href":84750,"rel":84751},"http:\u002F\u002Fdocs.ansible.com\u002Fansible\u002Fintro_installation.html#latest-releases-via-pacman-arch-linux",[531],"Ansible Docs",[638,84754,84755,84756],{},"For Debian: ",[527,84757,84752],{"href":84758,"rel":84759},"http:\u002F\u002Fdocs.ansible.com\u002Fansible\u002Fintro_installation.html#latest-releases-via-apt-ubuntu",[531],[638,84761,84762,84763],{},"For CentOS: ",[527,84764,84752],{"href":84765,"rel":84766},"http:\u002F\u002Fdocs.ansible.com\u002Fansible\u002Fintro_installation.html#latest-release-via-yum",[531],[535,84768,84770],{"id":84769},"create-the-cluster-inventory-file-for-the-deployment","Create the cluster inventory file for the deployment",[6072,84772,84773],{},[523,84774,84775,8939,84777],{},[584,84776,2951],{},[527,84778,84781],{"href":84779,"rel":84780},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-docker\u002Ftree\u002Fmaster\u002Fkubernetes202",[531],[567,84782,30363],{},[523,84784,84785,84786,1909],{},"Enter the task directory and look for a directory called ",[567,84787,84788],{},"ansible\u002F",[523,84790,76786,84791,84794],{},[567,84792,84793],{},"inventory",", in this folder. This file will contain the list\u002Finventory of the servers.\nYou create one line per server in the format below (username and password are valid for the provided vm, change to suit your environment):",[738,84796,84798],{"className":1621,"code":84797,"language":1623,"meta":743,"style":743},"[masters]\n# In most cases the first \"server\"\nSERVER_IP_ADDRESS:SSH_PORT ansible_user=docker ansible_ssh_pass=docker ansible_become_pass=docker\n\n[etcd]\n#Add all the node servers here\nSERVER_IP_ADDRESS:SSH_PORT ansible_user=docker ansible_ssh_pass=docker ansible_become_pass=docker\n[...]\nSERVER_IP_ADDRESS:SSH_PORT ansible_user=docker ansible_ssh_pass=docker ansible_become_pass=docker\n\n[nodes]\n# This can include the master server and the etcd servers too\nSERVER_IP_ADDRESS:SSH_PORT ansible_user=workshop ansible_ssh_pass=workshop ansible_become_pass=workshop\n[...]\nSERVER_IP_ADDRESS:SSH_PORT ansible_user=workshop ansible_ssh_pass=workshop ansible_become_pass=workshop\n",[567,84799,84800,84809,84814,84828,84832,84840,84845,84855,84863,84873,84877,84886,84891,84904,84912],{"__ignoreMap":743},[747,84801,84802,84804,84807],{"class":749,"line":750},[747,84803,4253],{"class":757},[747,84805,84806],{"class":1640},"masters",[747,84808,4268],{"class":757},[747,84810,84811],{"class":749,"line":761},[747,84812,84813],{"class":772},"# In most cases the first \"server\"\n",[747,84815,84816,84819,84822,84825],{"class":749,"line":769},[747,84817,84818],{"class":1630},"SERVER_IP_ADDRESS:SSH_PORT",[747,84820,84821],{"class":802}," ansible_user=docker",[747,84823,84824],{"class":802}," ansible_ssh_pass=docker",[747,84826,84827],{"class":802}," ansible_become_pass=docker\n",[747,84829,84830],{"class":749,"line":776},[747,84831,1255],{"emptyLinePlaceholder":1254},[747,84833,84834,84836,84838],{"class":749,"line":784},[747,84835,4253],{"class":757},[747,84837,26658],{"class":1640},[747,84839,4268],{"class":757},[747,84841,84842],{"class":749,"line":790},[747,84843,84844],{"class":772},"#Add all the node servers here\n",[747,84846,84847,84849,84851,84853],{"class":749,"line":796},[747,84848,84818],{"class":1630},[747,84850,84821],{"class":802},[747,84852,84824],{"class":802},[747,84854,84827],{"class":802},[747,84856,84857,84859,84861],{"class":749,"line":806},[747,84858,4253],{"class":757},[747,84860,5685],{"class":1640},[747,84862,4268],{"class":757},[747,84864,84865,84867,84869,84871],{"class":749,"line":814},[747,84866,84818],{"class":1630},[747,84868,84821],{"class":802},[747,84870,84824],{"class":802},[747,84872,84827],{"class":802},[747,84874,84875],{"class":749,"line":822},[747,84876,1255],{"emptyLinePlaceholder":1254},[747,84878,84879,84881,84884],{"class":749,"line":830},[747,84880,4253],{"class":757},[747,84882,84883],{"class":1640},"nodes",[747,84885,4268],{"class":757},[747,84887,84888],{"class":749,"line":836},[747,84889,84890],{"class":772},"# This can include the master server and the etcd servers too\n",[747,84892,84893,84895,84898,84901],{"class":749,"line":842},[747,84894,84818],{"class":1630},[747,84896,84897],{"class":802}," ansible_user=workshop",[747,84899,84900],{"class":802}," ansible_ssh_pass=workshop",[747,84902,84903],{"class":802}," ansible_become_pass=workshop\n",[747,84905,84906,84908,84910],{"class":749,"line":850},[747,84907,4253],{"class":757},[747,84909,5685],{"class":1640},[747,84911,4268],{"class":757},[747,84913,84914,84916,84918,84920],{"class":749,"line":863},[747,84915,84818],{"class":1630},[747,84917,84897],{"class":802},[747,84919,84900],{"class":802},[747,84921,84903],{"class":802},[6072,84923,84924,84928],{},[523,84925,84926],{},[584,84927,2957],{},[668,84929,84930,84936,84944,84950,84956],{},[638,84931,84932,84935],{},[567,84933,84934],{},"[GROUP_NAME]"," - Specifies a server\u002Finventory group.",[638,84937,84938,19221,84940,84943],{},[567,84939,84818],{},[567,84941,84942],{},"SSH_PORT"," is optional. A hostname or ip address the server is reachable.",[638,84945,84946,84949],{},[567,84947,84948],{},"ansible_user"," - Specifies the SSH username to login with.",[638,84951,84952,84955],{},[567,84953,84954],{},"ansible_ssh_pass"," - SSH user password.",[638,84957,84958,84961],{},[567,84959,84960],{},"ansible_become_pass"," - The sudo (default) password.",[523,84963,84964,84965,84968],{},"If you have created your inventory properly, run ",[567,84966,84967],{},".\u002Fsetup.sh --syntax-check"," to check for any syntax errors.",[523,84970,84971],{},"No syntax errors? Let's deploy the cluster!",[535,84973,84975],{"id":84974},"deploying-the-kubernetes-cluster","Deploying the Kubernetes cluster",[6072,84977,84978],{},[523,84979,84980,8939,84982,84987,8287,84990,8287,84992,8287,84995,8287,84997],{},[584,84981,2951],{},[527,84983,84985],{"href":84779,"rel":84984},[531],[567,84986,30363],{},[584,84988,84989],{},"The servers must have the",[584,84991,20515],{},[584,84993,84994],{},"and",[584,84996,84732],{},[584,84998,84999],{},"package installed!",[523,85001,85002,85003,85005,85006,85009],{},"Before you continue, enter the task ",[567,85004,30363],{}," directory. Execute the bash ",[567,85007,85008],{},"prepare.sh"," script. The script will download and setup all files required for the deployment of the cluster.\nIf the script exits with an error, please get in touch with me (It should normally not exit with an error).",[523,85011,85012,85013,85016,85017,85020,85021,6378,85024,85026],{},"Go into the ",[567,85014,85015],{},"kubernetes\u002Fcontrib\u002Fansible"," directory and execute the ",[567,85018,85019],{},".\u002Fsetup.sh"," with the following argument ",[567,85022,85023],{},"-vvvv",[567,85025,85023],{}," is for verbose output), this will setup Kubernetes on the machines in the inventory.",[523,85028,85029],{},"When you have done everything correct, it should go through without any errors.",[523,85031,85032,85033,85035],{},"After the deployment, please wait up to 10 minutes before continuing.\nThis waiting time is for giving the Kubernetes cluster some time to download all required images and start all ",[567,85034,2101],{}," containers.\nIf you want to be 100% safe, wait up to 15 minutes. Thanks!",[523,85037,85038],{},"After you have waited some time, please power cycle server after server.",[535,85040,85042],{"id":85041},"summary-of-the-kubernetes-deployment","Summary of the Kubernetes deployment",[523,85044,85045,85046,8287,85049,3052],{},"We now have a working Kubernetes cluster (",[584,85047,85048],{},"DON'T use this setup in production though!",[3049,85050,85051],{},"There is more work required to make it secure for production use.",[523,85053,85054],{},"We are now ready to deploy objects\u002Fcontainers on to our Kubernetes cluster. :)",[535,85056,37475],{"id":37474},[6072,85058,85059],{},[523,85060,85061,8939,85063],{},[584,85062,2951],{},[527,85064,85067],{"href":85065,"rel":85066},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-docker\u002Ftree\u002Fmaster\u002Fkubernetes101",[531],[567,85068,29729],{},[523,85070,37491,85071,37494,85073,37498],{},[567,85072,29729],{},[567,85074,37497],{},[738,85076,85077],{"className":1621,"code":38071,"language":1623,"meta":743,"style":743},[567,85078,85079,85085,85091,85095,85101,85107,85111,85115,85123,85129,85135,85145,85151,85157],{"__ignoreMap":743},[747,85080,85081,85083],{"class":749,"line":750},[747,85082,23195],{"class":1630},[747,85084,22608],{"class":802},[747,85086,85087,85089],{"class":749,"line":761},[747,85088,23230],{"class":1630},[747,85090,28795],{"class":802},[747,85092,85093],{"class":749,"line":769},[747,85094,23238],{"class":1630},[747,85096,85097,85099],{"class":749,"line":776},[747,85098,23251],{"class":1630},[747,85100,37526],{"class":802},[747,85102,85103,85105],{"class":749,"line":784},[747,85104,23215],{"class":1630},[747,85106,7736],{"class":802},[747,85108,85109],{"class":749,"line":790},[747,85110,37531],{"class":1630},[747,85112,85113],{"class":749,"line":796},[747,85114,37536],{"class":1630},[747,85116,85117,85119,85121],{"class":749,"line":806},[747,85118,1721],{"class":1630},[747,85120,37543],{"class":802},[747,85122,37526],{"class":802},[747,85124,85125,85127],{"class":749,"line":814},[747,85126,37550],{"class":4574},[747,85128,758],{"class":802},[747,85130,85131,85133],{"class":749,"line":822},[747,85132,799],{"class":1630},[747,85134,37559],{"class":802},[747,85136,85137,85139,85141,85143],{"class":749,"line":830},[747,85138,799],{"class":1630},[747,85140,969],{"class":757},[747,85142,37568],{"class":802},[747,85144,975],{"class":757},[747,85146,85147,85149],{"class":749,"line":836},[747,85148,37575],{"class":1630},[747,85150,37578],{"class":802},[747,85152,85153,85155],{"class":749,"line":842},[747,85154,37583],{"class":1630},[747,85156,37526],{"class":802},[747,85158,85159,85161],{"class":749,"line":850},[747,85160,37590],{"class":1630},[747,85162,25548],{"class":802},[523,85164,85165,85166,37627],{},"The syntax of a \"kubectl\" file, is similar to the syntax of ",[567,85167,2936],{},[523,85169,85170,85171,85173],{},"Connect to the Kubernetes master server. Create the busybox container by running the ",[567,85172,37497],{}," file, wait some seconds and then run the following command:",[738,85175,85177],{"className":1621,"code":85176,"language":1623,"meta":743,"style":743},"kubectl exec busybox -- nslookup kubernetes\n",[567,85178,85179],{"__ignoreMap":743},[747,85180,85181,85183,85185,85187,85189,85192],{"class":749,"line":750},[747,85182,15269],{"class":1630},[747,85184,2586],{"class":802},[747,85186,37668],{"class":802},[747,85188,2592],{"class":802},[747,85190,85191],{"class":802}," nslookup",[747,85193,18560],{"class":802},[523,85195,85196],{},"The output should look like this:",[6072,85198,85199],{},[523,85200,85201],{},[584,85202,3673],{},[523,85204,85205],{},"If the output shows an error, something went wrong, please contact me.",[523,85207,85208],{},"No errors? Good move on to the next section.",[535,85210,85212,85213,68830],{"id":85211},"take-a-look-at-the-pre-installed-kube-system-containers","Take a look at the pre-installed ",[567,85214,2101],{},[523,85216,85217],{},"Open a ssh tunnel, to the Kubernetes master:",[738,85219,85221],{"className":1621,"code":85220,"language":1623,"meta":743,"style":743},"ssh -L 8080:127.0.0.1:8080 -fN SERVER_IP_ADDRESS_HERE\n",[567,85222,85223],{"__ignoreMap":743},[747,85224,85225,85227,85229,85232,85235],{"class":749,"line":750},[747,85226,78686],{"class":1630},[747,85228,40190],{"class":802},[747,85230,85231],{"class":802}," 8080:127.0.0.1:8080",[747,85233,85234],{"class":802}," -fN",[747,85236,85237],{"class":802}," SERVER_IP_ADDRESS_HERE\n",[523,85239,85240,85241,85245],{},"Open your browser and navigate to ",[527,85242,85243],{"href":85243,"rel":85244},"http:\u002F\u002F127.0.0.1:8080\u002F",[531],".\nWelcome to the Kubernetes API!",[6072,85247,85248],{},[523,85249,85250,85252,85253],{},[584,85251,6189],{}," You can close the ssh tunnel, by simply killing the ssh tunnel process.\nYou can find it using ",[567,85254,85255],{},"ps ax",[613,85257,85259],{"id":85258},"kubernetes-own-dashboard","Kubernetes own Dashboard",[523,85261,85262,85263,85267],{},"Navigate to ",[527,85264,85265],{"href":85265,"rel":85266},"http:\u002F\u002F127.0.0.1:8080\u002Fui",[531]," and look around in the dashboard.",[6072,85269,85270,85279],{},[523,85271,85272,85274,85278],{},[584,85273,3673],{},[3069,85275],{"alt":85276,"src":85277},"Kubernetes Dashboard UI Example","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Fkubernetes-dashboard-ui.png","\nIn the above picture, I have already some ReplicationController running on the cluster.",[523,85280,85281,85285,85286,85289,85290,32159],{},[3069,85282],{"alt":85283,"src":85284},"Kubernetes Dashboard kube-dns RC overview","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Fkubernetes-dashboard-ui-rc-overview-dns.png","\nThe above picture shows the overview page of the ",[567,85287,85288],{},"kube-dns-v11"," replication controller in the ",[567,85291,2101],{},[523,85293,85294],{},"Just navigate around in the dashboard and see for yourself what you can do.",[613,85296,85298],{"id":85297},"monitoring-the-nodes-and-containers-with-heapster-and-grafana","Monitoring the nodes and containers (with Heapster and Grafana)",[523,85300,85262,85301,1909],{},[527,85302,85303],{"href":85303,"rel":85304},"http:\u002F\u002F127.0.0.1:8080\u002Fapi\u002Fv1\u002Fproxy\u002Fnamespaces\u002Fkube-system\u002Fservices\u002Fmonitoring-grafana\u002F",[531],[6072,85306,85307,85314,85316],{},[523,85308,85309,85313],{},[3069,85310],{"alt":85311,"src":85312},"Kubernetes Grafana Cluster Node01 Overview","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Fkubernetes-grafana-cluster-overview.png","\nOverview over the first workshop node usage.",[2979,85315],{},[523,85317,85318,85322,85323,85326,85327,1909],{},[3069,85319],{"alt":85320,"src":85321},"Kubernetes Grafana Pods kube-dns Overview","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Fkubernetes-grafana-pods-kube-dns.png","\nOverview over Pod ",[567,85324,85325],{},"monitoring-influxdb-grafana"," in namespace ",[567,85328,2101],{},[523,85330,85331],{},"Basic monitoring of the cluster nodes, out of the box.\nYou can see data for your cluster nodes, down to every single Pod.",[523,85333,85334,85335,85338],{},"Grafana may not work from the begining, but you can easily fix this by changing the data source to type ",[567,85336,85337],{},"direct"," and the url to:",[738,85340,85342],{"className":1621,"code":85341,"language":1623,"meta":743,"style":743},"http:\u002F\u002F127.0.0.1:8080\u002Fapi\u002Fv1\u002Fproxy\u002Fnamespaces\u002Fkube-system\u002Fservices\u002Fmonitoring-influxdb:api\u002F\n",[567,85343,85344],{"__ignoreMap":743},[747,85345,85346],{"class":749,"line":750},[747,85347,85341],{"class":1630},[613,85349,85351],{"id":85350},"all-container-logs-in-one-place-with-an-elk-stack","All Container logs in one place with an ELK stack",[523,85353,85262,85354,1909],{},[527,85355,85356],{"href":85356,"rel":85357},"http:\u002F\u002F127.0.0.1:8080\u002Fapi\u002Fv1\u002Fproxy\u002Fnamespaces\u002Fkube-system\u002Fservices\u002Fkibana-logging\u002F",[531],[523,85359,85360],{},"After you have created the default index in the formular, you should see the Kibana interface.",[6072,85362,85363],{},[523,85364,85365,85369,85370,85372],{},[3069,85366],{"alt":85367,"src":85368},"Kubernetes Kibana Logs","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Fkubernetes-kibana-logs.png","\nThe \"homepage\" of the Kibana running on top of your Kubernetes cluster.\n",[584,85371,6189],{}," It could happen, that the Kibana is a bit slow, that is just because you are not running on real server hardware or fast VM hosts.",[523,85374,85375],{},"You can try searching for specific logs or create visualizations.",[2979,85377],{},[79989,85379,85381],{"id":85380},"deployments-with-kubernetes","Deployments with Kubernetes",[523,85383,8764,85384,85386],{},[567,85385,15269],{}," utility allows us to create objects, in this section I'm going to cover how you can create \"deployment\" files for Kubernetes objects.",[535,85388,38040],{"id":38039},[6072,85390,85391],{},[523,85392,85393,8939,85395],{},[584,85394,2951],{},[527,85396,85399],{"href":85397,"rel":85398},"https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fworkshop-docker\u002Ftree\u002Fmaster\u002Fkubernetes303",[531],[567,85400,37774],{},[523,85402,85403],{},"You have already seen this example, but here again with explanations:",[738,85405,85406],{"className":1621,"code":38071,"language":1623,"meta":743,"style":743},[567,85407,85408,85414,85420,85424,85430,85436,85440,85444,85452,85458,85464,85474,85480,85486],{"__ignoreMap":743},[747,85409,85410,85412],{"class":749,"line":750},[747,85411,23195],{"class":1630},[747,85413,22608],{"class":802},[747,85415,85416,85418],{"class":749,"line":761},[747,85417,23230],{"class":1630},[747,85419,28795],{"class":802},[747,85421,85422],{"class":749,"line":769},[747,85423,23238],{"class":1630},[747,85425,85426,85428],{"class":749,"line":776},[747,85427,23251],{"class":1630},[747,85429,37526],{"class":802},[747,85431,85432,85434],{"class":749,"line":784},[747,85433,23215],{"class":1630},[747,85435,7736],{"class":802},[747,85437,85438],{"class":749,"line":790},[747,85439,37531],{"class":1630},[747,85441,85442],{"class":749,"line":796},[747,85443,37536],{"class":1630},[747,85445,85446,85448,85450],{"class":749,"line":806},[747,85447,1721],{"class":1630},[747,85449,37543],{"class":802},[747,85451,37526],{"class":802},[747,85453,85454,85456],{"class":749,"line":814},[747,85455,37550],{"class":4574},[747,85457,758],{"class":802},[747,85459,85460,85462],{"class":749,"line":822},[747,85461,799],{"class":1630},[747,85463,37559],{"class":802},[747,85465,85466,85468,85470,85472],{"class":749,"line":830},[747,85467,799],{"class":1630},[747,85469,969],{"class":757},[747,85471,37568],{"class":802},[747,85473,975],{"class":757},[747,85475,85476,85478],{"class":749,"line":836},[747,85477,37575],{"class":1630},[747,85479,37578],{"class":802},[747,85481,85482,85484],{"class":749,"line":842},[747,85483,37583],{"class":1630},[747,85485,37526],{"class":802},[747,85487,85488,85490],{"class":749,"line":850},[747,85489,37590],{"class":1630},[747,85491,25548],{"class":802},[6072,85493,85494,85498],{},[523,85495,85496],{},[584,85497,2957],{},[668,85499,85500,85504,85509,85513,85517,85520],{},[638,85501,85502,38171],{},[567,85503,38170],{},[638,85505,85506,85508],{},[567,85507,38176],{}," - Sets the type\u002Fkind of the \"obejct\".",[638,85510,85511,38183],{},[567,85512,38182],{},[638,85514,85515,38189],{},[567,85516,38188],{},[638,85518,85519],{},"Container part see below.",[638,85521,85522,85524],{},[567,85523,38200],{}," - Restart policy. In this case the pod always restarts, until deleted.",[738,85526,85527],{"className":1621,"code":38204,"language":1623,"meta":743,"style":743},[567,85528,85529,85537,85543,85549,85559,85565],{"__ignoreMap":743},[747,85530,85531,85533,85535],{"class":749,"line":750},[747,85532,3361],{"class":1630},[747,85534,37543],{"class":802},[747,85536,37526],{"class":802},[747,85538,85539,85541],{"class":749,"line":761},[747,85540,38219],{"class":4574},[747,85542,758],{"class":802},[747,85544,85545,85547],{"class":749,"line":769},[747,85546,18665],{"class":1630},[747,85548,37559],{"class":802},[747,85550,85551,85553,85555,85557],{"class":749,"line":776},[747,85552,18665],{"class":1630},[747,85554,969],{"class":757},[747,85556,37568],{"class":802},[747,85558,975],{"class":757},[747,85560,85561,85563],{"class":749,"line":784},[747,85562,38242],{"class":1630},[747,85564,37578],{"class":802},[747,85566,85567,85569],{"class":749,"line":790},[747,85568,23251],{"class":1630},[747,85570,37526],{"class":802},[6072,85572,85573,85577],{},[523,85574,85575],{},[584,85576,2957],{},[668,85578,85579,85585,85589,85593],{},[638,85580,85581,38264,85583,38267],{},[567,85582,38263],{},[567,85584,3361],{},[638,85586,85587,38273],{},[567,85588,38272],{},[638,85590,85591,38279],{},[567,85592,38278],{},[638,85594,85595,85597],{},[567,85596,38284],{}," - The name of the container of the pod.",[523,85599,38288,85600,38291],{},[567,85601,10821],{},[535,85603,85605],{"id":85604},"wordpress-and-mysql-pod-example","WordPress and MySQL Pod Example",[523,85607,85608,85609,85612],{},"See the file ",[567,85610,85611],{},"wordpress-mysql\u002Fwordpress-mysql-all-in-one.yaml",".\nThis code block only contains the pods, not the services.",[738,85614,85616],{"className":1621,"code":85615,"language":1623,"meta":743,"style":743},"apiVersion: v1\n# Service object\nkind: Service\nmetadata:\n  labels:\n    name: mysql\n  name: mysql\nspec:\n  ports:\n    # the port that this service should serve on\n    - port: 3306\n  # label keys and values that must match in order to receive traffic for this service\n  selector:\n    # select pods with the name \"mysql\"\n    name: mysql\n---\n# Kubernetes API version\napiVersion: v1\n# Type of \"request\" in this case a Pod\nkind: Pod\n# Metadata of the \"object\"\nmetadata:\n  # Name of the \"object\"\n  name: mysql\n  # Labels of the \"object\"\n  labels:\n    # A lable named \"name\" with value \"mysql\"\n    name: mysql\n# spec ~= Specificationsof the \"object\"\nspec:\n  # List of Container definitions\n  containers:\n    # The \"name\"\u002F\"suffix\" of the container name\n    - name: mysql\n      # What Docker image to use\n      image: sameersbn\u002Fmysql:latest\n      env:\n        - name: DB_NAME\n          value: wordpress\n        - name: DB_USER\n          value: wordpress\n        - name: DB_PASS\n          value: wordpress\n      # List of container ports reachable from within the cluster\n      ports:\n        - containerPort: 3306\n          name: mysql\n---\napiVersion: v1\n# Service object\nkind: Service\nmetadata:\n  # labels for the service\n  labels:\n    name: wordpress\n  # name of the service\n  name: wordpress\nspec:\n  ports:\n    # the port that this service should serve on\n    - port: 80\n  # label keys and values that must match in order to receive traffic for this service\n  selector:\n    # select pods with the name \"wordpress\"\n    name: wordpress\n---\n# Kubernetes API version\napiVersion: v1\n# Type of \"request\"\nkind: Pod\n# Metadata of the \"object\"\nmetadata:\n  # Name of the \"object\"\n  name: wordpress\n  # Labels of the \"object\"\n  labels:\n    # A lable named \"name\" with value \"wordpress\"\n    name: wordpress\n# spec ~= Specifications of the \"object\"\nspec:\n  # List of Container definitions\n  containers:\n    # What Docker image to use\n    - image: wordpress\n      # The \"name\"\u002F\"suffix\" of the container name\n      name: wordpress\n      # List of environment variables\n      env:\n        - name: WORDPRESS_DB_HOST\n          value: mysql.default:3306\n        - name: WORDPRESS_DB_NAME\n          value: wordpress\n        - name: WORDPRESS_DB_USER\n          value: wordpress\n        - name: WORDPRESS_DB_PASSWORD\n          value: wordpress\n        - name: WORDPRESS_AUTH_KEY\n          value: SECURE_AUTH_KEY\n        - name: WORDPRESS_LOGGED_IN_KEY\n          value: SECURE_LOGGED_IN_KEY\n        - name: WORDPRESS_AUTH_SALT\n          value: SECURE_AUTH_SALT\n        - name: WORDPRESS_LOGGED_IN_SALT\n          value: SECURE_LOGGED_IN_SALT\n      # List of ports to \"publish\"\n      ports:\n        # ContainerPort exposes only to the inside of your network, not to the outside\n        # To reach the container we create a cluster wide service\n        - containerPort: 80\n          # gives the port a name\n          name: wordpress\n",[567,85617,85618,85624,85629,85635,85639,85644,85650,85656,85660,85664,85669,85678,85683,85688,85693,85699,85703,85708,85714,85719,85725,85730,85734,85739,85745,85750,85754,85759,85765,85770,85774,85779,85783,85788,85797,85802,85809,85814,85823,85830,85839,85845,85854,85860,85865,85870,85879,85886,85890,85896,85900,85906,85910,85915,85919,85925,85930,85936,85940,85944,85948,85956,85960,85964,85969,85975,85979,85983,85989,85994,86000,86004,86008,86012,86018,86022,86026,86031,86037,86042,86046,86050,86054,86059,86067,86072,86079,86084,86088,86096,86103,86112,86118,86127,86133,86141,86147,86156,86162,86171,86177,86186,86192,86201,86207,86212,86216,86221,86226,86234,86239],{"__ignoreMap":743},[747,85619,85620,85622],{"class":749,"line":750},[747,85621,23195],{"class":1630},[747,85623,22608],{"class":802},[747,85625,85626],{"class":749,"line":761},[747,85627,85628],{"class":772},"# Service object\n",[747,85630,85631,85633],{"class":749,"line":769},[747,85632,23230],{"class":1630},[747,85634,25758],{"class":802},[747,85636,85637],{"class":749,"line":776},[747,85638,23238],{"class":1630},[747,85640,85641],{"class":749,"line":784},[747,85642,85643],{"class":1630},"  labels:\n",[747,85645,85646,85648],{"class":749,"line":790},[747,85647,37583],{"class":1630},[747,85649,11146],{"class":802},[747,85651,85652,85654],{"class":749,"line":796},[747,85653,23251],{"class":1630},[747,85655,11146],{"class":802},[747,85657,85658],{"class":749,"line":806},[747,85659,37531],{"class":1630},[747,85661,85662],{"class":749,"line":814},[747,85663,83659],{"class":1630},[747,85665,85666],{"class":749,"line":822},[747,85667,85668],{"class":772},"    # the port that this service should serve on\n",[747,85670,85671,85673,85676],{"class":749,"line":830},[747,85672,18665],{"class":1630},[747,85674,85675],{"class":802}," port:",[747,85677,30576],{"class":1895},[747,85679,85680],{"class":749,"line":836},[747,85681,85682],{"class":772},"  # label keys and values that must match in order to receive traffic for this service\n",[747,85684,85685],{"class":749,"line":842},[747,85686,85687],{"class":1630},"  selector:\n",[747,85689,85690],{"class":749,"line":850},[747,85691,85692],{"class":772},"    # select pods with the name \"mysql\"\n",[747,85694,85695,85697],{"class":749,"line":863},[747,85696,37583],{"class":1630},[747,85698,11146],{"class":802},[747,85700,85701],{"class":749,"line":869},[747,85702,12808],{"class":1630},[747,85704,85705],{"class":749,"line":877},[747,85706,85707],{"class":772},"# Kubernetes API version\n",[747,85709,85710,85712],{"class":749,"line":1015},[747,85711,23195],{"class":1630},[747,85713,22608],{"class":802},[747,85715,85716],{"class":749,"line":1021},[747,85717,85718],{"class":772},"# Type of \"request\" in this case a Pod\n",[747,85720,85721,85723],{"class":749,"line":1027},[747,85722,23230],{"class":1630},[747,85724,28795],{"class":802},[747,85726,85727],{"class":749,"line":1033},[747,85728,85729],{"class":772},"# Metadata of the \"object\"\n",[747,85731,85732],{"class":749,"line":1039},[747,85733,23238],{"class":1630},[747,85735,85736],{"class":749,"line":1054},[747,85737,85738],{"class":772},"  # Name of the \"object\"\n",[747,85740,85741,85743],{"class":749,"line":1060},[747,85742,23251],{"class":1630},[747,85744,11146],{"class":802},[747,85746,85747],{"class":749,"line":1066},[747,85748,85749],{"class":772},"  # Labels of the \"object\"\n",[747,85751,85752],{"class":749,"line":1081},[747,85753,85643],{"class":1630},[747,85755,85756],{"class":749,"line":1087},[747,85757,85758],{"class":772},"    # A lable named \"name\" with value \"mysql\"\n",[747,85760,85761,85763],{"class":749,"line":1102},[747,85762,37583],{"class":1630},[747,85764,11146],{"class":802},[747,85766,85767],{"class":749,"line":1110},[747,85768,85769],{"class":772},"# spec ~= Specificationsof the \"object\"\n",[747,85771,85772],{"class":749,"line":1117},[747,85773,37531],{"class":1630},[747,85775,85776],{"class":749,"line":1123},[747,85777,85778],{"class":772},"  # List of Container definitions\n",[747,85780,85781],{"class":749,"line":1129},[747,85782,37536],{"class":1630},[747,85784,85785],{"class":749,"line":1142},[747,85786,85787],{"class":772},"    # The \"name\"\u002F\"suffix\" of the container name\n",[747,85789,85790,85792,85795],{"class":749,"line":1150},[747,85791,18665],{"class":1630},[747,85793,85794],{"class":802}," name:",[747,85796,11146],{"class":802},[747,85798,85799],{"class":749,"line":1157},[747,85800,85801],{"class":772},"      # What Docker image to use\n",[747,85803,85804,85807],{"class":749,"line":1163},[747,85805,85806],{"class":1630},"      image:",[747,85808,83571],{"class":802},[747,85810,85811],{"class":749,"line":1168},[747,85812,85813],{"class":1630},"      env:\n",[747,85815,85816,85818,85820],{"class":749,"line":1174},[747,85817,14801],{"class":1630},[747,85819,85794],{"class":802},[747,85821,85822],{"class":802}," DB_NAME\n",[747,85824,85825,85828],{"class":749,"line":1480},[747,85826,85827],{"class":1630},"          value:",[747,85829,6540],{"class":802},[747,85831,85832,85834,85836],{"class":749,"line":1491},[747,85833,14801],{"class":1630},[747,85835,85794],{"class":802},[747,85837,85838],{"class":802}," DB_USER\n",[747,85840,85841,85843],{"class":749,"line":1496},[747,85842,85827],{"class":1630},[747,85844,6540],{"class":802},[747,85846,85847,85849,85851],{"class":749,"line":1502},[747,85848,14801],{"class":1630},[747,85850,85794],{"class":802},[747,85852,85853],{"class":802}," DB_PASS\n",[747,85855,85856,85858],{"class":749,"line":1510},[747,85857,85827],{"class":1630},[747,85859,6540],{"class":802},[747,85861,85862],{"class":749,"line":1520},[747,85863,85864],{"class":772},"      # List of container ports reachable from within the cluster\n",[747,85866,85867],{"class":749,"line":1525},[747,85868,85869],{"class":1630},"      ports:\n",[747,85871,85872,85874,85877],{"class":749,"line":1533},[747,85873,14801],{"class":1630},[747,85875,85876],{"class":802}," containerPort:",[747,85878,30576],{"class":1895},[747,85880,85881,85884],{"class":749,"line":1539},[747,85882,85883],{"class":1630},"          name:",[747,85885,11146],{"class":802},[747,85887,85888],{"class":749,"line":1549},[747,85889,12808],{"class":1630},[747,85891,85892,85894],{"class":749,"line":1554},[747,85893,23195],{"class":1630},[747,85895,22608],{"class":802},[747,85897,85898],{"class":749,"line":1562},[747,85899,85628],{"class":772},[747,85901,85902,85904],{"class":749,"line":1568},[747,85903,23230],{"class":1630},[747,85905,25758],{"class":802},[747,85907,85908],{"class":749,"line":1577},[747,85909,23238],{"class":1630},[747,85911,85912],{"class":749,"line":1582},[747,85913,85914],{"class":772},"  # labels for the service\n",[747,85916,85917],{"class":749,"line":1588},[747,85918,85643],{"class":1630},[747,85920,85921,85923],{"class":749,"line":1594},[747,85922,37583],{"class":1630},[747,85924,6540],{"class":802},[747,85926,85927],{"class":749,"line":1600},[747,85928,85929],{"class":772},"  # name of the service\n",[747,85931,85932,85934],{"class":749,"line":4804},[747,85933,23251],{"class":1630},[747,85935,6540],{"class":802},[747,85937,85938],{"class":749,"line":4810},[747,85939,37531],{"class":1630},[747,85941,85942],{"class":749,"line":4816},[747,85943,83659],{"class":1630},[747,85945,85946],{"class":749,"line":4822},[747,85947,85668],{"class":772},[747,85949,85950,85952,85954],{"class":749,"line":4828},[747,85951,18665],{"class":1630},[747,85953,85675],{"class":802},[747,85955,29869],{"class":1895},[747,85957,85958],{"class":749,"line":4834},[747,85959,85682],{"class":772},[747,85961,85962],{"class":749,"line":4840},[747,85963,85687],{"class":1630},[747,85965,85966],{"class":749,"line":4846},[747,85967,85968],{"class":772},"    # select pods with the name \"wordpress\"\n",[747,85970,85971,85973],{"class":749,"line":4852},[747,85972,37583],{"class":1630},[747,85974,6540],{"class":802},[747,85976,85977],{"class":749,"line":4858},[747,85978,12808],{"class":1630},[747,85980,85981],{"class":749,"line":4864},[747,85982,85707],{"class":772},[747,85984,85985,85987],{"class":749,"line":4870},[747,85986,23195],{"class":1630},[747,85988,22608],{"class":802},[747,85990,85991],{"class":749,"line":4876},[747,85992,85993],{"class":772},"# Type of \"request\"\n",[747,85995,85996,85998],{"class":749,"line":4882},[747,85997,23230],{"class":1630},[747,85999,28795],{"class":802},[747,86001,86002],{"class":749,"line":4888},[747,86003,85729],{"class":772},[747,86005,86006],{"class":749,"line":4894},[747,86007,23238],{"class":1630},[747,86009,86010],{"class":749,"line":4900},[747,86011,85738],{"class":772},[747,86013,86014,86016],{"class":749,"line":4906},[747,86015,23251],{"class":1630},[747,86017,6540],{"class":802},[747,86019,86020],{"class":749,"line":4912},[747,86021,85749],{"class":772},[747,86023,86024],{"class":749,"line":4928},[747,86025,85643],{"class":1630},[747,86027,86028],{"class":749,"line":4934},[747,86029,86030],{"class":772},"    # A lable named \"name\" with value \"wordpress\"\n",[747,86032,86033,86035],{"class":749,"line":4940},[747,86034,37583],{"class":1630},[747,86036,6540],{"class":802},[747,86038,86039],{"class":749,"line":4946},[747,86040,86041],{"class":772},"# spec ~= Specifications of the \"object\"\n",[747,86043,86044],{"class":749,"line":4952},[747,86045,37531],{"class":1630},[747,86047,86048],{"class":749,"line":4958},[747,86049,85778],{"class":772},[747,86051,86052],{"class":749,"line":4964},[747,86053,37536],{"class":1630},[747,86055,86056],{"class":749,"line":4970},[747,86057,86058],{"class":772},"    # What Docker image to use\n",[747,86060,86061,86063,86065],{"class":749,"line":4998},[747,86062,18665],{"class":1630},[747,86064,37543],{"class":802},[747,86066,6540],{"class":802},[747,86068,86069],{"class":749,"line":5016},[747,86070,86071],{"class":772},"      # The \"name\"\u002F\"suffix\" of the container name\n",[747,86073,86074,86077],{"class":749,"line":5048},[747,86075,86076],{"class":1630},"      name:",[747,86078,6540],{"class":802},[747,86080,86081],{"class":749,"line":5077},[747,86082,86083],{"class":772},"      # List of environment variables\n",[747,86085,86086],{"class":749,"line":5098},[747,86087,85813],{"class":1630},[747,86089,86090,86092,86094],{"class":749,"line":5121},[747,86091,14801],{"class":1630},[747,86093,85794],{"class":802},[747,86095,34014],{"class":802},[747,86097,86098,86100],{"class":749,"line":5127},[747,86099,85827],{"class":1630},[747,86101,86102],{"class":802}," mysql.default:3306\n",[747,86104,86105,86107,86109],{"class":749,"line":5133},[747,86106,14801],{"class":1630},[747,86108,85794],{"class":802},[747,86110,86111],{"class":802}," WORDPRESS_DB_NAME\n",[747,86113,86114,86116],{"class":749,"line":5139},[747,86115,85827],{"class":1630},[747,86117,6540],{"class":802},[747,86119,86120,86122,86124],{"class":749,"line":5164},[747,86121,14801],{"class":1630},[747,86123,85794],{"class":802},[747,86125,86126],{"class":802}," WORDPRESS_DB_USER\n",[747,86128,86129,86131],{"class":749,"line":5205},[747,86130,85827],{"class":1630},[747,86132,6540],{"class":802},[747,86134,86135,86137,86139],{"class":749,"line":5229},[747,86136,14801],{"class":1630},[747,86138,85794],{"class":802},[747,86140,34033],{"class":802},[747,86142,86143,86145],{"class":749,"line":5250},[747,86144,85827],{"class":1630},[747,86146,6540],{"class":802},[747,86148,86149,86151,86153],{"class":749,"line":5264},[747,86150,14801],{"class":1630},[747,86152,85794],{"class":802},[747,86154,86155],{"class":802}," WORDPRESS_AUTH_KEY\n",[747,86157,86158,86160],{"class":749,"line":5282},[747,86159,85827],{"class":1630},[747,86161,11053],{"class":802},[747,86163,86164,86166,86168],{"class":749,"line":5311},[747,86165,14801],{"class":1630},[747,86167,85794],{"class":802},[747,86169,86170],{"class":802}," WORDPRESS_LOGGED_IN_KEY\n",[747,86172,86173,86175],{"class":749,"line":5331},[747,86174,85827],{"class":1630},[747,86176,11063],{"class":802},[747,86178,86179,86181,86183],{"class":749,"line":5351},[747,86180,14801],{"class":1630},[747,86182,85794],{"class":802},[747,86184,86185],{"class":802}," WORDPRESS_AUTH_SALT\n",[747,86187,86188,86190],{"class":749,"line":5374},[747,86189,85827],{"class":1630},[747,86191,11073],{"class":802},[747,86193,86194,86196,86198],{"class":749,"line":5394},[747,86195,14801],{"class":1630},[747,86197,85794],{"class":802},[747,86199,86200],{"class":802}," WORDPRESS_LOGGED_IN_SALT\n",[747,86202,86203,86205],{"class":749,"line":5413},[747,86204,85827],{"class":1630},[747,86206,11083],{"class":802},[747,86208,86209],{"class":749,"line":5430},[747,86210,86211],{"class":772},"      # List of ports to \"publish\"\n",[747,86213,86214],{"class":749,"line":5447},[747,86215,85869],{"class":1630},[747,86217,86218],{"class":749,"line":5500},[747,86219,86220],{"class":772},"        # ContainerPort exposes only to the inside of your network, not to the outside\n",[747,86222,86223],{"class":749,"line":5517},[747,86224,86225],{"class":772},"        # To reach the container we create a cluster wide service\n",[747,86227,86228,86230,86232],{"class":749,"line":5534},[747,86229,14801],{"class":1630},[747,86231,85876],{"class":802},[747,86233,29869],{"class":1895},[747,86235,86236],{"class":749,"line":5556},[747,86237,86238],{"class":772},"          # gives the port a name\n",[747,86240,86241,86243],{"class":749,"line":5577},[747,86242,85883],{"class":1630},[747,86244,6540],{"class":802},[523,86246,86247,86248,86250,86251,86253,86254,86256],{},"You can see that the syntax is similar to the syntax of ",[567,86249,2936],{},". It has it's differences, for example the environment variables, but all in all it is similar.\nThe big difference to ",[567,86252,2936],{}," is that there is more around the container \"defintions\". In ",[567,86255,2936],{}," we \"only\" have containers, no services, replication controller and other objects.",[2979,86258],{},[79989,86260,86262],{"id":86261},"your-turn-lets-deploy-the-guestbook-application","Your turn, let's deploy the Guestbook application",[535,86264,86266],{"id":86265},"run-the-guestbook","Run the Guestbook",[6072,86268,86269],{},[523,86270,86271,8939,86273],{},[584,86272,2951],{},[527,86274,86276],{"href":85397,"rel":86275},[531],[567,86277,37774],{},[523,86279,86280,86281,86284,86285,86287,86288,86291],{},"Enter the ",[567,86282,86283],{},"guestbook\u002F"," directory and ",[567,86286,15269],{}," create\u002F\"run\" the ",[567,86289,86290],{},"guestbook-all-in-one.yaml"," file.\nFor the forgetful, this is how you create\u002F\"run\" the file:",[738,86293,86295],{"className":1621,"code":86294,"language":1623,"meta":743,"style":743},"kubectl create -f guestbook-all-in-one.yaml\n",[567,86296,86297],{"__ignoreMap":743},[747,86298,86299,86301,86303,86305],{"class":749,"line":750},[747,86300,15269],{"class":1630},[747,86302,1925],{"class":802},[747,86304,1934],{"class":802},[747,86306,86307],{"class":802}," guestbook-all-in-one.yaml\n",[6072,86309,86310],{},[523,86311,86312],{},[584,86313,3521],{},[523,86315,86316],{},"This will start all services and replication controller that are required by the guestbook application.",[535,86318,86320],{"id":86319},"test-the-guestbook","Test the Guestbook",[523,86322,86323,86324,1909],{},"To reach the guestbook, navigate to ",[527,86325,86326],{"href":86326,"rel":86327},"http:\u002F\u002F127.0.0.1:8080\u002Fapi\u002Fv1\u002Fproxy\u002Fnamespaces\u002Fdefault\u002Fservices\u002Ffrontend",[531],[6072,86329,86330],{},[523,86331,86332,86336,86337,86341],{},[3069,86333],{"alt":86334,"src":86335},"Kubernetes Guesbook App","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Fkubernetes-guesbook-home.png","\nThe guestbook app just started, so there are no entries yet.\n",[3069,86338],{"alt":86339,"src":86340},"Kubernetes Guesbook App with some example entries","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2\u002Fkubernetes-guesbook-entries.png","\nNow with some entries added.",[523,86343,86344],{},"Now add some entries on your own, then move on to the next section.",[535,86346,86348],{"id":86347},"shutdown-one-node","Shutdown one node",[6072,86350,86351],{},[523,86352,86353,86354,86357,86358,86361,86362,86365],{},"Please shutdown ",[584,86355,86356],{},"one"," node only, if you have less than ",[584,86359,86360],{},"five"," nodes. Thanks!\nAnd ",[584,86363,86364],{},"don't"," shutdown the master server, without a replicated master setup not much will work then.",[523,86367,86368],{},"Et voilà, the application is still up, running and reachable. Kubernetes is going to create new instances of the lost containers from the node.",[523,86370,86371],{},"Best would be to just reboot and not shutdown the server\u002FVM. Kubernetes has no problem restarting the containers on other servers, but when running with low resources it is the best to keep the \"downtime\" low.",[79989,86373,86375],{"id":86374},"write-your-own-deployment-files","Write your own \"deployment files\"",[523,86377,86378,86379,86382],{},"As you have already seen some Kubernetes \"deployment\" files in this ",[527,86380,85381],{"href":86381},"#Deployments-with-Kubernetes"," section. We are now going deeper into this topic. To be exact we are now writing our own Kubernetes \"deployment\" files.",[535,86384,86386],{"id":86385},"wordpress-mysql-wip","WordPress + MySQL - WIP",[523,86388,86389,86390],{},"Details about a deploying WordPress with MySQL to Kubernetes can be found here: ",[527,86391,86392],{"href":86392,"rel":86393},"https:\u002F\u002Fgithub.com\u002Fkubernetes\u002Fkubernetes\u002Ftree\u002Frelease-1.4\u002Fexamples\u002Fmysql-wordpress-pd",[531],[6072,86395,86396,86400],{},[523,86397,86398],{},[584,86399,6189],{},[523,86401,86402],{},"The link above uses PDs (PersistentDisks) (too. Replace the part with the PDs (PersistentDisks) with hostdirs.",[79989,86404,86406],{"id":86405},"have-fun-with-your-kubernetes-cluster","Have fun with your Kubernetes cluster!",[523,86408,86409],{},"Now you can continue to play around with your Kubernetes cluster. Deploy other applications, if you need help please contact me.",[523,86411,86412],{},"If you want to stop the Kubernetes cluster, please stop all nodes at the same time! Not stopping them at the same time, causes the services required to run the cluster to desync and causes fatal errors.",[2979,86414],{},[79989,86416,11751],{"id":11750},[523,86418,86419],{},"If you are reading this, you have made it to the end. Well done, sir or madame! Have a cookie on my cap.",[2979,86421],{},[79989,86423,86425],{"id":86424},"solutions-for-tests","Solutions for \"Tests\"",[535,86427,11764],{"id":11763},[738,86429,86431],{"className":9011,"code":86430,"language":9013,"meta":743,"style":743},"FROM debian:jessie\n\nRUN apt-get update && apt-get install -y nginx\n\nENTRYPOINT [\"nginx\"]\n",[567,86432,86433,86439,86443,86449,86453],{"__ignoreMap":743},[747,86434,86435,86437],{"class":749,"line":750},[747,86436,9020],{"class":1895},[747,86438,82542],{"class":1640},[747,86440,86441],{"class":749,"line":761},[747,86442,1255],{"emptyLinePlaceholder":1254},[747,86444,86445,86447],{"class":749,"line":769},[747,86446,9065],{"class":1895},[747,86448,11786],{"class":1640},[747,86450,86451],{"class":749,"line":776},[747,86452,1255],{"emptyLinePlaceholder":1254},[747,86454,86455,86457,86459,86461],{"class":749,"line":784},[747,86456,9210],{"class":1895},[747,86458,4262],{"class":1640},[747,86460,11799],{"class":802},[747,86462,4268],{"class":1640},[535,86464,11805,86465],{"id":11804},[567,86466,10821],{},[738,86468,86470],{"className":740,"code":86469,"language":742,"meta":743,"style":743},"# Taken from https:\u002F\u002Fwww.digitalocean.com\u002Fcommunity\u002Ftutorials\u002Fhow-to-install-wordpress-and-phpmyadmin-with-docker-compose-on-ubuntu-14-04\ndatabase:\n  image: sameersbn\u002Fmysql:latest\n  environment:\n    DB_NAME: wordpress\n    DB_USER: wordpress\n    DB_PASS: wordpress\n  volumes:\n    - \"\u002Fopt\u002Fdocker\u002Fdatabase:\u002Fvar\u002Flib\u002Fmysql:rw\"\nwordpress:\n  image: wordpress\n  links:\n    - mysql:database\n  ports:\n    - 8080:80\n  environment:\n    WORDPRESS_DB_HOST: mysql:3306\n    WORDPRESS_DB_NAME: wordpress\n    WORDPRESS_DB_USER: wordpress\n    WORDPRESS_DB_PASSWORD: wordpress\n    WORDPRESS_AUTH_KEY: SECURE_AUTH_KEY\n    WORDPRESS_LOGGED_IN_KEY: SECURE_LOGGED_IN_KEY\n    WORDPRESS_AUTH_SALT: SECURE_AUTH_SALT\n    WORDPRESS_LOGGED_IN_SALT: SECURE_LOGGED_IN_SALT\nphpmyadmin:\n  image: phpmyadmin\u002Fphpmyadmin\n  links:\n    - mysql:database\n  ports:\n    - 8181:80\n  environment:\n    PMA_HOST: mysql\n    PMA_USER: root\n    PMA_PASSWORD: workshop\n",[567,86471,86472,86477,86483,86491,86497,86506,86515,86524,86530,86540,86546,86554,86561,86567,86573,86579,86585,86594,86603,86612,86621,86630,86639,86648,86657,86664,86672,86678,86684,86690,86696,86702,86711,86720],{"__ignoreMap":743},[747,86473,86474],{"class":749,"line":750},[747,86475,86476],{"class":772},"# Taken from https:\u002F\u002Fwww.digitalocean.com\u002Fcommunity\u002Ftutorials\u002Fhow-to-install-wordpress-and-phpmyadmin-with-docker-compose-on-ubuntu-14-04\n",[747,86478,86479,86481],{"class":749,"line":761},[747,86480,6815],{"class":753},[747,86482,758],{"class":757},[747,86484,86485,86487,86489],{"class":749,"line":769},[747,86486,24395],{"class":753},[747,86488,856],{"class":757},[747,86490,83571],{"class":802},[747,86492,86493,86495],{"class":749,"line":776},[747,86494,24602],{"class":753},[747,86496,758],{"class":757},[747,86498,86499,86502,86504],{"class":749,"line":784},[747,86500,86501],{"class":753},"    DB_NAME",[747,86503,856],{"class":757},[747,86505,6540],{"class":802},[747,86507,86508,86511,86513],{"class":749,"line":790},[747,86509,86510],{"class":753},"    DB_USER",[747,86512,856],{"class":757},[747,86514,6540],{"class":802},[747,86516,86517,86520,86522],{"class":749,"line":796},[747,86518,86519],{"class":753},"    DB_PASS",[747,86521,856],{"class":757},[747,86523,6540],{"class":802},[747,86525,86526,86528],{"class":749,"line":806},[747,86527,29209],{"class":753},[747,86529,758],{"class":757},[747,86531,86532,86534,86536,86538],{"class":749,"line":814},[747,86533,18665],{"class":757},[747,86535,969],{"class":757},[747,86537,49135],{"class":802},[747,86539,975],{"class":757},[747,86541,86542,86544],{"class":749,"line":822},[747,86543,6725],{"class":753},[747,86545,758],{"class":757},[747,86547,86548,86550,86552],{"class":749,"line":830},[747,86549,24395],{"class":753},[747,86551,856],{"class":757},[747,86553,6540],{"class":802},[747,86555,86556,86559],{"class":749,"line":836},[747,86557,86558],{"class":753},"  links",[747,86560,758],{"class":757},[747,86562,86563,86565],{"class":749,"line":842},[747,86564,18665],{"class":757},[747,86566,83752],{"class":802},[747,86568,86569,86571],{"class":749,"line":850},[747,86570,25878],{"class":753},[747,86572,758],{"class":757},[747,86574,86575,86577],{"class":749,"line":863},[747,86576,18665],{"class":757},[747,86578,11000],{"class":802},[747,86580,86581,86583],{"class":749,"line":869},[747,86582,24602],{"class":753},[747,86584,758],{"class":757},[747,86586,86587,86590,86592],{"class":749,"line":877},[747,86588,86589],{"class":753},"    WORDPRESS_DB_HOST",[747,86591,856],{"class":757},[747,86593,11939],{"class":802},[747,86595,86596,86599,86601],{"class":749,"line":1015},[747,86597,86598],{"class":753},"    WORDPRESS_DB_NAME",[747,86600,856],{"class":757},[747,86602,6540],{"class":802},[747,86604,86605,86608,86610],{"class":749,"line":1021},[747,86606,86607],{"class":753},"    WORDPRESS_DB_USER",[747,86609,856],{"class":757},[747,86611,6540],{"class":802},[747,86613,86614,86617,86619],{"class":749,"line":1027},[747,86615,86616],{"class":753},"    WORDPRESS_DB_PASSWORD",[747,86618,856],{"class":757},[747,86620,6540],{"class":802},[747,86622,86623,86626,86628],{"class":749,"line":1033},[747,86624,86625],{"class":753},"    WORDPRESS_AUTH_KEY",[747,86627,856],{"class":757},[747,86629,11053],{"class":802},[747,86631,86632,86635,86637],{"class":749,"line":1039},[747,86633,86634],{"class":753},"    WORDPRESS_LOGGED_IN_KEY",[747,86636,856],{"class":757},[747,86638,11063],{"class":802},[747,86640,86641,86644,86646],{"class":749,"line":1054},[747,86642,86643],{"class":753},"    WORDPRESS_AUTH_SALT",[747,86645,856],{"class":757},[747,86647,11073],{"class":802},[747,86649,86650,86653,86655],{"class":749,"line":1060},[747,86651,86652],{"class":753},"    WORDPRESS_LOGGED_IN_SALT",[747,86654,856],{"class":757},[747,86656,11083],{"class":802},[747,86658,86659,86662],{"class":749,"line":1066},[747,86660,86661],{"class":753},"phpmyadmin",[747,86663,758],{"class":757},[747,86665,86666,86668,86670],{"class":749,"line":1081},[747,86667,24395],{"class":753},[747,86669,856],{"class":757},[747,86671,11117],{"class":802},[747,86673,86674,86676],{"class":749,"line":1087},[747,86675,86558],{"class":753},[747,86677,758],{"class":757},[747,86679,86680,86682],{"class":749,"line":1102},[747,86681,18665],{"class":757},[747,86683,83752],{"class":802},[747,86685,86686,86688],{"class":749,"line":1110},[747,86687,25878],{"class":753},[747,86689,758],{"class":757},[747,86691,86692,86694],{"class":749,"line":1117},[747,86693,18665],{"class":757},[747,86695,11130],{"class":802},[747,86697,86698,86700],{"class":749,"line":1123},[747,86699,24602],{"class":753},[747,86701,758],{"class":757},[747,86703,86704,86707,86709],{"class":749,"line":1129},[747,86705,86706],{"class":753},"    PMA_HOST",[747,86708,856],{"class":757},[747,86710,11146],{"class":802},[747,86712,86713,86716,86718],{"class":749,"line":1142},[747,86714,86715],{"class":753},"    PMA_USER",[747,86717,856],{"class":757},[747,86719,11156],{"class":802},[747,86721,86722,86725,86727],{"class":749,"line":1150},[747,86723,86724],{"class":753},"    PMA_PASSWORD",[747,86726,856],{"class":757},[747,86728,11166],{"class":802},[2890,86730,86731],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":743,"searchDepth":761,"depth":761,"links":86733},[86734,86737,86738,86739,86740,86741,86742,86743,86744,86745,86746,86747,86754,86759,86760,86761,86762,86763,86764,86765,86766,86767,86768,86769,86770,86774,86775,86779,86780,86781,86782,86783,86790,86791,86792,86793,86794,86795,86796,86798,86799,86800,86806,86814,86818,86819,86820,86821,86822,86823,86829,86830,86831,86832,86833,86834,86835,86836],{"id":39343,"depth":761,"text":39348,"children":86735},[86736],{"id":80050,"depth":769,"text":80051},{"id":3012,"depth":761,"text":3013},{"id":3043,"depth":761,"text":3044},{"id":3055,"depth":761,"text":3056},{"id":39514,"depth":761,"text":39515},{"id":80187,"depth":761,"text":80188},{"id":3144,"depth":761,"text":3145},{"id":3293,"depth":761,"text":3294},{"id":3486,"depth":761,"text":3487},{"id":3649,"depth":761,"text":3650},{"id":4152,"depth":761,"text":4153},{"id":5725,"depth":761,"text":5726,"children":86748},[86749,86750,86751,86752,86753],{"id":5759,"depth":769,"text":5760},{"id":5805,"depth":769,"text":5806},{"id":5908,"depth":769,"text":5909},{"id":6106,"depth":769,"text":6107},{"id":6203,"depth":769,"text":6204},{"id":6359,"depth":761,"text":6360,"children":86755},[86756,86757,86758],{"id":6366,"depth":769,"text":6367},{"id":6581,"depth":769,"text":6582},{"id":6718,"depth":769,"text":6719},{"id":45902,"depth":761,"text":45903},{"id":7355,"depth":761,"text":12117},{"id":7448,"depth":761,"text":7449},{"id":7458,"depth":761,"text":7459},{"id":7907,"depth":761,"text":7908},{"id":8244,"depth":761,"text":8245},{"id":8310,"depth":761,"text":8311},{"id":8438,"depth":761,"text":8439},{"id":8557,"depth":761,"text":8558},{"id":8787,"depth":761,"text":8788},{"id":8921,"depth":761,"text":8922},{"id":8976,"depth":761,"text":47620,"children":86771},[86772,86773],{"id":82522,"depth":769,"text":82523},{"id":9220,"depth":769,"text":9221},{"id":9498,"depth":761,"text":9499},{"id":10183,"depth":761,"text":10184,"children":86776},[86777,86778],{"id":10187,"depth":769,"text":10188},{"id":10238,"depth":769,"text":10239},{"id":83188,"depth":761,"text":83189},{"id":10730,"depth":761,"text":10731},{"id":10804,"depth":761,"text":10805},{"id":11246,"depth":761,"text":11247},{"id":11332,"depth":761,"text":12147,"children":86784},[86785,86787,86789],{"id":11347,"depth":769,"text":86786},"Stopping all containers run by the current docker-compose file",{"id":11399,"depth":769,"text":86788},"Deleting all containers run by the current docker-compose file",{"id":11455,"depth":769,"text":49816},{"id":11496,"depth":761,"text":12149},{"id":11537,"depth":761,"text":11538},{"id":11679,"depth":761,"text":84077},{"id":11706,"depth":761,"text":11707},{"id":29981,"depth":761,"text":22320},{"id":38349,"depth":761,"text":39242},{"id":84149,"depth":761,"text":86797},"Replication Controller (rc)",{"id":38391,"depth":761,"text":39246},{"id":38458,"depth":761,"text":84166},{"id":84187,"depth":761,"text":84188,"children":86801},[86802,86804,86805],{"id":84191,"depth":769,"text":86803},"The iptables rules will blow your mind",{"id":84206,"depth":769,"text":84207},{"id":27791,"depth":769,"text":27792},{"id":38502,"depth":761,"text":39253,"children":86807},[86808,86809,86810,86811,86812,86813],{"id":84251,"depth":769,"text":84252},{"id":38597,"depth":769,"text":38598},{"id":84355,"depth":769,"text":84356},{"id":38818,"depth":769,"text":38819},{"id":38914,"depth":769,"text":38915},{"id":38997,"depth":769,"text":38998},{"id":39068,"depth":761,"text":39069,"children":86815},[86816,86817],{"id":84604,"depth":769,"text":84605},{"id":84660,"depth":769,"text":84661},{"id":84718,"depth":761,"text":84719},{"id":84769,"depth":761,"text":84770},{"id":84974,"depth":761,"text":84975},{"id":85041,"depth":761,"text":85042},{"id":37474,"depth":761,"text":37475},{"id":85211,"depth":761,"text":86824,"children":86825},"Take a look at the pre-installed kube-system containers",[86826,86827,86828],{"id":85258,"depth":769,"text":85259},{"id":85297,"depth":769,"text":85298},{"id":85350,"depth":769,"text":85351},{"id":38039,"depth":761,"text":38040},{"id":85604,"depth":761,"text":85605},{"id":86265,"depth":761,"text":86266},{"id":86319,"depth":761,"text":86320},{"id":86347,"depth":761,"text":86348},{"id":86385,"depth":761,"text":86386},{"id":11763,"depth":761,"text":11764},{"id":11804,"depth":761,"text":12167},"2016-04-01T15:48:12+02:00","Improved version of the first \"Docker for Admins\"-Workshop. So to say the version 2.",{"src":12171},{"tags":86841},[12174,12175,124,12176],"\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop-v2",{"title":79982,"description":86838},"3.blog\u002F2016\u002Fdocker-for-admins-workshop-v2","ixcYV-Zjev8rmy3LgEFFrSat7kNii-dQEGLB_QlYcOU",{"id":86847,"title":86848,"authors":86849,"badge":518,"body":86852,"date":86926,"description":86927,"extension":2911,"image":518,"meta":86928,"navigation":1254,"path":86931,"seo":86932,"stem":86933,"__hash__":86934},"posts\u002F3.blog\u002F2016\u002Fascii-link-dump.md","ASCII Link Dump",[86850],{"name":514,"to":515,"avatar":86851},{"src":517},{"type":520,"value":86853,"toc":86921},[86854,86858,86878,86882,86908,86912],[535,86855,86857],{"id":86856},"ascii-editors","ASCII Editors",[668,86859,86860,86871],{},[638,86861,86862,6378,86867,86870],{},[527,86863,86866],{"href":86864,"rel":86865},"http:\u002F\u002Fasciiflow.com",[531],"ASCIIFlow Infinity",[527,86868,86864],{"href":86864,"rel":86869},[531],"), Developed by Lewis, Designed by Sam and Ryan",[638,86872,86873],{},[527,86874,86877],{"href":86875,"rel":86876},"http:\u002F\u002Fstable.ascii-flow.appspot.com\u002F",[531],"The old ASCIIFlow on AppSpot",[535,86879,86881],{"id":86880},"ascii-generators","ASCII Generators",[668,86883,86884,86892,86900],{},[638,86885,86886,86891],{},[527,86887,86890],{"href":86888,"rel":86889},"http:\u002F\u002Fpatorjk.com\u002Fsoftware\u002Ftaag\u002F",[531],"Text to ASCII Art Generator (TAAG)"," by patorjk.com",[638,86893,86894,86899],{},[527,86895,86898],{"href":86896,"rel":86897},"http:\u002F\u002Fwww.kammerl.de\u002Fascii\u002FAsciiSignature.php",[531],"ASCII Signature"," by kammerl.de",[638,86901,86902,86907],{},[527,86903,86906],{"href":86904,"rel":86905},"http:\u002F\u002Fwww.network-science.de\u002Fascii\u002F",[531],"ASCII Generator"," by network-science.de",[535,86909,86911],{"id":86910},"image-to-ascii","Image to ASCII",[668,86913,86914],{},[638,86915,86916],{},[527,86917,86920],{"href":86918,"rel":86919},"http:\u002F\u002Fpicascii.com\u002F",[531],"PicASCII",{"title":743,"searchDepth":761,"depth":761,"links":86922},[86923,86924,86925],{"id":86856,"depth":761,"text":86857},{"id":86880,"depth":761,"text":86881},{"id":86910,"depth":761,"text":86911},"2016-03-27T19:29:00+02:00","This is a dump of links to sites, where you can create ASCII content\u002Fart, convert images to ASCII and more.",{"tags":86929},[86930,76569],"ASCII","\u002Fblog\u002F2016\u002Fascii-link-dump",{"title":86848,"description":86927},"3.blog\u002F2016\u002Fascii-link-dump","K4Cn9XMoKUpd-odRLXJ70cU9JCl1p1wsguhBYB3Lynk",{"id":86936,"title":86937,"authors":86938,"badge":518,"body":86941,"date":90955,"description":90956,"extension":2911,"image":90957,"meta":90958,"navigation":1254,"path":90960,"seo":90961,"stem":90962,"__hash__":90963},"posts\u002F3.blog\u002F2016\u002Fdocker-for-admins-workshop.md","Docker for Admins - Workshop",[86939],{"name":514,"to":515,"avatar":86940},{"src":517},{"type":520,"value":86942,"toc":90934},[86943,86947,86955,86957,86959,86962,86964,86984,86988,86997,86999,87006,87018,87020,87028,87031,87033,87036,87038,87042,87055,87061,87063,87065,87067,87070,87072,87078,87082,87088,87090,87092,87094,87109,87111,87115,87119,87127,87129,87140,87142,87145,87155,87199,87205,87211,87223,87227,87239,87252,87260,87272,87275,87277,87281,87285,87294,87297,87301,87368,87414,87418,87421,87570,87588,87597,87606,87623,87636,87639,87641,87644,87646,87650,87681,87685,87690,87733,87739,87743,87746,87764,87775,87780,87792,87798,87801,87804,87819,87822,87825,87837,87853,87855,87861,87865,87893,87895,87899,87903,87912,87918,87994,88026,88029,88054,88057,88059,88062,88064,88072,88075,88081,88084,88089,88092,88106,88108,88112,88118,88123,88135,88153,88156,88159,88162,88217,88220,88226,88229,88233,88239,88244,88250,88269,88276,88291,88293,88295,88297,88299,88301,88303,88305,88309,88311,88313,88319,88359,88364,88370,88378,88385,88419,88421,88437,88448,88453,88493,88497,88509,88513,88531,88535,88545,88555,88589,88594,88602,88608,88666,88679,88682,88691,88694,88715,88717,88721,88723,88731,88746,88751,88760,88958,88988,88995,88997,89002,89018,89047,89061,89067,89088,89091,89095,89098,89114,89116,89121,89123,89130,89134,89137,89160,89163,89167,89169,89173,89177,89180,89185,89189,89193,89199,89204,89217,89221,89229,89234,89239,89353,89383,89387,89390,89394,89401,89409,89412,89425,89434,89437,89446,89449,89506,89510,89518,89522,89531,89534,89541,89544,89546,89799,89801,89888,89892,89895,90062,90065,90144,90147,90150,90293,90296,90393,90397,90400,90405,90408,90422,90446,90449,90466,90496,90499,90513,90530,90543,90546,90549,90551,90555,90559,90565,90569,90584,90587,90628,90630,90632,90639,90641,90645,90651,90685,90691,90931],[613,86944,86946],{"id":86945},"this-workshop-is-deprecated","This workshop is deprecated!",[523,86948,86949],{},[584,86950,86951,86952,1909],{},"Please use the new version of the \"Docker for Admins\" Workshop post, ",[527,86953,3396],{"href":86954},"\u002Fblog\u002F2016\u002FDocker-for-Admins-Workshop-v2.md",[2979,86956],{},[613,86958,2930],{"id":2929},[523,86960,86961],{},"The Goal is to show how easy it is to use Docker.\nThe simpleness in creating an image for an own project\u002Fapplication.\nIf there's enough time, we also look at how to orchestrate a Kubernetes cluster and let the first containers run on the cluster.",[613,86963,39306],{"id":39305},[668,86965,86966,86970,86979],{},[638,86967,86968,39314],{},[584,86969,80008],{},[638,86971,86972,86974,86975,86978],{},[584,86973,2951],{},": Is a refer to a task in the workshop repo mostly in the ",[567,86976,86977],{},"tasks\u002F"," folder.",[638,86980,86981,86983],{},[584,86982,2957],{},": Stands for \"What does what do\" aka \"Me explaining what the things listed below do\" (short forms FTW!), I only explain new things in this section.",[613,86985,86987],{"id":86986},"group-partitions","Group \"Partitions\"",[523,86989,86990,86991,80026,86994,2977],{},"At least 2 groups with 2-3 or more people. Every group will work on their own ",[527,86992,124],{"href":3033,"rel":86993},[531],[527,86995,2976],{"href":2974,"rel":86996},[531],[613,86998,80033],{"id":80032},[523,87000,87001,87002,87005],{},"The VirtualBox is available under ",[3049,87003,87004],{},"INSERT_DOWNLOAD_LINK_HERE",".\n(Most likely to be given around with an USB stick at the workshop day)",[668,87007,87008,87013],{},[638,87009,87010,87011],{},"VM Username: ",[567,87012,32148],{},[638,87014,87015,87016],{},"VM Password: ",[567,87017,32148],{},[3126,87019,39348],{"id":39343},[523,87021,87022],{},[527,87023,87025],{"href":39346,"rel":87024},[531],[3049,87026,87027],{},"Did I hear \"Box\"?!",[523,87029,87030],{},"Fedora 23 with Docker and Cockpit enabled.\nFirewalld removed, Iptables cleared and persistence disabled.",[3126,87032,80051],{"id":80050},[523,87034,87035],{},"That's simple. It is more up to date, than Debian ",[2979,87037],{},[613,87039,87041],{"id":87040},"readme-before-begining","README before begining!",[523,87043,2995,87044,87048,87049,87054],{},[584,87045,87046],{},[567,87047,2998],{}," to the command, to get a help page that may guide you to your goal or use ",[584,87050,87051],{},[567,87052,87053],{},"man INSERT_COMMAND_HERE"," to show the man(ual) page for the given command.",[6072,87056,87057],{},[523,87058,80073,87059],{},[3049,87060,514],{},[2979,87062],{},[613,87064,3009],{"id":3008},[3126,87066,3013],{"id":3012},[523,87068,87069],{},"Because the Docker-\"Principle\" means \"simpleness\". You want WordPress? One command and you're good to go. Enough said.",[3126,87071,3044],{"id":3043},[523,87073,87074,87075,87077],{},"Microservices allow you to test local, small scale, and run large (",[3049,87076,3051],{},"), large scale, on your bare metal, cloud or virtual machines.",[3126,87079,87081],{"id":87080},"whats-the-workshop-about","What's the Workshop about",[523,87083,87084,87085,87087],{},"The basics of Docker, how to use it, Networking, Data \"Management\" and ",[567,87086,2936],{},".\nOrchestration tools like Kubernetes and\u002For RancherOS.",[2979,87089],{},[613,87091,3110],{"id":3109},[3126,87093,39515],{"id":39514},[668,87095,87096,87099,87105],{},[638,87097,87098],{},"You can install Docker directly on your system or in a VirtualBox. If you use a VirtualBox, please use Fedora 23, as the OS.",[638,87100,87101,87102,80178],{},"If you are a Windows or Mac OSX user, ask yourself \"Why you use it?\", switch to linux, thanks! You can use ",[527,87103,39528],{"href":39526,"rel":87104},[531],[638,87106,80181,87107,1909],{},[527,87108,3396],{"href":80184},[3126,87110,80188],{"id":80187},[668,87112,87113],{},[638,87114,3137],{},[3126,87116,87118],{"id":87117},"preparation","Preparation",[6072,87120,87121],{},[523,87122,87123,8939,87125],{},[584,87124,2951],{},[567,87126,80164],{},[3142,87128,39575],{"id":39574},[523,87130,87131,87132,87136,87137,1909],{},"For Docker see the begining of script at ",[527,87133,3396],{"href":87134,"rel":87135},"https:\u002F\u002Fget.docker.com\u002F",[531]," or run the installation command ",[567,87138,87139],{},"curl -sSL https:\u002F\u002Fget.docker.com\u002F | sh",[3142,87141,3294],{"id":3293},[62787,87143,87144],{},"\n![docker-compose Logo](\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop\u002Fdocker-compose-logo.png)\n",[523,87146,87147,87148,87150,87151,87154],{},"For ",[567,87149,2936],{}," see the ",[527,87152,3181],{"href":3394,"rel":87153},[531]," or run the following command:",[738,87156,87158],{"className":1621,"code":87157,"language":1623,"meta":743,"style":743},"curl -L https:\u002F\u002Fgithub.com\u002Fdocker\u002Fcompose\u002Freleases\u002Fdownload\u002Fv2.29.7\u002Fdocker-compose-`uname -s`-`uname -m` > \u002Fusr\u002Flocal\u002Fbin\u002Fdocker-compose\nchmod +x \u002Fusr\u002Flocal\u002Fbin\u002Fdocker-compose\n",[567,87159,87160,87191],{"__ignoreMap":743},[747,87161,87162,87164,87166,87169,87171,87173,87175,87177,87179,87181,87183,87185,87187,87189],{"class":749,"line":750},[747,87163,3151],{"class":1630},[747,87165,40190],{"class":802},[747,87167,87168],{"class":802}," https:\u002F\u002Fgithub.com\u002Fdocker\u002Fcompose\u002Freleases\u002Fdownload\u002Fv2.29.7\u002Fdocker-compose-",[747,87170,3351],{"class":757},[747,87172,3354],{"class":1630},[747,87174,2598],{"class":802},[747,87176,3351],{"class":757},[747,87178,3361],{"class":1630},[747,87180,3351],{"class":757},[747,87182,3354],{"class":1630},[747,87184,3368],{"class":802},[747,87186,3351],{"class":757},[747,87188,35282],{"class":757},[747,87190,3385],{"class":1630},[747,87192,87193,87195,87197],{"class":749,"line":761},[747,87194,17276],{"class":1630},[747,87196,3382],{"class":802},[747,87198,3385],{"class":802},[3142,87200,87202],{"id":87201},"last-but-not-least",[584,87203,87204],{},"Last but not least",[523,87206,87207,87208,87210],{},"Clone the Workshop repo ",[567,87209,3493],{},", it'll provide all files used in the Workshop ;)",[738,87212,87213],{"className":1621,"code":3497,"language":1623,"meta":743,"style":743},[567,87214,87215],{"__ignoreMap":743},[747,87216,87217,87219,87221],{"class":749,"line":750},[747,87218,221],{"class":1630},[747,87220,3506],{"class":802},[747,87222,3509],{"class":802},[3126,87224,87226],{"id":87225},"test-your-installation","Test your installation",[523,87228,87229,87230,87232,87233,87235,87236,7258],{},"If you installed Docker correctly, you have to add yourself to the ",[567,87231,3257],{}," group. Relog or restart your machine.\nTo verify that Docker is working, run the ",[567,87234,3649],{}," image as a test (",[567,87237,87238],{}," hello-world",[6072,87240,87241],{},[523,87242,87243,87248],{},[584,87244,10412,87245],{},[567,87246,87247],{},"docker run hello-world",[3069,87249],{"alt":87250,"src":87251},"Output: docker run hello-world","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop\u002Fdocker-run-hello-world.png",[523,87253,87254,87255,87257,87258,856],{},"To see if ",[567,87256,2936],{}," got installed correctly, run ",[567,87259,3405],{},[6072,87261,87262],{},[523,87263,87264,87268],{},[584,87265,10412,87266],{},[567,87267,3405],{},[3069,87269],{"alt":87270,"src":87271},"Output: docker-compose --version","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop\u002Fdocker-compose-version-output.png",[523,87273,87274],{},"Everything seems right and working correctly? Move on to the next part.",[2979,87276],{},[613,87278,87280],{"id":87279},"everything-working-good-lets-go","Everything working? Good, let's go!",[3126,87282,87284],{"id":87283},"the-first-simple-task","The first simple Task",[6072,87286,87287],{},[523,87288,87289,8939,87291],{},[584,87290,2951],{},[567,87292,87293],{},"runit101",[523,87295,87296],{},"Let's start with something simple, the situation is that you want to run a WordPress Blog and a MySQL (in this case we use MariaDB) database.\nNo problem, Docker got you!",[3126,87298,87300],{"id":87299},"start-the-database-container-using-image-sameersbnmysqllatest","Start the database container (using image: sameersbn\u002Fmysql:latest):",[738,87302,87304],{"className":1621,"code":87303,"language":1623,"meta":743,"style":743},"docker run \\\n    --name mysql \\\n    -d \\\n    -e 'DB_NAME=wordpress' \\\n    -e 'DB_USER=wordpress' \\\n    -e 'DB_PASS=wordpress' \\\n    sameersbn\u002Fmysql:latest\n",[567,87305,87306,87314,87322,87328,87340,87352,87364],{"__ignoreMap":743},[747,87307,87308,87310,87312],{"class":749,"line":750},[747,87309,3257],{"class":1630},[747,87311,3665],{"class":802},[747,87313,1641],{"class":1640},[747,87315,87316,87318,87320],{"class":749,"line":761},[747,87317,5790],{"class":802},[747,87319,5793],{"class":802},[747,87321,1641],{"class":1640},[747,87323,87324,87326],{"class":749,"line":769},[747,87325,5866],{"class":802},[747,87327,1641],{"class":1640},[747,87329,87330,87332,87334,87336,87338],{"class":749,"line":776},[747,87331,5991],{"class":802},[747,87333,3537],{"class":757},[747,87335,80779],{"class":802},[747,87337,3543],{"class":757},[747,87339,1641],{"class":1640},[747,87341,87342,87344,87346,87348,87350],{"class":749,"line":784},[747,87343,5991],{"class":802},[747,87345,3537],{"class":757},[747,87347,80753],{"class":802},[747,87349,3543],{"class":757},[747,87351,1641],{"class":1640},[747,87353,87354,87356,87358,87360,87362],{"class":749,"line":790},[747,87355,5991],{"class":802},[747,87357,3537],{"class":757},[747,87359,80766],{"class":802},[747,87361,3543],{"class":757},[747,87363,1641],{"class":1640},[747,87365,87366],{"class":749,"line":796},[747,87367,80571],{"class":802},[6072,87369,87370,87374],{},[523,87371,87372],{},[584,87373,2957],{},[668,87375,87376,87383,87389,87395,87403,87409],{},[638,87377,87378,87380,87381,11295],{},[567,87379,3257],{}," - Execute ",[567,87382,3257],{},[638,87384,87385,87388],{},[567,87386,87387],{},"run"," - Run a container with the given configuration.",[638,87390,87391,87394],{},[567,87392,87393],{},"--name mysql"," - Gives the container a name",[638,87396,87397,87399,87400,87402],{},[567,87398,5841],{}," - Runs the container detached from the current session (don't attach stdin and stdout), the contrary is ",[567,87401,7184],{}," which attaches the stdin and stdout.",[638,87404,87405,87408],{},[567,87406,87407],{},"-e 'KEY=VALUE'"," - Defines an environment variable inside the container at \"runtime\".",[638,87410,87411,87413],{},[567,87412,80700],{}," - The name of the image used.",[3126,87415,87417],{"id":87416},"now-we-need-wordpress","Now we need WordPress",[523,87419,87420],{},"The command for starting a WordPress instance is:",[738,87422,87424],{"className":1621,"code":87423,"language":1623,"meta":743,"style":743},"docker run \\\n    --name wordpress \\\n    -d \\\n    --link mysql:database \\\n    -p 8080:80 \\\n    -e 'WORDPRESS_DB_HOST=mysql:3306' \\\n    -e 'WORDPRESS_DB_NAME=wordpress' \\\n    -e 'WORDPRESS_DB_USER=wordpress' \\\n    -e 'WORDPRESS_DB_PASSWORD=wordpress' \\\n    -e 'WORDPRESS_AUTH_KEY=SECURE_AUTH_KEY' \\\n    -e 'WORDPRESS_LOGGED_IN_KEY=SECURE_LOGGED_IN_KEY' \\\n    -e 'WORDPRESS_AUTH_SALT=SECURE_AUTH_SALT' \\\n    -e 'WORDPRESS_LOGGED_IN_SALT=SECURE_LOGGED_IN_SALT' \\\n    wordpress\n",[567,87425,87426,87434,87442,87448,87456,87464,87477,87490,87502,87514,87527,87540,87553,87566],{"__ignoreMap":743},[747,87427,87428,87430,87432],{"class":749,"line":750},[747,87429,3257],{"class":1630},[747,87431,3665],{"class":802},[747,87433,1641],{"class":1640},[747,87435,87436,87438,87440],{"class":749,"line":761},[747,87437,5790],{"class":802},[747,87439,6842],{"class":802},[747,87441,1641],{"class":1640},[747,87443,87444,87446],{"class":749,"line":769},[747,87445,5866],{"class":802},[747,87447,1641],{"class":1640},[747,87449,87450,87452,87454],{"class":749,"line":776},[747,87451,6422],{"class":802},[747,87453,6981],{"class":802},[747,87455,1641],{"class":1640},[747,87457,87458,87460,87462],{"class":749,"line":784},[747,87459,6614],{"class":802},[747,87461,10660],{"class":802},[747,87463,1641],{"class":1640},[747,87465,87466,87468,87470,87473,87475],{"class":749,"line":790},[747,87467,5991],{"class":802},[747,87469,3537],{"class":757},[747,87471,87472],{"class":802},"WORDPRESS_DB_HOST=mysql:3306",[747,87474,3543],{"class":757},[747,87476,1641],{"class":1640},[747,87478,87479,87481,87483,87486,87488],{"class":749,"line":796},[747,87480,5991],{"class":802},[747,87482,3537],{"class":757},[747,87484,87485],{"class":802},"WORDPRESS_DB_NAME=wordpress",[747,87487,3543],{"class":757},[747,87489,1641],{"class":1640},[747,87491,87492,87494,87496,87498,87500],{"class":749,"line":806},[747,87493,5991],{"class":802},[747,87495,3537],{"class":757},[747,87497,6866],{"class":802},[747,87499,3543],{"class":757},[747,87501,1641],{"class":1640},[747,87503,87504,87506,87508,87510,87512],{"class":749,"line":814},[747,87505,5991],{"class":802},[747,87507,3537],{"class":757},[747,87509,6879],{"class":802},[747,87511,3543],{"class":757},[747,87513,1641],{"class":1640},[747,87515,87516,87518,87520,87523,87525],{"class":749,"line":822},[747,87517,5991],{"class":802},[747,87519,3537],{"class":757},[747,87521,87522],{"class":802},"WORDPRESS_AUTH_KEY=SECURE_AUTH_KEY",[747,87524,3543],{"class":757},[747,87526,1641],{"class":1640},[747,87528,87529,87531,87533,87536,87538],{"class":749,"line":830},[747,87530,5991],{"class":802},[747,87532,3537],{"class":757},[747,87534,87535],{"class":802},"WORDPRESS_LOGGED_IN_KEY=SECURE_LOGGED_IN_KEY",[747,87537,3543],{"class":757},[747,87539,1641],{"class":1640},[747,87541,87542,87544,87546,87549,87551],{"class":749,"line":836},[747,87543,5991],{"class":802},[747,87545,3537],{"class":757},[747,87547,87548],{"class":802},"WORDPRESS_AUTH_SALT=SECURE_AUTH_SALT",[747,87550,3543],{"class":757},[747,87552,1641],{"class":1640},[747,87554,87555,87557,87559,87562,87564],{"class":749,"line":842},[747,87556,5991],{"class":802},[747,87558,3537],{"class":757},[747,87560,87561],{"class":802},"WORDPRESS_LOGGED_IN_SALT=SECURE_LOGGED_IN_SALT",[747,87563,3543],{"class":757},[747,87565,1641],{"class":1640},[747,87567,87568],{"class":749,"line":850},[747,87569,6510],{"class":802},[6072,87571,87572,87576],{},[523,87573,87574],{},[584,87575,2957],{},[668,87577,87578],{},[638,87579,87580,87583,87584,10616,87586],{},[567,87581,87582],{},"-p HOST_PORT:CONTAINER_PORT\u002Ftcp"," - Creates a tcp (or udp) proxy on the ",[567,87585,6691],{},[567,87587,6697],{},[523,87589,87590,87591,87593,87594,87596],{},"Enter the WordPress container using ",[567,87592,7110],{},". With ",[567,87595,7110],{}," you can execute a command or a shell inside the container, but be aware that the shell and or command has to be present inside the container to be executed.",[523,87598,87599,87602,87603,1909],{},[584,87600,87601],{},"But wait"," how does the WordPress instance talk to the database, when the database and WordPress are running in seperate containers?\nEvery container has a seperate container IP. Docker offers a simple way to allow these containers to speak to each other, by using ",[584,87604,87605],{},"links",[523,87607,87608,87609,87612,87613,6378,87616,87619,87620,87622],{},"To create a link between two containers, not much is needed, just adding the ",[3049,87610,87611],{},"link"," argument ",[567,87614,87615],{},"--link=CONTAINER_ID:LINK_NAME",[567,87617,87618],{},"CONTAINER_ID"," can be the id or the name; ",[567,87621,6452],{}," is the usable \"hostname\" and prefix for environment variables.",[523,87624,87625,87626,87629,87630,87632,87633,32418],{},"When you link a container, the ",[3049,87627,87628],{},"environment variables"," of the linked container will become available in the created container.\nThe \"inherited\" environment variables will be prefixed with the ",[567,87631,6452],{},", example link name is database ",[567,87634,87635],{},"DATABASE_ENV_DB_USER",[523,87637,87638],{},"But wait how can the containers communicate with each other and how does the created WordPress container know what IP address the database container has? See in the next part.",[3126,87640,14526],{"id":14525},[523,87642,87643],{},"We now can start a database and WordPress container.\nWe now know how to define environment variables, publish ports, link containers together.",[2979,87645],{},[613,87647,87649],{"id":87648},"how-can-the-containers-talk-local-and-multi-host","How can the containers talk? Local and multi host?",[6072,87651,87652,87656,87663,87672],{},[523,87653,87654],{},[584,87655,9515],{},[523,87657,55912,87658,87662],{},[527,87659,87661],{"href":80102,"rel":87660},[531],"WeaveScope"," to visualize your Docker network.",[523,87664,87665,8287,87667,47648,87669,87671],{},[584,87666,2951],{},[567,87668,8294],{},[567,87670,8342],{},": Starts WeaveScope",[523,87673,87674,87677],{},[584,87675,87676],{},"Example output",[3069,87678],{"alt":87679,"src":87680},"WeaveScope UI","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop\u002Fweavescope_ui.png",[3126,87682,87684],{"id":87683},"overview-over-possible-docker-networking-solutions","Overview over possible Docker networking \"solutions\"",[523,87686,87687],{},[584,87688,87689],{},"How would one connect..",[668,87691,87692,87709],{},[638,87693,87694,87695],{},"single host Docker installation\n",[668,87696,87697,87703],{},[638,87698,87699,87700,87702],{},"Default Docker networking (",[567,87701,6373],{}," - Inter-Container-Communication)",[638,87704,87705],{},[527,87706,77047],{"href":87707,"rel":87708},"http:\u002F\u002Fopenvswitch.org\u002F",[531],[638,87710,87711,87712],{},"multi host Docker installation (using overlay networks)\n",[668,87713,87714,87717,87723,87728],{},[638,87715,87716],{},"Docker Machine\u002FEngine \"Native\" Networking",[638,87718,87719],{},[527,87720,87722],{"href":27031,"rel":87721},[531],"Flanneld",[638,87724,87725],{},[527,87726,80104],{"href":80102,"rel":87727},[531],[638,87729,87730],{},[527,87731,27041],{"href":27039,"rel":87732},[531],[523,87734,87735,87738],{},[584,87736,87737],{},"Now enough"," about Docker networking solutions, back to the topic.",[3126,87740,87742],{"id":87741},"how-does-the-traffic-flow-in-and-out-of-containers","How does the traffic flow in and out of containers?",[523,87744,87745],{},"We are now going to find out how the traffic flows when it enters and exits the container(s).\nSo we use the following tools, to check the traffic:",[668,87747,87748,87758],{},[638,87749,87750,6378,87753,2006],{},[567,87751,87752],{},"ip link show",[3049,87754,87755,87756,11500],{},"DON'T you dare use ",[567,87757,7519],{},[638,87759,87760,6374,87762],{},[567,87761,8254],{},[567,87763,38000],{},[6072,87765,87766],{},[523,87767,87768,8939,87770,87772,87773],{},[584,87769,2951],{},[567,87771,8294],{},", file: ",[567,87774,47087],{},[523,87776,87777,87778,856],{},"Let's see if Docker creates some type of network device for our database and WordPress container using ",[567,87779,87752],{},[6072,87781,87782],{},[523,87783,87784,87788],{},[584,87785,10412,87786],{},[567,87787,87752],{},[3069,87789],{"alt":87790,"src":87791},"Output: iptables output","\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop\u002Fdocker-ip-link-show-output.png",[523,87793,87794,87795,87797],{},"Docker creates a bridge device called ",[567,87796,7472],{}," and for every container, running in default network mode, it creates one veth interface per container and every veth interface get's an IP address from a specified pool. This IP address pool can be specified when starting Docker\u002Fthe Docker Engine.",[523,87799,87800],{},"Now we know that because of every container having it's own \"dedicated\" IP, Docker uses NAT (Network Address Translation). Meaning we need more than just a separate interface per container. That means there has to be some sort of \"routing\" \"process\". Let's check the iptables.",[523,87802,87803],{},"Are there any iptables rules added by Docker?:",[6072,87805,87806],{},[523,87807,87808,87816],{},[584,87809,10412,87810,587,87813],{},[567,87811,87812],{},"iptables -L",[567,87814,87815],{},"iptables -t nat -L",[3069,87817],{"alt":87790,"src":87818},"\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop\u002Fdocker-iptables-output.png",[523,87820,87821],{},"As we can see, Docker creates iptables rules to route the NAT traffic to and from the containers.",[523,87823,87824],{},"Docker has an userspace proxy, the \"proxy\" is required so the ports that are published\u002Fforwarded can't be used twice or more.\nCause iptables can't \"block\" a port from being used multiple times, that's why there is this userspace proxy in place.",[523,87826,87827,87828,87830,87831,87833,87834,87836],{},"So if we start a container with published port ",[567,87829,31891],{}," and then start another container also with port ",[567,87832,31891],{}," published, the second container can't start. The second container would \"crash\" with the message that the port ",[567,87835,31891],{}," is already in use. Cause the userspace proxy of the first container, has the port in use (\u002F \"blocks\" the port).",[6072,87838,87839,87843],{},[523,87840,87841],{},[584,87842,9515],{},[523,87844,87845,87846,87848,87849,87852],{},"Keep in mind, that default Docker networking works using NAT with iptables.\nIt is important, if you have other iptables rules, that are in place to filter incoming traffic, because Docker traffic goes through the ",[567,87847,8281],{},"-Chain and not the ",[567,87850,87851],{},"INPUT","-Chain!",[3126,87854,14526],{"id":18119},[523,87856,87857,87858,87860],{},"Docker creates a iptables chain in nat and filter table. Docker creates a bridge interface called ",[567,87859,7472],{},". Every container has it's own veth interface.",[3126,87862,87864],{"id":87863},"pointers-tuts-and-docs","Pointers, Tuts and Docs",[668,87866,87867,87874,87881,87888],{},[638,87868,87869],{},[527,87870,87873],{"href":87871,"rel":87872},"https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Fuserguide\u002Fnetworking\u002Fdockernetworks\u002F",[531],"Dockernetworks Doc",[638,87875,87876],{},[527,87877,87880],{"href":87878,"rel":87879},"https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Fuserguide\u002Fnetworking\u002Fget-started-overlay\u002F",[531],"Docker Native Overlay Network",[638,87882,87883],{},[527,87884,87887],{"href":87885,"rel":87886},"https:\u002F\u002Fgithub.com\u002Fweaveworks\u002Fscope#getting-started",[531],"WeaveScope Getting started",[638,87889,87890],{},[527,87891,87722],{"href":27031,"rel":87892},[531],[2979,87894],{},[613,87896,87898],{"id":87897},"data-and-layer-cakes-in-docker","Data and Layer Cakes in Docker",[3126,87900,87902],{"id":87901},"data-in-containers","Data in Containers",[6072,87904,87905],{},[523,87906,87907,8939,87909],{},[584,87908,2951],{},[567,87910,87911],{},"datait101",[523,87913,87914,87915,87917],{},"Data is not persistent in containers. Currently if we stop the database container and delete it, all data is gone. :(\nTo make data in a container persistent, we use ",[3049,87916,11175],{},". So to make our database data persistent, we add the following argument to the command.",[738,87919,87921],{"className":1621,"code":87920,"language":1623,"meta":743,"style":743},"docker run \\\n    --name mysql \\\n    -d \\\n    -e 'DB_NAME=wordpress' \\\n    -e 'DB_USER=wordpress' \\\n    -e 'DB_PASS=wordpress' \\\n    -v \u002Fopt\u002Fdocker\u002Fdatabase:\u002Fvar\u002Flib\u002Fmysql:rw \\\n    sameersbn\u002Fmysql:latest\n",[567,87922,87923,87931,87939,87945,87957,87969,87981,87990],{"__ignoreMap":743},[747,87924,87925,87927,87929],{"class":749,"line":750},[747,87926,3257],{"class":1630},[747,87928,3665],{"class":802},[747,87930,1641],{"class":1640},[747,87932,87933,87935,87937],{"class":749,"line":761},[747,87934,5790],{"class":802},[747,87936,5793],{"class":802},[747,87938,1641],{"class":1640},[747,87940,87941,87943],{"class":749,"line":769},[747,87942,5866],{"class":802},[747,87944,1641],{"class":1640},[747,87946,87947,87949,87951,87953,87955],{"class":749,"line":776},[747,87948,5991],{"class":802},[747,87950,3537],{"class":757},[747,87952,80779],{"class":802},[747,87954,3543],{"class":757},[747,87956,1641],{"class":1640},[747,87958,87959,87961,87963,87965,87967],{"class":749,"line":784},[747,87960,5991],{"class":802},[747,87962,3537],{"class":757},[747,87964,80753],{"class":802},[747,87966,3543],{"class":757},[747,87968,1641],{"class":1640},[747,87970,87971,87973,87975,87977,87979],{"class":749,"line":790},[747,87972,5991],{"class":802},[747,87974,3537],{"class":757},[747,87976,80766],{"class":802},[747,87978,3543],{"class":757},[747,87980,1641],{"class":1640},[747,87982,87983,87985,87988],{"class":749,"line":796},[747,87984,6139],{"class":802},[747,87986,87987],{"class":802}," \u002Fopt\u002Fdocker\u002Fdatabase:\u002Fvar\u002Flib\u002Fmysql:rw",[747,87989,1641],{"class":1640},[747,87991,87992],{"class":749,"line":806},[747,87993,80571],{"class":802},[6072,87995,87996,88000],{},[523,87997,87998],{},[584,87999,2957],{},[668,88001,88002],{},[638,88003,88004,19221,88007,88009,88010,11304,88012,88014,88015,587,88018,6378,88020,88023,88024,3052],{},[567,88005,88006],{},"-v HOST_PATH:CONTAINER_PATH:rw",[567,88008,6161],{}," path to mount from the host into the container at the ",[567,88011,6167],{},[567,88013,6177],{}," means ",[567,88016,88017],{},"read-write",[567,88019,6181],{},[567,88021,88022],{},"read-only",") are possible arguments too (default is ",[567,88025,6177],{},[523,88027,88028],{},"We have to stop the WordPress container first, because it is linked to the database container:",[738,88030,88032],{"className":1621,"code":88031,"language":1623,"meta":743,"style":743},"docker stop wordpress database\ndocker rm wordpress database\n",[567,88033,88034,88044],{"__ignoreMap":743},[747,88035,88036,88038,88040,88042],{"class":749,"line":750},[747,88037,3257],{"class":1630},[747,88039,5324],{"class":802},[747,88041,6842],{"class":802},[747,88043,43796],{"class":802},[747,88045,88046,88048,88050,88052],{"class":749,"line":761},[747,88047,3257],{"class":1630},[747,88049,5902],{"class":802},[747,88051,6842],{"class":802},[747,88053,43796],{"class":802},[523,88055,88056],{},"Now you can start the database container and the WordPress container again.",[3126,88058,8922],{"id":8921},[62787,88060,88061],{},"\n![Layer Cake from Wikimedia](\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop\u002Flayer-cake-from-wikimedia.png)\n_Mhh, tasty, isn't it?_ But now back to the topic.\n",[12608,88063],{},[6072,88065,88066],{},[523,88067,88068,8939,88070],{},[584,88069,2951],{},[567,88071,8946],{},[523,88073,88074],{},"In the Docker universe, a cake would be built from the bottom using a baseimage (or any other image as a base).\nEvery \"new\" layer on top of it, is an action that had been run when building the image.",[523,88076,8952,88077,8956,88079,8960],{},[567,88078,8955],{},[567,88080,8959],{},[62787,88082,88083],{},"\n![Docker Dockerfile Layers](\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop\u002Fdocker-data-dockerfile-layers.png)\n",[523,88085,8969,88086,88088],{},[567,88087,8972],{},", you would only have to download the created\u002Fmodified layers, because the baseimage is the same in this case.",[3126,88090,87864],{"id":88091},"pointers-tuts-and-docs-1",[668,88093,88094,88101],{},[638,88095,88096],{},[527,88097,88100],{"href":88098,"rel":88099},"https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Fuserguide\u002Fcontainers\u002Fdockervolumes\u002F",[531],"Docker Volumes Docs",[638,88102,88103],{},[527,88104,80099],{"href":80097,"rel":88105},[531],[2979,88107],{},[613,88109,88111],{"id":88110},"take-an-image-create-your-first-docker-image","Take an image! - Create your first Docker image",[523,88113,88114,88115,88117],{},"Let's set our goal to creating a simple nginx container. We use ",[567,88116,8972],{}," as the baseimage.",[3126,88119,14231,88121],{"id":88120},"a-dockerfile",[567,88122,8959],{},[523,88124,88125,88126,8984,88128,8987,88130,82516,88132,88134],{},"As you may have already seen in task ",[567,88127,8983],{},[567,88129,8959],{},[567,88131,8959],{},[567,88133,8959],{},"s there is a \"special\" syntax, but the syntax is very simple.",[6072,88136,88137,88147],{},[523,88138,88139,88141,88142,8287,88145,7258],{},[584,88140,82523],{}," (Taken from the ",[527,88143,9005],{"href":9003,"rel":88144},[531],[567,88146,8959],{},[738,88148,88149],{"className":9011,"code":743,"language":9013,"meta":743,"style":743},[567,88150,88151],{"__ignoreMap":743},[747,88152],{"class":749,"line":750},[523,88154,88155],{},"FROM debian:jessie",[523,88157,88158],{},"ENV EBOT_HOME=\"\u002Febot\" TIMEZONE=\"Europe\u002FBerlin\"",[523,88160,88161],{},"ADD entrypoint.sh \u002Fsbin\u002Fentrypoint.sh",[523,88163,88164,88165,88167,88168,88170,88171,88173,88174,88170,88176,88178,88179,88182,88183,88185,88186,88188,88189,88193,88194,88196,88197,88199,88200,88204,88205,88207,88208,88210,88211,88213,88214,88216],{},"RUN apt-get update && ",[12608,88166],{},"\napt-get -y upgrade && ",[12608,88169],{},"\napt-get clean && ",[12608,88172],{},"\napt-get -y install nodejs npm curl git php5-cli php5-mysql screen git && ",[12608,88175],{},[12608,88177],{},"\nsed -i \"s~;date.timezone =",[29708,88180,88181],{},"date.timezone = $TIMEZONE","g\" \u002Fetc\u002Fphp5\u002Fcli\u002Fphp.ini && ",[12608,88184],{},"\n\u002Fbin\u002Fln -s \u002Fusr\u002Fbin\u002Fnodejs \u002Fusr\u002Fbin\u002Fnode && ",[12608,88187],{},"\ncurl -sS ",[527,88190,88191],{"href":88191,"rel":88192},"https:\u002F\u002Fgetcomposer.org\u002Finstaller",[531]," | php -- --install-dir=\u002Fusr\u002Fbin && ",[12608,88195],{},"\nmkdir \"$EBOT_HOME\" && ",[12608,88198],{},"\ngit clone ",[527,88201,88202],{"href":88202,"rel":88203},"https:\u002F\u002Fgithub.com\u002FdeStrO\u002FeBot-CSGO.git",[531]," \"$EBOT_HOME\" && ",[12608,88206],{},"\ncd \"$EBOT_HOME\" && ",[12608,88209],{},"\ngit checkout \"master\" && ",[12608,88212],{},"\n\u002Fusr\u002Fbin\u002Fphp \u002Fusr\u002Fbin\u002Fcomposer.phar install && ",[12608,88215],{},"\nnpm install socket.io formidable archiver",[523,88218,88219],{},"COPY Match.php $EBOT_HOME\u002Fsrc\u002FeBot\u002FMatch\u002FMatch.php",[523,88221,88222,88223],{},"VOLUME ",[747,88224,88225],{},"\"$EBOT_HOME\u002Fdemos\", \"$EBOT_HOME\u002Flogs\"",[523,88227,88228],{},"EXPOSE 12360 12361",[523,88230,83024,88231],{},[747,88232,9215],{},[738,88234,88237],{"className":88235,"code":88236,"language":12479},[12477],"> **Advanced Dockerfile Example** (Taken from the [galexrt\u002Fdocker-zulip](https:\u002F\u002Fgithub.com\u002Fgalexrt\u002Fdocker-zulip) `Dockerfile`):\n> ```dockerfile\nFROM quay.io\u002Fsameersbn\u002Fubuntu:latest\nMAINTAINER Alexander Trost \u003Cgalexrt@googlemail.com>\n\nENV ZULIP_VERSION=\"master\" DATA_DIR=\"\u002Fdata\"\n\nADD entrypoint.sh \u002Fsbin\u002Fentrypoint.sh\n\nRUN apt-get -q update && \\\n    apt-get -q dist-upgrade -y && \\\n    apt-get install -y git && \\\n    mkdir -p \"$DATA_DIR\" \u002Froot\u002Fzulip && \\\n    git clone https:\u002F\u002Fgithub.com\u002Fzulip\u002Fzulip.git \u002Froot\u002Fzulip && \\\n    cd \u002Froot\u002Fzulip && \\\n    git checkout \"$ZULIP_VERSION\" && \\\n    rm -rf \u002Froot\u002Fzulip\u002F.git\n\nADD custom_zulip_files\u002F \u002Froot\u002Fcustom_zulip\n\nRUN cp -rf \u002Froot\u002Fcustom_zulip\u002F* \u002Froot\u002Fzulip && \\\n    VOYAGER_CLASS=\"dockervoyager\" DEPLOYMENT_TYPE=\"dockervoyager\" ADDITIONAL_PACKAGES=\"python-dev python-six python-pbs\" \\\n    \u002Froot\u002Fzulip\u002Fscripts\u002Fsetup\u002Finstall && \\\n    wget -q https:\u002F\u002Fwww.zulip.com\u002Fdist\u002Freleases\u002Fzulip-server-latest.tar.gz -O \u002Ftmp\u002Fzulip-server.tar.gz && \\\n    tar xfz \u002Ftmp\u002Fzulip-server.tar.gz -C \"\u002Fhome\u002Fzulip\u002Fprod-static\" --strip-components=3 --wildcards *\u002Fprod-static\u002Fserve && \\\n    rm -rf \u002Ftmp\u002Fzulip-server.tar.gz && \\\n    ln -nsf \u002Fhome\u002Fzulip\u002Fdeployments\u002Fcurrent\u002Fprod-static\u002Fserve \u002Fhome\u002Fzulip\u002Fprod-static && \\\n    apt-get -qq autoremove --purge -y && \\\n    apt-get -qq clean && \\\n    rm -rf \u002Froot\u002Fzulip\u002Fpuppet\u002F \u002Fvar\u002Flib\u002Fapt\u002Flists\u002F* \u002Ftmp\u002F* \u002Fvar\u002Ftmp\u002F*\n\nADD setup_files\u002F \u002Fopt\u002Ffiles\nADD includes\u002Fsupervisor\u002Fconf.d\u002Fzulip_postsetup.conf \u002Fetc\u002Fsupervisor\u002Fconf.d\u002Fzulip_postsetup.conf\nADD includes\u002FcreateZulipAdmin.sh \u002FcreateZulipAdmin.sh\n\nVOLUME [\"$DATA_DIR\"]\nEXPOSE 80 443\n\nENTRYPOINT [\"\u002Fsbin\u002Fentrypoint.sh\"]\nCMD [\"app:run\"]\n",[567,88238,88236],{"__ignoreMap":743},[523,88240,88241,88243],{},[584,88242,9494],{}," we're just making a very simple and basic example. ;)",[3126,88245,88247,88249],{"id":88246},"dockerfile-explained",[567,88248,8959],{}," explained",[6072,88251,88252,88258,88262],{},[523,88253,88254,8939,88256],{},[584,88255,2951],{},[567,88257,9510],{},[523,88259,88260],{},[584,88261,9515],{},[523,88263,48233,88264,82967,88266,1909],{},[567,88265,8959],{},[527,88267,48239],{"href":9522,"rel":88268},[531],[523,88270,9527,88271,88273,88274,9537],{},[567,88272,9530],{}," installed (You can later expand it, with more functionality, like with PHP-FPM).\nTo guide you in creating a nginx image, I show you an example http webserver written in golang as an example, before we create the \"final\" ",[567,88275,9530],{},[6072,88277,88278,88285],{},[523,88279,88280,82985,88282,2006],{},[584,88281,9542],{},[527,88283,82990],{"href":82988,"rel":88284},[531],[738,88286,88287],{"className":9011,"code":743,"language":9013,"meta":743,"style":743},[567,88288,88289],{"__ignoreMap":743},[747,88290],{"class":749,"line":750},[79989,88292,83000],{"id":82999},[523,88294,83003],{},[79989,88296,83007],{"id":83006},[523,88298,83010],{},[79989,88300,83014],{"id":83013},[523,88302,83017],{},[79989,88304,83021],{"id":83020},[523,88306,83024,88307],{},[747,88308,83027],{},[79989,88310,83031],{"id":83030},[523,88312,83034],{},[738,88314,88317],{"className":88315,"code":88316,"language":12479},[12477],"> **WDWD**\n> * `FROM ...` - Sets the baseimage.\n> * `COPY ... ...` - Copy files from the build root.\n> * `ADD ... ...` - Same as `COPY`, but target can be \"online\" and if it is an archive, it will be extracted.\n> * `RUN ...` - Run commands (Shell used `\u002Fbin\u002Fsh`).\n> * `ENTRYPOINT [\"...\"]` - The command to execute when the container is started.\n> * `CMD [\"...\"]` - Arguments for the `ENTRYPOINT`.\n> * `EXPOSE 8080 ...` - Expose a port when linked (_If not specified port not reachable when linked!_).\n\nThere's even the possibility, to execute specific commands when the image is used as a base image, the instruction is called `ONBUILD ...`.\n\nTo build your image we use the `docker build` command. Building the example image run the following command:\n\n```bash\ndocker build -t golang-docker -f Dockerfile .\n",[567,88318,88316],{"__ignoreMap":743},[6072,88320,88321,88325],{},[523,88322,88323],{},[584,88324,2957],{},[668,88326,88327,88331,88340,88346],{},[638,88328,88329,9759],{},[567,88330,9758],{},[638,88332,88333,88336,88337,88339],{},[567,88334,88335],{},"-t TAG_NAME"," - Specify the tag\u002F name of the image, you are creating (Optional. ",[584,88338,9791],{}," when manually building and pushing a Docker image).",[638,88341,88342,9780,88344,9783],{},[567,88343,9779],{},[567,88345,8959],{},[638,88347,88348,88350,88351,9792,88353,6374,88355,9797,88357,3052],{},[567,88349,3326],{}," - The root of the image build (",[584,88352,9791],{},[567,88354,9669],{},[567,88356,9053],{},[567,88358,8959],{},[523,88360,83083,88361,1909],{},[527,88362,3396],{"href":83086,"rel":88363},[531],[3126,88365,88367,88368,3702],{"id":88366},"creating-the-nginx-image","Creating the ",[567,88369,9530],{},[523,88371,10331,88372,10334,88374,10337,88376,1909],{},[567,88373,8959],{},[567,88375,9530],{},[567,88377,8972],{},[523,88379,10342,88380,10346,88382,7258],{},[567,88381,10345],{},[527,88383,3396],{"href":88384},"#For-the-nginx-Dockerfile",[738,88386,88387],{"className":9011,"code":10352,"language":9013,"meta":743,"style":743},[567,88388,88389,88395,88399,88405,88409],{"__ignoreMap":743},[747,88390,88391,88393],{"class":749,"line":750},[747,88392,9020],{"class":1895},[747,88394,10361],{"class":1640},[747,88396,88397],{"class":749,"line":761},[747,88398,1255],{"emptyLinePlaceholder":1254},[747,88400,88401,88403],{"class":749,"line":769},[747,88402,9065],{"class":1895},[747,88404,10361],{"class":1640},[747,88406,88407],{"class":749,"line":776},[747,88408,1255],{"emptyLinePlaceholder":1254},[747,88410,88411,88413,88415,88417],{"class":749,"line":784},[747,88412,9210],{"class":1895},[747,88414,4262],{"class":1640},[747,88416,10384],{"class":802},[747,88418,4268],{"class":1640},[523,88420,10389],{},[738,88422,88423],{"className":1621,"code":10392,"language":1623,"meta":743,"style":743},[567,88424,88425],{"__ignoreMap":743},[747,88426,88427,88429,88431,88433,88435],{"class":749,"line":750},[747,88428,3257],{"class":1630},[747,88430,9733],{"class":802},[747,88432,9736],{"class":802},[747,88434,10405],{"class":802},[747,88436,9747],{"class":802},[6072,88438,88439],{},[523,88440,88441,88445],{},[584,88442,10412,88443],{},[567,88444,10415],{},[3069,88446],{"alt":10420,"src":88447},"\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop\u002Fdocker-build-nginx-image.png",[523,88449,10424,88450,856],{},[567,88451,88452],{},"nginx-workshop",[738,88454,88456],{"className":1621,"code":88455,"language":1623,"meta":743,"style":743},"docker run \\\n    --name nginx-workshop \\\n    -d \\\n    -p 80:80 \\\n    workshop-nginx\n",[567,88457,88458,88466,88475,88481,88489],{"__ignoreMap":743},[747,88459,88460,88462,88464],{"class":749,"line":750},[747,88461,3257],{"class":1630},[747,88463,3665],{"class":802},[747,88465,1641],{"class":1640},[747,88467,88468,88470,88473],{"class":749,"line":761},[747,88469,5790],{"class":802},[747,88471,88472],{"class":802}," nginx-workshop",[747,88474,1641],{"class":1640},[747,88476,88477,88479],{"class":749,"line":769},[747,88478,5866],{"class":802},[747,88480,1641],{"class":1640},[747,88482,88483,88485,88487],{"class":749,"line":776},[747,88484,6614],{"class":802},[747,88486,6990],{"class":802},[747,88488,1641],{"class":1640},[747,88490,88491],{"class":749,"line":784},[747,88492,10467],{"class":802},[523,88494,10470,88495,10473],{},[567,88496,6446],{},[738,88498,88499],{"className":1621,"code":10476,"language":1623,"meta":743,"style":743},[567,88500,88501],{"__ignoreMap":743},[747,88502,88503,88505,88507],{"class":749,"line":750},[747,88504,3257],{"class":1630},[747,88506,5902],{"class":802},[747,88508,10487],{"class":802},[523,88510,10490,88511,1909],{},[567,88512,5819],{},[6072,88514,88515,88519],{},[523,88516,88517],{},[584,88518,2957],{},[668,88520,88521,88527],{},[638,88522,88523,10504,88525,48780],{},[567,88524,10503],{},[567,88526,48779],{},[638,88528,88529,10512],{},[567,88530,4164],{},[523,88532,10515,88533,10519],{},[567,88534,10518],{},[523,88536,10522,88537,10525,88539,10529,88541,10532,88543,3052],{},[567,88538,9530],{},[567,88540,10528],{},[567,88542,9210],{},[567,88544,8959],{},[523,88546,10537,88547,10541,88549,10544,88551,10548,88553,10551],{},[567,88548,10540],{},[567,88550,10540],{},[584,88552,10547],{},[567,88554,9210],{},[738,88556,88557],{"className":1621,"code":10554,"language":1623,"meta":743,"style":743},[567,88558,88559],{"__ignoreMap":743},[747,88560,88561,88563,88565,88567,88569,88571,88573,88575,88577,88579,88581,88583,88585,88587],{"class":749,"line":750},[747,88562,9210],{"class":1630},[747,88564,4262],{"class":1640},[747,88566,3892],{"class":757},[747,88568,9530],{"class":802},[747,88570,3892],{"class":757},[747,88572,714],{"class":1640},[747,88574,3892],{"class":757},[747,88576,10575],{"class":802},[747,88578,3892],{"class":757},[747,88580,10580],{"class":802},[747,88582,969],{"class":757},[747,88584,10585],{"class":802},[747,88586,3892],{"class":757},[747,88588,4268],{"class":802},[523,88590,10592,88591,10597],{},[527,88592,10595],{"href":10595,"rel":88593},[531],[523,88595,10600,88596,10604,88598,8301,88600,10609],{},[567,88597,10603],{},[567,88599,10603],{},[567,88601,9510],{},[523,88603,10612,88604,10616,88606,48867],{},[567,88605,10615],{},[567,88607,4203],{},[738,88609,88610],{"className":1621,"code":10629,"language":1623,"meta":743,"style":743},[567,88611,88612,88620,88628,88634,88642,88662],{"__ignoreMap":743},[747,88613,88614,88616,88618],{"class":749,"line":750},[747,88615,3257],{"class":1630},[747,88617,3665],{"class":802},[747,88619,1641],{"class":1640},[747,88621,88622,88624,88626],{"class":749,"line":761},[747,88623,5790],{"class":802},[747,88625,10405],{"class":802},[747,88627,1641],{"class":1640},[747,88629,88630,88632],{"class":749,"line":769},[747,88631,5866],{"class":802},[747,88633,1641],{"class":1640},[747,88635,88636,88638,88640],{"class":749,"line":776},[747,88637,6614],{"class":802},[747,88639,10660],{"class":802},[747,88641,1641],{"class":1640},[747,88643,88644,88646,88648,88650,88652,88654,88656,88658,88660],{"class":749,"line":784},[747,88645,6139],{"class":802},[747,88647,10669],{"class":757},[747,88649,10672],{"class":4574},[747,88651,10675],{"class":757},[747,88653,856],{"class":802},[747,88655,3892],{"class":757},[747,88657,10682],{"class":802},[747,88659,3892],{"class":757},[747,88661,1641],{"class":1640},[747,88663,88664],{"class":749,"line":790},[747,88665,10467],{"class":802},[523,88667,10711,88668,10714,88670,10717,88672,10720,88674,10724,88677,10727],{},[567,88669,10427],{},[567,88671,10427],{},[567,88673,10682],{},[527,88675,10595],{"href":10595,"rel":88676},[531],[567,88678,10603],{},[3126,88680,14526],{"id":88681},"summary-2",[523,88683,88684,88685,88687,88688,88690],{},"We have created our own working ",[567,88686,9530],{}," image.\nWe are able to mount a folder into the container and see it's content per ",[567,88689,9530],{}," web server.",[3126,88692,87864],{"id":88693},"pointers-tuts-and-docs-2",[668,88695,88696,88701,88708],{},[638,88697,88698],{},[527,88699,48239],{"href":9522,"rel":88700},[531],[638,88702,88703],{},[527,88704,88707],{"href":88705,"rel":88706},"https:\u002F\u002Fwww.digitalocean.com\u002Fcommunity\u002Ftutorials\u002Fdocker-explained-using-dockerfiles-to-automate-building-of-images",[531],"Digitialocean Docker explained: Dockerfiles to automate building of images",[638,88709,88710],{},[527,88711,88714],{"href":88712,"rel":88713},"http:\u002F\u002Fcrosbymichael.com\u002Fdockerfile-best-practices.html",[531],"Dockerfile Best Practices by Michael Crosby",[2979,88716],{},[613,88718,88720],{"id":88719},"docker-composeyml-aka-simpleness-for-multi-container-applications","docker-compose.yml aka \"Simpleness for multi container applications\"",[3126,88722,10805],{"id":10804},[6072,88724,88725],{},[523,88726,88727,8939,88729],{},[584,88728,2951],{},[567,88730,11258],{},[523,88732,10808,88733,10811,88735,10814,88737,10818,88739,10822,88741,10826,88743,1909],{},[567,88734,2936],{},[567,88736,2936],{},[3049,88738,10817],{},[567,88740,10821],{},[3049,88742,10825],{},[527,88744,3396],{"href":10829,"rel":88745},[531],[523,88747,10833,88748,88750],{},[567,88749,10821],{}," for our database, WordPress and as an extra we'll add phpMyAdmin to it.",[523,88752,10839,88753,10842,88755,10346,88757,7258],{},[567,88754,10821],{},[567,88756,10345],{},[527,88758,3396],{"href":88759},"#For-WordPress-docker-compose-yml",[738,88761,88763],{"className":1621,"code":88762,"language":1623,"meta":743,"style":743},"# Taken from https:\u002F\u002Fwww.digitalocean.com\u002Fcommunity\u002Ftutorials\u002Fhow-to-install-wordpress-and-phpmyadmin-with-docker-compose-on-ubuntu-14-04\ndatabase:\n  image: sameersbn\u002Fmysql:latest\n  environment:\n    DB_NAME: wordpress\n    DB_USER: wordpress\n    DB_PASS: wordpress\n    DB_REMOTE_ROOT_NAME: root\n    DB_REMOTE_ROOT_PASS: workshop\n  volumes:\n    - \"\u002Fopt\u002Fdocker\u002Fdatabase:\u002Fvar\u002Flib\u002Fmysql:rw\"\nwordpress:\n  image: wordpress\n  links:\n    - __BLANK__:mysql\n  ports:\n    - 8080:80\n  environment:\n    WORDPRESS_DB_HOST: __BLANK__:3306\n    WORDPRESS_DB_NAME: __BLANK__\n    WORDPRESS_DB_USER: __BLANK__\n    WORDPRESS_DB_PASSWORD: __BLANK__\n    WORDPRESS_AUTH_KEY: SECURE_AUTH_KEY\n    WORDPRESS_LOGGED_IN_KEY: SECURE_LOGGED_IN_KEY\n    WORDPRESS_AUTH_SALT: SECURE_AUTH_SALT\n    WORDPRESS_LOGGED_IN_SALT: SECURE_LOGGED_IN_SALT\nphpmyadmin:\n  image: corbinu\u002Fdocker-phpmyadmin\n  links:\n    - __BLANK__:mysql\n  ports:\n    - 8181:80\n  environment:\n    MYSQL_USERNAME: root\n    MYSQL_ROOT_PASSWORD: wordpress\n",[567,88764,88765,88769,88773,88779,88783,88789,88795,88801,88807,88813,88817,88827,88831,88837,88841,88847,88851,88857,88861,88867,88873,88879,88885,88891,88897,88903,88909,88913,88920,88924,88930,88934,88940,88944,88951],{"__ignoreMap":743},[747,88766,88767],{"class":749,"line":750},[747,88768,86476],{"class":772},[747,88770,88771],{"class":749,"line":761},[747,88772,83564],{"class":1630},[747,88774,88775,88777],{"class":749,"line":769},[747,88776,49331],{"class":1630},[747,88778,83571],{"class":802},[747,88780,88781],{"class":749,"line":776},[747,88782,83576],{"class":1630},[747,88784,88785,88787],{"class":749,"line":784},[747,88786,83581],{"class":1630},[747,88788,6540],{"class":802},[747,88790,88791,88793],{"class":749,"line":790},[747,88792,83588],{"class":1630},[747,88794,6540],{"class":802},[747,88796,88797,88799],{"class":749,"line":796},[747,88798,83595],{"class":1630},[747,88800,6540],{"class":802},[747,88802,88803,88805],{"class":749,"line":806},[747,88804,83602],{"class":1630},[747,88806,11156],{"class":802},[747,88808,88809,88811],{"class":749,"line":814},[747,88810,83609],{"class":1630},[747,88812,11166],{"class":802},[747,88814,88815],{"class":749,"line":822},[747,88816,83616],{"class":1630},[747,88818,88819,88821,88823,88825],{"class":749,"line":830},[747,88820,18665],{"class":1630},[747,88822,969],{"class":757},[747,88824,49135],{"class":802},[747,88826,975],{"class":757},[747,88828,88829],{"class":749,"line":836},[747,88830,83636],{"class":1630},[747,88832,88833,88835],{"class":749,"line":842},[747,88834,49331],{"class":1630},[747,88836,6540],{"class":802},[747,88838,88839],{"class":749,"line":850},[747,88840,83647],{"class":1630},[747,88842,88843,88845],{"class":749,"line":863},[747,88844,18665],{"class":1630},[747,88846,83654],{"class":802},[747,88848,88849],{"class":749,"line":869},[747,88850,83659],{"class":1630},[747,88852,88853,88855],{"class":749,"line":877},[747,88854,18665],{"class":1630},[747,88856,11000],{"class":802},[747,88858,88859],{"class":749,"line":1015},[747,88860,83576],{"class":1630},[747,88862,88863,88865],{"class":749,"line":1021},[747,88864,83674],{"class":1630},[747,88866,11016],{"class":802},[747,88868,88869,88871],{"class":749,"line":1027},[747,88870,83681],{"class":1630},[747,88872,10361],{"class":802},[747,88874,88875,88877],{"class":749,"line":1033},[747,88876,83688],{"class":1630},[747,88878,10361],{"class":802},[747,88880,88881,88883],{"class":749,"line":1039},[747,88882,83695],{"class":1630},[747,88884,10361],{"class":802},[747,88886,88887,88889],{"class":749,"line":1054},[747,88888,83702],{"class":1630},[747,88890,11053],{"class":802},[747,88892,88893,88895],{"class":749,"line":1060},[747,88894,83709],{"class":1630},[747,88896,11063],{"class":802},[747,88898,88899,88901],{"class":749,"line":1066},[747,88900,83716],{"class":1630},[747,88902,11073],{"class":802},[747,88904,88905,88907],{"class":749,"line":1081},[747,88906,83723],{"class":1630},[747,88908,11083],{"class":802},[747,88910,88911],{"class":749,"line":1087},[747,88912,83735],{"class":1630},[747,88914,88915,88917],{"class":749,"line":1102},[747,88916,49331],{"class":1630},[747,88918,88919],{"class":802}," corbinu\u002Fdocker-phpmyadmin\n",[747,88921,88922],{"class":749,"line":1110},[747,88923,83647],{"class":1630},[747,88925,88926,88928],{"class":749,"line":1117},[747,88927,18665],{"class":1630},[747,88929,83654],{"class":802},[747,88931,88932],{"class":749,"line":1123},[747,88933,83659],{"class":1630},[747,88935,88936,88938],{"class":749,"line":1129},[747,88937,18665],{"class":1630},[747,88939,11130],{"class":802},[747,88941,88942],{"class":749,"line":1142},[747,88943,83576],{"class":1630},[747,88945,88946,88949],{"class":749,"line":1150},[747,88947,88948],{"class":1630},"    MYSQL_USERNAME:",[747,88950,11156],{"class":802},[747,88952,88953,88956],{"class":749,"line":1157},[747,88954,88955],{"class":1630},"    MYSQL_ROOT_PASSWORD:",[747,88957,6540],{"class":802},[6072,88959,88960,88964],{},[523,88961,88962],{},[584,88963,2957],{},[668,88965,88966,88970,88974,88978,88982],{},[638,88967,88968,49326],{},[567,88969,49325],{},[638,88971,88972,11216],{},[567,88973,49331],{},[638,88975,88976,11222],{},[567,88977,49336],{},[638,88979,88980,11228],{},[567,88981,49341],{},[638,88983,88984,11234,88986,3052],{},[567,88985,49346],{},[567,88987,11237],{},[523,88989,49352,88990,587,88992,88994],{},[567,88991,49355],{},[567,88993,49358],{},", so that phpMyAdmin can access the database.",[3126,88996,11247],{"id":11246},[523,88998,88999,89000,11264],{},"To \"run\"\u002Fstart our ",[567,89001,10821],{},[738,89003,89005],{"className":1621,"code":89004,"language":1623,"meta":743,"style":743},"docker-compose up -f DOCKER_COMPOSE_YML\n",[567,89006,89007],{"__ignoreMap":743},[747,89008,89009,89011,89013,89015],{"class":749,"line":750},[747,89010,2936],{"class":1630},[747,89012,16403],{"class":802},[747,89014,1934],{"class":802},[747,89016,89017],{"class":802}," DOCKER_COMPOSE_YML\n",[6072,89019,89020,89024],{},[523,89021,89022],{},[584,89023,2957],{},[668,89025,89026,89033,89037,89042],{},[638,89027,89028,89030,89031,1909],{},[567,89029,11300],{}," - Optional. Default is ",[567,89032,10821],{},[638,89034,89035,11317],{},[567,89036,11316],{},[638,89038,89039,89041],{},[567,89040,11360],{}," - Stops the containers defined in the given docker-compose file.",[638,89043,89044,89046],{},[567,89045,11411],{}," - Deletes the containers defined in the given docker-compose file.",[6072,89048,89049,89053],{},[523,89050,89051],{},[584,89052,9515],{},[523,89054,49725,89055,89057,89058,89060],{},[567,89056,9779],{}," argument in mind, when creating multiple ",[567,89059,10821],{},"'s.",[3126,89062,89064,89065,11500],{"id":89063},"lets-do-more-with-docker-compose","Let's do more with ",[567,89066,2936],{},[6072,89068,89069],{},[523,89070,89071,8939,89073,84044,89075,11517,89077,11520,89079,89081,89082,10548,89085,89087],{},[584,89072,2951],{},[567,89074,11511],{},[567,89076,10821],{},[567,89078,10821],{},[567,89080,2936],{}," a bit.\n",[584,89083,89084],{},"And don't forget",[567,89086,11300],{}," argument. ;)",[3126,89089,14526],{"id":89090},"summary-3",[523,89092,11541,89093,11544],{},[567,89094,10821],{},[3126,89096,87864],{"id":89097},"pointers-tuts-and-docs-3",[668,89099,89100,89107],{},[638,89101,89102],{},[527,89103,89106],{"href":89104,"rel":89105},"https:\u002F\u002Fdocs.docker.com\u002Fcompose\u002F",[531],"Docker Compose Docs",[638,89108,89109],{},[527,89110,89113],{"href":89111,"rel":89112},"https:\u002F\u002Fwww.digitalocean.com\u002Fcommunity\u002Ftutorials\u002Fhow-to-install-and-use-docker-compose-on-ubuntu-14-04",[531],"Digitalocean Docker Compose Installation Guide",[2979,89115],{},[6072,89117,89118],{},[523,89119,89120],{},"Below this line, everythings a bit vague and still needs some writing to be done. Please be aware of that!\nThis line will slowly move down, until I'm finished. ;)",[2979,89122],{},[6072,89124,89125],{},[523,89126,89127],{},[584,89128,89129],{},"Read this section carefully! This sections explain the basic principles of Kubernetes.",[613,89131,89133],{"id":89132},"kubessar-glossar","Kubessar - Glossar",[523,89135,89136],{},"Like a glossar, but for Kubernetes.",[668,89138,89139,89142,89145,89148,89151,89154,89157],{},[638,89140,89141],{},"Pod - A set of one or more containers.",[638,89143,89144],{},"ReplicationController - Replication for Pods.",[638,89146,89147],{},"Services - Exposing Pod ports as a service (\"loadbalanced\") to other pods.",[638,89149,89150],{},"Namespaces - Everything runs in a namespace.",[638,89152,89153],{},"ResourceQuotas - Quotas for \"everything\" in a namespace.",[638,89155,89156],{},"kubeclt Files - Run\u002F\"Deployment\" files for the kubectl command.",[638,89158,89159],{},"\"Object\" - A Pod, ReplicationController, Service or Namespace. A \"part\" of the available ressources to use with the Kubernetes API.",[523,89161,89162],{},"I highly recommend you to look through my Kubernetes presentation to get to know Kubernetes a bit before starting to work with it.\nKeep in mind, the presentation is written in german.",[18903,89164],{"src":89165,"frameBorder":3579,"width":89166,"height":79961,"allowFullScreen":5306,"mozallowfullscreen":5306,"webkitallowfullscreen":5306},"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002F1XHl6MlB0GE2rmoXbe5_603UFVkFF2S3ud6Uc0QI7fPo\u002Fembed?start=false&loop=true&delayms=5000",960,[2979,89168],{},[613,89170,89172],{"id":89171},"conductor-of-the-orchestra-kubernetes","Conductor of the orchestra - Kubernetes",[523,89174,89175],{},[3069,89176],{"alt":27731,"src":27584},[3126,89178,39515],{"id":89179},"side-notes-1",[668,89181,89182],{},[638,89183,89184],{},"Certificates are \"hard\" to generate, I'll be using the kubernetes ansible cert creation script.",[3126,89186,89188],{"id":89187},"installing-ansible","Installing Ansible",[523,89190,89191],{},[3049,89192,84724],{},[6072,89194,89195],{},[523,89196,84729,89197,84733],{},[567,89198,84732],{},[523,89200,84736,89201,84742],{},[527,89202,84741],{"href":84739,"rel":89203},[531],[523,89205,84747,89206,89209,89210,89213,89214],{},[527,89207,84750],{"href":84750,"rel":89208},[531],"\nFor Debian: ",[527,89211,84758],{"href":84758,"rel":89212},[531],"\nFor CentOS: ",[527,89215,84765],{"href":84765,"rel":89216},[531],[3126,89218,89220],{"id":89219},"create-the-inventory-for-the-cluster","Create the inventory for the cluster",[6072,89222,89223],{},[523,89224,89225,8939,89227],{},[584,89226,2951],{},[567,89228,29729],{},[523,89230,89231,89232,1909],{},"Enter the cloned repository and look out for a directory called ",[567,89233,84788],{},[523,89235,76786,89236,89238],{},[567,89237,84793],{},", this file will contain the list of servers.\nPer server one line in the format below (username and password are valid for the provided vm, change to suit your environment):",[738,89240,89241],{"className":1621,"code":84797,"language":1623,"meta":743,"style":743},[567,89242,89243,89251,89255,89265,89269,89277,89281,89291,89299,89309,89313,89321,89325,89335,89343],{"__ignoreMap":743},[747,89244,89245,89247,89249],{"class":749,"line":750},[747,89246,4253],{"class":757},[747,89248,84806],{"class":1640},[747,89250,4268],{"class":757},[747,89252,89253],{"class":749,"line":761},[747,89254,84813],{"class":772},[747,89256,89257,89259,89261,89263],{"class":749,"line":769},[747,89258,84818],{"class":1630},[747,89260,84821],{"class":802},[747,89262,84824],{"class":802},[747,89264,84827],{"class":802},[747,89266,89267],{"class":749,"line":776},[747,89268,1255],{"emptyLinePlaceholder":1254},[747,89270,89271,89273,89275],{"class":749,"line":784},[747,89272,4253],{"class":757},[747,89274,26658],{"class":1640},[747,89276,4268],{"class":757},[747,89278,89279],{"class":749,"line":790},[747,89280,84844],{"class":772},[747,89282,89283,89285,89287,89289],{"class":749,"line":796},[747,89284,84818],{"class":1630},[747,89286,84821],{"class":802},[747,89288,84824],{"class":802},[747,89290,84827],{"class":802},[747,89292,89293,89295,89297],{"class":749,"line":806},[747,89294,4253],{"class":757},[747,89296,5685],{"class":1640},[747,89298,4268],{"class":757},[747,89300,89301,89303,89305,89307],{"class":749,"line":814},[747,89302,84818],{"class":1630},[747,89304,84821],{"class":802},[747,89306,84824],{"class":802},[747,89308,84827],{"class":802},[747,89310,89311],{"class":749,"line":822},[747,89312,1255],{"emptyLinePlaceholder":1254},[747,89314,89315,89317,89319],{"class":749,"line":830},[747,89316,4253],{"class":757},[747,89318,84883],{"class":1640},[747,89320,4268],{"class":757},[747,89322,89323],{"class":749,"line":836},[747,89324,84890],{"class":772},[747,89326,89327,89329,89331,89333],{"class":749,"line":842},[747,89328,84818],{"class":1630},[747,89330,84897],{"class":802},[747,89332,84900],{"class":802},[747,89334,84903],{"class":802},[747,89336,89337,89339,89341],{"class":749,"line":850},[747,89338,4253],{"class":757},[747,89340,5685],{"class":1640},[747,89342,4268],{"class":757},[747,89344,89345,89347,89349,89351],{"class":749,"line":863},[747,89346,84818],{"class":1630},[747,89348,84897],{"class":802},[747,89350,84900],{"class":802},[747,89352,84903],{"class":802},[6072,89354,89355,89359],{},[523,89356,89357],{},[584,89358,2957],{},[668,89360,89361,89365,89371,89375,89379],{},[638,89362,89363,84935],{},[567,89364,84934],{},[638,89366,89367,19221,89369,84943],{},[567,89368,84818],{},[567,89370,84942],{},[638,89372,89373,84949],{},[567,89374,84948],{},[638,89376,89377,84955],{},[567,89378,84954],{},[638,89380,89381,84961],{},[567,89382,84960],{},[523,89384,84964,89385,84968],{},[567,89386,84967],{},[523,89388,89389],{},"No syntax errors? Let's bring the cluster up!",[3126,89391,89393],{"id":89392},"bringing-up-your-cluster-with-ansible","Bringing up your cluster with Ansible",[6072,89395,89396],{},[523,89397,89398],{},[584,89399,89400],{},"All the servers need to have python installed!",[523,89402,89403,89404,85016,89406,89408],{},"Before you continue to do anything, go to the task ",[567,89405,29729],{},[567,89407,85008],{}," script. The script will download and setup all files required for the deployment of the cluster.",[523,89410,89411],{},"If the script exits with an error, please get in touch with me (It should normally not exit with an error).",[523,89413,89414,89415,89417,89418,89421,89422,89424],{},"Then navigate into the ",[567,89416,85015],{}," directory, run ",[567,89419,89420],{},".\u002Fsetup.sh -vvvv "," (the ",[567,89423,85023],{}," are for verbose), this will setup all machines to your needings.",[523,89426,89427,89428,89433],{},"If a step fails (It shouldn't fail), try to fix it through ",[527,89429,89432],{"href":89430,"rel":89431},"http:\u002F\u002Flmgtfy.com\u002F",[531],"MAGIC",", most problems are solved by just running the command again.",[3126,89435,14526],{"id":89436},"summary-4",[523,89438,85045,89439,8287,89442,89445],{},[584,89440,89441],{},"DON'T use this setup in production!",[3049,89443,89444],{},"There is more work required to make it secure for productions use.",").\nWe are now ready to deploy a WordPress with Mysql on it :)",[3126,89447,87864],{"id":89448},"pointers-tuts-and-docs-4",[668,89450,89451,89477,89490,89498],{},[638,89452,89453,89454],{},"Kubernetes\n",[668,89455,89456,89461,89468,89471,89474],{},[638,89457,89458],{},[584,89459,89460],{},"My favorite one",[638,89462,89463],{},[527,89464,89467],{"href":89465,"rel":89466},"http:\u002F\u002Fkubernetes.io\u002Fv1.1\u002Fbasicstutorials.html",[531],"Kubernetes Basics",[638,89469,89470],{},"Storage \"Management\"",[638,89472,89473],{},"Service Loadbalancing (Kubernetes Style)",[638,89475,89476],{},"Uses a Key-Value Storage",[638,89478,89479,89480],{},"Docker Swarm\n",[668,89481,89482,89485,89488],{},[638,89483,89484],{},"Requires Docker Daemon to run on a network socket",[638,89486,89487],{},"Authentication using Certificates",[638,89489,89476],{},[638,89491,89492,89493],{},"Shipyard\n",[668,89494,89495],{},[638,89496,89497],{},"Simple setup",[638,89499,89500,89501],{},"Rancher\n",[668,89502,89503],{},[638,89504,89505],{},"Simple (non-https and non-ha) setup",[613,89507,89509],{"id":89508},"first-deployment-with-kubernetes","First Deployment with Kubernetes",[6072,89511,89512],{},[523,89513,89514,8939,89516],{},[584,89515,2951],{},[567,89517,30363],{},[3126,89519,89521],{"id":89520},"kubectl-files","kubectl Files",[523,89523,89524,89525,89527,89528,89530],{},"kubectl files, as I call them, are written in YAML (",[3049,89526,10825],{},") like ",[567,89529,10821],{}," files, but have some \"big\" differences.\nLet's take a look at an example of a WordPress, Database and phpMyAdmin Pod and services.",[523,89532,89533],{},"These files are also located in the task directory and are here shown for people that haven't cloned the workshop repository.",[6072,89535,89536],{},[523,89537,89538,89540],{},[584,89539,2957],{}," comments are included in the code boxes.",[3142,89542,89543],{"id":6725},"WordPress",[33091,89545,25722],{"id":38655},[738,89547,89549],{"className":1621,"code":89548,"language":1623,"meta":743,"style":743},"# Kubernetes API version\napiVersion: v1\n# Type of \"request\"\nkind: Pod\n# Metadata of the \"object\"\nmetadata:\n  # Name of the \"object\"\n  name: wordpress\n  # Labels of the \"object\"\n  labels:\n    # A lable named \"name\" with value \"wordpress\"\n    name: wordpress\n# spec ~= Specifications of the \"object\"\nspec:\n  # List of Container definitions\n  containers:\n    # What Docker image to use\n    - image: wordpress\n      # The \"name\"\u002F\"suffix\" of the container name\n      name: wordpress\n      # List of environment variables\n      env:\n        - name: WORDPRESS_DB_HOST\n          value: mysql.default:3306\n        - name: WORDPRESS_DB_NAME\n          value: wordpress\n        - name: WORDPRESS_DB_USER\n          value: wordpress\n        - name: WORDPRESS_DB_PASSWORD\n          value: wordpress\n        - name: WORDPRESS_AUTH_KEY\n          value: SECURE_AUTH_KEY\n        - name: WORDPRESS_LOGGED_IN_KEY\n          value: SECURE_LOGGED_IN_KEY\n        - name: WORDPRESS_AUTH_SALT\n          value: SECURE_AUTH_SALT\n        - name: WORDPRESS_LOGGED_IN_SALT\n          value: SECURE_LOGGED_IN_SALT\n      # List of ports to \"publish\"\n      ports:\n        # ContainerPort exposes only to the inside of your network, not to the outside\n        # To reach the container we create a cluster wide service\n        - containerPort: 80\n          # gives the port a name\n          name: wordpress\n",[567,89550,89551,89555,89561,89565,89571,89575,89579,89583,89589,89593,89597,89601,89607,89611,89615,89619,89623,89627,89635,89639,89645,89649,89653,89661,89667,89675,89681,89689,89695,89703,89709,89717,89723,89731,89737,89745,89751,89759,89765,89769,89773,89777,89781,89789,89793],{"__ignoreMap":743},[747,89552,89553],{"class":749,"line":750},[747,89554,85707],{"class":772},[747,89556,89557,89559],{"class":749,"line":761},[747,89558,23195],{"class":1630},[747,89560,22608],{"class":802},[747,89562,89563],{"class":749,"line":769},[747,89564,85993],{"class":772},[747,89566,89567,89569],{"class":749,"line":776},[747,89568,23230],{"class":1630},[747,89570,28795],{"class":802},[747,89572,89573],{"class":749,"line":784},[747,89574,85729],{"class":772},[747,89576,89577],{"class":749,"line":790},[747,89578,23238],{"class":1630},[747,89580,89581],{"class":749,"line":796},[747,89582,85738],{"class":772},[747,89584,89585,89587],{"class":749,"line":806},[747,89586,23251],{"class":1630},[747,89588,6540],{"class":802},[747,89590,89591],{"class":749,"line":814},[747,89592,85749],{"class":772},[747,89594,89595],{"class":749,"line":822},[747,89596,85643],{"class":1630},[747,89598,89599],{"class":749,"line":830},[747,89600,86030],{"class":772},[747,89602,89603,89605],{"class":749,"line":836},[747,89604,37583],{"class":1630},[747,89606,6540],{"class":802},[747,89608,89609],{"class":749,"line":842},[747,89610,86041],{"class":772},[747,89612,89613],{"class":749,"line":850},[747,89614,37531],{"class":1630},[747,89616,89617],{"class":749,"line":863},[747,89618,85778],{"class":772},[747,89620,89621],{"class":749,"line":869},[747,89622,37536],{"class":1630},[747,89624,89625],{"class":749,"line":877},[747,89626,86058],{"class":772},[747,89628,89629,89631,89633],{"class":749,"line":1015},[747,89630,18665],{"class":1630},[747,89632,37543],{"class":802},[747,89634,6540],{"class":802},[747,89636,89637],{"class":749,"line":1021},[747,89638,86071],{"class":772},[747,89640,89641,89643],{"class":749,"line":1027},[747,89642,86076],{"class":1630},[747,89644,6540],{"class":802},[747,89646,89647],{"class":749,"line":1033},[747,89648,86083],{"class":772},[747,89650,89651],{"class":749,"line":1039},[747,89652,85813],{"class":1630},[747,89654,89655,89657,89659],{"class":749,"line":1054},[747,89656,14801],{"class":1630},[747,89658,85794],{"class":802},[747,89660,34014],{"class":802},[747,89662,89663,89665],{"class":749,"line":1060},[747,89664,85827],{"class":1630},[747,89666,86102],{"class":802},[747,89668,89669,89671,89673],{"class":749,"line":1066},[747,89670,14801],{"class":1630},[747,89672,85794],{"class":802},[747,89674,86111],{"class":802},[747,89676,89677,89679],{"class":749,"line":1081},[747,89678,85827],{"class":1630},[747,89680,6540],{"class":802},[747,89682,89683,89685,89687],{"class":749,"line":1087},[747,89684,14801],{"class":1630},[747,89686,85794],{"class":802},[747,89688,86126],{"class":802},[747,89690,89691,89693],{"class":749,"line":1102},[747,89692,85827],{"class":1630},[747,89694,6540],{"class":802},[747,89696,89697,89699,89701],{"class":749,"line":1110},[747,89698,14801],{"class":1630},[747,89700,85794],{"class":802},[747,89702,34033],{"class":802},[747,89704,89705,89707],{"class":749,"line":1117},[747,89706,85827],{"class":1630},[747,89708,6540],{"class":802},[747,89710,89711,89713,89715],{"class":749,"line":1123},[747,89712,14801],{"class":1630},[747,89714,85794],{"class":802},[747,89716,86155],{"class":802},[747,89718,89719,89721],{"class":749,"line":1129},[747,89720,85827],{"class":1630},[747,89722,11053],{"class":802},[747,89724,89725,89727,89729],{"class":749,"line":1142},[747,89726,14801],{"class":1630},[747,89728,85794],{"class":802},[747,89730,86170],{"class":802},[747,89732,89733,89735],{"class":749,"line":1150},[747,89734,85827],{"class":1630},[747,89736,11063],{"class":802},[747,89738,89739,89741,89743],{"class":749,"line":1157},[747,89740,14801],{"class":1630},[747,89742,85794],{"class":802},[747,89744,86185],{"class":802},[747,89746,89747,89749],{"class":749,"line":1163},[747,89748,85827],{"class":1630},[747,89750,11073],{"class":802},[747,89752,89753,89755,89757],{"class":749,"line":1168},[747,89754,14801],{"class":1630},[747,89756,85794],{"class":802},[747,89758,86200],{"class":802},[747,89760,89761,89763],{"class":749,"line":1174},[747,89762,85827],{"class":1630},[747,89764,11083],{"class":802},[747,89766,89767],{"class":749,"line":1480},[747,89768,86211],{"class":772},[747,89770,89771],{"class":749,"line":1491},[747,89772,85869],{"class":1630},[747,89774,89775],{"class":749,"line":1496},[747,89776,86220],{"class":772},[747,89778,89779],{"class":749,"line":1502},[747,89780,86225],{"class":772},[747,89782,89783,89785,89787],{"class":749,"line":1510},[747,89784,14801],{"class":1630},[747,89786,85876],{"class":802},[747,89788,29869],{"class":1895},[747,89790,89791],{"class":749,"line":1520},[747,89792,86238],{"class":772},[747,89794,89795,89797],{"class":749,"line":1525},[747,89796,85883],{"class":1630},[747,89798,6540],{"class":802},[33091,89800,25729],{"id":3243},[738,89802,89804],{"className":1621,"code":89803,"language":1623,"meta":743,"style":743},"apiVersion: v1\n# Service object\nkind: Service\nmetadata:\n  # labels for the service\n  labels:\n    name: wordpress\n  # name of the service\n  name: wordpress\nspec:\n  ports:\n    # the port that this service should serve on\n    - port: 80\n  # label keys and values that must match in order to receive traffic for this service\n  selector:\n    # select pods with the name \"wordpress\"\n    name: wordpress\n",[567,89805,89806,89812,89816,89822,89826,89830,89834,89840,89844,89850,89854,89858,89862,89870,89874,89878,89882],{"__ignoreMap":743},[747,89807,89808,89810],{"class":749,"line":750},[747,89809,23195],{"class":1630},[747,89811,22608],{"class":802},[747,89813,89814],{"class":749,"line":761},[747,89815,85628],{"class":772},[747,89817,89818,89820],{"class":749,"line":769},[747,89819,23230],{"class":1630},[747,89821,25758],{"class":802},[747,89823,89824],{"class":749,"line":776},[747,89825,23238],{"class":1630},[747,89827,89828],{"class":749,"line":784},[747,89829,85914],{"class":772},[747,89831,89832],{"class":749,"line":790},[747,89833,85643],{"class":1630},[747,89835,89836,89838],{"class":749,"line":796},[747,89837,37583],{"class":1630},[747,89839,6540],{"class":802},[747,89841,89842],{"class":749,"line":806},[747,89843,85929],{"class":772},[747,89845,89846,89848],{"class":749,"line":814},[747,89847,23251],{"class":1630},[747,89849,6540],{"class":802},[747,89851,89852],{"class":749,"line":822},[747,89853,37531],{"class":1630},[747,89855,89856],{"class":749,"line":830},[747,89857,83659],{"class":1630},[747,89859,89860],{"class":749,"line":836},[747,89861,85668],{"class":772},[747,89863,89864,89866,89868],{"class":749,"line":842},[747,89865,18665],{"class":1630},[747,89867,85675],{"class":802},[747,89869,29869],{"class":1895},[747,89871,89872],{"class":749,"line":850},[747,89873,85682],{"class":772},[747,89875,89876],{"class":749,"line":863},[747,89877,85687],{"class":1630},[747,89879,89880],{"class":749,"line":869},[747,89881,85968],{"class":772},[747,89883,89884,89886],{"class":749,"line":877},[747,89885,37583],{"class":1630},[747,89887,6540],{"class":802},[3142,89889,89891],{"id":89890},"mysql-database-server","Mysql Database Server",[33091,89893,25722],{"id":89894},"pod-1",[738,89896,89898],{"className":1621,"code":89897,"language":1623,"meta":743,"style":743},"# Kubernetes API version\napiVersion: v1\n# Type of \"request\" in this case a Pod\nkind: Pod\n# Metadata of the \"object\"\nmetadata:\n  # Name of the \"object\"\n  name: mysql\n  # Labels of the \"object\"\n  labels:\n    # A lable named \"name\" with value \"mysql\"\n    name: mysql\n# spec ~= Specificationsof the \"object\"\nspec:\n  # List of Container definitions\n  containers:\n    # The \"name\"\u002F\"suffix\" of the container name\n    - name: mysql\n      # What Docker image to use\n      image: sameersbn\u002Fmysql:latest\n      env:\n        - name: DB_NAME\n          value: wordpress\n        - name: DB_USER\n          value: wordpress\n        - name: DB_PASS\n          value: wordpress\n      # List of container ports reachable from within the cluster\n      ports:\n        - containerPort: 3306\n          name: mysql\n",[567,89899,89900,89904,89910,89914,89920,89924,89928,89932,89938,89942,89946,89950,89956,89960,89964,89968,89972,89976,89984,89988,89994,89998,90006,90012,90020,90026,90034,90040,90044,90048,90056],{"__ignoreMap":743},[747,89901,89902],{"class":749,"line":750},[747,89903,85707],{"class":772},[747,89905,89906,89908],{"class":749,"line":761},[747,89907,23195],{"class":1630},[747,89909,22608],{"class":802},[747,89911,89912],{"class":749,"line":769},[747,89913,85718],{"class":772},[747,89915,89916,89918],{"class":749,"line":776},[747,89917,23230],{"class":1630},[747,89919,28795],{"class":802},[747,89921,89922],{"class":749,"line":784},[747,89923,85729],{"class":772},[747,89925,89926],{"class":749,"line":790},[747,89927,23238],{"class":1630},[747,89929,89930],{"class":749,"line":796},[747,89931,85738],{"class":772},[747,89933,89934,89936],{"class":749,"line":806},[747,89935,23251],{"class":1630},[747,89937,11146],{"class":802},[747,89939,89940],{"class":749,"line":814},[747,89941,85749],{"class":772},[747,89943,89944],{"class":749,"line":822},[747,89945,85643],{"class":1630},[747,89947,89948],{"class":749,"line":830},[747,89949,85758],{"class":772},[747,89951,89952,89954],{"class":749,"line":836},[747,89953,37583],{"class":1630},[747,89955,11146],{"class":802},[747,89957,89958],{"class":749,"line":842},[747,89959,85769],{"class":772},[747,89961,89962],{"class":749,"line":850},[747,89963,37531],{"class":1630},[747,89965,89966],{"class":749,"line":863},[747,89967,85778],{"class":772},[747,89969,89970],{"class":749,"line":869},[747,89971,37536],{"class":1630},[747,89973,89974],{"class":749,"line":877},[747,89975,85787],{"class":772},[747,89977,89978,89980,89982],{"class":749,"line":1015},[747,89979,18665],{"class":1630},[747,89981,85794],{"class":802},[747,89983,11146],{"class":802},[747,89985,89986],{"class":749,"line":1021},[747,89987,85801],{"class":772},[747,89989,89990,89992],{"class":749,"line":1027},[747,89991,85806],{"class":1630},[747,89993,83571],{"class":802},[747,89995,89996],{"class":749,"line":1033},[747,89997,85813],{"class":1630},[747,89999,90000,90002,90004],{"class":749,"line":1039},[747,90001,14801],{"class":1630},[747,90003,85794],{"class":802},[747,90005,85822],{"class":802},[747,90007,90008,90010],{"class":749,"line":1054},[747,90009,85827],{"class":1630},[747,90011,6540],{"class":802},[747,90013,90014,90016,90018],{"class":749,"line":1060},[747,90015,14801],{"class":1630},[747,90017,85794],{"class":802},[747,90019,85838],{"class":802},[747,90021,90022,90024],{"class":749,"line":1066},[747,90023,85827],{"class":1630},[747,90025,6540],{"class":802},[747,90027,90028,90030,90032],{"class":749,"line":1081},[747,90029,14801],{"class":1630},[747,90031,85794],{"class":802},[747,90033,85853],{"class":802},[747,90035,90036,90038],{"class":749,"line":1087},[747,90037,85827],{"class":1630},[747,90039,6540],{"class":802},[747,90041,90042],{"class":749,"line":1102},[747,90043,85864],{"class":772},[747,90045,90046],{"class":749,"line":1110},[747,90047,85869],{"class":1630},[747,90049,90050,90052,90054],{"class":749,"line":1117},[747,90051,14801],{"class":1630},[747,90053,85876],{"class":802},[747,90055,30576],{"class":1895},[747,90057,90058,90060],{"class":749,"line":1123},[747,90059,85883],{"class":1630},[747,90061,11146],{"class":802},[33091,90063,25729],{"id":90064},"service-1",[738,90066,90068],{"className":1621,"code":90067,"language":1623,"meta":743,"style":743},"apiVersion: v1\n# Service object\nkind: Service\nmetadata:\n  labels:\n    name: mysql\n  name: mysql\nspec:\n  ports:\n    # the port that this service should serve on\n    - port: 3306\n  # label keys and values that must match in order to receive traffic for this service\n  selector:\n    # select pods with the name \"mysql\"\n    name: mysql\n",[567,90069,90070,90076,90080,90086,90090,90094,90100,90106,90110,90114,90118,90126,90130,90134,90138],{"__ignoreMap":743},[747,90071,90072,90074],{"class":749,"line":750},[747,90073,23195],{"class":1630},[747,90075,22608],{"class":802},[747,90077,90078],{"class":749,"line":761},[747,90079,85628],{"class":772},[747,90081,90082,90084],{"class":749,"line":769},[747,90083,23230],{"class":1630},[747,90085,25758],{"class":802},[747,90087,90088],{"class":749,"line":776},[747,90089,23238],{"class":1630},[747,90091,90092],{"class":749,"line":784},[747,90093,85643],{"class":1630},[747,90095,90096,90098],{"class":749,"line":790},[747,90097,37583],{"class":1630},[747,90099,11146],{"class":802},[747,90101,90102,90104],{"class":749,"line":796},[747,90103,23251],{"class":1630},[747,90105,11146],{"class":802},[747,90107,90108],{"class":749,"line":806},[747,90109,37531],{"class":1630},[747,90111,90112],{"class":749,"line":814},[747,90113,83659],{"class":1630},[747,90115,90116],{"class":749,"line":822},[747,90117,85668],{"class":772},[747,90119,90120,90122,90124],{"class":749,"line":830},[747,90121,18665],{"class":1630},[747,90123,85675],{"class":802},[747,90125,30576],{"class":1895},[747,90127,90128],{"class":749,"line":836},[747,90129,85682],{"class":772},[747,90131,90132],{"class":749,"line":842},[747,90133,85687],{"class":1630},[747,90135,90136],{"class":749,"line":850},[747,90137,85692],{"class":772},[747,90139,90140,90142],{"class":749,"line":863},[747,90141,37583],{"class":1630},[747,90143,11146],{"class":802},[3142,90145,90146],{"id":86661},"phpMyAdmin",[33091,90148,25722],{"id":90149},"pod-2",[738,90151,90153],{"className":1621,"code":90152,"language":1623,"meta":743,"style":743},"# Kubernetes API version\napiVersion: v1\n# Type of \"request\"\nkind: Pod\n# Metadata of the \"object\"\nmetadata:\n  # Name of the \"object\"\n  name: phpmyadmin\n  # Labels of the \"object\"\n  labels:\n    # A lable named \"name\" with value \"phpmyadmin\"\n    name: phpmyadmin\n# spec ~= Specificationsof the \"object\"\nspec:\n  # List of Container definitions\n  containers:\n    # The \"name\"\u002F\"suffix\" of the container name\n    - name: phpmyadmin\n      # What Docker image to use\n      image: phpmyadmin\u002Fphpmyadmin\n      env:\n        - name: PMA_HOST\n          value: mysql.default\n      # List of container ports reachable from within the cluster\n      ports:\n        - containerPort: 80\n          name: phpmyadmin\n",[567,90154,90155,90159,90165,90169,90175,90179,90183,90187,90194,90198,90202,90207,90213,90217,90221,90225,90229,90233,90241,90245,90251,90255,90264,90271,90275,90279,90287],{"__ignoreMap":743},[747,90156,90157],{"class":749,"line":750},[747,90158,85707],{"class":772},[747,90160,90161,90163],{"class":749,"line":761},[747,90162,23195],{"class":1630},[747,90164,22608],{"class":802},[747,90166,90167],{"class":749,"line":769},[747,90168,85993],{"class":772},[747,90170,90171,90173],{"class":749,"line":776},[747,90172,23230],{"class":1630},[747,90174,28795],{"class":802},[747,90176,90177],{"class":749,"line":784},[747,90178,85729],{"class":772},[747,90180,90181],{"class":749,"line":790},[747,90182,23238],{"class":1630},[747,90184,90185],{"class":749,"line":796},[747,90186,85738],{"class":772},[747,90188,90189,90191],{"class":749,"line":806},[747,90190,23251],{"class":1630},[747,90192,90193],{"class":802}," phpmyadmin\n",[747,90195,90196],{"class":749,"line":814},[747,90197,85749],{"class":772},[747,90199,90200],{"class":749,"line":822},[747,90201,85643],{"class":1630},[747,90203,90204],{"class":749,"line":830},[747,90205,90206],{"class":772},"    # A lable named \"name\" with value \"phpmyadmin\"\n",[747,90208,90209,90211],{"class":749,"line":836},[747,90210,37583],{"class":1630},[747,90212,90193],{"class":802},[747,90214,90215],{"class":749,"line":842},[747,90216,85769],{"class":772},[747,90218,90219],{"class":749,"line":850},[747,90220,37531],{"class":1630},[747,90222,90223],{"class":749,"line":863},[747,90224,85778],{"class":772},[747,90226,90227],{"class":749,"line":869},[747,90228,37536],{"class":1630},[747,90230,90231],{"class":749,"line":877},[747,90232,85787],{"class":772},[747,90234,90235,90237,90239],{"class":749,"line":1015},[747,90236,18665],{"class":1630},[747,90238,85794],{"class":802},[747,90240,90193],{"class":802},[747,90242,90243],{"class":749,"line":1021},[747,90244,85801],{"class":772},[747,90246,90247,90249],{"class":749,"line":1027},[747,90248,85806],{"class":1630},[747,90250,11117],{"class":802},[747,90252,90253],{"class":749,"line":1033},[747,90254,85813],{"class":1630},[747,90256,90257,90259,90261],{"class":749,"line":1039},[747,90258,14801],{"class":1630},[747,90260,85794],{"class":802},[747,90262,90263],{"class":802}," PMA_HOST\n",[747,90265,90266,90268],{"class":749,"line":1054},[747,90267,85827],{"class":1630},[747,90269,90270],{"class":802}," mysql.default\n",[747,90272,90273],{"class":749,"line":1060},[747,90274,85864],{"class":772},[747,90276,90277],{"class":749,"line":1066},[747,90278,85869],{"class":1630},[747,90280,90281,90283,90285],{"class":749,"line":1081},[747,90282,14801],{"class":1630},[747,90284,85876],{"class":802},[747,90286,29869],{"class":1895},[747,90288,90289,90291],{"class":749,"line":1087},[747,90290,85883],{"class":1630},[747,90292,90193],{"class":802},[33091,90294,25729],{"id":90295},"service-2",[738,90297,90299],{"className":1621,"code":90298,"language":1623,"meta":743,"style":743},"apiVersion: v1\nkind: Service\nmetadata:\n  # labels for the service\n  labels:\n    name: phpmyadmin\n  # name of the service\n  name: phpmyadmin\nspec:\n  ports:\n    # the port that this service should serve on\n    - port: 81\n      # set the target of the port, in this case 81 -> 80\n      targetPort: 80\n  # label keys and values that must match in order to receive traffic for this service\n  selector:\n    # select pods with the name \"phpmyadmin\"\n    name: phpmyadmin\n",[567,90300,90301,90307,90313,90317,90321,90325,90331,90335,90341,90345,90349,90353,90362,90367,90374,90378,90382,90387],{"__ignoreMap":743},[747,90302,90303,90305],{"class":749,"line":750},[747,90304,23195],{"class":1630},[747,90306,22608],{"class":802},[747,90308,90309,90311],{"class":749,"line":761},[747,90310,23230],{"class":1630},[747,90312,25758],{"class":802},[747,90314,90315],{"class":749,"line":769},[747,90316,23238],{"class":1630},[747,90318,90319],{"class":749,"line":776},[747,90320,85914],{"class":772},[747,90322,90323],{"class":749,"line":784},[747,90324,85643],{"class":1630},[747,90326,90327,90329],{"class":749,"line":790},[747,90328,37583],{"class":1630},[747,90330,90193],{"class":802},[747,90332,90333],{"class":749,"line":796},[747,90334,85929],{"class":772},[747,90336,90337,90339],{"class":749,"line":806},[747,90338,23251],{"class":1630},[747,90340,90193],{"class":802},[747,90342,90343],{"class":749,"line":814},[747,90344,37531],{"class":1630},[747,90346,90347],{"class":749,"line":822},[747,90348,83659],{"class":1630},[747,90350,90351],{"class":749,"line":830},[747,90352,85668],{"class":772},[747,90354,90355,90357,90359],{"class":749,"line":836},[747,90356,18665],{"class":1630},[747,90358,85675],{"class":802},[747,90360,90361],{"class":1895}," 81\n",[747,90363,90364],{"class":749,"line":842},[747,90365,90366],{"class":772},"      # set the target of the port, in this case 81 -> 80\n",[747,90368,90369,90372],{"class":749,"line":850},[747,90370,90371],{"class":1630},"      targetPort:",[747,90373,29869],{"class":1895},[747,90375,90376],{"class":749,"line":863},[747,90377,85682],{"class":772},[747,90379,90380],{"class":749,"line":869},[747,90381,85687],{"class":1630},[747,90383,90384],{"class":749,"line":877},[747,90385,90386],{"class":772},"    # select pods with the name \"phpmyadmin\"\n",[747,90388,90389,90391],{"class":749,"line":1015},[747,90390,37583],{"class":1630},[747,90392,90193],{"class":802},[3126,90394,90396],{"id":90395},"kubectl-our-tool-to-rule-them-all","kubectl - Our tool to rule them all!",[62787,90398,90399],{},"\n![Kubernetes Zelda - It's dangerous to go alone](\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop\u002Fkubernetes-its-dangerous-to-go-alone.png)\n_Zelda Meme intensifies_\n",[523,90401,8764,90402,90404],{},[567,90403,15269],{}," command is used to create new \"objects\", view Pods, view Replication Controller and much more.",[523,90406,90407],{},"An example to view Pods in all namespaces:",[738,90409,90410],{"className":1621,"code":84258,"language":1623,"meta":743,"style":743},[567,90411,90412],{"__ignoreMap":743},[747,90413,90414,90416,90418,90420],{"class":749,"line":750},[747,90415,15269],{"class":1630},[747,90417,1951],{"class":802},[747,90419,84269],{"class":802},[747,90421,1958],{"class":802},[6072,90423,90424,90428],{},[523,90425,90426],{},[584,90427,2957],{},[668,90429,90430,90434,90438,90442],{},[638,90431,90432,38548],{},[567,90433,15269],{},[638,90435,90436,38554],{},[567,90437,38553],{},[638,90439,90440,38565],{},[567,90441,38564],{},[638,90443,90444,84296],{},[567,90445,38570],{},[523,90447,90448],{},"Get all information about a Pod:",[738,90450,90452],{"className":1621,"code":90451,"language":1623,"meta":743,"style":743},"kubectl describe --namespace=NAMESPACE TYPE NAME\n",[567,90453,90454],{"__ignoreMap":743},[747,90455,90456,90458,90460,90462,90464],{"class":749,"line":750},[747,90457,15269],{"class":1630},[747,90459,38613],{"class":802},[747,90461,38616],{"class":802},[747,90463,39094],{"class":802},[747,90465,5905],{"class":802},[6072,90467,90468,90472],{},[523,90469,90470],{},[584,90471,2957],{},[668,90473,90474,90478,90482,90490],{},[638,90475,90476,38640],{},[567,90477,38639],{},[638,90479,90480,38646],{},[567,90481,38645],{},[638,90483,90484,38652,90486,714,90488,84346],{},[567,90485,38651],{},[567,90487,38655],{},[567,90489,84153],{},[638,90491,90492,38663,90494,1909],{},[567,90493,2230],{},[567,90495,6725],{},[523,90497,90498],{},"To create our WordPress, MySQL, phpMyAdmin Pod and Services, we run:",[738,90500,90501],{"className":1621,"code":66581,"language":1623,"meta":743,"style":743},[567,90502,90503],{"__ignoreMap":743},[747,90504,90505,90507,90509,90511],{"class":749,"line":750},[747,90506,15269],{"class":1630},[747,90508,1925],{"class":802},[747,90510,1934],{"class":802},[747,90512,38705],{"class":802},[6072,90514,90515,90519],{},[523,90516,90517],{},[584,90518,2957],{},[668,90520,90521,90525],{},[638,90522,90523,84388],{},[567,90524,38675],{},[638,90526,90527,90529],{},[567,90528,38723],{}," - Can be one file, a directory or stdin.",[523,90531,90532,90533,90535,90536,90538,90539,90542],{},"In our case ",[567,90534,66599],{}," would be the path to the ",[567,90537,30363],{}," task, ",[567,90540,90541],{},"kubernetes202\u002F",".\nThe files are read and the objects are created in alphabetical order (FIFO).",[3126,90544,14526],{"id":90545},"summary-5",[523,90547,90548],{},"We have now knowledge about creating kubectl files.\nOur wordpress instance with the database is now running on the Kubernetes cluster, but currently not in HA mode (high Availability)",[2979,90550],{},[613,90552,90554],{"id":90553},"high-availability-and-balancing-with-loads-kubernetes","High Availability and \"Balancing with Loads\" - Kubernetes",[3126,90556,90558],{"id":90557},"kubernetes-balances-loads-by-default","Kubernetes balances loads by default",[523,90560,90561,90562],{},"Kubernetes uses iptables to \"balance\" the traffic between services that are running across the cluster.\n",[3049,90563,90564],{},"Not perfect, but a good software side approach using iptables.",[3126,90566,90568],{"id":90567},"kubernetes-ingress-aka-reverse-proxing-between-multiple-webservers","Kubernetes Ingress aka \"Reverse Proxing between multiple webservers\"",[6072,90570,90571],{},[523,90572,90573,90575,90576,90580,90581,1909],{},[584,90574,76064],{}," Kubernetes Ingress doesn't support L7 ssl termination yet! See ",[527,90577,3396],{"href":90578,"rel":90579},"http:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fuser-guide\u002Fingress\u002F#the-ingress-resource",[531],", list point ",[3049,90582,90583],{},"Global Parameters",[3126,90585,87864],{"id":90586},"pointers-tuts-and-docs-5",[668,90588,90589,90602],{},[638,90590,90591,90592],{},"\"Native\" Docker\n",[668,90593,90594],{},[638,90595,90596,90601],{},[527,90597,90600],{"href":90598,"rel":90599},"https:\u002F\u002Fgithub.com\u002Fjwilder\u002Fnginx-proxy",[531],"jwilder\u002Fnginx-proxy"," - Automatic Docker Nginx Proxy",[638,90603,90604,90605],{},"Multi Host\n",[668,90606,90607,90614,90621],{},[638,90608,90609],{},[527,90610,90613],{"href":90611,"rel":90612},"https:\u002F\u002Fvulcand.github.io\u002F",[531],"Vulcand",[638,90615,90616],{},[527,90617,90620],{"href":90618,"rel":90619},"http:\u002F\u002Fweaveworks.github.io\u002Fflux\u002F",[531],"Weave Flux",[638,90622,90623],{},[527,90624,90627],{"href":90625,"rel":90626},"http:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fuser-guide\u002Fingress\u002F",[531],"Kubernetes Ingress Support",[2979,90629],{},[613,90631,11751],{"id":11750},[523,90633,90634,90635,90638],{},"If you have any questions about the ",[584,90636,90637],{},"workshop content",", feel free to ask them in the comments or ask me directly at the workshop.",[2979,90640],{},[613,90642,90644],{"id":90643},"solutions","Solutions",[3126,90646,90648,90649],{"id":90647},"for-the-nginx-dockerfile","For the ",[567,90650,11764],{},[738,90652,90653],{"className":9011,"code":86430,"language":9013,"meta":743,"style":743},[567,90654,90655,90661,90665,90671,90675],{"__ignoreMap":743},[747,90656,90657,90659],{"class":749,"line":750},[747,90658,9020],{"class":1895},[747,90660,82542],{"class":1640},[747,90662,90663],{"class":749,"line":761},[747,90664,1255],{"emptyLinePlaceholder":1254},[747,90666,90667,90669],{"class":749,"line":769},[747,90668,9065],{"class":1895},[747,90670,11786],{"class":1640},[747,90672,90673],{"class":749,"line":776},[747,90674,1255],{"emptyLinePlaceholder":1254},[747,90676,90677,90679,90681,90683],{"class":749,"line":784},[747,90678,9210],{"class":1895},[747,90680,4262],{"class":1640},[747,90682,11799],{"class":802},[747,90684,4268],{"class":1640},[3126,90686,90688,90689],{"id":90687},"for-wordpress-docker-composeyml","For WordPress ",[567,90690,10821],{},[738,90692,90694],{"className":740,"code":90693,"language":742,"meta":743,"style":743},"# Taken from https:\u002F\u002Fwww.digitalocean.com\u002Fcommunity\u002Ftutorials\u002Fhow-to-install-wordpress-and-phpmyadmin-with-docker-compose-on-ubuntu-14-04\ndatabase:\n  image: sameersbn\u002Fmysql:latest\n  environment:\n    DB_NAME: wordpress\n    DB_USER: wordpress\n    DB_PASS: wordpress\n  volumes:\n    - \"\u002Fopt\u002Fdocker\u002Fdatabase:\u002Fvar\u002Flib\u002Fmysql:rw\"\nwordpress:\n  image: wordpress\n  links:\n    - database:mysql\n  ports:\n    - 8080:80\n  environment:\n    WORDPRESS_DB_HOST: mysql:3306\n    WORDPRESS_DB_NAME: wordpress\n    WORDPRESS_DB_USER: wordpress\n    WORDPRESS_DB_PASSWORD: wordpress\n    WORDPRESS_AUTH_KEY: SECURE_AUTH_KEY\n    WORDPRESS_LOGGED_IN_KEY: SECURE_LOGGED_IN_KEY\n    WORDPRESS_AUTH_SALT: SECURE_AUTH_SALT\n    WORDPRESS_LOGGED_IN_SALT: SECURE_LOGGED_IN_SALT\nphpmyadmin:\n  image: corbinu\u002Fdocker-phpmyadmin\n  links:\n    - database:mysql\n  ports:\n    - 8181:80\n  environment:\n    MYSQL_USERNAME: root\n    MYSQL_ROOT_PASSWORD: wordpress\n",[567,90695,90696,90700,90706,90714,90720,90728,90736,90744,90750,90760,90766,90774,90780,90787,90793,90799,90805,90813,90821,90829,90837,90845,90853,90861,90869,90875,90883,90889,90895,90901,90907,90913,90922],{"__ignoreMap":743},[747,90697,90698],{"class":749,"line":750},[747,90699,86476],{"class":772},[747,90701,90702,90704],{"class":749,"line":761},[747,90703,6815],{"class":753},[747,90705,758],{"class":757},[747,90707,90708,90710,90712],{"class":749,"line":769},[747,90709,24395],{"class":753},[747,90711,856],{"class":757},[747,90713,83571],{"class":802},[747,90715,90716,90718],{"class":749,"line":776},[747,90717,24602],{"class":753},[747,90719,758],{"class":757},[747,90721,90722,90724,90726],{"class":749,"line":784},[747,90723,86501],{"class":753},[747,90725,856],{"class":757},[747,90727,6540],{"class":802},[747,90729,90730,90732,90734],{"class":749,"line":790},[747,90731,86510],{"class":753},[747,90733,856],{"class":757},[747,90735,6540],{"class":802},[747,90737,90738,90740,90742],{"class":749,"line":796},[747,90739,86519],{"class":753},[747,90741,856],{"class":757},[747,90743,6540],{"class":802},[747,90745,90746,90748],{"class":749,"line":806},[747,90747,29209],{"class":753},[747,90749,758],{"class":757},[747,90751,90752,90754,90756,90758],{"class":749,"line":814},[747,90753,18665],{"class":757},[747,90755,969],{"class":757},[747,90757,49135],{"class":802},[747,90759,975],{"class":757},[747,90761,90762,90764],{"class":749,"line":822},[747,90763,6725],{"class":753},[747,90765,758],{"class":757},[747,90767,90768,90770,90772],{"class":749,"line":830},[747,90769,24395],{"class":753},[747,90771,856],{"class":757},[747,90773,6540],{"class":802},[747,90775,90776,90778],{"class":749,"line":836},[747,90777,86558],{"class":753},[747,90779,758],{"class":757},[747,90781,90782,90784],{"class":749,"line":842},[747,90783,18665],{"class":757},[747,90785,90786],{"class":802}," database:mysql\n",[747,90788,90789,90791],{"class":749,"line":850},[747,90790,25878],{"class":753},[747,90792,758],{"class":757},[747,90794,90795,90797],{"class":749,"line":863},[747,90796,18665],{"class":757},[747,90798,11000],{"class":802},[747,90800,90801,90803],{"class":749,"line":869},[747,90802,24602],{"class":753},[747,90804,758],{"class":757},[747,90806,90807,90809,90811],{"class":749,"line":877},[747,90808,86589],{"class":753},[747,90810,856],{"class":757},[747,90812,11939],{"class":802},[747,90814,90815,90817,90819],{"class":749,"line":1015},[747,90816,86598],{"class":753},[747,90818,856],{"class":757},[747,90820,6540],{"class":802},[747,90822,90823,90825,90827],{"class":749,"line":1021},[747,90824,86607],{"class":753},[747,90826,856],{"class":757},[747,90828,6540],{"class":802},[747,90830,90831,90833,90835],{"class":749,"line":1027},[747,90832,86616],{"class":753},[747,90834,856],{"class":757},[747,90836,6540],{"class":802},[747,90838,90839,90841,90843],{"class":749,"line":1033},[747,90840,86625],{"class":753},[747,90842,856],{"class":757},[747,90844,11053],{"class":802},[747,90846,90847,90849,90851],{"class":749,"line":1039},[747,90848,86634],{"class":753},[747,90850,856],{"class":757},[747,90852,11063],{"class":802},[747,90854,90855,90857,90859],{"class":749,"line":1054},[747,90856,86643],{"class":753},[747,90858,856],{"class":757},[747,90860,11073],{"class":802},[747,90862,90863,90865,90867],{"class":749,"line":1060},[747,90864,86652],{"class":753},[747,90866,856],{"class":757},[747,90868,11083],{"class":802},[747,90870,90871,90873],{"class":749,"line":1066},[747,90872,86661],{"class":753},[747,90874,758],{"class":757},[747,90876,90877,90879,90881],{"class":749,"line":1081},[747,90878,24395],{"class":753},[747,90880,856],{"class":757},[747,90882,88919],{"class":802},[747,90884,90885,90887],{"class":749,"line":1087},[747,90886,86558],{"class":753},[747,90888,758],{"class":757},[747,90890,90891,90893],{"class":749,"line":1102},[747,90892,18665],{"class":757},[747,90894,90786],{"class":802},[747,90896,90897,90899],{"class":749,"line":1110},[747,90898,25878],{"class":753},[747,90900,758],{"class":757},[747,90902,90903,90905],{"class":749,"line":1117},[747,90904,18665],{"class":757},[747,90906,11130],{"class":802},[747,90908,90909,90911],{"class":749,"line":1123},[747,90910,24602],{"class":753},[747,90912,758],{"class":757},[747,90914,90915,90918,90920],{"class":749,"line":1129},[747,90916,90917],{"class":753},"    MYSQL_USERNAME",[747,90919,856],{"class":757},[747,90921,11156],{"class":802},[747,90923,90924,90927,90929],{"class":749,"line":1142},[747,90925,90926],{"class":753},"    MYSQL_ROOT_PASSWORD",[747,90928,856],{"class":757},[747,90930,6540],{"class":802},[2890,90932,90933],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":743,"searchDepth":761,"depth":761,"links":90935},[90936,90937,90938,90939,90940,90941,90942,90943,90944,90945,90946,90947,90948,90949,90950,90951,90952,90953,90954],{"id":86945,"depth":769,"text":86946},{"id":2929,"depth":769,"text":2930},{"id":39305,"depth":769,"text":39306},{"id":86986,"depth":769,"text":86987},{"id":80032,"depth":769,"text":80033},{"id":87040,"depth":769,"text":87041},{"id":3008,"depth":769,"text":3009},{"id":3109,"depth":769,"text":3110},{"id":87279,"depth":769,"text":87280},{"id":87648,"depth":769,"text":87649},{"id":87897,"depth":769,"text":87898},{"id":88110,"depth":769,"text":88111},{"id":88719,"depth":769,"text":88720},{"id":89132,"depth":769,"text":89133},{"id":89171,"depth":769,"text":89172},{"id":89508,"depth":769,"text":89509},{"id":90553,"depth":769,"text":90554},{"id":11750,"depth":769,"text":11751},{"id":90643,"depth":769,"text":90644},"2016-03-08T14:39:00+02:00","This post is deprecated! Please move on to the new version of this post.",{"src":12171},{"tags":90959},[12174,12175,12176],"\u002Fblog\u002F2016\u002Fdocker-for-admins-workshop",{"title":86937,"description":90956},"3.blog\u002F2016\u002Fdocker-for-admins-workshop","1zk8Lht3MEN0L0FLj6eM2j4knaUM5D8w_9b4jZovzlI",{"id":90965,"title":90966,"authors":90967,"badge":518,"body":90970,"date":91005,"description":91006,"extension":2911,"image":518,"meta":91007,"navigation":1254,"path":91009,"seo":91010,"stem":91011,"__hash__":91012},"posts\u002F3.blog\u002F2016\u002Fonline-courses-courses-everywhere.md","Online Courses! Online Courses Everywhere!",[90968],{"name":514,"to":515,"avatar":90969},{"src":517},{"type":520,"value":90971,"toc":91003},[90972,90982,90987],[523,90973,90974],{},[3049,90975,90976,90977,1909],{},"Image made using the ",[527,90978,90981],{"href":90979,"rel":90980},"http:\u002F\u002Fimgur.com\u002Fmemegen",[531],"Imgur Meme Generator",[6072,90983,90984],{},[523,90985,90986],{},"In the future I'm going to add more online course sites.",[668,90988,90989,90996],{},[638,90990,90991],{},[527,90992,90995],{"href":90993,"rel":90994},"https:\u002F\u002Fwww.edx.org\u002F",[531],"edX - Free online courses from the world's best universities",[638,90997,90998],{},[527,90999,91002],{"href":91000,"rel":91001},"https:\u002F\u002Fwww.futurelearn.com\u002Fcourses",[531],"FutureLearn Courses",{"title":743,"searchDepth":761,"depth":761,"links":91004},[],"2016-03-02T21:50:00+02:00","A list of some online course sites.",{"tags":91008},[76569],"\u002Fblog\u002F2016\u002Fonline-courses-courses-everywhere",{"title":90966,"description":91006},"3.blog\u002F2016\u002Fonline-courses-courses-everywhere","Mbp-U0BdWoMo_b8Pvxn799yRJTeXykWn3xty1CdcpYc",{"id":91014,"title":91015,"authors":91016,"badge":518,"body":91019,"date":91040,"description":91041,"extension":2911,"image":91042,"meta":91043,"navigation":1254,"path":91045,"seo":91046,"stem":91047,"__hash__":91048},"posts\u002F3.blog\u002F2016\u002Fkubernetes-v1-presentation.md","Kubernetes v1 Presentation",[91017],{"name":514,"to":515,"avatar":91018},{"src":517},{"type":520,"value":91020,"toc":91038},[91021,91024,91032,91034,91036],[523,91022,91023],{},"I created this Kubernetes presentation last year in september and I think it's worth sharing it here on my blog.",[6072,91025,91026,91030],{},[523,91027,91028],{},[584,91029,6189],{},[523,91031,75716],{},[523,91033,58352],{},[18903,91035],{"src":89165,"frameBorder":3579,"height":18906,"allowFullScreen":5306,"mozallowfullscreen":5306,"webkitallowfullscreen":5306},[523,91037,52336],{},{"title":743,"searchDepth":761,"depth":761,"links":91039},[],"2016-02-27T15:15:00+02:00","A presentation of some of the current Kubernetes features.",{"src":58363},{"tags":91044},[18918,124],"\u002Fblog\u002F2016\u002Fkubernetes-v1-presentation",{"title":91015,"description":91041},"3.blog\u002F2016\u002Fkubernetes-v1-presentation","RcTth4hbnenx_uO0a3Y__XZp545q3_FOfoIvbyi26Tk",{"id":91050,"title":91051,"authors":91052,"badge":518,"body":91055,"date":91065,"description":91066,"extension":2911,"image":518,"meta":91067,"navigation":1254,"path":91069,"seo":91070,"stem":91071,"__hash__":91072},"posts\u002F3.blog\u002F2016\u002Ffirst-post.md","First Post",[91053],{"name":514,"to":515,"avatar":91054},{"src":517},{"type":520,"value":91056,"toc":91063},[91057,91060],[523,91058,91059],{},"I'm posting about linux server administration, Docker, Kubernetes and other suff.",[523,91061,91062],{},"Stay tuned for more! :)",{"title":743,"searchDepth":761,"depth":761,"links":91064},[],"2016-02-26T12:00:00+02:00","This is my first post on my blog Edenmal.",{"tags":91068},[],"\u002Fblog\u002F2016\u002Ffirst-post",{"title":91051,"description":91066},"3.blog\u002F2016\u002Ffirst-post","_5b7SoS5USVqJK1jJBe9KCjXFUa_cspRSXiy2KyDieI",[91074],{"id":510,"title":511,"authors":91075,"badge":518,"body":91078,"date":2909,"description":2910,"extension":2911,"image":2912,"meta":92948,"navigation":1254,"path":2914,"seo":92949,"stem":2916,"__hash__":2917},[91076],{"name":514,"to":515,"avatar":91077},{"src":517},{"type":520,"value":91079,"toc":92932},[91080,91085,91087,91089,91097,91104,91106,91117,91127,91129,91131,91136,91151,91159,91161,91177,91179,91195,91197,91201,91203,91205,91303,91305,91307,91541,91543,91545,91547,91551,91553,91889,91893,91937,91939,91945,91951,92067,92071,92117,92119,92124,92162,92354,92524,92654,92658,92880,92884,92886,92894,92896,92900,92916,92918,92920,92925,92930],[523,91081,525,91082,533],{},[527,91083,532],{"href":529,"rel":91084},[531],[535,91086,538],{"id":537},[523,91088,541],{},[523,91090,544,91091,550,91094,556],{},[527,91092,549],{"href":547,"rel":91093},[531],[527,91095,555],{"href":553,"rel":91096},[531],[523,91098,559,91099,565,91102,569],{},[527,91100,564],{"href":562,"rel":91101},[531],[567,91103,162],{},[535,91105,573],{"id":572},[523,91107,576,91108,582,91111,587,91113,591,91115,595],{},[527,91109,581],{"href":579,"rel":91110},[531],[584,91112,586],{},[584,91114,590],{},[567,91116,594],{},[597,91118,91119],{},[523,91120,601,91121,587,91123,591,91125,608],{},[584,91122,586],{},[584,91124,590],{},[567,91126,594],{},[523,91128,611],{},[613,91130,616],{"id":615},[523,91132,619,91133,625],{},[527,91134,624],{"href":622,"rel":91135},[531],[597,91137,91138,91140,91142],{},[523,91139,630],{},[523,91141,633],{},[635,91143,91144,91146],{},[638,91145,640],{},[638,91147,91148,648],{},[527,91149,647],{"href":645,"rel":91150},[531],[523,91152,651,91153,657,91156,663],{},[527,91154,656],{"href":654,"rel":91155},[531],[527,91157,662],{"href":660,"rel":91158},[531],[523,91160,666],{},[668,91162,91163,91168,91170,91175],{},[638,91164,672,91165,677],{},[527,91166,676],{"href":660,"rel":91167},[531],[638,91169,680],{},[638,91171,683,91172,689],{},[527,91173,688],{"href":686,"rel":91174},[531],[638,91176,692],{},[535,91178,696],{"id":695},[597,91180,91181,91185],{},[523,91182,701,91183,569],{},[567,91184,162],{},[523,91186,706,91187,710,91189,714,91191,718,91193,721],{},[567,91188,709],{},[567,91190,713],{},[567,91192,717],{},[567,91194,162],{},[523,91196,724],{},[597,91198,91199],{},[523,91200,729],{},[613,91202,733],{"id":732},[523,91204,736],{},[738,91206,91207],{"className":740,"code":741,"language":742,"meta":743,"style":743},[567,91208,91209,91215,91221,91225,91231,91235,91239,91245,91251,91257,91263,91267,91271,91277,91285,91289,91295],{"__ignoreMap":743},[747,91210,91211,91213],{"class":749,"line":750},[747,91212,754],{"class":753},[747,91214,758],{"class":757},[747,91216,91217,91219],{"class":749,"line":761},[747,91218,764],{"class":753},[747,91220,758],{"class":757},[747,91222,91223],{"class":749,"line":769},[747,91224,773],{"class":772},[747,91226,91227,91229],{"class":749,"line":776},[747,91228,779],{"class":753},[747,91230,758],{"class":757},[747,91232,91233],{"class":749,"line":784},[747,91234,787],{"class":772},[747,91236,91237],{"class":749,"line":790},[747,91238,793],{"class":772},[747,91240,91241,91243],{"class":749,"line":796},[747,91242,799],{"class":757},[747,91244,803],{"class":802},[747,91246,91247,91249],{"class":749,"line":806},[747,91248,799],{"class":757},[747,91250,811],{"class":802},[747,91252,91253,91255],{"class":749,"line":814},[747,91254,799],{"class":757},[747,91256,819],{"class":802},[747,91258,91259,91261],{"class":749,"line":822},[747,91260,825],{"class":753},[747,91262,758],{"class":757},[747,91264,91265],{"class":749,"line":830},[747,91266,833],{"class":772},[747,91268,91269],{"class":749,"line":836},[747,91270,839],{"class":772},[747,91272,91273,91275],{"class":749,"line":842},[747,91274,845],{"class":753},[747,91276,758],{"class":757},[747,91278,91279,91281,91283],{"class":749,"line":850},[747,91280,853],{"class":753},[747,91282,856],{"class":757},[747,91284,860],{"class":859},[747,91286,91287],{"class":749,"line":863},[747,91288,866],{"class":772},[747,91290,91291,91293],{"class":749,"line":869},[747,91292,872],{"class":753},[747,91294,758],{"class":757},[747,91296,91297,91299,91301],{"class":749,"line":877},[747,91298,880],{"class":753},[747,91300,856],{"class":757},[747,91302,860],{"class":859},[613,91304,888],{"id":887},[523,91306,891],{},[738,91308,91309],{"className":740,"code":894,"language":742,"meta":743,"style":743},[567,91310,91311,91317,91323,91327,91333,91341,91345,91349,91353,91357,91361,91367,91377,91381,91387,91397,91403,91409,91413,91417,91421,91425,91437,91441,91445,91457,91461,91473,91479,91485,91489,91493,91505,91511,91517,91521,91525,91529],{"__ignoreMap":743},[747,91312,91313,91315],{"class":749,"line":750},[747,91314,825],{"class":753},[747,91316,758],{"class":757},[747,91318,91319,91321],{"class":749,"line":761},[747,91320,764],{"class":753},[747,91322,758],{"class":757},[747,91324,91325],{"class":749,"line":769},[747,91326,913],{"class":772},[747,91328,91329,91331],{"class":749,"line":776},[747,91330,918],{"class":753},[747,91332,758],{"class":757},[747,91334,91335,91337,91339],{"class":749,"line":784},[747,91336,925],{"class":753},[747,91338,856],{"class":757},[747,91340,930],{"class":802},[747,91342,91343],{"class":749,"line":790},[747,91344,935],{"class":772},[747,91346,91347],{"class":749,"line":796},[747,91348,940],{"class":772},[747,91350,91351],{"class":749,"line":806},[747,91352,945],{"class":772},[747,91354,91355],{"class":749,"line":814},[747,91356,950],{"class":772},[747,91358,91359],{"class":749,"line":822},[747,91360,955],{"class":772},[747,91362,91363,91365],{"class":749,"line":830},[747,91364,960],{"class":753},[747,91366,758],{"class":757},[747,91368,91369,91371,91373,91375],{"class":749,"line":836},[747,91370,799],{"class":757},[747,91372,969],{"class":757},[747,91374,972],{"class":802},[747,91376,975],{"class":757},[747,91378,91379],{"class":749,"line":842},[747,91380,980],{"class":772},[747,91382,91383,91385],{"class":749,"line":850},[747,91384,985],{"class":753},[747,91386,758],{"class":757},[747,91388,91389,91391,91393,91395],{"class":749,"line":863},[747,91390,799],{"class":757},[747,91392,969],{"class":757},[747,91394,996],{"class":802},[747,91396,975],{"class":757},[747,91398,91399,91401],{"class":749,"line":869},[747,91400,1003],{"class":753},[747,91402,758],{"class":757},[747,91404,91405,91407],{"class":749,"line":877},[747,91406,1010],{"class":753},[747,91408,758],{"class":757},[747,91410,91411],{"class":749,"line":1015},[747,91412,1018],{"class":772},[747,91414,91415],{"class":749,"line":1021},[747,91416,1024],{"class":772},[747,91418,91419],{"class":749,"line":1027},[747,91420,1030],{"class":772},[747,91422,91423],{"class":749,"line":1033},[747,91424,1036],{"class":772},[747,91426,91427,91429,91431,91433,91435],{"class":749,"line":1039},[747,91428,1042],{"class":753},[747,91430,856],{"class":757},[747,91432,969],{"class":757},[747,91434,1049],{"class":802},[747,91436,975],{"class":757},[747,91438,91439],{"class":749,"line":1054},[747,91440,1057],{"class":772},[747,91442,91443],{"class":749,"line":1060},[747,91444,1063],{"class":772},[747,91446,91447,91449,91451,91453,91455],{"class":749,"line":1066},[747,91448,1069],{"class":753},[747,91450,856],{"class":757},[747,91452,969],{"class":757},[747,91454,1076],{"class":802},[747,91456,975],{"class":757},[747,91458,91459],{"class":749,"line":1081},[747,91460,1084],{"class":772},[747,91462,91463,91465,91467,91469,91471],{"class":749,"line":1087},[747,91464,1090],{"class":753},[747,91466,856],{"class":757},[747,91468,969],{"class":757},[747,91470,1097],{"class":802},[747,91472,975],{"class":757},[747,91474,91475,91477],{"class":749,"line":1102},[747,91476,1105],{"class":753},[747,91478,758],{"class":757},[747,91480,91481,91483],{"class":749,"line":1110},[747,91482,1010],{"class":753},[747,91484,758],{"class":757},[747,91486,91487],{"class":749,"line":1117},[747,91488,1120],{"class":772},[747,91490,91491],{"class":749,"line":1123},[747,91492,1126],{"class":772},[747,91494,91495,91497,91499,91501,91503],{"class":749,"line":1129},[747,91496,1042],{"class":753},[747,91498,856],{"class":757},[747,91500,969],{"class":757},[747,91502,1049],{"class":802},[747,91504,975],{"class":757},[747,91506,91507,91509],{"class":749,"line":1142},[747,91508,1145],{"class":753},[747,91510,758],{"class":757},[747,91512,91513,91515],{"class":749,"line":1150},[747,91514,1010],{"class":753},[747,91516,758],{"class":757},[747,91518,91519],{"class":749,"line":1157},[747,91520,1160],{"class":772},[747,91522,91523],{"class":749,"line":1163},[747,91524,1126],{"class":772},[747,91526,91527],{"class":749,"line":1168},[747,91528,1171],{"class":772},[747,91530,91531,91533,91535,91537,91539],{"class":749,"line":1174},[747,91532,1177],{"class":753},[747,91534,856],{"class":757},[747,91536,969],{"class":757},[747,91538,1184],{"class":802},[747,91540,975],{"class":757},[613,91542,1190],{"id":1189},[523,91544,1193],{},[535,91546,1197],{"id":1196},[523,91548,1200,91549,1203],{},[567,91550,594],{},[523,91552,1206],{},[738,91554,91555],{"className":740,"code":1209,"language":742,"meta":743,"style":743},[567,91556,91557,91561,91565,91577,91589,91593,91597,91605,91609,91615,91619,91627,91631,91637,91649,91653,91659,91667,91671,91675,91681,91693,91697,91703,91707,91715,91719,91727,91731,91735,91743,91751,91755,91761,91767,91771,91779,91783,91787,91795,91799,91803,91809,91817,91821,91827,91831,91839,91843,91849,91853,91861,91865,91869,91873,91877],{"__ignoreMap":743},[747,91558,91559],{"class":749,"line":750},[747,91560,1216],{"class":772},[747,91562,91563],{"class":749,"line":761},[747,91564,1221],{"class":772},[747,91566,91567,91569,91571,91573,91575],{"class":749,"line":769},[747,91568,1226],{"class":753},[747,91570,856],{"class":757},[747,91572,969],{"class":757},[747,91574,1233],{"class":802},[747,91576,975],{"class":757},[747,91578,91579,91581,91583,91585,91587],{"class":749,"line":776},[747,91580,1240],{"class":753},[747,91582,856],{"class":757},[747,91584,969],{"class":757},[747,91586,1247],{"class":802},[747,91588,975],{"class":757},[747,91590,91591],{"class":749,"line":784},[747,91592,1255],{"emptyLinePlaceholder":1254},[747,91594,91595],{"class":749,"line":790},[747,91596,1260],{"class":772},[747,91598,91599,91601,91603],{"class":749,"line":796},[747,91600,1265],{"class":753},[747,91602,856],{"class":757},[747,91604,860],{"class":859},[747,91606,91607],{"class":749,"line":806},[747,91608,1255],{"emptyLinePlaceholder":1254},[747,91610,91611,91613],{"class":749,"line":814},[747,91612,1278],{"class":753},[747,91614,758],{"class":757},[747,91616,91617],{"class":749,"line":822},[747,91618,1285],{"class":772},[747,91620,91621,91623,91625],{"class":749,"line":830},[747,91622,1290],{"class":753},[747,91624,856],{"class":757},[747,91626,860],{"class":859},[747,91628,91629],{"class":749,"line":836},[747,91630,1255],{"emptyLinePlaceholder":1254},[747,91632,91633,91635],{"class":749,"line":842},[747,91634,1303],{"class":753},[747,91636,758],{"class":757},[747,91638,91639,91641,91643,91645,91647],{"class":749,"line":850},[747,91640,1310],{"class":753},[747,91642,856],{"class":757},[747,91644,969],{"class":757},[747,91646,1317],{"class":802},[747,91648,975],{"class":757},[747,91650,91651],{"class":749,"line":863},[747,91652,1255],{"emptyLinePlaceholder":1254},[747,91654,91655,91657],{"class":749,"line":869},[747,91656,1328],{"class":753},[747,91658,758],{"class":757},[747,91660,91661,91663,91665],{"class":749,"line":877},[747,91662,1335],{"class":753},[747,91664,856],{"class":757},[747,91666,1340],{"class":859},[747,91668,91669],{"class":749,"line":1015},[747,91670,1255],{"emptyLinePlaceholder":1254},[747,91672,91673],{"class":749,"line":1021},[747,91674,1349],{"class":772},[747,91676,91677,91679],{"class":749,"line":1027},[747,91678,1354],{"class":753},[747,91680,758],{"class":757},[747,91682,91683,91685,91687,91689,91691],{"class":749,"line":1033},[747,91684,1361],{"class":753},[747,91686,856],{"class":757},[747,91688,969],{"class":757},[747,91690,1368],{"class":802},[747,91692,975],{"class":757},[747,91694,91695],{"class":749,"line":1039},[747,91696,1255],{"emptyLinePlaceholder":1254},[747,91698,91699,91701],{"class":749,"line":1054},[747,91700,1379],{"class":753},[747,91702,758],{"class":757},[747,91704,91705],{"class":749,"line":1060},[747,91706,1386],{"class":772},[747,91708,91709,91711,91713],{"class":749,"line":1066},[747,91710,1391],{"class":753},[747,91712,856],{"class":757},[747,91714,1340],{"class":859},[747,91716,91717],{"class":749,"line":1081},[747,91718,1400],{"class":772},[747,91720,91721,91723,91725],{"class":749,"line":1087},[747,91722,1405],{"class":753},[747,91724,856],{"class":757},[747,91726,860],{"class":859},[747,91728,91729],{"class":749,"line":1102},[747,91730,1255],{"emptyLinePlaceholder":1254},[747,91732,91733],{"class":749,"line":1110},[747,91734,1418],{"class":772},[747,91736,91737,91739,91741],{"class":749,"line":1117},[747,91738,1423],{"class":753},[747,91740,856],{"class":757},[747,91742,1340],{"class":859},[747,91744,91745,91747,91749],{"class":749,"line":1123},[747,91746,1432],{"class":753},[747,91748,856],{"class":757},[747,91750,1340],{"class":859},[747,91752,91753],{"class":749,"line":1129},[747,91754,1255],{"emptyLinePlaceholder":1254},[747,91756,91757,91759],{"class":749,"line":1142},[747,91758,1445],{"class":753},[747,91760,758],{"class":757},[747,91762,91763,91765],{"class":749,"line":1150},[747,91764,1452],{"class":753},[747,91766,758],{"class":757},[747,91768,91769],{"class":749,"line":1157},[747,91770,1459],{"class":772},[747,91772,91773,91775,91777],{"class":749,"line":1163},[747,91774,853],{"class":753},[747,91776,856],{"class":757},[747,91778,1340],{"class":859},[747,91780,91781],{"class":749,"line":1168},[747,91782,1472],{"class":772},[747,91784,91785],{"class":749,"line":1174},[747,91786,1477],{"class":772},[747,91788,91789,91791,91793],{"class":749,"line":1480},[747,91790,1483],{"class":753},[747,91792,856],{"class":757},[747,91794,1488],{"class":802},[747,91796,91797],{"class":749,"line":1491},[747,91798,1255],{"emptyLinePlaceholder":1254},[747,91800,91801],{"class":749,"line":1496},[747,91802,1499],{"class":772},[747,91804,91805,91807],{"class":749,"line":1502},[747,91806,1505],{"class":753},[747,91808,758],{"class":757},[747,91810,91811,91813,91815],{"class":749,"line":1510},[747,91812,1513],{"class":753},[747,91814,856],{"class":757},[747,91816,860],{"class":859},[747,91818,91819],{"class":749,"line":1520},[747,91820,1255],{"emptyLinePlaceholder":1254},[747,91822,91823,91825],{"class":749,"line":1525},[747,91824,1528],{"class":753},[747,91826,758],{"class":757},[747,91828,91829],{"class":749,"line":1533},[747,91830,1536],{"class":772},[747,91832,91833,91835,91837],{"class":749,"line":1539},[747,91834,1542],{"class":753},[747,91836,856],{"class":757},[747,91838,1340],{"class":859},[747,91840,91841],{"class":749,"line":1549},[747,91842,1255],{"emptyLinePlaceholder":1254},[747,91844,91845,91847],{"class":749,"line":1554},[747,91846,1557],{"class":753},[747,91848,758],{"class":757},[747,91850,91851],{"class":749,"line":1562},[747,91852,1565],{"class":772},[747,91854,91855,91857,91859],{"class":749,"line":1568},[747,91856,1542],{"class":753},[747,91858,856],{"class":757},[747,91860,860],{"class":859},[747,91862,91863],{"class":749,"line":1577},[747,91864,1255],{"emptyLinePlaceholder":1254},[747,91866,91867],{"class":749,"line":1582},[747,91868,1585],{"class":772},[747,91870,91871],{"class":749,"line":1588},[747,91872,1591],{"class":772},[747,91874,91875],{"class":749,"line":1594},[747,91876,1597],{"class":772},[747,91878,91879,91881,91883,91885,91887],{"class":749,"line":1600},[747,91880,1603],{"class":753},[747,91882,856],{"class":757},[747,91884,969],{"class":757},[747,91886,1368],{"class":802},[747,91888,975],{"class":757},[523,91890,1614,91891,1618],{},[567,91892,1617],{},[738,91894,91895],{"className":1621,"code":1622,"language":1623,"meta":743,"style":743},[567,91896,91897,91907,91913,91919,91927,91933],{"__ignoreMap":743},[747,91898,91899,91901,91903,91905],{"class":749,"line":750},[747,91900,1631],{"class":1630},[747,91902,1634],{"class":802},[747,91904,1637],{"class":802},[747,91906,1641],{"class":1640},[747,91908,91909,91911],{"class":749,"line":761},[747,91910,1646],{"class":802},[747,91912,1641],{"class":1640},[747,91914,91915,91917],{"class":749,"line":769},[747,91916,1653],{"class":802},[747,91918,1641],{"class":1640},[747,91920,91921,91923,91925],{"class":749,"line":776},[747,91922,1660],{"class":802},[747,91924,1663],{"class":802},[747,91926,1641],{"class":1640},[747,91928,91929,91931],{"class":749,"line":784},[747,91930,1670],{"class":802},[747,91932,1641],{"class":1640},[747,91934,91935],{"class":749,"line":790},[747,91936,1677],{"class":802},[535,91938,1681],{"id":1680},[523,91940,1684,91941,1687,91943,1690],{},[567,91942,594],{},[567,91944,594],{},[523,91946,1693,91947,1697,91949,595],{},[567,91948,1696],{},[567,91950,594],{},[738,91952,91953],{"className":740,"code":1702,"language":742,"meta":743,"style":743},[567,91954,91955,91959,91965,91971,91977,91981,91987,91991,91997,92003,92007,92013,92017,92023,92027,92035,92039,92043,92049,92059],{"__ignoreMap":743},[747,91956,91957],{"class":749,"line":750},[747,91958,1709],{"class":772},[747,91960,91961,91963],{"class":749,"line":761},[747,91962,1714],{"class":753},[747,91964,758],{"class":757},[747,91966,91967,91969],{"class":749,"line":769},[747,91968,1721],{"class":757},[747,91970,1724],{"class":802},[747,91972,91973,91975],{"class":749,"line":776},[747,91974,1721],{"class":757},[747,91976,1731],{"class":802},[747,91978,91979],{"class":749,"line":784},[747,91980,1255],{"emptyLinePlaceholder":1254},[747,91982,91983,91985],{"class":749,"line":790},[747,91984,1740],{"class":753},[747,91986,758],{"class":757},[747,91988,91989],{"class":749,"line":796},[747,91990,1747],{"class":772},[747,91992,91993,91995],{"class":749,"line":806},[747,91994,1721],{"class":757},[747,91996,1754],{"class":802},[747,91998,91999,92001],{"class":749,"line":814},[747,92000,1721],{"class":757},[747,92002,1761],{"class":802},[747,92004,92005],{"class":749,"line":822},[747,92006,1766],{"class":772},[747,92008,92009,92011],{"class":749,"line":830},[747,92010,1721],{"class":757},[747,92012,1773],{"class":802},[747,92014,92015],{"class":749,"line":836},[747,92016,1255],{"emptyLinePlaceholder":1254},[747,92018,92019,92021],{"class":749,"line":842},[747,92020,1782],{"class":753},[747,92022,758],{"class":757},[747,92024,92025],{"class":749,"line":850},[747,92026,1789],{"class":772},[747,92028,92029,92031,92033],{"class":749,"line":863},[747,92030,1542],{"class":753},[747,92032,856],{"class":757},[747,92034,860],{"class":859},[747,92036,92037],{"class":749,"line":869},[747,92038,1255],{"emptyLinePlaceholder":1254},[747,92040,92041],{"class":749,"line":877},[747,92042,1806],{"class":772},[747,92044,92045,92047],{"class":749,"line":1015},[747,92046,1811],{"class":753},[747,92048,758],{"class":757},[747,92050,92051,92053,92055,92057],{"class":749,"line":1021},[747,92052,1721],{"class":757},[747,92054,1820],{"class":753},[747,92056,856],{"class":757},[747,92058,1825],{"class":802},[747,92060,92061,92063,92065],{"class":749,"line":1027},[747,92062,1830],{"class":753},[747,92064,856],{"class":757},[747,92066,1835],{"class":802},[523,92068,1838,92069,1842],{},[567,92070,1841],{},[738,92072,92073],{"className":1621,"code":1845,"language":1623,"meta":743,"style":743},[567,92074,92075,92085,92091,92099,92105,92111],{"__ignoreMap":743},[747,92076,92077,92079,92081,92083],{"class":749,"line":750},[747,92078,1631],{"class":1630},[747,92080,1634],{"class":802},[747,92082,1637],{"class":802},[747,92084,1641],{"class":1640},[747,92086,92087,92089],{"class":749,"line":761},[747,92088,1646],{"class":802},[747,92090,1641],{"class":1640},[747,92092,92093,92095,92097],{"class":749,"line":769},[747,92094,1868],{"class":802},[747,92096,1871],{"class":802},[747,92098,1641],{"class":1640},[747,92100,92101,92103],{"class":749,"line":776},[747,92102,1878],{"class":802},[747,92104,1641],{"class":1640},[747,92106,92107,92109],{"class":749,"line":784},[747,92108,1885],{"class":802},[747,92110,1641],{"class":1640},[747,92112,92113,92115],{"class":749,"line":790},[747,92114,1892],{"class":802},[747,92116,1896],{"class":1895},[535,92118,1900],{"id":1899},[523,92120,1903,92121,1909],{},[527,92122,1908],{"href":1906,"rel":92123},[531],[738,92125,92126],{"className":1621,"code":1912,"language":1623,"meta":743,"style":743},[567,92127,92128,92144,92148],{"__ignoreMap":743},[747,92129,92130,92132,92134,92136,92138,92140,92142],{"class":749,"line":750},[747,92131,1919],{"class":1630},[747,92133,1922],{"class":802},[747,92135,1925],{"class":802},[747,92137,1928],{"class":802},[747,92139,1931],{"class":802},[747,92141,1934],{"class":802},[747,92143,1937],{"class":802},[747,92145,92146],{"class":749,"line":761},[747,92147,1942],{"class":772},[747,92149,92150,92152,92154,92156,92158,92160],{"class":749,"line":769},[747,92151,1919],{"class":1630},[747,92153,1922],{"class":802},[747,92155,1951],{"class":802},[747,92157,1928],{"class":802},[747,92159,1931],{"class":802},[747,92161,1958],{"class":802},[738,92163,92164],{"className":1621,"code":1961,"language":1623,"meta":743,"style":743},[567,92165,92166,92178,92200,92222,92244,92266,92288,92310,92332],{"__ignoreMap":743},[747,92167,92168,92170,92172,92174,92176],{"class":749,"line":750},[747,92169,1919],{"class":1630},[747,92171,1922],{"class":802},[747,92173,1951],{"class":802},[747,92175,1974],{"class":802},[747,92177,1977],{"class":802},[747,92179,92180,92182,92184,92186,92188,92190,92192,92194,92196,92198],{"class":749,"line":761},[747,92181,1982],{"class":1630},[747,92183,1985],{"class":802},[747,92185,1988],{"class":802},[747,92187,1991],{"class":802},[747,92189,1994],{"class":802},[747,92191,1997],{"class":802},[747,92193,2000],{"class":757},[747,92195,2003],{"class":1630},[747,92197,2006],{"class":757},[747,92199,2009],{"class":802},[747,92201,92202,92204,92206,92208,92210,92212,92214,92216,92218,92220],{"class":749,"line":769},[747,92203,2014],{"class":1630},[747,92205,2017],{"class":802},[747,92207,2020],{"class":802},[747,92209,2023],{"class":802},[747,92211,2026],{"class":757},[747,92213,2029],{"class":802},[747,92215,2032],{"class":1640},[747,92217,2035],{"class":757},[747,92219,2038],{"class":802},[747,92221,2041],{"class":802},[747,92223,92224,92226,92228,92230,92232,92234,92236,92238,92240,92242],{"class":749,"line":776},[747,92225,2014],{"class":1630},[747,92227,2048],{"class":802},[747,92229,2051],{"class":802},[747,92231,2054],{"class":802},[747,92233,2057],{"class":757},[747,92235,2029],{"class":802},[747,92237,2032],{"class":1640},[747,92239,2035],{"class":757},[747,92241,2066],{"class":802},[747,92243,2069],{"class":802},[747,92245,92246,92248,92250,92252,92254,92256,92258,92260,92262,92264],{"class":749,"line":784},[747,92247,2014],{"class":1630},[747,92249,2076],{"class":802},[747,92251,2079],{"class":802},[747,92253,2082],{"class":802},[747,92255,2026],{"class":757},[747,92257,2029],{"class":802},[747,92259,2032],{"class":1640},[747,92261,2035],{"class":757},[747,92263,2093],{"class":802},[747,92265,2096],{"class":802},[747,92267,92268,92270,92272,92274,92276,92278,92280,92282,92284,92286],{"class":749,"line":790},[747,92269,2101],{"class":1630},[747,92271,2104],{"class":802},[747,92273,2107],{"class":802},[747,92275,2110],{"class":802},[747,92277,2113],{"class":757},[747,92279,2029],{"class":802},[747,92281,2032],{"class":1640},[747,92283,2035],{"class":757},[747,92285,2122],{"class":802},[747,92287,2125],{"class":802},[747,92289,92290,92292,92294,92296,92298,92300,92302,92304,92306,92308],{"class":749,"line":796},[747,92291,2101],{"class":1630},[747,92293,2132],{"class":802},[747,92295,2135],{"class":802},[747,92297,2138],{"class":802},[747,92299,2026],{"class":757},[747,92301,2029],{"class":802},[747,92303,2032],{"class":1640},[747,92305,2035],{"class":757},[747,92307,2066],{"class":802},[747,92309,2151],{"class":802},[747,92311,92312,92314,92316,92318,92320,92322,92324,92326,92328,92330],{"class":749,"line":806},[747,92313,2101],{"class":1630},[747,92315,2158],{"class":802},[747,92317,2161],{"class":802},[747,92319,2164],{"class":802},[747,92321,2057],{"class":757},[747,92323,2029],{"class":802},[747,92325,2032],{"class":1640},[747,92327,2035],{"class":757},[747,92329,2175],{"class":802},[747,92331,2178],{"class":802},[747,92333,92334,92336,92338,92340,92342,92344,92346,92348,92350,92352],{"class":749,"line":814},[747,92335,2101],{"class":1630},[747,92337,2185],{"class":802},[747,92339,2188],{"class":802},[747,92341,2110],{"class":802},[747,92343,2113],{"class":757},[747,92345,2029],{"class":802},[747,92347,2032],{"class":1640},[747,92349,2035],{"class":757},[747,92351,2201],{"class":802},[747,92353,2096],{"class":802},[738,92355,92356],{"className":1621,"code":2206,"language":1623,"meta":743,"style":743},[567,92357,92358,92372,92396,92428,92460,92492],{"__ignoreMap":743},[747,92359,92360,92362,92364,92366,92368,92370],{"class":749,"line":750},[747,92361,1919],{"class":1630},[747,92363,1922],{"class":802},[747,92365,1951],{"class":802},[747,92367,2219],{"class":802},[747,92369,2222],{"class":802},[747,92371,2225],{"class":802},[747,92373,92374,92376,92378,92380,92382,92384,92386,92388,92390,92392,92394],{"class":749,"line":761},[747,92375,2230],{"class":1630},[747,92377,2233],{"class":802},[747,92379,2236],{"class":802},[747,92381,2239],{"class":802},[747,92383,2242],{"class":802},[747,92385,2245],{"class":802},[747,92387,2248],{"class":802},[747,92389,2251],{"class":802},[747,92391,2254],{"class":802},[747,92393,2257],{"class":802},[747,92395,2260],{"class":802},[747,92397,92398,92400,92402,92404,92406,92408,92410,92412,92414,92416,92418,92420,92422,92424,92426],{"class":749,"line":769},[747,92399,2265],{"class":1630},[747,92401,2268],{"class":802},[747,92403,2271],{"class":802},[747,92405,2274],{"class":1895},[747,92407,2277],{"class":802},[747,92409,2280],{"class":802},[747,92411,2283],{"class":802},[747,92413,2026],{"class":757},[747,92415,2029],{"class":802},[747,92417,2032],{"class":1640},[747,92419,2035],{"class":757},[747,92421,2294],{"class":757},[747,92423,2029],{"class":802},[747,92425,2032],{"class":1640},[747,92427,2301],{"class":757},[747,92429,92430,92432,92434,92436,92438,92440,92442,92444,92446,92448,92450,92452,92454,92456,92458],{"class":749,"line":776},[747,92431,2306],{"class":1630},[747,92433,2268],{"class":802},[747,92435,2271],{"class":802},[747,92437,2274],{"class":1895},[747,92439,2315],{"class":802},[747,92441,2318],{"class":802},[747,92443,2321],{"class":802},[747,92445,2026],{"class":757},[747,92447,2029],{"class":802},[747,92449,2032],{"class":1640},[747,92451,2035],{"class":757},[747,92453,2294],{"class":757},[747,92455,2029],{"class":802},[747,92457,2032],{"class":1640},[747,92459,2301],{"class":757},[747,92461,92462,92464,92466,92468,92470,92472,92474,92476,92478,92480,92482,92484,92486,92488,92490],{"class":749,"line":784},[747,92463,2342],{"class":1630},[747,92465,2345],{"class":802},[747,92467,2271],{"class":802},[747,92469,2274],{"class":1895},[747,92471,2315],{"class":802},[747,92473,2354],{"class":802},[747,92475,2283],{"class":802},[747,92477,2026],{"class":757},[747,92479,2029],{"class":802},[747,92481,2032],{"class":1640},[747,92483,2035],{"class":757},[747,92485,2294],{"class":757},[747,92487,2029],{"class":802},[747,92489,2032],{"class":1640},[747,92491,2301],{"class":757},[747,92493,92494,92496,92498,92500,92502,92504,92506,92508,92510,92512,92514,92516,92518,92520,92522],{"class":749,"line":790},[747,92495,2377],{"class":1630},[747,92497,2380],{"class":802},[747,92499,2271],{"class":802},[747,92501,2274],{"class":1895},[747,92503,2387],{"class":802},[747,92505,2390],{"class":802},[747,92507,2321],{"class":802},[747,92509,2026],{"class":757},[747,92511,2029],{"class":802},[747,92513,2032],{"class":1640},[747,92515,2035],{"class":757},[747,92517,2294],{"class":757},[747,92519,2029],{"class":802},[747,92521,2032],{"class":1640},[747,92523,2301],{"class":757},[738,92525,92526],{"className":1621,"code":2411,"language":1623,"meta":743,"style":743},[567,92527,92528,92542,92564,92590,92622],{"__ignoreMap":743},[747,92529,92530,92532,92534,92536,92538,92540],{"class":749,"line":750},[747,92531,1919],{"class":1630},[747,92533,1922],{"class":802},[747,92535,1951],{"class":802},[747,92537,2424],{"class":802},[747,92539,2222],{"class":802},[747,92541,2225],{"class":802},[747,92543,92544,92546,92548,92550,92552,92554,92556,92558,92560,92562],{"class":749,"line":761},[747,92545,2230],{"class":1630},[747,92547,2435],{"class":802},[747,92549,2438],{"class":802},[747,92551,2441],{"class":802},[747,92553,2444],{"class":802},[747,92555,2447],{"class":802},[747,92557,2450],{"class":802},[747,92559,2453],{"class":802},[747,92561,2456],{"class":802},[747,92563,2459],{"class":802},[747,92565,92566,92568,92570,92572,92574,92576,92578,92580,92582,92584,92586,92588],{"class":749,"line":769},[747,92567,2464],{"class":1630},[747,92569,2467],{"class":802},[747,92571,2470],{"class":802},[747,92573,2473],{"class":802},[747,92575,2476],{"class":802},[747,92577,2479],{"class":802},[747,92579,2026],{"class":757},[747,92581,2029],{"class":802},[747,92583,2032],{"class":1640},[747,92585,2035],{"class":757},[747,92587,2490],{"class":802},[747,92589,2493],{"class":1640},[747,92591,92592,92594,92596,92598,92600,92602,92604,92606,92608,92610,92612,92614,92616,92618,92620],{"class":749,"line":776},[747,92593,2498],{"class":1630},[747,92595,2501],{"class":802},[747,92597,2504],{"class":757},[747,92599,2029],{"class":802},[747,92601,2032],{"class":1640},[747,92603,2035],{"class":757},[747,92605,2513],{"class":802},[747,92607,2476],{"class":802},[747,92609,2518],{"class":802},[747,92611,2026],{"class":757},[747,92613,2029],{"class":802},[747,92615,2032],{"class":1640},[747,92617,2035],{"class":757},[747,92619,2490],{"class":802},[747,92621,2493],{"class":1640},[747,92623,92624,92626,92628,92630,92632,92634,92636,92638,92640,92642,92644,92646,92648,92650,92652],{"class":749,"line":784},[747,92625,2535],{"class":1630},[747,92627,2538],{"class":802},[747,92629,2026],{"class":757},[747,92631,2029],{"class":802},[747,92633,2032],{"class":1640},[747,92635,2035],{"class":757},[747,92637,2549],{"class":802},[747,92639,2476],{"class":802},[747,92641,2554],{"class":802},[747,92643,2026],{"class":757},[747,92645,2029],{"class":802},[747,92647,2032],{"class":1640},[747,92649,2035],{"class":757},[747,92651,2490],{"class":802},[747,92653,2493],{"class":1640},[523,92655,2569,92656,2572],{},[567,92657,2535],{},[738,92659,92660],{"className":1621,"code":2575,"language":1623,"meta":743,"style":743},[567,92661,92662,92682,92688,92708,92714,92728,92752,92784,92816,92848],{"__ignoreMap":743},[747,92663,92664,92666,92668,92670,92672,92674,92676,92678,92680],{"class":749,"line":750},[747,92665,1919],{"class":1630},[747,92667,1922],{"class":802},[747,92669,2586],{"class":802},[747,92671,2589],{"class":802},[747,92673,2592],{"class":802},[747,92675,2595],{"class":802},[747,92677,2598],{"class":802},[747,92679,2601],{"class":802},[747,92681,2604],{"class":802},[747,92683,92684,92686],{"class":749,"line":761},[747,92685,2609],{"class":1630},[747,92687,2612],{"class":802},[747,92689,92690,92692,92694,92696,92698,92700,92702,92704,92706],{"class":749,"line":769},[747,92691,1919],{"class":1630},[747,92693,1922],{"class":802},[747,92695,2586],{"class":802},[747,92697,2623],{"class":802},[747,92699,2592],{"class":802},[747,92701,2595],{"class":802},[747,92703,2598],{"class":802},[747,92705,2601],{"class":802},[747,92707,2604],{"class":802},[747,92709,92710,92712],{"class":749,"line":776},[747,92711,2609],{"class":1630},[747,92713,2612],{"class":802},[747,92715,92716,92718,92720,92722,92724,92726],{"class":749,"line":784},[747,92717,1919],{"class":1630},[747,92719,1922],{"class":802},[747,92721,1951],{"class":802},[747,92723,2219],{"class":802},[747,92725,2222],{"class":802},[747,92727,2225],{"class":802},[747,92729,92730,92732,92734,92736,92738,92740,92742,92744,92746,92748,92750],{"class":749,"line":790},[747,92731,2230],{"class":1630},[747,92733,2233],{"class":802},[747,92735,2236],{"class":802},[747,92737,2239],{"class":802},[747,92739,2242],{"class":802},[747,92741,2245],{"class":802},[747,92743,2248],{"class":802},[747,92745,2251],{"class":802},[747,92747,2254],{"class":802},[747,92749,2257],{"class":802},[747,92751,2260],{"class":802},[747,92753,92754,92756,92758,92760,92762,92764,92766,92768,92770,92772,92774,92776,92778,92780,92782],{"class":749,"line":796},[747,92755,2306],{"class":1630},[747,92757,2268],{"class":802},[747,92759,2271],{"class":802},[747,92761,2274],{"class":1895},[747,92763,2690],{"class":802},[747,92765,2318],{"class":802},[747,92767,2321],{"class":802},[747,92769,2026],{"class":757},[747,92771,2029],{"class":802},[747,92773,2032],{"class":1640},[747,92775,2035],{"class":757},[747,92777,2294],{"class":757},[747,92779,2029],{"class":802},[747,92781,2032],{"class":1640},[747,92783,2301],{"class":757},[747,92785,92786,92788,92790,92792,92794,92796,92798,92800,92802,92804,92806,92808,92810,92812,92814],{"class":749,"line":806},[747,92787,2715],{"class":1630},[747,92789,2268],{"class":802},[747,92791,2271],{"class":802},[747,92793,2274],{"class":1895},[747,92795,2724],{"class":802},[747,92797,2727],{"class":802},[747,92799,2321],{"class":802},[747,92801,2026],{"class":757},[747,92803,2029],{"class":802},[747,92805,2032],{"class":1640},[747,92807,2035],{"class":757},[747,92809,2294],{"class":757},[747,92811,2029],{"class":802},[747,92813,2032],{"class":1640},[747,92815,2301],{"class":757},[747,92817,92818,92820,92822,92824,92826,92828,92830,92832,92834,92836,92838,92840,92842,92844,92846],{"class":749,"line":814},[747,92819,2342],{"class":1630},[747,92821,2345],{"class":802},[747,92823,2271],{"class":802},[747,92825,2274],{"class":1895},[747,92827,2690],{"class":802},[747,92829,2354],{"class":802},[747,92831,2283],{"class":802},[747,92833,2026],{"class":757},[747,92835,2029],{"class":802},[747,92837,2032],{"class":1640},[747,92839,2035],{"class":757},[747,92841,2294],{"class":757},[747,92843,2029],{"class":802},[747,92845,2032],{"class":1640},[747,92847,2301],{"class":757},[747,92849,92850,92852,92854,92856,92858,92860,92862,92864,92866,92868,92870,92872,92874,92876,92878],{"class":749,"line":822},[747,92851,2377],{"class":1630},[747,92853,2380],{"class":802},[747,92855,2271],{"class":802},[747,92857,2274],{"class":1895},[747,92859,2790],{"class":802},[747,92861,2793],{"class":802},[747,92863,2321],{"class":802},[747,92865,2026],{"class":757},[747,92867,2029],{"class":802},[747,92869,2032],{"class":1640},[747,92871,2035],{"class":757},[747,92873,2294],{"class":757},[747,92875,2029],{"class":802},[747,92877,2032],{"class":1640},[747,92879,2301],{"class":757},[523,92881,2814,92882,2817],{},[567,92883,594],{},[535,92885,2821],{"id":2820},[523,92887,2824,92888,2827,92890,2830,92892,595],{},[567,92889,594],{},[567,92891,1696],{},[567,92893,594],{},[523,92895,2835],{},[523,92897,92898,856],{},[584,92899,2840],{},[668,92901,92902,92907],{},[638,92903,2845,92904,2851],{},[527,92905,2850],{"href":2848,"rel":92906},[531],[638,92908,2854,92909],{},[668,92910,92911],{},[638,92912,2859,92913,2865],{},[527,92914,2864],{"href":2862,"rel":92915},[531],[523,92917,2868],{},[535,92919,2872],{"id":2871},[523,92921,2875,92922,1909],{},[527,92923,2878],{"href":2878,"rel":92924},[531],[523,92926,2882,92927,2888],{},[527,92928,2887],{"href":2885,"rel":92929},[531],[2890,92931,2892],{},{"title":743,"searchDepth":761,"depth":761,"links":92933},[92934,92935,92938,92943,92944,92945,92946,92947],{"id":537,"depth":761,"text":538},{"id":572,"depth":761,"text":573,"children":92936},[92937],{"id":615,"depth":769,"text":616},{"id":695,"depth":761,"text":696,"children":92939},[92940,92941,92942],{"id":732,"depth":769,"text":733},{"id":887,"depth":769,"text":888},{"id":1189,"depth":769,"text":1190},{"id":1196,"depth":761,"text":1197},{"id":1680,"depth":761,"text":1681},{"id":1899,"depth":761,"text":1900},{"id":2820,"depth":761,"text":2821},{"id":2871,"depth":761,"text":2872},{},{"title":511,"description":2910},1776935207799]