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 myapp1myapp1
development environment
Server
docker run -p 443:80 loadbalancer
docker run myapp1
docker run myapp2myapp1
myapp2
loadbalancer
production environment
(simple)
Server
docker compose upmyapp1
myapp2
loadbalancer
production environment
(complex)
myapi
database
version: '3'
services:
loadbalancer:
image: loadbalancer
myapp:
image: myapp
deploy:
replicas: 2
myapi:
image: myapi
database:
image: mysqldocker compose updocker compose updocker compose upproduction environment
(complex
with success)
production environment
ERROR
ssh server
docker ps
docker compose updocker compose updocker compose upComplexity + 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-cliDev'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-systemkubeconfig
$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.uya 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" deletedimperative:
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/hostnameApplications 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: 8000Endpoint 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: 9999EC2
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