karmada/pkg/karmadactl/cmdinit/kubernetes/services.go

250 lines
6.3 KiB
Go

package kubernetes
import (
"context"
"fmt"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
applycorev1 "k8s.io/client-go/applyconfigurations/core/v1"
applymetav1 "k8s.io/client-go/applyconfigurations/meta/v1"
"k8s.io/klog/v2"
)
// serviceLabels remove via Labels karmada service
var serviceLabels = map[string]string{"karmada.io/bootstrapping": "service-defaults"}
// CreateService create service
func (i *CommandInitOption) CreateService(service *corev1.Service) error {
serviceClient := i.KubeClientSet.CoreV1().Services(i.Namespace)
serviceList, err := serviceClient.List(context.TODO(), metav1.ListOptions{})
if err != nil {
return err
}
// Update if service exists.
for _, v := range serviceList.Items {
if service.Name == v.Name {
t := &applycorev1.ServiceApplyConfiguration{
TypeMetaApplyConfiguration: applymetav1.TypeMetaApplyConfiguration{
APIVersion: &service.APIVersion,
Kind: &service.Kind,
},
ObjectMetaApplyConfiguration: &applymetav1.ObjectMetaApplyConfiguration{
Name: &service.Name,
Namespace: &service.Namespace,
},
Spec: &applycorev1.ServiceSpecApplyConfiguration{
ClusterIP: &service.Spec.ClusterIP,
ClusterIPs: service.Spec.ClusterIPs,
Type: &service.Spec.Type,
Selector: service.Spec.Selector,
},
}
_, err = serviceClient.Apply(context.TODO(), t, metav1.ApplyOptions{
TypeMeta: metav1.TypeMeta{
APIVersion: service.APIVersion,
Kind: service.Kind,
},
FieldManager: "apply",
})
if err != nil {
return fmt.Errorf("apply service %s failed: %v", service.Name, err)
}
klog.Infof("service %s update successfully.", service.Name)
return nil
}
}
_, err = serviceClient.Create(context.TODO(), service, metav1.CreateOptions{})
if err != nil {
return fmt.Errorf("create service %s failed: %v", service.Name, err)
}
klog.Infof("service %s create successfully.", service.Name)
return nil
}
// makeEtcdService etcd service
func (i *CommandInitOption) makeEtcdService(name string) *corev1.Service {
return &corev1.Service{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Service",
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: i.Namespace,
Labels: serviceLabels,
},
Spec: corev1.ServiceSpec{
Selector: etcdLabels,
ClusterIP: "None",
Type: corev1.ServiceTypeClusterIP,
Ports: []corev1.ServicePort{
{
Name: etcdContainerClientPortName,
Protocol: corev1.ProtocolTCP,
Port: etcdContainerClientPort,
TargetPort: intstr.IntOrString{
Type: intstr.Int,
IntVal: etcdContainerClientPort,
},
},
{
Name: etcdContainerServerPortName,
Protocol: corev1.ProtocolTCP,
Port: etcdContainerServerPort,
TargetPort: intstr.IntOrString{
Type: intstr.Int,
IntVal: etcdContainerServerPort,
},
},
},
},
}
}
func (i *CommandInitOption) makeKarmadaAPIServerService() *corev1.Service {
return &corev1.Service{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Service",
},
ObjectMeta: metav1.ObjectMeta{
Name: karmadaAPIServerDeploymentAndServiceName,
Namespace: i.Namespace,
Labels: serviceLabels,
},
Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeNodePort,
Selector: apiServerLabels,
Ports: []corev1.ServicePort{
{
Name: portName,
Protocol: corev1.ProtocolTCP,
Port: karmadaAPIServerContainerPort,
NodePort: i.KarmadaAPIServerNodePort,
TargetPort: intstr.IntOrString{
Type: intstr.Int,
IntVal: karmadaAPIServerContainerPort,
},
},
},
},
}
}
func (i *CommandInitOption) kubeControllerManagerService() *corev1.Service {
return &corev1.Service{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Service",
},
ObjectMeta: metav1.ObjectMeta{
Name: kubeControllerManagerClusterRoleAndDeploymentAndServiceName,
Namespace: i.Namespace,
Labels: serviceLabels,
},
Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeClusterIP,
Selector: kubeControllerManagerLabels,
Ports: []corev1.ServicePort{
{
Name: portName,
Protocol: corev1.ProtocolTCP,
Port: kubeControllerManagerPort,
TargetPort: intstr.IntOrString{
Type: intstr.Int,
IntVal: kubeControllerManagerPort,
},
},
},
},
}
}
func (i *CommandInitOption) karmadaWebhookService() *corev1.Service {
return &corev1.Service{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Service",
},
ObjectMeta: metav1.ObjectMeta{
Name: webhookDeploymentAndServiceAccountAndServiceName,
Namespace: i.Namespace,
Labels: serviceLabels,
},
Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeClusterIP,
Selector: webhookLabels,
Ports: []corev1.ServicePort{
{
Name: webhookPortName,
Protocol: corev1.ProtocolTCP,
Port: webhookPort,
TargetPort: intstr.IntOrString{
Type: intstr.Int,
IntVal: webhookTargetPort,
},
},
},
},
}
}
func (i *CommandInitOption) karmadaAggregatedAPIServerService() *corev1.Service {
return &corev1.Service{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Service",
},
ObjectMeta: metav1.ObjectMeta{
Name: karmadaAggregatedAPIServerDeploymentAndServiceName,
Namespace: i.Namespace,
Labels: serviceLabels,
},
Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeClusterIP,
Selector: aggregatedAPIServerLabels,
Ports: []corev1.ServicePort{
{
Protocol: corev1.ProtocolTCP,
Port: 443,
TargetPort: intstr.IntOrString{
Type: intstr.Int,
IntVal: 443,
},
},
},
},
}
}
func (i CommandInitOption) isNodePortExist() bool {
svc, err := i.KubeClientSet.CoreV1().Services("").List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Exit(err)
}
for _, v := range svc.Items {
if v.Spec.Type != corev1.ServiceTypeNodePort {
continue
}
if !nodePort(i.KarmadaAPIServerNodePort, v) {
return false
}
}
return true
}
func nodePort(nodePort int32, service corev1.Service) bool {
for _, v := range service.Spec.Ports {
if v.NodePort == nodePort {
return false
}
}
return true
}