Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: IPv6双栈、服务检查废弃接口更换、健康检查鉴权403、数据库初始化脚本为空 #445

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion operator/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ COPY api/ api/
COPY controllers/ controllers/
COPY pkg/ pkg/
ADD https://raw.githubusercontent.com/alibaba/nacos/develop/distribution/conf/mysql-schema.sql config/sql/nacos-mysql.sql
RUN sed -i 's/INSERT INTO/INSERT IGNORE INTO/' config/sql/nacos-mysql.sql

# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} GO111MODULE=on go build -a -v -o manager main.go
Expand All @@ -26,7 +27,7 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} GO111MODULE=on go build -a -v
FROM registry.cn-hangzhou.aliyuncs.com/shenkonghui/distroless-static:nonroot
WORKDIR /
COPY --from=builder /workspace/manager .
COPY --from=builder /workspace/config/sql/nacos-mysql.sql config/sql/nacos-mysql.sql
COPY --from=builder --chmod=644 /workspace/config/sql/nacos-mysql.sql config/sql/nacos-mysql.sql
USER nonroot:nonroot

ENTRYPOINT ["/manager"]
2 changes: 2 additions & 0 deletions operator/api/v1alpha1/nacos_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ type Certification struct {
Token string `json:"token,omitempty"`
TokenExpireSeconds string `json:"token_expire_seconds,omitempty"`
CacheEnabled bool `json:"cache_enabled,omitempty"`
IdentityKey string `json:"identity_key"`
IdentityValue string `json:"identity_value"`
}

type K8sWrapper struct {
Expand Down
5 changes: 4 additions & 1 deletion operator/chart/nacos-operator/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ spec:
command: ["/manager"]
args: ["--enable-leader-election"]
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: ENABLE_IPV6
value: "{{ .Values.enableIPv6 | default false }}"
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.nodeSelector }}
Expand All @@ -48,4 +51,4 @@ spec:
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
2 changes: 2 additions & 0 deletions operator/chart/nacos-operator/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ serviceAccount:
create: true
annotations: {}
name: ""

enableIPv6: false

podAnnotations: {}

Expand Down
4 changes: 4 additions & 0 deletions operator/config/crd/bases/nacos.io_nacos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,10 @@ spec:
type: string
token_expire_seconds:
type: string
identity_key:
type: string
identity_value:
type: string
type: object
config:
description: 配置文件
Expand Down
60 changes: 49 additions & 11 deletions operator/pkg/service/nacos/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,45 +18,83 @@ type NacosClient struct {
}

type ServersInfo struct {
Servers []struct {
Code int `json:"code"`
Message interface{} `json:"message"`
Data []struct {
IP string `json:"ip"`
Port int `json:"port"`
State string `json:"state"`
ExtendInfo struct {
LastRefreshTime int64 `json:"lastRefreshTime"`
RaftMetaData struct {
MetaDataMap struct {
NamingPersistentService struct {
NamingInstanceMetadata struct {
Leader string `json:"leader"`
RaftGroupMember []string `json:"raftGroupMember"`
Term int `json:"term"`
} `json:"naming_persistent_service"`
} `json:"naming_instance_metadata"`
NamingPersistentServiceV2 struct {
Leader string `json:"leader"`
RaftGroupMember []string `json:"raftGroupMember"`
Term int `json:"term"`
} `json:"naming_persistent_service_v2"`
NamingServiceMetadata struct {
Leader string `json:"leader"`
RaftGroupMember []string `json:"raftGroupMember"`
Term int `json:"term"`
} `json:"naming_service_metadata"`
} `json:"metaDataMap"`
} `json:"raftMetaData"`
RaftPort string `json:"raftPort"`
Version string `json:"version"`
RaftPort string `json:"raftPort"`
ReadyToUpgrade bool `json:"readyToUpgrade"`
Version string `json:"version"`
} `json:"extendInfo"`
Address string `json:"address"`
FailAccessCnt int `json:"failAccessCnt"`
} `json:"servers"`
Abilities struct {
RemoteAbility struct {
SupportRemoteConnection bool `json:"supportRemoteConnection"`
} `json:"remoteAbility"`
ConfigAbility struct {
SupportRemoteMetrics bool `json:"supportRemoteMetrics"`
} `json:"configAbility"`
NamingAbility struct {
SupportJraft bool `json:"supportJraft"`
} `json:"namingAbility"`
} `json:"abilities"`
} `json:"data"`
}

