forked from kubernetes-sigs/gateway-api
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request kubernetes-sigs#51 from mikouaj/ca-ingress
Created CloudArmor GKE ingress recipe
- Loading branch information
Showing
4 changed files
with
209 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
```` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |