Pod概念
pod 是k8s的基本操作单元,是应用运行的载体。包含一个或多个容器。
整个k8s系统都是围绕POD围绕展开的。
比如如何运行POD,保持POD数量、如何访问POD等。
Pod模板
#pod.yml
apiserver: v1 # Kubernetes的API版本声明,目前是V1
kind: pod # API对象的类型声明,当前类型是Pod
metadata: # 设置Pod的元数据
name: string # 指定POD的名称,POD名称必须在namespace内唯一,须符合RFC 1035
namespace: string # 命名空间,不指定是用default的命名空间
label: # 自定义属性列表,Service等可以根据label找到自定义POD
- name: string
annotations:
- name: string
spec: # POD的详细配置
containers:
- name:string # image镜像信息
images: string
imagePullPolice: [Always | Never | IfNotPresent] # 镜像下载策略,
command: [string] # 容器启动命令
args: [string]
workingDir: string # 容器工作目录
volumneMounts: # 数据持久化,挂载宿主机目录
- name: string
mountPath: string
readOnly: boolean
protocol: string
ports: # 端口映射策略
- name: string
containerPort: int # 容器Port
hostPort: int # 宿主机端口
protocol: string # TCP UDP
env: # 环境变量,POD内容器共享环境变量
- name: string
value: string
resources:
limits:
cpu: string
memory: string
requests:
cpu: string
memory: string
livenessPrbe:
exec:
command: [string]
httpGet:
path: string
port: int
host: string
scheme: string
httpHeaders:
- name: string
value: string
tcpSocket:
port: int
initialDelaySeconds: number
timeoutSeconds: number
periodSeconds: number
successThreadhold: 0
failureThreadhold: 0
securityContext:
privileged: false
RestartPolicy: [Always | Never | OnFailure] # POD的启动策略
nodeSelector: object
imagePullSecrets:
- name: string
hostNetwork: false
volumes:
- name: string
emptyDir: {}
hostPath:
path: string
secret:
secretName: string
items:
- key: string
path:string
configMap:
name: string
items:
- key: string
path: string
###操作pod
- 创建 kubectl create -f createpod.yml
- 查询 1.kubectl get pod pod名称 2.kubectl describe pod pod名称
- 删除 kubectl delete pod pod名称
- 更新 kubectl replace /path/to/yourYaml.yml
#createpod.yml
apiserver: v1
kind: pod
metadata:
name: testpod
spec:
containers:
- name: test
image: nginx
ports:
- name:web
containerPort: 80
Pod与容器
在docker中,容器是最小处理单元,增、删、改、查的对象是容器,容器间隔是基于Linux namespace 实现的。
在Kubernetes中,Pod 包含一个或者多个相关的容器,是容器的一种延伸扩展,一个Pod也是一个隔离体,
而Pod内部包含一组Docker容器又是共享的(PID NetWork IPC UTS等)
Pod生命周期
- Pending :POD已经创建,但是有一个或者多个容器还未创建,包括POD调度阶段,已经容器镜像的下载过程
- Running :POD已经调度到Node,所有容器已经创建,并且至少有一个正在运行,或者重启
- Succeeded : POD中所有容器正常退出
- Failed : POD至少有一个容器异常退出
容器状态
- Waiting 容器正在等待创建
- Running 容器已经创建,正在运行
- Terminate 容器终止退出
Pod容器间通信
每个Pod之间都拥有一个独立的IP地址,而且假定所有Pod都在一个可以直接连通的、扁平的网络空间之中。
Pod 中所有容器共享网络空间可以直接通过localhost:port访问
同一Node中的Pod通信
同一Node中的Pod通信默认路由都是Docker0的地址,由于他们连着一个Docker0网桥,地址段相同,直接可以通信。
不同Node中Pod间通信
Docker0网桥与宿主机网卡是两个完全不同的IP网段,并且Node之间的通信只能宿主机物理网卡进行,要实现不同Node上的Pod容器之间的通信,
必须想办法通过主机的IP地址进行寻址和通信。所有POD之间可以通过Pod的ip地址进行通信。
k8s官方推荐的是使用flannel组建一个大二层扁平网络,pod的ip分配由flannel统一分配,通讯过程也是走flannel的网桥。
每个node上面都会创建一个flannel0虚拟网卡,用于跨node之间通讯。所以容器直接可以直接使用pod id进行通讯。
跨节点通讯时,发送端数据会从docker0路由到flannel0虚拟网卡,接收端数据会从flannel0路由到docker0,这是因为flannel会添加一个路由。
kubernetes 自从1.7开始,可以在pod 的container 内获取pod的spec,metadata 等信息。
具体方法可以通过env获取:
env:
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: MY_POD_SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
kube-proxy
kube-proxy是一个简单的网络代理和负载均衡。
它的作用主要是负责Service的实现:Pod到Service,以及NodePort向Service的访问
单主机 Docker网络通信
- Host模式
Host模式 启用Host模式,那么该容器将不会获得一个独立的Network Namespace 而是宿主机共享一个Network Namespace 因此容器将不会虚拟自己的网卡,配置自己的IP等。
容器没有隔离、独立的网络栈、容器与宿主机公有网络栈而争抢网络资源,并且容器奔溃也可能导致主机崩溃。容器不再拥有所有的端口资源,因为一些端口已经被宿主机占用。 - Container 模式
Container 模式,Container 是一种特殊的网络模式,该模式下的使用相同网络命名空间的时候,这两个容器不存在网络隔离, 可以直接互通。 - None 模式
None 模式,Docker容器拥有自己的Network Namespace,但是没有网络配置信息(网卡、IP、路由信息) 需要用户自行配置网络信息 - Bridge 模式
Bridge 模式,这个是Dokcer默认模式,容器之间有独立的网络环境,通过docker0网桥相互通信。
跨主机Docker网络通信
-
Host 模式
容器之间是有宿主机网络,天生支持跨主机通信,但是场景有限,容易造成端口冲突,也无法做到网络隔离,引起整个宿主机网络奔溃 -
端口绑定
通过绑定容器端口和宿主机端口,跨主机通信使用“主机IP + 端口”的方式访问容器服务。
这种方式只能支持4层以上的应用,并且容器与宿主机紧耦合,很难灵活处理问题 -
定义容器网络
使用Open vSwitch 或 Flannel等等第三方SDN工具,为容器构建可以跨主机通信的网络环境。
这类方案一般要求各主机上的Docker0网桥的cidr不同。可以避免出现IP冲突的问题。只是需要比较复杂的配置。 -
Flannel 网络方案
-
它为每个Node上的Docker容器分配互不冲突的IP地址,
-
它能为这些IP地址之间建立一个叠加网络,通过叠加网络将数据包传递到目标容器内。 数据流入: data---->eth0---->flannel0---->docker0 数据流出:eth0<----flannel0<----docker0<----data
-
Calico 网络方案
Calico把每个操作系统的协议栈当做一个路由器,然后认为所有的容器是连在这个路由器上的网络终端,在路由器之间运行的标准路由协议———BGP
每个节点两个主要程序,一个是Felix,它会监听etcd,并从etcd获取事件,如节点新增容器或者增加IP地址等。
-
Felix,既Calico代理,跑在k8s的Node节点上,主要分配配置路由及ACL等信息来确保Endpoint的连通状态。
-
etcd,分布式键值存储,主要负责网络元数据一致,确保Calico网络状态的准确性,可以与k8s共用。
-
BGP client (BIRD),主要负责把Felix写入Kernel的路由信息分发到当前Calico网络,确保workload间通信的有效性。
-
BGP Route Reflector, 大规模部署时使用,摈弃所有节点互联的Mesh模式,通过一个或多个BGP Route Reflector来完成集中式路由分发