Ingress 控制器

什麼是Ingress

在Kubernetes v1.1中添加的Ingress公開了從集羣外部到集羣內服務的 HTTP和HTTPS路由 。流量路由由Ingress資源上定義的規則控制。

    internet
        |
   [ Ingress ]
   --|-----|--
   [ Services ]

Ingress可以配置爲提供服務外部可訪問的URL,負載平衡流量,終止SSL,並提供基於名稱的虛擬主機。一個入口控制器負責履行入口,通常與負載均衡器,雖然它也可以配置您的邊緣路由器或額外的前端,以幫助處理流量。

Ingress不會暴露任意端口或協議。將除HTTP和HTTPS之外的服務暴露給互聯網通常使用Service.Type = NodePort或 Service.Type = LoadBalancer類型的服務。

對比nodeport方式:

Ingress:

1 支持七層負載代理

2 支持自定義Service訪問策略

3 只支持基於域名的訪問

4 支持Tls

nodport方式需要規劃端口

Ingress官方文檔:

https://github.com/kubernetes/ingress-nginx/blob/master/docs/deploy/index.md

Ingress架構圖

獲取Ingress yaml文件



wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml

修改配置文件

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
###休要修改爲DaemonSet,以前爲deployment
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:
##需要增加
      hostNetwork: true
      # wait up to five minutes for the drain of connections
      terminationGracePeriodSeconds: 300
      serviceAccountName: nginx-ingress-serviceaccount
####需要增加或者修改,匹配node標籤
      nodeSelector:
        isIngress: "true"
      containers:
        - name: nginx-ingress-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.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:
  - min:
##資源使用需要按需修改
      memory: 900Mi
      cpu: 2000m
    type: Container

節點打標籤 

kubectl label node node01 isIngress="true"
kubectl label node node02 isIngress="true"
kubectl label node node03 isIngress="true"

運行Ingress

kubectl create -f mandatory.yaml 

Ingress 規則是通過域名做分發到後面的service,然後通過service轉發到真是pod。

 把 service  deployment  ingress 規則 寫在一個配置文件中


將deployment service ingress規則寫入到一個配置文件中

[root@master-1 ingress]# cat nginx-deploy-service-ingress.yaml 
#定義nginx deployment的service
apiVersion: v1
kind: Service
metadata: 
  name: nginx-service
  labels:
    app: nginx
spec:
  ports:
  - name: http
    port: 8080
    targetPort: 80
  selector:
    app: nginx

---
#定義nginx的deployment
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
      metadata:
        labels:
          app: nginx
      spec:
        containers:
        - name: nginx
          image: nginx:1.10
          ports:
          - containerPort: 80
---
#定義ingress規則關聯nginx service將規則寫入到ingress 控制器
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress-test
  annotations:
    kuberbetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-service
          servicePort: 8080


kubectl apply -f nginx-deploy-service-ingress.yaml
查看創建ingress控制器
# kubectl get pods -n ingress-nginx
NAME                                        READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-76f9fddcf8-sfqhc   1/1     Running   0          104s

查看爲deployment 創建的service
# kubectl get svc 
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP    3d2h
nginx-service   ClusterIP   10.103.204.39   <none>        8080/TCP   91s

查看爲service創建的ingress
# kubectl get ingress
NAME                 HOSTS         ADDRESS   PORTS   AGE
nginx-ingress-test   foo.bar.com             80      62s

查看爲service創建的ingress的詳細描述
# kubectl describe  ingress nginx-ingress-test
Name:             nginx-ingress-test
Namespace:        default
Address:          
Default backend:  default-http-backend:80 (<none>)
Rules:
  Host         Path  Backends
  ----         ----  --------
  foo.bar.com  
               /   nginx-service:8080 (10.244.1.3:80,10.244.2.3:80,10.244.2.4:80)
Annotations:
  kubectl.kubernetes.io/last-applied-configuration:  {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kuberbetes.io/ingress.class":"nginx"},"name":"nginx-ingress-test","namespace":"default"},"spec":{"rules":[{"host":"foo.bar.com","http":{"paths":[{"backend":{"serviceName":"nginx-service","servicePort":8080},"path":"/"}]}}]}}

  kuberbetes.io/ingress.class:  nginx
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  CREATE  106s  nginx-ingress-controller  Ingress default/nginx-ingress-test


[root@master-1 ingress]# kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
net-test-5764c456cb-kgjbg           1/1     Running   72         3d
net-test-5764c456cb-pjx4v           1/1     Running   72         3d
nginx-deployment-5694557fbc-kn7wv   1/1     Running   0          2m51s
nginx-deployment-5694557fbc-ljpf8   1/1     Running   0          2m51s
nginx-deployment-5694557fbc-t65qm   1/1     Running   0          2m51s

利用exec 命令將server1 server2 server3 分別echo 三個pod 的/usr/share/html/index.html中


查看爲service創建的ingress controller所在節點

# kubectl get pod -o wide -n ingress-nginx
NAME                                        READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
nginx-ingress-controller-76f9fddcf8-sfqhc   1/1     Running   0          28m   10.10.25.151   node2   <none>           <none>

需要通過域名訪問要綁定host

10.10.25.151 foo.bar.com

訪問測試:

此時說明已經負載到後端的pod上面

創建https ingress 規則

需要在相關網站生成相關證書或者製作自簽證書 但是是不受瀏覽器信任

使用kubectl進行創建,然後在ingress規則中指定


創建測試☞簽證書可能不受瀏覽器信任
創建key
openssl genrsa -out tls.key 2048
創建crt
openssl req -new -x509 -key tls.key -out tls.csr -subj /C=CN/ST=Beijing/O=DevOps/CN=hello.foo.com
創建secret 
kubectl create secret tls sslexample-foo-com --cert=tls.crt --key=tls.key
查看
kubectl get secret

Https Ingress規則

cat nginx-https-ingress
#定義nginx deployment的service
apiVersion: v1
kind: Service
metadata: 
  name: nginx-service-https
  labels:
    app: nginx-https
spec:
  ports:
  - name: http
    port: 8080
    targetPort: 80
  - name: https
    port: 8443
    targetPort: 443
  selector:
    app: nginx-https

---
#定義nginx的deployment
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: nginx-deployment-https
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-https
  template:
      metadata:
        labels:
          app: nginx-https
      spec:
        containers:
        - name: nginx
          image: nginx:1.10
          ports:
          - name: http
            containerPort: 80
          - name: https
            containerPort: 443
---
#定義ingress規則關聯nginx service將規則寫入到ingress 控制器
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress-test-https
  annotations:
    kuberbetes.io/ingress.class: "nginx"
spec:
  tls:
  - hosts:
    - hello.foo.com
    secretName: sslexample-foo-com
  rules:
  - host: hello.foo.com 
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-service-https
          servicePort: 8080


kubectl apply -f nginx-https-ingress

同樣的更改pod的index.html 文件 分別echo  https-server    https-server2  https-server3

查看創建的相關信息

需要通過域名訪問要綁定host

10.10.25.151 hello.foo.com
瀏覽器訪問 是不安全的,因爲直簽證書不受瀏覽器信任
https://hello.foo.com:443

查看證書頒發者 如下說明是我們做的自簽證書

注意:如果配置文件裏面匹配的證書文件錯誤,k8s會默認頒發一個自簽證書。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章