Kubernetes Concepts

Pod is the smallest units that you can create and manage in Kubernetes.

Pods are:

  • Group of one or more co-located containers
  • Containers in a pod shares network and storage
  • Defined lifecycle, supervised by kubelet

Common usage is to have a pod that run a single container.

If you want to scale your application horizontally, you should use multiple Pods, one for each instance. In Kubernetes, you can use Deployment to define the number of replicas you want.

apiVersion: v1

kind: Pod metadata: name: <my-pod> namespace: <my-namespace-name> labels: name: nginx-pod spec: containers: - name: nginx image: dockerfactory-playground.tech.orange/library/nginx:latest resources: requests: memory: "50Mi" cpu: "1m" limits : memory: "100Mi" cpu: "1"


Deployment provides declarative updates for pods.

Deployments can :

  • Trigger updates thanks to pod template changes (not, e.g., scaling)
  • Enable fine-grained control over rollout and rollback
  • Support pause/resume and history
apiVersion: apps/v1 kind: Deployment metadata: name: <my-deployment-name> namespace: <my-namespace-name> labels: app: nginx-deploy spec: replicas: 3 selector: matchLabels: app: nginx-pod template: metadata: labels: app: nginx-pod spec: containers: - name: nginx image: dockerfactory-playground.tech.orange/library/nginx:latest resources: requests: memory: "50Mi" cpu: "1m" limits : memory: "100Mi" cpu: "1"
The .spec.replicas field define the number of pods you want to deploy at the same time.
The .spec.selector field define how the deployment finds which pods to manage. In this case, you select a label that is defined in the pod template app: nginx

Now you have your deployment template, you can apply it on the cluster to create your pods :$ kubectl apply -f my_deployment.yaml
You can run the following command to check the status of your Deployment$ kubectl get deployments -n <my-namespace> NAME READY UP-TO-DATE AVAILABLE AGE mydeployment 0/3 3 0 10sWhen all the pods will be started, the READY field will be 3/3

Service is an abstraction which defines a logical set of Pods and a policy by which to access them.

Services can :

  • Target a set of pods determined by a selector
  • Provide Pods abstraction with a stable VIP
  • Load-balance across pods
  • Be resolved automaticaly by other pods thanks to the service discovery (DNS add-on)
apiVersion: v1 kind: Service metadata: name: <my-service-name> namespace: <my-namespace> labels: run: nginx-service spec: selector: app: nginx-pod ports: - port: 80 targetPort: 80 protocol: TCP

The .spec.selector has to match with the label define on the pods specification.

Now you have your service template, you can apply it on the CaaS-CNP cluster to create your service :

$ kubectl apply -f my_service.yaml


You can run the following command to check the status of your Deployment

$ kubectl get svc -n <my-namespace> NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE myservice ClusterIP 10.254.46.67 <none> 80/TCP 7s $ kubectl describe svc myservice -n <my-namespace> Name: myservice Namespace: <my-namespace> Labels: run=nginx-service Annotations: <none> Selector: app=nginx Type: ClusterIP IP Families: <none> IP: 10.254.46.67 IPs: 10.254.46.67 Port: <unset> 80/TCP TargetPort: 80/TCP Endpoints: 172.12.118.241:80,172.12.215.4:80,172.12.27.50:80 Session Affinity: None Events: <none>

he Endpoints field is the value of internal pods IPs. If this field is empty, the service will not know to which pods redirect the request : verify your selector/label.


Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster with TLS certificats. This need a ingress controller to manage the ingress rules (Nginx, Traefik, Haproxy...)


3 farms of Ingress Controllers are deployed :
- one Nginx for NoProd namespaces
- one Nginx for Prod namespaces
- one Traefik for NoProd/Prod namespace


On your template you have to adapt the .metadata.annotations.ingress.class with the categorie of ingress you wand to use.


HTTP

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: <my-ingress-name> namespace: <my-namespace> annotations: ingress.kubernetes.io/rewrite-target: / kubernetes.io/ingress.class: "nginx-noprod" spec: rules: - host: <my-application-name>.<my-namespace>.caas-cnp-apps-noprod.com.intraorange http: paths: - path: / pathType: Prefix backend: service: name: <my-service-name> port: number: 80


The .spec.rules.http.paths.backend.service.name has to match with the service name already defined.

Now you have your ingress template, you can apply it on the CaaS-CNP cluster to create your ingress :$ kubectl apply -f my_ingress.yaml

You can run the following command to check your ingress configuration

$ kubectl describe ing <my-ingress-name> -n <my-namespace> Name: <my-ingress-name> Namespace: <my-namespace> Address: 10.254.149.150 Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>) Rules: Host Path Backends ---- ---- -------- <my-application-name>.<my-namespace>.caas-cnp-apps-noprod.com.xyc / <my-service-name>:80 (172.12.118.241:80,172.12.215.4:80,172.12.27.50:80) Annotations: ingress.kubernetes.io/rewrite-target: / kubernetes.io/ingress.class: nginx-noprod


Your application should be available to the URL http://<my-application-name>.<my-namespace>.caas-cnp-apps-noprod.com.xyc

HTTPS

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: <my-ingress-name> namespace: <my-namespace> annotations: nginx.ingress.kubernetes.io/rewrite-target: "/" nginx.ingress.kubernetes.io/ssl-redirect: "true" kubernetes.io/ingress.class: "nginx-noprod" spec: tls: - hosts: - <my-application-name>.<my-namespace>.caas-cnp-apps-noprod.com.intraorange rules: - host: <my-application-name>.<my-namespace>.caas-cnp-apps-noprod.com.intraorange http: paths: - path: / pathType: Prefix backend: service: name: <my-service-name> port: number: 443

Using Certificates

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: <my-ingress-name> namespace: <my-namespace> annotations: nginx.ingress.kubernetes.io/rewrite-target: "/" nginx.ingress.kubernetes.io/ssl-redirect: "true" kubernetes.io/ingress.class: "nginx-noprod" spec: tls: - hosts: - <my-application-name>.<my-namespace>.caas-cnp-apps-noprod.com.intraorange secretName: <my-certificate>.tls rules: - host: <my-application-name>.<my-namespace>.caas-cnp-apps-noprod.com.intraorange http: paths: - path: / pathType: Prefix backend: service: name: <my-service-name> port: number: 443


Traefik automatically requests endpoint information based on the service provided in the ingress spec. Although Traefik will connect directly to the endpoints (pods), it still checks the service port to see if TLS communication is required.

There are 3 ways to configure Traefik to use HTTPS to communicate with pods:

  1. If the service port defined in the .spec.rules.http.paths.backend.service.port.number is 443 (note that you can still use targetPort to use a different port on your pod).
  2. If the service port defined in the ingress spec has a name that starts with https (such as https-apihttps-web or just https).
  3. If the ingress spec includes the annotation traefik.ingress.kubernetes.io/service.serversscheme: https.

If either of those configuration options exist, then the backend communication protocol is assumed to be TLS, and will connect via TLS automatically.

Comments

Popular posts from this blog

Microservice Pattern: SAGA

Microservice Pattern: Database per service Context

SQL vs NoSQL | Difference between SQL & NoSQL | SQL Vs NoSQL Tutorial | SQL, NoSQL system design