广州 定制网站3000元,价格划算的网站开发,智慧团建登录官网手机版,开发一个同城app需要多少钱一、docker简介
docker是一种方便跨平台迁移应用的程序#xff0c;通过docker可以实现在同一类操作系统中#xff0c;如Ubuntu和RedHat两个linux操作系统中#xff0c;实现程序的跨平台部署。比如我在Ubuntu中打包了一个go项目的docker镜像#xff08;镜像为二进制文件通过docker可以实现在同一类操作系统中如Ubuntu和RedHat两个linux操作系统中实现程序的跨平台部署。比如我在Ubuntu中打包了一个go项目的docker镜像镜像为二进制文件相当于windows中的exe文件这个镜像可以直接在另一台Ubuntu上运行而无需再次配运行环境。下面这张图是我对docker的理解。 原始程序迁移方式 docker镜像迁移方式
二、dockerfile编写
将项目打包为docker镜像通过编写dockerfile来实现dockerfile的写法类似于shell编程。 PS最终的dockerfile不易过长但是调试时可以多些RUN这样可以减少重复编译提高调试速度因为每个语句都会被编译为一个镜像然后commit到一起形成一个最终的镜像。 其基本的结构如下
FROM ***指定基础镜像即这个镜像在哪个操作系统下面运行
#示例FROM Ubuntu:20.04MAINTAINER ***(指定维护者信息选填)
#示例MAINTAINER TomLABEL ***(docker build的启动入口可以不写)
#示例LABEL helloworldRUN ***(docker build时需要执行的命令为shell指令)
#RUN git clone github.com/xxxx.gitADD/COPY ***(将宿主机的文件拷贝到目标镜像中,ADD会自动解压COPY不会)
#示例:COPY . .
#前一个目录为当前文件夹下的相对路径后一个文件为dockerfile镜像中的路径WORKDIR ***设置当前工作目录相当于进入容器后在哪个目录里面VOLUME ***存放文件的地方也叫挂载主机目录分布式存储中使用EXPOSE ***指定对外的端口CMD ***指定容器启动后要做的事情打包镜像
docker build -t demo/go-hello:1.0 -f dockerfile .
#docker build为固定写法-t表示生成目标镜像的名字以及版本号 -f表示dockerfile文件的名称
#最后的‘.’表示当前目录下构建docker构建运行容器
docker run -it -p xxx:xxx
#-i 以交互模式运行-t 为容器分配一个命令行
#-p 容器端口映射到主机端口的模式
三、docker build原理
完成dockerfile后需要运行docker build命令来执行程序。 docker build的执行过程如下 1.将上下文打包发送到docker的守护进程 2.docker build 命令向docker server 发送http请求请求包含上下文信息。 3.docker server开始构建镜像 ①创建一个临时目录将上下文中的内容解压到临时目录下然后读取dockerfile中的指令。 ②将执行分发到不同的模块进行操作为每一条指令构造一个临时容器并执行执行完毕后commit。 ③将所有commit的镜像合并得到最终的镜像。 这里需要注意docker build会将当前文件下的所有文件发送到docker server如果有些文件在docker过程中并不需要可以在当前目录下创建忽略 .dockerignore 文件并写入忽略文件的文件名。
docker避坑笔记
调试背景
我在windows10下安装VMWareWMware中安装了Ubuntu20.04并使用桥接模式连接的windows10主机。说明虚拟机与主机的IP地址互相独立Ubuntu无法通过127.0.0.1访问Windos10同时在Ubuntu20.04基础镜像下打包golang项目的镜像。
问题1docker build运行dockerfile报错E: Unable to locate package xxx
这里报错有很多原因大概可以归为以下几类 1、当前的apt-get不是最新版所以无法找到这个库 解决方案运行apt-get update
apt-get update2、使用上述方法后仍然报错可能就是真的没这个包或者这个包在外网下载国内无法访问或访问速度过慢。这里采用换源的方法看看能不能解决。 解决方案在dockerfile中加入
RUN sed -i s/archive.ubuntu.com/mirrors.aliyun.com/g /etc/apt/sources.list问题2dockerfile安装golang时报错显示Do you want to continue? [Y/n] Abort.
dockerfile运行过程中无法接受用户的输入但是有些软件包的安装过程需要用户进行交互所以会出现问题。 解决方案在dockerfile中加入下面两句话
ENV DEBIAN_FRONTENDnoninteractive #关闭交互功能apt-get install -y xxx #-y表示所有的交互都是选择默认的选项xxx为需要安装的包名问题3dockerfile运行apt-get install golang时报错显示Undefinedany
开发环境为golang1.21.3但是是用apt-get install golang默认下载的版本小于golang1.18,而any关键字是golang1.18以后才引入的关键字所以会没法编译。 解决方案不使用apt-get install golang安装更换下面的方式
#指定版本安装golang
RUN apt-get update apt-get install -y wget \wget https://mirrors.aliyun.com/golang/go1.21.3.linux-amd64.tar.gz \tar -C /usr/local -xzf go1.21.3.linux-amd64.tar.gz \rm go1.21.3.linux-amd64.tar.gz# 设置Go的环境变量
ENV PATH$PATH:/usr/local/go/bin问题4开启容器后使用Ubuntu访问容器端口发现连接被重置等于容器的端口连不上。
这里涉及到了2个知识 第一个知识是容器默认的网络模式是桥接即容器内部具有独立的IP地址通过0.0.0.0IP对外提供服务。所以如果程序内部原来通过127.0.0.1:8888的方式对其他容器或者主机提供服务那么需要改为0.0.0.0:8888。如果主机想要通过127.0.0.1::8888访问容器需要更改docker run语句如下
docker run -d -p 127.0.0.1:8888:8888 image_name这里说明了端口映射将容器的0.0.0.0::8888端口映射到主机的127.0.0.1:8888端口。 第二个知识是防火墙有可能会拦截请求最好把Ubuntu的防火墙关了。
#关闭防火墙服务
sudo systemctl stop ufw.service#检查防护墙服务是否关闭
sudo ufw status我试了前面两个办法都不行只能上大招重启容器的网卡服务。
systemctl stop docker # 停止docker 服务
pkill docker # 杀掉docker进程
iptables -t nat -F # 清理iptables
ip link set docker0 down # 停止docker0网卡
brctl delbr docker0 # 删除docker0网卡--重点
systemctl start docker # 启动docker服务问题5上述方法可以实现容器与主机的通信但是容器之间的通信还需要获取到容器的IP地址才可以实现
但是我在本地编写的代码都是用的127.0.0.1:xxxx的格式进行通讯现在突然要换为容器的IP地址进行通讯又需要更改代码所以我采用了其他方式将容器的网络模式更换为host模型即与主机共享同一个IP空间。
最终的dockerfile
# 使用指定的基础镜像
FROM ubuntu:20.04ENV DEBIAN_FRONTENDnoninteractive# 换为清华源
# RUN sed -i s/archive.ubuntu.com/mirrors.aliyun.com/g /etc/apt/sources.listRUN apt-get update apt-get install -y gcc gitRUN apt-get update apt-get install -y wget \wget https://mirrors.aliyun.com/golang/go1.21.3.linux-amd64.tar.gz \tar -C /usr/local -xzf go1.21.3.linux-amd64.tar.gz \rm go1.21.3.linux-amd64.tar.gz# 设置Go的环境变量
ENV PATH$PATH:/usr/local/go/bin# 创建工作目录并拷贝你的 Go 项目代码到容器中
WORKDIR /Cache
COPY . /Cache# 构建Go项目
RUN go build -o server2# 暴露应用程序所使用的端口
EXPOSE 9528
EXPOSE 8766# 定义容器启动命令这里假设你的Go项目生成了一个名为server1的可执行文件
CMD [./server2]
最终的docker-compose.yml
version: 3services:service1:build: ./server1network_mode: hostservice2:build: ./server2network_mode: hostservice3:build: ./server3network_mode: host