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
工作机制:
底层使用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流程
JWT认证
jwt全称json web token,做base64编码
目前无状态的http应用在跟踪用户状态的常用解决方案有2种,session认证和token认证
基于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
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/
例2:https透传
下游tcp连接envoy,envoy将https转给上游
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