当前位置: 首页 > news >正文

基础网络安全-K8S 配置Ingress-controller 通过HTTPS处理服务请求

一、前言

在K8S中可以通过service对外暴露服务,由service代表一组pod对外提供服务,同时也提供了通过Ingress-controller组件对外提供服务的方式,Ingress-controller类似于一个反向代理,前端向用户侧提供服务,后端将服务请求转发到每一个service上。而Ingress则在Ingress-controller的基础之上提供了一个用户配置规则的入口。K8S通过Ingress可以提供4层、7层的反向代理,同时具备了将服务绑定到证书上对外通过HTTPS提供安全服务的能力,本文主要记录通过Ingress提供HTTPS服务的配置。

二、组件与访问流程介绍

引入Ingress-controller后,如下图所示:

基础网络安全-K8S 配置Ingress-controller 通过HTTPS处理服务请求_ingress-nginx

1) Ingress-controller是以容器的方式部署在K8S集群中,ingress-controller底层是以nginx、lvs等方式实现的,目前多选用nginx。

2) Ingress是为用户提供配置规则的一个入口,ingress-controller可以将该配置文件中的规则转换为nginx的规则。

3) Service与未引入ingress-controller时一样,只不过作为ingress中配置的后端服务,而不直接对外提供服务。

4) Secret:与etcd类似,用于在K8S中存储配置相关的信息的,所不同的是secret主要存储一些敏感信息,在该架构中,我们将HTTPS证书存储于secret中,并且在ingress中调用相关的信息。

访问流程:

用户向ingress-controller发起https请求,ingress-controller进行HTTPS证书卸载,并将请求向后端的backend进行转发,转到到某一个service上。

三、配置Ingress-controller提供HTTPS服务

(1)  部署ingress-controller

通过yml文件部署,可以参考github的官方说明,网址: https://github.com/kubernetes/ingress-nginx,可以看到有相关的版本说明:

基础网络安全-K8S 配置Ingress-controller 通过HTTPS处理服务请求_k8s_02

不过由于我的k8s版本为1.16,已经比较老旧了,没有找到完整的yml文件,我从网上相关博客搜索,配合文心一言,组合了一份完整的ingress.yml文件。

[root@k8s-master1 ingress]# cat ingress.yml

apiVersion: v1

kind: Namespace

metadata:

  name: ingress-nginx

  labels:

    app.kubernetes.io/name: ingress-nginx

    app.kubernetes.io/part-of: ingress-nginx

kind: ConfigMap

apiVersion: v1

metadata:

  name: nginx-configuration

  namespace: ingress-nginx

  labels:

    app.kubernetes.io/name: ingress-nginx

    app.kubernetes.io/part-of: ingress-nginx

 

kind: ConfigMap

apiVersion: v1

metadata:

  name: tcp-services

  namespace: ingress-nginx

  labels:

    app.kubernetes.io/name: ingress-nginx

    app.kubernetes.io/part-of: ingress-nginx

 

---

kind: ConfigMap

apiVersion: v1

metadata:

  name: udp-services

  namespace: ingress-nginx

  labels:

    app.kubernetes.io/name: ingress-nginx

    app.kubernetes.io/part-of: ingress-nginx

apiVersion: v1

kind: ServiceAccount

metadata:

  name: nginx-ingress-serviceaccount

  namespace: ingress-nginx

  labels:

    app.kubernetes.io/name: ingress-nginx

    app.kubernetes.io/part-of: ingress-nginx

 

---

apiVersion: rbac.authorization.k8s.io/v1beta1

kind: ClusterRole

metadata:

  name: nginx-ingress-clusterrole

  labels:

    app.kubernetes.io/name: ingress-nginx

    app.kubernetes.io/part-of: ingress-nginx

