7.6 KiB
Deploying a WordPress Workload on GCP
This guide will walk you through how to use Crossplane to deploy a stateful workload in a portable way to GCP. In this environment, the following components will be dynamically provisioned and configured during this guide:
- GKE Kubernetes cluster
- CloudSQL database
- WordPress application
Pre-requisites
Before starting this guide, you should have already configured your GCP account for usage by Crossplane.
You should have a crossplane-gcp-provider-key.json
file on your local filesystem, preferably at the root of where you cloned the Crossplane repo.
Administrator Tasks
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)
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 and GCP Provider Credentials:
export PROJECT_ID=[your-demo-project-id] export BASE64ENCODED_GCP_PROVIDER_CREDS=$(base64 crossplane-gcp-provider-key.json | tr -d "\n")
-
Patch and Apply
provider.yaml
: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 -
-
Verify that GCP Provider is in
Ready
statekubectl -n crossplane-system get providers.gcp.crossplane.io -o custom-columns=NAME:.metadata.name,STATUS:'.status.Conditions[?(@.Status=="True")].Type',PROJECT-ID:.spec.projectID
Your output should look similar to:
NAME STATUS PROJECT-ID gcp-provider Ready [your-project-id]
-
Verify that Resource Classes have been created
kubectl -n crossplane-system get resourceclass -o custom-columns=NAME:metadata.name,PROVISIONER:.provisioner,PROVIDER:.providerReference.name,RECLAIM-POLICY:.reclaimPolicy
Your output should be:
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 theirWorkLoad(s)
As administrator, you will create a Kubernetes cluster leveraging the Kubernetes cluster
ResourceClass
that was created earlier andCrossplane
Kubernetes cluster dynamic provisioning.The
Application Developer(s)
will use thecomplex
namespace.kubectl apply -f cluster/examples/workloads/kubernetes/wordpress-gcp/cluster.yaml
-
Verify that the Kubernetes Cluster resource was created
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:
NAME CLUSTERCLASS CLUSTERREF wordpress-demo-cluster standard-cluster gke-67419e79-f5b3-11e8-9cec-9cb6d08bde99
-
Verify that the target GKE cluster was successfully created
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:
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
-
To recap the operations that we just performed as the administrator:
- Defined a
Provider
with Google Service Account credentials - Defined
ResourceClasses
forKubernetesCluster
andMySQLInstance
- Provisioned (dynamically) a GKE Cluster using the
ResourceClass
in a new namespace namedcomplex
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
Let's begin deploying the workload as the application developer:
-
Deploy workload
kubectl apply -f cluster/examples/workloads/kubernetes/wordpress-gcp/app.yaml
-
Wait for
MySQLInstance
to be inBound
StateYou can check the status via:
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:
NAME VERSION STATE CLASS sql 5.7 Bound standard-mysql
Note: to check on the concrete resource type status as
Administrator
you can run:kubectl -n crossplane-system get cloudsqlinstance -o custom-columns=NAME:.metadata.name,STATUS:.status.state,CLASS:.spec.classRef.name,VERSION:.spec.databaseVersion
Your output should be similar to:
NAME STATUS CLASS VERSION mysql-2fea0d8e-f5bb-11e8-9cec-9cb6d08bde99 RUNNABLE standard-mysql MYSQL_5_7
-
Wait for the Wordpress service, a
KubernetesApplicationResource
, to report its External IP Addresskubectl 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 (complex
) namespaceYour output should look similar to:
NAME NAMESPACE KIND SERVICE-EXTERNAL-IP wordpress-demo-deployment wordpress Deployment <none> wordpress-demo-namespace <none> Namespace <none> wordpress-demo-service wordpress Service 35.232.9.69
-
Verify that
WordPress
service is accessible viaSERVICE-EXTERNAL-IP
:- Navigate in your browser to
SERVICE-EXTERNAL-IP
- Navigate in your browser to
At this point, you should see the setup page for WordPress in your web browser.
Clean Up
Once you are done with this example, you can clean up all its artifacts with the following commands:
-
Remove the
App
kubectl delete -f cluster/examples/workloads/kubernetes/wordpress-gcp/app.yaml
-
Remove the
KubernetesCluster
kubectl delete -f cluster/examples/workloads/kubernetes/wordpress-gcp/cluster.yaml
-
Remove the GCP
Provider
and CrossplaneResourceClasses
kubectl delete -f cluster/examples/workloads/kubernetes/wordpress-gcp/provider.yaml
-
Delete Google Project
# list all your projects gcloud projects list # delete demo project gcloud projects delete [demo-project-id]