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             

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

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           

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

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          80/TCP    64s

kubernetes      ClusterIP  10.96.0.1            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             

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

my-pod                      1/1    Running  0          2m46s  10.244.1.14  node           

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

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

httpd-service  ClusterIP  10.96.79.49          80/TCP    11m

kubernetes      ClusterIP  10.96.0.1            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: 处的变化,不同的容器在提供服务

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           

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          80/TCP    50s

kubernetes      ClusterIP  10.96.0.1              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          80:30552/TCP  49s

kubernetes      ClusterIP  10.96.0.1              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

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    *                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

你可能感兴趣的:(k8s相关服务与负载均衡)