Create helm chart for spegel

This commit is contained in:
Philip Laine 2023-01-25 13:14:41 +01:00
parent 7c6c11efe6
commit b6fd45c393
13 changed files with 284 additions and 159 deletions

23
charts/spegel/.helmignore Normal file
View File

@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

6
charts/spegel/Chart.yaml Normal file
View File

@ -0,0 +1,6 @@
apiVersion: v2
name: spegel
description: Stateless distributed registry mirroring in Kubernetes.
type: application
version: v0.0.1
appVersion: v0.0.1

View File

@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "spegel.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "spegel.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "spegel.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "spegel.labels" -}}
helm.sh/chart: {{ include "spegel.chart" . }}
{{ include "spegel.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "spegel.selectorLabels" -}}
app.kubernetes.io/name: {{ include "spegel.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "spegel.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "spegel.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,97 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: {{ include "spegel.fullname" . }}
labels:
{{- include "spegel.labels" . | nindent 4 }}
spec:
selector:
matchLabels:
{{- include "spegel.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "spegel.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: registry
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
args:
- --pod-ip=$(POD_IP)
- --service-name={{ include "spegel.fullname" . }}-headless.{{ .Release.Namespace }}.svc.cluster.local.
- --registry-addr=:{{ .Values.service.registry.port }}
- --metrics-addr=:{{ .Values.service.metrics.port }}
- --redis-addr={{ required "Redis Address is required" .Values.spegel.redisAddr }}
- --containerd-sock={{ .Values.spegel.containerdSock }}
- --containerd-namespace={{ .Values.spegel.containerdNamespace }}
- --containerd-registry-config-path={{ .Values.spegel.containerdRegistryConfigPath }}
- --containerd-mirror-add={{ .Values.spegel.containerdMirrorAdd }}
- --containerd-mirror-remove={{ .Values.spegel.containerdMirrorRemove }}
{{- with .Values.spegel.imageFilter }}
- --image-filter
- {{ . | quote }}
{{- end }}
{{- with .Values.spegel.mirrorRegistries }}
- --mirror-registries
{{- range . }}
- {{ . | quote }}
{{- end }}
{{- end }}
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
ports:
- name: registry
containerPort: {{ .Values.service.registry.port }}
hostPort: {{ .Values.service.registry.port }}
hostIP: "127.0.0.1"
protocol: TCP
- name: metrics
containerPort: {{ .Values.service.metrics.port }}
protocol: TCP
readinessProbe:
httpGet:
path: /healthz
port: registry
volumeMounts:
- name: containerd-sock
mountPath: "/run/containerd/containerd.sock"
- name: containerd-config
mountPath: "/etc/containerd/certs.d"
resources:
{{- toYaml .Values.resources | nindent 10 }}
volumes:
- name: containerd-sock
hostPath:
path: "/run/containerd/containerd.sock"
- name: containerd-config
hostPath:
path: "/etc/containerd/certs.d"
type: DirectoryOrCreate
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@ -0,0 +1,30 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "spegel.fullname" . }}
labels:
{{- include "spegel.labels" . | nindent 4 }}
spec:
selector:
{{- include "spegel.selectorLabels" . | nindent 4 }}
ports:
- name: metrics
port: {{ .Values.service.metrics.port }}
targetPort: metrics
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: {{ include "spegel.fullname" . }}-headless
labels:
{{- include "spegel.labels" . | nindent 4 }}
spec:
clusterIP: "None"
selector:
{{- include "spegel.selectorLabels" . | nindent 4 }}
ports:
- name: registry
port: {{ .Values.service.registry.port }}
targetPort: registry
protocol: TCP

60
charts/spegel/values.yaml Normal file
View File

@ -0,0 +1,60 @@
image:
repository: ghcr.io/xenitab/spegel
pullPolicy: IfNotPresent
tag: ""
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
podAnnotations: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
registry:
port: 5000
metrics:
port: 9090
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations:
- operator: Exists
effect: NoSchedule
affinity: {}
spegel:
redisAddr: ""
mirrorRegistries:
- https://docker.io
- https://ghcr.io
- https://quay.io
imageFilter: ""
containerdSock: "/run/containerd/containerd.sock"
containerdNamespace: "k8s.io"
containerdRegistryConfigPath: "/etc/containerd/certs.d"
containerdMirrorAdd: true
containerdMirrorRemove: true

View File

@ -14,10 +14,10 @@ type RedisStore struct {
client rueidis.Client client rueidis.Client
} }
func NewRedisStore(podIP string, peer Peers, redisEndpoints []string) (Store, error) { func NewRedisStore(podIP string, peer Peers, redisAddr string) (Store, error) {
opts := rueidis.ClientOption{ opts := rueidis.ClientOption{
DisableCache: true, DisableCache: true,
InitAddress: redisEndpoints, InitAddress: []string{redisAddr},
} }
client, err := rueidis.NewClient(opts) client, err := rueidis.NewClient(opts)
if err != nil { if err != nil {

View File

@ -29,11 +29,11 @@ import (
type arguments struct { type arguments struct {
PodIP string `arg:"--pod-ip,required"` PodIP string `arg:"--pod-ip,required"`
ServiceName string `arg:"--service-name,required"` ServiceName string `arg:"--service-name,required"`
RedisEndpoints []string `arg:"--redis-endpoints,required"`
MirrorRegistries []url.URL `arg:"--mirror-registries,required"`
ImageFilter string `arg:"--image-filter"`
RegistryAddr string `arg:"--registry-addr" default:":5000"` RegistryAddr string `arg:"--registry-addr" default:":5000"`
MetricsAddr string `arg:"--metrics-addr" default:":9090"` MetricsAddr string `arg:"--metrics-addr" default:":9090"`
RedisAddr string `arg:"--redis-addr, required"`
MirrorRegistries []url.URL `arg:"--mirror-registries,required"`
ImageFilter string `arg:"--image-filter"`
ContainerdSock string `arg:"--containerd-sock" default:"/run/containerd/containerd.sock"` ContainerdSock string `arg:"--containerd-sock" default:"/run/containerd/containerd.sock"`
ContainerdNamespace string `arg:"--containerd-namespace" default:"k8s.io"` ContainerdNamespace string `arg:"--containerd-namespace" default:"k8s.io"`
ContainerdRegistryConfigPath string `arg:"--containerd-registry-config-path" default:"/etc/containerd/certs.d"` ContainerdRegistryConfigPath string `arg:"--containerd-registry-config-path" default:"/etc/containerd/certs.d"`
@ -84,7 +84,7 @@ func main() {
}) })
// Setup and run store // Setup and run store
store, err := store.NewRedisStore(args.PodIP, store.NewDNS(args.ServiceName), args.RedisEndpoints) store, err := store.NewRedisStore(args.PodIP, store.NewDNS(args.ServiceName), args.RedisAddr)
if err != nil { if err != nil {
log.Error(err, "could not create store") log.Error(err, "could not create store")
os.Exit(1) os.Exit(1)

View File

@ -1,58 +0,0 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: spegel
spec:
selector:
matchLabels:
name: spegel
template:
metadata:
labels:
name: spegel
spec:
containers:
- name: registry
image: xenitab/spegel:dev
imagePullPolicy: Never
args:
- "--mirror-registries"
- "https://docker.io"
- "--pod-ip"
- "$(POD_IP)"
- "--service-name"
- "spegel-headless.spegel.svc.cluster.local"
- "--redis-endpoints"
- "redis.spegel.svc.cluster.local:6379"
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
ports:
- name: registry
containerPort: 5000
hostPort: 5000
hostIP: "127.0.0.1"
- name: metrics
containerPort: 9090
readinessProbe:
httpGet:
path: /healthz
port: registry
volumeMounts:
- name: containerd-sock
mountPath: "/run/containerd/containerd.sock"
- name: containerd-config
mountPath: "/etc/containerd/certs.d"
volumes:
- name: containerd-sock
hostPath:
path: "/run/containerd/containerd.sock"
- name: containerd-config
hostPath:
path: "/etc/containerd/certs.d"
type: DirectoryOrCreate
tolerations:
- operator: Exists
effect: NoSchedule

View File

@ -1,8 +0,0 @@
namespace: spegel
resources:
- namespace.yaml
- daemonset.yaml
- service.yaml
- redis.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

View File

@ -1,4 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: spegel

View File

@ -1,57 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-config
data:
redis-config: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7.0.8
command:
- redis-server
- "/redis-master/redis.conf"
env:
- name: MASTER
value: "true"
ports:
- containerPort: 6379
volumeMounts:
- mountPath: /redis-master-data
name: data
- mountPath: /redis-master
name: config
volumes:
- name: data
emptyDir: {}
- name: config
configMap:
name: redis-config
items:
- key: redis-config
path: redis.conf
---
apiVersion: v1
kind: Service
metadata:
name: redis
spec:
selector:
app: redis
ports:
- port: 6379
targetPort: 6379

View File

@ -1,26 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: spegel
spec:
selector:
name: spegel
ports:
- name: metrics
protocol: TCP
port: 9090
targetPort: metrics
---
apiVersion: v1
kind: Service
metadata:
name: spegel-headless
spec:
clusterIP: "None"
selector:
name: spegel
ports:
- name: registry
protocol: TCP
port: 5000
targetPort: registry