Service Mesh vs API Gateway,用途特征大相径庭?

小数 发表了文章 • 0 个评论 • 422 次浏览 • 2018-04-16 10:30 • 来自相关话题

作者:Kasun Indrasiri

翻译:赵化冰(博客链接:http://zhaohuabing.com/)

原文:Service Mesh vs API Gateway

地址:https://medium.com/microservic ... 9bf56




在我前一篇关于 Service Mesh 的文章中(注1)有几个关于 Service Mesh 和 API Gateway 之间关系的问题。因此在我打算在本篇文章中讨论 Service Mesh 和 API Gateway 的用途。


为了区分 API Gateway 和 Service Mesh,让我们先分别看看两者的主要特征。


API Gateway:将你的服务作为被管理的API暴露给外部系统

使用 API Gateway 的主要目的是将你的微服务作为被管理的 API 暴露给外部系统。因此,我们在 API Gateway 层开发的 API 或者边界服务对外提供了业务功能。

API/Edge 服务调用下游微服务,通过组合/混装多个下游微服务形成业务逻辑。

API/Edge 服务需要以一种可靠的方式调用下游服务,因此需要应用断路器,超时,负载均衡/故障转移等可靠性模式。因此大部分的 API Gateway解决方案都内置了这些特性。

API Gateway 也需要内置对以下特性的支持,包括:服务发现,分析(可见性:性能指标,监控,分布式日志,分布式调用追踪) 和安全。

API Gateway 和 API 管理生态系统的其他这些组件的关系紧密,比如: API 市场/商店, API 发布门户。




Service Mesh

现在我们来看看Service Mesh有哪些不同。

Service Mesh是一个网络通信基础设施, 可以用于将网络功能从你的服务代码中剥离出来。

采用 Service Mesh, 你不用在服务代码中实现用于可靠通信的模式如断路,超时等,类似地,Service Mesh 也提供了服务发现,服务可见性等其他功能。




API Gateway and Service Mesh实践

API Gateway 和 Service Mesh 之间的主要不同点在于 API Gateway 是暴露 API/Edge 服务的关键组件,而 Service Mesh 则仅仅是一个服务间通信的基础设施,并不了解你应用中的业务逻辑。

下图说明了 API Gateway 和 Service Mesh 的关系。如同我们上所说,他们之间也有一些重叠的部分(例如断路器等),但重要的是需要理解这两者是用于完全不同的用途。

图1: API Gateway和Service Mesh实践








如图所示,Service Mesh 作为 Sidecar 和服务一起部署,它是独立于服务的业务逻辑的。


另一方面,API Gateway host 了所有的 API 服务(这些API服务有明确定义的业务功能),它是你应用的业务逻辑的一部分。API Gateway 可以具有内建的服务间通信能力,但它也可以使用 Service Mesh 来调用下游服务。(API Gateway->Service Mesh->Microservices)。


在API管理层次,你可以使用API Gateway内建的服务间通信能力;也可以通过Service Mesh来调用下游服务,以将应用网络通信功能从应用程序转移到Service Mesh中。




译者按:

API Gateway 和 Service Mesh 的关系是我最近一直在思考的问题,也和同事及社区的朋友之间进行了一些讨论。这篇短文很清晰地总结了两者之间的相似之处以及这两者在微服务架构中的不同用途。


文章中提到 “可以使用API Gateway内建的服务间通信能力;也可以通过Service Mesh来调用下游服务”。在和同事讨论时,大家提到一个比较重要的考虑因素是在 API Gateway 处引入一个 Sidecar 可能带来的额外延迟。


API Gateway 作为微服务引用的流量入口,其对效率要求较高,如果随 API Gateway 部署一个 Sidecar,可能对效率有一定影响。


我对此未进行测试,但从理论上来说,服务发现,重试,断路等逻辑无论放到 API Gateway 还是 Service Mesh 中耗时应该是差不多的,部署 Sidecar 只是增加了创建一个本地链接的消耗,如下图所示:







将 API Gateway 和 Service Mesh 的功能进行清晰划分,API Gateway 负责应用逻辑,Service Mes h负责服务通讯,Metrics 收集等微服务基础设施,这样划分后在架构上更为清晰。对于效率问题,我们可以考虑对 API Gateway 进行水平扩展来解决。




注:

1、https://medium.com/microservic ... a3c9a 查看全部
作者:Kasun Indrasiri

翻译:赵化冰(博客链接:http://zhaohuabing.com/

原文:Service Mesh vs API Gateway

地址:https://medium.com/microservic ... 9bf56




在我前一篇关于 Service Mesh 的文章中(注1)有几个关于 Service Mesh 和 API Gateway 之间关系的问题。因此在我打算在本篇文章中讨论 Service Mesh 和 API Gateway 的用途。


为了区分 API Gateway 和 Service Mesh,让我们先分别看看两者的主要特征。


API Gateway:将你的服务作为被管理的API暴露给外部系统

使用 API Gateway 的主要目的是将你的微服务作为被管理的 API 暴露给外部系统。因此,我们在 API Gateway 层开发的 API 或者边界服务对外提供了业务功能。

API/Edge 服务调用下游微服务,通过组合/混装多个下游微服务形成业务逻辑。

API/Edge 服务需要以一种可靠的方式调用下游服务,因此需要应用断路器,超时,负载均衡/故障转移等可靠性模式。因此大部分的 API Gateway解决方案都内置了这些特性。

API Gateway 也需要内置对以下特性的支持,包括:服务发现,分析(可见性:性能指标,监控,分布式日志,分布式调用追踪) 和安全。

API Gateway 和 API 管理生态系统的其他这些组件的关系紧密,比如: API 市场/商店, API 发布门户。




Service Mesh

现在我们来看看Service Mesh有哪些不同。

Service Mesh是一个网络通信基础设施, 可以用于将网络功能从你的服务代码中剥离出来。

采用 Service Mesh, 你不用在服务代码中实现用于可靠通信的模式如断路,超时等,类似地,Service Mesh 也提供了服务发现,服务可见性等其他功能。




API Gateway and Service Mesh实践

API Gateway 和 Service Mesh 之间的主要不同点在于 API Gateway 是暴露 API/Edge 服务的关键组件,而 Service Mesh 则仅仅是一个服务间通信的基础设施,并不了解你应用中的业务逻辑。

下图说明了 API Gateway 和 Service Mesh 的关系。如同我们上所说,他们之间也有一些重叠的部分(例如断路器等),但重要的是需要理解这两者是用于完全不同的用途。

图1: API Gateway和Service Mesh实践


微信图片_20180416102911.jpg



如图所示,Service Mesh 作为 Sidecar 和服务一起部署,它是独立于服务的业务逻辑的。


另一方面,API Gateway host 了所有的 API 服务(这些API服务有明确定义的业务功能),它是你应用的业务逻辑的一部分。API Gateway 可以具有内建的服务间通信能力,但它也可以使用 Service Mesh 来调用下游服务。(API Gateway->Service Mesh->Microservices)。


在API管理层次,你可以使用API Gateway内建的服务间通信能力;也可以通过Service Mesh来调用下游服务,以将应用网络通信功能从应用程序转移到Service Mesh中。




译者按:

API Gateway 和 Service Mesh 的关系是我最近一直在思考的问题,也和同事及社区的朋友之间进行了一些讨论。这篇短文很清晰地总结了两者之间的相似之处以及这两者在微服务架构中的不同用途。


文章中提到 “可以使用API Gateway内建的服务间通信能力;也可以通过Service Mesh来调用下游服务”。在和同事讨论时,大家提到一个比较重要的考虑因素是在 API Gateway 处引入一个 Sidecar 可能带来的额外延迟。


API Gateway 作为微服务引用的流量入口,其对效率要求较高,如果随 API Gateway 部署一个 Sidecar,可能对效率有一定影响。


我对此未进行测试,但从理论上来说,服务发现,重试,断路等逻辑无论放到 API Gateway 还是 Service Mesh 中耗时应该是差不多的,部署 Sidecar 只是增加了创建一个本地链接的消耗,如下图所示:

微信图片_20180416102956.jpg



将 API Gateway 和 Service Mesh 的功能进行清晰划分,API Gateway 负责应用逻辑,Service Mes h负责服务通讯,Metrics 收集等微服务基础设施,这样划分后在架构上更为清晰。对于效率问题,我们可以考虑对 API Gateway 进行水平扩展来解决。




注:

1、https://medium.com/microservic ... a3c9a

Service Mesh第三梯队,不可忽略的Nginmesh

小数 发表了文章 • 0 个评论 • 300 次浏览 • 2018-04-11 15:13 • 来自相关话题

作者简介:

      赵化冰是一名程序员及开源软件爱好者,目前在NFV&SDN编排开源社区ONAP担任MSB项目负责人,致力于高性能,高可用微服务架构在编排领域的应用。

      博客链接:http://zhaohuabing.com/


目录
前言安装Kubernetes Cluster安装Istio控制面和Bookinfo查看自动注入的sidecar关联阅读参考




1. 前言

Nginmesh 是 NGINX 的 Service Mesh 开源项目,用于 Istio 服务网格平台中的数据面代理。它旨在提供七层负载均衡和服务路由功能,与 Istio 集成作为 sidecar 部署,并将以“标准,可靠和安全的方式”使得服务间通信更容易。Nginmesh 在今年底已经连续发布了0.2和0.3版本,提供了服务发现,请求转发,路由规则,性能指标收集等功能。

备注:本文安装指南基于Ubuntu 16.04,在Centos上某些安装步骤的命令可能需要稍作改动。









2. 安装Kubernetes Cluster

Kubernetes Cluster 包含 etcd, api server, scheduler,controller manager 等多个组件,组件之间的配置较为复杂,如果要手动去逐个安装及配置各个组件,需要了解 kubernetes,操作系统及网络等多方面的知识,对安装人员的能力要求较高。kubeadm提供了一个简便,快速安装 Kubernetes Cluster 的方式,并且可以通过安装配置文件提供较高的灵活性,因此我们采用 kubeadm 安装 kubernetes cluster。

首先参照 kubeadm的说明文档(注1) 在计划部署 kubernetes cluster 的每个节点上安装 docker,kubeadm, kubelet 和 kubectl。

安装 docker

apt-get update
apt-get install -y docker.io

使用 google 的源安装 kubelet kubeadm 和 kubectl

apt-get update && apt-get install -y apt-transport-https
curl -s https://packages.cloud.google. ... y.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
apt-get update
apt-get install -y kubelet kubeadm kubectl

使用 kubeadmin 安装 kubernetes cluster

Nginmesh 使用 Kubernetes的 Initializer 机制 (注2)来实现 sidecar 的自动注入。Initializer 目前是 kubernetes 的一个 Alpha feature,缺省是未启用的,需要通过api server的参数(注3)打开。因此我们先创建一个 kubeadm-conf 配置文件,用于配置 api server的启动参数。

apiVersion: kubeadm.k8s.io/v1alpha1
kind: MasterConfiguration
apiServerExtraArgs:
 admission-control: Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ValidatingAdmissionWebhook,ResourceQuota,DefaultTolerationSeconds,MutatingAdmissionWebhook
 runtime-config: admissionregistration.k8s.io/v1alpha1

使用 kubeadmin init 命令创建 kubernetes master 节点。 可以先试用 –dry-run 参数验证一下配置文件。

kubeadm init --config kubeadm-conf --dry-run

如果一切正常,kubeadm 将提示:Finished dry-running successfully. Above are the resources that would be created.

下面再实际执行创建命令

kubeadm init --config kubeadm-conf

kubeadm 会花一点时间拉取 docker image,命令完成后,会提示如何将一个 work node 加入 cluster。如下所示:

kubeadm join --token fffbf6.13bcb3563428cf23 10.12.5.15:6443 --discovery-token-ca-cert-hash sha256:27ad08b4cd9f02e522334979deaf09e3fae80507afde63acf88892c8b72f143f

备注:目前 kubeadm 只能支持在一个节点上安装 master,支持高可用的安装将在后续版本实现。kubernetes 官方给出的 workaround 建议是定期备份 etcd 数据kubeadm limitations。

Kubeadm 并不会安装 Pod 需要的网络,因此需要手动安装一个 Pod 网络,这里采用的是 Calico

kubectl apply -f https://docs.projectcalico.org ... .yaml

使用 kubectl 命令检查 master 节点安装结果

ubuntu@kube-1:~$ kubectl get all
NAME             TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
svc/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   12m

在每台工作节点上执行上述 kubeadm join 命令,即可把工作节点加入集群中。使用kubectl 命令检查 cluster 中的节点情况。

ubuntu@kube-1:~$ kubectl get nodes
NAME      STATUS    ROLES     AGE       VERSION
kube-1    Ready     master    21m       v1.9.0
kube-2    Ready     <none>    47s       v1.9.0




3. 安装Istio控制面和Bookinfo

参考 Nginmesh文档 (注4)安装 Istio 控制面和 Bookinfo 该文档的步骤清晰明确,这里不再赘述。

需要注意的是,在 Niginmesh 文档中,建议通过 Ingress 的 External IP 访问 bookinfo应用程序。但 Loadbalancer 只在支持的云环境中才会生效(注5),并且还需要进行一定的配置。如我在 Openstack 环境中创建的 cluster,则需要参照该文档(注6)对Openstack 进行配置后,Openstack 才能够支持 kubernetes 的 Loadbalancer service。如未进行配置,通过命令查看 Ingress External IP 一直显示为 pending 状态。

NAME            TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                            AGE
istio-ingress   LoadBalancer   10.111.158.10   <pending>     80:32765/TCP,443:31969/TCP                                         11m
istio-mixer     ClusterIP      10.107.135.31   <none>        9091/TCP,15004/TCP,9093/TCP,9094/TCP,9102/TCP,9125/UDP,42422/TCP   11m
istio-pilot     ClusterIP      10.111.110.65   <none>        15003/TCP,443/TCP                                                  11m

如不能配置云环境提供 Loadbalancer 特性, 我们可以直接使用集群中的一个节点IP:Nodeport 访问 Bookinfo 应用程序。

http://10.12.5.31:32765/productpage

想要了解更多关于如何从集群外部进行访问的内容,可以参考如何从外部访问Kubernetes集群中的应用?(注7)




4. 查看自动注入的sidecar

使用 kubectl get pod reviews-v3-5fff595d9b-zsb2q -o yaml 命令查看 Bookinfo 应用的 reviews 服务的 Pod。

apiVersion: v1
kind: Pod
metadata:
 annotations:
   sidecar.istio.io/status: injected-version-0.2.12
 creationTimestamp: 2018-01-02T02:33:36Z
 generateName: reviews-v3-5fff595d9b-
 labels:
   app: reviews
   pod-template-hash: "1999151856"
   version: v3
 name: reviews-v3-5fff595d9b-zsb2q
 namespace: default
 ownerReferences:
 - apiVersion: extensions/v1beta1
   blockOwnerDeletion: true
   controller: true
   kind: ReplicaSet
   name: reviews-v3-5fff595d9b
   uid: 5599688c-ef65-11e7-8be6-fa163e160c7d
 resourceVersion: "3757"
 selfLink: /api/v1/namespaces/default/pods/reviews-v3-5fff595d9b-zsb2q
 uid: 559d8c6f-ef65-11e7-8be6-fa163e160c7d
spec:
 containers:
 - image: istio/examples-bookinfo-reviews-v3:0.2.3
   imagePullPolicy: IfNotPresent
   name: reviews
   ports:
   - containerPort: 9080
     protocol: TCP
   resources: {}
   terminationMessagePath: /dev/termination-log
   terminationMessagePolicy: File
   volumeMounts:
   - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
     name: default-token-48vxx
     readOnly: true
 - args:
   - proxy
   - sidecar
   - -v
   - "2"
   - --configPath
   - /etc/istio/proxy
   - --binaryPath
   - /usr/local/bin/envoy
   - --serviceCluster
   - reviews
   - --drainDuration
   - 45s
   - --parentShutdownDuration
   - 1m0s
   - --discoveryAddress
   - istio-pilot.istio-system:15003
   - --discoveryRefreshDelay
   - 1s
   - --zipkinAddress
   - zipkin.istio-system:9411
   - --connectTimeout
   - 10s
   - --statsdUdpAddress
   - istio-mixer.istio-system:9125
   - --proxyAdminPort
   - "15000"
   - --controlPlaneAuthPolicy
   - NONE
   env:
   - name: POD_NAME
     valueFrom:
       fieldRef:
         apiVersion: v1
         fieldPath: metadata.name
   - name: POD_NAMESPACE
     valueFrom:
       fieldRef:
         apiVersion: v1
         fieldPath: metadata.namespace
   - name: INSTANCE_IP
     valueFrom:
       fieldRef:
         apiVersion: v1
         fieldPath: status.podIP
   image: nginmesh/proxy_debug:0.2.12
   imagePullPolicy: Always
   name: istio-proxy
   resources: {}
   securityContext:
     privileged: true
     readOnlyRootFilesystem: false
     runAsUser: 1337
   terminationMessagePath: /dev/termination-log
   terminationMessagePolicy: File
   volumeMounts:
   - mountPath: /etc/istio/proxy
     name: istio-envoy
   - mountPath: /etc/certs/
     name: istio-certs
     readOnly: true
   - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
     name: default-token-48vxx
     readOnly: true
 dnsPolicy: ClusterFirst
 initContainers:
 - args:
   - -p
   - "15001"
   - -u
   - "1337"
   image: nginmesh/proxy_init:0.2.12
   imagePullPolicy: Always
   name: istio-init
   resources: {}
   securityContext:
     capabilities:
       add:
       - NET_ADMIN
     privileged: true
   terminationMessagePath: /dev/termination-log
   terminationMessagePolicy: File
   volumeMounts:
   - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
     name: default-token-48vxx
     readOnly: true
 nodeName: kube-2
 restartPolicy: Always
 schedulerName: default-scheduler
 securityContext: {}
 serviceAccount: default
 serviceAccountName: default
 terminationGracePeriodSeconds: 30
 tolerations:
 - effect: NoExecute
   key: node.kubernetes.io/not-ready
   operator: Exists
   tolerationSeconds: 300
 - effect: NoExecute
   key: node.kubernetes.io/unreachable
   operator: Exists
   tolerationSeconds: 300
 volumes:
 - emptyDir:
     medium: Memory
   name: istio-envoy
 - name: istio-certs
   secret:
     defaultMode: 420
     optional: true
     secretName: istio.default
 - name: default-token-48vxx
   secret:
     defaultMode: 420
     secretName: default-token-48vxx
status:
 conditions:
 - lastProbeTime: null
   lastTransitionTime: 2018-01-02T02:33:54Z
   status: "True"
   type: Initialized
 - lastProbeTime: null
   lastTransitionTime: 2018-01-02T02:36:06Z
   status: "True"
   type: Ready
 - lastProbeTime: null
   lastTransitionTime: 2018-01-02T02:33:36Z
   status: "True"
   type: PodScheduled
 containerStatuses:
 - containerID: docker://5d0c189b9dde8e14af4c8065ee5cf007508c0bb2b3c9535598d99dc49f531370
   image: nginmesh/proxy_debug:0.2.12
   imageID: docker-pullable://nginmesh/proxy_debug@sha256:6275934ea3a1ce5592e728717c4973ac704237b06b78966a1d50de3bc9319c71
   lastState: {}
   name: istio-proxy
   ready: true
   restartCount: 0
   state:
     running:
       startedAt: 2018-01-02T02:36:05Z
 - containerID: docker://aba3e114ac1aa87c75e969dcc1b0725696de78d3407c5341691d9db579429f28
   image: istio/examples-bookinfo-reviews-v3:0.2.3
   imageID: docker-pullable://istio/examples-bookinfo-reviews-v3@sha256:6e100e4805a8c10c47040ea7b66f10ad619c7e0068696032546ad3e35ad46570
   lastState: {}
   name: reviews
   ready: true
   restartCount: 0
   state:
     running:
       startedAt: 2018-01-02T02:35:47Z
 hostIP: 10.12.5.31
 initContainerStatuses:
 - containerID: docker://b55108625832a3205a265e8b45e5487df10276d5ae35af572ea4f30583933c1f
   image: nginmesh/proxy_init:0.2.12
   imageID: docker-pullable://nginmesh/proxy_init@sha256:f73b68839f6ac1596d6286ca498e4478b8fcfa834e4884418d23f9f625cbe5f5
   lastState: {}
   name: istio-init
   ready: true
   restartCount: 0
   state:
     terminated:
       containerID: docker://b55108625832a3205a265e8b45e5487df10276d5ae35af572ea4f30583933c1f
       exitCode: 0
       finishedAt: 2018-01-02T02:33:53Z
       reason: Completed
       startedAt: 2018-01-02T02:33:53Z
 phase: Running
 podIP: 192.168.79.138
 qosClass: BestEffort
 startTime: 2018-01-02T02:33:39Z

该命令行输出的内容相当长,我们可以看到 Pod 中注入了一个 nginmesh/proxy_debug container , 还增加了一个 initContainer nginmesh/proxy_init。这两个容器是通过kubernetes initializer 自动注入到 pod 中的。这两个 container 分别有什么作用呢?让我们看一下 Nginmesh 源代码中的说明(注8):

proxy_debug, which comes with the agent and NGINX.

proxy_init, which is used for configuring iptables rules for transparently injecting an NGINX proxy from the proxy_debug image into an application pod.

proxy_debug 就是 sidecar 代理,proxy_init 则用于配置 iptable 规则,以将应用的流量导入到 sidecar 代理中。

查看 proxy_init 的 Dockerfile 文件,可以看到 proxy_init 其实是调用了prepare_proxy.sh(注9)这个脚本来创建 iptable 规则。

proxy_debug Dockerfile

FROM debian:stretch-slim
RUN apt-get update && apt-get install -y iptables
ADD prepare_proxy.sh /
ENTRYPOINT ["/prepare_proxy.sh"]

prepare_proxy.sh节选

...omitted for brevity 

# Create a new chain for redirecting inbound and outbound traffic to
# the common Envoy port.
iptables -t nat -N ISTIO_REDIRECT                                             -m comment --comment "istio/redirect-common-chain"
iptables -t nat -A ISTIO_REDIRECT -p tcp -j REDIRECT --to-port ${ENVOY_PORT}  -m comment --comment "istio/redirect-to-envoy-port"

# Redirect all inbound traffic to Envoy.
iptables -t nat -A PREROUTING -j ISTIO_REDIRECT                               -m comment --comment "istio/install-istio-prerouting"

# Create a new chain for selectively redirecting outbound packets to
# Envoy.
iptables -t nat -N ISTIO_OUTPUT                                               -m comment --comment "istio/common-output-chain"

...omitted for brevity





4. 关联阅读

Istio  及Bookinfo 示例程序安装试用笔记(注10)




5. 参考

Service Mesh with Istio and NGINX(注11)

Using kubeadm to Create a Cluster(注12)

Kubernetes Reference Documentation-Dynamic Admission Control(注13)



注:

1、https://kubernetes.io/docs/set ... beadm

2、https://kubernetes.io/docs/adm ... izers

3、https://kubernetes.io/docs/adm ... lpha-

4、https://github.com/nginmesh/nginmesh

5、https://kubernetes.io/docs/con ... ancer

6、https://docs.openstack.org/mag ... .html

7、http://zhaohuabing.com/2017/11 ... side/

8、https://github.com/nginmesh/ng ... agent

9、https://github.com/nginmesh/ng ... xy.sh

10、https://github.com/nginmesh/ng ... xy.sh

11、https://github.com/nginmesh/nginmesh/

12、https://kubernetes.io/docs/set ... hosts

13、https://kubernetes.io/docs/set ... hosts


  查看全部
作者简介:

      赵化冰是一名程序员及开源软件爱好者,目前在NFV&SDN编排开源社区ONAP担任MSB项目负责人,致力于高性能,高可用微服务架构在编排领域的应用。

      博客链接:http://zhaohuabing.com/


目录
  1. 前言
  2. 安装Kubernetes Cluster
  3. 安装Istio控制面和Bookinfo
  4. 查看自动注入的sidecar
  5. 关联阅读
  6. 参考





1. 前言

Nginmesh 是 NGINX 的 Service Mesh 开源项目,用于 Istio 服务网格平台中的数据面代理。它旨在提供七层负载均衡和服务路由功能,与 Istio 集成作为 sidecar 部署,并将以“标准,可靠和安全的方式”使得服务间通信更容易。Nginmesh 在今年底已经连续发布了0.2和0.3版本,提供了服务发现,请求转发,路由规则,性能指标收集等功能。

备注:本文安装指南基于Ubuntu 16.04,在Centos上某些安装步骤的命令可能需要稍作改动。


11.png




2. 安装Kubernetes Cluster

Kubernetes Cluster 包含 etcd, api server, scheduler,controller manager 等多个组件,组件之间的配置较为复杂,如果要手动去逐个安装及配置各个组件,需要了解 kubernetes,操作系统及网络等多方面的知识,对安装人员的能力要求较高。kubeadm提供了一个简便,快速安装 Kubernetes Cluster 的方式,并且可以通过安装配置文件提供较高的灵活性,因此我们采用 kubeadm 安装 kubernetes cluster。

首先参照 kubeadm的说明文档(注1) 在计划部署 kubernetes cluster 的每个节点上安装 docker,kubeadm, kubelet 和 kubectl。

安装 docker

apt-get update
apt-get install -y docker.io

使用 google 的源安装 kubelet kubeadm 和 kubectl

apt-get update && apt-get install -y apt-transport-https
curl -s https://packages.cloud.google. ... y.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
apt-get update
apt-get install -y kubelet kubeadm kubectl

使用 kubeadmin 安装 kubernetes cluster

Nginmesh 使用 Kubernetes的 Initializer 机制 (注2)来实现 sidecar 的自动注入。Initializer 目前是 kubernetes 的一个 Alpha feature,缺省是未启用的,需要通过api server的参数(注3)打开。因此我们先创建一个 kubeadm-conf 配置文件,用于配置 api server的启动参数。

apiVersion: kubeadm.k8s.io/v1alpha1
kind: MasterConfiguration
apiServerExtraArgs:
 admission-control: Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ValidatingAdmissionWebhook,ResourceQuota,DefaultTolerationSeconds,MutatingAdmissionWebhook
 runtime-config: admissionregistration.k8s.io/v1alpha1

使用 kubeadmin init 命令创建 kubernetes master 节点。 可以先试用 –dry-run 参数验证一下配置文件。

kubeadm init --config kubeadm-conf --dry-run

如果一切正常,kubeadm 将提示:Finished dry-running successfully. Above are the resources that would be created.

下面再实际执行创建命令

kubeadm init --config kubeadm-conf

kubeadm 会花一点时间拉取 docker image,命令完成后,会提示如何将一个 work node 加入 cluster。如下所示:

kubeadm join --token fffbf6.13bcb3563428cf23 10.12.5.15:6443 --discovery-token-ca-cert-hash sha256:27ad08b4cd9f02e522334979deaf09e3fae80507afde63acf88892c8b72f143f

备注:目前 kubeadm 只能支持在一个节点上安装 master,支持高可用的安装将在后续版本实现。kubernetes 官方给出的 workaround 建议是定期备份 etcd 数据kubeadm limitations。

Kubeadm 并不会安装 Pod 需要的网络,因此需要手动安装一个 Pod 网络,这里采用的是 Calico

kubectl apply -f https://docs.projectcalico.org ... .yaml

使用 kubectl 命令检查 master 节点安装结果

ubuntu@kube-1:~$ kubectl get all
NAME             TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
svc/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   12m

在每台工作节点上执行上述 kubeadm join 命令,即可把工作节点加入集群中。使用kubectl 命令检查 cluster 中的节点情况。

ubuntu@kube-1:~$ kubectl get nodes
NAME      STATUS    ROLES     AGE       VERSION
kube-1    Ready     master    21m       v1.9.0
kube-2    Ready     <none>    47s       v1.9.0




3. 安装Istio控制面和Bookinfo

参考 Nginmesh文档 (注4)安装 Istio 控制面和 Bookinfo 该文档的步骤清晰明确,这里不再赘述。

需要注意的是,在 Niginmesh 文档中,建议通过 Ingress 的 External IP 访问 bookinfo应用程序。但 Loadbalancer 只在支持的云环境中才会生效(注5),并且还需要进行一定的配置。如我在 Openstack 环境中创建的 cluster,则需要参照该文档(注6)对Openstack 进行配置后,Openstack 才能够支持 kubernetes 的 Loadbalancer service。如未进行配置,通过命令查看 Ingress External IP 一直显示为 pending 状态。

NAME            TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                            AGE
istio-ingress   LoadBalancer   10.111.158.10   <pending>     80:32765/TCP,443:31969/TCP                                         11m
istio-mixer     ClusterIP      10.107.135.31   <none>        9091/TCP,15004/TCP,9093/TCP,9094/TCP,9102/TCP,9125/UDP,42422/TCP   11m
istio-pilot     ClusterIP      10.111.110.65   <none>        15003/TCP,443/TCP                                                  11m

如不能配置云环境提供 Loadbalancer 特性, 我们可以直接使用集群中的一个节点IP:Nodeport 访问 Bookinfo 应用程序。

http://10.12.5.31:32765/productpage

想要了解更多关于如何从集群外部进行访问的内容,可以参考如何从外部访问Kubernetes集群中的应用?(注7)




4. 查看自动注入的sidecar

使用 kubectl get pod reviews-v3-5fff595d9b-zsb2q -o yaml 命令查看 Bookinfo 应用的 reviews 服务的 Pod。

apiVersion: v1
kind: Pod
metadata:
 annotations:
   sidecar.istio.io/status: injected-version-0.2.12
 creationTimestamp: 2018-01-02T02:33:36Z
 generateName: reviews-v3-5fff595d9b-
 labels:
   app: reviews
   pod-template-hash: "1999151856"
   version: v3
 name: reviews-v3-5fff595d9b-zsb2q
 namespace: default
 ownerReferences:
 - apiVersion: extensions/v1beta1
   blockOwnerDeletion: true
   controller: true
   kind: ReplicaSet
   name: reviews-v3-5fff595d9b
   uid: 5599688c-ef65-11e7-8be6-fa163e160c7d
 resourceVersion: "3757"
 selfLink: /api/v1/namespaces/default/pods/reviews-v3-5fff595d9b-zsb2q
 uid: 559d8c6f-ef65-11e7-8be6-fa163e160c7d
spec:
 containers:
 - image: istio/examples-bookinfo-reviews-v3:0.2.3
   imagePullPolicy: IfNotPresent
   name: reviews
   ports:
   - containerPort: 9080
     protocol: TCP
   resources: {}
   terminationMessagePath: /dev/termination-log
   terminationMessagePolicy: File
   volumeMounts:
   - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
     name: default-token-48vxx
     readOnly: true
 - args:
   - proxy
   - sidecar
   - -v
   - "2"
   - --configPath
   - /etc/istio/proxy
   - --binaryPath
   - /usr/local/bin/envoy
   - --serviceCluster
   - reviews
   - --drainDuration
   - 45s
   - --parentShutdownDuration
   - 1m0s
   - --discoveryAddress
   - istio-pilot.istio-system:15003
   - --discoveryRefreshDelay
   - 1s
   - --zipkinAddress
   - zipkin.istio-system:9411
   - --connectTimeout
   - 10s
   - --statsdUdpAddress
   - istio-mixer.istio-system:9125
   - --proxyAdminPort
   - "15000"
   - --controlPlaneAuthPolicy
   - NONE
   env:
   - name: POD_NAME
     valueFrom:
       fieldRef:
         apiVersion: v1
         fieldPath: metadata.name
   - name: POD_NAMESPACE
     valueFrom:
       fieldRef:
         apiVersion: v1
         fieldPath: metadata.namespace
   - name: INSTANCE_IP
     valueFrom:
       fieldRef:
         apiVersion: v1
         fieldPath: status.podIP
   image: nginmesh/proxy_debug:0.2.12
   imagePullPolicy: Always
   name: istio-proxy
   resources: {}
   securityContext:
     privileged: true
     readOnlyRootFilesystem: false
     runAsUser: 1337
   terminationMessagePath: /dev/termination-log
   terminationMessagePolicy: File
   volumeMounts:
   - mountPath: /etc/istio/proxy
     name: istio-envoy
   - mountPath: /etc/certs/
     name: istio-certs
     readOnly: true
   - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
     name: default-token-48vxx
     readOnly: true
 dnsPolicy: ClusterFirst
 initContainers:
 - args:
   - -p
   - "15001"
   - -u
   - "1337"
   image: nginmesh/proxy_init:0.2.12
   imagePullPolicy: Always
   name: istio-init
   resources: {}
   securityContext:
     capabilities:
       add:
       - NET_ADMIN
     privileged: true
   terminationMessagePath: /dev/termination-log
   terminationMessagePolicy: File
   volumeMounts:
   - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
     name: default-token-48vxx
     readOnly: true
 nodeName: kube-2
 restartPolicy: Always
 schedulerName: default-scheduler
 securityContext: {}
 serviceAccount: default
 serviceAccountName: default
 terminationGracePeriodSeconds: 30
 tolerations:
 - effect: NoExecute
   key: node.kubernetes.io/not-ready
   operator: Exists
   tolerationSeconds: 300
 - effect: NoExecute
   key: node.kubernetes.io/unreachable
   operator: Exists
   tolerationSeconds: 300
 volumes:
 - emptyDir:
     medium: Memory
   name: istio-envoy
 - name: istio-certs
   secret:
     defaultMode: 420
     optional: true
     secretName: istio.default
 - name: default-token-48vxx
   secret:
     defaultMode: 420
     secretName: default-token-48vxx
status:
 conditions:
 - lastProbeTime: null
   lastTransitionTime: 2018-01-02T02:33:54Z
   status: "True"
   type: Initialized
 - lastProbeTime: null
   lastTransitionTime: 2018-01-02T02:36:06Z
   status: "True"
   type: Ready
 - lastProbeTime: null
   lastTransitionTime: 2018-01-02T02:33:36Z
   status: "True"
   type: PodScheduled
 containerStatuses:
 - containerID: docker://5d0c189b9dde8e14af4c8065ee5cf007508c0bb2b3c9535598d99dc49f531370
   image: nginmesh/proxy_debug:0.2.12
   imageID: docker-pullable://nginmesh/proxy_debug@sha256:6275934ea3a1ce5592e728717c4973ac704237b06b78966a1d50de3bc9319c71
   lastState: {}
   name: istio-proxy
   ready: true
   restartCount: 0
   state:
     running:
       startedAt: 2018-01-02T02:36:05Z
 - containerID: docker://aba3e114ac1aa87c75e969dcc1b0725696de78d3407c5341691d9db579429f28
   image: istio/examples-bookinfo-reviews-v3:0.2.3
   imageID: docker-pullable://istio/examples-bookinfo-reviews-v3@sha256:6e100e4805a8c10c47040ea7b66f10ad619c7e0068696032546ad3e35ad46570
   lastState: {}
   name: reviews
   ready: true
   restartCount: 0
   state:
     running:
       startedAt: 2018-01-02T02:35:47Z
 hostIP: 10.12.5.31
 initContainerStatuses:
 - containerID: docker://b55108625832a3205a265e8b45e5487df10276d5ae35af572ea4f30583933c1f
   image: nginmesh/proxy_init:0.2.12
   imageID: docker-pullable://nginmesh/proxy_init@sha256:f73b68839f6ac1596d6286ca498e4478b8fcfa834e4884418d23f9f625cbe5f5
   lastState: {}
   name: istio-init
   ready: true
   restartCount: 0
   state:
     terminated:
       containerID: docker://b55108625832a3205a265e8b45e5487df10276d5ae35af572ea4f30583933c1f
       exitCode: 0
       finishedAt: 2018-01-02T02:33:53Z
       reason: Completed
       startedAt: 2018-01-02T02:33:53Z
 phase: Running
 podIP: 192.168.79.138
 qosClass: BestEffort
 startTime: 2018-01-02T02:33:39Z

该命令行输出的内容相当长,我们可以看到 Pod 中注入了一个 nginmesh/proxy_debug container , 还增加了一个 initContainer nginmesh/proxy_init。这两个容器是通过kubernetes initializer 自动注入到 pod 中的。这两个 container 分别有什么作用呢?让我们看一下 Nginmesh 源代码中的说明(注8):

proxy_debug, which comes with the agent and NGINX.

proxy_init, which is used for configuring iptables rules for transparently injecting an NGINX proxy from the proxy_debug image into an application pod.

proxy_debug 就是 sidecar 代理,proxy_init 则用于配置 iptable 规则,以将应用的流量导入到 sidecar 代理中。

查看 proxy_init 的 Dockerfile 文件,可以看到 proxy_init 其实是调用了prepare_proxy.sh(注9)这个脚本来创建 iptable 规则。

proxy_debug Dockerfile

FROM debian:stretch-slim
RUN apt-get update && apt-get install -y iptables
ADD prepare_proxy.sh /
ENTRYPOINT ["/prepare_proxy.sh"]

prepare_proxy.sh节选

...omitted for brevity 

# Create a new chain for redirecting inbound and outbound traffic to
# the common Envoy port.
iptables -t nat -N ISTIO_REDIRECT                                             -m comment --comment "istio/redirect-common-chain"
iptables -t nat -A ISTIO_REDIRECT -p tcp -j REDIRECT --to-port ${ENVOY_PORT}  -m comment --comment "istio/redirect-to-envoy-port"

# Redirect all inbound traffic to Envoy.
iptables -t nat -A PREROUTING -j ISTIO_REDIRECT                               -m comment --comment "istio/install-istio-prerouting"

# Create a new chain for selectively redirecting outbound packets to
# Envoy.
iptables -t nat -N ISTIO_OUTPUT                                               -m comment --comment "istio/common-output-chain"

...omitted for brevity





4. 关联阅读

Istio  及Bookinfo 示例程序安装试用笔记(注10)




5. 参考

Service Mesh with Istio and NGINX(注11)

Using kubeadm to Create a Cluster(注12)

Kubernetes Reference Documentation-Dynamic Admission Control(注13)



注:

1、https://kubernetes.io/docs/set ... beadm

2、https://kubernetes.io/docs/adm ... izers

3、https://kubernetes.io/docs/adm ... lpha-

4、https://github.com/nginmesh/nginmesh

5、https://kubernetes.io/docs/con ... ancer

6、https://docs.openstack.org/mag ... .html

7、http://zhaohuabing.com/2017/11 ... side/

8、https://github.com/nginmesh/ng ... agent

9、https://github.com/nginmesh/ng ... xy.sh

10、https://github.com/nginmesh/ng ... xy.sh

11、https://github.com/nginmesh/nginmesh/

12、https://kubernetes.io/docs/set ... hosts

13、https://kubernetes.io/docs/set ... hosts


 

Service Mesh深度思考 | DreamMesh抛砖引玉(3)-艰难的过渡

小数 发表了文章 • 0 个评论 • 205 次浏览 • 2018-04-11 15:10 • 来自相关话题

作者:

       敖小剑,资深码农,十六年软件开发经验,微服务专家,Service Mesh布道师。专注于基础架构,Cloud Native 拥护者,敏捷实践者,坚守开发一线打磨匠艺的架构师。机缘巧合下对基础架构和微服务有过深入研究和实践。

        博客链接:https://skyao.io



在上一篇中,我们讨论的话题是:如果没有做好Cloud Native的准备,该怎么上Service Mesh。本章继续讨论,假定Cloud Native已经准备好,看看Service Mesh的道路是否就一帆风顺。



问题所在


如何从非Service Mesh体系过渡到Service Mesh?


我们需要考虑的是:

即使一切准备就绪,对于一个有存量应用的系统而言,绝无可能将所有应用都一起改为Service Mesh,然后一夜之间上线。


必然会有一个中间过渡状态,一部分应用开始搬迁到 Service Mesh,一部分还停留在原有体系。


那么,在过渡阶段,Service Mesh 内的服务和 Service Mesh 外的服务在通讯时会遇到哪些问题?



场景分析


我们来看一个具体的例子,有三个服务,调用关系分别是 A->B->C,然后在最前面架设 API Gateway。非常典型的微服务体系:






这里可以是 spring cloud/dubbo/motan 等各种侵入式微服务架构,左边的注册中心/registry 的实现也可以有多种,服务间通讯的方式也不尽相同。但是,都不影响我们的讨论。


上图可以看到,在标准的微服务框架中,处理这样一个请求,调用方式是清晰明了的。


如果开始转向 Service Mesh 体系,无论是 Istio/Conduit,都会引入一个新的 K8S 体系。为了充分演示,我们选择将服务B转移到 Service Mesh。调用关系就一下变成复杂:






这里我们引入两个术语(TBD:应该是业界通用术语吧?待确认):


东西向通讯:指微服务间相互调用。

南北向通讯:指外界访问微服务体系,通常是通过API Gateway。


当B被迁移后,B原有的上游调用(A调用B)和下游调用(B调用C),虽然业务语意上依然还是东西向通讯,但是由于跨了体系导致原有的调用方式被打破。只能另想办法,目前看通常的做法都是改走南北向通讯。



影响


而这个改变会带来巨大的工作量:


   1. B的所有上游服务都要修改

原有的标准服务间通讯(通过sdk进行服务发现/负载均衡等)都废弃,需要改为对k8s体系入口如Ingress的调用。然后在Ingress这边也要做好对服务B的配置。

  2. B对所有下游服务的调用方式都要修改


同样,原有的标准服务间通讯都废弃,需要改为对API Gateway的调用。然后在API Gateway这边也要做好对下游服务的配置。


而通讯机制改变带来的工作量不是唯一的问题,还有一个内部服务对外暴露的问题:

在原有体系中,服务B和服务C都是内部服务,完全可以不对外暴露,API Gateway访问的只是服务A;

迁移之后,为了让服务B的上游服务能够访问到服务B,就不得不将服务B暴露出来;

同样,为了让服务B能够访问它的下游服务,就不得不将服务C暴露出来。

原体系中只有服务A对外暴露,现在服务B和服务C也不得不暴露。而对外暴露服务,就意味着必然还会有一堆相关的工作需要完成:

认证

授权

加密

……


而这些都意味着:工作量/复杂度/更多的开发测试上线。






后续影响

随着应用往 Service Mesh 体系的逐渐迁移,我们开始迁移服务C和服务A。


先看服务C迁移到来的变化:







此时服务B到服务C的调用从原来的走 API Gateway 改变为 Service Mesh 体系内的服务间调用。然后 API Gateway 不再需要调用服务C,可以去除和服务C相关的内容。


再看服务A的迁移:








此时服务B不再需要暴露,而服务A的暴露方式发生变化,另外服务A调用服务B的方式也有改变。


我们抛开细节,只看整体:在服务 A/B/C 迁移到 Service Mesh 体系的过程中,服务间调用方式和对外暴露方式的变化,带来了一系列的工作量。而耗费这些工作量的中间环节,在整体迁移完成之后都会消失。换言之,都是迫不得已的临时投入,对最后的系统不产生增益。


直白一点:在过渡阶段的这诸多折腾,只是完成了服务迁移,而不能带来任何收益。这一点,无疑是令人沮丧的。


问题本质

反思一下:为何服务只是体系间迁移一下,就需要增加这么多不带来实际收益的工作量和复杂度?到底我们上面这些折腾是在做什么?

很明显,在这个过程中,我们没有任何业务改动,三个服务的实现也没有发生任何变化。

那么,改变的东西是什么?


是服务间通讯:


迁移过程中,服务A/B/C之间的通讯在业务语意上虽然依然属于东西向的服务间通讯机制,但是在实现上,却不得不临时转为南北向的网关到服务的通讯机制。


这个转变是无奈的,两个体系之间存在以下问题导致无法继续走东西向服务间通讯机制:


1. 没有共同的registry,因此无法相互感知;

2. 没有可以直接连通的网络通道,原有的服务间通讯被迫走公开的API Gateway和Ingress通道;

3. 两个体系的服务间通讯机制也可能不同,导致迁移之后不得不重新实现服务间通讯机制;

4. API Gateway和Ingress对于服务暴露的方式也不尽相同,各种特性如认证/加密/服务路由等方式也很可能完全不同。

这就如同江河中的淡水鱼,如果要随波汇入大海,就必须要能适应海水。


然后我们的问题在于,在过渡阶段,不得不花费大量投入来的完成被两个体系分割的服务间通讯,增加了大量额外的工作。



后记

有没有办法解决这个问题,或者部分减轻工作量,为将来的 Service Mesh 转型做好准备?

后续章节会深入探讨这个话题,给出部分解决方案,也欢迎大家给出意见或者参与讨论。

有兴趣的朋友,请添加小数微信:xiaoshu062,加入service mesh内部讨论群。



讨论和反馈

冉启春:任何两个架构体系的迁移都是痛苦的

于文涛:运维团队负责容器化和k8s,基础架构部负责数据库拆分和分库分表以及底层中间件,业务平台部门参与微服务业务改造,其实路径没有统一的,得看不同团队的执行结果和如何协调了。谁强势先突破可能会有主导权。不过一般的路径是先底层后业务层。


  查看全部
作者:

       敖小剑,资深码农,十六年软件开发经验,微服务专家,Service Mesh布道师。专注于基础架构,Cloud Native 拥护者,敏捷实践者,坚守开发一线打磨匠艺的架构师。机缘巧合下对基础架构和微服务有过深入研究和实践。

        博客链接:https://skyao.io



在上一篇中,我们讨论的话题是:如果没有做好Cloud Native的准备,该怎么上Service Mesh。本章继续讨论,假定Cloud Native已经准备好,看看Service Mesh的道路是否就一帆风顺。



问题所在


如何从非Service Mesh体系过渡到Service Mesh?


我们需要考虑的是:

即使一切准备就绪,对于一个有存量应用的系统而言,绝无可能将所有应用都一起改为Service Mesh,然后一夜之间上线。


必然会有一个中间过渡状态,一部分应用开始搬迁到 Service Mesh,一部分还停留在原有体系。


那么,在过渡阶段,Service Mesh 内的服务和 Service Mesh 外的服务在通讯时会遇到哪些问题?



场景分析


我们来看一个具体的例子,有三个服务,调用关系分别是 A->B->C,然后在最前面架设 API Gateway。非常典型的微服务体系:

1.png


这里可以是 spring cloud/dubbo/motan 等各种侵入式微服务架构,左边的注册中心/registry 的实现也可以有多种,服务间通讯的方式也不尽相同。但是,都不影响我们的讨论。


上图可以看到,在标准的微服务框架中,处理这样一个请求,调用方式是清晰明了的。


如果开始转向 Service Mesh 体系,无论是 Istio/Conduit,都会引入一个新的 K8S 体系。为了充分演示,我们选择将服务B转移到 Service Mesh。调用关系就一下变成复杂:

2.png


这里我们引入两个术语(TBD:应该是业界通用术语吧?待确认):


东西向通讯:指微服务间相互调用。

南北向通讯:指外界访问微服务体系,通常是通过API Gateway。


当B被迁移后,B原有的上游调用(A调用B)和下游调用(B调用C),虽然业务语意上依然还是东西向通讯,但是由于跨了体系导致原有的调用方式被打破。只能另想办法,目前看通常的做法都是改走南北向通讯。



影响


而这个改变会带来巨大的工作量:


   1. B的所有上游服务都要修改

原有的标准服务间通讯(通过sdk进行服务发现/负载均衡等)都废弃,需要改为对k8s体系入口如Ingress的调用。然后在Ingress这边也要做好对服务B的配置。

  2. B对所有下游服务的调用方式都要修改


同样,原有的标准服务间通讯都废弃,需要改为对API Gateway的调用。然后在API Gateway这边也要做好对下游服务的配置。


而通讯机制改变带来的工作量不是唯一的问题,还有一个内部服务对外暴露的问题:

在原有体系中,服务B和服务C都是内部服务,完全可以不对外暴露,API Gateway访问的只是服务A;

迁移之后,为了让服务B的上游服务能够访问到服务B,就不得不将服务B暴露出来;

同样,为了让服务B能够访问它的下游服务,就不得不将服务C暴露出来。

原体系中只有服务A对外暴露,现在服务B和服务C也不得不暴露。而对外暴露服务,就意味着必然还会有一堆相关的工作需要完成:

认证

授权

加密

……


而这些都意味着:工作量/复杂度/更多的开发测试上线。






后续影响

随着应用往 Service Mesh 体系的逐渐迁移,我们开始迁移服务C和服务A。


先看服务C迁移到来的变化:

3.png



此时服务B到服务C的调用从原来的走 API Gateway 改变为 Service Mesh 体系内的服务间调用。然后 API Gateway 不再需要调用服务C,可以去除和服务C相关的内容。


再看服务A的迁移:


4.png



此时服务B不再需要暴露,而服务A的暴露方式发生变化,另外服务A调用服务B的方式也有改变。


我们抛开细节,只看整体:在服务 A/B/C 迁移到 Service Mesh 体系的过程中,服务间调用方式和对外暴露方式的变化,带来了一系列的工作量。而耗费这些工作量的中间环节,在整体迁移完成之后都会消失。换言之,都是迫不得已的临时投入,对最后的系统不产生增益。


直白一点:在过渡阶段的这诸多折腾,只是完成了服务迁移,而不能带来任何收益。这一点,无疑是令人沮丧的。


问题本质

反思一下:为何服务只是体系间迁移一下,就需要增加这么多不带来实际收益的工作量和复杂度?到底我们上面这些折腾是在做什么?

很明显,在这个过程中,我们没有任何业务改动,三个服务的实现也没有发生任何变化。

那么,改变的东西是什么?


是服务间通讯:


迁移过程中,服务A/B/C之间的通讯在业务语意上虽然依然属于东西向的服务间通讯机制,但是在实现上,却不得不临时转为南北向的网关到服务的通讯机制。


这个转变是无奈的,两个体系之间存在以下问题导致无法继续走东西向服务间通讯机制:


1. 没有共同的registry,因此无法相互感知;

2. 没有可以直接连通的网络通道,原有的服务间通讯被迫走公开的API Gateway和Ingress通道;

3. 两个体系的服务间通讯机制也可能不同,导致迁移之后不得不重新实现服务间通讯机制;

4. API Gateway和Ingress对于服务暴露的方式也不尽相同,各种特性如认证/加密/服务路由等方式也很可能完全不同。

这就如同江河中的淡水鱼,如果要随波汇入大海,就必须要能适应海水。


然后我们的问题在于,在过渡阶段,不得不花费大量投入来的完成被两个体系分割的服务间通讯,增加了大量额外的工作。



后记

有没有办法解决这个问题,或者部分减轻工作量,为将来的 Service Mesh 转型做好准备?

后续章节会深入探讨这个话题,给出部分解决方案,也欢迎大家给出意见或者参与讨论。

有兴趣的朋友,请添加小数微信:xiaoshu062,加入service mesh内部讨论群。



讨论和反馈

冉启春:任何两个架构体系的迁移都是痛苦的

于文涛:运维团队负责容器化和k8s,基础架构部负责数据库拆分和分库分表以及底层中间件,业务平台部门参与微服务业务改造,其实路径没有统一的,得看不同团队的执行结果和如何协调了。谁强势先突破可能会有主导权。不过一般的路径是先底层后业务层。


 

Service Mesh深度思考 | DreamMesh抛砖引玉(2)-CloudNative

小数 发表了文章 • 0 个评论 • 322 次浏览 • 2018-03-30 10:55 • 来自相关话题

作者:
       敖小剑,资深码农,十六年软件开发经验,微服务专家,Service Mesh布道师。专注于基础架构,Cloud Native 拥护者,敏捷实践者,坚守开发一线打磨匠艺的架构师。机缘巧合下对基础架构和微服务有过深入研究和实践。
        博客链接:https://skyao.io
 
 
 
我对 Service Mesh 的第一个担忧,来自 Cloud Native。
 
 
Are You Ready?
 
作为 Cloud Native 的忠实拥护者,我从不怀疑 Cloud Native 的价值和前景。可以说,微服务/容器这些技术天然就适合走 Cloud Native 的道路。
 
但是,我担心的是:准备上 Service Mesh 的各位,是否都已经做到了 Ready for Cloud Native?
 

 
这真是一个尴尬的问题。
 
现实摆在眼前,根据我最近几个月跑过的企业客户(大大小小接近二十家)的实际情况看,可以说:情况非常不乐观。
 
备注: 这里只讨论普通企业用户,对于技术和管理都比较先进的互联网大公司来说,Cloud Native的普及情况要好很多。
 
这就引出了下面这个问题:
 
如果没有Cloud Native基础,那还能不能用Service Mesh?
 
 
 
发展路径
 
这里有三条发展路径可选:
 
1、先Cloud Native,再Service Mesh
 
理论上说,这是最合理的:先把底层基础设施铺好,再在其上构建上层业务应用。
 
具体说,就是先上云/容器/k8s,应用暂时维持原状。不管是单体应用,还是基于Dubbo/Spring Cloud等侵入式开发框架的微服务应用,先上云再说。更直白一点,上k8s。
 
等待Istio/Conduit成熟之后,再迁移到Service Mesh方案。
 
 
 2、先Service Mesh,再Cloud Native
 
这个方案理论上也是可行的:先用Service Mesh方案完成微服务体系建设,之后再迁移到k8s平台。
 
之所以说理论上没有问题,是指Service Mesh从设计理念上,对底层是不是容器并没有特别要求。无论是容器/虚拟机/物理机,Service Mesh都是可行的。
 
 
3、同时上 Service Mesh 加 Cloud Native
 
通常来说我们不赞成同时进行这两个技术变革,因为涉及到的内容实在太多,集中在一起,指望一口气吃成大胖子,容易被噎住。
 
但是不管怎么样这条路终究还是存在的,而且如果决心够大+愿意投入+高人护航,也不失是一个一次性彻底解决问题的方案,先列在这里。
 
 
 
何去何从
 
路径1和路径2,在讨论该如何选择之前,还有一个问题:就是路径2是不是真的可行?

 
青黄不接的尴尬

我们前面说道路径2理论上是可行的,但是目前的实际情况是真要选择就会发现:难。这要从目前市面上的 Service Mesh 产品谈起,按照我的划分方式,我将目前主流的四个 Service Mesh 产品划分为两代:
第一代 Service Mesh,包括 Linkerd 和 Envoy。
 
这两个产品目前都是 production ready,而且都和平台无关,对物理机/虚拟机/容器都可以支持。
第二代 Service Mesh,包括 Istio 和 Conduit
 
这两个产品目前都还在发展中,暂时都未能达到 production ready。
 
如果要在当前时刻进行 Service Mesh 的技术选型,我们就会发现这样一个尴尬的局面:
Istio 和 Conduit 还没有 production ready,上线不适合,只能继续等待。
 
Linkerd 和 Envoy 倒是可用,但是,在了解 Istio 和 Conduit 之后,又有多少人愿意在现在选择上 Linkerd 和 Envoy?
 
所谓青黄不接,便是如此。
 
在接下来的讨论中,我们假定大家都是在等待 Istio 和 Conduit。
 
我们回到前面的话题,限定 Istio 和 Conduit,如果选择路径2(先 Service Mesh,再 Cloud Native),会如何?
 
 
 
对平台的要求
  
Conduit

首先 Conduit 非常坚定执着的”Say No”了,官网非常清晰的表述:
 
Conduit is a next-generation ultralight service mesh for Kubernetes.
 
私底下和 William (小编注:Buoyant CEO)就此简单聊过,他给出来的回答很委婉也很实在:Conduit 总要从某个地方起步,K8S是目前最好选择。以后可以支持,但是肯定先 K8S 再说。考虑到 Conduit 和 Buoyant 公司的处境,尤其全公司才二十,我们不能要求太多。
 
可以明确的说,短期之内,起码2018年,Conduit 官方不会有对  K8S之外的支持。

 
Istio   

Isito 最早版本是只支持 K8S 的,后来陆续提供了对其他非 K8S 环境的支持,比如 Docker+Consul/Eureka 的方案,还有计划中但是还没有完成的 Cloud Fountry 和 Mesos 集成。
 
对于 VM,Istio 有提供一个 VM 解决方案,具体看见官方文档:
Integrating Virtual Machines集成虚拟机: 中文翻译版本
 
从文档上看是可以支持部分服务在 K8S 之外:
 
TBD: 需要继续调研看 Istio 是否可以在纯粹的  VM环境下运行,即完全脱离 K8S 和容器。
 
 
 
平台要求总结
 
Conduit 和 Istio(还有待最后确认)对容器/K8s/Cloud Native 都有要求,导致目前路径2(先 Service Mesh,再 Cloud Native)几乎没有无法实现,至少在不改动 Conduit 和 Istio 的情况下。
 
这就意味着,只能走路径1(先 Cloud Native,再 Service Mesh),也就回到了最早的问题: 做好了 Cloud Native 的准备吗?
 
 
 
后记
 
需要做一个市场调查,要有足够多的样本:
 
企业客户对微服务和容器,是打算先上容器/K8S再上微服务,还是希望可以直接在虚拟机/物理机上做微服务,后面再迁移到K8S?
 
有兴趣的朋友,添加小数微信:xiaoshu062,加入service mesh微信交流群,一起讨论~
 
 
 
讨论和反馈
 
在这篇博客文章编写前一天晚上,和来自 Google Istio 开发团队的Hu同学有过一次长时间的讨论。
 
在征得同意之后我将讨论内容整理如下。特别鸣谢Hu同学的指点:
 
Hu: 你好,这么晚还在工作?
 
敖小剑:正在整理思路。
 
Hu: 文章写的很好。
 
敖小剑:您客气了,还是你们产品做的好,istio我是报以厚望。
 
Hu:希望不要让大家失望,能够解决一些实际问题。
 
敖小剑:一起努力吧,就算有小的不足,也还是有机会改进的,istio的大方向我是非常认可的。
 
Hu:恩,现在是一个新时代的开始,cloud native是大势所趋,后面我们会看到更多有趣的技术出来。有什么想法和建议,也欢迎在istio的工作组里提。
 
敖小剑:我现在是一边等istio的production ready版本,一边着手准备,为落地可能遇到的问题或者需求预先研究一下。
 
国内可能情况和美国不太一样,目前国内企业,尤其传统形的企业,他们的技术基础非常糟糕,离cloud native差距很远。
 
但是他们又有强烈的意愿上微服务。
 
Hu:对,但这也是机遇。国内的企业软件市场还有很大空间。美国公司喜欢新技术,跟的比较紧。
 
敖小剑:我选择istio这种service mesh方案来推微服务落地,本意是降低微服务普及的门槛。
 
这样普通企业用户才有机会玩转微服务,毕竟这些公司连spring cloud都玩的很吃力。
 
现在的问题是,istio比较强调cloud native,而这些企业用户基本都没有准备好cloud native。
 
Hu:呵呵,我觉得你的想法很好,不过可能有点超前。据我所知,即使在很多互联网大企业, service mesh也没有完全落地。第一步可能还是docker化和普及kubernetes。
 
敖小剑:我刚才还在看如何在非k8s,非docker环境下跑istio。嗯,你的思路是先准备好路,再让istio这辆车上路?我的思路有点倾向于让service mesh这个车在没路的情况下也能跑起来。
 
Hu:我的意思是要看条件,可以把非K8S方案作为一个过渡。最终还是要迁移到kube和云上。
 
敖小剑:嗯,对的,我想增加一个过渡阶段。
 
Hu:都可以的,就看企业的自身条件了。Google这边是提供不同解决方案的,但最终目标还是希望客户迁移到云上。
 
敖小剑:cloud native条件不成熟的情况下,先过渡一下,把应用迁移到非docker条件下的istio,先完成微服务化。
 
两条路,一条先cloud native再service mesh,一条先service mesh再cloud native。
 
Hu:恩,我觉得都是可行的。如果是重IT的公司,建议直接cloudnative。
 
敖小剑:不同企业可能演进的速度和步骤不一样。微服务化更多是业务团队推动,cloud native通常是运维和基础架构团队。
 
Hu:我对国内情况不了解,只是个人看法,呵呵。其实可能最重要的还是普及devops的模式,人的问题解决了,别的都好办。
 
敖小剑:嗯,我个人的感觉是技术导向的互联网公司容易做到cloud native,他们走你说的路线比较合理。但是普通企业用户可能会选择先微服务化。
 
当然这个我还要继续调研和确认,比较我现在接触的样本也不够多。所以,多讨论多沟通,确认好实际需要再说。
 
我这段时间会陆陆续续把想法写出来,然后提交大家讨论。希望你多给意见。
 
Hu:好的。
 
在这篇博客文章发表收集到的讨论和评论反馈:
 
张琦:我们的经验,必定要走你说的路径2,servicemesh甚至要充当从传统应用到Cloudnative之间的桥梁。例如在逐渐微服务化的过程中 用mesh来接入原来的单体应用 然后再一点一点去拆;或者用mesh接入其他协议的遗留应用来做一下协议转换,我记得微博也有这种用法
 
崔秀龙:posta那篇微服务改造的文章还是很可以参考的
 
肖晟:没错,企业随着IT架构的演进,上面提到的遗留应用并不在少数。需要解决协议适配等问题,又不想受限于服务总线类流量中心的瓶颈,mesh是一种理想的解决之道;而想要上mesh,又可能推动其上cloudnative。所以从企业总体来说,这个演变很可能是混合的,不过从单应用来说会是分步的。
 
肖晟:另外在思考的一个问题是,在一个企业IT架构下,由于不同技术标准或安全需求等因素的影响,有没有可能同时存在两套或多套servicemesh。
 
备注: 这个话题后面会有专门的章节
崔秀龙:我觉得是两个必须:必须容器云,必须打SC。
 
宋净超:理想很丰满,现实很骨感啊。
 
崔秀龙:我个人的感觉是有了SM之后,微服务的定义就很清晰了。
 
宋净超:同意。
 
孟樊亮:迁移到k8s,感觉是服务注册/发现/互通只是第一步,后续的治理和运维才是无尽大坑。
 
于文涛:我们公司应该是偏第一种方案,先走容器化,k8s后微服务化。不过微服务和也其实在同时推进。
 
 
 
 
推荐阅读:

Service Mesh深度思考 | DreamMesh抛砖引玉(1)-序
Istio服务网格高级流量镜像,7种模式解决流量镜像难题
使用Istio简化微服务系列三:如何才能做“金丝雀部署”,并通过Istio增加流量?
在Kubernetes平台上,应对不同场景外部流量引入集群,这3种工具改如何选择?
 
 
  查看全部
作者:
       敖小剑,资深码农,十六年软件开发经验,微服务专家,Service Mesh布道师。专注于基础架构,Cloud Native 拥护者,敏捷实践者,坚守开发一线打磨匠艺的架构师。机缘巧合下对基础架构和微服务有过深入研究和实践。
        博客链接:https://skyao.io
 
 
 
我对 Service Mesh 的第一个担忧,来自 Cloud Native
 
 
Are You Ready?
 

作为 Cloud Native 的忠实拥护者,我从不怀疑 Cloud Native 的价值和前景。可以说,微服务/容器这些技术天然就适合走 Cloud Native 的道路。
 
但是,我担心的是:准备上 Service Mesh 的各位,是否都已经做到了 Ready for Cloud Native?
 

 
这真是一个尴尬的问题。
 
现实摆在眼前,根据我最近几个月跑过的企业客户(大大小小接近二十家)的实际情况看,可以说:情况非常不乐观。
 
备注: 这里只讨论普通企业用户,对于技术和管理都比较先进的互联网大公司来说,Cloud Native的普及情况要好很多。
 
这就引出了下面这个问题:
 
如果没有Cloud Native基础,那还能不能用Service Mesh?
 
 
 
发展路径

 
这里有三条发展路径可选:
 
1、先Cloud Native,再Service Mesh
 
理论上说,这是最合理的:先把底层基础设施铺好,再在其上构建上层业务应用。
 
具体说,就是先上云/容器/k8s,应用暂时维持原状。不管是单体应用,还是基于Dubbo/Spring Cloud等侵入式开发框架的微服务应用,先上云再说。更直白一点,上k8s。
 
等待Istio/Conduit成熟之后,再迁移到Service Mesh方案。
 
 
 2、先Service Mesh,再Cloud Native
 
这个方案理论上也是可行的:先用Service Mesh方案完成微服务体系建设,之后再迁移到k8s平台。
 
之所以说理论上没有问题,是指Service Mesh从设计理念上,对底层是不是容器并没有特别要求。无论是容器/虚拟机/物理机,Service Mesh都是可行的。
 
 
3、同时上 Service Mesh 加 Cloud Native
 
通常来说我们不赞成同时进行这两个技术变革,因为涉及到的内容实在太多,集中在一起,指望一口气吃成大胖子,容易被噎住。
 
但是不管怎么样这条路终究还是存在的,而且如果决心够大+愿意投入+高人护航,也不失是一个一次性彻底解决问题的方案,先列在这里。
 
 
 
何去何从

 
路径1和路径2,在讨论该如何选择之前,还有一个问题:就是路径2是不是真的可行?

 
青黄不接的尴尬


我们前面说道路径2理论上是可行的,但是目前的实际情况是真要选择就会发现:难。这要从目前市面上的 Service Mesh 产品谈起,按照我的划分方式,我将目前主流的四个 Service Mesh 产品划分为两代:
  • 第一代 Service Mesh,包括 Linkerd 和 Envoy。

 
这两个产品目前都是 production ready,而且都和平台无关,对物理机/虚拟机/容器都可以支持。
  • 第二代 Service Mesh,包括 Istio 和 Conduit

 
这两个产品目前都还在发展中,暂时都未能达到 production ready。
 
如果要在当前时刻进行 Service Mesh 的技术选型,我们就会发现这样一个尴尬的局面:
  • Istio 和 Conduit 还没有 production ready,上线不适合,只能继续等待。

 
  • Linkerd 和 Envoy 倒是可用,但是,在了解 Istio 和 Conduit 之后,又有多少人愿意在现在选择上 Linkerd 和 Envoy?

 
所谓青黄不接,便是如此。
 
在接下来的讨论中,我们假定大家都是在等待 Istio 和 Conduit。
 
我们回到前面的话题,限定 Istio 和 Conduit,如果选择路径2(先 Service Mesh,再 Cloud Native),会如何?
 
 
 
对平台的要求
  
Conduit

首先 Conduit 非常坚定执着的”Say No”了,官网非常清晰的表述:
 
Conduit is a next-generation ultralight service mesh for Kubernetes.
 
私底下和 William (小编注:Buoyant CEO)就此简单聊过,他给出来的回答很委婉也很实在:Conduit 总要从某个地方起步,K8S是目前最好选择。以后可以支持,但是肯定先 K8S 再说。考虑到 Conduit 和 Buoyant 公司的处境,尤其全公司才二十,我们不能要求太多。
 
可以明确的说,短期之内,起码2018年,Conduit 官方不会有对  K8S之外的支持。

 
Istio   

Isito 最早版本是只支持 K8S 的,后来陆续提供了对其他非 K8S 环境的支持,比如 Docker+Consul/Eureka 的方案,还有计划中但是还没有完成的 Cloud Fountry 和 Mesos 集成。
 
对于 VM,Istio 有提供一个 VM 解决方案,具体看见官方文档:
  • Integrating Virtual Machines
  • 集成虚拟机: 中文翻译版本

 
从文档上看是可以支持部分服务在 K8S 之外:
 
TBD: 需要继续调研看 Istio 是否可以在纯粹的  VM环境下运行,即完全脱离 K8S 和容器。
 
 
 
平台要求总结

 
Conduit 和 Istio(还有待最后确认)对容器/K8s/Cloud Native 都有要求,导致目前路径2(先 Service Mesh,再 Cloud Native)几乎没有无法实现,至少在不改动 Conduit 和 Istio 的情况下。
 
这就意味着,只能走路径1(先 Cloud Native,再 Service Mesh),也就回到了最早的问题: 做好了 Cloud Native 的准备吗?
 
 
 
后记
 
需要做一个市场调查,要有足够多的样本:
 
企业客户对微服务和容器,是打算先上容器/K8S再上微服务,还是希望可以直接在虚拟机/物理机上做微服务,后面再迁移到K8S?
 
有兴趣的朋友,添加小数微信:xiaoshu062,加入service mesh微信交流群,一起讨论~
 
 
 
讨论和反馈
 

在这篇博客文章编写前一天晚上,和来自 Google Istio 开发团队的Hu同学有过一次长时间的讨论。
 
在征得同意之后我将讨论内容整理如下。特别鸣谢Hu同学的指点:
 
Hu: 你好,这么晚还在工作?
 
敖小剑:正在整理思路。
 
Hu: 文章写的很好。
 
敖小剑:您客气了,还是你们产品做的好,istio我是报以厚望。
 
Hu:希望不要让大家失望,能够解决一些实际问题。
 
敖小剑:一起努力吧,就算有小的不足,也还是有机会改进的,istio的大方向我是非常认可的。
 
Hu:恩,现在是一个新时代的开始,cloud native是大势所趋,后面我们会看到更多有趣的技术出来。有什么想法和建议,也欢迎在istio的工作组里提。
 
敖小剑:我现在是一边等istio的production ready版本,一边着手准备,为落地可能遇到的问题或者需求预先研究一下。
 
国内可能情况和美国不太一样,目前国内企业,尤其传统形的企业,他们的技术基础非常糟糕,离cloud native差距很远。
 
但是他们又有强烈的意愿上微服务。
 
Hu:对,但这也是机遇。国内的企业软件市场还有很大空间。美国公司喜欢新技术,跟的比较紧。
 
敖小剑:我选择istio这种service mesh方案来推微服务落地,本意是降低微服务普及的门槛。
 
这样普通企业用户才有机会玩转微服务,毕竟这些公司连spring cloud都玩的很吃力。
 
现在的问题是,istio比较强调cloud native,而这些企业用户基本都没有准备好cloud native。
 
Hu:呵呵,我觉得你的想法很好,不过可能有点超前。据我所知,即使在很多互联网大企业, service mesh也没有完全落地。第一步可能还是docker化和普及kubernetes。
 
敖小剑:我刚才还在看如何在非k8s,非docker环境下跑istio。嗯,你的思路是先准备好路,再让istio这辆车上路?我的思路有点倾向于让service mesh这个车在没路的情况下也能跑起来。
 
Hu:我的意思是要看条件,可以把非K8S方案作为一个过渡。最终还是要迁移到kube和云上。
 
敖小剑:嗯,对的,我想增加一个过渡阶段。
 
Hu:都可以的,就看企业的自身条件了。Google这边是提供不同解决方案的,但最终目标还是希望客户迁移到云上。
 
敖小剑:cloud native条件不成熟的情况下,先过渡一下,把应用迁移到非docker条件下的istio,先完成微服务化。
 
两条路,一条先cloud native再service mesh,一条先service mesh再cloud native。
 
Hu:恩,我觉得都是可行的。如果是重IT的公司,建议直接cloudnative。
 
敖小剑:不同企业可能演进的速度和步骤不一样。微服务化更多是业务团队推动,cloud native通常是运维和基础架构团队。
 
Hu:我对国内情况不了解,只是个人看法,呵呵。其实可能最重要的还是普及devops的模式,人的问题解决了,别的都好办。
 
敖小剑:嗯,我个人的感觉是技术导向的互联网公司容易做到cloud native,他们走你说的路线比较合理。但是普通企业用户可能会选择先微服务化。
 
当然这个我还要继续调研和确认,比较我现在接触的样本也不够多。所以,多讨论多沟通,确认好实际需要再说。
 
我这段时间会陆陆续续把想法写出来,然后提交大家讨论。希望你多给意见。
 
Hu:好的。
 
在这篇博客文章发表收集到的讨论和评论反馈:
 
张琦:我们的经验,必定要走你说的路径2,servicemesh甚至要充当从传统应用到Cloudnative之间的桥梁。例如在逐渐微服务化的过程中 用mesh来接入原来的单体应用 然后再一点一点去拆;或者用mesh接入其他协议的遗留应用来做一下协议转换,我记得微博也有这种用法
 
崔秀龙:posta那篇微服务改造的文章还是很可以参考的
 
肖晟:没错,企业随着IT架构的演进,上面提到的遗留应用并不在少数。需要解决协议适配等问题,又不想受限于服务总线类流量中心的瓶颈,mesh是一种理想的解决之道;而想要上mesh,又可能推动其上cloudnative。所以从企业总体来说,这个演变很可能是混合的,不过从单应用来说会是分步的。
 
肖晟:另外在思考的一个问题是,在一个企业IT架构下,由于不同技术标准或安全需求等因素的影响,有没有可能同时存在两套或多套servicemesh。
 
备注: 这个话题后面会有专门的章节
崔秀龙:我觉得是两个必须:必须容器云,必须打SC。
 
宋净超:理想很丰满,现实很骨感啊。
 
崔秀龙:我个人的感觉是有了SM之后,微服务的定义就很清晰了。
 
宋净超:同意。
 
孟樊亮:迁移到k8s,感觉是服务注册/发现/互通只是第一步,后续的治理和运维才是无尽大坑。
 
于文涛:我们公司应该是偏第一种方案,先走容器化,k8s后微服务化。不过微服务和也其实在同时推进。
 
 
 
 
推荐阅读:

Service Mesh深度思考 | DreamMesh抛砖引玉(1)-序
Istio服务网格高级流量镜像,7种模式解决流量镜像难题
使用Istio简化微服务系列三:如何才能做“金丝雀部署”,并通过Istio增加流量?
在Kubernetes平台上,应对不同场景外部流量引入集群,这3种工具改如何选择?
 
 
 

Kubernetes NodePorts vs LoadBalancers vs Ingress,到底应该什么时候使用?

小数 发表了文章 • 0 个评论 • 271 次浏览 • 2018-03-29 10:25 • 来自相关话题

作者:Sandeep Dinesh

翻译:狄卫华

原文:Kubernetes NodePort vs LoadBalancer vs Ingress? When should I use what?

原文链接:https://medium.com/google-clou ... 849e0



最近有人向我了解 NodePorts ,LoadBalancers 和 Ingress 之间的区别是怎么样的。 它们都是将外部流量引入群集的方式,适用的场景却各不相同。 本文接下来我们将介绍它们的工作原理以及适用的相关场景。


注意:文中所述内容适用于 GKE (Google Kubernetes Engine 注1)。 如果你在其他云平台上运行使用步骤略有不同,比如 minikube 或其他相关软件。 我也不打算过多深入技术细节, 如果你有兴趣了解更多,Kubernetes 官方文档(注2)会提供更多的有用资源!



ClusterIP

ClusterIP 服务是 Kubernetes 默认的服务类型。 如果你在集群内部创建一个服务,则在集群内部的其他应用程序可以进行访问,但是不具备集群外部访问的能力。

ClusterIP 服务的 YAML 文件看起来像这样:


apiVersion: v1


kind: Service

metadata:  

  name: my-internal-service

selector:    

  app: my-app

spec:

  type: ClusterIP

  ports:  

  - name: http

    port: 80

    targetPort: 80

    protocol: TCP


如果不能从互联网访问 ClusterIP 服务,我为什么要谈论它呢?事实上,你可以通过 Kubernetes 代理进行访问。








感谢 Ahmet Alp Balkan(注3)提供的图表


启动 Kubernetes 代理:

$ kubectl proxy --port=8080

现在,可以通过 Kubernetes API 通过以下的模式来访问这个服务:


http://localhost:8080/api/v1/p ... t%3B/,


通过这种方式可以使用以下的地址来访问我们上述定义的服务:

http://localhost:8080/api/v1/p ... http/


何时使用这种访问方式?


有以下几种场景,你可以使用 Kubernetes 代理的方式来访问服务:

1. 调试服务或者某些情况下通过笔记本电脑直接连接服务

2. 允许内部的通信,显示内部的仪表盘(dashboards)等

因为此种方式需要作为一个授权用户运行 kubectl,因此不应该用来暴露服务至互联网访问或者用于生产环境。


NodePort

NodePort 服务通过外部访问服务的最基本的方式。顾名思义,NodePort 就是在所有的节点或者虚拟机上开放特定的端口,该端口的流量将被转发到对应的服务。
 





从技术上层面,这不能算是最准确的图表,但我认为它能够直观展示了 NodePort 的工作方式。

NodePort 服务的 YAML 文件看起来像这样:

apiVersion: v1

kind: Service

metadata:  

  name: my-nodeport-service

selector:    

  app: my-app

spec:

  type: NodePort

  ports:  

  - name: http

    port: 80

    targetPort: 80

    nodePort: 30036

    protocol: TCP

从根本上讲,NodePort 方式的服务与 ClusterIP 方式的服务有两个区别。第一,类型是 NodePort,这需要指定一个称作 nodePort 的附加端口,并在所有节点上打开对应的端口。如果我们不具体指定端口,集群会选择一个随机的端口。大多数的情况下,我们都可以让 Kubernetes 帮我们选择合适的端口。正如 thockin(注4) 所描述的那样,有许多相关的注意事项(caveats)关于那些端口可供我们使用。


何时使用这种访问方式?

NodePort 方式有许多缺点:

1. 每个服务占用一个端口
2. 可以使用的  30000-32767 范围端口 (译者注:可以通过api-server启动参数service-node-port-range,指定限制范围,默认为30000-32767)
3. 如果节点/虚拟机IP地址发生更改,需要进行相关处理


由于上述原因,我不建议在生产环境中使用直接暴露服务。 如果运行的服务不要求高可用或者非常关注成本,这种方法则比较适合。 很好的例子就是用于演示或临时使用的程序。



LoadBalancer

LoadBalancer 服务是暴露服务至互联网最标准的方式。在 GKE 上,这将启动一个网络负载均衡器(注5),它会提供一个 IP 地址,以将所有流量转发到服务。






感谢 Ahmet Alp Balkan提供图表

何时使用这种访问方式?这是公开服务的默认的方法。指定的端口上流量都将被转发到对应的服务,不经过过滤和其他路由等操作。这种方式意味着转发几乎任何类型的流量,如HTTP,TCP,UDP,Websockets,gRPC或其他。


这种方式最大的缺点是,负载均衡器公开的每个服务都将获取独立 IP 地址,而我们则必须为每个暴露的服务对应的负载均衡器支付相关费用,这可能会变得非常昂贵!




Ingress

和上述讨论的服务方式不同,Ingress 实际上并不是服务类型中的一种。相反,它位于多个服务的前端充当一个智能路由或者集群的入口点。

你可以使用 Ingress 做很多不同的事情,并且不同类型的 Ingress 控制也具备不同的能力。

GKE 默认的 Ingress 控制器将启动一个 HTTP(S) 的负载均衡器。则将使我们可以基于访问路径和子域名将流量路由到后端服务。例如,你可以将 `foo.yourdomain.com` 下的流量转发到 foo 服务,将`yourdomain.com/bar/` 路径下的流量转发到 bar 服务。







感谢 Ahmet Alp Balkan提供图表


在 GKE 上定义 L7层 HTTP 负载均衡器的 Ingress 对象定义的 YAML 看起来像这样:

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: my-ingress

spec:

  backend:

    serviceName: other

    servicePort: 8080

  rules:

  - host: foo.mydomain.com

    http:

      paths:

      - backend:

          serviceName: foo

          servicePort: 8080

  - host: mydomain.com

    http:

      paths:

      - path: /bar/*

        backend:

          serviceName: bar

          servicePort: 8080


何时使用这种方式?Ingress 方式可能是暴露服务的最强大的方式,但也最复杂。现在有不同类型的 Ingress 控制器,包括 Google 云 负载均衡器(注6), Nginx(注7), Contour(注8), Istio(注9)等。此外,还有 Ingress 控制器的许多插件,比如 cert-manager(注10)可以用来自动为服务提供 SSL 证书。


如果希望在同一个IP地址下暴露多个服务,并且它们都使用相同的 L7 协议(通常是HTTP),则 Ingress 方式最有用。 如果使用本地 GCP 集成,则只需支付一台负载平衡器费用,并且是“智能”性 Ingress ,可以获得许多开箱即用的功能(如SSL,Auth,路由等)。


资源:

Kubernetes:https://medium.com/tag/kubernetes?source=post

Microservices:https://medium.com/tag/microservices?source=post

Services:https://medium.com/tag/services?source=post

Load Balancing:https://medium.com/tag/load-balancing?source=post

Ingress:https://medium.com/tag/ingress?source=post





1、https://cloud.google.com/gke

2、https://kubernetes.io/docs/con ... vice/

3、https://medium.com/@ahmetb

4、(https://medium.com/@thockin)

5、https://cloud.google.com/compu ... work/

6、https://cloud.google.com/kuber ... ancer

7、https://github.com/kubernetes/ingress-nginx

8、https://github.com/heptio/contour

9、https://istio.io/docs/tasks/tr ... .html

10、https://github.com/jetstack/cert-manager
  查看全部
作者:Sandeep Dinesh

翻译:狄卫华

原文:Kubernetes NodePort vs LoadBalancer vs Ingress? When should I use what?

原文链接:https://medium.com/google-clou ... 849e0



最近有人向我了解 NodePorts ,LoadBalancers 和 Ingress 之间的区别是怎么样的。 它们都是将外部流量引入群集的方式,适用的场景却各不相同。 本文接下来我们将介绍它们的工作原理以及适用的相关场景。


注意:文中所述内容适用于 GKE (Google Kubernetes Engine 注1)。 如果你在其他云平台上运行使用步骤略有不同,比如 minikube 或其他相关软件。 我也不打算过多深入技术细节, 如果你有兴趣了解更多,Kubernetes 官方文档(注2)会提供更多的有用资源!



ClusterIP

ClusterIP 服务是 Kubernetes 默认的服务类型。 如果你在集群内部创建一个服务,则在集群内部的其他应用程序可以进行访问,但是不具备集群外部访问的能力。

ClusterIP 服务的 YAML 文件看起来像这样:


apiVersion: v1


kind: Service

metadata:  

  name: my-internal-service

selector:    

  app: my-app

spec:

  type: ClusterIP

  ports:  

  - name: http

    port: 80

    targetPort: 80

    protocol: TCP


如果不能从互联网访问 ClusterIP 服务,我为什么要谈论它呢?事实上,你可以通过 Kubernetes 代理进行访问。


1.png



感谢 Ahmet Alp Balkan(注3)提供的图表


启动 Kubernetes 代理:

$ kubectl proxy --port=8080

现在,可以通过 Kubernetes API 通过以下的模式来访问这个服务:


http://localhost:8080/api/v1/p ... t%3B/


通过这种方式可以使用以下的地址来访问我们上述定义的服务:

http://localhost:8080/api/v1/p ... http/


何时使用这种访问方式?


有以下几种场景,你可以使用 Kubernetes 代理的方式来访问服务:

1. 调试服务或者某些情况下通过笔记本电脑直接连接服务

2. 允许内部的通信,显示内部的仪表盘(dashboards)等

因为此种方式需要作为一个授权用户运行 kubectl,因此不应该用来暴露服务至互联网访问或者用于生产环境。


NodePort

NodePort 服务通过外部访问服务的最基本的方式。顾名思义,NodePort 就是在所有的节点或者虚拟机上开放特定的端口,该端口的流量将被转发到对应的服务。
 
2.png


从技术上层面,这不能算是最准确的图表,但我认为它能够直观展示了 NodePort 的工作方式。

NodePort 服务的 YAML 文件看起来像这样:

apiVersion: v1

kind: Service

metadata:  

  name: my-nodeport-service

selector:    

  app: my-app

spec:

  type: NodePort

  ports:  

  - name: http

    port: 80

    targetPort: 80

    nodePort: 30036

    protocol: TCP

从根本上讲,NodePort 方式的服务与 ClusterIP 方式的服务有两个区别。第一,类型是 NodePort,这需要指定一个称作 nodePort 的附加端口,并在所有节点上打开对应的端口。如果我们不具体指定端口,集群会选择一个随机的端口。大多数的情况下,我们都可以让 Kubernetes 帮我们选择合适的端口。正如 thockin(注4) 所描述的那样,有许多相关的注意事项(caveats)关于那些端口可供我们使用。


何时使用这种访问方式?

NodePort 方式有许多缺点:

1. 每个服务占用一个端口
2. 可以使用的  30000-32767 范围端口 (译者注:可以通过api-server启动参数service-node-port-range,指定限制范围,默认为30000-32767)
3. 如果节点/虚拟机IP地址发生更改,需要进行相关处理


由于上述原因,我不建议在生产环境中使用直接暴露服务。 如果运行的服务不要求高可用或者非常关注成本,这种方法则比较适合。 很好的例子就是用于演示或临时使用的程序。



LoadBalancer

LoadBalancer 服务是暴露服务至互联网最标准的方式。在 GKE 上,这将启动一个网络负载均衡器(注5),它会提供一个 IP 地址,以将所有流量转发到服务。

3.png


感谢 Ahmet Alp Balkan提供图表

何时使用这种访问方式?这是公开服务的默认的方法。指定的端口上流量都将被转发到对应的服务,不经过过滤和其他路由等操作。这种方式意味着转发几乎任何类型的流量,如HTTP,TCP,UDP,Websockets,gRPC或其他。


这种方式最大的缺点是,负载均衡器公开的每个服务都将获取独立 IP 地址,而我们则必须为每个暴露的服务对应的负载均衡器支付相关费用,这可能会变得非常昂贵!




Ingress

和上述讨论的服务方式不同,Ingress 实际上并不是服务类型中的一种。相反,它位于多个服务的前端充当一个智能路由或者集群的入口点。

你可以使用 Ingress 做很多不同的事情,并且不同类型的 Ingress 控制也具备不同的能力。

GKE 默认的 Ingress 控制器将启动一个 HTTP(S) 的负载均衡器。则将使我们可以基于访问路径和子域名将流量路由到后端服务。例如,你可以将 `foo.yourdomain.com` 下的流量转发到 foo 服务,将`yourdomain.com/bar/` 路径下的流量转发到 bar 服务。


4.png


感谢 Ahmet Alp Balkan提供图表


在 GKE 上定义 L7层 HTTP 负载均衡器的 Ingress 对象定义的 YAML 看起来像这样:

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: my-ingress

spec:

  backend:

    serviceName: other

    servicePort: 8080

  rules:

  - host: foo.mydomain.com

    http:

      paths:

      - backend:

          serviceName: foo

          servicePort: 8080

  - host: mydomain.com

    http:

      paths:

      - path: /bar/*

        backend:

          serviceName: bar

          servicePort: 8080


何时使用这种方式?Ingress 方式可能是暴露服务的最强大的方式,但也最复杂。现在有不同类型的 Ingress 控制器,包括 Google 云 负载均衡器(注6), Nginx(注7), Contour(注8), Istio(注9)等。此外,还有 Ingress 控制器的许多插件,比如 cert-manager(注10)可以用来自动为服务提供 SSL 证书。


如果希望在同一个IP地址下暴露多个服务,并且它们都使用相同的 L7 协议(通常是HTTP),则 Ingress 方式最有用。 如果使用本地 GCP 集成,则只需支付一台负载平衡器费用,并且是“智能”性 Ingress ,可以获得许多开箱即用的功能(如SSL,Auth,路由等)。


资源:

Kubernetes:https://medium.com/tag/kubernetes?source=post

Microservices:https://medium.com/tag/microservices?source=post

Services:https://medium.com/tag/services?source=post

Load Balancing:https://medium.com/tag/load-balancing?source=post

Ingress:https://medium.com/tag/ingress?source=post





1、https://cloud.google.com/gke

2、https://kubernetes.io/docs/con ... vice/

3、https://medium.com/@ahmetb

4、(https://medium.com/@thockin)

5、https://cloud.google.com/compu ... work/

6、https://cloud.google.com/kuber ... ancer

7、https://github.com/kubernetes/ingress-nginx

8、https://github.com/heptio/contour

9、https://istio.io/docs/tasks/tr ... .html

10、https://github.com/jetstack/cert-manager
 

Service Mesh深度思考 | DreamMesh抛砖引玉(1)-序言

小数 发表了文章 • 0 个评论 • 591 次浏览 • 2018-03-20 10:21 • 来自相关话题

 作者:
       敖小剑,资深码农,十六年软件开发经验,微服务专家,Service Mesh布道师。专注于基础架构,Cloud Native 拥护者,敏捷实践者,坚守开发一线打磨匠艺的架构师。机缘巧合下对基础架构和微服务有过深入研究和实践。博客链接:https://skyao.io



小数话:今天为大家整理了小剑老师的 Dream Mesh 系列文章,在之后的时间里,我们会依次为大家发送,对于该系列有兴趣的朋友,欢迎加入 service mesh 交流群(添加小数微信:xiaoshu062,备注:服务网格,即可),和小剑老师一起讨论关于 Dream Mesh 的相关内容~



前言

相信能看到这篇博客的同学,大体都知道过去几个月间,我在努力地研究 Service Mesh 并致力于在国内拓荒和布道。

坦言说:Service Mesh 的发展进程,当前还处于前景虽然一致看好,但是脚下的路还处于需要一步一步走的早期艰难阶段。由于 Istio 和 Conduit 的尚未成熟,造成目前 Service Mesh 青黄不接的尴尬局面。

近期在和很多朋友交流,也都谈到这个话题,着实有些无奈,只能静静的等待 Istio 和 Cconduit 的发展。好在这两个产品也很争气,近期都快速发出了新版本。


小编注:目前 Istio 是0.6版本(中文技术文档http://istio.doczh.cn/), Conduit 是 0.3.1版本(中文技术文档http://conduit.doczh.cn/)


然而 Service Mesh 的现状,它的不够成熟,终究还是引发了猜疑,不安和观望。







Doubt kills more dreams than failure ever has.

在猎鹰升空,马斯克“封神”的那周,我更能深刻体会这句话的内涵。



正视问题

过去的一个月间,我一直在认真的思考这样一个问题:

Service Mesh 真的能完美解决问题吗?

这里我们抛开前面所说的 Istio 或者 Conduit 暂未成熟的情况,毕竟在不远的未来即将可以被解决,不出意外会在2018年年中或者年底。


让我们设想:如果明天 Istio 或者 Conduit 发布出 Production Ready 的版本,是不是我们就可以欢欣鼓舞的直接将系统搬迁到 Service Mesh 上?


还差点什么?


我将会在稍后的系列文章中将我思考的问题逐个列出来,暂时会有下列内容:


1. Ready for Cloud Native?

我对 Service Mesh 的第一个担忧,来自 Cloud Native。

作为 Cloud Native 的忠实拥护者,我不怀疑 Cloud Native 的价值和前景。但是,我担心的是:准备上 Service Mesh 的各位,是否都已经做到了Ready for Cloud Native?


2. 如何从非 Service Mesh 体系过渡到 Service Mesh?

即使一切都 Ready,对于一个有存量应用的系统而言,绝无可能在一夜之间就将所有应用都改为 Service Mesh,然后一起上线。


必然会有一个中间过渡状态,一部分应用开始搬迁到 Service Mesh,大部分还停留在原有体系。那么,如何在过渡阶段让 Service Mesh 内的服务和Service Mesh 外的服务相互通讯?


3. 零侵入的代价

Service Mesh的一个突出优点就是对应用的侵入度非常低,低到可以”零侵入”。

然而,没有任何事情是可以十全十美的,零侵入带来的弊端:iptables 一刀切的方案有滥用嫌疑,为了不劫持某些网络访问又不得不增加配置去绕开。

是否考虑补充一个低侵入的方案?



4. 网络通讯方案

Service Mesh 解决服务间通讯的方式是基于网络层,HTTP1.1/HTTP2 和可能的 TCP,对于选择什么样的序列化方案和远程访问方案并未限制。

好处是我们可以自由的选择各种方案,坏处就是自由意味着自己做。

能否以类库或者最佳实践的方式给出适合 Service Mesh 时代的网络通讯方案?



5. 性能开销

我们反复谈到,Service Mesh 的核心在于将原有以类库方式提供的功能拆分到独立的 sidecar 进程中,以远程调用的方式来强行解耦服务间通讯的业务语义和服务间通讯的具体实现。这带来了诸多的好处,但是这对性能会有什么影响?


6. 绕不开的Spring

对于 Java 企业应用,Spring 是无论如何绕不开的。然而目前我们没有看到Spring社区对 Service Mesh 的任何回应。因此,如何以正确的姿势在 Service Mesh 时代使用 Spring,需要自己探索。

理论上说,springboot on service mesh 有可能成为一个清爽的解决方案。然后路终究是要走一遍才知道是不是那么美好。



7. Spring Cloud 迁移之路

虽然 Service Mesh 号称下一代微服务,取代 Spring Cloud 是 Service Mesh 与生俱来的天然目标之一。

但是以目前市场形式,Spring Cloud 在未来很长一段时间之内都会是市场主流和很多公司的第一选择。如何在迁移到 Service Mesh 之前加强 Spring Cloud,并为将来转入 Service Mesh 铺路,是一个艰难而极具价值的话题。



8. API gateway

Service Mesh 解决的是东西向服务间通讯的问题,我们来审视一下 API gateway 到微服务之间的南北向通讯: 服务发现,负载均衡,路由,灰度,安全,认证,加密,限流,熔断……几乎大部分的主要功能,在这两个方向上都高度重叠。


因此,是否该考虑提供一个统一的解决方案来处理?



9. 多集群/多机房的支持


如果有多集群/多机房的支持需求,该如何解决?

这个问题和前面列出的 service mesh 体系和非 service mesh 的并存问题,可能叠加:如何在多集群/多机房要求下实现 service mesh 体系和非 service mesh 的并存。


TBD:更多想法将稍后逐步列出,也欢迎在微信群中补充。



Dream Mesh

在经过一个月的冥思苦想和深度思考之后,我对上面列出的问题大致有了一些初步的想法和思路。


我个人心中理想的 Service Mesh 解决方案,希望是可以在 Istio 或者 Conduit 的基础上,进一步的扩展和完善,解决或者规避上述问题。


终极目标:让 Service Mesh 能够更加平稳的在普通企业落地。


这个美好的愿景,目前还只停留在我的脑海中,如梦境一般虚幻,又如梦境一般令人向往。

所以我将这个思路和解决方案,统称为”Dream Mesh“。

坦言说:Dream Mesh想法比较超前,规划也有点庞大,兼具高层架构和底层实现,极富挑战。

再一次用这张图片为自己打气,同时感谢太平洋对岸的埃隆·马斯克在这个关键的时间点上给了我更多的勇气。

诚邀在将 Dream Mesh 的规划和架构正式呈现出来之前,我会陆续将我目前的所思所想以文字的形式发表在我的博客上,然后会发起几轮内部讨论。之后修订/补充/完善,希望在四五月份的时候能给出一个成型的方案。

我真诚的邀请对此感兴趣的朋友参与讨论和交流,我会在近期陆续将我的想法和设想抛出来,希望能引出大家的更多更好的思路,正所谓:抛砖引玉。

没有什么事情是可以一个人闭门造车而独自琢磨出来的。

有兴趣参与讨论的同学,请直接在微信上联系小数:xiaoshu062,加入Service Mesh 交流群讨论。

十分期待。



社区活动:

3月31日(周六),数人云联合ServiceComb社区,并由ServiceMesh社区支持,开启meetup系列活动 Building Microservice 第2期 北京站 :微服务,从架构到发布,已经开始报名啦,点击链接报名啦
  查看全部

1.jpg

 作者:
       敖小剑,资深码农,十六年软件开发经验,微服务专家,Service Mesh布道师。专注于基础架构,Cloud Native 拥护者,敏捷实践者,坚守开发一线打磨匠艺的架构师。机缘巧合下对基础架构和微服务有过深入研究和实践。博客链接:https://skyao.io



小数话:今天为大家整理了小剑老师的 Dream Mesh 系列文章,在之后的时间里,我们会依次为大家发送,对于该系列有兴趣的朋友,欢迎加入 service mesh 交流群(添加小数微信:xiaoshu062,备注:服务网格,即可),和小剑老师一起讨论关于 Dream Mesh 的相关内容~



前言

相信能看到这篇博客的同学,大体都知道过去几个月间,我在努力地研究 Service Mesh 并致力于在国内拓荒和布道。

坦言说:Service Mesh 的发展进程,当前还处于前景虽然一致看好,但是脚下的路还处于需要一步一步走的早期艰难阶段。由于 Istio 和 Conduit 的尚未成熟,造成目前 Service Mesh 青黄不接的尴尬局面。

近期在和很多朋友交流,也都谈到这个话题,着实有些无奈,只能静静的等待 Istio 和 Cconduit 的发展。好在这两个产品也很争气,近期都快速发出了新版本。


小编注:目前 Istio 是0.6版本(中文技术文档http://istio.doczh.cn/), Conduit 是 0.3.1版本(中文技术文档http://conduit.doczh.cn/


然而 Service Mesh 的现状,它的不够成熟,终究还是引发了猜疑,不安和观望。


1.jpg


Doubt kills more dreams than failure ever has.

在猎鹰升空,马斯克“封神”的那周,我更能深刻体会这句话的内涵。



正视问题

过去的一个月间,我一直在认真的思考这样一个问题:

Service Mesh 真的能完美解决问题吗?

这里我们抛开前面所说的 Istio 或者 Conduit 暂未成熟的情况,毕竟在不远的未来即将可以被解决,不出意外会在2018年年中或者年底。


让我们设想:如果明天 Istio 或者 Conduit 发布出 Production Ready 的版本,是不是我们就可以欢欣鼓舞的直接将系统搬迁到 Service Mesh 上?


还差点什么?


我将会在稍后的系列文章中将我思考的问题逐个列出来,暂时会有下列内容:


1. Ready for Cloud Native?

我对 Service Mesh 的第一个担忧,来自 Cloud Native。

作为 Cloud Native 的忠实拥护者,我不怀疑 Cloud Native 的价值和前景。但是,我担心的是:准备上 Service Mesh 的各位,是否都已经做到了Ready for Cloud Native?


2. 如何从非 Service Mesh 体系过渡到 Service Mesh?

即使一切都 Ready,对于一个有存量应用的系统而言,绝无可能在一夜之间就将所有应用都改为 Service Mesh,然后一起上线。


必然会有一个中间过渡状态,一部分应用开始搬迁到 Service Mesh,大部分还停留在原有体系。那么,如何在过渡阶段让 Service Mesh 内的服务和Service Mesh 外的服务相互通讯?


3. 零侵入的代价

Service Mesh的一个突出优点就是对应用的侵入度非常低,低到可以”零侵入”。

然而,没有任何事情是可以十全十美的,零侵入带来的弊端:iptables 一刀切的方案有滥用嫌疑,为了不劫持某些网络访问又不得不增加配置去绕开。

是否考虑补充一个低侵入的方案?



4. 网络通讯方案

Service Mesh 解决服务间通讯的方式是基于网络层,HTTP1.1/HTTP2 和可能的 TCP,对于选择什么样的序列化方案和远程访问方案并未限制。

好处是我们可以自由的选择各种方案,坏处就是自由意味着自己做。

能否以类库或者最佳实践的方式给出适合 Service Mesh 时代的网络通讯方案?



5. 性能开销

我们反复谈到,Service Mesh 的核心在于将原有以类库方式提供的功能拆分到独立的 sidecar 进程中,以远程调用的方式来强行解耦服务间通讯的业务语义和服务间通讯的具体实现。这带来了诸多的好处,但是这对性能会有什么影响?


6. 绕不开的Spring

对于 Java 企业应用,Spring 是无论如何绕不开的。然而目前我们没有看到Spring社区对 Service Mesh 的任何回应。因此,如何以正确的姿势在 Service Mesh 时代使用 Spring,需要自己探索。

理论上说,springboot on service mesh 有可能成为一个清爽的解决方案。然后路终究是要走一遍才知道是不是那么美好。



7. Spring Cloud 迁移之路

虽然 Service Mesh 号称下一代微服务,取代 Spring Cloud 是 Service Mesh 与生俱来的天然目标之一。

但是以目前市场形式,Spring Cloud 在未来很长一段时间之内都会是市场主流和很多公司的第一选择。如何在迁移到 Service Mesh 之前加强 Spring Cloud,并为将来转入 Service Mesh 铺路,是一个艰难而极具价值的话题。



8. API gateway

Service Mesh 解决的是东西向服务间通讯的问题,我们来审视一下 API gateway 到微服务之间的南北向通讯: 服务发现,负载均衡,路由,灰度,安全,认证,加密,限流,熔断……几乎大部分的主要功能,在这两个方向上都高度重叠。


因此,是否该考虑提供一个统一的解决方案来处理?



9. 多集群/多机房的支持


如果有多集群/多机房的支持需求,该如何解决?

这个问题和前面列出的 service mesh 体系和非 service mesh 的并存问题,可能叠加:如何在多集群/多机房要求下实现 service mesh 体系和非 service mesh 的并存。


TBD:更多想法将稍后逐步列出,也欢迎在微信群中补充。



Dream Mesh

在经过一个月的冥思苦想和深度思考之后,我对上面列出的问题大致有了一些初步的想法和思路。


我个人心中理想的 Service Mesh 解决方案,希望是可以在 Istio 或者 Conduit 的基础上,进一步的扩展和完善,解决或者规避上述问题。


终极目标:让 Service Mesh 能够更加平稳的在普通企业落地。


这个美好的愿景,目前还只停留在我的脑海中,如梦境一般虚幻,又如梦境一般令人向往。

所以我将这个思路和解决方案,统称为”Dream Mesh“。

坦言说:Dream Mesh想法比较超前,规划也有点庞大,兼具高层架构和底层实现,极富挑战。

再一次用这张图片为自己打气,同时感谢太平洋对岸的埃隆·马斯克在这个关键的时间点上给了我更多的勇气。

诚邀在将 Dream Mesh 的规划和架构正式呈现出来之前,我会陆续将我目前的所思所想以文字的形式发表在我的博客上,然后会发起几轮内部讨论。之后修订/补充/完善,希望在四五月份的时候能给出一个成型的方案。

我真诚的邀请对此感兴趣的朋友参与讨论和交流,我会在近期陆续将我的想法和设想抛出来,希望能引出大家的更多更好的思路,正所谓:抛砖引玉。

没有什么事情是可以一个人闭门造车而独自琢磨出来的。

有兴趣参与讨论的同学,请直接在微信上联系小数:xiaoshu062,加入Service Mesh 交流群讨论。

十分期待。



社区活动:

3月31日(周六),数人云联合ServiceComb社区,并由ServiceMesh社区支持,开启meetup系列活动 Building Microservice 第2期 北京站 :微服务,从架构到发布,已经开始报名啦,点击链接报名啦
 

重磅 | 微软Service Fabric正式开源,入局第三代微服务框架争霸!

小数 发表了文章 • 0 个评论 • 807 次浏览 • 2018-03-16 10:03 • 来自相关话题

小数话:

今天一早 Service Mesh 微信交流群里传来了微软 Service Fabric 项目正式开源的消息,引起了大家广泛关注和讨论。小数为大家整理了目前有关 Service Fabric 开源的一些内容和原博客翻译,其中以下导读部分及结论部分感谢@张善友先生的贡献,该部分转自其知乎账号https://zhuanlan.zhihu.com/p/34574512 

 
导读 
 
微软的 Azure Service Fabric 的官方博客在2017.3.14日发布了一篇博客《Service Fabric .NET SDK goes open source 》,详见下面原文翻译。介绍了社区呼声最高的 Service Fabric 的开源情况以及当前的情况,当时开源了 Service Fabric 的 .NET SDK 部分,社区一直在期盼着 Service Fabric 的正式开源,经过了一年漫长的等待,2018年3月14日微软终于开源了 Service Fabric,而且是以 MIT 许可下开放源代码。
 
目前微软在 Github 上的开源地址是 https://github.com/Microsoft/service-fabric ,目前的代码构建适用于 Linux 的 Service Fabric,运行基本测试,有问题可以在上面提交 Issue和 PR 了,Windows 构建环境以及完整的 CI 环境还没有迁移过来,看到代码还是3个小时前初始化的。Windows内部为 Service Fabric 开发了将近十年的内部服务,其中大部分时间都是微软内部平台,比如 Office365,Azure Stack 平台等,这意味着我们有近十年的内部微软工具可以在迁移之前完成迁移和流程细化,逐步全部开源,以后全部开发都在开源模式下进行开发工作。

 
 原文翻译 
 
我们很高兴地宣布 Service Fabric 将在 MIT 许可下开放源代码,在未来几个月内,我们将在GitHub上过渡到一个完全开放的开发过程。
 
我们听到了很多关于能够参与到你所依赖的平台的开发和方向上,以运行你的关键任务应用程序的重要性。由于这个原因,我们在 GitHub 和 Stack Overflow 上保持活跃,开放源码平台使这种协作更好的自然演进。这就是为什么我们致力于将我们的整个开发和规划过程转移到 GitHub上,从而使Service Fabric成为一个成功的开源项目。在GitHub上,我们可以与社区与社区开放式协作,使Service Fabric更好地为每个人服务。
 
 
 
Where we are now
 
至此,我们已经在 GitHub 上使用了 Linux 构建和测试工具,这意味着你可以克隆repo,为 Linux 构建 Service Fabric,运行基本测试,打开问题,并提交pull请求。我们正在努力使 Windows 构建环境也迁移到一个完整的 CI 环境中。
 
这里有一点历史。我们在 Windows 内部为 Service Fabric 开发了将近十年的时间,其中大部分时间都是微软内部平台,这意味着我们有近十年的内部微软工具来迁移和处理, 可以把一些东西用在 GitHub 上。 当我们几年前开始研究 Linux 支持时,我们是一个公共产品,并且已经计划开源,所以我们尽可能使用通用的公共可用工具。
 
现在,您可以为Linux编译和测试 Service Fabric,从底层的集群和联合层一直到流程和容器的激活。我们也在为贡献而开放,尽管我们的步伐有限,我们也为开放捐款开放,尽管我们将所有事情都公开化,但速度有限。
 
 
 
How we got here
 
去年的这个时候,我们开放了 Service Fabric 的源代码部分,包括 Reliable Services,Reliable Actors 和我们的 ASP.NET Core 集成库。 从那时起,我们已经慢慢地将 Service Fabric 的其他小部分移动到了 GitHub,包括 Service Fabric Explorer 和 SF CLI。 在那段时间里,我们花了很多时间来制定一个将所有 Service Fabric 转换为开源代码的计划。
 
我们在这个项目上投入了大量资金,我们希望它能增长。许多微软都在使用服务架构,包括Azure基础设施服务和大型解决方案,如 Azure SQL DB、Azure Cosmos DB 和 Cortana。这是我们大规模分布式应用程序的秘诀。只是这个秘诀不再是我们的了。自从我们在2015年公开发布了服务架构以来,微软以外的许多其他公司也开始依赖于 Service Fabric,以满足其关键的、大规模的应用程序。
 
 
 
What's next and how you can join in on the fun
 
对于 Service Fabric 和团队来说,这是我们向开放式开发过渡的一大步。 我们现在主要关注的是将 Service Fabric 的整个构建,测试和开发流程移至 GitHub。 虽然我们正在致力于此,但创新并不止于此,我们将继续定期发布新功能,我们将继续定期发布新特性、bug修复和支持。
 
 
我们的下一个主要步骤有两方面:
转向开放发展。 我们将把问题跟踪和我们自己的开发转移到 GitHub上。 我们的目标是使工作重点明确,并将工作与明确的项目路线图相结合,并制定明确的治理和贡献指导。 我们立即欢迎捐助,但我们还没有达到全速,所以请耐心等待我们改进过程和指导方针。
 
针对 Windows 和 Linux 的完整构建,测试和 CI 管道。 如果没有这个,我们就不能做很多事情,所以我们专注于把所有的事情都安排好。 如果你有兴趣帮助我们设置(或者你只是喜欢构建和测试自动化),请转到 Microsoft / service-fabric 回购站,我们正在跟踪该设备的工作。
 
当我们朝着这些更大的里程碑前进时,我们将不断地改进 repo。我们会定期在博客和 Service Fabric 回购库中更新进度,因此请务必马上查看,我们将在 GitHub 上看到你!
 
 
 
常见问题
 
1.Service Fabric 的哪些部分正在开源?
整个 Service Fabric 运行时都在 GitHub 上开源 ——构建和运行 Service Fabric 所需的一切。最初,我们将有一个适用于 Linux 的构建环境,并且很快就会有 Windows。
 
 
2.我可以构建并运行所有 Service Fabric 吗?
您现在可以为Linux构建和运行 Service Fabric。Windows 工具的完整构建和测试环境尚不可用,但我们正在努力将所有内容都发布到 GitHub 上。请注意 repo 的更新。
 
 
3.Azure Service Fabric和其它独立产品将会发生什么?他们还会得到微软的支持吗?
绝对的。我们将继续为微软提供的所有服务产品提供同样的支持,包括 Azure 的 Service Fabric 和其它所有独立的产品。
 
 
4.我有个一直想要构建的新功能。既然你们已经开源,那我现在可以开始与团队一起工作吗?
当然,我们很乐意与你合作。你可以先在 GitHub 上打开一个话题,然后我们就从那里开始。请注意,我们仍在过渡,目前的开源项目的重点是要建立项目环境,所以请耐心等待,因为我们还没有达到全速。
 
 
5.这仍然是微软拥有的,还是会捐赠给 CNCF 或 .NET 基金会?
微软拥有该项目,Service Fabric 团队将是决定项目方向的管理机构。作为理事机构,我们有责任遵循社区的指导。也就是说,我们不排除将来捐赠给基金会的可能性。

 
 结论 
 
Service Fabric 会带来如下好处:
支持创建无状态和有状态的微服务,通过云平台来伸缩他们,以应对高复杂度、低延迟、数据密集的情况;通过应用程序级别的感知和洞察,为微服务带来编排和自动化的优势;解决分布式系统诸如状态管理这样的难点,为开发人员提供应用程序生命周期管理的能力以便随着业务的增长无需重构系统架构;相关工具会集成到 Visual Studio 中,也会提供相应命令行工具,以便开发人员能够快速和轻易地上手;同时支持 .NET和 Java,这个特性特别适合目前国内原来很多投资于 .NET 平台,被人忽悠爬上了 Java  “贼船”,看到了 .NET Core,想回来的可以回来了。
 
开源微服务框架从 第一代 Dubbo 到 第二代 Spring Cloud 到 第三代 基于ServiceMesh 的 Service Fabric、Istio、Conduit三国争霸。
 
 
 
图片来自网友贡献
data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==
 

 

 

 

 

 
 
 
 推荐阅读
 
使用Istio简化微服务系列二:如何通过HTTPS与外部服务进行通信?
使用Istio简化微服务系列一:如何用Isito解决Spring Cloud Netflix部署微服务
采用Istio实现灰度发布,给运维人员一支强心剂

 

 
ServiceMesh微信交流群:
添加微信xiaoshu062,备注:服务网格,即可加入Service Mesh微信交流群。
 
社区活动:
3月31日(周六),数人云联合ServiceComb社区,并由ServiceMesh社区支持,开启meetup系列活动 Building Microservice 第2期 北京站 :微服务,从架构到发布,已经开始报名啦,点击链接报名啦 查看全部
小数话:

今天一早 Service Mesh 微信交流群里传来了微软 Service Fabric 项目正式开源的消息,引起了大家广泛关注和讨论。小数为大家整理了目前有关 Service Fabric 开源的一些内容和原博客翻译,其中以下导读部分及结论部分感谢@张善友先生的贡献,该部分转自其知乎账号https://zhuanlan.zhihu.com/p/34574512 

 
导读 
 
微软的 Azure Service Fabric 的官方博客在2017.3.14日发布了一篇博客《Service Fabric .NET SDK goes open source 》详见下面原文翻译。介绍了社区呼声最高的 Service Fabric 的开源情况以及当前的情况,当时开源了 Service Fabric 的 .NET SDK 部分,社区一直在期盼着 Service Fabric 的正式开源,经过了一年漫长的等待,2018年3月14日微软终于开源了 Service Fabric,而且是以 MIT 许可下开放源代码。
 
目前微软在 Github 上的开源地址是 https://github.com/Microsoft/service-fabric ,目前的代码构建适用于 Linux 的 Service Fabric,运行基本测试,有问题可以在上面提交 Issue和 PR 了,Windows 构建环境以及完整的 CI 环境还没有迁移过来,看到代码还是3个小时前初始化的。Windows内部为 Service Fabric 开发了将近十年的内部服务,其中大部分时间都是微软内部平台,比如 Office365,Azure Stack 平台等,这意味着我们有近十年的内部微软工具可以在迁移之前完成迁移和流程细化,逐步全部开源,以后全部开发都在开源模式下进行开发工作。

 
 原文翻译 
 
我们很高兴地宣布 Service Fabric 将在 MIT 许可下开放源代码,在未来几个月内,我们将在GitHub上过渡到一个完全开放的开发过程。
 
我们听到了很多关于能够参与到你所依赖的平台的开发和方向上,以运行你的关键任务应用程序的重要性。由于这个原因,我们在 GitHub 和 Stack Overflow 上保持活跃,开放源码平台使这种协作更好的自然演进。这就是为什么我们致力于将我们的整个开发和规划过程转移到 GitHub上,从而使Service Fabric成为一个成功的开源项目。在GitHub上,我们可以与社区与社区开放式协作,使Service Fabric更好地为每个人服务。
 
 
 
Where we are now
 
至此,我们已经在 GitHub 上使用了 Linux 构建和测试工具,这意味着你可以克隆repo,为 Linux 构建 Service Fabric,运行基本测试,打开问题,并提交pull请求。我们正在努力使 Windows 构建环境也迁移到一个完整的 CI 环境中。
 
这里有一点历史。我们在 Windows 内部为 Service Fabric 开发了将近十年的时间,其中大部分时间都是微软内部平台,这意味着我们有近十年的内部微软工具来迁移和处理, 可以把一些东西用在 GitHub 上。 当我们几年前开始研究 Linux 支持时,我们是一个公共产品,并且已经计划开源,所以我们尽可能使用通用的公共可用工具。
 
现在,您可以为Linux编译和测试 Service Fabric,从底层的集群和联合层一直到流程和容器的激活。我们也在为贡献而开放,尽管我们的步伐有限,我们也为开放捐款开放,尽管我们将所有事情都公开化,但速度有限。
 
 
 
How we got here
 
去年的这个时候,我们开放了 Service Fabric 的源代码部分,包括 Reliable Services,Reliable Actors 和我们的 ASP.NET Core 集成库。 从那时起,我们已经慢慢地将 Service Fabric 的其他小部分移动到了 GitHub,包括 Service Fabric Explorer 和 SF CLI。 在那段时间里,我们花了很多时间来制定一个将所有 Service Fabric 转换为开源代码的计划。
 
我们在这个项目上投入了大量资金,我们希望它能增长。许多微软都在使用服务架构,包括Azure基础设施服务和大型解决方案,如 Azure SQL DB、Azure Cosmos DB 和 Cortana。这是我们大规模分布式应用程序的秘诀。只是这个秘诀不再是我们的了。自从我们在2015年公开发布了服务架构以来,微软以外的许多其他公司也开始依赖于 Service Fabric,以满足其关键的、大规模的应用程序。
 
 
 
What's next and how you can join in on the fun
 
对于 Service Fabric 和团队来说,这是我们向开放式开发过渡的一大步。 我们现在主要关注的是将 Service Fabric 的整个构建,测试和开发流程移至 GitHub。 虽然我们正在致力于此,但创新并不止于此,我们将继续定期发布新功能,我们将继续定期发布新特性、bug修复和支持。
 
 
我们的下一个主要步骤有两方面:
  • 转向开放发展。 我们将把问题跟踪和我们自己的开发转移到 GitHub上。 我们的目标是使工作重点明确,并将工作与明确的项目路线图相结合,并制定明确的治理和贡献指导。 我们立即欢迎捐助,但我们还没有达到全速,所以请耐心等待我们改进过程和指导方针。

 
  • 针对 Windows 和 Linux 的完整构建,测试和 CI 管道。 如果没有这个,我们就不能做很多事情,所以我们专注于把所有的事情都安排好。 如果你有兴趣帮助我们设置(或者你只是喜欢构建和测试自动化),请转到 Microsoft / service-fabric 回购站,我们正在跟踪该设备的工作。

 
当我们朝着这些更大的里程碑前进时,我们将不断地改进 repo。我们会定期在博客和 Service Fabric 回购库中更新进度,因此请务必马上查看,我们将在 GitHub 上看到你!
 
 
 
常见问题
 
1.Service Fabric 的哪些部分正在开源?
整个 Service Fabric 运行时都在 GitHub 上开源 ——构建和运行 Service Fabric 所需的一切。最初,我们将有一个适用于 Linux 的构建环境,并且很快就会有 Windows。
 
 
2.我可以构建并运行所有 Service Fabric 吗?
您现在可以为Linux构建和运行 Service Fabric。Windows 工具的完整构建和测试环境尚不可用,但我们正在努力将所有内容都发布到 GitHub 上。请注意 repo 的更新。
 
 
3.Azure Service Fabric和其它独立产品将会发生什么?他们还会得到微软的支持吗?
绝对的。我们将继续为微软提供的所有服务产品提供同样的支持,包括 Azure 的 Service Fabric 和其它所有独立的产品。
 
 
4.我有个一直想要构建的新功能。既然你们已经开源,那我现在可以开始与团队一起工作吗?
当然,我们很乐意与你合作。你可以先在 GitHub 上打开一个话题,然后我们就从那里开始。请注意,我们仍在过渡,目前的开源项目的重点是要建立项目环境,所以请耐心等待,因为我们还没有达到全速。
 
 
5.这仍然是微软拥有的,还是会捐赠给 CNCF 或 .NET 基金会?
微软拥有该项目,Service Fabric 团队将是决定项目方向的管理机构。作为理事机构,我们有责任遵循社区的指导。也就是说,我们不排除将来捐赠给基金会的可能性。

 
 结论 
 
Service Fabric 会带来如下好处:
  • 支持创建无状态和有状态的微服务,通过云平台来伸缩他们,以应对高复杂度、低延迟、数据密集的情况;
  • 通过应用程序级别的感知和洞察,为微服务带来编排和自动化的优势;
  • 解决分布式系统诸如状态管理这样的难点,为开发人员提供应用程序生命周期管理的能力以便随着业务的增长无需重构系统架构;
  • 相关工具会集成到 Visual Studio 中,也会提供相应命令行工具,以便开发人员能够快速和轻易地上手;
  • 同时支持 .NET和 Java,这个特性特别适合目前国内原来很多投资于 .NET 平台,被人忽悠爬上了 Java  “贼船”,看到了 .NET Core,想回来的可以回来了。

 
开源微服务框架从 第一代 Dubbo 到 第二代 Spring Cloud 到 第三代 基于ServiceMesh 的 Service Fabric、Istio、Conduit三国争霸。
 
 
 
图片来自网友贡献
data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==
 

 

 

 

 

 
 
 
 推荐阅读
 
使用Istio简化微服务系列二:如何通过HTTPS与外部服务进行通信?
使用Istio简化微服务系列一:如何用Isito解决Spring Cloud Netflix部署微服务
采用Istio实现灰度发布,给运维人员一支强心剂

 

 
ServiceMesh微信交流群:
添加微信xiaoshu062,备注:服务网格,即可加入Service Mesh微信交流群。
 
社区活动:
3月31日(周六),数人云联合ServiceComb社区,并由ServiceMesh社区支持,开启meetup系列活动 Building Microservice 第2期 北京站 :微服务,从架构到发布,已经开始报名啦,点击链接报名啦

构建分布式微服务系统,如何基于代理的服务网格做“减法”?

小数 发表了文章 • 0 个评论 • 484 次浏览 • 2018-03-08 10:09 • 来自相关话题

 
 
 作者:Emil Kirschner

翻译:张晔

原文:Proxy Based Service Mesh

地址:https://medium.com/%40entzik/p ... 4c198




基于代理的服务网格是一种新兴技术,通过使用专用代理在容器编排级别提供横切式的基础设施功能,如服务发现、负载平衡、断路器、度量监控、分布式跟踪等,从而简化分布式微服务系统的构建。 通过消除服务中的样板代码,可自由地使用任何技术和任何编程语言。

如果想建立一个分布式的微服务系统,通常必须寻找一组提供服务发现、负载平衡和断路器的组件或框架,然后必须专门制定服务来适配这些组件或框架。 通常这些组件或框架或多或少与特定语言或框架相关联。

例如 Netflix OSS 与 Spring Cloud Netflix 一起使用则非常容易。 只需在 Spring Boot 应用中添加一些注解,即可启动 Zuul 代理和 Eureka 服务器。 通过添加另一组不同的注解,则可以将微服务标记为 Eureka 客户端,且在注册后即可使用。 如果您需要调用下游服务则使用 Feign。 并且可以使用 Hystrix 来保护下游调用。

然而,只要离开了 Java / Spring Boot 领域,事情就会变得复杂起来。

如果需要使用 C ++ 或 Go 来编写服务,则需要自行构建与 Netflix OS S的集成。 这会产生更多的样板代码,每次使用一种新的语言到技术栈时都必须这样做一遍。


服务网格

容器和容器编排技术的兴起使得新的基础架构成为了可能,使我们能够摆脱服务发现/负载平衡/断路器框架的束缚。 这个新的基础设施就是“服务网格” —— 当说它新的时候,我的意思是在撰写本文时(2017年11月),它甚至还没有维基百科页面。

那服务网格是什么呢? 服务网格是一个基础架构层 ,主要是一个代理集合,每个逻辑服务都有一个代理 , 与 Docker Swarm 或 Kubernetes 等容器编排解决方案集成,并提供服务发现,负载平衡,断路器,故障注入,安全,监控,跟踪以及更多以非侵入性的方式提供的开箱即用功能。

由于服务网格在容器级别运行,它并不关心使用什么技术或编程语言来编写微服务。 你可以将微服务使用 Java,C ++,Rust,Go,NodeJS 来编写简单 HTTP 服务器,这些都已不再重要。

可以将服务网格有效地视为分布式容器化应用基础架构级的面向切面编程。 服务网格中的代理就像 AOP 中的一个切面。 它们包裹了一个容器化的微服务,就像 AspectJ 切面可以包裹和测试 Java 方法一样,通过分离横切关注点来简化系统。



乾坤内境

以非侵入方式免费获得所有这些是很酷的,但它是如何工作的? 让我们逐一展开:


服务发现和负载均衡

服务网格将 hook 到编排层 ,Docker Swarm 或 Kubernetes,并在每次启动和停止容器时收到通知。

当启动第一个带有 “service1” 实例的容器时,服务网格将创建一个代理并应用 iptables 配置,该配置将捕获所有到 “service1” 的流量并对其进行管理。 随着更多的 “service1” 实例出现,服务网格将被通知,并将新实例添加到代理的配置中。

当流量流入时,代理将提供:
通过配置软件定义网络来解析主机名 “service1” 到自身的服务发现;通过将传入请求平均分配给可用服务实例来实现负载平衡;


这两个功能有效地取代了 Netflix OSS 技术栈中的 Eureka 和 Ribbon。


断路器

断路器是一种快速失败机制。 如果底层服务实例变慢并且在配置的时间内没有对调用响应,则断路器将使请求失败,并向客户端返回适当的错误码。 客户端然后可以重试并最终到达更具响应力的实例。 这提供了更好的用户体验。

通常情况下,响应慢的实例将被标记为非活动状态,并在接收任何流量之前一段时间后才能恢复。

同样在服务网格中,位于服务的所有实例前的代理充当了断路器。 这有效地取代了 Netflix OSS 技术栈中的 Hystrix 断路器。


故障注入

分布式云原生应用必须设计为容错的。 应用在云中运行的硬件可能随时出现故障,可以取出机器进行定期维护,任何服务的任何实例可能随时无响应。 当这样的事件下游服务的实例故障时,应用必须优雅地处理这种情况,且不降低用户体验,或者最低限度地降低。

但由于这种情况在云环境中随机发生,因此很难在受控环境中再现并研究其对系统的影响。 这将是一件非常有用的事情。

为了解决这个问题,Netflix 的优秀人士提出了 “Chaos Monkey” 和整套相关工具,但这些工具不易部署和运维。

通过服务网格,通过代理配置可以实现相同的功能。 可以为每种服务引入两种随机扰动:

延迟一定比例的请求以观察在分布式系统上增加服务延迟的影响,确保系统作为一个整体能够处理它。

传入请求按百分比失败与随机错误代码,并确保系统可以存活。

在典型工作负载期间将这些扰动转移到不同程度时测量系统吞吐量和终端用户感知延迟,以确定哪些下游服务非常关键,哪些不是。


限速,配额,监控和追踪

服务网格代理处理所有到达服务的流量,它知道什么是正确的,哪里出了问题,它可以强制使用策略,如配额和限速。

代理能注意到每个失败和 SLA 违规。 这使它成为监控服务性能的理想场所。

因为从前端微服务到最后一个下游服务的每个调用都通过代理,所以这也是实现跟踪的理想场所。

一个好的服务网格可以自动安装诸如 Prometheus 和 Zipkin 等监控和跟踪基础设施部分,以及 Grafana 等可视化工具。



当前服务网格现状

当今在服务网格领域有两个玩家:Linkerd 和 Istio。

Linkerd 首当其冲,它是一个更成熟,经过生产验证的解决方案。 它最为人民所知的是被一家全新的在线英国银行 Monzo 用于生产环境中。

另一选择 Istio,则是新兴的挑战者。 它尚未达到生产质量,但速度非常快,并从一开始就得到 Google 云平台的支持。 它建立在 Lyft 开发的 Envoy 代理之上。

ServiceMesh微信交流群:

添加微信xiaoshu062,备注:服务网格,即可加入Service Mesh微信交流群。 查看全部

timg111.jpg

 
 
 作者:Emil Kirschner

翻译:张晔

原文:Proxy Based Service Mesh

地址:https://medium.com/%40entzik/p ... 4c198




基于代理的服务网格是一种新兴技术,通过使用专用代理在容器编排级别提供横切式的基础设施功能,如服务发现、负载平衡、断路器、度量监控、分布式跟踪等,从而简化分布式微服务系统的构建。 通过消除服务中的样板代码,可自由地使用任何技术和任何编程语言。

如果想建立一个分布式的微服务系统,通常必须寻找一组提供服务发现、负载平衡和断路器的组件或框架,然后必须专门制定服务来适配这些组件或框架。 通常这些组件或框架或多或少与特定语言或框架相关联。

例如 Netflix OSS 与 Spring Cloud Netflix 一起使用则非常容易。 只需在 Spring Boot 应用中添加一些注解,即可启动 Zuul 代理和 Eureka 服务器。 通过添加另一组不同的注解,则可以将微服务标记为 Eureka 客户端,且在注册后即可使用。 如果您需要调用下游服务则使用 Feign。 并且可以使用 Hystrix 来保护下游调用。

然而,只要离开了 Java / Spring Boot 领域,事情就会变得复杂起来。

如果需要使用 C ++ 或 Go 来编写服务,则需要自行构建与 Netflix OS S的集成。 这会产生更多的样板代码,每次使用一种新的语言到技术栈时都必须这样做一遍。


服务网格

容器和容器编排技术的兴起使得新的基础架构成为了可能,使我们能够摆脱服务发现/负载平衡/断路器框架的束缚。 这个新的基础设施就是“服务网格” —— 当说它新的时候,我的意思是在撰写本文时(2017年11月),它甚至还没有维基百科页面。

那服务网格是什么呢? 服务网格是一个基础架构层 ,主要是一个代理集合,每个逻辑服务都有一个代理 , 与 Docker Swarm 或 Kubernetes 等容器编排解决方案集成,并提供服务发现,负载平衡,断路器,故障注入,安全,监控,跟踪以及更多以非侵入性的方式提供的开箱即用功能。

由于服务网格在容器级别运行,它并不关心使用什么技术或编程语言来编写微服务。 你可以将微服务使用 Java,C ++,Rust,Go,NodeJS 来编写简单 HTTP 服务器,这些都已不再重要。

可以将服务网格有效地视为分布式容器化应用基础架构级的面向切面编程。 服务网格中的代理就像 AOP 中的一个切面。 它们包裹了一个容器化的微服务,就像 AspectJ 切面可以包裹和测试 Java 方法一样,通过分离横切关注点来简化系统。



乾坤内境

以非侵入方式免费获得所有这些是很酷的,但它是如何工作的? 让我们逐一展开:


服务发现和负载均衡

服务网格将 hook 到编排层 ,Docker Swarm 或 Kubernetes,并在每次启动和停止容器时收到通知。

当启动第一个带有 “service1” 实例的容器时,服务网格将创建一个代理并应用 iptables 配置,该配置将捕获所有到 “service1” 的流量并对其进行管理。 随着更多的 “service1” 实例出现,服务网格将被通知,并将新实例添加到代理的配置中。

当流量流入时,代理将提供:
  • 通过配置软件定义网络来解析主机名 “service1” 到自身的服务发现;
  • 通过将传入请求平均分配给可用服务实例来实现负载平衡;



这两个功能有效地取代了 Netflix OSS 技术栈中的 Eureka 和 Ribbon。


断路器

断路器是一种快速失败机制。 如果底层服务实例变慢并且在配置的时间内没有对调用响应,则断路器将使请求失败,并向客户端返回适当的错误码。 客户端然后可以重试并最终到达更具响应力的实例。 这提供了更好的用户体验。

通常情况下,响应慢的实例将被标记为非活动状态,并在接收任何流量之前一段时间后才能恢复。

同样在服务网格中,位于服务的所有实例前的代理充当了断路器。 这有效地取代了 Netflix OSS 技术栈中的 Hystrix 断路器。


故障注入

分布式云原生应用必须设计为容错的。 应用在云中运行的硬件可能随时出现故障,可以取出机器进行定期维护,任何服务的任何实例可能随时无响应。 当这样的事件下游服务的实例故障时,应用必须优雅地处理这种情况,且不降低用户体验,或者最低限度地降低。

但由于这种情况在云环境中随机发生,因此很难在受控环境中再现并研究其对系统的影响。 这将是一件非常有用的事情。

为了解决这个问题,Netflix 的优秀人士提出了 “Chaos Monkey” 和整套相关工具,但这些工具不易部署和运维。

通过服务网格,通过代理配置可以实现相同的功能。 可以为每种服务引入两种随机扰动:

延迟一定比例的请求以观察在分布式系统上增加服务延迟的影响,确保系统作为一个整体能够处理它。

传入请求按百分比失败与随机错误代码,并确保系统可以存活。

在典型工作负载期间将这些扰动转移到不同程度时测量系统吞吐量和终端用户感知延迟,以确定哪些下游服务非常关键,哪些不是。


限速,配额,监控和追踪

服务网格代理处理所有到达服务的流量,它知道什么是正确的,哪里出了问题,它可以强制使用策略,如配额和限速。

代理能注意到每个失败和 SLA 违规。 这使它成为监控服务性能的理想场所。

因为从前端微服务到最后一个下游服务的每个调用都通过代理,所以这也是实现跟踪的理想场所。

一个好的服务网格可以自动安装诸如 Prometheus 和 Zipkin 等监控和跟踪基础设施部分,以及 Grafana 等可视化工具。



当前服务网格现状

当今在服务网格领域有两个玩家:Linkerd 和 Istio。

Linkerd 首当其冲,它是一个更成熟,经过生产验证的解决方案。 它最为人民所知的是被一家全新的在线英国银行 Monzo 用于生产环境中。

另一选择 Istio,则是新兴的挑战者。 它尚未达到生产质量,但速度非常快,并从一开始就得到 Google 云平台的支持。 它建立在 Lyft 开发的 Envoy 代理之上。

ServiceMesh微信交流群:

添加微信xiaoshu062,备注:服务网格,即可加入Service Mesh微信交流群。

万字长文 | 如何构建安全的微服务应用,先要解决这两个问题

小数 发表了文章 • 0 个评论 • 382 次浏览 • 2018-03-02 10:19 • 来自相关话题

   
作者简介:
      赵化冰是一名程序员及开源软件爱好者,目前在NFV&SDN编排开源社区ONAP担任MSB项目PTL,致力于高性能,高可用性微服务架构在编排领域的应用。
      博客链接:http://zhaohuabing.com/  
 
目录 
一、前言
二、单体应用的实现方式
三、微服务认证和鉴权面临的问题
四、微服务认证和鉴权的技术方案
1.用户身份认证
2.用户状态保持
3.实现单点登录
4.用户权限控制
API Gateway处进行统一的权限控制
由各个微服务单独进行权限控制
5.第三方应用接入
API Token
OAuth
6.微服务之间的认证​
五、参考
  
一、前言 
 
微服务架构的引入为软件应用带来了诸多好处:包括小开发团队,缩短开发周期,语言选择灵活性,增强服务伸缩能力等。与此同时,也引入了分布式系统的诸多复杂问题。其中一个挑战就是如何在微服务架构中实现一个灵活,安全,高效的认证和鉴权方案。本文将尝试就此问题进行一次比较完整的探讨。
 
 
 
二、单体应用的实现方式
 
在单体架构下,整个应用是一个进程,在应用中,一般会用一个安全模块来实现用户认证和鉴权。 用户登录时,应用的安全模块对用户身份进行验证,验证用户身份合法后,为该用户生成一个会话(Session),并为该Session关联一个唯一的编号(Session Id)。Session是应用中的一小块内存结构,其中保存了登录用户的信息,如User name, Role, Permission等。服务器把该Session的Session Id返回给客户端,客户端将Session Id以cookie或者URL重写的方式记录下来,并在后续请求中发送给应用,这样应用在接收到客户端访问请求时可以使用Session Id验证用户身份,不用每次请求时都输入用户名和密码进行身份验证。

备注:为了避免Session Id被第三者截取和盗用,客户端和应用之前应使用TLS加密通信,session也会设置有过期时间。

 





                          单体应用用户登录认证序列图
 
客户端访问应用时,Session Id随着HTTP请求发送到应用,客户端请求一般会通过一个拦截器处理所有收到的客户端请求。拦截器首先判断Session Id是否存在,如果该Session Id存在,就知道该用户已经登录。然后再通过查询用户权限判断用户能否执行该此请求,以实现操作鉴权。
 





data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==单体应用用户操作鉴权序列图    
 
 

三、微服务认证和鉴权面临的问题 
 
在微服务架构下,一个应用被拆分为多个微服务进程,每个微服务实现原来单体应用中一个模块的业务功能。应用拆分后,对每个微服务的访问请求都需要进行认证和鉴权。如果参考单体应用的实现方式会遇到下述问题:
认证和鉴权逻辑需要在每个微服务中进行处理,需要在各个微服务中重复实现这部分公共逻辑。虽然我们可以使用代码库复用部分代码,但这又会导致所有微服务对特定代码库及其版本存在依赖,影响微服务语言/框架选择的灵活性。微服务应遵循单一职责原理,一个微服务只处理单一的业务逻辑。认证和鉴权的公共逻辑不应该放到微服务实现中。为了充分利用微服务架构的好处,实现微服务的水平扩展(Scalability)和弹性(Resiliency),微服务最好是无状态的。因此不建议使用session这种有状态的方案。微服务架构下的认证和鉴权涉及到场景更为复杂,涉及到用户访问微服务应用,第三方应用访问微服务应用,应用内多个微服务之间相互访问等多种场景,每种场景下的认证和鉴权方案都需要考虑到,以保证应用程序的安全性。 data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==
 微服务认证和鉴权涉及到的三种场景  
  
四、微服务认证和鉴权的技术方案

  1.用户身份认证
 
一个完整的微服务应用是由多个相互独立的微服务进程组成的,对每个微服务的访问都需要进行用户认证。如果将用户认证的工作放到每个微服务中,应用的认证逻辑将会非常复杂。因此需要考虑一个SSO(单点登录)的方案,即用户只需要登录一次,就可以访问所有微服务提供的服务。 由于在微服务架构中以API Gateway作为对外提供服务的入口,因此可以考虑在API Gateway处提供统一的用户认证。
 
 2.用户状态保持
 
HTTP是一个无状态的协议,对服务器来说,用户的每次HTTP请求是相互独立的。互联网是一个巨大的分布式系统,HTTP协议作为互联网上的一个重要协议,要考虑到大量应用访问的效率问题。无状态意味着服务端可以把客户端的请求根据需要发送到集群中的任何一个节点,HTTP的无状态设计对负载均衡有明显的好处,由于没有状态,用户请求可以被分发到任意一个服务器,应用也可以在靠近用户的网络边缘部署缓存服务器。对于不需要身份认证的服务,例如浏览新闻网页等,这是没有任何问题的。但很多服务如网络购物,企业管理系统等都需要对用户的身份进行认证,因此需要在HTTP协议基础上采用一种方式保存用户的登录状态,避免用户每发起一次请求都需要进行验证。
 
传统方式是在服务器端采用Cookie来保存用户状态,由于在服务器是有状态的,对服务器的水平扩展有影响。在微服务架构下建议采用Token来记录用户登录状态。
 
Token和Seesion主要的不同点是存储的地方不同。Session是集中存储在服务器中的;而Token是用户自己持有的,一般以cookie的形式存储在浏览器中。Token中保存了用户的身份信息,每次请求都会发送给服务器,服务器因此可以判断访问者的身份,并判断其对请求的资源有没有访问权限。
 
Token用于表明用户身份,因此需要对其内容进行加密,避免被请求方或者第三者篡改。JWT(Json Web Token)是一个定义Token格式的开放标准(RFC 7519),定义了Token的内容,加密方式,并提供了各种语言的lib。
 
JWT Token的结构非常简单,包括三部分:
Header头部包含类型,为固定值JWT。然后是JWT使用的Hash算法。{"alg": "HS256","typ": "JWT"}Payload包含发布者,过期时间,用户名等标准信息,也可以添加用户角色,用户自定义的信息。{"sub": "1234567890","name": "John Doe","admin": true}SignatureToken颁发方的签名,用于客户端验证Token颁发方的身份,也用于服务器防止Token被篡改。 签名算法HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)
 
这三部分使用Base64编码后组合在一起,成为最终返回给客户端的Token串,每部分之间采用”.”分隔。下图是上面例子最终形成的Token
data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==
采用Token进行用户认证,服务器端不再保存用户状态,客户端每次请求时都需要将Token发送到服务器端进行身份验证。Token发送的方式rfc6750进行了规定,采用一个 Authorization: Bearer HHTP Header进行发送。Authorization: Bearer mF_9.B5f-4.1JqM
 
采用Token方式进行用户认证的基本流程如下图所示:
用户输入用户名,密码等验证信息,向服务器发起登录请求服务器端验证用户登录信息,生成JWT token服务器端将Token返回给客户端,客户端保存在本地(一般以Cookie的方式保存)客户端向服务器端发送访问请求,请求中携带之前颁发的Token服务器端验证Token,确认用户的身份和对资源的访问权限,并进行相应的处理(拒绝或者允许访问) data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==



采用Token进行用户认证的流程图 
 
3、实现单点登录
 
单点登录的理念很简单,即用户只需要登录应用一次,就可以访问应用中所有的微服务。API Gateway提供了客户端访问微服务应用的入口,Token实现了无状态的用户认证。结合这两种技术,可以为微服务应用实现一个单点登录方案。
 
用户的认证流程和采用Token方式认证的基本流程类似,不同之处是加入了API Gateway作为外部请求的入口。
 
用户登录
客户端发送登录请求到API GatewayAPI Gateway将登录请求转发到Security ServiceSecurity Service验证用户身份,并颁发Token
用户请求
客户端请求发送到API GatewayAPI Gateway调用的Security Service对请求中的Token进行验证,检查用户的身份如果请求中没有Token,Token过期或者Token验证非法,则拒绝用户请求。Security Service检查用户是否具有该操作权如果用户具有该操作权限,则把请求发送到后端的Business Service,否则拒绝用户请求 data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==



采用API Gateway和Token实现微服务应用的单点登录   
 
 
4、用户权限控制 
用户权限控制有两种做法,在API Gateway处统一处理,或者在各个微服务中单独处理。 
 
API Gateway处进行统一的权限控制
 
客户端发送的HTTP请求中包含有请求的Resource及HTTP Method。如果系统遵循REST规范,以URI资源方式对访问对象进行建模,则API Gateway可以从请求中直接截取到访问的资源及需要进行的操作,然后调用Security Service进行权限判断,根据判断结果决定用户是否有权限对该资源进行操作,并转发到后端的Business Service。这种实现方式API Gateway处统一处理鉴权逻辑,各个微服务不需要考虑用户鉴权,只需要处理业务逻辑,简化了各微服务的实现。
由各个微服务单独进行权限控制
 
如果微服务未严格遵循REST规范对访问对象进行建模,或者应用需要进行定制化的权限控制,则需要在微服务中单独对用户权限进行判断和处理。这种情况下微服务的权限控制更为灵活,但各个微服务需要单独维护用户的授权数据,实现更复杂一些。

 
 5、第三方应用接入
 
对于第三方应用接入的访问控制,有两种实现方式:
API Token
 
第三方使用一个应用颁发的API Token对应用的数据进行访问。该Token由用户在应用中生成,并提供给第三方应用使用。在这种情况下,一般只允许第三方应用访问该Token所属用户自身的数据,而不能访问其他用户的敏感私有数据。
 
例如Github就提供了Personal API Token功能,用户可以在Github的开发者设置界面中创建Token,然后使用该Token来访问Github的API。在创建Token时,可以设置该Token可以访问用户的哪些数据,如查看Repo信息,删除Repo,查看用户信息,更新用户信息等。
 
使用API Token来访问Github APIcurl -u zhaohuabing:fbdf8e8862252ed0f3ba9dba4e328c01ac93aeec https://api.github.com/user
 
使用API Token而不是直接使用用户名/密码来访问API的好处是降低了用户密码暴露的风险,并且可以随时收回Token的权限而不用修改密码。
 
由于API Token只能访问指定用户的数据,因此适合于用户自己开发一些脚本或小程序对应用中自己的数据进行操作。
 
OAuth
 
某些第三方应用需要访问不同用户的数据,或者对多个用户的数据进行整合处理,则可以考虑采用OAuth。采用OAuth,当第三方应用访问服务时,应用会提示用户授权第三方应用相应的访问权限,根据用户的授权操作结果生成用于访问的Token,以对第三方应用的操作请求进行访问控制。
 
同样以Github为例,一些第三方应用如Travis CI,GitBook等就是通过OAuth和Github进行集成的。 OAuth针对不同场景有不同的认证流程,一个典型的认证流程如下图所示:
用户向OAuth客户端程序发起一个请求,OAuth客户端程序在处理该请求时发现需要访问用户在资源服务器中的数据。客户端程序将用户请求重定向到认证服务器,该请求中包含一个callback的URL。认证服务器返回授权页面,要求用户对OAuth客户端的资源请求进行授权。用户对该操作进行授权后,认证服务器将请求重定向到客户端程序的callback url,将授权码返回给客户端程序。客户端程序将授权码发送给认证服务器,请求token。认证服务器验证授权码后将token颁发给客户端程序。客户端程序采用颁发的token访问资源,完成用户请求。

备注:
OAuth中按照功能区分了资源服务器和认证服务器这两个角色,在实现时这两个角色常常是同一个应用。将该流程图中的各个角色对应到Github的例子中,资源服务器和认证服务器都是Github,客户端程序是Travis CI或者GitBook,用户则是使用Travis CI或者GitBook的直接用户。有人可能会疑惑在该流程中为何要使用一个授权码(Authorization Code)来申请Token,而不是由认证服务器直接返回Token给客户端。OAuth这样设计的原因是在重定向到客户端Callback URL的过程中会经过用户代理(浏览器),如果直接传递Token存在被窃取的风险。采用授权码的方式,申请Token时客户端直接和认证服务器进行交互,并且认证服务期在处理客户端的Token申请请求时还会对客户端进行身份认证,避免其他人伪造客户端身份来使用认证码申请Token。 下面是一个客户端程序采用Authorization Code来申请Token的示例,client_id和client_secret被用来验证客户端的身份。
POST /oauth/token HTTP/1.1
Host: authorization-server.com

grant_type=authorization_code
&code=xxxxxxxxxxx
&redirect_uri=https://example-app.com/redirect
&client_id=xxxxxxxxxx
&client_secret=xxxxxxxxxx

 
OAuth认证流程
 
另外在谈及OAuth时,我们需要注意微服务应用作为OAuth客户端和OAuth服务器的两种不同场景:
 
在实现微服务自身的用户认证时,也可以采用OAuth将微服务的用户认证委托给一个第三方的认证服务提供商,例如很多应用都将用户登录和微信或者QQ的OAuth服务进行了集成。
 
第三方应用接入和微服务自身用户认证采用OAuth的目的是不同的,前者是为了将微服务中用户的私有数据访问权限授权给第三方应用,微服务在OAuth架构中是认证和资源服务器的角色;而后者的目的是集成并利用知名认证提供服务商提供的OAuth认证服务,简化繁琐的注册操作,微服务在OAuth架构中是客户端的角色。
 
因此在我们需要区分这两种不同的场景,以免造成误解。
 
 
6、微服务之间的认证
 
除了来自用户和第三方的北向流量外,微服务之间还有大量的东西向流量,这些流量可能在同一个局域网中,也可能跨越不同的数据中心,这些服务间的流量存在被第三方的嗅探和攻击的危险,因此也需要进行安全控制。
 
通过双向SSL可以实现服务之间的相互身份认证,并通过TLS加密服务间的数据传输。需要为每个服务生成一个证书,服务之间通过彼此的证书进行身份验证。在微服务运行环境中,可能存在大量的微服务实例,并且微服务实例经常会动态变化,例如随着水平扩展增加服务实例。在这种情况下,为每个服务创建并分发证书变得非常困难。我们可以通过创建一个私有的证书中心(Internal PKI/CA)来为各个微服务提供证书管理如颁发、撤销、更新等。
 
 
  
五、参考
How We Solved Authentication and Authorization in Our Microservice ArchitectureHow to build your own public key infrastructureOAuth 2.0 Authorization Code RequestPKI/CA工作原理及架构深入聊聊微服务架构的身份认证问题
 
推荐阅读
实例 | 当Istio遇见Jaeger,如何解决端到端分布式追踪问题?
微服务架构之思维三部曲:What、Why、How
倍道而进:Conduit 0.3 正式从 experimental 升级到 alpha,实现生产指日可待

 
ServiceMesh中文社区:
ServiceMesh中文社区(servicemesh.cn)已上线,Istio、Conduit官方文档翻译版已在社区发布,欢迎大家登录浏览。社区翻译小组志愿者招募中,有兴趣的私信小数即可~
 
ServiceMesh微信交流群:
添加微信xiaoshu062,备注:服务网格,即可加入Service Mesh微信交流群。
  查看全部
   
作者简介:
      赵化冰是一名程序员及开源软件爱好者,目前在NFV&SDN编排开源社区ONAP担任MSB项目PTL,致力于高性能,高可用性微服务架构在编排领域的应用。
      博客链接:http://zhaohuabing.com/  
 
目录 
一、前言
二、单体应用的实现方式
三、微服务认证和鉴权面临的问题
四、微服务认证和鉴权的技术方案
1.用户身份认证
2.用户状态保持
3.实现单点登录
4.用户权限控制
  • API Gateway处进行统一的权限控制

  • 由各个微服务单独进行权限控制

5.第三方应用接入
  • API Token

  • OAuth

6.微服务之间的认证
五、参考
  
一、前言 
 
微服务架构的引入为软件应用带来了诸多好处:包括小开发团队,缩短开发周期,语言选择灵活性,增强服务伸缩能力等。与此同时,也引入了分布式系统的诸多复杂问题。其中一个挑战就是如何在微服务架构中实现一个灵活,安全,高效的认证和鉴权方案。本文将尝试就此问题进行一次比较完整的探讨。
 
 
 
二、单体应用的实现方式
 
在单体架构下,整个应用是一个进程,在应用中,一般会用一个安全模块来实现用户认证和鉴权。 用户登录时,应用的安全模块对用户身份进行验证,验证用户身份合法后,为该用户生成一个会话(Session),并为该Session关联一个唯一的编号(Session Id)。Session是应用中的一小块内存结构,其中保存了登录用户的信息,如User name, Role, Permission等。服务器把该Session的Session Id返回给客户端,客户端将Session Id以cookie或者URL重写的方式记录下来,并在后续请求中发送给应用,这样应用在接收到客户端访问请求时可以使用Session Id验证用户身份,不用每次请求时都输入用户名和密码进行身份验证


备注:为了避免Session Id被第三者截取和盗用,客户端和应用之前应使用TLS加密通信,session也会设置有过期时间。


 
1_(3).png


                          单体应用用户登录认证序列图
 
客户端访问应用时,Session Id随着HTTP请求发送到应用,客户端请求一般会通过一个拦截器处理所有收到的客户端请求。拦截器首先判断Session Id是否存在,如果该Session Id存在,就知道该用户已经登录。然后再通过查询用户权限判断用户能否执行该此请求,以实现操作鉴权。
 
2_(3).png


data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==单体应用用户操作鉴权序列图    
 
 

三、微服务认证和鉴权面临的问题 
 
在微服务架构下,一个应用被拆分为多个微服务进程,每个微服务实现原来单体应用中一个模块的业务功能。应用拆分后,对每个微服务的访问请求都需要进行认证和鉴权。如果参考单体应用的实现方式会遇到下述问题:
  • 认证和鉴权逻辑需要在每个微服务中进行处理,需要在各个微服务中重复实现这部分公共逻辑。虽然我们可以使用代码库复用部分代码,但这又会导致所有微服务对特定代码库及其版本存在依赖,影响微服务语言/框架选择的灵活性。
  • 微服务应遵循单一职责原理,一个微服务只处理单一的业务逻辑。认证和鉴权的公共逻辑不应该放到微服务实现中。
  • 为了充分利用微服务架构的好处,实现微服务的水平扩展(Scalability)和弹性(Resiliency),微服务最好是无状态的。因此不建议使用session这种有状态的方案。
  • 微服务架构下的认证和鉴权涉及到场景更为复杂,涉及到用户访问微服务应用,第三方应用访问微服务应用,应用内多个微服务之间相互访问等多种场景,每种场景下的认证和鉴权方案都需要考虑到,以保证应用程序的安全性。 data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==

 微服务认证和鉴权涉及到的三种场景  
  
四、微服务认证和鉴权的技术方案

  1.用户身份认证
 
一个完整的微服务应用是由多个相互独立的微服务进程组成的,对每个微服务的访问都需要进行用户认证。如果将用户认证的工作放到每个微服务中,应用的认证逻辑将会非常复杂。因此需要考虑一个SSO(单点登录)的方案,即用户只需要登录一次,就可以访问所有微服务提供的服务。 由于在微服务架构中以API Gateway作为对外提供服务的入口,因此可以考虑在API Gateway处提供统一的用户认证。
 
 2.用户状态保持
 
HTTP是一个无状态的协议,对服务器来说,用户的每次HTTP请求是相互独立的。互联网是一个巨大的分布式系统,HTTP协议作为互联网上的一个重要协议,要考虑到大量应用访问的效率问题。无状态意味着服务端可以把客户端的请求根据需要发送到集群中的任何一个节点,HTTP的无状态设计对负载均衡有明显的好处,由于没有状态,用户请求可以被分发到任意一个服务器,应用也可以在靠近用户的网络边缘部署缓存服务器。对于不需要身份认证的服务,例如浏览新闻网页等,这是没有任何问题的。但很多服务如网络购物,企业管理系统等都需要对用户的身份进行认证,因此需要在HTTP协议基础上采用一种方式保存用户的登录状态,避免用户每发起一次请求都需要进行验证。
 
传统方式是在服务器端采用Cookie来保存用户状态,由于在服务器是有状态的,对服务器的水平扩展有影响。在微服务架构下建议采用Token来记录用户登录状态。
 
Token和Seesion主要的不同点是存储的地方不同。Session是集中存储在服务器中的;而Token是用户自己持有的,一般以cookie的形式存储在浏览器中。Token中保存了用户的身份信息,每次请求都会发送给服务器,服务器因此可以判断访问者的身份,并判断其对请求的资源有没有访问权限。
 
Token用于表明用户身份,因此需要对其内容进行加密,避免被请求方或者第三者篡改。JWT(Json Web Token)是一个定义Token格式的开放标准(RFC 7519),定义了Token的内容,加密方式,并提供了各种语言的lib。
 
JWT Token的结构非常简单,包括三部分:
  • Header头部包含类型,为固定值JWT。然后是JWT使用的Hash算法。
  • {"alg": "HS256","typ": "JWT"}
  • Payload包含发布者,过期时间,用户名等标准信息,也可以添加用户角色,用户自定义的信息。
    {"sub": "1234567890","name": "John Doe","admin": true}
  • SignatureToken颁发方的签名,用于客户端验证Token颁发方的身份,也用于服务器防止Token被篡改。 签名算法
    HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)

 
这三部分使用Base64编码后组合在一起,成为最终返回给客户端的Token串,每部分之间采用”.”分隔。下图是上面例子最终形成的Token
data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==
采用Token进行用户认证,服务器端不再保存用户状态,客户端每次请求时都需要将Token发送到服务器端进行身份验证。Token发送的方式rfc6750进行了规定,采用一个 Authorization: Bearer HHTP Header进行发送。
Authorization: Bearer mF_9.B5f-4.1JqM

 
采用Token方式进行用户认证的基本流程如下图所示:
  1. 用户输入用户名,密码等验证信息,向服务器发起登录请求
  2. 服务器端验证用户登录信息,生成JWT token
  3. 服务器端将Token返回给客户端,客户端保存在本地(一般以Cookie的方式保存)
  4. 客户端向服务器端发送访问请求,请求中携带之前颁发的Token
  5. 服务器端验证Token,确认用户的身份和对资源的访问权限,并进行相应的处理(拒绝或者允许访问) data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==
    5_(2).png

采用Token进行用户认证的流程图 
 
3、实现单点登录
 
单点登录的理念很简单,即用户只需要登录应用一次,就可以访问应用中所有的微服务。API Gateway提供了客户端访问微服务应用的入口,Token实现了无状态的用户认证。结合这两种技术,可以为微服务应用实现一个单点登录方案。
 
用户的认证流程和采用Token方式认证的基本流程类似,不同之处是加入了API Gateway作为外部请求的入口。
 
用户登录
  1. 客户端发送登录请求到API Gateway
  2. API Gateway将登录请求转发到Security Service
  3. Security Service验证用户身份,并颁发Token

用户请求
  1. 客户端请求发送到API Gateway
  2. API Gateway调用的Security Service对请求中的Token进行验证,检查用户的身份
  3. 如果请求中没有Token,Token过期或者Token验证非法,则拒绝用户请求。
  4. Security Service检查用户是否具有该操作权
  5. 如果用户具有该操作权限,则把请求发送到后端的Business Service,否则拒绝用户请求 data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==
    api-gateway-sso.png

采用API Gateway和Token实现微服务应用的单点登录   
 
 
4、用户权限控制 
用户权限控制有两种做法,在API Gateway处统一处理,或者在各个微服务中单独处理。 
 
  • API Gateway处进行统一的权限控制

 
客户端发送的HTTP请求中包含有请求的Resource及HTTP Method。如果系统遵循REST规范,以URI资源方式对访问对象进行建模,则API Gateway可以从请求中直接截取到访问的资源及需要进行的操作,然后调用Security Service进行权限判断,根据判断结果决定用户是否有权限对该资源进行操作,并转发到后端的Business Service。这种实现方式API Gateway处统一处理鉴权逻辑,各个微服务不需要考虑用户鉴权,只需要处理业务逻辑,简化了各微服务的实现。
  • 由各个微服务单独进行权限控制

 
如果微服务未严格遵循REST规范对访问对象进行建模,或者应用需要进行定制化的权限控制,则需要在微服务中单独对用户权限进行判断和处理。这种情况下微服务的权限控制更为灵活,但各个微服务需要单独维护用户的授权数据,实现更复杂一些。

 
 5、第三方应用接入
 
对于第三方应用接入的访问控制,有两种实现方式:
  • API Token

 
第三方使用一个应用颁发的API Token对应用的数据进行访问。该Token由用户在应用中生成,并提供给第三方应用使用。在这种情况下,一般只允许第三方应用访问该Token所属用户自身的数据,而不能访问其他用户的敏感私有数据。
 
例如Github就提供了Personal API Token功能,用户可以在Github的开发者设置界面中创建Token,然后使用该Token来访问Github的API。在创建Token时,可以设置该Token可以访问用户的哪些数据,如查看Repo信息,删除Repo,查看用户信息,更新用户信息等。
 
使用API Token来访问Github API
curl -u zhaohuabing:fbdf8e8862252ed0f3ba9dba4e328c01ac93aeec https://api.github.com/user

 
使用API Token而不是直接使用用户名/密码来访问API的好处是降低了用户密码暴露的风险,并且可以随时收回Token的权限而不用修改密码。
 
由于API Token只能访问指定用户的数据,因此适合于用户自己开发一些脚本或小程序对应用中自己的数据进行操作。
 
  • OAuth

 
某些第三方应用需要访问不同用户的数据,或者对多个用户的数据进行整合处理,则可以考虑采用OAuth。采用OAuth,当第三方应用访问服务时,应用会提示用户授权第三方应用相应的访问权限,根据用户的授权操作结果生成用于访问的Token,以对第三方应用的操作请求进行访问控制。
 
同样以Github为例,一些第三方应用如Travis CI,GitBook等就是通过OAuth和Github进行集成的。 OAuth针对不同场景有不同的认证流程,一个典型的认证流程如下图所示:
  • 用户向OAuth客户端程序发起一个请求,OAuth客户端程序在处理该请求时发现需要访问用户在资源服务器中的数据。
  • 客户端程序将用户请求重定向到认证服务器,该请求中包含一个callback的URL。
  • 认证服务器返回授权页面,要求用户对OAuth客户端的资源请求进行授权。
  • 用户对该操作进行授权后,认证服务器将请求重定向到客户端程序的callback url,将授权码返回给客户端程序。
  • 客户端程序将授权码发送给认证服务器,请求token。
  • 认证服务器验证授权码后将token颁发给客户端程序。
  • 客户端程序采用颁发的token访问资源,完成用户请求。


备注:

  1. OAuth中按照功能区分了资源服务器和认证服务器这两个角色,在实现时这两个角色常常是同一个应用。将该流程图中的各个角色对应到Github的例子中,资源服务器和认证服务器都是Github,客户端程序是Travis CI或者GitBook,用户则是使用Travis CI或者GitBook的直接用户。
  2. 有人可能会疑惑在该流程中为何要使用一个授权码(Authorization Code)来申请Token,而不是由认证服务器直接返回Token给客户端。OAuth这样设计的原因是在重定向到客户端Callback URL的过程中会经过用户代理(浏览器),如果直接传递Token存在被窃取的风险。采用授权码的方式,申请Token时客户端直接和认证服务器进行交互,并且认证服务期在处理客户端的Token申请请求时还会对客户端进行身份认证,避免其他人伪造客户端身份来使用认证码申请Token。 下面是一个客户端程序采用Authorization Code来申请Token的示例,client_id和client_secret被用来验证客户端的身份。

POST /oauth/token HTTP/1.1
Host: authorization-server.com

grant_type=authorization_code
&code=xxxxxxxxxxx
&redirect_uri=https://example-app.com/redirect
&client_id=xxxxxxxxxx
&client_secret=xxxxxxxxxx


 
OAuth认证流程
 
另外在谈及OAuth时,我们需要注意微服务应用作为OAuth客户端和OAuth服务器的两种不同场景:
 
在实现微服务自身的用户认证时,也可以采用OAuth将微服务的用户认证委托给一个第三方的认证服务提供商,例如很多应用都将用户登录和微信或者QQ的OAuth服务进行了集成。
 
第三方应用接入和微服务自身用户认证采用OAuth的目的是不同的,前者是为了将微服务中用户的私有数据访问权限授权给第三方应用,微服务在OAuth架构中是认证和资源服务器的角色;而后者的目的是集成并利用知名认证提供服务商提供的OAuth认证服务,简化繁琐的注册操作,微服务在OAuth架构中是客户端的角色。
 
因此在我们需要区分这两种不同的场景,以免造成误解。
 
 
6、微服务之间的认证
 
除了来自用户和第三方的北向流量外,微服务之间还有大量的东西向流量,这些流量可能在同一个局域网中,也可能跨越不同的数据中心,这些服务间的流量存在被第三方的嗅探和攻击的危险,因此也需要进行安全控制。
 
通过双向SSL可以实现服务之间的相互身份认证,并通过TLS加密服务间的数据传输。需要为每个服务生成一个证书,服务之间通过彼此的证书进行身份验证。在微服务运行环境中,可能存在大量的微服务实例,并且微服务实例经常会动态变化,例如随着水平扩展增加服务实例。在这种情况下,为每个服务创建并分发证书变得非常困难。我们可以通过创建一个私有的证书中心(Internal PKI/CA)来为各个微服务提供证书管理如颁发、撤销、更新等。
 
 
  
五、参考
  • How We Solved Authentication and Authorization in Our Microservice Architecture
  • How to build your own public key infrastructure
  • OAuth 2.0 Authorization Code Request
  • PKI/CA工作原理及架构
  • 深入聊聊微服务架构的身份认证问题

 
推荐阅读
实例 | 当Istio遇见Jaeger,如何解决端到端分布式追踪问题?
微服务架构之思维三部曲:What、Why、How
倍道而进:Conduit 0.3 正式从 experimental 升级到 alpha,实现生产指日可待

 
ServiceMesh中文社区:
ServiceMesh中文社区(servicemesh.cn)已上线,Istio、Conduit官方文档翻译版已在社区发布,欢迎大家登录浏览。社区翻译小组志愿者招募中,有兴趣的私信小数即可~
 
ServiceMesh微信交流群:
添加微信xiaoshu062,备注:服务网格,即可加入Service Mesh微信交流群。
 

微服务架构之思维三部曲:What、Why、How

小数 发表了文章 • 0 个评论 • 514 次浏览 • 2018-02-27 10:02 • 来自相关话题

 
 
What:什么是微服务? 
 
某百科对微服务架构的定义和阐述:
 
微服务可以在“自己的程序”中运行,并通过“轻量级设备与 HTTP 型 API 进行沟通”。关键在于该服务可以在自己的程序中运行。通过这一点我们就可以将服务公开与微服务架构(在现有系统中分布一个API)区分开来。在服务公开中,许多服务都可以被内部独立进程所限制。如果其中任何一个服务需要增加某种功能,那么就必须缩小进程范围。在微服务架构中,只需要在特定的某种服务中增加所需功能,而不影响整体进程。
 
定义总是晦涩些,如果将微服务拆开理解就简单许多:
 
微:它基于单一责任的“微小”功能模块,这些微小模块从前端 WEB UI,到控制层、逻辑层、数据库访问以及数据库都可以是完全独立的一整套。——独立部署、互相隔离
 
服务:业务被拆分成多个“微小”服务模块,这些模块之间通过使用轻量的通讯协议和简单的数据结构沟通(通常可采用 http+json),因此,每个微小模块需要消费外部其它微小模块暴露的服务,同时还需对外提供服务。——我为人人,人人为我  
Why:为什么需要微服务
 
在讨论为什么的问题之前,我们先回顾一下服务化架构的演进。
 
data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==





图1  服务化架构演进图
 
从图1中我们可知,随着互联网的发展,网站应用的规模不断扩大,微服务之前的架构面临着多方面的挑战:
代码重复率高,模块过度依赖。共享困难,公共类库维护成本高。需求变更困难,新业务快速交付难。可扩展性差,功能模块按需扩展难。运维成本高,测试、部署成本高。
 
简单总结各个演进架构(包括微服务)的优缺点,如下表格所示:
 





其实,在软件开发里,不同的架构并没有哪个更好的说法。对于架构的选型,只有合适与不合适之说。比如,简单的小型应用开发,就可直接使用单体架构设计,直接打包,方便部署,容易测试,响应迅速。所以,我们应该结合对技术和业务的理解,选择更符合我们的目标架构。
 
 
 
How:怎么用微服务
 
从上文我们知道微服务能给我们带来众多好处,尤其对于较大规模的应用开发在业务大规模爬升时,微服务的架构的优势更加凸显:1、开发效率更高。2、沟通成本更低。3、响应速度更快。4、迭代周期更短。
 
那如何应用微服务呢?需要做哪些准备工作?下面从五个方面来谈:
 
1、单体架构拆分
下面这张老外的抽象“拆分图”,从三个维度概括了一个系统的扩展过程:
 
 

x轴,水平复制,即在负载均衡服务器后增加多个WEB服务器,实现分布式部署;z轴扩展,是对数据库的扩展,即分库分表(分库是将关系紧密的表放在一台数据库服务器上,分表是因为一张表的数据太多,需要将一张表的数据通过hash放在不同的数据库服务器上);y轴扩展,是功能分解,将不同职能的模块分成不同的服务。从y轴这个方向扩展,能将巨型应用分解为一组不同的服务。不同服务使用不同的数据,与外部交互通过消息或 API,每个服务设计需要把握“微”的度,不宜在基础功能上做过多堆叠,否则每个微服务组件可能又变成大的单体应用。
2、服务治理
服务治理依赖底层的技术支持,需要做好很多必要的技术知识储备。
 
搭建微服务总线和通讯机制
这个问题涉及到几个方面,如服务注册、服务发现、服务调用。阿里开源的 Dubbo 框架就是一种微服务框架,它借助 Zookeeper 等多种注册中心实现对 Provider 服务的注册,并且提供服务发现功能。Dubbo 支持 Hessian、WebService、Thrift 等方式的 RPC 远程服务调用,此外当当的 Dubbox(由 Dubbo 扩展新功能而成,即 DubboeXtensions)还支持 RESTAPI 的服务调用方式。事实上更地道的微服务架构会采用基于异步通信的调用。在异步通信中,各服务间彼此依赖,但不会因相互等待结果而导致响应速度缓慢。因此,如果一项服务发生故障,其不会影响到其它服务,瓶颈与单点故障问题也将不复存在。
 
负载均衡
Dubbo 提供的 ConfigServer 的原理,就可知道如何保证微服务系统的负载均衡和整体的可靠性问题了。Dubbo 的配置中心和每个 Server/Client 之间会作一个实时的心跳检测,收集并更新每个Server提供的服务的信息和每个 Client 的信息。每个 Server 启动时,主动与 ConfigServer 建立连接,并将自己的 IP,提供的服务名称,端口等信息直接发送给ConfigServer,ConfigServer 会更新服务列表。Client 在使用服务的时候根据服务名称去ConfigServer 中获取服务提供者信息,后面就可以直接调用服务了。当有多个服务提供者的时候,Client根据一定的规则来进行负载均衡,如轮询、随机、按权重等。一旦 Client 使用的服务它对应的服务提供者有变化,ConfigServer 就会把最新的服务提供者列表推送给 Client,Client 重新建立连接。
 
3、自动化测试
微服务一个明显的表象就是随着业务规模的扩大,服务将会增多、增强。传统的测试模式就会遇到瓶颈,为了保证高效的迭代,尽量做到更多的环节实现自动化。
 
4、自动运维
微服务拆分之后,每个服务都可以独立打包、发布、部署、启停、扩容和升级,核心服务独立集群部署,进而言之应该是随时随地可以升级。尤其当互联网发展到今天,业务要保持对市场变化的一个高效响应,自动化运维就是提升交付速度的一个重要环节。
 
5、监控
包括硬件环境、服务状态、系统健康度、接口调用情况、异常的实时告警以及潜在问题的事先预警等等。监控在实施微服务过程中会重要到什么程度呢?一句话:没准备好监控,就不要搞微服务。
 
  
微服务不是银弹?  软件领域没有银弹,微服务带来了很多收益,同时它也引入了很多问题,总结以下几点供将准备搞微服务架构的同学们思考。
 
时延问题,服务之间远程通信增加的性能损耗。事务一致性,有逻辑关联的多个数据库操作被分布到多个独立的服务中,在分布式环境下引起的事务一致性问题。[size=14]问题定位,分布式环境下,问题定位和日志检索。[/size]测试运维难度增大,跨服务的测试将更复杂,运维工作更具挑战。  查看全部


1518159112.png

 
 
What:什么是微服务? 
 
某百科对微服务架构的定义和阐述:
 
微服务可以在“自己的程序”中运行,并通过“轻量级设备与 HTTP 型 API 进行沟通”。关键在于该服务可以在自己的程序中运行。通过这一点我们就可以将服务公开与微服务架构(在现有系统中分布一个API)区分开来。在服务公开中,许多服务都可以被内部独立进程所限制。如果其中任何一个服务需要增加某种功能,那么就必须缩小进程范围。在微服务架构中,只需要在特定的某种服务中增加所需功能,而不影响整体进程。
 
定义总是晦涩些,如果将微服务拆开理解就简单许多:
 
  • 微:它基于单一责任的“微小”功能模块,这些微小模块从前端 WEB UI,到控制层、逻辑层、数据库访问以及数据库都可以是完全独立的一整套。——独立部署、互相隔离

 
  • 服务:业务被拆分成多个“微小”服务模块,这些模块之间通过使用轻量的通讯协议和简单的数据结构沟通(通常可采用 http+json),因此,每个微小模块需要消费外部其它微小模块暴露的服务,同时还需对外提供服务。——我为人人,人人为我  

Why:为什么需要微服务
 
在讨论为什么的问题之前,我们先回顾一下服务化架构的演进。
 
data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==
微信图片_20180227101557.jpg


图1  服务化架构演进图
 
从图1中我们可知,随着互联网的发展,网站应用的规模不断扩大,微服务之前的架构面临着多方面的挑战:
  • 代码重复率高,模块过度依赖。
  • 共享困难,公共类库维护成本高。
  • 需求变更困难,新业务快速交付难。
  • 可扩展性差,功能模块按需扩展难。
  • 运维成本高,测试、部署成本高。

 
简单总结各个演进架构(包括微服务)的优缺点,如下表格所示:
 
微信图片_20180227101621.jpg


其实,在软件开发里,不同的架构并没有哪个更好的说法。对于架构的选型,只有合适与不合适之说。比如,简单的小型应用开发,就可直接使用单体架构设计,直接打包,方便部署,容易测试,响应迅速。所以,我们应该结合对技术和业务的理解,选择更符合我们的目标架构。
 
 
 
How:怎么用微服务
 
从上文我们知道微服务能给我们带来众多好处,尤其对于较大规模的应用开发在业务大规模爬升时,微服务的架构的优势更加凸显:1、开发效率更高。2、沟通成本更低。3、响应速度更快。4、迭代周期更短。
 
那如何应用微服务呢?需要做哪些准备工作?下面从五个方面来谈:
 
1、单体架构拆分
下面这张老外的抽象“拆分图”,从三个维度概括了一个系统的扩展过程:
 
 

  • x轴,水平复制,即在负载均衡服务器后增加多个WEB服务器,实现分布式部署;
  • z轴扩展,是对数据库的扩展,即分库分表(分库是将关系紧密的表放在一台数据库服务器上,分表是因为一张表的数据太多,需要将一张表的数据通过hash放在不同的数据库服务器上);
  • y轴扩展,是功能分解,将不同职能的模块分成不同的服务。从y轴这个方向扩展,能将巨型应用分解为一组不同的服务。不同服务使用不同的数据,与外部交互通过消息或 API,每个服务设计需要把握“微”的度,不宜在基础功能上做过多堆叠,否则每个微服务组件可能又变成大的单体应用。

2、服务治理
服务治理依赖底层的技术支持,需要做好很多必要的技术知识储备。
 
  • 搭建微服务总线和通讯机制

这个问题涉及到几个方面,如服务注册、服务发现、服务调用。阿里开源的 Dubbo 框架就是一种微服务框架,它借助 Zookeeper 等多种注册中心实现对 Provider 服务的注册,并且提供服务发现功能。Dubbo 支持 Hessian、WebService、Thrift 等方式的 RPC 远程服务调用,此外当当的 Dubbox(由 Dubbo 扩展新功能而成,即 DubboeXtensions)还支持 RESTAPI 的服务调用方式。事实上更地道的微服务架构会采用基于异步通信的调用。在异步通信中,各服务间彼此依赖,但不会因相互等待结果而导致响应速度缓慢。因此,如果一项服务发生故障,其不会影响到其它服务,瓶颈与单点故障问题也将不复存在。
 
  • 负载均衡

Dubbo 提供的 ConfigServer 的原理,就可知道如何保证微服务系统的负载均衡和整体的可靠性问题了。Dubbo 的配置中心和每个 Server/Client 之间会作一个实时的心跳检测,收集并更新每个Server提供的服务的信息和每个 Client 的信息。每个 Server 启动时,主动与 ConfigServer 建立连接,并将自己的 IP,提供的服务名称,端口等信息直接发送给ConfigServer,ConfigServer 会更新服务列表。Client 在使用服务的时候根据服务名称去ConfigServer 中获取服务提供者信息,后面就可以直接调用服务了。当有多个服务提供者的时候,Client根据一定的规则来进行负载均衡,如轮询、随机、按权重等。一旦 Client 使用的服务它对应的服务提供者有变化,ConfigServer 就会把最新的服务提供者列表推送给 Client,Client 重新建立连接。
 
3、自动化测试
微服务一个明显的表象就是随着业务规模的扩大,服务将会增多、增强。传统的测试模式就会遇到瓶颈,为了保证高效的迭代,尽量做到更多的环节实现自动化。
 
4、自动运维
微服务拆分之后,每个服务都可以独立打包、发布、部署、启停、扩容和升级,核心服务独立集群部署,进而言之应该是随时随地可以升级。尤其当互联网发展到今天,业务要保持对市场变化的一个高效响应,自动化运维就是提升交付速度的一个重要环节。
 
5、监控
包括硬件环境、服务状态、系统健康度、接口调用情况、异常的实时告警以及潜在问题的事先预警等等。监控在实施微服务过程中会重要到什么程度呢?一句话:没准备好监控,就不要搞微服务。
 
  
微服务不是银弹?  软件领域没有银弹,微服务带来了很多收益,同时它也引入了很多问题,总结以下几点供将准备搞微服务架构的同学们思考。
 
  • 时延问题,服务之间远程通信增加的性能损耗。
  • 事务一致性,有逻辑关联的多个数据库操作被分布到多个独立的服务中,在分布式环境下引起的事务一致性问题。
  • [size=14]问题定位,分布式环境下,问题定位和日志检索。[/size]
  • 测试运维难度增大,跨服务的测试将更复杂,运维工作更具挑战。