Kubernetes笔记整合-1

一、kubernetes简介及部署

1、应用部署方式演变

在部署应用程序的方式上,主要经历了三个阶段:

传统部署:互联网早期,会直接将应用程序部署在物理机上

  • 优点:简单,不需要其它技术的参与

  • 缺点:不能为应用程序定义资源使用边界,很难合理地分配计算资源,而且程序之间容易产生影响

虚拟化部署:可以在一台物理机上运行多个虚拟机,每个虚拟机都是独立的一个环境

  • 优点:程序环境不会相互产生影响,提供了一定程度的安全性

  • 缺点:增加了操作系统,浪费了部分资源

容器化部署:与虚拟化类似,但是共享了操作系统

注:容器化部署方式给带来很多的便利,但是也会出现一些问题,比如说:

  • 一个容器故障停机了,怎么样让另外一个容器立刻启动去替补停机的容器

  • 当并发访问量变大的时候,怎么样做到横向扩展容器数量

为了解决容器编排问题,就有了一些容器编排的软件

Swarm:Docker自己的容器编排工具

Mesos:Apache的一个资源统一管控的工具,需要和Marathon结合使用

Kubernetes:Google开源的的容器编排工具

因为现在大多数使用的都是Kubernetes所以使用Kubernetes进行编排

2、Kubernetes简介

kubernetes的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。目的是实现资源管理的自动化,主要提供了如下的主要功能:

  • 自我修复:一旦某一个容器崩溃,能够在1秒中左右迅速启动新的容器

  • 弹性伸缩:可以根据需要,自动对集群中正在运行的容器数量进行调整

  • 服务发现:服务可以通过自动发现的形式找到它所依赖的服务

  • 负载均衡:如果一个服务起动了多个容器,能够自动实现请求的负载均衡

  • 版本回退:如果发现新发布的程序版本有问题,可以立即回退到原来的版本

  • 存储编排:可以根据容器自身的需求自动创建存储卷

3、Kubernetes的设计架构

k8s各个组件用途

一个kubernetes集群主要是由**控制节点(master)**、**工作节点(node)**构成,每个节点上都会安装不同的组件

1、master:集群的控制平面,负责集群的决策**

  • ApiServer : 资源操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制

  • Scheduler : 负责集群资源调度,按照预定的调度策略将Pod调度到相应的node节点上

  • ControllerManager : 负责维护集群的状态,比如程序部署安排、故障检测、自动扩展、滚动更新等

  • Etcd :负责存储集群中各种资源对象的信息

2、node:集群的数据平面,负责为容器提供运行环境**

  • kubelet:负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理

  • Container runtime:负责镜像管理以及Pod和容器的真正运行(CRI)

  • kube-proxy:负责为Service提供cluster内部的服务发现和负载均衡

k8s各组件之间的调用关系

当我们要运行一个web服务时

  1. kubernetes环境启动之后,master和node都会将自身的信息存储到etcd数据库中

  2. web服务的安装请求会首先被发送到master节点的apiServer组件

  3. apiServer组件会调用scheduler组件来决定到底应该把这个服务安装到哪个node节点上

在此时,它会从etcd中读取各个node节点的信息,然后按照一定的算法进行选择,并将结果告知apiServer

  1. apiServer调用controller-manager去调度Node节点安装web服务

  2. kubelet接收到指令后,会通知docker,然后由docker来启动一个web服务的pod

  3. 如果需要访问web服务,就需要通过kube-proxy来对pod产生访问的代理

k8s的常用名词概念

  • Master:集群控制节点,每个集群需要至少一个master节点负责集群的管控

  • ode:工作负载节点,由master分配容器到这些node工作节点上,然后node节点上的

  • Pod:kubernetes的最小控制单元,容器都是运行在pod中的,一个pod中可以有1个或者多个容器

  • Controller:控制器,通过它来实现对pod的管理,比如启动pod、停止pod、伸缩pod的数量等等

  • Service:pod对外服务的统一入口,下面可以维护者同一类的多个pod

  • Label:标签,用于对pod进行分类,同一类pod会拥有相同的标签

  • NameSpace:命名空间,用来隔离pod的运行环境

k8s的分层架构

  • 核心层:Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境

  • 应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等)

  • 管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)

  • 接口层:kubectl命令行工具、客户端SDK以及集群联邦

  • 生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴

  • Kubernetes外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS应用、ChatOps等

  • Kubernetes内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等

二、K8S集群环境搭建

1、k8s中容器的管理方式

k8s集群创建方式有3种:

centainerd

默认情况下,K8S在创建集群时使用的方式

docker

Docker使用的普记录最高,虽然K8S在1.24版本后已经废立了kubelet对docker的支持,但时可以借助cri-docker方式来实现集群创建

cri-o

CRI-O的方式是Kubernetes创建容器最直接的一种方式,在创建集群的时候,需要借助于cri-o插件的方式来实现Kubernetes集群的创建。

注:docker 和cri-o 这两种方式要对kubelet程序的启动参数进行设置

2、k8s集群部署

k8s环境部署说明

中文官网:https://kubernetes.io/zh-cn/

|-----------------|----------------|------------------|
| 主机名 | ip | 角色 |
| reg.suyawen.org | 172.25.254.200 | harbor仓库 |
| master | 172.25.254.100 | master,k8s集群控制节点 |
| node1 | 172.25.254.10 | worker,k8s集群工作节点 |
| node2 | 172.25.254.20 | worker,k8s集群工作节点 |

注:- 所有节点禁用selinux和防火墙

  • 所有节点同步时间和解析

  • 所有节点安装docker-ce

  • 所有节点禁用swap,注意注释掉/etc/fstab文件中的定义

在harbor机上下载好docker

编辑docker.service文件开启iptables

bash 复制代码
vim /lib/systemd/system/docker.service

开启docker

bash 复制代码
systemctl enable --now docker

搭建harbor仓库

bash 复制代码
#解压docker
[root@localhost packages]# tar zxf harbor-offline-installer-v2.5.4.tgz -C /mnt/harbor/

#生成证书和key
[root@localhost ~]# mkdir -p /data/certs
[root@localhost ~]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout /data/certs/suyawen.org.key \
> -addext "subjectAltName = DNS:reg.suyawen.org" \
> -x509 -days 365 -out /data/certs/suyawen.org.crt
#证书
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:shannxi
Locality Name (eg, city) [Default City]:xi'an
Organization Name (eg, company) [Default Company Ltd]:k8s
Organizational Unit Name (eg, section) []:harbor
Common Name (eg, your name or your server's hostname) []:reg.suyawen.org
Email Address []:123@syw

[root@localhost harbor]# ls
common.sh  harbor.v2.5.4.tar.gz  harbor.yml.tmpl  install.sh  LICENSE  prepare
[root@localhost harbor]# cp harbor.yml.tmpl harbor.yml
[root@localhost harbor]# vim harbor.yml
bash 复制代码
[root@localhost harbor]# ./install.sh --with-chartmuseum

建项目(仓库)

集群初始化

禁用所有主机的swap和本地解析

bash 复制代码
[root@localhost ~]# vim /etc/fstab
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl mask swap.target
Created symlink /etc/systemd/system/swap.target → /dev/null.   #锁住swap
[root@localhost ~]# swapoff -a   #关闭当前的所有swap
[root@localhost ~]# swapon -s    #查看有无开启swap

#在三台机子上配置iptables
[root@localhost docker]# vim /lib/systemd/system/docker.service
[root@localhost docker]# for i in 10 20
> do scp /lib/systemd/system/docker.service root@172.25.254.$i:/lib/systemd/system/docker.service
> done

#将harbor机子上的证书钥匙复制给这三个机子
[root@localhost ~]# for i in 100 10 20
> do
> ssh -l root 172.25.254.$i mkdir -p /etc/docker/certs.d
> scp /data/certs/suyawen.org.crt root@172.25.254.$i:/etc/docker/certs.d/reg.suyawen.org /ca.crt
> done

#把仓库作为docker的默认库(在master上)
[root@localhost ~]# cd /etc/docker/
[root@localhost docker]# vim daemon.json
{
  "registry-mirrors":["https://reg.suyawen.org"]
}
#复制给其他两个机子
[root@localhost docker]# for i in 10 20; do scp daemon.json  root@172.25.254.$i:/etc/docker/; done
#开三台机子的docker
[root@localhost docker]# for i in 100 10 20; do ssh  root@172.25.254.$i systemctl enable --now docker; done

#做解析
[root@localhost docker]# vim /etc/hosts
[root@localhost docker]# for i in  10 20; do scp /etc/hosts  root@172.25.254.$i:/etc/hosts; done

设置kubectl命令补齐功能

bash 复制代码
[root@k8s-master ~]# dnf install bash-completion -y
[root@k8s-master ~]# echo "source <(kubectl completion bash)" >> ~/.bashrc
[root@k8s-master ~]# source  ~/.bashrc

在所节点安装cri-docker

k8s从1.24版本开始移除了dockershim,所以需要安装cri-docker插件才能使用docker

软件下载:https://github.com/Mirantis/cri-dockerd

bash 复制代码
[root@master ~]# dnf install libcgroup-0.41-19.el8.x86_64.rpm \
> cri-dockerd-0.3.14-3.el8.x86_64.rpm -y

在cri-docker上做设定

bash 复制代码
[root@localhost ~]# vim /lib/systemd/system/cri-docker.service
[Service]
Type=notify
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// #指定网络插件#指定根节点 --network-plugin=cni --pod-infra-container-image=reg.suyawen.org/k8s/pause:3.9

在master中拉取k8s所需镜像

bash 复制代码
[root@localhost ~]# docker images | awk '/google/{print $1":"$2}' | awk -F / '{system("docker tag "$0" reg.suyawen.org/k8s/"$3)}'
[root@localhost ~]# docker images | awk '/suyawen/{system("docker push " $1":"$2)}'

拉取成功

集群初始化

bash 复制代码
#启动kubelet服务并执行初始化命令
[root@localhost ~]# systemctl enable --now kubelet.service
Created symlink /etc/systemd/system/multi-user.target.wants/kubelet.service → /usr/lib/systemd/system/kubelet.service.
[root@localhost ~]# kubeadm init --pod-network-cidr=10.244.0.0/16 --image-repository reg.suyawen.org/k8s --kubernetes-version v1.30.0 --cri-socket=unix:///var/run/cri-dockerd.sock 

#指定集群配置文件变量
[root@localhost ~]# echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
[root@localhost ~]# source ~/.bash_profile

注:在此阶段如果生成的集群token找不到了可以重新生成

bash 复制代码
[root@master ~]# kubeadm token create --print-join-command
kubeadm join 172.25.254.100:6443 --token 5hwptm.zwn7epa6pvatbpwf --discovery-token-ca-cert-hash sha256:52f1a83b70ffc8744db5570288ab51987ef2b563bf906ba4244a300f61e9db23

安装flannel网络插件

官方网站:https://github.com/flannel-io/flannel(这里本人用的资源包,用docker load -i将文件加载到本地Docker镜像仓库)

建立仓库

给加载好的镜像进行打标签后上传镜像到建立好的仓库里

bash 复制代码
[root@localhost mnt]# docker tag flannel/flannel:v0.25.5 reg.suyawen.org/flannel/flannel:v0.25.5
[root@localhost mnt]# docker push reg.suyawen.org/flannel/flannel:v0.25.5
[root@localhost mnt]# docker tag flannel/flannel-cni-plugin:v1.5.1-flannel1 reg.suyawen.org/flannel/flannel-cni-plugin:v1.5.1-flannel1
[root@localhost mnt]# docker push reg.suyawen.org/flannel/flannel-cni-plugin:v1.5.1-flannel1

#部署flannel网络插件,修改镜像下载位置
[root@localhost mnt]# vim kube-flannel.yml

#修改以下几行
[root@k8s-master ~]# grep -n image kube-flannel.yml
146:        image: reg.suyawen.org/flannel/flannel:v0.25.5
173:        image: reg.suyawen.org/flannel/flannel-cni-plugin:v1.5.1-flannel1
184:        image: reg.suyawen.org/flannel/flannel:v0.25.5

#安装flannel网络插件
[root@localhost mnt]# kubectl apply -f kube-flannel.yml
bash 复制代码
#测试一下pod容器,成功运行的话在master上做的动作相当于在两个node上做的
[root@master ~]# kubectl create deployment webcluster --image nginx --replicas 2
[root@master ~]# kubectl get pods -o wide
NAME                          READY   STATUS    RESTARTS   AGE   IP           NODE    NOMINATED NODE   READINESS GATES
webcluster-7c584f774b-dnkph   1/1     Running   0          30s   10.244.2.2   node2   <none>           <none>
webcluster-7c584f774b-mvn5l   1/1     Running   0          30s   10.244.1.2   node1   <none>           <none>

#node1 node2各运行一个
[root@node1 ~]# docker ps
CONTAINER ID   IMAGE                            COMMAND                  CREATED              STATUS              PORTS     NAMES
21d33885aa7e   nginx                            "/docker-entrypoint...."   About a minute ago   Up About a minute             k8s_nginx_webcluster-7c584f774b-mvn5l_default_693dc0a2-5e04-4f2b-ba3a-3e27f241b95a_0
908e7d532f39   reg.suyawen.org/k8s/pause:3.9    "/pause"                 2 minutes ago        Up 2 minutes                  k8s_POD_webcluster-7c584f774b-mvn5l_default_693dc0a2-5e04-4f2b-ba3a-3e27f241b95a_0
#因为创建的是Deployment,且指定了--replicas 2,Deployment 会确保始终维持 2 个 Pod 运行。因此,当你删除其中一个 Pod 后,Deployment 会自动新建一个 Pod 来替换它,以满足副本数要求。因此彻底删除这两个pod命令为
[root@master ~]# kubectl delete deployment webcluster

三、k8s的资源及pod管理

1、资源管理介绍

  • 在kubernetes中,所有的内容都抽象为资源,用户需要通过操作资源来管理kubernetes。

  • kubernetes的本质上就是一个集群系统,用户可以在集群中部署各种服务

  • 所谓的部署服务,其实就是在kubernetes集群中运行一个个的容器,并将指定的程序跑在容器中。

  • kubernetes的最小管理单元是pod而不是容器,只能将容器放在`Pod`中,

  • kubernetes一般也不会直接管理Pod,而是通过`Pod控制器`来管理Pod的。

  • Pod中服务的访问是由kubernetes提供的`Service`资源来实现。

  • Pod中程序的数据需要持久化是由kubernetes提供的各种存储系统来实现

2、资源管理方式

命令式对象管理:直接使用命令去操作kubernetes资源

bash 复制代码
kubectl run nginx-pod --image=nginx:latest --port=80

命令式对象配置:通过命令配置和配置文件去操作kubernetes资源

bash 复制代码
kubectl create/patch -f nginx-pod.yaml

声明式对象配置:通过apply命令和配置文件去操作kubernetes资源

bash 复制代码
kubectl apply -f nginx-pod.yaml
类型 适用环境 优点 缺点
命令式对象管理 测试 简单 只能操作活动对象,无法审计、跟踪
命令式对象配置 开发 可以审计、跟踪 项目大时,配置文件多,操作麻烦
声明式对象配置 开发 支持目录操作 意外情况下难以调试

命令式对象管理

kubectl是kubernetes集群的命令行工具,通过它能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署

kubectl命令的语法如下:

bash 复制代码
kubectl [command] [type] [name] [flags]

comand:指定要对资源执行的操作,例如create、get、delete、apply

type:指定资源类型,比如deployment、pod、service、namespaces

name:指定资源的名称,名称大小写敏感

flags:指定额外的可选参数

bash 复制代码
# 查看所有pod
kubectl get pod 

# 查看某个pod
kubectl get pod pod_name

# 查看某个pod,以yaml格式展示结果
kubectl get pod pod_name -o yaml

资源类型

kubernetes中所有的内容都抽象为资源

bash 复制代码
kubectl api-resources

常用资源类型

kubect常见命令操作

基本命令示例

kubectl的详细说明地址:https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands

bash 复制代码
#显示集群版本
[root@k8s-master ~]# kubectl version
Client Version: v1.30.0
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.30.0

#显示集群信息
[root@k8s-master ~]# kubectl  cluster-info
Kubernetes control plane is running at https://172.25.254.100:6443
CoreDNS is running at https://172.25.254.100:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

#创建一个webcluster控制器,控制器中pod数量为2
[root@k8s-master ~]# kubectl create deployment webcluseter --image nginx --replicas 2

#查看资源帮助
[root@k8s-master ~]# kubectl explain deployment
GROUP:      apps
KIND:       Deployment
VERSION:    v1
...

#查看控制器参数帮助 
[root@k8s-master ~]# kubectl explain deployment.spec
GROUP:      apps
KIND:       Deployment
VERSION:    v1

FIELD: spec <DeploymentSpec>


DESCRIPTION:
    Specification of the desired behavior of the Deployment.
...

#编辑控制器配置
[root@k8s-master ~]# kubectl edit deployments.apps web
@@@@省略内容@@@@@@
spec:
  progressDeadlineSeconds: 600
  replicas: 2

[root@k8s-master ~]# kubectl get deployments.apps
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web    2/2     2            2           73m

#利用补丁更改控制器配置
[root@k8s-master ~]# kubectl patch  deployments.apps web -p '{"spec":{"replicas":4}}'
deployment.apps/web patched
[root@k8s-master ~]# kubectl get deployments.apps
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web    4/4     4            4           74m

#删除资源
[root@k8s-master ~]# kubectl delete deployments.apps web
deployment.apps "web" deleted
[root@k8s-master ~]# kubectl get deployments.apps
No resources found in default namespace.

namespaces:隔离pod

bash 复制代码
[root@master ~]# kubectl get namespaces
NAME              STATUS   AGE
default           Active   5h9m
kube-flannel      Active   4h46m
kube-node-lease   Active   5h9m
kube-public       Active   5h9m
kube-system       Active   5h9m
[root@master ~]# kubectl create namespace syw
namespace/syw created
[root@master ~]# kubectl get namespaces
NAME              STATUS   AGE
default           Active   5h12m
kube-flannel      Active   4h48m
kube-node-lease   Active   5h12m
kube-public       Active   5h12m
kube-system       Active   5h12m
syw               Active   5s
[root@master ~]# kubectl -n syw run test --image=myapp:v1  #在syw空间里运行一个叫test的pod
pod/test created

#出现这种运行的是一个,显示的是两个在运行是因为没有指定namespaces默认展示了default里面的test
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS      AGE
test   2/2     Running   1 (92m ago)   103m

#不同空间里面的内容彼此是互相看不到的(所以名字一样叫test也不影响)
[root@master ~]# kubectl -n syw get pods
NAME   READY   STATUS    RESTARTS   AGE
test   1/1     Running   0          6m8s

#删除syw空间里面的test
[root@master ~]# kubectl -n syw delete pods test
pod "test" deleted

#删除syw空间
[root@master ~]# kubectl delete namespaces syw
namespace "syw" deleted

控制器

deployment

bash 复制代码
#建立控制器deployment,在控制器运行时会同时开启4个pod并监控(若其中有一个挂机,就再开一个替补)
[root@master ~]# kubectl create deployment webcluster --image myapp:v1 --replicas 4
deployment.apps/webcluster created

#对pods状态进行实时监控
[root@master ~]# watch -n 1 kubectl get pods -o wide

删除后控制器立马进行补充

四、什么是pod

k8s中最小的资源单位是pod,pod(可以看做是进程)里面可以运行多个容器(可以看做是线程)

  • pod是可以创建和管理Kubernetes计算的最小可部署单元

  • 一个Pod代表着集群中运行的一个进程,每个pod都有一个唯一的ip。

  • 一个pod类似一个豌豆荚,包含一个或多个容器(通常是docker)

  • 多个容器间共享IPC、Network和UTC namespace。

1、创建自主式pod (生产不推荐)

优点:

灵活性高:

  • 可以精确控制 Pod 的各种配置参数,包括容器的镜像、资源限制、环境变量、命令和参数等,满足特定的应用需求。

学习和调试方便:

  • 对于学习 Kubernetes 的原理和机制非常有帮助,通过手动创建 Pod 可以深入了解 Pod 的结构和配置方式。在调试问题时,可以更直接地观察和调整 Pod 的设置。

适用于特殊场景:

  • 在一些特殊情况下,如进行一次性任务、快速验证概念或在资源受限的环境中进行特定配置时,手动创建 Pod 可能是一种有效的方式。

缺点:

管理复杂:

  • 如果需要管理大量的 Pod,手动创建和维护会变得非常繁琐和耗时。难以实现自动化的扩缩容、故障恢复等操作。

缺乏高级功能:

  • 无法自动享受 Kubernetes 提供的高级功能,如自动部署、滚动更新、服务发现等。这可能导致应用的部署和管理效率低下。

可维护性差:

  • 手动创建的 Pod 在更新应用版本或修改配置时需要手动干预,容易出现错误,并且难以保证一致性。相比之下,通过声明式配置或使用 Kubernetes 的部署工具可以更方便地进行应用的维护和更新。
bash 复制代码
#查看所有pods
[root@master ~]# kubectl get pods
No resources found in default namespace.

#建立一个名为suyawen的pod
[root@master ~]# kubectl run suyawen --image nginx
pod/suyawen created


[root@k8s-master ~]# kubectl get pods
NAME        READY   STATUS    RESTARTS   AGE
suyawen   1/1     Running   0          6s

#显示pod的较为详细的信息
[root@k8s-master ~]# kubectl get pods -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP            NODE                      NOMINATED NODE   READINESS GATES
suyawen   1/1     Running   0          11s   10.244.1.17   node1   <none>           <none>

2、利用控制器管理pod(推荐)

高可用性和可靠性:

  • 自动故障恢复:如果一个 Pod 失败或被删除,控制器会自动创建新的 Pod 来维持期望的副本数量。确保应用始终处于可用状态,减少因单个 Pod 故障导致的服务中断。

  • 健康检查和自愈:可以配置控制器对 Pod 进行健康检查(如存活探针和就绪探针)。如果 Pod 不健康,控制器会采取适当的行动,如重启 Pod 或删除并重新创建它,以保证应用的正常运行。

可扩展性:

  • 轻松扩缩容:可以通过简单的命令或配置更改来增加或减少 Pod 的数量,以满足不同的工作负载需求。例如,在高流量期间可以快速扩展以处理更多请求,在低流量期间可以缩容以节省资源。

  • 水平自动扩缩容(HPA):可以基于自定义指标(如 CPU 利用率、内存使用情况或应用特定的指标)自动调整 Pod 的数量,实现动态的资源分配和成本优化。

版本管理和更新:

  • 滚动更新:对于 Deployment 等控制器,可以执行滚动更新来逐步替换旧版本的 Pod 为新版本,确保应用在更新过程中始终保持可用。可以控制更新的速率和策略,以减少对用户的影响。

  • 回滚:如果更新出现问题,可以轻松回滚到上一个稳定版本,保证应用的稳定性和可靠性。

声明式配置:

  • 简洁的配置方式:使用 YAML 或 JSON 格式的声明式配置文件来定义应用的部署需求。这种方式使得配置易于理解、维护和版本控制,同时也方便团队协作。

  • 期望状态管理:只需要定义应用的期望状态(如副本数量、容器镜像等),控制器会自动调整实际状态与期望状态保持一致。无需手动管理每个 Pod 的创建和删除,提高了管理效率。

服务发现和负载均衡:

  • 自动注册和发现:Kubernetes 中的服务(Service)可以自动发现由控制器管理的 Pod,并将流量路由到它们。这使得应用的服务发现和负载均衡变得简单和可靠,无需手动配置负载均衡器。

  • 流量分发:可以根据不同的策略(如轮询、随机等)将请求分发到不同的 Pod,提高应用的性能和可用性。

多环境一致性:

  • 一致的部署方式:在不同的环境(如开发、测试、生产)中,可以使用相同的控制器和配置来部署应用,确保应用在不同环境中的行为一致。这有助于减少部署差异和错误,提高开发和运维效率。

3、利用yaml文件部署应用

用yaml文件部署应用有以下优点

声明式配置:

  • 清晰表达期望状态:以声明式的方式描述应用的部署需求,包括副本数量、容器配置、网络设置等。这使得配置易于理解和维护,并且可以方便地查看应用的预期状态。

  • 可重复性和版本控制:配置文件可以被版本控制,确保在不同环境中的部署一致性。可以轻松回滚到以前的版本或在不同环境中重复使用相同的配置。

  • 团队协作:便于团队成员之间共享和协作,大家可以对配置文件进行审查和修改,提高部署的可靠性和稳定性。

灵活性和可扩展性:

  • 丰富的配置选项:可以通过 YAML 文件详细地配置各种 Kubernetes 资源,如 Deployment、Service、ConfigMap、Secret 等。可以根据应用的特定需求进行高度定制化。

  • 组合和扩展:可以将多个资源的配置组合在一个或多个 YAML 文件中,实现复杂的应用部署架构。同时,可以轻松地添加新的资源或修改现有资源以满足不断变化的需求。

与工具集成:

  • 与 CI/CD 流程集成:可以将 YAML 配置文件与持续集成和持续部署(CI/CD)工具集成,实现自动化的应用部署。例如,可以在代码提交后自动触发部署流程,使用配置文件来部署应用到不同的环境。

  • 命令行工具支持:Kubernetes 的命令行工具 `kubectl` 对 YAML 配置文件有很好的支持,可以方便地应用、更新和删除配置。同时,还可以使用其他工具来验证和分析 YAML 配置文件,确保其正确性和安全性。

资源清单参数

参数名称 类型 参数说明
version String 这里是指的是K8S API的版本,目前基本上是v1,可以用kubectl api-versions命令查询
kind String 这里指的是yaml文件定义的资源类型和角色,比如:Pod
metadata Object 元数据对象,固定值就写metadata
metadata.name String 元数据对象的名字,这里由我们编写,比如命名Pod的名字
metadata.namespace String 元数据对象的命名空间,由我们自身定义
Spec Object 详细定义对象,固定值就写Spec
spec.containers[] list 这里是Spec对象的容器列表定义,是个列表
spec.containers[].name String 这里定义容器的名字
spec.containers[].image string 这里定义要用到的镜像名称
spec.containers[].imagePullPolicy String 定义镜像拉取策略,有三个值可选: (1) Always: 每次都尝试重新拉取镜像 (2) IfNotPresent:如果本地有镜像就使用本地镜像 (3) )Never:表示仅使用本地镜像
spec.containers[].command[] list 指定容器运行时启动的命令,若未指定则运行容器打包时指定的命令
spec.containers[].args[] list 指定容器运行参数,可以指定多个
spec.containers[].workingDir String 指定容器工作目录
spec.containers[].volumeMounts[] list 指定容器内部的存储卷配置
spec.containers[].volumeMounts[].name String 指定可以被容器挂载的存储卷的名称
spec.containers[].volumeMounts[].mountPath String 指定可以被容器挂载的存储卷的路径
spec.containers[].volumeMounts[].readOnly String 设置存储卷路径的读写模式,ture或false,默认为读写模式
spec.containers[].ports[] list 指定容器需要用到的端口列表
spec.containers[].ports[].name String 指定端口名称
spec.containers[].ports[].containerPort String 指定容器需要监听的端口号
spec.containers[] ports[].hostPort String 指定容器所在主机需要监听的端口号,默认跟上面containerPort相同,注意设置了hostPort同一台主机无法启动该容器的相同副本(因为主机的端口号不能相同,这样会冲突)
spec.containers[].ports[].protocol String 指定端口协议,支持TCP和UDP,默认值为 TCP
spec.containers[].env[] list 指定容器运行前需设置的环境变量列表
spec.containers[].env[].name String 指定环境变量名称
spec.containers[].env[].value String 指定环境变量值
spec.containers[].resources Object 指定资源限制和资源请求的值(这里开始就是设置容器的资源上限)
spec.containers[].resources.limits Object 指定设置容器运行时资源的运行上限
spec.containers[].resources.limits.cpu String 指定CPU的限制,单位为核心数,1=1000m
spec.containers[].resources.limits.memory String 指定MEM内存的限制,单位为MIB、GiB
spec.containers[].resources.requests Object 指定容器启动和调度时的限制设置
spec.containers[].resources.requests.cpu String CPU请求,单位为core数,容器启动时初始化可用数量
spec.containers[].resources.requests.memory String 内存请求,单位为MIB、GIB,容器启动的初始化可用数量
spec.restartPolicy string 定义Pod的重启策略,默认值为Always. (1)Always: Pod-旦终止运行,无论容器是如何 终止的,kubelet服务都将重启它 (2)OnFailure: 只有Pod以非零退出码终止时,kubelet才会重启该容器。如果容器正常结束(退出码为0),则kubelet将不会重启它 (3) Never: Pod终止后,kubelet将退出码报告给Master,不会重启该
spec.nodeSelector Object 定义Node的Label过滤标签,以key:value格式指定
spec.imagePullSecrets Object 定义pull镜像时使用secret名称,以name:secretkey格式指定
spec.hostNetwork Boolean 定义是否使用主机网络模式,默认值为false。设置true表示使用宿主机网络,不使用docker网桥,同时设置了true将无法在同一台宿主机 上启动第二个副本

获得资源帮助

bash 复制代码
kubectl explain pod.spec.containers

编写示例

部署好所需容器

bash 复制代码
[root@master ~]# kubectl run test --image myapp:v1
pod/test created

#查看运行情况
[root@master ~]# kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
test                          1/1     Running   0          11m
webcluster-7c584f774b-dnkph   1/1     Running   0          35m
webcluster-7c584f774b-mvn5l   1/1     Running   0          35m
#查看详细信息
[root@master ~]# kubectl get pods -o wide
NAME                          READY   STATUS    RESTARTS   AGE   IP           NODE    NOMINATED NODE   READINESS GATES
test                          1/1     Running   0          12m   10.244.2.3   node2   <none>           <none>
webcluster-7c584f774b-dnkph   1/1     Running   0          35m   10.244.2.2   node2   <none>           <none>
webcluster-7c584f774b-mvn5l   1/1     Running   0          35m   10.244.1.2   node1   <none>           <none>
#对test进行结束(删除)
[root@master ~]# kubectl delete pods test
pod "test" deleted

#运行test用yaml方式输出
[root@master ~]# kubectl run test --image myapp:v1 --dry-run=client -o yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: test
  name: test
spec:
  containers:
  - image: myapp:v1
    name: test
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

#将yaml脚本保存到yml文件中(可以不用繁琐重复敲)
[root@master ~]# kubectl run test --image myapp:v1 --dry-run=client -o yaml > test.yml
[root@master ~]# vim test.yml

