Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >k8s之HTTP请求负载分发

k8s之HTTP请求负载分发

作者头像
Liusy
发布于 2020-11-11 08:12:02
发布于 2020-11-11 08:12:02
87800
代码可运行
举报
文章被收录于专栏:Liusy01Liusy01
运行总次数:0
代码可运行

导读

对于基于HTTP的服务来说,不同的URL地址经常对应不同的后端服务或者虚拟服务器,通常的做法是在应用前添加一个反向代理服务器Nginx,进行请求的负载转发,在Spring Cloud这个微服务框架中,使用zuul网关实现此功能。

而对于k8s集群来说,当然也是可以用Nginx实现请求的转发,但对于一个成熟的容器编排工具,k8s内置了一个HTTP请求负载分发的组件,就是Ingress Controll。另外,k8s的Service也是具有负载均衡能力的组件。

用法

在定义Ingress之前,需要先部署Ingress Controller,以实现所有后端Service提供一个统一的入口。Ingress Controller需要实现基于不同Http URL向后转发的负载分发规则 。

在K8s中,Ingress Controller将以Pod的形式运行,监控apiserver的/ingress接口后端的backend services,如果service发生变化,则Ingress Controller应自动更新其转发规则。

1、创建Ingress Controller

其实Ingress底层就可以用Nginx实现,Ingress Controller会监听ApiServer,获取全部的Ingress定义,然后根据定义生成Nginx的配置文件。

下面使用nginx-ingress-controller镜像来创建Ingress Controller。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx-ingress
  namespace: ingress
  labels:
    app: nginx-ingress
spec:
  replicas: 1
  template:
    metadata:
      name: nginx-ingress
      labels:
        app: nginx-ingress
    spec:
      serviceAccountName: ingress-sc
      containers:
      - name: nginx-ingress
        image: imagia/nginx-ingress-controller:0.32.0
        imagePullPolicy: IfNotPresent
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        ports:
        - containerPort: 80
          hostPort: 80
        - containerPort: 443
          hostPort: 443

这里为Nginx容器设置了hostPort,将容器应用监听的80和443端口 号映射到物理机上,使得客户端应用可以通过URL地址“http://物理机 IP:80”或“https://物理机IP:443”来访问该Ingress Controller。这使得Nginx 类似于通过NodePort映射到物理机的Service,成为代替kube-proxy的 HTTP层的Load Balancer:

2、创建Ingress

下面的Ingress定义了将/user的请求转发至user-svc的Service上,将/order的请求转发至order-svc的Service上。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myweb-ingress
  namespace: ingress
spec:
  rules:
  - host: myweb.com
    http:
      paths:
      - path: /api/user
        backend:
          serviceName: user-svc
          servicePort: 8081
      - path: /api/order
        backend:
          serviceName: order-svc
          servicePort: 8082

Ingress的策略配置:

(1)所有请求都转发到单个Service上

此时不用配置rules

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
spec:
  backend:
    serviceName: user
    servicePort: 8080

(2)同一域名,不同url转发到不同的服务上

比如域名都是myweb.com,/api/user转发到user服务,/api/order转发到 order服务。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
spec:
  rules:
  - host: myweb.com
    http:
      paths:
      - path: /api/user
        backend:
          serviceName: user-svc
          servicePort: 8081
      - path: /api/order
        backend:
          serviceName: order-svc
          servicePort: 8082

(3)不同域名

域名为myweb1.com的请求转发到user服务,域名为myweb2.com的请求转发到order服务

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
spec:
  rules:
  - host: myweb1.com
    http:
      paths:
      - backend:
          serviceName: user-svc
          servicePort: 8081
  - host: myweb2.com
    http:
      paths:
      - backend:
          serviceName: order-svc
          servicePort: 8082

(4)不使用域名

这种配置用于一个网站不使用域名直接提供服务的场景,此时通过 任意一台运行ingress-controller的Node都能访问到后端的服务。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
spec:
  rules:
  - http:
      paths:
      - path: /api/user
        backend:
          serviceName: user-svc
          servicePort: 8081

【注】使用无域名的Ingress转发规则时,将默认禁用非安全 HTTP,强制启用HTTPS。

案例

一、简介

创建一个命名空间:ingress,启动两个服务,一个是user,一个是order,利用Ingress-controller将请求/api/user转发到user服务,将请求/api/order转发到order服务。

二、创建服务

(1)创建简单springboot应用

只有两个api接口,分别是/api/order和/api/user,然后打成jar包上传至服务器

(2)将上述jar包创建为镜像

将jar包、jdk安装包和Dockerfile放在同一个目录

Dockerfile文件内容如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
FROM centos:7

LABEL author=lsy

ENV path=/usr/soft

RUN mkdir ${path}

WORKDIR ${path}

ADD jdk-8u191-linux-x64.tar.gz ${path}

ENV JAVA_HOME=${path}/jdk1.8.0_191
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH=$JAVA_HOME/bin:$PATH

COPY service-1.0.jar ${path}

EXPOSE 8080

CMD  java -jar service-1.0.jar

使用命令创建镜像:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
docker build ./ -t  cnode-1:5000/ingress-service:v1.0

镜像创建完成后记得上传到docker私有仓库

(3)在ingress命名空间启动相应的ReplicationController和Service

user-rc.yaml

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: v1
kind: ReplicationController
metadata:
  name: user-rc
  namespace: ingress
  labels:
    name: user-rc
spec:
  replicas: 1
  selector:
    name: user-rc
  template:
    metadata:
      name: user-rc
      labels:
        name: user-rc
    spec:
      containers:
      - name: user-rc
        image: cnode-1:5000/ingress-service:v1.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

user-svc.yaml

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: v1
kind: Service
metadata:
  name: user-svc
  namespace: ingress
spec:
  selector:
    name: user-rc
  ports:
  - port: 8081
    targetPort: 8080

order-rc.yaml

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: v1
kind: ReplicationController
metadata:
  name: order-rc
  namespace: ingress
  labels:
    name: order-rc
spec:
  replicas: 1
  selector:
    name: order-rc
  template:
    metadata:
      name: order-rc
      labels:
        name: order-rc
    spec:
      containers:
      - name: order-rc
        image: cnode-1:5000/ingress-service:v1.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

order-svc.yaml

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: v1
kind: Service
metadata:
  name: order-svc
  namespace: ingress
spec:
  selector:
    name: order-rc
  ports:
  - port: 8082
    targetPort: 8080

分别使用kubectl create 命令创建上述资源

(4)在ingress命名空间中创建ServiceAccount

创建ServiceAccount和ClusterRoleBinding,如果不创建的话,Ingress-controller会使用默认名为default的ServiceAccount,default权限很弱,获取不到相应的资源信息,这样Ingress-controller会启动失败。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    name: ingress-sc
  name: ingress-sc
  namespace: ingress

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: ingress
  labels:
    name: ingress-crb
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: ingress-sc
  namespace: ingress

(5)创建Ingress Controller

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx-ingress
  namespace: ingress
  labels:
    app: nginx-ingress
spec:
  replicas: 1
  template:
    metadata:
      name: nginx-ingress
      labels:
        app: nginx-ingress
    spec:
      serviceAccountName: ingress-sc
      containers:
      - name: nginx-ingress
        image: imagia/nginx-ingress-controller:0.32.0
        imagePullPolicy: IfNotPresent
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        ports:
        - containerPort: 80
          hostPort: 80
        - containerPort: 443
          hostPort: 443

创建完后查看:

【注】环境变量POD_NAME和POD_NAMESPACE是必须要设置的,不然会报错。

(6)创建Ingress

也就是规则设置,将请求地址为/api/user转发至user服务,请求地址为/api/order的转发至order服务。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myweb-ingress
  namespace: ingress
spec:
  rules:
  - host: myweb.com
    http:
      paths:
      - path: /api/user
        backend:
          serviceName: user-svc
          servicePort: 8081
      - path: /api/order
        backend:
          serviceName: order-svc
          servicePort: 8082

