service资源对象管理

service
- 接收用户流量的,转交给pod
- lables
- endpoint
Pod_ip + Pod_port

流量进入的方式

  1. 默认线 - clusterIP
  2. serviceIp + servicePort
  3. |
  4. lables selector
  5. |
  6. endpointPod_ip + Pod_port
  7. |
  8. container_Port
  9. 另外一条线 - NodePort
  10. hostIp + NodePort
  11. |
  12. lables selector
  13. |
  14. endpoint
  15. Pod_ip + Pod_port
  16. |
  17. container_Port

service类型

clusterIP 
    - 默认的,依赖于coredns,
    - 外部流量无法使用 
NodePort 
    - 一种特殊的ClusterIP
    - 将宿主机的port 和 service的端口一一映射
loadblancer 
    - 场景是 - 公有云平台
    - 简单的理解为 
        公司内网 
        唯一的出网的ip --> loadblancer
    - 如果没有出网ip,会处于
        pending状态
ExternalName
    - 将集群外部的服务,引入到k8s集群

service原理

外部流量如何转交给pod内部的容器的
userspace
    - 转发效率低下
    - iptables做拦截, kube-proxy做转发
iptables
    - 即做拦截,又做转发
    - k8s1.22.x, 每套service会有15-20条规则实现
ipvs
    - 拦截和转发由ipvs来做
    - 由于部分后面的资源对象依赖于iptables

注意:
    cluster_ip不是集群ip,而是service资源对象的ip地址,代理了很多pod
    service是k8s内部的serviceip,主要是内部流量的转发

service实践

1.service的基础实践
    clusterIP 仅限于k8s集群内部对象使用
    NodePort 
        是在clusterIP的基础上,将 
            servcie的端口 和 host主机的端口映射 
        不是太好的特点:
            nodePort会在所有的集群节点中,都映射一个端口

2.多端口实践
    场景     
        - tomcat 8080 8005 8009
        - nginx 80 443


3.ipvs
    前提:所有集群节点安装ipvs模块
        ipvsadm命令 
    更改
        - configmap

4.服务发现
    - coredns 
    主机名
        service名称.命名空间.svc.cluster.local.
    原则上:只能查看同命名空间的资源
    历史:
        sky-dns
        kube-dns
        coredns
    拓展:
        coredns的配置
            kube-system里面的 configmap

5.service进阶 
    会话粘滞
    无头服务    -->    特殊的service,没有ip,没有反向代理,一步到位找到后面的pod

存储对象管理和实践

存储原理

1 创建数据卷对象
    以哪种方式落地数据
        临时 - 空目录 emptyDir
        永久 - 本地   hostPath 
                   用宿主机的目录作为数据存储
                   不方便于数据的共享
                - 网络
          文件系统  nfs
          分布式系统 ceph、cinder、glusterfs等
          云环境存储 oss、S3、等
          问题:资源使用
                多路读写
                多路只读
                单路读写

2 挂载数据卷对象到pod内部的容器里

存储创建

1 创建数据卷对象
  volumes:
  - name <string> 

2 挂载数据卷对象到pod内部的容器里
  containers:
  - name: …
    image: …
    volumeMounts:
    - name <string>   # 数据卷
      mountPath <string>

存储实践

emptyDir 
    临时场景 

hostPath 
    - 只允许在指定的主机中使用
        如果需要在多主机使用的话,保证目录结构和文件都一样

    注意:
        原则上来说,创建数据卷是自动的,
        但是必须有相应的权限
        问题:
            没有权限创建制定目录,但是还要创建怎么?
            -- 只能在k8s范围里找方案
        方案:
            init容器
            poststarthook
            多容器

nfs
    网络的文件系统 
    - 多主机共享文件

存储进阶pv&pvc

pv - 基于网络的一个存储对象
pvc - 方便pod应用pv的一个中间人
pv 和 pvc是自动绑定的,但是受到两个方面的约束?
    - 容量限制
    - 权限限制

扩展一:
    RC&RS  vs Pod
    Cronjob vs Job
    StorageClass VS PV

拓展二:
    分级管理
        安全 
            单pod里面的指定容器
            单pod里面的所有容器
            集群里面所有pod

简单实践:
    1 创建pv
    2 创建pvc
    3 pod关联pvc

删除流程:pod - pvc - pv 

场景需求:A应用通过nodeName属性部署在node2上,数据需要持久化        - hostPath

配置管理configmap & secret

1 iptables -> ipvs              kube-proxy
2 dns 主机指定和域名排除      coredns

