【K8S专栏】Kubernetes应用访问管理(三)

本文涉及的产品
.cn 域名,1个 12个月
简介: 【K8S专栏】Kubernetes应用访问管理

地址重写

地址重写在ingress中通过在annotation中添加nginx.ingress.kubernetes.io/rewrite-target: "/$1"这种类型的配置即可。

通过地址重写,我们可以实现诸如访问a.com/foo 重写到a.com,访问a.com/foo重写到a.com/foo/bar,需要注意的是重写后的地址需要是能真实访问到资源的地址,不然重写也没什么意义。

实例如下:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-rewrite
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: "/$1"
spec:
  rules:
  - host: nginx-rewrite.dev.jokerbai.com
    http:
      paths:
      - path: /foo/?(.*)
        backend:
          service:
            name: nginx-svc
            port:
              number: 80
        pathType: Prefix

然后通过在访问URL中带/foo即可访问到Nginx服务,如下:

$ curl  -x 192.168.205.51:80 http://nginx-rewrite.dev.jokerbai.com/foo
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

认证访问

有时候,我们暴露出来的域名不想被其他人使用(可能有人会说:那你不暴露出来不就完事了),比如说prometheus的后台,默认是没有登录管理的,而运维是需要到后台去查询监控信息的,为了安全,我们需要给这类域名加上认证,以便在一定程度上降低风险。

ingress提供base auth的认证方式,我们可以通过这种方式为我们的域名提供认证。

(1)创建密码

$ htpasswd -c auth joker
New password: 
Re-type new password: 
Adding password for user joker

(2)将密码保存到secret中

$ kubectl create secret generic basic-auth --from-file=auth
secret/basic-auth created

(3)在Ingress中配置认证 只需要在ingress配置中添加两个annotation即可完成。

  • nginx.ingress.kubernetes.io/auth-type: basic  指明认证方式
  • nginx.ingress.kubernetes.io/auth-secret: basic-auth  指定认证的账号密码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-auth
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
spec:
  rules:
  - host: nginx-auth.dev.jokerbai.com
    http:
      paths:
      - path: /
        backend:
          service:
            name: nginx-svc
            port:
              number: 80
        pathType: Prefix

然后不带认证信息访问,结果如下:

$ curl  -x 192.168.205.51:80 http://nginx-auth.dev.jokerbai.com/foo
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx</center>
</body>
</html>

直接返回401,需要认证才能访问。

下面带上认证信息访问,结果如下:

$ curl -u "joker:123"  -x 192.168.205.51:80 http://nginx-auth.dev.jokerbai.com/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

如果是从浏览器访问,会给我们弹出一个输入框,输入账号密码即可进入应用。

黑白名单

有时候,光有认证访问也并不安全,这时候我们可以通过配置黑白名单的方式,把访问的范围降低,在nginx中,我们可以通过配置allow和deny来配置,在ingress中,也支持类似的配置。

配置白名单

在ingress里配置白名单可以通过两种方式实现:

  • 添加annotation,这种是只针对单个域名
  • 在ingress-nginx的configmap中配置,全局有效

(1)通过annotation配置,如下:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-whitelist
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/whitelist-source-range: 10.1.10.2
spec:
  rules:
  - host: nginx-whitelist.dev.jokerbai.com
    http:
      paths:
      - path: /
        backend:
          service:
            name: nginx-svc
            port:
              number: 80
        pathType: Prefix

配置了一个不存在的地址10.1.10.2,查看访问效果。

$ curl -I -x 192.168.205.51:80 http://nginx-whitelist.dev.jokerbai.com
HTTP/1.1 403 Forbidden
Date: Fri, 22 Jul 2022 06:57:45 GMT
Content-Type: text/html
Content-Length: 146
Connection: keep-alive

给我们返回403拒绝访问。

如果我们把地址配置成可以访问的IP,则可以访问。

