K8s创建pod 实例


K8s创建Pod 实例

在 Kubernetes 中,创建 Deployment 和创建 Pod 主要有以下区别:

目的

  • Pod:是 Kubernetes 中最小的可部署和可管理的计算单元,一个 Pod 可以包含一个或多个紧密相关的容器,这些容器共享存储、网络等资源,它主要用于运行容器化应用程序。例如,运行一个简单的 Nginx 服务器容器就可以用一个 Pod。
  • Deployment:是一种更高级的抽象,用于管理 Pod 的部署、升级和回滚等操作。它的目的是确保指定数量的 Pod 副本按照期望的状态运行,提供了一种声明式的方式来更新应用程序,比如实现滚动更新以减少应用更新过程中的服务中断。

功能特性

  • Pod:

    • 生命周期相对简单,它被创建后就开始运行其中的容器,一旦容器退出或者 Pod 被删除,生命周期就结束。
    • 缺乏自动扩缩容、自动恢复等功能。例如,如果一个 Pod 因为节点故障而消失,不会自动重新创建(除非被更高层的资源管理,如 Deployment 管理)。
  • Deployment:

    • 可以定义 Pod 的副本数量,确保有指定数量的 Pod 副本在运行。比如,设置副本数为 3,Kubernetes 就会始终尝试保持 3 个 Pod 在运行状态。
    • 支持自动扩容和缩容,根据负载情况动态地调整 Pod 的数量。
    • 方便应用的版本更新。在更新应用时,Deployment 可以通过滚动更新的方式,逐步替换旧版本的 Pod 为新版本,同时还能监控更新过程,在出现问题时进行回滚操作。

适用场景

  • Pod:适合简单的、一次性的容器运行场景,或者用于测试一些容器组合的运行情况。
  • Deployment:用于长期运行的、需要保证高可用性、能够自动更新和恢复的生产环境应用

使用deployment创建MySQL,并将3306对外映射端口

mysql-deployment.yaml 文件内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql  
        #镜像文件地址,这里使用的是阿里云公共镜像里的
          image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/mysql:8.0.30-8.6
          ports:
            - containerPort: 3306  #容器端口
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: "123456"   #设置root密码
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
spec:
  type: NodePort
  selector:
    app: mysql
  ports:
    - protocol: TCP
      port: 3306   #service端口
      targetPort: 3306  #内部访问端口
      nodePort: 30006   #映射node节点外部访问端口,端口范围30000~32767

kubectl apply -f mysql-deployment.yaml
#查询是否创建成功
kubectl get pod -o wide

root@ubuntu22-01:~# kubectl get pod -o wide
NAME                         READY   STATUS    RESTARTS   AGE   IP            NODE          NOMINATED NODE   READINESS GATES
mysql-dep-59c7bbf564-hq5fd   1/1     Running   0          31m   10.244.1.27   ubuntu22-02   <none>           <none>

#查询创建的service列表
kubectl get services

root@ubuntu22-01:~# kubectl get services
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP          6d
mysql-service   NodePort    10.109.70.246   <none>        3306:30006/TCP   28m


#查询显示更多信息
kubectl get pods -o wide --show-labels

root@ubuntu22-01:~# kubectl get pods -o wide --show-labels
NAME                         READY   STATUS    RESTARTS   AGE   IP            NODE          NOMINATED NODE   READINESS GATES   LABELS
mysql-dep-59c7bbf564-hq5fd   1/1     Running   0          27m   10.244.1.27   ubuntu22-02   <none>           <none>            app=mysql,pod-template-hash=59c7bbf564

#查看明细信息及事件
kubectl describe pod mysql-dep-59c7bbf564-hq5fd 
#查看详细信息yaml格式
kubectl get pod mysql-dep-59c7bbf564-hq5fd -o yaml

以上mysql-pod已经创建成功,此时集群内部间可使用10.244.1.27:3306进行访问,外部使用该节点服务器IP,192.168.2.102:30006端口访问

  1. 进入容器中

    kubectl exec -it mysql-pod -- /bin/bash
    

使用Pod的yaml创建Nginx

  1. 创建资源清单nginx-pod.yaml文件

    vim nginx-pod.yaml
    

    内容如下:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-pod
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80
    
  2. 创建nginx-pod

    kubectl apply -f nginx-pod.yaml
    
    #查看是否成功
    kubectl get pods 
    
  3. 将nginx-pod的80端口暴露

    #创建一个nginx-service.yaml
    vim nginx-service.yaml
    

    内容如下:

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-service
    spec:
      type: NodePort
      selector:
        app: nginx
      ports:
        - protocol: TCP
          port: 80
          targetPort: 80
          nodePort: 30080
    
    #创建nginx-service
    kubectl apply -f nginx-service.yaml
    
    #查询是否成功
    kubectl get services
    
    

    此时,用节点服务器IP:30080即可访问nginx页面

使用deployment创建nginx(本地镜像)

1.下载nginx镜像文件

docker pull nginx

root@ubuntu22-01:~# docker images
REPOSITORY     TAG      IMAGE ID       CREATED         SIZE                
nginx          latest  66f8bdd3810c   12 days ago     192MB