脚本解释

一个pod可运行多个容器(这里写了2个)

注:在一个pod中开启多个容器时一定要确保容器彼此不能互相干扰,如果多个容器运行在一个pod中,资源共享的同时在使用相同资源时也会干扰,比如端口

bash 复制代码
#进行创建运行(命令式对象配置)
[root@master ~]# kubectl create -f test.yml
pod/test created
[root@master ~]# kubectl get pods
NAME                          READY   STATUS              RESTARTS      AGE
test                          1/2     RunContainerError   1 (65m ago)   17s
#可以看出有一个运行失败可用"kubectl describe pods test"查看问题
 Message:      failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "/bin/bash": stat /bin/bash: no such file or directory: unknown#没有"/bin/bash"文件
[root@master ~]# kubectl delete -f test.yml   #用这个命令对错误文件进行回收(文件还在,只是不在kubectl中)
pod "test" deleted
[root@master ~]# vim test.yml  #将里面的"/bin/bash"改为/bin/sh

#问题解决!
[root@master ~]# kubectl create -f test.yml
pod/test created
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
test   2/2     Running   0          60s

#查看详细信息
[root@master ~]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE     IP           NODE    NOMINATED NODE   READINESS GATES
test   2/2     Running   0          3m22s   10.244.2.6   node2   <none>           <none>
[root@master ~]# curl 10.244.2.6
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

