Making Kubernetes Simple for Developers Suraj Deshmukh
About me: ● Works for Red Hat in Developer Tools team ● Contributes to Kompose, OpenCompose, Kubernetes, OpenShift, etc. ● IRC, slack - surajd ● Twitter - surajd_ ● Github - surajssd ● Email - surajd.service@gmail.com
This talk is going to have a lot of references to Kubernetes or OpenShift and Docker Compose. Disclaimer
Story of today’s developer (YMMV)
Deploy application in containers
Learn docker* * Now called moby
How do I run “stuff” with docker? $ docker run hello-world $ docker run -p 5432:5432 postgres First steps with Docker
Code is local python application: (venv) $ ls myapp.py requirements.txt (venv) $ python myapp.py
What do you need to package your application? ● A Dockerfile, here I am copying code from my machine to the container doing builds locally. FROM centos RUN yum install -y python-pip3 COPY . /code WORKDIR /code RUN cd /code && pip install -r requirements.txt CMD [ “myapp” ] ● And few commands Note: Don’t try this in production :p
My code repo ... $ ls Dockerfile myapp.py README.md requirements.txt
Run my awesome application $ docker build -t myapp . $ docker run -p 8080:8080 myapp $ curl localhost:8080
Need to add one more service $ ls apiserver.py Dockerfile.apiserver Dockerfile.myapp myapp.py README.md requirements.txt
And to bring this all up $ docker build -t myapp -f Dockerfile.myapp . $ docker build -t apiserver -f Dockerfile.apiserver . $ docker run postgres $ docker run apiserver $ docker run -p 8080:8080 myapp $ curl localhost:8080
Enter docker-compose
I write everything in a docker-compose file, which looks like this: services: postgresql: image: postgresql apiserver: build: Dockerfile.apiserver env: POSTGRESQL_HOST: postgresql myapp: build: Dockerfile.myapp
Updated code repo ... $ ls apiserver.py docker-compose.yml Dockerfile.apiserver Dockerfile.myapp myapp.py README.md requirements.txt
$ docker-compose up $ curl localhost:8080
Docker-compose is easier for development I am happy (Not for long).
Now that everything is running locally, how and where do I deploy this?
Container orchestrators ● Kubernetes ( OpenShift ) ● Docker Swarm ● Mesos
● Docker Compose I can use with Docker Swarm only ● Cannot use the docker-compose as is with swarm
● Kubernetes is robust ● Has Google’s production experience of more than a decade ● Huge contributor base and community
So what is this Kubernetes?
● Lot of new concepts for someone new in this world ● Pods, Service, Deployment, ReplicaSets etc. ● And what happened to all the investment I made with Docker Compose?
services: postgresql: image: postgresql apiserver: build: Dockerfile.apiserver env: POSTGRESQL_HOST: postgresql myapp: build: Dockerfile.myapp Remember this?
More google search I want to make my life easier
Enter Kompose!
$ kompose up
Demo!
Kompose helps me with ● Generating Kubernetes configurations. ● Defaults generated by Kompose are good enough. ● Kompose helps as long as the Docker Compose syntax helps ● But we don’t stop at good enough, do we? :)
● Works as long as I have fewer services and generic use cases. ● My application is now more than just application and database containers.
Use cases where kompose cannot do anything: ● Define service type. ● Kubernetes Jobs ● Secrets and Configmaps cannot be defined. ● Difficult to define volumes info. ● No way to define liveness probes and readiness probes ● How to club multiple containers in single pod ● Generating openshift templates directly.
● Most of the things (from previous slide) can be done, but needs changes in docker-compose.yaml ● May not break application.
● No direct mapping to any docker-compose constructs ● Kompose exploits docker-compose restart. Kubernetes Jobs
Secrets and Configmaps ● No direct mapping to any docker-compose constructs ● But other ways of doing it. service: foo: Env: SECRET: devenv service: foo: Env: SECRET: prodenv
Volumes ● Kompose assumes some size for PVC
Ingress and Routes ● No direct mapping in docker-compose world ● Hack around with labels : labels: kompose.service.expose: "counter.example.com"
Liveness probe and Readiness probe ● No equivalent concept in docker-compose
Kubernetes Service type ● Here also there is no direct mapping in docker-compose world to do so. ● More hacking with labels : labels: kompose.service.type: nodeport
So what do I do to get around it? ● Generate configs with Kompose ● Edit configs yourself to fill in the gaps
kind: List apiVersion: v1 metadata: {} items: - kind: Service apiVersion: v1 metadata: name: etherpad creationTimestamp: labels: service: etherpad spec: ports: - name: '80' protocol: TCP port: 80 targetPort: 9001 selector: service: etherpad status: loadBalancer: {} - kind: Service apiVersion: v1 metadata: name: mariadb creationTimestamp: labels: service: mariadb spec: ports: - name: '3306' protocol: TCP port: 3306 targetPort: 3306 selector: service: mariadb status: loadBalancer: {} - kind: Deployment apiVersion: extensions/v1beta1 metadata: name: etherpad creationTimestamp: spec: replicas: 1 template: metadata: creationTimestamp: labels: service: etherpad spec: containers: - name: etherpad image: centos/etherpad ports: - containerPort: 9001 protocol: TCP env: - name: DB_DBID value: etherpad - name: DB_HOST value: mariadb - name: DB_PASS value: etherpad - name: DB_PORT value: '3306' - name: DB_USER value: etherpad resources: {} restartPolicy: Always strategy: {} status: {} - kind: Deployment apiVersion: extensions/v1beta1 metadata: name: mariadb creationTimestamp: spec: replicas: 1 template: metadata: creationTimestamp: labels: service: mariadb spec: volumes: - name: mariadb-claim0 persistentVolumeClaim: claimName: mariadb-claim0 containers: - name: mariadb image: centos/mariadb ports: - containerPort: 3306 protocol: TCP env: - name: MYSQL_DATABASE value: etherpad - name: MYSQL_PASSWORD value: etherpad - name: MYSQL_ROOT_PASSWORD value: etherpad - name: MYSQL_USER value: etherpad resources: {} volumeMounts: - name: mariadb-claim0 mountPath: "/var/lib/mysql" restartPolicy: Always
As a kompose developer ... ● It’s tempting to extend docker-compose, which is done right now with labels. ● Need to build a solution that overcomes docker-compose limitations with respect to Kubernetes
What’s next?
Enter OpenCompose!
What is OpenCompose? ● OpenCompose is a declarative higher level abstraction for specific Kubernetes resources. ● Simple for developers to comprehend use it in their day to day development workflow. ● Kubernetes resources define how to deploy an application, OpenCompose tries to stick to define application only.
Sample OpenCompose file version: '0.1-dev' services: - name: database replicas: 2 containers: - image: mariadb:10 env: - MYSQL_ROOT_PASSWORD=rootpasswd - MYSQL_DATABASE=wordpress - MYSQL_USER=wordpress - MYSQL_PASSWORD=wordpress ports: - port: 3306 - name: web containers: - image: wordpress:4 env: - WORDPRESS_DB_HOST=database:3306 - WORDPRESS_DB_PASSWORD=wordpress - WORDPRESS_DB_USER=wordpress - WORDPRESS_DB_NAME=wordpress ports: - port: 80 type: external
Running opencompose tool $ opencompose convert -f wordpress.yaml created file "database-service.yaml" created file "database-deployment.yaml" created file "web-service.yaml" created file "web-deployment.yaml" $ kubectl create -f .
Demo!
Kollaborating with Kubernetes community
Comparison of all three tools Feature docker-compose Kompose OpenCompose Define k8s service type - Using docker-compose labels. Define type under port Kubernetes Jobs - Using docker-compose restart - Secrets - - Define a secret Volumes Cannot define size Creates a pvc of 100MB Well defined data structure for volumes Liveness and Readiness - - Define health Multiple containers in one Pod - - Define container list under each service
References: ● Kompose http://kompose.io/ ● OpenCompose https://github.com/redhat-developer/opencompose/
Meetup ● Upcoming meetup bit.ly/k8s101 ● Meetup Page bit.ly/meetupk8s

