From cd2788bae638fe204e7bce5eaff369171b7dec8d Mon Sep 17 00:00:00 2001 From: Crossplane Date: Thu, 13 Jun 2019 17:41:41 +0000 Subject: [PATCH] docs snapshot for crossplane version `master` --- .../cloud-providers/gcp/gcp-provider.md | 57 ++++++-- docs/master/troubleshoot.md | 2 +- docs/master/workloads/gcp/wordpress-gcp.md | 136 ++++++++++-------- 3 files changed, 122 insertions(+), 73 deletions(-) diff --git a/docs/master/cloud-providers/gcp/gcp-provider.md b/docs/master/cloud-providers/gcp/gcp-provider.md index 941f273c..ba386f0d 100644 --- a/docs/master/cloud-providers/gcp/gcp-provider.md +++ b/docs/master/cloud-providers/gcp/gcp-provider.md @@ -14,29 +14,60 @@ You can choose whichever you are more comfortable with. ## Option 1: gcloud Command Line Tool -If you have the `gcloud` tool installed, you can run below commands from the example directory. -It +If you have the `gcloud` tool installed, you can run the commands below from the crossplane directory. + Instructions for installing `gcloud` can be found in the [Google docs](https://cloud.google.com/sdk/install). +### Using `gcp-credentials.sh` + +In the `cluster/examples` directory you will find a helper script, `gcp-credentials.sh`. This script will prompt you for the organization, project, and billing account that will be used by `gcloud` when creating a project, service account, and credentials file (`crossplane-gcp-provider-key.json`). The chosen project and created service account will have access to the services and roles sufficient to run the Crossplane GCP examples. + +```console +$ cluster/examples/gcp-credentials.sh +... EXAMPLE OUTPUT ONLY +export ORGANIZATION_ID=987654321 +export PROJECT_ID=crossplane-example-1234 +export EXAMPLE_SA=example-1234@crossplane-example-1234.iam.gserviceaccount.com +export BASE64ENCODED_GCP_PROVIDER_CREDS=$(base64 -w0 crossplane-gcp-provider-key.json) +``` + +After running `gcp-credentials.sh`, a series of `export` commands will be shown. Copy and paste the `export` commands that are provided. These variable names will be referenced throughout the Crossplane examples, generally with a `sed` command. + +You will also find a `crossplane-gcp-provider-key.json` file in the current working directory. Be sure to remove this file when you are done with the example projects. + +### Running `gcloud` by hand + ```bash # list your organizations (if applicable), take note of the specific organization ID you want to use # if you have more than one organization (not common) gcloud organizations list -# create a new project -export EXAMPLE_PROJECT_NAME=crossplane-example-123 -gcloud projects create $EXAMPLE_PROJECT_NAME --enable-cloud-apis [--organization ORGANIZATION_ID] +# create a new project (project id must be <=30 characters) +export EXAMPLE_PROJECT_ID=crossplane-example-123 +gcloud projects create $EXAMPLE_PROJECT_ID --enable-cloud-apis # [--organization $ORGANIZATION_ID] -# record the PROJECT_ID value of the newly created project -export EXAMPLE_PROJECT_ID=$(gcloud projects list --filter NAME=$EXAMPLE_PROJECT_NAME --format="value(PROJECT_ID)") +# or, record the PROJECT_ID value of an existing project +# export EXAMPLE_PROJECT_ID=$(gcloud projects list --filter NAME=$EXAMPLE_PROJECT_NAME --format="value(PROJECT_ID)") + +# link billing to the new project +gcloud beta billing accounts list +gcloud beta billing projects link $EXAMPLE_PROJECT_ID --billing-account=$ACCOUNT_ID # enable Kubernetes API gcloud --project $EXAMPLE_PROJECT_ID services enable container.googleapis.com + # enable CloudSQL API -gcloud --project $EXAMPLE_PROJECT_ID services enable sqladmin.googleapis.com +gcloud --project $EXAMPLE_PROJECT_ID services enable sqladmin.googleapis.com + +# enable Redis API +gcloud --project $EXAMPLE_PROJECT_ID services enable redis.googleapis.com + +# enable Additional APIs needed for the example or project +# See `gcloud services list` for a complete list # create service account gcloud --project $EXAMPLE_PROJECT_ID iam service-accounts create example-123 --display-name "Crossplane Example" + # export service account email export EXAMPLE_SA="example-123@$EXAMPLE_PROJECT_ID.iam.gserviceaccount.com" @@ -47,6 +78,7 @@ gcloud --project $EXAMPLE_PROJECT_ID iam service-accounts keys create --iam-acco gcloud projects add-iam-policy-binding $EXAMPLE_PROJECT_ID --member "serviceAccount:$EXAMPLE_SA" --role="roles/iam.serviceAccountUser" gcloud projects add-iam-policy-binding $EXAMPLE_PROJECT_ID --member "serviceAccount:$EXAMPLE_SA" --role="roles/cloudsql.admin" gcloud projects add-iam-policy-binding $EXAMPLE_PROJECT_ID --member "serviceAccount:$EXAMPLE_SA" --role="roles/container.admin" +gcloud projects add-iam-policy-binding $EXAMPLE_PROJECT_ID --member "serviceAccount:$EXAMPLE_SA" --role="roles/redis.admin" ``` ## Option 2: GCP Console in a Web Browser @@ -56,7 +88,7 @@ If you chose to use the `gcloud` tool, you can skip this section entirely. Create a GCP example project which we will use to host our example GKE cluster, as well as our example CloudSQL instance. - Login into [GCP Console](https://console.cloud.google.com) -- Create a new project (either stand alone or under existing organization) +- Create a [new project](https://console.cloud.google.com/flows/enableapi?apiid=container.googleapis.com,sqladmin.googleapis.com,redis.googleapis.com) (either stand alone or under existing organization) - Create Example Service Account - Navigate to: [Create Service Account](https://console.cloud.google.com/iam-admin/serviceaccounts) - `Service Account Name`: type "example" @@ -87,10 +119,13 @@ Create a GCP example project which we will use to host our example GKE cluster, - Enable `Kubernetes Engine API` - Navigate to [Kubernetes Engine API](https://console.developers.google.com/apis/api/container.googleapis.com/overview) - Click `Enable` +- Enable `Cloud Memorystore for Redis` + - Navigate to [Cloud Memorystore for Redis](https://console.developers.google.com/apis/api/redis.googleapis.com/overview) + - Click `Enable` -## Enable Billing +### Enable Billing -No matter what option you chose to configure the previous steps, you will need to enable billing for your account in order to create and use Kubernetes clusters with GKE. +You will need to enable billing for your account in order to create and use Kubernetes clusters with GKE. - Go to [GCP Console](https://console.cloud.google.com) - Select example project diff --git a/docs/master/troubleshoot.md b/docs/master/troubleshoot.md index 05f294f7..01a2fcb4 100644 --- a/docs/master/troubleshoot.md +++ b/docs/master/troubleshoot.md @@ -17,7 +17,7 @@ The first place to look to get more information or investigate a failure would b To get the current Crossplane logs, run the following: ```console -kubectl -n crossplane-system logs $(kubectl -n crossplane-system get pod -l app=crossplane -o jsonpath='{.items[0].metadata.name}') +kubectl -n crossplane-system logs -lapp=crossplane ``` ## Resource Status and Conditions diff --git a/docs/master/workloads/gcp/wordpress-gcp.md b/docs/master/workloads/gcp/wordpress-gcp.md index 9451b3fa..4da58a76 100644 --- a/docs/master/workloads/gcp/wordpress-gcp.md +++ b/docs/master/workloads/gcp/wordpress-gcp.md @@ -17,81 +17,87 @@ You should have a `crossplane-gcp-provider-key.json` file on your local filesyst This section covers the tasks performed by the cluster or cloud administrator, which includes: -- Import GCP provider credentials -- Define Resource classes for cluster and database resources -- Create a target Kubernetes cluster (using dynamic provisioning with the cluster resource class) +* Import GCP provider credentials +* Define Resource classes for cluster and database resources +* Create a target Kubernetes cluster (using dynamic provisioning with the cluster resource class) **Note**: all artifacts created by the administrator are stored/hosted in the `crossplane-system` namespace, which has restricted access, i.e. `Application Owner(s)` should not have access to them. For the next steps, make sure your `kubectl` context points to the cluster where `Crossplane` was deployed. -- Export Project ID - - **NOTE** you can skip this step if you generated GCP Service Account using `gcloud` - ```bash - export DEMO_PROJECT_ID=[your-demo-project-id] - ``` - -- Patch and Apply `provider.yaml`: +* Export Project ID and GCP Provider Credentials: ```bash - sed "s/BASE64ENCODED_CREDS/`cat key.json|base64 | tr -d '\n'`/g;s/DEMO_PROJECT_ID/$DEMO_PROJECT_ID/g" cluster/examples/workloads/wordpress-gcp/provider.yaml | kubectl create -f - + export PROJECT_ID=[your-demo-project-id] + export BASE64ENCODED_GCP_PROVIDER_CREDS=$(base64 -w0 crossplane-gcp-provider-key.json) ``` - - Verify that GCP Provider is in `Ready` state +* Patch and Apply `provider.yaml`: - ```bash - kubectl -n crossplane-system get providers.gcp.crossplane.io -o custom-columns=NAME:.metadata.name,STATUS:'.status.Conditions[?(@.Status=="True")].Type',PROJECT-ID:.spec.projectID - ``` + ```bash + sed "s/BASE64ENCODED_GCP_PROVIDER_CREDS/$BASE64ENCODED_GCP_PROVIDER_CREDS/g;s/PROJECT_ID/$PROJECT_ID/g" cluster/examples/workloads/kubernetes/wordpress-gcp/provider.yaml | kubectl create -f - + ``` - Your output should look similar to: - ```bash - NAME STATUS PROJECT-ID - gcp-provider Ready [your-project-id] - ``` +* Verify that GCP Provider is in `Ready` state - - Verify that Resource Classes have been created + ```bash + kubectl -n crossplane-system get providers.gcp.crossplane.io -o custom-columns=NAME:.metadata.name,STATUS:'.status.Conditions[?(@.Status=="True")].Type',PROJECT-ID:.spec.projectID + ``` - ```bash - kubectl -n crossplane-system get resourceclass -o custom-columns=NAME:metadata.name,PROVISIONER:.provisioner,PROVIDER:.providerRef.name,RECLAIM-POLICY:.reclaimPolicy - ``` + Your output should look similar to: - Your output should be: - ```bash - NAME PROVISIONER PROVIDER RECLAIM-POLICY - standard-cluster gkecluster.compute.gcp.crossplane.io/v1alpha1 gcp-provider Delete - standard-mysql cloudsqlinstance.database.gcp.crossplane.io/v1alpha1 gcp-provider Delete - ``` + ```bash + NAME STATUS PROJECT-ID + gcp-provider Ready [your-project-id] + ``` -- Create a target Kubernetes cluster where `Application Owner(s)` will deploy their `WorkLoad(s)` +* Verify that Resource Classes have been created + + ```bash + kubectl -n crossplane-system get resourceclass -o custom-columns=NAME:metadata.name,PROVISIONER:.provisioner,PROVIDER:.providerRef.name,RECLAIM-POLICY:.reclaimPolicy + ``` + + Your output should be: + + ```bash + NAME PROVISIONER PROVIDER RECLAIM-POLICY + standard-cluster gkecluster.compute.gcp.crossplane.io/v1alpha1 gcp-provider Delete + standard-mysql cloudsqlinstance.database.gcp.crossplane.io/v1alpha1 gcp-provider Delete + ``` + +* Create a target Kubernetes cluster and namespace where `Application Owner(s)` will deploy their `WorkLoad(s)` As administrator, you will create a Kubernetes cluster leveraging the Kubernetes cluster `ResourceClass` that was created earlier and `Crossplane` Kubernetes cluster dynamic provisioning. + The `Application Developer(s)` will use the `complex` namespace. + ```bash - kubectl apply -f cluster/examples/workloads/wordpress-gcp/cluster.yaml + kubectl apply -f cluster/examples/workloads/kubernetes/wordpress-gcp/cluster.yaml ``` - - Verify that Kubernetes Cluster resource was created + * Verify that the Kubernetes Cluster resource was created ```bash - kubectl -n crossplane-system get kubernetescluster -o custom-columns=NAME:.metadata.name,CLUSTERCLASS:.spec.classReference.name,CLUSTERREF:.spec.resourceName.name + kubectl -n complex get kubernetescluster -o custom-columns=NAME:.metadata.name,CLUSTERCLASS:.spec.classReference.name,CLUSTERREF:.spec.resourceName.name ``` Your output should look similar to: + ```bash NAME CLUSTERCLASS CLUSTERREF - demo-gke-cluster standard-cluster gke-67419e79-f5b3-11e8-9cec-9cb6d08bde99 + wordpress-demo-cluster standard-cluster gke-67419e79-f5b3-11e8-9cec-9cb6d08bde99 ``` - - Verify that the target GKE cluster was successfully created + * Verify that the target GKE cluster was successfully created ```bash kubectl -n crossplane-system get gkecluster -o custom-columns=NAME:.metadata.name,STATE:.status.state,CLUSTERNAME:.status.clusterName,ENDPOINT:.status.endpoint,LOCATION:.spec.zone,CLUSTERCLASS:.spec.classRef.name,RECLAIMPOLICY:.spec.reclaimPolicy ``` Your output should look similar to: + ```bash NAME STATE CLUSTERNAME ENDPOINT LOCATION CLUSTERCLASS RECLAIMPOLICY gke-67419e79-f5b3-11e8-9cec-9cb6d08bde99 RUNNING gke-6742fe8d-f5b3-11e8-9cec-9cb6d08bde99 146.148.93.40 us-central1-a standard-cluster Delete @@ -99,36 +105,38 @@ For the next steps, make sure your `kubectl` context points to the cluster where To recap the operations that we just performed as the administrator: -- Defined a `Provider` with Google Service Account credentials -- Defined `ResourceClasses` for `KubernetesCluster` and `MySQLInstance` -- Provisioned (dynamically) a GKE Cluster using the `ResourceClass` +* Defined a `Provider` with Google Service Account credentials +* Defined `ResourceClasses` for `KubernetesCluster` and `MySQLInstance` +* Provisioned (dynamically) a GKE Cluster using the `ResourceClass` in a new namespace named `complex` ## Application Developer Tasks This section covers the tasks performed by the application developer, which includes: -- Define Workload in terms of Resources and Payload (Deployment/Service) which will be deployed into the target Kubernetes Cluster -- Define the dependency resource requirements, in this case a `MySQL` database +* Define Workload in terms of Resources and Payload (Deployment/Service) which will be deployed into the target Kubernetes Cluster +* Define the dependency resource requirements, in this case a `MySQL` database Let's begin deploying the workload as the application developer: -- Deploy workload +* Deploy workload ```bash - kubectl apply -f cluster/examples/workloads/wordpress-gcp/workload.yaml + kubectl apply -f cluster/examples/workloads/kubernetes/wordpress-gcp/app.yaml ``` -- Wait for `MySQLInstance` to be in `Bound` State +* Wait for `MySQLInstance` to be in `Bound` State You can check the status via: + ```bash - kubectl get mysqlinstance -o custom-columns=NAME:.metadata.name,VERSION:.spec.engineVersion,STATE:.status.bindingPhase,CLASS:.spec.classReference.name + kubectl get mysqlinstance -n complex -o custom-columns=NAME:.metadata.name,VERSION:.spec.engineVersion,STATE:.status.bindingPhase,CLASS:.spec.classReference.name ``` Your output should look like: + ```bash NAME VERSION STATE CLASS - demo 5.7 Bound standard-mysql + sql 5.7 Bound standard-mysql ``` **Note**: to check on the concrete resource type status as `Administrator` you can run: @@ -138,26 +146,32 @@ Let's begin deploying the workload as the application developer: ``` Your output should be similar to: + ```bash NAME STATUS CLASS VERSION mysql-2fea0d8e-f5bb-11e8-9cec-9cb6d08bde99 RUNNABLE standard-mysql MYSQL_5_7 ``` -- Wait for `Workload` External IP Address +* Wait for the Wordpress service, a `KubernetesApplicationResource`, to report its External IP Address ```bash - kubectl get workload -o custom-columns=NAME:.metadata.name,CLUSTER:.spec.targetCluster.name,NAMESPACE:.spec.targetNamespace,DEPLOYMENT:.spec.targetDeployment.metadata.name,SERVICE-EXTERNAL-IP:.status.service.loadBalancer.ingress[0].ip + kubectl get kubernetesapplicationresource.workload.crossplane.io -n complex -o custom-columns=NAME:.metadata.name,NAMESPACE:.spec.template.metadata.namespace,KIND:.spec.template.kind,SERVICE-EXTERNAL-IP:.status.remote.loadBalancer.ingress[0].ip ``` - **Note** the `Workload` is defined in Application Owner's (`default`) namespace + + **Note** the `Workload` is defined in Application Owner's (`complex`) namespace Your output should look similar to: + ```bash - NAME CLUSTER NAMESPACE DEPLOYMENT SERVICE-EXTERNAL-IP - demo demo-gke-cluster demo wordpress 35.193.100.113 + NAME NAMESPACE KIND SERVICE-EXTERNAL-IP + wordpress-demo-deployment wordpress Deployment + wordpress-demo-namespace Namespace + wordpress-demo-service wordpress Service 35.232.9.69 ``` -- Verify that `WordPress` service is accessible via `SERVICE-EXTERNAL-IP` by: - - Navigate in your browser to `SERVICE-EXTERNAL-IP` +* Verify that `WordPress` service is accessible via `SERVICE-EXTERNAL-IP`: + + * Navigate in your browser to `SERVICE-EXTERNAL-IP` At this point, you should see the setup page for WordPress in your web browser. @@ -165,25 +179,25 @@ At this point, you should see the setup page for WordPress in your web browser. Once you are done with this example, you can clean up all its artifacts with the following commands: -- Remove `Workload` +* Remove the `App` ```bash - kubectl delete -f cluster/examples/workloads/wordpress-gcp/workload.yaml + kubectl delete -f cluster/examples/workloads/kubernetes/wordpress-gcp/app.yaml ``` -- Remove `KubernetesCluster` +* Remove the `KubernetesCluster` ```bash - kubectl delete -f cluster/examples/workloads/wordpress-gcp/cluster.yaml + kubectl delete -f cluster/examples/workloads/kubernetes/wordpress-gcp/cluster.yaml ``` -- Remove GCP `Provider` and `ResourceClasses` +* Remove the GCP `Provider` and Crossplane `ResourceClasses` ```bash - kubectl delete -f cluster/examples/workloads/wordpress-gcp/provider.yaml + kubectl delete -f cluster/examples/workloads/kubernetes/wordpress-gcp/provider.yaml ``` -- Delete Google Project +* Delete Google Project ```bash # list all your projects