Kev tsiv teb tsaws chaw los ntawm Nginx mus rau Envoy Proxy

Nyob zoo, Habr! Kuv coj tuaj rau koj mloog ib tug neeg txhais lus ntawm tus ncej: Kev tsiv teb tsaws chaw los ntawm Nginx mus rau Envoy Proxy.

Envoy yog qhov ua tau zoo tshaj plaws faib cov neeg rau zaub mov (sau hauv C ++) tsim los rau cov kev pabcuam thiab kev siv tus kheej, nws tseem yog lub tsheb npav sib txuas lus thiab "cov ntaub ntawv dav dav dav dav" tsim los rau loj microservice "service mesh" architectures. Thaum tsim nws, cov kev daws teeb meem tshwm sim thaum lub sij hawm tsim cov servers xws li NGINX, HAProxy, hardware load balancers thiab cloud load balancers tau muab coj los rau hauv tus account. Envoy ua haujlwm nrog rau txhua daim ntawv thov thiab paub daws teeb meem lub network los muab kev ua haujlwm sib xws tsis hais lub platform. Thaum tag nrho cov kev pabcuam kev thauj mus los hauv cov txheej txheem ntws los ntawm Envoy mesh, nws dhau los ua ib qho yooj yim rau pom cov teeb meem nrog kev saib xyuas zoo ib yam, kho qhov kev ua tau zoo tag nrho, thiab ntxiv cov haujlwm tseem ceeb hauv qhov chaw tshwj xeeb.

Nta

  • Tawm-ntawm-tus txheej txheem architecture: tus neeg sawv cev yog tus kheej-muaj, cov neeg ua haujlwm siab uas siv RAM me me. Nws ua haujlwm ua ke nrog txhua yam lus thov lossis lub moj khaum.
  • http/2 thiab grpc kev txhawb nqa: tus neeg sawv cev muaj thawj chav kawm http/2 thiab grpc kev txhawb nqa rau kev sib txuas nkag thiab tawm. Qhov no yog lub npe pob tshab los ntawm http/1.1 rau http/2.
  • Advanced Load Balancing: tus neeg sawv cev txhawb nqa kev ntsuas siab tshaj plaws nrog rau kev rov ua haujlwm tsis siv neeg, kev sib tsoo, kev txwv thoob ntiaj teb, thov shadowing, cheeb tsam hauv zos load ntsuas, thiab lwm yam.
  • Configuration Management API: envoy muab API ruaj khov rau kev tswj hwm koj qhov kev teeb tsa.
  • Observability: Sib sib zog nqus soj ntsuam ntawm L7 tsheb, ib haiv neeg txhawb rau faib tracing thiab observability ntawm mongodb, dynamodb thiab ntau lwm yam kev siv.

Kauj ruam 1 - Piv txwv NGINX Config

Tsab ntawv no siv cov ntaub ntawv tshwj xeeb crafted nginx.conf ib, raws li qhov piv txwv tag nrho los ntawm NGINX Wiki. Koj tuaj yeem saib cov kev teeb tsa hauv tus editor los ntawm kev qhib nginx.conf ib

nginx qhov chaw config

user  www www;
pid /var/run/nginx.pid;
worker_processes  2;

events {
  worker_connections   2000;
}

http {
  gzip on;
  gzip_min_length  1100;
  gzip_buffers     4 8k;
  gzip_types       text/plain;

  log_format main      '$remote_addr - $remote_user [$time_local]  '
    '"$request" $status $bytes_sent '
    '"$http_referer" "$http_user_agent" '
    '"$gzip_ratio"';

  log_format download  '$remote_addr - $remote_user [$time_local]  '
    '"$request" $status $bytes_sent '
    '"$http_referer" "$http_user_agent" '
    '"$http_range" "$sent_http_content_range"';

  upstream targetCluster {
    172.18.0.3:80;
    172.18.0.4:80;
  }

  server {
    listen        8080;
    server_name   one.example.com  www.one.example.com;

    access_log   /var/log/nginx.access_log  main;
    error_log  /var/log/nginx.error_log  info;

    location / {
      proxy_pass         http://targetCluster/;
      proxy_redirect     off;

      proxy_set_header   Host             $host;
      proxy_set_header   X-Real-IP        $remote_addr;
    }
  }
}

