容器化奇迹:打开创新之门,加速业务发展的秘密武器

发布时间:2024年01月11日

目录

一、简介

二、容器的概念

三、容器的优势

部署容器:

四、容器的基本管理操作:

五、创建容器时常用的选项参数

六、容器的网络模式

??????? 通过flannel+etcd实现网络管理

?????????????? 一、flannel介绍

??????????????? 二、配置flannel + etcd

七、容器的镜像管理

一、镜像介绍

二、镜像管理操作

三、Dockerfile定制镜像

1、Dockerfile使用流程

2、Dockerfile常用指令


一、简介

??????? 在我之前的文章里涉及到了很多技术,其中就包含Docker容器,那么今天就来给小伙伴们以Docker为例讲讲容器。

??????? 对于刚入门的小白还不太了解,什么是容器呢?

二、容器的概念

??????? 容器是一种轻量级虚拟化技术,创建保证某业务可正常运行的必备的应用程序/指令,意思就是容器内部直接跑着你需要的服务,只要容器不会down,你的服务也不会出现异常。

????????容器技术的一个关键概念是隔离。容器利用操作系统级别的虚拟化,使得每个容器都拥有自己的文件系统、网络空间和进程空间,从而保持相对独立。这使得容器能够在同一主机上并行运行,而互不干扰。

????????? Docker 是目前最流行的容器化平台之一,它使得开发者能够更轻松地打包、交付和运行应用程序。容器技术在构建、部署和扩展应用程序方面提供了更高的灵活性、可移植性和效率,因此受到了广泛的关注和采用。

三、容器的优势

  1. 轻量级: 容器是轻量级的,因为它们共享主机操作系统的内核,避免了虚拟机中的操作系统重复。这使得容器的启动和停止速度更快,占用更少的资源。

  2. 可移植性: 容器可以在任何支持容器引擎的环境中运行,无论是在开发者的本地机器上、云平台上还是数据中心中。这种可移植性使得应用程序在不同环境中具有一致的行为。

  3. 快速部署: 容器可以快速启动和停止,使得应用程序的部署变得更加迅速和高效。这有助于实现持续集成和持续部署(CI/CD)流程。

  4. 隔离性: 容器提供了隔离性,每个容器都有自己的文件系统、网络和进程空间。这使得容器可以在同一主机上并行运行,互不干扰。

  5. 可扩展性: 容器可以根据负载需求进行水平扩展,通过在集群中添加或移除容器实例,快速适应变化的工作负载。

  6. 版本控制和复制: 容器允许开发者轻松创建、保存和分享容器镜像,这些镜像包含应用程序及其所有依赖项。这有助于确保开发、测试和生产环境之间的一致性。

  7. 资源利用率: 由于容器共享主机操作系统内核,它们的资源利用率相对较高,可以在相同硬件上运行更多的应用程序实例。

  8. 生态系统: 容器技术有强大的生态系统,包括各种容器编排工具(如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、指定容器的名称

  • --name
[root@localhost ~]# docker run -tid --name test_demo centos /bin/bash
  • --hostname
[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、设置容器间的网络别名

  • --link=容器名称:别名
[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模式:

??????????????????????????????? 容器不会有任何网络连接(不推荐)

??????? 这四种网络模式都有一个弊端,就是无法实现跨物理机之间相互通信,当然借助一定的技术手段完全可以解决这样的问题,

??????? 通过flannel+etcd实现网络管理

?????????????? 一、flannel介绍

??????????????????????? ????????作用:

??????????????????????????????????????? 跨物理机的容器相互通信

??????????????????????????????????????? 改变容器分配IP的方式

??????????????????????????????? etcd:

?????????????????????????????????????? 键值对数据库

?????????????????????????????????????? 用来记录网络分配信息

????????????????

??????????????? 二、配置flannel + 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 

三、Dockerfile定制镜像

1、Dockerfile使用流程

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 ./ 
2、Dockerfile常用指令

1) FROM指令

指定基础镜像,基础镜像不存在,自动联网下载

FROM  <基础镜像名称>

2) MAINTAINER指令

MAINTAINER  <user>  <email>

指定镜像的作者, 可以使用docker image inspect查看

3) RUN指令

执行定制的操作,RUN指定的命令在基础镜像中得事先存在

RUN   cmd1 && cmd2 && cmd3

4) CMD指令

指定创建容器时,自动执行的命令

  1. 一个Dockerfile中只能出现一个CMD
  2. 写前台启动服务的指令
  3. 创建容器时指定的命令会覆盖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指令

拷贝文件、目录

  1. 源文件可以是本地文件、URL地址

  2. 源文件是压缩包,相当于自动解压缩

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容器的部署以及管理操作,小伙伴们可以考虑如果有上百台甚至上千台容器,需要同意管理,怎么办?

??????? 关注博主,下期会更新如何批量操作容器。

文章来源:https://blog.csdn.net/hrk1234/article/details/135448894
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。