slides.cljs 35.7 KB
Newer Older
1 2 3
(ns slides.slides
  (:require [clojure.string :as str]))

Pieter Breed's avatar
Pieter Breed committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
(def curl-via-load-balancer
     ["# TYPE kafka_client_consumer_node_metrics_request_total gauge"
      "kafka_client_consumer_node_metrics_request_total{client_id=\"consumer-1\",node_id=\"node-2147483646\",} 164643.0"
      "kafka_client_consumer_node_metrics_request_total{client_id=\"consumer-1\",node_id=\"node-1\",} 659.0"
      "kafka_client_consumer_node_metrics_request_total{client_id=\"consumer-1\",node_id=\"node--1\",} 159.0"])

(def runtime-env-variables
  ["env {"
   "  GELF_HOST = \"${attr.unique.hostname}\""
   "  GELF_FACILITY = \"${NOMAD_TASK_NAME}:${NOMAD_ALLOC_ID}\""
   "  CONSUMER_GROUP_ID = \"s33d_${NOMAD_TASK_NAME}\""
   "  TRANSACTIONAL_ID = \"s33d_${NOMAD_TASK_NAME}:${attr.unique.hostname}\""
   "}"])


(def secret-with-vault-and-templates
  ["template {"
   "  destination = \"local/env.var\""
   "  change_mode = \"noop\""
   "  env = true"
   "  data = <<EOF"
   "{{with secret \"aws/creds/datomic_reader\"}}"
   "AWS_ACCESS_KEY_ID=\"{{.Data.access_key}}\""
   "AWS_SECRET_ACCESS_KEY=\"{{.Data.secret_key}}{{end}}\""
   "EOF"
   "}"])

(def service-discovery
  ["$ dig keo-analysis-persister.service.consul. SRV"
   ""
   "; <<>> DiG 9.10.6 <<>> keo-analysis-persister.service.consul. SRV"
   ""
   ";; ANSWER SECTION:"
   "keo-analysis-persister.service.consul. 0 IN SRV	1 1 31171 ip-10-10-3-207.node.dc1.consul."
   "keo-analysis-persister.service.consul. 0 IN SRV	1 1 26447 ip-10-10-1-161.node.dc1.consul."
   ""
   ";; ADDITIONAL SECTION:"
   "ip-10-10-1-161.node.dc1.consul.	0 IN	A	10.10.1.161"
   "ip-10-10-3-207.node.dc1.consul.	0 IN	A	10.10.3.207"])

Pieter Breed's avatar
Pieter Breed committed
44 45
(def technologies
   {:source-control ["gitlab.png" "git.png" "git-lfs.png" "magit.png"]
Pieter Breed's avatar
Pieter Breed committed
46
    :development ["homebrew.png" "lein.jpeg" "boot-clj.png" "clojure.png" "datomic.png" "emacs.png" "atom.png" "python.png"]
Pieter Breed's avatar
Pieter Breed committed
47
    :big-data ["kafka.png" "zookeeper.jpeg"]
Pieter Breed's avatar
Pieter Breed committed
48
    :runtime ["consul.png" "vault.png" "terraform.png" "nomad.png" "ansible.png" "linux.png"]
Pieter Breed's avatar
Pieter Breed committed
49 50
    :debugging ["graylog.jpg" "prometheus.png" "grafana.png"]
    :scripting ["bash.png" "jq.png" "gnu.png"]
Pieter Breed's avatar
Pieter Breed committed
51
    :operating-systems ["alpine.jpg" "ubuntu.png" "high-sierra.png" "win10.jpg"]
Pieter Breed's avatar
Pieter Breed committed
52 53 54 55
    :runtimes ["jvm.svg" "lambda.png" "ec2.png" "docker.png" "go-lang.png"]
    :storage ["s3.png" "elasticsearch.svg" "ddb.png"]
    :client-side ["cljs.png" "react.png" "re-frame.png"]})

Pieter Breed's avatar
Pieter Breed committed
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
(def nomad-run-keo-analysis-persister
  ["$ nomad run nomad/renders/keo-analysis-persister.hcl"
   "==> Monitoring evaluation \"c170c3ac\""
   "    Evaluation triggered by job \"keo-analysis-persister\""
   "    Allocation \"78bb4b5f\" modified: node \"109c70b5\", group \"keo-analysis-persister\""
   "    Allocation \"c2e29432\" created: node \"870eb387\", group \"keo-analysis-persister\""
   "    Evaluation status changed: \"pending\" -> \"complete\""
   "==> Evaluation \"c170c3ac\" finished with status \"complete\""
   "" ""
   "$ nomad status keo-analysis-persister"
   "Summary"
   "Task Group              Queued  Starting  Running  Failed  Complete  Lost"
   "keo-analysis-persister  0       0         2        1       12        3"
   ""
   "Allocations"
   "ID        Node ID   Task Group              Version  Desired  Status    Created    Modified"
   "c2e29432  870eb387  keo-analysis-persister  13       run      running   3m15s ago  2m44s ago"
   "78bb4b5f  109c70b5  keo-analysis-persister  13       run      running   3m33s ago  2m54s ago"
   "5f860e0a  d1e643d5  keo-analysis-persister  11       stop     complete  1h59m ago  3m24s ago"])

(def nomad-status-keo-line-analyzer
  ["$ nomad status keo-line-analyzer"
   "Allocations"
   "ID        Node ID   Task Group         Version  Desired  Status   Created    Modified"
   "648ab50e  fff45208  keo-line-analyzer  11       run      running  1h31m ago  1h31m ago"
   "a1b9e1e0  109c70b5  keo-line-analyzer  11       run      running  1h31m ago  1h31m ago"
   "dbfe55b9  870eb387  keo-line-analyzer  11       run      running  1h31m ago  1h31m ago"
   "f01268b7  d1e643d5  keo-line-analyzer  11       run      running  1h31m ago  1h31m ago"])

(def nomad-node-status
  ["$ nomad node-status"
   "ID        DC   Name            Class   Drain  Eligibility  Status"
   "fff45208  dc1  ip-10-10-1-61   <none>  false  eligible     ready"
   "109c70b5  dc1  ip-10-10-3-207  <none>  false  eligible     ready"
   "d1e643d5  dc1  ip-10-10-5-10   <none>  false  eligible     ready"
   "870eb387  dc1  ip-10-10-1-161  <none>  false  eligible     ready"])


(def keo-line-analyzer-nomad-job
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
  [""
   "job \"keo-line-analyzer\" {"
   "  datacenters = [\"dc1\"]"
   "  type = \"system\""
   ""
   "  group \"keo-line-analyzer\" {"
   "      count = 1"
   ""
   "      restart {"
   "        attempts = 2"
   "        delay = \"10s\""
   "        interval = \"60s\""
   "        mode = \"fail\""
   "      }"
   ""
   "      task \"keo-line-analyzer\" {"
   "          driver = \"docker\""
   ""
   "          config {"
   "              image = \"docker-registry.zoona.io/pieter/kafka-exactly-once/runtime:master\""
   ""
   "              port_map {"
   "                http = 8000"
   "              }"
   ""
   "              args = ["
   "                \"-jar\","
   "                \"/opt/app.jar\","
   "                \"-a\","
   "                \"--gelf-logs\","
   "                \"--http-port\", \"8000\""
   "              ]"
   "          }"
   ""
   "          env {"
   "            BOOTSTRAP_SERVERS = \"kafka-ops.service.consul:9092\""
   "            CONSUMER_GROUP_ID = \"s33d_${NOMAD_TASK_NAME}\""
   "            TRANSACTIONAL_ID = \"s33d_${NOMAD_TASK_NAME}:${attr.unique.hostname}\""
   "            LOG_LEVEL = \"debug\""
   "          }"
   ""
   "          service {"
   "            name = \"${TASK}\""
   "            tags = [\"prometheus-service\"]"
   "            port = \"http\""
   "            check {"
   "              type = \"http\""
   "              port = \"http\""
   "              path = \"/metrics\""
   "              interval = \"5s\""
   "              timeout = \"1s\""
   "            }"
   "          }"
   ""
   "          resources {"
   "            memory = 1024"
   "            network {"
   "              port \"http\" {}"
   "            }"
   "          }"
   "      }"
   "  }"
   "}"
   ""])

Pieter Breed's avatar
Pieter Breed committed
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
(def keo-analysis-persister-job-file
  ["job \"keo-analysis-persister\" {"
   "    datacenters = [\"dc1\"]"
   "    type = \"service\""
   ""
   "    group \"keo-analysis-persister\" {"
   "        count = 2"
   ""
   "        restart {"
   "          attempts = 2"
   "          delay = \"10s\""
   "          interval = \"60s\""
   "          mode = \"fail\""
   "        }"
   ""
   "        task \"keo-analysis-persister\" {"
   "            driver = \"docker\""
   ""
   "            config {"
   "                image = \"docker-registry.zoona.io/pieter/kafka-exactly-once/runtime:master\""
   "                port_map {"
   "                  http = 8000"
   "                }"
   ""
   "                args = ["
   "                  \"-jar\", \"/opt/app.jar\","
   "                  \"-p\","
   "                  \"--gelf-logs\","
   "                  \"--http-port\", \"8000\""
   "                ]"
   "            }"
   ""
   "            env {"
   "              BOOTSTRAP_SERVERS = \"kafka-ops.service.consul:9092\""
   "              CONSUMER_GROUP_ID = \"s33d_${NOMAD_TASK_NAME}\""
   "              LOG_LEVEL = \"debug\""
   "              LOG_NS_WHITELIST = \"[]\""
   "              DATOMIC_URI = \"datomic:ddb://eu-west-1/centaur.zoona.network-datomic_tachyon/kafka-exactly-once-demo\""
   "            }"
   ""
   "            template {"
   "              destination = \"local/env.var\""
   "              change_mode = \"noop\""
   "              env = true"
   "              data = <<EOF"
   "{{with secret \"aws/creds/datomic_reader\"}}"
   "AWS_ACCESS_KEY_ID=\"{{.Data.access_key}}\""
   "AWS_SECRET_ACCESS_KEY=\"{{.Data.secret_key}}{{end}}\""
   "EOF"
   "            }"
   ""
   "            vault {"
   "              policies = [\"datomic_reader\"]"
   "            }"
   ""
   "            service {"
   "              name = \"${TASK}\""
   "              tags = [\"prometheus-service\"]"
   "              port = \"http\""
   "              check {"
   "                type = \"http\""
   "                port = \"http\""
   "                path = \"/metrics\""
   "                interval = \"5s\""
   "                timeout = \"1s\""
   "              }"
   "            }"
   ""
   "            resources {"
   "              memory = 1024"
   "              network {"
   "                port \"http\" {}"
   "              }"
   "            }"
   "        }"
   "    }"
   "}"
   ""])

