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会默认颁发一个自签证书。

 

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