feat: python3.11 base runtime image + DockerHub registry support

- runtimes/python3.11/: Dockerfile + server.py (HTTP wrapper на :8080)
- builder.go: RegistrySecret field, volume mount docker-creds для kaniko, убран --skip-tls-verify
- config.go: добавлен RegistrySecret (env REGISTRY_SECRET, default sless-registry-auth)
- main.go: передаём RegistrySecret в builder.Config
- hack/create-registry-secret.sh: создаёт k8s Secret из DockerHub токена

Образ наружу: naeel/sless-runtime-python3.11:latest (DockerHub)
K8s secret: sless-registry-auth в namespace sless
This commit is contained in:
“Naeel”
2026-03-07 09:32:59 +04:00
parent 33ee17729f
commit c61e822308
6 changed files with 195 additions and 33 deletions
+61 -25
View File
@@ -21,38 +21,41 @@ import (
// Builder — управляет сборкой Docker образов через kaniko Jobs в k8s.
type Builder struct {
client client.Client
builderImage string // образ kaniko
registryHost string // куда пушим образ
s3Endpoint string // откуда kaniko берёт код
s3AccessKey string
s3SecretKey string
s3Bucket string
namespace string // namespace где запускаем build Job'ы
client client.Client
builderImage string // образ kaniko
registryHost string // куда пушим образ
registrySecret string // имя k8s Secret с docker-кредами для kaniko
s3Endpoint string // откуда kaniko берёт код
s3AccessKey string
s3SecretKey string
s3Bucket string
namespace string // namespace где запускаем build Job'ы
}
// Config — параметры для создания Builder'а.
type Config struct {
BuilderImage string
RegistryHost string
S3Endpoint string
S3AccessKey string
S3SecretKey string
S3Bucket string
Namespace string
BuilderImage string
RegistryHost string
RegistrySecret string // имя k8s Secret с .dockerconfigjson для пуша образов
S3Endpoint string
S3AccessKey string
S3SecretKey string
S3Bucket string
Namespace string
}
// New создаёт новый Builder.
func New(c client.Client, cfg Config) *Builder {
return &Builder{
client: c,
builderImage: cfg.BuilderImage,
registryHost: cfg.RegistryHost,
s3Endpoint: cfg.S3Endpoint,
s3AccessKey: cfg.S3AccessKey,
s3SecretKey: cfg.S3SecretKey,
s3Bucket: cfg.S3Bucket,
namespace: cfg.Namespace,
client: c,
builderImage: cfg.BuilderImage,
registryHost: cfg.RegistryHost,
registrySecret: cfg.RegistrySecret,
s3Endpoint: cfg.S3Endpoint,
s3AccessKey: cfg.S3AccessKey,
s3SecretKey: cfg.S3SecretKey,
s3Bucket: cfg.S3Bucket,
namespace: cfg.Namespace,
}
}
@@ -96,8 +99,7 @@ func (b *Builder) Build(ctx context.Context, namespace, funcName, s3Key string)
Args: []string{
"--context=" + s3ContextURL,
"--destination=" + imageRef,
"--skip-tls-verify", // для внутреннего registry без TLS
"--cache=true", // кешируем слои для ускорения повторных сборок
"--cache=true", // кешируем слои для ускорения повторных сборок
},
Env: []corev1.EnvVar{
{Name: "AWS_ACCESS_KEY_ID", Value: b.s3AccessKey},
@@ -106,8 +108,11 @@ func (b *Builder) Build(ctx context.Context, namespace, funcName, s3Key string)
// Kaniko использует AWS SDK совместимый с S3 — задаём кастомный endpoint
{Name: "AWS_REGION", Value: "us-east-1"},
},
// Монтируем docker-креды из k8s Secret — kaniko читает авторизацию из /kaniko/.docker/config.json
VolumeMounts: b.dockerConfigMounts(),
},
},
Volumes: b.dockerConfigVolumes(),
},
},
},
@@ -152,4 +157,35 @@ func (b *Builder) Cleanup(ctx context.Context, jobName string) error {
return b.client.Delete(ctx, job, &client.DeleteOptions{PropagationPolicy: &propagation})
}
// dockerConfigVolumes возвращает Volume с docker-кредами если RegistrySecret задан.
// Ключ .dockerconfigjson монтируется как config.json — стандартное имя для kaniko.
func (b *Builder) dockerConfigVolumes() []corev1.Volume {
if b.registrySecret == "" {
return nil
}
return []corev1.Volume{
{
Name: "docker-config",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: b.registrySecret,
Items: []corev1.KeyToPath{
{Key: ".dockerconfigjson", Path: "config.json"},
},
},
},
},
}
}
// dockerConfigMounts возвращает VolumeMount для docker-кредов если RegistrySecret задан.
func (b *Builder) dockerConfigMounts() []corev1.VolumeMount {
if b.registrySecret == "" {
return nil
}
return []corev1.VolumeMount{
{Name: "docker-config", MountPath: "/kaniko/.docker"},
}
}
func int32Ptr(i int32) *int32 { return &i }