[Kubernetes]沒有downtime的佈署

來源:Zero-Downtime Rolling Deployments in Kubernetes | Rakuten Engineering Blog

以下是摘錄。

在刪除掉 Pod 之前,流量還是會導向 Pod,要處理這種狀況,就需要去處理 SIGTERM。

文章建議三種方法。

  • 在 pre-stop hook 裡用 sleep
  • 延遲應用程式中止
  • 動態延遲應用程式中止

在 pre-stop hook 裡用 sleep

spec:
  terminationGracePeriodSeconds: 60
  containers:
  - name: "{{APP_NAME}}"
    lifecycle:
      preStop:
        exec:
          command: ["/bin/sh","-c","sleep 20"]

缺點,sleep 的時間是要去測量跟估算的,每個應用程式不同。而且,pre-stop 的主要用途不是用來做這事情的。

延遲應用程式中止

這個是要改應用程式的程式碼。

這裡有舉一個 wrapper script 的例子

#!/bin/bash

HAPROXY_PID=-1

# wait for 10 seconds, then send a USR1 signal to HAproxy
kill_haproxy(){
  sleep 10
  kill -USR1 $HAPROXY_PID
}
 
# invoke kill_haproxy function when receives the TERM signal
trap kill_haproxy SIGTERM

# Support the user hitting Ctrl-C, but only in interactive shells
if [[ -t 1 ]] ; then
  trap 'kill -USR1 "$HAPROXY_PID"' SIGINT
fi
 
haproxy -f config.cfg & HAPROXY_PID=$!
 
if [ -z "$HAPROXY_PID" ]
then
  echo "haproxy: Haproxy failed to start"
else
  echo "haproxy: haproxy started"
fi

在 Dockerfile 就這樣用

FROM alpine:3.5

# install bash, tini and haproxy
RUN apk add --no-cache bash tini haproxy=2.0.14-r0
 
# Run tini
ENTRYPOINT ["/usr/local/bin/tini", "—"]
CMD ["/launcher.sh"]

缺點跟前者差不多。

動態延遲應用程式中止

這個說不一定可用,就跳過了。

結論

好好處理 SIGTERM 。

電影流水帳(2023/01/01~2023/01/31)

Letitia Wright
Letitia Wright
  • Eurovision Song Contest: The Story of Fire Saga (IMDB, Wikipedia),台譯:歐洲歌唱大賽:火焰傳說。
  • Black Panther: Wakanda Forever (IMDB, Wikipedia),台譯:黑豹2:瓦干達萬歲。

Eurovision Song Contest: The Story of Fire Saga

蠻歡樂的電影,冰島上的 Lars 跟 Sigrit 從小就愛唱歌,一同組了團,期望日後可以參加歐洲歌唱大賽。長大以後,Lars 一事無成,父親嫌棄他只唱歌,不捕魚。Lars 一直懷抱著這夢想,直到一次爭吵後,他跟 Sigrit 決定去報名。冰島電視台本身不富裕,這次歐洲歌唱大賽又輪到冰島主辦,為了避免有人參賽,電視台老闆讓所有冰島的參賽者都上船開派對,然後把船炸了。沒上船的 Lars 跟 Sigrit ,就成了冰島的代表,參加歐洲歌唱大賽。

參加比賽的 Lars 跟 Sigrit 到巴黎參賽,Lars 在參加比賽之後,有一場出了大糗,跟 Sigrit 發生了爭吵,他失去了自己的方向,甚至打算不繼續參加了。回到冰島後,看到 Sigrit 仍然努力參加,冰島的其他人也鼓勵他,所以他後來醒了,再次回到巴黎,趕上最後一場決賽。Lars 幫 Sigrit 伴奏,要 Sigrit 唱出她寫的歌,最後奪得冠軍,一個快樂的結局。

Black Panther: Wakanda Forever

一開始就是 T’Challa 不好的消息,他快死了,妹妹舒莉急著想做出心形藥草來救哥哥,但生命就是這樣,說走就走,舒莉沒能來得及做出藥草。事實上,做出藥草,也不一定能救回 T’Challa,人都會這樣,會歸咎與自責,舒莉很過意不去,她覺得是自己不好。時間很快的過了一年,王后來找舒莉,找他出去走走,王后已經釋懷了,她知道自己的女兒還沒,想開導她。突然,海底人出現。

