Linux user. Programmer. Python, Go, Dart. Web developer. OpenStack contributer.
715 words

mapr 介紹

mapr 是一個非同步,批次執行指令的程式。擁有以下特點:

  • 非同步執行指令
  • 可以指定同時執行指令的數目
  • 指令執行失敗時,不在執行下一個指令
  • 能夠取得過去執行程式的結果作為這個指令的輸入(過去結果儲存在檔案裡面)
  • 能夠從檔案、指令執行結果、標準輸入做為指令參數
  • 能夠自動產生暫時檔案或是 uuid 作為指令參數

使用情境

  • 檢查特定主機的特定路徑是否有檔案,有檔案則顯示主機名稱
mapr -f '@a=hosts' 'ssh @a ls /somepath/somefile' 'echo @a' --last --no-header

上述指令執行從檔案讀取主機名稱(一行一個主機名稱),之後透過 ssh 指令檢查 /somepath/somefile 路徑是否存在,
如果存在則執行 echo 指令,印出主機名稱。如果路徑不存在,則不會執行 echo 指令。
@a會被替換成檔案hosts裡面的每一行。檔案有 n 行,則執行 n 次。

  • 刪除 OpenStack 下 project 所有的 volumes
mapr -c '@a=openstack volume list --format value --column ID' 'openstack volume delete @a'

先從 openstack volume list --format value --column ID 取得所有要刪除的 volume id。之後在一個一個傳進 openstack volume delete 做刪除動作。

上面指令與 openstack volume list --format value --column ID|xargs -L 1openstack volume delete 指令相似。但是透過 mapr 可以同時刪除多個 volume

  • 刪除 OpenStack 下 project 下,放在特定主機的 volume
mapr -c '@a=openstack volume list --format value --column ID' 'openstack volume show @a' 'grep @stdout1 host1' 'openstack volume delete @a'

先從 openstack volume list --format value --column ID 取得所有要刪除的 volume id。之後透過 openstack volume show 看 volume 詳細資訊。
該指令的 stdout 會存放在 @stdout1這個檔案裡面。方便後來的指令使用。grep @stdout1 host1 指令檢查檔案 @stdout1(由第一個指令openstack volume show @a產生的)
是否有包含 host1 這個字串。如果有的話,則執行下一個指令。刪除該 volume。

  • 建立檔案 file1~file99
mapr -l '@a=1-100' 'touch file@a'
  • 在 OpenStack 上建立 100 個 vm,vm 建立成功後立刻刪除
mapr -w 10 -l '@b=1-101' -u @a 'openstack server create --image image --network n1 --flavor f1 test-@a' 'openstack server delete test-@a'

上述指令會建立 100 個 vm ,vm 名字有 test- 這個 prefix,後面是 uuid。有 10 個 worker,指同時執行十個指令(可能是建立或是刪除)。
總共會建立100個 vm,但是至多有 10 vm 同時存在在系統。一個 worker 執行完建立與刪除 vm 後,才會在執行下一個建立與刪除vm的指令。

kubernetes 接 ceph 當 storage backend

kubernetes 版本:1.13.0
不同版本的設定可能會不一樣,我在201903測試過可以用
未來可能會有些許不同
不過原則應該都一樣

原則:
kubernetes 支援用 rbd 當 storage backend。但是 kube-controller-manager container 未必會包含 rbd 指令。如果 kube-controller-manager container 未包含 rbd 指令,你建立 storage 時就會看到 『failed to create rbd image: executable file not found in $PATH, command output:』的錯誤。這時候,你就要提供新的 container ,讓 kubernetes 可以透過你提供的 container (之後都叫 provider )來執行 rbd 相關操作。該 provider 放在 kube-system 下。

腳本簡易說明:

一開始建立名為 rbd-provisioner 的 serviceAccount ,之後在建立 secret 用來放 ceph keyring。最後建立 storage class ( 裡面放 ceph 相關資訊 )

https://gist.github.com/kjelly/97ebc4133b1293eff9135eada974d670

完整腳本如下:

