附011.Kubernetes-DNS及搭建

来源:https://www.cnblogs.com/itzgr/archive/2019/12/03/11978187.html
-Advertisement-
Play Games

一 Kubernetes DNS介紹1.1 Kubernetes DNS發展作為服務發現機制的基本功能,在集群內需要能夠通過服務名對服務進行訪問,因此需要一個集群範圍內的DNS服務來完成從服務名到ClusterIP的解析。DNS服務在Kubernetes的發展過程中經歷了3個階段,SkyDNS --... ...


一 Kubernetes DNS介紹

1.1 Kubernetes DNS發展

作為服務發現機制的基本功能,在集群內需要能夠通過服務名對服務進行訪問,因此需要一個集群範圍內的DNS服務來完成從服務名到ClusterIP的解析。 DNS服務在Kubernetes的發展過程中經歷了3個階段,SkyDNS ----> KubeDNS ----> CoreDNS。

1.2 SkyDNS

在Kubernetes 1.2版本時,DNS服務是由SkyDNS提供的,它由4個容器組成:kube2sky、skydns、etcd和healthz。 kube2sky容器監控Kubernetes中Service資源的變化,根據Service的名稱和IP地址信息生DNS記錄,並將其保存到etcd中。 skydns容器從etcd中讀取DNS記錄,併為客戶端容器應用提供DNS查詢服務。 healthz容器提供對skydns服務的健康檢查功能。 SkyDNS的總體架構如下: clipboard

1.3 KubeDNS

從Kubernetes 1.4版本開始,SkyDNS組件便被KubeDNS替換,主要考慮是SkyDNS組件之間通信較多,整體性能不高。 KubeDNS由3個容器組成:kubedns、dnsmasq和sidecar,去掉了SkyDNS中的etcd存儲,將DNS記錄直接保存在記憶體中,以提高查詢性能。 kubedns容器監控Kubernetes中Service資源的變化,根據Service的名稱和IP地址生成DNS記錄,並將DNS記錄保存在記憶體中。 dnsmasq容器從kubedns中獲取DNS記錄,提供DNS緩存,為客戶端容器應用提供DNS查詢服務。 sidecar提供對kubedns和dnsmasq服務的健康檢查功能。 KubeDNS的總體架構如下: clipboard

1.4 CoreDNS

從Kubernetes 1.11版本開始,Kubernetes集群的DNS服務由CoreDNS提供。CoreDNS是CNCF基金會的一個項目,是用Go語言實現的高性能、插件式、易擴展的DNS服務端。 CoreDNS解決了KubeDNS的一些問題,例如dnsmasq的安全漏洞、externalName不能使用stubDomains設置,等等。 CoreDNS支持自定義DNS記錄及配置upstream DNS Server,可以統一管理Kubernetes基於服務的內部DNS和數據中心的物理DNS。 CoreDNS沒有使用多個容器的架構,只用一個容器便實現了KubeDNS內3個容器的全部功能。 CoreDNS的總體架構如下: clipboard

二 CoreDNS部署

2.1 修改kubelet啟動參數

部署之前需要修改每個Node上kubelet的啟動參數,加上以下兩個參數:
  • --cluster-dns=169.169.0.100:為DNS服務的ClusterIP地址。
  • --cluster-domain=cluster.local:為在DNS服務中設置的功能變數名稱。
然後重啟kubelet服務。 提示:也可通過如下方式引入yaml配置文件實現:
  1 # vi /etc/systemd/system/kubelet.service
  2 ……
  3 --config=/etc/kubernetes/kubelet-config.yaml \
  4 ……
  5 # vi /etc/kubernetes/kubelet-config.yaml
  6 ……
  7 clusterDomain: "cluster.local"
  8 clusterDNS:
  9   - "10.254.0.2"
 10 ……

2.2 創建授權

