kubernetes

Introduction

Overview

Kubernetes is a portable, extensible, open source platform for managing containerized workloads and services, that facilitates both declarative configuration and automation. It has a large, rapidly growing ecosystem. Kubernetes services, support, and tools are widely available.

  • When you deploy Kubernetes, you get a cluster.
  • A Kubernetes cluster consists of a set of worker machines, called nodes, that run containerized applications.
  • Every cluster has at least one worker node.

Components

This document outlines the various components you need to have for a complete and working Kubernetes cluster.

Control Plane components

kube-api server

The API server is the front end for the Kubernetes control plane.

The main implementation of a Kubernetes API server is kube-apiserver. kube-apiserver is designed to scale horizontally—that is, it scales by deploying more instances. You can run several instances of kube-apiserver and balance traffic between those instances.

Horizontal scaling vs Vertical scaling:

水平扩展

是通过增加或减少工作负载的实例数量来调整资源的过程。在 Kubernetes 中,这通常是通过增加或减少 Pod 的副本数量来实现的。例如,如果一个应用程序的负载增加,可以增加 Pod 的数量来分散负载。这通常是通过使用 Kubernetes 的 Horizontal Pod Autoscaler (HPA) 来自动完成的,HPA 根据 CPU 利用率或其他选择的度量标准来自动调整 Pod 的数量。
水平扩展通常适用于无状态应用程序,因为增加的实例可以独立处理请求,不需要访问共享资源。

垂直扩展

是通过增加或减少单个实例的资源(如 CPU 或内存)来调整资源的过程。在 Kubernetes 中,这通常是通过增加或减少 Pod 的资源限制和请求来实现的。

例如,如果一个应用程序的性能受到 CPU 或内存的限制,可以增加 Pod 的 CPU 或内存资源来提高性能。

垂直扩展通常适用于有状态应用程序,因为这些应用程序通常需要访问共享资源,而且可能不容易在多个实例之间分散负载。

etcd

Consistent and highly-available key value store used as Kubernetes’ backing store for all cluster data. If your Kubernetes cluster uses etcd as its backing store, make sure you have a back up plan for the data.

Kube-scheduler

Control plane component that watches for newly created Pods with no assigned node, and selects a node for them to run on. Factors taken into account for scheduling decisions include: individual and collective resource requirements, hardware/software/policy constraints, affinity and anti-affinity specifications, data locality, inter-workload interference, and deadlines.

Kube-controller-manager

Control plane component that runs controller processes. Logically, each controller is a separate process, but to reduce complexity, they are all compiled into a single binary and run in a single process.

Some types of these controllers are:

  • Node controller: Responsible for noticing and responding when nodes go down.
  • Job controller: Watches for Job objects that represent one-off tasks, then creates Pods to run those tasks to completion.
  • EndpointSlice controller: Populates EndpointSlice objects (to provide a link between Services and Pods).
  • ServiceAccount controller: Create default ServiceAccounts for new namespaces.

Cloud-controller-manager

A Kubernetes control plane component that embeds cloud-specific control logic. The cloud controller manager lets you link your cluster into your cloud provider’s API, and separates out the components that interact with that cloud platform from components that only interact with your cluster.

Node Components

Kubelet

An agent that runs on each node in the cluster. It makes sure that containers are running in a Pod.

Kube-proxy

kube-proxy is a network proxy that runs on each node in your cluster, implementing part of the Kubernetes Service concept.

Container-runtime

The container runtime is the software that is responsible for running containers.

Addons

Addons use Kubernetes resources (DaemonSet, Deployment, etc) to implement cluster features. Because these are providing cluster-level features, namespaced resources for addons belong within the kube-system namespace.

DNS

While the other addons are not strictly required, all Kubernetes clusters should have cluster DNS, as many examples rely on it.

Web-UI(Dashboard)

Dashboard is a general purpose, web-based UI for Kubernetes clusters. It allows users to manage and troubleshoot applications running in the cluster, as well as the cluster itself.

Container Resource Monitoring

Container Resource Monitoring records generic time-series metrics about containers in a central database, and provides a UI for browsing that data.

Cluster-level Logging

A cluster-level logging mechanism is responsible for saving container logs to a central log store with search/browsing interface.

Network Plugins

Network plugins are software components that implement the container network interface (CNI) specification. They are responsible for allocating IP addresses to pods and enabling them to communicate with each other within the cluster.

Elementary

0.基础

A cluster is made by nodes(master node and worker nodes), Master is used to managed the cluster. Worker节点是虚拟机或物理计算机,充当k8s集群中的工作计算机。 每个Worker节点都有一个Kubelet,它管理该Worker节点并负责与Master节点通信。该Worker节点还应具有用于处理容器操作的工具,例如Docker。

A node is made by pods

Pod is created by deployment, you can specify how many replicas you want. You can use deployment to manage these pods replicas.

A pod is made by containers.

1.部署一个应用程序

首先得创建一个yaml文件,里面包含了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: apps/v1	#与k8s集群版本有关,使用 kubectl api-versions 即可查看当前集群支持的版本
kind: Deployment #该配置的类型,我们使用的是 Deployment
metadata: #译名为元数据,即 Deployment 的一些基本属性和信息
name: nginx-deployment #Deployment 的名称
labels: #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组,目前不需要理解
app: nginx #为该Deployment设置key为app,value为nginx的标签
spec: #这是关于该Deployment的描述,可以理解为你期待该Deployment在k8s中如何使用
replicas: 1 #使用该Deployment创建一个应用程序实例
selector: #标签选择器,与上面的标签共同作用,目前不需要理解
matchLabels: #选择包含标签app:nginx的资源
app: nginx
template: #这是选择或创建的Pod的模板
metadata: #Pod的元数据
labels: #Pod的标签,上面的selector即选择包含标签app:nginx的Pod
app: nginx
spec: #期望Pod实现的功能(即在pod中部署)
containers: #生成container,与docker中的container是同一种
- name: nginx #container的名称
image: nginx:1.7.9 #使用镜像nginx:1.7.9创建container,该container默认80端口可访问

然后

1
kubectl apply -f nginx-deployment.yaml

这样应该就能够看见了

1
2
3
4
5
6
# 查看 Deployment
kubectl get deployments

# 查看 Pod
kubectl get pods

2.查看pods/nodes

在部署完一个应用程序后,k8s创建了一个deployment,由它创建了一个pod来放置应用程序实例也就是container

在一个pod中,里面的容器containers会共享

  • 共享存储,称为卷(Volumes),即图上紫色圆柱
  • 网络,每个 Pod(容器组)在集群中有个唯一的 IP,pod(容器组)中的 container(容器)共享该IP地址
  • container(容器)的基本信息,例如容器的镜像版本,对外暴露的端口等

Pod(容器组)是 k8s 集群上的最基本的单元。当我们在 k8s 上创建 Deployment 时,会在集群上创建包含容器的 Pod (而不是直接创建容器)。每个Pod都与运行它的 worker 节点(Node)绑定,并保持在那里直到终止或被删除。如果节点(Node)发生故障,则会在群集中的其他可用节点(Node)上运行相同的 Pod(从同样的镜像创建 Container,使用同样的配置,IP 地址不同,Pod 名字不同)。

Node

![截屏2023-07-15 14.42.27](../images/截屏2023-07-15 14.42.27.png)

Pod总是在 Node 上运行。Node是 kubernetes 集群中的计算机,可以是虚拟机或物理机。每个 Node都由 master 管理。一个 Node可以有多个Pod,kubernetes master 会根据每个 Node上可用资源的情况,自动调度 Pod到最佳的 Node上。

每个 Kubernetes Node至少运行:

  • Kubelet,负责 master 节点和 worker 节点之间通信的进程;管理 Pod和 Pod内运行的 Containers.
  • 容器运行环境(如Docker)负责下载镜像、创建和运行容器等.

kubectl 还有如下四个常用命令,在我们排查问题时可以提供帮助:

kubectl get – 资源类型,

1
2
3
4
5
6
7
8
9
#获取类型为Deployment的资源列表
kubectl get deployments

#获取类型为Pod的资源列表
kubectl get pods

#获取类型为Node的资源列表
kubectl get nodes

名称空间

在命令后增加 -A--all-namespaces 可查看所有 名称空间中 的对象,使用参数 -n 可查看指定名称空间的对象,例如

