k8s_day04_02

k8s_day04_02

ipvs 代理模型

​ kube-proxy 会在每个节点上创建一个名为kube-ipvs0的虚拟接口,并将集群所有Service对象的ClusterIP和ExternalIP都配置在该接口; kube-proxy为每个service生成一个虚拟服务器(Virtual Server)的定义。

会生成一个kube-ipvs0 网卡,且在网卡动态绑定svc 的cluster ip地址;

ipvs 代理负载算法可以使用多种 ,而不是像是iptables只有 random 算法一种

注意仅需要借助于极少量的iptables规则完成源地址转换等功能。

调整kube-proxy 代理模型为ipvs

云原生应用特点 ,支持通过环境变量配置,支持配置文件的动态加载。改了配置文件后支持注入,通过配置中心加载配置信息后,自动重载,过一段时间自动生效。非云原生的应用可能需要通过重新打镜像或者重启容器 ,做些交互式配置

[root@node01 ~]# kubectl  get  configmaps/kube-proxy  -n kube-system
NAME         DATA   AGE
kube-proxy   2      14d
[root@node01 ~]# kubectl  edit  configmaps/kube-proxy  -n kube-system

把 mode"" 改为 mode: “ipvs” 就行 。 mode 默认值是 iptables

scheduler: “” 默认值是rr

修改之后 屏幕显示configmap/kube-proxy edited 就行。

​ 过段时间 ,集群节点的kube-proxy 就会收到配置,生成kube-ipvs0 网卡,如果没有自动触发 有些参数可能不支持动态生效,pod删除重建就行。发现没有生效 ,生产环境建议逐个删除,灰度发布 。

[root@node01 ~]# kubectl delete pods -l k8s-app=kube-proxy -n kube-system

验证结果

[root@node01 ~]#  ifconfig  kube-ipvs0
kube-ipvs0: flags=130<BROADCAST,NOARP>  mtu 1500
        inet 10.98.151.232  netmask 255.255.255.255  broadcast 0.0.0.0
        ether e6:14:a0:47:98:19  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

10.98.151.232 只是 所有的名称空间下 ,其中一个 svc 的接口地址 ,查看所有网卡的地址,如下

[root@node01 ~]#  ip addr s kube-ipvs0|grep  232
    inet 10.98.151.232/32 scope global kube-ipvs0

查看节点生成的 ipvs 规则

[root@node02 ~]# ipvsadm -Ln|grep  232 -A 4
TCP  10.98.151.232:80 rr
  -> 10.244.4.27:80               Masq    1      0          0         
  -> 10.244.4.29:80               Masq    1      0          0         
  -> 10.244.5.25:80               Masq    1      0          0         
TCP  10.106.240.186:80 rr

[root@node01 ~]# kubectl  describe   svc/demoapp-loadbalancer-svc|egrep  'IP:|Endpoints'
IP:                       10.98.151.232
IP:                       1.2.3.4
Endpoints:                10.244.4.27:80,10.244.4.29:80,10.244.5.25:80
[root@node01 ~]# 

验证 ipvs 规则 与svc 关系

[root@node01 ~]# kubectl  get  svc/demoapp-externalip-svc 
NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
demoapp-externalip-svc   ClusterIP   10.106.240.186   192.168.2.6   80/TCP    3d

[root@node01 ~]# ipvsadm -Ln |grep  10.106.240.186 -A4
TCP  10.106.240.186:80 rr
  -> 10.244.4.31:80               Masq    1      0          0         
  -> 10.244.4.32:80               Masq    1      0          0         
  -> 10.244.5.25:80               Masq    1      0          0         
TCP  10.107.176.51:80 rr
[root@node01 ~]# kubectl delete svc/demoapp-externalip-svc
service "demoapp-externalip-svc" deleted
[root@node01 ~]# ipvsadm -Ln |grep  10.106.240.186 -A4
[root@node01 ~]# ipvsadm -Ln |grep  10.106.240.186 -A4
[root@node01 ~]# 

k8s 服务发现

如果通过 Service:IP 访问服务 。当集群中有 1000+ 个 Service ,通过ip 就难管理。因此需要 service Name 。但是 k8s service 变动频繁 ,意味dns 记录必须频繁变动,靠手改不行。传统的服务发现注册 zookeeper, Euraka,Consul… 无法做名字解析。

所以k8s 将传统的DNS服务直接提供一个云原生解决方案,他支持从apiserver动态加载相关的service及端点信息,并自动生成资源记录:服务注册和发现的总线:KubeDNS。

实现方案上,有三代:SkyDNS、KubeDNS、CoreDNS

k8 如何做服务发现的:
一、基于环境变量:

​ 例如,前面在default名称空间中创建Service对象demoapp-svc的地址为10.97.72.1,且为TCP协议的80端口取名http,对于默认的cluster.local域名来说,此它会拥有如下3个DNS资源记录。

A记录:demoapp-svc.default.svc.cluster.local. 30 IN A 10.97.72.1;
SRV记录:_http._tcp.demoapp-svc.default.svc.cluster.local. 30 IN SRV 0 100 80 demoapp-svc.default.svc.cluster.local.
PTR记录:1.72.97.10.in-addr.arpa. 30 IN PTR demoapp-svc.default.svc.cluster.local.

1、Kubernetes Service环境变量

​ Kubernetes为每个Service资源生成包括以下形式的环境变量在内一系列环境变量,在同一名称空间中创建的 Pod对象都会自动拥有这些变量:

​ ① {SVCNAME}SERVICE_HOST ② _ {SVCNAME}_SERVICE_PORT

eg: default名称空间:创建的demoapp Service,意味着default名称空间下的每个Pod内部会被自动注入DEMOAPP_SERVICE_HOST:ClusterIP, DEMOAPP_SERVICE_PORT=80

注意的是只能注入当前pod 所在名称空间下的svc 变量信息

验证 , 例如default 名称空间下有 7个service时 ,default 名称空间每个pod就有 SVCNAME_SERVICE_HOST 7个

SVCNAME_SERVICE_PORT 变量 7个

[root@node01 ~]# kubectl  get   svc |awk '{print$1}'|grep -v ^NAME
demoapp
demoapp-loadbalancer-svc
demoapp-nodeport-svc
demoapp-svc
kubernetes
mysql-external
services-readiness-demo

验证 SVCNAME_SERVICE_HOST,, SVCNAME_SERVICE_PORT 同理

[root@node01 ~]# kubectl exec  mypod   -- printenv |grep  _SERVICE_HOST 
SERVICES_READINESS_DEMO_SERVICE_HOST=10.98.48.27
DEMOAPP_LOADBALANCER_SVC_SERVICE_HOST=10.98.151.232
DEMOAPP_SERVICE_HOST=10.107.176.51
DEMOAPP_NODEPORT_SVC_SERVICE_HOST=10.97.56.1
DEMOAPP_SVC_SERVICE_HOST=10.97.72.1
KUBERNETES_SERVICE_HOST=10.96.0.1
MYSQL_EXTERNAL_SERVICE_HOST=10.111.180.31
[root@node01 ~]# 

在同一个名称空间下,当我们不知道一个svc 的地址时 ,就可以通过名称来访问

[root@mypod /]# curl  ${SERVICES_READINESS_DEMO_SERVICE_HOST}
iKubernetes demoapp v1.0 !! ClientIP: 10.244.5.29, ServerName: demoapp2-677db795b4-zh5fz, ServerIP: 10.244.5.27!

2、Docker Link形式的环境变量

Docker使用–link选项实现容器连接时所设置的环境变量形式,具体使用方式请参考Docker的相关文档。在创建Pod对象时,kubernetes也会把与此形式兼容的一系列环境变量注入到Pod对象中。

docker 如何做服务发现的:

​ --link 选项 、、环境变量注入的方式

二、基于DNS的服务发现:

对于每个Service对象,都会具有以下3个类型的DNS资源记录。

1、A记录

