第一章 k8s 介绍
应用部署方式的演变

传统部署: app 直接在操作系统之上进行部署。

虚拟化部署: 一台物理机上虚拟化多个虚拟机。 每个虚拟机都是独立的环境。

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

在这里插入图片描述

虚拟化部署,与容器化部署程序直接相互隔离,但是虚拟化每个隔离之间都需要操作系统,比较消耗系统的资源。

容器化部署可以跨云服务商,跨linux 操作系统进行发布。且每个容器拥有自己的文件系统,cpu,内存,进程空间。app 所需要的资源由容器来提供。

容器存在的问题:

1 一个容器故障宕机了,如何让另外一个容器去替补停机的容器。

2 当并发量增大的时候,如何去横向扩展容器的数量。

容器管理的问题可以统称为容器的编排问题

k8s: google开源的容器编排工具。

SWarm : docker 自己的编排工具。

K8s 简介

k8s 的本质是一组服务器集群,在集群的每一个节点上运行特定的程序。对节点中的容器进行管理。目的是实现资源管理的自动化。

k8s 组件

一个k8s 集群是由控制节点(master)和 工作节点(node ),每个节点上都会安装不同的组件。

在这里插入图片描述
举例说明,向ApiServer 发送请求,请求运行一个nginx,则通过Scheduler 进行计算,Controller-manager进行调度,假设 nginx 服务运行在pod 节点上了。Etecd 记录 nginx 服务相关元数据。

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

Node 节点正真干活的(工作负载节点, node 节点上的 docker 负责容器的运行), kubelet 接受控制节点发送过来的信息,将信息发送给相应的docker,来执行各种操作。

kube-proxy 客户端访问接口。一个 nginx 服务运行了,如果要访问 nginx ,就需要 kube-proxy 来对pod 产生访问的代理。

在这里插入图片描述

k8s 中的一些概念

pod 是k8s 中的最小控制单元, 容器必须跑到pod 中。pod 中至少要有一个容器 k8s 是通过控制pod,然后再去控制容器的。

Controller: k8s 中有各种类型的 Controller。

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

Service: pod 对外服务的统一入口

NameSpace: 命名空间,用来隔离pod 的运行环境。Docker 也使用namspce 来隔离环境

k8s 安装

如果无法启动多个集群,建议使用官网的交互式环境。

k8s 集群介绍

k8s 集群一般分为两类,一主多从,和多主多从。

一主多从: 一个Master 节点,多个Node 节点,但存在单点故障等问题。常用于测试环境。

多主多从: 多个Mater节点,多个Node节点。搭建麻烦,但是安全性高,常用于生产环境。

在这里插入图片描述

k8s 安装方式

k8s 有多种部署方式,目前比较主流的方式有: kubeadm ,Minkube 二进制包

官网采用的是Minikube 部署方式

在这里插入图片描述

Minbikube: 用于快速搭建单节点的k8s 集群工具。

kubeadm: 一个用于快速搭建k8s集群工具。

二进制包: 从官网下载每个组件的二进制包,依次去安装,此方式对理解k8的组件更为有效,但操作起来比较麻烦。

Minikube 进行部署集群:

这里使用Minikube 进行部署集群。

下载minikube之后,输入下面命令。

1 minikube version

2 minikube start 启动k8s 集群

3 kubectl version

4 kubectl cluster-info

5 kubectl get nodes

kubeadm 安装 k8s 集群:

1 查看操作系统的版本,使用kubeadm 安装k8s集群,要求centos 的版本要在7.5 及以上。

​ cat /etc/redhat-release

2 主机名解析

​ 编辑三套服务器的 /etc/hosts 文件,添加服务器对应的ip地址和 主机名

在这里插入图片描述

3 时间同步

k8s 要求节点的时间要精确一致,这里使用chronyd 服务从网络中同步时间。

​ 3.1 启动 chronyd 服务命令 : systemctl start chronyd

​ 3.2 设置chronyd 服务开机自启动 : systemctl enable chronyd

4 禁用iptables 和firewalld 服务(生产环境才能做)(k8s 和docker 在运行中会产生大量iptables 规则,为了不跟系统的iptables 进行混淆,直接关闭系统的iptables)

​ systemctl stop firewalld

​ systemctl disable firewalld

​ systemctl stop iptables

​ systemctl disable iptables
5 禁用selinux
vi /etc/selinux/config
SELINUX=disabled
6 禁用swap分区
注释掉 最后一行就行
7修改linux内核参数
编辑 vi /etc/sysctl.d/kubernetes.conf文件,添加如下配置
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
重新加载配置
sysctl -p
加载网桥过滤模块
modprobe br_netfilter
查看网桥过滤模块是否加载成功
lsmod | grep br_netfilter
8配置ipvs功能
安装
yum install ipset ipvsadmin -y
添加需要加载的模块写入脚本文件
cat EOF /etc/sysconfig/modules/ipvs.modules
#!/bin/bash
modprobe – ip_vs
modprobe – ip_vs_rr
modprobe – ip_vs_wrr
modprobe – ip_vs_sh
modprobe – nf_conntrack_ipv4
EOF
为脚本文件添加执行权限
chmod +x /etc/sysconfig/modules/ipvs.modules
执行脚本文件
/bin/bash /etc/sysconfig/modules/ipvs.modules
查看对应的模块是否加载成功
lsmod | grep -e ip_vs -e nf_conntrack_ipv4

