k8s服务发现

基础知识 了解服务发现之前,先明确k8s内部为什么需要服务发现,而在了解为什么需要服务发现之前,先看下pod、service他们的关系。 应用运行在k8s的容器之中,而容器运行在pod内,一般来说一个pod一个容器 每个pod都处于一个扁平的IP网段内,每个pod都有其唯一IP,在这个网段内pod之间可以直接进行通信 在这个网络内,会新增、删除pod,从而也会分配新的IP或者删除IP,对于我们在pod内的应用来说,就得手动维护一个应用的IP列表,以此知道我们要访问别的应用时,对应的是哪个IP,非常耦合以及痛苦。 好在k8s提供了service这个组件,从网络的层面上,一个service代表了一组pod。当需要访问pod内的应用时,访问service的ip即可,而service除非手动删除变更,否则他的ip是稳定的。因此外界从直接访问ip经常变化的pod,变成了访问ip稳定的service,再由service将流量负载均衡到这些pod上。 服务发现是什么 平时用浏览器上过网都知道,输入一个网址比如google.com就能访问内容,背后是DNS帮我们将google.com解析成IP地址,最终浏览器才能基于TCP协议,从本地连接到这个服务提供商的IP地址。所以DNS属于服务发现的其中一种方式。 对于k8s内部来说,如果一个service中的pod的应用,想访问处于另一个service中pod的应用,最简单的就是知道对方service的IP地址。但我们编写应用的时候往往更希望连接的是一个service的名字而不是service的IP,因为service的IP说到底也还是动态分配的,如果service经过销毁重建,IP变化了,应用代码也得跟着改。 因此k8s需要服务发现,将service的名字解析为service的IP供应用去正确访问。 服务发现实际上包含两个功能点: 服务注册 服务发现 服务注册 k8s使用的是DNS服务发现,每个k8s集群都会在kube-system命名空间中运行DNS服务(这个服务本质上也是pod内的应用),称为集群DNS。每个service都会自动注册到集群DNS中,注册过程如下: 向API server提交一个新的service定义请求,请求经过认证、鉴权等准入策略后放行 Service分配得到ClusterIP,保存到集群数据仓库 在集群范围内传播该Service配置 集群DNS感知到该Service创建,创建DNS A记录 可以看到最关键的是第4步,这一步创建了A记录指向ClusterIP,这个A记录名称就是service的metadata.name,并且之后会持续关注这个Service对象。 接着就是service管理的pods,k8s自动为每个service创建endpoints对象,其中保存的是匹配标签选择器的pod列表,service后续会将流量负载均衡到这些pod上。 服务发现 为了让应用使用上集群DNS提供的服务发现功能,每个pod中的每个容器的/etc/resolv.conf文件都被配置为使用集群DNS进行解析。 比如图中my-app中的应用想要访问your-app中的应用,就得拿着"your-app-svr"这个名称去查询DNS服务拿到IP 10.0.0.20,但显然容器的网关并不维护到这个IP的路由,最终会缺省地转发到pod所在节点的网卡上,随后转发到节点的缺省网关,经过节点内核。 在继续之前,有必要插播一下:k8s的每个节点上都会运行一个名为kube-proxy的服务,其会监控API Server上service的变化,这些变化包括endpoints的变化(对应pod的增删),并根据这些变化创建iptables或IPVS规则,目的是告知节点捕获目标为Service的网络报文并转发给pod。 因此my-app发送出来的这个报文,最终会到达节点的缺省网关,经过节点内核时根据kube-proxy写入的路由规则,报文的目标IP被改成目标pod的IP。 参考 浅谈 Kubernetes 中的服务发现

十月 20, 2024 · by NOSAE

epoll中的LT和ET

