cookeem/kubeadm-ha

nginx-lb的问题

zeratullich opened this issue · 5 comments

这个问题会出现在k8s的准入控制(admission-webhook)高级应用中,比如istio的sidercar注入中、ingress-nginx配置校验,会出现类似--failed calling webhook "rev.validation.istio.io": Post "https://istiod.istio-system.svc:443/validate?timeout=10s" No such domain的错误,这是由于在配置nginx-lb的静态pod中少了跟主机共享网络,即需要在nginx-lb.yaml(/etc/kubernetes/manifests/nginx-lb.yaml)中写入hostNetwork: true,跟kube-scheduler.yaml或kube-controller-manager.yaml中配置类似。
这个问题困扰本人好久,google都找不到这个错,我为了找到这个错误原因测试各种版本的k8s集群,使用minikube搭建单节点的相同版本的集群进行单独测试,发现均没有此问题,最终追溯到是否集群配置有误,测试中把高可用集群重置了4次左右,在集群未成为高可用时候单个master抛弃掉nginx-lb组件测试才发现问题!请及时改正!

@zeratullich 抱歉回复晚了,主要考虑到使用hostNetwork: true不是一个很安全的选项,所以这里并没有启用hostNetwork这个选项。我这边也是有使用istio服务网格,目前没有出现你提到的问题呢,你使用什么网络插件?是否网络插件配置引起的问题?

@cookeem calico跟flannel都试过了,不是网络插件的问题,使用hostNetwork: true没关系,nginx做得只是代理,最终到达api-server需要进行认证的,加了这个就可以。不加不通行可能是集群内部admission认证时候,内部认证不认为是合理的域名所致,加了后认证的范围广了,不仅自己本身机器,其他的机器也可以通行,所以加了就行了。

@zeratullich 我们这里有集群使用flannel,有集群使用calico,也有使用istio作为服务网格,还真没有遇到你提到的这个问题。
我们这边生产环境都开启了firewalld,为了解决集群内部ping不通引起的网络组件起不来,一般需要定期执行。你看看你这个问题是否防火墙问题引起?

$ iptables -D INPUT -j REJECT --reject-with icmp-host-prohibited

找到原因了,是我为了翻墙设置了/etc/profile中的proxy代理http_proxyhttps_proxy,这样导致kubeadm 初始化加入时候,会在/etc/kubernetes/manifests/文件中的三个文件:kube-apiserver.yaml,kube-apiserver.yaml,kube-scheduler.yaml中写入env变量,导致运行时候会去代理服务器上进行查询,问题就出现在这里,给个示例:
#cat /etc/kubernetes/manifests/kube-apiserver.yaml

kind: Pod
metadata:
  annotations:
    kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 192.168.0.101:6443
  creationTimestamp: null
  labels:
    component: kube-apiserver
    tier: control-plane
  name: kube-apiserver
  namespace: kube-system
spec:
  containers:
  - command:
    - kube-apiserver
    - --advertise-address=192.168.0.101
    - --allow-privileged=true
    - --authorization-mode=Node,RBAC
    - --client-ca-file=/etc/kubernetes/pki/ca.crt
    - --enable-admission-plugins=NodeRestriction
    - --enable-bootstrap-token-auth=true
    - --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
    - --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
    - --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
    - --etcd-servers=https://127.0.0.1:2379
    - --insecure-port=0
    - --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
    - --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key
    - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
    - --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt
    - --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key
    - --requestheader-allowed-names=front-proxy-client
    - --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
    - --requestheader-extra-headers-prefix=X-Remote-Extra-
    - --requestheader-group-headers=X-Remote-Group
    - --requestheader-username-headers=X-Remote-User
    - --secure-port=6443
    - --service-account-issuer=https://kubernetes.default.svc.cluster.local
    - --service-account-key-file=/etc/kubernetes/pki/sa.pub
    - --service-account-signing-key-file=/etc/kubernetes/pki/sa.key
    - --service-cluster-ip-range=10.96.0.0/12
    - --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
    - --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
    env:
    - name: https_proxy
      value: http://192.168.0.250:8118
    - name: http_proxy
      value: http://192.168.0.250:8118
    - name: no_proxy
      value: 127.0.0.1,localhost,192.168.0.0/16,10.244.0.0/16,10.96.0.0/12,*.edu.cn
    image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.20.15
    .........................................

注销掉三个文件中的env部分即可正常运行,现在有个工具叫kube-vip的,用起来特别简单,不用再装keepalived跟nginx了。

@zeratullich 不错,谢谢推荐。其实原理都差不多,也是自动生成keepalived和nginx的配置并把lb启动起来。