Kubernetes+docker 浅述-针对云平台测试

Kubernetes+docker 浅述

本文在收集了一些资料,加上自己的一些工作理解完成。参考书籍:kubernetes 权威指南。简单讲诉了一下 dockerk8s,为什么使用 k8s 管理容器,docker 基础操作命令,K8S集群介绍,K8S 常用的对象资源,副本控制器介绍,以及 K8S 常用的基础命令,最后是一些K8S 使用集群场景的介绍,希望对大家有所帮助。

-- 阿木木

Kubernetes 学习网址推荐

https://kubernetes.io/blog/
https://feisky.gitbooks.io/kubernetes/
K8S 权威指南

什么是容器?

容器就是将软件打包成标准化单元,以用于开发、交付和部署。
1 、容器镜像是轻量的、可执行的独立软件包 ,包含软件运行所需的所有内容:代码、运行时环境、系统工具、系统库和设置。
2 、容器化软件适用于基于 Linux Windows 的应用,在任何环境中都能够始终如一地运行。
3 、容器赋予了软件独立性,使其免受外在环境差异(例如,开发和预演环境的差异)的影响,从而有助于减少团队间在相同基础设施上运行不同软件时的冲突。
总结来说:既容器包含了软件运行所需的必要环境,将软件运行无关的其他模块移除,容器之间相互隔离,举个例子:我们在自己的 PC 上安装了多种软件,他们的端口,进程 ID 的等信息可能是不同的,我们一个虚机环境可以运行许多的容器,他们所需要的 CPU MEMORY都是以千分之一 CPU 或者 MEMORY 为单位,也就意味着,我们一个虚机环境可运行的容器是成千上万的,具体根据虚机的配置来,容器之间相互隔离,容器本身包含软件所运行的基础环境,如果是 linux centos 容器,一个容器的端口是 0~65535 ,相当于我们所安装不同的软件都可以设置端口为 65535 ,因为容器隔离互不影响,还有 IP ,进程 ID 等其他项都可以相同,后面具体讲解

什么是 Docker?

Docker 属于 Linux 容器的一种封装 , 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。
Docker 特点:集装箱、标准化( ①运输方式 ② 存储方式 ③ API 接口),隔离
为什么使用 docker:
1 、 保持开发、测试、运维、客户使用环境的一致性 2 Docker 容器是应用程序运行所需的最小环境,启动速度非常快
3 Docker 容器之间相互隔离
4 Docker 容器支持弹性升缩,快速扩展
5 、 平台之间的迁移方便
6 、 持续交付,持续部署

Docker 镜像是什么?

一个特殊的文件系统操作系统分为内核和用户空间。对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持。而 Docker 镜像( Image ),就相当于是一个 root 文件系统。Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。Docker 容器(container )与镜像( Image )之间的关系:
1 、镜像( Image )和容器( Container )的关系,就像是面向对象程序设计中的 类 和 实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
2 、容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。也因为这种隔离的特性,很多人初学 Docker 时常常会混淆容器和虚拟机

Docker 基础操作,命令

查看 docker 版本信息 docker version
查看 docker 配置信息 docker info
列出本机的所有 image 文件 docker image ls
删除 image 文件
docker image rm imageName
拉取镜像
docker image pull 镜像地址
运行 image
docker container run imageName
进入 docker 容器,进入终端交互界面
docker container run –it dockerName bash
杀死不会自动结束的 docker 容器进程 ID docker container kill dockerId
查看 docker 进程 ID 、镜像 docker ps | grep containerName
列出本机正在运行的容器 docker container ls
列出本机所有容器(包括已经停止运行的容器) docker container ls –all
删除指定的容器文件 docker container rm containerId
查看 docker 容器输出 docker container logs containerId
终止 docker 容器运行 docker container stop containerId
启动已经生成、已经停止运行的容器文件 docker container start containerId
进入正在运行的 docker 容器 docker container exec –it continerId bash
从正在运行的 docker 容器拷贝文件到本机
docker container cp containerId:filePath 将镜像文件打成 tar
docker save –o imageName.tar image 地址

Kubernetes 是什么?

Kubernetes k8s )是自动化容器操作的开源平台,这些操作包括部署,调度和节点集群间扩展。如果你曾经用过 Docker 容器技术部署容器,那么可以将 Docker 看成 Kubernetes 内部使用的低级别组件。Kubernetes 不仅仅支持 Docker ,还支持 Rocket 这是另一种容器技术。
使用 Kubernetes 可以:
1、自动化容器的部署和复制
2、随时扩展或收缩容器规模
3、将容器组织成组,并且提供容器间的负载均衡
4、很容易地升级应用程序容器的新版本,支持滚动升级,平滑升级
5、提供容器弹性,如果容器失效就替换它 等等

K8Skubernetes)集群又是啥?

首先我们要知道什么是集群?集群( cluster )就是一组计算机,它们作为一个整体向用户提供一组网络资源,这些单个的计算机系统就是集群的节点(node ),集群是将几台服务器集中在一起,实现同一业务。什么又是分布式?分布式是指将不同的业务分布在不同的地方。分布式与集群的区别是什么?分布式的每一个节点,都可以做集群,而集群并不一定就是分布式的。而分布式,从狭义上理解,也与集群差不多,但是它的组织比较松散,不像集群,有一定组织性,一台服务器宕了,其他的服务器可以顶上来。分布式的每一个节点,都完成不同的业务,一个节点宕了,这个业务就不可访问了。什么又是分布式集群?结合分布式和集群的优点,我们可以实现,按照一定的算法,来分配任务,如果有一台服务器出问题了,我们还可以根据一定的算法转移另一台服务器上。一个 K8S 系统,通常称为一个 K8S 集群 (Cluster ), Kubernetes 是一个全新的基于容器技术的分布式架构领先方案,一个容器集群管理系统

K8S 集群介绍

K8S 集群主要包括两部分,一个 Master 节点,以及多个 node 节点(有的也叫做 worker 节点),Master 节点主要还是负责管理和控制。 Node 节点是工作负载节点,里面是具体的容器。

Master 节点

