Skip to content
This repository has been archived by the owner on May 8, 2023. It is now read-only.

istio-ified fortio - acme auto https (demo) setup #32

Merged
merged 24 commits into from Jan 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
69947cd
[wip] istio-ified fortio
ldemailly Dec 21, 2017
e91a3bf
Wip/trying the new build
ldemailly Dec 23, 2017
997a636
Merge branch 'master' into fortio-1
ldemailly Jan 7, 2018
00637c1
Updated for 0.6.0
ldemailly Jan 8, 2018
8b59346
Got acme https working including 2 domains
ldemailly Jan 12, 2018
c238d7a
Merge branch 'master' into fortio-1
ldemailly Jan 12, 2018
3fb1ef4
update: need a bogus additional ingress
ldemailly Jan 12, 2018
33abb81
Workaround for istio/istio#2573
ldemailly Jan 12, 2018
99ee227
Add http->https redirect
ldemailly Jan 12, 2018
30dc8de
Merge branch 'master' into fortio-1
ldemailly Jan 13, 2018
de37758
No -pre needed, added comment
ldemailly Jan 13, 2018
c1e29da
Seems like :latest is needed
ldemailly Jan 13, 2018
e0aad6d
Add -secret to secret refs by code review request
ldemailly Jan 16, 2018
cc33a7a
Trying ingressClass
ldemailly Jan 16, 2018
5fc9014
update: no more cleanup of ingress needed with the ingressClass
ldemailly Jan 22, 2018
3626ecb
Simpler version thanks to fortio 0.6.5 cloud sync, no need for persis…
ldemailly Jan 24, 2018
04fe038
Working egress rule
ldemailly Jan 24, 2018
2146ed1
Adding in memory volume for download
ldemailly Jan 25, 2018
396d9bb
Cert-manager is now in helm/stable so no need for submodule!
ldemailly Jan 25, 2018
1f64a25
Adding helm repo update
ldemailly Jan 25, 2018
d57944d
Review comments
ldemailly Jan 25, 2018
bb9adce
Forgot to mention cert provisioning in the summary
ldemailly Jan 25, 2018
35971cc
More readme tweaks
ldemailly Jan 25, 2018
72024ce
More links
ldemailly Jan 25, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Empty file added .gitmodules
Empty file.
26 changes: 26 additions & 0 deletions fortio/Makefile
@@ -0,0 +1,26 @@

deploy-fortio:
istioctl kube-inject --debug=false -f fortio.yaml | kubectl apply -f -

all: cert-setup ingress-setup cert-issue deploy-fortio

cert-setup:
# TODO: more granular rbac roles
-kubectl create clusterrolebinding add-on-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default
helm init
helm repo update
helm install stable/cert-manager

ingress-setup:
kubectl apply -f ingress.yaml

cert-issue:
kubectl apply -f cert.yaml

# dangerous as it deletes the cert and secret and if using the production
# letsencrypt server, rate limits may mean you can't get a new cert until
# the following week. uncomment if you understand the risks:
#force-reissue:
# kubectl delete secret -n istio-system istio-ingress-certs

.PHONY: deploy-fortio cert-setup ingress-setup cert-issue all
54 changes: 54 additions & 0 deletions fortio/README.md
@@ -0,0 +1,54 @@
# Fortio on Istio

Experimental istio on istio deployment:

[https://fortio.istio.io/](https://fortio.istio.io/) is running an istio deployment of the `fortio report` application

Using envoy directly as the internet facing istio ingress. SSL certificates are
automatically provisioned and renewed for multiple domains
([https://istio.fortio.org/](https://istio.fortio.org/) being the second one for the sake of this demonstration).

The data presented is pulled from a configurable google cloud storage or aws s3 bucket.

## Initial setup:

One time setup:

- Istio itself
```
# Istio 'perf' mode installation:
sh -c 'sed -e "s/_debug//g" install/kubernetes/istio-auth.yaml | egrep -v -e "- (-v|\"2\")" | kubectl apply -f -'
```

- Cert-manager

This installs the [cert-manager](https://github.com/jetstack/cert-manager)
```
make cert-setup
```

- Ingress

You can run this step separately for instance if you change ingress rules
in ingress.yaml.
```
make ingress-setup
```

- Get SSL certs

You can run this step separately for instance if switching from staging to
prod or editing cert.yaml to add new domains for instance.
```
make cert-issue
```
(check pod logs at each step etc)

## Fortio report app

Install fortio report app:
```
make deploy-fortio # or just 'make'
```

You can also delete the fortio-report pods to upgrade to latest fortio
116 changes: 116 additions & 0 deletions fortio/cert.yaml
@@ -0,0 +1,116 @@
apiVersion: certmanager.k8s.io/v1alpha1
kind: Issuer
metadata:
name: letsencrypt-staging
namespace: istio-system
spec:
acme:
# The ACME server URL
server: https://acme-staging.api.letsencrypt.org/directory
# Email address used for ACME registration
email: ldemailly@google.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-staging-secret
# Enable the HTTP-01 challenge provider
http01: {}
---
apiVersion: certmanager.k8s.io/v1alpha1
kind: Issuer
metadata:
name: letsencrypt-prod
namespace: istio-system
spec:
acme:
# The ACME server URL
server: https://acme-v01.api.letsencrypt.org/directory
# Email address used for ACME registration
email: ldemailly@google.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-prod-secret
# Enable the HTTP-01 challenge provider
http01: {}
---
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
name: fortio-cert-prod
namespace: istio-system
spec:
secretName: istio-ingress-certs
issuerRef:
name: letsencrypt-prod
commonName: fortio.istio.io
dnsNames:
- fortio.istio.io
- istio.fortio.org
acme:
config:
- http01:
# This class doesn't exist on purpose so we'll use the less specific
# istio ingress one because we need the auth off annotation on the svc
ingressClass: not-there
domains:
- fortio.istio.io
- istio.fortio.org
---
apiVersion: v1
kind: Service
metadata:
name: cert-manager-ingress1
namespace: istio-system
annotations:
auth.istio.io/8089: NONE
spec:
ports:
- port: 8089
name: http-certingr
selector:
certmanager.k8s.io/domain: fortio.istio.io
---
apiVersion: v1
kind: Service
metadata:
name: cert-manager-ingress2
namespace: istio-system
annotations:
auth.istio.io/8089: NONE
spec:
ports:
- port: 8089
name: http-certingr
selector:
certmanager.k8s.io/domain: istio.fortio.org
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: istio
certmanager.k8s.io/acme-challenge-type: http01
certmanager.k8s.io/issuer: letsencrypt-prod
# not working:
# kubernetes.io/ingress.global-static-ip-name: fortio-prod-ip
name: istio-ingress-certs-mgr
namespace: istio-system
spec:
rules:
- http:
paths:
# cert-manager adds its own rules to the ingress but we need our
# rule because we have to selectively disable auth for the service
# and route to the service and not a nodeport
- path: /.well-known/acme-challenge/.*
backend:
serviceName: cert-manager-ingress1
servicePort: http-certingr
# Unfortunately host isn't an array and there are no "*" allowed for all
host: fortio.istio.io
- http:
paths:
- path: /.well-known/acme-challenge/.*
backend:
serviceName: cert-manager-ingress2
servicePort: http-certingr
host: istio.fortio.org
90 changes: 90 additions & 0 deletions fortio/fortio.yaml
@@ -0,0 +1,90 @@
---
# Service definition
apiVersion: v1
kind: Service
metadata:
name: fortio-report
spec:
ports:
- port: 8080
name: http-report
- port: 8081
name: http-redir
selector:
app: fortio-report
---
# Deployment - 2 pods for miminal HA
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: fortio-report-deployment
spec:
replicas: 2 # tells deployment to run 2 pods matching the template
template: # create pods using pod definition in this template
metadata:
# a unique name is generated from the deployment name
labels:
app: fortio-report
spec:
containers:
- name: fortio-report
image: istio/fortio:latest
ports:
- containerPort: 8080 # main serving port
- containerPort: 8081 # redirection to https port
args:
- report # report only (readonly) mode
- -sync
# http...443 is not a typo, this is to work with egress
- http://storage.googleapis.com:443/fortio-data?prefix=fortio.istio.io/
#- -loglevel
#- verbose
volumeMounts:
- mountPath: /var/lib/istio/fortio
name: fortio-data
volumes:
- name: fortio-data
emptyDir:
medium: Memory
---
# Service definition
apiVersion: v1
kind: Service
metadata:
name: fortio-debug
spec:
ports:
- port: 8080
name: http-debug
selector:
app: fortio-debug
---
# Deployment (volume definition is in fortio-volume.yaml)
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: fortio-debug-deployment
spec:
replicas: 1 # tells deployment to run 1 pods matching the template
template: # create pods using pod definition in this template
metadata:
# a unique name is generated from the deployment name
labels:
app: fortio-debug
spec:
containers:
- name: fortio-debug
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resource limits would help with unbounded resource use and pod scheduling

image: istio/fortio:latest
ports:
- containerPort: 8080
---
apiVersion: "config.istio.io/v1alpha2"
kind: EgressRule
metadata:
name: cloud-storage-egress-rule
spec:
destination:
service: "storage.googleapis.com"
ports:
- port: 443
protocol: https
75 changes: 75 additions & 0 deletions fortio/ingress.yaml
@@ -0,0 +1,75 @@
# https version:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: istio
# Not working:
# kubernetes.io/ingress.global-static-ip-name: fortio-prod-ip
# Also not working:
kubernetes.io/ingress.allow-http: "false"
name: istio-ingress-https
spec:
tls:
- secretName: istio-ingress-certs # currently ignored/must be this
rules:
- http:
paths:
- path: /debug
backend:
serviceName: fortio-debug
servicePort: http-debug
- path: /.*
backend:
serviceName: fortio-report
servicePort: http-report
# Unfortunately host isn't an array and there are no "*" allowed for all
host: fortio.istio.io
- http:
paths:
- path: /debug
backend:
serviceName: fortio-debug
servicePort: http-debug
- path: /.*
backend:
serviceName: fortio-report
servicePort: http-report
host: istio.fortio.org
---
# http version (and catch all for all hosts/ips/...)
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: istio
# not working:
# kubernetes.io/ingress.global-static-ip-name: fortio-prod-ip
name: istio-ingress-http
spec:
rules:
- http:
paths:
- path: /debug
backend:
serviceName: fortio-debug
servicePort: http-debug
- path: /.*
backend:
serviceName: fortio-report
servicePort: http-report
# duplication needed because of #2573
- http:
paths:
- path: /.*
backend:
serviceName: fortio-report
servicePort: http-redir
host: fortio.istio.io
- http:
paths:
- path: /.*
backend:
serviceName: fortio-report
servicePort: http-redir
host: istio.fortio.org