聯合國剛發現海底也有汎合金,想作進一步調查,卻被攻擊,聯合國以為是瓦干達幹的。Namor 帶領的海底人也有汎合金,他們並不想被陸地人發現,所以想找出來探索海底汎合金的機器是誰做的,所以才來找瓦干達,要瓦干達找出那個人。瓦干達調查以後,知道機器是莉莉威廉斯做的,就派人去找了他。要帶莉莉回去瓦干達的路上,Namor 就帶人把他們劫走了。在海底,舒莉跟莉莉了解了 Namor 等海底人的由來。後來因為在處理事情的立場不同,大家意見有了分歧, Namor 海底人不想被發現,跟瓦干達起了爭執,兩邊就這樣一發不可收拾。王后因為這次的爭執,死掉了,舒莉很生氣,很努力的研究新型藥草。透過從 Namor 那邊拿到的手鍊,她找到了做出心型藥草的方法。舒莉吃了心型藥草以後,見到了他的堂哥,堂哥跟他說了,你自己明白為什麼會看到我,舒莉很驚訝,也很生氣,就醒了。

接下來,舒莉成為了繼任的黑豹,跟 Namor 展開對決,兩邊打的難分難解。打到後來舒莉打贏了 Namor ,她放下了要復仇的心,放過 Namor ,只是要 Namor 海底人不要再打瓦干達,Namor 答應了,舒莉同時也答應,會對 Namor 海底人的事情保密,不讓人類知道這件事情,就這樣,事情算是圓滿落幕。

Shell Script 最佳實踐

來源:Shell Script Best Practice

這篇寫的很好,整理並摘錄裡面的內容

  1. 用 bash,不要用 zsh / fish
  2. 一開頭的 Sha-Bang 統一都寫 #!/usr/bin/env bash,這樣可以確保都是用相同的 shell 來執行,我自己是都寫 #!/bin/bash
  3. 副檔名用 .sh
  4. 第二行寫 set -o errexit,只要裏面有一行錯誤,就離開,不要繼續。
  5. 第三行寫 set -o nounset,只要有未設定的變數,就離開,不要繼續。
  6. 第四行寫 set -o pipefail,只要 pipe 過程中的指令有錯誤,就離開,不要繼續。
  7. 加上判斷 TRACE 環境參數是否存在的腳本,當有設定這個環境變數時,就加上 set -o xtrace,這可以幫助除錯。
  8. 儘量使用 [[ ]]取代 [ ][[ ]]是 bash內建的關鍵字,基本上作用跟 []或 test 一樣,可以減少額外消耗,而且有更多功能。
  9. 存取變數時,前後都加上雙引號。
  10. 函式裏面用 local 宣告變數。
  11. 加上 -h--help來說明自己怎麼使用。
  12. 印出錯誤訊息時,要導向到 stderr :echo 'Something unexpected happened' >&2
  13. 呼叫指令若有帶參數,最好帶長的,例如用 --silent代替 -s,這樣可讀性比較高。
  14. 一開始就切換到腳本的目錄,例如: cd "$(dirname "$0")" 我想這個應該是要確定腳本所要作用的目錄,所以加上註解,或是印出當前所在目錄,都對於後續維護的人會很有幫助。
  15. shellcheck來檢查腳本

作者有提供一個範本,可以直接複製來修改:

#!/usr/bin/env bash

set -o errexit
set -o nounset
set -o pipefail
if [[ "${TRACE-0}" == "1" ]]; then
    set -o xtrace
fi

if [[ "${1-}" =~ ^-*h(elp)?$ ]]; then
    echo 'Usage: ./script.sh arg-one arg-two

This is an awesome bash script to make your life better.

'
    exit
fi

cd "$(dirname "$0")"

main() {
    echo do awesome stuff
}

main "$@"

基本上就包含了前面所提到的重點,這裡額外一提的是有 main,這對於理解腳本來說,也是很重要的事情。

巧用 ps 找 CPU 用量最高跟記憶體用量最高的程序

因為還蠻常用的,就紀錄起來,之後就直接複製了。

ps aux --sort -%cpu | head -n 10
ps aux --sort -%mem | head -n 10
ps -eo pid,ppid,cmd,comm,%mem,%cpu --sort=-%mem | head -10

這邊要注意的是,MacOS 的 ps 跟 Linux 的 ps 不一樣,沒有 –sort 這個參數,MacOS 是用 -r 跟 -m 來做排序。

ps aux -r | head -n 10
ps aux -m | head -n 10

參考資料

從 proc 找 IP

一般來說,在安裝完 Linux 都會有 ifconfig 或是 ip 指令可以查詢主機的 IP。在容器環境裡,會因為要節省容器映像的空間,就不裝這些指令了。那要怎麼查 IP 呢? 可以從 /proc 來查詢。

cat /proc/net/fib_trie
cat /proc/net/fib_trie | grep "|--"   | egrep -v "0.0.0.0| 127."

就這樣,蠻簡單的。

參考資料

