k8s相关服务与负载均衡

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: k8s相关服务与负载均衡

k8s相关服务与负载均衡

一,服务基础

1,多容器集群,多副本会自动分配到不同的计算节点上(2副本实验)

[root@master config]# vim pod-apache.yaml

replicas: 2            #副本数改成2

[root@master config]# kubectl apply -f pod-apache.yaml

[root@master config]# kubectl get pod -o wide  #查看,此时运行两个资源都在zsl节点上

NAME                        READY  STATUS    RESTARTS  AGE  IP            NODE  NOMINATED NODE  READINESS GATES

my-apache-695fd775fd-jpsgr  1/1    Running  0          27s  10.244.2.30  zsl    <none>          <none>

my-apache-695fd775fd-x8c4d  1/1    Running  0          27s  10.244.2.29  zsl    <none>          <none>

2,会变化的pod资源,当发现某一个pod不能使用的时候,RS会在其他节点上再创建一个相同的pod,及其对应的容器。

例:模拟其中一个资源容器不可用,此时会再创建出一个新的pod资源,而且可以在任何节点上生成,且ip地址也会发生改变。

[root@master config]# kubectl delete pod my-apache-695fd775fd-x8c4d            #删除其中一个资源

[root@master config]# kubectl get pod -o wide #再次查看,又新生一个pod资源在node节点上

NAME                        READY  STATUS    RESTARTS  AGE    IP            NODE  NOMINATED NODE  READINESS GATES

my-apache-695fd775fd-4bng8  1/1    Running  0          16s    10.244.1.13  node  <none>          <none>

my-apache-695fd775fd-jpsgr  1/1    Running  0          6m53s  10.244.2.30  zsl    <none>          <none>

3,service服务

①,pod存在生命周期,每个一段时间,pod就会自动重新创建,ip地址也会发生变化,所以直接对pod中的服务产生很大影响,因为访问地址在不断地变化。

②,service服务作用是创建一个cluster ip,也可以实现pod的负载均衡。用户访问web服务时,先访问service的cluster ip,由service代替用户找到对应的pod,最后访问pod中的web服务器。

③,会变化的pod给我们带来了诸多的不变,service就是解决这一问题的方法,会创建一个cluster ip,这个地址对应资源地址,且不会变化,会在多个服务上实现负载均衡的访问效果。

④,service服务通过port、nodeport、targetport将访问的请求最终映射到pod的容器内部服务上。

4,service服务端口

①,port:是service暴露在cluster ip上的端口,是提供给集群内部客户访问service的入口,供集群内部服务访问使用。

②,targetport:是pod上容器服务监听的端口,从port或nodeport上到来的数据最终经过kube-proxy流入到后端pod的targetport上进入容器,从而达到访问pod容器内部服务的目的。

5,service服务资源文件

①,作修改

[root@master config]# vim pod-apache.yaml      #修改Apache资源文件

matchLabels:              #匹配具体的东西

     app: mytest        #更改标签名字,与下面的labels相同

 replicas: 2

 template:

   metadata:

     labels:

       app: mytest      #更改标签名字

②,编辑

[root@master config]# vim pod-service.yaml #编辑新的yaml资源文件

---

apiVersion: v1

kind: Service

metadata:

 name: httpd-service

spec:

 ports:

 - protocol: TCP

   port: 80              #设置端口

   targetPort: 80

 selector:

   app: mytest          #要和上面pod-apache.yaml文件的标签一致

 type: ClusterIP

[root@master config]# kubectl delete -f pod-apache.yaml  #删除原来的

[root@master config]# kubectl apply -f pod-apache.yaml #运行修改后的

[root@master config]# kubectl apply -f pod-service.yaml #运行新创建的

③,查看k8s集群中service信息

[root@master config]# kubectl get service

NAME            TYPE        CLUSTER-IP    EXTERNAL-IP  PORT(S)  AGE

httpd-service  ClusterIP  10.96.79.49  <none>        80/TCP    64s

