Docker与NAT

昨天在火山云上抢到了29/年的一台小云服务器,今天用它做一下重做一下内网穿透的实验,顺便系统学习一遍docker的使用方法

实验说明:

  • 目标:借助云服务器完成内网穿透,学习docker的使用
  • 技术选择:frp与vaala的开源项目frp-panel
  • 参考资料:frp-panel的文档 与 B站上的docker入门教程
  • 环境说明:Linux iv-ydzvaocdmobw80cjj4s4 5.15.120-5.ve2.x86_64 #1 SMP Fri Nov 15 10:09:38 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

Docker

基本概念

容器:一个为特定应用程序封装的独立的运行环境,包含程序本体、依赖库和文件系统。相比于虚拟机没有操作系统部分。

镜像:容器的“安装包”,存在docker仓库以供分享,官方的仓库为dockerhub

安装

Docker技术是基于Linux系统的,所以windows和Mac上需要特殊处理(运行一个linux子系统),centOS直接来即可

第0步,更新:sudo yum update

然后,curl -fsSL https://get.docker.com -o install-docker.sh

sudo sh install-docker.sh

下载镜像

命令为docker pull XXX,后面的部分由三部分构成,registry类似于github的用户名 + 仓库名 + 镜像名:版本,默认最新

国内连不上docker的官方网站,需要翻墙改docker的配置文件换镜像站:

sudo vi /etc/docker/daemon.json以超级用户权限用vi打开对应路径下的文件

添加以下内容

{
    "registry-mirrors": [
        "https://docker.m.daocloud.io",
        "https://docker.1panel.live",
        "https://hub.rat.dev"
    ]
}

输入:wq!退出,提示E212: Can't open file for writing,教程没提到的意外,似乎是权限问题,先退出:q!。经排查docker没有正确完成安装,重装一遍解决。

然后重启sudo service docker restart

用nginx检验一下docker pull nginx

Status: Downloaded newer image for nginx:latest docker.io/library/nginx:latest成功

基本命令

sudo docker images展示所有下载过的镜像

sudo docker rmi XXXremove image,删除一个镜像,填写仓库名或ID

sudo docker run XXX运行一个docker

  • -d运行在后台
  • -p port1:port2,绑定端口,前为宿主机端口,后为容器内端口
  • -v 宿主机目录:容器内目录,绑定目录,建立一个映射
  • -e 后面跟着键值对,传递环境变量
  • –name 默认 自定义名字 ,给容器起名字,和ID作用相同
  • –rm容器停止时删除
  • -it让控制台进入容器内部
  • –restart 设置停止时的策略,
    • always 停止就重启
    • unless stopped 除非手动关闭否则自动重启(意外原因)

sudo docker ps process status,查看运行中的容器进程状态,-a all,展示所有容器包括未运行的

sudo docker rm XXX删除一个容器

  • -f force,强制删除

执行docker run一个本地没有的镜像时,默认行为是去仓库pull,所以第一步拉取镜像可以省略

sudo docker start XXX启动一个容器

sudo docker stop XXX停止一个容器

sudo docker inspect XXX 获取容器的配置文件

sudo docker create XXX 只创建容器不运行,参数同docker run

sudo docker logs XXX查看日志,-f滚动查看日志

Dockerfile

制作镜像的工具,即从一个本地运行的程序到一个镜像的指导文件

FROM …… 镜像从哪个镜像基础上构建而来,继承的感觉

WORKDIR 指定工作目录

COPY . . 本机当前目录到容器当前工作目录

RUN 在镜像里执行的命令

EXPOSE PORT 可不写,指定端口,优先级在运行容器时的-p 之后

CMD …… 容器运行时的默认启动命令

在命令行执行docker build -t newName . 在当前目录构建镜像

推送到dockerhub

docker login登录

docker push address推送,这一步需要镜像包含用户名作为命名空间

Docker网络

用于完成不同容器间的通信问题

docker network create XXX创建子网,同一子网之间可以互相通信,支持名称访问,也就是内置了一个小DNS

docker network rm XXX删除子网
容器在运行时加入-- network netName 完成加入网络

host模式,直接运行在宿主机的端口,和宿主机共享网络环境

none模式,不联网

Docker compose

解决的问题是,对于一个全栈项目把所有组件都打包在一起耦合性过高不便于调试,出错了会比较麻烦,而解决的方法是分开运行在多个容器,而Docker Compose就是用来管理编排多个容器的工具

用yaml文件统一管理配置,可以简单理解为把指令汇总到一个文件里,换一种记录格式。默认创建一个子网并把所有容器加入进去

sudo docker compose up创建这样一个docker集群,根据当前文件夹下的名为docker-compose.yaml的文件

sudo docker compose down停止并删除

sudo docker compose stop只停止不删除

sudo docker compose start让停止的运行

K8s:可以简单理解为docker compose plus

Frp-Panel

vaala在文档里提供了多种部署方法,选择docker compose的方法,因为编辑内容方便……如果编辑器再方便一点的话

vi docker-compose.yaml然后按照文档换密码和公网IP,然后运行docker compose up,自动拉取镜像并运行

开一下防火墙,浏览器访问IP:9000端口就可以进入到配置页面了,但是云服务器没有ssl证书,裸ip似乎是不能免费配,忽略吧

先了解一下frp的基本原理:简单的说就是通过一台公网可访问的服务器做中转,让外部可以访问一个内网设备。需要在云服务器上部署frp服务端,在内网设备上部署frp客户端,主动连接服务端

也就是说frp的配置是分开的,而frp-panel项目的目的是提供一个中心化的配置方案。设计架构是增加了一个管理server和client的master角色,管理者对master进行配置,而server和client在运行时都去master那里获取配置

接下来是具体配置,先服务端,公网IP,端口随便写一个,监听地址0.0.0.0;再客户端,保持默认配置复制启动命令,在本地执行windows命令,自动下载需要的东西,然后开始运行;下一步是新建隧道,选择好服务端和客户端、tcp、然后本地IP127.0.0.1、端口

最后开一下端口,完成!