上一回有关kubedns服务中报错,这一回整体整理一下。
一,Kubedns工作原理
1. kubedns:kubedns监控并记录service与ip之间的映射关系,以树形结构将数据保存在内存中。
2. dnsmasq:从记录的地方查询相关的解析记录
特点:使用内存做dns缓存,速度非常快
3. exechealthz:用来监控kubedns和dnsmasq是否出现问题,做健康检测
二,kubedns组成简介
1. dnsmasq
小巧的DNS配置工具
在kubedns中作用
通过kubedns容器获取DNS规则,在集群中提供DNS查询服务,相当于dns的server端。
提供DNS缓存,提高查询性能
降低kubedns容器的压力、提高稳定性
2. kubedns
监视k8s service资源并更新DNS记录
3. exechealthz
定期检查kubedns和dnsmasq的健康状态
为k8s活性检测提供HTTP API
4. github地址
https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns/kube-dns
5. 官网地址
https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/
6. yml文件位置
https://github.com/kubernetes/kubernetes/tree/release-1.16/cluster/addons/dns/kube-dns
注意:
release后面一定要对应版本
7. 基于kubernetes DNS的服务发现文档
官方地址: https://github.com/kubernetes/dns/blob/master/docs/specification.md
要点整理
1.定义
2.记录架构版本
示例
dns-version.cluster.local. 28800 IN TXT "1.0.0"
3.ClusterIP服务的记录
A记录
kubernetes.default.svc.cluster.local. 4 IN A 10.3.0.1
SRV记录
记录格式:
_
示例
_https._tcp.kubernetes.default.svc.cluster.local. 30 IN SRV 10 100 443 kubernetes.default.svc.cluster.local.
PTR记录
记录格式:
示例
1.0.3.10.in-addr.arpa. 14 IN PTR kubernetes.default.svc.cluster.local.
4.没有ClusterIP的服务记录
A记录
ClusterIP改成集群pod ip集
三,pod如何获取DNS解析
1. 途径
1. 从自己的namespace里获取
2.从集群默认域中获取
2. 例子
service1
name: foo
namespace:bar
pod1
namespace:bar
想要查询上面的service1?
使用 foo 做DNS查询
pod2
namespace:quux
想要查询上面的service1?
使用 bar.foo 做DNS查询
四, kubedns搭建报错可能原因
1.kubedns与kuberntes版本不匹配
参考地址
http://www.mamicode.com/info-detail-2341263.html
https://github.com/kubernetes/kubernetes/blob/release-1.16/cluster/addons/dns/kube-dns/kube-dns.yaml.sed
2.发现kubelet里配置的dns的ip地址和要运行的yaml文件中的ip地址不一致,而且k8s-dns-kube-dns的镜像没有上传到私有仓库
docker push 192.168.89.132:5000/k8s-dns-kube-dns:1.14.13
kubectl delete -f kube-dns.yaml
kubectl create -f kube-dns.yaml
kubectl get svc,pods -n kube-system
NAME READY STATUS RESTARTS AGE
pod/kube-dns-66c887d465-rsmjg 1/3 Error 6 4m39s
发现报错
Warning Unhealthy 3m44s (x9 over 5m4s) kubelet, 192.168.89.134 Readiness probe failed: Get http://10.1.3.2:8081/readiness: dial tcp 10.1.3.2:8081: connect: connection refused
Warning Unhealthy 3m37s (x4 over 4m7s) kubelet, 192.168.89.134 Liveness probe failed: HTTP probe failed with statuscode: 503
Warning BackOff 7s (x7 over 115s) kubelet, 192.168.89.134 Back-off restarting failed container
kubectl logs kube-dns-85bdb85857-8mwln -n kube-system kubedns
reflector.go:201] k8s.io/dns/pkg/dns/dns.go:192: Failed to list *v1.Service: Get https://169.169.0.1:443/api/v1/services?resourceVersion=0: x509: certificate is valid for 10.254.0.1, 192.168.89.132, not 169.169.0.1
可能原因:apiserver证书问题
解决方案:重新做master和node的证书
基于CA签名的双向数字证书认证方式
过程
1. 为kube-apiserver生成一个数字证书,并用CA证书进行签名
2. 为kube-apiserver进程配置证书相关的启动参数,包括CA证书(用于验证客户端证书的签名真伪)/自己的经过CA签名后的证书及私钥
3. 为每个访问K8S API Server的客户端进程生成自己的数字证书,也都用CA进行签名,在相关程序的启动参数里增加CA证书/自己的证书等相关参数
客户端包括: kube-controller-manager , kube-scheduler , kubelet , kube-proxy 以及 调用API Server的客户端程序kubectl等
步骤
1. 设置kube-apiserver的CA证书相关的文件和启动参数
使用OpenSSL工具在Master服务器上创建CA证书和私钥相关的文件
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=k8s.com" -days 5000 -out ca.crt
openssl genrsa -out server.key 2048
注意:生成ca.crt时,-subj参数中/CN的值通常为域名
准备master_ssl.cnf文件,该文件用于x509 v3版本的证书。在该文件中主要需要设置Master服务器的hostname/IP地址/以及K8S Master Service的虚拟机服务名称(kubernetes.default等)和该虚拟服务的ClusterIP地址
vim master_ssl.cnf
基于master_ssl.cnf创建server.csr和server.crt文件。在生成server.csr时,-subj参数中“/CN”指定的名字需要为Master所在的主机名
]# openssl req -new -key server.key -subj "/CN=master" -config master_ssl.cnf -out server.csr
]# openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 5000 -extensions v3_req -extfile master_ssl.cnf -out server.crt
Signature ok
subject=/CN=master
Getting CA Private Key
将这些文件复制到一个目录中,例如/var/run/kubernetes//,然后设置kube-apiserver的三个启动参数 “--client-ca-file” "--tls-cert-file"和“--tls-private-key-file”,分别代办CA根证书文件/服务端证书文件和服务端私钥文件
启动参数添加
同时,可以关掉非安全端口8080,设置安全端口为443(默认为6443)
重启kube-apiserver服务
2. 设置kube-controller-manager的客户端证书/私钥和启动参数
openssl genrsa -out cs_client.key 2048
openssl req -new -key cs_client.key -subj "/CN=master" -out cs_client.csr
openssl x509 -req -in cs_client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out cs_client.crt -days 5000
其中,在生成cs_client.crt时,-CA参数和-CAkey参数使用的是apiserver的ca.crt和ca.key文件。然后将这些文件复制到一个目录中(/var/run/kubernetes)
cp cs_client.* /var/run/kubernetes/
创建/etc/kubernetes/kubeconfig文件(kube-controller-manager和kube-scheduler共用),配置客户端证书等相关参数
然后,设置kube-controller-manager服务的启动参数,注意,--master的地址为HTTPS安全服务地址,不使用非安全地址 http://192.168.89.130:8080
重启kube-controller-manager
3. 设置kube-scheduler启动参数
kube-scheduler复用上一步kube-controller-manager创建的客户端证书,配置启动参数
重启kube-scheduler
4. 设置每台node上kubelet的客户端证书/私钥和启动参数
首先复制kube-apiserver的ca.crt和ca.key文件到node上,在生成kubelet_client.crt时,-CA参数和-CAkey参数使用的是apiserver的ca.crt和ca.key文件。在生成kubelet_client.csr时-subj参数中的/CN设置为本node的IP地址
]# openssl genrsa -out kubelet_client.key 2048
]# openssl req -new -key kubelet_client.key -subj "/CN=192.168.89.128" -out kubelet_client.csr
]# openssl x509 -req -in kubelet_client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out kubelet_client.crt -days 5000
Signature ok
subject=/CN=192.168.89.128
Getting CA Private Key
将这些文件复制到一个目录中(/var/run/kubernetes)
创建/etc/kubernetes/kubeconfig文件(kubelet和kube-proxy进程共用),配置客户端证书等相关参数
然后,设置kubelet服务的启动参数
5. 设置kube-proxy的启动参数
kube-proxy复用上一步kubelet创建的客户端证书,配置启动参数
重启kube-proxy服务
至此,一个基于CA的双向数字证书认证的K8S集群就搭建完成了。
6. 设置kubectl客户端使用安全方式访问apiserver
在使用kubectl 对K8S集群进行操作时,默认使用非安全端口8080对apiserver进行访问,也可以设置为安全访问apiserver模式,需要设置3个证书相关的参数
--certificate-authority
使用为Kube-apiserver生成的ca.crt文件
--client-certificate
使用kube-controller-manager生成的cs_client.crt文件
--client-key
使用为kube-controller-manager生成的cs_client.key文件
同时,指定apiserver的URL地址为HTTPS安全地址(例如:https://master:443),最后,输入需要执行的子命令,即可对apiserver进行安全访问了
命令
vim /root/.bashrc
注意:
操作之前最好把所有服务都停掉
排错:
修改kube-apiserver后,服务启动报错
Oct 22 04:10:39 master kube-apiserver[51631]: I1022 04:10:39.813663 51631 config.go:562] Will report 192.168.89.130 as public IP address.
Oct 22 04:10:39 master kube-apiserver[51631]: F1022 04:10:39.814492 51631 server.go:250] Failed to create clientset: Unable to set url for apiserver local client
解决:
kube-proxy
ip range
node节点上cluster集群网段错误,和169.169.0.0/16不一致,修改成一致的
五, kubedns功能验证
1. 创建test_svc
vim test_svc.yml
kubectl create -f test_svc.yml
kubectl get svc
[root@k8smaster busy_test]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 169.169.0.1
mysql-service NodePort 169.169.188.11
redis-php NodePort 169.169.163.193
2. 创建 busybox
vim busybox.yml
kubectl create -f busybox.yml
kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
default busybox 1/1 Running 0 18s 10.1.77.3 192.168.89.133
default static-web-192.168.89.133 1/1 Running 13 40d 10.1.77.2 192.168.89.133
kube-system kube-dns-85bdb85857-bnq6t 3/3 Running 0 22m 10.1.3.2 192.168.89.134
3. 进入 busybox 进行验证
kubectl exec -it busybox sh
/ # cat /etc/resolv.conf
nameserver 169.169.0.10
search default.svc.k8s.com svc.k8s.com k8s.com
options ndots:5
/ # ping mysql-service
PING mysql-service (169.169.188.11): 56 data bytes
64 bytes from 169.169.188.11: seq=0 ttl=64 time=0.029 ms
六,最后
kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
kube-dns-85bdb85857-bnq6t 3/3 Running 0 3m13s
kubectl describe pod kube-dns-85bdb85857-bnq6t -n kube-system ==> 没有报错
成功了,总结一下
一步错,步步错,后期还会有干扰,所以,每一步都要注意。多看看报错,多看 logs , describe 等信息
更换了kubedns的版本,更换过镜像版本,来来回回将近一个月,终于完成了,解决了这个问题,本来很困的,解决完后,感觉精神很多了。