创建完后查看:

可以看到,它的Hosts是myweb.com,物理机地址是192.168.197.120,端口为80.

如果ADDRESS列为空, 则通常说明Nginx未能正确连接到后端Service,需要排错。

【注】为什么只有一个ip,是因为这个RC只有一个Pod,调度到cnode-2这台机运行,如果想要每台机器都有一个,建议使用DaemonSet类型的Controller

此时查看ingress-controller的Pod的日志:

先获取Pod的名字

然后查看日志:

从上图可以看到,当ingress创建之后,ingress-controller会自动去加载,然后生成对应的nginx的conf文件。

进入容器查看nginx的配置文件:文件是/etc/nginx/nginx.conf

(7)测试效果

由于并没有上述设置的myweb.com这个域名,所以需要进行解析。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
curl --resolve myweb.com:80:192.168.197.120 http://myweb.com:80/api/order

访问order服务:

查看日志:可以看到是转发到order-svc这个Service上了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
192.168.197.100 - - [31/Oct/2020:07:40:46 +0000] "GET /api/order HTTP/1.1" 200 21 "-" "curl/7.29.0" 82 0.004 [ingress-order-svc-8082] [] 10.36.0.4:8080 21 0.004 200 0f7dfb1134644ee2ceb7a7d364ddfe45

访问user服务:

查看日志:可以看到是转发到user-svc这个Service上了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
192.168.197.100 - - [31/Oct/2020:07:42:16 +0000] "GET /api/user HTTP/1.1" 200 20 "-" "curl/7.29.0" 81 0.011 [ingress-user-svc-8081] [] 10.44.0.3:8080 20 0.010 200 46f66ab540c41590a74bbea66bd65ea8

结尾

秋风吹落叶,天气微凉,注意保暖!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Liusy01 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
ASP.NET Core on K8S深入学习(12)Ingress
本篇已加入《.NET Core on K8S学习实践系列文章索引》,可以点击查看更多容器化技术相关系列文章。
Edison Zhou
2020/05/11
1K0
ASP.NET Core on K8S深入学习(12)Ingress
《前端运维》五、k8s--2pod、services与Ingress部署
  前一篇啊,我们学完了基本的配置。这一篇,我们来看下服务部署的配置。我们先来看张图,理解下k8s的应用场景和调用流程:
zaking
2022/05/10
6500
《前端运维》五、k8s--2pod、services与Ingress部署
ASP.NET Core on K8S深入学习(14)Ingress灰度发布
本篇已加入《.NET Core on K8S学习实践系列文章索引》,可以点击查看更多容器化技术相关系列文章。
Edison Zhou
2020/05/25
6640
ASP.NET Core on K8S深入学习(14)Ingress灰度发布
027.掌握Service-Ingress使用
对于基于HTTP的服务来说,不同的URL地址经常对应到不同的后端服务(RS)或者虚拟服务器( Virtual Host),这些应用层的转发机制仅通过Kubernetes的Service机制是无法实现的。
木二
2020/03/19
1.5K0
K8S deployment可视化故障排查指南
假设您希望部署一个简单的Hello World应用程序,则该应用程序的YAML应该类似于以下内容:
有点技术
2020/07/13
2.6K0
K8S deployment可视化故障排查指南
深入玩转K8S之外网如何访问业务应用(nginx-ingress篇)
前面的文章介绍了如何安装kubernetes集群,集群部署完毕之后就可以在上面部署服务了。服务部署完之后如何访问集群中的服务呢?  访问部署在kubernetes中的服务有两种情况,一种是在kubernetes集群内部访问,另一种是在集群外部访问服务。
DevinGeng
2019/04/09
2.1K0
tke中如何通过clb类型ingress转发集群内和集群外服务
最近接到很多用户在将服务迁移到tke的时候遇到一个问题,那就是我的服务以前是部署在集群外的cvm上,但是现在我将一部分迁移到了tke,现在我需要用一个同一个的入口来提供访问。
聂伟星
2022/03/18
1.3K0
你知道K8S暴露服务的方式有哪些吗?
Kubernetes支持多种将外部流量引入集群的方法。ClusterIP、NodePort和Ingress是三种广泛使用的资源,它们都在路由流量中发挥作用。每一个都允许您使用一组独特的功能和折衷方案来公开服务。
KevinYan
2021/09/24
2.5K0
k8s loadbalancer与ingress实践
k8s可以通过三种方式将集群内服务暴露到外网,分别是NodePort、LoadBalancer、Ingress,其中NodePort作为基础通信形式我们在《k8s网络模型与集群通信》中进行了介绍,这里我们主要关注LoadBalancer和Ingress
你大哥
2022/01/10
1.7K0
k8s loadbalancer与ingress实践
「走进k8s」Kubernetes1.15.1的Ingress TLS 与 Traefik路径转发(36)
PS:上面就是traefik 和 path的使用方法,通过配置ingress 填写对应的规则就可以了,不是很复杂。也描述了traefik 关于https证书的使用。
IT架构圈
2019/09/12
1.2K0
「走进k8s」Kubernetes1.15.1的Ingress TLS 与 Traefik路径转发(36)
再战 k8s(15):Ingress和Ingress Controller
从前面的学习,我们可以了解到Kubernetes暴露服务的方式目前只有三种:LoadBlancer Service、ExternalName、NodePort Service、Ingress;而我们需要将集群内服务提供外界访问就会产生以下几个问题:
看、未来
2022/05/06
1.6K0
再战 k8s(15):Ingress和Ingress Controller
Kubernetes集群中使用ingress发布服务
当我们将kubernetes的应用部署完之后,就需要对外发布服务的访问地址。kubernetes 将服务发布到外部访问的方式主要有: LoadBlancer Service NodePort Service Ingress
星哥玩云
2022/07/13
5820
Kubernetes集群中使用ingress发布服务
超长可视化指南!你必须了解的K8s部署的debug思路
本周四晚上8:30,第二期k3s免费在线培训如约开播!本期课程将介绍k3s的核心架构,如高可用架构以及containerd。一起来进阶探索k3s吧!
CNCF
2020/02/24
1.7K0
K8s的Service详解
● 在kubernetes中,Pod是应用程序的载体,我们可以通过Pod的IP来访问应用程序,但是Pod的IP地址不是固定的,这就意味着不方便直接采用Pod的IP对服务进行访问。
大忽悠爱学习
2022/09/28
1.3K0
K8s的Service详解
在k8s中获取客户端真实IP实践
当需明确服务请求来源以满足业务需求时,则需后端服务能够准确获取请求客户端的真实源 IP。例如以下场景:
chen1900s
2022/07/17
7.1K0
如何在TKE集群玩转nginx-ingress
kubernetes Ingess 是有2部分组成,Ingress Controller 和Ingress服务组成,常用的Ingress Controller 是ingress-nginx,工作的原理是:
keepyan
2019/12/16
2.5K2
如何在TKE集群玩转nginx-ingress
mac 上学习k8s系列(7)basic auth
在mac 上学习k8s系列(2)安装ingress-nginx这一讲的基础上我们先启动一个service,里面仅仅包含一个简单的pod
golangLeetcode
2022/08/02
5110
kubernetes—Service介绍
在kubernetes中,pod是应用程序的载体,我们可以通过pod的ip来访问应用程序,但是pod的ip地址不是固定的,这也就意味着不方便直接采用pod的ip对服务进行访问。
Alone-林
2023/03/17
6490
kubernetes—Service介绍
附020.Nginx-ingress部署及使用
[root@master01 ingress]# git clone https://github.com/nginxinc/kubernetes-ingress/
木二
2020/06/04
1.2K0
08 . Kubernetes之 ingress及Ingress Controller
Ingress规则是很灵活的,可以根据不同域名,不同path转发请求到不同的service,并且支持https/http.
iginkgo18
2020/09/27
3.1K0
08 . Kubernetes之 ingress及Ingress Controller
推荐阅读
相关推荐
ASP.NET Core on K8S深入学习(12)Ingress
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文