Golang初级开发工程师职位 - United Internet招聘
Golang初级开发工程师职位 - United Internet招聘 IONOS凭借其商业应用,是欧洲领先的主机和云应用提供商之一。凭借我们先进的技术,我们每天都能赢得来自许多不同国家的超过800万客户的信赖。
你的任务
IONOS PaaS 托管 Kubernetes 团队正在寻找一位积极主动的软件工程师。
PaaS 托管 Kubernetes 团队负责为我们客户开发和维护托管 Kubernetes 服务。利用 Kubernetes Operators,我们管理 IONOS 云基础设施,以配置和维护可靠、地理冗余的 Kubernetes 集群。我们负责企业客户大量节点和集群的整个生命周期,持续更新 Kubernetes 堆栈以及我们自己的驱动程序,例如云控制器管理器和容器存储接口。
我们的小团队负责服务的整个生命周期:我们构建它、交付它、运行它。我们正在寻找一位成员加入我们的团队,与我们一起努力提供尽可能好的产品。
- 使用(主要是)Golang 进行编程(Kubernetes Operators、REST API、库和工具)。
- 设计解决方案,为客户提供新功能。
- 开发、改进和维护完整的工具链(例如 Helm Charts、Github Actions、GitOps)。
- 自动化繁琐的任务,特别是平台的自愈机制。
- 在自愈机制不足时承担待命职责。
我们看重
- 编程经验,最好是 Go 语言。
- 云环境经验。
- Kubernetes 经验。
- Linux 操作系统经验。
更多关于Golang初级开发工程师职位 - United Internet招聘的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang初级开发工程师职位 - United Internet招聘的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这是一个非常典型的Golang云原生开发职位,专注于Kubernetes Operator开发。以下是该职位所需的核心技术栈和示例代码:
核心要求分析:
- Golang Kubernetes Operator开发 - 使用controller-runtime和kubebuilder
- REST API开发 - 通常使用Gin或Echo框架
- 云基础设施集成 - 与IONOS云API交互
- GitOps工具链 - Helm Charts、GitHub Actions
示例代码 - 基础Kubernetes Operator结构:
package controllers
import (
"context"
"fmt"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
)
// 自定义资源定义
type MyCluster struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ClusterSpec `json:"spec,omitempty"`
Status ClusterStatus `json:"status,omitempty"`
}
type ClusterSpec struct {
Replicas int32 `json:"replicas"`
Region string `json:"region"`
}
type ClusterStatus struct {
Nodes int32 `json:"nodes"`
Phase string `json:"phase"`
}
// 控制器实现
type MyClusterReconciler struct {
client.Client
Scheme *runtime.Scheme
}
func (r *MyClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
logger := log.FromContext(ctx)
// 获取自定义资源
var cluster MyCluster
if err := r.Get(ctx, req.NamespacedName, &cluster); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
// 检查并创建Deployment
var deployment appsv1.Deployment
err := r.Get(ctx, client.ObjectKey{
Name: fmt.Sprintf("%s-deployment", cluster.Name),
Namespace: cluster.Namespace,
}, &deployment)
if err != nil {
// 创建新的Deployment
deployment = *r.constructDeployment(&cluster)
if err := r.Create(ctx, &deployment); err != nil {
logger.Error(err, "failed to create deployment")
return ctrl.Result{}, err
}
}
// 更新状态
cluster.Status.Nodes = 3
cluster.Status.Phase = "Running"
if err := r.Status().Update(ctx, &cluster); err != nil {
logger.Error(err, "failed to update cluster status")
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
}
func (r *MyClusterReconciler) constructDeployment(cluster *MyCluster) *appsv1.Deployment {
return &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-deployment", cluster.Name),
Namespace: cluster.Namespace,
},
Spec: appsv1.DeploymentSpec{
Replicas: &cluster.Spec.Replicas,
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"app": cluster.Name},
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"app": cluster.Name},
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "main",
Image: "nginx:latest",
},
},
},
},
},
}
}
func (r *MyClusterReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&MyCluster{}).
Owns(&appsv1.Deployment{}).
Complete(r)
}
示例代码 - REST API端点(使用Gin):
package main
import (
"net/http"
"github.com/gin-gonic/gin"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
type ClusterAPI struct {
k8sClient *kubernetes.Clientset
}
func NewClusterAPI() (*ClusterAPI, error) {
config, err := clientcmd.BuildConfigFromFlags("", "/path/to/kubeconfig")
if err != nil {
return nil, err
}
clientSet, err := kubernetes.NewForConfig(config)
if err != nil {
return nil, err
}
return &ClusterAPI{k8sClient: clientSet}, nil
}
func (api *ClusterAPI) GetClusters(c *gin.Context) {
// 从IONOS云API获取集群列表
clusters := []map[string]interface{}{
{"id": "cluster-1", "status": "running", "nodes": 3},
{"id": "cluster-2", "status": "provisioning", "nodes": 0},
}
c.JSON(http.StatusOK, gin.H{
"clusters": clusters,
"count": len(clusters),
})
}
func (api *ClusterAPI) CreateCluster(c *gin.Context) {
var request struct {
Name string `json:"name" binding:"required"`
Region string `json:"region" binding:"required"`
NodeType string `json:"node_type"`
}
if err := c.ShouldBindJSON(&request); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// 调用IONOS云API创建集群
// 这里应该是实际的云API调用
c.JSON(http.StatusCreated, gin.H{
"id": "new-cluster-id",
"status": "provisioning",
"name": request.Name,
})
}
func main() {
api, err := NewClusterAPI()
if err != nil {
panic(err)
}
router := gin.Default()
router.GET("/api/v1/clusters", api.GetClusters)
router.POST("/api/v1/clusters", api.CreateCluster)
router.Run(":8080")
}
示例代码 - Helm Chart模板片段:
# values.yaml
replicaCount: 3
image:
repository: nginx
tag: latest
pullPolicy: IfNotPresent
resources:
limits:
cpu: 200m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 80
# deployment.yaml模板
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "ionos-operator.fullname" . }}
labels:
{{- include "ionos-operator.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "ionos-operator.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "ionos-operator.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
这个职位需要熟练掌握Kubernetes Operator模式、Golang并发编程、云API集成和完整的CI/CD流水线。代码示例展示了Operator的基本结构、REST API实现和Helm Chart配置,这些都是该职位日常工作的核心内容。

