1 使用Service访问集群内部存在的问题

Kubernetes 暴露服务的方式目前只有三种:LoadBlancer Service、ExternalName、NodePort Service、Ingress

将集群内服务提供外界访问就会产生以下几个问题:

1、Pod 漂移问题

  • 随着 Pod 的创建和销毁,Pod IP 肯定会动态变化;那么如何把这个动态的 Pod IP 暴露出去,可以通过NodePort
    Service解决

2、端口管理问题

  • 采用 NodePort 方式暴露服务面临问题是,服务一旦多起来,NodePort
    在每个节点上开启的端口会及其庞大,而且难以维护。由于Pod与Pod之间是可以互相通信的,而Pod是可以共享宿主机的网络名称空间的,也就是说当在共享网络名称空间时,Pod上所监听的就是Node上的端口。简单的实现就是使用
    DaemonSet 在每个 Node 上监听 80,然后写好规则,因为 Nginx 外面绑定了宿主机 80
    端口,本身又在集群内,那么向后直接转发到相应 Service IP 就行了

在这里插入图片描述
3、域名分配及动态更新问题

  • 采用 Nginx-Pod 其实有一个很大缺陷:当每次有新服务加入又该如何修改 Nginx
    配置呢;使用Nginx可以通过虚拟主机域名进行区分不同的服务,而每个服务通过upstream进行定义不同的负载均衡池,再加上location进行负载均衡的反向代理,在日常使用中只需要修改nginx.conf即可实现。

目前面临的问题:

(1)在K8S中如何实现这种方式的调度;

(2)假设后端的服务初始服务只有ecshop,后面增加了bbs和member服务,那么又该如何将这2个服务加入到Nginx-Pod进行调度
在这里插入图片描述

2 Ingress 的介绍

官网:https://kubernetes.github.io/ingress-nginx/

Kubernetes 里的Ingress 服务一种全局的、为了代理不同后端 Service 而设置的负载均衡服务

Ingress由两部分组成:Ingress controller和Ingress服务

Ingress Controller 会根据定义的 Ingress 对象,提供对应的代理能力。业界常用的各种反向代理项目,比如 Nginx、HAProxy、Envoy、Traefik 等,都已经为Kubernetes 专门维护了对应的 Ingress Controller。

Ingress 控制器不同于Deployment 控制器的是,Ingress控制器不直接运行为kube-controller-manager的一部分,它仅仅是Kubernetes集群的一个附件,类似于CoreDNS,需要在集群上单独部署

在这里插入图片描述

ngress资源时基于HTTP虚拟主机或URL的转发规则,需要强调的是,这是一条转发规则。它在资源配置清单中的spec字段中嵌套了rules、backend和tls等字段进行定义。Ingress 中的spec字段是Ingress资源的核心组成部分,主要包含以下3个字段:

  • rules:用于定义当前Ingress资源的转发规则列表;由rules定义规则,或没有匹配到规则时,所有的流量会转发到由backend定义的默认后端。

  • backend:默认的后端用于服务那些没有匹配到任何规则的请求;定义Ingress资源时,必须要定义backend或rules两者之一,该字段用于让负载均衡器指定一个全局默认的后端

  • tls:TLS配置,目前仅支持通过默认端口443提供服务,如果要配置指定的列表成员指向不同的主机,则需要通过SNITLS扩展机制来支持该功能。

  • backend对象的定义由2个必要的字段组成:serviceName和servicePort,分别用于指定流量转发的后端目标Service资源名称和端口

3 ngress-nginx的部署

(1)下载官方的ingress应用文件:

wget  https://raw.githubusercontent.com/kubernetes/ingress nginx/controller-v0.33.0/deploy/static/provider/baremetal/deploy.yaml

(2)修改ingress controller部署文件

用DaemonSet结合nodeselector来部署ingress-controller到特定的node上,然后使用HostNetwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/443端口就能访问服务。

  • 优点是整个请求链路最简单,性能相对NodePort模式更好。
  • 缺点是由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
(3)将镜像上传至harbor仓库
在这里插入图片描述

在这里插入图片描述

(4)创建服务和pod

  • 编辑清单资源文件:demo.yml
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v1
  • 应用文件:kubectl apply -f demo.yml
  • 应用deploy文件:kubectl apply -f deploy.yaml
  • 查看namespace的信息:kubectl get ns
  • 查看ingress-nginx命名空间的pod信息:kubectl -n ingress-nginx get pod -o wide

在这里插入图片描述

  • 查看服务的信息:kubectl get svc

在这里插入图片描述

  • 查看myservice 服务的信息:kubectl describe svc myservice

在这里插入图片描述

4 创建ingress服务

4.1 通过域名访问后端

(1)编辑资源清单文件:vim ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-demo
spec:
  rules:
 - host: www1.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: myservice
          servicePort: 80
  • 应用文件:kubectl apply -f ingress.yaml

在这里插入图片描述

(2)查看指定命名空间的pod信息:kubectl -n ingress-nginx get pod -o wide

在这里插入图片描述
(3)测试

  • 查看myservice 服务的详细信息:kubectl describe svc myservice

