0

做微服务研发工程师的一年来的总结 - 紫色飞猪

 1 year ago
source link: https://www.cnblogs.com/zisefeizhu/p/16451495.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

18年的那个留校夏天,极其偶然接触到了《Docker+Kubernetes》,由纯运维的发展方向转到了云原生的发展方向。19年5月以《linux helmsman platform》获得IT创新大赛二等奖,其实质是围绕云原生的边侧服务集成部署。20年5月以《基于Kubernetes的舵手集群系统的设计与实现》获得河南省优秀毕业论文,其实质是在《linux helmsman platform》的基础上进行补丁而成。20年6月初在创业型公司做唯一的云原生运维,那是段足以影响一生的经历:https://www.cnblogs.com/zisefeizhu/p/14601287.html
21年6月底极其偶然的机会(面的kubernetes运维岗,入职了微服务研发工程师岗)来到这家公司以微服务研发工程师的角色实质开启纯研发历程,至今已一年有余。在项目空闲期回忆这一年的路程,承上启下。

一年来做的项目

这一年来重点围绕以下项目展开:

1)、 独立开发xxx项目的混合云容器模块:运用go+gin+gorm+mysql+client-go+kubernetes技术栈,实现对kubernetes集群的创建/导入、节点的管理、名称空间的管理、工作负载的管理、配置中心的管理、...、凭证的管理、镜像仓库的适配(harbor/acr/ccr/aws)、集群的适配(tke/ack/aws/自建集群)、等功能。总的来说此项目主要是api的对接,并不具备复杂的技术栈,在实际开发中最大的收获是:1、根据需求实现业务的开发考量 2、对各厂商的字段封装 3、开发中遇到问题的实际处理(1、返回错误信息 2、列表类接口的错误处理 3、数据库字段的设计 4、api接口的设计 5、适配层的转换 6、面向错误的开发)。期间思考了下图

1464583-20220706164438043-774329557.png
  • ps:上图只是个人对容器平台的构想,实际项目中并没有用此构思,所以谈不上涉密问题。
func Init(g *gin.Engine) {
	// 跨域
	g.Use(Cors())
	// 定义输出日志格式
	g.Use(middleware.LoggerToFile())
	g.Any("/", v1.Hello)
	g.GET("/health", v1.Health)
	api := g.Group("/container/api")
	clusterRouters(api)
	nodeRouters(api)
	nsRouters(api)
	workloadRouters(api)
	podRouters(api)
	pluginRouters(api)
	registryRouters(api)
	credentialRouters(api)
	configRouters(api)
	csiRouters(api)
	g.GET("/swagger/*any", gs.WrapHandler(swaggerFiles.Handler))
}

2)、根据开发devops同事的需求,独自设计与实现(运用helm+kubernetes技术栈)jenkins集群+插件的一键部署。总体来说此项目并不复杂,更多的是考验helm的书写与合理的利用kubernetes的特性。实际构思图如下:

1464583-20220706170545935-763688939.png
# Default values for jenkins.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
# By zisefeizhu
# Time 2021年 8月26日 星期四 10时45分56秒 CST

# namespaceOverride jenkins部署到的名称空间
namespaceOverride: devops

securityContext:
  enabled: true
  privileged: true
  runAsUser: 0
# replicaCount 副本数
replicaCount: 1

# image 镜像信息
image:
  repository: registry.cn-shenzhen.aliyuncs.com/zisefeizhu/annet
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: "jenkinsci-blueocean-v0.1.1"
  baseImageTag: "jenkins-plugins-v0.1.4"

# dockerRegistry Concentrated verification of consciousness
dockerRegistry:
  enabled: true
  secretName: jenkins
  user: xxxx
  password: xxxxxx


# containerPorts jenkins pod 端口
containers:
  ports:
  - containerPort: 8080
    name: web
    protocol: TCP
  - containerPort: 50000
    name: agent
    protocol: TCP

nameOverride: ""
fullnameOverride: ""

serviceAccount:
  # Specifies whether a service account should be created
  create: true
  # Annotations to add to the service account
  annotations: {}
  # The name of the service account to use.
  # If not set and create is true, a name is generated using the fullname template
  name: ""

# service 类型和端口信息
service:
  ports:
  - name: web
    port: 8080
    targetPort: web
    nodePort: 31031
  - name: agent
    port: 50000
    targetPort: agent
  type: NodePort
#  port: 31031   #端口

# pvc的access类型
pvc:
  enabled: true
  scName: xxxx
  accessModes: ReadWriteMany
  storage: xxx

ingress:
  enabled: false
  className: ""
  annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  hosts:
    - host: chart-example.local
      paths:
        - path: /
          pathType: ImplementationSpecific
  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local

# resources limit range obtained from pressure measurement
resources:
  enabled: falase
  limits:
    cpu: 1
    memory: 1Gi
  requests:
    cpu: 200m
    memory: 512Mi

# startupProbe 存活性探针
startupProbe:
  enabled: false
  probe:
    failureThreshold: 3
    httpGet:
      path: /login
      port: 8080
      scheme: HTTP
    initialDelaySeconds: 30
    periodSeconds: 10
    successThreshold: 1
    timeoutSeconds: 1

# livenessProbe 存活性探针
livenessProbe:
  enabled: false
  probe:
    failureThreshold: 3
    httpGet:
      path: /login
      port: 8080
      scheme: HTTP
    initialDelaySeconds: 30
    periodSeconds: 10
    successThreshold: 1
    timeoutSeconds: 5

# readinessProbe 就绪性探针
readinessProbe:
  enabled: false
  probe:
    failureThreshold: 3
    httpGet:
      path: /login
      port: 8080
      scheme: HTTP
    initialDelaySeconds: 30
    periodSeconds: 10
    successThreshold: 1
    timeoutSeconds: 5

autoscaling:
  enabled: true
  minReplicas: 1
  maxReplicas: 10
  targetCPUUtilizationPercentage: 80
  targetMemoryUtilizationPercentage: 80

3)、根据架构师构思(16年工作经验),独自验证/输出文档,运用:logstash+ceph+operator技术栈。实现es集群之间的全量/增量/全量+增量同步迁移、持久化队列/死信等功能。此项目具有一定复杂度。在实际开发中需要1、对logstash有一定程度的运用(需要对涉及到的功能点进行一一验证实践)、2、对operator有一定的掌握(特别是对spec和status的深度理解)。3、对k8s有较深度的掌握,理解涉及到的核心资源的运用。

1464583-20220706164544366-707610164.png
  • 架构图及源码涉密。

4)、近期为了加深operator的理解,写了workload-operator,实现对deployments/statefulsets/daemonsets/cronjobs/jobs/services 功能的封装。本项目为个人项目,难点在对控制器的理解与status的处理。

func (r *WorkloadReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	_ = r.Logger.WithValues("workloads", req.NamespacedName)
	forget := reconcile.Result{}
	requeue := ctrl.Result{
		RequeueAfter: time.Second * 2,
	}
	instance := &workloadsv1alpha1.Workload{}
	if err := r.Get(ctx, req.NamespacedName, instance); err != nil {
		return forget, client.IgnoreNotFound(err)
	}

	// 进入矫正
	if  instance.Status.Phase != workloadsv1alpha1.RunningPhase {
		// 这里料想复杂
		// todo 再优化
		err := r.workloadCorrectionProcessor(&instance)
		if err != nil {
			return requeue, err
		}
	}
	
	// 优先 svc 处理逻辑
	svcStatus, err := r.svc(ctx, instance)
	if err != nil {
		er := r.workloadPhase(ctx, instance, workloadsv1alpha1.FailedPhase)
		if er != nil {
			return requeue, er
		}
		return requeue, err
	}

	// 工作负载 处理逻辑
	dgStatus, err := r.deploymentGroup(ctx, instance, req)
	if err != nil {
		er := r.workloadPhase(ctx, instance, workloadsv1alpha1.FailedPhase)
		if er != nil {
			return ctrl.Result{}, er
		}
		return requeue, err
	}

	// wk 的 status 更新处理
	err  := r.workloadStatus(ctx, instance, dgStatus, svcStatus)
	if err != nil {
		return requeue, err
	}

	return forget, nil
}

operator 的书写逻辑 围绕以下四点即可:

观察:通过监控Kubernetes资源对象变化的事件来获取当前对象状态,只需要注入EventHandler让client-go 将变化的事件对象信息放入WorkQueue中

分析:确定当前状态和期望状态的不同,由Worker完成.

执行:执行能够驱动对象当前状态变化的操作,由Worker完成.

更新:更新对象的当前状态,由Worker完成.

5)、最近在看同事的xxx项目的devops模块,有所感悟:1、开发对需求的实现能力外,其实也应该对要实现的功能有一定的理解。2、对于中间件的掌握(比如Jenkins 的pipeline的书写)。

6)、这一年还帮助同事处理运维问题,帮助同学处理运维问题,也接过外快处理运维相关的问题,也基本每周都抽时间看看云原生相关的知识。偏向开发是必然要的,运维也是规划的重点,需要有意多接触。

综上,其实在过去的一年的开发严格意义还是围绕云原生在进行,也符合对职业生涯的规划:运维 --> 云原生运维 --> 容器开发(运维开发) --> sre(偏向开发的运维岗) -->

一年来的收获

这一年来收获很多,依如20年的运维工作一样,对职业产生深远影响:

1、查找资料由csdn/博客园 --> github/官网

2、研发能力由面向百度 --> 面向google/pkg

3、由遇到问题就请教同事 --> 和同事探讨/自我处理

4、由在一家初创企业 --> 一家还算适中的公司

展望下一年

在接下来的一年,重点实现以下几点:

1、巩固已掌握的

2、具备独立解决问题的能力

3、不断降低bug率 ,做到需求即理解、理解即实现、实现即交付。

4、对服务治理、微服务、数据库中间件、serverless 、算法 展开攻关

5、跳槽 ,再入江湖,出道下山、世界这么大

以如20年的贵人,阿里云MVP 如今入职字节的石老大一样,在过去的一年,遇到了我飞飞哥哥,不断骚扰与学习他的长处,嘿嘿嘿。

未来一年,依然坚信,懂云原生的go开发 是属于当下及未来一个时期的所需。凡是过往、皆为序章。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK