kubernetes负载均衡-service,阿里P8大牛亲自教你

spec:
publishNotReadyAddresses: true
selector:
role: web-readiness
ports:

  • protocol: TCP
    port: 8888
    targetPort: 80

apiVersion: apps/v1
kind: Deployment
metadata:
name: demoapp2
spec:
replicas: 4
selector:
matchLabels:
role: web-readiness
template:
metadata:
labels:
role: web-readiness
spec:
containers:
- name: demoapp2
image: oldxu3957/demoapp:v1.0
readinessProbe: # 就绪探针
httpGet:
path: ‘/readyz’
port: 80
initialDelaySeconds: 15 # 初次检测延时时长
periodSeconds: 10 # 检测周期



查看svc详情

kubectl describe svc demoapp-readiness-service

按照标签进行查看pod

kubectl get pod --show-labels
kubectl get pods -l role=web-readiness -o wide


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/040aa73e82cd4a69bc529478459f8f66.png)


#### 4.2、将其中的某个Pod设定为不就绪,看看是否会将该PodIP加入到NotReadAddress字段中



apiVersion: v1
kind: Service
metadata:
name: demoapp-readiness-service
spec:
publishNotReadyAddresses: true ## 添加该字段
selector:
role: web-readiness
ports:

  • protocol: TCP
    port: 8888
    targetPort: 80

apiVersion: apps/v1
kind: Deployment
metadata:
name: demoapp2
spec:
replicas: 2
selector:
matchLabels:
role: web-readiness
template:
metadata:
labels:
role: web-readiness
spec:
containers:
- name: demoapp2
image: oldxu3957/demoapp:v1.0
readinessProbe: # 就绪探针
httpGet:
path: ‘/readyz’
port: 80
initialDelaySeconds: 15 # 初次检测延时时长
periodSeconds: 10 # 检测周期


* 将pod设置成未就绪



curl -s -X POST -d ‘readyz=err’ 10.244.2.62/readyz

如果想将pod设置成就绪状态,只需要将pod进行删除重建就可以了


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b1b2ee2b2b294e66859a73a6eb173df7.png)


* 无论如何请求,只会请求只就绪的pod中  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/6aae2b45ad6646d890a865f408280b38.png)
* 添加参数后的svc



spec:
‘’’
publishNotReadyAddresses: true
‘’‘’


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/16dacfdaab6f46ab82ef9f9379597061.png)  
 可以调用到未就绪的pod中  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/61ce34236fc247c7a88c10b95eab3b14.png)


这种应用场景比较少


## 九、service的进阶-iptables和IPVS


### 1、service访问场景:


访问Service会出现如下4中情况:


* 1、Pod-A>Service >调度>Pod-B/Pod-C
* 2、Pod-A->Service >调度->Pod-A
* 3、Docker>Service>调度→>Pod-B/Pod-C
* 4、NodePort>Service>调度→>Pod-B/Pod-C


### 2、iptables规则


### 场景一,clusterIP规则


Pod-A>Service >调度>Pod-B/Pod-C


#### 1、编写资源



apiVersion: apps/v1
kind: Deployment
metadata:
name: demoapp

spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: webservers
image: oldxu3957/demoapp:v1.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80


apiVersion: v1
kind: Service
metadata:
name: demoapp-svc
spec:
type: ClusterIP
selector:
app: web
ports:

  • port: 80
    targetPort: 80

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/604973b295d148f8be3fa51264723a1b.png)


#### 2、登陆pod,访问svc


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/3939d91ad4d04e249ab83ef433b6c47a.png)


#### 3、iptables规则查看


iptables的流程:  
 入站本机:PREROUTING -->INPUT  
 从本机流入: OUTPUT --》 POSTROUTING  
 经过节点: PREROUTING --》FORWRD --》POSTROUTING


整体流程:  
 OUTPUT–>KUBE-SERVICES–>KUBE-SVC-–>KUBE-SEP------>POSTROUTING-----> KUBEPOSTROUTING ---->interface



第一步:所有从OUTPUT出去的数据包,都必须经过KUBE-SERVICES自定义链;

[root@node02 ~]# iptables -S OUTPUT
-P OUTPUT ACCEPT
-A OUTPUT -m conntrack --ctstate NEW -m comment --comment “kubernetes service portals” -j KUBE-SERVICES
-A OUTPUT -j KUBE-FIREWALL
-A OUTPUT -o virbr0 -p udp -m udp --dport 68 -j ACCEPT