rules:

  - apiGroups:

      - ""

    resources:

      - configmaps

      - endpoints

      - nodes

      - pods

      - secrets

    verbs:

      - list

      - watch

  - apiGroups:

      - ""

    resources:

      - nodes

    verbs:

      - get

  - apiGroups:

      - ""

    resources:

      - services

    verbs:

      - get

      - list

      - watch

  - apiGroups:

      - ""

    resources:

      - events

    verbs:

      - create

      - patch

  - apiGroups:

      - "extensions"

      - "networking.k8s.io"

    resources:

      - ingresses

    verbs:

      - get

      - list

      - watch

  - apiGroups:

      - "extensions"

      - "networking.k8s.io"

    resources:

      - ingresses/status

    verbs:

      - update

 

---

apiVersion: rbac.authorization.k8s.io/v1beta1

kind: Role

metadata:

  name: nginx-ingress-role

  namespace: ingress-nginx

  labels:

    app.kubernetes.io/name: ingress-nginx

    app.kubernetes.io/part-of: ingress-nginx

rules:

  - apiGroups:

      - ""

    resources:

      - configmaps

      - pods

      - secrets

      - namespaces

    verbs:

      - get

  - apiGroups:

      - ""

    resources:

      - configmaps

    resourceNames:

      # Defaults to "<election-id>-<ingress-class>"

      # Here: "<ingress-controller-leader>-<nginx>"

      # This has to be adapted if you change either parameter

      # when launching the nginx-ingress-controller.

      - "ingress-controller-leader-nginx"

    verbs:

      - get

      - update

  - apiGroups:

      - ""

    resources:

      - configmaps

    verbs:

      - create

  - apiGroups:

      - ""

    resources:

      - endpoints

    verbs:

      - get

 

---

apiVersion: rbac.authorization.k8s.io/v1beta1

kind: RoleBinding

metadata:

  name: nginx-ingress-role-nisa-binding

  namespace: ingress-nginx

  labels:

    app.kubernetes.io/name: ingress-nginx

    app.kubernetes.io/part-of: ingress-nginx

roleRef:

  apiGroup: rbac.authorization.k8s.io

  kind: Role

  name: nginx-ingress-role

subjects:

  - kind: ServiceAccount

    name: nginx-ingress-serviceaccount

    namespace: ingress-nginx

 

---

apiVersion: rbac.authorization.k8s.io/v1beta1

kind: ClusterRoleBinding

metadata:

  name: nginx-ingress-clusterrole-nisa-binding

  labels:

    app.kubernetes.io/name: ingress-nginx

    app.kubernetes.io/part-of: ingress-nginx

roleRef:

  apiGroup: rbac.authorization.k8s.io

  kind: ClusterRole

  name: nginx-ingress-clusterrole

subjects:

  - kind: ServiceAccount

    name: nginx-ingress-serviceaccount

    namespace: ingress-nginx

 

---

 

apiVersion: apps/v1

kind: Deployment

metadata:

  name: nginx-ingress-controller

  namespace: ingress-nginx

  labels:

    app.kubernetes.io/name: ingress-nginx

    app.kubernetes.io/part-of: ingress-nginx

spec:

  replicas: 1

  selector:

    matchLabels:

      app.kubernetes.io/name: ingress-nginx

      app.kubernetes.io/part-of: ingress-nginx

  template:

    metadata:

      labels:

        app.kubernetes.io/name: ingress-nginx

        app.kubernetes.io/part-of: ingress-nginx

      annotations:

        prometheus.io/port: "10254"

        prometheus.io/scrape: "true"

    spec:

      serviceAccountName: nginx-ingress-serviceaccount

      containers:

        - name: nginx-ingress-controller

          #image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.25.0

          image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.25.0

          args:

            - /nginx-ingress-controller

            - --configmap=$(POD_NAMESPACE)/nginx-configuration

            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services

            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services

            - --publish-service=$(POD_NAMESPACE)/ingress-nginx

            - --annotations-prefix=nginx.ingress.kubernetes.io

          securityContext:

            allowPrivilegeEscalation: true

            capabilities:

              drop:

                - ALL

              add:

                - NET_BIND_SERVICE

            # www-data -> 33

            runAsUser: 33

          env:

            - name: POD_NAME

              valueFrom:

                fieldRef:

                  fieldPath: metadata.name

            - name: POD_NAMESPACE

              valueFrom:

                fieldRef:

                  fieldPath: metadata.namespace

          ports:

            - name: http

              containerPort: 80

            - name: https

              containerPort: 443

          livenessProbe:

            failureThreshold: 3

            httpGet:

              path: /healthz

              port: 10254

              scheme: HTTP

            initialDelaySeconds: 10

            periodSeconds: 10

            successThreshold: 1

            timeoutSeconds: 10

          readinessProbe:

            failureThreshold: 3

            httpGet:

              path: /healthz

              port: 10254

              scheme: HTTP

            periodSeconds: 10

            successThreshold: 1

            timeoutSeconds: 10

 

