20:20 Vision in 2020

08 January 2020

A new year brings New Years’ Resolutions. I’ve lost track of the number of social media posts I’ve seen about this.

What I never see are posts describing how people will achieve their resolutions. After all, 90% of us stop going to the gym within 90 days. Sheer willpower doesn’t work.

I’m devoting most of this post to describe how I will achieve my goals.

My process for making 2020 goals has 6 parts:

  1. Brainstorm goal ideas. Use my 2019 retrospective as inspiration. Write everything down.
  2. Use these ideas to identify priorities. Write these down. This step frames the year.
  3. Use priorities to rank goals. Write down the 6 most important. Discard the rest.
  4. Make goals SMART. Write them down.
  5. Think creatively about different ways to use habits and systems. Ask others for suggestions.
  6. Pick a habit-based approach to achieve each goal. Add this to existing systems.
  7. Identify a way to catch myself when I struggle, as early as possible. Add this to systems as well.

Part 1: Brainstorming

Here’s what I came up with:

  • Run a 10K
  • Bike from Seattle to Portland
  • Do 50 pushups in a row
  • Do a 4-day, 50-mile hike
  • Publish 15 blog posts before July 1
  • Build a relationship with 10 people in my extended family
  • Grow closer to 6 friends
  • Develop 60 new professional connections
  • Teach 3 technologies to 30+ colleagues
  • Learn a popular programming language: Javascript, Go, or Java
  • Learn 4 popular frameworks: Tensorflow, Helm, Keras, and Serverless.
  • Gain proficiency in a software engineering ‘topic’ (e.g. infrastructure automation, rapid pipeline development, or cost optimization)
  • Learn more about genomics. A lot more
  • Catch up with the current state-of-the-art in machine learning
  • Learn a new instrument

(I’m leaving out anything involving my partner, politics, or work goals, for privacy reasons)

Part 2: Priorities

I spent a week thinking about goals and priorities. I wrote them on scraps of paper, and spent a day ordering them by asking 2 questions:

  • “What if I accomplished goal n but not n+1? Is that the result I want?”
  • “What happens if I switch the order? Is that better?”

That’s right, folks. I used bubblesort.

The steps we take change the path of our life. I sorted and re-sorted until I had a good result:

  1. Health
  2. Relationship
  3. Career
  4. Family & friends
  5. Work
  6. Music

I spend 96 hours a week working and sleeping. I’ll allocate the other 72 hours via priorities.

Part 3: Ranking

“Life is what happens while you’re making other plans” - John Lennon

A huge to-do list is a wish list. Unlike my 25-year-old self, I’m painfully aware of the cost of context switching.

I know how well I don’t multitask, and it takes 18-254 days to form a new habit. So, I will limit myself to 6 goals before July 1st:

  1. Do 50 pushups in a row
  2. Run a 10K
  3. Develop 60 new professional connections this year
  4. Publish 15 blog posts before July 1
  5. Learn 4 popular frameworks
  6. Grow closer to 6 friends

The rest I am ignoring deferring.


Parts 4 + 5: Brainstorm Habits and Systems

We fall to the level of our systems.

There are science-based strategies to achieve what you set out to do:

  1. Clarify and honor your values
  2. Frame goals and your life in positive terms
  3. Change your environment to make it easier (e.g. remove distractions, walk, make it easier to do tasks)
  4. Be prepared with if-then strategies
  5. Use a gradual approach
  6. Be kind to yourself, even during setbacks

I will construct a system to reach goals:

  1. Identify why this is important. Think of personal values
  2. Break the goal down into incremental achievements, and then further into micro tasks
  3. Figure out a way to make those micro tasks easy
  4. Find a way to build those steps into existing habits+systems
  5. Do it
  6. Reward myself
  7. Reflect on how things went. Adjust and keep going for the next incremental achievement

I’ll call this the Seven Ascending Steps (SAS).

Publish 15 Blog Posts Before 7/1

I’m not a natural or experienced writer. I get frustrated, distracted, and swear.

I read a book on writing well, and struggled with the first 3 bits of advice.

Writing is mentally daunting, and yet I’m committing to write 15 posts before July 1. It is good to push past your comfort zones. Let’s break this down…

