Linux
How to setup Nginx ingress controller in AWS EKS Kubernetes Cluster
In this tutorial, we are going to discuss how to set up the Nginx ingress controller in AWS EKS Kubernetes cluster using One elastic load balancer.
I,m assuming you are already set up the AWS EKS Kubernetes cluster and you can access the cluster using kubectl command.
Firstly, please download the below file and rename the file “kubernetes-ingress.txt” to “kubernetes-ingress.yaml”
this is the content of above file. No need to change anything.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
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.26.1 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 -> 33 runAsUser: 33 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace ports: - name: http containerPort: 80 - name: https containerPort: 443 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 --- |
You can apply it to Kubernetes using bellow command.
1 |
kubectl apply -f kubernetes-ingress.yaml |
Create an SSL certificate in the AWS certificate manager.
Now you have to create an SSL certificate for your domain using AWS certificate manager.
you can create a new FREE SSL certificate which provides by AWS or you can use the existing one.
Please follow this AWS documentation to create the certificate or add the existing one to the AWS certificate manager.
After you created the certificate, go to the certificate details in the AWS certificate manager, and copy the ARN.
Please check the below screenshot. you will get an idea.
The Yellow part is the ARN. we need to add that ARN to the below file. I will explain that.
Create Nginx Ingress Service
Firstly, please download below file and rename the file “nginx-ingress-service.txt” to “nginx-ingress-service.yaml”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
kind: Service apiVersion: v1 metadata: name: ingress-nginx namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx annotations: # replace with the correct value of the generated certificate in the AWS console service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:us-east-1:475895322345:certificate/bf4d782b9-9dbc-4906-9e56-b4c7i7icead4b3" # the backend instances are HTTP service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http" # Map port 443 service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" # Ensure the ELB idle timeout is less than nginx keep-alive timeout. By default, # NGINX keep-alive is set to 75s. If using WebSockets, the value will need to be # increased to '3600' to avoid any potential issues. service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "75" spec: type: LoadBalancer selector: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx ports: - name: http port: 80 targetPort: http - name: https port: 443 targetPort: http |
you can see this part in the above file
1 |
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:us-east-1:475895322345:certificate/bf4d782b9-9dbc-4906-9e56-b4c7i7icead4b3" |
you have to replace “arn:aws:acm:us-east-1:475895322345:certificate/bf4d782b9-9dbc-4906-9e56-b4c7i7icead4b3
” with your certificate ARN.
save the change and apply that service to the cluster by using bellow command.
1 |
kubectl apply -f nginx-ingress-service.yaml |
Now please download the below file and rename the file “patch-configmap.txt” to “patch-configmap.yaml”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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 data: use-proxy-protocol: "false" use-forwarded-headers: "true" proxy-real-ip-cidr: "0.0.0.0/0" # restrict this to the IP addresses of ELB --- |
NOTE: no need to change this “proxy-real-ip-cidr: “0.0.0.0/0″”. you can change it if you want.
Apply that using the below command.
1 |
kubectl apply -f patch-configmap.yaml |
After that, you can check the Nginx ingress controller pod logs using kubectl logs command in the ingress-nginx namespace.
if everything is ok there will be no errors in the logs.
Now you can go to your AWS console and check the load balancers and you can see the magic happened there. 🙂
Kubernetes created a load balancer automatically there. you can point your domain DNS to ARN of that load balancer.
Ingress resources
Now you can create your ingress resources in any namespace.
The ingress controller which we created automatically points the load balancer to that ingress resource.
no need to touch anything related to the ingress controller now. you can do anything using ingress resources.
Ingress resource is just a file, like attached below.
I will add a sample ingress resource here. you can download it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: sample-ingress annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: subdomain.your-domain-name.com http: paths: - path: / backend: serviceName: your-service servicePort: 80 |
for the host, you can use a subdomain or main domain. it’s not an issue.
you can create multiple ingress resources for multiple subdomains.
Then you can apply it using kubectl apply command.
it will take a few mins to point the load balancer to it.
you can check it by using below command
1 |
kubectl get ing INGRESS-NAME |
if the load balancer pointed properly you can see the load balancer name under the ADDRESS column.
Ok guys this is enough for this tutorial.
I will discuss in the next article about multiple Nginx ingress controllers with multiple domains in one Kubernetes cluster.
If you have any questions, please comment below.
Cheers!!!
-
DevOps55 years ago
Saltstack Tutorial for beginners [2023]
-
DevOps55 years ago
How to build a Docker cron job Container easily [2023]
-
Linux55 years ago
mail Command in Linux/Unix with 10+ Examples [2023]
-
DevOps55 years ago
Docker ADD vs COPY vs VOLUME – [2023]
-
DevOps55 years ago
How to setup Pritunl VPN on AWS to Access Servers
-
Linux55 years ago
Grep Command In Unix/Linux with 25+ Examples [2023]
-
Linux55 years ago
How To setup Django with Postgres, Nginx, and Gunicorn on Ubuntu 20.04
-
Linux55 years ago
Find command in Unix/Linux with 30+ Examples [2023]