(2)配置ConfigMap 部署好ingress-nginx后,会在ingress-nginx的namespace下生成叫“ingress-nginx-controller”的ConfigMap配置文件,我们只需要在这个配置文件进行配置即可。

$ kubectl edit cm -n ingress-nginx ingress-nginx-controller
apiVersion: v1
data:
  allow-snippet-annotations: "true"
  compute-full-forwarded-for: "true"
  use-forwarded-headers: "true"
  whitelist-source-range: 172.16.0.0/24
kind: ConfigMap
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.3.0
  name: ingress-nginx-controller
  namespace: ingress-nginx

配置完保存即可,ingress-nginx的pod会自动reload。不过这种配置是全局生效,在使用的时候慎重。

配置黑名单

有白名单就有黑名单,ingress的黑名单配置只能通过ConfigMap来,而且是全局生效的。

目前支持以下三种黑名单:

  • block-cidrs:限制IP
  • block-user-agents:限制User-Agent
  • block-referers:限制referer

配置很简单,如下:

$ kubectl edit cm -n ingress-nginx ingress-nginx-controller
apiVersion: v1
data:
  allow-snippet-annotations: "true"
  compute-full-forwarded-for: "true"
  use-forwarded-headers: "true"
  whitelist-source-range: 172.16.0.0/24
  block-cidrs: 10.1.10.100
kind: ConfigMap
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.3.0
  name: ingress-nginx-controller
  namespace: ingress-nginx

访问限速

有时候访问量太大,可以通过在ingress进行限速,配置如下:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-limit
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/limit-rate: "100K"
    nginx.ingress.kubernetes.io/limit-whitelist: "10.1.10.100"
    nginx.ingress.kubernetes.io/limit-rps: "1"
    nginx.ingress.kubernetes.io/limit-rpm: "30"
spec:
  rules:
  - host: nginx-limit.dev.jokerbai.com
    http:
      paths:
      - path: /
        backend:
          service:
            name: nginx-svc
            port:
              number: 80
        pathType: Prefix

其中:

  • nginx.ingress.kubernetes.io/limit-rate:限制客户端每秒传输的字节数
  • nginx.ingress.kubernetes.io/limit-whitelist:白名单中的IP不限速
  • nginx.ingress.kubernetes.io/limit-rps:单个IP每秒的连接数
  • nginx.ingress.kubernetes.io/limit-rpm:单个IP每分钟的连接数

灰度发布

?Nginx Annotations 支持以下 4 种 Canary 规则:

  • nginx.ingress.kubernetes.io/canary-by-header:基于 Request Header 的流量切分,适用于灰度发布以及 A/B 测试。当 Request Header 设置为 always时,请求将会被一直发送到 Canary 版本;当 Request Header 设置为 never时,请求不会被发送到 Canary 入口;对于任何其他 Header 值,将忽略 Header,并通过优先级将请求与其他金丝雀规则进行优先级的比较。
  • nginx.ingress.kubernetes.io/canary-by-header-value:要匹配的 Request Header 的值,用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务。当 Request Header 设置为此值时,它将被路由到 Canary 入口。该规则允许用户自定义 Request Header 的值,必须与上一个 annotation (即:canary-by-header)一起使用。
  • nginx.ingress.kubernetes.io/canary-weight:基于服务权重的流量切分,适用于蓝绿部署,权重范围 0 - 100 按百分比将请求路由到 Canary Ingress 中指定的服务。权重为 0 意味着该金丝雀规则不会向 Canary 入口的服务发送任何请求。权重为 100 意味着所有请求都将被发送到 Canary 入口。
  • nginx.ingress.kubernetes.io/canary-by-cookie:基于 Cookie 的流量切分,适用于灰度发布与 A/B 测试。用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务的cookie。当 cookie 值设置为 always时,它将被路由到 Canary 入口;当 cookie 值设置为 never时,请求不会被发送到 Canary 入口;对于任何其他值,将忽略 cookie 并将请求与其他金丝雀规则进行优先级的比较。

定义两个版本的代码。V1版本代码如下:

package main
import (
 "github.com/gin-gonic/gin"
 "net/http"
)
func main(){
 g:=gin.Default()
 g.GET("/", func(c *gin.Context) {
  c.JSON(http.StatusOK,gin.H{
   "version": "v1",
   "data": "hello world",
  })
  })
 _ = g.Run("8080")
}

V2版本代码如下:

package main
import (
 "github.com/gin-gonic/gin"
 "net/http"
)
func main(){
 g:=gin.Default()
 g.GET("/", func(c *gin.Context) {
  c.JSON(http.StatusOK,gin.H{
   "version": "v2",
   "data": "hello world,SB",
  })
  })
 _ = g.Run("8080")
}

然后制作镜像,Dockerfile如下:

FROM golang AS build-env
ADD . /go/src/app
WORKDIR /go/src/app
RUN go get -u -v github.com/gin-gonic/gin
RUN govendor sync
RUN GOOS=linux GOARCH=386 go build -v -o /go/src/app/app-server-v1
FROM alpine
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime
COPY --from=build-env /go/src/app/app-server-v1 /usr/local/bin/app-server-v1
EXPOSE 8080
CMD [ "/usr/local/bin/app-server-v1" ]

制作镜像并上传:

$ docker build -t registry.cn-hangzhou.aliyuncs.com/rookieops/go-test:v1 .
$ docker push registry.cn-hangzhou.aliyuncs.com/rookieops/go-test:v1

PS:V2版本操作类似

V1和V2版本的Deployment和Service如下:

apiVersion: apps/v1 
kind: Deployment
metadata:
  name: app-server-v1
spec:
  selector:
    matchLabels:
      app: app-server-v1
  replicas: 2
  template:
    metadata:
      labels:
        app: app-server-v1
    spec:
      containers:
      - name: app-server-v1
        image: registry.cn-hangzhou.aliyuncs.com/rookieops/go-test:v1
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: app-server-v1-svc
spec:
  selector:
    app: app-server-v1
  ports:
  - name: http
    port: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-server-v1
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: canary.dev.jokerbai.com
    http:
      paths:
      - path: /
        backend:
          service:
            name: app-server-v1-svc
            port:
              number: 8080
        pathType: Prefix
---
apiVersion: apps/v1 
kind: Deployment
metadata:
  name: app-server-v2
spec:
  selector:
    matchLabels:
      app: app-server-v2
  replicas: 2
  template:
    metadata:
      labels:
        app: app-server-v2
    spec:
      containers:
      - name: app-server-v2
        image: registry.cn-hangzhou.aliyuncs.com/rookieops/go-test:v2
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: app-server-v2-svc
spec:
  selector:
    app: app-server-v2
  ports:
  - name: http
    port: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-server-v2
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
  rules:
  - host: canary.dev.jokerbai.com
    http:
      paths:
      - path: /
        backend:
          service:
            name: app-server-v2-svc
            port:
              number: 8080
        pathType: Prefix

说明:

  • nginx.ingress.kubernetes.io/canary: true 表示开启canary
  • nginx.ingress.kubernetes.io/canary-weight: 10 表示权重为10,也就是v1:v2大致为9:1

在实际使用中,也是可以通过部署不同版本的Deployment来实现灰度发布。

总结

目前集群内应用的访问主要是通过Service和Ingress两种方式,其中Service是四层,Ingress是七层,在企业应用中,除了一些必须使用四层的应用,比如MySQL、Redis,其他的基本都采用Ingress进行访问。

