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
相关推荐
马可奥勒留4 小时前
《你以为职场是过家家?真正的高手都在用「职业化人际关系模型」》
程序员
袁煦丞5 小时前
数据库设计神器DrawDB:cpolar内网穿透实验室第595个成功挑战
前端·程序员·远程工作
codeGoogle5 小时前
不吹不黑理性讨论:疑似华为员工匿名指控盘古大模型造假,你怎么看?
程序员
陈随易7 小时前
MoonBit助力前端开发,加密&性能两不误,斐波那契测试提高3-4倍
前端·后端·程序员
难受啊马飞2.09 小时前
如何判断 AI 将优先自动化哪些任务?
运维·人工智能·ai·语言模型·程序员·大模型·大模型学习
顺丰同城前端技术团队12 小时前
DeepSeek 国产大模型新标杆
前端·后端·程序员
AI大模型12 小时前
COZE实战部署(二)—— 创建Coze应用
程序员·llm·coze
redreamSo14 小时前
AI Daily | AI日报:ChatGPT识破10年顽疾,医疗AI震撼登场; 微信支付MCP开放,机遇与风险并存; 蒙娜丽莎图让大模型几乎全军覆没
程序员·aigc·资讯
程序员鱼皮15 小时前
Cursor 1.2重磅更新,这个痛点终于被解决了!
ai·程序员·编程·agent·软件开发