{"id":15805183,"url":"https://github.com/ddobrin/container-to-container-networking-with-cloud-foundry","last_synced_at":"2025-03-31T22:11:24.323Z","repository":{"id":134175612,"uuid":"246464099","full_name":"ddobrin/container-to-container-networking-with-cloud-foundry","owner":"ddobrin","description":"Service-to-service communication using BOSH-DNS","archived":false,"fork":false,"pushed_at":"2020-03-26T14:35:50.000Z","size":346,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-06T02:05:24.031Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ddobrin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-11T03:19:42.000Z","updated_at":"2021-02-18T05:38:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"5b3bac63-0b85-4b5d-ab27-5e849a2ef490","html_url":"https://github.com/ddobrin/container-to-container-networking-with-cloud-foundry","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddobrin%2Fcontainer-to-container-networking-with-cloud-foundry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddobrin%2Fcontainer-to-container-networking-with-cloud-foundry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddobrin%2Fcontainer-to-container-networking-with-cloud-foundry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddobrin%2Fcontainer-to-container-networking-with-cloud-foundry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ddobrin","download_url":"https://codeload.github.com/ddobrin/container-to-container-networking-with-cloud-foundry/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246547365,"owners_count":20794970,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-05T02:04:50.351Z","updated_at":"2025-03-31T22:11:24.306Z","avatar_url":"https://github.com/ddobrin.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Java Demo for Pivotal Cloud Foundry Container-to-Container Communication\n\nThis project illustrates the usage of [BOSH-DNS](https://bosh.io/docs/dns) for invoking Java-based microservices\ndeployed on [Pivotal Cloud Foundry](https://pivotal.io/platform).\n\n## Why BOSH-DNS for container-to-container communication\nThanks to BOSH-DNS, microservices running on PCF do not require a service registry for discovery and service invocation (such as\n[Netflix Eureka](https://github.com/Netflix/eureka) or [Hashicorp Consul](https://www.consul.io)),\nsince all apps owning a route on the domain `apps.internal` can be resolved by all apps running\non the platform. \n\nFor example, if an app has a route `mynewapp.apps.internal`, any app can access it\nfrom within the platform. \n\nMoreover, these apps do not require a public route in order to be\naccessible from apps, and do not use the `gorouter`, thus offering also better performance.\n\n**Container architecture:**\n \n![Architecture](https://github.com/ddobrin/container-to-container-networking-with-cloud-foundry/blob/master/images/BoshDNS.png)  \n\n1. Routes:\n  * Routes are emitted from the Route Emitter. \n  * Internal routes are emitted from the Route Emitter as well, on a separate topic. \n  * The NATS message queue cluster that handles routes for the gorouter also handles internal routes.\n\n2. Service Discovery Controller (SDC): \nsubscribes to route updates from NATS on the internal routes topic and is highly available.\n\n3. BOSH-DNS routing:\n  * Each Diego Cell has a BOSH DNS and a BOSH-DNS Adapter\n  * App containers are configured to use the BOSH DNS server on their Diego cell as their DNS server\n  * The BOSH-DNS Adapter configures BOSH DNS to route queries for internal domains to itself\n  * When a request for an internal domain hits BOSH DNS it looks at the domain name. \n  * If it's internal it directs the request to the BOSH-DNS Adapter\n  * The BOSH DNS adapter in turn makes a request to the SDC\n  * SDC responds with all the IPs of all the app containers associated with the requested route\n  * BOSH DNS adapter returns all the IPs returned from the SDC, shuffled\n  * BOSH DNS in turn returns the full set of IPs originally from the SDC\n  * Clients pick an IP from the list, usually the first  one, as a form of load-balancing\n\n\n## Enable container-to-container access within PCF-based apps\nAn app making a direct connection to another app requires a network policy.\nThis [network policy](https://docs.cloudfoundry.org/concepts/understand-cf-networking.html)\nallows a container app to open a connection to another container:\n```shell\n# app-source - the consumer application\n# app-target - the provide application, aka the target app\n# port - the port where the target appp is being accessed\n\n\u003e cf add-network-policy \u003capp-source\u003e --destination-app \u003capp-target\u003e --protocol tcp --port \u003cport\u003e\n```\n\nUsing BOSH-DNS and container-to-container networking, your microservices do not require any external libraries\nto discover service endpoints.\n\nIf you are using these features, __**you do not need to install**__ the\n[Spring Cloud Service tile](https://docs.pivotal.io/spring-cloud-services/2-1/common/index.html)\non PCF, since BOSH-DNS is a core platform feature.\n\n**This Java demo project does not use Spring Cloud Netflix** and does not leverage Hystrix, no Eureka, no Ribbon.\n\n## REST-based service invocation\nREST calls are made using\n[Retrofit2](https://square.github.io/retrofit), and network errors are managed using\na circuit breaker pattern implemented by [Resilience4j](https://github.com/resilience4j/resilience4j).\nThis app is fault tolerant, and can be scaled-out (more instances) and scaled-up (more CPU/memory)\nwith zero downtime.\n\nAll these features are available for all apps with any language (not only Spring Boot apps\nwritten in Java).\n\nDevelopment teams can use other REST clients or circuit breakers of their choosing.\n\n# How to run the demo apps\n\nThis demo project consists of two components:\n - `pcf-c2c-java-backend`: a microservice exposing a REST API\n - `pcf-c2c-java-frontend`: a microservice connecting to backend instances\n \nYou can use this project on any PCF 2.2+ instances, such as [Pivotal Web Service](https://run.pivotal.io). It has been tested on version 2.8, the latest release at the time of this writing.\n\nCompile this project with Maven and a JDK 8, and deploy these apps to Pivotal Cloud Foundry:\n```shell\n\u003e ./mvnw clean package \u0026\u0026 cf push\n```\n\nThe Frontend Java app is the only one exposing a public endpoint: \n```shell\n# cUrl command\n\u003e curl -s http://pcf-c2c-java-frontend-\u003cRANDOM\u003e.domain.com\n\n# for example, deploying with a random route, the frontend app call might receive this sample response:\n# request\n\n\u003e curl https://pcf-c2c-java-frontend-chipper-parrot-vn.cfapps.io/ \n\n# sample response\n  Welcome to the Cloud Foundry Container-to-container Java Demo\n  Frontend Instance: [pcf-c2c-java-frontend/0 10.251.70.14]\n  Connecting to Backend Instance: pcf-c2c-java-backend.apps.internal:8080\n  Received message from Backend Instance:\n    No backend service available\n  Time spent: 10 ms\n```\n\nAs you can see, Backend app instances are not seen by Frontend app instances.\nYou need to \"allow\" connections between frontend app instances and backend app instances:\n```shell\n\u003e cf add-network-policy pcf-c2c-java-frontend --destination-app pcf-c2c-java-backend --protocol tcp --port 8080\n```\n\nThis command enables container-to-container networking between app instances, from the Frontend Java app\ninstances to the Backend Java app instances.\n\nAs soon as this network policy is applied (it can take up to ten seconds), Backend app instances\nare now accessible by frontend app instances:\n```shell\n# cUrl command\n\u003e curl -s http://pcf-c2c-java-frontend-\u003cRANDOM\u003e.domain.com\n\n# for example, deploying with a random route, the frontend app call might receive this sample response:\n# request\n\u003e curl https://pcf-c2c-java-frontend-chipper-parrot-vn.cfapps.io/ \n\n# sample response\n  Welcome to the Cloud Foundry Container-to-container Java Demo\n  Frontend Instance: [pcf-c2c-java-frontend/0 10.250.186.172]\n  Connecting to Backend Instance: pcf-c2c-java-backend.apps.internal:8080\n  Received message from Backend Instance:\n    [pcf-c2c-java-backend/1 10.240.219.2] says:\n    Thank you for coming, [pcf-c2c-java-frontend/0 10.250.186.172]!\n    Visitor count: 1\n  Time spent: 244 ms\n```\n\n## Load balancing requests\n\nThe demo startes the Backend Java app with 2 instances and provisions 2 endpoints to allow you to randomly pick the host address of a backend instance or to list the host address for all backend instances\n\nFor exmple:\n```\n# list host address for ALL backend instances \n\u003e curl https://pcf-c2c-java-frontend-chipper-parrot-vn.cfapps.io/backends\n\n# sample response\nList of ALL Backend instance host addresses:\n 10.243.232.119,  10.240.219.2\n\n# list host address for one of them picked up irandomly\n\u003e curl https://pcf-c2c-java-frontend-chipper-parrot-vn.cfapps.io/backend\n\n# sample response\nBackend instance host address: 10.240.219.2\n\nor \n\nBackend instance host address: 10.243.232.119\n```\n\nIf you kill one of the Backend app instances used by a Frontend app instance, another Backend app instance\nwill automatically be resolved by BOSH-DNS the next time a Frontend app instance is making a\nREST call. \n\nPlease note that there is no app downtime while a new backend app is being used.\n\nClient-side load-balancing is done without using an external\nlibrary (such as Netflix Ribbon). A custom\n[OkHttp3 Interceptor](https://square.github.io/okhttp/3.x/okhttp/okhttp3/Interceptor.html)\nimplementation (used by Retrofit2) is included to load balance \nnetwork requests. This implementation simply uses backend\nIP addresses given by BOSH-DNS, using a call to\n[InetAddress.getByName()](https://docs.oracle.com/javase/8/docs/api/java/net/InetAddress.html#getByName-java.lang.String-).\n\nA sample snippet of code showing the usage of InetAddress:\n```java\n    public String backendAddress() throws UnknownHostException {\n        InetAddress hostIP = InetAddress.getByName(this.backendProps.getHost());\n        Intrinsics.checkExpressionValueIsNotNull(hostIP, \"InetAddress.getByName(backendProps.host)\");\n\n        String hostAddress = hostIP.getHostAddress();\n        Intrinsics.checkExpressionValueIsNotNull(hostAddress, \"InetAddress.getByName(ba…ndProps.host).hostAddress\");\n\n        return \"Backend instance host address: \" + hostAddress;\n    }\n```\n\nYou can disable client-side load-balancing by overriding the\nproperty `backend.loadBalancing`, which is set to\n`true` by default. You may also set this property using an\nenvironment variable:\n```shell\n\u003e cf set-env pcf-c2c-java-frontend BACKEND_LOADBALANCING false\n\n# use 'cf restage pcf-c2c-java-frontend' to ensure your env variable changes take effect\n\u003e cf restage pcf-c2c-java-frontend\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fddobrin%2Fcontainer-to-container-networking-with-cloud-foundry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fddobrin%2Fcontainer-to-container-networking-with-cloud-foundry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fddobrin%2Fcontainer-to-container-networking-with-cloud-foundry/lists"}