本文主要介绍kubernetes官方推荐的ingress控制器ingress-Nginx controller在bare-metal环境中搭建的经验总结,因为我是在私有的服务器上搭建的kubernetes集群,而且还要求要通过IP的方式作为外部访问的入口点,在网上找了好多资料都没有找到满意的,最后还是根据官网指引完成的,所以这里对官网上bare-metal的安装指引总结一下(因为看英文太费劲了,所以记录一下,哈哈)。如果有不对的地方,也望能得到指正。

下面就开始了。

Ingress控制器

Ingress控制器有多种类型,我尝试安装的是traefik和kubernetes官方推荐的控制器ingress-Nginx。这两款ingress控制器是当前比较流行的两种控制器。traefik因能够实时和kubernetes api交互,并且能够与常见的微服务系统直接整合,可以实现自动化动态配置而越来越流行。

安装两款控制器后发现,traefik只能通过域名实现kubernetes 服务的统一访问入口(可能是因为基于规则的原因),而Nginx控制器可以支持域名或者IP的方式实现kubernetes服务的统一访问入口。

说明:ingress-Nginx是kubernetes官方提供的ingress控制器,Nginx-ingress是Nginx官方提供的ingress控制器,两者都支持域名和ip两种方式做kubernetes服务的统一入口,只是ingress的配置不太一样。

因为我要通过IP方式访问kubernetes中的服务,所以就选择了kubernetes官方的ingress-Nginx控制器,下面开始介绍ingress-Nginx控制器的安装。

注意:默认配置会监控所有命名空间的ingress对象。可以通过--watch-namespace 标志将监控范围限制到某一个特定的命名空间。

警告:如果有多个ingress定义了同一个域名的多个path,ingress控制器会将这些定义合并。

危险:准入webhook需要KubernetesAPI服务器和入口控制器之间的连接,如果有网络策略或者附加的防火墙,请允许访问端口8443。

参考:https://github.com/kubernetes/ingress-nginx中的Overview及Get Start部分

https://kubernetes.github.io/ingress-nginx/deploy/ingress-Nginx安装指引

https://kubernetes.github.io/ingress-nginx/deploy/baremetal/

因为是在自己的服务器上搭建的,所以就参考了bare-metal的安装方式(其他方式官网也有介绍,参考官网即可,我这里就不说了)。因为如果是在像GKE、AWS之类的云上安装的kubernetes集群的话,在搭建ingress控制器时就可以直接指定负载均衡的ip地址作为统一的入口,云提供商会自动分配这个IP地址。而在自己的服务器上搭建就需要参照Bare-metal considerations部分来完成负载均衡ip地址的配置。

bare-metal安装默认采用的是NodePort安装方式,就是ingress controller的service type设置成NodePort。

安装步骤如下:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/deploy.yaml

下面是我改之后的deploy.yaml:

apiVersion: v1
kind: Namespace
metadata:name: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginx---
# Source: ingress-nginx/templates/controller-serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:labels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: controllername: ingress-nginxnamespace: ingress-nginx
---
# Source: ingress-nginx/templates/controller-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:labels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: controllername: ingress-nginx-controllernamespace: ingress-nginx
data:
---
# Source: ingress-nginx/templates/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:labels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmname: ingress-nginx
rules:- apiGroups:- ''resources:- configmaps- endpoints- nodes- pods- secretsverbs:- list- watch- apiGroups:- ''resources:- nodesverbs:- get- apiGroups:- ''resources:- servicesverbs:- get- list- update- watch- apiGroups:- extensions- networking.k8s.io   # k8s 1.14+resources:- ingressesverbs:- get- list- watch- apiGroups:- ''resources:- eventsverbs:- create- patch- apiGroups:- extensions- networking.k8s.io   # k8s 1.14+resources:- ingresses/statusverbs:- update- apiGroups:- networking.k8s.io   # k8s 1.14+resources:- ingressclassesverbs:- get- list- watch
---
# Source: ingress-nginx/templates/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:labels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmname: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: ingress-nginx
subjects:- kind: ServiceAccountname: ingress-nginxnamespace: ingress-nginx
---
# Source: ingress-nginx/templates/controller-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:labels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: controllername: ingress-nginxnamespace: ingress-nginx
rules:- apiGroups:- ''resources:- namespacesverbs:- get- apiGroups:- ''resources:- configmaps- pods- secrets- endpointsverbs:- get- list- watch- apiGroups:- ''resources:- servicesverbs:- get- list- update- watch- apiGroups:- extensions- networking.k8s.io   # k8s 1.14+resources:- ingressesverbs:- get- list- watch- apiGroups:- extensions- networking.k8s.io   # k8s 1.14+resources:- ingresses/statusverbs:- update- apiGroups:- networking.k8s.io   # k8s 1.14+resources:- ingressclassesverbs:- get- list- watch- apiGroups:- ''resources:- configmapsresourceNames:- ingress-controller-leader-nginxverbs:- get- update- apiGroups:- ''resources:- configmapsverbs:- create- apiGroups:- ''resources:- endpointsverbs:- create- get- update- apiGroups:- ''resources:- eventsverbs:- create- patch
---
# Source: ingress-nginx/templates/controller-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:labels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: controllername: ingress-nginxnamespace: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: ingress-nginx
subjects:- kind: ServiceAccountname: ingress-nginxnamespace: ingress-nginx
---
# Source: ingress-nginx/templates/controller-service-webhook.yaml
apiVersion: v1
kind: Service
metadata:labels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: controllername: ingress-nginx-controller-admissionnamespace: ingress-nginx
spec:type: ClusterIPports:- name: https-webhookport: 443targetPort: webhookselector:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/component: controller
---
# Source: ingress-nginx/templates/controller-service.yaml
apiVersion: v1
kind: Service
metadata:annotations:labels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: controllername: ingress-nginx-controllernamespace: ingress-nginx
spec:# externalTrafficPolicy: Local# type: LoadBalancer# loadBalancerIP: 10.245.5.2type: NodePortports:- name: httpport: 80protocol: TCPtargetPort: httpnodePort: 30278- name: httpsport: 443protocol: TCPtargetPort: httpsnodePort: 30579selector:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/component: controller
---
# Source: ingress-nginx/templates/controller-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:labels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: controllername: ingress-nginx-controllernamespace: ingress-nginx
spec:# replicas: 1selector:matchLabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/component: controllerrevisionHistoryLimit: 10minReadySeconds: 0template:metadata:labels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/component: controllerspec:dnsPolicy: ClusterFirstWithHostNetcontainers:- name: controllerimage: xx.xx.xx.xx/kubernetes/ingress/nginx-ingress-controller:0.32.0imagePullPolicy: IfNotPresentlifecycle:preStop:exec:command:- /wait-shutdownargs:- /nginx-ingress-controller- --election-id=ingress-controller-leader- --ingress-class=nginx- --configmap=ingress-nginx/ingress-nginx-controller# - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller- --validating-webhook=:8443- --validating-webhook-certificate=/usr/local/certificates/cert- --validating-webhook-key=/usr/local/certificates/keysecurityContext:capabilities:drop:- ALLadd:- NET_BIND_SERVICErunAsUser: 101allowPrivilegeEscalation: trueenv:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespace- name: LD_PRELOADvalue: /usr/local/lib/libmimalloc.solivenessProbe:httpGet:path: /healthzport: 10254scheme: HTTPinitialDelaySeconds: 10periodSeconds: 10timeoutSeconds: 1successThreshold: 1failureThreshold: 5readinessProbe:httpGet:path: /healthzport: 10254scheme: HTTPinitialDelaySeconds: 10periodSeconds: 10timeoutSeconds: 1successThreshold: 1failureThreshold: 3ports:- name: httpcontainerPort: 80protocol: TCP# hostPort: 80- name: httpscontainerPort: 443protocol: TCP# hostPort: 443- name: webhookcontainerPort: 8443protocol: TCP# hostPort: 8443volumeMounts:- name: webhook-certmountPath: /usr/local/certificates/readOnly: trueresources:requests:cpu: 100mmemory: 90MinodeSelector:kubernetes.io/os: linuxserviceAccountName: ingress-nginxterminationGracePeriodSeconds: 300volumes:- name: webhook-certsecret:secretName: ingress-nginx-admission
---
# Source: ingress-nginx/templates/admission-webhooks/validating-webhook.yaml
# before changing this value, check the required kubernetes version
# https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#prerequisites
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:labels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhookname: ingress-nginx-admission
webhooks:- name: validate.nginx.ingress.kubernetes.iorules:- apiGroups:- networking.k8s.ioapiVersions:- v1beta1operations:- CREATE- UPDATEresources:- ingressesfailurePolicy: FailsideEffects: NoneadmissionReviewVersions:- v1- v1beta1clientConfig:service:namespace: ingress-nginxname: ingress-nginx-controller-admissionpath: /networking/v1beta1/ingresses
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:name: ingress-nginx-admissionannotations:helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgradehelm.sh/hook-delete-policy: before-hook-creation,hook-succeededlabels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhooknamespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: ingress-nginx-admissionannotations:helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgradehelm.sh/hook-delete-policy: before-hook-creation,hook-succeededlabels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhook
rules:- apiGroups:- admissionregistration.k8s.ioresources:- validatingwebhookconfigurationsverbs:- get- update
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: ingress-nginx-admissionannotations:helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgradehelm.sh/hook-delete-policy: before-hook-creation,hook-succeededlabels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhook
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: ingress-nginx-admission
subjects:- kind: ServiceAccountname: ingress-nginx-admissionnamespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:name: ingress-nginx-admissionannotations:helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgradehelm.sh/hook-delete-policy: before-hook-creation,hook-succeededlabels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhooknamespace: ingress-nginx
rules:- apiGroups:- ''resources:- secretsverbs:- get- create
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: ingress-nginx-admissionannotations:helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgradehelm.sh/hook-delete-policy: before-hook-creation,hook-succeededlabels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhooknamespace: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: ingress-nginx-admission
subjects:- kind: ServiceAccountname: ingress-nginx-admissionnamespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml
apiVersion: batch/v1
kind: Job
metadata:name: ingress-nginx-admission-createannotations:helm.sh/hook: pre-install,pre-upgradehelm.sh/hook-delete-policy: before-hook-creation,hook-succeededlabels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhooknamespace: ingress-nginx
spec:template:metadata:name: ingress-nginx-admission-createlabels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhookspec:containers:- name: createimage: xx.xx.xx.xx/kubernetes/ingress/kube-webhook-certgen:v1.2.0imagePullPolicy: IfNotPresentargs:- create- --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.ingress-nginx.svc- --namespace=ingress-nginx- --secret-name=ingress-nginx-admissionenv:- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespacerestartPolicy: OnFailureserviceAccountName: ingress-nginx-admissionsecurityContext:runAsNonRoot: truerunAsUser: 2000
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml
apiVersion: batch/v1
kind: Job
metadata:name: ingress-nginx-admission-patchannotations:helm.sh/hook: post-install,post-upgradehelm.sh/hook-delete-policy: before-hook-creation,hook-succeededlabels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhooknamespace: ingress-nginx
spec:template:metadata:name: ingress-nginx-admission-patchlabels:helm.sh/chart: ingress-nginx-2.0.3app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/version: 0.32.0app.kubernetes.io/managed-by: Helmapp.kubernetes.io/component: admission-webhookspec:containers:- name: patchimage: xx.xx.xx.xx/kubernetes/ingress/kube-webhook-certgen:v1.2.0imagePullPolicy: IfNotPresentargs:- patch- --webhook-name=ingress-nginx-admission- --namespace=ingress-nginx- --patch-mutating=false- --secret-name=ingress-nginx-admission- --patch-failure-policy=Failenv:- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespacerestartPolicy: OnFailureserviceAccountName: ingress-nginx-admissionsecurityContext:runAsNonRoot: truerunAsUser: 2000

