k8s Ingress 服務(wù)部署方式
通常情況下,service和pod僅可在集群內(nèi)部網(wǎng)絡(luò)中通過(guò)IP地址訪問(wèn)。所有到達(dá)邊界路由器的流量或被丟棄或被轉(zhuǎn)發(fā)到其他地方
官網(wǎng)對(duì) Ingress 的定義為管理對(duì)外服務(wù)到集群內(nèi)服務(wù)之間規(guī)則的集合,通俗點(diǎn)講就是它定義規(guī)則來(lái)允許進(jìn)入集群的請(qǐng)求被轉(zhuǎn)發(fā)到集群中對(duì)應(yīng)服務(wù)上,從來(lái)實(shí)現(xiàn)服務(wù)暴漏。Ingress 能把集群內(nèi) Service 配置成外網(wǎng)能夠訪問(wèn)的 URL,流量負(fù)載均衡,終止SSL,提供基于域名訪問(wèn)的虛擬主機(jī)等等。
Ingress
Ingress 使用開(kāi)源的反向代理負(fù)載均衡器來(lái)實(shí)現(xiàn)對(duì)外暴漏服務(wù),比如 Nginx、Apache、Haproxy等。Nginx Ingress 一般有三個(gè)組件組成:
Nginx 反向代理負(fù)載均衡器
Ingress Controller
Ingress Controller 可以理解為控制器,它通過(guò)不斷的跟 Kubernetes API 交互,實(shí)時(shí)獲取后端 Service、Pod 等的變化,比如新增、刪除等,然后結(jié)合 Ingress 定義的規(guī)則生成配置,然后動(dòng)態(tài)更新上邊的 Nginx 負(fù)載均衡器,并刷新使配置生效,來(lái)達(dá)到服務(wù)自動(dòng)發(fā)現(xiàn)的作用。
Ingress
Ingress 則是定義規(guī)則,通過(guò)它定義某個(gè)域名的請(qǐng)求過(guò)來(lái)之后轉(zhuǎn)發(fā)到集群中指定的 Service。它可以通過(guò) Yaml 文件定義,可以給一個(gè)或多個(gè) Service 定義一個(gè)或多個(gè) Ingress 規(guī)則。
以上三者有機(jī)的協(xié)調(diào)配合起來(lái),就可以完成 Kubernetes 集群服務(wù)的暴漏
Kubernetes 使用 Nginx Ingress 暴漏tomcat服務(wù),前提我們需要有一個(gè)正常運(yùn)行的集群服務(wù),根據(jù)之前創(chuàng)建的的kubernetes集群,進(jìn)行測(cè)試
官網(wǎng)地址:https://kubernetes.io/docs/concepts/services-networking/ingress/
https://github.com/kubernetes/ingress-nginx/
使用到的鏡像
gcr.io/google_containers/defaultbackend:1.4
quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.18.0
ingress-nginx組件有幾個(gè)部分組成:
configmap.yaml:提供configmap可以在線更行nginx的配置
default-backend.yaml:提供一個(gè)缺省的后臺(tái)錯(cuò)誤頁(yè)面 404
namespace.yaml:創(chuàng)建一個(gè)獨(dú)立的命名空間 ingress-nginx
rbac.yaml:創(chuàng)建對(duì)應(yīng)的role rolebinding 用于rbac
tcp-services-configmap.yaml:修改L4負(fù)載均衡配置的configmap
udp-services-configmap.yaml:修改L4負(fù)載均衡配置的configmap
nginx-ingress-controller.yaml:有應(yīng)用rbac的nginx-ingress-controller組件
YAML配置文件
namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
? name: ingress-nginx
default-backend.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
? name: default-http-backend
? labels:
?? app.kubernetes.io/name: default-http-backend
?? app.kubernetes.io/part-of: ingress-nginx
? namespace: ingress-nginx
spec:
? replicas: 1
? selector:
?? matchLabels:
? ?? app.kubernetes.io/name: default-http-backend
? ?? app.kubernetes.io/part-of: ingress-nginx
? template:
?? metadata:
? ?? labels:
? ? ?? app.kubernetes.io/name: default-http-backend
? ? ?? app.kubernetes.io/part-of: ingress-nginx
?? spec:
? ?? terminationGracePeriodSeconds: 60
? ?? containers:
? ? ?? - name: default-http-backend
? ? ? ?? image: googlecontainer/defaultbackend-amd64:1.4
? ? ? ?? #image:
? ? ? ?? livenessProbe:
? ? ? ? ?? httpGet:
? ? ? ? ? ?? path: /healthz
? ? ? ? ? ?? port: 8080
? ? ? ? ? ?? scheme: HTTP
? ? ? ? ?? initialDelaySeconds: 30
? ? ? ? ?? timeoutSeconds: 5
? ? ? ?? ports:
? ? ? ? ?? - containerPort: 8080
? ? ? ?? resources:
? ? ? ? ?? limits:
? ? ? ? ? ?? cpu: 10m
? ? ? ? ? ?? memory: 20Mi
? ? ? ? ?? requests:
? ? ? ? ? ?? cpu: 10m
? ? ? ? ? ?? memory: 20Mi
?
---
apiVersion: v1
kind: Service
metadata:
? name: default-http-backend
? namespace: ingress-nginx
? labels:
?? app.kubernetes.io/name: default-http-backend
?? app.kubernetes.io/part-of: ingress-nginx
spec:
? ports:
?? - port: 80
? ?? targetPort: 8080
? selector:
?? app.kubernetes.io/name: default-http-backend
?? app.kubernetes.io/part-of: ingress-nginx
---
?
configmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
? name: nginx-configuration
? namespace: ingress-nginx
? labels:
?? app: ingress-nginx
tcp-services-configmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
? name: tcp-services
? namespace: ingress-nginx
udp-services-configmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
? name: udp-services
? namespace: ingress-nginx
rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
? name: nginx-ingress-serviceaccount
? namespace: ingress-nginx
? labels:
?? app.kubernetes.io/name: ingress-nginx
?? app.kubernetes.io/part-of: ingress-nginx
?
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
? name: nginx-ingress-clusterrole
? labels:
?? app.kubernetes.io/name: ingress-nginx
?? app.kubernetes.io/part-of: ingress-nginx
rules:
? - apiGroups:
? ?? - ""
?? resources:
? ?? - configmaps
? ?? - endpoints
? ?? - nodes
? ?? - pods
? ?? - secrets
?? verbs:
? ?? - list
? ?? - watch
? - apiGroups:
? ?? - ""
?? resources:
? ?? - nodes
?? verbs:
? ?? - get
? - apiGroups:
? ?? - ""
?? resources:
? ?? - services
?? verbs:
? ?? - get
? ?? - list
? ?? - watch
? - apiGroups:
? ?? - "extensions"
?? resources:
? ?? - ingresses
?? verbs:
? ?? - get
? ?? - list
? ?? - watch
? - apiGroups:
? ?? - ""
?? resources:
? ?? - events
?? verbs:
? ?? - create
? ?? - patch
? - apiGroups:
? ?? - "extensions"
?? resources:
? ?? - ingresses/status
?? verbs:
? ?? - update
?
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
? name: nginx-ingress-role
? namespace: ingress-nginx
? labels:
?? app.kubernetes.io/name: ingress-nginx
?? app.kubernetes.io/part-of: ingress-nginx
rules:
? - apiGroups:
? ?? - ""
?? resources:
? ?? - configmaps
? ?? - pods
? ?? - secrets
? ?? - namespaces
?? verbs:
? ?? - get
? - apiGroups:
? ?? - ""
?? resources:
? ?? - configmaps
?? resourceNames:
? ?? # Defaults to "<election-id>-<ingress-class>"
? ?? # Here: "<ingress-controller-leader>-<nginx>"
? ?? # This has to be adapted if you change either parameter
? ?? # when launching the nginx-ingress-controller.
? ?? - "ingress-controller-leader-nginx"
?? verbs:
? ?? - get
? ?? - update
? - apiGroups:
? ?? - ""
?? resources:
? ?? - configmaps
?? verbs:
? ?? - create
? - apiGroups:
? ?? - ""
?? resources:
? ?? - endpoints
?? verbs:
? ?? - get
?
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
? name: nginx-ingress-role-nisa-binding
? namespace: ingress-nginx
? labels:
?? app.kubernetes.io/name: ingress-nginx
?? app.kubernetes.io/part-of: ingress-nginx
roleRef:
? apiGroup: rbac.authorization.k8s.io
? kind: Role
? name: nginx-ingress-role
subjects:
? - kind: ServiceAccount
?? name: nginx-ingress-serviceaccount
?? namespace: ingress-nginx
?
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
? name: nginx-ingress-clusterrole-nisa-binding
? labels:
?? app.kubernetes.io/name: ingress-nginx
?? app.kubernetes.io/part-of: ingress-nginx
roleRef:
? apiGroup: rbac.authorization.k8s.io
? kind: ClusterRole
? name: nginx-ingress-clusterrole
subjects:
? - kind: ServiceAccount
?? name: nginx-ingress-serviceaccount
?? namespace: ingress-nginx
?
---
nginx-ingress-controller.yaml
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
? name: nginx-ingress-controller
? namespace: ingress-nginx
spec:
? selector:
?? matchLabels:
? ?? app: ingress-nginx
? template:
?? metadata:
? ?? labels:
? ? ?? app: ingress-nginx
? ?? annotations:
? ? ?? prometheus.io/port: '10254'
? ? ?? prometheus.io/scrape: 'true'
?? spec:
? ?? serviceAccountName: nginx-ingress-serviceaccount
? ?? hostNetwork: true
? ?? containers:
? ? ?? - name: nginx-ingress-controller
? ? ? ?? image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.18.0
? ? ? ?? args:
? ? ? ? ?? - /nginx-ingress-controller
? ? ? ? ?? - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
? ? ? ? ?? - --configmap=$(POD_NAMESPACE)/nginx-configuration
? ? ? ? ?? - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
? ? ? ? ?? - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
? ? ? ? ?? - --annotations-prefix=nginx.ingress.kubernetes.io
? ? ? ?? env:
? ? ? ? ?? - name: POD_NAME
? ? ? ? ? ?? valueFrom:
? ? ? ? ? ? ?? fieldRef:
? ? ? ? ? ? ? ?? fieldPath: metadata.name
? ? ? ? ?? - name: POD_NAMESPACE
? ? ? ? ? ?? valueFrom:
? ? ? ? ? ? ?? fieldRef:
? ? ? ? ? ? ? ?? fieldPath: metadata.namespace
? ? ? ?? ports:
? ? ? ?? - name: http
? ? ? ? ?? containerPort: 80
? ? ? ?? - name: https
? ? ? ? ?? containerPort: 443
? ? ? ?? livenessProbe:
? ? ? ? ?? failureThreshold: 3
? ? ? ? ?? httpGet:
? ? ? ? ? ?? path: /healthz
? ? ? ? ? ?? port: 10254
? ? ? ? ? ?? scheme: HTTP
? ? ? ? ?? initialDelaySeconds: 10
? ? ? ? ?? periodSeconds: 10
? ? ? ? ?? successThreshold: 1
? ? ? ? ?? timeoutSeconds: 1
? ? ? ?? readinessProbe:
? ? ? ? ?? failureThreshold: 3
? ? ? ? ?? httpGet:
? ? ? ? ? ?? path: /healthz
? ? ? ? ? ?? port: 10254
? ? ? ? ? ?? scheme: HTTP
? ? ? ? ?? periodSeconds: 10
? ? ? ? ?? successThreshold: 1
? ? ? ? ?? timeoutSeconds: 1
? ?? #nodeSelector:
? ? ?? #custom/ingress-controller-ready: "true"
說(shuō)明:
kind: DaemonSet:官方文檔給的是deployment,replicate 為 1,這樣將會(huì)在某一臺(tái)節(jié)點(diǎn)上啟動(dòng)對(duì)應(yīng)的nginx-ingress-controller pod。外部流量訪問(wèn)至該節(jié)點(diǎn),由該節(jié)點(diǎn)負(fù)載分擔(dān)至內(nèi)部的service。測(cè)試環(huán)境考慮防止單點(diǎn)故障,改為DaemonSet,配合親和性部署在制定節(jié)點(diǎn)上啟動(dòng)nginx-ingress-controller pod,確保有多個(gè)節(jié)點(diǎn)啟動(dòng)nginx-ingress-controller pod,后續(xù)將這些節(jié)點(diǎn)加入到外部硬件負(fù)載均衡組實(shí)現(xiàn)高可用性。
hostNetwork: true:添加該字段,暴露nginx-ingress-controller pod的服務(wù)端口(80)
nodeSelector: 加入親和性部署,有custom/ingress-controller-ready label的才會(huì)部署該DaemonSet(未使用)
加載yaml文件
kubectl create -f .
查看pod創(chuàng)建情況
#kubectl get pod,svc,deployment -n ingress-nginx -o wide

