【云原生】Kubernetes核心技术(上)

 部署 Pod,Deployment 与 Service

博主昵称:跳楼梯企鹅
博主主页面链接:博主主页传送门

博主专栏页面连接:专栏传送门--网路安全技术
创作初心:本博客的初心为与技术朋友们相互交流,每个人的技术都存在短板,博主也是一样,虚心求教,希望各位技术友给予指导。
博主座右铭:发现光,追随光,成为光,散发光;
博主研究方向:渗透测试、机器学习 ;
博主寄语:感谢各位技术友的支持,您的支持就是我前进的动力 ;

本篇文章分为3次分享完

一、Pod

1.概述

Pod 是 K8S 系统中可以创建和管理的最小单元,是资源对象模型中由用户创建或部署的最小资源对象模型,也是在 K8S 上运行容器化应用的资源对象,其它的资源对象都是用来支撑或者扩展 Pod 对象功能的,比如控制器对象是用来管控 Pod 对象的,Service 或者 Ingress 资源对象是用来暴露 Pod 引用对象的,PersistentVolume 资源对象是用来为 Pod 提供存储等等,K8S 不会直接处理容器,而是 Pod,Pod 是由一个或多个 container 组成

Pod 是 Kubernetes 的最重要概念,每一个 Pod 都有一个特殊的被称为 “根容器”的 Pause 容器Pause 容器对应的镜像属于 Kubernetes 平台的一部分,除了 Pause 容器,每个 Pod 还包含一个或多个紧密相关的用户业务容器

 2.概念以及意义

  • 最小部署的单元
  • Pod 里面是由一个或多个容器组成【一组容器的集合】
  • 一个 pod 中的容器是共享网络命名空间
  • Pod 生命周期是短暂的
  • 每个 Pod 包含一个或多个紧密相关的用户业务容器

意义:Pod 是在 K8S 集群中运行部署应用或服务的最小单元,它是可以支持多容器的。Pod 的设计理念是支持多个容器在一个 Pod 中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。同时 Pod 对多容器的支持是 K8S 中最基础的设计理念。在生产环境中,通常是由不同的团队各自开发构建自己的容器镜像,在部署的时候组合成一个微服务对外提供服务。

3.分类

  • 长期伺服型:long-running
  • 批处理型:batch
  • 节点后台支撑型:node-daemon
  • 有状态应用型:stateful application

4.Pod机制

主要有以下两大机制

  • 共享网络
  • 共享存储

(1)共享网络:

容器本身之间相互隔离的,一般是通过 namespace 和 group 进行隔离,那么Pod里面的容器如何实现通信?

 首先需要满足前提条件,也就是容器都在同一个namespace之间关于Pod实现原理,首先会在Pod会创建一个根容器: pause容器然后我们在创建业务容器 【nginx,redis 等】,在我们创建业务容器的时候,会把它添加到 info容器 中

而在 info容器 中会独立出 ip地址,mac地址,port 等信息,然后实现网络的共享

(2)共享存储:

5.常用命令

# 查看所有的 pod 列表,-n 后面跟 namespace,查看指定的命名空间,-o wide 查看详细信息
kubectl get pod
kubectl get pod -n kube-system  # 查看 kube-system 命名空间下的 pod
kubectl get pod -o wide # 查看 pod 的详细信息,有 ip、node 节点等信息

# 显示 Node 的详细信息
kubectl describe node dce-10-6-215-190 # node 后面的是 node名称
# 显示 Pod 的详细信息, 特别是查看 pod 无法创建的时候的日志
kubectl describe pod web # web 是你创建 pod 时起的名称

# 根据 yaml 创建资源, apply 可以重复执行,create 不行
kubectl create -f pod.yaml
kubectl apply -f pod.yaml

# 删除所有 Pod
kubectl delete pod --all

# 强制删除某个文件名命名节点 ,基于 pod.yaml 定义的名称删除 pod 
kubectl delete -f <文件名>

# 删除某个Pod命令节点 
kubectl delete pod <pod名>
# 删除某个Replication Controller命名节点 
kubectl delete rc <rc名>
kubectl delete deployment 名称

# 删除某个服务命名节点 
kubectl delete service <service名>

# 删除所有Pod节点 
kubectl delete pod --all

二、Deployment

1.概述

  

 Deployment 是 k8s 中一种重要的pod控制器,主要用于实现控制 Pod 的副本数量和水平伸缩以及版本更新。起到一个实现应用程序级别的资源模拟的作用。

2.Deployment的两大功能

通过上面简单的介绍,我们已经大概了解了Deployment, ReplicaSet,以及 Pod 的关系,他们实际上是一种“层层控制”的关系。

那么,Deployment的作用到底是什么,又为什么需要 ReplicaSet 来间接控制 Pod 呢,答案就是为了实现水平扩展 / 收缩和滚动更新功能。

水平扩展 / 收缩

“水平扩展 / 收缩”非常容易实现,Deployment Controller 只需要修改它所控制的 ReplicaSet 的 Pod 副本个数就可以了。

 滚动更新

应用的发布和升级是运维最重要的核心职能之一,那么部署在K8S中的应用是怎么发布升级的呢?其实,你只要编辑修改下 Deployment 的 yaml 文件中镜像版本号,再 apply 一下,就更新成功了,但是具体的实现过程又是怎么样的呢?

在 K8S 中可以使用 kubectl rollout命令来查看 Deployment 对象的状态变化。

3. Deployment常用字段

apiVersion: apps/v1			# API群组和版本
kind: Deployment			# 资源类型
metadata:
  name <string>				# 资源名称,名称空间中要唯一
  namespace <string>		        # 名称空间
spec:
  minReadySeconds <integer>		# Pod就绪后多少秒后没有容器crash才视为“就绪”
  replicas <integer>			# Pod副本数,默认为1
  selector <object>			# 标签选择器,必须和template字段中Pod的标签一致
  template <object>			# 定义Pod模板

  revisionHistoryLimit <integer>	# 滚动更新历史记录数量,默认为10
  strategy <Object>			# 滚动更新策略
    type <string>			# 滚动更新类型,默认为RollingUpdate
    rollingUpdate <Object>		# 滚动更新参数,只能用于RollingUpdate类型
      maxSurge <string>			# 更新期间可以比replicas定义的数量多出的数量或比例
      maxUnavailable <string>		# 更新期间可以比replicas定义的数少的数量或比例 
  progressDeadlineSeconds <integer>	# 滚动更新故障超时时长,默认为600秒
  paused <boolean>			# 是否暂停部署

4.代码实操

#运行一个deployment
[root@ken ~]# kubectl run httpd-ken1--generator=run-pod/v1 --image=httpd --replicas=2

#详细分析 Kubernetes
[root@ken ~]# kubectl get deployment
NAME        READY   UP-TO-DATE   AVAILABLE   AGE
httpd-ken   2/2     2            2           35m

#kubectl get deplouyment命令可以查看 httpd-ken 的状态
[root@ken ~]# kubectl  describe deployment httpd-ken
Name:                   httpd-ken
Namespace:              default
CreationTimestamp:      Tue, 29 Jan 2019 15:27:40 +0800
Labels:                 run=httpd-ken
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               run=httpd-ken
Replicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  run=httpd-ken
  Containers:
   httpd-ken:
    Image:        httpd
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   httpd-ken-5c949b96f (2/2 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  18m   deployment-controller  Scaled up replica set httpd-ken-5c949b96f to 2
kubectl describe replicaset:
[root@ken ~]# kubectl get replicaset
NAME                  DESIRED   CURRENT   READY   AGE
httpd-ken-5c949b96f   2         2         2       20m


#用 kubectl describe replicaset 查看详细信息:
[root@ken ~]# kubectl describe replicaset
Name:           httpd-ken-5c949b96f
Namespace:      default
Selector:       pod-template-hash=5c949b96f,run=httpd-ken
Labels:         pod-template-hash=5c949b96f
                run=httpd-ken
Annotations:    deployment.kubernetes.io/desired-replicas: 2
                deployment.kubernetes.io/max-replicas: 3
                deployment.kubernetes.io/revision: 1
Controlled By:  Deployment/httpd-ken
Replicas:       2 current / 2 desired
Pods Status:    2 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  pod-template-hash=5c949b96f
           run=httpd-ken
  Containers:
   httpd-ken:
    Image:        httpd
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From                   Message
  ----    ------            ----  ----                   -------
  Normal  SuccessfulCreate  20m   replicaset-controller  Created pod: httpd-ken-5c949b96f-twdsd
  Normal  SuccessfulCreate  20m   replicaset-controller  Created pod: httpd-ken-5c949b96f-9cd52


#执行 kubectl get pod:
[root@ken ~]# kubectl get pod
NAME                        READY   STATUS    RESTARTS   AGE
httpd-ken-5c949b96f-9cd52   1/1     Running   0          22m
httpd-ken-5c949b96f-twdsd   1/1     Running   0          22m

 
#用 kubectl describe pod 查看更详细的信息:
root@ken ~]# kubectl describe pod
Name:               httpd-ken-5c949b96f-9cd52
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               host1/172.20.10.7
Start Time:         Tue, 29 Jan 2019 15:46:45 +0800
Labels:             pod-template-hash=5c949b96f
                    run=httpd-ken
Annotations:        <none>
Status:             Running
IP:                 10.244.1.3
Controlled By:      ReplicaSet/httpd-ken-5c949b96f
Containers:
  httpd-ken:
    Container ID:   docker://e59bda9941a16f20027c89a0d8fa8e17797b517f6f5461e905c0d29b57369dde
    Image:          httpd
    Image ID:       docker-pullable://httpd@sha256:44daa8e932a32ab6e50636d769ca9a60ad412124653707e5ed59c0209c72f9b3
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Tue, 29 Jan 2019 15:47:10 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-vb7lm (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-vb7lm:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-vb7lm
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  23m   default-scheduler  Successfully assigned default/httpd-ken-5c949b96f-9cd52 to host1
  Normal  Pulling    23m   kubelet, host1     pulling image "httpd"
  Normal  Pulled     22m   kubelet, host1     Successfully pulled image "httpd"
  Normal  Created    22m   kubelet, host1     Created container
  Normal  Started    22m   kubelet, host1     Started container

三、Service

1.概述

Pod是非永久性资源,会动态创建和销毁,pod的ip会变化。这会导致一类Pod(业务1)访问另一类Pod(业务2)需要找出并跟踪Pod(业务2)的IP地址,再者Pod(业务2)是多个的,如何提供负载均衡呢?虽然Pod1通过轮询一组Pod的ip可以实现,但会Pod就需要增加负载均衡的逻辑,Pod就变得不纯粹了,不符合单一设计原则。于是有了Service,把一类Pods上的应用程序抽象成服务,并提供可以访问他们的策略。

2.通过Service访问Pod

指定 spec.selector即通过打标签的方式

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

 自动创建相应的 Endpoint 对象

kubectl describe ep/my-service

自动创建的Endpoint对象

Subsets:
     Addresses: 10.244.2.1,10.244.4.1

3.Service的三种主要形式

  • ClusterIP: 仅仅使用一个集群内部的IP地址 - 这是默认值。选择这个值意味着你只想这个服务在集群内部才可以被访问到

  • NodePort: 在集群内部IP的基础上,在集群的每一个节点的端口上开放这个服务。你可以在任意:NodePort地址上访问到这个服务。

  • LoadBalancer: 在使用一个集群内部IP地址和在NodePort上开放一个服务之外,向云提供商申请一个负载均衡器,会让流量转发到这个在每个节点上以:NodePort的形式开放的服务上。

 4.部署

(1)配置文件如下

 spec.selector: 指定如何选择 Pod

 spec.ports: 指定如何暴露端

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

使用 kubectl apply 部署,查看 Service 状态

$ kubectl get svc nginx-service -o wide
NAME            TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE   SELECTOR
nginx-service   ClusterIP   10.108.9.49   <none>        80/TCP    11m   app=nginx

ClusterIP 代表服务只能在集群内部访问,此时我们访问服务

$ curl 指定ip
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    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>

服务发现,知道服务的ip就可以访问服务

在 k8s 中,服务可以通过 my-svc.my-namespace.svc.cluster.local 发现

对于刚才部署的 Service 就是 nginx-service.default.svc.cluster.local

在集群中的任意一个 Pod 中通过域名访问

$ curl nginx-service.default.svc.cluster.local
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    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>

四、小结

本次主要分享部署 Pod,Deployment 与 Service,后期还有两篇将进一步深入讲解。

尽情期待

猜你喜欢

转载自blog.csdn.net/weixin_50481708/article/details/126357546