其实通过上面的步骤部署好ingress controller之后,就可以通过master ip:NodePort/ingress path访问到内部服务了,但是还没有做到负载均衡。

在传统的云环境中,网络负载均衡器是按需提供的,单个Kubernetes manifest足以向外部客户端提供NGINX入口控制器的单一接触点,并间接地向在集群内运行的任何应用程序提供接触点。 bare-metal(裸机)环境缺乏这种商品,需要一个稍微不同的设置,以对外部消费者提供相同类型的访问入口。

对于运行在bare-metal环境中的kubernetes集群,官方文档中给了几种部署Nginx ingress Controller的推荐方法,下面逐一说明。

1、一个纯软件的解决方案:MetalLB

Metal LB为不在支持的云提供商上运行的Kubernetes集群提供了一个网络负载均衡器实现,有效地允许在任何集群中使用负载均衡器服务。

本节演示如何在具有公共可访问节点的Kubernetes集群中一起使用MetalLB的Layer 2配置模式和NGINX Ingress控制器。 在这种模式下,一个节点承担ingress-Nginx service IP的所有流量。

注意:此文档没有描述其他可支持的配置模式。

警告:Metal LB目前处于beta状态。

MetalLB可以通过一个简单的kubernetes manifast或者helm来部署,具体安装可以参考metalLB官网https://metallb.universe.tf/installation/,这里不再阐述。

