Containers and Kubernetes allow for code portability across on-premise VMs, bare metal or multiple cloud provider environments. Yet, despite this portability promise, developers may include configuration and application definitions that constrain or even eliminate application portability. In this meetup Oleg Chunikhin, CTO at Kublr, described best practices for “configuration as code” in a Kubernetes environment. He demonstrated how a properly constructed containerized app can be deployed to both Amazon and Azure using the Kublr platform, and how Kubernetes objects, such as persistent volumes, ingress rules and services, can be used to abstract from the infrastructure.
3. Reasons for Portability
• Move load quickly (geography, cost, features)
• Lifecycle (dev/test/staging/production)
• Disaster recovery
• Split-tier architecture (application tiers may reside
in different environments)
• Cloud-bursting
4. Best Practices for Portable Applications
12-factor app is your bible–especially verses 2, 3, 4, 6, 7, 12
2. Explicitly declare and isolate dependencies
3. Store configuration in the environment
4. Treat backing services as attached resources
6. Execute the app as one or more stateless processes
7. Export services via port binding
12. Run admin/management tasks as one-off processes
10. Kubernetes to the Rescue
• Extreme ease and flexibility of component configurations and connections
• Configuration templating tools
• Helm
• Abstractions and extensible framework for ingress traffic processing
• Service
• Ingress
• Ingress Controllers
• Abstractions and extensible framework for storage management
• Volumes
• Persistent Volumes
11. Service
External node ports or external load balancer
Kubernetes cluster
Pod A-1
10.0.0.3
Pod A-2
10.0.1.5
Pod B-1
10.0.0.8
SrvB
10.7.0.3
Internal service
SrvA
10.7.0.1
SrvC
10.7.0.5
Ext
Resource
18. Demo Application – Evaluation
WordPress
MySql
Routing SSL TermBalancing
MySql Data emptyDir Shared FS
ephemeral storage
provided by Kubernetes
Accessible from inside the cluster only via HTTP
19. Demo Application – Evaluation – Ingress
AWS
WordPress
MySql MySql Data emptyDir
Ingress Routing
Ingress SSL
Term + LEGO
ELB Balancing
Shared FS
ephemeral storage
provided by Kubernetes
Accessible via HTTPS on ELB with the given host
20. Demo Application – Production – EBS
AWS
WordPress
MySql
Ingress Routing
Ingress SSL
Term + LEGO
ELB Balancing
EBS MySql Data AWS EFS
persistent storage on AWS EBS
allocated by Kubernetes
Accessible via HTTPS on ELB with the given host
21. Demo Application – Production – RDS
AWS
WordPress
AWS RDS MySql
Ingress Routing
Ingress SSL
Term + LEGO
ELB Balancing
AWS EBS AWS EFS
persistent storage on AWS RDS
allocated outside of Kubernetes
Accessible via HTTPS on ELB with the given host
22. Demo Application – Production – Rook/Ceph
Azure
WordPress
MySql
Ingress Routing
Ingress SSL
Term + LEGO
Azure LB
Rook operator and Ceph cluster
MySql Data on Ceph
replica pool Ceph File System
Accessible via HTTPS on Azure LB with the given host
persistent storage on self-hosted
MySql and Ceph
24. Gotchas
• Self-hosted is more difficult to
operate than managed
• Different implementations
have varying functionalities
and QoS
• Performance
• Standards compliance
For example
• AWS EBS is AZ local
• Let’s Encrypt limits certificate
issuance rate
• Managed services may be better
hardware tuned
• Self-hosted services may be
better application tuned
25. Takeaways
• Cloud native Kubernetes applications are
portable, and easy to test, experiment,
and configure
• Portability tools
• Helm configuration templating
• Kubernetes abstractions: PV, PVC,
Ingress, Service etc
• Using self-hosted resources where
managed are not available
• Managed vs self-hosted services
considerations
• Different platforms
• On AWS and Azure
• On Ubuntu and RHEL
• Different ingress options
• With and without reverse-proxy
• With and without SSL
• Different persistence options
• Ephemeral storage
• Managed database
• Managed block storage, self-hosted
database
• Self-hosted cloud native storage
Kublr CTO
Building Kublr – a platform for managing Kubernetes clusters in an enterprise
Let me know if you cannot hear me
Feel free to ask questions as you have them
As they say, good portability is a two way street.
Application should be designed for portability, but technology stack and environments you use should support it too.
We will focus on technology stack and environment, but here is also a brief note on application design.
Messaging is out of scope for the demo
Explain application structure
Show helm package
Explain the demo application structure:
WP Ingress
WP Service
WP Deployment
MS Service
MS Deployment
MS PVC
Describe demo environment
Show clusters
AWS:
https://52.44.251.85/ui
Azure:
https://52.224.67.214/ui
Deploy evaluation on AWS:
helm --kube-context=aws upgrade -i demo demo-wordpress -f values-evaluation.yaml
Show values-evaluation.yaml
Only service inside the cluster
Accessible from inside the cluster or through k8s port forwarding
No persistence, ephemeral storage
1-2m
Start port forwarding:
kubectl --context aws port-forward \
$(kubectl --context aws get pods -l app=demo-demo-wordpress-wordpress -o custom-columns=name:metadata.name --no-headers=true) \
8080:80
Open localhost:8080
Deploy with Ingress and SSL termination
helm --kube-context=aws upgrade -i demo demo-wordpress -f values-evaluation-ingress-ssl-host-aws.yaml
Show values-evaluation-ingress-ssl-host-aws.yaml
Using Ingress with SSL termination and automatic certificate acquisition through Letsencrypt using LEGO
Still no persistence, ephemeral storage
Demo Wordpress access via http://wp.port-aws.demo.kublr.com/
Gets redirected to https://wp.port-aws.demo.kublr.com/ with correct certificate
Deploy AWS with EBS persistence:
helm --kube-context=aws upgrade -i demo demo-wordpress -f values-persistent-ingress-ssl-host-aws.yaml
Show values-persistent-ingress-ssl-host-aws.yaml
Using Ingress with SSL termination and automatic certificate acquisition through Letsencrypt using LEGO
Persistence is based on dynamically allocated EBS
In UI see PV, PVC, and restarted MySql pods
Open http://wp.port-aws.demo.kublr.com/
Error because DB has been recreated
Delete wordpress pod
Open http://wp.port-aws.demo.kublr.com/
Init site
Login
show works
Kill mysql
show that it continues working
3m
Show values-persistent-rds-ingress-ssl-host-aws.yaml
Explain using external RDS on the diagrams and yaml files (no demo)
1m
1. Using Ingress with SSL termination and automatic certificate acquisition through Letsencrypt using LEGO
Persistence is based on dynamically allocated Ceph disk image in a self-hosted Ceph cluster
2. Deploy Rook operator to Azure
kubectl --context=azure apply -f rook/rook-operator.yaml
Check that it is deployed (1 operator, 1 agent per node should be available)
kubectl --context=azure get -n rook-system pods
3. Deploy cluster and tools
# cluster
kubectl --context=azure apply -f rook/rook-cluster.yaml
# check deployed (1 api, 1 mgr, 3 mon, 1 osd per node)
kubectl --context=azure get -n rook pods
# tools
kubectl --context=azure apply -f rook/rook-tools.yaml
# test cluster and tools
kubectl --context=azure exec -n rook rook-tools -- rookctl status
4. Prepare Ceph replica pool and storage class
kubectl --context=azure apply -f rook/rook-storageclass.yaml
# check pools (replicapool)
kubectl --context=azure exec -n rook rook-tools -- ceph osd pool ls detail
5. Deploy demo application with Ceph persistence to AWS
helm --kube-context=azure upgrade -i demo demo-wordpress -f values-persistent-ingress-ssl-host-azure.yaml
5m - switch to the next slide for some time (3-5m)
6. Check that the application is working
Open http://wp.port-azure.demo.kublr.com/
Review objects in K8S UI - app, Ceph cluster, and Rook Ceph operator