API资源对象Deployment;API资源对象Service;API资源对象DaemonSet;API资源对象StatefulSet

API资源对象Deployment;API资源对象Service;API资源对象DaemonSet;API资源对象StatefulSet

API资源对象Deployment

Deployment YAML示例:

vi ng-deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: myng
  name: ng-deploy
spec:
  replicas: 2 ##副本数
  selector:
    matchLabels:
      app: myng
  template:
    metadata:
      labels:
        app: myng
    spec:
      containers:
        - name: myng
          image: nginx:1.23.2
          ports:
          - name: myng-port
            containerPort: 80

使用YAML创建deploy:

kubectl apply -f ng-deploy.yaml

查看:

kubectl get deploy 
kubectl get po

查看pod分配到哪个节点上

kubectl get po -o wide

API资源对象Service

Service简称(svc) YAML示例:

vi ng-svc.yaml

apiVersion: v1
kind: Service
metadata:
  name: ngx-svc
spec:
  selector:
    app: myng
  ports:
  - protocol: TCP
    port: 8080  ##service的port
    targetPort: 80  ##pod的port

使用YAML创建service:

kubectl apply -f ng-svc.yaml

查看:

kubectl get svc

三种Service 类型:

1)ClusterIP

该方式为默认类型,即,不定义type字段时(如上面service的示例),就是该类型。

spec:
  selector:
    app: myng
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 8080  ##service的port
    targetPort: 80  ##pod的port

2)NodePort

如果想直接通过k8s节点的IP直接访问到service对应的资源,可以使用NodePort,Nodeport对应的端口范围:30000-32767

spec:
  selector:
    app: myng
  type: NodePort
  ports:
  - protocol: TCP
    port: 8080  ##service的port
    targetPort: 80  ##pod的port
    nodePort: 30009  ##可以自定义,也可以不定义,它会自动获取一个端口

3)LoadBlancer

这种方式,需要配合公有云资源比如阿里云、亚马逊云来实现,这里需要一个公网IP作为入口,然后来负载均衡所有的Pod。

spec:
  selector:
    app: myng
  type: LoadBlancer
  ports:
  - protocol: TCP
    port: 8080  ##service的port
    targetPort: 80  ##pod的port

API资源对象DaemonSet

有些场景需要在每一个node上运行Pod(比如,网络插件calico、监控、日志收集),Deployment无法做到,而Daemonset(简称ds)可以。Deamonset的目标是,在集群的每一个节点上运行且只运行一个Pod。

Daemonset不支持使用kubectl create获取YAML模板,所以只能照葫芦画瓢了,参考Deployment的YAML编写,其实Daemonset和Deployment的差异很小,除了Kind不一样,还需要去掉replica配置。

vi ds-demo.yaml

apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app: ds-demo
  name: ds-demo
spec:
  selector:
    matchLabels:
      app: ds-demo
  template:
    metadata:
      labels:
        app: ds-demo
    spec:
      containers:
        - name: ds-demo
          image: nginx:1.23.2
          ports:
          - name: mysql-port
            containerPort: 80

使用YAML创建ds

kubectl apply -f ds-demo.yaml

查看:

kubectl get ds
kubectl get po

但只在两个node节点上启动了pod,没有在master上启动,这是因为默认master有限制。

kubectl describe node k8s01 |grep -i 'taint'
Taints:             node-role.kubernetes.io/control-plane:NoSchedule

说明:Taint叫做污点,如果某一个节点上有污点,则不会被调度运行pod。

但是这个还得取决于Pod自己的一个属性:toleration(容忍),即这个Pod是否能够容忍目标节点是否有污点。

为了解决此问题,我们可以在Pod上增加toleration属性。下面改一下YAML配置:

vi ds-demo.yaml

apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app: ds-demo
  name: ds-demo
spec:
  selector:
    matchLabels:
      app: ds-demo
  template:
    metadata:
      labels:
        app: ds-demo
    spec:
      tolerations:
        - key: node-role.kubernetes.io/control-plane
          effect: NoSchedule
      containers:
        - name: ds-demo
          image: nginx:1.23.2
          ports:
          - name: mysql-port
            containerPort: 80

再次应用此YAML

kubectl apply -f ds-demo.yaml

API资源对象StatefulSet

Pod根据是否有数据存储分为有状态和无状态:

  • 无状态:指的Pod运行期间不会产生重要数据,即使有数据产生,这些数据丢失了也不影响整个应用。比如Nginx、Tomcat等应用适合无状态。
  • 有状态:指的是Pod运行期间会产生重要的数据,这些数据必须要做持久化,比如MySQL、Redis、RabbitMQ等。

Deployment和Daemonset适合做无状态,而有状态也有一个对应的资源,那就是Statefulset(简称sts)。

说明:由于StatefulSet涉及到了数据持久化,用到了StorageClass,需要先创建一个基于NFS的StorageClass