第二步:分析KUBE-SERVICES
当发现请求的ServiceIP是 10.110.217.207的80端口时,则跳转KUBE-SVC-HASH这个自定义链上;
[root@node2 ~]# iptables -t nat -S KUBE-SERVICES | grep demoapp-svc
-A KUBE-SERVICES -d 10.110.217.207/32 -p tcp -m comment --comment “default/demoapp-svc cluster IP” -m tcp --dport 80 -j KUBE-SVC-EHL433DY3T7P3MZN

第三步:
第一条:创建自定义链;
第二条:如果来源不是POd的地址段,则将这个请求直接跳转到KUBE-MARK-MASQ这个自定义链上去; 然后给这个请求打上对应的标记 0x4000/0x4000
第三条到第五条:将请求通过调度算法调度到对应的自定义链上; --> 第一次请求第一条有1/3 第二次请求50% 第三次 100%

[root@node2 ~]# iptables -t nat -S KUBE-SVC-EHL433DY3T7P3MZN
-N KUBE-SVC-EHL433DY3T7P3MZN
-A KUBE-SVC-EHL433DY3T7P3MZN ! -s 10.244.0.0/16 -d 10.110.217.207/32 -p tcp -m comment --comment “default/demoapp-svc cluster IP” -m tcp --dport 80 -j KUBE-MARK-MASQ

通过轮休的方式进行调度到指定的地址上

-A KUBE-SVC-EHL433DY3T7P3MZN -m comment --comment “default/demoapp-svc” -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-OKCWPUIB7WHDSNLK
-A KUBE-SVC-EHL433DY3T7P3MZN -m comment --comment “default/demoapp-svc” -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-47KFJORAGBSAGTDM
-A KUBE-SVC-EHL433DY3T7P3MZN -m comment --comment “default/demoapp-svc” -j KUBE-SEP-GDD5ADYI2DAT4RQT

[root@node2 ~]# iptables -t nat -S KUBE-MARK-MASQ
-N KUBE-MARK-MASQ
-A KUBE-MARK-MASQ -j MARK --set-xmark 0x4000/0x4000 #请求打上对应的标记 0x4000/0x4000

第四步:
	
第一条:创建自定义链;
第二条:如果10.244.1.46 访问得是自己的Service,然后又被Service调度给自己本身,这个时候就将这个请求打上对应的标签  0x4000/0x4000
第三条:进行dnat操作,就是将请求Service的IP,替换为Service后端的Pod的IP地址;

[root@node2 ~]# iptables -t nat -S KUBE-SEP-OKCWPUIB7WHDSNLK
-N KUBE-SEP-OKCWPUIB7WHDSNLK
-A KUBE-SEP-OKCWPUIB7WHDSNLK -s 10.244.1.46/32 -m comment --comment “default/demoapp-svc” -j KUBE-MARK-MASQ
-A KUBE-SEP-OKCWPUIB7WHDSNLK -p tcp -m comment --comment “default/demoapp-svc” -m tcp -j DNAT --to-destination 10.244.1.46:80
[root@node2 ~]# iptables -t nat -S KUBE-SEP-47KFJORAGBSAGTDM
-N KUBE-SEP-47KFJORAGBSAGTDM
-A KUBE-SEP-47KFJORAGBSAGTDM -s 10.244.2.64/32 -m comment --comment “default/demoapp-svc” -j KUBE-MARK-MASQ
-A KUBE-SEP-47KFJORAGBSAGTDM -p tcp -m comment --comment “default/demoapp-svc” -m tcp -j DNAT --to-destination 10.244.2.64:80
[root@node2 ~]# iptables -t nat -S KUBE-SEP-GDD5ADYI2DAT4RQT
-N KUBE-SEP-GDD5ADYI2DAT4RQT
-A KUBE-SEP-GDD5ADYI2DAT4RQT -s 10.244.3.77/32 -m comment --comment “default/demoapp-svc” -j KUBE-MARK-MASQ
-A KUBE-SEP-GDD5ADYI2DAT4RQT -p tcp -m comment --comment “default/demoapp-svc” -m tcp -j DNAT --to-destination 10.244.3.77:80

第五步:
第一条:创建自定义链;
第二条:无条件调度到KUBE-POSTROUTING这个自定义链上;
第三条: docker相关的;忽略;
第四条:由于源地址是 192.168.122.0/16 目标 192.168.122.0/16,所以RETURN了;又回到了POSTROUTING链;看默认的规则是什么;ACEEPT; 数据包就会被送出;

[root@node2 ~]# iptables -t nat -S POSTROUTING
-P POSTROUTING ACCEPT
-A POSTROUTING -m comment --comment “kubernetes postrouting rules” -j KUBE-POSTROUTING
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 192.168.122.0/24 -d 224.0.0.0/24 -j RETURN
-A POSTROUTING -s 192.168.122.0/24 -d 255.255.255.255/32 -j RETURN
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p udp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE
-A POSTROUTING -s 10.244.0.0/16 -d 10.244.0.0/16 -m comment --comment “flanneld masq” -j RETURN
-A POSTROUTING -s 10.244.0.0/16 ! -d 224.0.0.0/4 -m comment --comment “flanneld masq” -j MASQUERADE
-A POSTROUTING ! -s 10.244.0.0/16 -d 10.244.2.0/24 -m comment --comment “flanneld masq” -j RETURN
-A POSTROUTING ! -s 10.244.0.0/16 -d 10.244.0.0/16 -m comment --comment “flanneld masq” -j MASQUERADE

第六步:
第一条:创建自定义链;
第二条:如果这个请求没有对应的标记,那么RETURN返回到POSTROUTING链;

[root@node2 ~]# iptables -t nat -S KUBE-POSTROUTING
-N KUBE-POSTROUTING
-A KUBE-POSTROUTING -m mark ! --mark 0x4000/0x4000 -j RETURN
-A KUBE-POSTROUTING -j MARK --set-xmark 0x4000/0x0
-A KUBE-POSTROUTING -m comment --comment “kubernetes service traffic requiring SNAT” -j MASQUERADE


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/cc6e10e5a3c642f4898b62e7b3fcee61.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/ee7c9e0458f5497ba3eed645f4259b23.png)


#### 4、iptables 的clusterIP模式图解


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/ef334e2b00c64f81abcb73a507c191dd.png)


#### 5、iptables的NodePort模式



apiVersion: apps/v1
kind: Deployment
metadata:
name: demoapp

spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: webservers
image: oldxu3957/demoapp:v1.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80


apiVersion: v1
kind: Service
metadata:
name: demoapp-svc
spec:
type: NodePort
selector:
app: web
ports:

  • port: 80
    targetPort: 80
    nodePort: 32000

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/938f5fc31b4f433997910107f5543a5d.png)


NodePort类型的service进行分析;Iptables规则:


PREROUTING -->FORWARD>POSTROUTING>interface



第一步:
所有经过PREROUTING链的请求,都会被拦截到KUBE-SERVICES自定义链上;
[root@node2 ~]# iptables -t nat -S PREROUTING
-P PREROUTING ACCEPT
-A PREROUTING -m comment --comment “kubernetes service portals” -j KUBE-SERVICES
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER

第二步:
所有的规则都不会被匹配,但是会匹配最后一条规则,最后一条规则是跳转到KUBE-NODEPORTS这个自定义链中;

[root@node2 ~]# iptables -t nat -S KUBE-SERVICES
-N KUBE-SERVICES
-A KUBE-SERVICES -d 10.110.217.207/32 -p tcp -m comment --comment “default/demoapp-svc cluster IP” -m tcp --dport 80 -j KUBE-SVC-EHL433DY3T7P3MZN
-A KUBE-SERVICES -d 10.96.0.1/32 -p tcp -m comment --comment “default/kubernetes:https cluster IP” -m tcp --dport 443 -j KUBE-SVC-NPX46M4PTMTKRN6Y
-A KUBE-SERVICES -d 10.96.0.10/32 -p udp -m comment --comment “kube-system/kube-dns:dns cluster IP” -m udp --dport 53 -j KUBE-SVC-TCOU7JCQXEZGVUNU
-A KUBE-SERVICES -d 10.96.0.10/32 -p tcp -m comment --comment “kube-system/kube-dns:dns-tcp cluster IP” -m tcp --dport 53 -j KUBE-SVC-ERIFXISQEP7F7OF4
-A KUBE-SERVICES -d 10.96.0.10/32 -p tcp -m comment --comment “kube-system/kube-dns:metrics cluster IP” -m tcp --dport 9153 -j KUBE-SVC-JD5MR3NA4I4DYORP
-A KUBE-SERVICES -d 10.100.82.155/32 -p tcp -m comment --comment “kube-system/metrics-server:https cluster IP” -m tcp --dport 443 -j KUBE-SVC-Z4ANX4WAEWEBLCTM
-A KUBE-SERVICES -m comment --comment “kubernetes service nodeports; NOTE: this must be the last rule in this chain” -m addrtype --dst-type LOCAL -j KUBE-NODEPORTS

