Kubernetes+docker 浅述
本文在收集了一些资料,加上自己的一些工作理解完成。参考书籍:kubernetes 权威指南。简单讲诉了一下 docker、k8s,为什么使用 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、提供容器弹性,如果容器失效就替换它
等等
K8S(kubernetes)集群又是啥?
首先我们要知道什么是集群?集群(
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