Ingress的选型非常多,可以根据企业的实际情况(比如技术栈、熟悉程度、规模大小)进行选择,而Service主要还是在集群内部使用。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
16天前
|
缓存 Kubernetes Docker
GitLab Runner 全面解析:Kubernetes 环境下的应用
GitLab Runner 是 GitLab CI/CD 的核心组件,负责执行由 `.gitlab-ci.yml` 定义的任务。它支持多种执行方式(如 Shell、Docker、Kubernetes),可在不同环境中运行作业。本文详细介绍了 GitLab Runner 的基本概念、功能特点及使用方法,重点探讨了流水线缓存(以 Python 项目为例)和构建镜像的应用,特别是在 Kubernetes 环境中的配置与优化。通过合理配置缓存和镜像构建,能够显著提升 CI/CD 流水线的效率和可靠性,助力开发团队实现持续集成与交付的目标。
|
9天前
|
存储 运维 Kubernetes
正式开源,Doris Operator 支持高效 Kubernetes 容器化部署方案
飞轮科技推出了 Doris 的 Kubernetes Operator 开源项目(简称:Doris Operator),并捐赠给 Apache 基金会。该工具集成了原生 Kubernetes 资源的复杂管理能力,并融合了 Doris 组件间的分布式协同、用户集群形态的按需定制等经验,为用户提供了一个更简洁、高效、易用的容器化部署方案。
正式开源,Doris Operator 支持高效 Kubernetes 容器化部署方案
|
4天前
|
存储 监控 对象存储
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
针对本地存储和 PVC 这两种容器存储使用方式,我们对 ACK 的容器存储监控功能进行了全新升级。此次更新完善了对集群中不同存储类型的监控能力,不仅对之前已有的监控大盘进行了优化,还针对不同的云存储类型,上线了全新的监控大盘,确保用户能够更好地理解和管理容器业务应用的存储资源。
|
9天前
|
存储 监控 对象存储
ACK容器监控存储全面更新:让您的应用运行更稳定、更透明
介绍升级之后的ACK容器监控体系,包括各大盘界面展示和概要介绍。
|
29天前
|
存储 Kubernetes Docker
Kubernetes(k8s)和Docker Compose本质区别
理解它们的区别和各自的优势,有助于选择合适的工具来满足特定的项目需求。
143 19
|
1月前
|
Kubernetes 应用服务中间件 nginx
二进制安装Kubernetes(k8s)v1.32.0
本指南提供了一个详细的步骤,用于在Linux系统上通过二进制文件安装Kubernetes(k8s)v1.32.0,支持IPv4+IPv6双栈。具体步骤包括环境准备、系统配置、组件安装和配置等。
450 10
|
1月前
|
Kubernetes 网络协议 应用服务中间件
Kubernetes Ingress:灵活的集群外部网络访问的利器
《Kubernetes Ingress:集群外部访问的利器-打造灵活的集群网络》介绍了如何通过Ingress实现Kubernetes集群的外部访问。前提条件是已拥有Kubernetes集群并安装了kubectl工具。文章详细讲解了Ingress的基本组成(Ingress Controller和资源对象),选择合适的版本,以及具体的安装步骤,如下载配置文件、部署Nginx Ingress Controller等。此外,还提供了常见问题的解决方案,例如镜像下载失败的应对措施。最后,通过部署示例应用展示了Ingress的实际使用方法。
65 2
|
存储 设计模式 运维
YAML 管理 Kubernetes 应用
YAML 管理 Kubernetes 应用
356 1
|
存储 设计模式 运维
如何不编写 YAML 管理 Kubernetes 应用?
Kubernetes 将自身边界内的事物都抽象为资源。其中的主要部分,是以 Deployment、StatefulSet 为代表的 workload 工作负载控制器,其他各类资源都围绕这些主要的资源工作。这些资源合并起来,可以为 IT 技术工作者展现出一个以 workload 为中心的模型。Kubernetes 中所有的资源,都通过声明式配置文件来编辑描述,一条条的 Yaml 字段定义,给了 IT 技术人员最大的自由度的同时,也对技术人员的能力提出了极高的要求。
|
Kubernetes Shell 开发工具
使用 Kustomize 帮你管理 kubernetes 应用(二): Kustomize 的使用方法
本篇为系列文章第二篇,手把手教你使用 Kustomize 的两种方式。
4591 0