k8s ver:1.6.7, 无CNI
使用hostnetwork来部署一个pod
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
apiVersion: extensions/v1beta1 kind: DaemonSet metadata: name: nginx-ingress-ds labels: app: nginx-ingress-ctrl spec: template: metadata: labels: app: nginx-ingress-ctrl spec: serviceAccountName: nginx-ingress hostNetwork: true <<<<<<<<<<使用hostnetwork containers: - image: nginxdemos/nginx-ingress:1.0.0 name: nginx-ingress-lb ports: - containerPort: 80 hostPort: 80 - containerPort: 443 hostPort: 443 env: - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace # Uncomment the lines below to enable extensive logging and/or customization of # NGINX configuration with configmaps args: #- -v=3 #- -nginx-configmaps=$(POD_NAMESPACE)/nginx-config - -default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret |
上述配置文件使用指定hostNetwork: true。发现,pod会用linux系统自身的路由表查找到目的地169.169.0.1:443, linux系统本身没有到169.169.0.1的路由,只能走缺省路由,导致无法连接到kubernetes service,最终导致pod失败。
当pod是非host模式时候,pod发起到kubernetes service 的访问(dst ip/port 169.169.0.1:443)会经过iptables最终做DNAT转到API server的IP:6443上。
所以如果一个pod需要去访问k8s内置的kubernetes service(169.169.0.1)的时候,可能这个pod不能使用hostnetwork模式,否则会出现类似如下情况: (系统使用host linux内置缺省路由去访问169.169.0.1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
[root@docker3 ~]# netstat -pan | grep 443 tcp 0 1 192.168.188.151:33992 169.169.0.1:443 SYN_SENT 39547/nginx-ingress [root@docker3 ~]# netstat -pan | grep 443 tcp 0 1 192.168.188.151:33992 169.169.0.1:443 SYN_SENT 39547/nginx-ingress [root@docker3 ~]# netstat -pan | grep 443 tcp 0 1 192.168.188.151:33992 169.169.0.1:443 SYN_SENT 39547/nginx-ingress [root@docker3 ~]# netstat -pan | grep 443 tcp 0 1 192.168.188.151:33992 169.169.0.1:443 SYN_SENT 39547/nginx-ingress [root@docker3 ~]# netstat -pan | grep 443 tcp 0 1 192.168.188.151:33992 169.169.0.1:443 SYN_SENT 39547/nginx-ingress [root@docker3 ~]# netstat -pan | grep 443 tcp 0 1 192.168.188.151:33992 169.169.0.1:443 SYN_SENT 39547/nginx-ingress [root@docker3 ~]# netstat -pan | grep 443 tcp 0 1 192.168.188.151:33992 169.169.0.1:443 SYN_SENT 39547/nginx-ingress [root@docker3 ~]# netstat -pan | grep 443 [root@docker3 ~]# netstat -pan | grep 443 tcp 0 1 192.168.188.151:33996 169.169.0.1:443 SYN_SENT 39620/nginx-ingress [root@docker3 ~]# netstat -pan | grep 443 tcp 0 1 192.168.188.151:33996 169.169.0.1:443 SYN_SENT 39620/nginx-ingress [root@docker3 ~]# netstat -pan | grep 443 tcp 0 1 192.168.188.151:33996 169.169.0.1:443 SYN_SENT 39620/nginx-ingress [root@docker3 ~]# netstat -pan | grep 443 tcp 0 1 192.168.188.151:33996 169.169.0.1:443 SYN_SENT 39620/nginx-ingress [root@docker3 ~]# netstat -pan | grep 443 tcp 0 1 192.168.188.151:33996 169.169.0.1:443 SYN_SENT 39620/nginx-ingress |
当遇到上述情形时候,可以考虑强行指定nginx controller使用不安全的api接口访问方式:
Using the flag --apiserver-host
: Using this flag --apiserver-host=http://localhost:8080
it is possible to specify an unsecure api server or reach a remote kubernetes cluster using kubectl proxy. Please do not use this approach in production.
https://github.com/kubernetes/ingress/blob/master/docs/troubleshooting.md
如果使用了CNI的话,可能遇到指定hostnetwork后,pod并没有在host上监听相关端口,这是由于bug
https://github.com/kubernetes/kubernetes/issues/31307
V1.7才修复
文章评论