Docker学习笔记
文件修订历史
目录
1. 认识Docker 5
1.1 什么是Docker 5
1.2 Docker能做什么 5
1.3 与虚拟的区别 5
2. 搭建Docker 6
2.1 环境准备 6
2.2 安装 6
2.3 启动 6
2.4 查看状态 7
2.5 停止 8
2.6 安装一个官方镜像 8
2.7 切换镜像仓库地址 8
3. 使用Docker 9
3.1 Hello world 9
3.2 可视化管理Docker UI 11
3.3 安装本地私服仓库 13
4. 使用Dockerfile 14
4.1 制作一个Dockerfile 16
4.2 启动容器 17
5. Maven与Docker集成 17
5.1 插件docker-maven-plugin 18
5.2 插件dockerfile-maven 19
6. 容器编排与调度 20
6.1 容器编排 20
6.2 容器调度 21
7. Docker常用命令 21
8. 常见问题 22
8.1 连不上docker官方仓库 22
8.2 启动mysql容器后,使用客户端连不上,报ERROR 2059 (HY000) 23
9. 参考资料及下载 24
本文档对Docker学习进行的记录笔记。
1.认识Docker
Docker是PasS提供商DoctCloud开源的一个基于LXC的高级容器引擎,源代码托管在Github上,基于go语言并遵从Apache2.0协议开源。
1.1 什么是Docker
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
1.2 Docker能做什么
Docker简化了开发流程中最复杂的事情:构建环境。
Docker的镜像称为image,容器称为container。
镜像:一个静态文件系统,可类比iso镜像文件
容器:一个可运行的动态文件系统,是镜像的实例。
1.3 与虚拟的区别
Docker是一个轻量级容器技术,类似于虚拟机技术(xen、kvm、vmware、virtual)。Docker是直接运行在当前操作系统(Linux)之上,而不是运行在虚拟机中,但是也实现了虚拟机技术的资源隔离,性能远远高于虚拟机技术。
Docker支持将软件编译成一个镜像(image),Docker支持将软件编译成一个镜像(image),在这个镜像里做好对软件的各种配置,然后发布这个镜像,使用者可以运行这个镜像,运行中的镜像称之为容器(container),容器的启动是非常快的这个有点像我们平时安装ghost操作系统,系统安装好后软件都有了,虽然完全不是一种东西,但是思路是类似的。
vs
2.搭建Docker
以下介绍如何搭建Docker。
2.1 环境准备
操作系统:
Linux(RHEL、Centos、Ubuntu) / Windows(windows7.1、windows 8)+VM+处理器需要支持硬件虚拟化
本教程演示使用的Linux发行版本:
CentOS Linux release 7.2.1511 (Core)
2.2 安装
Centos可以选择从yum仓库安装docker。
安装命令:
yum install docker |
2.3 启动
docker启动命令如下:
[root@VM_88_213_centos ~]# service docker start Redirecting to /bin/systemctl start docker.service
|
设置为开机启动命令:
systemctl start docker systemctl enable docker |
2.4 查看状态
待补充。
查看启停状态,命令如下:
[root@VM_88_213_centos ~]# service docker status Redirecting to /bin/systemctl status docker.service ● docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled) Active: active (running) since Fri 2018-06-01 10:58:05 CST; 15s ago Docs: http://docs.docker.com Main PID: 16145 (dockerd-current) CGroup: /system.slice/docker.service ├─16145 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/libexec/docker/docker-proxy-current --init-path=/usr/libexec/... └─16151 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc --run... ...... |
Main PID: 16145即为docker进程ID
2.5 停止
[root@VM_88_213_centos ~]# service docker stop Redirecting to /bin/systemctl stop docker.service
|
2.6 安装一个官方镜像
查找可用的镜像:
docker search tutorial |
拉取:
docker pull learn/tutorial |
注:在docker的镜像索引网站上面,镜像都是按照“用户名/镜像名”的方式来存储的。有一组比较特殊的镜像,比如ubuntu这类基础镜像,经过官方的验证,值得信任,可以直接用 镜像名来检索到。
2.7 切换镜像仓库地址
将镜像仓库地址切到国内,速度会有些提升。
如下:
修改/etc/docker/daemon.json
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}
其他镜像Docker 官方中国区
https://registry.docker-cn.com
网易
ustc
https://docker.mirrors.ustc.edu.cn
3.使用Docker
使用Docker的好处:
简化配置
代码流水线(Code Pipeline)管理
提高开发运维效率
整合服务器
资源隔离低消耗
快速部署
3.1 Hello world
使用Docker启动一个redis
docker pull docker.io/redis:latest
docker run -p 6699:6379 --name myredis -v $PWD/redis.conf:/etc/redis/redis.conf -v $PWD/data:/data -d redis:latest redis-server /etc/redis/redis.conf --appendonly yes
即可以启动一个redis容器
3.2 可视化管理Docker UI
以portainer、rancher为例
拉ui镜像:
docker pull portainer/portainer
docker run -d \
-p 9000:9000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer
docker run -it --name docker-portainer -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
检查端口是否启起来了,
然后宿主机,输入:
创建用户密码,密码至少为8位,比如:12345678
进入页面后,选择local environment。
3.3 安装本地私服仓库
首先安装好docker后,先拉取(PULL)Docker私有仓库Regostry镜像
Shell命令:docker pull registry:latest
运行镜像registry
Shell命令:
docker run -d -p 5000:5000 --name registry --restart=always --privileged=true -v /data:/var/lib/registry registry:latest
命令解释:
-p后面为docker宿主机端口:对应镜像内部运行端口
--name 为 运行镜像的进程名称
–restart是否开机启动
--privileged=true这一行很重要,不加能运行成功,但是docker push镜像的时候会报创建路径权限不足
-v /data:/var/lib/registry 对应docker宿主机的本地路径/data,和镜像内部路径/var/lib/registry
registry:latest 镜像名称及对应的的标签,至此我们就建立好docker私有仓库了,
验证地址为:
显示
{"repositories":["你push到私服的镜像"]}
http://私服IP:2375/info
显示版本的json串信息
{"Version":"1.13.1","ApiVersion":"1.26","MinAPIVersion":"1.12",
"GitCommit":"94f4240/1.13.1","GoVersion":"go1.9.4","Os":"linux",
"Arch":"amd64","KernelVersion":"3.10.0-862.el7.x86_64",
"BuildTime":"2018-05-18T15:44:33.522929015+00:00","PkgVersion":"docker-1.13.1-63.git94f4240.el7.centos.x86_64"}
如果无法访问2375端口,则
a. 首先VI打开文件vi /etc/sysconfig/docker
添加参数 DOCKER_OPTS="-H unix:///var/run/docker.sock -H 0.0.0.0:2375"
b. 然后vim /usr/lib/systemd/system/docker.service 打开
ExecStart=中追加参数 $DOCKER_OPTS (上面参数中的KEY)
c. 服务器防火墙开2375访问权限
d. 开启2375端口:firewall-cmd --zone=public --add-port=2375/tcp --permanent
重启防火墙:firewall-cmd --reload
如果提示(FirewallD is not running),则先开启:
systemctl start firewalld.service
e. 服务器PUSH的时候报错处理
a. 报Get https://10.100.14.17/v1/_ping: dial tcp 10.100.14.17:443: getsockopt: connection refused
请用vi /etc/docker/daemon.json 加入IP到
{
"insecure-registries":["172.22.94.111:5000","10.100.14.17"]
}
b. 报docker unauthorized: authentication required
因为docker仓库设置了登录验证权限,先docker login 10.100.14.17:5000 输入用户名密码(docker/tcuser)
4.使用Dockerfile
Docker通过对于在Dockerfile中的一系列指令的顺序解析实现自动的image的构建:
通过使用build命令,根据Dockerfiel的描述来构建镜像
通过源代码路径的方式
通过标准输入流的方式
Dockerfile:
Dockerfile由一行行命令语句组成,并且支持用“#”开头作为注释,一般的,Dockerfile分为四部分:基础镜像信息,维护者信息,镜像操作指令和容器启动时执行的指令。
Dockerfile指令:
1、FROM
格式:FROM <image>或 FROM <image>:<tag>
第一条指令必须为FROM指令,并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令(每个镜像一次)
2、MAINTAINET
格式:MAINTAINET <name>
指定维护者的信息
3、RUN
格式:RUN <command> 或 RUN ["", "", ""]
每条指令将在当前镜像基础上执行,并提交为新的镜像。(可以用“\”换行)
4、CMD
格式:CMD ["","",""]
指定启动容器时执行的命令,每个Dockerfile只能有一条CMD指令,如果指定了多条指令,则最后一条执行。(会被启动时指定的命令覆盖)
5、EXPOSE
格式:EXPOSE <port> [ <port> ...]
告诉Docker服务端暴露端口,在容器启动时需要通过 -p 做端口映射
6、ENV
格式:ENV <key> <value>
指定环境变量,会被RUN指令使用,并在容器运行时保存
7、ADD
格式:ADD <src> <dest>
复制指定的<src>到容器的<dest>中,<src>可以是Dockerfile所在的目录的一个相对路径;可以是URL,也可以是tar.gz(自动解压)
8、COPY
格式:COPY <src> <dest>
复制本地主机的 <src> ( 为 Dockerfile 所在目录的相对路径)到容器中的 <dest> (当使用本地目录为源目录时,推荐使用 COPY)
9、ENTRYPOINT
格式:ENTRYPOINT ["","",""]
配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。(每个 Dockerfile 中只能有一个 ENTRYPOINT ,当指定多个时,只有最后一个起效)
10、VOLUME
格式:VOLUME ["/mnt"]
创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等
11、USER
格式:USER daemon
指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。
12、WORKDIR
格式:WORKDIR /path/to/workdir
为后续的 RUN 、 CMD 、 ENTRYPOINT 指令配置工作目录。(可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径, 则会基于之前命令指定的路径)
13、ONBUILD
格式:ONBUILD [INSTRUCTION]
配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令
4.1 制作一个Dockerfile
先建一个目录,用于存放制作镜像的文件。
创建一个文件,名为:Dockerfile
FROM centos
MAINTAINER qujiayuan qujiayuan@tuandai.com
COPY jdk1.8.0_171 jdk1.8.0_171 ADD spring-boot-docker-demo-1.0.0.jar app.jar
ENV JAVA_HOME=/jdk1.8.0_171 ENV PATH=$JAVA_HOME/bin:$PATH ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
EXPOSE 8081
ENTRYPOINT ["java","-jar","/app.jar"] |
切换到Dockerfile所在目录,执行镜像构建命令:
docker build -t qujiayuan/spring-boot-docker-demo-docker . |
注意:最后的一个点,表示当级目录,不能去掉了。
运行:
docker run -it -p 8081:8081 --name spring-boot-docker-hello qujiayuan/spring-boot-docker-demo-docker
docker run -it -p 8081:8081 --name spring-boot-docker-hello qujiayuan/spring-boot-docker-demo-docker
然后在命令行键入 Ctrl + p , Ctrl + q,使容器在后台运行
4.2 启动容器
默认用户名密码:docker/tcuser
首次:
docker run -it -p 8081:8081 --name spring-boot-docker-hello qujiayuan/spring-boot-docker-demo-docker
备注:run=create+start
之后:
docker start spring-boot-docker-hello
5.Maven与Docker集成
使用docker-maven-plugin或dockerfile-maven可与maven集成。
docker-maven-plugin是dockerfile-maven的前身,由同一开源作者出品。
docker-maven-plugin是在pom.xml里集成插件,且集成制作Docker镜像的参和命令。
dockerfile-maven则是通过插件,直接调用Dockerfile来制作Docker镜像
以下以私服172.22.144.238为例
5.1 插件docker-maven-plugin
地址:
https://github.com/spotify/docker-maven-plugin
Pom文件里加上插件:
<docker.image.prefix>172.22.144.238:5000</docker.image.prefix> <docker.tag>test</docker.tag> ......
<plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.4.13</version> <executions> <execution> <phase>install</phase> <goals> <goal>build</goal> <goal>tag</goal> </goals> </execution> </executions> <configuration> <!-- 修改这里的docker节点ip,需要打开docker节点的远程管理端口2375, 具体如何配置可以参照之前的docker安装和配置的文章 --> <dockerHost>http://172.22.144.238:2375</dockerHost> <imageName>${docker.image.prefix}/${project.build.finalName}</imageName> <baseImage>java:8</baseImage> <!-- 这里的entryPoint定义了容器启动时的运行命令,容器启动时运行 java -jar 包名 , -Djava.security.egd这个配置解决tomcat8启动时, 因为需要收集环境噪声来生成安全随机数导致启动过慢的问题--> <entryPoint> ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/${project.build.finalName}.jar"] </entryPoint> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> <image>${docker.image.prefix}/${project.build.finalName}</image> <newName>${docker.image.prefix}/${project.build.finalName}:${docker.tag}</newName> <forceTags>true</forceTags> <!-- 如果需要在生成镜像时推送到远程库,pushImage设为true --> <pushImage>false</pushImage> </configuration> </plugin>
|
Mvn install时,系统会自动将会进行打包,并制作镜像
5.2 插件dockerfile-maven
开源地址:
https://github.com/spotify/dockerfile-maven
DOS设置PATH:
set DOCKER_HOST=http://172.22.144.238:2375
<plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> <version>1.4.0</version> <executions> <execution> <id>default</id> <goals> <goal>build</goal> <goal>tag</goal> </goals> </execution> </executions> <configuration> <repository>172.22.144.238:5000/${project.artifactId}</repository> <tag>${project.version}</tag> <buildArgs> <JAR_FILE>${project.build.finalName}.jar</JAR_FILE> </buildArgs> <useMavenSettingsForAuth>false</useMavenSettingsForAuth> </configuration> </plugin> |
插件:
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.10</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
<goal>tag</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>${project.artifactId}</repository>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
<useMavenSettingsForAuth>false</useMavenSettingsForAuth>
</configuration>
</plugin>
Dockerfile
FROM java:8
MAINTAINER qujiayuan <qujiayuan@tuandai.com>
WORKDIR /app
#RUN apt-get update
COPY target/${JAR_FILE} /app/app.jar
EXPOSE 8082
EXPOSE 8083
CMD [ "java", "-jar", "app.jar" ] |
${JAR_FILE}是pom.xml里定义的变量名
如果maven打包时,不想执行Docker相关操作,则在mvn命令后加:
-Ddockerfile.skip
如:mvn clean package -Ddockerfile.skip
6.容器编排与调度
Swarm、Kubernates,待补充
6.1 容器编排
待补充。
6.2 容器调度
待补充。
7.Docker常用命令
除了以上命令以后,还有以下的命令运行更方便快捷。
命令 | 说明 |
docker ps | 显示正在运行的容器 |
docker ps -a | 显示所有的容器 |
docker ps -l | 显示最近一次运行的容器 |
docker image ls | 列出已安装的顶层镜像 |
docker images xxx | 列出已安装的指定的某个镜像,xxx代表镜像名字,支持通配符 |
docker images -q | 列出已安装的镜像ID |
docker search xxx | 搜索镜像名,xxx代表镜像名字,支持通配符 |
docker pull redis:3.0.7 | 下载redis镜像,版本是3.0.7,如果不带:和3.0.7则默认下载最新版本 |
docker rm 容器名 | 删除指定的容器 |
docker rm $(docker ps -a -q) | 慎用!删除所有停止运行的容器 |
docker run 容器名 env | 等于: 查看指定容器的环境变量 |
docker images -viz | dot -T png -o docker.png | 生成容器依赖关系图 |
docker run -it 容器名 | docker run <=> 先docker create 再 docker start -it表示后台服务挂起 |
docker stop containerID | 停止指定的容器 |
docker exec -it containerID /bin/bash | 进入指定的容器的命令行 |
docker inspect -f='{{.Name}}' $(docker ps -a -q) | 查看容器的名称 |
docker inspect -f='{{.NetworkSettings.IPAddress}}' $(sudo docker ps -a -q) | 查看容器的名IP 或分步:
3. 从显示信息中可以看到IP |
docker run --name container-name -d image-name | 运行一个image-name镜像的一个实例,名为container-name |
docker run -d -p [本机端口]:[docker服务器端口] --name container-name image-name | 启动容器时,指定主机与容器的IP映射关系 |
docker logs firstmysql | 查看容器firstmysql的日志 |
docker run --name firstmysql -p 3306:13306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:latest
启动mysql的镜像,生成一个容器,3306是本地端口,13306是容器中的端口,两者可一样,123456是mysql的root密码,latest表示mysql镜像的版本号,latest表示最新版本。
docker run -p 6379:6379 -v $PWD/data:/data -d redis redis-server --appendonly yes
8.常见问题
以下针对docker安装或启动时的问题进行解答。
8.1 连不上docker官方仓库
国外网络有时访问比较慢,可以切到国内镜像仓库。
8.2 启动mysql容器后,使用客户端连不上,报ERROR 2059 (HY000)
ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded: /usr/lib64/mysql/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory
原因:指定了加密方式则可能在客户端连接时有问题
解决方案:
1.进入mysql容器
docker exec -it hello-mysql /bin/bash
2.进入mysql
mysql -uroot -p123456
3.修改密码
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root';
或:
update mysql.user set password=PASSWORD("pwd") where User='root';
报错:ERROR 1045 (28000): Access denied for user 'root'@'172.17.0.1' (using password: NO)
原因:主机没有访问容器数据库的权限
方法:
use mysql;
update user u set u.host = '%' where u.user = 'root' limit 1;
flush privileges;
如果客户端无法telnet容器,则需要关闭容器的防火墙
chkconfig iptables off
9.参考资料及下载
VMware-player下载
http://download3.vmware.com/software/player/file/VMware-player-14.0.0-6661328.exe
CentOS 7(64位)镜像文件下载
http://mirrors.sohu.com/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-1804.iso
dockerfile-maven项目
https://github.com/spotify/dockerfile-maven
docker-maven-plugin