云原生应用程序采用微服务架构来开发,势必产生大量的子系统,发布大量的程序包,部署起来工作量不小。
程序运行是有依赖的,C/C++程序依赖各种动态库,Java程序依赖JDK和各种Jar库,Python程序依赖其解释器,目标操作系统必须满足一定的条件才能正常部署。
大家会说,C/C++程序全部用静态链接方式,Java程序用SpringBoot打包本来就是可执行的,Python程序打包成可执行的,不就能解决上面讲的问题么,但实际打包部署中我们不会这么做,总有不这么做的情形,或者开发人员不关心运维人员的工作,根本就不理解其中的一些工作量。
有没有一种统一的方法,在开发环境就把所有的依赖解决了,目标系统真正地不需要关心这些环境依赖问题?2013年Docker技术横空出世,完美地解决了这一系列问题。
Docker最初是dotCloud公司创始人Solomon Hykes在法国期间发起的一个公司内部项目,它是基于dotCloud公司多年云服务技术的一次革新。Docker项目后来加入了Linux基金会,遵从了Apache 2.0协议,项目代码在GitHub上进行维护。Docker自开源后受到广泛的关注和讨论,以至于dotCloud公司后来都改名为Docker Inc,并专注于Docker相关技术和产品的开发。目前,Docker已经成为全球最大的Docker容器服务提供商。
因此,Docker背后的开发公司就是Docker Inc。它提供了Docker这个开源项目,并持续对其进行维护和更新。Docker Inc致力于推动容器技术的发展,使得开发者可以更加高效、便捷地打包、部署和管理应用程序。
Docker是一个被广泛使用的开源容器引擎,它基于Linux内核的Cgroups、NameSpace,以及UnionFS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。Docker提供了一种特殊进程的方式,可以在宿主机上运行,并且依赖于Linux内核特性:名字空间(namespace)进行资源的隔离和cgroups(限制、记录任务组所使用的物理资源)。
Docker也可以对应用程序进行打包,允许开发者将他们的应用以及依赖包一起打包到一个可移植的容器中,然后发布到任何流行的Linux机器上,实现虚拟化。
Docker的设计目标包括:
Docker的主要组件包括Docker Client(客户端)、Docker Daemon(守护进程)、Images(镜像)、Containers(容器)等。
Docker Daemon是一个运行在宿主机(DOCKER-HOST)的后台进程,可通过Docker客户端与之通信。
Images是Docker的镜像,相当于一个root文件系统,是只读的模板,用来创建Containers。
Containers是Docker的运行实例,它可以被创建、启动、停止、移动或删除等。
总的来说,Docker是一种轻量级的虚拟化技术,它可以让开发者更加高效、便捷地打包、部署和管理应用程序。
作为一个系统架构师,我们最重要的是要搞清楚Docker技术解决了我们什么问题,然后来看看我们系统面对的问题,以及我们最合适的解决方案,Docker技术是否是我们最合适的解决方案,或者其中一部分。
如果我们明确了这个问题,下决心选择了Docker技术,接下来具体安装工作,开发人员和运维人员都可以去做,用不着系统架构师自己亲自动手,下面把几年前运维人员安装的简单方法做一个记录,可能操作系统版本已经旧了,但基本方法是一样的。
我们第一版是在ubuntu 16系统下安装的,第二版是在ubuntu 22系统下安装的,其实按照Docker官网Install Docker Engine on Ubuntu | Docker Docs进行安装即可,根本不用看二手资料。
sudo apt-get update
sudo dpkg --get-selections |grep linux-image
uname -r
sudo apt-get install linux-image-extra-virtualsudo add-apt-repository "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-cache policy docker-ce
sudo apt-get install -y docker-ce
sudo systemctl status docker
Add the user int group docker:
sudo usermod -aG docker ${USER}Print user and group information for the specified USER:
id -nG
假如我们创建一个SpringBoot工程,名称为demo, 编译成可执行jar文件,有基本的配置文件和日志配置文件,现在我们来看怎么做一个Docker镜像。
# Demo for java# 指定一个基础镜像
FROM openjdk:8u131# 指定时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone# 创建目录
RUN mkdir /opt/demo
RUN mkdir /opt/demo/config
RUN mkdir /opt/demo/temp
RUN mkdir /opt/demo/logsVOLUME /opt/demo/logs
# 拷贝可执行jar文件和相关配置文件
COPY ./demo.jar /opt/demo/
COPY ./config/application.properties /opt/demo/config/
COPY ./config/log4j2.xml /opt/demo/config/# 赋予可执行权限
RUN chmod +x /opt/demo/demo.jar# 指定运行命令
CMD /opt/demo/demo.jar
sudo docker build -t domo:v1 .
docker run -d -v /data/log/demo:/opt/demo/logs demo:v1
docker ps
docker ps -a
docker rmi
如果有提示container还在关联引用着,不让删除的话,那先删除容器:
docker rm
Docker技术以其一种轻量级的虚拟化技术完美地解决了云原生应用程序大规模部署时的依赖问题,相对于VMWare等虚拟机技术又非常之轻量小巧,让开发环境、测试环境和线上环境的部署行为一致,解放了生产力,值得我们好好研究和使用。
以上讲得都是Docker作为一个技术工具,在单机上单程序打包运行的方案,Docker技术肯定不是这么简单的应用了事,那么我们怎么管理多个镜像,怎么管理多个容器等,怎么解决我们现实中大规模部署运行应用程序,思考和解决这些问题是我们学习云原生技术的一个思路,我们不能为了技术而技术,一种技术引进必须是要解决企业的一个方面的实际问题的,接下来的文章我会继续探讨这一系列问题。