pod是kubernetes最基本的执行单元(最小、最简单的单元),pod表示在集群上运行的进程。
pod封装了应用程序容器(某些情况下多个容器),存储资源、唯一网络IP、以及控制器该如何运行的选项。
运行单个容器的pod:一个pod运行一个容器是kubernetes最常见的。
运行多个容器的pod:pod可能封装多个紧密耦合且需要共享资源的共处容器组成的应用程序。
如果希望横向扩展应用程序,则应该使用多个pod,在kubernetes中,称为副本。
pod是短暂的。
网络
每个pod分配一个唯一的IP地址,pod的每个容器共享网络命名空间。包括IP地址和端口。pod内的容器可以使用localhsot相互通信。
存储
一个pod可以指定一组共享存储卷。pod中所有的容器都可以访问共享卷,允许这些容器共享数据。卷数据可以持久化
pod的分类
Infrastructure Container 基础容器
在node节点:cat /opt/kubernetes/cfg/kubelet.kubeconfig 可以看到指定的容器,每创建一个pod都会创建一个,和pod一一对应。
在node节点:通过 docker ps 会看到name为*/pause-amd64:3.0的就是了。
负责维护pod的网络空间。
该容器对用户无感知,由后台自动完成。
InitContainers 初始化容器
在pod启动时,在主容器启动前执行初始化工作。
参考简书 https://www.jianshu.com/p/2f3736deb16f
参考官网 https://kubernetes.io/zh/docs/concepts/workloads/pods/init-containers/
containers 业务容器
我们主要使用的容器
##init 初始化先于业务容器执行
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: [‘sh‘, ‘-c‘, ‘echo The app is running! && sleep 3600‘]
initContainers:
- name: init-myservice
image: busybox:1.28
command: [‘sh‘, ‘-c‘, ‘until nslookup myservice; do echo waiting for myservice; sleep 2; done;‘]
- name: init-mydb
image: busybox:1.28
command: [‘sh‘, ‘-c‘, ‘until nslookup mydb; do echo waiting for mydb; sleep 2; done;‘]
pod的意义
解决一个docker容器只运行一个程序的限制;pod是多进程模型,可以运行多个应用程序,每个程序由容器来管理。
某些亲密性应用场景是需要多个容器一起运行的;例如:频繁交互数据的两个应用,通过localhost相互访问可以提高性能,防止出现跨节点、跨网络的通信。
镜像拉取策略
官方参考地址:https://kubernetes.io/docs/concepts/containers/images/
?IfNotPresent:默认值,镜像在宿主机上不存在时才拉取
?Always:每次创建Pod 都会重新拉取一次镜像
?Never:Pod 永远不会主动拉取这个镜像
#要先任意一个node节点登录一下 docker login 10.192.27.115 就用在/root/.docker/config.json下面留下凭据
[root@node01 image]# cat /root/.docker/config.json #账号:0216000942 密码:Harbor12345
{
"auths": {
"10.192.27.111": {
"auth": "MDIxNjAwMDk0MjpIYXJib3IxMjM0NQ=="
}
},
"HttpHeaders": {
"User-Agent": "Docker-Client/18.09.4 (linux)"
}
}[root@node01 image]#
[root@node01 image]# cat /root/.docker/config.json |base64 #base64编码方式
ewoJImF1dGhzIjogewoJCSIxMC4xOTIuMjcuMTExIjogewoJCQkiYXV0aCI6ICJNREl4TmpBd01E
azBNanBJWVhKaWIzSXhNak0wTlE9PSIKCQl9Cgl9LAoJIkh0dHBIZWFkZXJzIjogewoJCSJVc2Vy
LUFnZW50IjogIkRvY2tlci1DbGllbnQvMTguMDkuNCAobGludXgpIgoJfQp9
[root@node01 image]# cat /root/.docker/config.json |base64 -w 0 #转化成一行
ewoJImF1dGhzIjogewoJCSIxMC4xOTIuMjcuMTExIjogewoJCQkiYXV0aCI6ICJNREl4TmpBd01EazBNanBJWVhKaWIzSXhNak0wTlE9PSIKCQl9Cgl9LAoJIkh0dHBIZWFkZXJzIjogewoJCSJVc2VyLUFnZW50IjogIkRvY2tlci1DbGllbnQvMTguMDkuNCAobGludXgpIgoJfQp9[root@node01 image]#
在master创建一个密钥配置文件
#master节点上创建一个秘钥配置文件
[root@master01 yaml_doc]# vim registry-pull-secret.yaml #创建一个Secret的yaml文件
apiVersion: v1
kind: Secret
metadata:
name: registry-pull-secret
data:
.dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxMC4xOTIuMjcuMTExIjogewoJCQkiYXV0aCI6ICJNREl4TmpBd01EazBNanBJWVhKaWIzSXhNak0wTlE9PSIKCQl9Cgl9LAoJIkh0dHBIZWFkZXJzIjogewoJCSJVc2VyLUFnZW50IjogIkRvY2tlci1DbGllbnQvMTguMDkuNCAobGludXgpIgoJfQp9
type: kubernetes.io/dockerconfigjson
[root@master01 yaml_doc]# kubectl create -f registry-pull-secret.yaml
[root@master01 yaml_doc]# kubectl get secrets
NAME TYPE DATA AGE
default-token-sj2lw kubernetes.io/service-account-token 3 9d
registry-pull-secret kubernetes.io/dockerconfigjson 1 176m
[root@master01 yaml_doc]#
pod测试
#master节点上创建一个pod
[root@master01 yaml_doc]# vim nginx-pod.yaml #创建一个pod的yaml文件
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
namespace: default
labels:
app: nginx-pod
spec:
imagePullSecrets: #使用密钥配置文件
- name: registry-pull-secret
containers:
- name: nginx
image: 10.192.27.111/project/nginx:latest
imagePullPolicy: IfNotPresent ##镜像拉取策略
command: [ "/bin/bash", "-ce", "tail -f /dev/null" ]
ports:
- containerPort: 80
[root@master01 yaml_doc]# kubectl create -f nginx-pod.yaml
pod/nginx-pod created
[root@master01 yaml_doc]# kubectl get pods -o wide #查看pod分配到哪个node节点 PodIP是172.17.46.2
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pod 1/1 Running 0 2m26s 172.17.46.2 10.192.27.116 <none> <none>
创建一个server 访问
#master节点上创建一个server
[root@master01 yaml_doc]# vim nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service-mxxl
spec:
type: NodePort #server负载均衡模式之一:暴露IP端口 默认是ClusterIP
ports:
- port: 80 #集群server端口
nodePort: 30080 #外部端口
selector: #匹配便签为nginx-pod的pod
app: nginx-pod
[root@master01 yaml_doc]# kubectl create -f nginx-service.yaml
service/nginx-service-mxxl created
[root@master01 yaml_doc]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 9d
nginx-service-mxxl NodePort 10.0.0.65 <none> 80:30080/TCP 5s #分配集群IP(可能对应一组pod)和Port为10.0.0.65:80《---- nodeIP:30080
#访问方式:
#浏览器:http://nodeIP:30080
[root@node01 ~]# curl 172.17.46.2 #访问podIP
[root@node01 ~]# curl 10.0.0.65 #访问集群IP
#学习一个命令
kubectl edit pod/nginx-pod #相当于 vim nginx-pod.yaml kubectl apply -f nginx-pod.yam 编辑后立即生效
资源限制
官方参考地址 https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
Pod和Container的资源请求和限制:
?spec.containers[].resources.limits.cpu
?spec.containers[].resources.limits.memory
?spec.containers[].resources.requests.cpu
?spec.containers[].resources.requests.memory
创建一个资源限制的容器示例
[root@master01 yaml_doc]# cat resources-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: db
image: 10.192.27.111/project/mysql:5.7
imagePullPolicy: IfNotPresent
command: [ "/bin/bash", "-ce", "tail -f /dev/null" ]
env:
- name: MYSQL_ROOT_PASSWORD
value: "Harbor12345"
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi" #最大128M
cpu: "500m" #最大半个CPU
- name: wp
image: 10.192.27.111/project/wordpress:latest
imagePullPolicy: IfNotPresent
command: [ "/bin/bash", "-ce", "tail -f /dev/null" ]
resources:
requests:
memory: "1G"
cpu: 0.5
limits:
memory: "2G"
cpu: 1
[root@master01 yaml_doc]# kubectl create -f resources-pod.yaml
pod/frontend created
[root@master01 yaml_doc]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
frontend 2/2 Running 0 8m23s 172.17.43.2 10.192.27.115 <none> <none>
nginx-pod 1/1 Running 0 20h 172.17.46.2 10.192.27.116 <none> <none>
[root@master01 yaml_doc]#
查看完整的pod创建信息
grep -A -B -C
-A -B -C 后面都跟阿拉伯数字
-A是显示匹配后和它后面的n行。
-B是显示匹配行和它前面的n行。
-C是匹配行和它前后各n行。
总体来说,-C覆盖面最大,这3个开关都是关于匹配行的上下文的(context)
kubectl describe pod frontend | grep -A 20 Events
重启策略(restartPolicy)
?Always:当容器终止退出后,总是重启容器,默认策略。
?OnFailure:当容器异常退出(退出状态码非0)时,才重启容器。
?Never::当容器终止退出,从不重启容器。
cat restart-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: restart-pod
spec:
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: nginx
image: 10.192.27.111/project/nginx:latest
imagePullPolicy: IfNotPresent
# command: [ "/bin/bash", "-ce", "tail -f /dev/null" ]
args:
- /bin/sh
- -c
- sleep 30; exit 0
restartPolicy: Always #当容器终止退出后,总是重启容器,默认策略。
学习一个命令
kubectl get ep #service endpoint
#endpoint是k8s集群中的一个资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址。service配置selector(关联一组pod),endpoint controller才会自动创建对应的endpoint对象;否则,不会生成endpoint对象。例如,k8s集群中创建一个名为nginx-service-mxxl的service,就会生成一个同名的endpoint对象,ENDPOINTS就是service关联的pod的ip地址和端口。
健康检查(Probe)
Probe有以下两种类型:
livenessProbe:如果检查失败,将杀死容器,根据Pod的restartPolicy来操作。 #根据 四、 重启机制
readinessProbe:如果检查失败,Kubernetes会把Pod从service endpoints中剔除。#剔除endpoints
官方详细介绍了:https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/
Probe支持以下三种检查方法:
httpGet:发送HTTP请求,返回200-400范围状态码为成功。
exec:执行Shell命令返回状态码是0为成功。
tcpSocket:发起TCP Socket建立成功。
livenessprobe 演示
[root@master01 yaml_doc]# cat liveness-pod.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: liveness
image: 10.192.27.111/project/busybox:latest
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy #如果这个文件不存在返回的状态码非零 echo $? 就是会重启容器
initialDelaySeconds: 5 # 容器启动五秒之后启动健康检查
periodSeconds: 5 #间隔5执行健康检查
[root@master01 yaml_doc]# kubectl get pods
NAME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 0 52s
[root@master01 yaml_doc]#
NAME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 1 53s #重启了一次
liveness检查示例
调度约束
nodeName用于将Pod调度到指定的Node名称上
nodeSelector用于将Pod调度到匹配Label的Node上
指定node 创建pod
############指定node节点创建pod########
[root@master01 yaml_doc]# cat nodeName-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
namespace: default
labels:
app: nginx-pod
spec:
nodeName: 10.192.27.115 ##调度到指定node
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: nginx
image: 10.192.27.111/project/nginx:latest
imagePullPolicy: IfNotPresent
command: [ "/bin/bash", "-ce", "tail -f /dev/null" ]
ports:
- containerPort: 80
##指定node节点创建pod
使用标签的方式
[root@master01 yaml_doc]# kubectl label nodes 10.192.27.115 team=a #给每个node设置标签
node/10.192.27.115 labeled
[root@master01 yaml_doc]# kubectl label nodes 10.192.27.116 team=b
node/10.192.27.116 labeled
[root@master01 yaml_doc]# kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
10.192.27.115 Ready <none> 9d v1.13.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=10.192.27.115,team=a
10.192.27.116 Ready <none> 9d v1.13.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=10.192.27.116,team=b
[root@master01 yaml_doc]#
[root@master01 yaml_doc]# vim pod5.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-example
kind: Pod
metadata:
name: pod-example
labels:
app: nginx
spec:
nodeSelector:
team: a
containers:
- name: nginx
image: nginx:1.15
[root@master01 yaml_doc]# kubectl apply -f pod5.yaml
pod/pod-example created
故障排查
使用kubectl describe
pod 创建过程
1,用户通过kubectl 运行工具向api server 发送创建请求和相关yamil 参数
2,API Server处理用户请求,存储Pod数据到etcd。
3,调度器通过API Server查看未绑定的Pod。scheduler尝试为Pod分配主机,分配成功后叫bindpod 信息写入etcd里面
4,kubelet 接受到api server bindpod 绑定信息 运行conertion runtime
5,contioner runtime 返回状态信息给apiserver 并写入到etcd里面
如果使用相关控制器,在scheduler 前面 conerll-manger 相关控制
原文:https://blog.51cto.com/1014810/2480815