2.将nginx镜像导入到containerd的k8s.io命名空间中(使用本地镜像时)

 #打包镜像
 docker save -o nginx.tar nginx:latest
 
 #将tar镜像压缩包导入
 sudo ctr -n k8s.io images import nginx.tar
 
 #验证是否成功,并记下路径,deployment的yaml文件中使用
 sudo ctr -n k8s.io i check | grep nginx
 
root@ubuntu22-01:~#  sudo ctr -n k8s.io i check | grep nginx
docker.io/library/nginx:latest              application/vnd.docker.distribution.manifest.v2+json sha256:926284c3d4dea022ccf85d86a14f8b5ce703ef8282d6de10299cd60135dd9ed2 complete (8/8) 186.8 MiB/186.8 MiB true

以上docker.io/library/nginx:latest就是本地nginx镜像文件地址

#将打包好的镜像文件tar拷贝到其它节点上,进行加载镜像,和导入
scp nginx.tar root@192.168.2.102:/

#加载镜像
docker load -i nginx.tar
#导入到k8s命名空间中
sudo ctr -n k8s.io images import nginx.tar

在 Kubernetes(k8s)中使用 Deployment 创建一个运行 Nginx 的 Pod 时,并不是所有节点都一定会拉取 Nginx 镜像。

Kubernetes 的容器运行时(如 Docker)会根据调度情况来决定在哪个节点上运行 Pod。当一个节点被调度用来运行包含 Nginx 容器的 Pod 时,这个节点上的容器运行时才会去拉取 Nginx 镜像。如果没有 Pod 被调度到某个节点上运行 Nginx,那这个节点就不需要拉取该镜像。

例如,假设有 3 个节点(Node1、Node2、Node3),而 Deployment 创建的 Nginx Pod 通过调度只运行在 Node1 和 Node2 上,那么只有 Node1 和 Node2 会拉取 Nginx 镜像,Node3 不会拉取。

3.创建nginx-deployment.yaml

内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-dep
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      imagePullSecrets:
      - name: nginx
      containers:
      - name: nginx  #pod容器名称
        image: docker.io/library/nginx:latest  #镜像文件地址
        imagePullPolicy: IfNotPresent #镜像拉取策略
        ports:
        - containerPort: 80 #容器暴露端口号

以上内容中,镜像拉取策略字段imagePullPolicy有三个取值:

  • Always 每次都下载最新镜像
  • Never 不会尝试获取镜像,如果镜像已经以某种方式存在本地,kubelet 会尝试启动容器;否则,会启动失败
  • IfNotPresent 只有当镜像在本地不存在时才会拉取

4.创建nginx Pod

kubectl apply -f nginx-deployment.yaml

#查看deployment创建结果
root@ubuntu22-01:~# kubectl get deployment
NAME        READY   UP-TO-DATE   AVAILABLE   AGE
blog-dep    1/1     1            1           2d23h
nginx-dep   1/1     1            1           117m
#查看pod创建结果
root@ubuntu22-01:~# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
blog-dep-d74f8b76-hdqqm      1/1     Running   2          2d23h
nginx-dep-864fb4b987-tpcsq   1/1     Running   0          118m

#如果创建不成功,查看详细信息,排查问题
kubectl describe pod nginx-dep-864fb4b987-tpcsq
  1. 部署网页

    将网页文件复制到创建的 Pod 中。您可以使用 kubectl cp 命令将静态网页文件复制到 Pod 的容器中(namespace为默认default可省略,否则添加 -n ):

    #把名为 index.html 的网页文件复制到 nginx-pod Pod 的 /usr/share/nginx/html/ 路径下
    kubectl cp /var/www/index.html nginx-pod:/usr/share/nginx/html/
    

    如果网页文件涉及多个文件,可以打包复制到容器中,然后进入容器中解压

    将本地的网页文件全部复制到 Nginx Pod 目录下,您可以使用以下方法:

    1. 首先,将网页文件打包成一个压缩文件(例如 tar 或 zip)。

      #执行以下命令将网页文件打包成一个 tar 压缩文件:
      tar -cvf website.tar /path/to/website
      

      其中 /path/to/website 是网页文件的路径。上述命令将创建一个名为 website.tar 的 tar 压缩文件,其中包含指定路径下的所有文件。

    2. 执行以下命令将压缩文件从本地复制到 Nginx Pod 中:

      kubectl cp path/to/website.tar nginx-pod:/usr/share/nginx/html/
      

      其中 path/to/website.tar 是网页文件的本地路径,nginx-pod 是您的 Nginx Pod 的名称。

      这将把压缩文件复制到 Nginx Pod 的 /usr/share/nginx/html/ 目录下。

    3. 在 Nginx Pod 中解压缩网页文件。您需要通过 Shell 登录到 Nginx Pod 中执行以下命令:

      kubectl exec -it nginx-pod -- /bin/bash
      

      在 Pod 中运行上述命令后,您会进入 Pod 的 Shell 环境。

    4. 在 Pod 的 Shell 中,解压缩网页文件:

      tar -xvf /usr/share/nginx/html/website.tar -C /usr/share/nginx/html/
      

      这将解压缩位于 /usr/share/nginx/html/ 目录下的网页文件。

    5. 退出 Pod 的 Shell:

      exit
      

    通过上述步骤,您可以将本地的网页文件全部复制到 Nginx Pod 的指定目录下。

教程