kubernetes      ClusterIP  10.96.0.1    <none>        443/TCP  2d1h

④,此时直接使用10.96.79.49这个ip地址是访问不了的,需要进入到容器访问。

创建一个资源类型为pod的资源文件

[root@master config]# vim pod-httpd.yaml

---

apiVersion: v1 #版本

kind: Pod    #资源类型

metadata:

 name: my-pod

 labels:

   app: mypod

spec:

 containers:

 - name: my-pod-httpd    #容器名字

   image: 192.168.1.134:5000/myapache:httpd  #指定镜像

   stdin: true      #开启交互式和终端

   tty: true

   #ports:                #注释掉端口和协议

   #- protocol: TCP

   #  containerPort: 80

⑤,创建资源

[root@master config]# kubectl apply -f pod-httpd.yaml

pod/my-pod created

[root@master config]# kubectl get pod -o wide #查看,pod下两个容器在运行

NAME                        READY  STATUS    RESTARTS  AGE    IP            NODE  NOMINATED NODE  READINESS GATES

my-apache-f9b95d95f-jn4vv  1/1    Running  0          10m    10.244.2.32  zsl    <none>          <none>

my-apache-f9b95d95f-skjh7  1/1    Running  0          10m    10.244.2.31  zsl    <none>          <none>

my-pod                      1/1    Running  0          2m46s  10.244.1.14  node  <none>          <none>

[root@master config]#  kubectl get service #查看集群中service服务信息

NAME            TYPE        CLUSTER-IP    EXTERNAL-IP  PORT(S)  AGE

httpd-service  ClusterIP  10.96.79.49  <none>        80/TCP    11m

kubernetes      ClusterIP  10.96.0.1    <none>        443/TCP  2d1h

⑥,进入容器

[root@master config]# kubectl exec -it my-pod -- /bin/bash

[root@my-pod html]#

⑦,访问成功

[root@my-pod html]# curl 10.96.79.49  #访问的是service服务中的httpd服务地址

[root@my-pod html]# curl 10.96.79.49/info.php  #访问成功,多访问几次,此时是轮询的,可以看到php_host: 处的变化,不同的容器在提供服务

<pre>

Array

(

   [REMOTE_ADDR] => 10.244.1.14

   [REQUEST_METHOD] => GET

   [HTTP_USER_AGENT] => curl/7.29.0

   [REQUEST_URI] => /info.php

)

php_host: my-apache-f9b95d95f-skjh7

1229

二,服务自动发现

1,创建服务:kubectl apply -f 资源文件

2,查询服务:kubectl get  service

3,服务自动发现:cluster ip是集群分配的服务ip,供集群访问,在集群内部也可以通过服务的名称访问,服务的名称是通过coredns解析的,每个服务在创建的过程中都会完成自动注册。

服务名称:<服务名称>.<名称空间>.svc.cluster.local

4,在刚才的容器里,直接访问服务名称

[root@my-pod html]# curl httpd-service    #服务名称,从service查看

[root@my-pod /]# curl httpd-service.default.svc.cluster.local #也可以加上后缀访问

[root@my-pod /]# cat /etc/resolv.conf  #后缀所在文件

nameserver 10.96.0.10

search default.svc.cluster.local svc.cluster.local cluster.local

options ndots:5

5,多资源文件,多个资源可以写到同一个文件中,使用---分割

[root@master config]# cat pod-apache.yaml > web.apache.yaml

[root@master config]# cat pod-service.yaml >> web.apache.yaml  #写到一个文件中

[root@master config]# kubectl delete -f pod-apache.yaml  #删除资源

[root@master config]# kubectl delete -f pod-service.yaml #删除资源

[root@master config]# kubectl get pod -o wide  #查看,还剩一个pod资源在运行

NAME    READY  STATUS    RESTARTS  AGE  IP            NODE  NOMINATED NODE  READINESS GATES

my-pod  1/1    Running  0          90m  10.244.1.14  node  <none>          <none>

6,查看并创建运行资源

[root@master config]# vim web.apache.yaml

         #tty: true

         ports:

           - protocol: TCP

             containerPort: 80

---                                      #两个资源文件,分割

apiVersion: v1

kind: Service

metadata:

 name: httpd-service


[root@master config]# kubectl apply -f web.apache.yaml #一次创建出两个

deployment.apps/my-apache created

service/httpd-service created

[root@master config]# kubectl get service #查看

NAME            TYPE        CLUSTER-IP      EXTERNAL-IP  PORT(S)  AGE

httpd-service  ClusterIP  10.96.211.116  <none>        80/TCP    50s

kubernetes      ClusterIP  10.96.0.1      <none>        443/TCP  2d2h

[root@master config]# kubectl get pod        #查看

NAME                        READY  STATUS    RESTARTS  AGE

my-apache-f9b95d95f-8m8qv  1/1    Running  0          56s

my-apache-f9b95d95f-zfkhh  1/1    Running  0          56s

my-pod                      1/1    Running  0          95m

三,服务原理

1,代理模式:

k8s v1.0服务支持userspace代理模式

k8s v1.1服务支持iptables代理模式

k8s v1.8服务支持IPVS代理模式

在k8s v1.2中,kube-proxy的iptables模式成为模式设置,现在默认使用IPVS,如果不能满足,要求退回至iptables模式

2,userspace用户空间代理模式:

用户访问的还是cluster ip,cluster ip并不是把请求转发给后端的容器,而是把请求转发给kube-proxy,再由kube-proxy转发给后端的容器,各个服务中,此时由于所有的请求都给了kube-proxy,对于这个软件的要求就比较高,性能很差,为了解决这个问题,就需要使用其他模式。

3,iptables模式:

此模式在用户访问的时候发生了变化,用户访问到cluster ip之后,由iptables实现端口映射,把请求转发到后端,此时kube-proxy只是设置负载均衡映射的访问策略和端口转发规则,但是算法有限,更多的功能支持不了,此时就有了IPVS模式,此模式架构不变,只是用户访问的是lvs模块。

4,IPVS模式:与iptables模式架构相同,只是用户访问的是lvs模块。

四,在外部访问集群

1,service允许指定一个type类型,默认是cluster ip。

2,type类型:

①,cluster ip:通过集群的内部ip暴露服务,服务只能够在集群内部可以访问,这就是默认的servicetype。

②,nodeport:通过每个node的ip和静态端口(nodeport)暴露服务,nodeport服务会路由到cluster ip服务。

③,loadbalancer:使用云提供商的负载均衡器,外部的负载均衡器可以路由到nodeport服务和cluster ip服务。

3,nodeport:是提供给集群外部用户访问service入口的一种方式,是提供给集群外部用户访问service的入口。

五,对外发布服务

1,之前构建的服务已经可以在集群内部运转起来了,但集群外部还是无法访问集群内部的服务。

2,有时候服务可能来自第三方或者其他团队,无法把所有服务都放入集群内部,这时候就需要集群内部和集群外部的服务实现互访。

①,loadbalancer:使用外部的云服务(需要支持,externallps)

②,nodeport:基于端口对外提供服务(四层)

③,lngress:使用ingress规则控制器(七层)

例:修改服务类型

[root@master config]# vim pod-service.yaml

   app: mytest

 type: NodePort            #改为nodeport,基于端口对外提供服务

[root@master config]# kubectl apply -f pod-apache.yaml#运行Apache资源

[root@master config]# kubectl apply -f pod-service.yaml  #创建资源

[root@master config]# kubectl get service    #查看

NAME            TYPE        CLUSTER-IP      EXTERNAL-IP  PORT(S)        AGE

httpd-service  NodePort    10.96.161.244  <none>        80:30552/TCP  49s

kubernetes      ClusterIP  10.96.0.1      <none>        443/TCP        2d3h

测试访问,都可以访问成功

访问:curl  节点主机名(IP地址):服务映射端口,任何节点都可以

