envoy网格安全

基础概念

身份认证方法

  • tls和mtls
  • jwt身份认证
    • jwt、jwk、jws
  • spiffe协议/框架
    • spire服务:使用spiffe框架,向每个pod发放一个身份,并基于该身份生成一个subject,最后生成证书,用sds发放
    • sds(secret服务发现)和mtls

授权

  • rbac
  • 外部授权和abac
    • opa(open policy agent)
    • opa决策机制

网格内安全方案

  • 应用内部使用jwt验证
  • 入口envoy做jwt
  • 入口envoy做tls透传,各sidecat envoy做jwt
  • 入口envoy、sidecat做mtls、jwt

身份认证机制

  • 服务间认证:mtls,基于证书,证书由彼此间信任的ca签发
    • 动态环境中,需要动态完成pod身份发放(spiffe框架),向sidecar envoy发放证书和私钥(sds、ca)
  • 最终用户认证:jwt(OAuth2、OIDC协议),客户端访问服务时,对访问者身份验证
    • 客户端基于http标头向服务端发送jwt,服务端验证签名
    • 使用envoy.filters.http.jwt_authn过滤器

envoy tls

支持在侦听器、集群配置tls

image-20231211163659051

工作机制:

底层使用boringSSL作为ssl库
DownstreamTlsContexts支持多个tls证书(多个证书需要同一类型,RSA、ECDSA),但UpstreamTlsContexts目前仅支持单个证书

tls配置

使用扩展支持tls通信,扩展为:

  • envoy.transport_sockets.tls

针对客户端和后端,有分别的配置:

  • 上游后端:extensions.tranposrt_sockets.tls.v3.UpstreamTlsContext
  • 下游客户端:extensions.transport_sockets.tls.v3.DownstreamTlsContext

数字证书配置

可通过sds动态获取也可静态配置,无需重启envoy
envoy与sds服务器之间的通信必须使用安全连接,sds服务器需要使用grpc协议

tls透传

下游与envoy仅建立tcp连接,envoy将https转给上游处理

配置:

filter_chains:
- filters:
  - name: envoy.filters.network.tcp_proxy
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.network.tcp_proxy.v3.TcpProxy
      cluster: web_cluster_1
      stat_prefix: tcp_tls_forwad

配置案例:

例1:静态

static_resources:
  secrets
  - name: server_cert
    tls_certificate:
      certificate_chain:
        filename: "/etc/envoy/certs/server.crt"
      private_key:
        filename: "/etc/envoy/certs/server.key"
  - name: client_cert
    tls_certificate:
      certificate_chain:
        filename: "/etc/envoy/certs/client.crt"
      private_key:
        filename: "/etc/envoy/certs/client.key"
  - name: valid_context
    validation_context:
      trusted_ca
        filename: "/etc/envoy/certs/ca.crt"
  listeners:
  - name: http
    address:
      socket_address: { address: 0.0.0.0, port_value: 80 }
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        http_filters:
        - name: envoy.filters.http.route
        ...
        route_config:
          name: local
          virtual_hosts:
          - name: backend
            domains:
            - '*'
            routes:
            - match:
                prefix: '/'
              redirect:
                https_redirect: true
                port_redirect: 443
  - name: https
    address:
      socket_address: { address: 0.0.0.0, port_value: 443 }
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
      transport_socket:
        name: envoy.transport_sockets.tls
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsConetext
          common_tls_context:
            tls_certificate_sds_secret_configs:
            - name: server_cert

例2:远程通信使用sds,本地内部通信使用套接字

clusters:
- name: sds_server_mtls
  typed_extension_protocol_options:
    envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
      "@type": type.gooleapis.com/envoy.extenions.upstreams.http.v3.HttpProtocolOptions
      explicit_http_config:
        http2_protocol_options:
          connection_keepalive:
            interval: 30s
            timeout: 5s
    load_assignment:
      cluster_name: sds_server
      endpoions:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address: { address: 127.0.0.1, port_value: 8234 }
    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
        common_tls_context:
        - tls_certificate:
          certificate_chain:
            filename: certs/sds.pem
          private_key:
            filename: certs/sds.key