第三步:
如果请求的是节点的32000端口;那么则跳转到 KUBE-SVC-
[root@node2 ~]# iptables -t nat -S KUBE-NODEPORTS
-N KUBE-NODEPORTS
-A KUBE-NODEPORTS -p tcp -m comment --comment “default/demoapp-svc” -m tcp --dport 32000 -j KUBE-SVC-EHL433DY3T7P3MZN

第四步:
如果来源不是Pod的地址端,但是请求的是Service的IP,ClusterIP,目标端口是80,那么则跳转KUBE-MARK-MASQ 这个自定义链进行打标记;
如果请求的是节点的32000端口,那么则跳转到KUBE-MARK-MASQ这个自定义链,进行打标记 (0x4000/0x4000)

[root@node2 ~]# iptables -t nat -S KUBE-SVC-EHL433DY3T7P3MZN
-N KUBE-SVC-EHL433DY3T7P3MZN
-A KUBE-SVC-EHL433DY3T7P3MZN ! -s 10.244.0.0/16 -d 10.110.217.207/32 -p tcp -m comment --comment “default/demoapp-svc cluster IP” -m tcp --dport 80 -j KUBE-MARK-MASQ
-A KUBE-SVC-EHL433DY3T7P3MZN -p tcp -m comment --comment “default/demoapp-svc” -m tcp --dport 32000 -j KUBE-MARK-MASQ
-A KUBE-SVC-EHL433DY3T7P3MZN -m comment --comment “default/demoapp-svc” -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-SI5EEDPDQ7NVQF2Y
-A KUBE-SVC-EHL433DY3T7P3MZN -m comment --comment “default/demoapp-svc” -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-O7GW75MMOH2ZK4J5
-A KUBE-SVC-EHL433DY3T7P3MZN -m comment --comment “default/demoapp-svc” -j KUBE-SEP-ZOJBNUN3LSLJECDO

[root@node2 ~]# iptables -t nat -S KUBE-MARK-MASQ
-N KUBE-MARK-MASQ
-A KUBE-MARK-MASQ -j MARK --set-xmark 0x4000/0x4000

第五步:
直接进行DNAT操作;

[root@node2 ~]# iptables -t nat -S KUBE-SEP-O7GW75MMOH2ZK4J5
-N KUBE-SEP-O7GW75MMOH2ZK4J5
-A KUBE-SEP-O7GW75MMOH2ZK4J5 -s 10.244.2.65/32 -m comment --comment “default/demoapp-svc” -j KUBE-MARK-MASQ
-A KUBE-SEP-O7GW75MMOH2ZK4J5 -p tcp -m comment --comment “default/demoapp-svc” -m tcp -j DNAT --to-destination 10.244.2.65:80

第六步:
所有流经FORWARD这个链中的报文,都必须先到KUBE-FORWARD自定义链中;
[root@node2 ~]# iptables -S FORWARD
-P FORWARD ACCEPT
-A FORWARD -m comment --comment “kubernetes forwarding rules” -j KUBE-FORWARD

第七步:
所有流经POSTROUTING这个链中的报文,都必须先到KUBE-POSTROUTING自定义链中;
[root@node2 ~]# iptables -t nat -S POSTROUTING
-P POSTROUTING ACCEPT
-A POSTROUTING -m comment --comment “kubernetes postrouting rules” -j KUBE-POSTROUTING
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 192.168.122.0/24 -d 224.0.0.0/24 -j RETURN
-A POSTROUTING -s 192.168.122.0/24 -d 255.255.255.255/32 -j RETURN
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p udp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE
-A POSTROUTING -s 10.244.0.0/16 -d 10.244.0.0/16 -m comment --comment “flanneld masq” -j RETURN
-A POSTROUTING -s 10.244.0.0/16 ! -d 224.0.0.0/4 -m comment --comment “flanneld masq” -j MASQUERADE
-A POSTROUTING ! -s 10.244.0.0/16 -d 10.244.2.0/24 -m comment --comment “flanneld masq” -j RETURN
-A POSTROUTING ! -s 10.244.0.0/16 -d 10.244.0.0/16 -m comment --comment “flanneld masq” -j MASQUERADE

第八步:

[root@node2 ~]# iptables -t nat -S KUBE-POSTROUTING
-N KUBE-POSTROUTING
-A KUBE-POSTROUTING -m mark ! --mark 0x4000/0x4000 -j RETURN
-A KUBE-POSTROUTING -j MARK --set-xmark 0x4000/0x0
-A KUBE-POSTROUTING -m comment --comment “kubernetes service traffic requiring SNAT” -j MASQUERADE


## 十、IPVS模型分析


1、会在每个节点上创建一个名为kube-ipvs0的虚拟接口,并将集群所有Service对象的ClusterIP都配置在该接口:2、Kube-Proxy将每个Service生成一个虚拟服务器VirtualServer的定义;


注意:ipvs仅需要借助极少量的iptables规则完成源地址转换、源端口转换等;


### 1、设置集群为IPVS模式


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/93fade9b36204ea494ddb7b51233014b.png)


#### 1.1 修改ipvs模式



kubectl edit configmaps kube-proxy -n kube-system

ipvs:
excludeCIDRs: null
minSyncPeriod: 0s
scheduler: “”
strictARP: false
syncPeriod: 0s
tcpFinTimeout: 0s
tcpTimeout: 0s
udpTimeout: 0s
kind: KubeProxyConfiguration
metricsBindAddress: “”
mode: “ipvs” #指定ipvs规则


#### 1.2、删除kube-proxy的pod,重启kube-proxy



kubectl delete pod $(kubectl get pod -n kube-system | grep proxy | awk ‘{print $1}’) -n kube-system

kubectl delete pod $(kubectl get pod -l k8s-app=kube-proxy -n kube-system | awk ‘NR>1 {print $1}’) -n kube-system

只删除第2和第三个pod

kubectl delete pod $(kubectl get pod -l k8s-app=kube-proxy -n kube-system | awk ‘NR3 || NR4 {print $1}’) -n kube-system


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/796b17eae97e4b8ba4a0aa6c613b5acb.png)


#### 1.3 IPVS 规则查看



全部规则查看

ipvsadm -L -n

IPVS的映射网卡查看

ip a s ## 查看网卡
kubect get svc ## 查看svc
如图所示,正式映射关系


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/dbbf82901cb34659aff0cf1c1a5a4510.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/cf5beff16c6a4047a916cb8bf606d5c7.png)


## 十一、服务发现


当Pod需要访问Service时,通过Service提供的ClusterIP就可以实现了,但是有几个问题;


1、Service的IP不稳定,删除重建会发生变化;  
 2、ServiceIP难以记忆,如果能通过一个固定的名称访问就好了;


为了解决这样的问题,Kubernetes引入了环境变量和DNS两种方案来解决这样的问题;  
 1、环境变量方式:通过特定的名称将环境变量注入到Pod内部;  
 2、DNS方式:通过APIServer来监视Service变动,而后动态创建对应Service名称与ServiceIP的域名解析记录;


### 1、环境变量


每个 Pod 启动的时候,会通过环境变量的方式将Service的IP以及Port信息注入进去,这样 Pod 中的应用可以通过读取环境变量来获取对应Service服务的地址信息,这种方法使用起来相对简单,但是也存在一定的问题。就是Pod所依赖的Service必须优Pod启动,否则无法注入到环境变量中。



kubectl run tools --image=registry.cn-hangzhou.aliyuncs.com/mokeyking/k8s-oldxu:tools-latest


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/2166b23f923f423d841654b1bc6b4a63.png)



kubectl exec -it tools – /bin/bash
env | grep -i demoapp_svc
ping ${DEMOAPP_SVC_SERVICE_HOST}


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/d9d09afedb774b74929b4a7cf12aacad.png)


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/6f179c069163427fb722dd387afd372b.png)


在创建一个svc。pod就无法获取到svc的环境变量



