all gcloud compute commands fails - Invalid value for project: myproject - google-compute-engine

I'm just starting to play with Google Compute Engine. I can create instances using the web interface, but nothing works from the console:
gcloud compute instances create example-instance \
> --machine-type n1-standard-1 \
> --image debian-7 \
> --zone europe-west1-b
ERROR: (gcloud.compute.instances.create) Failed to find image for alias [debian-7] in public image project [debian-cloud].
- Invalid value for project: myproject
It looks like the image is available.
$ gcloud compute images list --project debian-cloud --no-standard-images
NAME PROJECT ALIAS DEPRECATED STATUS
backports-debian-7-wheezy-v20150929 debian-cloud debian-7-backports READY
beta-accounts-backports-debian-7-wheezy-v20150930 debian-cloud READY
beta-accounts-debian-8-jessie-v20150930 debian-cloud READY
debian-7-wheezy-v20150929 debian-cloud debian-7 READY
debian-8-jessie-v20150929 debian-cloud debian-8 READY
ERROR: (gcloud.compute.images.list) Some requests did not succeed:
- Invalid value for project: myproject
I get an - Invalid value for project: myproject message for almost every gcloud command I try.
I can see myproject when I visit https://console.developers.google.com/project?authuser=1
And from the console:
$ gcloud config list project
[core]
project = myproject
What should I do to fix this?

My mistake.
I mixed project_name and project_id.
$ gcloud config set project PROJECT_ID #(not project name)

Related

Cannot push image to OCR container repository - unknown: Tenant with namespace - not found

I am trying to push an image to OCR within my 'training' compartment but docker returns with message: "unknown: Tenant with namespace training not found"
The compartment is there:
oci iam compartment list --all --output table --compartment-id-in-subtree true --query "data [?\"lifecycle-state\" =='ACTIVE'].{Name:name}" | grep training
| training |
Create repository 'ocr1'
export DISPLAY_NAME=ocr1
oci artifacts container repository create \
--compartment-id $C \
--is-public false \
--display-name $DISPLAY_NAME
Docker login
cat token | docker login fra.ocir.io --username=${NS}/api.user --password-stdin
Login Succeeded
Tag image and push
docker pull alpine:latest
docker tag alpine:latest fra.ocir.io/training/ocr1/alpine:latest
docker push fra.ocir.io/training/ocr1/alpine:latest
The push refers to repository [fra.ocir.io/training/ocr1/alpine]
7cd52847ad77: Retrying in 1 second
unknown: Tenant with namespace training not found
I am only able to push to root compartment ... (not what I want)
docker tag alpine:latest fra.ocir.io/$NS/ocr1/alpine:latest
docker push fra.ocir.io/$NS/ocr1/alpine:latest
The push refers to repository [fra.ocir.io/<NS>/ocr1/alpine]
7cd52847ad77: Layer already exists
latest: digest: sha256:e2e16842c9b54d985bf1ef9242a313f36b856181f188de21313820e177002501 size: 528
Why can't I push to a given compartment?
Thank you
I'm guessing you may be experiencing a permissions issue. Admins have more permissions in root than in a net new compartment where you need to specify access policies. Is this doc helpful?
https://docs.oracle.com/en-us/iaas/Content/Registry/Concepts/registrypolicyrepoaccess.htm

openshift error unknown flag: --ssh-privatekey

I am trying to generate an secrete for a private repo on openshift. But I keep getting this error any idea why?
oc secrets new-sshauth sshsecret --ssh-privatekey=C:\Users\Name\.ssh\id_rsa
Error: unknown flag: --ssh-privatekey
See 'oc create --help' for usage.
according to the documentation
I need to do this
oc secrets new-sshauth sshsecret --ssh-privatekey=$HOME/.ssh/id_rsa
You can create ssh private key type secrets in OpenShift with this way
First generate your SSH key if you dont have one with the following command
$ ssh-keygen -t rsa -C "your_email#example.com"
Then you can create a secret in your openshift project with the following command
oc create secret generic <secret_name> \
--from-file=ssh-privatekey=<path/to/ssh/private/key> \
--type=kubernetes.io/ssh-auth -n <youropenshiftprojectname>

