liu 发布的文章

1  引言


先思考一个问题:在kubernetes的网络环境下,如何做服务间的访问控制 和 提高访问的安全性?


你可能会想到 进行HTTPS加密、使用NetworkPolicy、使用RBAC控制权限...等等




总结起来要实现以下能力:


数据加密:确保传输中的数据经过加密,难以被截获破解


身份认证:确定客户端和服务端都是真实且经过验证的


权限控制:默认拒绝掉来历不明的请求,开放最小粒度的访问权限给必要的访问者




而原生kubernetes访问控制能力存在着缺陷: 


没有对应用层协议的分析处理能力。 


ServiceAccount 可以做到把服务和身份关联(每个deployment创建一个ServiceAccount),但一个sa token 只能在一个集群中标记负载身份,不能支持 Kubernetes 环境和虚拟机的异构场景、多kubernetes集群联合使用场景。




对此问题istio提出了解决方案:


为每个pod的sidecar自动下发x509证书,支持pod间使用mtls加密通信。


使用了SPIFFE (Secure Production Identity Framework For Everyone)开源的身份认证标准,标识工作负载(身份)。SPIFFE ID 是一个统一资源标识符, istio中 SPIFFE ID 格式为:spiffe://<trust_domain>/ns/<namespace>/sa/<service_ account> 。在kubernetes平台上,istio巧妙的借助kubernetes工作负载的Service Account信息,在istio生成工作负载证书时将  SPIFFE ID 字符串注入 X509 证书的 subjectAltName扩展中,随着 X.509 证书下发到数据面。通信双方通过这个字符串即可获得对方身份,实现了istio中的身份标识。(若工作负载没有配置服务账户的情况下使用命名空间的默认ServiceAccount)。其中“trust domain”参数通过 Istiod 环境变量 TRUST_DOMAIN 注入,用于在多kubernetes集群环境。


通过sidecar代理 拦截处理访问流量,进行权限管控。




2  istio访问管理架构


Istio 为微服务提供了无侵入,可插拔的底层安全基础设施。在istio中服务间端到端的通信安全通过服务网格中的代理实现,在整个请求过程中客户端和服务端应用程序是不感知的。


本文将从istio 证书管理、身份认证、访问鉴权策略  三个方面来介绍 Istio 的安全机制。


istio访问管理架构



3  istio证书管理


Istio通过向数据面代理颁发X.509证书来为工作负载提供身份标识。


证书管理和轮换由与Envoy代理在同一容器中运行的pilot-agent 进程代理完成。


Istio 通过以下流程管理证书:


istio证书下发管理流程

istiod 提供 gRPC 服务以接受证书签名请求(CSR)。


pilot-agent 在启动时创建私钥和 CSR,然后将 CSR 及其凭据发送到 istiod 进行签名。


istiod CA 验证 CSR 中携带的凭据,成功验证后签署 CSR 以生成证书,证书中包含对应的SPIFFEID。


当工作负载启动时,Envoy 通过 Secret 发现服务(SDS)API 向同容器内的 pilot-agent  发送证书和密钥请求。


pilot-agent 通过 Envoy SDS API 将从 istiod 收到的证书和密钥发送给 Envoy。


pilot-agent  监控工作负载证书的过期时间。上述过程会定期重复进行证书和密钥轮换。




4  istio身份认证


认证(Authentication)一般是指验证当前用户的身份,对于微服务而言则是验证请求对端的身份。在安全的理论模型中,身份是任何安全功能的基础条件。


Istio 提供两种类型的身份认证:


对等认证:基于mtls来实现的服务到服务的认证。(即通过x509证书获取对端身份),一般用于kubernetes集群内的服务之间的认证。


请求认证:基于jwt(JSON Web Token)来实现的请求级别的认证,它常被用于终端用户身份认证。


当前istio技术落地时大多数使用对等认证。istio请求认证的使用较少,大多数情况下jwt解析是在应用程序中进行,而不是istio代理解析,因为应用程序需要获取终端用户id来对数据库操作。


本文不介绍请求认证。




4.1 对等认证的概念和原理


TLS 协议是TCP/IP协议组的一部分,用于在两台主机间建立一个加密的双向网络通道。TLS协议一般会和其他协议结合使用来提供安全的应用层,例如我们熟知的HTTPS、FTPS等。




mTLS是TLS协议的扩展,旨在验证双方(Web客户端和Web服务器)的身份并保护他们在网络中的通信安全。


TLS单向认证与mTLS双向认证的区别如下:


TLS单向认证:只有客户端验证服务端的合法身份,服务端不关心客户端身份。服务端维护证书。web应用大多数是单向的TLS认证。


mTLS双向认证:客户端和服务端都要验证对端身份。客户端和服务端都必须持有标识身份的证书。常用于服务到服务的访问。


Istio对等认证基于mTLS,实现以下能力:


真实性:确保双方都是真实且经过验证的


保密性:确保传输中的数据安全


完整性:确保发送数据的正确性




4.2 对等认证的架构


istio的对等认证(mtls)是由网格代理完成的,在整个请求过程中客户端和服务端应用程序是不感知的。


mTLS认证架构和认证过程



4.3 对等认证生效范围


PeerAuthentication 的 metadata.namespace 和 spec.selector 字段 决定对等认证生效范围。


全网格范围:metadata.namespace 为istio-system 且 selector 字段为空。


命名空间范围:metadata.namespace  非istio-system ,selector 字段为空。


特定工作负载:metadata.namespace  非istio-system , selector 字段非空。


只能有一个网格范围的对等认证策略, 每个命名空间也只能有一个命名空间范围的对等认证策略。




一个工作负载只能生效一个认证规则,Istio 按照以下顺序为每个工作负载应用匹配的策略:


特定工作负载的规则 > 命名空间范围规则 > 全网格范围规则




4.4 对等认证生效位置


认证策略是对服务收到的请求生效的,即服务端生效。




4.5 对等认证配置


对等认证示例如下:


apiVersion: security.istio.io/v1beta1

kind: PeerAuthentication

metadata:

  name: "httpbin"

  namespace: "bar"                 ## 只可生效于"bar"命名空间下的工作负载

spec:

  selector:                        ## 通过label匹配pod

    matchLabels:

      app: httpbin # 匹配 httpbin 应用的标签

  mtls:

    mode: STRICT                   ## 安全模式,STRICT代表只接受mtls请求

其中spec.mtls.mode有3种可选值,对应3种身份认证模式:


PERMISSIVE:同时支持明文传输和mtls密文传输。不管是网格内还是网格外,服务间都可通信。


STRICT:此服务只接收双向 TLS 流量。


DISABLE:关闭MutualTLS。从安全的角度而言,官方并不建议在没有其他安全措施的情况下使用该模式。


缺省配置时:将从父级配置中继承(命名空间或网格层面),如果父级没有进行相应的配置,则使用PERMISSIVE模式。




4.4 对等认证部署验证


我们先准备下面的sleep.yaml 和 httpbin.yaml


## sleep.yaml文件

apiVersion: v1

kind: ServiceAccount

metadata:

  name: sleep

---

apiVersion: v1

kind: Service

metadata:

  name: sleep

  labels:

    app: sleep

    service: sleep

spec:

  ports:

  - port: 80

    name: http

  selector:

    app: sleep

---

apiVersion: apps/v1

kind: Deployment

metadata:

  name: sleep

spec:

  replicas: 1

  selector:

    matchLabels:

      app: sleep

  template:

    metadata:

      labels:

        app: sleep

    spec:

      terminationGracePeriodSeconds: 0

      serviceAccountName: sleep

      containers:

      - name: sleep

        image: curlimages/curl

        command: ["/bin/sleep", "infinity"]

        imagePullPolicy: IfNotPresent

        volumeMounts:

        - mountPath: /etc/sleep/tls

          name: secret-volume

      volumes:

      - name: secret-volume

        secret:

          secretName: sleep-secret

          optional: true


