Commit 2a6d9396 authored by Jens Langhammer's avatar Jens Langhammer

Merge branch 't1-cache' into 'master'

tier0 Cache

See merge request !2
parents b5d9f7b1 8ab98404
Pipeline #3864 passed with stage
in 1 minute and 42 seconds
......@@ -19,3 +19,4 @@ tag_name = version/{new_version}
[bumpversion:file:.gitlab-ci.yml]
[bumpversion:file:tier0/internal/version.go]
......@@ -3,7 +3,7 @@ stages:
- build-build-image
- test
- build
- docs
- package
image: docker.beryju.org/p2/build-base:latest
services:
- postgres:latest
......@@ -52,7 +52,8 @@ coverage:
- coverage html
stage: test
package-docker:
build-p2-server:
stage: build
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
......@@ -60,12 +61,24 @@ package-docker:
- echo "{\"auths\":{\"docker.beryju.org\":{\"auth\":\"$DOCKER_AUTH\"}}}" > /kaniko/.docker/config.json
script:
- /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination docker.beryju.org/p2/server:latest --destination docker.beryju.org/p2/server:0.5.7
only:
- tags
- /^version/.*$/
build-p2-tier0:
stage: build
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
before_script:
- echo "{\"auths\":{\"docker.beryju.org\":{\"auth\":\"$DOCKER_AUTH\"}}}" > /kaniko/.docker/config.json
script:
- /kaniko/executor --context $CI_PROJECT_DIR/tier0 --dockerfile $CI_PROJECT_DIR/tier0/Dockerfile --destination docker.beryju.org/p2/tier0:latest --destination docker.beryju.org/p2/tier0:0.5.7
only:
- tags
- /^version/.*$/
package-helm:
stage: build
stage: package
script:
- curl https://raw.githubusercontent.com/helm/helm/master/scripts/get | bash
- helm init --client-only
......@@ -79,7 +92,7 @@ package-helm:
- tags
- /^version/.*$/
package-installer:
stage: build
stage: package
script:
- echo Hello World
artifacts:
......
{{- if .Values.beta_enable_tier0 -}}
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: {{ include "p2.fullname" . }}-tier0
labels:
app.kubernetes.io/name: {{ include "p2.name" . }}
helm.sh/chart: {{ include "p2.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
replicas: {{ .Values.deployment.tier0Instances }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "p2.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "p2.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
k8s.p2.io/component: tier0
spec:
serviceAccountName: {{ include "p2.fullname" . }}-tier0
containers:
- name: {{ .Chart.Name }}-tier0
image: "docker.beryju.org/p2/tier0:{{ .Values.image.tag }}"
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8092
protocol: TCP
- name: http-cache
containerPort: 8093
protocol: TCP
livenessProbe:
httpGet:
path: /_/tier0/health
port: http
readinessProbe:
httpGet:
path: /_/tier0/health
port: http
{{- end }}
{{- if .Values.beta_enable_tier0 -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "p2.fullname" . }}-tier0
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "p2.fullname" . }}-tier0-role
rules:
- apiGroups: [""]
resources:
- services
- pods
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "p2.fullname" . }}-tier0
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ include "p2.fullname" . }}-tier0-role
subjects:
- kind: ServiceAccount
name: {{ include "p2.fullname" . }}-tier0
{{- end }}
{{- if .Values.beta_enable_tier0 -}}
apiVersion: v1
kind: Service
metadata:
name: {{ include "p2.fullname" . }}-tier0
labels:
app.kubernetes.io/name: {{ include "p2.name" . }}
helm.sh/chart: {{ include "p2.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
type: ClusterIP
ports:
- port: 8092
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: {{ include "p2.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
k8s.p2.io/component: tier0
{{- end }}
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "p2.fullname" . -}}
{{- $ingressPath := .Values.ingress.path -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ $fullName }}
name: {{ include "p2.fullname" . }}
labels:
app.kubernetes.io/name: {{ include "p2.name" . }}
helm.sh/chart: {{ include "p2.chart" . }}
......@@ -33,9 +31,20 @@ spec:
- host: {{ . | quote }}
http:
paths:
- path: {{ $ingressPath }}
{{- if .Values.beta_enable_tier0 -}}
- path: /_/
backend:
serviceName: {{ $fullName }}
serviceName: {{ include "p2.fullname" . }}-web
servicePort: http
- path: /
backend:
serviceName: {{ include "p2.fullname" . }}-tier0
servicePort: http
{{- else }}
- path: /
backend:
serviceName: {{ include "p2.fullname" . }}-web
servicePort: http
{{- end }}
{{- end }}
{{- end }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "p2.fullname" . }}
name: {{ include "p2.fullname" . }}-web
labels:
app.kubernetes.io/name: {{ include "p2.name" . }}
helm.sh/chart: {{ include "p2.chart" . }}
......
......@@ -15,9 +15,12 @@ config:
# configure passbook then upgrade with external_auth_only = true.
external_auth_only: false
beta_enable_tier0: false
deployment:
webInstances: 2
workerInstances: 1
tier0Instances: 2
postgresql:
postgresqlUsername: p2
......@@ -25,7 +28,6 @@ postgresql:
ingress:
enabled: true
path: /
hosts:
- p2.k8s.local
tls: []
......
vendor
Dockerfile
bin
# Created by https://www.gitignore.io/api/go
# Edit at https://www.gitignore.io/?templates=go
### Go ###
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
### Go Patch ###
/vendor/
/Godeps/
# End of https://www.gitignore.io/api/go
FROM golang:latest AS builder
WORKDIR /go/src/git.beryju.org/BeryJu.org/p2/tier0
ENV GO111MODULE=on
ENV GOOS=linux
ENV GOARCH=amd64
ENV CGO_ENABLED=0
COPY . .
RUN go mod download && \
go build -ldflags "-s -w" -v -o /go/bin/tier0
FROM alpine:latest
COPY --from=builder /go/bin/tier0 /tier0
CMD "/tier0"
module git.beryju.org/BeryJu.org/p2/tier0
go 1.12
require (
github.com/gogo/protobuf v1.2.1 // indirect
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef // indirect
github.com/golang/protobuf v1.3.1 // indirect
github.com/google/gofuzz v1.0.0 // indirect
github.com/googleapis/gnostic v0.3.0 // indirect
github.com/gorilla/handlers v1.4.0
github.com/hashicorp/golang-lru v0.5.1 // indirect
github.com/json-iterator/go v1.1.6 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/qbig/groupcache v0.0.0-20170504020517-747546dcc5ad
github.com/sirupsen/logrus v1.4.2
github.com/spf13/pflag v1.0.3 // indirect
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 // indirect
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 // indirect
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.2.2 // indirect
k8s.io/api v0.0.0-20190313235455-40a48860b5ab
k8s.io/apimachinery v0.0.0-20190313205120-d7deff9243b1
k8s.io/client-go v11.0.0+incompatible
k8s.io/klog v0.3.3 // indirect
k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a // indirect
sigs.k8s.io/yaml v1.1.0 // indirect
)
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/googleapis/gnostic v0.3.0 h1:CcQijm0XKekKjP/YCz28LXVSpgguuB+nCxaSjCe09y0=
github.com/googleapis/gnostic v0.3.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA=
github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/qbig/groupcache v0.0.0-20170504020517-747546dcc5ad h1:WJr46IY9YwA1M5+vSb2MBMIiJa/2ehqRvwIwYO1xVzo=
github.com/qbig/groupcache v0.0.0-20170504020517-747546dcc5ad/go.mod h1:Ax/m9kBsMl7sMEurQvYveoag1CzLyR6zQ6snXHxWAWc=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 h1:ydJNl0ENAG67pFbB+9tfhiL2pYqLhfoaZFw/cjLhY4A=
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
k8s.io/api v0.0.0-20190313235455-40a48860b5ab h1:DG9A67baNpoeweOy2spF1OWHhnVY5KR7/Ek/+U1lVZc=
k8s.io/api v0.0.0-20190313235455-40a48860b5ab/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
k8s.io/apimachinery v0.0.0-20190313205120-d7deff9243b1 h1:IS7K02iBkQXpCeieSiyJjGoLSdVOv2DbPaWHJ+ZtgKg=
k8s.io/apimachinery v0.0.0-20190313205120-d7deff9243b1/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
k8s.io/client-go v11.0.0+incompatible h1:LBbX2+lOwY9flffWlJM7f1Ct8V2SRNiMRDFeiwnJo9o=
k8s.io/client-go v11.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.3 h1:niceAagH1tzskmaie/icWd7ci1wbG7Bf2c6YGcQv+3c=
k8s.io/klog v0.3.3/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a h1:2jUDc9gJja832Ftp+QbDV0tVhQHMISFn01els+2ZAcw=
k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
package internal
const Version = "0.5.6"
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: demo-echo-service
labels:
k8s-app: demo-echo-service
spec:
replicas: 1
selector:
matchLabels:
k8s-app: demo-echo-service
template:
metadata:
labels:
k8s-app: demo-echo-service
spec:
terminationGracePeriodSeconds: 60
containers:
- name: echo-service
image: electroma/ingress-demo-echosvc-amd64:0.1
ports:
- containerPort: 8080
resources:
limits:
cpu: 10m
memory: 20Mi
requests:
cpu: 10m
memory: 20Mi
---
apiVersion: v1
kind: Service
metadata:
name: demo-echo-service
labels:
k8s-app: demo-echo-service
k8s.p2.io/component: web
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8080
selector:
k8s-app: demo-echo-service
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: p2-tier0
labels:
app.kubernetes.io/name: p2-tier0
app.kubernetes.io/managed-by: p2-tier0
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: p2-tier0
template:
metadata:
labels:
app.kubernetes.io/name: p2-tier0
k8s.p2.io/component: cache
spec:
containers:
- name: p2-tier0
image: "tier0:test"
imagePullPolicy: Never
ports:
- name: http
containerPort: 8092
protocol: TCP
- name: http-cache
containerPort: 8093
protocol: TCP
livenessProbe:
httpGet:
path: /_/tier0/health
port: http
readinessProbe:
httpGet:
path: /_/tier0/health
port: http
apiVersion: v1
kind: Service
metadata:
name: p2-tier0-http
labels:
app.kubernetes.io/name: p2-tier0
spec:
type: ClusterIP
ports:
- port: 8092
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: p2-tier0
package main
import (
"bytes"
"fmt"
"net/http"
"net/url"
"os"
"time"
"git.beryju.org/BeryJu.org/p2/tier0/internal"
"git.beryju.org/BeryJu.org/p2/tier0/pkg/cache"
"git.beryju.org/BeryJu.org/p2/tier0/pkg/constants"
"git.beryju.org/BeryJu.org/p2/tier0/pkg/k8s"
"git.beryju.org/BeryJu.org/p2/tier0/pkg/p2"
"github.com/gorilla/handlers"
"github.com/qbig/groupcache"
log "github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
)
func main() {
log.SetLevel(log.DebugLevel)
log.Debugf("Starting p2-tier0 Version %s", internal.Version)
k8sc, err := k8s.NewKubernetesContext()
if err != nil {
log.Fatal(err)
}
webClusterIP, err := k8sc.WebClusterIP()
if err != nil {
log.Fatal(err)
}
// Central stopping channel
stop := make(chan struct{})
upstream := p2.NewUpstream(fmt.Sprintf("http://%s", webClusterIP))
localCache := cache.NewCache(upstream)
localCache.SetPeersFromK8s(k8sc)
// Update Cache Peers by watching k8s
go k8sc.WatchNewCachePods(stop, func(pod v1.Pod) {
localCache.SetPeersFromK8s(k8sc)
})
go localCache.StartCacheServer()
groupcache.RegisterErrLogHook(func(err error) {
log.Warning(err)
})
log.Printf("Running on %s...", constants.Listen)
// Create main HTTP Server
mainServer := http.NewServeMux()
mainServer.HandleFunc("/_/tier0/health", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
})
mainServerHandler := func(w http.ResponseWriter, r *http.Request) {
var data []byte
escapedPath := url.QueryEscape(r.URL.Path)
context := cache.CacheContext{
RequestHeader: r.Header,
Host: r.Host,
}
err := localCache.Group.Get(context, escapedPath, groupcache.AllocatingByteSliceSink(&data))
if err != nil {
log.Fatal(err)
}
http.ServeContent(w, r, "", time.Now(), bytes.NewReader(data))
}
mainServer.Handle("/", handlers.LoggingHandler(os.Stdout, http.HandlerFunc(mainServerHandler)))
err = http.ListenAndServe(constants.Listen, mainServer)
if err != nil {
log.Fatal(err)
}
defer close(stop)
}
package cache
import (
"fmt"
"net"
"net/http"
"os"
"github.com/gorilla/handlers"
"git.beryju.org/BeryJu.org/p2/tier0/pkg/constants"
"git.beryju.org/BeryJu.org/p2/tier0/pkg/k8s"
"git.beryju.org/BeryJu.org/p2/tier0/pkg/p2"
"github.com/qbig/groupcache"
log "github.com/sirupsen/logrus"
)
type Cache struct {
Group *groupcache.Group
Logger *log.Entry
Pool *groupcache.HTTPPool
hostname string
localIP string
}
type CacheContext struct {
groupcache.Context
RequestHeader http.Header
Host string
}
func NewCache(upstream p2.Upstream) Cache {
logger := log.WithFields(log.Fields{
"component": "cache",
})
cache := groupcache.NewGroup("tier0", constants.CacheSize, groupcache.GetterFunc(
func(_ctx groupcache.Context, key string, dest groupcache.Sink) error {
if _ctx == nil {
logger.Warningf("Empty context for key '%s'", key)
return nil
}
ctx := _ctx.(CacheContext)
logger.Debugf("Fetching upstream key '%s'", key)
blob, err := upstream.Fetch(ctx.Host, key)
if err == nil {
dest.SetBytes(blob.Data)
} else {
logger.Debugf("Error fetching blob: %s", err)
}
return nil
}))
// We save our local IP to prevent endless circles
hostname, err := os.Hostname()
if err != nil {
logger.Debug(err)
}
ip, err := net.LookupHost(hostname)
if err != nil {
logger.Debug(err)
}
pool := groupcache.NewHTTPPool(fmt.Sprintf("http://%s%s", ip[0], constants.ListenCache))
return Cache{
Group: cache,
Logger: logger,
Pool: pool,
hostname: hostname,
localIP: ip[0],
}
}
func (c *Cache) StartCacheServer() {
cacheServer := http.NewServeMux()
cacheServer.HandleFunc("/_groupcache/", c.Pool.ServeHTTP)
log.Infof("Running Cache-Peer server on %s...", constants.ListenCache)
http.ListenAndServe(constants.ListenCache, handlers.LoggingHandler(os.Stdout, cacheServer))
}
func (c *Cache) SetPeersFromK8s(k8sc k8s.KubernetesContext) {
pods := k8sc.PodsForComponent("tier0")
podAddresses := make([]string, 0)
for _, element := range pods.Items {
if element.Status.PodIP != "" {
podURL := fmt.Sprintf("http://%s%s", element.Status.PodIP, constants.ListenCache)
podAddresses = append(podAddresses, podURL)
}
}
if len(podAddresses) > 0 {
c.Pool.Set(podAddresses...)
c.Logger.Debugf("Set Peers to %s", podAddresses)
}
}
package constants
const CacheSize = 64 << 20
const Listen = ":8092"
const ListenCache = ":8093"
package k8s
import (
"errors"
"io/ioutil"
log "github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)
type KubernetesContext struct {
*kubernetes.Clientset
Namespace string
Logger *log.Entry
}
// NewKubernetesContext Connect to kubernetes cluster
func NewKubernetesContext() (KubernetesContext, error) {
logger := log.WithFields(log.Fields{
"component": "k8s",
})
logger.Debug("Attempting to use InClusterConfig...")
// creates the in-cluster config
config, err := rest.InClusterConfig()
if err != nil {
logger.Warning(err)
return KubernetesContext{}, err
}
// creates the clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
logger.Warning(err)
return KubernetesContext{}, err
}
// Since we can't get the namespace directly, we have to try and read /var/run/secrets/kubernetes.io/serviceaccount/namespace
namespaceBytes, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace")
if err != nil {
logger.Warning(err)
return KubernetesContext{}, err
}
namespace := string(namespaceBytes)
logger.Debugf("Detected current namespace: %s", namespace)
return KubernetesContext{clientset, namespace, logger}, nil
}
// PodsForComponent get all pods which belong to component, used for Cache Peers
func (k8sc *KubernetesContext) PodsForComponent(component string) *v1.PodList {
labelSelector := metav1.LabelSelector{MatchLabels: map[string]string{"k8s.p2.io/component": component}}
pods, err := k8sc.CoreV1().Pods(k8sc.Namespace).List(metav1.ListOptions{
LabelSelector: labels.Set(labelSelector.MatchLabels).String(),
})
if err != nil {
k8sc.Logger.Warning(err)
return nil
}
return pods
}
// WebClusterIP Get ClusterIP to access p2 server
func (k8sc *KubernetesContext) WebClusterIP() (string, error) {
labelSelector := metav1.LabelSelector{MatchLabels: map[string]string{"k8s.p2.io/component": "web"}}
services, err := k8sc.CoreV1().Services(k8sc.Namespace).List(metav1.ListOptions{
LabelSelector: labels.Set(labelSelector.MatchLabels).String(),
})
if err != nil {
k8sc.Logger.Warning(err)
return "", err
}
if len(services.Items) < 1 {
err := errors.New("No Service found")
k8sc.Logger.Warning(err)
return "", err