根据ClusterIP的地址类型,为IPv4生成A记录,为IPv6生成AAAA记录;

主要的作用就是实现 service name -> service ip 解析

<service>.<ns>.svc.<zone>. <ttl>  IN  A  <cluster-ip>
<service>.<ns>.svc.<zone>. <ttl> IN AAAA <cluster-ip>

这里service 表示 service 名称

ns 所在的名称空间

svc 是固定值

zome 是 域名(非主机名)

例如 :demoapp.default.svc.magedu.com. ,域名不写就是默认的类型 .cluster.local.

eg: demoapp.default.svc.cluster.local. 点表示到根了

验证

[root@node01 ~]# kubectl exec mypod  -it -- /bin/sh
[root@mypod /]# nslookup --help
*** Invalid option: -help
> set q=A
> demoapp.default.svc.cluster.local
Server:		10.96.0.10
Address:	10.96.0.10#53

Name:	demoapp.default.svc.cluster.local
Address: 10.107.176.51
> 


[root@mypod /]# cat  /etc/resolv.conf 
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

发现demoapp.default.svc.cluster.local 的地址是 10.107.176.51 , 是svc/demoapp的 cluster-ip

[root@node01 ~]# kubectl  get  svc/demoapp
NAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
demoapp   ClusterIP   10.107.176.51   <none>        80/TCP    14d

发现mypod它的 dns 服务器地址 是10.96.0.10

这个10.96.0.10 是 svc/kube-dns 【coredns服务组件的】 的 CLUSTER-IP.

[root@node01 ~]# kubectl  get  svc/kube-dns -n kube-system 
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   14d

k8s中的域名解析 就靠这2个coredns pod 进行服务, 它们会始终监视着apiserver 中 service 相关的变动

[root@node01 ~]# 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,9153/TCP   14d
[root@node01 ~]# kubectl  get  po -n  kube-system  -l  k8s-app=kube-dns -o wide
NAME                       READY   STATUS    RESTARTS   AGE     IP             NODE       NOMINATED NODE   READINESS GATES
coredns-6d56c8448f-7lwtf   1/1     Running   11         7d17h   10.244.5.28    node01     <none>           <none>
coredns-6d56c8448f-j967l   1/1     Running   3          7d17h   10.244.0.179   master01   <none>           <none>

如果删除svc/demoapp-svc ,pod 内将立即无法访问

[root@master01 ~]# kubectl  delete svc/demoapp-svc
service "demoapp-svc" deleted
[root@master01 ~]# 


[root@mypod /]# curl demoapp-svc
curl: (6) Could not resolve host: demoapp-svc
[root@mypod /]# 

重新创建后就可以立即访问

[root@master01 chapter7]# kubectl  apply  -f services-clusterip-demo.yaml 
service/demoapp-svc created

[root@mypod /]# curl demoapp-svc
iKubernetes demoapp v1.0 !! ClientIP: 10.244.5.30, ServerName: demoapp-5f7d8f9847-hwxrb, ServerIP: 10.244.5.26!

每创建一个pod 就会自动为pod注入生成 /etc/resolv.conf 文件

image-20211209120658553

dns搜索域 ,由4个部分组成, 附带 特定空间的域名、附带k8s 标识专用子域svc的域名、集群本地域名、主机域域名

eg:

当我 直接用 curl 访问 service 名称时, 如果demoapp-svc 无法解析 ,就依次为他 加上 dns 搜索域的4个后缀,直到可以解析出来

[root@mypod /]# curl demoapp-svc
iKubernetes demoapp v1.0 !! ClientIP: 10.244.5.29, ServerName: demoapp-5f7d8f9847-hwxrb, ServerIP: 10.244.5.26!
[root@mypod /]# curl demoapp-svc.default
iKubernetes demoapp v1.0 !! ClientIP: 10.244.5.29, ServerName: demoapp-5f7d8f9847-vwdpc, ServerIP: 10.244.4.38!
[root@mypod /]# curl demoapp-svc.default.svc
iKubernetes demoapp v1.0 !! ClientIP: 10.244.5.29, ServerName: demoapp-5f7d8f9847-s9jvq, ServerIP: 10.244.4.36!
[root@mypod /]# curl demoapp-svc.default.svc.cluster.local
iKubernetes demoapp v1.0 !! ClientIP: 10.244.5.29, ServerName: demoapp-5f7d8f9847-hwxrb, ServerIP: 10.244.5.26!
[root@mypod /]#  

