目录

  • k8s服务发现Service

    • 理解
    • Service的实现模型
      • userspace代理模式
      • iptables代理模式
      • ipvs代理模式
    • Service定义
      • Service配置清单重要字段
      • 创建ClusterIP类型Service
      • 创建NodePort类型Service
      • Pod的会话保持
    • Headless无头Service
      • 参考资料

Kubernetes之(十)服务发现Service

理解

Service是对一组提供相同功能的Pods的抽象,并为它们提供一个统一的入口。借助Service,应用可以方便的实现服务发现与负载均衡,并实现应用的零宕机升级。Service通过标签来选取服务后端,一般配合Replication Controller或者Deployment来保证后端容器的正常运行。这些匹配标签的Pod IP和端口列表组成endpoints,由kubeproxy负责将服务IP负载均衡到这些endpoints上。
Service有四种类型:

  • ClusterIP:默认类型,自动分配一个仅cluster内部可以访问的虚拟IP
  • NodePort:在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过 :NodePort 来访问该服务
  • LoadBalancer:在NodePort的基础上,借助cloud provider创建一个外部的负载均衡器,并将请求转发到 :NodePort
  • ExternalName:将服务通过DNS CNAME记录方式转发到指定的域名(通过 spec.externlName 设定) 。需要kube-dns版本在1.7以上。

另外,也可以将已有的服务以Service的形式加入到Kubernetes集群中来,只需要在创建
Service的时候不指定Label selector,而是在Service创建好后手动为其添加endpoint。

Service的实现模型

在 Kubernetes 集群中,每个 Node 运行一个 kube-proxy 进程。kube-proxy 负责为 Service 实现了一种 VIP(虚拟 IP)的形式,而不是 ExternalName 的形式。 在 Kubernetes v1.0 版本,代理完全在 userspace。在 Kubernetes v1.1 版本,新增了 iptables 代理,但并不是默认的运行模式。 从 Kubernetes v1.2 起,默认就是 iptables 代理。在Kubernetes v1.8.0-beta.0中,添加了ipvs代理。在 Kubernetes v1.0 版本,Service 是 “4层”(TCP/UDP over IP)概念。 在 Kubernetes v1.1 版本,新增了 Ingress API(beta 版),用来表示 “7层”(HTTP)服务。
kube-proxy 这个组件始终监视着apiserver中有关service的变动信息,获取任何一个与service资源相关的变动状态,通过watch监视,一旦有service资源相关的变动和创建,kube-proxy都要转换为当前节点上的能够实现资源调度规则(例如:iptables、ipvs)。

userspace代理模式

当客户端Pod请求内核空间的service iptables后,把请求转到给用户空间监听的kube-proxy 的端口,由kube-proxy来处理后,再由kube-proxy将请求转给内核空间的 service ip,再由service iptalbes根据请求转给各节点中的的service pod。
这个模式有很大的问题,由客户端请求先进入内核空间的,又进去用户空间访问kube-proxy,由kube-proxy封装完成后再进去内核空间的iptables,再根据iptables的规则分发给各节点的用户空间的pod。这样流量从用户空间进出内核带来的性能损耗是不可接受的。在Kubernetes 1.1版本之前,userspace是默认的代理模型。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w8x639QH-1612426479772)(http://10.0.0.14:8181/uploads/kubetnetes/images/m_4b007aa6eec83d58515d8f8d67bfe1f2_r.png)]

iptables代理模式

客户端IP请求时,直接请求本地内核service ip,根据iptables的规则直接将请求转发到到各pod上,因为使用iptable NAT来完成转发,也存在不可忽视的性能损耗。另外,如果集群中存在上万的Service/Endpoint,那么Node上的iptables rules将会非常庞大,性能还会再打折扣。iptables代理模式由Kubernetes 1.1版本引入,自1.2版本开始成为默认类型。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZElqJDJo-1612426479783)(http://10.0.0.14:8181/uploads/kubetnetes/images/m_ec099b48ed77d624c4b7b1f32ea6efe8_r.png)]

ipvs代理模式

Kubernetes自1.9-alpha版本引入了ipvs代理模式,自1.11版本开始成为默认设置。客户端IP请求时到达内核空间时,根据ipvs的规则直接分发到各pod上。kube-proxy会监视Kubernetes Service对象和Endpoints,调用netlink接口以相应地创建ipvs规则并定期与Kubernetes Service对象和Endpoints对象同步ipvs规则,以确保ipvs状态与期望一致。访问服务时,流量将被重定向到其中一个后端Pod。

与iptables类似,ipvs基于netfilter 的 hook 功能,但使用哈希表作为底层数据结构并在内核空间中工作。这意味着ipvs可以更快地重定向流量,并且在同步代理规则时具有更好的性能。此外,ipvs为负载均衡算法提供了更多选项,如,rr轮询,lc最小连接数,dh目标哈希,sh源哈希,sed最短期望延迟,nq不排队调度。
注意: ipvs模式假定在运行kube-proxy之前在节点上都已经安装了IPVS内核模块。当kube-proxy以ipvs代理模式启动时,kube-proxy将验证节点上是否安装了IPVS模块,如果未安装,则kube-proxy将回退到iptables代理模式。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N2TuElAA-1612426479786)(http://10.0.0.14:8181/uploads/kubetnetes/images/m_4e5825eac5d1c326f4499b50c6e6603d_r.png)]

当某个服务后端pod发生变化,标签选择器适应的pod有多一个,适应的信息会立即反映到apiserver上,而kube-proxy一定可以watch到etc中的信息变化,而将它立即转为ipvs或者iptables中的规则,这一切都是动态和实时的,删除一个pod也是同样的原理。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NaKXgfPF-1612426479789)(http://10.0.0.14:8181/uploads/kubetnetes/images/m_1479135c6b7b3ab8944da7f559b45247_r.png)]

Service定义

Service配置清单重要字段

apiVersion:
kind:
metadata:
spec:clusterIP: 可以自定义,也可以动态分配ports:(与后端容器端口关联)selector:(关联到哪些pod资源上)type:服务类型

Service的服务类型
对一些应用(如 Frontend)的某些部分,可能希望通过外部(Kubernetes 集群外部)IP 地址暴露 Service。
Kubernetes ServiceTypes 允许指定一个需要的类型的 Service,默认是 ClusterIP 类型。
Type 的取值以及行为如下:

  • **ClusterIP:**通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的 ServiceType。
  • **NodePort:**通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 :,可以从集群的外部访问一个 NodePort 服务。
  • **LoadBalancer:**使用云提供商的负载均衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务。
  • **ExternalName:**通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容(例如, foo.bar.example.com)。 没有任何类型代理被创建,这只有 Kubernetes 1.7 或更高版本的 kube-dns 才支持。

创建ClusterIP类型Service

[root@master manifests]# vim redis-svc.yaml
apiVersion: v1
kind: Service
metadata:name: redisnamespace: default
spec:selector:app: redisrole: logstoreclusterIP: 10.97.97.97type: ClusterIPports:- port: 6379    #容器端口targetPort: 6379   #Pod端口

创建并查看svc:

[root@master manifests]# kubectl apply -f redis-svc.yaml
service/redis created
[root@master manifests]# kubectl get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP    4d22h
redis        ClusterIP   10.97.97.97   <none>        6379/TCP   4s

查看redis服务详细信息

[root@master manifests]# kubectl describe svc redis
Name:              redis
Namespace:         default
Labels:            <none>
Annotations:       kubectl.kubernetes.io/last-applied-configuration:{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"redis","namespace":"default"},"spec":{"clusterIP":"10.97.97.97","...
Selector:          app=redis,role=logstore
Type:              ClusterIP
IP:                10.97.97.97   #service ip
Port:              <unset>  6379/TCP
TargetPort:        6379/TCP
Endpoints:         10.244.2.43:6379   #此处的ip+端口就是pod的ip+端口
Session Affinity:  None
Events:            <none>[root@master manifests]# kubectl get pods  -o wide
NAME                     READY   STATUS    RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATES
filebeat-ds-h8rwk        1/1     Running   0          8m36s   10.244.1.39   node01   <none>           <none>
filebeat-ds-kzhxw        1/1     Running   0          8m36s   10.244.2.44   node02   <none>           <none>
readiness-httpget-pod    1/1     Running   0          2d21h   10.244.2.18   node02   <none>           <none>
redis-76c85b5744-94djm   1/1     Running   0          8m36s   10.244.2.43   node02   <none>           <none>

总结:

  • service不会直接到pod,service是直接到endpoint资源,就是地址加端口,再由endpoint再关联到pod。
  • service只要创建完,就会在dns中添加一个资源记录进行解析,添加完成即可进行解析。资源记录的格式为:SVC_NAME.NS_NAME.DOMAIN.LTD.
  • 默认的集群service 的A记录:svc.cluster.local.
  • redis服务创建的A记录:redis.default.svc.cluster.local.

创建NodePort类型Service

将myapp-deploy发布出去,并可以通过集群外部进行访问

[root@master manifests]# kubectl get pods --show-labels
NAME                            READY   STATUS    RESTARTS   AGE     LABELS
filebeat-ds-h8rwk               1/1     Running   0          12m     app=filebeat,controller-revision-hash=7f59445876,pod-template-generation=1,release=stable
filebeat-ds-kzhxw               1/1     Running   0          12m     app=filebeat,controller-revision-hash=7f59445876,pod-template-generation=1,release=stable
myapp-deploy-65df64765c-257gl   1/1     Running   0          26s     app=myapp,pod-template-hash=65df64765c,release=canary
myapp-deploy-65df64765c-czwkg   1/1     Running   0          26s     app=myapp,pod-template-hash=65df64765c,release=canary
myapp-deploy-65df64765c-hqmkd   1/1     Running   0          26s     app=myapp,pod-template-hash=65df64765c,release=canary
myapp-deploy-65df64765c-kvj92   1/1     Running   0          26s     app=myapp,pod-template-hash=65df64765c,release=canary
readiness-httpget-pod           1/1     Running   0          2d22h   <none>
redis-76c85b5744-94djm          1/1     Running   0          12m     app=redis,pod-template-hash=76c85b5744,role=logstore#编辑yaml文件
[root@master manifests]# vim myapp-svc.yaml
apiVersion: v1
kind: Service
metadata:name: myappnamespace: default
spec:selector:app: myapprelease: canaryclusterIP: 10.99.99.99type: NodePortports:- port: 80targetPort: 80nodePort: 31111    #节点端口设置非常用端口

创建并查看svc

[root@master manifests]# kubectl apply -f myapp-svc.yaml
service/myapp created
[root@master manifests]# kubectl get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP        4d22h
myapp        NodePort    10.99.99.99   <none>        80:31111/TCP   8s
redis        ClusterIP   10.97.97.97   <none>        6379/TCP       10m

此时可以在集群外使用31111端口进行访问

[root@nfs ~]# while true;do curl http://10.0.0.11:31111/hostname.html;sleep 1;done
myapp-deploy-65df64765c-czwkg
myapp-deploy-65df64765c-czwkg
myapp-deploy-65df64765c-hqmkd
myapp-deploy-65df64765c-czwkg
myapp-deploy-65df64765c-czwkg
myapp-deploy-65df64765c-czwkg
myapp-deploy-65df64765c-257gl
myapp-deploy-65df64765c-czwkg
myapp-deploy-65df64765c-257gl
myapp-deploy-65df64765c-czwkg
myapp-deploy-65df64765c-czwkg
myapp-deploy-65df64765c-czwkg
myapp-deploy-65df64765c-kvj92

**总结:**从以上例子,可以看到通过NodePort方式已经实现了从集群外部端口进行访问,访问链接如下:http://10.0.0.10:31111 。实践中并不鼓励用户自定义使用节点的端口,因为容易和其他现存的Service冲突,建议留给系统自动配置。

Pod的会话保持

Service资源还支持Session affinity(粘性会话)机制,可以将来自同一个客户端的请求始终转发至同一个后端的Pod对象,这意味着它会影响调度算法的流量分发功用,进而降低其负载均衡的效果。因此,当客户端访问Pod中的应用程序时,如果有基于客户端身份保存某些私有信息,并基于这些私有信息追踪用户的活动等一类的需求时,那么应该启用session affinity机制。

Service affinity的效果仅仅在一段时间内生效,默认值为10800秒,超出时长,客户端再次访问会重新调度。该机制仅能基于客户端IP地址识别客户端身份,它会将经由同一个NAT服务器进行原地址转换的所有客户端识别为同一个客户端,由此可知,其调度的效果并不理想。Service 资源 通过. spec. sessionAffinity 和. spec. sessionAffinityConfig 两个字段配置粘性会话。 spec. sessionAffinity 字段用于定义要使用的粘性会话的类型,它仅支持使用“ None” 和“ ClientIP” 两种属性值。如下:

[root@master ~]# kubectl explain svc.spec.sessionAffinity.
KIND:     Service
VERSION:  v1FIELD:    sessionAffinity <string>DESCRIPTION:Supports "ClientIP" and "None". Used to maintain session affinity. Enableclient IP based session affinity. Must be ClientIP or None. Defaults toNone. More info:https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

sessionAffinity支持ClientIP和None 两种方式,默认是None(随机调度) ClientIP是来自于同一个客户端的请求调度到同一个pod中:

[root@master manifests]# vim myapp-svc-clientip.yaml
apiVersion: v1
kind: Service
metadata:name: myappnamespace: default
spec:selector:app: myapprelease: canarysessionAffinity: ClientIPtype: NodePortports:- port: 80targetPort: 80nodePort: 31111[root@master manifests]# kubectl apply -f myapp-svc-clientip.yaml
service/myapp created[root@master manifests]# kubectl describe svc myapp
Name:                     myapp
Namespace:                default
Labels:                   <none>
Annotations:              kubectl.kubernetes.io/last-applied-configuration:{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"myapp","namespace":"default"},"spec":{"ports":[{"nodePort":31111,...
Selector:                 app=myapp,release=canary
Type:                     NodePort
IP:                       10.106.188.204
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  31111/TCP
Endpoints:                10.244.1.40:80,10.244.1.41:80,10.244.2.45:80 + 1 more...
Session Affinity:         ClientIP
External Traffic Policy:  Cluster
Events:                   <none>[root@nfs ~]# while true;do curl http://10.0.0.11:31111/hostname.html;sleep 1;done
myapp-deploy-65df64765c-257gl
myapp-deploy-65df64765c-257gl
myapp-deploy-65df64765c-257gl
myapp-deploy-65df64765c-257gl
myapp-deploy-65df64765c-257gl
myapp-deploy-65df64765c-257gl
myapp-deploy-65df64765c-257gl
myapp-deploy-65df64765c-257gl
myapp-deploy-65df64765c-257gl
myapp-deploy-65df64765c-257gl

也可以使用kubectl patch来动态修改

kubectl patch svc myapp -p '{"spec":{"sessionAffinity":"ClusterIP"}}'  #session保持,同一ip访问同一个pod
kubectl patch svc myapp -p '{"spec":{"sessionAffinity":"None"}}'    #取消session

Headless无头Service

有时不需要或不想要负载均衡,以及单独的Service IP。 遇到这种情况,可以通过指定 Cluster IP(spec.clusterIP)的值为 “None” 来创建 Headless Service。

这个选项允许开发人员自由寻找他们自己的方式,从而降低与 Kubernetes 系统的耦合性。 应用仍然可以使用一种自注册的模式和适配器,对其它需要发现机制的系统能够很容易地基于这个 API 来构建。

对这类 Service 并不会分配 Cluster IP,kube-proxy 不会处理它们,而且平台也不会为它们进行负载均衡和路由。 DNS 如何实现自动配置,依赖于 Service 是否定义了 selector

[root@master manifests]# vim myapp-svc-headless.yaml
apiVersion: v1
kind: Service
metadata:name: myapp-headlessnamespace: default
spec:selector:app: myapprelease: canaryclusterIP: "None"ports:- port: 80targetPort: 80

部署并查看

[root@master manifests]#  kubectl apply -f myapp-svc-headless.yaml
service/myapp-headless created
[root@master manifests]# kubectl get svc
NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes       ClusterIP   10.96.0.1        <none>        443/TCP        4d23h
myapp            NodePort    10.106.188.204   <none>        80:31111/TCP   10m
myapp-headless   ClusterIP   None             <none>        80/TCP         2s
redis            ClusterIP   10.97.97.97      <none>        6379/TCP       68m

使用coredns进行解析验证

[root@master manifests]# dig -t A myapp-svc.default.svc.cluster.local. @10.96.0.10; <<>> DiG 9.9.4-RedHat-9.9.4-73.el7_6 <<>> -t A myapp-svc.default.svc.cluster.local. @10.96.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 35237
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;myapp-svc.default.svc.cluster.local. IN        A;; AUTHORITY SECTION:
cluster.local.          30      IN      SOA     ns.dns.cluster.local. hostmaster.cluster.local. 1554105626 7200 1800 86400 30;; Query time: 2 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: 一 4月 01 16:03:40 CST 2019
;; MSG SIZE  rcvd: 157#10.96.0.10是coredns服务的svc地址
[root@master manifests]# kubectl get svc -n kube-system
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP   5d

解析普通的svc 来对比查看区别

[root@master manifests]# dig -t A myapp.default.svc.cluster.local. @10.96.0.10; <<>> DiG 9.9.4-RedHat-9.9.4-73.el7_6 <<>> -t A myapp.default.svc.cluster.local. @10.96.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26217
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0;; QUESTION SECTION:
;myapp.default.svc.cluster.local. IN    A;; ANSWER SECTION:
myapp.default.svc.cluster.local. 5 IN   A       10.99.99.99;; Query time: 0 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: 一 4月 01 16:09:34 CST 2019
;; MSG SIZE  rcvd: 96

从以上的演示可以看到对比普通的service和headless service,headless service做dns解析是直接解析到pod的,而servcie是解析到ClusterIP的。
headless无头服务主要用在statefulset中。

参考资料

https://www.cnblogs.com/linuxk
https://www.cnblogs.com/wlbl/p/10694316.html

k8s service服务发现详解:ipvs代理模式、服务类型相关推荐

  1. nacos的服务发现详解

    Nacos源码系列整体栏目 [一]nacos服务注册底层源码详解 [二]nacos服务发现底层源码详解 [三]nacos的心跳机制底层源码详解 [四]nacos配置中心的底层源码详解 nacos的服务 ...

  2. 微服务架构 与 Dubbo 微服务框架、SpringCloud 微服务框架 详解

    微服务架构 与 Dubbo 微服务框架.SpringCloud 微服务框架 详解 什么是微服务架构? 微服务架构就是将单体的应用程序分成多个应用程序,这一个应用程序就组成一个服务,这多个应用程序就组成 ...

  3. Kubernetes K8S在IPVS代理模式下Service服务的ClusterIP类型访问失败处理

    Kubernetes K8S使用IPVS代理模式,当Service的类型为ClusterIP时,如何处理访问service却不能访问后端pod的情况. 背景现象 Kubernetes K8S使用IPV ...

  4. 一文详解 Kubernetes 中的服务发现,运维请收藏

    K8S 服务发现之旅 Kubernetes 服务发现是一个经常让我产生困惑的主题之一.本文分为两个部分: 网络方面的背景知识 深入了解 Kubernetes 服务发现 要了解服务发现,首先要了解背后的 ...

  5. 【夯实Spring Cloud】Spring Cloud中的Eureka服务注册与发现详解

    本文属于[夯实Spring Cloud]系列文章,该系列旨在用通俗易懂的语言,带大家了解和学习Spring Cloud技术,希望能给读者带来一些干货.系列目录如下: [夯实Spring Cloud]D ...

  6. Kubernetes Service与Ingress详解

    SVC与Ingress 一.Service 的概念 二.Service 的类型 三.VIP 和 Service 代理 四.ipvs代理模式 五.Service实验讲解 5.1 ClusterIP 5. ...

  7. java调用webservice_笃学私教:Java开发网站架构演变过程-从单体应用到微服务架构详解...

    原标题:笃学私教:Java开发网站架构演变过程-从单体应用到微服务架构详解 Java开发网站架构演变过程,到目前为止,大致分为5个阶段,分别为单体架构.集群架构.分布式架构.SOA架构和微服务架构.下 ...

  8. k8s安装和部署详解

    k8s安装和部署详解 文章目录 k8s安装和部署详解 kubernetes官方提供的三种部署方式 minikube kubeadm 二进制包 使用kubeadm方式安装 1.准备环境 2.确认dock ...

  9. 微服务--Docker详解

    Docker详解 零.文章目录 一.Docker基础 1.容器发展 物理机 软件开发最大的麻烦事之一,就是环境配置.用户必须保证两件事:操作系统的设置,各种库和组件的安装.只有它们都正确,软件才能运行 ...

最新文章

  1. 【原创】linux命令bc使用详解
  2. Nagios+Centreon+Nrpe集成(二)
  3. 【Unity笔记】使用协程(Coroutine)异步加载场景
  4. 今天下棋,结合以前一些技巧的总结
  5. python2基本数据类型
  6. pythonsuper多重继承_小白都能理解的Python多继承
  7. 通过severlet获取请求头信息
  8. .net core 集成 autofac.
  9. SVN忽略不必要的配置文件
  10. Linux带给了我什么?
  11. ajax.actionlink使用问题
  12. Diango博客--17.统计各个分类和标签下的文章数
  13. 各层作用_终于弄明白了 Singleton,Transient,Scoped 的作用域是如何实现的
  14. HTML+CSS+JS实现canvas仿ps橡皮擦刮卡效果
  15. 重磅!一文读懂线性方程组的求解方法
  16. ubuntu未发现wifi适配器_Windows 10 9月更新频翻车,1903版本网络适配器又出bug
  17. 数据结构之---二叉树前序,中序,后序
  18. [转载]github在线更改mysql表结构工具gh-ost
  19. 中国口岸年鉴(2001-2015年)
  20. 新广告法违规词、敏感词在线检测工具 淘宝违规词检测、查询

热门文章

  1. 程序员硬核宝典(面试题集、在线免费工具箱)
  2. 【Python】Python爬虫快速入门,BeautifulSoup基本使用及实践
  3. 当深度学习遇上图: 图神经网络的兴起!(文末送书)
  4. 轻量高效!清华智能计算实验室开源基于PyTorch的视频 (图片) 去模糊框架SimDeblur
  5. 推荐算法工程笔记:PySpark特征工程入门总结
  6. Active Noise Cancelling-主动噪声消除
  7. 网易云信亮相LiveVideoStackCon 2019,分享BBR在实时音视频领域的应用
  8. MIUI 9稳定版即将推送,米粉:升级小米6相机算法比升级系统重要
  9. Minimal安装CentOS 7使用yum报This system is not registered to Red Hat Subscription Management.
  10. Python 十七章 Web开发