背景:

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.....点击以后特别想知道这个简体中文选项到底什么用途?仅仅是为了切换标题栏的语言吗.......。何况这不是国人搞的吗......就算与世界接轨中文也很容易吧........
image.png
实在不行也就别加这个中文切换了 我自己谷歌翻译......
image.png

以TKE helm安装文档为例Installation

安装这里由于我的环境是tke就看了一眼 Installation TKE (Tencent)的文档:
https://apisix.apache.org/docs/ingress-controller/deployments/tke/

满足先决条件:

helm是早先安装过的:

helm version
kubectl get nodes

image.png
满足先决条件:
image.png

添加helm repo 创建工作空间

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

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

helm pull apisix/apisix

01xOJEZVrk.png

安装 APISIX 和入口控制器

直接参照官方文档:
image.png

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

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

 kubectl get sc

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


kubectl get service apisix-gateway --namespace ingress-apisix -o jsonpath='{.status.loadBalancer.ingress[].ip}'

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

kubectl get svc -n ingress-apisix

但是上面按照文档gateway.type=LoadBalancer了阿?怎么还是NodePort?没有想明白......
BWSvHBxbBJ.png
怎么解决呢?我尝试了一下卸载,准备重新安装一下.....(默认以为自己输错了.......):

helm uninstall apisix -n ingress-apisix

再重新安装一下:

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

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

kubectl logs -f apisix-etcd-1 -n ingress-apisix

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

helm uninstall apisix -n ingress-apisix

删除pvc:

kubectl delete pvc data-apisix-etcd-0 data-apisix-etcd-1 data-apisix-etcd-2 -n ingress-apisix

B6AQeNackz.png
重新安装一下:

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

跑起来了 仍然与开始一样:
img_v2_3bd38b3c-8b49-47e3-9b52-7198362b8f0g.png
懒得kubectl命令去修改了,登陆tke控制台,找到对应集群-服务与路由-service,选择 ingress-apisix namespace。选择apisix-gateway 更改配置:
7Es5t5wO9a.png
选择公网LB访问,这里自动创建 端口都默认了
ljIqlTRzWc.png
修改完成后控制台如下,出现了lb以及相关信息
Luo7bjOvaL.png
当然了kubectl get svc -n ingress-apisix 也正常获取了loadbalancer:
sgAwwbPNO9.png
访问默认lb地址出现404页面如下:

UIxPWJTiLq.png

关于loadbalancer

怀疑自己,创建一个loadbalancer

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

cat svc.yaml

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
kubectl apply -f svc.yaml

image.png
完全没有问题阿!不去纠结了,起码不是集群的问题,应该是helm的配置问题,or压根不支持。起码按照文档搞不起来!
看一眼自动创建的lb:
image.png
这我还是喜欢使用http https监听器.......,好歹能启用sni阿!创建一个https的监听器,这里创建的默认的是tcp的监听器!

创建一个https监听器

创建一个https监听器,这是个人的习惯,习惯把证书挂载在负载均衡层。免得在ingress曾管理那么多证书......
启用SNI:
image.png
添加一个规则:输入域名,我这里直接用了泛域名 *.xxx.com的方式,具体的交给后面的ingress去处理选择对应域名证书:
cJ1YftDW4J.png
注意:我这里开启了目标组
下一步,直接默认就开通了健康检查了:
image.png
会话保持根据个人需求是否开启,我这里保持了默认:
xaQRRjnXcG.png
clb控制台创建了目标组
pRjW7KNP2V.png
随后转发规则这里绑定目标组:
PkQnqGNKzV.png

简单测试:

创建测试应用实例

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

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
kubectl apply -f nginx-php.yaml
kubectl get svc 

image.png

ApisixRoute 与ingress方式代理:

参照文档:https://apisix.apache.org/docs/ingress-controller/getting-started/
image.png
cat router.yaml

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
 kubectl apply -f router.yaml

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

kubectl get apisixroute

image.png
http方式访问:
image.png
https方式:
image.png
以ingress的方式试一下:
cat ingress.yaml

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文件:

kubectl apply -f ingress.yaml
kubeclt get ingress 

image.png
https访问
image.png
http方式访问:
image.png

启用dashboard:

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

helm upgrade apisix  apisix/apisix  --set dashboard.enabled=true   --namespace ingress-apisix

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

kubectl get all -n ingress-apisix

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

创建一个Loadbalancer

clb控制台新建一个clb实例:
image.png
注意选择所属网络。貌似今天刚出的实例规格。这里还是保持默认了共享型。立即购买!确认订单:
image.png
控制台选择对应的新建实例,打开监听器管理,创建https https监听器:
image.png
注意:依然启用SNI,命名名称可以根据个人喜好定义。我个人喜欢映射端口号命名!
image.png
创建转发规则(443下创建,80准备直接做重定向!),启用了http 2.0 quic 还启用了后端目标组!
image.png
健康检测也默认开启了

image.png
会话保持默认没有开启,提交:
image.png
绑定目标组:
注:仍然是上面创建的目标组!
image.png
重定向配置:
偷懒做了一个强制跳转80访问直接跳转到443:

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

对外暴露apisix dashboard

这里直接以Ingress方式暴露服务了:
cat apisix-dashboard-router.yaml

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文件:

kubectl apply -f apisix-dashboard-router.yaml

image.png
浏览器访问dashboard域名。默认账号密码admin admin进入?
image.png
控制台页面大致如下:
image.png
路由这里可以看到已有的路由策略:
image.png

修改dashboard默认用户名密码:

找了一圈没有修改密码的....
退出登陆,重新登陆页面,提示了可以修改配置文件?
image.png
edit configmap配置文件修改:

kubectl get cm -n ingress-apisix
kubectl edit cm apisix-dashboard -n ingress-apisix

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

kubectl get pods -n ingress-apisix
kubectl delete pods apisix-dashboard-55c654b869-9b9pg -n ingress-apisix

image.png
再使用 admin admin 已经无法登陆了:
image.png
使用新的账号密码登陆web控制台:
image.png
就先这样吧:
image.png

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

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

kubectl edit cm apisix -n ingress-apisix

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

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"}'

image.png
依然是delete pod 等待pod running:
image.png
日志json格式了看着顺眼点了,虽然上面打印的这些日志还有点强迫症........
image.png

总结一下:

  1. 文档中英文的支持,中文只替换了标题栏.
  2. 对loadbalancer的支持。文档写的都可以,结果启动了都是nodeport.
  3. dashboard 不知道能不能支持多用户?用户密钥不想明文希望能动态加载。
  4. dashboard中grafana这些的没有对我进行很好的用户引导......路由这些也没有按照namespace进行区分...用起来不是很习惯
  5. 其他功能慢慢体验吧,等我多体验完整了再考虑替代traefik......
  6. apisix实例helm安装了一个pod,怎么实现高性能呢?当时用traefik都是daemonsets的方式。这里是怎么更好的实现性能呢?

对你无可奈何
40 声望12 粉丝