不再舒适的2019

2020 新年快乐!!我不得不重复的说,时间过的太快了。其中的一个原因大概是我离开我舒适的环境去接受新的挑战。

2019年初我从 AFL 离职后加入了云计算顾问公司 Contino,想给自己找点挑战,结果还真是很挑战。我从来没做过顾问,因为我性格内向而且英语交流也仅仅达到及格的水平,我想一定是之前的技术经验为我赢得了这份工作。

入职后不久我就被派到一家4万多人的大企业做云迁移项目,就是将原本运行在 IBM 硬件上的业务系统搬迁到 AWS 上继续运行。这回算是体验到了 IBM 的傲慢,知道大客户要投奔 AWS 了也并不在意,但也不是很大方的提供技术上的支持就是了。在大企业里很多事情靠的不是技术而是人际关系和政治头脑,而我在这些方面基本属于幼稚园毕业。好在同事们非常有团队精神,帮我度过了最初几个月。后来我有幸参加了公司的软技能培训,收获非常大,瞬间意识到自己以前说话的方式有多么简陋。

另外一大收获就是我从一个“肉食动物”走上了素食之路,这简直是不可思议的。

在猫本的第一份工作期间我的一个同事 G 就是素食者。当时我们几个“正常人”总是开他的玩笑,例如:素汉堡不算汉堡。但至少我从此有了一个素食朋友。最近几年老婆将后院菜园种的有声有色,各种蔬菜直接从菜园进厨房,真正的新鲜蔬菜。我当然还是爱吃肉的,但老婆收获的蔬菜是必须吃的,所以我吃蔬菜的比例有了很大提高。令我感到意外的是,吃蔬菜的感觉还真不错。

与此同时,肉食产品的负面新闻接踵而来:禽流感,猪瘟,过度放牧,抗生素饲料等等。这些让我对吃肉的兴趣有所减弱。直到我看了 NetFlix 上的纪录片 The Game Changers ,我了解到了很多最强的人,例如运动员,铁人五项冠军等等都不吃肉:“很多人问我,你如何只吃素却像牛一样强壮?我反问,你见过牛吃肉吗?” 没错,就像“钻石恒久远 一颗永流传”一样,让人们喜欢吃肉也是市场运作的结果。

目前我已经不再吃猪牛羊肉了,希望在新的一年里能停吃鸡肉,仅偶尔吃些鱼肉。

Use fzf to Supercharge Your kubectl Command

First let’s have a look at fzf, a super fast command line fuzzy finder. It’s mostly written in golang and there are so many ways to use it. In this note, I’ll just use it to select a value from a list in a terminal and then return it to next command.

When working with kubernetes, I open need to switch between namespaces in a cluster. The raw kubectl command for this is:

 kubectl config set-context --current --namespace='my-namespace'

But I don’t remember every namespace, do I? If auto-completion of kubectl is available I can double-tab and then get a list of namespaces like this:

This is not quite convenient, not at all. So I created this simple bash function using fzf to speed this up.

#select k8s namespace
function kns() {
  kubectl config set-context --current --namespace=$(kubectl get namespaces --output=jsonpath='{range .items[*]}{.metadata.name}{"\n"}'|fzf)
}

The kubectl get... command in the sub shell above simple output a list of available kubernetes namespaces and then pipe to fzf to make an interactive auto-completion. And then the selected namespace will be passed back to kubectl config ... command to actually set the namespace to current context. The result looks like this:

PS. I’ve put this and other handy shorthand functions here.

Fedora 31, Optimus, Bumblebee and Steam

My laptop(XPS 15) has Nvidia 1050 Ti but I never used it to play games, because I replaced Windows 10 with Fedora Linux on the first day, not even a dual boot. I’ve tried Bumblebee to run Linux native games on Nvidia a few years ago but it wasn’t stable enough.

After I upgraded the laptop to Fedora 31, I decided to give Bumblebee another try. Luckily I got it working just by following instructions here. With very little efforts, I got Nvidia Settings and GLXSpheres working.

And it’s almost a no-brainer to launch Steam Linux native games with an extra launch option optirun -b primus %command%

That’s it, now I can play my Steam games on my Linux laptop 🙂

Golang and Docker Multi-Stage Build MK2

In my previous post I used Docker multi stage technique to build a Docker container image which only has the golang executable in a tiny Alpine Linux base image. I’ll go further to use the scratch base image which has basically nothing.

Here’s the Dockerfile I tested on my own project, I’ve also added comments to help understand important lines:

FROM golang:1.13.1 AS builder

# ENVs to ensure golang will need no external libraries
ENV CGO_ENABLED=0 GOOS=linux
WORKDIR /app
COPY . .
# build switches to ensure golang will need no external libraries
RUN go build -a -installsuffix cgo -o myapp main.go && \
# create non-privileged user and group to run the app
  addgroup --system --gid 2000 golang && \
  adduser --system --gid 2000 --uid 2000 golang

FROM scratch
# some sample ENVs for the app
ENV API_KEY=xxx \
  API_EMAIL=xxx
WORKDIR /app
# copy the golang executable over
COPY --from=builder /app/myapp .
# scratch has no adduser command so just copy the files from builder
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/group /etc/group
# use the CA cert from builder to enable HTTPS access
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
USER golang
# run the executable directly
ENTRYPOINT ["/app/myapp"]

The result image is only 7.7MB, only 1MB larger than the golang app itself. 🙂