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 image.png

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 (最终请求到达的容器监听的端口)
    1. apiVersion: v1
    2. kind: Service
    3. metadata:
    4. labels:
    5. run: nginx
    6. spec:
    7. ports:
    8. - nodePort: 31199
    9. port: 8080
    10. protocol: TCP
    11. targetPort: 80
    12. selector:
    13. run: nginx
    14. type: NodePort // 需要被外部访问才需设置成NodePort,默认是cluster Ip模式
    15. status:
    16. loadBalancer: {}
    | Node Ip | k8s集群中每个节点的物理网卡的IP地址,真实存在,所以属于这个网络的服务器都能直接通信,不管是否在集群内 | | | —- | —- | —- | | Pod Ip | docker Enginer 根据docker0网桥的IP地址段进行分配,虚拟二层网络 | k8s内部任意pod之间可以直接通过podip通信,但是真实TCP/IP流量是通过Node IP所在物流网卡流出的 | | Cluster Ip | 内部虚拟ip,仅作用于service对象。
    单独不具备通信能力,只能结合service port组成具体的通信端口 | 无实体网络对象,无发被ping |

image.png

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(存储卷)

是pod中能够被多个容器访问的共享目录
image.png

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工具 团队信息等等
image.png

ConfigMap

分布式系统希望集中管理系统的配置参数。而不是一堆配置文件
k8s会在Etcd数据库中,持久化存储以key-value结构的Map表,并提供API对齐CRUD。
这个Map就是k8s ConfigMap资源对象
k8s提供一种内建机制,将存储在etcd中的configmap通过volume映射的方式变成目标pod内的配置文件。
这种方式就成了分布式系统中最为简单且无侵入的配置中心,