---

 

apiVersion: v1 

kind: Service 

metadata: 

  name: ingress-nginx 

  namespace: ingress-nginx 

spec: 

  type: LoadBalancer

  # type: NodePort

  ports: 

    - name: http 

      port: 80 

      targetPort: 80 

      protocol: TCP 

    - name: https 

      port: 443 

      targetPort: 443 

      protocol: TCP 

  selector: 

    app.kubernetes.io/name: ingress-nginx 

    app.kubernetes.io/part-of: ingress-nginx

该文件中有几个关键的部分,包括namespace、configmap、serviceAccount、ClusterRole、Role、RoleBinding、ClusterRoleBing、Deployment、service。其中Deployment指定了nginx-ingress-controller镜像,用于将nginx-ingress-controller pod拉起,service则是用于将controller暴露出来。

执行kubectl create -f ingress.yml命令,可以看到相关的资源被创建,查看pod以及service的情况:

基础网络安全-K8S 配置Ingress-controller 通过HTTPS处理服务请求_ingress-controller_03

看一下nginx-ingress-controller的详细情况:kubectl describe pod nginx-ingress-controller-74879f74c6-cgrn2 -n ingress-nginx

基础网络安全-K8S 配置Ingress-controller 通过HTTPS处理服务请求_ingress_04

可以看到该pod运行在k8s-worker2上面。

注意:上面创建ingress-controller的过程中,其Pod,Service均在ingress-nginx namespace中。

(2)  创建HTTPS需要使用的证书

证书需要与域名绑定,假设域名为 www.mytest.com,使用Openssl生成证书:

# openssl genrsa -out server.key

# openssl req -new -x509 -key server.key -out server.crt -subj "/O=www.mytest.com,/CN=www.mytest.com"

此时已经生成了server.crt以及server.key两个文件。

(3)  将证书写入secret中

[root@k8s-master1 test]# kubectl create secret tls ingress-nginx-secret --key=server.key --cert=server.crt

基础网络安全-K8S 配置Ingress-controller 通过HTTPS处理服务请求_https_05

 (4)  创建后端的nginx服务

kubectl create deployment web --image=nginx:1.8

基础网络安全-K8S 配置Ingress-controller 通过HTTPS处理服务请求_https_06

(5)  创建提供nginx pod服务的service

kubectl expose deployment web --port=80 --target-port=80 --type=NodePort

基础网络安全-K8S 配置Ingress-controller 通过HTTPS处理服务请求_ingress-nginx_07

配置步骤四、五后可以通过 http://192.168.2.153:31111/访问到nginx服务了,下一步配置ingress规则,通过ingress-controller提供服务,并且启用HTTPS。

(6)  创建ingress规则

编写Ingress的资源清单,mytest-ingress01.yaml

[root@k8s-master1 BrowerCert]# cat mytest-ingress01.yaml

apiVersion: networking.k8s.io/v1beta1

kind: Ingress

metadata:

  name: mytest-https

 # namespace: ingress-nginx

spec:

  tls:

  - hosts:

    - www.mytest.com

    secretName: ingress-nginx-secret

  rules:

  - host: www.mytest.com

    http:

      paths:

      - path: /

        # pathType: Prefix

        backend:

          serviceName: web

          servicePort: 80

资源清单中hosts:www.mytest.com为域名,secretName为保存在secret中的证书的名称,serviceName及servicePort为第五步创建的服务名称与80端口。

kubectl apply -f mytest-ingress01.yaml

基础网络安全-K8S 配置Ingress-controller 通过HTTPS处理服务请求_ingress-nginx_08

 (7)  测试

