k8s Ingress 服務部署方式
通常情況下,service和pod僅可在集群內部網絡中通過IP地址訪問。所有到達邊界路由器的流量或被丟棄或被轉發到其他地方
官網對 Ingress 的定義為管理對外服務到集群內服務之間規則的集合,通俗點講就是它定義規則來允許進入集群的請求被轉發到集群中對應服務上,從來實現服務暴漏。Ingress 能把集群內 Service 配置成外網能夠訪問的 URL,流量負載均衡,終止SSL,提供基于域名訪問的虛擬主機等等。
Ingress
Ingress 使用開源的反向代理負載均衡器來實現對外暴漏服務,比如 Nginx、Apache、Haproxy等。Nginx Ingress 一般有三個組件組成:
Nginx 反向代理負載均衡器
Ingress Controller
Ingress Controller 可以理解為控制器,它通過不斷的跟 Kubernetes API 交互,實時獲取后端 Service、Pod 等的變化,比如新增、刪除等,然后結合 Ingress 定義的規則生成配置,然后動態更新上邊的 Nginx 負載均衡器,并刷新使配置生效,來達到服務自動發現的作用。
Ingress
Ingress 則是定義規則,通過它定義某個域名的請求過來之后轉發到集群中指定的 Service。它可以通過 Yaml 文件定義,可以給一個或多個 Service 定義一個或多個 Ingress 規則。
以上三者有機的協調配合起來,就可以完成 Kubernetes 集群服務的暴漏
Kubernetes 使用 Nginx Ingress 暴漏tomcat服務,前提我們需要有一個正常運行的集群服務,根據之前創建的的kubernetes集群,進行測試
官網地址: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組件有幾個部分組成:
configmap.yaml:提供configmap可以在線更行nginx的配置
default-backend.yaml:提供一個缺省的后臺錯誤頁面 404
namespace.yaml:創建一個獨立的命名空間 ingress-nginx
rbac.yaml:創建對應的role rolebinding 用于rbac
tcp-services-configmap.yaml:修改L4負載均衡配置的configmap
udp-services-configmap.yaml:修改L4負載均衡配置的configmap
nginx-ingress-controller.yaml:有應用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"
說明:
kind: DaemonSet:官方文檔給的是deployment,replicate 為 1,這樣將會在某一臺節點上啟動對應的nginx-ingress-controller pod。外部流量訪問至該節點,由該節點負載分擔至內部的service。測試環境考慮防止單點故障,改為DaemonSet,配合親和性部署在制定節點上啟動nginx-ingress-controller pod,確保有多個節點啟動nginx-ingress-controller pod,后續將這些節點加入到外部硬件負載均衡組實現高可用性。
hostNetwork: true:添加該字段,暴露nginx-ingress-controller pod的服務端口(80)
nodeSelector: 加入親和性部署,有custom/ingress-controller-ready label的才會部署該DaemonSet(未使用)
加載yaml文件
kubectl create -f .
查看pod創建情況
#kubectl get pod,svc,deployment -n ingress-nginx -o wide
在上面已經部署了 ingress-nginx,下面我們部署一個tomcat作為對外暴露的服務
使用ingress部署一個對外暴露的服務包含一個pod和一個service
創建tomcat service yaml
vi tomcat-deploy.yaml
復制下面的內容:
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
創建tomcat pod yaml文件
vi ingress-tomcat.yaml
復制下面內容:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
? name: ingress-tomcat
? namespace: default
? annotations:
?? kubernetes.io/ingress.class: "nginx"
spec:
? rules:
? - host: k8s.master ##這個地方使用主機名或者域名,不能使用IP地址
?? http:
? ?? paths:
? ?? - path:
? ? ?? backend:
? ? ? ?? serviceName: tomcat
? ? ? ?? servicePort: 8080
然后執行:
kubectl apply -f tomcat-deploy.yaml
?
kubectl apply -f ingress-tomcat.yaml
服務啟動以后就可以通過上面配置的主機名或者域名進行訪問tomcat 了