NGINX configurations feem ntau muaj peb lub ntsiab lus tseem ceeb:

  1. Configuring NGINX server, log qauv thiab Gzip functionality. Qhov no txhais tau hais tias thoob ntiaj teb hauv txhua kis.
  2. Configuring NGINX kom txais kev thov rau tus tswv tsev ib.example.com ua 8080.
  3. Teeb tsa lub hom phiaj qhov chaw, yuav ua li cas tswj kev khiav tsheb rau qhov sib txawv ntawm URL.

Tsis yog txhua qhov kev teeb tsa yuav siv rau Envoy Proxy, thiab koj tsis tas yuav teeb tsa qee qhov chaw. Envoy Proxy muaj plaub yam tseem ceeb, uas txhawb nqa cov txheej txheem tseem ceeb uas muab los ntawm NGINX. Lub hauv paus yog:

  • Cov neeg mloog: Lawv txiav txim siab li cas Envoy Proxy lees txais cov lus thov tuaj. Envoy Proxy tam sim no tsuas yog txhawb nqa TCP raws li cov neeg mloog. Thaum ib qho kev sib txuas tau tsim, nws raug xa mus rau cov txheej txheem lim rau kev ua haujlwm.
  • Cov lim dej: Lawv yog ib feem ntawm cov kav raj xa dej uas tuaj yeem ua cov ntaub ntawv nkag thiab tawm. Cov haujlwm no suav nrog cov ntxaij lim dej xws li Gzip, uas compresses cov ntaub ntawv ua ntej xa mus rau tus neeg siv khoom.
  • Routers: Lawv xa cov tsheb mus rau qhov chaw uas xav tau, txhais tau tias yog pawg.
  • Pawg: Lawv txhais qhov kawg ntawm kev khiav tsheb thiab kev teeb tsa.

Peb yuav siv plaub yam no los tsim tus Envoy Proxy teeb tsa kom phim ib qho kev teeb tsa NGINX tshwj xeeb. Envoy lub hom phiaj yog ua haujlwm nrog APIs thiab dynamic configuration. Nyob rau hauv rooj plaub no, lub hauv paus configuration yuav siv static, hard-coded nqis los ntawm NGINX.

Kauj ruam 2 - NGINX Configuration

Thawj tshooj nginx.conf ib txhais qee qhov NGINX sab hauv uas yuav tsum tau teeb tsa.

Cov neeg ua haujlwm sib txuas

Cov kev teeb tsa hauv qab no txiav txim siab tus naj npawb ntawm cov neeg ua haujlwm cov txheej txheem thiab kev sib txuas. Qhov no qhia tias NGINX yuav ntsuas li cas kom tau raws li qhov xav tau.

worker_processes  2;

events {
  worker_connections   2000;
}

Envoy Proxy tswj kev ua haujlwm thiab kev sib txuas hauv ntau txoj hauv kev.

Envoy tsim ib tus neeg ua haujlwm xov rau txhua lub xov tooj kho vajtse hauv qhov system. Txhua tus neeg ua haujlwm xov ua haujlwm tsis yog thaiv qhov xwm txheej uas yog lub luag haujlwm rau

  1. Mloog txhua tus mloog
  2. Txais kev sib txuas tshiab
  3. Tsim ib txheej lim rau kev sib txuas
  4. Ua txhua yam haujlwm I / O thaum lub neej ntawm kev sib txuas.

Tag nrho cov kev sib txuas txuas ntxiv yog ua tiav hauv cov neeg ua haujlwm xov, suav nrog txhua tus cwj pwm xa mus.