负责集群管理和调度,通常独占一台虚机或者服务器, K8S 集群所有命令基本通过master 节点下发
Master 节点上运行着以下一组关键进程。
1 Kubernetes API Server ( kube-apiserver ) : 提供了 HTTP Rest 接口的关键服务进程,是Kubernetes 里所有资源的增、删、改、查等操作的唯一入口,也是集群控制的入口进程。
2 Kubernetes Controller Manager ( kube-controller-manager ) : Kubernetes 里所有资源对象的自动化控制中心,可以理解为资源对象的“ 大总管
3 Kubernetes Scheduler (kube-scheduler ): 负责资源调度( Pod 调度〉的进程,相当于公交公司的调度室
4 Etcd: 负责 kubenetes 所有资源对象的数据存储

Node 节点

K8S 集群中的工作负载节点, Node 节点可以是一台物理主机,也可以是一台虚拟机。每个 Node 都会被 Master 分配一些工作负载( Docker 容器),当某个 Node 岩机时,其上的工作负载会被 Master 自动转移到其他节点上去。每个Node 节点上都运行着以下一组关键进程。 1 kubelet :负责 Pod 对应的容器的创建、启停等任务,同时与 Master 节点密切协作,实现集群管理的基本功能。
2 kube-proxy : 实现 Kubernetes Service 的通信与负载均衡机制的重要组件。
3 Docker Engine ( docker) : Docker 引擎,负责本机的容器创建和管理工作。
通过 kubectl get nodes 查看集群所有 node ROLES 是身份权限, AGE 是运行天数, VERSION 是版本

Pod 概念与 docker container 区别

Pod k8s 系统中可以创建和管理的最小单元,是资源对象模型中由用户创建或部署的最小资源对象模型,也是在 k8s 上运行容器化应用的资源对象,其他的资源对象都是用来支撑或者扩展 Pod 对象功能的,比如控制器对象是用来管控 Pod 对象的, Service 或者 Ingress资源对象是用来暴露 Pod 引用对象的, PersistentVolume 资源对象是用来为 Pod 提供存储等等,k8s 不会直接处理容器,而是 Pod Pod 是由一个或者多个 container 组成的。 Pod 也可以看成是 K8S 的容器, pod 容器和 docker 容器的区别是什么?浅显来说, pod 是一个容器组,其中含有一个根容器,pause 容器,用根容器 pause 的状态来判断整个容器组的状态, pause容器用以记录整个容器的 IP ,其他容器组可以共享 pause 容器挂载的存储卷 pause ,解决容器之间的通信问题。
Pod 类型:普通 pod 以及静态 pod
普通 pod: 存放于 etcd 存储中,随 kubenetes mater 调度到具体的 node 节点,该 pod 被该 node 节点上的 kubectl 进程实例化一组相关的 docker 容器启动起来,在默认情况瞎,当Pod 里面的某个容器停止时, pause 会记录 container 状态,反馈到 pod 的运行状态中,kubenetes 会自动检测这个问题 pod 并且尝试重启这个 Pod (重启 Pod 里面所有的 container ),如果 pod 所在 Node 宕机,会冲重新调度该节点上所有的 pod 到其他正常节点。
静态 pod (后面细讲,那种 pod 我们称为静态 pod ):静态 pod 是存放在具体的 Node上的一个具体文件中,因为静态 pod 的数据需要保存,不随着 pod 的重启而丢失数据。

什么是 Label

我们经常听到 label (标签),到底什么是 label ,在笔者看来, label 实质上就是对于 k8s资源对象(node/pod/service/rc/rs/deployment 等)的一种分类,打标签,然后使用 k8s 自带的标签选择器 Lable Selector 查询和筛选拥有某些 Lable 的资源对象,可以说是用于查询,举个 例 子 , 在 mysql 中 , 我 们 查 询 某 张 表 的 某 一 条 数 据 , select * from table where name=”zhangsan”,这个 zhangsan 就是一个标签,我们通过 name=”zhangsan” 进行数据锁定,然后进行一系列的相关操作,所以标签在 K8S 中以键值对的形式存在。我们通过给指定的资源对象绑定一个或者多个标签,用于资源的分配/ 调度 / 配置 / 部署等工作

什么是 RC/RS/deployment?以及副本控制器的演变

RC Repliccatioon Controller )是最早期的副本控制器,使 pod 运行的副本数满足你的预
期,现在基本上不适用 RC ,使用的是 RS ,可能大家新装的 K8S 的版本中 kubectl get RC
询不到该对象。 RC 的定义:
1 、定义 pod 期待的副本数
2 、使用 Label Selector 根据 Lable 删选 Pod
3 、当 Pod 的副本数小于预期数量时候,用于创建新的 Pod (即使生成了多个 Pod 的副 本,他们的 ID 也不一样)下图 replicas 数量为 1 ,如果集群环境的 Pod 数量为 0 时,会自动创建 Pod ,当出现异常情况,发现集群环境运行的 pod 数量超过了 1 个,
K8S 会自动 terminal掉一些 Pod ,使其的 Pod 数量和 replicacs 相等
RS Replica Set )新一代 RC k8s1.2 版本及以后出现,它与 RC 的区别在于支持的 Label Selector 进行了升级,增加了基于集合的 Label Selector ,补充说明, Label Selector 早期的 RC 只支持基于等式的 Label Selector Label Selector 拥有一套标签选择的语法,以后有时间补充说明。通常 RS 不单独使用, deployment 会自动的去调用 RS
Deployment ,内部使用了 RS Deployment 会自动的对 Pod 进行创建、调度、绑定节点以及在目标 Node 上启动对应的容器。
Deployment 的运用场景:
1 、创建一个 Deployment 对象来生成对应的 RS ,并完成 Pod 副本的创建过程
2 、检查 Deployment 的状态来查看 Pod 的副本数量是否达到预期的值
3 、更新 Deployment 来创建新的 Pod (比如镜像升级)
4 、如果当前 Deployment 不稳定,则回滚到早先的 Deployment 版本
5 、暂停 Deployment ,便于修改多个 PodTemplateSpec 的配置项,之后恢复 Deployment
进行新的 Pod 发布
6 、扩展 Deployment 用来提升微服务性能
7 、查看 Deployment 的状态,可以查看 Pod 是否发布成功
8 、清理不要的旧版本 RS
副本控制器的演变:早期的 RC- 新一代 RS-Deployment

StatefulSet(有状态服务副本控制器)

