Moralok's Blog

你在幼年时当快乐

本文记录了 Tmux 常用命令和快捷键作为备忘笔记(好容易忘啊 Orz)。

阅读全文 »

本文介绍了如何使用 SSH 连接 Github 和免密登录服务器作为备忘笔记,主要在新建虚拟机或重装云服务器系统时使用。

阅读全文 »

环境搭建

安装 Ubuntu 20.04

使用 Vmware Workstation 通过 ubuntu-20.04.6-live-server-amd64.iso 安装。需要满足条件如下:

  • 2 个或更多 CPU(2 CPU)。
  • 2GB 可用内存(4GB)。
  • 20GB 可用磁盘空间(30GB)。
  • 网络连接
  • 容器或虚拟机管理器(Docker)。

安装 Docker

参考官方文档:Install Docker Engine on Ubuntu

安装 Minikube

参考官方文档:minikube start

安装 kubectl 并启动 kubectl 自动补全功能

参考官方文档:在 Linux 系统中安装并设置 kubectl

开始使用

创建集群:

1
minikube start

创建集群时的权限问题

不加 sudo

不加 sudo 的时候,创建集群失败,提示无法选择默认 driver。可能是 docker 处于不健康状态或者用户权限不足。

1
2
3
4
5
6
7
8
9
10
11
12
$ minikube start
* minikube v1.30.1 on Ubuntu 20.04
* Unable to pick a default driver. Here is what was considered, in preference order:
- docker: Not healthy: "docker version --format {{.Server.Os}}-{{.Server.Version}}:{{.Server.Platform.Name}}" exit status 1: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/version": dial unix /var/run/docker.sock: connect: permission denied
- docker: Suggestion: Add your user to the 'docker' group: 'sudo usermod -aG docker $USER && newgrp docker' <https://docs.docker.com/engine/install/linux-postinstall/>
* Alternatively you could install one of these drivers:
- kvm2: Not installed: exec: "virsh": executable file not found in $PATH
- podman: Not installed: exec: "podman": executable file not found in $PATH
- qemu2: Not installed: exec: "qemu-system-x86_64": executable file not found in $PATH
- virtualbox: Not installed: unable to find VBoxManage in $PATH

X Exiting due to DRV_NOT_HEALTHY: Found driver(s) but none were healthy. See above for suggestions how to fix installed drivers.
使用 sudo

使用 sudo 的时候,会提示不建议通过 root 权限使用 docker,如果还是想要继续,可以使用选项 --force

1
2
3
4
5
6
7
8
$ sudo minikube start
* minikube v1.30.1 on Ubuntu 20.04
* Automatically selected the docker driver. Other choices: none, ssh
* The "docker" driver should not be used with root privileges. If you wish to continue as root, use --force.
* If you are running minikube within a VM, consider using --driver=none:
* https://minikube.sigs.k8s.io/docs/reference/drivers/none/

X Exiting due to DRV_AS_ROOT: The "docker" driver should not be used with root privileges.
使用选项 –force

考虑到仅用于测试,尝试通过 sudo minikube start --force 启动集群,成功启动集群但是提示使用该选项可能会引发未知行为。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ sudo minikube start --force
* minikube v1.30.1 on Ubuntu 20.04
! minikube skips various validations when --force is supplied; this may lead to unexpected behavior
* Automatically selected the docker driver. Other choices: ssh, none
* The "docker" driver should not be used with root privileges. If you wish to continue as root, use --force.
* If you are running minikube within a VM, consider using --driver=none:
* https://minikube.sigs.k8s.io/docs/reference/drivers/none/
* Using Docker driver with root privileges
* Starting control plane node minikube in cluster minikube
* Pulling base image ...
* Downloading Kubernetes v1.26.3 preload ...
> preloaded-images-k8s-v18-v1...: 397.02 MiB / 397.02 MiB 100.00% 25.89 M
> index.docker.io/kicbase/sta...: 373.53 MiB / 373.53 MiB 100.00% 7.17 Mi
! minikube was unable to download gcr.io/k8s-minikube/kicbase:v0.0.39, but successfully downloaded docker.io/kicbase/stable:v0.0.39 as a fallback image
* Creating docker container (CPUs=2, Memory=2200MB) ...
* Preparing Kubernetes v1.26.3 on Docker 23.0.2 ...
- Generating certificates and keys ...
- Booting up control plane ...
- Configuring RBAC rules ...
* Configuring bridge CNI (Container Networking Interface) ...
- Using image gcr.io/k8s-minikube/storage-provisioner:v5
* Verifying Kubernetes components...
* Enabled addons: default-storageclass, storage-provisioner
* Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

