暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Dapr quickstart

编程阁楼 2021-04-11
675

本文使用的demo是官方提供的hello-kubernates项目,代码地址:https://github.com/dapr/quickstarts/tree/master/hello-kubernetes

读者需自行clone该项目代码。

Step 1    -    dapr初始化

$ dapr init --kubernetes
ℹ️ Note: this installation is recommended for testing purposes. For production environments, please use Helm

⌛ Making the jump to hyperspace...
✅ Deploying the Dapr Operator to your cluster...
✅ Success! Dapr has been installed. To verify, run 'dapr status -k' in your terminal. To get started, go here: https://aka.ms/dapr-getting-started


Step 2 - Create and configure a state store

Dapr can use a number of different state stores (Redis, CosmosDB, DynamoDB, Cassandra, etc) to persist and retrieve state. This demo will use Redis.

本文使用已安装好的redis服务,修改redis.yaml文件中的redis连接信息:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
metadata:
 # These settings will work out of the box if you use `helm install
 # bitnami/redis`. If you have your own setup, replace
 # `redis-master:6379` with your own Redis master address, and the
 # Redis password with your own Secret's name. For more information,
 # see https://docs.dapr.io/operations/components/component-secrets .
- name: redisHost
  value: redis-master-0.redis-headless.redis.svc.cluster.local:6379
- name: redisPassword
  value: <YOUR_REDIS_PASSWORD>
 # secretKeyRef:
 #   name: redis
 #   key: redis-password
auth:
secretStore: kubernetes


执行apply安装:

$ kubectl apply -f ./deploy/redis.yaml
component.dapr.io/statestore created


Step 3 - Deploy the Node.js app with the Dapr sidecar

node.yaml

kind: Service
apiVersion: v1
metadata:
name: nodeapp
labels:
  app: node
spec:
selector:
  app: node
ports:
- protocol: TCP
  port: 80
  targetPort: 3000
type: LoadBalancer

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodeapp
labels:
  app: node
spec:
replicas: 1
selector:
  matchLabels:
    app: node
template:
  metadata:
    labels:
      app: node
    annotations:
      dapr.io/enabled: "true"
      dapr.io/app-id: "nodeapp"
      dapr.io/app-port: "3000"
  spec:
    containers:
    - name: node
      image: dapriosamples/hello-k8s-node:latest
      ports:
      - containerPort: 3000
      imagePullPolicy: Always

配置中的这三项是dapr的相关内容

# 启动dapr
dapr.io/enabled: "true"    
# dapr中的appId
dapr.io/app-id: "nodeapp"
# 应用的http端口
dapr.io/app-port: "3000"

这个app.js源码如下:

// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------

const express = require('express');
const bodyParser = require('body-parser');
require('isomorphic-fetch');

const app = express();
app.use(bodyParser.json());

// These ports are injected automatically into the container.
const daprPort = process.env.DAPR_HTTP_PORT;
const daprGRPCPort = process.env.DAPR_GRPC_PORT;

const stateStoreName = `statestore`;
const stateUrl = `http://localhost:${daprPort}/v1.0/state/${stateStoreName}`;
const port = 3000;

app.get('/order', (_req, res) => {
   fetch(`${stateUrl}/order`)
      .then((response) => {
           if (!response.ok) {
               throw "Could not get state.";
          }

           return response.text();
      }).then((orders) => {
           res.send(orders);
      }).catch((error) => {
           console.log(error);
           res.status(500).send({message: error});
      });
});

app.post('/neworder', (req, res) => {
   const data = req.body.data;
   const orderId = data.orderId;
   console.log("Got a new order! Order ID: " + orderId);

   const state = [{
       key: "order",
       value: data
  }];

   fetch(stateUrl, {
       method: "POST",
       body: JSON.stringify(state),
       headers: {
           "Content-Type": "application/json"
      }
  }).then((response) => {
       if (!response.ok) {
           throw "Failed to persist state.";
      }

       console.log("Successfully persisted state.");
       res.status(200).send();
  }).catch((error) => {
       console.log(error);
       res.status(500).send({message: error});
  });
});

app.get('/ports', (_req, res) => {
   console.log("DAPR_HTTP_PORT: " + daprPort);
   console.log("DAPR_GRPC_PORT: " + daprGRPCPort);
   res.status(200).send({DAPR_HTTP_PORT: daprPort, DAPR_GRPC_PORT: daprGRPCPort })
});

app.listen(port, () => console.log(`Node App listening on port ${port}!`));

注意:neworder接口,这里收到请求后调用Dapr的state接口将数据持久化存储了。


执行apply安装:

$ kubectl apply -f ./deploy/node.yaml

查看是否安装成功:

$ kubectl get svc nodeapp
NAME     TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S)       AGE
nodeapp   NodePort   10.88.0.173   <none>        80:32325/TCP   2h


我们采用NodePort模式(仅测试使用),将nodeapp ip映射出来:

$ curl -s 10.110.2.74:32325/ports | python -m json.tool
{
   "DAPR_GRPC_PORT": "50001",
   "DAPR_HTTP_PORT": "3500"
}


Step 5 - Deploy the Python app with the Dapr sidecar

python.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: pythonapp
labels:
  app: python
spec:
replicas: 2
selector:
  matchLabels:
    app: python
template:
  metadata:
    labels:
      app: python
    annotations:
      dapr.io/enabled: "true"
      dapr.io/app-id: "pythonapp"
  spec:
    containers:
    - name: python
      image: dapriosamples/hello-k8s-python:latest

这个app.py源码如下:

# ------------------------------------------------------------
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# ------------------------------------------------------------

import os
import requests
import time

dapr_port = os.getenv("DAPR_HTTP_PORT", 3500)
dapr_url = "http://localhost:{}/v1.0/invoke/nodeapp/method/neworder".format(dapr_port)

n = 0
while True:
   n += 1
   message = {"data": {"orderId": n}}

   try:
       response = requests.post(dapr_url, json=message, timeout=5)
       if not response.ok:
           print("HTTP %d => %s" % (response.status_code,
                                    response.content.decode("utf-8")), flush=True)
   except Exception as e:
       print(e, flush=True)

   time.sleep(1)

可以看到,一直循环调用nodeapp的neworder接口。


执行apply安装:

$ kubectl apply -f ./deploy/python.yaml

查看是否安装成功:

$ kubectl get pods --selector=app=python
NAME                         READY   STATUS   RESTARTS   AGE
pythonapp-6cc7dd7cfc-fg6mg   2/2     Running   0         2h


Step 6 - Observe messages

$ kubectl logs --selector=app=node -c node --tail=-1 -f
Got a new order! Order ID: 146155
Successfully persisted state.
Got a new order! Order ID: 146157
Successfully persisted state.
Got a new order! Order ID: 146159
Successfully persisted state.
Got a new order! Order ID: 146161
Successfully persisted state.
Got a new order! Order ID: 146163
Successfully persisted state.
Got a new order! Order ID: 146154


Step 7 - Confirm successful persistence

$ curl -s http://10.110.2.74:32325/order | python -m json.tool
{
   "orderId": 146398
}


Step 8 - 登录redis验证存储的数据

redis-master-0:/$ redis-cli 
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> keys *
1) "nodeapp||order"
2) "bitmap_cat"
3) "mybit"
127.0.0.1:6379> type nodeapp||order
hash
127.0.0.1:6379> hgetall nodeapp||order
1) "data"
2) "{\"orderId\":146856}"
3) "version"
4) "137146"


That is all!


文章转载自编程阁楼,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论