• k8s基础 随笔


      写个笔记,后面再完善

    部署第一个应用

    为什么先实战水平扩缩?因为这个最简单,首先来部署一个喜闻乐见的nginx

    kubectl create deployment web --image=nginx:1.14 --dry-run -o yaml > web.yaml
    • --dry-run表示试运行,试一下看行不行,但是不运行
    • -o yaml表示以yaml格式输出
    • > web.yaml表示将输出的内容重定向到web.yaml文件中

    这句话可以放心执行了,执行之后看看web.yaml文件里面有些啥

    1. apiVersion: apps/v1 # 表示资源版本号为apps/v1
    2. kind: Deployment # 表示这是一个Deployment
    3. metadata: # 一些元数据信息
    4. creationTimestamp: null
    5. labels: # 标签,可以随便定义
    6. app: web
    7. name: web # 这个资源的名字
    8. spec: # 资源的描述或者规格
    9. replicas: 1 # 副本数量
    10. selector: # 选择器
    11. matchLabels: # 需要匹配的标签
    12. app: web # 标签的具体键值对
    13. strategy: {}
    14. template: # 模板。表示Pod的生成规则
    15. metadata:
    16. creationTimestamp: null
    17. labels:
    18. app: web
    19. spec:
    20. containers:
    21. - image: nginx:1.14 #指定镜像文件
    22. name: nginx
    23. resources: {}
    24. status: {}

    用下面的命令应用web.yaml,web.yaml声明了一个Deployment和一个Pod

    kubectl apply -f web.yaml

    执行完后以后可以通过以下命令查看Deployment和Pod

    kubectl get deploy,po -o wide

    结果如下

    1. NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
    2. deployment.apps/web 1/1 1 1 2m40s nginx nginx:1.14 app=web
    3. NAME READY STATUS RESTARTS AGE IP NODE ...
    4. pod/web-5bb6fd4c98-lg555 1/1 Running 0 2m40s 10.100.255.120 my-node ...

    可以看到资源已经建立起来了,运行在Worker节点中,尝试访问一下Pod的IP

    curl 10.100.255.120

    有如下nginx的标准返回说明应用已经部署完毕

    1. html>
    2. <html>
    3. <head>
    4. <title>Welcome to nginx!title>
    5. ...
    6. html>

    有没有感觉这一路下来挺麻烦的,yaml文件还那么长,还不如无脑docker run呢,别急,在后面扩缩容的时候就可以看到它的威力了,当然也可以用最开始的命令来执行kubectl create deployment web --image=nginx:1.14,测试可以,在生产环境中强烈不建议这么做。

    但是现在还不能在外面访问

    先要创建一个Service

    要访问部署在 Kubernetes 中的应用程序,你通常需要使用 Service 对象来公开应用程序,以便从外部网络访问。以下是创建一个 Service 来访问你的 web deployment 的一般步骤:

    1. 创建一个 Service 对象:
    kubectl create service nodeport web --tcp=80:80
    

    这将创建一个 NodePort 类型的 Service,它将监听节点上的某个端口(通常在30000-32767之间),并将流量转发到你的 web deployment 的端口80。

    1. 获取 Service 的访问端口:
    kubectl get service web
    

    查找 "PORT(S)" 部分,你会看到 Service 的访问端口,其中 NodePort 是你可以使用的外部端口。

    1. 访问应用程序:

    现在,你可以使用集群的任何节点的 IP 地址和上面步骤中找到的 NodePort 访问你的应用程序。例如,如果你的集群节点的 IP 地址是 192.168.1.100,NodePort 是 31000,你可以在浏览器中输入 http://192.168.1.100:31000 来访问应用程序。

    请注意,NodePort Service 在生产环境中可能不是最佳选择,通常会使用 Ingress 控制器来管理外部访问。但对于测试和学习的目的,NodePort 可以用作一种简单的方法来访问应用程序

    节点污点

    Taint 污点:节点不做普通分配调度,是节点属性,属性值有三个

    • NoSchedule:一定不被调度
    • PreferNoSchedule:尽量不被调度(也有被调度的几率)
    • NoExecute:不会调度,并且还会驱逐Node已有Pod

    也就是说,给节点打上污点,那么调度的时候就会根据上面的属性来进行调度,一般来说Master节点的污点值是NoSchedule,查看Master污点值

    kubectl describe node my-master | grep Taints

    可以看到如下输出

    Taints:             node-role.kubernetes.io/master:NoSchedule

    这表明无论如何,Pod都不会被调度到Master节点上,也可以用上面弹性伸缩的列子来证明,无论副本多少个,都是在Worker节点上,现在将Master节点上的污点给去掉,用下面的命令

    kubectl taint node my-master node-role.kubernetes.io/master:NoSchedule-

    回显如下,说明污点已经去掉

    node/my-master untainted

    再来扩容一下,为了大概率调度到Master节点上,可以将副本设置多一点

    kubectl scale deploy web --replicas=20

    在查看Pod:kubectl get po -o wide

    1. web-5bb6fd4c98-9rrp2 1/1 Running 0 5m19s 10.100.255.108 my-node <none> ...
    2. web-5bb6fd4c98-fgsfn 1/1 Running 0 5m19s 10.100.0.200 my-master <none> ...
    3. web-5bb6fd4c98-g7p4w 1/1 Running 0 5m19s 10.100.255.112 my-node <none> ...

    可以看到,一部分节点调度到Master上面去了

    先缩容,将污点加回去(用下面的命令)再扩容试试看,可以发现新增加的节点都在Worker节点上了

    kubectl taint node my-master node-role.kubernetes.io/master:NoSchedule

    节点标签选择器

    首先删除deploy:kubectl delete deploy web

    给master节点打上标签test123_env=prod,标签就是键值对,随便起名儿

    kubectl label node my-master test123_env=prod

    然后在web.yaml中新增nodeSelector声明

    1. apiVersion: apps/v1
    2. kind: Deployment
    3. metadata:
    4. labels:
    5. app: web
    6. name: web
    7. spec:
    8. replicas: 10 # 副本改多一点
    9. selector:
    10. matchLabels:
    11. app: web
    12. strategy: {}
    13. template:
    14. metadata:
    15. labels:
    16. app: web
    17. spec:
    18. containers:
    19. - image: nginx:1.14
    20. name: nginx
    21. # 新增的内容
    22. nodeSelector:
    23. test123_env: prod
    24. status: {}

    最后执行,理论上所有Pod都应该被调度到Master节点上,但是发现所有的Pod都被挂起了,没有被调度

    1. web-6897865b86-sp6fh 0/1 Pending 0 30s <none> <none> <none> <none>
    2. web-6897865b86-vkcx2 0/1 Pending 0 30s <none> <none> <none> <none>
    3. web-6897865b86-wvdk6 0/1 Pending 0 30s <none> <none> <none> <none>

    这是什么原因呢?这是污点在作祟,别忘记了,Master节点的污点值默认是NoSchedule,不允许被调度的,查看一下Master节点的污点值

    1. [root@my-master ~]# kubectl describe node my-master | grep Taints
    2. Taints: node-role.kubernetes.io/master:NoSchedule

    果然是NoSchedule,先去掉污点值

    kubectl taint node my-master node-role.kubernetes.io/master:NoSchedule-

    机器突然有点卡,这应该是在调度Pod了,查看一下果不其然,节点都被调度到了Master上

    1. web-6897865b86-sp6fh 1/1 Running 0 4m2s 10.100.0.208 my-master <none> ...
    2. web-6897865b86-vkcx2 1/1 Running 0 4m2s 10.100.0.209 my-master <none> ...
    3. web-6897865b86-wvdk6 1/1 Running 0 4m2s 10.100.0.213 my-master <none> ...

    这里还可以得出一个结论,在Pod被调度的时候,节点污点值的优先级是高于节点标签的

    最后还原现场

    1. # 删除deploy
    2. kubectl delete deploy web
    3. # 删掉标签
    4. kubectl label node my-master test123_env-
    5. # 恢复污点
    6. kubectl taint node my-master node-role.kubernetes.io/master:NoSchedule

    节点亲和性

    亲和性和节点选择器类似,多了操作符表达式:In、NotIn、Exists、Gt、Lt、DoesNotExists,此处就不再演示了,感兴趣的同学自行尝试一下

    1. apiVersion: apps/v1
    2. kind: Deployment
    3. metadata:
    4. labels:
    5. app: web
    6. name: web
    7. spec:
    8. replicas: 10 # 副本改多一点
    9. selector:
    10. matchLabels:
    11. app: web
    12. strategy: {}
    13. template:
    14. metadata:
    15. labels:
    16. app: web
    17. spec:
    18. containers:
    19. - image: nginx:1.14
    20. name: nginx
    21. # 新增的内容
    22. affinity:
    23. nodeAffinity:
    24. requiredDuringSchedulingIgnoredDuringExecution:
    25. nodeSelectorTerms:
    26. - matchExpressions:
    27. - key: test123_env
    28. operator: In
    29. values:
    30. - dev
    31. - test
    32. preferreDuringSchedulingIgnoredDuringExecution:
    33. - weight: 1
    34. preference:
    35. - matchExpressions:
    36. - key: group
    37. operator: In
    38. values:
    39. - ttttest
    40. status: {}

    上面的亲和性表示如下含义

    • requiredDuringSchedulingIgnoredDuringExecution:硬亲和,test123_env等于dev或者test,必须满足
    • preferreDuringSchedulingIgnoredDuringExecution:软亲和,group等于ttttest,非必须满足

    K8S搞这么多策略有啥用呢?又是节点污点、节点标签、Pod调度策略之类的,目的当然是提供最大的灵活性,最终提高整体资源利用率,这就是自动装箱

    这里的 affinity 部分用于定义容器在调度到节点时的偏好设置。具体来说,这个配置包括两部分:

    1. requiredDuringSchedulingIgnoredDuringExecution:这是一个必需的亲和性规则,它要求容器只能被调度到满足指定条件的节点上。在这个示例中,它要求节点的 test123_env 标签的值必须是 "dev" 或 "test",否则容器将不会被调度到这些节点。

    2. preferreDuringSchedulingIgnoredDuringExecution:这是一个偏好的亲和性规则,它定义了容器倾向于被调度到满足指定条件的节点上。在这个示例中,它定义了一个权重为1的偏好规则,要求节点的 group 标签的值应为 "ttttest",以增加容器被调度到这些节点的可能性。这并不是一个硬性要求,只是一个偏好设置。

    总之,这些亲和性设置帮助 Kubernetes 调度器在将 Pod 调度到节点时考虑节点的标签和属性,以满足或偏好某些条件。这有助于优化应用程序的性能和资源利用。😺

  • 相关阅读:
    【第20例】华为 IPD 体系 | IPD 的底层思考逻辑(限制版)
    小程序中实现获取全部数据
    融合Sin混沌和分段权值的阿基米德优化算法-附代码
    二叉树—相关计算题
    图形像素的逻辑操作&通道分离与合并&图像色彩空间转换
    笔试面试相关记录(13)
    ElasticJob+Spring Boot简单使用
    MQ - 39 Serverless : 基于MQ和Serverless设计事件驱动架构
    Redis (二)
    ElasticSearch集群搭建
  • 原文地址:https://blog.csdn.net/cjj2006/article/details/133882778