额外开一台虚拟机,搭建NFS服务(具体步骤略)

假设NFS服务器IP地址为192.168.222.128,共享目录为/data/nfs

另外,要想使用NFS的sc,还需要安装一个NFS provisioner,它的作用是自动创建NFS的pv

github地址: https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner

将源码下载下来:

git clone https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
cd nfs-subdir-external-provisioner/deploy
sed -i 's/namespace: default/namespace: kube-system/' rbac.yaml  ##修改命名空间为kube-system
kubectl apply -f rbac.yaml  ##创建rbac授权

修改deployment.yaml

sed -i 's/namespace: default/namespace: kube-system/' deployment.yaml ##修改命名空间为kube-system

  ##你需要修改标红的部分 
   spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: chronolaw/nfs-subdir-external-provisioner:v4.0.2  ##改为dockerhub地址
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              value: 192.168.222.128  ##nfs服务器地址
            - name: NFS_PATH
              value: /data/nfs  ##nfs共享目录
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.222.128  ##nfs服务器地址
            path: /data/nfs  ##nfs共享目录

应用yaml

kubectl apply -f deployment.yaml 
kubectl apply -f class.yaml ##创建storageclass

SC YAML示例

cat class.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:
  archiveOnDelete: "false"  ##自动回收存储空间

Sts示例:

vi redis-sts.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis-sts

spec:
  serviceName: redis-svc ##这里要有一个serviceName,Sts必须和service关联

  volumeClaimTemplates:
  - metadata:
      name: redis-pvc
    spec:
      storageClassName: nfs-client
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 500Mi

  replicas: 2
  selector:
    matchLabels:
      app: redis-sts

  template:
    metadata:
      labels:
        app: redis-sts
    spec:
      containers:
      - image: redis:6.2
        name: redis
        ports:
        - containerPort: 6379

        volumeMounts:
        - name: redis-pvc
          mountPath: /data

vi redis-svc.yaml

apiVersion: v1
kind: Service
metadata:
  name: redis-svc

spec:
  selector:
    app: redis-sts

  ports:
  - port: 6379
    protocol: TCP
    targetPort: 6379

应用两个YAML文件

kubectl apply -f redis-sts.yaml -f redis-svc.yaml

对于Sts的Pod,有如下特点:

① Pod名固定有序,后缀从0开始;

② “域名”固定,这个“域名”组成: Pod名.Svc名,例如 redis-sts-0.redis-svc;

③ 每个Pod对应的PVC也是固定的;

实验:

ping 域名

kubectl exec -it redis-sts-0 -- bash   ##进去可以ping redis-sts-0.redis-svc 和  redis-sts-1.redis-svc

创建key

kubectl exec -it redis-sts-0 -- redis-cli
127.0.0.1:6379> set k1 'abc'
OK
127.0.0.1:6379> set k2 'bcd'
OK

模拟故障

kubectl delete pod redis-sts-0

删除后,它会自动重新创建同名Pod,再次进入查看redis key

kubectl exec -it redis-sts-0 -- redis-cli
127.0.0.1:6379> get k1
"abc"
127.0.0.1:6379> get k2
"bcd"

数据依然存在。

关于Sts里的多个Pod之间的数据同步

K8s并不负责Sts里的Pod间数据同步, 具体的数据同步和一致性策略取决于我们部署的有状态应用程序。不同的应用程序可能使用不同的数据同步和一致性策略。例如,关系型数据库(如 MySQL)可能使用主-从复制,而分布式数据库(如 MongoDB)可能使用一种基于分区和副本的数据同步机制。

相关推荐

  1. k8s的API资源对象CustomResourceDefinition(CRD)

    2023-12-08 11:10:02       73 阅读
  2. Spring原理分析--获取Environment资源对象

    2023-12-08 11:10:02       28 阅读
  3. 条款13:用对象管理资源(智能指针)

    2023-12-08 11:10:02       40 阅读
  4. k8s的资源对象Deployment该如何使用?

    2023-12-08 11:10:02       35 阅读
  5. 飞天使-k8s知识点8-kubernetes资源对象-编写中

    2023-12-08 11:10:02       56 阅读
  6. 飞天使-k8s知识点10-kubernetes资源对象3-controller

    2023-12-08 11:10:02       58 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-08 11:10:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-08 11:10:02       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-08 11:10:02       82 阅读
  4. Python语言-面向对象

    2023-12-08 11:10:02       91 阅读

热门阅读

  1. webpack打包体积优化,减少白屏时间

    2023-12-08 11:10:02       52 阅读
  2. 网络通信之网卡配置ip

    2023-12-08 11:10:02       49 阅读
  3. 软件测试——单元测试

    2023-12-08 11:10:02       57 阅读
  4. 算法___

    算法___

    2023-12-08 11:10:02      50 阅读