k8s笔记18--快速入门ingress和ingress controller

k8s笔记18--快速入门ingress和ingress controller

  • 1 介绍
  • 2 部署 ingress-nginx controller
  • 3 测试
  • 4 注意事项
  • 5 说明

1 介绍

Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。
下面是一个将所有流量都发送到同一 Service 的简单 Ingress 示例:
k8s笔记18--快速入门ingress和ingress controller_第1张图片
Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的 Service。

为了让 Ingress 资源工作,集群必须有一个正在运行的 Ingress 控制器。当controller运行后,每次新增一个 ingress 资源,都会在cotroller 的nginx 配置 nginx.conf 中新增记录,告诉nginx 将请求转发指定的服务中。
当前有很多中ingress controller, 很多云厂商也会定制 一些自己的控制器,本文基于最经典的 ingress-nginx controller 来做相关实验,具体包括部署controller、测试ingress 实例,以及解决常见注意事项。

2 部署 ingress-nginx controller

在 github.com/kubernetes/ingress-nginx/tree/main/deploy/static/provider/baremetal 中找到自己需要的版本,然后 kubectl apply 即可。

$ 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
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created

部署成功后,会拉起一个controller的pod和对应的 svc,如下所示:
xghome:~/.kube$ kubectl -n ingress-nginx get deploy,svc
NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ingress-nginx-controller   1/1     1            1           3h36m

NAME                                         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             NodePort    10.108.105.39   <none>        80:30080/TCP,443:30443/TCP   3h36m
service/ingress-nginx-controller-admission   ClusterIP   10.105.5.181    <none>        443/TCP                      3h36m

此外还会创建一个 IngressClass, 后续新建ingress 的时候需要指定 ingressClassName
xghome:~/.kube$ kubectl get IngressClass
NAME    CONTROLLER             PARAMETERS   AGE
nginx   k8s.io/ingress-nginx   <none>       3h51m

3 测试

  1. 准备一个基础镜像 py:hostname
    Dockerfile
    FROM python:3.8-slim
    RUN pip3 install Flask==2.1.2
    RUN mkdir -p /home
    WORKDIR /home
    USER nobody
    COPY app.py /home/
    CMD python3 -u app.py
    
    app.py
    from flask import Flask
    
    app = Flask(__name__)
    
    
    def get_hostname():
        hostname = ''
        with open('/etc/hostname', 'r') as f:
            line = f.readline()
            hostname = line.replace('\n', '')
        return hostname
    
    
    @app.route('/')
    @app.route('/')
    def hello_world(service=None):  # put application's code here
        hostname = get_hostname()
        if service is None:
            return f'Hello {hostname}\n'
        else:
            return f'Hello {hostname}, from {service}\n'
    
    
    if __name__ == '__main__':
        app.run(port=80, host="0.0.0.0")
    
    打包镜像
    docker build -t py:hostname .
    
  2. 部署服务test01 和 test02
    test01.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: test01
      name: test01
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: test01
      template:
        metadata:
          labels:
            app: test01
        spec:
          containers:
          - image: py:hostname
            name: test01
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: test01
      name: test01
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        app: test01
    
    test02.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: test02
      name: test02
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: test02
      template:
        metadata:
          labels:
            app: test02
        spec:
          containers:
          - image: py:hostname
            name: test02
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: test02
      name: test02
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        app: test02
    
  3. 部署 ingress
    test-ingress.yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: test
    spec:
      ingressClassName: nginx
      rules:
      - host: "test.xg.com"
        http:
          paths:
          - pathType: Prefix
            path: "/test01"
            backend:
              service:
                name: test01
                port:
                  number: 80
      - host: "test.xg.com"
        http:
          paths:
          - pathType: Prefix
            path: "/test02"
            backend:
              service:
                name: test02
                port:
                  number: 80
    
    k8s笔记18--快速入门ingress和ingress controller_第2张图片
  4. 前端测试
    如下图, test01 刚好进入到test01 的pod中,/test02 刚好进入到test02 的pod中,测试符合预期
    在这里插入图片描述
    注意:
    这里配置 nginx-ingress-controller 的 80端口为30080, 因此此处需要加上30080, 若在ingress controller 的外层加一个lb, 那么直接访问lb的ip即可。
    此时 test.xg.com 直接指向nginx controller的ip。若需要实现局域网|PC虚拟机之间的dns,可以参考ubuntu小技巧27–基于dnsmasq快速搭建局域网dns服务器

4 注意事项

  1. 笔者自己的服务器上没有专用的 lb, 因此直接将服务的域名指向 controller 的 ip; 实际项目中一般都会有专用 lb,lb 会对接到ingress controller 的多个节点,配置域名的时候直接指向 lb 的 ip 即可。

  2. 指定ingress | 设置默认ingress
    方法1:创建ingress的时候需要指定 spec.ingressClassName: nginx
    方法2: 配置默认ingress

     1)  在ingress-controller 中加参数 --watch-ingress-without-class=true
     2)  配置默认的 IngressClass, 在 annotations 中新增  ingressclass.kubernetes.io/is-default-class: "true"
    
  3. 解决无法拉国外镜像的问题

    若拉不下来,更改为阿里云的镜像即可(按需更改前缀即可,截至2023-08已经可以使用1.8.1了)
    registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.8.1
    registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v20230407
    

5 说明

软件环境:
ubuntu server 18.04
k8s 1.23.6
ingress controller v1.2.0
参考文档:
Kubernetes 文档/概念/服务、负载均衡和联网/Ingress
Kubernetes 文档/概念/服务、负载均衡和联网/Ingress控制器
ngress-nginx/master/deploy/static/mandatory.yaml
nginx-0.30.0/deploy/static/mandatory.yaml
github ingress
kubernetes 创建ingress不生效
ubuntu小技巧27–基于dnsmasq快速搭建局域网dns服务器

你可能感兴趣的:(K8S,&,Docker,nginx,kubernetes,ingress控制器,ingress-nginx)