Как развернуть node.js с помощью redis на kubernetes? - PullRequest
0 голосов
/ 28 октября 2018

У меня есть очень простое приложение node.js (служба HTTP), которое «общается» с redis.Я хочу создать развертывание и запустить его с помощью minikube.

Насколько я понимаю, мне нужен модуль Kubernetes для моего приложения, основанный на образе докера.Вот мой Dockerfile:

FROM node:8.9.1
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD ["npm", "start"]

Я создаю образ докера с помощью docker build -t my-app .

Затем я создал определение Pod для Pod моего приложения:

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: my-app
    image: my-app:latest
    imagePullPolicy: Never
    ports:
    - containerPort: 8080

Итакочень хорошоНо с этого момента у меня нет четкой идеи, как действовать с redis:

  1. должен ли redis быть другим Pod или службой (в терминах типа Kubernetes)?

  2. Как мне ссылаться на Redis внутри моего приложения?В зависимости от того, будет ли redis определен как Pod / Service, как мне получить URL-адрес и порт подключения?Я читал о переменных среды, создаваемых Kubernetes, но я не уверен, работают ли они для Pod или Сервисов.

  3. Как объединить оба (мое приложение и redis) в одной конфигурации?Как убедиться, что сначала запускается redis, затем мое приложение (для которого требуется запустить экземпляр redis), и как мне выставить мои конечные точки HTTP «внешнему миру»?Я читал о развертываниях, но я не уверен, как соединить эти части вместе.

В идеале, я хотел бы, чтобы все конфигурации были в файлах YAML, чтобы в конце днявся инфраструктура может быть запущена одной командой.

Ответы [ 5 ]

0 голосов
/ 29 октября 2018

Я согласен со всеми предыдущими ответами.Я просто пытаюсь сделать вещи проще, выполнив одну команду.

Во-первых, создайте необходимые манифесты для redis в файле скажем redis.yaml и сервис для его показа снаружи.

apiVersion: v1
kind: Service
metadata:
  name: redis
  labels:
    app: node-redis
spec:
  ports:
  - name: redis
    port: 6379
    targetPort: 6379
  type: NodePort
  selector:
    app: node-redis
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
spec:
  selector:
    matchLabels:
      app: node-redis
  replicas: 1
  template:
    metadata:
      labels:
        app: node-redis
    spec:
      containers:
      - name: redis
        image: redis:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 6379
        # data volume where redis writes data
        volumeMounts:
        - name: data
          mountPath: /data
          readOnly: false
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: redis-data
---
# data volume
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: redis-data
  labels:
    app: node-redis
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 100Mi

Затем поместите манифесты для вашего приложения в другом файле, скажем my-app.yaml.Здесь я поместил поле громкости, чтобы вы могли использовать данные, которые хранятся в Redis.

apiVersion: v1
kind: Pod
metadata:
  name: my-app
  labels:
    app: node-redis
spec:
  containers:
  - name: my-app
    image: my-app:latest
    ports:
    - containerPort: 8080
    # data volume from where my-app read data those are written by redis
    volumeMounts:
    - name: data
      mountPath: /data
      readOnly: false
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: redis-data

Теперь мы можем использовать следующий файл bash my-app.sh.

#!/bin/bash

kubectl create -f redis.yaml

pod_name=$(kubectl get po -l app=node-redis | grep app-with-redis | awk '{print $1}')

# check whether redis server is ready or not
while true; do
  pong=$(kubectl exec -it $pod_name -c redis redis-cli ping)
  if [[ "$pong" == *"PONG"* ]]; then
    echo ok;
    break
  fi
done

kubectl create -f my-app.yaml

Просто запуститеchmod +x my-app.sh; ./my-app.sh для развертывания.Чтобы получить URL, запустите minikube service redis --url.Вы также можете получить URL для вашего приложения.Единственное, вам нужен сервис типа nodePort, чтобы приложение могло обращаться к нему из-за пределов кластера.

Итак, все в ваших руках.

0 голосов
/ 29 октября 2018