在这里插入图片描述

  • 编辑测试真机的dns解析文件

在这里插入图片描述

  • 在真机上测试:curl www1.westos.org/hostname.html

在这里插入图片描述

4.2 不同的域名访问不同的后端服务

(1)编辑资源清单文件:vim nginx-svc.yml

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: ClusterIP

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: myapp:v2
  • 应用文件:kubectl apply -f nginx-svc.yml
  • 查看服务信息:kubectl get svc

在这里插入图片描述

  • 查看nginx-svc 服务的信息:kubectl describe svc nginx-svc

在这里插入图片描述

  • 过滤app标签的pod:kubectl get pod -L app

在这里插入图片描述

(2)编辑ingress服务文件:vim ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-demo
spec:
  rules:
 - host: www1.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: myservice
          servicePort: 80
 - host: www2.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-svc
          servicePort: 80
  • 应用文件:kubectl apply -f ingress.yaml
  • 查看ingress的信息:kubectl get ingress

在这里插入图片描述
(3)测试:

  • 编辑测试真机的dns解析文件

在这里插入图片描述

  • 在真机上测试
[root@westos Desktop]# curl www2.westos.org
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@westos Desktop]# curl www1.westos.org/hostname.html
deployment-59dff4cf5d-h56kz
[root@westos Desktop]# curl www1.westos.org/hostname.html
deployment-59dff4cf5d-fnhhb
[root@westos Desktop]# curl www1.westos.org/hostname.html
deployment-59dff4cf5d-j7b7h
[root@westos Desktop]# curl www2.westos.org/hostname.html
demo-6d4f5bf58f-r49bq
[root@westos Desktop]# curl www2.westos.org/hostname.html
demo-6d4f5bf58f-ztt7j
[root@westos Desktop]# curl www2.westos.org/hostname.html
demo-6d4f5bf58f-djlnv

4.3 Ingress TLS 配置

参考官方的配置步骤:https://kubernetes.github.io/ingress-nginx/examples/PREREQUISITES/

(1)openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj “/CN=nginxsvc/O=nginxsvc”

(2)生成证书:kubectl create secret tls tls-secret --key tls.key --cert tls.crt
在这里插入图片描述

(3)修改并应用配置文件:kubectl apply -f ingress.yaml

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-demo
spec:
  tls:
    - hosts:
      - www1.westos.org
      secretName: tls-secret
  rules:
 - host: www1.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: myservice
          servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-demo1
spec:
  rules:
 - host: www2.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-svc
          servicePort: 80
  • 查看get ingress的信息:kubectl get ingress

在这里插入图片描述

[root@server2 ~]# kubectl describe ingress ingress-demo
Name:             ingress-demo
Namespace:        default
Address:          172.25.12.4
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
  tls-secret terminates www1.westos.org
Rules:
  Host             Path  Backends
  ----             ----  --------
  www1.westos.org  
                   /   myservice:80 (10.244.1.87:80,10.244.1.88:80,10.244.2.63:80)
Annotations:       <none>
Events:
  Type    Reason  Age                From                      Message
  ----    ------  ----               ----                      -------
  Normal  UPDATE  46s (x5 over 64m)  nginx-ingress-controller  Ingress default/ingress-demo
  • 查看指定的ingress-demo1信息:kubectl describe ingress ingress-demo1

在这里插入图片描述
测试:
在真机访问:

  • 将域名加入真机的dns解析文件

在这里插入图片描述

  • 访问被重定向:curl www1.westos.org -I
  • 可以访问:curl -k https://www1.westos.org/

在这里插入图片描述
在浏览器端访问

在这里插入图片描述

  • 访问 www1.westos.org时提示有风险,忽略风险后可以正常访问

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.4 Ingress 认证配置

(1)生成auth认证文件

  • 安装http-tools工具 yum install http-tools
htpasswd -c auth admin  ## 生成认证用户,第一次创建必须用-c
htpasswd  auth tom   ## 添加认证用户,如果用-c会覆盖已经存在的认证的用户

在这里插入图片描述

(2) 创建secret:

kubectl create secret generic basic-auth --from-file=auth
## secret名称: basic-auth
## generic通过auth文件创建
  • 查看 secrets 的信息:kubectl get secrets

在这里插入图片描述

  • 将secret的basic-auth输出为yaml格式:kubectl get secret basic-auth -o yaml

在这里插入图片描述
(3) 应用文件:kubectl apply -f ingress.yaml

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-demo
    annotations:  ## 添加annotations的信息
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth  ## secret的名字
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - admin'  ## 能通过认证的用户名
spec:
  tls:
    - hosts:
      - www1.westos.org
      secretName: tls-secret
  rules:
  - host: www1.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: myservice
          servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-demo1
spec:
  rules:
  - host: www2.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-svc
          servicePort: 80
  • 查看 ingress-demo的信息:kubectl describe ingress ingress-demo,添加认证生效

在这里插入图片描述
(4)测试:

在本机主机上www1.westos.org没有访问的权限
在这里插入图片描述

在浏览器页面访问:www1.westos.org,忽略风险提示后会弹出认证页面,输入正确的认证信息后可以正常的访问服务

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