v1改v2(改版本)

bash 复制代码
#结果发现crate只能创建不能更新
[root@master ~]# kubectl create -f test.yml
Error from server (AlreadyExists): error when creating "test.yml": pods "test" already exists
#进行声明
[root@master ~]# kubectl apply -f test.yml
[root@master ~]# curl 10.244.2.6
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>  #版本变为v2
#查看配置信息
[root@master ~]# kubectl explain pod

五、pod的生命周期

1、INIT容器

官方文档:https://kubernetes.io/zh/docs/concepts/workloads/pods/

  • Pod 可以包含多个容器,应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。

  • Init 容器与普通的容器非常像,除了如下两点:

  • 它们总是运行到完成

  • init 容器不支持 Readiness,因为它们必须在 Pod 就绪之前运行完成,每个 Init 容器必须运行成功,下一个才能够运行。

  • 如果Pod的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。但是,如果 Pod 对应的 restartPolicy 值为 Never,它不会重新启动。

INIT 容器的功能

  • Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。

  • Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。

  • 应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。

  • Init 容器能以不同于Pod内应用容器的文件系统视图运行。因此,Init容器可具有访问 Secrets 的权限,而应用容器不能够访问。

  • 由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod内的所有的应用容器会并行启动。

INIT 容器示例

bash 复制代码
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
  labels:
    name: initpod
  name: initpod
