docker

Docker

在这里插入图片描述

一. 容器的概念,作用

  • 容器是为了隔离资源
  • 容器技术的三大重点:
    2.1 chroot
    2.2 namespaces:资源隔离
  • PID:进程隔离
  • NET:网络接口管理
  • IPC:进程间通信
  • MNT:管理挂载点
  • UTS:隔离内核和版本识别
    2.3 CCgroups:控制每个namespace中的资源分配

二. docker的安装部署

1. 下载镜像源

curl  http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

2. 安装依赖包


> yum install -y yum-utils device-mapper-persistent-data lvm2 
> yum list docker-ce.x86_64 --showduplicates | sort -r

3. 安装docker-ce

yum install -y --setopt=obsoletes=0 \
docker-ce-17.03.2.ce-1.el7.centos.x86_64 \
docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch

4. 启动docker服务

systemctl daemon-reload
systemctl restart docker
docker version
docker  info

5. docker的体系结构

docker分三部分:

  1. 客户端程序:执行docker命令
  2. 服务端程序:驻留docker deamon;存放镜像;存放容器
  3. 镜像源:存放别人做好的镜像供下载

在这里插入图片描述
在这里插入图片描述

6. docker状态

在这里插入图片描述

7. docker所占磁盘空间

[root@master overlay]# docker system df
TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
Images              8                   3                   776.8 MB            776.8 MB (100%)
Containers          11                  2                   -2 B                0 B
Local Volumes       0                   0                   0 B                 0 B

8. 自动清理磁盘空间(已停止的容器,未被任何容器所使用的卷,未被任何容器所关联的网络,所有悬空镜像)[root@master overlay]# docker system prune

WARNING! This will remove:
	- all stopped containers
	- all volumes not used by at least one container
	- all networks not used by at least one container
	- all dangling images
Are you sure you want to continue? [y/N] 

三. 镜像管理

  1. 从源上搜索可用的镜像
    docker search centos
  2. 从源上下载镜像(冒号后面是要下载的版本,如果不填默认下载最新版 )
    docker pull centos:6.9
    docker pull centos:7.5.1804
    docker pull nginx
  3. 查询本机上已经下载的镜像‘’
    docker images
    docker images -q # 加一个q参数是只显示镜像id
    docker inspect ID/name:tag # inspect是查看镜像的详细信息
  4. 从本地删除镜像
docker rmi  IID 
docker rmi `docker images -q`  #删除所有镜像
docker rmi $(docker images -q)

5.导入导出镜像

[root@docker ~]# docker image save nginx >/opt/nginx.tar.gz
[root@docker ~]# docker image load -i /opt/nginx.tar.gz

四. 容器管理

4.1 启动容器

# 交互式启动容器
 [root@docker ~]# docker run -it --name "testcentos" centos:6.9 /bin/bash
主要是针对于工具类的容器,一旦exit容器,容器就自动关闭

# 守护式启动
1.交互式启动的容器使用完后,用Ctrl+p+q退出会让容器还在底层活着
[root@docker ~]# docker run  -it --name "testnginx" nginx /bin/bash
加ctrl+p+q
[root@docker ~]# docker attach testnginx
2.死循环
docker run  --name testnginx1  -d nginx /bin/sh -c "while true ;do echo hello world; sleep 1;done"
3.服务前台运行
sshd -D  
nginx -g ""

4.2 查看容器的cpu,内存,网络资源等使用情况

[root@andy ~]# docker container stats

在这里插入图片描述

4.3 run中的–entrypoint

在这里插入图片描述 等价于dockerfile中的
在这里插入图片描述

五. 容器中数据永久保存、容器间共享数据、host与容器共享数据

1. 容器中热数据的永久保存、host与容器共享数据

冷数据存储在镜像中;
热数据存储在容器中;
容器中的热数据在容器关闭后就丢失了;
要想把容器中的热数据永久保存需要用到host上的data volume;
把host中的data volume映射到容器中的目录或文件(不能映射到容器的dev)
data volume分为两种bind mount和managed volume
在这里插入图片描述

1.1 bind mount

是把host的目录或文件映射到容器

# v参数后面加host的路径
# 映射目录
docker run -d -p 80:80 -v ~/htdocs:/usr/local/test/htdocs httpd
# 映射文件
docker run -d -p 81:80 -v ~/htdocs/1.txt:/usr/local/test/htdocs/1.txt --name test1 httpd

1.2. managed volume

是把容器的目录或文件映射到主机

# v参数后不加host目录
docker run -d -p 82:80 -v /usr/local/test/htdocs --name test2 httpd

1.3. docker volume命令只能查看managed volume产生的数据卷,不能查看bind mount产生的数据卷

在这里插入图片描述

2. 容器间共享数据

容器间共享数据有两种方式:数据卷容器和data-packed volume container

2.1 数据卷容器 volume container

# volume container 是专门为其它容器提供 volume 的容器。
# volume container 提供的卷可以是 bind mount,也可以是 docker managed volume。
volume container 的优点:
# 与 bind mount 相比,不必为每一容器指定 host path,所有 path 都在 volume container 中定义好,容器只需要与 volume container 关联,从而实现容器与 host 的解偶。
# 第一步:建立一个数据卷容器,容器里面用v参数指定host目录与容器目录的映射关系

