mirror of
https://github.com/siderolabs/talos.git
synced 2026-05-05 12:26:21 +02:00
fix: remove 'token creds' from maintenance service
This fixes the reverse Go dependency from `pkg/machinery` to `talos` package. Add a check to `Dockerfile` to prevent `pkg/machinery/go.mod` getting out of sync, this should prevent problems in the future. Fix potential security issue in `token` authorizer to deny requests without grpc metadata. In provisioner, add support for launching nodes without the config (config is not delivered to the provisioned nodes). Breaking change in `pkg/provision`: now `NodeRequest.Type` should be set to the node type (as config can be missing now). In `talosctl cluster create` add a flag to skip providing config to the nodes so that they enter maintenance mode, while the generated configs are written down to disk (so they can be tweaked and applied easily). Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
This commit is contained in:
parent
5fca20e137
commit
b2b86a622e
@ -123,6 +123,10 @@ COPY --from=generate /pkg/machinery/api ./pkg/machinery/api
|
||||
COPY --from=generate /pkg/machinery/config ./pkg/machinery/config
|
||||
RUN go list -mod=readonly all >/dev/null
|
||||
RUN ! go mod tidy -v 2>&1 | grep .
|
||||
WORKDIR /src/pkg/machinery
|
||||
RUN go list -mod=readonly all >/dev/null
|
||||
RUN ! go mod tidy -v 2>&1 | grep .
|
||||
WORKDIR /src
|
||||
|
||||
# The init target builds the init binary.
|
||||
|
||||
@ -579,7 +583,7 @@ RUN --mount=type=cache,target=/.cache/go-build --mount=type=cache,target=/.cache
|
||||
WORKDIR /src/pkg/machinery
|
||||
RUN --mount=type=cache,target=/.cache/go-build --mount=type=cache,target=/.cache/golangci-lint golangci-lint run --config ../../.golangci.yml
|
||||
WORKDIR /src
|
||||
# RUN --mount=type=cache,target=/.cache/go-build importvet github.com/talos-systems/talos/...
|
||||
RUN --mount=type=cache,target=/.cache/go-build importvet github.com/talos-systems/talos/...
|
||||
RUN find . -name '*.pb.go' | xargs rm
|
||||
RUN FILES="$(gofumports -l -local github.com/talos-systems/talos .)" && test -z "${FILES}" || (echo -e "Source code is not formatted with 'gofumports -w -local github.com/talos-systems/talos .':\n${FILES}"; exit 1)
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ import (
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/bundle"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/generate"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/machine"
|
||||
"github.com/talos-systems/talos/pkg/machinery/constants"
|
||||
"github.com/talos-systems/talos/pkg/provision"
|
||||
"github.com/talos-systems/talos/pkg/provision/access"
|
||||
@ -78,6 +79,7 @@ var (
|
||||
customCNIUrl string
|
||||
crashdumpOnFailure bool
|
||||
skipKubeconfig bool
|
||||
skipInjectingConfig bool
|
||||
)
|
||||
|
||||
// createCmd represents the cluster up command.
|
||||
@ -286,6 +288,18 @@ func create(ctx context.Context) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
if skipInjectingConfig {
|
||||
types := []machine.Type{machine.TypeControlPlane, machine.TypeJoin}
|
||||
|
||||
if withInitNode {
|
||||
types = append([]machine.Type{machine.TypeInit}, types...)
|
||||
}
|
||||
|
||||
if err = configBundle.Write(".", types...); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Add talosconfig to provision options so we'll have it to parse there
|
||||
provisionOptions = append(provisionOptions, provision.WithTalosConfig(configBundle.TalosConfig()))
|
||||
|
||||
@ -295,6 +309,7 @@ func create(ctx context.Context) (err error) {
|
||||
|
||||
nodeReq := provision.NodeRequest{
|
||||
Name: fmt.Sprintf("%s-master-%d", clusterName, i+1),
|
||||
Type: machine.TypeControlPlane,
|
||||
IP: ips[i],
|
||||
Memory: memory,
|
||||
NanoCPUs: nanoCPUs,
|
||||
@ -305,17 +320,16 @@ func create(ctx context.Context) (err error) {
|
||||
nodeReq.Ports = []string{"50000:50000/tcp", "6443:6443/tcp"}
|
||||
}
|
||||
|
||||
if withInitNode {
|
||||
if i == 0 {
|
||||
cfg = configBundle.Init()
|
||||
} else {
|
||||
cfg = configBundle.ControlPlane()
|
||||
}
|
||||
if withInitNode && i == 0 {
|
||||
cfg = configBundle.Init()
|
||||
nodeReq.Type = machine.TypeInit
|
||||
} else {
|
||||
cfg = configBundle.ControlPlane()
|
||||
}
|
||||
|
||||
nodeReq.Config = cfg
|
||||
if !skipInjectingConfig {
|
||||
nodeReq.Config = cfg
|
||||
}
|
||||
|
||||
request.Nodes = append(request.Nodes, nodeReq)
|
||||
}
|
||||
@ -323,14 +337,21 @@ func create(ctx context.Context) (err error) {
|
||||
for i := 1; i <= workers; i++ {
|
||||
name := fmt.Sprintf("%s-worker-%d", clusterName, i)
|
||||
|
||||
var cfg config.Provider
|
||||
|
||||
if !skipInjectingConfig {
|
||||
cfg = configBundle.Join()
|
||||
}
|
||||
|
||||
request.Nodes = append(request.Nodes,
|
||||
provision.NodeRequest{
|
||||
Name: name,
|
||||
Type: machine.TypeJoin,
|
||||
IP: ips[masters+i-1],
|
||||
Memory: memory,
|
||||
NanoCPUs: nanoCPUs,
|
||||
Disks: disks,
|
||||
Config: configBundle.Join(),
|
||||
Config: cfg,
|
||||
})
|
||||
}
|
||||
|
||||
@ -574,5 +595,6 @@ func init() {
|
||||
createCmd.Flags().StringVar(&dnsDomain, "dns-domain", "cluster.local", "the dns domain to use for cluster")
|
||||
createCmd.Flags().BoolVar(&crashdumpOnFailure, "crashdump", false, "print debug crashdump to stderr when cluster startup fails")
|
||||
createCmd.Flags().BoolVar(&skipKubeconfig, "skip-kubeconfig", false, "skip merging kubeconfig from the created cluster")
|
||||
createCmd.Flags().BoolVar(&skipInjectingConfig, "skip-injecting-config", false, "skip injecting config from embedded metadata server, write config files to current directory")
|
||||
Cmd.AddCommand(createCmd)
|
||||
}
|
||||
|
||||
@ -113,35 +113,8 @@ func genV1Alpha1Config(args []string) error {
|
||||
return fmt.Errorf("failed to generate config bundle: %w", err)
|
||||
}
|
||||
|
||||
for _, t := range []machine.Type{machine.TypeInit, machine.TypeControlPlane, machine.TypeJoin} {
|
||||
name := strings.ToLower(t.String()) + ".yaml"
|
||||
fullFilePath := filepath.Join(outputDir, name)
|
||||
|
||||
var configString string
|
||||
|
||||
switch t { //nolint: exhaustive
|
||||
case machine.TypeInit:
|
||||
configString, err = configBundle.Init().String()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case machine.TypeControlPlane:
|
||||
configString, err = configBundle.ControlPlane().String()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case machine.TypeJoin:
|
||||
configString, err = configBundle.Join().String()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err = ioutil.WriteFile(fullFilePath, []byte(configString), 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("created %s\n", fullFilePath)
|
||||
if err = configBundle.Write(outputDir, machine.TypeInit, machine.TypeControlPlane, machine.TypeJoin); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// We set the default endpoint to localhost for configs generated, with expectation user will tweak later
|
||||
|
||||
@ -6,6 +6,7 @@ package talos
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
@ -47,9 +48,9 @@ var applyConfigCmd = &cobra.Command{
|
||||
return fmt.Errorf("insecure mode requires one and only one node, got %d", len(Nodes))
|
||||
}
|
||||
|
||||
addr := Nodes[0]
|
||||
|
||||
c, err := client.NewInsecureTokenClient(ctx, addr)
|
||||
c, err := client.New(ctx, client.WithTLSConfig(&tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}), client.WithEndpoints(Nodes...))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -21,7 +21,6 @@ import (
|
||||
"github.com/talos-systems/talos/internal/app/maintenance/server"
|
||||
"github.com/talos-systems/talos/pkg/grpc/factory"
|
||||
"github.com/talos-systems/talos/pkg/grpc/gen"
|
||||
"github.com/talos-systems/talos/pkg/grpc/middleware/auth/basic"
|
||||
"github.com/talos-systems/talos/pkg/machinery/constants"
|
||||
)
|
||||
|
||||
@ -42,13 +41,9 @@ func Run(ctx context.Context, logger *log.Logger, r runtime.Runtime) ([]byte, er
|
||||
s := server.New(r, logger, cfgCh)
|
||||
|
||||
// Start the server.
|
||||
|
||||
creds := basic.NewTokenCredentials("")
|
||||
|
||||
server := factory.NewServer(
|
||||
s,
|
||||
factory.WithDefaultLog(),
|
||||
factory.WithUnaryInterceptor(creds.UnaryInterceptor()),
|
||||
factory.ServerOptions(
|
||||
grpc.Creds(
|
||||
credentials.NewTLS(tlsConfig),
|
||||
|
||||
@ -312,6 +312,7 @@ func (suite *UpgradeSuite) setupCluster() {
|
||||
request.Nodes = append(request.Nodes,
|
||||
provision.NodeRequest{
|
||||
Name: fmt.Sprintf("master-%d", i+1),
|
||||
Type: machine.TypeControlPlane,
|
||||
IP: ips[i],
|
||||
Memory: DefaultSettings.MemMB * 1024 * 1024,
|
||||
NanoCPUs: DefaultSettings.CPUs * 1000 * 1000 * 1000,
|
||||
@ -328,6 +329,7 @@ func (suite *UpgradeSuite) setupCluster() {
|
||||
request.Nodes = append(request.Nodes,
|
||||
provision.NodeRequest{
|
||||
Name: fmt.Sprintf("worker-%d", i),
|
||||
Type: machine.TypeJoin,
|
||||
IP: ips[suite.spec.MasterNodes+i-1],
|
||||
Memory: DefaultSettings.MemMB * 1024 * 1024,
|
||||
NanoCPUs: DefaultSettings.CPUs * 1000 * 1000 * 1000,
|
||||
|
||||
@ -48,11 +48,9 @@ func (b *TokenCredentials) authorize(ctx context.Context) error {
|
||||
if len(md["token"]) > 0 && md["token"][0] == b.Token {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("%s", codes.Unauthenticated.String())
|
||||
}
|
||||
|
||||
return nil
|
||||
return fmt.Errorf("%s", codes.Unauthenticated.String())
|
||||
}
|
||||
|
||||
// UnaryInterceptor sets the UnaryServerInterceptor for the server and enforces
|
||||
|
||||
@ -27,7 +27,6 @@ import (
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
|
||||
"github.com/talos-systems/talos/pkg/grpc/middleware/auth/basic"
|
||||
clusterapi "github.com/talos-systems/talos/pkg/machinery/api/cluster"
|
||||
"github.com/talos-systems/talos/pkg/machinery/api/common"
|
||||
machineapi "github.com/talos-systems/talos/pkg/machinery/api/machine"
|
||||
@ -144,24 +143,6 @@ func New(ctx context.Context, opts ...OptionFunc) (c *Client, err error) {
|
||||
c.TimeClient = timeapi.NewTimeServiceClient(c.conn)
|
||||
c.NetworkClient = networkapi.NewNetworkServiceClient(c.conn)
|
||||
c.ClusterClient = clusterapi.NewClusterServiceClient(c.conn)
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// NewInsecureTokenClient returns a new Client configured with an empty basic
|
||||
// token credentials.
|
||||
func NewInsecureTokenClient(ctx context.Context, addr string, opts ...grpc.DialOption) (c *Client, err error) {
|
||||
c = new(Client)
|
||||
|
||||
addr = net.FormatAddress(addr)
|
||||
|
||||
creds := basic.NewTokenCredentials("")
|
||||
|
||||
c.conn, err = basic.NewConnection(addr, constants.ApidPort, creds)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create client connection: %w", err)
|
||||
}
|
||||
|
||||
c.MaintenanceServiceClient = machineapi.NewMaintenanceServiceClient(c.conn)
|
||||
|
||||
return c, nil
|
||||
|
||||
@ -5,8 +5,14 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
clientconfig "github.com/talos-systems/talos/pkg/machinery/client/config"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/machine"
|
||||
)
|
||||
|
||||
// ConfigBundle defines the group of v1alpha1 config files.
|
||||
@ -37,3 +43,42 @@ func (c *ConfigBundle) Join() config.Provider {
|
||||
func (c *ConfigBundle) TalosConfig() *clientconfig.Config {
|
||||
return c.TalosCfg
|
||||
}
|
||||
|
||||
// Write config files to output directory.
|
||||
func (c *ConfigBundle) Write(outputDir string, types ...machine.Type) error {
|
||||
for _, t := range types {
|
||||
name := strings.ToLower(t.String()) + ".yaml"
|
||||
fullFilePath := filepath.Join(outputDir, name)
|
||||
|
||||
var (
|
||||
configString string
|
||||
err error
|
||||
)
|
||||
|
||||
switch t { //nolint: exhaustive
|
||||
case machine.TypeInit:
|
||||
configString, err = c.Init().String()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case machine.TypeControlPlane:
|
||||
configString, err = c.ControlPlane().String()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case machine.TypeJoin:
|
||||
configString, err = c.Join().String()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err = ioutil.WriteFile(fullFilePath, []byte(configString), 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("created %s\n", fullFilePath)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -63,20 +63,26 @@ func (p *provisioner) createNodes(ctx context.Context, clusterReq provision.Clus
|
||||
|
||||
//nolint: gocyclo
|
||||
func (p *provisioner) createNode(ctx context.Context, clusterReq provision.ClusterRequest, nodeReq provision.NodeRequest, options *provision.Options) (provision.NodeInfo, error) {
|
||||
cfg, err := nodeReq.Config.String()
|
||||
if err != nil {
|
||||
return provision.NodeInfo{}, err
|
||||
env := []string{"PLATFORM=container"}
|
||||
|
||||
if nodeReq.Config != nil {
|
||||
cfg, err := nodeReq.Config.String()
|
||||
if err != nil {
|
||||
return provision.NodeInfo{}, err
|
||||
}
|
||||
|
||||
env = append(env, "USERDATA="+base64.StdEncoding.EncodeToString([]byte(cfg)))
|
||||
}
|
||||
|
||||
// Create the container config.
|
||||
containerConfig := &container.Config{
|
||||
Hostname: nodeReq.Name,
|
||||
Image: clusterReq.Image,
|
||||
Env: []string{"PLATFORM=container", "USERDATA=" + base64.StdEncoding.EncodeToString([]byte(cfg))},
|
||||
Env: env,
|
||||
Labels: map[string]string{
|
||||
"talos.owned": "true",
|
||||
"talos.cluster.name": clusterReq.Name,
|
||||
"talos.type": nodeReq.Config.Machine().Type().String(),
|
||||
"talos.type": nodeReq.Type.String(),
|
||||
},
|
||||
Volumes: map[string]struct{}{
|
||||
"/var/lib/containerd": {},
|
||||
@ -110,16 +116,14 @@ func (p *provisioner) createNode(ctx context.Context, clusterReq provision.Clust
|
||||
|
||||
// Mutate the container configurations based on the node type.
|
||||
|
||||
if nodeReq.Config.Machine().Type() == machine.TypeInit || nodeReq.Config.Machine().Type() == machine.TypeControlPlane {
|
||||
if nodeReq.Type == machine.TypeInit || nodeReq.Type == machine.TypeControlPlane {
|
||||
portsToOpen := nodeReq.Ports
|
||||
|
||||
if len(options.DockerPorts) > 0 {
|
||||
portsToOpen = append(portsToOpen, options.DockerPorts...)
|
||||
}
|
||||
|
||||
var generatedPortMap portMap
|
||||
|
||||
generatedPortMap, err = genPortMap(portsToOpen, options.DockerPortsHostIP)
|
||||
generatedPortMap, err := genPortMap(portsToOpen, options.DockerPortsHostIP)
|
||||
if err != nil {
|
||||
return provision.NodeInfo{}, err
|
||||
}
|
||||
@ -160,7 +164,7 @@ func (p *provisioner) createNode(ctx context.Context, clusterReq provision.Clust
|
||||
nodeInfo := provision.NodeInfo{
|
||||
ID: info.ID,
|
||||
Name: info.Name,
|
||||
Type: nodeReq.Config.Machine().Type(),
|
||||
Type: nodeReq.Type,
|
||||
|
||||
NanoCPUs: nodeReq.NanoCPUs,
|
||||
Memory: nodeReq.Memory,
|
||||
|
||||
@ -91,9 +91,19 @@ func (p *provisioner) createNode(state *vm.State, clusterReq provision.ClusterRe
|
||||
|
||||
// Talos config
|
||||
cmdline.Append("talos.platform", "metal")
|
||||
cmdline.Append("talos.config", "{TALOS_CONFIG_URL}") // to be patched by launcher
|
||||
cmdline.Append("talos.hostname", nodeReq.Name)
|
||||
|
||||
var nodeConfig string
|
||||
|
||||
if nodeReq.Config != nil {
|
||||
cmdline.Append("talos.config", "{TALOS_CONFIG_URL}") // to be patched by launcher
|
||||
|
||||
nodeConfig, err = nodeReq.Config.String()
|
||||
if err != nil {
|
||||
return provision.NodeInfo{}, err
|
||||
}
|
||||
}
|
||||
|
||||
ones, _ := clusterReq.Network.CIDR.Mask.Size()
|
||||
|
||||
drives := make([]models.Drive, len(diskPaths))
|
||||
@ -144,11 +154,6 @@ func (p *provisioner) createNode(state *vm.State, clusterReq provision.ClusterRe
|
||||
|
||||
defer logFile.Close() //nolint: errcheck
|
||||
|
||||
nodeConfig, err := nodeReq.Config.String()
|
||||
if err != nil {
|
||||
return provision.NodeInfo{}, err
|
||||
}
|
||||
|
||||
launchConfig := LaunchConfig{
|
||||
FirecrackerConfig: cfg,
|
||||
Config: nodeConfig,
|
||||
@ -192,7 +197,7 @@ func (p *provisioner) createNode(state *vm.State, clusterReq provision.ClusterRe
|
||||
nodeInfo := provision.NodeInfo{
|
||||
ID: pidPath,
|
||||
Name: nodeReq.Name,
|
||||
Type: nodeReq.Config.Machine().Type(),
|
||||
Type: nodeReq.Type,
|
||||
|
||||
NanoCPUs: nodeReq.NanoCPUs,
|
||||
Memory: nodeReq.Memory,
|
||||
|
||||
@ -22,7 +22,6 @@ import (
|
||||
multierror "github.com/hashicorp/go-multierror"
|
||||
"github.com/talos-systems/go-procfs/procfs"
|
||||
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/machine"
|
||||
"github.com/talos-systems/talos/pkg/machinery/constants"
|
||||
"github.com/talos-systems/talos/pkg/provision"
|
||||
"github.com/talos-systems/talos/pkg/provision/providers/vm"
|
||||
@ -74,11 +73,12 @@ func (p *provisioner) createNode(state *vm.State, clusterReq provision.ClusterRe
|
||||
|
||||
// Talos config
|
||||
cmdline.Append("talos.platform", "metal")
|
||||
cmdline.Append("talos.config", "{TALOS_CONFIG_URL}") // to be patched by launcher
|
||||
|
||||
var nodeConfig string
|
||||
|
||||
if nodeReq.Config != nil {
|
||||
cmdline.Append("talos.config", "{TALOS_CONFIG_URL}") // to be patched by launcher
|
||||
|
||||
nodeConfig, err = nodeReq.Config.String()
|
||||
if err != nil {
|
||||
return provision.NodeInfo{}, err
|
||||
@ -160,16 +160,11 @@ func (p *provisioner) createNode(state *vm.State, clusterReq provision.ClusterRe
|
||||
|
||||
// no need to wait here, as cmd has all the Stdin/out/err via *os.File
|
||||
|
||||
nodeType := machine.TypeUnknown
|
||||
if nodeReq.Config != nil {
|
||||
nodeType = nodeReq.Config.Machine().Type()
|
||||
}
|
||||
|
||||
nodeInfo := provision.NodeInfo{
|
||||
ID: pidPath,
|
||||
UUID: nodeUUID,
|
||||
Name: nodeReq.Name,
|
||||
Type: nodeType,
|
||||
Type: nodeReq.Type,
|
||||
|
||||
NanoCPUs: nodeReq.NanoCPUs,
|
||||
Memory: nodeReq.Memory,
|
||||
|
||||
@ -86,11 +86,7 @@ func (reqs NodeRequests) FindInitNode() (req NodeRequest, err error) {
|
||||
// MasterNodes returns subset of nodes which are Init/ControlPlane type.
|
||||
func (reqs NodeRequests) MasterNodes() (nodes []NodeRequest) {
|
||||
for i := range reqs {
|
||||
if reqs[i].Config == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if reqs[i].Config.Machine().Type() == machine.TypeInit || reqs[i].Config.Machine().Type() == machine.TypeControlPlane {
|
||||
if reqs[i].Type == machine.TypeInit || reqs[i].Type == machine.TypeControlPlane {
|
||||
nodes = append(nodes, reqs[i])
|
||||
}
|
||||
}
|
||||
@ -101,11 +97,7 @@ func (reqs NodeRequests) MasterNodes() (nodes []NodeRequest) {
|
||||
// WorkerNodes returns subset of nodes which are Init/ControlPlane type.
|
||||
func (reqs NodeRequests) WorkerNodes() (nodes []NodeRequest) {
|
||||
for i := range reqs {
|
||||
if reqs[i].Config == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if reqs[i].Config.Machine().Type() == machine.TypeJoin {
|
||||
if reqs[i].Type == machine.TypeJoin {
|
||||
nodes = append(nodes, reqs[i])
|
||||
}
|
||||
}
|
||||
@ -137,6 +129,7 @@ type NodeRequest struct {
|
||||
Name string
|
||||
IP net.IP
|
||||
Config config.Provider
|
||||
Type machine.Type
|
||||
|
||||
// Share of CPUs, in 1e-9 fractions
|
||||
NanoCPUs int64
|
||||
|
||||
@ -98,6 +98,7 @@ talosctl cluster create [flags]
|
||||
--nameservers strings list of nameservers to use (default [8.8.8.8,1.1.1.1])
|
||||
--registry-insecure-skip-verify strings list of registry hostnames to skip TLS verification for
|
||||
--registry-mirror strings list of registry mirrors to use in format: <registry host>=<mirror URL>
|
||||
--skip-injecting-config skip injecting config from embedded metadata server, write config files to current directory
|
||||
--skip-kubeconfig skip merging kubeconfig from the created cluster
|
||||
--user-disk strings list of disks to create for each VM in format: <mount_point1>:<size1>:<mount_point2>:<size2>
|
||||
--vmlinuz-path string the compressed kernel image to use (default "_out/vmlinuz-${ARCH}")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user