Note:     
Platform GUI exmaple: PCF Apps Manager UI                
## Elastic Runtime Components/Architecture
* **Go Router**: The HTTP server that responds to all incoming traffic (CF CLI requests, request to apps, etc). It maintains a dynamic routing table constructed from information it receives from NATS.
* **Consul**: Service discovery service, it acts like a DNS service so CF components can find eachother using hard-coded internal hostnames.

### Elastic Runtime Subsystems:
#### **Cloud Controller API**
The Cloud Foundry API. managing the ER. All CF CLI requests are handled by it, allowing you to deploy your app and manage your system.
* **CC_DB**: Cloud Controller Database where the CC persists Org/Space/App data.
* **Blob Store**: The place where CC persists app packages and droplets; it’s a means to optimise the system so that you don’t have to do those tasks over and over again.
* **CC-Bridge**: The place where app specific messages/domain are translated into Diego tasks & LRPs generic language.
#### **Diego**
The container scheduling subsystem of CF. It schedules tasks and long-running processes (LRPs); these are run within an immutable container (once it gets created it won’t get changed). The API handles communication between Diego and the Cloud Controller and the Cells run the application containers.

- `Task` = app guaranteed to run at most once (e.g.: a PCF example is staging an app)
- `LRP` = web app that can have multiple instances
Containers are run within a `cell` = an OS.
PCF has a pool of cells, many VMs are of type cell and your app instances get distributed across those.
* Containers are managed by **Garden** = an interface with many diff backends, like Linux or Windows, to support diff types of platforms.
* **Rep**: The process running on the cell continuously reporting what is going on on a cell. It represents the cell in the `BBS`/`auctions`.
- An `auction` = is held to bid on executing a task or LRP
* **Executor**: Rep subprocess that manages container allocations on the cell; it also streams `stdout` and `stderr` to `Metron`.
* **Metron**: Process living on the cell and forwarding logs to the Loggregator susbsytem.
* **BBS (Bulletin Board System)**: The API to access the Diego DB for tasks and LRPs; data is persisted to `etcd`.
* **etcd database**: The Diego database for BBS tasks and LRPs.
* **Brain**: Main unit responsible for holding the auction, composed of 2 subprocesses:
- `Auctioneer` = holds auctions for tasks and LRPs
- `Converger` = reconciles desired LRPs vs actual LRPs through auctions
* **UAA**: User Account and Authentication. Various requests (login credentials, OAuth tokens, etc.) are authenticated against the UAA.
#### **Loggregator**
The logging subsystem consists of multiple VMs such as the `Doppler`, `Adapter`, `Log-api` and the `Scheduler`. Various parts of this system handle collecting logs from the applications, sending the logs off to user-configured remote logging services and responding to `cf logs`.
* **Doppler**: App syslog drains allowing you to drain logs to a 3rd party log manager system (like Splunk or Papertrail)
* **Traffic Controller**: Component responsible for handling requests such as `cf logs`; this exposes a websocket endpoint called the `firehose`.
* **Firehose**: Another way to plug in to the loggregator system via this websocket endpoint that exposes app logs, container metrics and ER (Elastic Runtime) component metrics; it does not include ER component logs.
* **Nozzles**: Firehose output consumers where logs are plugged into transformed to whatever data format you need.
#### **Routing**
It routes traffic to the appropriate component.
* **NATS**: Messaging bus, some components report runtime events here. The most important one probably is routing information, the Diego cells constantly update the Router with a list of applications and what hosntnames are registered to them.
#### Storage
* **etcd database**: The Diego database for BBS tasks and LRPs.
* **CC_DB**: The DB instance serving the Cloud Controller and the UAA. It can be substituted with any remote DB service such as Amazon RDS.
* **Blob store**: The Cloud Controller stores the prepared application images (droplets) in the blob store. Can be substituted with network filesystems (NFS, WebDav) or S3-compatible APIs.
### Login
#### Specify API endpoint

