参考文档:官网文档 中文文档

1 核心组件

k8s集群示意图

master节点

1.1 etcd(数据库)

作为apiServer的数据库,保存了整个集群所有资源的状态

1.2 kube-apiserver(暴露k8s资源api的服务)

apiServer实现了k8s的所有资源(Node/Pod/RC/Service等)的restful接口,可以通过 http请求 或者 kubectl命令 直接和apiServer 交互

1.3 kube-scheduler(调度器)

按照指定的调度策略 在集群的节点上调度工作负载

1.4 kube-controller-manager(控制器)

通过不同类型的控制器维护集群的状态,比如节点故障检测、自动扩展、滚动更新等

work节点

2.1 kubelet

负责与master节点通信,负责Pod的创建、启停等任务,同时也负责Volume(CVI)和网络(CNI)的管理

2.2 kube-proxy

网络路由,维护节点的网络规则,允许集群内部/外部的网络能与Pod的网络进行通信

2.3 Container 

例如docker,负责运行Pod里的container

 

 

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

2 基础概念

2.1 names

k8s的资源对象的唯一标识:name和UID,name(可以自定义,最长253个字符,包括数字字符,字母,-.),uid是k8s自动生成的

例如:获取某个pod的信息 kubectl get pod podname

2.2 namespace(用于多用户的资源隔离)

创建:

(1) 命令行直接创建
$ kubectl create namespace new-namespace

(2) 通过文件创建
$ cat my-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: new-namespace

$ kubectl create -f ./my-namespace.yaml

注意:命名空间名称满足正则表达式[a-z0-9]([-a-z0-9]*[a-z0-9])?,最大长度为63位

删除:

kubectl delete namespaces new-namespace

注意:

1 删除一个namespace会自动删除所有属于该namespace的资源。
2 default和kube-system命名空间不可删除。
3 PersistentVolumes是不属于任何namespace的,但PersistentVolumeClaim是属于某个特定namespace的。
4 Events是否属于namespace取决于产生events的对象

查看:

kubectl get namespaces
NAME          STATUS    AGE
default       Active    1d
kube-system   Active    1d

2.3 labels和 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2.1 namespace

多租户的资源隔离,用户分布在多个团队/项目里,默认有default(不指定namespace时会在default里创建资源)和 kube-system(k8s创建)

通过LimitRange配置Pod默认的资源控制(占用内存/CPU的最大/最小/默认大小)

通过ResourceQuota配置命名空间的资源控制(内存/CPU总大小 和 能创建Pod的数量)

大多数资源(pod/service/rc/deployment等)都位于某些namespace里(操作资源时需要指定namespace),少数底层资源(节点/持久卷等)不在任何namespace里

查看所有资源是否在namespace里:

# In a namespace
kubectl api-resources --namespaced=true

# Not in a namespace
kubectl api-resources --namespaced=false

2.2 label

Label就是用户指定的键值对,关联到各类资源上,其它的资源通过LabelSelector来指定该资源。

例如:Deployment指定Pod的副本数量

2.3 WorkLoad

Pod:k8s最小调度单元,一个pod 包含 业务容器( 用户定义的容器)+ Pause 容器

注:每个Pod里会运行一个Pause的容器,其他容器则为业务容器,这些业务容器共享Pause容器的网络和Volume挂载卷,使同一个Pod的业务容器之间通信和数据交换更为高效

业务容器一般是一个,也可以把多个业务容器放在一个Pod里对外提供服务

RC(Replication Controller):基于等式(只支持等式的匹配规则:key=value)的Label Selector筛选pod,能够控制Pod的副本数量(缩放滚动更新(逐渐的增加新的副本和删除旧的副本Pod)

RS(Replication Set):升级版的RC,支持基于集合(version in (v1.0, v2.0) 的Label Selector

Deployment:升级版的RS(基于RS,会创建RS),能回滚应用,暂停和继续Deployment

// 部署
kubectl create -f docs/user-guide/nginx-deployment.yaml
// 手动扩容/缩容
kubectl scale deployment nginx-deployment --replicas 10
// 集群启用HPA后,可以设置自动扩容
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
// 更新镜像
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1

 
// 查看当前部署状态
kubectl get deployments 
// 具体部署详情
kubectl describe deployments xxx
// 查看当前的RS和Pod
kubectl get rs
kubectl get pods --show-labels

// 升级和回滚
//检查升级历史记录
kubectl rollout history deployment/nginx-deployment
// 查看某一个版本的详情
kubectl rollout history deployment/nginx-deployment --revision=2
// 回滚本次更新
kubectl rollout undo deployment/nginx-deployment
// 回滚到某个历史版本
kubectl rollout undo deployment/nginx-deployment  --to-revision=2


// 暂停部署和恢复(暂停的时候,进行修改不会立即重新部署)
// 1 暂停部署
kubectl rollout pause deployment/nginx-deployment
// 2 进行扩容/修改镜像等多个操作
// 3 恢复部署
kubectl rollout resume deploy nginx
// 或者直接修改Deployment文件 修改完会自动重新部署
kubectl edit deployment/DeploymentName

StatefulSet(有状态服务):用于数据库集群,消息队列集群等中间件

特点:

1 有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,每个Pod部署成功才能部署下一个)。基于init containers来实现

2 有序收缩/删除(从N-1到0)

3 稳定的网络标志(Pod重新调度后PodName和HostName不变),基于Headless Service实现

4 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现

# 扩容
kubectl scale statefulset web --replicas=5

# 缩容
kubectl patch statefulset web -p '{"spec":{"replicas":3}}'

# 镜像更新(目前还不支持直接更新image,需要patch来间接实现)
$ kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"gcr.io/google_containers/nginx-slim:0.7"}]'

