K8s實(shí)現(xiàn)數(shù)據(jù)持久化

前言

在一切虛擬化解決方案中,數(shù)據(jù)的持久化都是需要我們非常關(guān)心的問題,docker如此,K8s也不例外。在k8s中,有一個(gè)數(shù)據(jù)卷的概念。

創(chuàng)新互聯(lián)是專業(yè)的廣平網(wǎng)站建設(shè)公司,廣平接單;提供做網(wǎng)站、成都網(wǎng)站設(shè)計(jì),網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行廣平網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!

k8s數(shù)據(jù)卷主要解決了以下兩方面問題:

  • 數(shù)據(jù)持久性:通常情況下,容器運(yùn)行起來后,寫入到其文件系統(tǒng)的文件時(shí)暫時(shí)性的。當(dāng)容器崩潰后,kebelet將這個(gè)容器kill掉,然后生成一個(gè)新的容器,此時(shí),新運(yùn)行的容器將沒有原來容器內(nèi)的文件,因?yàn)槿萜魇侵匦聫溺R像創(chuàng)建的。
  • 數(shù)據(jù)共享:同一個(gè)pod中運(yùn)行的容器之間,經(jīng)常會存在共享文件/文件夾的需求。

在k8s中,Volume(數(shù)據(jù)卷)存在明確的生命周期(與包含該數(shù)據(jù)卷的容器組(pod)相同)。因此Volume的生命周期比同一容器組(pod)中任意容器的生命周期要更長,不管容器重啟了多少次,數(shù)據(jù)都被保留下來。當(dāng)然,如果pod不存在了,數(shù)據(jù)卷自然退出了。此時(shí),根據(jù)pod所使用的數(shù)據(jù)卷類型不同,數(shù)據(jù)可能隨著數(shù)據(jù)卷的退出而刪除,也可能被真正持久化,并在下次容器組重啟時(shí)仍然可以使用。

從根本上來說,一個(gè)數(shù)據(jù)卷僅僅是一個(gè)可以被pod訪問的目錄或文件。這個(gè)目錄是怎么來的,取決于該數(shù)據(jù)卷的類型(不同類型的數(shù)據(jù)卷使用不同的存儲介質(zhì))。同一個(gè)pod中的兩個(gè)容器可以將一個(gè)數(shù)據(jù)卷掛載到不同的目錄下。

一、數(shù)據(jù)卷類型

k8s目前支持28種數(shù)據(jù)卷類型(其中大多數(shù)特定于云環(huán)境),這里將寫下在k8s中常用的幾種數(shù)據(jù)卷類型。

1、emptyDir

emptyDir類型的數(shù)據(jù)卷在創(chuàng)建pod時(shí)分配給該pod,并且直到pod被移除,該數(shù)據(jù)卷才被釋放。該數(shù)據(jù)卷初始分配時(shí),始終是一個(gè)空目錄。同一個(gè)pod中的不同容器都可以對該目錄執(zhí)行讀寫操作,并且共享其中的數(shù)據(jù)(盡管不同容器可能將該數(shù)據(jù)卷掛載到容器中的不同路徑)。當(dāng)pod被刪除后,emptyDir數(shù)據(jù)卷中的數(shù)據(jù)將被永久刪除。(PS:容器奔潰時(shí),kubelet并不會刪除pod,而僅僅是將容器重啟,因此emptyDir中的數(shù)據(jù)在容器崩潰并重啟后,仍然是存在的)。

emptyDir的使用場景如下:

  • 空白的初始空間,例如合并/排序算法中,臨時(shí)將數(shù)據(jù)保存在磁盤上。
  • 長時(shí)間計(jì)算中存儲檢查點(diǎn)(中間結(jié)果),以便容器崩潰時(shí),可以從上一次存儲的檢查點(diǎn)(中間結(jié)果)繼續(xù)進(jìn)行,而不是從頭開始。
  • 作為兩個(gè)容器的共享存儲,使得第一個(gè)內(nèi)容管理的容器可以將生成的數(shù)據(jù)存入其中,同時(shí)由一個(gè)webserver容器對外提供這些頁面。
  • 默認(rèn)情況下,emptyDir數(shù)據(jù)卷存儲在node節(jié)點(diǎn)的存儲介質(zhì)(機(jī)械硬盤、SSD或網(wǎng)絡(luò)存儲)上。
emptyDir的使用示例
[root@master ~]# vim emtydir.yaml     #pod的yaml文件如下

apiVersion: v1
kind: Pod
metadata:
  name: read-write
spec:
  containers:
  - name: write         #定義一個(gè)名為write的容器
    image: busybox
    volumeMounts:
    - mountPath: /write    #當(dāng)數(shù)據(jù)持久化類型為emtydir時(shí),這里的路徑指的是容器內(nèi)的路徑
      name: share-volume     #指定本地的目錄名
    args:        #容器運(yùn)行后,進(jìn)行寫操作
    - /bin/sh
    - -c
    - echo "emtydir test" > /write/hello;sleep 30000

  - name: read           #定義一個(gè)名為read的容器
    image: busybox
    volumeMounts:
    - mountPath: /read
      name: share-volume      #指定本地的目錄名
    args:                #容器運(yùn)行后,進(jìn)行讀操作
    - /bin/sh
    - -c
    - cat /read/hello; sleep 30000
  volumes:               #這里的volumes是指對上面掛載的進(jìn)行解釋
  - name: share-volume    #這里的名字必須和上面pod的mountPath下的name值對應(yīng)
    emptyDir: {}            #這里表示是個(gè)空目錄,主要是定義了一個(gè)數(shù)據(jù)持久化的類型
[root@master ~]# kubectl apply -f emtydir.yaml    #執(zhí)行yaml文件
[root@master ~]# kubectl exec -it read-write -c write /bin/sh  #進(jìn)入第一個(gè)pod
/ # cat /write/hello        #確認(rèn)yaml文件執(zhí)行的命令是否生效
emtydir test

[root@master ~]# kubectl exec -it read-write -c read /bin/sh  #進(jìn)入第二個(gè)容器名為read的容器查看
/ # cat /read/hello        #查看指定掛載的目錄下是否和write容器中的內(nèi)容一致
emtydir test
#至此,起碼可以確認(rèn)這兩個(gè)pod是掛載了同一個(gè)本地目錄,文件內(nèi)容都一致。
#那么,現(xiàn)在看看具體掛載的是本地哪個(gè)目錄?
[root@master ~]# kubectl get pod -o wide    #先通過此命令查看pod是運(yùn)行在哪個(gè)節(jié)點(diǎn)上的
#我這里是運(yùn)行在node01節(jié)點(diǎn)的,所以接下來需要到node01節(jié)點(diǎn)上進(jìn)行查看

#node01節(jié)點(diǎn)操作如下:
[root@node01 ~]# docker ps             #通過此命令查看出運(yùn)行的容器ID號
CONTAINER ID        IMAGE              #省略部分內(nèi)容
6186a08c6d5f        busybox              
5f19986f0879        busybox             
[root@node01 ~]# docker inspect 6186a08c6d5f      #查看第一個(gè)容器的詳細(xì)信息
 "Mounts": [          #找到mount字段
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/86b67ff4-9ca0-4f40-86d8-6778cfe949ec/volumes/kubernetes.io~empty-dir/share-volume",
#上面的source就是指定的本地目錄
                "Destination": "/read",
                "Mode": "Z",
                "RW": true,
                "Propagation": "rprivate"

[root@node01 ~]# docker inspect 5f19986f0879    #查看第二個(gè)容器的詳細(xì)信息

        "Mounts": [    #同樣定位到mount字段
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/86b67ff4-9ca0-4f40-86d8-6778cfe949ec/volumes/kubernetes.io~empty-dir/share-volume",
#可以看到,上面指定的本地目錄和第一個(gè)容器指定的是同一個(gè)目錄
                "Destination": "/write",
                "Mode": "Z",
                "RW": true,
                "Propagation": "rprivate"
            },
#至此,已經(jīng)可以確定這兩個(gè)容器的掛載目錄共享的是同一個(gè)本地目錄
[root@node01 ~]# cat /var/lib/kubelet/pods/86b67ff4-9ca0-4f40-86d8-6778cfe949ec/volumes/kubernetes.io~empty-dir/share-volume/hello 
#查看本地該目錄下的內(nèi)容,和pod中的一致
emtydir test

至此,emptyDir的特性就已經(jīng)驗(yàn)證了,只要這個(gè)pod中還有一個(gè)容器在運(yùn)行,那么這個(gè)本地的數(shù)據(jù)就不會丟失,但如果這個(gè)pod被刪除,那么本地的數(shù)據(jù)也將不復(fù)存在。

驗(yàn)證如下:

node01上刪除一個(gè)pod并再次查看本地目錄:

[root@node01 ~]# docker rm -f 6186a08c6d5f    #刪除一個(gè)pod
6186a08c6d5f
[root@node01 ~]# cat /var/lib/kubelet/pods/86b67ff4-9ca0-4f40-86d8-6778cfe949ec/volumes/kubernetes.io~empty-dir/share-volume/hello 
#查看本地目錄,發(fā)現(xiàn)文件還在
emtydir test

在master上將此pod刪除,再次去node01節(jié)點(diǎn)上查看本地目錄是否存在:

#master上刪除pod
[root@master ~]# kubectl delete -f emtydir.yaml 
#在node01上再次查看本地目錄,會提示不存在這個(gè)目錄
[root@node01 ~]# cat /var/lib/kubelet/pods/86b67ff4-9ca0-4f40-86d8-6778cfe949ec/volumes/kubernetes.io~empty-dir/share-volume/hello 
cat: /var/lib/kubelet/pods/86b67ff4-9ca0-4f40-86d8-6778cfe949ec/volumes/kubernetes.io~empty-dir/share-volume/hello: 沒有那個(gè)文件或目錄

emptyDir總結(jié):

同個(gè)pod里面的不同容器,共享同一個(gè)持久化目錄,當(dāng)pod節(jié)點(diǎn)刪除時(shí),volume的內(nèi)容也會被刪除。但如果僅僅是容器被銷毀,pod還在,則volume不會受到任何影響。說白了,emptyDir的數(shù)據(jù)持久化的生命周期和使用的pod一致。一般是作為臨時(shí)存儲使用。

2、HostPath數(shù)據(jù)卷類型

hostPath 類型的數(shù)據(jù)卷將 Pod(容器組)所在節(jié)點(diǎn)的文件系統(tǒng)上某一個(gè)文件或目錄掛載進(jìn)容器組(容器內(nèi)部),類似于docker中的bind mount掛載方式。

這種數(shù)據(jù)持久化的方式,使用場景不多,因?yàn)樗黾恿藀od與節(jié)點(diǎn)之間的耦合。

絕大多數(shù)容器組并不需要使用 hostPath 數(shù)據(jù)卷,但是少數(shù)情況下,hostPath 數(shù)據(jù)卷非常有用:

適用場景如下:

  • 某容器需要訪問 Docker,可使用 hostPath 掛載宿主節(jié)點(diǎn)的 /var/lib/docker
  • 在容器中運(yùn)行 cAdvisor,使用 hostPath 掛載宿主節(jié)點(diǎn)的 /sys

總言而之,一般對K8s集群本身的數(shù)據(jù)持久化和docker本身的數(shù)據(jù)持久化會使用這種方式。

由于其使用場景比較少,這里就不舉例了。

3、Persistent 數(shù)據(jù)卷類型

PersistentVolume(PV存儲卷)是集群中的一塊存儲空間,由集群管理員管理或者由Storage class(存儲類)自動管理,PV和pod、deployment、Service一樣,都是一個(gè)資源對象。

