
有着10余年一线大厂经验的IT策士, 专注于IT思维、架构以及职场进阶, 会在各个平台持续发布最新文章, 以助你少走弯路。第30篇里, 我们借助相关方式完成了基于域名以及路径的HTTP路由来实现, 将外部的流量进行了分发处理并作用于Flask应用。然而那不过是处于“裸奔”情形下的HTTP, 即所有的数据都是以明文形式来传输的, 任何一个人都存在着能够进行嗅探的可能性。那么生产环境之中的最低安全标准究竟是什么呢? 答案便是HTTPS。此外, 在真实业务当中, 还存在着两个高频出现的需求, 应用有可能会被部署在某一个子路径之下, 比如说 /api 这个路径, 然而代码里面所书写的却是根路径 /, 这样一来就需要进行路径重写, 某些管理页面期望能够添加简单的用户名密码保护措施, 并且不想要对应用代码作出改动。今天这一篇, 是要在第30篇予以的基础之上, 去给其添加TLS证书, 再添加路径重写, 还要添加Basic Auth认证, 以此达成让你的外部入口达到生产级标准的目的。一、TLS 证书给 加上 .1 什么是 TLSHTTPS 的基础呀是 TLS即传输层安全协议, 它会于客户端以及服务器之间构建加密通道, 以此来保障数据传输不会被窃听或者篡改, 在也就是K8s里面呢, TLS私钥还有证书借助对象去进行存储了后, 并于YAML里面予以引用。你或许会问: 这跟时代运用Nginx配置SSL存在啥区别呢? 于其中, 你得手动将证书文件复制至容器之内, 对Nginx配置文件予以修改, 接着重启容器。而在K8s里, 证书作为资源被独立管理着, 自动去处理TLS握手以及证书加载, 当证书更新之际只需更新, 不用重启应用Pod。1.2 创建自签名证书实验环境生产环境当中, 应当使用Lets, 或者去购买由CA签发的证书。在实验环境里面, 我们采用生成自签名证书的方式:# 生成私钥和自签名证书有效期 365 天 openssl req -x509 -newkey rsa:4096 -keyout tls.key -out tls.crt -days 365 -nodes \ -subj /CNcounter.example.com命令参数说明1.3 创建 TLSkubectl create secret tls counter-tls \ --certtls.crt \ --keytls.key输出secret/counter-tls created查看 kubectl describe secret counter-tls对于K8s所进行的, 将内容予以编码存储的操作, 其输出里只会把证书以及密钥的字节数显示出来, 而不会呈现原文, 虽说这并非是那种强加密方式, 然而却是要比以明文状态存放更加具备安全性的:Name: counter-tls Type: kubernetes.io/tls Data: tls.crt: 1964 bytes tls.key: 3244 bytes安全请注意: 自行签名所得的证书仅仅是被用于实验用途的。在生产环境当中, tls.key 的私钥是归属于最高等级别的敏感信息范畴, 绝对不可以提交到 Git 里面。本系列的第 33 篇将会阐述介绍怎样去使用加密之后进行保证安全的存储方式。1.4 配置 TLS以第30篇的multi为基础, 给其增添TLS。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: flask-tls-ingress spec: ingressClassName: nginx tls: - hosts: - counter.example.com secretName: counter-tls rules: - host: counter.example.com http: paths: - path: / pathType: Prefix backend: service: name: flask-service port: number: 5000关键字段说明kubectl apply -f flask-tls-ingress.yaml kubectl get ingress flask-tls-ingress输出NAME CLASS HOSTS ADDRESS PORTS AGE flask-tls-ingress nginx counter.example.com 192.168.49.2 80, 443 10sPORTS列呈现出80, 443, 当下正同时处于监听HTTP以及HTTPS的状态。1.5 验证 HTTPS通行使用curl之际, 运用其-k参数, 将证书验证予以跳过, 须知此自签名证书并不受curl信任哟。MINIKUBE_IP$(minikube ip) curl -k -H Host: counter.example.com https://$MINIKUBE_IP输出Hello World! I have been seen 3 times.你同样能够添加 -v 参数以查看 TLS 握手详情, 借此确认加密套件、证书信息等均正确协商 , 标点符号使用正确:curl -k -v https://$MINIKUBE_IP -H Host: counter.example.com 21 | grep -E SSL|subject|issuer # * subject: CNcounter.example.com # * issuer: CNcounter.example.com # * SSL certificate verify result: self-signed certificate (18), continuing anyway.1.6 强制 HTTPS 重定向当下, 与此同时接纳 HTTP 以及 HTTPS 请求。要是你期望全部 HTTP 流量自行跳转至 HTTPS, 能够增添重定向注解:metadata: annotations: nginx.ingress.kubernetes.io/ssl-redirect: true更新后再测试 HTTP 请求curl -H Host: counter.example.com http://$MINIKUBE_IP你会收到 308 头指向此一注解仅仅是对NGINX才会产生效用, 别的不同样式的配置方式是不一样的。二、路径重写让 帮你改写 URL路径重写属于七层反向代理极为常见的需求当中的某一个。假定你的Flask应用仅仅认识 / 和 / , 然而你期望借助 // 和 // 去进行访问, 借助路径前缀来区分不一样的应用, 与此同时不给应用增添 / 前缀的处理逻辑。能够在转发之际自动把 / 给剪掉。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: flask-rewrite-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: ingressClassName: nginx rules: - http: paths: - path: /counter(/|$)(.*) pathType: ImplementationSpecific backend: service: name: flask-service port: number: 5000这段配置的核心逻辑kubectl apply -f flask-rewrite-ingress.yaml curl http://$(minikube ip)/counter/ # Hello World! I have been seen 4 times. curl http://$(minikube ip)/counter/health # {status:ok}Flask所收到的请求路径的情况是, 为 / 和 / , 并非是 // 和 // , 原因是, 在进行转发之前, 已经把前缀给剪掉了。三、Basic Auth 认证轻量级访问控制Basic Auth属于一种最为简单的HTTP认证方式, 它并不适用于当作生产环境的主要安全手段, 不过它能够被用于保护管理后台、API文档等之类的内部页面。3.1 生成 文件# 安装 htpasswd 工具如果未安装 # macOS: brew install httpd # Ubuntu: sudo apt-get install apache2-utils # 创建用户 admin生成密码文件 htpasswd -c auth admin # 输入密码admin123实验用生产环境务必使用强密码3.2 创建 Basic Authkubectl create secret generic basic-auth \ --from-fileauthkubectl describe secret basic-auth # Name: basic-auth # Type: Opaque # Data: # auth: 45 bytes3.3 配置带 Basic Auth 的apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: flask-auth-ingress annotations: nginx.ingress.kubernetes.io/auth-type: basic nginx.ingress.kubernetes.io/auth-secret: basic-auth nginx.ingress.kubernetes.io/auth-realm: Authentication Required - Admin Area spec: ingressClassName: nginx rules: - host: admin.example.com http: paths: - path: / pathType: Prefix backend: service: name: flask-service port: number: 5000注解说明kubectl apply -f flask-auth-ingress.yaml3.4 验证认证效果不带认证信息拒绝访问curl -H Host: admin.example.com http://$(minikube ip) ##401 Authorization Required# ...带认证信息通过curl -H Host: admin.example.com -u admin:admin123 http://$(minikube ip) # Hello World! I have been seen 5 times.于实际运用里, 你能够把TLS跟Basic Auth搭配着用, 以此来保证用户名密码于加密通道内进行传输:spec: tls: - hosts: - admin.example.com secretName: admin-tls rules: - host: admin.example.com # ... Basic Auth 规则四、 注解 vs 原生能力本篇所借助的是多个归于 NGINX独有的注解, 分别是 ssl-、-、 auth-type。这些注解并非属于 K8s API 标准里的一部分, 而是属于 NGINX 的扩展内容。其他的, 比如 、Kong , 也有着自身的注解体系或者 CRD配置方式。选择建议如下: 针对中小规模集群而言, NGINX的注解已然足够灵活。当你有更细粒度的流量控制需求时, 像金丝雀发布、限流、熔断、基于请求头的路由这类情况, 便可以考虑使用所提供的自定义CRD, 例如NGINX的那种, 或者升级到Mesh, 像是Istio这种。第49篇会进一步探讨这两者的选型边界。五、命令速查表六、本篇总结凭借此篇这里, 你已然达到了具备生产级安全入口基础能力那般境地——传输借助 HTTPS 进行加密操作, 路径能够灵活予以 处理, 访问实施轻量级得以控制。紧邻的下一篇——也就是第 32 篇, 其主题在于配置管理详解, 那时我们会回转到应用配置自身范畴, 去钻研运用何种方式把配置与镜像予以解耦, 达成配置版本化管理以及动态更新目标之事。