Pieter Breed's avatar
Pieter Breed committed
239 240 241 242 243 244 245
(def freqs {:muladhara "#E63832"
            :svadhistana "#EBAB5C"
            :manipura "#F1D35C"
            :anahata "#71E073"
            :vishudda "#63C8DA"
            :ajna "#5F4ABB"
            :sahasrara "#B251BE"})
Pieter Breed's avatar
Pieter Breed committed
246

247 248 249
(defn slides []
  [
   {:template :title
Pieter Breed's avatar
Pieter Breed committed
250 251
    :freq :muladhara
    :title "Where, oh where can I run my d̶o̶c̶k̶e̶r̶z̶ processes?"
252
    :subtitle "We're all solving the same problems."
253 254
    :img-class "half"
    :img "docker.jpg"}
255

256
   {:template :title
Pieter Breed's avatar
Pieter Breed committed
257
    :freq :muladhara
258
    :title "But why not k8s?"
Pieter Breed's avatar
Pieter Breed committed
259
    :subtitle [:em "A dissenting voice in the job scheduling wilderness. A case for Hashicorp's Nomad."]
260 261
    :img-class "half"
    :img "swarm.png"}
Pieter Breed's avatar
Pieter Breed committed
262

263
   {:template :title
Pieter Breed's avatar
Pieter Breed committed
264
    :freq :muladhara
265
    :title "Job Scheduling Solutions"
Pieter Breed's avatar
Pieter Breed committed
266
    :img-class "half"
267
    :subtitle "A case for Hashicorp's Nomad."
Pieter Breed's avatar
Pieter Breed committed
268 269 270 271 272
    :img "nomad.jpg"
    :content [:ul [:li "If you're thinking of breaking up your monolith."]
                  [:li "If you have too many devs wanting to use too many programming languages."]
                  [:li "If you have w̶e̶i̶r̶d̶ interesting legacy technology you need to isolate."]
                  [:li [:span "If you know for a fact you need " [:em "microservices"] "."]]]}
Pieter Breed's avatar
Pieter Breed committed
273

274
   {:template :2-cols
Pieter Breed's avatar
Pieter Breed committed
275
    :freq :muladhara
Pieter Breed's avatar
Pieter Breed committed
276 277
    :title [:span "A little about me, " [:span {:style {:text-decoration "underline"}} "Pieter Breed"]]
    :cols [[[:div
Pieter Breed's avatar
Pieter Breed committed
278 279 280 281 282 283 284 285 286 287 288 289
             [:h3 "Conference appropriate ID photo"]
             [:img {:src "https://secure.gravatar.com/avatar/58282afa4411f1eba029fa3720f02c98?s=200"
                    :style {:height "200px"}}]
             [:p "Software scientist and engineer by training, systems operator by allegiance and helpful by choice."]
             [:h3 "CV"]
             [:ul [:li "GijimaAST (mine industry, CAD)"]
              [:li "Dimension Data (insurance)"]
              [:li "Cura (risk)"]
              [:li "Allan Gray (Wealth Management)"]
              [:li [:span {:style {:color "green"
                                   :font-weight "bold"}}
                    "Zoona (Payment Gateway, mobile wallets)"]]]]
Pieter Breed's avatar
Pieter Breed committed
290
            [:div [:h5 "Where can you find me online?"]
Pieter Breed's avatar
Pieter Breed committed
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
             [:ul
              [:li [:a {:href "http://pb.co.za"} "pb.co.za"]]
              [:li [:a {:href "https://keybase.io/pieterbreed"} "keybase.io/pieterbreed"]]
              [:li [:a {:href "http://twitter.com/pwab"} "twitter.com/pwab"]]
              [:li [:a {:href "https://github.com/pieterbreed/"} "github.com/pieterbreed"]]
              [:li [:span [:a {:href "https://gitlab.zoona.io/pieter"} "gitlab.zoona.io/pieter"]]]
              [:li [:a {:href "mailto:pieter@pb.co.za"} "pieter@pb.co.za"]]]
             [:h5 "vCard"]
             [:img {:src "QR_Code_Pieter_Breed.png"
                    :style {:height 200
                            :width 200}}]
             [:h5 "May the source be with you..."
              [:ul
               [:li [:a {:href "https://gitlab.zoona.io/pieter/devopsdays-2018"} "Slides source"]]
               [:li [:a {:href "https://gitlab.zoona.io/pieter/kafka-exactly-once/"} "Demo Source Code"]]]]]]]}
   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
307
    :freq :muladhara
308
    :title "What do we do at Zoona?"
Pieter Breed's avatar
Pieter Breed committed
309 310 311 312 313 314
    :content [:div
              [:img {:src "zoona.png"}]
              [:ul
               [:li "To develop products and services that improve the financial health and well-being of 1 billion people."]
               [:li "To empower emerging entrepreneurs to build profitable businesses that create 1 million jobs."]
               [:li "To prove that a purpose-driven business can be a global model for growth and impact."]]]}
Pieter Breed's avatar
Pieter Breed committed
315

316

Pieter Breed's avatar
Pieter Breed committed
317
   {:template :icon-cloud
Pieter Breed's avatar
Pieter Breed committed
318
    :freq :muladhara
Pieter Breed's avatar
Pieter Breed committed
319
    :title "Tools I use regularly"
320 321 322
    :icons technologies}

   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
323
    :freq :svadhistana
Pieter Breed's avatar
Pieter Breed committed
324
    :title "So what's the problem? #1"
325
    :content [:div [:h3 "And out of the blue, a developer happens..."]
Pieter Breed's avatar
Pieter Breed committed
326 327
              [:img {:src "i_are_developer.jpeg"
                     :class "full"}]]}
328
   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
329
    :freq :svadhistana
Pieter Breed's avatar
Pieter Breed committed
330
    :title "So whose problem is it anyway? #2"
331
    :content [:div [:p [:b "The developers blame it on business... "]]
Pieter Breed's avatar
Pieter Breed committed
332
              [:img {:src "building-a-raft.jpg"
Pieter Breed's avatar
Pieter Breed committed
333
                     :style {:width "600px"}}]]}
334 335

   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
336
    :freq :svadhistana
337 338
    :title "So what problems are we solving here? #3"
    :content [:div [:h3 "All business/functional features has these aspects in common:"]
Pieter Breed's avatar
Pieter Breed committed
339 340 341 342 343 344
              [:ul
               [:li "Get this data over here"]
               [:li "Transform it in a specific way"]
               [:li "(Maybe) change the world with it!"]
               [:li "Put it back down over there"]]
              [:img {:src "etl.png"}]]}
345 346

   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
347
    :freq :svadhistana
348 349
    :title "So how many problems are we solving here? #4"
    :content [:div [:h3 "For a computation to happen, it needs..."]
Pieter Breed's avatar
Pieter Breed committed
350 351 352 353 354 355
              [:ul
               [:li "CPU n*" [:code "Ghz"]]
               [:li "RAM " [:code "Gbyte"]]
               [:li "Network Bandwidth " [:code "Gbits/sec"]]
               [:li "Ports, eg " [:code "8080"]]]
              [:img {:src "turing.gif"}]
Pieter Breed's avatar
Pieter Breed committed
356
              [:p [:a {:href "https://en.wikipedia.org/wiki/Turing_machine"} "Turing machine"]]
Pieter Breed's avatar
Pieter Breed committed
357 358 359 360 361 362 363 364
              [:h3 "What else? The things people usually forget about..."]
              [:ul
               [:li "What credentials must it use to access all of this data?"]
               [:li "What are the availability requirements?"]
               [:li "What is the expected volume of data?"]
               [:li "How should the operations team know it's even ON?"]
               [:li "How should the operations team know it's working?"]
               [:li "Do you want me to call you when it stops?"]]]}
Pieter Breed's avatar
Pieter Breed committed
365

366
   {:template :title
Pieter Breed's avatar
Pieter Breed committed
367
    :freq     :svadhistana
368
    :title "Where can I run my d̶o̶c̶k̶e̶r̶z̶ processes?"
Pieter Breed's avatar
Pieter Breed committed
369
    :subtitle [:span
Pieter Breed's avatar
Pieter Breed committed
370 371 372 373
               "We're all solving the same problems, but this time with "
               [:a {:href "https://12factor.net"} "12 Factor Apps"]
               " and "
               [:a {:href "https://www.nomadproject.io/"} "Hashicorp's nomad"]]
374 375 376
    :img-class "half"
    :img "docker.jpg"}

377
   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
378
    :freq     :manipura
379
    :title [:span "Is " [:em "something"] " better than nothing, at least?"]
380
    :content [:div [:h3 "If you hand-deployed every process (with fancy bash)"]
Pieter Breed's avatar
Pieter Breed committed
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
              [:ul [:li "Some machines sit around idling all day long"]
               [:li "Some machines overwork"]
               [:li [:b "Bad resource allocation"]]]
              [:ul [:li "Do I put the IAM token on the ec2?"]
               [:li "The set of all permissions required by all processes on the box"]
               [:li "Who must get ssh access to the box?"]
               [:li "Who must not get ssh access to the box?"]
               [:li [:b "Inconsistent secrets management"]]]
              [:img {:src "dude-config.jpg"
                     :style {:width "450px"
                             :float "right"}}]
              [:ul [:li "What file contains that config setting again?"]
               [:li "Why does it work in dev but not in prod?"]
               [:li "What version is running in UAT?"]
               [:li "Where's the log file? What machine is that?"]
               [:li "How do you increase the log-level?"]
               [:li "How do I shut up " [:code "org.apache.http"] "?"]
               [:li [:b "Inconsistent configuration"]]]]}
