当前位置: 首页 > news >正文

在WSL2的Ubuntu中安装和使用Docker/Podman

在WSL2的Ubuntu中安装和使用Docker/Podman

0. 目的

当网络环境良好(例如在公司,能直接访问Google等)时, Docker/Podman 安装和使用不是问题。

当网络环境不佳(例如在家里),要把 WSL2 的 Ubuntu 安装好 Docker, 并顺利拉取 Docker/Podman 镜像, 并且运行的镜像实例也需要把网络问题搞定,我踩了5个坑, 记录如下。

我使用 WSL2, Ubuntu22.04。

1. 第一个坑:Docker Desktop 的 “诱惑”

Docker 官方文档太乱,两句话说清楚的非要写两百句, 动不动就让你安装 Docker Desktop。 装了有什么好处呢? 除了潜在的 “商业用途, 交钱”,我没看到任何用处。

2. 第二个坑:艰难的获取 docker 安装脚本

不要和我提 ubuntu, centos, fedora 每个发行版的安装方式有差异。 docker 官方你老早就提供了一键安装脚本,为啥不放明显位置让我们使用呢?

网络如果 OK, 就这么一句话,完事儿了:

curl -fsSL https://get.docker.com/ | sh

然而网络不好,https://get.docker.com/ 从 WSL 里访问不到。 直接从 Windows 浏览器访问,发现就是一段脚本。 拷过来:

点击展开/折叠
#!/bin/sh
set -e
# Docker Engine for Linux installation script.
#
# This script is intended as a convenient way to configure docker's package
# repositories and to install Docker Engine, This script is not recommended
# for production environments. Before running this script, make yourself familiar
# with potential risks and limitations, and refer to the installation manual
# at https://docs.docker.com/engine/install/ for alternative installation methods.
#
# The script:
#
# - Requires `root` or `sudo` privileges to run.
# - Attempts to detect your Linux distribution and version and configure your
#   package management system for you.
# - Doesn't allow you to customize most installation parameters.
# - Installs dependencies and recommendations without asking for confirmation.
# - Installs the latest stable release (by default) of Docker CLI, Docker Engine,
#   Docker Buildx, Docker Compose, containerd, and runc. When using this script
#   to provision a machine, this may result in unexpected major version upgrades
#   of these packages. Always test upgrades in a test environment before
#   deploying to your production systems.
# - Isn't designed to upgrade an existing Docker installation. When using the
#   script to update an existing installation, dependencies may not be updated
#   to the expected version, resulting in outdated versions.
#
# Source code is available at https://github.com/docker/docker-install/
#
# Usage
# ==============================================================================
#
# To install the latest stable versions of Docker CLI, Docker Engine, and their
# dependencies:
#
# 1. download the script
#
#   $ curl -fsSL https://get.docker.com -o install-docker.sh
#
# 2. verify the script's content
#
#   $ cat install-docker.sh
#
# 3. run the script with --dry-run to verify the steps it executes
#
#   $ sh install-docker.sh --dry-run
#
# 4. run the script either as root, or using sudo to perform the installation.
#
#   $ sudo sh install-docker.sh
#
# Command-line options
# ==============================================================================
#
# --version <VERSION>
# Use the --version option to install a specific version, for example:
#
#   $ sudo sh install-docker.sh --version 23.0
#
# --channel <stable|test>
#
# Use the --channel option to install from an alternative installation channel.
# The following example installs the latest versions from the "test" channel,
# which includes pre-releases (alpha, beta, rc):
#
#   $ sudo sh install-docker.sh --channel test
#
# Alternatively, use the script at https://test.docker.com, which uses the test
# channel as default.
#
# --mirror <Aliyun|AzureChinaCloud>
#
# Use the --mirror option to install from a mirror supported by this script.
# Available mirrors are "Aliyun" (https://mirrors.aliyun.com/docker-ce), and
# "AzureChinaCloud" (https://mirror.azure.cn/docker-ce), for example:
#
#   $ sudo sh install-docker.sh --mirror AzureChinaCloud
#
# ==============================================================================# Git commit from https://github.com/docker/docker-install when
# the script was uploaded (Should only be modified by upload job):
SCRIPT_COMMIT_SHA="6d9743e9656cc56f699a64800b098d5ea5a60020"# strip "v" prefix if present
VERSION="${VERSION#v}"# The channel to install from:
#   * stable
#   * test
#   * edge (deprecated)
#   * nightly (deprecated)
DEFAULT_CHANNEL_VALUE="stable"
if [ -z "$CHANNEL" ]; thenCHANNEL=$DEFAULT_CHANNEL_VALUE
fiDEFAULT_DOWNLOAD_URL="https://download.docker.com"
if [ -z "$DOWNLOAD_URL" ]; thenDOWNLOAD_URL=$DEFAULT_DOWNLOAD_URL
fiDEFAULT_REPO_FILE="docker-ce.repo"
if [ -z "$REPO_FILE" ]; thenREPO_FILE="$DEFAULT_REPO_FILE"
fimirror=''
DRY_RUN=${DRY_RUN:-}
while [ $# -gt 0 ]; docase "$1" in--channel)CHANNEL="$2"shift;;--dry-run)DRY_RUN=1;;--mirror)mirror="$2"shift;;--version)VERSION="${2#v}"shift;;--*)echo "Illegal option $1";;esacshift $(( $# > 0 ? 1 : 0 ))
donecase "$mirror" inAliyun)DOWNLOAD_URL="https://mirrors.aliyun.com/docker-ce";;AzureChinaCloud)DOWNLOAD_URL="https://mirror.azure.cn/docker-ce";;"");;*)>&2 echo "unknown mirror '$mirror': use either 'Aliyun', or 'AzureChinaCloud'."exit 1;;
esaccase "$CHANNEL" instable|test);;edge|nightly)>&2 echo "DEPRECATED: the $CHANNEL channel has been deprecated and is no longer supported by this script."exit 1;;*)>&2 echo "unknown CHANNEL '$CHANNEL': use either stable or test."exit 1;;
esaccommand_exists() {command -v "$@" > /dev/null 2>&1
}# version_gte checks if the version specified in $VERSION is at least the given
# SemVer (Maj.Minor[.Patch]), or CalVer (YY.MM) version.It returns 0 (success)
# if $VERSION is either unset (=latest) or newer or equal than the specified
# version, or returns 1 (fail) otherwise.
#
# examples:
#
# VERSION=23.0
# version_gte 23.0  // 0 (success)
# version_gte 20.10 // 0 (success)
# version_gte 19.03 // 0 (success)
# version_gte 21.10 // 1 (fail)
version_gte() {if [ -z "$VERSION" ]; thenreturn 0fieval version_compare "$VERSION" "$1"
}# version_compare compares two version strings (either SemVer (Major.Minor.Path),
# or CalVer (YY.MM) version strings. It returns 0 (success) if version A is newer
# or equal than version B, or 1 (fail) otherwise. Patch releases and pre-release
# (-alpha/-beta) are not taken into account
#
# examples:
#
# version_compare 23.0.0 20.10 // 0 (success)
# version_compare 23.0 20.10   // 0 (success)
# version_compare 20.10 19.03  // 0 (success)
# version_compare 20.10 20.10  // 0 (success)
# version_compare 19.03 20.10  // 1 (fail)
version_compare() (set +xyy_a="$(echo "$1" | cut -d'.' -f1)"yy_b="$(echo "$2" | cut -d'.' -f1)"if [ "$yy_a" -lt "$yy_b" ]; thenreturn 1fiif [ "$yy_a" -gt "$yy_b" ]; thenreturn 0fimm_a="$(echo "$1" | cut -d'.' -f2)"mm_b="$(echo "$2" | cut -d'.' -f2)"# trim leading zeros to accommodate CalVermm_a="${mm_a#0}"mm_b="${mm_b#0}"if [ "${mm_a:-0}" -lt "${mm_b:-0}" ]; thenreturn 1fireturn 0
)is_dry_run() {if [ -z "$DRY_RUN" ]; thenreturn 1elsereturn 0fi
}is_wsl() {case "$(uname -r)" in*microsoft* ) true ;; # WSL 2*Microsoft* ) true ;; # WSL 1* ) false;;esac
}is_darwin() {case "$(uname -s)" in*darwin* ) true ;;*Darwin* ) true ;;* ) false;;esac
}deprecation_notice() {distro=$1distro_version=$2echoprintf "\033[91;1mDEPRECATION WARNING\033[0m\n"printf "    This Linux distribution (\033[1m%s %s\033[0m) reached end-of-life and is no longer supported by this script.\n" "$distro" "$distro_version"echo   "    No updates or security fixes will be released for this distribution, and users are recommended"echo   "    to upgrade to a currently maintained version of $distro."echoprintf   "Press \033[1mCtrl+C\033[0m now to abort this script, or wait for the installation to continue."echosleep 10
}get_distribution() {lsb_dist=""# Every system that we officially support has /etc/os-releaseif [ -r /etc/os-release ]; thenlsb_dist="$(. /etc/os-release && echo "$ID")"fi# Returning an empty string here should be alright since the# case statements don't act unless you provide an actual valueecho "$lsb_dist"
}echo_docker_as_nonroot() {if is_dry_run; thenreturnfiif command_exists docker && [ -e /var/run/docker.sock ]; then(set -x$sh_c 'docker version') || truefi# intentionally mixed spaces and tabs here -- tabs are stripped by "<<-EOF", spaces are kept in the outputechoecho "================================================================================"echoif version_gte "20.10"; thenecho "To run Docker as a non-privileged user, consider setting up the"echo "Docker daemon in rootless mode for your user:"echoecho "    dockerd-rootless-setuptool.sh install"echoecho "Visit https://docs.docker.com/go/rootless/ to learn about rootless mode."echofiechoecho "To run the Docker daemon as a fully privileged service, but granting non-root"echo "users access, refer to https://docs.docker.com/go/daemon-access/"echoecho "WARNING: Access to the remote API on a privileged Docker daemon is equivalent"echo "         to root access on the host. Refer to the 'Docker daemon attack surface'"echo "         documentation for details: https://docs.docker.com/go/attack-surface/"echoecho "================================================================================"echo
}# Check if this is a forked Linux distro
check_forked() {# Check for lsb_release command existence, it usually exists in forked distrosif command_exists lsb_release; then# Check if the `-u` option is supportedset +elsb_release -a -u > /dev/null 2>&1lsb_release_exit_code=$?set -e# Check if the command has exited successfully, it means we're in a forked distroif [ "$lsb_release_exit_code" = "0" ]; then# Print info about current distrocat <<-EOFYou're using '$lsb_dist' version '$dist_version'.EOF# Get the upstream release infolsb_dist=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'id' | cut -d ':' -f 2 | tr -d '[:space:]')dist_version=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'codename' | cut -d ':' -f 2 | tr -d '[:space:]')# Print info about upstream distrocat <<-EOFUpstream release is '$lsb_dist' version '$dist_version'.EOFelseif [ -r /etc/debian_version ] && [ "$lsb_dist" != "ubuntu" ] && [ "$lsb_dist" != "raspbian" ]; thenif [ "$lsb_dist" = "osmc" ]; then# OSMC runs Raspbianlsb_dist=raspbianelse# We're Debian and don't even know it!lsb_dist=debianfidist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')"case "$dist_version" in12)dist_version="bookworm";;11)dist_version="bullseye";;10)dist_version="buster";;9)dist_version="stretch";;8)dist_version="jessie";;esacfififi
}do_install() {echo "# Executing docker install script, commit: $SCRIPT_COMMIT_SHA"if command_exists docker; thencat >&2 <<-'EOF'Warning: the "docker" command appears to already exist on this system.If you already have Docker installed, this script can cause trouble, which iswhy we're displaying this warning and provide the opportunity to cancel theinstallation.If you installed the current Docker package using this script and are using itagain to update Docker, you can safely ignore this message.You may press Ctrl+C now to abort this script.EOF( set -x; sleep 20 )fiuser="$(id -un 2>/dev/null || true)"sh_c='sh -c'if [ "$user" != 'root' ]; thenif command_exists sudo; thensh_c='sudo -E sh -c'elif command_exists su; thensh_c='su -c'elsecat >&2 <<-'EOF'Error: this installer needs the ability to run commands as root.We are unable to find either "sudo" or "su" available to make this happen.EOFexit 1fifiif is_dry_run; thensh_c="echo"fi# perform some very rudimentary platform detectionlsb_dist=$( get_distribution )lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')"if is_wsl; thenechoecho "WSL DETECTED: We recommend using Docker Desktop for Windows."echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop/"echocat >&2 <<-'EOF'You may press Ctrl+C now to abort this script.EOF( set -x; sleep 20 )ficase "$lsb_dist" inubuntu)if command_exists lsb_release; thendist_version="$(lsb_release --codename | cut -f2)"fiif [ -z "$dist_version" ] && [ -r /etc/lsb-release ]; thendist_version="$(. /etc/lsb-release && echo "$DISTRIB_CODENAME")"fi;;debian|raspbian)dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')"case "$dist_version" in12)dist_version="bookworm";;11)dist_version="bullseye";;10)dist_version="buster";;9)dist_version="stretch";;8)dist_version="jessie";;esac;;centos|rhel)if [ -z "$dist_version" ] && [ -r /etc/os-release ]; thendist_version="$(. /etc/os-release && echo "$VERSION_ID")"fi;;*)if command_exists lsb_release; thendist_version="$(lsb_release --release | cut -f2)"fiif [ -z "$dist_version" ] && [ -r /etc/os-release ]; thendist_version="$(. /etc/os-release && echo "$VERSION_ID")"fi;;esac# Check if this is a forked Linux distrocheck_forked# Print deprecation warnings for distro versions that recently reached EOL,# but may still be commonly used (especially LTS versions).case "$lsb_dist.$dist_version" indebian.stretch|debian.jessie)deprecation_notice "$lsb_dist" "$dist_version";;raspbian.stretch|raspbian.jessie)deprecation_notice "$lsb_dist" "$dist_version";;ubuntu.xenial|ubuntu.trusty)deprecation_notice "$lsb_dist" "$dist_version";;ubuntu.lunar|ubuntu.kinetic|ubuntu.impish|ubuntu.hirsute|ubuntu.groovy|ubuntu.eoan|ubuntu.disco|ubuntu.cosmic)deprecation_notice "$lsb_dist" "$dist_version";;fedora.*)if [ "$dist_version" -lt 36 ]; thendeprecation_notice "$lsb_dist" "$dist_version"fi;;esac# Run setup for each distro accordinglycase "$lsb_dist" inubuntu|debian|raspbian)pre_reqs="apt-transport-https ca-certificates curl"apt_repo="deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] $DOWNLOAD_URL/linux/$lsb_dist $dist_version $CHANNEL"(if ! is_dry_run; thenset -xfi$sh_c 'apt-get update -qq >/dev/null'$sh_c "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq $pre_reqs >/dev/null"$sh_c 'install -m 0755 -d /etc/apt/keyrings'$sh_c "curl -fsSL \"$DOWNLOAD_URL/linux/$lsb_dist/gpg\" -o /etc/apt/keyrings/docker.asc"$sh_c "chmod a+r /etc/apt/keyrings/docker.asc"$sh_c "echo \"$apt_repo\" > /etc/apt/sources.list.d/docker.list"$sh_c 'apt-get update -qq >/dev/null')pkg_version=""if [ -n "$VERSION" ]; thenif is_dry_run; thenecho "# WARNING: VERSION pinning is not supported in DRY_RUN"else# Will work for incomplete versions IE (17.12), but may not actually grab the "latest" if in the test channelpkg_pattern="$(echo "$VERSION" | sed 's/-ce-/~ce~.*/g' | sed 's/-/.*/g')"search_command="apt-cache madison docker-ce | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3"pkg_version="$($sh_c "$search_command")"echo "INFO: Searching repository for VERSION '$VERSION'"echo "INFO: $search_command"if [ -z "$pkg_version" ]; thenechoecho "ERROR: '$VERSION' not found amongst apt-cache madison results"echoexit 1fiif version_gte "18.09"; thensearch_command="apt-cache madison docker-ce-cli | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3"echo "INFO: $search_command"cli_pkg_version="=$($sh_c "$search_command")"fipkg_version="=$pkg_version"fifi(pkgs="docker-ce${pkg_version%=}"if version_gte "18.09"; then# older versions didn't ship the cli and containerd as separate packagespkgs="$pkgs docker-ce-cli${cli_pkg_version%=} containerd.io"fiif version_gte "20.10"; thenpkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version"fiif version_gte "23.0"; thenpkgs="$pkgs docker-buildx-plugin"fiif ! is_dry_run; thenset -xfi$sh_c "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq $pkgs >/dev/null")echo_docker_as_nonrootexit 0;;centos|fedora|rhel)if [ "$(uname -m)" != "s390x" ] && [ "$lsb_dist" = "rhel" ]; thenecho "Packages for RHEL are currently only available for s390x."exit 1fiif command_exists dnf; thenpkg_manager="dnf"pkg_manager_flags="--best"config_manager="dnf config-manager"enable_channel_flag="--set-enabled"disable_channel_flag="--set-disabled"pre_reqs="dnf-plugins-core"elsepkg_manager="yum"pkg_manager_flags=""config_manager="yum-config-manager"enable_channel_flag="--enable"disable_channel_flag="--disable"pre_reqs="yum-utils"fiif [ "$lsb_dist" = "fedora" ]; thenpkg_suffix="fc$dist_version"elsepkg_suffix="el"firepo_file_url="$DOWNLOAD_URL/linux/$lsb_dist/$REPO_FILE"(if ! is_dry_run; thenset -xfi$sh_c "$pkg_manager $pkg_manager_flags install -y -q $pre_reqs"$sh_c "$config_manager --add-repo $repo_file_url"if [ "$CHANNEL" != "stable" ]; then$sh_c "$config_manager $disable_channel_flag 'docker-ce-*'"$sh_c "$config_manager $enable_channel_flag 'docker-ce-$CHANNEL'"fi$sh_c "$pkg_manager makecache")pkg_version=""if [ -n "$VERSION" ]; thenif is_dry_run; thenecho "# WARNING: VERSION pinning is not supported in DRY_RUN"elsepkg_pattern="$(echo "$VERSION" | sed 's/-ce-/\\\\.ce.*/g' | sed 's/-/.*/g').*$pkg_suffix"search_command="$pkg_manager list --showduplicates docker-ce | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'"pkg_version="$($sh_c "$search_command")"echo "INFO: Searching repository for VERSION '$VERSION'"echo "INFO: $search_command"if [ -z "$pkg_version" ]; thenechoecho "ERROR: '$VERSION' not found amongst $pkg_manager list results"echoexit 1fiif version_gte "18.09"; then# older versions don't support a cli packagesearch_command="$pkg_manager list --showduplicates docker-ce-cli | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'"cli_pkg_version="$($sh_c "$search_command" | cut -d':' -f 2)"fi# Cut out the epoch and prefix with a '-'pkg_version="-$(echo "$pkg_version" | cut -d':' -f 2)"fifi(pkgs="docker-ce$pkg_version"if version_gte "18.09"; then# older versions didn't ship the cli and containerd as separate packagesif [ -n "$cli_pkg_version" ]; thenpkgs="$pkgs docker-ce-cli-$cli_pkg_version containerd.io"elsepkgs="$pkgs docker-ce-cli containerd.io"fifiif version_gte "20.10"; thenpkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version"fiif version_gte "23.0"; thenpkgs="$pkgs docker-buildx-plugin"fiif ! is_dry_run; thenset -xfi$sh_c "$pkg_manager $pkg_manager_flags install -y -q $pkgs")echo_docker_as_nonrootexit 0;;sles)if [ "$(uname -m)" != "s390x" ]; thenecho "Packages for SLES are currently only available for s390x"exit 1firepo_file_url="$DOWNLOAD_URL/linux/$lsb_dist/$REPO_FILE"pre_reqs="ca-certificates curl libseccomp2 awk"(if ! is_dry_run; thenset -xfi$sh_c "zypper install -y $pre_reqs"$sh_c "zypper addrepo $repo_file_url"if ! is_dry_run; thencat >&2 <<-'EOF'WARNING!!openSUSE repository (https://download.opensuse.org/repositories/security:/SELinux) will be enabled now.Do you wish to continue?You may press Ctrl+C now to abort this script.EOF( set -x; sleep 30 )fiopensuse_repo="https://download.opensuse.org/repositories/security:/SELinux/openSUSE_Factory/security:SELinux.repo"$sh_c "zypper addrepo $opensuse_repo"$sh_c "zypper --gpg-auto-import-keys refresh"$sh_c "zypper lr -d")pkg_version=""if [ -n "$VERSION" ]; thenif is_dry_run; thenecho "# WARNING: VERSION pinning is not supported in DRY_RUN"elsepkg_pattern="$(echo "$VERSION" | sed 's/-ce-/\\\\.ce.*/g' | sed 's/-/.*/g')"search_command="zypper search -s --match-exact 'docker-ce' | grep '$pkg_pattern' | tail -1 | awk '{print \$6}'"pkg_version="$($sh_c "$search_command")"echo "INFO: Searching repository for VERSION '$VERSION'"echo "INFO: $search_command"if [ -z "$pkg_version" ]; thenechoecho "ERROR: '$VERSION' not found amongst zypper list results"echoexit 1fisearch_command="zypper search -s --match-exact 'docker-ce-cli' | grep '$pkg_pattern' | tail -1 | awk '{print \$6}'"# It's okay for cli_pkg_version to be blank, since older versions don't support a cli packagecli_pkg_version="$($sh_c "$search_command")"pkg_version="-$pkg_version"fifi(pkgs="docker-ce$pkg_version"if version_gte "18.09"; thenif [ -n "$cli_pkg_version" ]; then# older versions didn't ship the cli and containerd as separate packagespkgs="$pkgs docker-ce-cli-$cli_pkg_version containerd.io"elsepkgs="$pkgs docker-ce-cli containerd.io"fifiif version_gte "20.10"; thenpkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version"fiif version_gte "23.0"; thenpkgs="$pkgs docker-buildx-plugin"fiif ! is_dry_run; thenset -xfi$sh_c "zypper -q install -y $pkgs")echo_docker_as_nonrootexit 0;;*)if [ -z "$lsb_dist" ]; thenif is_darwin; thenechoecho "ERROR: Unsupported operating system 'macOS'"echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop"echoexit 1fifiechoecho "ERROR: Unsupported distribution '$lsb_dist'"echoexit 1;;esacexit 1
}# wrapped up in a function so that we have some protection against only getting
# half the file during "curl | sh"
do_install