I am here for 147 days before July 1, so I need to complete a post every 9 days. I’m going to reduce that to once every 8 days plus 27 days’ buffer.

I already have ideas for posts; the effort is writing and editing. So, I broke up my writing process into micro tasks. I’ll spread them across 8 days, because consistency matters:

Day Tasks
1 Write substantive points on paper
2 Make a blog post file with tags & title
Make an outline from points
3 Write intro
Add relevant research + links to the post
4 Write half the post body
5 Write the second half of the post body
6 Write conclusion
Find images and add them
7 Print out, and edit with a pen
8 Publish
Reflect, and adjust for the next post.

None of these steps takes more than 30 minutes, so this will take 3.5 hours a week.

To accomplish these steps, I use a spreadsheet of micro tasks. Breaking a task into tiny pieces is the best way I know to do something daunting. I also put a comfy chair in the office, because changing our environment matters.

I have a system to get things done: Todoist. I’ve created a daily reminder to write, with a link to the micro tasks.

I’m using systems (to-do lists) I already have, and techniques (micro-tasks) I already know will work.

Finally, I’m going to use incentives. For each finished post, I will reward myself:

  • Buy a box of the pens I like
  • Spend 30 minutes going through old papers
  • Spend 30 minutes doodling
  • Spend $10 at the local bookstore

I’m choosing rewards that are topical, cheap, and that I already want. I’m granting permission to do what I hold back on, framing them as an earned reward.

This is working well. The last four posts used this approach.

50 Pushups

I want to do 50 pushups in a row.

It is an indicator of how often I’m working out, and therefore my health. This way I can take care of people, and do work that matters. Oh, and it’s good for brain function.

Right now I can do 15 pushups. I need to gain the strength to do 35 more. There are 169 days (24 weeks) left, so I need to gain the strength to do 1.5 more pushups each week. I’ll round up and do 2 more pushups each week, reaching the goal after 18 weeks. That’s mid-May, well before the deadline, so I have a comfortable buffer in case I slip.

I’ve read that it’s important to rest when strength training. I made reminders to work out 3 times a week. I’m going to adjust workouts to build in intensity every two weeks.

My workouts take 30 minutes, so this is a 1.5 hour commitment per week.

I’ll associate some rewards with achievements (‘30 in a row!’, ‘40 in a row!’):

  • Go climbing with a friend
  • Take a yoga class
  • Go on a snowshoeing hike
  • Learn to climb trees
  • Take an introductory parkour class

I created biweekly ‘validation’ tasks, to verify I’ve gained the endurance I am aiming for. I’ll adjust if needed.

This seems realistic. It uses SAS-y steps, and builds on systems I already have.

Learn frameworks

The final goal: learn 4 popular frameworks relevant to my career. I’ve chosen Tensorflow, Keras, Helm, and Serverless.

The lifespan of languages and frameworks is limited. I need to learn constantly to stay relevant in my profession. Thankfully, learning plays to my sense of curiosity. I was the kid who was always building with Legos. Learning has a similar feeling.

I learn frameworks in several steps. I want to build on previous steps, so I do this:

  1. Use Markdown files to document every command I run, why I did it, and helpful links.
  2. Use a container with persisted state, to start where I left off.
  3. 1-hour pomodoros work best for me. I shut off the phone, turn off music, and close all unrelated applications.

I’m allocating 35 days per framework, plus 7 days’ buffer:

Days Hours Tasks
1     1 Install & “hello world”
2-3    2 Set up with a basic dataset/application
4-8    5 Play around with questions/curiosity to figure out things work. How do the components of the framework interact? What are the design decisions?
9-14   6 Learn popular uses for the framework. What are common themes in its use? How does it compare with similar frameworks I already know?
15-30     15 Use a more complex dataset/application to learn. Can it do something weird, when I want it to? Why or why not? What patterns am I finding?
31-35    5 Write about what I’ve learned. Reflect, and adjust

I will work on this for an hour each day, or I’ll allocate a day to a big step. The time commitment is 8 hours a week, making this the goal with the biggest time commitment.

I’m productive immediately after work, before my commute. I’ll find a cozy spot and get to business.

