nginx ingress controller

参考链接:https://www.nginx.com/products/nginx/kubernetes-ingress-controller

一、nginx ingress controller部署

项目地址:https://github.com/kubernetes/ingress-nginx 安装文档地址: https://github.com/kubernetes/ingress-nginx/blob/nginx-0.30.0/docs/deploy/index.md

1.下载并修改配置文件

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:
      - "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:
      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.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
            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: 90Mi
      cpu: 100m
    type: Container

2.修改

210         prometheus.io/port: "10254"
211         prometheus.io/scrape: "true"
212     spec:
213       hostNetwork: true  		# 需要添加这句,使用主机网络
214       serviceAccountName: nginx-ingress-serviceaccount

3.应用配置文件

kubectl apply -f mandatory.yaml

验证部署结果,注意镜像较大,可提前下载至集群node节点中。

kubectl get pods -n ingress-nginx

hostNetwork: true的补充说明:

  • 此参数为true表示pod使用主机网络,也就是pod的IP就是node的IP
  • 但同一个deployment里的pod副本数如果为2或越过2,在同一个node上只能启一个pod *

vim deployment-nginx.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx
spec:
  replicas: 2							# 副本数为2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      hostNetwork: true					# 加上这一句
      containers:
      - name: c1
        image: nginx:1.15-alpine

kubectl apply -f deployment-nginx.yaml kubectl get pods -o wide

可以看到pod-IP就是node-IP,而且只能启动成功一个副本

二、ingress-http案例

1.创建deployment

vim nginx.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: ingress-nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: c1
        image: nginx:1.15-alpine
        imagePullPolicy: IfNotPresent

2.应用YAML

kubectl create namespace ingress-nginx kubectl apply -f nginx.yml

3.验证pod

kubectl get pods -n ingress-nginx

4.创建service

vim nginx-service.yml

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: ingress-nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx

5.应用YAML

kubectl apply -f nginx-service.yml

6.验证service

kubectl get svc -n ingress-nginx

7.创建ingress

vim ingress-nginx.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-nginx                    #自定义ingress名称
  namespace: ingress-nginx
spec:
  rules:
  - host: www.daniel.com                   # 自定义域名
    http:
      paths:
      - backend:
          serviceName: nginx-service     # 对应上面创建的service名称
          servicePort: 80

8.应用YAML

kubectl apply -f ingress-nginx.yaml

9.验证ingress

kubectl get ingress -n ingress-nginx

描述查看ingress信息

kubectl describe ingress ingress-nginx -n ingress-nginx


nginx-service:80 (172.20.104.48:80,172.20.166.190:80) 与下面查询的两个pod的IP对应

kubectl get pods -o wide -n ingress-nginx

可以看到两个pod的IP正好对应ingress域名对应的IP

确认nginx-ingress-controller的podIP为192.168.154.139

模拟客户端访问

1, 确认nginx-ingress-controller的podIP,

下面命令查询的结果为192.168.154.139 kubectl get pods -o wide -n ingress-nginx |grep ingress

2, 在集群之外任一主机中(我这里为hostos)添加上述域名与IP地址解析(模拟公网DNS)

[root@hostos ~]# vim /etc/hosts

192.168.154.139 www.daniel.com

3, 准备pod内容器运行的web主页

kubectl get pods -n ingress-nginx

 kubectl exec -it nginx-79654d7b8-6vn4v -n ingress-nginx  -- /bin/sh
/ # echo "ingress web1" > /usr/share/nginx/html/index.html
/ # exit

kubectl exec -it nginx-79654d7b8-vtqrl -n ingress-nginx  -- /bin/sh
/ # echo "ingress web2" > /usr/share/nginx/html/index.html
/ # exit

4, 访问及结果展示

[root@hostos ~]# curl www.daniel.com

三、 ingress-https案例

1.创建自签证书

mkdir ingress-https cd ingress-https/ openssl genrsa -out nginx.key 2048 openssl req -new -x509 -key nginx.key -out nginx.pem -days 365 ls

2.将证书创建成secret

kubectl create secret tls nginx-tls-secret --cert=nginx.pem --key=nginx.key -n ingress-nginx kubectl get secrets -n ingress-nginx |grep nginx-tls-secret

3.编排YAML并创建

vim ingress-https.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx2
  namespace: ingress-nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx2
  template:
    metadata:
      labels:
        app: nginx2
    spec:
      containers:
      - name: c1
        image: nginx:1.15-alpine
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80
        - name: https
          containerPort: 443
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service2
  namespace: ingress-nginx
  labels:
    app: nginx2
spec:
  ports:
  - name: http
    port: 80
    targetPort: 80
  - name: https
    port: 443
    targetPort: 443
  selector:
    app: nginx2
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-nginx2
  namespace: ingress-nginx
spec:
  tls:
  - hosts:
    - www.daniel2.com							  # 域名
    secretName: nginx-tls-secret				  # 调用前面创建的secret
  rules:
  - host: www.daniel2.com						  # 域名
    http:
      paths:
      - backend:
          serviceName: nginx-service2			  # 对应服务名
          servicePort: 80

kubectl apply -f ingress-https.yml

4.验证

kubectl get ingress -n ingress-nginx

5.模拟客户端访问

[root@hostos ~]# vim /etc/hosts

192.168.154.139 www.daniel2.com 添加这行模拟DNS

[root@hostos ~]# firefox https://www.daniel2.com &

四、ingress+nodeport服务

vim ingress-nodeport.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx3
  namespace: ingress-nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx3
  template:
    metadata:
      labels:
        app: nginx3
    spec:
      containers:
      - name: c1
        image: nginx:1.15-alpine
        imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service3
  namespace: ingress-nginx
  labels:
    app: nginx3
spec:
  type: NodePort						# NodePort类型服务
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx3
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-nginx3
  namespace: ingress-nginx
spec:
  rules:
  - host: www.daniel3.com
    http:
      paths:
      - backend:
          serviceName: nginx-service3
          servicePort: 80

kubectl apply -f ingress-nodeport.yml kubectl get svc -n ingress-nginx

nginx-service3是nodeport类型

[root@hostos ~]# vim /etc/hosts

192.168.154.139 www.daniel3.com 添加这行模拟DNS

[root@hostos ~]# curl www.daniel3.com