1 简单使用Pod
Pod是k8s的基本单位。一个pod可以由一个或多个关系紧密的容器构成。
1.1 创建Pod
(1)创建模板文件”myalpinepod.yaml“
# myalpinepod.yaml
# 注意键值对中的“空格”
# 使用v1版本的API
apiVersion: v1
# 设置创建的资源对象
kind: Pod
# 设置该资源对象的元数据
metadata:
# 设置资源对象的名称
name: myalpinepod
# 设置资源对象标签
labels:
app: myalpinepodlabel
# 设置资源对象的详细数据
spec:
# 配置容器
containers:
# 容器名称
- name: myalpinepod-container
# 配置镜像
image: alpine:3.12
# 配置镜像下载策略,ifNotPresent表示只有镜像不存在时,才会拉取
imagePullPolicy: IfNotPresent
# 容器启动的参数
command: ["/bin/sh","-c","--"]
args: ["while true; do sleep 30; done;"]
# 设置重启策略,Never表示不再重启该pod
# 注意:k8s中不支持重启、停止、启动Pod资源,只有删除重建
# 因为Pod是一个运行服务的实例,随时有可能在一个Node上停止,在另一个Node重建
restartPolicy: Never
(2)执行模板文件,生成Pod
kubectl apply -f myalpinepod.yaml
1.2 查看Pod
# 查看Pod
# -A: 显示所有Pod
kubectl get pod
NAME READY STATUS RESTARTS AGE
myalpinepod 0/1 Running 0 5s
# 查看Pod的更多概要信息
# -o json: 表示以json方式查看Pod详细信息
# -o yaml: 表示以yaml方式查看Pod详细信息
kubectl get pod -o wide
# 实时监控Pod
kubectl get pod -w
# 查看myalpinepod的详细信息
kubectl describe pods myalpinepod
# 查看myalpinepod的日志
kubectl logs myalpinepod
1.3 删除Pod
# 基于Pod删除
kubectl delete pod myalpinepod
# 基于模板文件删除
kubectl delete -f myalpinepod.yaml
# 当修改完yaml文件后,可以使用replace更新Pod
kubectl replace -f myalpinepod.yaml --force
1.4 进入Pod
# 查看Pod中的容器
kubectl get pods myalpinepod -o jsonpath={.spec.initContainers[*].name}
# 进入指定容器执行命令:
# kubectl exec -it <pod-name> -- /bin/bash
# 注意也有可能是 /bin/sh
# kubectl exec -it <pod-name> -- /bin/sh
kubectl exec -it myalpinepod /bin/sh
1.5 Pod模板
查看Pod模板配置
kubectl explain pod
详细配置如下:
# k8s配置模板
# 必选,版本号
apiVersion: v1
# 必选,Pod
kind: Pod
# 必选,元数据
metadata:
# 必选,Pod名称
name: string
# 必选,Pod所属的命名空间,默认加入defaul命名空间
namespace: string
# 自定义标签
labels:
# 自定义标签名字
- name: string
# 自定义注释列表
annotations:
- name: string
# 必选,Pod中容器的详细定义
spec:
# 必选,Pod中容器列表
containers:
# 必选,容器名称
- name: string
# 必选,容器的镜像名称
image: string
# 获取镜像的策略 Alawys表示下载镜像 IfnotPresent表示优先使用本地镜像,否则下载镜像,Nerver表示仅使用本地镜像
imagePullPolicy: [Always | Never | IfNotPresent]
# 容器的启动命令列表,如不指定,使用打包时使用的启动命令
command: [string]
# 容器的启动命令参数列表
args: [string]
# 容器的工作目录
workingDir: string
# 挂载到容器内部的存储卷配置
volumeMounts:
# 引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
- name: string
# 存储卷在容器内mount的绝对路径,应少于512字符
mountPath: string
# 是否为只读模式
readOnly: boolean
# 需要暴露的端口库号列表
ports:
# 端口号名称
- name: string
# 容器需要监听的端口号
containerPort: int
# 容器所在主机需要监听的端口号,默认与Container相同
hostPort: int
# 端口协议,支持TCP和UDP,默认TCP
protocol: string
# 容器运行前需设置的环境变量列表
env:
# 环境变量名称
- name: string
# 环境变量的值
value: string
# 资源限制和请求的设置
resources:
# 资源限制的设置
limits:
# cpu限制,单位为core数,将用于docker run --cpu-shares参数
cpu: string
# 内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
memory: string
# 资源请求的设置
requests:
# cpu请求,容器启动的初始可用数量
cpu: string
# 内存请求,容器启动的初始可用数量
memory: string
# 对Pod内容器健康检查的设置,当探测无响应几次后将自动重启该容器,检查方法有exec、httpGet和tcpSocket,对一个容器只需设置其中一种方法即可
livenessProbe:
# 对Pod容器内检查方式设置为exec方式
exec:
# exec方式需要制定的命令或脚本
command: [string]
# 对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
httpGet:
path: string
port: number
host: string
scheme: string
HttpHeaders:
- name: string
value: string
# 对Pod内个容器健康检查方式设置为tcpSocket方式
tcpSocket:
port: number
# 容器启动完成后首次探测的时间,单位为秒
initialDelaySeconds: 0
# 对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
timeoutSeconds: 0
# 对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
periodSeconds: 0
successThreshold: 0
failureThreshold: 0
securityContext:
privileged: false
# Pod的重启策略,Always表示一旦不管以何种方式终止运行,kubelet都将重启,OnFailure表示只有Pod以非0退出码退出才重启,Nerver表示不再重启该Pod
restartPolicy: [Always | Never | OnFailure]
# 设置NodeSelector表示将该Pod调度到包含这个label的node上,以key:value的格式指定
nodeSelector: obeject
# Pull镜像时使用的secret名称,以key:secretkey格式指定
imagePullSecrets:
- name: string
# 是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
hostNetwork: false
# 在该pod上定义共享存储卷列表
volumes:
# 共享存储卷名称 (volumes类型有很多种)
- name: string
# 类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录,为空值
emptyDir: {}
# 类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
hostPath:
# Pod所在宿主机的目录,将被用于同期中mount的目录
path: string
# 类型为secret的存储卷,挂载集群与定义的secre对象到容器内部
secret:
scretname: string
items:
- key: string
path: string
# 类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
configMap:
name: string
items:
- key: string
path: string
1.6 常见Pod的状态
相位值(或状态) | 说明 |
Pending | Pod创建成功 |
Running | Pod已绑定到Node,容器创建成功,至少有一个容器还在运行 |
Succeeded | Pod中全部容器已成功终止 |
Failed | Pod中全部容器已终止,但至少有一个容器表现出失败终止状态 |
Completed | Pod内容器创建成功,但容器启动失败 |
CrashLoopBackOff | 容器退出,kubelet正在将它重启 |
ContainerCreating | 容器创建中 |
RunContainerError | 启动容器失败 |
InvalidImageName | 无法解析镜像名称 |
CreateContainerError | 创建容器失败 |
2 简单使用控制器
2.1 k8s中的控制器
一般情况下,用户不需要直接创建Pod,而是直接创建控制器,由控制器直接管理Pod。
控制器 | ||
Deployment | 适合无状态的服务部署,用来创建Pod和ReplicaSet滚动更新和回滚扩容和缩容暂停与恢复 | |
DaemonSet | 在集群中的各个Node上运行且仅运行一个副本 | |
Job | 基于某一特定任务而运行,当运行任务的容器完成工作后,就成功退出 | |
ConJob | 它是在Job的基础上添加了时间调度,可以在设定的时间运行任务,也可以定期运行任务 | |
StatefulSet | 适合有状态的服务部署,它是一种提供排序和唯一性保证的特殊Pod控制器 | |
ReplicaSet | 保证副本数量一直维持在期望值,并支持pod数量扩缩容,镜像版本升级 |
2.2 创建Deployment控制器
Deployment的功能支持ReplicaSet 的所有功能,支持发布的停止、继续,支持版本的滚动更新和回退功能。
(1)创建模板文件”nginxDeployment.yaml“
# nginxDeployment.yaml
# 选择版本号,apps/v1表示K8s API的稳定版
apiVersion: apps/v1
# 设置创建的资源对象
kind: Deployment
# 设置该资源对象的信息
metadata:
# 资源名称
name: nginxdeployment
# 设置资源的命名空间,可以不设置默认是“default”
# namespace: dev
# 设置资源对象的元数据
spec:
# 设置选择器,可以建立控制器和Pod之间的关系,控制器可使用标签管理Pod
selector:
# 设置自定义标签
matchLabels:
app: nginx-pod
# 设置控制器托管的Pod需要保持的副本数量
replicas: 3
# 设置Pod模板,当副本数量不足时,会根据下面的模板创建pod副本
template:
metadata:
labels:
# 此处必须要与上面的matchLabels相同
app: nginx-pod
spec:
containers:
- name: containernginx
image: nginx:1.20.0
imagePullPolicy: IfNotPresent
ports:
- name: portnginx
containerPort: 80
(2)执行模板文件,生成Deployment
# --record:在执行模板时,建议添加,它可以把每次修改Deployment控制器时使用的命令记录到备注字段中,便于后期维护控制器
kubectl apply -f myalpinepod.yaml --record
2.3 查看控制器
# 查看控制器
kubectl get deployment
# 查看控制器的概要信息
kubectl get deployment -o wide
# 实时监控Deployment
kubectl get deployment -w
# 查看nginxdeployment的详细信息
kubectl describe deployment nginxdeployment
2.4 删除控制器
kubectl delete deployment nginxdeployment
2.5 Deployment模板
# 必选,接口版本
apiVersion: apps/v1
# 必选,资源类型
kind: Deployment
# 元数据
metadata:
# 必选,控制器名称
name: String
# 控制器命名空间
namespace: String
# 自定义标签列表
labels:
key: value
spec:
# 设置选择器,可以建立控制器和Pod之间的关系,控制器可使用标签管理Pod
selector:
# 设置自定义标签
matchLabels:
key: value
# 设置Pod数量
replicas: int
# 设置Pod的更新策略
strategy:
# Recreate:先终止所有已存在的Pod,再创建出新的Pod
# RollingUpdate:滚动更新,终止一部分Pod,同时启动一部分Pod,在更新过程中,存在两个版本Pod
type: Recreate/RollingUpdate
rollingUpdate:
# 滚动更新时,在所需数量的Pod上,允许创建的最大Pod数量
maxSurge: int/int%
# 滚动更新时,同时存在最大不可用Pod数量
maxUnavailable: int/int%
# 必填,Pod的模板,参见Pod模板
template: [PodTemplate]
3 简单使用Service
Service是K8s内部服务注册与负载均衡的一种组件,对相同功能的Pod进行逻辑分组,实现使用唯一的地址访问资源和服务。Service可用于将K8s集群内部服务发布出去(向外发布),也可用于将外部服务引入进来或者仅对内部提供服务(向内发布)。Service向外发布的服务类型有ClusterIP(默认方式)、NodePort和LoadBalancer,向内发布的服务类型有HeadLinesss、ExternalName。此处,简单使用一下ClusterIP类型。
3.1 创建Deployment控制器
Deployment控制器提供Service向外发布服务。
(1)创建“python-deployment-for-service.yaml”Deployment模板
# python-deployment-for-service.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: python-deployment-for-service
spec:
replicas: 3
selector:
matchLabels:
app: python-for-service-pod
template:
metadata:
labels:
app: python-for-service-pod
spec:
containers:
- name: python-sevice
image: python:3.8.2
imagePullPolicy: IfNotPresent
command: ['/bin/bash', '-c', '--']
# 启动"python -m http.server 80"服务
args: ['echo "<p> The host is $(hostname) </p>" > index.html; python -m http.server 80']
# 设置80端口
ports:
- name: http
containerPort: 80
(2)执行模板文件
# 执行控制器
kubectl apply -f python-deployment-for-service.yaml --record
(3)查看控制器
# 查看控制器详细信息
kubectl get deployment -o wide
# 查看Pod
kubectl get pod -o wide
# Pod的详细信息如下:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
python-deployment-for-service-5f54648c46-ccssn 1/1 Running 1 51m 10.12.1.20 mason-node2 <none> <none>
python-deployment-for-service-5f54648c46-gc8w2 1/1 Running 1 51m 10.12.1.21 mason-node2 <none> <none>
python-deployment-for-service-5f54648c46-gztgw 1/1 Running 1 51m 10.12.1.22 mason-node2 <none> <none>
# 查看Pod服务
kubectl get pod -o wide
# 查看单个pod提供的服务
curl 10.12.1.20
# 返回值信息如下
<p> The host is python-deployment-for-service-5f54648c46-ccssn </p>
(4)出现Pod节点无法ping通
可以在每个子节点中执行以下命令
# iptables是Linux平台下包过滤防火墙,注意Ubuntu下需要添加sudo
# Centos下
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
iptables -L -n
# ubuntu下
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -F
sudo iptables -L -n
3.2 创建Service服务
3.2.1 创建ClusterIP类型
(1)创建“python-clusterip-service.yaml”模板
# python-clusterip-service.yaml
apiVersion: v1
# 服务资源
kind: Service
# 元数据
metadata:
# 服务名称
name: python-clusterip-service
spec:
# 标签选择器
selector:
# 注意:此处一定要与python-deployment-for-service.yaml中的labels对应
app: python-for-service-pod
# Service类型
type: ClusterIP
# 设置端口
ports:
# 设置协议
- protocol: TCP
# Service端口
port: 8080
# 应用端口(Pod端口)
targetPort: 80
(2)执行模板
kubectl apply -f python-clusterip-service.yaml
(3)查看执行结果
# 内部查看,“10.11.62.32”是python-clusterip-service的IP
curl 10.11.62.32:8080
# 返回值
<p> The host is python-deployment-for-service-bfb9ccbfb-7b48d </p>
3.2.2 创建NodePort类型
(1)创建“python-nodeport-service.yaml”模板
# python-nodeport-service.yaml
apiVersion: v1
# 服务资源
kind: Service
# 元数据
metadata:
# 服务名称
name: python-nodeport-service
spec:
# 标签选择器
selector:
# 注意:此处一定要与python-deployment-for-service.yaml中的labels对应
app: python-for-service-pod
# Service类型
type: NodePort
# 设置端口
ports:
# 设置协议
- protocol: TCP
# Service端口
port: 8080
# 应用端口(Pod端口)
targetPort: 80
# 映射到主机的端口
nodePort: 30001
(2)执行模板
kubectl apply -f python-nodeport-service.yaml
(3)查看效果
# 内部查看,“10.11.240.208”是python-nodeport-service的IP
curl 10.11.240.208:8080
# 返回值
<p> The host is python-deployment-for-service-bfb9ccbfb-h4j2t </p>
# 使用节点查看,“192.168.108.100”是Master节点的IP
curl 192.168.108.100:30001
# 返回值
<p> The host is python-deployment-for-service-bfb9ccbfb-9wgms </p>
在浏览器中查看
3.3 查看Service
# 可以将service换成svc
# 查看Service
kubectl get service -o wide
# 详细信息如下
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.11.0.1 <none> 443/TCP 2d
python-clusterip-service ClusterIP 10.11.62.32 <none> 8080/TCP 3s
python-nodeport-service NodePort 10.11.240.208 <none> 8080:30001/TCP 12m
# 查看Service的详细信息
kubectl describe service python-clusterip-service
3.4 删除Service
# 删除clusterIP服务
kubectl delete service python-clusterip-service
# 删除NodePort服务
kubectl delete service python-nodeport-service
3.5 Service模板
# 版本
apiVersion: v1
# 服务资源
kind: Service
# 元数据
metadata:
# 服务名称
name: String
# Service所属的命名空间
namespace: String
# Service标签
labels:
- name: String
# Service注解
annotations:
- name: String
spec:
# 注意:标签选择器,键值对,管理指定标签的Pod,对应控制器中的labels,非常重要
selector: []
# Service类型, ClusterIP、NodePort、LoadBalancer、ExternalName
type: String
# 设置端口
ports:
# 端口名称
- name: String
# 设置协议
protocol: TCP
# Service端口
port: int
# 应用端口(Pod端口)
targetPort: int
# 当spec.type=NodePort时,设置映射到主机的端口,端口范围是30000~32767
nodePort: int
# 当spec.type=LoadBalancer时,设置外部负载均衡的地址
status:
loadBalancer:
ingress:
# 外部负载均衡的IP地址
ip: String
# 外部负载均衡的主机名
hostname: String