Skip to content

Commit

Permalink
Merge pull request kubernetes-sigs#51 from mikouaj/ca-ingress
Browse files Browse the repository at this point in the history
Created CloudArmor GKE ingress recipe
  • Loading branch information
boredabdel authored Jul 5, 2021
2 parents 9e5a795 + e470f0f commit 7d9cb3d
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ GKE is a managed Kubernetes platform that provides a more opinionated and seamle
- [Basic External Ingress](./ingress/external-ingress-basic) - Deploy host-based routing through an internet-facing HTTP load balancer
- [Basic Internal Ingress](./ingress/internal-ingress-basic) - Deploy host-based routing through a private, internal HTTP load balancer
- [Secure Ingress](./ingress/secure-ingress) - Secure Ingress-hosted Services with HTTPS, Google-managed certificates, SSL policies, and HTTPS redirects.
- Multi-cluster Ingress
- [IAP Ingress](./ingress/iap-ingress) - GKE Ingress with Identity-Aware Proxy based authentication.
- [CloudArmor Ingress](./ingress/cloudarmor-ingress) - GKE Ingress with Google CloudArmor policy protection.
- Multi-cluster Ingress
- [Basic Multi-cluster Ingress](./multi-cluster-ingress/multi-cluster-ingress-basic) - Deploy applications across different clusters and different regions but retain a single global load balancer and public IP for global traffic management.
- [Blue/Green Multi-cluster Ingress](./multi-cluster-ingress/multi-cluster-blue-green-cluster) - Deploy applications across multiple clusters in the same region, leveraging a single global load balancer and public IP for global traffic management, to support seamless cluster upgrades without impacting client access.
- Services
Expand Down
Binary file added images/cloudarmor-ingress.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
128 changes: 128 additions & 0 deletions ingress/cloudarmor-ingress/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Google Cloud Armor enabled ingress

Following recipe provides a walk-through for setting up [GKE Ingress](https://cloud.google.com/kubernetes-engine/docs/concepts/ingress)
with [Google Cloud Armor](https://cloud.google.com/armor) protection.

Google Cloud Armor protects your applications and websites against denial of service and web attacks.
Since GKE Ingresses use **proxy-based** [Google Cloud HTTP(s) Load Balancers](https://cloud.google.com/load-balancing/docs/https),
**protection against L3 and L4 DDos attacks is enabled by default**.

Applications can be also protected with Layer7 filtering by using Google Cloud Armor
[security policies](https://cloud.google.com/armor/docs/security-policy-overview). Once Google Cloud
Armor security policy is configured, it can be used to protect services associated with a given ingress.

## Use cases

* Protect backend services at the networking edge with Layer7 filtering rules

## Relevant documentation

* [Cloud Armor overview](https://cloud.google.com/armor)
* [Cloud Armor security policy](https://cloud.google.com/armor/docs/security-policy-overview)
* [GKE ingress overview](https://cloud.google.com/kubernetes-engine/docs/concepts/ingress)

## Versions & Compatibility

* GKE version 1.19.10+ *(for GA of this feature)*
* Works with [External Ingress](https://cloud.google.com/kubernetes-engine/docs/how-to/load-balance-ingress)
*(single-cluster)*
* Tested and validated with GKE version 1.19.10 on Jul 2nd 2021

---

![cloudarmor-ingress](../../images/cloudarmor-ingress.png)

Google Cloud Armor protection is integrated with ingress for GKE by leveraging [BackendConfig CRD](https://github.com/kubernetes/ingress-gce/tree/master/pkg/apis/backendconfig).
This object is associated with a given service and allows to specify configuration for HTTPs Load Balancer
that handles incoming traffic. Google Cloud Armor policy can be can be enabled for a service by specifying
`securityPolicy` block with `name` key that defines name of the policy that will be applied.

**NOTE**: GKE creates [default backend](https://cloud.google.com/kubernetes-engine/docs/concepts/ingress#default_backend)
service upon cluster creation. This default service returns `404` HTTP response code and is used
on any Ingress as a default destination for unmatched requests - unless `defaultBackend` field with custom
service is specified. Keep in mind that **GKE default backend service has no associated `BackendConfig`
by default**, so you need to configure CloudArmor policy for it explicitly.

**NOTE**: applying `cloud.google.com/backend-config` annotation on an existing service, that is
associated with an existing Ingress, makes no changes on underlying backend service.
Refer to [following issue for details](https://github.com/kubernetes/ingress-gce/issues/1503).

## Walk-through

Prerequisites:

* GKE cluster up and running *(check [Prerequisite: GKE setup](#prerequisite-gke-setup) below)*
* Google Cloud Armor policy configured *(check [Configuring Google Cloud Armor security policies](https://cloud.google.com/armor/docs/configure-security-policies)
guide)*

Steps:

1. (Optional) Enable Google CloudArmor policy on a `default-http-backend` service

* Create `BackendConfig` in a `kube-system` namespace. Substitute example policy name with your
CloudArmor policy name

```sh
cat << EOF | kubectl apply -f - -n kube-system
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: cloudarmor-test
spec:
securityPolicy:
name: cloudarmor-test
EOF
```
* Annotate `default-http-backend` service in a `kube-system` namespace with a newly created `BackendConfig`
```sh
kubectl annotate services default-http-backend \
beta.cloud.google.com/backend-config='{"default": "cloudarmor-test"}' -n kube-system
```
2. Replace `$POLICY_NAME` variable in `cloudarmor-ingress.yaml` file with your Google CloudArmor
policy name.
```sh
sed -i '.bak' 's/$POLICY_NAME/cloudarmor-test/g' cloudarmor-ingress.yaml
```
3. Apply `cloudarmor-ingress.yaml` file
```sh
$ kubectl apply -f cloudarmor-ingress.yaml
ingress.networking.k8s.io/cloudarmor-test created
backendconfig.cloud.google.com/cloudarmor-test created
service/whereami created
deployment.apps/whereami created
$
```
4. Wait until all created objects reach desired state
5. Verify and enjoy
### Prerequisite: GKE setup
1. Enable GKE API
```sh
gcloud services enable container.googleapis.com
```
2. Create simple zonal GKE cluster for tests
```sh
gcloud container clusters create cluster-test \
--zone europe-central2-a \
--release-channel regular \
--enable-ip-alias
```
3. Configure client credentials for a new cluster
```sh
gcloud container clusters get-credentials cluster-test \
--zone europe-central2-a
````
79 changes: 79 additions & 0 deletions ingress/cloudarmor-ingress/cloudarmor-ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@

# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: cloudarmor-test
spec:
rules:
- http:
paths:
- path: /whereami
backend:
serviceName: whereami
servicePort: 80
---
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: cloudarmor-test
spec:
securityPolicy:
name: $POLICY_NAME
---
apiVersion: v1
kind: Service
metadata:
name: whereami
annotations:
cloud.google.com/neg: '{"ingress": true}'
cloud.google.com/backend-config: '{"default": "cloudarmor-test"}'
spec:
type: ClusterIP
selector:
app: whereami
ports:
- port: 80
protocol: TCP
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: whereami
spec:
replicas: 3
selector:
matchLabels:
app: whereami
template:
metadata:
labels:
app: whereami
spec:
containers:
- name: whereami
image: gcr.io/google-samples/whereami:v1.0.1
ports:
- name: http
containerPort: 8080
readinessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTP
initialDelaySeconds: 5
timeoutSeconds: 1

0 comments on commit 7d9cb3d

Please sign in to comment.