apiVersion: v1
kind: Service
metadata:
name: env-svc
spec:
selector:
app: web
ports:

  • port: 80
    targetPort: 80

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/04060c8a2ba046d99331df5932d64c6f.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a88abe6c0c7f4fffbf28682cf34f9b8a.png)  
 pod无法获取新创建的svc的环境变量信息  
 但是再新创建一个pod就会能或者svc的变量信息  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/8342e7a601354b4290e7bba5d272c4be.png)  
 重新创建一个pod,能够或者两个svc的环境变量,这就是环境变量的作用


### 2、CoreDNS


在安装Kubernetes集群时,CoreDNS作为附加组件,用来为Pod提供DNS域名解析。CoreDNS监视 Kubernetes API 中的新Service,并为每个Service名称创建一组 DNS 记录。这样我们就可以通过固定的Service名称来转换出不固定的ServiceIP


了解CoreDNS的配置



[root@master service]# kubectl get configmap -n kube-system ## 查看所有的配置信息
NAME DATA AGE
coredns 1 97d
extension-apiserver-authentication 6 97d
kube-flannel-cfg 2 97d
kube-proxy 2 97d
kube-root-ca.crt 1 97d
kubeadm-config 1 97d
kubelet-config-1.23 1 97d
[root@master service]# kubectl get configmaps coredns -n kube-system -o yaml
apiVersion: v1
data:
Corefile: |
.:53 {
errors ## 错误记录
health { ## 监控检查
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa { ## 用于解析kubernetes集群内域名
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153 ## 监控端口
forward . /etc/resolv.conf { # 如果请求非Kubernetes域名,则由节点的resolv.conf中dns解析
max_concurrent 1000
}
cache 30 # 缓存所有内容
loop
reload # 支持热更新
loadbalance # 负载均衡,默认轮询
}
kind: ConfigMap
metadata:
creationTimestamp: “2023-12-15T16:08:05Z”
name: coredns
namespace: kube-system
resourceVersion: “233”
uid: 6fe29dab-17db-45f6-a7eb-70a08724337b


默认的域名解析配置  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/870ce0638bcb46eb8adaeb817ab20d11.png)


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/9b4f0118b88b41f9bdd605476ec22247.png)


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/57bf7c20fc3c489d87ce9e1ad8370812.png)


解析svc域名  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a98993ca95de4fc9989154a3029ac071.png)  
 总结:可以解析到对应的svcIP


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/3f740333cdb84fe4b3724fe6ee827deb.png)  
 总结:删除svc时,svc的ip就会发生变化,但是重新对svc的域名进行解析,仍然能够解析到svc的ip。只要service的名称不发生变化,就可以正常解析,所有可以将这个注入到pod的中,就可以解析svc的配置。这个DNS是通过cordDNS进行转发解析的。


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/aaf08731b722453d8ee707af495e58a7.png)


## 十二、CordDNS策略


DNS策略可以单独对Pod进行设定,在创建Pod时可以为其指定DNS的策略,最终配置会落在Pod的/etc/resolv.conf文件中,可以通过pod.spec.dnsPolicy字段设置DNS的策略


### 1、ClusterFirst(默认DNS策略)


表示Pod内的DNS使用集群中配置的DNS服务,简单来说就是使用Kubernetes 中的 coredns 服务进行域名解析。如果解析不成功,会使用当前Pod所在的宿主机 DNS 进行解析。



apiVersion: v1
kind: Pod
metadata:
name: pod-example-1
spec:
dnsPolicy: ClusterFirst
containers:

  • name: tools
    image: registry.cn-hangzhou.aliyuncs.com/mokeyking/k8s-oldxu:tools-latest
    ports:
    • containerPort: 8899

查看pod的DNS的策略  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/fd4ce02abece46429740fb11d670679d.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/0f8d84a8b1c74d54beea6f35427dbf65.png)  
 总结: 使用默认DNS解析


### 2、ClusterFirstWithHostNet


在某些场景下,我们的 Pod 是用 HostNetwork 模式启动的,一旦使用 HostNetwork 模式,那该Pod则会使用当前宿主机的/etc/resolv.conf来进行 DNS 查询,但如果任然想继续使用Kubernetes的DNS服务,那就将 dnsPolicy设置为ClusterFirstWithHostNet


* 为了方便验证,将三个node的主机域名解析都缓存不一样的的



vim /etc/resolv.conf

node1

nameserver 233.5.5.5

node2

nameserver 233.6.6.6

node3

nameserver 114.114.114.114


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/f643ae7434b5483c8d15ba128214409e.png)



apiVersion: v1
kind: Pod
metadata:
name: pod-example-2
spec:
hostNetwork: true ## 与主机共享网络
dnsPolicy: ClusterFirst
containers:

  • name: tools
    image: registry.cn-hangzhou.aliyuncs.com/mokeyking/k8s-oldxu:tools-latest
    imagePullPolicy: IfNotPresent
    ports:
    • containerPort: 8899

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/d2441289fb234f62a80f439808f248b0.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/16a17e6b073e4c92a103ee8b2c2f28ac.png)


* 通过指定node标签,让pod创建到指定的node上



kubectl get node --show-labels



apiVersion: v1
kind: Pod
metadata:
name: pod-example-2
spec:
hostNetwork: true
dnsPolicy: ClusterFirst
containers:

  • name: tools
    image: registry.cn-hangzhou.aliyuncs.com/mokeyking/k8s-oldxu:tools-latest
    imagePullPolicy: IfNotPresent
    ports:
    • containerPort: 8899
      nodeSelector:
      kubernetes.io/hostname: node2

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/45c746f8f248458b8702c2d75ffe45d0.png)


通过指定不的node便签进行创建pod,可以看到共享不同pod主机域名解析


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/42f209fa29a04078ad2fd4db56327ae0.png)pod无法通过svc进行解析,可以dnsPolicy规则改为ClusterFirstWithHostNet



apiVersion: v1
kind: Pod
metadata:
name: pod-example-2
spec:
hostNetwork: true ## 共享主机网络
dnsPolicy: ClusterFirstWithHostNet ## 如果配置了首要配置kubernetes的域名解析
containers:

  • name: tools
    image: registry.cn-hangzhou.aliyuncs.com/mokeyking/k8s-oldxu:tools-latest
    imagePullPolicy: IfNotPresent
    ports:
    • containerPort: 8899
      nodeSelector:
      kubernetes.io/hostname: node3

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/4afba21813e540cf838fcde8abba7858.png)


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/7cce6861803a4cdfb193e14772051230.png)


* 这个ClusterFirstWithHostNet策略也适用deployment


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/e169f4d3466f47069cc9df83117f8885.png)


* 编写deployment的资源清单



apiVersion: apps/v1
kind: Deployment
metadata:
name: demoapp

spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
hostNetwork: true
dnsPolicy: ClusterFirst
containers:
- name: webservers
image: oldxu3957/demoapp:v1.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80


apiVersion: v1
kind: Service
metadata:
name: demoapp-svc
spec:
type: NodePort
selector:
app: web
ports:

  • port: 80
    targetPort: 80
    nodePort: 32000

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/5a63df1909d34960b15cd19895089d3d.png)  
 域名解析能解析到node3的主机 /etc/resolv.conf


### 3、default


默认使用宿主机的 /etc/resolv.conf但可以使用 kubelet 的 --resolv-conf=/etc/resolv.conf 来指定 DNS 解析文件地址。


* 使用默认主机的 /etc/resolv.conf



apiVersion: v1
kind: Pod
metadata:
name: pod-example-3
spec:
dnsPolicy: Default
containers:

  • name: tools
    image: registry.cn-hangzhou.aliyuncs.com/mokeyking/k8s-oldxu:tools-latest
    ports:
    • containerPort: 8899
      nodeSelector:
      kubernetes.io/hostname: node3

使用了node3的 /etc/resolv.conf 的默认主机名认证


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/3d625970956a4753ab545db94121e1d1.png)


* 使用node节点的指定路径的域名解析的文件,使用主机挂载方式



apiVersion: v1
kind: Pod
metadata:
name: pod-example-6
spec:
containers:

  • name: tools
    image: registry.cn-hangzhou.aliyuncs.com/mokeyking/k8s-oldxu:tools-latest
    imagePullPolicy: IfNotPresent
    volumeMounts:
    • name: resolv-conf
      mountPath: /etc/resolv.conf
      readOnly: true
      dnsPolicy: Default
      dnsConfig:
      options:
      • name: ndots
        value: “2”
        volumes:
  • name: resolv-conf
    hostPath:
    path: /root/resolv.conf
    nodeSelector:
    kubernetes.io/hostname: node3

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/6a8adfed0e6f42a7bc1a35f132b1310a.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/fd824f9e39fa41d4929e8adf1ac32fc2.png)


* 将域名添加到,并执行域名解析的ip,我特定的域名地址



apiVersion: v1
kind: Pod
metadata:
name: pod-example-4
spec:
containers:

  • name: tools
    image: registry.cn-hangzhou.aliyuncs.com/mokeyking/k8s-oldxu:tools-latest
    dnsPolicy: Default
    dnsConfig:
    nameservers:
    • 10.0.0.1
    • 10.0.0.2
      searches:
    • /etc/resolv.conf
    • otherdomain.svc.cluster.local
      nodeSelector:
      kubernetes.io/hostname: node2

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/5936a6a00e5d49e887dedbf44d4a8021.png)


#### 4、Node


空的DNS设置,这种方式一般用于自定义 DNS 配置的场景,往往需要和dnsConfig一起使用才可以达到自定义DNS的目的。



apiVersion: v1
kind: Pod
metadata:
name: pod-example-7
spec:
containers:

  • name: tools
    image: registry.cn-hangzhou.aliyuncs.com/mokeyking/k8s-oldxu:tools-latest
    imagePullPolicy: IfNotPresent
    dnsPolicy: None
    dnsConfig:
    nameservers:
    • 233.5.5.5
    • 233.6.6.6
      searches:
    • mydomain.com
    • otherdomain.svc.cluster.local
    • king.net
      nodeSelector:
      kubernetes.io/hostname: node1

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/e5af54287242431d85c9e52e67461daa.png)


## 十三、HeadLess Service


### 1、什么是HeadLess


HeadlessService也叫无头服务,就是创建的Service没有ClusterIP,而是为Service所匹配的每个Pod都创建一条DNS的解析记录,这样每个Pod都有一个唯一的DNS名称标识身份,访问的格式如下


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/1c56329772084269a2dae6070cc64e30.png)


### 2、HeadLess的作用


像 elasticsearch,mongodb,kafka 等分布式服务,在做集群初始化时,配置文件中要写上集群中所有节点的IP(或是域名)但Pod是没有固定IP的,所以配置文件里写DNS名称是最合适的。


那为什么不用Service,因为 Service 作为 Pod 前置的负载均衡一般是为一组相同的后端 Pod 提供访问入口,而且 Service的selector也没有办法区分同一组Pod的不同身份。


但是我们可以使用 Statefulset控制器,它在创建每个Pod的时候,能为每个 Pod 做一个编号,就是为了能区分这一组Pod的不同角色,各个节点的角色不会变得混乱,然后再创建 headless service 资源,集群内的节点通过Pod名称+序号.Service名称,来进行彼此间通信的只要序号不变,访问就不会出错。


当statefulSet.spec.serviceName 配置与headless service相同时,可以通过 {hostName}.fheadless service}.{namespace}.svc.cluster.local 解析出节点IP。hostName 由{statefulSet name}-{编号}组成。



{statefulSet name}-{编号}.{headless service}{namespace}.svc.cluster.local

放在当前es中,对应的DNS子域名分别是

es-0.elastic.default.svc.cluster.local
es-1.elastic.default.svc.cluster.local
es-2.elastic.default.svc.cluster.local


### 3、HeadLess示例



apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
clusterIP: “None”
selector:
app: nginx
ports:

  • port: 80
    targetPort: 80

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/102ec1c606c5497a9f1c68bde327fcf7.png)


* 编写pod资源



apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: “myapp”
replicas: 2

selector:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Linux运维工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Linux运维知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加VX:vip1024b (备注Linux运维获取)
img

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

spec:
serviceName: “myapp”
replicas: 2

selector:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Linux运维工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-hR6V4YQ7-1712300261272)]
[外链图片转存中…(img-t0J2MvIQ-1712300261272)]
[外链图片转存中…(img-LXgp07AY-1712300261273)]
[外链图片转存中…(img-Is8CEMH2-1712300261273)]
[外链图片转存中…(img-PyMll2eE-1712300261273)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Linux运维知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加VX:vip1024b (备注Linux运维获取)
[外链图片转存中…(img-M2wAJMJs-1712300261273)]

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值