I’ve made to-do reminders, micro-tasks, and a biweekly task to reflect & adjust the process. Yay neuroplasticity!

Oh, and of course we need rewards:

  • Get a nerdy t-shirt
  • Get an Etsy decal for my phone
  • Spend an hour organizing a computer (yep, I’m that nerd)
  • Spend an afternoon on a side project

Once again this uses SAS-y steps, and fits well with existing systems I have.

Part 6: Safety Net

Building habits and practices is an unreliable process. Sometimes everything works the first time. More often, I have to experiment and adjust.

So, I use ‘safety net’ reminders. Every two weeks I will ask myself: what has been working, what hasn’t, and what should change? Reflective practice is an effective way for me to incrementally and reliably improve.


Change is challenging, especially for a creature of habit like me. And yet, I value growth periods…in hindsight.

I try to improve myself using habit formation, simple steps, reducing the mental load per task, working on a regular basis, and pausing to adjust.

How will you achieve your goals?


Kubernetes Snippets

07 January 2020

I do a bunch of work with Kubernetes (‘K8S’), building tools so researchers can do repeatable, scalable research using containers. To do so I had to figure out a bunch of useful commands for manipulating pods (containers), including deploying them, debugging, and host management. I started with the K8S cheatsheet and went from there.

We’ll use an example application that runs using web servers, database servers, and has a simple logging and monitoring setup.

  • VMs (nodes) with names of host1, host2, host3, etc.
  • A ReplicaSet of web servers, named ‘web’
  • A StatefulSet of database servers, named ‘db’
  • A DaemonSet of logging pods, named ‘logging’
  • A CronJob pod, ‘run-integrity-checks’ that runs logic checks against the K8S master node and emails them to the IT administrators.



Let’s work with configmaps, ‘web-config’

List all configmaps

kutectl get configmap

Find one configmap

kutectl get configmap | grep web

See the details about a configmap

kubectl describe configmap web-config

Create a configmap from a file

kubectl create configmap web-config --from-file=/home/dnambi/deploy/web-configs/config.json

Create a configmap from a folder

kubectl create configmap web-config --from-file=/home/dnambi/deploy/web-configs/

Delete a configmap

kubectl delete configmap web-config


Let’s play with a secret, db-secret

Create secrets from a file

kubectl create secret generic db-secret --from-file=./username.txt --from-file=./password.txt

Create secrets from key-value pairs

kubectl create secret generic db-secret --from-literal=username='my-app' --from-literal=password='39528$vdg7Jb'

List all secrets

kubectl get secrets

Find all secrets with db in the name

kubectl get secrets | grep db

See the details about a secret

kubectl get secret db-secret -o yaml

Delete a secret

kubectl delete secret db-secret


Docker Images

kubectl create secret docker-registry regcred 
   --docker-password=<your-pword> --docker-email=<your-email>


Find pod with one configmap DEVNFIXME Find pod that uses a service DEVNFIXME

List all pods

kubectl get pods

Find a pod named ‘logging’

kubectl get pods | grep logging

Find a pod that uses a particular configmap, ‘nginx-config’

kubectl get pods -o json 
| jq '.items[].spec.containers[].env[]?.valueFrom.ConfigMapKeyRef.name' 
| grep nginx | sort | uniq

Find all pods used for a particular service, ‘web-https’

kubectl get pods -l app=web-https

See the details about a pod, web-1

kubectl describe pods web-1

Delete a pod, web-2

kubectl delete pods web-2


See all services

kubectl get svc

Find one service, ‘web-https’

kubectl get svc | grep web

Find out the info about one service

kubectl describe svc web-https

Delete a service, ‘web-https’

kubectl delete svc web-https

Server Maintenance

See the details about a VM (‘node’, in K8S parlance).

List all nodes

kubectl get nodes

Find one node, ‘smallhost’

kubectl get nodes | grep smallhost

Find the details about one node, ‘smallhost’

kubectl describe nodes smallhost

Isolate a node for maintenance, ‘oldnode’

kubectl cordon oldnode
kubectl drain oldnode --ignore-daemonsets

Put a cordoned node back into service

kubectl uncordon oldnode

No piece of code is ever done. I’ll add more snippets over time. Happy coding!