在啟用了RBAC的集群中, 還可以設置ServiceAccount、 ClusterRole、 ClusterRoleBinding對CoreDNS容器進行許可權設置。ServiceAccount、 ClusterRole、 ClusterRoleBinding相關yaml如下:
  1 [root@k8smaster01 ~]# vi corednsaccout.yaml
  2 # __MACHINE_GENERATED_WARNING__
  3 
  4 apiVersion: v1
  5 kind: ServiceAccount
  6 metadata:
  7   name: coredns
  8   namespace: kube-system
  9   labels:
 10       kubernetes.io/cluster-service: "true"
 11       addonmanager.kubernetes.io/mode: Reconcile
 12 ---
 13 apiVersion: rbac.authorization.k8s.io/v1
 14 kind: ClusterRole
 15 metadata:
 16   labels:
 17     kubernetes.io/bootstrapping: rbac-defaults
 18     addonmanager.kubernetes.io/mode: Reconcile
 19   name: system:coredns
 20 rules:
 21 - apiGroups:
 22   - ""
 23   resources:
 24   - endpoints
 25   - services
 26   - pods
 27   - namespaces
 28   verbs:
 29   - list
 30   - watch
 31 - apiGroups:
 32   - ""
 33   resources:
 34   - nodes
 35   verbs:
 36   - get
 37 ---
 38 apiVersion: rbac.authorization.k8s.io/v1
 39 kind: ClusterRoleBinding
 40 metadata:
 41   annotations:
 42     rbac.authorization.kubernetes.io/autoupdate: "true"
 43   labels:
 44     kubernetes.io/bootstrapping: rbac-defaults
 45     addonmanager.kubernetes.io/mode: EnsureExists
 46   name: system:coredns
 47 roleRef:
 48   apiGroup: rbac.authorization.k8s.io
 49   kind: ClusterRole
 50   name: system:coredns
 51 subjects:
 52 - kind: ServiceAccount
 53   name: coredns
 54   namespace: kube-system
 55 
 56 [root@k8smaster01 ~]# kubectl create -f corednsaccout.yaml

2.3 創建ConfigMap

  1 [root@k8smaster01 ~]# vi corednsconfigmap.yaml
  2 apiVersion: v1
  3 kind: ConfigMap
  4 metadata:
  5   name: coredns
  6   namespace: kube-system
  7   labels:
  8       addonmanager.kubernetes.io/mode: EnsureExists
  9 data:
 10   Corefile: |
 11     .:53 {
 12         errors
 13         health
 14         kubernetes cluster.local in-addr.arpa ip6.arpa {
 15             pods insecure
 16             upstream
 17             fallthrough in-addr.arpa ip6.arpa
 18         }
 19         prometheus :9153
 20         forward . /etc/resolv.conf
 21         cache 30
 22         loop
 23         reload
 24         loadbalance
 25     }
 26 
 27 [root@k8smaster01 ~]# kubectl create -f corednsconfigmap.yaml

2.4 創建Deployment

  1 [root@k8smaster01 ~]# vi corednsdeploy.yaml
  2 apiVersion: apps/v1
  3 kind: Deployment
  4 metadata:
  5   name: coredns
  6   namespace: kube-system
  7   labels:
  8     k8s-app: kube-dns
  9     kubernetes.io/cluster-service: "true"
 10     addonmanager.kubernetes.io/mode: Reconcile
 11     kubernetes.io/name: "CoreDNS"
 12 spec:
 13   # replicas: not specified here:
 14   # 1. In order to make Addon Manager do not reconcile this replicas parameter.
 15   # 2. Default is 1.
 16   # 3. Will be tuned in real time if DNS horizontal auto-scaling is turned on.
 17   strategy:
 18     type: RollingUpdate
 19     rollingUpdate:
 20       maxUnavailable: 1
 21   selector:
 22     matchLabels:
 23       k8s-app: kube-dns
 24   template:
 25     metadata:
 26       labels:
 27         k8s-app: kube-dns
 28       annotations:
 29         seccomp.security.alpha.kubernetes.io/pod: 'docker/default'
 30     spec:
 31       priorityClassName: system-cluster-critical
 32       serviceAccountName: coredns
 33       tolerations:
 34         - key: "CriticalAddonsOnly"
 35           operator: "Exists"
 36       nodeSelector:
 37         beta.kubernetes.io/os: linux
 38       containers:
 39       - name: coredns
 40         image: registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.3.1
 41         imagePullPolicy: IfNotPresent
 42         resources:
 43           limits:
 44             memory: 170Mi
 45           requests:
 46             cpu: 100m
 47             memory: 70Mi
 48         args: [ "-conf", "/etc/coredns/Corefile" ]
 49         volumeMounts:
 50         - name: config-volume
 51           mountPath: /etc/coredns
 52           readOnly: true
 53         ports:
 54         - containerPort: 53
 55           name: dns
 56           protocol: UDP
 57         - containerPort: 53
 58           name: dns-tcp
 59           protocol: TCP
 60         - containerPort: 9153
 61           name: metrics
 62           protocol: TCP
 63         livenessProbe:
 64           httpGet:
 65             path: /health
 66             port: 8080
 67             scheme: HTTP
 68           initialDelaySeconds: 60
 69           timeoutSeconds: 5
 70           successThreshold: 1
 71           failureThreshold: 5
 72         readinessProbe:
 73           httpGet:
 74             path: /health
 75             port: 8080
 76             scheme: HTTP
 77         securityContext:
 78           allowPrivilegeEscalation: false
 79           capabilities:
 80             add:
 81             - NET_BIND_SERVICE
 82             drop:
 83             - all
 84           readOnlyRootFilesystem: true
 85       dnsPolicy: Default
 86       volumes:
 87         - name: config-volume
 88           configMap:
 89             name: coredns
 90             items:
 91             - key: Corefile
 92               path: Corefile
 93 
 94 [root@k8smaster01 ~]# kubectl create -f corednsdeploy.yaml
提示:replicas副本的數量通常應該根據集群的規模和服務數量確定,如果單個CoreDNS進程不足以支撐整個集群的DNS查詢,則可以通過水平擴展提高查詢能力。由於DNS服務是Kubernetes集群的關鍵核心服務,所以建議為其Deployment設置自動擴縮容控制器,自動管理其副本數量。 同時,對資源限制部分(CPU限制和記憶體限制) 的設置也應根據實際環境進行調整。

2.5 創建Service

  1 [root@k8smaster01 ~]# vi corednssvc.yaml
  2 apiVersion: v1
  3 kind: Service
  4 metadata:
  5   name: kube-dns
  6   namespace: kube-system
  7   annotations:
  8     prometheus.io/port: "9153"
  9     prometheus.io/scrape: "true"
 10   labels:
 11     k8s-app: kube-dns
 12     kubernetes.io/cluster-service: "true"
 13     addonmanager.kubernetes.io/mode: Reconcile
 14     kubernetes.io/name: "CoreDNS"
 15 spec:
 16   selector:
 17     k8s-app: kube-dns
 18   clusterIP: 10.254.0.2
 19   ports:
 20   - name: dns
 21     port: 53
 22     protocol: UDP
 23   - name: dns-tcp
 24     port: 53
 25     protocol: TCP
 26   - name: metrics
 27     port: 9153
 28     protocol: TCP
 29 
 30 [root@k8smaster01 ~]# kubectl create -f corednssvc.yaml

2.6 確認驗證

  1 [root@k8smaster01 ~]# kubectl get deployments --namespace=kube-system
  2 NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
  3 coredns                1/1     1            1           14s
  4 [root@k8smaster01 ~]# kubectl get pod --namespace=kube-system
  5 NAME                                    READY   STATUS    RESTARTS   AGE
  6 coredns-5b46b98d57-cknrr                1/1     Running   0          34s
  7 [root@k8smaster01 ~]# kubectl get svc --namespace=kube-system
  8 NAME                   TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                  AGE
  9 kube-dns               ClusterIP   10.254.0.2     <none>        53/UDP,53/TCP,9153/TCP   47s

三 服務名DNS解析

3.1 創建測試Pod

  1 [root@k8smaster01 ~]# vi busybox.yaml
  2 apiVersion: v1
  3 kind: Pod
  4 metadata:
  5   name: busybox
  6   namespace: default
  7 spec:
  8   containers:
  9   - name: busybox
 10     image: gcr.azk8s.cn/google_containers/busybox
 11     command:
 12       - sleep
 13       - "3600"
 14 
 15 [root@k8smaster01 ~]# kubectl exec -ti busybox -- nslookup webapp		#測試解析
 16 Server:    10.254.0.2
 17 Address 1: 10.254.0.2 kube-dns.kube-system.svc.cluster.local
 18 
 19 Name:      webapp
 20 Address 1: 10.254.156.234 webapp.default.svc.cluster.local
提示:如果某個Service屬於不同的命名空間,那麼在進行Service查找時,需要補充Namespace的名稱,組合成完整的功能變數名稱。
  1 [root@k8smaster01 ~]# kubectl exec -ti busybox -- nslookup kube-dns.kube-system	#補充kube-system的namespace
  2 Server:    10.254.0.2
  3 Address 1: 10.254.0.2 kube-dns.kube-system.svc.cluster.local
  4 
  5 Name:      kube-dns.kube-system
  6 Address 1: 10.254.0.2 kube-dns.kube-system.svc.cluster.local