# 删除StatefulSet和Headless Service
$ kubectl delete statefulset web
$ kubectl delete service nginx

# StatefulSet删除后PVC还会保留着,数据不再使用的话也需要删除
$ kubectl delete pvc www-web-0 www-web-1

HPA(Horizontal Pod Autoscaler):自动扩容,目前有2种方式:CPU利用率和服务每秒请求数(TPS/QPS)

 ● CPUUtilizationPercentage  是指Cpu利用率的平均值, 通常是过去1min内的平均值;

 ● 应用程序自定义的度量标准,比如服务在每秒内的响应的请求数(TPS或QPS)

2.4 Service(网络负载均衡)

为一组具有相同功能的容器提供统一的入口地址:定义了一个服务的访问入口地址, 其它应用通过这个入口地址访问其背后的一组由pod副本组成的集群实例

类别:
    ClusterIP(默认):集群的虚拟IP,用于集群内部的Pod访问 
    NodeIP:指定所有主机的该端口都能访问服务
    LoadBalance:使用公有云环境的负载均衡

è¿éåå¾çæè¿°

2.5 其它

Job:批处理型任务

CornJob:定时任务

InitContainer(初始化容器):很多应用在启动之前需要进行一些初始化操作(依赖相关组件等待该组件运行,基于环境变量/配置模板生成配置文件,从远程数据库获取本地所需配置/将自己注册到数据库,下载相关依赖包/对系统进行一些预配置操作)

ServiceAccount:为了方便Pod里的进程调用同一个namespace里的k8s集群的服务。每个container启动后都会挂载该service account的token和ca.crt到/var/run/secrets/kubernetes.io/serviceaccount/

ConfigMap:键值对集合。同一个namespace里,配置一个configMap,在Pod里直接将其作为环境变量引入(相比于在pod一个个配置环境变量,可以统一的管理所有Pod的环境变量)

2.6 数据挂载

Volume:将容器里的文件数据挂载出来。类似于Docker里的Volume,Docker里的Volume和容器的生命周期相同,K8s里Volume和Pod的生命周期相同,容器重启时,Volume里的数据不会丢失

Volume的类型:

emptyDir:Pod分配到Node上时创建,无需指定Pod所在宿主机的目录文件(K8s自动分配的主机目录),Pod从Node上移除时会自动删除

hostPath:Pod挂载到宿主机上指定的文件/目录,Pod移除后文件不会删除

getPersistentDisk/awsElasticBlockStore等:公有云提供的永久磁盘,Pod移除后文件不会删除

NFS:常见的网络文件系统,Pod移除后文件不会删除

注:
挂载文件时,主机上必须有该文件,启动后在两边的改动相互看不到
挂载目录时,主机上该目录下有内容则直接覆盖容器内的目录,主机上没有该目录时或主机该目录下文件缺失(该目录下没有容器内的一些文件时),会将容器内目录的内容(容器有主机没)复制到主机上,有改动时双方都能看的到

Persistent Volume(持久卷):k8s集群中的网络存储,不属于任何节点,但是任何节点都能访问

 

3 操作

3.1 集群项目隔离

场景:k8s通过namespace和context(运行环境)来设置不同的项目隔离,例如我们现在有 生产项目和开发项目

// 查看当前配置
kubectl config view 
// 配置namespace
kubectl create namespace production  &&   kubectl create namespace development
// 配置namespace对应的运行环境(context)
kubectl config set-context dev --namespace=dev --cluster=[集群名] --user=[用户名]
// 配置当前运行环境
kubectl config use-context development

3.2 节点的隔离/恢复

场景:某个节点出现问题(遇到过某个master节点因为6443端口被占用,无法启动Pod) 
步骤:
1 暂停调度该节点:kubectl cordon [NodeName]
2 驱散该节点上运行的pod到其它节点上:kubectl drain [NodeName] 
3 恢复调度该节点:kubectl uncordon [NodeName]

3.3  删除节点

主节点:

// 驱散该节点上所有的Pod
kubectl drain <node name> --delete-local-data --force --ignore-daemonsets
// 删除节点
kubectl delete node <node name>

从节点:

//重置
kubeadm reset
// 重新加入
kubeadm init or kubeadm join

 

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