---
# kubectl -n kube-system create -f create-kube-ceph-pbrc.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: rbd-provisioner
rules:
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
  - apiGroups: [""]
    resources: ["services"]
    resourceNames: ["kube-dns","coredns"]
    verbs: ["list", "get"]
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: rbd-provisioner
subjects:
  - kind: ServiceAccount
    name: rbd-provisioner
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: rbd-provisioner
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
  name: rbd-provisioner
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: rbd-provisioner
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: rbd-provisioner
subjects:
- kind: ServiceAccount
  name: rbd-provisioner
  namespace: kube-system

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: rbd-provisioner
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: rbd-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: rbd-provisioner
    spec:
      containers:
      - name: rbd-provisioner
        image: "quay.io/external_storage/rbd-provisioner:latest"
        env:
        - name: PROVISIONER_NAME
          value: ceph.com/rbd
      serviceAccount: rbd-provisioner

---
apiVersion: v1
kind: Secret
metadata:
  name: ceph-secret-admin
  namespace: kube-system
data:
  # change the value
  # sudo ceph auth get-key client.admin | base64
  key: QVFDYlFubGNVZjVzRkJBQUtKanN1R1FuWUpvNlRweWZQT0E0d3c9PQ==
type: kubernetes.io/rbd


---
apiVersion: v1
kind: Secret
metadata:
  name: ceph-secret-user
  namespace: kube-system
data:
  # change the value
  # sudo ceph auth get-key client.admin | base64
  key: QVFDYlFubGNVZjVzRkJBQUtKanN1R1FuWUpvNlRweWZQT0E0d3c9PQ==
type: kubernetes.io/rbd


---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: ceph-dynamic
  annotations:
     storageclass.beta.kubernetes.io/is-default-class: "true"
provisioner: ceph.com/rbd
parameters:
  monitors: 10.20.0.5:6789 # change it if needed.
  adminId: admin # change it if needed.
  adminSecretName: ceph-secret-admin # change it if needed.
  adminSecretNamespace: kube-system # change it if needed.
  pool: kube # change it if needed.
  userId: admin # change it if needed.
  userSecretName: ceph-secret-user # change it if needed.
  userSecretNamespace: kube-system # change it if needed.
  imageFormat: "2"
  imageFeatures: "layering"

在 linux 下使用指令將照片自動轉正

使用下面工具可以做圖片轉正

sudo apt install imagemagick
mogrify -auto-orient *.jpg 

debian 出現 locale: Cannot set LC_ALL to default locale: No such file or directory

debian 出現 locale: Cannot set LC_ALL to default locale: No such file or directory 

的解決辦法

sudo apt install locales
sudo locale-gen en_US.UTF-8
sudo dpkg-reconfigure locales

輸家競標

網路上有種競標方式,它的特性是每次下標都要付錢,我不知道到該怎麼稱呼這種競標方式。姑且叫他輸家競標。

為什麼我要叫他輸家競標呢? 因為你一下標你就輸了(輸了錢和時間),在這種競標模式下,只有兩個贏家,賣家、平台提供者。

在一般的競標模式下,競標者為了確保自己的最大利益,通常不會一次加碼太多錢。直到沒有人願意再加碼,此時競標就成立,買家確定。

可是在輸家競標的情形下,一旦你下標,要嗎你成為買家,要嗎你失去你因下標的而付出的錢。許多人為了避免損失之前下標的錢,就會盡量的下標,直到物品金額他無法負擔。也因為大部分下標的人不願意失去他因下標的而付出的錢。因此最後成交金額常常會比一般競標方式高,而買家通常不會得到太多好處(因為他需要負擔成交價、因下標而損失的錢、使用平台費用)。

一般的競標,因為出價不需要成本(當然有時間成本),所以要嗎成為買家,要嗎就浪費時間(輸家競標既浪費錢也浪費時間)。所以不會有買家競相出價的情形。因此一般的競標方式,對買家有利許多,賣家則還好。

論生活中常見成本概念

