作者:王飞龙(不物)

目前 Kubernetes 现已成为业界容器编列系统的事实规范,根据 Kubernetes 的云原生运用生态(Helm, Istio, Knative, Kubeflow, Spark on Kubernetes 等)更是让 Kubernetes 成为云操作系统。在这样的背景下,Serverless 容器成为现有 Container as a Service 的进化方向之一,一方面经过 Serverless 方法根本性处理了Kubernetes 自身的办理复杂性,让用户无需受困于Kubernetes 集群容量规划、安全维护、故障诊断;另一方面也进一步释放了云计算的才能,将安全、可用性、可伸缩性等需求由基础设施完结。

ASK 作为阿里云 Serverless Kubernetes 渠道 [ 1] ,不只有免运维、秒级弹性、超大 Pod 容量、弹性预测等重磅才能,更重要的是它依然是一个规范 Kubernetes 渠道。

本文会经过在 ASK 上试用 Istio 布置微服务运用的方法,来验证 ASK 对规范 Kubernetes 的兼容性。Istio 作为 Service Mesh(服务网格)的领导处理方案,一方面本身足够复杂具有代表性,另一方面它也代表了云原生时代微服务架构的趋势具有参考含义。

现在就让我们开端吧!

创立集群

试用 Istio 前,需求准备一个 ASK 集群。登录阿里云操控台,挑选产品与服务>容器服务Kubernetes版,在左侧边栏挑选集群进入集群列表页面。点击右上角创立集群开端创立集群,装备集群参数如下:

  • 集群称号:hello-istio
  • 集群标准:Pro 版
  • 地域:美国(硅谷)
  • 付费类型:按量付费
  • Kubernetes 版别:1.20.11-aliyun.1
  • 专有网络:主动创立
  • Service CIDR:172.21.0.0/20
  • API Server 拜访:规范型I(slb.s2.small)
  • 运用 EIP 暴露 API Server:是
  • 时区:Aisa/Shanghai(UTC+08:00)
  • 服务发现:CoreDNS
  • 运用日志服务:创立新 Project

承认装备后点击创立集群进入等候集群创立完结。Istio 依靠 DNS 服务,这儿挑选创立集群时默认装置 CoreDNS 组件。

基于阿里云 ASK 的 Istio 微服务应用部署初探

集群创立完结后,进入集群列表> hello-istio >概况>集群信息>连接信息页面,仿制公网拜访内容到本地/tmp/kube/config 文件,并经过如下指令装备好 kubelet:

$ export KUBECONFIG=/tmp/kube/config

试用 Istio

kubectl 装备好后就可以开端在集群装置和试用 Istio。

下载 Istio

进入Istio 发布页面 [ 2] 下载针对操作系统的装置文件,也可以经过如下指令下载并提取最新版别:

$ curl -L https://istio.io/downloadIstio | sh -

由于我本机~/bin 目录已参加 PATH,这儿我将提取的 Istio 目录仿制~/bin 目录,并建好软链接。

$ cp istio-1.13.3 ~/bin
$ cd ~/bin
$ ln -s istio-1.13.3/bin/istioctl
$ ls -al ~/bin/
total 28
drwxr-xr-x   5 feilong.wfl staff   160  5  4 22:40 ./
drwxr-xr-x+ 95 feilong.wfl staff  3040  5  8 22:30 ../
drwxr-x---   9 feilong.wfl staff   288  4 15 00:48 istio-1.13.3/
lrwxr-xr-x   1 feilong.wfl staff    25  5  4 22:40 istioctl -> istio-1.13.3/bin/istioctl*

如果 istioctl –help 指令输出正常,则 istioctl 已正确装备。

装置 Istio

  1. 本次装置采用demoprofile [ 3] ,它包括了一组专为测验准备的功用集合,别的还有用户生产或性能测验的装备组合。
$ istioctl install --set profile=demo -y
✔ Istio core installed
✔ Istiod installed
✔ Egress gateways installed
✔ Ingress gateways installed
✔ Installation complete
  1. 给命名空间增加标签,指示 Istio 在布置运用的时候,主动注入 Envoy 边车署理:
$ kubectl label namespace default istio-injection=enabled
namespace/default labeled

布置示例运用

  1. 布置Bookinfo 示例运用 [ 4]
$ kubectl apply -f ~/bin/istio-1.13.3/samples/bookinfo/platform/kube/bookinfo.yaml
service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created
service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created
deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created
service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created
  1. 检查 Pod 已安排妥当:
$ kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
details-v1-79f774bdb9-t2jhq       2/2     Running   0          2m54s
productpage-v1-6b746f74dc-qc9lg   2/2     Running   0          2m46s
ratings-v1-b6994bb9-tmbh6         2/2     Running   0          2m51s
reviews-v1-545db77b95-xdhp4       2/2     Running   0          2m49s
reviews-v2-7bf8c9648f-4gn6f       2/2     Running   0          2m48s
reviews-v3-84779c7bbc-jfndj       2/2     Running   0          2m48s

要等候并保证一切的 Pod 到达此状况:安排妥当状况(READY)的值为 2/2 、状况(STATUS)的值为 Running。根据渠道的不同,这个操作过程可能会花费几分钟的时间。

  1. 检查 Service 已安排妥当:
$ kubectl get services
NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
details       ClusterIP   172.21.11.168   <none>        9080/TCP   59s
kubernetes    ClusterIP   172.21.0.1      <none>        443/TCP    33m
productpage   ClusterIP   172.21.0.124    <none>        9080/TCP   51s
ratings       ClusterIP   172.21.9.7      <none>        9080/TCP   57s
reviews       ClusterIP   172.21.13.223   <none>        9080/TCP   55s
  1. 保证网页服务正常。如果指令返回页面标题,则运用已在集群中运转。
$ kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -s productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>

对外敞开服务

现在,BookInfo 运用现已布置,但还不能被外界拜访。要敞开拜访,需求创立 Istio 入站网关(Ingress Gateway), 它会把一个途径路由到网格内的服务。

  1. 把运用关联到 Istio 网关:
$ kubectl apply -f ~/bin/istio-1.13.3/samples/bookinfo/networking/bookinfo-gateway.yaml
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created
  1. 保证装备文件没有问题:
$ istioctl analyze
✔ No validation issues found when analyzing namespace: default.

确定入站 IP 和端口

运用如下指令为拜访网关设置 INGRESS_HOST 和 INGRESS_PORT 两个变量

$ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
$ export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')

设置变量 GATEWAY_URL,并保证 IP 地址和端口均成功的赋值给了该变量:

$ export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
$ echo "$GATEWAY_URL"
47.88.21.82:80

验证外部拜访

运转下面指令,获取 Bookinfo 运用的外部拜访地址:

$ echo "http://$GATEWAY_URL/productpage"
http://47.88.21.82:80/productpage

仿制上面指令的输出地址到浏览器并拜访,承认 Bookinfo 现已完结了外部拜访。改写页面,发现 Book Reviews 的显现样式会不断改变。

基于阿里云 ASK 的 Istio 微服务应用部署初探

检查仪表盘

仪表盘能帮助了解服务网格的结构、展现网络的拓扑结构、剖析网格的健康状况。

  1. 首要装置 Kiali 和其他插件,等候布置完结。
$ kubectl apply -f ~/bin/istio-1.13.3/samples/addons
$ kubectl rollout status deployment/kiali -n istio-system
Waiting for deployment "kiali" rollout to finish: 0 of 1 updated replicas are available...
deployment "kiali" successfully rolled out
  1. 拜访 Kiali 仪表板。
$ istioctl dashboard kiali
  1. 在左侧的导航菜单,挑选 Graph,然后在 Namespace 下拉列表中,挑选 default

Kiali 仪表板展现了网格的概览、以及 Bookinfo 示例运用的各个服务之间的联系。它还提供过滤器来可视化流量的活动。

基于阿里云 ASK 的 Istio 微服务应用部署初探

增加默认方针规矩

运用 Istio 操控 Bookinfo 版别路由前,需求先在方针规矩 [ 5] 中界说好可用的版别。运转以下指令为 Bookinfo 服务创立默认的方针规矩:

$ kubectl apply -f ~/bin/istio-1.13.3/samples/bookinfo/networking/destination-rule-all.yaml
destinationrule.networking.istio.io/productpage created
destinationrule.networking.istio.io/reviews created
destinationrule.networking.istio.io/ratings created
destinationrule.networking.istio.io/details created

等候几秒钟,方针规矩生效。您可以运用如下指令检查方针规矩:

$ kubectl get destinationrules
NAME          HOST          AGE
details       details       30s
productpage   productpage   32s
ratings       ratings       31s
reviews       reviews       32s

路由一切流量到 v1 版别

运转以下指令创立 Virtual Service 将一切流量路由到微服务的 v1 版别:

$ kubectl apply -f ~/bin/istio-1.13.3/samples/bookinfo/networking/virtual-service-all-v1.yaml
virtualservice.networking.istio.io/productpage created
virtualservice.networking.istio.io/reviews created
virtualservice.networking.istio.io/ratings created
virtualservice.networking.istio.io/details created

