Target
- daemonsets
- deployment
- statefulsets
Policy
- request cpu 單位以十進位設定
- 像是 50m 100m 200m 250m 500m 1000m(or 1)
- request memory 單位以二進位設定
- 像是 16Mi 32Mi 64Mi 128Mi 256Mi 384Mi 512Mi 768Mi 1024Mi(or 1Gi)
- request memory 是 node 實際上能放進 pod 的基本量, pod 塞不進 pod 就得生出新的 node 來放.
- pod cpu 吃到超過 limit cpu, 會被卡住等下一輪資源繼續跑, 不會被砍掉.
- pod memory 吃到超過 limit memory, 會被 OOM 機制砍掉.
- request cpu 太小的話, 有可能 schedule job 耗用的 cpu 反而比較高, 造成效率變差.
- limit memory 至少是 request memory 的一倍大, 才不會被塞進剩餘空間太小的 node 然後 OOM 被宰.
- nodejs 可能有 memory leak 狀況, memory 可能會越吃越多(無法被 gc), 最後被 OOM 砍掉.
- nodejs memory leak 越嚴重, cpu 耗用越高, 有可能卡到 limit cpu 導致卡卡的慢.
- java / nodejs 服務啟動時可能會吃大量 memory, 然後才 gc 放掉, limit memory 就得觀察後再提高.
Cloud Features
- AWS
- node instance type 用 t 系列可以 cpu burst (use credit or $$), 必要的時候 limit cpu 可以拉很高來用.
- GCP
- request minimum
- cpu 50m
- memory 52Mi
- resources cpu:memory 比例有最大上限 1:6.5
- Azure
- TBD
Azure
- cpu
- request 要看服務是用什麼服務/架構寫的, 太少的話可能 pod 不會在 1 分鐘內 ready, 像是 java.
- limit 要觀察服務量有多大而設定, 或是服務本身的機制耗用 cpu 高的話, limit 也拉高備用.
- go
- request
- 50m
- limit
- 200m or more
- nodejs / typescript
- request
- 100m
- or more for pod ready in 1min
- or less for low cpu resource use after startup
- limit
- 500m
- java / kotlin / scala
- request
- 200m
- or more for pod ready in 1min
- or less for low cpu resource use after startup
- limit
- 1
- 還是有可能 1 分鐘內 pod 沒來得及 ready, 得調整 deployment 加長 ready 偵測時間
- spec.template.spec.containers.livenessProbe.initialDelaySeconds: 60
- spec.template.spec.containers.readinessProbe.initialDelaySeconds: 60
- memory
- request 通常會設定為比目前用量小一階的基本量.
- limit 則是會設定為比目前用量大一階, 得花些時間觀察狀況持續更新.
% kubectl top pod | grep foobar-deploy
foobar-deploy-8487bddd77-cl5br 18m 365Mi
foobar-deploy-8487bddd77-pmpm4 43m 343Mi
foobar-deploy-8487bddd77-sfdtc 19m 299Mi
foobar-deploy-8487bddd77-sl5s9 21m 605Mi
foobar-deploy-8487bddd77-sr5kc 21m 618Mi
- request
- 256Mi
- limit
- 768Mi
% kubectl top pod | grep blahblah-deploy
blahblah-deploy-6fc6dd8c97-5txhc 25m 263Mi
blahblah-deploy-6fc6dd8c97-7s8jb 26m 287Mi
blahblah-deploy-6fc6dd8c97-9dc4z 25m 199Mi
blahblah-deploy-6fc6dd8c97-bc7kf 26m 330Mi
blahblah-deploy-6fc6dd8c97-bqwwf 26m 329Mi
blahblah-deploy-6fc6dd8c97-dgj22 24m 283Mi
blahblah-deploy-6fc6dd8c97-gjftr 26m 260Mi
blahblah-deploy-6fc6dd8c97-kgmf4 24m 279Mi
blahblah-deploy-6fc6dd8c97-nl667 25m 217Mi
blahblah-deploy-6fc6dd8c97-nqbqb 28m 266Mi
blahblah-deploy-6fc6dd8c97-pjfs9 33m 220Mi
blahblah-deploy-6fc6dd8c97-qbslb 26m 527Mi
blahblah-deploy-6fc6dd8c97-sf4hc 38m 261Mi
blahblah-deploy-6fc6dd8c97-tn5ch 27m 392Mi
blahblah-deploy-6fc6dd8c97-wg2qs 25m 258Mi
- request
- 128Mi
- limit
- 512Mi or 768Mi
- 因為 pod 數量夠多, 所以少數超過 512Mi 的情況可以接受設定 512Mi 被 OOM 砍掉換人做.
- 但如果是一次處理大量資料的 pod, 就不能發生被中途砍掉的狀況, 得設定 768Mi 甚至更多.
2025年3月10日 星期一
Kubernetes - tuning containers resources requests and limits
2025年1月13日 星期一
Akamai - CDN access logs to Datadog
目的: 把 blah.foobar.com 的 CDN access log 轉送到 datadog 備查
0. Datadog
- 設定設定
- https://docs.datadoghq.com/integrations/akamai_datastream_2/
1. COMMON SERVICES - DataStream
- 點選 Create stream - Delivery Products
- CONFIGURATION
- Display Name: blah-foobar-com-logs-to-datadog
- Group: Foobar-W-DEADBF
- Include properties: 勾選 blah.foobar.com
- DATA SETS
- Log information
- (include all)
- Message exchange data
- (include all)
- Request header data
- (include all)
- Network performance data
- (include all)
- Cache data
- (include all)
- Geo data
- (include all)
- Web security
- (include all)
- EdgeWorkers
- (include all)
- Content protection
- (include all)
- Custom fields
- (include all)
- Log file
- Log format: Json
- DELIVERY
- Destination
- Destination: 選 Datadog
- Display name: blah-foobar-com-logs-to-datadog
- Endpoint: (datadog input endpoint)
- https://http-intake.logs.datadoghq.com/v1/input
- https://http-intake.logs.datadoghq.eu/v1/input
- Tags: source:akamai.datastream
- Source: akamai.datastream
- Service:
- API Key: (datadog api key)
- Send compressed data: No
- Delivery options
- Push frequency: 60 Seconds
- SUMMARY
- 幾個步驟建立完之後, blah-foobar-com-logs-to-datadog 的 status 是 Activating - V1
- 只能 View / History / Clone, 無法 Edit / Deactivate / Delete
- V1 是指這個 Stream 設定是 version 1, 不是 DataStream 1 的意思
2. CDN - Properties
- 選 blah.foobar.com 再點選版本, 點 Edit New Version
- 左邊選 Default Rule, 右邊點 +Behavior 新增 DataStream
- Stream version 只有選 DataStream 2 會過
- DataStream 1 要被淘汰掉
- 選 DataStream 1 會跳出警告訊息, 可以 Save 但無法 Activate
- Stream names 選 blah-foobar-com-logs-to-datadog
- Sample rate 預設 100
- 通靈用的話一定要選 100, 要不然缺 log 會讓你通到屎
- 最後 Save
- 然後 Activate 這個新版本上線
- 最久 10 分鐘才會完成
3. 回到 COMMON SERVICES - DataStream
- blah-foobar-com-logs-to-datadog 的 status 在 Properties 上完之後變成 Active - V1
- 第一次比較快
- Active 狀態才可以 Edit / Deactivate
- 要 Delete 的話, 要先 Deactivate 讓狀態變成 Deactived 才能 Delete
- 無論是 Edit / Deactivate, 最久 60 分鐘才會生效
2025年1月9日 星期四
Akamai - CDN access logs to S3 bucket
目的: 把 blah.foobar.com 的 CDN access log 轉送到 s3 bucket 備查
0. AWS S3
- 開好 bucket
- blah-foobar-com-logs @us-west-2
- 建立完全存取這個 bucket 的 IAM User
- S3-blah-foobar-com-logs-ReadWrite
- 在這個 IAM User 建立 access key pair
1. COMMON SERVICES - DataStream
- 點選 Create stream - Delivery Products
- CONFIGURATION
- Display Name: blah-foobar-com-logs-to-s3
- Group: Foobar-W-DEADBF
- Include properties: 勾選 blah.foobar.com
- DATA SETS
- Log information
- Request time
- Message exchange data
- Bytes
- Client IP
- HTTP status code
- Protocol type
- Request host
- Request method
- Request path
- Request port
- Response Content-Length
- Response Content-Type
- User-Agent
- SSL overhead time
- SSL version
- Object size
- Uncompressed size
- Total bytes
- Query string
- Request header data
- Cookie
- Range
- Referer
- X-Forwarded-For
- Max age
- Network performance data
- Error code
- Cache data
- (null)
- Geo data
- (null)
- Web security
- (null)
- EdgeWorkers
- (null)
- Content protection
- (null)
- Custom fields
- Custom field
- Log file
- Log format: Json
- DELIVERY
- Destination
- Destination: 選 Amazon S3
- Display name: blah-foobar-com-logs-to-s3
- Bucket: blah-foobar-com-logs
- Path: logs/{%Y}/{%m}/{%d}/{%H}
- 檔案儲存結構用 年/月/日/小時 存放
- 目前每小時約產生兩千多個小檔案, gzip -d 解開之後就是純文字檔案
- Region: us-west-2
- Access key ID: (bucket 的 IAM user 的 access key id)
- Secret access key: (bucket 的 IAM user 的 secret access key)
- Delivery options
- Filename: ak -[random-string]-[epoch-timestamp]-[random-string]- ds
- 中間這一段沒辦法改, 我比較想要 [epoch-timestamp] 在前面比較好用
- Push frequency: 60 Seconds
- SUMMARY
- 幾個步驟建立完之後, blah-foobar-com-logs-to-s3 的 status 是 Activating - V1
- 只能 View / History / Clone, 無法 Edit / Deactivate / Delete
- V1 是指這個 Stream 設定是 version 1, 不是 DataStream 1 的意思
2. CDN - Properties
- 選 blah.foobar.com 再點選版本, 點 Edit New Version
- 左邊選 Default Rule, 右邊點 +Behavior 新增 DataStream
- Stream version 只有選 DataStream 2 會過
- DataStream 1 要被淘汰掉
- 選 DataStream 1 會跳出警告訊息, 可以 Save 但無法 Activate
- Stream names 選 blah-foobar-com-logs-to-s3
- Sample rate 預設 100
- 通靈用的話一定要選 100, 要不然缺 log 會讓你通到屎
- 最後 Save
- 然後 Activate 這個新版本上線
- 最久 10 分鐘才會完成
3. 回到 COMMON SERVICES - DataStream
- blah-foobar-com-logs-to-s3 的 status 在 Properties 上完之後變成 Active - V1
- 第一次比較快
- Active 狀態才可以 Edit / Deactivate
- 要 Delete 的話, 要先 Deactivate 讓狀態變成 Deactived 才能 Delete
- 無論是 Edit / Deactivate, 最久 60 分鐘才會生效
2024年6月6日 星期四
Terraform - aws_rds_proxy 接 RDS PostgreSQL 的 init_query 指令
在 Terraform 的文件 db_proxy_default_target_group 只有提供 MySQL 的使用範例:
resource "aws_db_proxy" "example" {
name = "example"
debug_logging = false
engine_family = "MYSQL"
idle_client_timeout = 1800
require_tls = true
role_arn = aws_iam_role.example.arn
vpc_security_group_ids = [aws_security_group.example.id]
vpc_subnet_ids = [aws_subnet.example.id]
auth {
auth_scheme = "SECRETS"
description = "example"
iam_auth = "DISABLED"
secret_arn = aws_secretsmanager_secret.example.arn
}
tags = {
Name = "example"
Key = "value"
}
}
resource "aws_db_proxy_default_target_group" "example" {
db_proxy_name = aws_db_proxy.example.name
connection_pool_config {
connection_borrow_timeout = 120
init_query = "SET x=1, y=2"
max_connections_percent = 100
max_idle_connections_percent = 50
session_pinning_filters = ["EXCLUDE_VARIABLE_SETS"]
}
}
這邊 init_query 是用 “SET x=1, y=2” 當作 proxy 連上 DB 的測通指令, 但是 MySQL 的 SET 指令跟 PostgreSQL 的 SET 指令用法不同, 所以直接把這個範例給 PostgreSQL 用的時候會噴錯誤:
proxy log: - [INFO] [dbConnection=1140488035] The database connection closed. Reason: An internal error occurred. DB log: - ERROR: syntax error at or near "=" at character 11 - STATEMENT: SET x=1, y=2
(以上來自 CloudWatch Log Groups, DB 跟 DB proxy 都有設定送出 log 到這邊)
伸進去 PostgreSQL DB 手動執行指令看看:
postgres=> SET x=1, y=2;
ERROR: syntax error at or near "="
LINE 1: SET x=1, y=2;
^
postgres=> SET x=1;
ERROR: unrecognized configuration parameter "x"
postgres=>
確認是 SET 指令造成錯誤.
Google 查了幾下也是有一些回報同樣的問題, 解法幾乎都是把 init_query 拿掉, 但是這樣就少了一個 proxy 連入 DB 後, 測通 DB 是否有正常反應的機制.
所以找個簡單的指令替代 SET 就解決了:
init_query = "VALUES (1,2)"
AWS - IAM Role with Policy
AWS 的 IAM Role 跟 Policy 有兩種連接方式: - Role 內嵌 Policy. - Role 和 Policy 是各自建立, 然後再接起來(attach)用.
以 Policy 編修來說, 前者就只能在 portal 上面 CRUD, 後者在 Policy 本身的 portal 介面還可以看 permission 檢查, 歷次編修版本與控管, 相同的 Policy 還可以接到多個 Role 共用, 後來我也盡量都用後者.
不過後者在 Terraform 的寫作上有需要注意的地方, 一般寫法如下:
resource "aws_iam_policy" "this" {}
resource "aws_iam_role" "this" {}
resource "aws_iam_role_policy_attachment" "this" {
depends_on = [
aws_iam_role.this,
aws_iam_policy.this
]
}
在 terraform apply 的時候不成問題, 但是在 terraform destroy 會發生 race condition: Policy 還沒從 Role 拆出來, 上面這個寫法會造成 aws_iam_policy 跟 aws_iam_role 同時進行 destroy, 在刪除 aws_iam_policy 就會噴錯誤訊息, 說 Policy 還接在 Role 上面所以不能被砍掉.
雖然再執行一次 terraform destroy 就過了(錯誤是在砍 aws_iam_policy 的時候噴的, 但同時砍 aws_iam_role 的動作有被完成), 但是這樣對於砍站跑路就不夠絲滑.
簡單解決的方式就是在 aws_iam_role 裡面加一個 depends_on aws_iam_policy:
resource "aws_iam_role" "this" {
...
depends_on = [
aws_iam_policy.this
]
}
這樣子在 destroy 的時候, aws_iam_role 就會先被刪除(無論 Policy 拆出來了沒), 再刪除 aws_iam_policy 就不會卡住了.
然後第一個方式在 Terraform 有個地雷, 在 Role 裡面內嵌 Policy 大概是這樣寫:
resource "aws_iam_role" "this" {
...
inline_policy {
name = "Role-foobar-Policy"
...
}
}
當不要用 inline_pocily 的時候, 把這段刪除成這樣:
resource "aws_iam_role" "this" {
...
}
然後 terraform apply 的時候, diff 並沒有出現 - 掉 inline_policy 這塊的訊息, 實際上 Terraform 真的沒做這個刪除, 在 portal 是還看得到 inline_policy 的存在, 得在這邊手動砍掉才算沒了.
隱欌地雷: AWS IAM 有好幾個拆連接的動作會產生 race condition, 表面上 API 回應 ok, 但是實際上裡面還在慢慢斷開, 沒那麼快拆完...
2022年11月30日 星期三
GCP - copy IAM custom role R from project A to project B
Role ID: projects/A/roles/R 0. gcloud auth login (with enough permission) 1. gcloud iam roles describe R --project=A > R.txt 2. gcloud iam roles create R --project=B --file=R.txt
2022年5月8日 星期日
random password generator - use jot + rs
適用於 BSD OS 與 Mac 環境 jot -r -c 160 / z | \ grep -e '[a-z]' -e '[A-Z]' -e '[0-9]' | \ rs -g0 0 64 以上會產生出 160 個 ascii / 到 z 的字元, 只擷取 a-z A-Z 0-9 來用, 集結成每行長度 64 的字串. 如果要放行一些符號的話, 像是底線(_)也在 / 到 z 的範圍內, 就可以在 grep 指令加上 -e _ 擷取來用. Ascii table (credit: https://c-for-dummies.com/blog/?p=4895)
