在这篇文章中我们介绍了Docker的基本概念以及入门教程。在这里我们聊一下为什么我们需要使用容器。通过下面的图进行对比。
在传统的项目部署时,使用物理机或者VM(虚拟机)来直接安装。如左图所示,在内核的上层是运行环境(需要一系列手动安装或使用脚本主动安装),上层运行着一个一个独立的APP。对于VM来说,它是可以整体迁移的,但是这个迁移还是比较重,主要体现在VM是整个操作系统的镜像实例,在做扩容和迁移时需要大费周章。
转到右图,容器是一个更轻量级的概念,他存在于VM之上,拥有自己的文件系统,也拥有一个独立的ip,等等。每一个应用均运行在一个容器中,有容器为其提供所需要的基础资源和运行时环境。它更适合扩展和迁移,并且迁移成本极低(镜像发布)。
简单来说,Docker不具备自动扩容、负载均衡以及分布式集群部署的能力。Kubernetes是容器集群管理系统,是一个开源的平台,可以实现容器集群的自动化部署、自动扩缩容、维护等功能。它是基于容器(通常是Docker)之上的。
这一层是给K8s的运维人员使用的,kubectl是命令行交互工具,可以通过它来操作K8s集群。
首先K8s是基于主从(Master-Slaver)模型的,Master节点负责整个集群的调度管理工作,不负责应用的运行。在K8s中,Master节点可以简称为Master,SLave节点可以简称Node。在企业级K8s集群中,通常存在多个Master节点以实现HA(高可用)。
Master节点全部的持久化数据都存储在ETCD上,除此之外,Node、Pod的运行状态、用户的配置信息等也都存放在此。值得注意的是,只有Api-SERVCER组件有权限读写ETCD,因此只能通过API-SERVER来访问ETCD。
Master节点还包含Scheduler进行资源调度,将Pod调度到满足条件的Node上运行。
ControllerManager负责管理全部的Controller,这些Controller负责监控、调度集群的状态,比如故障检测、自动扩展、滚动更新等。
ApiServer负责接收K8S所有请求,是k8s资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制。API Server根据的具体请求,去通知其他组件干活。
在Node上通常有Kublet、Kybe-proxy以及Conatiner-Runtime。
Kubelet是Node的监视器。每个节点上都运行一个 kubelet 服务进程,默认监听 10250 端口,接收并执行 master 发来的指令,管理 Pod 及 Pod 中的容器。每个 kubelet 进程会在 API Server 上注册节点自身信息,定期向 master 节点汇报节点的资源使用情况,并监控节点和容器的资源,维护node节点上Pod的生命周期。
Kube-Proxy是K8S的网络代理。Kube-Proxy负责Node在K8S的网络通讯、以及对外部网络流量的负载均衡。
Container Runtime是Node的运行环境。容器运行时(Container Runtime)是 Kubernetes 最重要的组件之一,负责真正管理镜像和容器的生命周期。Kubelet 通过 Container Runtime Interface (CRI) 与容器运行时交互,以管理镜像和容器。Docker是比较常见的容器运行时。
Node即一台物理机或者VM。
Node是Kubernetes中的工作节点,最开始被称为minion。每个Node(节点)具有运行pod的一些必要服务,并由Master组件进行管理,Node节点上的服务包括Docker、kubelet和kube-proxy。
Pod是Kubernetes创建或部署的最小/最简单的基本单位,一个Pod代表集群上正在运行的一个进程。
一个Pod封装一个应用容器(也可以有多个容器),存储资源、一个独立的网络IP以及管理控制容器运行方式的策略选项。Pod代表部署的一个单位:Kubernetes中单个应用的实例,它可能由单个容器或多个容器共享组成的资源。
Docker是Kubernetes Pod中最常见的runtime ,Pods也支持其他容器runtimes。
Kubernetes中的Pod使用可分两种主要方式:
每个Pod被分配一个独立的IP地址,Pod中的每个容器共享网络命名空间,包括IP地址和网络端口。Pod内的容器可以使用localhost相互通信。
Pod可以指定一组共享存储volumes。Pod中的所有容器都可以访问共享volumes,允许这些容器共享数据。volumes 还用于Pod中的数据持久化,以防其中一个容器需要重新启动而丢失数据。
Volume中文名叫卷,是Pod数据持久化存储的地方。
默认情况下容器中的磁盘文件是非持久化的,对于运行在容器中的应用来说面临两个问题:
你可以简单地认为Volume就是Pod的磁盘,它同Pod的生命周期一致,当Pod被销毁时Volume即被销毁。
Kubernetes支持许多类型的Volume。这里就不详细介绍了。
K8s同传统的分布式模型一样,有Master-Node之分。
Master组件提供集群的管理控制中心。Master相关的组件并不是只能运行在Master节点上,而是通常来讲将其运行在Master节点上。
kube-apiserver用于暴露Kubernetes API。任何的资源请求/调用操作都是通过kube-apiserver提供的接口进行。
K8S的存储服务。ETCD保存了集群中Master Node和Worker Node中各个组件的状态,同时也存储了K8S的关键配置和用户配置,k8s架构所有需要持久化的数据都会存储在ETCD中。K8S中仅API Server才具备读写权限,其他组件必须通过API Server的接口才能读写数据;
控制器管理器,管理所有的控制器。K8s包含的控制器可以分为:
这个组件的作用是为未分配的Pod分配一个Node。
不强制。但是每一个K8s集群都应该使用DNS组件。
图形化管理界面。
日志
节点组件运行在Node,提供Kubernetes运行时环境,以及维护Pod。
kubelet是主要的节点代理,它会监视已分配给节点的pod,具体功能为:
kube-proxy通过在主机上维护网络规则并执行连接转发来实现Kubernetes服务抽象。
kube-proxy在每个Node上。服务集群 IP 和端口是通过 Docker-links-compatible 环境变量找到的,指定proxy打开的端口。DNS组件为这些集群 IP 提供集群 DNS。用户必须使用上问题到的 apiserver API 创建服务来配置代理。
每一个Node需要安装Docker
监控并保障kubelet和docker正常运行。
日志
对象即指本节中提到的几乎全部的概念。K8s对象包括:
类别 | 名称 |
---|---|
资源对象 | Pod、ReplicaSet、ReplicationController、Deployment、StatefulSet、DaemonSet、Job CronJob、HorizontalPodAutoscaling |
配置对象 | Node、Namespace、Service、Secret、ConfigMap、Ingress、Label、ThirdPartyResource、 ServiceAccount |
存储对象 | Volume、Persistent Volume |
策略对象 | SecurityContext、ResourceQuota、LimitRange |
这些对象使用kubectl命令,传入yml文件作为参数来配置部署方案。
假设我们配置yml文件内容如下:
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
命令如下:
$ kubectl create -f docs/user-guide/nginx-deployment.yaml --record
每个pod有独一的ip地址,当有多个pod提供相同的服务的时候,就需要有负载均衡的能力,从而这里就涉及到一个概念就是service,专门用来提供服务的。服务主要是用来提供外界访问的接口,service可以关联一组pod,这些pod的ip地址各不相同,而service相当于一个复杂均衡的vip,用来指向各个pod,当pod的ip地址发生改变之后,也能做到自动进行负载均衡,在关联的时候,service和pod之间主要通过label来关联,也就是标签,例如图中的A,B就是标签,每个deployment通过标签可以知道它所管理哪些pod
##(六)ReplicaSet
ReplicaSet 的目的是维护一组Pod在任何时候都处于稳定运行的状态。 因此,它通常用来保证给定数量的、完全相同的 Pod 的可用性。ReplicaSet受控制于Deployment
##(七)Ingress
Ingress是整个K8S集群的接入层,负责集群内外通讯,类似springcloud的zuul网关的作用。
为了缩短篇幅本文不详细描述搭建K8s集群的过程,实际上,可以有多种方式搭建K8s集群,你可以选择简单地MiniKube搭建,也可以选择搭建一个完全自定义的K8s集群,都有相应的社区文档参考。
我们以在K8s上部署一个Nginx应用为例
apiVersion: v1 #类型为Namespace
kind: Namespace #类型为Namespace
metadata:
name: ns-test #命名空间名称
#创建
kubectl create -f nginx-namespace.yaml
#查询
kubectl get namespace
# 新建配置文件
vim nginx-deployment.yaml
# 配置文件内容
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: ns-test
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
#创建
kubectl create -f nginx-deployment.yaml
#查询
kubectl get deployment
#或
kubectl get pods -n ns-test
vim nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
kubectl create -f nginx-service.yaml
//查看生成的ip
kubectl get svc nginx-service -o wide
http://docs.kubernetes.org.cn/227.html
https://www.jianshu.com/p/20e8a74e3a73
https://www.jianshu.com/p/a73c33283de8
https://www.jianshu.com/p/8e077225e4f7