- name: sds_usd
  typed_extension_protocol_options:
    envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
      "@type": type.gooleapis.com/envoy.extenions.upstreams.http.v3.HttpProtocolOptions
      explicit_http_config: {}
    load_assignment:
      cluster_name: sds_uds
      endpoions:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address: { address: pipe { path: /tmp/usd_path } }
- name: sds
  connect_timeout: 0.25s
  load_assignment:
    cluster_name: local_tls
    ...
    transport_docket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
        common_tls_context:
          tls_certificate_sds_secret_configs:
          - name: client_cert
            sds_config:
              resource_api_version: V3
              api_config_source:
                api_type: GRPC
                transport_api_version: V3
                grpc_services:
                  goole_grpc:
                    target_uri: unix:/tmp/usd_path

spiffe和spire

spiffe是开源安全生产身份框架(可信bootstrap和identification框架),已被cncf收录

spiffe标准定义了一套能够跨异构环境和组织边界完成bootstrap以及向服务发布身份ID的规模框架,这些规范的核心是定义短期身份文档的规范,称为SVID,随后工作负载可以在向其他工作负载进行身份验证时,使用这些身份文档,如建立tls连接,或jwt令牌

spiffe规范标准化了工作负载的分配身份、验证、确认工作负载以及向工作负载api检索身份的过程

spiffe身份包含在svid(spiffe Verifiable Identify Document)中,svid规范提供了实现svid时必须支持的属性的要求

基于spiffe实现的应用

  • spire
  • lstio
  • hashicorp consul
  • kuma

spiffe框架

spiffe id

标准化身份命名空间,定义服务如何确认彼此身份
唯一标识符,一个workload字符串,也可表示workload运行的中间层,如虚拟机、k8s等

uri格式:

spiffe://信任域名/workload identifier

spiffe://可信域/namespace/ns名称/serviceaccounts/sa名

可信域
  • 对应1个系统的ca,统一个可信域的所有workload都属于这个域的ca进行验证
  • 可信域名自定义注册,与公共dns不同,可信域没有委派机制,可信域中必须存储签名机构,且该域名机构必须拥有自己的svid

svid

定义如何表示及验证办法的身份标识的规范
svid是workload用于证明自身身份的文档,可由可信域的ca签署后才生效
svid将spiffe id编码为可加密验证的文档,目前支持x.509和jwt-svid两种编码格式(jwt容易受到重放攻击,建议用证书)

workload api

工作负载值单个应用程序,可能包含多个正在运行的实例,所有这些实例都执行相同的任务,workload api用于颁发x.509-svid和jwt-svid

spire框架

组件:

spire server

签名授权机构,通过spire agent接收请求

负责管理和发布已配置的spiffe可信域中的所有身份,它存储条目(指定特定的spiffe id的发布条件的选择器)和签名秘钥,并使用node attestation自动认证agent的身份,并在经过认证的agent请求时,为其本地的workload创建svid

插件
  • node attestor插件:负责结合各节点上运行的agent node attestor插件来验证节点身份
  • node resolver:为server端提供一些列选择器, 可基于其他属性来验证节点身份
  • datastore插件:用于存储、查询、更新信息,如registration entries,包括哪些节点身份已经证明,这些节点各自相关的选择器等(内置数据存储插件用sqlite3火pgsql,默认前者)
  • key manager插件:负责控制服务器如何存储用于签署x509和jwt的私钥

注:默认情况下,spire server充当子集的证书颁发机构,必要时也可使用ipstream certificate authority插件(CA插件)来使用来自不同pki系统的不同ca

spire agent

运行在工作节点,用于向节点上的workload提供workload api。从服务器请求svid,并缓存它,直到workload请求对应的svid

将spiffe workload api暴露给本地节点上的workload,并负责证明调用它的workload的身份

在k8s环境中,可以直接使用kubelet当做spire agent,因为所有pod只有信任这个节点才能运行

签发svid流程

image-20230905142919892


JWT认证

jwt全称json web token,做base64编码

目前无状态的http应用在跟踪用户状态的常用解决方案有2种,session认证和token认证

image-20231211230858079

基于session认证

用户成功登陆后,服务器为其创建并存储1个session(map结构,有sessionID),并通过set-cookie将sessionID返回给客户端作为cookie,客户端随后的请求都将在标头中通过cookie附带该sessionID,并由服务器验证

