kubectl config set-context $(kubectl config current-context) --namespace=<my-namespace>nginx-deployment.yaml with the following contentapiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
anotherLabel: example
spec:
replicas: 1
selector:
matchLabels: # these labels are used by a Service (load balancer) to find a matching pod
app: nginx
anotherLabel: example
template:
metadata:
labels:
app: nginx
anotherLabel: example
spec:
containers:
- name: nginx
image: nginxinc/nginx-unprivileged:1.29-alpine-perl
ports:
- containerPort: 8080 #The unpriviliged nginx listens on port 8080 instead of 80
resources:
requests: # << requests are the guaranteed lower-bound
cpu: 100m
memory: 100Mi
limits: # << limits are the not-guaranteed upper-bound
cpu: 150m
memory: 200Mi
kubectl apply -f nginx-deployment.yamlkubectl get podskubectl logs nginx-deployment-<random>
my-amazing-app.com --> 1.2.3.4nginx-deployment.yaml---
# deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
anotherLabel: example
spec:
replicas: 1
selector:
matchLabels: # these labels are used by a Service (load balancer) to find a matching pod
app: nginx
anotherLabel: example
template:
metadata:
labels:
app: nginx
anotherLabel: example
spec:
containers:
- name: nginx
image: nginxinc/nginx-unprivileged:1.29-alpine-perl
ports:
- containerPort: 8080 #The unpriviliged nginx listens on port 8080 instead of 80
resources:
requests: # << requests are the guaranteed lower-bound for resource allocation
cpu: 100m
memory: 100Mi
limits: # << limits are the not-guaranteed upper-bound
cpu: 150m
memory: 200Mi
volumeMounts: #volumeMounts are used to mount a (defined volume underneath) in a container in a pod. The container sees it as a file
- name: nginx-html-in-configmap
mountPath: /usr/share/nginx/html
volumes: #a volume is a reference to any kind of storage provider (interface). It can be a file server, block storage, or even secrets and configmaps of k8s where data resides.
- name: nginx-html-in-configmap
configMap:
name: nginx-html-in-configmap
---
# ConfigMap containing a content for the index.html page which will be mounted to the container/pod
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-html-in-configmap
data:
#index.html is the key for the key-val. We put a simple html page in a configMap, and then mount this to the pod/container
index.html: |
<html>
<body>
<h1>Example application</h1>
<p>An example application used to show how an application is deployed on Softwaredam's k8s.</p>
</body>
</html>
---
# service to make sure the nginx pod is reachable in the cluster
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector: # a selector uses labels to find the pods with these labels
app: nginx
anotherLabel: example
ports:
- protocol: TCP
port: 8080 #we bind port 8080 to the pod/container port which is also 8080
targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-redirect-ingress-to-https
annotations:
#instructs Traefik to listen on http (80)
traefik.ingress.kubernetes.io/router.entrypoints: web
#test-force-https@kubernetescrd refers to a middleware in the test namespace which is called force-https.
traefik.ingress.kubernetes.io/router.middlewares: test-force-https@kubernetescrd
spec:
ingressClassName: traefik
rules:
- host: my-amazing-app.com # << change to your domain
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 8080
---
# ingress to make the application externally available on internet
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
#we use cert-manager to issue a let's encrypt certificate
cert-manager.io/cluster-issuer: lets-encrypt
#instructs Traefik to use https/443 (websecure)
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
#Useful if large objects are communicated over the line This referst to a middleware called big-body in test namespace
# traefik.ingress.kubernetes.io/router.middlewares: test-big-body@kubernetescrd
spec:
ingressClassName: traefik
tls:
- hosts:
- my-amazing-app.com # << change to your domain
secretName: nginx-ingress-tls
rules:
- host: my-amazing-app.com # << change to your domain
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 8080
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: big-body
spec:
buffering:
#20m body
maxRequestBodyBytes: 20971520
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: force-https
spec:
redirectScheme:
scheme: https
permanent: true
---
kubectl apply -f nginx-deployment.yamlkubectl get deployments
kubectl get pods #make
kubectl get services
kubectl get ingress
kubectl get certificates
Any data produced and saved in a container pod is ephemeral and will be wiped out when the pod restarts. To persist and keep your data, a PersistentVolumeClaim (PVC) can be created and mounted under the (nginx) app.
nginx-pvc.yamlapiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
kubectl apply -f nginx-pvc.yamlnginx-deployment.yaml.:...
volumeMounts:
- name: nginx-html-in-configmap #existing mount to configmap
mountPath: /usr/share/nginx/html
- name: nginx-pvc #new mount
mountPath: /usr/share/nginx/html/storage
volumes:
- name: nginx-html-in-configmap #existing mount
configMap:
name: nginx-html-in-configmap
- name: nginx-pvc #new mount to pvc
persistentVolumeClaim:
claimName: nginx-pvc
...
kubectl apply -f nginx-deployment.yaml