五分钟k8s实战-使用Ingress

五分钟,k8s,实战,使用,ingress · 浏览次数 : 297

小编点评

**Ingress 概述** Ingress 是一个 Kubernetes 中用于将多个服务连接到外部网络的控制器。它可以从多个服务中接收请求,并将请求路由到指定的目的地。 **安装 Ingress 控制器** 官方提供的 Ingress-nginx 控制器是一个简单易用的工具,可以用于 Kubernetes 版本 1.16 及更高版本。安装过程如下: 1. 下载 Ingress-nginx 控制器的资源文件: ``` kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yamlyaml ``` 2. 将资源文件复制到 Kubernetes 集群中的 `ingress-nginx-controller-7cdfb9988c-lbcst` 文件中。 **使用 Ingress 创建资源** 使用 `apiVersion`、`kind` 和 `metadata` 等字段创建 Ingress 资源。例如,以下创建了一个名为 `k8s-combat-ingress` 的 Ingress: ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: k8s-combat-ingress labels: app: k8s-combat rules: - host: www.service1.io to: port: 80 - host: www.service2.io to: port: 80 ``` **查看 Ingress** 可以使用 `kubectl describe ingress k8s-combat-ingress` 命令查看 Ingress 的定义和规则。 **使用 Istio 与 Ingress 之间通信** 如果您使用 Istio,您可以使用 Istio 所提供的控制器替换 Ingress-nginx。这可以更方便地管理内外网流量。

正文

ingress.png

背景

前两章中我们将应用部署到了 k8s 中,同时不同的服务之间也可以通过 service 进行调用,现在还有一个步骤就是将我们的应用暴露到公网,并提供域名的访问。

这一步类似于我们以前配置 Nginx 和绑定域名,提供这个能力的服务在 k8s 中成为 Ingress。

通过这个描述其实也能看出 Ingress 是偏运维的工作,但也不妨碍我们作为研发去了解这部分的内容;了解整个系统是如何运转的也是研发应该掌握的技能。

安装 Ingress 控制器

在正式使用 Ingress 之前需要给 k8s 安装一个 Ingress 控制器,我们这里安装官方提供的 Ingress-nginx 控制器。

当然还有社区或者企业提供的各种控制器:
image.png

有两种安装方式: helm 或者是直接 apply 一个资源文件。

关于 helm 我们会在后面的章节单独讲解。

这里就直接使用资源文件安装即可,我已经上传到 GitHub 可以在这里访问:
https://github.com/crossoverJie/k8s-combat/blob/main/deployment/ingress-nginx.yaml

其实这个文件也是直接从官方提供的复制过来的,也可以直接使用这个路径进行安装:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml

yaml 文件的内容是一样的。

不过要注意安装之后可能容器状态一直处于 Pending 状态,查看容器的事件时会发现镜像拉取失败。

k describe pod ingress-nginx-controller-7cdfb9988c-lbcst -n ingress-nginx

describe 是一个用于查看 k8s 对象详细信息的命令。

在刚才那份 yaml 文件中可以看到有几个镜像需要拉取,我们可以先在本地手动拉取镜像:
image.png

docker pull registry.k8s.io/ingress-nginx/controller:v1.8.2

如果依然无法拉取,可以尝试配置几个国内镜像源镜像拉取:

image.png

我这里使用的 docker-desktop 自带的 k8s,推荐读者朋友也使用这个工具。

创建 Ingress

使用刚才的 yaml 安装成功之后会在 ingress-nginx 命名空间下创建一个 Pod,通过 get 命令查看状态为 Running 即为安装成功。

$ k get pod -n ingress-nginx
NAME                            READY   STATUS    RESTARTS      AGE
ingress-nginx-controller-7cdf   1/1     Running   2 (35h ago)   3d

Namespace 也是 k8s 内置的一个对象,可以简单理解为对资源进行分组管理,我们通常可以使用它来区分各个不同的环境,比如 dev/test/prod 等,不同命名空间下的资源不会互相干扰,且相互独立。

之后便可以创建 Ingress 资源了:

apiVersion: networking.k8s.io/v1  
kind: Ingress  
metadata:  
  name: k8s-combat-ingress  
spec:  
  ingressClassName: nginx  
  rules:  
    - host: www.service1.io  
      http:  
        paths:  
          - backend:  
              service:  
                name: k8s-combat-service  
                port:  
                  number: 8081  
            path: /  
            pathType: Prefix  
    - host: www.service2.io  
      http:  
        paths:  
          - backend:  
              service:  
                name: k8s-combat-service-2  
                port:  
                  number: 8081  
            path: /  
            pathType: Prefix

看这个内容也很容易理解,创建了一个 Ingress 的对象,其中的重点就是这里的规则是如何定义的。

在 k8s 中今后还会接触到各种不同的 Kind

这里的 ingressClassName: nginx 也是在刚开始安装的控制器里定义的名字,由这个资源定义。

apiVersion: networking.k8s.io/v1  
kind: IngressClass  
metadata:  
  labels:  
    app.kubernetes.io/component: controller  
    app.kubernetes.io/instance: ingress-nginx  
    app.kubernetes.io/name: ingress-nginx  
    app.kubernetes.io/part-of: ingress-nginx  
    app.kubernetes.io/version: 1.8.2  
  name: nginx

咱们这个规则很简单,就是将两个不同的域名路由到两个不同的 service。

这里为了方便测试又创建了一个 k8s-combat-service-2 的 service,和 k8s-combat-service 是一样的,只是改了个名字而已。

测试

也是为了方便测试,我在应用镜像中新增了一个接口,用于返回当前 Pod 的 hostname。

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {  
   name, _ := os.Hostname()  
   fmt.Fprint(w, name)  
})

由于我实际并没有 www.service1.io/www.service2.io 这两个域名,所以只能在本地配置 host 进行模拟。

10.0.0.37 www.service1.io
10.0.0.37 www.service2.io

我测试所使用的 k8s 部署在我家里一台限制的 Mac 上,所以这里的 IP 它的地址。

当我们反复请求两次这个接口,会拿到两个不同的 hostname,也就是将我们的请求轮训负载到了这两个 service 所代理的两个 Pod 中。

❯ curl http://www.service1.io/
k8s-combat-service-79c5579587-b6nlj%
❯ curl http://www.service1.io/
k8s-combat-service-79c5579587-bk7nw%
❯ curl http://www.service2.io/
k8s-combat-service-2-7bbf56b4d9-dkj9b%
❯ curl http://www.service2.io/
k8s-combat-service-2-7bbf56b4d9-t5l4g

我们也可以直接使用 describe 查看我们的 ingress 定义以及路由规则:
image.png

$ k describe ingress k8s-combat-ingress
Name:             k8s-combat-ingress
Labels:           <none>
Namespace:        default
Address:          localhost
Ingress Class:    nginx
Default backend:  <default>
Rules:
  Host             Path  Backends
  ----             ----  --------
  www.service1.io
                   /   k8s-combat-service:8081 (10.1.0.65:8081,10.1.0.67:8081)
  www.service2.io
                   /   k8s-combat-service-2:8081 (10.1.0.63:8081,10.1.0.64:8081)
Annotations:       <none>
Events:            <none>

如果我们手动新增一个域名解析:

10.0.0.37 www.service3.io
❯ curl http://www.service3.io/
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

会直接 404,这是因为没有找到这个域名的规则。

访问原理

image.png
整个的请求路径如上图所示,其实我们的 Ingress 本质上也是一个 service(所以它也可以启动多个副本来进行负载),只是他的类型是 LoadBalancer,通常这种类型的 service 会由云厂商绑定一个外部 IP,这样就可以通过这个外部 IP 访问 Ingress 了。

而我们应用的 service 是 ClusterIP,只能在应用内部访问

image.png

通过 service 的信息也可以看到,我们 ingress 的 service 绑定的外部 IP 是 localhost(本地的原因)

总结

Ingress 通常是充当网关的作用,后续我们在使用 Istio 时,也可以使用 Istio 所提供的控制器来替换掉 Ingress-nginx,可以更方便的管理内外网流量。

本文的所有源码在这里可以访问:
https://github.com/crossoverJie/k8s-combat

与五分钟k8s实战-使用Ingress相似的内容:

五分钟k8s实战-使用Ingress

背景 前两章中我们将应用部署到了 k8s 中,同时不同的服务之间也可以通过 service 进行调用,现在还有一个步骤就是将我们的应用暴露到公网,并提供域名的访问。 这一步类似于我们以前配置 Nginx 和绑定域名,提供这个能力的服务在 k8s 中成为 Ingress。 通过这个描述其实也能看出 I

五分钟k8s入门到实战-应用配置

背景 在前面三节中已经讲到如何将我们的应用部署到 k8s 集群并提供对外访问的能力,x现在可以满足基本的应用开发需求了。 现在我们需要更进一步,使用 k8s 提供的一些其他对象来标准化我的应用开发。 首先就是 ConfigMap,从它的名字也可以看出这是用于管理配置的对象。 ConfigMap 不管

五分钟 k8s入门到实战--跨服务调用

![service.png](https://s2.loli.net/2023/09/05/GbZ1vKQNHY32wzD.png) # 背景 在做传统业务开发的时候,当我们的服务提供方有多个实例时,往往我们需要将对方的服务列表保存在本地,然后采用一定的算法进行调用;当服务提供方的列表变化时还得及时

K8S 实用工具之五-kompose

开篇 📜 引言: 磨刀不误砍柴工 工欲善其事必先利其器 第一篇:《K8S 实用工具之一 - 如何合并多个 kubeconfig?》 第二篇:《K8S 实用工具之二 - 终端 UI K9S》 第三篇:《K8S 实用工具之三 - 图形化 UI Lens》 第四篇:《K8S 实用工具之四 - kubec

【Azure K8S】AKS升级 Kubernetes version 失败问题的分析与解决

问题描述 创建Azure Kubernetes Service服务后,需要升级AKS集群的 kubernetes version。在AKS页面的 Cluster configuration 页面中,选择新的版本 1.25.5,确认升级。等待50分钟左右,却等到了升级失败的消息: Failed to

五分钟教你使用GitHub寻找优质项目

前言 经常会有同学会问如何使用GitHub找到自己想要的项目,今天咱们就出一期快速入门教程五分钟教你使用GitHub寻找优质项目。GitHub作为世界上最大的项目开源平台之一,上面有着无数优质的开源项目。善于使用它能够让你获得很多意想不到的惊喜。 首先解决访问慢的问题 FastGithub是GitH

一分钟学会、三分钟上手、五分钟应用,快速上手责任链框架详解 | 京东云技术团队

责任链模式是开发过程中常用的一种设计模式,在SpringMVC、Netty等许多框架中均有实现。我们日常的开发中如果要使用责任链模式,通常需要自己来实现,但自己临时实现的责任链既不通用,也很容易产生框架与业务代码耦合不清的问题,增加Code Review 的成本。

[转帖]Linux实用技巧——find查找指定时间内修改过的文件或目录

https://cloud.tencent.com/developer/article/1694949 解决方案 例:查找出五分钟内修改过的文件 [root@mobius ~]$ find ./* -mmin -5 加上-mmin 参数即可, 其中后面的 -5 即表示五分钟内修改过的, 如果是+5

Ansible 学习笔记 - 批量巡检站点 URL 状态

前言 不拖泥带水,不东拉西扯。 速战速决,五分钟学到一个工作用得上的技巧。 通过一个个具体的实战案例,来生动演示 Ansible 的用法。 需求 我需要定期巡检或定时监控我公司的所有站点的首页的可用性状态。 Ansible Playbook 实战脚本 check_url_status.yml 如下:

用【游乐场】说清楚“硬件、操作系统、跨平台、应用软件、开发语言、代码”的关系

经常有小伙伴对一些计算机技术和概念不太清楚,产生很多误区,甚至张冠李戴,在一起聊天时又很难给对方解释清楚,经过苦思冥想,终于想到一些比喻,能够很好地阐述了“硬件、操作系统、跨平台、应用软件、开发语言、代码”之间的关系。 硬件 陆地(Intel)与海洋(AMD):硬件就像是一个广阔的自然环境,其中In