searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

基于Yaml文件在K8S集群中部署APISIX网关

2025-06-06 08:33:17
0
0

Apache APISIX 是 Apache 软件基金会下的顶级项目,由 API7.ai 开发并捐赠。它是一个具有动态、实时、高性能等特点的云原生 API 网关。可以使用 APISIX 网关作为所有业务的流量入口,它提供了动态路由、动态上游、动态证书、A/B 测试、灰度发布(金丝雀发布)、蓝绿部署、限速、防攻击、收集指标、监控报警、可观测、服务治理等功能。
本教程基于Yaml文件在K8S集群中快速安装 Apache APISIX,并且通过管理 API 和APISIX Dashboard来验证是否安装成功。

一、基本概念

APISIX 主要分为两个部分:

  1. APISIX 核心:包括 Lua 插件、多语言插件运行时(Plugin Runner)、Wasm 插件运行时等;
  2. 功能丰富的各种内置插件:包括可观测性、安全、流量控制等。

APISIX 在其核心中,提供了路由匹配、负载均衡、服务发现、API 管理等重要功能,以及配置管理等基础性模块。除此之外,APISIX 插件运行时也包含其中,提供原生 Lua 插件的运行框架和多语言插件的运行框架,以及实验性的 Wasm 插件运行时等。APISIX 多语言插件运行时提供多种开发语言的支持,比如 Golang、Java、Python、JS 等。

APISIX 目前也内置了各类插件,覆盖了 API 网关的各种领域,如认证鉴权、安全、可观测性、流量管理、多协议接入等。当前 APISIX 内置的插件使用原生 Lua 实现,关于各个插件的介绍与使用方式,可以查看相关插件文档

Apache APISIX 使用 routes 来提供灵活的网关管理功能,在一个请求中,routes 包含了访问路径和上游目标等信息。

Route(也称之为路由)是访问上游目标的路径,在 Apache APISIX 中,Route 首先通过预定的规则来匹配客户端请求,然后加载和执行相应的插件,最后将请求转发至特定的 Upstream。

在 APISIX 中,一个最简单的 Route 仅由匹配路径和 Upstream 地址两个信息组成。

Upstream(也称之为上游)是一组具备相同功能的节点集合,它是对虚拟主机的抽象。Upstream 可以通过预先配置的规则对多个服务节点进行负载均衡。

二、APISIX部署方式

1、Helm Chart 部署

通过 Helm 包管理器快速部署 APISIX,适合需要标准化配置的场景。

  • 步骤:添加 Helm 仓库、安装 APISIX 及 Dashboard、配置端口转发。
  • 优势:简化依赖管理,支持一键安装,适合快速验证和轻量级环境。

2、YAML 文件手动部署

通过直接应用 Kubernetes 资源声明文件(YAML)部署,适合需要高度自定义的场景。

  • 步骤:克隆仓库、应用 etcd.yaml、apisix.yaml、apisix-dashboard.yaml 等文件,配置持久化存储。
  • 优势:灵活控制组件配置,便于集成自定义插件或调整资源分配。

3、Stand-alone 模式

独立运行模式,无需依赖 etcd,配置通过本地文件热加载。

  • 适用场景:K8s 声明式配置或需要与 Consul 等配置中心集成。
  • 限制:不支持 Admin API,仅通过 apisix.yaml 文件管理路由规则。

4、Docker Compose 部署

适用于本地开发或测试环境,通过 Docker 容器快速启动 APISIX 和 etcd。

特点:依赖外部 etcd 集群,需配置 docker-compose.yaml 和 config.yaml。

三、基于YAML文件在K8S中的部署流程

1、环境准备

在正式安装部署前,我们要准备好K8S集群并确保网络通畅。可以使用kubeadm、minikube、kubeasz、sealos等工具快速部署K8S集群。

2、部署etcd集群

etcd 是 APISIX 的配置中心,需通过 StatefulSet 部署并配置持久化存储

apiVersion: v1  
kind: Namespace  
metadata:  
  name: apisix
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: apisix-etcd
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix-etcd
    app.kubernetes.io/name: apisix-etcd
