前言
本文不保证正确性,纯属个人入门笔记
Kubernetes 是一个开源容器编排引擎,用于容器化应用的自动化部署、扩展和管理
随着云时代的到来,各大厂商也都将服务部署在云上了。
k8s作为Google开源的一个容器编排工具,也被国内外不少厂商实践并投入生产使用。随之也催生出了一系列CNCF的云应用,也加速了Go语言的发展。
全面上云,感觉也是个发展的大趋势把,菜如我只能先了解一些基本概念吧…
基本概念
Pod
k8s中最小的调度以资源单元。pod是一个或一组容器的集合。
同一个pod中的容器共享存储、网络、以及怎样运行这些容器的声明 。
相当于一个逻辑主机,同个pod中的不同容器共享网络和上下文资源。
形象来说就是同一组pod中的容器所看到的网络设备、自身的ip地址都是相同的,可以直接通过localhost进行通信。
更加哲学一点的说法就是容器相当于一个进程,而Pod类似于一个进程组,这些进程会共享/同步一些资源,从而协作变成一个统一提供服务的进程组(当然,不需要多个进程的时候,这个进程组中就一个进程,也就只有一个容器)。
Volumne
就是docker中的数据卷,用来管理k8s中的存储。
一个volumne可以被挂载在一个或多个pod的路径中。
volumne其实是一个存储层的抽象,后面实际的实现可以是一些本地存储、分布式存储、云存储之类。
Deployment
Deployment 是在 Pod 这个抽象上更为上层的一个抽象,它可以定义一组 Pod 的副本数目、以及这个 Pod 的版本。
k8s会通过Contorller去维护一个Deployment的状态,例如一些pod的自动恢复,一些版本的升级与回滚。
Service
Kubernetes
Service
定义了这样一种抽象:逻辑上的一组Pod
,一种可以访问它们的策略 —— 通常称为微服务。
一组pod的抽象,因为对于用户来说,这一组pod都提供的是同一个服务,就可以把这些pod抽象成一个service。
通过LoadBalancer等方式,相当于对内pod提供了层负载均衡代理,对外用户只要访问指定的service就能被代理到指定服务,而无需关心具体pod。
Namespace
Namespace 是用来做一个集群内部的逻辑隔离的,它包括鉴权、资源管理等。
默认为default,例如一些部门之间的容器隔离和一些权限控制,都可以通过namespace来操作,也解决了一些命名重复的问题。
ReplicaSet
ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。 然而,Deployment 是一个更高级的概念,它管理 ReplicaSet,并向 Pod 提供声明式的更新以及许多其他有用的功能。
ReplicaSet对应Deployment template的一个版本。
由Deployment管理ReplicaSet,ReplicaSet管理具体的Pod副本。
例如修改了Deployment中的template,升级了应用的版本,那Deployment则会生成一个新的ReplicaSet。
旧的ReplicaSet删除原先的pod,新的ReplicaSet生成新的pod。
Job
管理任务的控制器。
Job 会创建一个或多个Pod,并确保指定数量的Pod成功终止。
可以跟踪Pod状态,及时重试,以及保证任务执行的循序关系。
还有对应的CronJob,支持定时任务,可以根据cron语法进行定义
DaemonSet
DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。当有节点加入集群时, 也会为他们新增一个 Pod 。当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
例如一些日志收集、和监控的组件,都可以通过DaemonSet的方式进行创建,从而在每个节点上做一个日志收集、监控的操作。
API
交互格式
用户与master交互的方式有两种,一个是通过ui界面操作,还有一个就是通过kubectl进行操作。
但实际上两种的本质都是通过HTTP协议进行传输,格式为JSON/YAML。
例如对某个namespace的某个pod进行操作的url如下。
1 | /api/v1/namespaces/$NAMESPACE/pods/$NAME |
又或者我们通过apply -f
创建pod时,指定的yaml格式如下。
里面分别对应了对这个资源描述的几个部分
- apiVersion:api的版本信息
- kind:资源信息
- metadata:定义name,以及打一些lable或者其他描述
- spec:期望状态,例如这里指定了container的名字、镜像信息以及对应的端口
- status:获取资源信息时服务端返回的信息,显示资源的状态
一些字段含义
本来想整理下语法的,后来越整理越多,而且感觉很多对入门选手没太多必要,就挑了几个常见的记录下。
如果想看完整的可以看 https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/ ,对每一个应用都给出了对应的样例,并且介绍了每个字段的含义。
1、lable
一组Key/Value键值对,相当于对当前pod打上标签。
通过selector我们可以选择指定标签的pod,支持一些逻辑条件。
例如Deployment和Service创建时选择指定的pod,就可以通过lable来选择想要的pod。
2、selector
选择器,Deployment和Service创建时选择指定的pod,就可以通过matchLabels的方式选择特定lable的pod。
3、replicas
期望达到的pod数量。例如Deployment创建时期望达到的一个指定的pod数量。
4、template
描述将要被创建的pod的模板。在Deployment创建时指定其生成pod的模板。
5、revisionHistoryLimit
历史ReplicaSet的版本数,默认为10
yaml文件样例
对应一些具体的yaml文件可能会更好理解一些
deployment.yaml
1 | apiVersion: apps/v1 |
service.yaml
1 | apiVersion: v1 |
daemonset.yaml
1 | apiVersion: apps/v1 |
job.yaml
1 | apiVersion: batch/v1 |
kubectl指令
kubectl是用户与master节点进行通信的cli,完整的指令文档在 https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands
我就只介绍几个常见的命令操作
基本的命令格式如下
1 | kubectl [command] [TYPE] [NAME] [flags] |
常见的command操作有
create
: 创建资源get
: 获取资源信息describe
:获取特定资源的详细描述delete
: 删除资源
例如
1 | kubectl get nodes // 获取nodes节点信息 |
简写风格
kubectl还支持一部分简写,例如pod和pods,deployment和deployments其实是不区分的。
不仅如此,还有更大幅度的简写
- pods : po
- namespace : ns
- nodes : no
- services : svc
- deployments : deploy
输出选项
-o
、--ouput
参数 可支持格式化输出
-o wide
纯文本输出,但包含的信息内容更多-o name
仅输出名字-o yaml
yaml格式输出-o json
json格式输出
k8s组件
基本架构,我们主要通过cli或者web ui的方式去操控master节点(或者说是向master节点发送请求),再由master节点来总的管理我们的node节点。
Master组件
kube-apiserver
主节点上负责提供 Kubernetes API 服务的组件;它是 Kubernetes 控制面的前端。
别的组件都会与apiserver进行交互,相当于master中一个总的操作中心。
controller-manager
对集群状态的管理,比如一些扩缩容和一些修复之类的操作。
在文档中还分为kube-controller-manager和云控制器管理器-(cloud-controller-manager)。
kube-scheduler
相当于一个调度器,对目前拥有的资源的调度。
例如要创建一个pod时,scheduler就会选择一个合适的node节点来创建pod。
etcd
etcd 是兼具一致性和高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库。
一个分布式存储系统,存放一些k8s所需的元信息。
etcd也不仅可用于k8s,也可以用于一些服务发现的场景。
Node组件
kubelet
一个在集群中每个节点上运行的代理。它保证容器都运行在 Pod 中。
与master中的kube-apiserver做交互的组件,接受master发送的消息,然后做对应处理。
个人理解相当于node中的apiserver。
kube-proxy
kube-proxy是集群中每个节点上运行的网络代理,实现 Kubernetes Service概念的一部分。
kube-proxy 维护节点上的网络规则。这些网络规则允许从集群内部或外部的网络会话与 Pod 进行网络通信。
相当于一个流量的代理层,用于后续将一系列node节点在网络层面结合成一个总的service。
Container Runtime
容器运行环境是负责运行容器的软件。
真正实际运行容器的部分,这里的容器不仅限于Docker。
Addons
网络和存储的一些管理并不由k8s直接操作。
一般会由云厂商,或者k8s的使用方来描述如果做网络与存储的操作。
就可以通过插件的形式,来告诉k8s具体如何去做网络与存储之类的操作。
(文档中还有提到一些ui,资源监控的插件)
一次pod创建过程
可以来看下一次pod创建过程中,这些组件是如何相互协调工作的。
1、用户通过cli或者ui向master节点提交一次pod创建的请求。
2、master节点中的api-server接受到请求之后,将创建请求写入etcd中。
3、scheduler通过 watch 或者叫做 notification 机制从api-server中得到一个pod需要被创建的消息。
4、scheduler根据将被创建的pod资源进行一次决策,决定改pod在哪个node中被创建,并将消息发送个api-server。
5、api-server将要创建的信息存入etcd中,并将创建信息发送给对应的node节点。
6、node节点中的kubelet接受到创建node的消息之后,通过container runtime实际去启动容器,并调用所需的插件。
未授权访问利用
k8s的master节点上会暴露kube-apiserver,默认情况下会开启两个HTTP端口
1)本地主机端口
- HTTP服务
- 默认端口8080,修改标识–insecure-port
- 默认IP是本地主机,修改标识—insecure-bind-address
- 在HTTP中没有认证和授权检查
- 主机访问受保护
2)Secure Port
- 默认端口6443,修改标识—secure-port
- 默认IP是首个非本地主机的网络接口,修改标识—bind-address
- HTTPS服务。设置证书和秘钥的标识,–tls-cert-file,–tls-private-key-file
- 认证方式,令牌文件或者客户端证书
- 使用基于策略的授权方式
之前也提到过,可以通过ui接口进行管理和配置k8s。如果ui接口可以被我们未授权访问的话,我们就可以利用它来搞一些事情。
直接访问会返回可用的API列表
看别人的说法是访问/ui
就可以到对应的dashboard界面,我这边是用minikube起的,貌似有些差异,访问的是/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
但问题不大
我们通过ui界面创建一个pod,并将本地根目录挂载到pod的/mnt目录中
创建Pod的yaml1
2
3
4
5
6
7
8
9
10
11
12
13
14
15apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- image: nginx:1.7.9
name: container
volumeMounts:
- mountPath: /mnt
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /
这样,过一会之后就能看到我们创建的myapp Pod以及run起来了
通过右上角进入Pod的shell控制台
这样,进入挂载好的/mnt目录中,就是master节点的对应目录了
后面写cron之类的操作就不演示了。
kubectl也可以通过-s http://master-hostname:port
的方式来连接特定的未授权访问端口。
但是想exec执行命令时却被Forbidden了,不知道是我环境问题,还是k8s策略的原因
其余的未授权访问之类的还有如下,链接中也有比较详细的利用方式 https://www.freebuf.com/vuls/196993.html
- etcd 2379端口:默认通过证书认证,主要存放节点的信息,如一些token和证书。
- kubelet 10250端口:默认也是通过证书认证,与master节点交互的端口,如果可以利用可以直接控制该node的所有pod。
- docker rest-api 2375端口:其实和k8s关系不大,主要是docker服务的rest接口。
References
https://kubernetes.io/zh/docs/home/
https://edu.aliyun.com/roadmap/cloudnative
https://www.bilibili.com/video/av85429526
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/
https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands
https://www.freebuf.com/vuls/196993.html
https://www.mls-tech.info/docker/k8s-installation-on-ubuntu1804/