Openshift之服务网格Istio

作者: 潘晓华Michael | 来源:发表于2019-02-13 10:14 被阅读357次
    Openshift Istio

    什么是服务网格?

    服务网络就是指构成应用程序的微服务网络以及应用之间的交互。随着规模和复杂性的增长,服务网格越来越难以理解和管理。它的需求包括服务发现、负载均衡、故障恢复、指标收集和监控以及通常更加复杂的运维需求,例如 A/B 测试、金丝雀发布、限流、访问控制和端到端认证等。

    Istio是什么?

    Istio 是一个用来连接、管理和保护微服务的开放平台。Istio 提供一种简单的方式来为已部署的服务建立网络,该网络具有负载均衡、服务间认证、监控等功能,而不需要对服务的代码做任何改动。想要让服务支持 Istio,只需要在您的环境中部署一个特殊的 sidecar,使用 Istio 控制平面功能配置和管理代理,拦截微服务之间的所有网络通信。

    Istio能做什么?

    Istio 提供了一个完整的解决方案,通过为整个服务网格提供行为洞察和操作控制来满足微服务应用程序的多样化需求。它在服务网络中统一提供了许多关键功能:

    • 流量管理。控制服务之间的流量和API调用的流向,使得调用更可靠,并使网络在恶劣情况下更加健壮。
    • 服务身份和安全。为网格中的服务提供可验证身份,并提供保护服务流量的能力,使其可以在不同可信度的网络上流转。
    • 策略执行。将组织策略应用于服务之间的互动,确保访问策略得以执行,资源在消费者之间良好分配。可以通过通过配置网格而不是修改应用程序代码来完成策略的更改。
    • 遥测:了解服务之间的依赖关系,以及它们之间流量的本质和流向,从而提供快速识别问题的能力。

    Istio的基本架构

    Istio 服务网格逻辑上分为数据平面和控制平面。

    • Envoy(数据平面Proxy)
    • Mixer(负责在服务网格上执行访问控制和使用策略,并从 Envoy 代理和其他服务收集遥测数据。)
    • Pilot(Envoy sidecar 提供服务发现功能,为智能路由(例如 A/B 测试、金丝雀部署等)和弹性(超时、重试、熔断器等)提供流量管理功能。)
    • Citadel(通过内置身份和凭证管理可以提供强大的服务间和最终用户身份验证。)
    Istio架构图

    什么是Red Hat OpenShift服务网格?

    • Red Hat OpenShift服务网格是一个平台,它提供了对服务网格的行为监控和操作,提供了连接、保护和监控微服务应用程序的统一方式。
    • 基于开源Istio项目,Red Hat OpenShift服务网格在现有的应用程序上添加了一个透明层,而不需要对服务代码进行任何更改。通过在整个环境中部署一个特殊的sidecar proxy,拦截微服务之间的所有网络通信,通过使用控制平面的配置,管理服务网格,可以达到服务的网络控制。
    • Red Hat OpenShift Service Mesh能够简单地实现服务发现、负载均衡、服务间的认证、故障恢复、统计、监控,同时也提供了复杂的功能,包括A/B测试、金丝雀发布、速率限制、访问控制和端到端认证。
    • 当前最新版本的Openshift Service Mesh为 Technology Preview 7(技术预览版7)。它增了3scale Istio Adapter,同时相关软件服务版本为Istio 1.11、Kiali 0.13.x、Jaeger 1.9.0

    Red Hat OpenShift Service Mesh当前问题

    • Red Hat OpenShift Service Mesh不支持网络多租户
    • Red Hat OpenShift Service Mesh不支持IPV6
    • istio-init容器需要有privileged权限,或者至少需要root并具有NET管理功能。因为istio-init需要配置Pod中的iptable规则来拦截网络连接。

    安装Red Hat OpenShift Service MeshOpenShift Service Mesh

    准备环境

    • Openshift 3.11
    • oc命令行工具与Openshift集群版本匹配
    • 执行oc命令时,必须使用集群管理员账号
    • 配置所有Node节点系统参数
    • 安装的版本为0.7.0
    $ cat /etc/sysctl.d/99-elasticsearch.conf 
    vm.max_map_count = 262144
    $ sysctl vm.max_map_count=262144
    
    • 相关镜像
    registry.access.redhat.com/openshift-istio-tech-preview/istio-operator:0.7.0
    registry.access.redhat.com/openshift-istio-tech-preview/openshift-ansible:0.7.0
    registry.access.redhat.com/openshift-istio-tech-preview/citadel:0.7.0
    registry.access.redhat.com/openshift-istio-tech-preview/proxyv2:0.7.0
    registry.access.redhat.com/openshift-istio-tech-preview/pilot:0.7.0
    registry.access.redhat.com/openshift-istio-tech-preview/mixer:0.7.0
    registry.access.redhat.com/openshift-istio-tech-preview/galley:0.7.0
    registry.access.redhat.com/openshift-istio-tech-preview/sidecar-injector:0.7.0
    registry.access.redhat.com/openshift-istio-tech-preview/proxy-init:0.7.0
    registry.access.redhat.com/openshift-istio-tech-preview/kiali:0.13.0
    registry.access.redhat.com/distributed-tracing-tech-preview/jaeger-elasticsearch:5.6.10
    registry.access.redhat.com/distributed-tracing-tech-preview/jaeger-agent:1.9.0
    registry.access.redhat.com/distributed-tracing-tech-preview/jaeger-collector:1.9.0
    registry.access.redhat.com/distributed-tracing-tech-preview/jaeger-query:1.9.0
    docker.io/grafana/grafana:5.4.0
    docker.io/prom/prometheus:v2.3.1
    

    开始安装

    1. 创建CRD文件istio-installation.yaml
    $ cat istio-installation.yaml
    apiVersion: "istio.openshift.com/v1alpha1"
    kind: "Installation"
    metadata:
      name: "istio-installation"
    spec:
      deployment_type: openshift
      istio:
        authentication: true
        community: false
        prefix: openshift-istio-tech-preview/
        version: 0.7.0
      jaeger:
        prefix: distributed-tracing-tech-preview/
        version: 1.9.0
        elasticsearch_memory: 1Gi
      kiali:
        username: username
        password: password
        prefix: openshift-istio-tech-preview/
        version: 0.13.0
      launcher:
        openshift:
          user: user
          password: password
        github:
          username: username
          token: token
        catalog:
          filter: booster.mission.metadata.istio
          branch: v71
          repo: https://github.com/fabric8-launcher/launcher-booster-catalog.git
      threeScale:
        enabled: false
        prefix: openshift-istio-tech-preview/
        version: 0.2.0
        adapter:
          listenAddr: 3333
          logLevel: info
          logJSON: true
          reportMetrics: true
          metricsPort: 8080
          cacheTTLSeconds: 300
          cacheRefreshSeconds: 180
          cacheEntriesMax: 1000
          cacheRefreshRetries: 1
          allowInsecureConn: false
          clientTimeoutSeconds: 10
    

    注意
    metadata.name必须是istio-installation
    spec.launcher.openshift.userspec.launcher.openshift.password为openshift集群对应的用户名和密码
    spec.launcher.github.usernamespec.launcher.github.token为github对应的账号信息
    以上是最全的安装,当前也有最简安装的配置

    $ cat istio-installation.yaml
    apiVersion: "istio.openshift.com/v1alpha1"
    kind: "Installation"
    metadata:
      name: "istio-installation"
    
    1. 安装istio operator相关文件准备
      相关的配置文件在github上https://github.com/Maistra/openshift-ansible/tree/maistra-0.7/istio
      相关文件配置列表如下
      cr-full.yaml
      cr-kiali.yaml
      cr-minimal.yaml
      istio_community_operator_template.yaml
      istio_product_operator_template.yaml
      master-config.patch
    2. 安装istio operator
    $ oc new-project istio-operator
    $ oc new-app -f istio_product_operator_template.yaml --param=OPENSHIFT_ISTIO_MASTER_PUBLIC_URL=<master public url> --param=OPENSHIFT_ISTIO_PREFIX=registry.access.redhat.com/openshift-istio-tech-preview/
    
    • OPENSHIFT_ISTIO_MASTER_PUBLIC_URL为openshift集群对外的master地址,例如:https://master.example.com:8443
    • OPENSHIFT_ISTIO_PREFIX为openshift istio的镜像前缀,如果将准备中的镜像都导入到了自己的私有仓库中,就可以使用它换成自己的镜像仓库地址
    1. 验证operator安装是否成功
    $ oc logs -n istio-operator $(oc -n istio-operator get pods -l name=istio-operator --output=jsonpath={.items..metadata.name})
    
    time="2019-02-11T05:28:25Z" level=info msg="Go Version: go1.9.4"
    time="2019-02-11T05:28:25Z" level=info msg="Go OS/Arch: linux/amd64"
    time="2019-02-11T05:28:25Z" level=info msg="operator-sdk Version: 0.0.5+git"
    time="2019-02-11T05:28:25Z" level=info msg="Metrics service istio-operator created"
    time="2019-02-11T05:28:25Z" level=info msg="Watching resource istio.openshift.com/v1alpha1, kind Installation, namespace istio-operator, resyncPeriod 0"
    time="2019-02-11T05:33:10Z" level=info msg="Installing istio for Installation istio-installation"
    

    有类似如上的输出就说明安装好了。

    1. 部署控制平面CONTROL PLANE
    oc create -f istio-installation.yaml -n istio-operator
    

    其中istio-installation.yaml为第一步创建的文件。
    该步骤将创建istio-system项目,并调用operator中的ansible任务完成istio的安装。可以通过观察名为openshift-ansible-istio-installer-job的pod的状态,来确认安装的进度,如果它的状态为completed,说明安装完成。

    $ oc get pods -n istio-system
    NAME                                          READY     STATUS      RESTARTS   AGE
    3scale-istio-adapter-7df4db48cf-sc98s         1/1       Running     0          13s
    elasticsearch-0                               1/1       Running     0          29s
    grafana-c7f5cc6b6-vg6db                       1/1       Running     0          33s
    istio-citadel-d6d6bb7bb-jgfwt                 1/1       Running     0          1m
    istio-egressgateway-69448cf7dc-b2qj5          1/1       Running     0          1m
    istio-galley-f49696978-q949d                  1/1       Running     0          1m
    istio-ingressgateway-7759647fb6-pfpd5         1/1       Running     0          1m
    istio-pilot-7595bfd696-plffk                  2/2       Running     0          1m
    istio-policy-779454b878-xg7nq                 2/2       Running     2          1m
    istio-sidecar-injector-6655b6ffdb-rn69r       1/1       Running     0          1m
    istio-telemetry-dd9595888-8xjz2               2/2       Running     2          1m
    jaeger-agent-gmk72                            1/1       Running     0          25s
    jaeger-collector-7f644df9f5-dbzcv             1/1       Running     1          25s
    jaeger-query-6f47bf4777-h4wmh                 1/1       Running     1          25s
    kiali-7cc48b6cbb-74gcf                        1/1       Running     0          17s
    openshift-ansible-istio-installer-job-fbtfj   0/1       Completed   0          2m
    prometheus-5f9fd67f8-r6b86                    1/1       Running     0          1m
    
    $ oc get pods -n devex
    NAME                          READY     STATUS    RESTARTS   AGE
    configmapcontroller-1-8rr6w   1/1       Running   0          1m
    launcher-backend-2-2wg86      1/1       Running   0          1m
    launcher-frontend-2-jxjsd     1/1       Running   0          1m
    
    1. 配置master-config,使得应用能够自动注入istio-proxy sidecar
      在master-config.yaml文件所在目录下新建文件master-config.patch,内容见下面的代码块
    $ cd /etc/origin/master/
    $ cat master-config.patch
    admissionConfig:
      pluginConfig:
        MutatingAdmissionWebhook:
          configuration:
            apiVersion: apiserver.config.k8s.io/v1alpha1
            kubeConfigFile: /dev/null
            kind: WebhookAdmission
        ValidatingAdmissionWebhook:
          configuration:
            apiVersion: apiserver.config.k8s.io/v1alpha1
            kubeConfigFile: /dev/null
            kind: WebhookAdmission
    $ cp -p master-config.yaml master-config.yaml.prepatch
    $ oc ex config patch master-config.yaml.prepatch -p "$(cat master-config.patch)" > master-config.yaml
    $ /usr/local/bin/master-restart api && /usr/local/bin/master-restart controllers
    
    1. 创建自动注入istio-proxy的deployment,需要满足以下两个条件
    • 所在project下的容器需要privileged与anyuid的scc
    oc adm policy add-scc-to-user anyuid -z <service account> -n <namespace>
    oc adm policy add-scc-to-user privileged -z <service account> -n <namespace>
    

    <service account>默认为default
    <namespace>为需要istio控制的project

    • deployment中添加annotations sidecar.istio.io/inject: "true"
      例如
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: sleep
    spec:
      replicas: 1
      template:
        metadata:
          annotations:
            sidecar.istio.io/inject: "true"
          labels:
            app: sleep
        spec:
          containers:
          - name: sleep
            image: tutum/curl
            command: ["/bin/sleep","infinity"]
            imagePullPolicy: IfNotPresent
    

    卸载Red Hat OpenShift Service Mesh

    1. 删除自定义资源
    $ oc delete -n istio-operator installation istio-installation
    
    1. 删除operator
    $ oc process -f istio_product_operator_template.yaml | oc delete -f -
    

    升级Red Hat OpenShift Service Mesh

    目前Red Hat OpenShift Service Mesh不支持升级,如果需要使用新版本的Service Mesh,只能通过先卸载再安装的方式。

    实战Bookinfo

    目前Istio的测试例子几本都是用Bookinfo这个应用,它也是istio项目官方的测试例子,同样Red Hat Openshift Service Mesh也是用这个例子来做演练。
    这个Bookinfo应用包含有4个微服务,分别是:

    • productpage,该页面会去调用details和reviews服务
    • details,该服务获取书的信息
    • reviews,该服务包括对书的评价,它会调用rating服务
    • ratings,该服务包括书的评分
      同时reviews服务有三个版本:
      v1版本不调用 ratings服务
      v2版本,调用ratings服务,同时给评星显示五个黑色的星星
      v3版本,调用ratings服务,同时给评星显示五个红色的星星

    安装Bookinfo应用

    1. 为bookinfo应用单独创建一个project
    $ oc new-project myproject
    
    1. 为myproject项目的容器默认添加privileged与anyuid scc
    $ oc adm policy add-scc-to-user anyuid -z default -n myproject
    $ oc adm policy add-scc-to-user privileged -z default -n myproject
    
    1. 在myproject项目下部署应用
    $ oc apply -n myproject -f https://raw.githubusercontent.com/Maistra/bookinfo/master/bookinfo.yaml
    
    1. 为bookinfo创建ingress gateway,使得外部能够访问到bookinfo服务
    $ oc apply -n myproject -f https://raw.githubusercontent.com/Maistra/bookinfo/master/bookinfo-gateway.yaml
    
    1. 获得ingress gateway的请求域名
    $ oc get route -n istio-system istio-ingressgateway -o jsonpath='{.spec.host}'
    istio-ingressgateway-istio-system.apps.example.com
    
    1. 浏览器中访问:http://istio-ingressgateway-istio-system.apps.example.com/productpage
    ratings v1 ratings v2 ratings v3

    至此,Bookinfo应用已成功部署好了。

    添加额外的规则

    1. 不启用mutual TLS
    $ curl -o destination-rule-all.yaml https://raw.githubusercontent.com/istio/istio/release-1.0/samples/bookinfo/networking/destination-rule-all.yaml
    $ oc apply -f destination-rule-all.yaml
    
    $ cat destination-rule-all.yaml
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: productpage
    spec:
      host: productpage
      subsets:
      - name: v1
        labels:
          version: v1
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: reviews
    spec:
      host: reviews
      subsets:
      - name: v1
        labels:
          version: v1
      - name: v2
        labels:
          version: v2
      - name: v3
        labels:
          version: v3
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: ratings
    spec:
      host: ratings
      subsets:
      - name: v1
        labels:
          version: v1
      - name: v2
        labels:
          version: v2
      - name: v2-mysql
        labels:
          version: v2-mysql
      - name: v2-mysql-vm
        labels:
          version: v2-mysql-vm
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: details
    spec:
      host: details
      subsets:
      - name: v1
        labels:
          version: v1
      - name: v2
        labels:
          version: v2
    ---
    
    1. 启用mutual TLS
    $ curl -o destination-rule-all-mtls.yaml https://raw.githubusercontent.com/istio/istio/release-1.0/samples/bookinfo/networking/destination-rule-all-mtls.yaml
    $ oc apply -f destination-rule-all-mtls.yaml
    
    $ cat destination-rule-all-mtls.yaml
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: productpage
    spec:
      host: productpage
      trafficPolicy:
        tls:
          mode: ISTIO_MUTUAL
      subsets:
      - name: v1
        labels:
          version: v1
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: reviews
    spec:
      host: reviews
      trafficPolicy:
        tls:
          mode: ISTIO_MUTUAL
      subsets:
      - name: v1
        labels:
          version: v1
      - name: v2
        labels:
          version: v2
      - name: v3
        labels:
          version: v3
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: ratings
    spec:
      host: ratings
      trafficPolicy:
        tls:
          mode: ISTIO_MUTUAL
      subsets:
      - name: v1
        labels:
          version: v1
      - name: v2
        labels:
          version: v2
      - name: v2-mysql
        labels:
          version: v2-mysql
      - name: v2-mysql-vm
        labels:
          version: v2-mysql-vm
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: details
    spec:
      host: details
      trafficPolicy:
        tls:
          mode: ISTIO_MUTUAL
      subsets:
      - name: v1
        labels:
          version: v1
      - name: v2
        labels:
          version: v2
    ---
    
    1. 列出所有的目标规则
    $ oc get destinationrules -o yaml
    

    删除Bookinfo应用

    1. 下载清除Bookinfo的脚本代码
    $ curl -o cleanup.sh https://raw.githubusercontent.com/Maistra/bookinfo/master/cleanup.sh && chmod +x ./cleanup.sh
    
    1. 执行cleanup.sh
    $ ./cleanup.sh
    namespace ? [default] myproject
    
    1. 确认清除完成
    $ oc get virtualservices -n myproject
    No resources found.
    $ oc get gateway -n myproject
    No resources found.
    $ oc get pods -n myproject
    No resources found.
    

    RedHat Openshift Service Mesh扩展组件

    **RedHat Openshift Service Mesh的全量安装,还包括以下组件:分布式追踪Jaeger、Istio可视化工具Kiali、Prometheus监控及Grafana监控展示。下面分别介绍各个组件的功能与使用。
    请确保上一步安装的Bookinfo应用正常访问。

    Openshift Service Mesh扩展组件

    分布式追踪Jaeger

    Jaeger是Uber开源的分布式跟踪系统,现在已经成为CNCF的开源项目,其灵感来源于Google的Dapper和twitter的Zipkin,从2016年开始该系统在Uber内部得到了广泛的应用。 Jaege在设计上参考了Google的Dapper。

    1. 访问并刷新几次bookinfo页面:http://istio-ingressgateway-istio-system.apps.example.com/productpage
    2. 打开jaeger页面
    $ oc get route -n istio-system jaeger-query -o jsonpath='{.spec.host}'
    jaeger-query-istio-system.apps.example.com
    
    1. 浏览器访问https://jaeger-query-istio-system.apps.example.com
    2. jaeger页面的左侧Service选择productpage,并点击Find Traces按钮,将在右侧显示轨迹列表
    jaeger主页
    1. 点击列表中的一条轨迹,将打开该轨迹的详细视图
    轨迹详细视图
    • 从上图中可以看出,该追踪轨迹是由多个嵌套块组成。每个嵌套都对应一个Bookinfo服务的调用,所有的这些都是为了响应/productpage请求而执行的。
    • 该请求总共耗时46.23ms,详情服务(detail)耗时1.76ms,评论服务(reviews)耗时32.28ms,评分服务(ratings)耗时17.41ms。
    • 每个请求都是由调用客户端与服务端组成,例如:productpage details.myproject.svc.cluster.local:9080,即表示productpage服务调用了details服务。

    Kiali

    Kiali为网格管理和可观察性提供了良好的用户体验的可视化工具。Kiali 提供以下功能:

    • 服务拓扑图
    • 分布式跟踪
    • 指标度量收集和图标
    • 配置校验
    • 健康检查和显示
    • 服务发现
    1. 查看Kiali域名地址
    $ oc get route -n istio-system kiali -o jsonpath='{.spec.host}'
    kiali-istio-system.apps.example.com
    
    1. 浏览器访问 https://kiali-istio-system.apps.example.com
    kiali登录界面

    使用安装istio时的istio-installation.yaml中配置的kiali的用户名和密码登录,如:username,password

    1. OverView页面
    kiali overview页面

    可查看各project的运行状况。

    1. Graph页面
      在Graph页面上选择Namespace为myproject,可查看bookinfo这个项目的微服务关系图。
    Kiali Graph页面
    • 在Graph页面中能够看到一个包含所有微服务的图表,在页面上可以方便看到这些服务的相互交互关系。
    • 点击Legend按钮,可以查看每个节点图标代表的含义
    • 鼠标悬停在某个节点上,能够看到该节点相关的调用关系
    • 点击节点,展示该节点相关调用关系的详情
    1. Service页面
      Service页面可以查看项目的微服务列表,及服务相关的额外信息,如:健康状态、请求错误率。
    Kiali Service页面
    • 点击具体服务,可查看服务的详情信息
    1. Istio Config 页面
      Istio Config页面,可以查看当前运行的Istio配置信息,包括熔断器,规则、网关、故障注入、路由、路由规则、虚拟服务。
    Istio Config 页面
    • 点击具体的信息条目查看详情
    • 只能查看,不能修改
    1. 分布式追踪器链接
      分布式追踪器链接,跳转到对应的Jaeger页面

    Prometheus监控

    Prometheus是一个开源的服务工具包,可以按指定的时间间隔从配置的目标中获取监控数据,同时它还支持告警。经常使用Grafana来展示相关数据。

    1. 查看Prometheus页面地址
    $ oc get route -n istio-system prometheus -o jsonpath='{.spec.host}'
    prometheus-istio-system.apps.example.com
    
    1. 浏览器访问http://prometheus-istio-system.apps.example.com
    Prometheus监控

    Grafana监控展示

    Grafana是一个开源的监控展示工具,它可以与很多不同的数据源连接,如Mysql, InfluxDB,Prometheus等。图表丰富美观,同时也有告警功能。

    1. 查看Grafana页面地址
    $ oc get route -n istio-system grafana -o jsonpath='{.spec.host}'
    grafana-istio-system.apps.example.com
    
    1. 浏览器访问http://grafana-istio-system.apps.example.com
    Grafana监控展示
    1. 选择Istio Mesh Dashboard查看网格服务监控情况
    Istio Mesh Dashboard
    1. 在Istio Mesh Dashboard页面下点击相关Service,查看对应Service的监控详情
    Istio Service详情
    1. RedHat Openshift Service Mesh Grafana默认的监控图表,不仅仅只有应用服务的监控,同时也有Istio相关组件的监控(Mixer,Pilot)。所有的监控图表如下:
    • Istio Galley Dashboard
    • Istio Mesh Dashboard
    • Istio Performance Dashboard
    • Istio Service Dashboard
    • Istio Workload Dashboard
    • Mixer Dashboard
    • Pilot Dashboard

    总结

    • Istio 目前是在服务网格的产品中最为火热的产品,目前最新版本为1.1.0
    • 随着服务网格越来越火热,相关的周边应用也不断出现,分布式追踪工具Jaeger,Istio配置管理工具Kiali及监控Prometheus与Grafana也让服务网格更加的完整,可靠。
    • 与之前Openshift 3.10版本手动安装Istio相比,在Openshift 3.11版本通过Istio-operator安装部署,更加方便也更加稳定。

    参考文章

    Openshift官方文档之:Service Mesh

    相关文章

      网友评论

        本文标题:Openshift之服务网格Istio

        本文链接:https://www.haomeiwen.com/subject/dyeheqtx.html