Kubernetes 之 Pod 基本原理

Kubernetes 之 Pod 基本原理

Pod 的定义

Pod是 Kubernetes 中的最小调度单元,k8s是通过定义一个Pod的资源,然后在Pod里面运行容器,容器需要指定一个镜像,这样就可以用来运行具体的服务。一个Pod封装一个容器,也可以封装多个容器。其类似于豌豆荚,容器则是里面的豆子。Pod 里的容器共享存储、网络等。我们可以把整个 pod 看作一台虚拟机,每个容器相当于运行在虚拟机的进程。Pod 是需要被调度到 k8s 集群的工作节点来运行的,具体调度到哪个节点,是根据 k8s scheduler 调度器实现的。

Pod 的网络

Pod 是有 IP 地址的,由网络插件(calico、flannel、weave)分配的 IP ,每个 Pod 都被分配唯一的 IP 地址。在 k8s 中,启动 Pod 时,会先启动⼀个 pause 的容器,然后将后续的所有容器都链接到这个 pause 的容器,以实现⽹络共享。

Pod 的存储

创建 Pod 的时候可以指定挂载的存储卷。 Pod 中的所有容器都可以访问共享卷,允许这些容器共享数据。 Pod 只要挂载持久化数据卷,Pod 重启之后这些数据还是会存在的。

Pod 多容器特性

  1. 所有容器共享一个 IP 地址和网络端口,意味着容器之间可以通过 localhost 高效访问,但容器之间不能有端口冲突
  2. 容器之间共享存储卷,可以通过文件系统交互信息。通常用来实现收集业务日志

Pod 创建方式

