Docker 基本概念、常用命令


 

docker简介

docker是⼀个开源的应⽤容器引擎,使用go语言编写,实现了实现虚拟化,让应用的安装、部署变得十分简便。
 

docker的优点

  • 和虚拟机一样实现了虚拟化、环境隔离,但比虚拟机更轻量级
  • 使用镜像,开箱即⽤,可以快速安装、部署应用
  • 移植性强
     

docker的核心技术

  • NameSpace:命名空间,隔离进程、用户、网络、IPC、UTS等基础资源
  • CGroups:控制组,限制硬件资源
  • UnionFS:管理镜像
     

docker十分适合部署微服务项目,常用于部署微服务中的服务,方便扩充服务节点。和直接物理机上部署相比,毕竟有性能损耗,部署mysql、zk、kafka、redis之类的非项目服务应用时,如果集群节点数量稳定,可直接部署在物理机上。

 

基本概念

image 镜像

即容器模板,运行环境+用户程序,类似于安装操作系统时的windows镜像、centos镜像,只是一个模板。
 

container 容器

从镜像运行的实例,比如用tomcat镜像运行tomcat,就得到一个tomcat容器。容器是运行应用程序的容器,tomcat容器是运行tomcat的,mysql容器是运行mysql的。

从一个镜像可以运行多个容器(实例),这些容器(实例)相互隔离、互不影响。
 

registry 仓库

也有注册表的意思。用于存放镜像,分为公有仓库、私有仓库、本地仓库。

 

配置阿里云容器镜像服务

docker官方的镜像仓库docker hub在国外,pull、push都慢,可以使用国内的镜像仓库,比如阿里云的。

登录阿里云 -> 搜索找到 容器镜像服务
 

使用阿里云的镜像加速器

镜像加速器 -> centos -> 把那一串命令复制到centos上执行即可。每个人分配的加速器地址不同,需要自行登录阿里云。
 

使用阿里云的镜像仓库

1、创建命名空间,命名空间用来对应一个公司、组织或个人用户

2、创建镜像仓库,一个镜像仓库对应一个应用、服务,代码源选择本地仓库

 

镜像常用命令

镜像的体积一般比安装包大很多,往往几百兆、几个G,因为镜像不仅包含应用,还包含了所需的环境、依赖。

不指定镜像版本号时,默认为 latest 最新版。

#在公共仓库中搜索镜像,列出的镜像包括应用官方的、组织机构的、个人制作的。OFFICIAL表示是应用官方提供的镜像
docker search tomcat
#只列出应用官方提供的
docker search tomcat --filter is-official=true


#拉取镜像,会先在本地仓库中找,本地仓库没有才从远程仓库拉取到本地仓库中
docker pull tomcat:9
docker pull tomcat


#查看本地仓库中的镜像
docker images

#删除本地仓库中的镜像,rmi即remove image。如果该镜像已经有实例(容器),需要先删除实例
docker rmi tomcat:9
docker rmi tomcat

非官方的镜像名称是:用户名/应用名 的形式。官方的镜像名称不带用户名。

 

容器常用命令

docker run --name=nginx -p=80:80 -d nginx

#-v指定目录映射,挂载容器。宿主机path:容器path v即volume
docker run -d -p 8080:8080 -v /usr/local/tomcat1:/usr/local/tomcat/webapps --name=tomcat3 tomcat:9 

#也可以用-volumes-from指定 和某容器使用相同的挂载点设置
docker run -d -p 8081:8080 -volumes-from tomcat3 --name=tomcat4 tomcat:9

#查看容器日志
docker logs -f id|name

从镜像创建一个容器并运行,该容器中的程序会自动启动。

  • -p:端口映射,-p=宿主机端口:容器端口,通过访问宿主机的ip:port来访问对应容器中的应用。-p=:容器端口,如果缺省宿主机端口,会随机映射到一个未使用的端口上,可以docker ps查看。如果端口映射失败,又没有占用端口,可能是防火墙出于关闭状态,启动防火墙或重启docker后再试。一个-p映射一个端口,也可以使用多个-p。
  • -d:后台运行,不用-d会在控制台打印应用日志,Ctrl+C会终止应用运行
  • –link myredis:连接到另一个容器的网络,myredis不需要使用-p暴露端口,注意是2根短横。–link可以实现同一宿主机上不同容器之间的网络通信,不同宿主机上的不同容器的网络通信可以用overlay网络+etcd分布式存储实现,此处不再介绍。

可以不先pull镜像到本地仓库,执行docker run时如果本地仓库中没有,会自动从远程仓库中拉取。