cf api api_endpoint.pivotal.io

#### Login using your user credentials

cf login -a api_endpoint.pivotal.io

#### View your target
Review your current API endpoint, user, org and space:

cf target

### Managing your app
#### Deploy your app

cf push app_name \ [-p ./app.jar] \ [-m 128M] \ [--random-route] \ [--no-start]


If the app has the artifact path and the required memory specified via a _manifest.yml_ file, we simply need to push the app with no other params.                          Note:                         
- `-p` tells the cf command what file to upload
- `--random-route` assigns a random route to the app, as opposed to the default route `app_name.cfapps.io`
- `--no-start` tells the cf command not to start the app
For Java apps, specify the **java_buildpack** buildpack entry inside your manifest file.
#### Start your app

cf start app_name

#### Restart your app
Restarting an app makes sure that the environment variables (**VCAP_SERVICES**) are set/injected correctly in the app container.

cf restart app_name

#### Scale up/out your app

cf scale app_name \ -m memory_size_scale_up \ -i instances_scale_out

#### View your deployed apps

cf apps

Note:                         
View all apps deployed in your org and space.
### Marketplace
#### View available services in the marketplace

cf m

#### Get service plan info for a marketplace service

cf m -s market_service_name

### Environment Variables (VCAP_SERVICES) Note:
For bindable services, CF adds connection details to the **VCAP_SERVICES** environment variable when you restart your app, after binding a service instance to your app.
#### View your app's env variables

cf env app_name

#### Set an env variable

cf set-env app_name env_name env_value1,env_value2[,...] # make sure to restart your app # for the env variables to take effect cf restart app_name

### Wiring a service to an app
#### Provision a route service intance

cf create-service market_service_name \ market_service_plan_name service_name

#### Bind a route service to your app

cf bind-service app_name service_name # you will need to restart your app # so that the app can have access to the env variables cf restart app_name

#### View created services

cf services

### Wiring apps together
A user-provided service instance can be used to connect to any legacy system within your CF.

# hook an app to another cf create-user-provided-service user_provided_service_name \ -p uri # uri will wait for the app url, # e.g.: http://uri_to_reach_your_app # now bind the app you want to to this user-provided service cf bind-service app_to_hook_name user_provided_service_name cf restart app_to_hook_name                         

Note:                     
Java apps can read env variables via a Java Buildpack feature called **Auto-Reconfiguration** that will automatically re-write bean definitions to connect with services bound to an app.
### Rebuild app droplet
Application droplets need to be rebuilt when there are new dependencies to pull in:

cf restage app_name

### Reverse-engineer a manifest from a running app
You can create/save an app manifest for an app that has been pushed successfully:

cf create-app-manifest app_name \ [-p ./path_to_manifest/manifest.yml]

Note:                     
Manifests help you push your app by allowing you to specify all your app metadata and associated services and env variables in this **manifest.yml** file instead of on the command line.
### Security Groups
#### Create an app security group

cf create-security-group sg_name path_to_sg_json_file # bind the SG to an org and space cf bind-security-group sg_name org_name space_name # for changes to take effect, restart the app cf restart app_name

Note:
Application Security Groups (ASGs) are a collections of egress rules that specify the protocols, ports, and IP address ranges where app or task instances send traffic.
**ASGs** = virtual firewalls that control egress/outbound traffic for apps
#### See all security groups running & bound to your targeted ops and space

cf security-groups

#### Check the definition for a security group

cf security-group app_security_group_name

### Staging Security Groups                      Note:                     
Staging security groups bound during staging when the app droplet gets created.
- admins can define a staging ASG for app and task staging
#### See all staging security groups

cf staging-security-groups

### Running Security Group Note:
- admins can define a running ASG for app and task runtime
#### See all system wide running security groups

cf running-security-groups

Note:
Both staging and running SGs are system wide, they apply everywhere, despite the org and space you are targetting.
#### Lock down all of the egress traffic for a running app

cf unbind-running-security-group app_security_group_name # restart your app to see the effects cf restart app_name-log-drain

Note:
- by unbinding that SG
### Create a log drain
PCF does not persist logs. For long term storage of logs for log analysis, use 3rd party tools via CF's capability to drain app logs to some destination.

cf create-user-provided-service app_name-log-drain \ -l syslog://3rd_party_syslog_endpoint # `3rd_party_syslog_endpoint = host:port` # of external 3rd party syslog service, # like Papertrail or Splunk cf bind-service app_name app_name-log-drain cf restart app_name

### View all routes in your org and space

cf routes

### Blue-Green Deployments                          Note:                         
- used to achieve zero downtime when upgrading, when managing multiple versions of your app, traffic being devided up by the number of instances bound to the route.

Push your new app version:

# scale out your app to multiple instances cf scale app_name -i 2 # record the subdomain (host) for your app cf routes # push the new app version by declaring # your production route as `subdomain-temp` cf push app_name-v2 \ -p ./app-v2.jar \ -m 768M \ --hostname initial_app_hostname-temp \ --no-start


Bind app to service and map routes:

# bind the new version app to # any dependency apps the old app has cf bind-service app_name-v2 app_name cf start app_name-v2 # map production route to the new app v2 cf map-route app_name-v2 \ initial_app_domain \ --hostname initial_app_hostname \ [--port public_facing_port_to_the_app]


Redirect app traffic to the new version app:

# scale down your initial app cf scale initial_app_name -i 1 # scale out your new app and you will see most traffic # leaning in favor for this app cf scale app_name-v2 -i 2 # to cut over from the old app, # unmap the public route from your old app, # thus moving all traffic to app v2 cf unmap-route initial_app_name initial_app_domain \ -n initial_app_hostname


Make sure to cleanup after your blue-green deployment:

# cleanup by unmapping the temporary route cf unmap-route app_name-v2 initial_app_domain \ -n initial_app_hostname-temp # delete the old app cf delete app_name #rename app v2 to app_name cf rename app_name-v2 app_name # restart the app cf restart app_name # scale down cf scale app_name -i 1

### Autoscaling and Performance Testing
#### Provision an autoscaler service instance
Automatic app scaler service can be found on the marketplace. They will look at your app metrics and scale the app up or down on your behalf during periods of higher and lower traffic.

cf create-service app-autoscaler \ market_service_plan_name \ service_name # bind the created service to the app you want cf bind-service app_name service_name # restart your app cf restart app_name

#### Generate load on your app
- for performance testing and to see the autoscaler work:

cf m -s loadimpact

### Monitor your app
#### Check app status/health

cf app app_name

#### Troubleshoot app instances
Or how to view app events:

cf events app_name

#### View app logs

# view most recent logs cf logs app_name --recent # tail the logs = view logs in real-time cf logs app_name # filters logs containing API (Cloud Controller logs) # and CELL (Diego Cell logs); # observe this when you scale up & down/out your app cf logs app_name | grep "API\|CELL" # on Windows: cf logs app_name | findstr "API CELL" # filter logs excluding Router logs cf logs app_name | grep -v RTR

#### Monitor app state
A better way for monitoring the state of your app, including your app instances and their CPU usage is via CF CLI plugin:

# head over to CF plugins catalog: # https://plugins.cloudfoundry.org/ cf top

#### Monitor app performance
CF integrates well with application performance monitoring solutions like NewRelic or AppDynamics.

# these solutions add overhead to your app # so you need to scale up your app in terms of memory cf scale app_name -m 1G -i 1 cf create-user-provided-service newrelic_service_name \ -p newrelic_license_key # ! newrelic_service_name must be `newrelic` # OR use the newrelic marketplace service: cf create-service newrelic standard newrelic_service_name cf bind-service app_to_hook_name newrelic_service_name # restage app so that droplet can be rebuilt # to include the agent cf restage app_name

