为什么要使用docker
Docker是一个用于开发,发布和运行应用程序的开放平台。
在进行软件开发的过程中,我们时常会面临一个问题:我们只有一套系统环境的开发机,但是我们开发的软件却需要在不同的系统环境中运行和测试。这就导致我们需要不同的机器来进行测试,以确保软件在各个环境中运行正常。
docker可以让不同的系统环境以独立的进程,运行在同一台机器上,让一台机器就可以完成所有系统环境下的测试和运行。因为docker与虚拟机的原理有着本质的不同,docker无法运行除本机具备的其他指令集架构(x86-64的机器上无法运行arm64的程序),一定程度限制了docker的使用场景,但同时,docker可以以低成本,低资源占用的方式,运行更多的系统环境。正是这些优势,让docker在自动化测试,云原生中占据着稳固的地位。
回到本文,作者之所以想写这篇文章,主要是为了介绍如何在MacOS上搭建开发环境。毕竟MacOS与主流Linux发行版依然有着不少差别,而作为一个软件开发工程师,大部分时间是需要为Ubuntu,Centos这些Linux发行版开发软件,因此很有必要在MacOS上搭建其他系统的开发环境。而Docker无疑是非常合适的选择。闲话少叙,我们直接进入正题。
使用docker运行其他系统环境
镜像
操作系统分为内核和用户空间。对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 root 文件系统。
容器
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。
容器和镜像的相关操作
在实际工作中,我们往往先拉去镜像,然后生成一个容器实例,然后运行容器实例,进行一系列的工作:
# 查询pull相关帮助
docker pull --help
# the basic format is 'docker pull [option] [Docker Registry address[:port]/]repository[:tag]'
# examples
# pull Ubuntu image
# pull the latest Ubuntu. If the Docker Registry address is not provided, the default address is set.
docker pull ubuntu
# pull Ubuntu 18.04. The repository name is ubuntu, and the tag is 18.04, the Docker Registry address and its port are the default.
docker pull ubuntu:18.04
# list all available image
docker image ls
# run help
docker run --help
# Run the image ubuntu:18.04 with option '-i' and 't'.
# '-i' means run the image with interaction.
# '-t' means run the image with terminal.
# After exitting the container, delete the container.
docker run -it --rm ubuntu:18.04 bash
# After exitting the container, leave the container in the system.
docker run -it [imagename] bash
# or run image in the background.
docker run -d [imagename] /bin/sh
当我们运行完一个镜像之后,也就生成了一个相应的容器(container),这个容器就是可以认为是一个保存起来的系统状态,我们对镜像的所有操作产生的影响,都保存在这个容器中。当我们需要继续工作时,我们不能运行镜像(这意味着运行一个全新的系统),而是要启动容器,继续进行工作。
# list all available containers
docker container ls -a
#list all running containers
docker container ls
# start a container
docker container start [CONTAINER ID]
# enter a container with the terminal.
docker exec -it [CONTAINER ID] bash
复用镜像
为什么制作镜像
目前的操作已经基本覆盖了常见的几种docker操作。
然而仅仅在自己的机器上运行容器未免难以应付需要复用镜像的场景。
例如,换电脑时,我们希望能将搭建好的系统环境直接移植到新电脑中;老板会希望新同事直接利用我们当前的容器,免去搭建开发环境的困扰;我们搭建的系统环境有时需要在数以百计的服务器上运行。因此,制作一个镜像,让我们的制作的系统环境可以被更多的人使用,无疑是工作中必备的docker技能之一。
如何导出容器
如果我们只是想把容器移植到新的机器上,大可不必制作镜像,只需要将容器导出为打包文件(例如tar),然后在新的机器上引入就可以了。
# export the container
docker export [container id] > [output file]
# import the container as an image
cat [output file] | docker import - [repository:tag]
# Run the image and generate a new container!
docker run -it [repository:tag] bash
# or run image in the background.
docker run -d [imagename] /bin/sh
制作镜像并使用镜像
除了上述方法,也可以直接利用容器制作镜像:
# build a new image using existing container.
docker commit [container_id] [new_imagename]
docker run -d [new_imagename] /bin/sh
制作好的镜像也可以通过 docker push
命令来将自己的镜像推送到 Docker Hub。
利用vscode连接到docker
vscode链接docker和连接远程机器的原理基本一致,都是通过ssh协议进行连接。
ssh是默认依赖于22号端口TCP协议进行连接。然而我们运行中的开发环境是和本机共用网络端口的,因此如果直接连接到22号端口,只会连接到本机上,而不能连接到docker环境中。
好在 Dokcer 为应用程序所创造独立的网络环境,它能让应用从宿主机操作系统的网络环境中独立出来。我们可以通过端口映射来讲docker环境中的22号端口映射到其他端口。如下面的命令:
docker run -dit -p [port]:22 [image]
接下来就是在docker环境中安装ssh服务,设置密码,并且在vscode中安装相关插件。以Ubuntu为例,在docker环境中执行如下命令:
# install openssh-server
apt-get update
apt-get install openssh-server
# set password
passwd
# command out the line 'PermitRootLogin prohibit-password'
# Add the line 'PermitRootLogin yes'
vim /etc/ssh/sshd_config
# restart the ssh server
service ssh restart
在本机上安装brew install openssh
,在本机vscode上安装Remote-SSH插件,在插件中配置ssh信息(包括ip,用户名,端口等)。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。