id、name都可以唯一标识容器,可以通过id或name操作容器。使用id进行操作时可以只写id的前几个字符,只要能区分容器即可。id不好记,常使用name进行操,注意name是2根短横。

一些镜像在docker run创建、运行容器时,需要设置参数,比如msyql就需要设置数据库密码,如果不设置参数,能创建但启动不了。容器的环境都是打包好的,没有问题,如果docker run启动失败,多半是没有设置某些必需的参数。

 

#启动已存在的容器
docker start id|name
docker stop id|name
docker restart id|name

#删除容器,只能删除已停止的容器
docker rm id|name
#强制删除容器,正在运行的容器也能删掉
docker rm -f id|name

#以上命令都可以批量操作多个容器,容器之间空格隔开即可
docker start tomcat1 tomcat2

# -q 获取容器id
docker stop $(docker ps -q)
docker rm -f $(docker ps -aq)


#查看正在运行的容器信息,第一列是id
docker ps
#查看所有容器,a即all,正在运行的+停止的
docker ps -a
#查看指定容器的详细信息
docker inspect id|name


# 重命名容器
docker rename id|name  newName


# 进入容器,该容器处于运行状态才能进入,进入的目录就是工作目录(WORKDIR)
# -it是分配命令行终端进行交互,最后是进入容器后要执行的命令,可以是bash也可以是其它命令,bash也可以写成 /bin/bash
docker exec -it id|name bash

#退出该容器的命令行
exit

 

容器、宿主机之间的文件复制

#从宿主机复制到容器
docker cp srcPath id|name:distPath 

#从容器复制到宿主机
docker cp id|name:srcPath distPath

docker cp这个命令是在宿主机上执行的,不是进入容器执行

 

镜像的分层结构

在这里插入图片描述
镜像中的数据只读,容器中的数据可读可写,容器从镜像中加载基础数据。镜像是一个只读模板,docker run创建容器时从镜像中读取数据到内存,每个容器占据单独的内存空间。

一个镜像具有多层:基础镜像是一层,后续一个命令产生一层。

 

docker的网络模式

docker使用namespace隔离资源,给容器提供了3种网络模式

  • bridge:默认值,桥接,容器有自己单独的ip、port
  • host:直接使用宿主机的网络(ip、port)
  • none:不给容器分配网络资源,容器不能与外界进行网络通信

docker run时可以用–net指定容器使用的网络模式 eg. --net=host,一般使用默认的桥接,使用-p映射端口。

 

目录映射

目录映射也叫作目录挂载、容器数据的持久化。

目录挂载的优点

  • 实现宿主机、容器之间的数据共享,方便操作:不用进入容器就可以操作中的容器的文件、目录,比如映射tomcat的webapps目录,在宿主机上直接部署;比如映射多个容器中的应用日志存储目录,在宿主机上直接查看日志。
  • 数据安全:宿主机、容器的文件系统是单独的、隔离的,删除容器或容器发生故障,会丢失容器中的文件、数据,通常要把容器中重要的数据目录映射到宿主机上,以保证数据安全。

查看docker inspect查看时,Mounts可查看设置的挂载点,可以有多个挂载点,source是宿主机上的路径,dest是容器的路径。

 

制作镜像

基础镜像往往不能满足需求,经常要自行制作镜像。制作镜像的2种方式

  • Docker Commit
  • Dockerfile 主流
     
docker commit方式

先docker run创建运行一个容器,进入容器做一些修改,然后将容器制作为镜像,容器中的数据、配置会被打包到镜像中。

#-a指定作者,-m指定描述信息,均可选
#将容器打包为镜像,放到本地仓库中,docker commit时不必停掉容器
docker commit -a "xxx" -m "xxx" 容器id|name 镜像名:版本号

 

Dockerfile方式

vim Dockerfile 文件名是约定俗成的,不一定非要用这个

#指定基础镜像。基础镜像不需在存在本地仓库中
FROM tomcat:9
#镜像的所有者信息,非必需
MAINTAINER chy xxx@qq.com
RUN echo "正在构建镜像..."
#本地路径、容器路径,本地路径只能用相对路径,相对当前Dockerfile文件
COPY xxx.war /usr/local/tomcat/webapps
命令说明
FROM指定基础镜像,如果不使用基础镜像,写成FROM scratch
RUN执行命令,并创建新的镜像层。可以把多个命令写在一个RUN中:
# &&分隔,\换行。这样的好处是把多个命令划到一个镜像层中,一个RUN执行了多个命令,只生成一个镜像层
RUN 命令1 && 命令2 && 命令3 \
命令4

