部署kubernetes dns 服务
k8s中的service分配的虚拟IP是固定的,而pod异常后新生成的pod ip会发生变化,可以通过service做代理关联到后端的pod。
通过设置k8s中的dns服务可以直接解析service的名字,得到对应service的ip,可以实现服务在集群内部互相访问。
本文档操作前提:
1.建立私有仓库,将etcd、skydns 和kube2sky 镜像上传到私有仓库
2.k8s中的网络已经打通
修改每个node上的kubelet配置文件
–cluster_dns=10.254.0.3 为DNS服务的ClusterIP地址
–cluster_domain=cluster.local 为DNS服务中设置的域名
$ vi /etc/kubernetes/kubelet KUBELET_ARGS="--cluster_dns=10.254.0.3 --cluster_domain=cluster.local "
重启kubelet
创建dns rc和service
#######定义yaml文件
1.skydns-rc.yaml
分别定义了三个容器:etcd、kube2sky、skydns
一个pod中包含三个容器。
可以通过kubectl describe pod pod-name --namespace=ns-name 查看详细pod的详细信息
apiVersion: v1
kind: ReplicationController
metadata:
name: kube-dns-v9
namespace: kube-system
labels:
k8s-app: kube-dns
version: v9
kubernetes.io/cluster-service: "true"
spec:
replicas: 1
selector:
k8s-app: kube-dns
version: v9
template:
metadata:
labels:
k8s-app: kube-dns
version: v9
kubernetes.io/cluster-service: "true"
spec:
containers:
- name: etcd
image: test-registry:5000/etcd
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: test-registry:5000/kube2sky
resources:
limits:
cpu: 100m
memory: 50Mi
args:
- -domain=cluster.local #设置k8s集群中Service所属的域名
- -kube_master_url=http://192.168.30.60:8080 #k8s中master的ip地址和apiserver中配置的端口号
- name: skydns
image: test-registry:5000/skydns
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
volumes:
- name: etcd-storage
emptyDir: {}
2.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.254.0.3 #/etc/kubernetes/kubelet中已经设定好clusterIP
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
创建rc和service
kubectl create -f skydns-rc.yaml,skydns-svc.yaml
检查服务
kubectl get svc --all-namespaces kubectl get rc --all-namespaces kubectl get pods --all-namespaces
排错
pod启动失败
1.检查镜像是否可以docker pull
2.检查镜像是否正常,docker run -it imageID sh
3.检查私有仓库
curl http://test-registry:5000/v2/_catalog
查看私有仓库里面的镜像
4.删除rc,检查kubelet 中的配置,然后重新启动
5.查看pod中的某个容器日志
kubectl logs pod-name -c container-name --all-namespaces
kubectl logs pod-name -c container-name --namespace=name
.......
.......
验证服务
1.创建一个名为redis-master的Service
apiVersion: v1
kind: Service
metadata:
name: redis-master
labels:
name: redis-master
spec:
selector:
name: redis-master
ports:
- port: 6379
targetPort: 6379
kubectl create -f redis-service.yaml
创建服务
2.创建一个带有nslookup工具的pod
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- image: docker.io/busybox
command:
- sleep
- "3600"
imagePullPolicy: IfNotPresent
name: busybox
restartPolicy: Always
使用kubectl create -f busybox.yaml
创建
3.进入busybox中解析服务
[root@k8s-master conf]# kubectl exec -it busybox sh
/ # nslookup redis-master
Server: 10.254.0.3
Address 1: 10.254.0.3
Name: redis-master
Address 1: 10.254.222.213
k8s dns原理
(1)etcd:DNS的存储
(2)kube2sky:将k8s master中的Service(服务)注册到etcd中
(3)skyDNS:提供DNS域名解析服务
1.在kube2sky容器中需要指定访问k8s master的地址,获取k8s集群中的服务。
2.kube2sky容器和skydns容器的启动参数-domain,设置Kubernetes集群中Service所属的域名,本例中为cluster.local。启动后,kube2sky会监听Kubernetes,当有新的Service创建时,就会使用kubelet配置的-cluster_dns=10.254.0.3 --cluster_domain=cluster.local
,在创建的资源中指定使用对应的dns服务器,并且生成相应的记录并保存到etcd中。kube2sky为每个Service生成两条记录,例如:
redis-master.default.cluster.local
redis-master.default.svc.cluster.local
3.skydns从etcd中获取dns的数据,然后解析服务。
4.etcd的数据来自kube2sky容器,kube2sky通过监听k8s master 中API获取集群所有Service的信息。然后将Service的信息保存到etcd容器中,提供给skydns使用
资料参考:权威指南第二版P153