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
相关推荐
Cloud Traveler2 小时前
Kubernetes vs. OpenShift:深入比较与架构解析
架构·kubernetes·openshift
杰克逊的日记4 小时前
大规模k8s集群怎么规划
云原生·容器·kubernetes
luck_me54 小时前
K8S已经成为了Ai应用运行的平台工具
人工智能·容器·kubernetes
matrixlzp5 小时前
K8S Ingress、IngressController 快速开始
云原生·容器·kubernetes
探索云原生6 小时前
一文搞懂 GPU 共享方案: NVIDIA Time Slicing
ai·云原生·kubernetes·gpu
格桑阿sir11 小时前
Kubernetes控制平面组件:Kubelet 之 Static 静态 Pod
kubernetes·k8s·kubelet·static pod·静态pod·mirror pod·镜像pod
alden_ygq1 天前
Kubernetes生产实战(十九):镜像拉取失败排查处理
云原生·容器·kubernetes
alden_ygq1 天前
Kubernetes排错(十四):Pod状态异常排查手册
云原生·容器·kubernetes
hie988941 天前
k8s存储类型:emptyDir、hostPath、nfs、pvc及存储类storageclass的静态/动态创建pv
云原生·容器·kubernetes
alden_ygq1 天前
Kubernetes生产实战(十四):Secret高级使用模式与安全实践指南
java·安全·kubernetes