Docker常用知识记录

Docker—镜像和容器

  • 好记性不如烂笔头

关于Docker Image

  • docker image类似于层状结构,其底层基于Linux Kernel构造。

  • 每一个镜像包括着Linux内核和基础的 Centos/Ubuntu 镜像,在其上层可构建自定义镜像

  • 我们可以把每一个镜像看作成一台拥有了我们定制内容的 Linux 服务器

镜像获取及镜像加速器设置

  • 我们可以从docker镜像仓库源中去拉取镜像到我们本地机器进行使用
    • 镜像仓库源 类似 maven 仓库的概念
    • 通过 docker search 命令可以查找docker仓库中的镜像
    • 我们可以自己设置我们自己的镜像仓库源
vi /etc/docker/daemon.json
{
    
    
   "registry-mirrors": ["http://hub-mirror.c.163.com"]
}

or

{
    
    
   "registry-mirrors": ["https//orptaaqe.mirror.aliyuncs.com"]
}
# 重启docker服务  or  重启docker
systemctl restart docker.service
#  国内仓库镜像加速地址
	# Docker中国区官方镜像
https://registry.docker-cn.com
	# 网易镜像源
http://hub-mirror.c.163.com
  # 中国科技大学
https://docker.mirrors.ustc.edu.cn
	# 阿里云容器服务
https://cr.console.aliyun.com/

同样也可以通过Dockerfile自己去构建镜像

Dockerfile镜像制作

  • docker提供Dockerfile文件用来构建镜像

Dockerfile语法

# FROM  指定基础镜像
	# 例如指定ubuntu:14.04作为基础镜像
FROM ubuntu:14.04

# RUN  在镜像内部执行一些命令,例如:安装软件、配置环境、安装相关命令等等
RUN groupadd -r mysql && useradd -r -g mysql mysql

# ENV  设置变量的值,如下。可以通过 docker run --e key=value进行修改,可以使用  ${MYSQL_MAJOR} 来取值
ENV MYSQL_MAJOR 5.7

# LABEL  设置镜像标签
LABEL email="[email protected]" version="1.0"
LABEL name="zh2020yy"

# VOLUME   指定数据的挂载目录,改变外部文件夹的内容,会影响到容器内文件夹
VOLUME /var/lib/mysql

# COPY 将主机的文件复制到镜像内,如果目录不存在,会自动创建所需要的目录,注意只是复制,不会提取和解压
COPY demo.sh /usr/local/bin/

# ADD 将主机的文件复制到镜像内,和COPY类似,ADD命令会对压缩文件进行提取和解压
ADD demo.zip /etc/zh/

# WORKDIR  指定镜像的工作目录,之后的命令都是基于此目录工作,若不存在则创建
	# 这几个命令的意思是创建 /usr/local/tomcat  文件夹,接下来的命令在该目录下执行
WORKDIR /usr/local
WORKDIR tomcat
RUN touch test.txt

# CMD 容器启动的时候会执行的命令,若有多个CMD命令,则最后一个生效
CMD mysqld

# ENTRYPOINT  和CMD的使用类似
  #  和CMD命令不同的是,docker run执行时,会覆盖CMD的命令,而ENTRYPOINT不会被覆盖
ENTRYPOINT ["demo.sh"]

# EXPOSE  指定镜像要暴露的端口,启动镜像时,可以使用  -p  将该端口映射给宿主机
EXPOSE 3306

自己制作一个镜像

  • 首先自己准备一个Java jar包,上传到服务器的指定位置

  • 创建Dockerfile文件

  • 编写Dockerfile文件

    • MAINTAINER:设置镜像所有者
FROM openjdk:8
MAINTAINER zh2020
LABEL name="dockerfile-demo" version="1.0" author="zh2020"
COPY spring_boot_docker-0.0.1-SNAPSHOT.jar dockerfileEx.jar
#  启动容器后执行的命令
CMD ["java", "-jar", "dockerfileEx.jar"]
  • 基于Dockerfile构建镜像
docker build -t my-docker-image .
  • 构建成功,得到新的镜像

  • 基于镜像创建container

docker run -d --name zh -p 6666:8080 imageID
  • 通过 localhost:6666 进行访问,验证

镜像相关操作

#  删除所有镜像
docker rmi -f $(docker image ls)
#  通过 容器创建镜像,假设我们有一个容器名字叫做   containerA
docker commit containerA newImageName

镜像推送

  • 镜像仓库源中有许多镜像,我们也可以把自己创建的镜像推送到镜像仓库中去
  • 这里以docker官方仓库为例 https://hub.docker.com/ (也可以是阿里云or自己搭建的云服务器)
  • 首先进行注册、登录。拥有自己的账户
  • 登录docker官方仓库,并创建自己的仓库。仓库创建完成之后会拥有属于自己的仓库名称,假如仓库名称是 myrepo 账户名称是 account
  • 那么镜像推送的步骤为
