Setup Instructions – jjasghar.github.io/kube101-docs/ • Promo Codes: ibm.biz/BdYkQ3 • What you’ll be doing: – Creating an IBM Cloud Account – Adding Promo Code to enable Free Kubenetes cluster – Provisioning Kubernetes Cluster – this takes 20 – 30 minutes – Install IBM Cloud CLI and Kubectl for workshop – Git Clone code repo: github.com/ibm/kube101 • Please start this NOW if you want to do the hands on portion • If you run into issues raise your hand, HELPERS will come help
and Kubernetes Cluster • Learn basic Conceptual Model of common Kubernetes Resources • Build an application image • Deploy application image to Kubernetes • Explore lifecycle of pods • Debug when things go wrong / break things to see common debug steps • Upgrade application Today's Application: System Status Page
to: – Create a new directory – Lay-down the container's filesystem – Setup the networks, mounts, … – Start the process • Better resource utilization – Can fit far more containers than VMs into a host
factor of 10 • Virtualization → Containers has the potential to be even more than a factor of 10 • Container management can't just follow OS management strategies of the past • Kubernetes takes a definition of the desired state of the world – I need 3 of these, 5 of these, this application should always be running – Similar to config management approaches like Puppet & Chef • Many best practices baked into the platform • Can extend the platform from within the Platform using Custom Resource Definitions
Container Container Pod B Node Container Pod E Container Container Container Pod D Container Container Pod A1 Container Container Pod A2 Deployment Replicas = 2 Node Node A pod contains one or more containers A Deployment ensures a pod is always running on 1 or more nodes. A Deployment provides upgrade / rollback facilities. Pod is a unit of scheduling to a node
B Node Container Pod E Container Container Pod A1 Container Container Pod A2 Node Node Container Container Container Pod B' Container Container Pod A2 If a pod is deleted or crashes it goes away If a pod in a deployment is deleted or crashes, a new version is started
Pod A Container Container Container Container Pod E Pod D Node Node Node For developers Nodes are generally hidden. It doesn't matter which Node applications are on.* *High Availability supported by affinity rules
A Service name: foo-web 5000 80 Kube DNS Inside a pod, containers can talk to each other via localhost ports Pods must expose ports explicitly to the outside world Services create an internal DNS name and port mapping to allow other pods access Applications would connect to http://foo-web apiVersion: v1 kind: Service metadata: name: foo-web labels: app: foo-web spec: ports: - port: 80 targetPort: 5000 name: foo-web-port protocol: TCP selector: app: deploy-c apiVersion: apps/v1 kind: Deployment metadata: name: deploy-c labels: app: deploy-c spec: ... Container Container Pod C' 5000 Selectors can match more than one pod
5000 80 NodePort binds an external IP address to a single Node, with a port connection to the Pod. NodePort is the only external access solution available on Free Clusters. 169.60.78.157 Node
Loadbalancer 5000 80 Loadbalancers bind an external IP address to a service. Free clusters do not have LoadBalancer access. Paid clusters have access to 5 external IPs by default. 169.60.78.157 Container Pod C' 5000
Pod D Service name: foo-web 5000 80 Ingress host: sdague-k001.us-east.containers.mybluemix.net http: paths: - path: / backend: serviceName: foo-web servicePort: 80 - path: /data-admin backend: serviceName: foo-data servicePort: 3000 Service name: foo-data Ingress controllers provide open internet access to http(s) services based on path. Multiple services may be accessed based on path matching from a single ingress controller. Free clusters do not have access to Ingress controllers. Ingress controllers are the recommended way to run real kube applications.
Exposed to containers via ENV vars, or filesystem • Service Accounts – By default applications act as the IAM user – Service Accounts can be allocated to drop permissions • Role / RoleAssignment – Allow access to Kube API / secrets – Can restrict per namespace / user / service account
--sso > ibmcloud cr namespace-add status_page > ibmcloud cr build --tag \ registry.ng.bluemix.net/status_page/web:1 status_page • The Registry is Global, you’ll need to use something unique to YOU. • Creates a private namespace in IBM container registry • Builds the image for the application
cluster-config kubelisa OK The configuration for kubelisa was downloaded successfully. Export environment variables to start using Kubernetes. export KUBECONFIG=/home/YOU/.bluemix/plugins/container-service/clusters/kube lisa/kube-config-wdc06-kubelisa.yml • From here on out we will be using kubectl to interact with the cluster • Note: if cluster is not up yet, please raise hands. We'll try to address.
name: status-web labels: app: status-web spec: replicas: 3 selector: matchLabels: app: status-web template: metadata: labels: app: status-web spec: containers: - name: status-web image: registry.ng.bluemix.net/status_page/web:1 imagePullPolicy: Always env: - name: REDIS_HOST value: "redis-leader" ports: - name: http containerPort: 5000 protocol: TCP readinessProbe: httpGet: path: /readiness port: 5000 Labels allow you to query by metadata Number of Pods to run Pass configuration by environment What ports to expose Test for when pod is ready to be added to a servic Pod
is restarted – Useful in detecting aberrant behavior (deadlocks, other non fatal errors) • readinessProbe – When readiness fails, pod is removed from any Services it's a part of – Provides facility to ensure pod is ready to accept traffic before it is exposed to the world • Every non-toy application should have both of these checks
STATUS ROLES AGE VERSION EXTERNAL-IP OS-IMAGE KERNEL- VERSION CONTAINER-RUNTIME 10.188.103.229 Ready <none> 111d v1.11.3+IKS 169.60.97.54 Ubuntu 16.04.5 LTS 4.4.0-137- generic containerd://1.1.4 > kubectl get service -l app=status-web -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR status-web NodePort 172.21.242.132 <none> 5000:32358/TCP 23m app=status-web Navigate to http://169.60.97.54:32358 Does it work?
Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 27m default-scheduler Successfully assigned default/ status-web-5c47b9b67b-57ksk to 10.188.103.229 Normal Pulling 27m kubelet, 10.188.103.229 pulling image "registry.ng..." Normal Pulled 27m kubelet, 10.188.103.229 Successfully pulled image "..." Normal Created 27m kubelet, 10.188.103.229 Created container Normal Started 27m kubelet, 10.188.103.229 Started container Warning Unhealthy 2m (x151 over 27m) kubelet, 10.188.103.229 Readiness probe failed: HTTP probe failed with statuscode: 500
It's YAML all the way down • Readiness Checks ensure application is exposed to user only when ready • Deployments provide very basic HA/restart for services • kubectl describe provides events which are good for debugging
What facilities does Kubernetes provide for upgraded deployed software? • Also... Let's make this more interesting.... – What if we make a software change which actually doesn't start? – How would the environment react to that? – How would we figure out what's going on?
field to end in from :1 to :2 > kubectl apply -f deploy/status-deployment.yaml deployment.apps "status-web" configured service "status-web" unchanged > kubectl get pods -l app=status-web NAME READY STATUS RESTARTS AGE status-web-5c47b9b67b-cxk8c 1/1 Running 0 15m status-web-5c47b9b67b-q7ln4 1/1 Running 0 1h status-web-5c47b9b67b-srcbz 1/1 Running 0 1h status-web-5d6b4665dc-5t7c5 0/1 Error 3 56s
default • Attempt to start 1 new pod – If it succeeds, delete one of the old pods, start next pod – If it fails, keep existing applications running • You should still do testing before deploy, but some basic sanity checking in the application
logs status-web-5d6b4665dc-5t7c5 * Serving Flask app "status_page" * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off Usage: flask run [OPTIONS] Error: While importing "status_page", an ImportError was raised: Traceback (most recent call last): File "/usr/local/lib/python3.6/dist-packages/flask/cli.py", line 235, in locate_app __import__(module_name) File "/var/www/status_page/status_page/__init__.py", line 17, in <module> import status_page.views File "/var/www/status_page/status_page/views.py", line 3, in <module> import noimport ModuleNotFoundError: No module named 'noimport'
people use :latest on Docker images • This is an anti-pattern for kubernetes, as infrastructure doesn't know something changed • Even in development, use unique image versions
manager", provides templating for kube yaml • Istio - service mesh, metrics and observability inside the cluster • Knative - emerging effort to make image build / serverless use cases simpler
an application in a container – How to run that container in Kubernetes • Kubernetes – provides basic availability of applications – has built in health check mechanism for applications – provides rolling upgrade semantics out of the box, including basic failure detection – how to expose an application on the network* – how to debug when something goes wrong Thank You! • Feedback welcome ibm.biz/seagl2018-feedback