mirror of
https://github.com/eliasstepanik/caddy-ingess.git
synced 2026-01-11 04:28:28 +00:00
cleanup codebase and add documentation
This commit is contained in:
parent
d9e05a0a02
commit
cb1fbe77d9
5
Makefile
5
Makefile
@ -1,6 +1,3 @@
|
||||
build:
|
||||
@mkdir -p bin
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./bin/ingress-controller ./cmd/caddy
|
||||
|
||||
publish-docker:
|
||||
@echo 'TODO :- not implemented'
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./bin/ingress-controller ./cmd/caddy
|
||||
51
README.md
51
README.md
@ -47,3 +47,54 @@ View the pod logs:
|
||||
```sh
|
||||
kubectl logs <pod-name> -n caddy-system
|
||||
```
|
||||
|
||||
## Automatic HTTPS
|
||||
|
||||
By default, any hosts defined in an ingress resource will configure caddy to automatically get certificates from let's encrypt and
|
||||
will serve your side over HTTPS.
|
||||
|
||||
To disable automattic https you can set the argument `tls` on the caddy ingress controller to `false`.
|
||||
|
||||
Example:
|
||||
|
||||
Add args `tls=false` to the deployment.
|
||||
|
||||
```
|
||||
args:
|
||||
- -tls=false
|
||||
```
|
||||
|
||||
## Bringing Your Own Certificates
|
||||
|
||||
If you would like to disable automatic HTTPS for a specific host and use your own certificates you can create a new TLS secret in Kubernetes and define
|
||||
what certificates to use when serving your application on the ingress resource.
|
||||
|
||||
Example:
|
||||
|
||||
Create TLS secret `mycerts`, where `./tls.key` and `./tls.crt` are valid certificates for `test.com`.
|
||||
|
||||
```
|
||||
kubectl create secret tls mycerts --key ./tls.key --cert ./tls.crt
|
||||
```
|
||||
|
||||
```
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: example
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: caddy
|
||||
spec:
|
||||
rules:
|
||||
- host: test.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: test
|
||||
servicePort: 8080
|
||||
tls:
|
||||
- hosts:
|
||||
- test.com
|
||||
secretName: mycerts # use mycerts for host test.com
|
||||
```
|
||||
@ -12,7 +12,7 @@ func parseFlags() caddy.ControllerConfig {
|
||||
flag.StringVar(&email, "email", "", "the email address to use for requesting tls certificates if automatic https is enabled.")
|
||||
|
||||
var namespace string
|
||||
flag.StringVar(&namespace, "observe-namespace", "", "the namespace that you would like to observe kubernetes ingress resources in.")
|
||||
flag.StringVar(&namespace, "namespace", "", "the namespace that you would like to observe kubernetes ingress resources in.")
|
||||
|
||||
var enableAutomaticTLS bool
|
||||
flag.BoolVar(&enableAutomaticTLS, "tls", false, "defines if automatic tls should be enabled for hostnames defined in ingress resources.")
|
||||
|
||||
@ -37,22 +37,14 @@ func main() {
|
||||
// get client to access the kubernetes service api
|
||||
kubeClient, err := createApiserverClient()
|
||||
if err != nil {
|
||||
msg := `
|
||||
Error while initiating a connection to the Kubernetes API server.
|
||||
This could mean the cluster is misconfigured (e.g. it has invalid
|
||||
API server certificates or Service Accounts configuration)
|
||||
`
|
||||
|
||||
msg := "Could not establish a connection to the Kubernetes API Server."
|
||||
logrus.Fatalf(msg, err)
|
||||
}
|
||||
|
||||
restClient := kubeClient.ExtensionsV1beta1().RESTClient()
|
||||
|
||||
// start ingress controller
|
||||
c := controller.NewCaddyController(kubeClient, restClient, cfg)
|
||||
|
||||
reg := prometheus.NewRegistry()
|
||||
|
||||
reg.MustRegister(prometheus.NewGoCollector())
|
||||
reg.MustRegister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{
|
||||
PidFn: func() (int, error) { return os.Getpid(), nil },
|
||||
@ -69,6 +61,7 @@ func main() {
|
||||
logrus.Info("Starting the caddy ingress controller")
|
||||
go c.Run(stopCh)
|
||||
|
||||
// TODO :- listen to sigterm
|
||||
select {}
|
||||
}
|
||||
|
||||
@ -103,12 +96,11 @@ func createApiserverClient() (*kubernetes.Clientset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
logrus.Infof("Creating API client for %s", cfg.Host)
|
||||
|
||||
cfg.QPS = defaultQPS
|
||||
cfg.Burst = defaultBurst
|
||||
cfg.ContentType = "application/vnd.kubernetes.protobuf"
|
||||
|
||||
logrus.Infof("Creating API client for %s", cfg.Host)
|
||||
|
||||
client, err := kubernetes.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -143,13 +135,9 @@ func createApiserverClient() (*kubernetes.Clientset, error) {
|
||||
return nil, lastErr
|
||||
}
|
||||
|
||||
// this should not happen, warn the user
|
||||
if retries > 0 {
|
||||
logrus.Warningf("Initial connection to the Kubernetes API server was retried %d times.", retries)
|
||||
}
|
||||
|
||||
msg := "Running in Kubernetes cluster version v%v.%v (%v) - git (%v) commit %v - platform %v"
|
||||
logrus.Infof(msg, v.Major, v.Minor, v.GitVersion, v.GitTreeState, v.GitCommit, v.Platform)
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
@ -1,94 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: example
|
||||
labels:
|
||||
app: example
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: example
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: example
|
||||
spec:
|
||||
containers:
|
||||
- name: httpecho
|
||||
image: hashicorp/http-echo
|
||||
args:
|
||||
- "-listen=:8080"
|
||||
- "-text=hello world"
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: example2
|
||||
labels:
|
||||
app: example2
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: example2
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: example2
|
||||
spec:
|
||||
containers:
|
||||
- name: httpecho
|
||||
image: hashicorp/http-echo
|
||||
args:
|
||||
- "-listen=:8080"
|
||||
- "-text=hello world 2"
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: example
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: example2
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: example2
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: example
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: caddy
|
||||
spec:
|
||||
rules:
|
||||
- host: caddy2.kubed.co
|
||||
http:
|
||||
paths:
|
||||
- path: /hello2
|
||||
backend:
|
||||
serviceName: example2
|
||||
servicePort: 8080
|
||||
- backend:
|
||||
serviceName: example
|
||||
servicePort: 8080
|
||||
@ -12,12 +12,10 @@ import (
|
||||
// This is not used when this ingress controller is configured with a config map, so that we don't
|
||||
// override user defined routes.
|
||||
func ConvertToCaddyConfig(ings []*v1beta1.Ingress) (caddyhttp.RouteList, error) {
|
||||
// ~~~~
|
||||
// TODO :-
|
||||
// when setting the upstream url we should should bypass kube-dns and get the ip address of
|
||||
// the pod for the deployment we are proxying to so that we can proxy to that ip address port.
|
||||
// this is good for session affinity and increases performance.
|
||||
// ~~~~
|
||||
|
||||
// create a server route for each ingress route
|
||||
var routes caddyhttp.RouteList
|
||||
@ -46,6 +44,7 @@ func ConvertToCaddyConfig(ings []*v1beta1.Ingress) (caddyhttp.RouteList, error)
|
||||
return routes, nil
|
||||
}
|
||||
|
||||
// TODO :- configure log middleware for all routes
|
||||
func baseRoute(upstream string) caddyhttp.ServerRoute {
|
||||
return caddyhttp.ServerRoute{
|
||||
// Apply: []json.RawMessage{
|
||||
|
||||
@ -148,12 +148,11 @@ func (r ResourceDeletedAction) handle(c *CaddyController) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO :- Cleanup This Fn
|
||||
// updateConfig updates internal caddy config with new ingress info
|
||||
// updateConfig updates internal caddy config with new ingress info.
|
||||
func updateConfig(c *CaddyController) error {
|
||||
// if certs are defined on an ingress resource start a shared informer factory
|
||||
// to listen to any changes for these certs. If the certs are updated, reload
|
||||
// them into the caddy instance.
|
||||
apps := c.resourceStore.CaddyConfig.Apps
|
||||
|
||||
// if certs are defined on an ingress resource we need to handle them.
|
||||
tlsCfg, err := c.HandleOwnCertManagement(c.resourceStore.Ingresses)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "caddy config reload")
|
||||
@ -161,38 +160,20 @@ func updateConfig(c *CaddyController) error {
|
||||
|
||||
// after TLS secrets are synched we should load them in the cert pool.
|
||||
if tlsCfg != nil {
|
||||
if c, exists := c.resourceStore.CaddyConfig.Apps["tls"]; exists {
|
||||
if cfg, ok := c.(caddytls.TLS); ok {
|
||||
cfg.Certificates["load_folders"] = tlsCfg["load_folders"].(json.RawMessage)
|
||||
}
|
||||
}
|
||||
apps["tls"].(caddytls.TLS).Certificates["load_folders"] = tlsCfg["load_folders"].(json.RawMessage)
|
||||
} else {
|
||||
// reset cert loading
|
||||
if c, exists := c.resourceStore.CaddyConfig.Apps["tls"]; exists {
|
||||
if cfg, ok := c.(caddytls.TLS); ok {
|
||||
cfg.Certificates["load_folders"] = json.RawMessage(`[]`)
|
||||
}
|
||||
}
|
||||
apps["tls"].(caddytls.TLS).Certificates["load_folders"] = json.RawMessage(`[]`)
|
||||
}
|
||||
|
||||
// skip auto https for hosts with certs provided
|
||||
if tlsCfg != nil {
|
||||
if skipHosts, exists := tlsCfg["hosts"]; exists {
|
||||
if hosts, ok := skipHosts.([]string); ok {
|
||||
if httpCfg, exists := c.resourceStore.CaddyConfig.Apps["http"]; exists {
|
||||
if cfg, ok := httpCfg.(caddyhttp.App); ok {
|
||||
cfg.Servers["ingress_server"].AutoHTTPS.Skip = hosts
|
||||
}
|
||||
}
|
||||
}
|
||||
if hosts, ok := tlsCfg["hosts"].([]string); ok {
|
||||
apps["http"].(caddyhttp.App).Servers["ingress_server"].AutoHTTPS.Skip = hosts
|
||||
}
|
||||
} else {
|
||||
// reset any skipped hosts set
|
||||
if httpCfg, exists := c.resourceStore.CaddyConfig.Apps["http"]; exists {
|
||||
if cfg, ok := httpCfg.(caddyhttp.App); ok {
|
||||
cfg.Servers["ingress_server"].AutoHTTPS.Skip = make([]string, 0)
|
||||
}
|
||||
}
|
||||
apps["http"].(caddyhttp.App).Servers["ingress_server"].AutoHTTPS.Skip = make([]string, 0)
|
||||
}
|
||||
|
||||
if !c.usingConfigMap {
|
||||
@ -202,11 +183,7 @@ func updateConfig(c *CaddyController) error {
|
||||
}
|
||||
|
||||
// set the http server routes
|
||||
if httpCfg, exists := c.resourceStore.CaddyConfig.Apps["http"]; exists {
|
||||
if cfg, ok := httpCfg.(caddyhttp.App); ok {
|
||||
cfg.Servers["ingress_server"].Routes = serverRoutes
|
||||
}
|
||||
}
|
||||
apps["http"].(caddyhttp.App).Servers["ingress_server"].Routes = serverRoutes
|
||||
}
|
||||
|
||||
// reload caddy with new config
|
||||
|
||||
@ -31,10 +31,7 @@ func (c *CaddyController) syncStatus(ings []*v1beta1.Ingress) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// this happens about every 30 seconds and can pollute the logs, so we
|
||||
// only want to log on higher verbosity levels.
|
||||
logrus.Info("Synching Ingress resource source addresses")
|
||||
|
||||
c.updateIngStatuses(sliceToLoadBalancerIngress(addrs), ings)
|
||||
|
||||
return nil
|
||||
|
||||
@ -2,7 +2,6 @@ package controller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -73,8 +72,6 @@ func (c *CaddyController) HandleOwnCertManagement(ings []*v1beta1.Ingress) (map[
|
||||
go informer.Run(c.stopChan)
|
||||
}
|
||||
|
||||
fmt.Printf("\nCERTS: %+v - %+v\n", len(certs), certs)
|
||||
|
||||
if len(certs) > 0 {
|
||||
return getTLSConfig(hosts), nil
|
||||
}
|
||||
|
||||
@ -28,24 +28,26 @@ func NewStore(kubeClient *kubernetes.Clientset, namespace string, cfg c.Controll
|
||||
Ingresses: []*v1beta1.Ingress{},
|
||||
}
|
||||
|
||||
if cfgMapConfig == nil {
|
||||
s.CaddyConfig = c.NewConfig(namespace, cfg)
|
||||
} else {
|
||||
// set cert-magic storage provider
|
||||
cfgMapConfig.Storage = c.Storage{
|
||||
System: "secret_store",
|
||||
StorageValues: c.StorageValues{
|
||||
Namespace: namespace,
|
||||
},
|
||||
}
|
||||
|
||||
s.CaddyConfig = cfgMapConfig
|
||||
}
|
||||
|
||||
for _, i := range ingresses.Items {
|
||||
s.Ingresses = append(s.Ingresses, &i)
|
||||
}
|
||||
|
||||
// not using cfg map to configure the ingress controller
|
||||
if cfgMapConfig == nil {
|
||||
s.CaddyConfig = c.NewConfig(namespace, cfg)
|
||||
return s
|
||||
}
|
||||
|
||||
// set cert-magic storage provider
|
||||
cfgMapConfig.Storage = c.Storage{
|
||||
System: "secret_store",
|
||||
StorageValues: c.StorageValues{
|
||||
Namespace: namespace,
|
||||
},
|
||||
}
|
||||
|
||||
s.CaddyConfig = cfgMapConfig
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user