目录
??????????????? 二、配置flannel + etcd
??????? 在我之前的文章里涉及到了很多技术,其中就包含Docker容器,那么今天就来给小伙伴们以Docker为例讲讲容器。
??????? 对于刚入门的小白还不太了解,什么是容器呢?
??????? 容器是一种轻量级虚拟化技术,创建保证某业务可正常运行的必备的应用程序/指令,意思就是容器内部直接跑着你需要的服务,只要容器不会down,你的服务也不会出现异常。
????????容器技术的一个关键概念是隔离。容器利用操作系统级别的虚拟化,使得每个容器都拥有自己的文件系统、网络空间和进程空间,从而保持相对独立。这使得容器能够在同一主机上并行运行,而互不干扰。
????????? Docker 是目前最流行的容器化平台之一,它使得开发者能够更轻松地打包、交付和运行应用程序。容器技术在构建、部署和扩展应用程序方面提供了更高的灵活性、可移植性和效率,因此受到了广泛的关注和采用。
轻量级: 容器是轻量级的,因为它们共享主机操作系统的内核,避免了虚拟机中的操作系统重复。这使得容器的启动和停止速度更快,占用更少的资源。
可移植性: 容器可以在任何支持容器引擎的环境中运行,无论是在开发者的本地机器上、云平台上还是数据中心中。这种可移植性使得应用程序在不同环境中具有一致的行为。
快速部署: 容器可以快速启动和停止,使得应用程序的部署变得更加迅速和高效。这有助于实现持续集成和持续部署(CI/CD)流程。
隔离性: 容器提供了隔离性,每个容器都有自己的文件系统、网络和进程空间。这使得容器可以在同一主机上并行运行,互不干扰。
可扩展性: 容器可以根据负载需求进行水平扩展,通过在集群中添加或移除容器实例,快速适应变化的工作负载。
版本控制和复制: 容器允许开发者轻松创建、保存和分享容器镜像,这些镜像包含应用程序及其所有依赖项。这有助于确保开发、测试和生产环境之间的一致性。
资源利用率: 由于容器共享主机操作系统内核,它们的资源利用率相对较高,可以在相同硬件上运行更多的应用程序实例。
生态系统: 容器技术有强大的生态系统,包括各种容器编排工具(如Kubernetes)和仓库(如Docker Hub),为开发者提供了丰富的工具和资源。
??????? 因此容器化技术在当前行业中收到了广泛的关注和采用。想要在程序员中获得认可,容器技术是必不可少的。
1、配置docker软件仓库
[root@node01 ~]# cat /etc/yum.repos.d/docker.repo
[docker-ce]
name=docker-ce
baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7.9/x86_64/stable/
enabled=1
gpgcheck=0
2、安装,启动docker-ce
[root@localhost ~]# yum install -y docker-ce
[root@localhost ~]# systemctl start docker
[root@localhost ~]# systemctl enable docker
[root@localhost ~]# docker version
Client: Docker Engine - Community
Version: 20.10.7
API version: 1.41
Go version: go1.13.15
Git commit: f0df350
Built: Wed Jun 2 11:58:10 2021
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.7
API version: 1.41 (minimum version 1.12)
Go version: go1.13.15
Git commit: b0f5bc3
Built: Wed Jun 2 11:56:35 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.4.8
GitCommit: 7eba5930496d9bbe375fdf71603e610ad737d2b2
runc:
Version: 1.0.0
GitCommit: v1.0.0-0-g84113ee
docker-init:
Version: 0.19.0
GitCommit: de40ad0
3、查看主机网络环境的变化
[root@localhost ~]# cat /proc/sys/net/ipv4/ip_forward
1
[root@localhost ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
[root@localhost ~]# ifconfig docker0
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:a2ff:fe68:1f28 prefixlen 64 scopeid 0x20<link>
ether 02:42:a2:68:1f:28 txqueuelen 0 (Ethernet)
?1、查看镜像
# docker search <关键字>
# docker pull 镜像名称
[root@localhost ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 08b152afcfae 3 days ago 133MB
mysql latest c60d96bd2b77 3 days ago 514MB
centos latest 300e315adb2f 7 months ago 209MB09
2、创建镜像
[root@localhost ~]# docker run -tid centos ping baidu.com
[root@localhost ~]# docker run -tid centos sleep 10
[root@localhost ~]# docker run -tid centos /bin/bash
[root@localhost ~]# docker run -tid centos ls
[root@localhost ~]# docker run -tid nginx
核心要素:
3、查看容器
[root@localhost ~]# docker ps -a
4、删除容器
[root@localhost ~]# docker rm f296e797464f
[root@localhost ~]# docker stop 8b3d
8b3d
[root@localhost ~]# docker rm 8b3d
[root@localhost ~]# docker ps -qa | awk '{print "docker rm -f", $0}' | bash //批量删除容器
98e5ad206be7
d4969c8a7289
8c87f3bcffe5
902ca926ece7
16c899459118
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5、连接容器
[root@localhost ~]# docker exec -ti 16c8 bash
6、查看容器的详细信息
[root@localhost ~]# docker inspect 8c87
7、查看日志
# docker logs <ID>
8、导出容器
# docker export -o test.tar 8478
9、导入容器
# docker import <file>
1、指定容器的名称
[root@localhost ~]# docker run -tid --name test_demo centos /bin/bash
[root@node01 ~]# docker run -tid --name=test2 --hostname=masterDB centos
2、发布服务
-p 物理机端口:容器端口
-P
[root@localhost ~]# docker run -tid -p 80:80 nginx
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
447257e06d1f nginx "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp sharp_noether
[root@localhost ~]# docker exec -ti 4472 bash
root@447257e06d1f:/#
root@447257e06d1f:/# ls /usr/share/nginx/html/
50x.html index.html
root@447257e06d1f:/# echo "abc" > /usr/share/nginx/html/index.html
root@447257e06d1f:/#
root@447257e06d1f:/# exit
3、设置容器的重启策略
--restart=always
[root@localhost ~]# docker run -tid --restart=always centos /bin/bash
4、资源限制
针对CPU、内存进行限制
默认创建容器时,物理机是不会对容器做资源限制的,如果容器数量过多,导致oom现象,物理机启动oom-killler机制随机杀进程,可能会容器不能正常工作
1) 对CPU进行资源限制
[root@localhost ~]# docker run -tid --cpus=2 centos /bin/bash
[root@test ~]# docker run -tid --cpus=2 polinux/stress /bin/bash
[root@test ~]# docker exec -ti 3722 bash
bash-5.0# stress --cpu 2 --io 4 --vm 2 --vm-bytes 128M --timeout 60s &
在物理机使用top查看CPU使用率
2) 对内存进行资源限制
[root@localhost ~]# docker run -tid --memory=128M polinux/stress /bin/bash
620512838d0f723d310dca8a9801cf67538f97e4b47cdb2b40991c9d60fd405c
[root@test ~]# docker exec -ti 61e7 bash
bash-5.0# stress --vm 10 --vm-bytes 200M --verbose
5、传递变量
-e 变量名称=值
[root@localhost ~]# docker run -tid -e DATA_01=martin centos /bin/bash
222ae6e7cd485ab7d35b21ba1d029b787b284ef8fa9fe74277efd2825299d14b
[root@localhost ~]#
[root@localhost ~]# docker exec -ti 222a bash
[root@222ae6e7cd48 /]#
[root@222ae6e7cd48 /]# echo $DATA_01
martin
[root@222ae6e7cd48 /]# exit
exit
[root@localhost ~]# docker run -tid -e MYSQL_ROOT_PASSWORD="redhat" mysql
[root@localhost ~]# docker run -tid -e MYSQL_ROOT_PASSWORD="redhat" -e MYSQL_DATABASE="jishu" mysql
6、实现容器数据持久化保存
方式一) 将容器目录挂载到物理机目录上
-v 物理机目录:容器目录
[root@localhost ~]# docker run -tid -v /opt/projectA/:/webdata centos /bin/bash
[root@localhost ~]# docker run -tid -e MYSQL_ROOT_PASSWORD="redhat" -v /opt/MySQL/my.cnf:/etc/my.cnf mysql
7、设置容器间的网络别名
[root@localhost ~]# docker run -tid --name demo centos /bin/bash
[root@localhost ~]# docker run -tid --link=demo:test_server centos /bin/bash
?????????? 1、bridge模式:
??????????????????????????????? 属于NAT网络
??????????????????????????????? -p 可以端口映射
??????????????????????????????? 开启路由转发功能,SNAT规则
???????????? 2、host模式:
??????????????????????????????? 容器、物理机共享同一个网络命名空间
??????????????????????????????? 服务器运行在容器中,端口监听在物理机
???????????????????????????????? 注意端口冲突
????????????? 3、container模式:
????????????????????????????????? 新建的容器会与一个已有的容器共享同一个网络命名空间
????????????????????????????????? 前提
???????????????????????????????????????? ????????实现存在一个bridge模式的容器
?????????????????????????????????? 优势
??????????????????????????????????????????????? 减少网络消耗,增加网络通信效率
???????????????????????????????????? 劣势
??????????????????????????????????????????????? 原有的容器故障,所有的容器均失效
????????????? 4、none模式:
??????????????????????????????? 容器不会有任何网络连接(不推荐)
??????? 这四种网络模式都有一个弊端,就是无法实现跨物理机之间相互通信,当然借助一定的技术手段完全可以解决这样的问题,
??????????????????????? ????????作用:
??????????????????????????????????????? 跨物理机的容器相互通信
??????????????????????????????????????? 改变容器分配IP的方式
??????????????????????????????? etcd:
?????????????????????????????????????? 键值对数据库
?????????????????????????????????????? 用来记录网络分配信息
????????????????
???????????????? 1、环境描述
?????????????????????????????? 192.168.140.10?? docker、flannel、etcd
??????????????????????????????? 192.168.140.11? docker、flannel
???????????????? 2、两台服务器分别安装docker
???????????????? 3、安装配置etcd数据库
[root@localhost ~]# yum install -y etcd
[root@test ~]# vim /etc/etcd/etcd.conf
#[Member]
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
#
#[Clustering]
ETCD_ADVERTISE_CLIENT_URLS="http://0.0.0.0:2379"
[root@localhost ~]# systemctl start etcd
[root@localhost ~]# systemctl enable etcd
[root@localhost ~]# netstat -tunlp | grep etcd
tcp 0 0 127.0.0.1:2380 0.0.0.0:* LISTEN 12521/etcd
tcp6 0 0 :::2379 :::* LISTEN 12521/etcd
??????????????? 4、测试etcd数据库工作正常
[root@localhost ~]# etcdctl set file01/name sam
sam
[root@localhost ~]# etcdctl get file01/name
sam
??????????????? 5、在两台服务器上安装flannel
[root@localhost ~]# yum install -y flannel
??????????????? 6、编辑flannel配置文件,调参
[root@test ~]# vim /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://192.168.140.10:2379" //写入自己的ip地址和端口号
FLANNEL_ETCD_PREFIX="/atomic.io/network"
????????????????7、在etcd数据库写入flannel网络使用的网段信息
[root@localhost ~]# etcdctl mk /atomic.io/network/config '{"Network":"10.2.0.0/16"}'
{"Network":"10.2.0.0/16"}
????????????????8、启动flanneld
[root@localhost ~]# systemctl start flanneld
[root@localhost ~]# systemctl enable flanneld
[root@localhost ~]# ifconfig flannel0
flannel0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1472
inet 10.2.45.0 netmask 255.255.0.0 destination 10.2.45.0
inet6 fe80::1f96:1da1:2a1b:3771 prefixlen 64 scopeid 0x20<link>
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 500 (UNSPEC)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3 bytes 144 (144.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@localhost ~]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=10.2.0.0/16
FLANNEL_SUBNET=10.2.45.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false
[root@localhost ~]# cat /run/flannel/docker
DOCKER_OPT_BIP="--bip=10.2.45.1/24"
DOCKER_OPT_IPMASQ="--ip-masq=true"
DOCKER_OPT_MTU="--mtu=1472"
DOCKER_NETWORK_OPTIONS=" --bip=10.2.45.1/24 --ip-masq=true --mtu=1472"
????????????????9、修改docker启动脚本,重启docker
[root@test ~]# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock $DOCKER_NETWORK_OPTIONS
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
[root@localhost ~]# ifconfig docker0
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 10.2.45.1 netmask 255.255.255.0 broadcast 10.2.45.255
ether 02:42:38:a6:0c:c2 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
????????????????10、第二台服务参考上述配置flannel
[root@localhost ~]# ifconfig docker0
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 10.2.64.1 netmask 255.255.255.0 broadcast 10.2.64.255
ether 02:42:87:e8:70:b7 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
????????????????11、两台服务器创建容器、测试通信,通信成功,flannel网络搭建完成
[root@localhost ~]# iptables -P FORWARD ACCEPT
[root@8478dd5602e7 /]# ping 10.2.64.2
PING 10.2.64.2 (10.2.64.2) 56(84) bytes of data.
64 bytes from 10.2.64.2: icmp_seq=88 ttl=60 time=1.02 ms
64 bytes from 10.2.64.2: icmp_seq=89 ttl=60 time=0.719 ms
64 bytes from 10.2.64.2: icmp_seq=90 ttl=60 time=0.984 ms
64 bytes from 10.2.64.2: icmp_seq=91 ttl=60 time=0.694 ms
分层的文件系统
只读的
基于镜像创建容器时,镜像最上面会添加一个可写层
核心技术:
COW机制 Copy On Write 写时复制
创建容器时,镜像会在最上层添加一个读写层,只有修改文件时,该才会被复制到读写层进行修改
容器删除时,读写层会随之删除,所有容器对关键数据进行持久化存储
Union fs 联合文件系统
支持将多个不同的文件系统挂载到同一个虚拟文件系统中
overlay2
[root@localhost ~]# docker info
Client:
Context: default
Debug Mode: false
Plugins:
app: Docker App (Docker Inc., v0.9.1-beta3)
buildx: Build with BuildKit (Docker Inc., v0.5.1-docker)
scan: Docker Scan (Docker Inc., v0.8.0)
Server:
Containers: 1
Running: 1
Paused: 0
Stopped: 0
Images: 9
Server Version: 20.10.7
Storage Driver: overlay2
1、镜像命名格式
仓库名称/镜像名称[:标记]
标记tag默认是latest
test.linux.com/tomcat:8.9
polinux/stress
nginx
hub.docker.com/nginx:latest
2、下载、查看镜像
[root@localhost ~]# docker pull mysql:5.6
[root@localhost ~]# docker image ls
3、导出镜像
[root@localhost ~]# docker save -o MySQL56.tar mysql:5.6
4、导入镜像
[root@localhost ~]# docker load -i MySQL56.tar
5、删除镜像
# docker rmi mysql:5.6
6、查看镜像的详细信息
[root@localhost ~]# docker image inspect haproxy:latest
1) 规划目录
[root@localhost ~]# mkdir demoDockerFile
2) 编写Dockerfile
[root@localhost ~]# cd demoDockerFile/
[root@localhost demoDockerFile]# vim Dockerfile
FROM centos:latest
RUN yum install -y net-tools
3) 构建镜像
[root@localhost demoDockerFile]# docker build -t centos:v1 ./
1) FROM指令
指定基础镜像,基础镜像不存在,自动联网下载
FROM <基础镜像名称>
2) MAINTAINER指令
MAINTAINER <user> <email>
指定镜像的作者, 可以使用docker image inspect查看
3) RUN指令
执行定制的操作,RUN指定的命令在基础镜像中得事先存在
RUN cmd1 && cmd2 && cmd3
4) CMD指令
指定创建容器时,自动执行的命令
CMD /usr/sbin/httpd -D FOREGROUND
CMD [ "/usr/sbin/httpd", "-D", "FOREGROUND" ]
5) ENTRYPOINT指令
指定创建容器时,自动执行的命令
创建容器时指定的命令不会覆盖ENTRYPOINT指令的命令
ENTRYPOINT /usr/sbin/httpd -D FOREGROUND
ENTRYPOINT [ "/usr/sbin/httpd", "-D", "FOREGROUND" ]
6)COPY指令
拷贝本地文件、目录
源文件以相对路径的方式写
COPY <源文件> <目的文件>
7) ADD指令
拷贝文件、目录
源文件可以是本地文件、URL地址
源文件是压缩包,相当于自动解压缩
ADD file01.txt /tmp/file01.txt
ADD http://nginx.org/download/nginx-1.21.1.tar.gz /tmp
8) EXPOSE指令
说明容器要发布的服务端口
EXPOSE 80
配置-p选项、-P选项真正发布服务
-P 随机发布端口
[root@localhost testDockerFile]# docker run -tid -P centos:v7
9) VOLUME指令
指定持久化存储的目录
VOLUME /webdata
创建容器时,自动生成匿名卷进行持久化
[root@localhost testDockerFile]# docker inspect 96f0 | grep -i volume
10) ENV指令
在容器中定义环境变量
ENV 变量名称 值
11) WORKDIR指令
指定容器的当前目录
WORKDIR <目录名称>
12) USER指令
指定容器当前用户
USER <用户名>
案例1: 定制nginx镜像
FROM centos:latest
MAINTAINER Martin
ADD nginx-1.14.2.tar.gz /tmp
RUN yum install -y gcc openssl-devel pcre-devel zlib-devel make
RUN cd /tmp/nginx-1.14.2 \
&& ./configure --prefix=/usr/local/nginx \
&& make \
&& make install
EXPOSE 80
RUN rm -rf /tmp/nginx*
ENTRYPOINT /usr/local/nginx/sbin/nginx -g "daemon off;"
小结:
??????? 以上就是对docker容器的部署以及管理操作,小伙伴们可以考虑如果有上百台甚至上千台容器,需要同意管理,怎么办?
??????? 关注博主,下期会更新如何批量操作容器。