本来我在看的是golang的gmp调度器,然后看到注释和代码里面有提到netpoll这个东西,不知不觉又去翻看了下linux网络编程相关的知识,上网找了下博客,找到了ants开源库作者关于go netpoll的博客,而后又因为我不了解其中epoll的LT/ET是什么东西,又赶紧补了一下这些知识,唉,本该早点就了解的知识,一直没能沉下心来看,虽然平时开发业务大概率用不到,但是看稍微底层一点的知识就会涉及到这些东西呢… LT和ET的区别 epoll(linux)/kqueue(unix)是现代操作系统用来做I/O多路复用的著名技术,通常有两种不同的工作模式LT(level- triggered,水平触发)和ET(edge-triggered,边缘触发),默认情况下epoll是工作在LT模式下的。 之前摸过一段时间的verilog,很熟悉edge-triggered这个玩意。电平见过吧,1是高0是低,那么一段连续变化的电平,大概可以表示成这个样子: 电平是一段时间内的值,比如横线在上代表这段时间内电平值是1,下面横线代表0,竖线代表由0变1(下降沿,如图中绿色竖线)或者1变0(上升沿,如图中红色竖线)。 这个跟我们的要说的LT和ET有什么关系呢?我们将1代表有fd可读写(对应电平1),0代表没有fd可读写(对应电平0),如果epoll工作在LT模式下,只要fd可读写,那么就epoll_wait一定返回有值,否则阻塞,相当于你去询问现在电平是多少,他就返回当前电平的值给你。但如果epoll工作在ET模式下,只有当fd是从不可读写变为可读写的时候(有新事件到来),epoll_wait才会告诉你可读写,相当于存储了一个上升沿状态,你epoll_wait调用相当于去消费这个状态,消费完后,在下一次边缘到来之前,epoll_wait就没有数据返回了,因为这个边缘已经在上一次epoll_wait被消费掉了。 举个例子,当前注册fd1和fd2的可读事件到epoll上,初始状态为[0,0]: 工作模式为LT,调用epoll_wait fd1可读事件到达 epoll_wait返回fd1可读,状态变成[1,0] 再次调用epoll_wait(注意此时状态依然是[1,0]),立刻返回fd1可读 ET模式: 工作模式为ET,调用epoll_wait fd1可读事件到达,状态变成[1,0] epoll_wait返回fd1可读 再次调用epoll_wait(注意此时状态依然是[1,0]),阻塞 结论就是,在LT工作模式下,可以通过不断询问epoll_wait来决定是否要读写fd,因为他总能告诉你最真实的是否可读写的状态。在ET工作模式下,你只会被通知一次fd可以读写,然后你最好就一次性读写完成,相当于将fd的当前状态清除掉,然后才去进行下一次epoll_wait,这里说的“一次性读写”并不是说只调用一次read/write,而是反复调用直到没有数据可以读出/写入,注意到因为需要反复调用,如果fd是阻塞模型的话,很可能最后一次就阻塞住了,导致你的I/O从多路复用模式直接变成了阻塞模式,甚至这个fd以后可能不再可读写,那你这个程序就再也跑不下去了,所以ET一般和fd设置成非阻塞一起使用。而LT模式下,fd设成阻塞或非阻塞都可以,因为epoll_wait会告诉你是否可读写,如果可以读写,read/write一定是成功的,因此不会阻塞。 当然,ET还有一些坑需要了解,详情看参考链接 参考链接 https://strikefreedom.top/archives/linux-epoll-with-level-triggering-and-edge-triggering https://strikefreedom.top/archives/go-netpoll-io-multiplexing-reacto https://zhuanlan.zhihu.com/p/40572954

九月 16, 2024 · by NOSAE

在MacOS中运行k3s

k3s https://github.com/caicloud/kube-ladder 安装ubuntu家的multipass虚拟机 brew install multipass 创建一个虚拟机并启动 multipass launch -n k3s01 -c 2 -m 2G -d 16G 查看虚拟机 multipass list multipass info k3s01 进入虚拟机终端 multipass shell k3s01 设置root密码,更新apt sudo passwd apt-get update 数据卷,数据传输 multipass mount host-path vm-name:vm-path multipass umount vm-name multipass transfer host-file vm-name:vm-path 虚拟机操作 multipass start/stop/delete/purge vm-name 指定虚拟机初始化时的配置、执行的命令等 multipass launch -n vm-name --cloud-init config.yaml # config.yaml runcmd: - apt-get update # 更新包 - curl -sfL https://get.k3s.io | sh - # 安装k3s - echo "alias k=kubectl" >> ~/.bash_aliases 指定k3s启动时config的访问权限,使得在非root用户下也能kubectl管理k3s ...

九月 1, 2024 · by NOSAE

jekyll chrispy主题的语法

Headings H1 — heading {: .mt-4 .mb-0 } H2 — heading {: data-toc-skip=’’ .mt-4 .mb-0 } H3 — heading {: data-toc-skip=’’ .mt-4 .mb-0 } H4 — heading {: data-toc-skip=’’ .mt-4 } Paragraph Quisque egestas convallis ipsum, ut sollicitudin risus tincidunt a. Maecenas interdum malesuada egestas. Duis consectetur porta risus, sit amet vulputate urna facilisis ac. Phasellus semper dui non purus ultrices sodales. Aliquam ante lorem, ornare a feugiat ac, finibus nec mauris. Vivamus ut tristique nisi. Sed vel leo vulputate, efficitur risus non, posuere mi. Nullam tincidunt bibendum rutrum. Proin commodo ornare sapien. Vivamus interdum diam sed sapien blandit, sit amet aliquam risus mattis. Nullam arcu turpis, mollis quis laoreet at, placerat id nibh. Suspendisse venenatis eros eros. ...

八月 31, 2024 · by NOSAE