Kubernetes 是谷歌开源的容器集群管理系统,是 Google 多年大规模容器管理技术 Borg 的开源版本。其发展非常迅速,已经成为容器编排领域的领导者。
Kubernetes 是一个平台。它提供了很多的功能,可以简化应用程序的工作流,加快开发速度。通常,一个成功的应用编排系统需要有较强的自动化能力,这也是为什么 Kubernetes 被设计作为构建组件和工具的生态系统平台,以便更轻松地部署、扩展和管理应用程序。
用户可以使用 Label 以自己的方式组织管理资源,还可以使用 Annotation 来自定义资源的描述信息,比如为管理工具提供状态检查等。
此外,Kubernetes 控制器也是构建在跟开发人员和用户使用的相同的 API 之上。用户还可以编写自己的控制器和调度器,也可以通过各种插件机制扩展系统的功能。这种设计使得可以方便地在 Kubernetes 之上构建各种应用系统。
Kubernetes 主要由以下几个核心组件组成:
Kubernetes 包含如下资源对象:
名称 | 主要功能 | 其它 |
---|---|---|
Autoscaling (HPA) | 可以根据 CPU 使用率或应用自定义 metrics 自动扩展 Pod 数量(支持 replication controller、deployment 和 replica set ) | |
ConfigMap | ConfigMap 用于保存配置数据的键值对,可以用来保存单个属性,也可以用来保存配置文件。ConfigMap 跟 Secret 很类似,但它可以更方便地处理不包含敏感信息的字符串。 | |
CronJob | CronJob 即定时任务,就类似于 Linux 系统的 crontab,在指定的时间周期运行指定的任务。 | |
v1.7 新增的无需改变代码就可以扩展 Kubernetes API 的机制,用来管理自定义对象; v1.8 中已经弃用。 | ||
DaemonSet | DaemonSet 保证在每个 Node 上都运行一个容器副本,常用来部署一些集群的日志、监控或者其他系统管理应用。 | |
Deployment | Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义 (declarative) 方法,用来替代以前的 ReplicationController 来方便的管理应用。 | |
Ingress | Ingress 可以给 service 提供集群外部访问的 URL、负载均衡、SSL 终止、HTTP 路由等 | |
Job | Job 负责批量处理短暂的一次性任务 (short lived one-off tasks),即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束。 | |
LocalVolume | 本地数据卷(Local Volume)代表一个本地存储设备,比如磁盘、分区或者目录等。 | |
Namespace | Namespace 是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的 pod, service, replication controller 和 deployment 等都是属于某一个 namespace 的(默认是 default),而 node, persistent volume,namespace 等资源则不属于任何 namespace。 | |
NetworkPolicy | Network Policy 提供了基于策略的网络控制,用于隔离应用并减少攻击面。它使用标签选择器模拟传统的分段网络,并通过策略控制它们之间的流量以及来自外部的流量。 | |
Node | Node 是 Pod 真正运行的主机,可以是物理机,也可以是虚拟机。为了管理 Pod,每个 Node 节点上至少要运行 container runtime(比如 docker 或者 rkt)、kubelet 和 kube-proxy 服务。 | |
PersistentVolume | PersistentVolume (PV) 和 PersistentVolumeClaim (PVC) 提供了方便的持久化卷:PV 提供网络存储资源,而 PVC 请求存储资源。这样,设置持久化的工作流包括配置底层文件系统或者云数据卷、创建持久性数据卷、最后创建 PVC 来将 Pod 跟数据卷关联起来。PV 和 PVC 可以将 pod 和数据卷解耦,pod 不需要知道确切的文件系统或者支持它的持久化引擎。 | |
Pod | Pod 是一组紧密关联的容器集合,它们共享 IPC、Network 和 PID namespace,是 Kubernetes 调度的基本单位。Pod 的设计理念是支持多个容器在一个 Pod 中共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。 | |
PodPreset | PodPreset 用来给指定标签的 Pod 注入额外的信息,如环境变量、存储卷等。这样,Pod 模板就不需要为每个 Pod 都显式设置重复的信息。 | |
ReplicaSet | ReplicationController(也简称为 rc)用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的 Pod 来替代;而异常多出来的容器也会自动回收。ReplicationController 的典型应用场景包括确保健康 Pod 的数量、弹性伸缩、滚动升级以及应用多版本发布跟踪等。 在新版本的 Kubernetes 中建议使用 ReplicaSet(也简称为 rs)来取代 ReplicationController。ReplicaSet 跟 ReplicationController 没有本质的不同,只是名字不一样,并且 ReplicaSet 支持集合式的 selector(ReplicationController 仅支持等式)。 |
|
Resource Quota | 资源配额(Resource Quotas)是用来限制用户资源用量的一种机制。它的工作原理为: 资源配额应用在 Namespace 上,并且每个 Namespace 最多只能有一个 ResourceQuota 对象; 开启计算资源配额后,创建容器时必须配置计算资源请求或限制(也可以用 LimitRange 设置默认值);用户超额后禁止创建新的资源 | |
Secret | Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec 中。Secret 可以以 Volume 或者环境变量的方式使用。 | |
SecurityContext | Security Context 的目的是限制不可信容器的行为,保护系统和其他容器不受其影响。 | |
Service | Service 是对一组提供相同功能的 Pods 的抽象,并为它们提供一个统一的入口。借助 Service,应用可以方便的实现服务发现与负载均衡,并实现应用的零宕机升级。Service 通过标签来选取服务后端,一般配合 Replication Controller 或者 Deployment 来保证后端容器的正常运行。这些匹配标签的 Pod IP 和端口列表组成 endpoints,由 kube-proxy 负责将服务 IP 负载均衡到这些 endpoints 上。 | |
ServiceAccount | Service account 是为了方便 Pod 里面的进程调用 Kubernetes API 或其他外部服务而设计的。 | |
StatefulSet | StatefulSet 是为了解决有状态服务的问题(对应 Deployments 和 ReplicaSets 是为无状态服务而设计),其应用场景包括:稳定的持久化存储;稳定的网络标志;有序部署,有序扩展;有序收缩,有序删除。 | |
Volume | 默认情况下容器的数据都是非持久化的,在容器消亡以后数据也跟着丢失,所以 Docker 提供了 Volume 机制以便将数据持久化存储。类似的,Kubernetes 提供了更强大的 Volume 机制和丰富的插件,解决了容器数据持久化和容器间共享数据的问题。 与 Docker 不同,Kubernetes Volume 的生命周期与 Pod 绑定:容器挂掉后 Kubelet 再次重启容器时,Volume 的数据依然还在;而 Pod 删除时,Volume 才会清理。数据是否丢失取决于具体的 Volume 类型,比如 emptyDir 的数据会丢失,而 PV 的数据则不会丢。 |
存在的意义
pod 为亲密性应用而存在,应用场景:
1)两个应用之间发生文件交互;
2)两个应用需要通过127.0.0.1 或 socket 通信;
3)两个应用需要发生频繁的调用;
实现机制
Pod 天生地为其成员容器提供了两种共享资源:网络和 存储。
k8s 中每创建一个pod,都会创建基于 registry.aliyuncs.com/google_containers/pause:3.2 镜像的容器(infra容器),该容器创建一个网络命名空间, pod 内的其它容器都会加入该命名空间,从而实现了 pod内其它容器共享网络资源;
此处创建一个 deployment 包含nginx 和flask-app, 进入容器内部发现2者的ip a 信息是一样的(nginx 默认没有ip命令,需要 apt-get install iproute2 安装); 进一步可以通过netsta 查看,发现在如何容器内部都可以看到2个容器的端口信息; 其原因是它们具有相同的网络协议栈,共享网络资源。
deployment 包括2个容器:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: my-web
name: my-web
spec:
replicas: 1
selector:
matchLabels:
app: my-web
template:
metadata:
labels:
app: my-web
spec:
containers:
- image: nginx
name: nginx
- image: ubuntu_flask:v1.0
name: flask-app
imagePullPolicy: IfNotPresent
同样,一个pod内的容器可以通过volume的方式共享数据,以下定义了一pod,write向/data/hello 中写数据, read 从/data/hello中读数据;
通过 kubectl apply -f my-os.yaml 起pod后,就可以查看容器中的数据了;
apiVersion: v1
kind: Pod
metadata:
name: my-os
namespace: test-online
spec:
containers:
- image: ubuntu:20.04
name: write
command: ["bash", "-c", "for i in {1..100};do echo $i >>/data/hello;sleep 1;done"]
volumeMounts:
- mountPath: /data
name: test-data
- image: ubuntu:20.04
name: read
command: ["bash", "-c", "tail -f /data/hello"]
volumeMounts:
- mountPath: /data
name: test-data
volumes:
- name: test-data
emptyDir: {}
pod template常见字段
pod 模板中常用字段段包括:变量(env),拉取镜像(image),资源限制(resource),监控检查(readinessProbe, livenessProbe);
功能及应用场景
pod 与controlers关系
deployment 功能场景
使用deploment部署java应用
控制器定义:apiVersion,kind,metadata,spec
被控制对象:template{metadata,spec}
kubectl create deployment --help
kubectl create deployment web --image=nginx --dry-run -o yaml(或者web.yaml)
kubectl create deployment test-nginx --image=nginx --dry-run -o yaml > test-nginx.yaml
然后更改对应的参数和image即可;
kubectl apply -f test-nginx.yaml
使用service 和 ingress 暴露出应用;
kubectl expose deployment test-nginx --port=80 --target-port=80 --type=NodePort -o yaml --dry-run >svc-test-nginx.yaml (第二个端口80为pod中服务端口)
kubectl apply -f svc-test-nginx.yaml
kubectl get service
查看创建的pod:
# kubectl get pods,svc
NAME READY STATUS RESTARTS AGE
pod/nginx-554b9c67f9-jbclt 1/1 Running 3 4d19h
pod/test-nginx-76b4548894-w4qft 1/1 Running 0 5m58s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d20h
service/nginx NodePort 10.96.136.149 <none> 80:32063/TCP 4d19h
service/test-nginx NodePort 10.104.136.169 <none> 80:31400/TCP 29s
此时使用 http://192.168.2.134:31400/即可访问test-nginx服务了
应用升级、回滚、弹性伸缩
升级:
kubectl set image xxx
回滚:
kubectl rollout history|undo xxx
删除:
kubectl delete deployment
弹性伸缩:
kubectl scale deployment web --replicas=5
service 存在的意义
service 类型
service NodePort 对外暴露应用,其在每个node上启一个端口,通过nodeip:port 即可访问;
LB 多用于在共有云上部署k8s,通过LB实现负载均衡;
kubenetes 指南
1 天入门Kubernetes/K8S
k8s 中文官方文档
k8s 英文官方文档