關于K8s中Service Account的一些筆記:Pod內部如何訪問K8s API Server

      網友投稿 770 2025-04-03

      寫在前面

      學習K8s,這塊官方文檔的翻譯的有點生澀,不太好明白。所以整理下

      博文內容涉及

      Service Account的簡述

      Service Account的Demo

      官方文檔:https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-service-account/

      寫在前面

      學習K8s,這塊官方文檔的翻譯的有點生澀,不太好明白。所以整理下

      博文內容涉及

      Service Account的簡述

      Service Account的Demo

      官方文檔:https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-service-account/

      「 真正的堅持歸于平靜,靠的是溫和的發力,而不是時時刻刻的刺激。」

      學習環境

      ┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl get nodes NAME STATUS ROLES AGE VERSION vms81.liruilongs.github.io Ready control-plane,master 134d v1.22.2 vms82.liruilongs.github.io Ready 134d v1.22.2 vms83.liruilongs.github.io NotReady 134d v1.22.2 ┌──[root@vms81.liruilongs.github.io]-[~] └─$

      Service Account 是什么?

      學習Service Account之前,簡單介紹下K8s的安全體系,K8s中通過一系列機制來實現集群的安全控制,其中包括API Server的認證和授(鑒)權,關于認證和授(鑒)權,感興趣小伙伴可以看看之前的博文,我們這里簡單介紹下

      「關于授(鑒)權,現在用的比較多的是RBAC(Role-Based Access Control,基于角色的訪問控制)的方式」

      RBAC在Kubernetes的1.5版本中引入,在1.6版本時升級為Beta版本,在1.8版本時升級為GA。現在作為kubeadm安裝方式的默認選項,相對于其他訪問控制方式,RBAC對集群中的資源和非資源權限均有完整的覆蓋。整個RBAC完全由(Role,ClusterRole,RoleBinding,ClusterRoleBinding)API對象完成,同其他API對象一樣,可以用kubectl或API進行操作。可以在運行時進行調整,無須重新啟動 API Server。

      K8s的授權策略設置通過通過API Server的啟動參數"--authorization-mode"設置。 除了RBAC外,授權策略還包括:

      「關于認證機制,在K8s的認證中,如果按照集群內外認證分的話,分為集群外認證和集群內認證:」

      集群外認證一般三種,也可以理解為通過kubectl或者編程語言編寫的客戶端API訪問:

      HTTP Token認證:通過一個Token來識別合法用戶。

      HTTPS 證書認證:基于CA根證書簽名的雙向數字證書認證方式(Kubeconfig文件)

      HTTP Base認證:通過用戶名+密碼的方式認證(用戶賬戶),這個只有1.19之前的版本適用,之后的版本不在支持

      集群內的認證也就是我們今天要講的:Service Account對象,也叫服務賬戶

      所以說Service Account它并不是給Kubernetes集群的用戶(系統管理員、運維人員)用的,而是給運行在K8s上的Pod里的進程用的,為Pod里的進程提供認證。

      比如我們要編寫一個類似kubectl一樣的K8s的管理工具,如一些面板工具(kubernetes-dashboard),而且這個工具是運行在我們的K8s環境里的,那么這個時候,我們如何給這個工具訪問集群做認證授權,就要用到Service Account,簡寫為sa,所以我們一般直接叫sa,或者服務賬戶

      當我們創建任何一個Pod的時候,必須要有sa,否則會創建失敗,如果沒有顯示的指定對應的sa,即服務賬戶,Pod會默認使用當前的命令空間的default服務賬戶(每個命名空間都有一個名為 default 的sa資源。)

      這里要說明的是每個sa服務賬戶都會生成一個secret,這個secret里面包含一個token憑證。所以說sa實際認證是通過token實現的認證。(token)

      ┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl get sa default NAME SECRETS AGE default 1 67d ┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl run podcommon --image=nginx --image-pull-policy=IfNotPresent --labels="name=liruilong" --env="name=liruilong" pod/podcommon created ┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl get pods podcommon -o yaml | grep serviceAccount serviceAccount: default serviceAccountName: default - serviceAccountToken: ┌──[root@vms81.liruilongs.github.io]-[~] └─$

      可以使用自動掛載給Pod的default服務賬戶 token訪問 API,但是前提是需要給default授權,對于RBAC的方式來講,需要給角色授權,然后綁定角色。

      在 1.6 以上版本中,可以通過在sa上設置automountServiceAccountToken: false來實現不給服務賬號自動掛載 API token:

      apiVersion: v1 kind: ServiceAccount metadata: name: build-robot automountServiceAccountToken: false ...

      在 1.6 以上版本中,你也可以選擇不給特定 Pod 自動掛載 API token:

      apiVersion: v1 kind: Pod metadata: name: my-pod spec: serviceAccountName: build-robot automountServiceAccountToken: false ...

      如果 Pod 和服務賬戶都指定了automountServiceAccountToken值,則 Pod 的 spec 優先于服務帳戶。

      下面看一下kubernetes-dashboard對sa的應用,下面是一個已經部署好的dashboard

      關于kubernetes-dashboard是K8s官網提供的Kubernetes的Web UI網頁管理工具,可提供部署應用、資源對象管理、容器日志查詢、系統監控等常用的集群管理功能。

      ┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES dashboard-metrics-scraper-669c88c9d9-2qp62 1/1 Running 8 (7d11h ago) 61d 10.244.88.83 vms81.liruilongs.github.io kubernetes-dashboard-5d66bcd8fd-l22jm 1/1 Running 13 (7d3h ago) 61d 10.244.88.80 vms81.liruilongs.github.io ┌──[root@vms81.liruilongs.github.io]-[~] └─$ ┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl get svc -n kubernetes-dashboard NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE dashboard-metrics-scraper ClusterIP 10.109.92.159 8000/TCP 67d kubernetes-dashboard NodePort 10.106.48.37 443:32360/TCP 67d ┌──[root@vms81.liruilongs.github.io]-[~] └─$

      上面是一個我們之前部署好的面板工具,在部署的過程中,我們要主動創建一個sa(kubernetes-dashboard),并且為這個sa授權,而后,我們的這個面板工具才具有管理K8s集群的能力

      創建sa的資源文件

      apiVersion: v1 kind: ServiceAccount metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kubernetes-dashboard

      查看kubernetes-dashboard sa,可以看到對應的token

      ┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl get sa NAME SECRETS AGE ...... kubernetes-dashboard 1 67d ┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl get secrets NAME TYPE DATA AGE ......... kubernetes-dashboard-token-wnqqg kubernetes.io/service-account-token 3 67d ┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl describe secrets kubernetes-dashboard-token-wnqqg Name: kubernetes-dashboard-token-wnqqg Namespace: kubernetes-dashboard Labels: Annotations: kubernetes.io/service-account.name: kubernetes-dashboard kubernetes.io/service-account.uid: 8e209de5-14a0-4dd5-bd19-2264170531f5 Type: kubernetes.io/service-account-token Data ==== token: eyJhbGciOiJSUzI1NiIsImtpZCI6ImF2MmJVZ3d6M21JRC1BZUwwaHlDdzZHSGNyaVJON1BkUHF6MlhPV2NfX00ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJrdW.... ca.crt: 1099 bytes namespace: 20 bytes ┌──[root@vms81.liruilongs.github.io]-[~] └─$

      然后對sa授權,一般通過RBAC的方式.創建角色

      kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard rules: # Allow Metrics Scraper to get metrics from the Metrics server - apiGroups: ["metrics.k8s.io"] resources: ["pods", "nodes"] verbs: ["get", "list", "watch"]

      然后綁定角色到sa

      apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kubernetes-dashboard roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: kubernetes-dashboard subjects: - kind: ServiceAccount name: kubernetes-dashboard namespace: kubernetes-dashboard

      然后pod通過serviceAccount和serviceAccountName來綁定sa,當然這兩個參數指定一個就可以了。

      ┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl get pod kubernetes-dashboard-5d66bcd8fd-l22jm -o yaml | grep -C 5 serviceAccount preemptionPolicy: PreemptLowerPriority priority: 0 restartPolicy: Always schedulerName: default-scheduler securityContext: {} serviceAccount: kubernetes-dashboard serviceAccountName: kubernetes-dashboard terminationGracePeriodSeconds: 30

      通過yaml文件我們可以看到,值sa為kubernetes-dashboard,當然在資源文件中,是在Deployment和Servcie中指定,

      如果sa的automountServiceAccountToken或Pod的automountServiceAccountToken都未顯式設置為 false,那么會為對應的 Pod 創建一個 volume,在其中包含用來訪問 API 的令牌。

      如果為sa對應的token創建了卷,則為 Pod 中的每個容器添加一個 volumeSource,掛載在其 /var/run/secrets/kubernetes.io/serviceaccount 目錄下。

      ┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl get pod kubernetes-dashboard-5d66bcd8fd-l22jm -o yaml | grep -C 20 -i serviceAccount ........... volumeMounts: ........... - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: kube-api-access-8jlj7 readOnly: true ......... serviceAccount: kubernetes-dashboard serviceAccountName: kubernetes-dashboard ......... volumes: .......... - name: kube-api-access-8jlj7 projected: defaultMode: 420 sources: - serviceAccountToken: expirationSeconds: 3607 path: token ........ ┌──[root@vms81.liruilongs.github.io]-[~] └─$

      通過配置文件可以看到,token通過卷的方式掛載到了容器里的/var/run/secrets/kubernetes.io/serviceaccount 目錄,但是需要注意的是,這個token和sa對應的token在1.20版本之后進行了處理,不一樣,在之前的版本中是一樣的。

      Service Account Demo

      關于K8s中Service Account的一些筆記:Pod內部如何訪問K8s API Server

      創建一個sa

      ┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl create sa sa-demo serviceaccount/sa-demo created

      查看對應的secret和token

      ┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl get secrets sa-demo-token-pdrs8 NAME TYPE DATA AGE sa-demo-token-pdrs8 kubernetes.io/service-account-token 3 43s ┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl describe secrets sa-demo-token-pdrs8 Name: sa-demo-token-pdrs8 Namespace: kubernetes-dashboard Labels: Annotations: kubernetes.io/service-account.name: sa-demo kubernetes.io/service-account.uid: 7003de88-803a-4dae-a6e3-d647d0517c92 Type: kubernetes.io/service-account-token Data ==== ca.crt: 1099 bytes namespace: 20 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6ImF2MmJVZ3d6M21JRC1BZUwwaHlDdzZHSGNyaVJON1BkUHF6MlhPV2NfX00ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJzYS1kZW1vLXRva2VuLXBkcnM4Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6InNhLWRlbW8iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI3MDAzZGU4OC04MDNhLTRkYWUtYTZlMy1kNjQ3ZDA1MTdjOTIiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6c2EtZGVtbyJ9.sVAmtpfqFREjUCd9bkQvMuHpasXOcKYLJvVsJLLe6ufP4zs8ZVt6HqH4ylsxbmwtibNXBV9hVNEU_2X3T2enOjOSYuiyaEP4BifDQN7DmZbu2uXQCBglixaNB7ZIIPX_oQsW0ndBNonVqMSMm-ZItYDzLo-QTOxTxc5OQZ3zSBJqITAvWFlshWA7mKntNmWw6m5KunjhYZs14Lpa-NhknYS9G6ur8SKY4XdE44hzQhD7h4y01ZezZGR3IdGd3HktA5dWYTRXXr9H00odey2YtGfj40Vql3rMrdMPJOFbAozjyaWxhmSpjHVGcbXawai8znKPCdGlW4l2aRmbghovsw ┌──[root@vms81.liruilongs.github.io]-[~] └─$

      編寫pod資源文件,指定sa為剛才創建的sa

      ┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl run pod-sa --image=nginx --image-pull-policy=IfNotPresent --dry-run=client -o yaml > pod-sa.yaml ┌──[root@vms81.liruilongs.github.io]-[~] └─$vim pod-sa.yaml ┌──[root@vms81.liruilongs.github.io]-[~] └─$cat pod-sa.yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: pod-demo name: pod-demo spec: serviceAccount: sa-demo containers: - image: nginx imagePullPolicy: IfNotPresent name: pod-demo resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {} ┌──[root@vms81.liruilongs.github.io]-[~] └─$

      查看創建的pod

      ┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl apply -f pod-sa.yaml pod/pod-demo created ┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl get pods pod-demo NAME READY STATUS RESTARTS AGE pod-demo 1/1 Running 0 95s ┌──[root@vms81.liruilongs.github.io]-[~] └─$

      對于deplay的sa修改可以直接通過set的方式設置,時間關系這里不多講啦,文末的資源文件中有demo

      下面我們來看一道Service Account相關習題,這是某一期CKA認證的一道考題

      創建一個名為deployment-clusterrole且僅允許創建以下資源類型的新ClusterRole:

      Deployment

      StatefulSet

      DaemonSet

      在現有的 namespace app-team 中創建一個名為cicd-token的新 ServiceAccount。

      限于 namespace app-team 中,將新的ClusterRole deployment-clusterrole綁定到新的 ServiceAccount cicd-token。

      題目很簡單,一般的生產我們也會涉及,指定權限創建一個集群角色,然后把這個集群角色綁定到一個新建的sa上。

      # 創建集群角色 kubectl create clusterrole deployment-clusterrole --verb=create --resource=deployments,statefulsets,daemonsets # 創建服務賬戶 kubectl -n app-team create serviceaccount cicd-token # 綁定角色到服務賬戶 kubectl -n app-team create rolebinding cicd-token-rolebinding --clusterrole=deployment-clusterrole --serviceaccount=app-team:cicd-token

      對sa學習,感覺kubernetes-dashboard的是一個很好的Demo。這里把面板的資源文件貼出來,感興趣小伙伴可以研究下

      # Copyright 2017 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. apiVersion: v1 kind: Namespace metadata: name: kubernetes-dashboard --- apiVersion: v1 kind: ServiceAccount metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kubernetes-dashboard --- kind: Service apiVersion: v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kubernetes-dashboard spec: ports: - port: 443 targetPort: 8443 selector: k8s-app: kubernetes-dashboard --- apiVersion: v1 kind: Secret metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard-certs namespace: kubernetes-dashboard type: Opaque --- apiVersion: v1 kind: Secret metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard-csrf namespace: kubernetes-dashboard type: Opaque data: csrf: "" --- apiVersion: v1 kind: Secret metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard-key-holder namespace: kubernetes-dashboard type: Opaque --- kind: ConfigMap apiVersion: v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard-settings namespace: kubernetes-dashboard --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kubernetes-dashboard rules: # Allow Dashboard to get, update and delete Dashboard exclusive secrets. - apiGroups: [""] resources: ["secrets"] resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"] verbs: ["get", "update", "delete"] # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map. - apiGroups: [""] resources: ["configmaps"] resourceNames: ["kubernetes-dashboard-settings"] verbs: ["get", "update"] # Allow Dashboard to get metrics. - apiGroups: [""] resources: ["services"] resourceNames: ["heapster", "dashboard-metrics-scraper"] verbs: ["proxy"] - apiGroups: [""] resources: ["services/proxy"] resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"] verbs: ["get"] --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard rules: # Allow Metrics Scraper to get metrics from the Metrics server - apiGroups: ["metrics.k8s.io"] resources: ["pods", "nodes"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kubernetes-dashboard roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: kubernetes-dashboard subjects: - kind: ServiceAccount name: kubernetes-dashboard namespace: kubernetes-dashboard --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kubernetes-dashboard roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: kubernetes-dashboard subjects: - kind: ServiceAccount name: kubernetes-dashboard namespace: kubernetes-dashboard --- kind: Deployment apiVersion: apps/v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kubernetes-dashboard spec: replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: k8s-app: kubernetes-dashboard template: metadata: labels: k8s-app: kubernetes-dashboard spec: containers: - name: kubernetes-dashboard #image: kubernetesui/dashboard:v2.0.0-beta8 image: registry.cn-hangzhou.aliyuncs.com/kube-iamges/dashboard:v2.0.0-beta8 #imagePullPolicy: Always imagePullPolicy: IfNotPresent ports: - containerPort: 8443 protocol: TCP args: - --auto-generate-certificates - --namespace=kubernetes-dashboard # Uncomment the following line to manually specify Kubernetes API server Host # If not specified, Dashboard will attempt to auto discover the API server and connect # to it. Uncomment only if the default does not work. # - --apiserver-host=http://my-address:port volumeMounts: - name: kubernetes-dashboard-certs mountPath: /certs # Create on-disk volume to store exec logs - mountPath: /tmp name: tmp-volume livenessProbe: httpGet: scheme: HTTPS path: / port: 8443 initialDelaySeconds: 30 timeoutSeconds: 30 securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true runAsUser: 1001 runAsGroup: 2001 volumes: - name: kubernetes-dashboard-certs secret: secretName: kubernetes-dashboard-certs - name: tmp-volume emptyDir: {} serviceAccountName: kubernetes-dashboard nodeSelector: "kubernetes.io/os": linux # Comment the following tolerations if Dashboard must not be deployed on master tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule --- kind: Service apiVersion: v1 metadata: labels: k8s-app: dashboard-metrics-scraper name: dashboard-metrics-scraper namespace: kubernetes-dashboard spec: ports: - port: 8000 targetPort: 8000 selector: k8s-app: dashboard-metrics-scraper --- kind: Deployment apiVersion: apps/v1 metadata: labels: k8s-app: dashboard-metrics-scraper name: dashboard-metrics-scraper namespace: kubernetes-dashboard spec: replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: k8s-app: dashboard-metrics-scraper template: metadata: labels: k8s-app: dashboard-metrics-scraper annotations: seccompProfile: 'runtime/default' spec: containers: - name: dashboard-metrics-scraper #image: kubernetesui/metrics-scraper:v1.0.1 image: registry.cn-hangzhou.aliyuncs.com/kube-iamges/metrics-scraper:v1.0.1 imagePullPolicy: IfNotPresent ports: - containerPort: 8000 protocol: TCP livenessProbe: httpGet: scheme: HTTP path: / port: 8000 initialDelaySeconds: 30 timeoutSeconds: 30 volumeMounts: - mountPath: /tmp name: tmp-volume securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true runAsUser: 1001 runAsGroup: 2001 serviceAccountName: kubernetes-dashboard nodeSelector: "kubernetes.io/os": linux # Comment the following tolerations if Dashboard must not be deployed on master tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule volumes: - name: tmp-volume emptyDir: {}

      API Kubernetes

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

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

      上一篇:word表格如何增加一行
      下一篇:【云小課】【第35課】其他云MySQL遷移到RDS for MySQL實例
      相關文章
      亚洲А∨精品天堂在线| 亚洲AV无码一区二区三区鸳鸯影院| 亚洲国产第一站精品蜜芽| 亚洲精品福利网站| 亚洲AV蜜桃永久无码精品| 亚洲a∨无码一区二区| 亚洲自偷精品视频自拍| 亚洲一级二级三级不卡| 亚洲人成色7777在线观看不卡| 精品久久亚洲中文无码| 亚洲日本va在线视频观看| 中文字幕无码亚洲欧洲日韩| 国产AV无码专区亚洲AV手机麻豆| 亚洲成熟丰满熟妇高潮XXXXX| 亚洲色图在线观看| 亚洲精品麻豆av| 色欲色欲天天天www亚洲伊| 亚洲av日韩专区在线观看| 欧洲亚洲综合一区二区三区| 国产精品亚洲精品久久精品| 亚洲第一成人影院| 中文字幕在亚洲第一在线| 国产精品亚洲专区无码唯爱网| 日韩欧美亚洲中文乱码| 亚洲国产电影av在线网址| 亚洲麻豆精品国偷自产在线91| 亚洲综合av永久无码精品一区二区| 亚洲精品成人无限看| 久久精品国产精品亚洲下载| 中文字幕亚洲一区| 亚洲AV无码一区东京热| 国产精一品亚洲二区在线播放| 亚洲AV永久精品爱情岛论坛| 91在线亚洲精品专区| 久久精品国产亚洲av麻| 亚洲乱色熟女一区二区三区丝袜| 亚洲AV无码乱码国产麻豆| 亚洲经典在线中文字幕| 亚洲色精品VR一区区三区| 亚洲av无码一区二区三区四区| 亚洲国产欧美一区二区三区|