## httpbin.yaml文件

apiVersion: v1

kind: ServiceAccount

metadata:

  name: httpbin

---

apiVersion: v1

kind: Service

metadata:

  name: httpbin

  labels:

    app: httpbin

    service: httpbin

spec:

  ports:

  - name: http-http

    port: 80

    targetPort: 80

  selector:

    app: httpbin

---

apiVersion: apps/v1

kind: Deployment

metadata:

  name: httpbin

spec:

  replicas: 1

  selector:

    matchLabels:

      app: httpbin

      version: v1

  template:

    metadata:

      labels:

        app: httpbin

        version: v1

    spec:

      serviceAccountName: httpbin

      containers:

      - image: docker.io/kong/httpbin

        imagePullPolicy: IfNotPresent

        name: httpbin

        ports:

        - containerPort: 80

执行以下操作


## 创建三个命名空间

kubectl create ns foo

kubectl create ns bar

kubectl create ns legacy


## 对其中两个命名空间开启istio自动注入,另一个不开启istio自动注入

kubectl label namespace foo istio-injection=enabled

kubectl label namespace bar istio-injection=enabled


## 应用上面的yaml文件

kubectl apply -f  httpbin.yaml -n foo

kubectl apply -f sleep.yaml -n foo

kubectl apply -f httpbin.yaml -n bar

kubectl apply -f sleep.yaml -n bar

kubectl apply -f sleep.yaml -n legacy

实验先从默认的PERMISSIVE模式下开始,PERMISSIVE模式下服务网格对服务的流量都是放通的。遍历不同空间的sleep工作负载访问httpbin工作负载,可以看到是全通的。


服务间访问测试

生效下面的对等认证规则


## pa.yaml文件

apiVersion: security.istio.io/v1beta1

kind: PeerAuthentication

metadata:

  name: "example-peer-policy"

  namespace: "foo"

spec:

  selector:

    matchLabels:

      app: reviews

  mtls:

    mode: STRICT

执行如下命令进行测试:


for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec "$(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name})" -c sleep -n ${from} -- curl http://httpbin.${to}:80/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done

应用PeerAuthentication严格模式后,istio代理会自动把请求流量升级为mtls模式,所以foo、bar命名空间的请求正常。而legacy命名空间没有注入sidecar,没有代理为其实现mtls,请求失败。


服务间访问测试



4.5 使用需知


当服务开启严格模式的对等认证,只能用svc来访问pod,无法用podip去请求此工作负载。


bug详情连接  https://github.com/istio/istio/issues/37431#issuecomment-1054450785




5  istio服务访问授权


5.1 访问授权概念和原理


在安装完istio后,默认没有服务访问策略,这时允许全部的服务间访问。


istio提供了AUthorizationPolicy CRD来设置服务访问授权。例如:哪个服务、身份、源IP 可以访问某个服务的某个端口、接口。


由于istio作用的对象是服务,因此授权功能主要适用于四至七层(相比较而言,传统的防火主用于二至四层),例如,gRPC、HTTP、HTTPS、HTTP2,以及TCP等。上述协议Istio都可以提供原生支持。


就像istio的其他流量控制功能一样,Istio中授权功能的实现也是非侵入式的,通过sidecar代理完成。




5.2 访问授权架构


服务网格数据面是真正的授权策略执行角色。规则的配置、下发、执行架构如下:


运维人员将AuthorizationPolicy应用到k8s中,存储在etcd


istiod从 k8s中获取授权配置策略,下发到数据面


envoy在拦截到请求后根据授权策略判断是否允许访问。


istio访问授权架构



5.3 访问授权配置


AuthorizationPolicy 包括三个主要字段 selector、action、rules


selector 字段指定策略的目标


rules 指定何时触发动作


rules 下的 from 字段描述请求来源属性。可以不设置,表示匹配所有来源的请求。 from数组元素间是或的关系,form元素内部各个条件是与的关系。


rules 下的 to 字段述对目标服务的操作属性,如:port methods urlpath。若不配置to条件,则表示匹配所有操作。


rules 下的 when 字段指定应用规则所需的条件


action 字段指定最后的操作,支持 ALLOW、DENY 和 CUSTOM




以下示例授权策略拒绝来源非 foo 命名空间的对 httpbin的 "GET" 请求。我们生效配置,然后再次执行循环请求脚本。


apiVersion: security.istio.io/v1

kind: AuthorizationPolicy

metadata:

  name: httpbin

  namespace: foo

spec:

  selector:                               ## 通过标签指定生效的服务

    matchLabels:

      app: httpbin

      version: v1

  action: DENY                            ## 拒绝请求

  rules:                                  ## 匹配请求的条件

    - from:                               ## 不是来自foo命名空间的请求

        - source:

            notNamespaces: ["foo"]

      to:                                 ## Get方法的请求

        - operation:

            methods: ["GET"]

测试结果如下图:


访问授权测试



5.4 访问授权生效顺序


拒绝策略优先于允许策略。如果请求同时匹配上允许策略和拒绝策略,请求将被拒绝。


访问授权判断顺序



5.5 "访问授权"对"身份认证"的依赖


Istio对等认证使用双向 TLS 将某些信息从客户端安全地传递到服务器,这让服务端可以知道请求者的真实身份。 在使用授权策略中的以下任何字段之前,必须先启用双向 TLS:


source 部分下的 principals 和 notPrincipals 字段


source 部分下的 namespaces 和 notNamespaces 字段


source.principal 自定义条件


source.namespace 自定义条件




6  实战经验


6.1 使用访问管控时,建议开启envoy代理日志,便于分析异常问题


kubectl -n istio-system edit configmap istio

编辑yaml文件的对应配置:


data:

  mesh: |-

    accessLogEncoding: JSON

    accessLogFile: /dev/stdout



6.2 更新认证策略最佳实践


当更改认证策略时,Istio 无法保证所有工作负载都同时收到新政策。 以下建议有助于避免在更新认证策略时造成干扰:


将对等认证策略的模式从 DISABLE 更改为 STRICT 时, 请使用 PERMISSIVE 模式来过渡,反之亦然。当所有工作负载成功切换到所需模式时, 您可以将策略应用于最终模式。您可以使用 Istio 遥测技术来验证工作负载已成功切换。


将请求认证策略从一个 JWT 迁移到另一个 JWT 时, 将新 JWT 的规则添加到该策略中,而不删除旧规则。这样, 工作负载将接受两种类型的 JWT,当所有流量都切换到新的 JWT 时, 您可以删除旧规则。但是,每个 JWT 必须使用不同的位置。




6.3 禁止访问公网


有时候为了安全我们不允许kubernetes pod 随意访问公网,可以设置REGISTRY_ONLY。


在传统环境这个需求是由出口防火墙实现,但是在云环境上一般使用snat对整个子网进行出访代理,可以在istio中进行限制。


## 修改访问模式为REGISTRY_ONLY

kubectl get configmap istio -n istio-system -o yaml | sed 's/mode: ALLOW_ANY/mode: REGISTRY_ONLY/g' | kubectl replace -n istio-system -f -


## 切换回Allow-all

kubectl get configmap istio -n istio-system -o yaml | sed 's/mode: REGISTRY_ONLY/mode: ALLOW_ANY/g' | kubectl replace -n istio-system -f

在完成了修改之后,所有访问外部服务的请求都会返回 502 错误。为了正常访问,需要对外部服务进行注册,注册可通过创建服务条目资源来完成。下面的代码创建了第三方支付服务所对应的 ServiceEntry 资源。


apiVersion: networking.istio.io/v1beta1

kind: ServiceEntry

metadata:

  name: baidu-ip

