k8s之Pod概念和使用
Pod是可以在Kubernetes中创建和管理的最小可部署单元。Pod是一组(一个或多个)容器的打包,这一组容器共享存储、网络;pod中的容器地位均等且一同调度,在共享的上下文中运行。这些容器在业务上是紧密耦合在一起的。
Pod就像一台“逻辑主机”为这一组紧密相关的容器提供运行上下文。Pod除了正常运行的业务容器外还可以在启动期间运行Init容器。也可以在集群支持临时容器的情况下,以调试为目的注入临时容器。
通过kubectl get pod -o yaml 查看pod的信息,其中status.phase字段表示该pod的阶段。 通过kubectl describe pod 查看pod详情,其中State字段表示该pod的状态(阶段)。
kubectl get pod -o yaml
kubectl describe pod
| 阶段(状态) | 描述 |
|---|---|
| Pending | Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。 |
| Running | Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。 |
| Succeeded | Pod 中的所有容器都已成功终止,并且不会再重启。 |
| Failed | Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止。 |
| Unknown | 因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败 |
| 状态值 | 描述 |
|---|---|
| Waiting | 如果容器并不处在 Running 或 Terminated 状态之一,它就处在 Waiting 状态。处于 Waiting 状态的容器仍在运行它完成启动所需要的操作。使用 kubectl 来查询包含 Waiting 状态的容器的 Pod 时,会看到一个 Reason 字段,其中给出了容器处于等待状态的原因 |
| Running | Running 状态表明容器正在执行状态并且没有问题发生。 如果配置了 postStart回调,那么该回调已经执行且已完成。 如果使用 kubectl 来查询包含 Running 状态的容器的 Pod 时,也会看到 关于容器进入 Running 状态的信息。 |
| Terminated | 处于 Terminated 状态的容器已经开始执行并且正常结束或者因为某些原因失败。如果使用 kubectl 来查询包含 Terminated 状态的容器的 Pod 时,会看到 容器进入此状态的原因、退出代码以及容器执行期间的起止时间。 |
myhello-pod.yaml配置文件配置:
apiVersion: v1
kind: Pod
metadata:
name: myhello-pod
namespace: default
labels:
name: myhello-pod
env: dev
spec:
restartPolicy: Always
containers:
- name: myhello
image: nongtengfei/hello:1.0.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
command: ["./app"]
args: ["--param1=k8s-p1", "--param2=k8s-p2"]
resources:
limits:
cpu: 200m
memory: 500Mi
requests:
cpu: 100m
memory: 200Mi
env: # 注入到容器的环境变量
- name: env1
value: "k8s-env1"
- name: env2
value: "k8s-env2"
关键词的解释如下:
容器重启策略,可选值为:Always、Never、OnFailure,默认值为 Always。restartPolicy 适用于 Pod中的所有容器。当pod中的容器退出时,kubelet 会按指数回退 方式计算重启的延迟(10s、20s、40s、…),其最长延迟为 5 分钟。 一旦某容器执行了 10 分钟并且没有出现问题,kubelet 对该容器的重启回退计时器执行重置操作。
镜像拉取策略,可选值为:Always、Never、IfNotPresent,默认为:Always。
指定容器启动命令,若未指定该值则默认为镜像中指定的启动命令。
容器启动命令参数,若未指定则该值默认为容器镜像中指定的启动参数。
容器使用资源设置。
(1)创建pod。
kubectl create -f myhello-pod.yaml
(2)访问pod中的容器。
# 通过端口转发来查看该pod是否可以正常提供服务
kubectl port-forward pod/myhello-pod 5000:80
# 通过curl访问,该pod,查看其环境变量、启动参数等信息是否生效
curl http://localhost:5000/print/env
curl http://localhost:5000/print/startup
(1)定义。
apiVersion: v1
kind: Pod
metadata:
name: myhello-pod
namespace: default
labels:
name: myhello-pod
env: dev
spec:
restartPolicy: Always
containers:
- name: myhello
image: nongtengfei/hello:1.0.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
command: ["./app"]
args: ["--param1=k8s-p1", "--param2=k8s-p2"]
resources:
limits:
cpu: 200m
memory: 500Mi
requests:
cpu: 100m
memory: 200Mi
env: # 注入到容器的环境变量
- name: env1
value: "k8s-env1"
- name: env2
value: "k8s-env2"
- name: myredis #容器的名称
image: redis #容器对应的 Docker Image
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6379
resources:
limits:
cpu: 200m
memory: 500Mi
requests:
cpu: 100m
memory: 200Mi
# 根据文件删除资源
kubectl delete -f myhello-pod.yaml
# 根据文件应用资源
kubectl apply -f myhello-pod.yaml
(2)访问pod中的容器。
# 通过端口转发来查看该pod是否可以正常提供服务
kubectl port-forward pod/myhello-pod 5001:80 5002:6379 --address 192.168.0.142 --address localhost
# 访问myhello容器
curl http://localhost:5001/ping
# 访问redis,通过新创建一个其他redis,然后通过其他redis的客户端访问上面redis-server
kubectl run myredis --image=redis
# 进入redis交互
kubectl exec -it pod/myredis -- /bin/bash
# 以转发的地址和端口访问
redis-cli -h 192.168.0.142 -p 5002
# 以pod ip 访问
redis-cli -h <podIP> -p 6379
Init 容器是一种特殊容器,在 Pod 内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。
每个 Pod 中可以包含多个容器, 应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。
如果 Pod 的 Init 容器失败,kubelet 会不断地重启该 Init 容器直到该容器成功为止。 然而,如果 Pod对应的 restartPolicy 值为 “Never”,并且 Pod 的 Init 容器失败, 则 Kubernetes 会将整个 Pod 状态设置为失败。
Init 容器与普通容器的区别:
init 容器的特殊性,依次执行、容器必须来到完成状态、init容器完成后才会启动应用容器。
(1)定义。
apiVersion: v1
kind: Pod
metadata:
name: myhello-pod
namespace: default
labels:
name: myhello-pod
env: dev
spec:
restartPolicy: Always
initContainers:
- name: init-myservice
image: busybox
# 查找命名空间下myservice服务,如果存在则执行成功,如果不存在则一直查找
command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
- name: init-mydb
image: busybox
# 查找命名空间下mydb服务,如果存在则执行成功,如果不存在则一直查找
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
containers:
- name: myhello
image: nongtengfei/hello:1.0.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
command: ["./app"]
args: ["--param1=k8s-p1", "--param2=k8s-p2"]
resources:
limits:
cpu: 200m
memory: 500Mi
requests:
cpu: 100m
memory: 200Mi
env: # 注入到容器的环境变量
- name: env1
value: "k8s-env1"
- name: env2
value: "k8s-env2"
- name: myredis #容器的名称
image: redis #容器对应的 Docker Image
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6379
resources:
limits:
cpu: 200m
memory: 500Mi
requests:
cpu: 100m
memory: 200Mi
(2)创建容器。
# 删除原有pod
kubectl delete -f myhello-pod.yaml
# 重新应用
kubectl apply -f myhello-pod.yaml
(3)获取pod,可以看到pod一直处于init阶段。
# 获取pod
kubectl get -f myhello-pod.yaml
(4)查看pod详情。
kubectl describe -f myhello-pod.yaml
输出详细信息,pod状态为Pending,容器状态:仅init-myservice 为running,其他容器均为:Waiting。
(5)查看容器日志。
kubectl logs -f myhello-pod -c init-myservice
(6) 创建myservice服务。
内容:
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
kubectl create -f myservice.yaml
(7)查看pod状态,容器日志。
kubectl get -f myhello-pod.yaml
kubectl describe -f myhello-pod.yaml
kubectl logs -f myhello-pod -c init-mydb
(8)创建mydb服务。
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
kubectl create -f mydb.yaml
(9)查看pod状态,容器日志。
kubectl get -f myhello-pod.yaml
kubectl describe -f myhello-pod.yaml
kubectl logs -f myhello-pod -c init-mydb
以上示例可以看出:
Kubernetes 支持 postStart 和 preStop 事件。 当一个容器启动后,Kubernetes 将立即发送 postStart事件;在容器被终结之前, Kubernetes 将发送一个 preStop 事件。容器可以为每个事件指定一个处理程序。
apiVersion: v1
kind: Pod
metadata:
name: myhello-pod
namespace: default
labels:
name: myhello-pod
env: dev
spec:
restartPolicy: Always
initContainers:
- name: init-myservice
image: busybox
# 查找命名空间下myservice服务,如果存在则执行成功,如果不存在则一直查找
command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
- name: init-mydb
image: busybox
# 查找命名空间下mydb服务,如果存在则执行成功,如果不存在则一直查找
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
containers:
- name: myhello
image: nongtengfei/hello:1.0.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
command: ["./app"]
args: ["--param1=k8s-p1", "--param2=k8s-p2"]
resources:
limits:
cpu: 200m
memory: 500Mi
requests:
cpu: 100m
memory: 200Mi
env: # 注入到容器的环境变量
- name: env1
value: "k8s-env1"
- name: env2
value: "k8s-env2"
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c","echo post start command exec >> /tmp/data"]
preStop:
exec:
command: ["/bin/sh", "-c","echo pre stop command exec >> /tmp/data"]
- name: myredis #容器的名称
image: redis #容器对应的 Docker Image
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6379
- resources:
limits:
cpu: 200m
memory: 500Mi
requests:
cpu: 100m
memory: 200Mi
kubectl delete -f myhello-pod.yaml
kubectl apply -f myhello-pod.yaml
# 使用shell 连接到pod中的容器
kubectl exec -it pod/myhello-pod -c myhello -- sh
# 查看postStart处理函数写入的文本
cat /tmp/data

我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po