CMD|指定容器启动后要执行的命令、参数,有多个CMD时只执行最后一个。
ENTRYPOINT|指定容器启动时要执行的命令,ENTRYPOINT是容器入口,先执行ENTRYPOINT指定的命令,再执行CMD指定的命令。如果使用exec命令格式,CMD可以作为ENTRYPOINT命令的参数,可以被容器启动时设置的参数覆盖,也可以直接CMD [ ]写成空数组,接收docker run创建容器时末尾传入的参数。
COPY|复制宿主机上文件、目录到镜像中
ADD|同COPY,但有一些额外的功能,比如自动解压压缩包
EXPOSE|暴露端口给宿主机
MAINTAINER|维护者信息
WORKDIR|指定工作目录,docker exec进入容器时,会自动进入workdir指定的目录,相当于cd切换路径。构建镜像时,如果指定的路径不存在,会自动创建。eg. WORKDIR /usr/local/tomcat 尽量使用绝对路径。
ENV|设置环境变量,eg. ENV 名称 值,所谓环境变量只是一个公开的键值对,和常量差不多,可以当做常量来定义、使用。
USER|指定用户
VOLUME|设置挂载点。VOLUME ["/user/local/tomcat1"] 将容器的整个目录挂载到宿主机的该目录下

run、cmd、ENTRYPOINT的命令格式

  • shell格式:RUN yum install tomcat -y
  • exec格式:RUN [“yum”,“install”,“tomcat”,"-y"]命令写成字符串数组形式

使用exec命令格式时,cmd、ENTRYPOINT经常搭配使用,ENTRYPOINT写命令,cmd写默认参数,eg. ENTRYPOINT [“ps”],cmd写["-ef"],docker run … aux

aux会覆盖cmd设置的默认参数-ps

 

RUN yum install nginx -y

ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"

CMD echo "hello world"

EXPOSE 8080

 

mysql
按照官方镜像的说明文档做,注意:官方文档中没有提到要用-p映射端口,但实际使用时需要使用-p显示映射3306端口,不然默认只映射33060端口。
 

rabbitmq

docker run -d --hostname 0.0.0.0 --name rabbitmq -p 15672:15672 rabbitmq:3-management

 

#构建镜像,指定的是dockerfile的文件路径。-t指定镜像名称、版本,版本可以用latest,t即tag,不写版本默认是最新版?
#是存放到本地仓库中。如果文件名是Dockerfile,可以只写目录,缺省文件名 .
#-t后面的tag常写为 组织/镜像名称
docker build ./Dockerfile -t mall:1.0

用户名/应用名:版本号 唯一标识一个镜像
镜像名称要是 用户名/应用名 的形式,用户名要与远程仓库的用户名一致,不然push时没有权限?

 

推送镜像到远程仓库

#将指定镜像另存为新的镜像
docker tag nginx:9 mynginx:1
docker tag nginx mynginx

#镜像也可以是自己docker commit、docker build构建的


#登录远程docker仓库,根据提示输入输入用户名、密码,远程仓库可以是docker hub、阿里云的镜像仓库等
docker login

#上传镜像到远程docker仓库中
docker push mynginx:1
docker push mynginx

 

docker部署springboot项目

官方文档:https://spring.io/guides/gs/spring-boot-docker/

pom.xml

//<properties>
<docker.image.prefix>xdclass</docker.image.prefix>
​
​
<build>
    <finalName>alibaba-cloud-gateway</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId><configuration>
                <fork>true</fork>
                <addResources>true</addResources>
            </configuration>
        </plugin><plugin>
            <groupId>com.spotify</groupId>
            <artifactId>dockerfile-maven-plugin</artifactId>
            <version>1.4.10</version>
            <configuration>
                <repository>${docker.image.prefix}/${project.artifactId}</repository>
                <buildArgs>
                    <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
                </buildArgs>
            </configuration>
        </plugin>
    </plugins>
</build>

Spotify 的 docker-maven-plugin 插件是用maven插件方式构建docker镜像的。${project.build.finalName} 产出物名称,缺省为${project.artifactId}-${project.version}
 

如果打包失败,修改如下

 <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <fork>true</fork>
        <addResources>true</addResources>
    </configuration>
</plugin>

 

3、在服务根目录下新建文件Dockerfile

