前言
开始学习K8S了,下面就是笔记整理
简介
k8s是谷歌开源得容器管理系统,主要功能包括
- 基于容器得应用部署,维护和滚动升级
- 负载均衡和服务发现
- 跨机器和跨地区得集群调度
- 自动伸缩
- 无状态服务和有状态服务
- 广泛得Volume支持
- 插件保持扩展性
k8s是一个平台,简化应用程序得工作流,用户可以使用Lable以自己得方式组织管理资源,还可以使用Annotation来自动逸资源得描述信息,用户可以编写自己的控制器和调度器,也可以通过插件机制扩展系统的功能
k8s不是paas 平台及服务
核心组件
-
- etcd 保存了整个集群的状态
- apiserver 提供了资源操作的唯一入口,并且提供授权,访问控制,API注册和发现等机制
- controller manager 负责维护集群的状态,比如故障检测,自动扩展,滚动更新
- scheduler 负责资源调度 按照预定得调度策略将Pod调度到相应机器上
- kubelet 负责维护容器得生命周期 同时也负责Volume 和网络的管理
- Container runtime 负责镜像管理以及Pod和容器的真正运行
- kube-proxy 负责为Service提供cluster内部的服务发现和负载均衡
基本概念
Container
container (容器) 是一种虚拟化技术,使用namespace隔离不同的软件运行环境,并通过镜像自包含软件的运行环境,从而使得容器可以很方便再任何地方运行
使用容器不需要与外部的基础架构环境绑定,因为每个应用程序都不需要外部依赖,更不需要与外部的基础架构环境依赖,完美解决了从开发到生产的一致性问题
容器的优点还包括
- 敏捷的应用程序创建和部署
- 持续开发集成和不出
- 开发与运维的关注分离
- 开发测试与生产环境一致性
- 可观测性
- 云和操作系统的分发和移植性
- 以应用为中心的管理
- 松耦合
- 资源隔离
Pod
k8s使用Pod来管理容器,每个Pod可以包含一个或多个紧密关联的容器
Pod是一组紧密关联的容器集合 他们共享PID,IPC,Network和UTS namespace 是K8s调度的基本单位,Pod内的多个容器共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。
在k8s中,所有对象都使用manifest(yaml/json)来定义 比如一个简单的nginx服务可以定义为 nginx.yaml 包含了一个镜像为nginx的容器:
Node
Node 是Pod真正运行的主机,可以是物理机也可以是虚拟机,为了管理Pod 每个Node节点上至少要运行container runtime (比如docker) kubelet,和 kube-proxy 服务
Namespace
是对一组资源和对象的抽象集合,比如可以用来将胸痛内部的对象划分为不同的项目或用户组,常见的pods services replication controllers 和 deployments 都属于某一个namespace的(默认是default) 而node,persistentVolumes 等则不属于任何namespace
Service
Service 是应用服务的抽象,通过labels 为应用程序提供负载均衡和服务发现,匹配labels的Pod IP和端口列表组成endpoints 由kube-proxy负责将服务IP负载均衡到这些endpoints
每个Service 都会自动分配一个cluster IP (仅仅在集群内布可以访问的虚拟地址) 和DNS名 其他容器可以通过该地址或DNS来访问服务,而不需要了解后端容器的运行
Label
Label是世界k8s对象的标签,以key/value的方式附加到对象上, key最长不能超过63字节 value可以为空 也可以是不超过253字节的字符串
Lable不提供唯一性,并且实际上经常是很多对象(如Pods)都是用相同的label的对象(比如ReplicaSet和Service用label来选择一组Pod)Label Selector 支持以下几种方式
- 等式 app =nginx
- 集合 env in (xx,xx)
- 多个label 之间是and关系,如app=nginx,env=test
Annotations
Annotations是key/value 形式附加于对象的注解不同于labels用于标志和选择对象,Annotations则是用来记录一些附加信息,用来辅助应用部署,安全策略以及调度策略等,比如deployment 使用annotations来记录roliing update的状态。
Kubernets体验
使用kubectl操作容器
kubectl run --image=nginx:apline nginx-app --port=80 kubectl get pods
等到容器变成Running就可以使用kubectl命令来操作他
kubectl get 类似 docker ps 查询资源列表
kubectl describe 类似 docker inspect 获取资源详细信息
kubectl logs 类似 docker logs 获取容器日志
kubectl exec 类似 docker exec 在容器内执行一个命令
上述这种方式并不支持所有功能,我们更常用的是使用yaml 文件来定义资源 类似与docker File ,并哦通过kubectl create -f file.yaml 来创建资源
apiVersion: v1 kind:Pod metadata: name:nginx labels: app:nginx spec: containers: name:nginx image:nginx ports: containerPort:80
kubectl run 并不是直接创建一个Pod 而是创建一个Deployment资源(replicas=1) 再由与Deployment 关联的ReplicaSet来自动创建Pod 这等价于这样一个配置
使用Volume
pod的生命周期通常比较短,只要出现异常,就会创建一个新的Pod代替她,那容器产生的数据呢?容器内的数据会随着Pod的死亡而自动消失Volume就是为了持久化容器数据产生的,比如可以为redis容器指定一个hostpath来存储redis数据
使用Service
前面虽然创建了Pod 但是在k8s中Pod的IP地址会随之Pod的重启不断变化,并不建议直接拿Pod的IP来交互,那么如何来访问这些Pod提供的服务呢?使用Serivce,Service为一组Pod 提供一个统一入口,并为他们提供负载均衡和服务发现 比如可以为前面的nginx-app 创建一个Service
这样,在cluster内部就可以通过10.0.0.66 和 http://node-ip:30772 来访问nginx-app 而在cluster外面,则只能通过http://node-ip:30772
扩展应用
通过修改Deployment中副本的数量(replicas) 可以动态扩展或收缩应用:
这些自动扩展的哦让其会自动加入到service中,而收缩回收的容器也会自动从service中删除
kubectl scale --replicas=3 deployment/nginx-app
kubectl get deploy
滚动升级
滚动升级通过逐个容器替代升级的方式来实现五终端的服务升级
kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2
在滚动升级的过程中,如果发现了失败或者配置错误,还可以随时回滚
kubectl rolling-update frontend-v1 frontend-v2 --rollback
需要注意的是 kubectl rolling-update 只针对ReplicationController 对于更新策略是RollingUpdate的Deployment(Deployment 可以在spec中设置更新策略为RollingUpdate 默认就是RollingUpdate)更新应用后会自动滚动升级
而更新应用的话 直接使用 kubectl set命令
kubectl set image deployment/nginx-app nginx-app=nginx:1.9.1
滚动升级的过程可以使用 rollout 命令查看
kubectl rollout status deployment/nginx-app
Deployment也支持回滚
kubectl rollout history deployment/nginx-app
资源限制
k8s 通过 cgroups 提供容器资源管理的功能,可以限制每个容器的CPU和内存使用,比如对于刚开始创建的Deployment 可以通过下面的命令来限制nginx容器最多使用50%的CPU和128M内存
kubectl set resources deployment nginx-app -c=nginx --limits=cpu-500m,memory=128Mi
deployment "nginx" resources requirements updated
等同于在每个Pod中何止resources limits;
健康检查
为了保证容器在部署后处于正常运行的状态, k8s提供了两种探针(Probe 支持exectcpSocket和http)来探测容器的状态
- LivenessProbe: 探针应用是否处于健康状态如果不健康则删除并重新创建容器
- ReadinessProbe:探测应用是否启动完成并且处于正常服务状态,如果不正常则不会接手来则Kubernets Service的流量
对于已经部署的deployment 可以通过 kubectl edit deployment/nginx-app 来更新manifest 增加健康检查部分
Kubernetes集群
一个k8s集群由分布式存储etcd,控制节点controller 以及服务节点Node组成
- 控制节点负责整个集群的管理 比如容器的调度,维护资源的状态,自动扩展以及滚动更新
- 服务节点Node是真正运行容器的主机,负责管理容器镜像和容器以及cluster内的服务发现和负载句能
- etcd集群宝尊了整个集群的状态
集群联邦
集群联邦(Federation)用于阔可用去的Kubernetes集群,需要配合云服务商 一起实现
创建k8s集群
使用minikube
创建单机版最简单的办法是minikube:
minikube start
minikube cluster-info
play-with-k8s
提供了一个免费的k8s体验环境 直接访问Play with Kubernetes 就可以使用kubeadm来创建k8s集群,每次创建的集群最长可以使用4个小时
Katacoda playground
提供了免费2节点的体验环境网络基于weaveNet 并且会自动部署整个集群,注意刚打开页面集群可能还没有初始化完成,可以在master节点上运行launch.sh等待集群初始化完成