在这里插入图片描述# 第二步:用刚刚建立的数据卷容器创建三个容器test1,2,3
在这里插入图片描述
数据卷容器的缺点:

  1. host上的数据丢失的话,数据就没了;
  2. 一台host主机的数据没法给另一台host主机用

2.2 data-packed volume container

2.2.1 基本介绍

(1)前面例子 volume container 的数据归根到底还是在 host 里,如果想要将数据完全放到 volume container 中,同时又能与其它容器共享可以使用 data-packed volume container。
(2)data-packed volume container 原理是将数据打包到镜像中,然后通过 docker managed volume 共享。

2.2.2 使用场景

由于 data-packed volume container 是自包含的,不依赖 host 提供数据,具有很强的移植性,非常适合只使用静态数据的场景。比如应用的配置信息、Web server 的静态文件等。

2.2.3 data-packed volume container 的创建

(1)首先我们创建一个 Dockerfile 文件用于构建镜像

内容如下:

FROM busybox:latest
ADD htdocs /usr/local/apache2/htdocs
VOLUME /usr/local/apache2/htdocs

内容说明:

第二行:ADD 将静态文件添加到容器目录 /usr/local/apache2/htdocs
第三行:VOLUME 作用与 -v 等效,用来创建 docker managed volume,mount point 为 /usr/local/apache2/htdocs。因为这个目录就是 ADD 添加的目录,所以会将已有数据复制到 volume 中。

(2)接着 build 这个镜像,命名为 datapacked

docker build -t datapacked

(3)最后用这个镜像创建 data-packed volume container 即可

docker create --name vc_data datapacked

(4)data-packed volume container 的创建
data-packed volume container 创建好之后,其它容器同样通过 --volumes-from 来使用它。比如下面三个 httpd 容器都使用了 vc_data。

docker run --name web1 -d --volumes-from vc_data httpd
docker run --name web2 -d --volumes-from vc_data httpd
docker run --name web3 -d --volumes-from vc_data httpd

六. docker save、export、load、import

1. save和load

save:
可以将一个或多个image打包为tar文件;
也可对容器进行save,但save的是容器背后的image;
save命令后面即可跟镜像也可跟容器,跟容器实际是找背后得镜像去save
在这里插入图片描述load:
从save的tar向本地镜像库加载镜像,如果本地镜像库已经存在这两个镜像,将会被覆盖。
在这里插入图片描述

2. docker export和import

export:
用来讲容器的文件系统进行打包;
export后面要指定容器,不能指定镜像;
export得到的打包文件只能用import命令去生成镜像;
export的应用场景是制作基础镜像,比如你从一个ubuntu镜像启动一个容器,然后安装一些软件和进行一些设置后,使用docker export保存为一个打包文件,然后用import命令将这个打包文件制作为一个基础镜像。然后,把这个镜像分发给其他人使用,比如作为基础的开发环境。
在这里插入图片描述

import:将打包好的容器文件import到本地镜像仓库,同事可以指定新镜像的名字和tag

在这里插入图片描述

3. save和export的区别

总结一下docker save和docker export的区别:

  1. docker save保存的是镜像(image),docker export保存的是容器(container);
  2. docker load用来载入镜像包,docker import用来载入容器包,但两者都会恢复为镜像;
  3. docker load不能对载入的镜像重命名,而docker import可以为镜像指定新名称;
  4. save是保存一个镜像的所有层的内容;export只是保存容器的系统文件。

4. import和commit的区别

可以将docker import理解为将外部文件复制进来形成只有一层文件系统的镜像;
而docker commit则是将当前的改动提交为一层文件系统,然后叠加到原有镜像之上。

七. 用commit,load,import生成镜像的区别

1. commit

是将commit的容器的各层原始层叠加容器运行后的层所得,既n+1

2. save后load

就是原始镜像的各层,既n

3. export后import

将容器的系统文件作为一层放入镜像,既1

八. 基于容器制作新镜像

1. 基于centos6.9的镜像制作centos6.9+sshd+LAMP+PHP的镜像

(1). 运行基础centos6.9镜像

[root@andy centos]# mkdir -p /opt/vol/mysql /opt/vol/html
[root@andy centos]# docker run -it --name=old -v /opt/vol/mysql:/var/lib/mysql -v /opt/vol/html/:/var/www/html centos:6.9

(2). 安装需要的软件

# yum install openssl-server httpd mysql mysql-server php php-mysql -y

(3). 初始化刚安装的软件

3.1 sshd初始化

# /etc/init.d/sshd start
# /etc/init.d/sshd stop

3.2 mysqld初始化

# /etc/init.d/mysqld start
mysql> grant all on *.* to root@'%' identified by '123';
Query OK, 0 rows affected (0.00 sec)

mysql> grant all on *.* to discuz@'%' identified by '123';
Query OK, 0 rows affected (0.00 sec)
mysql> create database discuz charset utf8;
Query OK, 1 row affected (0.00 sec)

3.3 apache初始化

# /etc/init.d/httpd start

(4). 制作LAMP第一版基础镜像

# docker commit 3a57970e6767 centos_lamp:v1

(5). 根据第一版制作的镜像启动一个新容器

