TKE/EKS集群通过logrotate切割nginx-ingress访问日志

2022-12-15 23:58:39 浏览数 (1)

Nginx-ingress 是使用 Nginx 作为反向代理和负载平衡器的 Kubernetes 的 Ingress 控制器,容器服务 TKE 提供了产品化的能力,可以直接在集群内安装和使用 Nginx-ingress,具体可以参考文档https://cloud.tencent.com/document/product/457/50503

关于nginx-ingress的使用实践可以参考文档https://cloud.tencent.com/developer/article/1768089

使用nginx-ingress,会经常需要查下访问日志来定位问题,nginx-ingress组件也是支持直接将日志采集到腾讯云的cls,nginx-ingress实例默认配置的访问日志是写到容器的/var/log/nginx/nginx_access.log这个日志文件里面,然后配置日志采集规则采集这个日志文件到cls。

但是tke这边提供的nginx-ingress默认是不带日志切割功能的,如果运行时间长,nginx_access.log这个文件会非常大,占用较多的磁盘空间,因为日志是直接写在容器内,最终其实会落在node节点的容器存储目录,占用node节点磁盘空间。

如果容器存储目录没有单独挂盘,一般会直接在系统盘上,这个时候,随着文件增大,系统盘的可用磁盘空间不断减少,这个时候就会触发节点的kubelet的驱逐。 那么这里有什么办法可以解决这个问题,这里其实最终就是需要将nginx-ingress controller容器的/var/log/nginx/nginx_access.log日志文件进行轮转切割就行,因为日志是容器的文件里, 这里的方案是部署一个logrotate的sidecar容器来轮转切割这个日志文件,这来保证日志不会不断增加变得非常大。

下面我们来说下如何在nginx-ingress配置logrotate容器来轮转切割日志。

这里我们采集这个logrotate的镜像

代码语言:javascript复制
docker pull realz/logrotate:latest

具体介绍可以参考github https://github.com/hortonworks/docker-logrotate

主要需要在容器配置这几个环境变量

代码语言:javascript复制
CRON_EXPR="* * * * *"  
LOGROTATE_LOGFILES=/var/lib/docker/containers/*/*.log
LOGROTATE_FILESIZE=10M
LOGROTATE_FILENUM=5
  • CRON_EXPR:日志定时切割时间
  • LOGROTATE_LOGFILES:需要切割的日志
  • LOGROTATE_FILESIZE:日志文件多大就开始切割
  • LOGROTATE_FILENUM:最多保留几个日志文件

这里我们是通过emptydir来共享/var/log/nginx/目录,这样logrotate容器可以直接访问nginx_access.log,下面我们说说如何在控制台配置。

首先配置一个数据卷,名称叫做lograte,类型选择使用临时目录,然后controller的容器挂载点挂载这个数据卷

然后添加一个logrotate容器,镜像选择realz/logrotate,挂载点同样挂载lograte这个数据卷,然后添加这4个环境变量,这里是测试配置,最终根据实际需要配置即可。

代码语言:javascript复制
CRON_EXPR="* * * * *"  
LOGROTATE_LOGFILES=/var/log/nginx/*.log
LOGROTATE_FILESIZE=1M
LOGROTATE_FILENUM=5

配置好之后,直接报错工作负载更新pod即可,完整的yaml如下

代码语言:javascript复制
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: nginx-intranet-ingress-nginx-controller
    qcloud-app: nginx-intranet-ingress-nginx-controller
  name: nginx-intranet-ingress-nginx-controller
  namespace: kube-system
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: nginx-intranet-ingress-nginx-controller
      qcloud-app: nginx-intranet-ingress-nginx-controller
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        k8s-app: nginx-intranet-ingress-nginx-controller
        qcloud-app: nginx-intranet-ingress-nginx-controller
      name: nginx-intranet-ingress-nginx-controller
      namespace: kube-system
    spec:
      containers:
      - args:
        - /nginx-ingress-controller
        - --election-id=ingress-controller-leader
        - --ingress-class=nginx-intranet
        - --configmap=kube-system/nginx-intranet-ingress-nginx-controller
        - --publish-service=kube-system/nginx-intranet-ingress-nginx-controller
        - --validating-webhook=:8443
        - --validating-webhook-certificate=/usr/local/certificates/cert
        - --validating-webhook-key=/usr/local/certificates/key
        - --tcp-services-configmap=kube-system/nginx-intranet-ingress-nginx-tcp
        - --udp-services-configmap=kube-system/nginx-intranet-ingress-nginx-udp
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        image: ccr.ccs.tencentyun.com/paas/nginx-ingress-controller:v0.41.0
        imagePullPolicy: Always
        lifecycle:
          preStop:
            exec:
              command:
              - /wait-shutdown
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        name: controller
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
        - containerPort: 443
          name: https
          protocol: TCP
        - containerPort: 10254
          name: metrics
          protocol: TCP
        - containerPort: 8443
          name: webhook
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        resources: {}
        securityContext:
          allowPrivilegeEscalation: true
          capabilities:
            add:
            - NET_BIND_SERVICE
            drop:
            - ALL
          runAsUser: 101
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /usr/local/certificates/
          name: webhook-cert
          readOnly: true
        - mountPath: /var/log/nginx
          name: lograte
      - env:
        - name: LOGROTATE_LOGFILES
          value: /var/log/nginx/*.log
        - name: CRON_EXPR
          value: '* * * * *'
        - name: LOGROTATE_FILESIZE
          value: 1M
        - name: LOGROTATE_FILENUM
          value: "5"
        image: realz/logrotate
        imagePullPolicy: Always
        name: logrotate
        resources:
          limits:
            cpu: 500m
            memory: 1Gi
          requests:
            cpu: 250m
            memory: 256Mi
        securityContext:
          privileged: false
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /var/log/nginx
          name: lograte
      dnsPolicy: ClusterFirst
      initContainers:
      - command:
        - sh
        - -c
        - |-
          sysctl -w net.core.somaxconn=65535
          sysctl -w net.ipv4.ip_local_port_range="1024 65535"
          sysctl -w net.ipv4.tcp_tw_reuse=1
          sysctl -w fs.file-max=1048576
        image: ccr.ccs.tencentyun.com/tkeimages/busybox:latest
        imagePullPolicy: Always
        name: setsysctl
        resources: {}
        securityContext:
          privileged: true
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      serviceAccount: nginx-intranet-ingress-nginx
      serviceAccountName: nginx-intranet-ingress-nginx
      terminationGracePeriodSeconds: 300
      volumes:
      - name: webhook-cert
        secret:
          defaultMode: 420
          secretName: nginx-intranet-ingress-nginx-admission
      - emptyDir: {}
        name: lograte

pod运行后,我们通过ingress访问下后端的服务,生成一下访问日志

隔几分钟后,登陆容器查看日志可以发现日志被切割成多个了

通过上面的配置,我们就成功的通过logrotate切割了nginx-ingress controller的访问日志,并且这样还不影响cls采集日志。

0 人点赞