1
2
3
4
5
6
# 查看所有名称空间的 Deployment
kubectl get deployments -A
kubectl get deployments --all-namespaces
# 查看 kube-system 名称空间的 Deployment
kubectl get deployments -n kube-system

kubectl describe - 显示有关资源的详细信息

1
2
3
4
5
6
7
8
# kubectl describe 资源类型 资源名称

#查看名称为nginx-XXXXXX的Pod的信息
kubectl describe pod nginx-XXXXXX

#查看名称为nginx的Deployment的信息
kubectl describe deployment nginx

Kubectl logs

1
2
3
4
5
6
# kubectl logs Pod名称

#查看名称为nginx-pod-XXXXXXX的Pod内的容器打印的日志
#本案例中的 nginx-pod 没有输出日志,所以您看到的结果是空的
kubectl logs -f nginx-pod-XXXXXXX

Kubectl exec

1
2
3
4
5
# kubectl exec Pod名称 操作命令

# 在名称为nginx-pod-xxxxxx的Pod中运行bash
kubectl exec -it nginx-pod-xxxxxx /bin/bash

TIP

Worker节点是k8s中的工作计算机,可能是VM或物理计算机,具体取决于群集。多个Pod可以在一个节点上运行。

3.公布应用程序

Kubernetes service

Pod有自己的生命周期。当worker node故障的时候,节点上运行的pod也会消失,然后deployment可以通过创建新的 Pod(容器组)来动态地将群集调整回原来的状态,以使应用程序保持运行。

举个例子,假设有一个图像处理后端程序,具有 3 个运行时副本。这 3 个副本是可以替换的(无状态应用),即使 Pod消失并被重新创建,或者副本数由 3 增加到 5,前端系统也无需关注后端副本的变化。由于 Kubernetes 集群中每个 Pod都有一个唯一的 IP 地址(即使是同一个 Node 上的不同 Pod),我们需要一种机制,为前端系统屏蔽后端系统的 Pod在销毁、创建过程中所带来的 IP 地址的变化。

kubernetes 的 service就提供这样的功能,它提供了这样的一个抽象层,它选择具备某些特征的 Pod并为它们定义一个访问方式。Service使Pod之间的相互依赖解耦(原本从一个 Pod 中访问另外一个 Pod,需要知道对方的 IP 地址)。一个 Service选定哪些Pod通常由LabelSelector来决定。

在创建Service的时候,通过设置配置文件中的 spec.type 字段的值,可以以不同方式向外部暴露应用程序:

  • ClusterIP(默认)

    在群集中的内部IP上公布服务,这种方式的 Service(服务)只在集群内部可以访问到

  • NodePort

    使用 NAT 在集群中每个的同一端口上公布服务。这种方式下,可以通过访问集群中任意节点+端口号的方式访问服务 <NodeIP>:<NodePort>。此时 ClusterIP 的访问方式仍然可用。

  • LoadBalancer

    在云环境中(需要云供应商可以支持)创建一个集群外部的负载均衡器,并为使用该负载均衡器的 IP 地址作为服务的访问地址。此时 ClusterIP 和 NodePort 的访问方式仍然可用。

TIPs

Service是一个抽象层,它通过 LabelSelector 选择了一组 Pod(容器组),把这些 Pod 的指定端口公布到到集群外部,并支持负载均衡和服务发现。

  • 公布 Pod 的端口以使其可访问
  • 在多个 Pod 间实现负载均衡
  • 使用 Label 和 LabelSelector

下图中有两个服务Service A(黄色虚线)Service B(蓝色虚线) Service A 将请求转发到 IP 为 10.10.10.1 的Pod上, Service B 将请求转发到 IP 为 10.10.10.2、10.10.10.3、10.10.10.4 的Pod上。

![截屏2023-07-15 16.17.04](../images/截屏2023-07-15 16.17.04.png)

Service 将外部请求路由到一组 Pod 中,它提供了一个抽象层,使得 Kubernetes 可以在不影响服务调用者的情况下,动态地调度pods(在容器组失效后重新创建容器组,增加或者减少同一个 Deployment 对应容器组的数量等).