弊端

  • 服务端需要将session存储在内存中,数据量大时,存储占据开销
  • 用户的cookie被截获后,易导致csrf攻击

基于token认证

用户完成登陆后,服务器使用secret创建jwt,并将jwt返回给客户端存储,客户端在随后的请求标头中附带jwt,服务器在完成验证

服务端认证后返回json对象,客户端每次请求都要附加此对象,为防止客户端修改json对象,需要对它进行签名

其中,令牌的签发、认证、校验的过程可以委托给第三方完成(认证中心),这就变成客户端访问server时,server与第三方交互,签发、检验等,server与第三方通信的协议就是OAuth2


授权

RBAC:

基于角色的访问控制,围绕角色和许可定义,与策略无关

过滤器:

envoy.filters.http.rbac

支持基于连接属性(ip、端口、ssl对象)、请求标头(安全列表allow、阻止列表deny)策略集进行配置

支持强制模式和影子模式,影子模式仅用于验证策略而不会产生真正的影响

配置:

  • action:执行的操作,允许时只要匹配一个策略;拒绝时无任何匹配
  • policies:从策略名称到策略的映射,成功的条件至少1个策略与请求匹配
action: str     #策略匹配时的操作行为,支持ALLOW、DENY
policies:
  自定义角色名:     #角色名
    permissions:      #角色上的权限,选项间关机为或
      any: boolean    #是否匹配所有操作
      header: {}      #匹配请求标头
      destination_ip: {}    #目标ip匹配
      metadata: {}
      requested_server_name: str    #针对客户端的目标服务器的操作权限
      and_rules: {}     #与关系,定义一组操作权限
      or_rules: {}      #或关系,定义一组操作权限
      not_rules: {}     #非关系,定义一组操作权限
    principals:
    - any: true
      authenticated: {}   #经过认证的
      header: {}    #http请求标头
      metadata: {}    #描述有关subject的其他信息的元数据
      and_ids: {}
      or_ids: {}
      not_ids: {}
例:
action: ALLOW
policies:
  "service-admin":
    permissions:
    - any: true
    principals:
    - authenticated:
        principal_name:
          exact: "cluster.local/ns/default/sa/admin"
    - authenticated:
        principal_name:
          exact: "cluster.local/ns/default/sa/superuser"
  "product-viewer":
    permissions:
    - and_rules:
        rules:
        - header: { name: ":method", exact_match: "GET" }
        - header: { name: ":path", regex_match: "/products(/.*)?" }
    - or_rules:
        rules:
        - destination_port: 80
        - destination_port: 443
    principals:
    - any: true

ABAC:

将属性组合为策略授权用户访问权限,相比于RBAC兼顾角色和组之外的属性,可基于复杂的布尔规则集定义。动态授权管理机制,细粒度授权

外部授权

调用第三方授权服务来核验用户权限

外部授权服务通常应该定义为上游集群 ,收到请求并核验其授权时,若外部授权服务不可用,请求是否能获得授权则取决于过滤器的 failure_mode_allow参数的配置;

过滤器:

2个可以组合使用,网络失败会直接关闭连接,http失败则403

config.filter.network.ext_authz.v3.ExtAuthz #网络过滤器

config.filter.http.ext_authz.v3.ExtAuthz #http过滤器

OPA(open policy agent):

go编写的开源通用策略引擎,通过高级声明式语言rego(脚本)编写策略代码为应用程序实现细粒度访问控制。可用于微服务、k8s、ci/cd的pipeline、api网关等场景

opa可同微服务一起部署为独立运行的服务,如sidecar形式运行

一般发往微服务的每个请求都需要获得授权后才能进行处理,而为例检查授权,微服务则需要对opa服务发出api调用,以确定收到的请求是否被授权,但策略的执行需要由应用程序完成,如http请求被策略拒绝时应用程序需要响应403


配置