既然有了PV這個(gè)概念,那么PVC(PersistentVolumeClaim)這個(gè)概念也不得不說一下,PVC代表用戶使用存儲的請求,應(yīng)用申請PV持久化空間的一個(gè)申請、聲明。K8s集群可能會有多個(gè)PV,你需要不停的為不同的應(yīng)用創(chuàng)建多個(gè)PV。

比如說,pod是消耗node節(jié)點(diǎn)的計(jì)算資源,而PVC存儲卷聲明是消耗PV的存儲資源。Pod可以請求的是特定數(shù)量的計(jì)算資源(CPU或內(nèi)存等),而PVC請求的是特定大小或特定訪問模式(只能被單節(jié)點(diǎn)讀寫/可被多節(jié)點(diǎn)只讀/可被多節(jié)點(diǎn)讀寫)的存儲資源。

PV和PVC的關(guān)系

PV(存儲卷)和PVC(存儲卷聲明)的關(guān)系如下圖所示:

K8s實(shí)現(xiàn)數(shù)據(jù)持久化

上圖中的解釋如下:

  • PV是集群中的存儲資源,通常由集群管理員創(chuàng)建和管理;
  • StorageClass用于對PV進(jìn)行分類,如果配置正確,Storage也可以根據(jù)PVC的請求動態(tài)創(chuàng)建PV;
  • PVC是使用該資源的請求,通常由應(yīng)用程序提出請求,并指定對應(yīng)的StorageClass和需求的空間大??;
  • PVC可以作為數(shù)據(jù)卷的一種,被掛載到pod中使用。
存儲卷聲明(PVC)的管理過程

PV和PVC的管理過程描述如下:
1、在主機(jī)上劃分出一個(gè)單獨(dú)的目錄用于PV使用,并且定義其可用大小
2、創(chuàng)建PVC這個(gè)資源對象,以便請求PV的存儲空間
3、pod中添加數(shù)據(jù)卷,數(shù)據(jù)卷關(guān)聯(lián)到PVC;
4、Pod中包含容器,容器掛載數(shù)據(jù)卷

其實(shí)上面解釋那么多,可能還是云里霧里的,下面是一個(gè)使用案例,僅供參考。

案例大概過程如下:
底層存儲采用nfs存儲,然后在nfs的目錄下劃分1G的容量供PV調(diào)度。然后通過創(chuàng)建PVC來申請PV的存儲資源空間,最后創(chuàng)建pod測試,使用PVC聲明的存儲資源來實(shí)現(xiàn)數(shù)據(jù)的持久化。

1)搭建nfs存儲

為了方便操作,我直接在master上搭建nfs存儲。

[root@master ~]# yum -y install nfs-utils
[root@master ~]# systemctl enable rpcbind
[root@master ~]# vim /etc/exports
/nfsdata *(rw,sync,no_root_squash)
[root@master ~]# systemctl start nfs-server
[root@master ~]# systemctl enable nfs-server
[root@master ~]# showmount -e
Export list for master:
/nfsdata *
2)創(chuàng)建PV資源對象
[root@master ~]# vim test-pv.yaml    #編輯PV的yaml文件

apiVersion: v1
kind: PersistentVolume
metadata:
  name: test-pv
spec:
  capacity:
    storage: 1Gi          #該P(yáng)V可分配的容量為1G
  accessModes:
    - ReadWriteOnce              #訪問模式為只能以讀寫的方式掛載到單個(gè)節(jié)點(diǎn)
  persistentVolumeReclaimPolicy: Recycle   #回收策略為Recycle
  storageClassName: nfs            #定義存儲類名字
  nfs:                                #這里和上面定義的存儲類名字需要一致
    path: /nfsdata/test-pv       #指定nfs的目錄
    server: 192.168.20.6           #nfs服務(wù)器的IP