spec:
  containers:
    - image: myapp:v1
      name: myapp
  initContainers:
    - name: init-myservice
      image: busybox
      command: ["sh","-c","until test -e /testfile;do echo wating for myservice; sleep 2;done"]

[root@k8s-master ~]# kubectl apply  -f pod.yml
pod/initpod created
[root@k8s-master ~]# kubectl get  pods
NAME      READY   STATUS     RESTARTS   AGE
initpod   0/1     Init:0/1   0          3s

[root@k8s-master ~]# kubectl logs pods/initpod init-myservice
wating for myservice
wating for myservice
wating for myservice
wating for myservice
wating for myservice
wating for myservice
[root@k8s-master ~]# kubectl exec pods/initpod -c init-myservice -- /bin/sh -c "touch /testfile"

[root@k8s-master ~]# kubectl get  pods                                                     NAME      READY   STATUS    RESTARTS   AGE
initpod   1/1     Running   0          62s

2、探针

探针是由 kubelet 对容器执行的定期诊断:

  • ExecAction:在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。

  • TCPSocketAction:对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。

  • HTTPGetAction:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的。

每次探测都将获得以下三种结果之一:

  • 成功:容器通过了诊断。

  • 失败:容器未通过诊断。

  • 未知:诊断失败,因此不会采取任何行动。

Kubelet 可以选择是否执行在容器上运行的三种探针执行和做出反应:

  • livenessProbe:指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其重启策略的影响。如果容器不提供存活探针,则默认状态为 Success。

  • readinessProbe:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为 Success。

  • startupProbe: 指示容器中的应用是否已经启动。如果提供了启动探测(startup probe),则禁用所有其他探测,直到它成功为止。如果启动探测失败,kubelet 将杀死容器,容器服从其重启策略进行重启。如果容器没有提供启动探测,则默认状态为成功Success。

ReadinessProbe 与 LivenessProbe 的区别:

  • ReadinessProbe 当检测失败后,将 Pod 的 IP:Port 从对应的 EndPoint 列表中删除。

  • LivenessProbe 当检测失败后,将杀死容器并根据 Pod 的重启策略来决定作出对应的措施

StartupProbe 与 ReadinessProbe、LivenessProbe 的区别:

  • 如果三个探针同时存在,先执行 StartupProbe 探针,其他两个探针将会被暂时禁用,直到 pod 满足 StartupProbe 探针配置的条件,其他 2 个探针启动,如果不满足按照规则重启容器。

  • 另外两种探针在容器启动后,会按照配置,直到容器消亡才停止探测,而 StartupProbe 探针只是在容器启动后按照配置满足一次后,不在进行后续的探测。

探针实例

存活探针示例:

bash 复制代码
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
  labels:
    name: liveness
  name: liveness
spec:
  containers:
    - image: myapp:v1
      name: myapp
      livenessProbe:
        tcpSocket:					#检测端口存在性
          port: 8080
        initialDelaySeconds: 3		#容器启动后要等待多少秒后就探针开始工作,默认是 0
        periodSeconds: 1			#执行探测的时间间隔,默认为 10s
        timeoutSeconds: 1			#探针执行检测请求后,等待响应的超时时间,默认为 1s
        

#测试:
[root@k8s-master ~]# kubectl apply -f pod.yml
pod/liveness created
[root@k8s-master ~]# kubectl get pods
NAME       READY   STATUS             RESTARTS     AGE
liveness   0/1     CrashLoopBackOff   2 (7s ago)   22s

[root@k8s-master ~]# kubectl describe pods
Warning  Unhealthy  1s (x9 over 13s)  kubelet            Liveness probe failed: dial tcp 10.244.2.6:8080: connect: connection refused

就绪探针示例:

bash 复制代码
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
  labels:
    name: readiness
  name: readiness
spec:
  containers:
    - image: myapp:v1
      name: myapp
      readinessProbe:
        httpGet:
          path: /test.html
          port: 80
        initialDelaySeconds: 1
        periodSeconds: 3
        timeoutSeconds: 1


#测试:
[root@k8s-master ~]# kubectl expose pod readiness --port 80 --target-port 80

[root@k8s-master ~]# kubectl get pods
NAME        READY   STATUS    RESTARTS   AGE
readiness   0/1     Running   0          5m25s

[root@k8s-master ~]# kubectl describe pods readiness
Warning  Unhealthy  26s (x66 over 5m43s)  kubelet            Readiness probe failed: HTTP probe failed with statuscode: 404

[root@k8s-master ~]# kubectl describe services readiness
Name:              readiness
Namespace:         default
Labels:            name=readiness
Annotations:       <none>
Selector:          name=readiness
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.100.171.244
IPs:               10.100.171.244
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:										#没有暴漏端口,就绪探针探测不满足暴漏条件
Session Affinity:  None
Events:            <none>

kubectl exec pods/readiness -c myapp -- /bin/sh -c "echo test > /usr/share/nginx/html/test.html"

[root@k8s-master ~]# kubectl get pods
NAME        READY   STATUS    RESTARTS   AGE
readiness   1/1     Running   0          7m49s

[root@k8s-master ~]# kubectl describe services readiness
Name:              readiness
Namespace:         default
Labels:            name=readiness
Annotations:       <none>
Selector:          name=readiness
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.100.171.244
IPs:               10.100.171.244
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.2.8:80			#满组条件端口暴漏
Session Affinity:  None
Events:            <none>

六、k8s中控制器的使用

1、概念

官方文档:https://v1-30.docs.kubernetes.io/zh-cn/docs/concepts/workloads/controllers/

控制器也是管理pod的一种手段

  • 自主式pod:pod退出或意外关闭后不会被重新创建

  • 控制器管理的 Pod:在控制器的生命周期里,始终要维持 Pod 的副本数目

Pod控制器是管理pod的中间层,使用Pod控制器之后,只需要告诉Pod控制器,想要多少个什么样的Pod就可以了,它会创建出满足条件的Pod并确保每一个Pod资源处于用户期望的目标状态。如果Pod资源在运行中出现故障,它会基于指定策略重新编排Pod

当建立控制器后,会把期望值写入etcd,k8s中的apiserver检索etcd中我们保存的期望状态,并对比pod的当前状态,如果出现差异代码自驱动立即恢复

2、类型

控制器名称 控制器用途
Replication Controller 比较原始的pod控制器,已经被废弃,由ReplicaSet替代
ReplicaSet ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行
Deployment 一个 Deployment 为 PodReplicaSet 提供声明式的更新能力
DaemonSet DaemonSet 确保全指定节点上运行一个 Pod 的副本
StatefulSet StatefulSet 是用来管理有状态应用的工作负载 API 对象。
Job 执行批处理任务,仅执行一次任务,保证任务的一个或多个Pod成功结束
CronJob Cron Job 创建基于时间调度的 Jobs。
HPA全称Horizontal Pod Autoscaler 根据资源利用率自动调整service中Pod数量,实现Pod水平自动缩放