spec:
  podManagementPolicy: Parallel
  replicas: 3
  serviceName: apisix-etcd-headless
  selector:
    matchLabels:
      app.kubernetes.io/instance: apisix-etcd
      app.kubernetes.io/name: apisix-etcd
  template:
    metadata:
      labels:
        app.kubernetes.io/instance: apisix-etcd
        app.kubernetes.io/name: apisix-etcd
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - podAffinityTerm:
              labelSelector:
                matchLabels:
                  app.kubernetes.io/instance: apisix-etcd
                  app.kubernetes.io/name: apisix-etcd
              topologyKey: kubernetes.io/hostname
            weight: 1
      initContainers:  
      - name: init-permissions  
        image: busybox:1.32  
        command: ["sh", "-c", "chown -R 1001:1001 /bitnami/etcd && chmod -R 777 /bitnami/etcd"]  
        volumeMounts:  
        - name: data  
          mountPath: /bitnami/etcd
      containers:
      - name: apisix-etcd
        image: etcd:3.5.14-amd64
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 2379
          name: client
          protocol: TCP
        - containerPort: 2380
          name: peer
          protocol: TCP
        env:
        - name: BITNAMI_DEBUG
          value: 'false'
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: status.podIP
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: MY_STS_NAME
          value: apisix-etcd
        - name: ETCDCTL_API
          value: '3'
        - name: ETCD_ON_K8S
          value: 'yes'
        - name: ETCD_START_FROM_SNAPSHOT
          value: 'no'
        - name: ETCD_DISASTER_RECOVERY
          value: 'no'
        - name: ETCD_NAME
          value: $(MY_POD_NAME)
        - name: ETCD_DATA_DIR
          value: /bitnami/etcd/data
        - name: ETCD_LOG_LEVEL
          value: info
        - name: ALLOW_NONE_AUTHENTICATION
          value: 'yes'
        - name: ETCD_ADVERTISE_CLIENT_URLS
          value: http://$(MY_POD_NAME).apisix-etcd-headless.apisix.svc.cluster.local:2379
        - name: ETCD_LISTEN_CLIENT_URLS
          value: http://0.0.0.0:2379
        - name: ETCD_INITIAL_ADVERTISE_PEER_URLS
          value: http://$(MY_POD_NAME).apisix-etcd-headless.apisix.svc.cluster.local:2380
        - name: ETCD_LISTEN_PEER_URLS
          value: http://0.0.0.0:2380
        - name: ETCD_INITIAL_CLUSTER_TOKEN
          value: apisix-etcd-cluster-k8s
        - name: ETCD_INITIAL_CLUSTER_STATE
          value: new
        - name: ETCD_INITIAL_CLUSTER
          value: apisix-etcd-0=http://apisix-etcd-0.apisix-etcd-headless.apisix.svc.cluster.local:2380,apisix-etcd-1=http://apisix-etcd-1.apisix-etcd-headless.apisix.svc.cluster.local:2380,apisix-etcd-2=http://apisix-etcd-2.apisix-etcd-headless.apisix.svc.cluster.local:2380
        - name: ETCD_CLUSTER_DOMAIN
          value: apisix-etcd-headless.apisix.svc.cluster.local
        volumeMounts:
        - name: data
          mountPath: /bitnami/etcd
        lifecycle:
          preStop:
            exec:
              command:
              - /opt/bitnami/scripts/etcd/prestop.sh
        livenessProbe:
          exec:
            command:
            - /opt/bitnami/scripts/etcd/healthcheck.sh
          initialDelaySeconds: 60
          timeoutSeconds: 5
          periodSeconds: 30
          successThreshold: 1
          failureThreshold: 5
        readinessProbe:
          exec:
            command:
            - /opt/bitnami/scripts/etcd/healthcheck.sh
          initialDelaySeconds: 60
          timeoutSeconds: 5
          periodSeconds: 10
          successThreshold: 1
          failureThreshold: 5
      securityContext:
        fsGroup: 1001
  volumeClaimTemplates:
    - kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: data
        creationTimestamp: null
      spec:
        accessModes:
          - ReadWriteOnce
        storageClassName: apisix-etcd
        resources:
          requests:
            storage: 5Gi
        volumeMode: Filesystem
---
apiVersion: v1
kind: Service
metadata:
  name: apisix-etcd-headless
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix-etcd
    app.kubernetes.io/name: apisix-etcd
spec:
  ports:
  - name: client
    port: 2379
    protocol: TCP
    targetPort: 2379
  - name: peer
    port: 2380
    protocol: TCP
    targetPort: 2380
  clusterIP: None
  selector:
    app.kubernetes.io/instance: apisix-etcd
    app.kubernetes.io/name: apisix-etcd
  publishNotReadyAddresses: true
--- 
apiVersion: v1
kind: Service
metadata:
  name: apisix-etcd
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix-etcd
    app.kubernetes.io/name: apisix-etcd
spec:
  ports:
  - name: client
    port: 2379
    protocol: TCP
    targetPort: 2379
  - name: peer
    port: 2380
    protocol: TCP
    targetPort: 2380
  selector:
    app.kubernetes.io/instance: apisix-etcd
    app.kubernetes.io/name: apisix-etcd

---
apiVersion: v1  
kind: PersistentVolume  
metadata:  
  name: apisix-etcd-pv-0
spec:  
  capacity:  
    storage: 5Gi  
  accessModes:  
    - ReadWriteOnce  
  persistentVolumeReclaimPolicy: Retain  
  storageClassName: apisix-etcd  
  hostPath:  
    path: /data/apisix-etcd-pv-0  
    type: DirectoryOrCreate
---
apiVersion: v1  
kind: PersistentVolume  
metadata:  
  name: apisix-etcd-pv-1
spec:  
  capacity:  
    storage: 5Gi  
  accessModes:  
    - ReadWriteOnce  
  persistentVolumeReclaimPolicy: Retain  
  storageClassName: apisix-etcd  
  hostPath:  
    path: /data/apisix-etcd-pv-1  
    type: DirectoryOrCreate
---
apiVersion: v1  
kind: PersistentVolume  
metadata:  
  name: apisix-etcd-pv-2
spec:  
  capacity:  
    storage: 5Gi  
  accessModes:  
    - ReadWriteOnce  
  persistentVolumeReclaimPolicy: Retain  
  storageClassName: apisix-etcd  
  hostPath:  
    path: /data/apisix-etcd-pv-2  
    type: DirectoryOrCreate

3、部署APISIX

kind: Deployment
apiVersion: apps/v1
metadata:
  name: apisix
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix
    app.kubernetes.io/name: apisix
    app.kubernetes.io/version: 2.10.0
spec:
  replicas: 2
  selector:
    matchLabels:
      app.kubernetes.io/instance: apisix
      app.kubernetes.io/name: apisix
  template:
    metadata:
      creationTimestamp: null
      labels:
        app.kubernetes.io/instance: apisix
        app.kubernetes.io/name: apisix
    spec:
      volumes:
        - name: apisix-config
          configMap:
            name: apisix
            defaultMode: 420
      initContainers:
        - name: wait-etcd
          image: busybox:1.32
          command:
            - sh
            - '-c'
            - >-
              until nc -z apisix-etcd.apisix.svc.cluster.local 2379; do echo
              waiting for etcd `date`; sleep 2; done;
          resources: {}
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
      containers:
        - name: apisix
          image: apisix:3.7.0-debian-0820
          ports:
            - name: http
              containerPort: 9080
              protocol: TCP
            - name: tls
              containerPort: 9443
              protocol: TCP
            - name: admin
              containerPort: 9180
              protocol: TCP
          resources: {}
          volumeMounts:
            - name: apisix-config
              mountPath: /usr/local/apisix/conf/config.yaml
              subPath: config.yaml
          readinessProbe:
            tcpSocket:
              port: 9080
            initialDelaySeconds: 10
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 6
          lifecycle:
            preStop:
              exec:
                command:
                  - /bin/sh
                  - '-c'
                  - sleep 30
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      securityContext: {}
      schedulerName: default-scheduler
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: apisix
  namespace: apisix
data:
  config.yaml: >-
    apisix:
      node_listen: 9080              # APISIX listening port
      enable_ipv6: false
      enable_control: true
      control:
        ip: "0.0.0.0"
        port: 9092
    deployment:
      admin:
        allow_admin:               # https://nginx.org/en/docs/http/ngx_http_access_module.html#allow
          - 0.0.0.0/0              # We need to restrict ip access rules for security. 0.0.0.0/0 is for test.
    
        admin_key:
          - name: "admin"
            key: xxx
            role: admin                 # admin: manage all configuration data
    
          - name: "viewer"
            key: xxx
            role: viewer
    
      etcd:
        host:                           # it's possible to define multiple etcd hosts addresses of the same etcd cluster.
          - "http://apisix-etcd.apisix.svc.cluster.local:2379"
        prefix: "/apisix"               # apisix configurations prefix
        timeout: 30                     # 30 seconds

    plugins:                          # plugin list
      - api-breaker
      - authz-keycloak
      - basic-auth
      - batch-requests
      - consumer-restriction
      - cors
      - echo
      - fault-injection
      - grpc-transcode
      - hmac-auth
      - http-logger
      - ip-restriction
      - ua-restriction
      - jwt-auth
      - kafka-logger
      - key-auth
      - limit-conn
      - limit-count
      - limit-req
      - log-rotate
      - node-status
      - openid-connect
      - authz-casbin
      - prometheus
      - proxy-cache
      - proxy-mirror
      - proxy-rewrite
      - redirect
      - referer-restriction
      - request-id
      - request-validation
      - response-rewrite
      - serverless-post-function
      - serverless-pre-function
      - sls-logger
      - syslog
      - tcp-logger
      - udp-logger
      - uri-blocker
      - wolf-rbac
      - zipkin
      - server-info
      - traffic-split
      - gzip
      - real-ip
    stream_plugins:
      - mqtt-proxy
      - ip-restriction
      - limit-conn
    plugin_attr:
      server-info:
        report_interval: 60
        report_ttl: 3600
      log-rotate:
        interval: 3600    # rotate interval (unit: second)
        max_kept: 168     # max number of log files will be kept
        max_size: -1      # max size of log files will be kept
        enable_compression: false    # enable log file compression(gzip) or not, default false
---
kind: Service
apiVersion: v1
metadata:
  name: apisix-admin
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix
    app.kubernetes.io/name: apisix
spec:
  ports:
    - name: apisix-admin
      protocol: TCP
      port: 9180
      targetPort: 9180
  selector:
    app.kubernetes.io/instance: apisix
    app.kubernetes.io/name: apisix
  type: ClusterIP
---
kind: Service
apiVersion: v1
metadata:
  name: apisix-gateway
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix
    app.kubernetes.io/name: apisix
spec:
  ports:
    - name: apisix-gateway-http
      protocol: TCP
      port: 80
      targetPort: 9080
    - name: apisix-gateway-https
      protocol: TCP
      port: 443
      targetPort: 9443
  selector:
    app.kubernetes.io/instance: apisix
    app.kubernetes.io/name: apisix
  type: ClusterIP
  sessionAffinity: None

4、部署APISIX Dashboard

kind: Deployment
apiVersion: apps/v1
metadata:
  name: apisix-dashboard
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix-dashboard
    app.kubernetes.io/name: apisix-dashboard
    app.kubernetes.io/version: 2.9.0
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/instance: apisix-dashboard
      app.kubernetes.io/name: apisix-dashboard
  template:
    metadata:
      creationTimestamp: null
      labels:
        app.kubernetes.io/instance: apisix-dashboard
        app.kubernetes.io/name: apisix-dashboard
    spec:
      volumes:
        - name: apisix-dashboard-config
          configMap:
            name: apisix-dashboard
            defaultMode: 420
      containers:
        - name: apisix-dashboard
          image: apisix-dashboard:3.0.0-alpine
          ports:
            - name: http
              containerPort: 9000
              protocol: TCP
          resources: {}
          volumeMounts:
            - name: apisix-dashboard-config
              mountPath: /usr/local/apisix-dashboard/conf/conf.yaml
              subPath: conf.yaml
          livenessProbe:
            httpGet:
              path: /ping
              port: http
              scheme: HTTP
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          readinessProbe:
            httpGet:
              path: /ping
              port: http
              scheme: HTTP
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
          securityContext: {}
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      serviceAccountName: apisix-dashboard
      serviceAccount: apisix-dashboard
      securityContext: {}
      schedulerName: default-scheduler
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600
---
kind: Service
apiVersion: v1
metadata:
  name: apisix-dashboard
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix-dashboard
    app.kubernetes.io/name: apisix-dashboard
    app.kubernetes.io/version: 2.9.0
spec:
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 9000
  selector:
    app.kubernetes.io/instance: apisix-dashboard
    app.kubernetes.io/name: apisix-dashboard
  type: ClusterIP
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: apisix-dashboard
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix-dashboard
    app.kubernetes.io/name: apisix-dashboard
    app.kubernetes.io/version: 2.9.0
data:
  conf.yaml: |-
    conf:
      listen:
        host: 0.0.0.0
        port: 9000
      etcd:
        endpoints:
          - http://apisix-etcd.apisix.svc.cluster.local:2379
      log:
        error_log:
          level: warn
          file_path: /dev/stderr
        access_log:
          file_path: /dev/stdout
    authentication:
      secert: secert
      expire_time: 3600
      users:
        - username: admin
          password: 6p#0*urwP1s3X1Ey
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: apisix-dashboard
  namespace: apisix

 

5、配置APISIX与APISIX Dashboard Ingress

apiVersion: networking.k8s.io/v1  
kind: Ingress  
metadata:  
  name: apisix-ingress  
  namespace: apisix  
spec:  
  rules:  
    - host: apisix-dashboard.ctyun.cn  
      http:  
        paths:  
          - path: / 
            pathType: Prefix  
            backend:  
              service:  
                name: apisix-dashboard  
                port:  
                  number: 80    
    - host: apisix-gataway.ctyun.cn  
      http:  
        paths:  
          - path: / 
            pathType: Prefix  
            backend:  
              service:  
                name: apisix-gateway  
                port:  
                  number: 80    
  tls:  
    - hosts:  
      - apisix-dashboard.ctyun.cn 
      secretName: apisix-dashboard

验证

你可以创建一个路由,将客户端的请求转发至 httpbin.org(这个网站能测试 HTTP 请求和响应的各种信息)。

通过下面的命令,你将创建一个路由,把请求http://127.0.0.1:9080/ip 转发至 httpbin.org/ip

curl -i "http://127.0.0.1:9180/apisix/admin/routes" -X PUT -d '
{
  "id": "getting-started-ip",
  "uri": "/ip",
  "upstream": {
    "type": "roundrobin",
    "nodes": {
      "httpbin.org:80": 1
    }
  }
}'
<button class="copyButton_V-PD clean-btn" type="button" aria-label="Copy code to clipboard">Copy</button>

如果配置成功,将会返回 HTTP/1.1 201 Created

验证

curl "http://127.0.0.1:9080/ip"
<button class="copyButton_V-PD clean-btn" type="button" aria-label="Copy code to clipboard">Copy</button>

你将会得到类似下面的返回:

{
  "origin": "183.94.122.205"
}

 

APISIX Dashboard登录

0条评论
0 / 1000
高****民
1文章数
0粉丝数
高****民
1 文章 | 0 粉丝
高****民
1文章数
0粉丝数
高****民
1 文章 | 0 粉丝
原创

