第22节 sealer 1.9.1新年规划
❤️💕💕记录sealos开源项目的学习过程。k8s,docker和云原生的学习。Myblog:http://nsddd.top
[TOC]
准备
时间限制:
0.9.2 发布 - 20230228
截止到 2 月 28 号,两周为期限实现需求,最后一周检查。
所有命令必须以
root
用户身份运行,目前不支持运行为sudoers
或rootless
sealer 支持
sudoers
添加一些 e2e 测试案例:
我的任务
- https://github.com/sealerio/sealer/issues/1999
AFAK,安装 k8s 不一定需要 root 用户,而是具有 root 权限的用户。有些情况下用户不想提供 root 用户,所以我认为 sealer 需要支持这个功能。
sealer不支持没有sudo权限的普通用户安装运行。
目前,sealer 仍然不支持具有 sudo 权限的普通用户。而在未来对sealer进行一些重构之后,我们肯定会支持具有sudo权限的普通用户。
步骤:
- 确定用户权限要求:需要确定 k8s 安装过程中需要哪些权限,并且需要知道如何在非 root 用户下授予这些权限。
- 修改安装脚本和代码:根据用户权限要求,修改安装脚本以确保它能在非 root 用户下正常运行。
- 测试安装:在非 root 用户下测试 k8s 安装是否正常。
- 更新用户文档:更新 Sealer 用户文档,提供关于非 root 用户安装 k8s 的说明。
解决的问题
文档支持
本文档描述了如何在没有 root 权限的情况下运行 Kubernetes Node 组件,例如 kubelet、CRI、OCI 和 CNI,使用用户命名空间.
这种技术也称为 rootless mode。
解决方案
两种方案 异步开始 :
- 跑程序,快速使用非 root 用户过一遍,找出问题所在,跑通就实现了。
- 过代码,快速过一遍构建部分的代码,找出解决的方案。
跑程序
三台虚拟机
环境:
root@cubmaster01:~/workspces/sealer/_output/bin/sealer/linux_amd64# source /etc/profile;sealer version {"gitVersion":"unknown","gitCommit":"2cd5bb8af","buildDate":"2023-02-03 13:11:59","goVersion":"go1.19.3","compiler":"gc","platform":"linux/amd64"}
主机:
192.168.71.134 node01 192.168.71.133 node02 192.168.71.131 master01
运行:
sealer run docker.io/sealerio/kubernetes:v1.22.15 \
--masters 192.168.71.131 \
--nodes 192.168.71.133,192.168.71.134 --passwd 123456
test
root@cubmaster01:~/workspces# sealer run docker.io/sealerio/kubernetes:v1.22.15 --masters 192.168.71.131 --nodes 192.168.71.133,192.168.71.134 --passwd 123456
Trying to pull docker.io/sealerio/kubernetes:v1.22.15...
Getting image source signatures
Copying blob f5947d538452 skipped: already exists
Copying blob 570ae92500e2 done
Copying blob 55f8dfb1b045 done
Copying blob 8b638286c448 done
Copying blob 20d88a7b893f done
Copying blob 7193b0539042 done
Copying blob 2e3ef0681087 done
Copying blob c738739a1608 done
Copying blob bac05865934b done
Copying config bb75382891 done
Writing manifest to image destination
Storing signatures
2023-02-03 15:16:25 [INFO] [pull.go:79] bb75382891e7f04f192f1baeab18ef9c9f5503f4de8ac6dfc2a4d94f2164dde6
2023-02-03 15:16:25 [INFO] [run.go:229] start to create new cluster with image: docker.io/sealerio/kubernetes:v1.22.15
2023-02-03 15:16:36 [INFO] [pull.go:79] bb75382891e7f04f192f1baeab18ef9c9f5503f4de8ac6dfc2a4d94f2164dde6
copying files to 192.168.71.134: 31/31
copying files to 192.168.71.133: 31/31
+ set -e
+++ dirname /var/lib/sealer/data/my-cluster/rootfs/scripts/docker.sh
++ cd /var/lib/sealer/data/my-cluster/rootfs/scripts
++ pwd
+ scripts_path=/var/lib/sealer/data/my-cluster/rootfs/scripts
+ image_dir=/var/lib/sealer/data/my-cluster/rootfs/scripts/../images
+ DOCKER_VERSION=19.03.15
+ storage=/var/lib/docker
+ mkdir -p /var/lib/docker
+ utils_command_exists docker
+ command -v docker
+ disable_selinux
+ '[' -s /etc/selinux/config ']'
+ systemctl daemon-reload
+ systemctl restart docker.service
+ check_docker_valid
+ docker info
Client:
Context: default
Debug Mode: false
Plugins:
app: Docker App (Docker Inc., v0.9.1-beta3)
buildx: Docker Buildx (Docker Inc., v0.9.1-docker)
compose: Docker Compose (Docker Inc., v2.14.1)
scan: Docker Scan (Docker Inc., v0.23.0)
Server:
Containers: 34
Running: 0
Paused: 0
Stopped: 34
Images: 19
Server Version: 20.10.22
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 1
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 5b842e528e99d4d4c1686467debf2bd4b88ecd86
runc version: v1.1.4-0-g5fd4c4d
init version: de40ad0
Security Options:
apparmor
seccomp
Profile: default
Kernel Version: 5.4.0-137-generic
Operating System: Ubuntu 20.04.5 LTS
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 3.81GiB
Name: cubmaster01
ID: YROS:6C7Z:JISN:TGQP:AAGJ:JAOZ:A7XO:3LBP:YJWN:AQIR:TRPC:5ASC
Docker Root Dir: /var/lib/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
WARNING: No swap limit support
++ docker info --format '{{json .ServerVersion}}'
++ tr -d '"'
+ dockerVersion=20.10.22
+ '[' 20.10.22 '!=' 19.03.15 ']'
+ panic 'docker version is 20.10.22, should be 19.03.15, please check'
/var/lib/sealer/data/my-cluster/rootfs/scripts/docker.sh: line 64: panic: command not found
2023-02-03 15:17:25 [INFO] [remove_container.go:66] d400abc92de5308584e6a6e5b06a098698220124ec096b6bbeb3654c2e49bf28
Usage:
sealer run [flags]
Examples:
run cluster by Clusterfile:
sealer run -f Clusterfile
run cluster by CLI flags:
sealer run docker.io/sealerio/kubernetes:v1.22.15 -m 172.28.80.01 -n 172.28.80.02 -p Sealer123
run app image:
sealer run localhost/nginx:v1
Flags:
-f, --Clusterfile string Clusterfile path to run a Kubernetes cluster
--apps strings override default AppNames of clusterimage
--cmds strings override default LaunchCmds of clusterimage
-e, --env strings set custom environment variables
-h, --help help for run
-m, --masters string set count or IPList to masters
--mode string load images to the specified registry in advance (default "apply")
-n, --nodes string set count or IPList to nodes
-p, --passwd string set cloud provider or baremetal server password
--pk string set baremetal server private key (default "/root/.ssh/id_rsa")
--pk-passwd string set baremetal server private key password
--port uint16 set the sshd service port number for the server (default port: 22) (default 22)
-u, --user string set baremetal server username (default "root")
Global Flags:
--color string set the log color mode, the possible values can be [never always] (default "always") --config string config file of sealer tool (default is $HOME/.sealer.json)
-d, --debug turn on debug mode
--hide-path hide the log path
--hide-time hide the log time
--log-to-file write log message to disk
-q, --quiet silence the usage when fail
--remote-logger-url string remote logger url, if not empty, will send log to this url
--task-name string task name which will embedded in the remote logger header, only valid when --remote-logger-url is set
2023-02-03 15:17:25 [ERROR] [root.go:75] sealer-unknown: failed to install docker: execute command(bash /var/lib/sealer/data/my-cluster/rootfs/scripts/docker.sh ) on host (192.168.71.131): error(failed to execute command(bash /var/lib/sealer/data/my-cluster/rootfs/scripts/docker.sh ) on host(192.168.71.131): error(exit status 127))
root@cubmaster01:~/workspces# sealer images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/sealerio/kubernetes v1.22.15 bb75382891e7 4 weeks ago 963 MB
docker.io/fanux/ingress-nginx v1.2.0 d32b3c0b33a8 2 months ago 58.6 KB
localhost/3293172751/ingress-nginx v1.2.0 d32b3c0b33a8 2 months ago 58.6 KB
root@cubmaster01:~/workspces# kubectl get node
The connection to the server 127.0.0.1:6443 was refused - did you specify the right host or port?
root@cubmaster01:~/workspces#
遇到的问题,docker版本不符合
也有其他的问题,其他节点不够干净,docker版本不符合,还有docker所有权问题。
sudo chown root:docker /var/run/docker.sock
Ubuntu 22.04 是我的操作系统。在进行广泛研究并浏览大量网站后,我发现以非 root 用户身份运行 Docker 会创建不同的上下文。使用下面列出的命令解决了我的问题。
docker context ls
docker context use default
用户可能没有与 docker 守护进程通信的访问权限
2023-02-04 08:51:00 [ERROR] [root.go:75] sealer-unknown: failed to init master0: failed to execute command(kubeadm init --config=/etc/kubernetes/kubeadm.yaml --upload-certs -v 0 --ignore-preflight-errors=SystemVerification,Port-10250,DirAvailable--etc-kubernetes-manifests) on host(192.168.71.131): error(W0204 08:50:55.248878 36042 strict.go:55] error unmarshaling configuration schema.GroupVersionKind{Group:"kubelet.config.k8s.io", Version:"v1beta1", Kind:"KubeletConfiguration"}: error unmarshaling JSON: while decoding JSON: json: unknown field "flushFrequency"
[WARNING FileExisting-socat]: socat not found in system path
[WARNING Port-10250]: Port 10250 is in use
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR Port-6443]: Port 6443 is in use
[ERROR Port-10259]: Port 10259 is in use
[ERROR Port-10257]: Port 10257 is in use
[ERROR FileAvailable--etc-kubernetes-manifests-kube-apiserver.yaml]: /etc/kubernetes/manifests/kube-apiserver.yaml already exists
[ERROR FileAvailable--etc-kubernetes-manifests-kube-controller-manager.yaml]: /etc/kubernetes/manifests/kube-controller-manager.yaml already exists
[ERROR FileAvailable--etc-kubernetes-manifests-kube-scheduler.yaml]: /etc/kubernetes/manifests/kube-scheduler.yaml already exists
[ERROR FileAvailable--etc-kubernetes-manifests-etcd.yaml]: /etc/kubernetes/manifests/etcd.yaml already exists
[ERROR Port-2379]: Port 2379 is in use
[ERROR Port-2380]: Port 2380 is in use
[ERROR DirAvailable--var-lib-etcd]: /var/lib/etcd is not empty
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher
). Please clean and reinstall
清理集群:
sealer delete -a
rootless
主机:
192.168.71.130 node01
192.168.71.134 node02
192.168.71.133 master01
运行:
sealer run docker.io/sealerio/kubernetes:v1.22.15 --masters 192.168.71.133 --nodes 192.168.71.130,192.168.71.134 --passwd 123456
遇到的问题:
2023-02-04 11:58:21 [ERROR] [root.go:75] sealer-unknown: open /etc/containers/policy.json: permission denied
root.go:75 context
Execute 将所有子命令添加到root命令并适当设置标志。会被 main.main() 调用一次。
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "sealer",
Short: "A tool to build, share and run any distributed applications.",
Long: longRootCmdDescription,
SilenceUsage: true,
SilenceErrors: true,
}
// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
if err := rootCmd.Execute(); err != nil {
logrus.Errorf("sealer-%s: %v", version.GetSingleVersion(), err)
os.Exit(1)
}
}
rootCmd
是一个 cobra 应用程序的根命令,它代表整个应用程序的命令行界面。调用 rootCmd.Execute()
函数将执行整个命令行程序,并执行其中定义的命令和子命令。
安装时候没有权限打开目录
没有权限,我就用权限打开:
目录
文件 | 目的 |
---|---|
/etc/shadow | 保护用户帐户信息 |
/etc/passwd | 用户账户信息 |
/etc/gshadow | 包含组帐户的阴影信息 |
/etc/group | 定义用户所属的组 |
sudo
test@cubmaster01:/var/lib/dpkg$ sudo sealer run docker.io/sealerio/kubernetes:v1.22.15 --masters 192.168.71.133 --nodes 192.168.71.130,192.168.71.134 --passwd 123456
[sudo] password for test:
test is not in the sudoers file. This incident will be reported.
编辑sudoers文件:
即执行:vi /etc/sudoers
找到这行 root ALL=(ALL) ALL,在他下面添加xxx ALL=(ALL) ALL (这里的xxx是你的用户名)
ps:这里说下你可以sudoers添加下面四行中任意一条
youuser ALL=(ALL) ALL
%youuser ALL=(ALL) ALL
youuser ALL=(ALL) NOPASSWD: ALL
%youuser ALL=(ALL) NOPASSWD: ALL
- 第一行:允许用户youuser执行sudo命令(需要输入密码).
- 第二行:允许用户组youuser里面的用户执行sudo命令(需要输入密码).
- 第三行:允许用户youuser执行sudo命令,并且在执行的时候不输入密码.
- 第四行:允许用户组youuser里面的用户执行sudo命令,并且在执行的时候不输入密码.
passwd 文件
本地用户信息存储在纯文本/etc/passwd
文件中:它的每一行代表一个用户帐户,并且有七个由冒号分隔的字段。
帐户:密码:UID:GID:GECOS:目录:shell
在哪里:
*account*
是用户名。此字段不能为空。标准 *NIX 命名规则适用。password
是用户密码。
警告:该
passwd
文件是全球可读的,因此在此文件中存储密码(散列或其他方式)是不安全的。相反,Arch Linux 使用阴影密码:该password
字段将包含一个占位符字符 (x
),表示哈希密码保存在访问受限文件/etc/shadow
中。因此,建议始终使用passwd命令更改密码。*UID*
是数字用户 ID。在 Arch 中,与服务相对的所谓普通用户的第一个登录名(在 root 之后)默认为 UID 1000;用户的后续 UID 条目应大于 1000。*GID*
是用户的数字主要组 ID。GID 的数值列在/etc/group中。*GECOS*
是用于信息目的的可选字段;通常它包含完整的用户名,但它也可以由finger等服务使用,并通过chfn命令进行管理。此字段是可选的,可以留空。*directory*
由登录命令用来设置$HOME
环境变量。几个服务用自己的用户使用/
,但普通用户一般都设置在一个目录下/home
。*shell*
是用户默认命令 shell的路径。该字段是可选的,默认为/bin/bash
。
myidea
创建一个名为 sealer 的组向其中添加用户。 当 sealer 守护进程(docker daemon)启动时,它会创建一个可由 sealer 组成员访问的 Unix
套接字(Unix socket)。
Warning : docker
组拥有和根用户(root user)同等权限。
kk的解决方案:
func (s *SyncKubeConfigToWorker) Execute(runtime connector.Runtime) error {
if v, ok := s.PipelineCache.Get(common.ClusterStatus); ok {
cluster := v.(*KubernetesStatus)
createConfigDirCmd := "mkdir -p /root/.kube"
if _, err := runtime.GetRunner().SudoCmd(createConfigDirCmd, false); err != nil {
return errors.Wrap(errors.WithStack(err), "create .kube dir failed")
}
syncKubeConfigForRootCmd := fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, "/root/.kube/config")
if _, err := runtime.GetRunner().SudoCmd(syncKubeConfigForRootCmd, false); err != nil {
return errors.Wrap(errors.WithStack(err), "sync kube config for root failed")
}
userConfigDirCmd := "mkdir -p $HOME/.kube"
if _, err := runtime.GetRunner().Cmd(userConfigDirCmd, false); err != nil {
return errors.Wrap(errors.WithStack(err), "user mkdir $HOME/.kube failed")
}
syncKubeConfigForUserCmd := fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, "$HOME/.kube/config")
if _, err := runtime.GetRunner().Cmd(syncKubeConfigForUserCmd, false); err != nil {
return errors.Wrap(errors.WithStack(err), "sync kube config for normal user failed")
}
chownKubeConfig := "chown -R (id−u):(id -g) -R $HOME/.kube"
if _, err := runtime.GetRunner().Cmd(chownKubeConfig, false); err != nil {
userId, err := runtime.GetRunner().Cmd("echo $(id -u)", false)
if err != nil {
return errors.Wrap(errors.WithStack(err), "get user id failed")
}
userGroupId, err := runtime.GetRunner().Cmd("echo $(id -g)", false)
if err != nil {
return errors.Wrap(errors.WithStack(err), "get user group id failed")
}
chownKubeConfig := fmt.Sprintf("chown -R %s:%s -R $HOME/.kube", userId, userGroupId)
if _, err := runtime.GetRunner().SudoCmd(chownKubeConfig, false); err != nil {
return errors.Wrap(errors.WithStack(err), "chown user kube config failed")
}
}
return nil
}
针对问题:sealer version 的版本号问题的解决方案
chown -R 用户名:用户组 目录
修改用户,使其属于root组:
# 然后修改用户,使其属于root组(wheel),命令如下:
usermod -g root test
我的思路是安装 sealer 的
sealer 组
Docker 设定一个 docker 组是为了提供一种简便的方法来控制对 Docker 的访问。
通常,使用 Docker 需要 root 权限。但是,开放 root 权限带来的安全风险很大,因此 Docker 引入了一个 docker 组来提高安全性。
这意味着,只有加入 docker 组的用户才能够使用 Docker。可以使用以下命令将用户添加到 docker 组中:
sudo usermod -aG docker $USER
创建 Sealer 组:使用以下命令创建一个名为 Sealer 的组:
sudo groupadd Sealer
添加用户:将所有希望具有访问 Kubernetes 集群和镜像的用户添加到 Sealer 组中。使用以下命令添加用户:
sudo usermod -aG Sealer <username>
设置目录访问权限:将 Kubernetes 集群和镜像的目录的访问权限设置为 Sealer 组,以便 Sealer 组中的用户可以访问。使用以下命令设置目录访问权限:
sudo chown -R :Sealer <directory> sudo chmod -R g+rwx <directory>
其中
<directory>
是要访问的目录,<username>
是要添加到 Sealer 组中的用户的用户名。
如果系统用户需要特定的用户和组 ID,请在创建用户时 使用-u
/--uid
和-g
/选项指定它们:--gid
# useradd -r -u 850 -g 850 -s /usr/bin/nologin 用户名
新服务器测试
wget https://github.com/sealerio/sealer/releases/download/v0.9.0/sealer-v0.9.0-linux-amd64.tar.gz && \ tar zxvf sealer-v0.9.0-linux-amd64.tar.gz && sudo mv sealer /usr/bin ; sealer
bug:单节点也需要IP问题
单节点安装提醒:
#sudo sealer run docker.io/sealerio/kubernetes:v1.22.15
2023-02-05 16:32:44 [ERROR] [root.go:75] sealer-v0.9.0: you must input master ip Or use Clusterfile
#sudo sealer run docker.io/sealerio/kubernetes:v1.22.15 --masters 10.160.25.43
root用户安装单节点:
sealer run docker.io/sealerio/kubernetes:v1.22.15 --masters 10.160.25.43
EEROR:
2023-02-05 16:51:36 [ERROR] [root.go:75] sealer-v0.9.0: failed to execute command(RegistryDomain="sea.hub" RegistryPort="5000" RegistryURL="sea.hub:5000" && cd /var/lib/sealer/data/my-cluster/rootfs/scripts && bash init-registry.sh 5000 /var/lib/sealer/data/my-cluster/rootfs/registry sea.hub) on host(10.160.25.43): error(exit status 1)
给目录和用户权限后:
2023-02-05 21:19:02 [ERROR] [root.go:75] sealer-v0.9.0: cannot mount using driver overlay in rootless mode. You need to run it in a `buildah unshare` session
请给入权限:
sudo echo "sealer ALL=(ALL) ALL" >> /etc/sudoers
ssh:
sudo cat >> /etc/hosts <<EOF
10.0.0.235 master01
10.0.0.236 node01
10.0.0.237 node02
EOF
sealer三台服务器测试:
sealer run docker.io/sealerio/kubernetes:v1.22.15 \
--masters 10.0.0.235 \
--nodes 10.0.0.236 10.0.0.237 --passwd Sealer.io@123
error:
2023-02-07 20:08:47 [ERROR] [root.go:75] sealer-v0.9.0: [ssh][110.0.0.236] failed to create ssh session: dial tcp 110.0.0.236:22: i/o timeout
END 链接
✴️版权声明 © :本书所有内容遵循CC-BY-SA 3.0协议(署名-相同方式共享)©