## docker学习
![image-20210112231133829](http://tuchuang1234.oss-cn-shenzhen.aliyuncs.com/typora/202101/12/231134-36250.png)
### docker的安装
1. **安装https协议、CA证书**、dirmngr
```text
apt-get update
apt-get install -y apt-transport-https ca-certificates
apt-get install dirmngr
```
**2.添加GPG密钥并添加更新源**
```text
curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian/gpg | sudo apt-key add -
echo 'deb https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian/ buster stable' | sudo tee /etc/apt/sources.list.d/docker.list
```
**3.系统更新以及安装docker**
```text
apt-get update
apt install docker-ce
```
执行成功后查看docker的版本
>docker -v
输出以下结果代表安装成功
>root@yhn-PC:/home/yhn# docker -v <br>
Docker version 18.09.6, build 481bc77
<!-- more -->
### 阿里云配置容器镜像服务
阿里云搜索 容器镜像服务
然后找到镜像加速器
按照提示进行docker更换源
```
加速器
使用加速器可以提升获取Docker官方镜像的速度
加速器地址
https://llrl8e7g.mirror.aliyuncs.com
1. 安装/升级Docker客户端
推荐安装1.10.0以上版本的Docker客户端,参考文档 docker-ce
2. 配置镜像加速器
针对Docker客户端版本大于 1.10.0 的用户
您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://llrl8e7g.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
```
### docker进程命令
#### 启动、暂停和重启服务
>systemctl start(stop,restart为停止和重启) docker
#### 状态查看
>systemctl status docker
```shell
root@yhn-PC:/etc/systemd/system# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2020-03-30 16:05:16 CST; 23min ago
Docs: https://docs.docker.com
Main PID: 16127 (dockerd)
Tasks: 16
Memory: 34.6M
CPU: 866ms
CGroup: /system.slice/docker.service
└─16127 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
3月 30 16:05:16 yhn-PC dockerd[16127]: time="2020-03-30T16:05:16.432588632+08:00" level=warning msg="Your kernel does not support swap memory limit"
3月 30 16:05:16 yhn-PC dockerd[16127]: time="2020-03-30T16:05:16.432643243+08:00" level=warning msg="Your kernel does not support cgroup rt period"
3月 30 16:05:16 yhn-PC dockerd[16127]: time="2020-03-30T16:05:16.432652888+08:00" level=warning msg="Your kernel does not support cgroup rt runtime"
3月 30 16:05:16 yhn-PC dockerd[16127]: time="2020-03-30T16:05:16.433268163+08:00" level=info msg="Loading containers: start."
3月 30 16:05:16 yhn-PC dockerd[16127]: time="2020-03-30T16:05:16.609979119+08:00" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon
3月 30 16:05:16 yhn-PC dockerd[16127]: time="2020-03-30T16:05:16.794602138+08:00" level=info msg="Loading containers: done."
3月 30 16:05:16 yhn-PC dockerd[16127]: time="2020-03-30T16:05:16.876597431+08:00" level=info msg="Docker daemon" commit=481bc77 graphdriver(s)=overlay2 version=18.09.6
3月 30 16:05:16 yhn-PC dockerd[16127]: time="2020-03-30T16:05:16.876688934+08:00" level=info msg="Daemon has completed initialization"
3月 30 16:05:16 yhn-PC dockerd[16127]: time="2020-03-30T16:05:16.881746054+08:00" level=info msg="API listen on /var/run/docker.sock"
3月 30 16:05:16 yhn-PC systemd[1]: Started Docker Application Container Engine
```
#### docker开机启动
>systemctl enable docker
<br>
<br>
<br>
<br>
<br>
<br>
<br>
### docker 镜像相关命令
#### 查看镜像(本地)
>docker images
名称 版本号 ID 时间信息 大小
```
root@yhn-PC:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos_ssl v1 bbd839ae58fd 3 months ago 406MB
centos v4 d633bd4f9d5c 6 months ago 394MB
```
#### 搜索镜像(远程)
>docker search 镜像名
去https://hub.docker.com/ 找版本号 版本号不能瞎填<br>
#### 拉取(下载)镜像(远程)
>docker pull 镜像名:版本号
例子
>docker pull redis
```
下载完会多一个出来
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest f0453552d7f2 2 weeks ago 98.2MB
```
#### 删除镜像(本地)
>docker rmi 名字:版本 (Id)
例子
>docker rmi f0453552d7f2 <br>
>docker rmi redis:5.0
<br>
<br>
<br>
<br>
<br>
<br>
<br>
### docker容器相关命令
#### 查看容器
1. 查看正在运行的容器
>docker ps
2. 查看历史容器
>docker ps -a
#### 创建容器
##### 第一种方法创建容器
创建完退出后容器自动停止运行
>docker run -it --name=容器名字 容器名字:版本号 /bin/bash
例子
>docker run -it --name=aaa centos:v4 /bin/bash
i 一直运行着<br>
t 给容器分配一个终端<br>
--name=容器名字 给容器起名字
进入容器后 shell中显示会不一样
>[root@4c7aaef2fa03 /]
##### 第二种方法创建容器
>docker run -id --name=容器名字 容器名字:版本号 /bin/bash
其他东西类似
#### 进入容器
>docker exec -it 容器名称 /bin/bash
例子
>docker exec -it bbb /bin/bash
#### 启动容器
>docker start 容器名字
#### 停止容器
>docker stop 容器名字
#### 删除容器
>docker rm 容器名字
删除所有容器
```
docker rm `docker ps -aq`
```
#### 查看容器信息
>docker inspect 容器名称
<br>
<br>
<br>
<br>
<br>
<br>
<br>
### docker容器中的数据卷
- 三个问题
- docker容器删除了容器产生的数据会随之销毁吗
- docker容器和外部机器怎么交换文件
- docker容器之间可以进行数据交互吗
- 数据卷
- 数据卷是宿主机中的一个目录或者文件
- 当容器目录和数据卷目录绑定后,对方的修改会立即同步
- 一个数据卷目录可以被多个容器同时挂载
- 一个容器也可以挂载多个数据卷
- 数据卷的作用
- 容器数据持久化
- 外部机器和容器间间接通信
- 容器之间数据交换
<br>
<br>
<br>
<br>
<br>
<br>
<br>
### docker容器中的数据卷的配置
创建启动容器的时候使用 -v 参数来设置数据卷
>docker run ... -v 宿主机目录(文件):容器内目录(文件)
- 注意事项
- 目录必须是绝对路径
- 如果目录不存在,会自动创建
- 可以挂载多个数据卷
例子1 挂载一个数据卷
>docker run -it --name=aaa -v /project/docker/aaa:/docker centos:v4 /bin/bash
例子2 挂载多个数据卷
>docker run -it --name=aaa -v /project/docker/aaa:/docker/aaa -v /project/docker/bbb:/docker/bbb centos:v4 /bin/bash
例子3 数据卷容器
1. 创建c3数据容器卷 (下边/docker/c3是创建在容器中的目录)
> docker run -it --name=c3 -v /docker/c3 centos:v4 /bin/bash
2. 创建启动c1 c2容器,使用--volumes-from参数设置数据卷
>docker run -it --name=c1 --volumes-from c3 centos:v4 /bin/bash <br>
docker run -it --name=c2 --volumes-from c3 centos:v4 /bin/bash
<br>
<br>
<br>
<br>
<br>
<br>
<br>
### docker halo 博客系统的部署
```
docker run -it -d --name halo -p 81:8090 -v /project/docker/halo:/root/.halo --restart=always halohub/halo
```
### docker nextcloud 的部署
```
docker run --name nextcloud -p 17000:80 -v /mnt/nextCloudStorage/data:/var/www/html -d nextcloud
```
### docker mysql的部署
例子
通过端口映射将服务暴露给真机
```shell
docker run -itd -p 4000:3306 --name=mysql -v /project/docker/mysql/conf:/etc/mysql/conf.d -v /project/docker/mysql/logs:/logs -v /project/docker/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=你的密码 mysql
```
使用的是mysql8.0.19版本
命令行连接
>mysql -h 127.0.0.1 -uroot -P4000 -p123456
成功连接
<br>
<br>
<br>
<br>
<br>
<br>
<br>
### docker Tomcat的部署
```
docker run -id --name=tomcat -p 4001:8080 -v /project/docker/tomcat:/usr/local/tomcat/webapps tomcat
```
因为tomcat必须要在根目录下创建一个文件夹 所以直接把项目移动进去不行
<br>
<br>
<br>
<br>
<br>
<br>
<br>
### docker Nginx的部署
```
docker run -id --name=nginx -p 2:80 -v /project/docker/nginx/nginx.conf:/etc/nginx.conf -v /project/docker/nginx/logs:/var/log/nginx -v /project/docker/nginx/html:/usr/share/nginx/html nginx
```
nginx 下边的nginx.conf 文件需要提前创建好 否则会报错
<br>
<br>
<br>
<br>
<br>
<br>
<br>
### docker vscodeServer的部署
```shell
docker run -it \
-e PASSWORD='你的密码' \
-e "DOCKER_USER=root" \
-p 13999:8080 \
-u "$(id -u):$(id -g)" \
-v "/project/docker/vscodeServer/workspace:/workspace" \
-v "/project/docker/vscodeServer/.config:$PWD/config" codercom/code-server:latest
```
nginx反向代理 配置 nginx.conf文件
```ini
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
#以下属性中,以ssl开头的属性表示与证书配置有关。
server {
# 填写nginx向公网开放的端口
listen 14000 ssl;
# 填写SSL证书对应的域名
server_name 你的域名;
# SSL证书文件,请替换成对应的绝对路径和文件名
ssl_certificate /etc/nginx/cert/a.pem;
# SSL证书密钥文件,请替换成对应的绝对路径和文件名
ssl_certificate_key /etc/nginx/cert/a.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
# 填写nginx代理的本地端口,请把端口替换成上面code-server配置的实际端口
proxy_pass http://localhost:13999/;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
proxy_set_header Accept-Encoding gzip;
}
# 使用497状态码检测HTTP请求,自动转换为HTTPS
error_page 497 https://$host:$server_port$uri$is_args$args;
# 配置IP访问规则列表,下面会提到,如果不需要,就把这行注释并跳过IP访问规则列表配置
#include blockips.conf;
}
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
#mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
# }
#}
```
### docker redis的部署
```shell
docker run --name my-redis -p 5000:6379 -v /project/docker/redis/data:/data -d redis redis-server --appendonly yes --requirepass "你的密码"
####################################################################################################
# 解释
# --name # 容器名字
# -p 5000:6379 # 将容器内的6379端口 映射到物理机的5000端口上
# -v /project/docker/redis/data:/data # 将容器内的/data目录 映射到物理机上的/project/docker/redis/data目录下
# redis-server --appendonly yes # 在容器执行redis-server启动命令,并打开redis持久化配置
# --requirepass "123456" # 设置访问密码为123456
```
### docker gitlab的部署
```shell
docker run -d -p 15443:15443 -p 15000:15000 -p 15022:22 --name gitlab --restart always -v /project/docker/gitlab/config:/etc/gitlab -v /project/docker/gitlab/logs:/var/log/gitlab -v /project/docker/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce
#################################################
#gitlab配置文件 配置ssl 和 ssh
external_url 'https://你的网站域名:15443'
nginx['ssl_certificate'] = "/etc/gitlab/ssl/a.pem"
nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/a.key"
nginx['redirect_http_to_https'] = true
nginx['listen_port']=15443 # docker 里边端口改为15443 物理机外边也是15443
gitlab_rails['gitlab_shell_ssh_port'] = 15022 # 这个可以加 这样 复制的时候地址栏就是ssh://xxxxxx:15022/用户名/项目名.git
# 要想使用ssh 必须设置(docker内部机器)一下 先 docker exec -it xxxx /bin/bash
# nano /etc/hosts.allow
# 最后一行添加 sshd: ALL 这样就允许所有ip来访问ssh 的22端口 这样git clone的时候就不会被拒绝了
# 别忘了 执行service ssh restart 来重启一下ssh服务
# 注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意
# 注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意
# 注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意
# 注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意
# 注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意注意
# 注意每次重启之后 必须执行一边 service ssh restart 否则git clone会报错
# gitlab 容器内停止 重配置 和 启动
gitlab-ctl stop
gitlab-ctl reconfigure
gitlab-ctl start
#在 .ssh目录下 可以新建一个config文件 如果端口不是常见的端口 那么可以用这个配置文件代替一些东西
# 比如没有config文件之前 执行 git clone git@域名:用户名/项目名.git 默认走的端口是22
# 要不然就得改成 git clone ssh://域名:端口/用户名/项目名.git
# 有了config之后 执行 git clone git@域名:用户名/项目名.git 走的端口就是你config里写的端口
Host 你的域名
User git
Port 15022
IdentityFile /Users/用户名/.ssh/id_rsa
```
### docker gogs的部署
```bash
docker run -d --name=gogs -p 7778:22 -p 7777:3000 -v /project/docker/gogs/data:/data gogs/gogs
```
```
docker run -u root -d -p 8888:8080 -p 8889:50000 -v /project/docker/jenkins:/var/jenkins_home -v /project/docker/jenkins/run/docker.sock:/var/run/docker.sock jenkinsci/blueocean
```
```shell
docker run -d -p 8888:8080 -p 8889:50000 -v /project/docker/jenkins:/var/jenkins_home jenkinsci/blueocean
```
### docker portainer 可视化工具
```shell
docker pull portainer/portainer
docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v /project/docker/portainer_data:/data portainer/portainer
```
### docker sqlsever的部署
```shell
> docker pull microsoft/mssql-server-linux
> sudo docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=你的密码" \
-p 1433:1433 --name sql1 -h sql1 \
-d mcr.microsoft.com/mssql/server:2019-latest
```
### docker 禅道的部署(项目管理软件)
```shell
sudo docker run --name [容器名] -p [主机端口]:80 --network=[网络驱动名] --ip [容器IP] --mac-address [mac地址] -v [主机禅道目录]:/www/zentaopms -v [主机mysql目录]:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=[数据库密码] -d easysoft/zentao:[镜像标签]
########################################################
> docker network create --driver bridge --subnet 192.168.99.0/24 --gateway 192.168.99.1 mynet
> sudo docker run --name myzentao -p 8888:80 --network=mynet --ip 192.168.99.2 -v /project/docker/chandao:/www/zentaopms -v /project/docker/mysqlChandao:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=你的密码 -d easysoft/zentao
```
### docker的基本原理
1. linux操作系统由bootfs和rootfs组成<br>
bootfs包括BootLoader(引导加载程序)和kernel(内核)<br>
rootfs是root文件系统,包含的就是典型的linux系统中的/dev,/proc,/bin,/etc等标准目录和文件<br>
各个发行版不同的是rootfs而bootfs是相同的
2. docker镜像是由特殊的文件系统叠加而成<br>
最低端是bootfs,并使用宿主机的bootfs,所以docker启动非常快,因为docker会复用宿主系统的boottfs,另一方面,宿主系统是linux就不能混用其他内核的操作系统容器。
3. 第一层 bootfs <br>
第二层 rootfs基础镜像(例如ubuntu或者centos)<br>
第3到第n-1层 其他基础环境 (例如python或者jdk等等)<br>
第n层 真正的应用层 (例如ngnix mysql或者Apache等等)<br>
第n+1层 可写容器层(container)
4. 第2层到第n层都是只读镜像 不可更改
<br>
<br>
<br>
<br>
<br>
<br>
<br>
### docker的镜像制作
#### 第一种镜像制作方式
```
以下制作镜像的方式,只能保存在镜像中创建的文件 但是,挂载的目录是不会保存在镜像中的
```
1. 容器转为镜像
>docker commit 容器id 镜像名称:版本号
例子
>docker commit 59f8ef3cd1bd tomcatimage
2. 镜像文件转换成压缩文件
>docker save -o 压缩文件名称 镜像名称:版本号
例子
>docker save -o tomcatimage.tar tomcatimage
3. 把压缩文件还原成镜像
>docker load -i 压缩文件名称
例子
>docker load -i tomcatimage.tar
#### 第二种镜像制作方式 dockerfile、
1. dockerfile是什么<br>
dockerfile是一个文本文件,包含了一层层的指令,每一条指令构建一层,基于基础镜像最终构建出一个新的镜像,可以为开发人群提供一个完全一致的开发环境。
以下是centos8的dockerfile
```
FROM scratch
ADD CentOS-8-Container-8.1.1911-20200113.3-layer.x86_64.tar.xz /
LABEL org.label-schema.schema-version="1.0" \
org.label-schema.name="CentOS Base Image" \
org.label-schema.vendor="CentOS" \
org.label-schema.license="GPLv2" \
org.label-schema.build-date="20200114" \
org.opencontainers.image.title="CentOS Base Image" \
org.opencontainers.image.vendor="CentOS" \
org.opencontainers.image.licenses="GPL-2.0-only" \
org.opencontainers.image.created="2020-01-14 00:00:00-08:00"
CMD ["/bin/bash"]
```
2. dockerfile的关键字
| 关键字 | 作用 | 备注 |
|-------------|--------------|--------------------------------------------------------------------------------------------------------------------------------------|
| FROM | 指定基础镜像 | 指定dockerfile基于那个image构建,建议格式写全 registry/namespace/project:tag 或者 registry/namespace/project:tag as aliasName |
| MAINTAINER | 作者信息 | 用来标明这个dockerfile谁写的 |
| LABEL | 标签 | 用来标明dockerfile的标签 可以使用Label代替Maintainer 最终都是在docker image基本信息中可以查看 |
| RUN | 执行命令 | 执行一段命令 默认是/bin/sh 格式: RUN command 或者 RUN \["command" , "param1","param2"\] |
| CMD | 容器启动命令 | 提供启动容器时候的默认命令 和ENTRYPOINT配合使用 格式 CMD command param1 param2 或者 CMD \["command" , "param1","param2"\] |
| ENTRYPOINT | 入口 | 一般在制作一些执行就关闭的容器中会使用 配合CMD 使用更好 下面会专门说这个东西 |
| COPY | 复制文件 | build的时候复制文件到image中 可以使用通配符 只要复合go的filepath\.Match规则就行 COPY source target 如果是从标准输出流构建 无法使用这个关键字 |
| ADD | 添加文件 | build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务 ADD source target 注意: target如果带/ 那么会把target当成文件夹 内部文件名称自动推断 如果没有带/那么可能蒋target当成一个文件 |
| ENV | 环境变量 | 指定build时候的环境变量 可以在启动的容器的时候 通过\-e覆盖 格式ENV name=value \.\.\. |
| ARG | 构建参数 | 构建参数 只在构建的时候使用的参数 如果有ENV 那么ENV的相同名字的值始终覆盖arg的参数 |
| VOLUME | 定义外部可以挂载的数据卷 | 指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 \-v 绑定 格式 VOLUME \["目录"\] |
| EXPOSE | 暴露端口 | 定义容器运行的时候监听的端口 启动容器的使用\-p来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp 如果不指定监听tcp还是udp 那么默认为tcp |
| WORKDIR | 工作目录 | 指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条workdir的路径的相对路径 |
| USER | 指定执行用户 | 指定build或者启动的时候 用户 在RUN CMD ENTRYPONT执行的时候的用户 |
| HEALTHCHECK | 健康检查 | 指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制 |
| ONBUILD | 触发器 | 当存在ONBUILD关键字的镜像作为基础镜像的时候 当执行FROM完成之后 会执行 ONBUILD的命令 但是不影响当前镜像 用处也不怎么大 |
| STOPSIGNAL | 发送信号量到宿主机 | 该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。此信号可以是与内核的系统调用表中的位置匹配的有效无符号数,例如9,或SIGNAME格式的信号名,例如SIGKILL。 这个不太明白干啥的 看起来是和宿主机通过信号量交互的 |
| SHELL | 指定执行脚本的shell | 指定RUN CMD ENTRYPOINT 执行命令的时候 使用的shell 例如 sh bash zsh powershell 等 格式 SHELL zsh |
<br>
<br>
<br>
<br>
<br>
<br>
<br>
#### 自定义一个centos镜像
1. 需求
- 默认登录路径为/usr
- 可以使用vim(vim默认在centos中没有安装 只有vi)
创建一个叫centos_dockerfile的文件 填入以下内容
```
ROM centos:latest
MAINTAINER aaa
RUN yum install -y vim
WORKDIR /usr
cmd /bin/bash
```
然后执行
>docker build -f dockerfile文件位置 -t 镜像名称:版本号 寻址路径
>docker build -f ./centos_dockerfile -t mycentos:1 .
```
root@yhn-PC:/project/docker# docker build -f ./centos_dockerfile -t mycentos:1
"docker build" requires exactly 1 argument.
See 'docker build --help'.
Usage: docker build [OPTIONS] PATH | URL | -
Build an image from a Dockerfile
root@yhn-PC:/project/docker# docker build -f ./centos_dockerfile -t mycentos:1 .
Sending build context to Docker daemon 2.048kB
Step 1/5 : FROM centos:latest
---> 470671670cac
Step 2/5 : MAINTAINER aaa
---> Running in 2501e2decefe
Removing intermediate container 2501e2decefe
---> 7b1c942b3a53
Step 3/5 : RUN yum install -y vim
---> Running in dc66922adc88
CentOS-8 - AppStream 1.5 MB/s | 6.6 MB 00:04
CentOS-8 - Base 558 kB/s | 5.0 MB 00:09
CentOS-8 - Extras 972 B/s | 4.4 kB 00:04
Dependencies resolved.
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
vim-enhanced x86_64 2:8.0.1763-13.el8 AppStream 1.4 M
Installing dependencies:
gpm-libs x86_64 1.20.7-15.el8 AppStream 39 k
vim-common x86_64 2:8.0.1763-13.el8 AppStream 6.3 M
vim-filesystem noarch 2:8.0.1763-13.el8 AppStream 48 k
which x86_64 2.21-10.el8 BaseOS 49 k
Transaction Summary
================================================================================
Install 5 Packages
Total download size: 7.8 M
Installed size: 31 M
Downloading Packages:
(1/5): gpm-libs-1.20.7-15.el8.x86_64.rpm 30 kB/s | 39 kB 00:01
(2/5): vim-filesystem-8.0.1763-13.el8.noarch.rp 102 kB/s | 48 kB 00:00
(3/5): which-2.21-10.el8.x86_64.rpm 89 kB/s | 49 kB 00:00
(4/5): vim-enhanced-8.0.1763-13.el8.x86_64.rpm 181 kB/s | 1.4 MB 00:07
(5/5): vim-common-8.0.1763-13.el8.x86_64.rpm 120 kB/s | 6.3 MB 00:53
--------------------------------------------------------------------------------
Total 145 kB/s | 7.8 MB 00:55
warning: /var/cache/dnf/AppStream-02e86d1c976ab532/packages/gpm-libs-1.20.7-15.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
CentOS-8 - AppStream 1.6 MB/s | 1.6 kB 00:00
Importing GPG key 0x8483C65D:
Userid : "CentOS (CentOS Official Signing Key) <security@centos.org>"
Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : which-2.21-10.el8.x86_64 1/5
Installing : vim-filesystem-2:8.0.1763-13.el8.noarch 2/5
Installing : vim-common-2:8.0.1763-13.el8.x86_64 3/5
Installing : gpm-libs-1.20.7-15.el8.x86_64 4/5
Running scriptlet: gpm-libs-1.20.7-15.el8.x86_64 4/5
Installing : vim-enhanced-2:8.0.1763-13.el8.x86_64 5/5
Running scriptlet: vim-enhanced-2:8.0.1763-13.el8.x86_64 5/5
Running scriptlet: vim-common-2:8.0.1763-13.el8.x86_64 5/5
Verifying : gpm-libs-1.20.7-15.el8.x86_64 1/5
Verifying : vim-common-2:8.0.1763-13.el8.x86_64 2/5
Verifying : vim-enhanced-2:8.0.1763-13.el8.x86_64 3/5
Verifying : vim-filesystem-2:8.0.1763-13.el8.noarch 4/5
Verifying : which-2.21-10.el8.x86_64 5/5
Installed:
vim-enhanced-2:8.0.1763-13.el8.x86_64 gpm-libs-1.20.7-15.el8.x86_64
vim-common-2:8.0.1763-13.el8.x86_64 vim-filesystem-2:8.0.1763-13.el8.noarch
which-2.21-10.el8.x86_64
Complete!
Removing intermediate container dc66922adc88
---> f1b248867062
Step 4/5 : WORKDIR /usr
---> Running in 8e25e3ea04ce
Removing intermediate container 8e25e3ea04ce
---> 474e3bdcbcec
Step 5/5 : cmd /bin/bash
---> Running in 8536996c82bf
Removing intermediate container 8536996c82bf
---> fa659fa36555
Successfully built fa659fa36555
Successfully tagged mycentos:1
```
>[root@43f98994fd96 usr]# vim 可以使用
<br>
<br>
<br>
<br>
<br>
<br>
<br>
### docker服务编排
#### 概述
微服务架构的应用系统中一般包含若干个微服务,每个微服务一般会部署多个实例,如果每个微服务都需要手动启动停止,工作量会很大
- 要从dockerfile build image 或者 去dockerhub拉取image
- 要创建多个container
- 要管理这些container(启动停止删除)
#### Docker Compose
1. 利用Dockerfile定义运行环境镜像
2. 使用docker-compose.yml定义组成应用的各服务
3. 运行docker-compose up 启动应用
#### 因为我不会使用springboot 所以这里省略
使用compose可以进行集群部署 Nginx反向代理访问 很好用
### docker的私有仓库
#### 搭建私有仓库
```
一、安装docker私有仓库
1.拉取私有仓库的镜像
docker pull registry
2.启动私有仓库
docker run -di --name=registry -p 5000:5000 registry
3.浏览器访问http://localhost:5000/v2/_catalog。若浏览器显示{"repositories":[]}则表示安装成功
4.让docker信任私有仓库地址
1)编辑docker配置文件
vi /etc/docker/daemon.json
2)新增私有仓库地址
{
"registry-mirrors":["https://docker.mirrors.ustc.edu.cn"],
"insecure-registries":["192.168.25.129:5000"]
}
5.重启docker
systemctl restart docker
```
#### 上传镜像到私有仓库
```
二、上传镜像到私有仓库
1.标记此镜像为私有仓库的镜像
前一个为docker images命令下的
docker tag centos:latest 127.0.0.1:5000/centos:latest
2.启动私有仓库
docker start registry
3.上传标记的镜像
docker push 127.0.0.1:5000/centos
```
#### 拉取私有仓库的镜像
```
docker pull 127.0.0.1:5000/centos
```
### docker的具名挂载和匿名挂载
```shell
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径::容器内路径 # 指定路径挂载
```
#### 权限的控制
```shell
# 如果是ro的话只能从外部进行改变 内部容器内是没有权限的
> docker run -d -P --name nginx01 -v aaa-nginx:/etc/nginx:ro nginx
703140fcd93f6ec85bbba2da5df491183f2554c7611f86353afbc35379196a4e
> docker volume ls # 下边就有一个卷叫做 aaa-nginx
DRIVER VOLUME NAME
local 9c8e39ddda9702cb876602ba9a7a0c3a2e1428dad46a5a0a2ec718ba8dfa322c
local aaa-nginx
> curl localhost:32768 # 访问成功
<!DOCTYPE html>
```
### dockerfile
dockerfile就是用来构建docker镜像的构建文件! 命令脚本!
#### **FROM:指定基础镜像,必须为第一个命令**
```shell
格式:
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
示例:
FROM mysql:5.6
注:
tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像
```
#### **MAINTAINER: 维护者信息**
```shell
格式:
MAINTAINER <name>
示例:
MAINTAINER Jasper Xu
MAINTAINER sorex@163.com
MAINTAINER Jasper Xu <sorex@163.com>
```
#### **RUN:构建镜像时执行的命令**
```shell
RUN用于在镜像容器中执行命令,其有以下两种命令执行方式:
shell执行
格式:
RUN <command>
exec执行
格式:
RUN ["executable", "param1", "param2"]
示例:
RUN ["executable", "param1", "param2"]
RUN apk update
RUN ["/etc/execfile", "arg1", "arg1"]
注: RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache
```
#### **ADD:将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget**
```shell
格式:
ADD <src>... <dest>
ADD ["<src>",... "<dest>"] 用于支持包含空格的路径
示例:
ADD hom* /mydir/ # 添加所有以"hom"开头的文件
ADD hom?.txt /mydir/ # ? 替代一个单字符,例如:"home.txt"
ADD test relativeDir/ # 添加 "test" 到 `WORKDIR`/relativeDir/
ADD test /absoluteDir/ # 添加 "test" 到 /absoluteDir/
```
#### **COPY:功能类似ADD,但是是不会自动解压文件,也不能访问网络资源**
#### **CMD:构建容器后调用,也就是在容器启动时才进行调用。**
```shell
格式:
CMD ["executable","param1","param2"] (执行可执行文件,优先)
CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
CMD command param1 param2 (执行shell内部命令)
示例:
CMD echo "This is a test." | wc -
CMD ["/usr/bin/wc","--help"]注: CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
```
#### **ENTRYPOINT:配置容器,使其可执行化。配合CMD可省去"application",只使用参数。**
```shell
格式:
ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先)
ENTRYPOINT command param1 param2 (shell内部命令)
示例:
FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]注: ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令。
```
#### **LABEL:用于为镜像添加元数据**
```shell
格式:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
示例:
LABEL version="1.0" description="这是一个Web服务器" by="IT笔录"
注:
使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。
```
#### **ENV:设置环境变量**
```shell
格式:
ENV <key> <value> #<key>之后的所有内容均会被视为其<value>的组成部分,因此,一次只能设置一个变量
ENV <key>=<value> ... #可以设置多个变量,每个变量为一个"<key>=<value>"的键值对,如果<key>中包含空格,可以使用\来进行转义,也可以通过""来进行标示;另外,反斜线也可以用于续行
示例:
ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat=fluffy
```
#### **EXPOSE:指定于外界交互的端口**
```shell
格式:
EXPOSE <port> [<port>...]
示例:
EXPOSE 80 443
EXPOSE 8080 EXPOSE 11211/tcp 11211/udp注: EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口
```
#### **VOLUME:用于指定持久化目录**
```shell
格式:
VOLUME ["/path/to/dir"]
示例:
VOLUME ["/data"]
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"注: 一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:
1 卷可以容器间共享和重用
2 容器并不一定要和其它容器共享卷
3 修改卷后会立即生效
4 对卷的修改不会对镜像产生影响
5 卷会一直存在,直到没有任何容器在使用它
```
#### **WORKDIR:工作目录,类似于cd命令**
```shell
格式:
WORKDIR /path/to/workdir
示例:
WORKDIR /a (这时工作目录为/a)
WORKDIR b (这时工作目录为/a/b)
WORKDIR c (这时工作目录为/a/b/c)注: 通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。
```
**USER:***
```shell
*指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户**
格式:
USER user
USER user:group
USER uid
USER uid:gid
USER user:gid
USER uid:group
示例:
USER www
注:
使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。镜像构建完成后,通过`docker run`运行容器时,可以通过-u参数来覆盖所指定的用户。
```
**ARG:用于指定传递给构建运行时的变量**
```shell
格式:
ARG <name>[=<default value>]
示例:
ARG site
ARG build_user=www
```
**ONBUILD:用于设置镜像触发器**
```shell
格式: ONBUILD [INSTRUCTION]
示例:
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
注: 当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被钥触发
```
**以下是一个小例子:**
```shell
# This my first nginx Dockerfile
# Version 1.0
# Base images 基础镜像
FROM centos
#MAINTAINER 维护者信息
MAINTAINER tianfeiyu
#ENV 设置环境变量
ENV PATH /usr/local/nginx/sbin:$PATH
#ADD 文件放在当前目录下,拷过去会自动解压
ADD nginx-1.8.0.tar.gz /usr/local/
ADD epel-release-latest-7.noarch.rpm /usr/local/
#RUN 执行以下命令
RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpm
RUN yum install -y wget lftp gcc gcc-c++ make openssl-devel pcre-devel pcre && yum clean all
RUN useradd -s /sbin/nologin -M www
#WORKDIR 相当于cd
WORKDIR /usr/local/nginx-1.8.0
RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-pcre && make && make install
RUN echo "daemon off;" >> /etc/nginx.conf
#EXPOSE 映射端口
EXPOSE 80
#CMD 运行以下命令
CMD ["nginx"]
```
### dockerfile实战例子
#### 例子1
##### myDockerfile
```shell
FROM centos
LABEL haonan 99611400@tc.gmail.com
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD /bin/bash
```
##### 运行命令行
```shell
> docker build -f myDockerfile -t mycentos:0.1 .
Sending build context to Docker daemon 2.048kB
Step 1/9 : FROM centos
---> 300e315adb2f
Step 2/9 : LABEL haonan 99611400@tc.gmail.com
---> Running in f05f98f4a129
Removing intermediate container f05f98f4a129
---> 6f2591c69952
Step 3/9 : ENV MYPATH /usr/local
---> Running in b187f708bcc8
Removing intermediate container b187f708bcc8
---> 7463fb4acbd1
Step 4/9 : WORKDIR $MYPATH
---> Running in 86606833a3fe
Removing intermediate container 86606833a3fe
---> 901abea30b11
Step 5/9 : RUN yum -y install vim
---> Running in d720d16b45e3
CentOS Linux 8 - AppStream 3.6 MB/s | 6.3 MB 00:01
CentOS Linux 8 - BaseOS 1.6 MB/s | 2.3 MB 00:01
CentOS Linux 8 - Extras 144 B/s | 8.6 kB 01:01
Dependencies resolved.
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
vim-enhanced x86_64 2:8.0.1763-15.el8 appstream 1.4 M
Installing dependencies:
gpm-libs x86_64 1.20.7-15.el8 appstream 39 k
vim-common x86_64 2:8.0.1763-15.el8 appstream 6.3 M
vim-filesystem noarch 2:8.0.1763-15.el8 appstream 48 k
which x86_64 2.21-12.el8 baseos 49 k
Transaction Summary
================================================================================
Install 5 Packages
Total download size: 7.8 M
Installed size: 30 M
Downloading Packages:
(1/5): gpm-libs-1.20.7-15.el8.x86_64.rpm 323 kB/s | 39 kB 00:00
(2/5): vim-filesystem-8.0.1763-15.el8.noarch.rp 884 kB/s | 48 kB 00:00
(3/5): which-2.21-12.el8.x86_64.rpm 994 kB/s | 49 kB 00:00
(4/5): vim-enhanced-8.0.1763-15.el8.x86_64.rpm 4.9 MB/s | 1.4 MB 00:00
(5/5): vim-common-8.0.1763-15.el8.x86_64.rpm 15 MB/s | 6.3 MB 00:00
--------------------------------------------------------------------------------
Total 1.6 MB/s | 7.8 MB 00:04
warning: /var/cache/dnf/appstream-02e86d1c976ab532/packages/gpm-libs-1.20.7-15.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
CentOS Linux 8 - AppStream 1.6 MB/s | 1.6 kB 00:00
Importing GPG key 0x8483C65D:
Userid : "CentOS (CentOS Official Signing Key) <security@centos.org>"
Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : which-2.21-12.el8.x86_64 1/5
Installing : vim-filesystem-2:8.0.1763-15.el8.noarch 2/5
Installing : vim-common-2:8.0.1763-15.el8.x86_64 3/5
Installing : gpm-libs-1.20.7-15.el8.x86_64 4/5
Running scriptlet: gpm-libs-1.20.7-15.el8.x86_64 4/5
Installing : vim-enhanced-2:8.0.1763-15.el8.x86_64 5/5
Running scriptlet: vim-enhanced-2:8.0.1763-15.el8.x86_64 5/5
Running scriptlet: vim-common-2:8.0.1763-15.el8.x86_64 5/5
Verifying : gpm-libs-1.20.7-15.el8.x86_64 1/5
Verifying : vim-common-2:8.0.1763-15.el8.x86_64 2/5
Verifying : vim-enhanced-2:8.0.1763-15.el8.x86_64 3/5
Verifying : vim-filesystem-2:8.0.1763-15.el8.noarch 4/5
Verifying : which-2.21-12.el8.x86_64 5/5
Installed:
gpm-libs-1.20.7-15.el8.x86_64 vim-common-2:8.0.1763-15.el8.x86_64
vim-enhanced-2:8.0.1763-15.el8.x86_64 vim-filesystem-2:8.0.1763-15.el8.noarch
which-2.21-12.el8.x86_64
Complete!
Removing intermediate container d720d16b45e3
---> 0f8f9f94cf7c
Step 6/9 : RUN yum -y install net-tools
---> Running in 4b4e0e44ace3
Last metadata expiration check: 0:00:12 ago on Tue Jan 12 09:21:08 2021.
Dependencies resolved.
================================================================================
Package Architecture Version Repository Size
================================================================================
Installing:
net-tools x86_64 2.0-0.52.20160912git.el8 baseos 322 k
Transaction Summary
================================================================================
Install 1 Package
Total download size: 322 k
Installed size: 942 k
Downloading Packages:
net-tools-2.0-0.52.20160912git.el8.x86_64.rpm 1.6 MB/s | 322 kB 00:00
--------------------------------------------------------------------------------
Total 468 kB/s | 322 kB 00:00
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : net-tools-2.0-0.52.20160912git.el8.x86_64 1/1
Running scriptlet: net-tools-2.0-0.52.20160912git.el8.x86_64 1/1
Verifying : net-tools-2.0-0.52.20160912git.el8.x86_64 1/1
Installed:
net-tools-2.0-0.52.20160912git.el8.x86_64
Complete!
Removing intermediate container 4b4e0e44ace3
---> bb025a30a5b7
Step 7/9 : EXPOSE 80
---> Running in 6de293141c41
Removing intermediate container 6de293141c41
---> 39332ddc9cd4
Step 8/9 : CMD echo $MYPATH
---> Running in f44e6e5227d2
Removing intermediate container f44e6e5227d2
---> 57e00491128f
Step 9/9 : CMD /bin/bash
---> Running in 945dfac1bb6c
Removing intermediate container 945dfac1bb6c
---> 0d2180a43e4b
Successfully built 0d2180a43e4b
Successfully tagged mycentos:0.1
```
#### 例子2
### docker网络(新手)
#### mycentos01 与 mycentos02 的创建
```shell
> docker run -it -P --name mycentos01 mycentos:0.1
# docker容器mycentos01内
> exit
exit
> docker start mycentos01 # 原先只有一个 mysql 后边重新启动了centos
> docker run -it -P --name mycentos02 --link mycentos01 mycentos:0.1
> exit
exit
> docker start mycentos02 # 原先只有一个 mysql 后边重新启动了centos
```
#### 查看物理机网卡与docker0
```shell
# 查看本机的网卡 值得注意的是多出来的docker0 和 三个网卡 这4个网卡都是与docker相关
#
> ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.18.0.1 netmask 255.255.0.0 broadcast 172.18.255.255
ether 02:42:ca:c3:1a:79 txqueuelen 0 (Ethernet)
RX packets 119585 bytes 85105283 (81.1 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 138308 bytes 159763379 (152.3 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.2.181 netmask 255.255.192.0 broadcast 172.17.63.255
ether 00:16:3e:10:4c:f2 txqueuelen 1000 (Ethernet)
RX packets 38345497 bytes 7666894470 (7.1 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 32918996 bytes 22486660653 (20.9 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1 (Local Loopback)
RX packets 24909353 bytes 1588707203 (1.4 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 24909353 bytes 1588707203 (1.4 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
veth140d1b5: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether aa:28:8a:15:01:6d txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4 bytes 216 (216.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
veth50c4ba9: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 5a:b8:c7:94:d3:34 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
veth7b95d08: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 7a:ba:a9:33:f7:0d txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
> docker network ls
# 6f2529adaa82 就是docker0
NETWORK ID NAME DRIVER SCOPE
6f2529adaa82 bridge bridge local
0c11da59216d host host local
0e5167a1521c none null local
# 6f2529adaa82 就是docker0 检查这个网络
# 发现有三个容器在这个网络中 分别是mysql 、mycentos01 与mycentos02
# ip分别为 172.18.0.2/16 172.18.0.3/16 与 172.18.0.4/16
> docker network inspect 6f
[
{
"Name": "bridge",
"Id": "6f2529adaa8299b88167bbc896376650263d32ecb5b903af0ded2dd012e86348",
"Created": "2021-01-12T19:09:14.514807814+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"334e99391076991ee22299b017ae97ec09f9cbb223154f9a5fb17d88143479c6": {
"Name": "mycentos01",
"EndpointID": "e9b8164bc15ab7dbad043a0d8a8853232a422c4aaa3d653e4cb38a7d8461a164",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
},
"7e637a475b7d7415d121f23e5990976eea76ce6e21fae60d08cceb44521ba07c": {
"Name": "mycentos02",
"EndpointID": "723613729e4a2b00297733adfcdfd6eca03ef669ab1d820dadd4f011df0976a3",
"MacAddress": "02:42:ac:12:00:04",
"IPv4Address": "172.18.0.4/16",
"IPv6Address": ""
},
"c38afa6e25c4c0b1e0641082cfb7c4188acf03103a5b82807ef78a50a9b65ea6": {
"Name": "mysql",
"EndpointID": "8645793d2f7b4bb186e93bf0be6bade2d22c0a4cc1441432871f9691c6904cd1",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
```
#### 测试容器之间的连通性与link的实质
```shell
# mycentos02能ping mycentos01 但是mycentos01 不能ping mycentos02 因为没有link
# 1. mycentos02 能ping mycentos01
> docker exec -it mycentos02 ping mycentos01
PING mycentos01 (172.18.0.3) 56(84) bytes of data.
64 bytes from mycentos01 (172.18.0.3): icmp_seq=1 ttl=64 time=0.118 ms
64 bytes from mycentos01 (172.18.0.3): icmp_seq=2 ttl=64 time=0.075 ms
64 bytes from mycentos01 (172.18.0.3): icmp_seq=3 ttl=64 time=0.071 ms
64 bytes from mycentos01 (172.18.0.3): icmp_seq=4 ttl=64 time=0.073 ms
^C
--- mycentos01 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 0.071/0.084/0.118/0.020 ms
# 2. mycentos01 不能ping mycentos02
> docker exec -it mycentos01 ping mycentos02
ping: mycentos02: Name or service not known
# 使用ip所有的容器都能ping通
# link的作用在这里体现 注意下方命令只保留想要的那部分 其他部分省略了
> docker inspect mycentos02
"Links": [
"/mycentos01:/mycentos02/mycentos01"
]
# link的实质是hosts文件中添加了一点内容
> docker exec -it mycentos02 /bin/bash
# 进入到了mycentos02 这个容器中去了
> cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.18.0.3 mycentos01 334e99391076
172.18.0.4 7e637a475b7d
```
docker inspect 6f58b401d877 | grep IPAddress
iptables -t nat -A DOCKER -p tcp --dport 9999 -j DNAT --to 10.88.0.37:9999
iptables -t nat -A CNI-DN-c9912e682a4b2473729f3-p tcp --dport 9999 -j DNAT --to-destination 10.88.0.38:9999
iptables -t nat -A CNI-DN-c9912e682a4b2473729f3 -p tcp --dport 9999 -j DNAT --to-destination 10.88.0.38:9999
```
iptables -t nat -A CNI-DN-c9912e682a4b2473729f3 -p tcp --dport 9999 -j DNAT --to-destination 10.88.0.41:9999
```
iptables -t nat -vnL
iptables -t nat -A CNI-DN-c9912e682a4b2473729f3 -p tcp --dport 9999 -j CNI-HOSTPORT-SETMARK --to-destination 10.88.0.41:9999
### docker自定义网络
#### 查看所有的网络
> docker network ls
```shell
> docker network ls
NETWORK ID NAME DRIVER SCOPE
6f2529adaa82 bridge bridge local
0c11da59216d host host local
0e5167a1521c none null local
```
#### 创建自定义网络
```shell
> docker network create --help
Usage: docker network create [OPTIONS] NETWORK
Create a network
Options:
--attachable Enable manual container attachment
--aux-address map Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
--config-from string The network from which copying the configuration
--config-only Create a configuration only network
-d, --driver string Driver to manage the Network (default "bridge")
--gateway strings IPv4 or IPv6 Gateway for the master subnet
--ingress Create swarm routing-mesh network
--internal Restrict external access to the network
--ip-range strings Allocate container ip from a sub-range
--ipam-driver string IP Address Management Driver (default "default")
--ipam-opt map Set IPAM driver specific options (default map[])
--ipv6 Enable IPv6 networking
--label list Set metadata on a network
-o, --opt map Set driver specific options (default map[])
--scope string Control the network's scope
--subnet strings Subnet in CIDR format that represents a network segment
```
#### 具体的例子
```shell
# 创建网络 桥接 --driver bridge 子网 --subnet 192.168.99.0/24 网关 --gateway 192.168.99.1 mynet
> docker network create --driver bridge --subnet 192.168.99.0/24 --gateway 192.168.99.1 mynet
4bb8798a6b17e9aecb1b1b25da00154e552019b18c9c2044fd3078f4dd4d68b5
# 查看所有 网络信息
> docker network ls
NETWORK ID NAME DRIVER SCOPE
6f2529adaa82 bridge bridge local
0c11da59216d host host local
4bb8798a6b17 mynet bridge local
0e5167a1521c none null local
# 查看刚才创建的名为mynet的网络
> docker network inspect mynet
[
{
"Name": "mynet",
"Id": "4bb8798a6b17e9aecb1b1b25da00154e552019b18c9c2044fd3078f4dd4d68b5",
"Created": "2021-01-12T21:11:46.22556349+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.99.0/24",
"Gateway": "192.168.99.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
# 之前已经删除了现在重新添加两个mycentos01 和 02 并将其加入到mynet这个刚创建的网络中去
> docker run -it -P --net mynet --name mycentos01 mycentos:0.1
> exit
exit
> docker start mycentos01
mycentos01
> docker run -it -P --net mynet --name mycentos02 mycentos:0.1
> exit
exit
> docker start mycentos02
mycentos02
# 再次查看mynet这个网络 发现 里边已经有了两个容器 分别是mycentos01 和 02 省略了一部分内容
> docker network inspect mynet
"Containers": {
"687fa87bb0e31c12c7c7342ca12bda3d844e9e688fae498e8044a6060faa5f3b": {
"Name": "mycentos01",
"EndpointID": "d510825ecaa3fe232de408b26109ce16ce6d13b557e672acd3e15794ac61d3c7",
"MacAddress": "02:42:c0:a8:63:02",
"IPv4Address": "192.168.99.2/24",
"IPv6Address": ""
},
"f49df237e81492e980ee50457c44d0ce0fa8a4990bb60f443e3954a0b0630d1d": {
"Name": "mycentos02",
"EndpointID": "877ad9807414ea7d770af93cda5289eb77cbeb4ab12a593951331b720a036314",
"MacAddress": "02:42:c0:a8:63:03",
"IPv4Address": "192.168.99.3/24",
"IPv6Address": ""
}
}
# 测试连通性 发现可以使用容器名字实现相互之间的访问
> docker exec -it mycentos01 ping mycentos02
PING mycentos02 (192.168.99.3) 56(84) bytes of data.
64 bytes from mycentos02.mynet (192.168.99.3): icmp_seq=1 ttl=64 time=0.049 ms
> docker exec -it mycentos02 ping mycentos01
PING mycentos01 (192.168.99.2) 56(84) bytes of data.
64 bytes from mycentos01.mynet (192.168.99.2): icmp_seq=1 ttl=64 time=0.034 ms
```
这样的好处可以保证集群的隔离 ,保证安全性
### docker 的网络连通(自定义网络进阶)
**其实就是一个容器两个ip**
```shell
# 创建一个默认在网卡docker0的容器 命名为mycentos03
> docker run -it -P --name mycentos03 mycentos:0.1
> exit
exit
> docker start mycentos03
```
![image-20210112215203479](http://tuchuang1234.oss-cn-shenzhen.aliyuncs.com/typora/202101/12/215203-760362.png)
要想实现上述的效果,我们需要进行 docker network connect操作
```shell
> docker network connect --help
Usage: docker network connect [OPTIONS] NETWORK CONTAINER
Connect a container to a network
Options:
--alias strings Add network-scoped alias for the container
--driver-opt strings driver options for the network
--ip string IPv4 address (e.g., 172.30.100.104)
--ip6 string IPv6 address (e.g., 2001:db8::33)
--link list Add link to another container
--link-local-ip strings Add a link-local address for the container
# 连接操作 这样mycentos03 和网卡mynet就连接到一块了 非常方便 互相之间也能ping通
> docker network connect mynet mycentos03
> docker exec -it mycentos03 ping mycentos01
PING mycentos01 (192.168.99.2) 56(84) bytes of data.
64 bytes from mycentos01.mynet (192.168.99.2): icmp_seq=1 ttl=64 time=0.066 ms
> docker exec -it mycentos01 ping mycentos03
PING mycentos03 (192.168.99.4) 56(84) bytes of data.
64 bytes from mycentos03.mynet (192.168.99.4): icmp_seq=1 ttl=64 time=0.035 ms
# 实质是 将mycentos03 放到了 mynet中 当然docker0中也有mycentos03
# 其实就是一个容器两个ip
> docker network inspect mynet
"6e80e6bb5e1c296b95d12e17a40aae761006b49fbab51fbcbd772e3731e668c9": {
"Name": "mycentos03",
"EndpointID": "073755de6680baceb9c36a00037fc0ae24437392b0539b60473c59b6080f52a4",
"MacAddress": "02:42:c0:a8:63:04",
"IPv4Address": "192.168.99.4/24",
"IPv6Address": ""
}
```
### docker 批量化操作
```shell
# 停掉所有正在运行的容器
> docker stop $(docker ps -q)
# 删除所有容器
> docker rm $(docker ps -aq)
```
### docker 实战微服务发布
Dockerfile
```shell
FROM openjdk:13
COPY *.jar /app.jar
CMD ["--server.port=9999"]
EXPOSE 9999
ENTRYPOINT ["java", "-jar","/app.jar"]
```
运行命令
```shell
# 构建镜像
> docker build -t myspringboot01:0.1 .
Successfully tagged myspringboot01:0.1
# 后台创建容器
> docker run -d -P --name abc myspringboot01:0.1
604e89dc6c7ff39f28f7d5df00533f5edb44a6f1157ff17f7058c95bb864cc78
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
604e89dc6c7f myspringboot01:0.1 "java -jar /app.jar …" 4 seconds ago Up 3 seconds 0.0.0.0:32768->9999/tcp abc
# 访问测试成功
> curl localhost:32768/test
hello,world
> docker exec -it abc ls /
app.jar boot etc lib media opt root sbin sys usr
bin dev home lib64 mnt proc run srv tmp var
```
## docker 进阶
### docker compose
#### 安装
`这里使用的不是官方的地址而是镜像地址,因为官方的地址太慢了`
```shell
> curl -L "https://github.com/docker/compose/releases/download/1.29.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 633 100 633 0 0 720 0 --:--:-- --:--:-- --:--:-- 719
100 12.1M 100 12.1M 0 0 1643k 0 0:00:07 0:00:07 --:--:-- 1969k
> chmod +x /usr/local/bin/docker-compose
> docker-compose version
docker-compose version 1.29.0, build 07737305
docker-py version: 5.0.0
CPython version: 3.7.10
OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
```
#### 官方示例demo
##### 在一个文件夹中准备四个文件
requirements.txt 很简单 所以就不进行列举了 下边有三个文件的内容
```shell
>mkdir /
> ls
app.py docker-compose.yml Dockerfile requirements.txt
> cat requirements.txt
flask
redis
```
###### app.py
```python
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
```
###### docker-compose.yml
```yml
version: "3.9"
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
```
###### Dockerfile
```shell
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
```
##### 启动服务
```shell
> docker-compose up
Starting composetest_web_1 ... done
Starting composetest_redis_1 ... done
Attaching to composetest_redis_1, composetest_web_1
redis_1 | 1:C 13 Jan 2021 07:51:49.072 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1 | 1:C 13 Jan 2021 07:51:49.072 # Redis version=6.0.9, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1 | 1:C 13 Jan 2021 07:51:49.072 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis_1 | 1:M 13 Jan 2021 07:51:49.073 * Running mode=standalone, port=6379.
redis_1 | 1:M 13 Jan 2021 07:51:49.073 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
redis_1 | 1:M 13 Jan 2021 07:51:49.073 # Server initialized
redis_1 | 1:M 13 Jan 2021 07:51:49.073 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
redis_1 | 1:M 13 Jan 2021 07:51:49.073 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo madvise > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled (set to 'madvise' or 'never').
redis_1 | 1:M 13 Jan 2021 07:51:49.099 * Loading RDB produced by version 6.0.9
redis_1 | 1:M 13 Jan 2021 07:51:49.099 * RDB age 7559 seconds
redis_1 | 1:M 13 Jan 2021 07:51:49.099 * RDB memory usage when created 0.79 Mb
redis_1 | 1:M 13 Jan 2021 07:51:49.099 * DB loaded from disk: 0.010 seconds
redis_1 | 1:M 13 Jan 2021 07:51:49.099 * Ready to accept connections
web_1 | * Serving Flask app "app.py"
web_1 | * Environment: production
web_1 | WARNING: This is a development server. Do not use it in a production deployment.
web_1 | Use a production WSGI server instead.
web_1 | * Debug mode: off
web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
```
##### network 相关信息
```shell
# 默认一个项目启动的时候会创建一个composetest_default的网络,将所有的容器包括进去
> docker network ls
NETWORK ID NAME DRIVER SCOPE
64438adca831 composetest_default bridge local
# 查看一下 默认创建的这个网络 发现里边有两个容器 一个是 redis 另一个是flask的web项目 和预期一样
> docker network inspect composetest_default
"Config": [
{
"Subnet": "172.19.0.0/16",
"Gateway": "172.19.0.1"
}
"Containers": {
"90f1157140f977f08b0245ed3cab10d7c890855a47b372d4922cd14dc2d58ed3": {
"Name": "composetest_redis_1",
"EndpointID": "c86fb402ffd211013b7e3c6511adf3d680e1168b33634234bf4b5d255a47123a",
"MacAddress": "02:42:ac:13:00:02",
"IPv4Address": "172.19.0.2/16",
"IPv6Address": ""
},
"b5a8ce3118acd92097f75e4bedf22c179122fd9e960bf97560746217972eca8d": {
"Name": "composetest_web_1",
"EndpointID": "21d2318751e9cd749467431a9392108bd0ec5aa0c37c9c04f8322baafb38873e",
"MacAddress": "02:42:ac:13:00:03",
"IPv4Address": "172.19.0.3/16",
"IPv6Address": ""
```
##### 停止服务
两种方法 一种是直接 `ctrl + c `或者是 执行 `docker-compose down`
不过**后者会移除容器** 前者只会停止服务!!!!!!
```shell
> docker-compose down
Stopping composetest_redis_1 ... done
Stopping composetest_web_1 ... done
Removing composetest_redis_1 ... done
Removing composetest_web_1 ... done
Removing network composetest_default
```
#### springboot + mysql + redis + flask + torch
```yml
version: "3.9"
services:
mysql:
container_name: my_mysql
image: mysql:latest
ports:
- "3306:3306"
volumes:
- /project/docker/mysql/conf:/etc/mysql/conf.d
- /project/docker/mysql/conf:/logs
- /project/docker/mysql/data:/var/lib/mysql
environment:
- MYISQL_ROOT_PASSWORD=你的mysql
networks:
- study_assist_network
restart: always
redis:
container_name: my_redis
image: redis
volumes:
- /project/docker/redis/data:/data
- /project/docker/redis/conf:/usr/local/etc/redis
networks:
- study_assist_network
command: "redis-server /usr/local/etc/redis/redis.conf --appendonly yes"
tomcat:
container_name: my_tomcat
image: tomcat
networks:
- study_assist_network
networks:
study_assist_network:
```
docker学习