Making kubernetes simple for developers

  • 1.
  • 2.
    About me: ●Works for Red Hat in Developer Tools team ● Contributes to Kompose, OpenCompose, Kubernetes, OpenShift, etc. ● IRC, slack - surajd ● Twitter - surajd_ ● Github - surajssd ● Email - surajd.service@gmail.com
  • 3.
    This talk isgoing to have a lot of references to Kubernetes or OpenShift and Docker Compose. Disclaimer
  • 4.
    Story of today’sdeveloper (YMMV)
  • 5.
  • 6.
  • 7.
    How do Irun “stuff” with docker? $ docker run hello-world $ docker run -p 5432:5432 postgres First steps with Docker
  • 8.
    Code is localpython application: (venv) $ ls myapp.py requirements.txt (venv) $ python myapp.py
  • 9.
    What do youneed to package your application? ● A Dockerfile, here I am copying code from my machine to the container doing builds locally. FROM centos RUN yum install -y python-pip3 COPY . /code WORKDIR /code RUN cd /code && pip install -r requirements.txt CMD [ “myapp” ] ● And few commands Note: Don’t try this in production :p
  • 10.
    My code repo... $ ls Dockerfile myapp.py README.md requirements.txt
  • 11.
    Run my awesomeapplication $ docker build -t myapp . $ docker run -p 8080:8080 myapp $ curl localhost:8080
  • 12.
    Need to addone more service $ ls apiserver.py Dockerfile.apiserver Dockerfile.myapp myapp.py README.md requirements.txt
  • 13.
    And to bringthis all up $ docker build -t myapp -f Dockerfile.myapp . $ docker build -t apiserver -f Dockerfile.apiserver . $ docker run postgres $ docker run apiserver $ docker run -p 8080:8080 myapp $ curl localhost:8080
  • 14.
  • 15.
    I write everythingin a docker-compose file, which looks like this: services: postgresql: image: postgresql apiserver: build: Dockerfile.apiserver env: POSTGRESQL_HOST: postgresql myapp: build: Dockerfile.myapp
  • 16.
    Updated code repo... $ ls apiserver.py docker-compose.yml Dockerfile.apiserver Dockerfile.myapp myapp.py README.md requirements.txt
  • 17.
    $ docker-compose up $curl localhost:8080
  • 18.
    Docker-compose is easierfor development I am happy (Not for long).
  • 19.
    Now that everythingis running locally, how and where do I deploy this?
  • 20.
    Container orchestrators ● Kubernetes( OpenShift ) ● Docker Swarm ● Mesos
  • 21.
    ● Docker ComposeI can use with Docker Swarm only ● Cannot use the docker-compose as is with swarm
  • 22.
    ● Kubernetes isrobust ● Has Google’s production experience of more than a decade ● Huge contributor base and community
  • 23.
    So what isthis Kubernetes?
  • 25.
    ● Lot ofnew concepts for someone new in this world ● Pods, Service, Deployment, ReplicaSets etc. ● And what happened to all the investment I made with Docker Compose?
  • 26.
  • 27.
    More google search Iwant to make my life easier
  • 28.
  • 29.
  • 30.
  • 31.
    Kompose helps mewith ● Generating Kubernetes configurations. ● Defaults generated by Kompose are good enough. ● Kompose helps as long as the Docker Compose syntax helps ● But we don’t stop at good enough, do we? :)
  • 32.
    ● Works aslong as I have fewer services and generic use cases. ● My application is now more than just application and database containers.
  • 33.
    Use cases wherekompose cannot do anything: ● Define service type. ● Kubernetes Jobs ● Secrets and Configmaps cannot be defined. ● Difficult to define volumes info. ● No way to define liveness probes and readiness probes ● How to club multiple containers in single pod ● Generating openshift templates directly.
  • 34.
    ● Most ofthe things (from previous slide) can be done, but needs changes in docker-compose.yaml ● May not break application.
  • 35.
    ● No directmapping to any docker-compose constructs ● Kompose exploits docker-compose restart. Kubernetes Jobs
  • 36.
    Secrets and Configmaps ●No direct mapping to any docker-compose constructs ● But other ways of doing it. service: foo: Env: SECRET: devenv service: foo: Env: SECRET: prodenv
  • 37.
    Volumes ● Kompose assumessome size for PVC
  • 38.
    Ingress and Routes ●No direct mapping in docker-compose world ● Hack around with labels : labels: kompose.service.expose: "counter.example.com"
  • 39.
    Liveness probe andReadiness probe ● No equivalent concept in docker-compose
  • 40.
    Kubernetes Service type ●Here also there is no direct mapping in docker-compose world to do so. ● More hacking with labels : labels: kompose.service.type: nodeport
  • 41.
    So what doI do to get around it? ● Generate configs with Kompose ● Edit configs yourself to fill in the gaps
  • 42.
    kind: List apiVersion: v1 metadata:{} items: - kind: Service apiVersion: v1 metadata: name: etherpad creationTimestamp: labels: service: etherpad spec: ports: - name: '80' protocol: TCP port: 80 targetPort: 9001 selector: service: etherpad status: loadBalancer: {} - kind: Service apiVersion: v1 metadata: name: mariadb creationTimestamp: labels: service: mariadb spec: ports: - name: '3306' protocol: TCP port: 3306 targetPort: 3306 selector: service: mariadb status: loadBalancer: {} - kind: Deployment apiVersion: extensions/v1beta1 metadata: name: etherpad creationTimestamp: spec: replicas: 1 template: metadata: creationTimestamp: labels: service: etherpad spec: containers: - name: etherpad image: centos/etherpad ports: - containerPort: 9001 protocol: TCP env: - name: DB_DBID value: etherpad - name: DB_HOST value: mariadb - name: DB_PASS value: etherpad - name: DB_PORT value: '3306' - name: DB_USER value: etherpad resources: {} restartPolicy: Always strategy: {} status: {} - kind: Deployment apiVersion: extensions/v1beta1 metadata: name: mariadb creationTimestamp: spec: replicas: 1 template: metadata: creationTimestamp: labels: service: mariadb spec: volumes: - name: mariadb-claim0 persistentVolumeClaim: claimName: mariadb-claim0 containers: - name: mariadb image: centos/mariadb ports: - containerPort: 3306 protocol: TCP env: - name: MYSQL_DATABASE value: etherpad - name: MYSQL_PASSWORD value: etherpad - name: MYSQL_ROOT_PASSWORD value: etherpad - name: MYSQL_USER value: etherpad resources: {} volumeMounts: - name: mariadb-claim0 mountPath: "/var/lib/mysql" restartPolicy: Always
  • 43.
    As a komposedeveloper ... ● It’s tempting to extend docker-compose, which is done right now with labels. ● Need to build a solution that overcomes docker-compose limitations with respect to Kubernetes
  • 44.
  • 45.
  • 46.
    What is OpenCompose? ●OpenCompose is a declarative higher level abstraction for specific Kubernetes resources. ● Simple for developers to comprehend use it in their day to day development workflow. ● Kubernetes resources define how to deploy an application, OpenCompose tries to stick to define application only.
  • 47.
    Sample OpenCompose file version:'0.1-dev' services: - name: database replicas: 2 containers: - image: mariadb:10 env: - MYSQL_ROOT_PASSWORD=rootpasswd - MYSQL_DATABASE=wordpress - MYSQL_USER=wordpress - MYSQL_PASSWORD=wordpress ports: - port: 3306 - name: web containers: - image: wordpress:4 env: - WORDPRESS_DB_HOST=database:3306 - WORDPRESS_DB_PASSWORD=wordpress - WORDPRESS_DB_USER=wordpress - WORDPRESS_DB_NAME=wordpress ports: - port: 80 type: external
  • 48.
    Running opencompose tool $opencompose convert -f wordpress.yaml created file "database-service.yaml" created file "database-deployment.yaml" created file "web-service.yaml" created file "web-deployment.yaml" $ kubectl create -f .
  • 49.
  • 50.
  • 51.
    Comparison of allthree tools Feature docker-compose Kompose OpenCompose Define k8s service type - Using docker-compose labels. Define type under port Kubernetes Jobs - Using docker-compose restart - Secrets - - Define a secret Volumes Cannot define size Creates a pvc of 100MB Well defined data structure for volumes Liveness and Readiness - - Define health Multiple containers in one Pod - - Define container list under each service
  • 52.
    References: ● Kompose http://kompose.io/ ●OpenCompose https://github.com/redhat-developer/opencompose/
  • 53.
    Meetup ● Upcoming meetupbit.ly/k8s101 ● Meetup Page bit.ly/meetupk8s