# 首先进行登录
docker login --username=https://hub.docker.com/
# 输入用户名和密码 ,假设推送的镜像id为   a1b2c3
# 通过docker tag  给镜像打上标签  这里 v1  表示镜像的标签
docker tag a1b2c3 account/myrepo:v1
# 然后进行push
docker push account/myrepo:v1

Docker harbor

  • 同理,类似于maven私服。docker提供搭建docker harbor的方式,可作为私服使用。
#  首先从  github  上下载  harbor项目,选择合适的版本
https://github.com/goharbor/harbor/releases
#  在一台安装了  docker-compose 的机器,上传并解压
tar -zxvf xxx.tar.gz
#  解压完成之后,进入到 harbor 目录,修改 harbor.cfg 文件,主要修改 IP 地址为当前机器的 IP 地址,同时可以修改 harbor 密码

#  安装  harbor
sh install.sh
#  最后浏览器访问 IP,输入用户名和密码即可

关于Docker container

  • 通过 docker run 的方式运行 image,来创建容器

container资源限制

  • 运行中的container会占用物理资源
  • 可以通过 docker stats 来查看资源情况
  • 同样可以使用 docker 自由的内存资源限制命令,如下

内存限制

#  --memory     限制容器使用内存大小为 100M
docker run -d --memory 100M --name containerName imageID

CPU限制

#  --cpu--shares  权重,如下,这里配置权重为10
docker run -d --cpu--shares 10 --name containerName imageID 

图形化资源监控

  • 通过weaveworks scope可以更直观地对 docker 容器资源进行监控
    • https://github.com/weaveworks/scope
sudo curl -L git.io/scope -o /usr/local/bin/scope
sudo chmod a+x /usr/local/bin/scope
scope launch ip

#  停止 scope
scope stop

container常见操作

#  删除所有的 container
docker rm -f $(docker ps -a)
#  进入一个容器当中
docker exec -it containerID  bash
#  查看  container 日志
docker logs containerID 
#  查看容器详情信息
docker inspect containerID
#  停止启动容器
docker stop/start containerID 

网卡与Docker

相关预备知识

  • 网络相关认识——Configure networking
  • 计算机网络七层模型
    • 高级层、传输层、基础层
  • 计算机之间数据通信,数据包通过装包、拆包
    • 每一个计算机中拥有网卡,通过网卡建立通信
    • docker中的网络,网卡信息
    • 通过ipconfig可查看网卡信息
  • 网卡的定义
    • 计算机网络中,计算机中要能够进行通信的硬件支撑
    • 每一个网卡会有特定唯一的Mac地址
  • 通过命令行查看机器网卡的方式
#  以文件的形式去查看机器的网卡
ls /sys/class/net
#  查看机器网卡
ip a
ip link show

ip a解读

  • link/ether:MAC地址
  • inet:绑定的IP地址

网卡即配置文件

  • 在Linux中网卡对应的就是文件,通过一下方式可以查找到对应的网卡文件
cat /etc/sysconfig/network-scripts/ifcfg-eth0
  • 可以通过修改 ifcfg 文件的形式给网卡 添加/删除 IP地址
ip addr add 192.168.0.100/24 dev eth0
ip addr delete 192.168.0.100/24 dev eth0

网卡的启动与关闭

  • 重启网卡
service network restart
systemctl restart network
  • 启动或关闭某个网卡
ifup/ifdown eth0 or ip link set eth0 up/down

Network Namespace

  • 在Linux中,网络的隔离是通过 network namespace 来管理的。不同的 network namespace 互相隔离

查看当前机器上的network namespace

# 查看
ip netns list
# 添加
ip netns add nsl
# 删除
ip netns delete nsl

创建一个namespace

# 1.创建一个network namespace   nsl
ip netns add nsl
# 2.查看该 namespace 下的网卡情况
ip netns exec nsl ip a
# 3.启动nsl上的网卡
ip netns exec nsl ifup lo
or
ip netns exec nsl ip link set lo up
# 4.再次查看进行验证   发现state 变成了 UNKOWN
ip netns exec nsl ip a
# 5.再次创建一个network namespace
ip netns add ns2
# 6.现在想让两个namespace网络联通起来,两个namespace在本地拥有各自的网卡。网卡是网络通信的基石
	#为了两个  ns  彼此能够通信,为每个 ns 分别配置网卡和IP
  #  通过  veth pair:  Virtual Ethernet Pair 技术创建网卡
  #  创建出来的网卡能够彼此联通,网卡创建完成之后,分别派给  ns
# 7.创建一对  link  ,也就是接下来通过  veth pair 技术连接的link
ip link add veth-ns1 type veth peer name veth-ns2
# 8.查看  link  的情况
ip link
# 9. 将  veth-ns1   加入  ns1中,  veth-ns2加入ns2中
ip link set veth-ns1 netns ns1
ip link set veth-ns2 netns ns2
# 10.查看 宿主机 和 ns1、ns2的link情况
ip link
ip netns exec ns1 ip link
ip netns exec ns2 ip link
# 11.此时 veth-ns1和veth-ns2还没有IP地址,通信仍然缺少必要条件
ip netns exec ns1 ip addr add 192.168.0.11/24 dev veth-ns1
ip netns exec ns2 ip addr add 192.168.0.12/24 dev veth-ns2
# 12.再次查看,发现 state 是 DOWN ,仍然没有IP地址
ip netns exec ns1 ip link
ip netns exec ns2 ip link
# 13.启动  veth-ns1  和  veth-ns2
ip netns exec ns1 ip link set veth-ns1 up
ip netns exec ns2 ip link set veth-ns2 up
# 14.再次查看,发现  state 是 UP  ,同时有  IP
ip netns exec ns1 ip a
ip netns exec ns2 ip a
# 15.此时两个  network namespace 互相  ping 一下,发现可以进行  ping 通
ip netns exec ns1 ping 192.169.0.12
ip netns exec ns2 ping 192.168.0.11

Docker和网卡

  • 每一个container对应一个 network namespace 并且是独立的
  • 当我们创建多个容器之后,容器之间是能够互相 ping 通的。这里是如何进行 ping 通的呢?

container网络-Bridge

# 查看宿主机 网络  
ip a 
# 查看容器网络   
docker exec -it containerName ip a
  • 在宿主机中 ping 一下容器的网络,可以发现能够ping通
  • 由此可以推测,在container中有一个 eth0 和 centos 的 docker0 中的一个 veth3 是成对的。类似于 之前安装的 veth-ns1和veth-ns2
# 命令确认  brctl
yum install bridge-utils
brctl show
  • 通过测试,发现容器与容器之间也能够ping通
  • 联通方式如下
    • docker0中有着多个 veth ,每一个对应着一个容器的 veth
    • 这种网络连接方法称之为 Bridge
    • 可以通过命令查看docker中的网络模式
#  Bridge也是docker中默认的网络模式
docker network ls
#  检查  Bridge
docker network inspect bridge

在容器中是可以访问互联网的

  • 容器通过docker0种配对的 veth 以 NAT的方式进行网络地址的转换
  • NAT 通过 iptables 来实现的

创建自定义network

# 1.创建一个  network   类型为 bridge
docker network create demo-bri
or 
docker network create --subnet=172.18.0.0/24 demo-bri
# 2.查看已有的 network
docker network ls
# 3.查看  demo-bri 详情信息
docker network inspect demo-bri
# 4. 创建新的容器,并指定使用的  network
docker run -d --name container-name --network demo-bri imageID
# 5. 查看 container-name  的网络信息
docker exec -it container-name ip a
# 6. 查看网卡信息
ip a
# 7. 查看网卡接口
brctl show
# 8. 此时使用不同 network 的容器,无法  ping  通 
docker exec -it network1 ping network2-ip
# 9. 使用 connect  进行连接
docker network connect demo-bri network1-container
# 10. 此时查看  demo-bri  网络,能够发现  network1-container 也在其中
# 11. 此时,进入到  network1-container 中,不仅可以通过  ip ping通,而且可以通过名字  ping  通,因为都连接到了自定义的  bridge  上

Container网络-HOST & NONE

Host模式

#  1.  创建一个 容器,名字为  demo-host   并且指定网络为  host
docker run -d --name demo-host --network host imageID
#  2.  此时查看IP地址,可以发现和宿主机是一样的
docker exec -it demo-host ip a

None模式

#  1.  创建一个容器,名字为   demo-none  ,并且指定网络为  none
docker run -d --name demo-none --network none imageID
#  2.  查看IP地址  发现没有IP地址
docker exec -it demo-none ip a

Docker数据持久化

数据持久化的关键在于 Volume 设置

# 查看 volume  可查看目前  docker 容器的  卷  列表
docker volume ls

# 查看 volume 卷详情信息
docker volume inspect volumeID

# volume 使用,   my_volume代表宿主机目录,  /var/lib/mysql代表容器中的目录
docker run *** -v my_volume:/var/lib/mysql ***
  • 值得注意的是,当容器被删除后,创建出的 volume 并不会被删除,而且还可以再次使用

MySQL集群搭建

使用docker搭建mysql数据库集群

#  first of all
#  拉取  pxc  镜像,pxc 镜像是  docker  用来搭建mysql集群的一个成熟的解决方案
docker pull percona/percona-xtradb-cluster:5.7.21

#  创建一个单独的网段给  mysql 数据库集群来使用
docker network create --subnet=ip/port pxc-net
     #    查看详情
     docker network inspect pxc-net
     #    删除
     docker network rm pxc-net
     
     #    删除  volume
     docker volume rm v1
     #    创建  volume
     docker volume create --name volumeName
     
#  运行三个 PXC 容器,搭建 PXC[mysql] 集群
docker run -d -p 3301:3306 -v v1:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=jack123 \
-e CLUSTER_NAME=PXC \
-e XTRABACKUP_PASSWORD=jack123 \
--privileged --name=node1 \
--net=pxc-net --ip 172.18.0.2 pxc

docker run -d -p 3302:3306 -v v2:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=jack123 \
-e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=jack123 \
-e CLUSTER_JOIN=node1 \
--privileged --name=node2 --net=pxc-net --ip 172.18.0.3 pxc

docker run -d -p 3303:3306 -v v3:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=jack123 \
-e CLUSTER_NAME=PXC \
-e XTRABACKUP_PASSWORD=jack123 \
-e CLUSTER_JOIN=node1 \
--privileged --name=node3 --net=pxc-net --ip 172.18.0.4 pxc

#  工具连接测试

数据库集群负载均衡

通过对外暴露一个地址,来合理使用集群数据库服务

#  首先拉取  haproxy  镜像
docker pull haproxy
#  创建 haproxy ,使用 bind mounting 的方式
touch /tmp/haproxy/haproxy.cfg

haproxy.cfg

global 
  #工作目录,这边要和创建容器指定的目录对应 chroot /usr/local/etc/haproxy #日志文件
  log 127.0.0.1 local5 info 
  #守护进程运行
  daemon

defaults
	log global
	mode   http
	#日志格式
	option httplog 
	#日志中不记录负载均衡的心跳检测记录 
	option dontlognull 
	#连接超时(毫秒)
	timeout connect 5000 
	#客户端超时(毫秒) 
	timeout client 50000 
	#服务器超时(毫秒) 
	timeout server 50000
	#监控界面
	listen admin_stats
	#监控界面的访问的IP和端口
	bind 0.0.0.0:8888
	#访问协议
	mode http
	#URI相对地址
	stats uri  /dbs_monitor
	#统计报告格式
	stats realm Global\ statistics
	#登陆帐户信息
	stats auth admin:admin
	#数据库负载均衡
  listen proxy-mysql 
  #访问的IP和端口,haproxy开发的端口为3306 
  #假如有人访问haproxy的3306端口,则将请求转发给下面的数据库实例 
  bind 0.0.0.0:3306
  #网络协议
  mode tcp
  #负载均衡算法(轮询算法)
  #轮询算法:roundrobin
  #权重算法:static-rr
  #最少连接算法:leastconn
	#请求源IP算法:source
	balance roundrobin
	#日志格式
	option tcplog 
	#在MySQL中创建一个没有权限的haproxy用户,密码为空。
	#Haproxy使用这个账户对MySQL数据库心跳检测
	option mysql-check user haproxy
	server MySQL_1 172.18.0.2:3306 check weight 1 maxconn 2000 
	server MySQL_2 172.18.0.3:3306 check weight 1 maxconn 2000 
	server MySQL_3 172.18.0.4:3306 check weight 1 maxconn 2000 
	#使用keepalive检测死链
  option tcpka

创建 haproxy 容器

docker run -it -d -p 8888:8888 -p 3306:3306 -v /tmp/haproxy:/usr/local/etc/haproxy \
--name haproxy01 --privileged --net=pxc-net haproxy

启动 haproxy

docker exec -it haproxy01 bash haproxy -f /usr/local/etc/haproxy/haproxy.cfg

在MySQL数据库上创建用户,用于心跳检测

CREATE USER 'haproxy'@'%' IDENTIFIED BY ''; [小技巧[如果创建失败,可以先输入一下命令]:
    drop user 'haproxy'@'%';
    flush privileges;
    CREATE USER 'haproxy'@'%' IDENTIFIED BY '';
]

浏览器访问验证

http://centos_ip:8888/dbs_monitor 
# 用户名密码都是:admin

连接 haproxy01

ip:centos_ip
port:3306
user:root
password:123456

猜你喜欢

转载自blog.csdn.net/GoNewWay/article/details/109081007