listeners:
- name: str
  address: {}
  ...
  filter_chains:
  - filter_chain_match: {}
    filters:
    - name: envoy.filters.network.http_connection_manager
    use_proxy_proto: {}
    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
        common_tls_context:         #通用tls配置,如加密算法、证书等
        require_client_certificate:   #是否强制校验客户端证书
        session_ticket_key:         #为可以恢复tls会话,服务器使用session key将会话加密后发送给客户端保存,客户端需要透明支持该功能
        session_ticket_key_sds_secret_config:         #使用sds api请求加载session ticker key的配置
        disable_stateless_session_resumption: 布尔值     #true为不生成session_ticket,只启用stateless session;false为生成加密会话,使用的会话key可用session_ticket_key或session_ticket_key_sds_secret_config定义,未定义时自动生成
        session_timeout: 时间           #会话超时时间
        ocsp_staple_policy:             #
    transport_socket_connect_timeout: {}
clusters:
- name: str
  ...
  transport_socket:         #上游后端配置tls
    name: envoy.transport_sockets.tls
    typed_config:
      "@type": type.googleapi.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
      common_tls_context:         #通用tls配置
        tls_params:
          tls_minimum_protocol_version: TLS1.2    #最小tls版本,默认客户端1.2,服务端1.0
          tls_mmaximum_protocol_version: TLS1.2   #默认客户端1.2,服务端1.3
          cipher_suites: []         #tls1.0到1.2版本协商中支持的加密算法列表,1.3不受影响
          ecdh_curves: []           #使用ecdh curve算法
        tls_certificate_chain:      #证书,刺配静态配置,静态和动态不可同时配置
          filename: 文件            #证书文件
          inline_bytes: 字节证书        #证书字节码字符串
          inline_string: 证书           #证书字符串
        private_key: 私钥           #私钥配置,语法与公钥类似
        watched_directory:          #基于sds协议从文件系统加载证书和私钥监视的目录
          path: 目录                #监视的目录
      tls_certifacate_sds_secret_configs:       #通过sds动态加载secret配置,与静态互斥
      - name: xx              #引用的secret名。若同时指定sds_config配置,则从sds动态加载证书
        sds_configs:          #sds配置
          path:           #基于文件实现sds,以下3种只能取一个
          api_config_source:      #基于sds订阅
            api_type: GRPC
            transport_api_version: V3
            grpc_services:
              goole_grpc:
                target_uri: unix:/tmp/usd_path      #使用套接字
              envoy_grpc:
                cluster_name: sds集群               #使用集群
          ads:                    #基于ads订阅
          initial_fetch_timeout: 时间   #初始加载的超时时间
          resource_api_version: V3    #资源的api版本
      validation_context:               #校验对端证书相关配置
        trusted_ca: {}            #信任ca,支持文件、字节码、字符串冲加载
        watched_directory: {}     #sds监视的目录
        verify_certificate_spki: []     #spki校验,经过base64编码的spki的sha-256检验码列表
        verify_certificate_hash: []     #hash校验,仅该列表中的hash对应的证书会被接受
        match_subject_alt_names: []     #subject的可替换名称列表
        crl: {}             #证书吊销列表,相关信息可从文件、字节码、字符串中加载
        allow_expired_certificate:      #是否接受已经过期的证书
        trust_chain_verificate:          #证书信任链的校验模式,支持:VERIFY_TRUST_CHAIN、ACCEPT_UNTRUSTED,默认第一个
      validation_context_sds_secret_config:     #sds动态加载的校验配置
        name: xx            #引用的secret名。若同时指定sds_config配置,则从sds动态加载证书
        sds_config:         #sds服务端配置,与tls_certifacate_sds_secret_configs中一样
      combined_validation_context:        #混合模式的validation context加载机制,同时给了静态配置和sds,sds有返回数据时2者合并后使用
        default_validation_context: {}      #默认使用的validation_context
        validation_context_sds_secret_config: {}      #sds加载校验对端证书的配置
      sni:                    #sni支持基于FQDN的tls,创建tls后端连接时使用sni字符串
      allow_renegitiation: 布尔值       #是否启用协调机制(不安全)
      max_session_key: 1            #默认1为存储session恢复的key最大数量,0为禁止会话恢复

案例

例1:https到https

image-20231211181000530

1)front-envoy.yaml
admin:
  profile_path: /tmp/envoy.prof
  access_log_path: /tmp/admin_access.log
  address:
    socket_address:
       address: 0.0.0.0
       port_value: 9901