spec:

  hosts:

  - www.baidu.com

  addresses:

  - 36.152.44.96

  location: MESH_EXTERNAL           ## 声明了该服务位于服务网格之外

  ports:

  - number: 80                      ## 定义了允许访问的端口

    name: baidu-http

    protocol: HTTP

  resolution: NONE                  ## 属性表示服务代理如何解析服务的 IP 地址



6.4 istio入口网关黑名单


您使用 X-Forwarded-For HTTP 标头或代理协议来确定原始客户端 IP 地址,那么可以在 AuthorizationPolicy 中使用 remoteIpBlocks 设置黑白名单。


下面yaml配置禁止来自 "1.2.3.4" 和 “5.6.7.0/24” 网段的请求进入istio


apiVersion: security.istio.io/v1beta1

kind: AuthorizationPolicy

metadata:

  name: ingress-policy

  namespace: istio-system

spec:

  selector:

    matchLabels:

      app: istio-ingressgateway

  action: DENY

  rules:

  - from:

    - source:

        remoteIpBlocks: ["1.2.3.4", "5.6.7.0/24"]

 作者:BeijingToTokyo https://www.bilibili.com/read/cv29652221/ 出处:bilibili


本教程已加入Istio系列:https://istio.whuanle.cn

目录

2,部署 Istio

在本章中,将会介绍如何在 Kubernetes 中使用 Helm 部署 Istio。

Istio 的安装方式主要有两类,第一类是基于 Kubernetes 原生集群或虚拟机的安装。另一种是基于 Azure、KubeSphere 等公私有云或 Kubernetes 管理平台上的安装。而在本章中介绍的是基于 Kubernetes 的 Helm 安装。

Istio 官网关于这两类部署方式还有很多小细节,读者可根据实际需要从官方中获取部署资料。

https://istio.io/latest/zh/docs/setup/platform-setup/
https://istio.io/latest/zh/docs/setup/install/

安装 Helm

首先添加 Helm 官方仓库地址到 apt 源中。

代码语言:javascript

复制

curl https://baltocdn.com/helm/signing.asc | sudo apt-key add -  echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list

然后更新包索引。

代码语言:javascript

复制

apt-get update

通过 apt 命令安装 Helm。

代码语言:javascript

复制

apt-get install helm

验证是否安装完成。

代码语言:javascript

复制

helm version

image-20230507152206386

image-20230507152206386

部署 istio-base

Google 对 istio-base 的描述信息太少了,只得请教一下 ChatGPT 哥。

image-20230523084951637

image-20230523084951637

也就是说,只有先安装 istio-base,才能接着安装其它 Istio 组件。

在本文教程中,安装的 Istio 与官方使用 istiocli 部署的方式不同,本教程中是逐渐安装需要的组件,不会一次性安装完成所有组件。这样便于读者逐步了解不同的 Istio 组件的作用,了解其安装方式。

在 Helm 中 添加 Istio 的仓库。

代码语言:javascript

复制

helm repo add istio https://istio-release.storage.googleapis.com/charts
helm repo update

接着提前为 Istio 组件创建命名空间 istio-system

代码语言:javascript

复制

kubectl create namespace istio-system

接下来将使用 Helm 将 Istio 组件安装到 istio-system 命名空间中。

首先安装 Istio CRD:

代码语言:javascript

复制

helm install istio-base istio/base -n istio-system

代码语言:javascript

复制

root@k8smain:~# helm install istio-base istio/base -n istio-systemNAME: istio-baseLAST DEPLOYED: Tue May  2 07:19:15 2023NAMESPACE: istio-systemSTATUS: deployedREVISION: 1TEST SUITE: NoneNOTES:Istio base successfully installed!To learn more about the release, try:
  $ helm status istio-base
  $ helm get all istio-base

使用 helm ls 命令验证 Istio CRD 的安装情况:

代码语言:javascript

复制

root@k8smain:~# helm ls -n istio-systemNAME      	NAMESPACE   	REVISION	UPDATED                                	STATUS  	CHART      	APP VERSIONistio-base	istio-system	1       	2023-05-02 07:19:15.792125237 +0000 UTC	deployed	base-1.17.2	1.17.2

如果 STATUS 的内容是 deployed ,说明已经正常,接下来我们进行下一步操作。

部署 istiod

Istiod( Istio Discovery) 是 Istio 服务网格的核心组件,负责控制平面功能

istiod 具备了五大功能:

  • 配置管理:负责分发和同步 Istio 配置到数据平面(Envoy 代理)。

  • 服务发现:基于 Kubernetes 的 Service 和 Endpoint 信息生成服务发现数据,这些数据用于 Envoy Proxy 的负载均衡

  • 证书管理:为 Envoy Proxy 提供证书签发,以支持双向 TLS 身份验证

  • 验证和转换:验证 Istio 配置资源的正确性,并将它们转换为 Envoy Proxy 可以理解的格式。

  • Envoy 代理注入:负责将 Envoy Proxy 注入到服务 Pod 中,以便进行流量拦截和路由

简单看一下就好了,不用记。

新版本的 Istiod 将旧版本中零散的组件如 Mixer、Pilot、Citadel、Galley 等合并起来了,所以在网上看书查找资料的时候,要注意规避过旧的内容。

在 Helm 中添加 Istiod 仓库。

代码语言:javascript

复制

helm install istiod istio/istiod -n istio-system --wait

image-20230507153558751

image-20230507153558751

验证 Istiod 的安装情况:

代码语言:javascript

复制

root@k8smain:~# helm ls -n istio-systemNAME      	NAMESPACE   	REVISION	UPDATED                                	STATUS  	CHART        	APP VERSIONistio-base	istio-system	1       	2023-05-02 07:19:15.792125237 +0000 UTC	deployed	base-1.17.2  	1.17.2     istiod    	istio-system	1       	2023-05-02 07:21:07.791242626 +0000 UTC	failed  	istiod-1.17.2	1.17.2

检查 istiod 服务是否安装成功,其 Pod 是否正在运行:

代码语言:javascript

复制

root@k8smain:~# kubectl get deployments -n istio-system -o wideNAME     READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                         SELECTORistiod   1/1     1            1           10m   discovery    docker.io/istio/pilot:1.16.1   istio=pilot

部署 istio-ingressgateway

istio-ingressgateway (Istio Ingress Gateway )类似 Kubernetes 的 Ingress ,是 Istio 控制外部流量进入 Kubernetes 的入口组件,istio-ingressgateway 作为一个入口点,允许从服务网格外部访问服务网格内部的服务,起到了类似 nginx、apisix 等入口网关的作用。

Istio Ingress Gateway 的主要包括以下作用:

  • 接收集群外部的流量,并根据 Istio 的配置将请求路由到适当的内部服务(起到网关的作用)。

  • 提供负载均衡和流量控制功能,包括请求路由、重试、超时、熔断等(流量治理)。

  • 支持 TLS 配置,以便在流量进入服务网格之前进行加密(给域名配置证书)。

  • 支持双向 TLS 身份验证,以提高服务网格的安全性(服务间通讯)。

  • 提供 Metrics、Tracing 和 Logging 收集,以便更好地观察和监控流量(需要自己安装对应的组件)。

随便看看就好,不用记这些。

安装 istio-ingressgateway。

代码语言:javascript

复制

helm install istio-ingressgateway istio/gateway -n istio-system

image-20230503121734717

image-20230503121734717

实际上 istio-ingressgateway 是作为一个 Kubernetes Service 对外提供访问服务。

image-20230507154929369

image-20230507154929369

由于 Istio-ingressgateway 默认使用的是 LoadBalancer ,需要公有云平台支撑,不然会一直处于 <pending>,因此我们需要修改 Service ,将 istio-ingressway 的网络类型从 LoadBalancer 改成 NodePort,以便直接通过服务器的 IP 访问。