四 CoreDNS配置說明

4.1 常見插件

CoreDNS的主要功能是通過插件系統實現的。CoreDNS實現了一種鏈式插件結構,將DNS的邏輯抽象成了一個個插件,能夠靈活組合使用。 常用的插件如下:
  • loadbalance:提供基於DNS的負載均衡功能。
  • loop:檢測在DNS解析過程中出現的簡單迴圈問題。
  • cache:提供前端緩存功能。
  • health:對Endpoint進行健康檢查。
  • kubernetes:從Kubernetes中讀取zone數據。
  • etcd:從etcd讀取zone數據,可以用於自定義功能變數名稱記錄。
  • file:從RFC1035格式文件中讀取zone數據。
  • hosts:使用/etc/hosts文件或者其他文件讀取zone數據,可以用於自定義功能變數名稱記錄。
  • auto:從磁碟中自動載入區域文件。
  • reload:定時自動重新載入Corefile配置文件的內容。
  • forward:轉發功能變數名稱查詢到上游DNS伺服器。
  • proxy:轉發特定的功能變數名稱查詢到多個其他DNS伺服器,同時提供到多個DNS伺服器的負載均衡功能。
  • prometheus:為Prometheus系統提供採集性能指標數據的URL。
  • pprof:在URL路徑/debug/pprof下提供運行時的性能數據。
  • log:對DNS查詢進行日誌記錄。
  • errors:對錯誤信息進行日誌記錄。

4.2 插件配置

示例1:
  1 [root@k8smaster01 ~]# vi corednsconfigmap.yaml
  2 apiVersion: v1
  3 kind: ConfigMap
  4 metadata:
  5   name: coredns
  6   namespace: kube-system
  7   labels:
  8       addonmanager.kubernetes.io/mode: EnsureExists
  9 data:
 10   Corefile: |
 11     .:53 {
 12         errors
 13         health
 14         kubernetes cluster.local in-addr.arpa ip6.arpa {
 15             pods insecure
 16             upstream
 17             fallthrough in-addr.arpa ip6.arpa
 18         }
 19         prometheus :9153
 20         forward . /etc/resolv.conf
 21         cache 30
 22         loop
 23         reload
 24         loadbalance
 25     }
如上所示為功能變數名稱“cluster.local”設置了一系列插件, 包括errors、health、kubernetes、prometheus、forward、cache、loop、reload和loadbalance,在進行功能變數名稱解析時, 這些插件將以從上到下的順序依次執行。 示例2:如下為使用etcd插件的配置示例,將以“.com”結尾的功能變數名稱記錄配置為從etcd中獲取,並將功能變數名稱記錄保存在/skydns路徑下。
  1 {
  2 etcd com {
  3 path /skydns
  4 endpoint http://192.168.18.3:2379
  5 upstream /etc/resolv.conf
  6 }
  7 cache 160 com
  8 loadbalance
  9 proxy . /etc/resolv.conf
 10 
 11 }
 12 [root@k8smaster01 ~]# etcdctl put /skydns/com/mycompany '{"host":"10.1.1.1","ttl":"60"}'	#測試插入
 13 [root@k8smaster01 ~]# nslookpu mycompany.com
提示:forward和proxy插件都可以用於配置上游DNS伺服器或其他DNS伺服器,當在CoreDNS中查詢不到功能變數名稱時,會到其他DNS伺服器上進行查詢。在實際環境中,可以將Kubernetes集群外部的DNS納入CoreDNS,進行統一的DNS管理。

五 Pod級別的DNS設置

5.1 Pod級別設置

集群的DNS(CoreDNS)配置之外,針對Pod中也可以設置相應的DNS策略。 示例1:
  1 [root@k8smaster01 study]# vi mywebapp.yaml
  2 apiVersion: v1
  3 kind: Pod
  4 metadata:
  5   name: webapp
  6 spec:
  7   containers:
  8   - name: webapp
  9     image: tomcat
 10   dnsPolicy: Default
 11 ……