基于Yaml文件在K8S集群中部署APISIX网关

2025-06-06 08:33:17
0
0

Apache APISIX 是 Apache 软件基金会下的顶级项目,由 API7.ai 开发并捐赠。它是一个具有动态、实时、高性能等特点的云原生 API 网关。可以使用 APISIX 网关作为所有业务的流量入口,它提供了动态路由、动态上游、动态证书、A/B 测试、灰度发布(金丝雀发布)、蓝绿部署、限速、防攻击、收集指标、监控报警、可观测、服务治理等功能。
本教程基于Yaml文件在K8S集群中快速安装 Apache APISIX,并且通过管理 API 和APISIX Dashboard来验证是否安装成功。

一、基本概念

APISIX 主要分为两个部分:

  1. APISIX 核心:包括 Lua 插件、多语言插件运行时(Plugin Runner)、Wasm 插件运行时等;
  2. 功能丰富的各种内置插件:包括可观测性、安全、流量控制等。

APISIX 在其核心中,提供了路由匹配、负载均衡、服务发现、API 管理等重要功能,以及配置管理等基础性模块。除此之外,APISIX 插件运行时也包含其中,提供原生 Lua 插件的运行框架和多语言插件的运行框架,以及实验性的 Wasm 插件运行时等。APISIX 多语言插件运行时提供多种开发语言的支持,比如 Golang、Java、Python、JS 等。

APISIX 目前也内置了各类插件,覆盖了 API 网关的各种领域,如认证鉴权、安全、可观测性、流量管理、多协议接入等。当前 APISIX 内置的插件使用原生 Lua 实现,关于各个插件的介绍与使用方式,可以查看相关插件文档

Apache APISIX 使用 routes 来提供灵活的网关管理功能,在一个请求中,routes 包含了访问路径和上游目标等信息。

Route(也称之为路由)是访问上游目标的路径,在 Apache APISIX 中,Route 首先通过预定的规则来匹配客户端请求,然后加载和执行相应的插件,最后将请求转发至特定的 Upstream。

在 APISIX 中,一个最简单的 Route 仅由匹配路径和 Upstream 地址两个信息组成。

Upstream(也称之为上游)是一组具备相同功能的节点集合,它是对虚拟主机的抽象。Upstream 可以通过预先配置的规则对多个服务节点进行负载均衡。

二、APISIX部署方式

1、Helm Chart 部署

通过 Helm 包管理器快速部署 APISIX,适合需要标准化配置的场景。

  • 步骤:添加 Helm 仓库、安装 APISIX 及 Dashboard、配置端口转发。
  • 优势:简化依赖管理,支持一键安装,适合快速验证和轻量级环境。

2、YAML 文件手动部署

通过直接应用 Kubernetes 资源声明文件(YAML)部署,适合需要高度自定义的场景。

  • 步骤:克隆仓库、应用 etcd.yaml、apisix.yaml、apisix-dashboard.yaml 等文件,配置持久化存储。
  • 优势:灵活控制组件配置,便于集成自定义插件或调整资源分配。

3、Stand-alone 模式

独立运行模式,无需依赖 etcd,配置通过本地文件热加载。

  • 适用场景:K8s 声明式配置或需要与 Consul 等配置中心集成。
  • 限制:不支持 Admin API,仅通过 apisix.yaml 文件管理路由规则。

4、Docker Compose 部署

适用于本地开发或测试环境,通过 Docker 容器快速启动 APISIX 和 etcd。

特点:依赖外部 etcd 集群,需配置 docker-compose.yaml 和 config.yaml。

三、基于YAML文件在K8S中的部署流程

1、环境准备

在正式安装部署前,我们要准备好K8S集群并确保网络通畅。可以使用kubeadm、minikube、kubeasz、sealos等工具快速部署K8S集群。

2、部署etcd集群

etcd 是 APISIX 的配置中心,需通过 StatefulSet 部署并配置持久化存储

apiVersion: v1  
kind: Namespace  
metadata:  
  name: apisix
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: apisix-etcd
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix-etcd
    app.kubernetes.io/name: apisix-etcd
