美文网首页
DevOps:容器篇

DevOps:容器篇

作者: 程序员王旺 | 来源:发表于2021-08-15 11:05 被阅读0次

    1. docker

    Docker 是一个应用容器引擎,说简单点就是将你的应用里三层外三层打包成一个镜像,然后用一条命令将镜像跑起来,本质上它就是一个进程而已,只不过使用了一些隔离技术(cgroups 、namespace、rootfs、setns)让其“隐藏”起来,从而感觉上它是一个容器,而且是一个独立的系统。docker和虚拟机有着本质的区别,虚拟机会占用更多的物理资源,虚拟机比较笨重,重建或释放都比较费时。例如有个1000平的大房子,如果隔成10个甚至20个小房间都没问题,而且可以随时拆掉再隔;但如果在里面盖房子的话,可能盖5间就不错了。


    image.png

    用以下命令揭示“容器”的真实身份

    # 查看 a776ea6f142d2819 容器的进程号
    [root@node1 ~]# docker inspect --format '{{ .State.Pid }}'  a776ea6f142d
    2819
    # 发现容器在宿主机中进程
    [root@node1 ~]# ps -aux |grep 2819
    root     22819  0.0  0.0 109096  6604 ?        Sl   Apr28   3:40 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/a2b9a823d8451eaa32c92330599e7167dc69b46930746b536ec018ca91e30914 -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup
    
    

    2. kubernetes

    Kubernetes是Google开源的一个容器编排引擎,随着docker的流行,当运行数百、数千个容器时,人们就不得不考虑一个问题,如何让容器更高效的运行、以及如何在分布式环境下运行容器等。这是k8s就横空出世了,它简化了大规模部署的容器管理问题,而在k8s流行之前,docker公司就有三剑客的另外两个产品:docker-compose、swarm。swarm是docker公司主推的容器编排工具,也是和k8s一决高下的产品,但最终用户用脚投票,k8s以完胜收场,这里不得不提的一个大牛就是Tower(高塔),作为k8s的布道师功不可没。

    一、架构

    image.png

    (1) kubectl

    集群的客户端命令行工具,请求apiserver的rest接口,查看和维护集群,kubectl需要一个配置文件: kubeconfig,此文件包含用户、集群上下文、命名空间、认证机制信息等,kubectl可以同时管理多个集群,在请求apiserver需要认证信息。kubectl可以同时管理多个集群

    (2) kube-apiserver

    API Server提供了资源对象的唯一操作入口,其他所有组件都必须通过它提供的API来操作资源数据,只有API Server与存储通信,其他模块通过API Server访问集群状态。以RESTFul接口方式提供给外部客户和内部组件进行同一调用。

    (3) kube-controller-manager

    实现集群故障检测和恢复的自动化工作,负责执行各种控制器,主要有:

    • endpoint-controller:定期刷新service和pod(关联信息由endpoint对象维护)的关联关系,保证service到pod的映射总是最新的。

    • replication-controller:定期检查replicationController(新版叫ReplicaSet)中配置的pod数量和实际运行数量是否一致,如果不一致会自动启动或停止pod。

    (4) kube-scheduler

    Scheduler收集和分析当前Kubernetes集群中所有Work节点的资源(内存、CPU)负载情况,然后分发Pod到集群中可用的节点上,并实时监测集群中未分发和已分发的所有运行的Pod,将已分发的pod信息写回到API Server。为了避免频繁查询,Scheduler会缓存一份最新的信息在本地。

    (5) etcd

    和Zookeeper类似,负责存储各个组件的共享数据,保证集群高可用。

    (6) kube-proxy

    负责接收并转发请求。Kube-proxy的核心功能是将到达Service的访问请求转发到后台的某个具体的Pod。无论是通过ClusterIP+Port的方式还是NodeIP+NodePort的方式访问Service,最终都会被节点的Iptables规则(新版本是通过LVS转发)重定向到Kube-proxy监听服务代理端口,该代理端口实际上就是SocketServer在本地随机打开的一个端口,SocketServer是Kube-proxy为每一个服务都会创建的“服务代理对象”的一部分。当Kube-proxy监听到Service的访问请求后,它会找到最适合的Endpoints,然后将请求转发过去。具体的路由选择依据Round Robin算法及Service的Session会话保持这两个特性。

    (7) kubelet

    运行在每个work节点上,作为agent,负责分配该Node上的Pods任务、启动Pod、管理容器、周期性获取容器状态等,反馈给kube-apiserver。注意:kubelet 与 kube-apiserver 之间的通信是双向的, kubelet 既需要访问 kube-apiserver 获取分配到自己节点上的 pod 信息, kube-apiserver 也需要主动访问 kubelet 拉取日志, 状态, 监控数据等信息, 所以对两个组件来说, 认证是双向的, kube-apiserver 需要持有 kubelet 的客户端证书, 以完成 kubelet 对自己身份的校验; kubelet 也需要持有 kube-apiserver 的客户端证书, 完成 kube-apiserver 对自己身份的认证。
    通过kubeadm安装时,Kubelet是唯一一个运行在宿主机上的服务,因为它负责启动容器,如果它也运行在容器中,那就成了它在容器中启动其他容器啦,这样会有很多不方便。

    (8) kube-DNS

    一个可选的DNS服务,用于为每个Service对象创建DNS记录,这样所有的Pod就可以通过DNS访问服务了。

    (9) CRI

    CRI是k8s对容器操作的统一抽象,在1.20版本之前,k8s直接调用docker的API,所以搞了一个 dockershim的适配器来完成,之前比较热的话题k8s要废弃docker,其实是废弃这个东西。目前k8s最新版对容器操作直接对接OCI(容器统一的开发标准)来完成,这样的好处不言而喻,不管什么容器厂家,只要实现了OCI标准,就能和k8s无缝对接,详细请看我的文章《docker的陨落》

    二、安装

    使用kubeadm安装k8s非常简单,但经常失败,大致失败的原因有几点:

    • 镜像下载不下来,使用阿里云镜像,但版本比较老
    • 虚拟机,云主机等多网卡环境,需指定advertiseAddress,calico插件需要指定通信的网卡
    • pod网段和service网段和系统网段冲突
    • 浮动IP问题
    • OpenStack环境下容器跨节点无法通行问题,可尝试关闭port-security来解决
    1. 编写kubeadm配置文件: kubeadm-config.yaml
    apiVersion: kubeadm.k8s.io/v1beta2
    kind: InitConfiguration
    # kubeadm 使用 eth0 的默认网络接口(通常是内网IP,在virtualbox一般是10.0.2.15)做为 Master节点的advertise address
    # 如果是通过虚拟机安装k8s,那么必须设置advertiseAddress地址,否则导致其他节点无法正常和master通信
    localAPIEndpoint:
      # 不能绑定浮动IP
      advertiseAddress: 10.0.2.24
      bindPort: 6443
      
    ---
    # 开启Kube-proxy代理规则为ipvs,默认是Iptables
    apiVersion: kubeproxy.config.k8s.io/v1alpha1
    kind: KubeProxyConfiguration
    mode: "ipvs"
    
    ---
    apiVersion: "kubeadm.k8s.io/v1beta2"
    kind: ClusterConfiguration
    kubernetesVersion: v1.17.4
    controlPlaneEndpoint: "apiserver:6443"
    apiServer:
      extraArgs:
        service-node-port-range: 1000-40000
      certSANs:
      - 10.0.2.24
      - 127.0.0.1
    networking:
      # podSubnet相当于--pod-network-cidr 参数
      podSubnet: 192.244.0.0/16
      # serviceSubnet相当于--service-network-cidr 参数
      serviceSubnet: 10.96.0.0/16
    
    1. 执行kubeadm初始化操作
    #  加上此参数:--upload-certs ,其他节点加入时可以自动获取证书
    $ kubeadm init --config=kubeadm-config.yaml --upload-certs
    
    1. 安装客户端,执行节点加入操作等
    2. 安装网络插件,推荐安装 calico 插件。

    3. 应用部署

    k8s内置了多种资源类型,如pod是k8s中最小的单元, ReplicaSet管理pod的多个副本,Deployment 是无状态应用。

    下面是部署一个nginx到k8s集群,并设置有pod有3个副本

    apiVersion: apps/v1
    kind: Deployment
    
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    
    spec:
      replicas: 3
    apiVersion: apps/v1
    kind: Deployment
    
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: registry.cn-hangzhou.aliyuncs.com/moobox/nginx
            ports:
            - containerPort: 80---
    #service
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
    spec:
      ports:
    
      - port: 80
        protocol: TCP
        targetPort: 80
          selector:
        app: nginx
          type: ClusterIP
    
    $ kubectl apply -f nginx.yaml
    
    $ kubectl get pods
    NAME                                READY   STATUS    RESTARTS   AGE
    nginx-deployment-6c84b7494d-gj5qk   1/1     Running   0          4m11s
    nginx-deployment-6c84b7494d-j8fhz   1/1     Running   0          4m11s
    nginx-deployment-6c84b7494d-xbvdf   1/1     Running   0          4m11s
    

    4. 高级

    一、监控

    使用prometheus + Grafana监控k8s集群,支持operator的话,可下载kube-prometheus v0.5.0 版(最新版有一个镜像拉取不了)进行安装。安装完如果没有监控数据,可能是:

    问题1: 时间不同步,时区不对,设置为本地时区和当前时间,查看
    prometheus主页发现有警告,可通过timedatectl和date 命令修改

    问题2:Grafana 的prometheus数据源,默认配置的是k8s内部域名地址,所以外部无法访问,数据源需要修改为外部的地址: http://192.168.x.x:39090/

    二、蓝绿部署

    k8s默认就支持滚动升级,蓝绿部署也是支持的,加入有个服务之前的版本是V1,新部署了一个版本是V2,那我们就可以通过两个service来实现一个简单的蓝绿部署

    #service
    apiVersion: v1
    kind: Service
    metadata:
      name: web-bluegreen-v1
      namespace: dev
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 8080
      # 通过选择不同版本的webapp,来切换流量  
      selector:
        app: webapp
        version: v1.0 #version: v2.0
      type: ClusterIP
    
    #service
    apiVersion: v1
    kind: Service
    metadata:
      name: web-bluegreen-v2
      namespace: dev
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 8080
      # 通过选择不同版本的webapp,来切换流量  
      selector:
        app: webapp
        version:  v2.0
      type: ClusterIP
    

    k8s默认是不支持灰度发布的,想要实现灰度发布,可使用其他组件,如istio

    三、自动扩容

    HPA(Horizontal Pod Autoscaler)是k8s的一个资源对象,利用prometheus获取该资源对象的监控指标,可实现Pod自动伸缩。但有几点必须要注意:

    • pod一定要设置资源限制request、limit等,才能开启HPA
    • HPA控制器的时间窗口默认是15秒,即每隔15s拉取一次监控指标,可通过–horizontal-pod-autoscaler-sync-period参数设定
      kubernetes集群需要配置好metrics server
    • 目前是v1版本,从k8s v1.18 支持 v2beta2版本,可支持基于内存的伸缩指标,可自定义伸缩指标

    基于内存/CPU的自动伸缩
    下面我们对一个xxx应用进行自动伸缩,当CPU使用超过60%时,会自动增加pod,但不会超过6个

    $ kubectl autoscale deployment xxx --cpu-percent=60 --min=2 --max=6
    

    QPS的自动伸缩
    下面创建一个HPA来实现 一个QPS的 自动伸缩:

    apiVersion: autoscaling/v2beta2 
    kind: HorizontalPodAutoscaler
    metadata: 
      name: blog-web
    spec: 
      scaleTargetRef: 
        apiVersion: apps/v1 
        kind: Deployment 
        name: blog-web
      minReplicas: 2
      maxReplicas: 8 
      metrics:
      - type: Pods
        pods:
          metric:
            name: http_requests_received
          target:
            type: AverageValue
            averageValue: 10
    

    相关文章

      网友评论

          本文标题:DevOps:容器篇

          本文链接:https://www.haomeiwen.com/subject/ukrveltx.html