Rau txhua tus neeg ua haujlwm xov hauv Envoy, muaj lub pas dej sib txuas. Yog li HTTP / 2 kev sib txuas pas dej tsuas yog tsim ib qho kev sib txuas rau ib tus tswv tsev sab nraud ntawm ib lub sijhawm, yog tias muaj plaub tus neeg ua haujlwm xov yuav muaj plaub HTTP / 2 kev sib txuas rau ib tus tswv tsev sab nraud hauv lub xeev ruaj khov. Los ntawm khaws txhua yam hauv ib tus neeg ua haujlwm xov, yuav luag txhua tus lej tuaj yeem sau yam tsis muaj kev thaiv, zoo li nws yog ib leeg xov. Yog tias cov neeg ua haujlwm sib txuas ntau dua li qhov tsim nyog, qhov no tuaj yeem ua rau lub cim xeeb khib nyiab, tsim kom muaj ntau qhov kev sib txuas tsis ua haujlwm, thiab txo cov sij hawm sib txuas rov qab mus rau lub pas dej.

Yog xav paub ntxiv mus saib Envoy Proxy blog.

HTTP Configuration

NGINX configuration block hauv qab no txhais HTTP chaw xws li:

  • Dab tsi mime hom kev txhawb nqa
  • Default Timeouts
  • Gzip Configuration

Koj tuaj yeem hloov kho cov yam no siv cov ntxaij lim dej hauv Envoy Proxy, uas peb yuav tham tom qab.

Kauj ruam 3 - Server Configuration

Hauv HTTP configuration block, NGINX configuration qhia meej kom mloog ntawm chaw nres nkoj 8080 thiab teb rau cov lus thov tuaj rau cov thawj. ib.example.com ΠΈ www.one.example.com.

 server {
    listen        8080;
    server_name   one.example.com  www.one.example.com;

Nyob rau hauv Envoy, nws yog tswj los ntawm Listeners.

Tus sawv cev mloog

Qhov tseem ceeb tshaj plaws ntawm kev pib nrog Envoy Proxy yog txhais koj cov neeg mloog. Koj yuav tsum tsim cov ntaub ntawv teeb tsa uas piav qhia koj yuav ua li cas thiaj li khiav Envoy piv txwv.

Cov snippet hauv qab no yuav tsim ib tus neeg mloog tshiab thiab khi rau qhov chaw nres nkoj 8080. Qhov kev teeb tsa qhia Envoy Proxy qhov chaw nres nkoj uas nws yuav tsum khi rau kev thov tuaj.

Envoy Proxy siv YAML cim rau nws qhov kev teeb tsa. Rau ib qho kev taw qhia rau cov ntawv sau no, saib ntawm no txuas.

Copy to Editorstatic_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 8080 }

Tsis tas yuav txhais server_name, txij li Envoy Proxy cov ntxaij lim dej yuav daws qhov no.

Kauj ruam 4 - Qhov chaw Configuration

Thaum qhov kev thov tuaj rau hauv NGINX, qhov chaw thaiv qhov chaw txiav txim siab yuav ua li cas thiab qhov twg yuav khiav tsheb mus los. Hauv cov kab lus hauv qab no, tag nrho cov tsheb khiav mus rau qhov chaw raug xa mus rau ib qho dej ntws (tus neeg txhais lus ceeb toom: cov dej ntws feem ntau yog cov neeg siv khoom siv) pawg npe hu ua targetCluster. Lub upstream pawg txhais cov nodes uas yuav tsum ua raws li qhov kev thov. Peb yuav tham txog qhov no hauv kauj ruam tom ntej.

location / {
    proxy_pass         http://targetCluster/;
    proxy_redirect     off;

    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
}

Ntawm Envoy, Lim ua qhov no.

Envoy Filters

Rau qhov kev teeb tsa zoo li qub, cov ntxaij lim dej txiav txim siab yuav ua li cas thiaj li ua tau cov lus thov tuaj. Hauv qhov no peb teeb cov ntxaij lim dej uas phim server_names hauv cov kauj ruam dhau los. Thaum cov kev thov tuaj txog tuaj txog uas phim qee qhov chaw thiab cov kev, tsheb khiav mus rau pawg. Qhov no yog qhov sib npaug ntawm NGINX hauv qab-up configuration.