spec:
  podManagementPolicy: Parallel
  replicas: 3
  serviceName: apisix-etcd-headless
  selector:
    matchLabels:
      app.kubernetes.io/instance: apisix-etcd
      app.kubernetes.io/name: apisix-etcd
  template:
    metadata:
      labels:
        app.kubernetes.io/instance: apisix-etcd
        app.kubernetes.io/name: apisix-etcd
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - podAffinityTerm:
              labelSelector:
                matchLabels:
                  app.kubernetes.io/instance: apisix-etcd
                  app.kubernetes.io/name: apisix-etcd
              topologyKey: kubernetes.io/hostname
            weight: 1
      initContainers:  
      - name: init-permissions  
        image: busybox:1.32  
        command: ["sh", "-c", "chown -R 1001:1001 /bitnami/etcd && chmod -R 777 /bitnami/etcd"]  
        volumeMounts:  
        - name: data  
          mountPath: /bitnami/etcd
      containers:
      - name: apisix-etcd
        image: etcd:3.5.14-amd64
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 2379
          name: client
          protocol: TCP
        - containerPort: 2380
          name: peer
          protocol: TCP
        env:
        - name: BITNAMI_DEBUG
          value: 'false'
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: status.podIP
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: MY_STS_NAME
          value: apisix-etcd
        - name: ETCDCTL_API
          value: '3'
        - name: ETCD_ON_K8S
          value: 'yes'
        - name: ETCD_START_FROM_SNAPSHOT
          value: 'no'
        - name: ETCD_DISASTER_RECOVERY
          value: 'no'
        - name: ETCD_NAME
          value: $(MY_POD_NAME)
        - name: ETCD_DATA_DIR
          value: /bitnami/etcd/data
        - name: ETCD_LOG_LEVEL
          value: info
        - name: ALLOW_NONE_AUTHENTICATION
          value: 'yes'
        - name: ETCD_ADVERTISE_CLIENT_URLS
          value: http://$(MY_POD_NAME).apisix-etcd-headless.apisix.svc.cluster.local:2379
        - name: ETCD_LISTEN_CLIENT_URLS
          value: http://0.0.0.0:2379
        - name: ETCD_INITIAL_ADVERTISE_PEER_URLS
          value: http://$(MY_POD_NAME).apisix-etcd-headless.apisix.svc.cluster.local:2380
        - name: ETCD_LISTEN_PEER_URLS
          value: http://0.0.0.0:2380
        - name: ETCD_INITIAL_CLUSTER_TOKEN
          value: apisix-etcd-cluster-k8s
        - name: ETCD_INITIAL_CLUSTER_STATE
          value: new
        - name: ETCD_INITIAL_CLUSTER
          value: apisix-etcd-0=http://apisix-etcd-0.apisix-etcd-headless.apisix.svc.cluster.local:2380,apisix-etcd-1=http://apisix-etcd-1.apisix-etcd-headless.apisix.svc.cluster.local:2380,apisix-etcd-2=http://apisix-etcd-2.apisix-etcd-headless.apisix.svc.cluster.local:2380
        - name: ETCD_CLUSTER_DOMAIN
          value: apisix-etcd-headless.apisix.svc.cluster.local
        volumeMounts:
        - name: data
          mountPath: /bitnami/etcd
        lifecycle:
          preStop:
            exec:
              command:
              - /opt/bitnami/scripts/etcd/prestop.sh
        livenessProbe:
          exec:
            command:
            - /opt/bitnami/scripts/etcd/healthcheck.sh
          initialDelaySeconds: 60
          timeoutSeconds: 5
          periodSeconds: 30
          successThreshold: 1
          failureThreshold: 5
        readinessProbe:
          exec:
            command:
            - /opt/bitnami/scripts/etcd/healthcheck.sh
          initialDelaySeconds: 60
          timeoutSeconds: 5
          periodSeconds: 10
          successThreshold: 1
          failureThreshold: 5
      securityContext:
        fsGroup: 1001
  volumeClaimTemplates:
    - kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: data
        creationTimestamp: null
      spec:
        accessModes:
          - ReadWriteOnce
        storageClassName: apisix-etcd
        resources:
          requests:
            storage: 5Gi
        volumeMode: Filesystem
---
apiVersion: v1
kind: Service
metadata:
  name: apisix-etcd-headless
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix-etcd
    app.kubernetes.io/name: apisix-etcd
spec:
  ports:
  - name: client
    port: 2379
    protocol: TCP
    targetPort: 2379
  - name: peer
    port: 2380
    protocol: TCP
    targetPort: 2380
  clusterIP: None
  selector:
    app.kubernetes.io/instance: apisix-etcd
    app.kubernetes.io/name: apisix-etcd
  publishNotReadyAddresses: true
--- 
apiVersion: v1
kind: Service
metadata:
  name: apisix-etcd
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix-etcd
    app.kubernetes.io/name: apisix-etcd
spec:
  ports:
  - name: client
    port: 2379
    protocol: TCP
    targetPort: 2379
  - name: peer
    port: 2380
    protocol: TCP
    targetPort: 2380
  selector:
    app.kubernetes.io/instance: apisix-etcd
    app.kubernetes.io/name: apisix-etcd

---
apiVersion: v1  
kind: PersistentVolume  
metadata:  
  name: apisix-etcd-pv-0
spec:  
  capacity:  
    storage: 5Gi  
  accessModes:  
    - ReadWriteOnce  
  persistentVolumeReclaimPolicy: Retain  
  storageClassName: apisix-etcd  
  hostPath:  
    path: /data/apisix-etcd-pv-0  
    type: DirectoryOrCreate
---
apiVersion: v1  
kind: PersistentVolume  
metadata:  
  name: apisix-etcd-pv-1