timemachineeditor

事情是在去年發生的,那時是在家辦公,卻發現 MBP 慢的要命,網速也變慢,後來查了一下,才發現是 MBP 一直在那邊做時光機備份。

這下就麻煩了,改為手動,又怕忘記,用自動又變慢,這可讓我好生困擾。請 Google 大神幫忙以後,找到有人推薦 timemachineeditor 這個工具。timemachineeditor 這個工具可以設定在不使用電腦的時間去做備份,這樣就解決我的問題了。

我是用 homebrew 安裝的

brew install --cask timemachineeditor

設定畫面很簡單,一看就會用了,這裡就不多說。

電影流水帳(2022/12/01~2022/12/31)

Halle Berry & Pedro Pascal

這次拖了很久,主要是時間不夠,假日的時間有蠻多都拿來做公司的事情,已經有點失去平衡。

Enola Holmes 2

Enola 在上集之後,開了店,接收委託,但生意很差,就在決定要收攤不做的時候,有一位在火柴工廠工作的女孩 Bessie 前來委託,說他的女伴 Sarah 不見了,想請 Enola 尋找 Sarah。

Enola 就開始進行調查,調查到後來,這件調查居然跟哥哥 Sherlock 的調查也有關係,就攪到一起了。

整件事情大略是這樣子的,火柴工廠使用便宜但有毒的原料來製造火柴,藉此獲得暴利,同時也遮掩有女工因慢性中毒而死去的事情。Sarah 跟她的男友 William 得知了火柴工廠的祕密,想要揭發這個祕密。William 是這家工廠老闆的兒子,陷入一個糾結、複雜的狀況。後來 Sarah 就只能躲起來,這也就是 Bessie 以為她消失的原因。Sherlock 調查到這工廠的金流跟 Moriarty 有關係,也循線調查到這邊。最後就是揭發、解決了整件事情

整體來說,延續了上集的節奏跟風格,表現持平。這集有交代 Enola 的心情轉折,創業不順利,不敢面對自己喜歡 Tewkesbury 的事情,後半段也被捕,然後被媽媽以其媽媽的好友救出,真的是很多事情。看到這邊,我想應該還會有第三集吧,當作是一個結束。

我吃了那男孩一整年的早餐

之前是在某篇文章看到這故事,後來才知道有翻拍成電影,故事蠻有趣的。

有個男孩跟一個女孩告白失敗,後來就一直請女孩吃早餐。女孩不領情,本來想把早餐丟掉,她的好友覺得浪費,再加上當時缺餐費,就自告奮勇吃掉。這一吃,就吃了一整年,後來事情講開,兩人就認識了。之後才知道男孩其實早就知道早餐是被另外一個人吃掉,所以故意一直送早餐,想透過這機會能認識。

總之,緣份就是這樣,很莫名其妙的發生。

Moonfall

幾天前在 HBO 看了 Moonfall,這是一部特效片,感情鋪陳不夠,有些場景想帶這部份就顯得很薄弱。不過我覺得故事設定蠻有趣的,說月球是個巨型空心的結構,因為有狀況,導致裡面的核心無法提供動力讓月球維持在軌道上,就慢慢愈來愈靠近地球。那月球怎麼會是空心的?原因是遠古的外星人打造用來延續生命的。遠古的外星人在文明發展到極致以後,研發了機器人,但這些機器人卻變了,導致整個文明毀滅。為了宇宙的生命延續,文明的殘存者挖空了小行星,把電腦植入,讓這些小行星到其他星系去試著延續其他的高智慧生命,月球就是其中一個小行星。這些機器人在摧毀整個文明以後,緊追在後,在銀河系找到月球。

故事基本就是圍繞著月球這件事情,有一方的主張要把月球給炸了,另外一方則是覺得應該要掌握這一點點的可能性,去探究月球。反正後來就是上了月球,發現地球內部真的是個空心結構,也了解了來龍去脈,於是協助外星人的電腦,打趴了這些試圖摧毀月球的機器人,最後地球得救,月球也留下,世界和平。

kubeaudit

網址:https://github.com/Shopify/kubeaudit

可以用來稽核 kubernetes 叢集的工具,檢查的項目有

  • 確保容器以非 root 身份執行
  • 確保容器的根目錄是唯讀
  • 移除有危險的 capability
  • 不執行 privileged
  • 陸續增加中

安裝

直接從 github release 下載二進位檔案,然後放到 /usr/local/bin 就可以了。

使用

有三種模式

  • Manifest mode
  • Local mode
  • Cluster mode

Manifest mode

Manifest mode 就是掃檔案,意思是如果你有寫好的 yaml 檔案,kubeaudit 可以直接掃 yaml 檔案