#關(guān)于上述的具體解釋
#capacity:指定PV的大小
#AccessModes:指定訪問模式
    #ReadWriteOnce:只能以讀寫的方式掛載到單個(gè)節(jié)點(diǎn)(單個(gè)節(jié)點(diǎn)意味著只能被單個(gè)PVC聲明使用)
    #ReadOnlyMany:能以只讀的方式掛載到多個(gè)節(jié)點(diǎn)
    #ReadWriteMany:能以讀寫的方式掛載到多個(gè)節(jié)點(diǎn)
#persistentVolumeReclaimPolicy:PV的回收策略
    #Recycle:清除PV中的數(shù)據(jù),然后自動回收。
    #Retain:需要手動回收。
    #Delete:刪除云存儲資源。(云存儲專用)
    #PS:注意這里的回收策略是指,在PV被刪除后,在這個(gè)PV下所存儲的源文件是否刪除。
#storageClassName:PV和PVC關(guān)聯(lián)的依據(jù)。
[root@master ~]# kubectl apply -f test-pv.yaml     #執(zhí)行yaml文件
[root@master ~]# kubectl get pv test-pv    #既然PV是一個(gè)資源對象,那么自然可以通過此方式查看其狀態(tài)
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
test-pv   1Gi        RWO            Recycle          Available           nfs                     38s
#查看PV的狀態(tài)必須為Available才可以正常使用
3)創(chuàng)建PVC資源對象
[root@master ~]# vim test-pvc.yaml         #編寫yaml文件

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
spec:
  accessModes:          #定義訪問模式,必須和PV定義的訪問模式一致
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi          #直接請求使用最大的容量
  storageClassName: nfs      #這里的名字必須和PV定義的名字一致
[root@master ~]# kubectl apply -f test-pvc.yaml     #執(zhí)行yaml文件

#再次查看PV及PVC的狀態(tài)(狀態(tài)為bound,表示該P(yáng)V正在被使用)
[root@master ~]# kubectl get pvc      #查看PVC的狀態(tài)
NAME       STATUS   VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-pvc   Bound    test-pv   1Gi        RWO            nfs            2m10s
[root@master ~]# kubectl get pv      #查看PV的狀態(tài)
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM              STORAGECLASS   REASON   AGE
test-pv   1Gi        RWO            Recycle          Bound    default/test-pvc   nfs                     8m24s
4)創(chuàng)建一個(gè)Pod

這里創(chuàng)建的pod使用剛剛創(chuàng)建的PV來實(shí)現(xiàn)數(shù)據(jù)的持久化。

[root@master ~]# vim test-pod.yaml       #編寫pod的yaml文件
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: test-pod
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 30000
    volumeMounts:
    - mountPath: /testdata
      name: volumedata     #這里自定義個(gè)名稱
  volumes:
    - name: volumedata      #這里的是上面定義的名稱解釋,這兩個(gè)名稱必須一致
      persistentVolumeClaim:
        claimName: test-pvc
[root@master ~]# kubectl apply -f test-pod.yaml        #執(zhí)行yaml文件
[root@master ~]# kubectl get pod     #查看pod的狀態(tài),發(fā)現(xiàn)其一直處于ContainerCreating狀態(tài)
#怎么回事呢?
NAME       READY   STATUS              RESTARTS   AGE
test-pod   0/1     ContainerCreating   0          23s
#當(dāng)遇到pod狀態(tài)不正常時(shí),一般我們可以采用三種方式來排錯(cuò)
#第一就是使用kubectl  describe命令來查看pod的詳細(xì)信息
#第二就是使用kubectl logs命令來查看pod的日志
#第三就是查看宿主機(jī)本機(jī)的message日志
#這里我采用第一種方法排錯(cuò)
[root@master ~]# kubectl describe pod test-pod
#輸出的最后一條信息如下:
mount.nfs: mounting 192.168.20.6:/nfsdata/test-pv failed, reason given by server: No such file or directory
#原來是我們在掛載nfs存儲目錄時(shí),指定的目錄并不存在
#那就在nfs服務(wù)器上(這里是本機(jī))進(jìn)行創(chuàng)建相關(guān)目錄咯
[root@master ~]# mkdir -p /nfsdata/test-pv      #創(chuàng)建對應(yīng)目錄
[root@master ~]# kubectl get pod test-pod   #然后再次查看pod的狀態(tài)
#如果pod的狀態(tài)還是正在創(chuàng)建,那么就是因?yàn)檫\(yùn)行該pod的節(jié)點(diǎn)上的kubelet組件還沒有反應(yīng)過來
#如果要追求pod的啟動速度,可以手動將pod所在節(jié)點(diǎn)的kubelet組件進(jìn)行重啟即可。
[root@master ~]# kubectl get pod test-pod    #稍等片刻,再次查看,發(fā)現(xiàn)其pod已經(jīng)running了
NAME       READY   STATUS    RESTARTS   AGE
test-pod   1/1     Running   0          8m
5)測試其數(shù)據(jù)持久化的效果
[root@master ~]# kubectl exec -it test-pod /bin/sh   #進(jìn)入pod
/ # echo "test pv pvc" > /testdata/test.txt       #向數(shù)據(jù)持久化的目錄寫入測試信息
#回到nfs服務(wù)器,查看共享的目錄下是否有容器中寫入的信息
[root@master ~]# cat /nfsdata/test-pv/test.txt   #確定是有的
test pv pvc
#現(xiàn)在查看到pod容器的所在節(jié)點(diǎn),然后到對應(yīng)節(jié)點(diǎn)將其刪除
[root@master ~]# kubectl get pod -o wide       #我這里是運(yùn)行在node02節(jié)點(diǎn)
NAME       READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
test-pod   1/1     Running   0          11m   10.244.2.2   node02   <none>           <none>
#在node02節(jié)點(diǎn)查看到其pod容器的ID號,然后將其刪除
[root@node02 ~]# docker ps      #獲取容器的ID號
[root@node02 ~]# docker rm -f dd445dce9530   #刪除剛剛創(chuàng)建的容器
#回到nfs服務(wù)器,發(fā)現(xiàn)其本地目錄下的數(shù)據(jù)還是在的
[root@master ~]# cat /nfsdata/test-pv/test.txt 
test pv pvc
#那么現(xiàn)在測試,將這個(gè)pod刪除,nfs本地的數(shù)據(jù)是否還在?
[root@master ~]# kubectl delete -f test-pod.yaml 
[root@master ~]# cat /nfsdata/test-pv/test.txt      #哦吼,數(shù)據(jù)還在
test pv pvc
#那現(xiàn)在要是將PVC刪除呢?
[root@master ~]# kubectl delete -f test-pvc.yaml 
[root@master ~]# cat /nfsdata/test-pv/test.txt       #哦吼,數(shù)據(jù)不在了。
cat: /nfsdata/test-pv/test.txt: 沒有那個(gè)文件或目錄

總結(jié):由于我們在創(chuàng)建pv這個(gè)資源對象時(shí),采用的回收策略是清除PV中的數(shù)據(jù),然后自動回收,而PV這個(gè)資源對象是由PVC來申請使用的,所以不管是容器也好,pod也好,它們的銷毀并不會影響用于實(shí)現(xiàn)數(shù)據(jù)持久化的nfs本地目錄下的數(shù)據(jù),但是,一旦這個(gè)PVC被刪除,那么本地的數(shù)據(jù)就會隨著PVC的銷毀而不復(fù)存在,也就是說,采用PV這種數(shù)據(jù)卷來實(shí)現(xiàn)數(shù)據(jù)的持久化,它這個(gè)數(shù)據(jù)持久化的生命周期是和PVC的生命周期是一致的。

———————— 本文至此結(jié)束,感謝閱讀 ————————

分享題目:K8s實(shí)現(xiàn)數(shù)據(jù)持久化
網(wǎng)站路徑:http://muchs.cn/article8/jejiop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化電子商務(wù)、網(wǎng)站維護(hù)、App開發(fā)企業(yè)網(wǎng)站制作、虛擬主機(jī)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)