Copy to Editor    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains:
                - "one.example.com"
                - "www.one.example.com"
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: targetCluster
          http_filters:
          - name: envoy.router

lub npe envoy.http_connection_manager yog ib lub lim dej built-in hauv Envoy Proxy. Lwm cov lim dej muaj xws li Redis, Mongo, TCP. Koj tuaj yeem pom cov npe tiav ntawm cov ntaub ntawv.

Yog xav paub ntxiv txog lwm cov kev cai thauj khoom sib npaug, mus saib Envoy Cov Ntaub Ntawv.

Kauj Ruam 5 - Tso cai thiab Upstream Configuration

Hauv NGINX, qhov kev teeb tsa saum toj kawg nkaus txhais cov txheej txheem ntawm lub hom phiaj servers uas yuav ua rau kev khiav tsheb. Hauv qhov no, ob pawg tau raug xaiv.

  upstream targetCluster {
    172.18.0.3:80;
    172.18.0.4:80;
  }

Hauv Envoy, qhov no yog tswj los ntawm pawg.

Envoy Pawg

Qhov sib npaug upstream yog txhais ua pawg. Hauv qhov no, cov tswv tsev uas yuav ua haujlwm rau kev khiav tsheb tau raug txheeb xyuas. Txoj kev uas cov tswv tau nkag mus, xws li ncua sij hawm, txhais tau tias yog pawg teeb tsa. Qhov no tso cai rau kev tswj xyuas ntau dua ntawm cov khoom xws li latency thiab load ntsuas.

Copy to Editor  clusters:
  - name: targetCluster
    connect_timeout: 0.25s
    type: STRICT_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    hosts: [
      { socket_address: { address: 172.18.0.3, port_value: 80 }},
      { socket_address: { address: 172.18.0.4, port_value: 80 }}
    ]

Thaum siv cov kev pabcuam nrhiav pom STRICT_DNS Envoy yuav tsis tu ncua thiab asynchronously daws cov teeb meem DNS lub hom phiaj. Txhua tus IP chaw nyob xa rov qab los ntawm qhov txiaj ntsig DNS yuav raug suav hais tias yog tus tswv tsev pom tseeb hauv pawg upstream. Qhov no txhais tau hais tias yog tias qhov kev thov rov qab ob qhov chaw nyob IP, Envoy yuav xav tias muaj ob lub tswv cuab hauv pawg, thiab ob qho tib si yuav tsum tau thauj khoom sib npaug. Yog tias tus tswv tsev raug tshem tawm ntawm qhov tshwm sim, Envoy yuav xav tias nws tsis muaj lawm thiab yuav rub cov tsheb khiav los ntawm cov pas dej sib txuas uas twb muaj lawm.

Yog xav paub ntxiv saib Envoy proxy cov ntaub ntawv.

Kauj ruam 6 - Nkag mus thiab yuam kev

Qhov kawg configuration yog sau npe. Tsis txhob thawb cov ntawv yuam kev rau disk, Envoy Proxy siv cov huab-raws li txoj hauv kev. Tag nrho cov ntaub ntawv thov raug tso tawm rau stdout ΠΈ stderr.

Thaum cov neeg siv ua ib qho kev thov, nkag mus rau cov ntawv teev npe yog xaiv tau thiab raug kaw los ntawm lub neej ntawd. Txhawm rau pab kom nkag tau nkag rau HTTP thov, qhib qhov kev teeb tsa access_log rau tus thawj tswj kev sib txuas HTTP. Txoj kev tuaj yeem yog ib qho cuab yeej xws li stdout, los yog ib cov ntaub ntawv ntawm disk, nyob ntawm seb koj xav tau.

