4. k8s Ingress

0. 简介

前面我们介绍过k8s Service,Service 虽然可以对外暴露服务,比如 NodePort 类型,但是每个服务都会占用一个机器端口,这在服务数量增多后是不可接受的。因此,k8s 设计了 Ingress 用于将内部服务暴露到外部。Ingress 工作在 OSI模型的第七层。

后续 k8s 基于实际现状和需求,提出了 Gateway API 作为 Ingress 的继任者。

Ingress

Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。

Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。

Ingress 目前已停止更新。新的功能正在集成至网关 API 中。

Ingress 控制器

为了让 Ingress 资源工作,集群必须有一个正在运行的 Ingress 控制器。

Kubernetes 作为一个项目,目前支持和维护 AWSGCENginx Ingress 控制器。

这里需要注意的是:

  • ingress-nginx 是由Kubernetes社区基于Nginx Web服务器开发的,并补充了一组用于实现额外功能的Lua插件,作为"官方"默认控制器支持当然最优。
  • nginx-ingress 是 Nginx 官方社区开发产品,Nginx ingress 具有很高的稳定性,持续的向后兼容性,没有任何第三方模块,并且由于消除了 Lua 代码而保证了较高的速度。

1. Kind 部署 Ingress

1.1 部署 ingress-nginx controller

可以参考kind/ingress,下载:

bash 复制代码
~ wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
--2023-12-19 20:28:52--  https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
正在解析主机 raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.108.133, 185.199.110.133, ...
正在连接 raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:16613 (16K) [text/plain]
正在保存至: "deploy.yaml"

deploy.yaml                                                 100%[=========================================================================================================================================>]  16.22K  --.-KB/s  用时 0.007s

2023-12-19 20:28:53 (2.13 MB/s) - 已保存 "deploy.yaml" [16613/16613])

然后应用:

bash 复制代码
~ kubectl apply -f deploy.yaml
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
service/ingress-nginx-controller-admission created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
networkpolicy.networking.k8s.io/ingress-nginx-admission created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
arduino 复制代码
kubectl get pods --namespace ingress-nginx

这个时候会发现 ingress-nginx-controller 一直处于Pending状态,describe 后发现是 node 的 label 设置不准确,原因是我们没有按照指示文档设置 node 的label,如下:

yaml 复制代码
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  kubeadmConfigPatches:
  - |
    kind: InitConfiguration
    nodeRegistration:
      kubeletExtraArgs:
        node-labels: "ingress-ready=true"
  extraPortMappings:
  - containerPort: 80
    hostPort: 80
    protocol: TCP
  - containerPort: 443
    hostPort: 443
    protocol: TCP
- role: worker
- role: worker
- role: worker

然后我们就得重新创建一遍 kind,并且执行以上的命令,最后可以看到 controller 在运行状态:

bash 复制代码
  kubectl get pod --namespace ingress-nginx -o wide
NAME                                       READY   STATUS      RESTARTS   AGE   IP           NODE                  NOMINATED NODE   READINESS GATES
ingress-nginx-admission-create-lwqr8       0/1     Completed   0          18m   10.244.1.2   multi-worker          <none>           <none>
ingress-nginx-admission-patch-nn7r8        0/1     Completed   2          18m   10.244.3.2   multi-worker3         <none>           <none>
ingress-nginx-controller-d9b6d7bf5-p6dsq   1/1     Running     0          18m   10.244.0.5   multi-control-plane   <none>           <none>

1.2 创建 Ingress

创建服务

3. k8s Service中类似,我们创建两个 ClusterIP 类型的服务及其 Deployment:

yaml 复制代码
# custom
kind: Deployment
apiVersion: apps/v1
metadata:
  name: custom
spec:
  selector:
    matchLabels:
      app: custom
  replicas: 2
  template:
    metadata:
      labels:
        app: custom
    spec:
      containers:
      - name: custom
        image: k8s_service
        imagePullPolicy: Never

---
apiVersion: v1
kind: Service
metadata:
  name: custom
spec:
  ports:
  - name: http
    port: 9090 # image默认输出5678
    targetPort: 9090
  selector:
    app: custom

# echo
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: http-echo
spec:
  selector:
    matchLabels:
      app: echo
  replicas: 2
  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
      - name: http-echo
        image: hashicorp/http-echo:latest
        args:
        - "-listen=:9090"
---
apiVersion: v1
kind: Service
metadata:
  name: echo