kubeaudit all -f "/path/to/manifest.yml"

掃完會輸出掃描結果。

需要修正的話,可以用 autofix 來自動修正。

kubeaudit autofix -f "/path/to/manifest.yml"

怕改爛的話,可以輸出到另外一個檔案

kubeaudit autofix -f "/path/to/manifest.yml" -o "/path/to/fixed"

Cluster mode

Cluster mode 就是掃描當前的 Kubernetes 叢集,不要加上 -f 參數就可以

kubeaudit all

Local mode

Local mode 是在你管理多座 kubernetes 叢集時,可以指定 kubeconfig 跟 context,例如

kubeaudit all --kubeconfig "/path/to/config" --context my_cluster

設定

大部份掃描工具都會提供設定,讓開發者可以決定要掃描哪些項目,kubeaudit 也有,格式是 yaml 。

enabledAuditors:
  # Auditors are enabled by default if they are not explicitly set to "false"
  apparmor: false
  asat: false
  capabilities: true
  deprecatedapis: true
  hostns: true
  image: true
  limits: true
  mounts: true
  netpols: true
  nonroot: true
  privesc: true
  privileged: true
  rootfs: true
  seccomp: true
auditors:
  capabilities:
    # add capabilities needed to the add list, so kubeaudit won't report errors
    allowAddList: ['AUDIT_WRITE', 'CHOWN']
  deprecatedapis:
    # If no versions are specified and the'deprecatedapis' auditor is enabled, WARN
    # results will be genereted for the resources defined with a deprecated API.
    currentVersion: '1.22'
    targetedVersion: '1.25'
  image:
    # If no image is specified and the 'image' auditor is enabled, WARN results
    # will be generated for containers which use an image without a tag
    image: 'myimage:mytag'
  limits:
    # If no limits are specified and the 'limits' auditor is enabled, WARN results
    # will be generated for containers which have no cpu or memory limits specified
    cpu: '750m'
    memory: '500m'
  • enabledAuditors 是要啟用的稽核項目
  • auditors 下方則是每個稽核項目的設定

總結

透過使用 kubeaudit 這個工具,可以稽核 kubernetes 叢集,避免放上有危險的設定,是很實用的工具。

microk8s使用自建的mirror registry

文件在這邊:How to work with a private registry

設定方法很簡單,設定檔案位置在 /var/snap/microk8s/current/args/certs.d/ ,每個 registry server 都有一個對應的目錄,裏面會有 hosts.toml 。例如 docker.io ,目錄就是

/var/snap/microk8s/current/args/certs.d/docker.io ,hosts.toml 的內容是
server = "https://docker.io"

[host."https://registry-1.docker.io"]
  capabilities = ["pull", "resolve"]

要改為 mirror registry,就變為

server = "https://docker.io"

[host."http://your_registry_server/v2"]
  capabilities = ["pull", "resolve"]
  override_path = true

關鍵在於 [host.””] 裡的 server 位置還有 override_path = true

修改完成以後,重新啟動 microk8s 即可。

sudo snap restart microk8s

基本設定方法就是這樣。之前在看的時候因為眼花,一直想說為什麼會有 “‘ | sudo tee -a /var/snap/microk8s/current/args/certs.d/k8s.gcr.io/hosts.toml” 這一段,後來仔細看,才知道文件裡貼的是一個指令。

以後改為這樣,就可以不用去外部拉取,加快拉取 image 速度了。

ubuntu的apt與gpg

最近因為在 Ubuntu 更新的時候,老是出現 gpg pub key 錯誤,有問題的套件庫是 hashicorp 跟 yarn 的套件庫,今天終於下定決心處理。

第一個找到的是這篇:How to configure HashiCorp repository

處理方法是這樣的,先下載 gpg key,然後用 sudo gpg 匯入

wget --quiet --output-document - https://apt.releases.hashicorp.com/gpg | \
  sudo gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/hashicorp-archive-keyring.gpg --import

然後檢查 /usr/share/keyrings/hashicorp-archive-keyring.gpg

ls -l /usr/share/keyrings/hashicorp-archive-keyring.gpg

permission 結果應該要是 644 。

接著檢查 source list 檔案,裏面會有 signed-by 的字串

deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com jammy main

基本上這樣就解決了,yarn 的處理方式也一樣。

wget --quiet --output-document - https://dl.yarnpkg.com/debian/pubkey.gpg | sudo gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/yarnkey.gpg --import

只是這邊做完,還是有問題,後來才靈機一動想到要檢查 /usr/share/keyrings/yarnkey.gpg 的 permission,發現是 600,用 chmod 改為 644 以後,apt update 就沒問題了。