在 k8s 中,所有的资源都可以使用一个 yaml 文件来创建,创建 Pod 则可以使用 yaml 配置文件或者使用kubectl run在命令行创建 Pod(不常用且不推荐)。使用 yaml 文件创建 Pod 有两种方式:自主式创建 Pod (不推荐)和控制管理器创建 Pod (控制管理器例如 Replicaset、Deployment、Job、CronJob、Daemonset、Statefulset),下面是两者的对比:

  1. 创建 Pod 之前,使用 Dockerfile 文件创建用于测试的镜像文件和 nginx.conf文件,并编译镜像

    • 创建 dockerfile文件

      FROM alpine:latest
      
      RUN apk update && apk add nginx curl && mkdir "/usr/share/nginx/html"
      RUN echo "hello world" > "/usr/share/nginx/html/index.html"
      
      COPY nginx.conf /etc/nginx/nginx.conf
      
      EXPOSE 80
      
      CMD ["nginx", "-g", "daemon off;"]
      
    • 创建 nginx.conf文件

      worker_processes  1;
      
      events {
          worker_connections  1024;
      }
      
      http {
          include       /etc/nginx/mime.types;
          default_type  application/octet-stream;
      
          server {
              listen       80;
              server_name  localhost;
      
              location / {
                  root   /usr/share/nginx/html;
                  index  index.html index.htm;
              }
          }
      }
      
    • 编译镜像

      docker build -t curl-nginx:1.0 .
      
  2. 导出镜像,并导入 k8s 集群工作节点

    # 导出镜像
    docker save curl-nginx:1.0 -o curl-nginx.tar
    
    # 导入镜像
    ctr -n=k8s.io images import curl-nginx.tar
    
    # 查看镜像
    crictl images
    
  3. 自主式创建 Pod,curl-nginx-self.yaml文件如下:

    apiVersion: v1
    kind: Pod
    metadata:
      name: curl-nginx-test
      namespace: default
      labels:
        app:  nginx
    spec:
      containers:
      - name:  curl-nginx
        ports:
        - containerPort: 80
        image: curl-nginx:1.0
        imagePullPolicy: IfNotPresent
    
  4. 创建、查看并删除 Pod

    # 创建 Pod
    root@k8s-master1:~# kubectl apply -f curl-nginx-self.yaml 
    pod/curl-nginx-test created
    
    # 查看 Pod
    root@k8s-worker2:~# kubectl get pods -owide
    NAME              READY   STATUS    RESTARTS   AGE     IP              NODE          NOMINATED NODE   READINESS GATES
    curl-nginx-test   1/1     Running   0          7m35s   10.244.194.68   k8s-worker1   <none>           <none>
    
    # 进入 Pod 容器进行测试
    root@k8s-worker2:~# kubectl exec curl-nginx-test -- curl 10.244.194.68:80 
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100    12  100    12    0     0   6884      0 --:--:-- --:--:-- --:--:-- 12000
    hello world
    
    # 删除 Pod
    root@k8s-worker2:~# kubectl delete pod/curl-nginx-test
    pod "curl-nginx-test" deleted
    
  5. 控制管理器 Deployment 创建 Pod 的 yaml 文件如下:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-test
      labels:
        app: nginx-deploy
    spec:
      selector:
        matchLabels:
          app: nginx
      replicas: 2
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
            - name: curl-nginx
              image: curl-nginx:1.0
              imagePullPolicy: IfNotPresent
              ports:
                - containerPort: 80
    
  6. 创建、查看并删除 Pod

    root@k8s-master1:~# kubectl apply -f curl-nginx-deploy.yaml 
    deployment.apps/nginx-test created
    
    # 删除其中一个 Pod
    root@k8s-master1:~# kubectl get pods -l app=nginx -owide
    NAME                         READY   STATUS    RESTARTS   AGE     IP              NODE          NOMINATED NODE   READINESS GATES
    nginx-test-f8b6fbd9c-hc5vj   1/1     Running   0          3m34s   10.244.126.3    k8s-worker2   <none>           <none>
    nginx-test-f8b6fbd9c-xnf6p   1/1     Running   0          3m34s   10.244.194.69   k8s-worker1   <none>           <none>
    root@k8s-master1:~# kubectl delete pod/nginx-test-f8b6fbd9c-xnf6p
    pod "nginx-test-f8b6fbd9c-xnf6p" deleted
    
    # 自动恢复 Pod
    root@k8s-master1:~# kubectl get pods -l app=nginx -owide
    NAME                         READY   STATUS    RESTARTS   AGE     IP              NODE          NOMINATED NODE   READINESS GATES
    nginx-test-f8b6fbd9c-hc5vj   1/1     Running   0          4m22s   10.244.126.3    k8s-worker2   <none>           <none>
    nginx-test-f8b6fbd9c-stmnc   1/1     Running   0          4s      10.244.194.70   k8s-worker1   <none>           <none>
    
    # 删除所有 Pod
    root@k8s-master1:~# kubectl delete pods -l app=nginx
    pod "nginx-test-f8b6fbd9c-hc5vj" deleted
    pod "nginx-test-f8b6fbd9c-stmnc" deleted
    

自主式创建 Pod 缺陷

  1. Pod 被误删后不能自主恢复
  2. 不能弹性伸缩,进行均衡负载

Pod 创建流程

  1. 通过 kubectl 命令向 Apiserver 提交创建 Pod 的请求,Apiserver 接收到 Pod 创建请求后,会将 Pod 的属性信息 metadata 写入 etcd 数据库
  2. Apiserver 触发 watch 机制准备创建 Pod,信息转发给调度器 Scheduler,调度器使用调度算法选择工作节点,调度器将工作节点信息给 Apiserver ,Apiserver 将绑定的工作节点信息写入 etcd 数据库
  3. Apiserver 又通过 watch 机制,调用 kubelet,创建 Pod ,调用容器运行时 containerd 创建并启动 Pod 内的容器
  4. 容器创建完成之后反馈给 kubelet,kubelet 又将 Pod 的状态信息给 Apiserver,Apiserver 又将 Pod 的状态信息写入 etcd 数据库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值