Pieter Breed's avatar
Pieter Breed committed
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458

   {:template :newspaper
    :freq :manipura
    :title "The way nomad sees the domain #1"
    :content [:div [:h3 [:a {:href "https://en.wikipedia.org/wiki/Knapsack_problem" } "Knap-sack problem"]]
              [:p "The knapsack problem or rucksack problem is a problem in combinatorial optimization: Given a set of items, each with a weight and a value, determine the number of each item to include in a collection so that the total weight is less than or equal to a given limit and the total value is as large as possible."]
              [:img {:src "knapsack_problem.png"
                     :width "500px"}]]}
   {:template :newspaper
    :freq :manipura
    :title "The way nomad sees the domain #2"
    :content [:div [:h3 [:a {:href "https://en.wikipedia.org/wiki/Bin_packing_problem"} "Binpacking problem"]]
              [:p "In the bin packing problem, objects of different volumes must be packed into a finite number of bins or containers each of volume V in a way that minimizes the number of bins used. In computational complexity theory, it is a combinatorial NP-hard problem."]
              [:img {:src "binpack_2.png"
                     :width "750px"}]]}


   {:template :newspaper
    :freq :manipura
    :title "The way nomad sees the domain #3"
    :content [:div [:h3 [:a {:href "https://en.wikipedia.org/wiki/Raft_(computer_science)"} "Raft Consensus Algorithm"]]
              [:p "Raft is a consensus algorithm designed as an alternative to Paxos. It was meant to be more understandable than Paxos by means of separation of logic, but it is also formally proven safe and offers some additional features"]
              [:img {:src "raft.png"
                     :width "500px"}]
              [:h3 [:span "Looks like a key-value store, but is "
                    [:span {:style {:text-decoration "underline"}} "very consistent"]
                    " accross a cluster"]]
              [:img {:src "kv-store.jpg"
                     :width "200px"}]]}

   {:template :2-cols
    :freq :anahata
    :title "The state machine, producing new state..."
    :subtitle "λ S 𝑥 → Sʹ"
    :cols [[[:div [:h2 "COMBINE"]
             [:h4 "Current state: S"]
             [:ul [:li "What processes are running"]
              [:li "What ports are they consuming"]
              [:li "Are they healthy?"]
              [:li "How many nodes in the cluster"]
              [:li "How much CPU, RAM and network available?"]]]
            [:div [:h2 "WITH"]
             [:h4 "Changes in state: 𝑥"]
             [:img {:src "gremlin.webp"
                    :width "150px"
                    :style {:float "right"}}]
             [:ul [:li "Processes fail"]
              [:li "Nodes are drained, become unhealthy"]
              [:li "New nodes are added for extra capacity"]
              [:li "shit happens"]]
             [:h4 "The Other kind of change in state, when someone pulls a lever: 𝑥"]
             [:img {:src "lever.gif"
                    :width "200px"
                    :style {:float "right"}}]
             [:ul [:li "RUN process"]
              [:li "PLAN process"]
              [:li "STOP process"]
              [:li "DISPATCH job"]
              [:li "SCHEDULE job"]]]]]}

459
   {:template :title
Pieter Breed's avatar
Pieter Breed committed
460 461 462 463 464
    :freq     :anahata
    :title [:span "What does a minimal "
                  [:a {:href "https://www.nomadproject.io/"}
                      "nomad"]
                  " cluster look like?"]
465 466 467
    :img "nomad-nodes.png"}

   {:template :2-cols
Pieter Breed's avatar
Pieter Breed committed
468 469 470 471 472
    :freq     :anahata
    :title [:span "Two kinds of "
                  [:a {:href "https://www.nomadproject.io/"}
                      "nomad"]
                  " nodes"]
473 474
    :subtitle "This is what your ansible/chef sets up for you on ec2's"
    :cols [[[:div [:h3 "Masters"]
Pieter Breed's avatar
Pieter Breed committed
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
             [:ul
              [:li [:b "Analyze"]]
              [:li [:b "Synchronize"]]
              [:li [:b "Evaluate"]]
              [:li [:b "Allocate"]]]
             [:ul [:li "Few in number (At least 3)"]
              [:li "Need few resources"]
              [:li "Need to be careful with provisioning"]]
             [:ul [:li [:code "vault"] " server (secrets)"]
              [:li [:code "consul"] " master nodes (config & service-discovery)"]
              [:li [:code "nomad"] " master nodes (job scheduling algorithm)"]]
             [:h3 "Example Config"]
             [:p [:code "/etc/default/nomad"] " contains one environment variable " [:code "VAULT_TOKEN"]]
             [:pre {:style {:font-size "12"
                            :margin-right "20px"
                            :overflow "scroll"}}
              (str/join "\n"
                        ["$ ls"
                         "config.hcl  nomad.d"
                         ""
                         "$ cat config.hcl"
                         "enable_syslog = true"
                         ""
                         "server {"
                         "  enabled          = true"
                         "  bootstrap_expect = 1"
                         "}"
                         ""
                         "$ cat nomad.d/vault.hcl"
                         "vault {"
                         "   enabled = true"
                         "   create_from_role = \"nomad-cluster\""
                         "   address = \"http://active.vault.service.consul:8200\""
                         "}"
                         ""
                         "$ cat /lib/systemd/system/nomad.service"
                         "[Unit]"
                         "Description=nomad"
                         "After=consul.service"
                         ""
                         "[Service]"
                         "EnvironmentFile=/etc/default/nomad"
                         "ExecStart=/usr/local/bin/nomad agent -config=/etc/nomad/config.hcl -config=/etc/nomad/nomad.d/ -data-dir=/var/lib/nomad"
                         "ExecReload=/bin/kill -HUP $MAINPID"
                         "Restart=on-failure"
                         ""
                         "[Install]"
                         "WantedBy=multi-user.target"])]]
523 524

            [:div [:h3 "Worker"]
Pieter Breed's avatar
Pieter Breed committed
525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572
             [:ul [:li [:b "Execute"]]]
             [:ul [:li "Elastic cluster size, grow to have as many as demand requires"]
              [:li "Bigger nodes individually, more RAM, more CPU, more network bandwidth"]
              [:li "Un-specialized virtual machine images"]]
             [:ul [:li [:code "consul"] " (service registration)"]
              [:li [:code "nomad"] " worker nodes (docker, jvm, exec)"]]
             [:h3 "Example Config"]
             [:p [:code "/etc/default/nomad"] " is completely empty (so far)."]
             [:pre {:style {:font-size "12"
                            :overflow "scroll"}}
              (str/join "\n"
                        ["$ pwd"
                         "/etc/nomad"
                         "" ""
                         "$ cat config.hcl"
                         "enable_syslog = true"
                         ""
                         "client {"
                         "    enabled = true"
                         "    options {"
                         "        \"driver.raw_exec.enable\" = \"1\""
                         "    }"
                         "}"
                         "" ""
                         "$ ls"
                         "config.hcl  nomad.d"
                         "" ""
                         "$ cat nomad.d/vault.hcl"
                         "vault {"
                         "   enabled = true"
                         "   create_from_role = \"nomad-cluster\""
                         "   address = \"http://active.vault.service.consul:8200\""
                         "}"
                         "" ""
                         "$ cat /lib/systemd/system/nomad.service"
                         "[Unit]"
                         "Description=nomad"
                         "After=consul.service"
                         ""
                         "[Service]"
                         "EnvironmentFile=/etc/default/nomad"
                         "ExecStart=/usr/local/bin/nomad agent -config=/etc/nomad/config.hcl -config=/etc/nomad/nomad.d/ -data-dir=/var/lib/nomad"
                         "ExecReload=/bin/kill -HUP $MAINPID"
                         "Restart=on-failure"
                         "LimitNOFILE=128000"
                         ""
                         "[Install]"
                         "WantedBy=multi-user.target"])]]]]}
