Update to caddy v2.0.0 and fixes (#27)

* Update to caddy v2.0.0

* Fixes from #24

* Update rbac api and move ingresses from extensions api to networking

* Fix matchers

* Allow default backend

* Use caddyconfig.JSON

* Fix issuer

* Use empty image for docker
This commit is contained in:
Marc-Antoine 2020-05-16 13:43:57 +02:00 committed by GitHub
parent 3abf447b47
commit 022ff01309
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 640 additions and 118 deletions

View File

@ -1,26 +1,20 @@
FROM golang:alpine AS build
FROM golang:1.14.2-alpine AS builder
WORKDIR /app
ADD . /app
COPY go.mod go.sum ./
RUN go mod download
COPY ./cmd ./cmd
COPY ./pkg ./pkg
COPY ./internal ./internal
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./bin/ingress-controller ./cmd/caddy
FROM alpine:latest as certs
RUN apk --update add ca-certificates
FROM golang:1.13.5 as builder
WORKDIR /build
ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
RUN mkdir -p ./bin
COPY go.mod go.sum ./
RUN go mod download
COPY ./cmd ./cmd
COPY ./pkg ./pkg
COPY ./internal ./internal
RUN go build -o ./bin/ingress-controller ./cmd/caddy
FROM scratch
COPY --from=builder /build/bin/ingress-controller .
COPY --from=builder /app/bin/ingress-controller .
COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
EXPOSE 80 443
ENTRYPOINT ["/ingress-controller"]
ENTRYPOINT ["/ingress-controller"]

View File

@ -41,7 +41,7 @@ func main() {
logrus.Fatalf(msg, err)
}
restClient := kubeClient.ExtensionsV1beta1().RESTClient()
restClient := kubeClient.NetworkingV1beta1().RESTClient()
c := controller.NewCaddyController(kubeClient, restClient, cfg)
reg := prometheus.NewRegistry()

12
go.mod
View File

@ -1,13 +1,13 @@
module github.com/caddyserver/ingress
go 1.13
go 1.14
require (
github.com/caddyserver/caddy/v2 v2.0.0-beta11
github.com/mholt/certmagic v0.9.0
github.com/pkg/errors v0.8.1
github.com/prometheus/client_golang v1.1.0
github.com/sirupsen/logrus v1.4.2
github.com/caddyserver/caddy/v2 v2.0.0
github.com/caddyserver/certmagic v0.10.12
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.6.0
github.com/sirupsen/logrus v1.6.0
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
gopkg.in/go-playground/pool.v3 v3.1.1
k8s.io/api v0.17.0

628
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
apiVersion: extensions/v1beta1
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: example
@ -24,7 +24,7 @@ spec:
backend:
serviceName: example2
servicePort: 8080
- path: /hello
- path: /hello1
backend:
serviceName: example
servicePort: 8080

View File

@ -1,10 +1,8 @@
package caddy
import (
"encoding/json"
"fmt"
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig"
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
"github.com/caddyserver/caddy/v2/modules/caddytls"
)
@ -36,7 +34,9 @@ type ControllerConfig struct {
// NewConfig returns a plain slate caddy2 config file.
func NewConfig(namespace string, cfg ControllerConfig) *Config {
autoPolicyBytes := json.RawMessage(fmt.Sprintf(`{"module": "acme", "email": "%v"}`, cfg.Email))
acmeIssuer := caddytls.ACMEIssuer{
CA: getCAEndpoint(cfg.TLSUseStaging),
Email: cfg.Email}
return &Config{
Storage: Storage{
@ -48,10 +48,9 @@ func NewConfig(namespace string, cfg ControllerConfig) *Config {
Apps: map[string]interface{}{
"tls": caddytls.TLS{
Automation: &caddytls.AutomationConfig{
Policies: []caddytls.AutomationPolicy{
caddytls.AutomationPolicy{
Hosts: nil,
ManagementRaw: autoPolicyBytes,
Policies: []*caddytls.AutomationPolicy{
{
IssuerRaw: caddyconfig.JSONModuleObject(acmeIssuer, "module", "acme", nil),
},
},
},
@ -71,3 +70,10 @@ func NewConfig(namespace string, cfg ControllerConfig) *Config {
},
}
}
func getCAEndpoint(useStaging bool) string {
if useStaging {
return "https://acme-staging-v02.api.letsencrypt.org/directory"
}
return ""
}

View File

@ -3,9 +3,10 @@ package caddy
import (
"encoding/json"
"fmt"
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig"
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
"k8s.io/api/extensions/v1beta1"
"k8s.io/api/networking/v1beta1"
)
// ConvertToCaddyConfig returns a new caddy routelist based off of ingresses managed by this controller.
@ -25,18 +26,22 @@ func ConvertToCaddyConfig(ings []*v1beta1.Ingress) (caddyhttp.RouteList, error)
clusterHostName := fmt.Sprintf("%v.%v.svc.cluster.local:%d", path.Backend.ServiceName, ing.Namespace, path.Backend.ServicePort.IntVal)
r := baseRoute(clusterHostName)
r.MatcherSets = caddyhttp.MatcherSets{
{
caddyhttp.MatchHost{rule.Host},
caddyhttp.MatchPath{path.Path},
},
match := caddy.ModuleMap{}
if rule.Host != "" {
match["host"] = caddyconfig.JSON(caddyhttp.MatchHost{rule.Host}, nil)
}
if path.Path != "" {
match["path"] = caddyconfig.JSON(caddyhttp.MatchPath{path.Path}, nil)
}
r.MatcherSetsRaw = []caddy.ModuleMap{match}
routes = append(routes, r)
}
}
}
return routes, nil
}

View File

@ -10,7 +10,7 @@ import (
"github.com/caddyserver/ingress/internal/caddy"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"k8s.io/api/extensions/v1beta1"
"k8s.io/api/networking/v1beta1"
)
// loadConfigMap runs when a config map with caddy config is loaded on app start.

View File

@ -17,7 +17,7 @@ import (
"github.com/caddyserver/ingress/pkg/storage"
"github.com/sirupsen/logrus"
apiv1 "k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
"k8s.io/api/networking/v1beta1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"

View File

@ -9,7 +9,7 @@ import (
"github.com/sirupsen/logrus"
pool "gopkg.in/go-playground/pool.v3"
apiv1 "k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
"k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)
@ -47,7 +47,7 @@ func runUpdate(ing *v1beta1.Ingress, status []apiv1.LoadBalancerIngress, client
return nil, nil
}
ingClient := client.ExtensionsV1beta1().Ingresses(ing.Namespace)
ingClient := client.NetworkingV1beta1().Ingresses(ing.Namespace)
currIng, err := ingClient.Get(ing.Name, metav1.GetOptions{})
if err != nil {

View File

@ -7,7 +7,7 @@ import (
"github.com/caddyserver/ingress/internal/pod"
"github.com/sirupsen/logrus"
apiv1 "k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
"k8s.io/api/networking/v1beta1"
)
// dispatchSync is run every syncInterval duration to sync ingress source address fields.

View File

@ -8,7 +8,7 @@ import (
"github.com/sirupsen/logrus"
apiv1 "k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
"k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
sv1 "k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/kubernetes"

View File

@ -3,7 +3,7 @@ package store
import (
c "github.com/caddyserver/ingress/internal/caddy"
"github.com/sirupsen/logrus"
"k8s.io/api/extensions/v1beta1"
"k8s.io/api/networking/v1beta1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)
@ -18,7 +18,7 @@ type Store struct {
// NewStore returns a new store that keeps track of ingresses and secrets. It will attempt to get
// all current ingresses before returning.
func NewStore(kubeClient *kubernetes.Clientset, namespace string, cfg c.ControllerConfig, cfgMapConfig *c.Config) *Store {
ingresses, err := kubeClient.ExtensionsV1beta1().Ingresses("").List(v1.ListOptions{})
ingresses, err := kubeClient.NetworkingV1beta1().Ingresses("").List(v1.ListOptions{})
if err != nil {
logrus.Errorf("could not get existing ingresses in cluster")
return &Store{}

View File

@ -1,4 +1,4 @@
apiVersion: rbac.authorization.k8s.io/v1beta1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: caddy-ingress-controller-role
@ -6,7 +6,7 @@ metadata:
rules:
- apiGroups:
- ""
- "extensions"
- "networking.k8s.io"
resources:
- ingresses
- ingresses/status

View File

@ -1,5 +1,5 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: caddy-ingress-controller-role-binding
namespace: caddy-system

View File

@ -1,5 +1,5 @@
{{- if .Values.caddyingresscontroller.rbac.create }}
apiVersion: rbac.authorization.k8s.io/v1beta1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ .Values.name }}-role
@ -7,7 +7,7 @@ metadata:
rules:
- apiGroups:
- ""
- "extensions"
- "networking.k8s.io"
resources:
- ingresses
- ingresses/status

View File

@ -1,6 +1,6 @@
{{- if .Values.caddyingresscontroller.rbac.create }}
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ .Values.name }}-role-binding
namespace: {{ .Release.Namespace }}

View File

@ -6,11 +6,12 @@ import (
"strings"
"github.com/caddyserver/caddy/v2"
"github.com/mholt/certmagic"
"github.com/caddyserver/certmagic"
"github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
// matchLabels are attached to each resource so that they can be found in the future.
@ -42,6 +43,16 @@ func (SecretStorage) CaddyModule() caddy.ModuleInfo {
}
}
// Provisions the SecretStorage instance.
func (s *SecretStorage) Provision(ctx caddy.Context) error {
config, _ := clientcmd.BuildConfigFromFlags("", "")
// creates the clientset
clientset, _ := kubernetes.NewForConfig(config)
s.KubeClient = clientset
return nil
}
// CertMagicStorage returns a certmagic storage type to be used by caddy.
func (s *SecretStorage) CertMagicStorage() (certmagic.Storage, error) {
return s, nil