[root@master config]# curl node:30552

[root@master config]# curl zsl:30552

[root@master config]# curl node:30552/info.php

<pre>

Array

(

   [REMOTE_ADDR] => 10.244.1.0

   [REQUEST_METHOD] => GET

   [HTTP_USER_AGENT] => curl/7.29.0

   [REQUEST_URI] => /info.php

)

php_host: my-apache-f9b95d95f-thtrp

1229

五,headless服务

1,有时不需要或不想要负载均衡,以及单独的cluster ip,遇到这种情况,我们可以创建headless服务。

2,headless服务会把ip通过多个A记录的形式解析到具体的容器ip上面,多用于有状态的服务。

3,测试,复制service服务资源文件

[root@master config]# cp pod-service.yaml  headless.yaml

[root@master config]# vim headless.yaml

---

apiVersion: v1

kind: Service

metadata:

 name: headless        #名字可改可不改

spec:

 ports:

 - protocol: TCP

   port: 80

   targetPort: 80

 selector:

   app: mytest

 type: ClusterIP    #更改为ClusterIP类型

 clusterIP: None          #设置为none,不设置ip

4,创建资源

[root@master config]# kubectl apply -f headless.yaml  #运行headless资源文件

[root@master config]# kubectl apply -f pod-httpd.yaml#运行pod类型资源文件

[root@master config]# kubectl exec -it my-pod -- /bin/bash  #进入容器

5,安装需要的软件

[root@my-pod html]# cd /etc/yum.repos.d/  #这里需要配置yum源

[root@my-pod yum.repos.d]# ls

dv

[root@my-pod yum.repos.d]# vim dvd.repod.repo

[dvd]

name=dvd

baseurl=http://192.168.1.134/mnt  #去访问另外一个节点的挂载点,需要把挂载点放到/var/www/html下

enabled=1

gpgcheck=0

[root@my-pod ~]# yum -y install bind-utils #安装软件

6,访问测试

[root@my-pod yum.repos.d]# host headless  #如果访问不了,是dns域名解析失败

六,lngress控制器

1,lngress公开了集群外部到集群内部的service路由。

2,可以将lngress配置为提供服务、外部可访问的URL负载均衡流量。

3,lngress控制器通常由负载均衡器来实现。

4,必须具有ingress控制器才能满足lngress的要求,仅创建资源无效。

5,lngress:是从集群外部访问集群内部的路由。

6,lngress控制器接收用户的域名访问请求,将请求分发给集群中的service服务,由service服务以负载均衡的方式,将请求分发给pod,由pod中的容器提供对应的服务。

7,安装lngress

我这里已经准备好了ingress的安装tar包

[root@master ~]# cd ingress/

[root@master ingress]# ls

ingress-example.yaml  ingress-nginx.tar.gz  ingress-service.yaml  mandatory.yaml

[root@master ingress]# docker load -i ingress-nginx.tar.gz  #恢复镜像

[root@master ingress]# docker tag quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0  192.168.1.134:5000/nginx-ingress:0.30.0          #打标签

[root@master ingress]# docker push 192.168.1.134:5000/nginx-ingress:0.30.0            #传到私有仓库

[root@master ingress]# curl 192.168.1.134:5000/v2/_catalog  #查看,已上传到私有仓库

{"repositories":["centos","myapache","nginx","nginx-ingress","redis","ububtu"]}

8,编辑安装ingress的资源文件

[root@master ingress]# vim mandatory.yaml

221          image: 192.168.1.134:5000/nginx-ingress:0.30.0 #改成私有仓库地址

[root@master ingress]# kubectl apply -f mandatory.yaml #创建资源

9,验证是否成功,需要指定命名空间,因为ingress创建的有自己的命名空间

[root@master ingress]# kubectl -n ingress-nginx get  pod

NAME                                        READY  STATUS            RESTARTS  AGE

nginx-ingress-controller-5cdb8dbb4c-rz5qp  0/1    CrashLoopBackOff  2          40s