Cov kev teeb tsa hauv qab no yuav hloov pauv tag nrho cov ntawv nkag mus rau stdout (tus neeg txhais lus ceeb toom - stdout yuav tsum tau siv envoy hauv docker. Yog tias siv tsis muaj docker, ces hloov /dev/stdout nrog txoj hauv kev mus rau cov ntaub ntawv tsis tu ncua). Luam cov snippet mus rau seem configuration rau tus tswj kev sib txuas:

Copy to Clipboardaccess_log:
- name: envoy.file_access_log
  config:
    path: "/dev/stdout"

Cov txiaj ntsig yuav tsum zoo li no:

      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          access_log:
          - name: envoy.file_access_log
            config:
              path: "/dev/stdout"
          route_config:

Los ntawm lub neej ntawd, Envoy muaj txoj hlua hom uas suav nrog cov ntsiab lus ntawm HTTP thov:

[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"n

Qhov tshwm sim ntawm txoj hlua hom ntawv no yog:

[2018-11-23T04:51:00.281Z] "GET / HTTP/1.1" 200 - 0 58 4 1 "-" "curl/7.47.0" "f21ebd42-6770-4aa5-88d4-e56118165a7d" "one.example.com" "172.18.0.4:80"

Cov ntsiab lus tso zis tuaj yeem raug kho los ntawm kev teeb tsa hom ntawv. Piv txwv li:

access_log:
- name: envoy.file_access_log
  config:
    path: "/dev/stdout"
    format: "[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"n"

Lub cav kab kuj tuaj yeem tso tawm hauv JSON hom los ntawm kev teeb tsa lub teb json_format. Piv txwv li:

access_log:
- name: envoy.file_access_log
  config:
    path: "/dev/stdout"
    json_format: {"protocol": "%PROTOCOL%", "duration": "%DURATION%", "request_method": "%REQ(:METHOD)%"}

Yog xav paub ntxiv txog Envoy Registration Methodology, mus saib

https://www.envoyproxy.io/docs/envoy/latest/configuration/access_log#config-access-log-format-dictionaries

Kev sau npe tsis yog tib txoj hauv kev kom nkag siab txog kev ua haujlwm nrog Envoy Proxy. Nws muaj tracing advanced thiab metrics peev xwm ua rau hauv nws. Koj tuaj yeem paub ntau ntxiv ntawm tracing cov ntaub ntawv los sis dhau los Sib tham sib tracing tsab ntawv.

Kauj Ruam 7 - Tua tawm

Tam sim no koj tau tsiv koj qhov kev teeb tsa los ntawm NGINX rau Envoy Proxy. Cov kauj ruam kawg yog txhawm rau nthuav tawm Envoy Proxy piv txwv los sim nws.

Khiav raws li tus neeg siv

Nyob rau sab saum toj ntawm NGINX teeb tsa kab neeg siv www www; qhia kom khiav NGINX raws li tus neeg siv tsis muaj cai los txhim kho kev ruaj ntseg.

Envoy Proxy siv huab-raws li txoj hauv kev los tswj leej twg yog tus tswv txheej txheem. Thaum peb khiav Envoy Proxy los ntawm lub thawv, peb tuaj yeem qhia tus neeg siv tsawg.

Launching Envoy Proxy

Cov lus txib hauv qab no yuav khiav Envoy Proxy los ntawm Docker thawv ntawm tus tswv tsev. Cov lus txib no muab Envoy lub peev xwm los mloog rau cov lus thov tuaj ntawm qhov chaw nres nkoj 80. Txawm li cas los xij, raws li tau teev tseg hauv kev teeb tsa tus neeg mloog, Envoy Proxy mloog rau cov tsheb tuaj ntawm qhov chaw nres nkoj 8080. Qhov no tso cai rau cov txheej txheem khiav raws li cov neeg siv tsis muaj cai.

docker run --name proxy1 -p 80:8080 --user 1000:1000 -v /root/envoy.yaml:/etc/envoy/envoy.yaml envoyproxy/envoy

Kev Ntsuam Xyuas

Nrog rau lub npe ua haujlwm, tam sim no tuaj yeem ua thiab ua tiav. Cov lus txib cURL hauv qab no teeb meem kev thov nrog tus tswv tsev header uas tau teev tseg hauv kev teeb tsa npe.

curl -H "Host: one.example.com" localhost -i

Qhov kev thov HTTP yuav ua rau muaj qhov yuam kev 503. Qhov no yog vim kev sib txuas ntawm cov dej ntws tsis ua haujlwm thiab tsis muaj. Yog li, Envoy Proxy tsis muaj chaw nyob rau qhov kev thov. Cov lus txib hauv qab no yuav pib ua haujlwm HTTP cov kev pabcuam uas phim cov kev teeb tsa uas tau teev tseg rau Envoy.

docker run -d katacoda/docker-http-server; docker run -d katacoda/docker-http-server;

Nrog rau cov kev pabcuam muaj, Envoy tuaj yeem ua tiav kev tso npe nkag mus rau nws qhov chaw.

curl -H "Host: one.example.com" localhost -i

Koj yuav tsum pom cov lus teb uas qhia tias Docker ntim tau ua tiav qhov kev thov. Nyob rau hauv Envoy Proxy cav koj yuav tsum tau pom ib txoj hlua tso zis.

Ntxiv HTTP Response Headers

Koj yuav pom HTTP headers ntxiv nyob rau hauv cov lus teb headers ntawm qhov kev thov tiag tiag. Lub header qhia lub sij hawm tus tswv tsev upstream siv ua qhov kev thov. Qhia hauv milliseconds. Qhov no muaj txiaj ntsig yog tias tus neeg siv khoom xav txiav txim siab lub sijhawm pabcuam piv rau lub network latency.

x-envoy-upstream-service-time: 0
server: envoy

Thaum kawg config

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 8080 }
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains:
                - "one.example.com"
                - "www.one.example.com"
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: targetCluster
          http_filters:
          - name: envoy.router
          clusters:
  - name: targetCluster
    connect_timeout: 0.25s
    type: STRICT_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    hosts: [
      { socket_address: { address: 172.18.0.3, port_value: 80 }},
      { socket_address: { address: 172.18.0.4, port_value: 80 }}
    ]