Note:                         
If you no longer need this service, don't forget to unbind it from your apps, delete it, scale down your apps memory and restage your apps.
#### PCF Metrics (in Beta state)
Visit the following interface to see app events, metrics (CPU, memory, network) and logs in this monitor view: http://metrics.our_system_domain
(**our_system_domain = cfapps.io** in this case)
[PWS Metrics doc](http://docs.run.pivotal.io/metrics/using.html)
[PCF Metrics doc](http://docs.pivotal.io/pcf-metrics/using.html)
### Buildpacks
#### Explore system buildpacks
Buildpacks produce the droplet needed to run our app.

cf buildpacks

Note:                         
You have the option to use custom buildpacks as well.
#### Specify a custom buildpack

# deploy an app with the latest custom buildpack cf push app_name -p artifact_path \ -b custom_buildpack_git_repo

#### Configure the Java runtime that the Java buildpack provisions for your app
The system provided Java buildpack is offline, with a limited set of dependencies. For both the online and offline packages, unless the Java version is specified, the app is run with the latest Java version available to the buildpack.

# set env variables that you want your app to read cf set-end app_name JBP_CONFIG_OPEN_JDK_JRE \ "{jre: { version: your_desired_version}}" # where e.g. your_desired_version = 1.8.0_45 # the droplet needs to be rebuilt cf restage app_name

### Service Brokers Note:
- publish route services to the CF marketplace, making them available to devs
- help extend CF with managed services, by providing an interface for native and external 3rd party services
#### Create a service broker
Managed services can easily be plugged in in CF's extensible platform and made available in the service marketplace via the space-scoped service brokers feature. After pushing the service broker app to PCF, set the following env variables:

cf set-env service_app_name SERVICE_ID service_broker_id cf set-env service_app_name SERVICE_NAME service_name cf set-env service_app_name PLAN_ID service_plan_id cf start service_app_name cf create-service-broker service_broker_name \ username password \ service_app_name_url \ --space-scoped

Note:                         
Space-scoped brokers are private to a space and don't require an admin to enable access (list it in the marketplace, provision service instances, etc.).

If you have created say a MongoDB service broker, and you have provisioned say a MongoDB AWS instance, you have to setup the connectivity to that by defining the **MONGODB_HOST** env variable for your service broker (the hostname or IP address of that AWS instance):

cf set-env service_broker_name \ MONGODB_HOST mongodb_aws_instance_ip_address cf set-env service_broker_name \ MONGODB_PASSWORD mongodb_aws_instance_password cf restart service_broker_name

#### List service brokers

cf service-brokers # see service broker access level cf service-access

#### Delete a service broker

# the service created to bind # your app to the service-broker cf delete-service service_name cf delete-service-broker service_broker_name cf delete service_app_name

### Route Services Note:
- are a kind of a Marketplace that devs use to process traffic addressed to an app, to filter or transform an apps requests and responses by binding an app's route to a service instance (e.g.: authentication, rate limiting, caching)
#### Create a user-provided route service

cf create-user-provided-service route_service_name \ -r https://uri_to_reach_your_route_service_app

Note:
User-provided services live outside of CF; there is no service broker making them available.
They enable apps to connect to local services that are NOT managed by CF.
#### Bind the user-provided route service to the intercepted app

# capture the domain for your route-service and the # hostname of the app you are going to intercept cf routes # bind it cf bind-route-service route_service_domain \ route_service_name \ --hostname app_intercepting_hostname

#### Cleanup

cf unbind-route-service route_service_domain \ route_service_name \ --hostname app_intercepting_hostname


For a deeper understanding of Cloud Foundry,
checkout their [documentation](https://docs.cloudfoundry.org/#read-the-docs)
or try
[Pivotal's e-learning platform](https://pivotal.litmos.com/course).


The CF internals diagram at the beginning of this presentation was generated using [Code2Flow](https://code2flow.com/).