定位:各种应用软件本身的配置文件在k8s里面的存储    
操作:
    命令
        kubectl create configmap 
    资源对象 
        主要是属性的描写方法:
            样式1:
                key: value 
            样式2:
                file_name: |
                  第一行
                  第二行
                  ...
    应用:如果我们需要将现有的配置文件加入到k8s里面,推荐使用第一种方式

configmap的变量实践:
    对于configmap里面的环境变量,我们可以通过valueFrom.configMapKeyRef
    应用场景1:
        灰度发布 - 分区域
            - 1 将默认的发布属性定制为false
            - 2 更改部分区域的定制的属性为true 
            -- 功能开关

configmap的文件实践: **********
    对于普遍的软件配置的定制,都是以文件的方式来承载的
        1 定制configmap 
            命令也可,资源清单文件也可
        2 定制数据卷
            关联的是 configmap名称
        3 挂载数据卷 
            容器内挂载数据卷即可
特性:configmap 只要手工更改,立刻生效并同步到pod内部
原理是:双层软连接 
            时间目录(变动的) -- ..data -- 具体文件
注意:双层软连接 或者 一层软连接,在项目发布、软件部署这些场景中,是非常常见的。

要点:对于Docker应用改造的k8s环境,如果涉及到配置同步成功,但是业务不生效        -- 看看配置有没有重载
1 创建secret对象
2 在pod里通过 volumeMount 挂载到容器里面,secret信息,在容器里面会以文件的样式存在
    注意:在pod里面挂载secret的时候,会自动解密
案例:简单的secret的generic类型,一般应用于简单的变量存储,    但是需要注意 echo -n 的加密效果

tls实践 
    1 创建secret对象    针对的是 秘钥文件 
    2 在pod里通过 volumeMount 挂载到容器里面

对于任何一种Docker应用来说,在迁移到k8s里面的时候
部署线
        deployment - rs - pod 
            代码数据持久化 
                PV + PVC
            配置数据导入
                软件配置 - Configmap
                加密证书 - secret 
网络线
        service

状态管理stateful

http协议是有状态的么?- 无状态
我们基于http协议开发出来的应用,有没有状态?    - 有状态 

状态的本质    - 用户请求的数据保存在哪里
        无状态 - 保存在客户端,便于找到目标
        有状态 - 保存在服务端,便于下次连接
redis为例:
    pod 在启动的时候,必须加载指定位置的数据
    如果数据找不到的话,pod的状态就变了,集群就不存在了

要点:有状态的应用和无状态的应用
启动时候,必须找到对应的数据     - pod必须找到匹配的 pvc

如果我们要将 有状态的 Docker应用迁移到k8s:
    1 pod必须指定名称 - 不能是随机的
    2 pod在无限更新(杀死、新增)时候,必须找到 指定的 pvc
statefulset 具备了上面的两个功能

网络管理

由于网络插件的管理影响范围太大,所以生产中,网络插件一般是初始化的时候调整,后续就不再变动了。

插件 - flannal

主机网络模型:    net、桥接、仅主机
docker容器的网络:none、container、overlay

对于一个CNI网络方案包括哪些特质?
    1 专属的网络方案    -    vxlan、ipip、gpg等
    2 网络可以接入所有的pod    -    虚拟网卡对、macvlan、ipvlan、单根iov
    3 维护路由的基本信息
        动态路由 ******
        静态路由

flannel网络模型
  ipip             双层ip封装
            需要借助于 flanneld服务来进行数据包的拆分和解封
            所有的路由跳转都是 flannel.1
  host-gw     路由表
            动态的维护
            所有的路由跳转都是 ens33
  直连路由     综合

插件 - calico

BGP - (Border Gateway Protocol - 边界网关协议),意味着,每个节点都是一个独立的网络,它属于大网络的一个边缘节点
- 节点内部的网络控制        felix - 内部的iptables
- 节点间的网络控制        路由表 -    每个节点我都维持 n-1个路由条目

(50以上) 
反射器模型 -    反射器服务,它收集所有的路由信息,然后同步到各个节点中

组件:
    节点内 - 内部网络    Felix - pod本身的网络控制 - iptables        
    节点间 - 外部网络    etcd     - 数据存储 借助于 kube-apiserver将数据存储etcd里
                                        bird     - 向外公布自身网络信息
calico部署
    默认的网络模型 ipip模型 
    默认的隧道网卡 tunl0
    特点:专属的自定义资源对象 - 网络策略控制