func (c *NacosClient) GetClusterNodes(ip string) (ServersInfo, error) {
func (c *NacosClient) GetClusterNodes(ip string, identityKey string, identityValue string) (ServersInfo, error) {
servers := ServersInfo{}
//增加支持ipV6 pod状态探测
var resp *http.Response
client := &http.Client{}
var err error

var url string
if strings.Contains(ip, ":") {
resp, err = c.httpClient.Get(fmt.Sprintf("http://[%s]:8848/nacos/v1/ns/operator/servers", ip))
url = fmt.Sprintf("http://[%s]:8848/nacos/v1/core/cluster/nodes", ip)
} else {
resp, err = c.httpClient.Get(fmt.Sprintf("http://%s:8848/nacos/v1/ns/operator/servers", ip))
url = fmt.Sprintf("http://%s:8848/nacos/v1/core/cluster/nodes", ip)
}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return servers, err
}

if identityKey != "" {
header := http.Header{
identityKey: []string{identityValue},
}
req.Header = header
}

resp, err := client.Do(req)
if err != nil {
return servers, err
}

defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
return servers, err
Expand Down
10 changes: 5 additions & 5 deletions operator/pkg/service/operator/Check.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,18 @@ func (c *CheckClient) CheckNacos(nacos *nacosgroupv1alpha1.Nacos, pods []corev1.
nacos.Status.Conditions = []nacosgroupv1alpha1.Condition{}
// 检查nacos是否访问通
for _, pod := range pods {
servers, err := c.nacosClient.GetClusterNodes(pod.Status.PodIP)
servers, err := c.nacosClient.GetClusterNodes(pod.Status.PodIP, nacos.Spec.Certification.IdentityKey, nacos.Spec.Certification.IdentityValue)
myErrors.EnsureNormalMyError(err, myErrors.CODE_CLUSTER_FAILE)
// 确保cr中实例个数和server数量相同
myErrors.EnsureEqual(len(servers.Servers), int(*nacos.Spec.Replicas), myErrors.CODE_CLUSTER_FAILE, "server num is not equal")
for _, svc := range servers.Servers {
myErrors.EnsureEqual(len(servers.Data), int(*nacos.Spec.Replicas), myErrors.CODE_CLUSTER_FAILE, "server num is not equal")
for _, svc := range servers.Data {
myErrors.EnsureEqual(svc.State, "UP", myErrors.CODE_CLUSTER_FAILE, "node is not up")
if leader != "" {
// 确保每个节点leader相同
myErrors.EnsureEqual(leader, svc.ExtendInfo.RaftMetaData.MetaDataMap.NamingPersistentService.Leader,
myErrors.EnsureEqual(leader, svc.ExtendInfo.RaftMetaData.MetaDataMap.NamingPersistentServiceV2.Leader,
myErrors.CODE_CLUSTER_FAILE, "leader not equal")
} else {
leader = svc.ExtendInfo.RaftMetaData.MetaDataMap.NamingPersistentService.Leader
leader = svc.ExtendInfo.RaftMetaData.MetaDataMap.NamingPersistentServiceV2.Leader
}
nacos.Status.Version = svc.ExtendInfo.Version
}
Expand Down
73 changes: 51 additions & 22 deletions operator/pkg/service/operator/Kind.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package operator

import (
"fmt"
"os"
"path/filepath"
"strconv"

batchv1 "k8s.io/api/batch/v1"
"k8s.io/apimachinery/pkg/runtime"
"nacos.io/nacos-operator/pkg/util/merge"
"path/filepath"
"strconv"

"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"

Expand All @@ -21,12 +23,14 @@ import (
"nacos.io/nacos-operator/pkg/service/k8s"
)

const TYPE_STAND_ALONE = "standalone"
const TYPE_CLUSTER = "cluster"
const NACOS = "nacos"
const NACOS_PORT = 8848
const RAFT_PORT = 7848
const NEW_RAFT_PORT = 9848
const (
TYPE_STAND_ALONE = "standalone"
TYPE_CLUSTER = "cluster"
NACOS = "nacos"
NACOS_PORT = 8848
RAFT_PORT = 7848
NEW_RAFT_PORT = 9848
)

// 导入的sql文件名称
const SQL_FILE_NAME = "nacos-mysql.sql"
Expand Down Expand Up @@ -104,13 +108,13 @@ func (e *KindClient) generateName(nacos *nacosgroupv1alpha1.Nacos) string {
func (e *KindClient) generateHeadlessSvcName(nacos *nacosgroupv1alpha1.Nacos) string {
return fmt.Sprintf("%s-headless", nacos.Name)
}

func (e *KindClient) generateClientSvcName(nacos *nacosgroupv1alpha1.Nacos) string {
return fmt.Sprintf("%s-client", nacos.Name)
}

// CR格式验证
func (e *KindClient) ValidationField(nacos *nacosgroupv1alpha1.Nacos) {

setDefaultValue := []func(nacos *nacosgroupv1alpha1.Nacos){
setDefaultNacosType,
setDefaultMysql,
Expand Down Expand Up @@ -138,6 +142,12 @@ func setDefaultCertification(nacos *nacosgroupv1alpha1.Nacos) {
if nacos.Spec.Certification.TokenExpireSeconds == "" {
nacos.Spec.Certification.TokenExpireSeconds = "18000"
}
if nacos.Spec.Certification.IdentityKey == "" {
nacos.Spec.Certification.IdentityKey = "nacos_identity_key"
}
if nacos.Spec.Certification.IdentityValue == "" {
nacos.Spec.Certification.IdentityValue = "nacos_identity_value"
}
}
}

Expand Down Expand Up @@ -357,7 +367,7 @@ func (e *KindClient) buildJob(nacos *nacosgroupv1alpha1.Nacos) *batchv1.Job {
Key: "SQL_SCRIPT",
},
},
//Value: readSql(SQL_FILE_NAME),
// Value: readSql(SQL_FILE_NAME),
},
},
// 导入nacos-mysql.sql中的数据
Expand Down Expand Up @@ -459,17 +469,27 @@ func (e *KindClient) buildClientService(nacos *nacosgroupv1alpha1.Nacos) *v1.Ser
Selector: labels,
},
}
//client-service提供双栈
var ipf = make([]v1.IPFamily, 0)
// client-service提供双栈
ipf := make([]v1.IPFamily, 0)
ipf = append(ipf, v1.IPv4Protocol)
ipf = append(ipf, v1.IPv6Protocol)
if isIPv6Enabled() {
ipf = append(ipf, v1.IPv6Protocol)
}
svc.Spec.IPFamilies = ipf
var ipPli = v1.IPFamilyPolicyPreferDualStack
ipPli := v1.IPFamilyPolicyPreferDualStack
svc.Spec.IPFamilyPolicy = &ipPli
myErrors.EnsureNormal(controllerutil.SetControllerReference(nacos, svc, e.scheme))
return svc
}

func isIPv6Enabled() bool {
enableIPv6, err := strconv.ParseBool(os.Getenv("ENABLE_IPV6"))
if err != nil {
return false
}
return enableIPv6
}

func (e *KindClient) buildStatefulset(nacos *nacosgroupv1alpha1.Nacos) *appv1.StatefulSet {
// 生成label
labels := e.generateLabels(nacos.Name, NACOS)
Expand Down Expand Up @@ -516,6 +536,16 @@ func (e *KindClient) buildStatefulset(nacos *nacosgroupv1alpha1.Nacos) *appv1.St
Name: "NACOS_AUTH_CACHE_ENABLE",
Value: strconv.FormatBool(nacos.Spec.Certification.CacheEnabled),
})

env = append(env, v1.EnvVar{
Name: "NACOS_AUTH_IDENTITY_KEY",
Value: nacos.Spec.Certification.IdentityKey,
})

env = append(env, v1.EnvVar{
Name: "NACOS_AUTH_IDENTITY_VALUE",
Value: nacos.Spec.Certification.IdentityValue,
})
}

// 数据库设置
Expand Down Expand Up @@ -570,7 +600,7 @@ func (e *KindClient) buildStatefulset(nacos *nacosgroupv1alpha1.Nacos) *appv1.St
})
}

var ss = &appv1.StatefulSet{
ss := &appv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Name: e.generateName(nacos),
Namespace: nacos.Namespace,
Expand Down Expand Up @@ -638,7 +668,7 @@ func (e *KindClient) buildStatefulset(nacos *nacosgroupv1alpha1.Nacos) *appv1.St
if nacos.Spec.Volume.Enabled {
ss.Spec.VolumeClaimTemplates = append(ss.Spec.VolumeClaimTemplates, v1.PersistentVolumeClaim{
Spec: v1.PersistentVolumeClaimSpec{
//VolumeName: "db",
// VolumeName: "db",
StorageClassName: nacos.Spec.Volume.StorageClass,
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
Resources: v1.ResourceRequirements{
Expand Down Expand Up @@ -712,7 +742,6 @@ func (e *KindClient) buildStatefulset(nacos *nacosgroupv1alpha1.Nacos) *appv1.St

func (e *KindClient) AddCheckDatabase(nacos *nacosgroupv1alpha1.Nacos, sts *appv1.StatefulSet) *appv1.StatefulSet {
container := v1.Container{

Name: "mysql-check-database",
Image: nacos.Spec.MysqlInitImage,
Env: []v1.EnvVar{
Expand Down Expand Up @@ -740,7 +769,8 @@ func (e *KindClient) AddCheckDatabase(nacos *nacosgroupv1alpha1.Nacos, sts *appv
Command: []string{
"/bin/sh",
"-c",
"while ! mysqlcheck --host=\"${MYSQL_HOST}\" --port=\"${MYSQL_PORT}\" --user=\"${MYSQL_USER}\" --password=\"${MYSQL_PASS}\" --databases \"${MYSQL_DB}\" ; do sleep 1; done"},
"while ! mysqlcheck --host=\"${MYSQL_HOST}\" --port=\"${MYSQL_PORT}\" --user=\"${MYSQL_USER}\" --password=\"${MYSQL_PASS}\" --databases \"${MYSQL_DB}\" ; do sleep 1; done",
},
}
sts.Spec.Template.Spec.InitContainers = append(sts.Spec.Template.Spec.InitContainers, container)
return sts
Expand Down Expand Up @@ -833,7 +863,6 @@ func (e *KindClient) buildDefaultConfigMap(nacos *nacosgroupv1alpha1.Nacos) *v1.
}

func (e *KindClient) buildStatefulsetCluster(nacos *nacosgroupv1alpha1.Nacos, ss *appv1.StatefulSet) *appv1.StatefulSet {

domain := "cluster.local"
// 从环境变量中获取domain
for _, env := range nacos.Spec.Env {
Expand Down Expand Up @@ -864,11 +893,11 @@ func (e *KindClient) buildStatefulsetCluster(nacos *nacosgroupv1alpha1.Nacos, ss
func (e *KindClient) buildHeadlessServiceCluster(svc *v1.Service, nacos *nacosgroupv1alpha1.Nacos) *v1.Service {
svc.Spec.ClusterIP = "None"
svc.Name = e.generateHeadlessSvcName(nacos)
//nacos pod间raft 探测交互走ipv4
var ipf = make([]v1.IPFamily, 0)
// nacos pod间raft 探测交互走ipv4
ipf := make([]v1.IPFamily, 0)
ipf = append(ipf, v1.IPv4Protocol)
svc.Spec.IPFamilies = ipf
var ipPli = v1.IPFamilyPolicySingleStack
ipPli := v1.IPFamilyPolicySingleStack
svc.Spec.IPFamilyPolicy = &ipPli
return svc
}