spec:
  ports:
  - name: http
    port: 9090 # image默认输出5678
    targetPort: 9090
  selector:
    app: echo

然后 kubectl apply -f执行文件即可,可以发现:

bash 复制代码
~ kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
custom-5c5c478dcb-pbmqc      1/1     Running   0          2m19s
custom-5c5c478dcb-w4z6q      1/1     Running   0          2m19s
http-echo-5b5cff99fc-2cs8z   1/1     Running   0          2m19s
http-echo-5b5cff99fc-54x6n   1/1     Running   0          2m19s

~ kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
custom       ClusterIP   10.96.40.245   <none>        9090/TCP   2m39s
echo         ClusterIP   10.96.250.90   <none>        9090/TCP   2m39s
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP    14h

创建 Ingress

以上实现的是两个 ClusterIP 的服务,我们在集群外部无法访问,需要创建 Ingress,首先创建ingress.yaml

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  rules:
  - host: iguochan.org
    http:
      paths:
      - pathType: Prefix
        path: "/custom"
        backend:
          service:
            name: custom
            port:
              number: 9090
      - pathType: Prefix
        path: "/echo"
        backend:
          service:
            name: echo
            port:
              number: 9090

在 rules 中,我们通过路径来路由到指定的 Service,比如 /custom 路由到 custom 的 Service,而 \echo 路由到 echo 的 Service。

同时设定了一个 iguochan.org 的 host,所以我们需要到/etc/hosts 文件中添加下面一条:

bash 复制代码
127.0.0.1 iguochan.org

然后运行:

bash 复制代码
~ kubectl apply -f ingress.yaml

~ kubectl get ingress
NAME            CLASS    HOSTS          ADDRESS     PORTS   AGE
nginx-ingress   <none>   iguochan.org   localhost   80      21m

这时候可以看一下 ingress 的描述:

bash 复制代码
~ kubectl describe ingress nginx-ingress
Name:             nginx-ingress
Labels:           <none>
Namespace:        default
Address:          localhost
Ingress Class:    <none>
Default backend:  <default>
Rules:
  Host          Path  Backends
  ----          ----  --------
  iguochan.org
                /custom   custom:9090 (10.244.2.6:9090,10.244.3.7:9090)
                /echo     echo:9090 (10.244.1.7:9090,10.244.2.7:9090)
Annotations:    <none>
Events:
  Type    Reason  Age                From                      Message
  ----    ------  ----               ----                      -------
  Normal  Sync    34m (x2 over 34m)  nginx-ingress-controller  Scheduled for sync

即发现已经通过路径和不同的 Service 绑定,并且标注了 Service 对应的 Pod 的 ip:port

最后我们可以验证:

bash 复制代码
~ curl iguochan.org/custom
hello, I am custom-5c5c478dcb-pbmqc!
~ curl iguochan.org/custom
hello, I am custom-5c5c478dcb-w4z6q!
~ curl iguochan.org/echo
hello-world
相关推荐
moton20171 小时前
云原生:构建现代化应用的基石
后端·docker·微服务·云原生·容器·架构·kubernetes
xiao-xiang3 小时前
jenkins-k8s pod方式动态生成slave节点
java·kubernetes·jenkins
QQ_7781329746 小时前
在K8S中使用Values文件定制不同环境下的应用配置详解
kubernetes
元气满满的热码式21 小时前
K8S中Service详解(三)
云原生·容器·kubernetes
周杰伦_Jay1 天前
详细介绍:Kubernetes(K8s)的技术架构(核心概念、调度和资源管理、安全性、持续集成与持续部署、网络和服务发现)
网络·ci/cd·架构·kubernetes·服务发现·ai编程
周杰伦_Jay1 天前
详细介绍:云原生技术细节(关键组成部分、优势和挑战、常用云原生工具)
java·云原生·容器·架构·kubernetes·jenkins·devops
元气满满的热码式1 天前
K8S中Pod控制器之DaemonSet(DS)控制器
云原生·容器·kubernetes
夏子曦1 天前
k8s 蓝绿发布、滚动发布、灰度发布
云原生·容器·kubernetes
颜淡慕潇1 天前
【K8S系列】在 K8S 中使用 Values 文件定制不同环境下的应用配置
云原生·容器·kubernetes·环境配置
旦沐已成舟1 天前
K8S-Pod的环境变量,重启策略,数据持久化,资源限制
java·docker·kubernetes