How to deploy a node.js with redis on kubernetes?

前端 未结 5 1985
长发绾君心
长发绾君心 2021-01-12 18:57

I have a very simple node.js application (HTTP service), which \"talks\" to redis. I want to create a deployment and run it with minikube.

From my understanding, I n

相关标签:
5条回答
  • 2021-01-12 19:40

    I would run redis in a separate pod (i.e.: so your web app doesn't take down the redis server if itself crashes).

    Here is your redis deployment & service:

    deployment.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
    

    Since we've exposed a kubernetes Service you can then access your redis instance by hostname, or it's "service name", which is redis.

    You can check out my kubernetes redis repository at https://github.com/mateothegreat/k8-byexamples-redis. You can simply run make install if you want the easier route.

    Good luck and if you're still stuck please reach out!

    0 讨论(0)
  • 2021-01-12 19:41

    I recommend you to read further the k8s docs, but in general re your questions raised above:

    1. Yes another pod (with the relevant configuration) and an additional service depends on your use case, check this great example: https://kubernetes.io/docs/tutorials/configuration/configure-redis-using-configmap/
    2. Using services, read more here: https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/
    3. There are several ways to manage dependencies - search for deployment dependencies, but in general you can append them in the same file with readiness endpoint and expose using a Service - read more in the link in bullet 2
    0 讨论(0)
  • 2021-01-12 19:46
    1. yes you need a separete deployement and service for redis

    2. use kubernetes service discovery , should be built in , KubeDNS , CoreDNS

    3. use readniness and liveness probes

    Yes , you can write a single big yaml file to describe all the deployments and services. then:

    kubectl apply -f yourfile.yml

    or you can place the yaml in separate files and then do the :

     kubectl apply -f dir/
    
    0 讨论(0)
  • 2021-01-12 19:56

    I agree with all of the previous answers. I'm just trying to things more simple by executing a single command.

    First, create necessary manifests for redis in a file say redis.yaml and service to expose it outside.

    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
    

    Next put manifests for your app in another file say my-app.yaml. Here i put the volume field so that you can use the data that stored by 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
    

    Now we can use the following bash file 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
    

    Just run chmod +x my-app.sh; ./my-app.sh to deploy. To get the url run minikube service redis --url. You can similarly get the url for your app. The only thing is you need a nodePort type service for your app to access it from outside of the cluster.

    So, everything is in your hand now.

    0 讨论(0)
  • 2021-01-12 19:58

    I think I figured out a solution (using a Deployment and a Service).

    For my deployment, I used two containers (webapp + redis) within one Pod, since it doesn't make sense for a webapp to run without active redis instance, and additionally it connects to redis upon application start. I could be wrong in this reasoning, so feel free to correct me if you think otherwise.

    Here's my deployment:

    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: {}
    

    And here's the Service definition:

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

    I create the deployment with: kubectl create -f deployment.yaml Then, I create the service with kubectl create -f service.yaml I read the IP with minikube ip and extract the port from the output of kubectl describe service my-app-service.

    0 讨论(0)
提交回复
热议问题