k8s之DNS伺服器搭建
- 2021 年 1 月 3 日
- 筆記
- Kubernetes
一、導讀
在使用k8s部署springboot+redis簡單應用這篇文章中,spring boot連接redis是直接使用的IP連接,那麼可不可以直接使用服務名稱進行連接呢?答案是可以的,這就是k8s集群範圍內的DNS服務來完成服務名到ClusterIP的解析,接下來就一起看一下如何搭建DNS伺服器。
二、搭建DNS伺服器
(1)簡介
k8s提供的DNS服務是skydns,由四個組件組成
- etcd:DNS資訊存儲
- kube2sky:監控k8s中Service資源的變化,根據Service的名稱的IP地址資訊生成DNS記錄,並將其保存到etcd中
- skyDNS:從etcd中讀取DNS資訊,並提供DNS查詢服務
- healthz:提供對skydns服務的健康檢查功能
(2)skydns配置文件說明
skydns服務有一個RC和一個Service組成,分別由配置文件skydns-rc.yaml和skydns-svc.yaml定義。
skydns-rc.yaml包含了四個容器的定義:
apiVersion: v1 kind: ReplicationController metadata: name: kube-dns-v8 namespace: kube-system labels: k8s-app: kube-dns version: v8 kubernetes.io/cluster-service: "true" spec: replicas: 1 selector: k8s-app: kube-dns version: v8 template: metadata: labels: k8s-app: kube-dns version: v8 kubernetes.io/cluster-service: "true" spec: containers: - name: etcd image: empiregeneral/etcd-amd64:latest resources: limits: cpu: 100m memory: 50Mi command: - /usr/local/bin/etcd - -data-dir - /var/etcd/data - -listen-client-urls - //127.0.0.1:2379,//127.0.0.1:4001 - -advertise-client-urls - //127.0.0.1:2379,//127.0.0.1:4001 - -initial-cluster-token - skydns-etcd volumeMounts: - name: etcd-storage mountPath: /var/etcd/data - name: kube2sky image: syncgooglecontainers/kube2sky-amd64:1.15 resources: limits: cpu: 100m memory: 50Mi args: - --domain=cluster.local - --kube_master_url=//192.168.197.100:8080 - name: skydns image: yaronr/skydns:latest resources: limits: cpu: 100m memory: 50Mi args: - -machines=//localhost:4001 - -addr=0.0.0.0:53 - -domain=cluster.local ports: - containerPort: 53 name: dns protocol: UDP - containerPort: 53 name: dns-tcp protocol: TCP livenessProbe: httpGet: path: /healthz port: 8080 scheme: HTTP initialDelaySeconds: 30 timeoutSeconds: 5 - name: healthz image: syncgooglecontainers/exechealthz:1.1 resources: limits: cpu: 10m memory: 20Mi args: - -cmd=nslookup kubernetes.default.svc.cluster.local localhost >/dev/null - -port=8080 ports: - containerPort: 8080 protocol: TCP volumes: - name: etcd-storage emptyDir: {} dnsPolicy: Default # Don't use cluster DNS.
上述需要注意的是,需要將
--kube_master_url=//192.168.197.100:8080
改成集群中master的IP,鏡像如果下載失敗,可從docker hub裡面找,我就是從docker hub裡面找到相應的鏡像。
skydns-svc.yaml
apiVersion: v1 kind: Service metadata: name: kube-dns namespace: kube-system labels: k8s-app: kube-dns kubernetes.io/cluster-service: "true" kubernetes.io/name: "KubeDNS" spec: selector: k8s-app: kube-dns clusterIP: 10.96.0.10 ports: - name: dns port: 53 protocol: UDP - name: dns-tcp port: 53 protocol: TCP
需要指定一個clusterIP,不能靠k8s自動分配,每個Node的kubelet都是用這個IP地址,另外,這個IP需要在kube-apiserver啟動參數–service-cluster-ip-range指定的IP範圍內
kube-apiserver的配置文件在/etc/kubernetes/manifests目錄下:
(3)修改每台Node上的kubelet參數
添加以下兩個參數:
--cluster_dns=169.169.0.100: 為dns服務的clusterIP地址 --cluster_domain=cluster.local: 為dns服務中設置的域名
比如我這邊的是這樣:
vim /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf #添加如下一行 Environment="KUBELET_DNS_ARGS=--cluster-dns=10.96.0.10 --cluster-domain=cluster.local"
然後重啟kubelet,使用ps -ef | grep kubelet查看是否生效
重啟kubelet
systemctl stop kubelet systemctl daemon-reload systemctl start kubelet
修改完參數之後,啟動dns
kubectl create -f skydns-rc.yaml kubectl create -f skydns-svc.yaml
(4)驗證
啟動一個busybox容器。
apiVersion: v1 kind: Pod metadata: name: busybox labels: name: busybox namespace: default spec: containers: - image: busybox imagePullPolicy: IfNotPresent command: - sleep - "3600" name: busybox restartPolicy: Always
啟動之後進入容器內部:
nsloogup 服務名
可知解析後的ip是10.102.184.126。
然後查找對應的redis 的Service的ip,可以看到,兩個IP是對的上的。
又例如之前的springboot連接redis:
在構建鏡像的時候直接使用ip,這次改為使用服務名:
FROM centos:7 LABEL author=lsy ENV path=/usr/soft RUN mkdir ${path} WORKDIR ${path} ADD jdk-8u191-linux-x64.tar.gz ${path} ENV JAVA_HOME=${path}/jdk1.8.0_191 ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV PATH=$JAVA_HOME/bin:$PATH COPY k8s_demo-1.0.jar ${path} EXPOSE 8080 CMD java -jar -DredisIp=redis k8s_demo-1.0.jar
然後進行鏡像構建:
然後改為使用當前鏡像進行容器的構建,之後創建容器
測試:
設置值:
取值:
結尾:
祝願大家在新的一年裡心想事成!!!