K8S 中, Pod 分为两种,一个是有状态服务,通过 StatefulSet 副本控制器,一个是无状态服务,通过 RC Deployment DaemonSet RS Job 副本控制器控制。 K8S 中的中间级集群大多都是有状态服务 Pod kafka mysql hdfs 等集群。中间件集群的特点:
1 、每个节点有固定的身份 ID ,通过身份 ID ,集群中的成员可以相互通信,也就是说每
个中间件的 pod 是有顺序的,通常按照 0 1 2 3.... 递增
2 、集群规模是比较固定,不能随意变动
3 、集群的每个节点都是有状态大的,通常会持久化数据存储到永久存储 ETCD
4 、如果磁盘损坏,则集群的某个节点不可用,导致集群功能受损StatefulSet 特性:
1 StatefulSet 里每个 Pod 都有稳定、唯一的网络标识,用来发现集群内的其他节点,假设 StatefulSet 的名字叫做 Kafka ,真个 Kafka 集群的 pod ,都从 Kafka-0 Kafka-1 Kafka-2...
2 StatefulSet 的启停顺序是受控的,操作第 n Pod 时,前 n-1 Pod 已经是待运行状态
3 StatefulSet 里的 Pod 采用用稳定的持久化存储卷,通过 PV/PVC 来实现,删除 Pod 不会删除有状态服务 Pod 的存储卷

Service(服务)

Kubernetes Service 定义了一个服务的访问入口地址,前端的应用( Pod )通过这个入口地址访问其背后的一组由 Pod 副本组成的集群实例, Service 与其后端 Pod 副本集群之间则是通过 Label Selector 来实现 无缝对接 的 。而 RC 的作用实际上是保证 Service 的服务能力和服务质量始终处于预期的标准。通过 kubectl get service 可以查看。

Volumn(存储卷)

Volume Pod 中能够被多个容器访问的共享目录。 Kubemetes Volume 概念、用途和目的与 Docker Volume 比较类似,但两者不能等价 首先, Kubemetes 中的 volume 定义在 Pod上,然后被 Pod 里的多个容器挂载到具体的文件目录下;其次, Kubemetes 中的 Volume Pod的生命周期相同,但与容器的生命周期不相关,当容器终止或者重启时,Volum 中的数据也不会丢失。最后, Kubemetes 支持多种类型的 Volume ,例如 GlusterFS Ceph 等先进的分布式文件系统。可以通过查看 Pod 的资源对象去查看 Volume kubectl describe podName | grep Volume

Namespace(命名空间)