Я думаю, что я нашел решение (с использованием развертывания и службы).

Для своего развертывания я использовал два контейнера (webapp + redis) в одном модуле, так как это не имеет смысла длявеб-приложение, запускаемое без активного экземпляра Redis, и дополнительно оно подключается к Redis при запуске приложения.Я могу ошибаться в этом рассуждении, поэтому не стесняйтесь исправлять меня, если вы думаете иначе.

Вот мое развертывание:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment
spec:
  selector:
    matchLabels:
      app: my-app-deployment
  template:
    metadata:
      labels:
        app: my-app-deployment
    spec:
      containers:
      - name: redis
        image: redis:latest
        ports:
        - containerPort: 6379
        volumeMounts:
        - mountPath: /srv/www
          name: redis-storage
      - name: my-app
        image: my-app:latest
        imagePullPolicy: Never
        ports:
        - containerPort: 8080
      volumes:
      - name: redis-storage
        emptyDir: {}

А вот определение Сервиса:

apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  ports:
  - port: 8080
    protocol: TCP
  type: NodePort
  selector:
    app: my-app-deployment

Я создаю развертывание с помощью: kubectl create -f deployment.yaml Затем я создаю службу с kubectl create -f service.yaml Я читаю IP с помощью minikube ip и извлекаю порт из вывода kubectl describe service my-app-service.

0 голосов
/ 28 октября 2018

Я рекомендую вам прочитать далее документы k8s, но в целом ваши вопросы, поднятые выше:

  1. Да, еще один модуль (с соответствующей конфигурацией) и дополнительная услуга зависит от вашего варианта использования,посмотрите на этот замечательный пример: https://kubernetes.io/docs/tutorials/configuration/configure-redis-using-configmap/
  2. Используя службы, читайте больше здесь: https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/
  3. Существует несколько способов управления зависимостями - поиск зависимостей развертывания, но в целом вы можете добавить ихв том же файле с готовностью конечной точки и выставить с помощью службы - подробнее в ссылке в пуле 2
0 голосов
/ 29 октября 2018

Я бы запустил Redis в отдельном модуле (т. Е. Ваше веб-приложение не отключает сервер Redis в случае сбоя).

Вот ваше развертывание и служба Redis:

deploy.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
spec:
  selector:
    matchLabels:
      app: redis
  replicas: 1
  template:
    metadata:
      labels:
        app: redis
    spec:
      volumes:
        - name: host-sys
          hostPath:
            path: /sys
      initContainers:
        - name: disable-thp
          image: redis:4.0-alpine
          volumeMounts:
            - name: host-sys
              mountPath: /host-sys
          command: ["sh", "-c", "echo never > /host-sys/kernel/mm/transparent_hugepage/enabled"]
      containers:
      - name: redis
        image: redis:4.0-alpine
        imagePullPolicy: IfNotPresent
        resources:
          requests:
            cpu: 350m
            memory: 1024Mi
        ports:
        - containerPort: 6379

service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: redis
  labels:
    app: redis
spec:
  ports:
  - port: 6379
    name: redis
  selector:
    app: redis

Так как мы представили kubernetes Service, вы можете получить доступ к своему экземпляру redis по имени хоста, или это "имя службы ", которое redis.

Вы можете проверить мой репозиторий kubernetes redis на https://github.com/mateothegreat/k8-byexamples-redis. Вы можете просто запустить make install, если хотите более простой маршрут.

Удачи, и если вы все еще застряли, пожалуйста, протянуть руку!

0 голосов
/ 28 октября 2018
  1. да, вам нужен отдельный deployement и service для повторного использования

  2. использование обнаружения службы kubernetes, должно быть встроено, KubeDNS, CoreDNS

  3. использовать датчики готовности и работоспособности

Да, вы можете написать один большой файл yaml для описания всех развертываний и служб.затем:

kubectl apply -f yourfile.yml

или вы можете поместить yaml в отдельные файлы и затем выполнить:

 kubectl apply -f dir/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...