惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
K
Kaspersky official blog
Stack Overflow Blog
Stack Overflow Blog
Blog — PlanetScale
Blog — PlanetScale
Recorded Future
Recorded Future
Engineering at Meta
Engineering at Meta
U
Unit 42
D
Docker
I
InfoQ
D
DataBreaches.Net
Google DeepMind News
Google DeepMind News
N
Netflix TechBlog - Medium
C
Check Point Blog
The Cloudflare Blog
美团技术团队
V
Vulnerabilities – Threatpost
博客园_首页
T
Threat Research - Cisco Blogs
Google DeepMind News
Google DeepMind News
Attack and Defense Labs
Attack and Defense Labs
A
Arctic Wolf
IT之家
IT之家
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
Troy Hunt's Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
人人都是产品经理
人人都是产品经理
C
Cyber Attacks, Cyber Crime and Cyber Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Security Archives - TechRepublic
Security Archives - TechRepublic
S
Schneier on Security
Apple Machine Learning Research
Apple Machine Learning Research
MyScale Blog
MyScale Blog
P
Privacy International News Feed
云风的 BLOG
云风的 BLOG
Recent Commits to openclaw:main
Recent Commits to openclaw:main
T
The Blog of Author Tim Ferriss
GbyAI
GbyAI
The Last Watchdog
The Last Watchdog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
aimingoo的专栏
aimingoo的专栏
P
Proofpoint News Feed
The Register - Security
The Register - Security
博客园 - 三生石上(FineUI控件)
Forbes - Security
Forbes - Security
NISL@THU
NISL@THU
Y
Y Combinator Blog
T
Threatpost
Microsoft Azure Blog
Microsoft Azure Blog
L
Lohrmann on Cybersecurity

Hi,I`m lan

MCP协议新进展: 使用 Streamable HTTP 替换当前的 HTTP+SSE 实现。-liangyuanpeng 的博客 我的 AI 员工们开发的微信小程序上线了!-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog vercel 记录-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog [长期更新]cocos creator问题列表-liangyuanpeng 的博客 | liangyuanpeng's Blog go问题列表记录-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog node镜像的更多选择-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog containerd 中的弃用警告 - 为 2.0 做好准备!-liangyuanpeng 的博客 liangyuanpeng 的博客 | liangyuanpeng's Blog kep-1880-多服务CIDR-liangyuanpeng 的博客 | liangyuanpeng's Blog [长期更新]argoworkflow 的一些实践和思考-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog 将Etcd作为一个kubernetes sig来运作-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog argoworkflow 云原生工作流引擎-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog kubecon china 2023将在上海举办-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog 从零到 Kubernetes 子项目负责人-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog Kubernetes HPA:定制指标实现有效的CPU和内存扩展-liangyuanpeng 的博客 | liangyuanpeng's Blog JFrog 向 CD 基金会授予开源 Pyrsia-liangyuanpeng 的博客 helmchart发布v2.10.1-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog ingress浅试-liangyuanpeng 的博客 | liangyuanpeng's Blog gateway-liangyuanpeng 的博客 | liangyuanpeng's Blog 1.24.0发布-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog 部署去ZK后的Apache Pulsar-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog 用GO开发Envoy wasm filter-liangyuanpeng 的博客 | liangyuanpeng's Blog 用Rust开发Envoy wasm filter-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog v1.18.3发布-liangyuanpeng 的博客 | liangyuanpeng's Blog v1.20.0-beta.1发布-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog Bookkeeper-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog Bookkeeper开发环境搭建-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog webhook开发技巧-liangyuanpeng 的博客 | liangyuanpeng's Blog 部署在线的lank8s webhook之后,不再为k8s.gcr.io/gcr.io镜像苦恼-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog 部署metrics-server,把kubectl top用起来-liangyuanpeng 的博客 | liangyuanpeng's Blog v1.9.0发布-liangyuanpeng 的博客 | liangyuanpeng's Blog v1.19.1发布-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog KubeSphere使用Contour Ingress作为项目网关-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog 宣布Contour v1.13.0-liangyuanpeng 的博客 | liangyuanpeng's Blog [了解Rust基金会]介绍Mark Rousskov-liangyuanpeng 的博客 | liangyuanpeng's Blog [了解Rust基金会]介绍Tyler Mandry-liangyuanpeng 的博客 | liangyuanpeng's Blog [了解Rust基金会]介绍Bobby Holley-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog [了解Rust基金会]介绍Shane Miller-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog prometheus-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog 使用Cloudflare pages部署静态博客-liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog liangyuanpeng 的博客 | liangyuanpeng's Blog
liangyuanpeng 的博客 | liangyuanpeng's Blog
2022-01-22 · via Hi,I`m lan

TOC

前言

由于实验基于 kubernetes,因此你首先需要有一个 kubernetes 环境,这里推荐使用 Kind 命令来搭建.见用kind搭建k8s集群环境

前提

  • kubernetes

为什么选择configmap

