kubernetes 服务发现问题——kubedns[下部]

上一回有关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.定义
             =配置的群集域,例如cluster.local
             =命名空间
             =记录的标准DNS生存时间值
        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记录
                记录格式:
                    _._...svc.. IN SRV ..svc..
                示例
                    _https._tcp.kubernetes.default.svc.cluster.local. 30 IN SRV 10 100 443 kubernetes.default.svc.cluster.local.
            PTR记录
                记录格式:
                    ....in-addr.arpa. IN PTR ..svc..
                示例
                    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              443/TCP          55d
            mysql-service   NodePort    169.169.188.11            3306:64298/TCP   18s
            redis-php       NodePort    169.169.163.193          80:30002/TCP     54d
    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的版本,更换过镜像版本,来来回回将近一个月,终于完成了,解决了这个问题,本来很困的,解决完后,感觉精神很多了。
 

你可能感兴趣的:(云计算之运维之路)