Kubernetes: How to Use Affinity

Affinity is a great feature in Kubernetes to assign pods to nodes based on labels. In my case, I have a hybrid Kubernetes cluster with half nodes are of X86 architecture and other half of ARM architecture, and I need to deploy the X86 only containers to the X86 nodes. Of course I can build multi-arch containers to get rid of this restriction too, but let’s see how Affinity works first.

All the nodes have labels of their architecture, and those labels can be printed out like this

# the key in jsonpath is to escape the dot "." and slash "/" in the key names, in this example, kubernetes.io/arch
k get node -o=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.kubernetes\.io\/arch}{"\n"}{end}'
kmaster	arm
knode1	arm
knode2	arm
knode3	amd64
knode4	amd64
knode5	amd64

To deploy a Pod or Deployment, StatefulSet, etc, the Affinity should be put into the pod’s spec, eg.

# this is only a partial example of a deployment with affinity
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  template:
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                - key: kubernetes.io/arch
                  operator: In
                  values:
                    - amd64

The Deployment above will be scheduled onto a node running on X86 architecture.

Note: requiredDuringSchedulingIgnoredDuringExecution is a hard requirement and if it’s not met the pod won’t be deployed. If it’s a soft requirement, preferredDuringSchedulingIgnoredDuringExecution should be used instead.

🙂

Atom Won’t Start in OS X

Atom.io is still my favorite editor

I’ve updated Atom.io editor on MacBook Pro from 1.52 to 1.54 earlier today. Strange thing is that after the update Atom got stuck when starting up — only menu is shown and can’t open any docs.

By my experience on Linux, when something doesn’t work I run in in a terminal and see what error message it would say. So I try the same on OS X, which is a distant relative to Linux but a relative nonetheless. I started Atom in a terminal by entering:

/Applications/Atom.app/Contents/MacOS/Atom

To my surprise Atom started successfully without doing anything else. Also later it still worked well when opened from GUI. I couldn’t explain it, but it does prove to be a fix.

🙂

Kubernetes and GitOps with Flux CD V2.0

GitOps could be the next big thing in cloud automation so I’d give it a try with my in house hybrid Kubernetes cluster. I was recommended to try Flux CD and there’s a good reference project initiated by my colleage: k8s-gitops.

However, in order to fully understand how to use Flux CD, I chose to start from scratch. Following the official instructions it didn’t take me long to fully enable GitOps on my cluster. Here’s how I did it on my laptop running Ubuntu:

First, create a GitHub PAT(Personal Access Token) with full repository permissions. Details can be read here. Also make sure you can create a private repository in GitHub (everyone gets 1 for free). Export GitHub username and PAT as environment variables as following:

export GITHUB_TOKEN=<your-token>
export GITHUB_USER=<your-username>

Latest Flux2 CLI can be downloaded here. You can also use the installation script from Flux if you fully trust it:

curl -s https://toolkit.fluxcd.io/install.sh | sudo bash

From this step onward, you will need access to a Kubernetes cluster, eg. kubectl cluster-info command works and returns cluster information. Check Flux2’s prerequisites with:

flux check --pre
► checking prerequisites
✔ kubectl 1.18.6 >=1.18.0
✔ Kubernetes 1.18.9 >=1.16.0
✔ prerequisites checks passed

Then the Flux2 command below can be executed to bootstrap a private GitHub repository flux-gitops using your GitHub PAT and the repository will be your cluster-as-code command center for GitOps practice, also the CRD(Custom Resource Definition) and controllers for Flux2 will be installed to the current cluster

flux bootstrap github \
  --owner=$GITHUB_USER \
  --repository=flux-gitops \
  --branch=main \
  --path=home-cluster \
  --personal

In the generated flux-gitops repository, the file structure looks like

flux-gitops
  - home-cluster
    - flux-system

Now you can simply add Helm charts or Kustomization templates into this repository and the changes will be applied to the cluster automatically. The following commands will create a simple namespace in the cluster, then register it with Flux2. After the changes pushed to GitHub, Flux2 controllers will apply the changes and create the new namespace.

cd flux-gitops/home-cluster
mkdir my-test
cd my-test
kustomize create
kubectl create namespace my-test --dry-run=client -o yaml > ns.yaml
kustomize edit add resource ns.yaml
cd .. # in home-cluster
flux create kustomization my-test --source=flux-system --path=home-cluster/my-test --prune=true --validation=client --interval=2m --export > my-test.yaml
# check-in everything to test GitOps
git add my-test my-test.yaml
git commit -m "Added my-test"
git push

Then you use a watch command to see how the new change get applied

watch flux get kustomizations
NAME                    READY   MESSAGE                                                         REVISION                                        SUSPENDED
flux-system             True    Applied revision: main/529288eed6105909a97f0d3539bc68e5e934418a main/529288eed6105909a97f0d3539bc68e5e934418a   False
my-test                 True    Applied revision: main/529288eed6105909a97f0d3539bc68e5e934418a main/529288eed6105909a97f0d3539bc68e5e934418a   False

That’s it, the Flux2 Hello-world. 🙂

Google Nest Wifi: A Speaker With Mesh Wifi

I got my pair of Google Nest Wifi before last Christmas. Just in time.

I have been using a NetGear Nighthawk R7000 for many years, time for an upgrade. The Google Nest Wifi is very easy to setup, only need to connect the Nest Wifi router to existing router/modem and the rest can be done on a phone with Google Home app.

Here are some good stuff I got from a pair of Google Nest Wifi( 1 router + 1 node ):

  • Better control with the Google Home app
  • Easy toggle on/off of guest network
  • Parental controls which allow I to turn on safe search for kids’ devices
  • and also set schedules to limit screen/internet time
  • The node is also a very good smart speaker, thinking something between the original Google Home and a Google Home Max
  • Automatic wifi mesh network, no setup required
  • Internet speed test now automated, and with history of speed of past days
  • Extendable mesh so I can buy another node later

🙂