DevOps笔记 - k3s 默认ingress 配置

背景

之前有在 docker 中部署 Traefik 来实现服务发现和 TLS证书自动申请的经历,k3s 中默认 Ingress 也是 Traefik,所以考虑在此基础上扩展而不是切换到其他的 Ingress 了。

基于此我们需要解决以下几个问题:

  1. 修改 Traefik默认配置
  2. 服务发现

默认配置修改

这里我们在看 k3s 官方文档有提到使用 HelmChartConfig 自定义打包组件, 需要我们通过traefik-config.yaml 配置 HelmChartConfig 来覆盖原有的配置,当前也可以直接修改kubectl -n kube-system edit cm traefik该命令允许你在终端中编辑ConfigMap。

操作步骤如下:

  1. 创建持久卷(K3S 默认安装了本地存储服务,方便支持部署有状态的服务,可以使用kubectl get storageclass 查看)

    yml 复制代码
    # nano /var/lib/rancher/k3s/server/manifests/traefik-pv.yaml
    
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: traefik-pv
      labels:
        type: local
    spec:
      storageClassName: traefik-config
      capacity:
        storage: 10Gi
      accessModes:
        - ReadWriteOnce
      hostPath:
      	path: "/home/k3s/data/traefik"

    这里创建完成会自动应用配置,如果我们没有在此目录创建,需要手动应用配置

    bash 复制代码
    kubectl create -f /your-path/traefik-pv.yaml

    应用完成后查看状态:

    也可以直接在rancher中创建

  2. 新建 traefik-config.yaml,这里我们使用 nano(不使用 vim似乎在 pve 中输入法影响 vim相关命令,具体未深入探究)

    以下配置开启 traefik 的 Dashboard,开启 TLS、启用数据持久化、接入Prometheus监控

    bash 复制代码
    # nano /var/lib/rancher/k3s/server/manifests/traefik-config.yaml
    
    apiVersion: helm.cattle.io/v1
    kind: HelmChartConfig
    metadata:
      name: traefik
      namespace: kube-system
    spec:
      valuesContent: |-
        ports:
        	traefik:
            port: 9000
            expose: true
            exposedPort: 9000
          websecure:
            tls:
              enabled: true
              certResolver: "le"
        additionalArguments:
          - "--entrypoints.websecure.http.tls.domains[0].main=ipc.xxx.com"
          - "--entrypoints.websecure.http.tls.domains[0].sans=*.ipc.xxx.com"
          - "--certificatesresolvers.le.acme.email=xxx@qq.com"
          - "--certificatesresolvers.le.acme.storage=/data/acme.json"
          - "--certificatesresolvers.le.acme.dnschallenge=true"
          - "--certificatesresolvers.le.acme.dnschallenge.provider=dnspod"
          # link: https://doc.traefik.io/traefik/https/acme/#providers
          - "--certificatesresolvers.le.acme.dnschallenge.delaybeforecheck=0"
          - "--certificatesresolvers.le.acme.dnschallenge.resolvers=f1g1ns1.dnspod.net,f1g1ns2.dnspod.net,steam.dnspod.net,athena.dnspod.net"
        
        persistence:
          enabled: true
          name: data
          accessMode: ReadWriteOnce
          storageClass: "traefik-config"
          path: /data
        
        metrics:
        	expose: true
        
        env:
          - name: "DNSPOD_API_KEY"
            value: "id,key"
          - name: "DNSPOD_HTTP_TIMEOUT"
            value: "150"
          - name: "DNSPOD_POLLING_INTERVAL"
            value: "5"
          - name: "DNSPOD_PROPAGATION_TIMEOUT"
            value: "300"
        # logs:
        #   general:
        #     level: DEBUG
  3. 保存后K3s 将通过**helm-install-traefik**来更新 Pod

  4. 错误解决

    如果遇到 helm-install-rraefik-xx 的 STATUS 状态不是 Completed,比如这里遇到过状态为 CrashLoopBackOff,具体原因是因为手动指定了

    yml 复制代码
    image:
          name: traefik
          tag: v2.10.4

    Pod无法找到这个版本的资源,需要我们手动拉取镜像或者去除此配置,使用默认版本即可

  5. 如果已经存在之前版本可以使用kubectl删除相关配置

    bash 复制代码
    kubectl delete -f  /var/lib/rancher/k3s/server/manifests/traefik-config.yam
    systemctl daemon-reload
    systemctl restart k3s

服务发现

这里我们使用一个模板来测试 Ingress 是否能够正常进行服务发现

bash 复制代码
kubectl apply -f https://k8s.io/examples/service/load-balancer-example.yaml

并且开启外部访问