k8s 部署应用

1 kubectl get nodes 获取节点信息(当前只有一个节点)
在这里插入图片描述

2 kubectl create deployment 命令部署k8s 应用

kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1

该命令部署的是 kubernetes-bootcamp 应用。We need to provide the deployment name and app image location (include the full repository url for images hosted outside Docker hub).

3 kubectl get deployments 查看部署的应用

在这里插入图片描述

在单节点上的一个应用。

4 查看应用

Pods that are running inside Kubernetes are running on a private, isolated network.By default they are visible from other pods and services within the same kubernetes cluster, but not outside that network.

翻译: Kubernetes内部运行的pod运行在一个专用的隔离网络上。默认情况下,它们可以从同一Kubernetes集群内的其他pod和 service 中看到,但不能从该网络外部看到。

The kubectl command can create a proxy that will forward communications into the cluster-wide, private network. The proxy can be terminated by pressing control-C and won't show any output while its running.

4.1 `“kubectl”命令可以创建一个代理,将通信转发到集群范围的专用网络。可以通过按control-C终止代理,并且在代理运行时不会显示任何输出。下面命令来生成一个代理。

echo -e “\n\n\n\e[92mStarting Proxy. After starting it will not output a response. Please click the first Terminal Tab\n”; kubectl proxy

4.2 通过代理我们的主机与k8s 集群产生了联系。代理的节点提供了一些api 可以通过下面命令看到。

curl http://localhost:8001/version
在这里插入图片描述

  1. 3暴露接口

默认情况下,所有 Pod 只能在集群内部访问。因此要想在外部访问的话,需要做一个映射。

把容器的8080端口映射到节点的端口

kubectl expose deployment/kubernetes-bootcamp \

–type=“NodePort” \

–port 8080

NodePort 的意思是可以集群外部的网络进行访问。

4.4 查看服务的状态 命令 :kubectl get pods service

k8s 资源管理
资源管理介绍

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

k8s本质就是一个集群系统,用户可以在集群中部署各种服务,所谓部署服务就是在k8s 集群中运行一个个容器,并将指定的程序跑到容器中。

k8s 中最小的管理单位是pod 而不是容器,所以只能将容器放到pod 中,但是k8s一般不直接管理pod,而是通过pod 管理器 (Controller)来管理pod 的。

Pod 可以提供服务之后,就要考虑如何访问Pod 中的服务。K8s 提供了Service 资源实现了这个功能。

当然,pod中的程序的数据需要持久化,K8s 还提供了各种存储系统。

在这里插入图片描述

学习K8s的核心 就是学习如何对集群上的Pod,Pod控制器,Service,存储等各种资源进行操作。

资源管理方式

1 命令式对象管理: 直接使用命令去操作k8s 的各种资源

在这里插入图片描述

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

在这里插入图片描述

3 声明式对象配置: 通过apply 命令和配置文件去操作k8s 资源。
在这里插入图片描述
apply 命令有资源就更新,没有就创建。
比较:
在这里插入图片描述

命令式对象管理

kubectl 命令

​ kubectl 命令是 k8s 集群的命令行工具,可以通过它对集群本身进行管理。并且能在集群上进行容器化应用的安装部署。 kubectl 在 $HOME/.kube 目录中查找一个名为 config 的配置文件。kubectll 命令语法如下:

在这里插入图片描述

command 指对资源执行的操作 如 create get delet

type 指资源的类型,比如 deployment,pod,service

name 指资源的名称,注意名称大小写敏感。

flags 指定额外的可选参数。

常见命令

kubectl get pod # 查看所有的pod

kubectl get pod pod_name 查看某个pod

kubectl get pod pod_name -o yaml 查看某个pod,以yaml的格式进行展示

kubectl --help 查看kubectl 的所有命令

在这里插入图片描述
在这里插入图片描述

k8s 中的资源类型

k8s 中所有的内容都抽象为资源,可以通过下面命令查看k8s 中的各种资源类型。

kubectl api-resources

在这里插入图片描述

常用的资源有一下内容:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZRbgv3jD-1636892471039)(D:\java workstation\笔记\浪潮\images\image-20211113213547905.png)]
在这里插入图片描述

kubectl describe pods 命令运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fsn5ABkX-1636892471054)(D:\java workstation\笔记\浪潮\images\image-20211113215426816.png)]

命令式对象配置

命令式对象配置就是使用命令配合配置文件一起来操作k8s 资源。

ymal 文件声明要操作资源的具体信息。 比如说创建pod 的时候,要声明创建pod 容器镜像版本,所要预留的一些端口。

1 创建一个nginxpod.xml ,内容如下:

在这里插入图片描述

解释: 上面的是namespace 声明,kind 对应资源类型。metadata 元数据,只给了name 为dev, 创建一个名为dev 的namespace。 下面Pod的创建使用了这个namespace。 spec 详情描述。 containers 对应相应的容器细节。name 为容器名设置的是nginx-container,image 为对应的镜像名使用的是nginx:1.17.1 版本。

2 执行create 命令 ,创建资源

kubectl create -f nginxpod.xml

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PvylhX9u-1636892471061)(D:\java workstation\笔记\浪潮\images\image-20211113214445809.png)]

此时创建了两个资源,分别是namespace 和pod。 显示格式为 资源类型/资源名称

删除 kubectl delete -f nginxpod.xml

声明式对象配置

声明式对象配置和命令式对象配置很类似,但是它只需要一个apply 命令。

k8s 实战入门
Namespace

Namespace 是k8s 中非常重要的一种资源,它的主要作用是用来实现多套环境的资源隔离多租户的资源隔离

默认情况下,K8s 集群中所有的pod 都可以互相访问,但是在实际中,可能不想让两个pod 之间相互访问,这个时候就需要将这两个pod 划分到不同的namespace 之下,K8s 通过将集群内部的资源分配到不同的Namespace中,可以形成逻辑上的“组”。 以方便不同组的资源进行隔离使用和管理。

可以根据K8s 授权机制,将不同的namespace 交给不同的租户进行管理。这样就实现了多租户的资源隔离。此时还可以结合K8s 的资源配额机制,限定不同的租户能占用的资源,如cpu 使用量, 内存使用量等等。 来实现租户可用资源的管理。

在这里插入图片描述

K8s 集群启动之后,会默认创建几个namespace 。

使用命令式对象管理 查看:

    kubectl get namespace

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oooHPdQh-1636892471069)(D:\java workstation\笔记\浪潮\images\image-20211114182734278.png)]

default 指的是未指定namespace 的对象都会被分配在default 命名空间

kube-node-lease 集群节点之间的心跳维护,v1.13 开始引入

kube-public 此命名空间下的资源可以被所有人访问(包括未认证用户)

kube-system 所有由k8s系统创建的资源都处于这个命名空间

获得指定名称空间下的所有pods

kubectl get pods -n kube-system

在这里插入图片描述

这些pods 都是集群组件。

**对Namespace资源的具体操作 **:

​ 1 命令行操作

1.1 查询

kubectl get ns 

注意 :ns(namespace 的简写)

在这里插入图片描述

STATUS 为状态, Active 表示为此名称空间正在使用。 AGE 表示该名称空间已经工作的时间。

1.2 查看具体名称空间的描述

kubectl describe  ns default 

该命令查看的是 default 命名空间的描述
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uMrQ3ml4-1636892471081)(D:\java workstation\笔记\浪潮\images\image-20211114184802788.png)]

Name : 名称空间的名字

Label 名称空间的标签,

Annotations 名称空间的注释

Status 名称空间的状态 Active 表示此名称空间正在使用, Terminating 表示正在删除名称空间 (删除名称空间的话,其下的pods 也会被删除,删除pods 需要时间。)

ResourceQuota 针对namespace 做的资源配额, No resource quota 没有限制

LimitRange 针对namespace 中的每个组件做的资源配额。 No LimitRange resource 表示没有限制。

1.3 名称空间的创建

kubectl create ns dev

在这里插入图片描述

1.4 名称空间的删除

删除dev 名称空间

kubectl delete ns dev 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-txj54I5W-1636892471091)(D:\java workstation\笔记\浪潮\images\image-20211114190127702.png)]

2 配置的形式创建与删除

准备一个ns-dev.yaml 文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sX3OQPKc-1636892471095)(D:\java workstation\笔记\浪潮\images\image-20211114190330751.png)]

apiVersion 对应版本,Kind 对应要操作资源的类型 metadata 相关元数据

执行对应的创建与删除命令即可

 创建  kubectl create -f  ns-dev.yaml 

 删除  kubectl delete  -f ns-dev.yaml
Pod

Pod 是 Kubernetes 抽象出来的,表示一组一个或多个应用程序容器(如 Docker),以及这些容器的一些共享资源。这些资源包括:

  • 共享存储,当作卷
  • 网络,作为唯一的集群 IP 地址
  • 有关每个容器如何运行的信息,例如容器映像版本或要使用的特定端口。

Pod 可以认为是容器的封装,一个Pod 可以存在一个或多个容器。

1 查看集群组件pod

K8s 集群启动之后,集群中各个组件都是以Pod 的形式运行。可以通过下面命令查看

kubectl get pods -n kube-system

在这里插入图片描述

kube-apiserver-minikube : ApiServer 组件

还有一些组件, ControllerManager 组件, Scheduler 组件,etcd 组件,proxy 组件 这些在第一章中的k8s 组件中进行了介绍。

coredns 是用来做DNS 的。

2 命令行操作

​ 2.1 创建并运行Pod

​ k8s并没有提供单独运行pod 的命令,都是通过Pod 控制器来实现的。

​ 命令格式: kubectl run (pod 控制器名称) [参数]

	> 参数介绍
	>
	> --image  指定pod 的镜像
	>
	> --port 指定端口
	>
	> --namespace 指定名称空间
kubectl run  kubernetes-bootcamp  --image=gcr.io/google-samples/kubernetes-bootcamp:v1 --port=80 

2.2 查看pod 是否运行

kubectl get pod

在这里插入图片描述

NAME : pod 的名称

READY : 当前pod 有几个容器,容器里面有几个正在运行的。(计算不会将根容器计算在内)

RESTARTS: 重启次数, 在pod运行过程中如果出现问题会尝试重启。

查看更多详细信息可以加上 -o wide 参数

kubectl get pod  -o wide 

在这里插入图片描述

多出来的信息包括:

IP: 当前pod 的ip

Node: 当前pod 被调度到哪个结点上运行

查看描述信息

kubectl describe pod  kubernetes-bootcamp

运行结果

在这里插入图片描述
在这里插入图片描述

还有很多详细信息,这里不进行显示。

kubectl describe 命令十分重要, 当pod 出现错误的时候,可以使用该命令查看错误的具体细节

2.3 删除pod

Pod 是由pod 控制器来进行创建的,控制器会监控Pod 的状态,一旦发现Pod 死亡,会立即重启。所以想要删除Pod,必须要删除Pod 控制器

查询当前命名空间(当前为default)的Pod 控制器

kubectl get deploy 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QT5W10jS-1636892471117)(D:\java workstation\笔记\浪潮\images\image-20211114200300357.png)]

删除此Pod 控制器

kubectl  delete deploy kubernetes-bootcamp

只要删除Pod 控制器, 对应的Pod 也会被删除。

3 配置文件操作

注意使用命令行运行无法启动单独的Pod,但是使用 yaml 可以创建一个pod。 如下是使用yaml文件启动一个nginx pod

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sBTiiyoz-1636892471119)(D:\java workstation\笔记\浪潮\images\image-20211114201549799.png)]

注意这里的name 名 为pod 对应的name ,不是pod 控制器。

Label

Label 是k8s 中的重要概念,它的作用就是在资源上面添加标识。用来对他们进行区分和选择。

  1. Label 特点:
    1. 一个Label 会以 key/value 键值对的形式附加到各种对象上,比如Node,Pod,Service 等
    2. 一个资源对象可以定义任意数量的Label,同一个Label 也可以被添加到任意数量的资源对象上去。
    3. Label 通常在资源对象定义时确定,当然也可以在对象创建后动态添加和删除。

可以通过Label 实现资源的多维度分组,以便灵活方便的进行资源分配,调度,配置,部署等管理工作。

一些常用Label 示例如下

1 版本标签 “version”:“release” , “version”:“stable”

2 环境标签 “environment”:“dev”, “enviroment”:“test”, “environment”:“pro”

3 架构标签 “tier”:“frontend”, “tier”:“backend”

标签定义完毕之后,还要考虑到标签的选择,这就要使用到Label Selector,即:

Label 用于给某个资源对象定义标识。

Label Selector 用于查询和筛选拥有某些标签的资源对象

当前有两种Label Selector :

1基于等式的Label Selector
在这里插入图片描述

2 基于集合的Label Selector
在这里插入图片描述

1 命令方式

1.1 给资源打标签

kubectl get pods 查看有哪些pods

kubectl label pod  kubernetes-bootcamp-fb5c67579-7gwsb  version=1.0

​ 该命令为给pod kubernetes-bootcamp-fb5c67579-7gwsb 打上version 信息,其为1.0,其他资源也可以。

在这里插入图片描述

1.2 查看资源的标签

kubectl get pod kubernetes-bootcamp-fb5c67579-7gwsb --show-labels

在这里插入图片描述

可以看到有LABELS 这一列,同一个资源可以打多个Label,所以为LABELS

1.3 更新标签

kubectl label pod  kubernetes-bootcamp-fb5c67579-7gwsb  version=2.0 --overwrite

重点是参数 --overwrite

在这里插入图片描述

可以看到标签进行了更新,version 版本为2.0

1.4 筛选标签

kubectl get pod  -l version=2.0 --show-labels

-l 后面跟一个Label Selector

在这里插入图片描述

没找到会报错

1.5 删除标签

kubectl  label  pod   kubernetes-bootcamp-fb5c67579-7gwsb version- 

对应的标签的key-,-为减号

2 配置方式

pod-nginx.yaml

在这里插入图片描述

执行对应的更新命令即可

kubectl apply -f pod-nginx.yaml
Deployment

Deployment 是一种 pod 控制器(pod 控制器有很多种),Pod控制器用于pod 的管理,确保 pod 资源符合预期的状态,当 pod 的资源出现问题时候,可以尝试进行重启和重建 pod。

1 命令操作

1 .1 创建deployment 控制器

kubectl create deployment 名称 [参数]

参数

–image 指定pod 的镜像

–port 指定端口

–replicas 指定创建pod 数量 (该参数已被遗弃)

–namespace 指定namespace

kubectl create ns dev  创建dev 命名空间
kubectl create  deploy  kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1 --replicas=3 --namespace=dev  

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yF4EYmgc-1636981477152)(D:\java workstation\笔记\浪潮\images\image-20211115165327260.png)]

查看 dev 命名空间下的deployment 和pods

kubectl  get deployment pods -n dev

在这里插入图片描述

在该图中,一个 Deployment 控制着三个 Pod, 根据 Label Selector 建立 Deployment 与 Pod 的对应关系。

1.2 删除deployment

kubectl delete deploy  deployment 名字 -n  名称空间

2 配置文件

创建 deploy-nginx.yaml

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HldJTe3L-1636981477161)(D:\java workstation\笔记\浪潮\images\image-20211115153956016.png)]

通过选择器建立Deployment 和Pod 的对应关系。

 创建  kubetcl create -f  deploy-nginx.yaml

 删除  kubectl delete -f  deploy-nginx.yaml
Service

通过Deployment 可以创建一组Pod 来提供具有高可用性的服务。

虽然每个Pod 都会分配单独的Pod Ip,然而却存在如下两个问题

1 Pod IP 会随着Pod 的重建产生变化

2 Pod IP 仅仅是集群内部可见的虚拟ip,外部无法访问。

Service 是一组同类Pod 对外的访问接口,借助Service,应用可以方便的实现服务发现和负载均衡。

1 命令操作

1.1 创建集群内部可被访问的Service(暴露Service)

在这里插入图片描述

​ 对于上图

kubectl  expose deploy  nginx  [参数]

–name= 指定Service 的名称

–type= 指定Service 类型

​ 有ClusterIP:Service ip 地址只能集群内部使用

​ NodePort : 创建外部也可以访问的Service

–port= 指定Service 端口号

–target-port= 转发的目标端口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SiZEIO55-1636981477166)(D:\java workstation\笔记\浪潮\images\image-20211115163224591.png)]

查看Service

kubectl get svc -n dev

Service 可以简写成svc

在这里插入图片描述

Pod 详解

这一张主要详细介绍Pod 资源的各种配置(yaml) 和原理。

Pod 介绍

Pod 内部结构
在这里插入图片描述
Pod 中容器大致分为两类

  1. 用户容器 : 用户程序所在的容器,数量可多可少。

  2. Pause 容器: 每个Pod 都会有的一个根容器。它的作用有两个:
    2.1 可以以他为依据,评估整个pod 的健康状态
    2.2 可以在根容器上设置ip 地址,其他容器来共享这个ip, 实现pod 内部的网络通信

Pod 定义

Pod 的资源清单

apiVersion: v1 #必选 版本号, 例如v1,这是pod已经规定好的
kind: Pod     # 必选,资源类型 例如Pod
metadata:		#必选 元数据
	name: string 	#必选 Pod 名称
	namespace: string # pod 所属名称空间,默认为"default"
	labels: 			#自定义标签列表
		- name: string

spec:           # 必选,Pod中容器的详细定义
	containers :	#必选 Pod中容器列表
	- name: string 	#必选,容器名称
	  image: string # 必选,容器的镜像名称
等等	  

如果记不住这么多的命令怎么办?kubectl 提供了一个命令查看每种资源的可配置项。

kubectl explain 资源类型 查看某种资源可以配置的一级属性

kubectl explain 资源类型.属性 查看属性的子属性

kubectl explain pod

在这里插入图片描述
在这里插入图片描述

pod 容器详细配置

本小节主要研究pod.spec.containers属性,这也是 pod 配置中最为关键的一项配置。

在这里插入图片描述

1 基本配置

创建pod-base.yaml 文件,内容如下:

在这里插入图片描述

上面定义了一个比较简单的Pod 的配置,里面有两个容器。

1 nginx: 用1.17.1 版本的nginx 镜像创建(nginx 是一个轻量级web 容器)

2 busybox: 用1.30 版本的busybox 镜像创建(busybox 是一个小巧的linux 命令集合)

镜像是从远程docker 仓库拉去下来的。

镜像拉取策略

imagePullPolicy,用于设置镜像拉取策略,K8s 现在支持三种拉取策略。

  • Always: 总是从远程仓库拉取镜像(一直用远程的)
  • IfNotPresent: 本地有则使用本地镜像,本地没有则从远程仓库拉取镜像。
  • Never : 只使用本地仓库,从不去远程仓库拉取,本地没有则一直报错。

创建pod-imagepullpolicy.yaml 文件,内容如下:

在这里插入图片描述

默认值说明

​ 如果镜像的tag 为具体版本,默认策略是IfNotPresent

​ 如果镜像的tag 为latest(最终版本),默认的策略是 Always

1 创建pod

	kubectl create -f pod-imagepullpolicy.yaml

注意在K8s 中任何资源的name 必须为小写,大写会报错。 如果采用的是Never 策略,可以先在对应的节点上使用docker images 命令查看是否有对应的镜像。

启动命令

在上面的生成nginx 和busybox 的pods的配置文件,运行后会发现pod 在不断重启,pod 中有两个容器,但只有一个容器能够正常工作。

在这里插入图片描述

原来busybox 并不是一个程序,而是一个类似与工具类的集合。K8s 集群启动管理后,它会自动关闭。解决方法就是让其一直运行,这时候就要用到command 配置。

在这里插入图片描述

command 用于pod 中的容器初始化完毕之后运行一个命令。

“/bin/sh” “-c” 使用sh执行命令

“touch /tmp/hello.txt; while true;do /bin/echo $(date +%T) >> /tmp/hello.txt; sleep 3;done” 创建一个文件,每隔三秒向文件写入当前时间。

让其不断运行,使其不会终止。继续创建发现pod 中的两个容器都运行成功。

如何查看 busybox 容器中的hello.txt 文件?

​ 可以进入到busybox 容器中,查看文件内容。

进入容器命令

kubectl exec pod名称  -n 命名空间 -it -c 容器名称 /bin/sh 在容器内部执行命令	
kubectl exec pod-command  -n dev -it -c busybox  /bin/sh

上述命令会进入容器中的shell 。

在这里插入图片描述

环境变量

env 参数用于向容器传递环境变量。 所谓的环境变量就是键值对,可以进入容器打印这些环境变量。

在这里插入图片描述
在这里插入图片描述

端口设置

ports 支持的子选项

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-44yGdB3T-1636981477215)(D:\java workstation\笔记\浪潮\images\image-20211115201930029.png)]

在这里插入图片描述

创建pod-port.yaml

在这里插入图片描述

资源配额

容器中的程序运行,肯定要占用一定的资源,比如说cpu 和内存等,如果不对某个容器的资源进行限制,那它有可能会吃掉大量的资源,导致其他容器无法正常运行。针对这种情况,K8s 提供了对cpu 和内存资源进行配额的机制。这些机制主要通过resources 选项实现,它有两个子选项。

1 limits : 用于限制运行时容器的最大占用资源,当容器占用资源超过了limits 时会被终止,并进行重启。

2 requests: 用于设置容器需要的最小资源,如果环境资源不够,容器将无法启动。

可以通过上面两个选项设置资源的上下限。

创建pod-resources.yaml

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KUbJBXvj-1636981477223)(D:\java workstation\笔记\浪潮\images\image-20211115204044522.png)]

单位说明:

  • ​ cpu: core 数,可以为整数或小数
  • memory: 内存大小, 可以使用 Gi, Mi,G,M 等形式
Pod 的生命周期

我们一般将pod 对象从创建终止的这段时间范围称为pod 的生命周期。它主要包括下面几个过程。

  • pod 创建过程
  • 运行初始化容器(init container)过程
  • 运行主容器(main container) 过程
    • 容器启动后钩子( post start ) 容器终止前钩子 (pre stop) 执行过程
    • 容器存活性探测(liveness probe) 就绪性探测( readiness probe) : 用于探测容器是否正常运行
  • pod 终止过程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UASp2HMn-1636981477225)(D:\java workstation\笔记\浪潮\images\image-20211115205145389.png)]

第一部分运行初始化容器过程,一定要在主容器运行前执行,

第二部分: 运行主容器过程

post start 容器启动后钩子 pre stop 容器终止前钩子 : 其实就是K8s给我们设置的两个点,通过这两个点,我们可以传入相应的命令或操作。

在这里插入图片描述

pod 的创建过程

在这里插入图片描述

watch 机制很重要。

pod 终止过程

在这里插入图片描述

pod初始化容器过程

在这里插入图片描述

初始化容器是在pod主容器启动之前要运行的容器,主要做一些主容器的前置工作,它具有两大特征:

1 初始化容器必须运行完成直至结束,若某初始化容器运行失败,那么k8s 需要重启它,直到成功完成。

2 初始化容器必须按照定义的顺序执行,当且仅当前一个成功之后,后面的一个才能成功运行。

初始化容器有很多的应用场景,下面列出最常见的几个:

  • 提供主容器镜像中不具备的工具程序或自定义代码。

  • 初始化容器要先与应用容器串行启动,并运行完成。因此可用于延后应用容器的启动直至其依赖的条件得到满足。

    案例说明: 假设以主容器来运行nginx, 但是要求在运行nginx 之前能够连接上mysql 和redis 所在服务器。

    为了简化测试,事先规定mysql(192.168.109.201) 和redis(192.168.109.202) 服务器地址。

创建pod-initcontainer.yaml

在这里插入图片描述

initContainers初始化容器配置。注意其层级与容器齐平,

主容器钩子

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PwgNX911-1637368165522)(D:\java workstation\笔记\浪潮\images\image-20211116150336308.png)]

钩子函数: 钩子函数指的是k8s 所预留的点,允许在这些点去定义一些用户自己的行为代码。当pod 运行到这个点的时候,K8s会调用运行在该点的用户代码。

容器启动后钩子( post start ) : 会在容器启动后立即执行,如果执行失败就会,容器会以一定的重启策略进行重启。 容器终止前钩子 (pre stop) : 容器会在删除的时候调用该钩子。

钩子处理器支持使用下面三种方式定义动作:

  • Exec 命令: 在容器内执行一次命令

在这里插入图片描述

  • TCPSocket : 在当前容器尝试访问特定的socket

在这里插入图片描述

  • HTTPGet: 在当前容器中向某url 发起http 请求

在这里插入图片描述

主容器探测

容器探测用于检测容器应用实例当前是否能正常工作,是保障业务可用性的一种传统方式。如果经过探测,实例的状态不符合预期。那么K8s 就会把该问题的实例“摘除”,不承担业务流量。K8s提供了两种探针来实现容器探测。分别是:

  • liveness probe : 存活性探针,用于检测应用实例当前是否处于正常运行状态。如果不,k8s 会重启容器。
  • readiness probe : 就绪性探针,用于检测当前应用实例是否可以接受请求,如果不能,K8s不会转发流量。

上面两种探针目前均支持三种探测方式。

liveness probe 决定是否重启容器, readiness probe 决定是否将请求转发给容器

  • Exec 命令,在容器内执行一次命令,如果命令执行的退出码为0,则认为程序正常,否则为不正常。

在这里插入图片描述

  • TCPSocket :将会尝试访问一个容器的端口,如果能够建立这条连接,则认为程序正常,否则认为程序不正常。

在这里插入图片描述

  • HTTPGet: 调用容器内部Web应用的url,如果返回状态码在200和399 之间,则认为程序正常,否则认为不正常。

在这里插入图片描述

下面以liveiness probe 为例子,举例说明

1 Exec 命令

创建pod-liveness-exec.yaml
在这里插入图片描述

注意探针是在containers 目录下的。不要用在同级目录。

1 创建pod,观察效果:

kubectl create  -f pod-liveness-exec.yaml

发现容器在不断的重启

2 查看pod 详情

kubectl descibe pods pod-liveness-exec

在这里插入图片描述

发现错误。发现存活性探针探测失败,原因是没有/tmp/hello.txt 文件。探针探测失败之后,容器将会重启启动。

3 执行可以成功探测的yaml 文件

在这里插入图片描述

重启策略

在上一节中,一旦容器探测失败,k8s 就会对容器所在的pod进行重启。其实这是由pod 的重启策略确定的。pod 的重启策略有以下三种。

  • Always : 容器失效时,自动重启该容器,这也是默认值。
  • OnFailure : 容器终止运行且退出码不为0的时候进行重启。
  • Nerver: 不论任何状态,都不重启该容器。

重启策略适用pod 中对象中的所有容器,首次需要重启的容器,将在其需要时立即进行重启,随后再次需要进行重启的操作将有kubelet 延迟一段时间后进行,且反复的重启操作的延迟时常将以此为10s,20s,40s,80s,160s 和300s。300 s是最大延迟时常。

创建pod-restartpolicy.yaml

apiVersion: v1 # API版本号,注意:具有多个,不同的对象可能会使用不同API
kind: Pod  # 对象类型,pod
metadata:  # 元数据
  name: pod-restartpolicy # POD名称
  namespace: dev # 所属的命名空间
spec: # specification of the resource content(资源内容的规范)
  containers: # 容器列表
    - name: nginx # 容器名称
      image: nginx:1.17.1 # 容器镜像
	  ports:
	  -name: nginx-port
	  	containerPort: 80
	  livenessProbe: 
	    httpGet:
	      scheme: HTTP
	      port: 80
	      path: /hello
  restartPolicy: Always # 设置重启策略为Never
kubectl create -f pod-restartpolicy.yaml
kubctl get pods  pod-restartpolicy.yaml -n dev -w

-w 动态检测

在这里插入图片描述

因为探针会出现错误,重启策略是Always所以会不断的重启。改为Never 的运行结果。

在这里插入图片描述

一直没有启动。

Pod 调度

在默认情况下,一个Pod在哪个节点上运行,是由Scheduler组件采用相应的算法计算出来的。这个过程是不受人工控制德的,但在实际情况中,这并不满足需求,因为在很多的情况下,我们想控制某些pod 到达某些节点上,那么应该怎么做? 这就需要完全了解K8s对Pod 的调度规则,K8s 提供了四大调度策略。

  • 自动调度: 运行在哪个节点上完全是由Scheduler 经过一系列算法计算得出的。
  • 定向调度方式: NodeName,NodeSelector
  • 清和调度方式: NodeAffinity,PodAffinity,PodAntiAffinity
  • 污点(容忍)调度方式: Taints,Toleration
定向调度

​ 定向调度是指利用在pod 上声明的NodeName 或者NodeSelector,以此将Pod 调度到期望的node 节点上去,注意这些调度是强制性的,这就意味着即使要调度的目标Node 不存在,也会向上面进行调度。只不过pod 运行失败而已。

NodeName: NodeName 用于强制约束将pod 调度到指定的Name 的Node 节点上,这种方式,是直接跳过Scheduler 的调度逻辑,直接写入PodList 列表。

创建pod-nodename.yaml 文件

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodename
  namespace: dev
spec:
  containers:
  -  name: nginx
     image: nginx:1.17.1
  nodeName: minikube # 指定调度到minikube节点上

通过下面命令,查看集群中节点的名称

kubectl get nodes

在这里插入图片描述

nginx 容器正常运行。

查看详细信息

kubectl get pod pod-nodename -n dev -o wide

在这里插入图片描述

NodeSelector:

​ NodeSelector 用于将pod 调度到添加了指定标签的node 节点上,它是通过k8s 的 label-selector 机制实现的,也就是说,在pod 创建之前,会由scheduler 使用MatchNodeSelector 调度策略进行label 匹配。找出目标的node,然后将pod 调度到目标节点,该匹配规则是强制约束。

nodeName 是看node名, NodeSelector 是看node 的标签,所以首先需要给node 打上相关的标签。

模拟一个场景,在一个k8s 集群中,有一个master 节点和两个node 节点,使用NodeSelector进行调度。

1 首先分别给node节点添加标签

kubectl label nodes node1 nodeenv=pro

kubectl label nodes node2 nodeenv=test

分别给node1打 nodeenv:pro 标签,node2打nodeenv:test 标签

2 创建pod-nodeselector.yaml 文件

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeselector
  namespace: dev
spec:
  containers:
  -  name: nginx
     image: nginx:1.17.1
  nodeSelector:
    nodeenv: pro # 将当前pod 调度到标签为pro的节点上

成功。

亲和性调度

定向调度的缺点: 是强制调度的,如果没有满足条件的Node 。那么pod 将不会被运行。即使在集群中还有可用的Node 列表也不行。这就限制了它的使用场景。

基于定向调度的缺点,K8s 提出了一种亲和性调度(Affinity)。 它在NodeSelector 的基础之上进行了扩展。可以通过配置的形式,实现优先选择满足条件的Node 进行调度,如果没有,也可以调度到不满足条件的节点上,使得调度更加灵活。

Affinity 主要分为三类

  • nodeAffinity(node 亲和性): 以node 为目标解决pod 可以调度到哪些node 的问题

  • podAffinity( pod 亲和性): 以pod为目标,解决pod 可以与哪些已存在的pod 部署在同一拓扑域中的问题

  • podAntAffinity (pod 反亲和性): 以pod 为目标,解决pod 不能和哪些已存在的pod 部署在同一拓扑域中的问题

亲和性(反亲和性)使用场景说明:

​ 亲和性: 如果两个应用频繁交互,那么有必要利用亲和性让两个应用尽可能的靠近,这样就可以减少因为网络通信而带来的性能损耗。

​ 反亲和性: 当应用采用多副本进行部署的时候,有必要 采用反亲和性让各个应用实例打散分布在各个node 上,这样就可以提高服务的高可用性。

nodeAffinity

​ nodeAffinity 的可配置项:

​ 层级关系 pod.spec.affinity.nodeAffinity

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l0j1uzar-1637368165579)(D:\java workstation\笔记\浪潮\images\image-20211118153419451.png)]

看图,如硬限制和软限制之分

关系符的使用说明:

​ matcgExpressions 与matchFields ,推荐使用 matcgExpressions

在这里插入图片描述

创建pod-nodeaffinity-requied.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeaffinity-requied
  namespace: dev
spec:
  containers:
  -  name: nginx
     image: nginx:1.17.1
  affinity: #亲和性设置
    nodeAffinity: # 设置node 亲和性
      requiredDuringSchedulingIgnoredDuringExecution: #硬限制
        nodeSelectorTerm:
        - matchExpressions:
          - key: nodeenv
            operator: In
            values: ["xxx","yyy"]

没有标签 key 为nodenv value 为"xxx" 或 “yyy” 的Pod,就会报错。

可以把硬限制改为软限制

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeaffinity-requied
  namespace: dev
spec:
  containers:
  -  name: nginx
     image: nginx:1.17.1
  affinity: #亲和性设置
    nodeAffinity: # 设置node 亲和性
      preferredDuringSchedulingIgnoredDuringExecution: #硬限制
        - weight: 1
        - matchExpressions:
          - key: nodeenv
            operator: In
            values: ["xxx","yyy"]


K8s 官网交互环境应用指南

交互式环境网址: https://kubernetes.io/zh/docs/tutorials/kubernetes-basics/

K8 官网交互式应用可以学习到

  • 在集群上部署容器化应用程序
  • 弹性部署
  • 使用新的软件版本,更新容器化应用程序
  • 调试容器化应用程序

K8s 能做什么:

现代的Web 服务,用户希望应用程序能够 24/7 全天候使用,开发人员希望每天可以多次发布部署新版本的应用程序。 容器化可以帮助软件包达成这些目标,使应用程序能够以简单快速的方式发布和更新,而无需停机。Kubernetes 帮助您确保这些容器化的应用程序在您想要的时间和地点运行,并帮助应用程序找到它们需要的资源和工具。Kubernetes 是一个可用于生产的开源平台,根据 Google 容器集群方面积累的经验,以及来自社区的最佳实践而设计。

K8s 基础模块

在这里插入图片描述

处理生产级别流量的K8s 集群至少具备三个Node

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