573
   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
574 575 576 577 578 579
    :freq :vishudda
    :title "Minimum Complete Problem"
    :subtitle "Word and Letter Frequency Analysis"
    :content [:div [:ol [:li "Download a text file, and upload the lines one-by-one to kafka. (batch process)"]
                        [:li "Whenever lines of text are received from kafka, do letter and word frequency analysis over all of them and send the results on. (system job)"]
                        [:li "Receive letter and word frequency analysis and save them to the database. (service)"]]]}
580

581 582

   {:template :title
Pieter Breed's avatar
Pieter Breed committed
583
    :freq :vishudda
Pieter Breed's avatar
Pieter Breed committed
584 585
    :title "Batch jobs #1"
    :subtitle "Old-school terminology"
Pieter Breed's avatar
Pieter Breed committed
586 587 588
    :img-class "half"
    :img "batches.png"
    :content [:p "A batch job is a computer program or set of programs processed in batch mode. This means that a sequence of commands to be executed by the operating system is listed in a file (often called a batch file, command file, or shell script) and submitted for execution as a single unit."]}
589 590

   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
591
    :freq :vishudda
592 593
    :title "Batch jobs #2"
    :subtitle [:span "Processes that " [:em "start"] " often."]
Pieter Breed's avatar
Pieter Breed committed
594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657
    :content [:div
                  [:img {:src "batch.png"
                         :width "250px"
                         :style {:float "right"}}]
                  [:ul
                   [:li "End of day"]
                   [:li "ETL"]
                   [:li "Reports"]
                   [:li "Sometimes cyclical, sometimes lever-driven"]
                   [:li "λ When they take parameters, they're called " [:em "server-less"]]]
                  [:h4 "This one uploads a text file line-by-line from a URL to a kafka topic."]
                  [:pre {:style {:overflow "scroll"
                                 :height "200px"
                                 :font-size "12"}}
                        (str/join "\n"
                          ["job \"keo-file-uploader\" {"
                           "  datacenters = [\"dc1\"]"
                           "  type = \"batch\""
                           ""
                           "  parameterized {"
                           "    payload = \"optional\""
                           "  }"
                           ""
                           "  group \"keo-file-uploader\" {"
                           ""
                           "    task \"keo-file-uploader\" {"
                           "      driver = \"docker\""
                           ""
                           "      config {"
                           "        image = \"docker-registry.zoona.io/pieter/kafka-exactly-once/runtime:master\""
                           ""
                           "        volumes = ["
                           "          \"local/config.json:/opt/config.json\""
                           "        ]"
                           ""
                           "        args = ["
                           "          \"-jar\","
                           "          \"/opt/app.jar\","
                           "          \"--gelf-logs\","
                           "          \"--config-file\", \"/opt/config.json\","
                           "          \"-u\""
                           "          ]"
                           "      }"
                           "      dispatch_payload {"
                           "        file = \"config.json\""
                           "      }"
                           ""
                           "      env {"
                           "        LOG_LEVEL = \"debug\""
                           "        BOOTSTRAP_SERVERS = \"kafka-ops.service.consul:9092\""
                           "        UPLOAD_TOPIC = \"raw-lines\""
                           "      }"
                           "    }"
                           "  }"
                           "}"])]
                  [:div [:h4 "Kicking it off"]]
                  [:pre {:style {:overflow "scroll"
                                 :font-size "12"}}
                        (str/join "\n"
                             ["$ cat <<EOF | nomad job dispatch keo-file-uploader -"
                              "{"
                              "  \"SOURCE_URL\": \"https://s3-eu-west-1.amazonaws.com/centaur.zoona.network-datalake/cleanbooks/A_Commentary_to_Kants_Critique_of_Pure_Reason.txt\""
                              "}"
                              "EOF"])]]}
658 659

   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
660
    :freq :vishudda
661 662 663
    :title "Batch jobs #3"
    :subtitle "Every 15 minutes"
    :content [:div
Pieter Breed's avatar
Pieter Breed committed
664 665 666 667 668 669 670 671 672
              [:pre {:style {:overflow "scroll"}}
               (str/join "\n"
                         ["type = \"batch\""
                          "periodic {"
                          "    cron = \"*/15 * * * *\""
                          "    prohibit_overlap = true    "
                          "}"])]
              [:img {:style {}
                     :src "cronjob.jpeg"}]]}
673 674

   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
675
    :freq :vishudda
676 677
    :title [:span [:em "System"] " jobs #1"]
    :subtitle [:span "For when you want one process/sub-system instance for every “physical”/worker node"]
Pieter Breed's avatar
Pieter Breed committed
678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694
    :content [:div [:pre {:style {:display "inline-block"
                                  :float "right"}}
                        (str/join "\n"
                          ["; the map in map-reduce"
                           "(->letter-frequencies \"word\")"
                           "{\\w 1, \\o 1, \\r 1, \\d 1}"
                           ""
                           "(->letter-frequencies \"word ward\")"
                           "{\\w 2, \\o 1, \\r 2, \\d 2, \\a 1}"
                           "" ""
                           "(->word-frequencies \"word\")"
                           "{\"word\" 1}"
                           ""
                           "(->word-frequencies \"word ward weird\")"
                           "{\"word\" 1, \"ward\" 1, \"weird\" 1}"])]
                   [:ul
                    [:li "Long-running, always-on"]
Pieter Breed's avatar
Pieter Breed committed
695 696 697 698 699 700 701 702 703 704 705
                    [:li "Re-started by the scheduler when they crash"]
                    [:li "Useful for infrastructure integrations (ELB entrypoint to load-balancer process)"]
                    [:li "Useful when some of your processes can consume an entire worker-node"]
                    [:li [:span {:style {:text-decoration "underline"}} "Scales with infrastructure"]]]
              [:ul [:li "logging-sidecar (fileboat/logstash)"]
               [:li "traefik"]
               [:li "telemetry agent"]]
              [:h3 "Job file for line analyzer"]
              [:pre {:style {:overflow "scroll"
                             :height   "250px"}}
               (str/join "\n" keo-line-analyzer-nomad-job)]]}
Pieter Breed's avatar
Pieter Breed committed
706 707

   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
708
    :freq :vishudda
Pieter Breed's avatar
Pieter Breed committed
709 710
    :title [:span [:em "System"] " jobs #2"]
    :content [:div [:h3 "What is the current status?"]
Pieter Breed's avatar
Pieter Breed committed
711 712 713 714 715
              [:pre {:style {:overflow "scroll"}}
               (str/join "\n" nomad-status-keo-line-analyzer)]
              [:h3 "nomad node-status"]
              [:pre {:style {:overflow "scroll"}}
               (str/join "\n" nomad-node-status)]]}
Pieter Breed's avatar
Pieter Breed committed
716 717

   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
718
    :freq :vishudda
Pieter Breed's avatar
Pieter Breed committed
719 720
    :title "Service jobs #1"
    :subtitle "For when you need independently scalable software services."
Pieter Breed's avatar
Pieter Breed committed
721 722 723 724 725 726 727 728
    :content [:div [:pre {:style {:display "inline-block"
                                  :float "right"}}
                         (str/join "\n"
                           [
                            "{:words {\"word\" 3, \"ward\" 2, \"weird\" 1}, "
                            " :letters {\\w 6, \\o 3, \\r 6, "
                            "           \\d 6, \\a 2, \\e 1, \\i 1}}"])]
                   [:ul [:li "Long-running, always-on"]
Pieter Breed's avatar
Pieter Breed committed
729 730 731
                    [:li "Restarted by the scheduler when they crash"]
                    [:li "Useful for business code."]
                    [:li [:span {:style {:text-decoration "underline"}} "Scales with business load"]]]
Pieter Breed's avatar
Pieter Breed committed
732 733 734
              [:img {:src "reduce.png"
                     :style {:float "right"
                             :clear "both"}}]
Pieter Breed's avatar
Pieter Breed committed
735 736 737
              [:h3 "Examples:"]
              [:ul [:li "Kafka consumers"];]]]}
               [:li "REST services"]]]}
Pieter Breed's avatar
Pieter Breed committed
738 739

   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
740
    :freq :vishudda
Pieter Breed's avatar
Pieter Breed committed
741
    :title "Service jobs #2"
Pieter Breed's avatar
Pieter Breed committed
742
    :content [:div [:h3 "analysis result persister job file"]
Pieter Breed's avatar
Pieter Breed committed
743 744 745
              [:pre {:style {:overflow "scroll"
                             :height "250px"}}
               (str/join "\n" keo-analysis-persister-job-file)]
Pieter Breed's avatar
Pieter Breed committed
746
              [:h3 "launching/running the job"]
Pieter Breed's avatar
Pieter Breed committed
747 748 749
              [:pre {:style {:overflow "scroll"
                             :height "150px"}}
               (str/join "\n" nomad-run-keo-analysis-persister)]]}
Pieter Breed's avatar
Pieter Breed committed
750 751

   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
752
    :freq :ajna
Pieter Breed's avatar
Pieter Breed committed
753 754
    :title "Cool things #1"
    :content [:div [:h3 "Service discovery (integration with " [:code "consul"] ")"]
Pieter Breed's avatar
Pieter Breed committed
755 756 757
              [:pre {:style {:overflow "scroll"}
                     :height "200px"}
               (str/join "\n" service-discovery)]]}
Pieter Breed's avatar
Pieter Breed committed
758 759

   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
760
    :freq :ajna
Pieter Breed's avatar
Pieter Breed committed
761 762 763
    :title "Cool things #2"
    :subtitle [:spna "Integration with " [:code "vault"]]
    :content [:div [:p "Using a templating mechanism to load AWS IAM credentials into env vars"]
Pieter Breed's avatar
Pieter Breed committed
764 765 766 767
              [:pre {:style {:overflow "scroll"}}
               (str/join "\n" secret-with-vault-and-templates)]
              [:ul [:li "Each process only has the credentials it requires"]
               [:li "Service-specific authorization roles"]]]}
Pieter Breed's avatar
Pieter Breed committed
768
   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
769
    :freq :ajna
Pieter Breed's avatar
Pieter Breed committed
770 771 772
    :title "Cool things #3"
    :subtitle "Access to interesting runtime information"
    :content [:div [:pre {:style {:overflow "scroll"}}
Pieter Breed's avatar
Pieter Breed committed
773 774 775 776 777 778 779 780 781 782
                    (str/join "\n" runtime-env-variables)]
              [:table [:tr [:th "VARIABLE"] [:th "VALUE"]]
               [:tr [:td [:code "GELF_HOST"]]
                [:td [:code "ip-10-10-1-117"]]]
               [:tr [:td [:code "GELF_FACILITY"]]
                [:td [:code "keo-analysis-persister:78bb4b5f-332b-7e2c-c4c5-dd6f78a2504f"]]]
               [:tr [:td [:code "CONSUMER_GROUP_ID"]]
                [:td [:code "s33d_keo-analysis-persister"]]]
               [:tr [:td [:code "TRANSACTIONAL_ID"]]
                [:td [:code "s33d_keo-analysis-persister:ip-10-10-1-117"]]]]]}
Pieter Breed's avatar
Pieter Breed committed
783
   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
784
    :freq :ajna
Pieter Breed's avatar
Pieter Breed committed
785 786 787
    :title "Cool things #4"
    :subtitle "Programming the environment with tags"
    :content [:div [:h3 "Prometheus integration"]
Pieter Breed's avatar
Pieter Breed committed
788 789 790 791
              [:pre "tags = [\"prometheus-service\"]"]
              [:dev [:img {:src "prometheus-integration.png"
                           :style {:clear "both"
                                   :width "800px"}}]]]}
Pieter Breed's avatar
Pieter Breed committed
792 793

   {:template :newspaper
Pieter Breed's avatar
Pieter Breed committed
794
    :freq :ajna
Pieter Breed's avatar
Pieter Breed committed
795 796 797
    :title "Cool things #4"
    :subtitle "Programming the environment with tags #2"
    :content [:div [:h3 "Traefik load-balancer uses tags to find services"]
Pieter Breed's avatar
Pieter Breed committed
798 799
              [:code "$ curl http://keo-analysis-persister.zoona-internal/metrics | head -n 5"]
              [:pre (str/join "\n" curl-via-load-balancer)]]}
Pieter Breed's avatar
Pieter Breed committed
800 801

   {:template :2-cols
Pieter Breed's avatar
Pieter Breed committed
802
    :freq :ajna
Pieter Breed's avatar
Pieter Breed committed
803 804 805
    :title "Cool things #5"
    :subtitle "Resource Management"
    :cols [[[:div [:h3 "CPU stats"]
Pieter Breed's avatar
Pieter Breed committed
806 807
             [:img {:src "cpu_stats.png"
                    :width "500px"}]]
Pieter Breed's avatar
Pieter Breed committed
808
            [:div  [:h3 "RAM stats"]
Pieter Breed's avatar
Pieter Breed committed
809 810
             [:img {:src "ram_stats.png"
                    :width "500px"}]]]]}
Pieter Breed's avatar
Pieter Breed committed
811

Pieter Breed's avatar
Pieter Breed committed
812 813 814 815 816 817 818 819
   {:template :newspaper
    :freq :sahasrara
    :title "Recap:"
    :content [:div [:ul
                    [:li [:span "You need a " [:b "job scheduler"] " when the number of processes you operate starts to grow."]]
                    [:li [:span "It's possible to put a lot of your cross-cutting concerns (" [:b "non-functional requirements"] ") into the fabric."]]
                    [:li "Simple > Complicated > Complex"]]]}

Pieter Breed's avatar
Pieter Breed committed
820
   {:template :title
Pieter Breed's avatar
Pieter Breed committed
821
    :freq :sahasrara
Pieter Breed's avatar
Pieter Breed committed
822
    :title "Questions & Answers?"
Pieter Breed's avatar
Pieter Breed committed
823
    :img "ops-problem-now.jpg"}])