All Documents
Current Document

Content is empty

If you don't find the content you expect, please try another search term

Documentation

Create an NGINX Ingress Service

Last updated:2021-05-11 10:41:27

This topic describes how to create an NGINX Ingress Service based on KCE.

Deploy an NGINX Ingress Controller

To use an NGINX Ingress Service in a cluster, you must deploy an NGINX Ingress Controller in the cluster by using the nginx-install.yaml file:

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

Deploy NGINX Ingress Controller 0.30.0 by running the following command:

[root@vm10-0-11-170 ~]# kubectl apply -f nginx-install.yaml

# The following resources will be created in the cluster:
namespace/ingress-nginx created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-role created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
deployment.apps/nginx-ingress-controller created
limitrange/ingress-nginx created

Create a Service of the LoadBalancer type for the NGINX Ingress Controller. The Service will be exposed out of the cluster through SLB. The nginx-ingress-svc.yaml file is as follows:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx
  name: nginx-ingress
spec:
  ports:
  - name: "tcp-80-80"
    port: 80
    protocol: TCP
    targetPort: 80
  - name: "tcp-443-443"
    port: 443
    protocol: TCP
    targetPort: 443
  selector:
    app.kubernetes.io/name: "ingress-nginx"
    app.kubernetes.io/part-of: "ingress-nginx"
  type: LoadBalancer

Create a Service and obtain the IP address of the Service.

[root@vm10-0-11-170 ~]# kubectl apply -f nginx-ingress-svc.yaml -n ingress-nginx
service/nginx-ingress created

[root@vm10-0-11-170 ~]# kubectl get svc -n ingress-nginx
NAME            TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                      AGE
nginx-ingress   LoadBalancer   10.254.137.163   120.131.xx.xx   80:30563/TCP,443:30681/TCP   17s

Ingress traffic is routed to the NGINX Ingress Controller in the cluster through the public IP address 120.131.xx.xx and then routed and forwarded based on the Ingress policy.

[root@vm10-0-11-170 ~]# kubectl get all -n ingress-nginx
NAME                                            READY   STATUS    RESTARTS   AGE
pod/nginx-ingress-controller-7fcf8df75d-pqbgd   1/1     Running   0          132m

NAME                    TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                      AGE
service/nginx-ingress   LoadBalancer   10.254.137.163   120.131.xx.xx   80:30563/TCP,443:30681/TCP   2m52s

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-ingress-controller   1/1     1            1           149m

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-ingress-controller-7fcf8df75d   1         1         1       149m

Create test applications

Two applications are created for testing.

The hello-world.yaml file is as follows:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-world
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
      - name: hello-world
        image: hub.kce.ksyun.com/kingsoft/hello-world:latest
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: hello-world
  name: hello-world-svc
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: hello-world
  type: ClusterIP

The hello-k8s.yaml file is as follows:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-k8s
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-k8s
  template:
    metadata:
      labels:
        app: hello-k8s
    spec:
      containers:
      - name: hello-k8s
        image: hub.kce.ksyun.com/kingsoft/hello-k8s:latest
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: hello-k8s
  name: hello-k8s-svc
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: hello-k8s
  type: ClusterIP

Create the corresponding Deployment and Service.

[root@vm10-0-33-13 hello]# kubectl create -f hello-k8s.yaml 
deployment.extensions/hello-k8s created
service/hello-k8s-svc created

[root@vm10-0-33-13 hello]# kubectl create -f hello-world.yaml 
deployment.extensions/hello-world created
service/hello-world-svc created

[root@vm10-0-33-13 hello]# kubectl get deploy
NAME          DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-k8s     1         1         1            1           5m2s
hello-world   1         1         1            1           4m50s

[root@vm10-0-33-13 hello]# kubectl get svc
NAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
hello-k8s-svc     ClusterIP   10.254.131.29   <none>        8080/TCP   5m31s
hello-world-svc   ClusterIP   10.254.244.96   <none>        80/TCP     5m19s
kubernetes        ClusterIP   10.254.0.1      <none>        443/TCP    52d

Ingress configuration policy

