k8s

头像
carrot
    阅读 42 分钟
    1

    安装配置Kubernetes 最新版1.6.1

    资源

    特性

    • 分布式集群智能负载均衡、故障发现和自我修复、服务滚动升级、服务注册发现、资源自动调度
    • 服务监控、无侵入性。
    • 大部分都可以通过Kubectl工具进行增删改查。并保存在etcd库。
    • 通过对比etcd库中期望状态和实际资源状态的差异实现自动控制
    • 开发,测试,生产环境保持高度一致
    • 持续开发,持续集成以及持续部署
    • 使用etcd v3版本,因此可支持的集群规模也扩大至5,000个节点,可支持的Pod规模也增加到15万个
    • 基于角色的访问控制(RBAC)升级到Beta版
    • kubeadm的集群引导工具升级到了Beta版,亮点:所有的通信都通过TLS进行
    • 可以通过滚动升级来更新DaemonSet
    • API 响应性:99% 的 API 调用应该在一秒之内返回。
    • Pod 启动时间:99% 的 Pod 及其容器(已拉取镜像)在五秒之内完成启动。
    • 数据格式切换为 protobuf
    • v1.6 支持配置不超过2000个节点、不超过6万个pod、不超过12万个集装箱、每个节点不超过100个pod

    概念

    • Node 节点: 物理机或公有云上的主机,运行Pod
    • Master节点:集群控制节点,运行

      • kube-apiserver 提供Rest接口。所有资源的操作唯一入口
      • kube-controller-manager 所有资源的自动化控制中心
      • kube-scheduler 所有资源调度中心,调度Pod
      • etcd库 保存资源
    • Work节点:工作Node节点,运行

      • kubelet 负责Pod对应容器的创建,启动停止。向Master注册自己并定时汇报本机信息
      • kube-proxy 实现通信和负载均衡
      • Docker docker引擎
    • Pod : 运行多个容器,里面所有容器都是与一个业务紧密相关的,组合成一个微服务

      • pause 根容器:运行在Pod里,一个Pod一个,代理通信和挂载数据卷,代表Pod的所有容器的状态
      • Pod的里容器共享Pause容器的IP,共享Pause容器挂载的存储卷,相互之间文件共享
      • 每个Pod都有唯一IP。一个Pod里的容器与另外主机上的Pod容器能直接通讯
      • pod中多个容器中应用程序相互访问可以使用localhost就可以
      • Pod中根容器停止,将重启Pod即里面所有的容器。
      • Pod所在node节点宕机,将会被调度到其他Node节点中启动
      • Pod能限制容器使用的服务器资源CPU和内存

        • cpu资源,是一个绝对值,和服务器总cpu个数无关
        • 以千分之一的配额为最小单位用m表示,通常一个容器的cpu资源被定义为100-300m即0.1-0.3个cpu
        • 内存资源,也是一个绝对值,和服务器总内存数无关,单位可以是Mi 多少兆
        • requests: 最小申请值满足容器启动
        • limits: 最大使用值,限制容器使用量,超过将会被杀死进程并重启
      • pod中容器中的主程序必须在前台执行,不能在后台执行。创建的Docker镜像必须以一个前台命令作为启动命令。
      • 如果是无法改为前台执行的程序,可以使用supervisor辅助,其自身会在前台执行
      • ConfigMap:容器应用的配置管理

        • 将容器中程序的配置单独出来管理。通过环境变量或外挂载文件的方式在容器创建时注入
        • 生成为容器内的环境变量。设置成容器启动命令的启动参数。挂载为容器内部的文件目录
        • ConfigMap必须在pod创建之前创建。也可以定义命名空间,只有同一空间中的pod可以引用
        • 使用配置的变量:通过环境变量获取ConfigMap中的内容

          apiVersion:v1
          kind: ConfigMap
          metadata:
            name: cm-appvars
          data:  #环境变量形式
            apploglevel:info
            appdatadir:/var/data
          ---
          apiVersion:v1
          kind: Pod
          metadata:
            name: cm-appvars-pod
          spec:
            containers:
            - name: cm-test
              image: busybox
              command:["/bin/sh","-c","env |grep APP"]
              env:  #环境变量列表
              - name: APPLOGLEVEL   #定义环境变量名
                valueFrom:          #值内容从ConfigMap中获取
                  configMapKeyRef:  #ConfigMap配置
                    name: cm-appvars  #环境变量的值取自cm-appvars中
          ....
      ```
    • Pod生命周期和状态:

      • Pending已经创建Pod,但pod内还有容器的镜像没有创建
      • Runing Pod内所有容器都已经创建,并有一个容器在运行
      • Succedded Pod内所有容器都已经退出,并不会重启
      • Failed Pod内所有容器都已经退出,并有一个容器退出失败
      • Unknown 未知原因无法获取Pod状态,可以是网络原因
      • 失效容器重启时间间隔以sync-frequency的2倍计算,重启成功10分钟之后重置时间
    • Pod健康检查:livenessProbe探针判断容器是否存活

      • 探测方式:Exec:在容器内部执行一个命令,命令返回码为0,表明健康
      • TcpSocket:通过容器IP和端口执行TCP检查,能建立连接表明健康
      • HttpGet: 通过容器IP和端口及路径调用get方法,响应状态码大于200小于400则健康
    • Pod调度:将Pod分派到哪个Node中创建。

      • 定向调度:指定标签的Node中创建,先将Node打标签kubectl label nodes node名 标签key=标签value。再在Pod配置中的nodeSelector: 标签key:标签value
      • DaemonSet:特定场景调度,在每一个node中创建一个pod副本

        • 如每个node上创建一个存储的,日志采集的,性能健康监控采集的、负载均衡、网关入口
        • 只需要在Deployment的配置文件中将kind:Deployment改为kind:DaemonSet即可,定义的Pod将在每一个node中创建
    • Pod自动扩容缩容:可以手动命令形式配置,也可以使用HPA配置文件控制

      • 命令:kubectl autoscale rc php-apache --min=1 --max=10 --cpu-percent=90
      • 表示在1-10之间调整pod副本数量,使平均cpu使用率维持在50%。需要heapster组件
      • HPA配置脚本,通过CPU使用率判断是否扩容,需要Pod定义CPU资源限制Request值
      • 查看扩容缩容 kubectl get hpa 查看自动扩容详情 kubectl describe hpa
      • 只能自动扩容缩容Deployment,ReplicaSet或ReplicationController资源配置kind值

        apiVersion: autoscalingv1
        kind: HorizontalPodAutoscaler
        metadata:
          name: php-apache
          namespace: default
        spec: 
          scaleTargetRef:
            apiVersion: v1
            kind: ReplicationController
            name: php-appache
          minReplicas: 1
          maxReplicas: 10
          targetCPUUtilizationPercentage:90
    • Pod滚动升级:将创建一个新的RC,然后控制就的RC中的pod副本数量遂渐减少到0,同时新的RC中的pod副本的数量遂渐增加到目标值。要求新旧RC在同一命名空间中

      • kubectl rolling-update 旧rc名 -f 新rc的yml配置文件
      • 新rc配置文件中name不能和旧的RC名字相同,可以加版本号前缀区别
      • 在配置文件中所有selector选择器中至少有一个label标签和旧的RC中的Label不同,用来标识新RC 如添加版本标签 version: v2
      • 最后修改使用升级后的新版本镜像,即可实现升级
      • 或不使用配置文件使用新镜像名 kubectl rolling-update 旧rc名 --image=redis-master:2.0
      • 如果发现更新过程中发现配置错误,使用回滚命令,回到指定镜像
      • kubectl rolling-update 旧rc名 --image=redis-master:1.0 --rollback
      • DaemonSet的滚动更新https://kubernetes.io/docs/ta...

        必须将其设置 .spec.updateStrategy.type为RollingUpdate
        检查值,结果应该是RollingUpdate
        kubectl get ds/<daemonset-name> -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}'
        或者在创建DaemonSet控制器文件时指定,或者在UI管理界面中修改更新控制器文件
        使用更改后的配置文件使修改生效
        kubectl apply -f ds.yaml
        查看滚动更新状态
        kubectl rollout status ds/<daemonset-name>
        结果应该是
        daemon set "<daemonset-name>" successfully rolled out
      • replication controller滚动更新
      • https://kubernetes.io/docs/ta...

        #仅更新镜像
        kubectl rolling-update 副本控制器名 --image=nginx:1.9.1
        #回退之前版本
        kubectl rolling-update my-nginx --rollback
        #使用一个新的配置文件更新
        kubectl rolling-update 副本控制器名 -f 配置文件名
        配置文件必须选择
        metadata.name 新的名字标签使用新标签
    • 每个资源都有事件Event,记录事件的各种信息,可以帮助排查故障
    • Label标签:可以附加在各种资源上,如Pod、Node、Service、RC等,一个资源对象可以定义任意数量的多个标签,同一个标签也可以添加到任意数量的多个资源上。用来实现管理,使用标签筛选器查找。常用标签:

      • 版本标签:release:alpha初始版、release:beta测试版、release:stable稳定版
      • 环境标签:environment:dev开发、environment:production生产、environment:test测试
      • 架构标签:role:frontend前端、role:backend后端、role:middleware中间
    • Replication Controller(RC)副本控制器:定义资源预期期望的环境,声明pod副本的数量在任意时刻都符合某个预期值。调度管理pod

      • 定义了 Pod 期待的副本数量
      • 用户筛选pod的 Lable selector标签选择器
      • 包含了 创建新pod的pod定义模板
      • 可以动态修改pod数量实现自动扩容或缩容 kubectl scale rc php-slave --replicas=3
      • 删除RC并不会删除已经通过此RC创建的Pod,删除全部Pod 可以使用stop和delete命令
      • 滚动升级,就是通过RC的控制,改变Pod模板中的镜像版本,停掉旧的Pod启动新的Pod
      • Replica Set 下一代的RC。区别是支持集合的标签选择器,RC只支持等于的选择器

        apiVersion: v1
        kind: ReplicaSet
        metadata:
          name: mysql
        spec:
          selector:
            matchLabels:
              tier: mysql
            matchExpressions:
          ....
    ```
    • Replica Set 被Deployment资源使用。两者替换了RC的作用
    • Deployment :调度部署是新概念。内部使用RC的升级版Replica Set实现调度目的。

      • 可以随时知道当前Pod部署的进度,查看部署状态数量等信息。
      • 可以修改镜像更新Deployment,创建新的Pod
      • 如果当前Deployment 不稳定,可以回滚之前的版本
      • 同样可以通过kubectl get rc 查看副本控制信息
      • 同样可以通过kubectl get pods 查看pod的创建信息
      • 创建的Pod资源命名规则会以Deployment对应的Replica Set的名字为前缀

        apiVersion: v1
        kind: Deployment
        metadata:
          name: nginx-Deployment
          ....
    • Service 服务:定义一个服务的访问入口地址,前端应用如php的Pod通过这个入口地址,访问背后的一组由Pod副本集群组成提供的服务。服务与集群之间通过标签选择器定位,RC副本控制器保证集群处于预期状态。

      • 服务对外开启访问端口
      • 服务提供负载均衡,负载同一服务的不同Pod
      • 服务提供全局唯一虚拟IP即Cluster IP,服务生存期内IP不会改变。无法被ping。结合Service Port组合成一个具体的通信端口,单独的一个不具备TCP/IP通信基础。属于集群内部地址,外部无法访问。外部方法可以设置节点映射端口
      • 服务提供全局唯一的名字
      • 服务发现通过service的Name和Cluster IP做一个DNS域名映射解决
      • DNS系统支持服务发现,使用服务名作为DNS域名。
      • 服务支持多端口通过端口名字区分
      • Pod本身是变化的,比如当Pod发生迁移,那么Pod的IP是变化的, 那么Service的就是在Pod之间起到中转和代理的作用,Service会生成一个虚拟IP, 这个虚拟IP负载均衡到后端的Pod的IP
      • iptables-save 查看iptables重定向
      • 服务处在多节点服务器上的负载均衡需要一个单独的负载均衡设备,这个不属于Kubernetes
      • 只要部署了service 那么无论是使用哪种方式访问服务(访问服务IP也好服务域名也好,宿主机端口也好),都会被负载均衡调度,除非只有一个pod。因为发送到node上指定端口的数据,会通过iptables重定向到kube-proxy对应的端口上。然后由kube-proxy进一步把数据负载均衡发送到其中的一个pod上。

        apiVersion: v1
        kind: Service
        metadata:
          name: mysql-service
        spec:
          selector:
            tier: mysql
          type: NodePort    #使用节点端口开放服务
          ports:     #多服务端口支持
          - port: 3600
            name: service-port
            nodePort: 3600  #开放的节点端口,外部使用节点IP和此端口可以访问此服务
          - port: 3601
      ....
    ```
    • Volume:存储卷。挂载在Pod中,提供给Pod中所有容器共享访问的目录。

      • 生命周期和Pod的相同和容器无关,容器的重启终止不会影响。
      • 数据卷类型:

        • emptyDir:临时的,初始内容为空,不需要指定宿主机对应的目录。Pod被从Node删除时,数据卷数据也被删除。存储应用程序的临时数据。
        • hostPath:挂载在宿主机上的文件或目录。容器应用程序生产的日志文件等,注意不同Node的目录文件不一致
        • Persistent Volume:PV网络云存储。不属于任何Node,但可以在任何Node上访问。独立于Pod
        • https://github.com/kubeup/kub... 阿里云支持存储卷但不支持PVC
        • 网络存储PV 类型:NFS(网络文件系统NAS)、iSCSCI(降级SAN存储区域网络企业级存储)、GlusterFS、ceph
        • 阿里云内网速度是共享千兆网卡 1Gbps 速率
      • 定义在Pod的配置中

        apiVersion: v1  #版本号
        kind: Pod    # kind定义这个一个pod资源
        metadata:
          name: myweb   #定义pod名字
          labels:       #定义标签
            name:myweb
        spec:     #定义pod里容器属性
          volumes:  #定义数据卷的类型和名字
            - name: datavo1
              emptyDir: {}
            - name: storage
              hostPath:
      containers:
      - name: myweb   #定义容器名
        image: kuberguide/tomcat-app:v1   #定义容器使用镜像
        volumeMounts:   #挂载在pod的位置
          - mountPath: /mydata-data
            name: datavo1
        
        .....
    ```
    • Namespace:命名空间,支持多租户,实现资源隔离。默认空间是default。不指名空间所有资源pod、RC、Service都会被创建到默认命名空间,查询命令不加参数都查询的是默认空间中的对象数据。

      • kubectl get pods --namespace=developemnt 指定命名空间查询
      • 不同项目组不同空间,或者不同环境不同空间,如紫色医疗和嘟嘟医生,或开发环境、测试环境、正式环境
      • 可以隔离不同空间下不同租户使用资源如:cpu、内存

        apiVersion: v1  #版本号
        kind: Namespace   
        metadata:
          name: developemnt  #
          ...
        
        #使用
        apiVersion: v1  #版本号
        kind: Pod    
        metadata:
          name: myweb 
          namespace: developemnt  #指定pod创建在哪个租户下
          ....
        
    • secret 秘钥账号密码资源

      #创建一个ssh秘钥的资源
      kubectl create secret generic nginx-php-ssh-key --from-file=id_rsa=/home/kube_yaml/nginx_php/id_rsa --from-file=id_rsa.pub=/home/kube_yaml/nginx_php/id_rsa.pub
      
      #使用:挂载使用时 id_rsa和id_rsa.pub 这两个键名会作为挂载目录下的文件名 ,健值会作为文件对应的内容
        volumeMounts:
        - name: ssh-key
          mountPath: "/root/.ssh"
    #环境变量中使用
    env:
        - name: id_rsa
          valueFrom:
            secretKeyRef:
              name: nginx-php-ssh-key
              key: id_rsa.pub

    volumes:

    • name: ssh-key
      secret:
      secretName: nginx-php-ssh-key
    • Dashboard UI 图形化界面 1.4版本

    • kubeadm init和kubeadm join 简化安装部署 1.4版本
    • service account 服务账号并不是给集群的用户使用的,而是给运行在pod里的进程使用的,为pod里的进程提供必要的身份证明

      • 为确保集群安全,api server会对客户端进行身份认证,认证失败无法调用api。pod中访问api server服务时是以service方式访问服务名为kubernetes的服务的。这个服务只在https 443端口上提供服务,使用的是一种http token的认证方式
      • 每个namespace 命名空间下都有个名为default的默认service account对象,这个对象里有个名为tokens的可以当做volume一样被挂载到pod里的secret秘钥,当pod启动时,这个secret会被自动挂载到pod的指定目录下,来协助pod中的进程完成访问api server的身份验证过程 kubectl describe serviceaccounts 再查看详情 kubectl describe secrets default-token-xxxx
      • 如果一个pod在创建时没有定义spec.serviceAccountName属性,系统会自动设置为default,即大家都是用同一个namespace命名空间下默认的service account服务账号
      • service account 服务账号是属于某个具体的Namespace空间的
      • 如果一个Namespace下没有默认的service account账号将会为该空间创建一个default默认的setvice account
      • 在kube-apiserver 启动参数中 --admission_control=ServiceAccount准入控制器时,将会验证pod里的service accont是否合法
      • 如果pod的spec.serviceAccountName指定了default以外的service account 而该service account没有事先被创建,则该pod将无法创建
      • 创建一个service account

        • openssl genrsa -out /tmp/kube-serviceaccount.key 2048 首先生成key
        • kube-apiserver ... --service_account_key_file=/tmp/kube-serviceaccount.key 启动参数中添加key
        • kube-apiserver --admission_control=...,ServiceAccount 并且API Server设置admission_control包含ServiceAccount
        • kube-controller-manager ... --service_account_private_key_file=/tmp/kube-serviceaccount.key... 启动Controller Manager增加service_account_private_key_file
        • kubectl get serviceaccount --all-namespaces 查看每个namespace都会默认创建的一个ServiceAccount
        • 可以创建一个服务账号
          serviceaccount.yaml
          apiVersion: v1
          kind: ServiceAccount
          metadata:
            name: build-robot
            namespace: kube-system  #不指定命名空间则为default默认命名空间
        • kubectl create -f serviceaccount.yaml 创建
        • kubectl get serviceaccounts/build-robot -o yaml 查看ServiceAccount默认创建一个secret,也可以手动创建secret然后添加到ServiceAccount。
        • secrets: - name: build-robot-token-3uazg
        • 创建Pod使用ServiceAccount
        busybox-pod.yaml:
        
        apiVersion: v1
        kind: Pod
        metadata:
        name: busybox
        spec:
        containers:
        - image: busybox
        command:
          - sleep
          - "3600"
        imagePullPolicy: IfNotPresent
        name: busybox
        serviceAccountName: build-robot  #指定使用的非默认default的服务账号
        • Pod创建成功后,可以查询Pod的容器挂载/var/run/secrets/kubernetes.io/serviceaccount位置保存
        "Volumes": {
        "/var/run/secrets/kubernetes.io/serviceaccount": "/var/lib/kubelet/pods/05174b7d-426d-11e5-aacb-005056817c3e/volumes/kubernetes.io~secret/build-robot-token-3uazg"
        },
        • kubectl exec busybox cat /var/run/secrets/kubernetes.io/serviceaccount/token 查看token。实际上这个目录是ServiceAccount的Secret,里面包含了一个token,应用通过使用这个token便可以去访问

    安装

    • 升级:遂各隔离Node,等待上面容器执行完成,再更新Node上的kubelet、kube-proxy。全部更新完node之后,更新Master上的服务
    • 单机本地Minikube安装

      • https://github.com/kubernetes... 代码地址安装说明
      • 支持DNS、NodePorts、ConfigMaps、Secrets、Dashboards、Ingress
      • MacOS安装要求: VirtualBox虚拟机 和kubectl命令行工具

        • brew install kubectl 安装命令行脚本
        • kubectl version 检查版本号
        • brew install bash-completion 安装命令行自动完成支持,节约敲命令
        • 当前shell生效
        • source $(brew --prefix)/etc/bash_completion
        • source <(kubectl completion bash)
        • 加入环境
        • echo "source $(brew --prefix)/etc/bash_completion" >> ~/.bash_profile
        • echo "source <(kubectl completion bash)" >> ~/.bash_profile
      • 开始安装Minikube

        • curl -Lo minikube https://storage.googleapis.co... && chmod +x minikube && sudo mv minikube /usr/local/bin/
        • 无法下载可以从官网地址直接下载再安装
        • https://github.com/kubernetes... 下载地址
        • sudo mv minikube-darwin-amd64 /usr/local/bin/minikube 移动加改名
        • chmod +x minikube 执行权限
        • minikube start 启动
        • kubectl cluster-info 检查集群是否准备好
        • eval $(minikube docker-env) #连接集群中的docker,未连接的shell会话无法操作集群中的docker
        • docker ps #之后就可以获得运行的docker数据
        • minikube stop 停止集群 保留集群状态和数据,重启将恢复
        • minikube delete 删除集群
        • 安装仪表盘
        • 由于使用的镜像是在谷歌服务器所以国内访问不到,可以使用阿里云镜像
        • docker pull registry.cn-hangzhou.aliyuncs.com/kube_containers/kubernetes-dashboard-amd64
        • 再修改 kubernetes-dashboard.yaml 中的镜像来源配置
        • kubectl create -f https://rawgit.com/kubernetes...
        • minikube dashboard 获取web UI 地址
        • minikube service [-n NAMESPACE] [--url] NAME 获取集群中开放端口的服务访问地址
        • minikube ip 获取集群服务IP地址,任何开放的服务都可以通过该地址和端口号访问
        • kubectl get service 服务名 --output='jsonpath="{.spec.ports[0].nodePort}"' 获取集群中服务的访问端口号
        • 之后可以按照一般创建pod以及service的步骤去创建服务了
        • 查看服务需要使用命名空间参数kubectl get service kubernetes-dashboard --namespace=kube-system 删除和查询详情都是需要指定命名空间
        • kubectl describe pod kubernetes-dashboard --namespace=kube-system
        • 注意gcr.io/google_containers/pause-amd64:3.0 pod的基础容器pause也是在谷歌上
        • 临时解决方法:

          https://github.com/kingtongxingsheng/docker-library
          https://hub.docker.com/r/carrotking/kubernetes/~/settings/automated-builds/
          在我的dockerhub上的kubernetes项目中自动构建对应镜像
          执行 minikube ssh 命令登录到minikube节点中或eval $(minikube docker-env) 
          拉取镜像到本地仓库中
          docker pull carrotking/kubernetes:pause_amd64_3.0
          重新tag:  
          docker tag  image_id  gcr.io/google_containers/pause-amd64:3.0
          之后就能正常启动这个test pod了
    • kubeadm 安装
    • 完全手动遂一安装 官方参考文档https://kubernetes.io/docs/ge...

      • 基础依赖管理配置:

        • 多主机网络连通管理,使用flannel。每个Node节点的子网规划a/24可以配置254个pod,如果一个主机上不需要启动那么多pod也可以a/25 128个pod,a/26 62个pod,a/27 30个pod
        • 192.168.0.0/16 作为node节点的IP范围,那么可以有192.168.0.0/24 - 192.168.255.0/24 个node节点主机
        • 集群服务也需要IP,设置SERVICE_CLUSTER_IP_RANGE="192.168.0.0/16" 将有 65534 个服务可以同时存在,一个节点254个ip服务占据1/3 ip,pod占据2/3 ip
        • 主节点:需要设置静态IP MASTER_IP;打开任何防火墙以允许访问apiserver端口80和443;启用ipv4转发sysctl, net.ipv4.ip_forward = 1
        • 集群命名:CLUSTER_NAME 可以区分测试,开发,不同部门的环境,第三方,互不影响
        • 下载二进制包etcd数据库、docker、kubelet命令、kube-proxy网络代理、kube-apiserver接口服务、kub-controller-manager容器管理、kub-scheduler调度
        • DNS 服务
        • CA证书 在阿里内网环境可以不用证书验证,使用阿里安全组功能屏蔽外网访问
        • NFS 网络数据存储服务
        • flannel 使用 0.7.0 docker pull registry.cn-hangzhou.aliyuncs.com/gcr-io/flannel:v0.7.0-amd64
        • Etcd 版本使用Kubernetes二进制分发中提供的etcd版本,目前最新是3.0.17,经过了广泛测试 docker pull registry.cn-shenzhen.aliyuncs.com/gcrio/etcd-amd64:3.0.17
      • 关闭防火墙 systemctl status firewalld systemctl disable firewalld systemctl stop firewalld
      • Master安装etcd服务
      • Master安装kube-apiserver、kub-controller-manager、kub-scheduler 作为容器运行 docker pull registry.cn-hangzhou.aliyuncs.com/google-containers/hyperkube-amd64:1.6.1-f50fbf0

        wget https://github.com/kubernetes/kubernetes/releases/download/v1.6.1/kubernetes.tar.gz
        tar xzvf kubernetes.tar.gz && cd kubernetes && ./cluster/get-kube-binaries.sh  下载server和client的可执行文件
        #执行该shell会自动下载kube的server和client可执行文件,其中客户端文件会自动安装在kubernetes目录下的client文件夹下,只需将bin添加到PATH下就可以了 
        cd server &&tar xzvf kubernetes-server-linux-amd64.tar.gz
        #查看目录下文件
        ll kubernetes/server/bin
        cd kubernetes/server/bin
        cp -r server/bin/{kube-apiserver,kube-controller-manager,kube-scheduler,kubectl,kube-proxy,kubelet} /usr/local/bin/
        
        
        
        #编辑配置kubeconfig    server 地址为本机当中安装的apiserver地址
        vim /etc/kubernetes/kubeconfig
        current-context: kube-context
        apiVersion: v1
        kind: Config
        users:
        - name: controllermanager
          user:
            client-certificate: /root/ssl/apiserver.pem
    clusters:
    - name: kubernetes
      cluster:
        certificate-authority: /root/ssl/ca.pem
        server: https://10.29.167.233:6443
    contexts:
    - context:
        cluster: kubernetes
        user: controllermanager
      name: kube-context
    
    #编辑公共配置文件主从都有
    mkdir -p /etc/kubernetes
    vim /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
      # 为true 日志输出到屏幕 false 日志写入文件
      KUBE_LOGTOSTDERR="--logtostderr=false"
      #日志保存目录  日志目录主从都要先创建好才能启动服务
      KUBE_LOG_DIR="--log-dir=/var/log/k8s"
      # 日志等级 0 is debug 2
      KUBE_LOG_LEVEL="--v=2"
      
      # 是否允许允许系统特权容器Pod
      KUBE_ALLOW_PRIV="--allow-privileged=true"
      
      # How the controller-manager, scheduler, and proxy find the apiserver
      # master使用本机安装的apiserver地址
      KUBE_MASTER="--master=https://10.29.167.233:6443"
    
     查看端口占用netstat -anp |grep 6443
    #编辑apiserver配置文件
    vim /etc/kubernetes/apiserver
      ###
      ## kubernetes system config
      ##
      ## The following values are used to configure the kube-apiserver
      ##
      #
      ## 绑定非安全认证访问地址 insecure-bind-address默认0.0.0.0全部网络,可以允许外部访问,如果放置在负载均衡后面可以绑定本机IP
      KUBE_API_ADDRESS="--advertise-address=10.29.167.233 --bind-address=0.0.0.0"
      #
      ## 非安全认证访问监听端口默认8080 ,安全组中配置外部客户端不可访问
      KUBE_API_PORT="--insecure-port=0"
      #
      ##  etcd 集群
      KUBE_ETCD_SERVERS="--etcd-servers=http://10.29.167.233:2379,http://10.29.167.233:2377,http://10.29.167.233:2378"
      #
      ## 服务虚拟IP地址池,不能和物理机所在网络重合如169.169.0.0
      KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=169.169.0.0/16"
      #
      ## 默认允许控制政策,对发送给API Server的任何请求进行拦截和过滤
      KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota"
      #
      ## Add your own! secure-port=0不启用https默认6443
      KUBE_API_ARGS="--cloud-provider='' --enable-garbage-collector=true  --secure-port=6443 --service-node-port-range=30000-32767 --apiserver-count=1  --client-ca-file=/home/sharefiles/ssl/ca.pem --tls-cert-file=/home/sharefiles/ssl/kubernetes.pem --tls-private-key-file=/home/sharefiles/ssl/kubernetes-key.pem
      --service-account-key-file=/home/sharefiles/ssl/kubernetes-key.pem --etcd-prefix=kubernetes"
    
    #安装kube-apiserver服务
    #编辑系统启动服务配置
    vim /usr/lib/systemd/system/kube-apiserver.service
    [Unit]
    Description=Kubernetes API Service
    Documentation=https://github.com/GoogleCloudPlatform/kubernetes
    After=network.target
    
    
    [Service]
    EnvironmentFile=/etc/kubernetes/config
    EnvironmentFile=/etc/kubernetes/apiserver
    ExecStart=/usr/local/bin/kube-apiserver \
            $KUBE_LOGTOSTDERR \
            $KUBE_LOG_LEVEL \
            $KUBE_LOG_DIR \
            $KUBE_ETCD_SERVERS \
            $KUBE_API_ADDRESS \
            $KUBE_API_PORT \
            $KUBE_ALLOW_PRIV \
            $KUBE_SERVICE_ADDRESSES \
            $KUBE_ADMISSION_CONTROL \
            $KUBE_API_ARGS
    Restart=on-failure
    Type=notify
    LimitNOFILE=65536
    
    [Install]
    WantedBy=multi-user.target
    #启动服务
     systemctl daemon-reload
     systemctl enable kube-apiserver
     systemctl start kube-apiserver
     systemctl status -l kube-apiserver
     systemctl restart kube-apiserver
     systemctl stop kube-apiserver
     
    #安装controller-manager
    vim /etc/kubernetes/controller-manager
    # cluster-name 集群名 root-ca-file CA根证书
    KUBE_CONTROLLER_MANAGER_ARGS="--cloud-provider='' --enable-garbage-collector=true --terminated-pod-gc-threshold=5 --address=127.0.0.1 --service-cluster-ip-range=169.169.0.0/16  --cluster-cidr=172.17.0.0/16 --root-ca-file=/home/sharefiles/ssl/ca.pem --service-account-private-key-file=/home/sharefiles/ssl/kubernetes-key.pem --kubeconfig=/etc/kubernetes/kubeconfig"
    
    vim /usr/lib/systemd/system/kube-controller-manager.service
    [Unit]
    Description=Kubernetes Controller Manager
    Documentation=https://github.com/GoogleCloudPlatform/kubernetes
    After=kube-apiserver.service
    Requires=kube-apiserver.service
    
    [Service]
    EnvironmentFile=/etc/kubernetes/config
    EnvironmentFile=/etc/kubernetes/controller-manager
    ExecStart=/usr/local/bin/kube-controller-manager \
            $KUBE_LOGTOSTDERR \
            $KUBE_LOG_LEVEL \
            $KUBE_LOG_DIR \
            $KUBE_MASTER \
            $KUBE_CONTROLLER_MANAGER_ARGS
    Restart=on-failure
    LimitNOFILE=65536
    
    [Install]
    WantedBy=multi-user.target
    
    systemctl daemon-reload
    systemctl enable kube-controller-manager
    systemctl start kube-controller-manager
    systemctl status -l kube-controller-manager
    systemctl restart kube-controller-manager
    systemctl stop kube-controller-manager
    
    #安装kube-scheduler
    vim /etc/kubernetes/scheduler
    KUBE_SCHEDULER_ARGS="--address=127.0.0.1 --kubeconfig=/etc/kubernetes/kubeconfig"
    
    vim /usr/lib/systemd/system/kube-scheduler.service
    [Unit]
    Description=Kubernetes Scheduler Plugin
    Documentation=https://github.com/GoogleCloudPlatform/kubernetes
    After=kube-apiserver.service
    Requires=kube-apiserver.service
    
    [Service]
    EnvironmentFile=/etc/kubernetes/config
    EnvironmentFile=/etc/kubernetes/scheduler
    ExecStart=/usr/local/bin/kube-scheduler \
                $KUBE_LOGTOSTDERR \
                $KUBE_LOG_LEVEL \
                $KUBE_LOG_DIR \
                $KUBE_MASTER \
                $KUBE_SCHEDULER_ARGS
    Restart=on-failure
    LimitNOFILE=65536
    
    [Install]
    WantedBy=multi-user.target
    
    systemctl daemon-reload
    systemctl enable kube-scheduler
    systemctl start kube-scheduler
    systemctl status -l kube-scheduler
    systemctl restart kube-scheduler
    systemctl stop kube-scheduler
    
    #配置kubectl
    cd ~/.kube/
    vim config
    current-context: kube-context
    apiVersion: v1
    kind: Config
    users:
    - name: controllermanager
      user:
        client-certificate: /root/ssl/apiserver.pem
        client-key: /root/ssl/apiserver-key.pem
    clusters:
    - name: kubernetes
      cluster:
        certificate-authority: /root/ssl/ca.pem
        server: https://10.29.167.233:6443
    contexts:
    - context:
       cluster: kubernetes
       user: controllermanager
      name: kube-context
    #或使用命令行配置config
    # 设置集群参数
    kubectl config set-cluster kubernetes \
      --certificate-authority=/home/sharefiles/ssl/ca.pem \
      --embed-certs=true \
      --server=https://10.29.167.233:6443
    # 设置客户端认证参数
    kubectl config set-credentials controllermanager \
      --client-certificate=/home/sharefiles/ssl/apiserver.pem \
      --embed-certs=true \
      --client-key=/home/sharefiles/ssl/apiserver-key.pem
    # 设置上下文参数
    kubectl config set-context kube-context \
      --cluster=kubernetes \
      --user=controllermanager
    # 设置默认上下文
    kubectl config use-context kube-context
    #验证master节点
    kubectl --server=https://10.29.167.233:6443 --certificate-authority=/home/sharefiles/ssl/ca.pem \
    --client-certificate=/home/sharefiles/ssl/apiserver.pem \
    --client-key=/home/sharefiles/ssl/apiserver-key.pem \
    get cs
    或
    kubectl get cs
    
    #node节点安装
    创建工作目录
    mkdir /var/lib/kubelet
    
    修改主机名centos7
    vim /etc/cloud/cloud.cfg将
    preserve_hostname=fale  改为
    preserve_hostname=true
    hostnamectl set-hostname node_246  重新登录即可
    
    yum install conntrack-tools
    
    vim /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=10.29.168.24"
    #
    ## 本节点在集群中的名字 10.29.167.186
    KUBELET_HOSTNAME="--hostname-override=10.29.168.24"
    #
    ##  api-server服务地址
    KUBELET_API_SERVER="--api-servers=https://10.29.167.233:6443"
    #
    ## pod 基础pause镜像
    KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.cn-shenzhen.aliyuncs.com/gcrio/pause-amd64:3.0"
    #
    ## Add your own! 
    #--cluster-dns 指定 kubedns 的 Service IP(可以先分配,后续创建 kubedns 服务时指定该 IP),
    #--cluster-domain 指定域名后缀,这两个参数同时指定后才会生效
    #--root-dir 运行根目录 保存pod 和 volume 的文件
    KUBELET_ARGS="--cloud-provider='' --cluster-dns=169.169.1.1  --root-dir=/var/lib/kubelet --cluster-domain=cluster.local  --serialize-image-pulls=false  --kubeconfig=/etc/kubernetes/kubeconfig --hairpin-mode=promiscuous-bridge"
    
    vim /usr/lib/systemd/system/kubelet.service
    [Unit]
    Description=Kubernetes Kubelet Server
    Documentation=https://github.com/GoogleCloudPlatform/kubernetes
    After=docker.service
    Requires=docker.service
    
    [Service]
    WorkingDirectory=/var/lib/kubelet
    EnvironmentFile=/etc/kubernetes/config
    EnvironmentFile=/etc/kubernetes/kubelet
    ExecStart=/usr/local/bin/kubelet \
                $KUBE_LOGTOSTDERR \
                $KUBE_LOG_LEVEL \
                $KUBE_LOG_DIR \
                $KUBELET_API_SERVER \
                $KUBELET_ADDRESS \
                $KUBELET_HOSTNAME \
                $KUBE_ALLOW_PRIV \
                $KUBELET_POD_INFRA_CONTAINER \
                $KUBELET_ARGS
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target
    
    systemctl daemon-reload
    systemctl enable kubelet
    systemctl start kubelet
    systemctl status -l kubelet
    systemctl stop kubelet
    systemctl restart kubelet
    
    
    #安装kube-proxy
    vim /etc/kubernetes/proxy
    #--hostname-override 参数值必须与 kubelet 的值一致
    #kube-proxy 根据 --cluster-cidr 判断集群内部和外部流量 pod的地址范围,用于桥接集群外部流量到内部,
    #snat IP地址转换,将内网向外网发出的包的内网源地址改成可以被外网访问到的ip地址,方便外网的请求可以请求到内网
    KUBE_PROXY_ARGS="--bind-address=10.29.168.24 --hostname-override=10.29.168.24 --cluster-cidr=172.17.0.0/16  --kubeconfig=/etc/kubernetes/kubeconfig"
    
    vim /usr/lib/systemd/system/kube-proxy.service
    [Unit]
    Description=Kubernetes Kube-Proxy Server
    Documentation=https://github.com/GoogleCloudPlatform/kubernetes
    After=network.target
    Requires=network.service
    
    [Service]
    EnvironmentFile=/etc/kubernetes/config
    EnvironmentFile=/etc/kubernetes/proxy
    ExecStart=/usr/local/bin/kube-proxy \
            $KUBE_LOGTOSTDERR \
            $KUBE_LOG_LEVEL \
            $KUBE_LOG_DIR \
            $KUBE_MASTER \
            $KUBE_PROXY_ARGS
    Restart=on-failure
    LimitNOFILE=65536
    
    [Install]
    WantedBy=multi-user.target
    
    #启动服务
    systemctl daemon-reload
    systemctl enable kube-proxy
    systemctl start kube-proxy
    systemctl status -l kube-proxy
    systemctl stop kube-proxy
    systemctl restart kube-proxy
    
    
    #检查节点
    kubectl get nodes
    
    #测试
    kubectl run nginx --replicas=2 --labels="run=load-balancer-example" --image=nginx:1.11.13  --port=80
    kubectl expose deployment nginx --type=NodePort --name=example-service
    kubectl describe svc example-service
    
    #访问主节点所有从节点的主机端口都应该能访问到nginx,以及访问pod服务虚拟IP也应该能访问到nginx
    curl "121.42.248.198:30101"
    ```
    • Node安装Docker引擎
    • Node安装kubelet、kube-proxy
    • Master安装私有Docker镜像仓库
    • 获取kubeguide/google_containers/pause-amd64:3.0镜像提交到私有仓库,此仓库是创建Pod使用的
    • Node配置kubelet启动参数--pod_infra_container_image=kubeguide/google_containers/pause-amd64:3.0使用私有仓库地址为pause镜像地址。
    • 集群网络配置。多Node节点网络互通是底层配置,与Kubernetes无关需要自行配置

      • flannel 覆盖网络,官方推荐。封装了数据包,会降低性能。需要安装etcd
      • 直接路由:性能最好设置简单,就是多台Node节点配置静态路由转发规则较为繁琐,可以使用quagga管理。需要规划每台Node节点docker0网卡子网IP段不能相互冲突重复。重启服务器时,Docker0地址会变化需要设置固定值,阿里云网络不支持路由配置

        sudo ifconfig docker0 172.17.0.254/24   master 主机  ifconfig配置重启之后就会还原,需要使用bip绑定ip参数
        sudo ifconfig docker0 172.17.1.254/24   /24表示24个1 8个0 表示此子网段可以有256台主机
        sudo ifconfig docker0 172.17.2.254/24   254为节点主机Docker0网卡的IP地址。172.17.2.1-253 都是一个子网的
        
        ....  可以一直到172.17.254.254/24
        
        sudo systemctl restart docker  #重启
        #在主机master 上添加路由
        sudo route add -net 172.17.1.0 netmask 255.255.255.0 gw 节点主机1的内网IP
        sudo route add -net 172.17.2.0 netmask 255.255.255.0 gw 节点主机2的内网IP
        #在节点主机1上 添加路由
        sudo route add -net 172.17.0.0 netmask 255.255.255.0 gw master主机的内网IP
        sudo route add -net 172.17.2.0 netmask 255.255.255.0 gw 节点主机2的内网IP
        
        #不在同一网段   先将网关IP当成一个主机加进来,这样在这两个IP直接建立一个连接,并且不设置掩码,即能到达所有其他网段。 
        route add -host 202.194.20.254 netmask 0.0.0.0 dev eth0
        #然后再将网关IP加成网关 
        route add default gw 202.194.20.254 netmask 0.0.0.0 dev eth0
        #查看路由
        route -n 
        #删除路由记录
        route del -net 172.17.1.0/24 或
        route del -net 172.17.1.0 netmask 255.255.255.0
        #删除默认网关记录
        route del default gw 192.168.120.240
        #跟踪路由跳转
        traceroute  172.17.0.1
      • 使用Calico 网络插件:插件中性能最好,创建路由表形式,在同一个子网中,通过路由方式转发数据包,无性能损耗,在不同子网中,需要隧道,有性能损耗。但同样阿里云网络不支持路由修改;
      • 使用阿里云的vps 专用高速网络:配置一个大的自定义的局域网。用的也是隧道技术覆盖网络
    • DNS服务skydns安装

      • 安装etcd
      • kube2sky 时刻调取apiserver的API获取集群中所有服务的信息,并将service服务写入etcd
      • skyDns 解析DNS域名
      • healthz 健康检查
      • 将启动四个容器放在一个pod中,
      • skydns的pod虚拟clusterIP地址必须是固定的,不能通过系统自动分配需要在server服务配置文件中使用clusterIP:选项配置,并在apiserver的指定ip地址范围。
      • 再修改每台Node上kubelet启动参数配置DNS服务的固定IP地址及域名
      • 之后通过服务名:端口号即可找到对应服务。不再担心服务重启后IP地址变更的问题
      • 每台Node的kubelet服务会去访问DNS服务,得到解析域名之后的对应IP地址再去访问服务
    • 1.4版本DNS服务

      • kubedns容器

        • 监视k8s Service资源并更新DNS记录
        • 替换etcd,使用TreeCache数据结构保存DNS记录并实现SkyDNS的Backend接口
        • 接入SkyDNS,对dnsmasq提供DNS查询服务
      • dnsmasq容器

        • 对集群提供DNS查询服务
        • 设置kubedns为upstream
        • 提供DNS缓存,降低kubedns负载,提高性能
      • exechealthz容器

        • 定期检查kubedns和dnsmasq的健康状态
        • 为k8s活性检测提供HTTP API
      • 对比1.2版改进

        • 无状态服务。1.2版本中,需要将Etcd的数据Volume出来才能保证Etcd容器重启之后数据不会丢失,服务可以快速恢复。新版本中作为无状态服务出现,通过增加冗余来提高可靠性。即使kubedns容器重启,dnsmasq缓存机制也可以保证服务的可用性。
        • 优化查询效率。SkyDNS直接从内存中获取DNS记录。
        • 完善健康检查。1.2版本中只对kube2sky设置了健康检查
        • 不足,内存占用问题,默认设置了内存限制为170M,大规模集群中使用未验证
      • 安装

          mkdir -p /home/kube_yaml/kubedns/
          cd kubernetes/cluster/addons/dns/ 
          cp kubedns-sa.yaml  /home/kube_yaml/kubedns 修改namespace: kube-system
          cp kubedns-cm.yaml  /home/kube_yaml/kubedns  无需修改 ConfigMap
          cp kubedns-svc.yaml.base /home/kube_yaml/kubedns/kubedns-svc.yaml 
          替换clusterIP: __PILLAR__DNS__SERVER__ 为 clusterIP: 169.169.1.1 和 kubelet 的 --cluster-dns 参数值一致;
          cp kubedns-controller.yaml.base /home/kube_yaml/kubedns/kubedns-controller.yaml
          
          修改所有镜像地址为本地私有仓库
          dudureg.xip.io:5000/k8s-dns-dnsmasq-nanny-amd64:1.14.1
          dudureg.xip.io:5000/k8s-dns-kube-dns-amd64:1.14.1
          dudureg.xip.io:5000/k8s-dns-sidecar-amd64:1.14.1
          
          替换所有__PILLAR__DNS__DOMAIN__ 为cluster.local   如:-- domain=cluster.local. 域名
          #__PILLAR__FEDERATIONS__DOMAIN__MAP__ 注释
          #创建所有资源kubedns-cm.yaml  kubedns-controller.yaml  kubedns-sa.yaml  kubedns-svc.yaml
          kubectl create -f .
          
          #系统预定义的 RoleBinding system:kube-dns 将 kube-system 命名空间的 kube-dns ServiceAccount 与 system:kube-dns Role 绑定, 该 Role 具有访问 kube-apiserver DNS 相关 API 的权限;
          查看命令 kubectl get clusterrolebindings system:kube-dns -o yaml
          kubedns-controller.yaml 中定义的 Pods 时使用了 kubedns-sa.yaml 文件定义的 kube-dns ServiceAccount,所以具有访问 kube-apiserver DNS 相关 API 的权限。
          
          获取有密码账号验证的私有镜像仓库的镜像
          Pods只能在其自己的命名空间中引用图像拉取秘密,因此每个命名空间需要执行一次此过程。
          kubectl create secret docker-registry regsecret --docker-server=dudureg.ziseyiliao.com:5000 --docker-username=duduyisheng --docker-password=duducode --docker-email=tongxingsheng@ziseyiliao.com
          查看
          kubectl get secret regsecret --output=yaml
          在Pod中使用
          imagePullSecrets:
        也可以不设置私有仓库账号密码
        
    
        #测试
        mkdir -p /home/kube_yaml/test && cd  /home/kube_yaml/test
        cat << EOF > test-nginx.yaml
        apiVersion: extensions/v1beta1
        kind: Deployment
        metadata:
          name: test-nginx
        spec:
          replicas: 2
          template:
            metadata:
              labels:
                run: test-nginx
            spec:
              containers:
              - name: test-nginx
                image: dudureg.xip.io:5000/nginx:1.11.13
                ports:
                - containerPort: 80
        EOF
        kubectl create -f test-nginx.yaml
        kubectl expose deploy test-nginx
        kubectl get services --all-namespaces |grep test-nginx
        kubectl --namespace=kube-system  describe service/kube-dns
        
        #dns组件可以为k8s集群内的service做dns解析
        #进入一个pod
        docker exec -ti k8s_test-nginx_test-nginx-218109665-j3h5z_default_83630203-28b4-11e7-a447-00163e05ddb0_0 /bin/bash
        #查看
        cat /etc/resolv.conf
        3#ping域名 都不能ping通,但都有对应解析地址就是成功
        ping test-nginx
        ping kubernetes
        ping kube-dns.kube-system.svc.cluster.local
        
        #使用
        my-svc.my-namespace.svc.cluster.local  A记录服务域名
        my-svc 为服务名  my-namespace 为命名空间默认空间为 default。 svc.cluster.local 为域名
        pod-ip-address.my-namespace.pod.cluster.local  A记录Pod域名
        pod-ip-address 为pod的ip地址 my-namespace 为命名空间默认空间为 default。 pod.cluster.local 为pod域名
      ```
    • 安装配置UI

      • 官方yaml配置在kubernetes/cluster/addons/dashboard 目录
      • dashboard-service.yaml 无修改;
      • dashboard-controller.yaml 修改镜像地址image=dudureg.xip.io:5000/kubernetes-dashboard-amd64:v1.6.0
      • kubectl get services kubernetes-dashboard -n kube-system 查看服务
      • kubectl get deployment kubernetes-dashboard -n kube-system
      • kubectl get pods -n kube-system | grep dashboard
      • 访问方式 IP加端口号;kube-apiserver 接口访问;代理访问kubectl proxy
      • kubectl proxy --address='172.20.0.113' --port=8086 --accept-hosts='^*$' 启动代理
      • kubectl cluster-info 获取集群服务地址
    • 集群配置CA签名双向数字证书认证(可选)

      • 所有对apiserver的访问,都是用安全方式https端口443,并且可以对外网提供服务
      • 在安全的内网可以使用非安全的访问模式,默认也是非安全模式

          openssl genrsa -out rootCA.key 2048
          openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=$NGROK_DOMAIN" -days 3650 -out rootCA.pem
          openssl genrsa -out device.key 2048

        basic_auth.csv - 基本的用户和密码
        ca.crt - 证书颁发机构证书
        known_tokens.csv - 令实体(例如,kubelet)可以用来与apiserver通信
        kubecfg.crt - 客户端证书,公钥
        kubecfg.key - 客户端证书,私钥
        server.cert - 服务器证书,公钥
        server.key - 服务器证书,私钥

    • 集群外部访问集群内Pod或Service

      • 设置Pod将容器端口映射到物理机端口上,通过物理机IP加端口号访问
      • 设置Service将服务端口号映射到物理机端口上,通过物理机IP加端口号访问
      • 直接访问apiserver

        需要apiserver 配置--bind-address=0.0.0.0
        将证书转换格式
        openssl pkcs12 -export -in apiserver.pem  -out apiserver.p12 -inkey apiserver-key.pem
        在转换过程中可以配置一个密码,tongxingsheng123,再导入的时候需要使用这个密码
        
        
        就可以使用主机IP地址加6443安全端口号访问
        获取访问路径
        kubectl cluster-info
        Kubernetes master is running at https://121.42.248.198:6443
        
        Kibana is running at https://121.42.248.198:6443/api/v1/proxy/namespaces/kube-system/services/kibana-logging
        KubeDNS is running at https://121.42.248.198:6443/api/v1/proxy/namespaces/kube-system/services/kube-dns
        kubernetes-dashboard is running at https://121.42.248.198:6443/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard
        monitoring-grafana is running at https://121.42.248.198:6443/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana
        
    • 二进制安装
    cp -r server/bin/{kube-apiserver,kube-controller-manager,kube-scheduler,kubectl,kube-proxy,kubelet} /root/local/bin/
    

    常用操作命令

    • kubectl命令格式为 kubectl 子命令 资源类型 资源名 参数 -o=输出日志格式
    • 可操作的常用资源类型有:

      • deployments 、rc 副本控制
      • events 事件
      • endpoints
      • hpa 横向扩展
      • nodes 节点
      • namespaces 命名空间
      • pods
      • pv 数据卷
      • services 服务
    • 常用子命令:

      • apply 从配置文件对资源更新
      • cordon 将node隔离出集群调度
      • create 从配置文件中创建资源对象
      • delete 从配置文件资源名或标签选择器删除资源对象
      • describe 描述资源对象的详细信息
      • drain 隔离node节点并删除上面的所有pod
      • exec pod名 -c 容器名 命令 :在指定容器中执行命令
      • get 显示资源对象概要信息
      • logs 在屏幕打印一个容器的日志
      • rolling-update 对RC进行滚动升级
      • scale 扩容缩容pod的数量
      • set 修改容器的镜像
      • label 设置或更改资源对象的标签
    • 输出日志格式(可选参数)json、yaml、wide额外信息
    • kubectl create -f 资源定义文件.yaml 创建资源,pod、server、deployment、RC
    • kubectl get rc 查看创建的RC文件
    • kubectl get pods 查看所有创建的pod
    • kubectl describe pod pod的名字 查看具体某一个pod的信息
    • kubectl get nodes 查看集群中的node
    • kubectl describe noe node的名字 查看具体某一个node的信息,Ready状态表示正常
    • kubectl get deployments 查看所有创建的deployments
    • kubectl describe deployments 查看具体deployments控制的pod扩展过程
    • kubectl scale rc php-slave --replicas=3 手动实现pod扩容缩容
    • kubectl get endpoints 查看服务的端点Pod列表
    • kubectl exec -ti pod名 /bin/bash 登录指定容器 /bin/ash
    • kubectl logs pod名 查看容器日志
    • kubectl logs -f pod名 -c 容器名 跟踪查看指定容器日志
    • kubectl describe configmap 配置名 查看配置信息

    配置

    • Pod资源完整定义,推荐不要直接创建Pod,而是通过RC的模板定义Pod。哪怕只用到一个Pod副本,也强烈建议使用RC来定义

      apiVersion: v1  #版本号
      kind: Pod    # kind定义这个一个pod资源
      metadata:
        name: myweb   #定义pod名字
        namespace: string #命名空间
        labels:       #定义标签
          name:myweb
      spec:     #定义pod里容器属性
        containers:
        - name: myweb   #定义容器名
          image: kuberguide/tomcat-app:v1   #定义容器使用镜像
          imagePullPolicy:[Always|Never|IfNotPresent]每次都重新下载镜像|仅使用本地镜像|先使用本地镜像,不存在再下载镜像。默认每次重新下载镜像Always
          command:[string] #容器启动命令列表
          args:[string]#容器启动命令参数列表
          workingDir:string #容器工作目录
          volumeMounts: #挂载到容器的存储卷
            - name: string  #使用pod定义的共享存储卷名称
              mountPath:string 存储卷在容器内挂载的绝对路径,应少于512字符
      ports:      #定义容器开放暴露的端口号列表
      - containerPort: 8080   #定义pod对外开放的服务端口号,容器要监听的端口
      env:    #定义容器变量列表
      - name: MYSQL_SERVICE_HOST
        value: 'mysql'
      resources: #资源限制设置
        limits:  
          cpu: string   #容器启动后最多可用CPU核数。
          memory:string  #容器启动最多可用内存数 单位MiB、GiB
        requests:#最低启动限制设置
          cpu: string  #最低容器启动可用CPU核数。
          memory:string  #最低容器启动可用内存数 单位MiB、GiB
      restartPolicy:[Always|Never|OnFailure]#pod重启策略,一旦终止立即重启|终止后报告错误后不再重启|只有非0错误码终止才重启其他不重启。默认Always
      nodeSelector: #设置调度pod到指定这里配置的labe的Node上
        标签key:标签value
      imagePullSecrets: #拉取镜像时使用的秘钥信息
        - key:string 
      volumes: #pod的共享存储卷列表
        - name: string #存储卷名,唯一
          emptyDir:{}  #存储卷类型,生命周期和pod相同,临时目录
          hostPath:    #存储卷类型,表示从宿主机目录上挂载
            path: string  #使用的宿主机目录
          secret:  #存储卷类型。
            secretName: string
            items:
              - key: string
                path: stirng
          configMap:  #存储卷类型
            name: string
            items:
              - key: string
                path: sting
      livenessProbe: #Pod内容器健康检查设置,无响应之后自动重启该容器
        exec: #检查类型,仅需使用其中一种。
          command:[string]  #命令或脚本
        httpGet: #检查类型,仅需使用其中一种。
          path: string
          port: number
          host: string
          scheme: string
          httpHeaders:
          - name: string
            value: string
        tcpSocket:  #检查类型,仅需使用其中一种
          port: number
        initialDelaySeconds:0 #容器重启完成后,首次探测的间隔时间单位秒
        timeoutSeconds:0 #容器探测等待响应超时时间,单位秒。默认1秒,超时认为不健康重启
        periodSeconds:0 #容器探测间隔时间,单位秒,默认10秒。
        successThreshold:0
        failureThreshold:0
        securityContext:
          privileged: false
      
    * Service 服务资源完整定义

    apiVersion: v1
    kind: Service
    metadata: #元数据

    name: string #服务名
    namespace:string #命名空间
    labels:
      - name: string  #标签列表

    spec:

    selector: [] #标签选择器
    type: string  #服务访问方式默认ClusterIP访问、NodePort使用宿主机端口、
    clusterIP: string #指定服务IP地址,不指定系统分配
    sessionAffinity: ClientIP #是否支持session默认为空轮询负载,ClientIP模式同一个客户端IP请求发到同一pod
    ports:  #服务开放的端口列表
    - name: string #端口名
      protocol: string  #端口协议 默认TCP  可选UDP
      port: int  #服务监听端口号
      targetPort: int #转发到后端Pod端口号
      nodePort: int #映射到宿主机的端口号
    status:  #外部均衡器设置
      loadBalancer:
        ingress:
          ip: string
          hostname: string
    * RC 副本控制资源完整定义
     * 确保集群中Pod数量就是RC定义中的数量
     * 通过RC中的replicas属性来实现系统扩容和缩容
     * 通过改变RC中的Pod模板主要是镜像版本,实现系统的滚动升级
    apiVersion: v1
    kind: ReplicationController
    metadata:
      name: mysql
    spec:
      replicas: 1 #副本数量
      selector:
        name: mysql-pod
      template:
        metadata:
          labels:
            name: mysql-pod
        spec:
          containers:
            - name: php-redis
              image: redis
              env:
                - name: HOSTS
                  value: 1111
              ports:
                - containerPort: 90
                  .......
    ```
    • Secret私密凭据资源完整定义

      • 存放私密数据,如密码;OAuth TOken、ssh keys
      • 使用:在Docker镜像下载时使用:指定Pod的ImagePullSecrets来引用
      • 挂载该secret到Pod来使用,然后访问目录中的文件来获取数据
      • 在pod创建时,为pod指定ServiceAccount来自动使用该secret
      • 在更新Secret之后,需要删除旧的Pod,再创建一个新的Pod,更新secret的流程和部署一个新的image是一样的

        apiVersion: v1
        kind: Secret
        metadata:
          name: my_secret
        type: Opaque
        data:
          password: 1111
          username: 2222
        ---
        kind:pod
        .....
        volumes:
          - name: foo
            secret:
    ......
    ----
    kind:pod
    spec:
      containers:
        - name: foo
          image: redis
      imagePullSecrets:
        - name: my_registrykey  #拉取镜像使用
    ```
    • 要求:

      • Master:至少1核、2G内存;推荐2核、4G内存,
      • 谷歌推荐管理1-5个node节点服务器配置1cpu 4G内存 6-10node 2cpu 8G内存 11-100node 4cpu 15G内存 101-250node 8CPU 30G内存
      • Node:至少1核、2G内存;推荐安装需要运行的容器数量进行调整
      • 内核系统要求:3.10以上、64位系统、如CentOS7、RedHat7
      • Docker要求:至少1.9以上;推荐1.12,目前最新1.13 也就是17.03.1-ce这版
      • etcd要求:至少2.0以上;推荐3.0.7版本

    功能

    kubeconfig 文件

    • https://kubernetes.io/docs/co...
    • 使用命令修改添加配置集群选项 kubectl config set-cluster 选项
    • 使用命令修改用户部分选项 kubectl config set-credentials
    • 使用命令修改上下文部分 kubectl config set-context
    • 使用命令查看当前加载的配置 kubectl config view
    • 分为集群部分、用户部分、上下文部分

      current-context: federal-context
      apiVersion: v1
      clusters:
      - cluster:
          api-version: v1
          server: http://cow.org:8080
        name: cow-cluster
      - cluster:
          certificate-authority: path/to/my/cafile
          server: https://horse.org:4443
        name: horse-cluster
      - cluster:
          insecure-skip-tls-verify: true
          server: https://pig.org:443

    contexts:

    • context:

      cluster: horse-cluster
      namespace: chisel-ns
      user: green-user

      name: federal-context

    • context:

      cluster: pig-cluster
      namespace: saw-ns
      user: black-user

      name: queen-anne-context

    kind: Config
    users:

    • name: blue-user
      user:
      token: blue-token
    • name: green-user
      user:
      client-certificate: path/to/my/client/cert
      client-key: path/to/my/client/key
    • 默认主机Master的apiserver服务监听8080端口提供REST服务

      Node的隔离和恢复

    • 在升级Node硬件或维护的情况下,将Node隔离,脱离Kubernetes的调度范围:
    • 脱离之后,系统不会在该nod上创建pod,但已经创建运行的pod不会自动停止,需要手动停止

    apiVersion: v1
    kind: Node
    metadata:

    name:k8s-node-1
    labels:
      hostname: k8s-node-1

    spec:

    unschedulable:  true    #表示脱离调度,设置false表示恢复调度
    

    #完成修改命令
    kubectl replace -f unschedule node.yaml
    #查看node状态,会有所变化
    kubectl get nodes

    * 通过命令操作:
    * kubectl cordon k8s-node-1  隔离
    * kubectl uncordon k8s-node-1 恢复
    
    ### Node扩容,加入新node节点
    * 使用ansible 安装node组件和docker
    
    ### 集群环境分组隔离
    * 如开发环境、生产环境、测试环境、试错环境、第三方开放服务环境、管理后台环境、内部不同业务组紫色医疗和嘟嘟医生,都可以在一个kubernetes集群中,在不同空间,资源隔离互不影响
    * 创建对应命名空间 kubectl create -f namespace-test.yaml

    apiVersion: v1
    kind: Namespace
    metadata:

    name: development

    ---
    apiVersion: v1
    kind: Namespace
    metadata:

    name: test
    

    #查看命名空间
    kubectl get namespaces

    * 命令行创建命名空间 kubectl create namespace test
    * 定义运行环境Context,为每个命名空间定义一个运行环境

    #定义集群
    kubectl config set-cluster kubernetes-cluster --server=https://192.168.1.128.8080
    #定义开发环境的运行环境名、使用的命名空间、使用的集群、
    kubectl config set-cluster ctx-dev --namespace=development --cluster=kubernetes-cluster --user=dev
    #定义测试环境的运行环境名、使用的命名空间、使用的集群、
    kubectl config set-cluster ctx-test --namespace=test --cluster=kubernetes-cluster --user=test

    #查看定义的运行环境Context
    kubectl config view

    * 切换当前运行环境,切换之后操作创建的资源都在对应分组环境下,互不干扰

    kubectl Config use-context ctx-dev 或切换测试环境
    kubectl Config use-context ctx-test

    ### 全局cpu内存资源管理配置limitRange
    * 默认不设置资源限制,pod中的容器会无限制使用内存和cpu。
    * 通过Pod中的资源限制可以限制每一个容器使用的内存cpu。但设置每一个pod比较繁琐。可以全局配置统一
    * 可以一次限制一个命名空间运行环境下所有容器的最大使用cpu和内存数,给每个不同空间分组不同资源数。

    apiVersion: v1
    kind: LimitRange
    metadata:

    name: my_limits

    spec:

    limits:
      - max:#是pod中所有容器的最高上限的总和,一个pod所有容器加起来不能超过
          cpu: "4"
          memory: 2Gi
        min: #是pod中所有容器的最低下限的总和,一个pod所有容器加起来不能少于
          cpu: 50m
          memory: 100Mi
        maxLimitRequestRatio: #限制pod中所有容器的limits值总和和requests值总和的比例上限
          cpu: 3
          memory: 2
        type: pod
      - default:  #pod中所有未指定限制的容器的上限,值要小于等于max配置的
          cpu: 300m
          memory: 200Mi
        defaultRequest: #Pod中所有未指定限制的容器的下限,只要小于等于default
          cpu: 200m
          memory:100Mi
        max: #pod中所有容器的上限,
          cpu: "2"
          memory: 1Gi
        min: #pod中所有容器的下限,值要小于等于defaultRequest配置的
          cpu: 100m
          memory: 3Mi
        maxLimitRequestRatio: #限制pod中所有容器的limits值和requests值的比例上限
          cpu: 5
          memory: 4
        type: Container

    #在使用的命名空间分组创建全局配置
    kubectl create -f limits.yaml --namespace=limit-example
    #在使用命名空间分组中查看全局限制配置
    kubectl describe limits my_limits --namespace=limit-example

    ### pod服务可靠性
    * 一个pod中所有容器都设置了资源限制。并所有容器的Limits值和Requests值全部相等不为0
    * 这样的Pod服务在整个集群中是完全可靠的。在资源不够的情况下,最最后才会被杀掉进程释放资源
    * 关键服务需要这样的设置,保证服务可靠性
    
    ### Etcd服务高可用
    * 部署成为集群形式,存储数据使用高可用的存储设备,备份保存,如阿里OSS
    * kube-apiserver启动参数配置etcd。使用内网IP
    * --etcd-servers=http://10.0.0.1:2379,http://10.0.0.1:2380,http://10.0.0.1:2381,
    * 可以部署在同一个服务器上,启动不同端口号;
    * 可以部署在docker中,启动多个容器,使用宿主机的端口;方便之后扩展以及升级
    * 可以部署在不同服务器上,不同IP,相同端口号;
    * 可以只部署一个服务,使用守护进程监控,挂机自动重启。
    
    ### Master高可用
    * 由于系统不支持多个Master的配置和etcd不同,所以集群部署方式需要使用负载均衡。
    * kube-apiserver、kub-controller-manager、kube-scheduler安装在不同服务器中,需要负载均衡haproxy和keepalived健康监控。访问kube-apiserver需要使用负载均衡的地址。另外两个组件需要配置--leader-elect=true配置选举出leader。部署在多台服务器中
    * 部署在一台服务器中,使用守护进程监控。
    * 部署在一台服务器中,使用容器启动,使用宿主机端口。方便之后扩展以及升级
    
    ## 集群监控 cAdvisor + Heapster + Influxdb + Grafana
    * http://grafana.org
    * http://influxdb.com
    * https://github.com/google/cadvisor
    * https://github.com/kubernetes/heapster/releases  下载最新版Heapster
    * 集群默认集成cAdvisor监控容器的运行状态。采集node性能指标以及node上运行的容器性能指标
    * kubelet启动时自动启动cAdvisor服务。在每台Node中运行,单独监控单个Node。对外服务端口号作为web页面查看:4194。访问每个nodeIp地址:4194端口
    * cAdvisor + Heapster + Influxdb + Grafana :集群所有容器Node节点监控。
    * Heapster:访问每台Node中cAdvisor的api接口获取数据汇总保存到Influxdb。
    * Influxdb:分布式时序数据库,每条记录带有时间戳。用于实时的数据采集,事件跟踪,存储时间图表,原始数据。
    * Grafana:通过web界面将Influxdb中的时序数据展现成图表
    * 安装部署:使用Pod部署,创建3个服务,Influxdb + Grafana创建在同一个Pod中,Heapster在一个Pod中
    * Heapster服务 + Influxdb服务都在同一个命名空间中kube-system,不需要区分用户分组
    * Influxdb 服务可以通过主机端口号提供访问,通过web界面查看数据
    * Grafana 服务可以通过Master的代理模式访问
    * Heapster 需要和Master进行安全连接,需要设置CA证书安全模式
    * 安装

    wget https://github.com/kubernetes...
    unzip v1.3.0.zip
    mv v1.3.0.zip heapster-1.3.0
    cd heapster-1.3.0/deploy/kube-config/influxdb

    grafana-deployment.yaml 配置
    修改image=dudureg.xip.io:5000/heapster-grafana-amd64:v4.0.2
    开启value: /api/v1/proxy/namespaces/kube-system/services/monitoring-grafana/
    注释#value:/
    为了后续使用 kube-apiserver 或者 kubectl proxy 访问 grafana dashboard

    heapster-deployment 配置
    修改image=dudureg.xip.io:5000/heapster-amd64:v1.3.0

    influxdb-deployment 配置
    修改image=dudureg.xip.io:5000/heapster-influxdb-amd64:v1.1.1
    修改 数据卷
    # emptyDir: {}
    hostPath:

      path: home/nfs/influxdb_db 
    

    时区配置
    volumeMounts:

        - name: tz-config
          mountPath: /etc/localtime

    volumes:

      - name: tz-config
        hostPath:
          path: /usr/share/zoneinfo/Asia/Shanghai

    创建所有资源
    kubectl create -f .
    检查
    kubectl get deployments -n kube-system | grep -E 'heapster|monitoring'
    检查pods
    kubectl get pods -n kube-system | grep -E 'heapster|monitoring'
    查看api服务请求地址
    kubectl cluster-info
    monitoring-grafana is running at https://10.29.167.233:6443/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana
    monitoring-influxdb is running at https://10.29.167.233:6443/api/v1/proxy/namespaces/kube-system/services/monitoring-influxdb
    创建代理访问
    kubectl proxy --address='121.42.248.198' --port=8086 --accept-hosts='^*$'
    浏览器访问
    http://121.42.248.198:8086/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana

    
    ### 集群日志 Fluentd + ElasticSearch + Kibana
    * 需要配置CA证书安全模式、需要DNS服务
    * 服务运行在命名空间kube-system中
    * 容器中服务的日志集中输出到Node主机指定目录下
    * Fluentd: 在每个Node中运行一个容器,针对Node中的日志目录采集日志,保存到ElasticSearch
    * ElasticSearch:保存数据以及索引,需要集群模式分担负载。
    * 安装部署:DaemonSet模式在每台Node中启动Fluentd服务Pod容器
    * 每个组件都创建自己的rc和服务。使用kubectl cluster-info查看服务地址,使用kubectl proxy命令代理启动访问服务
    * 安装

    cd /home/kubernetes/cluster/addons/fluentd-elasticsearch

    es-controller.yaml 配置
    修改
    image:dudureg.xip.io:5000/elasticsearch:v2.4.1-2
    修改 数据卷
    # emptyDir: {}
    hostPath:

      path: /home/nfs/elasticsearch_db 
    

    fluentd-es-ds.yaml 配置
    修改
    image:dudureg.xip.io:5000/fluentd-elasticsearch:1.22
    kibana-controller.yaml 配置
    修改
    image:dudureg.xip.io:5000/kibana:v4.6.1-1

    时区配置
    volumeMounts:

        - name: tz-config
          mountPath: /etc/localtime

    volumes:

      - name: tz-config
        hostPath:
          path: /usr/share/zoneinfo/Asia/Shanghai
          

    查看节点
    kubectl get nodes
    给节点服务器打标签
    kubectl label nodes 10.29.168.24 beta.kubernetes.io/fluentd-ds-ready=true
    kubectl label nodes 10.29.167.186 beta.kubernetes.io/fluentd-ds-ready=true
    定义 DaemonSet fluentd-es-v1.22 时设置了 nodeSelector beta.kubernetes.io/fluentd-ds-ready=true ,所以需要在期望运行 fluentd 的 Node 上设置该标签
    创建资源
    kubectl create -f .

    查看
    kubectl get deployment -n kube-system|grep kibana
    kubectl get pods -n kube-system|grep -E 'elasticsearch|fluentd|kibana'
    kubectl get service -n kube-system|grep -E 'elasticsearch|kibana'

    kibana Pod 第一次启动时会用较长时间(10-20分钟)来优化和 Cache 状态页面,可以 tailf 该 Pod 的日志观察进度:
    kubectl logs kibana-logging-3358050253-xpwpz -n kube-system -f

    api服务访问
    kubectl cluster-info
    代理访问
    kubectl proxy --address='121.42.248.198' --port=8087 --accept-hosts='^*$'
    http://121.42.248.198:8087/api/v1/proxy/namespaces/kube-system/services/kibana-logging

    在 Settings -> Indices 页面创建一个 index(相当于 mysql 中的一个 database),选中 Index contains time-based events,使用默认的 logstash-* pattern,点击 Create ;

    如果你在这里发现Create按钮是灰色的无法点击,且Time-filed name中没有选项,fluentd要读取/var/log/containers/目录下的log日志,这些日志是从/var/lib/docker/containers/${CONTAINER_ID}/${CONTAINER_ID}-json.log链接过来的,查看你的docker配置,—log-driver需要设置为json-file格式,默认的可能是journald,参考docker logging。

    
    ### 报警提醒 AlertManager、ElastAlert、Stackdriver
    
    
    ### API网关服务 Kong + Cassandra
    * Cassandra:分布式NoSql数据库
    * Kong:需要在每台Node节点中运行服务。使用DaemonSet模式
    
    ### 事务追踪系统 Appdash、淘宝鹰眼、Zipkin
    
    ### 后台任务处理系统 Resque、Sidekiq、Delayed_job
    
    ### 事件驱动消息队列 Redis、Mq、Gearman
    
    ### CI/CD持续集成 Jenkins
    
    ### 负载均衡 Traefik、Nginx、LVS、HAProxy
    
    ### PHP7环境 部署
    * 1. php服务包括nginx、php-fpm、memcache、scribe等几大组件。
    * 2. 将PHP服务相关的组件制作成一个镜像。服务通过容器命令来启动。nginx+php+memecache
    * 3. 代码、配置、日志等经常变更部分通过挂载的方式和docker容器互动。代码镜像使用busybox为基础,大小仅1M
    * 镜像制作
    1. 从镜像仓库里拉去CentOS作为基础镜像。
    2. 运行镜像
    3. 在运行容器中安装PHP环境相关软件包。
    4. 提交修改并推送至仓库。
    5.     PHP服务镜像制作完毕
    * 代码镜像制作
    1. Dockerfile

    FROM registry.x.weibo.com/qinglong/busybox
    RUN mkdir -p /code/x.weibo.com
    ADD x.weibo.com /code/x.weibo.com

    1. Build

    registry.x.weibo.com/codeimg_x_weibo_com_git:324234

    1. 下载代码镜像、启动容器、拷贝代码

    docker pull registry.x.weibo.com/codeimg_x_weibo_com_git:324234
    docker run -name=code_container -t -i -d /phpcode codeimg_x_weibo_com_git:
    324234
    docker exec code_container cp -R /phpcode /code/x.weibo.com

    * 配置文件镜像制作
    * 配置文件制作成docker镜像
    * 每台机器拉取镜像,替换配置文件
    * 自定义脚本执行reload 重启加载新配置文件生效
    * 容器的优雅重启采用docker    exec    xx    reload 命令
    
    
    ### 复用包管理  Helm Chart
    * 是一个用于Kubernetes的包管理工具,自动安装流行软件包,可重复构建,可配合持续化集成
    * https://github.com/kubernetes/helm 
    * 分为客户端和服务端,客户端安装在笔记本上,服务端在集群中运行。
    * 客户端安装:brew install kubernetes-helm
    * 服务端安装:

    #Kubernetes 必须 1.4.1以上,本地必须有kubectl命令工具
    #通过读取$HOME/.kube/config 路径下的Kubernetes配置文件来决定安装服务端的环境,和kubectl命令工具使用的是同一个配置文件
    #查看安装到哪个集群,查看当前运行环境
    kubectl config current-context
    #本地初始化:helm init --kube-context=安装到指定集群,默认为当前环境
    #升级服务端:helm init --upgrade
    #helm同样需要从谷歌拉取镜像,需要在本地仓库保存一份
    #镜像使用问题,如果包配置中使用镜像拉取策略是使用远程的镜像,可以去kubernetes的UI界面中修改调度配置文件改成imagePullPolicy:IfNotPresent 即可或者使用命令行修改更新,或直接修改使用的镜像文件为本地的

    * 安装流程软件包:同一个包可以多次在同一集群环境中安装,并都能单独管理升级
    * helm search 查看可安装的包列表
    * helm repo update 更新资源列表;
    * helm install stable/mysql --name 新名字 安装稳定版  kubectl describe services 查看服务
    * helm inspect stable/mysql 了解查看包功能
    * helm ls  查看已经发布的包
    * helm list 查看已经部署的包
    * helm delete 发布包名  删除发布的包
    * helm status 发布包名  查看发布的包状态,配置信息,ip等信息
    * helm rollback happy-panda 1 回滚包
    * helm upgrade 升级包
    * helm get -h 帮助命令
    * helm --debug 调试模式,输出命令的具体执行信息
    * https://github.com/kubernetes/charts/tree/master/stable/  常见包github地址
    * 常见包stable/datadog、stable/grafana、stable/influxdb、stable/jenkins、stable/memcached、stable/mongodb、stable/mysql、stable/redis、stable/postgresql、stable/openvpn、stable/rabbitmq、stable/cockroachdb数据库、stable/traefik负载均衡、stable/testlink测试软件、stable/owncloud私有云、stable/minio分布式存储、stable/redmine项目管理、stable/prometheus服务监控系统、stable/gitlab-ce版本管理、
    * stable/wordpress博客、stable/phpbb论坛、stable/prestashop电商、stable/opencart电商、stable/joomla框架、stable/drupal框架、stable/osclass分类信息系统、stable/orangehrm人力资源、stable/odoo企业ERP、stable/mediawiki百科、stable/dokuwiki微型百科、
    
    ### 垃圾回收机制
    * 集群中创建的不再使用的容器和镜像会定期被清理,每分钟清理一次容器,每5分钟清理一次镜像
    * 只能清理被kubelet管理的容器。
    * 镜像清理,只会根据磁盘的使用率来触发
    
    ## 调试
    * kubectl describe 命令很有用
    * 查询系统事件: kubectl describe pod 查看一个Pod的详细信息,其中Event事件信息对排错有用
    * 查看容器日志: kubectl logs PodName -c 容器名 
    * 注意将集群的日志在启动参数中集中配置在指定目录中。
    * 主要从Kubelet中查看Pod的完整日志、kube-controller-manager日志、kube-scheduler日志、kube-proxy日志、防火墙
    
    ## 优化
    
    ## 常见问题
    * 经常遇见谷歌域名在Mac环境下DNS解析IP地址出错,结果超时无法访问谷歌服务器下载镜像等文件
    * 可以查看域名对应解析的IP如:host kubernetes-charts.storage.googleapis.com
    * 使用ping命令ping域名出来的IP地址不一致的话可以清理DNS缓存:
    * Mac下:sudo killall -HUP mDNSResponder
    * Liunx下:systemctrl restart nscd或/etc/init.d/nscd restart
    * 时区配置

    ls -l /etc/localtime
    spec:

      containers:
      - name: my-testpod
        image: 1604podimage:latest
        volumeMounts:
        - name: tz-config
          mountPath: /etc/localtime
      volumes:
      - name: tz-config
        hostPath:
          path: /usr/share/zoneinfo/Asia/Shanghai
    
    ## 实际应用
    * https://kubernetes.io/docs/samples/ 官方范例
    
    

    carrot
    9 声望1 粉丝