博主昵称:跳楼梯企鹅
博主主页面链接:博主主页传送门博主专栏页面连接:专栏传送门--网路安全技术
创作初心:本博客的初心为与技术朋友们相互交流,每个人的技术都存在短板,博主也是一样,虚心求教,希望各位技术友给予指导。
博主座右铭:发现光,追随光,成为光,散发光;
博主研究方向:渗透测试、机器学习 ;
博主寄语:感谢各位技术友的支持,您的支持就是我前进的动力 ;
本篇文章分为3次分享完
Pod 是 K8S 系统中可以创建和管理的最小单元,是资源对象模型中由用户创建或部署的最小资源对象模型,也是在 K8S 上运行容器化应用的资源对象,其它的资源对象都是用来支撑或者扩展 Pod 对象功能的,比如控制器对象是用来管控 Pod 对象的,Service 或者 Ingress 资源对象是用来暴露 Pod 引用对象的,PersistentVolume 资源对象是用来为 Pod 提供存储等等,K8S 不会直接处理容器,而是 Pod,Pod 是由一个或多个 container 组成。
Pod 是 Kubernetes 的最重要概念,每一个 Pod 都有一个特殊的被称为 “根容器”的 Pause 容器。Pause 容器对应的镜像属于 Kubernetes 平台的一部分,除了 Pause 容器,每个 Pod 还包含一个或多个紧密相关的用户业务容器
- 最小部署的单元
- Pod 里面是由一个或多个容器组成【一组容器的集合】
- 一个 pod 中的容器是共享网络命名空间
- Pod 生命周期是短暂的
- 每个 Pod 包含一个或多个紧密相关的用户业务容器
意义:Pod 是在 K8S 集群中运行部署应用或服务的最小单元,它是可以支持多容器的。Pod 的设计理念是支持多个容器在一个 Pod 中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。同时 Pod 对多容器的支持是 K8S 中最基础的设计理念。在生产环境中,通常是由不同的团队各自开发构建自己的容器镜像,在部署的时候组合成一个微服务对外提供服务。
- 长期伺服型:long-running
- 批处理型:batch
- 节点后台支撑型:node-daemon
- 有状态应用型:stateful application
主要有以下两大机制
- 共享网络
- 共享存储
(1)共享网络:
容器本身之间相互隔离的,一般是通过 namespace 和 group 进行隔离,那么Pod里面的容器如何实现通信?
首先需要满足前提条件,也就是容器都在同一个namespace之间关于Pod实现原理,首先会在Pod会创建一个根容器:
pause容器
,然后我们在创建业务容器 【nginx,redis 等】,在我们创建业务容器的时候,会把它添加到info容器
中而在
info容器
中会独立出 ip地址,mac地址,port 等信息,然后实现网络的共享
(2)共享存储:
- # 查看所有的 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
- # 删除某个Replication Controller命名节点
- kubectl delete rc
- kubectl delete deployment 名称
-
- # 删除某个服务命名节点
- kubectl delete service
-
- # 删除所有Pod节点
- kubectl delete pod --all
Deployment 是 k8s 中一种重要的pod控制器,主要用于实现控制 Pod 的副本数量和水平伸缩以及版本更新。起到一个实现应用程序级别的资源模拟的作用。
通过上面简单的介绍,我们已经大概了解了Deployment, ReplicaSet,以及 Pod 的关系,他们实际上是一种“层层控制”的关系。
那么,Deployment的作用到底是什么,又为什么需要 ReplicaSet 来间接控制 Pod 呢,答案就是为了实现水平扩展 / 收缩和滚动更新功能。
水平扩展 / 收缩
“水平扩展 / 收缩”非常容易实现,Deployment Controller 只需要修改它所控制的 ReplicaSet 的 Pod 副本个数就可以了。
滚动更新
应用的发布和升级是运维最重要的核心职能之一,那么部署在K8S中的应用是怎么发布升级的呢?其实,你只要编辑修改下 Deployment 的 yaml 文件中镜像版本号,再 apply 一下,就更新成功了,但是具体的实现过程又是怎么样的呢?
在 K8S 中可以使用 kubectl rollout命令来查看 Deployment 对象的状态变化。
- apiVersion: apps/v1 # API群组和版本
- kind: Deployment # 资源类型
- metadata:
- name
# 资源名称,名称空间中要唯一 - namespace
# 名称空间 - spec:
- minReadySeconds <integer> # Pod就绪后多少秒后没有容器crash才视为“就绪”
- replicas <integer> # Pod副本数,默认为1
- selector
- template
-
- revisionHistoryLimit <integer> # 滚动更新历史记录数量,默认为10
- strategy
- type
# 滚动更新类型,默认为RollingUpdate - rollingUpdate
- maxSurge
# 更新期间可以比replicas定义的数量多出的数量或比例 - maxUnavailable
# 更新期间可以比replicas定义的数少的数量或比例 - progressDeadlineSeconds <integer> # 滚动更新故障超时时长,默认为600秒
- paused
# 是否暂停部署
- #运行一个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
Pod是非永久性资源,会动态创建和销毁,pod的ip会变化。这会导致一类Pod(业务1)访问另一类Pod(业务2)需要找出并跟踪Pod(业务2)的IP地址,再者Pod(业务2)是多个的,如何提供负载均衡呢?虽然Pod1通过轮询一组Pod的ip可以实现,但会Pod就需要增加负载均衡的逻辑,Pod就变得不纯粹了,不符合单一设计原则。于是有了Service,把一类Pods上的应用程序抽象成服务,并提供可以访问他们的策略。
指定 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
ClusterIP: 仅仅使用一个集群内部的IP地址 - 这是默认值。选择这个值意味着你只想这个服务在集群内部才可以被访问到。
NodePort: 在集群内部IP的基础上,在集群的每一个节点的端口上开放这个服务。你可以在任意:NodePort地址上访问到这个服务。
LoadBalancer: 在使用一个集群内部IP地址和在NodePort上开放一个服务之外,向云提供商申请一个负载均衡器,会让流量转发到这个在每个节点上以:NodePort的形式开放的服务上。
(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
- 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.orga>.<br/>
- Commercial support is available at
- <a href="http://nginx.com/">nginx.coma>.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
- 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.orga>.<br/>
- Commercial support is available at
- <a href="http://nginx.com/">nginx.coma>.p>
-
- <p><em>Thank you for using nginx.em>p>
- body>
- html>
本次主要分享部署 Pod,Deployment 与 Service,后期还有两篇将进一步深入讲解。
尽情期待