Привет, Хабр! Сегодня мы попробуем развернуть простой сервис в Kubernetes на примере KaaS в облачной платформе Рег.ру. В качестве самого сервиса будем использовать imgproxy — минималистичный сервис подготовки изображений для web с предельно простым API.
Этот гайд будет полезен новичкам, которые только начинают работу с Kubernetes. Рассмотрим, как настраивать среду и управлять ей, и освоим принципы работы с контейнерами. Кроме того, развертывание imgproxy в качестве примера поможет научиться обрабатывать изображения с помощью Kubernetes простым и удобным способом.
Навигация по тексту:
→ Создание кластера Kubernetes
→ Получение kubeconfig
→ Проверка kubeconfig
→ Установка ingress-nginx
→ Установка cert-manager
→ Разворачиваем imgproxy
→ Проверка работоспособности
Создание кластера Kubernetes
Для начала нам нужно создать кластер Kubernetes в личном кабинете облака cloud.reg.ru, например, с тремя воркер-нодами:
Получение kubeconfig
После создания кластера, чтобы к нему подключиться через kubectl, нужно получить для него файл kubeconfig со страницы деталей:
Подсказка: если это ваш единственный кластер Kubernetes, вы можете переместить файл kubeconfig в место по умолчанию: ~/.kube/config и не использовать далее параметр —kubeconfig. Для этого достаточно выполнить в терминале:
→ mv -v <путь к скачанному файлу> ~/.kube/config
В случае, если кластер не единственный и/или управление контекстами в kubectl кажется неудобным, можно использовать разные файлы kubeconfig для разных окружений. Такой способ может быть безопаснее в некоторых случаях: например, если некоторые файлы kubeconfig находятся на внешних зашифрованных носителях.
Проверка kubeconfig
После получения файла kubeconfig нужно проверить его работоспособность. Запросим список нод, неймспейсов, подов:
→ kubectl --kubeconfig ~/Downloads/kubeconfig_4137209 get nodes NAME STATUS ROLES AGE VERSION k8s4137209-az1-md1-gb86x-6fbhz Ready <none> 24m v1.30.2 k8s4137209-az1-md1-gb86x-cxxwq Ready <none> 24m v1.30.2 k8s4137209-az1-md1-gb86x-pkvvk Ready <none> 24m v1.30.2
→ kubectl --kubeconfig ~/Downloads/kubeconfig_4137209 get namespaces NAME STATUS AGE default Active 26m kube-node-lease Active 26m kube-public Active 26m kube-system Active 26m
→ kubectl --kubeconfig ~/Downloads/kubeconfig_4137209 get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system cilium-99rxc 1/1 Running 0 24m kube-system cilium-envoy-72sxw 1/1 Running 0 25m kube-system cilium-envoy-88bcm 1/1 Running 0 24m kube-system cilium-envoy-xk7t7 1/1 Running 0 24m kube-system cilium-gfb8h 1/1 Running 0 25m kube-system cilium-l4q2c 1/1 Running 0 24m kube-system cilium-operator-5cb45868f8-n55fq 1/1 Running 0 25m kube-system coredns-68d4f9776f-l2sbw 1/1 Running 0 25m kube-system coredns-68d4f9776f-xjwm7 1/1 Running 0 25m kube-system konnectivity-agent-4924v 1/1 Running 0 24m kube-system konnectivity-agent-gmgvb 1/1 Running 0 24m kube-system konnectivity-agent-v4f2l 1/1 Running 0 24m
Похоже, что все компоненты на месте, ноды есть. kube-apiserver, отдающий нам эту информацию, тоже работает.
Установка ingress-nginx
Начнем с установки ingress controller’а. Он нужен нам для того, чтобы получить трафик внутрь кластера Kubernetes. Использовать ingress’ы — не единственный способ этого достичь, но зачастую самый простой и удобный. В качестве ingress контроллера мы будем использовать ingress-nginx и дополним его cert-manager’ом для обеспечения возможности выписывания TLS-сертификатов от Let’s Encrypt.
Для установки ingress-nginx проще всего использовать helm:
→ helm \ --kubeconfig ~/Downloads/kubeconfig_4137209 \ upgrade \ --install ingress-nginx ingress-nginx/ingress-nginx \ --namespace ingress-nginx \ --create-namespace \ --set controller.kind=DaemonSet
Затем смотрим список подов и сервисов в namespace’е ingress-nginx и убеждаемся, что под с ingress controller’ом запущен, сервис создан и ему выделен внешний IP-адрес:
→ kubectl --kubeconfig ~/Downloads/kubeconfig_4137209 get pods,svc -n ingress-nginx NAME READY STATUS RESTARTS AGE pod/ingress-nginx-controller-55dd9c5f4-bv2mc 1/1 Running 0 92s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/ingress-nginx-controller LoadBalancer 10.105.18.179 89.108.100.213 80:31362/TCP,443:32472/TCP 92s service/ingress-nginx-controller-admission ClusterIP 10.102.26.77 <none> 443/TCP 92s
Установка cert-manager
cert-manager устанавливается по аналогии:
→ helm \ --kubeconfig ~/Downloads/kubeconfig_4137209 \ upgrade \ --install cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --set crds.enabled=true
Если по какой-то причине эта операция завершится ошибкой, в этом нет ничего страшного. Нужно просто повторить команду.
Единственное отличие: нам нужно будет создать ClusterIssuer для использования Let’s Encrypt, который мы возьмем прямо из документации cert-manager:
--- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: # The ACME server URL server: https://acme-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: user@example.com # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-prod # Enable the HTTP-01 challenge provider solvers: - http01: ingress: ingressClassName: nginx
Сохраним в файл и выполним kubectl apply на него:
→ cat <<EOF > clusterissuer.yaml --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: # The ACME server URL server: https://acme-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: user@example.com # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-prod # Enable the HTTP-01 challenge provider solvers: - http01: ingress: ingressClassName: nginx EOF → kubectl --kubeconfig ~/Downloads/kubeconfig_4137209 apply -f clusterissuer.yaml
Теперь нам нужно определиться с доменным именем, на котором будет работать наше тестовое приложение imgproxy. Я выберу поддомен imgproxy к одному из своих доменов и добавлю для него A-запись в DNS со значением внешнего IP сервиса — 89.108.100.213 в примере выше (у вас будет свой IP-адрес, ну и поддомен вы также можете выбрать свой).
Разворачиваем imgproxy
На этом инфраструктурная часть фактически закончена, и мы можем развернуть imgproxy. Он уже собран и поставляется в виде образа контейнера, для него даже есть готовый Helm Chart. Сам imgproxy в своей конфигурации очень прост, и в данном случае хочется показать “подкапотное пространство”, потому егомы развернем вручную, т.е. с использованием описаний самого Kubernetes. Для этого нам потребуется создать три ресурса: Deployment — с самим с приложением, Service — для организации балансировки между несколькими инстансами imgproxy и Ingress — для обеспечения доступа из сети Интернет. Бонусом, т.к. мы настроили cert-manager, мы получим TLS для нашего imgproxy.
Создаем deployment.yaml:
→ cat <<EOF > deployment.yaml --- apiVersion: apps/v1 kind: Deployment metadata: name: imgproxy labels: app.kubernetes.io/name: imgproxy app.kubernetes.io/app: imgproxy spec: replicas: 3 strategy: type: RollingUpdate revisionHistoryLimit: 3 selector: matchLabels: app.kubernetes.io/name: imgproxy app.kubernetes.io/app: imgproxy template: metadata: labels: app.kubernetes.io/name: imgproxy app.kubernetes.io/app: imgproxy spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app.kubernetes.io/app operator: In values: - imgproxy topologyKey: "kubernetes.io/hostname" terminationGracePeriodSeconds: 30 automountServiceAccountToken: false containers: - name: imgproxy image: darthsim/imgproxy:latest imagePullPolicy: IfNotPresent env: # the maximum duration (in seconds) for processing the response. # Default: 10 - name: IMGPROXY_WRITE_TIMEOUT value: '30' # the maximum duration (in seconds) to wait for the next request # before closing the connection. When set to 0, keep-alive is # disabled. Default: 10 - name: IMGPROXY_KEEP_ALIVE_TIMEOUT value: '30' # the maximum duration (in seconds) to wait for the next request # before closing the HTTP client connection. The HTTP client is # used to download source images. When set to 0, keep-alive is # disabled. Default: 90 - name: IMGPROXY_CLIENT_KEEP_ALIVE_TIMEOUT value: '40' # the maximum duration (in seconds) for downloading the source # image. Default: 5 - name: IMGPROXY_DOWNLOAD_TIMEOUT value: '30' # when set to true, enables using the ETag HTTP header for HTTP # cache control. Default: false - name: IMGPROXY_USE_ETAG value: 'true' # when set to true, enables using the Last-Modified HTTP header # for HTTP cache control. Default: false - name: IMGPROXY_USE_LAST_MODIFIED value: 'true' # when set to true, imgproxy will add debug headers to the response. # Default: false. The following headers will be added: # # X-Origin-Content-Length: the size of the source image # X-Origin-Width: the width of the source image # X-Origin-Height: the height of the source image # X-Result-Width: the width of the resultant image # X-Result-Height: the height of the resultant image - name: IMGPROXY_ENABLE_DEBUG_HEADERS value: 'true' # the maximum resolution of the source image, in megapixels. # Images with larger actual size will be rejected. Default: 50 - name: IMGPROXY_MAX_SRC_RESOLUTION value: '70' # the maximum size of the source image, in bytes. Images with # larger file size will be rejected. When set to 0, file size # check is disabled. Default: 0 - name: IMGPROXY_MAX_SRC_FILE_SIZE value: '104857600' # the default quality of the resultant image, percentage. # Default: 80 - name: IMGPROXY_QUALITY value: '90' # default quality of the resulting image per format, separated # by commas. Example: jpeg=70,avif=40,webp=60. When a value for # the resulting format is not set, the IMGPROXY_QUALITY value is # used. Default: avif=65 - name: IMGPROXY_FORMAT_QUALITY value: 'jpeg=90' ports: - name: http containerPort: 8080 protocol: TCP resources: requests: cpu: 10m memory: 32Mi limits: memory: 1Gi securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true EOF
service.yaml:
→ cat <<EOF > service.yaml --- apiVersion: v1 kind: Service metadata: name: imgproxy labels: app.kubernetes.io/name: imgproxy app.kubernetes.io/app: imgproxy spec: ports: - name: http port: 8080 protocol: TCP targetPort: 8080 selector: app.kubernetes.io/name: imgproxy app.kubernetes.io/app: imgproxy type: ClusterIP EOF
В ingress.yaml нужно поменять название домена на свой собственный, для которого была добавлена A-запись:
→ cat <<EOF > ingress.yaml --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/ssl-redirect: "true" kubernetes.io/ingress.class: nginx kubernetes.io/tls-acme: "true" cert-manager.io/cluster-issuer: letsencrypt-prod nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" nginx.ingress.kubernetes.io/client-body-buffer-size: 256m nginx.ingress.kubernetes.io/proxy-body-size: 256m labels: app.kubernetes.io/name: imgproxy app.kubernetes.io/app: imgproxy name: imgproxy spec: ingressClassName: nginx rules: - host: imgproxy.my-domain.ru http: paths: - backend: service: name: imgproxy port: number: 8080 path: / pathType: Prefix tls: - hosts: - imgproxy.my-domain.ru secretName: imgproxy.my-domain.ru EOF
Примечание: в примере выше используется доменное имя imgproxy.my-domain.ru, его нужно заменить на свое собственное.
После создания файлов применяем изменения:
kubectl apply -f deployment.yaml -f service.yaml -f ingress.yaml
Проверка работоспособности
Открываем браузер и идем по адресу https://<наш домен>/unsafe/resize:fit:300:300/plain/https:%2F%2Fmars.nasa.gov%2Fsystem%2Fdownloadable_items%2F40368_PIA22228.jpg
В результате мы видим изображение с размером, вписанным в квадрат 300×300 пикселей, т.е. все работает.
Мы пошагово разобрали, как развернуть сервис imgproxy в Kubernetes с помощью KaaS в облаке Рег.ру. Теперь, когда сервис работает, можно смело настраивать его, масштабировать и оптимизировать для своих задач. Если вы хотите углубиться в тему Kubernetes, прочитайте наши предыдущие статьи. Ранее мы писали про архитектуру KaaS и рассказывали о том, как мы его запускали в облаке Рег.ру.
ссылка на оригинал статьи https://habr.com/ru/articles/856686/
Добавить комментарий