kubernetes1.22安装apisix

背景:

kubernetes环境(tke)1.20.6刚完成了升级,体验了一把Tke1.20.6升级Tke1.22.5留下的坑。traefik自定义crd各种的问题!算是比较早用traefik的用户了。大佬们都说traefik早期算是第一梯队。现在算是淘汰的网关了。纯go写的,GC语言写的网关后面都会成为三流网关。就也想顺路体验一下其他的网关,比如apisix。这貌似是基于nginx lua的网关。另外也关注张晋涛大佬各种博客文章很久了。也值得试一试。为什么 APISIX Ingress 是比 Traefik 更好的选择?

kubernetes1.22安装apisix

理想很丰满,文档很现实:

本来觉得国人团队开发的,文档应该会很易读,打开文档:https://apisix.apache.org/zh/docs/ingress-controller/getting-started/. 这里又简体中文的切换,but.....点击以后特别想知道这个简体中文选项到底什么用途?仅仅是为了切换标题栏的语言吗.......。何况这不是国人搞的吗......就算与世界接轨中文也很容易吧........

实在不行也就别加这个中文切换了 我自己谷歌翻译......

以TKE helm安装文档为例Installation

安装这里由于我的环境是tke就看了一眼 Installation TKE (Tencent)的文档:

https://apisix.apache.org/docs/ingress-controller/deployments/tke/

满足前提条件:

helm是早先安装过的:

代码语言:txt
复制
helm version
kubectl get nodes

满足先决条件:

添加helm repo 创建工作空间

代码语言:txt
复制
helm repo add apisix https://charts.apiseven.com
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
kubectl create ns ingress-apisix

特意备份一下这个版本,pull到本地存一下,个人习惯吧:

代码语言:txt
复制
helm pull apisix/apisix

安装 APISIX 和入口控制器

直接参照官方文档:

代码语言:txt
复制
helm install apisix apisix/apisix \
  --set gateway.type=LoadBalancer \
  --set ingress-controller.enabled=true \
  --set etcd.persistence.size="10Gi" \
  --namespace ingress-apisix \
  --set ingress-controller.config.apisix.serviceNamespace=ingress-apisix
kubectl get service --namespace ingress-apisix

默认存储cbs 10G最小步进也符合

代码语言:txt
复制
 kubectl get sc

等待helm 安装成功参照文档:

代码语言:txt
复制
kubectl get service apisix-gateway --namespace ingress-apisix -o jsonpath='{.status.loadBalancer.ingress[].ip}'

但是完全没有返回loadBalancer阿? get svc获取一下相关信息:

代码语言:txt
复制
kubectl get svc -n ingress-apisix

但是上面按照文档gateway.type=LoadBalancer了阿?怎么还是NodePort?没有想明白......

怎么解决呢?我尝试了一下卸载,准备重新安装一下.....(默认以为自己输错了.......):

代码语言:txt
复制
helm uninstall apisix -n ingress-apisix

再重新安装一下:

代码语言:txt
复制
helm install apisix apisix/apisix \
  --set gateway.type=LoadBalancer \
  --set ingress-controller.enabled=true \
  --set etcd.persistence.size="10Gi" \
  --namespace ingress-apisix \
  --set ingress-controller.config.apisix.serviceNamespace=ingress-apisix
kubectl get service --namespace ingress-apisix

but get pod发现etcd搞不起来了。大概就是下面的样子:

代码语言:txt
复制
kubectl logs -f apisix-etcd-1 -n ingress-apisix

无脑想一下应该是pv pvc里面残留的数据造成的。继续uninstall apisix

代码语言:txt
复制
helm uninstall apisix -n ingress-apisix

删除pvc:

代码语言:txt
复制
kubectl delete pvc data-apisix-etcd-0 data-apisix-etcd-1 data-apisix-etcd-2 -n ingress-apisix

重新安装一下:

代码语言:txt
复制
helm install apisix apisix/apisix \
  --set gateway.type=LoadBalancer \
  --set ingress-controller.enabled=true \
  --set etcd.persistence.size="10Gi" \
  --namespace ingress-apisix \
  --set ingress-controller.config.apisix.serviceNamespace=ingress-apisix
kubectl get service --namespace ingress-apisix

跑起来了 仍然与开始一样:

懒得kubectl命令去修改了,登陆tke控制台,找到对应集群-服务与路由-service,选择 ingress-apisix namespace。选择apisix-gateway 更改配置:

选择公网LB访问,这里自动创建 端口都默认了

修改完成后控制台如下,出现了lb以及相关信息

当然了kubectl get svc -n ingress-apisix 也正常获取了loadbalancer:

访问默认lb地址出现404页面如下:

关于loadbalancer

怀疑自己,创建一个loadbalancer

也怀疑了一下当时是我的集群有问题吗?没法创建loadbalancer?按照官方文档Service 基本功能

试了一下:

cat svc.yaml

代码语言:txt
复制
kind: Service
apiVersion: v1
metadata:
  ## annotations:
  ##   service.kubernetes.io/qcloud-loadbalancer-internal-subnetid: subnet-xxxxxxxx ##若是创建内网访问的 Service 需指定该条 annotation
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
  type: LoadBalancer
代码语言:txt
复制
kubectl apply -f svc.yaml

完全没有问题阿!不去纠结了,起码不是集群的问题,应该是helm的配置问题,or压根不支持。起码按照文档搞不起来!

看一眼自动创建的lb:

这我还是喜欢使用http https监听器.......,好歹能启用sni阿!创建一个https的监听器,这里创建的默认的是tcp的监听器!

创建一个https监听器

创建一个https监听器,这是个人的习惯,习惯把证书挂载在负载均衡层。免得在ingress曾管理那么多证书......

启用SNI:

添加一个规则:输入域名,我这里直接用了泛域名 *.xxx.com的方式,具体的交给后面的ingress去处理选择对应域名证书:

注意:我这里开启了目标组

下一步,直接默认就开通了健康检查了:

会话保持根据个人需求是否开启,我这里保持了默认:

clb控制台创建了目标组

随后转发规则这里绑定目标组:

简单测试:

创建测试应用实例

启动一个nginx 实例然后用apisix代理一下,以常用的nginx镜像启动一个实例:

cat nginx-php.yaml

代码语言:txt
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-php
spec:
  replicas: 1
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: nginx-php
  template:
    metadata:
      labels:
        app: nginx-php
    spec:
      containers:
        - name: nginx-php
          image: richarvey/nginx-php-fpm:latest
          ports:
            - containerPort: 80
          resources:
            requests:
              memory: "512M"
              cpu: "500m"
            limits:
              memory: "2048M"
              cpu: "2000m" 
---

apiVersion: v1
kind: Service
metadata:
name: nginx-php
labels:
app: nginx-php
spec:
ports:

  • port: 80
    protocol: TCP
    targetPort: 80
    selector:
    app: nginx-php
代码语言:txt
复制
kubectl apply -f nginx-php.yaml
kubectl get svc

ApisixRoute 与ingress方式代理:

参照文档:https://apisix.apache.org/docs/ingress-controller/getting-started/

cat router.yaml

