Docker kubernetes基础教程

什么是kubernetes

Kubernetes 这个名字源自希腊语,意思是“舵手”,也是“管理者”,“治理者”和“cybernetic”的源头。k8s 是Kubernetes的简称(用数字『8』替代中间的8个字母『ubernete』)。

对于现代Web服务,用户希望应用程序7×24全天候可用,开发人员希望每天多次部署这些应用程序的更新版本。

容器化帮助打包软件以实现这些目标,使应用程序能够以简单快速的方式发布和更新,而无需停机。

Kubernetes可帮助你确保这些容器化应用程序随时随地运行,并帮助它们找到工作所需的资源和工具。

Kubernetes是一个可用于生产环境的开源平台,它的设计结合了Google在容器编排方面积累的丰富经验和社区中的最佳创意。

 

 

创建集群

————————

k8s协调一个高度可用的计算机集群,这些计算机被连接起来工作,就好像是一个单独的单元。

k8s以更有效的方式自动化跨集群分发和调度应用程序容器。

1个k8s集群由以下2部分组成:

master:协调集群

nodes:运行应用程序的work节点

启动(仅google交互教程)

minikube start

查看版本

kubectl version

获取nodes

kubectl get nodes

 

 

部署应用

————————

当你运行了k8s集群,你就可以在上面部署容器化的应用程序。具体来说,你需要创建k8s Deployment 配置。

Deployment会指示k8s如何创建、更新你的应用程序。当你创建了1个Deployment, k8s master会把应用程序实例分配到不同的Node。

应用程序实例创建后,k8s Deployment控制器会持续进行监控这些实例,一旦实例所在的节点宕机或者被删除,k8s Deployment控制器就换换掉它。这其实提供了一种自我故障修复和维护的机制。

部署应用

kubectl run kubernetes-bootcamp –image=gcr.io/google-samples/kubernetes-bootcamp:v1 –port=8080

获取Deploy情况

kubectl get deployments

开启proxy(对外暴露服务)

kubectl proxy

获取pods列表

kubectl get pods

访问服务(POD_NAME来自于上一步)

curl https://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/

 

 

探索应用

————————

Pods和Nodes

pods:

pod是k8s的1个抽象概念,代表1组docker应用程序实例和他们共享的资源(存储,网络及端口等),举例来说,一个pod可以是下面这2个container组成:

1.1个nodejs应用container

2.1个上述nodejs应用提供数据的container

pods是k8s的原子单位,当我们在k8s上部署应用时,部署程序会创建内置container的Pods(而不是直接创建container),每个pod都会绑定到Nodes,当节点故障时,相同的pods会迁移到集群中的其他Nodes。

Nodes:

Pod通常运行在Node上,Node是k8s的工作机,它可以是物理机也可以是虚拟机。1个Node可以拥有多个Pods,k8s master会在Nodes之间调度Pods。

每个Node都有至少支持运行功能:

Kubelet:处理k8s master与Node之间的通信

contaienr运行环境:Docker/rkt,用于运行应用程序

最常用的kubectl命令:

kubectl get podsnodesrc/services:列出资源

kuubectl describe XXXX(同上):显示资源详情

kubectl logs $POD_NAME:打印pod中的某个container的日志

kubectl exec $POD_NAME:在pod的某个container中执行命令(类似docker exec)

 

 

对外公开应用程序

————————

使用service暴露应用程序

事实上node是有生命周期的,当node工作机挂掉的时候,运行在该node上的Pods也会丢失,ReplicationController 会通过创建新Podsl来动态的驱动集群回到期望的状态以便保持应用程序继续执行。

举个例子:

1个图片处理的后端有3个replicas Pods,这些replicas都是可替代的,前端系统不需要关心这些replicas,即便Pod丢失或者重建。

实际上,k8s中的每个Pod都有1个独立的IP,即使这些Pod在相同的Node机器。所以这里需要有一种机制,自动协调Pods之间的更改,这样应用程序才能持续正常工作。

service是k8s的1个抽象概念,它定义了1组pods的逻辑集合及访问策略。service是一系列独立pods之间的松散组合。像其他的k8s对象一样,service也通过yaml和json来定义。

尽管每个Pod都有独立的IP,但是如果没有service,这些IP就不会暴露到集群之外。service允许你的应用程序接收流量。

service可以通过type字段定义为以下内容:

ClusterIP:内部ip,使得service可以在集群内部被访问

NodePort:以NAT的方式,在每个Node的相同端口上暴露服务,使得service可被集群外部访问。

LoadBalancer:创建一个对外的负载均衡在云服务上面(如果支持的话),同时为service分配一个固定的内部IP。

