首页 > 其他 > 详细

(五)K8S 深入理解pod

时间:2020-03-23 00:07:52      阅读:57      评论:0      收藏:0      [点我收藏+]
基础知识

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 相关控制

(五)K8S 深入理解pod

原文:https://blog.51cto.com/1014810/2480815

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!