OpenShift deploy an application from private registry by using "oc new pp" command

In OpenShift, I want to deploy application by using docker image which its location is on the private docker registry. To do this I have written the following command from terminal by using OpenShift Container Platform Command Line Interface (oc CLI)
oc new-app --docker-image=myregistry.com/mycompany/myimage --name=private --insecure-registry=true
I received an error which type is 407 proxy authentication when I run the above command. Because, To pull the image from my private registry need to authentication. I have a secret for this authentication, too, but I don't know how can add the secret to above command.
Could you help me, please? or another way ...
Finally, I could have solved. The problem is lack of steps while creating secret for private docker registry. The all steps are:
1) If you do not already have a Docker credentials file for the secured registry, you can create a secret by running:
$ oc create secret docker-registry <pull_secret_name> \
--docker-server=<registry_server> \
--docker-username=<user_name> \
--docker-password=<password> \
--docker-email=<email>
2) To use a secret for pulling images for Pods, you must add the secret to your service account:
$ oc secrets link default <pull_secret_name> --for=pull
3) To use a secret for pushing and pulling build images, the secret must be mountable inside of a Pod. You can do this by running:
$ oc secrets link builder <pull_secret_name>
https://docs.openshift.com/container-platform/4.1/openshift_images/managing-images/using-image-pull-secrets.html

jdbc driver does not work in kubernetes, fails with timeout

I have a java 11 app with jdbc driver running together with mysql 8.0, the app is able to connect to mysql and execute one sql, but it looks like it never gets a response back?
It looks like a connectivity issue.
At first it'd be good to look at the Java program output.
First simple checks are at the Kubernetes level to ensure that key components are alive:
$ kubectl get deployments
$ kubectl get services
$ kubectl get pods
Additional checks could be done from within the container where your Java app is running.
A possible approach is below.
List deployments of your app and their labels:
$ kubectl get deployments --show-labels
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
hello-node 2/2 2 2 1h app=hello-node
Having got the label, you can list the relevant pods and their containers:
$ LABEL=hello-node; kubectl get pods -l app=$LABEL -o custom-columns=POD:metadata.name,CONTAINER:spec.containers[*].name
POD CONTAINER
hello-node-55b49fb9f8-7tbh4 hello-node
hello-node-55b49fb9f8-p7wt6 hello-node
Now it's possible to run basic diagnostic commands from within the Java app container.
Ping might not achieve the target but is available almost always in container and does primitive check of DNS resolution.
Services from the same namespace should be available via short DNS name.
Services from other namespaces inside of the same Kubernetes cluster should be available via internal FQDN.
$ kubectl exec hello-node-55b49fb9f8-p7wt6 -c hello-node -- ping -c1 hello-node
$ kubectl exec hello-node-55b49fb9f8-p7wt6 -c hello-node -- ping -c1 hello-node.default.svc.cluster.local
$ kubectl exec hello-node-55b49fb9f8-p7wt6 -c hello-node -- mysql -u [username] -p [dbname] -e [query]
From here on the connectivity diagnostics is pretty similar to the bare-metal server except the fact that you are limited by the tools available inside of container. You might install missing packages into the container as needed.
As soon as you obtain more diagnostic information, you'll get a clue what to check next.

How to make GCE instance stop when its deployed container finishes?

