文档章节

用户数从 0 到亿,我的 K8s 踩坑血泪史

阿里巴巴云原生
 阿里巴巴云原生
发布于 2019/09/03 18:34
字数 2070
阅读 32
收藏 0

file 作者 | 平名 阿里服务端开发技术专家

导读:容器服务 Kubernetes 是目前炙手可热的云原生基础设施,作者过去一年上线了一个用户数极速增长的应用:该应用一个月内日活用户从零至四千万,用户数从零到一亿的裂变式增长,充分享受了容器服务快速简便的扩容操作和高可用特性。作者使用容器服务 Kubernetes 集群将公司内系统完全上云 1 年多,本篇文章记录了其中的踩坑与优化记录。

关注“阿里巴巴云原生”公众号,回复关键词**“资料”****,即可获得 2019 全年meetup 活动 PPT 合集及 K8s 最全知识图谱。**

创建集群

创建集群时,做好规划,选择优化好的集群配置,可以大大减少后期运维工作,其中部分集群的配置在建立后再也没法修改或者修改极其麻烦。

集群规划

            Terway 是阿里云容器服务自研的网络插件,功能上完全兼容 Flannel,如果保守,还是使用 Flannel  

  • Pod 网络 CIDR

默认 16 的大网段,有效的网段或者其子网 10.0.0.0/8,172.16-31.0.0/12-16,192.168.0.0/16

  • Service CIDR

    • 默认 20 的网段,可选:10.0.0.0/16-24,172.16-31.0.0/16-24,192.168.0.0/16-24
    • 网段不能冲突重复,建立后没法修改;
    • 多个区域的多个交换机。
  • 公网访问 ApiServer

    • 对于线上等安全要求高的集群,可以选择不暴露 apiserver, 只有私网 SLB, 但是这样没法使用云效发布;
    • 日常预发等集群,可以暴露公网 SLB 到 apiserver, 集群建立后立即为 slb 建立访问控制,限制 slb 只能云效访问;

注: K8s 每次安全漏洞几乎都与 ApiServer 有关,对于线上 K8s 集群,要及时升级补丁,或者不开放公网 apiserver,使用严格的安全组和访问控制。

  • 安全组
    • 设置安全组限定访问范围,为 master 与 worker 机器使用。

 

  • Master 机器规划

   为了高可用,一般使用 3 节点,Master 选择规则如下:

节点数  master 规格
1-5个 4C8G
6-20个节点 4C16G
21-100个节点 8C32G
100-200个节点 16C64G

master 机器的存储建议高性能的 50-100G SSD,因为会运行 ETCD,操作系统占用不超过 8G。

  • Worker 机器规划
    • 阿里云首推神龙机器,没有神龙机器的区域,选用高配 ECS,配置规格根据部署的 POD 规格乘以一定倍数,比如 Java 应用 pod 一般选择 4C8G,ECS 则购买 32C64G 或者 64C128G 为好,设置部署的时候为 pod 设置固定的 request/limit;
    • 我们选用的机器配置:
      • 32C64G ECS
      • 存储。系统盘:100G SSD,  数据盘:400G 高效云盘
      • 操作系统:centos 7.4 64 位

集群建立与配置

建立集群时设置:

  • 通过控制台建立集群,阿里云容器服务提供的非常简易的一键部署集群功能,通过向导完成 K8S 集群的建立;
  • 按照以上规划设置 master,worker 节点,挂载 /var/lib/docker 到数据盘;
  • 设置合理的 Pod 网络 CIDR, Service CIDR ip 网段;
  • 设置合理的安全策略,是否暴露 apiserver(需要直接云效发布的,需要开放公网暴露,并做严格的访问控制);
  • ingress 选择安全,可以使用内网,如果需要公网,可以在控制台很方便建立,同时做好访问控制;
  • kube-proxy 模式,因为 iptables 模式在更新一条规则时把 iptables 锁住引发的性能问题,建议使用 IPVS 模式;
  • 节点 POD 数量,默认 128 太大,一个节点不可能部署这么多,建议改为 64;
  • 节点服务端口访问 (NodePort,SLB),可以适当扩大,默认的也一般足够用。

集群配置修改:

部署设置

无状态部署

使用无状态部署 Deployment,参考这篇文章实现分批发布。 优化设置模板: 

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: '34'
# 标签,映射 service
  labels:
    app: {app_name}-aone
  name: {app_name}-aone-1
  namespace: {app_name}
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: {app_name}-aone
# 批量重启更新策略      
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: {app_name}-aone
    spec:
      containers:
       # 环境变量增加时区
        - env:
            - name: TZ
              value: Asia/Shanghai
        - image: >-
            registry-vpc.cn-north-2-gov-1.aliyuncs.com/{namespace}/{app_name}:20190820190005
          imagePullPolicy: Always
          # 启动前执行优雅下线摘除 服务注册
          lifecycle:
            preStop:
              exec:
                command:
                  - sudo
                  - '-u'
                  - admin
                  - /home/{user_name}/{app_name}/bin/appctl.sh
                  - {app_name}
                  - stop
          # 存活检查,强烈建议设置        
          livenessProbe:
            failureThreshold: 10
            initialDelaySeconds: 30
            periodSeconds: 10
            successThreshold: 1
            tcpSocket:
              port: 5900
            timeoutSeconds: 1
          name: {app_name}-aone
          # 就绪检查,强烈建议设置
          readinessProbe:
            failureThreshold: 10
            initialDelaySeconds: 30
            periodSeconds: 10
            successThreshold: 1
            tcpSocket:
              port: 5900
            timeoutSeconds: 1
          # 资源限制,这个一定要合理设置  
          resources:
            limits:
              cpu: '4'
              memory: 8Gi
            requests:
              cpu: '4'
              memory: 8Gi
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          # 日志存放目录,映射到节点的/var/lib/docker/logs 数据盘,应用日志目录设置到/home/{user_name}/logs 下
          volumeMounts:
            - mountPath: /home/{user_name}/logs
              name: volume-1553755418538
      dnsPolicy: ClusterFirst
      ## 私有镜像仓库的密钥,从保密字段获取
      imagePullSecrets:
        - name: {app_name}-987
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
      # 日志存放目录,映射到节点的/var/lib/docker/logs 数据盘
      volumes:
        - hostPath:
            path: /var/lib/docker/logs/{app_name}
            type: ''
          name: volume-1553755418538

 

服务设置

因为容器服务的 Cloud Controller Manager 会同步删除 service 建立关联的 SLB,为了防止 service 配置修改误删除 slb 故障,并导致域名、安全等配置需要修改的坑,强烈建议 service 与 slb 解耦,service 采用 NodePort 的方式,slb 另外建立后端服务器指向集群节点,如果需要透传真实 IP,并考虑负载均衡,需要遵守一定的配置规则和方法,参考这个文章

NodePort:

apiVersion: v1
kind: Service
metadata:
  name: {app_name}
  namespace: {namespaces}
spec:
  clusterIP: 10.1.50.65
## 策略关系到是否透传真实 IP
  externalTrafficPolicy: Cluster
  ports:
    - name:  {app_name}-80-7001
      nodePort: 32653
      port: 80
      protocol: TCP
      targetPort: 7001
    - name:  {app_name}-5908-5908
      nodePort: 30835
      port: 5108
      protocol: TCP
      targetPort: 5108
  selector:
    app:  {app_name}
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

然后在负载均衡管理页面,选择后端服务器指向集群的 worker 机器,设置端口为以上服务的端口:32653,完成配置,这样在集群 service 修改或者删除重建的时候,slb 不会被集群的 CCM 删除,不会涉及到域名,安全等配置修改。同时,可以设置一些策略,需要升级修改服务配置时,分批切流等。

总结

阿里云容器服务控制台虽然是云上新产品,提供了极其简单的一键部署功能,以及简便的控制台管理。过去一年中,笔者一路见识阿里云容器服务控制台从简陋向强大的转变过程,虽然多次踩坑,但阿里云容器服务同学认真负责和极好的服务态度让人佩服。