您可以经过再次改写 Bookinfo 运用程序的/productpage 页面测验新装备。请注意,不管您改写多少次,页面的谈论部分都不会显现评级星标。这是由于当时已将 Istio 装备为谈论服务的一切流量路由到版别 reviews:v1,而此版别的服务不拜访星级评分服务。

根据用户身份的路由

接下来将更改路由装备,完结将来自特定用户的一切流量路由到特定的服务版别。示例中来自名为 Jason 用户的一切流量将被路由到服务 review:v2。

Istio 对用户身份没有任何特别的内置机制。本例中,productpage 服务在一切到 reviews 服务的 HTTP 恳求中都增加了一个自界说的 end-user 恳求头,从而到达效果。

  1. 运转以下指令以启用根据用户的路由:
$ kubectl apply -f ~/bin/istio-1.13.3/samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
virtualservice.networking.istio.io/reviews created
  1. 保证规矩已创立:
$ kubectl get virtualservice reviews -o yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"networking.istio.io/v1alpha3","kind":"VirtualService","metadata":{"annotations":{},"name":"reviews","namespace":"default"},"spec":{"hosts":["reviews"],"http":[{"match":[{"headers":{"end-user":{"exact":"jason"}}}],"route":[{"destination":{"host":"reviews","subset":"v2"}}]},{"route":[{"destination":{"host":"reviews","subset":"v1"}}]}]}}
  creationTimestamp: "2022-05-15T16:05:55Z"
  generation: 1
  name: reviews
  namespace: default
  resourceVersion: "1984849"
  uid: f3bd3dcb-d83c-4a75-9511-1fc9308ca05b
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1
  1. 在 Bookinfo 运用程序的/productpage 上,以用户 jason 身份登录。改写浏览器,看到每个谈论旁边显现星级评分。

基于阿里云 ASK 的 Istio 微服务应用部署初探

  1. 以其他用户身份登录,改写浏览器。发现星级评分消失了。

原理和限制

数据平面,Istio 经过向 Pod 注入的 Sidecar 署理(istio-proxy)来负责协谐和操控微服务之前的一切网络通信。为了让 Sidecar 署理(istio-proxy)劫持事务容器流量,Istio 需求向 Pod 所在网络下发 iptables 规矩。常规装置模式下,iptables 规矩下发是由 Istio 向 Pod 注入的初始化容器 istio-init 完结。向 Pod 网络下发 iptables 规矩需求容器可以运用 NET_ADMIN 和 NET_RAW 两个高权限的才能(Capabilities)。ASK 集群中这两个高权限才能受ASK Pod Security Policy [ 6] 和ECI Container Security Policy [ 7] 的影响。

ASK Pod Security Policy 的 CAPS 为 *,表示没有限制。

$ kubectl get psp
NAME             PRIV   CAPS   SELINUX    RUNASUSER   FSGROUP    SUPGROUP   READONLYROOTFS   VOLUMES
ack.privileged   true   *      RunAsAny   RunAsAny    RunAsAny   RunAsAny   false            *

ECI Container Security Policy 答应经过容器安全上下文装备即可。Istio 中 Pod 注入模板文件~/bin/istio-1.13.3/manifests/charts/istio-control/istio-discovery/files/injection-template.yaml 包括如下代码:不启用Istio CNI 插件 [ 8] 将增加 NET_ADMIN 和 NET_RAW 两个高权限才能:

securityContext:
  allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }}
  privileged: {{ .Values.global.proxy.privileged }}
  capabilities:
{{- if not .Values.istio_cni.enabled }}
    add:
    - NET_ADMIN
    - NET_RAW
{{- end }}
    drop:
    - ALL

所以从原理上剖析当时 ASK 集群运用 Istio 没有兼容性问题。

总结

本次在 ASK 上试用 Istio 这类高复杂度的软件,未发现兼容性问题。又从原理上正面剖析证明了产生兼容性问题的可能性较低。因而,ASK 对原生 Kubernetes 还是有着极好的兼容性。后续将在 ASK 集群上深入探究 Istio 其他功用,以进一步验证 ASK 对原生 Kubernetes 的兼容性。

参考链接:

[1]阿里云 Serverless Kubernetes

help.aliyun.com/document_de…

[2]Istio 发布页面

github.com/istio/istio…

[3] demoprofile**

istio.io/latest/docs…

[4]Bookinfo 示例运用

istio.io/latest/zh/d…

[5]方针规矩

https://istio.io/latest/docs/concepts/traffic-management/#destination-rules)中界说好可用的版别中界说好可用的版别)

[6]ASK Pod Security Policy

help.aliyun.com/document_de…

[7]ECI Container Security Policy

help.aliyun.com/document_de…

[8]Istio CNI 插件

istio.io/latest/docs…

点击此处,了解阿里云ASK更多概况和最佳实践