成功启动集群后,使用 kubectl get pod 测试,提示连接被拒绝。

1
2
3
4
5
6
7
$ kubectl get pod
E0622 21:55:27.400754 18561 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
E0622 21:55:27.401000 18561 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
E0622 21:55:27.410464 18561 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
E0622 21:55:27.410951 18561 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
E0622 21:55:27.412076 18561 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
The connection to the server localhost:8080 was refused - did you specify the right host or port?

使用 minikube dashboard 启动控制台,在访问时同样提示连接被拒绝:dial tcp 127.0.0.1:8080: connect: connection refused

考虑到可能还有别的问题,决定采用官方建议将用户添加到 docker 用户组。

将用户添加到 docker 用户组

使用 sudo usermod -aG docker $USER && newgrp docker 将当前用户添加到 docker 用户组并切换当前用户组到 docker 用户组后,正常启动集群。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ minikube start
* minikube v1.30.1 on Ubuntu 20.04
* Automatically selected the docker driver. Other choices: ssh, none
* Using Docker driver with root privileges
* Starting control plane node minikube in cluster minikube
* Pulling base image ...
* Downloading Kubernetes v1.26.3 preload ...
> preloaded-images-k8s-v18-v1...: 393.36 MiB / 397.02 MiB 99.08% 19.35 Mi! minikube was unable to download gcr.io/k8s-minikube/kicbase:v0.0.39, but successfully downloaded docker.io/kicbase/stable:v0.0.39 as a fallback image
> preloaded-images-k8s-v18-v1...: 397.02 MiB / 397.02 MiB 100.00% 21.44 M
* Creating docker container (CPUs=2, Memory=2200MB) ...
* Preparing Kubernetes v1.26.3 on Docker 23.0.2 ...
- Generating certificates and keys ...
- Booting up control plane ...
- Configuring RBAC rules ...
* Configuring bridge CNI (Container Networking Interface) ...
- Using image gcr.io/k8s-minikube/storage-provisioner:v5
* Verifying Kubernetes components...
* Enabled addons: storage-provisioner, default-storageclass
* Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

创建集群时下载镜像失败

在解决问题的过程中,发现有人存在下载镜像失败的情况。从启动日志可以看到,由于 minikube 下载 gcr.io/k8s-minikube/kicbase:v0.0.39 镜像失败,自动下载 docker.io/kicbase/stable:v0.0.39 镜像作为备选。如果从 docker.io 下载镜像也很困难,还可以通过指定镜像仓库启动集群。可以通过查看帮助内关于仓库的信息,获取官方建议中国大陆用户使用的镜像仓库地址。

1
2
3
4
5
$ minikube start --help | grep repo
--image-repository='':
Alternative image repository to pull docker images from. This can be used when you have limited access to gcr.io. Set it to "auto" to let minikube decide one for you. For Chinese mainland users, you may use local gcr.io mirrors such as registry.cn-hangzhou.aliyuncs.com/google_containers

$ minikube start --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers'

如何通过宿主机进行访问 minikube 控制台

启动控制台:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ minikube dashboard
* Enabling dashboard ...
- Using image docker.io/kubernetesui/dashboard:v2.7.0
- Using image docker.io/kubernetesui/metrics-scraper:v1.0.8
* Some dashboard features require the metrics-server addon. To enable all features please run:

minikube addons enable metrics-server


* Verifying dashboard health ...
* Launching proxy ...
* Verifying proxy health ...
* Opening http://127.0.0.1:35967/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/ in your default browser...
http://127.0.0.1:35967/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/

如果虚拟机安装的 Ubuntu 是 Desktop 版本,那么你可以在 Ubuntu 里直接通过浏览器访问。但是如果你安装的 Ubuntu 是 server 版本,除了使用 curl 访问 url 外,你也许想要在宿主机的浏览器访问:

1
kubectl proxy --port=your-port --address='your-virtual-machine-ip' --accept-hosts='^.*' &

使用过程中下载镜像失败

从其他镜像仓库下载代替

一般是在需要从 gcr.io 镜像仓库下载时发生,比如官方教程中需要执行以下命令,会发现 deploymentpod 迟迟不能达到目标状态。

1
2
3
4
5
6
7
8
9
$ kubectl create deployment hello-node --image=registry.k8s.io/e2e-test-images/agnhost:2.39 -- /agnhost netexec --http-port=8080

$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
hello-node 0/1 1 0 19s

$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-node-7b87cd5f68-zwd4g 0/1 ImagePullBackOff 0 38s

仅作为测试用途,可以从 Docker 官方仓库搜索镜像,找到排名靠前,版本相同或相近的可靠镜像代替。

配置代理

对于这类网络连接不通的情况,配置代理是通用的解决方案。开始使用后发现从其他镜像仓库下载代替的方法有点麻烦,于是决定设置代理。
刚开始我以为给 Ubuntu 上的 dockerd 配置代理帮助加速 docker pull 即可,后来发现仍然下载失败。即使我通过 docker pull 先下载镜像到本地,配置 imagePullPolicyNever 或者 IfNotPresent,minikube 还是不能识别到本地已有的镜像。猜测 minikube 的机制和我想象的是不同的,需要直接为 minikube 容器配置代理。搜索到以下命令满足需求:

1
minikube start --docker-env http_proxy=http://proxyAddress:port --docker-env https_proxy=http://proxyAddress:port --docker-env no_proxy=localhost,127.0.0.1,your-virtual-machine-ip/24

需要使用自定义镜像

测试过程中遇到需要使用自定义镜像的场景。在上一个问题中,我们已经发现 Minikube 不能直接使用本地已有的镜像,但是有两种方法可以解决该问题。

minikube image load
1
minikube image load <IMAGE_NAME>
minikube image build
1
minikube image build -t <IMAGE_NAME> .

参考链接

Install Docker Engine on Ubuntu
minikube start
k8s的迷你版——minikube+docker的安装
minikube - Why The “docker” driver should not be used with root privileges
安装Minikube无法访问k8s.gcr.io的简单解决办法
让其他电脑访问minikube dashboard
【问题解决】This container is having trouble accessing https://k8s.gcr.io | 如何解决从k8s.gcr.io拉取镜像失败问题?
K8S(kubernetes)镜像源
minikube 设置代理
两种在Minikube中运行本地Docker镜像的简单方式

Ubuntu 上安装 Clash 后,Clash 通过监听本地的 7890 端口,提供代理服务。但是不同程序设置代理的方式不尽相同,并不是启动了 Clash 以及在某一处设置后,整个系统发出的 HTTP 请求都能经过代理。本文将介绍如何为终端、docker 和容器添加代理。

为终端设置代理

有时候,我们需要在终端通过执行命令的方式访问网络和下载资源,比如使用 wgetcurl

设置 Shell 环境变量

这一类软件都是可以通过为 Shell 设置环境变量的方式来设置代理,涉及到的环境变量有 http_proxyhttps_proxyno_proxy
仅为当前会话设置,执行命令:

1
2
3
export http_proxy=http://proxyAddress:port
export https_proxy=http://proxyAddress:port
export no_proxy=localhost,127.0.0.1

永久设置代理,在设置 Shell 环境变量的脚本中(不同 Shell 的配置文件不同,比如 ~/.bashrc~/.zshrc)添加:

1
2
3
export http_proxy=http://proxyAddress:port
export https_proxy=http://proxyAddress:port
export no_proxy=localhost,127.0.0.1

重新启动一个会话或者执行命令 source ~/.bashrc 使其在当前会话立即生效。

修改 wget 配置文件

在搜索过程中发现还可以在 wget 的配置文件 ~/.wgetrc 中添加:

1
2
3
4
use_proxy = on

http_proxy = http://proxyAddress:port
https_proxy = http://proxyAddress:port

为 docker 设置代理

如果你以为为终端设置代理后 docker 就会使用代理,那你就错了。在从官方的镜像仓库 pull 镜像反复出错后并收到类似 Error response from daemon: Get "https://registry-1.docker.io/v2/": read tcp 192.168.3.140:59460->44.205.64.79:443: read: connection reset by peer 这样的报错信息后,我才开始怀疑我并没有真正给 docker 设置好代理。
在执行 docker pull 命令时,实际上命令是由守护进程 docker daemon 执行的。

通过 systemd 设置

如果你的 docker daemon 是通过 systemd 管理的,那么你可以通过设置 docker.service 服务的环境变量来设置代理。
执行命令查看 docker.service 信息,得知配置文件位置 /lib/systemd/system/docker.service