目前可以設置的DNS策略如下:
  • Default:繼承Pod所在宿主機的DNS設置。
  • ClusterFirst:優先使用Kubernetes環境的DNS服務(如CoreDNS提供的功能變數名稱解析服務),將無法解析的功能變數名稱轉發到從宿主機繼承的DNS伺服器。
  • ClusterFirstWithHostNet:與ClusterFirst相同,對於以hostNetwork模式運行的Pod,應明確指定使用該策略。
  • None:忽略Kubernetes環境的DNS配置,通過spec.dnsConfig自定義DNS配置。這個選項從Kubernetes1.9版本開始引入,到Kubernetes 1.10版本升級為Beta版,到Kubernetes1.14版本升級為穩定版。自定義DNS配置可以通過spec.dnsConfig欄位進行設置,可以設置下列信息。
    • nameservers:一組DNS伺服器的列表,最多可以設置3個。
    • searches:一組用於功能變數名稱搜索的DNS功能變數名稱尾碼,最多可以設置6個。
    • options:配置其他可選DNS參數,例如ndots、timeout等,以name或name/value對的形式表示。
示例2:dnsConfig外部欄位配置示例。
  1 [root@k8smaster01 study]# vi mywebapp.yaml
  2 apiVersion: v1
  3 kind: Pod
  4 metadata:
  5   namespace: default
  6   name: dns-example
  7 spec:
  8   containers:
  9   - name: test
 10     image: nginx
 11   dnsPolicy: "None"
 12   dnsConfig:
 13     nameservers:
 14       - 223.5.5.5
 15     searches:
 16       - ns1.svc.cluster.local
 17       - my.dns.search.suffix
 18     options:
 19       - name: ndots
 20         value: "2"
 21       - name: edns0
  1 [root@k8smaster01 study]# kubectl create -f mywebapp.yaml
  2 [root@k8smaster01 study]# kubectl exec -ti dns-example -- cat /etc/resolv.conf		#確認查看
  3 nameserver 223.5.5.5
  4 search ns1.svc.cluster.local my.dns.search.suffix
  5 options ndots:2 edns0
提示:如上配置從而實現Pod中自定義DNS,而不再使用Kubernetes環境的DNS服務。
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 複習一下WPF的UIElement.Clip 用了很久很久的WPF,但幾乎沒有主動用過它的Clip屬性,我只記得它很靈活,可以裁剪出多種形狀。在 "官方文檔" 複習了一下,大致用法和效果如下: WPF的Clip是一個 "Geometry" 屬性,它有多種派生類: 有這麼多種Geometry,W ...
  • 該問題可能導致tomcat啟動成功了,但是瀏覽器輸入http://127.0.0.1:8080無法顯示tomcat的歡迎界面 打開Tomcat安裝目錄下的bin文件下的setclasspath.sh,在文檔開頭添加如下語句: export JAVA_HOME=你的jdk路徑 export JRE_H ...
  • Linux 命令之 scp 命令詳解 一、scp 簡介 scp 命令用於不同主機之間複製文件和目錄。 scp 是 secure copy 的縮寫,是 基於 ssh 協議進行安全的遠程文件拷貝命令。 scp 想要免密進行複製,需要發送秘鑰給相應的節點。 scp 是加密的,rcp 是不加密的,scp 是 ...
  • KubeSphere 不僅支持部署在 Linux 之上,還支持在已有 Kubernetes 集群之上部署 KubeSphere,自動納管 Kubernetes 集群的已有資源與容器。 前提條件 版本: Helm = 2.10.0`(不支持 helm 2.16.0 " 6894" ),且已安裝了 Ti ...
  • CentOS 7 下安裝部署java+tomcat+mysql 前置:CentOS7安裝:https://jingyan.baidu.com/article/b7001fe1d1d8380e7382dd72.html 附常用命令合集:https://www.cnblogs.com/icebutter ...
  • 今天,下午刷手機的時候,突然看到kali出了一個非常新穎的主題;該主題可以使得kali系統偽裝成windows 10而變得低調起來;就像下麵這樣: 具體新聞鏈接:https://www.freebuf.com/news/221582.html Kali Undercover模式 如果你在某些環境中想 ...
  • 最近需要使用 kali 源安裝一些軟體: 配置 sources.list,根據如下鏈接:http://mirrors.ustc.edu.cn/help/kali.html 獲取 公鑰;apt-key adv --keyserver keyserver.ubuntu.com --recv ED444F ...
  • 前言 上周四,伺服器突然掛了。SSH都連接不上,日常的小程式後臺直接down掉,小程式每日大概3K左右訪問量。於是乎就開啟了,排查之後。 排查階段 什麼先別說,先把服務恢復再說。重啟阿裡雲伺服器,SSH連接。開啟nginx,redis,mysql,java服務。一系列操作,先把服務先啟動了。 伺服器 ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...