代码语言:javascript

复制

   kubectl edit svc istio-ingressgateway -n istio-system

找到 type: LoadBalancer ,修改为 type: NodePort

1683087604976

1683087604976

因为 LoadBalancer 包含了 NodePort,其实不修改也行。

istio-ingressgateway 本身包含 Kubernetes Service 、Pod,通过暴露节点端口,外部可以通过节点端口将流量打入 istio-ingressgateway 的 Pod。

image-20230523091815336

image-20230523091815336

流量经过 Istio 分析后,流量通过负载均衡转发到其中一个 Pod。

image-20230528090617137

image-20230528090617137

流量进入 Istio 之后,不需要将流量转发到 Service,但是依然需要依赖 Service。 Istio 会从 Service 中获取到所有的 Pod,然后 Istio 直接将流量转发到 Pod,实现熔断、故障处理等一系列任务。

经过以上步骤,我们已经安装和了解 istio-base、istiod、istio-ingressgateway 三个 Istio 基础组件,在后面的章节中,我们将开始真正实践使用 Istio ,去解决微服务中的一些问题。

清除

如果有一天不需要 Istio 了,你可以通过当前命令清空部署的 Istio 应用。

代码语言:javascript

复制

helm delete istio-ingressgateway -n istio-system
helm delete istiod -n istio-system
helm delete istio-base -n istio-system

kubectl delete namespace istio-system

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。

原始发表:2023-07-10,如有侵权请联系 cloudcommunity@tencent.com 删除


1 Service Mesh概述

微服务架构可谓是当前软件开发领域的技术热点,它在各种博客、社交媒体和会议演讲上的出镜率非常之高,无论是做基础架构还是做业务系统的工程师,对微服务都相当关注,而这个现象与热度到目前为止,已经持续了近 5 年之久。

尤其是近些年来,微服务架构逐渐发展成熟,从最初的星星之火到现在的大规模的落地与实践,几乎已经成为分布式环境下的首选架构。微服务成为时下技术热点,大量互联网公司都在做微服务架构的落地和推广。同时,也有很多传统企业基于微服务和容器,在做互联网技术转型。

而在这个技术转型中,国内有一个趋势,以 Spring Cloud 与 Dubbo 为代表的微服务开发框架非常普及和受欢迎。然而软件开发没有银弹,基于这些传统微服务框架构建的应用系统在享受其优势的同时,痛点也越加明显。这些痛点包括但不限于以下几点:

  • 侵入性强。想要集成 SDK 的能力,除了需要添加相关依赖,往往还需要在业务代码中增加一部分的代码、或注解、或配置;业务代码与治理层代码界限不清晰。

  • 升级成本高。每次升级都需要业务应用修改 SDK 版本,重新进行功能回归测试,并且对每一台机器进行部署上线,而这对于业务方来说,与业务的快速迭代开发是有冲突的,大多不愿意停下来做这些与业务目标不太相关的事情。

  • 版本碎片化严重。由于升级成本高,而中间件却不会停止向前发展的步伐,久而久之,就会导致线上不同服务引用的 SDK 版本不统一、能力参差不齐,造成很难统一治理。

  • 中间件演变困难。由于版本碎片化严重,导致中间件向前演进的过程中就需要在代码中兼容各种各样的老版本逻辑,带着 “枷锁” 前行,无法实现快速迭代。

  • 内容多、门槛高。Spring Cloud 被称为微服务治理的全家桶,包含大大小小几十个组件,内容相当之多,往往需要几年时间去熟悉其中的关键组件。而要想使用 Spring Cloud 作为完整的治理框架,则需要深入了解其中原理与实现,否则遇到问题还是很难定位。

  • 治理功能不全。不同于 RPC 框架,Spring Cloud 作为治理全家桶的典型,也不是万能的,诸如协议转换支持、多重授权机制、动态请求路由、故障注入、灰度发布等高级功能并没有覆盖到。而这些功能往往是企业大规模落地不可获缺的功能,因此公司往往还需要投入其它人力进行相关功能的自研或者调研其它组件作为补充。

以上列出了传统微服务框架的局限性,但这并不意味着它们就一无是处了。在中小企业,采用 Spring Cloud 这样的传统微服务框架已经可以满足绝大部分服务治理的需求,并且借此快速推进微服务化改造。这些痛点往往是技术发展到一定的程度必然要经历的阶段,这些痛点促使技术不断发展、不断前进。

2 什么是服务网格?

在过去的几十年中,我们已经看到了单体应用程序开始拆分为较小的应用程序。此外,诸如Docker之类的容器化技术和诸如Kubernetes之类的编排系统加速了这一变化。

尽管在像Kubernetes这样的分布式系统上采用微服务架构有许多优势,但它也具有相当的复杂性。由于分布式服务必须相互通信,因此我们必须考虑发现,路由,重试和故障转移。

还有其他一些问题,例如安全性和可观察性,我们还必须注意以下问题:

现在,在每个服务中建立这些通信功能可能非常繁琐,尤其是当服务范围扩大且通信变得复杂时,更是如此。这正是服务网格可以为我们提供帮助的地方。基本上,服务网格消除了在分布式软件系统中管理所有服务到服务通信的责任;

服务网格能够通过一组网络代理来做到这一点。本质上,服务之间的请求是通过与服务一起运行但位于基础结构层之外的代理路由的:

这些代理基本上为服务创建了一个网状网络——因此得名为服务网格!通过这些代理,服务网格能够控制服务到服务通信的各个方面。这样,我们可以使用它来解决分布式计算的八个谬误,这是一组断言,描述了我们经常对分布式应用程序做出的错误假设。

3 服务网格特征

现在,让我们了解服务网格可以为我们提供的一些功能。请注意,实际功能列表取决于服务网格的实现。但是,总的来说,我们应该在所有实现中都期望其中大多数功能。

我们可以将这些功能大致分为三类:流量管理,安全性和可观察性。

3.1 流量管理

服务网格的基本特征之一是流量管理。这包括动态服务发现和路由。尤其影子流量和流量拆分功能,这些对于实现金丝雀发布和A/B测试非常有用。

由于所有服务之间的通信都是由服务网格处理的,因此它还启用了一些可靠性功能。例如,服务网格可以提供重试,超时,速率限制和断路器。这些现成的故障恢复功能使通信更加可靠。

3.2 安全性

服务网格通常还处理服务到服务通信的安全性方面。这包括通过双向TLS(mTLS)强制进行流量加密,通过证书验证提供身份验证以及通过访问策略确保授权。
服务网格中还可能存在一些有趣的安全用例。例如,我们可以实现网络分段,从而允许某些服务进行通信而禁止其他服务。而且,服务网格可以为审核需求提供精确的历史信息。

3.3 可观察性

强大的可观察性是处理分布式系统复杂性的基本要求。由于服务网格可以处理所有通信,因此正确放置了它可以提供可观察性的功能。例如,它可以提供有关分布式追踪的信息。
服务网格可以生成许多指标,例如延迟,流量,错误和饱和度。此外,服务网格还可以生成访问日志,为每个请求提供完整记录。这些对于理解单个服务以及整个系统的行为非常有用。

4 Istio简介

Istio是最初由IBM,Google和Lyft开发的服务网格的开源实现。它可以透明地分层到分布式应用程序上,并提供服务网格的所有优点,例如流量管理,安全性和可观察性。

它旨在与各种部署配合使用,例如本地部署,云托管,Kubernetes容器以及虚拟机上运行的服务程序。尽管Istio与平台无关,但它经常与Kubernetes平台上部署的微服务一起使用。

从根本上讲, Istio的工作原理是以Sidcar形式将Envoy的扩展版本作为代理布署到每个微服务中:

该代理网络构成了Istio架构的数据平面,这些代理的配置和管理是从控制平面完成的:

控制平面基本上是服务网格的大脑。它为数据平面中的Envoy代理提供发现,配置和证书管理。
    当然,只有在拥有大量相互通信的微服务时,我们才能体现Istio的优势。在这里,sidecar代理在专用的基础架构层中形成一个复杂的服务网格:

Istio在与外部库和平台集成方面非常灵活,例如,我们可以将Istio与外部日志记录平台,遥测或策略系统集成。

5 Istio组件

我们已经看到,Istio体系结构由数据平面和控制平面组成。此外,还有几个使Istio起作用的核心组件。

在本节中,我们将详细介绍这些核心组件;

5.1 数据平面

Istio的数据平面主要包括Envoy代理的扩展版本。Envoy是一个开源边缘和服务代理,可帮助将网络问题与底层应用程序分离开来。应用程序仅向localhost发送消息或从localhost接收消息,而无需了解网络拓扑。

Envoy的核心是在OSI模型的L3和L4层运行的网络代理。它通过使用可插入网络过滤器链来执行连接处理。此外,Envoy支持用于基于HTTP的流量的附加L7层过滤器。而且,Envoy对HTTP/2和gRPC传输具有一流的支持。

Istio作为服务网格提供的许多功能实际上是由Envoy代理的基础内置功能启用的:

  • 流量控制:Envoy通过HTTP,gRPC,WebSocket和TCP流量的丰富路由规则启用细粒度的流量控制应用;

  • 网络弹性:Envoy包括对自动重试,断路和故障注入的开箱即用支持;

  • 安全性:Envoy还可以实施安全策略,并对基础服务之间的通信应用访问控制和速率限制;

Envoy在Istio上表现出色的另一个原因之一是它的可扩展性。Envoy提供了基于WebAssembly的可插拔扩展模型。这在定制策略执行和遥测生成中非常有用。此外,我们还可以使用基于Proxy-Wasm沙箱API的Istio扩展在Istio中扩展Envoy代理。

5.2 控制面

如上所述,控制平面负责管理和配置数据平面中的Envoy代理。在Istio架构中,控制面核心组件是istiod,Istiod负责将高级路由规则和流量控制行为转换为特定于Envoy的配置,并在运行时将其传播到Sidercar。

如果我们回顾一下Istio控制平面的架构,将会注意到它曾经是一组相互协作的独立组件。它包括诸如用于服务发现的Pilot,用于配置的Galley,用于证书生成的Citadel以及用于可扩展性的Mixer之类的组件。由于复杂性,这些单独的组件被合并为一个称为istiod的单个组件。

从根本上来说,istiod仍使用与先前各个组件相同的代码和API。例如,Pilot负责抽象特定于平台的服务发现机制,并将其合成为Sidecar可以使用的标准格式。因此,Istio可以支持针对多个环境(例如Kubernetes或虚拟机)的发现。

此外,istiod还提供安全性,通过内置的身份和凭据管理实现强大的服务到服务和最终用户身份验证。此外,借助istiod,我们可以基于服务身份来实施安全策略。该过程也充当证书颁发机构(CA)并生成证书,以促进数据平面中的相互TLS(MTLS)通信。

6 Istio工作原理

我们已经了解了服务网格的典型特征是什么。此外,我们介绍了Istio架构及其核心组件的基础。现在,是时候了解Istio如何通过其架构中的核心组件提供这些功能了;

我们将专注于我们之前经历过的相同类别的功能;

6.1 流量管理

我们可以使用Istio流量管理API对服务网格中的流量进行精细控制。我们可以使用这些API将自己的流量配置添加到Istio。此外,我们可以使用Kubernetes自定义资源定义(CRD)定义API资源。帮助我们控制流量路由的关键API资源是虚拟服务和目标规则:

微服务应用最大的痛点就是处理服务间的通信,而这一问题的核心其实就是流量管理。首先我们来看看传统的微服务应用在没有 Service Mesh 介入的情况下,是如何完成诸如金丝雀发布这样的路由功能的。我们假设不借助任何现成的第三方框架,一个最简单的实现方法,就是在服务间添加一个负载均衡(比如 Nginx)做代理,通过修改配置的权重来分配流量。这种方式使得对流量的管理和基础设施绑定在了一起,难以维护。

而使用 Istio 就可以轻松的实现各种维度的流量控制。下图是典型的金丝雀发布策略:根据权重把 5% 的流量路由给新版本,如果服务正常,再逐渐转移更多的流量到新版本。

基本上,虚拟服务使我们可以配置如何将请求路由到Istio服务网格中的服务。因此,虚拟服务由一个或多个按顺序评估的路由规则组成。评估虚拟服务的路由规则后,将应用目标规则。目标规则有助于我们控制到达目标的流量,例如,按版本对服务实例进行分组。

Istio 中的流量控制功能主要分为三个方面:

  • 请求路由和流量转移

  • 弹性功能,包括熔断、超时、重试

  • 调试能力,包括故障注入和流量镜像

6.2 安全性

Istio为每个服务提供身份。与每个Envoy代理一起运行的Istio代理与istiod一起使用以自动进行密钥和证书轮换:

Istio提供两种身份验证——对等身份验证和请求身份验证。对等身份验证用于服务到服务的身份验证,其中Istio提供双向TLS作为全栈解决方案。请求身份验证用于最终用户身份验证,其中Istio使用自定义身份验证提供程序或OpenID Connect(OIDC)提供程序提供JSON Web令牌(JWT)验证。

Istio还允许我们通过简单地将授权策略应用于服务来实施对服务的访问控制。授权策略对Envoy代理中的入站流量实施访问控制。这样,我们就可以在各种级别上应用访问控制:网格,命名空间和服务范围。

6.3 可观察性

Istio为网格网络内的所有服务通信生成详细的遥测,例如度量,分布式跟踪和访问日志。Istio生成一组丰富的代理级指标,面向服务的指标和控制平面指标。

之前,Istio遥测体系结构将Mixer作为核心组件。但是从Telemetry v2开始,混音器提供的功能已替换为Envoy代理插件:

此外,Istio通过Envoy代理生成分布式跟踪。Istio支持许多跟踪后端,例如Zipkin,Jaeger,Lightstep和Datadog。我们还可以控制跟踪速率的采样率。此外,Istio还以一组可配置的格式生成服务流量的访问日志。

7 Istio实战

上面我们已经讲述了Istio原理和架构,接下来我们开始实战部分。首先,我们将在Kubernetes集群中安装Istio。此外,我们将使用一个简单的基于微服务的应用程序来演示Istio在Kubernetes上的功能。

7.1 安装

有多种安装Istio的方法,但最简单的方法是下载并解压缩特定操作系统(例如Windows)的最新版本。提取的软件包在bin目录中包含istioctl客户端二进制文件。我们可以使用istioctl在目标Kubernetes集群上安装Istio:

代码语言:javascript

复制

istioctl install --set profile=demo -y

这会使用演示配置文件将Istio组件安装在默认的Kubernetes集群上。我们还可以使用任何其他特定于供应商的配置文件来代替演示;

最后,当我们在此Kubernetes集群上部署任何应用程序时,我们需要指示Istio自动注入Envoy sidecar代理:

代码语言:javascript

复制

kubectl label namespace default istio-injection=enabled

我们在这里使用kubectl的前提是,我们的机器上已经有像Minikube这样的Kubernetes集群和Kubernetes CLI kubectl。

7.2 示例应用

为了演示,我们将想象一个非常简单的在线下订单应用程序。该应用程序包含三个微服务,它们相互交互以满足最终用户的订购请求:

我们没有讨论这些微服务的细节,但是使用Spring Boot和REST API可以很简单地创建它们。最重要的是,我们为这些微服务创建了一个Docker镜像,以便我们可以将它们部署在Kubernetes上;