# docker container run -it --name old_v1 -v /opt/vol/mysql:/var/lib/mysql -v /opt/vol/html:/var/www/html -p 8080:80 centos_lamp:v1
[root@3fc96d397845 /]# /etc/init.d/mysqld start
[root@3fc96d397845 /]# /etc/init.d/httpd start

(6). 测试php功能

# vi /var/www/html/index.php
<?php
phpinfo();
?>

(7). 安装bbs论坛

上传bbs代码到宿主机/opt/vol/html目录

(8). 制作LAMP+BBS第二版镜像

# docker commit old_v1 centos_lamp:v2

(9). 创建容器启动的脚步

[root@andy centos]# cd /opt/vol/html/
[root@andy html]# vi init.sh

在这里插入图片描述

[root@andy html]# chmod 777 /opt/vol/html/init.sh

(10). 启动容器,映射端口,挂载数据卷,自启动多个服务

[root@andy html]# docker container run -d --name=new -v /opt/vol/mysql/:/var/lib/mysql -v /opt/vol/html/:/var/www/html -p 22222:22 -p 8888:80 -p 33060:3306 centos_lamp:v2 /var/www/html/init.sh

2. 基于centos7的容器做centos+sshd的镜像

(1). 下载并运行基础镜像centos7

# docker run -it --name=centos7base centos:7

(2).安装sshd服务

# yum install openssh-server -y

(3).初始化sshd

# mkdir /var/run/sshd
# echo 'UseDNS no' >> /etc/ssh/sshd_config
# sed -i -e '/pam_loginuid.so/d' /etc/pam.d/sshd
# echo 'root:123456' | chpasswd
# /usr/bin/ssh-keygen -A

(4).制作镜像

# docker commit e4b1b2f395ca centos7sshd:v1

(5).启动镜像

# docker container run -d -p 222:22 centos7sshd:v1 /usr/sbin/sshd -D 

九. 用dockerfile制作镜像

1. FROM 基础镜像

FROM 镜像名:tag
FROM 镜像名@id

2. RUN 制作镜像过程中使用的命令

# 这种方法会自动加一个/bin/bash, 第一进程就是bash
RUN /etc/init.d/sshd start &&  /etc/init.d/sshd stop
# 这种方式不会加bash,第一进程就是mysqld
RUN ["mysqld","--initialztion-insecure","--user=mysql"]

3. ARG 定义在build镜像时使用的变量

在Dockerfile中使用,仅仅在build docker image的过程中(包括CMD和ENTRYPOINT)有效,在image被创建和container启动之后,无效。

如果你在Dockerfile中使用了ARG但并未给定初始值,则在运行docker build的时候未指定该ARG变量,则会失败。

虽然其在container启动后不再生效,但是使用‘docker history’可以查看到。所以,敏感数据不建议使用ARG.

4. ENV 定义在build镜像时使用的变量并且在容器启动后会作为环境变量

在Dockerfile中使用,在build docker imag的过程中有效,在image被创建和container启动后作为环境变量依旧也有效,并且可以重写覆盖。printenv可查看其值。

# Set ENV
ENV JMETER_HOME /jmeter/apache-jmeter-$JMETER_VERSION/
ENV PATH $JMETER_HOME/bin:$PATH

3. EXPOSE 暴露端口

EXPOSE 22

4. 从宿主机向镜像copy文件

ADD:如果要复制的是.tar*格式的压缩文件,会自动解压到镜像
COPY:不会自动解压
#两者都能把源文件用一个url地址,这样相当于wget一个文件到镜像
#如果复制的是目录,会把目录下文件和目录复制,不会复制目录本身

5. VOLUME匿名挂载镜像目录到宿主机目录

VOLUME[目录1,目录2...]
#当该镜像被run为一个容器时会自动创建在VOLUME后面列表中的所有目录,并且将这些目录匿名挂载到宿主机的某目录

6. ENV设定变量,这些变量在构建镜像和运行为一个容器后都存在

ENV 变量名 变量值
如:
ENV datadir /var/www/html

3. CMD 用镜像启动容器时运行的第一个命令(如果写多个CMD,之前的将被覆盖)

CMD ["/usr/sbin/sshd","-D"]
在run一个容器时执行的第一个命令
CMD的命令可以被run容器时指定的命令替换

4. ENTRYPOINT用镜像启动容器时运行的第一个命令(如果写多个entrypiont,不会覆盖,会都执行)

# ENTRYPOINT还要一个用法:后一个entrypoint的内容会作为前一个entrypoint内容的参数来执行
# entrypoint不能被run容器时手动指定的命令替换

十 制作私有registry仓库

1. 私有registry仓库需要运行在registry这个容器中,所以要下载并运行这个容器;5000端口是registry提供服务的端口需要把5000这个端口映射出来;/var/lib/registry这个目录是registry存放镜像的目录,需要把这个目录数据卷到宿主机上的目录

[root@andy ~]# docker run -d -p 5000:5000 --restart=always --name registry -v /opt/registry:/var/lib/registry registry

2. 修改registry容器宿主机的配置文件,并重启docker服务

[root@andy ~]# vi /etc/docker/daemon.json 
{
"registry-mirrors":["https://68rmyzg7.mirror.aliyuncs.com"],
"insecure-registries":["192.168.1.223:5000"]
}
[root@andy ~]# systemctl restart docker

3.修改本地要上传到registry的镜像的镜像名为ip:端口号/名称:tag

[root@andy ~]# docker tag vinsdocker/jmserver 192.168.1.223:5000/jmeterserver:v1

4. 推送刚刚改为名的镜像到registry

[root@andy ~]# docker image push 192.168.1.223:5000/jmeterserver:v1
The push refers to a repository [192.168.1.223:5000/jmeterserver]
14ced7718937: Pushed 
22616b527a01: Pushed 
ead975661dc4: Pushed 
96e700309364: Pushed 
bca5421261df: Pushed 
473adefcdec2: Pushed 
7f877179d500: Pushed 
9c0da68f893b: Pushed 
e01103f88b34: Pushed 
2ec5c0a4cb57: Pushed 
v1: digest: sha256:1d261b04883e12d0d8ae728fc13e61efd334d353ff3cad325d1f961972d48c37 size: 2418

5. 查看本地库中的镜像文件

1 查看本地仓库容器中镜像的存放位置
[root@andy ~]# docker container inspect 9378451f8ffc | grep -i "source"
                "Source": "/opt/registry",
2 进入这个目录查看镜像的文件
[root@andy ~]# cd /opt/registry/docker/registry/v2/repositories/
[root@andy repositories]# ls
jmeterserver

6. 在另一个机器上下载私有库中的镜像

  1. 修改daemon.json文件
[root@andy ~]# vi /etc/docker/daemon.json 
{
"registry-mirrors":["https://68rmyzg7.mirror.aliyuncs.com"],
"insecure-registries":["192.168.1.223:5000"]
}
  1. pull镜像
[root@andy ~]# docker pull 192.168.1.223:5000/jmeterserver:v1

十一 给本地仓库加安全认证

1. 生成密码

# yum install httpd-tools -y
# mkdir /opt/registry-auth/ -p
# htpasswd -Bbn andy admin@123 > /opt/registry-auth/htpasswd

2. 运行带秘钥功能的registry容器

[root@andy ~]# docker run -d -p 5000:5000 -v /opt/registry-auth/:/auth/ -v /opt/registry:/var/lib/registry --name register-auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" registry

3. push镜像

1. 登录
[root@andy ~]# docker login 192.168.1.223:5000
Username: andy
Password: 
Login Succeeded

4. 在另一台pc上先登录在pull私有库中镜像

[root@andy ~]# docker login 192.168.1.223:5000
Username: andy
Password: 
Login Succeeded
You have mail in /var/spool/mail/root
[root@andy ~]# docker pull 192.168.1.223:5000/jmeterserver:v1

十二 发布镜像到docker hub

1. 注册一个hub账号,https://hub.docker.com/

2. 在docker hub上新建一个仓库

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3. 向docker hub推送镜像

# 1. 从本地的container中找一个容器,commit为一个名为51clearsight/jmeter的新镜像
[root@andy ~]# docker container ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                  PORTS               NAMES
0b5773599fb5        mysql               "docker-entrypoint..."   5 days ago          Exited (1) 5 days ago                       nervous_mayer
3be04a772429        mysql               "docker-entrypoint..."   5 days ago          Exited (1) 5 days ago                       optimistic_joliot
77ecedd7afbb        centos              "/bin/bash"              5 days ago          Up 5 days                                   amazing_boyd
b1d35daa2f17        centos              "/bin/bash"              5 days ago          Exited (0) 5 days ago                       gracious_lewin
[root@andy ~]# docker commit b1d35daa2f17 51clearsight/jmeter
sha256:ca732998bb9f58f00dcdc21125c41ab8c740301182b72ac5e9139a52dbf6addd

# 2. 登录docker hub
[root@andy ~]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: 51clearsight
Password: 
Login Succeeded

# 3. push这个新镜像
[root@andy ~]# docker push 51clearsight/jmeter:latest
The push refers to a repository [docker.io/51clearsight/jmeter]
184916df9627: Pushed 
291f6e44771a: Pushed 
latest: digest: sha256:d0adb1c8046b8e5aacde1d245f91deaa2a06937d790d6f448dfd467c83035446 size: 736

4. 去docker hub查看push是否成功,如果成功应该看到tag有内容

在这里插入图片描述

十三 发布镜像到阿里云

1. 在阿里云上新建一个仓库

https://cr.console.aliyun.com/

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 查看私有仓库的详情

在这里插入图片描述

3. 登录阿里云docker registry

[root@andy ~]# sudo docker login --username=clearsight51 registry.cn-beijing.aliyuncs.com
Password: 
Login Succeeded

4. 将准备上传到阿里云的本地镜像tag重命名一下

docker tag ca732998bb9f registry.cn-beijing.aliyuncs.com/51tangseng/51clearsight:v1

在这里插入图片描述

5. 将重命名的镜像推送到Registry

[root@andy ~]# docker image push registry.cn-beijing.aliyuncs.com/51tangseng/51clearsight:v1
The push refers to a repository [registry.cn-beijing.aliyuncs.com/51tangseng/51clearsight]
184916df9627: Pushed 
291f6e44771a: Pushed 
v1: digest: sha256:d0adb1c8046b8e5aacde1d245f91deaa2a06937d790d6f448dfd467c83035446 size: 736

6. 从阿里云查看上传的镜像

在这里插入图片描述

7. 从另一台docker宿主机中下载刚刚上传的镜像

# 如果是公开镜像,不用登录,直接pull
docker pull registry.cn-beijing.aliyuncs.com/51tangseng/51clearsight:v1

十四 网络

1. 本地网络

1. 1 查看支持的网络类型

docker network ls

在这里插入图片描述

1.2. run容器时指定网络类型

docker run --network=xxx

1.3. 四种本地网络类型

bridge:默认模式,相当于NAT
host:所有容器共用宿主机的Network Namespace,即所有容器的机器名都是宿主机的机器名;所有容器的ip都是宿主机的ip;宿主机和各个容器的端口号不能重复,如果重复宿主机的优先,先开的容器端口号能用,后开的容器相同端口号不能用
container: 各个容器之间共用Network Namespace
none:无网络模式

1.4. bridge

在这里插入图片描述

在这里插入图片描述
1.4.1 bridge的特点
docker run -it -d --network=bridge centos6.9
默认run一个容器时网络类型就是bridge
特点:

# 宿主机可以ping通容器172.17.x.x
# 容器可以ping通宿主机的网络网卡地址
# 容器可以ping通所有外部设备
# 外部设备只能通过容器与宿主机的端口映射出的端口来访问容器的某些端口
# 容器间可以用ip或容器id来ping通;但无法提供容器名来ping;如果想要用容器名来互通在run一个容器时要加--link参数,如:
[root@andy ~]# docker run -id --name busybox3 --link busybox1  busybox
这个参数的作用是在新run的容器busybox3中的host文件中加入172.17.0.X          busybox1

1.4.2. 创建自定义的bridge类型网络(自定义的brdge网络的各个容器间可以用容器名来互相访问)

 1. 
[root@andy ~]# docker network create --subnet 192.168.20.0/24 --gateway 192.168.20.1 -o parent=ens160 mybr0
a5626b4a59ef1e875404e1a3d744403aa94568a797688848dfefa1528d9d3328

2. 
[root@andy ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
82b558fe2ebf        bridge              bridge              local
b91c40f698d8        host                host                local
a5626b4a59ef        mybr0               bridge              local
58533a68f0a2        none                null                local

3.
[root@andy ~]# docker network inspect mybr0
[
    {
        "Name": "mybr0",
        "Id": "a5626b4a59ef1e875404e1a3d744403aa94568a797688848dfefa1528d9d3328",
        "Created": "2020-09-10T01:04:44.377764788+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.20.0/24",
                    "Gateway": "192.168.20.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Containers": {},
        "Options": {
            "parent": "ens160"
        },
        "Labels": {}
    }
]

4.
[root@andy ~]# docker run -id --name mybox1 --network mybr0 busybox
ccee428c31e58a41c21deea90e57075d97b71d8bed9720090cf9d8fc6e93f305
[root@andy ~]# docker run -id --name mybox2 --network mybr0 busybox
d832666b036dbf441c52c722dc228926a34a3785a1dce308f6fdd0b949e5327d
[root@andy ~]# docker exec -it mybox1 ping mybox2
PING mybox2 (192.168.20.3): 56 data bytes
64 bytes from 192.168.20.3: seq=0 ttl=64 time=0.114 ms
64 bytes from 192.168.20.3: seq=1 ttl=64 time=0.117 ms

1.4.3 不同bridge上的容器互通(本质是让某个容器有两块网卡)
在这里插入图片描述

1. 用network connect命令把busybox1这个容器连接到桥mybr0上
[root@andy ~]# docker network connect  mybr0 busybox1
2. 查看容器busybox1有两个网络bridge和mybr0
[root@andy ~]# docker container inspect busybox1
"Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "ebcf64e21dc8ab970b820d92003fcd60dbba5d339bcfdb6455bca6d719ac7682",
                    "EndpointID": "47f76d7f585056d34c419293279ecb236e978b04a60fde6259fcbc032ff28fba",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.3",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:03"
                },
                "mybr0": {
                    "IPAMConfig": {},
                    "Links": null,
                    "Aliases": [
                        "ff37925f147c"
                    ],
                    "NetworkID": "a5626b4a59ef1e875404e1a3d744403aa94568a797688848dfefa1528d9d3328",
                    "EndpointID": "47f567526511687dcd60858004ad6cc70b26cab806f61c4422510b9391ad56ff",
                    "Gateway": "192.168.20.1",
                    "IPAddress": "192.168.20.4",
                    "IPPrefixLen": 24,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:c0:a8:14:04"
                }

3. 用容器busybox1 连通 桥mybr0上的容器,是可以ping通的
[root@andy ~]# docker exec -it busybox1 ping 192.168.20.3
PING 192.168.20.3 (192.168.20.3): 56 data bytes
64 bytes from 192.168.20.3: seq=0 ttl=64 time=0.152 ms
64 bytes from 192.168.20.3: seq=1 ttl=64 time=0.099 ms

1.5. container

  1. container类型的网络是多个容器之间使用同一个namespace
  2. 使用方法:
# 创建一个httpd容器使用默认bridge网络
[root@andy ~]# docker run -itd --name web1 httpd
# 再创建一个busybox容器,让他使用container类型的网络并且指定和容器web1共用namespace
[root@andy ~]# docker run -itd --network container:web1 --name busy busybox
  1. 用处:
    当两个容器要通过loopback口快速通信时;
    当一个容器要监控另一个容器的网卡时

2. 跨主机网络(让不同docker宿主机里的容器能够互通)

2.1 两种跨主机网络类型

macvlan:

2.2 macvlan

  1. macvlan技术
    macvlan是一种linux虚拟网络设备技术,准确的说是网卡虚拟化技术,即把一块网络网卡虚拟成多块虚拟网卡
  2. macvlan的工作原理
    macvlan 是 Linux kernel 支持的新特性,支持的版本有 v3.9-3.19 和 4.0+,比较稳定的版本推荐 4.0+。它一般是以内核模块的形式存在,我们可以通过以下方法判断当前系统是否支持:
    在这里插入图片描述如果第一个命令报错,或者第二个命令没有返回,说明当前系统不支持 macvlan,需要升级内核。
    macvlan 这种技术听起来有点像 VLAN,但它们的实现机制是完全不一样的。macvlan 子接口和原来的主接口是完全独立的,可以单独配置 MAC 地址和 IP 地址,而 VLAN 子接口和主接口共用相同的 MAC 地址。VLAN 用来划分广播域,而 macvlan 共享同一个广播域。

通过不同的子接口,macvlan 也能做到流量的隔离。macvlan 会根据收到包的目的 MAC 地址判断这个包需要交给哪个虚拟网卡,虚拟网卡再把包交给上层的协议栈处理。
在这里插入图片描述3. 四种模式

根据 macvlan 子接口之间的通信模式,macvlan 有四种网络模式:

private 模式

vepa(virtual ethernet port aggregator) 模式

bridge 模式

passthru 模式
  1. macvlan用于docker网络
    4.1 docker的macvlan只支持bridge模式
    4.2 跨主机的容器使用相同macvlan进行通信的步骤:

1. 使用docker network create命令分别在所有docker宿主机上创建macvlan网络
[root@slave03 dockerfile]# docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=ens160 andy
be7b9af7c13906671dad3cc9cf5659f34e46ce84f4c60168f7370595d8a981a9


    -d 指定 Docker 网络 driver
    --subnet 指定 macvlan 网络所在的网络
    --gateway 指定网关
    -o parent 指定用来分配 macvlan 网络的物理网卡
    最后那个andy是随便起的一个macvlan名

2. 查看主机的网络环境,其中应该出现了 macvlan 网络
[root@slave03 dockerfile]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
be7b9af7c139        andy                macvlan             local
5cc154dc801b        bridge              bridge              local
b91c40f698d8        host                host                local
58533a68f0a2        none                null                local

3. 在第一台docker宿主机192.168.1.226上运行一个名叫macvlan1的容器并指定使用macvlan网络
docker run -itd --name macvlan1 --ip=192.168.1.236 --network andy busybox

这条命令中,

    --ip 指定容器 macvlan1 使用的 IP,这样做的目的是防止自动分配,造成 IP 冲突
    --network 指定 macvlan 网络

4. 同样在第二台docker宿主机192.168.1.227上运行一个名叫macvlan2的容器并指定使用macvlan网络
docker run -itd --name macvlan2 --ip=192.168.1.237 --network andy busybox

4.3 跨主机的容器使用不同macvlan进行通信的步骤(二层无法通信,需要借助三层路由):

在这里插入图片描述

安装上图分别在宿主机192.168.1.226和192.168.1.227上配置docker

192.168.1.226

docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=ens160 andy
docker network create -d macvlan --subnet=192.168.11.0/24 --gateway=192.168.11.1 -o parent=ens160 tom


十五 docker图形化界面管理工具之portainer

1. 启动portainer容器

[root@andy ~]# docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true --name keshihua portainer/portainer

[root@andy ~]# docker port keshihua
9000/tcp -> 0.0.0.0:8088


2. 登录portainer web界面

在这里插入图片描述

十五 docker服务端开启端口提供外部访问

15.1 服务端开启端口的操作步骤

  1. 编辑daemon.json文件,加入以下内容
    在这里插入图片描述

  2. reload配置并重启docker
    在这里插入图片描述3. 查看2375端口启动成功
    在这里插入图片描述

15.2 在其他docker机器上用docker -H ip地址来访问

十五 镜像的分层结构

15.1 分层结构

  1. 容器使用宿主机的bootfs Kernel
  2. 不同的操作系统镜像在镜像最底层有各自的rootfs即目录结构
  3. 镜像各层的冷数据无法修改
  4. 容器中的热数据在容器关闭后丢失
    在这里插入图片描述

15.2 容器中数据的读取和处理

  1. 容器读取数据时如果有几个镜像层都有该数据,会读取上层镜像层的数据
  2. 容器层对读取到容器层的数据的删,改,增都不会影响镜像层数据
    在这里插入图片描述

十六 docker machine

16.1 docker machine的作用

在一台docker宿主机上通过安装docker machine来使他能操控其他linux主机来安装docker并操作其上的docker

16.2 安装docker machine

  1. 从https://github.com/docker/machine/releases/download 下载docker machine
curl -L https://github.com/docker/machine/releases/download/v0.16.0/docker-machine-$(uname -s)-$(uname -m) >/tmp/docker-machine

或者自动安装:

base=https://github.com/docker/machine/releases/download/v0.16.1 &&
  curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/tmp/docker-machine &&
  sudo install /tmp/docker-machine /usr/local/bin/docker-machine

在这里插入图片描述
2. 给下载的文件添加可执行权限
在这里插入图片描述
3. 将下载的程序放到/usr/local/bin目录下
在这里插入图片描述
4. 验证docker machine安装成功
在这里插入图片描述

16.3 下载bash completion scripts

  1. bash completion scripts提供了在shell提示符中显示活动计算机名,使用子命令来切换活动机器等功能

  2. 确认docker machine的版本,并下载相应版本的脚本(docker-machine-prompt.bash 和 docker-machine-wrapper.bash 和 docker-machine.bash)到/etc/bash_completion.d 或 /usr/local/etc/bash_completion.d

下载这三个脚本的命令如下:

base=https://raw.githubusercontent.com/docker/machine/v0.16.0
for i in docker-machine-prompt.bash docker-machine-wrapper.bash docker-machine.bash
do
  sudo wget "$base/contrib/completion/bash/${i}" -P /etc/bash_completion.d
done

在这里插入图片描述
或者离线安装:

从https://github.com/docker/machine/tree/v0.16.1/contrib/completion/bash(对应版本号)下载以下三个脚本文件,然后拷贝到/etc/bash_completion.d目录下。

    docker-machine-prompt.bash
    docker-machine-wrapper.bash
    docker-machine.bash

16.4 加载docker-machine-prompt.bash

在这里插入图片描述

16.5 启用docker-machine的shell提示

添加 $(__docker_machine_ps1)到PS1设置中~/.bashrc

vim ~/.bashrc,添加以下内容。

PS1='[\u@\h \W$(__docker_machine_ps1)]\$ '

16.6 安装docker-machine的服务器要控制其他linux的docker安装需要配置免密ssh访问这台linux

配置免密登录步骤:
192.168.1.223安装了docker-machine,需要配置免密登录192.168.1.228来操控docker

  1. 在223上生成自己的一对公、私钥
    ssh-keygen -t rsa
    在这里插入图片描述在这里插入图片描述

  2. 把自己的公钥给228的root用户
    ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.1.228
    在这里插入图片描述

  3. 免秘钥登录
    在这里插入图片描述

  4. 免秘钥登录原理
    在这里插入图片描述

16.7 在linux主机上安装docker

  1. 创建docker host(在主机上安装docker)

docker-machine create --driver generic --generic-ip-address=192.168.1.228 andy1
在这里插入图片描述

  1. 查看docker client
    在这里插入图片描述

16.8 查看machine的环境变量

  1. 查看docker client andy1的环境变量

在这里插入图片描述

  1. 操作andy1

十七 docker 的监控

17.1 docker container top 容器名

用来查看一个容器中的进程

在这里插入图片描述

17.2 docker container stats

查看宿主机中所有容器的cpu,内存,网络使用情况
在这里插入图片描述

17.3 sysdig

  1. 下载sysdig镜像
[root@andy1 ~]# docker pull sysdig/sysdig
  1. 运行sysdig容器
[root@andy1 ~]# docker container run -it --name sysdig --privileged=true --volume=/var/run/docker.sock:/host/var/run/docker.sock --volume=/dev:/host/dev --volume=/proc:/host/proc:ro --volume=/boot:/host/boot:ro --volume=/lib/modules:/host/lib/modules:ro --volume=/usr:/host/usr:ro sysdig/sysdig

在这里插入图片描述

  1. 进入容器并执行csysdig来监控
docker container exec -it sysdig bash

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

17.4 Cadvisor

我们可以使用多种方法监控容器的运行情况,比如EFK等,但是我们仍旧需要一个资源利用率监控系统。这个时候,google开发的cadvisor就可以帮上我们的忙了。

  1. 安装Cadvisor
[root@andy1 ~]# docker run --volume=/:/rootfs:ro --volume=/var/run:/var/run:rw --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker:ro --publish=8089:8080 --detach=true --name=cadvisor google/cadvisor:latest

在这里插入图片描述

  1. 使用

在这里插入图片描述

十八 Compose

18.1 安装

[root@andy1 ~]# curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
[root@andy1 ~]# chmod +x /usr/local/bin/docker-compose 
[root@andy1 ~]# docker-compose --version
docker-compose version 1.26.2, build eefe0d31

18.2 基本操作流程

  1. 建立项目目录
    在这里插入图片描述
  2. 向目录中放入app.py和requirements.txt
    在这里插入图片描述
    在这里插入图片描述
  3. 建立Dockerfile
    在这里插入图片描述
  4. 建立compose file并在里面定义服务
    在这里插入图片描述
  5. 在项目目录中用命令docker-compose up建立并运行各个服务

18.3 docker-compse基本命令

  1. docker-compose up 建立并运行compose文件中定义的所有服务

  2. docker-compose up -d建立并后台运行各个服务

  3. docker-compose up web 只建立和运行compose文件中服务名为web的服务

  4. 用命令docker-compose down停止各个服务并删除容器

  5. 用命令CTRL+C停止各个服务,但不删除容器

  6. 用命令docker-compose stop停止各个服务,但不删除容器

  7. 用命令docker-compose down --volumes停止各个服务并删除容器并删除数据卷

  8. 登录到已经运行的服务中并执行命令
    登录到web服务,并运行命令python
    docker-compose exec web python

18.4 compose file-docker-compose.yaml

  1. compose file有三层:版本;服务;其他配置
    在这里插入图片描述
  2. compose文件中的version要和docker 引擎的版本匹配
  3. build
    用Dockerfile文件来build一个镜像,并run成一个容器
build                 # 指定包含构建上下文的路径, 或作为一个对象,该对象具有 context 和指定的 dockerfile 文件以及 args 参数值
    context               # context: 指定 Dockerfile 文件所在的路径
    dockerfile            # dockerfile: 指定 context 指定的目录下面的 Dockerfile 的名称(默认为 Dockerfile)
    args                  # args: Dockerfile 在 build 过程中需要的参数 (等同于 docker container build --build-arg 的作用)
    cache_from            # v3.2中新增的参数, 指定缓存的镜像列表 (等同于 docker container build --cache_from 的作用)
    labels                # v3.3中新增的参数, 设置镜像的元数据 (等同于 docker container build --labels 的作用)
    shm_size              # v3.5中新增的参数, 设置容器 /dev/shm 分区的大小 (等同于 docker container build --shm-size 的作用)
dockerfile为/root/test123

在这里插入图片描述

dockerfile在compose项目目录下并且文件名为Dockerfile

在这里插入图片描述

dockerfile是当前目录下的dir目录中的Dockerfile-alternate

在这里插入图片描述

build参数中的args参数是定义build时使用的环境变量的,有两种方式定义:mapping和list

在这里插入图片描述

build参数中的network参数是定义在build镜像时dockerfile文件中RUN命令运行时用的网络

在这里插入图片描述

  1. command
command               # 覆盖容器启动后默认执行的命令, 支持 shell 格式和 [] 格式

在这里插入图片描述

  1. container_name
container_name        # 指定容器的名称 (等同于 docker run --name 的作用)

在这里插入图片描述

  1. depends_on

depends_on # 定义容器启动顺序 (此选项解决了容器之间的依赖关系, 此选项在 v3 版本中 使用 swarm 部署时将忽略该选项)
示例:
docker-compose up 以依赖顺序启动服务,下面例子中 redis 和 db 服务在 web 启动前启动
默认情况下使用 docker-compose up web 这样的方式启动 web 服务时,也会启动 redis 和 db 两个服务,因为在配置文件中定义了依赖关系

    version: '3'
    services:
        web:
            build: .
            depends_on:
                - db      
                - redis  
        redis:
            image: redis
        db:
            image: postgres   
  1. networks
将容器加入指定网络 (等同于 docker network connect 的作用), networks 可以位于 compose 文件顶级键和 services 键的二级键

在这里插入图片描述

  1. volumes
volumes               # 定义容器和宿主机的卷映射关系, 其和 networks 一样可以位于 services 键的二级键和 compose 顶级键, 如果需要跨服务间使用则在顶级键定义, 在 services 中引用
    SHORT 语法格式示例:
        volumes:
            - /var/lib/mysql                # 映射容器内的 /var/lib/mysql 到宿主机的一个随机目录中
            - /opt/data:/var/lib/mysql      # 映射容器内的 /var/lib/mysql 到宿主机的 /opt/data
            - ./cache:/tmp/cache            # 映射容器内的 /var/lib/mysql 到宿主机 compose 文件所在的位置
            - ~/configs:/etc/configs/:ro    # 映射容器宿主机的目录到容器中去, 权限只读
            - datavolume:/var/lib/mysql     # datavolume 为 volumes 顶级键定义的目录, 在此处直接调用

    LONG 语法格式示例:(v3.2 新增的语法格式)
        version: "3.2"
        services:
            web:
                image: nginx:alpine
                ports:
                    - "80:80"
                volumes:
                    - type: volume                  # mount 的类型, 必须是 bind、volume 或 tmpfs
                        source: mydata              # 宿主机目录
                        target: /data               # 容器目录
                        volume:                     # 配置额外的选项, 其 key 必须和 type 的值相同
                            nocopy: true                # volume 额外的选项, 在创建卷时禁用从容器复制数据
                    - type: bind                    # volume 模式只指定容器路径即可, 宿主机路径随机生成; bind 需要指定容器和数据机的映射路径
                        source: ./static
                        target: /opt/app/static
                        read_only: true             # 设置文件系统为只读文件系统
        volumes:
            mydata:                                 # 定义在 volume, 可在所有服务中调用

18.5 compse中设置环境变量

  1. 使用shell中的环境变量
    用${变量名}
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  2. 把环境变量的定义都写到项目目录下的.env文件中,会被自动读取

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 用–env-file参数指定其他任意目录下的任意文件名的环境变量文件

在这里插入图片描述
在这里插入图片描述

18.4 在compost 文件中用关键字environment给某个容器定义环境变量,相当于docker run -e VARIABLE=VALUE …

在这里插入图片描述

在这里插入图片描述

18.5 在compost 文件中用关键字environment给某个容器定义环境变量文件,相当于docker run --env-file=FILE …在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值