容器编排 -- Job
编排对象
在线业务:Deployment、StatefulSet、DaemonSet
离线业务:Job、CronJob
Jobjob.yaml
Job对象不需要定义spec.selector(借助UUID)
job.yaml12345678910111213141516apiVersion: batch/v1kind: Jobmetadata: name: pispec: template: spec: containers: - name: pi image: resouer/ubuntu-bc command: - sh - '-c' - "echo 'scale=10000; 4*a(1)' | bc -l" restartPolicy: Never backoffLimit: 4
创建Job123456# kubectl apply -f job.yamljob.batch/pi cre ...
容器编排 -- DaemonSet
Daemon Pod特征
运行在Kubernetes集群的每个Node上
每个Node有且仅有一个Daemon Pod
新Node加入Kubernetes集群,Daemon Pod会自动在新Node上被创建
旧Node被删除后,上面的Daemon Pod也会被回收
场景
网络插件的Agent组件
存储插件的Agent组件
监控组件 + 日志组件
工作原理
循环控制:遍历所有Node,根据Node上是否有被管理Pod的情况,来决定是否需要创建或者删除Pod
DaemonSet在创建每个Pod时,做了两件额外的事情
自动给这个Pod加上一个nodeAffinity,来保证该Pod只会在指定节点上启动
自动给这个Pod加上一个Toleration,从而忽略Node上的unschedulable污点
API Object
该DaemonSet管理的是一个fluentd-elasticsearch镜像的Pod
fluentd-elasticsearch:通过fluentd将Docker容器里的日志转发到ElasticSearch
DaemonSet与Deployment非常类似,只是DaemonSet没有 ...
容器编排 -- StatefulSet(原理)
背景
Deployment的短板:Deployment认为一个应用的所有Pod,是完全一样的
有状态应用(Stateful Application)
实例之间有不对等的关系 – 拓扑
实例对外部数据有依赖关系 – 存储
StatefulSet
Kubernetes在Deployment的基础上,扩展出对有状态应用的初步支持
StatefulSet是Kubernetes在作业编排的集大成者
状态抽象
分类
拓扑状态:应用的多个实例之间是不完全对等的关系
存储状态:应用的多个实例分别绑定了不同的存储数据
核心功能:通过某种方式记录状态,然后在Pod被重新创建时,能够为新Pod恢复这些状态
设计思想
StatefulSet是一种特殊的Deployment,独特之处:为每个Pod编号(代表创建顺序、网络标识等)
编号 + Headless Service ==> 拓扑状态
编号 + Headless Service + PV/PVC ==> 存储状态
拓扑状态
StatefulSet控制器使用Pod模板创建Pod时,对它们进行编号,并 ...
容器编排 -- Deployment
基本概念
Deployment实现了Pod的水平伸缩(horizontal scaling out/in) – 滚动更新(rolling update)
滚动更新依赖于ReplicaSet
Deployment控制ReplicaSet(版本),ReplicaSet控制Pod(副本数)!!
ReplicaSet
ReplicaSet的定义是Deployment的一个子集
Deployment控制器实际操纵对象是ReplicaSet,而非Pod,Deployment所管理的Pod的ownerReference为ReplicaSet
12345678910111213141516171819apiVersion: apps/v1kind: ReplicaSetmetadata: name: nginx-set labels: app: nginxspec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: ...
容器编排 -- 控制器模型
控制器
kube-controller-manager是一系列控制器的集合,每一种控制器都以独有的方式负责某种编排功能
1234567# cd kubernetes/pkg/controller# ls -d */apis/ cronjob/ endpoint/ history/ nodelifecycle/ replication/ storageversiongc/ util/bootstrap/ daemon/ endpointslice/ job/ podautoscaler/ resourcequota/ testutil/ volume/certificates/ deployment/ endpoint ...
容器编排 -- Pod
基本概念
在Kubernetes中,Pod是一等公民
Pod是Kubernetes的原子调度单位,Kubernetes统一按照Pod(而非容器)的资源需求进行计算
容器的本质是进程
容器的单进程模型
并不是指容器里只能运行一个进程,而是指容器没有管理多个进程的能力
原因
容器里PID=1的进程是应用本身,其它进程都是PID=1进程的子进程
用户编写的应用,并不能像正常OS里面的init进程或者systemd进程那样拥有进程管理的功能
容器间具有『超亲密关系』的典型特征
互相之间会发生直接的文件交换
使用localhost或者Socket文件进行本地通信
会发生非常频繁的远程调用
需要共享某些Linux Namespace
并不是所有有关系的容器都属于同一个Pod,如Java应用容器和MySQL更适合做成两个Pod
Pod在Kubernetes中的重要意义 – 容器设计模式
实现原理
Pod只是一个逻辑概念
Kubernetes真正处理的,还是宿主机上Linux容器的Namespace和Cgroups,并不存在所谓的Pod的边界或者隔离环境
Pod里的所有容器,共享的是 ...
Kubernetes -- 集群搭建 & 应用容器化
kubeadm安装1$ apt-get install kubeadm
步骤12345# 创建一个Master节点$ kubeadm init# 将一个Worker节点加入到当前集群中$ kubeadm join <Master节点的IP和端口>
工作原理
直接容器化kubelet会面临很多问题,所以把kubelet直接运行在宿主机上,然后使用容器部署其它的Kubernetes组件
工作流程kubeadm initPreflight Checks
进行一系列的检查工作,确保该机器可以用来部署Kubernetes
Linux内核版本 ≥ 3.10
Linux Cgroups模块可用
机器的hostname标准(符合标准的DNS命名)
kubeadm与kubelet的版本匹配
机器上已经安装了Kubernetes的二进制文件
Kubernetes的工作端口(10250/10251/10252)没有被占用
ip、mount等Linux指令存在
Docker已经安装
生成证书
生成Kubernetes对外提供服务所需的各种证书和对应的目录
Kubernetes对外提供服 ...
Kubernetes -- 架构 & 设计思想
容器
本质:由Linux Namespace、Linux Cgroups和rootfs三种技术构建出来的进程的隔离环境
容器的视图
静态视图(Container Image):一组联合挂载在/var/lib/docker/aufs/mnt上的rootfs
动态视图(Container Runtime):由Namespace+Cgroups构成的隔离环境
开发人员并不关心Container Runtime的差异,因为承载容器信息进行传递的,是Container Image
Kubernetes架构
角色:Master(控制节点)、Node(计算节点)
Master
kube-apiserver:负责API服务,整个集群的持久化数据,由kube-apiserver处理后保存在Etcd中
kube-scheduler:负责调度
kube-controller-manager:负责容器编排
Node:kubelet,为最核心的组件
CRI,Container Runtime Interface
主要负责与Container Runtime打交道
只要Container Runtime能够运行标准的Co ...
容器基础 -- Docker容器
文件12# lsapp.py Dockerfile requirements.txt
app.py1234567891011121314from flask import Flaskimport socketimport osapp = Flask(__name__)@app.route('/')def hello(): html = "<h3>Hello {name}!</h3>" \ "<b>Hostname:</b> {hostname}<br/>" return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname())if __name__ == "__main__": app.run(host='0.0.0.0', port=8 ...
容器基础 -- rootfs
环境12345678# cat /etc/issueUbuntu 16.04.7 LTS \n \l# uname -aLinux ubuntu1604 4.4.0-186-generic #216-Ubuntu SMP Wed Jul 1 05:34:05 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux# docker --versionDocker version 18.03.1-ce, build 9ee9f40
12345678910# grep aufs /proc/filesystemsnodev aufs# cat /etc/docker/daemon.json{ "storage-driver": "aufs"}# docker info | grep 'Storage Driver'Storage Driver: aufs
Mount Namespace创建子进程时开启Namespace
123456789101112131415161718192021222324 ...