一、導讀
在使用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 - http://127.0.0.1:2379,http://127.0.0.1:4001 - -advertise-client-urls - http://127.0.0.1:2379,http://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=http://192.168.197.100:8080 - name: skydns image: yaronr/skydns:latest resources: limits: cpu: 100m memory: 50Mi args: - -machines=http://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=http://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
然後進行映象構建:
然後改為使用當前映象進行容器的構建,之後建立容器
測試:
設定值:
取值:
結尾:
祝願大家在新的一年裡心想事成!!!