spec:  
  capacity:  
    storage: 5Gi  
  accessModes:  
    - ReadWriteOnce  
  persistentVolumeReclaimPolicy: Retain  
  storageClassName: apisix-etcd  
  hostPath:  
    path: /data/apisix-etcd-pv-1  
    type: DirectoryOrCreate
---
apiVersion: v1  
kind: PersistentVolume  
metadata:  
  name: apisix-etcd-pv-2
spec:  
  capacity:  
    storage: 5Gi  
  accessModes:  
    - ReadWriteOnce  
  persistentVolumeReclaimPolicy: Retain  
  storageClassName: apisix-etcd  
  hostPath:  
    path: /data/apisix-etcd-pv-2  
    type: DirectoryOrCreate

3、部署APISIX

kind: Deployment
apiVersion: apps/v1
metadata:
  name: apisix
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix
    app.kubernetes.io/name: apisix
    app.kubernetes.io/version: 2.10.0
spec:
  replicas: 2
  selector:
    matchLabels:
      app.kubernetes.io/instance: apisix
      app.kubernetes.io/name: apisix
  template:
    metadata:
      creationTimestamp: null
      labels:
        app.kubernetes.io/instance: apisix
        app.kubernetes.io/name: apisix
    spec:
      volumes:
        - name: apisix-config
          configMap:
            name: apisix
            defaultMode: 420
      initContainers:
        - name: wait-etcd
          image: busybox:1.32
          command:
            - sh
            - '-c'
            - >-
              until nc -z apisix-etcd.apisix.svc.cluster.local 2379; do echo
              waiting for etcd `date`; sleep 2; done;
          resources: {}
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
      containers:
        - name: apisix
          image: apisix:3.7.0-debian-0820
          ports:
            - name: http
              containerPort: 9080
              protocol: TCP
            - name: tls
              containerPort: 9443
              protocol: TCP
            - name: admin
              containerPort: 9180
              protocol: TCP
          resources: {}
          volumeMounts:
            - name: apisix-config
              mountPath: /usr/local/apisix/conf/config.yaml
              subPath: config.yaml
          readinessProbe:
            tcpSocket:
              port: 9080
            initialDelaySeconds: 10
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 6
          lifecycle:
            preStop:
              exec:
                command:
                  - /bin/sh
                  - '-c'
                  - sleep 30
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      securityContext: {}
      schedulerName: default-scheduler
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: apisix
  namespace: apisix
data:
  config.yaml: >-
    apisix:
      node_listen: 9080              # APISIX listening port
      enable_ipv6: false
      enable_control: true
      control:
        ip: "0.0.0.0"
        port: 9092
    deployment:
      admin:
        allow_admin:               # https://nginx.org/en/docs/http/ngx_http_access_module.html#allow
          - 0.0.0.0/0              # We need to restrict ip access rules for security. 0.0.0.0/0 is for test.
    
        admin_key:
          - name: "admin"
            key: xxx
            role: admin                 # admin: manage all configuration data
    
          - name: "viewer"
            key: xxx
            role: viewer
    
      etcd:
        host:                           # it's possible to define multiple etcd hosts addresses of the same etcd cluster.
          - "http://apisix-etcd.apisix.svc.cluster.local:2379"
        prefix: "/apisix"               # apisix configurations prefix
        timeout: 30                     # 30 seconds

    plugins:                          # plugin list
      - api-breaker
      - authz-keycloak
      - basic-auth
      - batch-requests
      - consumer-restriction
      - cors
      - echo
      - fault-injection
      - grpc-transcode
      - hmac-auth
      - http-logger
      - ip-restriction
      - ua-restriction
      - jwt-auth
      - kafka-logger
      - key-auth
      - limit-conn
      - limit-count
      - limit-req
      - log-rotate
      - node-status
      - openid-connect
      - authz-casbin
      - prometheus
      - proxy-cache
      - proxy-mirror
      - proxy-rewrite
      - redirect
      - referer-restriction
      - request-id
      - request-validation
      - response-rewrite
      - serverless-post-function
      - serverless-pre-function
      - sls-logger
      - syslog
      - tcp-logger
      - udp-logger
      - uri-blocker
      - wolf-rbac
      - zipkin
      - server-info
      - traffic-split
      - gzip
      - real-ip
    stream_plugins:
      - mqtt-proxy
      - ip-restriction
      - limit-conn
    plugin_attr:
      server-info:
        report_interval: 60
        report_ttl: 3600
      log-rotate:
        interval: 3600    # rotate interval (unit: second)
        max_kept: 168     # max number of log files will be kept
        max_size: -1      # max size of log files will be kept
        enable_compression: false    # enable log file compression(gzip) or not, default false
---
kind: Service
apiVersion: v1
metadata:
  name: apisix-admin
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix
    app.kubernetes.io/name: apisix
spec:
  ports:
    - name: apisix-admin
      protocol: TCP
      port: 9180
      targetPort: 9180
  selector:
    app.kubernetes.io/instance: apisix
    app.kubernetes.io/name: apisix
  type: ClusterIP
