Istio 中实现客户端源 IP 的保持
作者
尹烨,腾讯专家工程师, 腾讯云 TCM 产品负责人。在 K8s、Service Mesh 等方面有多年的实践经验。
导语
对于很多后端服务业务,我们都希望得到客户端源 IP。云上的负载均衡器,比如,腾讯云 CLB 支持将客户端源IP传递到后端服务。但在使用 istio 的时候,由于 istio ingressgateway 以及 sidecar 的存在,后端服务如果需要获取客户端源 IP,特别是四层协议,情况会变得比较复杂。
正文
很多业务场景,我们都希望得到客户端源 IP。云上负载均衡器,比如,腾讯云 CLB支持将客户端 IP 传递到后端服务。TKE/TCM 也对该能力做了很好的集成。
但在使用 istio 的时候,由于中间链路上,istio ingressgateway 以及 sidecar 的存在,后端服务如果需要获取客户端 IP,特别是四层协议,情况会变得比较复杂。
对于应用服务来说,它只能看到 Envoy 过来的连接。
一些常见的源 IP 保持方法
先看看一些常见 Loadbalancer/Proxy 的源 IP 保持方法。我们的应用协议一般都是四层、或者七层协议。
七层协议的源 IP 保持
七层的客户端源 IP 保持方式比较简单,最具代表性的是 HTTP 头XFF(X-Forwarded-For)
,XFF 保存原始客户端的源 IP,并透传到后端,应用可以解析 XFF 头,得到客户端的源 IP。常见的七层代理组件,比如 Nginx、Haproxy,包括 Envoy 都支持该功能。
四层协议的源 IP 保持
DNAT
IPVS/iptables
都支持 DNAT,客户端通过 VIP 访问 LB,请求报文到达 LB 时,LB 根据连接调度算法选择一个后端 Server,将报文的目标地址 VIP 改写成选定 Server 的地址,报文的目标端口改写成选定 Server 的相应端口,最后将修改后的报文发送给选出的 Server。由于 LB 在转发报文时,没有修改报文的源 IP,所以,后端 Server 可以看到客户端的源 IP。
Transparent Proxy
Nginx/Haproxy
支持透明代理(Transparent Proxy
)。当开启该配置时,LB 与后端服务建立连接时,会将 socket 的源 IP 绑定为客户端的 IP 地址,这里依赖内核TPROXY以及 socket 的 IP_TRANSPARENT
选项。
此外,上面两种方式,后端服务的响应必须经过 LB,再回到 Client,一般还需要策略路由的配合。
TOA
TOA(TCP Option Address
)是基于四层协议(TCP)获取真实源 IP 的方法,本质是将源 IP 地址插入 TCP 协议的 Options 字段。这需要内核安装对应的TOA内核模块。
Proxy Protocol
Proxy Protocol是 Haproxy 实现的一个四层源地址保留方案。它的原理特别简单,Proxy 在与后端 Server 建立 TCP 连接后,在发送实际应用数据之前,首先发送一个Proxy Protocol
协议头(包括客户端源 IP/端口、目标IP/端口等信息)。这样,后端 server 通过解析协议头获取真实的客户端源 IP 地址。
Proxy Protocol
需要 Proxy 和 Server 同时支持该协议。但它却可以实现跨多层中间代理保持源 IP。这有点类似七层 XFF 的设计思想。
istio 中实现源 IP 保持
istio 中,由于 istio ingressgateway 以及 sidecar 的存在,应用要获取客户端源 IP 地址,会变得比较困难。但 Envoy 本身为了支持透明代理,它支持Proxy Protocol
,再结合 TPROXY,我们可以在 istio 的服务中获取到源 IP。
东西向流量
istio 东西向服务访问时,由于 Sidecar 的注入,所有进出服务的流量均被 Envoy 拦截代理,然后再由 Envoy 将请求转给应用。所以,应用收到的请求的源地址,是 Envoy 访问过来的地址127.0.0.6
。
# kubectl -n foo apply -f samples/httpbin/httpbin.yaml # kubectl -n foo apply -f samples/sleep/sleep.yaml # kubectl -n foo get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES httpbin-74fb669cc6-qvlb5 2/2 Running 0 4m9s 172.17.0.57 10.206.2.144 <none> <none> sleep-74b7c4c84c-9nbtr 2/2 Running 0 6s 172.17.0.58 10.206.2.144 <none> <none> # kubectl -n foo exec -it deploy/sleep -c sleep -- curl http://httpbin:8000/ip { "origin": "127.0.0.6" }
可以看到,httpbin 看到的源 IP 是127.0.0.6
。从 socket 信息,也可以确认这一点。
# kubectl -n foo exec -it deploy/httpbin -c httpbin -- netstat -ntp | grep 80 tcp 0 0 172.17.0.57:80 127.0.0.6:56043 TIME_WAIT -
- istio 开启 TPROXY
我们修改 httpbin deployment,使用 TPROXY(注意httpbin
的 IP 变成了172.17.0.59
):
# kubectl patch deployment -n foo httpbin -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/interceptionMode":"TPROXY"}}}}}' # kubectl -n foo get pods -l app=httpbin -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES httpbin-6565f59ff8-plnn7 2/2 Running 0 43m 172.17.0.59 10.206.2.144 <none> <none> # kubectl -n foo exec -it deploy/sleep -c sleep -- curl http://httpbin:8000/ip { "origin": "172.17.0.58" }
可以看到,httpbin 可以得到 sleep 端的真实 IP。
socket 的状态:
# kubectl -n foo exec -it deploy/httpbin -c httpbin -- netstat -ntp | grep 80 tcp 0 0 172.17.0.59:80 172.17.0.58:35899 ESTABLISHED 9/python3 tcp 0 0 172.17.0.58:35899 172.17.0.59:80 ESTABLISHED -
第一行是 httpbin 的接收端 socket,第二行是 envoy 的发送端 socket。
httpbin envoy
日志:
{"bytes_received":0,"upstream_local_address":"172.17.0.58:35899", "downstream_remote_address":"172.17.0.58:46864","x_forwarded_for":null, "path":"/ip","istio_policy_status":null, "response_code":200,"upstream_service_time":"1", "authority":"httpbin:8000","start_time":"2022-05-30T02:09:13.892Z", "downstream_local_address":"172.17.0.59:80","user_agent":"curl/7.81.0-DEV","response_flags":"-", "upstream_transport_failure_reason":null,"request_id":"2b2ab6cc-78da-95c0-b278-5b3e30b514a0", "protocol":"HTTP/1.1","requested_server_name":null,"duration":1,"bytes_sent":30,"route_name":"default", "upstream_cluster":"inbound|80||","upstream_host":"172.17.0.59:80","method":"GET"}
可以看到,
- downstream_remote_address: 172.17.0.58:46864 ## sleep的地址
- downstream_local_address: 172.17.0.59:80 ## sleep访问的目标地址
- upstream_local_address: 172.17.0.58:35899 ## httpbin envoy连接httpbin的local address(为sleep的IP)
- upstream_host: 172.17.0.59:80 ## httpbin envoy访问的目标地址
httpbin envoy 连接 httpbin 的 local address 为 sleep 的 IP 地址。
南北向流量
对于南北向流量,客户端先请求 CLB,CLB 将请求转给 ingressgateway,再转到后端服务,由于中间多了 ingressgateway 一跳,想要获取客户端源 IP,变得更加困难。
我们以 TCP 协议访问 httpbin:
apiVersion: v1 kind: Service metadata: name: httpbin namespace: foo labels: app: httpbin service: httpbin spec: ports: - name: tcp port: 8000 targetPort: 80 selector: app: httpbin --- apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: httpbin-gw namespace: foo spec: selector: istio: ingressgateway # use istio default controller servers: - port: number: 8000 name: tcp protocol: TCP hosts: - "*" --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: httpbin namespace: foo spec: hosts: - "*" gateways: - httpbin-gw tcp: - match: - port: 8000 route: - destination: port: number: 8000 host: httpbin
通过 ingressgateway 访问 httpbin:
# export GATEWAY_URL=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}') # curl http://$GATEWAY_URL:8000/ip { "origin": "172.17.0.54" }
可以看到,httpbin 看到的地址是ingressgateway
的地址:
# kubectl -n istio-system get pods -l istio=ingressgateway -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES istio-ingressgateway-5d5b776b7b-pxc2g 1/1 Running 0 3d15h 172.17.0.54 10.206.2.144 <none> <none>
虽然我们在httpbin envoy
开启了透明代理,但 ingressgateway 并不能把 client 的源地址传到httpbin envoy
。基于 envoy 实现的Proxy Protocol
,可以解决这个问题。
通过 EnvoyFilter 在 ingressgateway 和 httpbin 同时开启Proxy Protocol
支持。
apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: name: ingressgw-pp namespace: istio-system spec: configPatches: - applyTo: CLUSTER patch: operation: MERGE value: transport_socket: name: envoy.transport_sockets.upstream_proxy_protocol typed_config: "@type": type.googleapis.com/envoy.extensions.transport_sockets.proxy_protocol.v3.ProxyProtocolUpstreamTransport config: version: V1 transport_socket: name: "envoy.transport_sockets.raw_buffer" workloadSelector: labels: istio: ingressgateway --- apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: name: httpbin-pp namespace: foo spec: configPatches: - applyTo: LISTENER match: context: SIDECAR_INBOUND patch: operation: MERGE value: listener_filters: - name: envoy.filters.listener.proxy_protocol typed_config: "@type": type.googleapis.com/envoy.extensions.filters.listener.proxy_protocol.v3.ProxyProtocol - name: envoy.filters.listener.original_dst - name: envoy.filters.listener.original_src workloadSelector: labels: app: httpbin
再次通过 LB 访问 httpbin:
# curl http://$GATEWAY_URL:8000/ip { "origin": "106.52.131.116" }
httpbin 得到了客户端的源 IP。
- ingressgateway envoy 日志
{"istio_policy_status":null,"protocol":null,"bytes_sent":262,"downstream_remote_address":"106.52.131.116:6093","start_time":"2022-05-30T03:33:33.759Z", "upstream_service_time":null,"authority":null,"requested_server_name":null,"user_agent":null,"request_id":null, "upstream_cluster":"outbound|8000||httpbin.foo.svc.cluster.local","upstream_transport_failure_reason":null,"duration":37,"response_code":0, "method":null,"downstream_local_address":"172.17.0.54:8000","route_name":null,"upstream_host":"172.17.0.59:80","bytes_received":83,"path":null, "x_forwarded_for":null,"upstream_local_address":"172.17.0.54:36162","response_flags":"-"}
可以看到,
-
downstream_remote_address: 106.52.131.116:6093 ## 客户端源地址
-
downstream_local_address: 172.17.0.54:8000
-
upstream_local_address: 172.17.0.54:42122 ## ingressgw local addr
-
upstream_host: 172.17.0.59:80 ## httpbin 地址
- httpbin envoy日志
{"istio_policy_status":null,"response_flags":"-","protocol":null,"method":null,"upstream_transport_failure_reason":null,"authority":null,"duration":37, "x_forwarded_for":null,"user_agent":null,"downstream_remote_address":"106.52.131.116:6093","downstream_local_address":"172.17.0.59:80", "bytes_sent":262,"path":null,"requested_server_name":null,"upstream_service_time":null,"request_id":null,"bytes_received":83,"route_name":null, "upstream_local_address":"106.52.131.116:34431","upstream_host":"172.17.0.59:80","response_code":0,"start_time":"2022-05-30T03:33:33.759Z","upstream_cluster":"inbound|80||"}
可以看到,
- downstream_remote_address: 106.52.131.116:6093 ## 客户端源地址
- downstream_local_address: 172.17.0.59:80 ## httpbin地址
- upstream_local_address: 106.52.131.116:34431 ## 保留了客户端IP,port不一样
- upstream_host: 172.17.0.59:80 ## httpbin地址
值得注意的是,httpbin envoy
的upstream_local_address
保留了客户端的 IP,这样,httpbin 看到的源地址 IP,就是客户端的真实 IP。
- 数据流
相关实现分析
TRPOXY
TPROXY 的内核实现参考net/netfilter/xt_TPROXY.c。
istio-iptables
会设置下面的 iptables 规则,给数据报文设置标记。
-A PREROUTING -p tcp -j ISTIO_INBOUND -A PREROUTING -p tcp -m mark --mark 0x539 -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff -A OUTPUT -p tcp -m connmark --mark 0x539 -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff -A ISTIO_DIVERT -j MARK --set-xmark 0x539/0xffffffff -A ISTIO_DIVERT -j ACCEPT -A ISTIO_INBOUND -p tcp -m conntrack --ctstate RELATED,ESTABLISHED -j ISTIO_DIVERT -A ISTIO_INBOUND -p tcp -j ISTIO_TPROXY -A ISTIO_TPROXY ! -d 127.0.0.1/32 -p tcp -j TPROXY --on-port 15006 --on-ip 0.0.0.0 --tproxy-mark 0x539/0xffffffff
值得一提的是,TPROXY 不用依赖 NAT,本身就可以实现数据包的重定向。另外,结合策略路由,将非本地的数据包通过本地 lo 路由:
# ip rule list 0: from all lookup local 32765: from all fwmark 0x539 lookup 133 32766: from all lookup main 32767: from all lookup default # ip route show table 133 local default dev lo scope host
TPROXY 的更多详细介绍参考这里。
Envoy 中 Proxy Protocol 的实现
- proxy protocol header format
这里使用了Version 1(Human-readable header format)
,如下:
0000 50 52 4f 58 59 20 54 43 50 34 20 31 30 36 2e 35 PROXY TCP4 106.5 0010 32 2e 31 33 31 2e 31 31 36 20 31 37 32 2e 31 37 2.131.116 172.17 0020 2e 30 2e 35 34 20 36 30 39 33 20 38 30 30 30 0d .0.54 6093 8000. 0030 0a .
可以看到,header 包括 client 和 ingressgateway 的IP:PORT
信息。更加详细的介绍参考这里。
- ProxyProtocolUpstreamTransport
ingressgateway 作为发送端,使用ProxyProtocolUpstreamTransport
,构建Proxy Protocol
头部:
/// source/extensions/transport_sockets/proxy_protocol/proxy_protocol.cc void UpstreamProxyProtocolSocket::generateHeaderV1() { // Default to local addresses (used if no downstream connection exists e.g. health checks) auto src_addr = callbacks_->connection().addressProvider().localAddress(); auto dst_addr = callbacks_->connection().addressProvider().remoteAddress(); if (options_ && options_->proxyProtocolOptions().has_value()) { const auto options = options_->proxyProtocolOptions().value(); src_addr = options.src_addr_; dst_addr = options.dst_addr_; } Common::ProxyProtocol::generateV1Header(*src_addr->ip(), *dst_addr->ip(), header_buffer_); }
- envoy.filters.listener.proxy_protocol
httpbin envoy
作为接收端,配置ListenerFilter(envoy.filters.listener.proxy_protocol
)解析Proxy Protocol
头部:
/// source/extensions/filters/listener/proxy_protocol/proxy_protocol.cc ReadOrParseState Filter::onReadWorker() { Network::ConnectionSocket& socket = cb_->socket(); /// ConnectionHandlerImpl::ActiveTcpSocket ... if (proxy_protocol_header_.has_value() && !proxy_protocol_header_.value().local_command_) { ... // Only set the local address if it really changed, and mark it as address being restored. if (*proxy_protocol_header_.value().local_address_ != *socket.addressProvider().localAddress()) { /// proxy protocol header: 172.17.0.54:8000 socket.addressProvider().restoreLocalAddress(proxy_protocol_header_.value().local_address_); /// => 172.17.0.54:8000 } /// Network::ConnectionSocket socket.addressProvider().setRemoteAddress(proxy_protocol_header_.value().remote_address_); /// 修改downstream_remote_address为106.52.131.116 } // Release the file event so that we do not interfere with the connection read events. socket.ioHandle().resetFileEvents(); cb_->continueFilterChain(true); /// ConnectionHandlerImpl::ActiveTcpSocket return ReadOrParseState::Done; }
这里值得注意的,envoy.filters.listener.proxy_protocol
在解析proxy protocol header
时,local_address
为发送端的dst_addr(172.17.0.54:8000)
,remote_address
为发送端的src_addr(106.52.131.116)
。顺序刚好反过来了。
经过proxy_protocol
的处理,连接的downstream_remote_address
被修改为client的源地址。
- envoy.filters.listener.original_src
对于sidecar.istio.io/interceptionMode: TPROXY
,virtualInbound listener
会增加envoy.filters.listener.original_src
:
# istioctl -n foo pc listeners deploy/httpbin --port 15006 -o json [ { "name": "virtualInbound", "address": { "socketAddress": { "address": "0.0.0.0", "portValue": 15006 } }, "filterChains": [...], "listenerFilters": [ { "name": "envoy.filters.listener.original_dst", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.listener.original_dst.v3.OriginalDst" } }, { "name": "envoy.filters.listener.original_src", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.listener.original_src.v3.OriginalSrc", "mark": 1337 } } ... ] "listenerFiltersTimeout": "0s", "continueOnListenerFiltersTimeout": true, "transparent": true, "trafficDirection": "INBOUND", "accessLog": [...] } ]
envoy.filters.listener.original_src
通过tcp option
实现修改upstream_local_address
为downstream_remote_address
,实现透传client IP。
/// source/extensions/filters/listener/original_src/original_src.cc Network::FilterStatus OriginalSrcFilter::onAccept(Network::ListenerFilterCallbacks& cb) { auto& socket = cb.socket(); /// ConnectionHandlerImpl::ActiveTcpSocket.socket() auto address = socket.addressProvider().remoteAddress(); /// get downstream_remote_address ASSERT(address); ENVOY_LOG(debug, "Got a new connection in the original_src filter for address {}. Marking with {}", address->asString(), config_.mark()); ... auto options_to_add = Filters::Common::OriginalSrc::buildOriginalSrcOptions(std::move(address), config_.mark()); socket.addOptions(std::move(options_to_add)); /// Network::Socket::Options return Network::FilterStatus::Continue; }
- envoy.filters.listener.original_dst
另外,httbin envoy
作为 ingressgateway 的接收端,virtualInbound listener
还配置了 ListenerFilter(envoy.filters.listener.original_dst
),来看看它的作用。
// source/extensions/filters/listener/original_dst/original_dst.cc Network::FilterStatus OriginalDstFilter::onAccept(Network::ListenerFilterCallbacks& cb) { ENVOY_LOG(debug, "original_dst: New connection accepted"); Network::ConnectionSocket& socket = cb.socket(); if (socket.addressType() == Network::Address::Type::Ip) { /// socket SO_ORIGINAL_DST option Network::Address::InstanceConstSharedPtr original_local_address = getOriginalDst(socket); /// origin dst address // A listener that has the use_original_dst flag set to true can still receive // connections that are NOT redirected using iptables. If a connection was not redirected, // the address returned by getOriginalDst() matches the local address of the new socket. // In this case the listener handles the connection directly and does not hand it off. if (original_local_address) { /// change local address to origin dst address // Restore the local address to the original one. socket.addressProvider().restoreLocalAddress(original_local_address); } } return Network::FilterStatus::Continue; }
对于 istio,由 iptable 截持原有 request,并转到15006(in request),或者15001(out request)端口,所以,处理 request 的 socket 的local address
,并不请求的original dst address
。original_dst
ListenerFilter
负责将 socket 的 local address 改为original dst address
。
对于virtualOutbound listener
,不会直接添加envoy.filters.listener.original_dst
,而是将use_original_dst
设置为 true,然后 envoy 会自动添加envoy.filters.listener.original_dst
。同时,virtualOutbound listener
会将请求,转给请求原目的地址关联的 listener 进行处理。
对于virtualInbound listener
,会直接添加envoy.filters.listener.original_dst
。与virtualOutbound listener
不同的是,它只是将地址改为original dst address
,而不会将请求转给对应的 listener 处理(对于入请求,并不存在 dst address 的 listener)。实际上,对于入请求是由 FilterChain 完成处理。
参考 istio 生成virtualInbound listener
的代码:
// istio/istio/pilot/pkg/networking/core/v1alpha3/listener_builder.go func (lb *ListenerBuilder) aggregateVirtualInboundListener(passthroughInspectors map[int]enabledInspector) *ListenerBuilder { // Deprecated by envoyproxy. Replaced // 1. filter chains in this listener // 2. explicit original_dst listener filter // UseOriginalDst: proto.BoolTrue, lb.virtualInboundListener.UseOriginalDst = nil lb.virtualInboundListener.ListenerFilters = append(lb.virtualInboundListener.ListenerFilters, xdsfilters.OriginalDestination, /// 添加envoy.filters.listener.original_dst ) if lb.node.GetInterceptionMode() == model.InterceptionTproxy { /// TPROXY mode lb.virtualInboundListener.ListenerFilters = append(lb.virtualInboundListener.ListenerFilters, xdsfilters.OriginalSrc) } ...
小结
基于 TPROXY 以及 Proxy Protocol,我们可以在 istio 中,实现四层协议的客户端源 IP 的保持。
参考
- istio doc: Configuring Gateway Network Topology
- IP Transparency and Direct Server Return with NGINX and NGINX Plus as Transparent Proxy
- Kernel doc: Transparent proxy support
- Haproxy doc: The PROXY protocol
- Envoy doc: IP Transparency
- 【IstioCon 2021】如何在Istio中进行源地址保持?
关于我们
更多关于云原生的案例和知识,可关注同名【腾讯云原生】公众号~
福利:
①公众号后台回复【手册】,可获得《腾讯云原生路线图手册》&《腾讯云原生最佳实践》~
②公众号后台回复【系列】,可获得《15个系列100+篇超实用云原生原创干货合集》,包含Kubernetes 降本增效、K8s 性能优化实践、最佳实践等系列。
③公众号后台回复【白皮书】,可获得《腾讯云容器安全白皮书》&《降本之源-云原生成本管理白皮书v1.0》
④公众号后台回复【光速入门】,可获得腾讯云专家5万字精华教程,光速入门Prometheus和Grafana。
【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
TiDB 性能分析和优化
\n> 原文来源:https://tidb.net/blog/eb060e49\n\n本文介绍了基于数据库时间的系统优化方法,以及如何利用 TiDBPerformance Overview 面板进行性能分析和优化。 通过本文中介绍的方法,你可以从全局、自顶向下的角度分析用户响应时间和数据库时间,确认用户响应时间的瓶颈是否在数据库中。如果瓶颈在数据库中,你可以通过数据库时间概览和 SQL 延迟的分解,定位数据库内部的瓶颈点,并进行针对性的优化。 基于数据库时间的性能优化方法 TiDB 对 SQL 的处理路径和数据库时间进行了完善的测量和记录,方便定位数据库的性能瓶颈。即使在用户响应时间的性能数据缺失的情况下,基于 TiDB 数据库时间的相关性能指标,你也可以达到以下两个性能分析目标: 通过对比 SQL 处理平均延迟和事务中 TiDB 连接的空闲时间,确定整个系统的瓶颈是否在 TiDB 中。 如果瓶颈在 TiDB 内部,根据数据库时间概览、颜色优化法、关键指标和资源利用率、自上而下的延迟分解,定位到性能瓶颈具体在整个分布式系统的哪个模块。 确定整个系统的瓶颈是否在 TiDB 中 如果...
- 下一篇
华为云公布三大开源新项目,涉及数据库、云原生、AI
以开源软件为核心的云原生基础设施对云服务的重要性不言而喻,国内外各大云服务厂商近年来都在积极参与云原生开源社区建设。华为云在开源的云原生技术领域也做了很多工作和贡献,包括其陆续开源的 KuberEdge、Volcano、Karmada 等项目,并将之捐赠给云原生计算基金会 CNCF,在国际开源社区中也掌握了一定的话语权。 近日,华为云 CTO 张宇昕在对外媒体沟通会上透露了华为云今年即将推出的三个重要开源项目,涵盖数据库、云原生和 AI 三大技术领域。 张宇昕表示,开源是全球化协同和技术创新的重要模式,华为云一直是开源的坚定支持者和贡献者,这些年来一直坚持开源,也对外开源了一些重要的项目。华为云今年的重点开源项目将有以下 3 个: 时序时空数据库 openGemini openGemini 项目是华为云 GaussDB 的时序数据库内核,它支持多维条件组合查询,具备超强的写入能力以及海量数据的分析能力。据介绍,华为云之所以开源这个数据库,是因为时序数据库在面向互联网、物联网甚至包括企业 IT 的运维系统里面有非常广泛的应用场景,而该数据库基于时序条件下的读写性能和数据分析、压缩能力得到...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Windows10,CentOS7,CentOS8安装Nodejs环境
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS8编译安装MySQL8.0.19
- CentOS关闭SELinux安全模块
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Red5直播服务器,属于Java语言的直播服务器