Kubernetes 核心概念 POD及网络

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

  1. 创建 kubectl create -f createpod.yml
  2. 查询 1.kubectl get pod pod名称 2.kubectl describe pod pod名称
  3. 删除 kubectl delete pod pod名称
  4. 更新 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策略

Pod生命周期

  1. Pending :POD已经创建,但是有一个或者多个容器还未创建,包括POD调度阶段,已经容器镜像的下载过程
  2. Running :POD已经调度到Node,所有容器已经创建,并且至少有一个正在运行,或者重启
  3. Succeeded : POD中所有容器正常退出
  4. Failed : POD至少有一个容器异常退出

容器状态

  1. Waiting 容器正在等待创建
  2. Running 容器已经创建,正在运行
  3. Terminate 容器终止退出

Pod容器间通信

每个Pod之间都拥有一个独立的IP地址,而且假定所有Pod都在一个可以直接连通的、扁平的网络空间之中。
Pod 中所有容器共享网络空间可以直接通过localhost:port访问
Pod之间通信

同一Node中的Pod通信

同一Node中的Pod通信默认路由都是Docker0的地址,由于他们连着一个Docker0网桥,地址段相同,直接可以通信。
Node

不同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会添加一个路由。
Node之间通信
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的访问
kube-proxy

单主机 Docker网络通信

  1. Host模式
    Host模式 启用Host模式,那么该容器将不会获得一个独立的Network Namespace 而是宿主机共享一个Network Namespace 因此容器将不会虚拟自己的网卡,配置自己的IP等。
    容器没有隔离、独立的网络栈、容器与宿主机公有网络栈而争抢网络资源,并且容器奔溃也可能导致主机崩溃。容器不再拥有所有的端口资源,因为一些端口已经被宿主机占用。
  2. Container 模式
    Container 模式,Container 是一种特殊的网络模式,该模式下的使用相同网络命名空间的时候,这两个容器不存在网络隔离, 可以直接互通。
  3. None 模式
    None 模式,Docker容器拥有自己的Network Namespace,但是没有网络配置信息(网卡、IP、路由信息) 需要用户自行配置网络信息
  4. Bridge 模式
    Bridge 模式,这个是Dokcer默认模式,容器之间有独立的网络环境,通过docker0网桥相互通信。

跨主机Docker网络通信

  1. Host 模式
    容器之间是有宿主机网络,天生支持跨主机通信,但是场景有限,容易造成端口冲突,也无法做到网络隔离,引起整个宿主机网络奔溃

  2. 端口绑定
    通过绑定容器端口和宿主机端口,跨主机通信使用“主机IP + 端口”的方式访问容器服务。
    这种方式只能支持4层以上的应用,并且容器与宿主机紧耦合,很难灵活处理问题

  3. 定义容器网络
    使用Open vSwitch 或 Flannel等等第三方SDN工具,为容器构建可以跨主机通信的网络环境。
    这类方案一般要求各主机上的Docker0网桥的cidr不同。可以避免出现IP冲突的问题。只是需要比较复杂的配置。

  4. Flannel 网络方案

  5. 它为每个Node上的Docker容器分配互不冲突的IP地址,

  6. 它能为这些IP地址之间建立一个叠加网络,通过叠加网络将数据包传递到目标容器内。 数据流入: data---->eth0---->flannel0---->docker0 数据流出:eth0<----flannel0<----docker0<----data
    Flanneld网络图

  7. Calico 网络方案
    Calico把每个操作系统的协议栈当做一个路由器,然后认为所有的容器是连在这个路由器上的网络终端,在路由器之间运行的标准路由协议———BGP
    每个节点两个主要程序,一个是Felix,它会监听etcd,并从etcd获取事件,如节点新增容器或者增加IP地址等。
    Calico网络模型

  8. Felix,既Calico代理,跑在k8s的Node节点上,主要分配配置路由及ACL等信息来确保Endpoint的连通状态。

  9. etcd,分布式键值存储,主要负责网络元数据一致,确保Calico网络状态的准确性,可以与k8s共用。

  10. BGP client (BIRD),主要负责把Felix写入Kernel的路由信息分发到当前Calico网络,确保workload间通信的有效性。

  11. BGP Route Reflector, 大规模部署时使用,摈弃所有节点互联的Mesh模式,通过一个或多个BGP Route Reflector来完成集中式路由分发
    Calico实现方案

发布了21 篇原创文章 · 获赞 2 · 访问量 2861

猜你喜欢

转载自blog.csdn.net/ysf465639310/article/details/104773927