Найти тему

Локальный репозиторий для K8s

Понадобилось мне завести локальный репозиторий куда будут отправлятся собранные образы, которые будут исопльзоватся в k8s. Я не хочу устанавливать паралельно ни docker, ни podman, зачем оно мне если я ими не буду пользоваться...

И Так мне нужно две вещи:

1. Развернуть локальный registry

2. Придумать как собирать и публиковать образы в реестр

Наверное я плохо гуглю, но толком ничгео вразумительного не нашёл.

В Целом всё оказалось просто, как я понял есть все реестры базируются на https://github.com/distribution/distribution

у него есть оффициальный образ https://registry.hub.docker.com/_/registry/

Ну вот его и задеплоим в нашем кластере.

Создал 2 файла, в одном описал хранилище, во втором сам реестр:

volumes.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: registry.volume
labels:
target: registry
type: registry_volume
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
storageClassName: local-storage
hostPath:
path: /var/lib/registry

---

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
target: registry
type: registry_volume
name: registry.pvc
spec:
resources:
requests:
storage: 8Gi
storageClassName: local-storage
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
Проверим:
$ kubectl apply --dry-run=client -f volumes.yaml

persistentvolume/registry_volume created (dry run)
persistentvolumeclaim/registry_pvc created (dry run)
Примненим:
$ kubectl apply -f volumes.yaml

persistentvolume/registry.volume created
persistentvolumeclaim/registry.pvc created

Отлично разделы создали. Посмотрим что получилось

kubectl get pv,pvc --all-namespaces

Второй файл для самого реестра:

registry.yaml
apiVersion: v1
kind: Service
metadata:
name: registry-service
spec:
selector:
app: registry
ports:
- port: 5000
targetPort: 5000
nodePort: 30000
type: NodePort

---

apiVersion: apps/v1
kind: Deployment
metadata:
name: registry
labels:
app: registry
spec:
selector:
matchLabels:
app: registry
template:
metadata:
labels:
app: registry
spec:
volumes:
- name: registry-volume
persistentVolumeClaim:
claimName: registry.pvc
containers:
- name: registry
volumeMounts:
- name: registry-volume
mountPath: /var/lib/registry
image: registry:2.8.2
ports:
- containerPort: 5000

Тут я в service указал type:NodePort и nodePort: 30000, чтобы реестр был доступ из вне.

Проверим

$ kubectl apply --dry-run=client -f registry.yaml

service/registry-service configured (dry run)
deployment.apps/registry configured (dry run)

Применим

$ kubectl apply -f registry.yaml
service/registry-service configured
deployment.apps/registry configured

Ну вроди удачно.

Попробуем посмостреть, что есть в репозитории, и вообще можем ли мы к нему подключится:

curl -X GET http://localhost:30000/v2/_catalog
{"repositories":[]}

О, отлично, репозиторий пустой. ( ‾́ ◡ ‾́ )

Ещё одна фигня, это то что кубер не умеет сам собирать контейнеры... страннооооо это фсё... Т.к. я не хочу ставить docker и podman, то пошёл гуглить как же собирать образы...

В итоге там куча всяких проектов, можно взять Buildah и не мучаться, можно воспользоватся kaniko, что я и сделал, но я вообще не въехал как им пользоваться внутри k8s, поэтому я собрал бинарник

git clone https://github.com/GoogleContainerTools/kaniko.git

Т.к. я собирал на винде, под linux то нужно установить переменные, в терминале пишем:

> go env -w GOOS=linux
> go env GOOS GOARCH

Дальше если установлена система сборки пишем make и ждем, но у меня не стоит, и ставить ради этого не охота. поэтому я сделал это ручками: ¯\_(ツ)_/¯

go build -ldflags '-extldflags "-static" -X github.com/GoogleContainerTools/kaniko/pkg/version.version=v1.15.0 -w -s ' -o out/executor github.com/GoogleContainerTools/kaniko/cmd/executor

есть ещё какойто warmer, не знаю что это, ноаверно пригодится:)

go build -ldflags '-extldflags "-static" -X github.com/GoogleContainerTools/kaniko/pkg/version.version=v1.15.0 -w -s ' -o out/warmer github.com/GoogleContainerTools/kaniko/cmd/warmer

В директории out появится два бинарника, по сути нас интересует executor, закидываем его на наш сервер с k8s , я кинул в дирректорию /usr/local/bin и переименовал его в build, не забываем дать права на исполнение.

Протестируем, создадим Dockerfile, например /home/test/Dockerfile

FROM ubuntu
ENTRYPOINT ["/bin/bash", "-c", "echo hello"]

Не знаю на кой чёрт, но kaniko нужна папка /kaniko в корне сервера. Можно либо создать её самому, либо запутсить первый раз сборку с повышеными правами, так и сделаем:

sudo build  --dockerfile=/home/test/Dockerfile --destination=localhost:30000/kubuntu:v2 --force

Тут всё просто --dockerfile указываем путь к нашему Dockerfile , --destination указываем куда сохранить образ. Если всё отработало ок то вывод будет таким:

WARN[0000] Kaniko is being run outside of a container. This can have dangerous effects on your system
INFO[0000] Retrieving image manifest ubuntu
INFO[0000] Retrieving image ubuntu from registry index.docker.io
INFO[0005] Built cross stage deps: map[]
INFO[0005] Retrieving image manifest ubuntu
INFO[0005] Returning cached image manifest
INFO[0005] Executing 0 build triggers
INFO[0005] Building stage 'ubuntu' [idx: '0', base-idx: '-1']
INFO[0005] Skipping unpacking as no commands require it.
INFO[0005] ENTRYPOINT ["/bin/bash", "-c", "echo hello"]
INFO[0005] Pushing image to localhost:30000/kubuntu:v2
INFO[0006] Pushed localhost:30000/kubuntu@sha256:d7ba0f0d462ea09377da808fc744b4d071b4a49558375f1a7b35b57d4f86a9e7

Иначе выведет справку, в начале которой будет ошибка.

Проверим есть ли что то в нашем реестре:

$ curl -X GET http://localhost:30000/v2/_catalog
{"repositories":["kubuntu"]}

Magic (∩ᄑ_ᄑ)⊃━☆゚*・。*・:≡( ε:) Ура Ура!

Теперь попробуем использовать наш образ в k8s

Создадим yaml файл

kubuntu.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubuntu
spec:
selector:
matchLabels:
app: kubuntu
template:
metadata:
labels:
app: kubuntu
spec:
containers:
- name: kubuntu
image: localhost:30000/kubuntu:latest
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 6000

И применим

$ kubectl apply -f kubuntu.yaml

deployment.apps/kubuntu created

Посмотрим какие у нас поды:


$ kubectl get pods

NAME READY STATUS RESTARTS AGE
kubuntu-5b8b8c9bdd-9jhp5 0/1 ContainerCreating 0 3s
registry-5f98d4544c-dhd54 1/1 Running 0 77m

Отлично kubuntu контейнер создан, но остановлен, потому что там нечему выполнятся. Глянем логи:

$kubectl logs kubuntu-5b8b8c9bdd-9jhp5
hello

Отлично то что и должно было вывестись.

Удалим

kubectl delete kubuntu-5b8b8c9bdd-9jhp5