Skip to content

Commit

Permalink
Use skaffold to deploy the animal-rescue app and SCG object to k8s (s…
Browse files Browse the repository at this point in the history
  • Loading branch information
LittleBaiBai authored Oct 2, 2020
1 parent e343c7d commit c232519
Show file tree
Hide file tree
Showing 13 changed files with 204 additions and 4 deletions.
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,33 @@ All the gateway configuration can be found and updated here:
- Frontend routes configuration used on binding used on bind: `./frontend/gateway-config.json`
- Backend routes configuration used on binding used on bind:`./backend/gateway-config.json`

## Deploy to Kubernetes

Make sure you have Spring Cloud Gateway for k8s installed.

If you have `kustomize` installed, you can run the following command:

```bash
kustomize build ./k8s | kubectl apply -f -
```

If you don't want to use `kustomize`, you can apply each yaml file in the `k8s` folder manually into the `animal-rescue` namespace (or any namespace you like!).

There are two gateway instance being created - `animal-rescue-gateway` and `animal-rescue-gateway-with-dynamic-routes`.
* `animal-rescue-gateway` has all the routes pre-defined when creating the gateway.
* `animal-rescue-gateway-with-dynamic-routes` doesn't have any routes defined on creation. The route definition is defined in a `SpringCloudGatewayBinding` object that can be version-controlled with each routed application.

After applying all the manifest files, there should be a SCG deployment and a `ClusterIP` service for each gateway instance deployed in the SCG installation namespace (`spring-cloud-gateway` by default).

Expose your gateway instance in your favorite way, e.g. ingress or port forwarding, then access `/rescue` path` to view the animal-rescue app.

## Special frontend config related to gateway

The frontend application is implemented in ReactJS, and is pushed with static buildpack. Because of it's static nature, we had to do the following
1. `homepage` in `package.json` is set to `/rescue`, which is the path we set for the frontend application in gateway config (`frontend/gateway-config.json`). This is to make sure all related assets is requested under `/rescue` path as well.
1. `Sign in to adopt` button is linked to `/rescue/login`, which is a path that is `sso-enabled` in gateway config (`frontend/gateway-config.json`). This is necessary for frontend apps bound to a sub path on gateway because the Oauth2 login flow redirects users to the original requested location or back to `/` if no saved request exists. This setting is not necessary if the frontend app is bound to path `/`.
1. `REACT_APP_BACKEND_BASE_URI` is set to `/backend` in build script, which is the path we set for the backend application in gateway config (`backend/gateway-config.json`). This is to make sure all our backend API calls are appended with the `backend` path.


## Try it out
Visit `https://gateway-demo.${appsDomain}/rescue`, you should see cute animal bios with the `Adopt` buttons disabled. All the information are fetched from a public `GET` backend endpoint `/animals`.
![homepage](./docs/images/homepage.png)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ public AnimalController(AnimalRepository animalRepository) {

@GetMapping("/whoami")
public String whoami(Principal principal) {
if (principal == null) {
return "";
}
return principal.getName();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.spring.cloud.samples.animalrescue.backend;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

@Configuration
@Profile("k8s")
public class KubernetesSecurityConfiguration {

private static final Logger LOG = LoggerFactory.getLogger(KubernetesSecurityConfiguration.class);

@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity httpSecurity) {
return httpSecurity.httpBasic().disable().build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
Expand All @@ -15,10 +14,9 @@
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authentication.RedirectServerAuthenticationSuccessHandler;
import org.springframework.security.web.server.authentication.logout.RedirectServerLogoutSuccessHandler;
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers;

@Configuration
@Profile("!cloud") // cloud profile is automatically activated on CloudFoundry
@Profile("!cloud & !k8s") // cloud profile is automatically activated on CloudFoundry
public class SecurityConfiguration {

@Bean
Expand Down
1 change: 1 addition & 0 deletions frontend/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
2 changes: 2 additions & 0 deletions frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FROM nginx:1.17
COPY build /usr/share/nginx/html
51 changes: 51 additions & 0 deletions k8s/animal-rescue-backend.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: animal-rescue-backend
spec:
selector:
matchLabels:
app: animal-rescue-backend
template:
metadata:
labels:
app: animal-rescue-backend
spec:
containers:
- name: animal-rescue-backend
image: springcloudservices/animal-rescue-backend
env:
- name: spring.profiles.active
value: k8s
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
name: animal-rescue-backend
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: animal-rescue-backend

---
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayBinding
metadata:
name: animal-rescue-backend-routes
spec:
gateway: animal-rescue-gateway-with-dynamic-routes
service: animal-rescue-backend
routes:
- predicates:
- Path=/api/**
filters:
- StripPrefix=1
44 changes: 44 additions & 0 deletions k8s/animal-rescue-frontend.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: animal-rescue-frontend
spec:
selector:
matchLabels:
app: animal-rescue-frontend
template:
metadata:
labels:
app: animal-rescue-frontend
spec:
containers:
- name: animal-rescue-frontend
image: springcloudservices/animal-rescue-frontend
ports:
- containerPort: 80
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: animal-rescue-frontend
spec:
ports:
- port: 80
targetPort: 80
selector:
app: animal-rescue-frontend

---
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayBinding
metadata:
name: animal-rescue-frontend-routes
spec:
gateway: animal-rescue-gateway-with-dynamic-routes
service: animal-rescue-frontend
routes:
- predicates:
- Path=/rescue/**
filters:
- StripPrefix=1
5 changes: 5 additions & 0 deletions k8s/animal-rescue-gateway-with-dynamic-routes.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
name: animal-rescue-gateway-with-dynamic-routes
spec: {}
18 changes: 18 additions & 0 deletions k8s/animal-rescue-gateway.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
name: animal-rescue-gateway
spec:
routes:
- id: animal-rescue-frontend
uri: http://animal-rescue-frontend.animal-rescue.svc.cluster.local
predicates:
- Path=/rescue/**
filters:
- StripPrefix=1
- id: animal-rescue-backend
uri: http://animal-rescue-backend.animal-rescue.svc.cluster.local
predicates:
- Path=/api/**
filters:
- StripPrefix=1
10 changes: 10 additions & 0 deletions k8s/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: animal-rescue

resources:
- namespace.yaml
- animal-rescue-frontend.yaml
- animal-rescue-backend.yaml
- animal-rescue-gateway.yaml
- animal-rescue-gateway-with-dynamic-routes.yaml
4 changes: 4 additions & 0 deletions k8s/namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: animal-rescue
22 changes: 22 additions & 0 deletions skaffold.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
apiVersion: skaffold/v2beta6
kind: Config
build:
tagPolicy:
sha256: {}
artifacts:
- image: springcloudservices/animal-rescue-backend
context: backend
buildpacks:
builder: gcr.io/paketo-buildpacks/builder:base-platform-api-latest
dependencies:
paths:
- src/main/**
- build.gradle
- settings.gradle
- image: springcloudservices/animal-rescue-frontend
context: frontend

deploy:
kustomize:
paths:
- k8s

0 comments on commit c232519

Please sign in to comment.