[原创]Dapr入门教程之四:Dapr程序的部署(Kubernetes模式)

上一篇我们在Standalone模式部署了第一个Dapr程序。这一次我们换成在Kubernetes模式下部署同样的程序。
程序来自Dapr官方的quickstarts教程里的Hello Kubernetes,我们用目前的最新版本v1.0.0-rc.2。

$ git clone -b v1.0.0-rc.2 https://github.com/dapr/quickstarts.git
$ cd quickstarts/hello-kubernetes

里面包括一个Python的程序,每秒发1个HTTP Request给Node程序。一个Node程序,用来在StateStore里保存发过来的OrderId。

下面开始部署。Kubernetes模式的Dapr Runtime的安装,请参看本系列的第二章Dapr的安装
首先要先部署Redis。跟Standalone模式不同,Kubernetes模式的Dapr Runtime安装的时候不会自动安装Redis,需要手动安装。

$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm repo update
$ helm install redis bitnami/redis

NAME: redis
LAST DEPLOYED: Sun Jan  3 12:42:17 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
** Please be patient while the chart is being deployed **
Redis can be accessed via port 6379 on the following DNS names from within your cluster:

redis-master.default.svc.cluster.local for read/write operations
redis-slave.default.svc.cluster.local for read-only operations

To get your password run:

    export REDIS_PASSWORD=$(kubectl get secret --namespace default redis -o jsonpath="{.data.redis-password}" | base64 --decode)

To connect to your Redis server:

1. Run a Redis pod that you can use as a client:
   kubectl run --namespace default redis-client --rm --tty -i --restart='Never'     --env REDIS_PASSWORD=$REDIS_PASSWORD    --image docker.io/bitnami/redis:6.0.9-debian-10-r38 -- bash

2. Connect using the Redis CLI:
   redis-cli -h redis-master -a $REDIS_PASSWORD
   redis-cli -h redis-slave -a $REDIS_PASSWORD

To connect to your database from outside the cluster execute the following commands:

    kubectl port-forward --namespace default svc/redis-master 6379:6379 &
    redis-cli -h 127.0.0.1 -p 6379 -a $REDIS_PASSWORD

安装完成。看一下Pod里多了什么:

$ kubectl get pods
NAME             READY   STATUS    RESTARTS   AGE
redis-master-0   1/1     Running   0          2m5s
redis-slave-0    1/1     Running   0          2m5s
redis-slave-1    1/1     Running   0          1m7s

接下来部署Statestore。

$ cd quickstarts/hello-kubernetes/deploy
$ kubectl apply -f redis.yaml
component.dapr.io/statestore created

redis.yaml的内容如下:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore
spec:
  type: state.redis
  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:6379
  - name: redisPassword
    secretKeyRef:
      name: redis
      key: redis-password
auth:
  secretStore: kubernetes

意思是部署一个名字叫statestore的Component,类型为state.redis。
用dapr cli看一下components:

$ dapr components -k
  NAME        TYPE         VERSION  SCOPES  CREATED              AGE
  statestore  state.redis                   2021-01-03 12:50.41  58s

接下来部署Node的APP。

$ kubectl apply -f node.yaml
service/nodeapp created
deployment.apps/nodeapp created

其中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

看一下service:

$ kubectl get svc
NAME             TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                               AGE
kubernetes       ClusterIP      10.96.0.1        <none>        443/TCP                               83m
nodeapp          LoadBalancer   10.96.83.185     <pending>     80:31324/TCP                          49m
nodeapp-dapr     ClusterIP      None             <none>        80/TCP,50001/TCP,50002/TCP,9090/TCP   49m
redis-headless   ClusterIP      None             <none>        6379/TCP                              60m
redis-master     ClusterIP      10.109.27.202    <none>        6379/TCP                              60m
redis-slave      ClusterIP      10.103.201.158   <none>        6379/TCP                              60m

启动了一个nodeap的service和一个nodeapp-dapr(就是sidecar)的service。
因为是运行在minikube上,所以nodeapp的service没有EXTERNAL IP(显示为pending)。
看一下pod:

$ kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
nodeapp-5d5dc88584-kqr2v   2/2     Running   0          13m
redis-master-0             1/1     Running   0          142m
redis-slave-0              1/1     Running   0          142m
redis-slave-1              1/1     Running   0          141m

看一下nodeapp的log:

$ kubectl logs nodeapp-5d5dc88584-kqr2v -c node
Node App listening on port 3000!
DAPR_HTTP_PORT: 3500
DAPR_GRPC_PORT: 50001

下面部署python的APP:

$ kubectl apply -f python.yaml
deployment.apps/pythonapp created

python.yaml的内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pythonapp
  labels:
    app: python
spec:
  replicas: 1
  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

看一下pod里多了什么:

$ kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
nodeapp-5d5dc88584-kqr2v   2/2     Running   0          16m
pythonapp-fcb4f49b-n6ltf   2/2     Running   0          49s
redis-master-0             1/1     Running   0          145m
redis-slave-0              1/1     Running   0          145m
redis-slave-1              1/1     Running   0          144m

看一下nodeapp的log:

$ kubectl logs nodeapp-5d5dc88584-kqr2v -c node
Node App listening on port 3000!
DAPR_HTTP_PORT: 3500
DAPR_GRPC_PORT: 50001
Got a new order! Order ID: 5
Successfully persisted state.
Got a new order! Order ID: 6
Successfully persisted state.
Got a new order! Order ID: 7
Successfully persisted state.
Got a new order! Order ID: 8
Successfully persisted state.

用kubernetes的端口映射查看最新的orderid:

$ kubectl port-forward nodeapp-5d5dc88584-kqr2v 8080:3000

把pod里的nodeapp的http端口3000映射到localhost的8080。另开一个窗口,执行:

$ curl http://localhost:8080/order

或者

$ kubectl port-forward nodeapp-5d5dc88584-kqr2v 8080:3500

把pod里的dapr sidecar的http端口3500映射到localhost的8080。另开一个窗口,执行:

$ curl http://127.0.0.1:8080/v1.0/invoke/nodeapp/method/order/

如果想在redis里查看最新的orderid,执行下面的命令:

$ export REDIS_PASSWORD=$(kubectl get secret --namespace default redis -o jsonpath="{.data.redis-password}" | base64 --decode)
$ kubectl run --namespace default redis-client --rm --tty -i --restart='Never'      --env REDIS_PASSWORD=$REDIS_PASSWORD     --image docker.io/bitnami/redis:6.0.9-debian-10-r38 -- bash
If you don't see a command prompt, try pressing enter.
I have no name!@redis-client:/$ redis-cli -h redis-master -a $REDIS_PASSWORD
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
redis-master:6379> hgetall nodeapp||order
(0)

相关推荐