在使用 Envoy 的过程中时常会需要对接 XDS 用作流量的动态管理,那么如何以低成本的方式实现这个效果呢?

ConfigMap 你值得拥有,本质上还是使用文件作为 Envoy 的 XDS 服务实现,只不过将文件的内容以 ConfigMap 管理起来了.

原理

原理也很简单,在 Envoy 容器旁启动一个 SideCar,这个 SideCar 的唯一作用就是监听到文件变化之后做一个mv的操作,触发Envoy来重新加载最新的 XDS 规则文件.

这样就可以做到了动态的管理 Envoy 规则并且基本上没有上手难度.毕竟在 kubernetes 之上谁还不会操作一个 ConfigMap 呢?

遇到的问题

inotify 监听 modify 失败

实践的过程发现使用 inotify 监听文件时如果监听 modify 事件的话文件内容更新了,但是却没有触发监控事件,这是为什么呢?这与 configmap 将内容更新到 pod 中的机制有关.后续会有一篇文章来专门讲解一下这个原理.

configmap 挂载文件只读

另一个问题是配置文件通过 configmap 挂载到 pod 之后,是只读的,无法做修改,因此直接对挂载的配置文件做 mv envoy.yaml envoy.yaml_bak && mv envoy.yaml_bak envoy.yaml 是不可行的,本文的思路是用一个 initContainer 将 configmap 挂载的配置文件复制到另一个有读写权限的目录,然后后续每次 configmap 更新时都将文件复制到这个有读写权限的目录来做 mv 操作,进而最终达到让 Envoy 基于静态文件更新配置的效果.

开始尝试!

我将所有内容都揉在了一个 yaml 内,因此如果你对此感到不适可以拆分成多个单独的 yaml 文件 :)

对于 service,我使用 NodePort 暴露,只是为了更方便的测试,通过 Envoy admin 接口查看修改的内容是否生效.

开始部署 Envoy 到 kubernetes.

将下面展示的内容保存为 Envoy.yaml 并且执行命令应用:

kubectl apply -f envoy.yaml

或使用我整理好的在线文件:

kubectl apply -f https://liangyuanpeng.com/files/envoy-file-xds-with-reload-configmap/envoy.yaml

envoy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: envoy
  labels:
    app: envoy
spec:
  selector:
    matchLabels:
      app: envoy
  replicas: 1
  revisionHistoryLimit: 5
  template:
    metadata:
      labels:
        app: envoy
    spec:
      volumes:
        - name: envoy-config
          configMap:
            name: envoy
        - name: configs
          emptyDir: {}
      initContainers:
        - name: busybox
          image: busybox:1.35.0
          volumeMounts:
            - name: configs
              mountPath: /tmp
            - name: envoy-config
              mountPath: /configs
          command:
            - /bin/sh
            - -c
            - cat /configs/cds.yaml > /tmp/cds.yaml && cat /configs/envoy.yaml > /tmp/envoy.yaml && cat /configs/inotify.sh >  /tmp/inotify.sh  && cat /configs/lds.yaml > /tmp/lds.yaml
      containers:
        - name: envoy
          image: envoyproxy/envoy:v1.25.1
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: configs
              mountPath: /tmp
          ports:
            - name: admin
              containerPort: 19000
          command:
            - /bin/sh
            - -c
            - envoy -c /tmp/envoy.yaml
        - name: inotify
          image: twocows/inotifywait:0.1
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: configs
              mountPath: /tmp
            - name: envoy-config
              mountPath: /configs
          command:
            - /bin/sh
            - -c
            - sh /tmp/inotify.sh /configs
          resources:
            requests:
              memory: "10Mi"
              cpu: "10m"
            limits:
              memory: "512Mi"
              cpu: "800m"
---
apiVersion: v1
kind: Service
metadata:
  name: envoy
  labels:
    app: envoy
spec:
  ports:
    - name: admin
      port: 19000
      nodePort: 31900
  type: NodePort
  selector:
    app: envoy

---

apiVersion: v1
kind: ConfigMap
metadata:
  name: envoy
data:
  envoy.yaml: |
    node:
      id: id_1
      cluster: test

    dynamic_resources:
      cds_config:
        path_config_source:
          path: /tmp/cds.yaml
      lds_config:
        path_config_source:
          path: /tmp/lds.yaml

    admin:
      address:
        socket_address:
          address: 0.0.0.0
          port_value: 19000

  cds.yaml: |
    resources:
    - "@type": type.googleapis.com/envoy.config.cluster.v3.Cluster
      name: example_proxy_cluster
      type: STRICT_DNS
      load_assignment:
        cluster_name: example_proxy_cluster
        endpoints:
        - lb_endpoints:
          - endpoint:
              address:
                socket_address:
                  address: service1
                  port_value: 8080

  lds.yaml: |
    resources:
    - "@type": type.googleapis.com/envoy.config.listener.v3.Listener
      name: listener_0
      address:
        socket_address:
          address: 0.0.0.0
          port_value: 10001
      filter_chains:
      - filters:
          name: envoy.filters.network.http_connection_manager
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
            stat_prefix: ingress_http
            http_filters:
            - name: envoy.filters.http.router
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
            route_config:
              name: local_route
              virtual_hosts:
              - name: local_service
                domains:
                - "*"
                routes:
                - match:
                    prefix: "/"
                  route:
                    cluster: example_proxy_cluster

  inotify.sh: |
    #!/bin/bash
    /usr/bin/inotifywait -mrq --format '%f' -e create,close_write,delete $1  | while read line
    do
        if [ -f $1/$line ];then
            echo $1/$line
            cat $1/$line > /tmp/$line
            mv /tmp/$line /tmp/$line'_bak'
            mv /tmp/$line'_bak' /tmp/$line
        else
            echo "2"
        fi
    done

