https://github.com/callmer00t/kubeguide_example/tree/master/Chapter_1 (k8s权威指南代码)
基于容器技术的分布式加购领先方案。
k8s中大部分概念(如Node Pod RC Service等)都可以被看做一种资源对象, 可以被k8s提供的kubectl工具(或API调用)执行crud操作。并且可以采用YAML或JSON文件来定义和描述。
k8s将集群中的机器(物理机或者虚拟机)划分为一个Master和一些Node
Master-集群控制节点
基本上所有k8s的命令都是有master执行。通常占据一个服务器(高可用部署建议3台服务器)
运行着集群管理的一组进程,这些进程实现整个集群的资源管理 pod调度 弹性伸缩等管理功能
比如:
K8s API Server | 提供http Rest接口的关键服务进程 | k8s里面所有资源CRUD唯一入口 |
---|---|---|
k8s Controller Manager | 所有资源的自动化控制中心 | |
k8s Scheduler | 负责资源调度(pod调度)的进程 | |
etcd服务(通常部署) | k8s所有的资源对象的数据存在etcd里 |
Node-集群的工作节点
运行真正的应用程序,运行着kubelet、 kube-proxy 服务进程,负责Pod的创建 启动 监控 销毁以及负载均衡等
查看所有Nodes
Kubectl get nodes
Pod-节点上被k8s管理的最小运行单元
每个pod都包含一个特殊根容器(Pause),其他容器则为业务容器。
共享Pause容器的网络栈和Volume挂载卷
k8s会给每个pod分配唯一的IP(Pod IP), 集群内任意两个pod之间可以通过TCP/UDP直接通信。
EndPoint
Pod IP + Container port 组成,代表pod里面一个服务进程的对外通信地址
Container—使用docker容器技术隔离的具体的服务进程,如nginx
^
|
| k8s会给每个pod贴上一个标签(Label),如 name=mysql
| 给相应的Service定义标签选择器(Label Selector)
| 这样建立起对应关联关系
V
Service—分布式集群架构的核心
拥有唯一名字
拥有一个虚拟IP(Cluster IP)和 端口号
提供远程服务能力
被映射到提供改服务能力的一组容器应用上(既pod上)
service定义了一个服务的访问入口地址(虚拟Cluster Ip + Port),通过label selector,映射到通过RC控制的一组pod上。
相当于在一组pod集群服务前,架设一个负载均衡器(软/硬件, 在k8s上,其实就是Node上的kube-proxy进程),把service请求转发到对应的Pod实例上(EndPoint)
服务发现机制
任何分布式系统都会涉及“服务发现”的问题
k8s中每个service拥有全局唯一的name和cluster ip。
名字不会变,并且service都会生成一些linux环境变量(比如service-key: cluster ip),每个pod启动都会自动注入这些环境变量,环境变量命名有统一规范。
A服务想要调用B服务,可以直接在代码访问系统环境变量来得到所需要信息,比如B服务的ClusterIP+Port
DNS发现
通过环境变量获取还是不够方便。
类似互联网的DNS一样,k8s引入了DNS系统,服务名作为DSN域名。代码可以直接使用服务名来建立通信连接
service中的三种port
port / targetport / nodeport
- port: 8080 , Service暴露出来的Port (集群内部通过clustip+port 访问service服务)
- nodePort: 31199, Node 暴露出来的Port (集群外部通过NodeIP+nodePort访问service服务,实现方式是集群内每个Node都为需被外部访问的service开启一个对应的TCP监听端口,外部系统用任意一个NodeIP+NodePort端口即可访问此service)
- targetPort: 80, Container上暴露的Port (最终请求到达的容器监听的端口)
| Node Ip | k8s集群中每个节点的物理网卡的IP地址,真实存在,所以属于这个网络的服务器都能直接通信,不管是否在集群内 | | | —- | —- | —- | | Pod Ip | docker Enginer 根据docker0网桥的IP地址段进行分配,虚拟二层网络 | k8s内部任意pod之间可以直接通过podip通信,但是真实TCP/IP流量是通过Node IP所在物流网卡流出的 | | Cluster Ip | 内部虚拟ip,仅作用于service对象。apiVersion: v1
kind: Service
metadata:
labels:
run: nginx
spec:
ports:
- nodePort: 31199
port: 8080
protocol: TCP
targetPort: 80
selector:
run: nginx
type: NodePort // 需要被外部访问才需设置成NodePort,默认是cluster Ip模式
status:
loadBalancer: {}
单独不具备通信能力,只能结合service port组成具体的通信端口 | 无实体网络对象,无发被ping |
RC-pod副本控制器
(Replication Controller)是确保用户定义的Pod副本数保持不变
在用户定义范围内,如果pod增多,则ReplicationController会终止额外的pod,如果减少,RC会创建新的pod,始终保持在定义范围。例如,RC会在Pod维护(例如内核升级)后在节点上重新创建新Pod。
———-建议使用Deployment 配置 ReplicaSet (简称RS)方法来控制副本数
Replica Set—RC升级版
主要区别:
RC:只支持基于等式的Label Selector
RS: 支持基于集合的Label Selector
RS主要被Deployment这个更高层的资源对象所使用,RC基本已经被取代了。
Deployment
k8s 1.2引入的新概念
内部使用RS,整体是RC的升级,相似度超过90%
volume(存储卷)
Namespace-命名空间
Kubernetes 支持多个虚拟集群,它们底层依赖于同一个物理集群。 这些虚拟集群被称为名字空间。 在一些文档里名字空间也称为命名空间。
可以实现多租户的资源隔离
k8s启动后,默认创建一个名为default的Namespace
每个 Kubernetes 资源只能在一个名字空间中
你可以使用以下命令列出集群中现存的名字空间:
kubectl get namespace
NAME STATUS AGE
default Active 1d
kube-node-lease Active 1d
kube-system Active 1d
kube-public Active 1d
Kubernetes 会创建四个初始名字空间
为请求设置名字空间
要为当前请求设置名字空间,请使用 —namespace 参数。
例如:
kubectl run nginx —image=nginx —namespace=<名字空间名称> kubectl get pods —namespace=<名字空间名称>
Annotation-注解
跟label类似,key-value形式。
比label更随意,用户可以任意定义附加信息,以便外部工具查找。
比如:构建版本 PR号 日志库地址 debugger工具 团队信息等等
ConfigMap
分布式系统希望集中管理系统的配置参数。而不是一堆配置文件
k8s会在Etcd数据库中,持久化存储以key-value结构的Map表,并提供API对齐CRUD。
这个Map就是k8s ConfigMap资源对象
k8s提供一种内建机制,将存储在etcd中的configmap通过volume映射的方式变成目标pod内的配置文件。
这种方式就成了分布式系统中最为简单且无侵入的配置中心,