IBM Developer 博客

通过 IBM Developer 关注最新动态并获取信息

Istio 1.4 包括新的 Istio operator、新的 Istio 控制器、新的 `v1beta1` 授权策略、自动双向传输层安全性 (TLS) 支持以及 `istioctl` 的更新。


2019 年末,Istio 发布了 19 年连续第四季度版本,即 Istio 1.4。该版本的重点是改善用户体验,使运维人员更容易管理集群。新增的功能和改进包括新的 Istio operator、v1beta1 授权策略、自动双向传输层安全性 (mutual TLS) 支持以及对 istioctl 的更新,如下图所示:

从 Istio 1.1 到 1.4 的时间线

以下各部分描述了本次更新亮点,并让您通过一些示例要了解 Istio 1.4 的详细信息,请参阅社区发行说明Istio 文档。到目前为止,1.4 版本有三个补丁版本 – 1.4.11.4.21.4.3。这三个补丁包括错误修复、改进和安全更新。此外,请查看 Dan Berg 在 serviceMeshCon 大会中发布的 6 分钟演示视频:Istio 在用户体验方面有极大提升,并采用分析驱动的金丝雀部署(1118-RM06-06.mp4),该视频快速回顾了 Istio 1.4 版本。

Istio operator

Istio 1.4 的其中一个主要亮点是增加了 Istio operator,改进了 Istio 控制层面的部署和管理。该 operator 旨在取代 Helm,成为安装和升级 Istio 的主要工具。您现在可以使用 istioctl 来安装 Istio,而不必管理 多个 YAML 文件。Istio operator 使用自定义资源定义 (CRD) IstioControlPlane 来定义可用于自定义 Istio 控制层面安装的自定义资源。istioctl 安装命令使用相同的自定义资源来配置安装。

Istio operator使用 Istio 控制器(alpha 版本)来监控 IstioControlPlane 自定义资源。对此自定义资源的任何更新都会立即应用于 Istio 群集。

安装 Istio 的推荐方法是使用以下 istioctl 命令(使用 --set 标志指定要用于安装 Istio 的配置文件)。以下示例使用 demo 配置文件:

istioctl manifest apply --set profile=demo

自动双向 TLS

Istio 1.4 中的另一个非常有用的特性是支持自动双向 TLS,这简化了对登入到 Istio 的服务采用双向 TLS 的过程。您只需要定义身份验证策略,便可以使用这个新功能来采用双向 TLS,而不需要定义 DestinationRule 对象。如果您已经安装了 Istio,则可以使用以下命令启用自动双向 TLS(这会重新部署 Istio 来启用自动双向 TLS ):

istioctl manifest apply --set values.global.mtls.auto=true

或者,您也可以在启用自动双向 TLS 的情况下使用 demo 配置文件安装 Istio:

istioctl manifest apply --set profile=demo --set values.global.mtls.auto=true

采用此功能,运维人员就无需跟踪迁移到 Istio 的服务,该功能还可相应地调整 DestinationRules 以启用或禁用双向 TLS 流量。Istio 会自动使用 sidecar 跟踪服务器工作负载,并使用 sidecar 配置客户端以向它们发送双向 TLS 流量,并将纯文本流量发送到那些没有 sidecar 的工作负载。

