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
相关推荐
petaexpress8 小时前
k8s微服务架构就是云原生吗?两者是什么关系
微服务·云原生·架构·kubernetes·k8s
wenyue112120 小时前
Enhancing K8s Gateway API with Easegress Without Changing a Single Line of Code
容器·kubernetes·gateway
sxy1993sxy20181 天前
k8s rainbond centos7/win10 -20241124
云原生·容器·kubernetes
Python私教1 天前
Python 使用 Token 认证方案连接 Kubernetes (k8s) 的详细过程
开发语言·python·kubernetes
风霜不见闲沉月1 天前
k8s网络服务
linux·容器·kubernetes
夏沫的梦2 天前
kubernetes起源与介绍
kubernetes
胡八一2 天前
解决k8s拉取私有镜像401 Unauthorized 问题
云原生·容器·kubernetes
筑梦之路2 天前
银河麒麟v10 x86架构二进制方式kubeadm+docker+cri-docker搭建k8s集群(证书有效期100年) —— 筑梦之路
docker·容器·kubernetes
it噩梦2 天前
使用EFK收集k8s日志
容器·kubernetes
条纹布鲁斯3 天前
dockerdsktop修改安装路径/k8s部署wordpress和ubuntu
docker·kubernetes