這篇文章探討生活中的常見成本,讓你在思考成本時,有個方向。以下的名詞並非所有都是經濟學術語。成本不一定是金錢。

擁有成本:這是指當你從一個狀態轉變到另一個狀態(注:後者狀態的價值比前者狀態還高),所付出的成本。例如你從沒有車到有一台車,購買車的成本。或是從有第二台車到有第三台車的購車成本。

維持成本:維持狀態,使其狀態的價值避免嚴重減損。例如保養車的成本,避免車損壞。

機會成本:當你做一個選擇而需要放棄其他選擇,則其他選擇的最高價值者,為機會成本。在思考時間相關的問題時,應注意機會成本的問題。

沉沒成本:當你做了某件事,然後發現做下去沒意義(或價值)。但是因為過去花費的成本,又讓你繼續做沒意義(或低價值或非完全理性)的事。則過去花費的成本則為沉沒成本。例如你不小心買了一張很難看的電影票,你覺得去看只是又浪費時間。但最後又去看,而浪費了時間。該張電影票則為沉沒成本。

了解了上述成本的意義,則以情境來描述上面成本概念。

  • 情境一:

當你花錢買書,則買書錢為擁有成本(你必須付出錢,才能擁有該本書)。當你買了很多書,因而需要額外租空間來放書,則租額外空間的錢則是書的維持成本(為了讓你繼續擁有書,你需要付出額外的錢,讓你維持擁有)。當你不想付出額外租空間的成本時,而選擇丟棄一本書來放新進的書,則被丟棄的書的價值為你決定保留新進的書的機會成本。當你買一本新書,而決定租額外空間放書,而不丟棄最低價值的書,而對低價值的書已經對你沒意義。則該本最低價值的書的價值為你的沉沒成本(你為了一本沒意義的書,而租額外空間)。

  • 情境二:

當你打算寫一個網站,你在思考要學習組合語言或是 python 語言。最後你選擇了組合語言,此時 python 語言就是你的機會成本(你損失 python 語言所帶來的好處)。你花了很多時間,終於學會怎麼用組合語言寫網站,那些時間則是你的擁有成本。當你學會了用組合語言寫網站,你必須花時間去進修你的能力,或確保你不會忘記技能。此時你的付出為維護成本。後來發現用 python 寫網站比較好,但是你卻不換成更好的工具。此時過去在組合語言的付出為沉沒成本,他讓繼續沉沒下去。

新部落格!

舊的blog 在blogger

不過後來覺得 blogger 不好用

就很少寫文章了

現在用了 standard notes 後

發現 standards notes 有提供 blog 功能

覺得很方便

畢竟我的 blog 主要是用來記錄電腦筆記

這樣我自己的筆記和電腦筆記都可以用 standard notes 管理

探討解決問題的方法

在做決策時,一開始需要盡可能列出問題的所有可能解法,這樣可以避免在單一解法陷入太深,而看不到其他情形。在找出許多可能解法後,則需要深入探討評估各種解法。需要廣度分析、深度分析。評估各種解法,可以從下列三種角度來分析

利益分析:分析各種解法能夠帶來的好處。這會是優先考慮的角度,畢竟沒有好處的解法是不需要考慮的。

風險管理:任何解法都會有副作用,評估各個副作用發生的可能性,並副作用會造成的損害。

損害控制:當採取該解法時,發生不利或不預期的事情時,是否能夠降低損害或是接受該損害。 

以下象棋為例子,一開始要思考各種可以走的走法。之後深入分析各個走法,找出各個步數可能優缺點。評估各種走法,思考各種走法,有何風險。如會損失一隻”車”或是”馬”。損害控制像是這樣的走法,可能只會讓你損失兩隻兵,但是不會輸掉遊戲之類的。

ssh tunnel 只會監聽 localhost

當你在用 ssh tunnel 時
如用下列指令
ssh -NfR 0.0.0.0:1194:192.168.10.1:1194 remoteserver
你把 0.0.0.0 改成各種組合
他還是只會監聽 localhost

需要將 sshdconfig 的 GatewayPorts 改成 yes&
才有作用