FROM  adoptopenjdk/openjdk11:ubi
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
  • VOLUME 配置一个具有持久化功能的目录,主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp。改步骤是可选的,如果涉及到文件系统的应用就很有必要了。/tmp目录用来持久化到 Docker 数据文件夹,因为 Spring Boot 使用的内嵌 Tomcat 容器默认使用/tmp作为工作目录。​
  • ARG 设置编译镜像时加入的参数, JAR_FILE 是设置容器的环境变量(maven里面配置的)
  • COPY : 只支持将本地文件复制到容器 ,还有个ADD更强大但复杂点
  • ENTRYPOINT 容器启动时执行的命令
  • EXPOSE 8080 暴露服务使用的端口
     

IDEA终端cd到服务根目录下,执行

#默认Dockerfile文件在当前目录下,如果不是在当前目录下,需要显式指定Dockerfile文件的路径
mvn install -Dmaven.test.skip=true dockerfile:build

 
拷贝配置到各个服务中,分别打包。
 

4、推送镜像到私有仓库
参考阿里云的文档:

  • 命名空间:xxx-cloud 建议为项目名
  • 仓库:cloud-getway 建议一个服务一个仓库
  • 代码源:本地仓库
//登录。登出是docker logout
docker login --username=釉釉cxy registry.cn-shenzhen.aliyuncs.com
//打标签
docker tag 494d49ea5e78 registry.cn-shenzhen.aliyuncs.com/xdclass-cloud/cloud-gateway:v1.0
//推送
docker push registry.cn-shenzhen.aliyuncs.com/xdclass-cloud/cloud-gateway:v1.0

同名是否会覆盖?

 

5、从私人仓库拉取并运行
docker pull 仓库名/镜像名:版本号
docker run…docker run --name sentinel -d -p 8858:8858 镜像
docker logs -f id|name #查看日志

 

harbor镜像仓库的搭建

阿里云的镜像仓库适合个人、小公司使用,也有企业版适合大公司使用,但收费较高。大公司一般使用harbor搭建自己的镜像仓库。

安装之前确保前置条件是否满足,需要安装docker、docker-compose、openssl、python2.7.x或python3.x

docker -v
docker-compose -v
python -V

yum install openssl -y

 

离线安装包下载地址:https://github.com/goharbor/harbor/releases
下载tgz

tar -xf xxx.tgz


#修改配置
vim harbor.yml
#主机名改为实际ip,0.0.0.0可以?
hostname: 192.168.0.151
#密码
harbor_admin_password: Harbor12345


#执行脚本,会生成一个docker-compose.yml文件
sh prepare
#0表示执行成功。
echo $?


#安装。harbor实际是一个docker-compose的应用,安装实质是执行刚才生成的yml文件运行容器
sh install.sh

#完成后查看运行的容器
docker-compose ps

harbor中的nginx容器默认使用8080端口、映射到宿主机的80端口上,访问宿主机ip即可进入harbor界面,默认用户名admin。

#关闭、启动和docker compose相同。如果不是在harbor目录下执行,还需要指定harbor的docker-compose.yml文件路径
docker-compose down
docker-compose up -d

 

harbor镜像仓库的使用

docker默认只允许使用https访问仓库,如果要使用http访问仓库,进行如下配置

vim /etc/docker/daemon.json

{
"insecure-registries":["http://192.168.0.151"]
}

在这里插入图片描述
第一个是阿里云的加速器,可以从阿里云复制。

如果2太机器都在内网中,可以使用内网ip进行通信,否则使用外网ip。

重启docker服务生效,重启后harbor是停止状态需要启动。

 

在harbor仓库中新建项目名。

登录:docker login --username=admin 192.168.0.151

改名:docker tag mysql:5.7 192.168.0.151/xdclass/mysql:5.7
推送:docker push 192.168.0.151/xdclass/mysql:5.7

下载:docker pull 192.168.0.151/xdclass/mysql:5.7

退出:docker logout

docker login 后有一个登录凭证存储在 /root/.docker/config.json ,可删除,下次需要密码,建议从安全角度出发,每次登录后删除该文件。

 

本地镜像容器的载入、载出
如果没有或不能使用远程镜像仓库,可以使用本地镜像、容器的载入、载出实现2台机器上的镜像、容器传输。

#载出镜像。镜像name:tag 也可以换成镜像id,-o指定输出路径,也可以写成 >
docker save mysql:5.7 -o /home/mysql.tar

把文件传输到另一个节点

#载入镜像,-i也可以写成 <
docker load -i mysql.tar


#载出容器,容器id也可以换成name,-o可以写成 >
docker export 974b919e1fdd -o /home/mysql-export.tar

#传输到其它节点

#载入容器
docker import mysql-export.tar
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值