GCP/gcloud cli

From Ever changing code
< GCP
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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


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:

  1. If the environment variable GOOGLE_APPLICATION_CREDENTIALS is set, ADC uses the service account key or configuration file that the variable points to.
  2. 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

# 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

References