十、Ingress从外部访问的最佳方式

概述

客户使用https进行访问,域名会被解析为IP,而这个IP是你调度器的IP地址,
但是客户连接的后端节点真实服务器,如果你认为集群足够安全那么在调度器可以卸载ssl,客户和调度器之间使用https,而调度器和后端节点使用http,
但是service的NodePort是基于iptables或者ipvs的4层调度转发,不支持ssl卸载,那么就需要在每一个提供服务的节点配置https的sll证书,如果是k8s集群那么就是每个pod,

注:service的NodePort前端加lb还只能加4层lb,因为如果7+4的话7层卸载sll证书那么4层lb不支持http,只支持tcp后者udp根据ip和端口进行分发,4层调度无法携带证书
所有的前提是你的应用是http服务想提升为https

Ingress彻底帮我们解决了 ingress是7层,那么4层转发至7层卸载ssl,pod就可以不用ssl直接http,那么签发可信的证书直接放置7层,只需一套证书就可以搞定

1.POD与Ingress的关系

• 通过Service相关联 
• 通过Ingress Controller实现Pod的负载均衡 
- 支持TCP/UDP 4层和HTTP 7层

2.Ingress Controller

部署文档:https://github.com/kubernetes/ingress-nginx/blob/master/docs/deploy/index.md
官网:https://kubernetes.io/docs/concepts/services-networking/ingress/
部署ingress-controller
[root@k8s-master~]#wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
如果镜像拉去不成功那么
修改yaml
镜像地址修改成国内的:k8s/nginx-ingress-controller:0.20.0 
    spec:
      serviceAccountName: nginx-ingress-serviceaccount
      hostNetwork: true              #使用宿主机网络
      containers:
        - name: nginx-ingress-controller
          image: k8s/nginx-ingress-controller:0.20.0
          args:

在这里插入图片描述

因为设置了hostNetwork: true 所以ingress-nginx<service>这个环节可以省略,
直接让ingress-nginx<ingress controller>使用宿主机网络

3 关于ingress-controller的方案

方案1:让ingress-controller使用DaemonSet给每一个node节点来一个,但是当集群范围过大的情况下,
每一个node节点来一个不太现实,影响效率,那么我们可以分几个节点出来专门跑ingress-controller,实现方法有2个
(1)使用nodeSelector,来匹配固定node节点
(2)给node节点打污点然后污点匹配来实现,如果集群够大的情况下使用这种方法可以让几台节点只运行ingress-controller为集群接入流量
方案2:通过HA给node节点高可用来实现,node节点使用keepalived来做vip的漂移,直接访问vip来访问,
[root@k8s-master ~]# docker image  load  < nginx-ingress-controller.tar 
[root@k8s-master ~]# kubectl apply  -f mandatory.yaml 

配置ingress规则

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: blog.sancheng.com              #ingress的名字  下面也可以加命名空间
  namespace:default
spec:
  tls:                            #证书相关
  - hosts:
    - blog.ctnrs.com          #域名
    secretName: blog-sancheng-com      #secret的名字
  rules:                           #规则
  - host: blog.sancheng.com            #你web网站的域名
    http:
      paths:
      - backend:                  #指定后端pod
          serviceName: nginx       #service的名字
          servicePort: 80           #service的端口(ClusterIP端口)


基于虚拟主机
  rules:
  - host: blog.sancheng.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx
          servicePort: 80
  - host: www.test.com
    http:
      paths:
      - path: /
        backend:
          serviceName: tomcat
          servicePort: 8080

基于多url的ingress配置配置annotaions的网址:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: blog.ctnrs.com
  namespace: default
  annotations:
    kubernets.io/ingress.class: "nginx"
    kubernets.io/tls-acme: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: 50m
    nginx.ingress.kubernetes.io/configuration-snippet: |
      rewrite /nginx(.*) /$1 break;           #根据url设置有多少设置多少
spec:
  tls:
  - hosts:
    - blog.ctnrs.com
    secretName: blog-ctnrs-com
  rules:
  - host: blog.ctnrs.com
    http:
      paths:
      - path: /nginx
        backend:
          serviceName: nginx
          servicePort: 80
      - path: /
        backend:
          serviceName: tomcat 
          servicePort: 8080

3.Ingress(HTTP与HTTPS)

证书的类型(crt、key)

(1)自签 openssl、cfssl,内部使用可以对外提供服务的话,虽然可以https但是会提示不可信任,自签的都是不可信任的
(2)阿里云、腾讯云等等购买

安装工具

[root@k8s-master ~]# wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
[root@k8s-master~]#wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 [root@k8s-master ~]# wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
[root@k8s-master ~]# cp cfssl_linux-amd64 /usr/local/bin/cfssl 
[root@k8s-master ~]# cp cfssljson_linux-amd64 /usr/local/bin/cfssljson
[root@k8s-master ~]#cp cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo
[root@k8s-master ~]# chmod  +x /usr/local/bin/cfssl*
创建证书(脚本)
[root@k8s-master ~]# sh certs.sh 
cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
         "expiry": "87600h",
         "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ]
      }
    }
  }
}
EOF

cat > ca-csr.json <<EOF
{
    "CN": "kubernetes",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Beijing",
            "ST": "Beijing"
        }
    ]
}
EOF

cfssl gencert -initca ca-csr.json | cfssljson -bare ca -

cat > blog.ctnrs.com-csr.json <<EOF
{
  "CN": "blog.ctnrs.com",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing"
    }
  ]
}
EOF

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes blog.ctnrs.com-csr.json | cfssljson -bare blog.ctnrs.com 
将证书内容保存至k8s中
[root@k8s-master ssl]# kubectl create secret tls blog-ctnrs-com --cert=blog.ctnrs.com.pem --key=blog.ctnrs.com-key.pem
创建ingress的时候加上tls就可以,不过如果是对外提供服务的这里的证书最好是认证过的,自签的证书会被提示不可信任

小结:

(1)
User→cdn→waf/ddos→4/7 层LB→nginx-ingress-controller(在指定node节点,有ingress规则)→pod
在4/7层这里分为两种情况
如果这里用7层LB的话那么ingress就不需要证书了,在7层直接卸载证书后端使用http协议,但是性能可能没有4层好
如果这里用4层,性能比较好,但是由于4层LB不能携带证书,那么我们ingress就需要在创建的时候指定证书
(2)user→node(vip,ingress controller+keepalived主备)→pod
Ingress(http/https)→service/domain→pods

在这里插入图片描述

4.ingress用户指南

https://github.com/kubernetes/ingress-nginx/tree/master/docs/user-guide

猜你喜欢

转载自blog.csdn.net/qq_26489043/article/details/110949542