SkyDNS

2022-08-17 07:59:14 浏览数 (1)

为什么要使用SkyDNS

k8s最基础的调度单位是pod;当一个pod异常退出的时候会重新创建另一个pod,但是这个时候pod的ip就改变了,所以我们不能直接使用pod-ip来访问其他的pod。

k8s使用service,来处理这个问题,service可以理解成是pod的一个封装,会生成一个固定的虚拟ip来供其他service访问,访问service会被负载到后端的pod上面;具体service是如果负载到后端的pod是kube-proxy组件来控制的。

但是这里有一个问题service的ip是k8s生成的我们不能预先知道并不用,只能等service创建好,然后通过kubectl get svc来查询,这样就很不方便,而且当service很多的时候,ip的管理就复杂,难于记忆,而skydns就是用来处理这个问题,让我们通过域名(service的名称)来访问其他service。

SkyDNS组成

kube-dns是由四个容器组成。

SkyDNS是用于服务发现的开源框架,构建于etcd之上。作用是为k8s集群中的Pod提供DNS查询接口。

etcd是一种开源的分布式key-value存储,在kube-dns中的作用为存储SkyDNS需要的各种数据,写入方为kube2sky,读取方为SkyDNS。

kube2sky是k8s实现的一个适配程序,它通过名为kubernetes的Service(通过kubectl get svc可以查看到该Service,由集群自动创建)调用k8s的list和watch API来监听k8s Service资源的变更,从而修改etcd中的SkyDNS记录。

exec-healthz是k8s提供的一种辅助容器,多用于side car模式中。它的原理是定期执行指定的Linux指令,从而判断当前Pod中关键容器的健康状态。

搭建skydns

1.通过上面介绍我们知道skydns是由4个容器组成,所以我们第一步要拉取4个容器镜像(因为需要访问国外网站所以这里先手动拉取docek hub上面有大神已经上传,没弄健康检查)。

2.编写service.yaml,和rc.yaml

代码语言:javascript复制
//注意由于kube2sky要连接apiserver监听k8s Service资源的变更,从而修改etcd中的SkyDNS记录。所以要配置mastere的地址,但是master之前配置了要使用https去访问,这里不能直接配置--kube_master_url,而是通过--kubecfg-file来访问
[root@k8s-master1 ~]# cat skydns-rc.yml
apiVersion: v1
kind: ReplicationController
metadata:
name: kube-dns-v1
namespace: default
labels:
k8s-app: kube-dns
version: v1
spec:
replicas: 1
selector:
k8s-app: kube-dns
version: v1
template:
metadata:
labels:
k8s-app: kube-dns
version: v1
spec:
containers:
- name: etcd
image: outrider/etcd-amd64
command:
- /usr/local/bin/etcd
- -listen-client-urls
- http://0.0.0.0:2379,http://0.0.0.0:4001
- -advertise-client-urls
- http://127.0.0.1:2379,http://127.0.0.1:4001
- -initial-cluster-token
- skydns-etcd
- name: kube2sky
image: outrider/kube2sky
resources:
limits:
cpu: 100m
memory: 50Mi
command:
- /kube2sky
#- --kube_master_url=http://192.168.144.128:8080
- --kubecfg-file=/root/kubernetes/kubelet.kubeconfig
- --domain=cluster.local
volumeMounts:
- mountPath: /root/kubernetes/kubelet.kubeconfig
name: "kubeconfig"
- mountPath: /root/ssl
name: "ssl"
- name: skydns
image: outrider/skydns
resources:
command:
- /skydns
- -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
dnsPolicy: Default
volumes:
- name: "kubeconfig"
hostPath:
path: "/root/kubernetes/kubelet.kubeconfig"
- name: "ssl"
hostPath:
path: "/root/ssl"

kube-dns支持的域名格式,具体为:service_name.namespace.svc.cluster_domain

其中cluster_domain可以使用kubelet的—cluster-domain=SomeDomain参数进行设置,同时也要保证kube2sky容器的启动参数中—domain参数设置了相同的值。通常设置为cluster.local。既然完整域名是这样的,那为什么在Pod中只通过Service名称和Namespace就能访问Service呢?

kubelet —cluster-domain参数与search的具体配置是相对应的。而kube2sky容器的—domain参数影响的是写入到etcd中的域名,kube2sky会获取Service的名称和Namespace,并使用—domain参数拼接完整域名。这也就是让两个参数保持一致的原因。

为了在Pod中调用其他Service,kubelet会自动在容器中创建域名解析(/etc/resolv.conf)kubelet的配置参数 —cluster-dns=169.169.0.2 —cluster-domain=cluster.local resolv.conf内容

代码语言:javascript复制
[root@k8s-master1 ~]# cat /etc/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/root/kubelet
ExecStart=/usr/bin/kubelet 
--address=192.168.144.128 
--hostname-override=192.168.144.128 
--v=2 
--logtostderr=false 
--log-dir=/var/log/kubernetes 
--allow-privileged=true 
--anonymous-auth=true 
--client-ca-file=/root/ssl/ca.crt 
--cluster-dns=169.169.0.2 
--cluster-domain=cluster.local 
--fail-swap-on=false 
--kubeconfig=/root/kubernetes/kubelet.kubeconfig 
--pod-infra-container-image=xujinding/pause:3.1 
--register-node=true 
--cgroups-per-qos=true 
--cgroup-driver=cgroupfs 
--enforce-node-allocatable=pods,kube-reserved 
--kube-reserved-cgroup=/system.slice/kubelet.service 
--system-reserved-cgroup=/system.slice
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
[root@k8s-master1 ~]#

参考

0 人点赞