ingress controller在物理机上的两种部署方式
ingress controller(ingress-nginx)负责k8s中的7层负载均衡。其在物理机中有多种部署方式。本文中主要选择了nodePort和hostNetwork两种部署方式进行介绍。主要原因是这两种部署方式不需要借助于其他组件,直接使用的是k8s的基础组件和使用方式,较为容易理解和排障。
注:本文中的kube-proxy使用的是iptables
本文使用的ingress-nginx的commit版本是51ad0bc54b1475384b67bee9e8a8e41e26b18bc4。该版本的部署方式是在NGINX: 0.24.1版本后重构了deploy文件夹中的ingress-nginx的部署相关文件。采用了kustomize进行部署配置。因此推荐使用kubectl 1.14以上的版本。且特别注意,下面的命令都是使用了kubectl apply -k的方式运行,而不是-f参数。
deploy各个文件夹走读ingress-nginx项目deploy文件夹下有多个文件夹,为不同的环境提供支持。这里我们主要介绍的是与在物理机部署相关的几个文件夹。
cluster-wide ├── cluster-wide │ ├── cluster-role-binding.yaml │ ├── cluster-role.yaml │ └── kustomization.yamlcluster-wide文件夹主要用于创建cluster-role和cluster-role-binding,为ingress-controller提供apiserver的cluster访问权限。这里cluster-role-binding.yaml要作一下修改,指定namespace: ingress-nginx。因为在后面创建的ServiceAccount等其他资源都是默认在该namespace下。
[root@local cluster-wide]# cat cluster-role-binding.yaml apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: nginx-ingress-clusterrole-nisa-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: nginx-ingress-clusterrole subjects: - kind: ServiceAccount name: nginx-ingress-serviceaccount namespace: ingress-nginx cloud-generic ├── cloud-generic │ ├── deployment.yaml │ ├── kustomization.yaml │ ├── role-binding.yaml │ ├── role.yaml │ ├── service-account.yaml │ └── service.yamlcloud-generic文件夹提供了通用的一些部署文件。其中deployment.yaml是负责创建ingress-controller的deployment,默认副本数为1,可以进行调节。service.yaml是为ingress-controller创建的service。其他的主要是与账户相关的内容。
baremetal ├── baremetal │ ├── kustomization.yaml │ └── service-nodeport.yamlbaremetal文件夹主要是创建了一个NodePort类型的svc,然后向ingress-controller的容器进行导流的。因为该部署方式需要依赖cloud-generic里的资源,因此在kustomization.yaml中描述了对cloud-generic的依赖。可以参看kustomization.yaml中的bases。
[root@local baremetal]# cat deploy/baremetal/kustomization.yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization bases: - ../cloud-generic patchesStrategicMerge: - service-nodeport.yaml大致了解了相关部署文件的功能,那么结合具体的两种部署图(部署图来自官网),来进行一下具体介绍。
nodePort部署nodePort的部署思路就是通过在每个节点上开辟nodePort的端口,将流量引入进来,而后通过iptables首先转发到ingress-controller容器中(图中的nginx容器),而后由nginx根据ingress的规则进行判断,将其转发到对应的应用web容器中。因此采用nodePort部署较为简单,直接使用以下命令即可。
kubectl apply -k deploy/baremetal/ kubectl apply -k deploy/cluster-wide/ hostNetwork部署相比较起来,hostNetwork模式不再需要创建一个nodePort的svc,而是直接在每个节点都创建一个ingress-controller的容器,而且将该容器的网络模式设为hostNetwork。也就是说每个节点物理机的80和443端口将会被ingress-controller中的nginx容器占用。当流量通过80/443端口进入时,将直接进入到nginx中。而后nginx根据ingress规则再将流量转发到对应的web应用容器中。
这里需要对cloud-generic/deployment.yaml进行一下改动,将其资源类型从deployment改为daemonset,并且在spec中添加hostNetwork: true,从而使其可以使用物理机网络。
[root@local deploy]# cat cloud-generic/deployment.yaml apiVersion: extensions/v1beta1 kind: DaemonSet metadata: name: nginx-ingress-controller spec: template: metadata: annotations: prometheus.io/port: "10254" prometheus.io/scrape: "true" labels: nginx-ingress-controller: 0.24.1 spec: serviceAccountName: nginx-ingress-serviceaccount hostNetwork: true ...修改完成后,使用以下命令即可完成hostNetwork模式的部署。
kubectl apply -k deploy/cloud-generic/ kubectl apply -k deploy/cluster-wide/ 两种部署方式的比较相比较起来,nodePort部署模式中需要部署的ingress-controller容器较少。一个集群可以部署几个就可以了。而hostNetwork模式需要在每个节点部署一个ingress-controller容器,因此总起来消耗资源较多。另外一个比较直观的区别,nodePort模式主要占用的是svc的nodePort端口。而hostNetwork则需要占用物理机的80和443端口。