Pod
Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。Pod是一组containers,这些containers共享存储、网络、以及怎样运行这些容器的声明。
Pod中的所有容器共享一个IP地址和端口,并且可以通过 localhost 互相发现,也能进行互相通信。不同 Pod 中的容器的 IP 地址互不相同,如果没有特殊配置不能进行通信。这些不同Pod的容器之间经常通过 Pod IP 地址进行通信。
注意不能将Pod视为持久实体。它们无法在调度失败、节点故障或其他驱逐策略(例如由于缺乏资源或在节点维护的情况下)中生存。
在 Docker 体系的术语中,Pod可以被描述为一组具有共享命名空间和共享文件系统卷的 Docker 容器。
- 设计pod的目的
1.管理:在 Pod 中,系统自动处理多个容器的在并置运行(协同调度)、生命期共享(例如,终止),协同复制、资源共享和依赖项管理;
2.资源共享和通信:pod中的container间能够进行数据共享和通信。
- Pod<->在单个container中运行多个程序
1.使用Pod,Pod内的containers对基础设施可见,使得基础设施能够向这些容器提供服务,例如流程管理和资源监控;
2.解耦软件依赖关系,可以独立地对单个container进行版本控制、重新构建和重新部署,而不影响其他container;
3.效率高,因为基础结构承担了更多的责任,所以容器可以变得更加轻量化。
Pod Preset
在创建Pod 时,用户可以使用 PodPreset 对象将特定信息注入 Pod 中,这些信息可以包括 secret、 卷、卷挂载和环境变量。
PodPreset 是一种API资源,使用 Pod Preset 使得 Pod 模板编写者不必显式地为每个 Pod 设置信息。
当出现 Pod 创建请求时,系统会执行以下操作:
1.检索所有可用 PodPresets
2.检查 PodPreset 的label selector与要创建的 Pod 的标签是否匹配
3.尝试合并 PodPreset 中定义的各种资源,并注入要创建的 Pod
4.发生错误时抛出事件,该事件记录了 pod 信息合并错误,同时在 不注入 PodPreset 信息的情况下创建 Pod
5.为改动的 Pod spec 添加注解,来表明它被 PodPreset 所修改
Service
Service是将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。如果一组Pods需要为集群内的其他Pods提供功能,那么后一组Pods需要用service找出并跟踪要连接的IP地址,以便后一组Pods可以使用前一组。
Service在k8s中是一个RSET对象,与Pod类似。像所有的 REST 对象一样, Service 定义可以基于 POST 方式,请求 API server 创建新的实例。
例子:
(* Service
能够将一个接收 port
映射到任意的 targetPort
。 默认情况下,targetPort
将被设置为与 port
字段相同的值)
Service Type
Kubernetes ServiceTypes
允许指定一个需要的类型的 Service,默认是 ClusterIP
类型。Type
的取值以及行为如下:
ClusterIP
:通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的ServiceType
。NodePort
:通过每个 Node 上的 IP 和静态端口(NodePort
)暴露服务。NodePort
服务会路由到ClusterIP
服务,这个ClusterIP
服务会自动创建。通过请求<NodeIP>:<NodePort>
,可以从集群的外部访问一个NodePort
服务。LoadBalancer
:使用云提供商的负载局衡器,可以向外部暴露服务。外部的负载均衡器可以路由到NodePort
服务和ClusterIP
服务。externalName
:通过返回CNAME
和它的值,可以将服务映射到externalName
字段的内容(例如,foo.bar.example.com
)。 没有任何类型代理被创建。生成可访问的Pod&Service
加入集群
- 下载集群对应的kube客户端
https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.14.md
ssh-keygen -R ip
scp username@ip:/root/.kube/config ~/.kube/config-160
/root/.kube/config
:远程目录~/.kube/config-160
:本地目录
- 将config-160加入环境变量
- 测试配置是否成功,使用
kubectl get pod
,若配置成功,则能够获取到集群上的pods,如下图所示
ps:集群发生变化后需要重新操作以上步骤,否则会出现以下报错
参考:https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/
生成Pod
创建一般Pod
1)使用yaml文件
apiVersion: v1
kind: Pod //根据实际情况,此处资源类型可以是Deployment、Job、Ingress、Service等
metadata: //包含Pod的一些meta信息,比如名称、namespace、标签等信息
name: kube100-site
namespace: default
labels:
app: web
app1: abc234 #注意:labels里面的标签值不能是纯数字
//sepc:包括一些container,storage,volume以及其他Kubernetes需要的参数
//以及诸如是否在容器失败时重新启动容器的属性。可在特定Kubernetes API找到完整的Kubernetes Pod的属性
spec:
containers:
- name: front-end //容器名
image: nginx //表示是基于nginx基本镜像
ports:
- containerPort: 80 //容器将会监听的指定端口号
- name: flaskapp-demo
image: jcdemo/flaskapp
ports:
- containerPort: 5000
resources: //运行时需要的资源 分为limit和request
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
type: NodePort #svc类型
selector: #匹配如下标签的pod来进行访问,匹配不到是访问不了的 这里起作用的就是selector(选择器)
app: kube100-site
ports:
- name: http
protocol: TCP
port: 80 #前端访问端口
targetPort: 80 #后端真实服务使用端口
2)使用命令行kubectl run my-nginx --image=nginx --replicas=2 --port=80
暴露服务:kubectl expose deployment my-nginx --port=8080 --target-port=80 --external-ip=x.x.x.168
参数说明
—port 容器的端口
—container-port和target-port是一个意思,指的是宿主机转发的端口,可以随意指定一个,也可以不指定
—external-ip 对外暴露的ip地址,一般用公网IP地址,执行那个命令过后,我们就可以在公网上访问了,但是这里有个问题就是这个IP地址必须是安装了k8s的机器的IP,如果你随便用一个IP是不能访问的,这里也给应用上造成了不便
—type=LoadBalancer
- 创建Pod
kubectl create -f pod.yaml
(创建时验证语法,使用—validate。该命令会显示它发现的问题,但仍然会按照配置文件的声明来创建资源)kubectl create -f pod.yaml --validate
- 查看pod状态
status显示为ImagePullBackOff,即没有运行成功,使用kubectl describe
命令进行排查,可以查看报错并解决。
修改错误后,得到以下正常运行状态(status=running)。
查看pod输出kubectl logs <nodename>
。
- 查看service状态
kubectl get svc
- 启动服务
可以看到分配的node和分配的ip。
查看service:kubectl describe service/my-nginx
尝试访问,失败。这是由于service的Type为ClusterIP的缘故,当Type为ClusterIP时,只有在集群上的node才能访问服务,而本台电脑不在集群中。
重新创建Type类型为NodePort的service。
需要在node上运行,得到node的ip后,通过<nodeip>:30435
访问,成功。
- 相关命令
kubectl get svc myweb -o yaml
查看某个servicekubectl get node
查看nodekubectl get node -o wide
可以得到node的具体ipkubectl delete -f pod.yaml
基于yaml删除pod
- 解决ErrImagePull&&ImagePullBackOff