MetalLB需要一个IP池,以便拥有ingress-nginx的所有权。这个池可以在一个和MetalLB controller相同命名空间的ConfigMap的config位置进行定义。这个池里的IP必须是专用于MetalLB,不能重复使用kubernetes node节点的ip或者是一个DHCP服务器分配的ip。

示例:

下面的kubernetes集群有3个节点(其中,EXTERNAL-IP是作为例子加上的,在绝大多数的裸机环境中,这个值是<None>)

$ kubectl get node

NAME STATUS ROLES EXTERNAL-IP

host-1 Ready master 203.0.113.1

host-2 Ready node 203.0.113.2

host-3 Ready node 203.0.113.3

创建完下面的ConfigMap之后,MetalLB拥有池中某一个IP的所有权,并相应地更新ingress-nginx service的loadBalancer IP字段。

apiVersion: v1

kind: ConfigMap

metadata:

namespace: metallb-system

name: config

data:

config: |

address-pools:

- name: default

protocol: layer2

addresses:

- 203.0.113.10-203.0.113.15

$ kubectl -n ingress-nginx get svc

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)

default-http-backend ClusterIP 10.0.64.249 <none> 80/TCP

ingress-nginx LoadBalancer 10.0.220.217 203.0.113.10 80:30100/TCP,443:30101/TCP

一旦MetalLB设置了ingress-nginx负载均衡 service的外部IP地址,在iptable NAT表中就会创建相应的条目,具有选定的ip地址的节点开始响应负载均衡器service中配置的端口上的HTTP请求。

Tip:为了保存发送给NGINX的HTTP请求中的源IP地址,需要使用Local通信策略。更多的通信策略可以阅读https://metallb.universe.tf/usage/#traffic-policies。

2、基于NodePort服务

因为其简单性,这种方式也是用户在遵循安装指南中描述的步骤部署时的默认部署方式。

这种配置方式下,Nginx容器和本地的网络是独立的,因此,它能够安全的绑定到任何端口,包括HTTP的标准端口80和443。然而,因为容器的命名空间的独立性,一个集群网络外面的客户端(如公共网络)是不能通过80和443端口直接进入ingress主机的。外部客户端必须将分配给ingress-Nginx service的NodePort添加到HTTP请求中才可以访问。

示例:

给ingress-nginx服务配置30100端口

$ kubectl -n ingress-nginx get svc

NAME TYPE CLUSTER-IP PORT(S)

default-http-backend ClusterIP 10.0.64.249 80/TCP

ingress-nginx NodePort 10.0.220.217 80:30100/TCP,443:30101/TCP

一个拥有开放IP地址:203.0.113.2 集群节点(其中,EXTERNAL-IP是作为例子加上的,在绝大多数的裸机环境中,这个值是<None>)

$ kubectl get node NAME STATUS ROLES EXTERNAL-IP

host-1 Ready master 203.0.113.1

host-2 Ready node 203.0.113.2

host-3 Ready node 203.0.113.3

客户端将通过http:/myapp.example.com:30100到达带有host:myapp.example.com的ingress,其中myapp.example.com子域名解析为203.0.113.2 IP地址。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