[root@mypod /]# curl demoapp-svc
curl: (6) Could not resolve host: demoapp-svc
[root@mypod /]# 

2、 srv 记录

为每个定义了名称的端口生成一个SRV记录,未命名的端口号则不具有该记录;

了解就行。 只要能解析srv记录 , 就能完成服务发现。 主要作用是实现端口 的解析

_<port>._<proto>.<service>.<ns>.svc.<zone>. <ttl>  IN  SRV  <weight> <priority>  <port-number>  <service>.<ns>.svc.<zone>.
3、PTR 记录

主要的作用就是实现 service_ip -> service_name 的解析

​ 对于每个给定的A记录(例如a.b.c.d)或AAAA记录(例如a1a2a3a4:b1b2b3b4:c1c2c3c4:d1d2d3d4:e1e2e3e4:f1f2f3f4:g1g2g3g4:h1h2h3h4)都要生成PTR记录,它们各自的格式如下所示:

<d>.<c>.<b>.<a>.in-addr.arpa.  <ttl>  IN  PTR <service>.<ns>.svc.<zone>.
 h4.h3.h2.h1.g4.g3.g2.g1.f4.f3.f2.f1.e4.e3.e2.e1.d4.d3.d2.d1.c4.c3.c2.c1.b4.b3.b2.b1.a4.a3.a2.a1.ip6.arpa <ttl> IN PTR <service>.<ns>.svc.<zone>.

eg: 对service 的cluster-ip 做反向解析

[root@demoapp-5f7d8f9847-hwxrb /]# nslookup -query=PTR 10.97.72.1
Server:		10.96.0.10
Address:	10.96.0.10#53

1.72.97.10.in-addr.arpa	name = demoapp-svc.default.svc.cluster.local.

[root@demoapp-5f7d8f9847-hwxrb /]# nslookup -query=A demoapp-svc.default.svc.cluster.local.
Server:		10.96.0.10
Address:	10.96.0.10#53

Name:	demoapp-svc.default.svc.cluster.local
Address: 10.97.72.1

[root@demoapp-5f7d8f9847-hwxrb /]# 
修改 coredns 配置
[root@node01 ~]# kubectl get cm/coredns -n kube-system 
NAME      DATA   AGE
coredns   1      14d

多数情况下 ,都不用改,如果解析外部的地址就要修改

[root@node01 ~]# kubectl edit  cm/coredns -n kube-system 

apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors  #表示把错误日志发往标准输出,没有路径就发往控制台
        health {
           lameduck 5s # 健康状态检测,多久检测一次,通过http://localhost:8080/health报告健康状态
        }
        ready #所有端口 通过8081 响应200 ok 以报告就绪状态
        kubernetes cluster.local in-addr.arpa ip6.arpa {
        # k8系统本地区域及专用名称解析配置
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }
        prometheus :9153 # 通过http://localhost:9153/metrics 输出数据
        forward . /etc/resolv.conf { # 前向转发 ,如果pod内dns 无法解析 ,就向根调用宿主机的resolv.conf解析
           max_concurrent 1000
        }
        cache 30
        loop
        reload  # 一旦改了配置自动重载
        loadbalance  # A、4A、MX记录负载均衡器。如果一条A 记录解析的地址有多条就轮询
    }
kind: ConfigMap

forward 示例

把根域 转给 223.6.6.6 114.114.114.114 解析 , 除了内网 magedu.com

except 后面要写根域点

forward . 223.6.6.6  114.114.114.114 {
 
 max_concurrent 1000
 except magedu.com.

}
forward magedu.com 10.20.111.1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值