Published
- 4 min read
มาลองสร้าง Cloud Workstations โดยใช้ gcloud CLI กัน
เปิด blog ครั้งแรกก็ขออธิบาย steps สั้นๆ เกี่ยวกับการสร้าง Cloud Workstations เพื่อที่จะมาช่วยในการทำงานบน Google Cloud แทนการไป develop ที่ local machine ของตัวเองกันครับ
ประโยชน์ในการใช้ Cloud Workstations คือ บุคคลภายนอกจะไม่สามารถเข้ามาในเครื่อง VM ที่เรากำลังทำงานอยู่ได้ ยกเว้นแต่เพื่อนร่วมงานในบริษัทที่มีสิทธิ์ IAM policies ในการเข้าถึง Workstation นั้นๆ ครับ
ซึ่งเหมาะมากที่จะใช้เครื่อง VM ที่ถูก Cloud Workstations provision เครื่องขึ้นในการทำงานในสภาพแวดล้อมที่ปิดตัวไม่ให้คนนอกเข้าถึง และช่วยในการทำงานในระบบที่ root user ต้องการ run คำสั่ง gcloud บนเครื่อง VM แทนที่จะเป็นเครื่องคอมของตัวเอง เช่น เราอาจเก็บ source code shell scripts ต่างๆ ไว้บน Github ที่เป็น private repository ที่มีแต่เราที่เขาถึงได้คนเดียว (ซึ่งมันก็แล้วแต่ permissions ที่ตั้งไว้ เราอาจจะแชร์คนในทีมให้มีสิทธิ์ IAM เข้าเครื่อง VM อย่างเดียว แต่ไม่ต้องมีสิทธิ์ที่ Github ก็ได้ครับ)
ซึ่งโดย steps การที่เราจะไปถึงตรงนั้นได้เราก็ต้องเริ่มจากการสร้าง project บน GCP ก่อนครับ โดยผมจะเรียง steps ไว้ตามนี้เลย
#!/bin/bash
echo "#### START ####"
echo "#### CREATE PROJECT ####" &&
. ./local/create-project.sh > /dev/null 2>&1 &&
echo "#### WAITING FOR PROJECT INITIALIZATION... ####" &&
sleep 60 &&
echo "#### SET GCLOUD CONFIG ####" &&
. ./local/set-gcloud-config.sh > /dev/null 2>&1 &&
echo "#### LINK BILLING ACCOUNT ####" &&
. ./local/link-billing-account.sh > /dev/null 2>&1 &&
echo "#### CREATE SERVICE ACCOUNT ####" &&
. ./local/create-service-account.sh > /dev/null 2>&1 &&
echo "#### DOWNLOAD SERVICE ACCOUNT ####" &&
. ./local/download-service-account.sh > /dev/null 2>&1 &&
echo "#### CREATE NETWORK ####" &&
. ./local/create-temp-network.sh > /dev/null 2>&1 &&
echo "#### CREATE FIREWALL ####" &&
. ./local/create-temp-firewall.sh > /dev/null 2>&1 &&
echo "#### CREATE NAT GATEWAY USING CLOUD ROUTER ####" &&
. ./local/create-nat-gateway-using-cloud-router.sh > /dev/null 2>&1 &&
echo "#### CREATE CLOUD WORKSTATION ####" &&
. ./local/create-cloud-workstation.sh > /dev/null 2>&1 &&
echo "#### DONE ####"
ต่อมาจะขอแปะคำสั่งของแต่ script เรียงลงไปนะครับ (ต้องไปแก้ variable ที่อยู่ใน script เอง)
ปล. ผมทำ environment variable เป็น script ตัวกลางในการที่ script อื่นๆ จะสามารถดึงไปใช้ได้นะครับ
create-project.sh
#!/bin/bash
. $(pwd)/../base/env-vars.sh
gcloud projects create $GCP_PROJECT --name=$GCP_PROJECT_DES_NAME
set-gcloud-config.sh
#!/bin/bash
. $(pwd)/../base/env-vars.sh
# Set GCP default project
gcloud config set project $GCP_PROJECT
# Set GCP default zone
yes | gcloud config set compute/zone $GCP_ZONE
# Enable APIs
yes | gcloud services enable compute.googleapis.com &&
yes | gcloud services enable workstations.googleapis.com &&
yes | gcloud services enable container.googleapis.com &&
yes | gcloud services enable secretmanager.googleapis.com &&
sleep 120 && echo "Enabled APIs!"
link-billing-account.sh
#!/bin/bash
. $(pwd)/../base/env-vars.sh
# Link billing account
gcloud billing projects link $GCP_PROJECT \
--billing-account=$(gcloud billing accounts list | awk 'NR > 1 {print $1}')
create-service-account.sh
#!/bin/bash
. $(pwd)/../base/env-vars.sh
# https://pnatraj.medium.com/how-to-run-gcloud-command-line-using-a-service-account-f39043d515b9
gcloud iam service-accounts create $GCP_SERVICE_ACCOUNT_NAME
gcloud projects add-iam-policy-binding $GCP_PROJECT --member serviceAccount:$GCP_SERVICE_ACCOUNT_FULL_NAME --role "roles/owner"
download-service-account.sh
#!/bin/bash
. $(pwd)/../base/env-vars.sh
gcloud iam service-accounts keys create ./creds.json --iam-account $GCP_SERVICE_ACCOUNT_FULL_NAME
create-temp-network.sh
#!/bin/bash
. $(pwd)/../base/env-vars.sh
# Create a network
gcloud compute networks create $GKE_NETWORK_NAME \
--subnet-mode custom
# Create a subnet and secondary range
gcloud compute networks subnets create $GKE_SUBNET_NAME \
--region $GCP_REGION \
--network $GKE_NETWORK_NAME \
--range 192.168.0.0/20 \
--secondary-range $GKE_CLUSTER_SECONDARY_RANGE_NAME=10.4.0.0/14,$GKE_SERVICES_SECONDARY_RANGE_NAME=10.0.32.0/20 \
--enable-private-ip-google-access
create-temp-firewall.sh (ตามหลัก best practice ก็อย่า allow เป็น public อย่างนี้นะครับ ให้เรา allow IP ของ VPN แทน)
#!/bin/bash
. $(pwd)/../base/env-vars.sh
# Create firewall rules
gcloud compute firewall-rules create $GKE_FIREWALL_ALLOW_SSH_RULES_NAME \
--network $GKE_NETWORK_NAME \
--source-ranges 0.0.0.0/0 \
--allow tcp:22
gcloud compute firewall-rules create $GKE_FIREWALL_ALLOW_HTTP_RULES_NAME \
--network $GKE_NETWORK_NAME \
--source-ranges 0.0.0.0/0 \
--allow tcp:80
gcloud compute firewall-rules create $GKE_FIREWALL_ALLOW_HTTPS_RULES_NAME \
--network $GKE_NETWORK_NAME \
--source-ranges 0.0.0.0/0 \
--allow tcp:443
gcloud compute firewall-rules create $FIREWALL_ALLOW_ROOT_CA_NAME \
--direction INGRESS \
--priority 1000 \
--network $GKE_NETWORK_NAME \
--action ALLOW \
--rules all \
--source-service-accounts $GCP_SERVICE_ACCOUNT_FULL_NAME
create-nat-gateway-using-cloud-router.sh
#!/bin/bash
. $(pwd)/../base/env-vars.sh
# Create Cloud Router
gcloud compute routers create $GKE_NAT_CLOUD_ROUTER_NAME \
--network $GKE_NETWORK_NAME_FULL_PATH \
--region $GCP_REGION \
--async
# Add a configuration to the router
gcloud compute routers nats create $GKE_NAT_GATEWAY_NAME \
--router-region $GCP_REGION \
--router $GKE_NAT_CLOUD_ROUTER_NAME \
--nat-all-subnet-ip-ranges \
--no-enable-dynamic-port-allocation \
--enable-endpoint-independent-mapping \
--udp-idle-timeout 30s \
--tcp-established-idle-timeout 1200s \
--tcp-transitory-idle-timeout 30s \
--icmp-idle-timeout 30s \
--tcp-time-wait-timeout 120s \
--no-enable-logging \
--auto-allocate-nat-external-ips \
--async
create-cloud-workstation.sh
#!/bin/bash
. $(pwd)/../base/env-vars.sh
# Create Workstation cluster
gcloud workstations clusters create $WORKSTATION_CLUSTER_NAME \
--labels=workstation=$CONTROL_PLANE_NAME \
--region=$GCP_REGION \
--network=$GKE_NETWORK_NAME_FULL_PATH \
--subnetwork=$GKE_SUBNET_NAME_FULL_PATH
# Create Workstation config
gcloud workstations configs create $WORKSTATION_CONFIG_NAME \
--labels=workstation=$CONTROL_PLANE_NAME \
--network-tags=$GKE_NETWORK_NAME \
--cluster=$WORKSTATION_CLUSTER_NAME \
--region=$GCP_REGION \
--replica-zones=asia-southeast1-b,asia-southeast1-a
--machine-type=e2-standard-4 \
--container-predefined-image=codeoss \
--pd-disk-type=pd-standard \
--pd-disk-size=200 \
--pd-reclaim-policy=delete \
--pool-size=0 \
--idle-timeout=7200 \
--service-account="$GCP_SERVICE_ACCOUNT_FULL_NAME"
# Create Workstation
gcloud workstations create $WORKSTATION_NAME \
--cluster=$WORKSTATION_CLUSTER_NAME \
--config=$WORKSTATION_CONFIG_NAME \
--region=$GCP_REGION \
--labels=workstation=$CONTROL_PLANE_NAME
ผลลัพธ์ก็จะออกมาหน้าตาประมาณนี้ครับ
ต่อไปเราก็กดปุ่ม Start แล้วรอ Launch เครื่อง VM กันเลย แต่อาจจะรอนานหน่อยเพราะผมกำหนด Workstation configurations เป็นแบบ cost saving นะครับ (disabled quick start workstations)
พอรันขึ้นมาก็จะได้หน้าตาเครื่องทำงานบน Cloud ประมาณนี้ครับ (โดยทาง Google เลือก Code OSS ให้เป็น base editor นะครับ)
ส่วนนี่ก็จะเป็น Workstation Configuration กับ Workstation Cluster ที่เรา configure ให้มัน provision ขึ้นมาตามที่ได้กำหนดไปครับ
ทั้งหมดทั้งมวลก็น่าจะประมาณนี้ครับ ซึ่งบทความต่อไปน่าจะเป็นเกี่ยวกับเรื่อง Ingress-Nginx กับ ArgoCD และการใช้ cert manager บน GKE cluster ครับ
Ref: https://cloud.google.com/workstations/docs/quickstart-set-up-workstations-console