7.3 部署

在像Minikube这样的Kubernetes集群上部署容器化的工作负载非常简单。我们将使用Deployment和Service资源类型来声明和访问工作负载。通常,我们在YAML文件中定义它们:

代码语言:javascript

复制

apiVersion: apps/v1beta1kind: Deploymentmetadata:
  name: order-service  namespace: defaultspec:
  replicas: 1
  template:
    metadata:
      labels:
        app: order-service        version: v1    spec:
      containers:
      - name: order-service        image: kchandrakant/order-service:v1        resources:
          requests:
            cpu: 0.1
            memory: 200---apiVersion: v1kind: Servicemetadata:
  name: order-servicespec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http  selector:
    app: order-service

对于订单服务的“部署和服务”,这是一个非常简单的定义。同样,我们可以为库存服务和运输服务定义YAML文件;

使用kubectl部署这些资源也非常简单:

代码语言:javascript

复制

kubectl apply -f booking-service.yaml -f inventory-service.yaml -f shipping-service.yaml

由于我们已经为默认命名空间启用了自动注入Envoy sidecar代理,因此一切都会由istiod来处理。或者,我们可以使用istioctl的kube-inject命令手动注入Envoy sidecar代理。

7.4 访问应用

现在,Istio主要负责处理所有的网状网络流量。因此,默认情况下,不允许进出网格的任何流量。Istio使用网关来管理来自网格的入站和出站流量。这样,我们可以精确地控制进入或离开网格的流量。Istio提供了一些预配置的网关代理部署:istio-ingressgateway和istio-egressgateway。

我们将为我们的应用程序创建一个网关和一个虚拟服务来实现此目的:

代码语言:javascript

复制

apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata:
  name: booking-gatewayspec:
  selector:
    istio: ingressgateway  servers:
  - port:
      number: 80
      name: http      protocol: HTTP
    hosts:
    - "*"---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:
  name: bookingspec:
  hosts:
  - "*"
  gateways:
  - booking-gateway  http:
  - match:
    - uri:
        prefix: /api/v1/booking    route:
    - destination:
        host: booking-service        port:
          number: 8080

在这里,我们利用了Istio提供的默认入口控制器。此外,我们已经定义了一个虚拟服务,将我们的请求路由到预订服务。

同样,我们也可以为来自网格的出站流量定义出口网关;

8 Istio的常见案例

现在,我们已经看到了如何使用Istio在Kubernetes上部署一个简单的应用程序。但是,我们仍然没有利用Istio为我们启用的任何有趣功能。在本节中,我们将介绍服务网格的一些常见用例,并了解如何使用Istio为我们的简单应用程序实现它们。

8.1 请求路由

我们可能要以特定方式处理请求路由的原因有多个。例如,我们可能会部署微服务的多个版本,例如运输服务,并希望仅将一小部分请求路由到新版本;

我们可以使用虚拟服务的路由规则来实现这一点:

代码语言:javascript

复制

apiVersion: networking.istio.io/v1alpha3apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:
  name: shipping-servicespec:
  hosts:
    - shipping-service  http:
  - route:
    - destination:
        host: shipping-service        subset: v1      weight: 90
    - destination:
        host: shipping-service        subset: v2      weight: 10---apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata:
  name: shipping-servicespec:
  host: shipping-service  subsets:
  - name: v1    labels:
      version: v1  - name: v2    labels:
      version: v2

路由规则还允许我们基于诸如header参数之类的属性来定义匹配条件。此外,目的地字段指定与条件匹配的流量的实际目的地;

8.2 熔断

熔断器基本上是一种软件设计模式,用于检测故障并封装防止故障进一步级联的逻辑。这有助于创建有弹性的微服务应用程序,以限制故障和延迟尖峰的影响。

在Istio中,我们可以使用DestinationRule中的trafficPolicy配置在调用诸如清单服务之类的服务时应用熔断:

代码语言:javascript

复制

apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata:
  name: inventory-servicespec:
  host: inventory-service  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 1
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 1
    outlierDetection:
      consecutive5xxErrors: 1
      interval: 1s      baseEjectionTime: 3m      maxEjectionPercent: 100

在这里,我们将DestinationRule配置为maxConnections为1,httpMaxPendingRequests为1,maxRequestsPerConnection为1。这实际上意味着,如果我们将并发请求数超过1,熔断器将开始trap一些请求。

8.3 启用双向TLS

双向身份验证是指双方在诸如TLS之类的身份验证协议中同时相互进行身份验证的情况。默认情况下,具有代理的服务之间的所有流量在Istio中都使用相互TLS。但是,没有代理的服务仍继续以纯文本格式接收流量。

虽然Istio将具有代理的服务之间的所有流量自动升级为双向TLS,但这些服务仍可以接收纯文本流量。我们可以选择使用PeerAuthentication策略在整个网格范围内实施双向TLS:

代码语言:javascript

复制

apiVersion: "security.istio.io/v1beta1"kind: "PeerAuthentication"metadata:
  name: "default"
  namespace: "istio-system"spec:
  mtls:
    mode: STRICT

我们还提供了对每个命名空间或服务而不是在网格范围内强制实施双向TLS的选项。但是,特定于服务的PeerAuthentication策略优先于命名空间范围的策略。

8.4 使用JWT进行访问控制

JSON Web令牌(JWT)是用于创建数据的标准,该数据的有效载荷中包含声明许多声明的JSON。为了在身份提供者和服务提供者之间传递经过身份验证的用户的身份和标准或自定义声明,这一点已被广泛接受。

我们可以在Istio中启用授权策略,以允许访问基于JWT的预订服务之类的服务:

代码语言:javascript

复制

apiVersion: security.istio.io/v1beta1kind: AuthorizationPolicymetadata:
  name: require-jwt  namespace: defaultspec:
  selector:
    matchLabels:
      app: booking-service  action: ALLOW
  rules:
  - from:
    - source:
       requestPrincipals: ["testing@baeldung.com/testing@baeldung.io"]

在这里,AuthorizationPolicy强制所有请求具有有效的JWT,并将requestPrincipal设置为特定值。Istio通过组合声明JWT的iss和sub来创建requestPrincipal属性;

9 思考

因此,到目前为止,我们已经看到像Istio这样的服务网格如何使我们更轻松地处理诸如微服务之类的分布式架构中的许多常见问题。但是尽管如此,Istio还是一个复杂的系统,会增加最终部署的复杂性。与其他所有技术一样,Istio并非灵丹妙药,必须谨慎使用。

9.1 我们应该始终使用服务网格吗?

尽管我们已经看到了使用服务网格的足够理由,但下面列举了一些可能促使我们不使用它的原因:

  • 服务网格处理所有服务到服务的通信,而部署和操作服务网格则需要支付额外的费用。对于较简单的应用程序,这可能是不合理的

  • 由于我们已经习惯于处理一些此类问题,例如应用程序代码中的熔断,因此可能导致服务网格中的重复处理

  • 越来越依赖于诸如服务网格之类的外部系统可能会损害应用程序的可移植性,尤其是因为没有针对服务网格的行业标准

  • 由于服务网格通常通过拦截通过代理的网格流量来工作,因此它可能会给请求增加不希望的延迟

  • 服务网格增加了许多其他组件和配置,需要精确处理。这需要专业知识,并增加了学习曲线

  • 最后,我们可能最终将操作逻辑(应在服务网格中存在)与业务逻辑(不应在服务网格中)混合在一起

因此,正如我们所看到的,服务网格的故事不仅仅涉及好处,但这并不意味着它们不是真的。对我们来说,重要的是要仔细评估我们的需求和应用程序的复杂性,然后权衡服务网格的好处和它们所增加的复杂性;

9.2 Istio的替代品有哪些?

尽管Istio非常受欢迎,并得到了业内一些领导者的支持,但它当然不是唯一的选择。尽管我们在这里无法进行全面的比较,但让我们看一下Linkerd和Consul这两个选项。
Linkerd是已为Kubernetes平台创建的开源服务网格。它也很受欢迎,目前在CNCF中具有孵化项目的地位。它的工作原理类似于Istio等任何其他服务网格。它还利用TCP代理来处理网格流量。Linkerd使用用Rust编写的微型代理,称为Linkerd代理。

总体而言,Linkerd并不比Istio复杂,因为它仅支持Kubernetes。但是,除此之外,Linkerd中可用的功能列表与Istio中可用的功能非常相似。Linkerd的核心架构也非常类似于Istio。基本上,Linkerd包含三个主要组件:用户界面,数据平面和控制平面。

Consul是HashiCorp的服务网格的开源实现。它的好处是可以与HashiCorp的其他基础架构管理产品套件很好地集成,以提供更广泛的功能。Consul中的数据平面可以灵活地支持代理以及本机集成模型。它带有内置代理,但也可以与Envoy一起使用。

除了Kubernetes,Consul还可以与Nomad等其他平台一起使用。Consul通过在每个节点上运行Consul代理以执行运行状况检查来工作。这些代理与一台或多台存储和复制数据的Consul服务器通信。尽管它提供了服务网格(如Istio)的所有标准功能,但它是部署和管理的更复杂的系统。

译文链接:https://zhuanlan.zhihu.com/p/369068128

https://www.servicemesher.com/istio-handbook/concepts/pilot.html

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。


ERP进入低代码时代,明源云开放平台3.0重构房地产应用底层架构

开放”是房地产数字化建设的“火种”!明源云ERP开放平台负责人刘翔的这句话,形象地概括了房地产在信息技术领域,尤其在底层架构方面的重要变化。

过去,企业把ERP大多部署在自己的数据中心,更强调专有、私密等特性。在数字化转型浪潮的推动下,很多企业开始思考转型,在生态和应用层面进行源代码开放,但却没有真正改变软件的交付模式,无法快速满足企业的业务需求。直到DevOps、微服务架构、kubernetes容器化技术及相关解决方案出现,企业才找到解决服务割裂的秘密武器。

明源云开放平台3.0平台全新发布

近日,房地产行业数字化转型领导厂商明源云宣布,明源云开放平台3.0平台正式上线。该平台是业内首个颠覆传统IT架构的企业级低代码应用平台(LCAP),拥有“三高一开放”特性,是高性能、高稳定、高安全、最开放的技术平台。明源云开放平台3.0实现了各个层面的升级,包括建模平台、集成平台、流程中心和研发协同平台的升级。

▲端到端的在线研发协同

明源云建模平台是源数据驱动的低代码开发平台,具备可视化、参数化、模板化建模能力以及大量行业属性组件,通过WebIDE在线编码保障开发效率、质量,同时提供微应用开发框架构建高效、稳定的服务API,旨在为企业定制与创新提供低成本的应用搭建解决方案。

明源云集成平台(MIP)是一款全栈式应用集成平台,提供轻量化的API、事件、消息、数据集成能力,可以帮助用户以积木式、配置化的方式构建高可靠、高性能、低延迟的应用集成解决方案,实现企业云上云下、不同厂商、不同架构、不同协议的应用互联互通,并且平台还提供可视化的运维管理、实时的运维监控,保障集成交付上线后能够持续、健康运行。

流程中心则重构了BPM业务,以插件式的方式进行扩展,实现企业跨业务、部门以及端到端的流程管控,提升流程管理效率。流程管理中心的设计思路是,让设计可视化、过程可追踪、风险可预测、数据智能分析,进而统一管理企业流程,提高管理效率,提升资产利用率。

▲流程接入能力

明源云RDC(Research&Development Collaboration)是符合DevOps理念、规范、流程和标准的一站式研发协同平台,通过需求管理、原型设计、研发管理、测试服务、版本发布、在线更新等软件全生命周期、全流程在线化、可视化,为地产企业ERP的定制与创新提供端到端的交付能力,让企业只专注于价值交付,在提供交付效率的同时,保障交付质量,通过技术创新带动业务敏捷,助力地产企业的数字化转型。

全力拥抱ERP低代码时代

这几年,低代码以及无代码成为软件开发的另一股热潮,微软、SAP、Oracle、IBM等巨头企业都在极力拥抱这一新趋势。那么,这背后的驱动力是什么?ERP进入低代码时代,是否会成为主流趋势?

刘翔认为,效率和创新是推动企业进行技术变革的最根本原因。在Gartner的一份研究中显示,通过低代码平台、无代码平台或者第四代开发语言来构建部门级/企业级/公共应用的最终用户,已越来越多。从业务角度处理问题,以组件、积木式方式构建代码,企业应用的开发速度可以达到传统信息化构建效率的5倍以上。

基于低代码/无代码平台,业务人员也可以进入应用开发领域。当企业应用构建速度一旦提升,反映到企业信息化建设上面,会有两大表现:一方面,是解决业务问题;另一方面,也是最重要的原因,就是极大地降低了业务创新的试错成本,改变了企业业务创新和变更的速度,从而达到技术驱动业务的目标。

明源云结合低代码平台开发思路,构建了一整套DevOps持续交付解决方案,从需求、代码、测试、发布各个层面,全面提升了开放和协同能力,基于研发协同平台明源方、客户方IT等产品,ODC伙伴也可以提供有序、高质的交付服务。

对比传统ERP服务平台,明源云开放平台3.0可以支持企业级低代码应用开放的全场景服务。

首先,面向应用开放。提供建模平台,可以提供托拉拽、编码两种方式在线构建应用;

其次,面向流程集成。基于BPMN2.0规范全面升级的流程中心,明源云开放平台3.0沉淀了地产多年来的表单引擎、流程引擎,结合流程效率分析(IATQ指数)等,未来在统一流程基础上,可以让企业获得更好的洞察力,提升组织效率;

其三,面向数据分析。在ETL/BI工具的基础上,统一梳理和建立了ERP级数据服务中心,从CXO视角来看,可以提供全价值的数据分析和洞察力;

其四,面向应用集成。信息孤岛、服务割裂现象一直是传统IT系统集成的痛点,明源云结合微服务理念,在注册中心构建了一层广连接的连接中心,可以把通用的、常见的厂商自连接起来,通过API网关、Event事件中心提供了统一的集成和开放能力。

▲应用集成能力

低代码模式之所以能在明源云成功落地,是因为3.0平台在分布式、微服务、低代码层面做了增强和突破。明源云结合微服务架构思想,可以构建分布式的微应用,特别是在网关层、服务层、数据层都采用了分布式的技术来解决复杂的关系型系统的性能问题。

地产行业迎来无感知的技术架构改变

值得一提的是,明源云开放平台3.0并非只是为了拥抱时代变化,更多结合的是企业信息化现状,为有效推进地产行业数字化转型赋能。

▲应用定制能力

其实,在地产行业,大部分还处于”信息化-在线化”的路上,小部分处于”在线化-数字化”的阶段。也就是说,信息化还处于打地基阶段,再加上企业当前的信息化系统大部分都由其他厂商建设,并非同一技术栈或者同一平台构建,要想进行大而全的信息化改造和升级,成本和风险均不可控。所以,综合来看,这种小步快跑、逐步迭代的方式,是效果显著、最可能成功的路线。

在企业业务高速发展过程中,更换信息系统或者架构,无异于“飞机在空中飞行过程中换发动机”;但如果有了开放平台,就会给企业的数字化转型带来了新的火种,通过演进的思路逐步推进,而非完全推翻式创新,会让企业业务的稳定性多了一重保障。换言之,企业在逐步升级过程中,不断采用开放式的架构,企业信息系统的开放能力就会越来越强。当积累到一定程度,企业信息化的建设价值也就随之爆发了。

不管技术如何演进和升级,明源云希望给用户带来无感知体验。用户的无感,也是技术架构改变是否成功的最好验证指标。如果说有变化,那只有一点,就是3.0平台变得更快了,包括整体系统响应快了,一些特殊的操作(导入、批量操作)变快了,有些需求做起来更简单了。

对于地产行业用户来说,明源云开放平台3.0平台有三大优势:

第一,分布式的能力更明显了。一个是应用层面由传统的B/S架构,演变为支持高性能、高并发的分布式弹性架构,同时具备了服务治理的很多特性,整体上让服务的高可用有了更多保障。另外,数据库层面是分库,兼顾了后台关系型复杂的业务的问题,在应用层面、业务层面均有水平分库扩展能力,并且配合读写分离、工作单元等特性,数据库层面的分布式能力更有策略。还有,集中式的PaaS服务能力体现明显,特别是文档服务、调度服务、日志服务、缓存服务等PaaS形态,让集中式的计算业务拥有更强的并行处理和分布式能力。

第二、集成能力更为广泛了。过去那种废弃了的ESB总线模式,是基于微服务的服务发现、服务注册封装的连接中心,可以发现更多的不同厂商、不同架构、不同协议的服务提供商,基于客户IT整体视角的集成能力,让存量和增量的信息化能力得到了全面的统一和复用。最重要的是,数据、业务、消息三种维度的能力梳理、编排、输出,企业的信息化转向数字化的过程中包袱少了许多,创新的成本和试错的代价降低了不少。

第三、合作共赢的开放方式更健康了。这种平台化的生态合作,表面看变得有所束缚,其实更多的是售后的保障,基于同一个研发协同、同一个质量体系、同一个资产沉淀的生态协同,客户IT团队、明源项目团队、第三方合作伙伴,均以客户为中心提供高效率、高质量的服务,真正做到在双方约束、双方共建的前提下,进行可持续合作。

可以预测,ERP进入低代码时代,或许会成为一种主流发展趋势。而在房地产企业加速变革、推动数字化转型的过程中,明源云开放平台3.0平台一定会带来更极致的体验!


背景:

       最近要开始做K3Cloud移动,BOS平台的移动单据收费,就想单独做移动模块,搭建环境:后台SSH2,前端Android。在手机端登录时通过Ajax方式传递用户名和密码到后台校验,后台在去K3Cloud的数据库中进行匹配,那么问题来了!数据库中的密码是经过SHA1加密的,要匹配首先得先把手机客户端传过来的密码加密。呵呵……金蝶的加密方式我们不得而知,就算知道,在Java平台不一定能搞出来,我今天研究了一天发现结果对不上,最后放弃了,决定试试用Java调C#的方法去直接调用K3Cloud封装好的加密工具类。


说了这么多那我们开始吧:


环境、工具:


1、VS 2012


2、eclipse、tomcat


3、Jacob-1.18-M2


一、制作COM组建


1、先创建项目,选择window类库,起名随便哈!


using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Runtime.InteropServices;

using Kingdee.BOS.Util;

using Kingdee.BOS;

 

namespace TestCom

{

    [Guid("E9BCF867-CD81-40d0-9591-ED28D1ED2B53")]

    public interface IEncrypt

    {

        [DispId(1)]

        string GetEncrypt(string str, string str2);

    }

    [Guid("33A6E58D-E1F5-4b53-B2E2-03B9F8BA2FAD"), ClassInterface(ClassInterfaceType.None)]

    public class Encrypt : IEncrypt

    {

        public Encrypt() { }

 

        public string GetEncrypt(string passWord, string salt)

        {

            string pwd = ConfidentialDataSecurityUtil.GenSecurityPW(passWord, salt);

            return pwd;

        }

    }

}

Guid的生成:打开Visual Studio Command Prompt 输入guidgen 命令调出工具。类型选择Registry Format,点击New Guid,然后COPY出来。


[DispId(1)]为函数的标识。如果有多个函数可相应的在函数前面加[DispId(2)], [DispId(3)]…



2、在项目上右击选择属性,选择页签应用程序集-->程序集信息-->勾选“使程序集COM可见”,然后在切换页签到生成-->勾选“为COM互操作注册”。




3、设置强名称:打开Visual Studio Command Prompt 输入:sn -k TestComkey.snk 生成TestComkey.snk 签名文件。


注意:如果项目中引用了其他没有源码的dll文件,并且此dll文件是没有强名称的程序集,则编译时会出现类似 "Assembly generation failed -- 引用的程序集 'Kingdee.BOS.dll' 没有强名称" 这样的错误。

我这里引用的是Kingdee.BOS.dll程序集,它不是强名称的,则需要进行以下操作:


先将K3Cloud站点WebSide目录bin下的Kingdee.BOS.dll文件复制出来放到Visual Studio Command Prompt命令工具的目录。


1.打开打开Visual Studio Command Prompt命令提示窗口;


2.创建一个新的随机密钥对:

sn -k Kingdee.BOS.snk

3.反编译目标程序集

ildasm Kingdee.BOS.dll /out=Kingdee.BOS.il

3.重新编译,附带强命名参数

ilasm Kingdee.BOS.il /dll /resource=Kingdee.BOS.res /key=Kingdee.BOS.snk /optimize

4.验证签名信息

sn -v Kingdee.BOS.dll


OK,将生成的dll文件重新引入到项目中然后编译。

4、注册TestComkey.snk签名文件:项目--属性--签名,选择刚才生成的TestComkey.snk 文件



注册完后编译项目,会在Debug目录中会生成 TestCom.dll 和TestCom.tlb。


5、手工注册COM:


打开Visual Studio Command Prompt进入Debug目录,运行命令注册:


regasm TestCom.dll /tlb:TestCom.tlb


gacutil -i TestCom.dll (执行这个命令需要TestCom.dll 具有强名称)


gacutil -i Kingdee.BOS.dll (执行这个命令需要TestCom.dll 具有强名称)


二、java 调用 Com


部署jacob

1、在开发环境中引入jacob.jar 

2、拷贝jacob-1.18-M2-x64.dll 文件到 C:\Windows\System32目录,如果是Web应用的话还需要拷贝到jdk1.6.0_13\bin目录(jdk安装目录下的bin目录)


3、新建Java类:


package com.fanfan.demo;

import com.jacob.activeX.ActiveXComponent;

import com.jacob.com.Dispatch;

import com.jacob.com.Variant;

 

public class test {

 

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

try{

            ActiveXComponent dotnetCom = null;

            dotnetCom = new ActiveXComponent("TestCom.Encrypt");

            Variant var = Dispatch.call(dotnetCom,"GetEncrypt","000000","0002e61f1354ca2b837311e46ad9f343d545");

            String str  = var.toString(); //返回值

            System.out.println(str);

        } catch (Exception ex) {

            ex.printStackTrace();

        }

}

 

}


Dispatch.call(dotnetCom,"GetEncrypt","000000","0002e61f1354ca2b837311e46ad9f343d545");

00000就是我的密码,"0002e61f1354ca2b837311e46ad9f343d545"是密码调料,至于啥是密码调料我不知道,反正K3Cloud框架是这么注释的,这个可以通过用户名去查找FMEMO字段获取,每次更改密码这个会变,可以再写个方法专门获取salt。

运行Java代码,控制台输出了000000加密后的密码,然后就可以通过JDBD或者Hibernate访问数据库进行密码匹配了。


效果图:





OK!终于搞定了,老板在也不用担心收费的问题了,直接操作数据库,想干啥干啥。

————————————————


                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

                        

原文链接:https://blog.csdn.net/fyq891014/article/details/41595729