I have a Docker container that performs a single large computation. This computation requires lots of memory and takes about 12 hours to run.
I can create a Google Compute Engine VM of the appropriate size and use the "Deploy a container image to this VM instance" option to run this job perfectly. However once the job is finished the container quits but the VM is still running (and charging).
How can I make the VM exit/stop/delete when the container exits?
When the VM is in its zombie mode only the stackdriver containers are left running:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bfa2feb03180 gcr.io/stackdriver-agents/stackdriver-logging-agent:0.2-1.5.33-1-1 "/entrypoint.sh /u..." 17 hours ago Up 17 hours stackdriver-logging-agent
161439a487c2 gcr.io/stackdriver-agents/stackdriver-metadata-agent:0.2-0.0.17-2 "/bin/sh -c /opt/s..." 17 hours ago Up 17 hours 8000/tcp stackdriver-metadata-agent
I create the VM like this:
gcloud beta compute --project=abc instances create-with-container vm-name \
--zone=us-central1-c --machine-type=custom-1-65536-ext \
--network=default --network-tier=PREMIUM --metadata=google-logging-enabled=true \
--maintenance-policy=MIGRATE \
--service-account=xyz \
--scopes=https://www.googleapis.com/auth/cloud-platform \
--image=cos-stable-69-10895-71-0 --image-project=cos-cloud --boot-disk-size=10GB \
--boot-disk-type=pd-standard --boot-disk-device-name=vm-name \
--container-image=gcr.io/abc/my-image --container-restart-policy=on-failure \
--container-command=python3 \
--container-arg="a" --container-arg="b" --container-arg="c" \
--labels=container-vm=cos-stable-69-10895-71-0
When you create the VM, you'll need to give it write access to compute so you can delete the instance from within. You should also set container environment variables like gce_zone and gce_project_id at this time. You'll need them to delete the instance.
gcloud beta compute instances create-with-container {NAME} \
--container-env=gce_zone={ZONE},gce_project_id={PROJECT_ID} \
--service-account={SERVICE_ACCOUNT} \
--scopes=https://www.googleapis.com/auth/compute,...
...
Then within the container, whenever YOU determine your task is finished:
request an api token (im using curl for simplicity and DEFAULT gce service account)
curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google"
This will respond with json that looks like
{
"access_token": "foobarbaz...",
"expires_in": 1234,
"token_type": "Bearer"
}
Take that access token and hit the instances.delete api endpoint (notice the environment variables)
curl -XDELETE -H 'Authorization: Bearer {TOKEN}' https://www.googleapis.com/compute/v1/projects/$gce_project_id/zones/$gce_zone/instances/$HOSTNAME
Having grappled with the problem for some time, here's a full solution that works pretty well.
This solution doesn't use the "start machine with a container image" option. Instead it uses a startup script, which is more flexible. You still use a Container-Optimized OS instance.
Create a startup script:
#!/usr/bin/env bash
# get image name and container parameters from the metadata
IMAGE_NAME=$(curl http://metadata.google.internal/computeMetadata/v1/instance/attributes/image_name -H "Metadata-Flavor: Google")
CONTAINER_PARAM=$(curl http://metadata.google.internal/computeMetadata/v1/instance/attributes/container_param -H "Metadata-Flavor: Google")
# This is needed if you are using a private images in GCP Container Registry
# (possibly also for the gcp log driver?)
sudo HOME=/home/root /usr/bin/docker-credential-gcr configure-docker
# Run! The logs will go to stack driver
sudo HOME=/home/root docker run --log-driver=gcplogs ${IMAGE_NAME} ${CONTAINER_PARAM}
# Get the zone
zoneMetadata=$(curl "http://metadata.google.internal/computeMetadata/v1/instance/zone" -H "Metadata-Flavor:Google")
# Split on / and get the 4th element to get the actual zone name
IFS=$'/'
zoneMetadataSplit=($zoneMetadata)
ZONE="${zoneMetadataSplit[3]}"
# Run compute delete on the current instance. Need to run in a container
# because COS machines don't come with gcloud installed
docker run --entrypoint "gcloud" google/cloud-sdk:alpine compute instances delete ${HOSTNAME} --delete-disks=all --zone=${ZONE}
Put the script somewhere public. For example put it on Cloud Storage and create a public URL. You can't use a gs:// URI for a COS startup script.
Start an instance using a startup-script-url, and passing the image name and parameters, e.g.:
gcloud compute --project=PROJECT_NAME instances create INSTANCE_NAME \
--zone=ZONE --machine-type=TYPE \
--metadata=image_name=IMAGE_NAME,\
container_param="PARAM1 PARAM2 PARAM3",\
startup-script-url=PUBLIC_SCRIPT_URL \
--maintenance-policy=MIGRATE --service-account=SERVICE_ACCUNT \
--scopes=https://www.googleapis.com/auth/cloud-platform --image-family=cos-stable \
--image-project=cos-cloud --boot-disk-size=10GB --boot-disk-device-name=DISK_NAME
(You probably want to limit the scopes, the example uses full access for simplicity)
I wrote a self-contained Python function based on Vincent's answer.
def kill_vm():
"""
If we are running inside a GCE VM, kill it.
"""
# based on https://stackoverflow.com/q/52748332/321772
import json
import logging
import requests
# get the token
r = json.loads(
requests.get("http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token",
headers={"Metadata-Flavor": "Google"})
.text)
token = r["access_token"]
# get instance metadata
# based on https://cloud.google.com/compute/docs/storing-retrieving-metadata
project_id = requests.get("http://metadata.google.internal/computeMetadata/v1/project/project-id",
headers={"Metadata-Flavor": "Google"}).text
name = requests.get("http://metadata.google.internal/computeMetadata/v1/instance/name",
headers={"Metadata-Flavor": "Google"}).text
zone_long = requests.get("http://metadata.google.internal/computeMetadata/v1/instance/zone",
headers={"Metadata-Flavor": "Google"}).text
zone = zone_long.split("/")[-1]
# shut ourselves down
logging.info("Calling API to delete this VM, {zone}/{name}".format(zone=zone, name=name))
requests.delete("https://www.googleapis.com/compute/v1/projects/{project_id}/zones/{zone}/instances/{name}"
.format(project_id=project_id, zone=zone, name=name),
headers={"Authorization": "Bearer {token}".format(token=token)})
A simple atexit hook gets me my desired behavior:
import atexit
atexit.register(kill_vm)
Another solution is to not use GCE and instead use AI Platform's custom job service, which automatically shuts down the VM after the Docker container exits.
gcloud ai-platform jobs submit training $JOB_NAME \
--region $REGION \
--master-image-uri $IMAGE_URI
You can specify --master-machine-type.
See the GCP documentation on custom containers.
The simplest way, from within the container, once it's finished:
ZONE=`gcloud compute instances list --filter="name=($HOSTNAME)" --format 'csv[no-heading](zone)'`
gcloud compute instances delete $HOSTNAME --zone=$ZONE -q
-q skips the interactive confirmation
$HOSTNAME is already exported
Just use curl and the local metadata server (no need for Python scripts or gcloud). Add the following to the end of your Docker Entrypoint script, so it's run when the container finishes:
# Note: inside the container the name is exposed as $HOSTNAME
INSTANCE_NAME=$(curl -sq "http://metadata.google.internal/computeMetadata/v1/instance/name" -H "Metadata-Flavor: Google")
INSTANCE_ZONE=$(curl -sq "http://metadata.google.internal/computeMetadata/v1/instance/zone" -H "Metadata-Flavor: Google")
echo "Terminating instance [${INSTANCE_NAME}] in zone [${INSTANCE_ZONE}}"
TOKEN=$(curl -sq "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google" | jq -r '.access_token')
curl -X DELETE -H "Authorization: Bearer ${TOKEN}" https://www.googleapis.com/compute/v1/$INSTANCE_ZONE/instances/$INSTANCE_NAME
For security sake, and Principle of Least Privilege, you can run the VM with a custom service account, and give that service account a role, with this permission (a custom role is best).
compute.instances.delete