Service使用 Labels、LabelSelector(标签和选择器) (opens new window)匹配一组 Pod。Labels(标签)是附加到 Kubernetes 对象的键值对,其用途有多种:

  • 将 Kubernetes 对象(Node、Deployment、Pod、Service等)指派用于开发环境、测试环境或生产环境
  • 嵌入版本标签,使用标签区别不同应用软件版本
  • 使用标签对 Kubernetes 对象进行分类

下图体现了 Labels(标签)和 LabelSelector(标签选择器)之间的关联关系

  • Deployment B 含有 LabelSelector 为 app=B 通过此方式声明含有 app=B 标签的 Pod 与之关联

  • 通过 Deployment B 创建的 Pod 包含标签为 app=B

  • Service B 通过标签选择器 app=B 选择可以路由的 Pod

    ![截屏2023-07-15 16.24.25](../images/截屏2023-07-15 16.24.25.png)

Labels可以在创建 Kubernetes 对象时附加上去,也可以在创建之后再附加上去。任何时候都可以修改一个 Kubernetes 对象的 Labels.

实战:

1
2
3
4
metadata:	#译名为元数据,即Deployment的一些基本属性和信息
name: nginx-deployment #Deployment的名称
labels: #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组
app: nginx #为该Deployment设置key为app,value为nginx的标签
1
vim nginx-service.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: v1
kind: Service
metadata:
name: nginx-service #Service 的名称
labels: #Service 自己的标签
app: nginx #为该 Service 设置 key 为 app,value 为 nginx 的标签
spec: #这是关于该 Service 的定义,描述了 Service 如何选择 Pod,如何被访问
selector: #标签选择器
app: nginx #选择包含标签 app:nginx 的 Pod
ports:
- name: nginx-port #端口的名字
protocol: TCP #协议类型 TCP/UDP
port: 80 #集群内的其他容器组可通过 80 端口访问 Service
nodePort: 32600 #通过任意节点的 32600 端口访问 Service
targetPort: 80 #将请求转发到匹配 Pod 的 80 端口
type: NodePort #Serive的类型,ClusterIP/NodePort/LoaderBalancer

1
2
# 执行命令
kubectl apply -f nginx-service.yaml
1
2
3
4
# 检查执行结果
kubectl get services -o wide

# 可查看到名称为 nginx-service 的服务。
1
2
# 访问服务
curl <任意节点的 IP>:32600

4. Scaling

Sacling应用程序

在之前的文章中,我们创建了一个 Deployment ,然后通过 service提供访问 Pod 的方式。我们发布的 Deployment 只创建了一个 Pod 来运行我们的应用程序。当流量增加时,我们需要对应用程序进行伸缩操作以满足系统性能需求。

Scaling 的实现可以通过更改 nginx-deployment.yaml 文件中部署的 replicas(副本数)来完成

1
2
spec:
replicas: 2 #使用该Deployment创建两个应用程序实例

![截屏2023-07-16 00.01.42](../images/截屏2023-07-16 00.01.42.png)

修改了 Deployment 的 replicas 为 4 后,Kubernetes 又为该 Deployment 创建了 3 新的 Pod,这 4 个 Pod 有相同的标签。因此Service A通过标签选择器与新的 Pod建立了对应关系,将访问流量通过负载均衡在 4 个 Pod 之间进行转发。

![截屏2023-07-16 00.02.26](../images/截屏2023-07-16 00.02.26.png)

5.Rolling update

用户期望应用程序始终可用,为此开发者/运维者在更新应用程序时要分多次完成。在 Kubernetes 中,这是通过 Rolling Update 滚动更新完成的。Rolling Update滚动更新 通过使用新版本的 Pod 逐步替代旧版本的 Pod 来实现 Deployment 的更新,从而实现零停机。新的 Pod 将在具有可用资源的 Node(节点)上进行调度。

Kubernetes 更新多副本的 Deployment 的版本时,会逐步的创建新版本的 Pod,逐步的停止旧版本的 Pod,以便使应用一直处于可用状态。这个过程中,Service 能够监视 Pod 的状态,将流量始终转发到可用的 Pod 上。

Intermediate

Advanced

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2021-2024 Mingwei Li
  • Visitors: | Views:

Buy me a bottle of beer please~

支付宝
微信