第30节 localRegistry's info into a secret in namespace kube-system #2056


❤️💕💕记录sealosopen in new window开源项目的学习过程。k8s,docker和云原生的学习open in new window。Myblog:http://nsddd.topopen in new window


[TOC]

Issue Description

Maybe Sealer can dump localRegistry's info into a secret in namespace kube-system. Some component can use this secret.

Type: feature request

date: 2023-02-21

namespace

Three initial namespaces for a cluster:defaultkube-systemkube-public

  • Default: Used for some deployments that don't specify namespaces, this is a quick way to create messes that can be difficult to clean up if you do a lot of deployments without the right information. I'm not going to touch it because it has only one purpose and has misled me in more than one situation.
  • Kube-system : Is the namespace of all objects associated with the Kubernetes system. Any deployment of this namespace can be a dangerous operation that could irreparably damage the system itself. Yes, I've tried; So I don't recommend it.
  • Kube-public : It is readable by all (public), but the namespace is reserved for the system.

你好,sealer是搭建Kubernetes的工具,现在sealer有一个任务,需要将 localRegistry's info into a secret in namespace kube-system,Some component can use this secret.

Kube-system 是 Kubernetes 系统相关的所有对象组成的命名空间。请问我该怎么实现这个功能

localRegistry的信息在命名空间kube-system中变成了一个“秘密”,一些组件可以使用这个“秘密”。

API 集群配置文件(yaml文件)

端口密码,转存到 System namespace

默认生成。

pkg/cluster-runtime/installer.go

be19b04545eacc4fb0a793db36c3cc7a

Registry

There are at least three types of registry, Kubernetes Registry, Docker Registry and container registry. The following are the explanations for these registries:

maybe u should read this articreopen in new window

  • **Docker registry:**A Docker registry contains Docker images that you can pull in order to use them in your deployment. The registry is a stateless, scalable server side application that stores and lets you distribute Docker images.
  • Kubernetes registry:The Kubernetes registry is an image pull secret that your deployment uses to authenticate with a Docker registry.
  • Container registry: A container registry is a repository—or collection of repositories—used to store and access container images.

Secrets

A Secret is an object that contains a small amount of sensitive data such as a password, a token, or a key. Such information might otherwise be put in a Podopen in new window specification or in a container imageopen in new window. Using a Secret means that you don't need to include confidential data in your application code.

Secrets are similar to ConfigMapsopen in new window but are specifically intended to hold confidential data.

⚠️ Kubernetes Secrets are, by default, stored unencrypted in the API server's underlying data store (etcd). Anyone with API access can retrieve or modify a Secret, and so can anyone with access to etcd. Additionally, anyone who is authorized to create a Pod in a namespace can use that access to read any Secret in that namespace; this includes indirect access such as the ability to create a Deployment.