容器服务管理控制台还需要更多的考虑实际运维需求,并紧密结合已有的云产品,比如云效、EDAS、云监控、日志服务等,以应用为单位,提供更好服务。


**<br />扫描下方二维码添加小助手,与 8000 位云原生爱好者讨论技术趋势,实战进阶!<br />进群暗号:公司-岗位-城市<br /> file

© 著作权归作者所有

阿里巴巴云原生

阿里巴巴云原生

粉丝 65
博文 270
码字总数 873653
作品 0
杭州
私信 提问
加载中

评论(0)

【详记MySql问题大全集】四、设置MySql大小写敏感(踩坑血泪史)

系列目录 一、安装MySql 二、安装并破解Navicat 三、没有my.in配置文件怎么办 四、设置MySql的大小写敏感 五、重置MySql登陆密码 这一篇可以说是我的踩坑的血泪史了。。。 MySql在Windows下默...

在7楼
2018/07/30
0
0
不过劳动劫!技术人完美渡劫的七个姿势

五一劳动节近在眼前,连上6天班盼来的3天小长假格外可贵,但小编发现,不少兄台在假期里还要加班加点、忙碌不堪……也是,做IT的,谁不是一不小心踩个坑,两三倍的工作时间就耗进去了,瞬间劳...

助你渡劫的DBAplus社群
2018/04/28
0
0
JupyterHub Multiple Profiles实现

记录一下JupyterHub on k8s中,关于Multiple Profiles的实现方式。 JupyterHub很重要的一点功能就是实现用户NoteBook环境的定制化,JupyterHub设计出Profiles的概念。 在目前版本的JupyterHu...

北邮郭大宝
2019/12/19
0
0
解压时,慎用sudo!!!

在解压时,慎用sudo!!! 因为用了sudo之后,解压后得到的文件(夹)的属主和属组,全部是root;如果你是普通用户,在用到脚本执行程序时,没有注意到这些,用通常普通命令就能正常运行的程...

Airship
2016/01/23
36
0
Kubernetes使用Ceph动态卷部署应用

Kubernetes使用Ceph动态卷部署应用 [TOC] 1. 环境准备 可用的kubernetes,版本1.11.1 可用的Ceph集群,版本luminous Ceph monitor节点:lab1、lab2、lab3 GO语言环境和kubernetes-incubator/...

ygqygq2
2018/08/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

我可以在一个表中拥有多个主键吗?

我可以在一个表中拥有多个主键吗? #1楼 以比我能做的更好的方式给出了良好的技术答案。 我只能添加到这个主题: 如果你想要一些不允许/不可接受的东西,那么就有理由退一步。 理解为什么它不...

javail
14分钟前
62
0
Redis服务安全加固的说明

Redis(全称:Remote Dictionary Server 远程字典服务)是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 漏洞描述 Redi...

老孟的Linux私房菜
15分钟前
61
0
51单片机程序执行流程详细分析

单片机是没有上操作系统的东西,在keil中编写的代码都是裸机代码,深入编写裸机代码有助于了解硬件的特性。 若不是硬件特性已定的情况之下的其它流程都是代码作祟。忽然想到来探探51单片机的...

demyar
23分钟前
35
0
【ZStack学堂】第三季第2期:边缘计算平台ZStack Mini产品介绍(高清视频回顾)

本期我们邀请到ZStack产品经理 李慧敏,为大家进行边缘计算平台ZStack Mini产品的相关介绍: 1、ZStack Mini是什么? 2、产品特性及优势 3、ZStack Mini诞生背景 4、亮点功能介绍 感兴趣的伙...

ZStack社区版
28分钟前
54
0
Centos8 安装 docker-19.03.6

# 添加docker用户, 并把当前用户添加到docker组内, 是为了当前用户拥有操作docker的权限sudo useradd -m dockersudo usermod -a -G docker k8s# 关闭防火墙sudo systemctl stop firewa...

古世界
30分钟前
47
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部