服务的发布

发布的方式

之前说过了服务的发现,这个是服务的发布,服务的发布其实就是让你的应用可以被外部访问到,因为如果你的服务外部不可以访问的话那你起这个服务有什么作用呢?没有什么太大的作用是吧

默认情况下,外界是无法访问到集群内的ClusterIP的

1.NodePort

nodePort就是将svc的某个端口与集群的某个端口做了一个映射

通过nodePort映射出去有2种方法

方法一:创建的时候直接指定类型

这种方式比较简单

  1. # 先创建一个nginx的pod
  2. [root@master ~]# kubectl run web01 --image nginx --image-pull-policy IfNotPresent
  3. pod/web01 created
  4. [root@master ~]# kubectl get pods -o wide
  5. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  6. web01 1/1 Running 0 6s 10.244.104.13 node2 <none> <none>

我们可以看到他的IP地址是10.244.104.14,我们使用windows的cmd来ping一下这个地址看看能不能通



我们可以看到这个地址是不通的,既然不通那浏览器也肯动访问不到

我们现在通过nodePort将他映射出去

  1. [root@master ~]# kubectl expose pod web01 --type NodePort --port 80 --target-port 80
  2. service/web01 exposed
  3. [root@master ~]# kubectl get svc
  4. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  5. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 38d
  6. pod01 ClusterIP 10.100.218.31 <none> 80/TCP 4d4h
  7. web01 NodePort 10.102.81.211 <none> 80:31545/TCP 4s

我们可以看到有一个NodePort类型的svc 他也有一个集群内部的IP地址,但是我们要访问的不是这个IP,我们只用看他的端口

他映射的端口是31545,那么这个端口如何使用呢?

这个端口可以跟在集群内的任意一台节点的IP地址后面

比如,这个pod是跑在node02上的,我们可以通过node02的IP地址:31545就可以访问到,或者通过node01的IP地址:31545,当然使用master:31545也是可以的

是不是这样的呢?我们来看看

  1. 我们首先通过master的IP地址来访问



    可以看到是通的
  2. 我们再通过node01的IP地址来访问



    使用node01的也是可以的
  3. 使用node02的IP地址来访问



    也是没有任何的问题

    现在集群内部的nginx就可以被外部访问到了

方法二:在线修改(将其他类型改为NodePort)

我们先将刚刚创建的svc删除,pod保留

  1. [root@master ~]# kubectl expose pod web01 --port 80 --target-port 80
  2. service/web01 exposed
  3. [root@master ~]# kubectl get svc
  4. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  5. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 38d
  6. web01 ClusterIP 10.104.17.66 <none> 80/TCP 5s

只要不指定类型,那么默认就是ClusterIP,现在我们通过在线修改的方式去改变他

  1. [root@master ~]# kubectl edit svc/web01
  2. 我们只需要改动这几处地方,其他的地方不用变
  3. ports:
  4. # 这里加上一个nodePort,也就是你开放的端口,不写这里的话他就是随机开放一个端口
  5. - nodePort: 30888
  6. port: 80
  7. protocol: TCP
  8. targetPort: 80
  9. #type这个地方将clusterIP改为NodePort
  10. sessionAffinity: None
  11. type: NodePort
  12. # 改完这些之后保存退出就可以了
  13. [root@master ~]# kubectl get svc
  14. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  15. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 38d
  16. web01 NodePort 10.104.17.66 <none> 80:30888/TCP 114s

可见,他的类型从ClusterIP变成了NodePort

这个时候你可能会问,他后面还是得跟上端口啊,而且端口还是5位数,不太好记,也是一样的很麻烦啊,其实我们的服务并不会直接通过这种方式去暴露在互联网上,我们会通过负载均衡器或者防火墙来开放80/443端口,然后流量到80/443之后负载均衡器会把流量转发到对应的端口,这样的话用户就不用知道具体的端口,他只用输入域名或者IP就可以访问到我们的服务了

2.LoadBalance

要使用这个方式需要先安装第三方插件,因为LoadBalance翻译过来是负载均衡器,但是实际上不是的,他是一个地址池

集群起来之后每个节点都分配一个公网IP会有点浪费资源

我们通过实验来理解

前置条件:需要安装一个三方插件

  1. kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.3/config/manifests/metallb-native.yaml

如果因为网络原因创建失败的话可以使用一些特殊手段来尝试一下

安装完成之后执行这个命令

  1. [root@master metallb]# kubectl get pods -n metallb-system
  2. NAME READY STATUS RESTARTS AGE
  3. controller-7d678cf54-w8r9x 1/1 Running 0 62s
  4. speaker-2crsx 1/1 Running 0 61s
  5. speaker-s668p 1/1 Running 0 61s
  6. speaker-wcb7s 1/1 Running 0 61s

会有一个新的命名空间

注意:我们是模拟公网IP地址池,你把地址池里的地址当作是公网的IP地址就行了

安装完成之后再创建2个yaml文件,一个是创建地址池,一个是配置2层工作模式

  1. # 创建地址池
  2. apiVersion: metallb.io/v1beta1
  3. kind: IPAddressPool
  4. metadata:
  5. name: first
  6. namespace: metallb-system
  7. spec:
  8. addresses:
  9. # 写上地址段
  10. - 192.168.200.240-192.168.200.250

这就是第一个yaml文件

然后再来第二个yaml文件

  1. apiVersion: metallb.io/v1beta1
  2. kind: L2Advertisement
  3. metadata:
  4. name: example
  5. namespace: metallb-system
  6. spec:
  7. ipAddressPools:
  8. - first

然后应用这2个yaml文件

  1. [root@master ~]# kubectl apply -f ippools.yaml
  2. [root@master ~]# kubectl apply -f l2.yaml
  3. # 查询一下地址池
  4. [root@master ~]# kubectl get ipaddresspools.metallb.io -n metallb-system
  5. NAME AUTO ASSIGN AVOID BUGGY IPS ADDRESSES
  6. first true false ["192.168.200.240-192.168.200.250"]

然后我们现在创建一个nginx的pod,使用Load Balance方式将他发布出去

  1. [root@master ~]# kubectl run nginx01 --image nginx --image-pull-policy IfNotPresent
  2. pod/nginx01 created
  3. [root@master ~]# kubectl expose pods/nginx01 --type LoadBalancer --port 80 --target-port 80
  4. service/nginx01 exposed
  5. [root@master ~]# kubectl get pods
  6. NAME READY STATUS RESTARTS AGE
  7. nginx01 1/1 Running 0 21s
  8. [root@master ~]# kubectl get svc
  9. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  10. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 38d
  11. nginx01 LoadBalancer 10.99.228.13 192.168.200.240 80:32042/TCP 8s

到这里我们可以看到,external-ip这里是有一个ip地址的,我们来尝试访问一下这个IP地址



没有问题,我们同时也看到在port那里有一个32042的端口,这个端口是干嘛的呢?这个端口其实就是nodePort的端口

我们使用某个节点的IP:32042



没有任何的问题

我们之前就说了这个是模拟的公网IP,如果你是在公有云上部署这个并且你有一些公网IP,那么就可以直接通过公网IP来发布你的服务了

3.Ingress(推荐/重点)

ingress会根据用户的不同需求将流量转发到对应的服务上

使用ingress的话有3个步骤

  1. 配置反向代理
  2. 创建pod
  3. 创建svc

    操作开始

    我们现在开始配置反向代理,配置反向代理不要用nginx去手动配置,虽然行得通,但是很麻烦,我们直接使用ingress-nginx这个镜像
  1. kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml

如果网络不好的话这样操作

  1. # 在node1和node2上操作
  2. [root@node1 ~]# crictl pull registry.cn-hangzhou.aliyuncs.com/cloudcs/kube-webhook-certgen:v20220916-gd32f8c343
  3. [root@node1 ~]# crictl pull registry.cn-hangzhou.aliyuncs.com/cloudcs/controller:v1.6.4

然后将文件内容复制下来写到一个yaml文件里,需要改3个地方

  1. [root@master ingress]# grep image deploy.yaml
  2. # 这3个镜像的地方需要改,第2个和第3个使用的是同一个镜像
  3. image: registry.cn-hangzhou.aliyuncs.com/cloudcs/controller:v1.6.4
  4. imagePullPolicy: IfNotPresent
  5. image: registry.cn-hangzhou.aliyuncs.com/cloudcs/kube-webhook-certgen:v20220916-gd32f8c343
  6. imagePullPolicy: IfNotPresent
  7. image: registry.cn-hangzhou.aliyuncs.com/cloudcs/kube-webhook-certgen:v20220916-gd32f8c343
  8. imagePullPolicy: IfNotPresent

然后apply

  1. [root@master ingress]# kubectl get pods -n ingress-nginx
  2. NAME READY STATUS RESTARTS AGE
  3. ingress-nginx-admission-create-z27v4 0/1 Completed 0 5m44s
  4. ingress-nginx-admission-patch-fnx6b 0/1 Completed 0 5m44s
  5. ingress-nginx-controller-7ffff4c7dd-jps9m 1/1 Running 0 5m44s

他最后应该变成这样,2个完成,1个运行中

再查看一下svc

  1. [root@master ~]# kubectl get svc -n ingress-nginx
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. ingress-nginx-controller LoadBalancer 10.106.120.188 192.168.200.241 80:32558/TCP,443:32206/TCP 11h
  4. ingress-nginx-controller-admission ClusterIP 10.96.125.66 <none> 443/TCP 11h

这些东西都是为了反向代理做支撑的

然后我们还需要定义一个规则

  1. # 这个规则就是用户访问www.web1.com 的时候流量会走到pod01上,访问www.web2.com流量会到pod02上,www.web3.com则会到pod03
  2. apiVersion: networking.k8s.io/v1
  3. kind: Ingress
  4. metadata:
  5. name: ingress-wildcard-host
  6. spec:
  7. rules:
  8. - host: "www.web1.com"
  9. http:
  10. paths:
  11. - pathType: Prefix
  12. path: "/"
  13. backend:
  14. service:
  15. name: pod01
  16. port:
  17. number: 80
  18. - host: "www.web2.com"
  19. http:
  20. paths:
  21. - pathType: Prefix
  22. path: "/"
  23. backend:
  24. service:
  25. name: pod02
  26. port:
  27. number: 80
  28. - host: "www.web3.com"
  29. http:
  30. paths:
  31. - pathType: Prefix
  32. path: "/"
  33. backend:
  34. service:
  35. name: pod03
  36. port:
  37. number: 80

这个文件先别急着apply,还有一个操作

  1. # 修改ingress的默认class
  2. [root@master ~]# kubectl edit ingressclasses.networking.k8s.io
  3. apiVersion: networking.k8s.io/v1
  4. kind: IngressClass
  5. metadata:
  6. annotations:
  7. # 加上这一行,让他有一个默认类
  8. ingressclass.kubernetes.io/is-default-class: "true"
  9. kubectl.kubernetes.io/last-applied-configuration: |

然后我们开始创建pod

  1. # 创建3个pod,在ingress-nginx命名空间下,在哪都无所谓,我这里是在这个命名空间下的,只需要保证你的pod,svc和ingress在同一命名空间就行
  2. [root@master ~]# kubectl run pod01 --image nginx --image-pull-policy IfNotPresent --namespace ingress-nginx
  3. pod/pod01 created
  4. [root@master ~]# kubectl run pod02 --image nginx --image-pull-policy IfNotPresent --namespace ingress-nginx
  5. pod/pod02 created
  6. [root@master ~]# kubectl run pod03 --image nginx --image-pull-policy IfNotPresent --namespace ingress-nginx
  7. pod/pod03 created
  8. [root@master ~]# kubectl get pods -n ingress-nginx
  9. NAME READY STATUS RESTARTS AGE
  10. pod01 1/1 Running 0 21s
  11. pod02 1/1 Running 0 15s
  12. pod03 1/1 Running 0 11s
  13. # 然后进去pod修改index文件
  14. [root@master ~]# kubectl exec -it pods/pod01 -- bash
  15. root@pod01:/# echo 111 > /usr/share/nginx/html/index.html
  16. [root@master ~]# kubectl exec -it pods/pod02 -- bash
  17. root@pod01:/# echo 222 > /usr/share/nginx/html/index.html
  18. [root@master ~]# kubectl exec -it pods/pod03 -- bash
  19. root@pod01:/# echo 333 > /usr/share/nginx/html/index.html

然后我们去创建svc

  1. [root@master ~]# kubectl expose pods/pod01 --port 80 --target-port 80
  2. service/pod01 exposed
  3. [root@master ~]# kubectl expose pods/pod02 --port 80 --target-port 80
  4. service/pod02 exposed
  5. [root@master ~]# kubectl expose pods/pod03 --port 80 --target-port 80
  6. service/pod03 exposed

当在ingress-nginx命名空间下创建完pod和svc之后我们再去apply那个规则文件

  1. [root@master ~]# kubectl apply -f ingress.yaml
  2. # 然后我们来查看一下
  3. [root@master ingress]# kubectl describe ingress
  4. ……省略一些信息
  5. Rules:
  6. Host Path Backends
  7. ---- ---- --------
  8. www.web1.com
  9. / pod01:80 (10.244.104.40:80)
  10. www.web2.com
  11. / pod02:80 (10.244.104.19:80)
  12. www.web3.com
  13. / pod03:80 (10.244.166.145:80)
  14. Annotations: <none>
  15. Events:
  16. Type Reason Age From Message
  17. ---- ------ ---- ---- -------
  18. Normal Sync 26m (x2 over 27m) nginx-ingress-controller Scheduled for sync

这里我么可以看到 www.web1.com 他会转发到pod01上,那么没有问题

下面是验证环节,为了方便,我们直接在master节点上修改hosts文件

  1. # 先查询一下ingress的ip
  2. [root@master ingress]# kubectl get ingress
  3. NAME CLASS HOSTS ADDRESS PORTS AGE
  4. ingress-wildcard-host nginx www.web1.com,www.web2.com,www.web3.com 192.168.200.241 80 5m28s
  5. # 这里他的IP是192.168.200.241
  6. [root@master ~]# vim /etc/hosts
  7. 192.168.200.200 master
  8. 192.168.200.210 node1
  9. 192.168.200.220 node2
  10. 192.168.200.241 www.web1.com
  11. 192.168.200.241 www.web2.com
  12. 192.168.200.241 www.web3.com

好,我们来访问一下

  1. [root@master ingress]# curl www.web1.com
  2. 111
  3. [root@master ingress]# curl www.web2.com
  4. 222
  5. [root@master ingress]# curl www.web3.com
  6. 333

好的,我们的规则生效了,这个就是ingress发布,操作有点麻烦,但是可以对应不同的需求

这些就是服务的发布了,没有讲到ClusterIP,因为这个只能集群内部访问,上一节有提到过这个

SVC服务的发布的更多相关文章

  1. Thrift 个人实战--RPC服务的发布订阅实现(基于Zookeeper服务)

    前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ...

  2. ASP.NET 5系列教程 (四):向视图中添加服务和发布应用到公有云

    向视图中添加服务 现在,ASP.NET MVC 6 支持注入类到视图中,和VC类不同的是,对类是公开的.非嵌套或非抽象并没有限制.在这个例子中,我们创建了一个简单的类,用于统计代办事件.已完成事件和平 ...

  3. RPC服务的发布订阅实现Thrift

    Thrift 个人实战--RPC服务的发布订阅实现(基于Zookeeper服务) 前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的 ...

  4. JAVA版本微信管家平台—JeeWx 捷微 4.1 微服务版本发布,微信砍价活动闪亮登场!

    捷微 4.1   微服务版本发布,微信砍价活动闪亮登场 ^_^ JEEWX 从4.0版本开始,技术架构全新换代更名 “捷微H5”.这是一款开源免费的微信运营平台,是jeewx的新一代产品,平台涵盖了: ...

  5. 开源微信管家平台——JeeWx 捷微4.0 微服务版本发布,全新架构,全新UI,提供强大的图文编辑器

    JeeWx捷微4.0   微服务版本发布^_^ 换代产品(全新架构,全新UI,提供强大的图文编辑器) JEEWX 从4.0版本开始,技术架构全新换代,采用微服务架构,插件式开发,每个业务模块都是独立的 ...

  6. 使用thrift实现订阅服务和发布服务

    使用thrift实现订阅服务和发布服务 服务:订阅服务 market_subscriber 和 发布服务 market_publisher功能:market_subscriber 能够向 market ...

  7. 基于GeoServer切片地图服务的发布

    接着上一篇文章,如何将JPG格式的图片转化为带地理坐标的TIFF格式里提及的最近的一个项目,数据源是一张高分辨率的2.5维图片,现在已经成功转化成了带有地理坐标的TIFF格式.下面将介绍借助GeoSe ...

  8. (转)PostGIS+QGIS+GeoServer+OpenLayers实现数据的存储、服务的发布以及地图的显示

    http://blog.csdn.net/gisshixisheng/article/details/41575833 标题比较长,主要呢是实现以下几点: 1.将shp数据导入到PostGIS中: 2 ...

  9. cesium加载WFS服务(GeoServer发布)

    需求: 为了便于前端渲染数据,自定义图层渲染. 思路: 获取地图服务中的要素进行渲染. 工具: GeoServer 2.6.4,cesium, 思路有了就开始找资料写代码,cesium有接口可以加载W ...

  10. 通过Nginx、Consul、Upsync实现动态负载均衡和服务平滑发布

    前提 前段时间顺利地把整个服务集群和中间件全部从UCloud迁移到阿里云,笔者担任了架构和半个运维的角色.这里详细记录一下通过Nginx.Consul.Upsync实现动态负载均衡和服务平滑发布的核心 ...

随机推荐

  1. wxpython窗体之间传递参数

    如何界面存在frame1与frame2,通过frame1打开页面frame2,并将frame2的值传递给frame1 可以使用回调函数传值参考具体代码如下: # -*- coding: utf-8 - ...

  2. shell脚本(9)-流程控制for

    一.循环介绍 for循环叫做条件循环,或者for i in,可以通过for实现流程控制 二.for语法 1.for语法一:for in for var in value1 value2 ...... ...

  3. KVM 学习笔记:再谈虚拟化

    虚拟化是云计算的基石,抛开虚拟化谈云计算无异于缘木求鱼,不得要领. 虚拟化简介 虚拟化是一种技术,它是对物理硬件资源的虚拟.通过虚拟化使得应用运行在虚拟化之后的虚拟机上,达到充分利用物理资源的目的. ...

  4. Mysql 开启慢日志查询及查看慢日志 sql

    本文为博主原创,转载请注明出处: 目录:    1.Mysql 开启慢日志配置的查询    2. 通过sql 设置Mysql 的慢日志开启    3. 通过慢 sql 日志文件查看慢 sql  1.M ...

  5. Linux 安装 mysql 及配置存储位置

    本文为博主原创,未经允许不得转载: 新申请的服务器,需要确认服务器的磁盘是否进行了挂载,可参考这篇文章:https://www.cnblogs.com/zjdxr-up/p/14873242.html ...

  6. LLM面面观之Prefix LM vs Causal LM

    1. 背景 关于Prefix LM和Causal LM的区别,本qiang在网上逛了一翻,发现多数客官只给出了结论,但对于懵懵的本qiang,结果仍是懵懵... 因此,消遣了多半天,从原理及出处,交出 ...

  7. 【Mysql系列】(一)MySQL语句执行流程

    首发博客地址 首发博客地址 系列文章地址 参考文章 MySQL 逻辑架构 连接器 连接命令一般是这么写的 mysql -h$ip -P$port -u$user -p 那么 什么是连接器? MySQL ...

  8. [转帖]mysql - 使用文件中的 mysql 加载数据格式化 csv 日期列

    https://www.coder.work/article/2481907#:~:text=LOAD%20DATA%20INFILE%20%27%2Finvoices%2Finvoice138130 ...

  9. [转帖]TiDB Lightning 在数据迁移中的应用与错误处理实践

    TiDB Lightning 在数据迁移中的应用与错误处理实践 作者简介:DBA,会点 MySQL,懂点 TiDB,Python. 个人主页:https://tidb.net/u/seiang/ans ...

  10. [转帖]3.3.8. KWR运行期对比报告 KWR DIFF

    https://help.kingbase.com.cn/v8/perfor/performance-optimization/performance-optimization-6.html#sys- ...