星期二, 1月 30, 2024

GCP Authentication with Terraform 小記 - ADCs


GCP Authentication with Terraform 小記 - ADCs


Terraform: 1.7.1-dev 

Google Cloud SDK 461.0.0.0

OS: openSUSE Leap 15.5 in Azure


今天要來實作 Terraform 驗證方式


如果你是練習 Terraform 官方文件



這個時候就會有個想法, 我在使用 Terraform in GCP 的時候一定要建立 Service Account Key 嗎? 還是有不同的方式?


這邊引用一下 Terraform 官方的文件


Service Account 的方式在 Terrafrom 的官方練習就嘗試過了


今天來  Lab  Application Default Credentials (ADC) 方式


首先我在 Azure 上面建立一個 openSUSE Leap 15.5 的  VM


登入 openSUSE Leap 15.5


觀察資訊


> ls  ~/.config/gcloud/


active_config  config_sentinel  configurations  default_configs.db  gce  logs


此時剛裝好 terraform 以及 google Cloud SDK


進行初始化

> gcloud init


Welcome! This command will take you through the configuration of gcloud.


Your current configuration has been set to: [default]


You can skip diagnostics next time by using the following flag:

  gcloud init --skip-diagnostics


Network diagnostic detects and fixes local network connection issues.

Checking network connection...done.                                                                                     

Reachability Check passed.

Network diagnostic passed (1/1 checks passed).


You must log in to continue. Would you like to log in (Y/n)? Y

Go to the following link in your browser:


    https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=31555942549.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fsdk.cloud.google.com%2Fauthcode.html&scope=openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fappengine.admin+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fsqlservice.login+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcompute+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Faccounts.reauth&state=oxpO5ubmYhf7xOYF0yyADDXPA4pWkW&prompt=consent&access_type=offline&code_challenge=lQ7DbRpJUX1eFFBejQlR8qbiRoywmEgfJsgl4qx6Nbk&code_challenge_method=S256


Enter authorization code: 4/0AfJohXlD7SgI9MOd7zfJLph0sKwGcU1p5_i5rwby9G32SjPE8yoBiUItUwe5V2OLda2gxw


  • 開啟連結, 填入 authorization code

  • 選取預設的 project

  • 決定要不要設定預設的 Region


初始化完成後, 再次觀察目錄


> ls  ~/.config/gcloud/


access_tokens.db  config_sentinel  credentials.db      gce                 logs

active_config     configurations   default_configs.db  legacy_credentials


先不執行 gcloud auth application-default login


來直接執行  Terraform 看看會發生那種狀況


參考官方文件


建立實作目錄

> mkdir  learn-terraform-gcp


進入工作目錄

> cd  learn-terraform-gcp


建立 main.tf


terraform {

  required_providers {

    google = {

      source = "hashicorp/google"

      version = "4.51.0"

    }

  }

}


provider "google" {

#  credentials = file("<NAME>.json")


  project = "sakana-3"

  region  = "us-central1"

  zone    = "us-central1-c"

}


resource "google_compute_network" "vpc_network" {

  name = "terraform-network"

}


  • 這邊我故意先把 credentials 註解起來


進行  初始化

> terraform  init


> terraform  plan


Planning failed. Terraform encountered an error while generating this plan.


│ Error: Attempted to load application default credentials since neither `credentials` nor `access_token` was set in the provider block.  No credentials loaded. To use your gcloud credentials, run 'gcloud auth application-default login'.  Original error: google: could not find default credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.

│ 

│   with provider["registry.terraform.io/hashicorp/google"],

│   on main.tf line 10, in provider "google":