3、replicaset控制器

功能

  • ReplicaSet 是下一代的 Replication Controller,官方推荐使用ReplicaSet

  • ReplicaSet和Replication Controller的唯一区别是选择器的支持,ReplicaSet支持新的基于集合的选择器需求

  • ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行

  • 虽然 ReplicaSets 可以独立使用,但今天它主要被Deployments 用作协调 Pod 创建、删除和更新的机制

参数说明

参数名称 字段类型 参数说明
spec Object 详细定义对象,固定值就写Spec
spec.replicas integer 指定维护pod数量
spec.selector Object Selector是对pod的标签查询,与pod数量匹配
spec.selector.matchLabels string 指定Selector查询标签的名称和值,以key:value方式指定
spec.template Object 指定对pod的描述信息,比如lab标签,运行容器的信息等
spec.template.metadata Object 指定pod属性
spec.template.metadata.labels string 指定pod标签
spec.template.spec Object 详细定义对象
spec.template.spec.containers list Spec对象的容器列表定义
spec.template.spec.containers.name string 指定容器名称
spec.template.spec.containers.image string 指定容器镜像

示例

bash 复制代码
#生成yml文件
[root@master ~]# kubectl create deployment replicaset --image myapp:v1 --dry-run=client -o yaml > replicaset.yml
[root@master ~]# vim replicaset.yml
bash 复制代码
[root@master ~]# kubectl apply -f replicaset.yml
replicaset.apps/replicaset created
[root@master ~]# kubectl get pods --show-labels
NAME                        READY   STATUS    RESTARTS      AGE    LABELS
replicaset-9csjb            1/1     Running   0             21s    app=myapp
replicaset-vrnx2            1/1     Running   0             21s    app=myapp

#replicaset是通过标签匹配pod
[root@master ~]# kubectl label pod replicaset-9csjb app=syw --overwrite
pod/replicaset-9csjb labeled
[root@master ~]# kubectl get pods --show-labels
NAME                        READY   STATUS    RESTARTS      AGE     LABELS
replicaset-9csjb            1/1     Running   0             5m54s   app=syw
replicaset-spmkq            1/1     Running   0             33s     app=myapp #新开启的pod
replicaset-vrnx2            1/1     Running   0             5m54s   app=myapp

#恢复标签后
[root@master ~]# kubectl label pod replicaset-9csjb app-
pod/replicaset-9csjb unlabeled
[root@master ~]# kubectl get pods --show-labels
NAME                        READY   STATUS    RESTARTS      AGE     LABELS
replicaset-9csjb            1/1     Running   0             5m54s   app=myapp
replicaset-spmkq            1/1     Running   0             33s     app=myapp
replicaset-vrnx2            1/1     Running   0             5m54s   app=myapp

#replicaset自动控制副本数量,pod可以自愈
[root@master ~]# kubectl delete pods replicaset-spmkq
pod "replicaset-spmkq" deleted

[root@master ~]# kubectl get pods --show-labels
NAME               READY   STATUS    RESTARTS   AGE     LABELS
replicaset-vrnx2   1/1     Running   0          8m11s   app=myapp
replicaset-vrs58   1/1     Running   0          15s     app=myapp


#回收资源
[root@master ~]# kubectl delete -f replicaset.yml
replicaset.apps "replicaset" deleted

4、deployment 控制器

功能

  • 为了更好的解决服务编排的问题,kubernetes在V1.2版本开始,引入了Deployment控制器。

  • Deployment控制器并不直接管理pod,而是通过管理ReplicaSet来间接管理Pod

  • Deployment管理ReplicaSet,ReplicaSet管理Pod

  • Deployment 为 Pod 和 ReplicaSet 提供了一个申明式的定义方法

  • 在Deployment中ReplicaSet相当于一个版本

应用场景

  • 用来创建Pod和ReplicaSet

  • 滚动更新和回滚

  • 扩容和缩容

  • 暂停与恢复

示例

bash 复制代码
[root@master ~]# kubectl create deployment deployment --image myapp:v1 --dry-run=client -o yaml > deployment.yml
[root@master ~]# vim deployment.yml
bash 复制代码
#建立pod
[root@master ~]# kubectl apply -f deployment.yml
deployment.apps/deployment created

#查看信息
[root@master ~]# kubectl get pods --show-labels
NAME                          READY   STATUS    RESTARTS       AGE     LABELS
deployment-5d886954d4-jbnqz   1/1     Running   0              26s     app=myapp,pod-template-hash=5d886954d4
deployment-5d886954d4-k22z7   1/1     Running   0              26s     app=myapp,pod-template-hash=5d886954d4
deployment-5d886954d4-l4mct   1/1     Running   0              26s     app=myapp,pod-template-hash=5d886954d4
deployment-5d886954d4-rkpbp   1/1     Running   0              26s     app=myapp,pod-template-hash=5d886954d4

版本迭代

bash 复制代码
[root@master ~]# kubectl get pods -o wide
NAME                          READY   STATUS    RESTARTS       AGE     IP               NODE     NOMINATED NODE   READINESS GATES
deployment-5d886954d4-jbnqz   1/1     Running   0              3m30s   10.244.104.47    node2    <none>           <none>
deployment-5d886954d4-k22z7   1/1     Running   0              3m30s   10.244.166.152   node1    <none>           <none>
deployment-5d886954d4-l4mct   1/1     Running   0              3m30s   10.244.166.151   node1    <none>           <none>
deployment-5d886954d4-rkpbp   1/1     Running   0              3m30s   10.244.104.48    node2    <none>           <none>

#pod运行容器版本为v1
[root@master ~]# curl 10.244.104.47
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

更新容器运行版本

更新过程

测试更新效果

注:更新的过程是重新建立一个版本的RS,新版本的RS会把pod 重建,然后把老版本的RS回收

版本回滚

测试结果

滚动更新策略

这次更新了一部分,下次更新就5秒一次,一共要更新8个

bash 复制代码
[root@k8s-master ~]# vim deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment
spec:
  minReadySeconds: 5		#最小就绪时间,指定pod每隔多久更新一次
  replicas: 4
  strategy:					#指定更新策略
    rollingUpdate:
      maxSurge: 1			#比定义pod数量多几个
      maxUnavailable: 0		#比定义pod个数少几个
  selector:
    matchLabels:
      app: myapp

  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - image: myapp:v1
        name: myapp
[root@k8s2 pod]# kubectl apply -f deployment-example.yaml

影响最小的,最丝滑的更新策略,更一个关一个

暂停更新及恢复

在实际生产环境中我们做的变更可能不止一处,当修改了一处后,如果执行变更就直接触发了

我们期望的触发时当我们把所有修改都搞定后一次触发,暂停,避免触发不必要的线上更新

