k8s学习

k8s学习资料

k8s核心概念:

Deployment 与 ReplicaSet 和 pod的关系:

  • Deployment 是一种高级资源类型,用于声明式地管理应用程序的副本。它提供了一个声明式的方式来描述应用程序的期望状态,包括要运行的 Pod 的数量和模板。
  • Deployment 使用 ReplicaSet 来实现副本控制。当您创建一个 Deployment 时,Kubernetes 会自动创建关联的 ReplicaSet,它负责确保在集群中运行指定数量的 Pod 副本,并维护与 Deployment 的期望状态一致
  • ReplicaSet:是用于定义Pod副本数量的抽象层。它确保在集群中始终运行指定数量的Pod副本,以保证应用程序的高可用性和可伸缩性。当ReplicaSet的Pod数量与定义的副本数量不一致时,ReplicaSet会自动创建或删除Pod,使得Pod的数量与定义的副本数量保持一致。
  • Pod:Pod是Kubernetes中最基本的调度和部署单元。一个Pod是一个或多个容器的集合,它们共享相同的网络命名空间和存储卷。Pod是Kubernetes中最小的可部署对象。

简单来说 Deployment 用于声明部署策略和管理ReplicaSet副本集,ReplicaSet用于控制Pod副本数量,Pod是部署最小单元;

  • 以下一个简单的例子,创建Deployment:
apiVersion: apps/v1  #k8s api版本
kind: Deployment     #指定对象类型
metadata:            #元数据
  name: my-nginx     #定义Deployment的名称
spec:                #定于Deployment规格
  selector:          #定义如何选择pod
    matchLabels:     #标签选择器
      run: my-nginx  #选择run: my-nginx的pod
  replicas: 2        #副本数量
  template:          #定义创建pod的模版 
    metadata:        #定义pod的元数据
      labels:        #定义pod的标签
        run: my-nginx
    spec:            #定义pod规格
      containers:    #定义pod中要运行的容器
      - name: my-nginx  #容器名称
        image: nginx    #镜像名称
        ports:          #定义容器要监听的端口
        - containerPort: 80 #表示容器监听的端口是 80
  • service:创建完deployment后可以直接访问pod,但是pod都是临时的ip地址是会发生变化的,这时就需要创建service,它是将运行在一个或一组Pod上的网络应用程序公开为网络服务的方法。Service充当了Pod的稳定访问入口,可以将流量负载均衡到后端的Pod中,为应用程序提供了一种抽象的方式。
apiVersion: v1
kind: Service
metadata:           #定义元数据
  name: my-nginx    #定义service的名称
  labels:           #定义自身的标签
    run: my-nginx
spec:               #定义service的规格
  ports:            #定义service监听的端口
  - port: 80        #port: service的端口号
    targetPort: 80  #targetPort:后端pod的端口号
    protocol: TCP
  selector:         #标签选择器:定义选择那些pod作为关联
    run: my-nginx
  • EndpointSlice:创建service定义了selector会自动创建EndpointSlice,EndpointSlice定义了网络端点的列表,通常由 Service 引用,以定义可以将流量发送到哪些 Pod;
    EndpointSlice 都由某个 Service 所有, (因为)该端点切片正是为该服务跟踪记录其端点。

service,EndpointSlice, pod关联关系如何建立:

  • service与pod是通过service的selector进行关联;
  • EndpointSlice 与 Service 的关联是通过 Service 的 Selector 来实现的。当创建 Service 时, 在 Service 的规格(spec)中设置 Selector,定义哪些标签的 Pod 将与这个 Service 关联。
    EndpointSlice Controller 监视着 Service 和 Pod 的变化,一旦 Service 的 Selector 和 Pod 的标签匹配,
    EndpointSlice Controller 就会创建或更新相应的 EndpointSlice,将与 Service 关联的后端 Pod 的 IP 地址和端口信息添加到 EndpointSlice 中。

k8s内部Service之间访问

Kubernetes 支持两种查找服务的主要模式:环境变量和 DNS。前者开箱即用,而后者则需要 CoreDNS 集群插件。
在较新的 Kubernetes 版本中,CoreDNS 通常会作为集群的一部分自动部署; 在kube-system 命名空间中找到kube-dns

kube-dns应用会自动的给service分配dns名称,可以创建带有curl命令的pod进行测试:

kubectl run curl --image=radial/busyboxplus:curl -i --tty --rm

然后,按回车并执行命令 nslookup my-nginx:
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      my-nginx
Address 1: 10.103.194.41 my-nginx.default.svc.cluster.local

然后访问:curl http://my-nginx.default.svc.cluster.loca

会输出以下内容:

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

保护service(企业部署ssl证书不会与pod关联)

到现在为止,我们只在集群内部访问了 Nginx 服务器。在将 Service 暴露到因特网之前,我们希望确保通信信道是安全的。 为实现这一目的,需要:
* 用于 HTTPS 的自签名证书(除非已经有了一个身份证书)
* 使用证书配置的 Nginx 服务器
* 使 Pod 可以访问证书的 Secret