代码语言:txt
复制
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: nginx-php-route
namespace: default
spec:
http:
  • name: nginx-php-route
    match:
    hosts:
    • test.xxx.com
      paths:
    • /*
      backends:
    • serviceName: nginx-php
      servicePort: 80
  • 代码语言:txt
    复制
     kubectl apply -f router.yaml

    盲猜了一下应该是这样现实router.......

    代码语言:txt
    复制
    kubectl get apisixroute

    http方式访问:

    https方式:

    以ingress的方式试一下:

    cat ingress.yaml

    代码语言:txt
    复制
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    name: nginx-php-ingress
    namespace: default
    spec:
    ingressClassName: apisix
    rules:
  • host: test1.xxx.com
    http:
    paths:
    - backend:
    service:
    name: nginx-php
    port:
    number: 80
    path: /
    pathType: Prefix
  • 执行apply yaml文件:

    代码语言:txt
    复制
    kubectl apply -f ingress.yaml
    kubeclt get ingress

    https访问

    http方式访问:

    启用dashboard:

    启动dashboard控制台体验一下?--set dashboard.enabled=true

    代码语言:txt
    复制
    helm upgrade apisix  apisix/apisix  --set dashboard.enabled=true   --namespace ingress-apisix

    etcd这个提示忽略了......

    代码语言:txt
    复制
    kubectl get all -n ingress-apisix

    but loadbalancer又没有了....

    我再也不想用loadbalancer的这种方式了.....正好就启用一下http https监听器吧....

    创建一个Loadbalancer

    clb控制台新建一个clb实例:

    注意选择所属网络。貌似今天刚出的实例规格。这里还是保持默认了共享型。立即购买!确认订单:

    控制台选择对应的新建实例,打开监听器管理,创建https https监听器:

    注意:依然启用SNI,命名名称可以根据个人喜好定义。我个人喜欢映射端口号命名!

    创建转发规则(443下创建,80准备直接做重定向!),启用了http 2.0 quic 还启用了后端目标组!

    健康检测也默认开启了

    会话保持默认没有开启,提交:

    绑定目标组:

    注:仍然是上面创建的目标组!

    重定向配置:

    偷懒做了一个强制跳转80访问直接跳转到443:

    注意:当然了这里的重定向针对的是*.xxx.com 如果有其他监听器域名规则。依然要添加对应域名的重定向配置!

    对外暴露apisix dashboard

    这里直接以Ingress方式暴露服务了:

    cat apisix-dashboard-router.yaml

    代码语言:txt
    复制
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    name: apisix-dashboard-ingress
    namespace: ingress-apisix
    spec:
    ingressClassName: apisix
    rules:
  • host: apisix-dashboard.layaverse.com
    http:
    paths:
    - backend:
    service:
    name: apisix-dashboard
    port:
    number: 80
    path: /
    pathType: Prefix
  • apply yaml文件:

    代码语言:txt
    复制
    kubectl apply -f apisix-dashboard-router.yaml

    浏览器访问dashboard域名。默认账号密码admin admin进入?

    控制台页面大致如下:

    路由这里可以看到已有的路由策略:

    修改dashboard默认用户名密码:

    找了一圈没有修改密码的....

    退出登陆,重新登陆页面,提示了可以修改配置文件?

    edit configmap配置文件修改:

    代码语言:txt
    复制
    kubectl get cm -n ingress-apisix
    kubectl edit cm apisix-dashboard -n ingress-apisix

    明文....是很抗拒,另外不能动态加载生效阿毕竟。delete pods 等待pod running:

    代码语言:txt
    复制
    kubectl get pods -n ingress-apisix
    kubectl delete pods apisix-dashboard-55c654b869-9b9pg -n ingress-apisix

    再使用 admin admin 已经无法登陆了:

    使用新的账号密码登陆web控制台:

    就先这样吧:

    接下来我的需求日志json化:

    先个人习惯吧 看着日志就不爽了。一般都进行了json格式化:

    代码语言:txt
    复制
    kubectl edit cm apisix -n ingress-apisix

    参照 :apisix 修改日志为json格式 。修改参数如下:

    代码语言:txt
    复制
    access_log_format_escape: json
    
    
    
    

    access_log_format:'{"time": "time_iso8601", "remote_addr": "proxy_protocol_addr", "x_forward_for": "proxy_add_x_forwarded_for", "remote_user": "remote_user", "bytes_sent": bytes_sent, "request_time": request_time, "status": status, "vhost": "host", "request_proto": "server_protocol", "path": "uri", "request_query": "args", "request_length": request_length, "duration": request_time,"method": "request_method", "http_referrer": "http_referer", "http_user_agent": "http_user_agent", "upstream_addr": "upstream_addr", "upstream_response_time": "upstream_response_time", "upstream_status": "upstream_status", "upstream_scheme": "upstream_scheme", "upstream_host": "upstream_host", "upstream_uri": "upstream_uri", "http_host": "http_host", "request": "request", "time_local": "time_local", "body_bytes_sent": "body_bytes_sent"}'

    依然是delete pod 等待pod running:

    日志json格式了看着顺眼点了,虽然上面打印的这些日志还有点强迫症........

    总结一下:

    1. 文档中英文的支持,中文只替换了标题栏.
    2. 对loadbalancer的支持。文档写的都可以,结果启动了都是nodeport.
    3. dashboard 不知道能不能支持多用户?用户密钥不想明文希望能动态加载。
    4. dashboard中grafana这些的没有对我进行很好的用户引导......路由这些也没有按照namespace进行区分...用起来不是很习惯
    5. 其他功能慢慢体验吧,等我多体验完整了再考虑替代traefik......