bash 复制代码
[root@k8s2 pod]# kubectl rollout pause deployment deployment-example

[root@k8s2 pod]# vim deployment-example.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-example
spec:
  minReadySeconds: 5
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  replicas: 6				
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: nginx
        resources:
          limits:
            cpu: 0.5
            memory: 200Mi
          requests:
            cpu: 0.5
            memory: 200Mi

[root@k8s2 pod]# kubectl apply -f deployment-example.yaml

#调整副本数,不受影响
[root@k8s-master ~]# kubectl describe pods deployment-7f4786db9c-8jw22
Name:             deployment-7f4786db9c-8jw22
Namespace:        default
Priority:         0
Service Account:  default
Node:             k8s-node1/172.25.254.10
Start Time:       Mon, 02 Sep 2024 00:27:20 +0800
Labels:           app=myapp
                  pod-template-hash=7f4786db9c
Annotations:      <none>
Status:           Running
IP:               10.244.1.31
IPs:
  IP:           10.244.1.31
Controlled By:  ReplicaSet/deployment-7f4786db9c
Containers:
  myapp:
    Container ID:   docker://01ad7216e0a8c2674bf17adcc9b071e9bfb951eb294cafa2b8482bb8b4940c1d
    Image:          myapp:v2
    Image ID:       docker-pullable://myapp@sha256:5f4afc8302ade316fc47c99ee1d41f8ba94dbe7e3e7747dd87215a15429b9102
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Mon, 02 Sep 2024 00:27:21 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-mfjjp (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True
  Initialized                 True
  Ready                       True
  ContainersReady             True
  PodScheduled                True
Volumes:
  kube-api-access-mfjjp:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  6m22s  default-scheduler  Successfully assigned default/deployment-7f4786db9c-8jw22 to k8s-node1
  Normal  Pulled     6m22s  kubelet            Container image "myapp:v2" already present on machine
  Normal  Created    6m21s  kubelet            Created container myapp
  Normal  Started    6m21s  kubelet            Started container myapp


#但是更新镜像和修改资源并没有触发更新
[root@k8s2 pod]# kubectl rollout history deployment deployment-example
deployment.apps/deployment-example
REVISION  CHANGE-CAUSE
3         <none>
4         <none>

#恢复后开始触发更新
[root@k8s2 pod]# kubectl rollout resume deployment deployment-example

[root@k8s2 pod]# kubectl rollout history  deployment deployment-example
deployment.apps/deployment-example
REVISION  CHANGE-CAUSE
3         <none>
4         <none>
5         <none>

#回收
[root@k8s2 pod]# kubectl delete -f deployment-example.yaml

5、daemonset控制器

DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。当有节点加入集群时, 也会为他们新增一个 Pod ,当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod

DaemonSet 的典型用法:

  • 在每个节点上运行集群存储 DaemonSet,例如 glusterd、ceph。

  • 在每个节点上运行日志收集 DaemonSet,例如 fluentd、logstash。

  • 在每个节点上运行监控 DaemonSet,例如 Prometheus Node Exporter、zabbix agent等

  • 一个简单的用法是在所有的节点上都启动一个 DaemonSet,将被作为每种类型的 daemon 使用

  • 一个稍微复杂的用法是单独对每种 daemon 类型使用多个 DaemonSet,但具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求

示例

bash 复制代码
[root@k8s2 pod]# cat daemonset-example.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-example
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      tolerations:		#对于污点节点的容忍
      - effect: NoSchedule
        operator: Exists
      containers:
      - name: nginx
        image: nginx

[root@k8s-master ~]# kubectl get pods  -o wide
NAME              READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
daemonset-87h6s   1/1     Running   0          47s   10.244.0.8    k8s-master   <none>           <none>
daemonset-n4vs4   1/1     Running   0          47s   10.244.2.38   k8s-node2    <none>           <none>
daemonset-vhxmq   1/1     Running   0          47s   10.244.1.40   k8s-node1    <none>           <none>


#回收
[root@k8s2 pod]# kubectl delete -f daemonset-example.yml

6、job控制器

Job,主要用于负责批量处理(一次要处理指定数量任务)短暂的一次性(每个任务仅运行一次就结束)任务

Job特点如下:

  • 当Job创建的pod执行成功结束时,Job将记录成功结束的pod数量

  • 当成功结束的pod达到指定的数量时,Job将完成执行

示例

bash 复制代码
[root@k8s2 pod]# vim job.yml
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  completions: 6		#一共完成任务数为6		
  parallelism: 2		#每次并行完成2个
  template:
    spec:
      containers:
      - name: pi
        image: perl:5.34.0
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]	计算Π的后2000位
      restartPolicy: Never						#关闭后不自动重启
  backoffLimit: 4								#运行失败后尝试4重新运行

[root@k8s2 pod]# kubectl apply -f job.yml

关于重启策略设置的说明:

  • ​ 如果指定为OnFailure,则job会在pod出现故障时重启容器

​ 而不是创建pod,failed次数不变

  • ​ 如果指定为Never,则job会在pod出现故障时创建新的pod

​ 并且故障pod不会消失,也不会重启,failed次数加1

  • ​ 如果指定为Always的话,就意味着一直重启,意味着job任务会重复去执行了

7、cronjob 控制器

  • Cron Job 创建基于时间调度的 Jobs。

  • CronJob控制器以Job控制器资源为其管控对象,并借助它管理pod资源对象,

  • CronJob可以以类似于Linux操作系统的周期性任务作业计划的方式控制其运行时间点及重复运行的方式。

  • CronJob可以在特定的时间点(反复的)去运行job任务。

示例

bash 复制代码
[root@k8s2 pod]# vim cronjob.yml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "* * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

[root@k8s2 pod]# kubectl apply -f cronjob.yml
相关推荐
照物华11 分钟前
k8s之 Pod 资源管理与 QoS
云原生·容器·kubernetes
hhzz11 分钟前
重温 K8s 基础概念知识系列八( K8S 高级网络)
网络·容器·kubernetes
Insist75313 分钟前
K8s--调度管理:node节点、Pod亲和性、污点与容忍
linux·容器·kubernetes
Insist7531 小时前
k8s——持久化存储 PVC
java·容器·kubernetes
Demonsong_1 小时前
2025.8.22周五 在职老D渗透日记day24:burp+mumu抓包 安卓7.0以上证书配置
经验分享·笔记
MowenPan19952 小时前
高等数学 9.1多元函数的基本概念
笔记·学习·高等数学
qq_341160444 小时前
文件系统挂载详细分析(《图解Linux内核》虚拟文件系统篇笔记二)
linux·服务器·笔记
无级程序员5 小时前
kubernetes-dashboard使用http不登录
http·容器·kubernetes
张鱼小丸子6 小时前
K8S管理实战指南
云原生·容器·kubernetes