static_resources:
  listeners:
  - name: listener_http
    address:
      socket_address: { address: 0.0.0.0, port_value: 8443 }
    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
          codec_type: AUTO
          route_config:
            name: local_route
            virtual_hosts:
            - name: web_service_01
              domains: ["*"]
              routes:
              - match: { prefix: "/" }
                route: { cluster: web_cluster_01 }
          http_filters:
          - name: envoy.filters.http.router
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
      transport_socket:
        name: envoy.transport_sockets.tls
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
          common_tls_context:
            tls_certificates:
            - certificate_chain:
                filename: "/etc/envoy/certs/front-proxy.crt"
              private_key:
                filename: "/etc/envoy/certs/front-proxy.key"

  clusters:
  - name: web_cluster_01
    connect_timeout: 0.25s
    type: STATIC
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: web_cluster_01
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address: { address: 172.31.8.11, port_value: 443 }
        - endpoint:
            address:
              socket_address: { address: 172.31.8.12, port_value: 443 }
    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContex
2)envoy-sidecar-proxy.yaml
admin:
  profile_path: /tmp/envoy.prof
  access_log_path: /tmp/admin_access.log
  address:
    socket_address:
       address: 0.0.0.0
       port_value: 9901

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 443 }
    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
          codec_type: AUTO
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service 
              domains: ["*"]
              routes:
              - match: { prefix: "/" }
                route: { cluster: local_cluster }
          http_filters:
          - name: envoy.filters.http.router
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
      transport_socket:
        name: envoy.transport_sockets.tls
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
          common_tls_context:
            tls_certificates:
            - certificate_chain:
                filename: "/etc/envoy/certs/webserver.crt"
              private_key:
                filename: "/etc/envoy/certs/webserver.key"

  clusters:
  - name: local_cluster
    connect_timeout: 0.25s
    type: STATIC
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: local_cluster
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address: { address: 127.0.0.1, port_value: 8080 }
3)生成证书
mkdir front-proxy-certs sidecar-proxy-certs

openssl req -x509 -newkey rsa:2048 -keyout front-proxy-certs/front-proxy.key -out  front-proxy-certs/front-proxy.crt -days 3650 -nodes -subj '/CN=www.hj.com'

openssl req -x509 -newkey rsa:2048 -keyout sidecar-proxy-certs/webserver.key -out  sidecar-proxy-certs/webserver.crt -days 3650 -nodes -subj '/CN=webserver.hj.com'

chmod o+rwx -R front-proxy-certs/ sidecar-proxy-certs/
4)docker-compose.yaml
version: '3.3'

services:
  envoy:
    image: envoyproxy/envoy:v1.23-latest
    volumes:
    - ./front-envoy.yaml:/etc/envoy/envoy.yaml
    - ./front-proxy-certs/:/etc/envoy/certs/
    networks:
      envoymesh:
        ipv4_address: 172.31.8.2
        aliases:
        - front-proxy
    depends_on:
    - webserver01-sidecar
    - webserver02-sidecar

  webserver01-sidecar:
    image: envoyproxy/envoy:v1.23-latest
    volumes:
    - ./envoy-sidecar-proxy.yaml:/etc/envoy/envoy.yaml
    - ./sidecar-proxy-certs/:/etc/envoy/certs/
    hostname: webserver01
    networks:
      envoymesh:
        ipv4_address: 172.31.8.11
        aliases:
        - webserver01-sidecar

  webserver01:
    image: ikubernetes/demoapp:v1.0
    environment:
      - PORT=8080
      - HOST=127.0.0.1
    network_mode: "service:webserver01-sidecar"
    depends_on:
    - webserver01-sidecar

  webserver02-sidecar:
    image: envoyproxy/envoy:v1.23-latest
    volumes:
    - ./envoy-sidecar-proxy.yaml:/etc/envoy/envoy.yaml
    - ./sidecar-proxy-certs/:/etc/envoy/certs/
    hostname: webserver02
    networks:
      envoymesh:
        ipv4_address: 172.31.8.12
        aliases:
        - webserver02-sidecar

  webserver02:
    image: ikubernetes/demoapp:v1.0
    environment:
      - PORT=8080
      - HOST=127.0.0.1
    network_mode: "service:webserver02-sidecar"
    depends_on:
    - webserver02-sidecar

networks:
  envoymesh:
    driver: bridge
    ipam:
      config:
        - subnet: 172.31.8.0/24
5)测试
curl -k -v https://172.31.8.2:8443/