操作步骤可参考:https://kubernetes.io/zh-cn/docs/tutorials/services/connect-applications-service/

暴露service

给service设置完ssl证书后,可将service暴露外网ip进行访问;

Kubernetes ServiceTypes 允许指定你所需要的 Service 类型。

可用的 type 值及其行为有:

  • ClusterIP:
    通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。 这也是你没有为服务显式指定 type 时使用的默认值。 你可以使用 Ingress 或者 Gateway API 向公众暴露服务。
  • NodePort:
    通过每个节点上的 IP 和静态端口(NodePort)暴露服务。 为了让节点端口可用,Kubernetes 设置了集群 IP 地址,这等同于你请求 type: ClusterIP 的服务。
  • LoadBalancer:
    使用云提供商的负载均衡器向外部暴露服务。 Kubernetes 不直接提供负载均衡组件;它用于在云平台上创建一个外部负载均衡器,并将外部流量通过负载均衡器转发到后端 Pod;
  • ExternalName:
    将服务映射到 externalName 字段的内容(例如,映射到主机名 api.foo.bar.example)。 该映射将集群的 DNS 服务器配置为返回具有该外部主机名值的 CNAME 记录。 无需创建任何类型代理。
    服务 API 中的 type 字段被设计为层层递进的形式 - 每个级别都建立在前一个级别基础上。 并不是所有云提供商都如此严格要求的,但 Kubernetes 的 Service API 设计要求满足这一逻辑。
* 总结:service默认的type是ClusterIP可用于集群内部访问,可通过pod的ip加端口或者service的IP加端口访问;
* 类型是NodePord,可根据任意node的ip地址和service的NodePort端口号进行外网访问
* 类型为LoadBalancer 由云提供商(自建)决定如何进行负载平衡,应用场景比如mqtt,kafka,等消息中间件或者gateway服务;

使用ingress暴露service

Ingress 是对集群中服务的外部访问进行管理的 API 对象。
Ingress 是公开从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。
Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F1dzJiPQ-1690946689417)(img_1.png)]

  • 1.下载Ingress 控制器,常用的ingress-nginx控制器;
  • 2 创建IngressClass对象,它的作用是将 Ingress 对象与特定的 Ingress Controller 关联起来;
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: my-ingress-class
spec:
  controller: nginx #指定ingress-controller控制器
  
  • 3.创建Ingress资源
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  namespace: schedule-system  
spec:
  ingressClassName: nginx   #指定ingressClass的名称
  rules:
  - host: test.ddd
  - http:
      paths:
      - path: /test
        pathType: Prefix
        backend:
          service:
            name: my-nginx
            port:
              number: 80
  • 4 配置DNS域名解析(需要实际操作下)
  • 5.可根据test.ddd/testpath加上"ingress-nginx"控制器的service端口 访问test服务,常用的nacos可以通过Ingress来暴露服务;

无头服务(Headless Services)

在不需要k8s负载均衡的情况下,可以使用无头服务,可以通过显式指定 Cluster IP(spec.clusterIP)的值为 "None" 来创建 Headless Service

通常会与有状态的数据库集群联合使用,比如mongodb集群读写分离,可以通过无头服务来直接连接到数据库的各个节点,而不需要通过负载均衡,

容器中的文件在磁盘上是临时存放的,这给在容器中运行较重要的应用带来一些问题。
当容器崩溃或停止时会出现一个问题。此时容器状态未保存, 因此在容器生命周期内创建或修改的所有文件都将丢失。
在崩溃期间,kubelet 会以干净的状态重新启动容器。 当多个容器在一个 Pod 中运行并且需要共享文件时,会出现另一个问题。 跨所有容器设置和访问共享文件系统具有一定的挑战性。

使用卷的好处在于:

  • 使数据持久化,即使容器重启或迁移,数据也不会丢失。
  • 支持容器之间共享数据,方便数据处理和共享状态。
  • 解耦数据和容器,使得容器更加易于管理和迁移
  • 使用卷时, 在 .spec.volumes 字段中设置为 Pod 提供的卷,并在 .spec.containers[*].volumeMounts 字段中声明卷在容器中的挂载位置。

卷类型

  • 卷分配临时卷,持久卷
    ###临时卷:
    • emptyDir:当 Pod 分派到某个节点上时,emptyDir 卷会被创建,并且在 Pod 在该节点上运行期间,卷一直存在。 就像其名称表示的那样,卷最初是空的。
      Pod中的所有容器可以共享emptyDir卷存储;
    • emptyDir作用:一些不想要持久化的文件可以用emptyDir卷,比如不重要的日志文件xxx-job生成的日志;
    • emptyDir卷的生命周期与Pod的生命周期相同,卷的- mountPath: /cache 实际存储位置是Pod所在的Node节点上;

#StatefulSet
StatefulSet 是用来管理有状态应用的工作负载 API 对象。

StatefulSet 用来管理某 Pod 集合的部署和扩缩, 并为这些 Pod 提供持久存储和持久标识符。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值