zoukankan      html  css  js  c++  java
  • 【Linux】【Services】【SaaS】Docker+kubernetes(8. 安装和配置Kubernetes)

    1. 概念

    1.1. 比较主流的任务编排系统有mesos+marathon,swarm,openshift(红帽内部叫atom服务器)和最著名的kubernetes,居然说yarn也行,不过没见过谁用

    1.2. 官方网站 https://kubernetes.io/(需要科学上网)

    1.3. 软件架构图

    1.4. 每个组件的作用:https://kubernetes.io/docs/concepts/overview/components/

    Master Components:主节点组件提供集群的控制功能。他从整体的角度去决定集群应该怎么运行(例如计划任务),并且探测和回应集群的要求(当一个复制节点的“复制请求”失败的时候,他会去启动一个新的pod)
    主节点组建可以运行在集群中的任意一台机器。但是,简单来说,创建脚本只能在一台机器上启动所有的主要组件,但是不能在这台机器上启动用户容器。

      kube-apiserver:运行在主节点上,用来暴露Kubernetes接口的组建。他在Kubernetes控制面板的前端。他被用来设计成水平扩展,这就是说,他可以扩展成更多的实例。

      etcd:一致性和高可用键值存储,用来作为kubernetes集群的后端存储,为你的kubernetes集群准备一个备份计划,用来备份etcd的数据。

      kube-scheduler:主节点上的组件,用来观察新创建的,还没有被分配节点的pods,为他们选择一个节点并运行他们。

      这需要考虑到个人计划和整体资源的需求,硬件/软件/策略约束,松耦合和解耦,数据本地化,内部负载均衡和结束时间等因素


      kube-controller-manager:在主节点上用来运行控制器的。逻辑上来说,每个控制器都是一个独立的进程,但是为了减少复杂性,他们都被编译进了一个二进制文件并且以独立的进程来运行。

        Node Controller: 用来通知和响应哪个节点挂掉了
        Replication Controller: 为每个副本控制对象服务,负责维护正确的pods数量
        Endpoints Controller: 寄宿在终端对象,例如加入service以及pods
        Service Account & Token Controllers: 为新的用户空间创建默认用户和接口访问令牌

      cloud-controller-manager:云控制器作用在云服务的底层。云控制器在kubernetes1.6中是一个测试版本。云控制器只能跑在特定云服务控制器循环上。
      我们可以在 kube-controller-manager.禁止这些控制的循环。我们可以通过在启动 kube-controller-manager设置--cloud-provider选项来关闭它
      云控制器允许云供应商二次开发,并且kubernetes核心可以发展成为彼此独立的版本。
      在早期的版本,kubernetes核心代码是依赖于cloud-provider-specific的,在未来的版本,特定的为云供应商提供的服务的代码应该都有云供应商自己服务,并且在运行kubernetes的时候连接到cloud-controller-manager

      以下的控制器有独立的云提供者
        Node Controller: 查询云服务提供者,决定一个节点是否停止响应之后是否还能够被检测到
        Route Controller: 在云架构的底层建立起路由
        Service Controller: 建立,升级和删除云服务提供者的负载均衡
        Volume Controller: 创建,附加和挂载卷组,并且和云服务提供者交互去编排卷组

    Node Components:节点组建需要在每个节点上运行,维护工作中的pod并且提供Kubernetes的运行环境

      kubelet:在集群上的每个节点都要运行。他能保证每个pod上都有一个container运行,kubelet接管各种机器提供的PodSpecs并且确保这些在PodSpecs中注册的容器健康运行。kubelet不负责那些不是Kubernetes创建的容器

      kube-proxy:kube-proxy保证宿主机Kubernetes服务被网络规则抽象管理并且实行连接转发

      Container Runtime:运行时容器是负责运行中的容器。kubernetes支持多种运行时容器:Docker,rkt(CoreOS),runc和任何符合OCI(Open Container Initiative)运行时标准的容器

    Addons:其他插件是实现集群功能的pods和services。pods可能被部署,副本管理器等组件管理。名称空间插件在kube-system名称空间被创建

      DNS:其他的插件都不是严格需要的,但是所有kubenetes集群都必须拥有一个集群的DNS,因为集群非常依赖他
      集群DNS是一个dns服务器,作为您其他DNS服务器中的附加服务器,为kubernetes服务器提供DNS记录
      containers是由kubenetes搜索DNS之后自动启动的,包括这个DNS服务

      Web UI (Dashboard):Dashboard是一个统一管理,为了kubernets集群而准备的网络界面,他运行用户对集群的应用管理和排错,就好像在操作集群一样

      Container Resource Monitoring:容器资源监控继续在中心数据库记录创建容器的时间序列,并且提供UI以供浏览这些数据

      Cluster-level Logging:集群级别的日志机制是负责保存容器日志的,他可以集中存储日志,并提供搜索和浏览的接口

    1.5.  Policy Layer: API Server:

    API server是一个策略组件,提供对Etcd的过滤访问。它的作用本质上是相对通用的,目前正在被分解处理。因此,API Server也可以用于其他系统的控制平面。

    API server的主要货物是资源,通过暴露简单的REST API 向外提供服务。这些资源有一个标准结构可以实现一些扩展功能。无论如何,API Server,允许各类组件创建,读取,写入,更新,和监视资源。
    API  Server的具体的功能:
      •认证和授权。Kubernetes有一个可插拔的认证系统。有一些内置的用户认证机制和授权这些用户访问资源。此外,还有一些方法可用于向外部服务提供这些服务。这种可扩展性是Kubernetes构建的核心功能。
      •API Server运行一组可以拒绝或修改请求的准入控制器。 这些允许策略被应用并设置默认值。 这是确保在API Server客户端仍在等待请求确认时进入系统的数据有效性的关键。 虽然这些准入控制器目前正在编译到API Server中,但目前正在进行的工作是使其成为另一种可扩展性机制。
      •API Server 有助于API 版本控制。API 版本的一个关键问题是允许资源的字段的改变,字段添加,弃用,重新组织和以其他方式转换。 API Server在Etcd中存储资源的"true"表示,并根据满足的API版本转换/呈现该资源。 自项目早期开始,规划版本控制和API的发展一直是Kubernetes的一项重要工作。
      •API Server 一个重要特性是支持watch机制。这意味着API Server的客户端可以使用与Etcd相同的协调模式。Kubernetes中的大多数协调包括写入另一个组件正在监视的API服务器资源的组件。 第二个组件将对几乎立即发生的变化做出反应。

    1.6. 业务逻辑:Controller Manager and Scheduler

    这些是通过API Server 进行协调的组件。这些称为Controller Manager和Scheduler的组件绑定到单独的服务器Master上
    Scheduler组件将做许多事情让系统工作:
      1.查找未分配给节点的Pod(未绑定的Pod);
      2.检查集群的状态(缓存在内存中);
      3.选择具有空闲空间并满足其他约束条件的节点;
      4.将pod绑定到该节点。
    Controller Manager 组件,实现ReplicaSet的行为。(ReplicaSet可以确保任何时候都可以运行一个Pod模板的副本数量)。控制器将根据资源中的选择器 监控ReplicaSet 资源和一组Pod。为了保持在ReplicaSet中稳定的一组Pod,控制器将创建、销毁Pod。

    1.7. 一次请求:

    这个时序图展示了创建pod的流程,基本的流程如下:
      1. 用户提交创建Pod的请求,可以通过API Server的REST API ,也可用Kubectl命令行工具,支持Json和Yaml两种格式;
      2. API Server 处理用户请求,存储Pod数据到Etcd;
      3. Schedule通过和 API Server的watch机制,查看到新的pod,尝试为Pod绑定Node;
      4. 过滤主机:调度器用一组规则过滤掉不符合要求的主机,比如Pod指定了所需要的资源,那么就要过滤掉资源不够的主机;
      5. 主机打分:对第一步筛选出的符合要求的主机进行打分,在主机打分阶段,调度器会考虑一些整体优化策略,比如把一个Replication Controller的副本分布到不同的主机上,使用最低负载的主机等;
      6. 选择主机:选择打分最高的主机,进行binding操作,结果存储到Etcd中;

      7.      kubelet根据调度结果执行Pod创建操作: 绑定成功后,会启动container, docker run, scheduler会调用API Server的API在etcd中创建一个bound pod对象,描述在一个工作节点上绑定运行的所有pod信息。运行在每个工作节点上的kubelet也会定期与etcd同步bound pod信息,一旦发现应该在该工作节点上运行的bound pod对象没有更新,则调用Docker API创建并启动pod内的容器。

    2. 环境

    2.1. Kubernetes:1.5.2

    3. 安装与配置:参考文章:http://www.cnblogs.com/breezey/p/6545307.html

    3.1. 在所有节点上都安装docker

    yum install docker

    3.2. 配置docker信任我们前面做的仓库,修改/usr/lib/systemd/system/docker.service

    [Unit]
    Description=Docker Application Container Engine
    Documentation=http://docs.docker.com
    After=network.target
    Wants=docker-storage-setup.service
    Requires=rhel-push-plugin.socket registries.service
    Requires=docker-cleanup.timer
    
    [Service]
    Type=notify
    NotifyAccess=all
    EnvironmentFile=-/run/containers/registries.conf
    EnvironmentFile=-/etc/sysconfig/docker
    EnvironmentFile=-/etc/sysconfig/docker-storage
    EnvironmentFile=-/etc/sysconfig/docker-network
    Environment=GOTRACEBACK=crash
    Environment=DOCKER_HTTP_HOST_COMPAT=1
    Environment=PATH=/usr/libexec/docker:/usr/bin:/usr/sbin
    ExecStart=/usr/bin/dockerd-current 
              --insecure-registry hctjosadm01.hccos.cn:5000
              --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current 
              --default-runtime=docker-runc 
              --authorization-plugin=rhel-push-plugin 
              --exec-opt native.cgroupdriver=systemd 
              --userland-proxy-path=/usr/libexec/docker/docker-proxy-current 
              $OPTIONS 
              $DOCKER_STORAGE_OPTIONS 
              $DOCKER_NETWORK_OPTIONS 
              $ADD_REGISTRY 
              $BLOCK_REGISTRY 
              $INSECURE_REGISTRY
          $REGISTRIES
    ExecReload=/bin/kill -s HUP $MAINPID
    LimitNOFILE=1048576
    LimitNPROC=1048576
    LimitCORE=infinity
    TimeoutStartSec=0
    Restart=on-abnormal
    MountFlags=slave
    KillMode=process
    
    [Install]
    WantedBy=multi-user.target

    3.3. 设置服务随机启动

    systemctl daemon-reload && systemctl enable docker && systemctl start docker

    3.4. 在master节点上安装kuber master

    yum install -y kubernetes-master kubernetes-client

    3.5. 在master节点上修改配置文件 /etc/kubernetes/config

    ###
    # kubernetes system config
    #
    # The following values are used to configure various aspects of all
    # kubernetes services, including
    #
    #   kube-apiserver.service
    #   kube-controller-manager.service
    #   kube-scheduler.service
    #   kubelet.service
    #   kube-proxy.service
    # logging to stderr means we get it in the systemd journal
    KUBE_LOGTOSTDERR="--logtostderr=true"
    
    # journal message level, 0 is debug
    KUBE_LOG_LEVEL="--v=0"
    
    # Should this cluster be allowed to run privileged docker containers
    KUBE_ALLOW_PRIV="--allow-privileged=false"
    
    # How the controller-manager, scheduler, and proxy find the apiserver
    KUBE_MASTER="--master=http://172.16.0.90:8080"

    3.6. 记得创建一个key文件,要不在创建pod的时候会报错

    openssl genrsa -out /etc/kubernetes/serviceaccount.key 2048

    3.7. 在master节点上修改配置文件 /etc/kubernetes/apiserver

    ###
    # kubernetes system config
    #
    # The following values are used to configure the kube-apiserver
    #
    
    # The address on the local server to listen to.
    #KUBE_API_ADDRESS="--insecure-bind-address=127.0.0.1"
    KUBE_API_ADDRESS="--address=0.0.0.0"
    
    # The port on the local server to listen on.
    # KUBE_API_PORT="--port=8080"
    KUBE_API_PORT="--port=8080 --secure-port=443"
    KUBE_MASTER="--master=http://172.16.0.90:8080"
    
    # Port minions listen on
    # KUBELET_PORT="--kubelet-port=10250"
    KUBELET_PORT="--kubelet-port=10250"
    
    # Comma separated list of nodes in the etcd cluster
    #KUBE_ETCD_SERVERS="--etcd-servers=http://127.0.0.1:2379"
    KUBE_ETCD_SERVERS="--etcd-servers=http://172.16.0.83:2379,http://172.16.0.84:2379,http://172.16.0.85:2379"
    
    # Address range to use for services
    KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"
    
    # default admission control policies
    KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"
    
    # Add your own!
    #KUBE_API_ARGS="--service_account_key_file=/etc/kubernetes/serviceaccount.key"

    3.8. 修改/etc/kubernetes/controller-manager

    ###
    # The following values are used to configure the kubernetes controller-manager
    
    # defaults from config and apiserver should be adequate
    
    # Add your own!
    KUBE_CONTROLLER_MANAGER_ARGS="--service_account_private_key_file=/etc/kubernetes/serviceaccount.key"

    3.9. 启动master上的服务

    systemctl start kube-apiserver kube-controller-manager kube-scheduler
    systemctl enable kube-apiserver kube-controller-manager kube-scheduler

    3.10. 在所有node节点上安装服务

    yum install -y kubernetes-node

    3.11. 修改node上的配置文件 /etc/kubernetes/config

    ###
    # kubernetes system config
    #
    # The following values are used to configure various aspects of all
    # kubernetes services, including
    #
    #   kube-apiserver.service
    #   kube-controller-manager.service
    #   kube-scheduler.service
    #   kubelet.service
    #   kube-proxy.service
    # logging to stderr means we get it in the systemd journal
    KUBE_LOGTOSTDERR="--logtostderr=true"
    
    # journal message level, 0 is debug
    KUBE_LOG_LEVEL="--v=0"
    
    # Should this cluster be allowed to run privileged docker containers
    KUBE_ALLOW_PRIV="--allow-privileged=false"
    
    # How the controller-manager, scheduler, and proxy find the apiserver
    KUBE_MASTER="--master=http://172.16.0.90:8080"

    3.12. 修改node节点上的配置文件/etc/kubernetes/kubelet

    ###
    # kubernetes kubelet (minion) config
    
    # The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
    #KUBELET_ADDRESS="--address=127.0.0.1"
    KUBELET_ADDRESS="--address=0.0.0.0"
    
    # The port for the info server to serve on
    # KUBELET_PORT="--port=10250"
    
    # You may leave this blank to use the actual hostname
    KUBELET_HOSTNAME="--hostname-override=hctjosk8snode01"
    
    # location of the api-server
    KUBELET_API_SERVER="--api-servers=http://172.16.0.90:8080"
    
    # pod infrastructure container
    KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"
    
    # Add your own!
    KUBELET_ARGS=""

    3.13. 启动node节点上的服务

    systemctl start kubelet kube-proxy
    systemctl enable kubelet kube-proxy

    3.14. 在主节点上查看集群状态

    ~]# kubectl get nodes
    NAME              STATUS    AGE
    hctjosk8snode01   Ready     1h
    hctjosk8snode02   Ready     18s
    hctjosk8snode03   Ready     15s
    hctjosk8snode04   Ready     11s

     3.15. 在所有node节点上吧flannel安装上

    yum install flannel

    3.16. 在etcd服务器上(10.30.2.83/84/85任意一台即可),增加一条记录

    etcdctl set /hccos.cn/network/config '{"network": "172.17.0.0/16"}'

    3.17. 修改flannel配置文件 /etc/sysconfig/flanneld

    # Flanneld configuration options  
    
    # etcd url location.  Point this to the server where etcd runs
    FLANNEL_ETCD_ENDPOINTS="http://172.16.0.83:2379,http://172.16.0.84:2379,http://172.16.0.85:2379"
    
    # etcd config key.  This is the configuration key that flannel queries
    # For address range assignment
    FLANNEL_ETCD_PREFIX="/hccos.cn/network"
    
    # Any additional options that you want to pass
    #FLANNEL_OPTIONS=""

    3.18. 启动服务

    systemctl start flanneld
    systemctl enable flanneld

    3.19. 由于docker依赖于flanneld,需要重启docker服务

    systemctl restart docker

    4. YAML文件示例

    #test-pod
    apiVersion: v1 #指定api版本,此值必须在kubectl apiversion中  
    kind: Pod #指定创建资源的角色/类型  
    metadata: #资源的元数据/属性  
      name: test-pod #资源的名字,在同一个namespace中必须唯一  
      labels: #设定资源的标签
        k8s-app: apache  
        version: v1  
        kubernetes.io/cluster-service: "true"  
      annotations:            #自定义注解列表  
        - name: String        #自定义注解名字  
    spec: #specification of the resource content 指定该资源的内容  
      restartPolicy: Always #表明该容器一直运行,默认k8s的策略,在此容器退出后,会立即创建一个相同的容器  
      nodeSelector:     #节点选择,先给主机打标签kubectl label nodes kube-node1 zone=node1  
        zone: node1  
      containers:  
      - name: test-pod #容器的名字  
        image: 10.192.21.18:5000/test/chat:latest #容器使用的镜像地址  
        imagePullPolicy: Never #三个选择Always、Never、IfNotPresent,每次启动时检查和更新(从registery)images的策略,
                               # Always,每次都检查
                               # Never,每次都不检查(不管本地是否有)
                               # IfNotPresent,如果本地有就不检查,如果没有就拉取
        command: ['sh'] #启动容器的运行命令,将覆盖容器中的Entrypoint,对应Dockefile中的ENTRYPOINT  
        args: ["$(str)"] #启动容器的命令参数,对应Dockerfile中CMD参数  
        env: #指定容器中的环境变量  
        - name: str #变量的名字  
          value: "/etc/run.sh" #变量的值  
        resources: #资源管理
          requests: #容器运行时,最低资源需求,也就是说最少需要多少资源容器才能正常运行  
            cpu: 0.1 #CPU资源(核数),两种方式,浮点数或者是整数+m,0.1=100m,最少值为0.001核(1m)
            memory: 32Mi #内存使用量  
          limits: #资源限制  
            cpu: 0.5  
            memory: 1000Mi  
        ports:  
        - containerPort: 80 #容器开发对外的端口
          name: httpd  #名称
          protocol: TCP  
        livenessProbe: #pod内容器健康检查的设置
          httpGet: #通过httpget检查健康,返回200-399之间,则认为容器正常  
            path: / #URI地址  
            port: 80  
            #host: 127.0.0.1 #主机地址  
            scheme: HTTP  
          initialDelaySeconds: 180 #表明第一次检测在容器启动后多长时间后开始  
          timeoutSeconds: 5 #检测的超时时间  
          periodSeconds: 15  #检查间隔时间  
          #也可以用这种方法  
          #exec: 执行命令的方法进行监测,如果其退出码不为0,则认为容器正常  
          #  command:  
          #    - cat  
          #    - /tmp/health  
          #也可以用这种方法  
          #tcpSocket: //通过tcpSocket检查健康   
          #  port: number   
        lifecycle: #生命周期管理  
          postStart: #容器运行之前运行的任务  
            exec:  
              command:  
                - 'sh'  
                - 'yum upgrade -y'  
          preStop:#容器关闭之前运行的任务  
            exec:  
              command: ['service httpd stop']  
        volumeMounts:  #挂载持久存储卷
        - name: volume #挂载设备的名字,与volumes[*].name 需要对应    
          mountPath: /data #挂载到容器的某个路径下  
          readOnly: True  
      volumes: #定义一组挂载设备  
      - name: volume #定义一个挂载设备的名字  
        #meptyDir: {}  
        hostPath:  
          path: /opt #挂载设备类型为hostPath,路径为宿主机下的/opt,这里设备类型支持很多种
        #nfs
  • 相关阅读:
    sql注入之payload
    cve2019-0708漏洞复现
    xss学习
    kernel panic not syncing
    nodeJS爬虫
    JS刷题自制参考知识
    HTML Cookie
    点击按钮触发div颜色改变的几种写法
    Bootstrap4布局(简要)
    jQuery实现论坛发帖Demo
  • 原文地址:https://www.cnblogs.com/demonzk/p/8301087.html
Copyright © 2011-2022 走看看