在上面已經(jīng)部署了 ingress-nginx,下面我們部署一個(gè)tomcat作為對(duì)外暴露的服務(wù)
使用ingress部署一個(gè)對(duì)外暴露的服務(wù)包含一個(gè)pod和一個(gè)service
創(chuàng)建tomcat service yaml
vi tomcat-deploy.yaml
復(fù)制下面的內(nèi)容:
apiVersion: v1
kind: Service
metadata:
? name: tomcat
? namespace: default
spec:
? selector:
?? app: tomcat
?? release: canary
? ports:
? - name: http
?? targetPort: 8080
?? port: 8080
? - name: ajp
?? targetPort: 8009
?? port: 8009
?
---
apiVersion: apps/v1
kind: Deployment
metadata:
? name: tomcat-deploy
? namespace: default
spec:
? replicas: 1
? selector:
?? matchLabels:
? ?? app: tomcat
? ?? release: canary
? template:
?? metadata:
? ?? labels:
? ? ?? app: tomcat
? ? ?? release: canary
?? spec:
? ?? containers:
? ?? - name: tomcat
? ? ?? image: tomcat
? ? ?? ports:
? ? ?? - name: http
? ? ? ?? containerPort: 8080
創(chuàng)建tomcat pod yaml文件
vi ingress-tomcat.yaml
復(fù)制下面內(nèi)容:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
? name: ingress-tomcat
? namespace: default
? annotations:
?? kubernetes.io/ingress.class: "nginx"
spec:
? rules:
? - host: k8s.master ##這個(gè)地方使用主機(jī)名或者域名,不能使用IP地址
?? http:
? ?? paths:
? ?? - path:
? ? ?? backend:
? ? ? ?? serviceName: tomcat
? ? ? ?? servicePort: 8080
然后執(zhí)行:
kubectl apply -f tomcat-deploy.yaml
?
kubectl apply -f ingress-tomcat.yaml
服務(wù)啟動(dòng)以后就可以通過(guò)上面配置的主機(jī)名或者域名進(jìn)行訪問(wèn)tomcat 了