1
2
3
4
5
6
7
8
9
10
11
~$ systemctl status docker.service 
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2023-06-13 00:52:54 CST; 22h ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 387690 (dockerd)
Tasks: 139
Memory: 89.6M
CPU: 1min 26.512s
CGroup: /system.slice/docker.service

docker.service[Service] 模块添加:

1
2
3
Environment=HTTP_PROXY=http://proxyAddress:port
Environment=HTTPS_PROXY=http://proxyAddress:port
Environment=NO_PROXY=localhost,127.0.0.1

重新加载配置文件并重启服务:

1
2
systemctl daemon-reload
systemctl restart docker.service

修改 dockerd 配置文件

还可以修改 dockerd 配置文件,添加:

1
export http_proxy="http://proxyAddress:port"

然后重启 docker daemon 即可。

国内的镜像仓库在绝大多数时候都可以满足条件,但是存在个别镜像同步不及时的情况,如果使用 latest 标签拉取到的镜像并非近期的镜像,因此有时候需要直接从官方镜像仓库拉取镜像。

为 docker 容器设置代理

docker daemon 进程设置代理和为 docker 容器设置代理是有区别的。比如使用 docker 启动媒体服务器 jellyfin 后,jellyfin 的刮削功能就需要代理才能正常使用,这时候不要因为在很多地方设置过代理就以为容器内部已经在使用代理了。

修改配置文件

创建或修改 ~/.docker/config.json,添加:

1
2
3
4
5
6
7
8
9
10
11
{
"proxies":
{
"default":
{
"httpProxy": "http://proxyAddress:port",
"httpsProxy": "http://proxyAddress:port",
"noProxy": "localhost,127.0.0.1"
}
}
}

此后创建的新容器,会自动设置环境变量来使用代理。

为指定容器添加环境变量

在启动容器时使用 -e 手动注入环境变量 http_proxy。这意味着进入容器使用 export 设置环境变量的方式也是可行的。

注意:如果代理是使用宿主机的代理,当网络为 bridge 模式,proxyAddress 需要填写宿主机的 IP;如果使用 host 模式,proxyAddress 可以填写 127.0.0.1。

总结

不要因为在很多地方设置过代理,就想当然地以为当前的访问也是经过代理的。每个软件设置代理的方式不尽相同,但是大体上可以归结为:

  1. 使用系统的环境变量
  2. 修改软件的配置文件
  3. 执行时注入参数

举一反三,像 aptgit 这类软件也是有其设置代理的方法。当你的代理稳定但是相应的访问失败时,大胆假设你的代理没有设置成功。要理清楚,当前的访问是谁发起的,才能正确地使用关键词搜索到正确的设置方式。

原本我在 docker 相关的使用中,有关代理的设置方式是通过修改配置文件,实现永久、全局的代理配置。但是在后续的使用中,发现代理在一些场景(比如使用 cloudflare tunnel)中会引起不易排查的问题,决定采用临时、局部的配置方式。

参考链接

Linux 让终端走代理的几种方法
Linux ❀ wget设置代理
配置Docker使用代理
Docker的三种网络代理配置
docker 设置代理,以及国内加速镜像设置

本文记录了如何在 iOSmacOS 上安装和配置 OpenVPN 客户端,主要介绍如何编写客户端配置文件 client.ovpn 并导入。

阅读全文 »

本文记录了如何在 Ubuntu 上安装 Clash,以供各类程序在必要的时候使用代理。
有些时候我们面对特定资源会遇到下载速度极其缓慢甚至无法下载的情况,像是使用 Github,下载 k8s 相关镜像,还有访问特定网站等等。也许有些 Dirty Hack 的方式可以短暂地绕开限制,比如修改 hosts 文件,但这并不总是见效。也许添加国内的镜像仓库地址可以满足很多人的需求,但是说不准就会遇到镜像更新不及时甚至镜像被污染的情况。总之,如果你有一把不错的梯子,使用代理辅助开发肯定会拥有更好的体验。
当然,为 Git 设置代理,为 Terminal 设置代理,为 Docker Engine 设置代理,为 Docker 容器设置代理,为 “还有一些你尚未知道原来这还需要这样设置代理的地方” 设置代理,仍然是一件痛苦的事情。如果你有条件为全屋设备配置透明代理,肯定能避免踩非常多的坑。

阅读全文 »

根据个人使用经验记录常用的 MySQL 命令作为备忘清单。

阅读全文 »
0%