admin:
  access_log_path: /tmp/admin_access.log
  address:
    socket_address: { address: 0.0.0.0, port_value: 9090 }

Cov ntaub ntawv ntxiv los ntawm tus neeg txhais lus

Cov lus qhia rau kev txhim kho Envoy Proxy tuaj yeem pom ntawm lub vev xaib https://www.getenvoy.io/

Los ntawm lub neej ntawd, rpm tsis muaj qhov kev pabcuam systemd config.

Ntxiv systemd service config /etc/systemd/system/envoy.service:

[Unit]
Description=Envoy Proxy
Documentation=https://www.envoyproxy.io/
After=network-online.target
Requires=envoy-auth-server.service
Wants=nginx.service

[Service]
User=root
Restart=on-failure
ExecStart=/usr/bin/envoy --config-path /etc/envoy/config.yaml
[Install]
WantedBy=multi-user.target

Koj yuav tsum tsim ib daim ntawv teev npe /etc/envoy/ thiab muab lub config.yaml config rau ntawd.

Muaj kev sib tham hauv xov tooj siv tus neeg sawv cev tus neeg sawv cev: https://t.me/envoyproxy_ru

Envoy Proxy tsis txhawb nqa cov ntsiab lus zoo li qub. Yog li ntawd, leej twg tuaj yeem pov npav rau qhov tshwj xeeb: https://github.com/envoyproxy/envoy/issues/378

Tsuas yog cov neeg siv sau npe tuaj yeem koom nrog hauv daim ntawv ntsuam xyuas. Kos npe rau hauvthov.

Cov ntawv tshaj tawm no puas txhawb koj kom nruab thiab kuaj tus neeg sawv cev npe?

  • yog

  • tsis muaj

75 cov neeg siv pov npav. 18 cov neeg siv txwv tsis pub siv.

Tau qhov twg los: www.hab.com

Ntxiv ib saib