k8s的pod分类
pod分为两类:自主式pod与控制器管理的pod
自主式pod由k8s管理器进行管理,而static pod由kubelet进行创建与管理
自主式pod
自主式pod总是在前台运行,同时接受k8s管理与调度,当集群当中的pod因为某种原因停止,k8s会根据其副本的数量,重新的生成对应的pod
自我管理的pod,创建以后仍然需要提交给apiserver,由apiserver接收以后借助于调度器将其调度至指定的node节点,由node启动此pod
如果此pod出现故障,需要重启容器则由kubelet来完成
如果node节点故障了,那么此pod将会消失。其无法实现全局调度。所以不推荐使用此种pod
控制器管理的pod
常见的pod控制器:
ReplicationController:当启动一个pod时。这个pod如果不够用可以再启个副本,而后由控制器来管理同一类pod的各种副本与对象。一旦副本少了就会自动增加。采取多退少补的规则,精确符合我们所定义的期望。支持滚动更新
ReplicaSet:由一个名叫Deployment的声明式更新的控制器来管理
Deployment:Deployment只能管理无状态的应用
StateFulSet:有状态副本集,可以管理有状态的应用
DaemonSet:如果需要在每个node上运行一个副本的时候可以用DaemonSet
核心主键
HPA
Deployment还支持二级控制器,HPA(HorizontalPodAutoscaler,水平pod自动伸缩控制器),一般情况下我们可以确保一个node上有2个pod在运行,万一用户访问流量增加,2个pod不足以承载这么多访问量怎么办?此时我们就应该要增加pod资源,那么到底应该加几个?
HPA控制器可自动监控pod、自动进行扩展。
service
假如有2个pod,pod有其生命周期,万一pod所在的节点宕机了,那么此pod将应该要在其他的节点上重建,而重建完的pod与原来的pod已经不是同一个pod了,只是两者都是运行的同一个服务而已。且每个容器都有其IP地址,重建的pod中的容器其IP地址与之前的pod中容器的IP地址是不一样的,如此一来就会存在一个问题,客户端如何访问这些pod中的容器呢?(会转换到另一个节点去运行)
用于做服务发现,pod是有生命周期的,一个pod随时都有可能离去,随时都有可能会有其他内pod加进来,假如它们提供的是同一种服务,客户端是无法通过固定的手段来访问这些pod的,因为pod本身是不固定的,它们随时可能被替换掉,无论使用主机名还是IP地址,都随时会被替换掉。
为了尽可能的降低客户端与pod间协调的复杂度,k8s为每一组提供同类服务的pod和其客户端之间添加了一个中间层,这个中间层是固定的,这个中间层就叫service。
service只要不被删除,其地址与名称皆是固定的,当客户端需要在其配置文件中写*问某个服务时,它不再需要自动发现,只需要在配置文件中写明service的名称即可,而这个service是个调度器,其不但能够提供一个稳定的访问入口,还可以做反向代理,当service接收到客户端的请求后,会将其代理到后端的pod之上,一旦pod宕机了会立即新建一个pod,这个新建的pod会立即被service关联上,作为service后端的可用pod之一
客户端程序访问服务都是通过IP+端口或者主机名+端口的方式来实现的。而service关联后端的pod不是靠它的IP和主机名,而是靠pod的标签选择器。只要创建的pod的label是统一的,无论IP地址和主机如何改变,其都能被service所识别。如此一来,只要pod属于标签选择器,只要其在service的管理范围之内,则其就会被关联到service中,当这个动态的pod关联到service中之后,再进行动态的探测此pod的IP地址、端口,再将其作为自己后端可调度的可用服务蒂王机为象。因此,客户端的请求发送到service,然后由service代理到后端真实的pod中的容器进行响应。
service不是一个程序,也不是一个组件,它只是一个iptables的dnat规则,service作为k8s的对象,有其自身的名称,而service的名称相当于服务的名称,而这个名称可以被解析。
AddOns附件
dns pod:装完k8s后第一件事就需要在k8s集群上部署一个dns pod,以确保各service的名称能够被解析可以动态改变,包括动态创建、动态删除、动态修改,比如把service的名称改了,dnspod会自动触发,将dns解析记录中的名称也给改掉;假如我们手动把service的ip地址给改了,改完以后会自动触发,将dns服务中的解析记录给改掉。如此一来,客户端去访问pod资源的时候可以直接访问service的名称,然后由集群中专用的dns服务来负责解析。
这种pod是k8s自身的服务就需要用到的pod,所以我们把它称为基础性的系统架构级的pod对象,而且它们也被称为集群附件
Kubernetes网络模型
k8s的三种网络模型分别属于三个网段,分别是:
- 节点网络
- service集群网络
- pod网络
同一pod内的多个容器间如何通信
lo网卡
各pod之间如何通信?
1.物理桥桥接,规模大的情况下会产生广播风暴
2.Overlay Network,通过隧道的方式转发报文
同节点Pod之间的通信
在容器启动前,会为容器创建一个虚拟Ethernet接口对,这个接口对类似于管道的两端,其中一端在主机命名空间中,另外一端在容器命名空间中,并命名为eth0。在主机命名空间的接口会绑定到网桥。网桥的地址段会取IP赋值给容器的eth0接口。
不同节点上的Pod通信
我们已经知道一个节点上的容器都会连接到同一网桥,因此要让运行在不同节点上的容器之间能够通信,这些节点的网桥就需要以某种方式连接起来。
跨整个集群的Pod的IP地址必须是唯一的,所有跨节点的网桥必须使用不重叠的网络地址段,以防止不同节点上的Pod拿到同一IP地址,即确保没有IP地址冲突。
发送到B节点上的容器时,报文会先通过veth接口对到网桥,再由网桥到A节点的物理适配器,再通过网线传输到B节点的物理适配器,再通过B的网桥,经过接口对到达目标容器。
注意:上述情形仅在节点连接到相同网关,之间没有任何路由设备时有效。否则,路由设备会因为IP私有产生丢包现象,除非设置路由规则。但随着节点的增加,路由的配置会变得非常困难。因此我们使用SDN(软件定义网络)技术来简化此类问题,SDN可以忽略底层网络拓扑,使其就像连接到同一网关。
Pod与Service
在不同节点上的Pod通信中,我们知道了Pod是以IP地址进行通信,但Kubernetes 的集群中, Pod 可能会频繁的销毁和创建,也就是说 Pod 的 IP 不是固定的。
为了解决这个问题,Service 提供了访问 Pod 的抽象层,即为一组功能相同的Pod提供单一不变的接入点资源。
无论后端的 Pod 如何变化,Service 都作为稳定的前端对外提供服务。
同时,Service 还提供了高可用和负载均衡功能,Service 负责将请求转发给正确的 Pod。
kubectl常用命令的使用
命令 | 说明 |
---|---|
create | 使用文件或者标准输入的方式创建一个资源 |
expose | 将一个资源公开为为新的Kubernetes Service |
run | 创建并运行一个或多个容器镜像 |
set | 配置应用资源 |
explain | 显示资源文档信息 |
get | 获取显示一个或多个资源 |
edit | 编辑服务器上定义的资源 |
delete | 按文件名、stdin、资源和名称或按资源和标签选择器删除资源 |
kubectl help
查看kubectl相关的命令
[root@master ~]# kubectl help
kubectl controls the Kubernetes cluster manager.
Find more information at: https://kubernetes.io/docs/reference/kubectl/overview/
Basic Commands (Beginner):
create Create a resource from a file or from stdin.
expose 使用 replication controller, service, deployment 或者 pod 并暴露它作为一个 新的 Kubernetes Service
run 在集群中运行一个指定的镜像
set 为 objects 设置一个指定的特征
Basic Commands (Intermediate):
explain 查看资源的文档
get 显示一个或更多 resources
edit 在服务器上编辑一个资源
delete Delete resources by filenames, stdin, resources and names, or by resources and label selector
Deploy Commands:
rollout Manage the rollout of a resource
scale Set a new size for a Deployment, ReplicaSet or Replication Controller
autoscale 自动调整一个 Deployment, ReplicaSet, 或者 ReplicationController 的副本数量
Cluster Management Commands:
certificate 修改 certificate 资源.
cluster-info 显示集群信息
top Display Resource (CPU/Memory/Storage) usage.
cordon 标记 node 为 unschedulable
uncordon 标记 node 为 schedulable
drain Drain node in preparation for maintenance
taint 更新一个或者多个 node 上的 taints
Troubleshooting and Debugging Commands:
describe 显示一个指定 resource 或者 group 的 resources 详情
logs 输出容器在 pod 中的日志
attach Attach 到一个运行中的 container
exec 在一个 container 中执行一个命令
port-forward Forward one or more local ports to a pod
proxy 运行一个 proxy 到 Kubernetes API server
cp 复制 files 和 directories 到 containers 和从容器中复制 files 和 directories.
auth Inspect authorization
debug Create debugging sessions for troubleshooting workloads and nodes
Advanced Commands:
diff Diff live version against would-be applied version
apply 通过文件名或标准输入流(stdin)对资源进行配置
patch Update field(s) of a resource
replace 通过 filename 或者 stdin替换一个资源
wait Experimental: Wait for a specific condition on one or many resources.
kustomize Build a kustomization target from a directory or a remote url.
Settings Commands:
label 更新在这个资源上的 labels
annotate 更新一个资源的注解
completion Output shell completion code for the specified shell (bash or zsh)
Other Commands:
api-resources Print the supported API resources on the server
api-versions Print the supported API versions on the server, in the form of "group/version"
config 修改 kubeconfig 文件
plugin Provides utilities for interacting with plugins.
version 输出 client 和 server 的版本信息
Usage:
kubectl [flags] [options]
Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).
create
kubectl create可以通过配置文件名或stdin创建一个集群资源对象。支持JSON和YAML格式的文件
[root@master ~]# kubectl create deployment b1 --image busybox
deployment.apps/b1 created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
b1-68578fbb6c-g28l7 0/1 ContainerCreating 0 11s
nginx-6799fc88d8-5kshn 1/1 Running 0 33h
run
kubectl run创建并运行一个或多个容器镜像。
kubectl run和docker run一样,它能将一个镜像运行起来。下面使用kubectl run来将一个nginx的镜像启动起来。
[root@master ~]# kubectl run nginx --image=nginx --expose --port=80 #指定镜像,指定暴露端口
service/nginx created
deployment.apps/nginx created
使用kubectl run会自动创建deployment,加上--expose会自动创建service。
[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.68.0.1 <none> 443/TCP 10d
nginx ClusterIP 10.68.56.89 <none> 80/TCP 1m
[root@master ~]# kubectl get deploy
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
mysql 1 1 1 1 16m
nginx 1 1 1 1 1m
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mysql-5fb6c74b86-xg97j 1/1 Running 0 21m
nginx-6f858d4d45-dt44v 1/1 Running 0 6m
get
kubectl get获取列出一个或多个资源的信息。
例如,分别获取当前集群中pod、deployment和svc的信息。
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mysql-5fb6c74b86-xg97j 1/1 Running 0 42m
nginx-566c464789-w7669 1/1 Running 0 15m
[root@master ~]# kubectl get deploy
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
mysql 1 1 1 1 43m
nginx 1 1 1 1 28m
[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.68.0.1 <none> 443/TCP 10d
mysql ClusterIP 10.68.86.66 <none> 33060/TCP 36m
expose
创建一个service服务,并且暴露端口让外部可以访问
//常用选项
--port 要映射的宿主机端口
--target-port 映射给那个容器端口
[root@master ~]# kubectl expose deployment web --port 8080 --target-port 80
service/web exposed
[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web ClusterIP 10.104.77.75 <none> 8080/TCP 25s
[root@master ~]# curl http://10.104.77.75:8080
<!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>
delete
kubectl delete可以通过配置文件名、stdin、资源名称或label选择器来删除资源。支持JSON和YAML格式的文件。
下面删除nginx的pod。
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mysql-5fb6c74b86-xg97j 1/1 Running 0 55m
nginx-566c464789-w7669 1/1 Running 0 27m
[root@master ~]# kubectl delete pod/nginx-566c464789-w7669
pod "nginx-566c464789-w7669" deleted
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mysql-5fb6c74b86-xg97j 1/1 Running 0 55m
nginx-566c464789-8lr2x 0/1 ContainerCreating 0 1m
又生成了一个新的nginx的pod,为什么?这是因为对应的deployment还存在。
[root@master ~]# kubectl delete deploy/nginx
deployment.extensions "nginx" deleted
[root@master ~]# kubectl get deploy
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
mysql 1 1 1 1 1h
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mysql-5fb6c74b86-xg97j 1/1 Running 0 1h
删除掉deployment,其对应的pod也会被删除。