下面的示例介绍如何将 Bookinfo 示例应用程序部署到两个名称空间(namespace):fulllegacy,并演示自动双向 TLS 是如何工作的。在启用了自动双向 TLS 的情况下使用 demo 配置文件来安装 Istio。

  1. 创建一个 full 名称空间,在启用了 sidecar 注入的情况下部署 Bookinfo 示例应用程序(此名称空间中的工作负载可以同时服务纯文本和双向 TLS 流量):

     kubectl create ns full
    
     kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml) -n full
    
  2. 创建一个 legacy 名称空间,在未启用 sidecar 注入的情况下部署 Bookinfo 示例应用程序(此名称空间中的工作负载只能服务纯文本流量):

     kubectl create ns legacy
    
     kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n legacy
    
  3. 尝试从 legacy 名称空间中的 ratings pod 访问 full 名称空间中的 Bookinfo 应用程序的 productpage。注意,网格中的所有服务都以 PERMISSIVE 模式开始,这意味着 full 名称空间中的服务可以同时为双向 TLS 通信流量和纯文本流量提供服务。因此,full 名称空间中的 productpage 服务可以接受来自 legacy 名称空间中的 ratings 服务的纯文本流量:

     kubectl exec -it $(kubectl get pod -n legacy -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c  ratings -n legacy -- curl http://productpage.full:9080/productpage | grep -o "<title>.*</title>"
    
     <title>Simple Bookstore App</title>
    
  4. full 名称空间中的 ratings pod 访问 full 名称空间中的 productpage。自动交互 TLS 将 ratings 服务配置为将双向 TLS 流量发送到 full 名称空间中的 productpage 服务。

     kubectl exec -it $(kubectl get pod -n full -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -n full -- curl http://productpage.full:9080/productpage | grep -o "<title>.*</title>"
    
     <title>Simple Bookstore App</title>
    
  5. full 名称空间中 productpage 服务的身份验证策略配置为 STRICT 模式,而非 PERMISSIVE。这意味着 productpage 服务只能收到双向 TLS 流量:

     cat <<EOF | kubectl apply -n full -f -
     apiVersion: "authentication.istio.io/v1alpha1"
     kind: "Policy"
     metadata:
       name: "productpage"
     spec:
       targets:
       - name: productpage
       peers:
       - mtls: {}
     EOF
    
  6. 尝试从 legacy 名称空间中的 ratings pod 访问 full 名称空间中的 productpage。注意,这会失败,因为 legacy 名称空间中的 ratings pod 只能发送纯文本流量:

     kubectl exec -it $(kubectl get pod -n legacy -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -n legacy -- curl http://productpage.full:9080/productpage | grep -o "<title>.*</title>"
    
     command terminated with exit code 56
    
  7. 尝试从 full 名称空间中的 ratings pod 访问 full 名称空间中的 productpage。这会成功,因为自动双向 TLS 将 ratings Pod 配置为将双向 TLS 流量发送到 productpage 服务,而不需要用户定义 DestinationRule 对象。

     kubectl exec -it $(kubectl get pod -n full -l app=ratings -o  jsonpath='{.items[0].metadata.name}') -c ratings -n full -- curl http://productpage.full:9080/productpage | grep -o "<title>.*</title>"
    
     <title>Simple Bookstore App</title>
    

v1beta1 授权策略

在 Istio 中,授权策略控制对集群中工作负载的访问。在 Istio 1.4 中,Istio 社区引入了 v1beta1 授权策略,与之前 v1alpha1 基于角色的访问控制 (RBAC) 策略相比,这是一种重大的全新设计。新的授权策略现在与 Istio 配置模型(Configuration Model)保持一致,这有助于通过简化 API 来提高可用性。使用之前的 v1alpha1 API,您需要定义三种配置资源:ClusterRbacConfigServiceRoleServiceRoleBinding 才能强制对服务进行访问控制。使用 v1beta1 版本,您可以通过定义一个授权策略对象来实现相同的访问控制。

下面的示例展示了如何为 bookinfo 应用程序的 reviews 服务定义授权策略对象:

kubectl apply -f - <<EOF
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "reviews-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: reviews
      namespace: defa
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
    to:
    - operation:
        methods: ["GET"]
EOF

您可以使用 spec 下面的 selectorrules 部分来为特定工作负载定义 AuthorizationPolicyselector 指定此授权策略适用于哪些工作负载(在本例中,它适用于 default 名称空间中的 reviews 服务)。rules 部分定义了允许哪些工作负载访问 reviews 服务(使用 from:source:principals 部分),以及要使用哪些操作(在 to:operation:methods 部分中指定)。在前面的示例中,只允许来自 bookinfo-productpage 工作负载的 GET 请求访问 reviews 服务。所有其他请求均被拒绝。

在下面的示例中,您可以继续使用部署在两个不同名称空间(分别是 fulllegacy)中的 Bookinfo 应用程序来演示如何使用最新的 v1beta1 授权策略来授予对名称空间中服务的访问。

  1. 定义一个授权策略,该策略拒绝在 fulllegacy 名称空间中的任何工作负载的所有流量。在下面的示例中,spec 字段为空,这意味着它会拒绝流向给定名称空间中工作负载的所有流量。

     kubectl apply -f - <<EOF
     apiVersion: security.istio.io/v1beta1
     kind: AuthorizationPolicy
     metadata:
       name: deny-all-legacy
       namespace: legacy
     spec:
       {}
     EOF
    
  2. 尝试从 legacyfull 名称空间中的 ratings pod 访问 full 名称空间中的 productpage。这两个请求都会失败,因为 full 名称空间中的所有服务都被拒绝访问。

     kubectl exec -it $(kubectl get pod -n legacy -l app=ratings  -o jsonpath='{.items[0].metadata.name}') -c ratings -n legacy  -- curl http://productpage.full:9080/productpage
    
     RBAC: access denied
    
  3. 允许来自任何工作负载对 full 名称空间中的 productpage 服务进行 GET 请求访问。在本例中,您没有指定 from.source 字段,因此 full 名称空间中的 productpage 服务可以接受来自(任何名称空间中)任何工作负载的 GET 请求:

     kubectl apply -f - <<EOF
     apiVersion: "security.istio.io/v1beta1"
     kind: "AuthorizationPolicy"
     metadata:
       name: "productpage-viewer"
       namespace: full
     spec:
       selector:
         matchLabels:
           app: productpage
       rules:
       - to:
         - operation:
             methods: ["GET"]
     EOF
    
  4. 尝试从 legacy 名称空间中的 ratings pod 访问 full 名称空间中的产品页面。这将显示 productpage ,但您可以看到产品页面的 detailsreview 部分为空。这是因为拒绝全部授权策略仍然适用于 details, reviewsratings 服务。到目前为止,我们只允许访问 full 名称空间中的 productpage 服务。

     <title>Simple Bookstore App</title>
     ……
      ……
     <div class="row">
      <div class="col-md-6">
        <h4 class="text-center text-primary">Error fetching  product details!</h4>     
        <p>Sorry, product details are currently unavailable for this book.</p>            
      </div>
      <div class="col-md-6">      
        <h4 class="text-center text-primary">Error fetching product reviews!</h4>      
        <p>Sorry, product reviews are currently unavailable for this book.</p>      
      </div>
     </div>
    
  5. 要允许 productpage 服务访问 full 名称空间中的 details 服务,需要为 full 名称空间中的 details 服务创建另一个授权策略。在 selector 部分中,指定可以访问 details 服务的源(source)。源可以是服务帐户或名称空间:

     kubectl apply -f <<EOF
     apiVersion: "security.istio.io/v1beta1"
     kind: "AuthorizationPolicy"
     metadata:
       name: "details-viewer"
       namespace: full
     spec:
       selector:
         matchLabels:
           app: details
       rules:
       - from:
         - source:
             principals: [“cluster.local/ns/full/sa/bookinfo-  productpage"]
         to:
         - operation:
             methods: ["GET"]
     EOF
    
  6. 尝试从 legacy 名称空间中的 ratings pod 访问 full 名称空间中的 productpage,您将能够看到 details 部分。reviews 部分仍然是空白的。要获得评论和评分,您必须在 full 名称空间中为 reviewsratings 服务创建类似的授权策略,允许从 productpage 服务进行访问。

         <div class="row">
         <div class="col-md-6">   
           <h4 class="text-center text-primary">Book Details</h4>
           <dl>
             <dt>Type:</dt>paperback
             <dt>Pages:</dt>200
             <dt>Publisher:</dt>PublisherA
             <dt>Language:</dt>English
             <dt>ISBN-10:</dt>1234567890
             <dt>ISBN-13:</dt>123-1234567890
           </dl>     
         </div>
         <div class="col-md-6">
           <h4 class="text-center text-primary">Error fetching product reviews!</h4>
           <p>Sorry, product reviews are currently unavailable for this book.</p>
         </div>
       </div>
    

istioctl 的更新

Istio 1.4 中的几个新的 istioctl 实验子命令可帮助运维人员管理网格。其中一个是 analyze 命令。此命令可帮助您分析实时集群的配置问题,并在部署新配置之前进行验证:

istioctl x analyze -k

Istio 1.4 中还添加了以下实验子命令:create-remote-secretwait.

其他增强

Istio 1.4 版本中需要强调的另一个增强是在无混合遥测支持方面的改进。HTTP 指标的代理内生成从实验发展到 alpha 阶段。另外,还增加了对 TCP 指标的实验性支持。

Istio client-go 库是 Istio 1.4 中新发布的 GO 库,可帮助开发人员以编程方式访问 Kubernetes 集群中的 Istio API。使用这个库,您可以生成控制器来对 Kubernetes 集群中的 Istio 自定义资源执行 CRUD 操作。

Istio 1.4 还包括对 Envoy 功能集的改进,新增了一项功能,可将流量镜像到传入流量的百分比,而不是默认 100%。

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
    - httpbin
  http:
  - route:
    - destination:
        host: httpbin
        subset: v1
      weight: 100
    mirror:
      host: httpbin
      subset: v2
    mirror_percent: 80
EOF

Istio 和 IBM

自 2017 年启动以来,Istio 项目获得了巨大的增长和广泛的采用。作为 Istio 项目的联合创始方之一,IBM(以及 Google 和 Lyft)自项目启动一直积极参与和贡献。 300 多家公司参与了该项目,而 IBM 在不同版本中对项目的贡献排名第二。在 Istio 1.4 中,IBM 人员参与了关键性能的设计和实现,包括自动双向 TLS 和 Istio operator、新的 istioctl 特性以及为改进可用性和操作便利性而进行的更新。IBM 还参与了虚拟机网格扩展,以便将虚拟机工作负载连接到容器。IBM 几个活跃的维护人员共同领导不同的 Istio 工作组,分别在 Istio 技术监督委员会Istio 指导委员会中担任职位。

IBM 在 IBM Cloud Kubernetes Service上将 Istio 作为托理附加服提供务,可自动将所有 Istio 组件保持最新状态。IBM 于 2019 年 11 月宣布 IBM Cloud Kubernetes Service 上的托管 Istio 正式发布

结束语

回顾 2019 年,Istio 项目在生态系统和社区方面获得了巨大的发展。此外,越来越多的公司在生产环境中采用了 Istio。在 2019 年,Istio 被评为 GitHub 中增长最快的五大开源项目之一。社区在 2019 年的四个版本中对 Istio 做了许多改进,重点是提高性能和可用性,并使运维人员更容易部署、管理和排除故障。我们期待 Istio 项目和社区在 2020 年实现更多喜人的成就。

本文翻译自:Istio 1.4 improves user experience and simplifies managing clusters(2020-01-23)