目录
Linux普通用户操作时,省去sudo命令前缀的书写(加入docker用户组)
4.docker的容器(Container)之间是如何实现通信的?
5.docker的容器(Container)如何与外网(Internet)进行通信?
9.通过搭建etcd集群实现两台机器上的docker进行通信
第一种方式:通过指定volume的名称与存储位置(以mysql容器为例)
第二种方式:通过bind mount映射主机与容器的数据目录(以nginx为例)
11.Docker Compose的使用(未完成容器调用的记录)
安装docker-composer(https://github.com/docker/compose/releases)
13.Docker Stack的使用(基于docker swarm)
更新Stack(修改构建Stack的yml文件,重新运行构建命令即可)
17.如何设置容器跟随docker自动启动?(--restart=always)
安装
参考:Install Docker Engine on CentOS | Docker Documentation
a) 移除docker相关旧数据
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 查询系统是否还有残留的docker相关包,有则进行删除
yum list installed|grep docker
# 删除已安装的docker默认目录
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
b) 安装DOCKER REPOSITORY
yum install -y yum-utils
# 指定docker仓库,第一个是docker官方仓库,最好改成阿里云的仓库
# yum-config-manager \
# --add-repo \
# https://download.docker.com/linux/centos/docker-ce.repo
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
c) 安装DOCKER ENGINE
# 安装docker engine,第一种是指定版本进行安装、第二种是安装最后稳定版本
# yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
sudo yum install docker-ce docker-ce-cli containerd.io
d) 启动docker并查看版本测试是否安装成功
# 启动
systemctl start docker
# 配置docker开机自启
systemctl enable docker
# 查看安装的docker版本
docker version
注:如果安装成功,启动失败,报错Failed to start Docker Application Container Engine,则可以先将yum更新成最新版本
# 更新yum源
yum update
# 更新完成后,执行启动,失败则删除原docker再重新安装
Dockerfile语法与实践
FROM
a) FORM scratch 制作base image
b) FROM centos 使用base image
注:尽量使用官方的base image,安全性大大提高;
LABEL
a) Metadata必不可少
b) base image的说明(注释)
RUN
编写执行命令操作并创建新的Image Layer
CMD
设置容器启动后默认执行的命令和参数
ENTRYPOINT
设置容器启动时运行的命令
CMD和ENTRYPOINT的区别
CMD--容器启动时默认执行的命令;ENTRYPOINT--让容器以应用程序或者服务的形式运行
CMD--如果docker run指定了其它命令,CMD命令被忽略;ENTRYPOINT--不会被忽略,一定会执行
CMD--如果定义了多个CMD,只执行最后一个;
WORKDIR
创建并进入目录
a) 使用WORKDIR时,不要用RUN cd
b) 指定目录时,使用绝对目录 WORKDIR /root/test
ADD、COPY
添加本地文件到docker的image中指定目录
a) ADD添加压缩文件(.gz)时,会多出一步解压文件夹的操作;
ENV
设置环境变量
ENV MYSQL_VERSION 5.7
RUN apt-get install -y mysql-server="${MYSQL_VERSION}" && rm -rf /var/lib/apt/list/*
构建Dockerfile的两种方式
1.构建常驻内存的程序
# Dockerfile
FROM python:2.7
LABEL maintainer="east96<xxx@email.com>"
RUN pip install flask
COPY app.py /app/
WORKDIR /app
EXPOSE 5000
CMD ["python", "app.py"]
启用容器
docker run -d -it east96/python-flask
2.构建命令行工具
# Dockerfile
FROM ubuntu
RUN apt-get update && apt-get install -y stress
ENTRYPOINT ["/usr/bin/stress"]
CMD []
启用容器
docker run -it east96/ubuntu-stress --vm 1 --verbose
Image获取的方法
1.构建Dockerfile(Build From Dockerfile)
a) 编写Dockerfile文件
b) 通过docker build进行image构建
# docker build -t 构建image名称 Dockerfile所在路径
docker build -t east96/centos-vim ./
2.从Registry拉取(Pull From Registry)
Linux普通用户操作时,省去sudo命令前缀的书写(加入docker用户组)
# 切换root用户
su root
# 添加docker用户组(已存在)
groupadd docker
# 将普通用户加入docker用户组 gpasswd -a user group
gpasswd -a dong docker
# 重启docker
systemctl restart docker
# 关闭ssh连接重启,输入docker version查看效果,即完成配置
相关快捷使用
1.如何快捷查找命令的使用
# 直接敲docker可查看到Management Commands和Commands
docker
# 根据需要在Management Commands找到对应需要的命令,如docker image可查看到docker image可用的命令
docker image
# 最后根据docker image给出的提示命令找到对应需要的命令,如docker image ls:查找docker的image列表
docker image ls
2.常用命令行
查看docker报错日志
# 1.
dockerd
# 2.查看某个容器报错
docker logs 容器唯一标识
查询所有镜像(image)
# 查询所有镜像(image)
docker image ls
docker images
查询所有容器(container)
# 查询所有容器(container)
docker container ls -a
docker ps -a
运行容器(container)
# 运行容器(container)
docker run -d -p 5000:5000 --net=bridge east96/hello-world
# -d 表示后台运行模式
# -p 表示开放外部访问端口5000,映射内部端口5000
# --net 表示指定网络
启动容器(非启动状态的容器)(container)
# 启动容器(容器状态为非启动)
docker container start containerId1 containerId2 ...
docker start containerId1 containerId2 ...
停止容器(container)
# 停止容器(container)
docker container stop CONTAINERID1 CONTAINERID2 ...
docker stop CONTAINERID1 CONTAINERID2 ...
重启容器(container)
# 重启容器
docker container restart containerId1 containerId2 ...
docker restart containerId1 containerId2 ...
删除容器(container)
# 删除容器(container)
docker container rm CONTAINERID1 CONTAINERID2 ...
docker rm CONTAINERID1 CONTAINERID2 ...
删除所有容器(container)
# 删除所有容器(container)
docker rm $(docker container ls -aq)
删除指定状态的容器(container)
# 获取指定状态的容器(container)
docker container ls -f "status=exited" -q
# 删除获取指定状态的容器(container)
docker rm $(docker container ls -f "status=exited" -q)
查看某个容器的日志(container)
# 查看某个容器的日志(container)
docker container logs CONTAINERID
docker logs CONTAINERID
配置网络网段(network)
docker自带的网段是172.17.0.0
查看网络网段(ls、inspect)
# 查看所有网段
docker network ls
# 查看某个配置的网段信息(NETWORKID或NAME)
docker inspect name
添加网络网段(create)
# 添加(一般根据已有的网段网上加17->18,net1:自定义网段名称)
docker network create --subnet=172.18.0.0/24 net1
#
docker network create -d bridge my-bridge
删除某个网段中的容器信息(disconnect)
注:执行的顺序分两步走,第一步,将容器删除掉(容器已停止);第二步,执行下边的命令将容器从网段中删除
# odemo 网段名称 redis 容器名称
docker network disconnect --force odemo redis
配置docker卷(volume)
docker创建的容器生成的业务数据,通过容器指定docker卷完成数据存储,即把容器生成的业务数据存储在宿主服务器上;
查看docker卷(ls、inspect)
# 查看所有docker卷
docker volume ls
# 查看某个docker卷放置的宿主机目录(VOLUMENAME)
docker volumn inspect volumeName
创建docker卷(create)
# 创建docker卷
docker volumn create pxc
3.如何加速docker pull 拉取镜像
使用阿里云的容器镜像服务->镜像工具->镜像加速服务
4.docker的容器(Container)之间是如何实现通信的?
首先, 验证两个容器的网络与默认网络docker0的连接情况
# 查询主机上所有的网络接口
ip a
# 通过brctl工具,查询网络接口连接情况
yum install bridge-utils
# 查看
brctl show
证明,通过veth接口将两个network namespace(如下图,172.17.0.3与172.17.0.2)与默认的network namespace(如下图,172.17.0.1)进行连接,实现网络通信
5.docker的容器(Container)如何与外网(Internet)进行通信?
容器的network namespce与默认network namespace(docker0)实现了连接,docker0在通过NAT(网络地址转换)将172.17.0.3转换成全球IP地址,实现与外界Internet通信。
6.link参数的使用
作用:创建启用容器时,通过指定容器的标识将容器link起来,当ping或者访问另一个容器时直接过通过容器标识即可完成;
ping网络
未指定容器link的情况:(只能通过ip地址进行容器网络访问,无法直接通过容器标识进行网络访问)
docker run -it busybox /bin/sh
指定容器link 的情况:(可通过ip地址和容器标识进行容器网络访问)
docker run -it --link 4eda6ef47223 busybox /bin/sh
7.port参数的使用 -p 外部端口:容器端口
作用:在创建启用容器时,将容器的端口映射到本地,开放访问容器的端口,使得每个用户都可以通过指定的端口访问容器的服务;
未向外开放端口时(nginx服务为例)
docker run --name web -d nginx
服务器访问:可以访问
外网访问:无法访问
向外开放端口时(nginx服务为例)
docker run --name web -d -p 8080:80 nginx
服务器访问:可以访问
外网访问:可以访问
8.env参数的使用 -e 名称=值
作用:在创建启用容器时,设置容器的环境变量值
# Dockerfile内容
FROM python:2.7
LABEL maintaner=""
COPY . /app
WORKDIR /app
RUN pip install flask redis
EXPOSE 5000
CMD [ "python", "app.py" ]
# 创建容器
docker run -d -e REDIS_HOST=redis east96/flask-redis
# 进入被创建的flask-redis容器
docker exec -it flask-redis /bin/bash
9.通过搭建etcd集群实现两台机器上的docker进行通信
docker节点拉起可能发生的错误
1.在本地环境下,主机名称一致(参考:深入理解Linux修改hostname(原文作者:潇湘隐者)_24号信仰-CSDN博客)
etcd节点拉起可能发生的错误
1.端口号未打开(参考:检测etcd连接状态发生报错)
安装启用etcd
1.下载etcd集成包(演示下载v3.0.12)
# 下载etcd linux集成包,可通过wget或者直接到github进行下载https://github.com/etcd-io/etcd/releases
wget https://github.com/coreos/etcd/releases/download/v3.0.12/etcd-v3.0.12-linux-amd64.tar.gz
2.解压缩并进入文件夹,启用集群节点(以下代表node1与node2)
# 进入集成包所在目录进行解压
tar zxvf etcd-v3.0.12-linux-amd64.tar.gz
# 进入文件夹并进行节点拉起,在此之前,可以先通过命令 ip a 获取本机器的ip地址
cd etcd-v3.0.12-linux-amd64
nohup ./etcd --name docker-node1 --initial-advertise-peer-urls http://192.168.224.3:2380 \
--listen-peer-urls http://192.168.224.3:2380 \
--listen-client-urls http://192.168.224.3:2379,http://127.0.0.1:2379 \
--advertise-client-urls http://192.168.224.3:2379 \
--initial-cluster-token etcd-cluster \
--initial-cluster docker-node1=http://192.168.224.3:2380,docker-node2=http://192.168.224.130:2380 \
--initial-cluster-state new&
# 进入集成包所在目录进行解压
tar zxvf etcd-v3.0.12-linux-amd64.tar.gz
# 进入文件夹并进行节点拉起,在此之前,可以先通过命令 ip a 获取本机器的ip地址
cd etcd-v3.0.12-linux-amd64
nohup ./etcd --name docker-node2 --initial-advertise-peer-urls http://192.168.224.130:2380 \
--listen-peer-urls http://192.168.224.130:2380 \
--listen-client-urls http://192.168.224.130:2379,http://127.0.0.1:2379 \
--advertise-client-urls http://192.168.224.130:2379 \
--initial-cluster-token etcd-cluster \
--initial-cluster docker-node1=http://192.168.224.3:2380,docker-node2=http://192.168.224.130:2380 \
--initial-cluster-state new&
节点启用后,通过命令行进行状态测试
/usr/local/etcd-v3.0.12-linux-amd64/etcdctl cluster-health
3.启动docker/重启docker
节点1
# 尚未启动docker,则无需停止操作
systemctl stop docker
#
/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store=etcd://192.168.224.3:2379 --cluster-advertise=192.168.224.3:2375&
节点2
# 尚未启动docker,则无需停止操作
systemctl stop docker
#
/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store=etcd://192.168.224.130:2379 --cluster-advertise=192.168.224.130:2375&
4.创建overlay网络,使etcd的docker节点能够共享同一个网络
# 创建overlay网络(在主节点)
docker network create -d overlay etcd_cluster
主节点
从节点(集群成功拉起后,etcd会自动为从节点加入overlay网络)
5.测试两个服务器的容器是否可以在overlay网络中通信
注:首先将两台服务器的firewalld-cmd服务暂停,否则在容器之间ping网络无法连通
systemctl stop firewalld.service
节点1服务器
节点2服务器
检测etcd连接状态发生报错
原因:两台机器搭建etcd集群时涉及到的端口需要进行开放。
10.实现数据持久化存储
第一种方式:通过指定volume的名称与存储位置(以mysql容器为例)
1.创建mysql1容器
# 创建mysql容器,指定volume名称与数据存储位置
docker run -d -v mysql:/var/lib/mysql --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
进入mysql容器,创建一个docker数据库,退出容器,删除mysql1容器
# 进入mysql容器
docker exec -it mysql1 /bin/bash
2.创建mysql2容器
docker run -d -v mysql:/var/lib/mysql --name mysql2 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
进入mysql容器,进行数据库列表查询
3.总结,由此可见,通过指定volume的参考可实现容器数据持久化存储
第二种方式:通过bind mount映射主机与容器的数据目录(以nginx为例)
注:开发时可用,通过bind mount将本地项目文件与docker容器的文件进行同步,本地修改后,不需要重启容器即可看到修改的效果
注:以主机指定的目录为主,docker容器目录不存在则自动创建目录,已有数据则会被主机的目录直接覆盖;
Dockerfile内容
# this same shows how we can extend/change an existing official image from Docker Hub
FROM nginx:latest
# highly recommend you always pin versions for anything beyond dev/learn
WORKDIR /usr/share/nginx/html
# change working directory to root of nginx webhost
# using WORKDIR is prefered to using 'RUN cd /some/path'
COPY index.html index.html
# I don't have to specify EXPOSE or CMD because they're in my FROM
构建nginx镜像
# 构建nginx镜像
docker build -t east96/docker-nginx ./
创建nginx容器
# $(pwd) 表示指定当前目录作为与容器web2数据目录的同步目录
docker run -d -v $(pwd):/usr/share/nginx/html -p 82:80 --name web2 east96/docker-nginx
将当前地址的文件与nginx的数据目录进行同步,增删改操作一并同步;
存储在volume与存储在主机(host)目录的区别
参考:Docker学习笔记(6)——Docker Volume - 简书
11.Docker Compose的使用(未完成容器调用的记录)
安装docker-composer(https://github.com/docker/compose/releases)
描述:docker-compose不需要编译安装,下载后进行chmod授权即可使用
第一种方式:命令行下载
# 官网提供,直接curl命令进行下载->授权
curl -L "https://github.com/docker/compose/releases/download/1.29.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --version
第二种 方式:手动下载
# 到github的版本库中找到合适的进行下载,完成后将包移动到/usr/local/bin目录中
# 授权
chmod +x /usr/local/bin/docker-compose
# 测试
docker-compose --version
12.Docker Swarm的使用
描述:自带集群功能,横向扩展节点
需要开放的端口
2377(tcp)、7949(udp),4789(udp)
firewall-cmd --add-port=2377/tcp --permanent
firewall-cmd --add-port=7949/udp --permanent
firewall-cmd --add-port=4789/udp --permanent
firewall-cmd --reload
删除swarm
# 主节点直接删除整个swarm集群
docker swarm leave --force
从节点加入swarm集群的方法
# 在主节点查看从节点加入主节点的命令行
docker swarm join-token worker
查看swarm节点
# 查看swarm节点
docker node ls
从节点启用container(service)的方法
# 先查看原本service的节点数
docker service ls
# 如果是新增的节点,则通过横向扩展,即在原节点数+1皆可;如果是某个节点删除后又进行添加,则将原节点数-1,再进行+1操作,即可实现;
docker service scale whoami=3
原本3个节点,离开一个节点后,节点重新加入(如以下两图,3个容器分配到两个节点上)
节点加入成功,目前此节点并没有容器(如下图)
在主节点将原本三个节点的service缩为2个节点(如下图)
再在主节点将两个节点的service扩展为3个节点,新加入的节点即为被分配到容器(如下图)
部署实例(jwilder/whoami):
1.配置三台机器,设置hostname
2.开放访问端口(8080)
# 开放端口
firewall-cmd --add-port=8000/tcp --permanent
# 生效
firewall-cmd --reload
3.创建访问网络(overlay)
docker network create -d overlay wai
4.创建swarm(一个主节点+N个从节点)
# 设置swarm集群的manage机器,192.168.224.3为本机ip
docker swarm init --advertise-addr 192.168.224.3
# 从节点加入集群
docker swarm join --token SWMTKN-1-20tz0t5fnb3exa4fhsfp7ht5267v64gon911vyhvcot29rqa9w-a2b91xnqkwq3s35k0lwqc93wz 192.168.224.3:2377
查看集群节点
# 查看集群节点
docker node ls
5.创建service
docker service create --name whoami -p 8000:8000 --network wai-d jwilder/whoami
6.横向扩展service,使得集群里每个节点都有whoami容器。注:如果节点没有分配到whoami容器,则无法进行服务访问
# 扩展集群中可启用容器whoami的数量
docker service scale whoami=3
7.访问每个节点,查看效果
8.通过内网进行集群访问测试,查看效果
主节点访问不了节点2,节点1与节点2可访问到所有节点
13.Docker Stack的使用(基于docker swarm)
描述:通过编写stack.yml将多个swarm service进行自定义配置(包含network、container、scale),配置参考(Compose file version 3 reference | Docker Documentation)
创建Stack
# 创建stack,wordpress表示stack名称、--compose-file指定stack的service配置
docker stack deploy wordpress --compose-file=wordpress-stack.yml
# 简化写法
docker stack deploy wordpress -c=wordpress-stack.yml
删除Stack
# 删除stack,wordpress指向实际的stack名
docker stack rm wordpress
更新Stack(修改构建Stack的yml文件,重新运行构建命令即可)
14.docker Secret的使用
描述:管理docker容器服务的相关密码信息
创建secret
第一种方式:通过指定文件名进行密码存储,完成密码存储后将记录密码的文件删除
# 创建password文件,存储密码内容
echo admin123 > password
# 指定文件名,将其内容作为密码进行存储
docker secret create pw1 password
第二种方式:输入字符串进行密码存储
# 输入字符串进行密码存储
echo "admin123" | docker secret create pw2 -
如何设置或查看service的密码
创建service并指定secret
# 创建service并指定secret
docker service create -d --name client --secret pw1 busybox sh "while true;do sleep 3600;done"
查看service创建时设置的secret的值(设置可通过hub.docker.com->搜索mysql->进入容器后,搜索docker secrets参考使用方法)
# 查看运行的service对应容器
docker ps
# 进入容器
docker exec -it 0766 /bin/sh
# 进入/run/secrets目录,查看secret
cd /run/secrets
ls
cat pw1
15.排查本地无法访问docker容器(服务)的原因
1.检查防火墙是否开放了端口
2.检查ip是否被禁用
# 检查IP是否被禁用:0表示禁用、1表示未禁用
sysctl net.ipv4.ip_forward
# 当被禁用时,通过以下命令进行开启
echo 1 > /proc/sys/net/ipv4/ip_forward
# 使配置生效
sysctl -p /etc/sysctl.conf
3.docker swarm是否需要重构
4.到hub.docker.com查看使用容器的使用实例
16.docker资源加速下载(非github)
16.解决启动容器后弹出错误:WARNING: IPv4 forwarding is disabled. Networking will not work.
原因
docker是在vmware虚拟机的centos7中安装,由于暴力关闭导致重启时网络未启动;
解决(几种方法)
1、重启centos;
2、修改系统配置-->重启网络-->重启docker;
追加配置:echo "net.ipv4.ip_forward=1" >>/usr/lib/sysctl.d/00-system.conf
重启网络:systemctl restart network
重启docker:systemctl restart docker
17.如何设置容器跟随docker自动启动?(--restart=always)
注:--restart=always 的位置应该在容器的名称前
docker run -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600/udp --restart=always consul consul agent -dev -client=0.0.0.0
可以通过重启linux进行测试:reboot
18. docker镜像官网
网易云镜像中心:登录