image-20231211181822039

例2:https透传

下游tcp连接envoy,envoy将https转给上游

image-20231212131842381

1)front-envoy.yaml
admin:
  profile_path: /tmp/envoy.prof
  access_log_path: /tmp/admin_access.log
  address:
    socket_address:
       address: 0.0.0.0
       port_value: 9901

static_resources:
  listeners:
  - name: listener_http
    address:
      socket_address: { address: 0.0.0.0, port_value: 8443 }
    filter_chains:
    - filters:
      - name: envoy.filters.network.tcp_proxy
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
          cluster: web_cluster_01
          stat_prefix: https_passthrough

  clusters:
  - name: web_cluster_01
    connect_timeout: 0.25s
    type: STATIC
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: web_cluster_01
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address: { address: 172.31.9.11, port_value: 443 }
        - endpoint:
            address:
              socket_address: { address: 172.31.9.12, port_value: 443 }
2)envoy-sidecar-proxy.yaml
admin:
  profile_path: /tmp/envoy.prof
  access_log_path: /tmp/admin_access.log
  address:
    socket_address:
       address: 0.0.0.0
       port_value: 9901

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 443 }
    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
          codec_type: AUTO
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service 
              domains: ["*"]
              routes:
              - match: { prefix: "/" }
                route: { cluster: local_cluster }
          http_filters:
          - name: envoy.filters.http.router
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
      transport_socket:
        name: envoy.transport_sockets.tls
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
          common_tls_context:
            tls_certificates:
            - certificate_chain:
                filename: "/etc/envoy/certs/webserver.crt"
              private_key:
                filename: "/etc/envoy/certs/webserver.key"

  clusters:
  - name: local_cluster
    connect_timeout: 0.25s
    type: STATIC
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: local_cluster
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address: { address: 127.0.0.1, port_value: 8080 }
3)生成证书
mkdir sidecar-proxy-certs

openssl req -x509 -newkey rsa:2048 -keyout sidecar-proxy-certs/webserver.key -out  sidecar-proxy-certs/webserver.crt -days 3650 -nodes -subj '/CN=webserver.hj.com'
4)docker-compose.yaml
version: '3.3'

services:
  envoy:
    #image: envoyproxy/envoy-alpine:v1.21-latest
    image: envoyproxy/envoy:v1.23-latest
    volumes:
    - ./front-envoy.yaml:/etc/envoy/envoy.yaml
    networks:
      envoymesh:
        ipv4_address: 172.31.9.2
        aliases:
        - front-proxy
    depends_on:
    - webserver01-sidecar
    - webserver02-sidecar

  webserver01-sidecar:
    #image: envoyproxy/envoy-alpine:v1.21-latest
    image: envoyproxy/envoy:v1.23-latest
    volumes:
    - ./envoy-sidecar-proxy.yaml:/etc/envoy/envoy.yaml
    - ./sidecar-proxy-certs/:/etc/envoy/certs/
    hostname: webserver01
    networks:
      envoymesh:
        ipv4_address: 172.31.9.11
        aliases:
        - webserver01-sidecar

  webserver01:
    image: ikubernetes/demoapp:v1.0
    environment:
      - PORT=8080
      - HOST=127.0.0.1
    network_mode: "service:webserver01-sidecar"
    depends_on:
    - webserver01-sidecar

  webserver02-sidecar:
    #image: envoyproxy/envoy-alpine:v1.21-latest
    image: envoyproxy/envoy:v1.23-latest
    volumes:
    - ./envoy-sidecar-proxy.yaml:/etc/envoy/envoy.yaml
    - ./sidecar-proxy-certs/:/etc/envoy/certs/
    hostname: webserver02
    networks:
      envoymesh:
        ipv4_address: 172.31.9.12
        aliases:
        - webserver02-sidecar

  webserver02:
    image: ikubernetes/demoapp:v1.0
    environment:
      - PORT=8080
      - HOST=127.0.0.1
    network_mode: "service:webserver02-sidecar"
    depends_on:
    - webserver02-sidecar

networks:
  envoymesh:
    driver: bridge
    ipam:
      config:
        - subnet: 172.31.9.0/24
posted @ 2023-12-13 16:33  suyanhj  阅读(150)  评论(0)    收藏  举报