Namespace (命名空间〉是 kubenetes 系统中的另一个非常重要的概念, Namespace在很多情况下用于实现多租户的资源隔离。Namespace 通过将集群内部的资源对象 分配 ”到不同的 Namespace 中,形成逻辑上分组的不同项目、小组或用户组,便于不同的分组在共享使用整个集群的资源的同时还能被分别管理。可以简单将 Namespace 当成文件夹来看,当我们在创建资源对象时,可以指定这个文件属于那个文件夹,也就是 Namespace ,从而进行资源对象的一个种隔离、分组。kubernetes 在没有设置命名空间的资源对象,会将其放入default 空间中,系统自带的一些资源对象通常放置于 kube-system 空间中,通过 kubectl get namespace 可以查询出所有的命名空间。

Kubectl 常用基础,命令

查询所有 pod
kubectl get pod
查找指定 pod
kubectl get pod | grep podName
查看日志
kubectl logs podName
查看最新 500 行日志
kubectl logs –f –tail=500 podName
描述 pod
kubectl describe pod
podName
进入容器
kubectl exec -it podName sh
删除 pod
kubectl delete pod podName
删除所有 pod
kubectl delete pod --all
查看 pod 所在的运行节点 kubectl get pod –o wide
查看节点信息
kubectl get nodes
pod 扩容与缩容
kubectl scale deployment --replicas=2 podName
描述 node
kubectl describe nodes nodeName
获取集群节点信息
kubectl get nodes
获取集群状态
kubectl get cs
查看 k8s pod cpu , memory 使用率情况
kubectl top pod
查看 k8s node 节点实际 vm 节点使用情况
kubectl top node

Kubectl 非常用命令

创建 namespace
kubectl create namespace namespaceName
删除 namespace
kubectl delete namespace namespaceName
查询所有 namespace
kubectl get ns(kubectl get namespace)
查询所有 namespace 下的 pod
kubectl get pod –all-namespace
查询状态服务 pod ,即系统组件
kubectl get statefulsets

Pod 控制管理器管理的 pod(了解一下不同类型 pod 对应的控制管理器)

ReplicationController :第一代副本控制器,已暂停使用
ReplicaSet :新一代副本级控制器,不直接使用,集成至 Deployment 中使用,不用关注
Deployment :声明式更新的控制器,只能负责管理无状态的服务
StatefulSet :有状态副本级,负责管理有状态服务
DaemonSet :在每一个 node 节点运行一个副本,不能随意运行
Job,Ctonjob :运行周期化作业 Pod
在线镜像更新
查询微服务, kubectl get pod | grep podName
查看微服务的版本, kubectl describe pod podName | grep Image
更改镜像的 deployment 文件,
kubectl edit deployment podName( 不带标识 ID) ,然后更改 image
即可
查看这个 pod 是否启动, kubectl get pod | grep podName

离线环境下镜像更新

在镜像仓库拉取镜像:
1 、镜像拉取 docker pull image 地址
2 、镜像打包 docker save –o 镜像名字 .tar image 地址
3 、将微服务的 tar 包拷贝到离线私有云环境
4 、查询集群节点 IP
Kubectl get nodes
5 、将 tar scp 到其他集群节点
6 、在所有节点将 tar load 一下(集群节点都需要操作)
docker load –i tar
7 kubectl edit deployment podName ,然后更改 image docker load 之后的地址即可(还有
一种是修改微服务的配置文件例如: podName-deployment.json ,然后 kubectl apply –f
podNmae 重新创建 pod ),两种方式都可以

不重启 pod 开启微服务日志

该方法不通用,适用于 nodeJS 服务
Kubectl get pod | grep podName
Kubectl exec –it podName bash
进入 pod terminal 控制端
vi application.properties
修改 log.level=warn ,将 warn 改成其他日志级别
Kubectl get pod –o wide | grep podName
查询出微服务 pod 所在节点
ssh 微服务所在节点 IP
docker ps | grep podName
查询出 docker ID
docker restart docker ID
重启 docker container 容器, pod 容器不会重启
kubectl logs –f –tail=500 podName
打印日志

查询 mysql 数据库(通常由有状态副本级控制器控制StatefuSet

一般来说需要保存服务状态的都要做为系统组件的方式存在(即有状态 Pod
1 Kubectl exec –it podName (系统组件 mysql bash 2 、执行 ./mysql -uroot -proot 命令连接数据库
3 、所有数据库 show databases
4 、使用数据库 use 数据库名称
5 、所有表 show tables;

查询 mongodb 数据库(通常由有状态副本级控制器控制StatefuSet

k8s 集群环境, mongo 存储服务通常会配置 router 节点服务,负责路由分发,如果配
置了路由节点,则需要从路由节点进入容器内部
1 、进入容器 kubectl exec -it podName(router 节点 ) bash
2 、执行命令 mongo
3 、执行命令 use admin
4 、进行认证 db.auth(“name”,”password”)
5 、所有库 show dbs
6 、进入某一库: use 数据库名字
7 、所有集合 show collections
8 、查询某一集合的数据 db. 集合名 .find()

Rabbitmq 集群节点实例数修改(通常由有状态副本级控制器控制 StatefuSet

rabbitmq 节点上的 pod 实例修改为 0 kubectl scale statefulset podName --replicas=0
rabbitmq 节点上的 pod 实例修改为 1 kubectl scale statefulset podName --replicas=1

微服务实例数修改(无状态服务 pod 由声明式更新的控制器控制 Deployment)

Deployment 是声明式更新的副本控制器,负责管理无状态的应用服务
kubectl scale deployment --replicas=2 podName

添加微服务(原有的 deployment.json 文件不存在)

1 、 进入 deployment.json 的目录
2 、 创建一个 podName-deployment.json
3 、 最后 kubectl apply –f podName-deployment.json
欢迎加入测试交流群:夜行者自动化测试(816489363)进行交流学习QAQ