对主机系统的影响:

虽然可以使用-service-node-port-range API服务器标志重新配置NodePort的范围,使其可以包含非特权端口,并且能够公开端口80和443,但这样做可能会导致意想不到的问题,包括(但不限于)使用其他保留给系统守护进程的端口,以及必须授予它可能不需要的kube-proxy特权。因此不鼓励这么做。

这种方法还有一些其他限制:

(1) 源IP地址

NodePort类型的服务默认执行源地址转换。这意味着HTTP请求的源IP总是从NGINX的角度接收请求的Kubernetes节点的IP地址。

在NodePort设置中保存源IP的建议方法是将ingress-nginx service spec的externalTrafficPolicy 字段设置成Local。

注意:此设置有效地删除发送到Kubernetes节点的数据包,这些节点不运行NGINX入口控制器的任何实例。可以考虑将NGINX PODS分配给特定节点(https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/),以便控制NGINX ingress控制器应该调度或不调度哪些节点。

示例:

下面的kubernetes集群有3个节点(其中,EXTERNAL-IP是作为例子加上的,在绝大多数的裸机环境中,这个值是<None>)

$ kubectl get node

NAME STATUS ROLES EXTERNAL-IP

host-1 Ready master 203.0.113.1

host-2 Ready node 203.0.113.2

host-3 Ready node 203.0.113.3

一个ingress-nginx-controller 部署2个副本

$ kubectl -n ingress-nginx get pod -o wide

NAME READY STATUS IP NODE

default-http-backend-7c5bc89cc9-p86md 1/1 Running 172.17.1.1 host-2

ingress-nginx-controller-cf9ff8c96-8vvf8 1/1 Running 172.17.0.3 host-3

ingress-nginx-controller-cf9ff8c96-pxsds 1/1 Running 172.17.1.4 host-2

发送到host-2和host-3的请求将被转发到Nginx并且原始客户端的IP会被保存。而发送到host-1的请求将会被删掉,因为在那个节点上没有运行Nginx副本。

(2) ingress状态

因为NodePort service获取不到定义分配的LoadBalancerIP,NGINX Ingress controller不能更新它管理的ingress对象的状态。

$ kubectl get ingress

NAME HOSTS ADDRESS PORTS

test-ingress myapp.example.com 80

尽管没有向NGINX ingress控制器提供公共IP地址的负载均衡器,但可以通过设置ingress-Nginx service的externalIPs字段来强制所有管理的ingress对象的状态更新。

注意:设置externalIPs不仅仅用于可以使NGINX ingress控制器更新ingress对象的状态。 请阅读官方Kubernetes文档的 Services页面中的此选项以及本文档中关于External IPs 的部分,以获得更多信息。

(3) 重定向

由于NGINX不知道NodePort service操作的端口转换,后端应用程序负责生成考虑外部客户端(包括节点端口)使用的URL的重定向URL。

3、基于主机网络

在没有外部负载均衡器可用但使用NodePorts不是选项的设置中,可以配置ingress-NginxPods来使用它们运行的主机的网络,而不是专用的网络名称空间。这种方法的好处是NGINX ingress控制器可以将端口80和443直接绑定到Kubernetes节点的网络接口,而不需要NodePort service施加额外的网络转换。

注意:此方法不利用任何Service对象来暴露NGINX ingress控制器。如果目标集群中存在这样的ingress-Nginx service,建议删除。

这可以通过在Pod的spec中启用hostNetwork选项来实现。

template:

spec:

hostNetwork: true

安全因素:

启用此选项将每个系统守护进程暴露给任何网络接口上的NGINX ingress controller,包括主机的回送。 请仔细评估这可能对您的系统安全的影响。

这种部署方法的一个主要限制就是集群的每一个节点上只能部署一个Nginx ingress controller的pod,因为在同一个网络接口上多次绑定同一个端口在技术上是不可能的。因为这种情况导致pod调度失败会看到下面的事件:

$ kubectl -n ingress-nginx describe pod <unschedulable-ingress-nginx-controller-pod>

...

Events:

Type Reason From Message

---- ------ ---- -------

Warning FailedScheduling default-scheduler 0/3 nodes are available: 3 node(s) didn't have free ports for the requested pod ports.

一种确保只创建可调度的pod的方法就是将Nginx ingress controller部署成一个DaemonSet 而不是传统的Deployment。

info:DaemonSet对每个集群节点(包括masters)精确调度一种类型的Pod,除非配置了一个节点来击退这些Pods。 更多的信息可以查看 DaemonSet 。

跟NodePort一样,这种方法也有几个需要注意的问题:

(1) DNS解析

配置为hostNetwork: true的pod不会使用内部的DNS解析(如kube-dns或CoreDNS),除非它们的dnsPolicy spec字段被设置成ClusterFirstWithHostNet。如果NGINX因任何原因需要解析内部名称,请考虑使用此设置。

(2) Ingress状态

因为在使用主机网络的配置中,没有service暴露Nginx ingress controller,标准云设置中使用的--publish-service标志不适用,并且所有Ingress对象的状态保持为空白。

$ kubectl get ingress

NAME HOSTS ADDRESS PORTS

test-ingress myapp.example.com 80

相反,由于bare-metal节点通常没有外部IP,因此必须启用--report-node-internal-ip-address标志,该标志将所有ingress对象的状态设置为运行NGINX ingress controller的所有节点的内部IP地址。

注意:另外,可以使用--publish-status-address标志覆盖写入Ingress对象的地址。详见 Command line arguments。

4、使用自建的边缘(Using a self-provisioned edge)

与云环境类似,这种部署方法需要一个边缘网络组件,为Kubernetes集群提供一个公共入口点。这个边缘组件可以是硬件(例如 供应商设备)或软件(例如 Haproxy),并且通常由操作团队在Kubernetes集群之外进行管理。

这种部署方法建立在上面描述的“基于NodePort服务”之上,有一个重要的不同是:外部客户端不直接访问集群节点,只有边缘组件直接访问集群节点。这特别适合于私有Kubernetes集群,其中没有一个节点具有公共IP地址。

在边缘端,唯一的先决条件是指定一个公共IP地址,该地址将所有HTTP流量转发给Kubernetes node节点和/或master。在TCP端口80和443上的传入流量被转发到目标节点上相应的HTTP和HTTPS NodePort,如下图所示:

5、外部IP(External IPs)

危险:源IP地址

该方法不允许以任何方式保留HTTP请求的源IP,因此尽管它显然很简单,但不建议使用它。

这种externalIPs service选项在之前的NodePort部分也提到过了。

根据官方Kubernetes文档的 Services页面,externalIPs选项导致kube-proxy将发送到任意IP地址和服务端口的流量路由到该服务的端点。这些IP地址必须属于目标节点。

总结:阅读官方文档的安装及注意事项,我最终选择了使用自建边缘的方式搭建统一入口点,边缘我选择的是Nginx,并且把Nginx ingress controller的NodePort设置成固定的端口(在ingress controller service中指定NodePort: 30278),避免因为某些原因重新部署ingress controller后NodePort发生改变,还要改边缘Nginx的配置。

ingress配置举例:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-web-test
  namespace: test
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - http:
      paths:
      - path: /test
        backend:
          serviceName: hellotest
          servicePort: 8190
      - path: /test2
        backend:
          serviceName: hellotest
          servicePort: 8190

以上配置好后,就可以通过边缘组件Nginx的IP/test访问服务hellotest了。我用Nginx的80端口映射了kubernetes master ip:30278。

