跳到主要内容

docker安装和简单使用

参考文档

前言 - Docker — 从入门到实践

00 安装和设置

下载地址:https://www.docker.com/products/docker-desktop

docker -v可以查看安装的版本

设置镜像代理,阿里云和docker-cn等

img

02 docker命令

运行容器

docker run -d -p 80:80 docker/getting-started --name 自定义容器名

-d run the container in detached mode

-p 80:80 map port 80 of the host to port 80 in the container

docker/getting-started the image to user

--name 自定义容器名 不让docker自动生成,指定容器名字

docker run -dp 3000:3000 \
-w /app \
-v "$(pwd):/app" \
node:12-alpine \
sh -c "yarn install && yarn run dev"

-dp 3000:3000 run in detached mode and create a port mapping

-w /app 设置容器的当前目录,后面的sh -c 指定的命令就在容器的/app目录下运行 w就是workdir的意思

-v "$(pwd):/app" 挂载绑定,绑定当前电脑(而不是小型虚拟机)的当前目录到容器的/app目录下,当前目录中的内容(如源代码)有修改的时候,容器中就能看到这个修改了

node:12-alpine 使用的镜像,这是一个基础的node镜像,基于alpine

sh -c "yarn install && yarn run dev" 要在容器中执行的命令。(alpine没有bash,只有sh),yarn安装所有需要的依赖,然后通过yarn run dev来运行程序。

docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started

-v specify a volume mount. use the named volume and mount it to /etc/todos

docker run -d \
--network todo-app --network-alias mysql \
-v todo-mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=todos \
mysql:5.7

该命令,启动了一个mysql5.7镜像的容器,并且容器关联了网络todo-app,映射容器的/var/lib/mysql目录到volume(todo-mysql-data),设定了mysql的root密码,创建了mysql数据库todos

--netword attach the container to the network(todo-app)

-v todo-mysql-data:/var/lib/mysql /var/lib/mysql是mysql存储数据的目录,我们使用一个命名的volume(todo-mysql-data)并且挂载到容器的/var/lib/mysql目录上。

这里todo-mysql-data这个volume并没有通过docker volume create命令来创建,docker自动帮我们创建好了

docker run -it --network todo-app nicolaka/netshoot

Nicolaka/netshoot镜像,包含许多有用的工具来解决和调试网络问题

docker run options

-t --tty allocate a pseudo-tty

-w --workdir working directory inside the container

-p --publish expose a container's port to the host --publish

-m --memory memory limit

-l --label container metadata

-i --interactive keep stdin open even if not attached

-h --hostname container host name

-e --env environment variables

-d --detach detached mode:leave the container running in the background

-c --cpu-shares cpu shares(relative weight)

-a --attach attach to stdin, stdout or stderr

启动nicolaka/netshoot之后,执行命令 dig mysql,可以获取mysql的ip地址,如172.18.0.2

dig mysql这里的mysql,就是前面启动mysql容器的时候,指定的容器网络别名--network-alias mysql

所以,我们的应用想要访问一个链接到一个叫mysql的主机就可以链接数据库了,不能更简单了

查看、停止、重启、删除容器

docker ps

查看所有运行中的容器 -a 加上-a参数,可以列出容器,包括停止的和运行的

docker container inspect <container-id>

查看容器的详细信息

docker container start/stop/restart/rm <container-id>

docker start/stop/restart/rm <container-id>

启动,重启,停止,删除容器

进入容器

启动时,如果加了-d参数,容器启动后会进入后台。

某些时候需要进入容器操作,这可以使用docker attach或者docker exec命令

推荐使用docker exec命令,因为使用attach命令链接到容器之后,如果当前的命令行退出了,会导致容器停止。

下面是docker exec的用法:

docker exec -it <mysql-container-id> mysql -p

使用docker exec [options] container command [arg]

实际上是在指定的container中,执行command [arg]命令

docker exec -it <mysql-container-id> bash可以连接到container的bash命令行,之后在bash里执行mysql -p效果跟docker exec -it <mysql-container-id> mysql -p是一样的

一般,在容器启动后,如果要链接容器做一些操作,可以使用docker exec命令。

ELSE

docker volume create todo-db

Create a named volume todo-db

docker volume inspect todo-db

显示volume在磁盘的实际位置,访问这个目录大多需要root权限

注意:这个目录在桌面版的docker上,一般指的是小型虚拟机里的目录,而不是我们实际的操作系统目录

docker network create todo-app

创建网络,在同一个network里的docker可以通信,不在同一个network则不行

docker logs -f <container-id>

查看容器日志

docker diff <container-id>

查看容器和镜像相比,修改了什么内容

镜像是多层构建的,容器是在镜像之上再增加了一层,但是随着容器销毁,这一新增的层也会消失。

03 docker-compose

docker-compose

把一堆的app,打包到一起,统一启动和分发

Docker compose默认会为我们的app stack创建一个network,所以docker-compose.yml文件中并没有定义network

docker-compose up -d

启动应用栈,并后台运行

compose中的容器命名格式为 projectname-servicename-replicanumber

projectname一般是docker-compose.yml文件所在的文件夹名字,servicename即app,mysql等

docker-compose logs -f [app/mysql]

查看程序栈日志,多个应用日志会交错展示,会标识出具体是哪个app的日志

[app/mysql] 指定了具体的应用名,可以只查看该应用的日志

docker-compose down

the container will stop and the network will be removed.

默认named volumes不会被删除,如果要删,命令后面追加 --volumes 即可

docker-compose run [OPTIONS] SERVICE [COMMAND] [ARGS...]

对服务执行一次性命令,或者仅运行其中一个服务

docker-compose的ports、expose、links、depends_on使用

ports 把docker内部服务的端口,映射给宿主机,这样可以访问宿主机的ip和端口的人,都可以通过映射的宿主机端口访问到服务

ports:
- 8080:80 #把服务的80端口,映射到宿主机的8080端口
- 10.16.1.1:8080:80 #把服务的80端口,映射到宿主机的10.16.1.1的8080端口
- 80 #把服务的80端口,映射到宿主机的一个随机端口

expose 用来把服务端口开放给其他服务,如果服务的镜像本身已经通过expose暴露端口了,这里就可以不用通过expose再暴露一遍了。

expose:
- 80 #服务的端口映射出来给其他服务使用

links 把一个服务的名称,在当前服务里创建一个别名,类似于linux的link方式。一般不建议使用。

links:
- mysql:server_mysql # 源容器的名称或id:alias

depends_on 当前服务的依赖服务,启动当前服务之前,要先启动依赖的服务才行

不同容器间要通信,就会用到docker run --link选项,docker官方已不推荐使用--link来链接两个容器互相通信。

docker-compose.yml中的字符转义

docker-compose.yml文件中,如果有变量${xxx},想要原样输出的话,需要使用$符号转义$${xxx}

04 关于network

无论是通过docker,或者docker-compose启动的容器,如果使用到了network,那么这些容器之间互相联通的时候,是通过他们的专有内部网络来链接的,跟映射到本机的端口不完全一致。

假如有个容器a和容器b,通过一个名为my-net的网络相连,那么容器之间通信,是通过my-net来链接的,而不是通过我们宿主机的ip,同时服务端口,也是容器的端口,而不是映射的宿主机的端口。

如果知道这些容器的ip docker network inspect my-net

05 docker清理命令prune

命令描述
docker volume/container/image/system prune清理未使用的卷/清理所有停止的容器/清理所有未使用的镜像/清理所有未使用的网络、孤立镜像、构建缓存等,此命令比较危险,需要确认执行