Linux/Ubuntu入门之安装、使用Docker
Linux/Ubuntu入门之安装、使用Docker
docker的镜像总是几百M,大啊。。
前提条件
- 如果有旧版本,卸载旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc
- Ubuntu版本大于16.04,LTS版本
核心概念
- 镜像(images):docker镜像是用于创建docker容器的模板---一个特殊的文件系统
- 容器(container):容器是独立运行的一个或一组应用---镜像运行时的实体
- 客户端(client):客户端通过命令行或者其他工具使用dockerAPI与docker的守护进行通信
- 宿主机(host):一个物理或虚拟机用于执行docker守护进程和容器
- 仓库(Registry):docker仓库用来保存镜像---集中存放镜像文件的地方
安装步骤
基于apt-get
,deb格式的文件 就更简单,sudo dpkg -i /path/package.deb
-
其他安装需要的包来允许apt通过HTTPS使用存储库 (新Ubuntu基本都有了,可略过)
sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ gnupg \ lsb-release
-
添加/信任Docker的官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
-
设置存储库地址(稳定版 stable)
echo \ "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
-
完成上面几步才能使用apt包管理工具来安装Docker Engine (社区版)
sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io
-
运行
hello world
镜像检验是否安装成功且能正常运行sudo docker run hello-world
首次运行,没有这个镜像会从本地库中拉去然后输出
Hello from Docker! .......
-
若要卸载Docker,删除软件包的同时还需要删除镜像容器和卷(就docker的相关文件)
sudo apt-get purge docker-ce docker-ce-cli containerd.io sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd
是否使用root用户运行Docker?
docker官方是不建议用root,docker运维人员用root可能存在风险,做好权限隔离还是非常有必要。
那人如何使用非root账户管理呢?由于docker安装后会自动创建docker用户组,所以可以在docker用户组创建管理docker的用户或者把用户加入docker用户组,最后重启下
sudo useradd -g docker -d /home/appdocker appdocker
id appdocker # 查看该用户信息
# 用户id=1001(appdocker) 组id=998(docker) 组=998(docker)
sudo usermod -aG docker $USER # 将用户加入docker组
没有权限的用户运行docker version docker ps
会报错 权限拒绝,无法访问/var/run/docker.sock 这个文件
其他安装docker后续配置步骤参考官方文档:https://docs.docker.com/engine/install/linux-postinstall/
下文还是以root用户来操作...
修改仓库地址为国内镜像网站!
像npm需要设置仓库地址为淘宝的镜像网站一样,国内docker也需要将仓库改成默认的镜像网站
阿里云获取镜像地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
修改配置文件/etc/docker/daemon.json,没有就自己创建,修改后重启docker服务systemctl restart docker
{
"registry-mirrors": ["https://xxxxxx"]
}
// 以下是直接可用的镜像地址
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn","http://hub-mirror.c.163.com","https://registry.docker-cn.com"]
}
Docker概念之Image、Dockerfile、Volume
镜像文件(Image)用于生成容器,即容器模板,Image存在继承关系,在每次继承可以添加个性化设置如添加软件。
- Image是通用的。
- Image存在应用程序及其依赖。
- 常用Dockerfile来配置生成目标Image
构建脚本(Dockerfile)是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
FROM node:8.4
:该 image 文件继承官方的 node image,冒号表示标签,这里标签是8.4
,即8.4版本的 node。
COPY . /app
:将当前目录下的所有文件(除了.dockerignore
排除的路径),都拷贝进入 image 文件的/app
目录。
WORKDIR /app
:指定接下来的工作路径为/app
。
RUN npm install
:在/app
目录下,运行npm install
命令安装依赖。注意,安装后所有的依赖,都将打包进入 image 文件。格式:RUN <命令行命令> | RUN ["可执行文件", "参数1", "参数2"]
EXPOSE 3000
:将容器 3000 端口暴露出来, 允许外部连接这个端口。以上来自阮一峰的文章 和 https://www.runoob.com/docker/docker-dockerfile.html
数据卷(Volume)主要是用于数据持久化(也解决不同容器间数据共享问题),直接将数据写到宿主机上(我理解类似于目录映射),Volume由docker管理,位于/var/lib/docker/volumes
目录,使用docker volume help
命令获取有关Volume的帮助。具体使用如下:
root@ubuntu:/# docker volume create todo-db
todo-db
root@ubuntu:/# docker volume inspect todo-db
[
{
"CreatedAt": "2021-05-04T21:52:35+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/todo-db/_data",
"Name": "todo-db",
"Options": {},
"Scope": "local"
}
]
以 docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started
为例,todo-db
是一个卷的名字,-v todo-db:/etc/todos
中-v表示指定将卷(todo-db)mount到容器中的/etc/todos
目录。如果指定卷不存在,docker会自动帮忙创建卷。
另一种方式数据持久化实现Use bind mounts: https://docs.docker.com/get-started/06_bind_mounts/
Docker概念之Netword
作用:让一台机子上独立的容器应用之间进行通信对话。
创建:
-
创建网络:
docker network create app-net
-
为启动容器的命令添加额外参数来加入一个网络:
--network app-net
-
为特定容器在Netword中的ip添加别名--network-alias mysql` (mysql将被解析为ip,类似于域名)
? 例:jdbc的url可以写成
url: jdbc:mysql://mysql:3306/db?
Dockerfile概念之CMD、RUN、ENV
RUN是在image文件的构建阶段执行,执行结果会被一起打包进去。每条RUN指令会在docker上新建一层,最好使用&& 连接命令
CMD是容器启动后要执行的命令,只能有一个CMD命令,docker container run后面的命令等同于CMD
ENV是设置容器的环境变量使用ENV key value
或ENV key1=value1 key2=value2
两种格式
使用指南(Java&SpringBoot篇)
-
在某个工作目录下下载spring官方demo
git clone https://github.com/spring-projects/spring-petclinic.git
-
进入
spring-petclinic
目录 输入./mvnw spring-boot:run
下载依赖项、构建项目并运行 -
然后访问 http://localhost:8080 确保可以正常运行
-
在这个目录下创建 Dockerfile文件
-
第一行是解析器指令(只能放第一行),用于告诉Docker builder 用什么语法来解析这个Dockerfile
# syntax=docker/dockerfile:1 FROM openjdk:16-alpine3.13 # 创建工作目录,让后续命令更好写 WORKDIR /app COPY .mvn/ .mvn COPY mvnw pom.xml ./ # 根据pom文件来安装maven依赖项 RUN ./mvnw dependency:go-offline COPY src ./src # 源码也准备好之后,启动项目 CMD ["./mvnw", "spring-boot:run"]
-
创建.dockerignore文件用于排除不想被打包进镜像的文件和目录,java项目可以排除target文件夹
-
构建镜像
docker build --tag java-docker .
不显示的指定tag则为默认的latest
-
终端使用
docker images
命令查看构建的镜像 -
--------------------朴实无华的分割线--------------------
-
用镜像启动容器使用命令
docker run --publish 8080:8080 java-docker
--publish简写是-p ,将容器的8080端口暴露到宿主机的8080端口 -
可在启动时添加 --detach或者-d 分离容器,使其后台自己运行
-
可在启动时添加 --rm参数,使在容器退出时自动清理容器并删除文件系统
spring官网指南 https://spring.io/guides/gs/spring-boot-docker/
手动部署方式:jar包配合dockerfile,基于基础镜像搞个新镜像(jar先上传到有docker的环境中,用于生成镜像)
Maven插件方式:使用插件 docker-maven-plugin
使用指南(Mysql篇)
-
为mysql的数据创建一个卷
docker volume create mysql
-
为mysql的配置创建一个卷
docker volume create mysql_config
-
为应用程序和数据库直接创建网桥网络
docker network create mysqlnet
-
运行一个MySQL容器,并附加到刚刚创建的卷和网络上(版本8.0.23,从docker hub下载)
docker run -it --rm -d -v mysql_data:/var/lib/mysql \ -v mysql_config:/etc/mysql/conf.d \ --network mysqlnet \ --name mysqlserver \ -e MYSQL_USER=petclinic -e MYSQL_PASSWORD=petclinic \ -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=petclinic \ -p 3306:3306 mysql:8.0.23
-
对于刚刚的SpringBoot篇,可以修改它的dockerfile来指定项目的profile切换到有关mysql的配置
CMD ["./mvnw", "spring-boot:run", "-Dspring-boot.run.profiles=mysql"]
-
然后再重新构建镜像
docker build --tag java-docker .
-
同时多了mysql要连接,SpringBoot项目容器的也要有所修改
docker run --rm -d \ --name springboot-server \ --network mysqlnet \ -e MYSQL_URL=jdbc:mysql://mysqlserver/petclinic \ -p 8080:8080 java-docker
-
不用分别启动两个容器,还能再偷懒!使用Compose进行本地开发!
-
在刚刚的springboot项目(petclinic)根目录下,创建
docker-compose.dev.yml
文件version: '3.8' services: petclinic: build: context: . ports: - 8000:8000 - 8080:8080 environment: - SERVER_PORT=8080 - MYSQL_URL=jdbc:mysql://mysqlserver/petclinic volumes: - ./:/app command: ./mvnw spring-boot:run -Dspring-boot.run.profiles=mysql -Dspring-boot.run.jvmArguments="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000" mysqlserver: image: mysql:8.0.23 ports: - 3306:3306 environment: - MYSQL_ROOT_PASSWORD= - MYSQL_ALLOW_EMPTY_PASSWORD=true - MYSQL_USER=petclinic - MYSQL_PASSWORD=petclinic - MYSQL_DATABASE=petclinic volumes: - mysql_data:/var/lib/mysql - mysql_config:/etc/mysql/conf.d volumes: mysql_data: mysql_config:
-
相当于docker run的命令写到这个文件中了,同时mysqlserver也可以当作域名使用
-
执行compose.yml文件
docker-compose -f docker-compose.dev.yml up --build
-
*连接调试器 https://docs.docker.com/language/java/develop/#connect-a-debugger
-
TODO 看到这了 https://docs.docker.com/language/java/run-tests/
参考链接
- Docker 入门教程(阮一峰) https://www.ruanyifeng.com/blog/2018/02/docker-tutorial.html
- 官方使用案例教学 https://docs.docker.com/get-started/overview/
- 官方[run]参考 https://docs.docker.com/engine/reference/run/