An Ingress policy can be configured based on different distribution methods to achieve flexible distribution. The following section describes common Ingress forwarding policies.

Redirect different URLs of the same domain to different Services

Typically, this configuration is used when a website uses different URLs to provide different Services.

Access configuration:

The ingress.yaml file is as follows:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-test
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: my.nginx.test
    http:
      paths:
      - path: /hello-world
        backend:
          serviceName: hello-world-svc
          servicePort: 80
      - path: /hello-k8s
        backend:
          serviceName: hello-k8s-svc
          servicePort: 8080

Create an Ingress policy.

[root@vm10-0-11-170 ~]# kubectl apply -f ingress.yaml
ingress.extensions/nginx-test created

[root@vm10-0-11-170 ~]# kubectl get ingress
NAME         HOSTS           ADDRESS   PORTS   AGE
nginx-test   my.nginx.test             80      15s

Notes:

  • The domain name my.nginx.test is resolved to the IP address of SLB.
  • The annotation kubernetes.io/ingress.class: nginx specifies the mapping between the Ingress policy and the NGINX Ingress Controller, indicating that the Ingress policy is implemented by the NGINX Ingress Controller.

The following figures show access verification in a browser.

image20210122105056948.png

image20210122105125973.png

Redirect different domains to different Services

Typically, this configuration is used when a website uses different domains or virtual hosts to provide different Services.

Access configuration:

The ingress2.yaml file is as follows:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-test-2
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: nginx.hello.k8s
    http:
      paths:
      - path: /  
        backend:
          serviceName: hello-k8s-svc
          servicePort: 8080
  - host: nginx.hello.world
    http:
      paths:
      - path: /  
        backend:
          serviceName: hello-world-svc
          servicePort: 80

Create an Ingress policy.

[root@vm10-0-11-170 ~]# kubectl apply -f ingress2.yaml
ingress.extensions/nginx-test-2 created

[root@vm10-0-11-170 ~]# kubectl get ingress
NAME           HOSTS                               ADDRESS   PORTS   AGE
nginx-test-2   nginx.hello.k8s,nginx.hello.world             80      19s

The following figures show access verification in a browser.

image20210122104836113.png

image20210122104750314.png

HTTPS-based access

When a TLS certificate is configured for an Ingress, Services are exposed through HTTPS.

Prepare a certificate

A Kingsoft Cloud-signed certificate is used in this example. The following commands can be used to quickly create a certificate:

[root@vm10-0-11-170 ~]# openssl req -newkey rsa:2048 -nodes -keyout tls.key -x509 -days 365 -out tls.crt
Generating a 2048 bit RSA private key
...............+++
.............................+++
writing new private key to 'tls.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Beijing
Locality Name (eg, city) [Default City]:Beijing
Organization Name (eg, company) [Default Company Ltd]:Kingsoft
Organizational Unit Name (eg, section) []:Ksyun
Common Name (eg, your name or your server's hostname) []:nginx.hello.k8s    # The domain name to which the certificate is applied.
Email Address []:ksyun@kingsoft.com

The certificate tls.crt and key tls.key are created in the current path.

Create a Secret

A Secret of the kubernetes.io/tls type is created based on the certificate and key.

[root@vm10-0-11-170 ~]# kubectl create secret tls secret-https --key tls.key --cert tls.crt
secret/secret-https created
Create an Ingress policy

HTTP-based access in the preceding example is upgraded to enable access to nginx.hello.k8s through HTTPS. The ingress-https.yaml file is as follows:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-test-2
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "true"    # Enable the redirect feature. 
spec:
  rules:
  - host: nginx.hello.k8s
    http:
      paths:
      - path: /  
        backend:
          serviceName: hello-k8s-svc
          servicePort: 8080
  tls:
  - hosts:
    - nginx.hello.k8s
    secretName: secret-https

The following figure shows access verification in a browser.

image20210122144835757.png

For more information about the NGINX Ingress Controller, see NGINX Ingress Controller.

On this page
Pure ModeNormal Mode

Pure Mode

Click to preview the document content in full screen
Feedback