下载保存为 get-docker.sh, 放到 WSL 的目录中。

3. 第三个坑:执行脚本会卡住

正常人肯定是这样执行的:

sudo sh ./get-docker.sh

但是 get-docker.sh 里引用的 URL, 你还是访问不了。

必须换一个 DOWNLOAD_URL 来执行:

export DOWNLOAD_URL="https://mirrors.tuna.tsinghua.edu.cn/docker-ce"
sudo sh ./get-docker.sh

既然能换 URL, 咱能不能在网页加一个选项, 自动生成下载正确的脚本, 就像 mirrors.zju.edu.cn 那样的?

(ref: https://mirror.tuna.tsinghua.edu.cn/help/docker-ce/)

P.S. 在尝试排查 docker 网络问题时, 也顺带安装了 podman:

sudo apt-get -y install podman

4. 第四个坑: 安装 docker 后, hello-world 镜像拉取不下来

正常人安装 docker 后, 安装官方文档,拉取最简单的镜像试验下能否使用, 应该说5秒之内能搞定:

docker pull hello-world

然而我们错了, 等了1分钟可能都没动静。

这时候各种瞎试开始了,可能2小时都没搞定。 我的 Windows 是默认安装后几乎没配置的, WSL 是默认安装后没有配置过(配置常规ubuntu共有的不算), 我的 Docker 也是一样的。 怎么默认的就不行呢?

实际上,前面三个坑,都没有本质上解决 WSL 里面的问题: 网络不通畅。 正确解决思路, 是从整体做一次配置, 让任何命令行都能网络通畅, 而不是什么 “手动下载”, “改国内 mirror”。。。

4.1 有效的配置1: .wslconfig

创建 C:/Users/<用户名>/.wslconfig 文件,填入:

[experimental]
autoMemoryReclaim=gradual
networkingMode=mirrored
dnsTunneling=true
firewall=true
autoProxy=true

这解决了当你在 host 开启代理后进入 WSL 时的提示:

PS C:\Users\zz> wsl
wsl: 检测到 localhost 代理配置,但未镜像到 WSL。NAT 模式下的 WSL 不支持 localhost 代理。

4.2 有效的配置2: /etc/wsl.conf

sudo vim /etc/wsl.conf, 填入内容:

[boot]
systemd=true[network]
generateResolvConf = false

这解决的是, 先前修改了/etc/resolv.conf 时, 只有第一次 nameserver 的行,是正常的, 增加的两行的 IP 地址被提示为红色, 意思是配置无效:

# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 127.0.0.42
nameserver 114.114.114.114
nameserver 8.8.8.8

4.3 有效的设定4: /etc/resolv.conf

DNS servers
nameserver 114.114.114.114
nameserver 8.8.8.8

4.4 有效的设定3: 在 host 开启代理

不管是哪种代理。 总之, 由于 ~/.wslconfig 的配置, 现在里外用同样的网络了。

4.5 有效的设定4: 重启 WSL

在 PowerShell 里执行

wsl --shutdown
wsl

4.6 podman镜像: 和镜像无法拉取没关系

修改了 vim /etc/containers/registries.conf, 填入了 (验证了,非必要)

unqualified-search-registries = ["docker.io", "registry.cn-hangzhou.aliyuncs.com"]

4.7 重新安装 docker: 放弃

由于这一小节的网络配通, 让 podman 能拉取镜像, 一度让我尝试重新安装 docker。 然而 docker 的安装脚本还是太冗长了, 而 podman 的常规命令又和 docker 是兼容的,并且 apt 官方提供了 podman 包, 那就不折腾 docker 了。

5. 第五个坑:podman开启的镜像提示说代理不通

当第四步拉取了镜像, 人们很容易觉得万事大吉了。 在开启镜像后, 例如 ubuntu20.04, 第一步是apt更新,然后打算安装 gcc 等开发工具, 于是执行:

podman run -it -v $(pwd):/mnt ubuntu:20.04 /bin/bash

此时遇到网络问题:

Could not connect to 127.0.0.1:59133 (127.0.0.1). - connect (111: Connection refused)

也尝试了换 podman 镜像实例(ubuntu20.04) 里的 apt 源, 报错没变化。

尝试了临时关掉 HTTP_PROXY, HTTPS_PROXY 环境变量后再开启 podman 镜像实例,无效。

尝试了关闭 host 的代理, 无效。

解决办法: 尝试使用不同的网络模式启动容器, 例如指定 --network host 参数

podman run --network host -it -v $(pwd):/mnt ubuntu:20.04 /bin/bash

References

https://mirror.tuna.tsinghua.edu.cn/help/docker-ce/

https://docs.docker.com/engine/install/ubuntu/

https://zhuanlan.zhihu.com/p/670958325

相关文章:

在WSL2的Ubuntu中安装和使用Docker/Podman

在WSL2的Ubuntu中安装和使用Docker/Podman 0. 目的 当网络环境良好&#xff08;例如在公司&#xff0c;能直接访问Google等&#xff09;时&#xff0c; Docker/Podman 安装和使用不是问题。 当网络环境不佳&#xff08;例如在家里&#xff09;&#xff0c;要把 WSL2 的 Ubun…...

【WEEK16】Learning Objectives and Summaries【Spring Boot】【English Version】

Learning Objectives: Learning SpringBoot Learning Content: Reference video tutorials【狂神说Java】SpringBoot最新教程IDEA版通俗易懂Dubbo and Zookeeper Integration Learning time and outputs: Week16 TUE~FRI 2024.6.11【WEEK16】 【DAY2】Dubbo和Zookeeper集成第…...

AI大模型会让搜索引擎成为历史吗?

AI大模型会让搜索引擎成为历史吗&#xff1f; 随着人工智能技术的不断发展&#xff0c;AI大模型已经在许多领域展现出了强大的能力。从自然语言处理到图像识别&#xff0c;AI大模型的应用越来越广泛。在这种背景下&#xff0c;有人开始提出一个问题&#xff1a;AI大模型是否可…...

SpringSecurity6从入门到实战之SpringSecurity6自定义认证规则

SpringSecurity6从入门到实战之SpringSecurity6自定义认证规则 Spring Security 中默认所有的 http 请求都需要先认证通过后&#xff0c;才能访问。那么&#xff0c; 如何指定不需要认证就可以直接访问的资源呢&#xff1f;比如 用户的登录页面和注册页面&#xff0c;都是不需要…...

Java IO:byte[]、char[]、String三种对象的转换

String与byte[]对象进行转换时应指定编码格式&#xff0c;否则有潜在的乱码问题。byte[] b s.getBytes(“utf-8”); String s new String(b,“utf-8”); Java的IO库提供了专门的管道来对这3个对象进行读写&#xff0c;他们是StringReader/Writer CharArrayReader/Writer Byt…...

Elasticsearch:简化数据流的数据生命周期管理

作者&#xff1a;来自 Elastic Andrei Dan 今天&#xff0c;我们将探索 Elasticsearch 针对数据流的新数据管理系统&#xff1a;数据流生命周期&#xff0c;从版本 8.14 开始提供。凭借其简单而强大的执行模型&#xff0c;数据流生命周期可让n 你专注于数据生命周期的业务相关方…...

Verilog综合出来的图

Verilog写代码时需要清楚自己综合出来的是组合逻辑、锁存器还是寄存器。 甚至&#xff0c;有时写的代码有误&#xff0c;vivado不能识别出来&#xff0c;这时打开综合后的schematic简单查看一下是否综合出想要的结果。 比如&#xff1a;误将一个always模块重复一遍&#xff0c;…...

KT-H6测距模块标品,测距范围1500m,demo报价1000RMB,批量报价500RMB

激光测距传感器是一种用于测量距离的模块,通常由传感器和相关电子设备组成,测距模块可以集成到各种设备和系统中,以实现准确的测距和定位功能。KT-H6系列激光测距模块,为自主研发,激光波长905nm的激光器,专为热成像、夜视仪、无人机、安防、瞄具等产品定身打造,其优点是…...

C数据结构:排序

目录 冒泡排序 选择排序 堆排序 插入排序 希尔排序 快速排序 hoare版本 挖坑法 前后指针法 快速排序优化 三数取中法 小区间优化 快速排序非递归 栈版本 队列版本 归并排序 归并排序非递归 ​编辑 计数排序 各排序时间、空间、稳定汇总 冒泡排序 void Bub…...

【Python】在 Pandas 中使用 AdaBoost 进行分类

我们都找到天使了 说好了 心事不能偷藏着 什么都 一起做 幸福得 没话说 把坏脾气变成了好沟通 我们都找到天使了 约好了 负责对方的快乐 阳光下 的山坡 你素描 的以后 怎么抄袭我脑袋 想的 &#x1f3b5; 薛凯琪《找到天使了》 在数据科学和机器学习的工作…...

持续总结中!2024年面试必问 20 道并发编程面试题(九)

上一篇地址&#xff1a;持续总结中&#xff01;2024年面试必问 20 道并发编程面试题&#xff08;八&#xff09;-CSDN博客 十七、请解释什么是Callable和FutureTask。 Callable和FutureTask是Java并发API中的重要组成部分&#xff0c;它们用于处理可能产生结果的异步任务。 …...

Linux:线程池

Linux&#xff1a;线程池 线程池概念封装线程基本结构构造函数相关接口线程类总代码 封装线程池基本结构构造与析构初始化启动与回收主线程放任务其他线程读取任务终止线程池测试线程池总代码 线程池概念 线程池是一种线程使用模式。线程过多会带来调度开销&#xff0c;进而影…...

集成学习方法:Bagging与Boosting的应用与优势

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…...

JEnv-for-Windows 2 java版本工具的安装使用踩坑

0.环境 windows11pro 1.工具下载 GitHub - Mu-L/JEnv-for-Windows: Change your current Java version with one line or JEnv-for-Windows:Change your current Java version with one line - GitCode 2.执行jenv 初始化 2.1 问题&#xff1a;PowerShell 未对文件\XXX.…...

linux中: IDEA 由于JVM 设置内存过小,导致打开项目闪退问题

1. 找到idea安装目录 由于无法打开idea&#xff0c;只能找到idea安装目录 在linux(debian/ubuntu)中idea的插件默认安装位置和配置文件在哪里? 默认路径&#xff1a; /home/当前用户名/.config/JetBrains/IntelliJIdea2020.具体版本号/options2. 找到jvm配置文件 IDEA安装…...

d3.js获取流程图不同的节点

在D3.js中&#xff0c;获取流程图中不同的节点通常是通过选择SVG元素并使用数据绑定来实现的。流程图的节点可以通过BPMN、JSON或其他数据格式定义&#xff0c;然后在D3.js中根据这些数据动态生成和选择节点。 以下是一个基本的示例&#xff0c;展示如何使用D3.js选择和操作流…...

MFC socket编程-服务端和客户端流程

MFC 提供了一套丰富的类库来简化 Windows 应用程序的网络编程。以下是使用 MFC 进行 socket 编程时服务端和客户端的基本流程&#xff1a; 服务端流程&#xff1a; 初始化 Winsock&#xff1a; 调用 AfxSocketInit 初始化 Winsock 库。 创建 CSocket 或 CAsyncSocket 对象&am…...

22.1 正则表达式-定义正则表达式、正则语法

1.定义正则表达式 正则表达式意在描述隐藏在数据中的某种模式或规则。 例如&#xff1a;下面的几个字符串看似各不相同&#xff1a; slimshady999roger1813Wagner但看似不同的数据却隐藏着相同的特征&#xff1a; 仅由英语字母和数字组成英语字母有小写也有大写总字符数介于 …...

网络数据包抓取与分析工具wireshark的安及使用

WireShark安装和使用 WireShark是非常流行的网络封包分析工具&#xff0c;可以截取各种网络数据包&#xff0c;并显示数据包详细信息。常用于开发测试过程中各种问题定位。 1 任务目标 1.1 知识目标 了解WireShark的过滤器使用,通过过滤器可以筛选出想要分析的内容 掌握Wir…...

Docker镜像技术剖析

目录 1、概述1.1 什么是镜像&#xff1f;1.2 联合文件系统UnionFS1.3 bootfs和rootfs1.4 镜像结构1.5 镜像的主要技术特点1.5.1 镜像分层技术1.5.2 写时复制(copy-on-write)策略1.5.3 内容寻址存储(content-addressable storage)机制1.5.4 联合挂载(union mount)技术 2.机制原理…...

log4j漏洞学习

log4j漏洞学习 总结基础知识属性占位符之Interpolator&#xff08;插值器&#xff09;模式布局日志级别 Jndi RCE CVE-2021-44228环境搭建漏洞复现代码分析日志记录/触发点消息格式化 Lookup 处理JNDI 查询触发条件敏感数据带外漏洞修复MessagePatternConverter类JndiManager#l…...

架构设计 - WEB项目的基础序列化配置

摘要&#xff1a;web项目中做好基础架构(redis&#xff0c;json)的序列化配置有重要意义 支持复杂数据结构&#xff1a;Redis 支持多种不同的数据结构&#xff0c;如字符串、哈希表、列表、集合和有序集合。在将这些数据结构存储到 Redis 中时&#xff0c;需要将其序列化为字节…...

java(JVM)

JVM Java的JVM&#xff08;Java虚拟机&#xff09;是运行Java程序的关键部件。它不直接理解或执行Java源代码&#xff0c;而是与Java编译器生成的字节码&#xff08;Bytecode&#xff09;进行交互。下面是对Java JVM更详尽的解释&#xff1a; 1.字节码&#xff1a; 当你使用J…...

【网络安全】【深度学习】【入侵检测】SDN模拟网络入侵攻击并检测,实时检测,深度学习【二】

文章目录 1. 习惯终端2. 启动攻击3. 接受攻击4. 宿主机查看h2机器 1. 习惯终端 上次把ubuntu 22自带的终端玩没了&#xff0c;治好用xterm&#xff1a; 以通过 AltF2 然后输入 xterm 尝试打开xterm 。 然后输入这个切换默认的终端&#xff1a; sudo update-alternatives --co…...

飞腾银河麒麟V10安装Todesk

下载安装包 下载地址 https://www.todesk.com/linux.html 安装 yum makecache yum install libappindicator-gtk3-devel.aarch64 rpm -ivh 下载的安装包文件后台启动 service todeskd start修改配置 编辑 /opt/todesk/config/config.ini 移除自动更新临时密码 passupda…...

JWT令牌、过滤器Filter、拦截器Interceptor

目录 JWT令牌 简介 JWT生成 解析JWT 登陆后下发令牌 过滤器(Filter) Filter快速入门 Filter拦截路径 过滤器链 登录校验Filter-流程 拦截器(Interceptor) Interceptor 快速入门 拦截路径 登录校验流程 JWT令牌 简介 全称:JSON Web Token(https://iwt.io/) …...

iText7画发票PDF——小tips

itext7教程&#xff1a; 1、https://blog.csdn.net/allway2/article/details/124295097 2、https://max.book118.com/html/2017/0720/123235195.shtm 3、https://www.cnblogs.com/fonks/p/15090635.html 4、https://www.cnblogs.com/sky-chen/p/13026203.html 5、官方&#xff…...

跟着刘二大人学pytorch(第---10---节课之卷积神经网络)

文章目录 0 前言0.1 课程链接&#xff1a;0.2 课件下载地址&#xff1a; 回忆卷积卷积过程&#xff08;以输入为单通道、1个卷积核为例&#xff09;卷积过程&#xff08;以输入为3通道、1个卷积核为例&#xff09;卷积过程&#xff08;以输入为N通道、1个卷积核为例&#xff09…...

transformer实战

1.pipeline() 首先下载transformer&#xff0c;之后 from transformers import pipeline# 加载一个用于文本分类的pipeline # Use a pipeline as a high-level helperpipe pipeline("zero-shot-classification", model"https://hf-mirror.com/morit/chinese_…...

【Starrocks docker-compose部署】

一、docker-compose部署starrocks 官方的docker-compose地址:docker-compose地址 version: "3.9" services:starrocks-fe-0:image: starrocks/fe-ubuntu:latesthostname: starrocks-fe-0container_name: starrocks-fe-0command:- /bin/bash- -c- |/opt/starrocks/f…...

vi设计案例ppt/网络推广优化培训

第一部分 Javascript弹出子窗口 可以通过多种方式实现&#xff0c;下面介绍几种方法 (1) 通过window对象的open()方法&#xff0c;open()方法将会产生一个新的window窗口对象 window.open(URL,windowName,parameters); 也可以这样写&#xff1a; var newWindow open(,_blank)…...

厦门网站建设外包/中国国家人事人才培训网证书查询

某些查询条件确定范围between and&#xff0c;not between and确定集合in&#xff0c;not in字符匹配like&#xff0c;not like空值is null&#xff0c;is not null多重条件and&#xff0c;or&#xff0c;not1。确定范围 查询年龄在&#xff08;不在&#xff09;21到24之间的学…...

厦门外贸网站建设哪家公司大/网络推广和运营的区别

java-访问限制&#xff1a;由于对所需库.. \ jre \ lib \ rt.j的限制而无法访问我正在尝试修改一些旧代码&#xff0c;而又得到以下错误&#xff1a;访问限制&#xff1a;由于必需的库.. \ jre \ lib \ rt.jar的限制&#xff0c;无法访问标头类型的方法create(JAXBRIContext&am…...

网站建设及数据分析/成都调查事务所

k个男生和k个女生站成一列&#xff0c;前面k个是男生&#xff0c;后面k个是女生&#xff0c;从第一个男生开始报数&#xff0c;报到队列最后一个同学&#xff0c;循环到队首继续报&#xff0c;并且如果一个同学报到的数是m&#xff0c;这个同学就出列&#xff0c;然后后面的同学…...

做网站的注意什么问题/房地产市场现状分析

更多Java全套学习资源均在专栏&#xff0c;持续更新中↑↑戳进去领取~ &#x1f357;MySQL的安装及登陆基本操作&#xff08;附图&#xff09;手把手带你安装 &#x1f357;MySQL基础&#xff1a;通过SQL对数据库进行CRUD &#x1f357;MySQL基础&#xff1a;通过SQL对表、数据…...

wordpress企业网站模板/北京百度推广公司

杨利民&#xff1a; 点击打开链接王静&#xff1a; 点击打开链接颜洁&#xff1a; 点击打开链接伍道军&#xff1a; 点击打开链接陈俊&#xff1a; 点击打开链接 向慧琳&#xff1a;点击打开链接 张埂铝&#xff1a;点击打开链接 蒋俊&#xff1a;点击打开链接 代思雨&#xff…...