10,创建

[root@master ~]# kubectl delete -f config/web.apache.yaml #把原来的资源停掉

[root@master ~]# kubectl apply -f config/web.apache.yaml  #重新创建

[root@master ~]# kubectl apply -f ingress/ingress-example.yaml #创建ingress资源

[root@master ~]# kubectl get ingresses              #查看

NAME    CLASS    HOSTS  ADDRESS  PORTS  AGE

my-app  <none>  *                80      23s

11,访问,任何一个节点的ip都可以访问了,公开了内部、外部之间的路由

[root@master ~]# curl 192.168.1.133

[root@master ~]# curl 192.168.1.134

[root@master ~]# curl 192.168.1.135

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
20天前
|
运维 Kubernetes 容器
【Azure K8S】演示修复因AKS密钥过期而导致创建服务不成功的问题(The provided client secret keys for app ****** are expired)
【Azure K8S】演示修复因AKS密钥过期而导致创建服务不成功的问题(The provided client secret keys for app ****** are expired)
【Azure K8S】演示修复因AKS密钥过期而导致创建服务不成功的问题(The provided client secret keys for app ****** are expired)
|
21天前
|
Kubernetes 安全 Docker
在K8S中,在服务上线的时候Pod起不来怎么进行排查?
在K8S中,在服务上线的时候Pod起不来怎么进行排查?
|
21天前
|
Kubernetes 网络安全 容器
在K8S中,有个服务使用service的nodeport进行暴露,发现访问不到如何排查?
在K8S中,有个服务使用service的nodeport进行暴露,发现访问不到如何排查?
|
21天前
|
存储 JSON Kubernetes
在K8S中,服务是如何发布的?
在K8S中,服务是如何发布的?
|
21天前
|
Kubernetes 负载均衡 网络协议
在K8S中,headless服务是什么?
在K8S中,headless服务是什么?
|
22天前
|
Kubernetes 网络协议 网络安全
在K8S中,容器提供一个服务,外部访问慢,到底是容器网络问题?还是容器服务问题?这种怎么排查?
在K8S中,容器提供一个服务,外部访问慢,到底是容器网络问题?还是容器服务问题?这种怎么排查?
|
22天前
|
存储 缓存 Kubernetes
在K8S中,有状态服务与无状态服务都是怎么使用pv和pvc?(可以通过应用场景说明一下)
在K8S中,有状态服务与无状态服务都是怎么使用pv和pvc?(可以通过应用场景说明一下)
|
24天前
|
Kubernetes 关系型数据库 MySQL
k8s练习--通过NFS+PV+PVC+POD,部署一个MySQL服务,并将MySQL的数据进行持久化存储
本文档介绍了如何使用Kubernetes (K8s)、NFS、PersistentVolume (PV)、PersistentVolumeClaim (PVC)和Pod来部署并实现MySQL服务的数据持久化存储。Kubernetes是一个用于自动化部署、扩展和管理容器化应用的强大平台。NFS作为一种网络文件系统协议,能够使Kubernetes集群中的Pod跨节点访问共享文件。PV和PVC机制则提供了持久化的存储解决方案,确保数据即使在Pod生命周期结束后仍得以保留。
|
11天前
|
存储 Kubernetes 负载均衡
CentOS 7.9二进制部署K8S 1.28.3+集群实战
本文详细介绍了在CentOS 7.9上通过二进制方式部署Kubernetes 1.28.3+集群的全过程,包括环境准备、组件安装、证书生成、高可用配置以及网络插件部署等关键步骤。
89 3
CentOS 7.9二进制部署K8S 1.28.3+集群实战
|
11天前
|
Kubernetes 负载均衡 前端开发
二进制部署Kubernetes 1.23.15版本高可用集群实战
使用二进制文件部署Kubernetes 1.23.15版本高可用集群的详细教程,涵盖了从环境准备到网络插件部署的完整流程。
29 2
二进制部署Kubernetes 1.23.15版本高可用集群实战