前言
环境:centos7.9 docker-ce-20.10.9 kubernetes-version v1.22.6
介绍pod
在kubernetes的世界中,k8s并不直接处理容器,而是使用多个容器共存的理念,这组容器就叫做pod。
pod是k8s中可以创建和管理的最小单元,是资源对象模型中由用户创建或部署的最小资源对象模型,其他的资源对象都是用来支撑pod对象功能的,比如,pod控制器就是用来管理pod对象的,service或者imgress资源对象是用来暴露pod引用对象的,persistentvolume资源
是用来为pod提供存储等等,简而言之,k8s不会直接处理容器,而是pod,pod才是k8s中可以创建和管理的最小单元,也是基本单元。
pod的特点
1、每个pod就像一个独立的逻辑机器,k8s会为每个pod分配一个集群内部唯一的IP地址,所以每个pod都拥有自己的IP地址、主机名、进程等;
2、一个pod可以包含1个或多个容器,pod的生命周期是短暂,也就是pod可能随时被消亡(如节点异常,pod异常等情况);
2、每一个pod都有一个特殊的被称为"根容器"的pause容器,也称info容器,pause容器对应的镜像属于k8s平台的一部分,除了pause容器,每个pod还包含一个或多个跑业务相关组件的容器;
3、一个pod中的容器共享网络命名空间;
4、一个pod里的多个容器共享pod IP;
pod实现共享网络实现机制:首先pod会创建pause容器,把其他业务容器加入pause容器,
从而让所以业务容器都在同一个命名空间中,这样可是实现网络共享。
pod共享存储实现机制: 引入数据卷volume,使用数据卷进行持久化存储。
命令行创建pod、查看pod
[root@master ~]# kubectl run nginx --image=nginx:1.7.9 --labels="app=nginx" #创建一个pod,并设置标签为app=httpd
pod/nginx created
[root@master ~]# kubectl get pods -n default #查看pod,已经是运行状态
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 43s
[root@master ~]# kubectl get pod nginx -n default -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 75s 10.244.1.28 node1 <none> <none>
[root@master ~]#
kubectl describe 命令查看pod的详细信息
[root@master ~]# kubectl describe pod nginx #使用kubectl describe命令来查看我们刚才创建的pod的详细信息
Name: nginx #pod的名称为nginx
Namespace: default #pod的所属命名空间
Priority: 0 #这个参数是优先级,暂时不用管
Node: node1/192.168.118.132 #pod所在节点
Start Time: Mon, 14 Feb 2022 22:40:55 +0800 #pod启动时间
Labels: app=nginx #标签
Annotations: <none>
Status: Running #状态
IP: 10.244.1.28 #pod的IP,前面我们介绍pod的时候说过,pod就像一个逻辑机器,有着自己的IP
IPs:
IP: 10.244.1.28
Containers: #容器部分,一个pod可以跑多个容器
nginx: #
Container ID: docker://042179fde4baa7138ac0213bbfb99dd5f02bf915cd91d0ae38982b2bdd30cb9a #容器ID
Image: nginx:1.7.9 #镜像
Image ID: docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206a94affb40e0714846c451 #镜像ID
Port: <none>
Host Port: <none>
State: Running #容器状态
Started: Mon, 14 Feb 2022 22:40:56 +0800 #容器启动时间
Ready: True #是否准备就绪
Restart Count: 0 #重启次数
Environment: <none>
Mounts: #容器挂载点
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-n5gcr (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-n5gcr:
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 38m default-scheduler Successfully assigned default/nginx to node1
Normal Pulled 38m kubelet Container image "nginx:1.7.9" already present on machine
Normal Created 38m kubelet Created container nginx
Normal Started 38m kubelet Started container nginx
[root@master ~]#
查看pod的yaml文件
[root@master ~]# kubectl get pod nginx -o yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2022-02-14T14:40:55Z"
labels:
app: nginx
name: nginx
namespace: default
resourceVersion: "488083"
uid: dff1bcac-b229-4a5d-803d-d003a4311437
spec:
containers:
- image: nginx:1.7.9
imagePullPolicy: IfNotPresent
name: nginx
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-n5gcr
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
nodeName: node1
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: kube-api-access-n5gcr
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
status:
conditions:
- lastProbeTime: null
lastTransitionTime: "2022-02-14T14:40:55Z"
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: "2022-02-14T14:40:57Z"
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: "2022-02-14T14:40:57Z"
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: "2022-02-14T14:40:55Z"
status: "True"
type: PodScheduled
containerStatuses:
- containerID: docker://042179fde4baa7138ac0213bbfb99dd5f02bf915cd91d0ae38982b2bdd30cb9a
image: nginx:1.7.9
imageID: docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451
lastState: {}
name: nginx
ready: true
restartCount: 0
started: true
state:
running:
startedAt: "2022-02-14T14:40:56Z"
hostIP: 192.168.118.132
phase: Running
podIP: 10.244.1.28
podIPs:
- ip: 10.244.1.28
qosClass: BestEffort
startTime: "2022-02-14T14:40:55Z"
[root@master ~]#
对外暴露服务、测试访问
以上我们创建了一个名为nginx的pod,但是这个pod还不能被外部客户端连接访问,我们还需要做一步,就是对外暴露pod,让外部客户端能访问k8s集群的pod服务,如下所示:
# --port=8088 表示指定集群内部访问端口,--target-port=80表示pod里面容器的应用程序端口
# 节点端口,即客户外部访问端口是自动生成的
[root@master ~]# kubectl expose pod nginx -n default --port=8088 --target-port=80 --type=NodePort --name=nginx
service/nginx exposed
[root@master ~]# kubectl get pod,svc -n default
NAME READY STATUS RESTARTS AGE
pod/nginx 1/1 Running 0 2m34s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d
service/nginx NodePort 10.103.207.241 <none> 8088:30295/TCP 14s #8088为集群内部访问端口,30295为外部访问端口
[root@master ~]# curl http://10.103.207.241:8088 #使用集群内部IP+内部端口8088访问,能成功访问
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@master ~]#
在浏览器访问,任意一个节点的IP+30295端口都能访问到nginx,如下图所示:
编辑service
如果需要修改外部访问端口或者需要修改一下刚才定义的service,这时我们可以使用kubectl edit 编辑刚才创建的service,如下:
[root@master ~]# kubectl edit service nginx #编辑我们刚才创建的名为nginx的服务
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2022-02-14T14:43:15Z"
labels:
app: nginx
name: nginx
namespace: default
resourceVersion: "488275"
uid: e935f0c2-3f8b-48a0-b592-eae3332e40b1
spec:
clusterIP: 10.103.207.241
clusterIPs:
- 10.103.207.241
externalTrafficPolicy: Cluster
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- nodePort: 30005 #修改一下对外暴露的端口为30005,注意:端口是有范围了,不能随便定义
port: 8088
protocol: TCP
targetPort: 80
selector:
app: nginx
sessionAffinity: None
type: NodePort
status:
loadBalancer: {}
~
"/tmp/kubectl-edit-3488312699.yaml" 34L, 785C written
service/nginx edited #修改完成之后保存退出,k8s会立即自动应用你做的修改
[root@master ~]# kubectl get pod,svc -n default #查看service,发现外部端口已经改成了30005,浏览器就能使用这个端口来访问了
NAME READY STATUS RESTARTS AGE
pod/nginx 1/1 Running 0 26m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d
service/nginx NodePort 10.103.207.241 <none> 8088:30005/TCP 23m
[root@master ~]#
以上我们创建了一个跑nginx服务的pod,也使用service对外暴露了pod,这样外部客户就能访问k8s集群里pod的容器里nginx服务了,但是以上我们创建的pod是不受任何控制的,换句话说就是pod出现异常挂掉了就挂掉了,k8s不会帮你重启pod;在实际的生产环境中,我们并不是直接创建pod,而是创建pod控制器,所谓pod控制器,就是用来管理pod,其具有上线部署、副本设定、滚动升级、回滚等诸多功能。关于pod控制的讲解,我们不在本篇论述。