ExternalName:通过返回cname记录暴露一个service(使用任意的名字)

service会把流量路由到一系列pods。service是一个抽象概念,它允许k8s中的pod死亡、复制重建而不对应用程序产生影响。不同Pods之间的发现、路由,都由k8s service处理。

service通过lable和selector来匹配

创建并对外暴露服务

kubectl expose deployment/kubernetes-bootcamp –type=”NodePort” –port 8080

查看服务

kubectl describe services/kubernetes-bootcamp

获取Node端口

export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}’)

echo NODE_PORT=$NODE_PORT

访问service服务

curl $(minikube ip):$NODE_PORT

部署程序会为Pod创建label,可以通过以下命令查看部署及label

kubectl describe deployment

查看pods

kubectl get pods -l run=kubernetes-bootcamp

查看service

kubectl get services -l run=kubernetes-bootcamp

为pod增加新名字

kubectl label pod $POD_NAME app=v1

删除service(外部无法访问,但内部依然可访问,service只是抽象概念)

kubectl delete service -l run=kubernetes-bootcamp

 

 

运行多个应用程序实例

————————

应用程序伸缩性

前面,我们已经创建了1个deployment,并且通过service对外进行公开暴露。deployment只创建了1个pod来运行我们的应用程序,但是随着流量的增长,我们需要水平扩展应用程序,以满足用户的需求。

扩展通过改变deplyment中的replicas数量来完成。

扩展deployment将确保使用可用资源创建新的Pod并将其安排到Node。

k8s也支持autoscaling自动伸缩,这里不会详谈,当然,伸缩到0也是可能的,这会终止该deployment下所有的Pod。

运行应用程序的多个实例就需要在实例间分发流量。service内置了负载均衡器用于在deployment的Pods直接分发网络流量。service会通过端点持续监控运行的Pods,以确保流量只分发到可用的Pod。

获取deployments

kubectl get deployments

NAME                  DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE

kubernetes-bootcamp   1         1         1            1           21s

DESIRED显示的是replicas的数量, CURRENT显示的是当前运行的replicas数量,UP-TO-DATE显示的是已更新的replicas数量,AVALIABLE显示的是用户可用的replicas数量。

扩展deployment

kubectl scale deployments/kubernetes-bootcamp –replicas=4

查看pods信息

kubectl get pods -o wide

NAME                                   READY     STATUS    RESTARTS   AGE IP           NODE

kubernetes-bootcamp-5c69669756-8v6d9   1/1       Running   0          1m 172.18.0.7   minikube

kubernetes-bootcamp-5c69669756-fqtvp   1/1       Running   0          1m 172.18.0.6   minikube

kubernetes-bootcamp-5c69669756-m86tg   1/1       Running   0          6m 172.18.0.2   minikube

kubernetes-bootcamp-5c69669756-znz7b   1/1       Running   0          1m 172.18.0.5   minikube

1个旧的Pod(AGE=6m),3个新的Pod(AGE=1m)

当你运行了多个应用程序实例,当然是希望能够滚动更新而不进行停机的,这部分内容会在后面讲到。

滚动更新(rolling updates)

用户希望应用程序全天候都能够稳定可用,但是开发人员希望一天内部署多次更新的版本。在k8s里面,这通过滚动更新来完成。滚动更新允许deployment的更新通过增加更新Pods来实现。新的Pods会被安排到可用的Node节点。

前面,我们已经把应用程序扩展为多个实例。这其实是执行更新,而不影响应用程序可用性的1个要求。

默认的,滚动更新期间,Pod的最大不可用数量(禁用数量)和创建的新Pod最大数量都是1(意即逐个Pod进行更新)。当然,这个值是可以修改的(可改为具体数字或百分比)。

在k8s里,更新是有版本管理的,任何Deployment都能回滚到之前的版本。

更新过程(默认配置):

禁用1个旧Pod,创建1个新Pod,持续进行,直到全部Pod都更新完成。

更新Pod

kubectl set image deploymentskubernetes-bootcamp kubernetes-bootcamp=jocatalinkubernetes-bootcamp:v2

回滚Pod

kubectl rollout undo deployments/kubernetes-bootcamp

经典案例

无状态应用程序:

PHP+Redis留言板 Example: Deploying PHP Guestbook application with Redis – Kubernetes

有状态应用程序:

StatefulSet基本概念:StatefulSet Basics – Kubernetes

WordPress+MYSQL+持久数据卷Example: Deploying WordPress and MySQL with Persistent Volumes – Kubernetes

参考文档

Hello Minikube – Kubernetes

Kubernetes – Hello World 指南 – 中文文 可能已经过期,但仍有参考意义

Post Navigation