│   10: provider "google" {


  • 這邊因為找不到驗證資訊就會出現錯誤


建立  local authentication credentials


> gcloud  auth  application-default  login


Go to the following link in your browser:


    https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=764186021852-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fsdk.cloud.google.com%2Fapplicationdefaultauthcode.html&scope=openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fsqlservice.login&state=NdqQVFWU6dxpcH7eO5XqyqgGJalzr6&prompt=consent&access_type=offline&code_challenge=XrLVHJTkJCx00pDeoOEHSBLy9W0W-gWoZmc69lIEXSY&code_challenge_method=S256


Enter authorization code: 4/0AgJohXnEmaeA3UmFir2QTz_Dgi6zFJtvsWQqsu-t39J9jtI8Wli1CqxbEWrTFtJfYeEUug


Credentials saved to file: [/home/sakana/.config/gcloud/application_default_credentials.json]


These credentials will be used by any library that requests Application Default Credentials (ADC).


Quota project "sakana-3" was added to ADC which can be used by Google client libraries for billing and quota. Note that some services may still bill the project owning the resource.


  • 一樣驗證驗證碼

  • 會產生 Credentials  到 ~/.config/gcloud/application_default_credentials.json


觀察資訊


> ls ~/.config/gcloud/


access_tokens.db  application_default_credentials.json  configurations  default_configs.db  legacy_credentials

active_config     config_sentinel                       credentials.db  gce                 logs


再次嘗試


> terraform  plan


Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the

following symbols:

  + create


Terraform will perform the following actions:


  # google_compute_network.vpc_network will be created

  + resource "google_compute_network" "vpc_network" {

      + auto_create_subnetworks         = true

      + delete_default_routes_on_create = false

      + gateway_ipv4                    = (known after apply)

      + id                              = (known after apply)

      + internal_ipv6_range             = (known after apply)

      + mtu                             = (known after apply)

      + name                            = "terraform-network"

      + project                         = (known after apply)

      + routing_mode                    = (known after apply)

      + self_link                       = (known after apply)

    }


Plan: 1 to add, 0 to change, 0 to destroy.


────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────


Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if

you run "terraform apply" now.


也可以實際 apply 測試

> terraform  apply


建立成功, 也可以到 console 觀察



練習結束 刪除資源

> terraform  destroy


這個實驗可以多注意到一件事情, 我的 main.tf 中沒有使用 credentials = file("<NAME>.json")

也就是你是使用 ADCs  不一定要進行該項設定


又往 Terraform and GCP 前進一步


~ enjoy it


Reference


星期五, 1月 05, 2024

k6 with openSUSE Leap 15.5 小記



k6 with openSUSE Leap 15.5 小記


之前公司壓測用的是 JMeter, 最近想在 K8 上面玩一些 side project

看了些資料, 最後還是選擇 k6


官網


我是先看到黑暗執行緒的文章


同步參考 工程良田的小球場 文章


開始進行相關練習


k6 的安裝文件頁


一如往常的, 上面只有 Debian / Ubuntu / Fedora / CentOS / MacOS / Windows / Docker

沒有 openSUSE Leap :p 


這個部份想法上就是朝兩個方向

  • docker

  • snaps


這個部份我用 snaps 來解

參考 https://snapcraft.io/install/k6/opensuse


因為我的 snapd 已經啟動了, 所以直接安裝就可以

  • snapd 安裝與啟動可以直接看剛剛那個頁面


# snap install  k6


k6 v0.48.0 from Thomas Bille (tbmb) installed


確認版本


> k6  version


k6 v0.48.0 (commit/47c0a26798, go1.21.4, linux/amd64)


建立測試檔案

> k6  new


Initialized a new k6 test script in script.js. You can now execute it by running `k6 run script.js`.


觀察 script.js

> cat script.js | egrep  -v  '^//|  //|^$'


import http from 'k6/http';

import { sleep } from 'k6';

export const options = {

  vus: 10,

  duration: '30s',

};

export default function() {

  http.get('https://test.k6.io');

  sleep(1);

}


  • vus: 10 為 10 個虛擬使用者

  • duration: '30s' 為執行 30 秒


執行第一次測試


> k6  run  script.js 


          /\      |‾‾| /‾‾/   /‾‾/   

     /\  /  \     |  |/  /   /  /    

    /  \/    \    |     (   /   ‾‾\  

   /          \   |  |\  \ |  (‾)  | 

  / __________ \  |__| \__\ \_____/ .io


  execution: local

     script: script.js

     output: -


  scenarios: (100.00%) 1 scenario, 10 max VUs, 1m0s max duration (incl. graceful stop):

           * default: 10 looping VUs for 30s (gracefulStop: 30s)



     data_received..................: 2.8 MB 88 kB/s

     data_sent......................: 27 kB  846 B/s

     http_req_blocked...............: avg=19.16ms  min=2.57µs   med=6.42µs   max=467.15ms p(90)=9.51µs   p(95)=15.43µs 

     http_req_connecting............: avg=8.51ms   min=0s       med=0s       max=206.31ms p(90)=0s       p(95)=0s      

     http_req_duration..............: avg=289.35ms min=196.24ms med=211.84ms max=2.19s    p(90)=440.15ms p(95)=476.08ms

       { expected_response:true }...: avg=289.35ms min=196.24ms med=211.84ms max=2.19s    p(90)=440.15ms p(95)=476.08ms

     http_req_failed................: 0.00%  ✓ 0        ✗ 236 

     http_req_receiving.............: avg=11.15ms  min=22.21µs  med=98.35µs  max=247.56ms p(90)=143µs    p(95)=48.3ms  

     http_req_sending...............: avg=28.44µs  min=8.94µs   med=28.24µs  max=65.8µs   p(90)=37.64µs  p(95)=40.2µs  

     http_req_tls_handshaking.......: avg=9.1ms    min=0s       med=0s       max=227.42ms p(90)=0s       p(95)=0s      

     http_req_waiting...............: avg=278.17ms min=196.11ms med=211.27ms max=2.18s    p(90)=417.58ms p(95)=472.78ms

     http_reqs......................: 236    7.514047/s

     iteration_duration.............: avg=1.3s     min=1.19s    med=1.21s    max=3.65s    p(90)=1.46s    p(95)=1.51s   

     iterations.....................: 236    7.514047/s

     vus............................: 4      min=4      max=10

     vus_max........................: 10     min=10     max=10



running (0m31.4s), 00/10 VUs, 236 complete and 0 interrupted iterations

default ✓ [======================================] 10 VUs  30s



接下來透過參數的方式來進行動態調整


> k6  run  script.js  --vus 5



          /\      |‾‾| /‾‾/   /‾‾/   

     /\  /  \     |  |/  /   /  /    

    /  \/    \    |     (   /   ‾‾\  

   /          \   |  |\  \ |  (‾)  | 

  / __________ \  |__| \__\ \_____/ .io


  execution: local

     script: script.js

     output: -


  scenarios: (100.00%) 1 scenario, 5 max VUs, 1m0s max duration (incl. graceful stop):

           * default: 5 looping VUs for 30s (gracefulStop: 30s)



     data_received..................: 1.4 MB 45 kB/s

     data_sent......................: 14 kB  433 B/s

     http_req_blocked...............: avg=25.88ms  min=2.59µs   med=6.41µs   max=624.4ms  p(90)=9.1µs    p(95)=13.31µs 

     http_req_connecting............: avg=11.19ms  min=0s       med=0s       max=268.89ms p(90)=0s       p(95)=0s      

     http_req_duration..............: avg=251.16ms min=197.49ms med=227.5ms  max=532.37ms p(90)=301.99ms p(95)=452.32ms

       { expected_response:true }...: avg=251.16ms min=197.49ms med=227.5ms  max=532.37ms p(90)=301.99ms p(95)=452.32ms

     http_req_failed................: 0.00%  ✓ 0        ✗ 120

     http_req_receiving.............: avg=24.13ms  min=42.7µs   med=103.15µs max=303.15ms p(90)=20.02ms  p(95)=225.54ms

     http_req_sending...............: avg=28.37µs  min=6.93µs   med=27.48µs  max=97.53µs  p(90)=36.44µs  p(95)=38.93µs 

     http_req_tls_handshaking.......: avg=8.88ms   min=0s       med=0s       max=215.67ms p(90)=0s       p(95)=0s      

     http_req_waiting...............: avg=227ms    min=197.31ms med=227.08ms max=291.2ms  p(90)=262.82ms p(95)=268.15ms

     http_reqs......................: 120    3.857656/s

     iteration_duration.............: avg=1.27s    min=1.19s    med=1.22s    max=1.88s    p(90)=1.44s    p(95)=1.53s   

     iterations.....................: 120    3.857656/s

     vus............................: 1      min=1      max=5

     vus_max........................: 5      min=5      max=5



running (0m31.1s), 0/5 VUs, 120 complete and 0 interrupted iterations

default ✓ [======================================] 5 VUs  30s


  • 這邊透過將 --vus 5 將虛擬使用者調整為 5

  • 也可以觀察到相對於上次的測試 這次只有完成 120


接下來再來做一個有趣的實驗


> k6  run  script.js --vus 5 --iterations 15


          /\      |‾‾| /‾‾/   /‾‾/   

     /\  /  \     |  |/  /   /  /    

    /  \/    \    |     (   /   ‾‾\  

   /          \   |  |\  \ |  (‾)  | 

  / __________ \  |__| \__\ \_____/ .io


  execution: local

     script: script.js

     output: -


  scenarios: (100.00%) 1 scenario, 5 max VUs, 10m30s max duration (incl. graceful stop):

           * default: 15 iterations shared among 5 VUs (maxDuration: 10m0s, gracefulStop: 30s)



     data_received..................: 200 kB 43 kB/s

     data_sent......................: 3.2 kB 681 B/s

     http_req_blocked...............: avg=309.45ms min=4.59µs   med=7.42µs   max=930.12ms p(90)=929.12ms p(95)=929.64ms

     http_req_connecting............: avg=71.83ms  min=0s       med=0s       max=215.66ms p(90)=215.6ms  p(95)=215.64ms

     http_req_duration..............: avg=250.7ms  min=222.72ms med=226.56ms max=304.04ms p(90)=302.07ms p(95)=303.06ms

       { expected_response:true }...: avg=250.7ms  min=222.72ms med=226.56ms max=304.04ms p(90)=302.07ms p(95)=303.06ms

     http_req_failed................: 0.00%  ✓ 0        ✗ 15 

     http_req_receiving.............: avg=103.71µs min=42.58µs  med=90.17µs  max=190.48µs p(90)=175.19µs p(95)=179.8µs 

     http_req_sending...............: avg=50.35µs  min=17.1µs   med=34.93µs  max=288.13µs p(90)=55.23µs  p(95)=126.75µs

     http_req_tls_handshaking.......: avg=107.88ms min=0s       med=0s       max=325.32ms p(90)=324.4ms  p(95)=324.92ms

     http_req_waiting...............: avg=250.55ms min=222.58ms med=226.44ms max=303.56ms p(90)=301.98ms p(95)=302.85ms

     http_reqs......................: 15     3.202937/s

     iteration_duration.............: avg=1.56s    min=1.22s    med=1.22s    max=2.23s    p(90)=2.23s    p(95)=2.23s   

     iterations.....................: 15     3.202937/s

     vus............................: 5      min=5      max=5

     vus_max........................: 5      min=5      max=5



running (00m04.7s), 0/5 VUs, 15 complete and 0 interrupted iterations

default ✓ [======================================] 5 VUs  00m04.7s/10m0s  15/15 shared iters


  • script.js 內寫的是 執行 30 秒, 但是我們透過 --iterations 15, 指定執行次數 15 次, 當次數達到的時候, 測試便結束了


初步先這樣, 接下來再來試試看別的東西


~ enjoy it


References