查看ingress-controller情况:

基础网络安全-K8S 配置Ingress-controller 通过HTTPS处理服务请求_k8s_09

在windows的hosts中配置域名:

192.168.2.154 

浏览器中测试:

基础网络安全-K8S 配置Ingress-controller 通过HTTPS处理服务请求_k8s_10

 四、问题排查

1) 最开始的时候访问,通过kubectl logs -f -n ingress-nginx nginx-ingress-controller-74879f74c6-cgrn2命令查看ingress-controller日志,提示找不到err services "ingress-nginx" not found。该问题研究了很久,后来发现ingress.yml文件中没有service资源清单,补充后未再报该错误,完整资源清单见第一步。

kubectl logs -f -n ingress-nginx nginx-ingress-controller-74879f74c6-cgrn2查看实时日志,当Namespace不对,日志中报错,找不到相应的key或者service:

基础网络安全-K8S 配置Ingress-controller 通过HTTPS处理服务请求_https_11

调整namespace后,在kubectl apply -f mytest-ingress01.yaml的时候可以看到后端服务向controller注册成功:

基础网络安全-K8S 配置Ingress-controller 通过HTTPS处理服务请求_ingress-controller_12

2) nginx-ingress 报错 503 Service Temporarily Unavailable。要注意service、pod、ingress需要在相同的namespace中,本文是default;ingress-controller及其service是可以在其他namespace,本文是ingress-nginx。

五、总结

本文是基于k8s v1.16测试的ingress功能,配置了HTTPS对外提供服务。Ingress-controller可以主要用于负载均衡、反向代理,然而个人理解实际上是不适合配置HTTPS对外提供服务的,因为在实际的网络中,一定会部署IPS及WAF进行应用安全防护,因此需要在网络中对从用户发起的HTTPS请求进行SSL卸载转换为HTTP请求,然后才经过IPS/WAF的安全防护,否则设备可能不能识别流量中的异常行为。本文主要是熟悉在K8S中ingress-controller的功能,帮助在工作中遇到K8S进行安全评估。

 

最后我也整理了一些网络安全(黑客)方面的学习进阶资料

如果你想跟同道中人交流

相关文章:

  • GB8599-2023标准测试包/小规格测试包/标准生物测试包1.5kg/满负载织物7.5kg/不锈钢金属测试包/空腔负载试验的过程挑战装置(PCD)
  • Linux网络编程之——网络初认识
  • 启智畅想的集装箱号码识别技术,效率与技术的完美结合
  • [杂学笔记] TCP和UDP的区别,对http接口解释 , Cookie和Session的区别 ,http和https的区别 , 智能指针 ,断点续传
  • AF3 shaped_categorical函数解读
  • 大数据hadoop课程笔记
  • HTTPS协议原理:在Linux世界里的加密冒险
  • Jupyter Notebook 全平台安装与配置教程(附Python/Anaconda双方案)
  • Spring(3)—— 获取http头部信息
  • 如何创建一个Vue项目
  • 在Visual Studio 2022中实现Qt插件开发
  • 低版本 Linux 系统通过二进制方式升级部署高版本 Docker
  • Win7 火狐浏览器 Mozilla Firefox 115.7.0esr下载地址(及Chrome、Supermium浏览器)
  • Session、Cookie、Token的区别
  • OceanBase社区年度之星专访:张稚京与OB社区的双向奔赴
  • 算法手记1
  • 基于Java的面向对象的多态示例
  • Maven指定JDK
  • function call为大模型装上触手
  • Java中的分布式锁:原理、实现与最佳实践
  • 牛市早报|金融政策支持稳市场稳预期发布会将举行,商务部:中方决定同意与美方进行接触
  • 欧盟官员:欧盟酝酿对美关税政策反制措施,包含所有选项
  • 言短意长|党政主官如何塑造流量城市?
  • 许昌市场监管部门对胖东来玉石开展日常检查:平均毛利率不超20%
  • 国产基因测序仪龙头华大智造业绩持续承压,今年有望迎来拐点?
  • 特朗普:对所有在国外制作进入美国的电影征收100%关税