kubernetes负载均衡-service,【高级Linux运维架构师系统学习】

十、IPVS模型分析

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

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

1、设置集群为IPVS模式

在这里插入图片描述

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 'NR==3 || NR==4 {print $1}') -n kube-system 

在这里插入图片描述

1.3 IPVS 规则查看
## 全部规则查看
ipvsadm -L -n
## IPVS的映射网卡查看
ip a  s  ## 查看网卡
kubect get svc ## 查看svc 
如图所示,正式映射关系

在这里插入图片描述
在这里插入图片描述

十一、服务发现

当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

在这里插入图片描述

kubectl  exec  -it tools  -- /bin/bash
env | grep -i demoapp_svc 
ping ${DEMOAPP\_SVC\_SERVICE\_HOST}

在这里插入图片描述

在这里插入图片描述

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

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

在这里插入图片描述
在这里插入图片描述
pod无法获取新创建的svc的环境变量信息
但是再新创建一个pod就会能或者svc的变量信息
在这里插入图片描述
重新创建一个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

默认的域名解析配置
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

解析svc域名
在这里插入图片描述
总结:可以解析到对应的svcIP

在这里插入图片描述
总结:删除svc时,svc的ip就会发生变化,但是重新对svc的域名进行解析,仍然能够解析到svc的ip。只要service的名称不发生变化,就可以正常解析,所有可以将这个注入到pod的中,就可以解析svc的配置。这个DNS是通过cordDNS进行转发解析的。

在这里插入图片描述

十二、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的策略
在这里插入图片描述
在这里插入图片描述
总结: 使用默认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


在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

  • 通过指定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

在这里插入图片描述

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

在这里插入图片描述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

在这里插入图片描述

在这里插入图片描述

  • 这个ClusterFirstWithHostNet策略也适用deployment

在这里插入图片描述

  • 编写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
   

在这里插入图片描述
域名解析能解析到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 的默认主机名认证

在这里插入图片描述

  • 使用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

在这里插入图片描述
在这里插入图片描述

  • 将域名添加到,并执行域名解析的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

在这里插入图片描述

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

在这里插入图片描述

十三、HeadLess Service

1、什么是HeadLess

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

在这里插入图片描述

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

在这里插入图片描述

  • 编写pod资源
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "myapp"
  replicas: 2


  selector:
   matchLabels:
     app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: xx
        image: nginx:1.16
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80

在这里插入图片描述

  • 使用tools 进行验证测试
kubectl  exec -it tools -- /bin/bash

在这里插入图片描述

  • ping myapp.default.svc.cluster.local 可以轮询到不同的pod上。

在这里插入图片描述

  • ping web-1.myapp.default.svc.cluster.local 使用这个可以解析到指定的pod上

4、HeadLess测试

在这里插入图片描述
在这里插入图片描述
总结: 通过删除pod。依旧可以通过域名的方式进行解析

十四、guestBook案例实践

guestBook官网示例
guestBook的GitHub地址

1、场景描述

  • 1、启动 Redis、领导 者(Leader)
  • 2、启动两个 Redis 跟随者(Follower)
  • 3、启动并公开 GuestBook 服务,数据写入Redis Leader节点数据读取统一写入Redis Slave节点
  • 3.1 如果 GET HOSTS_FROM 设置为 env,则需要手动传递Redis Master、以及Slave的 Service名称;
    REDIS LEADER SERVICE HOST # 传递Leader节点的Service名称或IP
    REDIS FOLLOWER_SERVICE_HOST # 传递 Follower节点Service的名称或IP
  • 3.2 如果 GET HOSTS_FROM 设置为 dns,则站点会自动初始化两个变量,这就要求创建service时的名称得固定;
    $host =‘redis-leader’;
    $host =‘redis-follower’;

在这里插入图片描述

2、部署Redis-Leader

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-leader            # Deployment Pod的名称
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis-master
  template:
    metadata:
      labels:
        app: redis-master
    spec:
      containers:
      - name: redis-container
        image: redis
        ports:
        - containerPort: 6379

---
apiVersion: v1
kind: Service
metadata:
  name: redis-leader