等待 Envoy pod 启动,运行起来后请求 Envoy admin 接口查看当前 Envoy 监听的端口号:

lan@lan:~$ curl -X GET http://localhost:31900/listeners?format=text
listener_0::0.0.0.0:10001

可以看到,当前 Envoy 监听 10001 端口号,这是 Envoy lds 的内容决定的,也就是上述 ConfigMap 内容中的:


  lds.yaml: |
    resources:
    - "@type": type.googleapis.com/envoy.config.listener.v3.Listener
      name: listener_0
      address:
        socket_address:
          address: 0.0.0.0
          port_value: 10001
      ...

现在将 10001 修改为 10002,然后将更新应用到 kubernetes 当中:

kubectl apply -f envoy.yaml

如果你使用的是在线文件,那么直接使用 kubectl edit configmap envoy 来修改内容,保存后即可.这样就无需在本地操作文件.

使用命令 kubectl logs -f {podname} 查看 Envoy pod 的日志,等待一会后如果你也看到以下类似的日志,那么说明 Envoy xds(lds) 的内容更新已经动态修改成功了.

...
[2023-03-23 07:38:48.937][13][info][config] [source/extensions/listener_managers/listener_manager/listener_manager_impl.cc:858] all dependencies initialized. starting workers
[2023-03-23 07:40:06.556][13][info][upstream] [source/extensions/listener_managers/listener_manager/lds_api.cc:79] lds: add/update listener 'listener_0'
[2023-03-23 07:40:06.561][13][info][upstream] [source/common/upstream/cds_api_helper.cc:32] cds: add 1 cluster(s), remove 0 cluster(s)
[2023-03-23 07:40:06.561][13][info][upstream] [source/common/upstream/cds_api_helper.cc:69] cds: added/updated 0 cluster(s), skipped 1 unmodified cluster(s)
[2023-03-23 07:40:06.566][13][info][upstream] [source/common/upstream/cds_api_helper.cc:32] cds: add 1 cluster(s), remove 0 cluster(s)
[2023-03-23 07:40:06.566][13][info][upstream] [source/common/upstream/cds_api_helper.cc:69] cds: added/updated 0 cluster(s), skipped 1 unmodified cluster(s)
[2023-03-23 07:40:06.574][13][info][upstream] [source/common/upstream/cds_api_helper.cc:32] cds: add 1 cluster(s), remove 0 cluster(s)
[2023-03-23 07:40:06.574][13][info][upstream] [source/common/upstream/cds_api_helper.cc:69] cds: added/updated 0 cluster(s), skipped 1 unmodified cluster(s)

这时候再查看一下 Envoy listener 的内容:

lan@lan:~$ curl -X GET http://localhost:31900/listeners?format=text
listener_0::0.0.0.0:10002

可以看到 Envoy 监听的端口号从 10001 更新为了 10002,这里做的演示是一个更新操作,你也可以尝试做以下测试:

  • 新增/删除操作 lds.yaml 内容
  • 新增/修改/删除操作 cds.yaml 内容

对于 CDS 的内容,可以从 Envoy admin 接口中的 /clusters 中查看:

lan@lan:~$ curl -X GET http://localhost:31900/clusters
example_proxy_cluster::observability_name::example_proxy_cluster
example_proxy_cluster::default_priority::max_connections::1024
example_proxy_cluster::default_priority::max_pending_requests::1024
example_proxy_cluster::default_priority::max_requests::1024
example_proxy_cluster::default_priority::max_retries::3
example_proxy_cluster::high_priority::max_connections::1024
example_proxy_cluster::high_priority::max_pending_requests::1024
example_proxy_cluster::high_priority::max_requests::1024
example_proxy_cluster::high_priority::max_retries::3
example_proxy_cluster::added_via_api::true

总结

到目前为止,你已经拥有了一个基于 configmap 的 envoy xds,因此可以轻松的使用其他工具或程序来修改configmap,达到动态灵活的效果.如果你对这篇文章有任何疑问,欢迎和我进行交流.

微信公众号

扫描下面的二维码关注我们的微信公众号,第一时间查看最新内容。同时也可以关注我的Github,看看我都在了解什么技术,在页面底部可以找到我的Github。

wechat-qrcode