前文咱們瞭解了k8s上的service資源的相關話題,回顧請參考:http://www.javashuo.com/article/p-xcxfprec-nz.html;今天咱們來了解下k8s上的Ingress資源的相關話題;html
咱們知道在k8s上service是用來解決Pod訪問問題,它是經過kube-proxy在每一個節點上建立iptables規則或ipvs規則,在用戶請求某個pod時,用戶的請求會被其service規則所捕獲,從而實現訪問對應pod;對於service來說,用戶請求直接在傳輸層就被捕獲轉發,效率很高效,但這同時也引入了一個新問題;好比咱們運行的pod對外客戶端訪問須要https通訊,若是使用service這種4層調度,那就意味着每一個pod上咱們要配置證書,這很顯然不是咱們想要作的;那有沒有什麼辦法作到在用戶訪問pod對應的service時使用https,而對應pod裏又不用https協議呢?答案是有的;好比咱們可使用nginx來作https會話卸載器;咱們只須要在代理上配置證書便可;又好比咱們在k8s上運行了各類各樣的pod,這些pod的功能每一個都不同,有點是專門處理用戶認證的,有點是專門處理站點主頁的,有點專門處理支付的等等,而這些pod對外都是提供一個獨有的url,那麼這些pod須要怎麼才能被集羣外部訪問到呢?咱們知道對於一個站點來說,若是後端有多個server同時提供一種服務,咱們能夠把這些同功能的server定義成一個組,而後使用nginx代理將不一樣功能url的訪問代理到不一樣組上便可;這樣一來解決了後端多server被負載訪問的問題;那麼對於k8s上這種同功能的pod怎麼歸併成一個組呢?用戶訪問不一樣url怎麼調度到不一樣的組上呢?很顯然要想實現這些功能,在k8s上應該有一個相似nginx同樣的代理存在;這個代理就叫作ingress 控制器;ingress 控制器和k8s上的其餘控制不同,ingress控制器並不能直接運行爲kube-controller-manager的一部分,它相似k8s集羣上的coredns,須要在集羣上單獨部署,本質上就是一個pod,咱們可使用k8s上的ds或deploy控制器來建立它;ingress controller pod的做用主要是引入集羣外部流量,並實時監控着apiserver上ingress資源的變更,並將其ingress中定義的規則轉化爲對應ingress控制器對應應用程序的專有配置,而後動態的重載或重啓對應守護進程來使其配置文件生效;在k8s上ingress是一種標準資源,它本質上就是咱們定義的基於dns名稱(host)或url路徑把請求轉發至指定service資源的規則;簡單講ingress就是咱們用來定義代理的配置所建立的資源;ingress控制器就是把對應ingress規則轉換爲對應ingress控制器中應用程序的專有配置,而後重啓或重載對應配置文件使其生效的組件;node
ingress和ingress controller pod的關係linux
提示:如上圖所示,ingress就是ingress 控制器pod的代理規則;用戶請求某個後端pod所提供的服務時,首先會經過ingress controller pod把流量引入到集羣內部,而後ingress controller pod根據ingress定義的規則,把對應ingress規則轉化爲對應ingress controller pod實現的對應應用的配置(ingress controller 能夠由任何具備七層反向代理功能的服務實現,好比nginx,haproxy等等)而後再適配用戶請求,把對應請求反代到對應service上;而對於pod的選擇上,ingress控制器能夠基於對應service中的標籤選擇器,直接同pod直接通訊,無須經過service對象api的再次轉發,從而省去了用戶請求到kube-proxy實現的代理開銷(本質上ingress controller 也是運行爲一個pod,和其餘pod在同一網段中);nginx
ingress controller部署git
在k8s上ingress controller的實現有不少,好比基於nginx的,基於haproxy的等等,這裏以nginx爲例;github
下載ingress-nginx包web
wget https://github.com/kubernetes/ingress-nginx/archive/nginx-0.28.0.tar.gz
解壓包,找到對應的部署清單json
[root@master01 ~]# ll total 92144 -rw------- 1 root root 65586688 Dec 8 15:16 flannel-v0.13.1-rc1.tar drwxr-xr-x 2 root root 4096 Dec 21 21:04 manifests -rw-r--r-- 1 root root 28760559 Dec 21 21:02 nginx-0.28.0.tar.gz [root@master01 ~]# tar xf nginx-0.28.0.tar.gz [root@master01 ~]# ls flannel-v0.13.1-rc1.tar ingress-nginx-nginx-0.28.0 manifests nginx-0.28.0.tar.gz [root@master01 ~]# cd ingress-nginx-nginx-0.28.0/ [root@master01 ingress-nginx-nginx-0.28.0]# ls build code-of-conduct.md docs hack labels.yaml mkdocs.yml README.md SECURITY_CONTACTS version Changelog.md CONTRIBUTING.md go.mod images LICENSE OWNERS requirements-docs.txt test cmd deploy go.sum internal Makefile OWNERS_ALIASES rootfs vendor [root@master01 ingress-nginx-nginx-0.28.0]# cd deploy/ [root@master01 deploy]# ls aws cloud-generic grafana prometheus static with-validating-webhook.yaml.tpl baremetal cluster-wide minikube README.md validating-webhook.yaml.tpl [root@master01 deploy]# cd static/ [root@master01 static]# ls configmap.yaml mandatory.yaml namespace.yaml provider rbac.yaml with-rbac.yaml [root@master01 static]# pwd /root/ingress-nginx-nginx-0.28.0/deploy/static [root@master01 static]#
提示:資源配置清單在ingress-nginx-nginx-0.28.0/deploy/static下,名爲mandatory.yaml;後端
資源配置清單內容api
apiVersion: v1 kind: Namespace metadata: name: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: nginx-configuration namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: tcp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: udp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- 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: - "" resources: - events verbs: - create - patch - apiGroups: - "extensions" - "networking.k8s.io" resources: - ingresses verbs: - get - list - watch - apiGroups: - "extensions" - "networking.k8s.io" 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 --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-ingress-controller namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx template: metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx annotations: prometheus.io/port: "10254" prometheus.io/scrape: "true" spec: # wait up to five minutes for the drain of connections terminationGracePeriodSeconds: 300 serviceAccountName: nginx-ingress-serviceaccount nodeSelector: kubernetes.io/os: linux containers: - name: nginx-ingress-controller image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.28.0 args: - /nginx-ingress-controller - --configmap=$(POD_NAMESPACE)/nginx-configuration - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services - --udp-services-configmap=$(POD_NAMESPACE)/udp-services - --publish-service=$(POD_NAMESPACE)/ingress-nginx - --annotations-prefix=nginx.ingress.kubernetes.io securityContext: allowPrivilegeEscalation: true capabilities: drop: - ALL add: - NET_BIND_SERVICE # www-data -> 101 runAsUser: 101 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace ports: - name: http containerPort: 80 protocol: TCP - name: https containerPort: 443 protocol: TCP livenessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 readinessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 lifecycle: preStop: exec: command: - /wait-shutdown --- apiVersion: v1 kind: LimitRange metadata: name: ingress-nginx namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: limits: - default: min: memory: 90Mi cpu: 100m type: Container
提示:以上清單主要定義了一個名稱ingress-nginx的名稱空間,在其名稱空間下建立了幾個configmap,最重要的是用deployment建立了一個ingress-nginx pod;
這裏說一下,對於ingress-nginx控制器,它本質仍是運行爲一個pod,對於pod來講要想接入外部訪問流量到集羣內部來,有三種方式,一種是使用NodePort類型的service;第二種是使用ds或deploy控制器,在定義pod模板時使用hostPort把pod端口映射到宿主機方式;第三種是定義pod模板時使用hostNetwork,直接共享宿主機網絡名稱空間;以下所示
使用專有NodePort service來引入外部流量
提示:這種使用deploy控制管理ingress controller pod,若是在pod模板中沒有暴露端口,則須要建立一個service資源來暴露ingress controller pod的端口來引入外部流量到集羣內部;
使用ds控制器管理ingress controller pod在pod模板中使用hostPort方式暴露端口
提示:使用ds控制器可以保證每一個節點上只運行一個ingress controller,因此咱們能夠把對應ingress controller pod端端口經過端口映射的方式映射到宿主機上的某一固定端口;
使用ds控制器在pod模板中使用hostNetwork方式共享宿主機網絡名稱空間
提示:共享宿主機網絡名稱空間,也必須使用ds控制器來確保對應每一個節點上只能運行一個ingress controller pod,這樣才能確保每一個ingress controller pod可以正常把端口暴露出去,以供集羣外部客戶端訪問;
選擇上述其中一種方式暴露ingress controller pod的端口便可;若是選擇使用ds控制器來暴露端口,咱們就須要修改其對應資源配置清單中的pod模板,以下所示
使用ds控制器來管理ingress controller pod在pod模板中使用hostPort方式暴露端口
apiVersion: v1 kind: Namespace metadata: name: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: nginx-configuration namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: tcp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: udp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- 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: - "" resources: - events verbs: - create - patch - apiGroups: - "extensions" - "networking.k8s.io" resources: - ingresses verbs: - get - list - watch - apiGroups: - "extensions" - "networking.k8s.io" 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 --- apiVersion: apps/v1 kind: DaemonSet metadata: name: nginx-ingress-controller namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: selector: matchLabels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx template: metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx annotations: prometheus.io/port: "10254" prometheus.io/scrape: "true" spec: # wait up to five minutes for the drain of connections terminationGracePeriodSeconds: 300 serviceAccountName: nginx-ingress-serviceaccount nodeSelector: kubernetes.io/os: linux containers: - name: nginx-ingress-controller image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.28.0 args: - /nginx-ingress-controller - --configmap=$(POD_NAMESPACE)/nginx-configuration - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services - --udp-services-configmap=$(POD_NAMESPACE)/udp-services - --publish-service=$(POD_NAMESPACE)/ingress-nginx - --annotations-prefix=nginx.ingress.kubernetes.io securityContext: allowPrivilegeEscalation: true capabilities: drop: - ALL add: - NET_BIND_SERVICE # www-data -> 101 runAsUser: 101 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace ports: - name: http containerPort: 80 hostPort: 30080 protocol: TCP - name: https containerPort: 443 hostPort: 30443 protocol: TCP livenessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 readinessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 lifecycle: preStop: exec: command: - /wait-shutdown --- apiVersion: v1 kind: LimitRange metadata: name: ingress-nginx namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: limits: - default: min: memory: 90Mi cpu: 100m type: Container
提示:只需把對應控制器類型更改成DaemonSet,在pod模板中spec字段下把replicas去掉;在spec.template.spec.containers.ports字段中加上nodePort字段指定要把容器的端口映射到宿主機上某個端口;若是暴露的端口是非標準端口,在對應k8s集羣外部咱們還須要部署反代,好比使用nginx,haproxy,lvs;
使用ds控制器管理ingress controller pod在ds控制器資源配置中使用hostNetwork
apiVersion: v1 kind: Namespace metadata: name: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: nginx-configuration namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: tcp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: udp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- 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: - "" resources: - events verbs: - create - patch - apiGroups: - "extensions" - "networking.k8s.io" resources: - ingresses verbs: - get - list - watch - apiGroups: - "extensions" - "networking.k8s.io" 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 --- apiVersion: apps/v1 kind: DaemonSet metadata: name: nginx-ingress-controller namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: selector: matchLabels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx template: metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx annotations: prometheus.io/port: "10254" prometheus.io/scrape: "true" spec: # wait up to five minutes for the drain of connections terminationGracePeriodSeconds: 300 serviceAccountName: nginx-ingress-serviceaccount nodeSelector: kubernetes.io/os: linux hostNetwork: true containers: - name: nginx-ingress-controller image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.28.0 args: - /nginx-ingress-controller - --configmap=$(POD_NAMESPACE)/nginx-configuration - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services - --udp-services-configmap=$(POD_NAMESPACE)/udp-services - --publish-service=$(POD_NAMESPACE)/ingress-nginx - --annotations-prefix=nginx.ingress.kubernetes.io securityContext: allowPrivilegeEscalation: true capabilities: drop: - ALL add: - NET_BIND_SERVICE # www-data -> 101 runAsUser: 101 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace ports: - name: http containerPort: 80 protocol: TCP - name: https containerPort: 443 protocol: TCP livenessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 readinessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 lifecycle: preStop: exec: command: - /wait-shutdown --- apiVersion: v1 kind: LimitRange metadata: name: ingress-nginx namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: limits: - default: min: memory: 90Mi cpu: 100m type: Container
提示:把對應控制器類型更改外DaemonSet,在pod模板中spec字段下的replicas字段去掉;在spec.template.spec字段下加上hostNetwork: true便可;以上兩種使用ds控制器管理ingress controller pod也可使用node選擇器,來篩選在某個節點上建立ingress controller pod;
使用deploy控制器管理ingress controller pod,就直接應用mandatory.yaml便可
[root@master01 ~]# kubectl apply -f mandatory.yaml namespace/ingress-nginx created configmap/nginx-configuration created configmap/tcp-services created configmap/udp-services created serviceaccount/nginx-ingress-serviceaccount created Warning: rbac.authorization.k8s.io/v1beta1 ClusterRole is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRole clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created Warning: rbac.authorization.k8s.io/v1beta1 Role is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 Role role.rbac.authorization.k8s.io/nginx-ingress-role created Warning: rbac.authorization.k8s.io/v1beta1 RoleBinding is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 RoleBinding rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created Warning: rbac.authorization.k8s.io/v1beta1 ClusterRoleBinding is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRoleBinding clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created deployment.apps/nginx-ingress-controller created limitrange/ingress-nginx created [root@master01 ~]#
查看應用資源清單建立的資源對象
[root@master01 ~]# kubectl get all -n ingress-nginx NAME READY STATUS RESTARTS AGE pod/nginx-ingress-controller-5466cb8999-4lsjc 1/1 Running 0 80s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx-ingress-controller 1/1 1 1 80s NAME DESIRED CURRENT READY AGE replicaset.apps/nginx-ingress-controller-5466cb8999 1 1 1 80s [root@master01 ~]#
提示:能夠看到在ingress-nginx名稱空間下建立了一個deploy控制器,對應控制器建立了一個nginx-ingress-controller控制器pod;可是此pod如今不能被外部客戶端訪問到,咱們須要建立一個service來引入外部流量到此pod上;
查看pod標籤
[root@master01 ~]# kubectl get pod -n ingress-nginx --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-ingress-controller-5466cb8999-4lsjc 1/1 Running 0 4m38s app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx,pod-template-hash=5466cb8999 [root@master01 ~]#
根據上述標籤來寫一個建立ingress-service資源的配置清單
[root@master01 ~]# cat ingress-nginx-service.yaml apiVersion: v1 kind: Service metadata: name: ingress-nginx-svc namespace: ingress-nginx spec: type: NodePort ports: - port: 80 name: http nodePort: 30080 - port: 443 name: https nodePort: 30443 selector: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx [root@master01 ~]#
提示:以上配置清單主要把知足對應標籤選擇器的pod關聯起來;並把對應pod的80和443端口分別映射到對應主機上的30080和30443端口;
應用配置清單
[root@master01 ~]# kubectl apply -f ingress-nginx-service.yaml service/ingress-nginx-svc created [root@master01 ~]# kubectl get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-svc NodePort 10.98.4.208 <none> 80:30080/TCP,443:30443/TCP 13s [root@master01 ~]#
訪問集羣任意節點ip的30080和30443端口,看看是否訪問到對應pod?
提示:30080是可以正常訪問的,只是它顯示404,是由於咱們沒有對應的主頁;
訪問30443端口
提示:30443是一個https端口,因此訪問必須用https協議訪問,這裏提示訪問頁面有風險是由於瀏覽器不信任證書引發的,咱們能夠點擊高級,信任證書便可;一樣30443端口也是返回404,是由於沒有主頁的緣由;兩個端口可以正常訪問,說明咱們在k8s上部署的ingress-nginx controller就部署好了;
ingress資源的使用
在k8s上建立一個deploy控制器,讓其管理2個 ikubernetes/myapp:v1鏡像運行的pod,而後再建立一個對應的service
[root@master01 manifests]# cat myapp-demo.yaml apiVersion: apps/v1 kind: Deployment metadata: name: myapp namespace: default spec: replicas: 2 selector: matchLabels: app: myapp rel: stable template: metadata: namespace: default labels: app: myapp rel: stable spec: containers: - name: myapp image: ikubernetes/myapp:v1 --- apiVersion: v1 kind: Service metadata: name: myapp namespace: default spec: selector: app: myapp rel: stable ports: - name: http port: 80 targetPort: 80 [root@master01 manifests]#
提示:一個清單中定義多個資源,須要用「---」來分割資源;
應用資源清單
[root@master01 manifests]# kubectl apply -f myapp-demo.yaml deployment.apps/myapp created service/myapp created [root@master01 manifests]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-6479b786f5-9d4mh 1/1 Running 0 11s 10.244.2.98 node02.k8s.org <none> <none> myapp-6479b786f5-k252c 1/1 Running 0 11s 10.244.4.20 node04.k8s.org <none> <none> [root@master01 manifests]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4h52m myapp ClusterIP 10.105.208.218 <none> 80/TCP 21s [root@master01 manifests]# kubectl describe svc myapp Name: myapp Namespace: default Labels: <none> Annotations: <none> Selector: app=myapp,rel=stable Type: ClusterIP IP Families: <none> IP: 10.105.208.218 IPs: 10.105.208.218 Port: http 80/TCP TargetPort: 80/TCP Endpoints: 10.244.2.98:80,10.244.4.20:80 Session Affinity: None Events: <none> [root@master01 manifests]#
建立ingress資源來反代以上資源
示例:建立ingress資源
[root@master01 manifests]# cat ingress-myapp.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-myapp namespace: default annotations: kubernetes.io/ingress.class: "nginx" spec: rules: - host: www.myapp.com http: paths: - path: / backend: serviceName: myapp servicePort: 80 [root@master01 manifests]#
提示:建立ingress資源apiVersion的值要寫成extensions/v1beta1,kind爲Ingress;對應metadata中的annotations的配置表示把ingress資源通知給那個類別的ingress controller,若是k8s集羣上有多個類別的ingress controller時,這一項特別有用;在spec字段主要內嵌了三個字段,rules字段用來定義反代規則列表,其值爲一個對象列表;其中rules字段裏主要host和http字段;host用來指定虛擬主機的fqdn名稱,若是不寫表示匹配任意虛擬主機名稱;http是用來定義指向後端的http選擇器列表;其值爲一個對象,裏面只有一個paths字段,用於指定把請求映射到後端的某個路徑;其值爲一個對象列表;對應paths字段中能夠定義path,用來指定映射後端的路徑;backend用於指定後端pod的service,其值爲一個對象;serviceName用於指定對應pod的service名稱;servicePort用於指定後端服務的端口;以上配置表示把www.myapp.com這個虛擬主機的訪問所有反代至服務名稱爲myapp端口爲80的pod上;
應用配置清單
[root@master01 manifests]# kubectl apply -f ingress-myapp.yaml Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress ingress.extensions/ingress-myapp created [root@master01 manifests]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-myapp <none> www.myapp.com 80 29s [root@master01 manifests]#
查看ingress資源的詳細信息
[root@master01 manifests]# kubectl describe ingress ingress-myapp Name: ingress-myapp Namespace: default Address: Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>) Rules: Host Path Backends ---- ---- -------- www.myapp.com / myapp:80 (10.244.2.98:80,10.244.4.20:80) Annotations: kubernetes.io/ingress.class: nginx Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 81s nginx-ingress-controller Ingress default/ingress-myapp [root@master01 manifests]#
提示:能夠看到對應知足service名稱爲myapp而且其端口爲80的pod有兩個;
進入ingress controller pod裏,看看對應配置文件是否有www.myapp.com的配置?
[root@master01 manifests]# kubectl get pods -n ingress-nginx NAME READY STATUS RESTARTS AGE nginx-ingress-controller-5466cb8999-4lsjc 1/1 Running 0 78m [root@master01 manifests]# kubectl exec -it -n ingress-nginx pod/nginx-ingress-controller-5466cb8999-4lsjc -- /bin/sh /etc/nginx $ cd /etc/nginx/ /etc/nginx $ ls fastcgi.conf koi-utf modsecurity owasp-modsecurity-crs uwsgi_params.default fastcgi.conf.default koi-win modules scgi_params win-utf fastcgi_params lua nginx.conf scgi_params.default fastcgi_params.default mime.types nginx.conf.default template geoip mime.types.default opentracing.json uwsgi_params /etc/nginx $ grep "www.myapp.com" nginx.conf ## start server www.myapp.com server_name www.myapp.com ; ## end server www.myapp.com /etc/nginx $
提示:能夠看到在對應ingress-nginx 控制器pod中可以搜索到www.myapp.com的配置;說明咱們定義的ingress資源已經被ingress-nginx controller 捕獲;
用瀏覽器訪問www.myapp.com看看是否可以訪問到內容?
提示:使用www.myapp.com訪問,須要確保對應域名可以正常解析到k8s集羣任意一節點上;能夠看到訪問www.myapp.com:30080可以訪問到對應pod內容;
刪除ingress代理規則
[root@master01 manifests]# kubectl delete -f ingress-myapp.yaml Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress ingress.extensions "ingress-myapp" deleted [root@master01 manifests]# kubectl get ingress No resources found in default namespace. [root@master01 manifests]#
示例:配置基於url路徑進行流量分發
[root@master01 manifests]# cat ingress-myapp1.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-myapp namespace: default annotations: kubernetes.io/ingress.class: "nginx" ingress.kubernetes.io/rewrite-target: / spec: rules: - host: www.myapp.com http: paths: - path: /bbs backend: serviceName: myapp servicePort: 80 - path: /blog backend: serviceName: myapp servicePort: 80 [root@master01 manifests]#
提示:以上配置表示把www.myapp.com/bbs反代到service名稱爲myapp而且端口爲80的pod上;把www.myapp.com/blog反代到ervice名稱爲myapp而且端口爲80的pod上;我這裏是由於k8s上只有這一種應用,生成環境中按照對應的業務邏輯來反代對應url到對應pod上便可;
應用配置清單
[root@master01 manifests]# kubectl apply -f ingress-myapp1.yaml Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress ingress.extensions/ingress-myapp created [root@master01 manifests]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-myapp <none> www.myapp.com 80 5s [root@master01 manifests]# kubectl describe ingress ingress-myapp Name: ingress-myapp Namespace: default Address: Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>) Rules: Host Path Backends ---- ---- -------- www.myapp.com /bbs myapp:80 (10.244.2.98:80,10.244.4.20:80) /blog myapp:80 (10.244.2.98:80,10.244.4.20:80) Annotations: ingress.kubernetes.io/rewrite-target: / kubernetes.io/ingress.class: nginx Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 30s nginx-ingress-controller Ingress default/ingress-myapp [root@master01 manifests]#
提示:能夠看到對應ingress上就有兩個url分別指向後端service名稱爲myapp端口爲80的pod上;
訪問對應url,看看是否訪問到內容?
提示:這裏訪問不到內容的緣由是對應pod內部並無對應url的頁面;
進入ingress controller pod內部,查看是否有對應配置?
提示:能夠看到對應在ingress中定義的配置,都轉爲對應該ingress controller pod中的配置,說明咱們定義基於url分發流量的ingress沒有問題;
示例:定義ingress規則基於主機名稱的虛擬主機
[root@master01 manifests]# cat ingress-myapp2.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-myapp namespace: default annotations: kubernetes.io/ingress.class: "nginx" ingress.kubernetes.io/rewrite-target: / spec: rules: - host: www.myapp.com http: paths: - path: backend: serviceName: myapp servicePort: 80 - host: blog.myapp.com http: paths: - path: backend: serviceName: myapp servicePort: 80 [root@master01 manifests]#
提示:以上配置表示把www.myapp.com這個虛擬主機名稱的訪問流量分發至service名稱爲myapp端口爲80的pod上;把blog.myapp.com的流量分發至至service名稱爲myapp端口爲80的pod上;生成環境按照對應的service名稱來分發便可;
應用配置清單
[root@master01 manifests]# kubectl apply -f ingress-myapp2.yaml Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress ingress.extensions/ingress-myapp created [root@master01 manifests]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-myapp <none> www.myapp.com,blog.myapp.com 80 16s [root@master01 manifests]# kubectl describe ingress ingress-myapp Name: ingress-myapp Namespace: default Address: Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>) Rules: Host Path Backends ---- ---- -------- www.myapp.com myapp:80 (10.244.2.98:80,10.244.4.20:80) blog.myapp.com myapp:80 (10.244.2.98:80,10.244.4.20:80) Annotations: ingress.kubernetes.io/rewrite-target: / kubernetes.io/ingress.class: nginx Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 32s nginx-ingress-controller Ingress default/ingress-myapp [root@master01 manifests]#
驗證配置信息
訪問對應虛擬主機,看看是否可以訪問對應pod?
提示:能夠看到兩個虛擬主機名稱均可以正常訪問到,對應也作了調度;
示例:建立tls類型的ingress資源
建立證書
[root@master01 manifests]# openssl genrsa -out tls.key 2048 Generating RSA private key, 2048 bit long modulus .........................................+++ ........+++ e is 65537 (0x10001) [root@master01 manifests]# openssl req -x509 -key tls.key -out tls.crt -subj /C=CN/ST=SiChuan/L=GuangYuan/O=Test/CN=www.myapp.com -days 3650 [root@master01 manifests]#
提示:以上兩條命令建立了一個名爲tls.key的私鑰和一個自簽名證書,其名爲tls.crt;
建立Secret資源
[root@master01 manifests]# kubectl create secret tls www-myapp-com-ingress-secret --cert=./tls.crt --key=./tls.key secret/www-myapp-com-ingress-secret created [root@master01 manifests]# kubectl get secret NAME TYPE DATA AGE default-token-xvd4c kubernetes.io/service-account-token 3 13d www-myapp-com-ingress-secret kubernetes.io/tls 2 21s [root@master01 manifests]#
提示:在ingress控制器上配置https主機時,不能直接使用私鑰和證書文件,而是須要使用secret資源對象來傳遞相關數據;
定義tls類型ingress資源清單
[root@master01 manifests]# cat www-myapp-com-ingress-secret.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-myapp-tls namespace: default annotations: kubernetes.io/ingress.class: "nginx" spec: tls: - hosts: - www.myapp.com secretName: www-myapp-com-ingress-secret rules: - host: www.myapp.com http: paths: - path: / backend: serviceName: myapp servicePort: 80 [root@master01 manifests]#
提示:定義tls類型ingress資源清單,須要在spec字段下用tls字段來指定對應主機名稱,以及secret資源對象的名稱;
應用資源清單
[root@master01 manifests]# kubectl apply -f www-myapp-com-ingress-secret.yaml Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress ingress.extensions/ingress-myapp-tls created [root@master01 manifests]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-myapp <none> www.myapp.com,blog.myapp.com 80 31m ingress-myapp-tls <none> www.myapp.com 80, 443 8s [root@master01 manifests]# kubectl describe ingress ingress-myapp-tls Name: ingress-myapp-tls Namespace: default Address: Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>) TLS: www-myapp-com-ingress-secret terminates www.myapp.com Rules: Host Path Backends ---- ---- -------- www.myapp.com / myapp:80 (10.244.2.98:80,10.244.4.20:80) Annotations: kubernetes.io/ingress.class: nginx Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 26s nginx-ingress-controller Ingress default/ingress-myapp-tls [root@master01 manifests]#
驗證:訪問對應虛擬主機名稱,看看對應的https端口是否可以正常訪問到內容?
提示:能夠看到使用https協議訪問對應的30443端口可以正常訪問到對應後端pod提供的內容;