k8s概念入门:https://zhuanlan.zhihu.com/p/292081941
镜像仓储部署:
k8s底层cri支持docker运行时的。因此,你直接推送到各大公开镜像仓库即可,阿里云,dockerhub,http://Quay.io,公有云仓库,甚至自己搭建的harbor或docker registry都是可以的。你可以使用任何一种k8s支持的控制器应用部署方式来部署,有状态应用statefulset,或者deployment, 守护进程类工作负载daemonset,一次性任务job,甚至定时任务cronjob来通过他们的范式来部署到k8s集群。
本地部署
本地build的镜像甚至不用推送就能引用进去。
K8S是属于主从设备模型
K8S是属于主从设备模型(Master-Slave架构),即有Master节点负责核心的调度、管理和运维,Slave节点则在执行用户的程序。但是在K8S中,主节点一般被称为Master Node或者Head Node(本文采用Master Node称呼方式),而从节点则被称为Worker Node或者Node(本文采用Worker Node称呼方式)。
要注意一点:Master Node和Worker Node是分别安装了K8S的Master和Woker组件的实体服务器,每个Node都对应了一台实体服务器(虽然Master Node可以和其中一个Worker Node安装在同一台服务器,但是建议Master Node单独部署),所有Master Node和Worker Node组成了K8S集群,同一个集群可能存在多个Master Node和Worker Node。
Pod是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。
K8S中所有的对象都通过yaml来表示
apiVersion: v1
kind: Pod
metadata:
name: memory-demo
namespace: mem-example
spec:
containers:
- name: memory-demo-ctr
image: polinux/stress
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
volumeMounts:
- name: redis-storage
mountPath: /data/redis
volumes:
- name: redis-storage
emptyDir: {}
apiVersion记录K8S的API Server版本,现在看到的都是v1,用户不用管。
kind记录该yaml的对象,比如这是一份Pod的yaml配置文件,那么值内容就是Pod。
metadata记录了Pod自身的元数据,比如这个Pod的名字、这个Pod属于哪个namespace(命名空间的概念,后文会详述,暂时理解为“同一个命名空间内的对象互相可见”)。
spec记录了Pod内部所有的资源的详细信息,看懂这个很重要:
containers记录了Pod内的容器信息,containers包括了:name容器名,image容器的镜像地址,resources容器需要的CPU、内存、GPU等资源,command容器的入口命令,args容器的入口参数,volumeMounts容器要挂载的Pod数据卷等。可以看到,上述这些信息都是启动容器的必要和必需的信息。
volumes记录了Pod内的数据卷信息,后文会详细介绍Pod的数据卷。
概念图
同一个Pod之间的Container可以通过localhost互相访问,并且可以挂载Pod内所有的数据卷;但是不同的Pod之间的Container不能用localhost访问,也不能挂载其他Pod的数据卷。
Deployment就是包工头,主要负责监督底下的工人Pod干活,确保每时每刻有用户要求数量的Pod在工作。如果一旦发现某个工人Pod不行了,就赶紧新拉一个Pod过来替换它。
ReplicaSet的作用就是管理和控制Pod,管控他们好好干活。但是,ReplicaSet受控于Deployment。形象来说,ReplicaSet就是总包工头手下的小包工头。
Service是K8S服务的核心,屏蔽了服务细节,统一对外暴露服务接口,真正做到了“微服务”。举个例子,我们的一个服务A,部署了3个备份,也就是3个Pod;对于用户来说,只需要关注一个Service的入口就可以,而不需要操心究竟应该请求哪一个Pod。优势非常明显:一方面外部用户不需要感知因为Pod上服务的意外崩溃、K8S重新拉起Pod而造成的IP变更,外部用户也不需要感知因升级、变更服务带来的Pod替换而造成的IP变化,另一方面,Service还可以做流量负载均衡。
但是,Service主要负责K8S集群内部的网络拓扑。那么集群外部怎么访问集群内部呢?这个时候就需要Ingress了
ngress是整个K8S集群的接入层,复杂集群内外通讯。
namespace
是为了把一个K8S集群划分为若干个资源不可共享的虚拟集群而诞生的。
也就是说,可以通过在K8S集群内创建namespace来分隔资源和对象。比如我有2个业务A和B,那么我可以创建ns-a和ns-b分别部署业务A和B的服务,如在ns-a中部署了一个deployment,名字是hello,返回用户的是“hello a”;在ns-b中也部署了一个deployment,名字恰巧也是hello,返回用户的是“hello b”(要知道,在同一个namespace下deployment不能同名;但是不同namespace之间没有影响)。前文提到的所有对象,都是在namespace下的;
实际部署步骤
参考文档:https://zhuanlan.zhihu.com/p/308477039
官方命令:https://kubernetes.io/zh/docs/reference/kubectl/overview/
具体指令:https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#create
kubectl
kubectl是K8S的命令行工具,并不需要kubectl安装在K8S集群的任何Node上,但是,需要确保安装kubectl的机器和K8S的集群能够进行网络互通。
故障排查
这就好像你准备装修你的房子,Deployment就是一个非常棒的装修公司,而ReplicaSet则是实际干活的包工头,而Pod则是每个干活的工人。装修公司只需要告诉包工头这个工程需要多少个工人干活,之后包工头就会实时监控每个工人,如果有M个工人请假,包工头会马上再雇佣M个工人参与进来。如果你觉得说:这批工人做工质量不行啊,我需要升级更好的。那么装修公司会马上撤走这个工程队,包括包工头和他手下所有工人,再雇佣新的工程队,包括新的包工头和新的工人。