K8s入门知识详解

1.Kubernetes架构

k8s的物理架构是master/node模式:

K8S集群至少需要一个主节点(Master)和多个工作节点(Worker),Master节点是集群的控制节点,负责整个集群的管理和控制,主要用于暴露API、调度部署和对节点进行管理。工作节点主要是运行容器的。

单master节点架构图如下:

image-20220501233822602

多master节点架构图如下:

image-20220501233930188

2.kubernetes组件

Master node:

  • apiserver

  • scheduler

  • controller-manager

  • Etcd

  • calico

  • docker

Work node:

  • kubelet

  • kube-proxy

  • Calico

  • Coredns

  • docker

image-20220501234113763

kubectl:管理k8s的命令行工具,可以操作k8s中的资源对象,如增删改查等。

etcd: 是一个高可用的键值数据库,存储k8s的资源状态信息和网络信息的,etcd中的数据变更是通过api server进行的。

apiserver: 提供k8s api,是整个系统的对外接口,提供资源操作的唯一入口,供客户端和其它组件调用,提供了k8s各类资源对象(pod,deployment,Service等)的增删改查,是整个系统的数据总线和数据中心,并提供认证、授权、访问控制、API注册和发现等机制,并将操作对象持久化到etcd中。

scheduler:负责k8s集群中pod的调度的 , scheduler通过与apiserver交互监听到创建Pod副本的信息后,它会检索所有符合该Pod要求的工作节点列表,开始执行Pod调度逻辑。调度成功后将Pod绑定到目标节点上,相当于“调度室”。

Controller-Manager:作为集群内部的管理控制中心,负责集群内的Node、Pod副本、服务端点(Endpoint)、命名空间(Namespace)、服务账号(ServiceAccount)、资源定额(ResourceQuota)的管理,当某个Node意外宕机时,Controller Manager会及时发现并执行自动化修复流程,确保集群始终处于预期的工作状态。

image-20220501234239797

每个Controller通过API Server提供的接口实时监控整个集群的每个资源对象的当前状态,当发生各种故障导致系统状态发生变化时,会尝试将系统状态修复到“期望状态

kubelet: 每个Node节点上的kubelet定期就会调用API Server的REST接口报告自身状态,API Server接收这些信息后,将节点状态信息更新到etcd中。kubelet也通过API Server监听Pod信息,从而对Node机器上的POD进行管理,如创建、删除、更新Pod

kube-proxy:提供网络代理和负载均衡,是实现service的通信与负载均衡机制的重要组件,kube-proxy负责为Pod创建代理服务,从apiserver获取所有service信息,并根据service信息创建代理服务,实现service到Pod的请求路由和转发,从而实现K8s层级的虚拟转发网络,将到service的请求转发到后端的pod上。

Cordns:CoreDNS 其实就是一个 DNS 服务,而 DNS 作为一种常见的服务发现手段,很多开源项目以及工程师都会使用 CoreDNS 为集群提供服务发现的功能,Kubernetes 就在集群中使用 CoreDNS 解决服务发现的问题。

Calico: 是一套开源的网络和网络安全方案,用于容器、虚拟机、宿主机之前的网络连接,可以用在kubernetes、OpenShift、DockerEE、OpenStrack等PaaS或IaaS平台上。

Docker:容器运行时,负责启动容器的,在k8s1.20版本之后建议废弃docker,使用container作为容器运行时

3.kubernetes核心资源解读

3.1 Pod

Pod是Kubernetes中的最小调度单元,k8s是通过定义一个Pod的资源,然后在Pod里面运行容器,容器需要指定镜像,用来运行具体的服务。Pod代表集群上正在运行的一个进程,一个Pod封装一个容器(也可以封装多个容器),Pod里的容器共享存储、网络等。也就是说,应该把整个pod看作虚拟机,然后每个容器相当于运行在虚拟机的进程。

白话解释:

可以把pod看成是一个“豌豆荚”,里面有很多“豆子”(容器)。一个豌豆荚里的豆子,它们吸收着共同的营养成分、肥料、水分等,Pod和容器的关系也是一样,Pod里面的容器共享pod的网络、存储等。

image-20220501234615648

如何创建一个Pod资源?

在K8s中,所有的资源都可以使用一个yaml配置文件来创建,创建Pod也可以使用yaml配置文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
root@xianchaomaster1 ~]# cat pod.yaml

apiVersion: v1
kind: Pod
metadata:
name: tomcat-pod
namespace: default
labels:
tomcat: tomcat-pod
spec:
containers:
- name: tomcat-pod-java
ports:
- containerPort: 8080
image: tomcat:8.5-jre8-alpine
imagePullPolicy: IfNotPresent

[root@xianchaomaster1 ~]# kubectl apply -f pod.yaml
[root@xianchaomaster1 ~]# kubectl get pods -l tomcat=tomcat-pod

image-20220501234742170

3.2 Label

label是标签的意思,k8s中的资源对象大都可以打上标签,如Node、Pod、Service 等,一个资源可以绑定任意多个label,k8s 通过 Label 可实现多维度的资源分组管理,后续可通过 Label Selector 查询和筛选拥有某些 Label 的资源对象,例如创建一个 Pod,给定一个 Label是app=tomcat,那么service可以通过label selector选择拥有app=tomcat的pod,和其相关联,也可通过 app=tomcat 删除拥有该标签的 Pod 资源。

image-20220501234829189

3.3 Deployment

Replicaset是Kubernetes中的副本控制器,管理Pod,使pod副本的数量始终维持在预设的个数。

Deployment是管理Replicaset和Pod的副本控制器,Deployment可以管理多个Replicaset,是比Replicaset更高级的控制器,也即是说在创建Deployment的时候,会自动创建Replicaset,由Replicaset再创建Pod,Deployment能对Pod扩容、缩容、滚动更新和回滚、维持Pod数量。

image-20220501234955054

如何创建一个Deployment资源?

在K8s中,所有的资源都可以使用一个yaml配置文件来创建,创建Deployment也可以使用yaml配置文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
cat deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80

[root@xianchaomaster1 ~]# kubectl apply -f deployment.yaml
[root@xianchaomaster1 ~]# kubectl get deploy | grep my-nginx
my-nginx 2/2 2 2 2m52s
[root@xianchaomaster1 ~]# kubectl get rs | grep my-nginx
my-nginx-5b56ccd65f 2 2 2 3m26s
[root@xianchaomaster1 ~]# kubectl get pods -l run=my-nginx

3.4 Service

在kubernetes中,Pod是有生命周期的,如果Pod重启IP很有可能会发生变化。如果我们的服务都是将Pod的IP地址写死,Pod的挂掉或者重启,和刚才重启的pod相关联的其他服务将会找不到它所关联的Pod,为了解决这个问题,在kubernetes中定义了service资源对象,Service 定义了一个服务访问的入口,客户端通过这个入口即可访问服务背后的应用集群实例,service是一组Pod的逻辑集合,这一组 Pod 能够被 Service 访问到,通常是通过 Label Selector实现的。

可以看下面的图:

image-20220501235148950

如何创建一个Service资源?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#创建一个pod
cat pod_test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80

#创建一个service
cat service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx

[root@xianchaomaster1 ~]# kubectl apply -f service.yaml
[root@xianchaomaster1 ~]# kubectl get svc -l run=my-nginx

image-20220501235605445

1
[root@xianchaomaster1 ~]# curl 10.105.104.137

image-20220501235633189