---
kind: Service
apiVersion: v1
metadata:
  name: apisix-gateway
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix
    app.kubernetes.io/name: apisix
spec:
  ports:
    - name: apisix-gateway-http
      protocol: TCP
      port: 80
      targetPort: 9080
    - name: apisix-gateway-https
      protocol: TCP
      port: 443
      targetPort: 9443
  selector:
    app.kubernetes.io/instance: apisix
    app.kubernetes.io/name: apisix
  type: ClusterIP
  sessionAffinity: None

4、部署APISIX Dashboard

kind: Deployment
apiVersion: apps/v1
metadata:
  name: apisix-dashboard
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix-dashboard
    app.kubernetes.io/name: apisix-dashboard
    app.kubernetes.io/version: 2.9.0
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/instance: apisix-dashboard
      app.kubernetes.io/name: apisix-dashboard
  template:
    metadata:
      creationTimestamp: null
      labels:
        app.kubernetes.io/instance: apisix-dashboard
        app.kubernetes.io/name: apisix-dashboard
    spec:
      volumes:
        - name: apisix-dashboard-config
          configMap:
            name: apisix-dashboard
            defaultMode: 420
      containers:
        - name: apisix-dashboard
          image: apisix-dashboard:3.0.0-alpine
          ports:
            - name: http
              containerPort: 9000
              protocol: TCP
          resources: {}
          volumeMounts:
            - name: apisix-dashboard-config
              mountPath: /usr/local/apisix-dashboard/conf/conf.yaml
              subPath: conf.yaml
          livenessProbe:
            httpGet:
              path: /ping
              port: http
              scheme: HTTP
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          readinessProbe:
            httpGet:
              path: /ping
              port: http
              scheme: HTTP
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
          securityContext: {}
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      serviceAccountName: apisix-dashboard
      serviceAccount: apisix-dashboard
      securityContext: {}
      schedulerName: default-scheduler
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600
---
kind: Service
apiVersion: v1
metadata:
  name: apisix-dashboard
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix-dashboard
    app.kubernetes.io/name: apisix-dashboard
    app.kubernetes.io/version: 2.9.0
spec:
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 9000
  selector:
    app.kubernetes.io/instance: apisix-dashboard
    app.kubernetes.io/name: apisix-dashboard
  type: ClusterIP
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: apisix-dashboard
  namespace: apisix
  labels:
    app.kubernetes.io/instance: apisix-dashboard
    app.kubernetes.io/name: apisix-dashboard
    app.kubernetes.io/version: 2.9.0
data:
  conf.yaml: |-
    conf:
      listen:
        host: 0.0.0.0
        port: 9000
      etcd:
        endpoints:
          - http://apisix-etcd.apisix.svc.cluster.local:2379
      log:
        error_log:
          level: warn
          file_path: /dev/stderr
        access_log:
          file_path: /dev/stdout
    authentication:
      secert: secert
      expire_time: 3600
      users:
        - username: admin
          password: 6p#0*urwP1s3X1Ey
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: apisix-dashboard
  namespace: apisix

 

5、配置APISIX与APISIX Dashboard Ingress

apiVersion: networking.k8s.io/v1  
kind: Ingress  
metadata:  
  name: apisix-ingress  
  namespace: apisix  
spec:  
  rules:  
    - host: apisix-dashboard.ctyun.cn  
      http:  
        paths:  
          - path: / 
            pathType: Prefix  
            backend:  
              service:  
                name: apisix-dashboard  
                port:  
                  number: 80    
    - host: apisix-gataway.ctyun.cn  
      http:  
        paths:  
          - path: / 
            pathType: Prefix  
            backend:  
              service:  
                name: apisix-gateway  
                port:  
                  number: 80    
  tls:  
    - hosts:  
      - apisix-dashboard.ctyun.cn 
      secretName: apisix-dashboard

验证

你可以创建一个路由,将客户端的请求转发至 httpbin.org(这个网站能测试 HTTP 请求和响应的各种信息)。

通过下面的命令,你将创建一个路由,把请求http://127.0.0.1:9080/ip 转发至 httpbin.org/ip

curl -i "http://127.0.0.1:9180/apisix/admin/routes" -X PUT -d '
{
  "id": "getting-started-ip",
  "uri": "/ip",
  "upstream": {
    "type": "roundrobin",
    "nodes": {
      "httpbin.org:80": 1
    }
  }
}'
<button class="copyButton_V-PD clean-btn" type="button" aria-label="Copy code to clipboard">Copy</button>

如果配置成功,将会返回 HTTP/1.1 201 Created

验证

curl "http://127.0.0.1:9080/ip"
<button class="copyButton_V-PD clean-btn" type="button" aria-label="Copy code to clipboard">Copy</button>

你将会得到类似下面的返回:

{
  "origin": "183.94.122.205"
}

 

APISIX Dashboard登录

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0