Rodolfo Pilas
bloger podcaster devops sysadmin profesor father
Revisión 2022
The container
The container
The container
The application (codes)
The runtime environment (service)
a single immutable image that contains everything needed to run an application
The container
The application (codes)
The runtime environment (service)
The container
running
A storage
A network
Server
docker run myapp1
myapp1
development environment
Server
docker run -p 443:80 loadbalancer
docker run myapp1
docker run myapp2
myapp1
myapp2
loadbalancer
production environment
(simple)
Server
docker compose up
myapp1
myapp2
loadbalancer
production environment
(complex)
myapi
database
version: '3'
services:
loadbalancer:
image: loadbalancer
myapp:
image: myapp
deploy:
replicas: 2
myapi:
image: myapi
database:
image: mysql
docker compose up
docker compose up
docker compose up
production environment
(complex
with success)
production environment
ERROR
ssh server
docker ps
docker compose up
docker compose up
docker compose up
Complexity + Success
container orchestrator knows the cluster
container orchestrator monitors and alters
container orchestrator solves the issues
Complex and successful environments
require monitoring, alerting and react to solve issues,
a
CONTAINER ORCHESTRATOR
docker | docker compose | kubernetes |
---|---|---|
1-2 nodes dev environments speed deploy |
1-5 nodes complex environments repeated deploy fixed size no time to kubernetes |
+3 nodes complex environments dynamic deploy flexible resize always need to learn |
cluster
master
node
node
worker
(minion)
worker
(minion)
node
master
kubectl
(cli)
dashboard
(ui)
REST client
(code)
kubelet
API
server
Scheduller
etcd
Controller
Manager
kube-proxy
Pod
Pod
Pod
Junio
2014
Julio
2014
Julio
2015
Marzo
2018
Commit inicial en GitHub (Google) k8s - Go
Microsoft, RedHat, IBM y Docker
Kubernetes v1.0
Nov
2015
Primer KubeCon
Feb
2016
Helm Package Manager
CNCF Certified
brew install kubernetes-cli
Dev's clusters:
A single executable file that allows you to interact with the Kubernetes API using a command-line interface (CLI)
kubectl version
Client Version: version.Info{Major:"1", Minor:"25",
Kustomize Version: v4.5.7
Server Version: version.Info{Major:"1", Minor:"25",
kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:51076
CoreDNS is running at https://127.0.0.1:51076/api/v1/namespaces/kube-system
kubeconfig
$HOME/.kube/config <== file
--kubeconfig <== options
export KUBECONFIG <== environment
$ kubectl config get-contexts
CURRENT NAME
arn:aws:eks:us-east-1:040552251222:cluster/eksworkshop-eksctl
arn:aws:eks:us-east-1:037282212900:cluster/sre
docker-desktop
* kind-ws-mooveit
tp.w.uy
a context is an entity defined inside kubeconfig to alias cluster parameters with a human-readable name.
Kubernetes context only applies to the client side.
❯ git clone git@github.com:moove-it/k8s-workshop.git
# kubectl apply -f namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: my-namespace
# kubectl apply -f namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: my-namespace
❯ kubectl create namespace test
namespace/test created
❯ kubectl get namespace
NAME STATUS AGE
test Active 10s
❯ kubectl delete namespace test
namespace "test" deleted
❯ kubectl apply -f namespace.yaml
namespace/my-namespace created
❯ kubectl get namespaces
NAME STATUS AGE
my-namespace Active 32s
❯ kubectl delete -f namespace.yaml
namespace "my-namespace" deleted
imperative:
declarative:
with a yaml manifest
# kubectl apply -f hostname-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: hostname-pod-example
spec:
containers:
- name: hostname
image: oguzpastirmaci/hostname
❯ kubectl apply -f hostname-pod.yaml -n my-namespace
pod/hostname-pod-example created
❯ kubectl get pods -n my-namespace
NAME READY STATUS RESTARTS AGE
hostname-pod-example 1/1 Running 0 19s
❯ kubectl describe pod -n my-namespace hostname-pod-example
Name: hostname-pod-example
Namespace: my-namespace
Priority: 0
Service Account: default
Node: ws-mooveit-control-plane/172.18.0.2
❯ kubectl get all -n my-namespace
NAME READY STATUS RESTARTS AGE
pod/hostname-pod-example 1/1 Running 0 2m40s
# kubectl apply -f hostname-replicaset.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: hostname-rs-example
labels:
name: hostname
spec:
replicas: 3
selector:
matchLabels:
name: hostname
template:
metadata:
name: hostname-pod-example
labels:
name: hostname
language: golang
spec:
containers:
- name: hostname
image: oguzpastirmaci/hostname
❯ kubectl apply -f hostname-replicaset.yaml -n my-namespace
replicaset.apps/hostname-rs-example created
❯ kubectl get all -n my-namespace
NAME READY STATUS RESTARTS AGE
pod/hostname-pod-example 1/1 Running 0 3m52s
pod/hostname-rs-example-7k94n 1/1 Running 0 14s
pod/hostname-rs-example-j82pv 1/1 Running 0 14s
pod/hostname-rs-example-l2nqb 1/1 Running 0 14s
NAME DESIRED CURRENT READY AGE
replicaset.apps/hostname-rs-example 3 3 3 14s
❯ kubectl delete -f ws-02-hostname-pod.yaml -n my-namespace
pod "hostname-pod-example" deleted
❯ kubectl delete pod/hostname-rs-example-7k94n -n my-namespace
pod "hostname-rs-example-7k94n" deleted
❯ kubectl get all -n my-namespace
NAME READY STATUS RESTARTS AGE
pod/hostname-rs-example-5ppll 1/1 Running 0 15s
pod/hostname-rs-example-j82pv 1/1 Running 0 2m13s
pod/hostname-rs-example-l2nqb 1/1 Running 0 2m13s
NAME DESIRED CURRENT READY AGE
replicaset.apps/hostname-rs-example 3 3 3 2m14s
# kubectl apply -f hostname-deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-example-1
labels:
name: example-1
spec:
replicas: 5
selector:
matchLabels:
name: hostname
strategy:
type: RollingUpdate
template:
metadata:
name: hostname-pod-example
labels:
name: hostname
language: golang
spec:
containers:
- name: hostname
image: oguzpastirmaci/hostname
Applications are seeing as
Deployments
# kubectl apply -f hostname-deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-example-1
labels:
name: example-1
spec:
replicas: 5
selector:
matchLabels:
name: hostname
strategy:
type: RollingUpdate
template:
metadata:
name: hostname-pod-example
labels:
name: hostname
language: golang
spec:
containers:
- name: hostname
image: oguzpastirmaci/hostname
❯ kubectl apply -f hostname-deployment.yaml -n my-namespace
deployment.apps/deploy-example-1 created
❯ kubectl get all -n my-namespace
NAME READY STATUS RESTARTS AGE
pod/hostname-rs-example-5ppll 1/1 Running 0 13m
pod/hostname-rs-example-5vbv7 1/1 Running 0 23s
pod/hostname-rs-example-dqrbt 1/1 Running 0 23s
pod/hostname-rs-example-j82pv 1/1 Running 0 15m
pod/hostname-rs-example-l2nqb 1/1 Running 0 15m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/deploy-example-1 5/5 5 5 23s
NAME DESIRED CURRENT READY AGE
replicaset.apps/hostname-rs-example 5 5 5 15m
❯ kubectl describe -n my-namespace deployments.apps/deploy-example-1
Name: deploy-example-1
Namespace: my-namespace
CreationTimestamp: Wed, 07 Sep 2022 16:08:28 -0300
Labels: name=example-1
Annotations: deployment.kubernetes.io/revision: 1
Selector: name=hostname
Replicas: 5 desired | 5 updated | 5 total | 5 available
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
# kubectl apply -f hostname-service.yml
apiVersion: v1
kind: Service
metadata:
name: hostname-svc
labels:
app: hostname
spec:
type: ClusterIP
selector:
name: hostname
ports:
- port: 9999
protocol: TCP
targetPort: 8000
❯ kubectl apply -f hostname-service.yaml -n my-namespace
service/hostname-svc created
❯ kubectl get all -n my-namespace
NAME READY STATUS RESTARTS AGE
pod/hostname-rs-example-5ppll 1/1 Running 0 24m
pod/hostname-rs-example-5vbv7 1/1 Running 0 11m
pod/hostname-rs-example-dqrbt 1/1 Running 0 11m
pod/hostname-rs-example-j82pv 1/1 Running 0 25m
pod/hostname-rs-example-l2nqb 1/1 Running 0 25m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/hostname-svc ClusterIP 10.96.129.198 <none> 9999/TCP 31s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/deploy-example-1 5/5 5 5 11m
NAME DESIRED CURRENT READY AGE
replicaset.apps/hostname-rs-example 5 5 5 25m
❯ kubectl describe svc hostname-svc -n my-namespace
Name: hostname-svc
Namespace: my-namespace
IP: 10.96.129.198
IPs: 10.96.129.198
Port: <unset> 9999/TCP
TargetPort: 3000/TCP
# kubectl apply -f hostname-service.yml
apiVersion: v1
kind: Service
metadata:
name: hostname-svc
labels:
app: hostname
spec:
type: ClusterIP
selector:
name: hostname
ports:
- port: 9999
protocol: TCP
targetPort: 8000
Endpoint is internal.
Two connection options:
❯ kubectl run -n my-namespace nginx --image=nginx
pod/nginx created
❯ kubectl exec -n my-namespace nginx -- printenv | grep SERVICE
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
HOSTNAME_SVC_SERVICE_PORT=9999
KUBERNETES_SERVICE_HOST=10.96.0.1
HOSTNAME_SVC_SERVICE_HOST=10.96.129.198
❯ kubectl exec -n my-namespace -it nginx -- bash
root@nginx:/#
❯ kubectl exec -n my-namespace -it nginx -- bash
root@nginx:/# curl $HOSTNAME_SVC_SERVICE_HOST:$HOSTNAME_SVC_SERVICE_PORT
<!DOCTYPE html><html><head><title>Hello!</title><link rel="stylesheet"
href="http://netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
</head><body><div class="container"><div class="jumbotron">
<h1>This page was served by: deploy-example-1-6cf5b4fdf9-985nw</h1></div>
</div></body></html>
root@nginx:/#
❯ kubectl port-forward -n my-namespace services/hostname-svc 8882:9999
Forwarding from 127.0.0.1:8882 -> 9999
Forwarding from [::1]:8882 -> 9999
Handling connection for 8882
# Browser connect to
#
# http://localhost:8888
#
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: hostname-ing
labels:
name: hostname
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- http:
paths:
- path: /hostname(/|$)(.*)
backend:
serviceName: hostname-svc
servicePort: 9999
EC2
worker nodes
loadbalancers
launch configurations
ECR
registry
Route53
DNS
control plane
VPC
networking
IAM
roles
permissions
KMS
key store
Certificate Manager
SSL/TLS certificates
git push
docker build
docker build
docker push
kubectl apply -f deploy.yaml
poner en container las apps TODAS !
SRE Team puede colaborar
By Rodolfo Pilas
Moove-it Kubernetes for Developers