<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用 OpenTelemetry Collector 收集 Kubernetes 日志數(shù)據(jù)

          共 30243字,需瀏覽 61分鐘

           ·

          2023-08-28 00:16

          前面我們介紹了如何通過 OpenTelemetry Collector 來收集 Kubernetes 集群的指標(biāo)數(shù)據(jù),接下來我們再來了解下如何收集集群的日志記錄數(shù)據(jù)。

          45b7715c34a509102306ac0b1d330e31.webp

          安裝 Loki

          首先我們需要部署 Loki 來收集日志數(shù)據(jù),同樣我們這里使用 Helm Chart 來快速部署,不過需要注意同樣不需要部署任何日志采集器,因?yàn)槲覀儗⑹褂?OpenTelemetry Collector 來收集日志數(shù)據(jù),然后再將其發(fā)送到 Loki 中。

                
                $ helm repo add grafana https://grafana.github.io/helm-chart
          $ helm repo update

          我們這里創(chuàng)建一個(gè) loki-values.yaml 文件來配置 Loki Helm Chart:

                
                # loki-values.yaml
          loki:
            commonConfig:
              replication_factor: 1
            auth_enabled: false
            storage:
              type: "filesystem"
          singleBinary:
            replicas: 1
            persistence:
              enabled: true
              size: 10Gi
              storageClass: cfsauto
          monitoring:
            lokiCanary:
              enabled: false
            selfMonitoring:
              grafanaAgent:
                installOperator: false
          test:
            enabled: false
          gateway:
            ingress:
              enabled: true
              ingressClassName: nginx
              tls: []
              hosts:
                - host: loki.k8s.local
                  paths:
                    - path: /
                      pathType: Prefix

          然后直接使用下面的命令一鍵部署 Loki 即可:

                
                $ helm upgrade --install loki grafana/loki -f loki-values.yaml --namespace kube-otel
          $ kubectl get pods -n kube-otel -l app.kubernetes.io/instance=loki
          NAME                            READY   STATUS    RESTARTS   AGE
          loki-0                          1/1     Running   0          3m52s
          loki-gateway-5ffc9fbbf5-m5q75   1/1     Running   0          8m42s
          $ kubectl get ingress -n kube-otel
          NAME                 CLASS   HOSTS               ADDRESS       PORTS   AGE
          loki-gateway         nginx   loki.k8s.local      10.98.12.94   80      11m

          啟用 filelog 接收器

          接下來我們就需要配置 OpenTelemetry Collector 來將日志數(shù)據(jù)發(fā)送到 Loki 中,首先更新 otel-collector-ds-values.yaml 文件,我們需要添加一個(gè) Loki 的導(dǎo)出器,并開啟 filelogreceiver 接收器:

                
                # otel-collector-ds-values.yaml
          mode: daemonset

          presets:
            hostMetrics:
              enabled: true
            kubernetesAttributes:
              enabled: true
            kubeletMetrics:
              enabled: true
            # 啟用 filelogreceiver 收集器
            logsCollection:
              enabled: true

          config:
            exporters:
              loki:
                endpoint: http://loki-gateway/loki/api/v1/push
                timeout: 10s # 超時(shí)時(shí)間
                read_buffer_size: 200
                write_buffer_size: 100
                retry_on_failure: # 配置重試
                  enabled: true
                  initial_interval: 10s # 初始間隔
                  max_interval: 60s # 最大間隔
                  max_elapsed_time: 10m # 最大時(shí)間
                default_labels_enabled:
                  exporter: false

            processors:
              resource:
                attributes:
                  - action: insert
                    key: loki.resource.labels
                    value: k8s.namespace.name,k8s.pod.name,k8s.container.name

            service:
              pipelines:
                logs:
                  exporters:
                    - loki
                  processors:
                    - memory_limiter
                    - k8sattributes
                    - resource
                    - batch

          然后重新更新 OpenTelemetry Collector DaemonSet:

                
                $ helm upgrade --install opentelemetry-collector ./opentelemetry-collector -f otel-ds-values.yaml --namespace kube-otel --create-namespace

          同樣更新后查看完整的配置信息,使用命令 kubectl get cm -n opentelemetry-collector-agent -oyaml

                
                exporters:
            logging:
              loglevel: debug
            loki:
              endpoint: http://loki-gateway/loki/api/v1/push
              timeout: 10s # 超時(shí)時(shí)間
              read_buffer_size: 200
              write_buffer_size: 100
              retry_on_failure: # 配置重試
                enabled: true
                initial_interval: 10s # 初始間隔
                max_interval: 60s # 最大間隔
                max_elapsed_time: 10m # 最大時(shí)間
              default_labels_enabled:
                exporter: false
          extensions:
            health_check: {}
            memory_ballast:
              size_in_percentage: 40
          processors:
            batch: {}
            k8sattributes:
              extract:
                metadata:
                  - k8s.namespace.name
                  - k8s.deployment.name
                  - k8s.statefulset.name
                  - k8s.daemonset.name
                  - k8s.cronjob.name
                  - k8s.job.name
                  - k8s.node.name
                  - k8s.pod.name
                  - k8s.pod.uid
                  - k8s.pod.start_time
              filter:
                node_from_env_var: K8S_NODE_NAME
              passthrough: false
              pod_association:
                - sources:
                    - from: resource_attribute
                      name: k8s.pod.ip
                - sources:
                    - from: resource_attribute
                      name: k8s.pod.uid
                - sources:
                    - from: connection
            memory_limiter:
              check_interval: 5s
              limit_percentage: 80
              spike_limit_percentage: 25
            resource:
              attributes:
                - action: insert
                  key: loki.resource.labels
                  value: k8s.namespace.name,k8s.pod.name,k8s.container.name
          receivers:
            filelog:
              exclude:
                - /var/log/pods/kube-otel_opentelemetry-collector*_*/opentelemetry-collector/*.log
              include:
                - /var/log/pods/*/*/*.log
              include_file_name: false
              include_file_path: true
              operators:
                - id: get-format
                  routes:
                    - expr: body matches "^\\{"
                      output: parser-docker
                    - expr: body matches "^[^ Z]+ "
                      output: parser-crio
                    - expr: body matches "^[^ Z]+Z"
                      output: parser-containerd
                  type: router
                - id: parser-crio
                  regex: ^(?P<time>[^ Z]+) (?P<stream>stdout|stderr) (?P<logtag>[^ ]*) ?(?P<log>.*)$
                  timestamp:
                    layout: 2006-01-02T15:04:05.999999999Z07:00
                    layout_type: gotime
                    parse_from: attributes.time
                  type: regex_parser
                - combine_field: attributes.log
                  combine_with: ""
                  id: crio-recombine
                  is_last_entry: attributes.logtag == 'F'
                  max_log_size: 102400
                  output: extract_metadata_from_filepath
                  source_identifier: attributes["log.file.path"]
                  type: recombine
                - id: parser-containerd
                  regex: ^(?P<time>[^ ^Z]+Z) (?P<stream>stdout|stderr) (?P<logtag>[^ ]*) ?(?P<log>.*)$
                  timestamp:
                    layout: "%Y-%m-%dT%H:%M:%S.%LZ"
                    parse_from: attributes.time
                  type: regex_parser
                - combine_field: attributes.log
                  combine_with: ""
                  id: containerd-recombine
                  is_last_entry: attributes.logtag == 'F'
                  max_log_size: 102400
                  output: extract_metadata_from_filepath
                  source_identifier: attributes["log.file.path"]
                  type: recombine
                - id: parser-docker
                  output: extract_metadata_from_filepath
                  timestamp:
                    layout: "%Y-%m-%dT%H:%M:%S.%LZ"
                    parse_from: attributes.time
                  type: json_parser
                - id: extract_metadata_from_filepath
                  parse_from: attributes["log.file.path"]
                  regex: ^.*\/(?P<namespace>[^_]+)_(?P<pod_name>[^_]+)_(?P<uid>[a-f0-9\-]+)\/(?P<container_name>[^\._]+)\/(?P<restart_count>\d+)\.log$
                  type: regex_parser
                - from: attributes.stream
                  to: attributes["log.iostream"]
                  type: move
                - from: attributes.container_name
                  to: resource["k8s.container.name"]
                  type: move
                - from: attributes.namespace
                  to: resource["k8s.namespace.name"]
                  type: move
                - from: attributes.pod_name
                  to: resource["k8s.pod.name"]
                  type: move
                - from: attributes.restart_count
                  to: resource["k8s.container.restart_count"]
                  type: move
                - from: attributes.uid
                  to: resource["k8s.pod.uid"]
                  type: move
                - from: attributes.log
                  to: body
                  type: move
              start_at: beginning
            otlp:
              protocols:
                grpc:
                  endpoint: ${env:MY_POD_IP}:4317
                http:
                  endpoint: ${env:MY_POD_IP}:4318
          service:
            extensions:
              - health_check
              - memory_ballast
            pipelines:
              logs:
                exporters:
                  - loki
                processors:
                  - memory_limiter
                  - k8sattributes
                  - resource
                  - batch
                receivers:
                  - otlp
                  - filelog
          # 同樣只保留了和 logs 相關(guān)的配置,其他省略......

          我們新增加了一個(gè) loki 的導(dǎo)出器以及 filelog 接收器。

          loki 導(dǎo)出器

          該導(dǎo)出器是通過 HTTP 將數(shù)據(jù)導(dǎo)出到 Loki。該導(dǎo)出器可以做以下一些配置:

          • endpoint:Loki 的 HTTP 端點(diǎn)地址(如 http://loki:3100/loki/api/v1/push)。
          • default_labels_enabled(可選):允許禁用默認(rèn)標(biāo)簽的映射:exporterjobinstancelevel。如果省略default_labels_enabled,則會(huì)添加默認(rèn)標(biāo)簽。如果在 default_labels_enabled 中省略了其中一個(gè)標(biāo)簽,則會(huì)添加該標(biāo)簽。

          如果禁用了所有默認(rèn)標(biāo)簽,并且沒有添加其他標(biāo)簽,則日志條目將被丟棄,因?yàn)橹辽傩枰嬖谝粋€(gè)標(biāo)簽才能成功將日志記錄寫入 Loki 中。指標(biāo) otelcol_lokiexporter_send_failed_due_to_missing_labels 將會(huì)顯示由于未指定標(biāo)簽而被丟棄的日志記錄數(shù)量。

          Loki 導(dǎo)出器可以將 OTLP 資源和日志屬性轉(zhuǎn)換為 Loki 標(biāo)簽,并對(duì)其進(jìn)行索引。為此,需要配置提示,指定應(yīng)將哪些屬性設(shè)置為標(biāo)簽。提示本身就是屬性,在導(dǎo)出到 Loki 時(shí)將被忽略。以下示例使用 attributes 處理器提示 Loki 導(dǎo)出器將 event.domain 屬性設(shè)置為標(biāo)簽,并使用 resource 處理器提示 Loki 導(dǎo)出器將 service.name 設(shè)置為標(biāo)簽。

                
                processors:
            attributes:
              actions:
                - action: insert
                  key: loki.attribute.labels
                  value: event.domain

            resource:
              attributes:
                - action: insert
                  key: loki.resource.labels
                  value: service.name

          除非通過 default_labels_enabled 設(shè)置禁用,默認(rèn)標(biāo)簽始終會(huì)被設(shè)置。

          • job=service.namespace/service.name
          • instance=service.instance.id
          • exporter=OTLP
          • level=severity

          如果 service.nameservice.namespace 存在,那么設(shè)置 job=service.namespace/service.name。如果 service.name 存在且 service.namespace 不存在,則會(huì)設(shè)置 job=service.name。如果 service.name 不存在且 service.namespace 存在,則不會(huì)設(shè)置 job 標(biāo)簽。如果存在 service.instance.id 則設(shè)置 instance=service.instance.id。如果 service.instance.id 不存在,則不設(shè)置 instance 標(biāo)簽。

          我們這里的完整配置如下:

                
                loki:
            endpoint: http://loki-gateway/loki/api/v1/push
            timeout: 10s # 超時(shí)時(shí)間
            read_buffer_size: 200
            write_buffer_size: 100
            retry_on_failure: # 配置重試
              enabled: true
              initial_interval: 10s # 初始間隔
              max_interval: 60s # 最大間隔
              max_elapsed_time: 10m # 最大時(shí)間

          我們這里配置了超時(shí)時(shí)間,讀寫緩沖區(qū)大小,發(fā)送隊(duì)列,重試等。

          read_buffer_sizewrite_buffer_size 字段分別指定了 OpenTelemetry 導(dǎo)出器的讀取和寫入緩沖區(qū)的大小。這些緩沖區(qū)用于在發(fā)送數(shù)據(jù)之前緩存數(shù)據(jù),以提高發(fā)送效率和可靠性。

          read_buffer_size 字段指定了導(dǎo)出器從數(shù)據(jù)源讀取數(shù)據(jù)時(shí)使用的緩沖區(qū)大小。如果數(shù)據(jù)源產(chǎn)生的數(shù)據(jù)量超過了緩沖區(qū)的大小,導(dǎo)出器將分批讀取數(shù)據(jù)并將其緩存到緩沖區(qū)中,直到緩沖區(qū)被填滿或數(shù)據(jù)源沒有更多數(shù)據(jù)為止。

          write_buffer_size 字段指定了導(dǎo)出器將指標(biāo)數(shù)據(jù)寫入目標(biāo)時(shí)使用的緩沖區(qū)大小。如果導(dǎo)出器產(chǎn)生的數(shù)據(jù)量超過了緩沖區(qū)的大小,導(dǎo)出器將分批將數(shù)據(jù)寫入目標(biāo),并將其緩存到緩沖區(qū)中,直到緩沖區(qū)被填滿或目標(biāo)不可用為止。

          通過配置這些緩沖區(qū)的大小,您可以控制 OpenTelemetry 導(dǎo)出器的性能和可靠性。如果您的數(shù)據(jù)源產(chǎn)生的數(shù)據(jù)量很大,可以增加 read_buffer_sizewrite_buffer_size 的大小,以提高導(dǎo)出器的吞吐量和效率。如果您的目標(biāo)不太穩(wěn)定或網(wǎng)絡(luò)不太可靠,可以減小 write_buffer_size 的大小,以減少數(shù)據(jù)丟失的風(fēng)險(xiǎn)。

          另外添加了一個(gè)resource的處理器,將 k8s.namespace.namek8s.pod.namek8s.container.name 轉(zhuǎn)換為 Loki 標(biāo)簽,這樣我們就可以在 Loki 中對(duì)其進(jìn)行索引了。

                
                resource:
            attributes:
              - action: insert
                key: loki.resource.labels
                value: k8s.namespace.name,k8s.pod.name,k8s.container.name

          filelog 接收器

          該接收器用于從文件中收集并解析日志數(shù)據(jù),它會(huì)從指定的文件中讀取日志數(shù)據(jù),然后將其發(fā)送到 OpenTelemetry Collector 中。

          我們這里對(duì)該接收器的配置如下所示:

                
                filelog:
            exclude:
              - /var/log/pods/kube-otel_opentelemetry-collector*_*/opentelemetry-collector/*.log
            include:
              - /var/log/pods/*/*/*.log
            include_file_name: false
            include_file_path: true
            operators:
              - id: get-format
                routes:
                  - expr: body matches "^\\{"
                    output: parser-docker
                  - expr: body matches "^[^ Z]+ "
                    output: parser-crio
                  - expr: body matches "^[^ Z]+Z"
                    output: parser-containerd
                type: router
              - id: parser-crio
                regex: ^(?P<time>[^ Z]+) (?P<stream>stdout|stderr) (?P<logtag>[^ ]*) ?(?P<log>.*)$
                timestamp:
                  layout: 2006-01-02T15:04:05.999999999Z07:00
                  layout_type: gotime
                  parse_from: attributes.time
                type: regex_parser
              - combine_field: attributes.log
                combine_with: ""
                id: crio-recombine
                is_last_entry: attributes.logtag == 'F'
                max_log_size: 102400
                output: extract_metadata_from_filepath
                source_identifier: attributes["log.file.path"]
                type: recombine
              - id: parser-containerd
                regex: ^(?P<time>[^ ^Z]+Z) (?P<stream>stdout|stderr) (?P<logtag>[^ ]*) ?(?P<log>.*)$
                timestamp:
                  layout: "%Y-%m-%dT%H:%M:%S.%LZ"
                  parse_from: attributes.time
                type: regex_parser
              - combine_field: attributes.log
                combine_with: ""
                id: containerd-recombine
                is_last_entry: attributes.logtag == 'F'
                max_log_size: 102400
                output: extract_metadata_from_filepath
                source_identifier: attributes["log.file.path"]
                type: recombine
              - id: parser-docker
                output: extract_metadata_from_filepath
                timestamp:
                  layout: "%Y-%m-%dT%H:%M:%S.%LZ"
                  parse_from: attributes.time
                type: json_parser
              - id: extract_metadata_from_filepath
                parse_from: attributes["log.file.path"]
                regex: ^.*\/(?P<namespace>[^_]+)_(?P<pod_name>[^_]+)_(?P<uid>[a-f0-9\-]+)\/(?P<container_name>[^\._]+)\/(?P<restart_count>\d+)\.log$
                type: regex_parser
              - from: attributes.stream
                to: attributes["log.iostream"]
                type: move
              - from: attributes.container_name
                to: resource["k8s.container.name"]
                type: move
              - from: attributes.namespace
                to: resource["k8s.namespace.name"]
                type: move
              - from: attributes.pod_name
                to: resource["k8s.pod.name"]
                type: move
              - from: attributes.restart_count
                to: resource["k8s.container.restart_count"]
                type: move
              - from: attributes.uid
                to: resource["k8s.pod.uid"]
                type: move
              - from: attributes.log
                to: body
                type: move
            start_at: beginning

          可以看到配置非常長,首先通過 exclude 排除一些不需要收集的日志文件,然后通過 include 指定了需要收集的日志文件,由于我們的 Kubernetes 集群是基于 Containerd 容器運(yùn)行時(shí)的,所以采集的日志目錄為 /var/log/pods/*/*/*.log,然后通過 include_file_path 來指定是否將文件路徑添加為屬性 log.file.pathinclude_file_name 指定是否將文件名添加為屬性 log.file.name

          start_at 表示在啟動(dòng)時(shí),從文件的哪個(gè)位置開始讀取日志。選項(xiàng)有 beginningend,默認(rèn)為 end

          然后就是最重要的 operators 屬性,用來指定如何處理日志文件,運(yùn)算符是日志處理的最基本單元。每個(gè)運(yùn)算符都完成一個(gè)單一的責(zé)任,比如從文件中讀取行,或者從字段中解析 JSON。然后,這些運(yùn)算符被鏈接在一起,形成一個(gè)管道,以實(shí)現(xiàn)所需的結(jié)果。

          例如用戶可以使用 file_input 操作符從文件中讀取日志行。然后,這個(gè)操作的結(jié)果可以發(fā)送到 regex_parser 操作符,根據(jù)正則表達(dá)式創(chuàng)建字段。最后,這些結(jié)果可以發(fā)送到 file_output 操作符,將日志寫入到磁盤上的文件中。

          我們這里首先配置了一個(gè) router 操作符:

                
                id: get-format
          routes:
            - expr: body matches "^\\{"
              output: parser-docker
            - expr: body matches "^[^ Z]+ "
              output: parser-crio
            - expr: body matches "^[^ Z]+Z"
              output: parser-containerd
          type: router

          該操作符允許根據(jù)日志內(nèi)容動(dòng)態(tài)路由日志,我們這里是 Containerd 的容器運(yùn)行時(shí),產(chǎn)生的日志數(shù)據(jù)可以匹配 body matches "^[^ Z]+Z",然后將數(shù)據(jù)路由到 parser-containerd 操作符。

                
                id: parser-containerd
          regex: ^(?P<time>[^ ^Z]+Z) (?P<stream>stdout|stderr) (?P<logtag>[^ ]*) ?(?P<log>.*)$
          timestamp:
            layout: "%Y-%m-%dT%H:%M:%S.%LZ"
            parse_from: attributes.time
          type: regex_parser

          parser-containerd 是一個(gè) regex_parser 操作符,它使用指定的正則表達(dá)式來解析前面路由過來的日志數(shù)據(jù),然后會(huì)將結(jié)果存儲(chǔ)在 timestreamlogtaglog 等屬性中,并格式化 timestamp 時(shí)間戳。

          接下來再通過 recombine 操作符將連續(xù)的日志組合成單個(gè)日志。

                
                combine_field: attributes.log
          combine_with: ""
          id: containerd-recombine
          is_last_entry: attributes.logtag == 'F'
          max_log_size: 102400
          output: extract_metadata_from_filepath
          source_identifier: attributes["log.file.path"]
          type: recombine

          經(jīng)過上面處理后進(jìn)入 extract_metadata_from_filepath 這個(gè)操作符,該操作符使用正則表達(dá)式從文件路徑中提取元數(shù)據(jù),然后將其存儲(chǔ)在 namespacepod_nameuidcontainer_namerestart_count 等屬性中。

                
                id: extract_metadata_from_filepath
          parse_from: attributes["log.file.path"]
          regex: ^.*\/(?P<namespace>[^_]+)_(?P<pod_name>[^_]+)_(?P<uid>[a-f0-9\-]+)\/(?P<container_name>[^\._]+)\/(?P<restart_count>\d+)\.log$
          type: regex_parser

          接下來就是通過 move 操作符將一個(gè)字段從一個(gè)位置移動(dòng)(或重命名)到另一個(gè)位置。

                
                - from: attributes.stream
            to: attributes["log.iostream"]
            type: move
          - from: attributes.container_name
            to: resource["k8s.container.name"]
            type: move
          - from: attributes.namespace
            to: resource["k8s.namespace.name"]
            type: move
          - from: attributes.pod_name
            to: resource["k8s.pod.name"]
            type: move
          - from: attributes.restart_count
            to: resource["k8s.container.restart_count"]
            type: move
          - from: attributes.uid
            to: resource["k8s.pod.uid"]
            type: move
          - from: attributes.log
            to: body
            type: move

          最后我們可以將 Loki 數(shù)據(jù)源添加到 Grafana 中:

          26fae9c92a4ddc593cdcbdf600ecd367.webpLoki 數(shù)據(jù)源

          然后在 Explorer 頁面切換到 Loki 數(shù)據(jù)源下面就可以看到 Loki 中的日志數(shù)據(jù)了:

          073f619c8296f80c74db6bba63403748.webpLoki 日志

          啟用 k8sobject 接收器

          同樣對(duì)于 Gateway 模式的采集器我們還可以去開啟 k8sobject 接收器來采集 Kubernetes Events 數(shù)據(jù),然后更新 otel-collector-deploy-values.yaml 文件:

                
                # otel-collector-deploy-values.yaml
          mode: deployment

          # 我們只需要一個(gè)收集器 - 多了就會(huì)產(chǎn)生重復(fù)數(shù)據(jù)
          replicaCount: 1

          presets:
            clusterMetrics:
              enabled: true
            kubernetesEvents:
              enabled: true

          config:
            exporters:
              loki:
                endpoint: http://loki-gateway/loki/api/v1/push
                timeout: 10s # 超時(shí)時(shí)間
                read_buffer_size: 200
                write_buffer_size: 100
                retry_on_failure: # 配置重試
                  enabled: true
                  initial_interval: 10s # 初始間隔
                  max_interval: 60s # 最大間隔
                  max_elapsed_time: 10m # 最大時(shí)間

            service:
              pipelines:
                logs:
                  exporters:
                    - loki

          然后重新更新 OpenTelemetry Collector Deployment:

                
                $ helm upgrade --install opentelemetry-collector-cluster ./opentelemetry-collector -f otel-collector-deploy-values.yaml --namespace kube-otel --create-namespace

          這里我們開啟了 kubernetesEvents 預(yù)設(shè),對(duì)應(yīng)的配置如下所示:

                
                k8sobjects:
            objects:
              - group: events.k8s.io
                mode: watch
                name: events

          k8sobjects 接收器可以用來拉取或 Watch Kubernetes API 服務(wù)器中的對(duì)象,我們這里通過 groupmodename 來指定要拉取的 Kubernetes Events 對(duì)象。

          最后我們也可以在 Loki 中查找到對(duì)應(yīng)的 Events 日志數(shù)據(jù)。

          9e416bd0060e92730592da0430610822.webp
          瀏覽 136
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  爱爱网免费视频 | 亚洲AV成人无码精电影在线 | 波多野结衣一区二区三区中文字幕 | 在线看片日韩 | 国产女女百合在线播放 |