calico网络 - 反射器 
1 定制反射器角色
2 后端节点使用反射器
3 关闭默认的网格效果

网络策略

策略 - 流量控制 
    管控层次:
        命名空间级别 
        pod级别
        端口级别
        ip段级别

默认控制策略
    注意:podSelector: {}        这里的 {} 表示当前的命名空间的所有pod

1 默认通过 
2 默认不通过
3 针对制定的命名空间所有pod进行限制
4 针对ns内部的pod进行限制
    ip段限制 
    端口限制
5 网络策略的叠加    -    calico里面的网络策略,可以叠加
6 多个命名空间的策略管理

安全管理

认证基础

三个术语:
    认证 - 关注的是用户
    授权 - 关注的是资源权限 
    准入控制 - 关注的敏感执行命令
1.用户:
    普通用户  UserAccount  - UA
    服务用户  ServiceAccount - SA  
如何与k8s通信:token - 令牌 
                            证书 - crt、key等
注意:基本上所有的token信息都来自于证书

2.授权:授予认证通过的用户,具备操作某些资源对象的哪些权限
      默认的授权:Node
                 RBAC - Role base access controller
3.准入控制(了解)    - 为了防止用户执行某些包含隐患的命令,主要针对的是write操作
服务账号:    每一个服务账号都有一个配套的token
        -    资源对象创建的时候,会将相关的认证文件传递到容器里面

1.用户账号UA
    表现样式:
        样式1 - 服务账号 
        样式2 - CA用户            根据证书来进行认证 

2.k8s的证书使用
        -使用方式
            参数 
            变量 
            默认
        -证书里面的信息
            UA信息
            用户组信息

UA的逻辑
        1 创建证书    -    用户、用户组 
        2 创建资源角色 
        3 将资源角色和用户绑定
注意:由于这部分涉及到内容多,任何一个位置字符出现问题,整个操作就失败

基于角色的访问控制 RBCA

1.资源的权限
    资源对象 - pod、deployment、sc等
    权限 - get、put、post、patch、delete
2.资源使用的角色    -    将资源对象和权限绑定在一起
3.用户绑定角色    -     将用户和role绑定在一起

RBAC相关的资源对象
    角色
        - clusterrole
        - role
    绑定
        - clusterrole + cluserrolebinding    集群所有权限
        - role + rolebinding                             命名空间的权限
        - clusterrole + rolebinding                集群权限限制在了某个命名空间
    用户 - SA、UA

资源调度

调度框架

对于k8s来说,框架发生了一次大的变动
    版本1:预选 + 优选 + 选定 
        - 特点:耦合性强
        - 扩展功能:
            默认策略 + 扩展策略
            扩展接口
    版本2:
        1 函数拆分 + 接口使用 
        2 遵循基本的调度流程

pod调度

    1.节点
        标签调度
        污点调度
    2.pod    -    pod亲和

    3.网络拓扑 - 了解

调度术语:
- 节点 
        亲和 
        污点 
- pod 
        亲和 
            软亲和 - 看着办
            硬亲和 - 只能这么办
        反亲和


节点:
    nodeName 
    label
        硬亲和
        软亲和 
        注意:受底层节点资源限制

污点和容忍度
    污点 - 节点广而告之,不欢迎某些人
    容忍度 - 我(pod)忍受你
如果pod非要到某个节点中运行的话,必须包容节点的所有污点

插件 - ingress

场景:
    1 如果只想暴露一个端口 - 前提:集群内外通信的时候
    2 访问需要通过域名来访问

问题:
    1 如何分散流量到不同的pod        -    label
    2 如何控制域名的转发
        nginx
            location + proxy_pass
            upstream

环境搭建:
    ingress - 资源对象
    ingress-controller 

关系:ingress - service - pod 
    server_name www.example.com;
    upstream backend_host {
        server pod_ip:pod_port;
        server pod_ip:pod_port;
    }

    location /nginx {
       proxy_pass  http://backend_host/;
    }
    访问:www.example.com/nginx/xxx     --> http://backend_host/xxx

    location /flask {
       proxy_pass  http://backend_host;
    }
    访问:www.example.com/flask/xxx     --> http://backend_host/flask/xxx 

综合实践 
1.多个域名流量
    www.example1.com/
    www.example2.com/
2.单域名多url
    www.example.com/nginx
    www.example.com/flask
3.动态url
    www.example.com/#/xxx
4.https
    https://www.example.com/#/xxx
    www.xx.com/#/xxx    --> backend.com/dashoard/xxx