spec:
  type: ClusterIP
  selector:
    app: redis-master
  ports:
  - port: 6379
    targetPort: 6379

在这里插入图片描述

3、部署redis-follower

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-follower
spec:
  replicas: 2
  selector:
    matchLabels:
      app: redis-slave
  template:
    metadata:
      labels:
        app: redis-slave
    spec:
      containers:
      - name: redis-slave
        image: redis 
        command: ["redis-server"]
        args:
        - --port 6379
        - --slaveof redis-leader 6379

---
apiVersion: v1
kind: Service
metadata:
  name: redis-follower
spec:
  type: ClusterIP
  selector:
    app: redis-slave
  ports:
  - port: 6379
    targetPort: 6379

在这里插入图片描述
在这里插入图片描述

4、部署guestbooks的deploy和service

apiVersion: apps/v1
kind: Deployment
metadata:
  name: guestbooks
spec:
  replicas: 3
  selector:
    matchLabels:
      app: books
  template:
    metadata:
      labels:
        app: books
    spec:
      containers:
      - name: books-container
       # image: oldxu3957/guestbook:v5
        image: uhub.service.ucloud.cn/oldxu/guestbook:v7  
        env:
        - name: GET_HOSTS_FROM
          value: "env"
        - name: REDIS_LEADER_SERVICE_HOST
          value: "redis-leader"
        - name: REDIS_FOLLOWER_SERVICE_HOST
          value: "redis-follower"
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: guestbook-svc
spec:
  type: NodePort
  selector:
    app: books
  ports:
  - name: http
    port: 80
    targetPort: 80
    nodePort: 32002

在这里插入图片描述
将redis的server的环境变量注册到Guesbook的环境变量中

在这里插入图片描述
登陆redis从库查看数据
在这里插入图片描述

在这里插入图片描述

5、使用Ingress部署guestbooks

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: books-ingress
spec:
  ingressClassName: "nginx"
  rules:


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

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

**因此收集整理了一份《2024年Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/2b2c236a4f0f56463361a00c0e9ab5c1.png)
![img](https://img-blog.csdnimg.cn/img_convert/8aa2b9b95ecaac7dd974ed87c5ead87a.png)
![img](https://img-blog.csdnimg.cn/img_convert/420c13de5bcd657dec4149a22b2e0348.png)
![img](https://img-blog.csdnimg.cn/img_convert/fc91a80cb868c186479fcb8e6161b4b7.png)
![img](https://img-blog.csdnimg.cn/img_convert/96bccf15c34149ff11d2acf95403123b.png)

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

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

**如果你觉得这些内容对你有帮助,可以添加VX:vip1024b (备注Linux运维获取)**
![img](https://img-blog.csdnimg.cn/img_convert/7946a56113569a21ab7d90b22a39bbf0.jpeg)



### 最后的话

最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!

### 资料预览

给大家整理的视频资料:

![](https://img-blog.csdnimg.cn/img_convert/1481cc5cbeaf7e5caccb4a802063482e.png)

给大家整理的电子书资料:

  

![](https://img-blog.csdnimg.cn/img_convert/1c75dc6d44af8e17642974d7be0bb660.png)



**如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!**


**一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
![img](https://img-blog.csdnimg.cn/img_convert/07ea451fc03978bf58310dc900f41ebc.jpeg)

望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
[外链图片转存中...(img-meuM9DrC-1712504049894)]
[外链图片转存中...(img-sa25HJVl-1712504049895)]
[外链图片转存中...(img-QtQtm7cD-1712504049896)]
[外链图片转存中...(img-5jVGMOSg-1712504049896)]
[外链图片转存中...(img-llPZN8K0-1712504049897)]

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

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

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



### 最后的话

最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!

### 资料预览

给大家整理的视频资料:

[外链图片转存中...(img-DhR8xThF-1712504049897)]

给大家整理的电子书资料:

  

[外链图片转存中...(img-4cd1P0XS-1712504049898)]



**如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!**


**一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
[外链图片转存中...(img-G6UqZtFR-1712504049898)]

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值