ingress controller安装总结相关推荐

  1. 使用Golang自定义Kubernetes Ingress Controller

    在Kubernetes中通过Ingress来暴露服务到集群外部,这个已经是很普遍的方式了,而真正扮演请求转发的角色是背后的Ingress Controller,比如我们经常使用的traefik.ing ...

  2. ingress controller 和ingress使用实例

    ingress controller安装 官方文档: https://kubernetes.github.io/ingress-nginx/ 创建基础配置 kubectl apply -f https ...

  3. aws eks 配置nginx tls 和 nginx ingress controller

    参考资料 nginx快速入门 NGINX Ingress Controller 版本区别 社区版 Nginx ingress controller NGINX版 Nginx Ingress Contr ...

  4. kubernetes的ingress:Ingress controller,traefik

    文章目录 Ingress介绍 nginx ingress controller ingress URL Rewrite Basic Auth 灰度发布等各种发布方式 HTTPS CertManager ...

  5. Kubernetes 初识Ingress Controller以及部署

    在Kubernetes集群中,Ingress对集群服务(Service)中外部可访问的API对象进行管理,提供七层负载均衡能力. Ingress基本概念 在Kubernetes集群中,Ingress作 ...

  6. Kubernetes Service、Ingress、Ingress Controller

    Kubernetes 网络模型 K8S 是一种容器编排系统,可以方便地管理和部署容器应用程序.它支持通过四层负载和七层负载向容器集群中的应用程序提供负载均衡. 四层负载是一种基于传输层协议(例如TCP ...

  7. Nginx Ingress Controller 部署

    概述 本次实践的主要目的就是将入口统一,不再通过 LoadBalancer 等方式将端口暴露出来,而是使用 Ingress 提供的反向代理负载均衡功能作为我们的唯一入口.通过以下步骤操作仔细体会. 注 ...

  8. 通过阿里云容器服务K8S Ingress Controller实现应用服务的灰度发布

    简介 日常工作中我们经常需要对服务进行版本更新升级,为此我们经常使用到的发布方式有滚动升级.分批暂停发布.蓝绿发布以及灰度发布,今天主要跟大家分享下在阿里云容器服务Kubernetes集群中如何通过I ...

  9. k8s插件说明:CoreDNS、Ingress Controller、Federation、Prometheus、ELK

    CoreDNS:core公司提供的dns服务器.用于为集群中的svc创建一个域名IP的对应关系解析.有了它,就可以不通过pod的IP地址来实现pod间的互相访问,而是通过CoreDNS为pod生成的域 ...

最新文章

  1. 二叉树 | 根据前序中序遍历重建二叉树
  2. 内核驱动模块Makfle
  3. asp.net 安装element ui_Vue组件库系列三:打造属于自己的 UI 库文档(新版本的方案)...
  4. android 强制打开gps定位_Android 6.0 默认关闭定位和GPS,开启后默认选省电
  5. Requests方法 -- 关联用例执行
  6. 【组合数学】计数模型、常见组合数与组合恒等式 ★★
  7. Windows8 Metro开发 (04) : 保存/读取本地应用程序设置
  8. 加拿大留学|电气工程/计算机工程/计算机科学,傻傻分不清
  9. 网易马进:DDB从分布式数据库到结构化数据中心的架构变迁
  10. php 类中调用另类,PHP return语句另类用法不止是在函数中,return语句_PHP教程
  11. SQL无所不能:DBA宝妈宝爸系列分享
  12. HTML5唐诗三百首,《唐诗三百首》中王维5首五言绝句,代表了盛唐绝句的最高成就!...
  13. 【数据结构和算法笔记】AOE网和关键路径
  14. mysqld install mysql default_Mysql_安装
  15. 关于opencv中图像的坐标原点的区分
  16. excel将内容粘贴到筛选后的可见单元格
  17. Python 写入文件
  18. 【dell电脑Windows10重启自动修复】重启之后一直修复,又重启(已解决)
  19. STM32F4最小系统硬件设计
  20. 市场分析-全球与中国OLED用氧化氘市场现状及未来发展趋势

热门文章

  1. 同一块网络芯片的多个SOCKET,可以同时设置成客户端去连接电脑服务器的一个端口吗,怎么实现?
  2. nacos之负载均衡
  3. Linux qq查看对方ip,怎么知道对方是否隐身(基于Linux QQ)
  4. 用c语言描述普里姆算法和克鲁斯卡尔算法,克鲁斯卡尔算法+普里姆算法 详解
  5. 中国投入产出表(1990-2018年)
  6. bmp文件格式与保存
  7. Activity的四种状态
  8. 聊天功能获取聊天记录列表并展示最新一条聊天记录
  9. lamp Discuz 论坛搭建
  10. 判断闰年——判断2000年到3000年之间的所有的闰年