bash 复制代码
kubectl expose deployment hello-world --type=LoadBalancer --name=hl

然后我们就可以在 rancher 的服务发现里面看到我们暴露出的Service

创建对应的Ingress绑定到对应的服务

创建完成后访问 http://h1.xx.com 就可以看到测试页面

但是的但是,我发现无论如果配置都没法直接启用 TLS证书自动申请,在 traefik Dashboard 中查看 TLS 状态也是正常

暂时没有找到解决方案,只能转而采用配置ClusterIssuer 的方案,这里我们创建cluster-issuer-letsencrypt.yaml

yaml 复制代码
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  namespace: cert-manager
  name: letsencrypt
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: your@qq.com
    privateKeySecretRef:
      name: letsencrypt
    solvers:
      - http01:
          ingress:
            class: traefik

使用kubectl apply -f cluster-issuer-letsencrypt.yaml 部署,使用kubectl describe clusterissuer letsencrypt 查看状态。

修改Ingress配置如下:

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress

metadata:
  name: test
  namespace: test
  annotations:
    kubernetes.io/ingress.class: 'traefik' # 在创建 Issuer 资源的时候有配置 ingress.class,需要保持一致
    cert-manager.io/cluster-issuer: letsencrypt # 指定 cert-manager 的 Issuer 的名字
    kubernetes.io/tls-acme: 'true' # 可选
    ingress.kubernetes.io/ssl-redirect: "true" # 强制从 HTTP 重定向 HTTPS

spec:
  rules:
    - host: h2.xx.xxx.com # 此 Ingress 资源识别的 域名
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
              service:
                name: hl
                port:
                  number: 8080

  #  routes:
#    - match: Host(`h2.xx.xxx.com`)
#      kind: Rule
#      services:
#        - name: hl
#          port: 8080

  tls:                              # [12]
    - secretName: h1-secret         # [13]
      hosts:
        - h2.xx.xxx.com
    # certResolver: le               # [17]
    # domains:                        # [18]
    # - main: h2.xx.xxx.com

如果中间碰到问题可以使用以下两个命令来排查

bash 复制代码
# 查看状态
kubectl get certificate -A

kubectl get ingress -n test

# 查看具体出错原因
kubectl describe certificate -A
kubectl describe certificate -n hoteler-namespace

再次访问你的域名,查看证书应该为有效状态

这里给一个完整的应用部署配置:

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: default
  labels:
    app: demo-nginx
spec:
  selector:
    matchLabels:
      app: demo-nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: demo-nginx
    spec:
      containers:
        - image: nginx
          name: demo-nginx
          ports:
            - containerPort: 80
              name: 'demo-nginx'
              protocol: 'TCP'
---
apiVersion: v1
kind: Service
metadata:
  name: demo-nginx
  namespace: default
  labels:
    app: demo-nginx
spec:
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: demo-nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress

metadata:
  name: demo-nginx
  annotations:
    kubernetes.io/ingress.class: 'traefik'
    cert-manager.io/cluster-issuer: letsencrypt
    kubernetes.io/tls-acme: 'true'
    ingress.kubernetes.io/ssl-redirect: "true"

spec:
  rules:
    - host: ng.xx.xxx.com
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
              service:
                name: demo-nginx
                port:
                  number: 80

  tls:                              # [12]
    - secretName: ng-secret         # [13]
      hosts:
        - ng.xx.xxx.com
相关推荐
文心快码BaiduComate9 小时前
干货|Comate Harness Engineering工程实践指南
前端·后端·程序员
hyunbar77711 小时前
Git 死亡三连实录:pull 冲突 → push 被拒 → merge 炸锅,完整抢救指南
程序员
Captaincc13 小时前
转载:如何一眼看出别人的财富量级
程序员
DogDaoDao15 小时前
Windows 下 Git 报错:`touch` 无法识别 —— 原因分析与 7 种解决方案(从入门到精通)
windows·git·程序员·npm·powershell·cmd·touch
小孔龙16 小时前
Android `<activity-alias>` 指南:动态图标 · 多入口 · 重命名兼容
android·程序员·掘金·日新计划
彩票管理中心秘书长16 小时前
智能体状态指示:何时思考、何时调用工具、何时出错
前端·后端·程序员
彩票管理中心秘书长16 小时前
React + TypeScript拆解一整套“AI 变现代码流程”
前端·后端·程序员
AskHarries16 小时前
OpenClaw 是什么?为什么它不是普通 AI Agent
人工智能·后端·程序员
AskHarries16 小时前
如何判断一个需求是真需求
人工智能·程序员·产品
SimonKing18 小时前
IP定位库的完美替代品:ip2region,开源、免费!
java·后端·程序员