Skip to content

Instantly share code, notes, and snippets.

@proppy
Last active August 29, 2015 14:07
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save proppy/8e714bf41b6b0978ab0e to your computer and use it in GitHub Desktop.
Save proppy/8e714bf41b6b0978ab0e to your computer and use it in GitHub Desktop.
fig2kube

fig2kube

Detailed hand-conversion of a sample fig local config to a set of kubernetes distributed services.

Define the web container

fig/fig.yml

web:
  build: .
  ports:
   - "80:8080"
  links:
   - redis

kube/web-pod.yaml

id: web
desiredState:
  manifest:
    version: v1beta1
    containers:
    - name: counter
      # point to registry service endpoint
      image: localhost:5000/counter
      ports:
      - name: http-server
        containerPort: 8080
labels:
  name: web

Note:

  • no forward declaration of links: service indirection.
  • no build stanza

kube/web-service.yaml

id: web
port: 80
containerPort: http-server
selector:
  name: web

Note: Service ports automatically published on each nodes.

Define the redis container

fig/fig.yml

redis:
  image: redis

kube/redis-pod.yaml

id: redis
desiredState:
  manifest:
    version: v1beta1
    containers:
    - name: master
      image: redis
      ports:
      - name: redis-server
        containerPort: 6379
labels:
  name: redis
  role: master

kube/redis-service.yaml

apiVersion: v1beta1
kind: Service
id: redis
port: 6379
containerPort: redis-server
selector:
  name: redis
  role: master

Service discovery

fig

/etc/hosts
REDIS_PORT_6379_TCP
REDIS_PORT_6379_TCP_PROTO
REDIS_PORT_6379_TCP_PORT
REDIS_PORT_6379_TCP_ADDR

kube

REDIS_PORT_6379_TCP
REDIS_PORT_6379_TCP_PROTO
REDIS_PORT_6379_TCP_PORT
REDIS_PORT_6379_TCP_ADDR
REDIS_SERVICE_HOST
REDIS_SERVICE_PORT
REDIS_PORT

Note: Service exposed to all containers on any nodes thru a proxy.

Build the web container image

fig

$ fig build

kube:

# regular docker build
$ docker build -t counter .
# also push the container to the cluster storage
$ docker tag counter localhost:5000/counter
$ docker run -p 5000:5000 -e GCS_BUCKET=proppy-stuff-docker -e GCP_OAUTH2_REFRESH_TOKEN=some-secret docker/google-registry
$ docker push localhost:5000/counter

also define registry pointing to cluster storage

id: registry
desiredState:
  manifest:
    version: v1beta1
    containers:
    - name: registry
      image: google/docker-registry
      ports:
      - name: registry-server
        containerPort: 5000
        hostPort: 5000
      env:
      - name: GCS_BUCKET
        value: proppy-stuff-docker
labels:
  name: registry

and service to publish the endpoint on every node

id: redis
port: 6379
containerPort: redis-server
selector:
  name: redis
  role: master

Run the app

fig

$ fig up

kube

# run the registry pod and service
kubecfg -c registry-pod.yaml create pods
kubecfg -c registry-service.yaml create services
# run the web pod and service
kubecfg -c web-pod.yaml create pods
kubecfg -c web-service.yaml create services
# run the redis pod and service
kubecfg -c redis-pod.yaml create pods
kubecfg -c redis-service.yaml create redis

Scale

fig

$ fig scale web=3 redis=1
$ fig  ps
   Name                 Command             State            Ports          
---------------------------------------------------------------------------
fig_redis_1   /entrypoint.sh redis-server   Up      6379/tcp                
fig_web_1     python app.py                 Up      0.0.0.0:49155->8080/tcp 
fig_web_2     python app.py                 Up      0.0.0.0:49156->8080/tcp 
fig_web_3     python app.py                 Up      0.0.0.0:49157->8080/tcp 

Note: imperative, stateful, random ports allocated on the same node

kube/web-controller.yaml

id: web
desiredState:
  replicas: 3
  replicaSelector:
    name: web
  podTemplate:
    desiredState:
      manifest: ...
    labels: 
      name: web

Note: declarative

$ kubecfg -c web-controller.yaml create replicationControllers

Note: starts only 2 additional pods to satisfy the replica constraints

from flask import Flask
from redis import Redis
import os
app = Flask(__name__)
redis = Redis(os.environ.get('REDIS_PORT_6379_TCP_ADDR', 'redis'), port=6379)
@app.route('/')
def hello():
redis.incr('hits')
return 'Hello World! I have been seen %s times.' % redis.get('hits')
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080, debug=True)
FROM google/python:2.7
ADD requirements.txt /code/requirements.txt
RUN pip install -r /code/requirements.txt
ADD . /code
WORKDIR /code
ENTRYPOINT ["python", "app.py"]
web:
build: .
ports:
- "8080"
links:
- redis
redis:
image: redis
id: redis
desiredState:
manifest:
version: v1beta1
containers:
- name: master
image: redis
ports:
- name: redis-server
containerPort: 6379
labels:
name: redis
role: master
id: redis
port: 6379
containerPort: redis-server
selector:
name: redis
role: master
id: registry
desiredState:
manifest:
version: v1beta1
containers:
- name: registry
image: google/docker-registry
ports:
- name: registry-server
containerPort: 5000
hostPort: 5000
env:
- name: GCS_BUCKET
value: proppy-stuff-docker
labels:
name: registry
id: registry
port: 5000
containerPort: registry-server
selector:
name: registry
id: web
desiredState:
replicas: 3
replicaSelector:
name: web
podTemplate:
desiredState:
manifest:
version: v1beta1
containers:
- name: counter
image: localhost:5000/counter
ports:
- name: http-server
containerPort: 8080
labels:
name: web
id: web
desiredState:
manifest:
version: v1beta1
containers:
- name: counter
image: localhost:5000/counter
ports:
- name: http-server
containerPort: 8080
labels:
name: web
id: web
port: 80
containerPort: http-server
selector:
name: web
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment