【華為云專家原創】徹底搞懂 etcd 系列文章(三):etcd 集群運維部署

      網友投稿 1153 2025-04-02

      0 專輯概述

      etcd 是云原生架構中重要的基礎組件,由 CNCF 孵化托管。etcd 在微服務和 Kubernates 集群中不僅可以作為服務注冊與發現,還可以作為 key-value 存儲的中間件。

      《徹底搞懂 etcd 系列文章》將會從 etcd 的基本功能實踐、API 接口、實現原理、源碼分析,以及實現中的踩坑經驗等幾方面具體展開介紹 etcd。預計會有 20 篇左右的文章,筆者將會每周持續更新,歡迎關注。

      【華為云專家原創】徹底搞懂 etcd 系列文章(三):etcd 集群運維部署

      1 etcd 集群部署

      在生產環境中,為了整個集群的高可用,etcd 正常都會集群部署,避免單點故障。本節將會介紹如何進行 etcd 集群部署。引導 etcd 集群的啟動有以下三種機制:

      靜態

      etcd 動態發現

      DNS 發現

      0 專輯概述

      etcd 是云原生架構中重要的基礎組件,由 CNCF 孵化托管。etcd 在微服務和 Kubernates 集群中不僅可以作為服務注冊與發現,還可以作為 key-value 存儲的中間件。

      《徹底搞懂 etcd 系列文章》將會從 etcd 的基本功能實踐、API 接口、實現原理、源碼分析,以及實現中的踩坑經驗等幾方面具體展開介紹 etcd。預計會有 20 篇左右的文章,筆者將會每周持續更新,歡迎關注。

      1 etcd 集群部署

      在生產環境中,為了整個集群的高可用,etcd 正常都會集群部署,避免單點故障。本節將會介紹如何進行 etcd 集群部署。引導 etcd 集群的啟動有以下三種機制:

      靜態

      etcd 動態發現

      DNS 發現

      靜態啟動 etcd 集群要求每個成員都知道集群中的另一個成員。 在許多情況下,群集成員的 IP 可能會提前未知。在這些情況下,可以在發現服務的幫助下引導 etcd 群集。

      下面我們將會分別介紹這幾種方式。

      2 靜態方式啟動 etcd 集群

      如果想要在一臺機器上實踐 etcd 集群的搭建,可以通過 goreman 工具。

      我們需要確認 Go 安裝環境,然后直接執行:

      go?get?github.com/mattn/goreman

      編譯后的文件放在 $GOPATH/bin 中,$GOPATH/bin目錄已經添加到了系統 $PATH 中,所以我們可以方便執行命令 goreman 命令。下面就是編寫 Procfile 腳本,我們啟動三個 etcd,具體對應如下:

      Procfile 腳本如下:

      etcd1:?etcd?--name?infra1?--listen-client-urls?http://127.0.0.1:12379?--advertise-client-urls?http://127.0.0.1:12379?--listen-peer-urls?http://127.0.0.1:12380?--initial-advertise-peer-urls?http://127.0.0.1:12380?--initial-cluster-token?etcd-cluster-1?--initial-cluster?'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380'?--initial-cluster-state?new?--enable-pprof?--logger=zap?--log-outputs=stderr etcd2:?etcd?--name?infra2?--listen-client-urls?http://127.0.0.1:22379?--advertise-client-urls?http://127.0.0.1:22379?--listen-peer-urls?http://127.0.0.1:22380?--initial-advertise-peer-urls?http://127.0.0.1:22380?--initial-cluster-token?etcd-cluster-1?--initial-cluster?'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380'?--initial-cluster-state?new?--enable-pprof?--logger=zap?--log-outputs=stderr etcd3:?etcd?--name?infra3?--listen-client-urls?http://127.0.0.1:32379?--advertise-client-urls?http://127.0.0.1:32379?--listen-peer-urls?http://127.0.0.1:32380?--initial-advertise-peer-urls?http://127.0.0.1:32380?--initial-cluster-token?etcd-cluster-1?--initial-cluster?'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380'?--initial-cluster-state?new?--enable-pprof?--logger=zap?--log-outputs=stderr

      配置項說明:

      --name:etcd集群中的節點名,這里可以隨意,可區分且不重復就行

      --listen-peer-urls:監聽的用于節點之間通信的url,可監聽多個,集群內部將通過這些url進行數據交互(如選舉,數據同步等)

      --initial-advertise-peer-urls:建議用于節點之間通信的url,節點間將以該值進行通信。

      --listen-client-urls:監聽的用于客戶端通信的url,同樣可以監聽多個。

      --advertise-client-urls:建議使用的客戶端通信 url,該值用于 etcd 代理或 etcd 成員與 etcd 節點通信。

      --initial-cluster-token: etcd-cluster-1,節點的 token 值,設置該值后集群將生成唯一 id,并為每個節點也生成唯一 id,當使用相同配置文件再啟動一個集群時,只要該 token 值不一樣,etcd 集群就不會相互影響。

      --initial-cluster:也就是集群中所有的 initial-advertise-peer-urls 的合集。

      --initial-cluster-state:new,新建集群的標志

      注意上面的腳本,etcd 命令執行時需要根據本地實際的安裝地址進行配置。下面我們啟動 etcd 集群。

      goreman?-f?/opt/procfile?start

      使用如上的命令啟動啟動 etcd 集群,啟動完成之后查看集群內的成員。

      $?etcdctl?--endpoints=http://localhost:22379??member?list 8211f1d0f64f3269,?started,?infra1,?http://127.0.0.1:12380,?http://127.0.0.1:12379,?false 91bc3c398fb3c146,?started,?infra2,?http://127.0.0.1:22380,?http://127.0.0.1:22379,?false fd422379fda50e48,?started,?infra3,?http://127.0.0.1:32380,?http://127.0.0.1:32379,?false

      我們在單機搭建的偽集群成功,需要注意的是在集群啟動時,我們是通過靜態的方式指定集群的成員,在實際環境中,集群成員的 ip 可能不會提前知道。這時候就需要采用動態發現的機制。

      etcd 使用 gcr.io/etcd-development/etcd 作為容器的主要加速器, quay.io/coreos/etcd 作為輔助的加速器。可惜這兩個加速器我們都沒法訪問,如果下載不了,可以使用筆者提供的地址:

      docker?pull?bitnami/etcd:3.4.7

      然后將拉取的鏡像重新 tag:

      docker?image?tag?bitnami/etcd:3.4.7?quay.io/coreos/etcd:3.4.7

      鏡像設置好之后,我們啟動 3 個節點的 etcd 集群,腳本命令如下:

      REGISTRY=quay.io/coreos/etcd #?For?each?machine ETCD_VERSION=3.4.7 TOKEN=my-etcd-token CLUSTER_STATE=new NAME_1=etcd-node-0 NAME_2=etcd-node-1 NAME_3=etcd-node-2 HOST_1=?192.168.202.128 HOST_2=?192.168.202.129 HOST_3=?192.168.202.130 CLUSTER=${NAME_1}=http://${HOST_1}:2380,${NAME_2}=http://${HOST_2}:2380,${NAME_3}=http://${HOST_3}:2380 DATA_DIR=/var/lib/etcd #?For?node?1 THIS_NAME=${NAME_1} THIS_IP=${HOST_1} docker?run?\ ??-p?2379:2379?\ ??-p?2380:2380?\ ??--volume=${DATA_DIR}:/etcd-data?\ ??--name?etcd?${REGISTRY}:${ETCD_VERSION}?\ ??/usr/local/bin/etcd?\ ??--data-dir=/etcd-data?--name?${THIS_NAME}?\ ??--initial-advertise-peer-urls?http://${THIS_IP}:2380?--listen-peer-urls?http://0.0.0.0:2380?\ ??--advertise-client-urls?http://${THIS_IP}:2379?--listen-client-urls?http://0.0.0.0:2379?\ ??--initial-cluster?${CLUSTER}?\ ??--initial-cluster-state?${CLUSTER_STATE}?--initial-cluster-token?${TOKEN} #?For?node?2 THIS_NAME=${NAME_2} THIS_IP=${HOST_2} docker?run?\ ??-p?2379:2379?\ ??-p?2380:2380?\ ??--volume=${DATA_DIR}:/etcd-data?\ ??--name?etcd?${REGISTRY}:${ETCD_VERSION}?\ ??/usr/local/bin/etcd?\ ??--data-dir=/etcd-data?--name?${THIS_NAME}?\ ??--initial-advertise-peer-urls?http://${THIS_IP}:2380?--listen-peer-urls?http://0.0.0.0:2380?\ ??--advertise-client-urls?http://${THIS_IP}:2379?--listen-client-urls?http://0.0.0.0:2379?\ ??--initial-cluster?${CLUSTER}?\ ??--initial-cluster-state?${CLUSTER_STATE}?--initial-cluster-token?${TOKEN} #?For?node?3 THIS_NAME=${NAME_3} THIS_IP=${HOST_3} docker?run?\ ??-p?2379:2379?\ ??-p?2380:2380?\ ??--volume=${DATA_DIR}:/etcd-data?\ ??--name?etcd?${REGISTRY}:${ETCD_VERSION}?\ ??/usr/local/bin/etcd?\ ??--data-dir=/etcd-data?--name?${THIS_NAME}?\ ??--initial-advertise-peer-urls?http://${THIS_IP}:2380?--listen-peer-urls?http://0.0.0.0:2380?\ ??--advertise-client-urls?http://${THIS_IP}:2379?--listen-client-urls?http://0.0.0.0:2379?\ ??--initial-cluster?${CLUSTER}?\ ??--initial-cluster-state?${CLUSTER_STATE}?--initial-cluster-token?${TOKEN}

      注意,上面的腳本是部署在三臺機器上面,每臺機器執行對應的腳本即可。在運行時可以指定 API 版本:

      docker?exec?etcd?/bin/sh?-c?"export?ETCDCTL_API=3?&&?/usr/local/bin/etcdctl?put?foo?bar"

      docker 的安裝方式比較簡單,讀者根據需要可以定制一些配置。

      3 動態發現啟動 etcd 集群

      如前面所述,在實際環境中,集群成員的 ip 可能不會提前知道。在這種情況下,需要使用自動發現來引導 etcd 集群,而不是指定靜態配置,這個過程被稱為「發現」。我們啟動三個 etcd,具體對應如下:

      Discovery service protocol 幫助新的 etcd 成員使用共享 URL 在集群引導階段發現所有其他成員。

      該協議使用新的發現令牌來引導一個唯一的 etcd 集群。一個發現令牌只能代表一個 etcd 集群。只要此令牌上的發現協議啟動,即使它中途失敗,也不能用于引導另一個 etcd 集群。

      「提示」:Discovery service protocol 僅用于集群引導階段,不能用于運行時重新配置或集群監視。

      Discovery protocol 使用內部 etcd 集群來協調新集群的引導程序。首先,所有新成員都與發現服務交互,并幫助生成預期的成員列表。之后,每個新成員使用此列表引導其服務器,該列表執行與 --initial-cluster 標志相同的功能,即設置所有集群的成員信息。

      生成將標識新集群的唯一令牌。 在以下步驟中,它將用作發現鍵空間中的唯一前綴。 一種簡單的方法是使用uuidgen:

      UUID=$(uuidgen)

      獲取令牌時,必須指定群集大小。 發現服務使用該大小來了解何時發現了最初將組成集群的所有成員。

      curl?-X?PUT?http://10.0.10.10:2379/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83/_config/size?-d?value=3

      我們需要把該 url 地址 http://10.0.10.10:2379/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83 作為 --discovery 參數來啟動 etcd。

      節點會自動使用 http://10.0.10.10:2379/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83 目錄進行 etcd 的注冊和發現服務。

      當我們本地沒有可用的 etcd 集群,etcd 官網提供了一個可以公網訪問的 etcd 存儲地址。我們可以通過如下命令得到 etcd 服務的目錄,并把它作為 --discovery 參數使用。

      公共發現服務 discovery.etcd.io 以相同的方式工作,但是有一層修飾,可以提取丑陋的 URL,自動生成 UUID,并提供針對過多請求的保護。公共發現服務在其上仍然使用 etcd 群集作為數據存儲。

      $?curl?http://discovery.etcd.io/new?size=3 http://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de

      etcd 發現模式下,啟動 etcd 的命令如下:

      #?etcd1?啟動 $?/opt/etcd/bin/etcd??--name?etcd1?--initial-advertise-peer-urls?http://192.168.202.128:2380?\ ??--listen-peer-urls?http://192.168.202.128:2380?\ ??--data-dir?/opt/etcd/data?\ ??--listen-client-urls?http://192.168.202.128:2379,http://127.0.0.1:2379?\ ??--advertise-client-urls?http://192.168.202.128:2379?\ ??--discovery?https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de #?etcd2?啟動 ?/opt/etcd/bin/etcd??--name?etcd2?--initial-advertise-peer-urls?http://192.168.202.129:2380?\ ??--listen-peer-urls?http://192.168.202.129:2380?\ ??--data-dir?/opt/etcd/data?\ ??--listen-client-urls?http://192.168.202.129:2379,http://127.0.0.1:2379?\ ??--advertise-client-urls?http://192.168.202.129:2379?\ ??--discovery?https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de #?etcd3?啟動 ?/opt/etcd/bin/etcd??--name?etcd3?--initial-advertise-peer-urls?http://192.168.202.130:2380?\ ????--listen-peer-urls?http://192.168.202.130:2380?\ ????--data-dir?/opt/etcd/data?\ ????--listen-client-urls?http://192.168.202.130:2379,http://127.0.0.1:2379?\ ????--advertise-client-urls?http://192.168.202.130:2379?\ ????--discovery?https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de

      需要注意的是,在我們完成了集群的初始化后,這些信息就失去了作用。當需要增加節點時,需要使用 etcdctl 進行操作。為了安全,每次啟動新 etcd 集群時,都使用新的 discovery token 進行注冊。另外,如果初始化時啟動的節點超過了指定的數量,多余的節點會自動轉化為 Proxy 模式的 etcd。

      集群啟動好之后,進行驗證,我們看一下集群的成員:

      $?/opt/etcd/bin/etcdctl?member?list #?結果如下 ????40e2ac06ca1674a7,?started,?etcd3,?http://192.168.202.130:2380,?http://192.168.202.130:2379,?false ????c532c5cedfe84d3c,?started,?etcd1,?http://192.168.202.128:2380,?http://192.168.202.128:2379,?false ????db75d3022049742a,?started,?etcd2,?http://192.168.202.129:2380,?http://192.168.202.129:2379,?false

      結果符合預期,再看下節點的健康狀態:

      $?/opt/etcd/bin/etcdctl??--endpoints="http://192.168.202.128:2379,http://192.168.202.129:2379,http://192.168.202.130:2379"??endpoint??health #?結果如下 ????http://192.168.202.128:2379?is?healthy:?successfully?committed?proposal:?took?=?3.157068ms ????http://192.168.202.130:2379?is?healthy:?successfully?committed?proposal:?took?=?3.300984ms ????http://192.168.202.129:2379?is?healthy:?successfully?committed?proposal:?took?=?3.263923ms

      可以看到,集群中的三個節點都是健康的正常狀態。以動態發現方式啟動集群成功。

      4 DNS自發現模式

      etcd 還支持使用 DNS SRV 記錄進行啟動。實際上是利用 DNS 的 SRV 記錄不斷輪訓查詢實現。DNS SRV 是 DNS 數據庫中支持的一種資源記錄的類型,它記錄了計算機與所提供服務信息的對應關系。

      這里使用 Dnsmasq 創建 DNS 服務。Dnsmasq 提供 DNS 緩存和 DHCP 服務、Tftp 服務功能。作為域名解析服務器,Dnsmasq 可以通過緩存 DNS 請求來提高對訪問過的網址的連接速度。Dnsmasq 輕量且易配置,適用于個人用戶或少于 50 臺主機的網絡。此外它還自帶了一個 PXE 服務器。

      當接受到一個 DNS 請求時,Dnsmasq 首先會查找 /etc/hosts 這個文件,然后查找 /etc/resolv.conf 中定義的外部 DNS。配置 Dnsmasq 為 DNS 緩存服務器,同時在 /etc/hosts 文件中加入本地內網解析,這樣使得內網機器查詢時就會優先查詢 hosts 文件,這就等于將 /etc/hosts 共享給全內網機器使用,從而解決內網機器互相識別的問題。相比逐臺機器編輯 hosts 文件或者添加 Bind DNS 記錄,可以只編輯一個 hosts 文件。

      基于筆者使用的 Centos 7 的主機,首先安裝 Dnsmasq:

      yum?install?dnsmasq

      安裝好之后,進行配置,所有的配置都在一個文件中完成 /etc/dnsmasq.conf。我們也可以在 /etc/dnsmasq.d 中自己寫任意名字的配置文件。

      resolv-file 配置 Dnsmasq 額外的上游的 DNS 服務器,如果不開啟就使用 Linux 主機默認的 /etc/resolv.conf 里的 nameserver。

      $?vim?/etc/dnsmasq.conf #?增加如下的內容: resolv-file=/etc/resolv.dnsmasq.conf srv-host=_etcd-server._tcp.blueskykong.com,etcd1.blueskykong.com,2380,0,100 srv-host=_etcd-server._tcp.blueskykong.com,etcd2.blueskykong.com,2380,0,100 srv-host=_etcd-server._tcp.blueskykong.com,etcd3.blueskykong.com,2380,0,100

      在 dnsmasq.conf 中相應的域名記錄,配置了我們所涉及的三臺服務器,分別對應 etcd1,etcd2,etcd3。

      $?vim?/etc/resolv.dnsmasq.conf nameserver?8.8.8.8 nameserver?8.8.4.4

      這兩個免費的 DNS服務,大家應該不陌生。讀者可以根據本地實際網絡進行配置。

      $?vim?/etc/resolv.conf nameserver?127.0.0.1

      將 Dnsmasq 解析配置到本地,這很好理解。

      分別為各個域名配置相關的 A 記錄指向 etcd 核心節點對應的機器 IP。添加解析記錄有三種方式:使用系統默認 hosts、使用自定義 hosts 文件、使用自定義 conf。這里我們使用比較簡單的第一種方式。

      $?vim?/etc/hosts #?增加如下的內容解析 192.168.202.128?etcd1.blueskykong.com 192.168.202.129?etcd2.blueskykong.com 192.168.202.130?etcd3.blueskykong.com

      「啟動服務」

      service?dnsmasq?start

      啟動好之后,我們進行驗證:

      DNS 服務器上 SRV 記錄查詢,查詢到的結果如下:

      $?dig?@192.168.202.128?+noall?+answer?SRV?_etcd-server._tcp.blueskykong.com _etcd-server._tcp.blueskykong.com.?0?IN?SRV?????0?100?2380?etcd2.blueskykong.com. _etcd-server._tcp.blueskykong.com.?0?IN?SRV?????0?100?2380?etcd1.blueskykong.com. _etcd-server._tcp.blueskykong.com.?0?IN?SRV?????0?100?2380?etcd3.blueskykong.com.

      DNS 服務器上 SRV 記錄查詢,查詢到的結果如下:

      $?dig?@192.168.202.128?+noall?+answer?SRV?_etcd-server._tcp.blueskykong.com _etcd-server._tcp.blueskykong.com.?0?IN?SRV?????0?100?2380?etcd2.blueskykong.com. _etcd-server._tcp.blueskykong.com.?0?IN?SRV?????0?100?2380?etcd1.blueskykong.com. _etcd-server._tcp.blueskykong.com.?0?IN?SRV?????0?100?2380?etcd3.blueskykong.com.

      使查詢域名解析結果

      $?dig?@192.168.202.128?+noall?+answer?etcd1.blueskykong.com?etcd2.blueskykong.com?etcd3.blueskykong.com etcd1.blueskykong.com.??0???????IN??????A???????192.168.202.128 etcd2.blueskykong.com.??0???????IN??????A???????192.168.202.129 etcd3.blueskykong.com.??0???????IN??????A???????192.168.202.130

      使查詢域名解析結果

      $?dig?@192.168.202.128?+noall?+answer?etcd1.blueskykong.com?etcd2.blueskykong.com?etcd3.blueskykong.com etcd1.blueskykong.com.??0???????IN??????A???????192.168.202.128 etcd2.blueskykong.com.??0???????IN??????A???????192.168.202.129 etcd3.blueskykong.com.??0???????IN??????A???????192.168.202.130

      至此,我們已成功安裝好 Dnsmasq。下面我們基于 DNS 發現啟動 etcd 集群。

      做好了上述兩步 DNS 的配置,就可以使用 DNS 啟動 etcd 集群了。需要刪除ETCD_INITIAL_CLUSTER 配置(用于靜態服務發現),并指定 DNS SRV 域名(ETCD_DISCOVERY_SRV)。配置 DNS 解析的 url 參數為 -discovery-srv,其中 etcd1 節點地啟動命令如下:

      $?/opt/etcd/bin/etcd???--name?etcd1?\ --discovery-srv?blueskykong.com?\ --initial-advertise-peer-urls?http://etcd1.blueskykong.com:2380?\ --initial-cluster-token?etcd-cluster-1?\ --data-dir?/opt/etcd/data?\ --initial-cluster-state?new?\ --advertise-client-urls?http://etcd1.blueskykong.com:2379?\ --listen-client-urls?http://0.0.0.0:2379?\ --listen-peer-urls?http://0.0.0.0:2380

      etcd 群集成員可以使用域名或 IP 地址進行廣播,啟動的過程將解析 DNS 記錄。--initial-advertise-peer-urls 中的解析地址必須與 SRV 目標中的解析地址匹配。etcd 成員讀取解析的地址,以查找其是否屬于 SRV 記錄中定義的群集。

      我們驗證基于 DNS 發現啟動集群的正確性,查看集群的成員列表:

      $?/opt/etcd/bin/etcdctl?member?list #?結果如下: 40e2ac06ca1674a7,?started,?etcd3,?http://192.168.202.130:2380,?http://etcd3.blueskykong.com:2379,?false c532c5cedfe84d3c,?started,?etcd1,?http://192.168.202.128:2380,?http://etcd1.blueskykong.com:2379,?false db75d3022049742a,?started,?etcd2,?http://192.168.202.129:2380,?http://etcd2.blueskykong.com:2379,?false

      可以看到,結果輸出 etcd 集群有三個成員,符合預期。下面我們使用 IP 地址的方式,繼續驗證集群節點的狀態。

      $?/opt/etcd/bin/etcdctl??--endpoints="http://192.168.202.128:2379,http://192.168.202.129:2379,http://192.168.202.130:2379"??endpoint??health #?結果如下: http://192.168.202.129:2379?is?healthy:?successfully?committed?proposal:?took?=?2.933555ms http://192.168.202.128:2379?is?healthy:?successfully?committed?proposal:?took?=?7.252799ms http://192.168.202.130:2379?is?healthy:?successfully?committed?proposal:?took?=?7.415843ms

      更多的 etcd 集群操作,讀者可以自行嘗試,筆者不在此一一展開。

      5 小結

      本文在上一篇文章單機安裝 etcd 的基礎上進行了補充,主要介紹了 etcd 集群的多種安裝啟動方式:靜態單體,靜態 docker,動態發現以及 DNS 發現的啟動方式。這么多的安裝姿勢,都是為了我們實際的使用,下一篇我們將具體進入 etcdctl 的使用講解。

      etcd 與 Zookeeper、Consul 等其它 k-v 組件的對比

      徹底搞懂 etcd 系列文章(一):初識 etcd

      徹底搞懂 etcd 系列文章(二):etcd 的多種安裝姿勢

      etcd docs

      云原生 分布式 微服務

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:Excel2007中表格文檔擴展名稱的操作方法(excel文件擴展名稱)
      下一篇:頁數怎么能多一頁(怎么把頁數變成一頁)
      相關文章
      2022年亚洲午夜一区二区福利| 亚洲精品伊人久久久久| 亚洲网站在线观看| 中文字幕不卡亚洲 | 亚洲精品人成在线观看| 亚洲精品无码不卡在线播HE| 亚洲人成网站色在线入口| 337p日本欧洲亚洲大胆人人| 亚洲砖码砖专无区2023| 亚洲一区二区无码偷拍 | 亚洲美女高清一区二区三区| 亚洲国产综合精品一区在线播放| 亚洲成av人在片观看| 亚洲精品第一国产综合精品99| 亚洲狠狠爱综合影院婷婷| 亚洲精品线路一在线观看| 久久久青草青青国产亚洲免观 | 亚洲成a人片7777| 亚洲国产成a人v在线| 亚洲中文字幕无码av在线| 亚洲乱码一二三四区麻豆| 亚洲午夜一区二区三区| 亚洲色大成网站www| WWW国产亚洲精品久久麻豆| 亚洲AⅤ无码一区二区三区在线| 无码不卡亚洲成?人片| 亚洲欧洲日产国码一级毛片| 国产国拍精品亚洲AV片| 亚洲av一综合av一区| 麻豆亚洲AV永久无码精品久久| 亚洲的天堂av无码| 亚洲视频在线观看2018| 亚洲AV无码国产精品永久一区| 一区二区三区亚洲视频| 亚洲中文久久精品无码| 亚洲成人中文字幕| 亚洲婷婷天堂在线综合| 亚洲精品又粗又大又爽A片| 国产亚洲人成在线影院| 亚洲夜夜欢A∨一区二区三区| 亚洲av无码乱码国产精品|