GCP/gcloud cli
Install gcloud
cli
# Ubuntu 18.04 LTS, 20.04; Dec 2021 sudo apt-get install apt-transport-https ca-certificates gnupg # Add the Cloud SDK distribution URI as a package source echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" \ | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list # Import the Google Cloud Platform public key curl https://packages.cloud.google.com/apt/doc/apt-key.gpg \ | sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - # > Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)). # Update the package list and install the Cloud SDK sudo apt-get update && sudo apt-get install google-cloud-sdk # Additional packages are available: # google-cloud-sdk-app-engine-python # google-cloud-sdk-app-engine-python-extras # google-cloud-sdk-app-engine-java # google-cloud-sdk-app-engine-go # google-cloud-sdk-bigtable-emulator # google-cloud-sdk-cbt # google-cloud-sdk-cloud-build-local # google-cloud-sdk-datalab # google-cloud-sdk-datastore-emulator # google-cloud-sdk-firestore-emulator # google-cloud-sdk-pubsub-emulator # kubectl # <- interesting YEAH! # Update your installation gcloud components update sudo apt-get update && sudo apt-get --only-upgrade install google-cloud-sdk-pubsub-emulator google-cloud-sdk-bigtable-emulator google-cloud-sdk-app-engine-grpc google-cloud-sdk-kind google-cloud-sdk-cbt google-cloud-sdk-skaffold google-cloud-sdk-app-engine-java google-cloud-sdk-cloud-build-local google-cloud-sdk-anthos-auth google-cloud-sdk-datastore-emulator google-cloud-sdk-kpt google-cloud-sdk-app-engine-python google-cloud-sdk kubectl google-cloud-sdk-datalab google-cloud-sdk-app-engine-python-extras google-cloud-sdk-minikube google-cloud-sdk-spanner-emulator google-cloud-sdk-firestore-emulator google-cloud-sdk-app-engine-go # gcloud configuration location ls -la ~/.config/gcloud active_config application_default_credentials.json cache config_sentinel configurations # Show current configuration gcloud config list
Initialize and authenticate
Authenticate as a user
# Verify SDK version and connected account & project gcloud info | grep '\(Google\|Account\|Project\)' Google Cloud SDK [315.0.0] Account: [None] Project: [None] # Initialize gcloud init --console-only # console interactive mode gcloud init (...)Go to the following link in your browser: https://accounts.google.com/o/oauth2/auth?client_id=32555940559.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&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%2Fcompute+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Faccounts.reauth&code_challenge=cjLaWdeXW6fY2ux3RITtb4JkOPW477aQsfV_qKhHGDU&code_challenge_method=S256&access_type=offline&response_type=code&prompt=select_account # Set the project defaults ## Compute Engine zone, [17] europe-west1-b gcloud config set compute/zone europe-west1-b ## Compute Engine region gcloud config set compute/region europe-west1
Authenticate as serviceaccount
- GCP Authentication in production using Application Default Credentials (ADC)
Google recommends to use Google Cloud Client Libraries (GCCL) for the applications. Google Cloud Client Libraries use a library called Application Default Credentials (ADC) to automatically find your service account credentials. ADC looks for service account credentials in the following order:
- If the environment variable GOOGLE_APPLICATION_CREDENTIALS is set, ADC uses the service account key or configuration file that the variable points to.
- If the environment variable GOOGLE_APPLICATION_CREDENTIALS isn't set, ADC uses the service account that is attached to the resource that is running your code.
- Create SA credentials for the default `App Engine default service account` and authenticate from gcloud
## Get current project_id export GCP_PROJECT_ID=$(gcloud info --format='value(config.project)'); echo $GCP_PROJECT_ID ## Get the default `App Engine default service account` email export GCP_SA_EMAIL=$(gcloud iam service-accounts list --filter="displayName:App Engine default service account" --format='value(email)'); echo $GCP_SA_EMAIL ## Create a secret key gcloud iam service-accounts keys create ${GCP_SA_EMAIL}.json --iam-account $GCP_SA_EMAIL --project $GCP_PROJECT_ID ## Set SA as a account to be used as a identity when connecting with gcloud cli ACCOUNT=$GCP_SA_EMAIL # inpersonalization gcloud config set account $ACCOUNT # Add SA to gcloud auth export GOOGLE_APPLICATION_CREDENTIALS="KEY_PATH" export GOOGLE_APPLICATION_CREDENTIALS=~/.config/gcloud/legacy_credentials/${GCP_PROJECT_ID}@appspot.gserviceaccount.com/google-service-account.json GCP_SA=$(jq -r .client_email $GOOGLE_APPLICATION_CREDENTIALS); echo $GCP_SA # => "px-platform-dev@appspot.gserviceaccount.com" ## Add/activate SA to be used with gcloud auth gcloud auth activate-service-account $GCP_SA --key-file=$GOOGLE_APPLICATION_CREDENTIALS --project=$GCP_PROJECT_ID # Piotr's secret key path convention export GOOGLE_APPLICATION_CREDENTIALS=~/.config/gcloud/legacy_credentials/${GCP_SA_EMAIL}/${GCP_SA_EMAIL}.json export GOOGLE_APPLICATION_CREDENTIALS=~/.config/gcloud/legacy_credentials/${GCP_SA_EMAIL}/google-service-account.json
Asossiate ServiceAccount with a role
- how-do-i-list-the-roles-associated-with-a-gcp-service-account
- adding-roles-to-service-accounts-on-google-cloud-platform-using-rest-api
# Filter - get roles of a specific service account GCP_PROJECT_ID=acme-dev GCP_SA=serviceaccount-1@${GCP_PROJECT_ID}.iam.gserviceaccount.com gcloud projects get-iam-policy $GCP_PROJECT_ID \ --flatten="bindings[].members" \ --format="table(bindings.role)" \ --filter="bindings.members:$GCP_SA" # Filter - get members of a specific role ROLE=logging.logWriter gcloud projects get-iam-policy $GCP_PROJECT_ID \ --flatten="bindings[].members" \ --format="table(bindings.members)" \ --filter="bindings.role:$ROLE" # Add IAM policy binding for a project (bind a serviceaccount and a project) gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \ --member=serviceAccount:$GCP_SA \ --role=roles/$ROLE ``` = Verify = <source lang=bash> # List accounts whose credentials are stored on the local system: gcloud auth list Credentialed Accounts ACTIVE ACCOUNT * user1@gmail.com # List the properties in your active SDK configuration: gcloud config list [core] account = user1@gmail.com disable_usage_reporting = False project = responsive-sun-123456 # List multiple so called 'named configurations' gcloud config configurations list NAME IS_ACTIVE ACCOUNT PROJECT DEFAULT_ZONE DEFAULT_REGION default True user1@gmail.com responsive-sun-123456 europe-west1-b europe-west1 # View information about your Cloud SDK installation and the active SDK configuration: gcloud info Google Cloud SDK [253.0.0] ... # Verify gcloud project context $ gcloud info | grep '\(Google\|Account\|Project\)' Google Cloud SDK [277.0.0] Account: [user1@gmail.com] Project: [kinetic-physics-111111]
Kubernetes
Install kubectl
from Google
gcloud components install kubectl # Cloud SDK component manager must be enabled
Kubectl authentication in GKE
# Install using "gcloud components install" gcloud components install gke-gcloud-auth-plugin # Install using "apt-get install" for DEB based systems sudo apt-get install google-cloud-sdk-gke-gcloud-auth-plugin ## Pre-reqs sudo apt-get install apt-transport-https ca-certificates gnupg echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo tee /usr/share/keyrings/cloud.google.gpg sudo apt-get update && sudo apt-get install google-cloud-cli # Verify installation gke-gcloud-auth-plugin --version # Run kubectl with the new plugin prior to the release of v1.26 # Set `export USE_GKE_GCLOUD_AUTH_PLUGIN=True` in `~/.bashrc` # Re-create kubeconfig file that uses the auth-plugin gcloud components update gcloud container clusters get-credentials CLUSTER_NAME
Example
apiVersion: v1 clusters: - cluster: certificate-authority-data: DATA+OMITTED proxy-url: http://proxy.example.com:8123 server: https://10.10.10.2 name: gke_projectname_europe-west1_cluster-name contexts: - context: cluster: gke_projectname_europe-west1_cluster-name user: gke_projectname_europe-west1_cluster-name name: gke_projectname_europe-west1_cluster-name current-context: gke_projectname_europe-west1_cluster-name kind: Config preferences: {} users: - name: gke_projectname_europe-west1_cluster-name user: exec: # this auth part has been updated to use the plugin apiVersion: client.authentication.k8s.io/v1beta1 args: null command: gke-gcloud-auth-plugin env: null installHint: Install gke-gcloud-auth-plugin for use with kubectl by following https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke interactiveMode: IfAvailable provideClusterInfo: true
- Issues with the new gke-gcloud-auth-plugin
- (started with k8s 1.22, required in 1.26)
This is caused by gcloud auth activate-service-account --key-file=path/to/key
impersonation of GSA, and it's cached token. Switch to a correct account with:
gcloud config set ACCOUNT [PROJECT]
- if the token has not expired yet delete the authentication cache at
rm ~/.kube/gke_gcloud_auth_plugin_cache
Create GKE cluster
Note: Do not enable cluster-autoscaler --enable-autoscaling
option if you plan to size to zero
Note: GCP GKE release versions
gcloud services enable container.googleapis.com CLUSTER_RELEASE_CHANNEL=regular # stable, rapid -> gcloud container get-server-config CLUSTER_NAME=istio #CLUSTER_VERSION=1.17.12 gcloud container clusters describe $CLUSTER_NAME || gcloud container clusters create $CLUSTER_NAME \ --release-channel $CLUSTER_RELEASE_CHANNEL \ --machine-type=n1-standard-2 \ --min-nodes 3 \ --max-nodes 6 \ --enable-autoscaling \ --enable-network-policy \ --preemptible \ --no-enable-autoupgrade \ --no-enable-autoscaling # --cluster-version=$CLUSTER_VERSION # --preemptible # aka as spot instances, much cheaper but can be terminated at any time # --enable-autoupgrade # this is a default now 2020-11 # Optional. Create your specific 'cluster-admin' user kubectl get clusterrolebinding $(gcloud config get-value core/account)-cluster-admin || kubectl create clusterrolebinding $(gcloud config get-value core/account)-cluster-admin \ --clusterrole=cluster-admin \ --user="$(gcloud config get-value core/account)" # List gcloud container clusters list NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS istio europe-west1-b 1.16.13-gke.401 104.155.45.246 n1-standard-2 1.16.13-gke.401 3 RUNNING # Create/refresh kubeconfig new context entry REGION=europe-west1 gcloud container clusters get-credentials $CLUSTER_NAME --region $REGION # Delete gcloud container clusters delete $CLUSTER_NAME --region $REGION
Scale the cluster
Worker nodes are controlled by one or more node-pools. Scaling it means configuring the min, max and num-nodes parameters.
CLUSTER_NAME=istio gcloud container clusters list NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS istio europe-west1-b 1.17.12-gke.1504 104.199.53.112 n1-standard-2 1.17.12-gke.1504 3 RUNNING gcloud container clusters resize $CLUSTER_NAME --num-nodes 0 --node-pool $NODE_POOL_NAME # --node-pool can be skipped if only one
Update cluster setting
Network policy enforce, will cause rolling nodes update, read more...
gcloud container clusters update istio2 --no-enable-network-policy gcloud container clusters update istio2 --no-enable-stackdriver-kubernetes # default: no-enabled
List available K8s versions for GKE
gcloud container get-server-config # --zone compute-zone Fetching server config for europe-west1-b channels: - channel: RAPID defaultVersion: 1.18.9-gke.2501 validVersions: - 1.18.9-gke.2501 - 1.18.9-gke.1501 - channel: REGULAR defaultVersion: 1.17.12-gke.1504 validVersions: - 1.17.12-gke.1504 - 1.17.12-gke.1501 - channel: STABLE defaultVersion: 1.16.13-gke.401 validVersions: - 1.16.13-gke.403 +more... defaultClusterVersion: 1.16.13-gke.401 defaultImageType: COS validImageTypes: - UBUNTU +more... validMasterVersions: - 1.17.12-gke.2502 +more...
Compute - vm - GKE metadata service
kubectl apply -f <(cat <<EOF apiVersion: v1 kind: Pod metadata: namespace: workload-identity name: gcloud-1 spec: containers: - command: - "sleep" - "infinity" #- "7200" #args: #- "bash" image: google/cloud-sdk:slim #image: google/cloud-sdk:370.0.0-debian_component_based #image: google/cloud-sdk:370.0.0-alpine #image: google/cloud-sdk:372.0.0 #image: bitnami/google-cloud-sdk:0.372.0-debian-10-r0 imagePullPolicy: IfNotPresent name: gcloud restartPolicy: Never serviceAccountName: vault EOF ) --dry-run=server # Test the metadata service (MDS) endpoint curl http://metadata.google.internal/computeMetadata/v1/project/project-id -H "Metadata-Flavor: Google"
Cheatsheet
# Get credentials gcloud container clusters get-credentials mycluster # Delete default limits kubectl delete limits limits
Filters
# Flatten the output to get resource-key gcloud compute regions list --format=flattened
Troubleshooting
gcpdiag is a command-line diagnostics tool for GCP customers.
# Install or run in the Cloud Shell curl https://gcpdiag.dev/gcpdiag.sh >gcpdiag chmod +x gcpdiag ./gcpdiag lint --project=MYPROJECT ./gcpdiag lint --project=MYPROJECT --include gke ./gcpdiag lint --project=MYPROJECT --include gke --include-extended # may generate false positives