In order to safely use Secrets, take at least the following steps:

  1. Enable Encryption at Restopen in new window for Secrets.
  2. Enable or configure RBAC rules](https://kubernetes.io/docs/reference/access-authn-authz/authorization/) with least-privilege access to Secrets.
  3. Restrict Secret access to specific containers.
  4. Consider using external Secret store providersopen in new window.

There are several options to create a Secret:

查看 namespace 中所有 secret 对象:

$ kubectl get secrets -n kube-system

您应该能够看到一个名为<registry-name>-secret的Secret对象,其中<registry-name>是您在安装Docker Registry时指定的名称。此Secret对象包含 Docker Registry 的登录凭证,包括用户名和密码等信息。您可以使用以下命令获取Secret对象的详细信息:

$ kubectl describe secret <registry-name>-secret -n kube-system

如果您安装的是其他类型的容器镜像仓库,例如Harbor或Nexus等,那么这些容器镜像仓库的信息可能存储在其他位置。

以下是一个示例yaml文件,其中包含了一个名为registry-secret的Secret对象,用于存储 Docker Registry 的登录凭证。请将其中的占位符(<registry-url><registry-username><registry-password>)替换为您的Docker Registry的URL、用户名和密码。

apiVersion: v1
kind: Secret
metadata:
  name: registry-secret
  namespace: kube-system
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: eyAiYXV0aCI6ICJodHRwczovL2RvY2tlci5leGFtcGxlLmNvbSIsICJ1c2VybmFtZSI6ICJ1c2VybmFtZSIsICJwYXNzd29yZCI6ICJwYXNzd29yZCJ9Cg==

其中,data字段中的值是一个Base64编码的JSON字符串,其中包含Docker Registry的登录凭证。您可以使用以下命令将Docker Registry的登录凭证编码为Base64字符串:

echo -n '{"auth": "https://<registry-url>", "username": "<registry-username>", "password": "<registry-password>"}' | base64

要将这个yaml文件应用到Kubernetes集群中,可以使用以下命令:

kubectl apply -f registry-secret.yaml

这将创建名为registry-secret的Secret对象,并将其存储在kube-system命名空间中。其他Kubernetes组件可以使用此Secret对象中的凭证来访问您的Docker Registry。

如果您在安装Kubernetes时将Docker Registry的登录凭证存储在Secret对象中,那么您可以使用以下命令从Secret对象中提取出Docker Registry的信息:

kubectl get secret <registry-secret-name> -n kube-system -o jsonpath='{.data.\.dockerconfigjson}' | base64 --decode

其中,<registry-secret-name>是您在安装Kubernetes时创建的Secret对象的名称。这个命令将输出一个JSON字符串,其中包含Docker Registry的URL、用户名和密码等信息。

您可以使用jq命令对这个JSON字符串进行解析,例如:

kubectl get secret <registry-secret-name> -n kube-system -o jsonpath='{.data.\.dockerconfigjson}' | base64 --decode | jq '.auth'

这将输出Docker Registry的URL,例如:

"https://<registry-url>"

您可以使用类似的方式提取出其他登录凭证信息,例如用户名和密码:

kubectl get secret <registry-secret-name> -n kube-system -o jsonpath='{.data.\.dockerconfigjson}' | base64 --decode | jq '.username'
kubectl get secret <registry-secret-name> -n kube-system -o jsonpath='{.data.\.dockerconfigjson}' | base64 --decode | jq '.password'

创建 secret 对象:

installer.go中,可以使用以下命令创建一个名为registry-secret的Secret对象:

secret := &corev1.Secret{
    ObjectMeta: metav1.ObjectMeta{
        Name:      "registry-secret",
        Namespace: "kube-system",
    },
    Data: map[string][]byte{
        ".dockerconfigjson": []byte(<registry-login-info>),
    },
    Type: corev1.SecretTypeDockerConfigJson,
}

其中,<registry-login-info>是一个包含Docker Registry的登录凭证信息的JSON字符串。您需要将该字符串存储在Sealer代码中,或从外部读取并传递给Sealer代码。

将Secret对象保存到Kubernetes中

接下来,可以使用以下命令将上述创建的Secret对象保存到Kubernetes中:

_, err = kubeClient.CoreV1().Secrets("kube-system").Create(context.Background(), secret, metav1.CreateOptions{})
if err != nil {
    return err
}

这将在kube-system命名空间中创建一个名为registry-secret的Secret对象,并将其存储到Kubernetes中。

在需要使用登录凭证的组件中引用Secret对象

最后,您可以在需要使用Docker Registry的组件中引用上述创建的Secret对象。例如,可以将以下配置添加到Deployment对象的 spec.template.spec.containers[].imagePullSecrets 数组中:

{
    "name": "registry-secret"
}

这将使Kubernetes在拉取Docker镜像时使用registry-secret Secret对象中存储的Docker Registry的登录凭证。

关键目录

func NewInstaller(conf v2.ContainerRuntimeConfig, driver infradriver.InfraDriver) (Installer, error) {
	switch conf.Type {
	case common.Docker, "":
		conf.Type = common.Docker
		ret := &DefaultInstaller{
			rootfs: driver.GetClusterRootfsPath(),
			driver: driver,
			envs:   driver.GetClusterEnv(),
			Info: Info{
				CertsDir:               DefaultDockerCertsDir,
				CRISocket:              DefaultDockerCRISocket,
				ContainerRuntimeConfig: conf,
				ConfigFilePath:         filepath.Join(common.GetHomeDir(), ".docker", DockerConfigFileName),
			},
		}
		ret.Info.CgroupDriver = DefaultCgroupDriver
		if cd, ok := ret.envs[CgroupDriverArg]; ok && cd != nil {
			ret.Info.CgroupDriver = cd.(string)
		}

		return ret, nil
	case common.Containerd:
		ret := &DefaultInstaller{
			rootfs: driver.GetClusterRootfsPath(),
			driver: driver,
			envs:   driver.GetClusterEnv(),
			Info: Info{
				CertsDir:               DefaultContainerdCertsDir,
				CRISocket:              DefaultContainerdCRISocket,
				ContainerRuntimeConfig: conf,
			},
		}
		ret.Info.CgroupDriver = DefaultCgroupDriver
		if cd, ok := ret.envs[CgroupDriverArg]; ok && cd != nil {
			ret.Info.CgroupDriver = cd.(string)
		}

		return ret, nil
	default:
		return nil, fmt.Errorf("invalid container runtime type")
	}
}func NewInstaller(conf v2.ContainerRuntimeConfig, driver infradriver.InfraDriver) (Installer, error) {
	switch conf.Type {
	case common.Docker, "":
		conf.Type = common.Docker
		ret := &DefaultInstaller{
			rootfs: driver.GetClusterRootfsPath(),
			driver: driver,
			envs:   driver.GetClusterEnv(),
			Info: Info{
				CertsDir:               DefaultDockerCertsDir,
				CRISocket:              DefaultDockerCRISocket,
				ContainerRuntimeConfig: conf,
				ConfigFilePath:         filepath.Join(common.GetHomeDir(), ".docker", DockerConfigFileName),
			},
		}
		ret.Info.CgroupDriver = DefaultCgroupDriver
		if cd, ok := ret.envs[CgroupDriverArg]; ok && cd != nil {
			ret.Info.CgroupDriver = cd.(string)
		}

		return ret, nil
	case common.Containerd:
		ret := &DefaultInstaller{
			rootfs: driver.GetClusterRootfsPath(),
			driver: driver,
			envs:   driver.GetClusterEnv(),
			Info: Info{
				CertsDir:               DefaultContainerdCertsDir,
				CRISocket:              DefaultContainerdCRISocket,
				ContainerRuntimeConfig: conf,
			},
		}
		ret.Info.CgroupDriver = DefaultCgroupDriver
		if cd, ok := ret.envs[CgroupDriverArg]; ok && cd != nil {
			ret.Info.CgroupDriver = cd.(string)
		}

		return ret, nil
	default:
		return nil, fmt.Errorf("invalid container runtime type")
	}
}
func GetHomeDir() string {
	home, err := homedir.Dir()
	if err != nil {
		return "/root/.docker/config.json"
	}
	return home
}

localregistry

文件:

/root/.sealer/Clusterfile

kubectl get cm -n kube-system sealer-clusterfile  -oyaml

这是一个在 Kubernetes 集群中使用的命令,它用于获取名为 sealer-clusterfile 的 ConfigMap 的 YAML 格式,该 ConfigMap 位于 kube-system 命名空间中。输出将包括 ConfigMap 的名称、命名空间、标签和数据。由于使用了 -oyaml 标志,输出将以 YAML 格式呈现。

Clusterfile:

apiVersion: sealer.io/v2
kind: Cluster
metadata:
  creationTimestamp: null
  name: my-cluster
spec:
  containerRuntime: {}
  env:
  - LocalRegistryDomain=sea.hub
  - LocalRegistryPort=5000
  - LocalRegistryURL=sea.hub:5000
  - RegistryDomain=sea.hub
  - RegistryPort=5000
  - RegistryURL=sea.hub:5000
  hosts:
  - ips:
    - 192.168.137.133
    roles:
    - master
    ssh: {}
  image: docker.io/sealerio/kubernetes:v1.22.15
  registry:
    localRegistry:
      cert: {}
      domain: sea.hub
      ha: true
      insecure: false
      port: 5000
  ssh:
    pk: /root/.ssh/id_rsa
    port: "22"
    user: root
status: {}

END 链接